From be1c7e50e1e8809ea56f2c9d472eccd8ffd73a97 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Fri, 19 Apr 2024 04:57:58 +0200 Subject: Adding upstream version 1.44.3. Signed-off-by: Daniel Baumann --- web/server/h2o/libh2o/deps/brotli/.gitignore | 8 + web/server/h2o/libh2o/deps/brotli/.gitmodules | 3 + web/server/h2o/libh2o/deps/brotli/.travis.yml | 32 + web/server/h2o/libh2o/deps/brotli/CONTRIBUTING.md | 27 + web/server/h2o/libh2o/deps/brotli/LICENSE | 19 + web/server/h2o/libh2o/deps/brotli/README.md | 17 + web/server/h2o/libh2o/deps/brotli/appveyor.yml | 77 + .../h2o/libh2o/deps/brotli/appveyor/install.ps1 | 177 + .../deps/brotli/appveyor/run_with_compiler.cmd | 80 + web/server/h2o/libh2o/deps/brotli/dec/Makefile | 12 + web/server/h2o/libh2o/deps/brotli/dec/bit_reader.c | 48 + web/server/h2o/libh2o/deps/brotli/dec/bit_reader.h | 389 + web/server/h2o/libh2o/deps/brotli/dec/context.h | 251 + web/server/h2o/libh2o/deps/brotli/dec/decode.c | 2237 ++ web/server/h2o/libh2o/deps/brotli/dec/decode.h | 96 + web/server/h2o/libh2o/deps/brotli/dec/dictionary.c | 9466 +++++++ web/server/h2o/libh2o/deps/brotli/dec/dictionary.h | 38 + web/server/h2o/libh2o/deps/brotli/dec/huffman.c | 357 + web/server/h2o/libh2o/deps/brotli/dec/huffman.h | 73 + web/server/h2o/libh2o/deps/brotli/dec/port.h | 224 + web/server/h2o/libh2o/deps/brotli/dec/prefix.h | 749 + web/server/h2o/libh2o/deps/brotli/dec/state.c | 178 + web/server/h2o/libh2o/deps/brotli/dec/state.h | 249 + web/server/h2o/libh2o/deps/brotli/dec/transform.h | 300 + web/server/h2o/libh2o/deps/brotli/dec/types.h | 38 + .../docs/brotli-comparison-study-2015-09-22.pdf | Bin 0 -> 215208 bytes .../brotli/docs/draft-alakuijala-brotli-08.nroff | 5891 +++++ .../brotli/docs/draft-alakuijala-brotli-08.txt | 6723 +++++ web/server/h2o/libh2o/deps/brotli/enc/Makefile | 14 + .../libh2o/deps/brotli/enc/backward_references.cc | 783 + .../libh2o/deps/brotli/enc/backward_references.h | 39 + web/server/h2o/libh2o/deps/brotli/enc/bit_cost.h | 139 + .../h2o/libh2o/deps/brotli/enc/block_splitter.cc | 389 + .../h2o/libh2o/deps/brotli/enc/block_splitter.h | 61 + .../libh2o/deps/brotli/enc/brotli_bit_stream.cc | 1127 + .../h2o/libh2o/deps/brotli/enc/brotli_bit_stream.h | 175 + web/server/h2o/libh2o/deps/brotli/enc/cluster.h | 297 + web/server/h2o/libh2o/deps/brotli/enc/command.h | 136 + .../libh2o/deps/brotli/enc/compress_fragment.cc | 693 + .../h2o/libh2o/deps/brotli/enc/compress_fragment.h | 47 + .../deps/brotli/enc/compress_fragment_two_pass.cc | 519 + .../deps/brotli/enc/compress_fragment_two_pass.h | 40 + web/server/h2o/libh2o/deps/brotli/enc/context.h | 178 + .../h2o/libh2o/deps/brotli/enc/dictionary.cc | 9466 +++++++ web/server/h2o/libh2o/deps/brotli/enc/dictionary.h | 41 + .../h2o/libh2o/deps/brotli/enc/dictionary_hash.h | 4117 +++ web/server/h2o/libh2o/deps/brotli/enc/encode.cc | 958 + web/server/h2o/libh2o/deps/brotli/enc/encode.h | 211 + .../h2o/libh2o/deps/brotli/enc/encode_parallel.cc | 279 + .../h2o/libh2o/deps/brotli/enc/encode_parallel.h | 28 + .../h2o/libh2o/deps/brotli/enc/entropy_encode.cc | 469 + .../h2o/libh2o/deps/brotli/enc/entropy_encode.h | 102 + .../libh2o/deps/brotli/enc/entropy_encode_static.h | 572 + web/server/h2o/libh2o/deps/brotli/enc/fast_log.h | 139 + .../h2o/libh2o/deps/brotli/enc/find_match_length.h | 77 + web/server/h2o/libh2o/deps/brotli/enc/hash.h | 953 + web/server/h2o/libh2o/deps/brotli/enc/histogram.cc | 67 + web/server/h2o/libh2o/deps/brotli/enc/histogram.h | 94 + .../h2o/libh2o/deps/brotli/enc/literal_cost.cc | 165 + .../h2o/libh2o/deps/brotli/enc/literal_cost.h | 24 + web/server/h2o/libh2o/deps/brotli/enc/metablock.cc | 534 + web/server/h2o/libh2o/deps/brotli/enc/metablock.h | 80 + web/server/h2o/libh2o/deps/brotli/enc/port.h | 142 + web/server/h2o/libh2o/deps/brotli/enc/prefix.h | 79 + web/server/h2o/libh2o/deps/brotli/enc/ringbuffer.h | 114 + .../h2o/libh2o/deps/brotli/enc/static_dict.cc | 455 + .../h2o/libh2o/deps/brotli/enc/static_dict.h | 32 + .../h2o/libh2o/deps/brotli/enc/static_dict_lut.h | 12055 +++++++++ web/server/h2o/libh2o/deps/brotli/enc/streams.cc | 114 + web/server/h2o/libh2o/deps/brotli/enc/streams.h | 121 + web/server/h2o/libh2o/deps/brotli/enc/transform.h | 248 + web/server/h2o/libh2o/deps/brotli/enc/types.h | 27 + web/server/h2o/libh2o/deps/brotli/enc/utf8_util.cc | 83 + web/server/h2o/libh2o/deps/brotli/enc/utf8_util.h | 25 + web/server/h2o/libh2o/deps/brotli/enc/write_bits.h | 84 + web/server/h2o/libh2o/deps/brotli/python/README.md | 5 + web/server/h2o/libh2o/deps/brotli/python/bro.py | 132 + .../h2o/libh2o/deps/brotli/python/brotlimodule.cc | 302 + .../deps/brotli/python/tests/compatibility_test.py | 27 + .../brotli/python/tests/custom_dictionary_test.py | 36 + .../deps/brotli/python/tests/roundtrip_test.py | 43 + .../libh2o/deps/brotli/python/tests/test_utils.py | 36 + web/server/h2o/libh2o/deps/brotli/setup.py | 227 + web/server/h2o/libh2o/deps/brotli/shared.mk | 13 + web/server/h2o/libh2o/deps/brotli/tests/Makefile | 19 + .../libh2o/deps/brotli/tests/compatibility_test.sh | 21 + .../h2o/libh2o/deps/brotli/tests/roundtrip_test.sh | 31 + .../h2o/libh2o/deps/brotli/tests/testdata/10x10y | 1 + .../deps/brotli/tests/testdata/10x10y.compressed | Bin 0 -> 12 bytes .../h2o/libh2o/deps/brotli/tests/testdata/64x | 1 + .../deps/brotli/tests/testdata/64x.compressed | Bin 0 -> 10 bytes .../libh2o/deps/brotli/tests/testdata/alice29.txt | 3609 +++ .../brotli/tests/testdata/alice29.txt.compressed | Bin 0 -> 50096 bytes .../libh2o/deps/brotli/tests/testdata/asyoulik.txt | 4122 +++ .../brotli/tests/testdata/asyoulik.txt.compressed | Bin 0 -> 45687 bytes .../deps/brotli/tests/testdata/backward65536 | Bin 0 -> 65792 bytes .../brotli/tests/testdata/backward65536.compressed | Bin 0 -> 19 bytes .../libh2o/deps/brotli/tests/testdata/bb.binast | Bin 0 -> 12356697 bytes .../deps/brotli/tests/testdata/compressed_file | Bin 0 -> 50096 bytes .../tests/testdata/compressed_file.compressed | Bin 0 -> 50100 bytes .../deps/brotli/tests/testdata/compressed_repeated | Bin 0 -> 144224 bytes .../tests/testdata/compressed_repeated.compressed | Bin 0 -> 50299 bytes .../h2o/libh2o/deps/brotli/tests/testdata/empty | 0 .../deps/brotli/tests/testdata/empty.compressed | 1 + .../deps/brotli/tests/testdata/empty.compressed.00 | 1 + .../deps/brotli/tests/testdata/empty.compressed.01 | 1 + .../deps/brotli/tests/testdata/empty.compressed.02 | 1 + .../deps/brotli/tests/testdata/empty.compressed.03 | 1 + .../deps/brotli/tests/testdata/empty.compressed.04 | 1 + .../deps/brotli/tests/testdata/empty.compressed.05 | 1 + .../deps/brotli/tests/testdata/empty.compressed.06 | 1 + .../deps/brotli/tests/testdata/empty.compressed.07 | 1 + .../deps/brotli/tests/testdata/empty.compressed.08 | 1 + .../deps/brotli/tests/testdata/empty.compressed.09 | 1 + .../deps/brotli/tests/testdata/empty.compressed.10 | 1 + .../deps/brotli/tests/testdata/empty.compressed.11 | 1 + .../deps/brotli/tests/testdata/empty.compressed.12 | 1 + .../deps/brotli/tests/testdata/empty.compressed.13 | 1 + .../deps/brotli/tests/testdata/empty.compressed.14 | 1 + .../deps/brotli/tests/testdata/empty.compressed.15 | 1 + .../deps/brotli/tests/testdata/empty.compressed.16 | Bin 0 -> 4 bytes .../deps/brotli/tests/testdata/empty.compressed.17 | 1 + .../deps/brotli/tests/testdata/empty.compressed.18 | Bin 0 -> 196610 bytes .../libh2o/deps/brotli/tests/testdata/lcet10.txt | 7519 ++++++ .../brotli/tests/testdata/lcet10.txt.compressed | Bin 0 -> 124719 bytes .../libh2o/deps/brotli/tests/testdata/mapsdatazrh | Bin 0 -> 285886 bytes .../brotli/tests/testdata/mapsdatazrh.compressed | Bin 0 -> 161743 bytes .../h2o/libh2o/deps/brotli/tests/testdata/monkey | 1 + .../deps/brotli/tests/testdata/monkey.compressed | Bin 0 -> 425 bytes .../libh2o/deps/brotli/tests/testdata/plrabn12.txt | 10699 ++++++++ .../brotli/tests/testdata/plrabn12.txt.compressed | Bin 0 -> 174771 bytes .../h2o/libh2o/deps/brotli/tests/testdata/quickfox | 1 + .../deps/brotli/tests/testdata/quickfox.compressed | 1 + .../deps/brotli/tests/testdata/quickfox_repeated | 1 + .../tests/testdata/quickfox_repeated.compressed | 2 + .../deps/brotli/tests/testdata/random_chunks | Bin 0 -> 2704 bytes .../deps/brotli/tests/testdata/random_org_10k.bin | Bin 0 -> 10000 bytes .../tests/testdata/random_org_10k.bin.compressed | Bin 0 -> 10004 bytes .../h2o/libh2o/deps/brotli/tests/testdata/ukkonooa | 1 + .../deps/brotli/tests/testdata/ukkonooa.compressed | Bin 0 -> 69 bytes web/server/h2o/libh2o/deps/brotli/tests/testdata/x | 1 + .../libh2o/deps/brotli/tests/testdata/x.compressed | Bin 0 -> 5 bytes .../deps/brotli/tests/testdata/x.compressed.00 | Bin 0 -> 5 bytes .../deps/brotli/tests/testdata/x.compressed.01 | Bin 0 -> 8 bytes .../deps/brotli/tests/testdata/x.compressed.02 | Bin 0 -> 5 bytes .../deps/brotli/tests/testdata/x.compressed.03 | Bin 0 -> 10 bytes .../h2o/libh2o/deps/brotli/tests/testdata/xyzzy | 1 + .../deps/brotli/tests/testdata/xyzzy.compressed | 1 + .../h2o/libh2o/deps/brotli/tests/testdata/zeros | Bin 0 -> 262144 bytes .../deps/brotli/tests/testdata/zeros.compressed | Bin 0 -> 13 bytes web/server/h2o/libh2o/deps/brotli/tools/Makefile | 25 + web/server/h2o/libh2o/deps/brotli/tools/bro.cc | 303 + .../h2o/libh2o/deps/brotli/tools/rfc-format.py | 92 + web/server/h2o/libh2o/deps/brotli/tools/version.h | 14 + web/server/h2o/libh2o/deps/cloexec/cloexec.c | 93 + web/server/h2o/libh2o/deps/cloexec/cloexec.h | 36 + web/server/h2o/libh2o/deps/golombset/README.md | 26 + web/server/h2o/libh2o/deps/golombset/golombset.h | 162 + web/server/h2o/libh2o/deps/golombset/test.c | 58 + web/server/h2o/libh2o/deps/klib/.gitignore | 40 + web/server/h2o/libh2o/deps/klib/README.md | 237 + web/server/h2o/libh2o/deps/klib/bgzf.c | 555 + web/server/h2o/libh2o/deps/klib/bgzf.h | 196 + web/server/h2o/libh2o/deps/klib/kbit.h | 30 + web/server/h2o/libh2o/deps/klib/kbtree.h | 384 + web/server/h2o/libh2o/deps/klib/kgraph.h | 79 + web/server/h2o/libh2o/deps/klib/khash.h | 619 + web/server/h2o/libh2o/deps/klib/khmm.c | 423 + web/server/h2o/libh2o/deps/klib/khmm.h | 107 + web/server/h2o/libh2o/deps/klib/klist.h | 121 + web/server/h2o/libh2o/deps/klib/kmath.c | 456 + web/server/h2o/libh2o/deps/klib/kmath.h | 53 + web/server/h2o/libh2o/deps/klib/knetfile.c | 628 + web/server/h2o/libh2o/deps/klib/knetfile.h | 75 + web/server/h2o/libh2o/deps/klib/knhx.c | 166 + web/server/h2o/libh2o/deps/klib/knhx.h | 35 + web/server/h2o/libh2o/deps/klib/kopen.c | 343 + web/server/h2o/libh2o/deps/klib/ksa.c | 242 + web/server/h2o/libh2o/deps/klib/kseq.h | 235 + web/server/h2o/libh2o/deps/klib/kson.c | 253 + web/server/h2o/libh2o/deps/klib/kson.h | 64 + web/server/h2o/libh2o/deps/klib/ksort.h | 298 + web/server/h2o/libh2o/deps/klib/kstring.c | 229 + web/server/h2o/libh2o/deps/klib/kstring.h | 259 + web/server/h2o/libh2o/deps/klib/ksw.c | 633 + web/server/h2o/libh2o/deps/klib/ksw.h | 72 + web/server/h2o/libh2o/deps/klib/kthread.c | 143 + web/server/h2o/libh2o/deps/klib/kurl.c | 583 + web/server/h2o/libh2o/deps/klib/kurl.h | 57 + web/server/h2o/libh2o/deps/klib/kvec.h | 90 + web/server/h2o/libh2o/deps/klib/lua/bio.lua | 149 + web/server/h2o/libh2o/deps/klib/lua/klib.lua | 677 + web/server/h2o/libh2o/deps/klib/test/Makefile | 60 + web/server/h2o/libh2o/deps/klib/test/kbit_test.c | 137 + web/server/h2o/libh2o/deps/klib/test/kbtree_test.c | 94 + web/server/h2o/libh2o/deps/klib/test/kgraph_test.c | 26 + web/server/h2o/libh2o/deps/klib/test/khash_keith.c | 95 + .../h2o/libh2o/deps/klib/test/khash_keith2.c | 67 + web/server/h2o/libh2o/deps/klib/test/khash_test.c | 141 + web/server/h2o/libh2o/deps/klib/test/klist_test.c | 19 + web/server/h2o/libh2o/deps/klib/test/kmin_test.c | 48 + web/server/h2o/libh2o/deps/klib/test/kseq_bench.c | 69 + web/server/h2o/libh2o/deps/klib/test/kseq_bench2.c | 43 + web/server/h2o/libh2o/deps/klib/test/kseq_test.c | 27 + web/server/h2o/libh2o/deps/klib/test/kseq_test.dat | 12 + web/server/h2o/libh2o/deps/klib/test/ksort_test.c | 104 + web/server/h2o/libh2o/deps/klib/test/ksort_test.cc | 997 + .../h2o/libh2o/deps/klib/test/kstring_bench.c | 51 + .../h2o/libh2o/deps/klib/test/kstring_bench2.c | 131 + .../h2o/libh2o/deps/klib/test/kstring_test.c | 76 + .../h2o/libh2o/deps/klib/test/kthread_test.c | 69 + web/server/h2o/libh2o/deps/klib/test/kvec_test.cc | 69 + web/server/h2o/libh2o/deps/libgkc/gkc.c | 439 + web/server/h2o/libh2o/deps/libgkc/gkc.h | 37 + web/server/h2o/libh2o/deps/libgkc/test.c | 141 + web/server/h2o/libh2o/deps/libyrmcds/.gitignore | 13 + web/server/h2o/libh2o/deps/libyrmcds/.travis.yml | 16 + web/server/h2o/libh2o/deps/libyrmcds/COPYING | 25 + web/server/h2o/libh2o/deps/libyrmcds/Doxyfile | 1748 ++ web/server/h2o/libh2o/deps/libyrmcds/Makefile | 87 + web/server/h2o/libh2o/deps/libyrmcds/README.md | 78 + web/server/h2o/libh2o/deps/libyrmcds/USAGE.md | 221 + web/server/h2o/libh2o/deps/libyrmcds/close.c | 24 + web/server/h2o/libh2o/deps/libyrmcds/connect.c | 199 + web/server/h2o/libh2o/deps/libyrmcds/counter.c | 408 + .../h2o/libh2o/deps/libyrmcds/example/counter.c | 38 + .../h2o/libh2o/deps/libyrmcds/example/memcache.c | 38 + web/server/h2o/libh2o/deps/libyrmcds/recv.c | 354 + web/server/h2o/libh2o/deps/libyrmcds/send.c | 564 + web/server/h2o/libh2o/deps/libyrmcds/send_text.c | 414 + .../h2o/libh2o/deps/libyrmcds/set_compression.c | 14 + web/server/h2o/libh2o/deps/libyrmcds/socket.c | 35 + web/server/h2o/libh2o/deps/libyrmcds/strerror.c | 34 + web/server/h2o/libh2o/deps/libyrmcds/t/t.h | 75 + web/server/h2o/libh2o/deps/libyrmcds/t/text.c | 294 + web/server/h2o/libh2o/deps/libyrmcds/text_mode.c | 32 + web/server/h2o/libh2o/deps/libyrmcds/yc-cnt.c | 306 + web/server/h2o/libh2o/deps/libyrmcds/yc.c | 1099 + web/server/h2o/libh2o/deps/libyrmcds/yrmcds.h | 1071 + .../h2o/libh2o/deps/libyrmcds/yrmcds_portability.h | 50 + web/server/h2o/libh2o/deps/libyrmcds/yrmcds_text.h | 47 + web/server/h2o/libh2o/deps/mruby-digest/.gitignore | 5 + .../h2o/libh2o/deps/mruby-digest/.travis.yml | 2 + web/server/h2o/libh2o/deps/mruby-digest/Makefile | 14 + web/server/h2o/libh2o/deps/mruby-digest/README.md | 55 + .../h2o/libh2o/deps/mruby-digest/mrbgem.rake | 4 + .../h2o/libh2o/deps/mruby-digest/mrblib/digest.rb | 46 + .../h2o/libh2o/deps/mruby-digest/run_test.rb | 28 + .../h2o/libh2o/deps/mruby-digest/src/digest.c | 1007 + .../h2o/libh2o/deps/mruby-digest/src/picohash.h | 751 + .../h2o/libh2o/deps/mruby-digest/test/digest.rb | 203 + web/server/h2o/libh2o/deps/mruby-dir/.gitignore | 5 + web/server/h2o/libh2o/deps/mruby-dir/.travis.yml | 2 + web/server/h2o/libh2o/deps/mruby-dir/README.md | 56 + web/server/h2o/libh2o/deps/mruby-dir/mrbgem.rake | 6 + web/server/h2o/libh2o/deps/mruby-dir/mrblib/dir.rb | 64 + web/server/h2o/libh2o/deps/mruby-dir/run_test.rb | 26 + .../h2o/libh2o/deps/mruby-dir/src/Win/dirent.c | 154 + web/server/h2o/libh2o/deps/mruby-dir/src/dir.c | 281 + web/server/h2o/libh2o/deps/mruby-dir/test/dir.rb | 128 + .../h2o/libh2o/deps/mruby-dir/test/dirtest.c | 114 + web/server/h2o/libh2o/deps/mruby-env/.gitignore | 1 + web/server/h2o/libh2o/deps/mruby-env/.travis.yml | 2 + web/server/h2o/libh2o/deps/mruby-env/README.md | 52 + web/server/h2o/libh2o/deps/mruby-env/mrbgem.rake | 4 + web/server/h2o/libh2o/deps/mruby-env/mrblib/env.rb | 16 + web/server/h2o/libh2o/deps/mruby-env/run_test.rb | 27 + web/server/h2o/libh2o/deps/mruby-env/src/env.c | 243 + .../h2o/libh2o/deps/mruby-env/test/env_test.rb | 121 + web/server/h2o/libh2o/deps/mruby-errno/.gitignore | 1 + web/server/h2o/libh2o/deps/mruby-errno/.travis.yml | 2 + web/server/h2o/libh2o/deps/mruby-errno/README.md | 27 + web/server/h2o/libh2o/deps/mruby-errno/mrbgem.rake | 6 + web/server/h2o/libh2o/deps/mruby-errno/run_test.rb | 26 + web/server/h2o/libh2o/deps/mruby-errno/src/errno.c | 175 + web/server/h2o/libh2o/deps/mruby-errno/src/gen.rb | 25 + .../libh2o/deps/mruby-errno/src/known_errors.def | 145 + .../deps/mruby-errno/src/known_errors_def.cstub | 725 + .../deps/mruby-errno/src/known_errors_e2c.cstub | 435 + .../h2o/libh2o/deps/mruby-errno/test/errno.rb | 60 + .../h2o/libh2o/deps/mruby-file-stat/.gitignore | 5 + .../h2o/libh2o/deps/mruby-file-stat/.travis.yml | 15 + .../deps/mruby-file-stat/.travis_build_config.rb | 7 + .../h2o/libh2o/deps/mruby-file-stat/README.md | 82 + .../h2o/libh2o/deps/mruby-file-stat/appveyor.yml | 19 + .../h2o/libh2o/deps/mruby-file-stat/config.h.in | 19 + .../h2o/libh2o/deps/mruby-file-stat/configure | 4320 +++ .../h2o/libh2o/deps/mruby-file-stat/configure.ac | 20 + .../h2o/libh2o/deps/mruby-file-stat/mrbgem.rake | 32 + .../h2o/libh2o/deps/mruby-file-stat/mrblib/ext.rb | 5 + .../deps/mruby-file-stat/mrblib/file-stat.rb | 52 + .../libh2o/deps/mruby-file-stat/src/file-stat.c | 873 + .../libh2o/deps/mruby-file-stat/test/executable | 0 .../libh2o/deps/mruby-file-stat/test/file-stat.c | 30 + .../libh2o/deps/mruby-file-stat/test/file-stat.rb | 369 + .../h2o/libh2o/deps/mruby-file-stat/test/io.rb | 7 + .../h2o/libh2o/deps/mruby-file-stat/test/readable | 0 .../h2o/libh2o/deps/mruby-file-stat/test/writable | 0 web/server/h2o/libh2o/deps/mruby-iijson/.gitignore | 1 + .../h2o/libh2o/deps/mruby-iijson/.travis.yml | 2 + web/server/h2o/libh2o/deps/mruby-iijson/README.md | 87 + .../h2o/libh2o/deps/mruby-iijson/mrbgem.rake | 6 + .../h2o/libh2o/deps/mruby-iijson/mrblib/json.rb | 129 + .../h2o/libh2o/deps/mruby-iijson/mrblib/to_json.rb | 47 + .../h2o/libh2o/deps/mruby-iijson/run_test.rb | 23 + web/server/h2o/libh2o/deps/mruby-iijson/src/json.c | 641 + .../h2o/libh2o/deps/mruby-iijson/test/json.rb | 145 + .../h2o/libh2o/deps/mruby-iijson/test/testjson.c | 11 + .../h2o/libh2o/deps/mruby-input-stream/.travis.yml | 6 + .../h2o/libh2o/deps/mruby-input-stream/LICENSE | 19 + .../h2o/libh2o/deps/mruby-input-stream/README.md | 28 + .../h2o/libh2o/deps/mruby-input-stream/Rakefile | 28 + .../deps/mruby-input-stream/build_config_sample.rb | 17 + .../h2o/libh2o/deps/mruby-input-stream/mrbgem.rake | 6 + .../deps/mruby-input-stream/mrblib/input_stream.rb | 16 + .../mruby-input-stream/src/mruby_input_stream.c | 278 + .../mruby-input-stream/src/mruby_input_stream.h | 19 + .../deps/mruby-input-stream/test/input_stream.rb | 111 + web/server/h2o/libh2o/deps/mruby-io/.gitignore | 1 + web/server/h2o/libh2o/deps/mruby-io/.travis.yml | 2 + web/server/h2o/libh2o/deps/mruby-io/README.md | 185 + .../libh2o/deps/mruby-io/include/mruby/ext/io.h | 36 + web/server/h2o/libh2o/deps/mruby-io/mrbgem.rake | 16 + web/server/h2o/libh2o/deps/mruby-io/mrblib/file.rb | 173 + .../libh2o/deps/mruby-io/mrblib/file_constants.rb | 29 + web/server/h2o/libh2o/deps/mruby-io/mrblib/io.rb | 372 + .../h2o/libh2o/deps/mruby-io/mrblib/kernel.rb | 15 + web/server/h2o/libh2o/deps/mruby-io/run_test.rb | 25 + web/server/h2o/libh2o/deps/mruby-io/src/file.c | 325 + .../h2o/libh2o/deps/mruby-io/src/file_test.c | 365 + web/server/h2o/libh2o/deps/mruby-io/src/io.c | 941 + .../h2o/libh2o/deps/mruby-io/src/mruby_io_gem.c | 20 + web/server/h2o/libh2o/deps/mruby-io/test/file.rb | 108 + .../h2o/libh2o/deps/mruby-io/test/file_test.rb | 95 + .../h2o/libh2o/deps/mruby-io/test/gc_filedes.sh | 4 + web/server/h2o/libh2o/deps/mruby-io/test/io.rb | 416 + .../h2o/libh2o/deps/mruby-io/test/mruby_io_test.c | 141 + .../h2o/libh2o/deps/mruby-onig-regexp/.travis.yml | 10 + .../deps/mruby-onig-regexp/.travis_config.rb | 21 + .../deps/mruby-onig-regexp/Onigmo-6.1.1.tar.gz | Bin 0 -> 821378 bytes .../h2o/libh2o/deps/mruby-onig-regexp/README.md | 45 + .../h2o/libh2o/deps/mruby-onig-regexp/mrbgem.rake | 113 + .../deps/mruby-onig-regexp/mrblib/onig_regexp.rb | 140 + .../deps/mruby-onig-regexp/src/mruby_onig_regexp.c | 1064 + .../mruby-onig-regexp/test/mruby_onig_regexp.rb | 398 + web/server/h2o/libh2o/deps/mruby-pack/.gitignore | 5 + web/server/h2o/libh2o/deps/mruby-pack/.travis.yml | 2 + web/server/h2o/libh2o/deps/mruby-pack/README.md | 67 + web/server/h2o/libh2o/deps/mruby-pack/mrbgem.rake | 6 + web/server/h2o/libh2o/deps/mruby-pack/packtest.rb | 154 + web/server/h2o/libh2o/deps/mruby-pack/run_test.rb | 26 + web/server/h2o/libh2o/deps/mruby-pack/src/pack.c | 1144 + web/server/h2o/libh2o/deps/mruby-pack/test/pack.rb | 147 + .../h2o/libh2o/deps/mruby-require/.gitignore | 1 + .../h2o/libh2o/deps/mruby-require/.travis.yml | 2 + web/server/h2o/libh2o/deps/mruby-require/README.md | 59 + .../h2o/libh2o/deps/mruby-require/mrbgem.rake | 15 + .../libh2o/deps/mruby-require/mrblib/require.rb | 97 + .../h2o/libh2o/deps/mruby-require/run_test.rb | 29 + .../h2o/libh2o/deps/mruby-require/src/require.c | 208 + .../libh2o/deps/mruby-require/test/d/required.rb | 19 + .../h2o/libh2o/deps/mruby-require/test/require.rb | 28 + .../h2o/libh2o/deps/mruby-require/test/test.rb | 34 + .../h2o/libh2o/deps/mruby-require/test/test2.rb | 139 + .../libh2o/deps/mruby-require/test/test_context.rb | 33 + .../deps/mruby-require/test/test_nest_loop.rb | 58 + web/server/h2o/libh2o/deps/mruby/.gitignore | 26 + web/server/h2o/libh2o/deps/mruby/.gitlab-ci.yml | 3214 +++ web/server/h2o/libh2o/deps/mruby/.travis.yml | 18 + web/server/h2o/libh2o/deps/mruby/.yardopts | 17 + web/server/h2o/libh2o/deps/mruby/AUTHORS | 39 + web/server/h2o/libh2o/deps/mruby/CONTRIBUTING.md | 68 + web/server/h2o/libh2o/deps/mruby/LEGAL | 6 + web/server/h2o/libh2o/deps/mruby/MITL | 20 + web/server/h2o/libh2o/deps/mruby/Makefile | 17 + web/server/h2o/libh2o/deps/mruby/NEWS | 13 + web/server/h2o/libh2o/deps/mruby/README.md | 92 + web/server/h2o/libh2o/deps/mruby/Rakefile | 152 + web/server/h2o/libh2o/deps/mruby/TODO | 10 + web/server/h2o/libh2o/deps/mruby/appveyor.yml | 27 + .../h2o/libh2o/deps/mruby/appveyor_config.rb | 50 + .../libh2o/deps/mruby/benchmark/bm_ao_render.rb | 314 + .../deps/mruby/benchmark/bm_app_lc_fizzbuzz.rb | 52 + .../h2o/libh2o/deps/mruby/benchmark/bm_fib.rb | 7 + .../h2o/libh2o/deps/mruby/benchmark/bm_so_lists.rb | 47 + .../deps/mruby/benchmark/build_config_boxing.rb | 28 + .../libh2o/deps/mruby/benchmark/build_config_cc.rb | 13 + .../h2o/libh2o/deps/mruby/benchmark/plot.gpl | 5 + web/server/h2o/libh2o/deps/mruby/bin/.gitkeep | 0 web/server/h2o/libh2o/deps/mruby/build_config.rb | 152 + .../h2o/libh2o/deps/mruby/doc/guides/compile.md | 488 + .../h2o/libh2o/deps/mruby/doc/guides/debugger.md | 370 + .../libh2o/deps/mruby/doc/guides/gc-arena-howto.md | 177 + .../h2o/libh2o/deps/mruby/doc/guides/mrbconf.md | 146 + .../h2o/libh2o/deps/mruby/doc/guides/mrbgems.md | 340 + .../h2o/libh2o/deps/mruby/doc/limitations.md | 208 + .../mrbgems/c_and_ruby_extension_example/README.md | 4 + .../c_and_ruby_extension_example/mrbgem.rake | 23 + .../c_and_ruby_extension_example/mrblib/example.rb | 5 + .../c_and_ruby_extension_example/src/example.c | 20 + .../c_and_ruby_extension_example/test/example.rb | 7 + .../examples/mrbgems/c_extension_example/README.md | 4 + .../mrbgems/c_extension_example/mrbgem.rake | 23 + .../mrbgems/c_extension_example/src/example.c | 20 + .../mrbgems/c_extension_example/test/example.c | 7 + .../mrbgems/c_extension_example/test/example.rb | 3 + .../mrbgems/ruby_extension_example/README.md | 4 + .../mrbgems/ruby_extension_example/mrbgem.rake | 25 + .../ruby_extension_example/mrblib/example.rb | 5 + .../mrbgems/ruby_extension_example/test/example.rb | 3 + .../examples/targets/build_config_ArduinoDue.rb | 90 + .../examples/targets/build_config_IntelEdison.rb | 69 + .../examples/targets/build_config_IntelGalileo.rb | 106 + .../mruby/examples/targets/build_config_RX630.rb | 81 + .../targets/build_config_android_arm64-v8a.rb | 26 + .../targets/build_config_android_armeabi.rb | 26 + .../build_config_android_armeabi_v7a_neon_hard.rb | 28 + .../examples/targets/build_config_chipKITMax32.rb | 86 + web/server/h2o/libh2o/deps/mruby/include/mrbconf.h | 130 + web/server/h2o/libh2o/deps/mruby/include/mruby.h | 1257 + .../h2o/libh2o/deps/mruby/include/mruby/array.h | 279 + .../libh2o/deps/mruby/include/mruby/boxing_nan.h | 98 + .../libh2o/deps/mruby/include/mruby/boxing_no.h | 48 + .../libh2o/deps/mruby/include/mruby/boxing_word.h | 120 + .../h2o/libh2o/deps/mruby/include/mruby/class.h | 92 + .../h2o/libh2o/deps/mruby/include/mruby/common.h | 72 + .../h2o/libh2o/deps/mruby/include/mruby/compile.h | 195 + .../h2o/libh2o/deps/mruby/include/mruby/data.h | 75 + .../h2o/libh2o/deps/mruby/include/mruby/debug.h | 66 + .../h2o/libh2o/deps/mruby/include/mruby/dump.h | 196 + .../h2o/libh2o/deps/mruby/include/mruby/error.h | 76 + .../h2o/libh2o/deps/mruby/include/mruby/gc.h | 80 + .../h2o/libh2o/deps/mruby/include/mruby/hash.h | 182 + .../h2o/libh2o/deps/mruby/include/mruby/irep.h | 64 + .../h2o/libh2o/deps/mruby/include/mruby/istruct.h | 47 + .../h2o/libh2o/deps/mruby/include/mruby/khash.h | 274 + .../h2o/libh2o/deps/mruby/include/mruby/numeric.h | 155 + .../h2o/libh2o/deps/mruby/include/mruby/object.h | 43 + .../h2o/libh2o/deps/mruby/include/mruby/opcode.h | 161 + .../h2o/libh2o/deps/mruby/include/mruby/proc.h | 83 + .../h2o/libh2o/deps/mruby/include/mruby/range.h | 49 + .../h2o/libh2o/deps/mruby/include/mruby/re.h | 16 + .../h2o/libh2o/deps/mruby/include/mruby/string.h | 430 + .../h2o/libh2o/deps/mruby/include/mruby/throw.h | 55 + .../h2o/libh2o/deps/mruby/include/mruby/value.h | 303 + .../h2o/libh2o/deps/mruby/include/mruby/variable.h | 138 + .../h2o/libh2o/deps/mruby/include/mruby/version.h | 110 + .../h2o/libh2o/deps/mruby/lib/mruby-core-ext.rb | 79 + .../h2o/libh2o/deps/mruby/lib/mruby/build.rb | 355 + .../libh2o/deps/mruby/lib/mruby/build/command.rb | 324 + .../libh2o/deps/mruby/lib/mruby/build/load_gems.rb | 122 + web/server/h2o/libh2o/deps/mruby/lib/mruby/gem.rb | 459 + .../h2o/libh2o/deps/mruby/lib/mruby/source.rb | 30 + web/server/h2o/libh2o/deps/mruby/minirake | 484 + .../h2o/libh2o/deps/mruby/mrbgems/default.gembox | 79 + .../h2o/libh2o/deps/mruby/mrbgems/full-core.gembox | 9 + .../deps/mruby/mrbgems/mruby-array-ext/mrbgem.rake | 5 + .../mruby/mrbgems/mruby-array-ext/mrblib/array.rb | 811 + .../deps/mruby/mrbgems/mruby-array-ext/src/array.c | 244 + .../mruby/mrbgems/mruby-array-ext/test/array.rb | 383 + .../mrbgems/mruby-bin-debugger/bintest/mrdb.rb | 286 + .../mrbgems/mruby-bin-debugger/bintest/print.rb | 701 + .../mruby/mrbgems/mruby-bin-debugger/mrbgem.rake | 9 + .../mruby-bin-debugger/tools/mrdb/apibreak.c | 507 + .../mruby-bin-debugger/tools/mrdb/apibreak.h | 26 + .../mruby-bin-debugger/tools/mrdb/apilist.c | 239 + .../mruby-bin-debugger/tools/mrdb/apilist.h | 14 + .../mruby-bin-debugger/tools/mrdb/apiprint.c | 78 + .../mruby-bin-debugger/tools/mrdb/apiprint.h | 13 + .../mruby-bin-debugger/tools/mrdb/cmdbreak.c | 436 + .../mruby-bin-debugger/tools/mrdb/cmdmisc.c | 501 + .../mruby-bin-debugger/tools/mrdb/cmdprint.c | 58 + .../mrbgems/mruby-bin-debugger/tools/mrdb/cmdrun.c | 64 + .../mrbgems/mruby-bin-debugger/tools/mrdb/mrdb.c | 759 + .../mrbgems/mruby-bin-debugger/tools/mrdb/mrdb.h | 165 + .../mruby-bin-debugger/tools/mrdb/mrdbconf.h | 16 + .../mruby-bin-debugger/tools/mrdb/mrdberror.h | 20 + .../mruby/mrbgems/mruby-bin-mirb/bintest/mirb.rb | 12 + .../deps/mruby/mrbgems/mruby-bin-mirb/mrbgem.rake | 33 + .../mruby/mrbgems/mruby-bin-mirb/tools/mirb/mirb.c | 584 + .../deps/mruby/mrbgems/mruby-bin-mrbc/mrbgem.rake | 16 + .../mruby/mrbgems/mruby-bin-mrbc/tools/mrbc/mrbc.c | 336 + .../mrbgems/mruby-bin-mruby-config/mrbgem.rake | 30 + .../mrbgems/mruby-bin-mruby-config/mruby-config | 20 + .../mruby-bin-mruby-config/mruby-config.bat | 42 + .../mruby/mrbgems/mruby-bin-mruby/bintest/mruby.rb | 60 + .../deps/mruby/mrbgems/mruby-bin-mruby/mrbgem.rake | 12 + .../mrbgems/mruby-bin-mruby/tools/mruby/mruby.c | 254 + .../mrbgems/mruby-bin-strip/bintest/mruby-strip.rb | 73 + .../deps/mruby/mrbgems/mruby-bin-strip/mrbgem.rake | 6 + .../tools/mruby-strip/mruby-strip.c | 155 + .../deps/mruby/mrbgems/mruby-class-ext/mrbgem.rake | 5 + .../deps/mruby/mrbgems/mruby-class-ext/src/class.c | 30 + .../mruby/mrbgems/mruby-class-ext/test/module.rb | 34 + .../mruby/mrbgems/mruby-compiler/bintest/mrbc.rb | 30 + .../mruby/mrbgems/mruby-compiler/core/codegen.c | 3026 +++ .../mruby/mrbgems/mruby-compiler/core/keywords | 50 + .../deps/mruby/mrbgems/mruby-compiler/core/lex.def | 212 + .../deps/mruby/mrbgems/mruby-compiler/core/node.h | 118 + .../deps/mruby/mrbgems/mruby-compiler/core/parse.y | 6652 +++++ .../deps/mruby/mrbgems/mruby-compiler/mrbgem.rake | 40 + .../deps/mruby/mrbgems/mruby-enum-ext/mrbgem.rake | 5 + .../mruby/mrbgems/mruby-enum-ext/mrblib/enum.rb | 711 + .../deps/mruby/mrbgems/mruby-enum-ext/test/enum.rb | 171 + .../deps/mruby/mrbgems/mruby-enum-lazy/mrbgem.rake | 7 + .../mruby/mrbgems/mruby-enum-lazy/mrblib/lazy.rb | 163 + .../mruby/mrbgems/mruby-enum-lazy/test/lazy.rb | 53 + .../mruby/mrbgems/mruby-enumerator/mrbgem.rake | 7 + .../mrbgems/mruby-enumerator/mrblib/enumerator.rb | 645 + .../mrbgems/mruby-enumerator/test/enumerator.rb | 546 + .../deps/mruby/mrbgems/mruby-error/mrbgem.rake | 10 + .../deps/mruby/mrbgems/mruby-error/src/exception.c | 100 + .../mruby/mrbgems/mruby-error/test/exception.c | 59 + .../mruby/mrbgems/mruby-error/test/exception.rb | 55 + .../deps/mruby/mrbgems/mruby-eval/mrbgem.rake | 7 + .../deps/mruby/mrbgems/mruby-eval/src/eval.c | 346 + .../deps/mruby/mrbgems/mruby-eval/test/eval.rb | 101 + .../deps/mruby/mrbgems/mruby-exit/mrbgem.rake | 5 + .../deps/mruby/mrbgems/mruby-exit/src/mruby-exit.c | 24 + .../deps/mruby/mrbgems/mruby-fiber/mrbgem.rake | 5 + .../deps/mruby/mrbgems/mruby-fiber/src/fiber.c | 420 + .../deps/mruby/mrbgems/mruby-fiber/test/fiber.rb | 208 + .../deps/mruby/mrbgems/mruby-hash-ext/mrbgem.rake | 8 + .../mruby/mrbgems/mruby-hash-ext/mrblib/hash.rb | 477 + .../mruby/mrbgems/mruby-hash-ext/src/hash-ext.c | 88 + .../deps/mruby/mrbgems/mruby-hash-ext/test/hash.rb | 294 + .../mruby/mrbgems/mruby-inline-struct/mrbgem.rake | 5 + .../mrbgems/mruby-inline-struct/test/inline.c | 83 + .../mrbgems/mruby-inline-struct/test/inline.rb | 151 + .../mruby/mrbgems/mruby-kernel-ext/mrbgem.rake | 5 + .../mruby/mrbgems/mruby-kernel-ext/src/kernel.c | 243 + .../mruby/mrbgems/mruby-kernel-ext/test/kernel.rb | 86 + .../deps/mruby/mrbgems/mruby-math/mrbgem.rake | 5 + .../deps/mruby/mrbgems/mruby-math/src/math.c | 783 + .../deps/mruby/mrbgems/mruby-math/test/math.rb | 152 + .../mruby/mrbgems/mruby-numeric-ext/mrbgem.rake | 5 + .../mruby-numeric-ext/mrblib/numeric_ext.rb | 17 + .../mrbgems/mruby-numeric-ext/src/numeric_ext.c | 30 + .../mrbgems/mruby-numeric-ext/test/numeric.rb | 28 + .../mruby/mrbgems/mruby-object-ext/mrbgem.rake | 5 + .../mrbgems/mruby-object-ext/mrblib/object.rb | 19 + .../mruby/mrbgems/mruby-object-ext/src/object.c | 106 + .../mruby/mrbgems/mruby-object-ext/test/nil.rb | 11 + .../mruby/mrbgems/mruby-object-ext/test/object.rb | 53 + .../mruby/mrbgems/mruby-objectspace/mrbgem.rake | 5 + .../mruby-objectspace/src/mruby_objectspace.c | 187 + .../mrbgems/mruby-objectspace/test/objectspace.rb | 60 + .../deps/mruby/mrbgems/mruby-print/mrbgem.rake | 5 + .../deps/mruby/mrbgems/mruby-print/mrblib/print.rb | 64 + .../deps/mruby/mrbgems/mruby-print/src/print.c | 64 + .../deps/mruby/mrbgems/mruby-proc-ext/mrbgem.rake | 5 + .../mruby/mrbgems/mruby-proc-ext/mrblib/proc.rb | 42 + .../deps/mruby/mrbgems/mruby-proc-ext/src/proc.c | 173 + .../deps/mruby/mrbgems/mruby-proc-ext/test/proc.c | 56 + .../deps/mruby/mrbgems/mruby-proc-ext/test/proc.rb | 96 + .../deps/mruby/mrbgems/mruby-random/mrbgem.rake | 5 + .../mruby/mrbgems/mruby-random/src/mt19937ar.c | 224 + .../mruby/mrbgems/mruby-random/src/mt19937ar.h | 80 + .../deps/mruby/mrbgems/mruby-random/src/random.c | 349 + .../deps/mruby/mrbgems/mruby-random/src/random.h | 12 + .../deps/mruby/mrbgems/mruby-random/test/random.rb | 88 + .../deps/mruby/mrbgems/mruby-range-ext/mrbgem.rake | 5 + .../mruby/mrbgems/mruby-range-ext/mrblib/range.rb | 31 + .../deps/mruby/mrbgems/mruby-range-ext/src/range.c | 176 + .../mruby/mrbgems/mruby-range-ext/test/range.rb | 32 + .../deps/mruby/mrbgems/mruby-sprintf/mrbgem.rake | 5 + .../mruby/mrbgems/mruby-sprintf/mrblib/string.rb | 9 + .../deps/mruby/mrbgems/mruby-sprintf/src/kernel.c | 30 + .../deps/mruby/mrbgems/mruby-sprintf/src/sprintf.c | 1113 + .../mruby/mrbgems/mruby-sprintf/test/sprintf.rb | 109 + .../mruby/mrbgems/mruby-string-ext/mrbgem.rake | 6 + .../mrbgems/mruby-string-ext/mrblib/string.rb | 355 + .../mruby/mrbgems/mruby-string-ext/src/string.c | 685 + .../mruby/mrbgems/mruby-string-ext/test/string.rb | 667 + .../deps/mruby/mrbgems/mruby-struct/mrbgem.rake | 5 + .../mruby/mrbgems/mruby-struct/mrblib/struct.rb | 103 + .../deps/mruby/mrbgems/mruby-struct/src/struct.c | 714 + .../deps/mruby/mrbgems/mruby-struct/test/struct.rb | 212 + .../mruby/mrbgems/mruby-symbol-ext/mrbgem.rake | 5 + .../mrbgems/mruby-symbol-ext/mrblib/symbol.rb | 65 + .../mruby/mrbgems/mruby-symbol-ext/src/symbol.c | 64 + .../mruby/mrbgems/mruby-symbol-ext/test/symbol.rb | 48 + .../libh2o/deps/mruby/mrbgems/mruby-test/README.md | 7 + .../libh2o/deps/mruby/mrbgems/mruby-test/driver.c | 172 + .../deps/mruby/mrbgems/mruby-test/init_mrbtest.c | 38 + .../deps/mruby/mrbgems/mruby-test/mrbgem.rake | 187 + .../deps/mruby/mrbgems/mruby-time/mrbgem.rake | 5 + .../deps/mruby/mrbgems/mruby-time/mrblib/time.rb | 9 + .../deps/mruby/mrbgems/mruby-time/src/time.c | 869 + .../deps/mruby/mrbgems/mruby-time/test/time.rb | 228 + .../mruby/mrbgems/mruby-toplevel-ext/mrbgem.rake | 5 + .../mrbgems/mruby-toplevel-ext/mrblib/toplevel.rb | 11 + .../mrbgems/mruby-toplevel-ext/test/toplevel.rb | 24 + web/server/h2o/libh2o/deps/mruby/mrblib/00class.rb | 28 + web/server/h2o/libh2o/deps/mruby/mrblib/10error.rb | 56 + web/server/h2o/libh2o/deps/mruby/mrblib/array.rb | 243 + web/server/h2o/libh2o/deps/mruby/mrblib/compar.rb | 84 + web/server/h2o/libh2o/deps/mruby/mrblib/enum.rb | 348 + web/server/h2o/libh2o/deps/mruby/mrblib/hash.rb | 358 + .../h2o/libh2o/deps/mruby/mrblib/init_mrblib.c | 11 + web/server/h2o/libh2o/deps/mruby/mrblib/kernel.rb | 50 + .../h2o/libh2o/deps/mruby/mrblib/mrblib.rake | 18 + web/server/h2o/libh2o/deps/mruby/mrblib/numeric.rb | 173 + web/server/h2o/libh2o/deps/mruby/mrblib/range.rb | 67 + web/server/h2o/libh2o/deps/mruby/mrblib/string.rb | 275 + .../h2o/libh2o/deps/mruby/mruby-source.gemspec | 18 + web/server/h2o/libh2o/deps/mruby/src/array.c | 1249 + web/server/h2o/libh2o/deps/mruby/src/backtrace.c | 281 + web/server/h2o/libh2o/deps/mruby/src/class.c | 2474 ++ web/server/h2o/libh2o/deps/mruby/src/codedump.c | 474 + web/server/h2o/libh2o/deps/mruby/src/compar.c | 13 + web/server/h2o/libh2o/deps/mruby/src/crc.c | 39 + web/server/h2o/libh2o/deps/mruby/src/debug.c | 217 + web/server/h2o/libh2o/deps/mruby/src/dump.c | 1100 + web/server/h2o/libh2o/deps/mruby/src/enum.c | 14 + web/server/h2o/libh2o/deps/mruby/src/error.c | 503 + web/server/h2o/libh2o/deps/mruby/src/error.h | 3 + web/server/h2o/libh2o/deps/mruby/src/etc.c | 234 + web/server/h2o/libh2o/deps/mruby/src/ext/.gitkeep | 0 web/server/h2o/libh2o/deps/mruby/src/fmt_fp.c | 372 + web/server/h2o/libh2o/deps/mruby/src/gc.c | 1824 ++ web/server/h2o/libh2o/deps/mruby/src/hash.c | 905 + web/server/h2o/libh2o/deps/mruby/src/init.c | 51 + web/server/h2o/libh2o/deps/mruby/src/kernel.c | 1238 + web/server/h2o/libh2o/deps/mruby/src/load.c | 704 + .../h2o/libh2o/deps/mruby/src/mruby_core.rake | 19 + web/server/h2o/libh2o/deps/mruby/src/numeric.c | 1355 + web/server/h2o/libh2o/deps/mruby/src/object.c | 610 + web/server/h2o/libh2o/deps/mruby/src/opcode.h | 2 + web/server/h2o/libh2o/deps/mruby/src/pool.c | 198 + web/server/h2o/libh2o/deps/mruby/src/print.c | 47 + web/server/h2o/libh2o/deps/mruby/src/proc.c | 294 + web/server/h2o/libh2o/deps/mruby/src/range.c | 442 + web/server/h2o/libh2o/deps/mruby/src/state.c | 303 + web/server/h2o/libh2o/deps/mruby/src/string.c | 3013 +++ web/server/h2o/libh2o/deps/mruby/src/symbol.c | 494 + web/server/h2o/libh2o/deps/mruby/src/value_array.h | 27 + web/server/h2o/libh2o/deps/mruby/src/variable.c | 987 + web/server/h2o/libh2o/deps/mruby/src/version.c | 17 + web/server/h2o/libh2o/deps/mruby/src/vm.c | 2909 ++ .../h2o/libh2o/deps/mruby/tasks/benchmark.rake | 91 + web/server/h2o/libh2o/deps/mruby/tasks/gitlab.rake | 118 + .../h2o/libh2o/deps/mruby/tasks/libmruby.rake | 24 + .../h2o/libh2o/deps/mruby/tasks/mrbgems.rake | 96 + .../deps/mruby/tasks/toolchains/android.rake | 321 + .../libh2o/deps/mruby/tasks/toolchains/clang.rake | 9 + .../libh2o/deps/mruby/tasks/toolchains/gcc.rake | 58 + .../deps/mruby/tasks/toolchains/openwrt.rake | 38 + .../deps/mruby/tasks/toolchains/visualcpp.rake | 68 + web/server/h2o/libh2o/deps/mruby/test/assert.rb | 248 + web/server/h2o/libh2o/deps/mruby/test/bintest.rb | 33 + web/server/h2o/libh2o/deps/mruby/test/report.rb | 4 + .../h2o/libh2o/deps/mruby/test/t/argumenterror.rb | 16 + web/server/h2o/libh2o/deps/mruby/test/t/array.rb | 394 + .../h2o/libh2o/deps/mruby/test/t/basicobject.rb | 11 + .../h2o/libh2o/deps/mruby/test/t/bs_block.rb | 521 + .../h2o/libh2o/deps/mruby/test/t/bs_literal.rb | 38 + web/server/h2o/libh2o/deps/mruby/test/t/class.rb | 451 + web/server/h2o/libh2o/deps/mruby/test/t/codegen.rb | 197 + .../h2o/libh2o/deps/mruby/test/t/comparable.rb | 80 + web/server/h2o/libh2o/deps/mruby/test/t/ensure.rb | 54 + .../h2o/libh2o/deps/mruby/test/t/enumerable.rb | 134 + .../h2o/libh2o/deps/mruby/test/t/exception.rb | 422 + web/server/h2o/libh2o/deps/mruby/test/t/false.rb | 31 + web/server/h2o/libh2o/deps/mruby/test/t/float.rb | 205 + web/server/h2o/libh2o/deps/mruby/test/t/gc.rb | 45 + web/server/h2o/libh2o/deps/mruby/test/t/hash.rb | 375 + .../h2o/libh2o/deps/mruby/test/t/indexerror.rb | 6 + web/server/h2o/libh2o/deps/mruby/test/t/integer.rb | 268 + .../h2o/libh2o/deps/mruby/test/t/iterations.rb | 61 + web/server/h2o/libh2o/deps/mruby/test/t/kernel.rb | 643 + web/server/h2o/libh2o/deps/mruby/test/t/lang.rb | 74 + .../h2o/libh2o/deps/mruby/test/t/literals.rb | 337 + .../h2o/libh2o/deps/mruby/test/t/localjumperror.rb | 13 + web/server/h2o/libh2o/deps/mruby/test/t/methods.rb | 109 + web/server/h2o/libh2o/deps/mruby/test/t/module.rb | 914 + .../h2o/libh2o/deps/mruby/test/t/nameerror.rb | 28 + web/server/h2o/libh2o/deps/mruby/test/t/nil.rb | 39 + .../h2o/libh2o/deps/mruby/test/t/nomethoderror.rb | 22 + web/server/h2o/libh2o/deps/mruby/test/t/numeric.rb | 43 + web/server/h2o/libh2o/deps/mruby/test/t/object.rb | 11 + web/server/h2o/libh2o/deps/mruby/test/t/proc.rb | 180 + web/server/h2o/libh2o/deps/mruby/test/t/range.rb | 95 + .../h2o/libh2o/deps/mruby/test/t/rangeerror.rb | 6 + .../h2o/libh2o/deps/mruby/test/t/regexperror.rb | 4 + .../h2o/libh2o/deps/mruby/test/t/runtimeerror.rb | 6 + .../h2o/libh2o/deps/mruby/test/t/standarderror.rb | 6 + web/server/h2o/libh2o/deps/mruby/test/t/string.rb | 727 + .../h2o/libh2o/deps/mruby/test/t/superclass.rb | 47 + web/server/h2o/libh2o/deps/mruby/test/t/symbol.rb | 30 + web/server/h2o/libh2o/deps/mruby/test/t/syntax.rb | 468 + web/server/h2o/libh2o/deps/mruby/test/t/true.rb | 31 + .../h2o/libh2o/deps/mruby/test/t/typeerror.rb | 6 + web/server/h2o/libh2o/deps/mruby/test/t/unicode.rb | 39 + web/server/h2o/libh2o/deps/mruby/travis_config.rb | 53 + .../h2o/libh2o/deps/neverbleed/.clang-format | 7 + web/server/h2o/libh2o/deps/neverbleed/.gitignore | 32 + web/server/h2o/libh2o/deps/neverbleed/LICENSE | 22 + web/server/h2o/libh2o/deps/neverbleed/README.md | 70 + web/server/h2o/libh2o/deps/neverbleed/neverbleed.c | 1521 ++ web/server/h2o/libh2o/deps/neverbleed/neverbleed.h | 61 + web/server/h2o/libh2o/deps/neverbleed/test.c | 149 + .../h2o/libh2o/deps/picohttpparser/.clang-format | 7 + .../h2o/libh2o/deps/picohttpparser/.gitattributes | 1 + .../h2o/libh2o/deps/picohttpparser/.gitmodules | 3 + .../h2o/libh2o/deps/picohttpparser/.travis.yml | 6 + web/server/h2o/libh2o/deps/picohttpparser/Jamfile | 7 + web/server/h2o/libh2o/deps/picohttpparser/Makefile | 40 + .../h2o/libh2o/deps/picohttpparser/README.md | 116 + web/server/h2o/libh2o/deps/picohttpparser/bench.c | 66 + .../libh2o/deps/picohttpparser/picohttpparser.c | 620 + .../libh2o/deps/picohttpparser/picohttpparser.h | 89 + web/server/h2o/libh2o/deps/picohttpparser/test.c | 419 + web/server/h2o/libh2o/deps/picotest/picotest.c | 99 + web/server/h2o/libh2o/deps/picotest/picotest.h | 39 + web/server/h2o/libh2o/deps/picotls/.clang-format | 7 + web/server/h2o/libh2o/deps/picotls/.gitignore | 24 + web/server/h2o/libh2o/deps/picotls/.gitmodules | 3 + web/server/h2o/libh2o/deps/picotls/.travis.yml | 17 + web/server/h2o/libh2o/deps/picotls/CMakeLists.txt | 51 + web/server/h2o/libh2o/deps/picotls/README.md | 78 + web/server/h2o/libh2o/deps/picotls/WindowsPort.md | 34 + .../h2o/libh2o/deps/picotls/deps/cifra/.travis.yml | 29 + .../h2o/libh2o/deps/picotls/deps/cifra/COPYING | 121 + .../h2o/libh2o/deps/picotls/deps/cifra/README.md | 246 + .../deps/picotls/deps/cifra/curve25519-shootout.md | 16 + .../libh2o/deps/picotls/deps/cifra/doc/Makefile | 3 + .../libh2o/deps/picotls/deps/cifra/doc/build.py | 274 + .../h2o/libh2o/deps/picotls/deps/cifra/doc/conf.py | 263 + .../libh2o/deps/picotls/deps/cifra/doc/index.rst | 33 + .../deps/picotls/deps/cifra/extra_vecs/.gitignore | 1 + .../deps/picotls/deps/cifra/extra_vecs/Makefile | 13 + .../deps/picotls/deps/cifra/extra_vecs/README.md | 2 + .../picotls/deps/cifra/extra_vecs/openssl-hash.c | 60 + .../picotls/deps/cifra/extra_vecs/python-hash.py | 38 + .../deps/picotls/deps/cifra/shitlisp/.gitignore | 5 + .../deps/picotls/deps/cifra/shitlisp/Makefile | 17 + .../deps/picotls/deps/cifra/shitlisp/sl-cifra.c | 206 + .../deps/picotls/deps/cifra/shitlisp/test-aes.sl | 91 + .../picotls/deps/cifra/shitlisp/test-pbkdf2.sl | 36 + .../picotls/deps/cifra/shitlisp/test-sha224.sl | 41 + .../picotls/deps/cifra/shitlisp/test-sha256.sl | 62 + .../picotls/deps/cifra/shitlisp/test-sha384.sl | 67 + .../picotls/deps/cifra/shitlisp/test-sha512.sl | 67 + .../libh2o/deps/picotls/deps/cifra/src/.gitignore | 15 + .../libh2o/deps/picotls/deps/cifra/src/Makefile | 54 + .../h2o/libh2o/deps/picotls/deps/cifra/src/aes.c | 419 + .../h2o/libh2o/deps/picotls/deps/cifra/src/aes.h | 152 + .../deps/picotls/deps/cifra/src/arm/.gitignore | 3 + .../deps/picotls/deps/cifra/src/arm/Makefile | 184 + .../deps/picotls/deps/cifra/src/arm/analyse.py | 207 + .../libh2o/deps/picotls/deps/cifra/src/arm/boot.c | 144 + .../deps/cifra/src/arm/curve25519-results.txt | 22 + .../deps/picotls/deps/cifra/src/arm/ext/cutest.h | 55 + .../picotls/deps/cifra/src/arm/linkscript.efm32.ld | 8 + .../deps/cifra/src/arm/linkscript.lm3s6965evb.ld | 7 + .../deps/cifra/src/arm/linkscript.qemucm3.ld | 8 + .../picotls/deps/cifra/src/arm/linkscript.std.ld | 172 + .../deps/cifra/src/arm/linkscript.stm32f0.ld | 8 + .../deps/cifra/src/arm/linkscript.stm32f1.ld | 8 + .../deps/cifra/src/arm/linkscript.stm32f3.ld | 8 + .../libh2o/deps/picotls/deps/cifra/src/arm/main.c | 447 + .../deps/picotls/deps/cifra/src/arm/memcpy.s | 49 + .../deps/picotls/deps/cifra/src/arm/memset.s | 50 + .../deps/picotls/deps/cifra/src/arm/merge.py | 26 + .../picotls/deps/cifra/src/arm/openocd.efm32.cfg | 3 + .../picotls/deps/cifra/src/arm/openocd.stm32f0.cfg | 3 + .../picotls/deps/cifra/src/arm/openocd.stm32f1.cfg | 3 + .../picotls/deps/cifra/src/arm/openocd.stm32f3.cfg | 3 + .../deps/picotls/deps/cifra/src/arm/report.py | 276 + .../deps/picotls/deps/cifra/src/arm/semihost.c | 170 + .../deps/picotls/deps/cifra/src/arm/semihost.h | 40 + .../deps/picotls/deps/cifra/src/arm/semihost.s | 15 + .../deps/cifra/src/arm/unacl/cortex_m0_mpy121666.s | 199 + .../cifra/src/arm/unacl/cortex_m0_reduce25519.s | 176 + .../deps/picotls/deps/cifra/src/arm/unacl/mul.s | 1109 + .../picotls/deps/cifra/src/arm/unacl/scalarmult.c | 761 + .../deps/picotls/deps/cifra/src/arm/unacl/sqr.s | 777 + .../libh2o/deps/picotls/deps/cifra/src/bitops.h | 310 + .../libh2o/deps/picotls/deps/cifra/src/blockwise.c | 195 + .../libh2o/deps/picotls/deps/cifra/src/blockwise.h | 147 + .../libh2o/deps/picotls/deps/cifra/src/cbcmac.c | 79 + .../h2o/libh2o/deps/picotls/deps/cifra/src/ccm.c | 193 + .../libh2o/deps/picotls/deps/cifra/src/cf_config.h | 59 + .../libh2o/deps/picotls/deps/cifra/src/chacha20.c | 161 + .../deps/picotls/deps/cifra/src/chacha20poly1305.c | 148 + .../deps/picotls/deps/cifra/src/chacha20poly1305.h | 73 + .../h2o/libh2o/deps/picotls/deps/cifra/src/chash.c | 28 + .../h2o/libh2o/deps/picotls/deps/cifra/src/chash.h | 137 + .../h2o/libh2o/deps/picotls/deps/cifra/src/cmac.c | 150 + .../deps/picotls/deps/cifra/src/curve25519.c | 29 + .../deps/picotls/deps/cifra/src/curve25519.donna.c | 867 + .../deps/picotls/deps/cifra/src/curve25519.h | 42 + .../picotls/deps/cifra/src/curve25519.naclref.c | 273 + .../picotls/deps/cifra/src/curve25519.tweetnacl.c | 235 + .../h2o/libh2o/deps/picotls/deps/cifra/src/drbg.c | 434 + .../h2o/libh2o/deps/picotls/deps/cifra/src/drbg.h | 191 + .../h2o/libh2o/deps/picotls/deps/cifra/src/eax.c | 116 + .../deps/picotls/deps/cifra/src/ext/cutest.h | 620 + .../libh2o/deps/picotls/deps/cifra/src/ext/handy.h | 66 + .../h2o/libh2o/deps/picotls/deps/cifra/src/gcm.c | 249 + .../h2o/libh2o/deps/picotls/deps/cifra/src/gf128.c | 114 + .../h2o/libh2o/deps/picotls/deps/cifra/src/gf128.h | 55 + .../h2o/libh2o/deps/picotls/deps/cifra/src/hmac.c | 106 + .../h2o/libh2o/deps/picotls/deps/cifra/src/hmac.h | 78 + .../h2o/libh2o/deps/picotls/deps/cifra/src/modes.c | 99 + .../h2o/libh2o/deps/picotls/deps/cifra/src/modes.h | 587 + .../h2o/libh2o/deps/picotls/deps/cifra/src/norx.c | 410 + .../h2o/libh2o/deps/picotls/deps/cifra/src/norx.h | 84 + .../h2o/libh2o/deps/picotls/deps/cifra/src/ocb.c | 404 + .../libh2o/deps/picotls/deps/cifra/src/pbkdf2.c | 84 + .../libh2o/deps/picotls/deps/cifra/src/pbkdf2.h | 47 + .../libh2o/deps/picotls/deps/cifra/src/poly1305.c | 221 + .../libh2o/deps/picotls/deps/cifra/src/poly1305.h | 91 + .../libh2o/deps/picotls/deps/cifra/src/poly1305.py | 127 + .../h2o/libh2o/deps/picotls/deps/cifra/src/prp.h | 64 + .../libh2o/deps/picotls/deps/cifra/src/salsa20.c | 164 + .../libh2o/deps/picotls/deps/cifra/src/salsa20.h | 140 + .../h2o/libh2o/deps/picotls/deps/cifra/src/sha1.c | 150 + .../h2o/libh2o/deps/picotls/deps/cifra/src/sha1.h | 91 + .../h2o/libh2o/deps/picotls/deps/cifra/src/sha2.h | 235 + .../libh2o/deps/picotls/deps/cifra/src/sha256.c | 232 + .../h2o/libh2o/deps/picotls/deps/cifra/src/sha3.c | 444 + .../h2o/libh2o/deps/picotls/deps/cifra/src/sha3.h | 180 + .../libh2o/deps/picotls/deps/cifra/src/sha512.c | 248 + .../libh2o/deps/picotls/deps/cifra/src/tassert.h | 32 + .../libh2o/deps/picotls/deps/cifra/src/testaes.c | 258 + .../picotls/deps/cifra/src/testchacha20poly1305.c | 91 + .../deps/picotls/deps/cifra/src/testcurve25519.c | 56 + .../libh2o/deps/picotls/deps/cifra/src/testdrbg.c | 206 + .../libh2o/deps/picotls/deps/cifra/src/testmodes.c | 890 + .../libh2o/deps/picotls/deps/cifra/src/testnorx.c | 118 + .../picotls/deps/cifra/src/testnorx.katdata.inc | 4961 ++++ .../deps/picotls/deps/cifra/src/testpoly1305.c | 102 + .../deps/picotls/deps/cifra/src/testsalsa20.c | 210 + .../libh2o/deps/picotls/deps/cifra/src/testsha.h | 213 + .../libh2o/deps/picotls/deps/cifra/src/testsha1.c | 55 + .../libh2o/deps/picotls/deps/cifra/src/testsha2.c | 224 + .../libh2o/deps/picotls/deps/cifra/src/testsha3.c | 104 + .../libh2o/deps/picotls/deps/cifra/src/testutil.h | 61 + .../libh2o/deps/picotls/deps/micro-ecc/.gitignore | 8 + .../libh2o/deps/picotls/deps/micro-ecc/LICENSE.txt | 21 + .../libh2o/deps/picotls/deps/micro-ecc/README.md | 41 + .../libh2o/deps/picotls/deps/micro-ecc/asm_arm.inc | 820 + .../picotls/deps/micro-ecc/asm_arm_mult_square.inc | 2311 ++ .../deps/micro-ecc/asm_arm_mult_square_umaal.inc | 1202 + .../libh2o/deps/picotls/deps/micro-ecc/asm_avr.inc | 1089 + .../picotls/deps/micro-ecc/asm_avr_mult_square.inc | 26311 +++++++++++++++++++ .../deps/picotls/deps/micro-ecc/curve-specific.inc | 1248 + .../deps/picotls/deps/micro-ecc/emk_project.py | 127 + .../deps/picotls/deps/micro-ecc/emk_rules.py | 3 + .../picotls/deps/micro-ecc/platform-specific.inc | 67 + .../picotls/deps/micro-ecc/scripts/mult_arm.py | 188 + .../picotls/deps/micro-ecc/scripts/mult_avr.py | 203 + .../deps/micro-ecc/scripts/mult_avr_extra.py | 143 + .../picotls/deps/micro-ecc/scripts/square_arm.py | 242 + .../picotls/deps/micro-ecc/scripts/square_avr.py | 327 + .../deps/micro-ecc/test/ecc_test/ecc_test.ino | 85 + .../deps/picotls/deps/micro-ecc/test/emk_rules.py | 4 + .../picotls/deps/micro-ecc/test/test_compress.c | 79 + .../picotls/deps/micro-ecc/test/test_compute.c | 81 + .../deps/picotls/deps/micro-ecc/test/test_ecdh.c | 90 + .../deps/picotls/deps/micro-ecc/test/test_ecdsa.c | 59 + .../test/test_ecdsa_deterministic.c.example | 93 + .../h2o/libh2o/deps/picotls/deps/micro-ecc/types.h | 108 + .../h2o/libh2o/deps/picotls/deps/micro-ecc/uECC.c | 1634 ++ .../h2o/libh2o/deps/picotls/deps/micro-ecc/uECC.h | 362 + .../libh2o/deps/picotls/deps/micro-ecc/uECC_vli.h | 172 + .../h2o/libh2o/deps/picotls/include/picotls.h | 998 + .../h2o/libh2o/deps/picotls/include/picotls/asn1.h | 64 + .../deps/picotls/include/picotls/minicrypto.h | 61 + .../libh2o/deps/picotls/include/picotls/openssl.h | 85 + .../deps/picotls/include/picotls/pembase64.h | 44 + web/server/h2o/libh2o/deps/picotls/lib/asn1.c | 295 + web/server/h2o/libh2o/deps/picotls/lib/cifra.c | 530 + .../h2o/libh2o/deps/picotls/lib/minicrypto-pem.c | 339 + web/server/h2o/libh2o/deps/picotls/lib/openssl.c | 1066 + web/server/h2o/libh2o/deps/picotls/lib/pembase64.c | 373 + web/server/h2o/libh2o/deps/picotls/lib/picotls.c | 3761 +++ web/server/h2o/libh2o/deps/picotls/lib/uecc.c | 190 + .../deps/picotls/misc/dump-github-repository.pl | 41 + .../deps/picotls/picotls.xcodeproj/project.pbxproj | 1023 + .../project.xcworkspace/contents.xcworkspacedata | 7 + .../libh2o/deps/picotls/picotlsvs/cifra/ReadMe.txt | 29 + .../deps/picotls/picotlsvs/cifra/cifra.vcxproj | 188 + .../picotls/picotlsvs/cifra/cifra.vcxproj.filters | 150 + .../deps/picotls/picotlsvs/microecc/ReadMe.txt | 29 + .../picotls/picotlsvs/microecc/microecc.vcxproj | 140 + .../picotlsvs/microecc/microecc.vcxproj.filters | 25 + .../h2o/libh2o/deps/picotls/picotlsvs/openssl.cnf | 35 + .../deps/picotls/picotlsvs/picotls/ReadMe.txt | 37 + .../deps/picotls/picotlsvs/picotls/picotls.vcxproj | 175 + .../picotlsvs/picotls/picotls.vcxproj.filters | 123 + .../picotls/picotlsvs/picotls/picotls.vcxproj.user | 4 + .../deps/picotls/picotlsvs/picotls/targetver.h | 8 + .../deps/picotls/picotlsvs/picotls/wincompat.h | 35 + .../deps/picotls/picotlsvs/picotls/wintimeofday.c | 73 + .../libh2o/deps/picotls/picotlsvs/picotlsvs.sln | 78 + .../deps/picotls/picotlsvs/picotlsvs/ReadMe.txt | 40 + .../deps/picotls/picotlsvs/picotlsvs/cert.pem | 20 + .../deps/picotls/picotlsvs/picotlsvs/ec_cert.pem | 14 + .../deps/picotls/picotlsvs/picotlsvs/ec_key.pem | 5 + .../picotls/picotlsvs/picotlsvs/key-test-1.pem | 5 + .../picotls/picotlsvs/picotlsvs/key-test-2.pem | 9 + .../picotls/picotlsvs/picotlsvs/key-test-3.pem | 5 + .../picotls/picotlsvs/picotlsvs/key-test-4.pem | 5 + .../deps/picotls/picotlsvs/picotlsvs/key.pem | 28 + .../deps/picotls/picotlsvs/picotlsvs/myec1.pem | 5 + .../deps/picotls/picotlsvs/picotlsvs/openssl.cnf | 35 + .../deps/picotls/picotlsvs/picotlsvs/picotlsvs.c | 674 + .../picotls/picotlsvs/picotlsvs/picotlsvs.vcxproj | 161 + .../picotlsvs/picotlsvs/picotlsvs.vcxproj.filters | 30 + .../picotlsvs/picotlsvs/picotlsvs.vcxproj.user | 4 + .../deps/picotls/picotlsvs/picotlsvs/targetver.h | 8 + .../picotlsvs/testopenssl/testopenssl.vcxproj | 168 + .../testopenssl/testopenssl.vcxproj.filters | 41 + web/server/h2o/libh2o/deps/picotls/t/cli.c | 392 + web/server/h2o/libh2o/deps/picotls/t/minicrypto.c | 165 + web/server/h2o/libh2o/deps/picotls/t/openssl.c | 227 + web/server/h2o/libh2o/deps/picotls/t/picotls.c | 843 + web/server/h2o/libh2o/deps/picotls/t/test.h | 52 + web/server/h2o/libh2o/deps/picotls/t/util.h | 240 + .../libh2o/deps/ssl-conservatory/.gitattributes | 5 + .../h2o/libh2o/deps/ssl-conservatory/.gitignore | 34 + .../h2o/libh2o/deps/ssl-conservatory/LICENSE | 19 + .../h2o/libh2o/deps/ssl-conservatory/README.md | 28 + .../h2o/libh2o/deps/ssl-conservatory/ios/README.md | 89 + .../project.pbxproj | 456 + .../SSLCertificatePinning/ISPCertificatePinning.h | 62 + .../SSLCertificatePinning/ISPCertificatePinning.m | 112 + .../ISPPinnedNSURLConnectionDelegate.h | 23 + .../ISPPinnedNSURLConnectionDelegate.m | 49 + .../ISPPinnedNSURLSessionDelegate.h | 23 + .../ISPPinnedNSURLSessionDelegate.m | 47 + .../SSLCertificatePinning-Prefix.pch | 9 + .../NSURLConnectionTests.m | 154 + .../SSLCertificatePinningTests/NSURLSessionTests.m | 145 + .../SSLCertificatePinningTests-Info.plist | 22 + .../SSLPinsTestUtility.h | 15 + .../SSLPinsTestUtility.m | 57 + ...lass3PublicPrimaryCertificationAuthority-G5.der | Bin 0 -> 1239 bytes .../en.lproj/InfoPlist.strings | 2 + .../www.isecpartners.com.der | Bin 0 -> 1876 bytes .../openssl/DigiCertHighAssuranceEVRootCA.pem | 23 + .../libh2o/deps/ssl-conservatory/openssl/Makefile | 12 + .../deps/ssl-conservatory/openssl/Makefile_mingw | 18 + .../libh2o/deps/ssl-conservatory/openssl/README.md | 61 + ...everything-you-wanted-to-know-about-openssl.pdf | Bin 0 -> 180899 bytes .../openssl/openssl_hostname_validation.c | 181 + .../openssl/openssl_hostname_validation.h | 40 + .../deps/ssl-conservatory/openssl/test_client | Bin 0 -> 15680 bytes .../deps/ssl-conservatory/openssl/test_client.c | 142 + web/server/h2o/libh2o/deps/yaml/CMakeLists.txt | 16 + web/server/h2o/libh2o/deps/yaml/LICENSE | 19 + web/server/h2o/libh2o/deps/yaml/Makefile.am | 18 + web/server/h2o/libh2o/deps/yaml/Makefile.in | 810 + web/server/h2o/libh2o/deps/yaml/README | 27 + web/server/h2o/libh2o/deps/yaml/aclocal.m4 | 9577 +++++++ web/server/h2o/libh2o/deps/yaml/config.h.in | 80 + .../h2o/libh2o/deps/yaml/config/config.guess | 1530 ++ web/server/h2o/libh2o/deps/yaml/config/config.sub | 1773 ++ web/server/h2o/libh2o/deps/yaml/config/depcomp | 688 + web/server/h2o/libh2o/deps/yaml/config/install-sh | 527 + web/server/h2o/libh2o/deps/yaml/config/ltmain.sh | 9661 +++++++ web/server/h2o/libh2o/deps/yaml/config/missing | 331 + web/server/h2o/libh2o/deps/yaml/configure | 14029 ++++++++++ web/server/h2o/libh2o/deps/yaml/configure.ac | 73 + web/server/h2o/libh2o/deps/yaml/doc/doxygen.cfg | 222 + .../h2o/libh2o/deps/yaml/doc/html/annotated.html | 83 + web/server/h2o/libh2o/deps/yaml/doc/html/bc_s.png | Bin 0 -> 677 bytes .../h2o/libh2o/deps/yaml/doc/html/classes.html | 78 + .../h2o/libh2o/deps/yaml/doc/html/closed.png | Bin 0 -> 126 bytes .../h2o/libh2o/deps/yaml/doc/html/doxygen.css | 949 + .../h2o/libh2o/deps/yaml/doc/html/doxygen.png | Bin 0 -> 3942 bytes .../h2o/libh2o/deps/yaml/doc/html/files.html | 72 + .../h2o/libh2o/deps/yaml/doc/html/functions.html | 123 + .../libh2o/deps/yaml/doc/html/functions_0x62.html | 116 + .../libh2o/deps/yaml/doc/html/functions_0x63.html | 119 + .../libh2o/deps/yaml/doc/html/functions_0x64.html | 115 + .../libh2o/deps/yaml/doc/html/functions_0x65.html | 142 + .../libh2o/deps/yaml/doc/html/functions_0x66.html | 111 + .../libh2o/deps/yaml/doc/html/functions_0x68.html | 112 + .../libh2o/deps/yaml/doc/html/functions_0x69.html | 124 + .../libh2o/deps/yaml/doc/html/functions_0x6b.html | 103 + .../libh2o/deps/yaml/doc/html/functions_0x6c.html | 120 + .../libh2o/deps/yaml/doc/html/functions_0x6d.html | 128 + .../libh2o/deps/yaml/doc/html/functions_0x6e.html | 103 + .../libh2o/deps/yaml/doc/html/functions_0x6f.html | 112 + .../libh2o/deps/yaml/doc/html/functions_0x70.html | 132 + .../libh2o/deps/yaml/doc/html/functions_0x71.html | 103 + .../libh2o/deps/yaml/doc/html/functions_0x72.html | 119 + .../libh2o/deps/yaml/doc/html/functions_0x73.html | 195 + .../libh2o/deps/yaml/doc/html/functions_0x74.html | 147 + .../libh2o/deps/yaml/doc/html/functions_0x75.html | 103 + .../libh2o/deps/yaml/doc/html/functions_0x76.html | 112 + .../libh2o/deps/yaml/doc/html/functions_0x77.html | 109 + .../libh2o/deps/yaml/doc/html/functions_vars.html | 123 + .../deps/yaml/doc/html/functions_vars_0x62.html | 116 + .../deps/yaml/doc/html/functions_vars_0x63.html | 119 + .../deps/yaml/doc/html/functions_vars_0x64.html | 115 + .../deps/yaml/doc/html/functions_vars_0x65.html | 142 + .../deps/yaml/doc/html/functions_vars_0x66.html | 111 + .../deps/yaml/doc/html/functions_vars_0x68.html | 112 + .../deps/yaml/doc/html/functions_vars_0x69.html | 124 + .../deps/yaml/doc/html/functions_vars_0x6b.html | 103 + .../deps/yaml/doc/html/functions_vars_0x6c.html | 120 + .../deps/yaml/doc/html/functions_vars_0x6d.html | 128 + .../deps/yaml/doc/html/functions_vars_0x6e.html | 103 + .../deps/yaml/doc/html/functions_vars_0x6f.html | 112 + .../deps/yaml/doc/html/functions_vars_0x70.html | 132 + .../deps/yaml/doc/html/functions_vars_0x71.html | 103 + .../deps/yaml/doc/html/functions_vars_0x72.html | 119 + .../deps/yaml/doc/html/functions_vars_0x73.html | 195 + .../deps/yaml/doc/html/functions_vars_0x74.html | 147 + .../deps/yaml/doc/html/functions_vars_0x75.html | 103 + .../deps/yaml/doc/html/functions_vars_0x76.html | 112 + .../deps/yaml/doc/html/functions_vars_0x77.html | 109 + .../h2o/libh2o/deps/yaml/doc/html/globals.html | 699 + .../libh2o/deps/yaml/doc/html/globals_defs.html | 113 + .../libh2o/deps/yaml/doc/html/globals_enum.html | 110 + .../libh2o/deps/yaml/doc/html/globals_eval.html | 405 + .../libh2o/deps/yaml/doc/html/globals_func.html | 228 + .../libh2o/deps/yaml/doc/html/globals_type.html | 158 + .../libh2o/deps/yaml/doc/html/group__basic.html | 349 + .../libh2o/deps/yaml/doc/html/group__emitter.html | 845 + .../libh2o/deps/yaml/doc/html/group__events.html | 691 + .../libh2o/deps/yaml/doc/html/group__export.html | 91 + .../libh2o/deps/yaml/doc/html/group__nodes.html | 824 + .../libh2o/deps/yaml/doc/html/group__parser.html | 635 + .../libh2o/deps/yaml/doc/html/group__styles.html | 251 + .../libh2o/deps/yaml/doc/html/group__tokens.html | 276 + .../libh2o/deps/yaml/doc/html/group__version.html | 137 + .../h2o/libh2o/deps/yaml/doc/html/index.html | 63 + .../h2o/libh2o/deps/yaml/doc/html/modules.html | 74 + web/server/h2o/libh2o/deps/yaml/doc/html/nav_f.png | Bin 0 -> 159 bytes web/server/h2o/libh2o/deps/yaml/doc/html/nav_h.png | Bin 0 -> 97 bytes web/server/h2o/libh2o/deps/yaml/doc/html/open.png | Bin 0 -> 118 bytes .../yaml/doc/html/structyaml__alias__data__s.html | 137 + .../yaml/doc/html/structyaml__document__s.html | 264 + .../deps/yaml/doc/html/structyaml__emitter__s.html | 1321 + .../deps/yaml/doc/html/structyaml__event__s.html | 525 + .../deps/yaml/doc/html/structyaml__mark__s.html | 137 + .../yaml/doc/html/structyaml__node__pair__s.html | 120 + .../deps/yaml/doc/html/structyaml__node__s.html | 449 + .../deps/yaml/doc/html/structyaml__parser__s.html | 1248 + .../yaml/doc/html/structyaml__simple__key__s.html | 126 + .../doc/html/structyaml__tag__directive__s.html | 120 + .../deps/yaml/doc/html/structyaml__token__s.html | 442 + .../html/structyaml__version__directive__s.html | 120 + web/server/h2o/libh2o/deps/yaml/doc/html/tab_a.png | Bin 0 -> 140 bytes web/server/h2o/libh2o/deps/yaml/doc/html/tab_b.png | Bin 0 -> 178 bytes web/server/h2o/libh2o/deps/yaml/doc/html/tab_h.png | Bin 0 -> 192 bytes web/server/h2o/libh2o/deps/yaml/doc/html/tab_s.png | Bin 0 -> 189 bytes web/server/h2o/libh2o/deps/yaml/doc/html/tabs.css | 59 + .../h2o/libh2o/deps/yaml/doc/html/yaml_8h.html | 546 + .../h2o/libh2o/deps/yaml/include/Makefile.am | 17 + .../h2o/libh2o/deps/yaml/include/Makefile.in | 481 + web/server/h2o/libh2o/deps/yaml/include/yaml.h | 1961 ++ web/server/h2o/libh2o/deps/yaml/src/Makefile.am | 4 + web/server/h2o/libh2o/deps/yaml/src/Makefile.in | 542 + web/server/h2o/libh2o/deps/yaml/src/api.c | 1392 + web/server/h2o/libh2o/deps/yaml/src/dumper.c | 394 + web/server/h2o/libh2o/deps/yaml/src/emitter.c | 2329 ++ web/server/h2o/libh2o/deps/yaml/src/loader.c | 444 + web/server/h2o/libh2o/deps/yaml/src/parser.c | 1374 + web/server/h2o/libh2o/deps/yaml/src/reader.c | 469 + web/server/h2o/libh2o/deps/yaml/src/scanner.c | 3583 +++ web/server/h2o/libh2o/deps/yaml/src/writer.c | 141 + web/server/h2o/libh2o/deps/yaml/src/yaml_private.h | 661 + web/server/h2o/libh2o/deps/yaml/tests/Makefile.am | 8 + web/server/h2o/libh2o/deps/yaml/tests/Makefile.in | 680 + .../deps/yaml/tests/example-deconstructor-alt.c | 800 + .../libh2o/deps/yaml/tests/example-deconstructor.c | 1130 + .../deps/yaml/tests/example-reformatter-alt.c | 217 + .../libh2o/deps/yaml/tests/example-reformatter.c | 202 + web/server/h2o/libh2o/deps/yaml/tests/run-dumper.c | 311 + .../h2o/libh2o/deps/yaml/tests/run-emitter.c | 327 + web/server/h2o/libh2o/deps/yaml/tests/run-loader.c | 63 + web/server/h2o/libh2o/deps/yaml/tests/run-parser.c | 63 + .../h2o/libh2o/deps/yaml/tests/run-scanner.c | 63 + .../h2o/libh2o/deps/yaml/tests/test-reader.c | 354 + .../h2o/libh2o/deps/yaml/tests/test-version.c | 29 + web/server/h2o/libh2o/deps/yaml/win32/Makefile.am | 24 + web/server/h2o/libh2o/deps/yaml/win32/Makefile.in | 381 + web/server/h2o/libh2o/deps/yaml/win32/config.h | 4 + .../deps/yaml/win32/vc6/example_deconstructor.dsp | 102 + .../yaml/win32/vc6/example_deconstructor_alt.dsp | 102 + .../deps/yaml/win32/vc6/example_reformatter.dsp | 102 + .../yaml/win32/vc6/example_reformatter_alt.dsp | 102 + .../h2o/libh2o/deps/yaml/win32/vc6/libyaml.dsw | 206 + .../h2o/libh2o/deps/yaml/win32/vc6/run_dumper.dsp | 102 + .../h2o/libh2o/deps/yaml/win32/vc6/run_emitter.dsp | 102 + .../h2o/libh2o/deps/yaml/win32/vc6/run_loader.dsp | 102 + .../h2o/libh2o/deps/yaml/win32/vc6/run_parser.dsp | 102 + .../h2o/libh2o/deps/yaml/win32/vc6/run_scanner.dsp | 102 + .../h2o/libh2o/deps/yaml/win32/vc6/test_reader.dsp | 102 + .../libh2o/deps/yaml/win32/vc6/test_version.dsp | 102 + web/server/h2o/libh2o/deps/yaml/win32/vc6/yaml.dsp | 136 + .../h2o/libh2o/deps/yaml/win32/vc6/yamldll.dsp | 147 + .../yaml/win32/vs2003/example_deconstructor.vcproj | 134 + .../win32/vs2003/example_deconstructor_alt.vcproj | 134 + .../yaml/win32/vs2003/example_reformatter.vcproj | 134 + .../win32/vs2003/example_reformatter_alt.vcproj | 134 + .../h2o/libh2o/deps/yaml/win32/vs2003/libyaml.sln | 128 + .../deps/yaml/win32/vs2003/run_dumper.vcproj | 134 + .../deps/yaml/win32/vs2003/run_emitter.vcproj | 134 + .../deps/yaml/win32/vs2003/run_loader.vcproj | 134 + .../deps/yaml/win32/vs2003/run_parser.vcproj | 134 + .../deps/yaml/win32/vs2003/run_scanner.vcproj | 134 + .../deps/yaml/win32/vs2003/test_reader.vcproj | 134 + .../deps/yaml/win32/vs2003/test_version.vcproj | 134 + .../h2o/libh2o/deps/yaml/win32/vs2003/yaml.vcproj | 149 + .../libh2o/deps/yaml/win32/vs2003/yamldll.vcproj | 166 + .../yaml/win32/vs2008/example_deconstructor.vcproj | 201 + .../win32/vs2008/example_deconstructor_alt.vcproj | 201 + .../yaml/win32/vs2008/example_reformatter.vcproj | 201 + .../win32/vs2008/example_reformatter_alt.vcproj | 201 + .../h2o/libh2o/deps/yaml/win32/vs2008/libyaml.sln | 124 + .../deps/yaml/win32/vs2008/run_dumper.vcproj | 201 + .../deps/yaml/win32/vs2008/run_emitter.vcproj | 201 + .../deps/yaml/win32/vs2008/run_loader.vcproj | 201 + .../deps/yaml/win32/vs2008/run_parser.vcproj | 201 + .../deps/yaml/win32/vs2008/run_scanner.vcproj | 201 + .../deps/yaml/win32/vs2008/test_reader.vcproj | 201 + .../deps/yaml/win32/vs2008/test_version.vcproj | 201 + .../h2o/libh2o/deps/yaml/win32/vs2008/yaml.vcproj | 215 + .../libh2o/deps/yaml/win32/vs2008/yamldll.vcproj | 243 + web/server/h2o/libh2o/deps/yaml/yaml-0.1.pc.in | 10 + web/server/h2o/libh2o/deps/yoml/.gitmodules | 3 + web/server/h2o/libh2o/deps/yoml/Makefile | 3 + web/server/h2o/libh2o/deps/yoml/README.md | 66 + web/server/h2o/libh2o/deps/yoml/test-yoml.c | 278 + web/server/h2o/libh2o/deps/yoml/yoml-parser.h | 391 + web/server/h2o/libh2o/deps/yoml/yoml.h | 148 + 1134 files changed, 370447 insertions(+) create mode 100644 web/server/h2o/libh2o/deps/brotli/.gitignore create mode 100644 web/server/h2o/libh2o/deps/brotli/.gitmodules create mode 100644 web/server/h2o/libh2o/deps/brotli/.travis.yml create mode 100644 web/server/h2o/libh2o/deps/brotli/CONTRIBUTING.md create mode 100644 web/server/h2o/libh2o/deps/brotli/LICENSE create mode 100644 web/server/h2o/libh2o/deps/brotli/README.md create mode 100644 web/server/h2o/libh2o/deps/brotli/appveyor.yml create mode 100644 web/server/h2o/libh2o/deps/brotli/appveyor/install.ps1 create mode 100644 web/server/h2o/libh2o/deps/brotli/appveyor/run_with_compiler.cmd create mode 100644 web/server/h2o/libh2o/deps/brotli/dec/Makefile create mode 100644 web/server/h2o/libh2o/deps/brotli/dec/bit_reader.c create mode 100644 web/server/h2o/libh2o/deps/brotli/dec/bit_reader.h create mode 100644 web/server/h2o/libh2o/deps/brotli/dec/context.h create mode 100644 web/server/h2o/libh2o/deps/brotli/dec/decode.c create mode 100644 web/server/h2o/libh2o/deps/brotli/dec/decode.h create mode 100644 web/server/h2o/libh2o/deps/brotli/dec/dictionary.c create mode 100644 web/server/h2o/libh2o/deps/brotli/dec/dictionary.h create mode 100644 web/server/h2o/libh2o/deps/brotli/dec/huffman.c create mode 100644 web/server/h2o/libh2o/deps/brotli/dec/huffman.h create mode 100644 web/server/h2o/libh2o/deps/brotli/dec/port.h create mode 100644 web/server/h2o/libh2o/deps/brotli/dec/prefix.h create mode 100644 web/server/h2o/libh2o/deps/brotli/dec/state.c create mode 100644 web/server/h2o/libh2o/deps/brotli/dec/state.h create mode 100644 web/server/h2o/libh2o/deps/brotli/dec/transform.h create mode 100644 web/server/h2o/libh2o/deps/brotli/dec/types.h create mode 100644 web/server/h2o/libh2o/deps/brotli/docs/brotli-comparison-study-2015-09-22.pdf create mode 100644 web/server/h2o/libh2o/deps/brotli/docs/draft-alakuijala-brotli-08.nroff create mode 100644 web/server/h2o/libh2o/deps/brotli/docs/draft-alakuijala-brotli-08.txt create mode 100644 web/server/h2o/libh2o/deps/brotli/enc/Makefile create mode 100644 web/server/h2o/libh2o/deps/brotli/enc/backward_references.cc create mode 100644 web/server/h2o/libh2o/deps/brotli/enc/backward_references.h create mode 100644 web/server/h2o/libh2o/deps/brotli/enc/bit_cost.h create mode 100644 web/server/h2o/libh2o/deps/brotli/enc/block_splitter.cc create mode 100644 web/server/h2o/libh2o/deps/brotli/enc/block_splitter.h create mode 100644 web/server/h2o/libh2o/deps/brotli/enc/brotli_bit_stream.cc create mode 100644 web/server/h2o/libh2o/deps/brotli/enc/brotli_bit_stream.h create mode 100644 web/server/h2o/libh2o/deps/brotli/enc/cluster.h create mode 100644 web/server/h2o/libh2o/deps/brotli/enc/command.h create mode 100644 web/server/h2o/libh2o/deps/brotli/enc/compress_fragment.cc create mode 100644 web/server/h2o/libh2o/deps/brotli/enc/compress_fragment.h create mode 100644 web/server/h2o/libh2o/deps/brotli/enc/compress_fragment_two_pass.cc create mode 100644 web/server/h2o/libh2o/deps/brotli/enc/compress_fragment_two_pass.h create mode 100644 web/server/h2o/libh2o/deps/brotli/enc/context.h create mode 100644 web/server/h2o/libh2o/deps/brotli/enc/dictionary.cc create mode 100644 web/server/h2o/libh2o/deps/brotli/enc/dictionary.h create mode 100644 web/server/h2o/libh2o/deps/brotli/enc/dictionary_hash.h create mode 100644 web/server/h2o/libh2o/deps/brotli/enc/encode.cc create mode 100644 web/server/h2o/libh2o/deps/brotli/enc/encode.h create mode 100644 web/server/h2o/libh2o/deps/brotli/enc/encode_parallel.cc create mode 100644 web/server/h2o/libh2o/deps/brotli/enc/encode_parallel.h create mode 100644 web/server/h2o/libh2o/deps/brotli/enc/entropy_encode.cc create mode 100644 web/server/h2o/libh2o/deps/brotli/enc/entropy_encode.h create mode 100644 web/server/h2o/libh2o/deps/brotli/enc/entropy_encode_static.h create mode 100644 web/server/h2o/libh2o/deps/brotli/enc/fast_log.h create mode 100644 web/server/h2o/libh2o/deps/brotli/enc/find_match_length.h create mode 100644 web/server/h2o/libh2o/deps/brotli/enc/hash.h create mode 100644 web/server/h2o/libh2o/deps/brotli/enc/histogram.cc create mode 100644 web/server/h2o/libh2o/deps/brotli/enc/histogram.h create mode 100644 web/server/h2o/libh2o/deps/brotli/enc/literal_cost.cc create mode 100644 web/server/h2o/libh2o/deps/brotli/enc/literal_cost.h create mode 100644 web/server/h2o/libh2o/deps/brotli/enc/metablock.cc create mode 100644 web/server/h2o/libh2o/deps/brotli/enc/metablock.h create mode 100644 web/server/h2o/libh2o/deps/brotli/enc/port.h create mode 100644 web/server/h2o/libh2o/deps/brotli/enc/prefix.h create mode 100644 web/server/h2o/libh2o/deps/brotli/enc/ringbuffer.h create mode 100644 web/server/h2o/libh2o/deps/brotli/enc/static_dict.cc create mode 100644 web/server/h2o/libh2o/deps/brotli/enc/static_dict.h create mode 100644 web/server/h2o/libh2o/deps/brotli/enc/static_dict_lut.h create mode 100644 web/server/h2o/libh2o/deps/brotli/enc/streams.cc create mode 100644 web/server/h2o/libh2o/deps/brotli/enc/streams.h create mode 100644 web/server/h2o/libh2o/deps/brotli/enc/transform.h create mode 100644 web/server/h2o/libh2o/deps/brotli/enc/types.h create mode 100644 web/server/h2o/libh2o/deps/brotli/enc/utf8_util.cc create mode 100644 web/server/h2o/libh2o/deps/brotli/enc/utf8_util.h create mode 100644 web/server/h2o/libh2o/deps/brotli/enc/write_bits.h create mode 100644 web/server/h2o/libh2o/deps/brotli/python/README.md create mode 100755 web/server/h2o/libh2o/deps/brotli/python/bro.py create mode 100644 web/server/h2o/libh2o/deps/brotli/python/brotlimodule.cc create mode 100755 web/server/h2o/libh2o/deps/brotli/python/tests/compatibility_test.py create mode 100644 web/server/h2o/libh2o/deps/brotli/python/tests/custom_dictionary_test.py create mode 100755 web/server/h2o/libh2o/deps/brotli/python/tests/roundtrip_test.py create mode 100644 web/server/h2o/libh2o/deps/brotli/python/tests/test_utils.py create mode 100644 web/server/h2o/libh2o/deps/brotli/setup.py create mode 100644 web/server/h2o/libh2o/deps/brotli/shared.mk create mode 100644 web/server/h2o/libh2o/deps/brotli/tests/Makefile create mode 100755 web/server/h2o/libh2o/deps/brotli/tests/compatibility_test.sh create mode 100755 web/server/h2o/libh2o/deps/brotli/tests/roundtrip_test.sh create mode 100644 web/server/h2o/libh2o/deps/brotli/tests/testdata/10x10y create mode 100644 web/server/h2o/libh2o/deps/brotli/tests/testdata/10x10y.compressed create mode 100644 web/server/h2o/libh2o/deps/brotli/tests/testdata/64x create mode 100644 web/server/h2o/libh2o/deps/brotli/tests/testdata/64x.compressed create mode 100644 web/server/h2o/libh2o/deps/brotli/tests/testdata/alice29.txt create mode 100644 web/server/h2o/libh2o/deps/brotli/tests/testdata/alice29.txt.compressed create mode 100644 web/server/h2o/libh2o/deps/brotli/tests/testdata/asyoulik.txt create mode 100644 web/server/h2o/libh2o/deps/brotli/tests/testdata/asyoulik.txt.compressed create mode 100644 web/server/h2o/libh2o/deps/brotli/tests/testdata/backward65536 create mode 100644 web/server/h2o/libh2o/deps/brotli/tests/testdata/backward65536.compressed create mode 100644 web/server/h2o/libh2o/deps/brotli/tests/testdata/bb.binast create mode 100644 web/server/h2o/libh2o/deps/brotli/tests/testdata/compressed_file create mode 100644 web/server/h2o/libh2o/deps/brotli/tests/testdata/compressed_file.compressed create mode 100644 web/server/h2o/libh2o/deps/brotli/tests/testdata/compressed_repeated create mode 100644 web/server/h2o/libh2o/deps/brotli/tests/testdata/compressed_repeated.compressed create mode 100644 web/server/h2o/libh2o/deps/brotli/tests/testdata/empty create mode 100644 web/server/h2o/libh2o/deps/brotli/tests/testdata/empty.compressed create mode 100644 web/server/h2o/libh2o/deps/brotli/tests/testdata/empty.compressed.00 create mode 100644 web/server/h2o/libh2o/deps/brotli/tests/testdata/empty.compressed.01 create mode 100644 web/server/h2o/libh2o/deps/brotli/tests/testdata/empty.compressed.02 create mode 100644 web/server/h2o/libh2o/deps/brotli/tests/testdata/empty.compressed.03 create mode 100644 web/server/h2o/libh2o/deps/brotli/tests/testdata/empty.compressed.04 create mode 100644 web/server/h2o/libh2o/deps/brotli/tests/testdata/empty.compressed.05 create mode 100644 web/server/h2o/libh2o/deps/brotli/tests/testdata/empty.compressed.06 create mode 100644 web/server/h2o/libh2o/deps/brotli/tests/testdata/empty.compressed.07 create mode 100644 web/server/h2o/libh2o/deps/brotli/tests/testdata/empty.compressed.08 create mode 100644 web/server/h2o/libh2o/deps/brotli/tests/testdata/empty.compressed.09 create mode 100644 web/server/h2o/libh2o/deps/brotli/tests/testdata/empty.compressed.10 create mode 100644 web/server/h2o/libh2o/deps/brotli/tests/testdata/empty.compressed.11 create mode 100644 web/server/h2o/libh2o/deps/brotli/tests/testdata/empty.compressed.12 create mode 100644 web/server/h2o/libh2o/deps/brotli/tests/testdata/empty.compressed.13 create mode 100644 web/server/h2o/libh2o/deps/brotli/tests/testdata/empty.compressed.14 create mode 100644 web/server/h2o/libh2o/deps/brotli/tests/testdata/empty.compressed.15 create mode 100644 web/server/h2o/libh2o/deps/brotli/tests/testdata/empty.compressed.16 create mode 100644 web/server/h2o/libh2o/deps/brotli/tests/testdata/empty.compressed.17 create mode 100644 web/server/h2o/libh2o/deps/brotli/tests/testdata/empty.compressed.18 create mode 100644 web/server/h2o/libh2o/deps/brotli/tests/testdata/lcet10.txt create mode 100644 web/server/h2o/libh2o/deps/brotli/tests/testdata/lcet10.txt.compressed create mode 100644 web/server/h2o/libh2o/deps/brotli/tests/testdata/mapsdatazrh create mode 100644 web/server/h2o/libh2o/deps/brotli/tests/testdata/mapsdatazrh.compressed create mode 100644 web/server/h2o/libh2o/deps/brotli/tests/testdata/monkey create mode 100644 web/server/h2o/libh2o/deps/brotli/tests/testdata/monkey.compressed create mode 100644 web/server/h2o/libh2o/deps/brotli/tests/testdata/plrabn12.txt create mode 100644 web/server/h2o/libh2o/deps/brotli/tests/testdata/plrabn12.txt.compressed create mode 100644 web/server/h2o/libh2o/deps/brotli/tests/testdata/quickfox create mode 100644 web/server/h2o/libh2o/deps/brotli/tests/testdata/quickfox.compressed create mode 100644 web/server/h2o/libh2o/deps/brotli/tests/testdata/quickfox_repeated create mode 100644 web/server/h2o/libh2o/deps/brotli/tests/testdata/quickfox_repeated.compressed create mode 100644 web/server/h2o/libh2o/deps/brotli/tests/testdata/random_chunks create mode 100644 web/server/h2o/libh2o/deps/brotli/tests/testdata/random_org_10k.bin create mode 100644 web/server/h2o/libh2o/deps/brotli/tests/testdata/random_org_10k.bin.compressed create mode 100644 web/server/h2o/libh2o/deps/brotli/tests/testdata/ukkonooa create mode 100644 web/server/h2o/libh2o/deps/brotli/tests/testdata/ukkonooa.compressed create mode 100644 web/server/h2o/libh2o/deps/brotli/tests/testdata/x create mode 100644 web/server/h2o/libh2o/deps/brotli/tests/testdata/x.compressed create mode 100644 web/server/h2o/libh2o/deps/brotli/tests/testdata/x.compressed.00 create mode 100644 web/server/h2o/libh2o/deps/brotli/tests/testdata/x.compressed.01 create mode 100644 web/server/h2o/libh2o/deps/brotli/tests/testdata/x.compressed.02 create mode 100644 web/server/h2o/libh2o/deps/brotli/tests/testdata/x.compressed.03 create mode 100644 web/server/h2o/libh2o/deps/brotli/tests/testdata/xyzzy create mode 100644 web/server/h2o/libh2o/deps/brotli/tests/testdata/xyzzy.compressed create mode 100644 web/server/h2o/libh2o/deps/brotli/tests/testdata/zeros create mode 100644 web/server/h2o/libh2o/deps/brotli/tests/testdata/zeros.compressed create mode 100644 web/server/h2o/libh2o/deps/brotli/tools/Makefile create mode 100644 web/server/h2o/libh2o/deps/brotli/tools/bro.cc create mode 100755 web/server/h2o/libh2o/deps/brotli/tools/rfc-format.py create mode 100644 web/server/h2o/libh2o/deps/brotli/tools/version.h create mode 100644 web/server/h2o/libh2o/deps/cloexec/cloexec.c create mode 100644 web/server/h2o/libh2o/deps/cloexec/cloexec.h create mode 100644 web/server/h2o/libh2o/deps/golombset/README.md create mode 100644 web/server/h2o/libh2o/deps/golombset/golombset.h create mode 100644 web/server/h2o/libh2o/deps/golombset/test.c create mode 100644 web/server/h2o/libh2o/deps/klib/.gitignore create mode 100644 web/server/h2o/libh2o/deps/klib/README.md create mode 100644 web/server/h2o/libh2o/deps/klib/bgzf.c create mode 100644 web/server/h2o/libh2o/deps/klib/bgzf.h create mode 100644 web/server/h2o/libh2o/deps/klib/kbit.h create mode 100644 web/server/h2o/libh2o/deps/klib/kbtree.h create mode 100644 web/server/h2o/libh2o/deps/klib/kgraph.h create mode 100644 web/server/h2o/libh2o/deps/klib/khash.h create mode 100644 web/server/h2o/libh2o/deps/klib/khmm.c create mode 100644 web/server/h2o/libh2o/deps/klib/khmm.h create mode 100644 web/server/h2o/libh2o/deps/klib/klist.h create mode 100644 web/server/h2o/libh2o/deps/klib/kmath.c create mode 100644 web/server/h2o/libh2o/deps/klib/kmath.h create mode 100644 web/server/h2o/libh2o/deps/klib/knetfile.c create mode 100644 web/server/h2o/libh2o/deps/klib/knetfile.h create mode 100644 web/server/h2o/libh2o/deps/klib/knhx.c create mode 100644 web/server/h2o/libh2o/deps/klib/knhx.h create mode 100644 web/server/h2o/libh2o/deps/klib/kopen.c create mode 100644 web/server/h2o/libh2o/deps/klib/ksa.c create mode 100644 web/server/h2o/libh2o/deps/klib/kseq.h create mode 100644 web/server/h2o/libh2o/deps/klib/kson.c create mode 100644 web/server/h2o/libh2o/deps/klib/kson.h create mode 100644 web/server/h2o/libh2o/deps/klib/ksort.h create mode 100644 web/server/h2o/libh2o/deps/klib/kstring.c create mode 100644 web/server/h2o/libh2o/deps/klib/kstring.h create mode 100644 web/server/h2o/libh2o/deps/klib/ksw.c create mode 100644 web/server/h2o/libh2o/deps/klib/ksw.h create mode 100644 web/server/h2o/libh2o/deps/klib/kthread.c create mode 100644 web/server/h2o/libh2o/deps/klib/kurl.c create mode 100644 web/server/h2o/libh2o/deps/klib/kurl.h create mode 100644 web/server/h2o/libh2o/deps/klib/kvec.h create mode 100644 web/server/h2o/libh2o/deps/klib/lua/bio.lua create mode 100644 web/server/h2o/libh2o/deps/klib/lua/klib.lua create mode 100644 web/server/h2o/libh2o/deps/klib/test/Makefile create mode 100644 web/server/h2o/libh2o/deps/klib/test/kbit_test.c create mode 100644 web/server/h2o/libh2o/deps/klib/test/kbtree_test.c create mode 100644 web/server/h2o/libh2o/deps/klib/test/kgraph_test.c create mode 100644 web/server/h2o/libh2o/deps/klib/test/khash_keith.c create mode 100644 web/server/h2o/libh2o/deps/klib/test/khash_keith2.c create mode 100644 web/server/h2o/libh2o/deps/klib/test/khash_test.c create mode 100644 web/server/h2o/libh2o/deps/klib/test/klist_test.c create mode 100644 web/server/h2o/libh2o/deps/klib/test/kmin_test.c create mode 100644 web/server/h2o/libh2o/deps/klib/test/kseq_bench.c create mode 100644 web/server/h2o/libh2o/deps/klib/test/kseq_bench2.c create mode 100644 web/server/h2o/libh2o/deps/klib/test/kseq_test.c create mode 100644 web/server/h2o/libh2o/deps/klib/test/kseq_test.dat create mode 100644 web/server/h2o/libh2o/deps/klib/test/ksort_test.c create mode 100644 web/server/h2o/libh2o/deps/klib/test/ksort_test.cc create mode 100644 web/server/h2o/libh2o/deps/klib/test/kstring_bench.c create mode 100644 web/server/h2o/libh2o/deps/klib/test/kstring_bench2.c create mode 100644 web/server/h2o/libh2o/deps/klib/test/kstring_test.c create mode 100644 web/server/h2o/libh2o/deps/klib/test/kthread_test.c create mode 100644 web/server/h2o/libh2o/deps/klib/test/kvec_test.cc create mode 100644 web/server/h2o/libh2o/deps/libgkc/gkc.c create mode 100644 web/server/h2o/libh2o/deps/libgkc/gkc.h create mode 100644 web/server/h2o/libh2o/deps/libgkc/test.c create mode 100644 web/server/h2o/libh2o/deps/libyrmcds/.gitignore create mode 100644 web/server/h2o/libh2o/deps/libyrmcds/.travis.yml create mode 100644 web/server/h2o/libh2o/deps/libyrmcds/COPYING create mode 100644 web/server/h2o/libh2o/deps/libyrmcds/Doxyfile create mode 100644 web/server/h2o/libh2o/deps/libyrmcds/Makefile create mode 100644 web/server/h2o/libh2o/deps/libyrmcds/README.md create mode 100644 web/server/h2o/libh2o/deps/libyrmcds/USAGE.md create mode 100644 web/server/h2o/libh2o/deps/libyrmcds/close.c create mode 100644 web/server/h2o/libh2o/deps/libyrmcds/connect.c create mode 100644 web/server/h2o/libh2o/deps/libyrmcds/counter.c create mode 100644 web/server/h2o/libh2o/deps/libyrmcds/example/counter.c create mode 100644 web/server/h2o/libh2o/deps/libyrmcds/example/memcache.c create mode 100644 web/server/h2o/libh2o/deps/libyrmcds/recv.c create mode 100644 web/server/h2o/libh2o/deps/libyrmcds/send.c create mode 100644 web/server/h2o/libh2o/deps/libyrmcds/send_text.c create mode 100644 web/server/h2o/libh2o/deps/libyrmcds/set_compression.c create mode 100644 web/server/h2o/libh2o/deps/libyrmcds/socket.c create mode 100644 web/server/h2o/libh2o/deps/libyrmcds/strerror.c create mode 100644 web/server/h2o/libh2o/deps/libyrmcds/t/t.h create mode 100644 web/server/h2o/libh2o/deps/libyrmcds/t/text.c create mode 100644 web/server/h2o/libh2o/deps/libyrmcds/text_mode.c create mode 100644 web/server/h2o/libh2o/deps/libyrmcds/yc-cnt.c create mode 100644 web/server/h2o/libh2o/deps/libyrmcds/yc.c create mode 100644 web/server/h2o/libh2o/deps/libyrmcds/yrmcds.h create mode 100644 web/server/h2o/libh2o/deps/libyrmcds/yrmcds_portability.h create mode 100644 web/server/h2o/libh2o/deps/libyrmcds/yrmcds_text.h create mode 100644 web/server/h2o/libh2o/deps/mruby-digest/.gitignore create mode 100644 web/server/h2o/libh2o/deps/mruby-digest/.travis.yml create mode 100644 web/server/h2o/libh2o/deps/mruby-digest/Makefile create mode 100644 web/server/h2o/libh2o/deps/mruby-digest/README.md create mode 100644 web/server/h2o/libh2o/deps/mruby-digest/mrbgem.rake create mode 100644 web/server/h2o/libh2o/deps/mruby-digest/mrblib/digest.rb create mode 100644 web/server/h2o/libh2o/deps/mruby-digest/run_test.rb create mode 100644 web/server/h2o/libh2o/deps/mruby-digest/src/digest.c create mode 100644 web/server/h2o/libh2o/deps/mruby-digest/src/picohash.h create mode 100644 web/server/h2o/libh2o/deps/mruby-digest/test/digest.rb create mode 100644 web/server/h2o/libh2o/deps/mruby-dir/.gitignore create mode 100644 web/server/h2o/libh2o/deps/mruby-dir/.travis.yml create mode 100644 web/server/h2o/libh2o/deps/mruby-dir/README.md create mode 100644 web/server/h2o/libh2o/deps/mruby-dir/mrbgem.rake create mode 100644 web/server/h2o/libh2o/deps/mruby-dir/mrblib/dir.rb create mode 100644 web/server/h2o/libh2o/deps/mruby-dir/run_test.rb create mode 100644 web/server/h2o/libh2o/deps/mruby-dir/src/Win/dirent.c create mode 100644 web/server/h2o/libh2o/deps/mruby-dir/src/dir.c create mode 100644 web/server/h2o/libh2o/deps/mruby-dir/test/dir.rb create mode 100644 web/server/h2o/libh2o/deps/mruby-dir/test/dirtest.c create mode 100644 web/server/h2o/libh2o/deps/mruby-env/.gitignore create mode 100644 web/server/h2o/libh2o/deps/mruby-env/.travis.yml create mode 100644 web/server/h2o/libh2o/deps/mruby-env/README.md create mode 100644 web/server/h2o/libh2o/deps/mruby-env/mrbgem.rake create mode 100644 web/server/h2o/libh2o/deps/mruby-env/mrblib/env.rb create mode 100644 web/server/h2o/libh2o/deps/mruby-env/run_test.rb create mode 100644 web/server/h2o/libh2o/deps/mruby-env/src/env.c create mode 100644 web/server/h2o/libh2o/deps/mruby-env/test/env_test.rb create mode 100644 web/server/h2o/libh2o/deps/mruby-errno/.gitignore create mode 100644 web/server/h2o/libh2o/deps/mruby-errno/.travis.yml create mode 100644 web/server/h2o/libh2o/deps/mruby-errno/README.md create mode 100644 web/server/h2o/libh2o/deps/mruby-errno/mrbgem.rake create mode 100644 web/server/h2o/libh2o/deps/mruby-errno/run_test.rb create mode 100644 web/server/h2o/libh2o/deps/mruby-errno/src/errno.c create mode 100755 web/server/h2o/libh2o/deps/mruby-errno/src/gen.rb create mode 100644 web/server/h2o/libh2o/deps/mruby-errno/src/known_errors.def create mode 100644 web/server/h2o/libh2o/deps/mruby-errno/src/known_errors_def.cstub create mode 100644 web/server/h2o/libh2o/deps/mruby-errno/src/known_errors_e2c.cstub create mode 100644 web/server/h2o/libh2o/deps/mruby-errno/test/errno.rb create mode 100644 web/server/h2o/libh2o/deps/mruby-file-stat/.gitignore create mode 100644 web/server/h2o/libh2o/deps/mruby-file-stat/.travis.yml create mode 100644 web/server/h2o/libh2o/deps/mruby-file-stat/.travis_build_config.rb create mode 100644 web/server/h2o/libh2o/deps/mruby-file-stat/README.md create mode 100644 web/server/h2o/libh2o/deps/mruby-file-stat/appveyor.yml create mode 100644 web/server/h2o/libh2o/deps/mruby-file-stat/config.h.in create mode 100755 web/server/h2o/libh2o/deps/mruby-file-stat/configure create mode 100644 web/server/h2o/libh2o/deps/mruby-file-stat/configure.ac create mode 100644 web/server/h2o/libh2o/deps/mruby-file-stat/mrbgem.rake create mode 100644 web/server/h2o/libh2o/deps/mruby-file-stat/mrblib/ext.rb create mode 100644 web/server/h2o/libh2o/deps/mruby-file-stat/mrblib/file-stat.rb create mode 100644 web/server/h2o/libh2o/deps/mruby-file-stat/src/file-stat.c create mode 100644 web/server/h2o/libh2o/deps/mruby-file-stat/test/executable create mode 100644 web/server/h2o/libh2o/deps/mruby-file-stat/test/file-stat.c create mode 100644 web/server/h2o/libh2o/deps/mruby-file-stat/test/file-stat.rb create mode 100644 web/server/h2o/libh2o/deps/mruby-file-stat/test/io.rb create mode 100644 web/server/h2o/libh2o/deps/mruby-file-stat/test/readable create mode 100644 web/server/h2o/libh2o/deps/mruby-file-stat/test/writable create mode 100644 web/server/h2o/libh2o/deps/mruby-iijson/.gitignore create mode 100644 web/server/h2o/libh2o/deps/mruby-iijson/.travis.yml create mode 100644 web/server/h2o/libh2o/deps/mruby-iijson/README.md create mode 100644 web/server/h2o/libh2o/deps/mruby-iijson/mrbgem.rake create mode 100755 web/server/h2o/libh2o/deps/mruby-iijson/mrblib/json.rb create mode 100644 web/server/h2o/libh2o/deps/mruby-iijson/mrblib/to_json.rb create mode 100644 web/server/h2o/libh2o/deps/mruby-iijson/run_test.rb create mode 100644 web/server/h2o/libh2o/deps/mruby-iijson/src/json.c create mode 100644 web/server/h2o/libh2o/deps/mruby-iijson/test/json.rb create mode 100644 web/server/h2o/libh2o/deps/mruby-iijson/test/testjson.c create mode 100644 web/server/h2o/libh2o/deps/mruby-input-stream/.travis.yml create mode 100644 web/server/h2o/libh2o/deps/mruby-input-stream/LICENSE create mode 100644 web/server/h2o/libh2o/deps/mruby-input-stream/README.md create mode 100644 web/server/h2o/libh2o/deps/mruby-input-stream/Rakefile create mode 100644 web/server/h2o/libh2o/deps/mruby-input-stream/build_config_sample.rb create mode 100644 web/server/h2o/libh2o/deps/mruby-input-stream/mrbgem.rake create mode 100644 web/server/h2o/libh2o/deps/mruby-input-stream/mrblib/input_stream.rb create mode 100644 web/server/h2o/libh2o/deps/mruby-input-stream/src/mruby_input_stream.c create mode 100644 web/server/h2o/libh2o/deps/mruby-input-stream/src/mruby_input_stream.h create mode 100644 web/server/h2o/libh2o/deps/mruby-input-stream/test/input_stream.rb create mode 100644 web/server/h2o/libh2o/deps/mruby-io/.gitignore create mode 100644 web/server/h2o/libh2o/deps/mruby-io/.travis.yml create mode 100644 web/server/h2o/libh2o/deps/mruby-io/README.md create mode 100644 web/server/h2o/libh2o/deps/mruby-io/include/mruby/ext/io.h create mode 100644 web/server/h2o/libh2o/deps/mruby-io/mrbgem.rake create mode 100644 web/server/h2o/libh2o/deps/mruby-io/mrblib/file.rb create mode 100644 web/server/h2o/libh2o/deps/mruby-io/mrblib/file_constants.rb create mode 100644 web/server/h2o/libh2o/deps/mruby-io/mrblib/io.rb create mode 100644 web/server/h2o/libh2o/deps/mruby-io/mrblib/kernel.rb create mode 100644 web/server/h2o/libh2o/deps/mruby-io/run_test.rb create mode 100644 web/server/h2o/libh2o/deps/mruby-io/src/file.c create mode 100644 web/server/h2o/libh2o/deps/mruby-io/src/file_test.c create mode 100644 web/server/h2o/libh2o/deps/mruby-io/src/io.c create mode 100644 web/server/h2o/libh2o/deps/mruby-io/src/mruby_io_gem.c create mode 100644 web/server/h2o/libh2o/deps/mruby-io/test/file.rb create mode 100644 web/server/h2o/libh2o/deps/mruby-io/test/file_test.rb create mode 100644 web/server/h2o/libh2o/deps/mruby-io/test/gc_filedes.sh create mode 100644 web/server/h2o/libh2o/deps/mruby-io/test/io.rb create mode 100644 web/server/h2o/libh2o/deps/mruby-io/test/mruby_io_test.c create mode 100644 web/server/h2o/libh2o/deps/mruby-onig-regexp/.travis.yml create mode 100644 web/server/h2o/libh2o/deps/mruby-onig-regexp/.travis_config.rb create mode 100644 web/server/h2o/libh2o/deps/mruby-onig-regexp/Onigmo-6.1.1.tar.gz create mode 100644 web/server/h2o/libh2o/deps/mruby-onig-regexp/README.md create mode 100644 web/server/h2o/libh2o/deps/mruby-onig-regexp/mrbgem.rake create mode 100644 web/server/h2o/libh2o/deps/mruby-onig-regexp/mrblib/onig_regexp.rb create mode 100644 web/server/h2o/libh2o/deps/mruby-onig-regexp/src/mruby_onig_regexp.c create mode 100644 web/server/h2o/libh2o/deps/mruby-onig-regexp/test/mruby_onig_regexp.rb create mode 100644 web/server/h2o/libh2o/deps/mruby-pack/.gitignore create mode 100644 web/server/h2o/libh2o/deps/mruby-pack/.travis.yml create mode 100644 web/server/h2o/libh2o/deps/mruby-pack/README.md create mode 100644 web/server/h2o/libh2o/deps/mruby-pack/mrbgem.rake create mode 100644 web/server/h2o/libh2o/deps/mruby-pack/packtest.rb create mode 100644 web/server/h2o/libh2o/deps/mruby-pack/run_test.rb create mode 100644 web/server/h2o/libh2o/deps/mruby-pack/src/pack.c create mode 100644 web/server/h2o/libh2o/deps/mruby-pack/test/pack.rb create mode 100644 web/server/h2o/libh2o/deps/mruby-require/.gitignore create mode 100644 web/server/h2o/libh2o/deps/mruby-require/.travis.yml create mode 100644 web/server/h2o/libh2o/deps/mruby-require/README.md create mode 100644 web/server/h2o/libh2o/deps/mruby-require/mrbgem.rake create mode 100644 web/server/h2o/libh2o/deps/mruby-require/mrblib/require.rb create mode 100644 web/server/h2o/libh2o/deps/mruby-require/run_test.rb create mode 100644 web/server/h2o/libh2o/deps/mruby-require/src/require.c create mode 100644 web/server/h2o/libh2o/deps/mruby-require/test/d/required.rb create mode 100644 web/server/h2o/libh2o/deps/mruby-require/test/require.rb create mode 100644 web/server/h2o/libh2o/deps/mruby-require/test/test.rb create mode 100644 web/server/h2o/libh2o/deps/mruby-require/test/test2.rb create mode 100644 web/server/h2o/libh2o/deps/mruby-require/test/test_context.rb create mode 100644 web/server/h2o/libh2o/deps/mruby-require/test/test_nest_loop.rb create mode 100644 web/server/h2o/libh2o/deps/mruby/.gitignore create mode 100644 web/server/h2o/libh2o/deps/mruby/.gitlab-ci.yml create mode 100644 web/server/h2o/libh2o/deps/mruby/.travis.yml create mode 100644 web/server/h2o/libh2o/deps/mruby/.yardopts create mode 100644 web/server/h2o/libh2o/deps/mruby/AUTHORS create mode 100644 web/server/h2o/libh2o/deps/mruby/CONTRIBUTING.md create mode 100644 web/server/h2o/libh2o/deps/mruby/LEGAL create mode 100644 web/server/h2o/libh2o/deps/mruby/MITL create mode 100644 web/server/h2o/libh2o/deps/mruby/Makefile create mode 100644 web/server/h2o/libh2o/deps/mruby/NEWS create mode 100644 web/server/h2o/libh2o/deps/mruby/README.md create mode 100644 web/server/h2o/libh2o/deps/mruby/Rakefile create mode 100644 web/server/h2o/libh2o/deps/mruby/TODO create mode 100644 web/server/h2o/libh2o/deps/mruby/appveyor.yml create mode 100644 web/server/h2o/libh2o/deps/mruby/appveyor_config.rb create mode 100644 web/server/h2o/libh2o/deps/mruby/benchmark/bm_ao_render.rb create mode 100644 web/server/h2o/libh2o/deps/mruby/benchmark/bm_app_lc_fizzbuzz.rb create mode 100644 web/server/h2o/libh2o/deps/mruby/benchmark/bm_fib.rb create mode 100644 web/server/h2o/libh2o/deps/mruby/benchmark/bm_so_lists.rb create mode 100644 web/server/h2o/libh2o/deps/mruby/benchmark/build_config_boxing.rb create mode 100644 web/server/h2o/libh2o/deps/mruby/benchmark/build_config_cc.rb create mode 100644 web/server/h2o/libh2o/deps/mruby/benchmark/plot.gpl create mode 100644 web/server/h2o/libh2o/deps/mruby/bin/.gitkeep create mode 100644 web/server/h2o/libh2o/deps/mruby/build_config.rb create mode 100644 web/server/h2o/libh2o/deps/mruby/doc/guides/compile.md create mode 100644 web/server/h2o/libh2o/deps/mruby/doc/guides/debugger.md create mode 100644 web/server/h2o/libh2o/deps/mruby/doc/guides/gc-arena-howto.md create mode 100644 web/server/h2o/libh2o/deps/mruby/doc/guides/mrbconf.md create mode 100644 web/server/h2o/libh2o/deps/mruby/doc/guides/mrbgems.md create mode 100644 web/server/h2o/libh2o/deps/mruby/doc/limitations.md create mode 100644 web/server/h2o/libh2o/deps/mruby/examples/mrbgems/c_and_ruby_extension_example/README.md create mode 100644 web/server/h2o/libh2o/deps/mruby/examples/mrbgems/c_and_ruby_extension_example/mrbgem.rake create mode 100644 web/server/h2o/libh2o/deps/mruby/examples/mrbgems/c_and_ruby_extension_example/mrblib/example.rb create mode 100644 web/server/h2o/libh2o/deps/mruby/examples/mrbgems/c_and_ruby_extension_example/src/example.c create mode 100644 web/server/h2o/libh2o/deps/mruby/examples/mrbgems/c_and_ruby_extension_example/test/example.rb create mode 100644 web/server/h2o/libh2o/deps/mruby/examples/mrbgems/c_extension_example/README.md create mode 100644 web/server/h2o/libh2o/deps/mruby/examples/mrbgems/c_extension_example/mrbgem.rake create mode 100644 web/server/h2o/libh2o/deps/mruby/examples/mrbgems/c_extension_example/src/example.c create mode 100644 web/server/h2o/libh2o/deps/mruby/examples/mrbgems/c_extension_example/test/example.c create mode 100644 web/server/h2o/libh2o/deps/mruby/examples/mrbgems/c_extension_example/test/example.rb create mode 100644 web/server/h2o/libh2o/deps/mruby/examples/mrbgems/ruby_extension_example/README.md create mode 100644 web/server/h2o/libh2o/deps/mruby/examples/mrbgems/ruby_extension_example/mrbgem.rake create mode 100644 web/server/h2o/libh2o/deps/mruby/examples/mrbgems/ruby_extension_example/mrblib/example.rb create mode 100644 web/server/h2o/libh2o/deps/mruby/examples/mrbgems/ruby_extension_example/test/example.rb create mode 100644 web/server/h2o/libh2o/deps/mruby/examples/targets/build_config_ArduinoDue.rb create mode 100644 web/server/h2o/libh2o/deps/mruby/examples/targets/build_config_IntelEdison.rb create mode 100644 web/server/h2o/libh2o/deps/mruby/examples/targets/build_config_IntelGalileo.rb create mode 100644 web/server/h2o/libh2o/deps/mruby/examples/targets/build_config_RX630.rb create mode 100644 web/server/h2o/libh2o/deps/mruby/examples/targets/build_config_android_arm64-v8a.rb create mode 100644 web/server/h2o/libh2o/deps/mruby/examples/targets/build_config_android_armeabi.rb create mode 100644 web/server/h2o/libh2o/deps/mruby/examples/targets/build_config_android_armeabi_v7a_neon_hard.rb create mode 100644 web/server/h2o/libh2o/deps/mruby/examples/targets/build_config_chipKITMax32.rb create mode 100644 web/server/h2o/libh2o/deps/mruby/include/mrbconf.h create mode 100644 web/server/h2o/libh2o/deps/mruby/include/mruby.h create mode 100644 web/server/h2o/libh2o/deps/mruby/include/mruby/array.h create mode 100644 web/server/h2o/libh2o/deps/mruby/include/mruby/boxing_nan.h create mode 100644 web/server/h2o/libh2o/deps/mruby/include/mruby/boxing_no.h create mode 100644 web/server/h2o/libh2o/deps/mruby/include/mruby/boxing_word.h create mode 100644 web/server/h2o/libh2o/deps/mruby/include/mruby/class.h create mode 100644 web/server/h2o/libh2o/deps/mruby/include/mruby/common.h create mode 100644 web/server/h2o/libh2o/deps/mruby/include/mruby/compile.h create mode 100644 web/server/h2o/libh2o/deps/mruby/include/mruby/data.h create mode 100644 web/server/h2o/libh2o/deps/mruby/include/mruby/debug.h create mode 100644 web/server/h2o/libh2o/deps/mruby/include/mruby/dump.h create mode 100644 web/server/h2o/libh2o/deps/mruby/include/mruby/error.h create mode 100644 web/server/h2o/libh2o/deps/mruby/include/mruby/gc.h create mode 100644 web/server/h2o/libh2o/deps/mruby/include/mruby/hash.h create mode 100644 web/server/h2o/libh2o/deps/mruby/include/mruby/irep.h create mode 100644 web/server/h2o/libh2o/deps/mruby/include/mruby/istruct.h create mode 100644 web/server/h2o/libh2o/deps/mruby/include/mruby/khash.h create mode 100644 web/server/h2o/libh2o/deps/mruby/include/mruby/numeric.h create mode 100644 web/server/h2o/libh2o/deps/mruby/include/mruby/object.h create mode 100644 web/server/h2o/libh2o/deps/mruby/include/mruby/opcode.h create mode 100644 web/server/h2o/libh2o/deps/mruby/include/mruby/proc.h create mode 100644 web/server/h2o/libh2o/deps/mruby/include/mruby/range.h create mode 100644 web/server/h2o/libh2o/deps/mruby/include/mruby/re.h create mode 100644 web/server/h2o/libh2o/deps/mruby/include/mruby/string.h create mode 100644 web/server/h2o/libh2o/deps/mruby/include/mruby/throw.h create mode 100644 web/server/h2o/libh2o/deps/mruby/include/mruby/value.h create mode 100644 web/server/h2o/libh2o/deps/mruby/include/mruby/variable.h create mode 100644 web/server/h2o/libh2o/deps/mruby/include/mruby/version.h create mode 100644 web/server/h2o/libh2o/deps/mruby/lib/mruby-core-ext.rb create mode 100644 web/server/h2o/libh2o/deps/mruby/lib/mruby/build.rb create mode 100644 web/server/h2o/libh2o/deps/mruby/lib/mruby/build/command.rb create mode 100644 web/server/h2o/libh2o/deps/mruby/lib/mruby/build/load_gems.rb create mode 100644 web/server/h2o/libh2o/deps/mruby/lib/mruby/gem.rb create mode 100644 web/server/h2o/libh2o/deps/mruby/lib/mruby/source.rb create mode 100755 web/server/h2o/libh2o/deps/mruby/minirake create mode 100644 web/server/h2o/libh2o/deps/mruby/mrbgems/default.gembox create mode 100644 web/server/h2o/libh2o/deps/mruby/mrbgems/full-core.gembox create mode 100644 web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-array-ext/mrbgem.rake create mode 100644 web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-array-ext/mrblib/array.rb create mode 100644 web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-array-ext/src/array.c create mode 100644 web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-array-ext/test/array.rb create mode 100644 web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-bin-debugger/bintest/mrdb.rb create mode 100644 web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-bin-debugger/bintest/print.rb create mode 100644 web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-bin-debugger/mrbgem.rake create mode 100644 web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-bin-debugger/tools/mrdb/apibreak.c create mode 100644 web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-bin-debugger/tools/mrdb/apibreak.h create mode 100644 web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-bin-debugger/tools/mrdb/apilist.c create mode 100644 web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-bin-debugger/tools/mrdb/apilist.h create mode 100644 web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-bin-debugger/tools/mrdb/apiprint.c create mode 100644 web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-bin-debugger/tools/mrdb/apiprint.h create mode 100644 web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-bin-debugger/tools/mrdb/cmdbreak.c create mode 100644 web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-bin-debugger/tools/mrdb/cmdmisc.c create mode 100644 web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-bin-debugger/tools/mrdb/cmdprint.c create mode 100644 web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-bin-debugger/tools/mrdb/cmdrun.c create mode 100644 web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-bin-debugger/tools/mrdb/mrdb.c create mode 100644 web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-bin-debugger/tools/mrdb/mrdb.h create mode 100644 web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-bin-debugger/tools/mrdb/mrdbconf.h create mode 100644 web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-bin-debugger/tools/mrdb/mrdberror.h create mode 100644 web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-bin-mirb/bintest/mirb.rb create mode 100644 web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-bin-mirb/mrbgem.rake create mode 100644 web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-bin-mirb/tools/mirb/mirb.c create mode 100644 web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-bin-mrbc/mrbgem.rake create mode 100644 web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-bin-mrbc/tools/mrbc/mrbc.c create mode 100644 web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-bin-mruby-config/mrbgem.rake create mode 100644 web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-bin-mruby-config/mruby-config create mode 100644 web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-bin-mruby-config/mruby-config.bat create mode 100644 web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-bin-mruby/bintest/mruby.rb create mode 100644 web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-bin-mruby/mrbgem.rake create mode 100644 web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-bin-mruby/tools/mruby/mruby.c create mode 100644 web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-bin-strip/bintest/mruby-strip.rb create mode 100644 web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-bin-strip/mrbgem.rake create mode 100644 web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-bin-strip/tools/mruby-strip/mruby-strip.c create mode 100644 web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-class-ext/mrbgem.rake create mode 100644 web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-class-ext/src/class.c create mode 100644 web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-class-ext/test/module.rb create mode 100644 web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-compiler/bintest/mrbc.rb create mode 100644 web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-compiler/core/codegen.c create mode 100644 web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-compiler/core/keywords create mode 100644 web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-compiler/core/lex.def create mode 100644 web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-compiler/core/node.h create mode 100644 web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-compiler/core/parse.y create mode 100644 web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-compiler/mrbgem.rake create mode 100644 web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-enum-ext/mrbgem.rake create mode 100644 web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-enum-ext/mrblib/enum.rb create mode 100644 web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-enum-ext/test/enum.rb create mode 100644 web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-enum-lazy/mrbgem.rake create mode 100644 web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-enum-lazy/mrblib/lazy.rb create mode 100644 web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-enum-lazy/test/lazy.rb create mode 100644 web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-enumerator/mrbgem.rake create mode 100644 web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-enumerator/mrblib/enumerator.rb create mode 100644 web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-enumerator/test/enumerator.rb create mode 100644 web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-error/mrbgem.rake create mode 100644 web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-error/src/exception.c create mode 100644 web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-error/test/exception.c create mode 100644 web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-error/test/exception.rb create mode 100644 web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-eval/mrbgem.rake create mode 100644 web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-eval/src/eval.c create mode 100644 web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-eval/test/eval.rb create mode 100644 web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-exit/mrbgem.rake create mode 100644 web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-exit/src/mruby-exit.c create mode 100644 web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-fiber/mrbgem.rake create mode 100644 web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-fiber/src/fiber.c create mode 100644 web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-fiber/test/fiber.rb create mode 100644 web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-hash-ext/mrbgem.rake create mode 100644 web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-hash-ext/mrblib/hash.rb create mode 100644 web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-hash-ext/src/hash-ext.c create mode 100644 web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-hash-ext/test/hash.rb create mode 100644 web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-inline-struct/mrbgem.rake create mode 100644 web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-inline-struct/test/inline.c create mode 100644 web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-inline-struct/test/inline.rb create mode 100644 web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-kernel-ext/mrbgem.rake create mode 100644 web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-kernel-ext/src/kernel.c create mode 100644 web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-kernel-ext/test/kernel.rb create mode 100644 web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-math/mrbgem.rake create mode 100644 web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-math/src/math.c create mode 100644 web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-math/test/math.rb create mode 100644 web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-numeric-ext/mrbgem.rake create mode 100644 web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-numeric-ext/mrblib/numeric_ext.rb create mode 100644 web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-numeric-ext/src/numeric_ext.c create mode 100644 web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-numeric-ext/test/numeric.rb create mode 100644 web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-object-ext/mrbgem.rake create mode 100644 web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-object-ext/mrblib/object.rb create mode 100644 web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-object-ext/src/object.c create mode 100644 web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-object-ext/test/nil.rb create mode 100644 web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-object-ext/test/object.rb create mode 100644 web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-objectspace/mrbgem.rake create mode 100644 web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-objectspace/src/mruby_objectspace.c create mode 100644 web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-objectspace/test/objectspace.rb create mode 100644 web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-print/mrbgem.rake create mode 100644 web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-print/mrblib/print.rb create mode 100644 web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-print/src/print.c create mode 100644 web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-proc-ext/mrbgem.rake create mode 100644 web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-proc-ext/mrblib/proc.rb create mode 100644 web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-proc-ext/src/proc.c create mode 100644 web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-proc-ext/test/proc.c create mode 100644 web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-proc-ext/test/proc.rb create mode 100644 web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-random/mrbgem.rake create mode 100644 web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-random/src/mt19937ar.c create mode 100644 web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-random/src/mt19937ar.h create mode 100644 web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-random/src/random.c create mode 100644 web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-random/src/random.h create mode 100644 web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-random/test/random.rb create mode 100644 web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-range-ext/mrbgem.rake create mode 100644 web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-range-ext/mrblib/range.rb create mode 100644 web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-range-ext/src/range.c create mode 100644 web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-range-ext/test/range.rb create mode 100644 web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-sprintf/mrbgem.rake create mode 100644 web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-sprintf/mrblib/string.rb create mode 100644 web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-sprintf/src/kernel.c create mode 100644 web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-sprintf/src/sprintf.c create mode 100644 web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-sprintf/test/sprintf.rb create mode 100644 web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-string-ext/mrbgem.rake create mode 100644 web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-string-ext/mrblib/string.rb create mode 100644 web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-string-ext/src/string.c create mode 100644 web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-string-ext/test/string.rb create mode 100644 web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-struct/mrbgem.rake create mode 100644 web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-struct/mrblib/struct.rb create mode 100644 web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-struct/src/struct.c create mode 100644 web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-struct/test/struct.rb create mode 100644 web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-symbol-ext/mrbgem.rake create mode 100644 web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-symbol-ext/mrblib/symbol.rb create mode 100644 web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-symbol-ext/src/symbol.c create mode 100644 web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-symbol-ext/test/symbol.rb create mode 100644 web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-test/README.md create mode 100644 web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-test/driver.c create mode 100644 web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-test/init_mrbtest.c create mode 100644 web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-test/mrbgem.rake create mode 100644 web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-time/mrbgem.rake create mode 100644 web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-time/mrblib/time.rb create mode 100644 web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-time/src/time.c create mode 100644 web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-time/test/time.rb create mode 100644 web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-toplevel-ext/mrbgem.rake create mode 100644 web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-toplevel-ext/mrblib/toplevel.rb create mode 100644 web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-toplevel-ext/test/toplevel.rb create mode 100644 web/server/h2o/libh2o/deps/mruby/mrblib/00class.rb create mode 100644 web/server/h2o/libh2o/deps/mruby/mrblib/10error.rb create mode 100644 web/server/h2o/libh2o/deps/mruby/mrblib/array.rb create mode 100644 web/server/h2o/libh2o/deps/mruby/mrblib/compar.rb create mode 100644 web/server/h2o/libh2o/deps/mruby/mrblib/enum.rb create mode 100644 web/server/h2o/libh2o/deps/mruby/mrblib/hash.rb create mode 100644 web/server/h2o/libh2o/deps/mruby/mrblib/init_mrblib.c create mode 100644 web/server/h2o/libh2o/deps/mruby/mrblib/kernel.rb create mode 100644 web/server/h2o/libh2o/deps/mruby/mrblib/mrblib.rake create mode 100644 web/server/h2o/libh2o/deps/mruby/mrblib/numeric.rb create mode 100644 web/server/h2o/libh2o/deps/mruby/mrblib/range.rb create mode 100644 web/server/h2o/libh2o/deps/mruby/mrblib/string.rb create mode 100644 web/server/h2o/libh2o/deps/mruby/mruby-source.gemspec create mode 100644 web/server/h2o/libh2o/deps/mruby/src/array.c create mode 100644 web/server/h2o/libh2o/deps/mruby/src/backtrace.c create mode 100644 web/server/h2o/libh2o/deps/mruby/src/class.c create mode 100644 web/server/h2o/libh2o/deps/mruby/src/codedump.c create mode 100644 web/server/h2o/libh2o/deps/mruby/src/compar.c create mode 100644 web/server/h2o/libh2o/deps/mruby/src/crc.c create mode 100644 web/server/h2o/libh2o/deps/mruby/src/debug.c create mode 100644 web/server/h2o/libh2o/deps/mruby/src/dump.c create mode 100644 web/server/h2o/libh2o/deps/mruby/src/enum.c create mode 100644 web/server/h2o/libh2o/deps/mruby/src/error.c create mode 100644 web/server/h2o/libh2o/deps/mruby/src/error.h create mode 100644 web/server/h2o/libh2o/deps/mruby/src/etc.c create mode 100644 web/server/h2o/libh2o/deps/mruby/src/ext/.gitkeep create mode 100644 web/server/h2o/libh2o/deps/mruby/src/fmt_fp.c create mode 100644 web/server/h2o/libh2o/deps/mruby/src/gc.c create mode 100644 web/server/h2o/libh2o/deps/mruby/src/hash.c create mode 100644 web/server/h2o/libh2o/deps/mruby/src/init.c create mode 100644 web/server/h2o/libh2o/deps/mruby/src/kernel.c create mode 100644 web/server/h2o/libh2o/deps/mruby/src/load.c create mode 100644 web/server/h2o/libh2o/deps/mruby/src/mruby_core.rake create mode 100644 web/server/h2o/libh2o/deps/mruby/src/numeric.c create mode 100644 web/server/h2o/libh2o/deps/mruby/src/object.c create mode 100644 web/server/h2o/libh2o/deps/mruby/src/opcode.h create mode 100644 web/server/h2o/libh2o/deps/mruby/src/pool.c create mode 100644 web/server/h2o/libh2o/deps/mruby/src/print.c create mode 100644 web/server/h2o/libh2o/deps/mruby/src/proc.c create mode 100644 web/server/h2o/libh2o/deps/mruby/src/range.c create mode 100644 web/server/h2o/libh2o/deps/mruby/src/state.c create mode 100644 web/server/h2o/libh2o/deps/mruby/src/string.c create mode 100644 web/server/h2o/libh2o/deps/mruby/src/symbol.c create mode 100644 web/server/h2o/libh2o/deps/mruby/src/value_array.h create mode 100644 web/server/h2o/libh2o/deps/mruby/src/variable.c create mode 100644 web/server/h2o/libh2o/deps/mruby/src/version.c create mode 100644 web/server/h2o/libh2o/deps/mruby/src/vm.c create mode 100644 web/server/h2o/libh2o/deps/mruby/tasks/benchmark.rake create mode 100644 web/server/h2o/libh2o/deps/mruby/tasks/gitlab.rake create mode 100644 web/server/h2o/libh2o/deps/mruby/tasks/libmruby.rake create mode 100644 web/server/h2o/libh2o/deps/mruby/tasks/mrbgems.rake create mode 100644 web/server/h2o/libh2o/deps/mruby/tasks/toolchains/android.rake create mode 100644 web/server/h2o/libh2o/deps/mruby/tasks/toolchains/clang.rake create mode 100644 web/server/h2o/libh2o/deps/mruby/tasks/toolchains/gcc.rake create mode 100644 web/server/h2o/libh2o/deps/mruby/tasks/toolchains/openwrt.rake create mode 100644 web/server/h2o/libh2o/deps/mruby/tasks/toolchains/visualcpp.rake create mode 100644 web/server/h2o/libh2o/deps/mruby/test/assert.rb create mode 100644 web/server/h2o/libh2o/deps/mruby/test/bintest.rb create mode 100644 web/server/h2o/libh2o/deps/mruby/test/report.rb create mode 100644 web/server/h2o/libh2o/deps/mruby/test/t/argumenterror.rb create mode 100644 web/server/h2o/libh2o/deps/mruby/test/t/array.rb create mode 100644 web/server/h2o/libh2o/deps/mruby/test/t/basicobject.rb create mode 100644 web/server/h2o/libh2o/deps/mruby/test/t/bs_block.rb create mode 100644 web/server/h2o/libh2o/deps/mruby/test/t/bs_literal.rb create mode 100644 web/server/h2o/libh2o/deps/mruby/test/t/class.rb create mode 100644 web/server/h2o/libh2o/deps/mruby/test/t/codegen.rb create mode 100644 web/server/h2o/libh2o/deps/mruby/test/t/comparable.rb create mode 100644 web/server/h2o/libh2o/deps/mruby/test/t/ensure.rb create mode 100644 web/server/h2o/libh2o/deps/mruby/test/t/enumerable.rb create mode 100644 web/server/h2o/libh2o/deps/mruby/test/t/exception.rb create mode 100644 web/server/h2o/libh2o/deps/mruby/test/t/false.rb create mode 100644 web/server/h2o/libh2o/deps/mruby/test/t/float.rb create mode 100644 web/server/h2o/libh2o/deps/mruby/test/t/gc.rb create mode 100644 web/server/h2o/libh2o/deps/mruby/test/t/hash.rb create mode 100644 web/server/h2o/libh2o/deps/mruby/test/t/indexerror.rb create mode 100644 web/server/h2o/libh2o/deps/mruby/test/t/integer.rb create mode 100644 web/server/h2o/libh2o/deps/mruby/test/t/iterations.rb create mode 100644 web/server/h2o/libh2o/deps/mruby/test/t/kernel.rb create mode 100755 web/server/h2o/libh2o/deps/mruby/test/t/lang.rb create mode 100644 web/server/h2o/libh2o/deps/mruby/test/t/literals.rb create mode 100644 web/server/h2o/libh2o/deps/mruby/test/t/localjumperror.rb create mode 100644 web/server/h2o/libh2o/deps/mruby/test/t/methods.rb create mode 100644 web/server/h2o/libh2o/deps/mruby/test/t/module.rb create mode 100644 web/server/h2o/libh2o/deps/mruby/test/t/nameerror.rb create mode 100644 web/server/h2o/libh2o/deps/mruby/test/t/nil.rb create mode 100644 web/server/h2o/libh2o/deps/mruby/test/t/nomethoderror.rb create mode 100644 web/server/h2o/libh2o/deps/mruby/test/t/numeric.rb create mode 100644 web/server/h2o/libh2o/deps/mruby/test/t/object.rb create mode 100644 web/server/h2o/libh2o/deps/mruby/test/t/proc.rb create mode 100644 web/server/h2o/libh2o/deps/mruby/test/t/range.rb create mode 100644 web/server/h2o/libh2o/deps/mruby/test/t/rangeerror.rb create mode 100644 web/server/h2o/libh2o/deps/mruby/test/t/regexperror.rb create mode 100644 web/server/h2o/libh2o/deps/mruby/test/t/runtimeerror.rb create mode 100644 web/server/h2o/libh2o/deps/mruby/test/t/standarderror.rb create mode 100644 web/server/h2o/libh2o/deps/mruby/test/t/string.rb create mode 100644 web/server/h2o/libh2o/deps/mruby/test/t/superclass.rb create mode 100644 web/server/h2o/libh2o/deps/mruby/test/t/symbol.rb create mode 100644 web/server/h2o/libh2o/deps/mruby/test/t/syntax.rb create mode 100644 web/server/h2o/libh2o/deps/mruby/test/t/true.rb create mode 100644 web/server/h2o/libh2o/deps/mruby/test/t/typeerror.rb create mode 100644 web/server/h2o/libh2o/deps/mruby/test/t/unicode.rb create mode 100644 web/server/h2o/libh2o/deps/mruby/travis_config.rb create mode 100644 web/server/h2o/libh2o/deps/neverbleed/.clang-format create mode 100644 web/server/h2o/libh2o/deps/neverbleed/.gitignore create mode 100644 web/server/h2o/libh2o/deps/neverbleed/LICENSE create mode 100644 web/server/h2o/libh2o/deps/neverbleed/README.md create mode 100644 web/server/h2o/libh2o/deps/neverbleed/neverbleed.c create mode 100644 web/server/h2o/libh2o/deps/neverbleed/neverbleed.h create mode 100644 web/server/h2o/libh2o/deps/neverbleed/test.c create mode 100644 web/server/h2o/libh2o/deps/picohttpparser/.clang-format create mode 100644 web/server/h2o/libh2o/deps/picohttpparser/.gitattributes create mode 100644 web/server/h2o/libh2o/deps/picohttpparser/.gitmodules create mode 100644 web/server/h2o/libh2o/deps/picohttpparser/.travis.yml create mode 100644 web/server/h2o/libh2o/deps/picohttpparser/Jamfile create mode 100644 web/server/h2o/libh2o/deps/picohttpparser/Makefile create mode 100644 web/server/h2o/libh2o/deps/picohttpparser/README.md create mode 100644 web/server/h2o/libh2o/deps/picohttpparser/bench.c create mode 100644 web/server/h2o/libh2o/deps/picohttpparser/picohttpparser.c create mode 100644 web/server/h2o/libh2o/deps/picohttpparser/picohttpparser.h create mode 100644 web/server/h2o/libh2o/deps/picohttpparser/test.c create mode 100644 web/server/h2o/libh2o/deps/picotest/picotest.c create mode 100644 web/server/h2o/libh2o/deps/picotest/picotest.h create mode 100644 web/server/h2o/libh2o/deps/picotls/.clang-format create mode 100644 web/server/h2o/libh2o/deps/picotls/.gitignore create mode 100644 web/server/h2o/libh2o/deps/picotls/.gitmodules create mode 100644 web/server/h2o/libh2o/deps/picotls/.travis.yml create mode 100644 web/server/h2o/libh2o/deps/picotls/CMakeLists.txt create mode 100644 web/server/h2o/libh2o/deps/picotls/README.md create mode 100644 web/server/h2o/libh2o/deps/picotls/WindowsPort.md create mode 100644 web/server/h2o/libh2o/deps/picotls/deps/cifra/.travis.yml create mode 100644 web/server/h2o/libh2o/deps/picotls/deps/cifra/COPYING create mode 100644 web/server/h2o/libh2o/deps/picotls/deps/cifra/README.md create mode 100644 web/server/h2o/libh2o/deps/picotls/deps/cifra/curve25519-shootout.md create mode 100644 web/server/h2o/libh2o/deps/picotls/deps/cifra/doc/Makefile create mode 100644 web/server/h2o/libh2o/deps/picotls/deps/cifra/doc/build.py create mode 100644 web/server/h2o/libh2o/deps/picotls/deps/cifra/doc/conf.py create mode 100644 web/server/h2o/libh2o/deps/picotls/deps/cifra/doc/index.rst create mode 100644 web/server/h2o/libh2o/deps/picotls/deps/cifra/extra_vecs/.gitignore create mode 100644 web/server/h2o/libh2o/deps/picotls/deps/cifra/extra_vecs/Makefile create mode 100644 web/server/h2o/libh2o/deps/picotls/deps/cifra/extra_vecs/README.md create mode 100644 web/server/h2o/libh2o/deps/picotls/deps/cifra/extra_vecs/openssl-hash.c create mode 100644 web/server/h2o/libh2o/deps/picotls/deps/cifra/extra_vecs/python-hash.py create mode 100644 web/server/h2o/libh2o/deps/picotls/deps/cifra/shitlisp/.gitignore create mode 100644 web/server/h2o/libh2o/deps/picotls/deps/cifra/shitlisp/Makefile create mode 100644 web/server/h2o/libh2o/deps/picotls/deps/cifra/shitlisp/sl-cifra.c create mode 100644 web/server/h2o/libh2o/deps/picotls/deps/cifra/shitlisp/test-aes.sl create mode 100644 web/server/h2o/libh2o/deps/picotls/deps/cifra/shitlisp/test-pbkdf2.sl create mode 100644 web/server/h2o/libh2o/deps/picotls/deps/cifra/shitlisp/test-sha224.sl create mode 100644 web/server/h2o/libh2o/deps/picotls/deps/cifra/shitlisp/test-sha256.sl create mode 100644 web/server/h2o/libh2o/deps/picotls/deps/cifra/shitlisp/test-sha384.sl create mode 100644 web/server/h2o/libh2o/deps/picotls/deps/cifra/shitlisp/test-sha512.sl create mode 100644 web/server/h2o/libh2o/deps/picotls/deps/cifra/src/.gitignore create mode 100644 web/server/h2o/libh2o/deps/picotls/deps/cifra/src/Makefile create mode 100644 web/server/h2o/libh2o/deps/picotls/deps/cifra/src/aes.c create mode 100644 web/server/h2o/libh2o/deps/picotls/deps/cifra/src/aes.h create mode 100644 web/server/h2o/libh2o/deps/picotls/deps/cifra/src/arm/.gitignore create mode 100644 web/server/h2o/libh2o/deps/picotls/deps/cifra/src/arm/Makefile create mode 100644 web/server/h2o/libh2o/deps/picotls/deps/cifra/src/arm/analyse.py create mode 100644 web/server/h2o/libh2o/deps/picotls/deps/cifra/src/arm/boot.c create mode 100644 web/server/h2o/libh2o/deps/picotls/deps/cifra/src/arm/curve25519-results.txt create mode 100644 web/server/h2o/libh2o/deps/picotls/deps/cifra/src/arm/ext/cutest.h create mode 100644 web/server/h2o/libh2o/deps/picotls/deps/cifra/src/arm/linkscript.efm32.ld create mode 100644 web/server/h2o/libh2o/deps/picotls/deps/cifra/src/arm/linkscript.lm3s6965evb.ld create mode 100644 web/server/h2o/libh2o/deps/picotls/deps/cifra/src/arm/linkscript.qemucm3.ld create mode 100644 web/server/h2o/libh2o/deps/picotls/deps/cifra/src/arm/linkscript.std.ld create mode 100644 web/server/h2o/libh2o/deps/picotls/deps/cifra/src/arm/linkscript.stm32f0.ld create mode 100644 web/server/h2o/libh2o/deps/picotls/deps/cifra/src/arm/linkscript.stm32f1.ld create mode 100644 web/server/h2o/libh2o/deps/picotls/deps/cifra/src/arm/linkscript.stm32f3.ld create mode 100644 web/server/h2o/libh2o/deps/picotls/deps/cifra/src/arm/main.c create mode 100644 web/server/h2o/libh2o/deps/picotls/deps/cifra/src/arm/memcpy.s create mode 100644 web/server/h2o/libh2o/deps/picotls/deps/cifra/src/arm/memset.s create mode 100644 web/server/h2o/libh2o/deps/picotls/deps/cifra/src/arm/merge.py create mode 100644 web/server/h2o/libh2o/deps/picotls/deps/cifra/src/arm/openocd.efm32.cfg create mode 100644 web/server/h2o/libh2o/deps/picotls/deps/cifra/src/arm/openocd.stm32f0.cfg create mode 100644 web/server/h2o/libh2o/deps/picotls/deps/cifra/src/arm/openocd.stm32f1.cfg create mode 100644 web/server/h2o/libh2o/deps/picotls/deps/cifra/src/arm/openocd.stm32f3.cfg create mode 100644 web/server/h2o/libh2o/deps/picotls/deps/cifra/src/arm/report.py create mode 100644 web/server/h2o/libh2o/deps/picotls/deps/cifra/src/arm/semihost.c create mode 100644 web/server/h2o/libh2o/deps/picotls/deps/cifra/src/arm/semihost.h create mode 100644 web/server/h2o/libh2o/deps/picotls/deps/cifra/src/arm/semihost.s create mode 100644 web/server/h2o/libh2o/deps/picotls/deps/cifra/src/arm/unacl/cortex_m0_mpy121666.s create mode 100644 web/server/h2o/libh2o/deps/picotls/deps/cifra/src/arm/unacl/cortex_m0_reduce25519.s create mode 100644 web/server/h2o/libh2o/deps/picotls/deps/cifra/src/arm/unacl/mul.s create mode 100644 web/server/h2o/libh2o/deps/picotls/deps/cifra/src/arm/unacl/scalarmult.c create mode 100644 web/server/h2o/libh2o/deps/picotls/deps/cifra/src/arm/unacl/sqr.s create mode 100644 web/server/h2o/libh2o/deps/picotls/deps/cifra/src/bitops.h create mode 100644 web/server/h2o/libh2o/deps/picotls/deps/cifra/src/blockwise.c create mode 100644 web/server/h2o/libh2o/deps/picotls/deps/cifra/src/blockwise.h create mode 100644 web/server/h2o/libh2o/deps/picotls/deps/cifra/src/cbcmac.c create mode 100644 web/server/h2o/libh2o/deps/picotls/deps/cifra/src/ccm.c create mode 100644 web/server/h2o/libh2o/deps/picotls/deps/cifra/src/cf_config.h create mode 100644 web/server/h2o/libh2o/deps/picotls/deps/cifra/src/chacha20.c create mode 100644 web/server/h2o/libh2o/deps/picotls/deps/cifra/src/chacha20poly1305.c create mode 100644 web/server/h2o/libh2o/deps/picotls/deps/cifra/src/chacha20poly1305.h create mode 100644 web/server/h2o/libh2o/deps/picotls/deps/cifra/src/chash.c create mode 100644 web/server/h2o/libh2o/deps/picotls/deps/cifra/src/chash.h create mode 100644 web/server/h2o/libh2o/deps/picotls/deps/cifra/src/cmac.c create mode 100644 web/server/h2o/libh2o/deps/picotls/deps/cifra/src/curve25519.c create mode 100644 web/server/h2o/libh2o/deps/picotls/deps/cifra/src/curve25519.donna.c create mode 100644 web/server/h2o/libh2o/deps/picotls/deps/cifra/src/curve25519.h create mode 100644 web/server/h2o/libh2o/deps/picotls/deps/cifra/src/curve25519.naclref.c create mode 100644 web/server/h2o/libh2o/deps/picotls/deps/cifra/src/curve25519.tweetnacl.c create mode 100644 web/server/h2o/libh2o/deps/picotls/deps/cifra/src/drbg.c create mode 100644 web/server/h2o/libh2o/deps/picotls/deps/cifra/src/drbg.h create mode 100644 web/server/h2o/libh2o/deps/picotls/deps/cifra/src/eax.c create mode 100644 web/server/h2o/libh2o/deps/picotls/deps/cifra/src/ext/cutest.h create mode 100644 web/server/h2o/libh2o/deps/picotls/deps/cifra/src/ext/handy.h create mode 100644 web/server/h2o/libh2o/deps/picotls/deps/cifra/src/gcm.c create mode 100644 web/server/h2o/libh2o/deps/picotls/deps/cifra/src/gf128.c create mode 100644 web/server/h2o/libh2o/deps/picotls/deps/cifra/src/gf128.h create mode 100644 web/server/h2o/libh2o/deps/picotls/deps/cifra/src/hmac.c create mode 100644 web/server/h2o/libh2o/deps/picotls/deps/cifra/src/hmac.h create mode 100644 web/server/h2o/libh2o/deps/picotls/deps/cifra/src/modes.c create mode 100644 web/server/h2o/libh2o/deps/picotls/deps/cifra/src/modes.h create mode 100644 web/server/h2o/libh2o/deps/picotls/deps/cifra/src/norx.c create mode 100644 web/server/h2o/libh2o/deps/picotls/deps/cifra/src/norx.h create mode 100644 web/server/h2o/libh2o/deps/picotls/deps/cifra/src/ocb.c create mode 100644 web/server/h2o/libh2o/deps/picotls/deps/cifra/src/pbkdf2.c create mode 100644 web/server/h2o/libh2o/deps/picotls/deps/cifra/src/pbkdf2.h create mode 100644 web/server/h2o/libh2o/deps/picotls/deps/cifra/src/poly1305.c create mode 100644 web/server/h2o/libh2o/deps/picotls/deps/cifra/src/poly1305.h create mode 100644 web/server/h2o/libh2o/deps/picotls/deps/cifra/src/poly1305.py create mode 100644 web/server/h2o/libh2o/deps/picotls/deps/cifra/src/prp.h create mode 100644 web/server/h2o/libh2o/deps/picotls/deps/cifra/src/salsa20.c create mode 100644 web/server/h2o/libh2o/deps/picotls/deps/cifra/src/salsa20.h create mode 100644 web/server/h2o/libh2o/deps/picotls/deps/cifra/src/sha1.c create mode 100644 web/server/h2o/libh2o/deps/picotls/deps/cifra/src/sha1.h create mode 100644 web/server/h2o/libh2o/deps/picotls/deps/cifra/src/sha2.h create mode 100644 web/server/h2o/libh2o/deps/picotls/deps/cifra/src/sha256.c create mode 100644 web/server/h2o/libh2o/deps/picotls/deps/cifra/src/sha3.c create mode 100644 web/server/h2o/libh2o/deps/picotls/deps/cifra/src/sha3.h create mode 100644 web/server/h2o/libh2o/deps/picotls/deps/cifra/src/sha512.c create mode 100644 web/server/h2o/libh2o/deps/picotls/deps/cifra/src/tassert.h create mode 100644 web/server/h2o/libh2o/deps/picotls/deps/cifra/src/testaes.c create mode 100644 web/server/h2o/libh2o/deps/picotls/deps/cifra/src/testchacha20poly1305.c create mode 100644 web/server/h2o/libh2o/deps/picotls/deps/cifra/src/testcurve25519.c create mode 100644 web/server/h2o/libh2o/deps/picotls/deps/cifra/src/testdrbg.c create mode 100644 web/server/h2o/libh2o/deps/picotls/deps/cifra/src/testmodes.c create mode 100644 web/server/h2o/libh2o/deps/picotls/deps/cifra/src/testnorx.c create mode 100644 web/server/h2o/libh2o/deps/picotls/deps/cifra/src/testnorx.katdata.inc create mode 100644 web/server/h2o/libh2o/deps/picotls/deps/cifra/src/testpoly1305.c create mode 100644 web/server/h2o/libh2o/deps/picotls/deps/cifra/src/testsalsa20.c create mode 100644 web/server/h2o/libh2o/deps/picotls/deps/cifra/src/testsha.h create mode 100644 web/server/h2o/libh2o/deps/picotls/deps/cifra/src/testsha1.c create mode 100644 web/server/h2o/libh2o/deps/picotls/deps/cifra/src/testsha2.c create mode 100644 web/server/h2o/libh2o/deps/picotls/deps/cifra/src/testsha3.c create mode 100644 web/server/h2o/libh2o/deps/picotls/deps/cifra/src/testutil.h create mode 100644 web/server/h2o/libh2o/deps/picotls/deps/micro-ecc/.gitignore create mode 100644 web/server/h2o/libh2o/deps/picotls/deps/micro-ecc/LICENSE.txt create mode 100644 web/server/h2o/libh2o/deps/picotls/deps/micro-ecc/README.md create mode 100644 web/server/h2o/libh2o/deps/picotls/deps/micro-ecc/asm_arm.inc create mode 100644 web/server/h2o/libh2o/deps/picotls/deps/micro-ecc/asm_arm_mult_square.inc create mode 100644 web/server/h2o/libh2o/deps/picotls/deps/micro-ecc/asm_arm_mult_square_umaal.inc create mode 100644 web/server/h2o/libh2o/deps/picotls/deps/micro-ecc/asm_avr.inc create mode 100644 web/server/h2o/libh2o/deps/picotls/deps/micro-ecc/asm_avr_mult_square.inc create mode 100644 web/server/h2o/libh2o/deps/picotls/deps/micro-ecc/curve-specific.inc create mode 100644 web/server/h2o/libh2o/deps/picotls/deps/micro-ecc/emk_project.py create mode 100644 web/server/h2o/libh2o/deps/picotls/deps/micro-ecc/emk_rules.py create mode 100644 web/server/h2o/libh2o/deps/picotls/deps/micro-ecc/platform-specific.inc create mode 100755 web/server/h2o/libh2o/deps/picotls/deps/micro-ecc/scripts/mult_arm.py create mode 100755 web/server/h2o/libh2o/deps/picotls/deps/micro-ecc/scripts/mult_avr.py create mode 100755 web/server/h2o/libh2o/deps/picotls/deps/micro-ecc/scripts/mult_avr_extra.py create mode 100755 web/server/h2o/libh2o/deps/picotls/deps/micro-ecc/scripts/square_arm.py create mode 100755 web/server/h2o/libh2o/deps/picotls/deps/micro-ecc/scripts/square_avr.py create mode 100644 web/server/h2o/libh2o/deps/picotls/deps/micro-ecc/test/ecc_test/ecc_test.ino create mode 100644 web/server/h2o/libh2o/deps/picotls/deps/micro-ecc/test/emk_rules.py create mode 100644 web/server/h2o/libh2o/deps/picotls/deps/micro-ecc/test/test_compress.c create mode 100644 web/server/h2o/libh2o/deps/picotls/deps/micro-ecc/test/test_compute.c create mode 100644 web/server/h2o/libh2o/deps/picotls/deps/micro-ecc/test/test_ecdh.c create mode 100644 web/server/h2o/libh2o/deps/picotls/deps/micro-ecc/test/test_ecdsa.c create mode 100644 web/server/h2o/libh2o/deps/picotls/deps/micro-ecc/test/test_ecdsa_deterministic.c.example create mode 100644 web/server/h2o/libh2o/deps/picotls/deps/micro-ecc/types.h create mode 100644 web/server/h2o/libh2o/deps/picotls/deps/micro-ecc/uECC.c create mode 100644 web/server/h2o/libh2o/deps/picotls/deps/micro-ecc/uECC.h create mode 100644 web/server/h2o/libh2o/deps/picotls/deps/micro-ecc/uECC_vli.h create mode 100644 web/server/h2o/libh2o/deps/picotls/include/picotls.h create mode 100644 web/server/h2o/libh2o/deps/picotls/include/picotls/asn1.h create mode 100644 web/server/h2o/libh2o/deps/picotls/include/picotls/minicrypto.h create mode 100644 web/server/h2o/libh2o/deps/picotls/include/picotls/openssl.h create mode 100644 web/server/h2o/libh2o/deps/picotls/include/picotls/pembase64.h create mode 100644 web/server/h2o/libh2o/deps/picotls/lib/asn1.c create mode 100644 web/server/h2o/libh2o/deps/picotls/lib/cifra.c create mode 100644 web/server/h2o/libh2o/deps/picotls/lib/minicrypto-pem.c create mode 100644 web/server/h2o/libh2o/deps/picotls/lib/openssl.c create mode 100644 web/server/h2o/libh2o/deps/picotls/lib/pembase64.c create mode 100644 web/server/h2o/libh2o/deps/picotls/lib/picotls.c create mode 100644 web/server/h2o/libh2o/deps/picotls/lib/uecc.c create mode 100755 web/server/h2o/libh2o/deps/picotls/misc/dump-github-repository.pl create mode 100644 web/server/h2o/libh2o/deps/picotls/picotls.xcodeproj/project.pbxproj create mode 100644 web/server/h2o/libh2o/deps/picotls/picotls.xcodeproj/project.xcworkspace/contents.xcworkspacedata create mode 100644 web/server/h2o/libh2o/deps/picotls/picotlsvs/cifra/ReadMe.txt create mode 100644 web/server/h2o/libh2o/deps/picotls/picotlsvs/cifra/cifra.vcxproj create mode 100644 web/server/h2o/libh2o/deps/picotls/picotlsvs/cifra/cifra.vcxproj.filters create mode 100644 web/server/h2o/libh2o/deps/picotls/picotlsvs/microecc/ReadMe.txt create mode 100644 web/server/h2o/libh2o/deps/picotls/picotlsvs/microecc/microecc.vcxproj create mode 100644 web/server/h2o/libh2o/deps/picotls/picotlsvs/microecc/microecc.vcxproj.filters create mode 100644 web/server/h2o/libh2o/deps/picotls/picotlsvs/openssl.cnf create mode 100644 web/server/h2o/libh2o/deps/picotls/picotlsvs/picotls/ReadMe.txt create mode 100644 web/server/h2o/libh2o/deps/picotls/picotlsvs/picotls/picotls.vcxproj create mode 100644 web/server/h2o/libh2o/deps/picotls/picotlsvs/picotls/picotls.vcxproj.filters create mode 100644 web/server/h2o/libh2o/deps/picotls/picotlsvs/picotls/picotls.vcxproj.user create mode 100644 web/server/h2o/libh2o/deps/picotls/picotlsvs/picotls/targetver.h create mode 100644 web/server/h2o/libh2o/deps/picotls/picotlsvs/picotls/wincompat.h create mode 100644 web/server/h2o/libh2o/deps/picotls/picotlsvs/picotls/wintimeofday.c create mode 100644 web/server/h2o/libh2o/deps/picotls/picotlsvs/picotlsvs.sln create mode 100644 web/server/h2o/libh2o/deps/picotls/picotlsvs/picotlsvs/ReadMe.txt create mode 100644 web/server/h2o/libh2o/deps/picotls/picotlsvs/picotlsvs/cert.pem create mode 100644 web/server/h2o/libh2o/deps/picotls/picotlsvs/picotlsvs/ec_cert.pem create mode 100644 web/server/h2o/libh2o/deps/picotls/picotlsvs/picotlsvs/ec_key.pem create mode 100644 web/server/h2o/libh2o/deps/picotls/picotlsvs/picotlsvs/key-test-1.pem create mode 100644 web/server/h2o/libh2o/deps/picotls/picotlsvs/picotlsvs/key-test-2.pem create mode 100644 web/server/h2o/libh2o/deps/picotls/picotlsvs/picotlsvs/key-test-3.pem create mode 100644 web/server/h2o/libh2o/deps/picotls/picotlsvs/picotlsvs/key-test-4.pem create mode 100644 web/server/h2o/libh2o/deps/picotls/picotlsvs/picotlsvs/key.pem create mode 100644 web/server/h2o/libh2o/deps/picotls/picotlsvs/picotlsvs/myec1.pem create mode 100644 web/server/h2o/libh2o/deps/picotls/picotlsvs/picotlsvs/openssl.cnf create mode 100644 web/server/h2o/libh2o/deps/picotls/picotlsvs/picotlsvs/picotlsvs.c create mode 100644 web/server/h2o/libh2o/deps/picotls/picotlsvs/picotlsvs/picotlsvs.vcxproj create mode 100644 web/server/h2o/libh2o/deps/picotls/picotlsvs/picotlsvs/picotlsvs.vcxproj.filters create mode 100644 web/server/h2o/libh2o/deps/picotls/picotlsvs/picotlsvs/picotlsvs.vcxproj.user create mode 100644 web/server/h2o/libh2o/deps/picotls/picotlsvs/picotlsvs/targetver.h create mode 100644 web/server/h2o/libh2o/deps/picotls/picotlsvs/testopenssl/testopenssl.vcxproj create mode 100644 web/server/h2o/libh2o/deps/picotls/picotlsvs/testopenssl/testopenssl.vcxproj.filters create mode 100644 web/server/h2o/libh2o/deps/picotls/t/cli.c create mode 100644 web/server/h2o/libh2o/deps/picotls/t/minicrypto.c create mode 100644 web/server/h2o/libh2o/deps/picotls/t/openssl.c create mode 100644 web/server/h2o/libh2o/deps/picotls/t/picotls.c create mode 100644 web/server/h2o/libh2o/deps/picotls/t/test.h create mode 100644 web/server/h2o/libh2o/deps/picotls/t/util.h create mode 100644 web/server/h2o/libh2o/deps/ssl-conservatory/.gitattributes create mode 100644 web/server/h2o/libh2o/deps/ssl-conservatory/.gitignore create mode 100644 web/server/h2o/libh2o/deps/ssl-conservatory/LICENSE create mode 100644 web/server/h2o/libh2o/deps/ssl-conservatory/README.md create mode 100644 web/server/h2o/libh2o/deps/ssl-conservatory/ios/README.md create mode 100644 web/server/h2o/libh2o/deps/ssl-conservatory/ios/SSLCertificatePinning/SSLCertificatePinning.xcodeproj/project.pbxproj create mode 100644 web/server/h2o/libh2o/deps/ssl-conservatory/ios/SSLCertificatePinning/SSLCertificatePinning/ISPCertificatePinning.h create mode 100644 web/server/h2o/libh2o/deps/ssl-conservatory/ios/SSLCertificatePinning/SSLCertificatePinning/ISPCertificatePinning.m create mode 100644 web/server/h2o/libh2o/deps/ssl-conservatory/ios/SSLCertificatePinning/SSLCertificatePinning/ISPPinnedNSURLConnectionDelegate.h create mode 100644 web/server/h2o/libh2o/deps/ssl-conservatory/ios/SSLCertificatePinning/SSLCertificatePinning/ISPPinnedNSURLConnectionDelegate.m create mode 100644 web/server/h2o/libh2o/deps/ssl-conservatory/ios/SSLCertificatePinning/SSLCertificatePinning/ISPPinnedNSURLSessionDelegate.h create mode 100644 web/server/h2o/libh2o/deps/ssl-conservatory/ios/SSLCertificatePinning/SSLCertificatePinning/ISPPinnedNSURLSessionDelegate.m create mode 100644 web/server/h2o/libh2o/deps/ssl-conservatory/ios/SSLCertificatePinning/SSLCertificatePinning/SSLCertificatePinning-Prefix.pch create mode 100644 web/server/h2o/libh2o/deps/ssl-conservatory/ios/SSLCertificatePinning/SSLCertificatePinningTests/NSURLConnectionTests.m create mode 100644 web/server/h2o/libh2o/deps/ssl-conservatory/ios/SSLCertificatePinning/SSLCertificatePinningTests/NSURLSessionTests.m create mode 100644 web/server/h2o/libh2o/deps/ssl-conservatory/ios/SSLCertificatePinning/SSLCertificatePinningTests/SSLCertificatePinningTests-Info.plist create mode 100644 web/server/h2o/libh2o/deps/ssl-conservatory/ios/SSLCertificatePinning/SSLCertificatePinningTests/SSLPinsTestUtility.h create mode 100644 web/server/h2o/libh2o/deps/ssl-conservatory/ios/SSLCertificatePinning/SSLCertificatePinningTests/SSLPinsTestUtility.m create mode 100644 web/server/h2o/libh2o/deps/ssl-conservatory/ios/SSLCertificatePinning/SSLCertificatePinningTests/VeriSignClass3PublicPrimaryCertificationAuthority-G5.der create mode 100644 web/server/h2o/libh2o/deps/ssl-conservatory/ios/SSLCertificatePinning/SSLCertificatePinningTests/en.lproj/InfoPlist.strings create mode 100644 web/server/h2o/libh2o/deps/ssl-conservatory/ios/SSLCertificatePinning/SSLCertificatePinningTests/www.isecpartners.com.der create mode 100644 web/server/h2o/libh2o/deps/ssl-conservatory/openssl/DigiCertHighAssuranceEVRootCA.pem create mode 100644 web/server/h2o/libh2o/deps/ssl-conservatory/openssl/Makefile create mode 100644 web/server/h2o/libh2o/deps/ssl-conservatory/openssl/Makefile_mingw create mode 100644 web/server/h2o/libh2o/deps/ssl-conservatory/openssl/README.md create mode 100644 web/server/h2o/libh2o/deps/ssl-conservatory/openssl/everything-you-wanted-to-know-about-openssl.pdf create mode 100644 web/server/h2o/libh2o/deps/ssl-conservatory/openssl/openssl_hostname_validation.c create mode 100644 web/server/h2o/libh2o/deps/ssl-conservatory/openssl/openssl_hostname_validation.h create mode 100755 web/server/h2o/libh2o/deps/ssl-conservatory/openssl/test_client create mode 100644 web/server/h2o/libh2o/deps/ssl-conservatory/openssl/test_client.c create mode 100644 web/server/h2o/libh2o/deps/yaml/CMakeLists.txt create mode 100644 web/server/h2o/libh2o/deps/yaml/LICENSE create mode 100644 web/server/h2o/libh2o/deps/yaml/Makefile.am create mode 100644 web/server/h2o/libh2o/deps/yaml/Makefile.in create mode 100644 web/server/h2o/libh2o/deps/yaml/README create mode 100644 web/server/h2o/libh2o/deps/yaml/aclocal.m4 create mode 100644 web/server/h2o/libh2o/deps/yaml/config.h.in create mode 100755 web/server/h2o/libh2o/deps/yaml/config/config.guess create mode 100755 web/server/h2o/libh2o/deps/yaml/config/config.sub create mode 100755 web/server/h2o/libh2o/deps/yaml/config/depcomp create mode 100755 web/server/h2o/libh2o/deps/yaml/config/install-sh create mode 100644 web/server/h2o/libh2o/deps/yaml/config/ltmain.sh create mode 100755 web/server/h2o/libh2o/deps/yaml/config/missing create mode 100755 web/server/h2o/libh2o/deps/yaml/configure create mode 100644 web/server/h2o/libh2o/deps/yaml/configure.ac create mode 100644 web/server/h2o/libh2o/deps/yaml/doc/doxygen.cfg create mode 100644 web/server/h2o/libh2o/deps/yaml/doc/html/annotated.html create mode 100644 web/server/h2o/libh2o/deps/yaml/doc/html/bc_s.png create mode 100644 web/server/h2o/libh2o/deps/yaml/doc/html/classes.html create mode 100644 web/server/h2o/libh2o/deps/yaml/doc/html/closed.png create mode 100644 web/server/h2o/libh2o/deps/yaml/doc/html/doxygen.css create mode 100644 web/server/h2o/libh2o/deps/yaml/doc/html/doxygen.png create mode 100644 web/server/h2o/libh2o/deps/yaml/doc/html/files.html create mode 100644 web/server/h2o/libh2o/deps/yaml/doc/html/functions.html create mode 100644 web/server/h2o/libh2o/deps/yaml/doc/html/functions_0x62.html create mode 100644 web/server/h2o/libh2o/deps/yaml/doc/html/functions_0x63.html create mode 100644 web/server/h2o/libh2o/deps/yaml/doc/html/functions_0x64.html create mode 100644 web/server/h2o/libh2o/deps/yaml/doc/html/functions_0x65.html create mode 100644 web/server/h2o/libh2o/deps/yaml/doc/html/functions_0x66.html create mode 100644 web/server/h2o/libh2o/deps/yaml/doc/html/functions_0x68.html create mode 100644 web/server/h2o/libh2o/deps/yaml/doc/html/functions_0x69.html create mode 100644 web/server/h2o/libh2o/deps/yaml/doc/html/functions_0x6b.html create mode 100644 web/server/h2o/libh2o/deps/yaml/doc/html/functions_0x6c.html create mode 100644 web/server/h2o/libh2o/deps/yaml/doc/html/functions_0x6d.html create mode 100644 web/server/h2o/libh2o/deps/yaml/doc/html/functions_0x6e.html create mode 100644 web/server/h2o/libh2o/deps/yaml/doc/html/functions_0x6f.html create mode 100644 web/server/h2o/libh2o/deps/yaml/doc/html/functions_0x70.html create mode 100644 web/server/h2o/libh2o/deps/yaml/doc/html/functions_0x71.html create mode 100644 web/server/h2o/libh2o/deps/yaml/doc/html/functions_0x72.html create mode 100644 web/server/h2o/libh2o/deps/yaml/doc/html/functions_0x73.html create mode 100644 web/server/h2o/libh2o/deps/yaml/doc/html/functions_0x74.html create mode 100644 web/server/h2o/libh2o/deps/yaml/doc/html/functions_0x75.html create mode 100644 web/server/h2o/libh2o/deps/yaml/doc/html/functions_0x76.html create mode 100644 web/server/h2o/libh2o/deps/yaml/doc/html/functions_0x77.html create mode 100644 web/server/h2o/libh2o/deps/yaml/doc/html/functions_vars.html create mode 100644 web/server/h2o/libh2o/deps/yaml/doc/html/functions_vars_0x62.html create mode 100644 web/server/h2o/libh2o/deps/yaml/doc/html/functions_vars_0x63.html create mode 100644 web/server/h2o/libh2o/deps/yaml/doc/html/functions_vars_0x64.html create mode 100644 web/server/h2o/libh2o/deps/yaml/doc/html/functions_vars_0x65.html create mode 100644 web/server/h2o/libh2o/deps/yaml/doc/html/functions_vars_0x66.html create mode 100644 web/server/h2o/libh2o/deps/yaml/doc/html/functions_vars_0x68.html create mode 100644 web/server/h2o/libh2o/deps/yaml/doc/html/functions_vars_0x69.html create mode 100644 web/server/h2o/libh2o/deps/yaml/doc/html/functions_vars_0x6b.html create mode 100644 web/server/h2o/libh2o/deps/yaml/doc/html/functions_vars_0x6c.html create mode 100644 web/server/h2o/libh2o/deps/yaml/doc/html/functions_vars_0x6d.html create mode 100644 web/server/h2o/libh2o/deps/yaml/doc/html/functions_vars_0x6e.html create mode 100644 web/server/h2o/libh2o/deps/yaml/doc/html/functions_vars_0x6f.html create mode 100644 web/server/h2o/libh2o/deps/yaml/doc/html/functions_vars_0x70.html create mode 100644 web/server/h2o/libh2o/deps/yaml/doc/html/functions_vars_0x71.html create mode 100644 web/server/h2o/libh2o/deps/yaml/doc/html/functions_vars_0x72.html create mode 100644 web/server/h2o/libh2o/deps/yaml/doc/html/functions_vars_0x73.html create mode 100644 web/server/h2o/libh2o/deps/yaml/doc/html/functions_vars_0x74.html create mode 100644 web/server/h2o/libh2o/deps/yaml/doc/html/functions_vars_0x75.html create mode 100644 web/server/h2o/libh2o/deps/yaml/doc/html/functions_vars_0x76.html create mode 100644 web/server/h2o/libh2o/deps/yaml/doc/html/functions_vars_0x77.html create mode 100644 web/server/h2o/libh2o/deps/yaml/doc/html/globals.html create mode 100644 web/server/h2o/libh2o/deps/yaml/doc/html/globals_defs.html create mode 100644 web/server/h2o/libh2o/deps/yaml/doc/html/globals_enum.html create mode 100644 web/server/h2o/libh2o/deps/yaml/doc/html/globals_eval.html create mode 100644 web/server/h2o/libh2o/deps/yaml/doc/html/globals_func.html create mode 100644 web/server/h2o/libh2o/deps/yaml/doc/html/globals_type.html create mode 100644 web/server/h2o/libh2o/deps/yaml/doc/html/group__basic.html create mode 100644 web/server/h2o/libh2o/deps/yaml/doc/html/group__emitter.html create mode 100644 web/server/h2o/libh2o/deps/yaml/doc/html/group__events.html create mode 100644 web/server/h2o/libh2o/deps/yaml/doc/html/group__export.html create mode 100644 web/server/h2o/libh2o/deps/yaml/doc/html/group__nodes.html create mode 100644 web/server/h2o/libh2o/deps/yaml/doc/html/group__parser.html create mode 100644 web/server/h2o/libh2o/deps/yaml/doc/html/group__styles.html create mode 100644 web/server/h2o/libh2o/deps/yaml/doc/html/group__tokens.html create mode 100644 web/server/h2o/libh2o/deps/yaml/doc/html/group__version.html create mode 100644 web/server/h2o/libh2o/deps/yaml/doc/html/index.html create mode 100644 web/server/h2o/libh2o/deps/yaml/doc/html/modules.html create mode 100644 web/server/h2o/libh2o/deps/yaml/doc/html/nav_f.png create mode 100644 web/server/h2o/libh2o/deps/yaml/doc/html/nav_h.png create mode 100644 web/server/h2o/libh2o/deps/yaml/doc/html/open.png create mode 100644 web/server/h2o/libh2o/deps/yaml/doc/html/structyaml__alias__data__s.html create mode 100644 web/server/h2o/libh2o/deps/yaml/doc/html/structyaml__document__s.html create mode 100644 web/server/h2o/libh2o/deps/yaml/doc/html/structyaml__emitter__s.html create mode 100644 web/server/h2o/libh2o/deps/yaml/doc/html/structyaml__event__s.html create mode 100644 web/server/h2o/libh2o/deps/yaml/doc/html/structyaml__mark__s.html create mode 100644 web/server/h2o/libh2o/deps/yaml/doc/html/structyaml__node__pair__s.html create mode 100644 web/server/h2o/libh2o/deps/yaml/doc/html/structyaml__node__s.html create mode 100644 web/server/h2o/libh2o/deps/yaml/doc/html/structyaml__parser__s.html create mode 100644 web/server/h2o/libh2o/deps/yaml/doc/html/structyaml__simple__key__s.html create mode 100644 web/server/h2o/libh2o/deps/yaml/doc/html/structyaml__tag__directive__s.html create mode 100644 web/server/h2o/libh2o/deps/yaml/doc/html/structyaml__token__s.html create mode 100644 web/server/h2o/libh2o/deps/yaml/doc/html/structyaml__version__directive__s.html create mode 100644 web/server/h2o/libh2o/deps/yaml/doc/html/tab_a.png create mode 100644 web/server/h2o/libh2o/deps/yaml/doc/html/tab_b.png create mode 100644 web/server/h2o/libh2o/deps/yaml/doc/html/tab_h.png create mode 100644 web/server/h2o/libh2o/deps/yaml/doc/html/tab_s.png create mode 100644 web/server/h2o/libh2o/deps/yaml/doc/html/tabs.css create mode 100644 web/server/h2o/libh2o/deps/yaml/doc/html/yaml_8h.html create mode 100644 web/server/h2o/libh2o/deps/yaml/include/Makefile.am create mode 100644 web/server/h2o/libh2o/deps/yaml/include/Makefile.in create mode 100644 web/server/h2o/libh2o/deps/yaml/include/yaml.h create mode 100644 web/server/h2o/libh2o/deps/yaml/src/Makefile.am create mode 100644 web/server/h2o/libh2o/deps/yaml/src/Makefile.in create mode 100644 web/server/h2o/libh2o/deps/yaml/src/api.c create mode 100644 web/server/h2o/libh2o/deps/yaml/src/dumper.c create mode 100644 web/server/h2o/libh2o/deps/yaml/src/emitter.c create mode 100644 web/server/h2o/libh2o/deps/yaml/src/loader.c create mode 100644 web/server/h2o/libh2o/deps/yaml/src/parser.c create mode 100644 web/server/h2o/libh2o/deps/yaml/src/reader.c create mode 100644 web/server/h2o/libh2o/deps/yaml/src/scanner.c create mode 100644 web/server/h2o/libh2o/deps/yaml/src/writer.c create mode 100644 web/server/h2o/libh2o/deps/yaml/src/yaml_private.h create mode 100644 web/server/h2o/libh2o/deps/yaml/tests/Makefile.am create mode 100644 web/server/h2o/libh2o/deps/yaml/tests/Makefile.in create mode 100644 web/server/h2o/libh2o/deps/yaml/tests/example-deconstructor-alt.c create mode 100644 web/server/h2o/libh2o/deps/yaml/tests/example-deconstructor.c create mode 100644 web/server/h2o/libh2o/deps/yaml/tests/example-reformatter-alt.c create mode 100644 web/server/h2o/libh2o/deps/yaml/tests/example-reformatter.c create mode 100644 web/server/h2o/libh2o/deps/yaml/tests/run-dumper.c create mode 100644 web/server/h2o/libh2o/deps/yaml/tests/run-emitter.c create mode 100644 web/server/h2o/libh2o/deps/yaml/tests/run-loader.c create mode 100644 web/server/h2o/libh2o/deps/yaml/tests/run-parser.c create mode 100644 web/server/h2o/libh2o/deps/yaml/tests/run-scanner.c create mode 100644 web/server/h2o/libh2o/deps/yaml/tests/test-reader.c create mode 100644 web/server/h2o/libh2o/deps/yaml/tests/test-version.c create mode 100644 web/server/h2o/libh2o/deps/yaml/win32/Makefile.am create mode 100644 web/server/h2o/libh2o/deps/yaml/win32/Makefile.in create mode 100644 web/server/h2o/libh2o/deps/yaml/win32/config.h create mode 100644 web/server/h2o/libh2o/deps/yaml/win32/vc6/example_deconstructor.dsp create mode 100644 web/server/h2o/libh2o/deps/yaml/win32/vc6/example_deconstructor_alt.dsp create mode 100644 web/server/h2o/libh2o/deps/yaml/win32/vc6/example_reformatter.dsp create mode 100644 web/server/h2o/libh2o/deps/yaml/win32/vc6/example_reformatter_alt.dsp create mode 100644 web/server/h2o/libh2o/deps/yaml/win32/vc6/libyaml.dsw create mode 100644 web/server/h2o/libh2o/deps/yaml/win32/vc6/run_dumper.dsp create mode 100644 web/server/h2o/libh2o/deps/yaml/win32/vc6/run_emitter.dsp create mode 100644 web/server/h2o/libh2o/deps/yaml/win32/vc6/run_loader.dsp create mode 100644 web/server/h2o/libh2o/deps/yaml/win32/vc6/run_parser.dsp create mode 100644 web/server/h2o/libh2o/deps/yaml/win32/vc6/run_scanner.dsp create mode 100644 web/server/h2o/libh2o/deps/yaml/win32/vc6/test_reader.dsp create mode 100644 web/server/h2o/libh2o/deps/yaml/win32/vc6/test_version.dsp create mode 100644 web/server/h2o/libh2o/deps/yaml/win32/vc6/yaml.dsp create mode 100644 web/server/h2o/libh2o/deps/yaml/win32/vc6/yamldll.dsp create mode 100644 web/server/h2o/libh2o/deps/yaml/win32/vs2003/example_deconstructor.vcproj create mode 100644 web/server/h2o/libh2o/deps/yaml/win32/vs2003/example_deconstructor_alt.vcproj create mode 100644 web/server/h2o/libh2o/deps/yaml/win32/vs2003/example_reformatter.vcproj create mode 100644 web/server/h2o/libh2o/deps/yaml/win32/vs2003/example_reformatter_alt.vcproj create mode 100644 web/server/h2o/libh2o/deps/yaml/win32/vs2003/libyaml.sln create mode 100644 web/server/h2o/libh2o/deps/yaml/win32/vs2003/run_dumper.vcproj create mode 100644 web/server/h2o/libh2o/deps/yaml/win32/vs2003/run_emitter.vcproj create mode 100644 web/server/h2o/libh2o/deps/yaml/win32/vs2003/run_loader.vcproj create mode 100644 web/server/h2o/libh2o/deps/yaml/win32/vs2003/run_parser.vcproj create mode 100644 web/server/h2o/libh2o/deps/yaml/win32/vs2003/run_scanner.vcproj create mode 100644 web/server/h2o/libh2o/deps/yaml/win32/vs2003/test_reader.vcproj create mode 100644 web/server/h2o/libh2o/deps/yaml/win32/vs2003/test_version.vcproj create mode 100644 web/server/h2o/libh2o/deps/yaml/win32/vs2003/yaml.vcproj create mode 100644 web/server/h2o/libh2o/deps/yaml/win32/vs2003/yamldll.vcproj create mode 100644 web/server/h2o/libh2o/deps/yaml/win32/vs2008/example_deconstructor.vcproj create mode 100644 web/server/h2o/libh2o/deps/yaml/win32/vs2008/example_deconstructor_alt.vcproj create mode 100644 web/server/h2o/libh2o/deps/yaml/win32/vs2008/example_reformatter.vcproj create mode 100644 web/server/h2o/libh2o/deps/yaml/win32/vs2008/example_reformatter_alt.vcproj create mode 100644 web/server/h2o/libh2o/deps/yaml/win32/vs2008/libyaml.sln create mode 100644 web/server/h2o/libh2o/deps/yaml/win32/vs2008/run_dumper.vcproj create mode 100644 web/server/h2o/libh2o/deps/yaml/win32/vs2008/run_emitter.vcproj create mode 100644 web/server/h2o/libh2o/deps/yaml/win32/vs2008/run_loader.vcproj create mode 100644 web/server/h2o/libh2o/deps/yaml/win32/vs2008/run_parser.vcproj create mode 100644 web/server/h2o/libh2o/deps/yaml/win32/vs2008/run_scanner.vcproj create mode 100644 web/server/h2o/libh2o/deps/yaml/win32/vs2008/test_reader.vcproj create mode 100644 web/server/h2o/libh2o/deps/yaml/win32/vs2008/test_version.vcproj create mode 100644 web/server/h2o/libh2o/deps/yaml/win32/vs2008/yaml.vcproj create mode 100644 web/server/h2o/libh2o/deps/yaml/win32/vs2008/yamldll.vcproj create mode 100644 web/server/h2o/libh2o/deps/yaml/yaml-0.1.pc.in create mode 100644 web/server/h2o/libh2o/deps/yoml/.gitmodules create mode 100644 web/server/h2o/libh2o/deps/yoml/Makefile create mode 100644 web/server/h2o/libh2o/deps/yoml/README.md create mode 100644 web/server/h2o/libh2o/deps/yoml/test-yoml.c create mode 100644 web/server/h2o/libh2o/deps/yoml/yoml-parser.h create mode 100644 web/server/h2o/libh2o/deps/yoml/yoml.h (limited to 'web/server/h2o/libh2o/deps') diff --git a/web/server/h2o/libh2o/deps/brotli/.gitignore b/web/server/h2o/libh2o/deps/brotli/.gitignore new file mode 100644 index 00000000..162f0365 --- /dev/null +++ b/web/server/h2o/libh2o/deps/brotli/.gitignore @@ -0,0 +1,8 @@ +*.o +*.pyc +*.txt.uncompressed +*.bro +*.unbro +tools/bro +build/ +dist/ diff --git a/web/server/h2o/libh2o/deps/brotli/.gitmodules b/web/server/h2o/libh2o/deps/brotli/.gitmodules new file mode 100644 index 00000000..3d602550 --- /dev/null +++ b/web/server/h2o/libh2o/deps/brotli/.gitmodules @@ -0,0 +1,3 @@ +[submodule "terryfy"] + path = terryfy + url = https://github.com/MacPython/terryfy.git diff --git a/web/server/h2o/libh2o/deps/brotli/.travis.yml b/web/server/h2o/libh2o/deps/brotli/.travis.yml new file mode 100644 index 00000000..c6fd74d7 --- /dev/null +++ b/web/server/h2o/libh2o/deps/brotli/.travis.yml @@ -0,0 +1,32 @@ +language: +- objective-c +env: + matrix: + - INSTALL_TYPE='system' VERSION=2.7 + - INSTALL_TYPE='macpython' VERSION=2.7.10 CC=clang CXX=clang++ + - INSTALL_TYPE='macpython' VERSION=3.4.3 CC=clang CXX=clang++ + - INSTALL_TYPE='macpython' VERSION=3.5.0 CC=clang CXX=clang++ + - INSTALL_TYPE='homebrew' VERSION=2.7.10 + - INSTALL_TYPE='homebrew' VERSION=3.4.3 + - INSTALL_TYPE='homebrew' VERSION=3.5.0 +install: +- source terryfy/travis_tools.sh +- get_python_environment $INSTALL_TYPE $VERSION venv +- pip install --upgrade wheel +script: +- python setup.py build_ext test +after_success: +- pip wheel -w dist . +before_deploy: +- export WHEELS=$(ls ./dist/*.whl) + +deploy: + provider: releases + api_key: + secure: YcCBi6W/w4dtKCa59Wfm8L5lGWvK7KxaFNDr3yh1Hz5aStXXf758pEMHGewnlbfbwuj5a3SjBb1nLp1M69OQJfxm442uXBaBKo52PM9PPbD7NjvbNIso73pqcSODXQXKuZxDFpEhfuDTVq3hUkUqiwhChWhrFucJsSL51i7qSss= + file: + - "${WHEELS}" + skip_cleanup: true + on: + repo: google/brotli + tags: true diff --git a/web/server/h2o/libh2o/deps/brotli/CONTRIBUTING.md b/web/server/h2o/libh2o/deps/brotli/CONTRIBUTING.md new file mode 100644 index 00000000..a00e37d1 --- /dev/null +++ b/web/server/h2o/libh2o/deps/brotli/CONTRIBUTING.md @@ -0,0 +1,27 @@ +Want to contribute? Great! First, read this page (including the small print at +the end). + +### Before you contribute +Before we can use your code, you must sign the +[Google Individual Contributor License Agreement] +(https://cla.developers.google.com/about/google-individual) +(CLA), which you can do online. The CLA is necessary mainly because you own the +copyright to your changes, even after your contribution becomes part of our +codebase, so we need your permission to use and distribute your code. We also +need to be sure of various other things—for instance that you'll tell us if you +know that your code infringes on other people's patents. You don't have to sign +the CLA until after you've submitted your code for review and a member has +approved it, but you must do it before we can put your code into our codebase. +Before you start working on a larger contribution, you should get in touch with +us first through the issue tracker with your idea so that we can help out and +possibly guide you. Coordinating up front makes it much easier to avoid +frustration later on. + +### Code reviews +All submissions, including submissions by project members, require review. We +use Github pull requests for this purpose. + +### The small print +Contributions made by corporations are covered by a different agreement than +the one above, the [Software Grant and Corporate Contributor License Agreement] +(https://cla.developers.google.com/about/google-corporate). diff --git a/web/server/h2o/libh2o/deps/brotli/LICENSE b/web/server/h2o/libh2o/deps/brotli/LICENSE new file mode 100644 index 00000000..6298a5dc --- /dev/null +++ b/web/server/h2o/libh2o/deps/brotli/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2009, 2010, 2013-2015 by the Brotli Authors. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/web/server/h2o/libh2o/deps/brotli/README.md b/web/server/h2o/libh2o/deps/brotli/README.md new file mode 100644 index 00000000..520a0657 --- /dev/null +++ b/web/server/h2o/libh2o/deps/brotli/README.md @@ -0,0 +1,17 @@ +brotli +====== + +Brotli is a generic-purpose lossless compression algorithm that compresses data +using a combination of a modern variant of the LZ77 algorithm, Huffman coding +and 2nd order context modeling, with a compression ratio comparable to the best +currently available general-purpose compression methods. It is similar in speed +with deflate but offers more dense compression. + +The specification of the Brotli Compressed Data Format is defined in the +following internet draft: +http://www.ietf.org/id/draft-alakuijala-brotli + +Brotli is open-sourced under the MIT License, see the LICENSE file. + +Brotli mailing list: +https://groups.google.com/forum/#!forum/brotli diff --git a/web/server/h2o/libh2o/deps/brotli/appveyor.yml b/web/server/h2o/libh2o/deps/brotli/appveyor.yml new file mode 100644 index 00000000..d4144252 --- /dev/null +++ b/web/server/h2o/libh2o/deps/brotli/appveyor.yml @@ -0,0 +1,77 @@ +environment: + + global: + # SDK v7.0 MSVC Express 2008's SetEnv.cmd script will fail if the + # /E:ON and /V:ON options are not enabled in the batch script intepreter + # See: http://stackoverflow.com/a/13751649/163740 + WITH_COMPILER: "cmd /E:ON /V:ON /C .\\appveyor\\run_with_compiler.cmd" + + matrix: + - PYTHON: "C:\\Python27" + PYTHON_VERSION: "2.7.x" + PYTHON_ARCH: "32" + + - PYTHON: "C:\\Python34" + PYTHON_VERSION: "3.4.x" + PYTHON_ARCH: "32" + + - PYTHON: "C:\\Python35" + PYTHON_VERSION: "3.5.0" + PYTHON_ARCH: "32" + + - PYTHON: "C:\\Python27-x64" + PYTHON_VERSION: "2.7.x" + PYTHON_ARCH: "64" + + - PYTHON: "C:\\Python34-x64" + PYTHON_VERSION: "3.4.x" + PYTHON_ARCH: "64" + + - PYTHON: "C:\\Python35-x64" + PYTHON_VERSION: "3.5.0" + PYTHON_ARCH: "64" + +init: + - "ECHO %PYTHON% %PYTHON_VERSION% %PYTHON_ARCH%" + +install: + # install Python and pip when not already installed + - ps: if (-not(Test-Path($env:PYTHON))) { & appveyor\install.ps1 } + + # prepend newly installed Python to the PATH + - "SET PATH=%PYTHON%;%PYTHON%\\Scripts;%PATH%" + + # check that we have the expected version and architecture for Python + - "python --version" + - "python -c \"import struct; print(struct.calcsize('P') * 8)\"" + + # upgrade pip to avoid out-of-date warnings + - "pip install --disable-pip-version-check --user --upgrade pip" + + # install wheel to build compiled packages + - "pip install --upgrade wheel" + +build: false + +test_script: + - "%WITH_COMPILER% python setup.py build_ext test" + +after_test: + # if tests are successful, create binary packages for the project + - "%WITH_COMPILER% pip wheel -w dist ." + +artifacts: + # archive the generated packages in the ci.appveyor.com build report + - path: dist\* + +# For info, see: http://www.appveyor.com/docs/deployment/github + +deploy: + - provider: GitHub + auth_token: + secure: dfL56DgbwuGJNNE5GzKi/pAgBQnJ37Du+AnCtnsTnIYxpis8ah3fPmA/G+bn4NJ3 + artifact: + draft: false + prerelease: false + on: + appveyor_repo_tag: true diff --git a/web/server/h2o/libh2o/deps/brotli/appveyor/install.ps1 b/web/server/h2o/libh2o/deps/brotli/appveyor/install.ps1 new file mode 100644 index 00000000..bdd0cd37 --- /dev/null +++ b/web/server/h2o/libh2o/deps/brotli/appveyor/install.ps1 @@ -0,0 +1,177 @@ +# Sample script to install Python and pip under Windows +# Authors: Olivier Grisel, Jonathan Helmus, Kyle Kastner, and Alex Willmer +# License: CC0 1.0 Universal: http://creativecommons.org/publicdomain/zero/1.0/ +# Source: https://github.com/ogrisel/python-appveyor-demo/blob/master/appveyor/install.ps1 + +$BASE_URL = "https://www.python.org/ftp/python/" +$GET_PIP_URL = "https://bootstrap.pypa.io/get-pip.py" +$GET_PIP_PATH = "C:\get-pip.py" + +$PYTHON_PRERELEASE_REGEX = @" +(?x) +(?\d+) +\. +(?\d+) +\. +(?\d+) +(?[a-z]{1,2}\d+) +"@ + + +function Download ($filename, $url) { + $webclient = New-Object System.Net.WebClient + + $basedir = $pwd.Path + "\" + $filepath = $basedir + $filename + if (Test-Path $filename) { + Write-Host "Reusing" $filepath + return $filepath + } + + # Download and retry up to 3 times in case of network transient errors. + Write-Host "Downloading" $filename "from" $url + $retry_attempts = 2 + for ($i = 0; $i -lt $retry_attempts; $i++) { + try { + $webclient.DownloadFile($url, $filepath) + break + } + Catch [Exception]{ + Start-Sleep 1 + } + } + if (Test-Path $filepath) { + Write-Host "File saved at" $filepath + } else { + # Retry once to get the error message if any at the last try + $webclient.DownloadFile($url, $filepath) + } + return $filepath +} + + +function ParsePythonVersion ($python_version) { + if ($python_version -match $PYTHON_PRERELEASE_REGEX) { + return ([int]$matches.major, [int]$matches.minor, [int]$matches.micro, + $matches.prerelease) + } + $version_obj = [version]$python_version + return ($version_obj.major, $version_obj.minor, $version_obj.build, "") +} + + +function DownloadPython ($python_version, $platform_suffix) { + $major, $minor, $micro, $prerelease = ParsePythonVersion $python_version + + if (($major -le 2 -and $micro -eq 0) ` + -or ($major -eq 3 -and $minor -le 2 -and $micro -eq 0) ` + ) { + $dir = "$major.$minor" + $python_version = "$major.$minor$prerelease" + } else { + $dir = "$major.$minor.$micro" + } + + if ($prerelease) { + if (($major -le 2) ` + -or ($major -eq 3 -and $minor -eq 1) ` + -or ($major -eq 3 -and $minor -eq 2) ` + -or ($major -eq 3 -and $minor -eq 3) ` + ) { + $dir = "$dir/prev" + } + } + + if (($major -le 2) -or ($major -le 3 -and $minor -le 4)) { + $ext = "msi" + if ($platform_suffix) { + $platform_suffix = ".$platform_suffix" + } + } else { + $ext = "exe" + if ($platform_suffix) { + $platform_suffix = "-$platform_suffix" + } + } + + $filename = "python-$python_version$platform_suffix.$ext" + $url = "$BASE_URL$dir/$filename" + $filepath = Download $filename $url + return $filepath +} + + +function InstallPython ($python_version, $architecture, $python_home) { + Write-Host "Installing Python" $python_version "for" $architecture "bit architecture to" $python_home + if (Test-Path $python_home) { + Write-Host $python_home "already exists, skipping." + return $false + } + if ($architecture -eq "32") { + $platform_suffix = "" + } else { + $platform_suffix = "amd64" + } + $installer_path = DownloadPython $python_version $platform_suffix + $installer_ext = [System.IO.Path]::GetExtension($installer_path) + Write-Host "Installing $installer_path to $python_home" + $install_log = $python_home + ".log" + if ($installer_ext -eq '.msi') { + InstallPythonMSI $installer_path $python_home $install_log + } else { + InstallPythonEXE $installer_path $python_home $install_log + } + if (Test-Path $python_home) { + Write-Host "Python $python_version ($architecture) installation complete" + } else { + Write-Host "Failed to install Python in $python_home" + Get-Content -Path $install_log + Exit 1 + } +} + + +function InstallPythonEXE ($exepath, $python_home, $install_log) { + $install_args = "/quiet InstallAllUsers=1 TargetDir=$python_home" + RunCommand $exepath $install_args +} + + +function InstallPythonMSI ($msipath, $python_home, $install_log) { + $install_args = "/qn /log $install_log /i $msipath TARGETDIR=$python_home" + $uninstall_args = "/qn /x $msipath" + RunCommand "msiexec.exe" $install_args + if (-not(Test-Path $python_home)) { + Write-Host "Python seems to be installed else-where, reinstalling." + RunCommand "msiexec.exe" $uninstall_args + RunCommand "msiexec.exe" $install_args + } +} + +function RunCommand ($command, $command_args) { + Write-Host $command $command_args + Start-Process -FilePath $command -ArgumentList $command_args -Wait -Passthru +} + + +function InstallPip ($python_home) { + $pip_path = $python_home + "\Scripts\pip.exe" + $python_path = $python_home + "\python.exe" + if (-not(Test-Path $pip_path)) { + Write-Host "Installing pip..." + $webclient = New-Object System.Net.WebClient + $webclient.DownloadFile($GET_PIP_URL, $GET_PIP_PATH) + Write-Host "Executing:" $python_path $GET_PIP_PATH + & $python_path $GET_PIP_PATH + } else { + Write-Host "pip already installed." + } +} + + +function main () { + InstallPython $env:PYTHON_VERSION $env:PYTHON_ARCH $env:PYTHON + InstallPip $env:PYTHON +} + +main \ No newline at end of file diff --git a/web/server/h2o/libh2o/deps/brotli/appveyor/run_with_compiler.cmd b/web/server/h2o/libh2o/deps/brotli/appveyor/run_with_compiler.cmd new file mode 100644 index 00000000..ad125ec5 --- /dev/null +++ b/web/server/h2o/libh2o/deps/brotli/appveyor/run_with_compiler.cmd @@ -0,0 +1,80 @@ +:: To build extensions for 64 bit Python 3, we need to configure environment +:: variables to use the MSVC 2010 C++ compilers from GRMSDKX_EN_DVD.iso of: +:: MS Windows SDK for Windows 7 and .NET Framework 4 (SDK v7.1) +:: +:: To build extensions for 64 bit Python 2, we need to configure environment +:: variables to use the MSVC 2008 C++ compilers from GRMSDKX_EN_DVD.iso of: +:: MS Windows SDK for Windows 7 and .NET Framework 3.5 (SDK v7.0) +:: +:: 32 bit builds, and 64-bit builds for 3.5 and beyond, do not require specific +:: environment configurations. +:: +:: Note: this script needs to be run with the /E:ON and /V:ON flags for the +:: cmd interpreter, at least for (SDK v7.0) +:: +:: More details at: +:: https://github.com/cython/cython/wiki/64BitCythonExtensionsOnWindows +:: http://stackoverflow.com/a/13751649/163740 +:: +:: Original source: +:: https://github.com/ogrisel/python-appveyor-demo/blob/master/appveyor/run_with_env.cmd +:: +:: Author: Olivier Grisel +:: License: CC0 1.0 Universal: http://creativecommons.org/publicdomain/zero/1.0/ +@ECHO OFF + +SET COMMAND_TO_RUN=%* +SET WIN_SDK_ROOT=C:\Program Files\Microsoft SDKs\Windows +SET WIN_WDK=c:\Program Files (x86)\Windows Kits\10\Include\wdf + +:: Extract the major and minor versions, and allow for the minor version to be +:: more than 9. This requires the version number to have two dots in it. +SET MAJOR_PYTHON_VERSION=%PYTHON_VERSION:~0,1% +IF "%PYTHON_VERSION:~3,1%" == "." ( + SET MINOR_PYTHON_VERSION=%PYTHON_VERSION:~2,1% +) ELSE ( + SET MINOR_PYTHON_VERSION=%PYTHON_VERSION:~2,2% +) + +:: Based on the Python version, determine what SDK version to use, and whether +:: to set the SDK for 64-bit. +IF %MAJOR_PYTHON_VERSION% == 2 ( + SET WINDOWS_SDK_VERSION="v7.0" + SET SET_SDK_64=Y +) ELSE ( + IF %MAJOR_PYTHON_VERSION% == 3 ( + SET WINDOWS_SDK_VERSION="v7.1" + IF %MINOR_PYTHON_VERSION% LEQ 4 ( + SET SET_SDK_64=Y + ) ELSE ( + SET SET_SDK_64=N + IF EXIST "%WIN_WDK%" ( + :: See: https://connect.microsoft.com/VisualStudio/feedback/details/1610302/ + REN "%WIN_WDK%" 0wdf + ) + ) + ) ELSE ( + ECHO Unsupported Python version: "%MAJOR_PYTHON_VERSION%" + EXIT 1 + ) +) + +IF %PYTHON_ARCH% == 64 ( + IF %SET_SDK_64% == Y ( + ECHO Configuring Windows SDK %WINDOWS_SDK_VERSION% for Python %MAJOR_PYTHON_VERSION% on a 64 bit architecture + SET DISTUTILS_USE_SDK=1 + SET MSSdk=1 + "%WIN_SDK_ROOT%\%WINDOWS_SDK_VERSION%\Setup\WindowsSdkVer.exe" -q -version:%WINDOWS_SDK_VERSION% + "%WIN_SDK_ROOT%\%WINDOWS_SDK_VERSION%\Bin\SetEnv.cmd" /x64 /release + ECHO Executing: %COMMAND_TO_RUN% + call %COMMAND_TO_RUN% || EXIT 1 + ) ELSE ( + ECHO Using default MSVC build environment for 64 bit architecture + ECHO Executing: %COMMAND_TO_RUN% + call %COMMAND_TO_RUN% || EXIT 1 + ) +) ELSE ( + ECHO Using default MSVC build environment for 32 bit architecture + ECHO Executing: %COMMAND_TO_RUN% + call %COMMAND_TO_RUN% || EXIT 1 +) diff --git a/web/server/h2o/libh2o/deps/brotli/dec/Makefile b/web/server/h2o/libh2o/deps/brotli/dec/Makefile new file mode 100644 index 00000000..4d11ed19 --- /dev/null +++ b/web/server/h2o/libh2o/deps/brotli/dec/Makefile @@ -0,0 +1,12 @@ +#brotli/dec + +include ../shared.mk + +CFLAGS += -Wall + +OBJS = bit_reader.o decode.o dictionary.o huffman.o state.o + +all : $(OBJS) + +clean : + rm -f $(OBJS) diff --git a/web/server/h2o/libh2o/deps/brotli/dec/bit_reader.c b/web/server/h2o/libh2o/deps/brotli/dec/bit_reader.c new file mode 100644 index 00000000..cde90af5 --- /dev/null +++ b/web/server/h2o/libh2o/deps/brotli/dec/bit_reader.c @@ -0,0 +1,48 @@ +/* Copyright 2013 Google Inc. All Rights Reserved. + + Distributed under MIT license. + See file LICENSE for detail or copy at https://opensource.org/licenses/MIT +*/ + +/* Bit reading helpers */ + +#include "./bit_reader.h" + +#include "./port.h" +#include "./types.h" + +#if defined(__cplusplus) || defined(c_plusplus) +extern "C" { +#endif + +void BrotliInitBitReader(BrotliBitReader* const br) { + br->val_ = 0; + br->bit_pos_ = sizeof(br->val_) << 3; +} + +int BrotliWarmupBitReader(BrotliBitReader* const br) { + size_t aligned_read_mask = (sizeof(br->val_) >> 1) - 1; + /* Fixing alignment after unaligned BrotliFillWindow would result accumulator + overflow. If unalignment is caused by BrotliSafeReadBits, then there is + enough space in accumulator to fix aligment. */ + if (!BROTLI_ALIGNED_READ) { + aligned_read_mask = 0; + } + if (BrotliGetAvailableBits(br) == 0) { + if (!BrotliPullByte(br)) { + return 0; + } + } + + while ((((size_t)br->next_in) & aligned_read_mask) != 0) { + if (!BrotliPullByte(br)) { + /* If we consumed all the input, we don't care about the alignment. */ + return 1; + } + } + return 1; +} + +#if defined(__cplusplus) || defined(c_plusplus) +} /* extern "C" */ +#endif diff --git a/web/server/h2o/libh2o/deps/brotli/dec/bit_reader.h b/web/server/h2o/libh2o/deps/brotli/dec/bit_reader.h new file mode 100644 index 00000000..e77d1143 --- /dev/null +++ b/web/server/h2o/libh2o/deps/brotli/dec/bit_reader.h @@ -0,0 +1,389 @@ +/* Copyright 2013 Google Inc. All Rights Reserved. + + Distributed under MIT license. + See file LICENSE for detail or copy at https://opensource.org/licenses/MIT +*/ + +/* Bit reading helpers */ + +#ifndef BROTLI_DEC_BIT_READER_H_ +#define BROTLI_DEC_BIT_READER_H_ + +#include /* memcpy */ + +#include "./port.h" +#include "./types.h" + +#ifdef BROTLI_DECODE_DEBUG +#include +#endif + +#if defined(__cplusplus) || defined(c_plusplus) +extern "C" { +#endif + +#if (BROTLI_64_BITS) +#define BROTLI_SHORT_FILL_BIT_WINDOW_READ 4 +typedef uint64_t reg_t; +#else +#define BROTLI_SHORT_FILL_BIT_WINDOW_READ 2 +typedef uint32_t reg_t; +#endif + +static const uint32_t kBitMask[33] = { 0x0000, + 0x00000001, 0x00000003, 0x00000007, 0x0000000F, + 0x0000001F, 0x0000003F, 0x0000007F, 0x000000FF, + 0x000001FF, 0x000003FF, 0x000007FF, 0x00000FFF, + 0x00001FFF, 0x00003FFF, 0x00007FFF, 0x0000FFFF, + 0x0001FFFF, 0x0003FFFF, 0x0007FFFF, 0x000FFFFF, + 0x001FFFFF, 0x003FFFFF, 0x007FFFFF, 0x00FFFFFF, + 0x01FFFFFF, 0x03FFFFFF, 0x07FFFFFF, 0x0FFFFFFF, + 0x1FFFFFFF, 0x3FFFFFFF, 0x7FFFFFFF, 0xFFFFFFFF +}; + +static BROTLI_INLINE uint32_t BitMask(uint32_t n) { + if (IS_CONSTANT(n) || BROTLI_HAS_UBFX) { + /* Masking with this expression turns to a single + "Unsigned Bit Field Extract" UBFX instruction on ARM. */ + return ~((0xffffffffU) << n); + } else { + return kBitMask[n]; + } +} + +typedef struct { + reg_t val_; /* pre-fetched bits */ + uint32_t bit_pos_; /* current bit-reading position in val_ */ + const uint8_t* next_in; /* the byte we're reading from */ + size_t avail_in; +} BrotliBitReader; + +typedef struct { + reg_t val_; + uint32_t bit_pos_; + const uint8_t* next_in; + size_t avail_in; +} BrotliBitReaderState; + +/* Initializes the bitreader fields. */ +void BrotliInitBitReader(BrotliBitReader* const br); + +/* Ensures that accumulator is not empty. May consume one byte of input. + Returns 0 if data is required but there is no input available. + For BROTLI_ALIGNED_READ this function also prepares bit reader for aligned + reading. */ +int BrotliWarmupBitReader(BrotliBitReader* const br); + +static BROTLI_INLINE void BrotliBitReaderSaveState( + BrotliBitReader* const from, BrotliBitReaderState* to) { + to->val_ = from->val_; + to->bit_pos_ = from->bit_pos_; + to->next_in = from->next_in; + to->avail_in = from->avail_in; +} + +static BROTLI_INLINE void BrotliBitReaderRestoreState( + BrotliBitReader* const to, BrotliBitReaderState* from) { + to->val_ = from->val_; + to->bit_pos_ = from->bit_pos_; + to->next_in = from->next_in; + to->avail_in = from->avail_in; +} + +static BROTLI_INLINE uint32_t BrotliGetAvailableBits( + const BrotliBitReader* br) { + return (BROTLI_64_BITS ? 64 : 32) - br->bit_pos_; +} + +/* Returns amount of unread bytes the bit reader still has buffered from the + BrotliInput, including whole bytes in br->val_. */ +static BROTLI_INLINE size_t BrotliGetRemainingBytes(BrotliBitReader* br) { + return br->avail_in + (BrotliGetAvailableBits(br) >> 3); +} + +/* Checks if there is at least num bytes left in the input ringbuffer (excluding + the bits remaining in br->val_). */ +static BROTLI_INLINE int BrotliCheckInputAmount( + BrotliBitReader* const br, size_t num) { + return br->avail_in >= num; +} + +static BROTLI_INLINE uint16_t BrotliLoad16LE(const uint8_t* in) { + if (BROTLI_LITTLE_ENDIAN) { + return *((const uint16_t*)in); + } else if (BROTLI_BIG_ENDIAN) { + uint16_t value = *((const uint16_t*)in); + return (uint16_t)(((value & 0xFFU) << 8) | ((value & 0xFF00U) >> 8)); + } else { + return (uint16_t)(in[0] | (in[1] << 8)); + } +} + +static BROTLI_INLINE uint32_t BrotliLoad32LE(const uint8_t* in) { + if (BROTLI_LITTLE_ENDIAN) { + return *((const uint32_t*)in); + } else if (BROTLI_BIG_ENDIAN) { + uint32_t value = *((const uint32_t*)in); + return ((value & 0xFFU) << 24) | ((value & 0xFF00U) << 8) | + ((value & 0xFF0000U) >> 8) | ((value & 0xFF000000U) >> 24); + } else { + uint32_t value = (uint32_t)(*(in++)); + value |= (uint32_t)(*(in++)) << 8; + value |= (uint32_t)(*(in++)) << 16; + value |= (uint32_t)(*(in++)) << 24; + return value; + } +} + +#if (BROTLI_64_BITS) +static BROTLI_INLINE uint64_t BrotliLoad64LE(const uint8_t* in) { + if (BROTLI_LITTLE_ENDIAN) { + return *((const uint64_t*)in); + } else if (BROTLI_BIG_ENDIAN) { + uint64_t value = *((const uint64_t*)in); + return + ((value & 0xFFU) << 56) | + ((value & 0xFF00U) << 40) | + ((value & 0xFF0000U) << 24) | + ((value & 0xFF000000U) << 8) | + ((value & 0xFF00000000U) >> 8) | + ((value & 0xFF0000000000U) >> 24) | + ((value & 0xFF000000000000U) >> 40) | + ((value & 0xFF00000000000000U) >> 56); + } else { + uint64_t value = (uint64_t)(*(in++)); + value |= (uint64_t)(*(in++)) << 8; + value |= (uint64_t)(*(in++)) << 16; + value |= (uint64_t)(*(in++)) << 24; + value |= (uint64_t)(*(in++)) << 32; + value |= (uint64_t)(*(in++)) << 40; + value |= (uint64_t)(*(in++)) << 48; + value |= (uint64_t)(*(in++)) << 56; + return value; + } +} +#endif + +/* Guarantees that there are at least n_bits + 1 bits in accumulator. + Precondition: accumulator contains at least 1 bit. + n_bits should be in the range [1..24] for regular build. For portable + non-64-bit little endian build only 16 bits are safe to request. */ +static BROTLI_INLINE void BrotliFillBitWindow( + BrotliBitReader* const br, uint32_t n_bits) { +#if (BROTLI_64_BITS) + if (!BROTLI_ALIGNED_READ && IS_CONSTANT(n_bits) && (n_bits <= 8)) { + if (br->bit_pos_ >= 56) { + br->val_ >>= 56; + br->bit_pos_ ^= 56; /* here same as -= 56 because of the if condition */ + br->val_ |= BrotliLoad64LE(br->next_in) << 8; + br->avail_in -= 7; + br->next_in += 7; + } + } else if (!BROTLI_ALIGNED_READ && IS_CONSTANT(n_bits) && (n_bits <= 16)) { + if (br->bit_pos_ >= 48) { + br->val_ >>= 48; + br->bit_pos_ ^= 48; /* here same as -= 48 because of the if condition */ + br->val_ |= BrotliLoad64LE(br->next_in) << 16; + br->avail_in -= 6; + br->next_in += 6; + } + } else { + if (br->bit_pos_ >= 32) { + br->val_ >>= 32; + br->bit_pos_ ^= 32; /* here same as -= 32 because of the if condition */ + br->val_ |= ((uint64_t)BrotliLoad32LE(br->next_in)) << 32; + br->avail_in -= BROTLI_SHORT_FILL_BIT_WINDOW_READ; + br->next_in += BROTLI_SHORT_FILL_BIT_WINDOW_READ; + } + } +#else + if (!BROTLI_ALIGNED_READ && IS_CONSTANT(n_bits) && (n_bits <= 8)) { + if (br->bit_pos_ >= 24) { + br->val_ >>= 24; + br->bit_pos_ ^= 24; /* here same as -= 24 because of the if condition */ + br->val_ |= BrotliLoad32LE(br->next_in) << 8; + br->avail_in -= 3; + br->next_in += 3; + } + } else { + if (br->bit_pos_ >= 16) { + br->val_ >>= 16; + br->bit_pos_ ^= 16; /* here same as -= 16 because of the if condition */ + br->val_ |= ((uint32_t)BrotliLoad16LE(br->next_in)) << 16; + br->avail_in -= BROTLI_SHORT_FILL_BIT_WINDOW_READ; + br->next_in += BROTLI_SHORT_FILL_BIT_WINDOW_READ; + } + } +#endif +} + +/* Mosltly like BrotliFillBitWindow, but guarantees only 16 bits and reads no + more than BROTLI_SHORT_FILL_BIT_WINDOW_READ bytes of input. */ +static BROTLI_INLINE void BrotliFillBitWindow16(BrotliBitReader* const br) { + BrotliFillBitWindow(br, 17); +} + +/* Pulls one byte of input to accumulator. */ +static BROTLI_INLINE int BrotliPullByte(BrotliBitReader* const br) { + if (br->avail_in == 0) { + return 0; + } + br->val_ >>= 8; +#if (BROTLI_64_BITS) + br->val_ |= ((uint64_t)*br->next_in) << 56; +#else + br->val_ |= ((uint32_t)*br->next_in) << 24; +#endif + br->bit_pos_ -= 8; + --br->avail_in; + ++br->next_in; + return 1; +} + +/* Returns currently available bits. + The number of valid bits could be calclulated by BrotliGetAvailableBits. */ +static BROTLI_INLINE reg_t BrotliGetBitsUnmasked(BrotliBitReader* const br) { + return br->val_ >> br->bit_pos_; +} + +/* Like BrotliGetBits, but does not mask the result. + The result contains at least 16 valid bits. */ +static BROTLI_INLINE uint32_t BrotliGet16BitsUnmasked( + BrotliBitReader* const br) { + BrotliFillBitWindow(br, 16); + return (uint32_t)BrotliGetBitsUnmasked(br); +} + +/* Returns the specified number of bits from br without advancing bit pos. */ +static BROTLI_INLINE uint32_t BrotliGetBits( + BrotliBitReader* const br, uint32_t n_bits) { + BrotliFillBitWindow(br, n_bits); + return (uint32_t)BrotliGetBitsUnmasked(br) & BitMask(n_bits); +} + +/* Tries to peek the specified amount of bits. Returns 0, if there is not + enough input. */ +static BROTLI_INLINE int BrotliSafeGetBits( + BrotliBitReader* const br, uint32_t n_bits, uint32_t* val) { + while (BrotliGetAvailableBits(br) < n_bits) { + if (!BrotliPullByte(br)) { + return 0; + } + } + *val = (uint32_t)BrotliGetBitsUnmasked(br) & BitMask(n_bits); + return 1; +} + +/* Advances the bit pos by n_bits. */ +static BROTLI_INLINE void BrotliDropBits( + BrotliBitReader* const br, uint32_t n_bits) { + br->bit_pos_ += n_bits; +} + +static BROTLI_INLINE void BrotliBitReaderUnload(BrotliBitReader* br) { + uint32_t unused_bytes = BrotliGetAvailableBits(br) >> 3; + uint32_t unused_bits = unused_bytes << 3; + br->avail_in += unused_bytes; + br->next_in -= unused_bytes; + if (unused_bits == sizeof(br->val_) << 3) { + br->val_ = 0; + } else { + br->val_ <<= unused_bits; + } + br->bit_pos_ += unused_bits; +} + +/* Reads the specified number of bits from br and advances the bit pos. + Precondition: accumulator MUST contain at least n_bits. */ +static BROTLI_INLINE void BrotliTakeBits( + BrotliBitReader* const br, uint32_t n_bits, uint32_t* val) { + *val = (uint32_t)BrotliGetBitsUnmasked(br) & BitMask(n_bits); +#ifdef BROTLI_DECODE_DEBUG + printf("[BrotliReadBits] %d %d %d val: %6x\n", + (int)br->avail_in, (int)br->bit_pos_, n_bits, (int)*val); +#endif + BrotliDropBits(br, n_bits); +} + +/* Reads the specified number of bits from br and advances the bit pos. + Assumes that there is enough input to perform BrotliFillBitWindow. */ +static BROTLI_INLINE uint32_t BrotliReadBits( + BrotliBitReader* const br, uint32_t n_bits) { + if (BROTLI_64_BITS || (n_bits <= 16)) { + uint32_t val; + BrotliFillBitWindow(br, n_bits); + BrotliTakeBits(br, n_bits, &val); + return val; + } else { + uint32_t low_val; + uint32_t high_val; + BrotliFillBitWindow(br, 16); + BrotliTakeBits(br, 16, &low_val); + BrotliFillBitWindow(br, 8); + BrotliTakeBits(br, n_bits - 16, &high_val); + return low_val | (high_val << 16); + } +} + +/* Tries to read the specified amount of bits. Returns 0, if there is not + enough input. n_bits MUST be positive. */ +static BROTLI_INLINE int BrotliSafeReadBits( + BrotliBitReader* const br, uint32_t n_bits, uint32_t* val) { + while (BrotliGetAvailableBits(br) < n_bits) { + if (!BrotliPullByte(br)) { + return 0; + } + } + BrotliTakeBits(br, n_bits, val); + return 1; +} + +/* Advances the bit reader position to the next byte boundary and verifies + that any skipped bits are set to zero. */ +static BROTLI_INLINE int BrotliJumpToByteBoundary(BrotliBitReader* br) { + uint32_t pad_bits_count = BrotliGetAvailableBits(br) & 0x7; + uint32_t pad_bits = 0; + if (pad_bits_count != 0) { + BrotliTakeBits(br, pad_bits_count, &pad_bits); + } + return pad_bits == 0; +} + +/* Peeks a byte at specified offset. + Precondition: bit reader is parked to a byte boundary. + Returns -1 if operation is not feasible. */ +static BROTLI_INLINE int BrotliPeekByte(BrotliBitReader* br, size_t offset) { + uint32_t available_bits = BrotliGetAvailableBits(br); + size_t bytes_left = available_bits >> 3; + BROTLI_DCHECK((available_bits & 7) == 0); + if (offset < bytes_left) { + return (BrotliGetBitsUnmasked(br) >> (unsigned)(offset << 3)) & 0xFF; + } + offset -= bytes_left; + if (offset < br->avail_in) { + return br->next_in[offset]; + } + return -1; +} + +/* Copies remaining input bytes stored in the bit reader to the output. Value + num may not be larger than BrotliGetRemainingBytes. The bit reader must be + warmed up again after this. */ +static BROTLI_INLINE void BrotliCopyBytes(uint8_t* dest, + BrotliBitReader* br, size_t num) { + while (BrotliGetAvailableBits(br) >= 8 && num > 0) { + *dest = (uint8_t)BrotliGetBitsUnmasked(br); + BrotliDropBits(br, 8); + ++dest; + --num; + } + memcpy(dest, br->next_in, num); + br->avail_in -= num; + br->next_in += num; +} + +#if defined(__cplusplus) || defined(c_plusplus) +} /* extern "C" */ +#endif + +#endif /* BROTLI_DEC_BIT_READER_H_ */ diff --git a/web/server/h2o/libh2o/deps/brotli/dec/context.h b/web/server/h2o/libh2o/deps/brotli/dec/context.h new file mode 100644 index 00000000..37ebe6ae --- /dev/null +++ b/web/server/h2o/libh2o/deps/brotli/dec/context.h @@ -0,0 +1,251 @@ +/* Copyright 2013 Google Inc. All Rights Reserved. + + Distributed under MIT license. + See file LICENSE for detail or copy at https://opensource.org/licenses/MIT +*/ + +/* Lookup table to map the previous two bytes to a context id. + + There are four different context modeling modes defined here: + CONTEXT_LSB6: context id is the least significant 6 bits of the last byte, + CONTEXT_MSB6: context id is the most significant 6 bits of the last byte, + CONTEXT_UTF8: second-order context model tuned for UTF8-encoded text, + CONTEXT_SIGNED: second-order context model tuned for signed integers. + + The context id for the UTF8 context model is calculated as follows. If p1 + and p2 are the previous two bytes, we calculate the context as + + context = kContextLookup[p1] | kContextLookup[p2 + 256]. + + If the previous two bytes are ASCII characters (i.e. < 128), this will be + equivalent to + + context = 4 * context1(p1) + context2(p2), + + where context1 is based on the previous byte in the following way: + + 0 : non-ASCII control + 1 : \t, \n, \r + 2 : space + 3 : other punctuation + 4 : " ' + 5 : % + 6 : ( < [ { + 7 : ) > ] } + 8 : , ; : + 9 : . + 10 : = + 11 : number + 12 : upper-case vowel + 13 : upper-case consonant + 14 : lower-case vowel + 15 : lower-case consonant + + and context2 is based on the second last byte: + + 0 : control, space + 1 : punctuation + 2 : upper-case letter, number + 3 : lower-case letter + + If the last byte is ASCII, and the second last byte is not (in a valid UTF8 + stream it will be a continuation byte, value between 128 and 191), the + context is the same as if the second last byte was an ASCII control or space. + + If the last byte is a UTF8 lead byte (value >= 192), then the next byte will + be a continuation byte and the context id is 2 or 3 depending on the LSB of + the last byte and to a lesser extent on the second last byte if it is ASCII. + + If the last byte is a UTF8 continuation byte, the second last byte can be: + - continuation byte: the next byte is probably ASCII or lead byte (assuming + 4-byte UTF8 characters are rare) and the context id is 0 or 1. + - lead byte (192 - 207): next byte is ASCII or lead byte, context is 0 or 1 + - lead byte (208 - 255): next byte is continuation byte, context is 2 or 3 + + The possible value combinations of the previous two bytes, the range of + context ids and the type of the next byte is summarized in the table below: + + |--------\-----------------------------------------------------------------| + | \ Last byte | + | Second \---------------------------------------------------------------| + | last byte \ ASCII | cont. byte | lead byte | + | \ (0-127) | (128-191) | (192-) | + |=============|===================|=====================|==================| + | ASCII | next: ASCII/lead | not valid | next: cont. | + | (0-127) | context: 4 - 63 | | context: 2 - 3 | + |-------------|-------------------|---------------------|------------------| + | cont. byte | next: ASCII/lead | next: ASCII/lead | next: cont. | + | (128-191) | context: 4 - 63 | context: 0 - 1 | context: 2 - 3 | + |-------------|-------------------|---------------------|------------------| + | lead byte | not valid | next: ASCII/lead | not valid | + | (192-207) | | context: 0 - 1 | | + |-------------|-------------------|---------------------|------------------| + | lead byte | not valid | next: cont. | not valid | + | (208-) | | context: 2 - 3 | | + |-------------|-------------------|---------------------|------------------| + + The context id for the signed context mode is calculated as: + + context = (kContextLookup[512 + p1] << 3) | kContextLookup[512 + p2]. + + For any context modeling modes, the context ids can be calculated by |-ing + together two lookups from one table using context model dependent offsets: + + context = kContextLookup[offset1 + p1] | kContextLookup[offset2 + p2]. + + where offset1 and offset2 are dependent on the context mode. +*/ + +#ifndef BROTLI_DEC_CONTEXT_H_ +#define BROTLI_DEC_CONTEXT_H_ + +#include "./types.h" + +enum ContextType { + CONTEXT_LSB6 = 0, + CONTEXT_MSB6 = 1, + CONTEXT_UTF8 = 2, + CONTEXT_SIGNED = 3 +}; + +/* Common context lookup table for all context modes. */ +static const uint8_t kContextLookup[1792] = { + /* CONTEXT_UTF8, last byte. */ + /* ASCII range. */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 0, 0, 4, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 8, 12, 16, 12, 12, 20, 12, 16, 24, 28, 12, 12, 32, 12, 36, 12, + 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 32, 32, 24, 40, 28, 12, + 12, 48, 52, 52, 52, 48, 52, 52, 52, 48, 52, 52, 52, 52, 52, 48, + 52, 52, 52, 52, 52, 48, 52, 52, 52, 52, 52, 24, 12, 28, 12, 12, + 12, 56, 60, 60, 60, 56, 60, 60, 60, 56, 60, 60, 60, 60, 60, 56, + 60, 60, 60, 60, 60, 56, 60, 60, 60, 60, 60, 24, 12, 28, 12, 0, + /* UTF8 continuation byte range. */ + 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, + 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, + 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, + 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, + /* UTF8 lead byte range. */ + 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, + 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, + 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, + 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, + /* CONTEXT_UTF8 second last byte. */ + /* ASCII range. */ + 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, 0, 0, 0, 0, 0, 0, + 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, + 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, + 1, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 1, 1, 1, 1, 0, + /* UTF8 continuation byte range. */ + 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, 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, 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, 0, 0, + /* UTF8 lead byte range. */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + /* CONTEXT_SIGNED, second last byte. */ + 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 7, + /* CONTEXT_SIGNED, last byte, same as the above values shifted by 3 bits. */ + 0, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, + 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, + 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 56, + /* CONTEXT_LSB6, last byte. */ + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, + 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, + 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, + 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, + 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, + 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, + 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, + 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, + 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, + /* CONTEXT_MSB6, last byte. */ + 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, + 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, + 8, 8, 8, 8, 9, 9, 9, 9, 10, 10, 10, 10, 11, 11, 11, 11, + 12, 12, 12, 12, 13, 13, 13, 13, 14, 14, 14, 14, 15, 15, 15, 15, + 16, 16, 16, 16, 17, 17, 17, 17, 18, 18, 18, 18, 19, 19, 19, 19, + 20, 20, 20, 20, 21, 21, 21, 21, 22, 22, 22, 22, 23, 23, 23, 23, + 24, 24, 24, 24, 25, 25, 25, 25, 26, 26, 26, 26, 27, 27, 27, 27, + 28, 28, 28, 28, 29, 29, 29, 29, 30, 30, 30, 30, 31, 31, 31, 31, + 32, 32, 32, 32, 33, 33, 33, 33, 34, 34, 34, 34, 35, 35, 35, 35, + 36, 36, 36, 36, 37, 37, 37, 37, 38, 38, 38, 38, 39, 39, 39, 39, + 40, 40, 40, 40, 41, 41, 41, 41, 42, 42, 42, 42, 43, 43, 43, 43, + 44, 44, 44, 44, 45, 45, 45, 45, 46, 46, 46, 46, 47, 47, 47, 47, + 48, 48, 48, 48, 49, 49, 49, 49, 50, 50, 50, 50, 51, 51, 51, 51, + 52, 52, 52, 52, 53, 53, 53, 53, 54, 54, 54, 54, 55, 55, 55, 55, + 56, 56, 56, 56, 57, 57, 57, 57, 58, 58, 58, 58, 59, 59, 59, 59, + 60, 60, 60, 60, 61, 61, 61, 61, 62, 62, 62, 62, 63, 63, 63, 63, + /* CONTEXT_{M,L}SB6, second last byte, */ + 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, 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, 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, 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, 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, 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, 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, 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, + 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, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +}; + +static const int kContextLookupOffsets[8] = { + /* CONTEXT_LSB6 */ + 1024, 1536, + /* CONTEXT_MSB6 */ + 1280, 1536, + /* CONTEXT_UTF8 */ + 0, 256, + /* CONTEXT_SIGNED */ + 768, 512, +}; + +#endif /* BROTLI_DEC_CONTEXT_H_ */ diff --git a/web/server/h2o/libh2o/deps/brotli/dec/decode.c b/web/server/h2o/libh2o/deps/brotli/dec/decode.c new file mode 100644 index 00000000..a81706b0 --- /dev/null +++ b/web/server/h2o/libh2o/deps/brotli/dec/decode.c @@ -0,0 +1,2237 @@ +/* Copyright 2013 Google Inc. All Rights Reserved. + + Distributed under MIT license. + See file LICENSE for detail or copy at https://opensource.org/licenses/MIT +*/ + +#include "./decode.h" + +#ifdef __ARM_NEON__ +#include +#endif + +#include /* printf (debug output) */ +#include /* free, malloc */ +#include /* memcpy, memset */ + +#include "./bit_reader.h" +#include "./context.h" +#include "./dictionary.h" +#include "./huffman.h" +#include "./port.h" +#include "./prefix.h" +#include "./transform.h" + +#if defined(__cplusplus) || defined(c_plusplus) +extern "C" { +#endif + +/* BROTLI_FAILURE macro unwraps to BROTLI_RESULT_ERROR in non-debug build. */ +/* In debug build it dumps file name, line and pretty function name. */ +#if defined(_MSC_VER) || \ + (!defined(BROTLI_DEBUG) && !defined(BROTLI_DECODE_DEBUG)) +#define BROTLI_FAILURE() BROTLI_RESULT_ERROR +#else +#define BROTLI_FAILURE() BrotliFailure(__FILE__, __LINE__, __PRETTY_FUNCTION__) +static inline BrotliResult BrotliFailure(const char* f, int l, const char* fn) { + fprintf(stderr, "ERROR at %s:%d (%s)\n", f, l, fn); + fflush(stderr); + return BROTLI_RESULT_ERROR; +} +#endif + +#ifdef BROTLI_DECODE_DEBUG +#define BROTLI_LOG_UINT(name) \ + printf("[%s] %s = %lu\n", __func__, #name, (unsigned long)(name)) +#define BROTLI_LOG_ARRAY_INDEX(array_name, idx) \ + printf("[%s] %s[%lu] = %lu\n", __func__, #array_name, \ + (unsigned long)(idx), (unsigned long)array_name[idx]) +#define BROTLI_LOG(x) printf x +#else +#define BROTLI_LOG_UINT(name) +#define BROTLI_LOG_ARRAY_INDEX(array_name, idx) +#define BROTLI_LOG(x) +#endif + +static const uint32_t kDefaultCodeLength = 8; +static const uint32_t kCodeLengthRepeatCode = 16; +static const uint32_t kNumLiteralCodes = 256; +static const uint32_t kNumInsertAndCopyCodes = 704; +static const uint32_t kNumBlockLengthCodes = 26; +static const int kLiteralContextBits = 6; +static const int kDistanceContextBits = 2; + +#define HUFFMAN_TABLE_BITS 8U +#define HUFFMAN_TABLE_MASK 0xff + +#define CODE_LENGTH_CODES 18 +static const uint8_t kCodeLengthCodeOrder[CODE_LENGTH_CODES] = { + 1, 2, 3, 4, 0, 5, 17, 6, 16, 7, 8, 9, 10, 11, 12, 13, 14, 15, +}; + +/* Static prefix code for the complex code length code lengths. */ +static const uint8_t kCodeLengthPrefixLength[16] = { + 2, 2, 2, 3, 2, 2, 2, 4, 2, 2, 2, 3, 2, 2, 2, 4, +}; + +static const uint8_t kCodeLengthPrefixValue[16] = { + 0, 4, 3, 2, 0, 4, 3, 1, 0, 4, 3, 2, 0, 4, 3, 5, +}; + +#define NUM_DISTANCE_SHORT_CODES 16 + +BrotliState* BrotliCreateState( + brotli_alloc_func alloc_func, brotli_free_func free_func, void* opaque) { + BrotliState* state = 0; + if (!alloc_func && !free_func) { + state = (BrotliState*)malloc(sizeof(BrotliState)); + } else if (alloc_func && free_func) { + state = (BrotliState*)alloc_func(opaque, sizeof(BrotliState)); + } + if (state == 0) { + (void)BROTLI_FAILURE(); + return 0; + } + BrotliStateInitWithCustomAllocators(state, alloc_func, free_func, opaque); + return state; +} + +/* Deinitializes and frees BrotliState instance. */ +void BrotliDestroyState(BrotliState* state) { + if (!state) { + return; + } else { + brotli_free_func free_func = state->free_func; + void* opaque = state->memory_manager_opaque; + BrotliStateCleanup(state); + free_func(opaque, state); + } +} + +/* Decodes a number in the range [9..24], by reading 1 - 7 bits. + Precondition: bit-reader accumulator has at least 7 bits. */ +static uint32_t DecodeWindowBits(BrotliBitReader* br) { + uint32_t n; + BrotliTakeBits(br, 1, &n); + if (n == 0) { + return 16; + } + BrotliTakeBits(br, 3, &n); + if (n != 0) { + return 17 + n; + } + BrotliTakeBits(br, 3, &n); + if (n != 0) { + return 8 + n; + } + return 17; +} + +static BROTLI_INLINE void memmove16(uint8_t* dst, uint8_t* src) { +#if defined(__ARM_NEON__) + vst1q_u8(dst, vld1q_u8(src)); +#else + uint32_t buffer[4]; + memcpy(buffer, src, 16); + memcpy(dst, buffer, 16); +#endif +} + +/* Decodes a number in the range [0..255], by reading 1 - 11 bits. */ +static BROTLI_NOINLINE BrotliResult DecodeVarLenUint8(BrotliState* s, + BrotliBitReader* br, uint32_t* value) { + uint32_t bits; + switch (s->substate_decode_uint8) { + case BROTLI_STATE_DECODE_UINT8_NONE: + if (PREDICT_FALSE(!BrotliSafeReadBits(br, 1, &bits))) { + return BROTLI_RESULT_NEEDS_MORE_INPUT; + } + if (bits == 0) { + *value = 0; + return BROTLI_RESULT_SUCCESS; + } + /* No break, transit to the next state. */ + + case BROTLI_STATE_DECODE_UINT8_SHORT: + if (PREDICT_FALSE(!BrotliSafeReadBits(br, 3, &bits))) { + s->substate_decode_uint8 = BROTLI_STATE_DECODE_UINT8_SHORT; + return BROTLI_RESULT_NEEDS_MORE_INPUT; + } + if (bits == 0) { + *value = 1; + s->substate_decode_uint8 = BROTLI_STATE_DECODE_UINT8_NONE; + return BROTLI_RESULT_SUCCESS; + } + /* Use output value as a temporary storage. It MUST be persisted. */ + *value = bits; + /* No break, transit to the next state. */ + + case BROTLI_STATE_DECODE_UINT8_LONG: + if (PREDICT_FALSE(!BrotliSafeReadBits(br, *value, &bits))) { + s->substate_decode_uint8 = BROTLI_STATE_DECODE_UINT8_LONG; + return BROTLI_RESULT_NEEDS_MORE_INPUT; + } + *value = (1U << *value) + bits; + s->substate_decode_uint8 = BROTLI_STATE_DECODE_UINT8_NONE; + return BROTLI_RESULT_SUCCESS; + + default: + return BROTLI_FAILURE(); + } +} + +/* Decodes a metablock length and flags by reading 2 - 31 bits. */ +static BrotliResult BROTLI_NOINLINE DecodeMetaBlockLength(BrotliState* s, + BrotliBitReader* br) { + uint32_t bits; + int i; + for (;;) { + switch (s->substate_metablock_header) { + case BROTLI_STATE_METABLOCK_HEADER_NONE: + if (!BrotliSafeReadBits(br, 1, &bits)) { + return BROTLI_RESULT_NEEDS_MORE_INPUT; + } + s->is_last_metablock = (uint8_t)bits; + s->meta_block_remaining_len = 0; + s->is_uncompressed = 0; + s->is_metadata = 0; + if (!s->is_last_metablock) { + s->substate_metablock_header = BROTLI_STATE_METABLOCK_HEADER_NIBBLES; + break; + } + s->substate_metablock_header = BROTLI_STATE_METABLOCK_HEADER_EMPTY; + /* No break, transit to the next state. */ + + case BROTLI_STATE_METABLOCK_HEADER_EMPTY: + if (!BrotliSafeReadBits(br, 1, &bits)) { + return BROTLI_RESULT_NEEDS_MORE_INPUT; + } + if (bits) { + s->substate_metablock_header = BROTLI_STATE_METABLOCK_HEADER_NONE; + return BROTLI_RESULT_SUCCESS; + } + s->substate_metablock_header = BROTLI_STATE_METABLOCK_HEADER_NIBBLES; + /* No break, transit to the next state. */ + + case BROTLI_STATE_METABLOCK_HEADER_NIBBLES: + if (!BrotliSafeReadBits(br, 2, &bits)) { + return BROTLI_RESULT_NEEDS_MORE_INPUT; + } + s->size_nibbles = (uint8_t)(bits + 4); + s->loop_counter = 0; + if (bits == 3) { + s->is_metadata = 1; + s->substate_metablock_header = BROTLI_STATE_METABLOCK_HEADER_RESERVED; + break; + } + s->substate_metablock_header = BROTLI_STATE_METABLOCK_HEADER_SIZE; + /* No break, transit to the next state. */ + + case BROTLI_STATE_METABLOCK_HEADER_SIZE: + i = s->loop_counter; + for (; i < s->size_nibbles; ++i) { + if (!BrotliSafeReadBits(br, 4, &bits)) { + s->loop_counter = i; + return BROTLI_RESULT_NEEDS_MORE_INPUT; + } + if (i + 1 == s->size_nibbles && s->size_nibbles > 4 && bits == 0) { + return BROTLI_FAILURE(); + } + s->meta_block_remaining_len |= (int)(bits << (i * 4)); + } + s->substate_metablock_header = + BROTLI_STATE_METABLOCK_HEADER_UNCOMPRESSED; + /* No break, transit to the next state. */ + + case BROTLI_STATE_METABLOCK_HEADER_UNCOMPRESSED: + if (!s->is_last_metablock) { + if (!BrotliSafeReadBits(br, 1, &bits)) { + return BROTLI_RESULT_NEEDS_MORE_INPUT; + } + s->is_uncompressed = (uint8_t)bits; + } + ++s->meta_block_remaining_len; + s->substate_metablock_header = BROTLI_STATE_METABLOCK_HEADER_NONE; + return BROTLI_RESULT_SUCCESS; + + case BROTLI_STATE_METABLOCK_HEADER_RESERVED: + if (!BrotliSafeReadBits(br, 1, &bits)) { + return BROTLI_RESULT_NEEDS_MORE_INPUT; + } + if (bits != 0) { + return BROTLI_FAILURE(); + } + s->substate_metablock_header = BROTLI_STATE_METABLOCK_HEADER_BYTES; + /* No break, transit to the next state. */ + + case BROTLI_STATE_METABLOCK_HEADER_BYTES: + if (!BrotliSafeReadBits(br, 2, &bits)) { + return BROTLI_RESULT_NEEDS_MORE_INPUT; + } + if (bits == 0) { + s->substate_metablock_header = BROTLI_STATE_METABLOCK_HEADER_NONE; + return BROTLI_RESULT_SUCCESS; + } + s->size_nibbles = (uint8_t)bits; + s->substate_metablock_header = BROTLI_STATE_METABLOCK_HEADER_METADATA; + /* No break, transit to the next state. */ + + case BROTLI_STATE_METABLOCK_HEADER_METADATA: + i = s->loop_counter; + for (; i < s->size_nibbles; ++i) { + if (!BrotliSafeReadBits(br, 8, &bits)) { + s->loop_counter = i; + return BROTLI_RESULT_NEEDS_MORE_INPUT; + } + if (i + 1 == s->size_nibbles && s->size_nibbles > 1 && bits == 0) { + return BROTLI_FAILURE(); + } + s->meta_block_remaining_len |= (int)(bits << (i * 8)); + } + ++s->meta_block_remaining_len; + s->substate_metablock_header = BROTLI_STATE_METABLOCK_HEADER_NONE; + return BROTLI_RESULT_SUCCESS; + + default: + return BROTLI_FAILURE(); + } + } +} + +/* Decodes the Huffman code. + This method doesn't read data from the bit reader, BUT drops the amount of + bits that correspond to the decoded symbol. + bits MUST contain at least 15 (BROTLI_HUFFMAN_MAX_CODE_LENGTH) valid bits. */ +static BROTLI_INLINE uint32_t DecodeSymbol(uint32_t bits, + const HuffmanCode* table, + BrotliBitReader* br) { + table += bits & HUFFMAN_TABLE_MASK; + if (table->bits > HUFFMAN_TABLE_BITS) { + uint32_t nbits = table->bits - HUFFMAN_TABLE_BITS; + BrotliDropBits(br, HUFFMAN_TABLE_BITS); + table += table->value; + table += (bits >> HUFFMAN_TABLE_BITS) & BitMask(nbits); + } + BrotliDropBits(br, table->bits); + return table->value; +} + +/* Reads and decodes the next Huffman code from bit-stream. + This method peeks 16 bits of input and drops 0 - 15 of them. */ +static BROTLI_INLINE uint32_t ReadSymbol(const HuffmanCode* table, + BrotliBitReader* br) { + return DecodeSymbol(BrotliGet16BitsUnmasked(br), table, br); +} + +/* Same as DecodeSymbol, but it is known that there is less than 15 bits of + input are currently available. */ +static BROTLI_NOINLINE int SafeDecodeSymbol(const HuffmanCode* table, + BrotliBitReader* br, + uint32_t* result) { + uint32_t val; + uint32_t available_bits = BrotliGetAvailableBits(br); + if (available_bits == 0) { + if (table->bits == 0) { + *result = table->value; + return 1; + } + return 0; /* No valid bits at all. */ + } + val = (uint32_t)BrotliGetBitsUnmasked(br); + table += val & HUFFMAN_TABLE_MASK; + if (table->bits <= HUFFMAN_TABLE_BITS) { + if (table->bits <= available_bits) { + BrotliDropBits(br, table->bits); + *result = table->value; + return 1; + } else { + return 0; /* Not enough bits for the first level. */ + } + } + if (available_bits <= HUFFMAN_TABLE_BITS) { + return 0; /* Not enough bits to move to the second level. */ + } + + /* Speculatively drop HUFFMAN_TABLE_BITS. */ + val = (val & BitMask(table->bits)) >> HUFFMAN_TABLE_BITS; + available_bits -= HUFFMAN_TABLE_BITS; + table += table->value + val; + if (available_bits < table->bits) { + return 0; /* Not enough bits for the second level. */ + } + + BrotliDropBits(br, HUFFMAN_TABLE_BITS + table->bits); + *result = table->value; + return 1; +} + +static BROTLI_INLINE int SafeReadSymbol(const HuffmanCode* table, + BrotliBitReader* br, + uint32_t* result) { + uint32_t val; + if (PREDICT_TRUE(BrotliSafeGetBits(br, 15, &val))) { + *result = DecodeSymbol(val, table, br); + return 1; + } + return SafeDecodeSymbol(table, br, result); +} + + +/* Makes a look-up in first level Huffman table. Peeks 8 bits. */ +static BROTLI_INLINE void PreloadSymbol(int safe, + const HuffmanCode* table, + BrotliBitReader* br, + uint32_t* bits, + uint32_t* value) { + if (safe) { + return; + } + table += BrotliGetBits(br, HUFFMAN_TABLE_BITS); + *bits = table->bits; + *value = table->value; +} + +/* Decodes the next Huffman code using data prepared by PreloadSymbol. + Reads 0 - 15 bits. Also peeks 8 following bits. */ +static BROTLI_INLINE uint32_t ReadPreloadedSymbol(const HuffmanCode* table, + BrotliBitReader* br, + uint32_t* bits, + uint32_t* value) { + uint32_t result = *value; + if (PREDICT_FALSE(*bits > HUFFMAN_TABLE_BITS)) { + uint32_t val = BrotliGet16BitsUnmasked(br); + const HuffmanCode* ext = table + (val & HUFFMAN_TABLE_MASK) + *value; + uint32_t mask = BitMask((*bits - HUFFMAN_TABLE_BITS)); + BrotliDropBits(br, HUFFMAN_TABLE_BITS); + ext += (val >> HUFFMAN_TABLE_BITS) & mask; + BrotliDropBits(br, ext->bits); + result = ext->value; + } else { + BrotliDropBits(br, *bits); + } + PreloadSymbol(0, table, br, bits, value); + return result; +} + +static BROTLI_INLINE uint32_t Log2Floor(uint32_t x) { + uint32_t result = 0; + while (x) { + x >>= 1; + ++result; + } + return result; +} + +/* Reads (s->symbol + 1) symbols. + Totally 1..4 symbols are read, 1..10 bits each. + The list of symbols MUST NOT contain duplicates. + */ +static BrotliResult ReadSimpleHuffmanSymbols(uint32_t alphabet_size, + BrotliState* s) { + /* max_bits == 1..10; symbol == 0..3; 1..40 bits will be read. */ + BrotliBitReader* br = &s->br; + uint32_t max_bits = Log2Floor(alphabet_size - 1); + uint32_t i = s->sub_loop_counter; + uint32_t num_symbols = s->symbol; + while (i <= num_symbols) { + uint32_t v; + if (PREDICT_FALSE(!BrotliSafeReadBits(br, max_bits, &v))) { + s->sub_loop_counter = i; + s->substate_huffman = BROTLI_STATE_HUFFMAN_SIMPLE_READ; + return BROTLI_RESULT_NEEDS_MORE_INPUT; + } + if (v >= alphabet_size) { + return BROTLI_FAILURE(); + } + s->symbols_lists_array[i] = (uint16_t)v; + BROTLI_LOG_UINT(s->symbols_lists_array[i]); + ++i; + } + + for (i = 0; i < num_symbols; ++i) { + uint32_t k = i + 1; + for (; k <= num_symbols; ++k) { + if (s->symbols_lists_array[i] == s->symbols_lists_array[k]) { + return BROTLI_FAILURE(); + } + } + } + + return BROTLI_RESULT_SUCCESS; +} + +/* Process single decoded symbol code length: + A) reset the repeat variable + B) remember code length (if it is not 0) + C) extend corredponding index-chain + D) reduce the huffman space + E) update the histogram + */ +static BROTLI_INLINE void ProcessSingleCodeLength(uint32_t code_len, + uint32_t* symbol, uint32_t* repeat, uint32_t* space, + uint32_t* prev_code_len, uint16_t* symbol_lists, + uint16_t* code_length_histo, int* next_symbol) { + *repeat = 0; + if (code_len != 0) { /* code_len == 1..15 */ + symbol_lists[next_symbol[code_len]] = (uint16_t)(*symbol); + next_symbol[code_len] = (int)(*symbol); + *prev_code_len = code_len; + *space -= 32768U >> code_len; + code_length_histo[code_len]++; + BROTLI_LOG(("[ReadHuffmanCode] code_length[%d] = %d\n", *symbol, code_len)); + } + (*symbol)++; +} + +/* Process repeated symbol code length. + A) Check if it is the extension of previous repeat sequence; if the decoded + value is not kCodeLengthRepeatCode, then it is a new symbol-skip + B) Update repeat variable + C) Check if operation is feasible (fits alphapet) + D) For each symbol do the same operations as in ProcessSingleCodeLength + + PRECONDITION: code_len == kCodeLengthRepeatCode or kCodeLengthRepeatCode + 1 + */ +static BROTLI_INLINE void ProcessRepeatedCodeLength(uint32_t code_len, + uint32_t repeat_delta, uint32_t alphabet_size, uint32_t* symbol, + uint32_t* repeat, uint32_t* space, uint32_t* prev_code_len, + uint32_t* repeat_code_len, uint16_t* symbol_lists, + uint16_t* code_length_histo, int* next_symbol) { + uint32_t old_repeat; + uint32_t new_len = 0; + if (code_len == kCodeLengthRepeatCode) { + new_len = *prev_code_len; + } + if (*repeat_code_len != new_len) { + *repeat = 0; + *repeat_code_len = new_len; + } + old_repeat = *repeat; + if (*repeat > 0) { + *repeat -= 2; + *repeat <<= code_len - 14U; + } + *repeat += repeat_delta + 3U; + repeat_delta = *repeat - old_repeat; + if (*symbol + repeat_delta > alphabet_size) { + (void)BROTLI_FAILURE(); + *symbol = alphabet_size; + *space = 0xFFFFF; + return; + } + BROTLI_LOG(("[ReadHuffmanCode] code_length[%d..%d] = %d\n", + *symbol, *symbol + repeat_delta - 1, *repeat_code_len)); + if (*repeat_code_len != 0) { + unsigned last = *symbol + repeat_delta; + int next = next_symbol[*repeat_code_len]; + do { + symbol_lists[next] = (uint16_t)*symbol; + next = (int)*symbol; + } while (++(*symbol) != last); + next_symbol[*repeat_code_len] = next; + *space -= repeat_delta << (15 - *repeat_code_len); + code_length_histo[*repeat_code_len] = + (uint16_t)(code_length_histo[*repeat_code_len] + repeat_delta); + } else { + *symbol += repeat_delta; + } +} + +/* Reads and decodes symbol codelengths. */ +static BrotliResult ReadSymbolCodeLengths( + uint32_t alphabet_size, BrotliState* s) { + BrotliBitReader* br = &s->br; + uint32_t symbol = s->symbol; + uint32_t repeat = s->repeat; + uint32_t space = s->space; + uint32_t prev_code_len = s->prev_code_len; + uint32_t repeat_code_len = s->repeat_code_len; + uint16_t* symbol_lists = s->symbol_lists; + uint16_t* code_length_histo = s->code_length_histo; + int* next_symbol = s->next_symbol; + if (!BrotliWarmupBitReader(br)) { + return BROTLI_RESULT_NEEDS_MORE_INPUT; + } + while (symbol < alphabet_size && space > 0) { + const HuffmanCode* p = s->table; + uint32_t code_len; + if (!BrotliCheckInputAmount(br, BROTLI_SHORT_FILL_BIT_WINDOW_READ)) { + s->symbol = symbol; + s->repeat = repeat; + s->prev_code_len = prev_code_len; + s->repeat_code_len = repeat_code_len; + s->space = space; + return BROTLI_RESULT_NEEDS_MORE_INPUT; + } + BrotliFillBitWindow16(br); + p += BrotliGetBitsUnmasked(br) & + BitMask(BROTLI_HUFFMAN_MAX_CODE_LENGTH_CODE_LENGTH); + BrotliDropBits(br, p->bits); /* Use 1..5 bits */ + code_len = p->value; /* code_len == 0..17 */ + if (code_len < kCodeLengthRepeatCode) { + ProcessSingleCodeLength(code_len, &symbol, &repeat, &space, + &prev_code_len, symbol_lists, code_length_histo, next_symbol); + } else { /* code_len == 16..17, extra_bits == 2..3 */ + uint32_t repeat_delta = + (uint32_t)BrotliGetBitsUnmasked(br) & BitMask(code_len - 14U); + BrotliDropBits(br, code_len - 14U); + ProcessRepeatedCodeLength(code_len, repeat_delta, alphabet_size, + &symbol, &repeat, &space, &prev_code_len, &repeat_code_len, + symbol_lists, code_length_histo, next_symbol); + } + } + s->space = space; + return BROTLI_RESULT_SUCCESS; +} + +static BrotliResult SafeReadSymbolCodeLengths( + uint32_t alphabet_size, BrotliState* s) { + BrotliBitReader* br = &s->br; + while (s->symbol < alphabet_size && s->space > 0) { + const HuffmanCode* p = s->table; + uint32_t code_len; + uint32_t bits = 0; + uint32_t available_bits = BrotliGetAvailableBits(br); + if (available_bits != 0) { + bits = (uint32_t)BrotliGetBitsUnmasked(br); + } + p += bits & BitMask(BROTLI_HUFFMAN_MAX_CODE_LENGTH_CODE_LENGTH); + if (p->bits > available_bits) goto pullMoreInput; + code_len = p->value; /* code_len == 0..17 */ + if (code_len < kCodeLengthRepeatCode) { + BrotliDropBits(br, p->bits); + ProcessSingleCodeLength(code_len, &s->symbol, &s->repeat, &s->space, + &s->prev_code_len, s->symbol_lists, s->code_length_histo, + s->next_symbol); + } else { /* code_len == 16..17, extra_bits == 2..3 */ + uint32_t extra_bits = code_len - 14U; + uint32_t repeat_delta = (bits >> p->bits) & BitMask(extra_bits); + if (available_bits < p->bits + extra_bits) goto pullMoreInput; + BrotliDropBits(br, p->bits + extra_bits); + ProcessRepeatedCodeLength(code_len, repeat_delta, alphabet_size, + &s->symbol, &s->repeat, &s->space, &s->prev_code_len, + &s->repeat_code_len, s->symbol_lists, s->code_length_histo, + s->next_symbol); + } + continue; + +pullMoreInput: + if (!BrotliPullByte(br)) { + return BROTLI_RESULT_NEEDS_MORE_INPUT; + } + } + return BROTLI_RESULT_SUCCESS; +} + +/* Reads and decodes 15..18 codes using static prefix code. + Each code is 2..4 bits long. In total 30..72 bits are used. */ +static BrotliResult ReadCodeLengthCodeLengths(BrotliState* s) { + BrotliBitReader* br = &s->br; + uint32_t num_codes = s->repeat; + unsigned space = s->space; + uint32_t i = s->sub_loop_counter; + for (; i < CODE_LENGTH_CODES; ++i) { + const uint8_t code_len_idx = kCodeLengthCodeOrder[i]; + uint32_t ix; + uint32_t v; + if (PREDICT_FALSE(!BrotliSafeGetBits(br, 4, &ix))) { + uint32_t available_bits = BrotliGetAvailableBits(br); + if (available_bits != 0) { + ix = BrotliGetBitsUnmasked(br) & 0xF; + } else { + ix = 0; + } + if (kCodeLengthPrefixLength[ix] > available_bits) { + s->sub_loop_counter = i; + s->repeat = num_codes; + s->space = space; + s->substate_huffman = BROTLI_STATE_HUFFMAN_COMPLEX; + return BROTLI_RESULT_NEEDS_MORE_INPUT; + } + } + v = kCodeLengthPrefixValue[ix]; + BrotliDropBits(br, kCodeLengthPrefixLength[ix]); + s->code_length_code_lengths[code_len_idx] = (uint8_t)v; + BROTLI_LOG_ARRAY_INDEX(s->code_length_code_lengths, code_len_idx); + if (v != 0) { + space = space - (32U >> v); + ++num_codes; + ++s->code_length_histo[v]; + if (space - 1U >= 32U) { + /* space is 0 or wrapped around */ + break; + } + } + } + if (!(num_codes == 1 || space == 0)) { + return BROTLI_FAILURE(); + } + return BROTLI_RESULT_SUCCESS; +} + +/* Decodes the Huffman tables. + There are 2 scenarios: + A) Huffman code contains only few symbols (1..4). Those symbols are read + directly; their code lengths are defined by the number of symbols. + For this scenario 4 - 45 bits will be read. + + B) 2-phase decoding: + B.1) Small Huffman table is decoded; it is specified with code lengths + encoded with predefined entropy code. 32 - 74 bits are used. + B.2) Decoded table is used to decode code lengths of symbols in resulting + Huffman table. In worst case 3520 bits are read. +*/ +static BrotliResult ReadHuffmanCode(uint32_t alphabet_size, + HuffmanCode* table, + uint32_t* opt_table_size, + BrotliState* s) { + BrotliBitReader* br = &s->br; + /* Unnecessary masking, but might be good for safety. */ + alphabet_size &= 0x3ff; + /* State machine */ + switch (s->substate_huffman) { + case BROTLI_STATE_HUFFMAN_NONE: + if (!BrotliSafeReadBits(br, 2, &s->sub_loop_counter)) { + return BROTLI_RESULT_NEEDS_MORE_INPUT; + } + BROTLI_LOG_UINT(s->sub_loop_counter); + /* The value is used as follows: + 1 for simple code; + 0 for no skipping, 2 skips 2 code lengths, 3 skips 3 code lengths */ + if (s->sub_loop_counter != 1) { + s->space = 32; + s->repeat = 0; /* num_codes */ + memset(&s->code_length_histo[0], 0, sizeof(s->code_length_histo[0]) * + (BROTLI_HUFFMAN_MAX_CODE_LENGTH_CODE_LENGTH + 1)); + memset(&s->code_length_code_lengths[0], 0, + sizeof(s->code_length_code_lengths)); + s->substate_huffman = BROTLI_STATE_HUFFMAN_COMPLEX; + goto Complex; + } + /* No break, transit to the next state. */ + + case BROTLI_STATE_HUFFMAN_SIMPLE_SIZE: + /* Read symbols, codes & code lengths directly. */ + if (!BrotliSafeReadBits(br, 2, &s->symbol)) { /* num_symbols */ + s->substate_huffman = BROTLI_STATE_HUFFMAN_SIMPLE_SIZE; + return BROTLI_RESULT_NEEDS_MORE_INPUT; + } + s->sub_loop_counter = 0; + /* No break, transit to the next state. */ + case BROTLI_STATE_HUFFMAN_SIMPLE_READ: { + BrotliResult result = ReadSimpleHuffmanSymbols(alphabet_size, s); + if (result != BROTLI_RESULT_SUCCESS) { + return result; + } + /* No break, transit to the next state. */ + } + case BROTLI_STATE_HUFFMAN_SIMPLE_BUILD: { + uint32_t table_size; + if (s->symbol == 3) { + uint32_t bits; + if (!BrotliSafeReadBits(br, 1, &bits)) { + s->substate_huffman = BROTLI_STATE_HUFFMAN_SIMPLE_BUILD; + return BROTLI_RESULT_NEEDS_MORE_INPUT; + } + s->symbol += bits; + } + BROTLI_LOG_UINT(s->symbol); + table_size = BrotliBuildSimpleHuffmanTable( + table, HUFFMAN_TABLE_BITS, s->symbols_lists_array, s->symbol); + if (opt_table_size) { + *opt_table_size = table_size; + } + s->substate_huffman = BROTLI_STATE_HUFFMAN_NONE; + return BROTLI_RESULT_SUCCESS; + } + +Complex: /* Decode Huffman-coded code lengths. */ + case BROTLI_STATE_HUFFMAN_COMPLEX: { + uint32_t i; + BrotliResult result = ReadCodeLengthCodeLengths(s); + if (result != BROTLI_RESULT_SUCCESS) { + return result; + } + BrotliBuildCodeLengthsHuffmanTable(s->table, + s->code_length_code_lengths, + s->code_length_histo); + memset(&s->code_length_histo[0], 0, sizeof(s->code_length_histo)); + for (i = 0; i <= BROTLI_HUFFMAN_MAX_CODE_LENGTH; ++i) { + s->next_symbol[i] = (int)i - (BROTLI_HUFFMAN_MAX_CODE_LENGTH + 1); + s->symbol_lists[(int)i - (BROTLI_HUFFMAN_MAX_CODE_LENGTH + 1)] = 0xFFFF; + } + + s->symbol = 0; + s->prev_code_len = kDefaultCodeLength; + s->repeat = 0; + s->repeat_code_len = 0; + s->space = 32768; + s->substate_huffman = BROTLI_STATE_HUFFMAN_LENGTH_SYMBOLS; + /* No break, transit to the next state. */ + } + case BROTLI_STATE_HUFFMAN_LENGTH_SYMBOLS: { + uint32_t table_size; + BrotliResult result = ReadSymbolCodeLengths(alphabet_size, s); + if (result == BROTLI_RESULT_NEEDS_MORE_INPUT) { + result = SafeReadSymbolCodeLengths(alphabet_size, s); + } + if (result != BROTLI_RESULT_SUCCESS) { + return result; + } + + if (s->space != 0) { + BROTLI_LOG(("[ReadHuffmanCode] space = %d\n", s->space)); + return BROTLI_FAILURE(); + } + table_size = BrotliBuildHuffmanTable( + table, HUFFMAN_TABLE_BITS, s->symbol_lists, s->code_length_histo); + if (opt_table_size) { + *opt_table_size = table_size; + } + s->substate_huffman = BROTLI_STATE_HUFFMAN_NONE; + return BROTLI_RESULT_SUCCESS; + } + + default: + return BROTLI_FAILURE(); + } +} + +/* Decodes a block length by reading 3..39 bits. */ +static BROTLI_INLINE uint32_t ReadBlockLength(const HuffmanCode* table, + BrotliBitReader* br) { + uint32_t code; + uint32_t nbits; + code = ReadSymbol(table, br); + nbits = kBlockLengthPrefixCode[code].nbits; /* nbits == 2..24 */ + return kBlockLengthPrefixCode[code].offset + BrotliReadBits(br, nbits); +} + +/* WARNING: if state is not BROTLI_STATE_READ_BLOCK_LENGTH_NONE, then + reading can't be continued with ReadBlockLength. */ +static BROTLI_INLINE int SafeReadBlockLength(BrotliState* s, + uint32_t* result, + const HuffmanCode* table, + BrotliBitReader* br) { + uint32_t index; + if (s->substate_read_block_length == BROTLI_STATE_READ_BLOCK_LENGTH_NONE) { + if (!SafeReadSymbol(table, br, &index)) { + return 0; + } + } else { + index = s->block_length_index; + } + { + uint32_t bits; + uint32_t nbits = kBlockLengthPrefixCode[index].nbits; /* nbits == 2..24 */ + if (!BrotliSafeReadBits(br, nbits, &bits)) { + s->block_length_index = index; + s->substate_read_block_length = BROTLI_STATE_READ_BLOCK_LENGTH_SUFFIX; + return 0; + } + *result = kBlockLengthPrefixCode[index].offset + bits; + s->substate_read_block_length = BROTLI_STATE_READ_BLOCK_LENGTH_NONE; + return 1; + } +} + +/* Transform: + 1) initialize list L with values 0, 1,... 255 + 2) For each input element X: + 2.1) let Y = L[X] + 2.2) remove X-th element from L + 2.3) prepend Y to L + 2.4) append Y to output + + In most cases max(Y) <= 7, so most of L remains intact. + To reduce the cost of initialization, we reuse L, remember the upper bound + of Y values, and reinitialize only first elements in L. + + Most of input values are 0 and 1. To reduce number of branches, we replace + inner for loop with do-while. + */ +static BROTLI_NOINLINE void InverseMoveToFrontTransform(uint8_t* v, + uint32_t v_len, BrotliState* state) { + /* Reinitialize elements that could have been changed. */ + uint32_t i = 4; + uint32_t upper_bound = state->mtf_upper_bound; + uint8_t* mtf = state->mtf; + /* Load endian-aware constant. */ + const uint8_t b0123[4] = {0, 1, 2, 3}; + uint32_t pattern; + memcpy(&pattern, &b0123, 4); + + /* Initialize list using 4 consequent values pattern. */ + *(uint32_t*)mtf = pattern; + do { + pattern += 0x04040404; /* Advance all 4 values by 4. */ + *(uint32_t*)(mtf + i) = pattern; + i += 4; + } while (i <= upper_bound); + + /* Transform the input. */ + upper_bound = 0; + for (i = 0; i < v_len; ++i) { + int index = v[i]; + uint8_t value = mtf[index]; + upper_bound |= v[i]; + v[i] = value; + do { + index--; + mtf[index + 1] = mtf[index]; + } while (index > 0); + mtf[0] = value; + } + /* Remember amount of elements to be reinitialized. */ + state->mtf_upper_bound = upper_bound; +} + + +/* Decodes a series of Huffman table using ReadHuffmanCode function. */ +static BrotliResult HuffmanTreeGroupDecode(HuffmanTreeGroup* group, + BrotliState* s) { + if (s->substate_tree_group != BROTLI_STATE_TREE_GROUP_LOOP) { + s->next = group->codes; + s->htree_index = 0; + s->substate_tree_group = BROTLI_STATE_TREE_GROUP_LOOP; + } + while (s->htree_index < group->num_htrees) { + uint32_t table_size; + BrotliResult result = + ReadHuffmanCode(group->alphabet_size, s->next, &table_size, s); + if (result != BROTLI_RESULT_SUCCESS) return result; + group->htrees[s->htree_index] = s->next; + s->next += table_size; + ++s->htree_index; + } + s->substate_tree_group = BROTLI_STATE_TREE_GROUP_NONE; + return BROTLI_RESULT_SUCCESS; +} + +/* Decodes a context map. + Decoding is done in 4 phases: + 1) Read auxiliary information (6..16 bits) and allocate memory. + In case of trivial context map, decoding is finished at this phase. + 2) Decode Huffman table using ReadHuffmanCode function. + This table will be used for reading context map items. + 3) Read context map items; "0" values could be run-length encoded. + 4) Optionally, apply InverseMoveToFront transform to the resulting map. + */ +static BrotliResult DecodeContextMap(uint32_t context_map_size, + uint32_t* num_htrees, + uint8_t** context_map_arg, + BrotliState* s) { + BrotliBitReader* br = &s->br; + BrotliResult result = BROTLI_RESULT_SUCCESS; + + switch ((int)s->substate_context_map) { + case BROTLI_STATE_CONTEXT_MAP_NONE: + result = DecodeVarLenUint8(s, br, num_htrees); + if (result != BROTLI_RESULT_SUCCESS) { + return result; + } + (*num_htrees)++; + s->context_index = 0; + BROTLI_LOG_UINT(context_map_size); + BROTLI_LOG_UINT(*num_htrees); + *context_map_arg = (uint8_t*)BROTLI_ALLOC(s, (size_t)context_map_size); + if (*context_map_arg == 0) { + return BROTLI_FAILURE(); + } + if (*num_htrees <= 1) { + memset(*context_map_arg, 0, (size_t)context_map_size); + return BROTLI_RESULT_SUCCESS; + } + s->substate_context_map = BROTLI_STATE_CONTEXT_MAP_READ_PREFIX; + /* No break, continue to next state. */ + case BROTLI_STATE_CONTEXT_MAP_READ_PREFIX: { + uint32_t bits; + /* In next stage ReadHuffmanCode uses at least 4 bits, so it is safe + to peek 4 bits ahead. */ + if (!BrotliSafeGetBits(br, 5, &bits)) { + return BROTLI_RESULT_NEEDS_MORE_INPUT; + } + if ((bits & 1) != 0) { /* Use RLE for zeroes. */ + s->max_run_length_prefix = (bits >> 1) + 1; + BrotliDropBits(br, 5); + } else { + s->max_run_length_prefix = 0; + BrotliDropBits(br, 1); + } + BROTLI_LOG_UINT(s->max_run_length_prefix); + s->substate_context_map = BROTLI_STATE_CONTEXT_MAP_HUFFMAN; + /* No break, continue to next state. */ + } + case BROTLI_STATE_CONTEXT_MAP_HUFFMAN: + result = ReadHuffmanCode(*num_htrees + s->max_run_length_prefix, + s->context_map_table, NULL, s); + if (result != BROTLI_RESULT_SUCCESS) return result; + s->code = 0xFFFF; + s->substate_context_map = BROTLI_STATE_CONTEXT_MAP_DECODE; + /* No break, continue to next state. */ + case BROTLI_STATE_CONTEXT_MAP_DECODE: { + uint32_t context_index = s->context_index; + uint32_t max_run_length_prefix = s->max_run_length_prefix; + uint8_t* context_map = *context_map_arg; + uint32_t code = s->code; + if (code != 0xFFFF) { + goto rleCode; + } + while (context_index < context_map_size) { + if (!SafeReadSymbol(s->context_map_table, br, &code)) { + s->code = 0xFFFF; + s->context_index = context_index; + return BROTLI_RESULT_NEEDS_MORE_INPUT; + } + BROTLI_LOG_UINT(code); + + if (code == 0) { + context_map[context_index++] = 0; + continue; + } + if (code > max_run_length_prefix) { + context_map[context_index++] = + (uint8_t)(code - max_run_length_prefix); + continue; + } +rleCode: + { + uint32_t reps; + if (!BrotliSafeReadBits(br, code, &reps)) { + s->code = code; + s->context_index = context_index; + return BROTLI_RESULT_NEEDS_MORE_INPUT; + } + reps += 1U << code; + BROTLI_LOG_UINT(reps); + if (context_index + reps > context_map_size) { + return BROTLI_FAILURE(); + } + do { + context_map[context_index++] = 0; + } while (--reps); + } + } + /* No break, continue to next state. */ + } + case BROTLI_STATE_CONTEXT_MAP_TRANSFORM: { + uint32_t bits; + if (!BrotliSafeReadBits(br, 1, &bits)) { + s->substate_context_map = BROTLI_STATE_CONTEXT_MAP_TRANSFORM; + return BROTLI_RESULT_NEEDS_MORE_INPUT; + } + if (bits != 0) { + InverseMoveToFrontTransform(*context_map_arg, context_map_size, s); + } + s->substate_context_map = BROTLI_STATE_CONTEXT_MAP_NONE; + return BROTLI_RESULT_SUCCESS; + } + default: + return BROTLI_FAILURE(); + } +} + +/* Decodes a command or literal and updates block type ringbuffer. + Reads 3..54 bits. */ +static BROTLI_INLINE int DecodeBlockTypeAndLength(int safe, + BrotliState* s, int tree_type) { + uint32_t max_block_type = s->num_block_types[tree_type]; + const HuffmanCode* type_tree = &s->block_type_trees[ + tree_type * BROTLI_HUFFMAN_MAX_SIZE_258]; + const HuffmanCode* len_tree = &s->block_len_trees[ + tree_type * BROTLI_HUFFMAN_MAX_SIZE_26]; + BrotliBitReader* br = &s->br; + uint32_t* ringbuffer = &s->block_type_rb[tree_type * 2]; + uint32_t block_type; + + /* Read 0..15 + 3..39 bits */ + if (!safe) { + block_type = ReadSymbol(type_tree, br); + s->block_length[tree_type] = ReadBlockLength(len_tree, br); + } else { + BrotliBitReaderState memento; + BrotliBitReaderSaveState(br, &memento); + if (!SafeReadSymbol(type_tree, br, &block_type)) return 0; + if (!SafeReadBlockLength(s, &s->block_length[tree_type], len_tree, br)) { + s->substate_read_block_length = BROTLI_STATE_READ_BLOCK_LENGTH_NONE; + BrotliBitReaderRestoreState(br, &memento); + return 0; + } + } + + if (block_type == 1) { + block_type = ringbuffer[1] + 1; + } else if (block_type == 0) { + block_type = ringbuffer[0]; + } else { + block_type -= 2; + } + if (block_type >= max_block_type) { + block_type -= max_block_type; + } + ringbuffer[0] = ringbuffer[1]; + ringbuffer[1] = block_type; + return 1; +} + +/* Decodes the block type and updates the state for literal context. + Reads 3..54 bits. */ +static BROTLI_INLINE int DecodeLiteralBlockSwitchInternal(int safe, + BrotliState* s) { + uint8_t context_mode; + uint32_t context_offset; + if (!DecodeBlockTypeAndLength(safe, s, 0)) { + return 0; + } + context_offset = s->block_type_rb[1] << kLiteralContextBits; + s->context_map_slice = s->context_map + context_offset; + s->literal_htree_index = s->context_map_slice[0]; + s->literal_htree = s->literal_hgroup.htrees[s->literal_htree_index]; + context_mode = s->context_modes[s->block_type_rb[1]]; + s->context_lookup1 = &kContextLookup[kContextLookupOffsets[context_mode]]; + s->context_lookup2 = &kContextLookup[kContextLookupOffsets[context_mode + 1]]; + return 1; +} + +static void BROTLI_NOINLINE DecodeLiteralBlockSwitch(BrotliState* s) { + DecodeLiteralBlockSwitchInternal(0, s); +} + +static int BROTLI_NOINLINE SafeDecodeLiteralBlockSwitch(BrotliState* s) { + return DecodeLiteralBlockSwitchInternal(1, s); +} + +/* Block switch for insert/copy length. + Reads 3..54 bits. */ +static BROTLI_INLINE int DecodeCommandBlockSwitchInternal(int safe, + BrotliState* s) { + if (!DecodeBlockTypeAndLength(safe, s, 1)) { + return 0; + } + s->htree_command = s->insert_copy_hgroup.htrees[s->block_type_rb[3]]; + return 1; +} + +static void BROTLI_NOINLINE DecodeCommandBlockSwitch(BrotliState* s) { + DecodeCommandBlockSwitchInternal(0, s); +} +static int BROTLI_NOINLINE SafeDecodeCommandBlockSwitch(BrotliState* s) { + return DecodeCommandBlockSwitchInternal(1, s); +} + +/* Block switch for distance codes. + Reads 3..54 bits. */ +static BROTLI_INLINE int DecodeDistanceBlockSwitchInternal(int safe, + BrotliState* s) { + if (!DecodeBlockTypeAndLength(safe, s, 2)) { + return 0; + } + s->dist_context_map_slice = + s->dist_context_map + (s->block_type_rb[5] << kDistanceContextBits); + s->dist_htree_index = s->dist_context_map_slice[s->distance_context]; + return 1; +} + +static void BROTLI_NOINLINE DecodeDistanceBlockSwitch(BrotliState* s) { + DecodeDistanceBlockSwitchInternal(0, s); +} + +static int BROTLI_NOINLINE SafeDecodeDistanceBlockSwitch(BrotliState* s) { + return DecodeDistanceBlockSwitchInternal(1, s); +} + +static BrotliResult WriteRingBuffer(size_t* available_out, uint8_t** next_out, + size_t* total_out, BrotliState* s) { + size_t pos = (s->pos > s->ringbuffer_size) ? (size_t)s->ringbuffer_size + : (size_t)(s->pos); + uint8_t* start = + s->ringbuffer + (s->partial_pos_out & (size_t)s->ringbuffer_mask); + size_t partial_pos_rb = (s->rb_roundtrips * (size_t)s->ringbuffer_size) + pos; + size_t to_write = (partial_pos_rb - s->partial_pos_out); + size_t num_written = *available_out; + if (num_written > to_write) { + num_written = to_write; + } + if (s->meta_block_remaining_len < 0) { + return BROTLI_FAILURE(); + } + memcpy(*next_out, start, num_written); + *next_out += num_written; + *available_out -= num_written; + BROTLI_LOG_UINT(to_write); + BROTLI_LOG_UINT(num_written); + s->partial_pos_out += num_written; + *total_out = s->partial_pos_out; + if (num_written < to_write) { + return BROTLI_RESULT_NEEDS_MORE_OUTPUT; + } + return BROTLI_RESULT_SUCCESS; +} + +/* Allocates ringbuffer. + + s->ringbuffer_size MUST be updated by BrotliCalculateRingBufferSize before + this function is called. + + Last two bytes of ringbuffer are initialized to 0, so context calculation + could be done uniformly for the first two and all other positions. + + Custom dictionary, if any, is copied to the end of ringbuffer. +*/ +static int BROTLI_NOINLINE BrotliAllocateRingBuffer(BrotliState* s) { + /* We need the slack region for the following reasons: + - doing up to two 16-byte copies for fast backward copying + - inserting transformed dictionary word (5 prefix + 24 base + 8 suffix) */ + static const int kRingBufferWriteAheadSlack = 42; + s->ringbuffer = (uint8_t*)BROTLI_ALLOC(s, (size_t)(s->ringbuffer_size + + kRingBufferWriteAheadSlack)); + if (s->ringbuffer == 0) { + return 0; + } + + s->ringbuffer_end = s->ringbuffer + s->ringbuffer_size; + + s->ringbuffer[s->ringbuffer_size - 2] = 0; + s->ringbuffer[s->ringbuffer_size - 1] = 0; + + if (s->custom_dict) { + memcpy(&s->ringbuffer[(-s->custom_dict_size) & s->ringbuffer_mask], + s->custom_dict, (size_t)s->custom_dict_size); + } + + return 1; +} + +static BrotliResult BROTLI_NOINLINE CopyUncompressedBlockToOutput( + size_t* available_out, uint8_t** next_out, size_t* total_out, + BrotliState* s) { + /* TODO: avoid allocation for single uncompressed block. */ + if (!s->ringbuffer && !BrotliAllocateRingBuffer(s)) { + return BROTLI_FAILURE(); + } + + /* State machine */ + for (;;) { + switch (s->substate_uncompressed) { + case BROTLI_STATE_UNCOMPRESSED_NONE: { + int nbytes = (int)BrotliGetRemainingBytes(&s->br); + if (nbytes > s->meta_block_remaining_len) { + nbytes = s->meta_block_remaining_len; + } + if (s->pos + nbytes > s->ringbuffer_size) { + nbytes = s->ringbuffer_size - s->pos; + } + /* Copy remaining bytes from s->br.buf_ to ringbuffer. */ + BrotliCopyBytes(&s->ringbuffer[s->pos], &s->br, (size_t)nbytes); + s->pos += nbytes; + s->meta_block_remaining_len -= nbytes; + if (s->pos < s->ringbuffer_size) { + if (s->meta_block_remaining_len == 0) { + return BROTLI_RESULT_SUCCESS; + } + return BROTLI_RESULT_NEEDS_MORE_INPUT; + } + s->substate_uncompressed = BROTLI_STATE_UNCOMPRESSED_WRITE; + /* No break, continue to next state */ + } + case BROTLI_STATE_UNCOMPRESSED_WRITE: { + BrotliResult result = + WriteRingBuffer(available_out, next_out, total_out, s); + if (result != BROTLI_RESULT_SUCCESS) { + return result; + } + s->pos = 0; + s->rb_roundtrips++; + s->max_distance = s->max_backward_distance; + s->substate_uncompressed = BROTLI_STATE_UNCOMPRESSED_NONE; + break; + } + } + } + return BROTLI_FAILURE(); +} + +int BrotliDecompressedSize(size_t encoded_size, + const uint8_t* encoded_buffer, + size_t* decoded_size) { + BrotliState s; + int next_block_header; + BrotliStateInit(&s); + s.br.next_in = encoded_buffer; + s.br.avail_in = encoded_size; + if (!BrotliWarmupBitReader(&s.br)) { + return 0; + } + DecodeWindowBits(&s.br); + if (DecodeMetaBlockLength(&s, &s.br) != BROTLI_RESULT_SUCCESS) { + return 0; + } + *decoded_size = (size_t)s.meta_block_remaining_len; + if (s.is_last_metablock) { + return 1; + } + if (!s.is_uncompressed || !BrotliJumpToByteBoundary(&s.br)) { + return 0; + } + next_block_header = BrotliPeekByte(&s.br, (size_t)s.meta_block_remaining_len); + return (next_block_header != -1) && ((next_block_header & 3) == 3); +} + +/* Calculates the smallest feasible ring buffer. + + If we know the data size is small, do not allocate more ringbuffer + size than needed to reduce memory usage. + + When this method is called, metablock size and flags MUST be decoded. +*/ +static void BROTLI_NOINLINE BrotliCalculateRingBufferSize(BrotliState* s, + BrotliBitReader* br) { + int is_last = s->is_last_metablock; + s->ringbuffer_size = 1 << s->window_bits; + + if (s->is_uncompressed) { + int next_block_header = + BrotliPeekByte(br, (size_t)s->meta_block_remaining_len); + if (next_block_header != -1) { /* Peek succeeded */ + if ((next_block_header & 3) == 3) { /* ISLAST and ISEMPTY */ + is_last = 1; + } + } + } + + /* We need at least 2 bytes of ring buffer size to get the last two + bytes for context from there */ + if (is_last) { + while (s->ringbuffer_size >= s->meta_block_remaining_len * 2 && + s->ringbuffer_size > 32) { + s->ringbuffer_size >>= 1; + } + } + + /* But make it fit the custom dictionary if there is one. */ + while (s->ringbuffer_size < s->custom_dict_size) { + s->ringbuffer_size <<= 1; + } + + s->ringbuffer_mask = s->ringbuffer_size - 1; +} + +/* Reads 1..256 2-bit context modes. */ +static BrotliResult ReadContextModes(BrotliState* s) { + BrotliBitReader* br = &s->br; + int i = s->loop_counter; + + while (i < (int)s->num_block_types[0]) { + uint32_t bits; + if (!BrotliSafeReadBits(br, 2, &bits)) { + s->loop_counter = i; + return BROTLI_RESULT_NEEDS_MORE_INPUT; + } + s->context_modes[i] = (uint8_t)(bits << 1); + BROTLI_LOG_ARRAY_INDEX(s->context_modes, i); + i++; + } + return BROTLI_RESULT_SUCCESS; +} + +static BROTLI_INLINE void TakeDistanceFromRingBuffer(BrotliState* s) { + if (s->distance_code == 0) { + --s->dist_rb_idx; + s->distance_code = s->dist_rb[s->dist_rb_idx & 3]; + } else { + int distance_code = s->distance_code << 1; + /* kDistanceShortCodeIndexOffset has 2-bit values from LSB: */ + /* 3, 2, 1, 0, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2 */ + const uint32_t kDistanceShortCodeIndexOffset = 0xaaafff1b; + /* kDistanceShortCodeValueOffset has 2-bit values from LSB: */ + /*-0, 0,-0, 0,-1, 1,-2, 2,-3, 3,-1, 1,-2, 2,-3, 3 */ + const uint32_t kDistanceShortCodeValueOffset = 0xfa5fa500; + int v = (s->dist_rb_idx + + (int)(kDistanceShortCodeIndexOffset >> distance_code)) & 0x3; + s->distance_code = s->dist_rb[v]; + v = (int)(kDistanceShortCodeValueOffset >> distance_code) & 0x3; + if ((distance_code & 0x3) != 0) { + s->distance_code += v; + } else { + s->distance_code -= v; + if (s->distance_code <= 0) { + /* A huge distance will cause a BROTLI_FAILURE() soon. */ + /* This is a little faster than failing here. */ + s->distance_code = 0x0fffffff; + } + } + } +} + +static BROTLI_INLINE int SafeReadBits( + BrotliBitReader* const br, uint32_t n_bits, uint32_t* val) { + if (n_bits != 0) { + return BrotliSafeReadBits(br, n_bits, val); + } else { + *val = 0; + return 1; + } +} + +/* Precondition: s->distance_code < 0 */ +static BROTLI_INLINE int ReadDistanceInternal(int safe, + BrotliState* s, BrotliBitReader* br) { + int distval; + BrotliBitReaderState memento; + HuffmanCode* distance_tree = s->distance_hgroup.htrees[s->dist_htree_index]; + if (!safe) { + s->distance_code = (int)ReadSymbol(distance_tree, br); + } else { + uint32_t code; + BrotliBitReaderSaveState(br, &memento); + if (!SafeReadSymbol(distance_tree, br, &code)) { + return 0; + } + s->distance_code = (int)code; + } + /* Convert the distance code to the actual distance by possibly */ + /* looking up past distances from the s->ringbuffer. */ + if ((s->distance_code & ~0xf) == 0) { + TakeDistanceFromRingBuffer(s); + --s->block_length[2]; + return 1; + } + distval = s->distance_code - (int)s->num_direct_distance_codes; + if (distval >= 0) { + uint32_t nbits; + int postfix; + int offset; + if (!safe && (s->distance_postfix_bits == 0)) { + nbits = ((uint32_t)distval >> 1) + 1; + offset = ((2 + (distval & 1)) << nbits) - 4; + s->distance_code = (int)s->num_direct_distance_codes + offset + + (int)BrotliReadBits(br, nbits); + } else { + /* This branch also works well when s->distance_postfix_bits == 0 */ + uint32_t bits; + postfix = distval & s->distance_postfix_mask; + distval >>= s->distance_postfix_bits; + nbits = ((uint32_t)distval >> 1) + 1; + if (safe) { + if (!SafeReadBits(br, nbits, &bits)) { + s->distance_code = -1; /* Restore precondition. */ + BrotliBitReaderRestoreState(br, &memento); + return 0; + } + } else { + bits = BrotliReadBits(br, nbits); + } + offset = ((2 + (distval & 1)) << nbits) - 4; + s->distance_code = (int)s->num_direct_distance_codes + + ((offset + (int)bits) << s->distance_postfix_bits) + postfix; + } + } + s->distance_code = s->distance_code - NUM_DISTANCE_SHORT_CODES + 1; + --s->block_length[2]; + return 1; +} + +static BROTLI_INLINE void ReadDistance(BrotliState* s, BrotliBitReader* br) { + ReadDistanceInternal(0, s, br); +} + +static BROTLI_INLINE int SafeReadDistance(BrotliState* s, BrotliBitReader* br) { + return ReadDistanceInternal(1, s, br); +} + +static BROTLI_INLINE int ReadCommandInternal(int safe, + BrotliState* s, BrotliBitReader* br, int* insert_length) { + uint32_t cmd_code; + uint32_t insert_len_extra = 0; + uint32_t copy_length; + CmdLutElement v; + BrotliBitReaderState memento; + if (!safe) { + cmd_code = ReadSymbol(s->htree_command, br); + } else { + BrotliBitReaderSaveState(br, &memento); + if (!SafeReadSymbol(s->htree_command, br, &cmd_code)) { + return 0; + } + } + v = kCmdLut[cmd_code]; + s->distance_code = v.distance_code; + s->distance_context = v.context; + s->dist_htree_index = s->dist_context_map_slice[s->distance_context]; + *insert_length = v.insert_len_offset; + if (!safe) { + if (PREDICT_FALSE(v.insert_len_extra_bits != 0)) { + insert_len_extra = BrotliReadBits(br, v.insert_len_extra_bits); + } + copy_length = BrotliReadBits(br, v.copy_len_extra_bits); + } else { + if (!SafeReadBits(br, v.insert_len_extra_bits, &insert_len_extra) || + !SafeReadBits(br, v.copy_len_extra_bits, ©_length)) { + BrotliBitReaderRestoreState(br, &memento); + return 0; + } + } + s->copy_length = (int)copy_length + v.copy_len_offset; + --s->block_length[1]; + *insert_length += (int)insert_len_extra; + return 1; +} + +static BROTLI_INLINE void ReadCommand(BrotliState* s, BrotliBitReader* br, + int* insert_length) { + ReadCommandInternal(0, s, br, insert_length); +} + +static BROTLI_INLINE int SafeReadCommand(BrotliState* s, BrotliBitReader* br, + int* insert_length) { + return ReadCommandInternal(1, s, br, insert_length); +} + +static BROTLI_INLINE int CheckInputAmount(int safe, + BrotliBitReader* const br, size_t num) { + if (safe) { + return 1; + } + return BrotliCheckInputAmount(br, num); +} + +#define BROTLI_SAFE(METHOD) \ + { \ + if (safe) { \ + if (!Safe##METHOD) { \ + result = BROTLI_RESULT_NEEDS_MORE_INPUT; \ + goto saveStateAndReturn; \ + } \ + } else { \ + METHOD; \ + } \ + } + +static BROTLI_INLINE BrotliResult ProcessCommandsInternal(int safe, + BrotliState* s) { + int pos = s->pos; + int i = s->loop_counter; + BrotliResult result = BROTLI_RESULT_SUCCESS; + BrotliBitReader* br = &s->br; + + if (!CheckInputAmount(safe, br, 28)) { + result = BROTLI_RESULT_NEEDS_MORE_INPUT; + goto saveStateAndReturn; + } + if (!safe) { + BROTLI_UNUSED(BrotliWarmupBitReader(br)); + } + + /* Jump into state machine. */ + if (s->state == BROTLI_STATE_COMMAND_BEGIN) { + goto CommandBegin; + } else if (s->state == BROTLI_STATE_COMMAND_INNER) { + goto CommandInner; + } else if (s->state == BROTLI_STATE_COMMAND_POST_DECODE_LITERALS) { + goto CommandPostDecodeLiterals; + } else if (s->state == BROTLI_STATE_COMMAND_POST_WRAP_COPY) { + goto CommandPostWrapCopy; + } else { + return BROTLI_FAILURE(); + } + +CommandBegin: + if (safe) { + s->state = BROTLI_STATE_COMMAND_BEGIN; + } + if (!CheckInputAmount(safe, br, 28)) { /* 156 bits + 7 bytes */ + s->state = BROTLI_STATE_COMMAND_BEGIN; + result = BROTLI_RESULT_NEEDS_MORE_INPUT; + goto saveStateAndReturn; + } + if (PREDICT_FALSE(s->block_length[1] == 0)) { + BROTLI_SAFE(DecodeCommandBlockSwitch(s)); + goto CommandBegin; + } + /* Read the insert/copy length in the command */ + BROTLI_SAFE(ReadCommand(s, br, &i)); + BROTLI_LOG(("[ProcessCommandsInternal] pos = %d insert = %d copy = %d\n", + pos, i, s->copy_length)); + if (i == 0) { + goto CommandPostDecodeLiterals; + } + s->meta_block_remaining_len -= i; + +CommandInner: + if (safe) { + s->state = BROTLI_STATE_COMMAND_INNER; + } + /* Read the literals in the command */ + if (s->trivial_literal_context) { + uint32_t bits; + uint32_t value; + PreloadSymbol(safe, s->literal_htree, br, &bits, &value); + do { + if (!CheckInputAmount(safe, br, 28)) { /* 162 bits + 7 bytes */ + s->state = BROTLI_STATE_COMMAND_INNER; + result = BROTLI_RESULT_NEEDS_MORE_INPUT; + goto saveStateAndReturn; + } + if (PREDICT_FALSE(s->block_length[0] == 0)) { + BROTLI_SAFE(DecodeLiteralBlockSwitch(s)); + PreloadSymbol(safe, s->literal_htree, br, &bits, &value); + } + if (!safe) { + s->ringbuffer[pos] = + (uint8_t)ReadPreloadedSymbol(s->literal_htree, br, &bits, &value); + } else { + uint32_t literal; + if (!SafeReadSymbol(s->literal_htree, br, &literal)) { + result = BROTLI_RESULT_NEEDS_MORE_INPUT; + goto saveStateAndReturn; + } + s->ringbuffer[pos] = (uint8_t)literal; + } + --s->block_length[0]; + BROTLI_LOG_UINT(s->literal_htree_index); + BROTLI_LOG_ARRAY_INDEX(s->ringbuffer, pos); + ++pos; + if (PREDICT_FALSE(pos == s->ringbuffer_size)) { + s->state = BROTLI_STATE_COMMAND_INNER_WRITE; + --i; + goto saveStateAndReturn; + } + } while (--i != 0); + } else { + uint8_t p1 = s->ringbuffer[(pos - 1) & s->ringbuffer_mask]; + uint8_t p2 = s->ringbuffer[(pos - 2) & s->ringbuffer_mask]; + do { + const HuffmanCode* hc; + uint8_t context; + if (!CheckInputAmount(safe, br, 28)) { /* 162 bits + 7 bytes */ + s->state = BROTLI_STATE_COMMAND_INNER; + result = BROTLI_RESULT_NEEDS_MORE_INPUT; + goto saveStateAndReturn; + } + if (PREDICT_FALSE(s->block_length[0] == 0)) { + BROTLI_SAFE(DecodeLiteralBlockSwitch(s)); + } + context = s->context_lookup1[p1] | s->context_lookup2[p2]; + BROTLI_LOG_UINT(context); + hc = s->literal_hgroup.htrees[s->context_map_slice[context]]; + p2 = p1; + if (!safe) { + p1 = (uint8_t)ReadSymbol(hc, br); + } else { + uint32_t literal; + if (!SafeReadSymbol(hc, br, &literal)) { + result = BROTLI_RESULT_NEEDS_MORE_INPUT; + goto saveStateAndReturn; + } + p1 = (uint8_t)literal; + } + s->ringbuffer[pos] = p1; + --s->block_length[0]; + BROTLI_LOG_UINT(s->context_map_slice[context]); + BROTLI_LOG_ARRAY_INDEX(s->ringbuffer, pos & s->ringbuffer_mask); + ++pos; + if (PREDICT_FALSE(pos == s->ringbuffer_size)) { + s->state = BROTLI_STATE_COMMAND_INNER_WRITE; + --i; + goto saveStateAndReturn; + } + } while (--i != 0); + } + BROTLI_LOG_UINT(s->meta_block_remaining_len); + if (s->meta_block_remaining_len <= 0) { + s->state = BROTLI_STATE_METABLOCK_DONE; + goto saveStateAndReturn; + } + +CommandPostDecodeLiterals: + if (safe) { + s->state = BROTLI_STATE_COMMAND_POST_DECODE_LITERALS; + } + if (s->distance_code >= 0) { + --s->dist_rb_idx; + s->distance_code = s->dist_rb[s->dist_rb_idx & 3]; + goto postReadDistance; /* We already have the implicit distance */ + } + /* Read distance code in the command, unless it was implicitly zero. */ + if (PREDICT_FALSE(s->block_length[2] == 0)) { + BROTLI_SAFE(DecodeDistanceBlockSwitch(s)); + } + BROTLI_SAFE(ReadDistance(s, br)); +postReadDistance: + BROTLI_LOG(("[ProcessCommandsInternal] pos = %d distance = %d\n", + pos, s->distance_code)); + if (s->max_distance != s->max_backward_distance) { + if (pos < s->max_backward_distance_minus_custom_dict_size) { + s->max_distance = pos + s->custom_dict_size; + } else { + s->max_distance = s->max_backward_distance; + } + } + i = s->copy_length; + /* Apply copy of LZ77 back-reference, or static dictionary reference if + the distance is larger than the max LZ77 distance */ + if (s->distance_code > s->max_distance) { + if (i >= kBrotliMinDictionaryWordLength && + i <= kBrotliMaxDictionaryWordLength) { + int offset = (int)kBrotliDictionaryOffsetsByLength[i]; + int word_id = s->distance_code - s->max_distance - 1; + uint32_t shift = kBrotliDictionarySizeBitsByLength[i]; + int mask = (int)BitMask(shift); + int word_idx = word_id & mask; + int transform_idx = word_id >> shift; + offset += word_idx * i; + if (transform_idx < kNumTransforms) { + const uint8_t* word = &kBrotliDictionary[offset]; + int len = i; + if (transform_idx == 0) { + memcpy(&s->ringbuffer[pos], word, (size_t)len); + } else { + len = TransformDictionaryWord( + &s->ringbuffer[pos], word, len, transform_idx); + } + pos += len; + s->meta_block_remaining_len -= len; + if (pos >= s->ringbuffer_size) { + /*s->partial_pos_rb += (size_t)s->ringbuffer_size;*/ + s->state = BROTLI_STATE_COMMAND_POST_WRITE_1; + goto saveStateAndReturn; + } + } else { + BROTLI_LOG(("Invalid backward reference. pos: %d distance: %d " + "len: %d bytes left: %d\n", + pos, s->distance_code, i, s->meta_block_remaining_len)); + return BROTLI_FAILURE(); + } + } else { + BROTLI_LOG(("Invalid backward reference. pos: %d distance: %d " + "len: %d bytes left: %d\n", + pos, s->distance_code, i, s->meta_block_remaining_len)); + return BROTLI_FAILURE(); + } + } else { + int src_start = (pos - s->distance_code) & s->ringbuffer_mask; + uint8_t* copy_dst = &s->ringbuffer[pos]; + uint8_t* copy_src = &s->ringbuffer[src_start]; + int dst_end = pos + i; + int src_end = src_start + i; + /* update the recent distances cache */ + s->dist_rb[s->dist_rb_idx & 3] = s->distance_code; + ++s->dist_rb_idx; + s->meta_block_remaining_len -= i; + if (PREDICT_FALSE(s->meta_block_remaining_len < 0)) { + BROTLI_LOG(("Invalid backward reference. pos: %d distance: %d " + "len: %d bytes left: %d\n", + pos, s->distance_code, i, s->meta_block_remaining_len)); + return BROTLI_FAILURE(); + } + /* There are 32+ bytes of slack in the ringbuffer allocation. + Also, we have 16 short codes, that make these 16 bytes irrelevant + in the ringbuffer. Let's copy over them as a first guess. + */ + memmove16(copy_dst, copy_src); + if (src_end > pos && dst_end > src_start) { + /* Regions intersect. */ + goto CommandPostWrapCopy; + } + if (dst_end >= s->ringbuffer_size || src_end >= s->ringbuffer_size) { + /* At least one region wraps. */ + goto CommandPostWrapCopy; + } + pos += i; + if (i > 16) { + if (i > 32) { + memcpy(copy_dst + 16, copy_src + 16, (size_t)(i - 16)); + } else { + /* This branch covers about 45% cases. + Fixed size short copy allows more compiler optimizations. */ + memmove16(copy_dst + 16, copy_src + 16); + } + } + } + BROTLI_LOG_UINT(s->meta_block_remaining_len); + if (s->meta_block_remaining_len <= 0) { + /* Next metablock, if any */ + s->state = BROTLI_STATE_METABLOCK_DONE; + goto saveStateAndReturn; + } else { + goto CommandBegin; + } +CommandPostWrapCopy: + { + int wrap_guard = s->ringbuffer_size - pos; + while (--i >= 0) { + s->ringbuffer[pos] = + s->ringbuffer[(pos - s->distance_code) & s->ringbuffer_mask]; + ++pos; + if (PREDICT_FALSE(--wrap_guard == 0)) { + s->state = BROTLI_STATE_COMMAND_POST_WRITE_2; + goto saveStateAndReturn; + } + } + } + if (s->meta_block_remaining_len <= 0) { + /* Next metablock, if any */ + s->state = BROTLI_STATE_METABLOCK_DONE; + goto saveStateAndReturn; + } else { + goto CommandBegin; + } + +saveStateAndReturn: + s->pos = pos; + s->loop_counter = i; + return result; +} + +#undef BROTLI_SAFE + +static BROTLI_NOINLINE BrotliResult ProcessCommands(BrotliState* s) { + return ProcessCommandsInternal(0, s); +} + +static BROTLI_NOINLINE BrotliResult SafeProcessCommands(BrotliState* s) { + return ProcessCommandsInternal(1, s); +} + +BrotliResult BrotliDecompressBuffer(size_t encoded_size, + const uint8_t* encoded_buffer, + size_t* decoded_size, + uint8_t* decoded_buffer) { + BrotliState s; + BrotliResult result; + size_t total_out = 0; + size_t available_in = encoded_size; + const uint8_t* next_in = encoded_buffer; + size_t available_out = *decoded_size; + uint8_t* next_out = decoded_buffer; + BrotliStateInit(&s); + result = BrotliDecompressStream(&available_in, &next_in, &available_out, + &next_out, &total_out, &s); + *decoded_size = total_out; + BrotliStateCleanup(&s); + if (result != BROTLI_RESULT_SUCCESS) { + result = BROTLI_RESULT_ERROR; + } + return result; +} + +/* Invariant: input stream is never overconsumed: + * invalid input implies that the whole stream is invalid -> any amount of + input could be read and discarded + * when result is "needs more input", then at leat one more byte is REQUIRED + to complete decoding; all input data MUST be consumed by decoder, so + client could swap the input buffer + * when result is "needs more output" decoder MUST ensure that it doesn't + hold more than 7 bits in bit reader; this saves client from swapping input + buffer ahead of time + * when result is "success" decoder MUST return all unused data back to input + buffer; this is possible because the invariant is hold on enter +*/ +BrotliResult BrotliDecompressStream(size_t* available_in, + const uint8_t** next_in, size_t* available_out, uint8_t** next_out, + size_t* total_out, BrotliState* s) { + BrotliResult result = BROTLI_RESULT_SUCCESS; + BrotliBitReader* br = &s->br; + if (s->buffer_length == 0) { /* Just connect bit reader to input stream. */ + br->avail_in = *available_in; + br->next_in = *next_in; + } else { + /* At least one byte of input is required. More than one byte of input may + be required to complete the transaction -> reading more data must be + done in a loop -> do it in a main loop. */ + result = BROTLI_RESULT_NEEDS_MORE_INPUT; + br->next_in = &s->buffer.u8[0]; + } + /* State machine */ + for (;;) { + if (result != BROTLI_RESULT_SUCCESS) { /* Error | needs more input/output */ + if (result == BROTLI_RESULT_NEEDS_MORE_INPUT) { + if (s->ringbuffer != 0) { /* Proactively push output. */ + WriteRingBuffer(available_out, next_out, total_out, s); + } + if (s->buffer_length != 0) { /* Used with internal buffer. */ + if (br->avail_in == 0) { /* Successfully finished read transaction. */ + /* Accamulator contains less than 8 bits, because internal buffer + is expanded byte-by-byte until it is enough to complete read. */ + s->buffer_length = 0; + /* Switch to input stream and restart. */ + result = BROTLI_RESULT_SUCCESS; + br->avail_in = *available_in; + br->next_in = *next_in; + continue; + } else if (*available_in != 0) { + /* Not enough data in buffer, but can take one more byte from + input stream. */ + result = BROTLI_RESULT_SUCCESS; + s->buffer.u8[s->buffer_length] = **next_in; + s->buffer_length++; + br->avail_in = s->buffer_length; + (*next_in)++; + (*available_in)--; + /* Retry with more data in buffer. */ + continue; + } + /* Can't finish reading and no more input.*/ + break; + } else { /* Input stream doesn't contain enough input. */ + /* Copy tail to internal buffer and return. */ + *next_in = br->next_in; + *available_in = br->avail_in; + while (*available_in) { + s->buffer.u8[s->buffer_length] = **next_in; + s->buffer_length++; + (*next_in)++; + (*available_in)--; + } + break; + } + /* Unreachable. */ + } + + /* Fail or needs more output. */ + + if (s->buffer_length != 0) { + /* Just consumed the buffered input and produced some output. Otherwise + it would result in "needs more input". Reset internal buffer.*/ + s->buffer_length = 0; + } else { + /* Using input stream in last iteration. When decoder switches to input + stream it has less than 8 bits in accamulator, so it is safe to + return unused accamulator bits there. */ + BrotliBitReaderUnload(br); + *available_in = br->avail_in; + *next_in = br->next_in; + } + break; + } + switch (s->state) { + case BROTLI_STATE_UNINITED: + /* Prepare to the first read. */ + if (!BrotliWarmupBitReader(br)) { + result = BROTLI_RESULT_NEEDS_MORE_INPUT; + break; + } + /* Decode window size. */ + s->window_bits = DecodeWindowBits(br); /* Reads 1..7 bits. */ + BROTLI_LOG_UINT(s->window_bits); + if (s->window_bits == 9) { + /* Value 9 is reserved for future use. */ + result = BROTLI_FAILURE(); + break; + } + s->max_backward_distance = (1 << s->window_bits) - 16; + s->max_backward_distance_minus_custom_dict_size = + s->max_backward_distance - s->custom_dict_size; + + /* Allocate memory for both block_type_trees and block_len_trees. */ + s->block_type_trees = (HuffmanCode*)BROTLI_ALLOC(s, + sizeof(HuffmanCode) * 3 * + (BROTLI_HUFFMAN_MAX_SIZE_258 + BROTLI_HUFFMAN_MAX_SIZE_26)); + if (s->block_type_trees == 0) { + result = BROTLI_FAILURE(); + break; + } + s->block_len_trees = + s->block_type_trees + 3 * BROTLI_HUFFMAN_MAX_SIZE_258; + + s->state = BROTLI_STATE_METABLOCK_BEGIN; + /* No break, continue to next state */ + case BROTLI_STATE_METABLOCK_BEGIN: + BrotliStateMetablockBegin(s); + BROTLI_LOG_UINT(s->pos); + s->state = BROTLI_STATE_METABLOCK_HEADER; + /* No break, continue to next state */ + case BROTLI_STATE_METABLOCK_HEADER: + result = DecodeMetaBlockLength(s, br); /* Reads 2 - 31 bits. */ + if (result != BROTLI_RESULT_SUCCESS) { + break; + } + BROTLI_LOG_UINT(s->is_last_metablock); + BROTLI_LOG_UINT(s->meta_block_remaining_len); + BROTLI_LOG_UINT(s->is_metadata); + BROTLI_LOG_UINT(s->is_uncompressed); + if (s->is_metadata || s->is_uncompressed) { + if (!BrotliJumpToByteBoundary(br)) { + result = BROTLI_FAILURE(); + break; + } + } + if (s->is_metadata) { + s->state = BROTLI_STATE_METADATA; + break; + } + if (s->meta_block_remaining_len == 0) { + s->state = BROTLI_STATE_METABLOCK_DONE; + break; + } + if (!s->ringbuffer) { + BrotliCalculateRingBufferSize(s, br); + } + if (s->is_uncompressed) { + s->state = BROTLI_STATE_UNCOMPRESSED; + break; + } + s->loop_counter = 0; + s->state = BROTLI_STATE_HUFFMAN_CODE_0; + break; + case BROTLI_STATE_UNCOMPRESSED: { + int bytes_copied = s->meta_block_remaining_len; + result = CopyUncompressedBlockToOutput( + available_out, next_out, total_out, s); + bytes_copied -= s->meta_block_remaining_len; + if (result != BROTLI_RESULT_SUCCESS) { + break; + } + s->state = BROTLI_STATE_METABLOCK_DONE; + break; + } + case BROTLI_STATE_METADATA: + for (; s->meta_block_remaining_len > 0; --s->meta_block_remaining_len) { + uint32_t bits; + /* Read one byte and ignore it. */ + if (!BrotliSafeReadBits(br, 8, &bits)) { + result = BROTLI_RESULT_NEEDS_MORE_INPUT; + break; + } + } + if (result == BROTLI_RESULT_SUCCESS) { + s->state = BROTLI_STATE_METABLOCK_DONE; + } + break; + case BROTLI_STATE_HUFFMAN_CODE_0: + if (s->loop_counter >= 3) { + s->state = BROTLI_STATE_METABLOCK_HEADER_2; + break; + } + /* Reads 1..11 bits. */ + result = DecodeVarLenUint8(s, br, &s->num_block_types[s->loop_counter]); + if (result != BROTLI_RESULT_SUCCESS) { + break; + } + s->num_block_types[s->loop_counter]++; + BROTLI_LOG_UINT(s->num_block_types[s->loop_counter]); + if (s->num_block_types[s->loop_counter] < 2) { + s->loop_counter++; + break; + } + s->state = BROTLI_STATE_HUFFMAN_CODE_1; + /* No break, continue to next state */ + case BROTLI_STATE_HUFFMAN_CODE_1: { + int tree_offset = s->loop_counter * BROTLI_HUFFMAN_MAX_SIZE_258; + result = ReadHuffmanCode(s->num_block_types[s->loop_counter] + 2, + &s->block_type_trees[tree_offset], NULL, s); + if (result != BROTLI_RESULT_SUCCESS) break; + s->state = BROTLI_STATE_HUFFMAN_CODE_2; + /* No break, continue to next state */ + } + case BROTLI_STATE_HUFFMAN_CODE_2: { + int tree_offset = s->loop_counter * BROTLI_HUFFMAN_MAX_SIZE_26; + result = ReadHuffmanCode(kNumBlockLengthCodes, + &s->block_len_trees[tree_offset], NULL, s); + if (result != BROTLI_RESULT_SUCCESS) break; + s->state = BROTLI_STATE_HUFFMAN_CODE_3; + /* No break, continue to next state */ + } + case BROTLI_STATE_HUFFMAN_CODE_3: { + int tree_offset = s->loop_counter * BROTLI_HUFFMAN_MAX_SIZE_26; + if (!SafeReadBlockLength(s, &s->block_length[s->loop_counter], + &s->block_len_trees[tree_offset], br)) { + result = BROTLI_RESULT_NEEDS_MORE_INPUT; + break; + } + BROTLI_LOG_UINT(s->block_length[s->loop_counter]); + s->loop_counter++; + s->state = BROTLI_STATE_HUFFMAN_CODE_0; + break; + } + case BROTLI_STATE_METABLOCK_HEADER_2: { + uint32_t bits; + if (!BrotliSafeReadBits(br, 6, &bits)) { + result = BROTLI_RESULT_NEEDS_MORE_INPUT; + break; + } + s->distance_postfix_bits = bits & BitMask(2); + bits >>= 2; + s->num_direct_distance_codes = + NUM_DISTANCE_SHORT_CODES + (bits << s->distance_postfix_bits); + BROTLI_LOG_UINT(s->num_direct_distance_codes); + BROTLI_LOG_UINT(s->distance_postfix_bits); + s->distance_postfix_mask = (int)BitMask(s->distance_postfix_bits); + s->context_modes = + (uint8_t*)BROTLI_ALLOC(s, (size_t)s->num_block_types[0]); + if (s->context_modes == 0) { + result = BROTLI_FAILURE(); + break; + } + s->loop_counter = 0; + s->state = BROTLI_STATE_CONTEXT_MODES; + /* No break, continue to next state */ + } + case BROTLI_STATE_CONTEXT_MODES: + result = ReadContextModes(s); + if (result != BROTLI_RESULT_SUCCESS) { + break; + } + s->state = BROTLI_STATE_CONTEXT_MAP_1; + /* No break, continue to next state */ + case BROTLI_STATE_CONTEXT_MAP_1: { + uint32_t j; + result = DecodeContextMap(s->num_block_types[0] << kLiteralContextBits, + &s->num_literal_htrees, &s->context_map, s); + if (result != BROTLI_RESULT_SUCCESS) { + break; + } + s->trivial_literal_context = 1; + for (j = 0; j < s->num_block_types[0] << kLiteralContextBits; j++) { + if (s->context_map[j] != j >> kLiteralContextBits) { + s->trivial_literal_context = 0; + break; + } + } + s->state = BROTLI_STATE_CONTEXT_MAP_2; + /* No break, continue to next state */ + } + case BROTLI_STATE_CONTEXT_MAP_2: + { + uint32_t num_distance_codes = + s->num_direct_distance_codes + (48U << s->distance_postfix_bits); + result = DecodeContextMap( + s->num_block_types[2] << kDistanceContextBits, + &s->num_dist_htrees, &s->dist_context_map, s); + if (result != BROTLI_RESULT_SUCCESS) { + break; + } + BrotliHuffmanTreeGroupInit(s, &s->literal_hgroup, kNumLiteralCodes, + s->num_literal_htrees); + BrotliHuffmanTreeGroupInit(s, &s->insert_copy_hgroup, + kNumInsertAndCopyCodes, + s->num_block_types[1]); + BrotliHuffmanTreeGroupInit(s, &s->distance_hgroup, num_distance_codes, + s->num_dist_htrees); + if (s->literal_hgroup.codes == 0 || + s->insert_copy_hgroup.codes == 0 || + s->distance_hgroup.codes == 0) { + return BROTLI_FAILURE(); + } + } + s->loop_counter = 0; + s->state = BROTLI_STATE_TREE_GROUP; + /* No break, continue to next state */ + case BROTLI_STATE_TREE_GROUP: + { + HuffmanTreeGroup* hgroup = NULL; + switch (s->loop_counter) { + case 0: + hgroup = &s->literal_hgroup; + break; + case 1: + hgroup = &s->insert_copy_hgroup; + break; + case 2: + hgroup = &s->distance_hgroup; + break; + default: + return BROTLI_FAILURE(); + } + result = HuffmanTreeGroupDecode(hgroup, s); + } + if (result != BROTLI_RESULT_SUCCESS) break; + s->loop_counter++; + if (s->loop_counter >= 3) { + uint8_t context_mode = s->context_modes[s->block_type_rb[1]]; + s->context_map_slice = s->context_map; + s->dist_context_map_slice = s->dist_context_map; + s->context_lookup1 = + &kContextLookup[kContextLookupOffsets[context_mode]]; + s->context_lookup2 = + &kContextLookup[kContextLookupOffsets[context_mode + 1]]; + s->htree_command = s->insert_copy_hgroup.htrees[0]; + s->literal_htree = s->literal_hgroup.htrees[s->literal_htree_index]; + if (!s->ringbuffer && !BrotliAllocateRingBuffer(s)) { + result = BROTLI_FAILURE(); + break; + } + s->state = BROTLI_STATE_COMMAND_BEGIN; + } + break; + case BROTLI_STATE_COMMAND_BEGIN: + case BROTLI_STATE_COMMAND_INNER: + case BROTLI_STATE_COMMAND_POST_DECODE_LITERALS: + case BROTLI_STATE_COMMAND_POST_WRAP_COPY: + result = ProcessCommands(s); + if (result == BROTLI_RESULT_NEEDS_MORE_INPUT) { + result = SafeProcessCommands(s); + } + break; + case BROTLI_STATE_COMMAND_INNER_WRITE: + case BROTLI_STATE_COMMAND_POST_WRITE_1: + case BROTLI_STATE_COMMAND_POST_WRITE_2: + result = WriteRingBuffer(available_out, next_out, total_out, s); + if (result != BROTLI_RESULT_SUCCESS) { + break; + } + s->pos -= s->ringbuffer_size; + s->rb_roundtrips++; + s->max_distance = s->max_backward_distance; + if (s->state == BROTLI_STATE_COMMAND_POST_WRITE_1) { + memcpy(s->ringbuffer, s->ringbuffer_end, (size_t)s->pos); + if (s->meta_block_remaining_len == 0) { + /* Next metablock, if any */ + s->state = BROTLI_STATE_METABLOCK_DONE; + } else { + s->state = BROTLI_STATE_COMMAND_BEGIN; + } + break; + } else if (s->state == BROTLI_STATE_COMMAND_POST_WRITE_2) { + s->state = BROTLI_STATE_COMMAND_POST_WRAP_COPY; + } else { /* BROTLI_STATE_COMMAND_INNER_WRITE */ + if (s->loop_counter == 0) { + if (s->meta_block_remaining_len == 0) { + s->state = BROTLI_STATE_METABLOCK_DONE; + } else { + s->state = BROTLI_STATE_COMMAND_POST_DECODE_LITERALS; + } + break; + } + s->state = BROTLI_STATE_COMMAND_INNER; + } + break; + case BROTLI_STATE_METABLOCK_DONE: + BrotliStateCleanupAfterMetablock(s); + if (!s->is_last_metablock) { + s->state = BROTLI_STATE_METABLOCK_BEGIN; + break; + } + if (!BrotliJumpToByteBoundary(br)) { + result = BROTLI_FAILURE(); + } + if (s->buffer_length == 0) { + BrotliBitReaderUnload(br); + *available_in = br->avail_in; + *next_in = br->next_in; + } + s->state = BROTLI_STATE_DONE; + /* No break, continue to next state */ + case BROTLI_STATE_DONE: + if (s->ringbuffer != 0) { + result = WriteRingBuffer(available_out, next_out, total_out, s); + if (result != BROTLI_RESULT_SUCCESS) { + break; + } + } + return result; + } + } + return result; +} + +void BrotliSetCustomDictionary( + size_t size, const uint8_t* dict, BrotliState* s) { + s->custom_dict = dict; + s->custom_dict_size = (int)size; +} + + +#if defined(__cplusplus) || defined(c_plusplus) +} /* extern "C" */ +#endif diff --git a/web/server/h2o/libh2o/deps/brotli/dec/decode.h b/web/server/h2o/libh2o/deps/brotli/dec/decode.h new file mode 100644 index 00000000..074b2f58 --- /dev/null +++ b/web/server/h2o/libh2o/deps/brotli/dec/decode.h @@ -0,0 +1,96 @@ +/* Copyright 2013 Google Inc. All Rights Reserved. + + Distributed under MIT license. + See file LICENSE for detail or copy at https://opensource.org/licenses/MIT +*/ + +/* API for Brotli decompression */ + +#ifndef BROTLI_DEC_DECODE_H_ +#define BROTLI_DEC_DECODE_H_ + +#include "./state.h" +#include "./types.h" + +#if defined(__cplusplus) || defined(c_plusplus) +extern "C" { +#endif + +typedef enum { + /* Decoding error, e.g. corrupt input or memory allocation problem */ + BROTLI_RESULT_ERROR = 0, + /* Decoding successfully completed */ + BROTLI_RESULT_SUCCESS = 1, + /* Partially done; should be called again with more input */ + BROTLI_RESULT_NEEDS_MORE_INPUT = 2, + /* Partially done; should be called again with more output */ + BROTLI_RESULT_NEEDS_MORE_OUTPUT = 3 +} BrotliResult; + +/* Creates the instance of BrotliState and initializes it. |alloc_func| and + |free_func| MUST be both zero or both non-zero. In the case they are both + zero, default memory allocators are used. |opaque| is passed to |alloc_func| + and |free_func| when they are called. */ +BrotliState* BrotliCreateState( + brotli_alloc_func alloc_func, brotli_free_func free_func, void* opaque); + +/* Deinitializes and frees BrotliState instance. */ +void BrotliDestroyState(BrotliState* state); + +/* Sets |*decoded_size| to the decompressed size of the given encoded stream. + This function only works if the encoded buffer has a single meta block, + or if it has two meta-blocks, where the first is uncompressed and the + second is empty. + Returns 1 on success, 0 on failure. */ +int BrotliDecompressedSize(size_t encoded_size, + const uint8_t* encoded_buffer, + size_t* decoded_size); + +/* Decompresses the data in |encoded_buffer| into |decoded_buffer|, and sets + |*decoded_size| to the decompressed length. */ +BrotliResult BrotliDecompressBuffer(size_t encoded_size, + const uint8_t* encoded_buffer, + size_t* decoded_size, + uint8_t* decoded_buffer); + +/* Decompresses the data. Supports partial input and output. + + Must be called with an allocated input buffer in |*next_in| and an allocated + output buffer in |*next_out|. The values |*available_in| and |*available_out| + must specify the allocated size in |*next_in| and |*next_out| respectively. + + After each call, |*available_in| will be decremented by the amount of input + bytes consumed, and the |*next_in| pointer will be incremented by that + amount. Similarly, |*available_out| will be decremented by the amount of + output bytes written, and the |*next_out| pointer will be incremented by that + amount. |total_out| will be set to the number of bytes decompressed since + last state initialization. + + Input is never overconsumed, so |next_in| and |available_in| could be passed + to the next consumer after decoding is complete. */ +BrotliResult BrotliDecompressStream(size_t* available_in, + const uint8_t** next_in, + size_t* available_out, + uint8_t** next_out, + size_t* total_out, + BrotliState* s); + +/* Fills the new state with a dictionary for LZ77, warming up the ringbuffer, + e.g. for custom static dictionaries for data formats. + Not to be confused with the built-in transformable dictionary of Brotli. + The dictionary must exist in memory until decoding is done and is owned by + the caller. To use: + 1) initialize state with BrotliStateInit + 2) use BrotliSetCustomDictionary + 3) use BrotliDecompressStream + 4) clean up with BrotliStateCleanup +*/ +void BrotliSetCustomDictionary( + size_t size, const uint8_t* dict, BrotliState* s); + + +#if defined(__cplusplus) || defined(c_plusplus) +} /* extern "C" */ +#endif + +#endif /* BROTLI_DEC_DECODE_H_ */ diff --git a/web/server/h2o/libh2o/deps/brotli/dec/dictionary.c b/web/server/h2o/libh2o/deps/brotli/dec/dictionary.c new file mode 100644 index 00000000..f8f58575 --- /dev/null +++ b/web/server/h2o/libh2o/deps/brotli/dec/dictionary.c @@ -0,0 +1,9466 @@ +/* Copyright 2013 Google Inc. All Rights Reserved. + + Distributed under MIT license. + See file LICENSE for detail or copy at https://opensource.org/licenses/MIT +*/ + +#include "./dictionary.h" + +#if defined(__cplusplus) || defined(c_plusplus) +extern "C" { +#endif + +/* In case of multiple definition linker error with dictionary.cc from the + encoder: include only one of enc/dictionary.cc or dec/dictionary.c in a + target using both enc and dec. */ +const uint8_t kBrotliDictionary[122784] = { + 0x74, 0x69, 0x6d, 0x65, 0x64, 0x6f, 0x77, 0x6e, 0x6c, 0x69, 0x66, 0x65, 0x6c, + 0x65, 0x66, 0x74, 0x62, 0x61, 0x63, 0x6b, 0x63, 0x6f, 0x64, 0x65, 0x64, 0x61, + 0x74, 0x61, 0x73, 0x68, 0x6f, 0x77, 0x6f, 0x6e, 0x6c, 0x79, 0x73, 0x69, 0x74, + 0x65, 0x63, 0x69, 0x74, 0x79, 0x6f, 0x70, 0x65, 0x6e, 0x6a, 0x75, 0x73, 0x74, + 0x6c, 0x69, 0x6b, 0x65, 0x66, 0x72, 0x65, 0x65, 0x77, 0x6f, 0x72, 0x6b, 0x74, + 0x65, 0x78, 0x74, 0x79, 0x65, 0x61, 0x72, 0x6f, 0x76, 0x65, 0x72, 0x62, 0x6f, + 0x64, 0x79, 0x6c, 0x6f, 0x76, 0x65, 0x66, 0x6f, 0x72, 0x6d, 0x62, 0x6f, 0x6f, + 0x6b, 0x70, 0x6c, 0x61, 0x79, 0x6c, 0x69, 0x76, 0x65, 0x6c, 0x69, 0x6e, 0x65, + 0x68, 0x65, 0x6c, 0x70, 0x68, 0x6f, 0x6d, 0x65, 0x73, 0x69, 0x64, 0x65, 0x6d, + 0x6f, 0x72, 0x65, 0x77, 0x6f, 0x72, 0x64, 0x6c, 0x6f, 0x6e, 0x67, 0x74, 0x68, + 0x65, 0x6d, 0x76, 0x69, 0x65, 0x77, 0x66, 0x69, 0x6e, 0x64, 0x70, 0x61, 0x67, + 0x65, 0x64, 0x61, 0x79, 0x73, 0x66, 0x75, 0x6c, 0x6c, 0x68, 0x65, 0x61, 0x64, + 0x74, 0x65, 0x72, 0x6d, 0x65, 0x61, 0x63, 0x68, 0x61, 0x72, 0x65, 0x61, 0x66, + 0x72, 0x6f, 0x6d, 0x74, 0x72, 0x75, 0x65, 0x6d, 0x61, 0x72, 0x6b, 0x61, 0x62, + 0x6c, 0x65, 0x75, 0x70, 0x6f, 0x6e, 0x68, 0x69, 0x67, 0x68, 0x64, 0x61, 0x74, + 0x65, 0x6c, 0x61, 0x6e, 0x64, 0x6e, 0x65, 0x77, 0x73, 0x65, 0x76, 0x65, 0x6e, + 0x6e, 0x65, 0x78, 0x74, 0x63, 0x61, 0x73, 0x65, 0x62, 0x6f, 0x74, 0x68, 0x70, + 0x6f, 0x73, 0x74, 0x75, 0x73, 0x65, 0x64, 0x6d, 0x61, 0x64, 0x65, 0x68, 0x61, + 0x6e, 0x64, 0x68, 0x65, 0x72, 0x65, 0x77, 0x68, 0x61, 0x74, 0x6e, 0x61, 0x6d, + 0x65, 0x4c, 0x69, 0x6e, 0x6b, 0x62, 0x6c, 0x6f, 0x67, 0x73, 0x69, 0x7a, 0x65, + 0x62, 0x61, 0x73, 0x65, 0x68, 0x65, 0x6c, 0x64, 0x6d, 0x61, 0x6b, 0x65, 0x6d, + 0x61, 0x69, 0x6e, 0x75, 0x73, 0x65, 0x72, 0x27, 0x29, 0x20, 0x2b, 0x68, 0x6f, + 0x6c, 0x64, 0x65, 0x6e, 0x64, 0x73, 0x77, 0x69, 0x74, 0x68, 0x4e, 0x65, 0x77, + 0x73, 0x72, 0x65, 0x61, 0x64, 0x77, 0x65, 0x72, 0x65, 0x73, 0x69, 0x67, 0x6e, + 0x74, 0x61, 0x6b, 0x65, 0x68, 0x61, 0x76, 0x65, 0x67, 0x61, 0x6d, 0x65, 0x73, + 0x65, 0x65, 0x6e, 0x63, 0x61, 0x6c, 0x6c, 0x70, 0x61, 0x74, 0x68, 0x77, 0x65, + 0x6c, 0x6c, 0x70, 0x6c, 0x75, 0x73, 0x6d, 0x65, 0x6e, 0x75, 0x66, 0x69, 0x6c, + 0x6d, 0x70, 0x61, 0x72, 0x74, 0x6a, 0x6f, 0x69, 0x6e, 0x74, 0x68, 0x69, 0x73, + 0x6c, 0x69, 0x73, 0x74, 0x67, 0x6f, 0x6f, 0x64, 0x6e, 0x65, 0x65, 0x64, 0x77, + 0x61, 0x79, 0x73, 0x77, 0x65, 0x73, 0x74, 0x6a, 0x6f, 0x62, 0x73, 0x6d, 0x69, + 0x6e, 0x64, 0x61, 0x6c, 0x73, 0x6f, 0x6c, 0x6f, 0x67, 0x6f, 0x72, 0x69, 0x63, + 0x68, 0x75, 0x73, 0x65, 0x73, 0x6c, 0x61, 0x73, 0x74, 0x74, 0x65, 0x61, 0x6d, + 0x61, 0x72, 0x6d, 0x79, 0x66, 0x6f, 0x6f, 0x64, 0x6b, 0x69, 0x6e, 0x67, 0x77, + 0x69, 0x6c, 0x6c, 0x65, 0x61, 0x73, 0x74, 0x77, 0x61, 0x72, 0x64, 0x62, 0x65, + 0x73, 0x74, 0x66, 0x69, 0x72, 0x65, 0x50, 0x61, 0x67, 0x65, 0x6b, 0x6e, 0x6f, + 0x77, 0x61, 0x77, 0x61, 0x79, 0x2e, 0x70, 0x6e, 0x67, 0x6d, 0x6f, 0x76, 0x65, + 0x74, 0x68, 0x61, 0x6e, 0x6c, 0x6f, 0x61, 0x64, 0x67, 0x69, 0x76, 0x65, 0x73, + 0x65, 0x6c, 0x66, 0x6e, 0x6f, 0x74, 0x65, 0x6d, 0x75, 0x63, 0x68, 0x66, 0x65, + 0x65, 0x64, 0x6d, 0x61, 0x6e, 0x79, 0x72, 0x6f, 0x63, 0x6b, 0x69, 0x63, 0x6f, + 0x6e, 0x6f, 0x6e, 0x63, 0x65, 0x6c, 0x6f, 0x6f, 0x6b, 0x68, 0x69, 0x64, 0x65, + 0x64, 0x69, 0x65, 0x64, 0x48, 0x6f, 0x6d, 0x65, 0x72, 0x75, 0x6c, 0x65, 0x68, + 0x6f, 0x73, 0x74, 0x61, 0x6a, 0x61, 0x78, 0x69, 0x6e, 0x66, 0x6f, 0x63, 0x6c, + 0x75, 0x62, 0x6c, 0x61, 0x77, 0x73, 0x6c, 0x65, 0x73, 0x73, 0x68, 0x61, 0x6c, + 0x66, 0x73, 0x6f, 0x6d, 0x65, 0x73, 0x75, 0x63, 0x68, 0x7a, 0x6f, 0x6e, 0x65, + 0x31, 0x30, 0x30, 0x25, 0x6f, 0x6e, 0x65, 0x73, 0x63, 0x61, 0x72, 0x65, 0x54, + 0x69, 0x6d, 0x65, 0x72, 0x61, 0x63, 0x65, 0x62, 0x6c, 0x75, 0x65, 0x66, 0x6f, + 0x75, 0x72, 0x77, 0x65, 0x65, 0x6b, 0x66, 0x61, 0x63, 0x65, 0x68, 0x6f, 0x70, + 0x65, 0x67, 0x61, 0x76, 0x65, 0x68, 0x61, 0x72, 0x64, 0x6c, 0x6f, 0x73, 0x74, + 0x77, 0x68, 0x65, 0x6e, 0x70, 0x61, 0x72, 0x6b, 0x6b, 0x65, 0x70, 0x74, 0x70, + 0x61, 0x73, 0x73, 0x73, 0x68, 0x69, 0x70, 0x72, 0x6f, 0x6f, 0x6d, 0x48, 0x54, + 0x4d, 0x4c, 0x70, 0x6c, 0x61, 0x6e, 0x54, 0x79, 0x70, 0x65, 0x64, 0x6f, 0x6e, + 0x65, 0x73, 0x61, 0x76, 0x65, 0x6b, 0x65, 0x65, 0x70, 0x66, 0x6c, 0x61, 0x67, + 0x6c, 0x69, 0x6e, 0x6b, 0x73, 0x6f, 0x6c, 0x64, 0x66, 0x69, 0x76, 0x65, 0x74, + 0x6f, 0x6f, 0x6b, 0x72, 0x61, 0x74, 0x65, 0x74, 0x6f, 0x77, 0x6e, 0x6a, 0x75, + 0x6d, 0x70, 0x74, 0x68, 0x75, 0x73, 0x64, 0x61, 0x72, 0x6b, 0x63, 0x61, 0x72, + 0x64, 0x66, 0x69, 0x6c, 0x65, 0x66, 0x65, 0x61, 0x72, 0x73, 0x74, 0x61, 0x79, + 0x6b, 0x69, 0x6c, 0x6c, 0x74, 0x68, 0x61, 0x74, 0x66, 0x61, 0x6c, 0x6c, 0x61, + 0x75, 0x74, 0x6f, 0x65, 0x76, 0x65, 0x72, 0x2e, 0x63, 0x6f, 0x6d, 0x74, 0x61, + 0x6c, 0x6b, 0x73, 0x68, 0x6f, 0x70, 0x76, 0x6f, 0x74, 0x65, 0x64, 0x65, 0x65, + 0x70, 0x6d, 0x6f, 0x64, 0x65, 0x72, 0x65, 0x73, 0x74, 0x74, 0x75, 0x72, 0x6e, + 0x62, 0x6f, 0x72, 0x6e, 0x62, 0x61, 0x6e, 0x64, 0x66, 0x65, 0x6c, 0x6c, 0x72, + 0x6f, 0x73, 0x65, 0x75, 0x72, 0x6c, 0x28, 0x73, 0x6b, 0x69, 0x6e, 0x72, 0x6f, + 0x6c, 0x65, 0x63, 0x6f, 0x6d, 0x65, 0x61, 0x63, 0x74, 0x73, 0x61, 0x67, 0x65, + 0x73, 0x6d, 0x65, 0x65, 0x74, 0x67, 0x6f, 0x6c, 0x64, 0x2e, 0x6a, 0x70, 0x67, + 0x69, 0x74, 0x65, 0x6d, 0x76, 0x61, 0x72, 0x79, 0x66, 0x65, 0x6c, 0x74, 0x74, + 0x68, 0x65, 0x6e, 0x73, 0x65, 0x6e, 0x64, 0x64, 0x72, 0x6f, 0x70, 0x56, 0x69, + 0x65, 0x77, 0x63, 0x6f, 0x70, 0x79, 0x31, 0x2e, 0x30, 0x22, 0x3c, 0x2f, 0x61, + 0x3e, 0x73, 0x74, 0x6f, 0x70, 0x65, 0x6c, 0x73, 0x65, 0x6c, 0x69, 0x65, 0x73, + 0x74, 0x6f, 0x75, 0x72, 0x70, 0x61, 0x63, 0x6b, 0x2e, 0x67, 0x69, 0x66, 0x70, + 0x61, 0x73, 0x74, 0x63, 0x73, 0x73, 0x3f, 0x67, 0x72, 0x61, 0x79, 0x6d, 0x65, + 0x61, 0x6e, 0x26, 0x67, 0x74, 0x3b, 0x72, 0x69, 0x64, 0x65, 0x73, 0x68, 0x6f, + 0x74, 0x6c, 0x61, 0x74, 0x65, 0x73, 0x61, 0x69, 0x64, 0x72, 0x6f, 0x61, 0x64, + 0x76, 0x61, 0x72, 0x20, 0x66, 0x65, 0x65, 0x6c, 0x6a, 0x6f, 0x68, 0x6e, 0x72, + 0x69, 0x63, 0x6b, 0x70, 0x6f, 0x72, 0x74, 0x66, 0x61, 0x73, 0x74, 0x27, 0x55, + 0x41, 0x2d, 0x64, 0x65, 0x61, 0x64, 0x3c, 0x2f, 0x62, 0x3e, 0x70, 0x6f, 0x6f, + 0x72, 0x62, 0x69, 0x6c, 0x6c, 0x74, 0x79, 0x70, 0x65, 0x55, 0x2e, 0x53, 0x2e, + 0x77, 0x6f, 0x6f, 0x64, 0x6d, 0x75, 0x73, 0x74, 0x32, 0x70, 0x78, 0x3b, 0x49, + 0x6e, 0x66, 0x6f, 0x72, 0x61, 0x6e, 0x6b, 0x77, 0x69, 0x64, 0x65, 0x77, 0x61, + 0x6e, 0x74, 0x77, 0x61, 0x6c, 0x6c, 0x6c, 0x65, 0x61, 0x64, 0x5b, 0x30, 0x5d, + 0x3b, 0x70, 0x61, 0x75, 0x6c, 0x77, 0x61, 0x76, 0x65, 0x73, 0x75, 0x72, 0x65, + 0x24, 0x28, 0x27, 0x23, 0x77, 0x61, 0x69, 0x74, 0x6d, 0x61, 0x73, 0x73, 0x61, + 0x72, 0x6d, 0x73, 0x67, 0x6f, 0x65, 0x73, 0x67, 0x61, 0x69, 0x6e, 0x6c, 0x61, + 0x6e, 0x67, 0x70, 0x61, 0x69, 0x64, 0x21, 0x2d, 0x2d, 0x20, 0x6c, 0x6f, 0x63, + 0x6b, 0x75, 0x6e, 0x69, 0x74, 0x72, 0x6f, 0x6f, 0x74, 0x77, 0x61, 0x6c, 0x6b, + 0x66, 0x69, 0x72, 0x6d, 0x77, 0x69, 0x66, 0x65, 0x78, 0x6d, 0x6c, 0x22, 0x73, + 0x6f, 0x6e, 0x67, 0x74, 0x65, 0x73, 0x74, 0x32, 0x30, 0x70, 0x78, 0x6b, 0x69, + 0x6e, 0x64, 0x72, 0x6f, 0x77, 0x73, 0x74, 0x6f, 0x6f, 0x6c, 0x66, 0x6f, 0x6e, + 0x74, 0x6d, 0x61, 0x69, 0x6c, 0x73, 0x61, 0x66, 0x65, 0x73, 0x74, 0x61, 0x72, + 0x6d, 0x61, 0x70, 0x73, 0x63, 0x6f, 0x72, 0x65, 0x72, 0x61, 0x69, 0x6e, 0x66, + 0x6c, 0x6f, 0x77, 0x62, 0x61, 0x62, 0x79, 0x73, 0x70, 0x61, 0x6e, 0x73, 0x61, + 0x79, 0x73, 0x34, 0x70, 0x78, 0x3b, 0x36, 0x70, 0x78, 0x3b, 0x61, 0x72, 0x74, + 0x73, 0x66, 0x6f, 0x6f, 0x74, 0x72, 0x65, 0x61, 0x6c, 0x77, 0x69, 0x6b, 0x69, + 0x68, 0x65, 0x61, 0x74, 0x73, 0x74, 0x65, 0x70, 0x74, 0x72, 0x69, 0x70, 0x6f, + 0x72, 0x67, 0x2f, 0x6c, 0x61, 0x6b, 0x65, 0x77, 0x65, 0x61, 0x6b, 0x74, 0x6f, + 0x6c, 0x64, 0x46, 0x6f, 0x72, 0x6d, 0x63, 0x61, 0x73, 0x74, 0x66, 0x61, 0x6e, + 0x73, 0x62, 0x61, 0x6e, 0x6b, 0x76, 0x65, 0x72, 0x79, 0x72, 0x75, 0x6e, 0x73, + 0x6a, 0x75, 0x6c, 0x79, 0x74, 0x61, 0x73, 0x6b, 0x31, 0x70, 0x78, 0x3b, 0x67, + 0x6f, 0x61, 0x6c, 0x67, 0x72, 0x65, 0x77, 0x73, 0x6c, 0x6f, 0x77, 0x65, 0x64, + 0x67, 0x65, 0x69, 0x64, 0x3d, 0x22, 0x73, 0x65, 0x74, 0x73, 0x35, 0x70, 0x78, + 0x3b, 0x2e, 0x6a, 0x73, 0x3f, 0x34, 0x30, 0x70, 0x78, 0x69, 0x66, 0x20, 0x28, + 0x73, 0x6f, 0x6f, 0x6e, 0x73, 0x65, 0x61, 0x74, 0x6e, 0x6f, 0x6e, 0x65, 0x74, + 0x75, 0x62, 0x65, 0x7a, 0x65, 0x72, 0x6f, 0x73, 0x65, 0x6e, 0x74, 0x72, 0x65, + 0x65, 0x64, 0x66, 0x61, 0x63, 0x74, 0x69, 0x6e, 0x74, 0x6f, 0x67, 0x69, 0x66, + 0x74, 0x68, 0x61, 0x72, 0x6d, 0x31, 0x38, 0x70, 0x78, 0x63, 0x61, 0x6d, 0x65, + 0x68, 0x69, 0x6c, 0x6c, 0x62, 0x6f, 0x6c, 0x64, 0x7a, 0x6f, 0x6f, 0x6d, 0x76, + 0x6f, 0x69, 0x64, 0x65, 0x61, 0x73, 0x79, 0x72, 0x69, 0x6e, 0x67, 0x66, 0x69, + 0x6c, 0x6c, 0x70, 0x65, 0x61, 0x6b, 0x69, 0x6e, 0x69, 0x74, 0x63, 0x6f, 0x73, + 0x74, 0x33, 0x70, 0x78, 0x3b, 0x6a, 0x61, 0x63, 0x6b, 0x74, 0x61, 0x67, 0x73, + 0x62, 0x69, 0x74, 0x73, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x64, 0x69, 0x74, 0x6b, + 0x6e, 0x65, 0x77, 0x6e, 0x65, 0x61, 0x72, 0x3c, 0x21, 0x2d, 0x2d, 0x67, 0x72, + 0x6f, 0x77, 0x4a, 0x53, 0x4f, 0x4e, 0x64, 0x75, 0x74, 0x79, 0x4e, 0x61, 0x6d, + 0x65, 0x73, 0x61, 0x6c, 0x65, 0x79, 0x6f, 0x75, 0x20, 0x6c, 0x6f, 0x74, 0x73, + 0x70, 0x61, 0x69, 0x6e, 0x6a, 0x61, 0x7a, 0x7a, 0x63, 0x6f, 0x6c, 0x64, 0x65, + 0x79, 0x65, 0x73, 0x66, 0x69, 0x73, 0x68, 0x77, 0x77, 0x77, 0x2e, 0x72, 0x69, + 0x73, 0x6b, 0x74, 0x61, 0x62, 0x73, 0x70, 0x72, 0x65, 0x76, 0x31, 0x30, 0x70, + 0x78, 0x72, 0x69, 0x73, 0x65, 0x32, 0x35, 0x70, 0x78, 0x42, 0x6c, 0x75, 0x65, + 0x64, 0x69, 0x6e, 0x67, 0x33, 0x30, 0x30, 0x2c, 0x62, 0x61, 0x6c, 0x6c, 0x66, + 0x6f, 0x72, 0x64, 0x65, 0x61, 0x72, 0x6e, 0x77, 0x69, 0x6c, 0x64, 0x62, 0x6f, + 0x78, 0x2e, 0x66, 0x61, 0x69, 0x72, 0x6c, 0x61, 0x63, 0x6b, 0x76, 0x65, 0x72, + 0x73, 0x70, 0x61, 0x69, 0x72, 0x6a, 0x75, 0x6e, 0x65, 0x74, 0x65, 0x63, 0x68, + 0x69, 0x66, 0x28, 0x21, 0x70, 0x69, 0x63, 0x6b, 0x65, 0x76, 0x69, 0x6c, 0x24, + 0x28, 0x22, 0x23, 0x77, 0x61, 0x72, 0x6d, 0x6c, 0x6f, 0x72, 0x64, 0x64, 0x6f, + 0x65, 0x73, 0x70, 0x75, 0x6c, 0x6c, 0x2c, 0x30, 0x30, 0x30, 0x69, 0x64, 0x65, + 0x61, 0x64, 0x72, 0x61, 0x77, 0x68, 0x75, 0x67, 0x65, 0x73, 0x70, 0x6f, 0x74, + 0x66, 0x75, 0x6e, 0x64, 0x62, 0x75, 0x72, 0x6e, 0x68, 0x72, 0x65, 0x66, 0x63, + 0x65, 0x6c, 0x6c, 0x6b, 0x65, 0x79, 0x73, 0x74, 0x69, 0x63, 0x6b, 0x68, 0x6f, + 0x75, 0x72, 0x6c, 0x6f, 0x73, 0x73, 0x66, 0x75, 0x65, 0x6c, 0x31, 0x32, 0x70, + 0x78, 0x73, 0x75, 0x69, 0x74, 0x64, 0x65, 0x61, 0x6c, 0x52, 0x53, 0x53, 0x22, + 0x61, 0x67, 0x65, 0x64, 0x67, 0x72, 0x65, 0x79, 0x47, 0x45, 0x54, 0x22, 0x65, + 0x61, 0x73, 0x65, 0x61, 0x69, 0x6d, 0x73, 0x67, 0x69, 0x72, 0x6c, 0x61, 0x69, + 0x64, 0x73, 0x38, 0x70, 0x78, 0x3b, 0x6e, 0x61, 0x76, 0x79, 0x67, 0x72, 0x69, + 0x64, 0x74, 0x69, 0x70, 0x73, 0x23, 0x39, 0x39, 0x39, 0x77, 0x61, 0x72, 0x73, + 0x6c, 0x61, 0x64, 0x79, 0x63, 0x61, 0x72, 0x73, 0x29, 0x3b, 0x20, 0x7d, 0x70, + 0x68, 0x70, 0x3f, 0x68, 0x65, 0x6c, 0x6c, 0x74, 0x61, 0x6c, 0x6c, 0x77, 0x68, + 0x6f, 0x6d, 0x7a, 0x68, 0x3a, 0xe5, 0x2a, 0x2f, 0x0d, 0x0a, 0x20, 0x31, 0x30, + 0x30, 0x68, 0x61, 0x6c, 0x6c, 0x2e, 0x0a, 0x0a, 0x41, 0x37, 0x70, 0x78, 0x3b, + 0x70, 0x75, 0x73, 0x68, 0x63, 0x68, 0x61, 0x74, 0x30, 0x70, 0x78, 0x3b, 0x63, + 0x72, 0x65, 0x77, 0x2a, 0x2f, 0x3c, 0x2f, 0x68, 0x61, 0x73, 0x68, 0x37, 0x35, + 0x70, 0x78, 0x66, 0x6c, 0x61, 0x74, 0x72, 0x61, 0x72, 0x65, 0x20, 0x26, 0x26, + 0x20, 0x74, 0x65, 0x6c, 0x6c, 0x63, 0x61, 0x6d, 0x70, 0x6f, 0x6e, 0x74, 0x6f, + 0x6c, 0x61, 0x69, 0x64, 0x6d, 0x69, 0x73, 0x73, 0x73, 0x6b, 0x69, 0x70, 0x74, + 0x65, 0x6e, 0x74, 0x66, 0x69, 0x6e, 0x65, 0x6d, 0x61, 0x6c, 0x65, 0x67, 0x65, + 0x74, 0x73, 0x70, 0x6c, 0x6f, 0x74, 0x34, 0x30, 0x30, 0x2c, 0x0d, 0x0a, 0x0d, + 0x0a, 0x63, 0x6f, 0x6f, 0x6c, 0x66, 0x65, 0x65, 0x74, 0x2e, 0x70, 0x68, 0x70, + 0x3c, 0x62, 0x72, 0x3e, 0x65, 0x72, 0x69, 0x63, 0x6d, 0x6f, 0x73, 0x74, 0x67, + 0x75, 0x69, 0x64, 0x62, 0x65, 0x6c, 0x6c, 0x64, 0x65, 0x73, 0x63, 0x68, 0x61, + 0x69, 0x72, 0x6d, 0x61, 0x74, 0x68, 0x61, 0x74, 0x6f, 0x6d, 0x2f, 0x69, 0x6d, + 0x67, 0x26, 0x23, 0x38, 0x32, 0x6c, 0x75, 0x63, 0x6b, 0x63, 0x65, 0x6e, 0x74, + 0x30, 0x30, 0x30, 0x3b, 0x74, 0x69, 0x6e, 0x79, 0x67, 0x6f, 0x6e, 0x65, 0x68, + 0x74, 0x6d, 0x6c, 0x73, 0x65, 0x6c, 0x6c, 0x64, 0x72, 0x75, 0x67, 0x46, 0x52, + 0x45, 0x45, 0x6e, 0x6f, 0x64, 0x65, 0x6e, 0x69, 0x63, 0x6b, 0x3f, 0x69, 0x64, + 0x3d, 0x6c, 0x6f, 0x73, 0x65, 0x6e, 0x75, 0x6c, 0x6c, 0x76, 0x61, 0x73, 0x74, + 0x77, 0x69, 0x6e, 0x64, 0x52, 0x53, 0x53, 0x20, 0x77, 0x65, 0x61, 0x72, 0x72, + 0x65, 0x6c, 0x79, 0x62, 0x65, 0x65, 0x6e, 0x73, 0x61, 0x6d, 0x65, 0x64, 0x75, + 0x6b, 0x65, 0x6e, 0x61, 0x73, 0x61, 0x63, 0x61, 0x70, 0x65, 0x77, 0x69, 0x73, + 0x68, 0x67, 0x75, 0x6c, 0x66, 0x54, 0x32, 0x33, 0x3a, 0x68, 0x69, 0x74, 0x73, + 0x73, 0x6c, 0x6f, 0x74, 0x67, 0x61, 0x74, 0x65, 0x6b, 0x69, 0x63, 0x6b, 0x62, + 0x6c, 0x75, 0x72, 0x74, 0x68, 0x65, 0x79, 0x31, 0x35, 0x70, 0x78, 0x27, 0x27, + 0x29, 0x3b, 0x29, 0x3b, 0x22, 0x3e, 0x6d, 0x73, 0x69, 0x65, 0x77, 0x69, 0x6e, + 0x73, 0x62, 0x69, 0x72, 0x64, 0x73, 0x6f, 0x72, 0x74, 0x62, 0x65, 0x74, 0x61, + 0x73, 0x65, 0x65, 0x6b, 0x54, 0x31, 0x38, 0x3a, 0x6f, 0x72, 0x64, 0x73, 0x74, + 0x72, 0x65, 0x65, 0x6d, 0x61, 0x6c, 0x6c, 0x36, 0x30, 0x70, 0x78, 0x66, 0x61, + 0x72, 0x6d, 0xe2, 0x80, 0x99, 0x73, 0x62, 0x6f, 0x79, 0x73, 0x5b, 0x30, 0x5d, + 0x2e, 0x27, 0x29, 0x3b, 0x22, 0x50, 0x4f, 0x53, 0x54, 0x62, 0x65, 0x61, 0x72, + 0x6b, 0x69, 0x64, 0x73, 0x29, 0x3b, 0x7d, 0x7d, 0x6d, 0x61, 0x72, 0x79, 0x74, + 0x65, 0x6e, 0x64, 0x28, 0x55, 0x4b, 0x29, 0x71, 0x75, 0x61, 0x64, 0x7a, 0x68, + 0x3a, 0xe6, 0x2d, 0x73, 0x69, 0x7a, 0x2d, 0x2d, 0x2d, 0x2d, 0x70, 0x72, 0x6f, + 0x70, 0x27, 0x29, 0x3b, 0x0d, 0x6c, 0x69, 0x66, 0x74, 0x54, 0x31, 0x39, 0x3a, + 0x76, 0x69, 0x63, 0x65, 0x61, 0x6e, 0x64, 0x79, 0x64, 0x65, 0x62, 0x74, 0x3e, + 0x52, 0x53, 0x53, 0x70, 0x6f, 0x6f, 0x6c, 0x6e, 0x65, 0x63, 0x6b, 0x62, 0x6c, + 0x6f, 0x77, 0x54, 0x31, 0x36, 0x3a, 0x64, 0x6f, 0x6f, 0x72, 0x65, 0x76, 0x61, + 0x6c, 0x54, 0x31, 0x37, 0x3a, 0x6c, 0x65, 0x74, 0x73, 0x66, 0x61, 0x69, 0x6c, + 0x6f, 0x72, 0x61, 0x6c, 0x70, 0x6f, 0x6c, 0x6c, 0x6e, 0x6f, 0x76, 0x61, 0x63, + 0x6f, 0x6c, 0x73, 0x67, 0x65, 0x6e, 0x65, 0x20, 0xe2, 0x80, 0x94, 0x73, 0x6f, + 0x66, 0x74, 0x72, 0x6f, 0x6d, 0x65, 0x74, 0x69, 0x6c, 0x6c, 0x72, 0x6f, 0x73, + 0x73, 0x3c, 0x68, 0x33, 0x3e, 0x70, 0x6f, 0x75, 0x72, 0x66, 0x61, 0x64, 0x65, + 0x70, 0x69, 0x6e, 0x6b, 0x3c, 0x74, 0x72, 0x3e, 0x6d, 0x69, 0x6e, 0x69, 0x29, + 0x7c, 0x21, 0x28, 0x6d, 0x69, 0x6e, 0x65, 0x7a, 0x68, 0x3a, 0xe8, 0x62, 0x61, + 0x72, 0x73, 0x68, 0x65, 0x61, 0x72, 0x30, 0x30, 0x29, 0x3b, 0x6d, 0x69, 0x6c, + 0x6b, 0x20, 0x2d, 0x2d, 0x3e, 0x69, 0x72, 0x6f, 0x6e, 0x66, 0x72, 0x65, 0x64, + 0x64, 0x69, 0x73, 0x6b, 0x77, 0x65, 0x6e, 0x74, 0x73, 0x6f, 0x69, 0x6c, 0x70, + 0x75, 0x74, 0x73, 0x2f, 0x6a, 0x73, 0x2f, 0x68, 0x6f, 0x6c, 0x79, 0x54, 0x32, + 0x32, 0x3a, 0x49, 0x53, 0x42, 0x4e, 0x54, 0x32, 0x30, 0x3a, 0x61, 0x64, 0x61, + 0x6d, 0x73, 0x65, 0x65, 0x73, 0x3c, 0x68, 0x32, 0x3e, 0x6a, 0x73, 0x6f, 0x6e, + 0x27, 0x2c, 0x20, 0x27, 0x63, 0x6f, 0x6e, 0x74, 0x54, 0x32, 0x31, 0x3a, 0x20, + 0x52, 0x53, 0x53, 0x6c, 0x6f, 0x6f, 0x70, 0x61, 0x73, 0x69, 0x61, 0x6d, 0x6f, + 0x6f, 0x6e, 0x3c, 0x2f, 0x70, 0x3e, 0x73, 0x6f, 0x75, 0x6c, 0x4c, 0x49, 0x4e, + 0x45, 0x66, 0x6f, 0x72, 0x74, 0x63, 0x61, 0x72, 0x74, 0x54, 0x31, 0x34, 0x3a, + 0x3c, 0x68, 0x31, 0x3e, 0x38, 0x30, 0x70, 0x78, 0x21, 0x2d, 0x2d, 0x3c, 0x39, + 0x70, 0x78, 0x3b, 0x54, 0x30, 0x34, 0x3a, 0x6d, 0x69, 0x6b, 0x65, 0x3a, 0x34, + 0x36, 0x5a, 0x6e, 0x69, 0x63, 0x65, 0x69, 0x6e, 0x63, 0x68, 0x59, 0x6f, 0x72, + 0x6b, 0x72, 0x69, 0x63, 0x65, 0x7a, 0x68, 0x3a, 0xe4, 0x27, 0x29, 0x29, 0x3b, + 0x70, 0x75, 0x72, 0x65, 0x6d, 0x61, 0x67, 0x65, 0x70, 0x61, 0x72, 0x61, 0x74, + 0x6f, 0x6e, 0x65, 0x62, 0x6f, 0x6e, 0x64, 0x3a, 0x33, 0x37, 0x5a, 0x5f, 0x6f, + 0x66, 0x5f, 0x27, 0x5d, 0x29, 0x3b, 0x30, 0x30, 0x30, 0x2c, 0x7a, 0x68, 0x3a, + 0xe7, 0x74, 0x61, 0x6e, 0x6b, 0x79, 0x61, 0x72, 0x64, 0x62, 0x6f, 0x77, 0x6c, + 0x62, 0x75, 0x73, 0x68, 0x3a, 0x35, 0x36, 0x5a, 0x4a, 0x61, 0x76, 0x61, 0x33, + 0x30, 0x70, 0x78, 0x0a, 0x7c, 0x7d, 0x0a, 0x25, 0x43, 0x33, 0x25, 0x3a, 0x33, + 0x34, 0x5a, 0x6a, 0x65, 0x66, 0x66, 0x45, 0x58, 0x50, 0x49, 0x63, 0x61, 0x73, + 0x68, 0x76, 0x69, 0x73, 0x61, 0x67, 0x6f, 0x6c, 0x66, 0x73, 0x6e, 0x6f, 0x77, + 0x7a, 0x68, 0x3a, 0xe9, 0x71, 0x75, 0x65, 0x72, 0x2e, 0x63, 0x73, 0x73, 0x73, + 0x69, 0x63, 0x6b, 0x6d, 0x65, 0x61, 0x74, 0x6d, 0x69, 0x6e, 0x2e, 0x62, 0x69, + 0x6e, 0x64, 0x64, 0x65, 0x6c, 0x6c, 0x68, 0x69, 0x72, 0x65, 0x70, 0x69, 0x63, + 0x73, 0x72, 0x65, 0x6e, 0x74, 0x3a, 0x33, 0x36, 0x5a, 0x48, 0x54, 0x54, 0x50, + 0x2d, 0x32, 0x30, 0x31, 0x66, 0x6f, 0x74, 0x6f, 0x77, 0x6f, 0x6c, 0x66, 0x45, + 0x4e, 0x44, 0x20, 0x78, 0x62, 0x6f, 0x78, 0x3a, 0x35, 0x34, 0x5a, 0x42, 0x4f, + 0x44, 0x59, 0x64, 0x69, 0x63, 0x6b, 0x3b, 0x0a, 0x7d, 0x0a, 0x65, 0x78, 0x69, + 0x74, 0x3a, 0x33, 0x35, 0x5a, 0x76, 0x61, 0x72, 0x73, 0x62, 0x65, 0x61, 0x74, + 0x27, 0x7d, 0x29, 0x3b, 0x64, 0x69, 0x65, 0x74, 0x39, 0x39, 0x39, 0x3b, 0x61, + 0x6e, 0x6e, 0x65, 0x7d, 0x7d, 0x3c, 0x2f, 0x5b, 0x69, 0x5d, 0x2e, 0x4c, 0x61, + 0x6e, 0x67, 0x6b, 0x6d, 0xc2, 0xb2, 0x77, 0x69, 0x72, 0x65, 0x74, 0x6f, 0x79, + 0x73, 0x61, 0x64, 0x64, 0x73, 0x73, 0x65, 0x61, 0x6c, 0x61, 0x6c, 0x65, 0x78, + 0x3b, 0x0a, 0x09, 0x7d, 0x65, 0x63, 0x68, 0x6f, 0x6e, 0x69, 0x6e, 0x65, 0x2e, + 0x6f, 0x72, 0x67, 0x30, 0x30, 0x35, 0x29, 0x74, 0x6f, 0x6e, 0x79, 0x6a, 0x65, + 0x77, 0x73, 0x73, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x67, 0x73, 0x72, 0x6f, 0x6f, + 0x66, 0x30, 0x30, 0x30, 0x29, 0x20, 0x32, 0x30, 0x30, 0x77, 0x69, 0x6e, 0x65, + 0x67, 0x65, 0x61, 0x72, 0x64, 0x6f, 0x67, 0x73, 0x62, 0x6f, 0x6f, 0x74, 0x67, + 0x61, 0x72, 0x79, 0x63, 0x75, 0x74, 0x73, 0x74, 0x79, 0x6c, 0x65, 0x74, 0x65, + 0x6d, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x78, 0x6d, 0x6c, 0x63, 0x6f, 0x63, + 0x6b, 0x67, 0x61, 0x6e, 0x67, 0x24, 0x28, 0x27, 0x2e, 0x35, 0x30, 0x70, 0x78, + 0x50, 0x68, 0x2e, 0x44, 0x6d, 0x69, 0x73, 0x63, 0x61, 0x6c, 0x61, 0x6e, 0x6c, + 0x6f, 0x61, 0x6e, 0x64, 0x65, 0x73, 0x6b, 0x6d, 0x69, 0x6c, 0x65, 0x72, 0x79, + 0x61, 0x6e, 0x75, 0x6e, 0x69, 0x78, 0x64, 0x69, 0x73, 0x63, 0x29, 0x3b, 0x7d, + 0x0a, 0x64, 0x75, 0x73, 0x74, 0x63, 0x6c, 0x69, 0x70, 0x29, 0x2e, 0x0a, 0x0a, + 0x37, 0x30, 0x70, 0x78, 0x2d, 0x32, 0x30, 0x30, 0x44, 0x56, 0x44, 0x73, 0x37, + 0x5d, 0x3e, 0x3c, 0x74, 0x61, 0x70, 0x65, 0x64, 0x65, 0x6d, 0x6f, 0x69, 0x2b, + 0x2b, 0x29, 0x77, 0x61, 0x67, 0x65, 0x65, 0x75, 0x72, 0x6f, 0x70, 0x68, 0x69, + 0x6c, 0x6f, 0x70, 0x74, 0x73, 0x68, 0x6f, 0x6c, 0x65, 0x46, 0x41, 0x51, 0x73, + 0x61, 0x73, 0x69, 0x6e, 0x2d, 0x32, 0x36, 0x54, 0x6c, 0x61, 0x62, 0x73, 0x70, + 0x65, 0x74, 0x73, 0x55, 0x52, 0x4c, 0x20, 0x62, 0x75, 0x6c, 0x6b, 0x63, 0x6f, + 0x6f, 0x6b, 0x3b, 0x7d, 0x0d, 0x0a, 0x48, 0x45, 0x41, 0x44, 0x5b, 0x30, 0x5d, + 0x29, 0x61, 0x62, 0x62, 0x72, 0x6a, 0x75, 0x61, 0x6e, 0x28, 0x31, 0x39, 0x38, + 0x6c, 0x65, 0x73, 0x68, 0x74, 0x77, 0x69, 0x6e, 0x3c, 0x2f, 0x69, 0x3e, 0x73, + 0x6f, 0x6e, 0x79, 0x67, 0x75, 0x79, 0x73, 0x66, 0x75, 0x63, 0x6b, 0x70, 0x69, + 0x70, 0x65, 0x7c, 0x2d, 0x0a, 0x21, 0x30, 0x30, 0x32, 0x29, 0x6e, 0x64, 0x6f, + 0x77, 0x5b, 0x31, 0x5d, 0x3b, 0x5b, 0x5d, 0x3b, 0x0a, 0x4c, 0x6f, 0x67, 0x20, + 0x73, 0x61, 0x6c, 0x74, 0x0d, 0x0a, 0x09, 0x09, 0x62, 0x61, 0x6e, 0x67, 0x74, + 0x72, 0x69, 0x6d, 0x62, 0x61, 0x74, 0x68, 0x29, 0x7b, 0x0d, 0x0a, 0x30, 0x30, + 0x70, 0x78, 0x0a, 0x7d, 0x29, 0x3b, 0x6b, 0x6f, 0x3a, 0xec, 0x66, 0x65, 0x65, + 0x73, 0x61, 0x64, 0x3e, 0x0d, 0x73, 0x3a, 0x2f, 0x2f, 0x20, 0x5b, 0x5d, 0x3b, + 0x74, 0x6f, 0x6c, 0x6c, 0x70, 0x6c, 0x75, 0x67, 0x28, 0x29, 0x7b, 0x0a, 0x7b, + 0x0d, 0x0a, 0x20, 0x2e, 0x6a, 0x73, 0x27, 0x32, 0x30, 0x30, 0x70, 0x64, 0x75, + 0x61, 0x6c, 0x62, 0x6f, 0x61, 0x74, 0x2e, 0x4a, 0x50, 0x47, 0x29, 0x3b, 0x0a, + 0x7d, 0x71, 0x75, 0x6f, 0x74, 0x29, 0x3b, 0x0a, 0x0a, 0x27, 0x29, 0x3b, 0x0a, + 0x0d, 0x0a, 0x7d, 0x0d, 0x32, 0x30, 0x31, 0x34, 0x32, 0x30, 0x31, 0x35, 0x32, + 0x30, 0x31, 0x36, 0x32, 0x30, 0x31, 0x37, 0x32, 0x30, 0x31, 0x38, 0x32, 0x30, + 0x31, 0x39, 0x32, 0x30, 0x32, 0x30, 0x32, 0x30, 0x32, 0x31, 0x32, 0x30, 0x32, + 0x32, 0x32, 0x30, 0x32, 0x33, 0x32, 0x30, 0x32, 0x34, 0x32, 0x30, 0x32, 0x35, + 0x32, 0x30, 0x32, 0x36, 0x32, 0x30, 0x32, 0x37, 0x32, 0x30, 0x32, 0x38, 0x32, + 0x30, 0x32, 0x39, 0x32, 0x30, 0x33, 0x30, 0x32, 0x30, 0x33, 0x31, 0x32, 0x30, + 0x33, 0x32, 0x32, 0x30, 0x33, 0x33, 0x32, 0x30, 0x33, 0x34, 0x32, 0x30, 0x33, + 0x35, 0x32, 0x30, 0x33, 0x36, 0x32, 0x30, 0x33, 0x37, 0x32, 0x30, 0x31, 0x33, + 0x32, 0x30, 0x31, 0x32, 0x32, 0x30, 0x31, 0x31, 0x32, 0x30, 0x31, 0x30, 0x32, + 0x30, 0x30, 0x39, 0x32, 0x30, 0x30, 0x38, 0x32, 0x30, 0x30, 0x37, 0x32, 0x30, + 0x30, 0x36, 0x32, 0x30, 0x30, 0x35, 0x32, 0x30, 0x30, 0x34, 0x32, 0x30, 0x30, + 0x33, 0x32, 0x30, 0x30, 0x32, 0x32, 0x30, 0x30, 0x31, 0x32, 0x30, 0x30, 0x30, + 0x31, 0x39, 0x39, 0x39, 0x31, 0x39, 0x39, 0x38, 0x31, 0x39, 0x39, 0x37, 0x31, + 0x39, 0x39, 0x36, 0x31, 0x39, 0x39, 0x35, 0x31, 0x39, 0x39, 0x34, 0x31, 0x39, + 0x39, 0x33, 0x31, 0x39, 0x39, 0x32, 0x31, 0x39, 0x39, 0x31, 0x31, 0x39, 0x39, + 0x30, 0x31, 0x39, 0x38, 0x39, 0x31, 0x39, 0x38, 0x38, 0x31, 0x39, 0x38, 0x37, + 0x31, 0x39, 0x38, 0x36, 0x31, 0x39, 0x38, 0x35, 0x31, 0x39, 0x38, 0x34, 0x31, + 0x39, 0x38, 0x33, 0x31, 0x39, 0x38, 0x32, 0x31, 0x39, 0x38, 0x31, 0x31, 0x39, + 0x38, 0x30, 0x31, 0x39, 0x37, 0x39, 0x31, 0x39, 0x37, 0x38, 0x31, 0x39, 0x37, + 0x37, 0x31, 0x39, 0x37, 0x36, 0x31, 0x39, 0x37, 0x35, 0x31, 0x39, 0x37, 0x34, + 0x31, 0x39, 0x37, 0x33, 0x31, 0x39, 0x37, 0x32, 0x31, 0x39, 0x37, 0x31, 0x31, + 0x39, 0x37, 0x30, 0x31, 0x39, 0x36, 0x39, 0x31, 0x39, 0x36, 0x38, 0x31, 0x39, + 0x36, 0x37, 0x31, 0x39, 0x36, 0x36, 0x31, 0x39, 0x36, 0x35, 0x31, 0x39, 0x36, + 0x34, 0x31, 0x39, 0x36, 0x33, 0x31, 0x39, 0x36, 0x32, 0x31, 0x39, 0x36, 0x31, + 0x31, 0x39, 0x36, 0x30, 0x31, 0x39, 0x35, 0x39, 0x31, 0x39, 0x35, 0x38, 0x31, + 0x39, 0x35, 0x37, 0x31, 0x39, 0x35, 0x36, 0x31, 0x39, 0x35, 0x35, 0x31, 0x39, + 0x35, 0x34, 0x31, 0x39, 0x35, 0x33, 0x31, 0x39, 0x35, 0x32, 0x31, 0x39, 0x35, + 0x31, 0x31, 0x39, 0x35, 0x30, 0x31, 0x30, 0x30, 0x30, 0x31, 0x30, 0x32, 0x34, + 0x31, 0x33, 0x39, 0x34, 0x30, 0x30, 0x30, 0x30, 0x39, 0x39, 0x39, 0x39, 0x63, + 0x6f, 0x6d, 0x6f, 0x6d, 0xc3, 0xa1, 0x73, 0x65, 0x73, 0x74, 0x65, 0x65, 0x73, + 0x74, 0x61, 0x70, 0x65, 0x72, 0x6f, 0x74, 0x6f, 0x64, 0x6f, 0x68, 0x61, 0x63, + 0x65, 0x63, 0x61, 0x64, 0x61, 0x61, 0xc3, 0xb1, 0x6f, 0x62, 0x69, 0x65, 0x6e, + 0x64, 0xc3, 0xad, 0x61, 0x61, 0x73, 0xc3, 0xad, 0x76, 0x69, 0x64, 0x61, 0x63, + 0x61, 0x73, 0x6f, 0x6f, 0x74, 0x72, 0x6f, 0x66, 0x6f, 0x72, 0x6f, 0x73, 0x6f, + 0x6c, 0x6f, 0x6f, 0x74, 0x72, 0x61, 0x63, 0x75, 0x61, 0x6c, 0x64, 0x69, 0x6a, + 0x6f, 0x73, 0x69, 0x64, 0x6f, 0x67, 0x72, 0x61, 0x6e, 0x74, 0x69, 0x70, 0x6f, + 0x74, 0x65, 0x6d, 0x61, 0x64, 0x65, 0x62, 0x65, 0x61, 0x6c, 0x67, 0x6f, 0x71, + 0x75, 0xc3, 0xa9, 0x65, 0x73, 0x74, 0x6f, 0x6e, 0x61, 0x64, 0x61, 0x74, 0x72, + 0x65, 0x73, 0x70, 0x6f, 0x63, 0x6f, 0x63, 0x61, 0x73, 0x61, 0x62, 0x61, 0x6a, + 0x6f, 0x74, 0x6f, 0x64, 0x61, 0x73, 0x69, 0x6e, 0x6f, 0x61, 0x67, 0x75, 0x61, + 0x70, 0x75, 0x65, 0x73, 0x75, 0x6e, 0x6f, 0x73, 0x61, 0x6e, 0x74, 0x65, 0x64, + 0x69, 0x63, 0x65, 0x6c, 0x75, 0x69, 0x73, 0x65, 0x6c, 0x6c, 0x61, 0x6d, 0x61, + 0x79, 0x6f, 0x7a, 0x6f, 0x6e, 0x61, 0x61, 0x6d, 0x6f, 0x72, 0x70, 0x69, 0x73, + 0x6f, 0x6f, 0x62, 0x72, 0x61, 0x63, 0x6c, 0x69, 0x63, 0x65, 0x6c, 0x6c, 0x6f, + 0x64, 0x69, 0x6f, 0x73, 0x68, 0x6f, 0x72, 0x61, 0x63, 0x61, 0x73, 0x69, 0xd0, + 0xb7, 0xd0, 0xb0, 0xd0, 0xbd, 0xd0, 0xb0, 0xd0, 0xbe, 0xd0, 0xbc, 0xd1, 0x80, + 0xd0, 0xb0, 0xd1, 0x80, 0xd1, 0x83, 0xd1, 0x82, 0xd0, 0xb0, 0xd0, 0xbd, 0xd0, + 0xb5, 0xd0, 0xbf, 0xd0, 0xbe, 0xd0, 0xbe, 0xd1, 0x82, 0xd0, 0xb8, 0xd0, 0xb7, + 0xd0, 0xbd, 0xd0, 0xbe, 0xd0, 0xb4, 0xd0, 0xbe, 0xd1, 0x82, 0xd0, 0xbe, 0xd0, + 0xb6, 0xd0, 0xb5, 0xd0, 0xbe, 0xd0, 0xbd, 0xd0, 0xb8, 0xd1, 0x85, 0xd0, 0x9d, + 0xd0, 0xb0, 0xd0, 0xb5, 0xd0, 0xb5, 0xd0, 0xb1, 0xd1, 0x8b, 0xd0, 0xbc, 0xd1, + 0x8b, 0xd0, 0x92, 0xd1, 0x8b, 0xd1, 0x81, 0xd0, 0xbe, 0xd0, 0xb2, 0xd1, 0x8b, + 0xd0, 0xb2, 0xd0, 0xbe, 0xd0, 0x9d, 0xd0, 0xbe, 0xd0, 0xbe, 0xd0, 0xb1, 0xd0, + 0x9f, 0xd0, 0xbe, 0xd0, 0xbb, 0xd0, 0xb8, 0xd0, 0xbd, 0xd0, 0xb8, 0xd0, 0xa0, + 0xd0, 0xa4, 0xd0, 0x9d, 0xd0, 0xb5, 0xd0, 0x9c, 0xd1, 0x8b, 0xd1, 0x82, 0xd1, + 0x8b, 0xd0, 0x9e, 0xd0, 0xbd, 0xd0, 0xb8, 0xd0, 0xbc, 0xd0, 0xb4, 0xd0, 0xb0, + 0xd0, 0x97, 0xd0, 0xb0, 0xd0, 0x94, 0xd0, 0xb0, 0xd0, 0x9d, 0xd1, 0x83, 0xd0, + 0x9e, 0xd0, 0xb1, 0xd1, 0x82, 0xd0, 0xb5, 0xd0, 0x98, 0xd0, 0xb7, 0xd0, 0xb5, + 0xd0, 0xb9, 0xd0, 0xbd, 0xd1, 0x83, 0xd0, 0xbc, 0xd0, 0xbc, 0xd0, 0xa2, 0xd1, + 0x8b, 0xd1, 0x83, 0xd0, 0xb6, 0xd9, 0x81, 0xd9, 0x8a, 0xd8, 0xa3, 0xd9, 0x86, + 0xd9, 0x85, 0xd8, 0xa7, 0xd9, 0x85, 0xd8, 0xb9, 0xd9, 0x83, 0xd9, 0x84, 0xd8, + 0xa3, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf, 0xd9, 0x8a, 0xd8, 0xa7, 0xd9, 0x81, + 0xd9, 0x89, 0xd9, 0x87, 0xd9, 0x88, 0xd9, 0x84, 0xd9, 0x85, 0xd9, 0x84, 0xd9, + 0x83, 0xd8, 0xa7, 0xd9, 0x88, 0xd9, 0x84, 0xd9, 0x87, 0xd8, 0xa8, 0xd8, 0xb3, + 0xd8, 0xa7, 0xd9, 0x84, 0xd8, 0xa5, 0xd9, 0x86, 0xd9, 0x87, 0xd9, 0x8a, 0xd8, + 0xa3, 0xd9, 0x8a, 0xd9, 0x82, 0xd8, 0xaf, 0xd9, 0x87, 0xd9, 0x84, 0xd8, 0xab, + 0xd9, 0x85, 0xd8, 0xa8, 0xd9, 0x87, 0xd9, 0x84, 0xd9, 0x88, 0xd9, 0x84, 0xd9, + 0x8a, 0xd8, 0xa8, 0xd9, 0x84, 0xd8, 0xa7, 0xd9, 0x8a, 0xd8, 0xa8, 0xd9, 0x83, + 0xd8, 0xb4, 0xd9, 0x8a, 0xd8, 0xa7, 0xd9, 0x85, 0xd8, 0xa3, 0xd9, 0x85, 0xd9, + 0x86, 0xd8, 0xaa, 0xd8, 0xa8, 0xd9, 0x8a, 0xd9, 0x84, 0xd9, 0x86, 0xd8, 0xad, + 0xd8, 0xa8, 0xd9, 0x87, 0xd9, 0x85, 0xd9, 0x85, 0xd8, 0xb4, 0xd9, 0x88, 0xd8, + 0xb4, 0x66, 0x69, 0x72, 0x73, 0x74, 0x76, 0x69, 0x64, 0x65, 0x6f, 0x6c, 0x69, + 0x67, 0x68, 0x74, 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x6d, 0x65, 0x64, 0x69, 0x61, + 0x77, 0x68, 0x69, 0x74, 0x65, 0x63, 0x6c, 0x6f, 0x73, 0x65, 0x62, 0x6c, 0x61, + 0x63, 0x6b, 0x72, 0x69, 0x67, 0x68, 0x74, 0x73, 0x6d, 0x61, 0x6c, 0x6c, 0x62, + 0x6f, 0x6f, 0x6b, 0x73, 0x70, 0x6c, 0x61, 0x63, 0x65, 0x6d, 0x75, 0x73, 0x69, + 0x63, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x70, 0x6f, + 0x69, 0x6e, 0x74, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x6c, 0x65, 0x76, 0x65, 0x6c, + 0x74, 0x61, 0x62, 0x6c, 0x65, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x68, 0x6f, 0x75, + 0x73, 0x65, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x79, + 0x65, 0x61, 0x72, 0x73, 0x73, 0x74, 0x61, 0x74, 0x65, 0x74, 0x6f, 0x64, 0x61, + 0x79, 0x77, 0x61, 0x74, 0x65, 0x72, 0x73, 0x74, 0x61, 0x72, 0x74, 0x73, 0x74, + 0x79, 0x6c, 0x65, 0x64, 0x65, 0x61, 0x74, 0x68, 0x70, 0x6f, 0x77, 0x65, 0x72, + 0x70, 0x68, 0x6f, 0x6e, 0x65, 0x6e, 0x69, 0x67, 0x68, 0x74, 0x65, 0x72, 0x72, + 0x6f, 0x72, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x61, 0x62, 0x6f, 0x75, 0x74, 0x74, + 0x65, 0x72, 0x6d, 0x73, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x74, 0x6f, 0x6f, 0x6c, + 0x73, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x74, 0x69, + 0x6d, 0x65, 0x73, 0x6c, 0x61, 0x72, 0x67, 0x65, 0x77, 0x6f, 0x72, 0x64, 0x73, + 0x67, 0x61, 0x6d, 0x65, 0x73, 0x73, 0x68, 0x6f, 0x72, 0x74, 0x73, 0x70, 0x61, + 0x63, 0x65, 0x66, 0x6f, 0x63, 0x75, 0x73, 0x63, 0x6c, 0x65, 0x61, 0x72, 0x6d, + 0x6f, 0x64, 0x65, 0x6c, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x67, 0x75, 0x69, 0x64, + 0x65, 0x72, 0x61, 0x64, 0x69, 0x6f, 0x73, 0x68, 0x61, 0x72, 0x65, 0x77, 0x6f, + 0x6d, 0x65, 0x6e, 0x61, 0x67, 0x61, 0x69, 0x6e, 0x6d, 0x6f, 0x6e, 0x65, 0x79, + 0x69, 0x6d, 0x61, 0x67, 0x65, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x79, 0x6f, 0x75, + 0x6e, 0x67, 0x6c, 0x69, 0x6e, 0x65, 0x73, 0x6c, 0x61, 0x74, 0x65, 0x72, 0x63, + 0x6f, 0x6c, 0x6f, 0x72, 0x67, 0x72, 0x65, 0x65, 0x6e, 0x66, 0x72, 0x6f, 0x6e, + 0x74, 0x26, 0x61, 0x6d, 0x70, 0x3b, 0x77, 0x61, 0x74, 0x63, 0x68, 0x66, 0x6f, + 0x72, 0x63, 0x65, 0x70, 0x72, 0x69, 0x63, 0x65, 0x72, 0x75, 0x6c, 0x65, 0x73, + 0x62, 0x65, 0x67, 0x69, 0x6e, 0x61, 0x66, 0x74, 0x65, 0x72, 0x76, 0x69, 0x73, + 0x69, 0x74, 0x69, 0x73, 0x73, 0x75, 0x65, 0x61, 0x72, 0x65, 0x61, 0x73, 0x62, + 0x65, 0x6c, 0x6f, 0x77, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x74, 0x6f, 0x74, 0x61, + 0x6c, 0x68, 0x6f, 0x75, 0x72, 0x73, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x70, 0x72, + 0x69, 0x6e, 0x74, 0x70, 0x72, 0x65, 0x73, 0x73, 0x62, 0x75, 0x69, 0x6c, 0x74, + 0x6c, 0x69, 0x6e, 0x6b, 0x73, 0x73, 0x70, 0x65, 0x65, 0x64, 0x73, 0x74, 0x75, + 0x64, 0x79, 0x74, 0x72, 0x61, 0x64, 0x65, 0x66, 0x6f, 0x75, 0x6e, 0x64, 0x73, + 0x65, 0x6e, 0x73, 0x65, 0x75, 0x6e, 0x64, 0x65, 0x72, 0x73, 0x68, 0x6f, 0x77, + 0x6e, 0x66, 0x6f, 0x72, 0x6d, 0x73, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x61, 0x64, + 0x64, 0x65, 0x64, 0x73, 0x74, 0x69, 0x6c, 0x6c, 0x6d, 0x6f, 0x76, 0x65, 0x64, + 0x74, 0x61, 0x6b, 0x65, 0x6e, 0x61, 0x62, 0x6f, 0x76, 0x65, 0x66, 0x6c, 0x61, + 0x73, 0x68, 0x66, 0x69, 0x78, 0x65, 0x64, 0x6f, 0x66, 0x74, 0x65, 0x6e, 0x6f, + 0x74, 0x68, 0x65, 0x72, 0x76, 0x69, 0x65, 0x77, 0x73, 0x63, 0x68, 0x65, 0x63, + 0x6b, 0x6c, 0x65, 0x67, 0x61, 0x6c, 0x72, 0x69, 0x76, 0x65, 0x72, 0x69, 0x74, + 0x65, 0x6d, 0x73, 0x71, 0x75, 0x69, 0x63, 0x6b, 0x73, 0x68, 0x61, 0x70, 0x65, + 0x68, 0x75, 0x6d, 0x61, 0x6e, 0x65, 0x78, 0x69, 0x73, 0x74, 0x67, 0x6f, 0x69, + 0x6e, 0x67, 0x6d, 0x6f, 0x76, 0x69, 0x65, 0x74, 0x68, 0x69, 0x72, 0x64, 0x62, + 0x61, 0x73, 0x69, 0x63, 0x70, 0x65, 0x61, 0x63, 0x65, 0x73, 0x74, 0x61, 0x67, + 0x65, 0x77, 0x69, 0x64, 0x74, 0x68, 0x6c, 0x6f, 0x67, 0x69, 0x6e, 0x69, 0x64, + 0x65, 0x61, 0x73, 0x77, 0x72, 0x6f, 0x74, 0x65, 0x70, 0x61, 0x67, 0x65, 0x73, + 0x75, 0x73, 0x65, 0x72, 0x73, 0x64, 0x72, 0x69, 0x76, 0x65, 0x73, 0x74, 0x6f, + 0x72, 0x65, 0x62, 0x72, 0x65, 0x61, 0x6b, 0x73, 0x6f, 0x75, 0x74, 0x68, 0x76, + 0x6f, 0x69, 0x63, 0x65, 0x73, 0x69, 0x74, 0x65, 0x73, 0x6d, 0x6f, 0x6e, 0x74, + 0x68, 0x77, 0x68, 0x65, 0x72, 0x65, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x77, 0x68, + 0x69, 0x63, 0x68, 0x65, 0x61, 0x72, 0x74, 0x68, 0x66, 0x6f, 0x72, 0x75, 0x6d, + 0x74, 0x68, 0x72, 0x65, 0x65, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x70, 0x61, 0x72, + 0x74, 0x79, 0x43, 0x6c, 0x69, 0x63, 0x6b, 0x6c, 0x6f, 0x77, 0x65, 0x72, 0x6c, + 0x69, 0x76, 0x65, 0x73, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x6c, 0x61, 0x79, 0x65, + 0x72, 0x65, 0x6e, 0x74, 0x72, 0x79, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x75, 0x73, + 0x61, 0x67, 0x65, 0x73, 0x6f, 0x75, 0x6e, 0x64, 0x63, 0x6f, 0x75, 0x72, 0x74, + 0x79, 0x6f, 0x75, 0x72, 0x20, 0x62, 0x69, 0x72, 0x74, 0x68, 0x70, 0x6f, 0x70, + 0x75, 0x70, 0x74, 0x79, 0x70, 0x65, 0x73, 0x61, 0x70, 0x70, 0x6c, 0x79, 0x49, + 0x6d, 0x61, 0x67, 0x65, 0x62, 0x65, 0x69, 0x6e, 0x67, 0x75, 0x70, 0x70, 0x65, + 0x72, 0x6e, 0x6f, 0x74, 0x65, 0x73, 0x65, 0x76, 0x65, 0x72, 0x79, 0x73, 0x68, + 0x6f, 0x77, 0x73, 0x6d, 0x65, 0x61, 0x6e, 0x73, 0x65, 0x78, 0x74, 0x72, 0x61, + 0x6d, 0x61, 0x74, 0x63, 0x68, 0x74, 0x72, 0x61, 0x63, 0x6b, 0x6b, 0x6e, 0x6f, + 0x77, 0x6e, 0x65, 0x61, 0x72, 0x6c, 0x79, 0x62, 0x65, 0x67, 0x61, 0x6e, 0x73, + 0x75, 0x70, 0x65, 0x72, 0x70, 0x61, 0x70, 0x65, 0x72, 0x6e, 0x6f, 0x72, 0x74, + 0x68, 0x6c, 0x65, 0x61, 0x72, 0x6e, 0x67, 0x69, 0x76, 0x65, 0x6e, 0x6e, 0x61, + 0x6d, 0x65, 0x64, 0x65, 0x6e, 0x64, 0x65, 0x64, 0x54, 0x65, 0x72, 0x6d, 0x73, + 0x70, 0x61, 0x72, 0x74, 0x73, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x62, 0x72, 0x61, + 0x6e, 0x64, 0x75, 0x73, 0x69, 0x6e, 0x67, 0x77, 0x6f, 0x6d, 0x61, 0x6e, 0x66, + 0x61, 0x6c, 0x73, 0x65, 0x72, 0x65, 0x61, 0x64, 0x79, 0x61, 0x75, 0x64, 0x69, + 0x6f, 0x74, 0x61, 0x6b, 0x65, 0x73, 0x77, 0x68, 0x69, 0x6c, 0x65, 0x2e, 0x63, + 0x6f, 0x6d, 0x2f, 0x6c, 0x69, 0x76, 0x65, 0x64, 0x63, 0x61, 0x73, 0x65, 0x73, + 0x64, 0x61, 0x69, 0x6c, 0x79, 0x63, 0x68, 0x69, 0x6c, 0x64, 0x67, 0x72, 0x65, + 0x61, 0x74, 0x6a, 0x75, 0x64, 0x67, 0x65, 0x74, 0x68, 0x6f, 0x73, 0x65, 0x75, + 0x6e, 0x69, 0x74, 0x73, 0x6e, 0x65, 0x76, 0x65, 0x72, 0x62, 0x72, 0x6f, 0x61, + 0x64, 0x63, 0x6f, 0x61, 0x73, 0x74, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x61, 0x70, + 0x70, 0x6c, 0x65, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x63, 0x79, 0x63, 0x6c, 0x65, + 0x73, 0x63, 0x65, 0x6e, 0x65, 0x70, 0x6c, 0x61, 0x6e, 0x73, 0x63, 0x6c, 0x69, + 0x63, 0x6b, 0x77, 0x72, 0x69, 0x74, 0x65, 0x71, 0x75, 0x65, 0x65, 0x6e, 0x70, + 0x69, 0x65, 0x63, 0x65, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x66, 0x72, 0x61, 0x6d, + 0x65, 0x6f, 0x6c, 0x64, 0x65, 0x72, 0x70, 0x68, 0x6f, 0x74, 0x6f, 0x6c, 0x69, + 0x6d, 0x69, 0x74, 0x63, 0x61, 0x63, 0x68, 0x65, 0x63, 0x69, 0x76, 0x69, 0x6c, + 0x73, 0x63, 0x61, 0x6c, 0x65, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x74, 0x68, 0x65, + 0x6d, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x74, 0x6f, 0x75, 0x63, 0x68, 0x62, + 0x6f, 0x75, 0x6e, 0x64, 0x72, 0x6f, 0x79, 0x61, 0x6c, 0x61, 0x73, 0x6b, 0x65, + 0x64, 0x77, 0x68, 0x6f, 0x6c, 0x65, 0x73, 0x69, 0x6e, 0x63, 0x65, 0x73, 0x74, + 0x6f, 0x63, 0x6b, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x66, 0x61, 0x69, 0x74, 0x68, + 0x68, 0x65, 0x61, 0x72, 0x74, 0x65, 0x6d, 0x70, 0x74, 0x79, 0x6f, 0x66, 0x66, + 0x65, 0x72, 0x73, 0x63, 0x6f, 0x70, 0x65, 0x6f, 0x77, 0x6e, 0x65, 0x64, 0x6d, + 0x69, 0x67, 0x68, 0x74, 0x61, 0x6c, 0x62, 0x75, 0x6d, 0x74, 0x68, 0x69, 0x6e, + 0x6b, 0x62, 0x6c, 0x6f, 0x6f, 0x64, 0x61, 0x72, 0x72, 0x61, 0x79, 0x6d, 0x61, + 0x6a, 0x6f, 0x72, 0x74, 0x72, 0x75, 0x73, 0x74, 0x63, 0x61, 0x6e, 0x6f, 0x6e, + 0x75, 0x6e, 0x69, 0x6f, 0x6e, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x76, 0x61, 0x6c, + 0x69, 0x64, 0x73, 0x74, 0x6f, 0x6e, 0x65, 0x53, 0x74, 0x79, 0x6c, 0x65, 0x4c, + 0x6f, 0x67, 0x69, 0x6e, 0x68, 0x61, 0x70, 0x70, 0x79, 0x6f, 0x63, 0x63, 0x75, + 0x72, 0x6c, 0x65, 0x66, 0x74, 0x3a, 0x66, 0x72, 0x65, 0x73, 0x68, 0x71, 0x75, + 0x69, 0x74, 0x65, 0x66, 0x69, 0x6c, 0x6d, 0x73, 0x67, 0x72, 0x61, 0x64, 0x65, + 0x6e, 0x65, 0x65, 0x64, 0x73, 0x75, 0x72, 0x62, 0x61, 0x6e, 0x66, 0x69, 0x67, + 0x68, 0x74, 0x62, 0x61, 0x73, 0x69, 0x73, 0x68, 0x6f, 0x76, 0x65, 0x72, 0x61, + 0x75, 0x74, 0x6f, 0x3b, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x2e, 0x68, 0x74, 0x6d, + 0x6c, 0x6d, 0x69, 0x78, 0x65, 0x64, 0x66, 0x69, 0x6e, 0x61, 0x6c, 0x59, 0x6f, + 0x75, 0x72, 0x20, 0x73, 0x6c, 0x69, 0x64, 0x65, 0x74, 0x6f, 0x70, 0x69, 0x63, + 0x62, 0x72, 0x6f, 0x77, 0x6e, 0x61, 0x6c, 0x6f, 0x6e, 0x65, 0x64, 0x72, 0x61, + 0x77, 0x6e, 0x73, 0x70, 0x6c, 0x69, 0x74, 0x72, 0x65, 0x61, 0x63, 0x68, 0x52, + 0x69, 0x67, 0x68, 0x74, 0x64, 0x61, 0x74, 0x65, 0x73, 0x6d, 0x61, 0x72, 0x63, + 0x68, 0x71, 0x75, 0x6f, 0x74, 0x65, 0x67, 0x6f, 0x6f, 0x64, 0x73, 0x4c, 0x69, + 0x6e, 0x6b, 0x73, 0x64, 0x6f, 0x75, 0x62, 0x74, 0x61, 0x73, 0x79, 0x6e, 0x63, + 0x74, 0x68, 0x75, 0x6d, 0x62, 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x63, 0x68, 0x69, + 0x65, 0x66, 0x79, 0x6f, 0x75, 0x74, 0x68, 0x6e, 0x6f, 0x76, 0x65, 0x6c, 0x31, + 0x30, 0x70, 0x78, 0x3b, 0x73, 0x65, 0x72, 0x76, 0x65, 0x75, 0x6e, 0x74, 0x69, + 0x6c, 0x68, 0x61, 0x6e, 0x64, 0x73, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x53, 0x70, + 0x61, 0x63, 0x65, 0x71, 0x75, 0x65, 0x72, 0x79, 0x6a, 0x61, 0x6d, 0x65, 0x73, + 0x65, 0x71, 0x75, 0x61, 0x6c, 0x74, 0x77, 0x69, 0x63, 0x65, 0x30, 0x2c, 0x30, + 0x30, 0x30, 0x53, 0x74, 0x61, 0x72, 0x74, 0x70, 0x61, 0x6e, 0x65, 0x6c, 0x73, + 0x6f, 0x6e, 0x67, 0x73, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x65, 0x69, 0x67, 0x68, + 0x74, 0x73, 0x68, 0x69, 0x66, 0x74, 0x77, 0x6f, 0x72, 0x74, 0x68, 0x70, 0x6f, + 0x73, 0x74, 0x73, 0x6c, 0x65, 0x61, 0x64, 0x73, 0x77, 0x65, 0x65, 0x6b, 0x73, + 0x61, 0x76, 0x6f, 0x69, 0x64, 0x74, 0x68, 0x65, 0x73, 0x65, 0x6d, 0x69, 0x6c, + 0x65, 0x73, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x73, 0x6d, 0x61, 0x72, 0x74, 0x61, + 0x6c, 0x70, 0x68, 0x61, 0x70, 0x6c, 0x61, 0x6e, 0x74, 0x6d, 0x61, 0x72, 0x6b, + 0x73, 0x72, 0x61, 0x74, 0x65, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x73, 0x63, 0x6c, + 0x61, 0x69, 0x6d, 0x73, 0x61, 0x6c, 0x65, 0x73, 0x74, 0x65, 0x78, 0x74, 0x73, + 0x73, 0x74, 0x61, 0x72, 0x73, 0x77, 0x72, 0x6f, 0x6e, 0x67, 0x3c, 0x2f, 0x68, + 0x33, 0x3e, 0x74, 0x68, 0x69, 0x6e, 0x67, 0x2e, 0x6f, 0x72, 0x67, 0x2f, 0x6d, + 0x75, 0x6c, 0x74, 0x69, 0x68, 0x65, 0x61, 0x72, 0x64, 0x50, 0x6f, 0x77, 0x65, + 0x72, 0x73, 0x74, 0x61, 0x6e, 0x64, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x6f, + 0x6c, 0x69, 0x64, 0x28, 0x74, 0x68, 0x69, 0x73, 0x62, 0x72, 0x69, 0x6e, 0x67, + 0x73, 0x68, 0x69, 0x70, 0x73, 0x73, 0x74, 0x61, 0x66, 0x66, 0x74, 0x72, 0x69, + 0x65, 0x64, 0x63, 0x61, 0x6c, 0x6c, 0x73, 0x66, 0x75, 0x6c, 0x6c, 0x79, 0x66, + 0x61, 0x63, 0x74, 0x73, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x54, 0x68, 0x69, 0x73, + 0x20, 0x2f, 0x2f, 0x2d, 0x2d, 0x3e, 0x61, 0x64, 0x6d, 0x69, 0x6e, 0x65, 0x67, + 0x79, 0x70, 0x74, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x31, 0x35, 0x70, 0x78, 0x3b, + 0x45, 0x6d, 0x61, 0x69, 0x6c, 0x74, 0x72, 0x75, 0x65, 0x22, 0x63, 0x72, 0x6f, + 0x73, 0x73, 0x73, 0x70, 0x65, 0x6e, 0x74, 0x62, 0x6c, 0x6f, 0x67, 0x73, 0x62, + 0x6f, 0x78, 0x22, 0x3e, 0x6e, 0x6f, 0x74, 0x65, 0x64, 0x6c, 0x65, 0x61, 0x76, + 0x65, 0x63, 0x68, 0x69, 0x6e, 0x61, 0x73, 0x69, 0x7a, 0x65, 0x73, 0x67, 0x75, + 0x65, 0x73, 0x74, 0x3c, 0x2f, 0x68, 0x34, 0x3e, 0x72, 0x6f, 0x62, 0x6f, 0x74, + 0x68, 0x65, 0x61, 0x76, 0x79, 0x74, 0x72, 0x75, 0x65, 0x2c, 0x73, 0x65, 0x76, + 0x65, 0x6e, 0x67, 0x72, 0x61, 0x6e, 0x64, 0x63, 0x72, 0x69, 0x6d, 0x65, 0x73, + 0x69, 0x67, 0x6e, 0x73, 0x61, 0x77, 0x61, 0x72, 0x65, 0x64, 0x61, 0x6e, 0x63, + 0x65, 0x70, 0x68, 0x61, 0x73, 0x65, 0x3e, 0x3c, 0x21, 0x2d, 0x2d, 0x65, 0x6e, + 0x5f, 0x55, 0x53, 0x26, 0x23, 0x33, 0x39, 0x3b, 0x32, 0x30, 0x30, 0x70, 0x78, + 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6e, 0x65, 0x6e, 0x6a, + 0x6f, 0x79, 0x61, 0x6a, 0x61, 0x78, 0x2e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, + 0x6d, 0x69, 0x74, 0x68, 0x55, 0x2e, 0x53, 0x2e, 0x20, 0x68, 0x6f, 0x6c, 0x64, + 0x73, 0x70, 0x65, 0x74, 0x65, 0x72, 0x69, 0x6e, 0x64, 0x69, 0x61, 0x6e, 0x61, + 0x76, 0x22, 0x3e, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x73, 0x63, 0x6f, 0x72, 0x65, + 0x63, 0x6f, 0x6d, 0x65, 0x73, 0x64, 0x6f, 0x69, 0x6e, 0x67, 0x70, 0x72, 0x69, + 0x6f, 0x72, 0x53, 0x68, 0x61, 0x72, 0x65, 0x31, 0x39, 0x39, 0x30, 0x73, 0x72, + 0x6f, 0x6d, 0x61, 0x6e, 0x6c, 0x69, 0x73, 0x74, 0x73, 0x6a, 0x61, 0x70, 0x61, + 0x6e, 0x66, 0x61, 0x6c, 0x6c, 0x73, 0x74, 0x72, 0x69, 0x61, 0x6c, 0x6f, 0x77, + 0x6e, 0x65, 0x72, 0x61, 0x67, 0x72, 0x65, 0x65, 0x3c, 0x2f, 0x68, 0x32, 0x3e, + 0x61, 0x62, 0x75, 0x73, 0x65, 0x61, 0x6c, 0x65, 0x72, 0x74, 0x6f, 0x70, 0x65, + 0x72, 0x61, 0x22, 0x2d, 0x2f, 0x2f, 0x57, 0x63, 0x61, 0x72, 0x64, 0x73, 0x68, + 0x69, 0x6c, 0x6c, 0x73, 0x74, 0x65, 0x61, 0x6d, 0x73, 0x50, 0x68, 0x6f, 0x74, + 0x6f, 0x74, 0x72, 0x75, 0x74, 0x68, 0x63, 0x6c, 0x65, 0x61, 0x6e, 0x2e, 0x70, + 0x68, 0x70, 0x3f, 0x73, 0x61, 0x69, 0x6e, 0x74, 0x6d, 0x65, 0x74, 0x61, 0x6c, + 0x6c, 0x6f, 0x75, 0x69, 0x73, 0x6d, 0x65, 0x61, 0x6e, 0x74, 0x70, 0x72, 0x6f, + 0x6f, 0x66, 0x62, 0x72, 0x69, 0x65, 0x66, 0x72, 0x6f, 0x77, 0x22, 0x3e, 0x67, + 0x65, 0x6e, 0x72, 0x65, 0x74, 0x72, 0x75, 0x63, 0x6b, 0x6c, 0x6f, 0x6f, 0x6b, + 0x73, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x2e, 0x6e, + 0x65, 0x74, 0x2f, 0x2d, 0x2d, 0x3e, 0x0a, 0x3c, 0x74, 0x72, 0x79, 0x20, 0x7b, + 0x0a, 0x76, 0x61, 0x72, 0x20, 0x6d, 0x61, 0x6b, 0x65, 0x73, 0x63, 0x6f, 0x73, + 0x74, 0x73, 0x70, 0x6c, 0x61, 0x69, 0x6e, 0x61, 0x64, 0x75, 0x6c, 0x74, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x74, 0x72, 0x61, 0x69, 0x6e, 0x6c, 0x61, 0x62, 0x6f, + 0x72, 0x68, 0x65, 0x6c, 0x70, 0x73, 0x63, 0x61, 0x75, 0x73, 0x65, 0x6d, 0x61, + 0x67, 0x69, 0x63, 0x6d, 0x6f, 0x74, 0x6f, 0x72, 0x74, 0x68, 0x65, 0x69, 0x72, + 0x32, 0x35, 0x30, 0x70, 0x78, 0x6c, 0x65, 0x61, 0x73, 0x74, 0x73, 0x74, 0x65, + 0x70, 0x73, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x63, 0x6f, 0x75, 0x6c, 0x64, 0x67, + 0x6c, 0x61, 0x73, 0x73, 0x73, 0x69, 0x64, 0x65, 0x73, 0x66, 0x75, 0x6e, 0x64, + 0x73, 0x68, 0x6f, 0x74, 0x65, 0x6c, 0x61, 0x77, 0x61, 0x72, 0x64, 0x6d, 0x6f, + 0x75, 0x74, 0x68, 0x6d, 0x6f, 0x76, 0x65, 0x73, 0x70, 0x61, 0x72, 0x69, 0x73, + 0x67, 0x69, 0x76, 0x65, 0x73, 0x64, 0x75, 0x74, 0x63, 0x68, 0x74, 0x65, 0x78, + 0x61, 0x73, 0x66, 0x72, 0x75, 0x69, 0x74, 0x6e, 0x75, 0x6c, 0x6c, 0x2c, 0x7c, + 0x7c, 0x5b, 0x5d, 0x3b, 0x74, 0x6f, 0x70, 0x22, 0x3e, 0x0a, 0x3c, 0x21, 0x2d, + 0x2d, 0x50, 0x4f, 0x53, 0x54, 0x22, 0x6f, 0x63, 0x65, 0x61, 0x6e, 0x3c, 0x62, + 0x72, 0x2f, 0x3e, 0x66, 0x6c, 0x6f, 0x6f, 0x72, 0x73, 0x70, 0x65, 0x61, 0x6b, + 0x64, 0x65, 0x70, 0x74, 0x68, 0x20, 0x73, 0x69, 0x7a, 0x65, 0x62, 0x61, 0x6e, + 0x6b, 0x73, 0x63, 0x61, 0x74, 0x63, 0x68, 0x63, 0x68, 0x61, 0x72, 0x74, 0x32, + 0x30, 0x70, 0x78, 0x3b, 0x61, 0x6c, 0x69, 0x67, 0x6e, 0x64, 0x65, 0x61, 0x6c, + 0x73, 0x77, 0x6f, 0x75, 0x6c, 0x64, 0x35, 0x30, 0x70, 0x78, 0x3b, 0x75, 0x72, + 0x6c, 0x3d, 0x22, 0x70, 0x61, 0x72, 0x6b, 0x73, 0x6d, 0x6f, 0x75, 0x73, 0x65, + 0x4d, 0x6f, 0x73, 0x74, 0x20, 0x2e, 0x2e, 0x2e, 0x3c, 0x2f, 0x61, 0x6d, 0x6f, + 0x6e, 0x67, 0x62, 0x72, 0x61, 0x69, 0x6e, 0x62, 0x6f, 0x64, 0x79, 0x20, 0x6e, + 0x6f, 0x6e, 0x65, 0x3b, 0x62, 0x61, 0x73, 0x65, 0x64, 0x63, 0x61, 0x72, 0x72, + 0x79, 0x64, 0x72, 0x61, 0x66, 0x74, 0x72, 0x65, 0x66, 0x65, 0x72, 0x70, 0x61, + 0x67, 0x65, 0x5f, 0x68, 0x6f, 0x6d, 0x65, 0x2e, 0x6d, 0x65, 0x74, 0x65, 0x72, + 0x64, 0x65, 0x6c, 0x61, 0x79, 0x64, 0x72, 0x65, 0x61, 0x6d, 0x70, 0x72, 0x6f, + 0x76, 0x65, 0x6a, 0x6f, 0x69, 0x6e, 0x74, 0x3c, 0x2f, 0x74, 0x72, 0x3e, 0x64, + 0x72, 0x75, 0x67, 0x73, 0x3c, 0x21, 0x2d, 0x2d, 0x20, 0x61, 0x70, 0x72, 0x69, + 0x6c, 0x69, 0x64, 0x65, 0x61, 0x6c, 0x61, 0x6c, 0x6c, 0x65, 0x6e, 0x65, 0x78, + 0x61, 0x63, 0x74, 0x66, 0x6f, 0x72, 0x74, 0x68, 0x63, 0x6f, 0x64, 0x65, 0x73, + 0x6c, 0x6f, 0x67, 0x69, 0x63, 0x56, 0x69, 0x65, 0x77, 0x20, 0x73, 0x65, 0x65, + 0x6d, 0x73, 0x62, 0x6c, 0x61, 0x6e, 0x6b, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x20, + 0x28, 0x32, 0x30, 0x30, 0x73, 0x61, 0x76, 0x65, 0x64, 0x5f, 0x6c, 0x69, 0x6e, + 0x6b, 0x67, 0x6f, 0x61, 0x6c, 0x73, 0x67, 0x72, 0x61, 0x6e, 0x74, 0x67, 0x72, + 0x65, 0x65, 0x6b, 0x68, 0x6f, 0x6d, 0x65, 0x73, 0x72, 0x69, 0x6e, 0x67, 0x73, + 0x72, 0x61, 0x74, 0x65, 0x64, 0x33, 0x30, 0x70, 0x78, 0x3b, 0x77, 0x68, 0x6f, + 0x73, 0x65, 0x70, 0x61, 0x72, 0x73, 0x65, 0x28, 0x29, 0x3b, 0x22, 0x20, 0x42, + 0x6c, 0x6f, 0x63, 0x6b, 0x6c, 0x69, 0x6e, 0x75, 0x78, 0x6a, 0x6f, 0x6e, 0x65, + 0x73, 0x70, 0x69, 0x78, 0x65, 0x6c, 0x27, 0x29, 0x3b, 0x22, 0x3e, 0x29, 0x3b, + 0x69, 0x66, 0x28, 0x2d, 0x6c, 0x65, 0x66, 0x74, 0x64, 0x61, 0x76, 0x69, 0x64, + 0x68, 0x6f, 0x72, 0x73, 0x65, 0x46, 0x6f, 0x63, 0x75, 0x73, 0x72, 0x61, 0x69, + 0x73, 0x65, 0x62, 0x6f, 0x78, 0x65, 0x73, 0x54, 0x72, 0x61, 0x63, 0x6b, 0x65, + 0x6d, 0x65, 0x6e, 0x74, 0x3c, 0x2f, 0x65, 0x6d, 0x3e, 0x62, 0x61, 0x72, 0x22, + 0x3e, 0x2e, 0x73, 0x72, 0x63, 0x3d, 0x74, 0x6f, 0x77, 0x65, 0x72, 0x61, 0x6c, + 0x74, 0x3d, 0x22, 0x63, 0x61, 0x62, 0x6c, 0x65, 0x68, 0x65, 0x6e, 0x72, 0x79, + 0x32, 0x34, 0x70, 0x78, 0x3b, 0x73, 0x65, 0x74, 0x75, 0x70, 0x69, 0x74, 0x61, + 0x6c, 0x79, 0x73, 0x68, 0x61, 0x72, 0x70, 0x6d, 0x69, 0x6e, 0x6f, 0x72, 0x74, + 0x61, 0x73, 0x74, 0x65, 0x77, 0x61, 0x6e, 0x74, 0x73, 0x74, 0x68, 0x69, 0x73, + 0x2e, 0x72, 0x65, 0x73, 0x65, 0x74, 0x77, 0x68, 0x65, 0x65, 0x6c, 0x67, 0x69, + 0x72, 0x6c, 0x73, 0x2f, 0x63, 0x73, 0x73, 0x2f, 0x31, 0x30, 0x30, 0x25, 0x3b, + 0x63, 0x6c, 0x75, 0x62, 0x73, 0x73, 0x74, 0x75, 0x66, 0x66, 0x62, 0x69, 0x62, + 0x6c, 0x65, 0x76, 0x6f, 0x74, 0x65, 0x73, 0x20, 0x31, 0x30, 0x30, 0x30, 0x6b, + 0x6f, 0x72, 0x65, 0x61, 0x7d, 0x29, 0x3b, 0x0d, 0x0a, 0x62, 0x61, 0x6e, 0x64, + 0x73, 0x71, 0x75, 0x65, 0x75, 0x65, 0x3d, 0x20, 0x7b, 0x7d, 0x3b, 0x38, 0x30, + 0x70, 0x78, 0x3b, 0x63, 0x6b, 0x69, 0x6e, 0x67, 0x7b, 0x0d, 0x0a, 0x09, 0x09, + 0x61, 0x68, 0x65, 0x61, 0x64, 0x63, 0x6c, 0x6f, 0x63, 0x6b, 0x69, 0x72, 0x69, + 0x73, 0x68, 0x6c, 0x69, 0x6b, 0x65, 0x20, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x73, + 0x74, 0x61, 0x74, 0x73, 0x46, 0x6f, 0x72, 0x6d, 0x22, 0x79, 0x61, 0x68, 0x6f, + 0x6f, 0x29, 0x5b, 0x30, 0x5d, 0x3b, 0x41, 0x62, 0x6f, 0x75, 0x74, 0x66, 0x69, + 0x6e, 0x64, 0x73, 0x3c, 0x2f, 0x68, 0x31, 0x3e, 0x64, 0x65, 0x62, 0x75, 0x67, + 0x74, 0x61, 0x73, 0x6b, 0x73, 0x55, 0x52, 0x4c, 0x20, 0x3d, 0x63, 0x65, 0x6c, + 0x6c, 0x73, 0x7d, 0x29, 0x28, 0x29, 0x3b, 0x31, 0x32, 0x70, 0x78, 0x3b, 0x70, + 0x72, 0x69, 0x6d, 0x65, 0x74, 0x65, 0x6c, 0x6c, 0x73, 0x74, 0x75, 0x72, 0x6e, + 0x73, 0x30, 0x78, 0x36, 0x30, 0x30, 0x2e, 0x6a, 0x70, 0x67, 0x22, 0x73, 0x70, + 0x61, 0x69, 0x6e, 0x62, 0x65, 0x61, 0x63, 0x68, 0x74, 0x61, 0x78, 0x65, 0x73, + 0x6d, 0x69, 0x63, 0x72, 0x6f, 0x61, 0x6e, 0x67, 0x65, 0x6c, 0x2d, 0x2d, 0x3e, + 0x3c, 0x2f, 0x67, 0x69, 0x66, 0x74, 0x73, 0x73, 0x74, 0x65, 0x76, 0x65, 0x2d, + 0x6c, 0x69, 0x6e, 0x6b, 0x62, 0x6f, 0x64, 0x79, 0x2e, 0x7d, 0x29, 0x3b, 0x0a, + 0x09, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x20, 0x28, 0x31, 0x39, 0x39, 0x46, 0x41, + 0x51, 0x3c, 0x2f, 0x72, 0x6f, 0x67, 0x65, 0x72, 0x66, 0x72, 0x61, 0x6e, 0x6b, + 0x43, 0x6c, 0x61, 0x73, 0x73, 0x32, 0x38, 0x70, 0x78, 0x3b, 0x66, 0x65, 0x65, + 0x64, 0x73, 0x3c, 0x68, 0x31, 0x3e, 0x3c, 0x73, 0x63, 0x6f, 0x74, 0x74, 0x74, + 0x65, 0x73, 0x74, 0x73, 0x32, 0x32, 0x70, 0x78, 0x3b, 0x64, 0x72, 0x69, 0x6e, + 0x6b, 0x29, 0x20, 0x7c, 0x7c, 0x20, 0x6c, 0x65, 0x77, 0x69, 0x73, 0x73, 0x68, + 0x61, 0x6c, 0x6c, 0x23, 0x30, 0x33, 0x39, 0x3b, 0x20, 0x66, 0x6f, 0x72, 0x20, + 0x6c, 0x6f, 0x76, 0x65, 0x64, 0x77, 0x61, 0x73, 0x74, 0x65, 0x30, 0x30, 0x70, + 0x78, 0x3b, 0x6a, 0x61, 0x3a, 0xe3, 0x82, 0x73, 0x69, 0x6d, 0x6f, 0x6e, 0x3c, + 0x66, 0x6f, 0x6e, 0x74, 0x72, 0x65, 0x70, 0x6c, 0x79, 0x6d, 0x65, 0x65, 0x74, + 0x73, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x63, 0x68, 0x65, 0x61, 0x70, 0x74, 0x69, + 0x67, 0x68, 0x74, 0x42, 0x72, 0x61, 0x6e, 0x64, 0x29, 0x20, 0x21, 0x3d, 0x20, + 0x64, 0x72, 0x65, 0x73, 0x73, 0x63, 0x6c, 0x69, 0x70, 0x73, 0x72, 0x6f, 0x6f, + 0x6d, 0x73, 0x6f, 0x6e, 0x6b, 0x65, 0x79, 0x6d, 0x6f, 0x62, 0x69, 0x6c, 0x6d, + 0x61, 0x69, 0x6e, 0x2e, 0x4e, 0x61, 0x6d, 0x65, 0x20, 0x70, 0x6c, 0x61, 0x74, + 0x65, 0x66, 0x75, 0x6e, 0x6e, 0x79, 0x74, 0x72, 0x65, 0x65, 0x73, 0x63, 0x6f, + 0x6d, 0x2f, 0x22, 0x31, 0x2e, 0x6a, 0x70, 0x67, 0x77, 0x6d, 0x6f, 0x64, 0x65, + 0x70, 0x61, 0x72, 0x61, 0x6d, 0x53, 0x54, 0x41, 0x52, 0x54, 0x6c, 0x65, 0x66, + 0x74, 0x20, 0x69, 0x64, 0x64, 0x65, 0x6e, 0x2c, 0x20, 0x32, 0x30, 0x31, 0x29, + 0x3b, 0x0a, 0x7d, 0x0a, 0x66, 0x6f, 0x72, 0x6d, 0x2e, 0x76, 0x69, 0x72, 0x75, + 0x73, 0x63, 0x68, 0x61, 0x69, 0x72, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x77, 0x6f, + 0x72, 0x73, 0x74, 0x50, 0x61, 0x67, 0x65, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, + 0x70, 0x61, 0x74, 0x63, 0x68, 0x3c, 0x21, 0x2d, 0x2d, 0x0a, 0x6f, 0x2d, 0x63, + 0x61, 0x63, 0x66, 0x69, 0x72, 0x6d, 0x73, 0x74, 0x6f, 0x75, 0x72, 0x73, 0x2c, + 0x30, 0x30, 0x30, 0x20, 0x61, 0x73, 0x69, 0x61, 0x6e, 0x69, 0x2b, 0x2b, 0x29, + 0x7b, 0x61, 0x64, 0x6f, 0x62, 0x65, 0x27, 0x29, 0x5b, 0x30, 0x5d, 0x69, 0x64, + 0x3d, 0x31, 0x30, 0x62, 0x6f, 0x74, 0x68, 0x3b, 0x6d, 0x65, 0x6e, 0x75, 0x20, + 0x2e, 0x32, 0x2e, 0x6d, 0x69, 0x2e, 0x70, 0x6e, 0x67, 0x22, 0x6b, 0x65, 0x76, + 0x69, 0x6e, 0x63, 0x6f, 0x61, 0x63, 0x68, 0x43, 0x68, 0x69, 0x6c, 0x64, 0x62, + 0x72, 0x75, 0x63, 0x65, 0x32, 0x2e, 0x6a, 0x70, 0x67, 0x55, 0x52, 0x4c, 0x29, + 0x2b, 0x2e, 0x6a, 0x70, 0x67, 0x7c, 0x73, 0x75, 0x69, 0x74, 0x65, 0x73, 0x6c, + 0x69, 0x63, 0x65, 0x68, 0x61, 0x72, 0x72, 0x79, 0x31, 0x32, 0x30, 0x22, 0x20, + 0x73, 0x77, 0x65, 0x65, 0x74, 0x74, 0x72, 0x3e, 0x0d, 0x0a, 0x6e, 0x61, 0x6d, + 0x65, 0x3d, 0x64, 0x69, 0x65, 0x67, 0x6f, 0x70, 0x61, 0x67, 0x65, 0x20, 0x73, + 0x77, 0x69, 0x73, 0x73, 0x2d, 0x2d, 0x3e, 0x0a, 0x0a, 0x23, 0x66, 0x66, 0x66, + 0x3b, 0x22, 0x3e, 0x4c, 0x6f, 0x67, 0x2e, 0x63, 0x6f, 0x6d, 0x22, 0x74, 0x72, + 0x65, 0x61, 0x74, 0x73, 0x68, 0x65, 0x65, 0x74, 0x29, 0x20, 0x26, 0x26, 0x20, + 0x31, 0x34, 0x70, 0x78, 0x3b, 0x73, 0x6c, 0x65, 0x65, 0x70, 0x6e, 0x74, 0x65, + 0x6e, 0x74, 0x66, 0x69, 0x6c, 0x65, 0x64, 0x6a, 0x61, 0x3a, 0xe3, 0x83, 0x69, + 0x64, 0x3d, 0x22, 0x63, 0x4e, 0x61, 0x6d, 0x65, 0x22, 0x77, 0x6f, 0x72, 0x73, + 0x65, 0x73, 0x68, 0x6f, 0x74, 0x73, 0x2d, 0x62, 0x6f, 0x78, 0x2d, 0x64, 0x65, + 0x6c, 0x74, 0x61, 0x0a, 0x26, 0x6c, 0x74, 0x3b, 0x62, 0x65, 0x61, 0x72, 0x73, + 0x3a, 0x34, 0x38, 0x5a, 0x3c, 0x64, 0x61, 0x74, 0x61, 0x2d, 0x72, 0x75, 0x72, + 0x61, 0x6c, 0x3c, 0x2f, 0x61, 0x3e, 0x20, 0x73, 0x70, 0x65, 0x6e, 0x64, 0x62, + 0x61, 0x6b, 0x65, 0x72, 0x73, 0x68, 0x6f, 0x70, 0x73, 0x3d, 0x20, 0x22, 0x22, + 0x3b, 0x70, 0x68, 0x70, 0x22, 0x3e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x31, 0x33, + 0x70, 0x78, 0x3b, 0x62, 0x72, 0x69, 0x61, 0x6e, 0x68, 0x65, 0x6c, 0x6c, 0x6f, + 0x73, 0x69, 0x7a, 0x65, 0x3d, 0x6f, 0x3d, 0x25, 0x32, 0x46, 0x20, 0x6a, 0x6f, + 0x69, 0x6e, 0x6d, 0x61, 0x79, 0x62, 0x65, 0x3c, 0x69, 0x6d, 0x67, 0x20, 0x69, + 0x6d, 0x67, 0x22, 0x3e, 0x2c, 0x20, 0x66, 0x6a, 0x73, 0x69, 0x6d, 0x67, 0x22, + 0x20, 0x22, 0x29, 0x5b, 0x30, 0x5d, 0x4d, 0x54, 0x6f, 0x70, 0x42, 0x54, 0x79, + 0x70, 0x65, 0x22, 0x6e, 0x65, 0x77, 0x6c, 0x79, 0x44, 0x61, 0x6e, 0x73, 0x6b, + 0x63, 0x7a, 0x65, 0x63, 0x68, 0x74, 0x72, 0x61, 0x69, 0x6c, 0x6b, 0x6e, 0x6f, + 0x77, 0x73, 0x3c, 0x2f, 0x68, 0x35, 0x3e, 0x66, 0x61, 0x71, 0x22, 0x3e, 0x7a, + 0x68, 0x2d, 0x63, 0x6e, 0x31, 0x30, 0x29, 0x3b, 0x0a, 0x2d, 0x31, 0x22, 0x29, + 0x3b, 0x74, 0x79, 0x70, 0x65, 0x3d, 0x62, 0x6c, 0x75, 0x65, 0x73, 0x74, 0x72, + 0x75, 0x6c, 0x79, 0x64, 0x61, 0x76, 0x69, 0x73, 0x2e, 0x6a, 0x73, 0x27, 0x3b, + 0x3e, 0x0d, 0x0a, 0x3c, 0x21, 0x73, 0x74, 0x65, 0x65, 0x6c, 0x20, 0x79, 0x6f, + 0x75, 0x20, 0x68, 0x32, 0x3e, 0x0d, 0x0a, 0x66, 0x6f, 0x72, 0x6d, 0x20, 0x6a, + 0x65, 0x73, 0x75, 0x73, 0x31, 0x30, 0x30, 0x25, 0x20, 0x6d, 0x65, 0x6e, 0x75, + 0x2e, 0x0d, 0x0a, 0x09, 0x0d, 0x0a, 0x77, 0x61, 0x6c, 0x65, 0x73, 0x72, 0x69, + 0x73, 0x6b, 0x73, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x64, 0x64, 0x69, 0x6e, 0x67, + 0x62, 0x2d, 0x6c, 0x69, 0x6b, 0x74, 0x65, 0x61, 0x63, 0x68, 0x67, 0x69, 0x66, + 0x22, 0x20, 0x76, 0x65, 0x67, 0x61, 0x73, 0x64, 0x61, 0x6e, 0x73, 0x6b, 0x65, + 0x65, 0x73, 0x74, 0x69, 0x73, 0x68, 0x71, 0x69, 0x70, 0x73, 0x75, 0x6f, 0x6d, + 0x69, 0x73, 0x6f, 0x62, 0x72, 0x65, 0x64, 0x65, 0x73, 0x64, 0x65, 0x65, 0x6e, + 0x74, 0x72, 0x65, 0x74, 0x6f, 0x64, 0x6f, 0x73, 0x70, 0x75, 0x65, 0x64, 0x65, + 0x61, 0xc3, 0xb1, 0x6f, 0x73, 0x65, 0x73, 0x74, 0xc3, 0xa1, 0x74, 0x69, 0x65, + 0x6e, 0x65, 0x68, 0x61, 0x73, 0x74, 0x61, 0x6f, 0x74, 0x72, 0x6f, 0x73, 0x70, + 0x61, 0x72, 0x74, 0x65, 0x64, 0x6f, 0x6e, 0x64, 0x65, 0x6e, 0x75, 0x65, 0x76, + 0x6f, 0x68, 0x61, 0x63, 0x65, 0x72, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x6d, 0x69, + 0x73, 0x6d, 0x6f, 0x6d, 0x65, 0x6a, 0x6f, 0x72, 0x6d, 0x75, 0x6e, 0x64, 0x6f, + 0x61, 0x71, 0x75, 0xc3, 0xad, 0x64, 0xc3, 0xad, 0x61, 0x73, 0x73, 0xc3, 0xb3, + 0x6c, 0x6f, 0x61, 0x79, 0x75, 0x64, 0x61, 0x66, 0x65, 0x63, 0x68, 0x61, 0x74, + 0x6f, 0x64, 0x61, 0x73, 0x74, 0x61, 0x6e, 0x74, 0x6f, 0x6d, 0x65, 0x6e, 0x6f, + 0x73, 0x64, 0x61, 0x74, 0x6f, 0x73, 0x6f, 0x74, 0x72, 0x61, 0x73, 0x73, 0x69, + 0x74, 0x69, 0x6f, 0x6d, 0x75, 0x63, 0x68, 0x6f, 0x61, 0x68, 0x6f, 0x72, 0x61, + 0x6c, 0x75, 0x67, 0x61, 0x72, 0x6d, 0x61, 0x79, 0x6f, 0x72, 0x65, 0x73, 0x74, + 0x6f, 0x73, 0x68, 0x6f, 0x72, 0x61, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x61, + 0x6e, 0x74, 0x65, 0x73, 0x66, 0x6f, 0x74, 0x6f, 0x73, 0x65, 0x73, 0x74, 0x61, + 0x73, 0x70, 0x61, 0xc3, 0xad, 0x73, 0x6e, 0x75, 0x65, 0x76, 0x61, 0x73, 0x61, + 0x6c, 0x75, 0x64, 0x66, 0x6f, 0x72, 0x6f, 0x73, 0x6d, 0x65, 0x64, 0x69, 0x6f, + 0x71, 0x75, 0x69, 0x65, 0x6e, 0x6d, 0x65, 0x73, 0x65, 0x73, 0x70, 0x6f, 0x64, + 0x65, 0x72, 0x63, 0x68, 0x69, 0x6c, 0x65, 0x73, 0x65, 0x72, 0xc3, 0xa1, 0x76, + 0x65, 0x63, 0x65, 0x73, 0x64, 0x65, 0x63, 0x69, 0x72, 0x6a, 0x6f, 0x73, 0xc3, + 0xa9, 0x65, 0x73, 0x74, 0x61, 0x72, 0x76, 0x65, 0x6e, 0x74, 0x61, 0x67, 0x72, + 0x75, 0x70, 0x6f, 0x68, 0x65, 0x63, 0x68, 0x6f, 0x65, 0x6c, 0x6c, 0x6f, 0x73, + 0x74, 0x65, 0x6e, 0x67, 0x6f, 0x61, 0x6d, 0x69, 0x67, 0x6f, 0x63, 0x6f, 0x73, + 0x61, 0x73, 0x6e, 0x69, 0x76, 0x65, 0x6c, 0x67, 0x65, 0x6e, 0x74, 0x65, 0x6d, + 0x69, 0x73, 0x6d, 0x61, 0x61, 0x69, 0x72, 0x65, 0x73, 0x6a, 0x75, 0x6c, 0x69, + 0x6f, 0x74, 0x65, 0x6d, 0x61, 0x73, 0x68, 0x61, 0x63, 0x69, 0x61, 0x66, 0x61, + 0x76, 0x6f, 0x72, 0x6a, 0x75, 0x6e, 0x69, 0x6f, 0x6c, 0x69, 0x62, 0x72, 0x65, + 0x70, 0x75, 0x6e, 0x74, 0x6f, 0x62, 0x75, 0x65, 0x6e, 0x6f, 0x61, 0x75, 0x74, + 0x6f, 0x72, 0x61, 0x62, 0x72, 0x69, 0x6c, 0x62, 0x75, 0x65, 0x6e, 0x61, 0x74, + 0x65, 0x78, 0x74, 0x6f, 0x6d, 0x61, 0x72, 0x7a, 0x6f, 0x73, 0x61, 0x62, 0x65, + 0x72, 0x6c, 0x69, 0x73, 0x74, 0x61, 0x6c, 0x75, 0x65, 0x67, 0x6f, 0x63, 0xc3, + 0xb3, 0x6d, 0x6f, 0x65, 0x6e, 0x65, 0x72, 0x6f, 0x6a, 0x75, 0x65, 0x67, 0x6f, + 0x70, 0x65, 0x72, 0xc3, 0xba, 0x68, 0x61, 0x62, 0x65, 0x72, 0x65, 0x73, 0x74, + 0x6f, 0x79, 0x6e, 0x75, 0x6e, 0x63, 0x61, 0x6d, 0x75, 0x6a, 0x65, 0x72, 0x76, + 0x61, 0x6c, 0x6f, 0x72, 0x66, 0x75, 0x65, 0x72, 0x61, 0x6c, 0x69, 0x62, 0x72, + 0x6f, 0x67, 0x75, 0x73, 0x74, 0x61, 0x69, 0x67, 0x75, 0x61, 0x6c, 0x76, 0x6f, + 0x74, 0x6f, 0x73, 0x63, 0x61, 0x73, 0x6f, 0x73, 0x67, 0x75, 0xc3, 0xad, 0x61, + 0x70, 0x75, 0x65, 0x64, 0x6f, 0x73, 0x6f, 0x6d, 0x6f, 0x73, 0x61, 0x76, 0x69, + 0x73, 0x6f, 0x75, 0x73, 0x74, 0x65, 0x64, 0x64, 0x65, 0x62, 0x65, 0x6e, 0x6e, + 0x6f, 0x63, 0x68, 0x65, 0x62, 0x75, 0x73, 0x63, 0x61, 0x66, 0x61, 0x6c, 0x74, + 0x61, 0x65, 0x75, 0x72, 0x6f, 0x73, 0x73, 0x65, 0x72, 0x69, 0x65, 0x64, 0x69, + 0x63, 0x68, 0x6f, 0x63, 0x75, 0x72, 0x73, 0x6f, 0x63, 0x6c, 0x61, 0x76, 0x65, + 0x63, 0x61, 0x73, 0x61, 0x73, 0x6c, 0x65, 0xc3, 0xb3, 0x6e, 0x70, 0x6c, 0x61, + 0x7a, 0x6f, 0x6c, 0x61, 0x72, 0x67, 0x6f, 0x6f, 0x62, 0x72, 0x61, 0x73, 0x76, + 0x69, 0x73, 0x74, 0x61, 0x61, 0x70, 0x6f, 0x79, 0x6f, 0x6a, 0x75, 0x6e, 0x74, + 0x6f, 0x74, 0x72, 0x61, 0x74, 0x61, 0x76, 0x69, 0x73, 0x74, 0x6f, 0x63, 0x72, + 0x65, 0x61, 0x72, 0x63, 0x61, 0x6d, 0x70, 0x6f, 0x68, 0x65, 0x6d, 0x6f, 0x73, + 0x63, 0x69, 0x6e, 0x63, 0x6f, 0x63, 0x61, 0x72, 0x67, 0x6f, 0x70, 0x69, 0x73, + 0x6f, 0x73, 0x6f, 0x72, 0x64, 0x65, 0x6e, 0x68, 0x61, 0x63, 0x65, 0x6e, 0xc3, + 0xa1, 0x72, 0x65, 0x61, 0x64, 0x69, 0x73, 0x63, 0x6f, 0x70, 0x65, 0x64, 0x72, + 0x6f, 0x63, 0x65, 0x72, 0x63, 0x61, 0x70, 0x75, 0x65, 0x64, 0x61, 0x70, 0x61, + 0x70, 0x65, 0x6c, 0x6d, 0x65, 0x6e, 0x6f, 0x72, 0xc3, 0xba, 0x74, 0x69, 0x6c, + 0x63, 0x6c, 0x61, 0x72, 0x6f, 0x6a, 0x6f, 0x72, 0x67, 0x65, 0x63, 0x61, 0x6c, + 0x6c, 0x65, 0x70, 0x6f, 0x6e, 0x65, 0x72, 0x74, 0x61, 0x72, 0x64, 0x65, 0x6e, + 0x61, 0x64, 0x69, 0x65, 0x6d, 0x61, 0x72, 0x63, 0x61, 0x73, 0x69, 0x67, 0x75, + 0x65, 0x65, 0x6c, 0x6c, 0x61, 0x73, 0x73, 0x69, 0x67, 0x6c, 0x6f, 0x63, 0x6f, + 0x63, 0x68, 0x65, 0x6d, 0x6f, 0x74, 0x6f, 0x73, 0x6d, 0x61, 0x64, 0x72, 0x65, + 0x63, 0x6c, 0x61, 0x73, 0x65, 0x72, 0x65, 0x73, 0x74, 0x6f, 0x6e, 0x69, 0xc3, + 0xb1, 0x6f, 0x71, 0x75, 0x65, 0x64, 0x61, 0x70, 0x61, 0x73, 0x61, 0x72, 0x62, + 0x61, 0x6e, 0x63, 0x6f, 0x68, 0x69, 0x6a, 0x6f, 0x73, 0x76, 0x69, 0x61, 0x6a, + 0x65, 0x70, 0x61, 0x62, 0x6c, 0x6f, 0xc3, 0xa9, 0x73, 0x74, 0x65, 0x76, 0x69, + 0x65, 0x6e, 0x65, 0x72, 0x65, 0x69, 0x6e, 0x6f, 0x64, 0x65, 0x6a, 0x61, 0x72, + 0x66, 0x6f, 0x6e, 0x64, 0x6f, 0x63, 0x61, 0x6e, 0x61, 0x6c, 0x6e, 0x6f, 0x72, + 0x74, 0x65, 0x6c, 0x65, 0x74, 0x72, 0x61, 0x63, 0x61, 0x75, 0x73, 0x61, 0x74, + 0x6f, 0x6d, 0x61, 0x72, 0x6d, 0x61, 0x6e, 0x6f, 0x73, 0x6c, 0x75, 0x6e, 0x65, + 0x73, 0x61, 0x75, 0x74, 0x6f, 0x73, 0x76, 0x69, 0x6c, 0x6c, 0x61, 0x76, 0x65, + 0x6e, 0x64, 0x6f, 0x70, 0x65, 0x73, 0x61, 0x72, 0x74, 0x69, 0x70, 0x6f, 0x73, + 0x74, 0x65, 0x6e, 0x67, 0x61, 0x6d, 0x61, 0x72, 0x63, 0x6f, 0x6c, 0x6c, 0x65, + 0x76, 0x61, 0x70, 0x61, 0x64, 0x72, 0x65, 0x75, 0x6e, 0x69, 0x64, 0x6f, 0x76, + 0x61, 0x6d, 0x6f, 0x73, 0x7a, 0x6f, 0x6e, 0x61, 0x73, 0x61, 0x6d, 0x62, 0x6f, + 0x73, 0x62, 0x61, 0x6e, 0x64, 0x61, 0x6d, 0x61, 0x72, 0x69, 0x61, 0x61, 0x62, + 0x75, 0x73, 0x6f, 0x6d, 0x75, 0x63, 0x68, 0x61, 0x73, 0x75, 0x62, 0x69, 0x72, + 0x72, 0x69, 0x6f, 0x6a, 0x61, 0x76, 0x69, 0x76, 0x69, 0x72, 0x67, 0x72, 0x61, + 0x64, 0x6f, 0x63, 0x68, 0x69, 0x63, 0x61, 0x61, 0x6c, 0x6c, 0xc3, 0xad, 0x6a, + 0x6f, 0x76, 0x65, 0x6e, 0x64, 0x69, 0x63, 0x68, 0x61, 0x65, 0x73, 0x74, 0x61, + 0x6e, 0x74, 0x61, 0x6c, 0x65, 0x73, 0x73, 0x61, 0x6c, 0x69, 0x72, 0x73, 0x75, + 0x65, 0x6c, 0x6f, 0x70, 0x65, 0x73, 0x6f, 0x73, 0x66, 0x69, 0x6e, 0x65, 0x73, + 0x6c, 0x6c, 0x61, 0x6d, 0x61, 0x62, 0x75, 0x73, 0x63, 0x6f, 0xc3, 0xa9, 0x73, + 0x74, 0x61, 0x6c, 0x6c, 0x65, 0x67, 0x61, 0x6e, 0x65, 0x67, 0x72, 0x6f, 0x70, + 0x6c, 0x61, 0x7a, 0x61, 0x68, 0x75, 0x6d, 0x6f, 0x72, 0x70, 0x61, 0x67, 0x61, + 0x72, 0x6a, 0x75, 0x6e, 0x74, 0x61, 0x64, 0x6f, 0x62, 0x6c, 0x65, 0x69, 0x73, + 0x6c, 0x61, 0x73, 0x62, 0x6f, 0x6c, 0x73, 0x61, 0x62, 0x61, 0xc3, 0xb1, 0x6f, + 0x68, 0x61, 0x62, 0x6c, 0x61, 0x6c, 0x75, 0x63, 0x68, 0x61, 0xc3, 0x81, 0x72, + 0x65, 0x61, 0x64, 0x69, 0x63, 0x65, 0x6e, 0x6a, 0x75, 0x67, 0x61, 0x72, 0x6e, + 0x6f, 0x74, 0x61, 0x73, 0x76, 0x61, 0x6c, 0x6c, 0x65, 0x61, 0x6c, 0x6c, 0xc3, + 0xa1, 0x63, 0x61, 0x72, 0x67, 0x61, 0x64, 0x6f, 0x6c, 0x6f, 0x72, 0x61, 0x62, + 0x61, 0x6a, 0x6f, 0x65, 0x73, 0x74, 0xc3, 0xa9, 0x67, 0x75, 0x73, 0x74, 0x6f, + 0x6d, 0x65, 0x6e, 0x74, 0x65, 0x6d, 0x61, 0x72, 0x69, 0x6f, 0x66, 0x69, 0x72, + 0x6d, 0x61, 0x63, 0x6f, 0x73, 0x74, 0x6f, 0x66, 0x69, 0x63, 0x68, 0x61, 0x70, + 0x6c, 0x61, 0x74, 0x61, 0x68, 0x6f, 0x67, 0x61, 0x72, 0x61, 0x72, 0x74, 0x65, + 0x73, 0x6c, 0x65, 0x79, 0x65, 0x73, 0x61, 0x71, 0x75, 0x65, 0x6c, 0x6d, 0x75, + 0x73, 0x65, 0x6f, 0x62, 0x61, 0x73, 0x65, 0x73, 0x70, 0x6f, 0x63, 0x6f, 0x73, + 0x6d, 0x69, 0x74, 0x61, 0x64, 0x63, 0x69, 0x65, 0x6c, 0x6f, 0x63, 0x68, 0x69, + 0x63, 0x6f, 0x6d, 0x69, 0x65, 0x64, 0x6f, 0x67, 0x61, 0x6e, 0x61, 0x72, 0x73, + 0x61, 0x6e, 0x74, 0x6f, 0x65, 0x74, 0x61, 0x70, 0x61, 0x64, 0x65, 0x62, 0x65, + 0x73, 0x70, 0x6c, 0x61, 0x79, 0x61, 0x72, 0x65, 0x64, 0x65, 0x73, 0x73, 0x69, + 0x65, 0x74, 0x65, 0x63, 0x6f, 0x72, 0x74, 0x65, 0x63, 0x6f, 0x72, 0x65, 0x61, + 0x64, 0x75, 0x64, 0x61, 0x73, 0x64, 0x65, 0x73, 0x65, 0x6f, 0x76, 0x69, 0x65, + 0x6a, 0x6f, 0x64, 0x65, 0x73, 0x65, 0x61, 0x61, 0x67, 0x75, 0x61, 0x73, 0x26, + 0x71, 0x75, 0x6f, 0x74, 0x3b, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x63, 0x6f, + 0x6d, 0x6d, 0x6f, 0x6e, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x65, 0x76, 0x65, + 0x6e, 0x74, 0x73, 0x6d, 0x61, 0x73, 0x74, 0x65, 0x72, 0x73, 0x79, 0x73, 0x74, + 0x65, 0x6d, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x62, 0x61, 0x6e, 0x6e, 0x65, + 0x72, 0x72, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x73, 0x63, 0x72, 0x6f, 0x6c, 0x6c, + 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x6d, + 0x65, 0x64, 0x69, 0x75, 0x6d, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x6e, 0x75, + 0x6d, 0x62, 0x65, 0x72, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x72, 0x65, 0x73, + 0x75, 0x6c, 0x74, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x73, 0x63, 0x72, 0x65, + 0x65, 0x6e, 0x63, 0x68, 0x6f, 0x6f, 0x73, 0x65, 0x6e, 0x6f, 0x72, 0x6d, 0x61, + 0x6c, 0x74, 0x72, 0x61, 0x76, 0x65, 0x6c, 0x69, 0x73, 0x73, 0x75, 0x65, 0x73, + 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x73, + 0x70, 0x72, 0x69, 0x6e, 0x67, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x6d, 0x6f, + 0x62, 0x69, 0x6c, 0x65, 0x73, 0x77, 0x69, 0x74, 0x63, 0x68, 0x70, 0x68, 0x6f, + 0x74, 0x6f, 0x73, 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x72, 0x65, 0x67, 0x69, + 0x6f, 0x6e, 0x69, 0x74, 0x73, 0x65, 0x6c, 0x66, 0x73, 0x6f, 0x63, 0x69, 0x61, + 0x6c, 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, 0x63, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, + 0x72, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x66, 0x6f, 0x6c, 0x6c, 0x6f, 0x77, 0x74, + 0x69, 0x74, 0x6c, 0x65, 0x3e, 0x65, 0x69, 0x74, 0x68, 0x65, 0x72, 0x6c, 0x65, + 0x6e, 0x67, 0x74, 0x68, 0x66, 0x61, 0x6d, 0x69, 0x6c, 0x79, 0x66, 0x72, 0x69, + 0x65, 0x6e, 0x64, 0x6c, 0x61, 0x79, 0x6f, 0x75, 0x74, 0x61, 0x75, 0x74, 0x68, + 0x6f, 0x72, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x72, 0x65, 0x76, 0x69, 0x65, + 0x77, 0x73, 0x75, 0x6d, 0x6d, 0x65, 0x72, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, + 0x70, 0x6c, 0x61, 0x79, 0x65, 0x64, 0x70, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x65, + 0x78, 0x70, 0x61, 0x6e, 0x64, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x66, 0x6f, + 0x72, 0x6d, 0x61, 0x74, 0x64, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x70, 0x6f, 0x69, + 0x6e, 0x74, 0x73, 0x73, 0x65, 0x72, 0x69, 0x65, 0x73, 0x70, 0x65, 0x72, 0x73, + 0x6f, 0x6e, 0x6c, 0x69, 0x76, 0x69, 0x6e, 0x67, 0x64, 0x65, 0x73, 0x69, 0x67, + 0x6e, 0x6d, 0x6f, 0x6e, 0x74, 0x68, 0x73, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x73, + 0x75, 0x6e, 0x69, 0x71, 0x75, 0x65, 0x77, 0x65, 0x69, 0x67, 0x68, 0x74, 0x70, + 0x65, 0x6f, 0x70, 0x6c, 0x65, 0x65, 0x6e, 0x65, 0x72, 0x67, 0x79, 0x6e, 0x61, + 0x74, 0x75, 0x72, 0x65, 0x73, 0x65, 0x61, 0x72, 0x63, 0x68, 0x66, 0x69, 0x67, + 0x75, 0x72, 0x65, 0x68, 0x61, 0x76, 0x69, 0x6e, 0x67, 0x63, 0x75, 0x73, 0x74, + 0x6f, 0x6d, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x6c, 0x65, 0x74, 0x74, 0x65, + 0x72, 0x77, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x73, 0x75, 0x62, 0x6d, 0x69, 0x74, + 0x72, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x75, + 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x68, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x6d, 0x65, + 0x74, 0x68, 0x6f, 0x64, 0x76, 0x69, 0x64, 0x65, 0x6f, 0x73, 0x73, 0x63, 0x68, + 0x6f, 0x6f, 0x6c, 0x66, 0x75, 0x74, 0x75, 0x72, 0x65, 0x73, 0x68, 0x61, 0x64, + 0x6f, 0x77, 0x64, 0x65, 0x62, 0x61, 0x74, 0x65, 0x76, 0x61, 0x6c, 0x75, 0x65, + 0x73, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x6f, 0x74, 0x68, 0x65, 0x72, 0x73, + 0x72, 0x69, 0x67, 0x68, 0x74, 0x73, 0x6c, 0x65, 0x61, 0x67, 0x75, 0x65, 0x63, + 0x68, 0x72, 0x6f, 0x6d, 0x65, 0x73, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x6e, 0x6f, + 0x74, 0x69, 0x63, 0x65, 0x73, 0x68, 0x61, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x64, + 0x69, 0x6e, 0x67, 0x73, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x72, 0x65, 0x70, 0x6f, + 0x72, 0x74, 0x6f, 0x6e, 0x6c, 0x69, 0x6e, 0x65, 0x73, 0x71, 0x75, 0x61, 0x72, + 0x65, 0x62, 0x75, 0x74, 0x74, 0x6f, 0x6e, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x73, + 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x6d, 0x6f, 0x76, 0x69, 0x6e, 0x67, 0x6c, + 0x61, 0x74, 0x65, 0x73, 0x74, 0x77, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x46, 0x72, + 0x61, 0x6e, 0x63, 0x65, 0x70, 0x65, 0x72, 0x69, 0x6f, 0x64, 0x73, 0x74, 0x72, + 0x6f, 0x6e, 0x67, 0x72, 0x65, 0x70, 0x65, 0x61, 0x74, 0x4c, 0x6f, 0x6e, 0x64, + 0x6f, 0x6e, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x66, 0x6f, 0x72, 0x6d, 0x65, + 0x64, 0x64, 0x65, 0x6d, 0x61, 0x6e, 0x64, 0x73, 0x65, 0x63, 0x75, 0x72, 0x65, + 0x70, 0x61, 0x73, 0x73, 0x65, 0x64, 0x74, 0x6f, 0x67, 0x67, 0x6c, 0x65, 0x70, + 0x6c, 0x61, 0x63, 0x65, 0x73, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x73, 0x74, + 0x61, 0x74, 0x69, 0x63, 0x63, 0x69, 0x74, 0x69, 0x65, 0x73, 0x73, 0x74, 0x72, + 0x65, 0x61, 0x6d, 0x79, 0x65, 0x6c, 0x6c, 0x6f, 0x77, 0x61, 0x74, 0x74, 0x61, + 0x63, 0x6b, 0x73, 0x74, 0x72, 0x65, 0x65, 0x74, 0x66, 0x6c, 0x69, 0x67, 0x68, + 0x74, 0x68, 0x69, 0x64, 0x64, 0x65, 0x6e, 0x69, 0x6e, 0x66, 0x6f, 0x22, 0x3e, + 0x6f, 0x70, 0x65, 0x6e, 0x65, 0x64, 0x75, 0x73, 0x65, 0x66, 0x75, 0x6c, 0x76, + 0x61, 0x6c, 0x6c, 0x65, 0x79, 0x63, 0x61, 0x75, 0x73, 0x65, 0x73, 0x6c, 0x65, + 0x61, 0x64, 0x65, 0x72, 0x73, 0x65, 0x63, 0x72, 0x65, 0x74, 0x73, 0x65, 0x63, + 0x6f, 0x6e, 0x64, 0x64, 0x61, 0x6d, 0x61, 0x67, 0x65, 0x73, 0x70, 0x6f, 0x72, + 0x74, 0x73, 0x65, 0x78, 0x63, 0x65, 0x70, 0x74, 0x72, 0x61, 0x74, 0x69, 0x6e, + 0x67, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x74, 0x68, 0x69, 0x6e, 0x67, 0x73, + 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x73, + 0x74, 0x61, 0x74, 0x65, 0x73, 0x6f, 0x66, 0x66, 0x69, 0x63, 0x65, 0x76, 0x69, + 0x73, 0x75, 0x61, 0x6c, 0x65, 0x64, 0x69, 0x74, 0x6f, 0x72, 0x76, 0x6f, 0x6c, + 0x75, 0x6d, 0x65, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x6d, 0x75, 0x73, 0x65, + 0x75, 0x6d, 0x6d, 0x6f, 0x76, 0x69, 0x65, 0x73, 0x70, 0x61, 0x72, 0x65, 0x6e, + 0x74, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x6d, 0x6f, 0x73, 0x74, 0x6c, 0x79, + 0x6d, 0x6f, 0x74, 0x68, 0x65, 0x72, 0x22, 0x20, 0x69, 0x64, 0x3d, 0x22, 0x6d, + 0x61, 0x72, 0x6b, 0x65, 0x74, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x63, 0x68, + 0x61, 0x6e, 0x63, 0x65, 0x73, 0x75, 0x72, 0x76, 0x65, 0x79, 0x62, 0x65, 0x66, + 0x6f, 0x72, 0x65, 0x73, 0x79, 0x6d, 0x62, 0x6f, 0x6c, 0x6d, 0x6f, 0x6d, 0x65, + 0x6e, 0x74, 0x73, 0x70, 0x65, 0x65, 0x63, 0x68, 0x6d, 0x6f, 0x74, 0x69, 0x6f, + 0x6e, 0x69, 0x6e, 0x73, 0x69, 0x64, 0x65, 0x6d, 0x61, 0x74, 0x74, 0x65, 0x72, + 0x43, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x65, + 0x78, 0x69, 0x73, 0x74, 0x73, 0x6d, 0x69, 0x64, 0x64, 0x6c, 0x65, 0x45, 0x75, + 0x72, 0x6f, 0x70, 0x65, 0x67, 0x72, 0x6f, 0x77, 0x74, 0x68, 0x6c, 0x65, 0x67, + 0x61, 0x63, 0x79, 0x6d, 0x61, 0x6e, 0x6e, 0x65, 0x72, 0x65, 0x6e, 0x6f, 0x75, + 0x67, 0x68, 0x63, 0x61, 0x72, 0x65, 0x65, 0x72, 0x61, 0x6e, 0x73, 0x77, 0x65, + 0x72, 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x70, 0x6f, 0x72, 0x74, 0x61, 0x6c, + 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x72, + 0x61, 0x6e, 0x64, 0x6f, 0x6d, 0x63, 0x6c, 0x6f, 0x73, 0x65, 0x64, 0x74, 0x6f, + 0x70, 0x69, 0x63, 0x73, 0x63, 0x6f, 0x6d, 0x69, 0x6e, 0x67, 0x66, 0x61, 0x74, + 0x68, 0x65, 0x72, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x69, 0x6d, 0x70, + 0x6c, 0x79, 0x72, 0x61, 0x69, 0x73, 0x65, 0x64, 0x65, 0x73, 0x63, 0x61, 0x70, + 0x65, 0x63, 0x68, 0x6f, 0x73, 0x65, 0x6e, 0x63, 0x68, 0x75, 0x72, 0x63, 0x68, + 0x64, 0x65, 0x66, 0x69, 0x6e, 0x65, 0x72, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x63, + 0x6f, 0x72, 0x6e, 0x65, 0x72, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x6d, 0x65, + 0x6d, 0x6f, 0x72, 0x79, 0x69, 0x66, 0x72, 0x61, 0x6d, 0x65, 0x70, 0x6f, 0x6c, + 0x69, 0x63, 0x65, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x73, 0x4e, 0x75, 0x6d, 0x62, + 0x65, 0x72, 0x64, 0x75, 0x72, 0x69, 0x6e, 0x67, 0x6f, 0x66, 0x66, 0x65, 0x72, + 0x73, 0x73, 0x74, 0x79, 0x6c, 0x65, 0x73, 0x6b, 0x69, 0x6c, 0x6c, 0x65, 0x64, + 0x6c, 0x69, 0x73, 0x74, 0x65, 0x64, 0x63, 0x61, 0x6c, 0x6c, 0x65, 0x64, 0x73, + 0x69, 0x6c, 0x76, 0x65, 0x72, 0x6d, 0x61, 0x72, 0x67, 0x69, 0x6e, 0x64, 0x65, + 0x6c, 0x65, 0x74, 0x65, 0x62, 0x65, 0x74, 0x74, 0x65, 0x72, 0x62, 0x72, 0x6f, + 0x77, 0x73, 0x65, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x73, 0x47, 0x6c, 0x6f, 0x62, + 0x61, 0x6c, 0x73, 0x69, 0x6e, 0x67, 0x6c, 0x65, 0x77, 0x69, 0x64, 0x67, 0x65, + 0x74, 0x63, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x62, 0x75, 0x64, 0x67, 0x65, 0x74, + 0x6e, 0x6f, 0x77, 0x72, 0x61, 0x70, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x63, + 0x6c, 0x61, 0x69, 0x6d, 0x73, 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x73, 0x61, + 0x66, 0x65, 0x74, 0x79, 0x63, 0x68, 0x6f, 0x69, 0x63, 0x65, 0x73, 0x70, 0x69, + 0x72, 0x69, 0x74, 0x2d, 0x73, 0x74, 0x79, 0x6c, 0x65, 0x73, 0x70, 0x72, 0x65, + 0x61, 0x64, 0x6d, 0x61, 0x6b, 0x69, 0x6e, 0x67, 0x6e, 0x65, 0x65, 0x64, 0x65, + 0x64, 0x72, 0x75, 0x73, 0x73, 0x69, 0x61, 0x70, 0x6c, 0x65, 0x61, 0x73, 0x65, + 0x65, 0x78, 0x74, 0x65, 0x6e, 0x74, 0x53, 0x63, 0x72, 0x69, 0x70, 0x74, 0x62, + 0x72, 0x6f, 0x6b, 0x65, 0x6e, 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x73, 0x63, 0x68, + 0x61, 0x72, 0x67, 0x65, 0x64, 0x69, 0x76, 0x69, 0x64, 0x65, 0x66, 0x61, 0x63, + 0x74, 0x6f, 0x72, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x2d, 0x62, 0x61, 0x73, + 0x65, 0x64, 0x74, 0x68, 0x65, 0x6f, 0x72, 0x79, 0x63, 0x6f, 0x6e, 0x66, 0x69, + 0x67, 0x61, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x77, 0x6f, 0x72, 0x6b, 0x65, 0x64, + 0x68, 0x65, 0x6c, 0x70, 0x65, 0x64, 0x43, 0x68, 0x75, 0x72, 0x63, 0x68, 0x69, + 0x6d, 0x70, 0x61, 0x63, 0x74, 0x73, 0x68, 0x6f, 0x75, 0x6c, 0x64, 0x61, 0x6c, + 0x77, 0x61, 0x79, 0x73, 0x6c, 0x6f, 0x67, 0x6f, 0x22, 0x20, 0x62, 0x6f, 0x74, + 0x74, 0x6f, 0x6d, 0x6c, 0x69, 0x73, 0x74, 0x22, 0x3e, 0x29, 0x7b, 0x76, 0x61, + 0x72, 0x20, 0x70, 0x72, 0x65, 0x66, 0x69, 0x78, 0x6f, 0x72, 0x61, 0x6e, 0x67, + 0x65, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x2e, 0x70, 0x75, 0x73, 0x68, 0x28, + 0x63, 0x6f, 0x75, 0x70, 0x6c, 0x65, 0x67, 0x61, 0x72, 0x64, 0x65, 0x6e, 0x62, + 0x72, 0x69, 0x64, 0x67, 0x65, 0x6c, 0x61, 0x75, 0x6e, 0x63, 0x68, 0x52, 0x65, + 0x76, 0x69, 0x65, 0x77, 0x74, 0x61, 0x6b, 0x69, 0x6e, 0x67, 0x76, 0x69, 0x73, + 0x69, 0x6f, 0x6e, 0x6c, 0x69, 0x74, 0x74, 0x6c, 0x65, 0x64, 0x61, 0x74, 0x69, + 0x6e, 0x67, 0x42, 0x75, 0x74, 0x74, 0x6f, 0x6e, 0x62, 0x65, 0x61, 0x75, 0x74, + 0x79, 0x74, 0x68, 0x65, 0x6d, 0x65, 0x73, 0x66, 0x6f, 0x72, 0x67, 0x6f, 0x74, + 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x61, 0x6e, 0x63, 0x68, 0x6f, 0x72, 0x61, + 0x6c, 0x6d, 0x6f, 0x73, 0x74, 0x6c, 0x6f, 0x61, 0x64, 0x65, 0x64, 0x43, 0x68, + 0x61, 0x6e, 0x67, 0x65, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x73, 0x74, 0x72, + 0x69, 0x6e, 0x67, 0x72, 0x65, 0x6c, 0x6f, 0x61, 0x64, 0x4d, 0x6f, 0x62, 0x69, + 0x6c, 0x65, 0x69, 0x6e, 0x63, 0x6f, 0x6d, 0x65, 0x73, 0x75, 0x70, 0x70, 0x6c, + 0x79, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x73, + 0x76, 0x69, 0x65, 0x77, 0x65, 0x64, 0x26, 0x6e, 0x62, 0x73, 0x70, 0x3b, 0x63, + 0x6f, 0x75, 0x72, 0x73, 0x65, 0x41, 0x62, 0x6f, 0x75, 0x74, 0x20, 0x69, 0x73, + 0x6c, 0x61, 0x6e, 0x64, 0x3c, 0x68, 0x74, 0x6d, 0x6c, 0x20, 0x63, 0x6f, 0x6f, + 0x6b, 0x69, 0x65, 0x6e, 0x61, 0x6d, 0x65, 0x3d, 0x22, 0x61, 0x6d, 0x61, 0x7a, + 0x6f, 0x6e, 0x6d, 0x6f, 0x64, 0x65, 0x72, 0x6e, 0x61, 0x64, 0x76, 0x69, 0x63, + 0x65, 0x69, 0x6e, 0x3c, 0x2f, 0x61, 0x3e, 0x3a, 0x20, 0x54, 0x68, 0x65, 0x20, + 0x64, 0x69, 0x61, 0x6c, 0x6f, 0x67, 0x68, 0x6f, 0x75, 0x73, 0x65, 0x73, 0x42, + 0x45, 0x47, 0x49, 0x4e, 0x20, 0x4d, 0x65, 0x78, 0x69, 0x63, 0x6f, 0x73, 0x74, + 0x61, 0x72, 0x74, 0x73, 0x63, 0x65, 0x6e, 0x74, 0x72, 0x65, 0x68, 0x65, 0x69, + 0x67, 0x68, 0x74, 0x61, 0x64, 0x64, 0x69, 0x6e, 0x67, 0x49, 0x73, 0x6c, 0x61, + 0x6e, 0x64, 0x61, 0x73, 0x73, 0x65, 0x74, 0x73, 0x45, 0x6d, 0x70, 0x69, 0x72, + 0x65, 0x53, 0x63, 0x68, 0x6f, 0x6f, 0x6c, 0x65, 0x66, 0x66, 0x6f, 0x72, 0x74, + 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6e, 0x65, 0x61, 0x72, 0x6c, 0x79, 0x6d, + 0x61, 0x6e, 0x75, 0x61, 0x6c, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x2e, 0x0a, + 0x0a, 0x4f, 0x6e, 0x65, 0x6a, 0x6f, 0x69, 0x6e, 0x65, 0x64, 0x6d, 0x65, 0x6e, + 0x75, 0x22, 0x3e, 0x50, 0x68, 0x69, 0x6c, 0x69, 0x70, 0x61, 0x77, 0x61, 0x72, + 0x64, 0x73, 0x68, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x69, 0x6d, 0x70, 0x6f, 0x72, + 0x74, 0x4f, 0x66, 0x66, 0x69, 0x63, 0x65, 0x72, 0x65, 0x67, 0x61, 0x72, 0x64, + 0x73, 0x6b, 0x69, 0x6c, 0x6c, 0x73, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, + 0x70, 0x6f, 0x72, 0x74, 0x73, 0x64, 0x65, 0x67, 0x72, 0x65, 0x65, 0x77, 0x65, + 0x65, 0x6b, 0x6c, 0x79, 0x20, 0x28, 0x65, 0x2e, 0x67, 0x2e, 0x62, 0x65, 0x68, + 0x69, 0x6e, 0x64, 0x64, 0x6f, 0x63, 0x74, 0x6f, 0x72, 0x6c, 0x6f, 0x67, 0x67, + 0x65, 0x64, 0x75, 0x6e, 0x69, 0x74, 0x65, 0x64, 0x3c, 0x2f, 0x62, 0x3e, 0x3c, + 0x2f, 0x62, 0x65, 0x67, 0x69, 0x6e, 0x73, 0x70, 0x6c, 0x61, 0x6e, 0x74, 0x73, + 0x61, 0x73, 0x73, 0x69, 0x73, 0x74, 0x61, 0x72, 0x74, 0x69, 0x73, 0x74, 0x69, + 0x73, 0x73, 0x75, 0x65, 0x64, 0x33, 0x30, 0x30, 0x70, 0x78, 0x7c, 0x63, 0x61, + 0x6e, 0x61, 0x64, 0x61, 0x61, 0x67, 0x65, 0x6e, 0x63, 0x79, 0x73, 0x63, 0x68, + 0x65, 0x6d, 0x65, 0x72, 0x65, 0x6d, 0x61, 0x69, 0x6e, 0x42, 0x72, 0x61, 0x7a, + 0x69, 0x6c, 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x6c, 0x6f, 0x67, 0x6f, 0x22, + 0x3e, 0x62, 0x65, 0x79, 0x6f, 0x6e, 0x64, 0x2d, 0x73, 0x63, 0x61, 0x6c, 0x65, + 0x61, 0x63, 0x63, 0x65, 0x70, 0x74, 0x73, 0x65, 0x72, 0x76, 0x65, 0x64, 0x6d, + 0x61, 0x72, 0x69, 0x6e, 0x65, 0x46, 0x6f, 0x6f, 0x74, 0x65, 0x72, 0x63, 0x61, + 0x6d, 0x65, 0x72, 0x61, 0x3c, 0x2f, 0x68, 0x31, 0x3e, 0x0a, 0x5f, 0x66, 0x6f, + 0x72, 0x6d, 0x22, 0x6c, 0x65, 0x61, 0x76, 0x65, 0x73, 0x73, 0x74, 0x72, 0x65, + 0x73, 0x73, 0x22, 0x20, 0x2f, 0x3e, 0x0d, 0x0a, 0x2e, 0x67, 0x69, 0x66, 0x22, + 0x20, 0x6f, 0x6e, 0x6c, 0x6f, 0x61, 0x64, 0x6c, 0x6f, 0x61, 0x64, 0x65, 0x72, + 0x4f, 0x78, 0x66, 0x6f, 0x72, 0x64, 0x73, 0x69, 0x73, 0x74, 0x65, 0x72, 0x73, + 0x75, 0x72, 0x76, 0x69, 0x76, 0x6c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x66, 0x65, + 0x6d, 0x61, 0x6c, 0x65, 0x44, 0x65, 0x73, 0x69, 0x67, 0x6e, 0x73, 0x69, 0x7a, + 0x65, 0x3d, 0x22, 0x61, 0x70, 0x70, 0x65, 0x61, 0x6c, 0x74, 0x65, 0x78, 0x74, + 0x22, 0x3e, 0x6c, 0x65, 0x76, 0x65, 0x6c, 0x73, 0x74, 0x68, 0x61, 0x6e, 0x6b, + 0x73, 0x68, 0x69, 0x67, 0x68, 0x65, 0x72, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x64, + 0x61, 0x6e, 0x69, 0x6d, 0x61, 0x6c, 0x61, 0x6e, 0x79, 0x6f, 0x6e, 0x65, 0x41, + 0x66, 0x72, 0x69, 0x63, 0x61, 0x61, 0x67, 0x72, 0x65, 0x65, 0x64, 0x72, 0x65, + 0x63, 0x65, 0x6e, 0x74, 0x50, 0x65, 0x6f, 0x70, 0x6c, 0x65, 0x3c, 0x62, 0x72, + 0x20, 0x2f, 0x3e, 0x77, 0x6f, 0x6e, 0x64, 0x65, 0x72, 0x70, 0x72, 0x69, 0x63, + 0x65, 0x73, 0x74, 0x75, 0x72, 0x6e, 0x65, 0x64, 0x7c, 0x7c, 0x20, 0x7b, 0x7d, + 0x3b, 0x6d, 0x61, 0x69, 0x6e, 0x22, 0x3e, 0x69, 0x6e, 0x6c, 0x69, 0x6e, 0x65, + 0x73, 0x75, 0x6e, 0x64, 0x61, 0x79, 0x77, 0x72, 0x61, 0x70, 0x22, 0x3e, 0x66, + 0x61, 0x69, 0x6c, 0x65, 0x64, 0x63, 0x65, 0x6e, 0x73, 0x75, 0x73, 0x6d, 0x69, + 0x6e, 0x75, 0x74, 0x65, 0x62, 0x65, 0x61, 0x63, 0x6f, 0x6e, 0x71, 0x75, 0x6f, + 0x74, 0x65, 0x73, 0x31, 0x35, 0x30, 0x70, 0x78, 0x7c, 0x65, 0x73, 0x74, 0x61, + 0x74, 0x65, 0x72, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x65, 0x6d, 0x61, 0x69, 0x6c, + 0x22, 0x6c, 0x69, 0x6e, 0x6b, 0x65, 0x64, 0x72, 0x69, 0x67, 0x68, 0x74, 0x3b, + 0x73, 0x69, 0x67, 0x6e, 0x61, 0x6c, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x6c, 0x31, + 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0x73, 0x69, 0x67, 0x6e, 0x75, 0x70, 0x70, 0x72, + 0x69, 0x6e, 0x63, 0x65, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x3a, 0x2e, 0x70, 0x6e, + 0x67, 0x22, 0x20, 0x66, 0x6f, 0x72, 0x75, 0x6d, 0x2e, 0x41, 0x63, 0x63, 0x65, + 0x73, 0x73, 0x70, 0x61, 0x70, 0x65, 0x72, 0x73, 0x73, 0x6f, 0x75, 0x6e, 0x64, + 0x73, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x64, 0x48, 0x65, 0x69, 0x67, 0x68, 0x74, + 0x73, 0x6c, 0x69, 0x64, 0x65, 0x72, 0x55, 0x54, 0x46, 0x2d, 0x38, 0x22, 0x26, + 0x61, 0x6d, 0x70, 0x3b, 0x20, 0x42, 0x65, 0x66, 0x6f, 0x72, 0x65, 0x2e, 0x20, + 0x57, 0x69, 0x74, 0x68, 0x73, 0x74, 0x75, 0x64, 0x69, 0x6f, 0x6f, 0x77, 0x6e, + 0x65, 0x72, 0x73, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x70, 0x72, 0x6f, 0x66, + 0x69, 0x74, 0x6a, 0x51, 0x75, 0x65, 0x72, 0x79, 0x61, 0x6e, 0x6e, 0x75, 0x61, + 0x6c, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x62, 0x6f, 0x75, 0x67, 0x68, 0x74, + 0x66, 0x61, 0x6d, 0x6f, 0x75, 0x73, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x6c, + 0x6f, 0x6e, 0x67, 0x65, 0x72, 0x69, 0x2b, 0x2b, 0x29, 0x20, 0x7b, 0x69, 0x73, + 0x72, 0x61, 0x65, 0x6c, 0x73, 0x61, 0x79, 0x69, 0x6e, 0x67, 0x64, 0x65, 0x63, + 0x69, 0x64, 0x65, 0x68, 0x6f, 0x6d, 0x65, 0x22, 0x3e, 0x68, 0x65, 0x61, 0x64, + 0x65, 0x72, 0x65, 0x6e, 0x73, 0x75, 0x72, 0x65, 0x62, 0x72, 0x61, 0x6e, 0x63, + 0x68, 0x70, 0x69, 0x65, 0x63, 0x65, 0x73, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x3b, + 0x73, 0x74, 0x61, 0x74, 0x65, 0x64, 0x74, 0x6f, 0x70, 0x22, 0x3e, 0x3c, 0x72, + 0x61, 0x63, 0x69, 0x6e, 0x67, 0x72, 0x65, 0x73, 0x69, 0x7a, 0x65, 0x2d, 0x2d, + 0x26, 0x67, 0x74, 0x3b, 0x70, 0x61, 0x63, 0x69, 0x74, 0x79, 0x73, 0x65, 0x78, + 0x75, 0x61, 0x6c, 0x62, 0x75, 0x72, 0x65, 0x61, 0x75, 0x2e, 0x6a, 0x70, 0x67, + 0x22, 0x20, 0x31, 0x30, 0x2c, 0x30, 0x30, 0x30, 0x6f, 0x62, 0x74, 0x61, 0x69, + 0x6e, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x73, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, + 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x63, 0x6f, 0x6d, 0x65, 0x64, 0x79, 0x6d, + 0x65, 0x6e, 0x75, 0x22, 0x20, 0x6c, 0x79, 0x72, 0x69, 0x63, 0x73, 0x74, 0x6f, + 0x64, 0x61, 0x79, 0x2e, 0x69, 0x6e, 0x64, 0x65, 0x65, 0x64, 0x63, 0x6f, 0x75, + 0x6e, 0x74, 0x79, 0x5f, 0x6c, 0x6f, 0x67, 0x6f, 0x2e, 0x46, 0x61, 0x6d, 0x69, + 0x6c, 0x79, 0x6c, 0x6f, 0x6f, 0x6b, 0x65, 0x64, 0x4d, 0x61, 0x72, 0x6b, 0x65, + 0x74, 0x6c, 0x73, 0x65, 0x20, 0x69, 0x66, 0x50, 0x6c, 0x61, 0x79, 0x65, 0x72, + 0x74, 0x75, 0x72, 0x6b, 0x65, 0x79, 0x29, 0x3b, 0x76, 0x61, 0x72, 0x20, 0x66, + 0x6f, 0x72, 0x65, 0x73, 0x74, 0x67, 0x69, 0x76, 0x69, 0x6e, 0x67, 0x65, 0x72, + 0x72, 0x6f, 0x72, 0x73, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x7d, 0x65, 0x6c, + 0x73, 0x65, 0x7b, 0x69, 0x6e, 0x73, 0x65, 0x72, 0x74, 0x42, 0x6c, 0x6f, 0x67, + 0x3c, 0x2f, 0x66, 0x6f, 0x6f, 0x74, 0x65, 0x72, 0x6c, 0x6f, 0x67, 0x69, 0x6e, + 0x2e, 0x66, 0x61, 0x73, 0x74, 0x65, 0x72, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x73, + 0x3c, 0x62, 0x6f, 0x64, 0x79, 0x20, 0x31, 0x30, 0x70, 0x78, 0x20, 0x30, 0x70, + 0x72, 0x61, 0x67, 0x6d, 0x61, 0x66, 0x72, 0x69, 0x64, 0x61, 0x79, 0x6a, 0x75, + 0x6e, 0x69, 0x6f, 0x72, 0x64, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x70, 0x6c, 0x61, + 0x63, 0x65, 0x64, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x73, 0x70, 0x6c, 0x75, 0x67, + 0x69, 0x6e, 0x35, 0x2c, 0x30, 0x30, 0x30, 0x20, 0x70, 0x61, 0x67, 0x65, 0x22, + 0x3e, 0x62, 0x6f, 0x73, 0x74, 0x6f, 0x6e, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x28, + 0x61, 0x76, 0x61, 0x74, 0x61, 0x72, 0x74, 0x65, 0x73, 0x74, 0x65, 0x64, 0x5f, + 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x66, 0x6f, 0x72, 0x75, 0x6d, 0x73, 0x73, 0x63, + 0x68, 0x65, 0x6d, 0x61, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x2c, 0x66, 0x69, 0x6c, + 0x6c, 0x65, 0x64, 0x73, 0x68, 0x61, 0x72, 0x65, 0x73, 0x72, 0x65, 0x61, 0x64, + 0x65, 0x72, 0x61, 0x6c, 0x65, 0x72, 0x74, 0x28, 0x61, 0x70, 0x70, 0x65, 0x61, + 0x72, 0x53, 0x75, 0x62, 0x6d, 0x69, 0x74, 0x6c, 0x69, 0x6e, 0x65, 0x22, 0x3e, + 0x62, 0x6f, 0x64, 0x79, 0x22, 0x3e, 0x0a, 0x2a, 0x20, 0x54, 0x68, 0x65, 0x54, + 0x68, 0x6f, 0x75, 0x67, 0x68, 0x73, 0x65, 0x65, 0x69, 0x6e, 0x67, 0x6a, 0x65, + 0x72, 0x73, 0x65, 0x79, 0x4e, 0x65, 0x77, 0x73, 0x3c, 0x2f, 0x76, 0x65, 0x72, + 0x69, 0x66, 0x79, 0x65, 0x78, 0x70, 0x65, 0x72, 0x74, 0x69, 0x6e, 0x6a, 0x75, + 0x72, 0x79, 0x77, 0x69, 0x64, 0x74, 0x68, 0x3d, 0x43, 0x6f, 0x6f, 0x6b, 0x69, + 0x65, 0x53, 0x54, 0x41, 0x52, 0x54, 0x20, 0x61, 0x63, 0x72, 0x6f, 0x73, 0x73, + 0x5f, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x74, 0x68, 0x72, 0x65, 0x61, 0x64, 0x6e, + 0x61, 0x74, 0x69, 0x76, 0x65, 0x70, 0x6f, 0x63, 0x6b, 0x65, 0x74, 0x62, 0x6f, + 0x78, 0x22, 0x3e, 0x0a, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x20, 0x44, 0x61, + 0x76, 0x69, 0x64, 0x63, 0x61, 0x6e, 0x63, 0x65, 0x72, 0x74, 0x61, 0x62, 0x6c, + 0x65, 0x73, 0x70, 0x72, 0x6f, 0x76, 0x65, 0x64, 0x41, 0x70, 0x72, 0x69, 0x6c, + 0x20, 0x72, 0x65, 0x61, 0x6c, 0x6c, 0x79, 0x64, 0x72, 0x69, 0x76, 0x65, 0x72, + 0x69, 0x74, 0x65, 0x6d, 0x22, 0x3e, 0x6d, 0x6f, 0x72, 0x65, 0x22, 0x3e, 0x62, + 0x6f, 0x61, 0x72, 0x64, 0x73, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x73, 0x63, 0x61, + 0x6d, 0x70, 0x75, 0x73, 0x66, 0x69, 0x72, 0x73, 0x74, 0x20, 0x7c, 0x7c, 0x20, + 0x5b, 0x5d, 0x3b, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x2e, 0x67, 0x75, 0x69, 0x74, + 0x61, 0x72, 0x66, 0x69, 0x6e, 0x69, 0x73, 0x68, 0x77, 0x69, 0x64, 0x74, 0x68, + 0x3a, 0x73, 0x68, 0x6f, 0x77, 0x65, 0x64, 0x4f, 0x74, 0x68, 0x65, 0x72, 0x20, + 0x2e, 0x70, 0x68, 0x70, 0x22, 0x20, 0x61, 0x73, 0x73, 0x75, 0x6d, 0x65, 0x6c, + 0x61, 0x79, 0x65, 0x72, 0x73, 0x77, 0x69, 0x6c, 0x73, 0x6f, 0x6e, 0x73, 0x74, + 0x6f, 0x72, 0x65, 0x73, 0x72, 0x65, 0x6c, 0x69, 0x65, 0x66, 0x73, 0x77, 0x65, + 0x64, 0x65, 0x6e, 0x43, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x65, 0x61, 0x73, 0x69, + 0x6c, 0x79, 0x20, 0x79, 0x6f, 0x75, 0x72, 0x20, 0x53, 0x74, 0x72, 0x69, 0x6e, + 0x67, 0x0a, 0x0a, 0x57, 0x68, 0x69, 0x6c, 0x74, 0x61, 0x79, 0x6c, 0x6f, 0x72, + 0x63, 0x6c, 0x65, 0x61, 0x72, 0x3a, 0x72, 0x65, 0x73, 0x6f, 0x72, 0x74, 0x66, + 0x72, 0x65, 0x6e, 0x63, 0x68, 0x74, 0x68, 0x6f, 0x75, 0x67, 0x68, 0x22, 0x29, + 0x20, 0x2b, 0x20, 0x22, 0x3c, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0x62, 0x75, 0x79, + 0x69, 0x6e, 0x67, 0x62, 0x72, 0x61, 0x6e, 0x64, 0x73, 0x4d, 0x65, 0x6d, 0x62, + 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x3e, 0x6f, 0x70, 0x70, 0x69, 0x6e, + 0x67, 0x73, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x35, 0x70, 0x78, 0x3b, 0x22, 0x3e, + 0x76, 0x73, 0x70, 0x61, 0x63, 0x65, 0x70, 0x6f, 0x73, 0x74, 0x65, 0x72, 0x6d, + 0x61, 0x6a, 0x6f, 0x72, 0x20, 0x63, 0x6f, 0x66, 0x66, 0x65, 0x65, 0x6d, 0x61, + 0x72, 0x74, 0x69, 0x6e, 0x6d, 0x61, 0x74, 0x75, 0x72, 0x65, 0x68, 0x61, 0x70, + 0x70, 0x65, 0x6e, 0x3c, 0x2f, 0x6e, 0x61, 0x76, 0x3e, 0x6b, 0x61, 0x6e, 0x73, + 0x61, 0x73, 0x6c, 0x69, 0x6e, 0x6b, 0x22, 0x3e, 0x49, 0x6d, 0x61, 0x67, 0x65, + 0x73, 0x3d, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x77, 0x68, 0x69, 0x6c, 0x65, 0x20, + 0x68, 0x73, 0x70, 0x61, 0x63, 0x65, 0x30, 0x26, 0x61, 0x6d, 0x70, 0x3b, 0x20, + 0x0a, 0x0a, 0x49, 0x6e, 0x20, 0x20, 0x70, 0x6f, 0x77, 0x65, 0x72, 0x50, 0x6f, + 0x6c, 0x73, 0x6b, 0x69, 0x2d, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x6a, 0x6f, 0x72, + 0x64, 0x61, 0x6e, 0x42, 0x6f, 0x74, 0x74, 0x6f, 0x6d, 0x53, 0x74, 0x61, 0x72, + 0x74, 0x20, 0x2d, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x32, 0x2e, 0x68, 0x74, 0x6d, + 0x6c, 0x6e, 0x65, 0x77, 0x73, 0x22, 0x3e, 0x30, 0x31, 0x2e, 0x6a, 0x70, 0x67, + 0x4f, 0x6e, 0x6c, 0x69, 0x6e, 0x65, 0x2d, 0x72, 0x69, 0x67, 0x68, 0x74, 0x6d, + 0x69, 0x6c, 0x6c, 0x65, 0x72, 0x73, 0x65, 0x6e, 0x69, 0x6f, 0x72, 0x49, 0x53, + 0x42, 0x4e, 0x20, 0x30, 0x30, 0x2c, 0x30, 0x30, 0x30, 0x20, 0x67, 0x75, 0x69, + 0x64, 0x65, 0x73, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x29, 0x65, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x72, 0x65, 0x70, 0x61, 0x69, 0x72, 0x2e, 0x78, 0x6d, 0x6c, 0x22, + 0x20, 0x20, 0x72, 0x69, 0x67, 0x68, 0x74, 0x73, 0x2e, 0x68, 0x74, 0x6d, 0x6c, + 0x2d, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x72, 0x65, 0x67, 0x45, 0x78, 0x70, 0x3a, + 0x68, 0x6f, 0x76, 0x65, 0x72, 0x77, 0x69, 0x74, 0x68, 0x69, 0x6e, 0x76, 0x69, + 0x72, 0x67, 0x69, 0x6e, 0x70, 0x68, 0x6f, 0x6e, 0x65, 0x73, 0x3c, 0x2f, 0x74, + 0x72, 0x3e, 0x0d, 0x75, 0x73, 0x69, 0x6e, 0x67, 0x20, 0x0a, 0x09, 0x76, 0x61, + 0x72, 0x20, 0x3e, 0x27, 0x29, 0x3b, 0x0a, 0x09, 0x3c, 0x2f, 0x74, 0x64, 0x3e, + 0x0a, 0x3c, 0x2f, 0x74, 0x72, 0x3e, 0x0a, 0x62, 0x61, 0x68, 0x61, 0x73, 0x61, + 0x62, 0x72, 0x61, 0x73, 0x69, 0x6c, 0x67, 0x61, 0x6c, 0x65, 0x67, 0x6f, 0x6d, + 0x61, 0x67, 0x79, 0x61, 0x72, 0x70, 0x6f, 0x6c, 0x73, 0x6b, 0x69, 0x73, 0x72, + 0x70, 0x73, 0x6b, 0x69, 0xd8, 0xb1, 0xd8, 0xaf, 0xd9, 0x88, 0xe4, 0xb8, 0xad, + 0xe6, 0x96, 0x87, 0xe7, 0xae, 0x80, 0xe4, 0xbd, 0x93, 0xe7, 0xb9, 0x81, 0xe9, + 0xab, 0x94, 0xe4, 0xbf, 0xa1, 0xe6, 0x81, 0xaf, 0xe4, 0xb8, 0xad, 0xe5, 0x9b, + 0xbd, 0xe6, 0x88, 0x91, 0xe4, 0xbb, 0xac, 0xe4, 0xb8, 0x80, 0xe4, 0xb8, 0xaa, + 0xe5, 0x85, 0xac, 0xe5, 0x8f, 0xb8, 0xe7, 0xae, 0xa1, 0xe7, 0x90, 0x86, 0xe8, + 0xae, 0xba, 0xe5, 0x9d, 0x9b, 0xe5, 0x8f, 0xaf, 0xe4, 0xbb, 0xa5, 0xe6, 0x9c, + 0x8d, 0xe5, 0x8a, 0xa1, 0xe6, 0x97, 0xb6, 0xe9, 0x97, 0xb4, 0xe4, 0xb8, 0xaa, + 0xe4, 0xba, 0xba, 0xe4, 0xba, 0xa7, 0xe5, 0x93, 0x81, 0xe8, 0x87, 0xaa, 0xe5, + 0xb7, 0xb1, 0xe4, 0xbc, 0x81, 0xe4, 0xb8, 0x9a, 0xe6, 0x9f, 0xa5, 0xe7, 0x9c, + 0x8b, 0xe5, 0xb7, 0xa5, 0xe4, 0xbd, 0x9c, 0xe8, 0x81, 0x94, 0xe7, 0xb3, 0xbb, + 0xe6, 0xb2, 0xa1, 0xe6, 0x9c, 0x89, 0xe7, 0xbd, 0x91, 0xe7, 0xab, 0x99, 0xe6, + 0x89, 0x80, 0xe6, 0x9c, 0x89, 0xe8, 0xaf, 0x84, 0xe8, 0xae, 0xba, 0xe4, 0xb8, + 0xad, 0xe5, 0xbf, 0x83, 0xe6, 0x96, 0x87, 0xe7, 0xab, 0xa0, 0xe7, 0x94, 0xa8, + 0xe6, 0x88, 0xb7, 0xe9, 0xa6, 0x96, 0xe9, 0xa1, 0xb5, 0xe4, 0xbd, 0x9c, 0xe8, + 0x80, 0x85, 0xe6, 0x8a, 0x80, 0xe6, 0x9c, 0xaf, 0xe9, 0x97, 0xae, 0xe9, 0xa2, + 0x98, 0xe7, 0x9b, 0xb8, 0xe5, 0x85, 0xb3, 0xe4, 0xb8, 0x8b, 0xe8, 0xbd, 0xbd, + 0xe6, 0x90, 0x9c, 0xe7, 0xb4, 0xa2, 0xe4, 0xbd, 0xbf, 0xe7, 0x94, 0xa8, 0xe8, + 0xbd, 0xaf, 0xe4, 0xbb, 0xb6, 0xe5, 0x9c, 0xa8, 0xe7, 0xba, 0xbf, 0xe4, 0xb8, + 0xbb, 0xe9, 0xa2, 0x98, 0xe8, 0xb5, 0x84, 0xe6, 0x96, 0x99, 0xe8, 0xa7, 0x86, + 0xe9, 0xa2, 0x91, 0xe5, 0x9b, 0x9e, 0xe5, 0xa4, 0x8d, 0xe6, 0xb3, 0xa8, 0xe5, + 0x86, 0x8c, 0xe7, 0xbd, 0x91, 0xe7, 0xbb, 0x9c, 0xe6, 0x94, 0xb6, 0xe8, 0x97, + 0x8f, 0xe5, 0x86, 0x85, 0xe5, 0xae, 0xb9, 0xe6, 0x8e, 0xa8, 0xe8, 0x8d, 0x90, + 0xe5, 0xb8, 0x82, 0xe5, 0x9c, 0xba, 0xe6, 0xb6, 0x88, 0xe6, 0x81, 0xaf, 0xe7, + 0xa9, 0xba, 0xe9, 0x97, 0xb4, 0xe5, 0x8f, 0x91, 0xe5, 0xb8, 0x83, 0xe4, 0xbb, + 0x80, 0xe4, 0xb9, 0x88, 0xe5, 0xa5, 0xbd, 0xe5, 0x8f, 0x8b, 0xe7, 0x94, 0x9f, + 0xe6, 0xb4, 0xbb, 0xe5, 0x9b, 0xbe, 0xe7, 0x89, 0x87, 0xe5, 0x8f, 0x91, 0xe5, + 0xb1, 0x95, 0xe5, 0xa6, 0x82, 0xe6, 0x9e, 0x9c, 0xe6, 0x89, 0x8b, 0xe6, 0x9c, + 0xba, 0xe6, 0x96, 0xb0, 0xe9, 0x97, 0xbb, 0xe6, 0x9c, 0x80, 0xe6, 0x96, 0xb0, + 0xe6, 0x96, 0xb9, 0xe5, 0xbc, 0x8f, 0xe5, 0x8c, 0x97, 0xe4, 0xba, 0xac, 0xe6, + 0x8f, 0x90, 0xe4, 0xbe, 0x9b, 0xe5, 0x85, 0xb3, 0xe4, 0xba, 0x8e, 0xe6, 0x9b, + 0xb4, 0xe5, 0xa4, 0x9a, 0xe8, 0xbf, 0x99, 0xe4, 0xb8, 0xaa, 0xe7, 0xb3, 0xbb, + 0xe7, 0xbb, 0x9f, 0xe7, 0x9f, 0xa5, 0xe9, 0x81, 0x93, 0xe6, 0xb8, 0xb8, 0xe6, + 0x88, 0x8f, 0xe5, 0xb9, 0xbf, 0xe5, 0x91, 0x8a, 0xe5, 0x85, 0xb6, 0xe4, 0xbb, + 0x96, 0xe5, 0x8f, 0x91, 0xe8, 0xa1, 0xa8, 0xe5, 0xae, 0x89, 0xe5, 0x85, 0xa8, + 0xe7, 0xac, 0xac, 0xe4, 0xb8, 0x80, 0xe4, 0xbc, 0x9a, 0xe5, 0x91, 0x98, 0xe8, + 0xbf, 0x9b, 0xe8, 0xa1, 0x8c, 0xe7, 0x82, 0xb9, 0xe5, 0x87, 0xbb, 0xe7, 0x89, + 0x88, 0xe6, 0x9d, 0x83, 0xe7, 0x94, 0xb5, 0xe5, 0xad, 0x90, 0xe4, 0xb8, 0x96, + 0xe7, 0x95, 0x8c, 0xe8, 0xae, 0xbe, 0xe8, 0xae, 0xa1, 0xe5, 0x85, 0x8d, 0xe8, + 0xb4, 0xb9, 0xe6, 0x95, 0x99, 0xe8, 0x82, 0xb2, 0xe5, 0x8a, 0xa0, 0xe5, 0x85, + 0xa5, 0xe6, 0xb4, 0xbb, 0xe5, 0x8a, 0xa8, 0xe4, 0xbb, 0x96, 0xe4, 0xbb, 0xac, + 0xe5, 0x95, 0x86, 0xe5, 0x93, 0x81, 0xe5, 0x8d, 0x9a, 0xe5, 0xae, 0xa2, 0xe7, + 0x8e, 0xb0, 0xe5, 0x9c, 0xa8, 0xe4, 0xb8, 0x8a, 0xe6, 0xb5, 0xb7, 0xe5, 0xa6, + 0x82, 0xe4, 0xbd, 0x95, 0xe5, 0xb7, 0xb2, 0xe7, 0xbb, 0x8f, 0xe7, 0x95, 0x99, + 0xe8, 0xa8, 0x80, 0xe8, 0xaf, 0xa6, 0xe7, 0xbb, 0x86, 0xe7, 0xa4, 0xbe, 0xe5, + 0x8c, 0xba, 0xe7, 0x99, 0xbb, 0xe5, 0xbd, 0x95, 0xe6, 0x9c, 0xac, 0xe7, 0xab, + 0x99, 0xe9, 0x9c, 0x80, 0xe8, 0xa6, 0x81, 0xe4, 0xbb, 0xb7, 0xe6, 0xa0, 0xbc, + 0xe6, 0x94, 0xaf, 0xe6, 0x8c, 0x81, 0xe5, 0x9b, 0xbd, 0xe9, 0x99, 0x85, 0xe9, + 0x93, 0xbe, 0xe6, 0x8e, 0xa5, 0xe5, 0x9b, 0xbd, 0xe5, 0xae, 0xb6, 0xe5, 0xbb, + 0xba, 0xe8, 0xae, 0xbe, 0xe6, 0x9c, 0x8b, 0xe5, 0x8f, 0x8b, 0xe9, 0x98, 0x85, + 0xe8, 0xaf, 0xbb, 0xe6, 0xb3, 0x95, 0xe5, 0xbe, 0x8b, 0xe4, 0xbd, 0x8d, 0xe7, + 0xbd, 0xae, 0xe7, 0xbb, 0x8f, 0xe6, 0xb5, 0x8e, 0xe9, 0x80, 0x89, 0xe6, 0x8b, + 0xa9, 0xe8, 0xbf, 0x99, 0xe6, 0xa0, 0xb7, 0xe5, 0xbd, 0x93, 0xe5, 0x89, 0x8d, + 0xe5, 0x88, 0x86, 0xe7, 0xb1, 0xbb, 0xe6, 0x8e, 0x92, 0xe8, 0xa1, 0x8c, 0xe5, + 0x9b, 0xa0, 0xe4, 0xb8, 0xba, 0xe4, 0xba, 0xa4, 0xe6, 0x98, 0x93, 0xe6, 0x9c, + 0x80, 0xe5, 0x90, 0x8e, 0xe9, 0x9f, 0xb3, 0xe4, 0xb9, 0x90, 0xe4, 0xb8, 0x8d, + 0xe8, 0x83, 0xbd, 0xe9, 0x80, 0x9a, 0xe8, 0xbf, 0x87, 0xe8, 0xa1, 0x8c, 0xe4, + 0xb8, 0x9a, 0xe7, 0xa7, 0x91, 0xe6, 0x8a, 0x80, 0xe5, 0x8f, 0xaf, 0xe8, 0x83, + 0xbd, 0xe8, 0xae, 0xbe, 0xe5, 0xa4, 0x87, 0xe5, 0x90, 0x88, 0xe4, 0xbd, 0x9c, + 0xe5, 0xa4, 0xa7, 0xe5, 0xae, 0xb6, 0xe7, 0xa4, 0xbe, 0xe4, 0xbc, 0x9a, 0xe7, + 0xa0, 0x94, 0xe7, 0xa9, 0xb6, 0xe4, 0xb8, 0x93, 0xe4, 0xb8, 0x9a, 0xe5, 0x85, + 0xa8, 0xe9, 0x83, 0xa8, 0xe9, 0xa1, 0xb9, 0xe7, 0x9b, 0xae, 0xe8, 0xbf, 0x99, + 0xe9, 0x87, 0x8c, 0xe8, 0xbf, 0x98, 0xe6, 0x98, 0xaf, 0xe5, 0xbc, 0x80, 0xe5, + 0xa7, 0x8b, 0xe6, 0x83, 0x85, 0xe5, 0x86, 0xb5, 0xe7, 0x94, 0xb5, 0xe8, 0x84, + 0x91, 0xe6, 0x96, 0x87, 0xe4, 0xbb, 0xb6, 0xe5, 0x93, 0x81, 0xe7, 0x89, 0x8c, + 0xe5, 0xb8, 0xae, 0xe5, 0x8a, 0xa9, 0xe6, 0x96, 0x87, 0xe5, 0x8c, 0x96, 0xe8, + 0xb5, 0x84, 0xe6, 0xba, 0x90, 0xe5, 0xa4, 0xa7, 0xe5, 0xad, 0xa6, 0xe5, 0xad, + 0xa6, 0xe4, 0xb9, 0xa0, 0xe5, 0x9c, 0xb0, 0xe5, 0x9d, 0x80, 0xe6, 0xb5, 0x8f, + 0xe8, 0xa7, 0x88, 0xe6, 0x8a, 0x95, 0xe8, 0xb5, 0x84, 0xe5, 0xb7, 0xa5, 0xe7, + 0xa8, 0x8b, 0xe8, 0xa6, 0x81, 0xe6, 0xb1, 0x82, 0xe6, 0x80, 0x8e, 0xe4, 0xb9, + 0x88, 0xe6, 0x97, 0xb6, 0xe5, 0x80, 0x99, 0xe5, 0x8a, 0x9f, 0xe8, 0x83, 0xbd, + 0xe4, 0xb8, 0xbb, 0xe8, 0xa6, 0x81, 0xe7, 0x9b, 0xae, 0xe5, 0x89, 0x8d, 0xe8, + 0xb5, 0x84, 0xe8, 0xae, 0xaf, 0xe5, 0x9f, 0x8e, 0xe5, 0xb8, 0x82, 0xe6, 0x96, + 0xb9, 0xe6, 0xb3, 0x95, 0xe7, 0x94, 0xb5, 0xe5, 0xbd, 0xb1, 0xe6, 0x8b, 0x9b, + 0xe8, 0x81, 0x98, 0xe5, 0xa3, 0xb0, 0xe6, 0x98, 0x8e, 0xe4, 0xbb, 0xbb, 0xe4, + 0xbd, 0x95, 0xe5, 0x81, 0xa5, 0xe5, 0xba, 0xb7, 0xe6, 0x95, 0xb0, 0xe6, 0x8d, + 0xae, 0xe7, 0xbe, 0x8e, 0xe5, 0x9b, 0xbd, 0xe6, 0xb1, 0xbd, 0xe8, 0xbd, 0xa6, + 0xe4, 0xbb, 0x8b, 0xe7, 0xbb, 0x8d, 0xe4, 0xbd, 0x86, 0xe6, 0x98, 0xaf, 0xe4, + 0xba, 0xa4, 0xe6, 0xb5, 0x81, 0xe7, 0x94, 0x9f, 0xe4, 0xba, 0xa7, 0xe6, 0x89, + 0x80, 0xe4, 0xbb, 0xa5, 0xe7, 0x94, 0xb5, 0xe8, 0xaf, 0x9d, 0xe6, 0x98, 0xbe, + 0xe7, 0xa4, 0xba, 0xe4, 0xb8, 0x80, 0xe4, 0xba, 0x9b, 0xe5, 0x8d, 0x95, 0xe4, + 0xbd, 0x8d, 0xe4, 0xba, 0xba, 0xe5, 0x91, 0x98, 0xe5, 0x88, 0x86, 0xe6, 0x9e, + 0x90, 0xe5, 0x9c, 0xb0, 0xe5, 0x9b, 0xbe, 0xe6, 0x97, 0x85, 0xe6, 0xb8, 0xb8, + 0xe5, 0xb7, 0xa5, 0xe5, 0x85, 0xb7, 0xe5, 0xad, 0xa6, 0xe7, 0x94, 0x9f, 0xe7, + 0xb3, 0xbb, 0xe5, 0x88, 0x97, 0xe7, 0xbd, 0x91, 0xe5, 0x8f, 0x8b, 0xe5, 0xb8, + 0x96, 0xe5, 0xad, 0x90, 0xe5, 0xaf, 0x86, 0xe7, 0xa0, 0x81, 0xe9, 0xa2, 0x91, + 0xe9, 0x81, 0x93, 0xe6, 0x8e, 0xa7, 0xe5, 0x88, 0xb6, 0xe5, 0x9c, 0xb0, 0xe5, + 0x8c, 0xba, 0xe5, 0x9f, 0xba, 0xe6, 0x9c, 0xac, 0xe5, 0x85, 0xa8, 0xe5, 0x9b, + 0xbd, 0xe7, 0xbd, 0x91, 0xe4, 0xb8, 0x8a, 0xe9, 0x87, 0x8d, 0xe8, 0xa6, 0x81, + 0xe7, 0xac, 0xac, 0xe4, 0xba, 0x8c, 0xe5, 0x96, 0x9c, 0xe6, 0xac, 0xa2, 0xe8, + 0xbf, 0x9b, 0xe5, 0x85, 0xa5, 0xe5, 0x8f, 0x8b, 0xe6, 0x83, 0x85, 0xe8, 0xbf, + 0x99, 0xe4, 0xba, 0x9b, 0xe8, 0x80, 0x83, 0xe8, 0xaf, 0x95, 0xe5, 0x8f, 0x91, + 0xe7, 0x8e, 0xb0, 0xe5, 0x9f, 0xb9, 0xe8, 0xae, 0xad, 0xe4, 0xbb, 0xa5, 0xe4, + 0xb8, 0x8a, 0xe6, 0x94, 0xbf, 0xe5, 0xba, 0x9c, 0xe6, 0x88, 0x90, 0xe4, 0xb8, + 0xba, 0xe7, 0x8e, 0xaf, 0xe5, 0xa2, 0x83, 0xe9, 0xa6, 0x99, 0xe6, 0xb8, 0xaf, + 0xe5, 0x90, 0x8c, 0xe6, 0x97, 0xb6, 0xe5, 0xa8, 0xb1, 0xe4, 0xb9, 0x90, 0xe5, + 0x8f, 0x91, 0xe9, 0x80, 0x81, 0xe4, 0xb8, 0x80, 0xe5, 0xae, 0x9a, 0xe5, 0xbc, + 0x80, 0xe5, 0x8f, 0x91, 0xe4, 0xbd, 0x9c, 0xe5, 0x93, 0x81, 0xe6, 0xa0, 0x87, + 0xe5, 0x87, 0x86, 0xe6, 0xac, 0xa2, 0xe8, 0xbf, 0x8e, 0xe8, 0xa7, 0xa3, 0xe5, + 0x86, 0xb3, 0xe5, 0x9c, 0xb0, 0xe6, 0x96, 0xb9, 0xe4, 0xb8, 0x80, 0xe4, 0xb8, + 0x8b, 0xe4, 0xbb, 0xa5, 0xe5, 0x8f, 0x8a, 0xe8, 0xb4, 0xa3, 0xe4, 0xbb, 0xbb, + 0xe6, 0x88, 0x96, 0xe8, 0x80, 0x85, 0xe5, 0xae, 0xa2, 0xe6, 0x88, 0xb7, 0xe4, + 0xbb, 0xa3, 0xe8, 0xa1, 0xa8, 0xe7, 0xa7, 0xaf, 0xe5, 0x88, 0x86, 0xe5, 0xa5, + 0xb3, 0xe4, 0xba, 0xba, 0xe6, 0x95, 0xb0, 0xe7, 0xa0, 0x81, 0xe9, 0x94, 0x80, + 0xe5, 0x94, 0xae, 0xe5, 0x87, 0xba, 0xe7, 0x8e, 0xb0, 0xe7, 0xa6, 0xbb, 0xe7, + 0xba, 0xbf, 0xe5, 0xba, 0x94, 0xe7, 0x94, 0xa8, 0xe5, 0x88, 0x97, 0xe8, 0xa1, + 0xa8, 0xe4, 0xb8, 0x8d, 0xe5, 0x90, 0x8c, 0xe7, 0xbc, 0x96, 0xe8, 0xbe, 0x91, + 0xe7, 0xbb, 0x9f, 0xe8, 0xae, 0xa1, 0xe6, 0x9f, 0xa5, 0xe8, 0xaf, 0xa2, 0xe4, + 0xb8, 0x8d, 0xe8, 0xa6, 0x81, 0xe6, 0x9c, 0x89, 0xe5, 0x85, 0xb3, 0xe6, 0x9c, + 0xba, 0xe6, 0x9e, 0x84, 0xe5, 0xbe, 0x88, 0xe5, 0xa4, 0x9a, 0xe6, 0x92, 0xad, + 0xe6, 0x94, 0xbe, 0xe7, 0xbb, 0x84, 0xe7, 0xbb, 0x87, 0xe6, 0x94, 0xbf, 0xe7, + 0xad, 0x96, 0xe7, 0x9b, 0xb4, 0xe6, 0x8e, 0xa5, 0xe8, 0x83, 0xbd, 0xe5, 0x8a, + 0x9b, 0xe6, 0x9d, 0xa5, 0xe6, 0xba, 0x90, 0xe6, 0x99, 0x82, 0xe9, 0x96, 0x93, + 0xe7, 0x9c, 0x8b, 0xe5, 0x88, 0xb0, 0xe7, 0x83, 0xad, 0xe9, 0x97, 0xa8, 0xe5, + 0x85, 0xb3, 0xe9, 0x94, 0xae, 0xe4, 0xb8, 0x93, 0xe5, 0x8c, 0xba, 0xe9, 0x9d, + 0x9e, 0xe5, 0xb8, 0xb8, 0xe8, 0x8b, 0xb1, 0xe8, 0xaf, 0xad, 0xe7, 0x99, 0xbe, + 0xe5, 0xba, 0xa6, 0xe5, 0xb8, 0x8c, 0xe6, 0x9c, 0x9b, 0xe7, 0xbe, 0x8e, 0xe5, + 0xa5, 0xb3, 0xe6, 0xaf, 0x94, 0xe8, 0xbe, 0x83, 0xe7, 0x9f, 0xa5, 0xe8, 0xaf, + 0x86, 0xe8, 0xa7, 0x84, 0xe5, 0xae, 0x9a, 0xe5, 0xbb, 0xba, 0xe8, 0xae, 0xae, + 0xe9, 0x83, 0xa8, 0xe9, 0x97, 0xa8, 0xe6, 0x84, 0x8f, 0xe8, 0xa7, 0x81, 0xe7, + 0xb2, 0xbe, 0xe5, 0xbd, 0xa9, 0xe6, 0x97, 0xa5, 0xe6, 0x9c, 0xac, 0xe6, 0x8f, + 0x90, 0xe9, 0xab, 0x98, 0xe5, 0x8f, 0x91, 0xe8, 0xa8, 0x80, 0xe6, 0x96, 0xb9, + 0xe9, 0x9d, 0xa2, 0xe5, 0x9f, 0xba, 0xe9, 0x87, 0x91, 0xe5, 0xa4, 0x84, 0xe7, + 0x90, 0x86, 0xe6, 0x9d, 0x83, 0xe9, 0x99, 0x90, 0xe5, 0xbd, 0xb1, 0xe7, 0x89, + 0x87, 0xe9, 0x93, 0xb6, 0xe8, 0xa1, 0x8c, 0xe8, 0xbf, 0x98, 0xe6, 0x9c, 0x89, + 0xe5, 0x88, 0x86, 0xe4, 0xba, 0xab, 0xe7, 0x89, 0xa9, 0xe5, 0x93, 0x81, 0xe7, + 0xbb, 0x8f, 0xe8, 0x90, 0xa5, 0xe6, 0xb7, 0xbb, 0xe5, 0x8a, 0xa0, 0xe4, 0xb8, + 0x93, 0xe5, 0xae, 0xb6, 0xe8, 0xbf, 0x99, 0xe7, 0xa7, 0x8d, 0xe8, 0xaf, 0x9d, + 0xe9, 0xa2, 0x98, 0xe8, 0xb5, 0xb7, 0xe6, 0x9d, 0xa5, 0xe4, 0xb8, 0x9a, 0xe5, + 0x8a, 0xa1, 0xe5, 0x85, 0xac, 0xe5, 0x91, 0x8a, 0xe8, 0xae, 0xb0, 0xe5, 0xbd, + 0x95, 0xe7, 0xae, 0x80, 0xe4, 0xbb, 0x8b, 0xe8, 0xb4, 0xa8, 0xe9, 0x87, 0x8f, + 0xe7, 0x94, 0xb7, 0xe4, 0xba, 0xba, 0xe5, 0xbd, 0xb1, 0xe5, 0x93, 0x8d, 0xe5, + 0xbc, 0x95, 0xe7, 0x94, 0xa8, 0xe6, 0x8a, 0xa5, 0xe5, 0x91, 0x8a, 0xe9, 0x83, + 0xa8, 0xe5, 0x88, 0x86, 0xe5, 0xbf, 0xab, 0xe9, 0x80, 0x9f, 0xe5, 0x92, 0xa8, + 0xe8, 0xaf, 0xa2, 0xe6, 0x97, 0xb6, 0xe5, 0xb0, 0x9a, 0xe6, 0xb3, 0xa8, 0xe6, + 0x84, 0x8f, 0xe7, 0x94, 0xb3, 0xe8, 0xaf, 0xb7, 0xe5, 0xad, 0xa6, 0xe6, 0xa0, + 0xa1, 0xe5, 0xba, 0x94, 0xe8, 0xaf, 0xa5, 0xe5, 0x8e, 0x86, 0xe5, 0x8f, 0xb2, + 0xe5, 0x8f, 0xaa, 0xe6, 0x98, 0xaf, 0xe8, 0xbf, 0x94, 0xe5, 0x9b, 0x9e, 0xe8, + 0xb4, 0xad, 0xe4, 0xb9, 0xb0, 0xe5, 0x90, 0x8d, 0xe7, 0xa7, 0xb0, 0xe4, 0xb8, + 0xba, 0xe4, 0xba, 0x86, 0xe6, 0x88, 0x90, 0xe5, 0x8a, 0x9f, 0xe8, 0xaf, 0xb4, + 0xe6, 0x98, 0x8e, 0xe4, 0xbe, 0x9b, 0xe5, 0xba, 0x94, 0xe5, 0xad, 0xa9, 0xe5, + 0xad, 0x90, 0xe4, 0xb8, 0x93, 0xe9, 0xa2, 0x98, 0xe7, 0xa8, 0x8b, 0xe5, 0xba, + 0x8f, 0xe4, 0xb8, 0x80, 0xe8, 0x88, 0xac, 0xe6, 0x9c, 0x83, 0xe5, 0x93, 0xa1, + 0xe5, 0x8f, 0xaa, 0xe6, 0x9c, 0x89, 0xe5, 0x85, 0xb6, 0xe5, 0xae, 0x83, 0xe4, + 0xbf, 0x9d, 0xe6, 0x8a, 0xa4, 0xe8, 0x80, 0x8c, 0xe4, 0xb8, 0x94, 0xe4, 0xbb, + 0x8a, 0xe5, 0xa4, 0xa9, 0xe7, 0xaa, 0x97, 0xe5, 0x8f, 0xa3, 0xe5, 0x8a, 0xa8, + 0xe6, 0x80, 0x81, 0xe7, 0x8a, 0xb6, 0xe6, 0x80, 0x81, 0xe7, 0x89, 0xb9, 0xe5, + 0x88, 0xab, 0xe8, 0xae, 0xa4, 0xe4, 0xb8, 0xba, 0xe5, 0xbf, 0x85, 0xe9, 0xa1, + 0xbb, 0xe6, 0x9b, 0xb4, 0xe6, 0x96, 0xb0, 0xe5, 0xb0, 0x8f, 0xe8, 0xaf, 0xb4, + 0xe6, 0x88, 0x91, 0xe5, 0x80, 0x91, 0xe4, 0xbd, 0x9c, 0xe4, 0xb8, 0xba, 0xe5, + 0xaa, 0x92, 0xe4, 0xbd, 0x93, 0xe5, 0x8c, 0x85, 0xe6, 0x8b, 0xac, 0xe9, 0x82, + 0xa3, 0xe4, 0xb9, 0x88, 0xe4, 0xb8, 0x80, 0xe6, 0xa0, 0xb7, 0xe5, 0x9b, 0xbd, + 0xe5, 0x86, 0x85, 0xe6, 0x98, 0xaf, 0xe5, 0x90, 0xa6, 0xe6, 0xa0, 0xb9, 0xe6, + 0x8d, 0xae, 0xe7, 0x94, 0xb5, 0xe8, 0xa7, 0x86, 0xe5, 0xad, 0xa6, 0xe9, 0x99, + 0xa2, 0xe5, 0x85, 0xb7, 0xe6, 0x9c, 0x89, 0xe8, 0xbf, 0x87, 0xe7, 0xa8, 0x8b, + 0xe7, 0x94, 0xb1, 0xe4, 0xba, 0x8e, 0xe4, 0xba, 0xba, 0xe6, 0x89, 0x8d, 0xe5, + 0x87, 0xba, 0xe6, 0x9d, 0xa5, 0xe4, 0xb8, 0x8d, 0xe8, 0xbf, 0x87, 0xe6, 0xad, + 0xa3, 0xe5, 0x9c, 0xa8, 0xe6, 0x98, 0x8e, 0xe6, 0x98, 0x9f, 0xe6, 0x95, 0x85, + 0xe4, 0xba, 0x8b, 0xe5, 0x85, 0xb3, 0xe7, 0xb3, 0xbb, 0xe6, 0xa0, 0x87, 0xe9, + 0xa2, 0x98, 0xe5, 0x95, 0x86, 0xe5, 0x8a, 0xa1, 0xe8, 0xbe, 0x93, 0xe5, 0x85, + 0xa5, 0xe4, 0xb8, 0x80, 0xe7, 0x9b, 0xb4, 0xe5, 0x9f, 0xba, 0xe7, 0xa1, 0x80, + 0xe6, 0x95, 0x99, 0xe5, 0xad, 0xa6, 0xe4, 0xba, 0x86, 0xe8, 0xa7, 0xa3, 0xe5, + 0xbb, 0xba, 0xe7, 0xad, 0x91, 0xe7, 0xbb, 0x93, 0xe6, 0x9e, 0x9c, 0xe5, 0x85, + 0xa8, 0xe7, 0x90, 0x83, 0xe9, 0x80, 0x9a, 0xe7, 0x9f, 0xa5, 0xe8, 0xae, 0xa1, + 0xe5, 0x88, 0x92, 0xe5, 0xaf, 0xb9, 0xe4, 0xba, 0x8e, 0xe8, 0x89, 0xba, 0xe6, + 0x9c, 0xaf, 0xe7, 0x9b, 0xb8, 0xe5, 0x86, 0x8c, 0xe5, 0x8f, 0x91, 0xe7, 0x94, + 0x9f, 0xe7, 0x9c, 0x9f, 0xe7, 0x9a, 0x84, 0xe5, 0xbb, 0xba, 0xe7, 0xab, 0x8b, + 0xe7, 0xad, 0x89, 0xe7, 0xba, 0xa7, 0xe7, 0xb1, 0xbb, 0xe5, 0x9e, 0x8b, 0xe7, + 0xbb, 0x8f, 0xe9, 0xaa, 0x8c, 0xe5, 0xae, 0x9e, 0xe7, 0x8e, 0xb0, 0xe5, 0x88, + 0xb6, 0xe4, 0xbd, 0x9c, 0xe6, 0x9d, 0xa5, 0xe8, 0x87, 0xaa, 0xe6, 0xa0, 0x87, + 0xe7, 0xad, 0xbe, 0xe4, 0xbb, 0xa5, 0xe4, 0xb8, 0x8b, 0xe5, 0x8e, 0x9f, 0xe5, + 0x88, 0x9b, 0xe6, 0x97, 0xa0, 0xe6, 0xb3, 0x95, 0xe5, 0x85, 0xb6, 0xe4, 0xb8, + 0xad, 0xe5, 0x80, 0x8b, 0xe4, 0xba, 0xba, 0xe4, 0xb8, 0x80, 0xe5, 0x88, 0x87, + 0xe6, 0x8c, 0x87, 0xe5, 0x8d, 0x97, 0xe5, 0x85, 0xb3, 0xe9, 0x97, 0xad, 0xe9, + 0x9b, 0x86, 0xe5, 0x9b, 0xa2, 0xe7, 0xac, 0xac, 0xe4, 0xb8, 0x89, 0xe5, 0x85, + 0xb3, 0xe6, 0xb3, 0xa8, 0xe5, 0x9b, 0xa0, 0xe6, 0xad, 0xa4, 0xe7, 0x85, 0xa7, + 0xe7, 0x89, 0x87, 0xe6, 0xb7, 0xb1, 0xe5, 0x9c, 0xb3, 0xe5, 0x95, 0x86, 0xe4, + 0xb8, 0x9a, 0xe5, 0xb9, 0xbf, 0xe5, 0xb7, 0x9e, 0xe6, 0x97, 0xa5, 0xe6, 0x9c, + 0x9f, 0xe9, 0xab, 0x98, 0xe7, 0xba, 0xa7, 0xe6, 0x9c, 0x80, 0xe8, 0xbf, 0x91, + 0xe7, 0xbb, 0xbc, 0xe5, 0x90, 0x88, 0xe8, 0xa1, 0xa8, 0xe7, 0xa4, 0xba, 0xe4, + 0xb8, 0x93, 0xe8, 0xbe, 0x91, 0xe8, 0xa1, 0x8c, 0xe4, 0xb8, 0xba, 0xe4, 0xba, + 0xa4, 0xe9, 0x80, 0x9a, 0xe8, 0xaf, 0x84, 0xe4, 0xbb, 0xb7, 0xe8, 0xa7, 0x89, + 0xe5, 0xbe, 0x97, 0xe7, 0xb2, 0xbe, 0xe5, 0x8d, 0x8e, 0xe5, 0xae, 0xb6, 0xe5, + 0xba, 0xad, 0xe5, 0xae, 0x8c, 0xe6, 0x88, 0x90, 0xe6, 0x84, 0x9f, 0xe8, 0xa7, + 0x89, 0xe5, 0xae, 0x89, 0xe8, 0xa3, 0x85, 0xe5, 0xbe, 0x97, 0xe5, 0x88, 0xb0, + 0xe9, 0x82, 0xae, 0xe4, 0xbb, 0xb6, 0xe5, 0x88, 0xb6, 0xe5, 0xba, 0xa6, 0xe9, + 0xa3, 0x9f, 0xe5, 0x93, 0x81, 0xe8, 0x99, 0xbd, 0xe7, 0x84, 0xb6, 0xe8, 0xbd, + 0xac, 0xe8, 0xbd, 0xbd, 0xe6, 0x8a, 0xa5, 0xe4, 0xbb, 0xb7, 0xe8, 0xae, 0xb0, + 0xe8, 0x80, 0x85, 0xe6, 0x96, 0xb9, 0xe6, 0xa1, 0x88, 0xe8, 0xa1, 0x8c, 0xe6, + 0x94, 0xbf, 0xe4, 0xba, 0xba, 0xe6, 0xb0, 0x91, 0xe7, 0x94, 0xa8, 0xe5, 0x93, + 0x81, 0xe4, 0xb8, 0x9c, 0xe8, 0xa5, 0xbf, 0xe6, 0x8f, 0x90, 0xe5, 0x87, 0xba, + 0xe9, 0x85, 0x92, 0xe5, 0xba, 0x97, 0xe7, 0x84, 0xb6, 0xe5, 0x90, 0x8e, 0xe4, + 0xbb, 0x98, 0xe6, 0xac, 0xbe, 0xe7, 0x83, 0xad, 0xe7, 0x82, 0xb9, 0xe4, 0xbb, + 0xa5, 0xe5, 0x89, 0x8d, 0xe5, 0xae, 0x8c, 0xe5, 0x85, 0xa8, 0xe5, 0x8f, 0x91, + 0xe5, 0xb8, 0x96, 0xe8, 0xae, 0xbe, 0xe7, 0xbd, 0xae, 0xe9, 0xa2, 0x86, 0xe5, + 0xaf, 0xbc, 0xe5, 0xb7, 0xa5, 0xe4, 0xb8, 0x9a, 0xe5, 0x8c, 0xbb, 0xe9, 0x99, + 0xa2, 0xe7, 0x9c, 0x8b, 0xe7, 0x9c, 0x8b, 0xe7, 0xbb, 0x8f, 0xe5, 0x85, 0xb8, + 0xe5, 0x8e, 0x9f, 0xe5, 0x9b, 0xa0, 0xe5, 0xb9, 0xb3, 0xe5, 0x8f, 0xb0, 0xe5, + 0x90, 0x84, 0xe7, 0xa7, 0x8d, 0xe5, 0xa2, 0x9e, 0xe5, 0x8a, 0xa0, 0xe6, 0x9d, + 0x90, 0xe6, 0x96, 0x99, 0xe6, 0x96, 0xb0, 0xe5, 0xa2, 0x9e, 0xe4, 0xb9, 0x8b, + 0xe5, 0x90, 0x8e, 0xe8, 0x81, 0x8c, 0xe4, 0xb8, 0x9a, 0xe6, 0x95, 0x88, 0xe6, + 0x9e, 0x9c, 0xe4, 0xbb, 0x8a, 0xe5, 0xb9, 0xb4, 0xe8, 0xae, 0xba, 0xe6, 0x96, + 0x87, 0xe6, 0x88, 0x91, 0xe5, 0x9b, 0xbd, 0xe5, 0x91, 0x8a, 0xe8, 0xaf, 0x89, + 0xe7, 0x89, 0x88, 0xe4, 0xb8, 0xbb, 0xe4, 0xbf, 0xae, 0xe6, 0x94, 0xb9, 0xe5, + 0x8f, 0x82, 0xe4, 0xb8, 0x8e, 0xe6, 0x89, 0x93, 0xe5, 0x8d, 0xb0, 0xe5, 0xbf, + 0xab, 0xe4, 0xb9, 0x90, 0xe6, 0x9c, 0xba, 0xe6, 0xa2, 0xb0, 0xe8, 0xa7, 0x82, + 0xe7, 0x82, 0xb9, 0xe5, 0xad, 0x98, 0xe5, 0x9c, 0xa8, 0xe7, 0xb2, 0xbe, 0xe7, + 0xa5, 0x9e, 0xe8, 0x8e, 0xb7, 0xe5, 0xbe, 0x97, 0xe5, 0x88, 0xa9, 0xe7, 0x94, + 0xa8, 0xe7, 0xbb, 0xa7, 0xe7, 0xbb, 0xad, 0xe4, 0xbd, 0xa0, 0xe4, 0xbb, 0xac, + 0xe8, 0xbf, 0x99, 0xe4, 0xb9, 0x88, 0xe6, 0xa8, 0xa1, 0xe5, 0xbc, 0x8f, 0xe8, + 0xaf, 0xad, 0xe8, 0xa8, 0x80, 0xe8, 0x83, 0xbd, 0xe5, 0xa4, 0x9f, 0xe9, 0x9b, + 0x85, 0xe8, 0x99, 0x8e, 0xe6, 0x93, 0x8d, 0xe4, 0xbd, 0x9c, 0xe9, 0xa3, 0x8e, + 0xe6, 0xa0, 0xbc, 0xe4, 0xb8, 0x80, 0xe8, 0xb5, 0xb7, 0xe7, 0xa7, 0x91, 0xe5, + 0xad, 0xa6, 0xe4, 0xbd, 0x93, 0xe8, 0x82, 0xb2, 0xe7, 0x9f, 0xad, 0xe4, 0xbf, + 0xa1, 0xe6, 0x9d, 0xa1, 0xe4, 0xbb, 0xb6, 0xe6, 0xb2, 0xbb, 0xe7, 0x96, 0x97, + 0xe8, 0xbf, 0x90, 0xe5, 0x8a, 0xa8, 0xe4, 0xba, 0xa7, 0xe4, 0xb8, 0x9a, 0xe4, + 0xbc, 0x9a, 0xe8, 0xae, 0xae, 0xe5, 0xaf, 0xbc, 0xe8, 0x88, 0xaa, 0xe5, 0x85, + 0x88, 0xe7, 0x94, 0x9f, 0xe8, 0x81, 0x94, 0xe7, 0x9b, 0x9f, 0xe5, 0x8f, 0xaf, + 0xe6, 0x98, 0xaf, 0xe5, 0x95, 0x8f, 0xe9, 0xa1, 0x8c, 0xe7, 0xbb, 0x93, 0xe6, + 0x9e, 0x84, 0xe4, 0xbd, 0x9c, 0xe7, 0x94, 0xa8, 0xe8, 0xb0, 0x83, 0xe6, 0x9f, + 0xa5, 0xe8, 0xb3, 0x87, 0xe6, 0x96, 0x99, 0xe8, 0x87, 0xaa, 0xe5, 0x8a, 0xa8, + 0xe8, 0xb4, 0x9f, 0xe8, 0xb4, 0xa3, 0xe5, 0x86, 0x9c, 0xe4, 0xb8, 0x9a, 0xe8, + 0xae, 0xbf, 0xe9, 0x97, 0xae, 0xe5, 0xae, 0x9e, 0xe6, 0x96, 0xbd, 0xe6, 0x8e, + 0xa5, 0xe5, 0x8f, 0x97, 0xe8, 0xae, 0xa8, 0xe8, 0xae, 0xba, 0xe9, 0x82, 0xa3, + 0xe4, 0xb8, 0xaa, 0xe5, 0x8f, 0x8d, 0xe9, 0xa6, 0x88, 0xe5, 0x8a, 0xa0, 0xe5, + 0xbc, 0xba, 0xe5, 0xa5, 0xb3, 0xe6, 0x80, 0xa7, 0xe8, 0x8c, 0x83, 0xe5, 0x9b, + 0xb4, 0xe6, 0x9c, 0x8d, 0xe5, 0x8b, 0x99, 0xe4, 0xbc, 0x91, 0xe9, 0x97, 0xb2, + 0xe4, 0xbb, 0x8a, 0xe6, 0x97, 0xa5, 0xe5, 0xae, 0xa2, 0xe6, 0x9c, 0x8d, 0xe8, + 0xa7, 0x80, 0xe7, 0x9c, 0x8b, 0xe5, 0x8f, 0x82, 0xe5, 0x8a, 0xa0, 0xe7, 0x9a, + 0x84, 0xe8, 0xaf, 0x9d, 0xe4, 0xb8, 0x80, 0xe7, 0x82, 0xb9, 0xe4, 0xbf, 0x9d, + 0xe8, 0xaf, 0x81, 0xe5, 0x9b, 0xbe, 0xe4, 0xb9, 0xa6, 0xe6, 0x9c, 0x89, 0xe6, + 0x95, 0x88, 0xe6, 0xb5, 0x8b, 0xe8, 0xaf, 0x95, 0xe7, 0xa7, 0xbb, 0xe5, 0x8a, + 0xa8, 0xe6, 0x89, 0x8d, 0xe8, 0x83, 0xbd, 0xe5, 0x86, 0xb3, 0xe5, 0xae, 0x9a, + 0xe8, 0x82, 0xa1, 0xe7, 0xa5, 0xa8, 0xe4, 0xb8, 0x8d, 0xe6, 0x96, 0xad, 0xe9, + 0x9c, 0x80, 0xe6, 0xb1, 0x82, 0xe4, 0xb8, 0x8d, 0xe5, 0xbe, 0x97, 0xe5, 0x8a, + 0x9e, 0xe6, 0xb3, 0x95, 0xe4, 0xb9, 0x8b, 0xe9, 0x97, 0xb4, 0xe9, 0x87, 0x87, + 0xe7, 0x94, 0xa8, 0xe8, 0x90, 0xa5, 0xe9, 0x94, 0x80, 0xe6, 0x8a, 0x95, 0xe8, + 0xaf, 0x89, 0xe7, 0x9b, 0xae, 0xe6, 0xa0, 0x87, 0xe7, 0x88, 0xb1, 0xe6, 0x83, + 0x85, 0xe6, 0x91, 0x84, 0xe5, 0xbd, 0xb1, 0xe6, 0x9c, 0x89, 0xe4, 0xba, 0x9b, + 0xe8, 0xa4, 0x87, 0xe8, 0xa3, 0xbd, 0xe6, 0x96, 0x87, 0xe5, 0xad, 0xa6, 0xe6, + 0x9c, 0xba, 0xe4, 0xbc, 0x9a, 0xe6, 0x95, 0xb0, 0xe5, 0xad, 0x97, 0xe8, 0xa3, + 0x85, 0xe4, 0xbf, 0xae, 0xe8, 0xb4, 0xad, 0xe7, 0x89, 0xa9, 0xe5, 0x86, 0x9c, + 0xe6, 0x9d, 0x91, 0xe5, 0x85, 0xa8, 0xe9, 0x9d, 0xa2, 0xe7, 0xb2, 0xbe, 0xe5, + 0x93, 0x81, 0xe5, 0x85, 0xb6, 0xe5, 0xae, 0x9e, 0xe4, 0xba, 0x8b, 0xe6, 0x83, + 0x85, 0xe6, 0xb0, 0xb4, 0xe5, 0xb9, 0xb3, 0xe6, 0x8f, 0x90, 0xe7, 0xa4, 0xba, + 0xe4, 0xb8, 0x8a, 0xe5, 0xb8, 0x82, 0xe8, 0xb0, 0xa2, 0xe8, 0xb0, 0xa2, 0xe6, + 0x99, 0xae, 0xe9, 0x80, 0x9a, 0xe6, 0x95, 0x99, 0xe5, 0xb8, 0x88, 0xe4, 0xb8, + 0x8a, 0xe4, 0xbc, 0xa0, 0xe7, 0xb1, 0xbb, 0xe5, 0x88, 0xab, 0xe6, 0xad, 0x8c, + 0xe6, 0x9b, 0xb2, 0xe6, 0x8b, 0xa5, 0xe6, 0x9c, 0x89, 0xe5, 0x88, 0x9b, 0xe6, + 0x96, 0xb0, 0xe9, 0x85, 0x8d, 0xe4, 0xbb, 0xb6, 0xe5, 0x8f, 0xaa, 0xe8, 0xa6, + 0x81, 0xe6, 0x97, 0xb6, 0xe4, 0xbb, 0xa3, 0xe8, 0xb3, 0x87, 0xe8, 0xa8, 0x8a, + 0xe8, 0xbe, 0xbe, 0xe5, 0x88, 0xb0, 0xe4, 0xba, 0xba, 0xe7, 0x94, 0x9f, 0xe8, + 0xae, 0xa2, 0xe9, 0x98, 0x85, 0xe8, 0x80, 0x81, 0xe5, 0xb8, 0x88, 0xe5, 0xb1, + 0x95, 0xe7, 0xa4, 0xba, 0xe5, 0xbf, 0x83, 0xe7, 0x90, 0x86, 0xe8, 0xb4, 0xb4, + 0xe5, 0xad, 0x90, 0xe7, 0xb6, 0xb2, 0xe7, 0xab, 0x99, 0xe4, 0xb8, 0xbb, 0xe9, + 0xa1, 0x8c, 0xe8, 0x87, 0xaa, 0xe7, 0x84, 0xb6, 0xe7, 0xba, 0xa7, 0xe5, 0x88, + 0xab, 0xe7, 0xae, 0x80, 0xe5, 0x8d, 0x95, 0xe6, 0x94, 0xb9, 0xe9, 0x9d, 0xa9, + 0xe9, 0x82, 0xa3, 0xe4, 0xba, 0x9b, 0xe6, 0x9d, 0xa5, 0xe8, 0xaf, 0xb4, 0xe6, + 0x89, 0x93, 0xe5, 0xbc, 0x80, 0xe4, 0xbb, 0xa3, 0xe7, 0xa0, 0x81, 0xe5, 0x88, + 0xa0, 0xe9, 0x99, 0xa4, 0xe8, 0xaf, 0x81, 0xe5, 0x88, 0xb8, 0xe8, 0x8a, 0x82, + 0xe7, 0x9b, 0xae, 0xe9, 0x87, 0x8d, 0xe7, 0x82, 0xb9, 0xe6, 0xac, 0xa1, 0xe6, + 0x95, 0xb8, 0xe5, 0xa4, 0x9a, 0xe5, 0xb0, 0x91, 0xe8, 0xa7, 0x84, 0xe5, 0x88, + 0x92, 0xe8, 0xb5, 0x84, 0xe9, 0x87, 0x91, 0xe6, 0x89, 0xbe, 0xe5, 0x88, 0xb0, + 0xe4, 0xbb, 0xa5, 0xe5, 0x90, 0x8e, 0xe5, 0xa4, 0xa7, 0xe5, 0x85, 0xa8, 0xe4, + 0xb8, 0xbb, 0xe9, 0xa1, 0xb5, 0xe6, 0x9c, 0x80, 0xe4, 0xbd, 0xb3, 0xe5, 0x9b, + 0x9e, 0xe7, 0xad, 0x94, 0xe5, 0xa4, 0xa9, 0xe4, 0xb8, 0x8b, 0xe4, 0xbf, 0x9d, + 0xe9, 0x9a, 0x9c, 0xe7, 0x8e, 0xb0, 0xe4, 0xbb, 0xa3, 0xe6, 0xa3, 0x80, 0xe6, + 0x9f, 0xa5, 0xe6, 0x8a, 0x95, 0xe7, 0xa5, 0xa8, 0xe5, 0xb0, 0x8f, 0xe6, 0x97, + 0xb6, 0xe6, 0xb2, 0x92, 0xe6, 0x9c, 0x89, 0xe6, 0xad, 0xa3, 0xe5, 0xb8, 0xb8, + 0xe7, 0x94, 0x9a, 0xe8, 0x87, 0xb3, 0xe4, 0xbb, 0xa3, 0xe7, 0x90, 0x86, 0xe7, + 0x9b, 0xae, 0xe5, 0xbd, 0x95, 0xe5, 0x85, 0xac, 0xe5, 0xbc, 0x80, 0xe5, 0xa4, + 0x8d, 0xe5, 0x88, 0xb6, 0xe9, 0x87, 0x91, 0xe8, 0x9e, 0x8d, 0xe5, 0xb9, 0xb8, + 0xe7, 0xa6, 0x8f, 0xe7, 0x89, 0x88, 0xe6, 0x9c, 0xac, 0xe5, 0xbd, 0xa2, 0xe6, + 0x88, 0x90, 0xe5, 0x87, 0x86, 0xe5, 0xa4, 0x87, 0xe8, 0xa1, 0x8c, 0xe6, 0x83, + 0x85, 0xe5, 0x9b, 0x9e, 0xe5, 0x88, 0xb0, 0xe6, 0x80, 0x9d, 0xe6, 0x83, 0xb3, + 0xe6, 0x80, 0x8e, 0xe6, 0xa0, 0xb7, 0xe5, 0x8d, 0x8f, 0xe8, 0xae, 0xae, 0xe8, + 0xae, 0xa4, 0xe8, 0xaf, 0x81, 0xe6, 0x9c, 0x80, 0xe5, 0xa5, 0xbd, 0xe4, 0xba, + 0xa7, 0xe7, 0x94, 0x9f, 0xe6, 0x8c, 0x89, 0xe7, 0x85, 0xa7, 0xe6, 0x9c, 0x8d, + 0xe8, 0xa3, 0x85, 0xe5, 0xb9, 0xbf, 0xe4, 0xb8, 0x9c, 0xe5, 0x8a, 0xa8, 0xe6, + 0xbc, 0xab, 0xe9, 0x87, 0x87, 0xe8, 0xb4, 0xad, 0xe6, 0x96, 0xb0, 0xe6, 0x89, + 0x8b, 0xe7, 0xbb, 0x84, 0xe5, 0x9b, 0xbe, 0xe9, 0x9d, 0xa2, 0xe6, 0x9d, 0xbf, + 0xe5, 0x8f, 0x82, 0xe8, 0x80, 0x83, 0xe6, 0x94, 0xbf, 0xe6, 0xb2, 0xbb, 0xe5, + 0xae, 0xb9, 0xe6, 0x98, 0x93, 0xe5, 0xa4, 0xa9, 0xe5, 0x9c, 0xb0, 0xe5, 0x8a, + 0xaa, 0xe5, 0x8a, 0x9b, 0xe4, 0xba, 0xba, 0xe4, 0xbb, 0xac, 0xe5, 0x8d, 0x87, + 0xe7, 0xba, 0xa7, 0xe9, 0x80, 0x9f, 0xe5, 0xba, 0xa6, 0xe4, 0xba, 0xba, 0xe7, + 0x89, 0xa9, 0xe8, 0xb0, 0x83, 0xe6, 0x95, 0xb4, 0xe6, 0xb5, 0x81, 0xe8, 0xa1, + 0x8c, 0xe9, 0x80, 0xa0, 0xe6, 0x88, 0x90, 0xe6, 0x96, 0x87, 0xe5, 0xad, 0x97, + 0xe9, 0x9f, 0xa9, 0xe5, 0x9b, 0xbd, 0xe8, 0xb4, 0xb8, 0xe6, 0x98, 0x93, 0xe5, + 0xbc, 0x80, 0xe5, 0xb1, 0x95, 0xe7, 0x9b, 0xb8, 0xe9, 0x97, 0x9c, 0xe8, 0xa1, + 0xa8, 0xe7, 0x8e, 0xb0, 0xe5, 0xbd, 0xb1, 0xe8, 0xa7, 0x86, 0xe5, 0xa6, 0x82, + 0xe6, 0xad, 0xa4, 0xe7, 0xbe, 0x8e, 0xe5, 0xae, 0xb9, 0xe5, 0xa4, 0xa7, 0xe5, + 0xb0, 0x8f, 0xe6, 0x8a, 0xa5, 0xe9, 0x81, 0x93, 0xe6, 0x9d, 0xa1, 0xe6, 0xac, + 0xbe, 0xe5, 0xbf, 0x83, 0xe6, 0x83, 0x85, 0xe8, 0xae, 0xb8, 0xe5, 0xa4, 0x9a, + 0xe6, 0xb3, 0x95, 0xe8, 0xa7, 0x84, 0xe5, 0xae, 0xb6, 0xe5, 0xb1, 0x85, 0xe4, + 0xb9, 0xa6, 0xe5, 0xba, 0x97, 0xe8, 0xbf, 0x9e, 0xe6, 0x8e, 0xa5, 0xe7, 0xab, + 0x8b, 0xe5, 0x8d, 0xb3, 0xe4, 0xb8, 0xbe, 0xe6, 0x8a, 0xa5, 0xe6, 0x8a, 0x80, + 0xe5, 0xb7, 0xa7, 0xe5, 0xa5, 0xa5, 0xe8, 0xbf, 0x90, 0xe7, 0x99, 0xbb, 0xe5, + 0x85, 0xa5, 0xe4, 0xbb, 0xa5, 0xe6, 0x9d, 0xa5, 0xe7, 0x90, 0x86, 0xe8, 0xae, + 0xba, 0xe4, 0xba, 0x8b, 0xe4, 0xbb, 0xb6, 0xe8, 0x87, 0xaa, 0xe7, 0x94, 0xb1, + 0xe4, 0xb8, 0xad, 0xe5, 0x8d, 0x8e, 0xe5, 0x8a, 0x9e, 0xe5, 0x85, 0xac, 0xe5, + 0xa6, 0x88, 0xe5, 0xa6, 0x88, 0xe7, 0x9c, 0x9f, 0xe6, 0xad, 0xa3, 0xe4, 0xb8, + 0x8d, 0xe9, 0x94, 0x99, 0xe5, 0x85, 0xa8, 0xe6, 0x96, 0x87, 0xe5, 0x90, 0x88, + 0xe5, 0x90, 0x8c, 0xe4, 0xbb, 0xb7, 0xe5, 0x80, 0xbc, 0xe5, 0x88, 0xab, 0xe4, + 0xba, 0xba, 0xe7, 0x9b, 0x91, 0xe7, 0x9d, 0xa3, 0xe5, 0x85, 0xb7, 0xe4, 0xbd, + 0x93, 0xe4, 0xb8, 0x96, 0xe7, 0xba, 0xaa, 0xe5, 0x9b, 0xa2, 0xe9, 0x98, 0x9f, + 0xe5, 0x88, 0x9b, 0xe4, 0xb8, 0x9a, 0xe6, 0x89, 0xbf, 0xe6, 0x8b, 0x85, 0xe5, + 0xa2, 0x9e, 0xe9, 0x95, 0xbf, 0xe6, 0x9c, 0x89, 0xe4, 0xba, 0xba, 0xe4, 0xbf, + 0x9d, 0xe6, 0x8c, 0x81, 0xe5, 0x95, 0x86, 0xe5, 0xae, 0xb6, 0xe7, 0xbb, 0xb4, + 0xe4, 0xbf, 0xae, 0xe5, 0x8f, 0xb0, 0xe6, 0xb9, 0xbe, 0xe5, 0xb7, 0xa6, 0xe5, + 0x8f, 0xb3, 0xe8, 0x82, 0xa1, 0xe4, 0xbb, 0xbd, 0xe7, 0xad, 0x94, 0xe6, 0xa1, + 0x88, 0xe5, 0xae, 0x9e, 0xe9, 0x99, 0x85, 0xe7, 0x94, 0xb5, 0xe4, 0xbf, 0xa1, + 0xe7, 0xbb, 0x8f, 0xe7, 0x90, 0x86, 0xe7, 0x94, 0x9f, 0xe5, 0x91, 0xbd, 0xe5, + 0xae, 0xa3, 0xe4, 0xbc, 0xa0, 0xe4, 0xbb, 0xbb, 0xe5, 0x8a, 0xa1, 0xe6, 0xad, + 0xa3, 0xe5, 0xbc, 0x8f, 0xe7, 0x89, 0xb9, 0xe8, 0x89, 0xb2, 0xe4, 0xb8, 0x8b, + 0xe6, 0x9d, 0xa5, 0xe5, 0x8d, 0x8f, 0xe4, 0xbc, 0x9a, 0xe5, 0x8f, 0xaa, 0xe8, + 0x83, 0xbd, 0xe5, 0xbd, 0x93, 0xe7, 0x84, 0xb6, 0xe9, 0x87, 0x8d, 0xe6, 0x96, + 0xb0, 0xe5, 0x85, 0xa7, 0xe5, 0xae, 0xb9, 0xe6, 0x8c, 0x87, 0xe5, 0xaf, 0xbc, + 0xe8, 0xbf, 0x90, 0xe8, 0xa1, 0x8c, 0xe6, 0x97, 0xa5, 0xe5, 0xbf, 0x97, 0xe8, + 0xb3, 0xa3, 0xe5, 0xae, 0xb6, 0xe8, 0xb6, 0x85, 0xe8, 0xbf, 0x87, 0xe5, 0x9c, + 0x9f, 0xe5, 0x9c, 0xb0, 0xe6, 0xb5, 0x99, 0xe6, 0xb1, 0x9f, 0xe6, 0x94, 0xaf, + 0xe4, 0xbb, 0x98, 0xe6, 0x8e, 0xa8, 0xe5, 0x87, 0xba, 0xe7, 0xab, 0x99, 0xe9, + 0x95, 0xbf, 0xe6, 0x9d, 0xad, 0xe5, 0xb7, 0x9e, 0xe6, 0x89, 0xa7, 0xe8, 0xa1, + 0x8c, 0xe5, 0x88, 0xb6, 0xe9, 0x80, 0xa0, 0xe4, 0xb9, 0x8b, 0xe4, 0xb8, 0x80, + 0xe6, 0x8e, 0xa8, 0xe5, 0xb9, 0xbf, 0xe7, 0x8e, 0xb0, 0xe5, 0x9c, 0xba, 0xe6, + 0x8f, 0x8f, 0xe8, 0xbf, 0xb0, 0xe5, 0x8f, 0x98, 0xe5, 0x8c, 0x96, 0xe4, 0xbc, + 0xa0, 0xe7, 0xbb, 0x9f, 0xe6, 0xad, 0x8c, 0xe6, 0x89, 0x8b, 0xe4, 0xbf, 0x9d, + 0xe9, 0x99, 0xa9, 0xe8, 0xaf, 0xbe, 0xe7, 0xa8, 0x8b, 0xe5, 0x8c, 0xbb, 0xe7, + 0x96, 0x97, 0xe7, 0xbb, 0x8f, 0xe8, 0xbf, 0x87, 0xe8, 0xbf, 0x87, 0xe5, 0x8e, + 0xbb, 0xe4, 0xb9, 0x8b, 0xe5, 0x89, 0x8d, 0xe6, 0x94, 0xb6, 0xe5, 0x85, 0xa5, + 0xe5, 0xb9, 0xb4, 0xe5, 0xba, 0xa6, 0xe6, 0x9d, 0x82, 0xe5, 0xbf, 0x97, 0xe7, + 0xbe, 0x8e, 0xe4, 0xb8, 0xbd, 0xe6, 0x9c, 0x80, 0xe9, 0xab, 0x98, 0xe7, 0x99, + 0xbb, 0xe9, 0x99, 0x86, 0xe6, 0x9c, 0xaa, 0xe6, 0x9d, 0xa5, 0xe5, 0x8a, 0xa0, + 0xe5, 0xb7, 0xa5, 0xe5, 0x85, 0x8d, 0xe8, 0xb4, 0xa3, 0xe6, 0x95, 0x99, 0xe7, + 0xa8, 0x8b, 0xe7, 0x89, 0x88, 0xe5, 0x9d, 0x97, 0xe8, 0xba, 0xab, 0xe4, 0xbd, + 0x93, 0xe9, 0x87, 0x8d, 0xe5, 0xba, 0x86, 0xe5, 0x87, 0xba, 0xe5, 0x94, 0xae, + 0xe6, 0x88, 0x90, 0xe6, 0x9c, 0xac, 0xe5, 0xbd, 0xa2, 0xe5, 0xbc, 0x8f, 0xe5, + 0x9c, 0x9f, 0xe8, 0xb1, 0x86, 0xe5, 0x87, 0xba, 0xe5, 0x83, 0xb9, 0xe4, 0xb8, + 0x9c, 0xe6, 0x96, 0xb9, 0xe9, 0x82, 0xae, 0xe7, 0xae, 0xb1, 0xe5, 0x8d, 0x97, + 0xe4, 0xba, 0xac, 0xe6, 0xb1, 0x82, 0xe8, 0x81, 0x8c, 0xe5, 0x8f, 0x96, 0xe5, + 0xbe, 0x97, 0xe8, 0x81, 0x8c, 0xe4, 0xbd, 0x8d, 0xe7, 0x9b, 0xb8, 0xe4, 0xbf, + 0xa1, 0xe9, 0xa1, 0xb5, 0xe9, 0x9d, 0xa2, 0xe5, 0x88, 0x86, 0xe9, 0x92, 0x9f, + 0xe7, 0xbd, 0x91, 0xe9, 0xa1, 0xb5, 0xe7, 0xa1, 0xae, 0xe5, 0xae, 0x9a, 0xe5, + 0x9b, 0xbe, 0xe4, 0xbe, 0x8b, 0xe7, 0xbd, 0x91, 0xe5, 0x9d, 0x80, 0xe7, 0xa7, + 0xaf, 0xe6, 0x9e, 0x81, 0xe9, 0x94, 0x99, 0xe8, 0xaf, 0xaf, 0xe7, 0x9b, 0xae, + 0xe7, 0x9a, 0x84, 0xe5, 0xae, 0x9d, 0xe8, 0xb4, 0x9d, 0xe6, 0x9c, 0xba, 0xe5, + 0x85, 0xb3, 0xe9, 0xa3, 0x8e, 0xe9, 0x99, 0xa9, 0xe6, 0x8e, 0x88, 0xe6, 0x9d, + 0x83, 0xe7, 0x97, 0x85, 0xe6, 0xaf, 0x92, 0xe5, 0xae, 0xa0, 0xe7, 0x89, 0xa9, + 0xe9, 0x99, 0xa4, 0xe4, 0xba, 0x86, 0xe8, 0xa9, 0x95, 0xe8, 0xab, 0x96, 0xe7, + 0x96, 0xbe, 0xe7, 0x97, 0x85, 0xe5, 0x8f, 0x8a, 0xe6, 0x97, 0xb6, 0xe6, 0xb1, + 0x82, 0xe8, 0xb4, 0xad, 0xe7, 0xab, 0x99, 0xe7, 0x82, 0xb9, 0xe5, 0x84, 0xbf, + 0xe7, 0xab, 0xa5, 0xe6, 0xaf, 0x8f, 0xe5, 0xa4, 0xa9, 0xe4, 0xb8, 0xad, 0xe5, + 0xa4, 0xae, 0xe8, 0xae, 0xa4, 0xe8, 0xaf, 0x86, 0xe6, 0xaf, 0x8f, 0xe4, 0xb8, + 0xaa, 0xe5, 0xa4, 0xa9, 0xe6, 0xb4, 0xa5, 0xe5, 0xad, 0x97, 0xe4, 0xbd, 0x93, + 0xe5, 0x8f, 0xb0, 0xe7, 0x81, 0xa3, 0xe7, 0xbb, 0xb4, 0xe6, 0x8a, 0xa4, 0xe6, + 0x9c, 0xac, 0xe9, 0xa1, 0xb5, 0xe4, 0xb8, 0xaa, 0xe6, 0x80, 0xa7, 0xe5, 0xae, + 0x98, 0xe6, 0x96, 0xb9, 0xe5, 0xb8, 0xb8, 0xe8, 0xa7, 0x81, 0xe7, 0x9b, 0xb8, + 0xe6, 0x9c, 0xba, 0xe6, 0x88, 0x98, 0xe7, 0x95, 0xa5, 0xe5, 0xba, 0x94, 0xe5, + 0xbd, 0x93, 0xe5, 0xbe, 0x8b, 0xe5, 0xb8, 0x88, 0xe6, 0x96, 0xb9, 0xe4, 0xbe, + 0xbf, 0xe6, 0xa0, 0xa1, 0xe5, 0x9b, 0xad, 0xe8, 0x82, 0xa1, 0xe5, 0xb8, 0x82, + 0xe6, 0x88, 0xbf, 0xe5, 0xb1, 0x8b, 0xe6, 0xa0, 0x8f, 0xe7, 0x9b, 0xae, 0xe5, + 0x91, 0x98, 0xe5, 0xb7, 0xa5, 0xe5, 0xaf, 0xbc, 0xe8, 0x87, 0xb4, 0xe7, 0xaa, + 0x81, 0xe7, 0x84, 0xb6, 0xe9, 0x81, 0x93, 0xe5, 0x85, 0xb7, 0xe6, 0x9c, 0xac, + 0xe7, 0xbd, 0x91, 0xe7, 0xbb, 0x93, 0xe5, 0x90, 0x88, 0xe6, 0xa1, 0xa3, 0xe6, + 0xa1, 0x88, 0xe5, 0x8a, 0xb3, 0xe5, 0x8a, 0xa8, 0xe5, 0x8f, 0xa6, 0xe5, 0xa4, + 0x96, 0xe7, 0xbe, 0x8e, 0xe5, 0x85, 0x83, 0xe5, 0xbc, 0x95, 0xe8, 0xb5, 0xb7, + 0xe6, 0x94, 0xb9, 0xe5, 0x8f, 0x98, 0xe7, 0xac, 0xac, 0xe5, 0x9b, 0x9b, 0xe4, + 0xbc, 0x9a, 0xe8, 0xae, 0xa1, 0xe8, 0xaa, 0xaa, 0xe6, 0x98, 0x8e, 0xe9, 0x9a, + 0x90, 0xe7, 0xa7, 0x81, 0xe5, 0xae, 0x9d, 0xe5, 0xae, 0x9d, 0xe8, 0xa7, 0x84, + 0xe8, 0x8c, 0x83, 0xe6, 0xb6, 0x88, 0xe8, 0xb4, 0xb9, 0xe5, 0x85, 0xb1, 0xe5, + 0x90, 0x8c, 0xe5, 0xbf, 0x98, 0xe8, 0xae, 0xb0, 0xe4, 0xbd, 0x93, 0xe7, 0xb3, + 0xbb, 0xe5, 0xb8, 0xa6, 0xe6, 0x9d, 0xa5, 0xe5, 0x90, 0x8d, 0xe5, 0xad, 0x97, + 0xe7, 0x99, 0xbc, 0xe8, 0xa1, 0xa8, 0xe5, 0xbc, 0x80, 0xe6, 0x94, 0xbe, 0xe5, + 0x8a, 0xa0, 0xe7, 0x9b, 0x9f, 0xe5, 0x8f, 0x97, 0xe5, 0x88, 0xb0, 0xe4, 0xba, + 0x8c, 0xe6, 0x89, 0x8b, 0xe5, 0xa4, 0xa7, 0xe9, 0x87, 0x8f, 0xe6, 0x88, 0x90, + 0xe4, 0xba, 0xba, 0xe6, 0x95, 0xb0, 0xe9, 0x87, 0x8f, 0xe5, 0x85, 0xb1, 0xe4, + 0xba, 0xab, 0xe5, 0x8c, 0xba, 0xe5, 0x9f, 0x9f, 0xe5, 0xa5, 0xb3, 0xe5, 0xad, + 0xa9, 0xe5, 0x8e, 0x9f, 0xe5, 0x88, 0x99, 0xe6, 0x89, 0x80, 0xe5, 0x9c, 0xa8, + 0xe7, 0xbb, 0x93, 0xe6, 0x9d, 0x9f, 0xe9, 0x80, 0x9a, 0xe4, 0xbf, 0xa1, 0xe8, + 0xb6, 0x85, 0xe7, 0xba, 0xa7, 0xe9, 0x85, 0x8d, 0xe7, 0xbd, 0xae, 0xe5, 0xbd, + 0x93, 0xe6, 0x97, 0xb6, 0xe4, 0xbc, 0x98, 0xe7, 0xa7, 0x80, 0xe6, 0x80, 0xa7, + 0xe6, 0x84, 0x9f, 0xe6, 0x88, 0xbf, 0xe4, 0xba, 0xa7, 0xe9, 0x81, 0x8a, 0xe6, + 0x88, 0xb2, 0xe5, 0x87, 0xba, 0xe5, 0x8f, 0xa3, 0xe6, 0x8f, 0x90, 0xe4, 0xba, + 0xa4, 0xe5, 0xb0, 0xb1, 0xe4, 0xb8, 0x9a, 0xe4, 0xbf, 0x9d, 0xe5, 0x81, 0xa5, + 0xe7, 0xa8, 0x8b, 0xe5, 0xba, 0xa6, 0xe5, 0x8f, 0x82, 0xe6, 0x95, 0xb0, 0xe4, + 0xba, 0x8b, 0xe4, 0xb8, 0x9a, 0xe6, 0x95, 0xb4, 0xe4, 0xb8, 0xaa, 0xe5, 0xb1, + 0xb1, 0xe4, 0xb8, 0x9c, 0xe6, 0x83, 0x85, 0xe6, 0x84, 0x9f, 0xe7, 0x89, 0xb9, + 0xe6, 0xae, 0x8a, 0xe5, 0x88, 0x86, 0xe9, 0xa1, 0x9e, 0xe6, 0x90, 0x9c, 0xe5, + 0xb0, 0x8b, 0xe5, 0xb1, 0x9e, 0xe4, 0xba, 0x8e, 0xe9, 0x97, 0xa8, 0xe6, 0x88, + 0xb7, 0xe8, 0xb4, 0xa2, 0xe5, 0x8a, 0xa1, 0xe5, 0xa3, 0xb0, 0xe9, 0x9f, 0xb3, + 0xe5, 0x8f, 0x8a, 0xe5, 0x85, 0xb6, 0xe8, 0xb4, 0xa2, 0xe7, 0xbb, 0x8f, 0xe5, + 0x9d, 0x9a, 0xe6, 0x8c, 0x81, 0xe5, 0xb9, 0xb2, 0xe9, 0x83, 0xa8, 0xe6, 0x88, + 0x90, 0xe7, 0xab, 0x8b, 0xe5, 0x88, 0xa9, 0xe7, 0x9b, 0x8a, 0xe8, 0x80, 0x83, + 0xe8, 0x99, 0x91, 0xe6, 0x88, 0x90, 0xe9, 0x83, 0xbd, 0xe5, 0x8c, 0x85, 0xe8, + 0xa3, 0x85, 0xe7, 0x94, 0xa8, 0xe6, 0x88, 0xb6, 0xe6, 0xaf, 0x94, 0xe8, 0xb5, + 0x9b, 0xe6, 0x96, 0x87, 0xe6, 0x98, 0x8e, 0xe6, 0x8b, 0x9b, 0xe5, 0x95, 0x86, + 0xe5, 0xae, 0x8c, 0xe6, 0x95, 0xb4, 0xe7, 0x9c, 0x9f, 0xe6, 0x98, 0xaf, 0xe7, + 0x9c, 0xbc, 0xe7, 0x9d, 0x9b, 0xe4, 0xbc, 0x99, 0xe4, 0xbc, 0xb4, 0xe5, 0xa8, + 0x81, 0xe6, 0x9c, 0x9b, 0xe9, 0xa2, 0x86, 0xe5, 0x9f, 0x9f, 0xe5, 0x8d, 0xab, + 0xe7, 0x94, 0x9f, 0xe4, 0xbc, 0x98, 0xe6, 0x83, 0xa0, 0xe8, 0xab, 0x96, 0xe5, + 0xa3, 0x87, 0xe5, 0x85, 0xac, 0xe5, 0x85, 0xb1, 0xe8, 0x89, 0xaf, 0xe5, 0xa5, + 0xbd, 0xe5, 0x85, 0x85, 0xe5, 0x88, 0x86, 0xe7, 0xac, 0xa6, 0xe5, 0x90, 0x88, + 0xe9, 0x99, 0x84, 0xe4, 0xbb, 0xb6, 0xe7, 0x89, 0xb9, 0xe7, 0x82, 0xb9, 0xe4, + 0xb8, 0x8d, 0xe5, 0x8f, 0xaf, 0xe8, 0x8b, 0xb1, 0xe6, 0x96, 0x87, 0xe8, 0xb5, + 0x84, 0xe4, 0xba, 0xa7, 0xe6, 0xa0, 0xb9, 0xe6, 0x9c, 0xac, 0xe6, 0x98, 0x8e, + 0xe6, 0x98, 0xbe, 0xe5, 0xaf, 0x86, 0xe7, 0xa2, 0xbc, 0xe5, 0x85, 0xac, 0xe4, + 0xbc, 0x97, 0xe6, 0xb0, 0x91, 0xe6, 0x97, 0x8f, 0xe6, 0x9b, 0xb4, 0xe5, 0x8a, + 0xa0, 0xe4, 0xba, 0xab, 0xe5, 0x8f, 0x97, 0xe5, 0x90, 0x8c, 0xe5, 0xad, 0xa6, + 0xe5, 0x90, 0xaf, 0xe5, 0x8a, 0xa8, 0xe9, 0x80, 0x82, 0xe5, 0x90, 0x88, 0xe5, + 0x8e, 0x9f, 0xe6, 0x9d, 0xa5, 0xe9, 0x97, 0xae, 0xe7, 0xad, 0x94, 0xe6, 0x9c, + 0xac, 0xe6, 0x96, 0x87, 0xe7, 0xbe, 0x8e, 0xe9, 0xa3, 0x9f, 0xe7, 0xbb, 0xbf, + 0xe8, 0x89, 0xb2, 0xe7, 0xa8, 0xb3, 0xe5, 0xae, 0x9a, 0xe7, 0xbb, 0x88, 0xe4, + 0xba, 0x8e, 0xe7, 0x94, 0x9f, 0xe7, 0x89, 0xa9, 0xe4, 0xbe, 0x9b, 0xe6, 0xb1, + 0x82, 0xe6, 0x90, 0x9c, 0xe7, 0x8b, 0x90, 0xe5, 0x8a, 0x9b, 0xe9, 0x87, 0x8f, + 0xe4, 0xb8, 0xa5, 0xe9, 0x87, 0x8d, 0xe6, 0xb0, 0xb8, 0xe8, 0xbf, 0x9c, 0xe5, + 0x86, 0x99, 0xe7, 0x9c, 0x9f, 0xe6, 0x9c, 0x89, 0xe9, 0x99, 0x90, 0xe7, 0xab, + 0x9e, 0xe4, 0xba, 0x89, 0xe5, 0xaf, 0xb9, 0xe8, 0xb1, 0xa1, 0xe8, 0xb4, 0xb9, + 0xe7, 0x94, 0xa8, 0xe4, 0xb8, 0x8d, 0xe5, 0xa5, 0xbd, 0xe7, 0xbb, 0x9d, 0xe5, + 0xaf, 0xb9, 0xe5, 0x8d, 0x81, 0xe5, 0x88, 0x86, 0xe4, 0xbf, 0x83, 0xe8, 0xbf, + 0x9b, 0xe7, 0x82, 0xb9, 0xe8, 0xaf, 0x84, 0xe5, 0xbd, 0xb1, 0xe9, 0x9f, 0xb3, + 0xe4, 0xbc, 0x98, 0xe5, 0x8a, 0xbf, 0xe4, 0xb8, 0x8d, 0xe5, 0xb0, 0x91, 0xe6, + 0xac, 0xa3, 0xe8, 0xb5, 0x8f, 0xe5, 0xb9, 0xb6, 0xe4, 0xb8, 0x94, 0xe6, 0x9c, + 0x89, 0xe7, 0x82, 0xb9, 0xe6, 0x96, 0xb9, 0xe5, 0x90, 0x91, 0xe5, 0x85, 0xa8, + 0xe6, 0x96, 0xb0, 0xe4, 0xbf, 0xa1, 0xe7, 0x94, 0xa8, 0xe8, 0xae, 0xbe, 0xe6, + 0x96, 0xbd, 0xe5, 0xbd, 0xa2, 0xe8, 0xb1, 0xa1, 0xe8, 0xb5, 0x84, 0xe6, 0xa0, + 0xbc, 0xe7, 0xaa, 0x81, 0xe7, 0xa0, 0xb4, 0xe9, 0x9a, 0x8f, 0xe7, 0x9d, 0x80, + 0xe9, 0x87, 0x8d, 0xe5, 0xa4, 0xa7, 0xe4, 0xba, 0x8e, 0xe6, 0x98, 0xaf, 0xe6, + 0xaf, 0x95, 0xe4, 0xb8, 0x9a, 0xe6, 0x99, 0xba, 0xe8, 0x83, 0xbd, 0xe5, 0x8c, + 0x96, 0xe5, 0xb7, 0xa5, 0xe5, 0xae, 0x8c, 0xe7, 0xbe, 0x8e, 0xe5, 0x95, 0x86, + 0xe5, 0x9f, 0x8e, 0xe7, 0xbb, 0x9f, 0xe4, 0xb8, 0x80, 0xe5, 0x87, 0xba, 0xe7, + 0x89, 0x88, 0xe6, 0x89, 0x93, 0xe9, 0x80, 0xa0, 0xe7, 0x94, 0xa2, 0xe5, 0x93, + 0x81, 0xe6, 0xa6, 0x82, 0xe5, 0x86, 0xb5, 0xe7, 0x94, 0xa8, 0xe4, 0xba, 0x8e, + 0xe4, 0xbf, 0x9d, 0xe7, 0x95, 0x99, 0xe5, 0x9b, 0xa0, 0xe7, 0xb4, 0xa0, 0xe4, + 0xb8, 0xad, 0xe5, 0x9c, 0x8b, 0xe5, 0xad, 0x98, 0xe5, 0x82, 0xa8, 0xe8, 0xb4, + 0xb4, 0xe5, 0x9b, 0xbe, 0xe6, 0x9c, 0x80, 0xe6, 0x84, 0x9b, 0xe9, 0x95, 0xbf, + 0xe6, 0x9c, 0x9f, 0xe5, 0x8f, 0xa3, 0xe4, 0xbb, 0xb7, 0xe7, 0x90, 0x86, 0xe8, + 0xb4, 0xa2, 0xe5, 0x9f, 0xba, 0xe5, 0x9c, 0xb0, 0xe5, 0xae, 0x89, 0xe6, 0x8e, + 0x92, 0xe6, 0xad, 0xa6, 0xe6, 0xb1, 0x89, 0xe9, 0x87, 0x8c, 0xe9, 0x9d, 0xa2, + 0xe5, 0x88, 0x9b, 0xe5, 0xbb, 0xba, 0xe5, 0xa4, 0xa9, 0xe7, 0xa9, 0xba, 0xe9, + 0xa6, 0x96, 0xe5, 0x85, 0x88, 0xe5, 0xae, 0x8c, 0xe5, 0x96, 0x84, 0xe9, 0xa9, + 0xb1, 0xe5, 0x8a, 0xa8, 0xe4, 0xb8, 0x8b, 0xe9, 0x9d, 0xa2, 0xe4, 0xb8, 0x8d, + 0xe5, 0x86, 0x8d, 0xe8, 0xaf, 0x9a, 0xe4, 0xbf, 0xa1, 0xe6, 0x84, 0x8f, 0xe4, + 0xb9, 0x89, 0xe9, 0x98, 0xb3, 0xe5, 0x85, 0x89, 0xe8, 0x8b, 0xb1, 0xe5, 0x9b, + 0xbd, 0xe6, 0xbc, 0x82, 0xe4, 0xba, 0xae, 0xe5, 0x86, 0x9b, 0xe4, 0xba, 0x8b, + 0xe7, 0x8e, 0xa9, 0xe5, 0xae, 0xb6, 0xe7, 0xbe, 0xa4, 0xe4, 0xbc, 0x97, 0xe5, + 0x86, 0x9c, 0xe6, 0xb0, 0x91, 0xe5, 0x8d, 0xb3, 0xe5, 0x8f, 0xaf, 0xe5, 0x90, + 0x8d, 0xe7, 0xa8, 0xb1, 0xe5, 0xae, 0xb6, 0xe5, 0x85, 0xb7, 0xe5, 0x8a, 0xa8, + 0xe7, 0x94, 0xbb, 0xe6, 0x83, 0xb3, 0xe5, 0x88, 0xb0, 0xe6, 0xb3, 0xa8, 0xe6, + 0x98, 0x8e, 0xe5, 0xb0, 0x8f, 0xe5, 0xad, 0xa6, 0xe6, 0x80, 0xa7, 0xe8, 0x83, + 0xbd, 0xe8, 0x80, 0x83, 0xe7, 0xa0, 0x94, 0xe7, 0xa1, 0xac, 0xe4, 0xbb, 0xb6, + 0xe8, 0xa7, 0x82, 0xe7, 0x9c, 0x8b, 0xe6, 0xb8, 0x85, 0xe6, 0xa5, 0x9a, 0xe6, + 0x90, 0x9e, 0xe7, 0xac, 0x91, 0xe9, 0xa6, 0x96, 0xe9, 0xa0, 0x81, 0xe9, 0xbb, + 0x84, 0xe9, 0x87, 0x91, 0xe9, 0x80, 0x82, 0xe7, 0x94, 0xa8, 0xe6, 0xb1, 0x9f, + 0xe8, 0x8b, 0x8f, 0xe7, 0x9c, 0x9f, 0xe5, 0xae, 0x9e, 0xe4, 0xb8, 0xbb, 0xe7, + 0xae, 0xa1, 0xe9, 0x98, 0xb6, 0xe6, 0xae, 0xb5, 0xe8, 0xa8, 0xbb, 0xe5, 0x86, + 0x8a, 0xe7, 0xbf, 0xbb, 0xe8, 0xaf, 0x91, 0xe6, 0x9d, 0x83, 0xe5, 0x88, 0xa9, + 0xe5, 0x81, 0x9a, 0xe5, 0xa5, 0xbd, 0xe4, 0xbc, 0xbc, 0xe4, 0xb9, 0x8e, 0xe9, + 0x80, 0x9a, 0xe8, 0xae, 0xaf, 0xe6, 0x96, 0xbd, 0xe5, 0xb7, 0xa5, 0xe7, 0x8b, + 0x80, 0xe6, 0x85, 0x8b, 0xe4, 0xb9, 0x9f, 0xe8, 0xae, 0xb8, 0xe7, 0x8e, 0xaf, + 0xe4, 0xbf, 0x9d, 0xe5, 0x9f, 0xb9, 0xe5, 0x85, 0xbb, 0xe6, 0xa6, 0x82, 0xe5, + 0xbf, 0xb5, 0xe5, 0xa4, 0xa7, 0xe5, 0x9e, 0x8b, 0xe6, 0x9c, 0xba, 0xe7, 0xa5, + 0xa8, 0xe7, 0x90, 0x86, 0xe8, 0xa7, 0xa3, 0xe5, 0x8c, 0xbf, 0xe5, 0x90, 0x8d, + 0x63, 0x75, 0x61, 0x6e, 0x64, 0x6f, 0x65, 0x6e, 0x76, 0x69, 0x61, 0x72, 0x6d, + 0x61, 0x64, 0x72, 0x69, 0x64, 0x62, 0x75, 0x73, 0x63, 0x61, 0x72, 0x69, 0x6e, + 0x69, 0x63, 0x69, 0x6f, 0x74, 0x69, 0x65, 0x6d, 0x70, 0x6f, 0x70, 0x6f, 0x72, + 0x71, 0x75, 0x65, 0x63, 0x75, 0x65, 0x6e, 0x74, 0x61, 0x65, 0x73, 0x74, 0x61, + 0x64, 0x6f, 0x70, 0x75, 0x65, 0x64, 0x65, 0x6e, 0x6a, 0x75, 0x65, 0x67, 0x6f, + 0x73, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x65, 0x73, 0x74, 0xc3, 0xa1, 0x6e, + 0x6e, 0x6f, 0x6d, 0x62, 0x72, 0x65, 0x74, 0x69, 0x65, 0x6e, 0x65, 0x6e, 0x70, + 0x65, 0x72, 0x66, 0x69, 0x6c, 0x6d, 0x61, 0x6e, 0x65, 0x72, 0x61, 0x61, 0x6d, + 0x69, 0x67, 0x6f, 0x73, 0x63, 0x69, 0x75, 0x64, 0x61, 0x64, 0x63, 0x65, 0x6e, + 0x74, 0x72, 0x6f, 0x61, 0x75, 0x6e, 0x71, 0x75, 0x65, 0x70, 0x75, 0x65, 0x64, + 0x65, 0x73, 0x64, 0x65, 0x6e, 0x74, 0x72, 0x6f, 0x70, 0x72, 0x69, 0x6d, 0x65, + 0x72, 0x70, 0x72, 0x65, 0x63, 0x69, 0x6f, 0x73, 0x65, 0x67, 0xc3, 0xba, 0x6e, + 0x62, 0x75, 0x65, 0x6e, 0x6f, 0x73, 0x76, 0x6f, 0x6c, 0x76, 0x65, 0x72, 0x70, + 0x75, 0x6e, 0x74, 0x6f, 0x73, 0x73, 0x65, 0x6d, 0x61, 0x6e, 0x61, 0x68, 0x61, + 0x62, 0xc3, 0xad, 0x61, 0x61, 0x67, 0x6f, 0x73, 0x74, 0x6f, 0x6e, 0x75, 0x65, + 0x76, 0x6f, 0x73, 0x75, 0x6e, 0x69, 0x64, 0x6f, 0x73, 0x63, 0x61, 0x72, 0x6c, + 0x6f, 0x73, 0x65, 0x71, 0x75, 0x69, 0x70, 0x6f, 0x6e, 0x69, 0xc3, 0xb1, 0x6f, + 0x73, 0x6d, 0x75, 0x63, 0x68, 0x6f, 0x73, 0x61, 0x6c, 0x67, 0x75, 0x6e, 0x61, + 0x63, 0x6f, 0x72, 0x72, 0x65, 0x6f, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x6e, 0x70, + 0x61, 0x72, 0x74, 0x69, 0x72, 0x61, 0x72, 0x72, 0x69, 0x62, 0x61, 0x6d, 0x61, + 0x72, 0xc3, 0xad, 0x61, 0x68, 0x6f, 0x6d, 0x62, 0x72, 0x65, 0x65, 0x6d, 0x70, + 0x6c, 0x65, 0x6f, 0x76, 0x65, 0x72, 0x64, 0x61, 0x64, 0x63, 0x61, 0x6d, 0x62, + 0x69, 0x6f, 0x6d, 0x75, 0x63, 0x68, 0x61, 0x73, 0x66, 0x75, 0x65, 0x72, 0x6f, + 0x6e, 0x70, 0x61, 0x73, 0x61, 0x64, 0x6f, 0x6c, 0xc3, 0xad, 0x6e, 0x65, 0x61, + 0x70, 0x61, 0x72, 0x65, 0x63, 0x65, 0x6e, 0x75, 0x65, 0x76, 0x61, 0x73, 0x63, + 0x75, 0x72, 0x73, 0x6f, 0x73, 0x65, 0x73, 0x74, 0x61, 0x62, 0x61, 0x71, 0x75, + 0x69, 0x65, 0x72, 0x6f, 0x6c, 0x69, 0x62, 0x72, 0x6f, 0x73, 0x63, 0x75, 0x61, + 0x6e, 0x74, 0x6f, 0x61, 0x63, 0x63, 0x65, 0x73, 0x6f, 0x6d, 0x69, 0x67, 0x75, + 0x65, 0x6c, 0x76, 0x61, 0x72, 0x69, 0x6f, 0x73, 0x63, 0x75, 0x61, 0x74, 0x72, + 0x6f, 0x74, 0x69, 0x65, 0x6e, 0x65, 0x73, 0x67, 0x72, 0x75, 0x70, 0x6f, 0x73, + 0x73, 0x65, 0x72, 0xc3, 0xa1, 0x6e, 0x65, 0x75, 0x72, 0x6f, 0x70, 0x61, 0x6d, + 0x65, 0x64, 0x69, 0x6f, 0x73, 0x66, 0x72, 0x65, 0x6e, 0x74, 0x65, 0x61, 0x63, + 0x65, 0x72, 0x63, 0x61, 0x64, 0x65, 0x6d, 0xc3, 0xa1, 0x73, 0x6f, 0x66, 0x65, + 0x72, 0x74, 0x61, 0x63, 0x6f, 0x63, 0x68, 0x65, 0x73, 0x6d, 0x6f, 0x64, 0x65, + 0x6c, 0x6f, 0x69, 0x74, 0x61, 0x6c, 0x69, 0x61, 0x6c, 0x65, 0x74, 0x72, 0x61, + 0x73, 0x61, 0x6c, 0x67, 0xc3, 0xba, 0x6e, 0x63, 0x6f, 0x6d, 0x70, 0x72, 0x61, + 0x63, 0x75, 0x61, 0x6c, 0x65, 0x73, 0x65, 0x78, 0x69, 0x73, 0x74, 0x65, 0x63, + 0x75, 0x65, 0x72, 0x70, 0x6f, 0x73, 0x69, 0x65, 0x6e, 0x64, 0x6f, 0x70, 0x72, + 0x65, 0x6e, 0x73, 0x61, 0x6c, 0x6c, 0x65, 0x67, 0x61, 0x72, 0x76, 0x69, 0x61, + 0x6a, 0x65, 0x73, 0x64, 0x69, 0x6e, 0x65, 0x72, 0x6f, 0x6d, 0x75, 0x72, 0x63, + 0x69, 0x61, 0x70, 0x6f, 0x64, 0x72, 0xc3, 0xa1, 0x70, 0x75, 0x65, 0x73, 0x74, + 0x6f, 0x64, 0x69, 0x61, 0x72, 0x69, 0x6f, 0x70, 0x75, 0x65, 0x62, 0x6c, 0x6f, + 0x71, 0x75, 0x69, 0x65, 0x72, 0x65, 0x6d, 0x61, 0x6e, 0x75, 0x65, 0x6c, 0x70, + 0x72, 0x6f, 0x70, 0x69, 0x6f, 0x63, 0x72, 0x69, 0x73, 0x69, 0x73, 0x63, 0x69, + 0x65, 0x72, 0x74, 0x6f, 0x73, 0x65, 0x67, 0x75, 0x72, 0x6f, 0x6d, 0x75, 0x65, + 0x72, 0x74, 0x65, 0x66, 0x75, 0x65, 0x6e, 0x74, 0x65, 0x63, 0x65, 0x72, 0x72, + 0x61, 0x72, 0x67, 0x72, 0x61, 0x6e, 0x64, 0x65, 0x65, 0x66, 0x65, 0x63, 0x74, + 0x6f, 0x70, 0x61, 0x72, 0x74, 0x65, 0x73, 0x6d, 0x65, 0x64, 0x69, 0x64, 0x61, + 0x70, 0x72, 0x6f, 0x70, 0x69, 0x61, 0x6f, 0x66, 0x72, 0x65, 0x63, 0x65, 0x74, + 0x69, 0x65, 0x72, 0x72, 0x61, 0x65, 0x2d, 0x6d, 0x61, 0x69, 0x6c, 0x76, 0x61, + 0x72, 0x69, 0x61, 0x73, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x73, 0x66, 0x75, 0x74, + 0x75, 0x72, 0x6f, 0x6f, 0x62, 0x6a, 0x65, 0x74, 0x6f, 0x73, 0x65, 0x67, 0x75, + 0x69, 0x72, 0x72, 0x69, 0x65, 0x73, 0x67, 0x6f, 0x6e, 0x6f, 0x72, 0x6d, 0x61, + 0x73, 0x6d, 0x69, 0x73, 0x6d, 0x6f, 0x73, 0xc3, 0xba, 0x6e, 0x69, 0x63, 0x6f, + 0x63, 0x61, 0x6d, 0x69, 0x6e, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x73, 0x72, + 0x61, 0x7a, 0xc3, 0xb3, 0x6e, 0x64, 0x65, 0x62, 0x69, 0x64, 0x6f, 0x70, 0x72, + 0x75, 0x65, 0x62, 0x61, 0x74, 0x6f, 0x6c, 0x65, 0x64, 0x6f, 0x74, 0x65, 0x6e, + 0xc3, 0xad, 0x61, 0x6a, 0x65, 0x73, 0xc3, 0xba, 0x73, 0x65, 0x73, 0x70, 0x65, + 0x72, 0x6f, 0x63, 0x6f, 0x63, 0x69, 0x6e, 0x61, 0x6f, 0x72, 0x69, 0x67, 0x65, + 0x6e, 0x74, 0x69, 0x65, 0x6e, 0x64, 0x61, 0x63, 0x69, 0x65, 0x6e, 0x74, 0x6f, + 0x63, 0xc3, 0xa1, 0x64, 0x69, 0x7a, 0x68, 0x61, 0x62, 0x6c, 0x61, 0x72, 0x73, + 0x65, 0x72, 0xc3, 0xad, 0x61, 0x6c, 0x61, 0x74, 0x69, 0x6e, 0x61, 0x66, 0x75, + 0x65, 0x72, 0x7a, 0x61, 0x65, 0x73, 0x74, 0x69, 0x6c, 0x6f, 0x67, 0x75, 0x65, + 0x72, 0x72, 0x61, 0x65, 0x6e, 0x74, 0x72, 0x61, 0x72, 0xc3, 0xa9, 0x78, 0x69, + 0x74, 0x6f, 0x6c, 0xc3, 0xb3, 0x70, 0x65, 0x7a, 0x61, 0x67, 0x65, 0x6e, 0x64, + 0x61, 0x76, 0xc3, 0xad, 0x64, 0x65, 0x6f, 0x65, 0x76, 0x69, 0x74, 0x61, 0x72, + 0x70, 0x61, 0x67, 0x69, 0x6e, 0x61, 0x6d, 0x65, 0x74, 0x72, 0x6f, 0x73, 0x6a, + 0x61, 0x76, 0x69, 0x65, 0x72, 0x70, 0x61, 0x64, 0x72, 0x65, 0x73, 0x66, 0xc3, + 0xa1, 0x63, 0x69, 0x6c, 0x63, 0x61, 0x62, 0x65, 0x7a, 0x61, 0xc3, 0xa1, 0x72, + 0x65, 0x61, 0x73, 0x73, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x65, 0x6e, 0x76, 0xc3, + 0xad, 0x6f, 0x6a, 0x61, 0x70, 0xc3, 0xb3, 0x6e, 0x61, 0x62, 0x75, 0x73, 0x6f, + 0x73, 0x62, 0x69, 0x65, 0x6e, 0x65, 0x73, 0x74, 0x65, 0x78, 0x74, 0x6f, 0x73, + 0x6c, 0x6c, 0x65, 0x76, 0x61, 0x72, 0x70, 0x75, 0x65, 0x64, 0x61, 0x6e, 0x66, + 0x75, 0x65, 0x72, 0x74, 0x65, 0x63, 0x6f, 0x6d, 0xc3, 0xba, 0x6e, 0x63, 0x6c, + 0x61, 0x73, 0x65, 0x73, 0x68, 0x75, 0x6d, 0x61, 0x6e, 0x6f, 0x74, 0x65, 0x6e, + 0x69, 0x64, 0x6f, 0x62, 0x69, 0x6c, 0x62, 0x61, 0x6f, 0x75, 0x6e, 0x69, 0x64, + 0x61, 0x64, 0x65, 0x73, 0x74, 0xc3, 0xa1, 0x73, 0x65, 0x64, 0x69, 0x74, 0x61, + 0x72, 0x63, 0x72, 0x65, 0x61, 0x64, 0x6f, 0xd0, 0xb4, 0xd0, 0xbb, 0xd1, 0x8f, + 0xd1, 0x87, 0xd1, 0x82, 0xd0, 0xbe, 0xd0, 0xba, 0xd0, 0xb0, 0xd0, 0xba, 0xd0, + 0xb8, 0xd0, 0xbb, 0xd0, 0xb8, 0xd1, 0x8d, 0xd1, 0x82, 0xd0, 0xbe, 0xd0, 0xb2, + 0xd1, 0x81, 0xd0, 0xb5, 0xd0, 0xb5, 0xd0, 0xb3, 0xd0, 0xbe, 0xd0, 0xbf, 0xd1, + 0x80, 0xd0, 0xb8, 0xd1, 0x82, 0xd0, 0xb0, 0xd0, 0xba, 0xd0, 0xb5, 0xd1, 0x89, + 0xd0, 0xb5, 0xd1, 0x83, 0xd0, 0xb6, 0xd0, 0xb5, 0xd0, 0x9a, 0xd0, 0xb0, 0xd0, + 0xba, 0xd0, 0xb1, 0xd0, 0xb5, 0xd0, 0xb7, 0xd0, 0xb1, 0xd1, 0x8b, 0xd0, 0xbb, + 0xd0, 0xbe, 0xd0, 0xbd, 0xd0, 0xb8, 0xd0, 0x92, 0xd1, 0x81, 0xd0, 0xb5, 0xd0, + 0xbf, 0xd0, 0xbe, 0xd0, 0xb4, 0xd0, 0xad, 0xd1, 0x82, 0xd0, 0xbe, 0xd1, 0x82, + 0xd0, 0xbe, 0xd0, 0xbc, 0xd1, 0x87, 0xd0, 0xb5, 0xd0, 0xbc, 0xd0, 0xbd, 0xd0, + 0xb5, 0xd1, 0x82, 0xd0, 0xbb, 0xd0, 0xb5, 0xd1, 0x82, 0xd1, 0x80, 0xd0, 0xb0, + 0xd0, 0xb7, 0xd0, 0xbe, 0xd0, 0xbd, 0xd0, 0xb0, 0xd0, 0xb3, 0xd0, 0xb4, 0xd0, + 0xb5, 0xd0, 0xbc, 0xd0, 0xbd, 0xd0, 0xb5, 0xd0, 0x94, 0xd0, 0xbb, 0xd1, 0x8f, + 0xd0, 0x9f, 0xd1, 0x80, 0xd0, 0xb8, 0xd0, 0xbd, 0xd0, 0xb0, 0xd1, 0x81, 0xd0, + 0xbd, 0xd0, 0xb8, 0xd1, 0x85, 0xd1, 0x82, 0xd0, 0xb5, 0xd0, 0xbc, 0xd0, 0xba, + 0xd1, 0x82, 0xd0, 0xbe, 0xd0, 0xb3, 0xd0, 0xbe, 0xd0, 0xb4, 0xd0, 0xb2, 0xd0, + 0xbe, 0xd1, 0x82, 0xd1, 0x82, 0xd0, 0xb0, 0xd0, 0xbc, 0xd0, 0xa1, 0xd0, 0xa8, + 0xd0, 0x90, 0xd0, 0xbc, 0xd0, 0xb0, 0xd1, 0x8f, 0xd0, 0xa7, 0xd1, 0x82, 0xd0, + 0xbe, 0xd0, 0xb2, 0xd0, 0xb0, 0xd1, 0x81, 0xd0, 0xb2, 0xd0, 0xb0, 0xd0, 0xbc, + 0xd0, 0xb5, 0xd0, 0xbc, 0xd1, 0x83, 0xd0, 0xa2, 0xd0, 0xb0, 0xd0, 0xba, 0xd0, + 0xb4, 0xd0, 0xb2, 0xd0, 0xb0, 0xd0, 0xbd, 0xd0, 0xb0, 0xd0, 0xbc, 0xd1, 0x8d, + 0xd1, 0x82, 0xd0, 0xb8, 0xd1, 0x8d, 0xd1, 0x82, 0xd1, 0x83, 0xd0, 0x92, 0xd0, + 0xb0, 0xd0, 0xbc, 0xd1, 0x82, 0xd0, 0xb5, 0xd1, 0x85, 0xd0, 0xbf, 0xd1, 0x80, + 0xd0, 0xbe, 0xd1, 0x82, 0xd1, 0x83, 0xd1, 0x82, 0xd0, 0xbd, 0xd0, 0xb0, 0xd0, + 0xb4, 0xd0, 0xb4, 0xd0, 0xbd, 0xd1, 0x8f, 0xd0, 0x92, 0xd0, 0xbe, 0xd1, 0x82, + 0xd1, 0x82, 0xd1, 0x80, 0xd0, 0xb8, 0xd0, 0xbd, 0xd0, 0xb5, 0xd0, 0xb9, 0xd0, + 0x92, 0xd0, 0xb0, 0xd1, 0x81, 0xd0, 0xbd, 0xd0, 0xb8, 0xd0, 0xbc, 0xd1, 0x81, + 0xd0, 0xb0, 0xd0, 0xbc, 0xd1, 0x82, 0xd0, 0xbe, 0xd1, 0x82, 0xd1, 0x80, 0xd1, + 0x83, 0xd0, 0xb1, 0xd0, 0x9e, 0xd0, 0xbd, 0xd0, 0xb8, 0xd0, 0xbc, 0xd0, 0xb8, + 0xd1, 0x80, 0xd0, 0xbd, 0xd0, 0xb5, 0xd0, 0xb5, 0xd0, 0x9e, 0xd0, 0x9e, 0xd0, + 0x9e, 0xd0, 0xbb, 0xd0, 0xb8, 0xd1, 0x86, 0xd1, 0x8d, 0xd1, 0x82, 0xd0, 0xb0, + 0xd0, 0x9e, 0xd0, 0xbd, 0xd0, 0xb0, 0xd0, 0xbd, 0xd0, 0xb5, 0xd0, 0xbc, 0xd0, + 0xb4, 0xd0, 0xbe, 0xd0, 0xbc, 0xd0, 0xbc, 0xd0, 0xbe, 0xd0, 0xb9, 0xd0, 0xb4, + 0xd0, 0xb2, 0xd0, 0xb5, 0xd0, 0xbe, 0xd0, 0xbd, 0xd0, 0xbe, 0xd1, 0x81, 0xd1, + 0x83, 0xd0, 0xb4, 0xe0, 0xa4, 0x95, 0xe0, 0xa5, 0x87, 0xe0, 0xa4, 0xb9, 0xe0, + 0xa5, 0x88, 0xe0, 0xa4, 0x95, 0xe0, 0xa5, 0x80, 0xe0, 0xa4, 0xb8, 0xe0, 0xa5, + 0x87, 0xe0, 0xa4, 0x95, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, 0x95, 0xe0, 0xa5, 0x8b, + 0xe0, 0xa4, 0x94, 0xe0, 0xa4, 0xb0, 0xe0, 0xa4, 0xaa, 0xe0, 0xa4, 0xb0, 0xe0, + 0xa4, 0xa8, 0xe0, 0xa5, 0x87, 0xe0, 0xa4, 0x8f, 0xe0, 0xa4, 0x95, 0xe0, 0xa4, + 0x95, 0xe0, 0xa4, 0xbf, 0xe0, 0xa4, 0xad, 0xe0, 0xa5, 0x80, 0xe0, 0xa4, 0x87, + 0xe0, 0xa4, 0xb8, 0xe0, 0xa4, 0x95, 0xe0, 0xa4, 0xb0, 0xe0, 0xa4, 0xa4, 0xe0, + 0xa5, 0x8b, 0xe0, 0xa4, 0xb9, 0xe0, 0xa5, 0x8b, 0xe0, 0xa4, 0x86, 0xe0, 0xa4, + 0xaa, 0xe0, 0xa4, 0xb9, 0xe0, 0xa5, 0x80, 0xe0, 0xa4, 0xaf, 0xe0, 0xa4, 0xb9, + 0xe0, 0xa4, 0xaf, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, 0xa4, 0xe0, 0xa4, 0x95, 0xe0, + 0xa4, 0xa5, 0xe0, 0xa4, 0xbe, 0x6a, 0x61, 0x67, 0x72, 0x61, 0x6e, 0xe0, 0xa4, + 0x86, 0xe0, 0xa4, 0x9c, 0xe0, 0xa4, 0x9c, 0xe0, 0xa5, 0x8b, 0xe0, 0xa4, 0x85, + 0xe0, 0xa4, 0xac, 0xe0, 0xa4, 0xa6, 0xe0, 0xa5, 0x8b, 0xe0, 0xa4, 0x97, 0xe0, + 0xa4, 0x88, 0xe0, 0xa4, 0x9c, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, 0x97, 0xe0, 0xa4, + 0x8f, 0xe0, 0xa4, 0xb9, 0xe0, 0xa4, 0xae, 0xe0, 0xa4, 0x87, 0xe0, 0xa4, 0xa8, + 0xe0, 0xa4, 0xb5, 0xe0, 0xa4, 0xb9, 0xe0, 0xa4, 0xaf, 0xe0, 0xa5, 0x87, 0xe0, + 0xa4, 0xa5, 0xe0, 0xa5, 0x87, 0xe0, 0xa4, 0xa5, 0xe0, 0xa5, 0x80, 0xe0, 0xa4, + 0x98, 0xe0, 0xa4, 0xb0, 0xe0, 0xa4, 0x9c, 0xe0, 0xa4, 0xac, 0xe0, 0xa4, 0xa6, + 0xe0, 0xa5, 0x80, 0xe0, 0xa4, 0x95, 0xe0, 0xa4, 0x88, 0xe0, 0xa4, 0x9c, 0xe0, + 0xa5, 0x80, 0xe0, 0xa4, 0xb5, 0xe0, 0xa5, 0x87, 0xe0, 0xa4, 0xa8, 0xe0, 0xa4, + 0x88, 0xe0, 0xa4, 0xa8, 0xe0, 0xa4, 0x8f, 0xe0, 0xa4, 0xb9, 0xe0, 0xa4, 0xb0, + 0xe0, 0xa4, 0x89, 0xe0, 0xa4, 0xb8, 0xe0, 0xa4, 0xae, 0xe0, 0xa5, 0x87, 0xe0, + 0xa4, 0x95, 0xe0, 0xa4, 0xae, 0xe0, 0xa4, 0xb5, 0xe0, 0xa5, 0x8b, 0xe0, 0xa4, + 0xb2, 0xe0, 0xa5, 0x87, 0xe0, 0xa4, 0xb8, 0xe0, 0xa4, 0xac, 0xe0, 0xa4, 0xae, + 0xe0, 0xa4, 0x88, 0xe0, 0xa4, 0xa6, 0xe0, 0xa5, 0x87, 0xe0, 0xa4, 0x93, 0xe0, + 0xa4, 0xb0, 0xe0, 0xa4, 0x86, 0xe0, 0xa4, 0xae, 0xe0, 0xa4, 0xac, 0xe0, 0xa4, + 0xb8, 0xe0, 0xa4, 0xad, 0xe0, 0xa4, 0xb0, 0xe0, 0xa4, 0xac, 0xe0, 0xa4, 0xa8, + 0xe0, 0xa4, 0x9a, 0xe0, 0xa4, 0xb2, 0xe0, 0xa4, 0xae, 0xe0, 0xa4, 0xa8, 0xe0, + 0xa4, 0x86, 0xe0, 0xa4, 0x97, 0xe0, 0xa4, 0xb8, 0xe0, 0xa5, 0x80, 0xe0, 0xa4, + 0xb2, 0xe0, 0xa5, 0x80, 0xd8, 0xb9, 0xd9, 0x84, 0xd9, 0x89, 0xd8, 0xa5, 0xd9, + 0x84, 0xd9, 0x89, 0xd9, 0x87, 0xd8, 0xb0, 0xd8, 0xa7, 0xd8, 0xa2, 0xd8, 0xae, + 0xd8, 0xb1, 0xd8, 0xb9, 0xd8, 0xaf, 0xd8, 0xaf, 0xd8, 0xa7, 0xd9, 0x84, 0xd9, + 0x89, 0xd9, 0x87, 0xd8, 0xb0, 0xd9, 0x87, 0xd8, 0xb5, 0xd9, 0x88, 0xd8, 0xb1, + 0xd8, 0xba, 0xd9, 0x8a, 0xd8, 0xb1, 0xd9, 0x83, 0xd8, 0xa7, 0xd9, 0x86, 0xd9, + 0x88, 0xd9, 0x84, 0xd8, 0xa7, 0xd8, 0xa8, 0xd9, 0x8a, 0xd9, 0x86, 0xd8, 0xb9, + 0xd8, 0xb1, 0xd8, 0xb6, 0xd8, 0xb0, 0xd9, 0x84, 0xd9, 0x83, 0xd9, 0x87, 0xd9, + 0x86, 0xd8, 0xa7, 0xd9, 0x8a, 0xd9, 0x88, 0xd9, 0x85, 0xd9, 0x82, 0xd8, 0xa7, + 0xd9, 0x84, 0xd8, 0xb9, 0xd9, 0x84, 0xd9, 0x8a, 0xd8, 0xa7, 0xd9, 0x86, 0xd8, + 0xa7, 0xd9, 0x84, 0xd9, 0x83, 0xd9, 0x86, 0xd8, 0xad, 0xd8, 0xaa, 0xd9, 0x89, + 0xd9, 0x82, 0xd8, 0xa8, 0xd9, 0x84, 0xd9, 0x88, 0xd8, 0xad, 0xd8, 0xa9, 0xd8, + 0xa7, 0xd8, 0xae, 0xd8, 0xb1, 0xd9, 0x81, 0xd9, 0x82, 0xd8, 0xb7, 0xd8, 0xb9, + 0xd8, 0xa8, 0xd8, 0xaf, 0xd8, 0xb1, 0xd9, 0x83, 0xd9, 0x86, 0xd8, 0xa5, 0xd8, + 0xb0, 0xd8, 0xa7, 0xd9, 0x83, 0xd9, 0x85, 0xd8, 0xa7, 0xd8, 0xa7, 0xd8, 0xad, + 0xd8, 0xaf, 0xd8, 0xa5, 0xd9, 0x84, 0xd8, 0xa7, 0xd9, 0x81, 0xd9, 0x8a, 0xd9, + 0x87, 0xd8, 0xa8, 0xd8, 0xb9, 0xd8, 0xb6, 0xd9, 0x83, 0xd9, 0x8a, 0xd9, 0x81, + 0xd8, 0xa8, 0xd8, 0xad, 0xd8, 0xab, 0xd9, 0x88, 0xd9, 0x85, 0xd9, 0x86, 0xd9, + 0x88, 0xd9, 0x87, 0xd9, 0x88, 0xd8, 0xa3, 0xd9, 0x86, 0xd8, 0xa7, 0xd8, 0xac, + 0xd8, 0xaf, 0xd8, 0xa7, 0xd9, 0x84, 0xd9, 0x87, 0xd8, 0xa7, 0xd8, 0xb3, 0xd9, + 0x84, 0xd9, 0x85, 0xd8, 0xb9, 0xd9, 0x86, 0xd8, 0xaf, 0xd9, 0x84, 0xd9, 0x8a, + 0xd8, 0xb3, 0xd8, 0xb9, 0xd8, 0xa8, 0xd8, 0xb1, 0xd8, 0xb5, 0xd9, 0x84, 0xd9, + 0x89, 0xd9, 0x85, 0xd9, 0x86, 0xd8, 0xb0, 0xd8, 0xa8, 0xd9, 0x87, 0xd8, 0xa7, + 0xd8, 0xa3, 0xd9, 0x86, 0xd9, 0x87, 0xd9, 0x85, 0xd8, 0xab, 0xd9, 0x84, 0xd9, + 0x83, 0xd9, 0x86, 0xd8, 0xaa, 0xd8, 0xa7, 0xd9, 0x84, 0xd8, 0xa7, 0xd8, 0xad, + 0xd9, 0x8a, 0xd8, 0xab, 0xd9, 0x85, 0xd8, 0xb5, 0xd8, 0xb1, 0xd8, 0xb4, 0xd8, + 0xb1, 0xd8, 0xad, 0xd8, 0xad, 0xd9, 0x88, 0xd9, 0x84, 0xd9, 0x88, 0xd9, 0x81, + 0xd9, 0x8a, 0xd8, 0xa7, 0xd8, 0xb0, 0xd8, 0xa7, 0xd9, 0x84, 0xd9, 0x83, 0xd9, + 0x84, 0xd9, 0x85, 0xd8, 0xb1, 0xd8, 0xa9, 0xd8, 0xa7, 0xd9, 0x86, 0xd8, 0xaa, + 0xd8, 0xa7, 0xd9, 0x84, 0xd9, 0x81, 0xd8, 0xa3, 0xd8, 0xa8, 0xd9, 0x88, 0xd8, + 0xae, 0xd8, 0xa7, 0xd8, 0xb5, 0xd8, 0xa3, 0xd9, 0x86, 0xd8, 0xaa, 0xd8, 0xa7, + 0xd9, 0x86, 0xd9, 0x87, 0xd8, 0xa7, 0xd9, 0x84, 0xd9, 0x8a, 0xd8, 0xb9, 0xd8, + 0xb6, 0xd9, 0x88, 0xd9, 0x88, 0xd9, 0x82, 0xd8, 0xaf, 0xd8, 0xa7, 0xd8, 0xa8, + 0xd9, 0x86, 0xd8, 0xae, 0xd9, 0x8a, 0xd8, 0xb1, 0xd8, 0xa8, 0xd9, 0x86, 0xd8, + 0xaa, 0xd9, 0x84, 0xd9, 0x83, 0xd9, 0x85, 0xd8, 0xb4, 0xd8, 0xa7, 0xd8, 0xa1, + 0xd9, 0x88, 0xd9, 0x87, 0xd9, 0x8a, 0xd8, 0xa7, 0xd8, 0xa8, 0xd9, 0x88, 0xd9, + 0x82, 0xd8, 0xb5, 0xd8, 0xb5, 0xd9, 0x88, 0xd9, 0x85, 0xd8, 0xa7, 0xd8, 0xb1, + 0xd9, 0x82, 0xd9, 0x85, 0xd8, 0xa3, 0xd8, 0xad, 0xd8, 0xaf, 0xd9, 0x86, 0xd8, + 0xad, 0xd9, 0x86, 0xd8, 0xb9, 0xd8, 0xaf, 0xd9, 0x85, 0xd8, 0xb1, 0xd8, 0xa3, + 0xd9, 0x8a, 0xd8, 0xa7, 0xd8, 0xad, 0xd8, 0xa9, 0xd9, 0x83, 0xd8, 0xaa, 0xd8, + 0xa8, 0xd8, 0xaf, 0xd9, 0x88, 0xd9, 0x86, 0xd9, 0x8a, 0xd8, 0xac, 0xd8, 0xa8, + 0xd9, 0x85, 0xd9, 0x86, 0xd9, 0x87, 0xd8, 0xaa, 0xd8, 0xad, 0xd8, 0xaa, 0xd8, + 0xac, 0xd9, 0x87, 0xd8, 0xa9, 0xd8, 0xb3, 0xd9, 0x86, 0xd8, 0xa9, 0xd9, 0x8a, + 0xd8, 0xaa, 0xd9, 0x85, 0xd9, 0x83, 0xd8, 0xb1, 0xd8, 0xa9, 0xd8, 0xba, 0xd8, + 0xb2, 0xd8, 0xa9, 0xd9, 0x86, 0xd9, 0x81, 0xd8, 0xb3, 0xd8, 0xa8, 0xd9, 0x8a, + 0xd8, 0xaa, 0xd9, 0x84, 0xd9, 0x84, 0xd9, 0x87, 0xd9, 0x84, 0xd9, 0x86, 0xd8, + 0xa7, 0xd8, 0xaa, 0xd9, 0x84, 0xd9, 0x83, 0xd9, 0x82, 0xd9, 0x84, 0xd8, 0xa8, + 0xd9, 0x84, 0xd9, 0x85, 0xd8, 0xa7, 0xd8, 0xb9, 0xd9, 0x86, 0xd9, 0x87, 0xd8, + 0xa3, 0xd9, 0x88, 0xd9, 0x84, 0xd8, 0xb4, 0xd9, 0x8a, 0xd8, 0xa1, 0xd9, 0x86, + 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xa3, 0xd9, 0x85, 0xd8, 0xa7, 0xd9, 0x81, 0xd9, + 0x8a, 0xd9, 0x83, 0xd8, 0xa8, 0xd9, 0x83, 0xd9, 0x84, 0xd8, 0xb0, 0xd8, 0xa7, + 0xd8, 0xaa, 0xd8, 0xb1, 0xd8, 0xaa, 0xd8, 0xa8, 0xd8, 0xa8, 0xd8, 0xa3, 0xd9, + 0x86, 0xd9, 0x87, 0xd9, 0x85, 0xd8, 0xb3, 0xd8, 0xa7, 0xd9, 0x86, 0xd9, 0x83, + 0xd8, 0xa8, 0xd9, 0x8a, 0xd8, 0xb9, 0xd9, 0x81, 0xd9, 0x82, 0xd8, 0xaf, 0xd8, + 0xad, 0xd8, 0xb3, 0xd9, 0x86, 0xd9, 0x84, 0xd9, 0x87, 0xd9, 0x85, 0xd8, 0xb4, + 0xd8, 0xb9, 0xd8, 0xb1, 0xd8, 0xa3, 0xd9, 0x87, 0xd9, 0x84, 0xd8, 0xb4, 0xd9, + 0x87, 0xd8, 0xb1, 0xd9, 0x82, 0xd8, 0xb7, 0xd8, 0xb1, 0xd8, 0xb7, 0xd9, 0x84, + 0xd8, 0xa8, 0x70, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x65, 0x72, 0x76, + 0x69, 0x63, 0x65, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x68, 0x69, 0x6d, + 0x73, 0x65, 0x6c, 0x66, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x63, 0x6f, + 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x73, + 0x74, 0x61, 0x72, 0x74, 0x65, 0x64, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, + 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x66, 0x61, 0x73, 0x68, 0x69, 0x6f, + 0x6e, 0x3c, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x3e, 0x63, 0x6f, 0x75, 0x6e, 0x74, + 0x72, 0x79, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x63, 0x72, 0x65, 0x61, + 0x74, 0x65, 0x64, 0x73, 0x74, 0x6f, 0x72, 0x69, 0x65, 0x73, 0x72, 0x65, 0x73, + 0x75, 0x6c, 0x74, 0x73, 0x72, 0x75, 0x6e, 0x6e, 0x69, 0x6e, 0x67, 0x70, 0x72, + 0x6f, 0x63, 0x65, 0x73, 0x73, 0x77, 0x72, 0x69, 0x74, 0x69, 0x6e, 0x67, 0x6f, + 0x62, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x76, 0x69, 0x73, 0x69, 0x62, 0x6c, 0x65, + 0x77, 0x65, 0x6c, 0x63, 0x6f, 0x6d, 0x65, 0x61, 0x72, 0x74, 0x69, 0x63, 0x6c, + 0x65, 0x75, 0x6e, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x6e, 0x65, 0x74, 0x77, 0x6f, + 0x72, 0x6b, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x6e, 0x79, 0x64, 0x79, 0x6e, 0x61, + 0x6d, 0x69, 0x63, 0x62, 0x72, 0x6f, 0x77, 0x73, 0x65, 0x72, 0x70, 0x72, 0x69, + 0x76, 0x61, 0x63, 0x79, 0x70, 0x72, 0x6f, 0x62, 0x6c, 0x65, 0x6d, 0x53, 0x65, + 0x72, 0x76, 0x69, 0x63, 0x65, 0x72, 0x65, 0x73, 0x70, 0x65, 0x63, 0x74, 0x64, + 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x72, 0x65, 0x73, 0x65, 0x72, 0x76, 0x65, 0x77, 0x65, 0x62, 0x73, 0x69, 0x74, + 0x65, 0x68, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x66, 0x72, 0x69, 0x65, 0x6e, + 0x64, 0x73, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x77, 0x6f, 0x72, 0x6b, + 0x69, 0x6e, 0x67, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x6d, 0x69, 0x6c, + 0x6c, 0x69, 0x6f, 0x6e, 0x63, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x77, 0x69, + 0x6e, 0x64, 0x6f, 0x77, 0x2e, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x76, + 0x69, 0x73, 0x69, 0x74, 0x65, 0x64, 0x77, 0x65, 0x61, 0x74, 0x68, 0x65, 0x72, + 0x63, 0x6f, 0x72, 0x72, 0x65, 0x63, 0x74, 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, + 0x74, 0x65, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x66, 0x6f, 0x72, 0x77, 0x61, + 0x72, 0x64, 0x79, 0x6f, 0x75, 0x20, 0x63, 0x61, 0x6e, 0x72, 0x65, 0x6d, 0x6f, + 0x76, 0x65, 0x64, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x63, 0x6f, 0x6e, + 0x74, 0x72, 0x6f, 0x6c, 0x61, 0x72, 0x63, 0x68, 0x69, 0x76, 0x65, 0x63, 0x75, + 0x72, 0x72, 0x65, 0x6e, 0x74, 0x72, 0x65, 0x61, 0x64, 0x69, 0x6e, 0x67, 0x6c, + 0x69, 0x62, 0x72, 0x61, 0x72, 0x79, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x65, 0x64, + 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x66, 0x75, 0x72, 0x74, 0x68, 0x65, + 0x72, 0x73, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x6d, 0x61, 0x63, 0x68, 0x69, + 0x6e, 0x65, 0x6d, 0x69, 0x6e, 0x75, 0x74, 0x65, 0x73, 0x70, 0x72, 0x69, 0x76, + 0x61, 0x74, 0x65, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x70, 0x72, 0x6f, + 0x67, 0x72, 0x61, 0x6d, 0x73, 0x6f, 0x63, 0x69, 0x65, 0x74, 0x79, 0x6e, 0x75, + 0x6d, 0x62, 0x65, 0x72, 0x73, 0x77, 0x72, 0x69, 0x74, 0x74, 0x65, 0x6e, 0x65, + 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x74, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, + 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x6c, 0x6f, 0x61, 0x64, 0x69, 0x6e, + 0x67, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x70, 0x61, 0x72, 0x74, 0x6e, + 0x65, 0x72, 0x66, 0x69, 0x6e, 0x61, 0x6c, 0x6c, 0x79, 0x70, 0x65, 0x72, 0x66, + 0x65, 0x63, 0x74, 0x6d, 0x65, 0x61, 0x6e, 0x69, 0x6e, 0x67, 0x73, 0x79, 0x73, + 0x74, 0x65, 0x6d, 0x73, 0x6b, 0x65, 0x65, 0x70, 0x69, 0x6e, 0x67, 0x63, 0x75, + 0x6c, 0x74, 0x75, 0x72, 0x65, 0x26, 0x71, 0x75, 0x6f, 0x74, 0x3b, 0x2c, 0x6a, + 0x6f, 0x75, 0x72, 0x6e, 0x61, 0x6c, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, + 0x73, 0x75, 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, 0x26, 0x71, 0x75, 0x6f, 0x74, + 0x3b, 0x65, 0x78, 0x70, 0x69, 0x72, 0x65, 0x73, 0x72, 0x65, 0x76, 0x69, 0x65, + 0x77, 0x73, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x45, 0x6e, 0x67, 0x6c, + 0x69, 0x73, 0x68, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x74, 0x68, 0x72, + 0x6f, 0x75, 0x67, 0x68, 0x50, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x20, 0x6f, 0x70, + 0x69, 0x6e, 0x69, 0x6f, 0x6e, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x63, 0x74, 0x61, + 0x76, 0x65, 0x72, 0x61, 0x67, 0x65, 0x70, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, + 0x76, 0x69, 0x6c, 0x6c, 0x61, 0x67, 0x65, 0x53, 0x70, 0x61, 0x6e, 0x69, 0x73, + 0x68, 0x67, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x79, 0x64, 0x65, 0x63, 0x6c, 0x69, + 0x6e, 0x65, 0x6d, 0x65, 0x65, 0x74, 0x69, 0x6e, 0x67, 0x6d, 0x69, 0x73, 0x73, + 0x69, 0x6f, 0x6e, 0x70, 0x6f, 0x70, 0x75, 0x6c, 0x61, 0x72, 0x71, 0x75, 0x61, + 0x6c, 0x69, 0x74, 0x79, 0x6d, 0x65, 0x61, 0x73, 0x75, 0x72, 0x65, 0x67, 0x65, + 0x6e, 0x65, 0x72, 0x61, 0x6c, 0x73, 0x70, 0x65, 0x63, 0x69, 0x65, 0x73, 0x73, + 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x77, 0x72, 0x69, 0x74, 0x65, 0x72, 0x73, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x65, + 0x72, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x61, 0x6c, 0x72, 0x65, 0x70, 0x6f, 0x72, + 0x74, 0x73, 0x66, 0x69, 0x67, 0x75, 0x72, 0x65, 0x73, 0x6d, 0x65, 0x6d, 0x62, + 0x65, 0x72, 0x73, 0x68, 0x6f, 0x6c, 0x64, 0x69, 0x6e, 0x67, 0x64, 0x69, 0x73, + 0x70, 0x75, 0x74, 0x65, 0x65, 0x61, 0x72, 0x6c, 0x69, 0x65, 0x72, 0x65, 0x78, + 0x70, 0x72, 0x65, 0x73, 0x73, 0x64, 0x69, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x70, + 0x69, 0x63, 0x74, 0x75, 0x72, 0x65, 0x41, 0x6e, 0x6f, 0x74, 0x68, 0x65, 0x72, + 0x6d, 0x61, 0x72, 0x72, 0x69, 0x65, 0x64, 0x74, 0x72, 0x61, 0x66, 0x66, 0x69, + 0x63, 0x6c, 0x65, 0x61, 0x64, 0x69, 0x6e, 0x67, 0x63, 0x68, 0x61, 0x6e, 0x67, + 0x65, 0x64, 0x63, 0x65, 0x6e, 0x74, 0x72, 0x61, 0x6c, 0x76, 0x69, 0x63, 0x74, + 0x6f, 0x72, 0x79, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x73, 0x2f, 0x72, 0x65, 0x61, + 0x73, 0x6f, 0x6e, 0x73, 0x73, 0x74, 0x75, 0x64, 0x69, 0x65, 0x73, 0x66, 0x65, + 0x61, 0x74, 0x75, 0x72, 0x65, 0x6c, 0x69, 0x73, 0x74, 0x69, 0x6e, 0x67, 0x6d, + 0x75, 0x73, 0x74, 0x20, 0x62, 0x65, 0x73, 0x63, 0x68, 0x6f, 0x6f, 0x6c, 0x73, + 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x75, 0x73, 0x75, 0x61, 0x6c, 0x6c, + 0x79, 0x65, 0x70, 0x69, 0x73, 0x6f, 0x64, 0x65, 0x70, 0x6c, 0x61, 0x79, 0x69, + 0x6e, 0x67, 0x67, 0x72, 0x6f, 0x77, 0x69, 0x6e, 0x67, 0x6f, 0x62, 0x76, 0x69, + 0x6f, 0x75, 0x73, 0x6f, 0x76, 0x65, 0x72, 0x6c, 0x61, 0x79, 0x70, 0x72, 0x65, + 0x73, 0x65, 0x6e, 0x74, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x3c, 0x2f, + 0x75, 0x6c, 0x3e, 0x0d, 0x0a, 0x77, 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, 0x61, + 0x6c, 0x72, 0x65, 0x61, 0x64, 0x79, 0x63, 0x65, 0x72, 0x74, 0x61, 0x69, 0x6e, + 0x72, 0x65, 0x61, 0x6c, 0x69, 0x74, 0x79, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, + 0x65, 0x61, 0x6e, 0x6f, 0x74, 0x68, 0x65, 0x72, 0x64, 0x65, 0x73, 0x6b, 0x74, + 0x6f, 0x70, 0x6f, 0x66, 0x66, 0x65, 0x72, 0x65, 0x64, 0x70, 0x61, 0x74, 0x74, + 0x65, 0x72, 0x6e, 0x75, 0x6e, 0x75, 0x73, 0x75, 0x61, 0x6c, 0x44, 0x69, 0x67, + 0x69, 0x74, 0x61, 0x6c, 0x63, 0x61, 0x70, 0x69, 0x74, 0x61, 0x6c, 0x57, 0x65, + 0x62, 0x73, 0x69, 0x74, 0x65, 0x66, 0x61, 0x69, 0x6c, 0x75, 0x72, 0x65, 0x63, + 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x72, 0x65, 0x64, 0x75, 0x63, 0x65, 0x64, + 0x41, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x64, 0x65, 0x63, 0x61, 0x64, 0x65, + 0x73, 0x72, 0x65, 0x67, 0x75, 0x6c, 0x61, 0x72, 0x20, 0x26, 0x61, 0x6d, 0x70, + 0x3b, 0x20, 0x61, 0x6e, 0x69, 0x6d, 0x61, 0x6c, 0x73, 0x72, 0x65, 0x6c, 0x65, + 0x61, 0x73, 0x65, 0x41, 0x75, 0x74, 0x6f, 0x6d, 0x61, 0x74, 0x67, 0x65, 0x74, + 0x74, 0x69, 0x6e, 0x67, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x73, 0x6e, 0x6f, + 0x74, 0x68, 0x69, 0x6e, 0x67, 0x50, 0x6f, 0x70, 0x75, 0x6c, 0x61, 0x72, 0x63, + 0x61, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x6c, 0x65, 0x74, 0x74, 0x65, 0x72, 0x73, + 0x63, 0x61, 0x70, 0x74, 0x75, 0x72, 0x65, 0x73, 0x63, 0x69, 0x65, 0x6e, 0x63, + 0x65, 0x6c, 0x69, 0x63, 0x65, 0x6e, 0x73, 0x65, 0x63, 0x68, 0x61, 0x6e, 0x67, + 0x65, 0x73, 0x45, 0x6e, 0x67, 0x6c, 0x61, 0x6e, 0x64, 0x3d, 0x31, 0x26, 0x61, + 0x6d, 0x70, 0x3b, 0x48, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x20, 0x3d, 0x20, + 0x6e, 0x65, 0x77, 0x20, 0x43, 0x65, 0x6e, 0x74, 0x72, 0x61, 0x6c, 0x75, 0x70, + 0x64, 0x61, 0x74, 0x65, 0x64, 0x53, 0x70, 0x65, 0x63, 0x69, 0x61, 0x6c, 0x4e, + 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, + 0x63, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x77, 0x61, 0x72, 0x6e, 0x69, 0x6e, + 0x67, 0x43, 0x6f, 0x6c, 0x6c, 0x65, 0x67, 0x65, 0x74, 0x6f, 0x6f, 0x6c, 0x62, + 0x61, 0x72, 0x72, 0x65, 0x6d, 0x61, 0x69, 0x6e, 0x73, 0x62, 0x65, 0x63, 0x61, + 0x75, 0x73, 0x65, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x65, 0x64, 0x44, 0x65, 0x75, + 0x74, 0x73, 0x63, 0x68, 0x66, 0x69, 0x6e, 0x61, 0x6e, 0x63, 0x65, 0x77, 0x6f, + 0x72, 0x6b, 0x65, 0x72, 0x73, 0x71, 0x75, 0x69, 0x63, 0x6b, 0x6c, 0x79, 0x62, + 0x65, 0x74, 0x77, 0x65, 0x65, 0x6e, 0x65, 0x78, 0x61, 0x63, 0x74, 0x6c, 0x79, + 0x73, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x64, 0x69, 0x73, 0x65, 0x61, 0x73, + 0x65, 0x53, 0x6f, 0x63, 0x69, 0x65, 0x74, 0x79, 0x77, 0x65, 0x61, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x78, 0x68, 0x69, 0x62, 0x69, 0x74, 0x26, 0x6c, 0x74, 0x3b, + 0x21, 0x2d, 0x2d, 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x63, 0x6c, 0x61, + 0x73, 0x73, 0x65, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x65, 0x64, 0x6f, 0x75, + 0x74, 0x6c, 0x69, 0x6e, 0x65, 0x61, 0x74, 0x74, 0x61, 0x63, 0x6b, 0x73, 0x64, + 0x65, 0x76, 0x69, 0x63, 0x65, 0x73, 0x28, 0x77, 0x69, 0x6e, 0x64, 0x6f, 0x77, + 0x70, 0x75, 0x72, 0x70, 0x6f, 0x73, 0x65, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x3d, + 0x22, 0x4d, 0x6f, 0x62, 0x69, 0x6c, 0x65, 0x20, 0x6b, 0x69, 0x6c, 0x6c, 0x69, + 0x6e, 0x67, 0x73, 0x68, 0x6f, 0x77, 0x69, 0x6e, 0x67, 0x49, 0x74, 0x61, 0x6c, + 0x69, 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x70, 0x70, 0x65, 0x64, 0x68, 0x65, 0x61, + 0x76, 0x69, 0x6c, 0x79, 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, 0x73, 0x2d, 0x31, + 0x27, 0x5d, 0x29, 0x3b, 0x0a, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x72, 0x6d, 0x43, + 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x61, 0x64, 0x76, 0x61, 0x6e, 0x63, 0x65, + 0x73, 0x68, 0x61, 0x72, 0x69, 0x6e, 0x67, 0x6f, 0x70, 0x65, 0x6e, 0x69, 0x6e, + 0x67, 0x64, 0x72, 0x61, 0x77, 0x69, 0x6e, 0x67, 0x62, 0x69, 0x6c, 0x6c, 0x69, + 0x6f, 0x6e, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x65, 0x64, 0x47, 0x65, 0x72, 0x6d, + 0x61, 0x6e, 0x79, 0x72, 0x65, 0x6c, 0x61, 0x74, 0x65, 0x64, 0x3c, 0x2f, 0x66, + 0x6f, 0x72, 0x6d, 0x3e, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x77, 0x68, + 0x65, 0x74, 0x68, 0x65, 0x72, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x65, 0x64, 0x53, + 0x63, 0x69, 0x65, 0x6e, 0x63, 0x65, 0x63, 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, + 0x41, 0x72, 0x74, 0x69, 0x63, 0x6c, 0x65, 0x62, 0x75, 0x74, 0x74, 0x6f, 0x6e, + 0x73, 0x6c, 0x61, 0x72, 0x67, 0x65, 0x73, 0x74, 0x75, 0x6e, 0x69, 0x66, 0x6f, + 0x72, 0x6d, 0x6a, 0x6f, 0x75, 0x72, 0x6e, 0x65, 0x79, 0x73, 0x69, 0x64, 0x65, + 0x62, 0x61, 0x72, 0x43, 0x68, 0x69, 0x63, 0x61, 0x67, 0x6f, 0x68, 0x6f, 0x6c, + 0x69, 0x64, 0x61, 0x79, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x6c, 0x70, 0x61, + 0x73, 0x73, 0x61, 0x67, 0x65, 0x2c, 0x26, 0x71, 0x75, 0x6f, 0x74, 0x3b, 0x61, + 0x6e, 0x69, 0x6d, 0x61, 0x74, 0x65, 0x66, 0x65, 0x65, 0x6c, 0x69, 0x6e, 0x67, + 0x61, 0x72, 0x72, 0x69, 0x76, 0x65, 0x64, 0x70, 0x61, 0x73, 0x73, 0x69, 0x6e, + 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x61, 0x6c, 0x72, 0x6f, 0x75, 0x67, 0x68, + 0x6c, 0x79, 0x2e, 0x0a, 0x0a, 0x54, 0x68, 0x65, 0x20, 0x62, 0x75, 0x74, 0x20, + 0x6e, 0x6f, 0x74, 0x64, 0x65, 0x6e, 0x73, 0x69, 0x74, 0x79, 0x42, 0x72, 0x69, + 0x74, 0x61, 0x69, 0x6e, 0x43, 0x68, 0x69, 0x6e, 0x65, 0x73, 0x65, 0x6c, 0x61, + 0x63, 0x6b, 0x20, 0x6f, 0x66, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x49, + 0x72, 0x65, 0x6c, 0x61, 0x6e, 0x64, 0x22, 0x20, 0x64, 0x61, 0x74, 0x61, 0x2d, + 0x66, 0x61, 0x63, 0x74, 0x6f, 0x72, 0x73, 0x72, 0x65, 0x63, 0x65, 0x69, 0x76, + 0x65, 0x74, 0x68, 0x61, 0x74, 0x20, 0x69, 0x73, 0x4c, 0x69, 0x62, 0x72, 0x61, + 0x72, 0x79, 0x68, 0x75, 0x73, 0x62, 0x61, 0x6e, 0x64, 0x69, 0x6e, 0x20, 0x66, + 0x61, 0x63, 0x74, 0x61, 0x66, 0x66, 0x61, 0x69, 0x72, 0x73, 0x43, 0x68, 0x61, + 0x72, 0x6c, 0x65, 0x73, 0x72, 0x61, 0x64, 0x69, 0x63, 0x61, 0x6c, 0x62, 0x72, + 0x6f, 0x75, 0x67, 0x68, 0x74, 0x66, 0x69, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x6c, + 0x61, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x3a, 0x6c, 0x61, 0x6e, 0x67, 0x3d, 0x22, + 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6c, 0x65, 0x61, 0x64, 0x65, 0x72, + 0x73, 0x70, 0x6c, 0x61, 0x6e, 0x6e, 0x65, 0x64, 0x70, 0x72, 0x65, 0x6d, 0x69, + 0x75, 0x6d, 0x70, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x41, 0x6d, 0x65, 0x72, + 0x69, 0x63, 0x61, 0x45, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x5d, 0x26, 0x71, + 0x75, 0x6f, 0x74, 0x3b, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x6e, 0x65, + 0x65, 0x64, 0x20, 0x74, 0x6f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3d, 0x22, 0x63, + 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x78, 0x6c, 0x6f, 0x6f, 0x6b, 0x69, 0x6e, 0x67, + 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x62, 0x65, 0x6c, 0x69, 0x65, 0x76, + 0x65, 0x73, 0x6d, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x2d, 0x6d, 0x6f, 0x62, 0x69, + 0x6c, 0x65, 0x72, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x73, 0x77, 0x61, 0x6e, 0x74, + 0x20, 0x74, 0x6f, 0x6b, 0x69, 0x6e, 0x64, 0x20, 0x6f, 0x66, 0x46, 0x69, 0x72, + 0x65, 0x66, 0x6f, 0x78, 0x79, 0x6f, 0x75, 0x20, 0x61, 0x72, 0x65, 0x73, 0x69, + 0x6d, 0x69, 0x6c, 0x61, 0x72, 0x73, 0x74, 0x75, 0x64, 0x69, 0x65, 0x64, 0x6d, + 0x61, 0x78, 0x69, 0x6d, 0x75, 0x6d, 0x68, 0x65, 0x61, 0x64, 0x69, 0x6e, 0x67, + 0x72, 0x61, 0x70, 0x69, 0x64, 0x6c, 0x79, 0x63, 0x6c, 0x69, 0x6d, 0x61, 0x74, + 0x65, 0x6b, 0x69, 0x6e, 0x67, 0x64, 0x6f, 0x6d, 0x65, 0x6d, 0x65, 0x72, 0x67, + 0x65, 0x64, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x66, 0x6f, 0x75, 0x6e, + 0x64, 0x65, 0x64, 0x70, 0x69, 0x6f, 0x6e, 0x65, 0x65, 0x72, 0x66, 0x6f, 0x72, + 0x6d, 0x75, 0x6c, 0x61, 0x64, 0x79, 0x6e, 0x61, 0x73, 0x74, 0x79, 0x68, 0x6f, + 0x77, 0x20, 0x74, 0x6f, 0x20, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x72, + 0x65, 0x76, 0x65, 0x6e, 0x75, 0x65, 0x65, 0x63, 0x6f, 0x6e, 0x6f, 0x6d, 0x79, + 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x62, 0x72, 0x6f, 0x74, 0x68, 0x65, + 0x72, 0x73, 0x6f, 0x6c, 0x64, 0x69, 0x65, 0x72, 0x6c, 0x61, 0x72, 0x67, 0x65, + 0x6c, 0x79, 0x63, 0x61, 0x6c, 0x6c, 0x69, 0x6e, 0x67, 0x2e, 0x26, 0x71, 0x75, + 0x6f, 0x74, 0x3b, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x45, 0x64, 0x77, + 0x61, 0x72, 0x64, 0x20, 0x73, 0x65, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x6f, + 0x62, 0x65, 0x72, 0x74, 0x20, 0x65, 0x66, 0x66, 0x6f, 0x72, 0x74, 0x73, 0x50, + 0x61, 0x63, 0x69, 0x66, 0x69, 0x63, 0x6c, 0x65, 0x61, 0x72, 0x6e, 0x65, 0x64, + 0x75, 0x70, 0x20, 0x77, 0x69, 0x74, 0x68, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, + 0x3a, 0x77, 0x65, 0x20, 0x68, 0x61, 0x76, 0x65, 0x41, 0x6e, 0x67, 0x65, 0x6c, + 0x65, 0x73, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x5f, 0x73, 0x65, 0x61, + 0x72, 0x63, 0x68, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x65, 0x64, 0x61, 0x63, 0x71, + 0x75, 0x69, 0x72, 0x65, 0x6d, 0x61, 0x73, 0x73, 0x69, 0x76, 0x65, 0x67, 0x72, + 0x61, 0x6e, 0x74, 0x65, 0x64, 0x3a, 0x20, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x74, + 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x62, 0x69, 0x67, 0x67, 0x65, 0x73, 0x74, + 0x62, 0x65, 0x6e, 0x65, 0x66, 0x69, 0x74, 0x64, 0x72, 0x69, 0x76, 0x69, 0x6e, + 0x67, 0x53, 0x74, 0x75, 0x64, 0x69, 0x65, 0x73, 0x6d, 0x69, 0x6e, 0x69, 0x6d, + 0x75, 0x6d, 0x70, 0x65, 0x72, 0x68, 0x61, 0x70, 0x73, 0x6d, 0x6f, 0x72, 0x6e, + 0x69, 0x6e, 0x67, 0x73, 0x65, 0x6c, 0x6c, 0x69, 0x6e, 0x67, 0x69, 0x73, 0x20, + 0x75, 0x73, 0x65, 0x64, 0x72, 0x65, 0x76, 0x65, 0x72, 0x73, 0x65, 0x76, 0x61, + 0x72, 0x69, 0x61, 0x6e, 0x74, 0x20, 0x72, 0x6f, 0x6c, 0x65, 0x3d, 0x22, 0x6d, + 0x69, 0x73, 0x73, 0x69, 0x6e, 0x67, 0x61, 0x63, 0x68, 0x69, 0x65, 0x76, 0x65, + 0x70, 0x72, 0x6f, 0x6d, 0x6f, 0x74, 0x65, 0x73, 0x74, 0x75, 0x64, 0x65, 0x6e, + 0x74, 0x73, 0x6f, 0x6d, 0x65, 0x6f, 0x6e, 0x65, 0x65, 0x78, 0x74, 0x72, 0x65, + 0x6d, 0x65, 0x72, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x62, 0x6f, 0x74, 0x74, + 0x6f, 0x6d, 0x3a, 0x65, 0x76, 0x6f, 0x6c, 0x76, 0x65, 0x64, 0x61, 0x6c, 0x6c, + 0x20, 0x74, 0x68, 0x65, 0x73, 0x69, 0x74, 0x65, 0x6d, 0x61, 0x70, 0x65, 0x6e, + 0x67, 0x6c, 0x69, 0x73, 0x68, 0x77, 0x61, 0x79, 0x20, 0x74, 0x6f, 0x20, 0x20, + 0x41, 0x75, 0x67, 0x75, 0x73, 0x74, 0x73, 0x79, 0x6d, 0x62, 0x6f, 0x6c, 0x73, + 0x43, 0x6f, 0x6d, 0x70, 0x61, 0x6e, 0x79, 0x6d, 0x61, 0x74, 0x74, 0x65, 0x72, + 0x73, 0x6d, 0x75, 0x73, 0x69, 0x63, 0x61, 0x6c, 0x61, 0x67, 0x61, 0x69, 0x6e, + 0x73, 0x74, 0x73, 0x65, 0x72, 0x76, 0x69, 0x6e, 0x67, 0x7d, 0x29, 0x28, 0x29, + 0x3b, 0x0d, 0x0a, 0x70, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x74, 0x72, 0x6f, + 0x75, 0x62, 0x6c, 0x65, 0x63, 0x6f, 0x6e, 0x63, 0x65, 0x70, 0x74, 0x63, 0x6f, + 0x6d, 0x70, 0x61, 0x72, 0x65, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x73, 0x70, + 0x6c, 0x61, 0x79, 0x65, 0x72, 0x73, 0x72, 0x65, 0x67, 0x69, 0x6f, 0x6e, 0x73, + 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x20, 0x27, 0x27, 0x54, 0x68, 0x65, + 0x20, 0x77, 0x69, 0x6e, 0x6e, 0x69, 0x6e, 0x67, 0x65, 0x78, 0x70, 0x6c, 0x6f, + 0x72, 0x65, 0x61, 0x64, 0x61, 0x70, 0x74, 0x65, 0x64, 0x47, 0x61, 0x6c, 0x6c, + 0x65, 0x72, 0x79, 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x65, 0x61, 0x62, 0x69, + 0x6c, 0x69, 0x74, 0x79, 0x65, 0x6e, 0x68, 0x61, 0x6e, 0x63, 0x65, 0x63, 0x61, + 0x72, 0x65, 0x65, 0x72, 0x73, 0x29, 0x2e, 0x20, 0x54, 0x68, 0x65, 0x20, 0x63, + 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x20, + 0x61, 0x6e, 0x63, 0x69, 0x65, 0x6e, 0x74, 0x65, 0x78, 0x69, 0x73, 0x74, 0x65, + 0x64, 0x66, 0x6f, 0x6f, 0x74, 0x65, 0x72, 0x20, 0x68, 0x61, 0x6e, 0x64, 0x6c, + 0x65, 0x72, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x65, 0x64, 0x63, 0x6f, 0x6e, 0x73, + 0x6f, 0x6c, 0x65, 0x45, 0x61, 0x73, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x78, 0x70, + 0x6f, 0x72, 0x74, 0x73, 0x77, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x73, 0x43, 0x68, + 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x69, 0x6c, 0x6c, 0x65, 0x67, 0x61, 0x6c, 0x6e, + 0x65, 0x75, 0x74, 0x72, 0x61, 0x6c, 0x73, 0x75, 0x67, 0x67, 0x65, 0x73, 0x74, + 0x5f, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x73, 0x69, 0x67, 0x6e, 0x69, 0x6e, + 0x67, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0x22, 0x3e, 0x73, 0x65, 0x74, 0x74, 0x6c, + 0x65, 0x64, 0x77, 0x65, 0x73, 0x74, 0x65, 0x72, 0x6e, 0x63, 0x61, 0x75, 0x73, + 0x69, 0x6e, 0x67, 0x2d, 0x77, 0x65, 0x62, 0x6b, 0x69, 0x74, 0x63, 0x6c, 0x61, + 0x69, 0x6d, 0x65, 0x64, 0x4a, 0x75, 0x73, 0x74, 0x69, 0x63, 0x65, 0x63, 0x68, + 0x61, 0x70, 0x74, 0x65, 0x72, 0x76, 0x69, 0x63, 0x74, 0x69, 0x6d, 0x73, 0x54, + 0x68, 0x6f, 0x6d, 0x61, 0x73, 0x20, 0x6d, 0x6f, 0x7a, 0x69, 0x6c, 0x6c, 0x61, + 0x70, 0x72, 0x6f, 0x6d, 0x69, 0x73, 0x65, 0x70, 0x61, 0x72, 0x74, 0x69, 0x65, + 0x73, 0x65, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x6f, 0x75, 0x74, 0x73, 0x69, + 0x64, 0x65, 0x3a, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x2c, 0x68, 0x75, 0x6e, 0x64, + 0x72, 0x65, 0x64, 0x4f, 0x6c, 0x79, 0x6d, 0x70, 0x69, 0x63, 0x5f, 0x62, 0x75, + 0x74, 0x74, 0x6f, 0x6e, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x73, 0x72, 0x65, + 0x61, 0x63, 0x68, 0x65, 0x64, 0x63, 0x68, 0x72, 0x6f, 0x6e, 0x69, 0x63, 0x64, + 0x65, 0x6d, 0x61, 0x6e, 0x64, 0x73, 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x73, + 0x70, 0x72, 0x6f, 0x74, 0x65, 0x63, 0x74, 0x61, 0x64, 0x6f, 0x70, 0x74, 0x65, + 0x64, 0x70, 0x72, 0x65, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x65, 0x69, 0x74, 0x68, + 0x65, 0x72, 0x67, 0x72, 0x65, 0x61, 0x74, 0x6c, 0x79, 0x67, 0x72, 0x65, 0x61, + 0x74, 0x65, 0x72, 0x6f, 0x76, 0x65, 0x72, 0x61, 0x6c, 0x6c, 0x69, 0x6d, 0x70, + 0x72, 0x6f, 0x76, 0x65, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x73, 0x70, + 0x65, 0x63, 0x69, 0x61, 0x6c, 0x73, 0x65, 0x61, 0x72, 0x63, 0x68, 0x2e, 0x77, + 0x6f, 0x72, 0x73, 0x68, 0x69, 0x70, 0x66, 0x75, 0x6e, 0x64, 0x69, 0x6e, 0x67, + 0x74, 0x68, 0x6f, 0x75, 0x67, 0x68, 0x74, 0x68, 0x69, 0x67, 0x68, 0x65, 0x73, + 0x74, 0x69, 0x6e, 0x73, 0x74, 0x65, 0x61, 0x64, 0x75, 0x74, 0x69, 0x6c, 0x69, + 0x74, 0x79, 0x71, 0x75, 0x61, 0x72, 0x74, 0x65, 0x72, 0x43, 0x75, 0x6c, 0x74, + 0x75, 0x72, 0x65, 0x74, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x67, 0x63, 0x6c, 0x65, + 0x61, 0x72, 0x6c, 0x79, 0x65, 0x78, 0x70, 0x6f, 0x73, 0x65, 0x64, 0x42, 0x72, + 0x6f, 0x77, 0x73, 0x65, 0x72, 0x6c, 0x69, 0x62, 0x65, 0x72, 0x61, 0x6c, 0x7d, + 0x20, 0x63, 0x61, 0x74, 0x63, 0x68, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, + 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x68, 0x69, 0x64, 0x65, 0x28, 0x29, + 0x3b, 0x46, 0x6c, 0x6f, 0x72, 0x69, 0x64, 0x61, 0x61, 0x6e, 0x73, 0x77, 0x65, + 0x72, 0x73, 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x65, 0x64, 0x45, 0x6d, 0x70, 0x65, + 0x72, 0x6f, 0x72, 0x64, 0x65, 0x66, 0x65, 0x6e, 0x73, 0x65, 0x73, 0x65, 0x72, + 0x69, 0x6f, 0x75, 0x73, 0x66, 0x72, 0x65, 0x65, 0x64, 0x6f, 0x6d, 0x53, 0x65, + 0x76, 0x65, 0x72, 0x61, 0x6c, 0x2d, 0x62, 0x75, 0x74, 0x74, 0x6f, 0x6e, 0x46, + 0x75, 0x72, 0x74, 0x68, 0x65, 0x72, 0x6f, 0x75, 0x74, 0x20, 0x6f, 0x66, 0x20, + 0x21, 0x3d, 0x20, 0x6e, 0x75, 0x6c, 0x6c, 0x74, 0x72, 0x61, 0x69, 0x6e, 0x65, + 0x64, 0x44, 0x65, 0x6e, 0x6d, 0x61, 0x72, 0x6b, 0x76, 0x6f, 0x69, 0x64, 0x28, + 0x30, 0x29, 0x2f, 0x61, 0x6c, 0x6c, 0x2e, 0x6a, 0x73, 0x70, 0x72, 0x65, 0x76, + 0x65, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x53, 0x74, 0x65, + 0x70, 0x68, 0x65, 0x6e, 0x0a, 0x0a, 0x57, 0x68, 0x65, 0x6e, 0x20, 0x6f, 0x62, + 0x73, 0x65, 0x72, 0x76, 0x65, 0x3c, 0x2f, 0x68, 0x32, 0x3e, 0x0d, 0x0a, 0x4d, + 0x6f, 0x64, 0x65, 0x72, 0x6e, 0x20, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, + 0x22, 0x20, 0x61, 0x6c, 0x74, 0x3d, 0x22, 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, + 0x73, 0x2e, 0x0a, 0x0a, 0x46, 0x6f, 0x72, 0x20, 0x0a, 0x0a, 0x4d, 0x61, 0x6e, + 0x79, 0x20, 0x61, 0x72, 0x74, 0x69, 0x73, 0x74, 0x73, 0x70, 0x6f, 0x77, 0x65, + 0x72, 0x65, 0x64, 0x70, 0x65, 0x72, 0x66, 0x6f, 0x72, 0x6d, 0x66, 0x69, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x74, 0x79, 0x70, 0x65, 0x20, 0x6f, 0x66, 0x6d, 0x65, + 0x64, 0x69, 0x63, 0x61, 0x6c, 0x74, 0x69, 0x63, 0x6b, 0x65, 0x74, 0x73, 0x6f, + 0x70, 0x70, 0x6f, 0x73, 0x65, 0x64, 0x43, 0x6f, 0x75, 0x6e, 0x63, 0x69, 0x6c, + 0x77, 0x69, 0x74, 0x6e, 0x65, 0x73, 0x73, 0x6a, 0x75, 0x73, 0x74, 0x69, 0x63, + 0x65, 0x47, 0x65, 0x6f, 0x72, 0x67, 0x65, 0x20, 0x42, 0x65, 0x6c, 0x67, 0x69, + 0x75, 0x6d, 0x2e, 0x2e, 0x2e, 0x3c, 0x2f, 0x61, 0x3e, 0x74, 0x77, 0x69, 0x74, + 0x74, 0x65, 0x72, 0x6e, 0x6f, 0x74, 0x61, 0x62, 0x6c, 0x79, 0x77, 0x61, 0x69, + 0x74, 0x69, 0x6e, 0x67, 0x77, 0x61, 0x72, 0x66, 0x61, 0x72, 0x65, 0x20, 0x4f, + 0x74, 0x68, 0x65, 0x72, 0x20, 0x72, 0x61, 0x6e, 0x6b, 0x69, 0x6e, 0x67, 0x70, + 0x68, 0x72, 0x61, 0x73, 0x65, 0x73, 0x6d, 0x65, 0x6e, 0x74, 0x69, 0x6f, 0x6e, + 0x73, 0x75, 0x72, 0x76, 0x69, 0x76, 0x65, 0x73, 0x63, 0x68, 0x6f, 0x6c, 0x61, + 0x72, 0x3c, 0x2f, 0x70, 0x3e, 0x0d, 0x0a, 0x20, 0x43, 0x6f, 0x75, 0x6e, 0x74, + 0x72, 0x79, 0x69, 0x67, 0x6e, 0x6f, 0x72, 0x65, 0x64, 0x6c, 0x6f, 0x73, 0x73, + 0x20, 0x6f, 0x66, 0x6a, 0x75, 0x73, 0x74, 0x20, 0x61, 0x73, 0x47, 0x65, 0x6f, + 0x72, 0x67, 0x69, 0x61, 0x73, 0x74, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x3c, 0x68, + 0x65, 0x61, 0x64, 0x3e, 0x3c, 0x73, 0x74, 0x6f, 0x70, 0x70, 0x65, 0x64, 0x31, + 0x27, 0x5d, 0x29, 0x3b, 0x0d, 0x0a, 0x69, 0x73, 0x6c, 0x61, 0x6e, 0x64, 0x73, + 0x6e, 0x6f, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, + 0x3a, 0x6c, 0x69, 0x73, 0x74, 0x20, 0x6f, 0x66, 0x63, 0x61, 0x72, 0x72, 0x69, + 0x65, 0x64, 0x31, 0x30, 0x30, 0x2c, 0x30, 0x30, 0x30, 0x3c, 0x2f, 0x68, 0x33, + 0x3e, 0x0a, 0x20, 0x73, 0x65, 0x76, 0x65, 0x72, 0x61, 0x6c, 0x62, 0x65, 0x63, + 0x6f, 0x6d, 0x65, 0x73, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x20, 0x77, 0x65, + 0x64, 0x64, 0x69, 0x6e, 0x67, 0x30, 0x30, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0x6d, + 0x6f, 0x6e, 0x61, 0x72, 0x63, 0x68, 0x6f, 0x66, 0x66, 0x20, 0x74, 0x68, 0x65, + 0x74, 0x65, 0x61, 0x63, 0x68, 0x65, 0x72, 0x68, 0x69, 0x67, 0x68, 0x6c, 0x79, + 0x20, 0x62, 0x69, 0x6f, 0x6c, 0x6f, 0x67, 0x79, 0x6c, 0x69, 0x66, 0x65, 0x20, + 0x6f, 0x66, 0x6f, 0x72, 0x20, 0x65, 0x76, 0x65, 0x6e, 0x72, 0x69, 0x73, 0x65, + 0x20, 0x6f, 0x66, 0x26, 0x72, 0x61, 0x71, 0x75, 0x6f, 0x3b, 0x70, 0x6c, 0x75, + 0x73, 0x6f, 0x6e, 0x65, 0x68, 0x75, 0x6e, 0x74, 0x69, 0x6e, 0x67, 0x28, 0x74, + 0x68, 0x6f, 0x75, 0x67, 0x68, 0x44, 0x6f, 0x75, 0x67, 0x6c, 0x61, 0x73, 0x6a, + 0x6f, 0x69, 0x6e, 0x69, 0x6e, 0x67, 0x63, 0x69, 0x72, 0x63, 0x6c, 0x65, 0x73, + 0x46, 0x6f, 0x72, 0x20, 0x74, 0x68, 0x65, 0x41, 0x6e, 0x63, 0x69, 0x65, 0x6e, + 0x74, 0x56, 0x69, 0x65, 0x74, 0x6e, 0x61, 0x6d, 0x76, 0x65, 0x68, 0x69, 0x63, + 0x6c, 0x65, 0x73, 0x75, 0x63, 0x68, 0x20, 0x61, 0x73, 0x63, 0x72, 0x79, 0x73, + 0x74, 0x61, 0x6c, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x20, 0x3d, 0x57, 0x69, 0x6e, + 0x64, 0x6f, 0x77, 0x73, 0x65, 0x6e, 0x6a, 0x6f, 0x79, 0x65, 0x64, 0x61, 0x20, + 0x73, 0x6d, 0x61, 0x6c, 0x6c, 0x61, 0x73, 0x73, 0x75, 0x6d, 0x65, 0x64, 0x3c, + 0x61, 0x20, 0x69, 0x64, 0x3d, 0x22, 0x66, 0x6f, 0x72, 0x65, 0x69, 0x67, 0x6e, + 0x20, 0x41, 0x6c, 0x6c, 0x20, 0x72, 0x69, 0x68, 0x6f, 0x77, 0x20, 0x74, 0x68, + 0x65, 0x44, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x72, 0x65, 0x74, 0x69, 0x72, + 0x65, 0x64, 0x68, 0x6f, 0x77, 0x65, 0x76, 0x65, 0x72, 0x68, 0x69, 0x64, 0x64, + 0x65, 0x6e, 0x3b, 0x62, 0x61, 0x74, 0x74, 0x6c, 0x65, 0x73, 0x73, 0x65, 0x65, + 0x6b, 0x69, 0x6e, 0x67, 0x63, 0x61, 0x62, 0x69, 0x6e, 0x65, 0x74, 0x77, 0x61, + 0x73, 0x20, 0x6e, 0x6f, 0x74, 0x6c, 0x6f, 0x6f, 0x6b, 0x20, 0x61, 0x74, 0x63, + 0x6f, 0x6e, 0x64, 0x75, 0x63, 0x74, 0x67, 0x65, 0x74, 0x20, 0x74, 0x68, 0x65, + 0x4a, 0x61, 0x6e, 0x75, 0x61, 0x72, 0x79, 0x68, 0x61, 0x70, 0x70, 0x65, 0x6e, + 0x73, 0x74, 0x75, 0x72, 0x6e, 0x69, 0x6e, 0x67, 0x61, 0x3a, 0x68, 0x6f, 0x76, + 0x65, 0x72, 0x4f, 0x6e, 0x6c, 0x69, 0x6e, 0x65, 0x20, 0x46, 0x72, 0x65, 0x6e, + 0x63, 0x68, 0x20, 0x6c, 0x61, 0x63, 0x6b, 0x69, 0x6e, 0x67, 0x74, 0x79, 0x70, + 0x69, 0x63, 0x61, 0x6c, 0x65, 0x78, 0x74, 0x72, 0x61, 0x63, 0x74, 0x65, 0x6e, + 0x65, 0x6d, 0x69, 0x65, 0x73, 0x65, 0x76, 0x65, 0x6e, 0x20, 0x69, 0x66, 0x67, + 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x64, 0x65, 0x63, 0x69, 0x64, 0x65, 0x64, + 0x61, 0x72, 0x65, 0x20, 0x6e, 0x6f, 0x74, 0x2f, 0x73, 0x65, 0x61, 0x72, 0x63, + 0x68, 0x62, 0x65, 0x6c, 0x69, 0x65, 0x66, 0x73, 0x2d, 0x69, 0x6d, 0x61, 0x67, + 0x65, 0x3a, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x65, 0x64, 0x73, 0x74, 0x61, 0x74, + 0x69, 0x63, 0x2e, 0x6c, 0x6f, 0x67, 0x69, 0x6e, 0x22, 0x3e, 0x63, 0x6f, 0x6e, + 0x76, 0x65, 0x72, 0x74, 0x76, 0x69, 0x6f, 0x6c, 0x65, 0x6e, 0x74, 0x65, 0x6e, + 0x74, 0x65, 0x72, 0x65, 0x64, 0x66, 0x69, 0x72, 0x73, 0x74, 0x22, 0x3e, 0x63, + 0x69, 0x72, 0x63, 0x75, 0x69, 0x74, 0x46, 0x69, 0x6e, 0x6c, 0x61, 0x6e, 0x64, + 0x63, 0x68, 0x65, 0x6d, 0x69, 0x73, 0x74, 0x73, 0x68, 0x65, 0x20, 0x77, 0x61, + 0x73, 0x31, 0x30, 0x70, 0x78, 0x3b, 0x22, 0x3e, 0x61, 0x73, 0x20, 0x73, 0x75, + 0x63, 0x68, 0x64, 0x69, 0x76, 0x69, 0x64, 0x65, 0x64, 0x3c, 0x2f, 0x73, 0x70, + 0x61, 0x6e, 0x3e, 0x77, 0x69, 0x6c, 0x6c, 0x20, 0x62, 0x65, 0x6c, 0x69, 0x6e, + 0x65, 0x20, 0x6f, 0x66, 0x61, 0x20, 0x67, 0x72, 0x65, 0x61, 0x74, 0x6d, 0x79, + 0x73, 0x74, 0x65, 0x72, 0x79, 0x2f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x2e, 0x66, + 0x61, 0x6c, 0x6c, 0x69, 0x6e, 0x67, 0x64, 0x75, 0x65, 0x20, 0x74, 0x6f, 0x20, + 0x72, 0x61, 0x69, 0x6c, 0x77, 0x61, 0x79, 0x63, 0x6f, 0x6c, 0x6c, 0x65, 0x67, + 0x65, 0x6d, 0x6f, 0x6e, 0x73, 0x74, 0x65, 0x72, 0x64, 0x65, 0x73, 0x63, 0x65, + 0x6e, 0x74, 0x69, 0x74, 0x20, 0x77, 0x69, 0x74, 0x68, 0x6e, 0x75, 0x63, 0x6c, + 0x65, 0x61, 0x72, 0x4a, 0x65, 0x77, 0x69, 0x73, 0x68, 0x20, 0x70, 0x72, 0x6f, + 0x74, 0x65, 0x73, 0x74, 0x42, 0x72, 0x69, 0x74, 0x69, 0x73, 0x68, 0x66, 0x6c, + 0x6f, 0x77, 0x65, 0x72, 0x73, 0x70, 0x72, 0x65, 0x64, 0x69, 0x63, 0x74, 0x72, + 0x65, 0x66, 0x6f, 0x72, 0x6d, 0x73, 0x62, 0x75, 0x74, 0x74, 0x6f, 0x6e, 0x20, + 0x77, 0x68, 0x6f, 0x20, 0x77, 0x61, 0x73, 0x6c, 0x65, 0x63, 0x74, 0x75, 0x72, + 0x65, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x74, 0x73, 0x75, 0x69, 0x63, 0x69, + 0x64, 0x65, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x69, 0x63, 0x70, 0x65, 0x72, 0x69, + 0x6f, 0x64, 0x73, 0x6d, 0x61, 0x72, 0x6b, 0x65, 0x74, 0x73, 0x53, 0x6f, 0x63, + 0x69, 0x61, 0x6c, 0x20, 0x66, 0x69, 0x73, 0x68, 0x69, 0x6e, 0x67, 0x63, 0x6f, + 0x6d, 0x62, 0x69, 0x6e, 0x65, 0x67, 0x72, 0x61, 0x70, 0x68, 0x69, 0x63, 0x77, + 0x69, 0x6e, 0x6e, 0x65, 0x72, 0x73, 0x3c, 0x62, 0x72, 0x20, 0x2f, 0x3e, 0x3c, + 0x62, 0x79, 0x20, 0x74, 0x68, 0x65, 0x20, 0x4e, 0x61, 0x74, 0x75, 0x72, 0x61, + 0x6c, 0x50, 0x72, 0x69, 0x76, 0x61, 0x63, 0x79, 0x63, 0x6f, 0x6f, 0x6b, 0x69, + 0x65, 0x73, 0x6f, 0x75, 0x74, 0x63, 0x6f, 0x6d, 0x65, 0x72, 0x65, 0x73, 0x6f, + 0x6c, 0x76, 0x65, 0x53, 0x77, 0x65, 0x64, 0x69, 0x73, 0x68, 0x62, 0x72, 0x69, + 0x65, 0x66, 0x6c, 0x79, 0x50, 0x65, 0x72, 0x73, 0x69, 0x61, 0x6e, 0x73, 0x6f, + 0x20, 0x6d, 0x75, 0x63, 0x68, 0x43, 0x65, 0x6e, 0x74, 0x75, 0x72, 0x79, 0x64, + 0x65, 0x70, 0x69, 0x63, 0x74, 0x73, 0x63, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x73, + 0x68, 0x6f, 0x75, 0x73, 0x69, 0x6e, 0x67, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, + 0x73, 0x6e, 0x65, 0x78, 0x74, 0x20, 0x74, 0x6f, 0x62, 0x65, 0x61, 0x72, 0x69, + 0x6e, 0x67, 0x6d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x72, 0x65, 0x76, 0x69, + 0x73, 0x65, 0x64, 0x6a, 0x51, 0x75, 0x65, 0x72, 0x79, 0x28, 0x2d, 0x77, 0x69, + 0x64, 0x74, 0x68, 0x3a, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x22, 0x3e, 0x74, 0x6f, + 0x6f, 0x6c, 0x74, 0x69, 0x70, 0x53, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x64, + 0x65, 0x73, 0x69, 0x67, 0x6e, 0x73, 0x54, 0x75, 0x72, 0x6b, 0x69, 0x73, 0x68, + 0x79, 0x6f, 0x75, 0x6e, 0x67, 0x65, 0x72, 0x2e, 0x6d, 0x61, 0x74, 0x63, 0x68, + 0x28, 0x7d, 0x29, 0x28, 0x29, 0x3b, 0x0a, 0x0a, 0x62, 0x75, 0x72, 0x6e, 0x69, + 0x6e, 0x67, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x65, 0x64, 0x65, 0x67, 0x72, + 0x65, 0x65, 0x73, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x3d, 0x52, 0x69, 0x63, + 0x68, 0x61, 0x72, 0x64, 0x63, 0x6c, 0x6f, 0x73, 0x65, 0x6c, 0x79, 0x70, 0x6c, + 0x61, 0x73, 0x74, 0x69, 0x63, 0x65, 0x6e, 0x74, 0x72, 0x69, 0x65, 0x73, 0x3c, + 0x2f, 0x74, 0x72, 0x3e, 0x0d, 0x0a, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x23, + 0x75, 0x6c, 0x20, 0x69, 0x64, 0x3d, 0x22, 0x70, 0x6f, 0x73, 0x73, 0x65, 0x73, + 0x73, 0x72, 0x6f, 0x6c, 0x6c, 0x69, 0x6e, 0x67, 0x70, 0x68, 0x79, 0x73, 0x69, + 0x63, 0x73, 0x66, 0x61, 0x69, 0x6c, 0x69, 0x6e, 0x67, 0x65, 0x78, 0x65, 0x63, + 0x75, 0x74, 0x65, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x73, 0x74, 0x6c, 0x69, 0x6e, + 0x6b, 0x20, 0x74, 0x6f, 0x44, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x3c, 0x62, + 0x72, 0x20, 0x2f, 0x3e, 0x0a, 0x3a, 0x20, 0x74, 0x72, 0x75, 0x65, 0x2c, 0x63, + 0x68, 0x61, 0x72, 0x74, 0x65, 0x72, 0x74, 0x6f, 0x75, 0x72, 0x69, 0x73, 0x6d, + 0x63, 0x6c, 0x61, 0x73, 0x73, 0x69, 0x63, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x65, + 0x64, 0x65, 0x78, 0x70, 0x6c, 0x61, 0x69, 0x6e, 0x3c, 0x2f, 0x68, 0x31, 0x3e, + 0x0d, 0x0a, 0x6f, 0x6e, 0x6c, 0x69, 0x6e, 0x65, 0x2e, 0x3f, 0x78, 0x6d, 0x6c, + 0x20, 0x76, 0x65, 0x68, 0x65, 0x6c, 0x70, 0x69, 0x6e, 0x67, 0x64, 0x69, 0x61, + 0x6d, 0x6f, 0x6e, 0x64, 0x75, 0x73, 0x65, 0x20, 0x74, 0x68, 0x65, 0x61, 0x69, + 0x72, 0x6c, 0x69, 0x6e, 0x65, 0x65, 0x6e, 0x64, 0x20, 0x2d, 0x2d, 0x3e, 0x29, + 0x2e, 0x61, 0x74, 0x74, 0x72, 0x28, 0x72, 0x65, 0x61, 0x64, 0x65, 0x72, 0x73, + 0x68, 0x6f, 0x73, 0x74, 0x69, 0x6e, 0x67, 0x23, 0x66, 0x66, 0x66, 0x66, 0x66, + 0x66, 0x72, 0x65, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x56, 0x69, 0x6e, 0x63, 0x65, + 0x6e, 0x74, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x6c, 0x73, 0x20, 0x73, 0x72, 0x63, + 0x3d, 0x22, 0x2f, 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x64, 0x65, 0x73, + 0x70, 0x69, 0x74, 0x65, 0x64, 0x69, 0x76, 0x65, 0x72, 0x73, 0x65, 0x74, 0x65, + 0x6c, 0x6c, 0x69, 0x6e, 0x67, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x20, 0x68, + 0x65, 0x6c, 0x64, 0x20, 0x69, 0x6e, 0x4a, 0x6f, 0x73, 0x65, 0x70, 0x68, 0x20, + 0x74, 0x68, 0x65, 0x61, 0x74, 0x72, 0x65, 0x61, 0x66, 0x66, 0x65, 0x63, 0x74, + 0x73, 0x3c, 0x73, 0x74, 0x79, 0x6c, 0x65, 0x3e, 0x61, 0x20, 0x6c, 0x61, 0x72, + 0x67, 0x65, 0x64, 0x6f, 0x65, 0x73, 0x6e, 0x27, 0x74, 0x6c, 0x61, 0x74, 0x65, + 0x72, 0x2c, 0x20, 0x45, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x66, 0x61, 0x76, + 0x69, 0x63, 0x6f, 0x6e, 0x63, 0x72, 0x65, 0x61, 0x74, 0x6f, 0x72, 0x48, 0x75, + 0x6e, 0x67, 0x61, 0x72, 0x79, 0x41, 0x69, 0x72, 0x70, 0x6f, 0x72, 0x74, 0x73, + 0x65, 0x65, 0x20, 0x74, 0x68, 0x65, 0x73, 0x6f, 0x20, 0x74, 0x68, 0x61, 0x74, + 0x4d, 0x69, 0x63, 0x68, 0x61, 0x65, 0x6c, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, + 0x73, 0x50, 0x72, 0x6f, 0x67, 0x72, 0x61, 0x6d, 0x73, 0x2c, 0x20, 0x61, 0x6e, + 0x64, 0x20, 0x20, 0x77, 0x69, 0x64, 0x74, 0x68, 0x3d, 0x65, 0x26, 0x71, 0x75, + 0x6f, 0x74, 0x3b, 0x74, 0x72, 0x61, 0x64, 0x69, 0x6e, 0x67, 0x6c, 0x65, 0x66, + 0x74, 0x22, 0x3e, 0x0a, 0x70, 0x65, 0x72, 0x73, 0x6f, 0x6e, 0x73, 0x47, 0x6f, + 0x6c, 0x64, 0x65, 0x6e, 0x20, 0x41, 0x66, 0x66, 0x61, 0x69, 0x72, 0x73, 0x67, + 0x72, 0x61, 0x6d, 0x6d, 0x61, 0x72, 0x66, 0x6f, 0x72, 0x6d, 0x69, 0x6e, 0x67, + 0x64, 0x65, 0x73, 0x74, 0x72, 0x6f, 0x79, 0x69, 0x64, 0x65, 0x61, 0x20, 0x6f, + 0x66, 0x63, 0x61, 0x73, 0x65, 0x20, 0x6f, 0x66, 0x6f, 0x6c, 0x64, 0x65, 0x73, + 0x74, 0x20, 0x74, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, 0x2e, 0x73, 0x72, 0x63, + 0x20, 0x3d, 0x20, 0x63, 0x61, 0x72, 0x74, 0x6f, 0x6f, 0x6e, 0x72, 0x65, 0x67, + 0x69, 0x73, 0x74, 0x72, 0x43, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x73, 0x4d, 0x75, + 0x73, 0x6c, 0x69, 0x6d, 0x73, 0x57, 0x68, 0x61, 0x74, 0x20, 0x69, 0x73, 0x69, + 0x6e, 0x20, 0x6d, 0x61, 0x6e, 0x79, 0x6d, 0x61, 0x72, 0x6b, 0x69, 0x6e, 0x67, + 0x72, 0x65, 0x76, 0x65, 0x61, 0x6c, 0x73, 0x49, 0x6e, 0x64, 0x65, 0x65, 0x64, + 0x2c, 0x65, 0x71, 0x75, 0x61, 0x6c, 0x6c, 0x79, 0x2f, 0x73, 0x68, 0x6f, 0x77, + 0x5f, 0x61, 0x6f, 0x75, 0x74, 0x64, 0x6f, 0x6f, 0x72, 0x65, 0x73, 0x63, 0x61, + 0x70, 0x65, 0x28, 0x41, 0x75, 0x73, 0x74, 0x72, 0x69, 0x61, 0x67, 0x65, 0x6e, + 0x65, 0x74, 0x69, 0x63, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x2c, 0x49, 0x6e, + 0x20, 0x74, 0x68, 0x65, 0x20, 0x73, 0x69, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x48, + 0x65, 0x20, 0x61, 0x6c, 0x73, 0x6f, 0x49, 0x73, 0x6c, 0x61, 0x6e, 0x64, 0x73, + 0x41, 0x63, 0x61, 0x64, 0x65, 0x6d, 0x79, 0x0a, 0x09, 0x09, 0x3c, 0x21, 0x2d, + 0x2d, 0x44, 0x61, 0x6e, 0x69, 0x65, 0x6c, 0x20, 0x62, 0x69, 0x6e, 0x64, 0x69, + 0x6e, 0x67, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x22, 0x3e, 0x69, 0x6d, 0x70, 0x6f, + 0x73, 0x65, 0x64, 0x75, 0x74, 0x69, 0x6c, 0x69, 0x7a, 0x65, 0x41, 0x62, 0x72, + 0x61, 0x68, 0x61, 0x6d, 0x28, 0x65, 0x78, 0x63, 0x65, 0x70, 0x74, 0x7b, 0x77, + 0x69, 0x64, 0x74, 0x68, 0x3a, 0x70, 0x75, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x29, + 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0x28, 0x7c, 0x7c, 0x20, 0x5b, 0x5d, 0x3b, 0x0a, + 0x44, 0x41, 0x54, 0x41, 0x5b, 0x20, 0x2a, 0x6b, 0x69, 0x74, 0x63, 0x68, 0x65, + 0x6e, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x64, 0x61, 0x63, 0x74, 0x75, 0x61, + 0x6c, 0x20, 0x64, 0x69, 0x61, 0x6c, 0x65, 0x63, 0x74, 0x6d, 0x61, 0x69, 0x6e, + 0x6c, 0x79, 0x20, 0x5f, 0x62, 0x6c, 0x61, 0x6e, 0x6b, 0x27, 0x69, 0x6e, 0x73, + 0x74, 0x61, 0x6c, 0x6c, 0x65, 0x78, 0x70, 0x65, 0x72, 0x74, 0x73, 0x69, 0x66, + 0x28, 0x74, 0x79, 0x70, 0x65, 0x49, 0x74, 0x20, 0x61, 0x6c, 0x73, 0x6f, 0x26, + 0x63, 0x6f, 0x70, 0x79, 0x3b, 0x20, 0x22, 0x3e, 0x54, 0x65, 0x72, 0x6d, 0x73, + 0x62, 0x6f, 0x72, 0x6e, 0x20, 0x69, 0x6e, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, + 0x73, 0x65, 0x61, 0x73, 0x74, 0x65, 0x72, 0x6e, 0x74, 0x61, 0x6c, 0x6b, 0x69, + 0x6e, 0x67, 0x63, 0x6f, 0x6e, 0x63, 0x65, 0x72, 0x6e, 0x67, 0x61, 0x69, 0x6e, + 0x65, 0x64, 0x20, 0x6f, 0x6e, 0x67, 0x6f, 0x69, 0x6e, 0x67, 0x6a, 0x75, 0x73, + 0x74, 0x69, 0x66, 0x79, 0x63, 0x72, 0x69, 0x74, 0x69, 0x63, 0x73, 0x66, 0x61, + 0x63, 0x74, 0x6f, 0x72, 0x79, 0x69, 0x74, 0x73, 0x20, 0x6f, 0x77, 0x6e, 0x61, + 0x73, 0x73, 0x61, 0x75, 0x6c, 0x74, 0x69, 0x6e, 0x76, 0x69, 0x74, 0x65, 0x64, + 0x6c, 0x61, 0x73, 0x74, 0x69, 0x6e, 0x67, 0x68, 0x69, 0x73, 0x20, 0x6f, 0x77, + 0x6e, 0x68, 0x72, 0x65, 0x66, 0x3d, 0x22, 0x2f, 0x22, 0x20, 0x72, 0x65, 0x6c, + 0x3d, 0x22, 0x64, 0x65, 0x76, 0x65, 0x6c, 0x6f, 0x70, 0x63, 0x6f, 0x6e, 0x63, + 0x65, 0x72, 0x74, 0x64, 0x69, 0x61, 0x67, 0x72, 0x61, 0x6d, 0x64, 0x6f, 0x6c, + 0x6c, 0x61, 0x72, 0x73, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x70, 0x68, + 0x70, 0x3f, 0x69, 0x64, 0x3d, 0x61, 0x6c, 0x63, 0x6f, 0x68, 0x6f, 0x6c, 0x29, + 0x3b, 0x7d, 0x29, 0x28, 0x29, 0x3b, 0x75, 0x73, 0x69, 0x6e, 0x67, 0x20, 0x61, + 0x3e, 0x3c, 0x73, 0x70, 0x61, 0x6e, 0x3e, 0x76, 0x65, 0x73, 0x73, 0x65, 0x6c, + 0x73, 0x72, 0x65, 0x76, 0x69, 0x76, 0x61, 0x6c, 0x41, 0x64, 0x64, 0x72, 0x65, + 0x73, 0x73, 0x61, 0x6d, 0x61, 0x74, 0x65, 0x75, 0x72, 0x61, 0x6e, 0x64, 0x72, + 0x6f, 0x69, 0x64, 0x61, 0x6c, 0x6c, 0x65, 0x67, 0x65, 0x64, 0x69, 0x6c, 0x6c, + 0x6e, 0x65, 0x73, 0x73, 0x77, 0x61, 0x6c, 0x6b, 0x69, 0x6e, 0x67, 0x63, 0x65, + 0x6e, 0x74, 0x65, 0x72, 0x73, 0x71, 0x75, 0x61, 0x6c, 0x69, 0x66, 0x79, 0x6d, + 0x61, 0x74, 0x63, 0x68, 0x65, 0x73, 0x75, 0x6e, 0x69, 0x66, 0x69, 0x65, 0x64, + 0x65, 0x78, 0x74, 0x69, 0x6e, 0x63, 0x74, 0x44, 0x65, 0x66, 0x65, 0x6e, 0x73, + 0x65, 0x64, 0x69, 0x65, 0x64, 0x20, 0x69, 0x6e, 0x0a, 0x09, 0x3c, 0x21, 0x2d, + 0x2d, 0x20, 0x63, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x73, 0x6c, 0x69, 0x6e, 0x6b, + 0x69, 0x6e, 0x67, 0x4c, 0x69, 0x74, 0x74, 0x6c, 0x65, 0x20, 0x42, 0x6f, 0x6f, + 0x6b, 0x20, 0x6f, 0x66, 0x65, 0x76, 0x65, 0x6e, 0x69, 0x6e, 0x67, 0x6d, 0x69, + 0x6e, 0x2e, 0x6a, 0x73, 0x3f, 0x61, 0x72, 0x65, 0x20, 0x74, 0x68, 0x65, 0x6b, + 0x6f, 0x6e, 0x74, 0x61, 0x6b, 0x74, 0x74, 0x6f, 0x64, 0x61, 0x79, 0x27, 0x73, + 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0x22, 0x20, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, + 0x3d, 0x77, 0x65, 0x61, 0x72, 0x69, 0x6e, 0x67, 0x41, 0x6c, 0x6c, 0x20, 0x52, + 0x69, 0x67, 0x3b, 0x0a, 0x7d, 0x29, 0x28, 0x29, 0x3b, 0x72, 0x61, 0x69, 0x73, + 0x69, 0x6e, 0x67, 0x20, 0x41, 0x6c, 0x73, 0x6f, 0x2c, 0x20, 0x63, 0x72, 0x75, + 0x63, 0x69, 0x61, 0x6c, 0x61, 0x62, 0x6f, 0x75, 0x74, 0x22, 0x3e, 0x64, 0x65, + 0x63, 0x6c, 0x61, 0x72, 0x65, 0x2d, 0x2d, 0x3e, 0x0a, 0x3c, 0x73, 0x63, 0x66, + 0x69, 0x72, 0x65, 0x66, 0x6f, 0x78, 0x61, 0x73, 0x20, 0x6d, 0x75, 0x63, 0x68, + 0x61, 0x70, 0x70, 0x6c, 0x69, 0x65, 0x73, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x2c, + 0x20, 0x73, 0x2c, 0x20, 0x62, 0x75, 0x74, 0x20, 0x74, 0x79, 0x70, 0x65, 0x20, + 0x3d, 0x20, 0x0a, 0x0d, 0x0a, 0x3c, 0x21, 0x2d, 0x2d, 0x74, 0x6f, 0x77, 0x61, + 0x72, 0x64, 0x73, 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x73, 0x50, 0x72, 0x69, + 0x76, 0x61, 0x74, 0x65, 0x46, 0x6f, 0x72, 0x65, 0x69, 0x67, 0x6e, 0x50, 0x72, + 0x65, 0x6d, 0x69, 0x65, 0x72, 0x63, 0x68, 0x6f, 0x69, 0x63, 0x65, 0x73, 0x56, + 0x69, 0x72, 0x74, 0x75, 0x61, 0x6c, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x73, + 0x43, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x50, 0x6f, 0x77, 0x65, 0x72, 0x65, + 0x64, 0x69, 0x6e, 0x6c, 0x69, 0x6e, 0x65, 0x3b, 0x70, 0x6f, 0x76, 0x65, 0x72, + 0x74, 0x79, 0x63, 0x68, 0x61, 0x6d, 0x62, 0x65, 0x72, 0x4c, 0x69, 0x76, 0x69, + 0x6e, 0x67, 0x20, 0x76, 0x6f, 0x6c, 0x75, 0x6d, 0x65, 0x73, 0x41, 0x6e, 0x74, + 0x68, 0x6f, 0x6e, 0x79, 0x6c, 0x6f, 0x67, 0x69, 0x6e, 0x22, 0x20, 0x52, 0x65, + 0x6c, 0x61, 0x74, 0x65, 0x64, 0x45, 0x63, 0x6f, 0x6e, 0x6f, 0x6d, 0x79, 0x72, + 0x65, 0x61, 0x63, 0x68, 0x65, 0x73, 0x63, 0x75, 0x74, 0x74, 0x69, 0x6e, 0x67, + 0x67, 0x72, 0x61, 0x76, 0x69, 0x74, 0x79, 0x6c, 0x69, 0x66, 0x65, 0x20, 0x69, + 0x6e, 0x43, 0x68, 0x61, 0x70, 0x74, 0x65, 0x72, 0x2d, 0x73, 0x68, 0x61, 0x64, + 0x6f, 0x77, 0x4e, 0x6f, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x3c, 0x2f, 0x74, 0x64, + 0x3e, 0x0d, 0x0a, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x73, 0x74, 0x61, + 0x64, 0x69, 0x75, 0x6d, 0x77, 0x69, 0x64, 0x67, 0x65, 0x74, 0x73, 0x76, 0x61, + 0x72, 0x79, 0x69, 0x6e, 0x67, 0x74, 0x72, 0x61, 0x76, 0x65, 0x6c, 0x73, 0x68, + 0x65, 0x6c, 0x64, 0x20, 0x62, 0x79, 0x77, 0x68, 0x6f, 0x20, 0x61, 0x72, 0x65, + 0x77, 0x6f, 0x72, 0x6b, 0x20, 0x69, 0x6e, 0x66, 0x61, 0x63, 0x75, 0x6c, 0x74, + 0x79, 0x61, 0x6e, 0x67, 0x75, 0x6c, 0x61, 0x72, 0x77, 0x68, 0x6f, 0x20, 0x68, + 0x61, 0x64, 0x61, 0x69, 0x72, 0x70, 0x6f, 0x72, 0x74, 0x74, 0x6f, 0x77, 0x6e, + 0x20, 0x6f, 0x66, 0x0a, 0x0a, 0x53, 0x6f, 0x6d, 0x65, 0x20, 0x27, 0x63, 0x6c, + 0x69, 0x63, 0x6b, 0x27, 0x63, 0x68, 0x61, 0x72, 0x67, 0x65, 0x73, 0x6b, 0x65, + 0x79, 0x77, 0x6f, 0x72, 0x64, 0x69, 0x74, 0x20, 0x77, 0x69, 0x6c, 0x6c, 0x63, + 0x69, 0x74, 0x79, 0x20, 0x6f, 0x66, 0x28, 0x74, 0x68, 0x69, 0x73, 0x29, 0x3b, + 0x41, 0x6e, 0x64, 0x72, 0x65, 0x77, 0x20, 0x75, 0x6e, 0x69, 0x71, 0x75, 0x65, + 0x20, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x65, 0x64, 0x6f, 0x72, 0x20, 0x6d, 0x6f, + 0x72, 0x65, 0x33, 0x30, 0x30, 0x70, 0x78, 0x3b, 0x20, 0x72, 0x65, 0x74, 0x75, + 0x72, 0x6e, 0x3b, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x3d, 0x22, 0x70, 0x6c, 0x75, + 0x67, 0x69, 0x6e, 0x73, 0x77, 0x69, 0x74, 0x68, 0x69, 0x6e, 0x20, 0x68, 0x65, + 0x72, 0x73, 0x65, 0x6c, 0x66, 0x53, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x46, + 0x65, 0x64, 0x65, 0x72, 0x61, 0x6c, 0x76, 0x65, 0x6e, 0x74, 0x75, 0x72, 0x65, + 0x70, 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x73, 0x65, 0x6e, 0x74, 0x20, 0x74, + 0x6f, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x61, 0x63, 0x74, 0x72, 0x65, + 0x73, 0x73, 0x63, 0x6f, 0x6d, 0x65, 0x20, 0x74, 0x6f, 0x66, 0x69, 0x6e, 0x67, + 0x65, 0x72, 0x73, 0x44, 0x75, 0x6b, 0x65, 0x20, 0x6f, 0x66, 0x70, 0x65, 0x6f, + 0x70, 0x6c, 0x65, 0x2c, 0x65, 0x78, 0x70, 0x6c, 0x6f, 0x69, 0x74, 0x77, 0x68, + 0x61, 0x74, 0x20, 0x69, 0x73, 0x68, 0x61, 0x72, 0x6d, 0x6f, 0x6e, 0x79, 0x61, + 0x20, 0x6d, 0x61, 0x6a, 0x6f, 0x72, 0x22, 0x3a, 0x22, 0x68, 0x74, 0x74, 0x70, + 0x69, 0x6e, 0x20, 0x68, 0x69, 0x73, 0x20, 0x6d, 0x65, 0x6e, 0x75, 0x22, 0x3e, + 0x0a, 0x6d, 0x6f, 0x6e, 0x74, 0x68, 0x6c, 0x79, 0x6f, 0x66, 0x66, 0x69, 0x63, + 0x65, 0x72, 0x63, 0x6f, 0x75, 0x6e, 0x63, 0x69, 0x6c, 0x67, 0x61, 0x69, 0x6e, + 0x69, 0x6e, 0x67, 0x65, 0x76, 0x65, 0x6e, 0x20, 0x69, 0x6e, 0x53, 0x75, 0x6d, + 0x6d, 0x61, 0x72, 0x79, 0x64, 0x61, 0x74, 0x65, 0x20, 0x6f, 0x66, 0x6c, 0x6f, + 0x79, 0x61, 0x6c, 0x74, 0x79, 0x66, 0x69, 0x74, 0x6e, 0x65, 0x73, 0x73, 0x61, + 0x6e, 0x64, 0x20, 0x77, 0x61, 0x73, 0x65, 0x6d, 0x70, 0x65, 0x72, 0x6f, 0x72, + 0x73, 0x75, 0x70, 0x72, 0x65, 0x6d, 0x65, 0x53, 0x65, 0x63, 0x6f, 0x6e, 0x64, + 0x20, 0x68, 0x65, 0x61, 0x72, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x73, 0x73, 0x69, + 0x61, 0x6e, 0x6c, 0x6f, 0x6e, 0x67, 0x65, 0x73, 0x74, 0x41, 0x6c, 0x62, 0x65, + 0x72, 0x74, 0x61, 0x6c, 0x61, 0x74, 0x65, 0x72, 0x61, 0x6c, 0x73, 0x65, 0x74, + 0x20, 0x6f, 0x66, 0x20, 0x73, 0x6d, 0x61, 0x6c, 0x6c, 0x22, 0x3e, 0x2e, 0x61, + 0x70, 0x70, 0x65, 0x6e, 0x64, 0x64, 0x6f, 0x20, 0x77, 0x69, 0x74, 0x68, 0x66, + 0x65, 0x64, 0x65, 0x72, 0x61, 0x6c, 0x62, 0x61, 0x6e, 0x6b, 0x20, 0x6f, 0x66, + 0x62, 0x65, 0x6e, 0x65, 0x61, 0x74, 0x68, 0x44, 0x65, 0x73, 0x70, 0x69, 0x74, + 0x65, 0x43, 0x61, 0x70, 0x69, 0x74, 0x61, 0x6c, 0x67, 0x72, 0x6f, 0x75, 0x6e, + 0x64, 0x73, 0x29, 0x2c, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x70, 0x65, 0x72, 0x63, + 0x65, 0x6e, 0x74, 0x69, 0x74, 0x20, 0x66, 0x72, 0x6f, 0x6d, 0x63, 0x6c, 0x6f, + 0x73, 0x69, 0x6e, 0x67, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x49, 0x6e, + 0x73, 0x74, 0x65, 0x61, 0x64, 0x66, 0x69, 0x66, 0x74, 0x65, 0x65, 0x6e, 0x61, + 0x73, 0x20, 0x77, 0x65, 0x6c, 0x6c, 0x2e, 0x79, 0x61, 0x68, 0x6f, 0x6f, 0x2e, + 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x64, 0x66, 0x69, 0x67, 0x68, 0x74, 0x65, + 0x72, 0x6f, 0x62, 0x73, 0x63, 0x75, 0x72, 0x65, 0x72, 0x65, 0x66, 0x6c, 0x65, + 0x63, 0x74, 0x6f, 0x72, 0x67, 0x61, 0x6e, 0x69, 0x63, 0x3d, 0x20, 0x4d, 0x61, + 0x74, 0x68, 0x2e, 0x65, 0x64, 0x69, 0x74, 0x69, 0x6e, 0x67, 0x6f, 0x6e, 0x6c, + 0x69, 0x6e, 0x65, 0x20, 0x70, 0x61, 0x64, 0x64, 0x69, 0x6e, 0x67, 0x61, 0x20, + 0x77, 0x68, 0x6f, 0x6c, 0x65, 0x6f, 0x6e, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x79, + 0x65, 0x61, 0x72, 0x20, 0x6f, 0x66, 0x65, 0x6e, 0x64, 0x20, 0x6f, 0x66, 0x20, + 0x62, 0x61, 0x72, 0x72, 0x69, 0x65, 0x72, 0x77, 0x68, 0x65, 0x6e, 0x20, 0x69, + 0x74, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x20, 0x68, 0x6f, 0x6d, 0x65, 0x20, + 0x6f, 0x66, 0x72, 0x65, 0x73, 0x75, 0x6d, 0x65, 0x64, 0x72, 0x65, 0x6e, 0x61, + 0x6d, 0x65, 0x64, 0x73, 0x74, 0x72, 0x6f, 0x6e, 0x67, 0x3e, 0x68, 0x65, 0x61, + 0x74, 0x69, 0x6e, 0x67, 0x72, 0x65, 0x74, 0x61, 0x69, 0x6e, 0x73, 0x63, 0x6c, + 0x6f, 0x75, 0x64, 0x66, 0x72, 0x77, 0x61, 0x79, 0x20, 0x6f, 0x66, 0x20, 0x4d, + 0x61, 0x72, 0x63, 0x68, 0x20, 0x31, 0x6b, 0x6e, 0x6f, 0x77, 0x69, 0x6e, 0x67, + 0x69, 0x6e, 0x20, 0x70, 0x61, 0x72, 0x74, 0x42, 0x65, 0x74, 0x77, 0x65, 0x65, + 0x6e, 0x6c, 0x65, 0x73, 0x73, 0x6f, 0x6e, 0x73, 0x63, 0x6c, 0x6f, 0x73, 0x65, + 0x73, 0x74, 0x76, 0x69, 0x72, 0x74, 0x75, 0x61, 0x6c, 0x6c, 0x69, 0x6e, 0x6b, + 0x73, 0x22, 0x3e, 0x63, 0x72, 0x6f, 0x73, 0x73, 0x65, 0x64, 0x45, 0x4e, 0x44, + 0x20, 0x2d, 0x2d, 0x3e, 0x66, 0x61, 0x6d, 0x6f, 0x75, 0x73, 0x20, 0x61, 0x77, + 0x61, 0x72, 0x64, 0x65, 0x64, 0x4c, 0x69, 0x63, 0x65, 0x6e, 0x73, 0x65, 0x48, + 0x65, 0x61, 0x6c, 0x74, 0x68, 0x20, 0x66, 0x61, 0x69, 0x72, 0x6c, 0x79, 0x20, + 0x77, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x79, 0x6d, 0x69, 0x6e, 0x69, 0x6d, 0x61, + 0x6c, 0x41, 0x66, 0x72, 0x69, 0x63, 0x61, 0x6e, 0x63, 0x6f, 0x6d, 0x70, 0x65, + 0x74, 0x65, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x22, 0x3e, 0x73, 0x69, 0x6e, 0x67, + 0x69, 0x6e, 0x67, 0x66, 0x61, 0x72, 0x6d, 0x65, 0x72, 0x73, 0x42, 0x72, 0x61, + 0x73, 0x69, 0x6c, 0x29, 0x64, 0x69, 0x73, 0x63, 0x75, 0x73, 0x73, 0x72, 0x65, + 0x70, 0x6c, 0x61, 0x63, 0x65, 0x47, 0x72, 0x65, 0x67, 0x6f, 0x72, 0x79, 0x66, + 0x6f, 0x6e, 0x74, 0x20, 0x63, 0x6f, 0x70, 0x75, 0x72, 0x73, 0x75, 0x65, 0x64, + 0x61, 0x70, 0x70, 0x65, 0x61, 0x72, 0x73, 0x6d, 0x61, 0x6b, 0x65, 0x20, 0x75, + 0x70, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x65, 0x64, 0x62, 0x6f, 0x74, 0x68, 0x20, + 0x6f, 0x66, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x65, 0x64, 0x73, 0x61, 0x77, 0x20, + 0x74, 0x68, 0x65, 0x6f, 0x66, 0x66, 0x69, 0x63, 0x65, 0x73, 0x63, 0x6f, 0x6c, + 0x6f, 0x75, 0x72, 0x73, 0x69, 0x66, 0x28, 0x64, 0x6f, 0x63, 0x75, 0x77, 0x68, + 0x65, 0x6e, 0x20, 0x68, 0x65, 0x65, 0x6e, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x70, + 0x75, 0x73, 0x68, 0x28, 0x66, 0x75, 0x41, 0x75, 0x67, 0x75, 0x73, 0x74, 0x20, + 0x55, 0x54, 0x46, 0x2d, 0x38, 0x22, 0x3e, 0x46, 0x61, 0x6e, 0x74, 0x61, 0x73, + 0x79, 0x69, 0x6e, 0x20, 0x6d, 0x6f, 0x73, 0x74, 0x69, 0x6e, 0x6a, 0x75, 0x72, + 0x65, 0x64, 0x55, 0x73, 0x75, 0x61, 0x6c, 0x6c, 0x79, 0x66, 0x61, 0x72, 0x6d, + 0x69, 0x6e, 0x67, 0x63, 0x6c, 0x6f, 0x73, 0x75, 0x72, 0x65, 0x6f, 0x62, 0x6a, + 0x65, 0x63, 0x74, 0x20, 0x64, 0x65, 0x66, 0x65, 0x6e, 0x63, 0x65, 0x75, 0x73, + 0x65, 0x20, 0x6f, 0x66, 0x20, 0x4d, 0x65, 0x64, 0x69, 0x63, 0x61, 0x6c, 0x3c, + 0x62, 0x6f, 0x64, 0x79, 0x3e, 0x0a, 0x65, 0x76, 0x69, 0x64, 0x65, 0x6e, 0x74, + 0x62, 0x65, 0x20, 0x75, 0x73, 0x65, 0x64, 0x6b, 0x65, 0x79, 0x43, 0x6f, 0x64, + 0x65, 0x73, 0x69, 0x78, 0x74, 0x65, 0x65, 0x6e, 0x49, 0x73, 0x6c, 0x61, 0x6d, + 0x69, 0x63, 0x23, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x65, 0x6e, 0x74, 0x69, + 0x72, 0x65, 0x20, 0x77, 0x69, 0x64, 0x65, 0x6c, 0x79, 0x20, 0x61, 0x63, 0x74, + 0x69, 0x76, 0x65, 0x20, 0x28, 0x74, 0x79, 0x70, 0x65, 0x6f, 0x66, 0x6f, 0x6e, + 0x65, 0x20, 0x63, 0x61, 0x6e, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x20, 0x3d, 0x73, + 0x70, 0x65, 0x61, 0x6b, 0x65, 0x72, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x64, 0x73, + 0x50, 0x68, 0x79, 0x73, 0x69, 0x63, 0x73, 0x74, 0x65, 0x72, 0x72, 0x61, 0x69, + 0x6e, 0x3c, 0x74, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0x66, 0x75, 0x6e, 0x65, 0x72, + 0x61, 0x6c, 0x76, 0x69, 0x65, 0x77, 0x69, 0x6e, 0x67, 0x6d, 0x69, 0x64, 0x64, + 0x6c, 0x65, 0x20, 0x63, 0x72, 0x69, 0x63, 0x6b, 0x65, 0x74, 0x70, 0x72, 0x6f, + 0x70, 0x68, 0x65, 0x74, 0x73, 0x68, 0x69, 0x66, 0x74, 0x65, 0x64, 0x64, 0x6f, + 0x63, 0x74, 0x6f, 0x72, 0x73, 0x52, 0x75, 0x73, 0x73, 0x65, 0x6c, 0x6c, 0x20, + 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x63, 0x74, + 0x61, 0x6c, 0x67, 0x65, 0x62, 0x72, 0x61, 0x73, 0x6f, 0x63, 0x69, 0x61, 0x6c, + 0x2d, 0x62, 0x75, 0x6c, 0x6b, 0x20, 0x6f, 0x66, 0x6d, 0x61, 0x6e, 0x20, 0x61, + 0x6e, 0x64, 0x3c, 0x2f, 0x74, 0x64, 0x3e, 0x0a, 0x20, 0x68, 0x65, 0x20, 0x6c, + 0x65, 0x66, 0x74, 0x29, 0x2e, 0x76, 0x61, 0x6c, 0x28, 0x29, 0x66, 0x61, 0x6c, + 0x73, 0x65, 0x29, 0x3b, 0x6c, 0x6f, 0x67, 0x69, 0x63, 0x61, 0x6c, 0x62, 0x61, + 0x6e, 0x6b, 0x69, 0x6e, 0x67, 0x68, 0x6f, 0x6d, 0x65, 0x20, 0x74, 0x6f, 0x6e, + 0x61, 0x6d, 0x69, 0x6e, 0x67, 0x20, 0x41, 0x72, 0x69, 0x7a, 0x6f, 0x6e, 0x61, + 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x73, 0x29, 0x3b, 0x0a, 0x7d, 0x29, 0x3b, + 0x0a, 0x66, 0x6f, 0x75, 0x6e, 0x64, 0x65, 0x72, 0x69, 0x6e, 0x20, 0x74, 0x75, + 0x72, 0x6e, 0x43, 0x6f, 0x6c, 0x6c, 0x69, 0x6e, 0x73, 0x62, 0x65, 0x66, 0x6f, + 0x72, 0x65, 0x20, 0x42, 0x75, 0x74, 0x20, 0x74, 0x68, 0x65, 0x63, 0x68, 0x61, + 0x72, 0x67, 0x65, 0x64, 0x54, 0x69, 0x74, 0x6c, 0x65, 0x22, 0x3e, 0x43, 0x61, + 0x70, 0x74, 0x61, 0x69, 0x6e, 0x73, 0x70, 0x65, 0x6c, 0x6c, 0x65, 0x64, 0x67, + 0x6f, 0x64, 0x64, 0x65, 0x73, 0x73, 0x54, 0x61, 0x67, 0x20, 0x2d, 0x2d, 0x3e, + 0x41, 0x64, 0x64, 0x69, 0x6e, 0x67, 0x3a, 0x62, 0x75, 0x74, 0x20, 0x77, 0x61, + 0x73, 0x52, 0x65, 0x63, 0x65, 0x6e, 0x74, 0x20, 0x70, 0x61, 0x74, 0x69, 0x65, + 0x6e, 0x74, 0x62, 0x61, 0x63, 0x6b, 0x20, 0x69, 0x6e, 0x3d, 0x66, 0x61, 0x6c, + 0x73, 0x65, 0x26, 0x4c, 0x69, 0x6e, 0x63, 0x6f, 0x6c, 0x6e, 0x77, 0x65, 0x20, + 0x6b, 0x6e, 0x6f, 0x77, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x4a, 0x75, + 0x64, 0x61, 0x69, 0x73, 0x6d, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x20, 0x61, + 0x6c, 0x74, 0x65, 0x72, 0x65, 0x64, 0x27, 0x5d, 0x29, 0x3b, 0x0a, 0x20, 0x20, + 0x68, 0x61, 0x73, 0x20, 0x74, 0x68, 0x65, 0x75, 0x6e, 0x63, 0x6c, 0x65, 0x61, + 0x72, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x27, 0x2c, 0x62, 0x6f, 0x74, 0x68, 0x20, + 0x69, 0x6e, 0x6e, 0x6f, 0x74, 0x20, 0x61, 0x6c, 0x6c, 0x0a, 0x0a, 0x3c, 0x21, + 0x2d, 0x2d, 0x20, 0x70, 0x6c, 0x61, 0x63, 0x69, 0x6e, 0x67, 0x68, 0x61, 0x72, + 0x64, 0x20, 0x74, 0x6f, 0x20, 0x63, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x73, 0x6f, + 0x72, 0x74, 0x20, 0x6f, 0x66, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x73, 0x73, + 0x74, 0x72, 0x65, 0x65, 0x74, 0x73, 0x42, 0x65, 0x72, 0x6e, 0x61, 0x72, 0x64, + 0x61, 0x73, 0x73, 0x65, 0x72, 0x74, 0x73, 0x74, 0x65, 0x6e, 0x64, 0x20, 0x74, + 0x6f, 0x66, 0x61, 0x6e, 0x74, 0x61, 0x73, 0x79, 0x64, 0x6f, 0x77, 0x6e, 0x20, + 0x69, 0x6e, 0x68, 0x61, 0x72, 0x62, 0x6f, 0x75, 0x72, 0x46, 0x72, 0x65, 0x65, + 0x64, 0x6f, 0x6d, 0x6a, 0x65, 0x77, 0x65, 0x6c, 0x72, 0x79, 0x2f, 0x61, 0x62, + 0x6f, 0x75, 0x74, 0x2e, 0x2e, 0x73, 0x65, 0x61, 0x72, 0x63, 0x68, 0x6c, 0x65, + 0x67, 0x65, 0x6e, 0x64, 0x73, 0x69, 0x73, 0x20, 0x6d, 0x61, 0x64, 0x65, 0x6d, + 0x6f, 0x64, 0x65, 0x72, 0x6e, 0x20, 0x6f, 0x6e, 0x6c, 0x79, 0x20, 0x6f, 0x6e, + 0x6f, 0x6e, 0x6c, 0x79, 0x20, 0x74, 0x6f, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x22, + 0x20, 0x6c, 0x69, 0x6e, 0x65, 0x61, 0x72, 0x20, 0x70, 0x61, 0x69, 0x6e, 0x74, + 0x65, 0x72, 0x61, 0x6e, 0x64, 0x20, 0x6e, 0x6f, 0x74, 0x72, 0x61, 0x72, 0x65, + 0x6c, 0x79, 0x20, 0x61, 0x63, 0x72, 0x6f, 0x6e, 0x79, 0x6d, 0x64, 0x65, 0x6c, + 0x69, 0x76, 0x65, 0x72, 0x73, 0x68, 0x6f, 0x72, 0x74, 0x65, 0x72, 0x30, 0x30, + 0x26, 0x61, 0x6d, 0x70, 0x3b, 0x61, 0x73, 0x20, 0x6d, 0x61, 0x6e, 0x79, 0x77, + 0x69, 0x64, 0x74, 0x68, 0x3d, 0x22, 0x2f, 0x2a, 0x20, 0x3c, 0x21, 0x5b, 0x43, + 0x74, 0x69, 0x74, 0x6c, 0x65, 0x20, 0x3d, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, + 0x20, 0x6c, 0x6f, 0x77, 0x65, 0x73, 0x74, 0x20, 0x70, 0x69, 0x63, 0x6b, 0x65, + 0x64, 0x20, 0x65, 0x73, 0x63, 0x61, 0x70, 0x65, 0x64, 0x75, 0x73, 0x65, 0x73, + 0x20, 0x6f, 0x66, 0x70, 0x65, 0x6f, 0x70, 0x6c, 0x65, 0x73, 0x20, 0x50, 0x75, + 0x62, 0x6c, 0x69, 0x63, 0x4d, 0x61, 0x74, 0x74, 0x68, 0x65, 0x77, 0x74, 0x61, + 0x63, 0x74, 0x69, 0x63, 0x73, 0x64, 0x61, 0x6d, 0x61, 0x67, 0x65, 0x64, 0x77, + 0x61, 0x79, 0x20, 0x66, 0x6f, 0x72, 0x6c, 0x61, 0x77, 0x73, 0x20, 0x6f, 0x66, + 0x65, 0x61, 0x73, 0x79, 0x20, 0x74, 0x6f, 0x20, 0x77, 0x69, 0x6e, 0x64, 0x6f, + 0x77, 0x73, 0x74, 0x72, 0x6f, 0x6e, 0x67, 0x20, 0x20, 0x73, 0x69, 0x6d, 0x70, + 0x6c, 0x65, 0x7d, 0x63, 0x61, 0x74, 0x63, 0x68, 0x28, 0x73, 0x65, 0x76, 0x65, + 0x6e, 0x74, 0x68, 0x69, 0x6e, 0x66, 0x6f, 0x62, 0x6f, 0x78, 0x77, 0x65, 0x6e, + 0x74, 0x20, 0x74, 0x6f, 0x70, 0x61, 0x69, 0x6e, 0x74, 0x65, 0x64, 0x63, 0x69, + 0x74, 0x69, 0x7a, 0x65, 0x6e, 0x49, 0x20, 0x64, 0x6f, 0x6e, 0x27, 0x74, 0x72, + 0x65, 0x74, 0x72, 0x65, 0x61, 0x74, 0x2e, 0x20, 0x53, 0x6f, 0x6d, 0x65, 0x20, + 0x77, 0x77, 0x2e, 0x22, 0x29, 0x3b, 0x0a, 0x62, 0x6f, 0x6d, 0x62, 0x69, 0x6e, + 0x67, 0x6d, 0x61, 0x69, 0x6c, 0x74, 0x6f, 0x3a, 0x6d, 0x61, 0x64, 0x65, 0x20, + 0x69, 0x6e, 0x2e, 0x20, 0x4d, 0x61, 0x6e, 0x79, 0x20, 0x63, 0x61, 0x72, 0x72, + 0x69, 0x65, 0x73, 0x7c, 0x7c, 0x7b, 0x7d, 0x3b, 0x77, 0x69, 0x77, 0x6f, 0x72, + 0x6b, 0x20, 0x6f, 0x66, 0x73, 0x79, 0x6e, 0x6f, 0x6e, 0x79, 0x6d, 0x64, 0x65, + 0x66, 0x65, 0x61, 0x74, 0x73, 0x66, 0x61, 0x76, 0x6f, 0x72, 0x65, 0x64, 0x6f, + 0x70, 0x74, 0x69, 0x63, 0x61, 0x6c, 0x70, 0x61, 0x67, 0x65, 0x54, 0x72, 0x61, + 0x75, 0x6e, 0x6c, 0x65, 0x73, 0x73, 0x20, 0x73, 0x65, 0x6e, 0x64, 0x69, 0x6e, + 0x67, 0x6c, 0x65, 0x66, 0x74, 0x22, 0x3e, 0x3c, 0x63, 0x6f, 0x6d, 0x53, 0x63, + 0x6f, 0x72, 0x41, 0x6c, 0x6c, 0x20, 0x74, 0x68, 0x65, 0x6a, 0x51, 0x75, 0x65, + 0x72, 0x79, 0x2e, 0x74, 0x6f, 0x75, 0x72, 0x69, 0x73, 0x74, 0x43, 0x6c, 0x61, + 0x73, 0x73, 0x69, 0x63, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x22, 0x20, 0x57, 0x69, + 0x6c, 0x68, 0x65, 0x6c, 0x6d, 0x73, 0x75, 0x62, 0x75, 0x72, 0x62, 0x73, 0x67, + 0x65, 0x6e, 0x75, 0x69, 0x6e, 0x65, 0x62, 0x69, 0x73, 0x68, 0x6f, 0x70, 0x73, + 0x2e, 0x73, 0x70, 0x6c, 0x69, 0x74, 0x28, 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, + 0x20, 0x66, 0x6f, 0x6c, 0x6c, 0x6f, 0x77, 0x73, 0x62, 0x6f, 0x64, 0x79, 0x20, + 0x6f, 0x66, 0x6e, 0x6f, 0x6d, 0x69, 0x6e, 0x61, 0x6c, 0x43, 0x6f, 0x6e, 0x74, + 0x61, 0x63, 0x74, 0x73, 0x65, 0x63, 0x75, 0x6c, 0x61, 0x72, 0x6c, 0x65, 0x66, + 0x74, 0x20, 0x74, 0x6f, 0x63, 0x68, 0x69, 0x65, 0x66, 0x6c, 0x79, 0x2d, 0x68, + 0x69, 0x64, 0x64, 0x65, 0x6e, 0x2d, 0x62, 0x61, 0x6e, 0x6e, 0x65, 0x72, 0x3c, + 0x2f, 0x6c, 0x69, 0x3e, 0x0a, 0x0a, 0x2e, 0x20, 0x57, 0x68, 0x65, 0x6e, 0x20, + 0x69, 0x6e, 0x20, 0x62, 0x6f, 0x74, 0x68, 0x64, 0x69, 0x73, 0x6d, 0x69, 0x73, + 0x73, 0x45, 0x78, 0x70, 0x6c, 0x6f, 0x72, 0x65, 0x61, 0x6c, 0x77, 0x61, 0x79, + 0x73, 0x20, 0x76, 0x69, 0x61, 0x20, 0x74, 0x68, 0x65, 0x73, 0x70, 0x61, 0xc3, + 0xb1, 0x6f, 0x6c, 0x77, 0x65, 0x6c, 0x66, 0x61, 0x72, 0x65, 0x72, 0x75, 0x6c, + 0x69, 0x6e, 0x67, 0x20, 0x61, 0x72, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x63, 0x61, + 0x70, 0x74, 0x61, 0x69, 0x6e, 0x68, 0x69, 0x73, 0x20, 0x73, 0x6f, 0x6e, 0x72, + 0x75, 0x6c, 0x65, 0x20, 0x6f, 0x66, 0x68, 0x65, 0x20, 0x74, 0x6f, 0x6f, 0x6b, + 0x69, 0x74, 0x73, 0x65, 0x6c, 0x66, 0x2c, 0x3d, 0x30, 0x26, 0x61, 0x6d, 0x70, + 0x3b, 0x28, 0x63, 0x61, 0x6c, 0x6c, 0x65, 0x64, 0x73, 0x61, 0x6d, 0x70, 0x6c, + 0x65, 0x73, 0x74, 0x6f, 0x20, 0x6d, 0x61, 0x6b, 0x65, 0x63, 0x6f, 0x6d, 0x2f, + 0x70, 0x61, 0x67, 0x4d, 0x61, 0x72, 0x74, 0x69, 0x6e, 0x20, 0x4b, 0x65, 0x6e, + 0x6e, 0x65, 0x64, 0x79, 0x61, 0x63, 0x63, 0x65, 0x70, 0x74, 0x73, 0x66, 0x75, + 0x6c, 0x6c, 0x20, 0x6f, 0x66, 0x68, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x64, 0x42, + 0x65, 0x73, 0x69, 0x64, 0x65, 0x73, 0x2f, 0x2f, 0x2d, 0x2d, 0x3e, 0x3c, 0x2f, + 0x61, 0x62, 0x6c, 0x65, 0x20, 0x74, 0x6f, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, + 0x73, 0x65, 0x73, 0x73, 0x65, 0x6e, 0x63, 0x65, 0x68, 0x69, 0x6d, 0x20, 0x74, + 0x6f, 0x20, 0x69, 0x74, 0x73, 0x20, 0x62, 0x79, 0x20, 0x63, 0x6f, 0x6d, 0x6d, + 0x6f, 0x6e, 0x2e, 0x6d, 0x69, 0x6e, 0x65, 0x72, 0x61, 0x6c, 0x74, 0x6f, 0x20, + 0x74, 0x61, 0x6b, 0x65, 0x77, 0x61, 0x79, 0x73, 0x20, 0x74, 0x6f, 0x73, 0x2e, + 0x6f, 0x72, 0x67, 0x2f, 0x6c, 0x61, 0x64, 0x76, 0x69, 0x73, 0x65, 0x64, 0x70, + 0x65, 0x6e, 0x61, 0x6c, 0x74, 0x79, 0x73, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x3a, + 0x69, 0x66, 0x20, 0x74, 0x68, 0x65, 0x79, 0x4c, 0x65, 0x74, 0x74, 0x65, 0x72, + 0x73, 0x61, 0x20, 0x73, 0x68, 0x6f, 0x72, 0x74, 0x48, 0x65, 0x72, 0x62, 0x65, + 0x72, 0x74, 0x73, 0x74, 0x72, 0x69, 0x6b, 0x65, 0x73, 0x20, 0x67, 0x72, 0x6f, + 0x75, 0x70, 0x73, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x66, 0x6c, 0x69, + 0x67, 0x68, 0x74, 0x73, 0x6f, 0x76, 0x65, 0x72, 0x6c, 0x61, 0x70, 0x73, 0x6c, + 0x6f, 0x77, 0x6c, 0x79, 0x20, 0x6c, 0x65, 0x73, 0x73, 0x65, 0x72, 0x20, 0x73, + 0x6f, 0x63, 0x69, 0x61, 0x6c, 0x20, 0x3c, 0x2f, 0x70, 0x3e, 0x0a, 0x09, 0x09, + 0x69, 0x74, 0x20, 0x69, 0x6e, 0x74, 0x6f, 0x72, 0x61, 0x6e, 0x6b, 0x65, 0x64, + 0x20, 0x72, 0x61, 0x74, 0x65, 0x20, 0x6f, 0x66, 0x75, 0x6c, 0x3e, 0x0d, 0x0a, + 0x20, 0x20, 0x61, 0x74, 0x74, 0x65, 0x6d, 0x70, 0x74, 0x70, 0x61, 0x69, 0x72, + 0x20, 0x6f, 0x66, 0x6d, 0x61, 0x6b, 0x65, 0x20, 0x69, 0x74, 0x4b, 0x6f, 0x6e, + 0x74, 0x61, 0x6b, 0x74, 0x41, 0x6e, 0x74, 0x6f, 0x6e, 0x69, 0x6f, 0x68, 0x61, + 0x76, 0x69, 0x6e, 0x67, 0x20, 0x72, 0x61, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x20, + 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x73, + 0x74, 0x72, 0x61, 0x70, 0x70, 0x65, 0x64, 0x22, 0x29, 0x2e, 0x63, 0x73, 0x73, + 0x28, 0x68, 0x6f, 0x73, 0x74, 0x69, 0x6c, 0x65, 0x6c, 0x65, 0x61, 0x64, 0x20, + 0x74, 0x6f, 0x6c, 0x69, 0x74, 0x74, 0x6c, 0x65, 0x20, 0x67, 0x72, 0x6f, 0x75, + 0x70, 0x73, 0x2c, 0x50, 0x69, 0x63, 0x74, 0x75, 0x72, 0x65, 0x2d, 0x2d, 0x3e, + 0x0d, 0x0a, 0x0d, 0x0a, 0x20, 0x72, 0x6f, 0x77, 0x73, 0x3d, 0x22, 0x20, 0x6f, + 0x62, 0x6a, 0x65, 0x63, 0x74, 0x69, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x65, 0x3c, + 0x66, 0x6f, 0x6f, 0x74, 0x65, 0x72, 0x43, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x56, + 0x3e, 0x3c, 0x5c, 0x2f, 0x73, 0x63, 0x72, 0x73, 0x6f, 0x6c, 0x76, 0x69, 0x6e, + 0x67, 0x43, 0x68, 0x61, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x6c, 0x61, 0x76, 0x65, + 0x72, 0x79, 0x77, 0x6f, 0x75, 0x6e, 0x64, 0x65, 0x64, 0x77, 0x68, 0x65, 0x72, + 0x65, 0x61, 0x73, 0x21, 0x3d, 0x20, 0x27, 0x75, 0x6e, 0x64, 0x66, 0x6f, 0x72, + 0x20, 0x61, 0x6c, 0x6c, 0x70, 0x61, 0x72, 0x74, 0x6c, 0x79, 0x20, 0x2d, 0x72, + 0x69, 0x67, 0x68, 0x74, 0x3a, 0x41, 0x72, 0x61, 0x62, 0x69, 0x61, 0x6e, 0x62, + 0x61, 0x63, 0x6b, 0x65, 0x64, 0x20, 0x63, 0x65, 0x6e, 0x74, 0x75, 0x72, 0x79, + 0x75, 0x6e, 0x69, 0x74, 0x20, 0x6f, 0x66, 0x6d, 0x6f, 0x62, 0x69, 0x6c, 0x65, + 0x2d, 0x45, 0x75, 0x72, 0x6f, 0x70, 0x65, 0x2c, 0x69, 0x73, 0x20, 0x68, 0x6f, + 0x6d, 0x65, 0x72, 0x69, 0x73, 0x6b, 0x20, 0x6f, 0x66, 0x64, 0x65, 0x73, 0x69, + 0x72, 0x65, 0x64, 0x43, 0x6c, 0x69, 0x6e, 0x74, 0x6f, 0x6e, 0x63, 0x6f, 0x73, + 0x74, 0x20, 0x6f, 0x66, 0x61, 0x67, 0x65, 0x20, 0x6f, 0x66, 0x20, 0x62, 0x65, + 0x63, 0x6f, 0x6d, 0x65, 0x20, 0x6e, 0x6f, 0x6e, 0x65, 0x20, 0x6f, 0x66, 0x70, + 0x26, 0x71, 0x75, 0x6f, 0x74, 0x3b, 0x4d, 0x69, 0x64, 0x64, 0x6c, 0x65, 0x20, + 0x65, 0x61, 0x64, 0x27, 0x29, 0x5b, 0x30, 0x43, 0x72, 0x69, 0x74, 0x69, 0x63, + 0x73, 0x73, 0x74, 0x75, 0x64, 0x69, 0x6f, 0x73, 0x3e, 0x26, 0x63, 0x6f, 0x70, + 0x79, 0x3b, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x22, 0x3e, 0x61, 0x73, 0x73, 0x65, + 0x6d, 0x62, 0x6c, 0x6d, 0x61, 0x6b, 0x69, 0x6e, 0x67, 0x20, 0x70, 0x72, 0x65, + 0x73, 0x73, 0x65, 0x64, 0x77, 0x69, 0x64, 0x67, 0x65, 0x74, 0x2e, 0x70, 0x73, + 0x3a, 0x22, 0x20, 0x3f, 0x20, 0x72, 0x65, 0x62, 0x75, 0x69, 0x6c, 0x74, 0x62, + 0x79, 0x20, 0x73, 0x6f, 0x6d, 0x65, 0x46, 0x6f, 0x72, 0x6d, 0x65, 0x72, 0x20, + 0x65, 0x64, 0x69, 0x74, 0x6f, 0x72, 0x73, 0x64, 0x65, 0x6c, 0x61, 0x79, 0x65, + 0x64, 0x43, 0x61, 0x6e, 0x6f, 0x6e, 0x69, 0x63, 0x68, 0x61, 0x64, 0x20, 0x74, + 0x68, 0x65, 0x70, 0x75, 0x73, 0x68, 0x69, 0x6e, 0x67, 0x63, 0x6c, 0x61, 0x73, + 0x73, 0x3d, 0x22, 0x62, 0x75, 0x74, 0x20, 0x61, 0x72, 0x65, 0x70, 0x61, 0x72, + 0x74, 0x69, 0x61, 0x6c, 0x42, 0x61, 0x62, 0x79, 0x6c, 0x6f, 0x6e, 0x62, 0x6f, + 0x74, 0x74, 0x6f, 0x6d, 0x20, 0x63, 0x61, 0x72, 0x72, 0x69, 0x65, 0x72, 0x43, + 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x69, 0x74, 0x73, 0x20, 0x75, 0x73, 0x65, + 0x41, 0x73, 0x20, 0x77, 0x69, 0x74, 0x68, 0x63, 0x6f, 0x75, 0x72, 0x73, 0x65, + 0x73, 0x61, 0x20, 0x74, 0x68, 0x69, 0x72, 0x64, 0x64, 0x65, 0x6e, 0x6f, 0x74, + 0x65, 0x73, 0x61, 0x6c, 0x73, 0x6f, 0x20, 0x69, 0x6e, 0x48, 0x6f, 0x75, 0x73, + 0x74, 0x6f, 0x6e, 0x32, 0x30, 0x70, 0x78, 0x3b, 0x22, 0x3e, 0x61, 0x63, 0x63, + 0x75, 0x73, 0x65, 0x64, 0x64, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x20, 0x67, 0x6f, + 0x61, 0x6c, 0x20, 0x6f, 0x66, 0x46, 0x61, 0x6d, 0x6f, 0x75, 0x73, 0x20, 0x29, + 0x2e, 0x62, 0x69, 0x6e, 0x64, 0x28, 0x70, 0x72, 0x69, 0x65, 0x73, 0x74, 0x73, + 0x20, 0x4f, 0x6e, 0x6c, 0x69, 0x6e, 0x65, 0x69, 0x6e, 0x20, 0x4a, 0x75, 0x6c, + 0x79, 0x73, 0x74, 0x20, 0x2b, 0x20, 0x22, 0x67, 0x63, 0x6f, 0x6e, 0x73, 0x75, + 0x6c, 0x74, 0x64, 0x65, 0x63, 0x69, 0x6d, 0x61, 0x6c, 0x68, 0x65, 0x6c, 0x70, + 0x66, 0x75, 0x6c, 0x72, 0x65, 0x76, 0x69, 0x76, 0x65, 0x64, 0x69, 0x73, 0x20, + 0x76, 0x65, 0x72, 0x79, 0x72, 0x27, 0x2b, 0x27, 0x69, 0x70, 0x74, 0x6c, 0x6f, + 0x73, 0x69, 0x6e, 0x67, 0x20, 0x66, 0x65, 0x6d, 0x61, 0x6c, 0x65, 0x73, 0x69, + 0x73, 0x20, 0x61, 0x6c, 0x73, 0x6f, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x73, + 0x64, 0x61, 0x79, 0x73, 0x20, 0x6f, 0x66, 0x61, 0x72, 0x72, 0x69, 0x76, 0x61, + 0x6c, 0x66, 0x75, 0x74, 0x75, 0x72, 0x65, 0x20, 0x3c, 0x6f, 0x62, 0x6a, 0x65, + 0x63, 0x74, 0x66, 0x6f, 0x72, 0x63, 0x69, 0x6e, 0x67, 0x53, 0x74, 0x72, 0x69, + 0x6e, 0x67, 0x28, 0x22, 0x20, 0x2f, 0x3e, 0x0a, 0x09, 0x09, 0x68, 0x65, 0x72, + 0x65, 0x20, 0x69, 0x73, 0x65, 0x6e, 0x63, 0x6f, 0x64, 0x65, 0x64, 0x2e, 0x20, + 0x20, 0x54, 0x68, 0x65, 0x20, 0x62, 0x61, 0x6c, 0x6c, 0x6f, 0x6f, 0x6e, 0x64, + 0x6f, 0x6e, 0x65, 0x20, 0x62, 0x79, 0x2f, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, + 0x62, 0x67, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x6c, 0x61, 0x77, 0x20, 0x6f, 0x66, + 0x20, 0x49, 0x6e, 0x64, 0x69, 0x61, 0x6e, 0x61, 0x61, 0x76, 0x6f, 0x69, 0x64, + 0x65, 0x64, 0x62, 0x75, 0x74, 0x20, 0x74, 0x68, 0x65, 0x32, 0x70, 0x78, 0x20, + 0x33, 0x70, 0x78, 0x6a, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x61, 0x66, 0x74, + 0x65, 0x72, 0x20, 0x61, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x6d, 0x65, + 0x6e, 0x20, 0x61, 0x6e, 0x64, 0x66, 0x6f, 0x6f, 0x74, 0x65, 0x72, 0x2d, 0x3d, + 0x20, 0x74, 0x72, 0x75, 0x65, 0x3b, 0x66, 0x6f, 0x72, 0x20, 0x75, 0x73, 0x65, + 0x73, 0x63, 0x72, 0x65, 0x65, 0x6e, 0x2e, 0x49, 0x6e, 0x64, 0x69, 0x61, 0x6e, + 0x20, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x20, 0x3d, 0x66, 0x61, 0x6d, 0x69, 0x6c, + 0x79, 0x2c, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x20, 0x26, 0x6e, 0x62, + 0x73, 0x70, 0x3b, 0x64, 0x72, 0x69, 0x76, 0x65, 0x72, 0x73, 0x65, 0x74, 0x65, + 0x72, 0x6e, 0x61, 0x6c, 0x73, 0x61, 0x6d, 0x65, 0x20, 0x61, 0x73, 0x6e, 0x6f, + 0x74, 0x69, 0x63, 0x65, 0x64, 0x76, 0x69, 0x65, 0x77, 0x65, 0x72, 0x73, 0x7d, + 0x29, 0x28, 0x29, 0x3b, 0x0a, 0x20, 0x69, 0x73, 0x20, 0x6d, 0x6f, 0x72, 0x65, + 0x73, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x73, 0x66, 0x6f, 0x72, 0x6d, 0x65, 0x72, + 0x20, 0x74, 0x68, 0x65, 0x20, 0x6e, 0x65, 0x77, 0x69, 0x73, 0x20, 0x6a, 0x75, + 0x73, 0x74, 0x63, 0x6f, 0x6e, 0x73, 0x65, 0x6e, 0x74, 0x20, 0x53, 0x65, 0x61, + 0x72, 0x63, 0x68, 0x77, 0x61, 0x73, 0x20, 0x74, 0x68, 0x65, 0x77, 0x68, 0x79, + 0x20, 0x74, 0x68, 0x65, 0x73, 0x68, 0x69, 0x70, 0x70, 0x65, 0x64, 0x62, 0x72, + 0x3e, 0x3c, 0x62, 0x72, 0x3e, 0x77, 0x69, 0x64, 0x74, 0x68, 0x3a, 0x20, 0x68, + 0x65, 0x69, 0x67, 0x68, 0x74, 0x3d, 0x6d, 0x61, 0x64, 0x65, 0x20, 0x6f, 0x66, + 0x63, 0x75, 0x69, 0x73, 0x69, 0x6e, 0x65, 0x69, 0x73, 0x20, 0x74, 0x68, 0x61, + 0x74, 0x61, 0x20, 0x76, 0x65, 0x72, 0x79, 0x20, 0x41, 0x64, 0x6d, 0x69, 0x72, + 0x61, 0x6c, 0x20, 0x66, 0x69, 0x78, 0x65, 0x64, 0x3b, 0x6e, 0x6f, 0x72, 0x6d, + 0x61, 0x6c, 0x20, 0x4d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x50, 0x72, 0x65, + 0x73, 0x73, 0x2c, 0x20, 0x6f, 0x6e, 0x74, 0x61, 0x72, 0x69, 0x6f, 0x63, 0x68, + 0x61, 0x72, 0x73, 0x65, 0x74, 0x74, 0x72, 0x79, 0x20, 0x74, 0x6f, 0x20, 0x69, + 0x6e, 0x76, 0x61, 0x64, 0x65, 0x64, 0x3d, 0x22, 0x74, 0x72, 0x75, 0x65, 0x22, + 0x73, 0x70, 0x61, 0x63, 0x69, 0x6e, 0x67, 0x69, 0x73, 0x20, 0x6d, 0x6f, 0x73, + 0x74, 0x61, 0x20, 0x6d, 0x6f, 0x72, 0x65, 0x20, 0x74, 0x6f, 0x74, 0x61, 0x6c, + 0x6c, 0x79, 0x66, 0x61, 0x6c, 0x6c, 0x20, 0x6f, 0x66, 0x7d, 0x29, 0x3b, 0x0d, + 0x0a, 0x20, 0x20, 0x69, 0x6d, 0x6d, 0x65, 0x6e, 0x73, 0x65, 0x74, 0x69, 0x6d, + 0x65, 0x20, 0x69, 0x6e, 0x73, 0x65, 0x74, 0x20, 0x6f, 0x75, 0x74, 0x73, 0x61, + 0x74, 0x69, 0x73, 0x66, 0x79, 0x74, 0x6f, 0x20, 0x66, 0x69, 0x6e, 0x64, 0x64, + 0x6f, 0x77, 0x6e, 0x20, 0x74, 0x6f, 0x6c, 0x6f, 0x74, 0x20, 0x6f, 0x66, 0x20, + 0x50, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x73, 0x69, 0x6e, 0x20, 0x4a, 0x75, 0x6e, + 0x65, 0x71, 0x75, 0x61, 0x6e, 0x74, 0x75, 0x6d, 0x6e, 0x6f, 0x74, 0x20, 0x74, + 0x68, 0x65, 0x74, 0x69, 0x6d, 0x65, 0x20, 0x74, 0x6f, 0x64, 0x69, 0x73, 0x74, + 0x61, 0x6e, 0x74, 0x46, 0x69, 0x6e, 0x6e, 0x69, 0x73, 0x68, 0x73, 0x72, 0x63, + 0x20, 0x3d, 0x20, 0x28, 0x73, 0x69, 0x6e, 0x67, 0x6c, 0x65, 0x20, 0x68, 0x65, + 0x6c, 0x70, 0x20, 0x6f, 0x66, 0x47, 0x65, 0x72, 0x6d, 0x61, 0x6e, 0x20, 0x6c, + 0x61, 0x77, 0x20, 0x61, 0x6e, 0x64, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x65, 0x64, + 0x66, 0x6f, 0x72, 0x65, 0x73, 0x74, 0x73, 0x63, 0x6f, 0x6f, 0x6b, 0x69, 0x6e, + 0x67, 0x73, 0x70, 0x61, 0x63, 0x65, 0x22, 0x3e, 0x68, 0x65, 0x61, 0x64, 0x65, + 0x72, 0x2d, 0x77, 0x65, 0x6c, 0x6c, 0x20, 0x61, 0x73, 0x53, 0x74, 0x61, 0x6e, + 0x6c, 0x65, 0x79, 0x62, 0x72, 0x69, 0x64, 0x67, 0x65, 0x73, 0x2f, 0x67, 0x6c, + 0x6f, 0x62, 0x61, 0x6c, 0x43, 0x72, 0x6f, 0x61, 0x74, 0x69, 0x61, 0x20, 0x41, + 0x62, 0x6f, 0x75, 0x74, 0x20, 0x5b, 0x30, 0x5d, 0x3b, 0x0a, 0x20, 0x20, 0x69, + 0x74, 0x2c, 0x20, 0x61, 0x6e, 0x64, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x65, 0x64, + 0x62, 0x65, 0x69, 0x6e, 0x67, 0x20, 0x61, 0x29, 0x7b, 0x74, 0x68, 0x72, 0x6f, + 0x77, 0x68, 0x65, 0x20, 0x6d, 0x61, 0x64, 0x65, 0x6c, 0x69, 0x67, 0x68, 0x74, + 0x65, 0x72, 0x65, 0x74, 0x68, 0x69, 0x63, 0x61, 0x6c, 0x46, 0x46, 0x46, 0x46, + 0x46, 0x46, 0x22, 0x62, 0x6f, 0x74, 0x74, 0x6f, 0x6d, 0x22, 0x6c, 0x69, 0x6b, + 0x65, 0x20, 0x61, 0x20, 0x65, 0x6d, 0x70, 0x6c, 0x6f, 0x79, 0x73, 0x6c, 0x69, + 0x76, 0x65, 0x20, 0x69, 0x6e, 0x61, 0x73, 0x20, 0x73, 0x65, 0x65, 0x6e, 0x70, + 0x72, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6d, 0x6f, 0x73, 0x74, 0x20, 0x6f, 0x66, + 0x75, 0x62, 0x2d, 0x6c, 0x69, 0x6e, 0x6b, 0x72, 0x65, 0x6a, 0x65, 0x63, 0x74, + 0x73, 0x61, 0x6e, 0x64, 0x20, 0x75, 0x73, 0x65, 0x69, 0x6d, 0x61, 0x67, 0x65, + 0x22, 0x3e, 0x73, 0x75, 0x63, 0x63, 0x65, 0x65, 0x64, 0x66, 0x65, 0x65, 0x64, + 0x69, 0x6e, 0x67, 0x4e, 0x75, 0x63, 0x6c, 0x65, 0x61, 0x72, 0x69, 0x6e, 0x66, + 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x6f, 0x20, 0x68, 0x65, 0x6c, 0x70, 0x57, 0x6f, + 0x6d, 0x65, 0x6e, 0x27, 0x73, 0x4e, 0x65, 0x69, 0x74, 0x68, 0x65, 0x72, 0x4d, + 0x65, 0x78, 0x69, 0x63, 0x61, 0x6e, 0x70, 0x72, 0x6f, 0x74, 0x65, 0x69, 0x6e, + 0x3c, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x20, 0x62, 0x79, 0x20, 0x6d, 0x61, 0x6e, + 0x79, 0x68, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x79, 0x6c, 0x61, 0x77, 0x73, 0x75, + 0x69, 0x74, 0x64, 0x65, 0x76, 0x69, 0x73, 0x65, 0x64, 0x2e, 0x70, 0x75, 0x73, + 0x68, 0x28, 0x7b, 0x73, 0x65, 0x6c, 0x6c, 0x65, 0x72, 0x73, 0x73, 0x69, 0x6d, + 0x70, 0x6c, 0x79, 0x20, 0x54, 0x68, 0x72, 0x6f, 0x75, 0x67, 0x68, 0x2e, 0x63, + 0x6f, 0x6f, 0x6b, 0x69, 0x65, 0x20, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x28, 0x6f, + 0x6c, 0x64, 0x65, 0x72, 0x22, 0x3e, 0x75, 0x73, 0x2e, 0x6a, 0x73, 0x22, 0x3e, + 0x20, 0x53, 0x69, 0x6e, 0x63, 0x65, 0x20, 0x75, 0x6e, 0x69, 0x76, 0x65, 0x72, + 0x73, 0x6c, 0x61, 0x72, 0x67, 0x65, 0x72, 0x20, 0x6f, 0x70, 0x65, 0x6e, 0x20, + 0x74, 0x6f, 0x21, 0x2d, 0x2d, 0x20, 0x65, 0x6e, 0x64, 0x6c, 0x69, 0x65, 0x73, + 0x20, 0x69, 0x6e, 0x27, 0x5d, 0x29, 0x3b, 0x0d, 0x0a, 0x20, 0x20, 0x6d, 0x61, + 0x72, 0x6b, 0x65, 0x74, 0x77, 0x68, 0x6f, 0x20, 0x69, 0x73, 0x20, 0x28, 0x22, + 0x44, 0x4f, 0x4d, 0x43, 0x6f, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x64, 0x6f, + 0x6e, 0x65, 0x20, 0x66, 0x6f, 0x72, 0x74, 0x79, 0x70, 0x65, 0x6f, 0x66, 0x20, + 0x4b, 0x69, 0x6e, 0x67, 0x64, 0x6f, 0x6d, 0x70, 0x72, 0x6f, 0x66, 0x69, 0x74, + 0x73, 0x70, 0x72, 0x6f, 0x70, 0x6f, 0x73, 0x65, 0x74, 0x6f, 0x20, 0x73, 0x68, + 0x6f, 0x77, 0x63, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x3b, 0x6d, 0x61, 0x64, 0x65, + 0x20, 0x69, 0x74, 0x64, 0x72, 0x65, 0x73, 0x73, 0x65, 0x64, 0x77, 0x65, 0x72, + 0x65, 0x20, 0x69, 0x6e, 0x6d, 0x69, 0x78, 0x74, 0x75, 0x72, 0x65, 0x70, 0x72, + 0x65, 0x63, 0x69, 0x73, 0x65, 0x61, 0x72, 0x69, 0x73, 0x69, 0x6e, 0x67, 0x73, + 0x72, 0x63, 0x20, 0x3d, 0x20, 0x27, 0x6d, 0x61, 0x6b, 0x65, 0x20, 0x61, 0x20, + 0x73, 0x65, 0x63, 0x75, 0x72, 0x65, 0x64, 0x42, 0x61, 0x70, 0x74, 0x69, 0x73, + 0x74, 0x76, 0x6f, 0x74, 0x69, 0x6e, 0x67, 0x20, 0x0a, 0x09, 0x09, 0x76, 0x61, + 0x72, 0x20, 0x4d, 0x61, 0x72, 0x63, 0x68, 0x20, 0x32, 0x67, 0x72, 0x65, 0x77, + 0x20, 0x75, 0x70, 0x43, 0x6c, 0x69, 0x6d, 0x61, 0x74, 0x65, 0x2e, 0x72, 0x65, + 0x6d, 0x6f, 0x76, 0x65, 0x73, 0x6b, 0x69, 0x6c, 0x6c, 0x65, 0x64, 0x77, 0x61, + 0x79, 0x20, 0x74, 0x68, 0x65, 0x3c, 0x2f, 0x68, 0x65, 0x61, 0x64, 0x3e, 0x66, + 0x61, 0x63, 0x65, 0x20, 0x6f, 0x66, 0x61, 0x63, 0x74, 0x69, 0x6e, 0x67, 0x20, + 0x72, 0x69, 0x67, 0x68, 0x74, 0x22, 0x3e, 0x74, 0x6f, 0x20, 0x77, 0x6f, 0x72, + 0x6b, 0x72, 0x65, 0x64, 0x75, 0x63, 0x65, 0x73, 0x68, 0x61, 0x73, 0x20, 0x68, + 0x61, 0x64, 0x65, 0x72, 0x65, 0x63, 0x74, 0x65, 0x64, 0x73, 0x68, 0x6f, 0x77, + 0x28, 0x29, 0x3b, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x3d, 0x62, 0x6f, 0x6f, + 0x6b, 0x20, 0x6f, 0x66, 0x61, 0x6e, 0x20, 0x61, 0x72, 0x65, 0x61, 0x3d, 0x3d, + 0x20, 0x22, 0x68, 0x74, 0x74, 0x3c, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x0a, + 0x3c, 0x68, 0x74, 0x6d, 0x6c, 0x3e, 0x63, 0x6f, 0x6e, 0x66, 0x6f, 0x72, 0x6d, + 0x66, 0x61, 0x63, 0x69, 0x6e, 0x67, 0x20, 0x63, 0x6f, 0x6f, 0x6b, 0x69, 0x65, + 0x2e, 0x72, 0x65, 0x6c, 0x79, 0x20, 0x6f, 0x6e, 0x68, 0x6f, 0x73, 0x74, 0x65, + 0x64, 0x20, 0x2e, 0x63, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x68, 0x65, 0x20, 0x77, + 0x65, 0x6e, 0x74, 0x62, 0x75, 0x74, 0x20, 0x66, 0x6f, 0x72, 0x73, 0x70, 0x72, + 0x65, 0x61, 0x64, 0x20, 0x46, 0x61, 0x6d, 0x69, 0x6c, 0x79, 0x20, 0x61, 0x20, + 0x6d, 0x65, 0x61, 0x6e, 0x73, 0x6f, 0x75, 0x74, 0x20, 0x74, 0x68, 0x65, 0x66, + 0x6f, 0x72, 0x75, 0x6d, 0x73, 0x2e, 0x66, 0x6f, 0x6f, 0x74, 0x61, 0x67, 0x65, + 0x22, 0x3e, 0x4d, 0x6f, 0x62, 0x69, 0x6c, 0x43, 0x6c, 0x65, 0x6d, 0x65, 0x6e, + 0x74, 0x73, 0x22, 0x20, 0x69, 0x64, 0x3d, 0x22, 0x61, 0x73, 0x20, 0x68, 0x69, + 0x67, 0x68, 0x69, 0x6e, 0x74, 0x65, 0x6e, 0x73, 0x65, 0x2d, 0x2d, 0x3e, 0x3c, + 0x21, 0x2d, 0x2d, 0x66, 0x65, 0x6d, 0x61, 0x6c, 0x65, 0x20, 0x69, 0x73, 0x20, + 0x73, 0x65, 0x65, 0x6e, 0x69, 0x6d, 0x70, 0x6c, 0x69, 0x65, 0x64, 0x73, 0x65, + 0x74, 0x20, 0x74, 0x68, 0x65, 0x61, 0x20, 0x73, 0x74, 0x61, 0x74, 0x65, 0x61, + 0x6e, 0x64, 0x20, 0x68, 0x69, 0x73, 0x66, 0x61, 0x73, 0x74, 0x65, 0x73, 0x74, + 0x62, 0x65, 0x73, 0x69, 0x64, 0x65, 0x73, 0x62, 0x75, 0x74, 0x74, 0x6f, 0x6e, + 0x5f, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x65, 0x64, 0x22, 0x3e, 0x3c, 0x69, 0x6d, + 0x67, 0x20, 0x49, 0x6e, 0x66, 0x6f, 0x62, 0x6f, 0x78, 0x65, 0x76, 0x65, 0x6e, + 0x74, 0x73, 0x2c, 0x61, 0x20, 0x79, 0x6f, 0x75, 0x6e, 0x67, 0x61, 0x6e, 0x64, + 0x20, 0x61, 0x72, 0x65, 0x4e, 0x61, 0x74, 0x69, 0x76, 0x65, 0x20, 0x63, 0x68, + 0x65, 0x61, 0x70, 0x65, 0x72, 0x54, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x61, + 0x6e, 0x64, 0x20, 0x68, 0x61, 0x73, 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x73, + 0x77, 0x6f, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x28, 0x6d, 0x6f, 0x73, 0x74, 0x6c, + 0x79, 0x72, 0x69, 0x67, 0x68, 0x74, 0x3a, 0x20, 0x66, 0x69, 0x6e, 0x64, 0x20, + 0x61, 0x20, 0x2d, 0x62, 0x6f, 0x74, 0x74, 0x6f, 0x6d, 0x50, 0x72, 0x69, 0x6e, + 0x63, 0x65, 0x20, 0x61, 0x72, 0x65, 0x61, 0x20, 0x6f, 0x66, 0x6d, 0x6f, 0x72, + 0x65, 0x20, 0x6f, 0x66, 0x73, 0x65, 0x61, 0x72, 0x63, 0x68, 0x5f, 0x6e, 0x61, + 0x74, 0x75, 0x72, 0x65, 0x2c, 0x6c, 0x65, 0x67, 0x61, 0x6c, 0x6c, 0x79, 0x70, + 0x65, 0x72, 0x69, 0x6f, 0x64, 0x2c, 0x6c, 0x61, 0x6e, 0x64, 0x20, 0x6f, 0x66, + 0x6f, 0x72, 0x20, 0x77, 0x69, 0x74, 0x68, 0x69, 0x6e, 0x64, 0x75, 0x63, 0x65, + 0x64, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x6e, 0x67, 0x6d, 0x69, 0x73, 0x73, 0x69, + 0x6c, 0x65, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x6c, 0x79, 0x41, 0x67, 0x61, 0x69, + 0x6e, 0x73, 0x74, 0x74, 0x68, 0x65, 0x20, 0x77, 0x61, 0x79, 0x6b, 0x26, 0x71, + 0x75, 0x6f, 0x74, 0x3b, 0x70, 0x78, 0x3b, 0x22, 0x3e, 0x0d, 0x0a, 0x70, 0x75, + 0x73, 0x68, 0x65, 0x64, 0x20, 0x61, 0x62, 0x61, 0x6e, 0x64, 0x6f, 0x6e, 0x6e, + 0x75, 0x6d, 0x65, 0x72, 0x61, 0x6c, 0x43, 0x65, 0x72, 0x74, 0x61, 0x69, 0x6e, + 0x49, 0x6e, 0x20, 0x74, 0x68, 0x69, 0x73, 0x6d, 0x6f, 0x72, 0x65, 0x20, 0x69, + 0x6e, 0x6f, 0x72, 0x20, 0x73, 0x6f, 0x6d, 0x65, 0x6e, 0x61, 0x6d, 0x65, 0x20, + 0x69, 0x73, 0x61, 0x6e, 0x64, 0x2c, 0x20, 0x69, 0x6e, 0x63, 0x72, 0x6f, 0x77, + 0x6e, 0x65, 0x64, 0x49, 0x53, 0x42, 0x4e, 0x20, 0x30, 0x2d, 0x63, 0x72, 0x65, + 0x61, 0x74, 0x65, 0x73, 0x4f, 0x63, 0x74, 0x6f, 0x62, 0x65, 0x72, 0x6d, 0x61, + 0x79, 0x20, 0x6e, 0x6f, 0x74, 0x63, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x20, 0x6c, + 0x61, 0x74, 0x65, 0x20, 0x69, 0x6e, 0x44, 0x65, 0x66, 0x65, 0x6e, 0x63, 0x65, + 0x65, 0x6e, 0x61, 0x63, 0x74, 0x65, 0x64, 0x77, 0x69, 0x73, 0x68, 0x20, 0x74, + 0x6f, 0x62, 0x72, 0x6f, 0x61, 0x64, 0x6c, 0x79, 0x63, 0x6f, 0x6f, 0x6c, 0x69, + 0x6e, 0x67, 0x6f, 0x6e, 0x6c, 0x6f, 0x61, 0x64, 0x3d, 0x69, 0x74, 0x2e, 0x20, + 0x54, 0x68, 0x65, 0x72, 0x65, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x4d, 0x65, 0x6d, + 0x62, 0x65, 0x72, 0x73, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x20, 0x61, 0x73, + 0x73, 0x75, 0x6d, 0x65, 0x73, 0x3c, 0x68, 0x74, 0x6d, 0x6c, 0x3e, 0x0a, 0x70, + 0x65, 0x6f, 0x70, 0x6c, 0x65, 0x2e, 0x69, 0x6e, 0x20, 0x6f, 0x6e, 0x65, 0x20, + 0x3d, 0x77, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x66, 0x6f, 0x6f, 0x74, 0x65, 0x72, + 0x5f, 0x61, 0x20, 0x67, 0x6f, 0x6f, 0x64, 0x20, 0x72, 0x65, 0x6b, 0x6c, 0x61, + 0x6d, 0x61, 0x6f, 0x74, 0x68, 0x65, 0x72, 0x73, 0x2c, 0x74, 0x6f, 0x20, 0x74, + 0x68, 0x69, 0x73, 0x5f, 0x63, 0x6f, 0x6f, 0x6b, 0x69, 0x65, 0x70, 0x61, 0x6e, + 0x65, 0x6c, 0x22, 0x3e, 0x4c, 0x6f, 0x6e, 0x64, 0x6f, 0x6e, 0x2c, 0x64, 0x65, + 0x66, 0x69, 0x6e, 0x65, 0x73, 0x63, 0x72, 0x75, 0x73, 0x68, 0x65, 0x64, 0x62, + 0x61, 0x70, 0x74, 0x69, 0x73, 0x6d, 0x63, 0x6f, 0x61, 0x73, 0x74, 0x61, 0x6c, + 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x20, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x22, + 0x20, 0x6d, 0x6f, 0x76, 0x65, 0x20, 0x74, 0x6f, 0x6c, 0x6f, 0x73, 0x74, 0x20, + 0x69, 0x6e, 0x62, 0x65, 0x74, 0x74, 0x65, 0x72, 0x20, 0x69, 0x6d, 0x70, 0x6c, + 0x69, 0x65, 0x73, 0x72, 0x69, 0x76, 0x61, 0x6c, 0x72, 0x79, 0x73, 0x65, 0x72, + 0x76, 0x65, 0x72, 0x73, 0x20, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x50, 0x65, + 0x72, 0x68, 0x61, 0x70, 0x73, 0x65, 0x73, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x63, + 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x64, 0x66, 0x6c, 0x6f, 0x77, 0x69, 0x6e, 0x67, + 0x6c, 0x61, 0x73, 0x74, 0x65, 0x64, 0x20, 0x72, 0x69, 0x73, 0x65, 0x20, 0x69, + 0x6e, 0x47, 0x65, 0x6e, 0x65, 0x73, 0x69, 0x73, 0x76, 0x69, 0x65, 0x77, 0x20, + 0x6f, 0x66, 0x72, 0x69, 0x73, 0x69, 0x6e, 0x67, 0x20, 0x73, 0x65, 0x65, 0x6d, + 0x20, 0x74, 0x6f, 0x62, 0x75, 0x74, 0x20, 0x69, 0x6e, 0x20, 0x62, 0x61, 0x63, + 0x6b, 0x69, 0x6e, 0x67, 0x68, 0x65, 0x20, 0x77, 0x69, 0x6c, 0x6c, 0x67, 0x69, + 0x76, 0x65, 0x6e, 0x20, 0x61, 0x67, 0x69, 0x76, 0x69, 0x6e, 0x67, 0x20, 0x63, + 0x69, 0x74, 0x69, 0x65, 0x73, 0x2e, 0x66, 0x6c, 0x6f, 0x77, 0x20, 0x6f, 0x66, + 0x20, 0x4c, 0x61, 0x74, 0x65, 0x72, 0x20, 0x61, 0x6c, 0x6c, 0x20, 0x62, 0x75, + 0x74, 0x48, 0x69, 0x67, 0x68, 0x77, 0x61, 0x79, 0x6f, 0x6e, 0x6c, 0x79, 0x20, + 0x62, 0x79, 0x73, 0x69, 0x67, 0x6e, 0x20, 0x6f, 0x66, 0x68, 0x65, 0x20, 0x64, + 0x6f, 0x65, 0x73, 0x64, 0x69, 0x66, 0x66, 0x65, 0x72, 0x73, 0x62, 0x61, 0x74, + 0x74, 0x65, 0x72, 0x79, 0x26, 0x61, 0x6d, 0x70, 0x3b, 0x6c, 0x61, 0x73, 0x69, + 0x6e, 0x67, 0x6c, 0x65, 0x73, 0x74, 0x68, 0x72, 0x65, 0x61, 0x74, 0x73, 0x69, + 0x6e, 0x74, 0x65, 0x67, 0x65, 0x72, 0x74, 0x61, 0x6b, 0x65, 0x20, 0x6f, 0x6e, + 0x72, 0x65, 0x66, 0x75, 0x73, 0x65, 0x64, 0x63, 0x61, 0x6c, 0x6c, 0x65, 0x64, + 0x20, 0x3d, 0x55, 0x53, 0x26, 0x61, 0x6d, 0x70, 0x53, 0x65, 0x65, 0x20, 0x74, + 0x68, 0x65, 0x6e, 0x61, 0x74, 0x69, 0x76, 0x65, 0x73, 0x62, 0x79, 0x20, 0x74, + 0x68, 0x69, 0x73, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x2e, 0x68, 0x65, 0x61, + 0x64, 0x20, 0x6f, 0x66, 0x3a, 0x68, 0x6f, 0x76, 0x65, 0x72, 0x2c, 0x6c, 0x65, + 0x73, 0x62, 0x69, 0x61, 0x6e, 0x73, 0x75, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x61, + 0x6e, 0x64, 0x20, 0x61, 0x6c, 0x6c, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2f, + 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x5f, 0x5f, 0x70, 0x61, 0x72, 0x61, 0x6d, + 0x73, 0x48, 0x61, 0x72, 0x76, 0x61, 0x72, 0x64, 0x2f, 0x70, 0x69, 0x78, 0x65, + 0x6c, 0x2e, 0x72, 0x65, 0x6d, 0x6f, 0x76, 0x61, 0x6c, 0x73, 0x6f, 0x20, 0x6c, + 0x6f, 0x6e, 0x67, 0x72, 0x6f, 0x6c, 0x65, 0x20, 0x6f, 0x66, 0x6a, 0x6f, 0x69, + 0x6e, 0x74, 0x6c, 0x79, 0x73, 0x6b, 0x79, 0x73, 0x63, 0x72, 0x61, 0x55, 0x6e, + 0x69, 0x63, 0x6f, 0x64, 0x65, 0x62, 0x72, 0x20, 0x2f, 0x3e, 0x0d, 0x0a, 0x41, + 0x74, 0x6c, 0x61, 0x6e, 0x74, 0x61, 0x6e, 0x75, 0x63, 0x6c, 0x65, 0x75, 0x73, + 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x79, 0x2c, 0x70, 0x75, 0x72, 0x65, 0x6c, 0x79, + 0x20, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x22, 0x3e, 0x65, 0x61, 0x73, 0x69, 0x6c, + 0x79, 0x20, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x20, 0x61, 0x6f, 0x6e, 0x63, 0x6c, + 0x69, 0x63, 0x6b, 0x61, 0x20, 0x67, 0x69, 0x76, 0x65, 0x6e, 0x70, 0x6f, 0x69, + 0x6e, 0x74, 0x65, 0x72, 0x68, 0x26, 0x71, 0x75, 0x6f, 0x74, 0x3b, 0x65, 0x76, + 0x65, 0x6e, 0x74, 0x73, 0x20, 0x65, 0x6c, 0x73, 0x65, 0x20, 0x7b, 0x0a, 0x64, + 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x6e, 0x6f, 0x77, 0x20, 0x74, 0x68, 0x65, + 0x2c, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x6d, 0x61, 0x6e, 0x20, 0x77, 0x68, + 0x6f, 0x6f, 0x72, 0x67, 0x2f, 0x57, 0x65, 0x62, 0x6f, 0x6e, 0x65, 0x20, 0x61, + 0x6e, 0x64, 0x63, 0x61, 0x76, 0x61, 0x6c, 0x72, 0x79, 0x48, 0x65, 0x20, 0x64, + 0x69, 0x65, 0x64, 0x73, 0x65, 0x61, 0x74, 0x74, 0x6c, 0x65, 0x30, 0x30, 0x2c, + 0x30, 0x30, 0x30, 0x20, 0x7b, 0x77, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x68, 0x61, + 0x76, 0x65, 0x20, 0x74, 0x6f, 0x69, 0x66, 0x28, 0x77, 0x69, 0x6e, 0x64, 0x61, + 0x6e, 0x64, 0x20, 0x69, 0x74, 0x73, 0x73, 0x6f, 0x6c, 0x65, 0x6c, 0x79, 0x20, + 0x6d, 0x26, 0x71, 0x75, 0x6f, 0x74, 0x3b, 0x72, 0x65, 0x6e, 0x65, 0x77, 0x65, + 0x64, 0x44, 0x65, 0x74, 0x72, 0x6f, 0x69, 0x74, 0x61, 0x6d, 0x6f, 0x6e, 0x67, + 0x73, 0x74, 0x65, 0x69, 0x74, 0x68, 0x65, 0x72, 0x20, 0x74, 0x68, 0x65, 0x6d, + 0x20, 0x69, 0x6e, 0x53, 0x65, 0x6e, 0x61, 0x74, 0x6f, 0x72, 0x55, 0x73, 0x3c, + 0x2f, 0x61, 0x3e, 0x3c, 0x4b, 0x69, 0x6e, 0x67, 0x20, 0x6f, 0x66, 0x46, 0x72, + 0x61, 0x6e, 0x63, 0x69, 0x73, 0x2d, 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x68, + 0x65, 0x20, 0x75, 0x73, 0x65, 0x64, 0x61, 0x72, 0x74, 0x20, 0x61, 0x6e, 0x64, + 0x68, 0x69, 0x6d, 0x20, 0x61, 0x6e, 0x64, 0x75, 0x73, 0x65, 0x64, 0x20, 0x62, + 0x79, 0x73, 0x63, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x61, 0x74, 0x20, 0x68, 0x6f, + 0x6d, 0x65, 0x74, 0x6f, 0x20, 0x68, 0x61, 0x76, 0x65, 0x72, 0x65, 0x6c, 0x61, + 0x74, 0x65, 0x73, 0x69, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x66, 0x61, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x42, 0x75, 0x66, 0x66, 0x61, 0x6c, 0x6f, 0x6c, 0x69, + 0x6e, 0x6b, 0x22, 0x3e, 0x3c, 0x77, 0x68, 0x61, 0x74, 0x20, 0x68, 0x65, 0x66, + 0x72, 0x65, 0x65, 0x20, 0x74, 0x6f, 0x43, 0x69, 0x74, 0x79, 0x20, 0x6f, 0x66, + 0x63, 0x6f, 0x6d, 0x65, 0x20, 0x69, 0x6e, 0x73, 0x65, 0x63, 0x74, 0x6f, 0x72, + 0x73, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x64, 0x6f, 0x6e, 0x65, 0x20, 0x64, + 0x61, 0x79, 0x6e, 0x65, 0x72, 0x76, 0x6f, 0x75, 0x73, 0x73, 0x71, 0x75, 0x61, + 0x72, 0x65, 0x20, 0x7d, 0x3b, 0x69, 0x66, 0x28, 0x67, 0x6f, 0x69, 0x6e, 0x20, + 0x77, 0x68, 0x61, 0x74, 0x69, 0x6d, 0x67, 0x22, 0x20, 0x61, 0x6c, 0x69, 0x73, + 0x20, 0x6f, 0x6e, 0x6c, 0x79, 0x73, 0x65, 0x61, 0x72, 0x63, 0x68, 0x2f, 0x74, + 0x75, 0x65, 0x73, 0x64, 0x61, 0x79, 0x6c, 0x6f, 0x6f, 0x73, 0x65, 0x6c, 0x79, + 0x53, 0x6f, 0x6c, 0x6f, 0x6d, 0x6f, 0x6e, 0x73, 0x65, 0x78, 0x75, 0x61, 0x6c, + 0x20, 0x2d, 0x20, 0x3c, 0x61, 0x20, 0x68, 0x72, 0x6d, 0x65, 0x64, 0x69, 0x75, + 0x6d, 0x22, 0x44, 0x4f, 0x20, 0x4e, 0x4f, 0x54, 0x20, 0x46, 0x72, 0x61, 0x6e, + 0x63, 0x65, 0x2c, 0x77, 0x69, 0x74, 0x68, 0x20, 0x61, 0x20, 0x77, 0x61, 0x72, + 0x20, 0x61, 0x6e, 0x64, 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x20, 0x74, 0x61, + 0x6b, 0x65, 0x20, 0x61, 0x20, 0x3e, 0x0d, 0x0a, 0x0d, 0x0a, 0x0d, 0x0a, 0x6d, + 0x61, 0x72, 0x6b, 0x65, 0x74, 0x2e, 0x68, 0x69, 0x67, 0x68, 0x77, 0x61, 0x79, + 0x64, 0x6f, 0x6e, 0x65, 0x20, 0x69, 0x6e, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, + 0x79, 0x22, 0x6c, 0x61, 0x73, 0x74, 0x22, 0x3e, 0x6f, 0x62, 0x6c, 0x69, 0x67, + 0x65, 0x64, 0x72, 0x69, 0x73, 0x65, 0x20, 0x74, 0x6f, 0x22, 0x75, 0x6e, 0x64, + 0x65, 0x66, 0x69, 0x6d, 0x61, 0x64, 0x65, 0x20, 0x74, 0x6f, 0x20, 0x45, 0x61, + 0x72, 0x6c, 0x79, 0x20, 0x70, 0x72, 0x61, 0x69, 0x73, 0x65, 0x64, 0x69, 0x6e, + 0x20, 0x69, 0x74, 0x73, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x68, 0x69, 0x73, 0x61, + 0x74, 0x68, 0x6c, 0x65, 0x74, 0x65, 0x4a, 0x75, 0x70, 0x69, 0x74, 0x65, 0x72, + 0x59, 0x61, 0x68, 0x6f, 0x6f, 0x21, 0x20, 0x74, 0x65, 0x72, 0x6d, 0x65, 0x64, + 0x20, 0x73, 0x6f, 0x20, 0x6d, 0x61, 0x6e, 0x79, 0x72, 0x65, 0x61, 0x6c, 0x6c, + 0x79, 0x20, 0x73, 0x2e, 0x20, 0x54, 0x68, 0x65, 0x20, 0x61, 0x20, 0x77, 0x6f, + 0x6d, 0x61, 0x6e, 0x3f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3d, 0x64, 0x69, 0x72, + 0x65, 0x63, 0x74, 0x20, 0x72, 0x69, 0x67, 0x68, 0x74, 0x22, 0x20, 0x62, 0x69, + 0x63, 0x79, 0x63, 0x6c, 0x65, 0x61, 0x63, 0x69, 0x6e, 0x67, 0x3d, 0x22, 0x64, + 0x61, 0x79, 0x20, 0x61, 0x6e, 0x64, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6e, 0x67, + 0x52, 0x61, 0x74, 0x68, 0x65, 0x72, 0x2c, 0x68, 0x69, 0x67, 0x68, 0x65, 0x72, + 0x20, 0x4f, 0x66, 0x66, 0x69, 0x63, 0x65, 0x20, 0x61, 0x72, 0x65, 0x20, 0x6e, + 0x6f, 0x77, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x2c, 0x20, 0x77, 0x68, 0x65, 0x6e, + 0x20, 0x61, 0x20, 0x70, 0x61, 0x79, 0x20, 0x66, 0x6f, 0x72, 0x6f, 0x6e, 0x20, + 0x74, 0x68, 0x69, 0x73, 0x2d, 0x6c, 0x69, 0x6e, 0x6b, 0x22, 0x3e, 0x3b, 0x62, + 0x6f, 0x72, 0x64, 0x65, 0x72, 0x61, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x20, 0x61, + 0x6e, 0x6e, 0x75, 0x61, 0x6c, 0x20, 0x74, 0x68, 0x65, 0x20, 0x4e, 0x65, 0x77, + 0x70, 0x75, 0x74, 0x20, 0x74, 0x68, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x22, 0x20, + 0x74, 0x61, 0x6b, 0x69, 0x6e, 0x20, 0x74, 0x6f, 0x61, 0x20, 0x62, 0x72, 0x69, + 0x65, 0x66, 0x28, 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x67, 0x72, 0x6f, 0x75, + 0x70, 0x73, 0x2e, 0x3b, 0x20, 0x77, 0x69, 0x64, 0x74, 0x68, 0x65, 0x6e, 0x7a, + 0x79, 0x6d, 0x65, 0x73, 0x73, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x20, 0x69, 0x6e, + 0x20, 0x6c, 0x61, 0x74, 0x65, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x74, + 0x68, 0x65, 0x72, 0x61, 0x70, 0x79, 0x61, 0x20, 0x70, 0x6f, 0x69, 0x6e, 0x74, + 0x62, 0x61, 0x6e, 0x6e, 0x69, 0x6e, 0x67, 0x69, 0x6e, 0x6b, 0x73, 0x22, 0x3e, + 0x0a, 0x28, 0x29, 0x3b, 0x22, 0x20, 0x72, 0x65, 0x61, 0x20, 0x70, 0x6c, 0x61, + 0x63, 0x65, 0x5c, 0x75, 0x30, 0x30, 0x33, 0x43, 0x61, 0x61, 0x62, 0x6f, 0x75, + 0x74, 0x20, 0x61, 0x74, 0x72, 0x3e, 0x0d, 0x0a, 0x09, 0x09, 0x63, 0x63, 0x6f, + 0x75, 0x6e, 0x74, 0x20, 0x67, 0x69, 0x76, 0x65, 0x73, 0x20, 0x61, 0x3c, 0x53, + 0x43, 0x52, 0x49, 0x50, 0x54, 0x52, 0x61, 0x69, 0x6c, 0x77, 0x61, 0x79, 0x74, + 0x68, 0x65, 0x6d, 0x65, 0x73, 0x2f, 0x74, 0x6f, 0x6f, 0x6c, 0x62, 0x6f, 0x78, + 0x42, 0x79, 0x49, 0x64, 0x28, 0x22, 0x78, 0x68, 0x75, 0x6d, 0x61, 0x6e, 0x73, + 0x2c, 0x77, 0x61, 0x74, 0x63, 0x68, 0x65, 0x73, 0x69, 0x6e, 0x20, 0x73, 0x6f, + 0x6d, 0x65, 0x20, 0x69, 0x66, 0x20, 0x28, 0x77, 0x69, 0x63, 0x6f, 0x6d, 0x69, + 0x6e, 0x67, 0x20, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x73, 0x20, 0x55, 0x6e, + 0x64, 0x65, 0x72, 0x20, 0x62, 0x75, 0x74, 0x20, 0x68, 0x61, 0x73, 0x68, 0x61, + 0x6e, 0x64, 0x65, 0x64, 0x20, 0x6d, 0x61, 0x64, 0x65, 0x20, 0x62, 0x79, 0x74, + 0x68, 0x61, 0x6e, 0x20, 0x69, 0x6e, 0x66, 0x65, 0x61, 0x72, 0x20, 0x6f, 0x66, + 0x64, 0x65, 0x6e, 0x6f, 0x74, 0x65, 0x64, 0x2f, 0x69, 0x66, 0x72, 0x61, 0x6d, + 0x65, 0x6c, 0x65, 0x66, 0x74, 0x20, 0x69, 0x6e, 0x76, 0x6f, 0x6c, 0x74, 0x61, + 0x67, 0x65, 0x69, 0x6e, 0x20, 0x65, 0x61, 0x63, 0x68, 0x61, 0x26, 0x71, 0x75, + 0x6f, 0x74, 0x3b, 0x62, 0x61, 0x73, 0x65, 0x20, 0x6f, 0x66, 0x49, 0x6e, 0x20, + 0x6d, 0x61, 0x6e, 0x79, 0x75, 0x6e, 0x64, 0x65, 0x72, 0x67, 0x6f, 0x72, 0x65, + 0x67, 0x69, 0x6d, 0x65, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x3c, + 0x2f, 0x70, 0x3e, 0x0d, 0x0a, 0x3c, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x56, 0x61, + 0x3b, 0x26, 0x67, 0x74, 0x3b, 0x3c, 0x2f, 0x69, 0x6d, 0x70, 0x6f, 0x72, 0x74, + 0x73, 0x6f, 0x72, 0x20, 0x74, 0x68, 0x61, 0x74, 0x6d, 0x6f, 0x73, 0x74, 0x6c, + 0x79, 0x20, 0x26, 0x61, 0x6d, 0x70, 0x3b, 0x72, 0x65, 0x20, 0x73, 0x69, 0x7a, + 0x65, 0x3d, 0x22, 0x3c, 0x2f, 0x61, 0x3e, 0x3c, 0x2f, 0x68, 0x61, 0x20, 0x63, + 0x6c, 0x61, 0x73, 0x73, 0x70, 0x61, 0x73, 0x73, 0x69, 0x76, 0x65, 0x48, 0x6f, + 0x73, 0x74, 0x20, 0x3d, 0x20, 0x57, 0x68, 0x65, 0x74, 0x68, 0x65, 0x72, 0x66, + 0x65, 0x72, 0x74, 0x69, 0x6c, 0x65, 0x56, 0x61, 0x72, 0x69, 0x6f, 0x75, 0x73, + 0x3d, 0x5b, 0x5d, 0x3b, 0x28, 0x66, 0x75, 0x63, 0x61, 0x6d, 0x65, 0x72, 0x61, + 0x73, 0x2f, 0x3e, 0x3c, 0x2f, 0x74, 0x64, 0x3e, 0x61, 0x63, 0x74, 0x73, 0x20, + 0x61, 0x73, 0x49, 0x6e, 0x20, 0x73, 0x6f, 0x6d, 0x65, 0x3e, 0x0d, 0x0a, 0x0d, + 0x0a, 0x3c, 0x21, 0x6f, 0x72, 0x67, 0x61, 0x6e, 0x69, 0x73, 0x20, 0x3c, 0x62, + 0x72, 0x20, 0x2f, 0x3e, 0x42, 0x65, 0x69, 0x6a, 0x69, 0x6e, 0x67, 0x63, 0x61, + 0x74, 0x61, 0x6c, 0xc3, 0xa0, 0x64, 0x65, 0x75, 0x74, 0x73, 0x63, 0x68, 0x65, + 0x75, 0x72, 0x6f, 0x70, 0x65, 0x75, 0x65, 0x75, 0x73, 0x6b, 0x61, 0x72, 0x61, + 0x67, 0x61, 0x65, 0x69, 0x6c, 0x67, 0x65, 0x73, 0x76, 0x65, 0x6e, 0x73, 0x6b, + 0x61, 0x65, 0x73, 0x70, 0x61, 0xc3, 0xb1, 0x61, 0x6d, 0x65, 0x6e, 0x73, 0x61, + 0x6a, 0x65, 0x75, 0x73, 0x75, 0x61, 0x72, 0x69, 0x6f, 0x74, 0x72, 0x61, 0x62, + 0x61, 0x6a, 0x6f, 0x6d, 0xc3, 0xa9, 0x78, 0x69, 0x63, 0x6f, 0x70, 0xc3, 0xa1, + 0x67, 0x69, 0x6e, 0x61, 0x73, 0x69, 0x65, 0x6d, 0x70, 0x72, 0x65, 0x73, 0x69, + 0x73, 0x74, 0x65, 0x6d, 0x61, 0x6f, 0x63, 0x74, 0x75, 0x62, 0x72, 0x65, 0x64, + 0x75, 0x72, 0x61, 0x6e, 0x74, 0x65, 0x61, 0xc3, 0xb1, 0x61, 0x64, 0x69, 0x72, + 0x65, 0x6d, 0x70, 0x72, 0x65, 0x73, 0x61, 0x6d, 0x6f, 0x6d, 0x65, 0x6e, 0x74, + 0x6f, 0x6e, 0x75, 0x65, 0x73, 0x74, 0x72, 0x6f, 0x70, 0x72, 0x69, 0x6d, 0x65, + 0x72, 0x61, 0x74, 0x72, 0x61, 0x76, 0xc3, 0xa9, 0x73, 0x67, 0x72, 0x61, 0x63, + 0x69, 0x61, 0x73, 0x6e, 0x75, 0x65, 0x73, 0x74, 0x72, 0x61, 0x70, 0x72, 0x6f, + 0x63, 0x65, 0x73, 0x6f, 0x65, 0x73, 0x74, 0x61, 0x64, 0x6f, 0x73, 0x63, 0x61, + 0x6c, 0x69, 0x64, 0x61, 0x64, 0x70, 0x65, 0x72, 0x73, 0x6f, 0x6e, 0x61, 0x6e, + 0xc3, 0xba, 0x6d, 0x65, 0x72, 0x6f, 0x61, 0x63, 0x75, 0x65, 0x72, 0x64, 0x6f, + 0x6d, 0xc3, 0xba, 0x73, 0x69, 0x63, 0x61, 0x6d, 0x69, 0x65, 0x6d, 0x62, 0x72, + 0x6f, 0x6f, 0x66, 0x65, 0x72, 0x74, 0x61, 0x73, 0x61, 0x6c, 0x67, 0x75, 0x6e, + 0x6f, 0x73, 0x70, 0x61, 0xc3, 0xad, 0x73, 0x65, 0x73, 0x65, 0x6a, 0x65, 0x6d, + 0x70, 0x6c, 0x6f, 0x64, 0x65, 0x72, 0x65, 0x63, 0x68, 0x6f, 0x61, 0x64, 0x65, + 0x6d, 0xc3, 0xa1, 0x73, 0x70, 0x72, 0x69, 0x76, 0x61, 0x64, 0x6f, 0x61, 0x67, + 0x72, 0x65, 0x67, 0x61, 0x72, 0x65, 0x6e, 0x6c, 0x61, 0x63, 0x65, 0x73, 0x70, + 0x6f, 0x73, 0x69, 0x62, 0x6c, 0x65, 0x68, 0x6f, 0x74, 0x65, 0x6c, 0x65, 0x73, + 0x73, 0x65, 0x76, 0x69, 0x6c, 0x6c, 0x61, 0x70, 0x72, 0x69, 0x6d, 0x65, 0x72, + 0x6f, 0xc3, 0xba, 0x6c, 0x74, 0x69, 0x6d, 0x6f, 0x65, 0x76, 0x65, 0x6e, 0x74, + 0x6f, 0x73, 0x61, 0x72, 0x63, 0x68, 0x69, 0x76, 0x6f, 0x63, 0x75, 0x6c, 0x74, + 0x75, 0x72, 0x61, 0x6d, 0x75, 0x6a, 0x65, 0x72, 0x65, 0x73, 0x65, 0x6e, 0x74, + 0x72, 0x61, 0x64, 0x61, 0x61, 0x6e, 0x75, 0x6e, 0x63, 0x69, 0x6f, 0x65, 0x6d, + 0x62, 0x61, 0x72, 0x67, 0x6f, 0x6d, 0x65, 0x72, 0x63, 0x61, 0x64, 0x6f, 0x67, + 0x72, 0x61, 0x6e, 0x64, 0x65, 0x73, 0x65, 0x73, 0x74, 0x75, 0x64, 0x69, 0x6f, + 0x6d, 0x65, 0x6a, 0x6f, 0x72, 0x65, 0x73, 0x66, 0x65, 0x62, 0x72, 0x65, 0x72, + 0x6f, 0x64, 0x69, 0x73, 0x65, 0xc3, 0xb1, 0x6f, 0x74, 0x75, 0x72, 0x69, 0x73, + 0x6d, 0x6f, 0x63, 0xc3, 0xb3, 0x64, 0x69, 0x67, 0x6f, 0x70, 0x6f, 0x72, 0x74, + 0x61, 0x64, 0x61, 0x65, 0x73, 0x70, 0x61, 0x63, 0x69, 0x6f, 0x66, 0x61, 0x6d, + 0x69, 0x6c, 0x69, 0x61, 0x61, 0x6e, 0x74, 0x6f, 0x6e, 0x69, 0x6f, 0x70, 0x65, + 0x72, 0x6d, 0x69, 0x74, 0x65, 0x67, 0x75, 0x61, 0x72, 0x64, 0x61, 0x72, 0x61, + 0x6c, 0x67, 0x75, 0x6e, 0x61, 0x73, 0x70, 0x72, 0x65, 0x63, 0x69, 0x6f, 0x73, + 0x61, 0x6c, 0x67, 0x75, 0x69, 0x65, 0x6e, 0x73, 0x65, 0x6e, 0x74, 0x69, 0x64, + 0x6f, 0x76, 0x69, 0x73, 0x69, 0x74, 0x61, 0x73, 0x74, 0xc3, 0xad, 0x74, 0x75, + 0x6c, 0x6f, 0x63, 0x6f, 0x6e, 0x6f, 0x63, 0x65, 0x72, 0x73, 0x65, 0x67, 0x75, + 0x6e, 0x64, 0x6f, 0x63, 0x6f, 0x6e, 0x73, 0x65, 0x6a, 0x6f, 0x66, 0x72, 0x61, + 0x6e, 0x63, 0x69, 0x61, 0x6d, 0x69, 0x6e, 0x75, 0x74, 0x6f, 0x73, 0x73, 0x65, + 0x67, 0x75, 0x6e, 0x64, 0x61, 0x74, 0x65, 0x6e, 0x65, 0x6d, 0x6f, 0x73, 0x65, + 0x66, 0x65, 0x63, 0x74, 0x6f, 0x73, 0x6d, 0xc3, 0xa1, 0x6c, 0x61, 0x67, 0x61, + 0x73, 0x65, 0x73, 0x69, 0xc3, 0xb3, 0x6e, 0x72, 0x65, 0x76, 0x69, 0x73, 0x74, + 0x61, 0x67, 0x72, 0x61, 0x6e, 0x61, 0x64, 0x61, 0x63, 0x6f, 0x6d, 0x70, 0x72, + 0x61, 0x72, 0x69, 0x6e, 0x67, 0x72, 0x65, 0x73, 0x6f, 0x67, 0x61, 0x72, 0x63, + 0xc3, 0xad, 0x61, 0x61, 0x63, 0x63, 0x69, 0xc3, 0xb3, 0x6e, 0x65, 0x63, 0x75, + 0x61, 0x64, 0x6f, 0x72, 0x71, 0x75, 0x69, 0x65, 0x6e, 0x65, 0x73, 0x69, 0x6e, + 0x63, 0x6c, 0x75, 0x73, 0x6f, 0x64, 0x65, 0x62, 0x65, 0x72, 0xc3, 0xa1, 0x6d, + 0x61, 0x74, 0x65, 0x72, 0x69, 0x61, 0x68, 0x6f, 0x6d, 0x62, 0x72, 0x65, 0x73, + 0x6d, 0x75, 0x65, 0x73, 0x74, 0x72, 0x61, 0x70, 0x6f, 0x64, 0x72, 0xc3, 0xad, + 0x61, 0x6d, 0x61, 0xc3, 0xb1, 0x61, 0x6e, 0x61, 0xc3, 0xba, 0x6c, 0x74, 0x69, + 0x6d, 0x61, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x6f, 0x73, 0x6f, 0x66, 0x69, 0x63, + 0x69, 0x61, 0x6c, 0x74, 0x61, 0x6d, 0x62, 0x69, 0x65, 0x6e, 0x6e, 0x69, 0x6e, + 0x67, 0xc3, 0xba, 0x6e, 0x73, 0x61, 0x6c, 0x75, 0x64, 0x6f, 0x73, 0x70, 0x6f, + 0x64, 0x65, 0x6d, 0x6f, 0x73, 0x6d, 0x65, 0x6a, 0x6f, 0x72, 0x61, 0x72, 0x70, + 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x62, 0x75, 0x73, 0x69, 0x6e, 0x65, + 0x73, 0x73, 0x68, 0x6f, 0x6d, 0x65, 0x70, 0x61, 0x67, 0x65, 0x73, 0x65, 0x63, + 0x75, 0x72, 0x69, 0x74, 0x79, 0x6c, 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, + 0x73, 0x74, 0x61, 0x6e, 0x64, 0x61, 0x72, 0x64, 0x63, 0x61, 0x6d, 0x70, 0x61, + 0x69, 0x67, 0x6e, 0x66, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x63, 0x61, + 0x74, 0x65, 0x67, 0x6f, 0x72, 0x79, 0x65, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, + 0x6c, 0x63, 0x68, 0x69, 0x6c, 0x64, 0x72, 0x65, 0x6e, 0x72, 0x65, 0x73, 0x65, + 0x72, 0x76, 0x65, 0x64, 0x72, 0x65, 0x73, 0x65, 0x61, 0x72, 0x63, 0x68, 0x65, + 0x78, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x66, 0x61, 0x76, 0x6f, 0x72, 0x69, + 0x74, 0x65, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x6d, 0x69, 0x6c, + 0x69, 0x74, 0x61, 0x72, 0x79, 0x69, 0x6e, 0x64, 0x75, 0x73, 0x74, 0x72, 0x79, + 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x6d, 0x61, 0x74, 0x65, 0x72, + 0x69, 0x61, 0x6c, 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x73, 0x7a, 0x2d, + 0x69, 0x6e, 0x64, 0x65, 0x78, 0x3a, 0x63, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, + 0x73, 0x73, 0x6f, 0x66, 0x74, 0x77, 0x61, 0x72, 0x65, 0x63, 0x6f, 0x6d, 0x70, + 0x6c, 0x65, 0x74, 0x65, 0x63, 0x61, 0x6c, 0x65, 0x6e, 0x64, 0x61, 0x72, 0x70, + 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x72, 0x74, 0x69, 0x63, 0x6c, + 0x65, 0x73, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x6d, 0x6f, 0x76, + 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x71, 0x75, 0x65, 0x73, 0x74, 0x69, 0x6f, 0x6e, + 0x62, 0x75, 0x69, 0x6c, 0x64, 0x69, 0x6e, 0x67, 0x70, 0x6f, 0x6c, 0x69, 0x74, + 0x69, 0x63, 0x73, 0x70, 0x6f, 0x73, 0x73, 0x69, 0x62, 0x6c, 0x65, 0x72, 0x65, + 0x6c, 0x69, 0x67, 0x69, 0x6f, 0x6e, 0x70, 0x68, 0x79, 0x73, 0x69, 0x63, 0x61, + 0x6c, 0x66, 0x65, 0x65, 0x64, 0x62, 0x61, 0x63, 0x6b, 0x72, 0x65, 0x67, 0x69, + 0x73, 0x74, 0x65, 0x72, 0x70, 0x69, 0x63, 0x74, 0x75, 0x72, 0x65, 0x73, 0x64, + 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, + 0x6f, 0x6c, 0x61, 0x75, 0x64, 0x69, 0x65, 0x6e, 0x63, 0x65, 0x73, 0x65, 0x74, + 0x74, 0x69, 0x6e, 0x67, 0x73, 0x61, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, + 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x6c, 0x65, 0x61, 0x72, 0x6e, + 0x69, 0x6e, 0x67, 0x61, 0x6e, 0x79, 0x74, 0x68, 0x69, 0x6e, 0x67, 0x61, 0x62, + 0x73, 0x74, 0x72, 0x61, 0x63, 0x74, 0x70, 0x72, 0x6f, 0x67, 0x72, 0x65, 0x73, + 0x73, 0x6f, 0x76, 0x65, 0x72, 0x76, 0x69, 0x65, 0x77, 0x6d, 0x61, 0x67, 0x61, + 0x7a, 0x69, 0x6e, 0x65, 0x65, 0x63, 0x6f, 0x6e, 0x6f, 0x6d, 0x69, 0x63, 0x74, + 0x72, 0x61, 0x69, 0x6e, 0x69, 0x6e, 0x67, 0x70, 0x72, 0x65, 0x73, 0x73, 0x75, + 0x72, 0x65, 0x76, 0x61, 0x72, 0x69, 0x6f, 0x75, 0x73, 0x20, 0x3c, 0x73, 0x74, + 0x72, 0x6f, 0x6e, 0x67, 0x3e, 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, + 0x73, 0x68, 0x6f, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x74, 0x6f, 0x67, 0x65, 0x74, + 0x68, 0x65, 0x72, 0x61, 0x64, 0x76, 0x61, 0x6e, 0x63, 0x65, 0x64, 0x62, 0x65, + 0x68, 0x61, 0x76, 0x69, 0x6f, 0x72, 0x64, 0x6f, 0x77, 0x6e, 0x6c, 0x6f, 0x61, + 0x64, 0x66, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x64, 0x66, 0x6f, 0x6f, 0x74, + 0x62, 0x61, 0x6c, 0x6c, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x65, 0x64, 0x4c, + 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, 0x64, 0x69, 0x73, 0x74, 0x61, 0x6e, + 0x63, 0x65, 0x72, 0x65, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x74, 0x72, 0x61, + 0x63, 0x6b, 0x69, 0x6e, 0x67, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, + 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x69, 0x65, 0x64, 0x73, 0x74, 0x75, 0x64, 0x65, + 0x6e, 0x74, 0x73, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6c, 0x79, 0x66, 0x69, + 0x67, 0x68, 0x74, 0x69, 0x6e, 0x67, 0x6e, 0x6f, 0x72, 0x74, 0x68, 0x65, 0x72, + 0x6e, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x66, 0x65, 0x73, 0x74, + 0x69, 0x76, 0x61, 0x6c, 0x62, 0x72, 0x65, 0x61, 0x6b, 0x69, 0x6e, 0x67, 0x6c, + 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, + 0x65, 0x74, 0x64, 0x72, 0x6f, 0x70, 0x64, 0x6f, 0x77, 0x6e, 0x70, 0x72, 0x61, + 0x63, 0x74, 0x69, 0x63, 0x65, 0x65, 0x76, 0x69, 0x64, 0x65, 0x6e, 0x63, 0x65, + 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x6d, 0x61, 0x72, 0x72, 0x69, + 0x61, 0x67, 0x65, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x70, 0x72, + 0x6f, 0x62, 0x6c, 0x65, 0x6d, 0x73, 0x6e, 0x65, 0x67, 0x61, 0x74, 0x69, 0x76, + 0x65, 0x70, 0x72, 0x6f, 0x67, 0x72, 0x61, 0x6d, 0x73, 0x61, 0x6e, 0x61, 0x6c, + 0x79, 0x73, 0x69, 0x73, 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x64, 0x62, + 0x61, 0x6e, 0x6e, 0x65, 0x72, 0x22, 0x3e, 0x70, 0x75, 0x72, 0x63, 0x68, 0x61, + 0x73, 0x65, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x69, 0x65, 0x73, 0x72, 0x65, 0x67, + 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x63, 0x72, 0x65, 0x61, 0x74, 0x69, 0x76, 0x65, + 0x61, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x62, 0x6f, 0x6f, 0x6b, 0x6d, + 0x61, 0x72, 0x6b, 0x72, 0x65, 0x66, 0x65, 0x72, 0x72, 0x65, 0x72, 0x63, 0x68, + 0x65, 0x6d, 0x69, 0x63, 0x61, 0x6c, 0x64, 0x69, 0x76, 0x69, 0x73, 0x69, 0x6f, + 0x6e, 0x63, 0x61, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x73, 0x65, 0x70, 0x61, + 0x72, 0x61, 0x74, 0x65, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x63, + 0x6f, 0x6e, 0x66, 0x6c, 0x69, 0x63, 0x74, 0x68, 0x61, 0x72, 0x64, 0x77, 0x61, + 0x72, 0x65, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x65, 0x73, 0x74, 0x64, 0x65, 0x6c, + 0x69, 0x76, 0x65, 0x72, 0x79, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x61, 0x69, 0x6e, + 0x6f, 0x62, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x64, 0x3d, 0x20, 0x66, 0x61, 0x6c, + 0x73, 0x65, 0x3b, 0x66, 0x6f, 0x72, 0x28, 0x76, 0x61, 0x72, 0x20, 0x61, 0x63, + 0x63, 0x65, 0x70, 0x74, 0x65, 0x64, 0x63, 0x61, 0x70, 0x61, 0x63, 0x69, 0x74, + 0x79, 0x63, 0x6f, 0x6d, 0x70, 0x75, 0x74, 0x65, 0x72, 0x69, 0x64, 0x65, 0x6e, + 0x74, 0x69, 0x74, 0x79, 0x61, 0x69, 0x72, 0x63, 0x72, 0x61, 0x66, 0x74, 0x65, + 0x6d, 0x70, 0x6c, 0x6f, 0x79, 0x65, 0x64, 0x70, 0x72, 0x6f, 0x70, 0x6f, 0x73, + 0x65, 0x64, 0x64, 0x6f, 0x6d, 0x65, 0x73, 0x74, 0x69, 0x63, 0x69, 0x6e, 0x63, + 0x6c, 0x75, 0x64, 0x65, 0x73, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x64, + 0x68, 0x6f, 0x73, 0x70, 0x69, 0x74, 0x61, 0x6c, 0x76, 0x65, 0x72, 0x74, 0x69, + 0x63, 0x61, 0x6c, 0x63, 0x6f, 0x6c, 0x6c, 0x61, 0x70, 0x73, 0x65, 0x61, 0x70, + 0x70, 0x72, 0x6f, 0x61, 0x63, 0x68, 0x70, 0x61, 0x72, 0x74, 0x6e, 0x65, 0x72, + 0x73, 0x6c, 0x6f, 0x67, 0x6f, 0x22, 0x3e, 0x3c, 0x61, 0x64, 0x61, 0x75, 0x67, + 0x68, 0x74, 0x65, 0x72, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x22, 0x20, 0x63, + 0x75, 0x6c, 0x74, 0x75, 0x72, 0x61, 0x6c, 0x66, 0x61, 0x6d, 0x69, 0x6c, 0x69, + 0x65, 0x73, 0x2f, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x73, 0x2f, 0x61, 0x73, 0x73, + 0x65, 0x6d, 0x62, 0x6c, 0x79, 0x70, 0x6f, 0x77, 0x65, 0x72, 0x66, 0x75, 0x6c, + 0x74, 0x65, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x67, 0x66, 0x69, 0x6e, 0x69, 0x73, + 0x68, 0x65, 0x64, 0x64, 0x69, 0x73, 0x74, 0x72, 0x69, 0x63, 0x74, 0x63, 0x72, + 0x69, 0x74, 0x69, 0x63, 0x61, 0x6c, 0x63, 0x67, 0x69, 0x2d, 0x62, 0x69, 0x6e, + 0x2f, 0x70, 0x75, 0x72, 0x70, 0x6f, 0x73, 0x65, 0x73, 0x72, 0x65, 0x71, 0x75, + 0x69, 0x72, 0x65, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x62, + 0x65, 0x63, 0x6f, 0x6d, 0x69, 0x6e, 0x67, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, + 0x65, 0x73, 0x61, 0x63, 0x61, 0x64, 0x65, 0x6d, 0x69, 0x63, 0x65, 0x78, 0x65, + 0x72, 0x63, 0x69, 0x73, 0x65, 0x61, 0x63, 0x74, 0x75, 0x61, 0x6c, 0x6c, 0x79, + 0x6d, 0x65, 0x64, 0x69, 0x63, 0x69, 0x6e, 0x65, 0x63, 0x6f, 0x6e, 0x73, 0x74, + 0x61, 0x6e, 0x74, 0x61, 0x63, 0x63, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x4d, 0x61, + 0x67, 0x61, 0x7a, 0x69, 0x6e, 0x65, 0x64, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, + 0x74, 0x73, 0x74, 0x61, 0x72, 0x74, 0x69, 0x6e, 0x67, 0x62, 0x6f, 0x74, 0x74, + 0x6f, 0x6d, 0x22, 0x3e, 0x6f, 0x62, 0x73, 0x65, 0x72, 0x76, 0x65, 0x64, 0x3a, + 0x20, 0x26, 0x71, 0x75, 0x6f, 0x74, 0x3b, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x64, + 0x65, 0x64, 0x70, 0x72, 0x65, 0x76, 0x69, 0x6f, 0x75, 0x73, 0x53, 0x6f, 0x66, + 0x74, 0x77, 0x61, 0x72, 0x65, 0x63, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x65, 0x72, + 0x64, 0x65, 0x63, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x74, 0x72, 0x65, 0x6e, + 0x67, 0x74, 0x68, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x65, 0x64, 0x73, 0x6c, + 0x69, 0x67, 0x68, 0x74, 0x6c, 0x79, 0x70, 0x6c, 0x61, 0x6e, 0x6e, 0x69, 0x6e, + 0x67, 0x74, 0x65, 0x78, 0x74, 0x61, 0x72, 0x65, 0x61, 0x63, 0x75, 0x72, 0x72, + 0x65, 0x6e, 0x63, 0x79, 0x65, 0x76, 0x65, 0x72, 0x79, 0x6f, 0x6e, 0x65, 0x73, + 0x74, 0x72, 0x61, 0x69, 0x67, 0x68, 0x74, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, + 0x65, 0x72, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x76, 0x65, 0x70, 0x72, 0x6f, + 0x64, 0x75, 0x63, 0x65, 0x64, 0x68, 0x65, 0x72, 0x69, 0x74, 0x61, 0x67, 0x65, + 0x73, 0x68, 0x69, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x61, 0x62, 0x73, 0x6f, 0x6c, + 0x75, 0x74, 0x65, 0x72, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x64, 0x72, 0x65, + 0x6c, 0x65, 0x76, 0x61, 0x6e, 0x74, 0x62, 0x75, 0x74, 0x74, 0x6f, 0x6e, 0x22, + 0x20, 0x76, 0x69, 0x6f, 0x6c, 0x65, 0x6e, 0x63, 0x65, 0x61, 0x6e, 0x79, 0x77, + 0x68, 0x65, 0x72, 0x65, 0x62, 0x65, 0x6e, 0x65, 0x66, 0x69, 0x74, 0x73, 0x6c, + 0x61, 0x75, 0x6e, 0x63, 0x68, 0x65, 0x64, 0x72, 0x65, 0x63, 0x65, 0x6e, 0x74, + 0x6c, 0x79, 0x61, 0x6c, 0x6c, 0x69, 0x61, 0x6e, 0x63, 0x65, 0x66, 0x6f, 0x6c, + 0x6c, 0x6f, 0x77, 0x65, 0x64, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x70, 0x6c, 0x65, + 0x62, 0x75, 0x6c, 0x6c, 0x65, 0x74, 0x69, 0x6e, 0x69, 0x6e, 0x63, 0x6c, 0x75, + 0x64, 0x65, 0x64, 0x6f, 0x63, 0x63, 0x75, 0x72, 0x72, 0x65, 0x64, 0x69, 0x6e, + 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x24, 0x28, 0x74, 0x68, 0x69, 0x73, 0x29, + 0x2e, 0x72, 0x65, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x3e, 0x3c, 0x74, 0x72, + 0x3e, 0x3c, 0x74, 0x64, 0x63, 0x6f, 0x6e, 0x67, 0x72, 0x65, 0x73, 0x73, 0x72, + 0x65, 0x63, 0x6f, 0x72, 0x64, 0x65, 0x64, 0x75, 0x6c, 0x74, 0x69, 0x6d, 0x61, + 0x74, 0x65, 0x73, 0x6f, 0x6c, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x3c, 0x75, 0x6c, + 0x20, 0x69, 0x64, 0x3d, 0x22, 0x64, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, + 0x48, 0x6f, 0x6d, 0x65, 0x3c, 0x2f, 0x61, 0x3e, 0x77, 0x65, 0x62, 0x73, 0x69, + 0x74, 0x65, 0x73, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x61, 0x6c, + 0x74, 0x68, 0x6f, 0x75, 0x67, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x72, 0x65, 0x6c, + 0x79, 0x6d, 0x65, 0x6d, 0x6f, 0x72, 0x69, 0x61, 0x6c, 0x6d, 0x65, 0x73, 0x73, + 0x61, 0x67, 0x65, 0x73, 0x63, 0x6f, 0x6e, 0x74, 0x69, 0x6e, 0x75, 0x65, 0x61, + 0x63, 0x74, 0x69, 0x76, 0x65, 0x22, 0x3e, 0x73, 0x6f, 0x6d, 0x65, 0x77, 0x68, + 0x61, 0x74, 0x76, 0x69, 0x63, 0x74, 0x6f, 0x72, 0x69, 0x61, 0x57, 0x65, 0x73, + 0x74, 0x65, 0x72, 0x6e, 0x20, 0x20, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x3d, 0x22, + 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x63, 0x6f, 0x6e, 0x74, 0x72, + 0x61, 0x63, 0x74, 0x76, 0x69, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x73, 0x44, 0x6f, + 0x77, 0x6e, 0x6c, 0x6f, 0x61, 0x64, 0x77, 0x69, 0x74, 0x68, 0x6f, 0x75, 0x74, + 0x20, 0x72, 0x69, 0x67, 0x68, 0x74, 0x22, 0x3e, 0x0a, 0x6d, 0x65, 0x61, 0x73, + 0x75, 0x72, 0x65, 0x73, 0x77, 0x69, 0x64, 0x74, 0x68, 0x20, 0x3d, 0x20, 0x76, + 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x69, 0x6e, 0x76, 0x6f, 0x6c, 0x76, + 0x65, 0x64, 0x76, 0x69, 0x72, 0x67, 0x69, 0x6e, 0x69, 0x61, 0x6e, 0x6f, 0x72, + 0x6d, 0x61, 0x6c, 0x6c, 0x79, 0x68, 0x61, 0x70, 0x70, 0x65, 0x6e, 0x65, 0x64, + 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x73, 0x74, 0x61, 0x6e, 0x64, + 0x69, 0x6e, 0x67, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x52, 0x65, + 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x70, 0x72, 0x65, 0x70, 0x61, 0x72, 0x65, + 0x64, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x73, 0x61, 0x63, 0x63, 0x75, + 0x72, 0x61, 0x74, 0x65, 0x62, 0x69, 0x72, 0x74, 0x68, 0x64, 0x61, 0x79, 0x73, + 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x6f, 0x66, 0x66, 0x69, 0x63, 0x69, + 0x61, 0x6c, 0x67, 0x72, 0x61, 0x70, 0x68, 0x69, 0x63, 0x73, 0x63, 0x72, 0x69, + 0x6d, 0x69, 0x6e, 0x61, 0x6c, 0x70, 0x6f, 0x73, 0x73, 0x69, 0x62, 0x6c, 0x79, + 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6d, 0x65, 0x72, 0x50, 0x65, 0x72, 0x73, 0x6f, + 0x6e, 0x61, 0x6c, 0x73, 0x70, 0x65, 0x61, 0x6b, 0x69, 0x6e, 0x67, 0x76, 0x61, + 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x61, 0x63, 0x68, 0x69, 0x65, 0x76, 0x65, + 0x64, 0x2e, 0x6a, 0x70, 0x67, 0x22, 0x20, 0x2f, 0x3e, 0x6d, 0x61, 0x63, 0x68, + 0x69, 0x6e, 0x65, 0x73, 0x3c, 0x2f, 0x68, 0x32, 0x3e, 0x0a, 0x20, 0x20, 0x6b, + 0x65, 0x79, 0x77, 0x6f, 0x72, 0x64, 0x73, 0x66, 0x72, 0x69, 0x65, 0x6e, 0x64, + 0x6c, 0x79, 0x62, 0x72, 0x6f, 0x74, 0x68, 0x65, 0x72, 0x73, 0x63, 0x6f, 0x6d, + 0x62, 0x69, 0x6e, 0x65, 0x64, 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x61, 0x6c, + 0x63, 0x6f, 0x6d, 0x70, 0x6f, 0x73, 0x65, 0x64, 0x65, 0x78, 0x70, 0x65, 0x63, + 0x74, 0x65, 0x64, 0x61, 0x64, 0x65, 0x71, 0x75, 0x61, 0x74, 0x65, 0x70, 0x61, + 0x6b, 0x69, 0x73, 0x74, 0x61, 0x6e, 0x66, 0x6f, 0x6c, 0x6c, 0x6f, 0x77, 0x22, + 0x20, 0x76, 0x61, 0x6c, 0x75, 0x61, 0x62, 0x6c, 0x65, 0x3c, 0x2f, 0x6c, 0x61, + 0x62, 0x65, 0x6c, 0x3e, 0x72, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x76, 0x65, 0x62, + 0x72, 0x69, 0x6e, 0x67, 0x69, 0x6e, 0x67, 0x69, 0x6e, 0x63, 0x72, 0x65, 0x61, + 0x73, 0x65, 0x67, 0x6f, 0x76, 0x65, 0x72, 0x6e, 0x6f, 0x72, 0x70, 0x6c, 0x75, + 0x67, 0x69, 0x6e, 0x73, 0x2f, 0x4c, 0x69, 0x73, 0x74, 0x20, 0x6f, 0x66, 0x20, + 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x22, 0x3e, 0x22, 0x20, 0x6e, 0x61, 0x6d, + 0x65, 0x3d, 0x22, 0x20, 0x28, 0x26, 0x71, 0x75, 0x6f, 0x74, 0x3b, 0x67, 0x72, + 0x61, 0x64, 0x75, 0x61, 0x74, 0x65, 0x3c, 0x2f, 0x68, 0x65, 0x61, 0x64, 0x3e, + 0x0a, 0x63, 0x6f, 0x6d, 0x6d, 0x65, 0x72, 0x63, 0x65, 0x6d, 0x61, 0x6c, 0x61, + 0x79, 0x73, 0x69, 0x61, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x6d, + 0x61, 0x69, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x3b, 0x68, 0x65, 0x69, 0x67, 0x68, + 0x74, 0x3a, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x63, 0x68, 0x61, + 0x6e, 0x67, 0x69, 0x6e, 0x67, 0x62, 0x61, 0x63, 0x6b, 0x20, 0x74, 0x6f, 0x20, + 0x63, 0x61, 0x74, 0x68, 0x6f, 0x6c, 0x69, 0x63, 0x70, 0x61, 0x74, 0x74, 0x65, + 0x72, 0x6e, 0x73, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x20, 0x23, 0x67, 0x72, + 0x65, 0x61, 0x74, 0x65, 0x73, 0x74, 0x73, 0x75, 0x70, 0x70, 0x6c, 0x69, 0x65, + 0x73, 0x72, 0x65, 0x6c, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x3c, 0x2f, 0x75, 0x6c, + 0x3e, 0x0a, 0x09, 0x09, 0x3c, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x20, 0x63, + 0x69, 0x74, 0x69, 0x7a, 0x65, 0x6e, 0x73, 0x63, 0x6c, 0x6f, 0x74, 0x68, 0x69, + 0x6e, 0x67, 0x77, 0x61, 0x74, 0x63, 0x68, 0x69, 0x6e, 0x67, 0x3c, 0x6c, 0x69, + 0x20, 0x69, 0x64, 0x3d, 0x22, 0x73, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x63, + 0x63, 0x61, 0x72, 0x72, 0x79, 0x69, 0x6e, 0x67, 0x73, 0x65, 0x6e, 0x74, 0x65, + 0x6e, 0x63, 0x65, 0x3c, 0x63, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x3e, 0x63, 0x6f, + 0x6e, 0x74, 0x72, 0x61, 0x73, 0x74, 0x74, 0x68, 0x69, 0x6e, 0x6b, 0x69, 0x6e, + 0x67, 0x63, 0x61, 0x74, 0x63, 0x68, 0x28, 0x65, 0x29, 0x73, 0x6f, 0x75, 0x74, + 0x68, 0x65, 0x72, 0x6e, 0x4d, 0x69, 0x63, 0x68, 0x61, 0x65, 0x6c, 0x20, 0x6d, + 0x65, 0x72, 0x63, 0x68, 0x61, 0x6e, 0x74, 0x63, 0x61, 0x72, 0x6f, 0x75, 0x73, + 0x65, 0x6c, 0x70, 0x61, 0x64, 0x64, 0x69, 0x6e, 0x67, 0x3a, 0x69, 0x6e, 0x74, + 0x65, 0x72, 0x69, 0x6f, 0x72, 0x2e, 0x73, 0x70, 0x6c, 0x69, 0x74, 0x28, 0x22, + 0x6c, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4f, 0x63, 0x74, 0x6f, 0x62, + 0x65, 0x72, 0x20, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x69, 0x6d, + 0x70, 0x72, 0x6f, 0x76, 0x65, 0x64, 0x2d, 0x2d, 0x26, 0x67, 0x74, 0x3b, 0x0a, + 0x0a, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x61, 0x67, 0x65, 0x63, 0x68, 0x61, 0x69, + 0x72, 0x6d, 0x61, 0x6e, 0x2e, 0x70, 0x6e, 0x67, 0x22, 0x20, 0x2f, 0x3e, 0x73, + 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x52, 0x69, 0x63, 0x68, 0x61, 0x72, + 0x64, 0x20, 0x77, 0x68, 0x61, 0x74, 0x65, 0x76, 0x65, 0x72, 0x70, 0x72, 0x6f, + 0x62, 0x61, 0x62, 0x6c, 0x79, 0x72, 0x65, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x79, + 0x62, 0x61, 0x73, 0x65, 0x62, 0x61, 0x6c, 0x6c, 0x6a, 0x75, 0x64, 0x67, 0x6d, + 0x65, 0x6e, 0x74, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x2e, 0x2e, 0x63, + 0x73, 0x73, 0x22, 0x20, 0x2f, 0x3e, 0x20, 0x77, 0x65, 0x62, 0x73, 0x69, 0x74, + 0x65, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x64, 0x65, 0x66, 0x61, + 0x75, 0x6c, 0x74, 0x22, 0x2f, 0x3e, 0x3c, 0x2f, 0x61, 0x3e, 0x0d, 0x0a, 0x65, + 0x6c, 0x65, 0x63, 0x74, 0x72, 0x69, 0x63, 0x73, 0x63, 0x6f, 0x74, 0x6c, 0x61, + 0x6e, 0x64, 0x63, 0x72, 0x65, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x71, 0x75, 0x61, + 0x6e, 0x74, 0x69, 0x74, 0x79, 0x2e, 0x20, 0x49, 0x53, 0x42, 0x4e, 0x20, 0x30, + 0x64, 0x69, 0x64, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x69, 0x6e, 0x73, 0x74, 0x61, + 0x6e, 0x63, 0x65, 0x2d, 0x73, 0x65, 0x61, 0x72, 0x63, 0x68, 0x2d, 0x22, 0x20, + 0x6c, 0x61, 0x6e, 0x67, 0x3d, 0x22, 0x73, 0x70, 0x65, 0x61, 0x6b, 0x65, 0x72, + 0x73, 0x43, 0x6f, 0x6d, 0x70, 0x75, 0x74, 0x65, 0x72, 0x63, 0x6f, 0x6e, 0x74, + 0x61, 0x69, 0x6e, 0x73, 0x61, 0x72, 0x63, 0x68, 0x69, 0x76, 0x65, 0x73, 0x6d, + 0x69, 0x6e, 0x69, 0x73, 0x74, 0x65, 0x72, 0x72, 0x65, 0x61, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x64, 0x69, 0x73, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x49, 0x74, 0x61, + 0x6c, 0x69, 0x61, 0x6e, 0x6f, 0x63, 0x72, 0x69, 0x74, 0x65, 0x72, 0x69, 0x61, + 0x73, 0x74, 0x72, 0x6f, 0x6e, 0x67, 0x6c, 0x79, 0x3a, 0x20, 0x27, 0x68, 0x74, + 0x74, 0x70, 0x3a, 0x27, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x27, 0x63, 0x6f, + 0x76, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x6f, 0x66, 0x66, 0x65, 0x72, 0x69, 0x6e, + 0x67, 0x61, 0x70, 0x70, 0x65, 0x61, 0x72, 0x65, 0x64, 0x42, 0x72, 0x69, 0x74, + 0x69, 0x73, 0x68, 0x20, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x79, 0x46, + 0x61, 0x63, 0x65, 0x62, 0x6f, 0x6f, 0x6b, 0x6e, 0x75, 0x6d, 0x65, 0x72, 0x6f, + 0x75, 0x73, 0x76, 0x65, 0x68, 0x69, 0x63, 0x6c, 0x65, 0x73, 0x63, 0x6f, 0x6e, + 0x63, 0x65, 0x72, 0x6e, 0x73, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x6e, + 0x68, 0x61, 0x6e, 0x64, 0x6c, 0x69, 0x6e, 0x67, 0x64, 0x69, 0x76, 0x20, 0x69, + 0x64, 0x3d, 0x22, 0x57, 0x69, 0x6c, 0x6c, 0x69, 0x61, 0x6d, 0x20, 0x70, 0x72, + 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, + 0x74, 0x61, 0x63, 0x63, 0x75, 0x72, 0x61, 0x63, 0x79, 0x73, 0x65, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x20, 0x61, 0x6e, 0x64, 0x65, 0x72, 0x73, 0x6f, 0x6e, 0x66, + 0x6c, 0x65, 0x78, 0x69, 0x62, 0x6c, 0x65, 0x43, 0x61, 0x74, 0x65, 0x67, 0x6f, + 0x72, 0x79, 0x6c, 0x61, 0x77, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x3c, 0x73, 0x63, + 0x72, 0x69, 0x70, 0x74, 0x3e, 0x6c, 0x61, 0x79, 0x6f, 0x75, 0x74, 0x3d, 0x22, + 0x61, 0x70, 0x70, 0x72, 0x6f, 0x76, 0x65, 0x64, 0x20, 0x6d, 0x61, 0x78, 0x69, + 0x6d, 0x75, 0x6d, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x22, 0x3e, 0x3c, 0x2f, + 0x74, 0x61, 0x62, 0x6c, 0x65, 0x3e, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, + 0x73, 0x68, 0x61, 0x6d, 0x69, 0x6c, 0x74, 0x6f, 0x6e, 0x63, 0x75, 0x72, 0x72, + 0x65, 0x6e, 0x74, 0x20, 0x63, 0x61, 0x6e, 0x61, 0x64, 0x69, 0x61, 0x6e, 0x63, + 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x73, 0x2f, 0x74, 0x68, 0x65, 0x6d, 0x65, + 0x73, 0x2f, 0x2f, 0x61, 0x72, 0x74, 0x69, 0x63, 0x6c, 0x65, 0x6f, 0x70, 0x74, + 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x70, 0x6f, 0x72, 0x74, 0x75, 0x67, 0x61, 0x6c, + 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3d, 0x22, 0x22, 0x69, 0x6e, 0x74, 0x65, 0x72, + 0x76, 0x61, 0x6c, 0x77, 0x69, 0x72, 0x65, 0x6c, 0x65, 0x73, 0x73, 0x65, 0x6e, + 0x74, 0x69, 0x74, 0x6c, 0x65, 0x64, 0x61, 0x67, 0x65, 0x6e, 0x63, 0x69, 0x65, + 0x73, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x22, 0x20, 0x6d, 0x65, 0x61, 0x73, + 0x75, 0x72, 0x65, 0x64, 0x74, 0x68, 0x6f, 0x75, 0x73, 0x61, 0x6e, 0x64, 0x73, + 0x70, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x26, 0x68, 0x65, 0x6c, 0x6c, 0x69, + 0x70, 0x3b, 0x6e, 0x65, 0x77, 0x20, 0x44, 0x61, 0x74, 0x65, 0x22, 0x20, 0x73, + 0x69, 0x7a, 0x65, 0x3d, 0x22, 0x70, 0x61, 0x67, 0x65, 0x4e, 0x61, 0x6d, 0x65, + 0x6d, 0x69, 0x64, 0x64, 0x6c, 0x65, 0x22, 0x20, 0x22, 0x20, 0x2f, 0x3e, 0x3c, + 0x2f, 0x61, 0x3e, 0x68, 0x69, 0x64, 0x64, 0x65, 0x6e, 0x22, 0x3e, 0x73, 0x65, + 0x71, 0x75, 0x65, 0x6e, 0x63, 0x65, 0x70, 0x65, 0x72, 0x73, 0x6f, 0x6e, 0x61, + 0x6c, 0x6f, 0x76, 0x65, 0x72, 0x66, 0x6c, 0x6f, 0x77, 0x6f, 0x70, 0x69, 0x6e, + 0x69, 0x6f, 0x6e, 0x73, 0x69, 0x6c, 0x6c, 0x69, 0x6e, 0x6f, 0x69, 0x73, 0x6c, + 0x69, 0x6e, 0x6b, 0x73, 0x22, 0x3e, 0x0a, 0x09, 0x3c, 0x74, 0x69, 0x74, 0x6c, + 0x65, 0x3e, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x73, 0x61, 0x74, + 0x75, 0x72, 0x64, 0x61, 0x79, 0x74, 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x61, 0x6c, + 0x69, 0x74, 0x65, 0x6d, 0x70, 0x72, 0x6f, 0x70, 0x65, 0x6e, 0x67, 0x69, 0x6e, + 0x65, 0x65, 0x72, 0x73, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x64, 0x65, + 0x73, 0x69, 0x67, 0x6e, 0x65, 0x72, 0x70, 0x72, 0x6f, 0x70, 0x6f, 0x73, 0x61, + 0x6c, 0x3d, 0x22, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x22, 0x45, 0x73, 0x70, 0x61, + 0xc3, 0xb1, 0x6f, 0x6c, 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x73, 0x73, + 0x75, 0x62, 0x6d, 0x69, 0x74, 0x22, 0x20, 0x65, 0x72, 0x26, 0x71, 0x75, 0x6f, + 0x74, 0x3b, 0x61, 0x64, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x79, 0x6d, + 0x70, 0x74, 0x6f, 0x6d, 0x73, 0x6f, 0x72, 0x69, 0x65, 0x6e, 0x74, 0x65, 0x64, + 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x72, 0x69, 0x67, 0x68, 0x74, + 0x22, 0x3e, 0x3c, 0x70, 0x6c, 0x65, 0x61, 0x73, 0x75, 0x72, 0x65, 0x73, 0x74, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x68, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, + 0x2e, 0x6c, 0x65, 0x61, 0x76, 0x69, 0x6e, 0x67, 0x20, 0x20, 0x62, 0x6f, 0x72, + 0x64, 0x65, 0x72, 0x3d, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x73, 0x63, + 0x65, 0x6e, 0x74, 0x65, 0x72, 0x22, 0x3e, 0x2e, 0x0a, 0x0a, 0x53, 0x6f, 0x6d, + 0x65, 0x20, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x65, 0x64, 0x73, 0x75, 0x69, + 0x74, 0x61, 0x62, 0x6c, 0x65, 0x62, 0x75, 0x6c, 0x67, 0x61, 0x72, 0x69, 0x61, + 0x2e, 0x73, 0x68, 0x6f, 0x77, 0x28, 0x29, 0x3b, 0x64, 0x65, 0x73, 0x69, 0x67, + 0x6e, 0x65, 0x64, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x6c, 0x20, 0x63, 0x6f, + 0x6e, 0x63, 0x65, 0x70, 0x74, 0x73, 0x45, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, + 0x73, 0x77, 0x69, 0x6c, 0x6c, 0x69, 0x61, 0x6d, 0x73, 0x4f, 0x72, 0x69, 0x67, + 0x69, 0x6e, 0x61, 0x6c, 0x22, 0x3e, 0x3c, 0x73, 0x70, 0x61, 0x6e, 0x3e, 0x73, + 0x65, 0x61, 0x72, 0x63, 0x68, 0x22, 0x3e, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, + 0x6f, 0x72, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x73, 0x61, 0x20, 0x26, + 0x71, 0x75, 0x6f, 0x74, 0x3b, 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x69, 0x6e, 0x67, + 0x44, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x72, 0x65, 0x76, 0x69, 0x73, + 0x69, 0x6f, 0x6e, 0x2e, 0x20, 0x0a, 0x0a, 0x54, 0x68, 0x65, 0x20, 0x79, 0x6f, + 0x75, 0x72, 0x73, 0x65, 0x6c, 0x66, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x63, 0x74, + 0x20, 0x6d, 0x69, 0x63, 0x68, 0x69, 0x67, 0x61, 0x6e, 0x45, 0x6e, 0x67, 0x6c, + 0x69, 0x73, 0x68, 0x20, 0x63, 0x6f, 0x6c, 0x75, 0x6d, 0x62, 0x69, 0x61, 0x70, + 0x72, 0x69, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x69, + 0x6e, 0x67, 0x64, 0x72, 0x69, 0x6e, 0x6b, 0x69, 0x6e, 0x67, 0x66, 0x61, 0x63, + 0x69, 0x6c, 0x69, 0x74, 0x79, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x65, 0x64, + 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x20, 0x6f, 0x66, 0x66, 0x69, 0x63, + 0x65, 0x72, 0x73, 0x52, 0x75, 0x73, 0x73, 0x69, 0x61, 0x6e, 0x20, 0x67, 0x65, + 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x2d, 0x38, 0x38, 0x35, 0x39, 0x2d, 0x31, + 0x22, 0x69, 0x6e, 0x64, 0x69, 0x63, 0x61, 0x74, 0x65, 0x66, 0x61, 0x6d, 0x69, + 0x6c, 0x69, 0x61, 0x72, 0x20, 0x71, 0x75, 0x61, 0x6c, 0x69, 0x74, 0x79, 0x6d, + 0x61, 0x72, 0x67, 0x69, 0x6e, 0x3a, 0x30, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x65, + 0x6e, 0x74, 0x76, 0x69, 0x65, 0x77, 0x70, 0x6f, 0x72, 0x74, 0x63, 0x6f, 0x6e, + 0x74, 0x61, 0x63, 0x74, 0x73, 0x2d, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x22, 0x3e, + 0x70, 0x6f, 0x72, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x2e, 0x6c, 0x65, 0x6e, 0x67, + 0x74, 0x68, 0x20, 0x65, 0x6c, 0x69, 0x67, 0x69, 0x62, 0x6c, 0x65, 0x69, 0x6e, + 0x76, 0x6f, 0x6c, 0x76, 0x65, 0x73, 0x61, 0x74, 0x6c, 0x61, 0x6e, 0x74, 0x69, + 0x63, 0x6f, 0x6e, 0x6c, 0x6f, 0x61, 0x64, 0x3d, 0x22, 0x64, 0x65, 0x66, 0x61, + 0x75, 0x6c, 0x74, 0x2e, 0x73, 0x75, 0x70, 0x70, 0x6c, 0x69, 0x65, 0x64, 0x70, + 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x67, 0x6c, 0x6f, 0x73, 0x73, 0x61, + 0x72, 0x79, 0x0a, 0x0a, 0x41, 0x66, 0x74, 0x65, 0x72, 0x20, 0x67, 0x75, 0x69, + 0x64, 0x61, 0x6e, 0x63, 0x65, 0x3c, 0x2f, 0x74, 0x64, 0x3e, 0x3c, 0x74, 0x64, + 0x65, 0x6e, 0x63, 0x6f, 0x64, 0x69, 0x6e, 0x67, 0x6d, 0x69, 0x64, 0x64, 0x6c, + 0x65, 0x22, 0x3e, 0x63, 0x61, 0x6d, 0x65, 0x20, 0x74, 0x6f, 0x20, 0x64, 0x69, + 0x73, 0x70, 0x6c, 0x61, 0x79, 0x73, 0x73, 0x63, 0x6f, 0x74, 0x74, 0x69, 0x73, + 0x68, 0x6a, 0x6f, 0x6e, 0x61, 0x74, 0x68, 0x61, 0x6e, 0x6d, 0x61, 0x6a, 0x6f, + 0x72, 0x69, 0x74, 0x79, 0x77, 0x69, 0x64, 0x67, 0x65, 0x74, 0x73, 0x2e, 0x63, + 0x6c, 0x69, 0x6e, 0x69, 0x63, 0x61, 0x6c, 0x74, 0x68, 0x61, 0x69, 0x6c, 0x61, + 0x6e, 0x64, 0x74, 0x65, 0x61, 0x63, 0x68, 0x65, 0x72, 0x73, 0x3c, 0x68, 0x65, + 0x61, 0x64, 0x3e, 0x0a, 0x09, 0x61, 0x66, 0x66, 0x65, 0x63, 0x74, 0x65, 0x64, + 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x70, 0x6f, 0x69, 0x6e, 0x74, + 0x65, 0x72, 0x3b, 0x74, 0x6f, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x3c, 0x2f, + 0x73, 0x6d, 0x61, 0x6c, 0x6c, 0x3e, 0x6f, 0x6b, 0x6c, 0x61, 0x68, 0x6f, 0x6d, + 0x61, 0x77, 0x69, 0x6c, 0x6c, 0x20, 0x62, 0x65, 0x20, 0x69, 0x6e, 0x76, 0x65, + 0x73, 0x74, 0x6f, 0x72, 0x30, 0x22, 0x20, 0x61, 0x6c, 0x74, 0x3d, 0x22, 0x68, + 0x6f, 0x6c, 0x69, 0x64, 0x61, 0x79, 0x73, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, + 0x63, 0x65, 0x6c, 0x69, 0x63, 0x65, 0x6e, 0x73, 0x65, 0x64, 0x20, 0x28, 0x77, + 0x68, 0x69, 0x63, 0x68, 0x20, 0x2e, 0x20, 0x41, 0x66, 0x74, 0x65, 0x72, 0x20, + 0x63, 0x6f, 0x6e, 0x73, 0x69, 0x64, 0x65, 0x72, 0x76, 0x69, 0x73, 0x69, 0x74, + 0x69, 0x6e, 0x67, 0x65, 0x78, 0x70, 0x6c, 0x6f, 0x72, 0x65, 0x72, 0x70, 0x72, + 0x69, 0x6d, 0x61, 0x72, 0x79, 0x20, 0x73, 0x65, 0x61, 0x72, 0x63, 0x68, 0x22, + 0x20, 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x22, 0x71, 0x75, 0x69, 0x63, + 0x6b, 0x6c, 0x79, 0x20, 0x6d, 0x65, 0x65, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x65, + 0x73, 0x74, 0x69, 0x6d, 0x61, 0x74, 0x65, 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, + 0x6e, 0x20, 0x3b, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x23, 0x20, 0x68, 0x65, + 0x69, 0x67, 0x68, 0x74, 0x3d, 0x61, 0x70, 0x70, 0x72, 0x6f, 0x76, 0x61, 0x6c, + 0x2c, 0x20, 0x26, 0x71, 0x75, 0x6f, 0x74, 0x3b, 0x20, 0x63, 0x68, 0x65, 0x63, + 0x6b, 0x65, 0x64, 0x2e, 0x6d, 0x69, 0x6e, 0x2e, 0x6a, 0x73, 0x22, 0x6d, 0x61, + 0x67, 0x6e, 0x65, 0x74, 0x69, 0x63, 0x3e, 0x3c, 0x2f, 0x61, 0x3e, 0x3c, 0x2f, + 0x68, 0x66, 0x6f, 0x72, 0x65, 0x63, 0x61, 0x73, 0x74, 0x2e, 0x20, 0x57, 0x68, + 0x69, 0x6c, 0x65, 0x20, 0x74, 0x68, 0x75, 0x72, 0x73, 0x64, 0x61, 0x79, 0x64, + 0x76, 0x65, 0x72, 0x74, 0x69, 0x73, 0x65, 0x26, 0x65, 0x61, 0x63, 0x75, 0x74, + 0x65, 0x3b, 0x68, 0x61, 0x73, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x65, 0x76, 0x61, + 0x6c, 0x75, 0x61, 0x74, 0x65, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x69, 0x6e, 0x67, + 0x65, 0x78, 0x69, 0x73, 0x74, 0x69, 0x6e, 0x67, 0x70, 0x61, 0x74, 0x69, 0x65, + 0x6e, 0x74, 0x73, 0x20, 0x4f, 0x6e, 0x6c, 0x69, 0x6e, 0x65, 0x20, 0x63, 0x6f, + 0x6c, 0x6f, 0x72, 0x61, 0x64, 0x6f, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, + 0x22, 0x63, 0x61, 0x6d, 0x70, 0x62, 0x65, 0x6c, 0x6c, 0x3c, 0x21, 0x2d, 0x2d, + 0x20, 0x65, 0x6e, 0x64, 0x3c, 0x2f, 0x73, 0x70, 0x61, 0x6e, 0x3e, 0x3c, 0x3c, + 0x62, 0x72, 0x20, 0x2f, 0x3e, 0x0d, 0x0a, 0x5f, 0x70, 0x6f, 0x70, 0x75, 0x70, + 0x73, 0x7c, 0x73, 0x63, 0x69, 0x65, 0x6e, 0x63, 0x65, 0x73, 0x2c, 0x26, 0x71, + 0x75, 0x6f, 0x74, 0x3b, 0x20, 0x71, 0x75, 0x61, 0x6c, 0x69, 0x74, 0x79, 0x20, + 0x57, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x73, 0x20, 0x61, 0x73, 0x73, 0x69, 0x67, + 0x6e, 0x65, 0x64, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x3a, 0x20, 0x3c, 0x62, + 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x6c, 0x65, 0x26, 0x71, 0x75, 0x6f, 0x74, + 0x3b, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3d, 0x22, 0x20, 0x43, 0x6f, 0x6d, + 0x70, 0x61, 0x6e, 0x79, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x73, 0x3c, + 0x69, 0x66, 0x72, 0x61, 0x6d, 0x65, 0x20, 0x62, 0x65, 0x6c, 0x69, 0x65, 0x76, + 0x65, 0x73, 0x70, 0x72, 0x65, 0x73, 0x65, 0x6e, 0x74, 0x73, 0x6d, 0x61, 0x72, + 0x73, 0x68, 0x61, 0x6c, 0x6c, 0x70, 0x61, 0x72, 0x74, 0x20, 0x6f, 0x66, 0x20, + 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x6c, 0x79, 0x29, 0x2e, 0x0a, 0x0a, 0x54, + 0x68, 0x65, 0x20, 0x74, 0x61, 0x78, 0x6f, 0x6e, 0x6f, 0x6d, 0x79, 0x6d, 0x75, + 0x63, 0x68, 0x20, 0x6f, 0x66, 0x20, 0x3c, 0x2f, 0x73, 0x70, 0x61, 0x6e, 0x3e, + 0x0a, 0x22, 0x20, 0x64, 0x61, 0x74, 0x61, 0x2d, 0x73, 0x72, 0x74, 0x75, 0x67, + 0x75, 0xc3, 0xaa, 0x73, 0x73, 0x63, 0x72, 0x6f, 0x6c, 0x6c, 0x54, 0x6f, 0x20, + 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x3c, 0x68, 0x65, 0x61, 0x64, 0x3e, + 0x0d, 0x0a, 0x61, 0x74, 0x74, 0x6f, 0x72, 0x6e, 0x65, 0x79, 0x65, 0x6d, 0x70, + 0x68, 0x61, 0x73, 0x69, 0x73, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x6f, 0x72, 0x73, + 0x66, 0x61, 0x6e, 0x63, 0x79, 0x62, 0x6f, 0x78, 0x77, 0x6f, 0x72, 0x6c, 0x64, + 0x27, 0x73, 0x20, 0x77, 0x69, 0x6c, 0x64, 0x6c, 0x69, 0x66, 0x65, 0x63, 0x68, + 0x65, 0x63, 0x6b, 0x65, 0x64, 0x3d, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, + 0x73, 0x70, 0x72, 0x6f, 0x67, 0x72, 0x61, 0x6d, 0x6d, 0x70, 0x78, 0x3b, 0x66, + 0x6f, 0x6e, 0x74, 0x2d, 0x20, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x6a, + 0x6f, 0x75, 0x72, 0x6e, 0x61, 0x6c, 0x73, 0x62, 0x65, 0x6c, 0x69, 0x65, 0x76, + 0x65, 0x64, 0x76, 0x61, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x74, 0x68, 0x6f, + 0x6d, 0x70, 0x73, 0x6f, 0x6e, 0x6c, 0x69, 0x67, 0x68, 0x74, 0x69, 0x6e, 0x67, + 0x61, 0x6e, 0x64, 0x20, 0x74, 0x68, 0x65, 0x20, 0x73, 0x70, 0x65, 0x63, 0x69, + 0x61, 0x6c, 0x20, 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x3d, 0x30, 0x63, 0x68, + 0x65, 0x63, 0x6b, 0x69, 0x6e, 0x67, 0x3c, 0x2f, 0x74, 0x62, 0x6f, 0x64, 0x79, + 0x3e, 0x3c, 0x62, 0x75, 0x74, 0x74, 0x6f, 0x6e, 0x20, 0x43, 0x6f, 0x6d, 0x70, + 0x6c, 0x65, 0x74, 0x65, 0x63, 0x6c, 0x65, 0x61, 0x72, 0x66, 0x69, 0x78, 0x0a, + 0x3c, 0x68, 0x65, 0x61, 0x64, 0x3e, 0x0a, 0x61, 0x72, 0x74, 0x69, 0x63, 0x6c, + 0x65, 0x20, 0x3c, 0x73, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x66, 0x69, 0x6e, + 0x64, 0x69, 0x6e, 0x67, 0x73, 0x72, 0x6f, 0x6c, 0x65, 0x20, 0x69, 0x6e, 0x20, + 0x70, 0x6f, 0x70, 0x75, 0x6c, 0x61, 0x72, 0x20, 0x20, 0x4f, 0x63, 0x74, 0x6f, + 0x62, 0x65, 0x72, 0x77, 0x65, 0x62, 0x73, 0x69, 0x74, 0x65, 0x20, 0x65, 0x78, + 0x70, 0x6f, 0x73, 0x75, 0x72, 0x65, 0x75, 0x73, 0x65, 0x64, 0x20, 0x74, 0x6f, + 0x20, 0x20, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x6f, 0x70, 0x65, 0x72, + 0x61, 0x74, 0x65, 0x64, 0x63, 0x6c, 0x69, 0x63, 0x6b, 0x69, 0x6e, 0x67, 0x65, + 0x6e, 0x74, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, + 0x64, 0x73, 0x69, 0x6e, 0x66, 0x6f, 0x72, 0x6d, 0x65, 0x64, 0x20, 0x6e, 0x75, + 0x6d, 0x62, 0x65, 0x72, 0x73, 0x20, 0x20, 0x3c, 0x2f, 0x64, 0x69, 0x76, 0x3e, + 0x63, 0x72, 0x65, 0x61, 0x74, 0x69, 0x6e, 0x67, 0x6f, 0x6e, 0x53, 0x75, 0x62, + 0x6d, 0x69, 0x74, 0x6d, 0x61, 0x72, 0x79, 0x6c, 0x61, 0x6e, 0x64, 0x63, 0x6f, + 0x6c, 0x6c, 0x65, 0x67, 0x65, 0x73, 0x61, 0x6e, 0x61, 0x6c, 0x79, 0x74, 0x69, + 0x63, 0x6c, 0x69, 0x73, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x63, 0x6f, 0x6e, 0x74, + 0x61, 0x63, 0x74, 0x2e, 0x6c, 0x6f, 0x67, 0x67, 0x65, 0x64, 0x49, 0x6e, 0x61, + 0x64, 0x76, 0x69, 0x73, 0x6f, 0x72, 0x79, 0x73, 0x69, 0x62, 0x6c, 0x69, 0x6e, + 0x67, 0x73, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x22, 0x73, 0x26, 0x71, + 0x75, 0x6f, 0x74, 0x3b, 0x29, 0x73, 0x2e, 0x20, 0x54, 0x68, 0x69, 0x73, 0x20, + 0x70, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x73, 0x63, 0x68, 0x65, 0x63, 0x6b, + 0x62, 0x6f, 0x78, 0x73, 0x75, 0x67, 0x67, 0x65, 0x73, 0x74, 0x73, 0x70, 0x72, + 0x65, 0x67, 0x6e, 0x61, 0x6e, 0x74, 0x74, 0x6f, 0x6d, 0x6f, 0x72, 0x72, 0x6f, + 0x77, 0x73, 0x70, 0x61, 0x63, 0x69, 0x6e, 0x67, 0x3d, 0x69, 0x63, 0x6f, 0x6e, + 0x2e, 0x70, 0x6e, 0x67, 0x6a, 0x61, 0x70, 0x61, 0x6e, 0x65, 0x73, 0x65, 0x63, + 0x6f, 0x64, 0x65, 0x62, 0x61, 0x73, 0x65, 0x62, 0x75, 0x74, 0x74, 0x6f, 0x6e, + 0x22, 0x3e, 0x67, 0x61, 0x6d, 0x62, 0x6c, 0x69, 0x6e, 0x67, 0x73, 0x75, 0x63, + 0x68, 0x20, 0x61, 0x73, 0x20, 0x2c, 0x20, 0x77, 0x68, 0x69, 0x6c, 0x65, 0x20, + 0x3c, 0x2f, 0x73, 0x70, 0x61, 0x6e, 0x3e, 0x20, 0x6d, 0x69, 0x73, 0x73, 0x6f, + 0x75, 0x72, 0x69, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x69, 0x6e, 0x67, 0x74, 0x6f, + 0x70, 0x3a, 0x31, 0x70, 0x78, 0x20, 0x2e, 0x3c, 0x2f, 0x73, 0x70, 0x61, 0x6e, + 0x3e, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x77, 0x69, 0x64, 0x74, + 0x68, 0x3d, 0x22, 0x32, 0x6c, 0x61, 0x7a, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x6e, + 0x6f, 0x76, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x75, 0x73, 0x65, 0x64, 0x20, 0x69, + 0x6e, 0x20, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x3d, 0x22, 0x63, 0x72, 0x69, + 0x70, 0x74, 0x22, 0x3e, 0x0a, 0x26, 0x6e, 0x62, 0x73, 0x70, 0x3b, 0x3c, 0x2f, + 0x3c, 0x74, 0x72, 0x3e, 0x3c, 0x74, 0x64, 0x20, 0x68, 0x65, 0x69, 0x67, 0x68, + 0x74, 0x3a, 0x32, 0x2f, 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x63, 0x6f, + 0x75, 0x6e, 0x74, 0x72, 0x79, 0x20, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, + 0x20, 0x66, 0x6f, 0x6f, 0x74, 0x65, 0x72, 0x22, 0x20, 0x26, 0x6c, 0x74, 0x3b, + 0x21, 0x2d, 0x2d, 0x20, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x22, 0x3e, 0x3c, 0x2f, + 0x6a, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x3c, 0x2f, 0x66, 0x6f, 0x72, 0x6d, + 0x3e, 0x0a, 0x28, 0xe7, 0xae, 0x80, 0xe4, 0xbd, 0x93, 0x29, 0x28, 0xe7, 0xb9, + 0x81, 0xe9, 0xab, 0x94, 0x29, 0x68, 0x72, 0x76, 0x61, 0x74, 0x73, 0x6b, 0x69, + 0x69, 0x74, 0x61, 0x6c, 0x69, 0x61, 0x6e, 0x6f, 0x72, 0x6f, 0x6d, 0xc3, 0xa2, + 0x6e, 0xc4, 0x83, 0x74, 0xc3, 0xbc, 0x72, 0x6b, 0xc3, 0xa7, 0x65, 0xd8, 0xa7, + 0xd8, 0xb1, 0xd8, 0xaf, 0xd9, 0x88, 0x74, 0x61, 0x6d, 0x62, 0x69, 0xc3, 0xa9, + 0x6e, 0x6e, 0x6f, 0x74, 0x69, 0x63, 0x69, 0x61, 0x73, 0x6d, 0x65, 0x6e, 0x73, + 0x61, 0x6a, 0x65, 0x73, 0x70, 0x65, 0x72, 0x73, 0x6f, 0x6e, 0x61, 0x73, 0x64, + 0x65, 0x72, 0x65, 0x63, 0x68, 0x6f, 0x73, 0x6e, 0x61, 0x63, 0x69, 0x6f, 0x6e, + 0x61, 0x6c, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x69, 0x6f, 0x63, 0x6f, 0x6e, + 0x74, 0x61, 0x63, 0x74, 0x6f, 0x75, 0x73, 0x75, 0x61, 0x72, 0x69, 0x6f, 0x73, + 0x70, 0x72, 0x6f, 0x67, 0x72, 0x61, 0x6d, 0x61, 0x67, 0x6f, 0x62, 0x69, 0x65, + 0x72, 0x6e, 0x6f, 0x65, 0x6d, 0x70, 0x72, 0x65, 0x73, 0x61, 0x73, 0x61, 0x6e, + 0x75, 0x6e, 0x63, 0x69, 0x6f, 0x73, 0x76, 0x61, 0x6c, 0x65, 0x6e, 0x63, 0x69, + 0x61, 0x63, 0x6f, 0x6c, 0x6f, 0x6d, 0x62, 0x69, 0x61, 0x64, 0x65, 0x73, 0x70, + 0x75, 0xc3, 0xa9, 0x73, 0x64, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x73, 0x70, + 0x72, 0x6f, 0x79, 0x65, 0x63, 0x74, 0x6f, 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, + 0x74, 0x6f, 0x70, 0xc3, 0xba, 0x62, 0x6c, 0x69, 0x63, 0x6f, 0x6e, 0x6f, 0x73, + 0x6f, 0x74, 0x72, 0x6f, 0x73, 0x68, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x69, 0x61, + 0x70, 0x72, 0x65, 0x73, 0x65, 0x6e, 0x74, 0x65, 0x6d, 0x69, 0x6c, 0x6c, 0x6f, + 0x6e, 0x65, 0x73, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x6e, 0x74, 0x65, 0x70, 0x72, + 0x65, 0x67, 0x75, 0x6e, 0x74, 0x61, 0x61, 0x6e, 0x74, 0x65, 0x72, 0x69, 0x6f, + 0x72, 0x72, 0x65, 0x63, 0x75, 0x72, 0x73, 0x6f, 0x73, 0x70, 0x72, 0x6f, 0x62, + 0x6c, 0x65, 0x6d, 0x61, 0x73, 0x61, 0x6e, 0x74, 0x69, 0x61, 0x67, 0x6f, 0x6e, + 0x75, 0x65, 0x73, 0x74, 0x72, 0x6f, 0x73, 0x6f, 0x70, 0x69, 0x6e, 0x69, 0xc3, + 0xb3, 0x6e, 0x69, 0x6d, 0x70, 0x72, 0x69, 0x6d, 0x69, 0x72, 0x6d, 0x69, 0x65, + 0x6e, 0x74, 0x72, 0x61, 0x73, 0x61, 0x6d, 0xc3, 0xa9, 0x72, 0x69, 0x63, 0x61, + 0x76, 0x65, 0x6e, 0x64, 0x65, 0x64, 0x6f, 0x72, 0x73, 0x6f, 0x63, 0x69, 0x65, + 0x64, 0x61, 0x64, 0x72, 0x65, 0x73, 0x70, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x65, + 0x61, 0x6c, 0x69, 0x7a, 0x61, 0x72, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, + 0x6f, 0x70, 0x61, 0x6c, 0x61, 0x62, 0x72, 0x61, 0x73, 0x69, 0x6e, 0x74, 0x65, + 0x72, 0xc3, 0xa9, 0x73, 0x65, 0x6e, 0x74, 0x6f, 0x6e, 0x63, 0x65, 0x73, 0x65, + 0x73, 0x70, 0x65, 0x63, 0x69, 0x61, 0x6c, 0x6d, 0x69, 0x65, 0x6d, 0x62, 0x72, + 0x6f, 0x73, 0x72, 0x65, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x64, 0x63, 0xc3, 0xb3, + 0x72, 0x64, 0x6f, 0x62, 0x61, 0x7a, 0x61, 0x72, 0x61, 0x67, 0x6f, 0x7a, 0x61, + 0x70, 0xc3, 0xa1, 0x67, 0x69, 0x6e, 0x61, 0x73, 0x73, 0x6f, 0x63, 0x69, 0x61, + 0x6c, 0x65, 0x73, 0x62, 0x6c, 0x6f, 0x71, 0x75, 0x65, 0x61, 0x72, 0x67, 0x65, + 0x73, 0x74, 0x69, 0xc3, 0xb3, 0x6e, 0x61, 0x6c, 0x71, 0x75, 0x69, 0x6c, 0x65, + 0x72, 0x73, 0x69, 0x73, 0x74, 0x65, 0x6d, 0x61, 0x73, 0x63, 0x69, 0x65, 0x6e, + 0x63, 0x69, 0x61, 0x73, 0x63, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x6f, 0x76, + 0x65, 0x72, 0x73, 0x69, 0xc3, 0xb3, 0x6e, 0x63, 0x6f, 0x6d, 0x70, 0x6c, 0x65, + 0x74, 0x61, 0x65, 0x73, 0x74, 0x75, 0x64, 0x69, 0x6f, 0x73, 0x70, 0xc3, 0xba, + 0x62, 0x6c, 0x69, 0x63, 0x61, 0x6f, 0x62, 0x6a, 0x65, 0x74, 0x69, 0x76, 0x6f, + 0x61, 0x6c, 0x69, 0x63, 0x61, 0x6e, 0x74, 0x65, 0x62, 0x75, 0x73, 0x63, 0x61, + 0x64, 0x6f, 0x72, 0x63, 0x61, 0x6e, 0x74, 0x69, 0x64, 0x61, 0x64, 0x65, 0x6e, + 0x74, 0x72, 0x61, 0x64, 0x61, 0x73, 0x61, 0x63, 0x63, 0x69, 0x6f, 0x6e, 0x65, + 0x73, 0x61, 0x72, 0x63, 0x68, 0x69, 0x76, 0x6f, 0x73, 0x73, 0x75, 0x70, 0x65, + 0x72, 0x69, 0x6f, 0x72, 0x6d, 0x61, 0x79, 0x6f, 0x72, 0xc3, 0xad, 0x61, 0x61, + 0x6c, 0x65, 0x6d, 0x61, 0x6e, 0x69, 0x61, 0x66, 0x75, 0x6e, 0x63, 0x69, 0xc3, + 0xb3, 0x6e, 0xc3, 0xba, 0x6c, 0x74, 0x69, 0x6d, 0x6f, 0x73, 0x68, 0x61, 0x63, + 0x69, 0x65, 0x6e, 0x64, 0x6f, 0x61, 0x71, 0x75, 0x65, 0x6c, 0x6c, 0x6f, 0x73, + 0x65, 0x64, 0x69, 0x63, 0x69, 0xc3, 0xb3, 0x6e, 0x66, 0x65, 0x72, 0x6e, 0x61, + 0x6e, 0x64, 0x6f, 0x61, 0x6d, 0x62, 0x69, 0x65, 0x6e, 0x74, 0x65, 0x66, 0x61, + 0x63, 0x65, 0x62, 0x6f, 0x6f, 0x6b, 0x6e, 0x75, 0x65, 0x73, 0x74, 0x72, 0x61, + 0x73, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x65, 0x73, 0x70, 0x72, 0x6f, 0x63, + 0x65, 0x73, 0x6f, 0x73, 0x62, 0x61, 0x73, 0x74, 0x61, 0x6e, 0x74, 0x65, 0x70, + 0x72, 0x65, 0x73, 0x65, 0x6e, 0x74, 0x61, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, + 0x61, 0x72, 0x63, 0x6f, 0x6e, 0x67, 0x72, 0x65, 0x73, 0x6f, 0x70, 0x75, 0x62, + 0x6c, 0x69, 0x63, 0x61, 0x72, 0x63, 0x6f, 0x6d, 0x65, 0x72, 0x63, 0x69, 0x6f, + 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x74, 0x6f, 0x6a, 0xc3, 0xb3, 0x76, 0x65, + 0x6e, 0x65, 0x73, 0x64, 0x69, 0x73, 0x74, 0x72, 0x69, 0x74, 0x6f, 0x74, 0xc3, + 0xa9, 0x63, 0x6e, 0x69, 0x63, 0x61, 0x63, 0x6f, 0x6e, 0x6a, 0x75, 0x6e, 0x74, + 0x6f, 0x65, 0x6e, 0x65, 0x72, 0x67, 0xc3, 0xad, 0x61, 0x74, 0x72, 0x61, 0x62, + 0x61, 0x6a, 0x61, 0x72, 0x61, 0x73, 0x74, 0x75, 0x72, 0x69, 0x61, 0x73, 0x72, + 0x65, 0x63, 0x69, 0x65, 0x6e, 0x74, 0x65, 0x75, 0x74, 0x69, 0x6c, 0x69, 0x7a, + 0x61, 0x72, 0x62, 0x6f, 0x6c, 0x65, 0x74, 0xc3, 0xad, 0x6e, 0x73, 0x61, 0x6c, + 0x76, 0x61, 0x64, 0x6f, 0x72, 0x63, 0x6f, 0x72, 0x72, 0x65, 0x63, 0x74, 0x61, + 0x74, 0x72, 0x61, 0x62, 0x61, 0x6a, 0x6f, 0x73, 0x70, 0x72, 0x69, 0x6d, 0x65, + 0x72, 0x6f, 0x73, 0x6e, 0x65, 0x67, 0x6f, 0x63, 0x69, 0x6f, 0x73, 0x6c, 0x69, + 0x62, 0x65, 0x72, 0x74, 0x61, 0x64, 0x64, 0x65, 0x74, 0x61, 0x6c, 0x6c, 0x65, + 0x73, 0x70, 0x61, 0x6e, 0x74, 0x61, 0x6c, 0x6c, 0x61, 0x70, 0x72, 0xc3, 0xb3, + 0x78, 0x69, 0x6d, 0x6f, 0x61, 0x6c, 0x6d, 0x65, 0x72, 0xc3, 0xad, 0x61, 0x61, + 0x6e, 0x69, 0x6d, 0x61, 0x6c, 0x65, 0x73, 0x71, 0x75, 0x69, 0xc3, 0xa9, 0x6e, + 0x65, 0x73, 0x63, 0x6f, 0x72, 0x61, 0x7a, 0xc3, 0xb3, 0x6e, 0x73, 0x65, 0x63, + 0x63, 0x69, 0xc3, 0xb3, 0x6e, 0x62, 0x75, 0x73, 0x63, 0x61, 0x6e, 0x64, 0x6f, + 0x6f, 0x70, 0x63, 0x69, 0x6f, 0x6e, 0x65, 0x73, 0x65, 0x78, 0x74, 0x65, 0x72, + 0x69, 0x6f, 0x72, 0x63, 0x6f, 0x6e, 0x63, 0x65, 0x70, 0x74, 0x6f, 0x74, 0x6f, + 0x64, 0x61, 0x76, 0xc3, 0xad, 0x61, 0x67, 0x61, 0x6c, 0x65, 0x72, 0xc3, 0xad, + 0x61, 0x65, 0x73, 0x63, 0x72, 0x69, 0x62, 0x69, 0x72, 0x6d, 0x65, 0x64, 0x69, + 0x63, 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x63, 0x65, 0x6e, 0x63, 0x69, 0x61, 0x63, + 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x74, 0x61, 0x61, 0x73, 0x70, 0x65, 0x63, 0x74, + 0x6f, 0x73, 0x63, 0x72, 0xc3, 0xad, 0x74, 0x69, 0x63, 0x61, 0x64, 0xc3, 0xb3, + 0x6c, 0x61, 0x72, 0x65, 0x73, 0x6a, 0x75, 0x73, 0x74, 0x69, 0x63, 0x69, 0x61, + 0x64, 0x65, 0x62, 0x65, 0x72, 0xc3, 0xa1, 0x6e, 0x70, 0x65, 0x72, 0xc3, 0xad, + 0x6f, 0x64, 0x6f, 0x6e, 0x65, 0x63, 0x65, 0x73, 0x69, 0x74, 0x61, 0x6d, 0x61, + 0x6e, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x70, 0x65, 0x71, 0x75, 0x65, 0xc3, 0xb1, + 0x6f, 0x72, 0x65, 0x63, 0x69, 0x62, 0x69, 0x64, 0x61, 0x74, 0x72, 0x69, 0x62, + 0x75, 0x6e, 0x61, 0x6c, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x69, 0x66, 0x65, 0x63, + 0x61, 0x6e, 0x63, 0x69, 0xc3, 0xb3, 0x6e, 0x63, 0x61, 0x6e, 0x61, 0x72, 0x69, + 0x61, 0x73, 0x64, 0x65, 0x73, 0x63, 0x61, 0x72, 0x67, 0x61, 0x64, 0x69, 0x76, + 0x65, 0x72, 0x73, 0x6f, 0x73, 0x6d, 0x61, 0x6c, 0x6c, 0x6f, 0x72, 0x63, 0x61, + 0x72, 0x65, 0x71, 0x75, 0x69, 0x65, 0x72, 0x65, 0x74, 0xc3, 0xa9, 0x63, 0x6e, + 0x69, 0x63, 0x6f, 0x64, 0x65, 0x62, 0x65, 0x72, 0xc3, 0xad, 0x61, 0x76, 0x69, + 0x76, 0x69, 0x65, 0x6e, 0x64, 0x61, 0x66, 0x69, 0x6e, 0x61, 0x6e, 0x7a, 0x61, + 0x73, 0x61, 0x64, 0x65, 0x6c, 0x61, 0x6e, 0x74, 0x65, 0x66, 0x75, 0x6e, 0x63, + 0x69, 0x6f, 0x6e, 0x61, 0x63, 0x6f, 0x6e, 0x73, 0x65, 0x6a, 0x6f, 0x73, 0x64, + 0x69, 0x66, 0xc3, 0xad, 0x63, 0x69, 0x6c, 0x63, 0x69, 0x75, 0x64, 0x61, 0x64, + 0x65, 0x73, 0x61, 0x6e, 0x74, 0x69, 0x67, 0x75, 0x61, 0x73, 0x61, 0x76, 0x61, + 0x6e, 0x7a, 0x61, 0x64, 0x61, 0x74, 0xc3, 0xa9, 0x72, 0x6d, 0x69, 0x6e, 0x6f, + 0x75, 0x6e, 0x69, 0x64, 0x61, 0x64, 0x65, 0x73, 0x73, 0xc3, 0xa1, 0x6e, 0x63, + 0x68, 0x65, 0x7a, 0x63, 0x61, 0x6d, 0x70, 0x61, 0xc3, 0xb1, 0x61, 0x73, 0x6f, + 0x66, 0x74, 0x6f, 0x6e, 0x69, 0x63, 0x72, 0x65, 0x76, 0x69, 0x73, 0x74, 0x61, + 0x73, 0x63, 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x6e, 0x65, 0x73, 0x65, 0x63, 0x74, + 0x6f, 0x72, 0x65, 0x73, 0x6d, 0x6f, 0x6d, 0x65, 0x6e, 0x74, 0x6f, 0x73, 0x66, + 0x61, 0x63, 0x75, 0x6c, 0x74, 0x61, 0x64, 0x63, 0x72, 0xc3, 0xa9, 0x64, 0x69, + 0x74, 0x6f, 0x64, 0x69, 0x76, 0x65, 0x72, 0x73, 0x61, 0x73, 0x73, 0x75, 0x70, + 0x75, 0x65, 0x73, 0x74, 0x6f, 0x66, 0x61, 0x63, 0x74, 0x6f, 0x72, 0x65, 0x73, + 0x73, 0x65, 0x67, 0x75, 0x6e, 0x64, 0x6f, 0x73, 0x70, 0x65, 0x71, 0x75, 0x65, + 0xc3, 0xb1, 0x61, 0xd0, 0xb3, 0xd0, 0xbe, 0xd0, 0xb4, 0xd0, 0xb0, 0xd0, 0xb5, + 0xd1, 0x81, 0xd0, 0xbb, 0xd0, 0xb8, 0xd0, 0xb5, 0xd1, 0x81, 0xd1, 0x82, 0xd1, + 0x8c, 0xd0, 0xb1, 0xd1, 0x8b, 0xd0, 0xbb, 0xd0, 0xbe, 0xd0, 0xb1, 0xd1, 0x8b, + 0xd1, 0x82, 0xd1, 0x8c, 0xd1, 0x8d, 0xd1, 0x82, 0xd0, 0xbe, 0xd0, 0xbc, 0xd0, + 0x95, 0xd1, 0x81, 0xd0, 0xbb, 0xd0, 0xb8, 0xd1, 0x82, 0xd0, 0xbe, 0xd0, 0xb3, + 0xd0, 0xbe, 0xd0, 0xbc, 0xd0, 0xb5, 0xd0, 0xbd, 0xd1, 0x8f, 0xd0, 0xb2, 0xd1, + 0x81, 0xd0, 0xb5, 0xd1, 0x85, 0xd1, 0x8d, 0xd1, 0x82, 0xd0, 0xbe, 0xd0, 0xb9, + 0xd0, 0xb4, 0xd0, 0xb0, 0xd0, 0xb6, 0xd0, 0xb5, 0xd0, 0xb1, 0xd1, 0x8b, 0xd0, + 0xbb, 0xd0, 0xb8, 0xd0, 0xb3, 0xd0, 0xbe, 0xd0, 0xb4, 0xd1, 0x83, 0xd0, 0xb4, + 0xd0, 0xb5, 0xd0, 0xbd, 0xd1, 0x8c, 0xd1, 0x8d, 0xd1, 0x82, 0xd0, 0xbe, 0xd1, + 0x82, 0xd0, 0xb1, 0xd1, 0x8b, 0xd0, 0xbb, 0xd0, 0xb0, 0xd1, 0x81, 0xd0, 0xb5, + 0xd0, 0xb1, 0xd1, 0x8f, 0xd0, 0xbe, 0xd0, 0xb4, 0xd0, 0xb8, 0xd0, 0xbd, 0xd1, + 0x81, 0xd0, 0xb5, 0xd0, 0xb1, 0xd0, 0xb5, 0xd0, 0xbd, 0xd0, 0xb0, 0xd0, 0xb4, + 0xd0, 0xbe, 0xd1, 0x81, 0xd0, 0xb0, 0xd0, 0xb9, 0xd1, 0x82, 0xd1, 0x84, 0xd0, + 0xbe, 0xd1, 0x82, 0xd0, 0xbe, 0xd0, 0xbd, 0xd0, 0xb5, 0xd0, 0xb3, 0xd0, 0xbe, + 0xd1, 0x81, 0xd0, 0xb2, 0xd0, 0xbe, 0xd0, 0xb8, 0xd1, 0x81, 0xd0, 0xb2, 0xd0, + 0xbe, 0xd0, 0xb9, 0xd0, 0xb8, 0xd0, 0xb3, 0xd1, 0x80, 0xd1, 0x8b, 0xd1, 0x82, + 0xd0, 0xbe, 0xd0, 0xb6, 0xd0, 0xb5, 0xd0, 0xb2, 0xd1, 0x81, 0xd0, 0xb5, 0xd0, + 0xbc, 0xd1, 0x81, 0xd0, 0xb2, 0xd0, 0xbe, 0xd1, 0x8e, 0xd0, 0xbb, 0xd0, 0xb8, + 0xd1, 0x88, 0xd1, 0x8c, 0xd1, 0x8d, 0xd1, 0x82, 0xd0, 0xb8, 0xd1, 0x85, 0xd0, + 0xbf, 0xd0, 0xbe, 0xd0, 0xba, 0xd0, 0xb0, 0xd0, 0xb4, 0xd0, 0xbd, 0xd0, 0xb5, + 0xd0, 0xb9, 0xd0, 0xb4, 0xd0, 0xbe, 0xd0, 0xbc, 0xd0, 0xb0, 0xd0, 0xbc, 0xd0, + 0xb8, 0xd1, 0x80, 0xd0, 0xb0, 0xd0, 0xbb, 0xd0, 0xb8, 0xd0, 0xb1, 0xd0, 0xbe, + 0xd1, 0x82, 0xd0, 0xb5, 0xd0, 0xbc, 0xd1, 0x83, 0xd1, 0x85, 0xd0, 0xbe, 0xd1, + 0x82, 0xd1, 0x8f, 0xd0, 0xb4, 0xd0, 0xb2, 0xd1, 0x83, 0xd1, 0x85, 0xd1, 0x81, + 0xd0, 0xb5, 0xd1, 0x82, 0xd0, 0xb8, 0xd0, 0xbb, 0xd1, 0x8e, 0xd0, 0xb4, 0xd0, + 0xb8, 0xd0, 0xb4, 0xd0, 0xb5, 0xd0, 0xbb, 0xd0, 0xbe, 0xd0, 0xbc, 0xd0, 0xb8, + 0xd1, 0x80, 0xd0, 0xb5, 0xd1, 0x82, 0xd0, 0xb5, 0xd0, 0xb1, 0xd1, 0x8f, 0xd1, + 0x81, 0xd0, 0xb2, 0xd0, 0xbe, 0xd0, 0xb5, 0xd0, 0xb2, 0xd0, 0xb8, 0xd0, 0xb4, + 0xd0, 0xb5, 0xd1, 0x87, 0xd0, 0xb5, 0xd0, 0xb3, 0xd0, 0xbe, 0xd1, 0x8d, 0xd1, + 0x82, 0xd0, 0xb8, 0xd0, 0xbc, 0xd1, 0x81, 0xd1, 0x87, 0xd0, 0xb5, 0xd1, 0x82, + 0xd1, 0x82, 0xd0, 0xb5, 0xd0, 0xbc, 0xd1, 0x8b, 0xd1, 0x86, 0xd0, 0xb5, 0xd0, + 0xbd, 0xd1, 0x8b, 0xd1, 0x81, 0xd1, 0x82, 0xd0, 0xb0, 0xd0, 0xbb, 0xd0, 0xb2, + 0xd0, 0xb5, 0xd0, 0xb4, 0xd1, 0x8c, 0xd1, 0x82, 0xd0, 0xb5, 0xd0, 0xbc, 0xd0, + 0xb5, 0xd0, 0xb2, 0xd0, 0xbe, 0xd0, 0xb4, 0xd1, 0x8b, 0xd1, 0x82, 0xd0, 0xb5, + 0xd0, 0xb1, 0xd0, 0xb5, 0xd0, 0xb2, 0xd1, 0x8b, 0xd1, 0x88, 0xd0, 0xb5, 0xd0, + 0xbd, 0xd0, 0xb0, 0xd0, 0xbc, 0xd0, 0xb8, 0xd1, 0x82, 0xd0, 0xb8, 0xd0, 0xbf, + 0xd0, 0xb0, 0xd1, 0x82, 0xd0, 0xbe, 0xd0, 0xbc, 0xd1, 0x83, 0xd0, 0xbf, 0xd1, + 0x80, 0xd0, 0xb0, 0xd0, 0xb2, 0xd0, 0xbb, 0xd0, 0xb8, 0xd1, 0x86, 0xd0, 0xb0, + 0xd0, 0xbe, 0xd0, 0xb4, 0xd0, 0xbd, 0xd0, 0xb0, 0xd0, 0xb3, 0xd0, 0xbe, 0xd0, + 0xb4, 0xd1, 0x8b, 0xd0, 0xb7, 0xd0, 0xbd, 0xd0, 0xb0, 0xd1, 0x8e, 0xd0, 0xbc, + 0xd0, 0xbe, 0xd0, 0xb3, 0xd1, 0x83, 0xd0, 0xb4, 0xd1, 0x80, 0xd1, 0x83, 0xd0, + 0xb3, 0xd0, 0xb2, 0xd1, 0x81, 0xd0, 0xb5, 0xd0, 0xb9, 0xd0, 0xb8, 0xd0, 0xb4, + 0xd0, 0xb5, 0xd1, 0x82, 0xd0, 0xba, 0xd0, 0xb8, 0xd0, 0xbd, 0xd0, 0xbe, 0xd0, + 0xbe, 0xd0, 0xb4, 0xd0, 0xbd, 0xd0, 0xbe, 0xd0, 0xb4, 0xd0, 0xb5, 0xd0, 0xbb, + 0xd0, 0xb0, 0xd0, 0xb4, 0xd0, 0xb5, 0xd0, 0xbb, 0xd0, 0xb5, 0xd1, 0x81, 0xd1, + 0x80, 0xd0, 0xbe, 0xd0, 0xba, 0xd0, 0xb8, 0xd1, 0x8e, 0xd0, 0xbd, 0xd1, 0x8f, + 0xd0, 0xb2, 0xd0, 0xb5, 0xd1, 0x81, 0xd1, 0x8c, 0xd0, 0x95, 0xd1, 0x81, 0xd1, + 0x82, 0xd1, 0x8c, 0xd1, 0x80, 0xd0, 0xb0, 0xd0, 0xb7, 0xd0, 0xb0, 0xd0, 0xbd, + 0xd0, 0xb0, 0xd1, 0x88, 0xd0, 0xb8, 0xd8, 0xa7, 0xd9, 0x84, 0xd9, 0x84, 0xd9, + 0x87, 0xd8, 0xa7, 0xd9, 0x84, 0xd8, 0xaa, 0xd9, 0x8a, 0xd8, 0xac, 0xd9, 0x85, + 0xd9, 0x8a, 0xd8, 0xb9, 0xd8, 0xae, 0xd8, 0xa7, 0xd8, 0xb5, 0xd8, 0xa9, 0xd8, + 0xa7, 0xd9, 0x84, 0xd8, 0xb0, 0xd9, 0x8a, 0xd8, 0xb9, 0xd9, 0x84, 0xd9, 0x8a, + 0xd9, 0x87, 0xd8, 0xac, 0xd8, 0xaf, 0xd9, 0x8a, 0xd8, 0xaf, 0xd8, 0xa7, 0xd9, + 0x84, 0xd8, 0xa2, 0xd9, 0x86, 0xd8, 0xa7, 0xd9, 0x84, 0xd8, 0xb1, 0xd8, 0xaf, + 0xd8, 0xaa, 0xd8, 0xad, 0xd9, 0x83, 0xd9, 0x85, 0xd8, 0xb5, 0xd9, 0x81, 0xd8, + 0xad, 0xd8, 0xa9, 0xd9, 0x83, 0xd8, 0xa7, 0xd9, 0x86, 0xd8, 0xaa, 0xd8, 0xa7, + 0xd9, 0x84, 0xd9, 0x84, 0xd9, 0x8a, 0xd9, 0x8a, 0xd9, 0x83, 0xd9, 0x88, 0xd9, + 0x86, 0xd8, 0xb4, 0xd8, 0xa8, 0xd9, 0x83, 0xd8, 0xa9, 0xd9, 0x81, 0xd9, 0x8a, + 0xd9, 0x87, 0xd8, 0xa7, 0xd8, 0xa8, 0xd9, 0x86, 0xd8, 0xa7, 0xd8, 0xaa, 0xd8, + 0xad, 0xd9, 0x88, 0xd8, 0xa7, 0xd8, 0xa1, 0xd8, 0xa3, 0xd9, 0x83, 0xd8, 0xab, + 0xd8, 0xb1, 0xd8, 0xae, 0xd9, 0x84, 0xd8, 0xa7, 0xd9, 0x84, 0xd8, 0xa7, 0xd9, + 0x84, 0xd8, 0xad, 0xd8, 0xa8, 0xd8, 0xaf, 0xd9, 0x84, 0xd9, 0x8a, 0xd9, 0x84, + 0xd8, 0xaf, 0xd8, 0xb1, 0xd9, 0x88, 0xd8, 0xb3, 0xd8, 0xa7, 0xd8, 0xb6, 0xd8, + 0xba, 0xd8, 0xb7, 0xd8, 0xaa, 0xd9, 0x83, 0xd9, 0x88, 0xd9, 0x86, 0xd9, 0x87, + 0xd9, 0x86, 0xd8, 0xa7, 0xd9, 0x83, 0xd8, 0xb3, 0xd8, 0xa7, 0xd8, 0xad, 0xd8, + 0xa9, 0xd9, 0x86, 0xd8, 0xa7, 0xd8, 0xaf, 0xd9, 0x8a, 0xd8, 0xa7, 0xd9, 0x84, + 0xd8, 0xb7, 0xd8, 0xa8, 0xd8, 0xb9, 0xd9, 0x84, 0xd9, 0x8a, 0xd9, 0x83, 0xd8, + 0xb4, 0xd9, 0x83, 0xd8, 0xb1, 0xd8, 0xa7, 0xd9, 0x8a, 0xd9, 0x85, 0xd9, 0x83, + 0xd9, 0x86, 0xd9, 0x85, 0xd9, 0x86, 0xd9, 0x87, 0xd8, 0xa7, 0xd8, 0xb4, 0xd8, + 0xb1, 0xd9, 0x83, 0xd8, 0xa9, 0xd8, 0xb1, 0xd8, 0xa6, 0xd9, 0x8a, 0xd8, 0xb3, + 0xd9, 0x86, 0xd8, 0xb4, 0xd9, 0x8a, 0xd8, 0xb7, 0xd9, 0x85, 0xd8, 0xa7, 0xd8, + 0xb0, 0xd8, 0xa7, 0xd8, 0xa7, 0xd9, 0x84, 0xd9, 0x81, 0xd9, 0x86, 0xd8, 0xb4, + 0xd8, 0xa8, 0xd8, 0xa7, 0xd8, 0xa8, 0xd8, 0xaa, 0xd8, 0xb9, 0xd8, 0xa8, 0xd8, + 0xb1, 0xd8, 0xb1, 0xd8, 0xad, 0xd9, 0x85, 0xd8, 0xa9, 0xd9, 0x83, 0xd8, 0xa7, + 0xd9, 0x81, 0xd8, 0xa9, 0xd9, 0x8a, 0xd9, 0x82, 0xd9, 0x88, 0xd9, 0x84, 0xd9, + 0x85, 0xd8, 0xb1, 0xd9, 0x83, 0xd8, 0xb2, 0xd9, 0x83, 0xd9, 0x84, 0xd9, 0x85, + 0xd8, 0xa9, 0xd8, 0xa3, 0xd8, 0xad, 0xd9, 0x85, 0xd8, 0xaf, 0xd9, 0x82, 0xd9, + 0x84, 0xd8, 0xa8, 0xd9, 0x8a, 0xd9, 0x8a, 0xd8, 0xb9, 0xd9, 0x86, 0xd9, 0x8a, + 0xd8, 0xb5, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xa9, 0xd8, 0xb7, 0xd8, 0xb1, 0xd9, + 0x8a, 0xd9, 0x82, 0xd8, 0xb4, 0xd8, 0xa7, 0xd8, 0xb1, 0xd9, 0x83, 0xd8, 0xac, + 0xd9, 0x88, 0xd8, 0xa7, 0xd9, 0x84, 0xd8, 0xa3, 0xd8, 0xae, 0xd8, 0xb1, 0xd9, + 0x89, 0xd9, 0x85, 0xd8, 0xb9, 0xd9, 0x86, 0xd8, 0xa7, 0xd8, 0xa7, 0xd8, 0xa8, + 0xd8, 0xad, 0xd8, 0xab, 0xd8, 0xb9, 0xd8, 0xb1, 0xd9, 0x88, 0xd8, 0xb6, 0xd8, + 0xa8, 0xd8, 0xb4, 0xd9, 0x83, 0xd9, 0x84, 0xd9, 0x85, 0xd8, 0xb3, 0xd8, 0xac, + 0xd9, 0x84, 0xd8, 0xa8, 0xd9, 0x86, 0xd8, 0xa7, 0xd9, 0x86, 0xd8, 0xae, 0xd8, + 0xa7, 0xd9, 0x84, 0xd8, 0xaf, 0xd9, 0x83, 0xd8, 0xaa, 0xd8, 0xa7, 0xd8, 0xa8, + 0xd9, 0x83, 0xd9, 0x84, 0xd9, 0x8a, 0xd8, 0xa9, 0xd8, 0xa8, 0xd8, 0xaf, 0xd9, + 0x88, 0xd9, 0x86, 0xd8, 0xa3, 0xd9, 0x8a, 0xd8, 0xb6, 0xd8, 0xa7, 0xd9, 0x8a, + 0xd9, 0x88, 0xd8, 0xac, 0xd8, 0xaf, 0xd9, 0x81, 0xd8, 0xb1, 0xd9, 0x8a, 0xd9, + 0x82, 0xd9, 0x83, 0xd8, 0xaa, 0xd8, 0xa8, 0xd8, 0xaa, 0xd8, 0xa3, 0xd9, 0x81, + 0xd8, 0xb6, 0xd9, 0x84, 0xd9, 0x85, 0xd8, 0xb7, 0xd8, 0xa8, 0xd8, 0xae, 0xd8, + 0xa7, 0xd9, 0x83, 0xd8, 0xab, 0xd8, 0xb1, 0xd8, 0xa8, 0xd8, 0xa7, 0xd8, 0xb1, + 0xd9, 0x83, 0xd8, 0xa7, 0xd9, 0x81, 0xd8, 0xb6, 0xd9, 0x84, 0xd8, 0xa7, 0xd8, + 0xad, 0xd9, 0x84, 0xd9, 0x89, 0xd9, 0x86, 0xd9, 0x81, 0xd8, 0xb3, 0xd9, 0x87, + 0xd8, 0xa3, 0xd9, 0x8a, 0xd8, 0xa7, 0xd9, 0x85, 0xd8, 0xb1, 0xd8, 0xaf, 0xd9, + 0x88, 0xd8, 0xaf, 0xd8, 0xa3, 0xd9, 0x86, 0xd9, 0x87, 0xd8, 0xa7, 0xd8, 0xaf, + 0xd9, 0x8a, 0xd9, 0x86, 0xd8, 0xa7, 0xd8, 0xa7, 0xd9, 0x84, 0xd8, 0xa7, 0xd9, + 0x86, 0xd9, 0x85, 0xd8, 0xb9, 0xd8, 0xb1, 0xd8, 0xb6, 0xd8, 0xaa, 0xd8, 0xb9, + 0xd9, 0x84, 0xd9, 0x85, 0xd8, 0xaf, 0xd8, 0xa7, 0xd8, 0xae, 0xd9, 0x84, 0xd9, + 0x85, 0xd9, 0x85, 0xd9, 0x83, 0xd9, 0x86, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x07, 0x06, 0x05, 0x04, 0x03, + 0x02, 0x01, 0x00, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x0f, 0x0e, + 0x0d, 0x0c, 0x0b, 0x0a, 0x09, 0x08, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, + 0x17, 0x17, 0x16, 0x15, 0x14, 0x13, 0x12, 0x11, 0x10, 0x18, 0x19, 0x1a, 0x1b, + 0x1c, 0x1d, 0x1e, 0x1f, 0x1f, 0x1e, 0x1d, 0x1c, 0x1b, 0x1a, 0x19, 0x18, 0xff, + 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, + 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, + 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0xff, 0xff, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0xff, 0xff, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x00, + 0x00, 0x01, 0x00, 0x02, 0x00, 0x03, 0x00, 0x04, 0x00, 0x05, 0x00, 0x06, 0x00, + 0x07, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x63, 0x6f, 0x75, + 0x6e, 0x74, 0x72, 0x69, 0x65, 0x73, 0x71, 0x75, 0x65, 0x73, 0x74, 0x69, 0x6f, + 0x6e, 0x73, 0x65, 0x71, 0x75, 0x69, 0x70, 0x6d, 0x65, 0x6e, 0x74, 0x63, 0x6f, + 0x6d, 0x6d, 0x75, 0x6e, 0x69, 0x74, 0x79, 0x61, 0x76, 0x61, 0x69, 0x6c, 0x61, + 0x62, 0x6c, 0x65, 0x68, 0x69, 0x67, 0x68, 0x6c, 0x69, 0x67, 0x68, 0x74, 0x44, + 0x54, 0x44, 0x2f, 0x78, 0x68, 0x74, 0x6d, 0x6c, 0x6d, 0x61, 0x72, 0x6b, 0x65, + 0x74, 0x69, 0x6e, 0x67, 0x6b, 0x6e, 0x6f, 0x77, 0x6c, 0x65, 0x64, 0x67, 0x65, + 0x73, 0x6f, 0x6d, 0x65, 0x74, 0x68, 0x69, 0x6e, 0x67, 0x63, 0x6f, 0x6e, 0x74, + 0x61, 0x69, 0x6e, 0x65, 0x72, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x73, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x61, 0x64, 0x76, + 0x65, 0x72, 0x74, 0x69, 0x73, 0x65, 0x63, 0x68, 0x61, 0x72, 0x61, 0x63, 0x74, + 0x65, 0x72, 0x22, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3d, 0x22, 0x3c, 0x2f, + 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x3e, 0x41, 0x75, 0x73, 0x74, 0x72, 0x61, + 0x6c, 0x69, 0x61, 0x22, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x22, 0x73, + 0x69, 0x74, 0x75, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x75, 0x74, 0x68, 0x6f, + 0x72, 0x69, 0x74, 0x79, 0x66, 0x6f, 0x6c, 0x6c, 0x6f, 0x77, 0x69, 0x6e, 0x67, + 0x70, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x69, 0x6c, 0x79, 0x6f, 0x70, 0x65, 0x72, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x63, 0x68, 0x61, 0x6c, 0x6c, 0x65, 0x6e, 0x67, + 0x65, 0x64, 0x65, 0x76, 0x65, 0x6c, 0x6f, 0x70, 0x65, 0x64, 0x61, 0x6e, 0x6f, + 0x6e, 0x79, 0x6d, 0x6f, 0x75, 0x73, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x63, 0x6f, + 0x6d, 0x70, 0x61, 0x6e, 0x69, 0x65, 0x73, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, + 0x75, 0x72, 0x65, 0x61, 0x67, 0x72, 0x65, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x22, + 0x20, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x3d, 0x22, 0x70, 0x6f, 0x74, 0x65, 0x6e, + 0x74, 0x69, 0x61, 0x6c, 0x65, 0x64, 0x75, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x61, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x73, 0x65, 0x63, 0x6f, + 0x6e, 0x64, 0x61, 0x72, 0x79, 0x63, 0x6f, 0x70, 0x79, 0x72, 0x69, 0x67, 0x68, + 0x74, 0x6c, 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, 0x73, 0x65, 0x78, 0x63, + 0x6c, 0x75, 0x73, 0x69, 0x76, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, + 0x6f, 0x6e, 0x3c, 0x2f, 0x66, 0x6f, 0x72, 0x6d, 0x3e, 0x0d, 0x0a, 0x73, 0x74, + 0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x61, 0x74, 0x74, 0x65, 0x6e, 0x74, + 0x69, 0x6f, 0x6e, 0x42, 0x69, 0x6f, 0x67, 0x72, 0x61, 0x70, 0x68, 0x79, 0x7d, + 0x20, 0x65, 0x6c, 0x73, 0x65, 0x20, 0x7b, 0x0a, 0x73, 0x6f, 0x6c, 0x75, 0x74, + 0x69, 0x6f, 0x6e, 0x73, 0x77, 0x68, 0x65, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, + 0x41, 0x6e, 0x61, 0x6c, 0x79, 0x74, 0x69, 0x63, 0x73, 0x74, 0x65, 0x6d, 0x70, + 0x6c, 0x61, 0x74, 0x65, 0x73, 0x64, 0x61, 0x6e, 0x67, 0x65, 0x72, 0x6f, 0x75, + 0x73, 0x73, 0x61, 0x74, 0x65, 0x6c, 0x6c, 0x69, 0x74, 0x65, 0x64, 0x6f, 0x63, + 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68, + 0x65, 0x72, 0x69, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x61, 0x6e, 0x74, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x74, 0x79, 0x70, 0x65, 0x69, 0x6e, 0x66, 0x6c, 0x75, 0x65, + 0x6e, 0x63, 0x65, 0x26, 0x72, 0x61, 0x71, 0x75, 0x6f, 0x3b, 0x3c, 0x2f, 0x65, + 0x66, 0x66, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x67, 0x65, 0x6e, 0x65, 0x72, + 0x61, 0x6c, 0x6c, 0x79, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x6f, 0x72, 0x6d, + 0x62, 0x65, 0x61, 0x75, 0x74, 0x69, 0x66, 0x75, 0x6c, 0x74, 0x72, 0x61, 0x6e, + 0x73, 0x70, 0x6f, 0x72, 0x74, 0x6f, 0x72, 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x65, + 0x64, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x65, 0x64, 0x70, 0x72, 0x6f, + 0x6d, 0x69, 0x6e, 0x65, 0x6e, 0x74, 0x75, 0x6e, 0x74, 0x69, 0x6c, 0x20, 0x74, + 0x68, 0x65, 0x74, 0x68, 0x75, 0x6d, 0x62, 0x6e, 0x61, 0x69, 0x6c, 0x4e, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x20, 0x2e, 0x66, 0x6f, 0x63, 0x75, 0x73, + 0x28, 0x29, 0x3b, 0x6f, 0x76, 0x65, 0x72, 0x20, 0x74, 0x68, 0x65, 0x20, 0x6d, + 0x69, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6e, 0x6e, 0x6f, 0x75, + 0x6e, 0x63, 0x65, 0x64, 0x66, 0x6f, 0x6f, 0x74, 0x65, 0x72, 0x22, 0x3e, 0x0a, + 0x65, 0x78, 0x63, 0x65, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x6c, 0x65, 0x73, 0x73, + 0x20, 0x74, 0x68, 0x61, 0x6e, 0x65, 0x78, 0x70, 0x65, 0x6e, 0x73, 0x69, 0x76, + 0x65, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x66, 0x72, 0x61, + 0x6d, 0x65, 0x77, 0x6f, 0x72, 0x6b, 0x74, 0x65, 0x72, 0x72, 0x69, 0x74, 0x6f, + 0x72, 0x79, 0x6e, 0x64, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x63, 0x75, + 0x72, 0x72, 0x65, 0x6e, 0x74, 0x6c, 0x79, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x4e, + 0x61, 0x6d, 0x65, 0x63, 0x72, 0x69, 0x74, 0x69, 0x63, 0x69, 0x73, 0x6d, 0x74, + 0x72, 0x61, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x65, 0x6c, 0x73, 0x65, 0x77, + 0x68, 0x65, 0x72, 0x65, 0x41, 0x6c, 0x65, 0x78, 0x61, 0x6e, 0x64, 0x65, 0x72, + 0x61, 0x70, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x65, 0x64, 0x6d, 0x61, 0x74, 0x65, + 0x72, 0x69, 0x61, 0x6c, 0x73, 0x62, 0x72, 0x6f, 0x61, 0x64, 0x63, 0x61, 0x73, + 0x74, 0x6d, 0x65, 0x6e, 0x74, 0x69, 0x6f, 0x6e, 0x65, 0x64, 0x61, 0x66, 0x66, + 0x69, 0x6c, 0x69, 0x61, 0x74, 0x65, 0x3c, 0x2f, 0x6f, 0x70, 0x74, 0x69, 0x6f, + 0x6e, 0x3e, 0x74, 0x72, 0x65, 0x61, 0x74, 0x6d, 0x65, 0x6e, 0x74, 0x64, 0x69, + 0x66, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x74, 0x2f, 0x64, 0x65, 0x66, 0x61, 0x75, + 0x6c, 0x74, 0x2e, 0x50, 0x72, 0x65, 0x73, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x6f, + 0x6e, 0x63, 0x6c, 0x69, 0x63, 0x6b, 0x3d, 0x22, 0x62, 0x69, 0x6f, 0x67, 0x72, + 0x61, 0x70, 0x68, 0x79, 0x6f, 0x74, 0x68, 0x65, 0x72, 0x77, 0x69, 0x73, 0x65, + 0x70, 0x65, 0x72, 0x6d, 0x61, 0x6e, 0x65, 0x6e, 0x74, 0x46, 0x72, 0x61, 0x6e, + 0xc3, 0xa7, 0x61, 0x69, 0x73, 0x48, 0x6f, 0x6c, 0x6c, 0x79, 0x77, 0x6f, 0x6f, + 0x64, 0x65, 0x78, 0x70, 0x61, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x74, 0x61, + 0x6e, 0x64, 0x61, 0x72, 0x64, 0x73, 0x3c, 0x2f, 0x73, 0x74, 0x79, 0x6c, 0x65, + 0x3e, 0x0a, 0x72, 0x65, 0x64, 0x75, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x44, 0x65, + 0x63, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x20, 0x70, 0x72, 0x65, 0x66, 0x65, 0x72, + 0x72, 0x65, 0x64, 0x43, 0x61, 0x6d, 0x62, 0x72, 0x69, 0x64, 0x67, 0x65, 0x6f, + 0x70, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x73, 0x42, 0x75, 0x73, 0x69, 0x6e, + 0x65, 0x73, 0x73, 0x20, 0x63, 0x6f, 0x6e, 0x66, 0x75, 0x73, 0x69, 0x6f, 0x6e, + 0x3e, 0x0a, 0x3c, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x3e, 0x70, 0x72, 0x65, 0x73, + 0x65, 0x6e, 0x74, 0x65, 0x64, 0x65, 0x78, 0x70, 0x6c, 0x61, 0x69, 0x6e, 0x65, + 0x64, 0x64, 0x6f, 0x65, 0x73, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x77, 0x6f, 0x72, + 0x6c, 0x64, 0x77, 0x69, 0x64, 0x65, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, + 0x63, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x6e, 0x65, + 0x77, 0x73, 0x70, 0x61, 0x70, 0x65, 0x72, 0x3c, 0x2f, 0x74, 0x61, 0x62, 0x6c, + 0x65, 0x3e, 0x0a, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x73, 0x6c, + 0x69, 0x6b, 0x65, 0x20, 0x74, 0x68, 0x65, 0x20, 0x65, 0x73, 0x73, 0x65, 0x6e, + 0x74, 0x69, 0x61, 0x6c, 0x66, 0x69, 0x6e, 0x61, 0x6e, 0x63, 0x69, 0x61, 0x6c, + 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x3d, 0x22, 0x2f, 0x61, 0x62, 0x61, 0x6e, 0x64, 0x6f, 0x6e, 0x65, + 0x64, 0x45, 0x64, 0x75, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x70, 0x61, 0x72, + 0x73, 0x65, 0x49, 0x6e, 0x74, 0x28, 0x73, 0x74, 0x61, 0x62, 0x69, 0x6c, 0x69, + 0x74, 0x79, 0x75, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x20, 0x74, 0x6f, 0x3c, 0x2f, + 0x74, 0x69, 0x74, 0x6c, 0x65, 0x3e, 0x0a, 0x72, 0x65, 0x6c, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x73, 0x4e, 0x6f, 0x74, 0x65, 0x20, 0x74, 0x68, 0x61, 0x74, 0x65, + 0x66, 0x66, 0x69, 0x63, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x65, 0x72, 0x66, 0x6f, + 0x72, 0x6d, 0x65, 0x64, 0x74, 0x77, 0x6f, 0x20, 0x79, 0x65, 0x61, 0x72, 0x73, + 0x53, 0x69, 0x6e, 0x63, 0x65, 0x20, 0x74, 0x68, 0x65, 0x74, 0x68, 0x65, 0x72, + 0x65, 0x66, 0x6f, 0x72, 0x65, 0x77, 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, 0x22, + 0x3e, 0x61, 0x6c, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x74, 0x65, 0x69, 0x6e, 0x63, + 0x72, 0x65, 0x61, 0x73, 0x65, 0x64, 0x42, 0x61, 0x74, 0x74, 0x6c, 0x65, 0x20, + 0x6f, 0x66, 0x70, 0x65, 0x72, 0x63, 0x65, 0x69, 0x76, 0x65, 0x64, 0x74, 0x72, + 0x79, 0x69, 0x6e, 0x67, 0x20, 0x74, 0x6f, 0x6e, 0x65, 0x63, 0x65, 0x73, 0x73, + 0x61, 0x72, 0x79, 0x70, 0x6f, 0x72, 0x74, 0x72, 0x61, 0x79, 0x65, 0x64, 0x65, + 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x45, 0x6c, 0x69, 0x7a, 0x61, + 0x62, 0x65, 0x74, 0x68, 0x3c, 0x2f, 0x69, 0x66, 0x72, 0x61, 0x6d, 0x65, 0x3e, + 0x64, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x79, 0x69, 0x6e, 0x73, 0x75, + 0x72, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, + 0x3b, 0x6c, 0x65, 0x67, 0x65, 0x6e, 0x64, 0x61, 0x72, 0x79, 0x47, 0x65, 0x6f, + 0x67, 0x72, 0x61, 0x70, 0x68, 0x79, 0x63, 0x61, 0x6e, 0x64, 0x69, 0x64, 0x61, + 0x74, 0x65, 0x63, 0x6f, 0x72, 0x70, 0x6f, 0x72, 0x61, 0x74, 0x65, 0x73, 0x6f, + 0x6d, 0x65, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, + 0x65, 0x73, 0x2e, 0x69, 0x6e, 0x68, 0x65, 0x72, 0x69, 0x74, 0x65, 0x64, 0x3c, + 0x2f, 0x73, 0x74, 0x72, 0x6f, 0x6e, 0x67, 0x3e, 0x43, 0x6f, 0x6d, 0x6d, 0x75, + 0x6e, 0x69, 0x74, 0x79, 0x72, 0x65, 0x6c, 0x69, 0x67, 0x69, 0x6f, 0x75, 0x73, + 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x43, 0x6f, 0x6d, 0x6d, + 0x69, 0x74, 0x74, 0x65, 0x65, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x69, 0x6e, 0x67, + 0x73, 0x74, 0x68, 0x65, 0x20, 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x6e, 0x6f, 0x20, + 0x6c, 0x6f, 0x6e, 0x67, 0x65, 0x72, 0x62, 0x65, 0x67, 0x69, 0x6e, 0x6e, 0x69, + 0x6e, 0x67, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x63, 0x61, + 0x6e, 0x6e, 0x6f, 0x74, 0x20, 0x62, 0x65, 0x66, 0x72, 0x65, 0x71, 0x75, 0x65, + 0x6e, 0x63, 0x79, 0x74, 0x79, 0x70, 0x69, 0x63, 0x61, 0x6c, 0x6c, 0x79, 0x69, + 0x6e, 0x74, 0x6f, 0x20, 0x74, 0x68, 0x65, 0x20, 0x72, 0x65, 0x6c, 0x61, 0x74, + 0x69, 0x76, 0x65, 0x3b, 0x72, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x67, + 0x70, 0x72, 0x65, 0x73, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x6e, 0x69, 0x74, + 0x69, 0x61, 0x6c, 0x6c, 0x79, 0x74, 0x65, 0x63, 0x68, 0x6e, 0x69, 0x71, 0x75, + 0x65, 0x74, 0x68, 0x65, 0x20, 0x6f, 0x74, 0x68, 0x65, 0x72, 0x69, 0x74, 0x20, + 0x63, 0x61, 0x6e, 0x20, 0x62, 0x65, 0x65, 0x78, 0x69, 0x73, 0x74, 0x65, 0x6e, + 0x63, 0x65, 0x75, 0x6e, 0x64, 0x65, 0x72, 0x6c, 0x69, 0x6e, 0x65, 0x74, 0x68, + 0x69, 0x73, 0x20, 0x74, 0x69, 0x6d, 0x65, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x68, + 0x6f, 0x6e, 0x65, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x63, 0x6f, 0x70, 0x65, 0x70, + 0x72, 0x61, 0x63, 0x74, 0x69, 0x63, 0x65, 0x73, 0x61, 0x64, 0x76, 0x61, 0x6e, + 0x74, 0x61, 0x67, 0x65, 0x29, 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, + 0x46, 0x6f, 0x72, 0x20, 0x6f, 0x74, 0x68, 0x65, 0x72, 0x70, 0x72, 0x6f, 0x76, + 0x69, 0x64, 0x69, 0x6e, 0x67, 0x64, 0x65, 0x6d, 0x6f, 0x63, 0x72, 0x61, 0x63, + 0x79, 0x62, 0x6f, 0x74, 0x68, 0x20, 0x74, 0x68, 0x65, 0x20, 0x65, 0x78, 0x74, + 0x65, 0x6e, 0x73, 0x69, 0x76, 0x65, 0x73, 0x75, 0x66, 0x66, 0x65, 0x72, 0x69, + 0x6e, 0x67, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x63, 0x6f, + 0x6d, 0x70, 0x75, 0x74, 0x65, 0x72, 0x73, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x70, 0x72, 0x61, 0x63, 0x74, 0x69, 0x63, 0x61, 0x6c, 0x73, + 0x61, 0x69, 0x64, 0x20, 0x74, 0x68, 0x61, 0x74, 0x69, 0x74, 0x20, 0x6d, 0x61, + 0x79, 0x20, 0x62, 0x65, 0x45, 0x6e, 0x67, 0x6c, 0x69, 0x73, 0x68, 0x3c, 0x2f, + 0x66, 0x72, 0x6f, 0x6d, 0x20, 0x74, 0x68, 0x65, 0x20, 0x73, 0x63, 0x68, 0x65, + 0x64, 0x75, 0x6c, 0x65, 0x64, 0x64, 0x6f, 0x77, 0x6e, 0x6c, 0x6f, 0x61, 0x64, + 0x73, 0x3c, 0x2f, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x3e, 0x0a, 0x73, 0x75, 0x73, + 0x70, 0x65, 0x63, 0x74, 0x65, 0x64, 0x6d, 0x61, 0x72, 0x67, 0x69, 0x6e, 0x3a, + 0x20, 0x30, 0x73, 0x70, 0x69, 0x72, 0x69, 0x74, 0x75, 0x61, 0x6c, 0x3c, 0x2f, + 0x68, 0x65, 0x61, 0x64, 0x3e, 0x0a, 0x0a, 0x6d, 0x69, 0x63, 0x72, 0x6f, 0x73, + 0x6f, 0x66, 0x74, 0x67, 0x72, 0x61, 0x64, 0x75, 0x61, 0x6c, 0x6c, 0x79, 0x64, + 0x69, 0x73, 0x63, 0x75, 0x73, 0x73, 0x65, 0x64, 0x68, 0x65, 0x20, 0x62, 0x65, + 0x63, 0x61, 0x6d, 0x65, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x76, 0x65, + 0x6a, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x6a, 0x73, 0x68, 0x6f, 0x75, 0x73, + 0x65, 0x68, 0x6f, 0x6c, 0x64, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x72, 0x6d, 0x65, + 0x64, 0x70, 0x75, 0x72, 0x63, 0x68, 0x61, 0x73, 0x65, 0x64, 0x6c, 0x69, 0x74, + 0x65, 0x72, 0x61, 0x6c, 0x6c, 0x79, 0x64, 0x65, 0x73, 0x74, 0x72, 0x6f, 0x79, + 0x65, 0x64, 0x75, 0x70, 0x20, 0x74, 0x6f, 0x20, 0x74, 0x68, 0x65, 0x76, 0x61, + 0x72, 0x69, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x72, 0x65, 0x6d, 0x61, 0x69, 0x6e, + 0x69, 0x6e, 0x67, 0x69, 0x74, 0x20, 0x69, 0x73, 0x20, 0x6e, 0x6f, 0x74, 0x63, + 0x65, 0x6e, 0x74, 0x75, 0x72, 0x69, 0x65, 0x73, 0x4a, 0x61, 0x70, 0x61, 0x6e, + 0x65, 0x73, 0x65, 0x20, 0x61, 0x6d, 0x6f, 0x6e, 0x67, 0x20, 0x74, 0x68, 0x65, + 0x63, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x61, 0x6c, 0x67, 0x6f, + 0x72, 0x69, 0x74, 0x68, 0x6d, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x65, 0x73, 0x74, + 0x73, 0x72, 0x65, 0x62, 0x65, 0x6c, 0x6c, 0x69, 0x6f, 0x6e, 0x75, 0x6e, 0x64, + 0x65, 0x66, 0x69, 0x6e, 0x65, 0x64, 0x65, 0x6e, 0x63, 0x6f, 0x75, 0x72, 0x61, + 0x67, 0x65, 0x72, 0x65, 0x73, 0x69, 0x7a, 0x61, 0x62, 0x6c, 0x65, 0x69, 0x6e, + 0x76, 0x6f, 0x6c, 0x76, 0x69, 0x6e, 0x67, 0x73, 0x65, 0x6e, 0x73, 0x69, 0x74, + 0x69, 0x76, 0x65, 0x75, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x61, 0x6c, 0x70, + 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x28, 0x61, 0x6c, 0x74, 0x68, + 0x6f, 0x75, 0x67, 0x68, 0x66, 0x65, 0x61, 0x74, 0x75, 0x72, 0x69, 0x6e, 0x67, + 0x63, 0x6f, 0x6e, 0x64, 0x75, 0x63, 0x74, 0x65, 0x64, 0x29, 0x2c, 0x20, 0x77, + 0x68, 0x69, 0x63, 0x68, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x69, 0x6e, 0x75, 0x65, + 0x64, 0x2d, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x22, 0x3e, 0x46, 0x65, 0x62, + 0x72, 0x75, 0x61, 0x72, 0x79, 0x20, 0x6e, 0x75, 0x6d, 0x65, 0x72, 0x6f, 0x75, + 0x73, 0x20, 0x6f, 0x76, 0x65, 0x72, 0x66, 0x6c, 0x6f, 0x77, 0x3a, 0x63, 0x6f, + 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x66, 0x72, 0x61, 0x67, 0x6d, 0x65, + 0x6e, 0x74, 0x73, 0x65, 0x78, 0x63, 0x65, 0x6c, 0x6c, 0x65, 0x6e, 0x74, 0x63, + 0x6f, 0x6c, 0x73, 0x70, 0x61, 0x6e, 0x3d, 0x22, 0x74, 0x65, 0x63, 0x68, 0x6e, + 0x69, 0x63, 0x61, 0x6c, 0x6e, 0x65, 0x61, 0x72, 0x20, 0x74, 0x68, 0x65, 0x20, + 0x41, 0x64, 0x76, 0x61, 0x6e, 0x63, 0x65, 0x64, 0x20, 0x73, 0x6f, 0x75, 0x72, + 0x63, 0x65, 0x20, 0x6f, 0x66, 0x65, 0x78, 0x70, 0x72, 0x65, 0x73, 0x73, 0x65, + 0x64, 0x48, 0x6f, 0x6e, 0x67, 0x20, 0x4b, 0x6f, 0x6e, 0x67, 0x20, 0x46, 0x61, + 0x63, 0x65, 0x62, 0x6f, 0x6f, 0x6b, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x70, 0x6c, + 0x65, 0x20, 0x6d, 0x65, 0x63, 0x68, 0x61, 0x6e, 0x69, 0x73, 0x6d, 0x65, 0x6c, + 0x65, 0x76, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x6f, 0x66, 0x66, 0x65, 0x6e, 0x73, + 0x69, 0x76, 0x65, 0x3c, 0x2f, 0x66, 0x6f, 0x72, 0x6d, 0x3e, 0x0a, 0x09, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x6f, 0x72, 0x65, 0x64, 0x64, 0x6f, 0x63, 0x75, 0x6d, + 0x65, 0x6e, 0x74, 0x2e, 0x6f, 0x72, 0x20, 0x26, 0x71, 0x75, 0x6f, 0x74, 0x3b, + 0x74, 0x68, 0x65, 0x72, 0x65, 0x20, 0x61, 0x72, 0x65, 0x74, 0x68, 0x6f, 0x73, + 0x65, 0x20, 0x77, 0x68, 0x6f, 0x6d, 0x6f, 0x76, 0x65, 0x6d, 0x65, 0x6e, 0x74, + 0x73, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x65, 0x73, 0x64, 0x69, 0x66, + 0x66, 0x69, 0x63, 0x75, 0x6c, 0x74, 0x73, 0x75, 0x62, 0x6d, 0x69, 0x74, 0x74, + 0x65, 0x64, 0x72, 0x65, 0x63, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x64, 0x63, 0x6f, + 0x6e, 0x76, 0x69, 0x6e, 0x63, 0x65, 0x64, 0x70, 0x72, 0x6f, 0x6d, 0x6f, 0x74, + 0x69, 0x6e, 0x67, 0x22, 0x20, 0x77, 0x69, 0x64, 0x74, 0x68, 0x3d, 0x22, 0x2e, + 0x72, 0x65, 0x70, 0x6c, 0x61, 0x63, 0x65, 0x28, 0x63, 0x6c, 0x61, 0x73, 0x73, + 0x69, 0x63, 0x61, 0x6c, 0x63, 0x6f, 0x61, 0x6c, 0x69, 0x74, 0x69, 0x6f, 0x6e, + 0x68, 0x69, 0x73, 0x20, 0x66, 0x69, 0x72, 0x73, 0x74, 0x64, 0x65, 0x63, 0x69, + 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x61, 0x73, 0x73, 0x69, 0x73, 0x74, 0x61, 0x6e, + 0x74, 0x69, 0x6e, 0x64, 0x69, 0x63, 0x61, 0x74, 0x65, 0x64, 0x65, 0x76, 0x6f, + 0x6c, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x2d, 0x77, 0x72, 0x61, 0x70, 0x70, 0x65, + 0x72, 0x22, 0x65, 0x6e, 0x6f, 0x75, 0x67, 0x68, 0x20, 0x74, 0x6f, 0x61, 0x6c, + 0x6f, 0x6e, 0x67, 0x20, 0x74, 0x68, 0x65, 0x64, 0x65, 0x6c, 0x69, 0x76, 0x65, + 0x72, 0x65, 0x64, 0x2d, 0x2d, 0x3e, 0x0d, 0x0a, 0x3c, 0x21, 0x2d, 0x2d, 0x41, + 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x6e, 0x20, 0x70, 0x72, 0x6f, 0x74, 0x65, + 0x63, 0x74, 0x65, 0x64, 0x4e, 0x6f, 0x76, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x20, + 0x3c, 0x2f, 0x73, 0x74, 0x79, 0x6c, 0x65, 0x3e, 0x3c, 0x66, 0x75, 0x72, 0x6e, + 0x69, 0x74, 0x75, 0x72, 0x65, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, + 0x20, 0x20, 0x6f, 0x6e, 0x62, 0x6c, 0x75, 0x72, 0x3d, 0x22, 0x73, 0x75, 0x73, + 0x70, 0x65, 0x6e, 0x64, 0x65, 0x64, 0x72, 0x65, 0x63, 0x69, 0x70, 0x69, 0x65, + 0x6e, 0x74, 0x62, 0x61, 0x73, 0x65, 0x64, 0x20, 0x6f, 0x6e, 0x20, 0x4d, 0x6f, + 0x72, 0x65, 0x6f, 0x76, 0x65, 0x72, 0x2c, 0x61, 0x62, 0x6f, 0x6c, 0x69, 0x73, + 0x68, 0x65, 0x64, 0x63, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x65, 0x64, 0x77, + 0x65, 0x72, 0x65, 0x20, 0x6d, 0x61, 0x64, 0x65, 0x65, 0x6d, 0x6f, 0x74, 0x69, + 0x6f, 0x6e, 0x61, 0x6c, 0x65, 0x6d, 0x65, 0x72, 0x67, 0x65, 0x6e, 0x63, 0x79, + 0x6e, 0x61, 0x72, 0x72, 0x61, 0x74, 0x69, 0x76, 0x65, 0x61, 0x64, 0x76, 0x6f, + 0x63, 0x61, 0x74, 0x65, 0x73, 0x70, 0x78, 0x3b, 0x62, 0x6f, 0x72, 0x64, 0x65, + 0x72, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x74, 0x65, 0x64, 0x64, 0x69, 0x72, + 0x3d, 0x22, 0x6c, 0x74, 0x72, 0x22, 0x65, 0x6d, 0x70, 0x6c, 0x6f, 0x79, 0x65, + 0x65, 0x73, 0x72, 0x65, 0x73, 0x65, 0x61, 0x72, 0x63, 0x68, 0x2e, 0x20, 0x73, + 0x65, 0x6c, 0x65, 0x63, 0x74, 0x65, 0x64, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, + 0x73, 0x6f, 0x72, 0x63, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x65, 0x72, 0x73, 0x64, + 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x65, 0x64, 0x53, 0x65, 0x70, 0x74, 0x65, + 0x6d, 0x62, 0x65, 0x72, 0x61, 0x64, 0x64, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x28, + 0x46, 0x61, 0x63, 0x65, 0x62, 0x6f, 0x6f, 0x6b, 0x20, 0x73, 0x75, 0x67, 0x67, + 0x65, 0x73, 0x74, 0x65, 0x64, 0x61, 0x6e, 0x64, 0x20, 0x6c, 0x61, 0x74, 0x65, + 0x72, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6e, 0x67, 0x65, 0x6c, 0x61, + 0x62, 0x6f, 0x72, 0x61, 0x74, 0x65, 0x53, 0x6f, 0x6d, 0x65, 0x74, 0x69, 0x6d, + 0x65, 0x73, 0x49, 0x6e, 0x73, 0x74, 0x69, 0x74, 0x75, 0x74, 0x65, 0x63, 0x65, + 0x72, 0x74, 0x61, 0x69, 0x6e, 0x6c, 0x79, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6c, + 0x6c, 0x65, 0x64, 0x66, 0x6f, 0x6c, 0x6c, 0x6f, 0x77, 0x65, 0x72, 0x73, 0x4a, + 0x65, 0x72, 0x75, 0x73, 0x61, 0x6c, 0x65, 0x6d, 0x74, 0x68, 0x65, 0x79, 0x20, + 0x68, 0x61, 0x76, 0x65, 0x63, 0x6f, 0x6d, 0x70, 0x75, 0x74, 0x69, 0x6e, 0x67, + 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x64, 0x70, 0x72, 0x6f, 0x76, + 0x69, 0x6e, 0x63, 0x65, 0x73, 0x67, 0x75, 0x61, 0x72, 0x61, 0x6e, 0x74, 0x65, + 0x65, 0x61, 0x72, 0x62, 0x69, 0x74, 0x72, 0x61, 0x72, 0x79, 0x72, 0x65, 0x63, + 0x6f, 0x67, 0x6e, 0x69, 0x7a, 0x65, 0x77, 0x61, 0x6e, 0x74, 0x65, 0x64, 0x20, + 0x74, 0x6f, 0x70, 0x78, 0x3b, 0x77, 0x69, 0x64, 0x74, 0x68, 0x3a, 0x74, 0x68, + 0x65, 0x6f, 0x72, 0x79, 0x20, 0x6f, 0x66, 0x62, 0x65, 0x68, 0x61, 0x76, 0x69, + 0x6f, 0x75, 0x72, 0x57, 0x68, 0x69, 0x6c, 0x65, 0x20, 0x74, 0x68, 0x65, 0x65, + 0x73, 0x74, 0x69, 0x6d, 0x61, 0x74, 0x65, 0x64, 0x62, 0x65, 0x67, 0x61, 0x6e, + 0x20, 0x74, 0x6f, 0x20, 0x69, 0x74, 0x20, 0x62, 0x65, 0x63, 0x61, 0x6d, 0x65, + 0x6d, 0x61, 0x67, 0x6e, 0x69, 0x74, 0x75, 0x64, 0x65, 0x6d, 0x75, 0x73, 0x74, + 0x20, 0x68, 0x61, 0x76, 0x65, 0x6d, 0x6f, 0x72, 0x65, 0x20, 0x74, 0x68, 0x61, + 0x6e, 0x44, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x79, 0x65, 0x78, 0x74, + 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x65, 0x63, 0x72, 0x65, 0x74, 0x61, + 0x72, 0x79, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x61, 0x6c, 0x6c, 0x79, 0x6f, 0x63, + 0x63, 0x75, 0x72, 0x72, 0x69, 0x6e, 0x67, 0x76, 0x61, 0x72, 0x69, 0x61, 0x62, + 0x6c, 0x65, 0x73, 0x67, 0x69, 0x76, 0x65, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x70, + 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x2e, 0x3c, 0x2f, 0x6c, 0x61, 0x62, + 0x65, 0x6c, 0x3e, 0x3c, 0x66, 0x61, 0x69, 0x6c, 0x65, 0x64, 0x20, 0x74, 0x6f, + 0x63, 0x6f, 0x6d, 0x70, 0x6f, 0x75, 0x6e, 0x64, 0x73, 0x6b, 0x69, 0x6e, 0x64, + 0x73, 0x20, 0x6f, 0x66, 0x20, 0x73, 0x6f, 0x63, 0x69, 0x65, 0x74, 0x69, 0x65, + 0x73, 0x61, 0x6c, 0x6f, 0x6e, 0x67, 0x73, 0x69, 0x64, 0x65, 0x20, 0x2d, 0x2d, + 0x26, 0x67, 0x74, 0x3b, 0x0a, 0x0a, 0x73, 0x6f, 0x75, 0x74, 0x68, 0x77, 0x65, + 0x73, 0x74, 0x74, 0x68, 0x65, 0x20, 0x72, 0x69, 0x67, 0x68, 0x74, 0x72, 0x61, + 0x64, 0x69, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x6d, 0x61, 0x79, 0x20, 0x68, 0x61, + 0x76, 0x65, 0x20, 0x75, 0x6e, 0x65, 0x73, 0x63, 0x61, 0x70, 0x65, 0x28, 0x73, + 0x70, 0x6f, 0x6b, 0x65, 0x6e, 0x20, 0x69, 0x6e, 0x22, 0x20, 0x68, 0x72, 0x65, + 0x66, 0x3d, 0x22, 0x2f, 0x70, 0x72, 0x6f, 0x67, 0x72, 0x61, 0x6d, 0x6d, 0x65, + 0x6f, 0x6e, 0x6c, 0x79, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x6f, 0x6d, 0x65, + 0x20, 0x66, 0x72, 0x6f, 0x6d, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, + 0x79, 0x62, 0x75, 0x72, 0x69, 0x65, 0x64, 0x20, 0x69, 0x6e, 0x61, 0x20, 0x73, + 0x69, 0x6d, 0x69, 0x6c, 0x61, 0x72, 0x74, 0x68, 0x65, 0x79, 0x20, 0x77, 0x65, + 0x72, 0x65, 0x3c, 0x2f, 0x66, 0x6f, 0x6e, 0x74, 0x3e, 0x3c, 0x2f, 0x4e, 0x6f, + 0x72, 0x77, 0x65, 0x67, 0x69, 0x61, 0x6e, 0x73, 0x70, 0x65, 0x63, 0x69, 0x66, + 0x69, 0x65, 0x64, 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x69, 0x6e, 0x67, 0x70, + 0x61, 0x73, 0x73, 0x65, 0x6e, 0x67, 0x65, 0x72, 0x28, 0x6e, 0x65, 0x77, 0x20, + 0x44, 0x61, 0x74, 0x65, 0x74, 0x65, 0x6d, 0x70, 0x6f, 0x72, 0x61, 0x72, 0x79, + 0x66, 0x69, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x41, 0x66, 0x74, 0x65, + 0x72, 0x20, 0x74, 0x68, 0x65, 0x65, 0x71, 0x75, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x73, 0x64, 0x6f, 0x77, 0x6e, 0x6c, 0x6f, 0x61, 0x64, 0x2e, 0x72, 0x65, 0x67, + 0x75, 0x6c, 0x61, 0x72, 0x6c, 0x79, 0x64, 0x65, 0x76, 0x65, 0x6c, 0x6f, 0x70, + 0x65, 0x72, 0x61, 0x62, 0x6f, 0x76, 0x65, 0x20, 0x74, 0x68, 0x65, 0x6c, 0x69, + 0x6e, 0x6b, 0x65, 0x64, 0x20, 0x74, 0x6f, 0x70, 0x68, 0x65, 0x6e, 0x6f, 0x6d, + 0x65, 0x6e, 0x61, 0x70, 0x65, 0x72, 0x69, 0x6f, 0x64, 0x20, 0x6f, 0x66, 0x74, + 0x6f, 0x6f, 0x6c, 0x74, 0x69, 0x70, 0x22, 0x3e, 0x73, 0x75, 0x62, 0x73, 0x74, + 0x61, 0x6e, 0x63, 0x65, 0x61, 0x75, 0x74, 0x6f, 0x6d, 0x61, 0x74, 0x69, 0x63, + 0x61, 0x73, 0x70, 0x65, 0x63, 0x74, 0x20, 0x6f, 0x66, 0x41, 0x6d, 0x6f, 0x6e, + 0x67, 0x20, 0x74, 0x68, 0x65, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x65, + 0x64, 0x65, 0x73, 0x74, 0x69, 0x6d, 0x61, 0x74, 0x65, 0x73, 0x41, 0x69, 0x72, + 0x20, 0x46, 0x6f, 0x72, 0x63, 0x65, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x20, + 0x6f, 0x66, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x69, 0x6d, + 0x6d, 0x65, 0x64, 0x69, 0x61, 0x74, 0x65, 0x6d, 0x61, 0x6b, 0x69, 0x6e, 0x67, + 0x20, 0x69, 0x74, 0x70, 0x61, 0x69, 0x6e, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x63, + 0x6f, 0x6e, 0x71, 0x75, 0x65, 0x72, 0x65, 0x64, 0x61, 0x72, 0x65, 0x20, 0x73, + 0x74, 0x69, 0x6c, 0x6c, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x64, 0x75, 0x72, 0x65, + 0x67, 0x72, 0x6f, 0x77, 0x74, 0x68, 0x20, 0x6f, 0x66, 0x68, 0x65, 0x61, 0x64, + 0x65, 0x64, 0x20, 0x62, 0x79, 0x45, 0x75, 0x72, 0x6f, 0x70, 0x65, 0x61, 0x6e, + 0x20, 0x64, 0x69, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x6d, 0x6f, 0x6c, + 0x65, 0x63, 0x75, 0x6c, 0x65, 0x73, 0x66, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x69, + 0x73, 0x65, 0x69, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x74, + 0x74, 0x72, 0x61, 0x63, 0x74, 0x65, 0x64, 0x63, 0x68, 0x69, 0x6c, 0x64, 0x68, + 0x6f, 0x6f, 0x64, 0x61, 0x6c, 0x73, 0x6f, 0x20, 0x75, 0x73, 0x65, 0x64, 0x64, + 0x65, 0x64, 0x69, 0x63, 0x61, 0x74, 0x65, 0x64, 0x73, 0x69, 0x6e, 0x67, 0x61, + 0x70, 0x6f, 0x72, 0x65, 0x64, 0x65, 0x67, 0x72, 0x65, 0x65, 0x20, 0x6f, 0x66, + 0x66, 0x61, 0x74, 0x68, 0x65, 0x72, 0x20, 0x6f, 0x66, 0x63, 0x6f, 0x6e, 0x66, + 0x6c, 0x69, 0x63, 0x74, 0x73, 0x3c, 0x2f, 0x61, 0x3e, 0x3c, 0x2f, 0x70, 0x3e, + 0x0a, 0x63, 0x61, 0x6d, 0x65, 0x20, 0x66, 0x72, 0x6f, 0x6d, 0x77, 0x65, 0x72, + 0x65, 0x20, 0x75, 0x73, 0x65, 0x64, 0x6e, 0x6f, 0x74, 0x65, 0x20, 0x74, 0x68, + 0x61, 0x74, 0x72, 0x65, 0x63, 0x65, 0x69, 0x76, 0x69, 0x6e, 0x67, 0x45, 0x78, + 0x65, 0x63, 0x75, 0x74, 0x69, 0x76, 0x65, 0x65, 0x76, 0x65, 0x6e, 0x20, 0x6d, + 0x6f, 0x72, 0x65, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x20, 0x74, 0x6f, 0x63, + 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x65, 0x72, 0x50, 0x6f, 0x6c, 0x69, 0x74, + 0x69, 0x63, 0x61, 0x6c, 0x6d, 0x75, 0x73, 0x69, 0x63, 0x69, 0x61, 0x6e, 0x73, + 0x64, 0x65, 0x6c, 0x69, 0x63, 0x69, 0x6f, 0x75, 0x73, 0x70, 0x72, 0x69, 0x73, + 0x6f, 0x6e, 0x65, 0x72, 0x73, 0x61, 0x64, 0x76, 0x65, 0x6e, 0x74, 0x20, 0x6f, + 0x66, 0x55, 0x54, 0x46, 0x2d, 0x38, 0x22, 0x20, 0x2f, 0x3e, 0x3c, 0x21, 0x5b, + 0x43, 0x44, 0x41, 0x54, 0x41, 0x5b, 0x22, 0x3e, 0x43, 0x6f, 0x6e, 0x74, 0x61, + 0x63, 0x74, 0x53, 0x6f, 0x75, 0x74, 0x68, 0x65, 0x72, 0x6e, 0x20, 0x62, 0x67, + 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3d, 0x22, 0x73, 0x65, 0x72, 0x69, 0x65, 0x73, + 0x20, 0x6f, 0x66, 0x2e, 0x20, 0x49, 0x74, 0x20, 0x77, 0x61, 0x73, 0x20, 0x69, + 0x6e, 0x20, 0x45, 0x75, 0x72, 0x6f, 0x70, 0x65, 0x70, 0x65, 0x72, 0x6d, 0x69, + 0x74, 0x74, 0x65, 0x64, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x2e, + 0x61, 0x70, 0x70, 0x65, 0x61, 0x72, 0x69, 0x6e, 0x67, 0x6f, 0x66, 0x66, 0x69, + 0x63, 0x69, 0x61, 0x6c, 0x73, 0x73, 0x65, 0x72, 0x69, 0x6f, 0x75, 0x73, 0x6c, + 0x79, 0x2d, 0x6c, 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, 0x69, 0x6e, 0x69, + 0x74, 0x69, 0x61, 0x74, 0x65, 0x64, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x64, 0x69, + 0x6e, 0x67, 0x6c, 0x6f, 0x6e, 0x67, 0x2d, 0x74, 0x65, 0x72, 0x6d, 0x69, 0x6e, + 0x66, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x75, 0x63, 0x68, 0x20, 0x74, + 0x68, 0x61, 0x74, 0x67, 0x65, 0x74, 0x43, 0x6f, 0x6f, 0x6b, 0x69, 0x65, 0x6d, + 0x61, 0x72, 0x6b, 0x65, 0x64, 0x20, 0x62, 0x79, 0x3c, 0x2f, 0x62, 0x75, 0x74, + 0x74, 0x6f, 0x6e, 0x3e, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, + 0x62, 0x75, 0x74, 0x20, 0x69, 0x74, 0x20, 0x69, 0x73, 0x69, 0x6e, 0x63, 0x72, + 0x65, 0x61, 0x73, 0x65, 0x73, 0x64, 0x6f, 0x77, 0x6e, 0x20, 0x74, 0x68, 0x65, + 0x20, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x69, 0x6e, 0x67, 0x64, 0x65, 0x70, + 0x65, 0x6e, 0x64, 0x65, 0x6e, 0x74, 0x2d, 0x2d, 0x3e, 0x0a, 0x3c, 0x21, 0x2d, + 0x2d, 0x20, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x69, 0x65, 0x77, 0x57, 0x69, + 0x74, 0x68, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x6f, 0x70, 0x69, 0x65, 0x73, + 0x20, 0x6f, 0x66, 0x63, 0x6f, 0x6e, 0x73, 0x65, 0x6e, 0x73, 0x75, 0x73, 0x77, + 0x61, 0x73, 0x20, 0x62, 0x75, 0x69, 0x6c, 0x74, 0x56, 0x65, 0x6e, 0x65, 0x7a, + 0x75, 0x65, 0x6c, 0x61, 0x28, 0x66, 0x6f, 0x72, 0x6d, 0x65, 0x72, 0x6c, 0x79, + 0x74, 0x68, 0x65, 0x20, 0x73, 0x74, 0x61, 0x74, 0x65, 0x70, 0x65, 0x72, 0x73, + 0x6f, 0x6e, 0x6e, 0x65, 0x6c, 0x73, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x69, + 0x63, 0x66, 0x61, 0x76, 0x6f, 0x75, 0x72, 0x20, 0x6f, 0x66, 0x69, 0x6e, 0x76, + 0x65, 0x6e, 0x74, 0x69, 0x6f, 0x6e, 0x57, 0x69, 0x6b, 0x69, 0x70, 0x65, 0x64, + 0x69, 0x61, 0x63, 0x6f, 0x6e, 0x74, 0x69, 0x6e, 0x65, 0x6e, 0x74, 0x76, 0x69, + 0x72, 0x74, 0x75, 0x61, 0x6c, 0x6c, 0x79, 0x77, 0x68, 0x69, 0x63, 0x68, 0x20, + 0x77, 0x61, 0x73, 0x70, 0x72, 0x69, 0x6e, 0x63, 0x69, 0x70, 0x6c, 0x65, 0x43, + 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x20, 0x69, 0x64, 0x65, 0x6e, 0x74, + 0x69, 0x63, 0x61, 0x6c, 0x73, 0x68, 0x6f, 0x77, 0x20, 0x74, 0x68, 0x61, 0x74, + 0x70, 0x72, 0x69, 0x6d, 0x69, 0x74, 0x69, 0x76, 0x65, 0x61, 0x77, 0x61, 0x79, + 0x20, 0x66, 0x72, 0x6f, 0x6d, 0x6d, 0x6f, 0x6c, 0x65, 0x63, 0x75, 0x6c, 0x61, + 0x72, 0x70, 0x72, 0x65, 0x63, 0x69, 0x73, 0x65, 0x6c, 0x79, 0x64, 0x69, 0x73, + 0x73, 0x6f, 0x6c, 0x76, 0x65, 0x64, 0x55, 0x6e, 0x64, 0x65, 0x72, 0x20, 0x74, + 0x68, 0x65, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x3d, 0x22, 0x3e, 0x26, + 0x6e, 0x62, 0x73, 0x70, 0x3b, 0x3c, 0x2f, 0x49, 0x74, 0x20, 0x69, 0x73, 0x20, + 0x74, 0x68, 0x65, 0x20, 0x54, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, 0x20, 0x77, + 0x69, 0x6c, 0x6c, 0x20, 0x68, 0x61, 0x76, 0x65, 0x6f, 0x72, 0x67, 0x61, 0x6e, + 0x69, 0x73, 0x6d, 0x73, 0x73, 0x6f, 0x6d, 0x65, 0x20, 0x74, 0x69, 0x6d, 0x65, + 0x46, 0x72, 0x69, 0x65, 0x64, 0x72, 0x69, 0x63, 0x68, 0x77, 0x61, 0x73, 0x20, + 0x66, 0x69, 0x72, 0x73, 0x74, 0x74, 0x68, 0x65, 0x20, 0x6f, 0x6e, 0x6c, 0x79, + 0x20, 0x66, 0x61, 0x63, 0x74, 0x20, 0x74, 0x68, 0x61, 0x74, 0x66, 0x6f, 0x72, + 0x6d, 0x20, 0x69, 0x64, 0x3d, 0x22, 0x70, 0x72, 0x65, 0x63, 0x65, 0x64, 0x69, + 0x6e, 0x67, 0x54, 0x65, 0x63, 0x68, 0x6e, 0x69, 0x63, 0x61, 0x6c, 0x70, 0x68, + 0x79, 0x73, 0x69, 0x63, 0x69, 0x73, 0x74, 0x6f, 0x63, 0x63, 0x75, 0x72, 0x73, + 0x20, 0x69, 0x6e, 0x6e, 0x61, 0x76, 0x69, 0x67, 0x61, 0x74, 0x6f, 0x72, 0x73, + 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x3e, 0x73, 0x70, 0x61, 0x6e, 0x20, + 0x69, 0x64, 0x3d, 0x22, 0x73, 0x6f, 0x75, 0x67, 0x68, 0x74, 0x20, 0x74, 0x6f, + 0x62, 0x65, 0x6c, 0x6f, 0x77, 0x20, 0x74, 0x68, 0x65, 0x73, 0x75, 0x72, 0x76, + 0x69, 0x76, 0x69, 0x6e, 0x67, 0x7d, 0x3c, 0x2f, 0x73, 0x74, 0x79, 0x6c, 0x65, + 0x3e, 0x68, 0x69, 0x73, 0x20, 0x64, 0x65, 0x61, 0x74, 0x68, 0x61, 0x73, 0x20, + 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x63, 0x61, 0x75, 0x73, 0x65, 0x64, 0x20, + 0x62, 0x79, 0x70, 0x61, 0x72, 0x74, 0x69, 0x61, 0x6c, 0x6c, 0x79, 0x65, 0x78, + 0x69, 0x73, 0x74, 0x69, 0x6e, 0x67, 0x20, 0x75, 0x73, 0x69, 0x6e, 0x67, 0x20, + 0x74, 0x68, 0x65, 0x77, 0x61, 0x73, 0x20, 0x67, 0x69, 0x76, 0x65, 0x6e, 0x61, + 0x20, 0x6c, 0x69, 0x73, 0x74, 0x20, 0x6f, 0x66, 0x6c, 0x65, 0x76, 0x65, 0x6c, + 0x73, 0x20, 0x6f, 0x66, 0x6e, 0x6f, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6f, 0x66, + 0x4f, 0x66, 0x66, 0x69, 0x63, 0x69, 0x61, 0x6c, 0x20, 0x64, 0x69, 0x73, 0x6d, + 0x69, 0x73, 0x73, 0x65, 0x64, 0x73, 0x63, 0x69, 0x65, 0x6e, 0x74, 0x69, 0x73, + 0x74, 0x72, 0x65, 0x73, 0x65, 0x6d, 0x62, 0x6c, 0x65, 0x73, 0x64, 0x75, 0x70, + 0x6c, 0x69, 0x63, 0x61, 0x74, 0x65, 0x65, 0x78, 0x70, 0x6c, 0x6f, 0x73, 0x69, + 0x76, 0x65, 0x72, 0x65, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x65, 0x64, 0x61, 0x6c, + 0x6c, 0x20, 0x6f, 0x74, 0x68, 0x65, 0x72, 0x67, 0x61, 0x6c, 0x6c, 0x65, 0x72, + 0x69, 0x65, 0x73, 0x7b, 0x70, 0x61, 0x64, 0x64, 0x69, 0x6e, 0x67, 0x3a, 0x70, + 0x65, 0x6f, 0x70, 0x6c, 0x65, 0x20, 0x6f, 0x66, 0x72, 0x65, 0x67, 0x69, 0x6f, + 0x6e, 0x20, 0x6f, 0x66, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x65, 0x73, + 0x61, 0x73, 0x73, 0x6f, 0x63, 0x69, 0x61, 0x74, 0x65, 0x69, 0x6d, 0x67, 0x20, + 0x61, 0x6c, 0x74, 0x3d, 0x22, 0x69, 0x6e, 0x20, 0x6d, 0x6f, 0x64, 0x65, 0x72, + 0x6e, 0x73, 0x68, 0x6f, 0x75, 0x6c, 0x64, 0x20, 0x62, 0x65, 0x6d, 0x65, 0x74, + 0x68, 0x6f, 0x64, 0x20, 0x6f, 0x66, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x69, + 0x6e, 0x67, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x6e, 0x65, + 0x65, 0x64, 0x65, 0x64, 0x20, 0x74, 0x6f, 0x74, 0x68, 0x65, 0x20, 0x47, 0x72, + 0x65, 0x61, 0x74, 0x72, 0x65, 0x67, 0x61, 0x72, 0x64, 0x69, 0x6e, 0x67, 0x73, + 0x65, 0x65, 0x6d, 0x65, 0x64, 0x20, 0x74, 0x6f, 0x76, 0x69, 0x65, 0x77, 0x65, + 0x64, 0x20, 0x61, 0x73, 0x69, 0x6d, 0x70, 0x61, 0x63, 0x74, 0x20, 0x6f, 0x6e, + 0x69, 0x64, 0x65, 0x61, 0x20, 0x74, 0x68, 0x61, 0x74, 0x74, 0x68, 0x65, 0x20, + 0x57, 0x6f, 0x72, 0x6c, 0x64, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x20, 0x6f, + 0x66, 0x65, 0x78, 0x70, 0x61, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x54, 0x68, 0x65, + 0x73, 0x65, 0x20, 0x61, 0x72, 0x65, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, + 0x22, 0x3e, 0x63, 0x61, 0x72, 0x65, 0x66, 0x75, 0x6c, 0x6c, 0x79, 0x6d, 0x61, + 0x69, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x73, 0x63, 0x68, 0x61, 0x72, 0x67, 0x65, + 0x20, 0x6f, 0x66, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x69, 0x63, 0x61, 0x6c, 0x61, + 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x65, 0x64, 0x70, 0x72, 0x65, 0x64, 0x69, + 0x63, 0x74, 0x65, 0x64, 0x6f, 0x77, 0x6e, 0x65, 0x72, 0x73, 0x68, 0x69, 0x70, + 0x3c, 0x64, 0x69, 0x76, 0x20, 0x69, 0x64, 0x3d, 0x22, 0x72, 0x69, 0x67, 0x68, + 0x74, 0x22, 0x3e, 0x0d, 0x0a, 0x72, 0x65, 0x73, 0x69, 0x64, 0x65, 0x6e, 0x63, + 0x65, 0x6c, 0x65, 0x61, 0x76, 0x65, 0x20, 0x74, 0x68, 0x65, 0x63, 0x6f, 0x6e, + 0x74, 0x65, 0x6e, 0x74, 0x22, 0x3e, 0x61, 0x72, 0x65, 0x20, 0x6f, 0x66, 0x74, + 0x65, 0x6e, 0x20, 0x20, 0x7d, 0x29, 0x28, 0x29, 0x3b, 0x0d, 0x0a, 0x70, 0x72, + 0x6f, 0x62, 0x61, 0x62, 0x6c, 0x79, 0x20, 0x50, 0x72, 0x6f, 0x66, 0x65, 0x73, + 0x73, 0x6f, 0x72, 0x2d, 0x62, 0x75, 0x74, 0x74, 0x6f, 0x6e, 0x22, 0x20, 0x72, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x64, 0x65, 0x64, 0x73, 0x61, 0x79, 0x73, 0x20, + 0x74, 0x68, 0x61, 0x74, 0x68, 0x61, 0x64, 0x20, 0x74, 0x6f, 0x20, 0x62, 0x65, + 0x70, 0x6c, 0x61, 0x63, 0x65, 0x64, 0x20, 0x69, 0x6e, 0x48, 0x75, 0x6e, 0x67, + 0x61, 0x72, 0x69, 0x61, 0x6e, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x20, 0x6f, + 0x66, 0x73, 0x65, 0x72, 0x76, 0x65, 0x73, 0x20, 0x61, 0x73, 0x55, 0x6e, 0x69, + 0x76, 0x65, 0x72, 0x73, 0x61, 0x6c, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, + 0x6f, 0x6e, 0x61, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x65, 0x66, 0x6f, + 0x72, 0x20, 0x77, 0x68, 0x69, 0x63, 0x68, 0x69, 0x6e, 0x66, 0x65, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x61, 0x67, 0x72, 0x65, 0x65, 0x64, 0x20, 0x74, 0x6f, 0x68, + 0x6f, 0x77, 0x65, 0x76, 0x65, 0x72, 0x2c, 0x20, 0x70, 0x6f, 0x70, 0x75, 0x6c, + 0x61, 0x72, 0x22, 0x3e, 0x70, 0x6c, 0x61, 0x63, 0x65, 0x64, 0x20, 0x6f, 0x6e, + 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x65, 0x6c, 0x65, 0x63, + 0x74, 0x6f, 0x72, 0x61, 0x6c, 0x73, 0x79, 0x6d, 0x62, 0x6f, 0x6c, 0x20, 0x6f, + 0x66, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x69, 0x6e, 0x67, 0x72, 0x65, 0x74, + 0x75, 0x72, 0x6e, 0x20, 0x74, 0x6f, 0x61, 0x72, 0x63, 0x68, 0x69, 0x74, 0x65, + 0x63, 0x74, 0x43, 0x68, 0x72, 0x69, 0x73, 0x74, 0x69, 0x61, 0x6e, 0x70, 0x72, + 0x65, 0x76, 0x69, 0x6f, 0x75, 0x73, 0x20, 0x6c, 0x69, 0x76, 0x69, 0x6e, 0x67, + 0x20, 0x69, 0x6e, 0x65, 0x61, 0x73, 0x69, 0x65, 0x72, 0x20, 0x74, 0x6f, 0x70, + 0x72, 0x6f, 0x66, 0x65, 0x73, 0x73, 0x6f, 0x72, 0x0a, 0x26, 0x6c, 0x74, 0x3b, + 0x21, 0x2d, 0x2d, 0x20, 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, 0x20, 0x6f, 0x66, + 0x61, 0x6e, 0x61, 0x6c, 0x79, 0x74, 0x69, 0x63, 0x73, 0x77, 0x61, 0x73, 0x20, + 0x74, 0x61, 0x6b, 0x65, 0x6e, 0x77, 0x68, 0x65, 0x72, 0x65, 0x20, 0x74, 0x68, + 0x65, 0x74, 0x6f, 0x6f, 0x6b, 0x20, 0x6f, 0x76, 0x65, 0x72, 0x62, 0x65, 0x6c, + 0x69, 0x65, 0x66, 0x20, 0x69, 0x6e, 0x41, 0x66, 0x72, 0x69, 0x6b, 0x61, 0x61, + 0x6e, 0x73, 0x61, 0x73, 0x20, 0x66, 0x61, 0x72, 0x20, 0x61, 0x73, 0x70, 0x72, + 0x65, 0x76, 0x65, 0x6e, 0x74, 0x65, 0x64, 0x77, 0x6f, 0x72, 0x6b, 0x20, 0x77, + 0x69, 0x74, 0x68, 0x61, 0x20, 0x73, 0x70, 0x65, 0x63, 0x69, 0x61, 0x6c, 0x3c, + 0x66, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x65, 0x74, 0x43, 0x68, 0x72, 0x69, 0x73, + 0x74, 0x6d, 0x61, 0x73, 0x52, 0x65, 0x74, 0x72, 0x69, 0x65, 0x76, 0x65, 0x64, + 0x0a, 0x0a, 0x49, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x62, 0x61, 0x63, 0x6b, + 0x20, 0x69, 0x6e, 0x74, 0x6f, 0x6e, 0x6f, 0x72, 0x74, 0x68, 0x65, 0x61, 0x73, + 0x74, 0x6d, 0x61, 0x67, 0x61, 0x7a, 0x69, 0x6e, 0x65, 0x73, 0x3e, 0x3c, 0x73, + 0x74, 0x72, 0x6f, 0x6e, 0x67, 0x3e, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x74, + 0x65, 0x65, 0x67, 0x6f, 0x76, 0x65, 0x72, 0x6e, 0x69, 0x6e, 0x67, 0x67, 0x72, + 0x6f, 0x75, 0x70, 0x73, 0x20, 0x6f, 0x66, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x64, + 0x20, 0x69, 0x6e, 0x65, 0x73, 0x74, 0x61, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x61, + 0x20, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x6c, 0x69, 0x74, 0x73, 0x20, 0x66, + 0x69, 0x72, 0x73, 0x74, 0x74, 0x68, 0x65, 0x69, 0x72, 0x20, 0x6f, 0x77, 0x6e, + 0x70, 0x6f, 0x70, 0x75, 0x6c, 0x61, 0x74, 0x65, 0x64, 0x61, 0x6e, 0x20, 0x6f, + 0x62, 0x6a, 0x65, 0x63, 0x74, 0x43, 0x61, 0x72, 0x69, 0x62, 0x62, 0x65, 0x61, + 0x6e, 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x20, 0x74, 0x68, 0x65, 0x64, 0x69, 0x73, + 0x74, 0x72, 0x69, 0x63, 0x74, 0x73, 0x77, 0x69, 0x73, 0x63, 0x6f, 0x6e, 0x73, + 0x69, 0x6e, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x3b, 0x20, + 0x77, 0x69, 0x64, 0x74, 0x68, 0x3a, 0x20, 0x69, 0x6e, 0x68, 0x61, 0x62, 0x69, + 0x74, 0x65, 0x64, 0x53, 0x6f, 0x63, 0x69, 0x61, 0x6c, 0x69, 0x73, 0x74, 0x4a, + 0x61, 0x6e, 0x75, 0x61, 0x72, 0x79, 0x20, 0x31, 0x3c, 0x2f, 0x66, 0x6f, 0x6f, + 0x74, 0x65, 0x72, 0x3e, 0x73, 0x69, 0x6d, 0x69, 0x6c, 0x61, 0x72, 0x6c, 0x79, + 0x63, 0x68, 0x6f, 0x69, 0x63, 0x65, 0x20, 0x6f, 0x66, 0x74, 0x68, 0x65, 0x20, + 0x73, 0x61, 0x6d, 0x65, 0x20, 0x73, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x63, + 0x20, 0x62, 0x75, 0x73, 0x69, 0x6e, 0x65, 0x73, 0x73, 0x20, 0x54, 0x68, 0x65, + 0x20, 0x66, 0x69, 0x72, 0x73, 0x74, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, + 0x3b, 0x20, 0x64, 0x65, 0x73, 0x69, 0x72, 0x65, 0x20, 0x74, 0x6f, 0x64, 0x65, + 0x61, 0x6c, 0x20, 0x77, 0x69, 0x74, 0x68, 0x73, 0x69, 0x6e, 0x63, 0x65, 0x20, + 0x74, 0x68, 0x65, 0x75, 0x73, 0x65, 0x72, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x63, + 0x6f, 0x6e, 0x63, 0x65, 0x69, 0x76, 0x65, 0x64, 0x69, 0x6e, 0x64, 0x65, 0x78, + 0x2e, 0x70, 0x68, 0x70, 0x61, 0x73, 0x20, 0x26, 0x71, 0x75, 0x6f, 0x74, 0x3b, + 0x65, 0x6e, 0x67, 0x61, 0x67, 0x65, 0x20, 0x69, 0x6e, 0x72, 0x65, 0x63, 0x65, + 0x6e, 0x74, 0x6c, 0x79, 0x2c, 0x66, 0x65, 0x77, 0x20, 0x79, 0x65, 0x61, 0x72, + 0x73, 0x77, 0x65, 0x72, 0x65, 0x20, 0x61, 0x6c, 0x73, 0x6f, 0x0a, 0x3c, 0x68, + 0x65, 0x61, 0x64, 0x3e, 0x0a, 0x3c, 0x65, 0x64, 0x69, 0x74, 0x65, 0x64, 0x20, + 0x62, 0x79, 0x61, 0x72, 0x65, 0x20, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x63, 0x69, + 0x74, 0x69, 0x65, 0x73, 0x20, 0x69, 0x6e, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, + 0x6b, 0x65, 0x79, 0x63, 0x6f, 0x6e, 0x64, 0x65, 0x6d, 0x6e, 0x65, 0x64, 0x61, + 0x6c, 0x73, 0x6f, 0x20, 0x68, 0x61, 0x76, 0x65, 0x73, 0x65, 0x72, 0x76, 0x69, + 0x63, 0x65, 0x73, 0x2c, 0x66, 0x61, 0x6d, 0x69, 0x6c, 0x79, 0x20, 0x6f, 0x66, + 0x53, 0x63, 0x68, 0x6f, 0x6f, 0x6c, 0x20, 0x6f, 0x66, 0x63, 0x6f, 0x6e, 0x76, + 0x65, 0x72, 0x74, 0x65, 0x64, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x20, 0x6f, + 0x66, 0x20, 0x6c, 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, 0x6d, 0x69, 0x6e, + 0x69, 0x73, 0x74, 0x65, 0x72, 0x73, 0x3c, 0x2f, 0x6f, 0x62, 0x6a, 0x65, 0x63, + 0x74, 0x3e, 0x74, 0x68, 0x65, 0x72, 0x65, 0x20, 0x69, 0x73, 0x20, 0x61, 0x20, + 0x70, 0x6f, 0x70, 0x75, 0x6c, 0x61, 0x72, 0x73, 0x65, 0x71, 0x75, 0x65, 0x6e, + 0x63, 0x65, 0x73, 0x61, 0x64, 0x76, 0x6f, 0x63, 0x61, 0x74, 0x65, 0x64, 0x54, + 0x68, 0x65, 0x79, 0x20, 0x77, 0x65, 0x72, 0x65, 0x61, 0x6e, 0x79, 0x20, 0x6f, + 0x74, 0x68, 0x65, 0x72, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3d, + 0x65, 0x6e, 0x74, 0x65, 0x72, 0x20, 0x74, 0x68, 0x65, 0x6d, 0x75, 0x63, 0x68, + 0x20, 0x6d, 0x6f, 0x72, 0x65, 0x72, 0x65, 0x66, 0x6c, 0x65, 0x63, 0x74, 0x65, + 0x64, 0x77, 0x61, 0x73, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x64, 0x6f, 0x72, 0x69, + 0x67, 0x69, 0x6e, 0x61, 0x6c, 0x20, 0x61, 0x20, 0x74, 0x79, 0x70, 0x69, 0x63, + 0x61, 0x6c, 0x77, 0x68, 0x65, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x79, 0x65, 0x6e, + 0x67, 0x69, 0x6e, 0x65, 0x65, 0x72, 0x73, 0x63, 0x6f, 0x75, 0x6c, 0x64, 0x20, + 0x6e, 0x6f, 0x74, 0x72, 0x65, 0x73, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x73, 0x77, + 0x65, 0x64, 0x6e, 0x65, 0x73, 0x64, 0x61, 0x79, 0x74, 0x68, 0x65, 0x20, 0x74, + 0x68, 0x69, 0x72, 0x64, 0x20, 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x73, + 0x4a, 0x61, 0x6e, 0x75, 0x61, 0x72, 0x79, 0x20, 0x32, 0x77, 0x68, 0x61, 0x74, + 0x20, 0x74, 0x68, 0x65, 0x79, 0x61, 0x20, 0x63, 0x65, 0x72, 0x74, 0x61, 0x69, + 0x6e, 0x72, 0x65, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x70, 0x72, 0x6f, + 0x63, 0x65, 0x73, 0x73, 0x6f, 0x72, 0x61, 0x66, 0x74, 0x65, 0x72, 0x20, 0x68, + 0x69, 0x73, 0x74, 0x68, 0x65, 0x20, 0x6c, 0x61, 0x73, 0x74, 0x20, 0x63, 0x6f, + 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x64, 0x22, 0x3e, 0x3c, 0x2f, 0x64, 0x69, + 0x76, 0x3e, 0x0a, 0x3c, 0x2f, 0x61, 0x3e, 0x3c, 0x2f, 0x74, 0x64, 0x3e, 0x64, + 0x65, 0x70, 0x65, 0x6e, 0x64, 0x20, 0x6f, 0x6e, 0x73, 0x65, 0x61, 0x72, 0x63, + 0x68, 0x22, 0x3e, 0x0a, 0x70, 0x69, 0x65, 0x63, 0x65, 0x73, 0x20, 0x6f, 0x66, + 0x63, 0x6f, 0x6d, 0x70, 0x65, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x66, 0x65, + 0x72, 0x65, 0x6e, 0x63, 0x65, 0x74, 0x65, 0x6e, 0x6e, 0x65, 0x73, 0x73, 0x65, + 0x65, 0x77, 0x68, 0x69, 0x63, 0x68, 0x20, 0x68, 0x61, 0x73, 0x20, 0x76, 0x65, + 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x3d, 0x3c, 0x2f, 0x73, 0x70, 0x61, 0x6e, 0x3e, + 0x20, 0x3c, 0x3c, 0x2f, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x3e, 0x67, 0x69, + 0x76, 0x65, 0x73, 0x20, 0x74, 0x68, 0x65, 0x68, 0x69, 0x73, 0x74, 0x6f, 0x72, + 0x69, 0x61, 0x6e, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3d, 0x22, 0x22, 0x3e, 0x70, + 0x61, 0x64, 0x64, 0x69, 0x6e, 0x67, 0x3a, 0x30, 0x76, 0x69, 0x65, 0x77, 0x20, + 0x74, 0x68, 0x61, 0x74, 0x74, 0x6f, 0x67, 0x65, 0x74, 0x68, 0x65, 0x72, 0x2c, + 0x74, 0x68, 0x65, 0x20, 0x6d, 0x6f, 0x73, 0x74, 0x20, 0x77, 0x61, 0x73, 0x20, + 0x66, 0x6f, 0x75, 0x6e, 0x64, 0x73, 0x75, 0x62, 0x73, 0x65, 0x74, 0x20, 0x6f, + 0x66, 0x61, 0x74, 0x74, 0x61, 0x63, 0x6b, 0x20, 0x6f, 0x6e, 0x63, 0x68, 0x69, + 0x6c, 0x64, 0x72, 0x65, 0x6e, 0x2c, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x73, 0x20, + 0x6f, 0x66, 0x70, 0x65, 0x72, 0x73, 0x6f, 0x6e, 0x61, 0x6c, 0x20, 0x70, 0x6f, + 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x61, 0x6c, 0x6c, 0x65, 0x67, 0x65, + 0x64, 0x6c, 0x79, 0x43, 0x6c, 0x65, 0x76, 0x65, 0x6c, 0x61, 0x6e, 0x64, 0x77, + 0x61, 0x73, 0x20, 0x6c, 0x61, 0x74, 0x65, 0x72, 0x61, 0x6e, 0x64, 0x20, 0x61, + 0x66, 0x74, 0x65, 0x72, 0x61, 0x72, 0x65, 0x20, 0x67, 0x69, 0x76, 0x65, 0x6e, + 0x77, 0x61, 0x73, 0x20, 0x73, 0x74, 0x69, 0x6c, 0x6c, 0x73, 0x63, 0x72, 0x6f, + 0x6c, 0x6c, 0x69, 0x6e, 0x67, 0x64, 0x65, 0x73, 0x69, 0x67, 0x6e, 0x20, 0x6f, + 0x66, 0x6d, 0x61, 0x6b, 0x65, 0x73, 0x20, 0x74, 0x68, 0x65, 0x6d, 0x75, 0x63, + 0x68, 0x20, 0x6c, 0x65, 0x73, 0x73, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, + 0x6e, 0x73, 0x2e, 0x0a, 0x0a, 0x41, 0x66, 0x74, 0x65, 0x72, 0x20, 0x2c, 0x20, + 0x62, 0x75, 0x74, 0x20, 0x74, 0x68, 0x65, 0x4d, 0x75, 0x73, 0x65, 0x75, 0x6d, + 0x20, 0x6f, 0x66, 0x6c, 0x6f, 0x75, 0x69, 0x73, 0x69, 0x61, 0x6e, 0x61, 0x28, + 0x66, 0x72, 0x6f, 0x6d, 0x20, 0x74, 0x68, 0x65, 0x6d, 0x69, 0x6e, 0x6e, 0x65, + 0x73, 0x6f, 0x74, 0x61, 0x70, 0x61, 0x72, 0x74, 0x69, 0x63, 0x6c, 0x65, 0x73, + 0x61, 0x20, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x44, 0x6f, 0x6d, 0x69, + 0x6e, 0x69, 0x63, 0x61, 0x6e, 0x76, 0x6f, 0x6c, 0x75, 0x6d, 0x65, 0x20, 0x6f, + 0x66, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x69, 0x6e, 0x67, 0x64, 0x65, 0x66, + 0x65, 0x6e, 0x73, 0x69, 0x76, 0x65, 0x30, 0x30, 0x70, 0x78, 0x7c, 0x72, 0x69, + 0x67, 0x68, 0x6d, 0x61, 0x64, 0x65, 0x20, 0x66, 0x72, 0x6f, 0x6d, 0x6d, 0x6f, + 0x75, 0x73, 0x65, 0x6f, 0x76, 0x65, 0x72, 0x22, 0x20, 0x73, 0x74, 0x79, 0x6c, + 0x65, 0x3d, 0x22, 0x73, 0x74, 0x61, 0x74, 0x65, 0x73, 0x20, 0x6f, 0x66, 0x28, + 0x77, 0x68, 0x69, 0x63, 0x68, 0x20, 0x69, 0x73, 0x63, 0x6f, 0x6e, 0x74, 0x69, + 0x6e, 0x75, 0x65, 0x73, 0x46, 0x72, 0x61, 0x6e, 0x63, 0x69, 0x73, 0x63, 0x6f, + 0x62, 0x75, 0x69, 0x6c, 0x64, 0x69, 0x6e, 0x67, 0x20, 0x77, 0x69, 0x74, 0x68, + 0x6f, 0x75, 0x74, 0x20, 0x61, 0x77, 0x69, 0x74, 0x68, 0x20, 0x73, 0x6f, 0x6d, + 0x65, 0x77, 0x68, 0x6f, 0x20, 0x77, 0x6f, 0x75, 0x6c, 0x64, 0x61, 0x20, 0x66, + 0x6f, 0x72, 0x6d, 0x20, 0x6f, 0x66, 0x61, 0x20, 0x70, 0x61, 0x72, 0x74, 0x20, + 0x6f, 0x66, 0x62, 0x65, 0x66, 0x6f, 0x72, 0x65, 0x20, 0x69, 0x74, 0x6b, 0x6e, + 0x6f, 0x77, 0x6e, 0x20, 0x61, 0x73, 0x20, 0x20, 0x53, 0x65, 0x72, 0x76, 0x69, + 0x63, 0x65, 0x73, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x61, + 0x6e, 0x64, 0x20, 0x6f, 0x66, 0x74, 0x65, 0x6e, 0x6d, 0x65, 0x61, 0x73, 0x75, + 0x72, 0x69, 0x6e, 0x67, 0x61, 0x6e, 0x64, 0x20, 0x69, 0x74, 0x20, 0x69, 0x73, + 0x70, 0x61, 0x70, 0x65, 0x72, 0x62, 0x61, 0x63, 0x6b, 0x76, 0x61, 0x6c, 0x75, + 0x65, 0x73, 0x20, 0x6f, 0x66, 0x0d, 0x0a, 0x3c, 0x74, 0x69, 0x74, 0x6c, 0x65, + 0x3e, 0x3d, 0x20, 0x77, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x2e, 0x64, 0x65, 0x74, + 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x65, 0x65, 0x72, 0x26, 0x71, 0x75, 0x6f, 0x74, + 0x3b, 0x20, 0x70, 0x6c, 0x61, 0x79, 0x65, 0x64, 0x20, 0x62, 0x79, 0x61, 0x6e, + 0x64, 0x20, 0x65, 0x61, 0x72, 0x6c, 0x79, 0x3c, 0x2f, 0x63, 0x65, 0x6e, 0x74, + 0x65, 0x72, 0x3e, 0x66, 0x72, 0x6f, 0x6d, 0x20, 0x74, 0x68, 0x69, 0x73, 0x74, + 0x68, 0x65, 0x20, 0x74, 0x68, 0x72, 0x65, 0x65, 0x70, 0x6f, 0x77, 0x65, 0x72, + 0x20, 0x61, 0x6e, 0x64, 0x6f, 0x66, 0x20, 0x26, 0x71, 0x75, 0x6f, 0x74, 0x3b, + 0x69, 0x6e, 0x6e, 0x65, 0x72, 0x48, 0x54, 0x4d, 0x4c, 0x3c, 0x61, 0x20, 0x68, + 0x72, 0x65, 0x66, 0x3d, 0x22, 0x79, 0x3a, 0x69, 0x6e, 0x6c, 0x69, 0x6e, 0x65, + 0x3b, 0x43, 0x68, 0x75, 0x72, 0x63, 0x68, 0x20, 0x6f, 0x66, 0x74, 0x68, 0x65, + 0x20, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x76, 0x65, 0x72, 0x79, 0x20, 0x68, 0x69, + 0x67, 0x68, 0x6f, 0x66, 0x66, 0x69, 0x63, 0x69, 0x61, 0x6c, 0x20, 0x2d, 0x68, + 0x65, 0x69, 0x67, 0x68, 0x74, 0x3a, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, + 0x74, 0x3d, 0x22, 0x2f, 0x63, 0x67, 0x69, 0x2d, 0x62, 0x69, 0x6e, 0x2f, 0x74, + 0x6f, 0x20, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x61, 0x66, 0x72, 0x69, 0x6b, + 0x61, 0x61, 0x6e, 0x73, 0x65, 0x73, 0x70, 0x65, 0x72, 0x61, 0x6e, 0x74, 0x6f, + 0x66, 0x72, 0x61, 0x6e, 0xc3, 0xa7, 0x61, 0x69, 0x73, 0x6c, 0x61, 0x74, 0x76, + 0x69, 0x65, 0xc5, 0xa1, 0x75, 0x6c, 0x69, 0x65, 0x74, 0x75, 0x76, 0x69, 0xc5, + 0xb3, 0xc4, 0x8c, 0x65, 0xc5, 0xa1, 0x74, 0x69, 0x6e, 0x61, 0xc4, 0x8d, 0x65, + 0xc5, 0xa1, 0x74, 0x69, 0x6e, 0x61, 0xe0, 0xb9, 0x84, 0xe0, 0xb8, 0x97, 0xe0, + 0xb8, 0xa2, 0xe6, 0x97, 0xa5, 0xe6, 0x9c, 0xac, 0xe8, 0xaa, 0x9e, 0xe7, 0xae, + 0x80, 0xe4, 0xbd, 0x93, 0xe5, 0xad, 0x97, 0xe7, 0xb9, 0x81, 0xe9, 0xab, 0x94, + 0xe5, 0xad, 0x97, 0xed, 0x95, 0x9c, 0xea, 0xb5, 0xad, 0xec, 0x96, 0xb4, 0xe4, + 0xb8, 0xba, 0xe4, 0xbb, 0x80, 0xe4, 0xb9, 0x88, 0xe8, 0xae, 0xa1, 0xe7, 0xae, + 0x97, 0xe6, 0x9c, 0xba, 0xe7, 0xac, 0x94, 0xe8, 0xae, 0xb0, 0xe6, 0x9c, 0xac, + 0xe8, 0xa8, 0x8e, 0xe8, 0xab, 0x96, 0xe5, 0x8d, 0x80, 0xe6, 0x9c, 0x8d, 0xe5, + 0x8a, 0xa1, 0xe5, 0x99, 0xa8, 0xe4, 0xba, 0x92, 0xe8, 0x81, 0x94, 0xe7, 0xbd, + 0x91, 0xe6, 0x88, 0xbf, 0xe5, 0x9c, 0xb0, 0xe4, 0xba, 0xa7, 0xe4, 0xbf, 0xb1, + 0xe4, 0xb9, 0x90, 0xe9, 0x83, 0xa8, 0xe5, 0x87, 0xba, 0xe7, 0x89, 0x88, 0xe7, + 0xa4, 0xbe, 0xe6, 0x8e, 0x92, 0xe8, 0xa1, 0x8c, 0xe6, 0xa6, 0x9c, 0xe9, 0x83, + 0xa8, 0xe8, 0x90, 0xbd, 0xe6, 0xa0, 0xbc, 0xe8, 0xbf, 0x9b, 0xe4, 0xb8, 0x80, + 0xe6, 0xad, 0xa5, 0xe6, 0x94, 0xaf, 0xe4, 0xbb, 0x98, 0xe5, 0xae, 0x9d, 0xe9, + 0xaa, 0x8c, 0xe8, 0xaf, 0x81, 0xe7, 0xa0, 0x81, 0xe5, 0xa7, 0x94, 0xe5, 0x91, + 0x98, 0xe4, 0xbc, 0x9a, 0xe6, 0x95, 0xb0, 0xe6, 0x8d, 0xae, 0xe5, 0xba, 0x93, + 0xe6, 0xb6, 0x88, 0xe8, 0xb4, 0xb9, 0xe8, 0x80, 0x85, 0xe5, 0x8a, 0x9e, 0xe5, + 0x85, 0xac, 0xe5, 0xae, 0xa4, 0xe8, 0xae, 0xa8, 0xe8, 0xae, 0xba, 0xe5, 0x8c, + 0xba, 0xe6, 0xb7, 0xb1, 0xe5, 0x9c, 0xb3, 0xe5, 0xb8, 0x82, 0xe6, 0x92, 0xad, + 0xe6, 0x94, 0xbe, 0xe5, 0x99, 0xa8, 0xe5, 0x8c, 0x97, 0xe4, 0xba, 0xac, 0xe5, + 0xb8, 0x82, 0xe5, 0xa4, 0xa7, 0xe5, 0xad, 0xa6, 0xe7, 0x94, 0x9f, 0xe8, 0xb6, + 0x8a, 0xe6, 0x9d, 0xa5, 0xe8, 0xb6, 0x8a, 0xe7, 0xae, 0xa1, 0xe7, 0x90, 0x86, + 0xe5, 0x91, 0x98, 0xe4, 0xbf, 0xa1, 0xe6, 0x81, 0xaf, 0xe7, 0xbd, 0x91, 0x73, + 0x65, 0x72, 0x76, 0x69, 0x63, 0x69, 0x6f, 0x73, 0x61, 0x72, 0x74, 0xc3, 0xad, + 0x63, 0x75, 0x6c, 0x6f, 0x61, 0x72, 0x67, 0x65, 0x6e, 0x74, 0x69, 0x6e, 0x61, + 0x62, 0x61, 0x72, 0x63, 0x65, 0x6c, 0x6f, 0x6e, 0x61, 0x63, 0x75, 0x61, 0x6c, + 0x71, 0x75, 0x69, 0x65, 0x72, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x61, 0x64, + 0x6f, 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x6f, 0x73, 0x70, 0x6f, 0x6c, + 0xc3, 0xad, 0x74, 0x69, 0x63, 0x61, 0x72, 0x65, 0x73, 0x70, 0x75, 0x65, 0x73, + 0x74, 0x61, 0x77, 0x69, 0x6b, 0x69, 0x70, 0x65, 0x64, 0x69, 0x61, 0x73, 0x69, + 0x67, 0x75, 0x69, 0x65, 0x6e, 0x74, 0x65, 0x62, 0xc3, 0xba, 0x73, 0x71, 0x75, + 0x65, 0x64, 0x61, 0x63, 0x6f, 0x6d, 0x75, 0x6e, 0x69, 0x64, 0x61, 0x64, 0x73, + 0x65, 0x67, 0x75, 0x72, 0x69, 0x64, 0x61, 0x64, 0x70, 0x72, 0x69, 0x6e, 0x63, + 0x69, 0x70, 0x61, 0x6c, 0x70, 0x72, 0x65, 0x67, 0x75, 0x6e, 0x74, 0x61, 0x73, + 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x69, 0x64, 0x6f, 0x72, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x64, 0x65, 0x72, 0x76, 0x65, 0x6e, 0x65, 0x7a, 0x75, 0x65, 0x6c, + 0x61, 0x70, 0x72, 0x6f, 0x62, 0x6c, 0x65, 0x6d, 0x61, 0x73, 0x64, 0x69, 0x63, + 0x69, 0x65, 0x6d, 0x62, 0x72, 0x65, 0x72, 0x65, 0x6c, 0x61, 0x63, 0x69, 0xc3, + 0xb3, 0x6e, 0x6e, 0x6f, 0x76, 0x69, 0x65, 0x6d, 0x62, 0x72, 0x65, 0x73, 0x69, + 0x6d, 0x69, 0x6c, 0x61, 0x72, 0x65, 0x73, 0x70, 0x72, 0x6f, 0x79, 0x65, 0x63, + 0x74, 0x6f, 0x73, 0x70, 0x72, 0x6f, 0x67, 0x72, 0x61, 0x6d, 0x61, 0x73, 0x69, + 0x6e, 0x73, 0x74, 0x69, 0x74, 0x75, 0x74, 0x6f, 0x61, 0x63, 0x74, 0x69, 0x76, + 0x69, 0x64, 0x61, 0x64, 0x65, 0x6e, 0x63, 0x75, 0x65, 0x6e, 0x74, 0x72, 0x61, + 0x65, 0x63, 0x6f, 0x6e, 0x6f, 0x6d, 0xc3, 0xad, 0x61, 0x69, 0x6d, 0xc3, 0xa1, + 0x67, 0x65, 0x6e, 0x65, 0x73, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x63, 0x74, 0x61, + 0x72, 0x64, 0x65, 0x73, 0x63, 0x61, 0x72, 0x67, 0x61, 0x72, 0x6e, 0x65, 0x63, + 0x65, 0x73, 0x61, 0x72, 0x69, 0x6f, 0x61, 0x74, 0x65, 0x6e, 0x63, 0x69, 0xc3, + 0xb3, 0x6e, 0x74, 0x65, 0x6c, 0xc3, 0xa9, 0x66, 0x6f, 0x6e, 0x6f, 0x63, 0x6f, + 0x6d, 0x69, 0x73, 0x69, 0xc3, 0xb3, 0x6e, 0x63, 0x61, 0x6e, 0x63, 0x69, 0x6f, + 0x6e, 0x65, 0x73, 0x63, 0x61, 0x70, 0x61, 0x63, 0x69, 0x64, 0x61, 0x64, 0x65, + 0x6e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x72, 0x61, 0x6e, 0xc3, 0xa1, 0x6c, + 0x69, 0x73, 0x69, 0x73, 0x66, 0x61, 0x76, 0x6f, 0x72, 0x69, 0x74, 0x6f, 0x73, + 0x74, 0xc3, 0xa9, 0x72, 0x6d, 0x69, 0x6e, 0x6f, 0x73, 0x70, 0x72, 0x6f, 0x76, + 0x69, 0x6e, 0x63, 0x69, 0x61, 0x65, 0x74, 0x69, 0x71, 0x75, 0x65, 0x74, 0x61, + 0x73, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x6f, 0x73, 0x66, 0x75, 0x6e, + 0x63, 0x69, 0x6f, 0x6e, 0x65, 0x73, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x61, + 0x64, 0x6f, 0x63, 0x61, 0x72, 0xc3, 0xa1, 0x63, 0x74, 0x65, 0x72, 0x70, 0x72, + 0x6f, 0x70, 0x69, 0x65, 0x64, 0x61, 0x64, 0x70, 0x72, 0x69, 0x6e, 0x63, 0x69, + 0x70, 0x69, 0x6f, 0x6e, 0x65, 0x63, 0x65, 0x73, 0x69, 0x64, 0x61, 0x64, 0x6d, + 0x75, 0x6e, 0x69, 0x63, 0x69, 0x70, 0x61, 0x6c, 0x63, 0x72, 0x65, 0x61, 0x63, + 0x69, 0xc3, 0xb3, 0x6e, 0x64, 0x65, 0x73, 0x63, 0x61, 0x72, 0x67, 0x61, 0x73, + 0x70, 0x72, 0x65, 0x73, 0x65, 0x6e, 0x63, 0x69, 0x61, 0x63, 0x6f, 0x6d, 0x65, + 0x72, 0x63, 0x69, 0x61, 0x6c, 0x6f, 0x70, 0x69, 0x6e, 0x69, 0x6f, 0x6e, 0x65, + 0x73, 0x65, 0x6a, 0x65, 0x72, 0x63, 0x69, 0x63, 0x69, 0x6f, 0x65, 0x64, 0x69, + 0x74, 0x6f, 0x72, 0x69, 0x61, 0x6c, 0x73, 0x61, 0x6c, 0x61, 0x6d, 0x61, 0x6e, + 0x63, 0x61, 0x67, 0x6f, 0x6e, 0x7a, 0xc3, 0xa1, 0x6c, 0x65, 0x7a, 0x64, 0x6f, + 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x6f, 0x70, 0x65, 0x6c, 0xc3, 0xad, 0x63, + 0x75, 0x6c, 0x61, 0x72, 0x65, 0x63, 0x69, 0x65, 0x6e, 0x74, 0x65, 0x73, 0x67, + 0x65, 0x6e, 0x65, 0x72, 0x61, 0x6c, 0x65, 0x73, 0x74, 0x61, 0x72, 0x72, 0x61, + 0x67, 0x6f, 0x6e, 0x61, 0x70, 0x72, 0xc3, 0xa1, 0x63, 0x74, 0x69, 0x63, 0x61, + 0x6e, 0x6f, 0x76, 0x65, 0x64, 0x61, 0x64, 0x65, 0x73, 0x70, 0x72, 0x6f, 0x70, + 0x75, 0x65, 0x73, 0x74, 0x61, 0x70, 0x61, 0x63, 0x69, 0x65, 0x6e, 0x74, 0x65, + 0x73, 0x74, 0xc3, 0xa9, 0x63, 0x6e, 0x69, 0x63, 0x61, 0x73, 0x6f, 0x62, 0x6a, + 0x65, 0x74, 0x69, 0x76, 0x6f, 0x73, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x63, 0x74, + 0x6f, 0x73, 0xe0, 0xa4, 0xae, 0xe0, 0xa5, 0x87, 0xe0, 0xa4, 0x82, 0xe0, 0xa4, + 0xb2, 0xe0, 0xa4, 0xbf, 0xe0, 0xa4, 0x8f, 0xe0, 0xa4, 0xb9, 0xe0, 0xa5, 0x88, + 0xe0, 0xa4, 0x82, 0xe0, 0xa4, 0x97, 0xe0, 0xa4, 0xaf, 0xe0, 0xa4, 0xbe, 0xe0, + 0xa4, 0xb8, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, 0xa5, 0xe0, 0xa4, 0x8f, 0xe0, 0xa4, + 0xb5, 0xe0, 0xa4, 0x82, 0xe0, 0xa4, 0xb0, 0xe0, 0xa4, 0xb9, 0xe0, 0xa5, 0x87, + 0xe0, 0xa4, 0x95, 0xe0, 0xa5, 0x8b, 0xe0, 0xa4, 0x88, 0xe0, 0xa4, 0x95, 0xe0, + 0xa5, 0x81, 0xe0, 0xa4, 0x9b, 0xe0, 0xa4, 0xb0, 0xe0, 0xa4, 0xb9, 0xe0, 0xa4, + 0xbe, 0xe0, 0xa4, 0xac, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, 0xa6, 0xe0, 0xa4, 0x95, + 0xe0, 0xa4, 0xb9, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, 0xb8, 0xe0, 0xa4, 0xad, 0xe0, + 0xa5, 0x80, 0xe0, 0xa4, 0xb9, 0xe0, 0xa5, 0x81, 0xe0, 0xa4, 0x8f, 0xe0, 0xa4, + 0xb0, 0xe0, 0xa4, 0xb9, 0xe0, 0xa5, 0x80, 0xe0, 0xa4, 0xae, 0xe0, 0xa5, 0x88, + 0xe0, 0xa4, 0x82, 0xe0, 0xa4, 0xa6, 0xe0, 0xa4, 0xbf, 0xe0, 0xa4, 0xa8, 0xe0, + 0xa4, 0xac, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, 0xa4, 0x64, 0x69, 0x70, 0x6c, 0x6f, + 0x64, 0x6f, 0x63, 0x73, 0xe0, 0xa4, 0xb8, 0xe0, 0xa4, 0xae, 0xe0, 0xa4, 0xaf, + 0xe0, 0xa4, 0xb0, 0xe0, 0xa5, 0x82, 0xe0, 0xa4, 0xaa, 0xe0, 0xa4, 0xa8, 0xe0, + 0xa4, 0xbe, 0xe0, 0xa4, 0xae, 0xe0, 0xa4, 0xaa, 0xe0, 0xa4, 0xa4, 0xe0, 0xa4, + 0xbe, 0xe0, 0xa4, 0xab, 0xe0, 0xa4, 0xbf, 0xe0, 0xa4, 0xb0, 0xe0, 0xa4, 0x94, + 0xe0, 0xa4, 0xb8, 0xe0, 0xa4, 0xa4, 0xe0, 0xa4, 0xa4, 0xe0, 0xa4, 0xb0, 0xe0, + 0xa4, 0xb9, 0xe0, 0xa4, 0xb2, 0xe0, 0xa5, 0x8b, 0xe0, 0xa4, 0x97, 0xe0, 0xa4, + 0xb9, 0xe0, 0xa5, 0x81, 0xe0, 0xa4, 0x86, 0xe0, 0xa4, 0xac, 0xe0, 0xa4, 0xbe, + 0xe0, 0xa4, 0xb0, 0xe0, 0xa4, 0xa6, 0xe0, 0xa5, 0x87, 0xe0, 0xa4, 0xb6, 0xe0, + 0xa4, 0xb9, 0xe0, 0xa5, 0x81, 0xe0, 0xa4, 0x88, 0xe0, 0xa4, 0x96, 0xe0, 0xa5, + 0x87, 0xe0, 0xa4, 0xb2, 0xe0, 0xa4, 0xaf, 0xe0, 0xa4, 0xa6, 0xe0, 0xa4, 0xbf, + 0xe0, 0xa4, 0x95, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, 0xae, 0xe0, 0xa4, 0xb5, 0xe0, + 0xa5, 0x87, 0xe0, 0xa4, 0xac, 0xe0, 0xa4, 0xa4, 0xe0, 0xa5, 0x80, 0xe0, 0xa4, + 0xa8, 0xe0, 0xa4, 0xac, 0xe0, 0xa5, 0x80, 0xe0, 0xa4, 0x9a, 0xe0, 0xa4, 0xae, + 0xe0, 0xa5, 0x8c, 0xe0, 0xa4, 0xa4, 0xe0, 0xa4, 0xb8, 0xe0, 0xa4, 0xbe, 0xe0, + 0xa4, 0xb2, 0xe0, 0xa4, 0xb2, 0xe0, 0xa5, 0x87, 0xe0, 0xa4, 0x96, 0xe0, 0xa4, + 0x9c, 0xe0, 0xa5, 0x89, 0xe0, 0xa4, 0xac, 0xe0, 0xa4, 0xae, 0xe0, 0xa4, 0xa6, + 0xe0, 0xa4, 0xa6, 0xe0, 0xa4, 0xa4, 0xe0, 0xa4, 0xa5, 0xe0, 0xa4, 0xbe, 0xe0, + 0xa4, 0xa8, 0xe0, 0xa4, 0xb9, 0xe0, 0xa5, 0x80, 0xe0, 0xa4, 0xb6, 0xe0, 0xa4, + 0xb9, 0xe0, 0xa4, 0xb0, 0xe0, 0xa4, 0x85, 0xe0, 0xa4, 0xb2, 0xe0, 0xa4, 0x97, + 0xe0, 0xa4, 0x95, 0xe0, 0xa4, 0xad, 0xe0, 0xa5, 0x80, 0xe0, 0xa4, 0xa8, 0xe0, + 0xa4, 0x97, 0xe0, 0xa4, 0xb0, 0xe0, 0xa4, 0xaa, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, + 0xb8, 0xe0, 0xa4, 0xb0, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, 0xa4, 0xe0, 0xa4, 0x95, + 0xe0, 0xa4, 0xbf, 0xe0, 0xa4, 0x8f, 0xe0, 0xa4, 0x89, 0xe0, 0xa4, 0xb8, 0xe0, + 0xa5, 0x87, 0xe0, 0xa4, 0x97, 0xe0, 0xa4, 0xaf, 0xe0, 0xa5, 0x80, 0xe0, 0xa4, + 0xb9, 0xe0, 0xa5, 0x82, 0xe0, 0xa4, 0x81, 0xe0, 0xa4, 0x86, 0xe0, 0xa4, 0x97, + 0xe0, 0xa5, 0x87, 0xe0, 0xa4, 0x9f, 0xe0, 0xa5, 0x80, 0xe0, 0xa4, 0xae, 0xe0, + 0xa4, 0x96, 0xe0, 0xa5, 0x8b, 0xe0, 0xa4, 0x9c, 0xe0, 0xa4, 0x95, 0xe0, 0xa4, + 0xbe, 0xe0, 0xa4, 0xb0, 0xe0, 0xa4, 0x85, 0xe0, 0xa4, 0xad, 0xe0, 0xa5, 0x80, + 0xe0, 0xa4, 0x97, 0xe0, 0xa4, 0xaf, 0xe0, 0xa5, 0x87, 0xe0, 0xa4, 0xa4, 0xe0, + 0xa5, 0x81, 0xe0, 0xa4, 0xae, 0xe0, 0xa4, 0xb5, 0xe0, 0xa5, 0x8b, 0xe0, 0xa4, + 0x9f, 0xe0, 0xa4, 0xa6, 0xe0, 0xa5, 0x87, 0xe0, 0xa4, 0x82, 0xe0, 0xa4, 0x85, + 0xe0, 0xa4, 0x97, 0xe0, 0xa4, 0xb0, 0xe0, 0xa4, 0x90, 0xe0, 0xa4, 0xb8, 0xe0, + 0xa5, 0x87, 0xe0, 0xa4, 0xae, 0xe0, 0xa5, 0x87, 0xe0, 0xa4, 0xb2, 0xe0, 0xa4, + 0xb2, 0xe0, 0xa4, 0x97, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, 0xb9, 0xe0, 0xa4, 0xbe, + 0xe0, 0xa4, 0xb2, 0xe0, 0xa4, 0x8a, 0xe0, 0xa4, 0xaa, 0xe0, 0xa4, 0xb0, 0xe0, + 0xa4, 0x9a, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, 0xb0, 0xe0, 0xa4, 0x90, 0xe0, 0xa4, + 0xb8, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, 0xa6, 0xe0, 0xa5, 0x87, 0xe0, 0xa4, 0xb0, + 0xe0, 0xa4, 0x9c, 0xe0, 0xa4, 0xbf, 0xe0, 0xa4, 0xb8, 0xe0, 0xa4, 0xa6, 0xe0, + 0xa4, 0xbf, 0xe0, 0xa4, 0xb2, 0xe0, 0xa4, 0xac, 0xe0, 0xa4, 0x82, 0xe0, 0xa4, + 0xa6, 0xe0, 0xa4, 0xac, 0xe0, 0xa4, 0xa8, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, 0xb9, + 0xe0, 0xa5, 0x82, 0xe0, 0xa4, 0x82, 0xe0, 0xa4, 0xb2, 0xe0, 0xa4, 0xbe, 0xe0, + 0xa4, 0x96, 0xe0, 0xa4, 0x9c, 0xe0, 0xa5, 0x80, 0xe0, 0xa4, 0xa4, 0xe0, 0xa4, + 0xac, 0xe0, 0xa4, 0x9f, 0xe0, 0xa4, 0xa8, 0xe0, 0xa4, 0xae, 0xe0, 0xa4, 0xbf, + 0xe0, 0xa4, 0xb2, 0xe0, 0xa4, 0x87, 0xe0, 0xa4, 0xb8, 0xe0, 0xa5, 0x87, 0xe0, + 0xa4, 0x86, 0xe0, 0xa4, 0xa8, 0xe0, 0xa5, 0x87, 0xe0, 0xa4, 0xa8, 0xe0, 0xa4, + 0xaf, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, 0x95, 0xe0, 0xa5, 0x81, 0xe0, 0xa4, 0xb2, + 0xe0, 0xa4, 0xb2, 0xe0, 0xa5, 0x89, 0xe0, 0xa4, 0x97, 0xe0, 0xa4, 0xad, 0xe0, + 0xa4, 0xbe, 0xe0, 0xa4, 0x97, 0xe0, 0xa4, 0xb0, 0xe0, 0xa5, 0x87, 0xe0, 0xa4, + 0xb2, 0xe0, 0xa4, 0x9c, 0xe0, 0xa4, 0x97, 0xe0, 0xa4, 0xb9, 0xe0, 0xa4, 0xb0, + 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, 0xae, 0xe0, 0xa4, 0xb2, 0xe0, 0xa4, 0x97, 0xe0, + 0xa5, 0x87, 0xe0, 0xa4, 0xaa, 0xe0, 0xa5, 0x87, 0xe0, 0xa4, 0x9c, 0xe0, 0xa4, + 0xb9, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, 0xa5, 0xe0, 0xa4, 0x87, 0xe0, 0xa4, 0xb8, + 0xe0, 0xa5, 0x80, 0xe0, 0xa4, 0xb8, 0xe0, 0xa4, 0xb9, 0xe0, 0xa5, 0x80, 0xe0, + 0xa4, 0x95, 0xe0, 0xa4, 0xb2, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, 0xa0, 0xe0, 0xa5, + 0x80, 0xe0, 0xa4, 0x95, 0xe0, 0xa4, 0xb9, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, 0x81, + 0xe0, 0xa4, 0xa6, 0xe0, 0xa5, 0x82, 0xe0, 0xa4, 0xb0, 0xe0, 0xa4, 0xa4, 0xe0, + 0xa4, 0xb9, 0xe0, 0xa4, 0xa4, 0xe0, 0xa4, 0xb8, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, + 0xa4, 0xe0, 0xa4, 0xaf, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, 0xa6, 0xe0, 0xa4, 0x86, + 0xe0, 0xa4, 0xaf, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, 0xaa, 0xe0, 0xa4, 0xbe, 0xe0, + 0xa4, 0x95, 0xe0, 0xa4, 0x95, 0xe0, 0xa5, 0x8c, 0xe0, 0xa4, 0xa8, 0xe0, 0xa4, + 0xb6, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, 0xae, 0xe0, 0xa4, 0xa6, 0xe0, 0xa5, 0x87, + 0xe0, 0xa4, 0x96, 0xe0, 0xa4, 0xaf, 0xe0, 0xa4, 0xb9, 0xe0, 0xa5, 0x80, 0xe0, + 0xa4, 0xb0, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, 0xaf, 0xe0, 0xa4, 0x96, 0xe0, 0xa5, + 0x81, 0xe0, 0xa4, 0xa6, 0xe0, 0xa4, 0xb2, 0xe0, 0xa4, 0x97, 0xe0, 0xa5, 0x80, + 0x63, 0x61, 0x74, 0x65, 0x67, 0x6f, 0x72, 0x69, 0x65, 0x73, 0x65, 0x78, 0x70, + 0x65, 0x72, 0x69, 0x65, 0x6e, 0x63, 0x65, 0x3c, 0x2f, 0x74, 0x69, 0x74, 0x6c, + 0x65, 0x3e, 0x0d, 0x0a, 0x43, 0x6f, 0x70, 0x79, 0x72, 0x69, 0x67, 0x68, 0x74, + 0x20, 0x6a, 0x61, 0x76, 0x61, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x63, 0x6f, + 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x65, 0x76, 0x65, 0x72, 0x79, + 0x74, 0x68, 0x69, 0x6e, 0x67, 0x3c, 0x70, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, + 0x3d, 0x22, 0x74, 0x65, 0x63, 0x68, 0x6e, 0x6f, 0x6c, 0x6f, 0x67, 0x79, 0x62, + 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x3c, 0x61, 0x20, 0x63, + 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x22, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, + 0x65, 0x6e, 0x74, 0x26, 0x63, 0x6f, 0x70, 0x79, 0x3b, 0x20, 0x32, 0x30, 0x31, + 0x6a, 0x61, 0x76, 0x61, 0x53, 0x63, 0x72, 0x69, 0x70, 0x74, 0x63, 0x68, 0x61, + 0x72, 0x61, 0x63, 0x74, 0x65, 0x72, 0x73, 0x62, 0x72, 0x65, 0x61, 0x64, 0x63, + 0x72, 0x75, 0x6d, 0x62, 0x74, 0x68, 0x65, 0x6d, 0x73, 0x65, 0x6c, 0x76, 0x65, + 0x73, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x6f, 0x6e, 0x74, 0x61, 0x6c, 0x67, 0x6f, + 0x76, 0x65, 0x72, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x43, 0x61, 0x6c, 0x69, 0x66, + 0x6f, 0x72, 0x6e, 0x69, 0x61, 0x61, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x69, + 0x65, 0x73, 0x64, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x65, 0x64, 0x4e, + 0x61, 0x76, 0x69, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x6e, + 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x6e, 0x61, 0x76, 0x69, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x61, 0x70, 0x70, 0x65, 0x61, 0x72, 0x61, 0x6e, 0x63, 0x65, 0x3c, 0x2f, 0x74, + 0x69, 0x74, 0x6c, 0x65, 0x3e, 0x3c, 0x6d, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x62, + 0x6f, 0x78, 0x22, 0x20, 0x74, 0x65, 0x63, 0x68, 0x6e, 0x69, 0x71, 0x75, 0x65, + 0x73, 0x70, 0x72, 0x6f, 0x74, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x70, + 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x6c, 0x79, 0x61, 0x73, 0x20, 0x77, 0x65, + 0x6c, 0x6c, 0x20, 0x61, 0x73, 0x75, 0x6e, 0x74, 0x27, 0x2c, 0x20, 0x27, 0x55, + 0x41, 0x2d, 0x72, 0x65, 0x73, 0x6f, 0x6c, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x6f, + 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x74, 0x65, 0x6c, 0x65, + 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x6c, 0x61, + 0x74, 0x65, 0x64, 0x57, 0x61, 0x73, 0x68, 0x69, 0x6e, 0x67, 0x74, 0x6f, 0x6e, + 0x6e, 0x61, 0x76, 0x69, 0x67, 0x61, 0x74, 0x6f, 0x72, 0x2e, 0x20, 0x3d, 0x20, + 0x77, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x2e, 0x69, 0x6d, 0x70, 0x72, 0x65, 0x73, + 0x73, 0x69, 0x6f, 0x6e, 0x26, 0x6c, 0x74, 0x3b, 0x62, 0x72, 0x26, 0x67, 0x74, + 0x3b, 0x6c, 0x69, 0x74, 0x65, 0x72, 0x61, 0x74, 0x75, 0x72, 0x65, 0x70, 0x6f, + 0x70, 0x75, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x62, 0x67, 0x63, 0x6f, 0x6c, + 0x6f, 0x72, 0x3d, 0x22, 0x23, 0x65, 0x73, 0x70, 0x65, 0x63, 0x69, 0x61, 0x6c, + 0x6c, 0x79, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x3d, 0x22, 0x70, + 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x6e, 0x65, 0x77, 0x73, + 0x6c, 0x65, 0x74, 0x74, 0x65, 0x72, 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, + 0x69, 0x65, 0x73, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, + 0x6c, 0x65, 0x61, 0x64, 0x65, 0x72, 0x73, 0x68, 0x69, 0x70, 0x54, 0x65, 0x63, + 0x68, 0x6e, 0x6f, 0x6c, 0x6f, 0x67, 0x79, 0x50, 0x61, 0x72, 0x6c, 0x69, 0x61, + 0x6d, 0x65, 0x6e, 0x74, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x72, 0x69, 0x73, 0x6f, + 0x6e, 0x75, 0x6c, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x22, 0x2e, 0x69, + 0x6e, 0x64, 0x65, 0x78, 0x4f, 0x66, 0x28, 0x22, 0x63, 0x6f, 0x6e, 0x63, 0x6c, + 0x75, 0x73, 0x69, 0x6f, 0x6e, 0x64, 0x69, 0x73, 0x63, 0x75, 0x73, 0x73, 0x69, + 0x6f, 0x6e, 0x63, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x73, 0x62, + 0x69, 0x6f, 0x6c, 0x6f, 0x67, 0x69, 0x63, 0x61, 0x6c, 0x52, 0x65, 0x76, 0x6f, + 0x6c, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, + 0x6e, 0x65, 0x72, 0x75, 0x6e, 0x64, 0x65, 0x72, 0x73, 0x74, 0x6f, 0x6f, 0x64, + 0x6e, 0x6f, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x3e, 0x3c, 0x70, 0x65, 0x72, + 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x61, 0x63, 0x68, 0x20, 0x6f, + 0x74, 0x68, 0x65, 0x72, 0x61, 0x74, 0x6d, 0x6f, 0x73, 0x70, 0x68, 0x65, 0x72, + 0x65, 0x20, 0x6f, 0x6e, 0x66, 0x6f, 0x63, 0x75, 0x73, 0x3d, 0x22, 0x3c, 0x66, + 0x6f, 0x72, 0x6d, 0x20, 0x69, 0x64, 0x3d, 0x22, 0x70, 0x72, 0x6f, 0x63, 0x65, + 0x73, 0x73, 0x69, 0x6e, 0x67, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x76, 0x61, 0x6c, + 0x75, 0x65, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x43, + 0x6f, 0x6e, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x73, 0x75, 0x62, 0x73, + 0x65, 0x71, 0x75, 0x65, 0x6e, 0x74, 0x77, 0x65, 0x6c, 0x6c, 0x2d, 0x6b, 0x6e, + 0x6f, 0x77, 0x6e, 0x76, 0x61, 0x72, 0x69, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, + 0x72, 0x65, 0x70, 0x75, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x70, 0x68, 0x65, + 0x6e, 0x6f, 0x6d, 0x65, 0x6e, 0x6f, 0x6e, 0x64, 0x69, 0x73, 0x63, 0x69, 0x70, + 0x6c, 0x69, 0x6e, 0x65, 0x6c, 0x6f, 0x67, 0x6f, 0x2e, 0x70, 0x6e, 0x67, 0x22, + 0x20, 0x28, 0x64, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x2c, 0x62, 0x6f, + 0x75, 0x6e, 0x64, 0x61, 0x72, 0x69, 0x65, 0x73, 0x65, 0x78, 0x70, 0x72, 0x65, + 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x65, 0x74, 0x74, 0x6c, 0x65, 0x6d, 0x65, + 0x6e, 0x74, 0x42, 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x6f, + 0x75, 0x74, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x65, 0x6e, 0x74, 0x65, + 0x72, 0x70, 0x72, 0x69, 0x73, 0x65, 0x28, 0x22, 0x68, 0x74, 0x74, 0x70, 0x73, + 0x3a, 0x22, 0x20, 0x75, 0x6e, 0x65, 0x73, 0x63, 0x61, 0x70, 0x65, 0x28, 0x22, + 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x22, 0x20, 0x64, 0x65, 0x6d, + 0x6f, 0x63, 0x72, 0x61, 0x74, 0x69, 0x63, 0x3c, 0x61, 0x20, 0x68, 0x72, 0x65, + 0x66, 0x3d, 0x22, 0x2f, 0x77, 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, 0x22, 0x3e, + 0x0a, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x68, 0x69, 0x70, 0x6c, 0x69, + 0x6e, 0x67, 0x75, 0x69, 0x73, 0x74, 0x69, 0x63, 0x70, 0x78, 0x3b, 0x70, 0x61, + 0x64, 0x64, 0x69, 0x6e, 0x67, 0x70, 0x68, 0x69, 0x6c, 0x6f, 0x73, 0x6f, 0x70, + 0x68, 0x79, 0x61, 0x73, 0x73, 0x69, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x75, + 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x69, 0x74, 0x79, 0x66, 0x61, 0x63, 0x69, + 0x6c, 0x69, 0x74, 0x69, 0x65, 0x73, 0x72, 0x65, 0x63, 0x6f, 0x67, 0x6e, 0x69, + 0x7a, 0x65, 0x64, 0x70, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, + 0x69, 0x66, 0x20, 0x28, 0x74, 0x79, 0x70, 0x65, 0x6f, 0x66, 0x6d, 0x61, 0x69, + 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x64, 0x76, 0x6f, 0x63, 0x61, 0x62, 0x75, + 0x6c, 0x61, 0x72, 0x79, 0x68, 0x79, 0x70, 0x6f, 0x74, 0x68, 0x65, 0x73, 0x69, + 0x73, 0x2e, 0x73, 0x75, 0x62, 0x6d, 0x69, 0x74, 0x28, 0x29, 0x3b, 0x26, 0x61, + 0x6d, 0x70, 0x3b, 0x6e, 0x62, 0x73, 0x70, 0x3b, 0x61, 0x6e, 0x6e, 0x6f, 0x74, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x62, 0x65, 0x68, 0x69, 0x6e, 0x64, 0x20, 0x74, + 0x68, 0x65, 0x46, 0x6f, 0x75, 0x6e, 0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x70, + 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x65, 0x72, 0x22, 0x61, 0x73, 0x73, 0x75, + 0x6d, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x69, 0x6e, 0x74, 0x72, 0x6f, 0x64, 0x75, + 0x63, 0x65, 0x64, 0x63, 0x6f, 0x72, 0x72, 0x75, 0x70, 0x74, 0x69, 0x6f, 0x6e, + 0x73, 0x63, 0x69, 0x65, 0x6e, 0x74, 0x69, 0x73, 0x74, 0x73, 0x65, 0x78, 0x70, + 0x6c, 0x69, 0x63, 0x69, 0x74, 0x6c, 0x79, 0x69, 0x6e, 0x73, 0x74, 0x65, 0x61, + 0x64, 0x20, 0x6f, 0x66, 0x64, 0x69, 0x6d, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, + 0x73, 0x20, 0x6f, 0x6e, 0x43, 0x6c, 0x69, 0x63, 0x6b, 0x3d, 0x22, 0x63, 0x6f, + 0x6e, 0x73, 0x69, 0x64, 0x65, 0x72, 0x65, 0x64, 0x64, 0x65, 0x70, 0x61, 0x72, + 0x74, 0x6d, 0x65, 0x6e, 0x74, 0x6f, 0x63, 0x63, 0x75, 0x70, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x73, 0x6f, 0x6f, 0x6e, 0x20, 0x61, 0x66, 0x74, 0x65, 0x72, 0x69, + 0x6e, 0x76, 0x65, 0x73, 0x74, 0x6d, 0x65, 0x6e, 0x74, 0x70, 0x72, 0x6f, 0x6e, + 0x6f, 0x75, 0x6e, 0x63, 0x65, 0x64, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, + 0x69, 0x65, 0x64, 0x65, 0x78, 0x70, 0x65, 0x72, 0x69, 0x6d, 0x65, 0x6e, 0x74, + 0x4d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x67, 0x65, 0x6f, + 0x67, 0x72, 0x61, 0x70, 0x68, 0x69, 0x63, 0x22, 0x20, 0x68, 0x65, 0x69, 0x67, + 0x68, 0x74, 0x3d, 0x22, 0x6c, 0x69, 0x6e, 0x6b, 0x20, 0x72, 0x65, 0x6c, 0x3d, + 0x22, 0x2e, 0x72, 0x65, 0x70, 0x6c, 0x61, 0x63, 0x65, 0x28, 0x2f, 0x64, 0x65, + 0x70, 0x72, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x63, 0x6f, 0x6e, 0x66, 0x65, + 0x72, 0x65, 0x6e, 0x63, 0x65, 0x70, 0x75, 0x6e, 0x69, 0x73, 0x68, 0x6d, 0x65, + 0x6e, 0x74, 0x65, 0x6c, 0x69, 0x6d, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x64, 0x72, + 0x65, 0x73, 0x69, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x61, 0x64, 0x61, 0x70, + 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x6f, 0x70, 0x70, 0x6f, 0x73, 0x69, 0x74, + 0x69, 0x6f, 0x6e, 0x77, 0x65, 0x6c, 0x6c, 0x20, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, + 0x73, 0x75, 0x70, 0x70, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x64, 0x65, 0x74, + 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x65, 0x64, 0x68, 0x31, 0x20, 0x63, 0x6c, 0x61, + 0x73, 0x73, 0x3d, 0x22, 0x30, 0x70, 0x78, 0x3b, 0x6d, 0x61, 0x72, 0x67, 0x69, + 0x6e, 0x6d, 0x65, 0x63, 0x68, 0x61, 0x6e, 0x69, 0x63, 0x61, 0x6c, 0x73, 0x74, + 0x61, 0x74, 0x69, 0x73, 0x74, 0x69, 0x63, 0x73, 0x63, 0x65, 0x6c, 0x65, 0x62, + 0x72, 0x61, 0x74, 0x65, 0x64, 0x47, 0x6f, 0x76, 0x65, 0x72, 0x6e, 0x6d, 0x65, + 0x6e, 0x74, 0x0a, 0x0a, 0x44, 0x75, 0x72, 0x69, 0x6e, 0x67, 0x20, 0x74, 0x64, + 0x65, 0x76, 0x65, 0x6c, 0x6f, 0x70, 0x65, 0x72, 0x73, 0x61, 0x72, 0x74, 0x69, + 0x66, 0x69, 0x63, 0x69, 0x61, 0x6c, 0x65, 0x71, 0x75, 0x69, 0x76, 0x61, 0x6c, + 0x65, 0x6e, 0x74, 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x64, + 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x61, 0x74, 0x74, + 0x61, 0x63, 0x68, 0x6d, 0x65, 0x6e, 0x74, 0x3c, 0x73, 0x70, 0x61, 0x6e, 0x20, + 0x69, 0x64, 0x3d, 0x22, 0x74, 0x68, 0x65, 0x72, 0x65, 0x20, 0x77, 0x65, 0x72, + 0x65, 0x4e, 0x65, 0x64, 0x65, 0x72, 0x6c, 0x61, 0x6e, 0x64, 0x73, 0x62, 0x65, + 0x79, 0x6f, 0x6e, 0x64, 0x20, 0x74, 0x68, 0x65, 0x72, 0x65, 0x67, 0x69, 0x73, + 0x74, 0x65, 0x72, 0x65, 0x64, 0x6a, 0x6f, 0x75, 0x72, 0x6e, 0x61, 0x6c, 0x69, + 0x73, 0x74, 0x66, 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x74, 0x6c, 0x79, 0x61, + 0x6c, 0x6c, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x6c, 0x61, 0x6e, 0x67, + 0x3d, 0x22, 0x65, 0x6e, 0x22, 0x20, 0x3c, 0x2f, 0x73, 0x74, 0x79, 0x6c, 0x65, + 0x3e, 0x0d, 0x0a, 0x61, 0x62, 0x73, 0x6f, 0x6c, 0x75, 0x74, 0x65, 0x3b, 0x20, + 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x69, 0x6e, 0x67, 0x65, 0x78, 0x74, + 0x72, 0x65, 0x6d, 0x65, 0x6c, 0x79, 0x20, 0x6d, 0x61, 0x69, 0x6e, 0x73, 0x74, + 0x72, 0x65, 0x61, 0x6d, 0x3c, 0x2f, 0x73, 0x74, 0x72, 0x6f, 0x6e, 0x67, 0x3e, + 0x20, 0x70, 0x6f, 0x70, 0x75, 0x6c, 0x61, 0x72, 0x69, 0x74, 0x79, 0x65, 0x6d, + 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x3c, 0x2f, 0x74, 0x61, 0x62, + 0x6c, 0x65, 0x3e, 0x0d, 0x0a, 0x20, 0x63, 0x6f, 0x6c, 0x73, 0x70, 0x61, 0x6e, + 0x3d, 0x22, 0x3c, 0x2f, 0x66, 0x6f, 0x72, 0x6d, 0x3e, 0x0a, 0x20, 0x20, 0x63, + 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x61, 0x62, 0x6f, 0x75, + 0x74, 0x20, 0x74, 0x68, 0x65, 0x20, 0x3c, 0x2f, 0x70, 0x3e, 0x3c, 0x2f, 0x64, + 0x69, 0x76, 0x3e, 0x69, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x65, 0x64, + 0x22, 0x20, 0x6c, 0x61, 0x6e, 0x67, 0x3d, 0x22, 0x65, 0x6e, 0x50, 0x6f, 0x72, + 0x74, 0x75, 0x67, 0x75, 0x65, 0x73, 0x65, 0x73, 0x75, 0x62, 0x73, 0x74, 0x69, + 0x74, 0x75, 0x74, 0x65, 0x69, 0x6e, 0x64, 0x69, 0x76, 0x69, 0x64, 0x75, 0x61, + 0x6c, 0x69, 0x6d, 0x70, 0x6f, 0x73, 0x73, 0x69, 0x62, 0x6c, 0x65, 0x6d, 0x75, + 0x6c, 0x74, 0x69, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x61, 0x6c, 0x6d, 0x6f, 0x73, + 0x74, 0x20, 0x61, 0x6c, 0x6c, 0x70, 0x78, 0x20, 0x73, 0x6f, 0x6c, 0x69, 0x64, + 0x20, 0x23, 0x61, 0x70, 0x61, 0x72, 0x74, 0x20, 0x66, 0x72, 0x6f, 0x6d, 0x73, + 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x20, 0x74, 0x6f, 0x69, 0x6e, 0x20, 0x45, + 0x6e, 0x67, 0x6c, 0x69, 0x73, 0x68, 0x63, 0x72, 0x69, 0x74, 0x69, 0x63, 0x69, + 0x7a, 0x65, 0x64, 0x65, 0x78, 0x63, 0x65, 0x70, 0x74, 0x20, 0x66, 0x6f, 0x72, + 0x67, 0x75, 0x69, 0x64, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x73, 0x6f, 0x72, 0x69, + 0x67, 0x69, 0x6e, 0x61, 0x6c, 0x6c, 0x79, 0x72, 0x65, 0x6d, 0x61, 0x72, 0x6b, + 0x61, 0x62, 0x6c, 0x65, 0x74, 0x68, 0x65, 0x20, 0x73, 0x65, 0x63, 0x6f, 0x6e, + 0x64, 0x68, 0x32, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x22, 0x3c, 0x61, + 0x20, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x3d, 0x22, 0x28, 0x69, 0x6e, 0x63, 0x6c, + 0x75, 0x64, 0x69, 0x6e, 0x67, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, + 0x72, 0x73, 0x70, 0x72, 0x6f, 0x68, 0x69, 0x62, 0x69, 0x74, 0x65, 0x64, 0x3d, + 0x20, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x64, 0x69, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x61, 0x72, 0x79, 0x70, 0x65, 0x72, 0x63, 0x65, 0x70, 0x74, + 0x69, 0x6f, 0x6e, 0x72, 0x65, 0x76, 0x6f, 0x6c, 0x75, 0x74, 0x69, 0x6f, 0x6e, + 0x66, 0x6f, 0x75, 0x6e, 0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x70, 0x78, 0x3b, + 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x3a, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, + 0x73, 0x66, 0x75, 0x6c, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x72, + 0x73, 0x6d, 0x69, 0x6c, 0x6c, 0x65, 0x6e, 0x6e, 0x69, 0x75, 0x6d, 0x68, 0x69, + 0x73, 0x20, 0x66, 0x61, 0x74, 0x68, 0x65, 0x72, 0x74, 0x68, 0x65, 0x20, 0x26, + 0x71, 0x75, 0x6f, 0x74, 0x3b, 0x6e, 0x6f, 0x2d, 0x72, 0x65, 0x70, 0x65, 0x61, + 0x74, 0x3b, 0x63, 0x6f, 0x6d, 0x6d, 0x65, 0x72, 0x63, 0x69, 0x61, 0x6c, 0x69, + 0x6e, 0x64, 0x75, 0x73, 0x74, 0x72, 0x69, 0x61, 0x6c, 0x65, 0x6e, 0x63, 0x6f, + 0x75, 0x72, 0x61, 0x67, 0x65, 0x64, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x20, + 0x6f, 0x66, 0x20, 0x75, 0x6e, 0x6f, 0x66, 0x66, 0x69, 0x63, 0x69, 0x61, 0x6c, + 0x65, 0x66, 0x66, 0x69, 0x63, 0x69, 0x65, 0x6e, 0x63, 0x79, 0x52, 0x65, 0x66, + 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x73, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x69, + 0x6e, 0x61, 0x74, 0x65, 0x64, 0x69, 0x73, 0x63, 0x6c, 0x61, 0x69, 0x6d, 0x65, + 0x72, 0x65, 0x78, 0x70, 0x65, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x64, 0x65, + 0x76, 0x65, 0x6c, 0x6f, 0x70, 0x69, 0x6e, 0x67, 0x63, 0x61, 0x6c, 0x63, 0x75, + 0x6c, 0x61, 0x74, 0x65, 0x64, 0x73, 0x69, 0x6d, 0x70, 0x6c, 0x69, 0x66, 0x69, + 0x65, 0x64, 0x6c, 0x65, 0x67, 0x69, 0x74, 0x69, 0x6d, 0x61, 0x74, 0x65, 0x73, + 0x75, 0x62, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x28, 0x30, 0x22, 0x20, 0x63, + 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x22, 0x63, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, + 0x65, 0x6c, 0x79, 0x69, 0x6c, 0x6c, 0x75, 0x73, 0x74, 0x72, 0x61, 0x74, 0x65, + 0x66, 0x69, 0x76, 0x65, 0x20, 0x79, 0x65, 0x61, 0x72, 0x73, 0x69, 0x6e, 0x73, + 0x74, 0x72, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x73, + 0x68, 0x69, 0x6e, 0x67, 0x31, 0x22, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x3d, + 0x22, 0x70, 0x73, 0x79, 0x63, 0x68, 0x6f, 0x6c, 0x6f, 0x67, 0x79, 0x63, 0x6f, + 0x6e, 0x66, 0x69, 0x64, 0x65, 0x6e, 0x63, 0x65, 0x6e, 0x75, 0x6d, 0x62, 0x65, + 0x72, 0x20, 0x6f, 0x66, 0x20, 0x61, 0x62, 0x73, 0x65, 0x6e, 0x63, 0x65, 0x20, + 0x6f, 0x66, 0x66, 0x6f, 0x63, 0x75, 0x73, 0x65, 0x64, 0x20, 0x6f, 0x6e, 0x6a, + 0x6f, 0x69, 0x6e, 0x65, 0x64, 0x20, 0x74, 0x68, 0x65, 0x73, 0x74, 0x72, 0x75, + 0x63, 0x74, 0x75, 0x72, 0x65, 0x73, 0x70, 0x72, 0x65, 0x76, 0x69, 0x6f, 0x75, + 0x73, 0x6c, 0x79, 0x3e, 0x3c, 0x2f, 0x69, 0x66, 0x72, 0x61, 0x6d, 0x65, 0x3e, + 0x6f, 0x6e, 0x63, 0x65, 0x20, 0x61, 0x67, 0x61, 0x69, 0x6e, 0x62, 0x75, 0x74, + 0x20, 0x72, 0x61, 0x74, 0x68, 0x65, 0x72, 0x69, 0x6d, 0x6d, 0x69, 0x67, 0x72, + 0x61, 0x6e, 0x74, 0x73, 0x6f, 0x66, 0x20, 0x63, 0x6f, 0x75, 0x72, 0x73, 0x65, + 0x2c, 0x61, 0x20, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x20, 0x6f, 0x66, 0x4c, 0x69, + 0x74, 0x65, 0x72, 0x61, 0x74, 0x75, 0x72, 0x65, 0x55, 0x6e, 0x6c, 0x69, 0x6b, + 0x65, 0x20, 0x74, 0x68, 0x65, 0x3c, 0x2f, 0x61, 0x3e, 0x26, 0x6e, 0x62, 0x73, + 0x70, 0x3b, 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x69, + 0x74, 0x20, 0x77, 0x61, 0x73, 0x20, 0x74, 0x68, 0x65, 0x43, 0x6f, 0x6e, 0x76, + 0x65, 0x6e, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x75, 0x74, 0x6f, 0x6d, 0x6f, 0x62, + 0x69, 0x6c, 0x65, 0x50, 0x72, 0x6f, 0x74, 0x65, 0x73, 0x74, 0x61, 0x6e, 0x74, + 0x61, 0x67, 0x67, 0x72, 0x65, 0x73, 0x73, 0x69, 0x76, 0x65, 0x61, 0x66, 0x74, + 0x65, 0x72, 0x20, 0x74, 0x68, 0x65, 0x20, 0x53, 0x69, 0x6d, 0x69, 0x6c, 0x61, + 0x72, 0x6c, 0x79, 0x2c, 0x22, 0x20, 0x2f, 0x3e, 0x3c, 0x2f, 0x64, 0x69, 0x76, + 0x3e, 0x63, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x0d, 0x0a, + 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x76, 0x69, 0x73, 0x69, 0x62, + 0x69, 0x6c, 0x69, 0x74, 0x79, 0x74, 0x68, 0x65, 0x20, 0x75, 0x73, 0x65, 0x20, + 0x6f, 0x66, 0x76, 0x6f, 0x6c, 0x75, 0x6e, 0x74, 0x65, 0x65, 0x72, 0x73, 0x61, + 0x74, 0x74, 0x72, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x75, 0x6e, 0x64, 0x65, + 0x72, 0x20, 0x74, 0x68, 0x65, 0x20, 0x74, 0x68, 0x72, 0x65, 0x61, 0x74, 0x65, + 0x6e, 0x65, 0x64, 0x2a, 0x3c, 0x21, 0x5b, 0x43, 0x44, 0x41, 0x54, 0x41, 0x5b, + 0x69, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x69, 0x6e, 0x20, + 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x6c, 0x74, 0x68, 0x65, 0x20, 0x6c, 0x61, + 0x74, 0x74, 0x65, 0x72, 0x3c, 0x2f, 0x66, 0x6f, 0x72, 0x6d, 0x3e, 0x0a, 0x3c, + 0x2f, 0x2e, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x4f, 0x66, 0x28, 0x27, 0x69, 0x20, + 0x3d, 0x20, 0x30, 0x3b, 0x20, 0x69, 0x20, 0x3c, 0x64, 0x69, 0x66, 0x66, 0x65, + 0x72, 0x65, 0x6e, 0x63, 0x65, 0x64, 0x65, 0x76, 0x6f, 0x74, 0x65, 0x64, 0x20, + 0x74, 0x6f, 0x74, 0x72, 0x61, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x73, + 0x65, 0x61, 0x72, 0x63, 0x68, 0x20, 0x66, 0x6f, 0x72, 0x75, 0x6c, 0x74, 0x69, + 0x6d, 0x61, 0x74, 0x65, 0x6c, 0x79, 0x74, 0x6f, 0x75, 0x72, 0x6e, 0x61, 0x6d, + 0x65, 0x6e, 0x74, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, + 0x73, 0x6f, 0x2d, 0x63, 0x61, 0x6c, 0x6c, 0x65, 0x64, 0x20, 0x7d, 0x0a, 0x3c, + 0x2f, 0x73, 0x74, 0x79, 0x6c, 0x65, 0x3e, 0x65, 0x76, 0x61, 0x6c, 0x75, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x65, 0x6d, 0x70, 0x68, 0x61, 0x73, 0x69, 0x7a, 0x65, + 0x64, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x69, 0x62, 0x6c, 0x65, 0x3c, 0x2f, + 0x73, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x3e, 0x73, 0x75, 0x63, 0x63, 0x65, + 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x6f, 0x6e, 0x67, 0x20, 0x77, 0x69, + 0x74, 0x68, 0x4d, 0x65, 0x61, 0x6e, 0x77, 0x68, 0x69, 0x6c, 0x65, 0x2c, 0x69, + 0x6e, 0x64, 0x75, 0x73, 0x74, 0x72, 0x69, 0x65, 0x73, 0x3c, 0x2f, 0x61, 0x3e, + 0x3c, 0x62, 0x72, 0x20, 0x2f, 0x3e, 0x68, 0x61, 0x73, 0x20, 0x62, 0x65, 0x63, + 0x6f, 0x6d, 0x65, 0x61, 0x73, 0x70, 0x65, 0x63, 0x74, 0x73, 0x20, 0x6f, 0x66, + 0x54, 0x65, 0x6c, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x75, 0x66, + 0x66, 0x69, 0x63, 0x69, 0x65, 0x6e, 0x74, 0x62, 0x61, 0x73, 0x6b, 0x65, 0x74, + 0x62, 0x61, 0x6c, 0x6c, 0x62, 0x6f, 0x74, 0x68, 0x20, 0x73, 0x69, 0x64, 0x65, + 0x73, 0x63, 0x6f, 0x6e, 0x74, 0x69, 0x6e, 0x75, 0x69, 0x6e, 0x67, 0x61, 0x6e, + 0x20, 0x61, 0x72, 0x74, 0x69, 0x63, 0x6c, 0x65, 0x3c, 0x69, 0x6d, 0x67, 0x20, + 0x61, 0x6c, 0x74, 0x3d, 0x22, 0x61, 0x64, 0x76, 0x65, 0x6e, 0x74, 0x75, 0x72, + 0x65, 0x73, 0x68, 0x69, 0x73, 0x20, 0x6d, 0x6f, 0x74, 0x68, 0x65, 0x72, 0x6d, + 0x61, 0x6e, 0x63, 0x68, 0x65, 0x73, 0x74, 0x65, 0x72, 0x70, 0x72, 0x69, 0x6e, + 0x63, 0x69, 0x70, 0x6c, 0x65, 0x73, 0x70, 0x61, 0x72, 0x74, 0x69, 0x63, 0x75, + 0x6c, 0x61, 0x72, 0x63, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x61, 0x72, 0x79, + 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, 0x73, 0x20, 0x6f, 0x66, 0x64, 0x65, 0x63, + 0x69, 0x64, 0x65, 0x64, 0x20, 0x74, 0x6f, 0x22, 0x3e, 0x3c, 0x73, 0x74, 0x72, + 0x6f, 0x6e, 0x67, 0x3e, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x65, 0x72, + 0x73, 0x4a, 0x6f, 0x75, 0x72, 0x6e, 0x61, 0x6c, 0x20, 0x6f, 0x66, 0x64, 0x69, + 0x66, 0x66, 0x69, 0x63, 0x75, 0x6c, 0x74, 0x79, 0x66, 0x61, 0x63, 0x69, 0x6c, + 0x69, 0x74, 0x61, 0x74, 0x65, 0x61, 0x63, 0x63, 0x65, 0x70, 0x74, 0x61, 0x62, + 0x6c, 0x65, 0x73, 0x74, 0x79, 0x6c, 0x65, 0x2e, 0x63, 0x73, 0x73, 0x22, 0x09, + 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x69, 0x6e, 0x6e, 0x6f, + 0x76, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3e, 0x43, 0x6f, 0x70, 0x79, 0x72, 0x69, + 0x67, 0x68, 0x74, 0x73, 0x69, 0x74, 0x75, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, + 0x77, 0x6f, 0x75, 0x6c, 0x64, 0x20, 0x68, 0x61, 0x76, 0x65, 0x62, 0x75, 0x73, + 0x69, 0x6e, 0x65, 0x73, 0x73, 0x65, 0x73, 0x44, 0x69, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x61, 0x72, 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e, 0x74, + 0x73, 0x6f, 0x66, 0x74, 0x65, 0x6e, 0x20, 0x75, 0x73, 0x65, 0x64, 0x70, 0x65, + 0x72, 0x73, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x74, 0x69, 0x6e, 0x20, 0x4a, 0x61, + 0x6e, 0x75, 0x61, 0x72, 0x79, 0x63, 0x6f, 0x6d, 0x70, 0x72, 0x69, 0x73, 0x69, + 0x6e, 0x67, 0x3c, 0x2f, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x3e, 0x0a, 0x09, 0x64, + 0x69, 0x70, 0x6c, 0x6f, 0x6d, 0x61, 0x74, 0x69, 0x63, 0x63, 0x6f, 0x6e, 0x74, + 0x61, 0x69, 0x6e, 0x69, 0x6e, 0x67, 0x70, 0x65, 0x72, 0x66, 0x6f, 0x72, 0x6d, + 0x69, 0x6e, 0x67, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x73, + 0x6d, 0x61, 0x79, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x62, 0x65, 0x63, 0x6f, 0x6e, + 0x63, 0x65, 0x70, 0x74, 0x20, 0x6f, 0x66, 0x20, 0x6f, 0x6e, 0x63, 0x6c, 0x69, + 0x63, 0x6b, 0x3d, 0x22, 0x49, 0x74, 0x20, 0x69, 0x73, 0x20, 0x61, 0x6c, 0x73, + 0x6f, 0x66, 0x69, 0x6e, 0x61, 0x6e, 0x63, 0x69, 0x61, 0x6c, 0x20, 0x6d, 0x61, + 0x6b, 0x69, 0x6e, 0x67, 0x20, 0x74, 0x68, 0x65, 0x4c, 0x75, 0x78, 0x65, 0x6d, + 0x62, 0x6f, 0x75, 0x72, 0x67, 0x61, 0x64, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, + 0x61, 0x6c, 0x61, 0x72, 0x65, 0x20, 0x63, 0x61, 0x6c, 0x6c, 0x65, 0x64, 0x65, + 0x6e, 0x67, 0x61, 0x67, 0x65, 0x64, 0x20, 0x69, 0x6e, 0x22, 0x73, 0x63, 0x72, + 0x69, 0x70, 0x74, 0x22, 0x29, 0x3b, 0x62, 0x75, 0x74, 0x20, 0x69, 0x74, 0x20, + 0x77, 0x61, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x72, 0x6f, 0x6e, 0x69, 0x63, + 0x6f, 0x6e, 0x73, 0x75, 0x62, 0x6d, 0x69, 0x74, 0x3d, 0x22, 0x0a, 0x3c, 0x21, + 0x2d, 0x2d, 0x20, 0x45, 0x6e, 0x64, 0x20, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x72, + 0x69, 0x63, 0x61, 0x6c, 0x6f, 0x66, 0x66, 0x69, 0x63, 0x69, 0x61, 0x6c, 0x6c, + 0x79, 0x73, 0x75, 0x67, 0x67, 0x65, 0x73, 0x74, 0x69, 0x6f, 0x6e, 0x74, 0x6f, + 0x70, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x75, 0x6e, 0x6c, 0x69, 0x6b, + 0x65, 0x20, 0x74, 0x68, 0x65, 0x41, 0x75, 0x73, 0x74, 0x72, 0x61, 0x6c, 0x69, + 0x61, 0x6e, 0x4f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x61, 0x6c, 0x6c, 0x79, 0x72, + 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x73, 0x0a, 0x3c, 0x2f, 0x68, + 0x65, 0x61, 0x64, 0x3e, 0x0d, 0x0a, 0x72, 0x65, 0x63, 0x6f, 0x67, 0x6e, 0x69, + 0x73, 0x65, 0x64, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x61, 0x6c, 0x69, 0x7a, 0x65, + 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x65, 0x64, 0x20, 0x74, 0x6f, 0x41, 0x6c, 0x65, + 0x78, 0x61, 0x6e, 0x64, 0x72, 0x69, 0x61, 0x72, 0x65, 0x74, 0x69, 0x72, 0x65, + 0x6d, 0x65, 0x6e, 0x74, 0x41, 0x64, 0x76, 0x65, 0x6e, 0x74, 0x75, 0x72, 0x65, + 0x73, 0x66, 0x6f, 0x75, 0x72, 0x20, 0x79, 0x65, 0x61, 0x72, 0x73, 0x0a, 0x0a, + 0x26, 0x6c, 0x74, 0x3b, 0x21, 0x2d, 0x2d, 0x20, 0x69, 0x6e, 0x63, 0x72, 0x65, + 0x61, 0x73, 0x69, 0x6e, 0x67, 0x64, 0x65, 0x63, 0x6f, 0x72, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x68, 0x33, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x22, 0x6f, + 0x72, 0x69, 0x67, 0x69, 0x6e, 0x73, 0x20, 0x6f, 0x66, 0x6f, 0x62, 0x6c, 0x69, + 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x72, 0x65, 0x67, 0x75, 0x6c, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x69, 0x66, 0x69, 0x65, 0x64, + 0x28, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x61, 0x64, 0x76, + 0x61, 0x6e, 0x74, 0x61, 0x67, 0x65, 0x73, 0x62, 0x65, 0x69, 0x6e, 0x67, 0x20, + 0x74, 0x68, 0x65, 0x20, 0x68, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x69, 0x61, 0x6e, + 0x73, 0x3c, 0x62, 0x61, 0x73, 0x65, 0x20, 0x68, 0x72, 0x65, 0x66, 0x72, 0x65, + 0x70, 0x65, 0x61, 0x74, 0x65, 0x64, 0x6c, 0x79, 0x77, 0x69, 0x6c, 0x6c, 0x69, + 0x6e, 0x67, 0x20, 0x74, 0x6f, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x72, 0x61, 0x62, + 0x6c, 0x65, 0x64, 0x65, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x65, 0x64, 0x6e, + 0x6f, 0x6d, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x66, 0x75, 0x6e, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x69, 0x6e, 0x73, 0x69, 0x64, 0x65, 0x20, + 0x74, 0x68, 0x65, 0x72, 0x65, 0x76, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x65, 0x6e, 0x64, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x73, 0x20, 0x66, + 0x6f, 0x72, 0x20, 0x74, 0x68, 0x65, 0x20, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, + 0x69, 0x7a, 0x65, 0x64, 0x72, 0x65, 0x66, 0x75, 0x73, 0x65, 0x64, 0x20, 0x74, + 0x6f, 0x74, 0x61, 0x6b, 0x65, 0x20, 0x70, 0x6c, 0x61, 0x63, 0x65, 0x61, 0x75, + 0x74, 0x6f, 0x6e, 0x6f, 0x6d, 0x6f, 0x75, 0x73, 0x63, 0x6f, 0x6d, 0x70, 0x72, + 0x6f, 0x6d, 0x69, 0x73, 0x65, 0x70, 0x6f, 0x6c, 0x69, 0x74, 0x69, 0x63, 0x61, + 0x6c, 0x20, 0x72, 0x65, 0x73, 0x74, 0x61, 0x75, 0x72, 0x61, 0x6e, 0x74, 0x74, + 0x77, 0x6f, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x46, 0x65, 0x62, 0x72, + 0x75, 0x61, 0x72, 0x79, 0x20, 0x32, 0x71, 0x75, 0x61, 0x6c, 0x69, 0x74, 0x79, + 0x20, 0x6f, 0x66, 0x73, 0x77, 0x66, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x2e, + 0x75, 0x6e, 0x64, 0x65, 0x72, 0x73, 0x74, 0x61, 0x6e, 0x64, 0x6e, 0x65, 0x61, + 0x72, 0x6c, 0x79, 0x20, 0x61, 0x6c, 0x6c, 0x77, 0x72, 0x69, 0x74, 0x74, 0x65, + 0x6e, 0x20, 0x62, 0x79, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x69, 0x65, 0x77, + 0x73, 0x22, 0x20, 0x77, 0x69, 0x64, 0x74, 0x68, 0x3d, 0x22, 0x31, 0x77, 0x69, + 0x74, 0x68, 0x64, 0x72, 0x61, 0x77, 0x61, 0x6c, 0x66, 0x6c, 0x6f, 0x61, 0x74, + 0x3a, 0x6c, 0x65, 0x66, 0x74, 0x69, 0x73, 0x20, 0x75, 0x73, 0x75, 0x61, 0x6c, + 0x6c, 0x79, 0x63, 0x61, 0x6e, 0x64, 0x69, 0x64, 0x61, 0x74, 0x65, 0x73, 0x6e, + 0x65, 0x77, 0x73, 0x70, 0x61, 0x70, 0x65, 0x72, 0x73, 0x6d, 0x79, 0x73, 0x74, + 0x65, 0x72, 0x69, 0x6f, 0x75, 0x73, 0x44, 0x65, 0x70, 0x61, 0x72, 0x74, 0x6d, + 0x65, 0x6e, 0x74, 0x62, 0x65, 0x73, 0x74, 0x20, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, + 0x70, 0x61, 0x72, 0x6c, 0x69, 0x61, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x75, 0x70, + 0x70, 0x72, 0x65, 0x73, 0x73, 0x65, 0x64, 0x63, 0x6f, 0x6e, 0x76, 0x65, 0x6e, + 0x69, 0x65, 0x6e, 0x74, 0x72, 0x65, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x65, + 0x64, 0x64, 0x69, 0x66, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x74, 0x20, 0x73, 0x79, + 0x73, 0x74, 0x65, 0x6d, 0x61, 0x74, 0x69, 0x63, 0x68, 0x61, 0x73, 0x20, 0x6c, + 0x65, 0x64, 0x20, 0x74, 0x6f, 0x70, 0x72, 0x6f, 0x70, 0x61, 0x67, 0x61, 0x6e, + 0x64, 0x61, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x64, 0x69, + 0x6e, 0x66, 0x6c, 0x75, 0x65, 0x6e, 0x63, 0x65, 0x73, 0x63, 0x65, 0x72, 0x65, + 0x6d, 0x6f, 0x6e, 0x69, 0x61, 0x6c, 0x70, 0x72, 0x6f, 0x63, 0x6c, 0x61, 0x69, + 0x6d, 0x65, 0x64, 0x50, 0x72, 0x6f, 0x74, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x6c, 0x69, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x22, 0x53, 0x63, 0x69, + 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x63, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x3d, + 0x22, 0x6e, 0x6f, 0x2d, 0x74, 0x72, 0x61, 0x64, 0x65, 0x6d, 0x61, 0x72, 0x6b, + 0x73, 0x6d, 0x6f, 0x72, 0x65, 0x20, 0x74, 0x68, 0x61, 0x6e, 0x20, 0x77, 0x69, + 0x64, 0x65, 0x73, 0x70, 0x72, 0x65, 0x61, 0x64, 0x4c, 0x69, 0x62, 0x65, 0x72, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x74, 0x6f, 0x6f, 0x6b, 0x20, 0x70, 0x6c, 0x61, + 0x63, 0x65, 0x64, 0x61, 0x79, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x61, + 0x73, 0x20, 0x6c, 0x6f, 0x6e, 0x67, 0x20, 0x61, 0x73, 0x69, 0x6d, 0x70, 0x72, + 0x69, 0x73, 0x6f, 0x6e, 0x65, 0x64, 0x41, 0x64, 0x64, 0x69, 0x74, 0x69, 0x6f, + 0x6e, 0x61, 0x6c, 0x0a, 0x3c, 0x68, 0x65, 0x61, 0x64, 0x3e, 0x0a, 0x3c, 0x6d, + 0x4c, 0x61, 0x62, 0x6f, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x79, 0x4e, 0x6f, 0x76, + 0x65, 0x6d, 0x62, 0x65, 0x72, 0x20, 0x32, 0x65, 0x78, 0x63, 0x65, 0x70, 0x74, + 0x69, 0x6f, 0x6e, 0x73, 0x49, 0x6e, 0x64, 0x75, 0x73, 0x74, 0x72, 0x69, 0x61, + 0x6c, 0x76, 0x61, 0x72, 0x69, 0x65, 0x74, 0x79, 0x20, 0x6f, 0x66, 0x66, 0x6c, + 0x6f, 0x61, 0x74, 0x3a, 0x20, 0x6c, 0x65, 0x66, 0x44, 0x75, 0x72, 0x69, 0x6e, + 0x67, 0x20, 0x74, 0x68, 0x65, 0x61, 0x73, 0x73, 0x65, 0x73, 0x73, 0x6d, 0x65, + 0x6e, 0x74, 0x68, 0x61, 0x76, 0x65, 0x20, 0x62, 0x65, 0x65, 0x6e, 0x20, 0x64, + 0x65, 0x61, 0x6c, 0x73, 0x20, 0x77, 0x69, 0x74, 0x68, 0x53, 0x74, 0x61, 0x74, + 0x69, 0x73, 0x74, 0x69, 0x63, 0x73, 0x6f, 0x63, 0x63, 0x75, 0x72, 0x72, 0x65, + 0x6e, 0x63, 0x65, 0x2f, 0x75, 0x6c, 0x3e, 0x3c, 0x2f, 0x64, 0x69, 0x76, 0x3e, + 0x63, 0x6c, 0x65, 0x61, 0x72, 0x66, 0x69, 0x78, 0x22, 0x3e, 0x74, 0x68, 0x65, + 0x20, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x6d, 0x61, 0x6e, 0x79, 0x20, 0x79, + 0x65, 0x61, 0x72, 0x73, 0x77, 0x68, 0x69, 0x63, 0x68, 0x20, 0x77, 0x65, 0x72, + 0x65, 0x6f, 0x76, 0x65, 0x72, 0x20, 0x74, 0x69, 0x6d, 0x65, 0x2c, 0x73, 0x79, + 0x6e, 0x6f, 0x6e, 0x79, 0x6d, 0x6f, 0x75, 0x73, 0x63, 0x6f, 0x6e, 0x74, 0x65, + 0x6e, 0x74, 0x22, 0x3e, 0x0a, 0x70, 0x72, 0x65, 0x73, 0x75, 0x6d, 0x61, 0x62, + 0x6c, 0x79, 0x68, 0x69, 0x73, 0x20, 0x66, 0x61, 0x6d, 0x69, 0x6c, 0x79, 0x75, + 0x73, 0x65, 0x72, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x75, 0x6e, 0x65, 0x78, + 0x70, 0x65, 0x63, 0x74, 0x65, 0x64, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x69, + 0x6e, 0x67, 0x20, 0x63, 0x68, 0x61, 0x6c, 0x6c, 0x65, 0x6e, 0x67, 0x65, 0x64, + 0x61, 0x20, 0x6d, 0x69, 0x6e, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x75, 0x6e, 0x64, + 0x65, 0x66, 0x69, 0x6e, 0x65, 0x64, 0x22, 0x62, 0x65, 0x6c, 0x6f, 0x6e, 0x67, + 0x73, 0x20, 0x74, 0x6f, 0x74, 0x61, 0x6b, 0x65, 0x6e, 0x20, 0x66, 0x72, 0x6f, + 0x6d, 0x69, 0x6e, 0x20, 0x4f, 0x63, 0x74, 0x6f, 0x62, 0x65, 0x72, 0x70, 0x6f, + 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x73, 0x61, 0x69, 0x64, 0x20, + 0x74, 0x6f, 0x20, 0x62, 0x65, 0x72, 0x65, 0x6c, 0x69, 0x67, 0x69, 0x6f, 0x75, + 0x73, 0x20, 0x46, 0x65, 0x64, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, + 0x72, 0x6f, 0x77, 0x73, 0x70, 0x61, 0x6e, 0x3d, 0x22, 0x6f, 0x6e, 0x6c, 0x79, + 0x20, 0x61, 0x20, 0x66, 0x65, 0x77, 0x6d, 0x65, 0x61, 0x6e, 0x74, 0x20, 0x74, + 0x68, 0x61, 0x74, 0x6c, 0x65, 0x64, 0x20, 0x74, 0x6f, 0x20, 0x74, 0x68, 0x65, + 0x2d, 0x2d, 0x3e, 0x0d, 0x0a, 0x3c, 0x64, 0x69, 0x76, 0x20, 0x3c, 0x66, 0x69, + 0x65, 0x6c, 0x64, 0x73, 0x65, 0x74, 0x3e, 0x41, 0x72, 0x63, 0x68, 0x62, 0x69, + 0x73, 0x68, 0x6f, 0x70, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x22, 0x6e, + 0x6f, 0x62, 0x65, 0x69, 0x6e, 0x67, 0x20, 0x75, 0x73, 0x65, 0x64, 0x61, 0x70, + 0x70, 0x72, 0x6f, 0x61, 0x63, 0x68, 0x65, 0x73, 0x70, 0x72, 0x69, 0x76, 0x69, + 0x6c, 0x65, 0x67, 0x65, 0x73, 0x6e, 0x6f, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, + 0x3e, 0x0a, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x20, 0x69, 0x6e, 0x6d, + 0x61, 0x79, 0x20, 0x62, 0x65, 0x20, 0x74, 0x68, 0x65, 0x45, 0x61, 0x73, 0x74, + 0x65, 0x72, 0x20, 0x65, 0x67, 0x67, 0x6d, 0x65, 0x63, 0x68, 0x61, 0x6e, 0x69, + 0x73, 0x6d, 0x73, 0x72, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x61, 0x62, 0x6c, 0x65, + 0x50, 0x6f, 0x70, 0x75, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x6c, + 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, + 0x65, 0x64, 0x22, 0x3e, 0x6e, 0x6f, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x3e, + 0x0d, 0x2f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x2e, 0x70, 0x68, 0x70, 0x61, 0x72, + 0x72, 0x69, 0x76, 0x61, 0x6c, 0x20, 0x6f, 0x66, 0x2d, 0x6a, 0x73, 0x73, 0x64, + 0x6b, 0x27, 0x29, 0x29, 0x3b, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x64, 0x20, + 0x74, 0x6f, 0x69, 0x6e, 0x63, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x63, + 0x61, 0x73, 0x75, 0x61, 0x6c, 0x74, 0x69, 0x65, 0x73, 0x63, 0x6f, 0x6d, 0x70, + 0x6c, 0x65, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x68, 0x72, 0x69, 0x73, 0x74, 0x69, + 0x61, 0x6e, 0x73, 0x53, 0x65, 0x70, 0x74, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x20, + 0x61, 0x72, 0x69, 0x74, 0x68, 0x6d, 0x65, 0x74, 0x69, 0x63, 0x70, 0x72, 0x6f, + 0x63, 0x65, 0x64, 0x75, 0x72, 0x65, 0x73, 0x6d, 0x69, 0x67, 0x68, 0x74, 0x20, + 0x68, 0x61, 0x76, 0x65, 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x69, 0x74, 0x20, 0x61, 0x70, 0x70, 0x65, 0x61, 0x72, 0x73, 0x50, 0x68, + 0x69, 0x6c, 0x6f, 0x73, 0x6f, 0x70, 0x68, 0x79, 0x66, 0x72, 0x69, 0x65, 0x6e, + 0x64, 0x73, 0x68, 0x69, 0x70, 0x6c, 0x65, 0x61, 0x64, 0x69, 0x6e, 0x67, 0x20, + 0x74, 0x6f, 0x67, 0x69, 0x76, 0x69, 0x6e, 0x67, 0x20, 0x74, 0x68, 0x65, 0x74, + 0x6f, 0x77, 0x61, 0x72, 0x64, 0x20, 0x74, 0x68, 0x65, 0x67, 0x75, 0x61, 0x72, + 0x61, 0x6e, 0x74, 0x65, 0x65, 0x64, 0x64, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, + 0x74, 0x65, 0x64, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x23, 0x30, 0x30, 0x30, + 0x76, 0x69, 0x64, 0x65, 0x6f, 0x20, 0x67, 0x61, 0x6d, 0x65, 0x63, 0x6f, 0x6d, + 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x72, 0x65, 0x66, 0x6c, 0x65, 0x63, + 0x74, 0x69, 0x6e, 0x67, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x20, 0x74, 0x68, + 0x65, 0x61, 0x73, 0x73, 0x6f, 0x63, 0x69, 0x61, 0x74, 0x65, 0x64, 0x73, 0x61, + 0x6e, 0x73, 0x2d, 0x73, 0x65, 0x72, 0x69, 0x66, 0x6f, 0x6e, 0x6b, 0x65, 0x79, + 0x70, 0x72, 0x65, 0x73, 0x73, 0x3b, 0x20, 0x70, 0x61, 0x64, 0x64, 0x69, 0x6e, + 0x67, 0x3a, 0x48, 0x65, 0x20, 0x77, 0x61, 0x73, 0x20, 0x74, 0x68, 0x65, 0x75, + 0x6e, 0x64, 0x65, 0x72, 0x6c, 0x79, 0x69, 0x6e, 0x67, 0x74, 0x79, 0x70, 0x69, + 0x63, 0x61, 0x6c, 0x6c, 0x79, 0x20, 0x2c, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x74, + 0x68, 0x65, 0x20, 0x73, 0x72, 0x63, 0x45, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, + 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x69, 0x76, 0x65, 0x73, 0x69, 0x6e, + 0x63, 0x65, 0x20, 0x74, 0x68, 0x65, 0x20, 0x73, 0x68, 0x6f, 0x75, 0x6c, 0x64, + 0x20, 0x62, 0x65, 0x20, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x69, 0x6e, + 0x67, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x69, 0x6e, 0x67, 0x75, 0x73, + 0x65, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x6c, 0x6f, 0x77, 0x65, 0x72, + 0x20, 0x74, 0x68, 0x61, 0x6e, 0x73, 0x68, 0x6f, 0x77, 0x73, 0x20, 0x74, 0x68, + 0x61, 0x74, 0x3c, 0x2f, 0x73, 0x70, 0x61, 0x6e, 0x3e, 0x0a, 0x09, 0x09, 0x63, + 0x6f, 0x6d, 0x70, 0x6c, 0x61, 0x69, 0x6e, 0x74, 0x73, 0x63, 0x6f, 0x6e, 0x74, + 0x69, 0x6e, 0x75, 0x6f, 0x75, 0x73, 0x71, 0x75, 0x61, 0x6e, 0x74, 0x69, 0x74, + 0x69, 0x65, 0x73, 0x61, 0x73, 0x74, 0x72, 0x6f, 0x6e, 0x6f, 0x6d, 0x65, 0x72, + 0x68, 0x65, 0x20, 0x64, 0x69, 0x64, 0x20, 0x6e, 0x6f, 0x74, 0x64, 0x75, 0x65, + 0x20, 0x74, 0x6f, 0x20, 0x69, 0x74, 0x73, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x65, + 0x64, 0x20, 0x74, 0x6f, 0x61, 0x6e, 0x20, 0x61, 0x76, 0x65, 0x72, 0x61, 0x67, + 0x65, 0x65, 0x66, 0x66, 0x6f, 0x72, 0x74, 0x73, 0x20, 0x74, 0x6f, 0x74, 0x68, + 0x65, 0x20, 0x66, 0x75, 0x74, 0x75, 0x72, 0x65, 0x61, 0x74, 0x74, 0x65, 0x6d, + 0x70, 0x74, 0x20, 0x74, 0x6f, 0x54, 0x68, 0x65, 0x72, 0x65, 0x66, 0x6f, 0x72, + 0x65, 0x2c, 0x63, 0x61, 0x70, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x52, + 0x65, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x61, 0x6e, 0x77, 0x61, 0x73, 0x20, + 0x66, 0x6f, 0x72, 0x6d, 0x65, 0x64, 0x45, 0x6c, 0x65, 0x63, 0x74, 0x72, 0x6f, + 0x6e, 0x69, 0x63, 0x6b, 0x69, 0x6c, 0x6f, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, + 0x63, 0x68, 0x61, 0x6c, 0x6c, 0x65, 0x6e, 0x67, 0x65, 0x73, 0x70, 0x75, 0x62, + 0x6c, 0x69, 0x73, 0x68, 0x69, 0x6e, 0x67, 0x74, 0x68, 0x65, 0x20, 0x66, 0x6f, + 0x72, 0x6d, 0x65, 0x72, 0x69, 0x6e, 0x64, 0x69, 0x67, 0x65, 0x6e, 0x6f, 0x75, + 0x73, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x73, 0x75, + 0x62, 0x73, 0x69, 0x64, 0x69, 0x61, 0x72, 0x79, 0x63, 0x6f, 0x6e, 0x73, 0x70, + 0x69, 0x72, 0x61, 0x63, 0x79, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x20, + 0x6f, 0x66, 0x61, 0x6e, 0x64, 0x20, 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x61, + 0x66, 0x66, 0x6f, 0x72, 0x64, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x75, 0x62, 0x73, + 0x74, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x72, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x20, + 0x66, 0x6f, 0x72, 0x63, 0x6f, 0x6e, 0x76, 0x65, 0x6e, 0x74, 0x69, 0x6f, 0x6e, + 0x69, 0x74, 0x65, 0x6d, 0x74, 0x79, 0x70, 0x65, 0x3d, 0x22, 0x61, 0x62, 0x73, + 0x6f, 0x6c, 0x75, 0x74, 0x65, 0x6c, 0x79, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x73, + 0x65, 0x64, 0x6c, 0x79, 0x72, 0x65, 0x6d, 0x61, 0x69, 0x6e, 0x65, 0x64, 0x20, + 0x61, 0x61, 0x74, 0x74, 0x72, 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, 0x74, 0x72, + 0x61, 0x76, 0x65, 0x6c, 0x6c, 0x69, 0x6e, 0x67, 0x73, 0x65, 0x70, 0x61, 0x72, + 0x61, 0x74, 0x65, 0x6c, 0x79, 0x66, 0x6f, 0x63, 0x75, 0x73, 0x65, 0x73, 0x20, + 0x6f, 0x6e, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x61, 0x72, 0x79, 0x61, + 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x62, 0x6c, 0x65, 0x66, 0x6f, 0x75, 0x6e, + 0x64, 0x20, 0x74, 0x68, 0x61, 0x74, 0x73, 0x74, 0x79, 0x6c, 0x65, 0x73, 0x68, + 0x65, 0x65, 0x74, 0x6d, 0x61, 0x6e, 0x75, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, + 0x73, 0x74, 0x61, 0x6e, 0x64, 0x73, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x6e, 0x6f, + 0x2d, 0x72, 0x65, 0x70, 0x65, 0x61, 0x74, 0x28, 0x73, 0x6f, 0x6d, 0x65, 0x74, + 0x69, 0x6d, 0x65, 0x73, 0x43, 0x6f, 0x6d, 0x6d, 0x65, 0x72, 0x63, 0x69, 0x61, + 0x6c, 0x69, 0x6e, 0x20, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x75, 0x6e, + 0x64, 0x65, 0x72, 0x74, 0x61, 0x6b, 0x65, 0x6e, 0x71, 0x75, 0x61, 0x72, 0x74, + 0x65, 0x72, 0x20, 0x6f, 0x66, 0x61, 0x6e, 0x20, 0x65, 0x78, 0x61, 0x6d, 0x70, + 0x6c, 0x65, 0x70, 0x65, 0x72, 0x73, 0x6f, 0x6e, 0x61, 0x6c, 0x6c, 0x79, 0x69, + 0x6e, 0x64, 0x65, 0x78, 0x2e, 0x70, 0x68, 0x70, 0x3f, 0x3c, 0x2f, 0x62, 0x75, + 0x74, 0x74, 0x6f, 0x6e, 0x3e, 0x0a, 0x70, 0x65, 0x72, 0x63, 0x65, 0x6e, 0x74, + 0x61, 0x67, 0x65, 0x62, 0x65, 0x73, 0x74, 0x2d, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, + 0x63, 0x72, 0x65, 0x61, 0x74, 0x69, 0x6e, 0x67, 0x20, 0x61, 0x22, 0x20, 0x64, + 0x69, 0x72, 0x3d, 0x22, 0x6c, 0x74, 0x72, 0x4c, 0x69, 0x65, 0x75, 0x74, 0x65, + 0x6e, 0x61, 0x6e, 0x74, 0x0a, 0x3c, 0x64, 0x69, 0x76, 0x20, 0x69, 0x64, 0x3d, + 0x22, 0x74, 0x68, 0x65, 0x79, 0x20, 0x77, 0x6f, 0x75, 0x6c, 0x64, 0x61, 0x62, + 0x69, 0x6c, 0x69, 0x74, 0x79, 0x20, 0x6f, 0x66, 0x6d, 0x61, 0x64, 0x65, 0x20, + 0x75, 0x70, 0x20, 0x6f, 0x66, 0x6e, 0x6f, 0x74, 0x65, 0x64, 0x20, 0x74, 0x68, + 0x61, 0x74, 0x63, 0x6c, 0x65, 0x61, 0x72, 0x20, 0x74, 0x68, 0x61, 0x74, 0x61, + 0x72, 0x67, 0x75, 0x65, 0x20, 0x74, 0x68, 0x61, 0x74, 0x74, 0x6f, 0x20, 0x61, + 0x6e, 0x6f, 0x74, 0x68, 0x65, 0x72, 0x63, 0x68, 0x69, 0x6c, 0x64, 0x72, 0x65, + 0x6e, 0x27, 0x73, 0x70, 0x75, 0x72, 0x70, 0x6f, 0x73, 0x65, 0x20, 0x6f, 0x66, + 0x66, 0x6f, 0x72, 0x6d, 0x75, 0x6c, 0x61, 0x74, 0x65, 0x64, 0x62, 0x61, 0x73, + 0x65, 0x64, 0x20, 0x75, 0x70, 0x6f, 0x6e, 0x74, 0x68, 0x65, 0x20, 0x72, 0x65, + 0x67, 0x69, 0x6f, 0x6e, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x20, 0x6f, + 0x66, 0x70, 0x61, 0x73, 0x73, 0x65, 0x6e, 0x67, 0x65, 0x72, 0x73, 0x70, 0x6f, + 0x73, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x2e, 0x0a, 0x0a, 0x49, 0x6e, + 0x20, 0x74, 0x68, 0x65, 0x20, 0x42, 0x65, 0x66, 0x6f, 0x72, 0x65, 0x20, 0x74, + 0x68, 0x65, 0x61, 0x66, 0x74, 0x65, 0x72, 0x77, 0x61, 0x72, 0x64, 0x73, 0x63, + 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x6c, 0x79, 0x20, 0x61, 0x63, 0x72, 0x6f, + 0x73, 0x73, 0x20, 0x74, 0x68, 0x65, 0x73, 0x63, 0x69, 0x65, 0x6e, 0x74, 0x69, + 0x66, 0x69, 0x63, 0x63, 0x6f, 0x6d, 0x6d, 0x75, 0x6e, 0x69, 0x74, 0x79, 0x2e, + 0x63, 0x61, 0x70, 0x69, 0x74, 0x61, 0x6c, 0x69, 0x73, 0x6d, 0x69, 0x6e, 0x20, + 0x47, 0x65, 0x72, 0x6d, 0x61, 0x6e, 0x79, 0x72, 0x69, 0x67, 0x68, 0x74, 0x2d, + 0x77, 0x69, 0x6e, 0x67, 0x74, 0x68, 0x65, 0x20, 0x73, 0x79, 0x73, 0x74, 0x65, + 0x6d, 0x53, 0x6f, 0x63, 0x69, 0x65, 0x74, 0x79, 0x20, 0x6f, 0x66, 0x70, 0x6f, + 0x6c, 0x69, 0x74, 0x69, 0x63, 0x69, 0x61, 0x6e, 0x64, 0x69, 0x72, 0x65, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x77, 0x65, 0x6e, 0x74, 0x20, 0x6f, 0x6e, 0x20, + 0x74, 0x6f, 0x72, 0x65, 0x6d, 0x6f, 0x76, 0x61, 0x6c, 0x20, 0x6f, 0x66, 0x20, + 0x4e, 0x65, 0x77, 0x20, 0x59, 0x6f, 0x72, 0x6b, 0x20, 0x61, 0x70, 0x61, 0x72, + 0x74, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x69, 0x6e, 0x64, 0x69, 0x63, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x64, 0x75, 0x72, 0x69, 0x6e, 0x67, 0x20, 0x74, 0x68, 0x65, + 0x75, 0x6e, 0x6c, 0x65, 0x73, 0x73, 0x20, 0x74, 0x68, 0x65, 0x68, 0x69, 0x73, + 0x74, 0x6f, 0x72, 0x69, 0x63, 0x61, 0x6c, 0x68, 0x61, 0x64, 0x20, 0x62, 0x65, + 0x65, 0x6e, 0x20, 0x61, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x76, + 0x65, 0x69, 0x6e, 0x67, 0x72, 0x65, 0x64, 0x69, 0x65, 0x6e, 0x74, 0x61, 0x74, + 0x74, 0x65, 0x6e, 0x64, 0x61, 0x6e, 0x63, 0x65, 0x43, 0x65, 0x6e, 0x74, 0x65, + 0x72, 0x20, 0x66, 0x6f, 0x72, 0x70, 0x72, 0x6f, 0x6d, 0x69, 0x6e, 0x65, 0x6e, + 0x63, 0x65, 0x72, 0x65, 0x61, 0x64, 0x79, 0x53, 0x74, 0x61, 0x74, 0x65, 0x73, + 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x69, 0x65, 0x73, 0x62, 0x75, 0x74, 0x20, + 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x61, 0x73, 0x20, 0x70, 0x61, 0x72, 0x74, + 0x20, 0x6f, 0x66, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x69, 0x74, 0x75, 0x74, 0x65, + 0x63, 0x6c, 0x61, 0x69, 0x6d, 0x20, 0x74, 0x68, 0x61, 0x74, 0x6c, 0x61, 0x62, + 0x6f, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x79, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x74, + 0x69, 0x62, 0x6c, 0x65, 0x66, 0x61, 0x69, 0x6c, 0x75, 0x72, 0x65, 0x20, 0x6f, + 0x66, 0x2c, 0x20, 0x73, 0x75, 0x63, 0x68, 0x20, 0x61, 0x73, 0x20, 0x62, 0x65, + 0x67, 0x61, 0x6e, 0x20, 0x77, 0x69, 0x74, 0x68, 0x75, 0x73, 0x69, 0x6e, 0x67, + 0x20, 0x74, 0x68, 0x65, 0x20, 0x74, 0x6f, 0x20, 0x70, 0x72, 0x6f, 0x76, 0x69, + 0x64, 0x65, 0x66, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x20, 0x6f, 0x66, 0x66, + 0x72, 0x6f, 0x6d, 0x20, 0x77, 0x68, 0x69, 0x63, 0x68, 0x2f, 0x22, 0x20, 0x63, + 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x22, 0x67, 0x65, 0x6f, 0x6c, 0x6f, 0x67, 0x69, + 0x63, 0x61, 0x6c, 0x73, 0x65, 0x76, 0x65, 0x72, 0x61, 0x6c, 0x20, 0x6f, 0x66, + 0x64, 0x65, 0x6c, 0x69, 0x62, 0x65, 0x72, 0x61, 0x74, 0x65, 0x69, 0x6d, 0x70, + 0x6f, 0x72, 0x74, 0x61, 0x6e, 0x74, 0x20, 0x68, 0x6f, 0x6c, 0x64, 0x73, 0x20, + 0x74, 0x68, 0x61, 0x74, 0x69, 0x6e, 0x67, 0x26, 0x71, 0x75, 0x6f, 0x74, 0x3b, + 0x20, 0x76, 0x61, 0x6c, 0x69, 0x67, 0x6e, 0x3d, 0x74, 0x6f, 0x70, 0x74, 0x68, + 0x65, 0x20, 0x47, 0x65, 0x72, 0x6d, 0x61, 0x6e, 0x6f, 0x75, 0x74, 0x73, 0x69, + 0x64, 0x65, 0x20, 0x6f, 0x66, 0x6e, 0x65, 0x67, 0x6f, 0x74, 0x69, 0x61, 0x74, + 0x65, 0x64, 0x68, 0x69, 0x73, 0x20, 0x63, 0x61, 0x72, 0x65, 0x65, 0x72, 0x73, + 0x65, 0x70, 0x61, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x69, 0x64, 0x3d, 0x22, + 0x73, 0x65, 0x61, 0x72, 0x63, 0x68, 0x77, 0x61, 0x73, 0x20, 0x63, 0x61, 0x6c, + 0x6c, 0x65, 0x64, 0x74, 0x68, 0x65, 0x20, 0x66, 0x6f, 0x75, 0x72, 0x74, 0x68, + 0x72, 0x65, 0x63, 0x72, 0x65, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x6f, 0x74, 0x68, + 0x65, 0x72, 0x20, 0x74, 0x68, 0x61, 0x6e, 0x70, 0x72, 0x65, 0x76, 0x65, 0x6e, + 0x74, 0x69, 0x6f, 0x6e, 0x77, 0x68, 0x69, 0x6c, 0x65, 0x20, 0x74, 0x68, 0x65, + 0x20, 0x65, 0x64, 0x75, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2c, 0x63, 0x6f, + 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6e, 0x67, 0x61, 0x63, 0x63, 0x75, 0x72, + 0x61, 0x74, 0x65, 0x6c, 0x79, 0x77, 0x65, 0x72, 0x65, 0x20, 0x62, 0x75, 0x69, + 0x6c, 0x74, 0x77, 0x61, 0x73, 0x20, 0x6b, 0x69, 0x6c, 0x6c, 0x65, 0x64, 0x61, + 0x67, 0x72, 0x65, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x6d, 0x75, 0x63, 0x68, + 0x20, 0x6d, 0x6f, 0x72, 0x65, 0x20, 0x44, 0x75, 0x65, 0x20, 0x74, 0x6f, 0x20, + 0x74, 0x68, 0x65, 0x77, 0x69, 0x64, 0x74, 0x68, 0x3a, 0x20, 0x31, 0x30, 0x30, + 0x73, 0x6f, 0x6d, 0x65, 0x20, 0x6f, 0x74, 0x68, 0x65, 0x72, 0x4b, 0x69, 0x6e, + 0x67, 0x64, 0x6f, 0x6d, 0x20, 0x6f, 0x66, 0x74, 0x68, 0x65, 0x20, 0x65, 0x6e, + 0x74, 0x69, 0x72, 0x65, 0x66, 0x61, 0x6d, 0x6f, 0x75, 0x73, 0x20, 0x66, 0x6f, + 0x72, 0x74, 0x6f, 0x20, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x6f, 0x62, + 0x6a, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x73, 0x74, 0x68, 0x65, 0x20, 0x46, + 0x72, 0x65, 0x6e, 0x63, 0x68, 0x70, 0x65, 0x6f, 0x70, 0x6c, 0x65, 0x20, 0x61, + 0x6e, 0x64, 0x66, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x64, 0x22, 0x3e, 0x69, + 0x73, 0x20, 0x73, 0x61, 0x69, 0x64, 0x20, 0x74, 0x6f, 0x73, 0x74, 0x72, 0x75, + 0x63, 0x74, 0x75, 0x72, 0x61, 0x6c, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, + 0x64, 0x75, 0x6d, 0x6d, 0x6f, 0x73, 0x74, 0x20, 0x6f, 0x66, 0x74, 0x65, 0x6e, + 0x61, 0x20, 0x73, 0x65, 0x70, 0x61, 0x72, 0x61, 0x74, 0x65, 0x2d, 0x3e, 0x0a, + 0x3c, 0x64, 0x69, 0x76, 0x20, 0x69, 0x64, 0x20, 0x4f, 0x66, 0x66, 0x69, 0x63, + 0x69, 0x61, 0x6c, 0x20, 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x77, 0x69, 0x64, 0x65, + 0x2e, 0x61, 0x72, 0x69, 0x61, 0x2d, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x74, 0x68, + 0x65, 0x20, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x74, 0x61, 0x6e, 0x64, 0x20, 0x69, + 0x74, 0x20, 0x77, 0x61, 0x73, 0x64, 0x22, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, + 0x3d, 0x22, 0x6c, 0x6f, 0x6f, 0x6b, 0x69, 0x6e, 0x67, 0x20, 0x61, 0x74, 0x62, + 0x65, 0x6e, 0x65, 0x66, 0x69, 0x63, 0x69, 0x61, 0x6c, 0x61, 0x72, 0x65, 0x20, + 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, + 0x69, 0x6e, 0x67, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x6c, 0x79, + 0x74, 0x68, 0x65, 0x20, 0x6d, 0x6f, 0x64, 0x65, 0x72, 0x6e, 0x77, 0x6f, 0x72, + 0x6b, 0x69, 0x6e, 0x67, 0x20, 0x6f, 0x6e, 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x65, + 0x64, 0x20, 0x74, 0x6f, 0x77, 0x68, 0x65, 0x72, 0x65, 0x20, 0x74, 0x68, 0x65, + 0x20, 0x69, 0x6e, 0x6e, 0x6f, 0x76, 0x61, 0x74, 0x69, 0x76, 0x65, 0x3c, 0x2f, + 0x61, 0x3e, 0x3c, 0x2f, 0x64, 0x69, 0x76, 0x3e, 0x73, 0x6f, 0x75, 0x6e, 0x64, + 0x74, 0x72, 0x61, 0x63, 0x6b, 0x73, 0x65, 0x61, 0x72, 0x63, 0x68, 0x46, 0x6f, + 0x72, 0x6d, 0x74, 0x65, 0x6e, 0x64, 0x20, 0x74, 0x6f, 0x20, 0x62, 0x65, 0x69, + 0x6e, 0x70, 0x75, 0x74, 0x20, 0x69, 0x64, 0x3d, 0x22, 0x6f, 0x70, 0x65, 0x6e, + 0x69, 0x6e, 0x67, 0x20, 0x6f, 0x66, 0x72, 0x65, 0x73, 0x74, 0x72, 0x69, 0x63, + 0x74, 0x65, 0x64, 0x61, 0x64, 0x6f, 0x70, 0x74, 0x65, 0x64, 0x20, 0x62, 0x79, + 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x69, 0x6e, 0x67, 0x74, 0x68, 0x65, + 0x6f, 0x6c, 0x6f, 0x67, 0x69, 0x61, 0x6e, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, + 0x73, 0x20, 0x6f, 0x66, 0x76, 0x61, 0x72, 0x69, 0x61, 0x6e, 0x74, 0x20, 0x6f, + 0x66, 0x43, 0x68, 0x72, 0x69, 0x73, 0x74, 0x69, 0x61, 0x6e, 0x20, 0x76, 0x65, + 0x72, 0x79, 0x20, 0x6c, 0x61, 0x72, 0x67, 0x65, 0x61, 0x75, 0x74, 0x6f, 0x6d, + 0x6f, 0x74, 0x69, 0x76, 0x65, 0x62, 0x79, 0x20, 0x66, 0x61, 0x72, 0x20, 0x74, + 0x68, 0x65, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x20, 0x66, 0x72, 0x6f, 0x6d, 0x70, + 0x75, 0x72, 0x73, 0x75, 0x69, 0x74, 0x20, 0x6f, 0x66, 0x66, 0x6f, 0x6c, 0x6c, + 0x6f, 0x77, 0x20, 0x74, 0x68, 0x65, 0x62, 0x72, 0x6f, 0x75, 0x67, 0x68, 0x74, + 0x20, 0x74, 0x6f, 0x69, 0x6e, 0x20, 0x45, 0x6e, 0x67, 0x6c, 0x61, 0x6e, 0x64, + 0x61, 0x67, 0x72, 0x65, 0x65, 0x20, 0x74, 0x68, 0x61, 0x74, 0x61, 0x63, 0x63, + 0x75, 0x73, 0x65, 0x64, 0x20, 0x6f, 0x66, 0x63, 0x6f, 0x6d, 0x65, 0x73, 0x20, + 0x66, 0x72, 0x6f, 0x6d, 0x70, 0x72, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x69, 0x6e, + 0x67, 0x64, 0x69, 0x76, 0x20, 0x73, 0x74, 0x79, 0x6c, 0x65, 0x3d, 0x68, 0x69, + 0x73, 0x20, 0x6f, 0x72, 0x20, 0x68, 0x65, 0x72, 0x74, 0x72, 0x65, 0x6d, 0x65, + 0x6e, 0x64, 0x6f, 0x75, 0x73, 0x66, 0x72, 0x65, 0x65, 0x64, 0x6f, 0x6d, 0x20, + 0x6f, 0x66, 0x63, 0x6f, 0x6e, 0x63, 0x65, 0x72, 0x6e, 0x69, 0x6e, 0x67, 0x30, + 0x20, 0x31, 0x65, 0x6d, 0x20, 0x31, 0x65, 0x6d, 0x3b, 0x42, 0x61, 0x73, 0x6b, + 0x65, 0x74, 0x62, 0x61, 0x6c, 0x6c, 0x2f, 0x73, 0x74, 0x79, 0x6c, 0x65, 0x2e, + 0x63, 0x73, 0x73, 0x61, 0x6e, 0x20, 0x65, 0x61, 0x72, 0x6c, 0x69, 0x65, 0x72, + 0x65, 0x76, 0x65, 0x6e, 0x20, 0x61, 0x66, 0x74, 0x65, 0x72, 0x2f, 0x22, 0x20, + 0x74, 0x69, 0x74, 0x6c, 0x65, 0x3d, 0x22, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x69, + 0x6e, 0x64, 0x65, 0x78, 0x74, 0x61, 0x6b, 0x69, 0x6e, 0x67, 0x20, 0x74, 0x68, + 0x65, 0x70, 0x69, 0x74, 0x74, 0x73, 0x62, 0x75, 0x72, 0x67, 0x68, 0x63, 0x6f, + 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x22, 0x3e, 0x0d, 0x3c, 0x73, 0x63, 0x72, 0x69, + 0x70, 0x74, 0x3e, 0x28, 0x66, 0x74, 0x75, 0x72, 0x6e, 0x65, 0x64, 0x20, 0x6f, + 0x75, 0x74, 0x68, 0x61, 0x76, 0x69, 0x6e, 0x67, 0x20, 0x74, 0x68, 0x65, 0x3c, + 0x2f, 0x73, 0x70, 0x61, 0x6e, 0x3e, 0x0d, 0x0a, 0x20, 0x6f, 0x63, 0x63, 0x61, + 0x73, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x62, 0x65, 0x63, 0x61, 0x75, 0x73, 0x65, + 0x20, 0x69, 0x74, 0x73, 0x74, 0x61, 0x72, 0x74, 0x65, 0x64, 0x20, 0x74, 0x6f, + 0x70, 0x68, 0x79, 0x73, 0x69, 0x63, 0x61, 0x6c, 0x6c, 0x79, 0x3e, 0x3c, 0x2f, + 0x64, 0x69, 0x76, 0x3e, 0x0a, 0x20, 0x20, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, + 0x64, 0x20, 0x62, 0x79, 0x43, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x6c, 0x79, + 0x2c, 0x20, 0x62, 0x67, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3d, 0x22, 0x74, 0x61, + 0x62, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x3d, 0x22, 0x64, 0x69, 0x73, 0x61, 0x73, + 0x74, 0x72, 0x6f, 0x75, 0x73, 0x41, 0x6e, 0x61, 0x6c, 0x79, 0x74, 0x69, 0x63, + 0x73, 0x20, 0x61, 0x6c, 0x73, 0x6f, 0x20, 0x68, 0x61, 0x73, 0x20, 0x61, 0x3e, + 0x3c, 0x64, 0x69, 0x76, 0x20, 0x69, 0x64, 0x3d, 0x22, 0x3c, 0x2f, 0x73, 0x74, + 0x79, 0x6c, 0x65, 0x3e, 0x0a, 0x3c, 0x63, 0x61, 0x6c, 0x6c, 0x65, 0x64, 0x20, + 0x66, 0x6f, 0x72, 0x73, 0x69, 0x6e, 0x67, 0x65, 0x72, 0x20, 0x61, 0x6e, 0x64, + 0x2e, 0x73, 0x72, 0x63, 0x20, 0x3d, 0x20, 0x22, 0x2f, 0x2f, 0x76, 0x69, 0x6f, + 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x74, 0x68, 0x69, 0x73, 0x20, 0x70, + 0x6f, 0x69, 0x6e, 0x74, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x74, 0x6c, + 0x79, 0x69, 0x73, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x65, 0x64, 0x72, 0x65, + 0x63, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x67, 0x73, 0x64, 0x20, 0x66, 0x72, 0x6f, + 0x6d, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x65, 0x64, 0x65, 0x72, 0x6c, 0x61, 0x6e, + 0x64, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x75, 0x67, 0x75, 0xc3, 0xaa, 0x73, 0xd7, + 0xa2, 0xd7, 0x91, 0xd7, 0xa8, 0xd7, 0x99, 0xd7, 0xaa, 0xd9, 0x81, 0xd8, 0xa7, + 0xd8, 0xb1, 0xd8, 0xb3, 0xdb, 0x8c, 0x64, 0x65, 0x73, 0x61, 0x72, 0x72, 0x6f, + 0x6c, 0x6c, 0x6f, 0x63, 0x6f, 0x6d, 0x65, 0x6e, 0x74, 0x61, 0x72, 0x69, 0x6f, + 0x65, 0x64, 0x75, 0x63, 0x61, 0x63, 0x69, 0xc3, 0xb3, 0x6e, 0x73, 0x65, 0x70, + 0x74, 0x69, 0x65, 0x6d, 0x62, 0x72, 0x65, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, + 0x72, 0x61, 0x64, 0x6f, 0x64, 0x69, 0x72, 0x65, 0x63, 0x63, 0x69, 0xc3, 0xb3, + 0x6e, 0x75, 0x62, 0x69, 0x63, 0x61, 0x63, 0x69, 0xc3, 0xb3, 0x6e, 0x70, 0x75, + 0x62, 0x6c, 0x69, 0x63, 0x69, 0x64, 0x61, 0x64, 0x72, 0x65, 0x73, 0x70, 0x75, + 0x65, 0x73, 0x74, 0x61, 0x73, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x61, 0x64, + 0x6f, 0x73, 0x69, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x61, 0x6e, 0x74, 0x65, 0x72, + 0x65, 0x73, 0x65, 0x72, 0x76, 0x61, 0x64, 0x6f, 0x73, 0x61, 0x72, 0x74, 0xc3, + 0xad, 0x63, 0x75, 0x6c, 0x6f, 0x73, 0x64, 0x69, 0x66, 0x65, 0x72, 0x65, 0x6e, + 0x74, 0x65, 0x73, 0x73, 0x69, 0x67, 0x75, 0x69, 0x65, 0x6e, 0x74, 0x65, 0x73, + 0x72, 0x65, 0x70, 0xc3, 0xba, 0x62, 0x6c, 0x69, 0x63, 0x61, 0x73, 0x69, 0x74, + 0x75, 0x61, 0x63, 0x69, 0xc3, 0xb3, 0x6e, 0x6d, 0x69, 0x6e, 0x69, 0x73, 0x74, + 0x65, 0x72, 0x69, 0x6f, 0x70, 0x72, 0x69, 0x76, 0x61, 0x63, 0x69, 0x64, 0x61, + 0x64, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x69, 0x6f, 0x66, 0x6f, + 0x72, 0x6d, 0x61, 0x63, 0x69, 0xc3, 0xb3, 0x6e, 0x70, 0x6f, 0x62, 0x6c, 0x61, + 0x63, 0x69, 0xc3, 0xb3, 0x6e, 0x70, 0x72, 0x65, 0x73, 0x69, 0x64, 0x65, 0x6e, + 0x74, 0x65, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x69, 0x64, 0x6f, 0x73, 0x61, + 0x63, 0x63, 0x65, 0x73, 0x6f, 0x72, 0x69, 0x6f, 0x73, 0x74, 0x65, 0x63, 0x68, + 0x6e, 0x6f, 0x72, 0x61, 0x74, 0x69, 0x70, 0x65, 0x72, 0x73, 0x6f, 0x6e, 0x61, + 0x6c, 0x65, 0x73, 0x63, 0x61, 0x74, 0x65, 0x67, 0x6f, 0x72, 0xc3, 0xad, 0x61, + 0x65, 0x73, 0x70, 0x65, 0x63, 0x69, 0x61, 0x6c, 0x65, 0x73, 0x64, 0x69, 0x73, + 0x70, 0x6f, 0x6e, 0x69, 0x62, 0x6c, 0x65, 0x61, 0x63, 0x74, 0x75, 0x61, 0x6c, + 0x69, 0x64, 0x61, 0x64, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x69, + 0x61, 0x76, 0x61, 0x6c, 0x6c, 0x61, 0x64, 0x6f, 0x6c, 0x69, 0x64, 0x62, 0x69, + 0x62, 0x6c, 0x69, 0x6f, 0x74, 0x65, 0x63, 0x61, 0x72, 0x65, 0x6c, 0x61, 0x63, + 0x69, 0x6f, 0x6e, 0x65, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x6e, 0x64, 0x61, 0x72, + 0x69, 0x6f, 0x70, 0x6f, 0x6c, 0xc3, 0xad, 0x74, 0x69, 0x63, 0x61, 0x73, 0x61, + 0x6e, 0x74, 0x65, 0x72, 0x69, 0x6f, 0x72, 0x65, 0x73, 0x64, 0x6f, 0x63, 0x75, + 0x6d, 0x65, 0x6e, 0x74, 0x6f, 0x73, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x61, 0x6c, + 0x65, 0x7a, 0x61, 0x6d, 0x61, 0x74, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x65, 0x73, + 0x64, 0x69, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x69, 0x61, 0x65, 0x63, 0x6f, + 0x6e, 0xc3, 0xb3, 0x6d, 0x69, 0x63, 0x61, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x70, + 0x6f, 0x72, 0x74, 0x65, 0x72, 0x6f, 0x64, 0x72, 0xc3, 0xad, 0x67, 0x75, 0x65, + 0x7a, 0x70, 0x61, 0x72, 0x74, 0x69, 0x63, 0x69, 0x70, 0x61, 0x72, 0x65, 0x6e, + 0x63, 0x75, 0x65, 0x6e, 0x74, 0x72, 0x61, 0x6e, 0x64, 0x69, 0x73, 0x63, 0x75, + 0x73, 0x69, 0xc3, 0xb3, 0x6e, 0x65, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x75, + 0x72, 0x61, 0x66, 0x75, 0x6e, 0x64, 0x61, 0x63, 0x69, 0xc3, 0xb3, 0x6e, 0x66, + 0x72, 0x65, 0x63, 0x75, 0x65, 0x6e, 0x74, 0x65, 0x73, 0x70, 0x65, 0x72, 0x6d, + 0x61, 0x6e, 0x65, 0x6e, 0x74, 0x65, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x6d, 0x65, + 0x6e, 0x74, 0x65, 0xd0, 0xbc, 0xd0, 0xbe, 0xd0, 0xb6, 0xd0, 0xbd, 0xd0, 0xbe, + 0xd0, 0xb1, 0xd1, 0x83, 0xd0, 0xb4, 0xd0, 0xb5, 0xd1, 0x82, 0xd0, 0xbc, 0xd0, + 0xbe, 0xd0, 0xb6, 0xd0, 0xb5, 0xd1, 0x82, 0xd0, 0xb2, 0xd1, 0x80, 0xd0, 0xb5, + 0xd0, 0xbc, 0xd1, 0x8f, 0xd1, 0x82, 0xd0, 0xb0, 0xd0, 0xba, 0xd0, 0xb6, 0xd0, + 0xb5, 0xd1, 0x87, 0xd1, 0x82, 0xd0, 0xbe, 0xd0, 0xb1, 0xd1, 0x8b, 0xd0, 0xb1, + 0xd0, 0xbe, 0xd0, 0xbb, 0xd0, 0xb5, 0xd0, 0xb5, 0xd0, 0xbe, 0xd1, 0x87, 0xd0, + 0xb5, 0xd0, 0xbd, 0xd1, 0x8c, 0xd1, 0x8d, 0xd1, 0x82, 0xd0, 0xbe, 0xd0, 0xb3, + 0xd0, 0xbe, 0xd0, 0xba, 0xd0, 0xbe, 0xd0, 0xb3, 0xd0, 0xb4, 0xd0, 0xb0, 0xd0, + 0xbf, 0xd0, 0xbe, 0xd1, 0x81, 0xd0, 0xbb, 0xd0, 0xb5, 0xd0, 0xb2, 0xd1, 0x81, + 0xd0, 0xb5, 0xd0, 0xb3, 0xd0, 0xbe, 0xd1, 0x81, 0xd0, 0xb0, 0xd0, 0xb9, 0xd1, + 0x82, 0xd0, 0xb5, 0xd1, 0x87, 0xd0, 0xb5, 0xd1, 0x80, 0xd0, 0xb5, 0xd0, 0xb7, + 0xd0, 0xbc, 0xd0, 0xbe, 0xd0, 0xb3, 0xd1, 0x83, 0xd1, 0x82, 0xd1, 0x81, 0xd0, + 0xb0, 0xd0, 0xb9, 0xd1, 0x82, 0xd0, 0xb0, 0xd0, 0xb6, 0xd0, 0xb8, 0xd0, 0xb7, + 0xd0, 0xbd, 0xd0, 0xb8, 0xd0, 0xbc, 0xd0, 0xb5, 0xd0, 0xb6, 0xd0, 0xb4, 0xd1, + 0x83, 0xd0, 0xb1, 0xd1, 0x83, 0xd0, 0xb4, 0xd1, 0x83, 0xd1, 0x82, 0xd0, 0x9f, + 0xd0, 0xbe, 0xd0, 0xb8, 0xd1, 0x81, 0xd0, 0xba, 0xd0, 0xb7, 0xd0, 0xb4, 0xd0, + 0xb5, 0xd1, 0x81, 0xd1, 0x8c, 0xd0, 0xb2, 0xd0, 0xb8, 0xd0, 0xb4, 0xd0, 0xb5, + 0xd0, 0xbe, 0xd1, 0x81, 0xd0, 0xb2, 0xd1, 0x8f, 0xd0, 0xb7, 0xd0, 0xb8, 0xd0, + 0xbd, 0xd1, 0x83, 0xd0, 0xb6, 0xd0, 0xbd, 0xd0, 0xbe, 0xd1, 0x81, 0xd0, 0xb2, + 0xd0, 0xbe, 0xd0, 0xb5, 0xd0, 0xb9, 0xd0, 0xbb, 0xd1, 0x8e, 0xd0, 0xb4, 0xd0, + 0xb5, 0xd0, 0xb9, 0xd0, 0xbf, 0xd0, 0xbe, 0xd1, 0x80, 0xd0, 0xbd, 0xd0, 0xbe, + 0xd0, 0xbc, 0xd0, 0xbd, 0xd0, 0xbe, 0xd0, 0xb3, 0xd0, 0xbe, 0xd0, 0xb4, 0xd0, + 0xb5, 0xd1, 0x82, 0xd0, 0xb5, 0xd0, 0xb9, 0xd1, 0x81, 0xd0, 0xb2, 0xd0, 0xbe, + 0xd0, 0xb8, 0xd1, 0x85, 0xd0, 0xbf, 0xd1, 0x80, 0xd0, 0xb0, 0xd0, 0xb2, 0xd0, + 0xb0, 0xd1, 0x82, 0xd0, 0xb0, 0xd0, 0xba, 0xd0, 0xbe, 0xd0, 0xb9, 0xd0, 0xbc, + 0xd0, 0xb5, 0xd1, 0x81, 0xd1, 0x82, 0xd0, 0xbe, 0xd0, 0xb8, 0xd0, 0xbc, 0xd0, + 0xb5, 0xd0, 0xb5, 0xd1, 0x82, 0xd0, 0xb6, 0xd0, 0xb8, 0xd0, 0xb7, 0xd0, 0xbd, + 0xd1, 0x8c, 0xd0, 0xbe, 0xd0, 0xb4, 0xd0, 0xbd, 0xd0, 0xbe, 0xd0, 0xb9, 0xd0, + 0xbb, 0xd1, 0x83, 0xd1, 0x87, 0xd1, 0x88, 0xd0, 0xb5, 0xd0, 0xbf, 0xd0, 0xb5, + 0xd1, 0x80, 0xd0, 0xb5, 0xd0, 0xb4, 0xd1, 0x87, 0xd0, 0xb0, 0xd1, 0x81, 0xd1, + 0x82, 0xd0, 0xb8, 0xd1, 0x87, 0xd0, 0xb0, 0xd1, 0x81, 0xd1, 0x82, 0xd1, 0x8c, + 0xd1, 0x80, 0xd0, 0xb0, 0xd0, 0xb1, 0xd0, 0xbe, 0xd1, 0x82, 0xd0, 0xbd, 0xd0, + 0xbe, 0xd0, 0xb2, 0xd1, 0x8b, 0xd1, 0x85, 0xd0, 0xbf, 0xd1, 0x80, 0xd0, 0xb0, + 0xd0, 0xb2, 0xd0, 0xbe, 0xd1, 0x81, 0xd0, 0xbe, 0xd0, 0xb1, 0xd0, 0xbe, 0xd0, + 0xb9, 0xd0, 0xbf, 0xd0, 0xbe, 0xd1, 0x82, 0xd0, 0xbe, 0xd0, 0xbc, 0xd0, 0xbc, + 0xd0, 0xb5, 0xd0, 0xbd, 0xd0, 0xb5, 0xd0, 0xb5, 0xd1, 0x87, 0xd0, 0xb8, 0xd1, + 0x81, 0xd0, 0xbb, 0xd0, 0xb5, 0xd0, 0xbd, 0xd0, 0xbe, 0xd0, 0xb2, 0xd1, 0x8b, + 0xd0, 0xb5, 0xd1, 0x83, 0xd1, 0x81, 0xd0, 0xbb, 0xd1, 0x83, 0xd0, 0xb3, 0xd0, + 0xbe, 0xd0, 0xba, 0xd0, 0xbe, 0xd0, 0xbb, 0xd0, 0xbe, 0xd0, 0xbd, 0xd0, 0xb0, + 0xd0, 0xb7, 0xd0, 0xb0, 0xd0, 0xb4, 0xd1, 0x82, 0xd0, 0xb0, 0xd0, 0xba, 0xd0, + 0xbe, 0xd0, 0xb5, 0xd1, 0x82, 0xd0, 0xbe, 0xd0, 0xb3, 0xd0, 0xb4, 0xd0, 0xb0, + 0xd0, 0xbf, 0xd0, 0xbe, 0xd1, 0x87, 0xd1, 0x82, 0xd0, 0xb8, 0xd0, 0x9f, 0xd0, + 0xbe, 0xd1, 0x81, 0xd0, 0xbb, 0xd0, 0xb5, 0xd1, 0x82, 0xd0, 0xb0, 0xd0, 0xba, + 0xd0, 0xb8, 0xd0, 0xb5, 0xd0, 0xbd, 0xd0, 0xbe, 0xd0, 0xb2, 0xd1, 0x8b, 0xd0, + 0xb9, 0xd1, 0x81, 0xd1, 0x82, 0xd0, 0xbe, 0xd0, 0xb8, 0xd1, 0x82, 0xd1, 0x82, + 0xd0, 0xb0, 0xd0, 0xba, 0xd0, 0xb8, 0xd1, 0x85, 0xd1, 0x81, 0xd1, 0x80, 0xd0, + 0xb0, 0xd0, 0xb7, 0xd1, 0x83, 0xd0, 0xa1, 0xd0, 0xb0, 0xd0, 0xbd, 0xd0, 0xba, + 0xd1, 0x82, 0xd1, 0x84, 0xd0, 0xbe, 0xd1, 0x80, 0xd1, 0x83, 0xd0, 0xbc, 0xd0, + 0x9a, 0xd0, 0xbe, 0xd0, 0xb3, 0xd0, 0xb4, 0xd0, 0xb0, 0xd0, 0xba, 0xd0, 0xbd, + 0xd0, 0xb8, 0xd0, 0xb3, 0xd0, 0xb8, 0xd1, 0x81, 0xd0, 0xbb, 0xd0, 0xbe, 0xd0, + 0xb2, 0xd0, 0xb0, 0xd0, 0xbd, 0xd0, 0xb0, 0xd1, 0x88, 0xd0, 0xb5, 0xd0, 0xb9, + 0xd0, 0xbd, 0xd0, 0xb0, 0xd0, 0xb9, 0xd1, 0x82, 0xd0, 0xb8, 0xd1, 0x81, 0xd0, + 0xb2, 0xd0, 0xbe, 0xd0, 0xb8, 0xd0, 0xbc, 0xd1, 0x81, 0xd0, 0xb2, 0xd1, 0x8f, + 0xd0, 0xb7, 0xd1, 0x8c, 0xd0, 0xbb, 0xd1, 0x8e, 0xd0, 0xb1, 0xd0, 0xbe, 0xd0, + 0xb9, 0xd1, 0x87, 0xd0, 0xb0, 0xd1, 0x81, 0xd1, 0x82, 0xd0, 0xbe, 0xd1, 0x81, + 0xd1, 0x80, 0xd0, 0xb5, 0xd0, 0xb4, 0xd0, 0xb8, 0xd0, 0x9a, 0xd1, 0x80, 0xd0, + 0xbe, 0xd0, 0xbc, 0xd0, 0xb5, 0xd0, 0xa4, 0xd0, 0xbe, 0xd1, 0x80, 0xd1, 0x83, + 0xd0, 0xbc, 0xd1, 0x80, 0xd1, 0x8b, 0xd0, 0xbd, 0xd0, 0xba, 0xd0, 0xb5, 0xd1, + 0x81, 0xd1, 0x82, 0xd0, 0xb0, 0xd0, 0xbb, 0xd0, 0xb8, 0xd0, 0xbf, 0xd0, 0xbe, + 0xd0, 0xb8, 0xd1, 0x81, 0xd0, 0xba, 0xd1, 0x82, 0xd1, 0x8b, 0xd1, 0x81, 0xd1, + 0x8f, 0xd1, 0x87, 0xd0, 0xbc, 0xd0, 0xb5, 0xd1, 0x81, 0xd1, 0x8f, 0xd1, 0x86, + 0xd1, 0x86, 0xd0, 0xb5, 0xd0, 0xbd, 0xd1, 0x82, 0xd1, 0x80, 0xd1, 0x82, 0xd1, + 0x80, 0xd1, 0x83, 0xd0, 0xb4, 0xd0, 0xb0, 0xd1, 0x81, 0xd0, 0xb0, 0xd0, 0xbc, + 0xd1, 0x8b, 0xd1, 0x85, 0xd1, 0x80, 0xd1, 0x8b, 0xd0, 0xbd, 0xd0, 0xba, 0xd0, + 0xb0, 0xd0, 0x9d, 0xd0, 0xbe, 0xd0, 0xb2, 0xd1, 0x8b, 0xd0, 0xb9, 0xd1, 0x87, + 0xd0, 0xb0, 0xd1, 0x81, 0xd0, 0xbe, 0xd0, 0xb2, 0xd0, 0xbc, 0xd0, 0xb5, 0xd1, + 0x81, 0xd1, 0x82, 0xd0, 0xb0, 0xd1, 0x84, 0xd0, 0xb8, 0xd0, 0xbb, 0xd1, 0x8c, + 0xd0, 0xbc, 0xd0, 0xbc, 0xd0, 0xb0, 0xd1, 0x80, 0xd1, 0x82, 0xd0, 0xb0, 0xd1, + 0x81, 0xd1, 0x82, 0xd1, 0x80, 0xd0, 0xb0, 0xd0, 0xbd, 0xd0, 0xbc, 0xd0, 0xb5, + 0xd1, 0x81, 0xd1, 0x82, 0xd0, 0xb5, 0xd1, 0x82, 0xd0, 0xb5, 0xd0, 0xba, 0xd1, + 0x81, 0xd1, 0x82, 0xd0, 0xbd, 0xd0, 0xb0, 0xd1, 0x88, 0xd0, 0xb8, 0xd1, 0x85, + 0xd0, 0xbc, 0xd0, 0xb8, 0xd0, 0xbd, 0xd1, 0x83, 0xd1, 0x82, 0xd0, 0xb8, 0xd0, + 0xbc, 0xd0, 0xb5, 0xd0, 0xbd, 0xd0, 0xb8, 0xd0, 0xb8, 0xd0, 0xbc, 0xd0, 0xb5, + 0xd1, 0x8e, 0xd1, 0x82, 0xd0, 0xbd, 0xd0, 0xbe, 0xd0, 0xbc, 0xd0, 0xb5, 0xd1, + 0x80, 0xd0, 0xb3, 0xd0, 0xbe, 0xd1, 0x80, 0xd0, 0xbe, 0xd0, 0xb4, 0xd1, 0x81, + 0xd0, 0xb0, 0xd0, 0xbc, 0xd0, 0xbe, 0xd0, 0xbc, 0xd1, 0x8d, 0xd1, 0x82, 0xd0, + 0xbe, 0xd0, 0xbc, 0xd1, 0x83, 0xd0, 0xba, 0xd0, 0xbe, 0xd0, 0xbd, 0xd1, 0x86, + 0xd0, 0xb5, 0xd1, 0x81, 0xd0, 0xb2, 0xd0, 0xbe, 0xd0, 0xb5, 0xd0, 0xbc, 0xd0, + 0xba, 0xd0, 0xb0, 0xd0, 0xba, 0xd0, 0xbe, 0xd0, 0xb9, 0xd0, 0x90, 0xd1, 0x80, + 0xd1, 0x85, 0xd0, 0xb8, 0xd0, 0xb2, 0xd9, 0x85, 0xd9, 0x86, 0xd8, 0xaa, 0xd8, + 0xaf, 0xd9, 0x89, 0xd8, 0xa5, 0xd8, 0xb1, 0xd8, 0xb3, 0xd8, 0xa7, 0xd9, 0x84, + 0xd8, 0xb1, 0xd8, 0xb3, 0xd8, 0xa7, 0xd9, 0x84, 0xd8, 0xa9, 0xd8, 0xa7, 0xd9, + 0x84, 0xd8, 0xb9, 0xd8, 0xa7, 0xd9, 0x85, 0xd9, 0x83, 0xd8, 0xaa, 0xd8, 0xa8, + 0xd9, 0x87, 0xd8, 0xa7, 0xd8, 0xa8, 0xd8, 0xb1, 0xd8, 0xa7, 0xd9, 0x85, 0xd8, + 0xac, 0xd8, 0xa7, 0xd9, 0x84, 0xd9, 0x8a, 0xd9, 0x88, 0xd9, 0x85, 0xd8, 0xa7, + 0xd9, 0x84, 0xd8, 0xb5, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xac, 0xd8, 0xaf, 0xd9, + 0x8a, 0xd8, 0xaf, 0xd8, 0xa9, 0xd8, 0xa7, 0xd9, 0x84, 0xd8, 0xb9, 0xd8, 0xb6, + 0xd9, 0x88, 0xd8, 0xa5, 0xd8, 0xb6, 0xd8, 0xa7, 0xd9, 0x81, 0xd8, 0xa9, 0xd8, + 0xa7, 0xd9, 0x84, 0xd9, 0x82, 0xd8, 0xb3, 0xd9, 0x85, 0xd8, 0xa7, 0xd9, 0x84, + 0xd8, 0xb9, 0xd8, 0xa7, 0xd8, 0xa8, 0xd8, 0xaa, 0xd8, 0xad, 0xd9, 0x85, 0xd9, + 0x8a, 0xd9, 0x84, 0xd9, 0x85, 0xd9, 0x84, 0xd9, 0x81, 0xd8, 0xa7, 0xd8, 0xaa, + 0xd9, 0x85, 0xd9, 0x84, 0xd8, 0xaa, 0xd9, 0x82, 0xd9, 0x89, 0xd8, 0xaa, 0xd8, + 0xb9, 0xd8, 0xaf, 0xd9, 0x8a, 0xd9, 0x84, 0xd8, 0xa7, 0xd9, 0x84, 0xd8, 0xb4, + 0xd8, 0xb9, 0xd8, 0xb1, 0xd8, 0xa3, 0xd8, 0xae, 0xd8, 0xa8, 0xd8, 0xa7, 0xd8, + 0xb1, 0xd8, 0xaa, 0xd8, 0xb7, 0xd9, 0x88, 0xd9, 0x8a, 0xd8, 0xb1, 0xd8, 0xb9, + 0xd9, 0x84, 0xd9, 0x8a, 0xd9, 0x83, 0xd9, 0x85, 0xd8, 0xa5, 0xd8, 0xb1, 0xd9, + 0x81, 0xd8, 0xa7, 0xd9, 0x82, 0xd8, 0xb7, 0xd9, 0x84, 0xd8, 0xa8, 0xd8, 0xa7, + 0xd8, 0xaa, 0xd8, 0xa7, 0xd9, 0x84, 0xd9, 0x84, 0xd8, 0xba, 0xd8, 0xa9, 0xd8, + 0xaa, 0xd8, 0xb1, 0xd8, 0xaa, 0xd9, 0x8a, 0xd8, 0xa8, 0xd8, 0xa7, 0xd9, 0x84, + 0xd9, 0x86, 0xd8, 0xa7, 0xd8, 0xb3, 0xd8, 0xa7, 0xd9, 0x84, 0xd8, 0xb4, 0xd9, + 0x8a, 0xd8, 0xae, 0xd9, 0x85, 0xd9, 0x86, 0xd8, 0xaa, 0xd8, 0xaf, 0xd9, 0x8a, + 0xd8, 0xa7, 0xd9, 0x84, 0xd8, 0xb9, 0xd8, 0xb1, 0xd8, 0xa8, 0xd8, 0xa7, 0xd9, + 0x84, 0xd9, 0x82, 0xd8, 0xb5, 0xd8, 0xb5, 0xd8, 0xa7, 0xd9, 0x81, 0xd9, 0x84, + 0xd8, 0xa7, 0xd9, 0x85, 0xd8, 0xb9, 0xd9, 0x84, 0xd9, 0x8a, 0xd9, 0x87, 0xd8, + 0xa7, 0xd8, 0xaa, 0xd8, 0xad, 0xd8, 0xaf, 0xd9, 0x8a, 0xd8, 0xab, 0xd8, 0xa7, + 0xd9, 0x84, 0xd9, 0x84, 0xd9, 0x87, 0xd9, 0x85, 0xd8, 0xa7, 0xd9, 0x84, 0xd8, + 0xb9, 0xd9, 0x85, 0xd9, 0x84, 0xd9, 0x85, 0xd9, 0x83, 0xd8, 0xaa, 0xd8, 0xa8, + 0xd8, 0xa9, 0xd9, 0x8a, 0xd9, 0x85, 0xd9, 0x83, 0xd9, 0x86, 0xd9, 0x83, 0xd8, + 0xa7, 0xd9, 0x84, 0xd8, 0xb7, 0xd9, 0x81, 0xd9, 0x84, 0xd9, 0x81, 0xd9, 0x8a, + 0xd8, 0xaf, 0xd9, 0x8a, 0xd9, 0x88, 0xd8, 0xa5, 0xd8, 0xaf, 0xd8, 0xa7, 0xd8, + 0xb1, 0xd8, 0xa9, 0xd8, 0xaa, 0xd8, 0xa7, 0xd8, 0xb1, 0xd9, 0x8a, 0xd8, 0xae, + 0xd8, 0xa7, 0xd9, 0x84, 0xd8, 0xb5, 0xd8, 0xad, 0xd8, 0xa9, 0xd8, 0xaa, 0xd8, + 0xb3, 0xd8, 0xac, 0xd9, 0x8a, 0xd9, 0x84, 0xd8, 0xa7, 0xd9, 0x84, 0xd9, 0x88, + 0xd9, 0x82, 0xd8, 0xaa, 0xd8, 0xb9, 0xd9, 0x86, 0xd8, 0xaf, 0xd9, 0x85, 0xd8, + 0xa7, 0xd9, 0x85, 0xd8, 0xaf, 0xd9, 0x8a, 0xd9, 0x86, 0xd8, 0xa9, 0xd8, 0xaa, + 0xd8, 0xb5, 0xd9, 0x85, 0xd9, 0x8a, 0xd9, 0x85, 0xd8, 0xa3, 0xd8, 0xb1, 0xd8, + 0xb4, 0xd9, 0x8a, 0xd9, 0x81, 0xd8, 0xa7, 0xd9, 0x84, 0xd8, 0xb0, 0xd9, 0x8a, + 0xd9, 0x86, 0xd8, 0xb9, 0xd8, 0xb1, 0xd8, 0xa8, 0xd9, 0x8a, 0xd8, 0xa9, 0xd8, + 0xa8, 0xd9, 0x88, 0xd8, 0xa7, 0xd8, 0xa8, 0xd8, 0xa9, 0xd8, 0xa3, 0xd9, 0x84, + 0xd8, 0xb9, 0xd8, 0xa7, 0xd8, 0xa8, 0xd8, 0xa7, 0xd9, 0x84, 0xd8, 0xb3, 0xd9, + 0x81, 0xd8, 0xb1, 0xd9, 0x85, 0xd8, 0xb4, 0xd8, 0xa7, 0xd9, 0x83, 0xd9, 0x84, + 0xd8, 0xaa, 0xd8, 0xb9, 0xd8, 0xa7, 0xd9, 0x84, 0xd9, 0x89, 0xd8, 0xa7, 0xd9, + 0x84, 0xd8, 0xa3, 0xd9, 0x88, 0xd9, 0x84, 0xd8, 0xa7, 0xd9, 0x84, 0xd8, 0xb3, + 0xd9, 0x86, 0xd8, 0xa9, 0xd8, 0xac, 0xd8, 0xa7, 0xd9, 0x85, 0xd8, 0xb9, 0xd8, + 0xa9, 0xd8, 0xa7, 0xd9, 0x84, 0xd8, 0xb5, 0xd8, 0xad, 0xd9, 0x81, 0xd8, 0xa7, + 0xd9, 0x84, 0xd8, 0xaf, 0xd9, 0x8a, 0xd9, 0x86, 0xd9, 0x83, 0xd9, 0x84, 0xd9, + 0x85, 0xd8, 0xa7, 0xd8, 0xaa, 0xd8, 0xa7, 0xd9, 0x84, 0xd8, 0xae, 0xd8, 0xa7, + 0xd8, 0xb5, 0xd8, 0xa7, 0xd9, 0x84, 0xd9, 0x85, 0xd9, 0x84, 0xd9, 0x81, 0xd8, + 0xa3, 0xd8, 0xb9, 0xd8, 0xb6, 0xd8, 0xa7, 0xd8, 0xa1, 0xd9, 0x83, 0xd8, 0xaa, + 0xd8, 0xa7, 0xd8, 0xa8, 0xd8, 0xa9, 0xd8, 0xa7, 0xd9, 0x84, 0xd8, 0xae, 0xd9, + 0x8a, 0xd8, 0xb1, 0xd8, 0xb1, 0xd8, 0xb3, 0xd8, 0xa7, 0xd8, 0xa6, 0xd9, 0x84, + 0xd8, 0xa7, 0xd9, 0x84, 0xd9, 0x82, 0xd9, 0x84, 0xd8, 0xa8, 0xd8, 0xa7, 0xd9, + 0x84, 0xd8, 0xa3, 0xd8, 0xaf, 0xd8, 0xa8, 0xd9, 0x85, 0xd9, 0x82, 0xd8, 0xa7, + 0xd8, 0xb7, 0xd8, 0xb9, 0xd9, 0x85, 0xd8, 0xb1, 0xd8, 0xa7, 0xd8, 0xb3, 0xd9, + 0x84, 0xd9, 0x85, 0xd9, 0x86, 0xd8, 0xb7, 0xd9, 0x82, 0xd8, 0xa9, 0xd8, 0xa7, + 0xd9, 0x84, 0xd9, 0x83, 0xd8, 0xaa, 0xd8, 0xa8, 0xd8, 0xa7, 0xd9, 0x84, 0xd8, + 0xb1, 0xd8, 0xac, 0xd9, 0x84, 0xd8, 0xa7, 0xd8, 0xb4, 0xd8, 0xaa, 0xd8, 0xb1, + 0xd9, 0x83, 0xd8, 0xa7, 0xd9, 0x84, 0xd9, 0x82, 0xd8, 0xaf, 0xd9, 0x85, 0xd9, + 0x8a, 0xd8, 0xb9, 0xd8, 0xb7, 0xd9, 0x8a, 0xd9, 0x83, 0x73, 0x42, 0x79, 0x54, + 0x61, 0x67, 0x4e, 0x61, 0x6d, 0x65, 0x28, 0x2e, 0x6a, 0x70, 0x67, 0x22, 0x20, + 0x61, 0x6c, 0x74, 0x3d, 0x22, 0x31, 0x70, 0x78, 0x20, 0x73, 0x6f, 0x6c, 0x69, + 0x64, 0x20, 0x23, 0x2e, 0x67, 0x69, 0x66, 0x22, 0x20, 0x61, 0x6c, 0x74, 0x3d, + 0x22, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x69, + 0x6e, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x70, 0x70, + 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x20, 0x6f, 0x6e, 0x63, + 0x6c, 0x69, 0x63, 0x6b, 0x3d, 0x22, 0x65, 0x73, 0x74, 0x61, 0x62, 0x6c, 0x69, + 0x73, 0x68, 0x65, 0x64, 0x61, 0x64, 0x76, 0x65, 0x72, 0x74, 0x69, 0x73, 0x69, + 0x6e, 0x67, 0x2e, 0x70, 0x6e, 0x67, 0x22, 0x20, 0x61, 0x6c, 0x74, 0x3d, 0x22, + 0x65, 0x6e, 0x76, 0x69, 0x72, 0x6f, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x70, 0x65, + 0x72, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x6e, 0x63, 0x65, 0x61, 0x70, 0x70, 0x72, + 0x6f, 0x70, 0x72, 0x69, 0x61, 0x74, 0x65, 0x26, 0x61, 0x6d, 0x70, 0x3b, 0x6d, + 0x64, 0x61, 0x73, 0x68, 0x3b, 0x69, 0x6d, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x74, + 0x65, 0x6c, 0x79, 0x3c, 0x2f, 0x73, 0x74, 0x72, 0x6f, 0x6e, 0x67, 0x3e, 0x3c, + 0x2f, 0x72, 0x61, 0x74, 0x68, 0x65, 0x72, 0x20, 0x74, 0x68, 0x61, 0x6e, 0x74, + 0x65, 0x6d, 0x70, 0x65, 0x72, 0x61, 0x74, 0x75, 0x72, 0x65, 0x64, 0x65, 0x76, + 0x65, 0x6c, 0x6f, 0x70, 0x6d, 0x65, 0x6e, 0x74, 0x63, 0x6f, 0x6d, 0x70, 0x65, + 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x70, 0x6c, 0x61, 0x63, 0x65, 0x68, 0x6f, + 0x6c, 0x64, 0x65, 0x72, 0x76, 0x69, 0x73, 0x69, 0x62, 0x69, 0x6c, 0x69, 0x74, + 0x79, 0x3a, 0x63, 0x6f, 0x70, 0x79, 0x72, 0x69, 0x67, 0x68, 0x74, 0x22, 0x3e, + 0x30, 0x22, 0x20, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x3d, 0x22, 0x65, 0x76, + 0x65, 0x6e, 0x20, 0x74, 0x68, 0x6f, 0x75, 0x67, 0x68, 0x72, 0x65, 0x70, 0x6c, + 0x61, 0x63, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x64, 0x65, 0x73, 0x74, 0x69, 0x6e, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x72, 0x70, 0x6f, 0x72, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x3c, 0x75, 0x6c, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x3d, + 0x22, 0x41, 0x73, 0x73, 0x6f, 0x63, 0x69, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x69, + 0x6e, 0x64, 0x69, 0x76, 0x69, 0x64, 0x75, 0x61, 0x6c, 0x73, 0x70, 0x65, 0x72, + 0x73, 0x70, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x73, 0x65, 0x74, 0x54, 0x69, + 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x28, 0x75, 0x72, 0x6c, 0x28, 0x68, 0x74, 0x74, + 0x70, 0x3a, 0x2f, 0x2f, 0x6d, 0x61, 0x74, 0x68, 0x65, 0x6d, 0x61, 0x74, 0x69, + 0x63, 0x73, 0x6d, 0x61, 0x72, 0x67, 0x69, 0x6e, 0x2d, 0x74, 0x6f, 0x70, 0x3a, + 0x65, 0x76, 0x65, 0x6e, 0x74, 0x75, 0x61, 0x6c, 0x6c, 0x79, 0x20, 0x64, 0x65, + 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x29, 0x20, 0x6e, 0x6f, + 0x2d, 0x72, 0x65, 0x70, 0x65, 0x61, 0x74, 0x63, 0x6f, 0x6c, 0x6c, 0x65, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x4a, 0x50, 0x47, 0x7c, 0x74, 0x68, 0x75, + 0x6d, 0x62, 0x7c, 0x70, 0x61, 0x72, 0x74, 0x69, 0x63, 0x69, 0x70, 0x61, 0x74, + 0x65, 0x2f, 0x68, 0x65, 0x61, 0x64, 0x3e, 0x3c, 0x62, 0x6f, 0x64, 0x79, 0x66, + 0x6c, 0x6f, 0x61, 0x74, 0x3a, 0x6c, 0x65, 0x66, 0x74, 0x3b, 0x3c, 0x6c, 0x69, + 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x22, 0x68, 0x75, 0x6e, 0x64, 0x72, + 0x65, 0x64, 0x73, 0x20, 0x6f, 0x66, 0x0a, 0x0a, 0x48, 0x6f, 0x77, 0x65, 0x76, + 0x65, 0x72, 0x2c, 0x20, 0x63, 0x6f, 0x6d, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, + 0x6f, 0x6e, 0x63, 0x6c, 0x65, 0x61, 0x72, 0x3a, 0x62, 0x6f, 0x74, 0x68, 0x3b, + 0x63, 0x6f, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x77, 0x69, + 0x74, 0x68, 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x6c, 0x61, 0x62, 0x65, + 0x6c, 0x20, 0x66, 0x6f, 0x72, 0x3d, 0x22, 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, + 0x2d, 0x74, 0x6f, 0x70, 0x3a, 0x4e, 0x65, 0x77, 0x20, 0x5a, 0x65, 0x61, 0x6c, + 0x61, 0x6e, 0x64, 0x72, 0x65, 0x63, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x64, 0x65, + 0x64, 0x70, 0x68, 0x6f, 0x74, 0x6f, 0x67, 0x72, 0x61, 0x70, 0x68, 0x79, 0x69, + 0x6e, 0x74, 0x65, 0x72, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x67, 0x26, 0x6c, 0x74, + 0x3b, 0x73, 0x75, 0x70, 0x26, 0x67, 0x74, 0x3b, 0x63, 0x6f, 0x6e, 0x74, 0x72, + 0x6f, 0x76, 0x65, 0x72, 0x73, 0x79, 0x4e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x6c, + 0x61, 0x6e, 0x64, 0x73, 0x61, 0x6c, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x74, 0x69, + 0x76, 0x65, 0x6d, 0x61, 0x78, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3d, 0x22, + 0x73, 0x77, 0x69, 0x74, 0x7a, 0x65, 0x72, 0x6c, 0x61, 0x6e, 0x64, 0x44, 0x65, + 0x76, 0x65, 0x6c, 0x6f, 0x70, 0x6d, 0x65, 0x6e, 0x74, 0x65, 0x73, 0x73, 0x65, + 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x6c, 0x79, 0x0a, 0x0a, 0x41, 0x6c, 0x74, 0x68, + 0x6f, 0x75, 0x67, 0x68, 0x20, 0x3c, 0x2f, 0x74, 0x65, 0x78, 0x74, 0x61, 0x72, + 0x65, 0x61, 0x3e, 0x74, 0x68, 0x75, 0x6e, 0x64, 0x65, 0x72, 0x62, 0x69, 0x72, + 0x64, 0x72, 0x65, 0x70, 0x72, 0x65, 0x73, 0x65, 0x6e, 0x74, 0x65, 0x64, 0x26, + 0x61, 0x6d, 0x70, 0x3b, 0x6e, 0x64, 0x61, 0x73, 0x68, 0x3b, 0x73, 0x70, 0x65, + 0x63, 0x75, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x63, 0x6f, 0x6d, 0x6d, 0x75, + 0x6e, 0x69, 0x74, 0x69, 0x65, 0x73, 0x6c, 0x65, 0x67, 0x69, 0x73, 0x6c, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x72, 0x6f, 0x6e, 0x69, + 0x63, 0x73, 0x0a, 0x09, 0x3c, 0x64, 0x69, 0x76, 0x20, 0x69, 0x64, 0x3d, 0x22, + 0x69, 0x6c, 0x6c, 0x75, 0x73, 0x74, 0x72, 0x61, 0x74, 0x65, 0x64, 0x65, 0x6e, + 0x67, 0x69, 0x6e, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x74, 0x65, 0x72, 0x72, + 0x69, 0x74, 0x6f, 0x72, 0x69, 0x65, 0x73, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, + 0x69, 0x74, 0x69, 0x65, 0x73, 0x64, 0x69, 0x73, 0x74, 0x72, 0x69, 0x62, 0x75, + 0x74, 0x65, 0x64, 0x36, 0x22, 0x20, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x3d, + 0x22, 0x73, 0x61, 0x6e, 0x73, 0x2d, 0x73, 0x65, 0x72, 0x69, 0x66, 0x3b, 0x63, + 0x61, 0x70, 0x61, 0x62, 0x6c, 0x65, 0x20, 0x6f, 0x66, 0x20, 0x64, 0x69, 0x73, + 0x61, 0x70, 0x70, 0x65, 0x61, 0x72, 0x65, 0x64, 0x69, 0x6e, 0x74, 0x65, 0x72, + 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, 0x6c, 0x6f, 0x6f, 0x6b, 0x69, 0x6e, 0x67, + 0x20, 0x66, 0x6f, 0x72, 0x69, 0x74, 0x20, 0x77, 0x6f, 0x75, 0x6c, 0x64, 0x20, + 0x62, 0x65, 0x41, 0x66, 0x67, 0x68, 0x61, 0x6e, 0x69, 0x73, 0x74, 0x61, 0x6e, + 0x77, 0x61, 0x73, 0x20, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x4d, 0x61, + 0x74, 0x68, 0x2e, 0x66, 0x6c, 0x6f, 0x6f, 0x72, 0x28, 0x73, 0x75, 0x72, 0x72, + 0x6f, 0x75, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x63, 0x61, 0x6e, 0x20, 0x61, 0x6c, + 0x73, 0x6f, 0x20, 0x62, 0x65, 0x6f, 0x62, 0x73, 0x65, 0x72, 0x76, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x6d, 0x61, 0x69, 0x6e, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x63, + 0x65, 0x65, 0x6e, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x65, 0x64, 0x3c, + 0x68, 0x32, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x22, 0x6d, 0x6f, 0x72, + 0x65, 0x20, 0x72, 0x65, 0x63, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x20, 0x68, 0x61, + 0x73, 0x20, 0x62, 0x65, 0x65, 0x6e, 0x69, 0x6e, 0x76, 0x61, 0x73, 0x69, 0x6f, + 0x6e, 0x20, 0x6f, 0x66, 0x29, 0x2e, 0x67, 0x65, 0x74, 0x54, 0x69, 0x6d, 0x65, + 0x28, 0x29, 0x66, 0x75, 0x6e, 0x64, 0x61, 0x6d, 0x65, 0x6e, 0x74, 0x61, 0x6c, + 0x44, 0x65, 0x73, 0x70, 0x69, 0x74, 0x65, 0x20, 0x74, 0x68, 0x65, 0x22, 0x3e, + 0x3c, 0x64, 0x69, 0x76, 0x20, 0x69, 0x64, 0x3d, 0x22, 0x69, 0x6e, 0x73, 0x70, + 0x69, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x65, 0x78, 0x61, 0x6d, 0x69, 0x6e, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x70, 0x72, 0x65, 0x70, 0x61, 0x72, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x65, 0x78, 0x70, 0x6c, 0x61, 0x6e, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x3c, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x20, 0x69, 0x64, 0x3d, 0x22, 0x3c, + 0x2f, 0x61, 0x3e, 0x3c, 0x2f, 0x73, 0x70, 0x61, 0x6e, 0x3e, 0x76, 0x65, 0x72, + 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x6f, 0x66, 0x69, 0x6e, 0x73, 0x74, 0x72, + 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x62, 0x65, 0x66, 0x6f, 0x72, 0x65, 0x20, + 0x74, 0x68, 0x65, 0x20, 0x20, 0x3d, 0x20, 0x27, 0x68, 0x74, 0x74, 0x70, 0x3a, + 0x2f, 0x2f, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, + 0x72, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x76, 0x65, 0x6c, 0x79, 0x20, 0x2e, 0x73, + 0x75, 0x62, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x28, 0x65, 0x61, 0x63, 0x68, + 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x65, 0x78, 0x70, 0x65, 0x72, 0x69, + 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x69, 0x6e, 0x66, 0x6c, 0x75, 0x65, 0x6e, 0x74, + 0x69, 0x61, 0x6c, 0x69, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x6d, 0x61, 0x6e, 0x79, 0x20, 0x70, 0x65, 0x6f, 0x70, 0x6c, 0x65, 0x64, + 0x75, 0x65, 0x20, 0x74, 0x6f, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x6f, 0x6d, + 0x62, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x64, 0x6f, 0x20, 0x6e, 0x6f, + 0x74, 0x20, 0x68, 0x61, 0x76, 0x65, 0x4d, 0x69, 0x64, 0x64, 0x6c, 0x65, 0x20, + 0x45, 0x61, 0x73, 0x74, 0x3c, 0x6e, 0x6f, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, + 0x3e, 0x3c, 0x63, 0x6f, 0x70, 0x79, 0x72, 0x69, 0x67, 0x68, 0x74, 0x22, 0x20, + 0x70, 0x65, 0x72, 0x68, 0x61, 0x70, 0x73, 0x20, 0x74, 0x68, 0x65, 0x69, 0x6e, + 0x73, 0x74, 0x69, 0x74, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x69, 0x6e, 0x20, 0x44, + 0x65, 0x63, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x61, 0x72, 0x72, 0x61, 0x6e, 0x67, + 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x6d, 0x6f, 0x73, 0x74, 0x20, 0x66, 0x61, 0x6d, + 0x6f, 0x75, 0x73, 0x70, 0x65, 0x72, 0x73, 0x6f, 0x6e, 0x61, 0x6c, 0x69, 0x74, + 0x79, 0x63, 0x72, 0x65, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6f, 0x66, 0x6c, + 0x69, 0x6d, 0x69, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x65, 0x78, 0x63, + 0x6c, 0x75, 0x73, 0x69, 0x76, 0x65, 0x6c, 0x79, 0x73, 0x6f, 0x76, 0x65, 0x72, + 0x65, 0x69, 0x67, 0x6e, 0x74, 0x79, 0x2d, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, + 0x74, 0x22, 0x3e, 0x0a, 0x3c, 0x74, 0x64, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, + 0x3d, 0x22, 0x75, 0x6e, 0x64, 0x65, 0x72, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, + 0x70, 0x61, 0x72, 0x61, 0x6c, 0x6c, 0x65, 0x6c, 0x20, 0x74, 0x6f, 0x64, 0x6f, + 0x63, 0x74, 0x72, 0x69, 0x6e, 0x65, 0x20, 0x6f, 0x66, 0x6f, 0x63, 0x63, 0x75, + 0x70, 0x69, 0x65, 0x64, 0x20, 0x62, 0x79, 0x74, 0x65, 0x72, 0x6d, 0x69, 0x6e, + 0x6f, 0x6c, 0x6f, 0x67, 0x79, 0x52, 0x65, 0x6e, 0x61, 0x69, 0x73, 0x73, 0x61, + 0x6e, 0x63, 0x65, 0x61, 0x20, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x20, 0x6f, + 0x66, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x20, 0x66, 0x6f, 0x72, 0x65, + 0x78, 0x70, 0x6c, 0x6f, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x72, 0x65, 0x63, + 0x6f, 0x67, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x70, 0x72, 0x65, 0x64, 0x65, + 0x63, 0x65, 0x73, 0x73, 0x6f, 0x72, 0x3c, 0x69, 0x6d, 0x67, 0x20, 0x73, 0x72, + 0x63, 0x3d, 0x22, 0x2f, 0x3c, 0x68, 0x31, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, + 0x3d, 0x22, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x6d, 0x61, 0x79, 0x20, 0x61, 0x6c, 0x73, 0x6f, 0x20, 0x62, 0x65, 0x73, 0x70, + 0x65, 0x63, 0x69, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x64, 0x3c, 0x2f, 0x66, 0x69, + 0x65, 0x6c, 0x64, 0x73, 0x65, 0x74, 0x3e, 0x70, 0x72, 0x6f, 0x67, 0x72, 0x65, + 0x73, 0x73, 0x69, 0x76, 0x65, 0x6d, 0x69, 0x6c, 0x6c, 0x69, 0x6f, 0x6e, 0x73, + 0x20, 0x6f, 0x66, 0x73, 0x74, 0x61, 0x74, 0x65, 0x73, 0x20, 0x74, 0x68, 0x61, + 0x74, 0x65, 0x6e, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x61, + 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x20, 0x74, 0x68, 0x65, 0x20, 0x6f, 0x6e, 0x65, + 0x20, 0x61, 0x6e, 0x6f, 0x74, 0x68, 0x65, 0x72, 0x2e, 0x70, 0x61, 0x72, 0x65, + 0x6e, 0x74, 0x4e, 0x6f, 0x64, 0x65, 0x61, 0x67, 0x72, 0x69, 0x63, 0x75, 0x6c, + 0x74, 0x75, 0x72, 0x65, 0x41, 0x6c, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x74, 0x69, + 0x76, 0x65, 0x72, 0x65, 0x73, 0x65, 0x61, 0x72, 0x63, 0x68, 0x65, 0x72, 0x73, + 0x74, 0x6f, 0x77, 0x61, 0x72, 0x64, 0x73, 0x20, 0x74, 0x68, 0x65, 0x4d, 0x6f, + 0x73, 0x74, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x6d, 0x61, 0x6e, 0x79, + 0x20, 0x6f, 0x74, 0x68, 0x65, 0x72, 0x20, 0x28, 0x65, 0x73, 0x70, 0x65, 0x63, + 0x69, 0x61, 0x6c, 0x6c, 0x79, 0x3c, 0x74, 0x64, 0x20, 0x77, 0x69, 0x64, 0x74, + 0x68, 0x3d, 0x22, 0x3b, 0x77, 0x69, 0x64, 0x74, 0x68, 0x3a, 0x31, 0x30, 0x30, + 0x25, 0x69, 0x6e, 0x64, 0x65, 0x70, 0x65, 0x6e, 0x64, 0x65, 0x6e, 0x74, 0x3c, + 0x68, 0x33, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x22, 0x20, 0x6f, 0x6e, + 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x3d, 0x22, 0x29, 0x2e, 0x61, 0x64, 0x64, + 0x43, 0x6c, 0x61, 0x73, 0x73, 0x28, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x61, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x4f, 0x6e, 0x65, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, + 0x65, 0x20, 0x64, 0x61, 0x75, 0x67, 0x68, 0x74, 0x65, 0x72, 0x20, 0x6f, 0x66, + 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x6f, 0x72, 0x69, 0x65, 0x73, 0x62, 0x72, + 0x61, 0x6e, 0x63, 0x68, 0x65, 0x73, 0x20, 0x6f, 0x66, 0x0d, 0x0a, 0x3c, 0x64, + 0x69, 0x76, 0x20, 0x69, 0x64, 0x3d, 0x22, 0x74, 0x68, 0x65, 0x20, 0x6c, 0x61, + 0x72, 0x67, 0x65, 0x73, 0x74, 0x64, 0x65, 0x63, 0x6c, 0x61, 0x72, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x72, 0x65, 0x67, 0x75, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x73, 0x49, 0x6e, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x74, + 0x72, 0x61, 0x6e, 0x73, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x64, 0x6f, 0x63, + 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x61, 0x72, 0x79, 0x69, 0x6e, 0x20, 0x6f, 0x72, + 0x64, 0x65, 0x72, 0x20, 0x74, 0x6f, 0x22, 0x3e, 0x0a, 0x3c, 0x68, 0x65, 0x61, + 0x64, 0x3e, 0x0a, 0x3c, 0x22, 0x20, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x3d, + 0x22, 0x31, 0x61, 0x63, 0x72, 0x6f, 0x73, 0x73, 0x20, 0x74, 0x68, 0x65, 0x20, + 0x6f, 0x72, 0x69, 0x65, 0x6e, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x29, 0x3b, + 0x3c, 0x2f, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x3e, 0x69, 0x6d, 0x70, 0x6c, + 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x65, 0x64, 0x63, 0x61, 0x6e, 0x20, 0x62, 0x65, + 0x20, 0x73, 0x65, 0x65, 0x6e, 0x74, 0x68, 0x65, 0x72, 0x65, 0x20, 0x77, 0x61, + 0x73, 0x20, 0x61, 0x64, 0x65, 0x6d, 0x6f, 0x6e, 0x73, 0x74, 0x72, 0x61, 0x74, + 0x65, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x22, 0x3e, 0x63, + 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x74, 0x68, 0x65, + 0x20, 0x42, 0x72, 0x69, 0x74, 0x69, 0x73, 0x68, 0x77, 0x61, 0x73, 0x20, 0x77, + 0x72, 0x69, 0x74, 0x74, 0x65, 0x6e, 0x21, 0x69, 0x6d, 0x70, 0x6f, 0x72, 0x74, + 0x61, 0x6e, 0x74, 0x3b, 0x70, 0x78, 0x3b, 0x20, 0x6d, 0x61, 0x72, 0x67, 0x69, + 0x6e, 0x2d, 0x66, 0x6f, 0x6c, 0x6c, 0x6f, 0x77, 0x65, 0x64, 0x20, 0x62, 0x79, + 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x20, 0x74, 0x6f, 0x20, 0x63, 0x6f, + 0x6d, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x65, 0x64, 0x64, 0x75, 0x72, 0x69, + 0x6e, 0x67, 0x20, 0x74, 0x68, 0x65, 0x20, 0x69, 0x6d, 0x6d, 0x69, 0x67, 0x72, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x73, 0x6f, 0x20, 0x63, 0x61, 0x6c, + 0x6c, 0x65, 0x64, 0x3c, 0x68, 0x34, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x3d, + 0x22, 0x64, 0x69, 0x73, 0x74, 0x69, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x72, + 0x65, 0x70, 0x6c, 0x61, 0x63, 0x65, 0x64, 0x20, 0x62, 0x79, 0x67, 0x6f, 0x76, + 0x65, 0x72, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x6c, 0x6f, 0x63, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x20, 0x6f, 0x66, 0x69, 0x6e, 0x20, 0x4e, 0x6f, 0x76, 0x65, + 0x6d, 0x62, 0x65, 0x72, 0x77, 0x68, 0x65, 0x74, 0x68, 0x65, 0x72, 0x20, 0x74, + 0x68, 0x65, 0x3c, 0x2f, 0x70, 0x3e, 0x0a, 0x3c, 0x2f, 0x64, 0x69, 0x76, 0x3e, + 0x61, 0x63, 0x71, 0x75, 0x69, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x63, 0x61, + 0x6c, 0x6c, 0x65, 0x64, 0x20, 0x74, 0x68, 0x65, 0x20, 0x70, 0x65, 0x72, 0x73, + 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x64, 0x65, 0x73, 0x69, 0x67, 0x6e, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x7b, 0x66, 0x6f, 0x6e, 0x74, 0x2d, 0x73, 0x69, + 0x7a, 0x65, 0x3a, 0x61, 0x70, 0x70, 0x65, 0x61, 0x72, 0x65, 0x64, 0x20, 0x69, + 0x6e, 0x69, 0x6e, 0x76, 0x65, 0x73, 0x74, 0x69, 0x67, 0x61, 0x74, 0x65, 0x65, + 0x78, 0x70, 0x65, 0x72, 0x69, 0x65, 0x6e, 0x63, 0x65, 0x64, 0x6d, 0x6f, 0x73, + 0x74, 0x20, 0x6c, 0x69, 0x6b, 0x65, 0x6c, 0x79, 0x77, 0x69, 0x64, 0x65, 0x6c, + 0x79, 0x20, 0x75, 0x73, 0x65, 0x64, 0x64, 0x69, 0x73, 0x63, 0x75, 0x73, 0x73, + 0x69, 0x6f, 0x6e, 0x73, 0x70, 0x72, 0x65, 0x73, 0x65, 0x6e, 0x63, 0x65, 0x20, + 0x6f, 0x66, 0x20, 0x28, 0x64, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x2e, + 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x76, 0x65, 0x6c, 0x79, 0x49, 0x74, + 0x20, 0x68, 0x61, 0x73, 0x20, 0x62, 0x65, 0x65, 0x6e, 0x69, 0x74, 0x20, 0x64, + 0x6f, 0x65, 0x73, 0x20, 0x6e, 0x6f, 0x74, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x61, + 0x72, 0x79, 0x20, 0x74, 0x6f, 0x69, 0x6e, 0x68, 0x61, 0x62, 0x69, 0x74, 0x61, + 0x6e, 0x74, 0x73, 0x69, 0x6d, 0x70, 0x72, 0x6f, 0x76, 0x65, 0x6d, 0x65, 0x6e, + 0x74, 0x73, 0x63, 0x68, 0x6f, 0x6c, 0x61, 0x72, 0x73, 0x68, 0x69, 0x70, 0x63, + 0x6f, 0x6e, 0x73, 0x75, 0x6d, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x69, 0x6e, 0x73, + 0x74, 0x72, 0x75, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x66, 0x6f, 0x72, 0x20, 0x65, + 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x6f, 0x6e, 0x65, 0x20, 0x6f, 0x72, 0x20, + 0x6d, 0x6f, 0x72, 0x65, 0x70, 0x78, 0x3b, 0x20, 0x70, 0x61, 0x64, 0x64, 0x69, + 0x6e, 0x67, 0x74, 0x68, 0x65, 0x20, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, + 0x61, 0x20, 0x73, 0x65, 0x72, 0x69, 0x65, 0x73, 0x20, 0x6f, 0x66, 0x61, 0x72, + 0x65, 0x20, 0x75, 0x73, 0x75, 0x61, 0x6c, 0x6c, 0x79, 0x72, 0x6f, 0x6c, 0x65, + 0x20, 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x70, 0x72, 0x65, 0x76, 0x69, 0x6f, + 0x75, 0x73, 0x6c, 0x79, 0x20, 0x64, 0x65, 0x72, 0x69, 0x76, 0x61, 0x74, 0x69, + 0x76, 0x65, 0x73, 0x65, 0x76, 0x69, 0x64, 0x65, 0x6e, 0x63, 0x65, 0x20, 0x6f, + 0x66, 0x65, 0x78, 0x70, 0x65, 0x72, 0x69, 0x65, 0x6e, 0x63, 0x65, 0x73, 0x63, + 0x6f, 0x6c, 0x6f, 0x72, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x65, 0x73, 0x74, 0x61, + 0x74, 0x65, 0x64, 0x20, 0x74, 0x68, 0x61, 0x74, 0x63, 0x65, 0x72, 0x74, 0x69, + 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x3c, 0x2f, 0x61, 0x3e, 0x3c, 0x2f, 0x64, + 0x69, 0x76, 0x3e, 0x0a, 0x20, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x65, 0x64, + 0x3d, 0x22, 0x68, 0x69, 0x67, 0x68, 0x20, 0x73, 0x63, 0x68, 0x6f, 0x6f, 0x6c, + 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x20, 0x74, 0x6f, 0x63, 0x6f, + 0x6d, 0x66, 0x6f, 0x72, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x61, 0x64, 0x6f, 0x70, + 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6f, 0x66, 0x74, 0x68, 0x72, 0x65, 0x65, 0x20, + 0x79, 0x65, 0x61, 0x72, 0x73, 0x74, 0x68, 0x65, 0x20, 0x63, 0x6f, 0x75, 0x6e, + 0x74, 0x72, 0x79, 0x69, 0x6e, 0x20, 0x46, 0x65, 0x62, 0x72, 0x75, 0x61, 0x72, + 0x79, 0x73, 0x6f, 0x20, 0x74, 0x68, 0x61, 0x74, 0x20, 0x74, 0x68, 0x65, 0x70, + 0x65, 0x6f, 0x70, 0x6c, 0x65, 0x20, 0x77, 0x68, 0x6f, 0x20, 0x70, 0x72, 0x6f, + 0x76, 0x69, 0x64, 0x65, 0x64, 0x20, 0x62, 0x79, 0x3c, 0x70, 0x61, 0x72, 0x61, + 0x6d, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x61, 0x66, 0x66, 0x65, 0x63, 0x74, 0x65, + 0x64, 0x20, 0x62, 0x79, 0x69, 0x6e, 0x20, 0x74, 0x65, 0x72, 0x6d, 0x73, 0x20, + 0x6f, 0x66, 0x61, 0x70, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x6d, 0x65, 0x6e, 0x74, + 0x49, 0x53, 0x4f, 0x2d, 0x38, 0x38, 0x35, 0x39, 0x2d, 0x31, 0x22, 0x77, 0x61, + 0x73, 0x20, 0x62, 0x6f, 0x72, 0x6e, 0x20, 0x69, 0x6e, 0x68, 0x69, 0x73, 0x74, + 0x6f, 0x72, 0x69, 0x63, 0x61, 0x6c, 0x20, 0x72, 0x65, 0x67, 0x61, 0x72, 0x64, + 0x65, 0x64, 0x20, 0x61, 0x73, 0x6d, 0x65, 0x61, 0x73, 0x75, 0x72, 0x65, 0x6d, + 0x65, 0x6e, 0x74, 0x69, 0x73, 0x20, 0x62, 0x61, 0x73, 0x65, 0x64, 0x20, 0x6f, + 0x6e, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x6f, 0x74, 0x68, 0x65, 0x72, 0x20, 0x3a, + 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x73, 0x69, 0x67, + 0x6e, 0x69, 0x66, 0x69, 0x63, 0x61, 0x6e, 0x74, 0x63, 0x65, 0x6c, 0x65, 0x62, + 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x6d, 0x69, + 0x74, 0x74, 0x65, 0x64, 0x2f, 0x6a, 0x73, 0x2f, 0x6a, 0x71, 0x75, 0x65, 0x72, + 0x79, 0x2e, 0x69, 0x73, 0x20, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x20, 0x61, 0x73, + 0x74, 0x68, 0x65, 0x6f, 0x72, 0x65, 0x74, 0x69, 0x63, 0x61, 0x6c, 0x20, 0x74, + 0x61, 0x62, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x3d, 0x22, 0x69, 0x74, 0x20, 0x63, + 0x6f, 0x75, 0x6c, 0x64, 0x20, 0x62, 0x65, 0x3c, 0x6e, 0x6f, 0x73, 0x63, 0x72, + 0x69, 0x70, 0x74, 0x3e, 0x0a, 0x68, 0x61, 0x76, 0x69, 0x6e, 0x67, 0x20, 0x62, + 0x65, 0x65, 0x6e, 0x0d, 0x0a, 0x3c, 0x68, 0x65, 0x61, 0x64, 0x3e, 0x0d, 0x0a, + 0x3c, 0x20, 0x26, 0x71, 0x75, 0x6f, 0x74, 0x3b, 0x54, 0x68, 0x65, 0x20, 0x63, + 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x68, 0x65, 0x20, + 0x68, 0x61, 0x64, 0x20, 0x62, 0x65, 0x65, 0x6e, 0x70, 0x72, 0x6f, 0x64, 0x75, + 0x63, 0x65, 0x64, 0x20, 0x62, 0x79, 0x70, 0x68, 0x69, 0x6c, 0x6f, 0x73, 0x6f, + 0x70, 0x68, 0x65, 0x72, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, + 0x65, 0x64, 0x69, 0x6e, 0x74, 0x65, 0x6e, 0x64, 0x65, 0x64, 0x20, 0x74, 0x6f, + 0x61, 0x6d, 0x6f, 0x6e, 0x67, 0x20, 0x6f, 0x74, 0x68, 0x65, 0x72, 0x63, 0x6f, + 0x6d, 0x70, 0x61, 0x72, 0x65, 0x64, 0x20, 0x74, 0x6f, 0x74, 0x6f, 0x20, 0x73, + 0x61, 0x79, 0x20, 0x74, 0x68, 0x61, 0x74, 0x45, 0x6e, 0x67, 0x69, 0x6e, 0x65, + 0x65, 0x72, 0x69, 0x6e, 0x67, 0x61, 0x20, 0x64, 0x69, 0x66, 0x66, 0x65, 0x72, + 0x65, 0x6e, 0x74, 0x72, 0x65, 0x66, 0x65, 0x72, 0x72, 0x65, 0x64, 0x20, 0x74, + 0x6f, 0x64, 0x69, 0x66, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x73, 0x62, + 0x65, 0x6c, 0x69, 0x65, 0x66, 0x20, 0x74, 0x68, 0x61, 0x74, 0x70, 0x68, 0x6f, + 0x74, 0x6f, 0x67, 0x72, 0x61, 0x70, 0x68, 0x73, 0x69, 0x64, 0x65, 0x6e, 0x74, + 0x69, 0x66, 0x79, 0x69, 0x6e, 0x67, 0x48, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, + 0x20, 0x6f, 0x66, 0x20, 0x52, 0x65, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x20, + 0x6f, 0x66, 0x6e, 0x65, 0x63, 0x65, 0x73, 0x73, 0x61, 0x72, 0x69, 0x6c, 0x79, + 0x70, 0x72, 0x6f, 0x62, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x74, 0x65, + 0x63, 0x68, 0x6e, 0x69, 0x63, 0x61, 0x6c, 0x6c, 0x79, 0x6c, 0x65, 0x61, 0x76, + 0x69, 0x6e, 0x67, 0x20, 0x74, 0x68, 0x65, 0x73, 0x70, 0x65, 0x63, 0x74, 0x61, + 0x63, 0x75, 0x6c, 0x61, 0x72, 0x66, 0x72, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x20, 0x6f, 0x66, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x72, 0x69, 0x63, 0x69, 0x74, + 0x79, 0x68, 0x65, 0x61, 0x64, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x72, + 0x65, 0x73, 0x74, 0x61, 0x75, 0x72, 0x61, 0x6e, 0x74, 0x73, 0x70, 0x61, 0x72, + 0x74, 0x6e, 0x65, 0x72, 0x73, 0x68, 0x69, 0x70, 0x65, 0x6d, 0x70, 0x68, 0x61, + 0x73, 0x69, 0x73, 0x20, 0x6f, 0x6e, 0x6d, 0x6f, 0x73, 0x74, 0x20, 0x72, 0x65, + 0x63, 0x65, 0x6e, 0x74, 0x73, 0x68, 0x61, 0x72, 0x65, 0x20, 0x77, 0x69, 0x74, + 0x68, 0x20, 0x73, 0x61, 0x79, 0x69, 0x6e, 0x67, 0x20, 0x74, 0x68, 0x61, 0x74, + 0x66, 0x69, 0x6c, 0x6c, 0x65, 0x64, 0x20, 0x77, 0x69, 0x74, 0x68, 0x64, 0x65, + 0x73, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x20, 0x74, 0x6f, 0x69, 0x74, 0x20, 0x69, + 0x73, 0x20, 0x6f, 0x66, 0x74, 0x65, 0x6e, 0x22, 0x3e, 0x3c, 0x2f, 0x69, 0x66, + 0x72, 0x61, 0x6d, 0x65, 0x3e, 0x61, 0x73, 0x20, 0x66, 0x6f, 0x6c, 0x6c, 0x6f, + 0x77, 0x73, 0x3a, 0x6d, 0x65, 0x72, 0x67, 0x65, 0x64, 0x20, 0x77, 0x69, 0x74, + 0x68, 0x74, 0x68, 0x72, 0x6f, 0x75, 0x67, 0x68, 0x20, 0x74, 0x68, 0x65, 0x63, + 0x6f, 0x6d, 0x6d, 0x65, 0x72, 0x63, 0x69, 0x61, 0x6c, 0x20, 0x70, 0x6f, 0x69, + 0x6e, 0x74, 0x65, 0x64, 0x20, 0x6f, 0x75, 0x74, 0x6f, 0x70, 0x70, 0x6f, 0x72, + 0x74, 0x75, 0x6e, 0x69, 0x74, 0x79, 0x76, 0x69, 0x65, 0x77, 0x20, 0x6f, 0x66, + 0x20, 0x74, 0x68, 0x65, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x6d, 0x65, + 0x6e, 0x74, 0x64, 0x69, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x20, 0x6f, 0x66, + 0x70, 0x72, 0x6f, 0x67, 0x72, 0x61, 0x6d, 0x6d, 0x69, 0x6e, 0x67, 0x68, 0x65, + 0x20, 0x72, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x64, 0x73, 0x65, 0x74, 0x49, + 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x22, 0x3e, 0x3c, 0x2f, 0x73, 0x70, + 0x61, 0x6e, 0x3e, 0x3c, 0x2f, 0x69, 0x6e, 0x20, 0x4e, 0x65, 0x77, 0x20, 0x59, + 0x6f, 0x72, 0x6b, 0x61, 0x64, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, + 0x20, 0x63, 0x6f, 0x6d, 0x70, 0x72, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x0a, + 0x0a, 0x3c, 0x64, 0x69, 0x76, 0x20, 0x69, 0x64, 0x3d, 0x22, 0x69, 0x6e, 0x63, + 0x6f, 0x72, 0x70, 0x6f, 0x72, 0x61, 0x74, 0x65, 0x3b, 0x3c, 0x2f, 0x73, 0x63, + 0x72, 0x69, 0x70, 0x74, 0x3e, 0x3c, 0x61, 0x74, 0x74, 0x61, 0x63, 0x68, 0x45, + 0x76, 0x65, 0x6e, 0x74, 0x62, 0x65, 0x63, 0x61, 0x6d, 0x65, 0x20, 0x74, 0x68, + 0x65, 0x20, 0x22, 0x20, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x3d, 0x22, 0x5f, + 0x63, 0x61, 0x72, 0x72, 0x69, 0x65, 0x64, 0x20, 0x6f, 0x75, 0x74, 0x53, 0x6f, + 0x6d, 0x65, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x73, 0x63, 0x69, 0x65, + 0x6e, 0x63, 0x65, 0x20, 0x61, 0x6e, 0x64, 0x74, 0x68, 0x65, 0x20, 0x74, 0x69, + 0x6d, 0x65, 0x20, 0x6f, 0x66, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, + 0x72, 0x22, 0x3e, 0x6d, 0x61, 0x69, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x69, 0x6e, + 0x67, 0x43, 0x68, 0x72, 0x69, 0x73, 0x74, 0x6f, 0x70, 0x68, 0x65, 0x72, 0x4d, + 0x75, 0x63, 0x68, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x77, 0x72, 0x69, + 0x74, 0x69, 0x6e, 0x67, 0x73, 0x20, 0x6f, 0x66, 0x22, 0x20, 0x68, 0x65, 0x69, + 0x67, 0x68, 0x74, 0x3d, 0x22, 0x32, 0x73, 0x69, 0x7a, 0x65, 0x20, 0x6f, 0x66, + 0x20, 0x74, 0x68, 0x65, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x20, 0x6f, + 0x66, 0x20, 0x6d, 0x69, 0x78, 0x74, 0x75, 0x72, 0x65, 0x20, 0x6f, 0x66, 0x20, + 0x62, 0x65, 0x74, 0x77, 0x65, 0x65, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x45, 0x78, + 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x73, 0x20, 0x6f, 0x66, 0x65, 0x64, 0x75, 0x63, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x63, 0x6f, 0x6d, 0x70, 0x65, 0x74, + 0x69, 0x74, 0x69, 0x76, 0x65, 0x20, 0x6f, 0x6e, 0x73, 0x75, 0x62, 0x6d, 0x69, + 0x74, 0x3d, 0x22, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x20, 0x6f, + 0x66, 0x64, 0x69, 0x73, 0x74, 0x69, 0x6e, 0x63, 0x74, 0x69, 0x76, 0x65, 0x2f, + 0x44, 0x54, 0x44, 0x20, 0x58, 0x48, 0x54, 0x4d, 0x4c, 0x20, 0x72, 0x65, 0x6c, + 0x61, 0x74, 0x69, 0x6e, 0x67, 0x20, 0x74, 0x6f, 0x74, 0x65, 0x6e, 0x64, 0x65, + 0x6e, 0x63, 0x79, 0x20, 0x74, 0x6f, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x6e, 0x63, + 0x65, 0x20, 0x6f, 0x66, 0x77, 0x68, 0x69, 0x63, 0x68, 0x20, 0x77, 0x6f, 0x75, + 0x6c, 0x64, 0x64, 0x65, 0x73, 0x70, 0x69, 0x74, 0x65, 0x20, 0x74, 0x68, 0x65, + 0x73, 0x63, 0x69, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x63, 0x20, 0x6c, 0x65, + 0x67, 0x69, 0x73, 0x6c, 0x61, 0x74, 0x75, 0x72, 0x65, 0x2e, 0x69, 0x6e, 0x6e, + 0x65, 0x72, 0x48, 0x54, 0x4d, 0x4c, 0x20, 0x61, 0x6c, 0x6c, 0x65, 0x67, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x41, 0x67, 0x72, 0x69, 0x63, 0x75, 0x6c, 0x74, + 0x75, 0x72, 0x65, 0x77, 0x61, 0x73, 0x20, 0x75, 0x73, 0x65, 0x64, 0x20, 0x69, + 0x6e, 0x61, 0x70, 0x70, 0x72, 0x6f, 0x61, 0x63, 0x68, 0x20, 0x74, 0x6f, 0x69, + 0x6e, 0x74, 0x65, 0x6c, 0x6c, 0x69, 0x67, 0x65, 0x6e, 0x74, 0x79, 0x65, 0x61, + 0x72, 0x73, 0x20, 0x6c, 0x61, 0x74, 0x65, 0x72, 0x2c, 0x73, 0x61, 0x6e, 0x73, + 0x2d, 0x73, 0x65, 0x72, 0x69, 0x66, 0x64, 0x65, 0x74, 0x65, 0x72, 0x6d, 0x69, + 0x6e, 0x69, 0x6e, 0x67, 0x50, 0x65, 0x72, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x6e, + 0x63, 0x65, 0x61, 0x70, 0x70, 0x65, 0x61, 0x72, 0x61, 0x6e, 0x63, 0x65, 0x73, + 0x2c, 0x20, 0x77, 0x68, 0x69, 0x63, 0x68, 0x20, 0x69, 0x73, 0x20, 0x66, 0x6f, + 0x75, 0x6e, 0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x61, 0x62, 0x62, 0x72, + 0x65, 0x76, 0x69, 0x61, 0x74, 0x65, 0x64, 0x68, 0x69, 0x67, 0x68, 0x65, 0x72, + 0x20, 0x74, 0x68, 0x61, 0x6e, 0x73, 0x20, 0x66, 0x72, 0x6f, 0x6d, 0x20, 0x74, + 0x68, 0x65, 0x20, 0x69, 0x6e, 0x64, 0x69, 0x76, 0x69, 0x64, 0x75, 0x61, 0x6c, + 0x20, 0x63, 0x6f, 0x6d, 0x70, 0x6f, 0x73, 0x65, 0x64, 0x20, 0x6f, 0x66, 0x73, + 0x75, 0x70, 0x70, 0x6f, 0x73, 0x65, 0x64, 0x20, 0x74, 0x6f, 0x63, 0x6c, 0x61, + 0x69, 0x6d, 0x73, 0x20, 0x74, 0x68, 0x61, 0x74, 0x61, 0x74, 0x74, 0x72, 0x69, + 0x62, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x66, 0x6f, 0x6e, 0x74, 0x2d, 0x73, 0x69, + 0x7a, 0x65, 0x3a, 0x31, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x20, + 0x6f, 0x66, 0x48, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x69, 0x63, 0x61, 0x6c, 0x20, + 0x68, 0x69, 0x73, 0x20, 0x62, 0x72, 0x6f, 0x74, 0x68, 0x65, 0x72, 0x61, 0x74, + 0x20, 0x74, 0x68, 0x65, 0x20, 0x74, 0x69, 0x6d, 0x65, 0x61, 0x6e, 0x6e, 0x69, + 0x76, 0x65, 0x72, 0x73, 0x61, 0x72, 0x79, 0x67, 0x6f, 0x76, 0x65, 0x72, 0x6e, + 0x65, 0x64, 0x20, 0x62, 0x79, 0x72, 0x65, 0x6c, 0x61, 0x74, 0x65, 0x64, 0x20, + 0x74, 0x6f, 0x20, 0x75, 0x6c, 0x74, 0x69, 0x6d, 0x61, 0x74, 0x65, 0x6c, 0x79, + 0x20, 0x69, 0x6e, 0x6e, 0x6f, 0x76, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x69, + 0x74, 0x20, 0x69, 0x73, 0x20, 0x73, 0x74, 0x69, 0x6c, 0x6c, 0x63, 0x61, 0x6e, + 0x20, 0x6f, 0x6e, 0x6c, 0x79, 0x20, 0x62, 0x65, 0x64, 0x65, 0x66, 0x69, 0x6e, + 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x74, 0x6f, 0x47, 0x4d, 0x54, 0x53, 0x74, + 0x72, 0x69, 0x6e, 0x67, 0x41, 0x20, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x20, + 0x6f, 0x66, 0x69, 0x6d, 0x67, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x22, + 0x45, 0x76, 0x65, 0x6e, 0x74, 0x75, 0x61, 0x6c, 0x6c, 0x79, 0x2c, 0x77, 0x61, + 0x73, 0x20, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x64, 0x6f, 0x63, 0x63, 0x75, + 0x72, 0x72, 0x65, 0x64, 0x20, 0x69, 0x6e, 0x6e, 0x65, 0x69, 0x67, 0x68, 0x62, + 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x64, 0x69, 0x73, 0x74, 0x69, 0x6e, 0x67, 0x75, + 0x69, 0x73, 0x68, 0x77, 0x68, 0x65, 0x6e, 0x20, 0x68, 0x65, 0x20, 0x77, 0x61, + 0x73, 0x69, 0x6e, 0x74, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x69, 0x6e, 0x67, 0x74, + 0x65, 0x72, 0x72, 0x65, 0x73, 0x74, 0x72, 0x69, 0x61, 0x6c, 0x4d, 0x61, 0x6e, + 0x79, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x61, 0x72, 0x67, 0x75, 0x65, + 0x73, 0x20, 0x74, 0x68, 0x61, 0x74, 0x61, 0x6e, 0x20, 0x41, 0x6d, 0x65, 0x72, + 0x69, 0x63, 0x61, 0x6e, 0x63, 0x6f, 0x6e, 0x71, 0x75, 0x65, 0x73, 0x74, 0x20, + 0x6f, 0x66, 0x77, 0x69, 0x64, 0x65, 0x73, 0x70, 0x72, 0x65, 0x61, 0x64, 0x20, + 0x77, 0x65, 0x72, 0x65, 0x20, 0x6b, 0x69, 0x6c, 0x6c, 0x65, 0x64, 0x73, 0x63, + 0x72, 0x65, 0x65, 0x6e, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x49, 0x6e, 0x20, 0x6f, + 0x72, 0x64, 0x65, 0x72, 0x20, 0x74, 0x6f, 0x65, 0x78, 0x70, 0x65, 0x63, 0x74, + 0x65, 0x64, 0x20, 0x74, 0x6f, 0x64, 0x65, 0x73, 0x63, 0x65, 0x6e, 0x64, 0x61, + 0x6e, 0x74, 0x73, 0x61, 0x72, 0x65, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x65, + 0x64, 0x6c, 0x65, 0x67, 0x69, 0x73, 0x6c, 0x61, 0x74, 0x69, 0x76, 0x65, 0x67, + 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x62, 0x61, + 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x6d, 0x6f, 0x73, 0x74, 0x20, + 0x70, 0x65, 0x6f, 0x70, 0x6c, 0x65, 0x79, 0x65, 0x61, 0x72, 0x73, 0x20, 0x61, + 0x66, 0x74, 0x65, 0x72, 0x74, 0x68, 0x65, 0x72, 0x65, 0x20, 0x69, 0x73, 0x20, + 0x6e, 0x6f, 0x74, 0x68, 0x65, 0x20, 0x68, 0x69, 0x67, 0x68, 0x65, 0x73, 0x74, + 0x66, 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x74, 0x6c, 0x79, 0x20, 0x74, 0x68, + 0x65, 0x79, 0x20, 0x64, 0x6f, 0x20, 0x6e, 0x6f, 0x74, 0x61, 0x72, 0x67, 0x75, + 0x65, 0x64, 0x20, 0x74, 0x68, 0x61, 0x74, 0x73, 0x68, 0x6f, 0x77, 0x65, 0x64, + 0x20, 0x74, 0x68, 0x61, 0x74, 0x70, 0x72, 0x65, 0x64, 0x6f, 0x6d, 0x69, 0x6e, + 0x61, 0x6e, 0x74, 0x74, 0x68, 0x65, 0x6f, 0x6c, 0x6f, 0x67, 0x69, 0x63, 0x61, + 0x6c, 0x62, 0x79, 0x20, 0x74, 0x68, 0x65, 0x20, 0x74, 0x69, 0x6d, 0x65, 0x63, + 0x6f, 0x6e, 0x73, 0x69, 0x64, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x73, 0x68, 0x6f, + 0x72, 0x74, 0x2d, 0x6c, 0x69, 0x76, 0x65, 0x64, 0x3c, 0x2f, 0x73, 0x70, 0x61, + 0x6e, 0x3e, 0x3c, 0x2f, 0x61, 0x3e, 0x63, 0x61, 0x6e, 0x20, 0x62, 0x65, 0x20, + 0x75, 0x73, 0x65, 0x64, 0x76, 0x65, 0x72, 0x79, 0x20, 0x6c, 0x69, 0x74, 0x74, + 0x6c, 0x65, 0x6f, 0x6e, 0x65, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, + 0x68, 0x61, 0x64, 0x20, 0x61, 0x6c, 0x72, 0x65, 0x61, 0x64, 0x79, 0x69, 0x6e, + 0x74, 0x65, 0x72, 0x70, 0x72, 0x65, 0x74, 0x65, 0x64, 0x63, 0x6f, 0x6d, 0x6d, + 0x75, 0x6e, 0x69, 0x63, 0x61, 0x74, 0x65, 0x66, 0x65, 0x61, 0x74, 0x75, 0x72, + 0x65, 0x73, 0x20, 0x6f, 0x66, 0x67, 0x6f, 0x76, 0x65, 0x72, 0x6e, 0x6d, 0x65, + 0x6e, 0x74, 0x2c, 0x3c, 0x2f, 0x6e, 0x6f, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, + 0x3e, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x65, 0x64, 0x20, 0x74, 0x68, 0x65, 0x22, + 0x20, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x3d, 0x22, 0x33, 0x49, 0x6e, 0x64, + 0x65, 0x70, 0x65, 0x6e, 0x64, 0x65, 0x6e, 0x74, 0x70, 0x6f, 0x70, 0x75, 0x6c, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x6c, 0x61, 0x72, 0x67, 0x65, 0x2d, 0x73, + 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x20, 0x41, 0x6c, 0x74, 0x68, 0x6f, 0x75, 0x67, + 0x68, 0x20, 0x75, 0x73, 0x65, 0x64, 0x20, 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, + 0x64, 0x65, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x70, 0x6f, + 0x73, 0x73, 0x69, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x73, 0x74, 0x61, 0x72, + 0x74, 0x69, 0x6e, 0x67, 0x20, 0x69, 0x6e, 0x74, 0x77, 0x6f, 0x20, 0x6f, 0x72, + 0x20, 0x6d, 0x6f, 0x72, 0x65, 0x65, 0x78, 0x70, 0x72, 0x65, 0x73, 0x73, 0x69, + 0x6f, 0x6e, 0x73, 0x73, 0x75, 0x62, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x61, 0x74, + 0x65, 0x6c, 0x61, 0x72, 0x67, 0x65, 0x72, 0x20, 0x74, 0x68, 0x61, 0x6e, 0x68, + 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x20, 0x61, 0x6e, 0x64, 0x3c, 0x2f, 0x6f, + 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x3e, 0x0d, 0x0a, 0x43, 0x6f, 0x6e, 0x74, 0x69, + 0x6e, 0x65, 0x6e, 0x74, 0x61, 0x6c, 0x65, 0x6c, 0x69, 0x6d, 0x69, 0x6e, 0x61, + 0x74, 0x69, 0x6e, 0x67, 0x77, 0x69, 0x6c, 0x6c, 0x20, 0x6e, 0x6f, 0x74, 0x20, + 0x62, 0x65, 0x70, 0x72, 0x61, 0x63, 0x74, 0x69, 0x63, 0x65, 0x20, 0x6f, 0x66, + 0x69, 0x6e, 0x20, 0x66, 0x72, 0x6f, 0x6e, 0x74, 0x20, 0x6f, 0x66, 0x73, 0x69, + 0x74, 0x65, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x65, 0x6e, 0x73, 0x75, + 0x72, 0x65, 0x20, 0x74, 0x68, 0x61, 0x74, 0x74, 0x6f, 0x20, 0x63, 0x72, 0x65, + 0x61, 0x74, 0x65, 0x20, 0x61, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x73, 0x73, 0x69, + 0x70, 0x70, 0x69, 0x70, 0x6f, 0x74, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x6c, + 0x79, 0x6f, 0x75, 0x74, 0x73, 0x74, 0x61, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x62, + 0x65, 0x74, 0x74, 0x65, 0x72, 0x20, 0x74, 0x68, 0x61, 0x6e, 0x77, 0x68, 0x61, + 0x74, 0x20, 0x69, 0x73, 0x20, 0x6e, 0x6f, 0x77, 0x73, 0x69, 0x74, 0x75, 0x61, + 0x74, 0x65, 0x64, 0x20, 0x69, 0x6e, 0x6d, 0x65, 0x74, 0x61, 0x20, 0x6e, 0x61, + 0x6d, 0x65, 0x3d, 0x22, 0x54, 0x72, 0x61, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, + 0x61, 0x6c, 0x73, 0x75, 0x67, 0x67, 0x65, 0x73, 0x74, 0x69, 0x6f, 0x6e, 0x73, + 0x54, 0x72, 0x61, 0x6e, 0x73, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x74, 0x68, + 0x65, 0x20, 0x66, 0x6f, 0x72, 0x6d, 0x20, 0x6f, 0x66, 0x61, 0x74, 0x6d, 0x6f, + 0x73, 0x70, 0x68, 0x65, 0x72, 0x69, 0x63, 0x69, 0x64, 0x65, 0x6f, 0x6c, 0x6f, + 0x67, 0x69, 0x63, 0x61, 0x6c, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x70, 0x72, 0x69, + 0x73, 0x65, 0x73, 0x63, 0x61, 0x6c, 0x63, 0x75, 0x6c, 0x61, 0x74, 0x69, 0x6e, + 0x67, 0x65, 0x61, 0x73, 0x74, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x72, + 0x65, 0x6d, 0x6e, 0x61, 0x6e, 0x74, 0x73, 0x20, 0x6f, 0x66, 0x70, 0x6c, 0x75, + 0x67, 0x69, 0x6e, 0x73, 0x70, 0x61, 0x67, 0x65, 0x2f, 0x69, 0x6e, 0x64, 0x65, + 0x78, 0x2e, 0x70, 0x68, 0x70, 0x3f, 0x72, 0x65, 0x6d, 0x61, 0x69, 0x6e, 0x65, + 0x64, 0x20, 0x69, 0x6e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x6f, 0x72, 0x6d, + 0x65, 0x64, 0x48, 0x65, 0x20, 0x77, 0x61, 0x73, 0x20, 0x61, 0x6c, 0x73, 0x6f, + 0x77, 0x61, 0x73, 0x20, 0x61, 0x6c, 0x72, 0x65, 0x61, 0x64, 0x79, 0x73, 0x74, + 0x61, 0x74, 0x69, 0x73, 0x74, 0x69, 0x63, 0x61, 0x6c, 0x69, 0x6e, 0x20, 0x66, + 0x61, 0x76, 0x6f, 0x72, 0x20, 0x6f, 0x66, 0x4d, 0x69, 0x6e, 0x69, 0x73, 0x74, + 0x72, 0x79, 0x20, 0x6f, 0x66, 0x6d, 0x6f, 0x76, 0x65, 0x6d, 0x65, 0x6e, 0x74, + 0x20, 0x6f, 0x66, 0x66, 0x6f, 0x72, 0x6d, 0x75, 0x6c, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x69, 0x73, 0x20, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x3c, + 0x6c, 0x69, 0x6e, 0x6b, 0x20, 0x72, 0x65, 0x6c, 0x3d, 0x22, 0x54, 0x68, 0x69, + 0x73, 0x20, 0x69, 0x73, 0x20, 0x74, 0x68, 0x65, 0x20, 0x3c, 0x61, 0x20, 0x68, + 0x72, 0x65, 0x66, 0x3d, 0x22, 0x2f, 0x70, 0x6f, 0x70, 0x75, 0x6c, 0x61, 0x72, + 0x69, 0x7a, 0x65, 0x64, 0x69, 0x6e, 0x76, 0x6f, 0x6c, 0x76, 0x65, 0x64, 0x20, + 0x69, 0x6e, 0x61, 0x72, 0x65, 0x20, 0x75, 0x73, 0x65, 0x64, 0x20, 0x74, 0x6f, + 0x61, 0x6e, 0x64, 0x20, 0x73, 0x65, 0x76, 0x65, 0x72, 0x61, 0x6c, 0x6d, 0x61, + 0x64, 0x65, 0x20, 0x62, 0x79, 0x20, 0x74, 0x68, 0x65, 0x73, 0x65, 0x65, 0x6d, + 0x73, 0x20, 0x74, 0x6f, 0x20, 0x62, 0x65, 0x6c, 0x69, 0x6b, 0x65, 0x6c, 0x79, + 0x20, 0x74, 0x68, 0x61, 0x74, 0x50, 0x61, 0x6c, 0x65, 0x73, 0x74, 0x69, 0x6e, + 0x69, 0x61, 0x6e, 0x6e, 0x61, 0x6d, 0x65, 0x64, 0x20, 0x61, 0x66, 0x74, 0x65, + 0x72, 0x69, 0x74, 0x20, 0x68, 0x61, 0x64, 0x20, 0x62, 0x65, 0x65, 0x6e, 0x6d, + 0x6f, 0x73, 0x74, 0x20, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x74, 0x6f, 0x20, + 0x72, 0x65, 0x66, 0x65, 0x72, 0x20, 0x74, 0x6f, 0x62, 0x75, 0x74, 0x20, 0x74, + 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, 0x63, 0x6f, 0x6e, 0x73, 0x65, 0x63, 0x75, + 0x74, 0x69, 0x76, 0x65, 0x74, 0x65, 0x6d, 0x70, 0x6f, 0x72, 0x61, 0x72, 0x69, + 0x6c, 0x79, 0x49, 0x6e, 0x20, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x6c, 0x2c, + 0x63, 0x6f, 0x6e, 0x76, 0x65, 0x6e, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x74, 0x61, + 0x6b, 0x65, 0x73, 0x20, 0x70, 0x6c, 0x61, 0x63, 0x65, 0x73, 0x75, 0x62, 0x64, + 0x69, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x74, 0x65, 0x72, 0x72, 0x69, 0x74, + 0x6f, 0x72, 0x69, 0x61, 0x6c, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x61, 0x6c, 0x70, 0x65, 0x72, 0x6d, 0x61, 0x6e, 0x65, 0x6e, 0x74, 0x6c, + 0x79, 0x77, 0x61, 0x73, 0x20, 0x6c, 0x61, 0x72, 0x67, 0x65, 0x6c, 0x79, 0x6f, + 0x75, 0x74, 0x62, 0x72, 0x65, 0x61, 0x6b, 0x20, 0x6f, 0x66, 0x69, 0x6e, 0x20, + 0x74, 0x68, 0x65, 0x20, 0x70, 0x61, 0x73, 0x74, 0x66, 0x6f, 0x6c, 0x6c, 0x6f, + 0x77, 0x69, 0x6e, 0x67, 0x20, 0x61, 0x20, 0x78, 0x6d, 0x6c, 0x6e, 0x73, 0x3a, + 0x6f, 0x67, 0x3d, 0x22, 0x3e, 0x3c, 0x61, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, + 0x3d, 0x22, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x22, 0x74, 0x65, 0x78, 0x74, + 0x43, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x20, 0x6d, 0x61, + 0x79, 0x20, 0x62, 0x65, 0x20, 0x75, 0x73, 0x65, 0x64, 0x6d, 0x61, 0x6e, 0x75, + 0x66, 0x61, 0x63, 0x74, 0x75, 0x72, 0x65, 0x61, 0x66, 0x74, 0x65, 0x72, 0x20, + 0x62, 0x65, 0x69, 0x6e, 0x67, 0x63, 0x6c, 0x65, 0x61, 0x72, 0x66, 0x69, 0x78, + 0x22, 0x3e, 0x0a, 0x71, 0x75, 0x65, 0x73, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6f, + 0x66, 0x77, 0x61, 0x73, 0x20, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x65, 0x64, 0x74, + 0x6f, 0x20, 0x62, 0x65, 0x63, 0x6f, 0x6d, 0x65, 0x20, 0x61, 0x62, 0x65, 0x63, + 0x61, 0x75, 0x73, 0x65, 0x20, 0x6f, 0x66, 0x20, 0x73, 0x6f, 0x6d, 0x65, 0x20, + 0x70, 0x65, 0x6f, 0x70, 0x6c, 0x65, 0x69, 0x6e, 0x73, 0x70, 0x69, 0x72, 0x65, + 0x64, 0x20, 0x62, 0x79, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x66, 0x75, + 0x6c, 0x20, 0x61, 0x20, 0x74, 0x69, 0x6d, 0x65, 0x20, 0x77, 0x68, 0x65, 0x6e, + 0x6d, 0x6f, 0x72, 0x65, 0x20, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x61, 0x6d, + 0x6f, 0x6e, 0x67, 0x73, 0x74, 0x20, 0x74, 0x68, 0x65, 0x61, 0x6e, 0x20, 0x6f, + 0x66, 0x66, 0x69, 0x63, 0x69, 0x61, 0x6c, 0x77, 0x69, 0x64, 0x74, 0x68, 0x3a, + 0x31, 0x30, 0x30, 0x25, 0x3b, 0x74, 0x65, 0x63, 0x68, 0x6e, 0x6f, 0x6c, 0x6f, + 0x67, 0x79, 0x2c, 0x77, 0x61, 0x73, 0x20, 0x61, 0x64, 0x6f, 0x70, 0x74, 0x65, + 0x64, 0x74, 0x6f, 0x20, 0x6b, 0x65, 0x65, 0x70, 0x20, 0x74, 0x68, 0x65, 0x73, + 0x65, 0x74, 0x74, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x6c, 0x69, 0x76, + 0x65, 0x20, 0x62, 0x69, 0x72, 0x74, 0x68, 0x73, 0x69, 0x6e, 0x64, 0x65, 0x78, + 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0x22, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, + 0x69, 0x63, 0x75, 0x74, 0x61, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x20, + 0x74, 0x6f, 0x26, 0x61, 0x6d, 0x70, 0x3b, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x3b, + 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x20, 0x66, 0x6f, 0x72, 0x61, 0x6c, + 0x69, 0x67, 0x6e, 0x3d, 0x72, 0x69, 0x67, 0x68, 0x74, 0x74, 0x68, 0x65, 0x20, + 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x6e, 0x79, 0x61, 0x6c, 0x77, 0x61, 0x79, 0x73, + 0x20, 0x62, 0x65, 0x65, 0x6e, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x65, 0x64, + 0x20, 0x74, 0x6f, 0x69, 0x6e, 0x76, 0x6f, 0x6c, 0x76, 0x65, 0x6d, 0x65, 0x6e, + 0x74, 0x42, 0x65, 0x63, 0x61, 0x75, 0x73, 0x65, 0x20, 0x74, 0x68, 0x65, 0x74, + 0x68, 0x69, 0x73, 0x20, 0x70, 0x65, 0x72, 0x69, 0x6f, 0x64, 0x22, 0x20, 0x6e, + 0x61, 0x6d, 0x65, 0x3d, 0x22, 0x71, 0x22, 0x20, 0x63, 0x6f, 0x6e, 0x66, 0x69, + 0x6e, 0x65, 0x64, 0x20, 0x74, 0x6f, 0x61, 0x20, 0x72, 0x65, 0x73, 0x75, 0x6c, + 0x74, 0x20, 0x6f, 0x66, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3d, 0x22, 0x22, 0x20, + 0x2f, 0x3e, 0x69, 0x73, 0x20, 0x61, 0x63, 0x74, 0x75, 0x61, 0x6c, 0x6c, 0x79, + 0x45, 0x6e, 0x76, 0x69, 0x72, 0x6f, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x0d, 0x0a, + 0x3c, 0x2f, 0x68, 0x65, 0x61, 0x64, 0x3e, 0x0d, 0x0a, 0x43, 0x6f, 0x6e, 0x76, + 0x65, 0x72, 0x73, 0x65, 0x6c, 0x79, 0x2c, 0x3e, 0x0a, 0x3c, 0x64, 0x69, 0x76, + 0x20, 0x69, 0x64, 0x3d, 0x22, 0x30, 0x22, 0x20, 0x77, 0x69, 0x64, 0x74, 0x68, + 0x3d, 0x22, 0x31, 0x69, 0x73, 0x20, 0x70, 0x72, 0x6f, 0x62, 0x61, 0x62, 0x6c, + 0x79, 0x68, 0x61, 0x76, 0x65, 0x20, 0x62, 0x65, 0x63, 0x6f, 0x6d, 0x65, 0x63, + 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x69, 0x6e, 0x67, 0x74, 0x68, 0x65, + 0x20, 0x70, 0x72, 0x6f, 0x62, 0x6c, 0x65, 0x6d, 0x63, 0x69, 0x74, 0x69, 0x7a, + 0x65, 0x6e, 0x73, 0x20, 0x6f, 0x66, 0x70, 0x6f, 0x6c, 0x69, 0x74, 0x69, 0x63, + 0x69, 0x61, 0x6e, 0x73, 0x72, 0x65, 0x61, 0x63, 0x68, 0x65, 0x64, 0x20, 0x74, + 0x68, 0x65, 0x61, 0x73, 0x20, 0x65, 0x61, 0x72, 0x6c, 0x79, 0x20, 0x61, 0x73, + 0x3a, 0x6e, 0x6f, 0x6e, 0x65, 0x3b, 0x20, 0x6f, 0x76, 0x65, 0x72, 0x3c, 0x74, + 0x61, 0x62, 0x6c, 0x65, 0x20, 0x63, 0x65, 0x6c, 0x6c, 0x76, 0x61, 0x6c, 0x69, + 0x64, 0x69, 0x74, 0x79, 0x20, 0x6f, 0x66, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, + 0x6c, 0x79, 0x20, 0x74, 0x6f, 0x6f, 0x6e, 0x6d, 0x6f, 0x75, 0x73, 0x65, 0x64, + 0x6f, 0x77, 0x6e, 0x77, 0x68, 0x65, 0x72, 0x65, 0x20, 0x69, 0x74, 0x20, 0x69, + 0x73, 0x77, 0x68, 0x65, 0x6e, 0x20, 0x69, 0x74, 0x20, 0x77, 0x61, 0x73, 0x6d, + 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x20, 0x6f, 0x66, 0x20, 0x72, 0x65, 0x6c, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x74, 0x6f, 0x61, 0x63, 0x63, 0x6f, 0x6d, + 0x6d, 0x6f, 0x64, 0x61, 0x74, 0x65, 0x61, 0x6c, 0x6f, 0x6e, 0x67, 0x20, 0x77, + 0x69, 0x74, 0x68, 0x20, 0x49, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x6c, 0x61, + 0x74, 0x65, 0x74, 0x68, 0x65, 0x20, 0x45, 0x6e, 0x67, 0x6c, 0x69, 0x73, 0x68, + 0x64, 0x65, 0x6c, 0x69, 0x63, 0x69, 0x6f, 0x75, 0x73, 0x22, 0x3e, 0x74, 0x68, + 0x69, 0x73, 0x20, 0x69, 0x73, 0x20, 0x6e, 0x6f, 0x74, 0x74, 0x68, 0x65, 0x20, + 0x70, 0x72, 0x65, 0x73, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x20, 0x74, 0x68, 0x65, + 0x79, 0x20, 0x61, 0x72, 0x65, 0x61, 0x6e, 0x64, 0x20, 0x66, 0x69, 0x6e, 0x61, + 0x6c, 0x6c, 0x79, 0x61, 0x20, 0x6d, 0x61, 0x74, 0x74, 0x65, 0x72, 0x20, 0x6f, + 0x66, 0x0d, 0x0a, 0x09, 0x3c, 0x2f, 0x64, 0x69, 0x76, 0x3e, 0x0d, 0x0a, 0x0d, + 0x0a, 0x3c, 0x2f, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x3e, 0x66, 0x61, 0x73, + 0x74, 0x65, 0x72, 0x20, 0x74, 0x68, 0x61, 0x6e, 0x6d, 0x61, 0x6a, 0x6f, 0x72, + 0x69, 0x74, 0x79, 0x20, 0x6f, 0x66, 0x61, 0x66, 0x74, 0x65, 0x72, 0x20, 0x77, + 0x68, 0x69, 0x63, 0x68, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x72, 0x61, 0x74, 0x69, + 0x76, 0x65, 0x74, 0x6f, 0x20, 0x6d, 0x61, 0x69, 0x6e, 0x74, 0x61, 0x69, 0x6e, + 0x69, 0x6d, 0x70, 0x72, 0x6f, 0x76, 0x65, 0x20, 0x74, 0x68, 0x65, 0x61, 0x77, + 0x61, 0x72, 0x64, 0x65, 0x64, 0x20, 0x74, 0x68, 0x65, 0x65, 0x72, 0x22, 0x20, + 0x63, 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x22, 0x66, 0x72, 0x61, 0x6d, 0x65, 0x62, + 0x6f, 0x72, 0x64, 0x65, 0x72, 0x72, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x73, 0x61, 0x6d, + 0x65, 0x61, 0x6e, 0x61, 0x6c, 0x79, 0x73, 0x69, 0x73, 0x20, 0x6f, 0x66, 0x74, + 0x68, 0x65, 0x69, 0x72, 0x20, 0x66, 0x69, 0x72, 0x73, 0x74, 0x44, 0x75, 0x72, + 0x69, 0x6e, 0x67, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x69, + 0x6e, 0x65, 0x6e, 0x74, 0x61, 0x6c, 0x73, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, + 0x65, 0x20, 0x6f, 0x66, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, + 0x29, 0x7b, 0x66, 0x6f, 0x6e, 0x74, 0x2d, 0x73, 0x69, 0x7a, 0x65, 0x3a, 0x20, + 0x77, 0x6f, 0x72, 0x6b, 0x20, 0x6f, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x3c, 0x2f, + 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x3e, 0x0a, 0x3c, 0x62, 0x65, 0x67, 0x69, + 0x6e, 0x73, 0x20, 0x77, 0x69, 0x74, 0x68, 0x6a, 0x61, 0x76, 0x61, 0x73, 0x63, + 0x72, 0x69, 0x70, 0x74, 0x3a, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x69, 0x74, 0x75, + 0x65, 0x6e, 0x74, 0x77, 0x61, 0x73, 0x20, 0x66, 0x6f, 0x75, 0x6e, 0x64, 0x65, + 0x64, 0x65, 0x71, 0x75, 0x69, 0x6c, 0x69, 0x62, 0x72, 0x69, 0x75, 0x6d, 0x61, + 0x73, 0x73, 0x75, 0x6d, 0x65, 0x20, 0x74, 0x68, 0x61, 0x74, 0x69, 0x73, 0x20, + 0x67, 0x69, 0x76, 0x65, 0x6e, 0x20, 0x62, 0x79, 0x6e, 0x65, 0x65, 0x64, 0x73, + 0x20, 0x74, 0x6f, 0x20, 0x62, 0x65, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x69, 0x6e, + 0x61, 0x74, 0x65, 0x73, 0x74, 0x68, 0x65, 0x20, 0x76, 0x61, 0x72, 0x69, 0x6f, + 0x75, 0x73, 0x61, 0x72, 0x65, 0x20, 0x70, 0x61, 0x72, 0x74, 0x20, 0x6f, 0x66, + 0x6f, 0x6e, 0x6c, 0x79, 0x20, 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x73, 0x65, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x6f, 0x66, 0x69, 0x73, 0x20, 0x61, + 0x20, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x74, 0x68, 0x65, 0x6f, 0x72, 0x69, + 0x65, 0x73, 0x20, 0x6f, 0x66, 0x64, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, + 0x69, 0x65, 0x73, 0x61, 0x73, 0x73, 0x6f, 0x63, 0x69, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x65, 0x64, 0x67, 0x65, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x73, + 0x74, 0x72, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x20, 0x6f, 0x66, 0x70, 0x6f, 0x73, + 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x69, 0x6e, 0x70, 0x72, 0x65, 0x73, 0x65, + 0x6e, 0x74, 0x2d, 0x64, 0x61, 0x79, 0x75, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, + 0x61, 0x6c, 0x6c, 0x79, 0x74, 0x6f, 0x20, 0x66, 0x6f, 0x72, 0x6d, 0x20, 0x74, + 0x68, 0x65, 0x62, 0x75, 0x74, 0x20, 0x69, 0x6e, 0x73, 0x74, 0x65, 0x61, 0x64, + 0x63, 0x6f, 0x72, 0x70, 0x6f, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x74, + 0x74, 0x61, 0x63, 0x68, 0x65, 0x64, 0x20, 0x74, 0x6f, 0x69, 0x73, 0x20, 0x63, + 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x6c, 0x79, 0x72, 0x65, 0x61, 0x73, 0x6f, 0x6e, + 0x73, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x26, 0x71, 0x75, 0x6f, 0x74, 0x3b, 0x74, + 0x68, 0x65, 0x20, 0x63, 0x61, 0x6e, 0x20, 0x62, 0x65, 0x20, 0x6d, 0x61, 0x64, + 0x65, 0x77, 0x61, 0x73, 0x20, 0x61, 0x62, 0x6c, 0x65, 0x20, 0x74, 0x6f, 0x77, + 0x68, 0x69, 0x63, 0x68, 0x20, 0x6d, 0x65, 0x61, 0x6e, 0x73, 0x62, 0x75, 0x74, + 0x20, 0x64, 0x69, 0x64, 0x20, 0x6e, 0x6f, 0x74, 0x6f, 0x6e, 0x4d, 0x6f, 0x75, + 0x73, 0x65, 0x4f, 0x76, 0x65, 0x72, 0x61, 0x73, 0x20, 0x70, 0x6f, 0x73, 0x73, + 0x69, 0x62, 0x6c, 0x65, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x65, 0x64, 0x20, + 0x62, 0x79, 0x63, 0x6f, 0x6d, 0x69, 0x6e, 0x67, 0x20, 0x66, 0x72, 0x6f, 0x6d, + 0x74, 0x68, 0x65, 0x20, 0x70, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x61, 0x64, + 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6f, 0x66, 0x66, 0x6f, 0x72, 0x20, + 0x73, 0x65, 0x76, 0x65, 0x72, 0x61, 0x6c, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, + 0x65, 0x72, 0x72, 0x65, 0x64, 0x61, 0x20, 0x70, 0x65, 0x72, 0x69, 0x6f, 0x64, + 0x20, 0x6f, 0x66, 0x61, 0x72, 0x65, 0x20, 0x61, 0x62, 0x6c, 0x65, 0x20, 0x74, + 0x6f, 0x68, 0x6f, 0x77, 0x65, 0x76, 0x65, 0x72, 0x2c, 0x20, 0x69, 0x74, 0x73, + 0x68, 0x6f, 0x75, 0x6c, 0x64, 0x20, 0x68, 0x61, 0x76, 0x65, 0x6d, 0x75, 0x63, + 0x68, 0x20, 0x6c, 0x61, 0x72, 0x67, 0x65, 0x72, 0x0a, 0x09, 0x3c, 0x2f, 0x73, + 0x63, 0x72, 0x69, 0x70, 0x74, 0x3e, 0x61, 0x64, 0x6f, 0x70, 0x74, 0x65, 0x64, + 0x20, 0x74, 0x68, 0x65, 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x20, + 0x6f, 0x66, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x65, 0x64, 0x20, 0x62, 0x79, + 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x6c, 0x79, 0x77, 0x61, + 0x73, 0x20, 0x62, 0x72, 0x6f, 0x75, 0x67, 0x68, 0x74, 0x63, 0x68, 0x69, 0x6c, + 0x64, 0x72, 0x65, 0x6e, 0x20, 0x6f, 0x66, 0x50, 0x72, 0x6f, 0x67, 0x72, 0x61, + 0x6d, 0x6d, 0x69, 0x6e, 0x67, 0x6c, 0x6f, 0x6e, 0x67, 0x65, 0x72, 0x20, 0x74, + 0x68, 0x61, 0x6e, 0x6d, 0x61, 0x6e, 0x75, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, + 0x73, 0x77, 0x61, 0x72, 0x20, 0x61, 0x67, 0x61, 0x69, 0x6e, 0x73, 0x74, 0x62, + 0x79, 0x20, 0x6d, 0x65, 0x61, 0x6e, 0x73, 0x20, 0x6f, 0x66, 0x61, 0x6e, 0x64, + 0x20, 0x6d, 0x6f, 0x73, 0x74, 0x20, 0x6f, 0x66, 0x73, 0x69, 0x6d, 0x69, 0x6c, + 0x61, 0x72, 0x20, 0x74, 0x6f, 0x20, 0x70, 0x72, 0x6f, 0x70, 0x72, 0x69, 0x65, + 0x74, 0x61, 0x72, 0x79, 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x61, 0x74, 0x69, + 0x6e, 0x67, 0x70, 0x72, 0x65, 0x73, 0x74, 0x69, 0x67, 0x69, 0x6f, 0x75, 0x73, + 0x67, 0x72, 0x61, 0x6d, 0x6d, 0x61, 0x74, 0x69, 0x63, 0x61, 0x6c, 0x65, 0x78, + 0x70, 0x65, 0x72, 0x69, 0x65, 0x6e, 0x63, 0x65, 0x2e, 0x74, 0x6f, 0x20, 0x6d, + 0x61, 0x6b, 0x65, 0x20, 0x74, 0x68, 0x65, 0x49, 0x74, 0x20, 0x77, 0x61, 0x73, + 0x20, 0x61, 0x6c, 0x73, 0x6f, 0x69, 0x73, 0x20, 0x66, 0x6f, 0x75, 0x6e, 0x64, + 0x20, 0x69, 0x6e, 0x63, 0x6f, 0x6d, 0x70, 0x65, 0x74, 0x69, 0x74, 0x6f, 0x72, + 0x73, 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x55, 0x2e, 0x53, 0x2e, 0x72, + 0x65, 0x70, 0x6c, 0x61, 0x63, 0x65, 0x20, 0x74, 0x68, 0x65, 0x62, 0x72, 0x6f, + 0x75, 0x67, 0x68, 0x74, 0x20, 0x74, 0x68, 0x65, 0x63, 0x61, 0x6c, 0x63, 0x75, + 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x66, 0x61, 0x6c, 0x6c, 0x20, 0x6f, 0x66, + 0x20, 0x74, 0x68, 0x65, 0x74, 0x68, 0x65, 0x20, 0x67, 0x65, 0x6e, 0x65, 0x72, + 0x61, 0x6c, 0x70, 0x72, 0x61, 0x63, 0x74, 0x69, 0x63, 0x61, 0x6c, 0x6c, 0x79, + 0x69, 0x6e, 0x20, 0x68, 0x6f, 0x6e, 0x6f, 0x72, 0x20, 0x6f, 0x66, 0x72, 0x65, + 0x6c, 0x65, 0x61, 0x73, 0x65, 0x64, 0x20, 0x69, 0x6e, 0x72, 0x65, 0x73, 0x69, + 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x61, 0x6e, 0x64, 0x20, 0x73, 0x6f, + 0x6d, 0x65, 0x20, 0x6f, 0x66, 0x6b, 0x69, 0x6e, 0x67, 0x20, 0x6f, 0x66, 0x20, + 0x74, 0x68, 0x65, 0x72, 0x65, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x74, + 0x6f, 0x31, 0x73, 0x74, 0x20, 0x45, 0x61, 0x72, 0x6c, 0x20, 0x6f, 0x66, 0x63, + 0x75, 0x6c, 0x74, 0x75, 0x72, 0x65, 0x20, 0x61, 0x6e, 0x64, 0x70, 0x72, 0x69, + 0x6e, 0x63, 0x69, 0x70, 0x61, 0x6c, 0x6c, 0x79, 0x3c, 0x2f, 0x74, 0x69, 0x74, + 0x6c, 0x65, 0x3e, 0x0a, 0x20, 0x20, 0x74, 0x68, 0x65, 0x79, 0x20, 0x63, 0x61, + 0x6e, 0x20, 0x62, 0x65, 0x62, 0x61, 0x63, 0x6b, 0x20, 0x74, 0x6f, 0x20, 0x74, + 0x68, 0x65, 0x73, 0x6f, 0x6d, 0x65, 0x20, 0x6f, 0x66, 0x20, 0x68, 0x69, 0x73, + 0x65, 0x78, 0x70, 0x6f, 0x73, 0x75, 0x72, 0x65, 0x20, 0x74, 0x6f, 0x61, 0x72, + 0x65, 0x20, 0x73, 0x69, 0x6d, 0x69, 0x6c, 0x61, 0x72, 0x66, 0x6f, 0x72, 0x6d, + 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x61, 0x64, 0x64, 0x46, 0x61, 0x76, + 0x6f, 0x72, 0x69, 0x74, 0x65, 0x63, 0x69, 0x74, 0x69, 0x7a, 0x65, 0x6e, 0x73, + 0x68, 0x69, 0x70, 0x70, 0x61, 0x72, 0x74, 0x20, 0x69, 0x6e, 0x20, 0x74, 0x68, + 0x65, 0x70, 0x65, 0x6f, 0x70, 0x6c, 0x65, 0x20, 0x77, 0x69, 0x74, 0x68, 0x69, + 0x6e, 0x20, 0x70, 0x72, 0x61, 0x63, 0x74, 0x69, 0x63, 0x65, 0x74, 0x6f, 0x20, + 0x63, 0x6f, 0x6e, 0x74, 0x69, 0x6e, 0x75, 0x65, 0x26, 0x61, 0x6d, 0x70, 0x3b, + 0x6d, 0x69, 0x6e, 0x75, 0x73, 0x3b, 0x61, 0x70, 0x70, 0x72, 0x6f, 0x76, 0x65, + 0x64, 0x20, 0x62, 0x79, 0x20, 0x74, 0x68, 0x65, 0x20, 0x66, 0x69, 0x72, 0x73, + 0x74, 0x20, 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x65, 0x64, 0x20, 0x74, 0x68, 0x65, + 0x61, 0x6e, 0x64, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x74, 0x68, 0x65, 0x66, 0x75, + 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x69, 0x6e, 0x67, 0x70, 0x6c, 0x61, 0x79, + 0x69, 0x6e, 0x67, 0x20, 0x74, 0x68, 0x65, 0x73, 0x6f, 0x6c, 0x75, 0x74, 0x69, + 0x6f, 0x6e, 0x20, 0x74, 0x6f, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x3d, 0x22, + 0x30, 0x22, 0x20, 0x69, 0x6e, 0x20, 0x68, 0x69, 0x73, 0x20, 0x62, 0x6f, 0x6f, + 0x6b, 0x6d, 0x6f, 0x72, 0x65, 0x20, 0x74, 0x68, 0x61, 0x6e, 0x20, 0x61, 0x66, + 0x6f, 0x6c, 0x6c, 0x6f, 0x77, 0x73, 0x20, 0x74, 0x68, 0x65, 0x63, 0x72, 0x65, + 0x61, 0x74, 0x65, 0x64, 0x20, 0x74, 0x68, 0x65, 0x70, 0x72, 0x65, 0x73, 0x65, + 0x6e, 0x63, 0x65, 0x20, 0x69, 0x6e, 0x26, 0x6e, 0x62, 0x73, 0x70, 0x3b, 0x3c, + 0x2f, 0x74, 0x64, 0x3e, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x69, + 0x73, 0x74, 0x74, 0x68, 0x65, 0x20, 0x69, 0x64, 0x65, 0x61, 0x20, 0x6f, 0x66, + 0x61, 0x20, 0x63, 0x68, 0x61, 0x72, 0x61, 0x63, 0x74, 0x65, 0x72, 0x77, 0x65, + 0x72, 0x65, 0x20, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x64, 0x20, 0x63, 0x6c, 0x61, + 0x73, 0x73, 0x3d, 0x22, 0x62, 0x74, 0x6e, 0x64, 0x61, 0x79, 0x73, 0x20, 0x6f, + 0x66, 0x20, 0x74, 0x68, 0x65, 0x66, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x64, + 0x20, 0x69, 0x6e, 0x73, 0x68, 0x6f, 0x77, 0x69, 0x6e, 0x67, 0x20, 0x74, 0x68, + 0x65, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x65, 0x73, 0x74, 0x20, 0x69, 0x6e, 0x69, + 0x6e, 0x20, 0x70, 0x6c, 0x61, 0x63, 0x65, 0x20, 0x6f, 0x66, 0x74, 0x75, 0x72, + 0x6e, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x74, 0x68, 0x65, 0x20, 0x68, + 0x65, 0x61, 0x64, 0x20, 0x6f, 0x66, 0x4c, 0x6f, 0x72, 0x64, 0x20, 0x6f, 0x66, + 0x20, 0x74, 0x68, 0x65, 0x70, 0x6f, 0x6c, 0x69, 0x74, 0x69, 0x63, 0x61, 0x6c, + 0x6c, 0x79, 0x68, 0x61, 0x73, 0x20, 0x69, 0x74, 0x73, 0x20, 0x6f, 0x77, 0x6e, + 0x45, 0x64, 0x75, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x61, 0x70, + 0x70, 0x72, 0x6f, 0x76, 0x61, 0x6c, 0x20, 0x6f, 0x66, 0x73, 0x6f, 0x6d, 0x65, + 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x65, 0x61, 0x63, 0x68, 0x20, 0x6f, + 0x74, 0x68, 0x65, 0x72, 0x2c, 0x62, 0x65, 0x68, 0x61, 0x76, 0x69, 0x6f, 0x72, + 0x20, 0x6f, 0x66, 0x61, 0x6e, 0x64, 0x20, 0x62, 0x65, 0x63, 0x61, 0x75, 0x73, + 0x65, 0x61, 0x6e, 0x64, 0x20, 0x61, 0x6e, 0x6f, 0x74, 0x68, 0x65, 0x72, 0x61, + 0x70, 0x70, 0x65, 0x61, 0x72, 0x65, 0x64, 0x20, 0x6f, 0x6e, 0x72, 0x65, 0x63, + 0x6f, 0x72, 0x64, 0x65, 0x64, 0x20, 0x69, 0x6e, 0x62, 0x6c, 0x61, 0x63, 0x6b, + 0x26, 0x71, 0x75, 0x6f, 0x74, 0x3b, 0x6d, 0x61, 0x79, 0x20, 0x69, 0x6e, 0x63, + 0x6c, 0x75, 0x64, 0x65, 0x74, 0x68, 0x65, 0x20, 0x77, 0x6f, 0x72, 0x6c, 0x64, + 0x27, 0x73, 0x63, 0x61, 0x6e, 0x20, 0x6c, 0x65, 0x61, 0x64, 0x20, 0x74, 0x6f, + 0x72, 0x65, 0x66, 0x65, 0x72, 0x73, 0x20, 0x74, 0x6f, 0x20, 0x61, 0x62, 0x6f, + 0x72, 0x64, 0x65, 0x72, 0x3d, 0x22, 0x30, 0x22, 0x20, 0x67, 0x6f, 0x76, 0x65, + 0x72, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x20, 0x77, 0x69, 0x6e, 0x6e, 0x69, 0x6e, + 0x67, 0x20, 0x74, 0x68, 0x65, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x65, 0x64, + 0x20, 0x69, 0x6e, 0x20, 0x77, 0x68, 0x69, 0x6c, 0x65, 0x20, 0x74, 0x68, 0x65, + 0x20, 0x57, 0x61, 0x73, 0x68, 0x69, 0x6e, 0x67, 0x74, 0x6f, 0x6e, 0x2c, 0x74, + 0x68, 0x65, 0x20, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x63, 0x69, 0x74, + 0x79, 0x20, 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x3e, 0x3c, 0x2f, 0x64, 0x69, + 0x76, 0x3e, 0x0d, 0x0a, 0x09, 0x09, 0x72, 0x65, 0x66, 0x6c, 0x65, 0x63, 0x74, + 0x20, 0x74, 0x68, 0x65, 0x74, 0x6f, 0x20, 0x63, 0x6f, 0x6d, 0x70, 0x6c, 0x65, + 0x74, 0x65, 0x62, 0x65, 0x63, 0x61, 0x6d, 0x65, 0x20, 0x6d, 0x6f, 0x72, 0x65, + 0x72, 0x61, 0x64, 0x69, 0x6f, 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, 0x72, 0x65, + 0x6a, 0x65, 0x63, 0x74, 0x65, 0x64, 0x20, 0x62, 0x79, 0x77, 0x69, 0x74, 0x68, + 0x6f, 0x75, 0x74, 0x20, 0x61, 0x6e, 0x79, 0x68, 0x69, 0x73, 0x20, 0x66, 0x61, + 0x74, 0x68, 0x65, 0x72, 0x2c, 0x77, 0x68, 0x69, 0x63, 0x68, 0x20, 0x63, 0x6f, + 0x75, 0x6c, 0x64, 0x63, 0x6f, 0x70, 0x79, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, + 0x65, 0x74, 0x6f, 0x20, 0x69, 0x6e, 0x64, 0x69, 0x63, 0x61, 0x74, 0x65, 0x61, + 0x20, 0x70, 0x6f, 0x6c, 0x69, 0x74, 0x69, 0x63, 0x61, 0x6c, 0x61, 0x63, 0x63, + 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x20, 0x6f, 0x66, 0x63, 0x6f, 0x6e, 0x73, 0x74, + 0x69, 0x74, 0x75, 0x74, 0x65, 0x73, 0x77, 0x6f, 0x72, 0x6b, 0x65, 0x64, 0x20, + 0x77, 0x69, 0x74, 0x68, 0x65, 0x72, 0x3c, 0x2f, 0x61, 0x3e, 0x3c, 0x2f, 0x6c, + 0x69, 0x3e, 0x6f, 0x66, 0x20, 0x68, 0x69, 0x73, 0x20, 0x6c, 0x69, 0x66, 0x65, + 0x61, 0x63, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x6e, 0x69, 0x65, 0x64, 0x63, 0x6c, + 0x69, 0x65, 0x6e, 0x74, 0x57, 0x69, 0x64, 0x74, 0x68, 0x70, 0x72, 0x65, 0x76, + 0x65, 0x6e, 0x74, 0x20, 0x74, 0x68, 0x65, 0x4c, 0x65, 0x67, 0x69, 0x73, 0x6c, + 0x61, 0x74, 0x69, 0x76, 0x65, 0x64, 0x69, 0x66, 0x66, 0x65, 0x72, 0x65, 0x6e, + 0x74, 0x6c, 0x79, 0x74, 0x6f, 0x67, 0x65, 0x74, 0x68, 0x65, 0x72, 0x20, 0x69, + 0x6e, 0x68, 0x61, 0x73, 0x20, 0x73, 0x65, 0x76, 0x65, 0x72, 0x61, 0x6c, 0x66, + 0x6f, 0x72, 0x20, 0x61, 0x6e, 0x6f, 0x74, 0x68, 0x65, 0x72, 0x74, 0x65, 0x78, + 0x74, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x66, 0x6f, 0x75, 0x6e, 0x64, + 0x65, 0x64, 0x20, 0x74, 0x68, 0x65, 0x65, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, + 0x74, 0x68, 0x65, 0x20, 0x69, 0x73, 0x20, 0x75, 0x73, 0x65, 0x64, 0x20, 0x66, + 0x6f, 0x72, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x64, 0x20, 0x74, 0x68, 0x65, + 0x75, 0x73, 0x75, 0x61, 0x6c, 0x6c, 0x79, 0x20, 0x74, 0x68, 0x65, 0x70, 0x6c, + 0x61, 0x63, 0x65, 0x20, 0x77, 0x68, 0x65, 0x72, 0x65, 0x77, 0x68, 0x65, 0x72, + 0x65, 0x61, 0x73, 0x20, 0x74, 0x68, 0x65, 0x3e, 0x20, 0x3c, 0x61, 0x20, 0x68, + 0x72, 0x65, 0x66, 0x3d, 0x22, 0x22, 0x3e, 0x3c, 0x61, 0x20, 0x68, 0x72, 0x65, + 0x66, 0x3d, 0x22, 0x74, 0x68, 0x65, 0x6d, 0x73, 0x65, 0x6c, 0x76, 0x65, 0x73, + 0x2c, 0x61, 0x6c, 0x74, 0x68, 0x6f, 0x75, 0x67, 0x68, 0x20, 0x68, 0x65, 0x74, + 0x68, 0x61, 0x74, 0x20, 0x63, 0x61, 0x6e, 0x20, 0x62, 0x65, 0x74, 0x72, 0x61, + 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x72, 0x6f, 0x6c, 0x65, 0x20, + 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x61, 0x73, 0x20, 0x61, 0x20, 0x72, 0x65, + 0x73, 0x75, 0x6c, 0x74, 0x72, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x43, 0x68, 0x69, + 0x6c, 0x64, 0x64, 0x65, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x20, 0x62, 0x79, + 0x77, 0x65, 0x73, 0x74, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x53, 0x6f, + 0x6d, 0x65, 0x20, 0x70, 0x65, 0x6f, 0x70, 0x6c, 0x65, 0x70, 0x72, 0x6f, 0x64, + 0x75, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x2c, 0x73, 0x69, 0x64, 0x65, 0x20, 0x6f, + 0x66, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x65, 0x77, 0x73, 0x6c, 0x65, 0x74, 0x74, + 0x65, 0x72, 0x73, 0x75, 0x73, 0x65, 0x64, 0x20, 0x62, 0x79, 0x20, 0x74, 0x68, + 0x65, 0x64, 0x6f, 0x77, 0x6e, 0x20, 0x74, 0x6f, 0x20, 0x74, 0x68, 0x65, 0x61, + 0x63, 0x63, 0x65, 0x70, 0x74, 0x65, 0x64, 0x20, 0x62, 0x79, 0x6c, 0x69, 0x76, + 0x65, 0x20, 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x61, 0x74, 0x74, 0x65, 0x6d, + 0x70, 0x74, 0x73, 0x20, 0x74, 0x6f, 0x6f, 0x75, 0x74, 0x73, 0x69, 0x64, 0x65, + 0x20, 0x74, 0x68, 0x65, 0x66, 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x69, + 0x65, 0x73, 0x48, 0x6f, 0x77, 0x65, 0x76, 0x65, 0x72, 0x2c, 0x20, 0x69, 0x6e, + 0x70, 0x72, 0x6f, 0x67, 0x72, 0x61, 0x6d, 0x6d, 0x65, 0x72, 0x73, 0x61, 0x74, + 0x20, 0x6c, 0x65, 0x61, 0x73, 0x74, 0x20, 0x69, 0x6e, 0x61, 0x70, 0x70, 0x72, + 0x6f, 0x78, 0x69, 0x6d, 0x61, 0x74, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x6f, 0x75, + 0x67, 0x68, 0x20, 0x69, 0x74, 0x77, 0x61, 0x73, 0x20, 0x70, 0x61, 0x72, 0x74, + 0x20, 0x6f, 0x66, 0x61, 0x6e, 0x64, 0x20, 0x76, 0x61, 0x72, 0x69, 0x6f, 0x75, + 0x73, 0x47, 0x6f, 0x76, 0x65, 0x72, 0x6e, 0x6f, 0x72, 0x20, 0x6f, 0x66, 0x74, + 0x68, 0x65, 0x20, 0x61, 0x72, 0x74, 0x69, 0x63, 0x6c, 0x65, 0x74, 0x75, 0x72, + 0x6e, 0x65, 0x64, 0x20, 0x69, 0x6e, 0x74, 0x6f, 0x3e, 0x3c, 0x61, 0x20, 0x68, + 0x72, 0x65, 0x66, 0x3d, 0x22, 0x2f, 0x74, 0x68, 0x65, 0x20, 0x65, 0x63, 0x6f, + 0x6e, 0x6f, 0x6d, 0x79, 0x69, 0x73, 0x20, 0x74, 0x68, 0x65, 0x20, 0x6d, 0x6f, + 0x73, 0x74, 0x6d, 0x6f, 0x73, 0x74, 0x20, 0x77, 0x69, 0x64, 0x65, 0x6c, 0x79, + 0x77, 0x6f, 0x75, 0x6c, 0x64, 0x20, 0x6c, 0x61, 0x74, 0x65, 0x72, 0x61, 0x6e, + 0x64, 0x20, 0x70, 0x65, 0x72, 0x68, 0x61, 0x70, 0x73, 0x72, 0x69, 0x73, 0x65, + 0x20, 0x74, 0x6f, 0x20, 0x74, 0x68, 0x65, 0x6f, 0x63, 0x63, 0x75, 0x72, 0x73, + 0x20, 0x77, 0x68, 0x65, 0x6e, 0x75, 0x6e, 0x64, 0x65, 0x72, 0x20, 0x77, 0x68, + 0x69, 0x63, 0x68, 0x63, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, + 0x2e, 0x74, 0x68, 0x65, 0x20, 0x77, 0x65, 0x73, 0x74, 0x65, 0x72, 0x6e, 0x74, + 0x68, 0x65, 0x6f, 0x72, 0x79, 0x20, 0x74, 0x68, 0x61, 0x74, 0x69, 0x73, 0x20, + 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x65, 0x64, 0x74, 0x68, 0x65, 0x20, 0x63, + 0x69, 0x74, 0x79, 0x20, 0x6f, 0x66, 0x69, 0x6e, 0x20, 0x77, 0x68, 0x69, 0x63, + 0x68, 0x20, 0x68, 0x65, 0x73, 0x65, 0x65, 0x6e, 0x20, 0x69, 0x6e, 0x20, 0x74, + 0x68, 0x65, 0x74, 0x68, 0x65, 0x20, 0x63, 0x65, 0x6e, 0x74, 0x72, 0x61, 0x6c, + 0x62, 0x75, 0x69, 0x6c, 0x64, 0x69, 0x6e, 0x67, 0x20, 0x6f, 0x66, 0x6d, 0x61, + 0x6e, 0x79, 0x20, 0x6f, 0x66, 0x20, 0x68, 0x69, 0x73, 0x61, 0x72, 0x65, 0x61, + 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x69, 0x73, 0x20, 0x74, 0x68, 0x65, + 0x20, 0x6f, 0x6e, 0x6c, 0x79, 0x6d, 0x6f, 0x73, 0x74, 0x20, 0x6f, 0x66, 0x20, + 0x74, 0x68, 0x65, 0x6d, 0x61, 0x6e, 0x79, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, + 0x65, 0x74, 0x68, 0x65, 0x20, 0x57, 0x65, 0x73, 0x74, 0x65, 0x72, 0x6e, 0x54, + 0x68, 0x65, 0x72, 0x65, 0x20, 0x69, 0x73, 0x20, 0x6e, 0x6f, 0x65, 0x78, 0x74, + 0x65, 0x6e, 0x64, 0x65, 0x64, 0x20, 0x74, 0x6f, 0x53, 0x74, 0x61, 0x74, 0x69, + 0x73, 0x74, 0x69, 0x63, 0x61, 0x6c, 0x63, 0x6f, 0x6c, 0x73, 0x70, 0x61, 0x6e, + 0x3d, 0x32, 0x20, 0x7c, 0x73, 0x68, 0x6f, 0x72, 0x74, 0x20, 0x73, 0x74, 0x6f, + 0x72, 0x79, 0x70, 0x6f, 0x73, 0x73, 0x69, 0x62, 0x6c, 0x65, 0x20, 0x74, 0x6f, + 0x74, 0x6f, 0x70, 0x6f, 0x6c, 0x6f, 0x67, 0x69, 0x63, 0x61, 0x6c, 0x63, 0x72, + 0x69, 0x74, 0x69, 0x63, 0x61, 0x6c, 0x20, 0x6f, 0x66, 0x72, 0x65, 0x70, 0x6f, + 0x72, 0x74, 0x65, 0x64, 0x20, 0x74, 0x6f, 0x61, 0x20, 0x43, 0x68, 0x72, 0x69, + 0x73, 0x74, 0x69, 0x61, 0x6e, 0x64, 0x65, 0x63, 0x69, 0x73, 0x69, 0x6f, 0x6e, + 0x20, 0x74, 0x6f, 0x69, 0x73, 0x20, 0x65, 0x71, 0x75, 0x61, 0x6c, 0x20, 0x74, + 0x6f, 0x70, 0x72, 0x6f, 0x62, 0x6c, 0x65, 0x6d, 0x73, 0x20, 0x6f, 0x66, 0x54, + 0x68, 0x69, 0x73, 0x20, 0x63, 0x61, 0x6e, 0x20, 0x62, 0x65, 0x6d, 0x65, 0x72, + 0x63, 0x68, 0x61, 0x6e, 0x64, 0x69, 0x73, 0x65, 0x66, 0x6f, 0x72, 0x20, 0x6d, + 0x6f, 0x73, 0x74, 0x20, 0x6f, 0x66, 0x6e, 0x6f, 0x20, 0x65, 0x76, 0x69, 0x64, + 0x65, 0x6e, 0x63, 0x65, 0x65, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, + 0x6f, 0x66, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x20, 0x69, 0x6e, + 0x26, 0x71, 0x75, 0x6f, 0x74, 0x3b, 0x2e, 0x20, 0x54, 0x68, 0x65, 0x63, 0x6f, + 0x6d, 0x2f, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x73, 0x2f, 0x77, 0x68, 0x69, 0x63, + 0x68, 0x20, 0x6d, 0x61, 0x6b, 0x65, 0x73, 0x74, 0x68, 0x65, 0x20, 0x70, 0x72, + 0x6f, 0x63, 0x65, 0x73, 0x73, 0x72, 0x65, 0x6d, 0x61, 0x69, 0x6e, 0x73, 0x20, + 0x74, 0x68, 0x65, 0x6c, 0x69, 0x74, 0x65, 0x72, 0x61, 0x74, 0x75, 0x72, 0x65, + 0x2c, 0x69, 0x73, 0x20, 0x61, 0x20, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x74, + 0x68, 0x65, 0x20, 0x70, 0x6f, 0x70, 0x75, 0x6c, 0x61, 0x72, 0x74, 0x68, 0x65, + 0x20, 0x61, 0x6e, 0x63, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x72, 0x6f, 0x62, 0x6c, + 0x65, 0x6d, 0x73, 0x20, 0x69, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x20, 0x6f, 0x66, + 0x20, 0x74, 0x68, 0x65, 0x64, 0x65, 0x66, 0x65, 0x61, 0x74, 0x65, 0x64, 0x20, + 0x62, 0x79, 0x62, 0x6f, 0x64, 0x79, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, + 0x61, 0x20, 0x66, 0x65, 0x77, 0x20, 0x79, 0x65, 0x61, 0x72, 0x73, 0x6d, 0x75, + 0x63, 0x68, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x74, 0x68, 0x65, 0x20, + 0x77, 0x6f, 0x72, 0x6b, 0x20, 0x6f, 0x66, 0x43, 0x61, 0x6c, 0x69, 0x66, 0x6f, + 0x72, 0x6e, 0x69, 0x61, 0x2c, 0x73, 0x65, 0x72, 0x76, 0x65, 0x64, 0x20, 0x61, + 0x73, 0x20, 0x61, 0x67, 0x6f, 0x76, 0x65, 0x72, 0x6e, 0x6d, 0x65, 0x6e, 0x74, + 0x2e, 0x63, 0x6f, 0x6e, 0x63, 0x65, 0x70, 0x74, 0x73, 0x20, 0x6f, 0x66, 0x6d, + 0x6f, 0x76, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x20, 0x69, 0x6e, 0x09, 0x09, 0x3c, + 0x64, 0x69, 0x76, 0x20, 0x69, 0x64, 0x3d, 0x22, 0x69, 0x74, 0x22, 0x20, 0x76, + 0x61, 0x6c, 0x75, 0x65, 0x3d, 0x22, 0x6c, 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, + 0x65, 0x20, 0x6f, 0x66, 0x61, 0x73, 0x20, 0x74, 0x68, 0x65, 0x79, 0x20, 0x61, + 0x72, 0x65, 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x65, 0x64, 0x20, 0x69, 0x6e, + 0x69, 0x73, 0x20, 0x74, 0x68, 0x61, 0x74, 0x20, 0x74, 0x68, 0x65, 0x65, 0x78, + 0x70, 0x6c, 0x61, 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x64, 0x69, 0x76, 0x3e, + 0x3c, 0x2f, 0x64, 0x69, 0x76, 0x3e, 0x0a, 0x48, 0x6f, 0x77, 0x65, 0x76, 0x65, + 0x72, 0x20, 0x74, 0x68, 0x65, 0x6c, 0x65, 0x61, 0x64, 0x20, 0x74, 0x6f, 0x20, + 0x74, 0x68, 0x65, 0x09, 0x3c, 0x61, 0x20, 0x68, 0x72, 0x65, 0x66, 0x3d, 0x22, + 0x2f, 0x77, 0x61, 0x73, 0x20, 0x67, 0x72, 0x61, 0x6e, 0x74, 0x65, 0x64, 0x70, + 0x65, 0x6f, 0x70, 0x6c, 0x65, 0x20, 0x68, 0x61, 0x76, 0x65, 0x63, 0x6f, 0x6e, + 0x74, 0x69, 0x6e, 0x75, 0x61, 0x6c, 0x6c, 0x79, 0x77, 0x61, 0x73, 0x20, 0x73, + 0x65, 0x65, 0x6e, 0x20, 0x61, 0x73, 0x61, 0x6e, 0x64, 0x20, 0x72, 0x65, 0x6c, + 0x61, 0x74, 0x65, 0x64, 0x74, 0x68, 0x65, 0x20, 0x72, 0x6f, 0x6c, 0x65, 0x20, + 0x6f, 0x66, 0x70, 0x72, 0x6f, 0x70, 0x6f, 0x73, 0x65, 0x64, 0x20, 0x62, 0x79, + 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x62, 0x65, 0x73, 0x74, 0x65, 0x61, + 0x63, 0x68, 0x20, 0x6f, 0x74, 0x68, 0x65, 0x72, 0x2e, 0x43, 0x6f, 0x6e, 0x73, + 0x74, 0x61, 0x6e, 0x74, 0x69, 0x6e, 0x65, 0x70, 0x65, 0x6f, 0x70, 0x6c, 0x65, + 0x20, 0x66, 0x72, 0x6f, 0x6d, 0x64, 0x69, 0x61, 0x6c, 0x65, 0x63, 0x74, 0x73, + 0x20, 0x6f, 0x66, 0x74, 0x6f, 0x20, 0x72, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, + 0x6e, 0x77, 0x61, 0x73, 0x20, 0x72, 0x65, 0x6e, 0x61, 0x6d, 0x65, 0x64, 0x61, + 0x20, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x20, 0x6f, 0x66, 0x74, 0x68, 0x65, + 0x20, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x61, 0x6c, 0x6c, 0x61, 0x75, 0x6e, 0x63, + 0x68, 0x65, 0x64, 0x20, 0x69, 0x6e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, + 0x20, 0x74, 0x68, 0x65, 0x74, 0x6f, 0x20, 0x74, 0x68, 0x65, 0x20, 0x77, 0x65, + 0x73, 0x74, 0x77, 0x68, 0x65, 0x72, 0x65, 0x20, 0x74, 0x68, 0x65, 0x72, 0x65, + 0x61, 0x6e, 0x64, 0x20, 0x73, 0x69, 0x6d, 0x69, 0x6c, 0x61, 0x72, 0x62, 0x65, + 0x74, 0x77, 0x65, 0x65, 0x6e, 0x20, 0x74, 0x77, 0x6f, 0x69, 0x73, 0x20, 0x61, + 0x6c, 0x73, 0x6f, 0x20, 0x74, 0x68, 0x65, 0x45, 0x6e, 0x67, 0x6c, 0x69, 0x73, + 0x68, 0x20, 0x61, 0x6e, 0x64, 0x63, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, + 0x6e, 0x73, 0x2c, 0x74, 0x68, 0x61, 0x74, 0x20, 0x69, 0x74, 0x20, 0x77, 0x61, + 0x73, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x64, 0x20, 0x74, 0x6f, 0x74, + 0x68, 0x65, 0x6d, 0x73, 0x65, 0x6c, 0x76, 0x65, 0x73, 0x2e, 0x71, 0x75, 0x61, + 0x6e, 0x74, 0x69, 0x74, 0x79, 0x20, 0x6f, 0x66, 0x72, 0x61, 0x6e, 0x73, 0x70, + 0x61, 0x72, 0x65, 0x6e, 0x63, 0x79, 0x74, 0x68, 0x65, 0x20, 0x73, 0x61, 0x6d, + 0x65, 0x20, 0x61, 0x73, 0x74, 0x6f, 0x20, 0x6a, 0x6f, 0x69, 0x6e, 0x20, 0x74, + 0x68, 0x65, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x72, 0x79, 0x20, 0x61, 0x6e, 0x64, + 0x74, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, 0x20, 0x74, 0x68, 0x65, 0x54, 0x68, + 0x69, 0x73, 0x20, 0x6c, 0x65, 0x64, 0x20, 0x74, 0x6f, 0x61, 0x20, 0x73, 0x74, + 0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x61, + 0x73, 0x74, 0x20, 0x74, 0x6f, 0x6c, 0x61, 0x73, 0x74, 0x49, 0x6e, 0x64, 0x65, + 0x78, 0x4f, 0x66, 0x74, 0x68, 0x72, 0x6f, 0x75, 0x67, 0x68, 0x20, 0x68, 0x69, + 0x73, 0x69, 0x73, 0x20, 0x64, 0x65, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x74, + 0x68, 0x65, 0x20, 0x74, 0x65, 0x72, 0x6d, 0x20, 0x69, 0x73, 0x69, 0x73, 0x20, + 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x64, 0x70, 0x72, 0x6f, 0x74, 0x65, + 0x63, 0x74, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x67, 0x3c, 0x2f, 0x61, 0x3e, 0x3c, + 0x2f, 0x6c, 0x69, 0x3e, 0x54, 0x68, 0x65, 0x20, 0x63, 0x75, 0x72, 0x72, 0x65, + 0x6e, 0x74, 0x74, 0x68, 0x65, 0x20, 0x73, 0x69, 0x74, 0x65, 0x20, 0x6f, 0x66, + 0x73, 0x75, 0x62, 0x73, 0x74, 0x61, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x65, 0x78, + 0x70, 0x65, 0x72, 0x69, 0x65, 0x6e, 0x63, 0x65, 0x2c, 0x69, 0x6e, 0x20, 0x74, + 0x68, 0x65, 0x20, 0x57, 0x65, 0x73, 0x74, 0x74, 0x68, 0x65, 0x79, 0x20, 0x73, + 0x68, 0x6f, 0x75, 0x6c, 0x64, 0x73, 0x6c, 0x6f, 0x76, 0x65, 0x6e, 0xc4, 0x8d, + 0x69, 0x6e, 0x61, 0x63, 0x6f, 0x6d, 0x65, 0x6e, 0x74, 0x61, 0x72, 0x69, 0x6f, + 0x73, 0x75, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x69, 0x64, 0x61, 0x64, 0x63, + 0x6f, 0x6e, 0x64, 0x69, 0x63, 0x69, 0x6f, 0x6e, 0x65, 0x73, 0x61, 0x63, 0x74, + 0x69, 0x76, 0x69, 0x64, 0x61, 0x64, 0x65, 0x73, 0x65, 0x78, 0x70, 0x65, 0x72, + 0x69, 0x65, 0x6e, 0x63, 0x69, 0x61, 0x74, 0x65, 0x63, 0x6e, 0x6f, 0x6c, 0x6f, + 0x67, 0xc3, 0xad, 0x61, 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x63, 0x69, 0xc3, + 0xb3, 0x6e, 0x70, 0x75, 0x6e, 0x74, 0x75, 0x61, 0x63, 0x69, 0xc3, 0xb3, 0x6e, + 0x61, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x63, 0x69, 0xc3, 0xb3, 0x6e, 0x63, 0x6f, + 0x6e, 0x74, 0x72, 0x61, 0x73, 0x65, 0xc3, 0xb1, 0x61, 0x63, 0x61, 0x74, 0x65, + 0x67, 0x6f, 0x72, 0xc3, 0xad, 0x61, 0x73, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, + 0x72, 0x61, 0x72, 0x73, 0x65, 0x70, 0x72, 0x6f, 0x66, 0x65, 0x73, 0x69, 0x6f, + 0x6e, 0x61, 0x6c, 0x74, 0x72, 0x61, 0x74, 0x61, 0x6d, 0x69, 0x65, 0x6e, 0x74, + 0x6f, 0x72, 0x65, 0x67, 0xc3, 0xad, 0x73, 0x74, 0x72, 0x61, 0x74, 0x65, 0x73, + 0x65, 0x63, 0x72, 0x65, 0x74, 0x61, 0x72, 0xc3, 0xad, 0x61, 0x70, 0x72, 0x69, + 0x6e, 0x63, 0x69, 0x70, 0x61, 0x6c, 0x65, 0x73, 0x70, 0x72, 0x6f, 0x74, 0x65, + 0x63, 0x63, 0x69, 0xc3, 0xb3, 0x6e, 0x69, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x61, + 0x6e, 0x74, 0x65, 0x73, 0x69, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x61, 0x6e, 0x63, + 0x69, 0x61, 0x70, 0x6f, 0x73, 0x69, 0x62, 0x69, 0x6c, 0x69, 0x64, 0x61, 0x64, + 0x69, 0x6e, 0x74, 0x65, 0x72, 0x65, 0x73, 0x61, 0x6e, 0x74, 0x65, 0x63, 0x72, + 0x65, 0x63, 0x69, 0x6d, 0x69, 0x65, 0x6e, 0x74, 0x6f, 0x6e, 0x65, 0x63, 0x65, + 0x73, 0x69, 0x64, 0x61, 0x64, 0x65, 0x73, 0x73, 0x75, 0x73, 0x63, 0x72, 0x69, + 0x62, 0x69, 0x72, 0x73, 0x65, 0x61, 0x73, 0x6f, 0x63, 0x69, 0x61, 0x63, 0x69, + 0xc3, 0xb3, 0x6e, 0x64, 0x69, 0x73, 0x70, 0x6f, 0x6e, 0x69, 0x62, 0x6c, 0x65, + 0x73, 0x65, 0x76, 0x61, 0x6c, 0x75, 0x61, 0x63, 0x69, 0xc3, 0xb3, 0x6e, 0x65, + 0x73, 0x74, 0x75, 0x64, 0x69, 0x61, 0x6e, 0x74, 0x65, 0x73, 0x72, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x72, 0x65, 0x73, 0x6f, 0x6c, + 0x75, 0x63, 0x69, 0xc3, 0xb3, 0x6e, 0x67, 0x75, 0x61, 0x64, 0x61, 0x6c, 0x61, + 0x6a, 0x61, 0x72, 0x61, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x61, 0x64, + 0x6f, 0x73, 0x6f, 0x70, 0x6f, 0x72, 0x74, 0x75, 0x6e, 0x69, 0x64, 0x61, 0x64, + 0x63, 0x6f, 0x6d, 0x65, 0x72, 0x63, 0x69, 0x61, 0x6c, 0x65, 0x73, 0x66, 0x6f, + 0x74, 0x6f, 0x67, 0x72, 0x61, 0x66, 0xc3, 0xad, 0x61, 0x61, 0x75, 0x74, 0x6f, + 0x72, 0x69, 0x64, 0x61, 0x64, 0x65, 0x73, 0x69, 0x6e, 0x67, 0x65, 0x6e, 0x69, + 0x65, 0x72, 0xc3, 0xad, 0x61, 0x74, 0x65, 0x6c, 0x65, 0x76, 0x69, 0x73, 0x69, + 0xc3, 0xb3, 0x6e, 0x63, 0x6f, 0x6d, 0x70, 0x65, 0x74, 0x65, 0x6e, 0x63, 0x69, + 0x61, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x63, 0x69, 0x6f, 0x6e, 0x65, 0x73, 0x65, + 0x73, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x63, 0x69, 0x64, 0x6f, 0x73, 0x69, 0x6d, + 0x70, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x65, 0x61, 0x63, 0x74, 0x75, 0x61, + 0x6c, 0x6d, 0x65, 0x6e, 0x74, 0x65, 0x6e, 0x61, 0x76, 0x65, 0x67, 0x61, 0x63, + 0x69, 0xc3, 0xb3, 0x6e, 0x63, 0x6f, 0x6e, 0x66, 0x6f, 0x72, 0x6d, 0x69, 0x64, + 0x61, 0x64, 0x6c, 0x69, 0x6e, 0x65, 0x2d, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, + 0x3a, 0x66, 0x6f, 0x6e, 0x74, 0x2d, 0x66, 0x61, 0x6d, 0x69, 0x6c, 0x79, 0x3a, + 0x22, 0x20, 0x3a, 0x20, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x61, + 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x6c, 0x69, + 0x6e, 0x6b, 0x22, 0x20, 0x68, 0x72, 0x65, 0x66, 0x3d, 0x22, 0x73, 0x70, 0x65, + 0x63, 0x69, 0x66, 0x69, 0x63, 0x61, 0x6c, 0x6c, 0x79, 0x2f, 0x2f, 0x3c, 0x21, + 0x5b, 0x43, 0x44, 0x41, 0x54, 0x41, 0x5b, 0x0a, 0x4f, 0x72, 0x67, 0x61, 0x6e, + 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x64, 0x69, 0x73, 0x74, 0x72, 0x69, + 0x62, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x30, 0x70, 0x78, 0x3b, 0x20, 0x68, 0x65, + 0x69, 0x67, 0x68, 0x74, 0x3a, 0x72, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x73, 0x68, 0x69, 0x70, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x2d, 0x77, 0x69, + 0x64, 0x74, 0x68, 0x3c, 0x64, 0x69, 0x76, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, + 0x3d, 0x22, 0x3c, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x20, 0x66, 0x6f, 0x72, 0x3d, + 0x22, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x3c, 0x2f, 0x6e, 0x6f, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x3e, 0x0a, 0x2f, + 0x69, 0x6e, 0x64, 0x65, 0x78, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0x22, 0x77, 0x69, + 0x6e, 0x64, 0x6f, 0x77, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x28, 0x20, 0x21, 0x69, + 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x61, 0x6e, 0x74, 0x3b, 0x61, 0x70, 0x70, 0x6c, + 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x69, 0x6e, 0x64, 0x65, 0x70, + 0x65, 0x6e, 0x64, 0x65, 0x6e, 0x63, 0x65, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, + 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x6f, 0x72, 0x67, 0x61, 0x6e, 0x69, 0x7a, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x75, 0x74, 0x6f, 0x63, 0x6f, 0x6d, 0x70, + 0x6c, 0x65, 0x74, 0x65, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x6d, 0x65, + 0x6e, 0x74, 0x73, 0x63, 0x6f, 0x6e, 0x73, 0x65, 0x72, 0x76, 0x61, 0x74, 0x69, + 0x76, 0x65, 0x3c, 0x66, 0x6f, 0x72, 0x6d, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x3d, + 0x22, 0x69, 0x6e, 0x74, 0x65, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x75, 0x61, 0x6c, + 0x6d, 0x61, 0x72, 0x67, 0x69, 0x6e, 0x2d, 0x6c, 0x65, 0x66, 0x74, 0x3a, 0x31, + 0x38, 0x74, 0x68, 0x20, 0x63, 0x65, 0x6e, 0x74, 0x75, 0x72, 0x79, 0x61, 0x6e, + 0x20, 0x69, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x61, 0x6e, 0x74, 0x69, 0x6e, 0x73, + 0x74, 0x69, 0x74, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x61, 0x62, 0x62, 0x72, + 0x65, 0x76, 0x69, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3c, 0x69, 0x6d, 0x67, 0x20, + 0x63, 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x22, 0x6f, 0x72, 0x67, 0x61, 0x6e, 0x69, + 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x63, 0x69, 0x76, 0x69, 0x6c, 0x69, 0x7a, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x31, 0x39, 0x74, 0x68, 0x20, 0x63, 0x65, 0x6e, + 0x74, 0x75, 0x72, 0x79, 0x61, 0x72, 0x63, 0x68, 0x69, 0x74, 0x65, 0x63, 0x74, + 0x75, 0x72, 0x65, 0x69, 0x6e, 0x63, 0x6f, 0x72, 0x70, 0x6f, 0x72, 0x61, 0x74, + 0x65, 0x64, 0x32, 0x30, 0x74, 0x68, 0x20, 0x63, 0x65, 0x6e, 0x74, 0x75, 0x72, + 0x79, 0x2d, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x22, 0x3e, + 0x6d, 0x6f, 0x73, 0x74, 0x20, 0x6e, 0x6f, 0x74, 0x61, 0x62, 0x6c, 0x79, 0x2f, + 0x3e, 0x3c, 0x2f, 0x61, 0x3e, 0x3c, 0x2f, 0x64, 0x69, 0x76, 0x3e, 0x6e, 0x6f, + 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x27, 0x75, 0x6e, + 0x64, 0x65, 0x66, 0x69, 0x6e, 0x65, 0x64, 0x27, 0x29, 0x46, 0x75, 0x72, 0x74, + 0x68, 0x65, 0x72, 0x6d, 0x6f, 0x72, 0x65, 0x2c, 0x62, 0x65, 0x6c, 0x69, 0x65, + 0x76, 0x65, 0x20, 0x74, 0x68, 0x61, 0x74, 0x69, 0x6e, 0x6e, 0x65, 0x72, 0x48, + 0x54, 0x4d, 0x4c, 0x20, 0x3d, 0x20, 0x70, 0x72, 0x69, 0x6f, 0x72, 0x20, 0x74, + 0x6f, 0x20, 0x74, 0x68, 0x65, 0x64, 0x72, 0x61, 0x6d, 0x61, 0x74, 0x69, 0x63, + 0x61, 0x6c, 0x6c, 0x79, 0x72, 0x65, 0x66, 0x65, 0x72, 0x72, 0x69, 0x6e, 0x67, + 0x20, 0x74, 0x6f, 0x6e, 0x65, 0x67, 0x6f, 0x74, 0x69, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x73, 0x68, 0x65, 0x61, 0x64, 0x71, 0x75, 0x61, 0x72, 0x74, 0x65, 0x72, + 0x73, 0x53, 0x6f, 0x75, 0x74, 0x68, 0x20, 0x41, 0x66, 0x72, 0x69, 0x63, 0x61, + 0x75, 0x6e, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x66, 0x75, 0x6c, 0x50, + 0x65, 0x6e, 0x6e, 0x73, 0x79, 0x6c, 0x76, 0x61, 0x6e, 0x69, 0x61, 0x41, 0x73, + 0x20, 0x61, 0x20, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x2c, 0x3c, 0x68, 0x74, + 0x6d, 0x6c, 0x20, 0x6c, 0x61, 0x6e, 0x67, 0x3d, 0x22, 0x26, 0x6c, 0x74, 0x3b, + 0x2f, 0x73, 0x75, 0x70, 0x26, 0x67, 0x74, 0x3b, 0x64, 0x65, 0x61, 0x6c, 0x69, + 0x6e, 0x67, 0x20, 0x77, 0x69, 0x74, 0x68, 0x70, 0x68, 0x69, 0x6c, 0x61, 0x64, + 0x65, 0x6c, 0x70, 0x68, 0x69, 0x61, 0x68, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x69, + 0x63, 0x61, 0x6c, 0x6c, 0x79, 0x29, 0x3b, 0x3c, 0x2f, 0x73, 0x63, 0x72, 0x69, + 0x70, 0x74, 0x3e, 0x0a, 0x70, 0x61, 0x64, 0x64, 0x69, 0x6e, 0x67, 0x2d, 0x74, + 0x6f, 0x70, 0x3a, 0x65, 0x78, 0x70, 0x65, 0x72, 0x69, 0x6d, 0x65, 0x6e, 0x74, + 0x61, 0x6c, 0x67, 0x65, 0x74, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, + 0x65, 0x69, 0x6e, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, + 0x74, 0x65, 0x63, 0x68, 0x6e, 0x6f, 0x6c, 0x6f, 0x67, 0x69, 0x65, 0x73, 0x70, + 0x61, 0x72, 0x74, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x3d, 0x66, + 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x29, 0x7b, 0x73, 0x75, 0x62, + 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x6c, 0x2e, 0x64, 0x74, + 0x64, 0x22, 0x3e, 0x0d, 0x0a, 0x3c, 0x68, 0x74, 0x67, 0x65, 0x6f, 0x67, 0x72, + 0x61, 0x70, 0x68, 0x69, 0x63, 0x61, 0x6c, 0x43, 0x6f, 0x6e, 0x73, 0x74, 0x69, + 0x74, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x27, 0x2c, 0x20, 0x66, 0x75, 0x6e, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, + 0x64, 0x20, 0x62, 0x79, 0x61, 0x67, 0x72, 0x69, 0x63, 0x75, 0x6c, 0x74, 0x75, + 0x72, 0x61, 0x6c, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x73, 0x66, 0x6f, 0x6e, 0x74, 0x2d, 0x73, 0x69, 0x7a, 0x65, 0x3a, 0x20, 0x31, + 0x61, 0x20, 0x76, 0x61, 0x72, 0x69, 0x65, 0x74, 0x79, 0x20, 0x6f, 0x66, 0x3c, + 0x64, 0x69, 0x76, 0x20, 0x73, 0x74, 0x79, 0x6c, 0x65, 0x3d, 0x22, 0x45, 0x6e, + 0x63, 0x79, 0x63, 0x6c, 0x6f, 0x70, 0x65, 0x64, 0x69, 0x61, 0x69, 0x66, 0x72, + 0x61, 0x6d, 0x65, 0x20, 0x73, 0x72, 0x63, 0x3d, 0x22, 0x64, 0x65, 0x6d, 0x6f, + 0x6e, 0x73, 0x74, 0x72, 0x61, 0x74, 0x65, 0x64, 0x61, 0x63, 0x63, 0x6f, 0x6d, + 0x70, 0x6c, 0x69, 0x73, 0x68, 0x65, 0x64, 0x75, 0x6e, 0x69, 0x76, 0x65, 0x72, + 0x73, 0x69, 0x74, 0x69, 0x65, 0x73, 0x44, 0x65, 0x6d, 0x6f, 0x67, 0x72, 0x61, + 0x70, 0x68, 0x69, 0x63, 0x73, 0x29, 0x3b, 0x3c, 0x2f, 0x73, 0x63, 0x72, 0x69, + 0x70, 0x74, 0x3e, 0x3c, 0x64, 0x65, 0x64, 0x69, 0x63, 0x61, 0x74, 0x65, 0x64, + 0x20, 0x74, 0x6f, 0x6b, 0x6e, 0x6f, 0x77, 0x6c, 0x65, 0x64, 0x67, 0x65, 0x20, + 0x6f, 0x66, 0x73, 0x61, 0x74, 0x69, 0x73, 0x66, 0x61, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x70, 0x61, 0x72, 0x74, 0x69, 0x63, 0x75, 0x6c, 0x61, 0x72, 0x6c, 0x79, + 0x3c, 0x2f, 0x64, 0x69, 0x76, 0x3e, 0x3c, 0x2f, 0x64, 0x69, 0x76, 0x3e, 0x45, + 0x6e, 0x67, 0x6c, 0x69, 0x73, 0x68, 0x20, 0x28, 0x55, 0x53, 0x29, 0x61, 0x70, + 0x70, 0x65, 0x6e, 0x64, 0x43, 0x68, 0x69, 0x6c, 0x64, 0x28, 0x74, 0x72, 0x61, + 0x6e, 0x73, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x20, 0x48, + 0x6f, 0x77, 0x65, 0x76, 0x65, 0x72, 0x2c, 0x20, 0x69, 0x6e, 0x74, 0x65, 0x6c, + 0x6c, 0x69, 0x67, 0x65, 0x6e, 0x63, 0x65, 0x22, 0x20, 0x74, 0x61, 0x62, 0x69, + 0x6e, 0x64, 0x65, 0x78, 0x3d, 0x22, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x3a, 0x72, + 0x69, 0x67, 0x68, 0x74, 0x3b, 0x43, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x77, 0x65, + 0x61, 0x6c, 0x74, 0x68, 0x72, 0x61, 0x6e, 0x67, 0x69, 0x6e, 0x67, 0x20, 0x66, + 0x72, 0x6f, 0x6d, 0x69, 0x6e, 0x20, 0x77, 0x68, 0x69, 0x63, 0x68, 0x20, 0x74, + 0x68, 0x65, 0x61, 0x74, 0x20, 0x6c, 0x65, 0x61, 0x73, 0x74, 0x20, 0x6f, 0x6e, + 0x65, 0x72, 0x65, 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x65, 0x6e, 0x63, 0x79, 0x63, 0x6c, 0x6f, 0x70, 0x65, 0x64, 0x69, 0x61, 0x3b, + 0x66, 0x6f, 0x6e, 0x74, 0x2d, 0x73, 0x69, 0x7a, 0x65, 0x3a, 0x31, 0x6a, 0x75, + 0x72, 0x69, 0x73, 0x64, 0x69, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x74, 0x20, + 0x74, 0x68, 0x61, 0x74, 0x20, 0x74, 0x69, 0x6d, 0x65, 0x22, 0x3e, 0x3c, 0x61, + 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x22, 0x49, 0x6e, 0x20, 0x61, 0x64, + 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x2c, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, + 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x2b, 0x63, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x63, 0x74, 0x20, + 0x77, 0x69, 0x74, 0x68, 0x69, 0x73, 0x20, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, + 0x6c, 0x6c, 0x79, 0x72, 0x22, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, + 0x3d, 0x22, 0x72, 0x65, 0x70, 0x72, 0x65, 0x73, 0x65, 0x6e, 0x74, 0x69, 0x6e, + 0x67, 0x26, 0x6c, 0x74, 0x3b, 0x6d, 0x61, 0x74, 0x68, 0x26, 0x67, 0x74, 0x3b, + 0x70, 0x72, 0x65, 0x73, 0x65, 0x6e, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x6f, + 0x63, 0x63, 0x61, 0x73, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x6c, 0x79, 0x3c, 0x69, + 0x6d, 0x67, 0x20, 0x77, 0x69, 0x64, 0x74, 0x68, 0x3d, 0x22, 0x6e, 0x61, 0x76, + 0x69, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x3e, 0x63, 0x6f, 0x6d, 0x70, + 0x65, 0x6e, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x63, 0x68, 0x61, 0x6d, 0x70, + 0x69, 0x6f, 0x6e, 0x73, 0x68, 0x69, 0x70, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x3d, + 0x22, 0x61, 0x6c, 0x6c, 0x22, 0x20, 0x76, 0x69, 0x6f, 0x6c, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x20, 0x6f, 0x66, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, + 0x65, 0x20, 0x74, 0x6f, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x74, 0x72, + 0x75, 0x65, 0x3b, 0x53, 0x74, 0x72, 0x69, 0x63, 0x74, 0x2f, 0x2f, 0x45, 0x4e, + 0x22, 0x20, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x73, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x65, 0x6e, 0x74, 0x69, 0x6f, 0x6e, + 0x76, 0x65, 0x72, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, + 0x6e, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x64, 0x69, + 0x66, 0x66, 0x69, 0x63, 0x75, 0x6c, 0x74, 0x69, 0x65, 0x73, 0x43, 0x68, 0x61, + 0x6d, 0x70, 0x69, 0x6f, 0x6e, 0x73, 0x68, 0x69, 0x70, 0x63, 0x61, 0x70, 0x61, + 0x62, 0x69, 0x6c, 0x69, 0x74, 0x69, 0x65, 0x73, 0x3c, 0x21, 0x5b, 0x65, 0x6e, + 0x64, 0x69, 0x66, 0x5d, 0x2d, 0x2d, 0x3e, 0x7d, 0x0a, 0x3c, 0x2f, 0x73, 0x63, + 0x72, 0x69, 0x70, 0x74, 0x3e, 0x0a, 0x43, 0x68, 0x72, 0x69, 0x73, 0x74, 0x69, + 0x61, 0x6e, 0x69, 0x74, 0x79, 0x66, 0x6f, 0x72, 0x20, 0x65, 0x78, 0x61, 0x6d, + 0x70, 0x6c, 0x65, 0x2c, 0x50, 0x72, 0x6f, 0x66, 0x65, 0x73, 0x73, 0x69, 0x6f, + 0x6e, 0x61, 0x6c, 0x72, 0x65, 0x73, 0x74, 0x72, 0x69, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x73, 0x73, 0x75, 0x67, 0x67, 0x65, 0x73, 0x74, 0x20, 0x74, 0x68, 0x61, + 0x74, 0x77, 0x61, 0x73, 0x20, 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x64, + 0x28, 0x73, 0x75, 0x63, 0x68, 0x20, 0x61, 0x73, 0x20, 0x74, 0x68, 0x65, 0x72, + 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x28, 0x75, 0x6e, + 0x65, 0x6d, 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x74, 0x68, 0x65, + 0x20, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x6e, 0x73, 0x74, 0x72, 0x75, + 0x63, 0x74, 0x75, 0x72, 0x65, 0x20, 0x6f, 0x66, 0x2f, 0x69, 0x6e, 0x64, 0x65, + 0x78, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0x20, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x73, + 0x68, 0x65, 0x64, 0x20, 0x69, 0x6e, 0x73, 0x70, 0x61, 0x6e, 0x20, 0x63, 0x6c, + 0x61, 0x73, 0x73, 0x3d, 0x22, 0x22, 0x3e, 0x3c, 0x61, 0x20, 0x68, 0x72, 0x65, + 0x66, 0x3d, 0x22, 0x2f, 0x69, 0x6e, 0x74, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x62, 0x65, 0x6c, 0x6f, 0x6e, 0x67, 0x69, 0x6e, 0x67, 0x20, + 0x74, 0x6f, 0x63, 0x6c, 0x61, 0x69, 0x6d, 0x65, 0x64, 0x20, 0x74, 0x68, 0x61, + 0x74, 0x63, 0x6f, 0x6e, 0x73, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x65, 0x73, + 0x3c, 0x6d, 0x65, 0x74, 0x61, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x3d, 0x22, 0x47, + 0x75, 0x69, 0x64, 0x65, 0x20, 0x74, 0x6f, 0x20, 0x74, 0x68, 0x65, 0x6f, 0x76, + 0x65, 0x72, 0x77, 0x68, 0x65, 0x6c, 0x6d, 0x69, 0x6e, 0x67, 0x61, 0x67, 0x61, + 0x69, 0x6e, 0x73, 0x74, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x6f, 0x6e, 0x63, + 0x65, 0x6e, 0x74, 0x72, 0x61, 0x74, 0x65, 0x64, 0x2c, 0x0a, 0x2e, 0x6e, 0x6f, + 0x6e, 0x74, 0x6f, 0x75, 0x63, 0x68, 0x20, 0x6f, 0x62, 0x73, 0x65, 0x72, 0x76, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x3c, 0x2f, 0x61, 0x3e, 0x0a, 0x3c, 0x2f, + 0x64, 0x69, 0x76, 0x3e, 0x0a, 0x66, 0x20, 0x28, 0x64, 0x6f, 0x63, 0x75, 0x6d, + 0x65, 0x6e, 0x74, 0x2e, 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x3a, 0x20, 0x31, + 0x70, 0x78, 0x20, 0x7b, 0x66, 0x6f, 0x6e, 0x74, 0x2d, 0x73, 0x69, 0x7a, 0x65, + 0x3a, 0x31, 0x74, 0x72, 0x65, 0x61, 0x74, 0x6d, 0x65, 0x6e, 0x74, 0x20, 0x6f, + 0x66, 0x30, 0x22, 0x20, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x3d, 0x22, 0x31, + 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, + 0x6e, 0x64, 0x65, 0x70, 0x65, 0x6e, 0x64, 0x65, 0x6e, 0x63, 0x65, 0x64, 0x69, + 0x76, 0x69, 0x64, 0x65, 0x64, 0x20, 0x69, 0x6e, 0x74, 0x6f, 0x67, 0x72, 0x65, + 0x61, 0x74, 0x65, 0x72, 0x20, 0x74, 0x68, 0x61, 0x6e, 0x61, 0x63, 0x68, 0x69, + 0x65, 0x76, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x65, 0x73, 0x74, 0x61, 0x62, + 0x6c, 0x69, 0x73, 0x68, 0x69, 0x6e, 0x67, 0x4a, 0x61, 0x76, 0x61, 0x53, 0x63, + 0x72, 0x69, 0x70, 0x74, 0x22, 0x20, 0x6e, 0x65, 0x76, 0x65, 0x72, 0x74, 0x68, + 0x65, 0x6c, 0x65, 0x73, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x69, 0x66, 0x69, 0x63, + 0x61, 0x6e, 0x63, 0x65, 0x42, 0x72, 0x6f, 0x61, 0x64, 0x63, 0x61, 0x73, 0x74, + 0x69, 0x6e, 0x67, 0x3e, 0x26, 0x6e, 0x62, 0x73, 0x70, 0x3b, 0x3c, 0x2f, 0x74, + 0x64, 0x3e, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x22, 0x3e, + 0x0a, 0x73, 0x75, 0x63, 0x68, 0x20, 0x61, 0x73, 0x20, 0x74, 0x68, 0x65, 0x20, + 0x69, 0x6e, 0x66, 0x6c, 0x75, 0x65, 0x6e, 0x63, 0x65, 0x20, 0x6f, 0x66, 0x61, + 0x20, 0x70, 0x61, 0x72, 0x74, 0x69, 0x63, 0x75, 0x6c, 0x61, 0x72, 0x73, 0x72, + 0x63, 0x3d, 0x27, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6e, 0x61, 0x76, + 0x69, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x20, 0x68, 0x61, 0x6c, 0x66, + 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x73, 0x75, 0x62, 0x73, 0x74, + 0x61, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x20, 0x26, 0x6e, 0x62, 0x73, 0x70, 0x3b, + 0x3c, 0x2f, 0x64, 0x69, 0x76, 0x3e, 0x61, 0x64, 0x76, 0x61, 0x6e, 0x74, 0x61, + 0x67, 0x65, 0x20, 0x6f, 0x66, 0x64, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, + 0x79, 0x20, 0x6f, 0x66, 0x66, 0x75, 0x6e, 0x64, 0x61, 0x6d, 0x65, 0x6e, 0x74, + 0x61, 0x6c, 0x20, 0x6d, 0x65, 0x74, 0x72, 0x6f, 0x70, 0x6f, 0x6c, 0x69, 0x74, + 0x61, 0x6e, 0x74, 0x68, 0x65, 0x20, 0x6f, 0x70, 0x70, 0x6f, 0x73, 0x69, 0x74, + 0x65, 0x22, 0x20, 0x78, 0x6d, 0x6c, 0x3a, 0x6c, 0x61, 0x6e, 0x67, 0x3d, 0x22, + 0x64, 0x65, 0x6c, 0x69, 0x62, 0x65, 0x72, 0x61, 0x74, 0x65, 0x6c, 0x79, 0x61, + 0x6c, 0x69, 0x67, 0x6e, 0x3d, 0x63, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x65, 0x76, + 0x6f, 0x6c, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6f, 0x66, 0x70, 0x72, 0x65, + 0x73, 0x65, 0x72, 0x76, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x69, 0x6d, 0x70, 0x72, + 0x6f, 0x76, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x62, 0x65, 0x67, 0x69, 0x6e, + 0x6e, 0x69, 0x6e, 0x67, 0x20, 0x69, 0x6e, 0x4a, 0x65, 0x73, 0x75, 0x73, 0x20, + 0x43, 0x68, 0x72, 0x69, 0x73, 0x74, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x64, 0x69, 0x73, 0x61, 0x67, 0x72, 0x65, 0x65, + 0x6d, 0x65, 0x6e, 0x74, 0x74, 0x65, 0x78, 0x74, 0x2d, 0x61, 0x6c, 0x69, 0x67, + 0x6e, 0x3a, 0x72, 0x2c, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x28, 0x29, 0x73, 0x69, 0x6d, 0x69, 0x6c, 0x61, 0x72, 0x69, 0x74, 0x69, 0x65, + 0x73, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0x3c, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x3e, + 0x69, 0x73, 0x20, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x6c, 0x79, 0x61, + 0x6c, 0x70, 0x68, 0x61, 0x62, 0x65, 0x74, 0x69, 0x63, 0x61, 0x6c, 0x69, 0x73, + 0x20, 0x73, 0x6f, 0x6d, 0x65, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x79, 0x70, + 0x65, 0x3d, 0x22, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x2f, 0x6d, 0x61, 0x6e, 0x79, + 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x66, 0x6c, 0x6f, 0x77, 0x3a, + 0x68, 0x69, 0x64, 0x64, 0x65, 0x6e, 0x3b, 0x61, 0x76, 0x61, 0x69, 0x6c, 0x61, + 0x62, 0x6c, 0x65, 0x20, 0x69, 0x6e, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x62, + 0x65, 0x20, 0x74, 0x68, 0x65, 0x65, 0x78, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x63, + 0x65, 0x20, 0x6f, 0x66, 0x61, 0x6c, 0x6c, 0x20, 0x6f, 0x76, 0x65, 0x72, 0x20, + 0x74, 0x68, 0x65, 0x74, 0x68, 0x65, 0x20, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, + 0x65, 0x74, 0x09, 0x3c, 0x75, 0x6c, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x3d, + 0x22, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x6e, 0x65, 0x69, 0x67, 0x68, 0x62, 0x6f, 0x72, 0x68, 0x6f, 0x6f, 0x64, 0x61, + 0x72, 0x6d, 0x65, 0x64, 0x20, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x73, 0x72, 0x65, + 0x64, 0x75, 0x63, 0x69, 0x6e, 0x67, 0x20, 0x74, 0x68, 0x65, 0x63, 0x6f, 0x6e, + 0x74, 0x69, 0x6e, 0x75, 0x65, 0x73, 0x20, 0x74, 0x6f, 0x4e, 0x6f, 0x6e, 0x65, + 0x74, 0x68, 0x65, 0x6c, 0x65, 0x73, 0x73, 0x2c, 0x74, 0x65, 0x6d, 0x70, 0x65, + 0x72, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x0a, 0x09, 0x09, 0x3c, 0x61, 0x20, + 0x68, 0x72, 0x65, 0x66, 0x3d, 0x22, 0x63, 0x6c, 0x6f, 0x73, 0x65, 0x20, 0x74, + 0x6f, 0x20, 0x74, 0x68, 0x65, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x73, + 0x20, 0x6f, 0x66, 0x20, 0x69, 0x73, 0x20, 0x61, 0x62, 0x6f, 0x75, 0x74, 0x20, + 0x74, 0x68, 0x65, 0x28, 0x73, 0x65, 0x65, 0x20, 0x62, 0x65, 0x6c, 0x6f, 0x77, + 0x29, 0x2e, 0x22, 0x20, 0x69, 0x64, 0x3d, 0x22, 0x73, 0x65, 0x61, 0x72, 0x63, + 0x68, 0x70, 0x72, 0x6f, 0x66, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x61, 0x6c, + 0x69, 0x73, 0x20, 0x61, 0x76, 0x61, 0x69, 0x6c, 0x61, 0x62, 0x6c, 0x65, 0x74, + 0x68, 0x65, 0x20, 0x6f, 0x66, 0x66, 0x69, 0x63, 0x69, 0x61, 0x6c, 0x09, 0x09, + 0x3c, 0x2f, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x3e, 0x0a, 0x0a, 0x09, 0x09, + 0x3c, 0x64, 0x69, 0x76, 0x20, 0x69, 0x64, 0x3d, 0x22, 0x61, 0x63, 0x63, 0x65, + 0x6c, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x74, 0x68, 0x72, 0x6f, 0x75, + 0x67, 0x68, 0x20, 0x74, 0x68, 0x65, 0x20, 0x48, 0x61, 0x6c, 0x6c, 0x20, 0x6f, + 0x66, 0x20, 0x46, 0x61, 0x6d, 0x65, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, + 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x6c, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x73, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x65, 0x72, 0x65, + 0x6e, 0x63, 0x65, 0x20, 0x74, 0x79, 0x70, 0x65, 0x3d, 0x27, 0x74, 0x65, 0x78, + 0x74, 0x2f, 0x72, 0x65, 0x63, 0x65, 0x6e, 0x74, 0x20, 0x79, 0x65, 0x61, 0x72, + 0x73, 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x77, 0x6f, 0x72, 0x6c, 0x64, + 0x76, 0x65, 0x72, 0x79, 0x20, 0x70, 0x6f, 0x70, 0x75, 0x6c, 0x61, 0x72, 0x7b, + 0x62, 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x3a, 0x74, 0x72, + 0x61, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x20, 0x73, 0x6f, 0x6d, + 0x65, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x6f, 0x6e, 0x6e, + 0x65, 0x63, 0x74, 0x65, 0x64, 0x20, 0x74, 0x6f, 0x65, 0x78, 0x70, 0x6c, 0x6f, + 0x69, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x65, 0x6d, 0x65, 0x72, 0x67, 0x65, + 0x6e, 0x63, 0x65, 0x20, 0x6f, 0x66, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x69, 0x74, + 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x41, 0x20, 0x48, 0x69, 0x73, 0x74, 0x6f, 0x72, + 0x79, 0x20, 0x6f, 0x66, 0x73, 0x69, 0x67, 0x6e, 0x69, 0x66, 0x69, 0x63, 0x61, + 0x6e, 0x74, 0x20, 0x6d, 0x61, 0x6e, 0x75, 0x66, 0x61, 0x63, 0x74, 0x75, 0x72, + 0x65, 0x64, 0x65, 0x78, 0x70, 0x65, 0x63, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x73, 0x3e, 0x3c, 0x6e, 0x6f, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x3e, 0x3c, + 0x63, 0x61, 0x6e, 0x20, 0x62, 0x65, 0x20, 0x66, 0x6f, 0x75, 0x6e, 0x64, 0x62, + 0x65, 0x63, 0x61, 0x75, 0x73, 0x65, 0x20, 0x74, 0x68, 0x65, 0x20, 0x68, 0x61, + 0x73, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x62, 0x65, 0x65, 0x6e, 0x6e, 0x65, 0x69, + 0x67, 0x68, 0x62, 0x6f, 0x75, 0x72, 0x69, 0x6e, 0x67, 0x77, 0x69, 0x74, 0x68, + 0x6f, 0x75, 0x74, 0x20, 0x74, 0x68, 0x65, 0x20, 0x61, 0x64, 0x64, 0x65, 0x64, + 0x20, 0x74, 0x6f, 0x20, 0x74, 0x68, 0x65, 0x09, 0x3c, 0x6c, 0x69, 0x20, 0x63, + 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x22, 0x69, 0x6e, 0x73, 0x74, 0x72, 0x75, 0x6d, + 0x65, 0x6e, 0x74, 0x61, 0x6c, 0x53, 0x6f, 0x76, 0x69, 0x65, 0x74, 0x20, 0x55, + 0x6e, 0x69, 0x6f, 0x6e, 0x61, 0x63, 0x6b, 0x6e, 0x6f, 0x77, 0x6c, 0x65, 0x64, + 0x67, 0x65, 0x64, 0x77, 0x68, 0x69, 0x63, 0x68, 0x20, 0x63, 0x61, 0x6e, 0x20, + 0x62, 0x65, 0x6e, 0x61, 0x6d, 0x65, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x74, 0x68, + 0x65, 0x61, 0x74, 0x74, 0x65, 0x6e, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x74, 0x6f, + 0x61, 0x74, 0x74, 0x65, 0x6d, 0x70, 0x74, 0x73, 0x20, 0x74, 0x6f, 0x20, 0x64, + 0x65, 0x76, 0x65, 0x6c, 0x6f, 0x70, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x49, 0x6e, + 0x20, 0x66, 0x61, 0x63, 0x74, 0x2c, 0x20, 0x74, 0x68, 0x65, 0x3c, 0x6c, 0x69, + 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x22, 0x61, 0x69, 0x6d, 0x70, 0x6c, + 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x73, 0x75, 0x69, 0x74, 0x61, + 0x62, 0x6c, 0x65, 0x20, 0x66, 0x6f, 0x72, 0x6d, 0x75, 0x63, 0x68, 0x20, 0x6f, + 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x6f, 0x6c, 0x6f, 0x6e, 0x69, 0x7a, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x70, 0x72, 0x65, 0x73, 0x69, 0x64, 0x65, 0x6e, + 0x74, 0x69, 0x61, 0x6c, 0x63, 0x61, 0x6e, 0x63, 0x65, 0x6c, 0x42, 0x75, 0x62, + 0x62, 0x6c, 0x65, 0x20, 0x49, 0x6e, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x6d, 0x6f, 0x73, 0x74, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, + 0x20, 0x69, 0x73, 0x20, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x64, + 0x72, 0x65, 0x73, 0x74, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x6d, + 0x6f, 0x72, 0x65, 0x20, 0x6f, 0x72, 0x20, 0x6c, 0x65, 0x73, 0x73, 0x69, 0x6e, + 0x20, 0x53, 0x65, 0x70, 0x74, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x49, 0x6e, 0x74, + 0x65, 0x6c, 0x6c, 0x69, 0x67, 0x65, 0x6e, 0x63, 0x65, 0x73, 0x72, 0x63, 0x3d, + 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x70, 0x78, 0x3b, 0x20, 0x68, + 0x65, 0x69, 0x67, 0x68, 0x74, 0x3a, 0x20, 0x61, 0x76, 0x61, 0x69, 0x6c, 0x61, + 0x62, 0x6c, 0x65, 0x20, 0x74, 0x6f, 0x6d, 0x61, 0x6e, 0x75, 0x66, 0x61, 0x63, + 0x74, 0x75, 0x72, 0x65, 0x72, 0x68, 0x75, 0x6d, 0x61, 0x6e, 0x20, 0x72, 0x69, + 0x67, 0x68, 0x74, 0x73, 0x6c, 0x69, 0x6e, 0x6b, 0x20, 0x68, 0x72, 0x65, 0x66, + 0x3d, 0x22, 0x2f, 0x61, 0x76, 0x61, 0x69, 0x6c, 0x61, 0x62, 0x69, 0x6c, 0x69, + 0x74, 0x79, 0x70, 0x72, 0x6f, 0x70, 0x6f, 0x72, 0x74, 0x69, 0x6f, 0x6e, 0x61, + 0x6c, 0x6f, 0x75, 0x74, 0x73, 0x69, 0x64, 0x65, 0x20, 0x74, 0x68, 0x65, 0x20, + 0x61, 0x73, 0x74, 0x72, 0x6f, 0x6e, 0x6f, 0x6d, 0x69, 0x63, 0x61, 0x6c, 0x68, + 0x75, 0x6d, 0x61, 0x6e, 0x20, 0x62, 0x65, 0x69, 0x6e, 0x67, 0x73, 0x6e, 0x61, + 0x6d, 0x65, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x61, 0x72, 0x65, + 0x20, 0x66, 0x6f, 0x75, 0x6e, 0x64, 0x20, 0x69, 0x6e, 0x61, 0x72, 0x65, 0x20, + 0x62, 0x61, 0x73, 0x65, 0x64, 0x20, 0x6f, 0x6e, 0x73, 0x6d, 0x61, 0x6c, 0x6c, + 0x65, 0x72, 0x20, 0x74, 0x68, 0x61, 0x6e, 0x61, 0x20, 0x70, 0x65, 0x72, 0x73, + 0x6f, 0x6e, 0x20, 0x77, 0x68, 0x6f, 0x65, 0x78, 0x70, 0x61, 0x6e, 0x73, 0x69, + 0x6f, 0x6e, 0x20, 0x6f, 0x66, 0x61, 0x72, 0x67, 0x75, 0x69, 0x6e, 0x67, 0x20, + 0x74, 0x68, 0x61, 0x74, 0x6e, 0x6f, 0x77, 0x20, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, + 0x20, 0x61, 0x73, 0x49, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x65, 0x61, 0x72, + 0x6c, 0x79, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x74, + 0x65, 0x64, 0x65, 0x72, 0x69, 0x76, 0x65, 0x64, 0x20, 0x66, 0x72, 0x6f, 0x6d, + 0x53, 0x63, 0x61, 0x6e, 0x64, 0x69, 0x6e, 0x61, 0x76, 0x69, 0x61, 0x6e, 0x3c, + 0x2f, 0x61, 0x3e, 0x3c, 0x2f, 0x64, 0x69, 0x76, 0x3e, 0x0d, 0x0a, 0x63, 0x6f, + 0x6e, 0x73, 0x69, 0x64, 0x65, 0x72, 0x20, 0x74, 0x68, 0x65, 0x61, 0x6e, 0x20, + 0x65, 0x73, 0x74, 0x69, 0x6d, 0x61, 0x74, 0x65, 0x64, 0x74, 0x68, 0x65, 0x20, + 0x4e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x3c, 0x64, 0x69, 0x76, 0x20, + 0x69, 0x64, 0x3d, 0x22, 0x70, 0x61, 0x67, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, + 0x69, 0x6e, 0x67, 0x20, 0x69, 0x6e, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x73, 0x73, + 0x69, 0x6f, 0x6e, 0x65, 0x64, 0x61, 0x6e, 0x61, 0x6c, 0x6f, 0x67, 0x6f, 0x75, + 0x73, 0x20, 0x74, 0x6f, 0x61, 0x72, 0x65, 0x20, 0x72, 0x65, 0x71, 0x75, 0x69, + 0x72, 0x65, 0x64, 0x2f, 0x75, 0x6c, 0x3e, 0x0a, 0x3c, 0x2f, 0x64, 0x69, 0x76, + 0x3e, 0x0a, 0x77, 0x61, 0x73, 0x20, 0x62, 0x61, 0x73, 0x65, 0x64, 0x20, 0x6f, + 0x6e, 0x61, 0x6e, 0x64, 0x20, 0x62, 0x65, 0x63, 0x61, 0x6d, 0x65, 0x20, 0x61, + 0x26, 0x6e, 0x62, 0x73, 0x70, 0x3b, 0x26, 0x6e, 0x62, 0x73, 0x70, 0x3b, 0x74, + 0x22, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3d, 0x22, 0x22, 0x20, 0x77, 0x61, + 0x73, 0x20, 0x63, 0x61, 0x70, 0x74, 0x75, 0x72, 0x65, 0x64, 0x6e, 0x6f, 0x20, + 0x6d, 0x6f, 0x72, 0x65, 0x20, 0x74, 0x68, 0x61, 0x6e, 0x72, 0x65, 0x73, 0x70, + 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x6c, 0x79, 0x63, 0x6f, 0x6e, 0x74, 0x69, + 0x6e, 0x75, 0x65, 0x20, 0x74, 0x6f, 0x20, 0x3e, 0x0d, 0x0a, 0x3c, 0x68, 0x65, + 0x61, 0x64, 0x3e, 0x0d, 0x0a, 0x3c, 0x77, 0x65, 0x72, 0x65, 0x20, 0x63, 0x72, + 0x65, 0x61, 0x74, 0x65, 0x64, 0x6d, 0x6f, 0x72, 0x65, 0x20, 0x67, 0x65, 0x6e, + 0x65, 0x72, 0x61, 0x6c, 0x69, 0x6e, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x20, 0x75, 0x73, 0x65, 0x64, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x74, + 0x68, 0x65, 0x69, 0x6e, 0x64, 0x65, 0x70, 0x65, 0x6e, 0x64, 0x65, 0x6e, 0x74, + 0x20, 0x74, 0x68, 0x65, 0x20, 0x49, 0x6d, 0x70, 0x65, 0x72, 0x69, 0x61, 0x6c, + 0x63, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x20, 0x6f, 0x66, 0x74, + 0x6f, 0x20, 0x74, 0x68, 0x65, 0x20, 0x6e, 0x6f, 0x72, 0x74, 0x68, 0x69, 0x6e, + 0x63, 0x6c, 0x75, 0x64, 0x65, 0x20, 0x74, 0x68, 0x65, 0x20, 0x43, 0x6f, 0x6e, + 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x69, 0x64, 0x65, + 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x77, 0x6f, 0x75, 0x6c, 0x64, + 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x62, 0x65, 0x66, 0x6f, 0x72, 0x20, 0x69, 0x6e, + 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x69, 0x6e, 0x76, 0x65, 0x6e, 0x74, 0x69, + 0x6f, 0x6e, 0x20, 0x6f, 0x66, 0x6d, 0x6f, 0x72, 0x65, 0x20, 0x63, 0x6f, 0x6d, + 0x70, 0x6c, 0x65, 0x78, 0x63, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x76, + 0x65, 0x6c, 0x79, 0x62, 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, + 0x3a, 0x20, 0x74, 0x65, 0x78, 0x74, 0x2d, 0x61, 0x6c, 0x69, 0x67, 0x6e, 0x3a, + 0x20, 0x69, 0x74, 0x73, 0x20, 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x61, 0x6c, + 0x69, 0x6e, 0x74, 0x6f, 0x20, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x74, + 0x68, 0x69, 0x73, 0x20, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x61, 0x6e, + 0x20, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x76, 0x65, 0x68, 0x6f, 0x77, + 0x65, 0x76, 0x65, 0x72, 0x2c, 0x20, 0x74, 0x68, 0x65, 0x74, 0x68, 0x65, 0x79, + 0x20, 0x61, 0x72, 0x65, 0x20, 0x6e, 0x6f, 0x74, 0x72, 0x65, 0x6a, 0x65, 0x63, + 0x74, 0x65, 0x64, 0x20, 0x74, 0x68, 0x65, 0x63, 0x72, 0x69, 0x74, 0x69, 0x63, + 0x69, 0x73, 0x6d, 0x20, 0x6f, 0x66, 0x64, 0x75, 0x72, 0x69, 0x6e, 0x67, 0x20, + 0x77, 0x68, 0x69, 0x63, 0x68, 0x70, 0x72, 0x6f, 0x62, 0x61, 0x62, 0x6c, 0x79, + 0x20, 0x74, 0x68, 0x65, 0x74, 0x68, 0x69, 0x73, 0x20, 0x61, 0x72, 0x74, 0x69, + 0x63, 0x6c, 0x65, 0x28, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, + 0x29, 0x7b, 0x49, 0x74, 0x20, 0x73, 0x68, 0x6f, 0x75, 0x6c, 0x64, 0x20, 0x62, + 0x65, 0x61, 0x6e, 0x20, 0x61, 0x67, 0x72, 0x65, 0x65, 0x6d, 0x65, 0x6e, 0x74, + 0x61, 0x63, 0x63, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x61, 0x6c, 0x6c, 0x79, 0x64, + 0x69, 0x66, 0x66, 0x65, 0x72, 0x73, 0x20, 0x66, 0x72, 0x6f, 0x6d, 0x41, 0x72, + 0x63, 0x68, 0x69, 0x74, 0x65, 0x63, 0x74, 0x75, 0x72, 0x65, 0x62, 0x65, 0x74, + 0x74, 0x65, 0x72, 0x20, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x61, 0x72, 0x72, 0x61, + 0x6e, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x69, 0x6e, 0x66, 0x6c, 0x75, + 0x65, 0x6e, 0x63, 0x65, 0x20, 0x6f, 0x6e, 0x61, 0x74, 0x74, 0x65, 0x6e, 0x64, + 0x65, 0x64, 0x20, 0x74, 0x68, 0x65, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x63, + 0x61, 0x6c, 0x20, 0x74, 0x6f, 0x73, 0x6f, 0x75, 0x74, 0x68, 0x20, 0x6f, 0x66, + 0x20, 0x74, 0x68, 0x65, 0x70, 0x61, 0x73, 0x73, 0x20, 0x74, 0x68, 0x72, 0x6f, + 0x75, 0x67, 0x68, 0x78, 0x6d, 0x6c, 0x22, 0x20, 0x74, 0x69, 0x74, 0x6c, 0x65, + 0x3d, 0x22, 0x77, 0x65, 0x69, 0x67, 0x68, 0x74, 0x3a, 0x62, 0x6f, 0x6c, 0x64, + 0x3b, 0x63, 0x72, 0x65, 0x61, 0x74, 0x69, 0x6e, 0x67, 0x20, 0x74, 0x68, 0x65, + 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x3a, 0x6e, 0x6f, 0x6e, 0x65, 0x72, + 0x65, 0x70, 0x6c, 0x61, 0x63, 0x65, 0x64, 0x20, 0x74, 0x68, 0x65, 0x3c, 0x69, + 0x6d, 0x67, 0x20, 0x73, 0x72, 0x63, 0x3d, 0x22, 0x2f, 0x69, 0x68, 0x74, 0x74, + 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x57, 0x6f, 0x72, 0x6c, + 0x64, 0x20, 0x57, 0x61, 0x72, 0x20, 0x49, 0x49, 0x74, 0x65, 0x73, 0x74, 0x69, + 0x6d, 0x6f, 0x6e, 0x69, 0x61, 0x6c, 0x73, 0x66, 0x6f, 0x75, 0x6e, 0x64, 0x20, + 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, + 0x64, 0x20, 0x74, 0x6f, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x74, 0x68, 0x61, 0x74, + 0x20, 0x74, 0x68, 0x65, 0x62, 0x65, 0x74, 0x77, 0x65, 0x65, 0x6e, 0x20, 0x74, + 0x68, 0x65, 0x20, 0x77, 0x61, 0x73, 0x20, 0x64, 0x65, 0x73, 0x69, 0x67, 0x6e, + 0x65, 0x64, 0x63, 0x6f, 0x6e, 0x73, 0x69, 0x73, 0x74, 0x73, 0x20, 0x6f, 0x66, + 0x20, 0x63, 0x6f, 0x6e, 0x73, 0x69, 0x64, 0x65, 0x72, 0x61, 0x62, 0x6c, 0x79, + 0x70, 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x65, 0x64, 0x20, 0x62, 0x79, 0x74, + 0x68, 0x65, 0x20, 0x6c, 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, 0x43, 0x6f, + 0x6e, 0x73, 0x65, 0x72, 0x76, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x63, 0x6f, 0x6e, + 0x73, 0x69, 0x73, 0x74, 0x65, 0x64, 0x20, 0x6f, 0x66, 0x72, 0x65, 0x66, 0x65, + 0x72, 0x20, 0x74, 0x6f, 0x20, 0x74, 0x68, 0x65, 0x62, 0x61, 0x63, 0x6b, 0x20, + 0x74, 0x6f, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x73, 0x73, 0x22, 0x20, 0x6d, + 0x65, 0x64, 0x69, 0x61, 0x3d, 0x22, 0x50, 0x65, 0x6f, 0x70, 0x6c, 0x65, 0x20, + 0x66, 0x72, 0x6f, 0x6d, 0x20, 0x61, 0x76, 0x61, 0x69, 0x6c, 0x61, 0x62, 0x6c, + 0x65, 0x20, 0x6f, 0x6e, 0x70, 0x72, 0x6f, 0x76, 0x65, 0x64, 0x20, 0x74, 0x6f, + 0x20, 0x62, 0x65, 0x73, 0x75, 0x67, 0x67, 0x65, 0x73, 0x74, 0x69, 0x6f, 0x6e, + 0x73, 0x22, 0x77, 0x61, 0x73, 0x20, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x20, 0x61, + 0x73, 0x76, 0x61, 0x72, 0x69, 0x65, 0x74, 0x69, 0x65, 0x73, 0x20, 0x6f, 0x66, + 0x6c, 0x69, 0x6b, 0x65, 0x6c, 0x79, 0x20, 0x74, 0x6f, 0x20, 0x62, 0x65, 0x63, + 0x6f, 0x6d, 0x70, 0x72, 0x69, 0x73, 0x65, 0x64, 0x20, 0x6f, 0x66, 0x73, 0x75, + 0x70, 0x70, 0x6f, 0x72, 0x74, 0x20, 0x74, 0x68, 0x65, 0x20, 0x68, 0x61, 0x6e, + 0x64, 0x73, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x63, 0x6f, 0x75, 0x70, + 0x6c, 0x65, 0x64, 0x20, 0x77, 0x69, 0x74, 0x68, 0x63, 0x6f, 0x6e, 0x6e, 0x65, + 0x63, 0x74, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, + 0x3a, 0x6e, 0x6f, 0x6e, 0x65, 0x3b, 0x70, 0x65, 0x72, 0x66, 0x6f, 0x72, 0x6d, + 0x61, 0x6e, 0x63, 0x65, 0x73, 0x62, 0x65, 0x66, 0x6f, 0x72, 0x65, 0x20, 0x62, + 0x65, 0x69, 0x6e, 0x67, 0x6c, 0x61, 0x74, 0x65, 0x72, 0x20, 0x62, 0x65, 0x63, + 0x61, 0x6d, 0x65, 0x63, 0x61, 0x6c, 0x63, 0x75, 0x6c, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x73, 0x6f, 0x66, 0x74, 0x65, 0x6e, 0x20, 0x63, 0x61, 0x6c, 0x6c, 0x65, + 0x64, 0x72, 0x65, 0x73, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x73, 0x20, 0x6f, 0x66, + 0x6d, 0x65, 0x61, 0x6e, 0x69, 0x6e, 0x67, 0x20, 0x74, 0x68, 0x61, 0x74, 0x3e, + 0x3c, 0x6c, 0x69, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x22, 0x65, 0x76, + 0x69, 0x64, 0x65, 0x6e, 0x63, 0x65, 0x20, 0x66, 0x6f, 0x72, 0x65, 0x78, 0x70, + 0x6c, 0x61, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x65, 0x6e, 0x76, 0x69, + 0x72, 0x6f, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x22, 0x3e, 0x3c, 0x2f, 0x61, + 0x3e, 0x3c, 0x2f, 0x64, 0x69, 0x76, 0x3e, 0x77, 0x68, 0x69, 0x63, 0x68, 0x20, + 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x73, 0x49, 0x6e, 0x74, 0x72, 0x6f, 0x64, 0x75, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x64, 0x65, 0x76, 0x65, 0x6c, 0x6f, 0x70, 0x65, + 0x64, 0x20, 0x62, 0x79, 0x61, 0x20, 0x77, 0x69, 0x64, 0x65, 0x20, 0x72, 0x61, + 0x6e, 0x67, 0x65, 0x6f, 0x6e, 0x20, 0x62, 0x65, 0x68, 0x61, 0x6c, 0x66, 0x20, + 0x6f, 0x66, 0x76, 0x61, 0x6c, 0x69, 0x67, 0x6e, 0x3d, 0x22, 0x74, 0x6f, 0x70, + 0x22, 0x70, 0x72, 0x69, 0x6e, 0x63, 0x69, 0x70, 0x6c, 0x65, 0x20, 0x6f, 0x66, + 0x61, 0x74, 0x20, 0x74, 0x68, 0x65, 0x20, 0x74, 0x69, 0x6d, 0x65, 0x2c, 0x3c, + 0x2f, 0x6e, 0x6f, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x3e, 0x0d, 0x73, 0x61, + 0x69, 0x64, 0x20, 0x74, 0x6f, 0x20, 0x68, 0x61, 0x76, 0x65, 0x69, 0x6e, 0x20, + 0x74, 0x68, 0x65, 0x20, 0x66, 0x69, 0x72, 0x73, 0x74, 0x77, 0x68, 0x69, 0x6c, + 0x65, 0x20, 0x6f, 0x74, 0x68, 0x65, 0x72, 0x73, 0x68, 0x79, 0x70, 0x6f, 0x74, + 0x68, 0x65, 0x74, 0x69, 0x63, 0x61, 0x6c, 0x70, 0x68, 0x69, 0x6c, 0x6f, 0x73, + 0x6f, 0x70, 0x68, 0x65, 0x72, 0x73, 0x70, 0x6f, 0x77, 0x65, 0x72, 0x20, 0x6f, + 0x66, 0x20, 0x74, 0x68, 0x65, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, + 0x64, 0x20, 0x69, 0x6e, 0x70, 0x65, 0x72, 0x66, 0x6f, 0x72, 0x6d, 0x65, 0x64, + 0x20, 0x62, 0x79, 0x69, 0x6e, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x20, + 0x74, 0x6f, 0x77, 0x65, 0x72, 0x65, 0x20, 0x77, 0x72, 0x69, 0x74, 0x74, 0x65, + 0x6e, 0x73, 0x70, 0x61, 0x6e, 0x20, 0x73, 0x74, 0x79, 0x6c, 0x65, 0x3d, 0x22, + 0x69, 0x6e, 0x70, 0x75, 0x74, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x3d, 0x22, 0x74, + 0x68, 0x65, 0x20, 0x71, 0x75, 0x65, 0x73, 0x74, 0x69, 0x6f, 0x6e, 0x69, 0x6e, + 0x74, 0x65, 0x6e, 0x64, 0x65, 0x64, 0x20, 0x66, 0x6f, 0x72, 0x72, 0x65, 0x6a, + 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6f, 0x66, 0x69, 0x6d, 0x70, 0x6c, + 0x69, 0x65, 0x73, 0x20, 0x74, 0x68, 0x61, 0x74, 0x69, 0x6e, 0x76, 0x65, 0x6e, + 0x74, 0x65, 0x64, 0x20, 0x74, 0x68, 0x65, 0x74, 0x68, 0x65, 0x20, 0x73, 0x74, + 0x61, 0x6e, 0x64, 0x61, 0x72, 0x64, 0x77, 0x61, 0x73, 0x20, 0x70, 0x72, 0x6f, + 0x62, 0x61, 0x62, 0x6c, 0x79, 0x6c, 0x69, 0x6e, 0x6b, 0x20, 0x62, 0x65, 0x74, + 0x77, 0x65, 0x65, 0x6e, 0x70, 0x72, 0x6f, 0x66, 0x65, 0x73, 0x73, 0x6f, 0x72, + 0x20, 0x6f, 0x66, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x61, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x73, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x69, 0x6e, 0x67, 0x20, 0x74, 0x68, + 0x65, 0x49, 0x6e, 0x64, 0x69, 0x61, 0x6e, 0x20, 0x4f, 0x63, 0x65, 0x61, 0x6e, + 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x22, 0x6c, 0x61, 0x73, 0x74, 0x77, + 0x6f, 0x72, 0x6b, 0x69, 0x6e, 0x67, 0x20, 0x77, 0x69, 0x74, 0x68, 0x27, 0x68, + 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x79, 0x65, 0x61, + 0x72, 0x73, 0x20, 0x62, 0x65, 0x66, 0x6f, 0x72, 0x65, 0x54, 0x68, 0x69, 0x73, + 0x20, 0x77, 0x61, 0x73, 0x20, 0x74, 0x68, 0x65, 0x72, 0x65, 0x63, 0x72, 0x65, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x69, + 0x6e, 0x67, 0x20, 0x74, 0x68, 0x65, 0x6d, 0x65, 0x61, 0x73, 0x75, 0x72, 0x65, + 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x61, 0x6e, 0x20, 0x65, 0x78, 0x74, 0x72, 0x65, + 0x6d, 0x65, 0x6c, 0x79, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x20, 0x6f, 0x66, 0x20, + 0x74, 0x68, 0x65, 0x73, 0x74, 0x61, 0x72, 0x74, 0x20, 0x6f, 0x66, 0x20, 0x74, + 0x68, 0x65, 0x0a, 0x3c, 0x2f, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x3e, 0x0a, + 0x0a, 0x61, 0x6e, 0x20, 0x65, 0x66, 0x66, 0x6f, 0x72, 0x74, 0x20, 0x74, 0x6f, + 0x69, 0x6e, 0x63, 0x72, 0x65, 0x61, 0x73, 0x65, 0x20, 0x74, 0x68, 0x65, 0x74, + 0x6f, 0x20, 0x74, 0x68, 0x65, 0x20, 0x73, 0x6f, 0x75, 0x74, 0x68, 0x73, 0x70, + 0x61, 0x63, 0x69, 0x6e, 0x67, 0x3d, 0x22, 0x30, 0x22, 0x3e, 0x73, 0x75, 0x66, + 0x66, 0x69, 0x63, 0x69, 0x65, 0x6e, 0x74, 0x6c, 0x79, 0x74, 0x68, 0x65, 0x20, + 0x45, 0x75, 0x72, 0x6f, 0x70, 0x65, 0x61, 0x6e, 0x63, 0x6f, 0x6e, 0x76, 0x65, + 0x72, 0x74, 0x65, 0x64, 0x20, 0x74, 0x6f, 0x63, 0x6c, 0x65, 0x61, 0x72, 0x54, + 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x64, 0x69, 0x64, 0x20, 0x6e, 0x6f, 0x74, + 0x20, 0x68, 0x61, 0x76, 0x65, 0x63, 0x6f, 0x6e, 0x73, 0x65, 0x71, 0x75, 0x65, + 0x6e, 0x74, 0x6c, 0x79, 0x66, 0x6f, 0x72, 0x20, 0x74, 0x68, 0x65, 0x20, 0x6e, + 0x65, 0x78, 0x74, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x20, + 0x6f, 0x66, 0x65, 0x63, 0x6f, 0x6e, 0x6f, 0x6d, 0x69, 0x63, 0x20, 0x61, 0x6e, + 0x64, 0x61, 0x6c, 0x74, 0x68, 0x6f, 0x75, 0x67, 0x68, 0x20, 0x74, 0x68, 0x65, + 0x61, 0x72, 0x65, 0x20, 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x65, 0x64, 0x61, + 0x6e, 0x64, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x74, 0x68, 0x65, 0x69, 0x6e, + 0x73, 0x75, 0x66, 0x66, 0x69, 0x63, 0x69, 0x65, 0x6e, 0x74, 0x67, 0x69, 0x76, + 0x65, 0x6e, 0x20, 0x62, 0x79, 0x20, 0x74, 0x68, 0x65, 0x73, 0x74, 0x61, 0x74, + 0x69, 0x6e, 0x67, 0x20, 0x74, 0x68, 0x61, 0x74, 0x65, 0x78, 0x70, 0x65, 0x6e, + 0x64, 0x69, 0x74, 0x75, 0x72, 0x65, 0x73, 0x3c, 0x2f, 0x73, 0x70, 0x61, 0x6e, + 0x3e, 0x3c, 0x2f, 0x61, 0x3e, 0x0a, 0x74, 0x68, 0x6f, 0x75, 0x67, 0x68, 0x74, + 0x20, 0x74, 0x68, 0x61, 0x74, 0x6f, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x62, + 0x61, 0x73, 0x69, 0x73, 0x63, 0x65, 0x6c, 0x6c, 0x70, 0x61, 0x64, 0x64, 0x69, + 0x6e, 0x67, 0x3d, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x20, 0x6f, 0x66, 0x20, 0x74, + 0x68, 0x65, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x69, 0x6e, 0x67, 0x20, 0x74, + 0x6f, 0x69, 0x6e, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2c, + 0x73, 0x65, 0x70, 0x61, 0x72, 0x61, 0x74, 0x65, 0x64, 0x20, 0x62, 0x79, 0x61, + 0x73, 0x73, 0x61, 0x73, 0x73, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x64, 0x73, 0x22, + 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x3d, 0x22, 0x61, 0x75, 0x74, + 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x20, 0x6f, 0x66, 0x6e, 0x6f, 0x72, 0x74, + 0x68, 0x77, 0x65, 0x73, 0x74, 0x65, 0x72, 0x6e, 0x3c, 0x2f, 0x64, 0x69, 0x76, + 0x3e, 0x0a, 0x3c, 0x64, 0x69, 0x76, 0x20, 0x22, 0x3e, 0x3c, 0x2f, 0x64, 0x69, + 0x76, 0x3e, 0x0d, 0x0a, 0x20, 0x20, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x74, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x63, 0x6f, 0x6d, 0x6d, 0x75, 0x6e, 0x69, 0x74, + 0x79, 0x20, 0x6f, 0x66, 0x74, 0x68, 0x65, 0x20, 0x6e, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x61, 0x6c, 0x69, 0x74, 0x20, 0x73, 0x68, 0x6f, 0x75, 0x6c, 0x64, 0x20, + 0x62, 0x65, 0x70, 0x61, 0x72, 0x74, 0x69, 0x63, 0x69, 0x70, 0x61, 0x6e, 0x74, + 0x73, 0x20, 0x61, 0x6c, 0x69, 0x67, 0x6e, 0x3d, 0x22, 0x6c, 0x65, 0x66, 0x74, + 0x74, 0x68, 0x65, 0x20, 0x67, 0x72, 0x65, 0x61, 0x74, 0x65, 0x73, 0x74, 0x73, + 0x65, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6f, 0x66, 0x73, 0x75, + 0x70, 0x65, 0x72, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x61, 0x6c, 0x64, 0x65, 0x70, + 0x65, 0x6e, 0x64, 0x65, 0x6e, 0x74, 0x20, 0x6f, 0x6e, 0x69, 0x73, 0x20, 0x6d, + 0x65, 0x6e, 0x74, 0x69, 0x6f, 0x6e, 0x65, 0x64, 0x61, 0x6c, 0x6c, 0x6f, 0x77, + 0x69, 0x6e, 0x67, 0x20, 0x74, 0x68, 0x65, 0x77, 0x61, 0x73, 0x20, 0x69, 0x6e, + 0x76, 0x65, 0x6e, 0x74, 0x65, 0x64, 0x61, 0x63, 0x63, 0x6f, 0x6d, 0x70, 0x61, + 0x6e, 0x79, 0x69, 0x6e, 0x67, 0x68, 0x69, 0x73, 0x20, 0x70, 0x65, 0x72, 0x73, + 0x6f, 0x6e, 0x61, 0x6c, 0x61, 0x76, 0x61, 0x69, 0x6c, 0x61, 0x62, 0x6c, 0x65, + 0x20, 0x61, 0x74, 0x73, 0x74, 0x75, 0x64, 0x79, 0x20, 0x6f, 0x66, 0x20, 0x74, + 0x68, 0x65, 0x6f, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x6f, 0x74, 0x68, 0x65, + 0x72, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6f, 0x66, + 0x48, 0x75, 0x6d, 0x61, 0x6e, 0x20, 0x52, 0x69, 0x67, 0x68, 0x74, 0x73, 0x74, + 0x65, 0x72, 0x6d, 0x73, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x61, 0x73, + 0x73, 0x6f, 0x63, 0x69, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x72, 0x65, 0x73, + 0x65, 0x61, 0x72, 0x63, 0x68, 0x20, 0x61, 0x6e, 0x64, 0x73, 0x75, 0x63, 0x63, + 0x65, 0x65, 0x64, 0x65, 0x64, 0x20, 0x62, 0x79, 0x64, 0x65, 0x66, 0x65, 0x61, + 0x74, 0x65, 0x64, 0x20, 0x74, 0x68, 0x65, 0x61, 0x6e, 0x64, 0x20, 0x66, 0x72, + 0x6f, 0x6d, 0x20, 0x74, 0x68, 0x65, 0x62, 0x75, 0x74, 0x20, 0x74, 0x68, 0x65, + 0x79, 0x20, 0x61, 0x72, 0x65, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x65, + 0x72, 0x20, 0x6f, 0x66, 0x73, 0x74, 0x61, 0x74, 0x65, 0x20, 0x6f, 0x66, 0x20, + 0x74, 0x68, 0x65, 0x79, 0x65, 0x61, 0x72, 0x73, 0x20, 0x6f, 0x66, 0x20, 0x61, + 0x67, 0x65, 0x74, 0x68, 0x65, 0x20, 0x73, 0x74, 0x75, 0x64, 0x79, 0x20, 0x6f, + 0x66, 0x3c, 0x75, 0x6c, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x22, 0x73, + 0x70, 0x6c, 0x61, 0x63, 0x65, 0x20, 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x77, + 0x68, 0x65, 0x72, 0x65, 0x20, 0x68, 0x65, 0x20, 0x77, 0x61, 0x73, 0x3c, 0x6c, + 0x69, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x22, 0x66, 0x74, 0x68, 0x65, + 0x72, 0x65, 0x20, 0x61, 0x72, 0x65, 0x20, 0x6e, 0x6f, 0x77, 0x68, 0x69, 0x63, + 0x68, 0x20, 0x62, 0x65, 0x63, 0x61, 0x6d, 0x65, 0x68, 0x65, 0x20, 0x70, 0x75, + 0x62, 0x6c, 0x69, 0x73, 0x68, 0x65, 0x64, 0x65, 0x78, 0x70, 0x72, 0x65, 0x73, + 0x73, 0x65, 0x64, 0x20, 0x69, 0x6e, 0x74, 0x6f, 0x20, 0x77, 0x68, 0x69, 0x63, + 0x68, 0x20, 0x74, 0x68, 0x65, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x73, 0x73, 0x69, + 0x6f, 0x6e, 0x65, 0x72, 0x66, 0x6f, 0x6e, 0x74, 0x2d, 0x77, 0x65, 0x69, 0x67, + 0x68, 0x74, 0x3a, 0x74, 0x65, 0x72, 0x72, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x20, + 0x6f, 0x66, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x22, + 0x3e, 0x52, 0x6f, 0x6d, 0x61, 0x6e, 0x20, 0x45, 0x6d, 0x70, 0x69, 0x72, 0x65, + 0x65, 0x71, 0x75, 0x61, 0x6c, 0x20, 0x74, 0x6f, 0x20, 0x74, 0x68, 0x65, 0x49, + 0x6e, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x73, 0x74, 0x2c, 0x68, 0x6f, + 0x77, 0x65, 0x76, 0x65, 0x72, 0x2c, 0x20, 0x61, 0x6e, 0x64, 0x69, 0x73, 0x20, + 0x74, 0x79, 0x70, 0x69, 0x63, 0x61, 0x6c, 0x6c, 0x79, 0x61, 0x6e, 0x64, 0x20, + 0x68, 0x69, 0x73, 0x20, 0x77, 0x69, 0x66, 0x65, 0x28, 0x61, 0x6c, 0x73, 0x6f, + 0x20, 0x63, 0x61, 0x6c, 0x6c, 0x65, 0x64, 0x3e, 0x3c, 0x75, 0x6c, 0x20, 0x63, + 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x22, 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, 0x69, + 0x76, 0x65, 0x6c, 0x79, 0x20, 0x65, 0x76, 0x6f, 0x6c, 0x76, 0x65, 0x64, 0x20, + 0x69, 0x6e, 0x74, 0x6f, 0x73, 0x65, 0x65, 0x6d, 0x20, 0x74, 0x6f, 0x20, 0x68, + 0x61, 0x76, 0x65, 0x77, 0x68, 0x69, 0x63, 0x68, 0x20, 0x69, 0x73, 0x20, 0x74, + 0x68, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x20, 0x77, 0x61, 0x73, 0x20, 0x6e, + 0x6f, 0x61, 0x6e, 0x20, 0x65, 0x78, 0x63, 0x65, 0x6c, 0x6c, 0x65, 0x6e, 0x74, + 0x61, 0x6c, 0x6c, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x73, 0x65, 0x64, + 0x65, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x64, 0x20, 0x62, 0x79, 0x49, 0x6e, + 0x20, 0x70, 0x72, 0x61, 0x63, 0x74, 0x69, 0x63, 0x65, 0x2c, 0x62, 0x72, 0x6f, + 0x61, 0x64, 0x63, 0x61, 0x73, 0x74, 0x69, 0x6e, 0x67, 0x63, 0x68, 0x61, 0x72, + 0x67, 0x65, 0x64, 0x20, 0x77, 0x69, 0x74, 0x68, 0x72, 0x65, 0x66, 0x6c, 0x65, + 0x63, 0x74, 0x65, 0x64, 0x20, 0x69, 0x6e, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, + 0x74, 0x65, 0x64, 0x20, 0x74, 0x6f, 0x6d, 0x69, 0x6c, 0x69, 0x74, 0x61, 0x72, + 0x79, 0x20, 0x61, 0x6e, 0x64, 0x74, 0x6f, 0x20, 0x74, 0x68, 0x65, 0x20, 0x70, + 0x6f, 0x69, 0x6e, 0x74, 0x65, 0x63, 0x6f, 0x6e, 0x6f, 0x6d, 0x69, 0x63, 0x61, + 0x6c, 0x6c, 0x79, 0x73, 0x65, 0x74, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x69, + 0x6e, 0x67, 0x61, 0x72, 0x65, 0x20, 0x61, 0x63, 0x74, 0x75, 0x61, 0x6c, 0x6c, + 0x79, 0x76, 0x69, 0x63, 0x74, 0x6f, 0x72, 0x79, 0x20, 0x6f, 0x76, 0x65, 0x72, + 0x28, 0x29, 0x3b, 0x3c, 0x2f, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x3e, 0x63, + 0x6f, 0x6e, 0x74, 0x69, 0x6e, 0x75, 0x6f, 0x75, 0x73, 0x6c, 0x79, 0x72, 0x65, + 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x20, 0x66, 0x6f, 0x72, 0x65, 0x76, 0x6f, + 0x6c, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x72, 0x79, 0x61, 0x6e, 0x20, 0x65, + 0x66, 0x66, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x6e, 0x6f, 0x72, 0x74, 0x68, + 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x2c, 0x20, 0x77, 0x68, 0x69, 0x63, + 0x68, 0x20, 0x77, 0x61, 0x73, 0x20, 0x66, 0x72, 0x6f, 0x6e, 0x74, 0x20, 0x6f, + 0x66, 0x20, 0x74, 0x68, 0x65, 0x6f, 0x72, 0x20, 0x6f, 0x74, 0x68, 0x65, 0x72, + 0x77, 0x69, 0x73, 0x65, 0x73, 0x6f, 0x6d, 0x65, 0x20, 0x66, 0x6f, 0x72, 0x6d, + 0x20, 0x6f, 0x66, 0x68, 0x61, 0x64, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x62, 0x65, + 0x65, 0x6e, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x64, 0x20, 0x62, + 0x79, 0x69, 0x6e, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, + 0x70, 0x65, 0x72, 0x6d, 0x69, 0x74, 0x74, 0x65, 0x64, 0x20, 0x74, 0x6f, 0x69, + 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x73, 0x20, 0x74, 0x68, 0x65, 0x64, 0x65, + 0x76, 0x65, 0x6c, 0x6f, 0x70, 0x6d, 0x65, 0x6e, 0x74, 0x2c, 0x65, 0x6e, 0x74, + 0x65, 0x72, 0x65, 0x64, 0x20, 0x69, 0x6e, 0x74, 0x6f, 0x74, 0x68, 0x65, 0x20, + 0x70, 0x72, 0x65, 0x76, 0x69, 0x6f, 0x75, 0x73, 0x63, 0x6f, 0x6e, 0x73, 0x69, + 0x73, 0x74, 0x65, 0x6e, 0x74, 0x6c, 0x79, 0x61, 0x72, 0x65, 0x20, 0x6b, 0x6e, + 0x6f, 0x77, 0x6e, 0x20, 0x61, 0x73, 0x74, 0x68, 0x65, 0x20, 0x66, 0x69, 0x65, + 0x6c, 0x64, 0x20, 0x6f, 0x66, 0x74, 0x68, 0x69, 0x73, 0x20, 0x74, 0x79, 0x70, + 0x65, 0x20, 0x6f, 0x66, 0x67, 0x69, 0x76, 0x65, 0x6e, 0x20, 0x74, 0x6f, 0x20, + 0x74, 0x68, 0x65, 0x74, 0x68, 0x65, 0x20, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x20, + 0x6f, 0x66, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x73, 0x20, 0x74, 0x68, + 0x65, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x20, 0x6f, 0x66, + 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x6e, 0x6f, 0x72, 0x74, 0x68, 0x64, + 0x75, 0x65, 0x20, 0x74, 0x6f, 0x20, 0x74, 0x68, 0x65, 0x69, 0x72, 0x61, 0x72, + 0x65, 0x20, 0x64, 0x65, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x63, 0x6f, 0x72, + 0x70, 0x6f, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x77, 0x61, 0x73, 0x20, + 0x74, 0x68, 0x61, 0x74, 0x20, 0x74, 0x68, 0x65, 0x6f, 0x6e, 0x65, 0x20, 0x6f, + 0x66, 0x20, 0x74, 0x68, 0x65, 0x73, 0x65, 0x6d, 0x6f, 0x72, 0x65, 0x20, 0x70, + 0x6f, 0x70, 0x75, 0x6c, 0x61, 0x72, 0x73, 0x75, 0x63, 0x63, 0x65, 0x65, 0x64, + 0x65, 0x64, 0x20, 0x69, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x20, + 0x66, 0x72, 0x6f, 0x6d, 0x69, 0x6e, 0x20, 0x64, 0x69, 0x66, 0x66, 0x65, 0x72, + 0x65, 0x6e, 0x74, 0x64, 0x6f, 0x6d, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x64, 0x20, + 0x62, 0x79, 0x64, 0x65, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x20, 0x66, 0x6f, + 0x72, 0x6f, 0x77, 0x6e, 0x65, 0x72, 0x73, 0x68, 0x69, 0x70, 0x20, 0x6f, 0x66, + 0x61, 0x6e, 0x64, 0x20, 0x70, 0x6f, 0x73, 0x73, 0x69, 0x62, 0x6c, 0x79, 0x73, + 0x74, 0x61, 0x6e, 0x64, 0x61, 0x72, 0x64, 0x69, 0x7a, 0x65, 0x64, 0x72, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x54, 0x65, 0x78, 0x74, 0x77, 0x61, 0x73, + 0x20, 0x69, 0x6e, 0x74, 0x65, 0x6e, 0x64, 0x65, 0x64, 0x72, 0x65, 0x63, 0x65, + 0x69, 0x76, 0x65, 0x64, 0x20, 0x74, 0x68, 0x65, 0x61, 0x73, 0x73, 0x75, 0x6d, + 0x65, 0x64, 0x20, 0x74, 0x68, 0x61, 0x74, 0x61, 0x72, 0x65, 0x61, 0x73, 0x20, + 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x70, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x69, + 0x6c, 0x79, 0x20, 0x69, 0x6e, 0x74, 0x68, 0x65, 0x20, 0x62, 0x61, 0x73, 0x69, + 0x73, 0x20, 0x6f, 0x66, 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x73, 0x65, + 0x6e, 0x73, 0x65, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x20, 0x66, + 0x6f, 0x72, 0x64, 0x65, 0x73, 0x74, 0x72, 0x6f, 0x79, 0x65, 0x64, 0x20, 0x62, + 0x79, 0x61, 0x74, 0x20, 0x6c, 0x65, 0x61, 0x73, 0x74, 0x20, 0x74, 0x77, 0x6f, + 0x77, 0x61, 0x73, 0x20, 0x64, 0x65, 0x63, 0x6c, 0x61, 0x72, 0x65, 0x64, 0x63, + 0x6f, 0x75, 0x6c, 0x64, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x62, 0x65, 0x53, 0x65, + 0x63, 0x72, 0x65, 0x74, 0x61, 0x72, 0x79, 0x20, 0x6f, 0x66, 0x61, 0x70, 0x70, + 0x65, 0x61, 0x72, 0x20, 0x74, 0x6f, 0x20, 0x62, 0x65, 0x6d, 0x61, 0x72, 0x67, + 0x69, 0x6e, 0x2d, 0x74, 0x6f, 0x70, 0x3a, 0x31, 0x2f, 0x5e, 0x5c, 0x73, 0x2b, + 0x7c, 0x5c, 0x73, 0x2b, 0x24, 0x2f, 0x67, 0x65, 0x29, 0x7b, 0x74, 0x68, 0x72, + 0x6f, 0x77, 0x20, 0x65, 0x7d, 0x3b, 0x74, 0x68, 0x65, 0x20, 0x73, 0x74, 0x61, + 0x72, 0x74, 0x20, 0x6f, 0x66, 0x74, 0x77, 0x6f, 0x20, 0x73, 0x65, 0x70, 0x61, + 0x72, 0x61, 0x74, 0x65, 0x6c, 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, 0x20, + 0x61, 0x6e, 0x64, 0x77, 0x68, 0x6f, 0x20, 0x68, 0x61, 0x64, 0x20, 0x62, 0x65, + 0x65, 0x6e, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6f, + 0x66, 0x64, 0x65, 0x61, 0x74, 0x68, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, + 0x72, 0x65, 0x61, 0x6c, 0x20, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x09, + 0x3c, 0x6c, 0x69, 0x6e, 0x6b, 0x20, 0x72, 0x65, 0x6c, 0x3d, 0x22, 0x70, 0x72, + 0x6f, 0x76, 0x69, 0x64, 0x65, 0x64, 0x20, 0x74, 0x68, 0x65, 0x74, 0x68, 0x65, + 0x20, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x20, 0x6f, 0x66, 0x63, 0x6f, 0x6d, 0x70, + 0x65, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x65, 0x6e, 0x67, 0x6c, 0x69, + 0x73, 0x68, 0x20, 0x28, 0x55, 0x4b, 0x29, 0x65, 0x6e, 0x67, 0x6c, 0x69, 0x73, + 0x68, 0x20, 0x28, 0x55, 0x53, 0x29, 0xd0, 0x9c, 0xd0, 0xbe, 0xd0, 0xbd, 0xd0, + 0xb3, 0xd0, 0xbe, 0xd0, 0xbb, 0xd0, 0xa1, 0xd1, 0x80, 0xd0, 0xbf, 0xd1, 0x81, + 0xd0, 0xba, 0xd0, 0xb8, 0xd1, 0x81, 0xd1, 0x80, 0xd0, 0xbf, 0xd1, 0x81, 0xd0, + 0xba, 0xd0, 0xb8, 0xd1, 0x81, 0xd1, 0x80, 0xd0, 0xbf, 0xd1, 0x81, 0xd0, 0xba, + 0xd0, 0xbe, 0xd9, 0x84, 0xd8, 0xb9, 0xd8, 0xb1, 0xd8, 0xa8, 0xd9, 0x8a, 0xd8, + 0xa9, 0xe6, 0xad, 0xa3, 0xe9, 0xab, 0x94, 0xe4, 0xb8, 0xad, 0xe6, 0x96, 0x87, + 0xe7, 0xae, 0x80, 0xe4, 0xbd, 0x93, 0xe4, 0xb8, 0xad, 0xe6, 0x96, 0x87, 0xe7, + 0xb9, 0x81, 0xe4, 0xbd, 0x93, 0xe4, 0xb8, 0xad, 0xe6, 0x96, 0x87, 0xe6, 0x9c, + 0x89, 0xe9, 0x99, 0x90, 0xe5, 0x85, 0xac, 0xe5, 0x8f, 0xb8, 0xe4, 0xba, 0xba, + 0xe6, 0xb0, 0x91, 0xe6, 0x94, 0xbf, 0xe5, 0xba, 0x9c, 0xe9, 0x98, 0xbf, 0xe9, + 0x87, 0x8c, 0xe5, 0xb7, 0xb4, 0xe5, 0xb7, 0xb4, 0xe7, 0xa4, 0xbe, 0xe4, 0xbc, + 0x9a, 0xe4, 0xb8, 0xbb, 0xe4, 0xb9, 0x89, 0xe6, 0x93, 0x8d, 0xe4, 0xbd, 0x9c, + 0xe7, 0xb3, 0xbb, 0xe7, 0xbb, 0x9f, 0xe6, 0x94, 0xbf, 0xe7, 0xad, 0x96, 0xe6, + 0xb3, 0x95, 0xe8, 0xa7, 0x84, 0x69, 0x6e, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x63, + 0x69, 0xc3, 0xb3, 0x6e, 0x68, 0x65, 0x72, 0x72, 0x61, 0x6d, 0x69, 0x65, 0x6e, + 0x74, 0x61, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x72, 0xc3, 0xb3, 0x6e, 0x69, + 0x63, 0x6f, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x63, 0x69, 0xc3, 0xb3, + 0x6e, 0x63, 0x6c, 0x61, 0x73, 0x69, 0x66, 0x69, 0x63, 0x61, 0x64, 0x6f, 0x73, + 0x63, 0x6f, 0x6e, 0x6f, 0x63, 0x69, 0x6d, 0x69, 0x65, 0x6e, 0x74, 0x6f, 0x70, + 0x75, 0x62, 0x6c, 0x69, 0x63, 0x61, 0x63, 0x69, 0xc3, 0xb3, 0x6e, 0x72, 0x65, + 0x6c, 0x61, 0x63, 0x69, 0x6f, 0x6e, 0x61, 0x64, 0x61, 0x73, 0x69, 0x6e, 0x66, + 0x6f, 0x72, 0x6d, 0xc3, 0xa1, 0x74, 0x69, 0x63, 0x61, 0x72, 0x65, 0x6c, 0x61, + 0x63, 0x69, 0x6f, 0x6e, 0x61, 0x64, 0x6f, 0x73, 0x64, 0x65, 0x70, 0x61, 0x72, + 0x74, 0x61, 0x6d, 0x65, 0x6e, 0x74, 0x6f, 0x74, 0x72, 0x61, 0x62, 0x61, 0x6a, + 0x61, 0x64, 0x6f, 0x72, 0x65, 0x73, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x61, + 0x6d, 0x65, 0x6e, 0x74, 0x65, 0x61, 0x79, 0x75, 0x6e, 0x74, 0x61, 0x6d, 0x69, + 0x65, 0x6e, 0x74, 0x6f, 0x6d, 0x65, 0x72, 0x63, 0x61, 0x64, 0x6f, 0x4c, 0x69, + 0x62, 0x72, 0x65, 0x63, 0x6f, 0x6e, 0x74, 0xc3, 0xa1, 0x63, 0x74, 0x65, 0x6e, + 0x6f, 0x73, 0x68, 0x61, 0x62, 0x69, 0x74, 0x61, 0x63, 0x69, 0x6f, 0x6e, 0x65, + 0x73, 0x63, 0x75, 0x6d, 0x70, 0x6c, 0x69, 0x6d, 0x69, 0x65, 0x6e, 0x74, 0x6f, + 0x72, 0x65, 0x73, 0x74, 0x61, 0x75, 0x72, 0x61, 0x6e, 0x74, 0x65, 0x73, 0x64, + 0x69, 0x73, 0x70, 0x6f, 0x73, 0x69, 0x63, 0x69, 0xc3, 0xb3, 0x6e, 0x63, 0x6f, + 0x6e, 0x73, 0x65, 0x63, 0x75, 0x65, 0x6e, 0x63, 0x69, 0x61, 0x65, 0x6c, 0x65, + 0x63, 0x74, 0x72, 0xc3, 0xb3, 0x6e, 0x69, 0x63, 0x61, 0x61, 0x70, 0x6c, 0x69, + 0x63, 0x61, 0x63, 0x69, 0x6f, 0x6e, 0x65, 0x73, 0x64, 0x65, 0x73, 0x63, 0x6f, + 0x6e, 0x65, 0x63, 0x74, 0x61, 0x64, 0x6f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6c, + 0x61, 0x63, 0x69, 0xc3, 0xb3, 0x6e, 0x72, 0x65, 0x61, 0x6c, 0x69, 0x7a, 0x61, + 0x63, 0x69, 0xc3, 0xb3, 0x6e, 0x75, 0x74, 0x69, 0x6c, 0x69, 0x7a, 0x61, 0x63, + 0x69, 0xc3, 0xb3, 0x6e, 0x65, 0x6e, 0x63, 0x69, 0x63, 0x6c, 0x6f, 0x70, 0x65, + 0x64, 0x69, 0x61, 0x65, 0x6e, 0x66, 0x65, 0x72, 0x6d, 0x65, 0x64, 0x61, 0x64, + 0x65, 0x73, 0x69, 0x6e, 0x73, 0x74, 0x72, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x6f, + 0x73, 0x65, 0x78, 0x70, 0x65, 0x72, 0x69, 0x65, 0x6e, 0x63, 0x69, 0x61, 0x73, + 0x69, 0x6e, 0x73, 0x74, 0x69, 0x74, 0x75, 0x63, 0x69, 0xc3, 0xb3, 0x6e, 0x70, + 0x61, 0x72, 0x74, 0x69, 0x63, 0x75, 0x6c, 0x61, 0x72, 0x65, 0x73, 0x73, 0x75, + 0x62, 0x63, 0x61, 0x74, 0x65, 0x67, 0x6f, 0x72, 0x69, 0x61, 0xd1, 0x82, 0xd0, + 0xbe, 0xd0, 0xbb, 0xd1, 0x8c, 0xd0, 0xba, 0xd0, 0xbe, 0xd0, 0xa0, 0xd0, 0xbe, + 0xd1, 0x81, 0xd1, 0x81, 0xd0, 0xb8, 0xd0, 0xb8, 0xd1, 0x80, 0xd0, 0xb0, 0xd0, + 0xb1, 0xd0, 0xbe, 0xd1, 0x82, 0xd1, 0x8b, 0xd0, 0xb1, 0xd0, 0xbe, 0xd0, 0xbb, + 0xd1, 0x8c, 0xd1, 0x88, 0xd0, 0xb5, 0xd0, 0xbf, 0xd1, 0x80, 0xd0, 0xbe, 0xd1, + 0x81, 0xd1, 0x82, 0xd0, 0xbe, 0xd0, 0xbc, 0xd0, 0xbe, 0xd0, 0xb6, 0xd0, 0xb5, + 0xd1, 0x82, 0xd0, 0xb5, 0xd0, 0xb4, 0xd1, 0x80, 0xd1, 0x83, 0xd0, 0xb3, 0xd0, + 0xb8, 0xd1, 0x85, 0xd1, 0x81, 0xd0, 0xbb, 0xd1, 0x83, 0xd1, 0x87, 0xd0, 0xb0, + 0xd0, 0xb5, 0xd1, 0x81, 0xd0, 0xb5, 0xd0, 0xb9, 0xd1, 0x87, 0xd0, 0xb0, 0xd1, + 0x81, 0xd0, 0xb2, 0xd1, 0x81, 0xd0, 0xb5, 0xd0, 0xb3, 0xd0, 0xb4, 0xd0, 0xb0, + 0xd0, 0xa0, 0xd0, 0xbe, 0xd1, 0x81, 0xd1, 0x81, 0xd0, 0xb8, 0xd1, 0x8f, 0xd0, + 0x9c, 0xd0, 0xbe, 0xd1, 0x81, 0xd0, 0xba, 0xd0, 0xb2, 0xd0, 0xb5, 0xd0, 0xb4, + 0xd1, 0x80, 0xd1, 0x83, 0xd0, 0xb3, 0xd0, 0xb8, 0xd0, 0xb5, 0xd0, 0xb3, 0xd0, + 0xbe, 0xd1, 0x80, 0xd0, 0xbe, 0xd0, 0xb4, 0xd0, 0xb0, 0xd0, 0xb2, 0xd0, 0xbe, + 0xd0, 0xbf, 0xd1, 0x80, 0xd0, 0xbe, 0xd1, 0x81, 0xd0, 0xb4, 0xd0, 0xb0, 0xd0, + 0xbd, 0xd0, 0xbd, 0xd1, 0x8b, 0xd1, 0x85, 0xd0, 0xb4, 0xd0, 0xbe, 0xd0, 0xbb, + 0xd0, 0xb6, 0xd0, 0xbd, 0xd1, 0x8b, 0xd0, 0xb8, 0xd0, 0xbc, 0xd0, 0xb5, 0xd0, + 0xbd, 0xd0, 0xbd, 0xd0, 0xbe, 0xd0, 0x9c, 0xd0, 0xbe, 0xd1, 0x81, 0xd0, 0xba, + 0xd0, 0xb2, 0xd1, 0x8b, 0xd1, 0x80, 0xd1, 0x83, 0xd0, 0xb1, 0xd0, 0xbb, 0xd0, + 0xb5, 0xd0, 0xb9, 0xd0, 0x9c, 0xd0, 0xbe, 0xd1, 0x81, 0xd0, 0xba, 0xd0, 0xb2, + 0xd0, 0xb0, 0xd1, 0x81, 0xd1, 0x82, 0xd1, 0x80, 0xd0, 0xb0, 0xd0, 0xbd, 0xd1, + 0x8b, 0xd0, 0xbd, 0xd0, 0xb8, 0xd1, 0x87, 0xd0, 0xb5, 0xd0, 0xb3, 0xd0, 0xbe, + 0xd1, 0x80, 0xd0, 0xb0, 0xd0, 0xb1, 0xd0, 0xbe, 0xd1, 0x82, 0xd0, 0xb5, 0xd0, + 0xb4, 0xd0, 0xbe, 0xd0, 0xbb, 0xd0, 0xb6, 0xd0, 0xb5, 0xd0, 0xbd, 0xd1, 0x83, + 0xd1, 0x81, 0xd0, 0xbb, 0xd1, 0x83, 0xd0, 0xb3, 0xd0, 0xb8, 0xd1, 0x82, 0xd0, + 0xb5, 0xd0, 0xbf, 0xd0, 0xb5, 0xd1, 0x80, 0xd1, 0x8c, 0xd0, 0x9e, 0xd0, 0xb4, + 0xd0, 0xbd, 0xd0, 0xb0, 0xd0, 0xba, 0xd0, 0xbe, 0xd0, 0xbf, 0xd0, 0xbe, 0xd1, + 0x82, 0xd0, 0xbe, 0xd0, 0xbc, 0xd1, 0x83, 0xd1, 0x80, 0xd0, 0xb0, 0xd0, 0xb1, + 0xd0, 0xbe, 0xd1, 0x82, 0xd1, 0x83, 0xd0, 0xb0, 0xd0, 0xbf, 0xd1, 0x80, 0xd0, + 0xb5, 0xd0, 0xbb, 0xd1, 0x8f, 0xd0, 0xb2, 0xd0, 0xbe, 0xd0, 0xbe, 0xd0, 0xb1, + 0xd1, 0x89, 0xd0, 0xb5, 0xd0, 0xbe, 0xd0, 0xb4, 0xd0, 0xbd, 0xd0, 0xbe, 0xd0, + 0xb3, 0xd0, 0xbe, 0xd1, 0x81, 0xd0, 0xb2, 0xd0, 0xbe, 0xd0, 0xb5, 0xd0, 0xb3, + 0xd0, 0xbe, 0xd1, 0x81, 0xd1, 0x82, 0xd0, 0xb0, 0xd1, 0x82, 0xd1, 0x8c, 0xd0, + 0xb8, 0xd0, 0xb4, 0xd1, 0x80, 0xd1, 0x83, 0xd0, 0xb3, 0xd0, 0xbe, 0xd0, 0xb9, + 0xd1, 0x84, 0xd0, 0xbe, 0xd1, 0x80, 0xd1, 0x83, 0xd0, 0xbc, 0xd0, 0xb5, 0xd1, + 0x85, 0xd0, 0xbe, 0xd1, 0x80, 0xd0, 0xbe, 0xd1, 0x88, 0xd0, 0xbe, 0xd0, 0xbf, + 0xd1, 0x80, 0xd0, 0xbe, 0xd1, 0x82, 0xd0, 0xb8, 0xd0, 0xb2, 0xd1, 0x81, 0xd1, + 0x81, 0xd1, 0x8b, 0xd0, 0xbb, 0xd0, 0xba, 0xd0, 0xb0, 0xd0, 0xba, 0xd0, 0xb0, + 0xd0, 0xb6, 0xd0, 0xb4, 0xd1, 0x8b, 0xd0, 0xb9, 0xd0, 0xb2, 0xd0, 0xbb, 0xd0, + 0xb0, 0xd1, 0x81, 0xd1, 0x82, 0xd0, 0xb8, 0xd0, 0xb3, 0xd1, 0x80, 0xd1, 0x83, + 0xd0, 0xbf, 0xd0, 0xbf, 0xd1, 0x8b, 0xd0, 0xb2, 0xd0, 0xbc, 0xd0, 0xb5, 0xd1, + 0x81, 0xd1, 0x82, 0xd0, 0xb5, 0xd1, 0x80, 0xd0, 0xb0, 0xd0, 0xb1, 0xd0, 0xbe, + 0xd1, 0x82, 0xd0, 0xb0, 0xd1, 0x81, 0xd0, 0xba, 0xd0, 0xb0, 0xd0, 0xb7, 0xd0, + 0xb0, 0xd0, 0xbb, 0xd0, 0xbf, 0xd0, 0xb5, 0xd1, 0x80, 0xd0, 0xb2, 0xd1, 0x8b, + 0xd0, 0xb9, 0xd0, 0xb4, 0xd0, 0xb5, 0xd0, 0xbb, 0xd0, 0xb0, 0xd1, 0x82, 0xd1, + 0x8c, 0xd0, 0xb4, 0xd0, 0xb5, 0xd0, 0xbd, 0xd1, 0x8c, 0xd0, 0xb3, 0xd0, 0xb8, + 0xd0, 0xbf, 0xd0, 0xb5, 0xd1, 0x80, 0xd0, 0xb8, 0xd0, 0xbe, 0xd0, 0xb4, 0xd0, + 0xb1, 0xd0, 0xb8, 0xd0, 0xb7, 0xd0, 0xbd, 0xd0, 0xb5, 0xd1, 0x81, 0xd0, 0xbe, + 0xd1, 0x81, 0xd0, 0xbd, 0xd0, 0xbe, 0xd0, 0xb2, 0xd0, 0xb5, 0xd0, 0xbc, 0xd0, + 0xbe, 0xd0, 0xbc, 0xd0, 0xb5, 0xd0, 0xbd, 0xd1, 0x82, 0xd0, 0xba, 0xd1, 0x83, + 0xd0, 0xbf, 0xd0, 0xb8, 0xd1, 0x82, 0xd1, 0x8c, 0xd0, 0xb4, 0xd0, 0xbe, 0xd0, + 0xbb, 0xd0, 0xb6, 0xd0, 0xbd, 0xd0, 0xb0, 0xd1, 0x80, 0xd0, 0xb0, 0xd0, 0xbc, + 0xd0, 0xba, 0xd0, 0xb0, 0xd1, 0x85, 0xd0, 0xbd, 0xd0, 0xb0, 0xd1, 0x87, 0xd0, + 0xb0, 0xd0, 0xbb, 0xd0, 0xbe, 0xd0, 0xa0, 0xd0, 0xb0, 0xd0, 0xb1, 0xd0, 0xbe, + 0xd1, 0x82, 0xd0, 0xb0, 0xd0, 0xa2, 0xd0, 0xbe, 0xd0, 0xbb, 0xd1, 0x8c, 0xd0, + 0xba, 0xd0, 0xbe, 0xd1, 0x81, 0xd0, 0xbe, 0xd0, 0xb2, 0xd1, 0x81, 0xd0, 0xb5, + 0xd0, 0xbc, 0xd0, 0xb2, 0xd1, 0x82, 0xd0, 0xbe, 0xd1, 0x80, 0xd0, 0xbe, 0xd0, + 0xb9, 0xd0, 0xbd, 0xd0, 0xb0, 0xd1, 0x87, 0xd0, 0xb0, 0xd0, 0xbb, 0xd0, 0xb0, + 0xd1, 0x81, 0xd0, 0xbf, 0xd0, 0xb8, 0xd1, 0x81, 0xd0, 0xbe, 0xd0, 0xba, 0xd1, + 0x81, 0xd0, 0xbb, 0xd1, 0x83, 0xd0, 0xb6, 0xd0, 0xb1, 0xd1, 0x8b, 0xd1, 0x81, + 0xd0, 0xb8, 0xd1, 0x81, 0xd1, 0x82, 0xd0, 0xb5, 0xd0, 0xbc, 0xd0, 0xbf, 0xd0, + 0xb5, 0xd1, 0x87, 0xd0, 0xb0, 0xd1, 0x82, 0xd0, 0xb8, 0xd0, 0xbd, 0xd0, 0xbe, + 0xd0, 0xb2, 0xd0, 0xbe, 0xd0, 0xb3, 0xd0, 0xbe, 0xd0, 0xbf, 0xd0, 0xbe, 0xd0, + 0xbc, 0xd0, 0xbe, 0xd1, 0x89, 0xd0, 0xb8, 0xd1, 0x81, 0xd0, 0xb0, 0xd0, 0xb9, + 0xd1, 0x82, 0xd0, 0xbe, 0xd0, 0xb2, 0xd0, 0xbf, 0xd0, 0xbe, 0xd1, 0x87, 0xd0, + 0xb5, 0xd0, 0xbc, 0xd1, 0x83, 0xd0, 0xbf, 0xd0, 0xbe, 0xd0, 0xbc, 0xd0, 0xbe, + 0xd1, 0x89, 0xd1, 0x8c, 0xd0, 0xb4, 0xd0, 0xbe, 0xd0, 0xbb, 0xd0, 0xb6, 0xd0, + 0xbd, 0xd0, 0xbe, 0xd1, 0x81, 0xd1, 0x81, 0xd1, 0x8b, 0xd0, 0xbb, 0xd0, 0xba, + 0xd0, 0xb8, 0xd0, 0xb1, 0xd1, 0x8b, 0xd1, 0x81, 0xd1, 0x82, 0xd1, 0x80, 0xd0, + 0xbe, 0xd0, 0xb4, 0xd0, 0xb0, 0xd0, 0xbd, 0xd0, 0xbd, 0xd1, 0x8b, 0xd0, 0xb5, + 0xd0, 0xbc, 0xd0, 0xbd, 0xd0, 0xbe, 0xd0, 0xb3, 0xd0, 0xb8, 0xd0, 0xb5, 0xd0, + 0xbf, 0xd1, 0x80, 0xd0, 0xbe, 0xd0, 0xb5, 0xd0, 0xba, 0xd1, 0x82, 0xd0, 0xa1, + 0xd0, 0xb5, 0xd0, 0xb9, 0xd1, 0x87, 0xd0, 0xb0, 0xd1, 0x81, 0xd0, 0xbc, 0xd0, + 0xbe, 0xd0, 0xb4, 0xd0, 0xb5, 0xd0, 0xbb, 0xd0, 0xb8, 0xd1, 0x82, 0xd0, 0xb0, + 0xd0, 0xba, 0xd0, 0xbe, 0xd0, 0xb3, 0xd0, 0xbe, 0xd0, 0xbe, 0xd0, 0xbd, 0xd0, + 0xbb, 0xd0, 0xb0, 0xd0, 0xb9, 0xd0, 0xbd, 0xd0, 0xb3, 0xd0, 0xbe, 0xd1, 0x80, + 0xd0, 0xbe, 0xd0, 0xb4, 0xd0, 0xb5, 0xd0, 0xb2, 0xd0, 0xb5, 0xd1, 0x80, 0xd1, + 0x81, 0xd0, 0xb8, 0xd1, 0x8f, 0xd1, 0x81, 0xd1, 0x82, 0xd1, 0x80, 0xd0, 0xb0, + 0xd0, 0xbd, 0xd0, 0xb5, 0xd1, 0x84, 0xd0, 0xb8, 0xd0, 0xbb, 0xd1, 0x8c, 0xd0, + 0xbc, 0xd1, 0x8b, 0xd1, 0x83, 0xd1, 0x80, 0xd0, 0xbe, 0xd0, 0xb2, 0xd0, 0xbd, + 0xd1, 0x8f, 0xd1, 0x80, 0xd0, 0xb0, 0xd0, 0xb7, 0xd0, 0xbd, 0xd1, 0x8b, 0xd1, + 0x85, 0xd0, 0xb8, 0xd1, 0x81, 0xd0, 0xba, 0xd0, 0xb0, 0xd1, 0x82, 0xd1, 0x8c, + 0xd0, 0xbd, 0xd0, 0xb5, 0xd0, 0xb4, 0xd0, 0xb5, 0xd0, 0xbb, 0xd1, 0x8e, 0xd1, + 0x8f, 0xd0, 0xbd, 0xd0, 0xb2, 0xd0, 0xb0, 0xd1, 0x80, 0xd1, 0x8f, 0xd0, 0xbc, + 0xd0, 0xb5, 0xd0, 0xbd, 0xd1, 0x8c, 0xd1, 0x88, 0xd0, 0xb5, 0xd0, 0xbc, 0xd0, + 0xbd, 0xd0, 0xbe, 0xd0, 0xb3, 0xd0, 0xb8, 0xd1, 0x85, 0xd0, 0xb4, 0xd0, 0xb0, + 0xd0, 0xbd, 0xd0, 0xbd, 0xd0, 0xbe, 0xd0, 0xb9, 0xd0, 0xb7, 0xd0, 0xbd, 0xd0, + 0xb0, 0xd1, 0x87, 0xd0, 0xb8, 0xd1, 0x82, 0xd0, 0xbd, 0xd0, 0xb5, 0xd0, 0xbb, + 0xd1, 0x8c, 0xd0, 0xb7, 0xd1, 0x8f, 0xd1, 0x84, 0xd0, 0xbe, 0xd1, 0x80, 0xd1, + 0x83, 0xd0, 0xbc, 0xd0, 0xb0, 0xd0, 0xa2, 0xd0, 0xb5, 0xd0, 0xbf, 0xd0, 0xb5, + 0xd1, 0x80, 0xd1, 0x8c, 0xd0, 0xbc, 0xd0, 0xb5, 0xd1, 0x81, 0xd1, 0x8f, 0xd1, + 0x86, 0xd0, 0xb0, 0xd0, 0xb7, 0xd0, 0xb0, 0xd1, 0x89, 0xd0, 0xb8, 0xd1, 0x82, + 0xd1, 0x8b, 0xd0, 0x9b, 0xd1, 0x83, 0xd1, 0x87, 0xd1, 0x88, 0xd0, 0xb8, 0xd0, + 0xb5, 0xe0, 0xa4, 0xa8, 0xe0, 0xa4, 0xb9, 0xe0, 0xa5, 0x80, 0xe0, 0xa4, 0x82, + 0xe0, 0xa4, 0x95, 0xe0, 0xa4, 0xb0, 0xe0, 0xa4, 0xa8, 0xe0, 0xa5, 0x87, 0xe0, + 0xa4, 0x85, 0xe0, 0xa4, 0xaa, 0xe0, 0xa4, 0xa8, 0xe0, 0xa5, 0x87, 0xe0, 0xa4, + 0x95, 0xe0, 0xa4, 0xbf, 0xe0, 0xa4, 0xaf, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, 0x95, + 0xe0, 0xa4, 0xb0, 0xe0, 0xa5, 0x87, 0xe0, 0xa4, 0x82, 0xe0, 0xa4, 0x85, 0xe0, + 0xa4, 0xa8, 0xe0, 0xa5, 0x8d, 0xe0, 0xa4, 0xaf, 0xe0, 0xa4, 0x95, 0xe0, 0xa5, + 0x8d, 0xe0, 0xa4, 0xaf, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, 0x97, 0xe0, 0xa4, 0xbe, + 0xe0, 0xa4, 0x87, 0xe0, 0xa4, 0xa1, 0xe0, 0xa4, 0xac, 0xe0, 0xa4, 0xbe, 0xe0, + 0xa4, 0xb0, 0xe0, 0xa5, 0x87, 0xe0, 0xa4, 0x95, 0xe0, 0xa4, 0xbf, 0xe0, 0xa4, + 0xb8, 0xe0, 0xa5, 0x80, 0xe0, 0xa4, 0xa6, 0xe0, 0xa4, 0xbf, 0xe0, 0xa4, 0xaf, + 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, 0xaa, 0xe0, 0xa4, 0xb9, 0xe0, 0xa4, 0xb2, 0xe0, + 0xa5, 0x87, 0xe0, 0xa4, 0xb8, 0xe0, 0xa4, 0xbf, 0xe0, 0xa4, 0x82, 0xe0, 0xa4, + 0xb9, 0xe0, 0xa4, 0xad, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, 0xb0, 0xe0, 0xa4, 0xa4, + 0xe0, 0xa4, 0x85, 0xe0, 0xa4, 0xaa, 0xe0, 0xa4, 0xa8, 0xe0, 0xa5, 0x80, 0xe0, + 0xa4, 0xb5, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, 0xb2, 0xe0, 0xa5, 0x87, 0xe0, 0xa4, + 0xb8, 0xe0, 0xa5, 0x87, 0xe0, 0xa4, 0xb5, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, 0x95, + 0xe0, 0xa4, 0xb0, 0xe0, 0xa4, 0xa4, 0xe0, 0xa5, 0x87, 0xe0, 0xa4, 0xae, 0xe0, + 0xa5, 0x87, 0xe0, 0xa4, 0xb0, 0xe0, 0xa5, 0x87, 0xe0, 0xa4, 0xb9, 0xe0, 0xa5, + 0x8b, 0xe0, 0xa4, 0xa8, 0xe0, 0xa5, 0x87, 0xe0, 0xa4, 0xb8, 0xe0, 0xa4, 0x95, + 0xe0, 0xa4, 0xa4, 0xe0, 0xa5, 0x87, 0xe0, 0xa4, 0xac, 0xe0, 0xa4, 0xb9, 0xe0, + 0xa5, 0x81, 0xe0, 0xa4, 0xa4, 0xe0, 0xa4, 0xb8, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, + 0x87, 0xe0, 0xa4, 0x9f, 0xe0, 0xa4, 0xb9, 0xe0, 0xa5, 0x8b, 0xe0, 0xa4, 0x97, + 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, 0x9c, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, 0xa8, 0xe0, + 0xa5, 0x87, 0xe0, 0xa4, 0xae, 0xe0, 0xa4, 0xbf, 0xe0, 0xa4, 0xa8, 0xe0, 0xa4, + 0x9f, 0xe0, 0xa4, 0x95, 0xe0, 0xa4, 0xb0, 0xe0, 0xa4, 0xa4, 0xe0, 0xa4, 0xbe, + 0xe0, 0xa4, 0x95, 0xe0, 0xa4, 0xb0, 0xe0, 0xa4, 0xa8, 0xe0, 0xa4, 0xbe, 0xe0, + 0xa4, 0x89, 0xe0, 0xa4, 0xa8, 0xe0, 0xa4, 0x95, 0xe0, 0xa5, 0x87, 0xe0, 0xa4, + 0xaf, 0xe0, 0xa4, 0xb9, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, 0x81, 0xe0, 0xa4, 0xb8, + 0xe0, 0xa4, 0xac, 0xe0, 0xa4, 0xb8, 0xe0, 0xa5, 0x87, 0xe0, 0xa4, 0xad, 0xe0, + 0xa4, 0xbe, 0xe0, 0xa4, 0xb7, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, 0x86, 0xe0, 0xa4, + 0xaa, 0xe0, 0xa4, 0x95, 0xe0, 0xa5, 0x87, 0xe0, 0xa4, 0xb2, 0xe0, 0xa4, 0xbf, + 0xe0, 0xa4, 0xaf, 0xe0, 0xa5, 0x87, 0xe0, 0xa4, 0xb6, 0xe0, 0xa5, 0x81, 0xe0, + 0xa4, 0xb0, 0xe0, 0xa5, 0x82, 0xe0, 0xa4, 0x87, 0xe0, 0xa4, 0xb8, 0xe0, 0xa4, + 0x95, 0xe0, 0xa5, 0x87, 0xe0, 0xa4, 0x98, 0xe0, 0xa4, 0x82, 0xe0, 0xa4, 0x9f, + 0xe0, 0xa5, 0x87, 0xe0, 0xa4, 0xae, 0xe0, 0xa5, 0x87, 0xe0, 0xa4, 0xb0, 0xe0, + 0xa5, 0x80, 0xe0, 0xa4, 0xb8, 0xe0, 0xa4, 0x95, 0xe0, 0xa4, 0xa4, 0xe0, 0xa4, + 0xbe, 0xe0, 0xa4, 0xae, 0xe0, 0xa5, 0x87, 0xe0, 0xa4, 0xb0, 0xe0, 0xa4, 0xbe, + 0xe0, 0xa4, 0xb2, 0xe0, 0xa5, 0x87, 0xe0, 0xa4, 0x95, 0xe0, 0xa4, 0xb0, 0xe0, + 0xa4, 0x85, 0xe0, 0xa4, 0xa7, 0xe0, 0xa4, 0xbf, 0xe0, 0xa4, 0x95, 0xe0, 0xa4, + 0x85, 0xe0, 0xa4, 0xaa, 0xe0, 0xa4, 0xa8, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, 0xb8, + 0xe0, 0xa4, 0xae, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, 0x9c, 0xe0, 0xa4, 0xae, 0xe0, + 0xa5, 0x81, 0xe0, 0xa4, 0x9d, 0xe0, 0xa5, 0x87, 0xe0, 0xa4, 0x95, 0xe0, 0xa4, + 0xbe, 0xe0, 0xa4, 0xb0, 0xe0, 0xa4, 0xa3, 0xe0, 0xa4, 0xb9, 0xe0, 0xa5, 0x8b, + 0xe0, 0xa4, 0xa4, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, 0x95, 0xe0, 0xa4, 0xa1, 0xe0, + 0xa4, 0xbc, 0xe0, 0xa5, 0x80, 0xe0, 0xa4, 0xaf, 0xe0, 0xa4, 0xb9, 0xe0, 0xa4, + 0xbe, 0xe0, 0xa4, 0x82, 0xe0, 0xa4, 0xb9, 0xe0, 0xa5, 0x8b, 0xe0, 0xa4, 0x9f, + 0xe0, 0xa4, 0xb2, 0xe0, 0xa4, 0xb6, 0xe0, 0xa4, 0xac, 0xe0, 0xa5, 0x8d, 0xe0, + 0xa4, 0xa6, 0xe0, 0xa4, 0xb2, 0xe0, 0xa4, 0xbf, 0xe0, 0xa4, 0xaf, 0xe0, 0xa4, + 0xbe, 0xe0, 0xa4, 0x9c, 0xe0, 0xa5, 0x80, 0xe0, 0xa4, 0xb5, 0xe0, 0xa4, 0xa8, + 0xe0, 0xa4, 0x9c, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, 0xa4, 0xe0, 0xa4, 0xbe, 0xe0, + 0xa4, 0x95, 0xe0, 0xa5, 0x88, 0xe0, 0xa4, 0xb8, 0xe0, 0xa5, 0x87, 0xe0, 0xa4, + 0x86, 0xe0, 0xa4, 0xaa, 0xe0, 0xa4, 0x95, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, 0xb5, + 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, 0xb2, 0xe0, 0xa5, 0x80, 0xe0, 0xa4, 0xa6, 0xe0, + 0xa5, 0x87, 0xe0, 0xa4, 0xa8, 0xe0, 0xa5, 0x87, 0xe0, 0xa4, 0xaa, 0xe0, 0xa5, + 0x82, 0xe0, 0xa4, 0xb0, 0xe0, 0xa5, 0x80, 0xe0, 0xa4, 0xaa, 0xe0, 0xa4, 0xbe, + 0xe0, 0xa4, 0xa8, 0xe0, 0xa5, 0x80, 0xe0, 0xa4, 0x89, 0xe0, 0xa4, 0xb8, 0xe0, + 0xa4, 0x95, 0xe0, 0xa5, 0x87, 0xe0, 0xa4, 0xb9, 0xe0, 0xa5, 0x8b, 0xe0, 0xa4, + 0x97, 0xe0, 0xa5, 0x80, 0xe0, 0xa4, 0xac, 0xe0, 0xa5, 0x88, 0xe0, 0xa4, 0xa0, + 0xe0, 0xa4, 0x95, 0xe0, 0xa4, 0x86, 0xe0, 0xa4, 0xaa, 0xe0, 0xa4, 0x95, 0xe0, + 0xa5, 0x80, 0xe0, 0xa4, 0xb5, 0xe0, 0xa4, 0xb0, 0xe0, 0xa5, 0x8d, 0xe0, 0xa4, + 0xb7, 0xe0, 0xa4, 0x97, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, 0x82, 0xe0, 0xa4, 0xb5, + 0xe0, 0xa4, 0x86, 0xe0, 0xa4, 0xaa, 0xe0, 0xa4, 0x95, 0xe0, 0xa5, 0x8b, 0xe0, + 0xa4, 0x9c, 0xe0, 0xa4, 0xbf, 0xe0, 0xa4, 0xb2, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, + 0x9c, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, 0xa8, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, 0xb8, + 0xe0, 0xa4, 0xb9, 0xe0, 0xa4, 0xae, 0xe0, 0xa4, 0xa4, 0xe0, 0xa4, 0xb9, 0xe0, + 0xa4, 0xae, 0xe0, 0xa5, 0x87, 0xe0, 0xa4, 0x82, 0xe0, 0xa4, 0x89, 0xe0, 0xa4, + 0xa8, 0xe0, 0xa4, 0x95, 0xe0, 0xa5, 0x80, 0xe0, 0xa4, 0xaf, 0xe0, 0xa4, 0xbe, + 0xe0, 0xa4, 0xb9, 0xe0, 0xa5, 0x82, 0xe0, 0xa4, 0xa6, 0xe0, 0xa4, 0xb0, 0xe0, + 0xa5, 0x8d, 0xe0, 0xa4, 0x9c, 0xe0, 0xa4, 0xb8, 0xe0, 0xa5, 0x82, 0xe0, 0xa4, + 0x9a, 0xe0, 0xa5, 0x80, 0xe0, 0xa4, 0xaa, 0xe0, 0xa4, 0xb8, 0xe0, 0xa4, 0x82, + 0xe0, 0xa4, 0xa6, 0xe0, 0xa4, 0xb8, 0xe0, 0xa4, 0xb5, 0xe0, 0xa4, 0xbe, 0xe0, + 0xa4, 0xb2, 0xe0, 0xa4, 0xb9, 0xe0, 0xa5, 0x8b, 0xe0, 0xa4, 0xa8, 0xe0, 0xa4, + 0xbe, 0xe0, 0xa4, 0xb9, 0xe0, 0xa5, 0x8b, 0xe0, 0xa4, 0xa4, 0xe0, 0xa5, 0x80, + 0xe0, 0xa4, 0x9c, 0xe0, 0xa5, 0x88, 0xe0, 0xa4, 0xb8, 0xe0, 0xa5, 0x87, 0xe0, + 0xa4, 0xb5, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, 0xaa, 0xe0, 0xa4, 0xb8, 0xe0, 0xa4, + 0x9c, 0xe0, 0xa4, 0xa8, 0xe0, 0xa4, 0xa4, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, 0xa8, + 0xe0, 0xa5, 0x87, 0xe0, 0xa4, 0xa4, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, 0x9c, 0xe0, + 0xa4, 0xbe, 0xe0, 0xa4, 0xb0, 0xe0, 0xa5, 0x80, 0xe0, 0xa4, 0x98, 0xe0, 0xa4, + 0xbe, 0xe0, 0xa4, 0xaf, 0xe0, 0xa4, 0xb2, 0xe0, 0xa4, 0x9c, 0xe0, 0xa4, 0xbf, + 0xe0, 0xa4, 0xb2, 0xe0, 0xa5, 0x87, 0xe0, 0xa4, 0xa8, 0xe0, 0xa5, 0x80, 0xe0, + 0xa4, 0x9a, 0xe0, 0xa5, 0x87, 0xe0, 0xa4, 0x9c, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, + 0x82, 0xe0, 0xa4, 0x9a, 0xe0, 0xa4, 0xaa, 0xe0, 0xa4, 0xa4, 0xe0, 0xa5, 0x8d, + 0xe0, 0xa4, 0xb0, 0xe0, 0xa4, 0x97, 0xe0, 0xa5, 0x82, 0xe0, 0xa4, 0x97, 0xe0, + 0xa4, 0xb2, 0xe0, 0xa4, 0x9c, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, 0xa4, 0xe0, 0xa5, + 0x87, 0xe0, 0xa4, 0xac, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, 0xb9, 0xe0, 0xa4, 0xb0, + 0xe0, 0xa4, 0x86, 0xe0, 0xa4, 0xaa, 0xe0, 0xa4, 0xa8, 0xe0, 0xa5, 0x87, 0xe0, + 0xa4, 0xb5, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, 0xb9, 0xe0, 0xa4, 0xa8, 0xe0, 0xa4, + 0x87, 0xe0, 0xa4, 0xb8, 0xe0, 0xa4, 0x95, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, 0xb8, + 0xe0, 0xa5, 0x81, 0xe0, 0xa4, 0xac, 0xe0, 0xa4, 0xb9, 0xe0, 0xa4, 0xb0, 0xe0, + 0xa4, 0xb9, 0xe0, 0xa4, 0xa8, 0xe0, 0xa5, 0x87, 0xe0, 0xa4, 0x87, 0xe0, 0xa4, + 0xb8, 0xe0, 0xa4, 0xb8, 0xe0, 0xa5, 0x87, 0xe0, 0xa4, 0xb8, 0xe0, 0xa4, 0xb9, + 0xe0, 0xa4, 0xbf, 0xe0, 0xa4, 0xa4, 0xe0, 0xa4, 0xac, 0xe0, 0xa4, 0xa1, 0xe0, + 0xa4, 0xbc, 0xe0, 0xa5, 0x87, 0xe0, 0xa4, 0x98, 0xe0, 0xa4, 0x9f, 0xe0, 0xa4, + 0xa8, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, 0xa4, 0xe0, 0xa4, 0xb2, 0xe0, 0xa4, 0xbe, + 0xe0, 0xa4, 0xb6, 0xe0, 0xa4, 0xaa, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, 0x82, 0xe0, + 0xa4, 0x9a, 0xe0, 0xa4, 0xb6, 0xe0, 0xa5, 0x8d, 0xe0, 0xa4, 0xb0, 0xe0, 0xa5, + 0x80, 0xe0, 0xa4, 0xac, 0xe0, 0xa4, 0xa1, 0xe0, 0xa4, 0xbc, 0xe0, 0xa5, 0x80, + 0xe0, 0xa4, 0xb9, 0xe0, 0xa5, 0x8b, 0xe0, 0xa4, 0xa4, 0xe0, 0xa5, 0x87, 0xe0, + 0xa4, 0xb8, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, 0x88, 0xe0, 0xa4, 0x9f, 0xe0, 0xa4, + 0xb6, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, 0xaf, 0xe0, 0xa4, 0xa6, 0xe0, 0xa4, 0xb8, + 0xe0, 0xa4, 0x95, 0xe0, 0xa4, 0xa4, 0xe0, 0xa5, 0x80, 0xe0, 0xa4, 0x9c, 0xe0, + 0xa4, 0xbe, 0xe0, 0xa4, 0xa4, 0xe0, 0xa5, 0x80, 0xe0, 0xa4, 0xb5, 0xe0, 0xa4, + 0xbe, 0xe0, 0xa4, 0xb2, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, 0xb9, 0xe0, 0xa4, 0x9c, + 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, 0xb0, 0xe0, 0xa4, 0xaa, 0xe0, 0xa4, 0x9f, 0xe0, + 0xa4, 0xa8, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, 0xb0, 0xe0, 0xa4, 0x96, 0xe0, 0xa4, + 0xa8, 0xe0, 0xa5, 0x87, 0xe0, 0xa4, 0xb8, 0xe0, 0xa4, 0xa1, 0xe0, 0xa4, 0xbc, + 0xe0, 0xa4, 0x95, 0xe0, 0xa4, 0xae, 0xe0, 0xa4, 0xbf, 0xe0, 0xa4, 0xb2, 0xe0, + 0xa4, 0xbe, 0xe0, 0xa4, 0x89, 0xe0, 0xa4, 0xb8, 0xe0, 0xa4, 0x95, 0xe0, 0xa5, + 0x80, 0xe0, 0xa4, 0x95, 0xe0, 0xa5, 0x87, 0xe0, 0xa4, 0xb5, 0xe0, 0xa4, 0xb2, + 0xe0, 0xa4, 0xb2, 0xe0, 0xa4, 0x97, 0xe0, 0xa4, 0xa4, 0xe0, 0xa4, 0xbe, 0xe0, + 0xa4, 0x96, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, 0xa8, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, + 0x85, 0xe0, 0xa4, 0xb0, 0xe0, 0xa5, 0x8d, 0xe0, 0xa4, 0xa5, 0xe0, 0xa4, 0x9c, + 0xe0, 0xa4, 0xb9, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, 0x82, 0xe0, 0xa4, 0xa6, 0xe0, + 0xa5, 0x87, 0xe0, 0xa4, 0x96, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, 0xaa, 0xe0, 0xa4, + 0xb9, 0xe0, 0xa4, 0xb2, 0xe0, 0xa5, 0x80, 0xe0, 0xa4, 0xa8, 0xe0, 0xa4, 0xbf, + 0xe0, 0xa4, 0xaf, 0xe0, 0xa4, 0xae, 0xe0, 0xa4, 0xac, 0xe0, 0xa4, 0xbf, 0xe0, + 0xa4, 0xa8, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, 0xac, 0xe0, 0xa5, 0x88, 0xe0, 0xa4, + 0x82, 0xe0, 0xa4, 0x95, 0xe0, 0xa4, 0x95, 0xe0, 0xa4, 0xb9, 0xe0, 0xa5, 0x80, + 0xe0, 0xa4, 0x82, 0xe0, 0xa4, 0x95, 0xe0, 0xa4, 0xb9, 0xe0, 0xa4, 0xa8, 0xe0, + 0xa4, 0xbe, 0xe0, 0xa4, 0xa6, 0xe0, 0xa5, 0x87, 0xe0, 0xa4, 0xa4, 0xe0, 0xa4, + 0xbe, 0xe0, 0xa4, 0xb9, 0xe0, 0xa4, 0xae, 0xe0, 0xa4, 0xb2, 0xe0, 0xa5, 0x87, + 0xe0, 0xa4, 0x95, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, 0xab, 0xe0, 0xa5, 0x80, 0xe0, + 0xa4, 0x9c, 0xe0, 0xa4, 0xac, 0xe0, 0xa4, 0x95, 0xe0, 0xa4, 0xbf, 0xe0, 0xa4, + 0xa4, 0xe0, 0xa5, 0x81, 0xe0, 0xa4, 0xb0, 0xe0, 0xa4, 0xa4, 0xe0, 0xa4, 0xae, + 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, 0x82, 0xe0, 0xa4, 0x97, 0xe0, 0xa4, 0xb5, 0xe0, + 0xa4, 0xb9, 0xe0, 0xa5, 0x80, 0xe0, 0xa4, 0x82, 0xe0, 0xa4, 0xb0, 0xe0, 0xa5, + 0x8b, 0xe0, 0xa4, 0x9c, 0xe0, 0xa4, 0xbc, 0xe0, 0xa4, 0xae, 0xe0, 0xa4, 0xbf, + 0xe0, 0xa4, 0xb2, 0xe0, 0xa5, 0x80, 0xe0, 0xa4, 0x86, 0xe0, 0xa4, 0xb0, 0xe0, + 0xa5, 0x8b, 0xe0, 0xa4, 0xaa, 0xe0, 0xa4, 0xb8, 0xe0, 0xa5, 0x87, 0xe0, 0xa4, + 0xa8, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, 0xaf, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, 0xa6, + 0xe0, 0xa4, 0xb5, 0xe0, 0xa4, 0xb2, 0xe0, 0xa5, 0x87, 0xe0, 0xa4, 0xa8, 0xe0, + 0xa5, 0x87, 0xe0, 0xa4, 0x96, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, 0xa4, 0xe0, 0xa4, + 0xbe, 0xe0, 0xa4, 0x95, 0xe0, 0xa4, 0xb0, 0xe0, 0xa5, 0x80, 0xe0, 0xa4, 0xac, + 0xe0, 0xa4, 0x89, 0xe0, 0xa4, 0xa8, 0xe0, 0xa4, 0x95, 0xe0, 0xa4, 0xbe, 0xe0, + 0xa4, 0x9c, 0xe0, 0xa4, 0xb5, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, 0xac, 0xe0, 0xa4, + 0xaa, 0xe0, 0xa5, 0x82, 0xe0, 0xa4, 0xb0, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, 0xac, + 0xe0, 0xa4, 0xa1, 0xe0, 0xa4, 0xbc, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, 0xb8, 0xe0, + 0xa5, 0x8c, 0xe0, 0xa4, 0xa6, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, 0xb6, 0xe0, 0xa5, + 0x87, 0xe0, 0xa4, 0xaf, 0xe0, 0xa4, 0xb0, 0xe0, 0xa4, 0x95, 0xe0, 0xa4, 0xbf, + 0xe0, 0xa4, 0xaf, 0xe0, 0xa5, 0x87, 0xe0, 0xa4, 0x95, 0xe0, 0xa4, 0xb9, 0xe0, + 0xa4, 0xbe, 0xe0, 0xa4, 0x82, 0xe0, 0xa4, 0x85, 0xe0, 0xa4, 0x95, 0xe0, 0xa4, + 0xb8, 0xe0, 0xa4, 0xb0, 0xe0, 0xa4, 0xac, 0xe0, 0xa4, 0xa8, 0xe0, 0xa4, 0xbe, + 0xe0, 0xa4, 0x8f, 0xe0, 0xa4, 0xb5, 0xe0, 0xa4, 0xb9, 0xe0, 0xa4, 0xbe, 0xe0, + 0xa4, 0x82, 0xe0, 0xa4, 0xb8, 0xe0, 0xa5, 0x8d, 0xe0, 0xa4, 0xa5, 0xe0, 0xa4, + 0xb2, 0xe0, 0xa4, 0xae, 0xe0, 0xa4, 0xbf, 0xe0, 0xa4, 0xb2, 0xe0, 0xa5, 0x87, + 0xe0, 0xa4, 0xb2, 0xe0, 0xa5, 0x87, 0xe0, 0xa4, 0x96, 0xe0, 0xa4, 0x95, 0xe0, + 0xa4, 0xb5, 0xe0, 0xa4, 0xbf, 0xe0, 0xa4, 0xb7, 0xe0, 0xa4, 0xaf, 0xe0, 0xa4, + 0x95, 0xe0, 0xa5, 0x8d, 0xe0, 0xa4, 0xb0, 0xe0, 0xa4, 0x82, 0xe0, 0xa4, 0xb8, + 0xe0, 0xa4, 0xae, 0xe0, 0xa5, 0x82, 0xe0, 0xa4, 0xb9, 0xe0, 0xa4, 0xa5, 0xe0, + 0xa4, 0xbe, 0xe0, 0xa4, 0xa8, 0xe0, 0xa4, 0xbe, 0xd8, 0xaa, 0xd8, 0xb3, 0xd8, + 0xaa, 0xd8, 0xb7, 0xd9, 0x8a, 0xd8, 0xb9, 0xd9, 0x85, 0xd8, 0xb4, 0xd8, 0xa7, + 0xd8, 0xb1, 0xd9, 0x83, 0xd8, 0xa9, 0xd8, 0xa8, 0xd9, 0x88, 0xd8, 0xa7, 0xd8, + 0xb3, 0xd8, 0xb7, 0xd8, 0xa9, 0xd8, 0xa7, 0xd9, 0x84, 0xd8, 0xb5, 0xd9, 0x81, + 0xd8, 0xad, 0xd8, 0xa9, 0xd9, 0x85, 0xd9, 0x88, 0xd8, 0xa7, 0xd8, 0xb6, 0xd9, + 0x8a, 0xd8, 0xb9, 0xd8, 0xa7, 0xd9, 0x84, 0xd8, 0xae, 0xd8, 0xa7, 0xd8, 0xb5, + 0xd8, 0xa9, 0xd8, 0xa7, 0xd9, 0x84, 0xd9, 0x85, 0xd8, 0xb2, 0xd9, 0x8a, 0xd8, + 0xaf, 0xd8, 0xa7, 0xd9, 0x84, 0xd8, 0xb9, 0xd8, 0xa7, 0xd9, 0x85, 0xd8, 0xa9, + 0xd8, 0xa7, 0xd9, 0x84, 0xd9, 0x83, 0xd8, 0xa7, 0xd8, 0xaa, 0xd8, 0xa8, 0xd8, + 0xa7, 0xd9, 0x84, 0xd8, 0xb1, 0xd8, 0xaf, 0xd9, 0x88, 0xd8, 0xaf, 0xd8, 0xa8, + 0xd8, 0xb1, 0xd9, 0x86, 0xd8, 0xa7, 0xd9, 0x85, 0xd8, 0xac, 0xd8, 0xa7, 0xd9, + 0x84, 0xd8, 0xaf, 0xd9, 0x88, 0xd9, 0x84, 0xd8, 0xa9, 0xd8, 0xa7, 0xd9, 0x84, + 0xd8, 0xb9, 0xd8, 0xa7, 0xd9, 0x84, 0xd9, 0x85, 0xd8, 0xa7, 0xd9, 0x84, 0xd9, + 0x85, 0xd9, 0x88, 0xd9, 0x82, 0xd8, 0xb9, 0xd8, 0xa7, 0xd9, 0x84, 0xd8, 0xb9, + 0xd8, 0xb1, 0xd8, 0xa8, 0xd9, 0x8a, 0xd8, 0xa7, 0xd9, 0x84, 0xd8, 0xb3, 0xd8, + 0xb1, 0xd9, 0x8a, 0xd8, 0xb9, 0xd8, 0xa7, 0xd9, 0x84, 0xd8, 0xac, 0xd9, 0x88, + 0xd8, 0xa7, 0xd9, 0x84, 0xd8, 0xa7, 0xd9, 0x84, 0xd8, 0xb0, 0xd9, 0x87, 0xd8, + 0xa7, 0xd8, 0xa8, 0xd8, 0xa7, 0xd9, 0x84, 0xd8, 0xad, 0xd9, 0x8a, 0xd8, 0xa7, + 0xd8, 0xa9, 0xd8, 0xa7, 0xd9, 0x84, 0xd8, 0xad, 0xd9, 0x82, 0xd9, 0x88, 0xd9, + 0x82, 0xd8, 0xa7, 0xd9, 0x84, 0xd9, 0x83, 0xd8, 0xb1, 0xd9, 0x8a, 0xd9, 0x85, + 0xd8, 0xa7, 0xd9, 0x84, 0xd8, 0xb9, 0xd8, 0xb1, 0xd8, 0xa7, 0xd9, 0x82, 0xd9, + 0x85, 0xd8, 0xad, 0xd9, 0x81, 0xd9, 0x88, 0xd8, 0xb8, 0xd8, 0xa9, 0xd8, 0xa7, + 0xd9, 0x84, 0xd8, 0xab, 0xd8, 0xa7, 0xd9, 0x86, 0xd9, 0x8a, 0xd9, 0x85, 0xd8, + 0xb4, 0xd8, 0xa7, 0xd9, 0x87, 0xd8, 0xaf, 0xd8, 0xa9, 0xd8, 0xa7, 0xd9, 0x84, + 0xd9, 0x85, 0xd8, 0xb1, 0xd8, 0xa3, 0xd8, 0xa9, 0xd8, 0xa7, 0xd9, 0x84, 0xd9, + 0x82, 0xd8, 0xb1, 0xd8, 0xa2, 0xd9, 0x86, 0xd8, 0xa7, 0xd9, 0x84, 0xd8, 0xb4, + 0xd8, 0xa8, 0xd8, 0xa7, 0xd8, 0xa8, 0xd8, 0xa7, 0xd9, 0x84, 0xd8, 0xad, 0xd9, + 0x88, 0xd8, 0xa7, 0xd8, 0xb1, 0xd8, 0xa7, 0xd9, 0x84, 0xd8, 0xac, 0xd8, 0xaf, + 0xd9, 0x8a, 0xd8, 0xaf, 0xd8, 0xa7, 0xd9, 0x84, 0xd8, 0xa3, 0xd8, 0xb3, 0xd8, + 0xb1, 0xd8, 0xa9, 0xd8, 0xa7, 0xd9, 0x84, 0xd8, 0xb9, 0xd9, 0x84, 0xd9, 0x88, + 0xd9, 0x85, 0xd9, 0x85, 0xd8, 0xac, 0xd9, 0x85, 0xd9, 0x88, 0xd8, 0xb9, 0xd8, + 0xa9, 0xd8, 0xa7, 0xd9, 0x84, 0xd8, 0xb1, 0xd8, 0xad, 0xd9, 0x85, 0xd9, 0x86, + 0xd8, 0xa7, 0xd9, 0x84, 0xd9, 0x86, 0xd9, 0x82, 0xd8, 0xa7, 0xd8, 0xb7, 0xd9, + 0x81, 0xd9, 0x84, 0xd8, 0xb3, 0xd8, 0xb7, 0xd9, 0x8a, 0xd9, 0x86, 0xd8, 0xa7, + 0xd9, 0x84, 0xd9, 0x83, 0xd9, 0x88, 0xd9, 0x8a, 0xd8, 0xaa, 0xd8, 0xa7, 0xd9, + 0x84, 0xd8, 0xaf, 0xd9, 0x86, 0xd9, 0x8a, 0xd8, 0xa7, 0xd8, 0xa8, 0xd8, 0xb1, + 0xd9, 0x83, 0xd8, 0xa7, 0xd8, 0xaa, 0xd9, 0x87, 0xd8, 0xa7, 0xd9, 0x84, 0xd8, + 0xb1, 0xd9, 0x8a, 0xd8, 0xa7, 0xd8, 0xb6, 0xd8, 0xaa, 0xd8, 0xad, 0xd9, 0x8a, + 0xd8, 0xa7, 0xd8, 0xaa, 0xd9, 0x8a, 0xd8, 0xa8, 0xd8, 0xaa, 0xd9, 0x88, 0xd9, + 0x82, 0xd9, 0x8a, 0xd8, 0xaa, 0xd8, 0xa7, 0xd9, 0x84, 0xd8, 0xa3, 0xd9, 0x88, + 0xd9, 0x84, 0xd9, 0x89, 0xd8, 0xa7, 0xd9, 0x84, 0xd8, 0xa8, 0xd8, 0xb1, 0xd9, + 0x8a, 0xd8, 0xaf, 0xd8, 0xa7, 0xd9, 0x84, 0xd9, 0x83, 0xd9, 0x84, 0xd8, 0xa7, + 0xd9, 0x85, 0xd8, 0xa7, 0xd9, 0x84, 0xd8, 0xb1, 0xd8, 0xa7, 0xd8, 0xa8, 0xd8, + 0xb7, 0xd8, 0xa7, 0xd9, 0x84, 0xd8, 0xb4, 0xd8, 0xae, 0xd8, 0xb5, 0xd9, 0x8a, + 0xd8, 0xb3, 0xd9, 0x8a, 0xd8, 0xa7, 0xd8, 0xb1, 0xd8, 0xa7, 0xd8, 0xaa, 0xd8, + 0xa7, 0xd9, 0x84, 0xd8, 0xab, 0xd8, 0xa7, 0xd9, 0x84, 0xd8, 0xab, 0xd8, 0xa7, + 0xd9, 0x84, 0xd8, 0xb5, 0xd9, 0x84, 0xd8, 0xa7, 0xd8, 0xa9, 0xd8, 0xa7, 0xd9, + 0x84, 0xd8, 0xad, 0xd8, 0xaf, 0xd9, 0x8a, 0xd8, 0xab, 0xd8, 0xa7, 0xd9, 0x84, + 0xd8, 0xb2, 0xd9, 0x88, 0xd8, 0xa7, 0xd8, 0xb1, 0xd8, 0xa7, 0xd9, 0x84, 0xd8, + 0xae, 0xd9, 0x84, 0xd9, 0x8a, 0xd8, 0xac, 0xd8, 0xa7, 0xd9, 0x84, 0xd8, 0xac, + 0xd9, 0x85, 0xd9, 0x8a, 0xd8, 0xb9, 0xd8, 0xa7, 0xd9, 0x84, 0xd8, 0xb9, 0xd8, + 0xa7, 0xd9, 0x85, 0xd9, 0x87, 0xd8, 0xa7, 0xd9, 0x84, 0xd8, 0xac, 0xd9, 0x85, + 0xd8, 0xa7, 0xd9, 0x84, 0xd8, 0xa7, 0xd9, 0x84, 0xd8, 0xb3, 0xd8, 0xa7, 0xd8, + 0xb9, 0xd8, 0xa9, 0xd9, 0x85, 0xd8, 0xb4, 0xd8, 0xa7, 0xd9, 0x87, 0xd8, 0xaf, + 0xd9, 0x87, 0xd8, 0xa7, 0xd9, 0x84, 0xd8, 0xb1, 0xd8, 0xa6, 0xd9, 0x8a, 0xd8, + 0xb3, 0xd8, 0xa7, 0xd9, 0x84, 0xd8, 0xaf, 0xd8, 0xae, 0xd9, 0x88, 0xd9, 0x84, + 0xd8, 0xa7, 0xd9, 0x84, 0xd9, 0x81, 0xd9, 0x86, 0xd9, 0x8a, 0xd8, 0xa9, 0xd8, + 0xa7, 0xd9, 0x84, 0xd9, 0x83, 0xd8, 0xaa, 0xd8, 0xa7, 0xd8, 0xa8, 0xd8, 0xa7, + 0xd9, 0x84, 0xd8, 0xaf, 0xd9, 0x88, 0xd8, 0xb1, 0xd9, 0x8a, 0xd8, 0xa7, 0xd9, + 0x84, 0xd8, 0xaf, 0xd8, 0xb1, 0xd9, 0x88, 0xd8, 0xb3, 0xd8, 0xa7, 0xd8, 0xb3, + 0xd8, 0xaa, 0xd8, 0xba, 0xd8, 0xb1, 0xd9, 0x82, 0xd8, 0xaa, 0xd8, 0xb5, 0xd8, + 0xa7, 0xd9, 0x85, 0xd9, 0x8a, 0xd9, 0x85, 0xd8, 0xa7, 0xd9, 0x84, 0xd8, 0xa8, + 0xd9, 0x86, 0xd8, 0xa7, 0xd8, 0xaa, 0xd8, 0xa7, 0xd9, 0x84, 0xd8, 0xb9, 0xd8, + 0xb8, 0xd9, 0x8a, 0xd9, 0x85, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x74, 0x61, 0x69, + 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x75, 0x6e, 0x64, 0x65, 0x72, 0x73, 0x74, 0x61, + 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x20, 0x3d, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x28, 0x29, 0x2e, 0x6a, 0x70, 0x67, 0x22, 0x20, 0x77, 0x69, + 0x64, 0x74, 0x68, 0x3d, 0x22, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x70, 0x6e, 0x67, 0x22, 0x20, 0x77, 0x69, + 0x64, 0x74, 0x68, 0x3d, 0x22, 0x3c, 0x62, 0x6f, 0x64, 0x79, 0x20, 0x63, 0x6c, + 0x61, 0x73, 0x73, 0x3d, 0x22, 0x4d, 0x61, 0x74, 0x68, 0x2e, 0x72, 0x61, 0x6e, + 0x64, 0x6f, 0x6d, 0x28, 0x29, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6d, 0x70, 0x6f, + 0x72, 0x61, 0x72, 0x79, 0x20, 0x55, 0x6e, 0x69, 0x74, 0x65, 0x64, 0x20, 0x53, + 0x74, 0x61, 0x74, 0x65, 0x73, 0x63, 0x69, 0x72, 0x63, 0x75, 0x6d, 0x73, 0x74, + 0x61, 0x6e, 0x63, 0x65, 0x73, 0x2e, 0x61, 0x70, 0x70, 0x65, 0x6e, 0x64, 0x43, + 0x68, 0x69, 0x6c, 0x64, 0x28, 0x6f, 0x72, 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x3c, 0x73, 0x70, 0x61, 0x6e, 0x20, 0x63, 0x6c, + 0x61, 0x73, 0x73, 0x3d, 0x22, 0x22, 0x3e, 0x3c, 0x69, 0x6d, 0x67, 0x20, 0x73, + 0x72, 0x63, 0x3d, 0x22, 0x2f, 0x64, 0x69, 0x73, 0x74, 0x69, 0x6e, 0x67, 0x75, + 0x69, 0x73, 0x68, 0x65, 0x64, 0x74, 0x68, 0x6f, 0x75, 0x73, 0x61, 0x6e, 0x64, + 0x73, 0x20, 0x6f, 0x66, 0x20, 0x63, 0x6f, 0x6d, 0x6d, 0x75, 0x6e, 0x69, 0x63, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x63, 0x6c, 0x65, 0x61, 0x72, 0x22, 0x3e, 0x3c, + 0x2f, 0x64, 0x69, 0x76, 0x3e, 0x69, 0x6e, 0x76, 0x65, 0x73, 0x74, 0x69, 0x67, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x66, 0x61, 0x76, 0x69, 0x63, 0x6f, 0x6e, 0x2e, + 0x69, 0x63, 0x6f, 0x22, 0x20, 0x6d, 0x61, 0x72, 0x67, 0x69, 0x6e, 0x2d, 0x72, + 0x69, 0x67, 0x68, 0x74, 0x3a, 0x62, 0x61, 0x73, 0x65, 0x64, 0x20, 0x6f, 0x6e, + 0x20, 0x74, 0x68, 0x65, 0x20, 0x4d, 0x61, 0x73, 0x73, 0x61, 0x63, 0x68, 0x75, + 0x73, 0x65, 0x74, 0x74, 0x73, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x20, 0x62, 0x6f, + 0x72, 0x64, 0x65, 0x72, 0x3d, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x61, 0x6c, 0x73, 0x6f, 0x20, 0x6b, 0x6e, 0x6f, + 0x77, 0x6e, 0x20, 0x61, 0x73, 0x70, 0x72, 0x6f, 0x6e, 0x75, 0x6e, 0x63, 0x69, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x62, 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, + 0x6e, 0x64, 0x3a, 0x23, 0x66, 0x70, 0x61, 0x64, 0x64, 0x69, 0x6e, 0x67, 0x2d, + 0x6c, 0x65, 0x66, 0x74, 0x3a, 0x46, 0x6f, 0x72, 0x20, 0x65, 0x78, 0x61, 0x6d, + 0x70, 0x6c, 0x65, 0x2c, 0x20, 0x6d, 0x69, 0x73, 0x63, 0x65, 0x6c, 0x6c, 0x61, + 0x6e, 0x65, 0x6f, 0x75, 0x73, 0x26, 0x6c, 0x74, 0x3b, 0x2f, 0x6d, 0x61, 0x74, + 0x68, 0x26, 0x67, 0x74, 0x3b, 0x70, 0x73, 0x79, 0x63, 0x68, 0x6f, 0x6c, 0x6f, + 0x67, 0x69, 0x63, 0x61, 0x6c, 0x69, 0x6e, 0x20, 0x70, 0x61, 0x72, 0x74, 0x69, + 0x63, 0x75, 0x6c, 0x61, 0x72, 0x65, 0x61, 0x72, 0x63, 0x68, 0x22, 0x20, 0x74, + 0x79, 0x70, 0x65, 0x3d, 0x22, 0x66, 0x6f, 0x72, 0x6d, 0x20, 0x6d, 0x65, 0x74, + 0x68, 0x6f, 0x64, 0x3d, 0x22, 0x61, 0x73, 0x20, 0x6f, 0x70, 0x70, 0x6f, 0x73, + 0x65, 0x64, 0x20, 0x74, 0x6f, 0x53, 0x75, 0x70, 0x72, 0x65, 0x6d, 0x65, 0x20, + 0x43, 0x6f, 0x75, 0x72, 0x74, 0x6f, 0x63, 0x63, 0x61, 0x73, 0x69, 0x6f, 0x6e, + 0x61, 0x6c, 0x6c, 0x79, 0x20, 0x41, 0x64, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, + 0x61, 0x6c, 0x6c, 0x79, 0x2c, 0x4e, 0x6f, 0x72, 0x74, 0x68, 0x20, 0x41, 0x6d, + 0x65, 0x72, 0x69, 0x63, 0x61, 0x70, 0x78, 0x3b, 0x62, 0x61, 0x63, 0x6b, 0x67, + 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x6f, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x75, 0x6e, + 0x69, 0x74, 0x69, 0x65, 0x73, 0x45, 0x6e, 0x74, 0x65, 0x72, 0x74, 0x61, 0x69, + 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x74, 0x6f, 0x4c, 0x6f, 0x77, 0x65, 0x72, + 0x43, 0x61, 0x73, 0x65, 0x28, 0x6d, 0x61, 0x6e, 0x75, 0x66, 0x61, 0x63, 0x74, + 0x75, 0x72, 0x69, 0x6e, 0x67, 0x70, 0x72, 0x6f, 0x66, 0x65, 0x73, 0x73, 0x69, + 0x6f, 0x6e, 0x61, 0x6c, 0x20, 0x63, 0x6f, 0x6d, 0x62, 0x69, 0x6e, 0x65, 0x64, + 0x20, 0x77, 0x69, 0x74, 0x68, 0x46, 0x6f, 0x72, 0x20, 0x69, 0x6e, 0x73, 0x74, + 0x61, 0x6e, 0x63, 0x65, 0x2c, 0x63, 0x6f, 0x6e, 0x73, 0x69, 0x73, 0x74, 0x69, + 0x6e, 0x67, 0x20, 0x6f, 0x66, 0x22, 0x20, 0x6d, 0x61, 0x78, 0x6c, 0x65, 0x6e, + 0x67, 0x74, 0x68, 0x3d, 0x22, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x66, + 0x61, 0x6c, 0x73, 0x65, 0x3b, 0x63, 0x6f, 0x6e, 0x73, 0x63, 0x69, 0x6f, 0x75, + 0x73, 0x6e, 0x65, 0x73, 0x73, 0x4d, 0x65, 0x64, 0x69, 0x74, 0x65, 0x72, 0x72, + 0x61, 0x6e, 0x65, 0x61, 0x6e, 0x65, 0x78, 0x74, 0x72, 0x61, 0x6f, 0x72, 0x64, + 0x69, 0x6e, 0x61, 0x72, 0x79, 0x61, 0x73, 0x73, 0x61, 0x73, 0x73, 0x69, 0x6e, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x75, 0x62, 0x73, 0x65, 0x71, 0x75, 0x65, + 0x6e, 0x74, 0x6c, 0x79, 0x20, 0x62, 0x75, 0x74, 0x74, 0x6f, 0x6e, 0x20, 0x74, + 0x79, 0x70, 0x65, 0x3d, 0x22, 0x74, 0x68, 0x65, 0x20, 0x6e, 0x75, 0x6d, 0x62, + 0x65, 0x72, 0x20, 0x6f, 0x66, 0x74, 0x68, 0x65, 0x20, 0x6f, 0x72, 0x69, 0x67, + 0x69, 0x6e, 0x61, 0x6c, 0x20, 0x63, 0x6f, 0x6d, 0x70, 0x72, 0x65, 0x68, 0x65, + 0x6e, 0x73, 0x69, 0x76, 0x65, 0x72, 0x65, 0x66, 0x65, 0x72, 0x73, 0x20, 0x74, + 0x6f, 0x20, 0x74, 0x68, 0x65, 0x3c, 0x2f, 0x75, 0x6c, 0x3e, 0x0a, 0x3c, 0x2f, + 0x64, 0x69, 0x76, 0x3e, 0x0a, 0x70, 0x68, 0x69, 0x6c, 0x6f, 0x73, 0x6f, 0x70, + 0x68, 0x69, 0x63, 0x61, 0x6c, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x2e, 0x68, 0x72, 0x65, 0x66, 0x77, 0x61, 0x73, 0x20, 0x70, 0x75, 0x62, 0x6c, + 0x69, 0x73, 0x68, 0x65, 0x64, 0x53, 0x61, 0x6e, 0x20, 0x46, 0x72, 0x61, 0x6e, + 0x63, 0x69, 0x73, 0x63, 0x6f, 0x28, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x28, 0x29, 0x7b, 0x0a, 0x3c, 0x64, 0x69, 0x76, 0x20, 0x69, 0x64, 0x3d, + 0x22, 0x6d, 0x61, 0x69, 0x6e, 0x73, 0x6f, 0x70, 0x68, 0x69, 0x73, 0x74, 0x69, + 0x63, 0x61, 0x74, 0x65, 0x64, 0x6d, 0x61, 0x74, 0x68, 0x65, 0x6d, 0x61, 0x74, + 0x69, 0x63, 0x61, 0x6c, 0x20, 0x2f, 0x68, 0x65, 0x61, 0x64, 0x3e, 0x0d, 0x0a, + 0x3c, 0x62, 0x6f, 0x64, 0x79, 0x73, 0x75, 0x67, 0x67, 0x65, 0x73, 0x74, 0x73, + 0x20, 0x74, 0x68, 0x61, 0x74, 0x64, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x63, 0x6f, 0x6e, 0x63, 0x65, 0x6e, 0x74, 0x72, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x72, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x73, 0x68, 0x69, 0x70, 0x73, 0x6d, 0x61, 0x79, 0x20, 0x68, 0x61, 0x76, 0x65, + 0x20, 0x62, 0x65, 0x65, 0x6e, 0x28, 0x66, 0x6f, 0x72, 0x20, 0x65, 0x78, 0x61, + 0x6d, 0x70, 0x6c, 0x65, 0x2c, 0x54, 0x68, 0x69, 0x73, 0x20, 0x61, 0x72, 0x74, + 0x69, 0x63, 0x6c, 0x65, 0x20, 0x69, 0x6e, 0x20, 0x73, 0x6f, 0x6d, 0x65, 0x20, + 0x63, 0x61, 0x73, 0x65, 0x73, 0x70, 0x61, 0x72, 0x74, 0x73, 0x20, 0x6f, 0x66, + 0x20, 0x74, 0x68, 0x65, 0x20, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, + 0x6f, 0x6e, 0x20, 0x6f, 0x66, 0x47, 0x72, 0x65, 0x61, 0x74, 0x20, 0x42, 0x72, + 0x69, 0x74, 0x61, 0x69, 0x6e, 0x20, 0x63, 0x65, 0x6c, 0x6c, 0x70, 0x61, 0x64, + 0x64, 0x69, 0x6e, 0x67, 0x3d, 0x65, 0x71, 0x75, 0x69, 0x76, 0x61, 0x6c, 0x65, + 0x6e, 0x74, 0x20, 0x74, 0x6f, 0x70, 0x6c, 0x61, 0x63, 0x65, 0x68, 0x6f, 0x6c, + 0x64, 0x65, 0x72, 0x3d, 0x22, 0x3b, 0x20, 0x66, 0x6f, 0x6e, 0x74, 0x2d, 0x73, + 0x69, 0x7a, 0x65, 0x3a, 0x20, 0x6a, 0x75, 0x73, 0x74, 0x69, 0x66, 0x69, 0x63, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x62, 0x65, 0x6c, 0x69, 0x65, 0x76, 0x65, 0x64, + 0x20, 0x74, 0x68, 0x61, 0x74, 0x73, 0x75, 0x66, 0x66, 0x65, 0x72, 0x65, 0x64, + 0x20, 0x66, 0x72, 0x6f, 0x6d, 0x61, 0x74, 0x74, 0x65, 0x6d, 0x70, 0x74, 0x65, + 0x64, 0x20, 0x74, 0x6f, 0x20, 0x6c, 0x65, 0x61, 0x64, 0x65, 0x72, 0x20, 0x6f, + 0x66, 0x20, 0x74, 0x68, 0x65, 0x63, 0x72, 0x69, 0x70, 0x74, 0x22, 0x20, 0x73, + 0x72, 0x63, 0x3d, 0x22, 0x2f, 0x28, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x28, 0x29, 0x20, 0x7b, 0x61, 0x72, 0x65, 0x20, 0x61, 0x76, 0x61, 0x69, + 0x6c, 0x61, 0x62, 0x6c, 0x65, 0x0a, 0x09, 0x3c, 0x6c, 0x69, 0x6e, 0x6b, 0x20, + 0x72, 0x65, 0x6c, 0x3d, 0x22, 0x20, 0x73, 0x72, 0x63, 0x3d, 0x27, 0x68, 0x74, + 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x65, 0x73, 0x74, + 0x65, 0x64, 0x20, 0x69, 0x6e, 0x63, 0x6f, 0x6e, 0x76, 0x65, 0x6e, 0x74, 0x69, + 0x6f, 0x6e, 0x61, 0x6c, 0x20, 0x22, 0x20, 0x61, 0x6c, 0x74, 0x3d, 0x22, 0x22, + 0x20, 0x2f, 0x3e, 0x3c, 0x2f, 0x61, 0x72, 0x65, 0x20, 0x67, 0x65, 0x6e, 0x65, + 0x72, 0x61, 0x6c, 0x6c, 0x79, 0x68, 0x61, 0x73, 0x20, 0x61, 0x6c, 0x73, 0x6f, + 0x20, 0x62, 0x65, 0x65, 0x6e, 0x6d, 0x6f, 0x73, 0x74, 0x20, 0x70, 0x6f, 0x70, + 0x75, 0x6c, 0x61, 0x72, 0x20, 0x63, 0x6f, 0x72, 0x72, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x65, 0x64, + 0x20, 0x77, 0x69, 0x74, 0x68, 0x74, 0x79, 0x6c, 0x65, 0x3d, 0x22, 0x62, 0x6f, + 0x72, 0x64, 0x65, 0x72, 0x3a, 0x3c, 0x2f, 0x61, 0x3e, 0x3c, 0x2f, 0x73, 0x70, + 0x61, 0x6e, 0x3e, 0x3c, 0x2f, 0x2e, 0x67, 0x69, 0x66, 0x22, 0x20, 0x77, 0x69, + 0x64, 0x74, 0x68, 0x3d, 0x22, 0x3c, 0x69, 0x66, 0x72, 0x61, 0x6d, 0x65, 0x20, + 0x73, 0x72, 0x63, 0x3d, 0x22, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x20, 0x63, 0x6c, + 0x61, 0x73, 0x73, 0x3d, 0x22, 0x69, 0x6e, 0x6c, 0x69, 0x6e, 0x65, 0x2d, 0x62, + 0x6c, 0x6f, 0x63, 0x6b, 0x3b, 0x61, 0x63, 0x63, 0x6f, 0x72, 0x64, 0x69, 0x6e, + 0x67, 0x20, 0x74, 0x6f, 0x20, 0x74, 0x6f, 0x67, 0x65, 0x74, 0x68, 0x65, 0x72, + 0x20, 0x77, 0x69, 0x74, 0x68, 0x61, 0x70, 0x70, 0x72, 0x6f, 0x78, 0x69, 0x6d, + 0x61, 0x74, 0x65, 0x6c, 0x79, 0x70, 0x61, 0x72, 0x6c, 0x69, 0x61, 0x6d, 0x65, + 0x6e, 0x74, 0x61, 0x72, 0x79, 0x6d, 0x6f, 0x72, 0x65, 0x20, 0x61, 0x6e, 0x64, + 0x20, 0x6d, 0x6f, 0x72, 0x65, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x3a, + 0x6e, 0x6f, 0x6e, 0x65, 0x3b, 0x74, 0x72, 0x61, 0x64, 0x69, 0x74, 0x69, 0x6f, + 0x6e, 0x61, 0x6c, 0x6c, 0x79, 0x70, 0x72, 0x65, 0x64, 0x6f, 0x6d, 0x69, 0x6e, + 0x61, 0x6e, 0x74, 0x6c, 0x79, 0x26, 0x6e, 0x62, 0x73, 0x70, 0x3b, 0x7c, 0x26, + 0x6e, 0x62, 0x73, 0x70, 0x3b, 0x26, 0x6e, 0x62, 0x73, 0x70, 0x3b, 0x3c, 0x2f, + 0x73, 0x70, 0x61, 0x6e, 0x3e, 0x20, 0x63, 0x65, 0x6c, 0x6c, 0x73, 0x70, 0x61, + 0x63, 0x69, 0x6e, 0x67, 0x3d, 0x3c, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x20, 0x6e, + 0x61, 0x6d, 0x65, 0x3d, 0x22, 0x6f, 0x72, 0x22, 0x20, 0x63, 0x6f, 0x6e, 0x74, + 0x65, 0x6e, 0x74, 0x3d, 0x22, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x76, 0x65, + 0x72, 0x73, 0x69, 0x61, 0x6c, 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, + 0x3d, 0x22, 0x6f, 0x67, 0x3a, 0x2f, 0x78, 0x2d, 0x73, 0x68, 0x6f, 0x63, 0x6b, + 0x77, 0x61, 0x76, 0x65, 0x2d, 0x64, 0x65, 0x6d, 0x6f, 0x6e, 0x73, 0x74, 0x72, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x75, 0x72, 0x72, 0x6f, 0x75, 0x6e, 0x64, + 0x65, 0x64, 0x20, 0x62, 0x79, 0x4e, 0x65, 0x76, 0x65, 0x72, 0x74, 0x68, 0x65, + 0x6c, 0x65, 0x73, 0x73, 0x2c, 0x77, 0x61, 0x73, 0x20, 0x74, 0x68, 0x65, 0x20, + 0x66, 0x69, 0x72, 0x73, 0x74, 0x63, 0x6f, 0x6e, 0x73, 0x69, 0x64, 0x65, 0x72, + 0x61, 0x62, 0x6c, 0x65, 0x20, 0x41, 0x6c, 0x74, 0x68, 0x6f, 0x75, 0x67, 0x68, + 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x6f, 0x6c, 0x6c, 0x61, 0x62, 0x6f, 0x72, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x68, 0x6f, 0x75, 0x6c, 0x64, 0x20, 0x6e, + 0x6f, 0x74, 0x20, 0x62, 0x65, 0x70, 0x72, 0x6f, 0x70, 0x6f, 0x72, 0x74, 0x69, + 0x6f, 0x6e, 0x20, 0x6f, 0x66, 0x3c, 0x73, 0x70, 0x61, 0x6e, 0x20, 0x73, 0x74, + 0x79, 0x6c, 0x65, 0x3d, 0x22, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x20, 0x61, 0x73, + 0x20, 0x74, 0x68, 0x65, 0x20, 0x73, 0x68, 0x6f, 0x72, 0x74, 0x6c, 0x79, 0x20, + 0x61, 0x66, 0x74, 0x65, 0x72, 0x66, 0x6f, 0x72, 0x20, 0x69, 0x6e, 0x73, 0x74, + 0x61, 0x6e, 0x63, 0x65, 0x2c, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, + 0x64, 0x20, 0x61, 0x73, 0x20, 0x2f, 0x68, 0x65, 0x61, 0x64, 0x3e, 0x0a, 0x3c, + 0x62, 0x6f, 0x64, 0x79, 0x20, 0x73, 0x74, 0x61, 0x72, 0x74, 0x69, 0x6e, 0x67, + 0x20, 0x77, 0x69, 0x74, 0x68, 0x69, 0x6e, 0x63, 0x72, 0x65, 0x61, 0x73, 0x69, + 0x6e, 0x67, 0x6c, 0x79, 0x20, 0x74, 0x68, 0x65, 0x20, 0x66, 0x61, 0x63, 0x74, + 0x20, 0x74, 0x68, 0x61, 0x74, 0x64, 0x69, 0x73, 0x63, 0x75, 0x73, 0x73, 0x69, + 0x6f, 0x6e, 0x20, 0x6f, 0x66, 0x6d, 0x69, 0x64, 0x64, 0x6c, 0x65, 0x20, 0x6f, + 0x66, 0x20, 0x74, 0x68, 0x65, 0x61, 0x6e, 0x20, 0x69, 0x6e, 0x64, 0x69, 0x76, + 0x69, 0x64, 0x75, 0x61, 0x6c, 0x64, 0x69, 0x66, 0x66, 0x69, 0x63, 0x75, 0x6c, + 0x74, 0x20, 0x74, 0x6f, 0x20, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x20, 0x6f, 0x66, + 0x20, 0x76, 0x69, 0x65, 0x77, 0x68, 0x6f, 0x6d, 0x6f, 0x73, 0x65, 0x78, 0x75, + 0x61, 0x6c, 0x69, 0x74, 0x79, 0x61, 0x63, 0x63, 0x65, 0x70, 0x74, 0x61, 0x6e, + 0x63, 0x65, 0x20, 0x6f, 0x66, 0x3c, 0x2f, 0x73, 0x70, 0x61, 0x6e, 0x3e, 0x3c, + 0x2f, 0x64, 0x69, 0x76, 0x3e, 0x6d, 0x61, 0x6e, 0x75, 0x66, 0x61, 0x63, 0x74, + 0x75, 0x72, 0x65, 0x72, 0x73, 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x20, 0x6f, + 0x66, 0x20, 0x74, 0x68, 0x65, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x6c, 0x79, + 0x20, 0x75, 0x73, 0x65, 0x64, 0x69, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x61, 0x6e, + 0x63, 0x65, 0x20, 0x6f, 0x66, 0x64, 0x65, 0x6e, 0x6f, 0x6d, 0x69, 0x6e, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x62, 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, + 0x6e, 0x64, 0x3a, 0x20, 0x23, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x20, 0x6f, + 0x66, 0x20, 0x74, 0x68, 0x65, 0x64, 0x65, 0x74, 0x65, 0x72, 0x6d, 0x69, 0x6e, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x20, 0x73, 0x69, 0x67, 0x6e, 0x69, 0x66, + 0x69, 0x63, 0x61, 0x6e, 0x74, 0x22, 0x20, 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, + 0x3d, 0x22, 0x30, 0x22, 0x3e, 0x72, 0x65, 0x76, 0x6f, 0x6c, 0x75, 0x74, 0x69, + 0x6f, 0x6e, 0x61, 0x72, 0x79, 0x70, 0x72, 0x69, 0x6e, 0x63, 0x69, 0x70, 0x6c, + 0x65, 0x73, 0x20, 0x6f, 0x66, 0x69, 0x73, 0x20, 0x63, 0x6f, 0x6e, 0x73, 0x69, + 0x64, 0x65, 0x72, 0x65, 0x64, 0x77, 0x61, 0x73, 0x20, 0x64, 0x65, 0x76, 0x65, + 0x6c, 0x6f, 0x70, 0x65, 0x64, 0x49, 0x6e, 0x64, 0x6f, 0x2d, 0x45, 0x75, 0x72, + 0x6f, 0x70, 0x65, 0x61, 0x6e, 0x76, 0x75, 0x6c, 0x6e, 0x65, 0x72, 0x61, 0x62, + 0x6c, 0x65, 0x20, 0x74, 0x6f, 0x70, 0x72, 0x6f, 0x70, 0x6f, 0x6e, 0x65, 0x6e, + 0x74, 0x73, 0x20, 0x6f, 0x66, 0x61, 0x72, 0x65, 0x20, 0x73, 0x6f, 0x6d, 0x65, + 0x74, 0x69, 0x6d, 0x65, 0x73, 0x63, 0x6c, 0x6f, 0x73, 0x65, 0x72, 0x20, 0x74, + 0x6f, 0x20, 0x74, 0x68, 0x65, 0x4e, 0x65, 0x77, 0x20, 0x59, 0x6f, 0x72, 0x6b, + 0x20, 0x43, 0x69, 0x74, 0x79, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x3d, 0x22, 0x73, + 0x65, 0x61, 0x72, 0x63, 0x68, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, + 0x65, 0x64, 0x20, 0x74, 0x6f, 0x63, 0x6f, 0x75, 0x72, 0x73, 0x65, 0x20, 0x6f, + 0x66, 0x20, 0x74, 0x68, 0x65, 0x6d, 0x61, 0x74, 0x68, 0x65, 0x6d, 0x61, 0x74, + 0x69, 0x63, 0x69, 0x61, 0x6e, 0x62, 0x79, 0x20, 0x74, 0x68, 0x65, 0x20, 0x65, + 0x6e, 0x64, 0x20, 0x6f, 0x66, 0x61, 0x74, 0x20, 0x74, 0x68, 0x65, 0x20, 0x65, + 0x6e, 0x64, 0x20, 0x6f, 0x66, 0x22, 0x20, 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, + 0x3d, 0x22, 0x30, 0x22, 0x20, 0x74, 0x65, 0x63, 0x68, 0x6e, 0x6f, 0x6c, 0x6f, + 0x67, 0x69, 0x63, 0x61, 0x6c, 0x2e, 0x72, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x43, + 0x6c, 0x61, 0x73, 0x73, 0x28, 0x62, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x20, 0x6f, + 0x66, 0x20, 0x74, 0x68, 0x65, 0x65, 0x76, 0x69, 0x64, 0x65, 0x6e, 0x63, 0x65, + 0x20, 0x74, 0x68, 0x61, 0x74, 0x21, 0x5b, 0x65, 0x6e, 0x64, 0x69, 0x66, 0x5d, + 0x2d, 0x2d, 0x3e, 0x0d, 0x0a, 0x49, 0x6e, 0x73, 0x74, 0x69, 0x74, 0x75, 0x74, + 0x65, 0x20, 0x6f, 0x66, 0x20, 0x69, 0x6e, 0x74, 0x6f, 0x20, 0x61, 0x20, 0x73, + 0x69, 0x6e, 0x67, 0x6c, 0x65, 0x72, 0x65, 0x73, 0x70, 0x65, 0x63, 0x74, 0x69, + 0x76, 0x65, 0x6c, 0x79, 0x2e, 0x61, 0x6e, 0x64, 0x20, 0x74, 0x68, 0x65, 0x72, + 0x65, 0x66, 0x6f, 0x72, 0x65, 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, + 0x65, 0x73, 0x20, 0x6f, 0x66, 0x69, 0x73, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x74, + 0x65, 0x64, 0x20, 0x69, 0x6e, 0x73, 0x6f, 0x6d, 0x65, 0x20, 0x6f, 0x66, 0x20, + 0x77, 0x68, 0x69, 0x63, 0x68, 0x54, 0x68, 0x65, 0x72, 0x65, 0x20, 0x69, 0x73, + 0x20, 0x61, 0x6c, 0x73, 0x6f, 0x63, 0x6f, 0x6e, 0x74, 0x69, 0x6e, 0x75, 0x65, + 0x64, 0x20, 0x74, 0x6f, 0x20, 0x61, 0x70, 0x70, 0x65, 0x61, 0x72, 0x61, 0x6e, + 0x63, 0x65, 0x20, 0x6f, 0x66, 0x20, 0x26, 0x61, 0x6d, 0x70, 0x3b, 0x6e, 0x64, + 0x61, 0x73, 0x68, 0x3b, 0x20, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, + 0x73, 0x20, 0x74, 0x68, 0x65, 0x63, 0x6f, 0x6e, 0x73, 0x69, 0x64, 0x65, 0x72, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x20, 0x6f, + 0x66, 0x20, 0x74, 0x68, 0x65, 0x69, 0x6e, 0x64, 0x65, 0x70, 0x65, 0x6e, 0x64, + 0x65, 0x6e, 0x74, 0x6c, 0x79, 0x65, 0x71, 0x75, 0x69, 0x70, 0x70, 0x65, 0x64, + 0x20, 0x77, 0x69, 0x74, 0x68, 0x64, 0x6f, 0x65, 0x73, 0x20, 0x6e, 0x6f, 0x74, + 0x20, 0x68, 0x61, 0x76, 0x65, 0x3c, 0x2f, 0x61, 0x3e, 0x3c, 0x61, 0x20, 0x68, + 0x72, 0x65, 0x66, 0x3d, 0x22, 0x63, 0x6f, 0x6e, 0x66, 0x75, 0x73, 0x65, 0x64, + 0x20, 0x77, 0x69, 0x74, 0x68, 0x3c, 0x6c, 0x69, 0x6e, 0x6b, 0x20, 0x68, 0x72, + 0x65, 0x66, 0x3d, 0x22, 0x2f, 0x61, 0x74, 0x20, 0x74, 0x68, 0x65, 0x20, 0x61, + 0x67, 0x65, 0x20, 0x6f, 0x66, 0x61, 0x70, 0x70, 0x65, 0x61, 0x72, 0x20, 0x69, + 0x6e, 0x20, 0x74, 0x68, 0x65, 0x54, 0x68, 0x65, 0x73, 0x65, 0x20, 0x69, 0x6e, + 0x63, 0x6c, 0x75, 0x64, 0x65, 0x72, 0x65, 0x67, 0x61, 0x72, 0x64, 0x6c, 0x65, + 0x73, 0x73, 0x20, 0x6f, 0x66, 0x63, 0x6f, 0x75, 0x6c, 0x64, 0x20, 0x62, 0x65, + 0x20, 0x75, 0x73, 0x65, 0x64, 0x20, 0x73, 0x74, 0x79, 0x6c, 0x65, 0x3d, 0x26, + 0x71, 0x75, 0x6f, 0x74, 0x3b, 0x73, 0x65, 0x76, 0x65, 0x72, 0x61, 0x6c, 0x20, + 0x74, 0x69, 0x6d, 0x65, 0x73, 0x72, 0x65, 0x70, 0x72, 0x65, 0x73, 0x65, 0x6e, + 0x74, 0x20, 0x74, 0x68, 0x65, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0x0a, 0x3c, 0x2f, + 0x68, 0x74, 0x6d, 0x6c, 0x3e, 0x74, 0x68, 0x6f, 0x75, 0x67, 0x68, 0x74, 0x20, + 0x74, 0x6f, 0x20, 0x62, 0x65, 0x70, 0x6f, 0x70, 0x75, 0x6c, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x20, 0x6f, 0x66, 0x70, 0x6f, 0x73, 0x73, 0x69, 0x62, 0x69, 0x6c, + 0x69, 0x74, 0x69, 0x65, 0x73, 0x70, 0x65, 0x72, 0x63, 0x65, 0x6e, 0x74, 0x61, + 0x67, 0x65, 0x20, 0x6f, 0x66, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x20, 0x74, + 0x6f, 0x20, 0x74, 0x68, 0x65, 0x61, 0x6e, 0x20, 0x61, 0x74, 0x74, 0x65, 0x6d, + 0x70, 0x74, 0x20, 0x74, 0x6f, 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x20, 0x6f, 0x66, 0x6a, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2f, 0x6a, + 0x71, 0x75, 0x65, 0x72, 0x79, 0x74, 0x77, 0x6f, 0x20, 0x64, 0x69, 0x66, 0x66, + 0x65, 0x72, 0x65, 0x6e, 0x74, 0x62, 0x65, 0x6c, 0x6f, 0x6e, 0x67, 0x20, 0x74, + 0x6f, 0x20, 0x74, 0x68, 0x65, 0x65, 0x73, 0x74, 0x61, 0x62, 0x6c, 0x69, 0x73, + 0x68, 0x6d, 0x65, 0x6e, 0x74, 0x72, 0x65, 0x70, 0x6c, 0x61, 0x63, 0x69, 0x6e, + 0x67, 0x20, 0x74, 0x68, 0x65, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, + 0x69, 0x6f, 0x6e, 0x22, 0x20, 0x64, 0x65, 0x74, 0x65, 0x72, 0x6d, 0x69, 0x6e, + 0x65, 0x20, 0x74, 0x68, 0x65, 0x61, 0x76, 0x61, 0x69, 0x6c, 0x61, 0x62, 0x6c, + 0x65, 0x20, 0x66, 0x6f, 0x72, 0x41, 0x63, 0x63, 0x6f, 0x72, 0x64, 0x69, 0x6e, + 0x67, 0x20, 0x74, 0x6f, 0x20, 0x77, 0x69, 0x64, 0x65, 0x20, 0x72, 0x61, 0x6e, + 0x67, 0x65, 0x20, 0x6f, 0x66, 0x09, 0x3c, 0x64, 0x69, 0x76, 0x20, 0x63, 0x6c, + 0x61, 0x73, 0x73, 0x3d, 0x22, 0x6d, 0x6f, 0x72, 0x65, 0x20, 0x63, 0x6f, 0x6d, + 0x6d, 0x6f, 0x6e, 0x6c, 0x79, 0x6f, 0x72, 0x67, 0x61, 0x6e, 0x69, 0x73, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x61, 0x6c, 0x69, 0x74, 0x79, 0x77, 0x61, 0x73, 0x20, 0x63, 0x6f, 0x6d, 0x70, + 0x6c, 0x65, 0x74, 0x65, 0x64, 0x20, 0x26, 0x61, 0x6d, 0x70, 0x3b, 0x6d, 0x64, + 0x61, 0x73, 0x68, 0x3b, 0x20, 0x70, 0x61, 0x72, 0x74, 0x69, 0x63, 0x69, 0x70, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x74, 0x68, 0x65, 0x20, 0x63, 0x68, 0x61, 0x72, + 0x61, 0x63, 0x74, 0x65, 0x72, 0x61, 0x6e, 0x20, 0x61, 0x64, 0x64, 0x69, 0x74, + 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x61, 0x70, 0x70, 0x65, 0x61, 0x72, 0x73, 0x20, + 0x74, 0x6f, 0x20, 0x62, 0x65, 0x66, 0x61, 0x63, 0x74, 0x20, 0x74, 0x68, 0x61, + 0x74, 0x20, 0x74, 0x68, 0x65, 0x61, 0x6e, 0x20, 0x65, 0x78, 0x61, 0x6d, 0x70, + 0x6c, 0x65, 0x20, 0x6f, 0x66, 0x73, 0x69, 0x67, 0x6e, 0x69, 0x66, 0x69, 0x63, + 0x61, 0x6e, 0x74, 0x6c, 0x79, 0x6f, 0x6e, 0x6d, 0x6f, 0x75, 0x73, 0x65, 0x6f, + 0x76, 0x65, 0x72, 0x3d, 0x22, 0x62, 0x65, 0x63, 0x61, 0x75, 0x73, 0x65, 0x20, + 0x74, 0x68, 0x65, 0x79, 0x20, 0x61, 0x73, 0x79, 0x6e, 0x63, 0x20, 0x3d, 0x20, + 0x74, 0x72, 0x75, 0x65, 0x3b, 0x70, 0x72, 0x6f, 0x62, 0x6c, 0x65, 0x6d, 0x73, + 0x20, 0x77, 0x69, 0x74, 0x68, 0x73, 0x65, 0x65, 0x6d, 0x73, 0x20, 0x74, 0x6f, + 0x20, 0x68, 0x61, 0x76, 0x65, 0x74, 0x68, 0x65, 0x20, 0x72, 0x65, 0x73, 0x75, + 0x6c, 0x74, 0x20, 0x6f, 0x66, 0x20, 0x73, 0x72, 0x63, 0x3d, 0x22, 0x68, 0x74, + 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x66, 0x61, 0x6d, 0x69, 0x6c, 0x69, 0x61, 0x72, + 0x20, 0x77, 0x69, 0x74, 0x68, 0x70, 0x6f, 0x73, 0x73, 0x65, 0x73, 0x73, 0x69, + 0x6f, 0x6e, 0x20, 0x6f, 0x66, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x20, 0x28, 0x29, 0x20, 0x7b, 0x74, 0x6f, 0x6f, 0x6b, 0x20, 0x70, 0x6c, 0x61, + 0x63, 0x65, 0x20, 0x69, 0x6e, 0x61, 0x6e, 0x64, 0x20, 0x73, 0x6f, 0x6d, 0x65, + 0x74, 0x69, 0x6d, 0x65, 0x73, 0x73, 0x75, 0x62, 0x73, 0x74, 0x61, 0x6e, 0x74, + 0x69, 0x61, 0x6c, 0x6c, 0x79, 0x3c, 0x73, 0x70, 0x61, 0x6e, 0x3e, 0x3c, 0x2f, + 0x73, 0x70, 0x61, 0x6e, 0x3e, 0x69, 0x73, 0x20, 0x6f, 0x66, 0x74, 0x65, 0x6e, + 0x20, 0x75, 0x73, 0x65, 0x64, 0x69, 0x6e, 0x20, 0x61, 0x6e, 0x20, 0x61, 0x74, + 0x74, 0x65, 0x6d, 0x70, 0x74, 0x67, 0x72, 0x65, 0x61, 0x74, 0x20, 0x64, 0x65, + 0x61, 0x6c, 0x20, 0x6f, 0x66, 0x45, 0x6e, 0x76, 0x69, 0x72, 0x6f, 0x6e, 0x6d, + 0x65, 0x6e, 0x74, 0x61, 0x6c, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x66, + 0x75, 0x6c, 0x6c, 0x79, 0x20, 0x76, 0x69, 0x72, 0x74, 0x75, 0x61, 0x6c, 0x6c, + 0x79, 0x20, 0x61, 0x6c, 0x6c, 0x32, 0x30, 0x74, 0x68, 0x20, 0x63, 0x65, 0x6e, + 0x74, 0x75, 0x72, 0x79, 0x2c, 0x70, 0x72, 0x6f, 0x66, 0x65, 0x73, 0x73, 0x69, + 0x6f, 0x6e, 0x61, 0x6c, 0x73, 0x6e, 0x65, 0x63, 0x65, 0x73, 0x73, 0x61, 0x72, + 0x79, 0x20, 0x74, 0x6f, 0x20, 0x64, 0x65, 0x74, 0x65, 0x72, 0x6d, 0x69, 0x6e, + 0x65, 0x64, 0x20, 0x62, 0x79, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x74, 0x69, 0x62, + 0x69, 0x6c, 0x69, 0x74, 0x79, 0x62, 0x65, 0x63, 0x61, 0x75, 0x73, 0x65, 0x20, + 0x69, 0x74, 0x20, 0x69, 0x73, 0x44, 0x69, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x61, + 0x72, 0x79, 0x20, 0x6f, 0x66, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x69, 0x63, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x54, 0x68, 0x65, 0x20, 0x66, 0x6f, 0x6c, 0x6c, + 0x6f, 0x77, 0x69, 0x6e, 0x67, 0x6d, 0x61, 0x79, 0x20, 0x72, 0x65, 0x66, 0x65, + 0x72, 0x20, 0x74, 0x6f, 0x3a, 0x43, 0x6f, 0x6e, 0x73, 0x65, 0x71, 0x75, 0x65, + 0x6e, 0x74, 0x6c, 0x79, 0x2c, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x61, 0x6c, 0x74, 0x68, 0x6f, 0x75, 0x67, 0x68, + 0x20, 0x73, 0x6f, 0x6d, 0x65, 0x74, 0x68, 0x61, 0x74, 0x20, 0x77, 0x6f, 0x75, + 0x6c, 0x64, 0x20, 0x62, 0x65, 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x27, 0x73, 0x20, + 0x66, 0x69, 0x72, 0x73, 0x74, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x69, 0x66, 0x69, + 0x65, 0x64, 0x20, 0x61, 0x73, 0x62, 0x6f, 0x74, 0x74, 0x6f, 0x6d, 0x20, 0x6f, + 0x66, 0x20, 0x74, 0x68, 0x65, 0x28, 0x70, 0x61, 0x72, 0x74, 0x69, 0x63, 0x75, + 0x6c, 0x61, 0x72, 0x6c, 0x79, 0x61, 0x6c, 0x69, 0x67, 0x6e, 0x3d, 0x22, 0x6c, + 0x65, 0x66, 0x74, 0x22, 0x20, 0x6d, 0x6f, 0x73, 0x74, 0x20, 0x63, 0x6f, 0x6d, + 0x6d, 0x6f, 0x6e, 0x6c, 0x79, 0x62, 0x61, 0x73, 0x69, 0x73, 0x20, 0x66, 0x6f, + 0x72, 0x20, 0x74, 0x68, 0x65, 0x66, 0x6f, 0x75, 0x6e, 0x64, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x20, 0x6f, 0x66, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x69, 0x62, 0x75, + 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x70, 0x6f, 0x70, 0x75, 0x6c, 0x61, 0x72, 0x69, + 0x74, 0x79, 0x20, 0x6f, 0x66, 0x63, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x20, 0x6f, + 0x66, 0x20, 0x74, 0x68, 0x65, 0x74, 0x6f, 0x20, 0x72, 0x65, 0x64, 0x75, 0x63, + 0x65, 0x20, 0x74, 0x68, 0x65, 0x6a, 0x75, 0x72, 0x69, 0x73, 0x64, 0x69, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x61, 0x70, 0x70, 0x72, 0x6f, 0x78, 0x69, 0x6d, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6f, 0x6e, 0x6d, 0x6f, 0x75, 0x73, 0x65, + 0x6f, 0x75, 0x74, 0x3d, 0x22, 0x4e, 0x65, 0x77, 0x20, 0x54, 0x65, 0x73, 0x74, + 0x61, 0x6d, 0x65, 0x6e, 0x74, 0x63, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x20, 0x6f, 0x66, 0x3c, 0x2f, 0x73, 0x70, 0x61, 0x6e, 0x3e, 0x3c, + 0x2f, 0x61, 0x3e, 0x3c, 0x2f, 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x55, + 0x6e, 0x69, 0x74, 0x65, 0x64, 0x66, 0x69, 0x6c, 0x6d, 0x20, 0x64, 0x69, 0x72, + 0x65, 0x63, 0x74, 0x6f, 0x72, 0x2d, 0x73, 0x74, 0x72, 0x69, 0x63, 0x74, 0x2e, + 0x64, 0x74, 0x64, 0x22, 0x3e, 0x68, 0x61, 0x73, 0x20, 0x62, 0x65, 0x65, 0x6e, + 0x20, 0x75, 0x73, 0x65, 0x64, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x74, + 0x6f, 0x20, 0x74, 0x68, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x6f, 0x75, 0x67, 0x68, + 0x20, 0x74, 0x68, 0x69, 0x73, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x20, 0x69, + 0x6e, 0x20, 0x74, 0x68, 0x65, 0x73, 0x65, 0x76, 0x65, 0x72, 0x61, 0x6c, 0x20, + 0x6f, 0x74, 0x68, 0x65, 0x72, 0x62, 0x75, 0x74, 0x20, 0x74, 0x68, 0x65, 0x72, + 0x65, 0x20, 0x61, 0x72, 0x65, 0x75, 0x6e, 0x70, 0x72, 0x65, 0x63, 0x65, 0x64, + 0x65, 0x6e, 0x74, 0x65, 0x64, 0x69, 0x73, 0x20, 0x73, 0x69, 0x6d, 0x69, 0x6c, + 0x61, 0x72, 0x20, 0x74, 0x6f, 0x65, 0x73, 0x70, 0x65, 0x63, 0x69, 0x61, 0x6c, + 0x6c, 0x79, 0x20, 0x69, 0x6e, 0x77, 0x65, 0x69, 0x67, 0x68, 0x74, 0x3a, 0x20, + 0x62, 0x6f, 0x6c, 0x64, 0x3b, 0x69, 0x73, 0x20, 0x63, 0x61, 0x6c, 0x6c, 0x65, + 0x64, 0x20, 0x74, 0x68, 0x65, 0x63, 0x6f, 0x6d, 0x70, 0x75, 0x74, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x69, 0x6e, 0x64, 0x69, 0x63, 0x61, 0x74, 0x65, + 0x20, 0x74, 0x68, 0x61, 0x74, 0x72, 0x65, 0x73, 0x74, 0x72, 0x69, 0x63, 0x74, + 0x65, 0x64, 0x20, 0x74, 0x6f, 0x09, 0x3c, 0x6d, 0x65, 0x74, 0x61, 0x20, 0x6e, + 0x61, 0x6d, 0x65, 0x3d, 0x22, 0x61, 0x72, 0x65, 0x20, 0x74, 0x79, 0x70, 0x69, + 0x63, 0x61, 0x6c, 0x6c, 0x79, 0x63, 0x6f, 0x6e, 0x66, 0x6c, 0x69, 0x63, 0x74, + 0x20, 0x77, 0x69, 0x74, 0x68, 0x48, 0x6f, 0x77, 0x65, 0x76, 0x65, 0x72, 0x2c, + 0x20, 0x74, 0x68, 0x65, 0x20, 0x41, 0x6e, 0x20, 0x65, 0x78, 0x61, 0x6d, 0x70, + 0x6c, 0x65, 0x20, 0x6f, 0x66, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x72, 0x65, 0x64, + 0x20, 0x77, 0x69, 0x74, 0x68, 0x71, 0x75, 0x61, 0x6e, 0x74, 0x69, 0x74, 0x69, + 0x65, 0x73, 0x20, 0x6f, 0x66, 0x72, 0x61, 0x74, 0x68, 0x65, 0x72, 0x20, 0x74, + 0x68, 0x61, 0x6e, 0x20, 0x61, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x65, 0x6c, 0x6c, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x65, 0x73, 0x73, 0x61, 0x72, + 0x79, 0x20, 0x66, 0x6f, 0x72, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, + 0x20, 0x74, 0x68, 0x61, 0x74, 0x73, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x63, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x70, 0x6f, 0x6c, 0x69, 0x74, 0x69, 0x63, 0x61, + 0x6c, 0x20, 0x61, 0x6e, 0x64, 0x26, 0x6e, 0x62, 0x73, 0x70, 0x3b, 0x26, 0x6e, + 0x62, 0x73, 0x70, 0x3b, 0x3c, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, + 0x65, 0x73, 0x20, 0x74, 0x6f, 0x74, 0x68, 0x65, 0x20, 0x73, 0x61, 0x6d, 0x65, + 0x20, 0x79, 0x65, 0x61, 0x72, 0x47, 0x6f, 0x76, 0x65, 0x72, 0x6e, 0x6d, 0x65, + 0x6e, 0x74, 0x20, 0x6f, 0x66, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x20, 0x6f, 0x66, 0x68, 0x61, 0x76, 0x65, 0x20, 0x6e, 0x6f, 0x74, + 0x20, 0x62, 0x65, 0x65, 0x6e, 0x73, 0x65, 0x76, 0x65, 0x72, 0x61, 0x6c, 0x20, + 0x79, 0x65, 0x61, 0x72, 0x73, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x6d, 0x65, + 0x6e, 0x74, 0x20, 0x74, 0x6f, 0x09, 0x09, 0x3c, 0x75, 0x6c, 0x20, 0x63, 0x6c, + 0x61, 0x73, 0x73, 0x3d, 0x22, 0x76, 0x69, 0x73, 0x75, 0x61, 0x6c, 0x69, 0x7a, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x31, 0x39, 0x74, 0x68, 0x20, 0x63, 0x65, 0x6e, + 0x74, 0x75, 0x72, 0x79, 0x2c, 0x70, 0x72, 0x61, 0x63, 0x74, 0x69, 0x74, 0x69, + 0x6f, 0x6e, 0x65, 0x72, 0x73, 0x74, 0x68, 0x61, 0x74, 0x20, 0x68, 0x65, 0x20, + 0x77, 0x6f, 0x75, 0x6c, 0x64, 0x61, 0x6e, 0x64, 0x20, 0x63, 0x6f, 0x6e, 0x74, + 0x69, 0x6e, 0x75, 0x65, 0x64, 0x6f, 0x63, 0x63, 0x75, 0x70, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x20, 0x6f, 0x66, 0x69, 0x73, 0x20, 0x64, 0x65, 0x66, 0x69, 0x6e, + 0x65, 0x64, 0x20, 0x61, 0x73, 0x63, 0x65, 0x6e, 0x74, 0x72, 0x65, 0x20, 0x6f, + 0x66, 0x20, 0x74, 0x68, 0x65, 0x74, 0x68, 0x65, 0x20, 0x61, 0x6d, 0x6f, 0x75, + 0x6e, 0x74, 0x20, 0x6f, 0x66, 0x3e, 0x3c, 0x64, 0x69, 0x76, 0x20, 0x73, 0x74, + 0x79, 0x6c, 0x65, 0x3d, 0x22, 0x65, 0x71, 0x75, 0x69, 0x76, 0x61, 0x6c, 0x65, + 0x6e, 0x74, 0x20, 0x6f, 0x66, 0x64, 0x69, 0x66, 0x66, 0x65, 0x72, 0x65, 0x6e, + 0x74, 0x69, 0x61, 0x74, 0x65, 0x62, 0x72, 0x6f, 0x75, 0x67, 0x68, 0x74, 0x20, + 0x61, 0x62, 0x6f, 0x75, 0x74, 0x6d, 0x61, 0x72, 0x67, 0x69, 0x6e, 0x2d, 0x6c, + 0x65, 0x66, 0x74, 0x3a, 0x20, 0x61, 0x75, 0x74, 0x6f, 0x6d, 0x61, 0x74, 0x69, + 0x63, 0x61, 0x6c, 0x6c, 0x79, 0x74, 0x68, 0x6f, 0x75, 0x67, 0x68, 0x74, 0x20, + 0x6f, 0x66, 0x20, 0x61, 0x73, 0x53, 0x6f, 0x6d, 0x65, 0x20, 0x6f, 0x66, 0x20, + 0x74, 0x68, 0x65, 0x73, 0x65, 0x0a, 0x3c, 0x64, 0x69, 0x76, 0x20, 0x63, 0x6c, + 0x61, 0x73, 0x73, 0x3d, 0x22, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x20, 0x63, 0x6c, + 0x61, 0x73, 0x73, 0x3d, 0x22, 0x72, 0x65, 0x70, 0x6c, 0x61, 0x63, 0x65, 0x64, + 0x20, 0x77, 0x69, 0x74, 0x68, 0x69, 0x73, 0x20, 0x6f, 0x6e, 0x65, 0x20, 0x6f, + 0x66, 0x20, 0x74, 0x68, 0x65, 0x65, 0x64, 0x75, 0x63, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x20, 0x61, 0x6e, 0x64, 0x69, 0x6e, 0x66, 0x6c, 0x75, 0x65, 0x6e, 0x63, + 0x65, 0x64, 0x20, 0x62, 0x79, 0x72, 0x65, 0x70, 0x75, 0x74, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x20, 0x61, 0x73, 0x0a, 0x3c, 0x6d, 0x65, 0x74, 0x61, 0x20, 0x6e, + 0x61, 0x6d, 0x65, 0x3d, 0x22, 0x61, 0x63, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x64, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3c, 0x2f, 0x64, 0x69, 0x76, 0x3e, 0x0a, 0x3c, + 0x2f, 0x64, 0x69, 0x76, 0x3e, 0x6c, 0x61, 0x72, 0x67, 0x65, 0x20, 0x70, 0x61, + 0x72, 0x74, 0x20, 0x6f, 0x66, 0x49, 0x6e, 0x73, 0x74, 0x69, 0x74, 0x75, 0x74, + 0x65, 0x20, 0x66, 0x6f, 0x72, 0x74, 0x68, 0x65, 0x20, 0x73, 0x6f, 0x2d, 0x63, + 0x61, 0x6c, 0x6c, 0x65, 0x64, 0x20, 0x61, 0x67, 0x61, 0x69, 0x6e, 0x73, 0x74, + 0x20, 0x74, 0x68, 0x65, 0x20, 0x49, 0x6e, 0x20, 0x74, 0x68, 0x69, 0x73, 0x20, + 0x63, 0x61, 0x73, 0x65, 0x2c, 0x77, 0x61, 0x73, 0x20, 0x61, 0x70, 0x70, 0x6f, + 0x69, 0x6e, 0x74, 0x65, 0x64, 0x63, 0x6c, 0x61, 0x69, 0x6d, 0x65, 0x64, 0x20, + 0x74, 0x6f, 0x20, 0x62, 0x65, 0x48, 0x6f, 0x77, 0x65, 0x76, 0x65, 0x72, 0x2c, + 0x20, 0x74, 0x68, 0x69, 0x73, 0x44, 0x65, 0x70, 0x61, 0x72, 0x74, 0x6d, 0x65, + 0x6e, 0x74, 0x20, 0x6f, 0x66, 0x74, 0x68, 0x65, 0x20, 0x72, 0x65, 0x6d, 0x61, + 0x69, 0x6e, 0x69, 0x6e, 0x67, 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, 0x20, 0x6f, + 0x6e, 0x20, 0x74, 0x68, 0x65, 0x70, 0x61, 0x72, 0x74, 0x69, 0x63, 0x75, 0x6c, + 0x61, 0x72, 0x6c, 0x79, 0x20, 0x64, 0x65, 0x61, 0x6c, 0x20, 0x77, 0x69, 0x74, + 0x68, 0x20, 0x74, 0x68, 0x65, 0x0a, 0x3c, 0x64, 0x69, 0x76, 0x20, 0x73, 0x74, + 0x79, 0x6c, 0x65, 0x3d, 0x22, 0x61, 0x6c, 0x6d, 0x6f, 0x73, 0x74, 0x20, 0x61, + 0x6c, 0x77, 0x61, 0x79, 0x73, 0x61, 0x72, 0x65, 0x20, 0x63, 0x75, 0x72, 0x72, + 0x65, 0x6e, 0x74, 0x6c, 0x79, 0x65, 0x78, 0x70, 0x72, 0x65, 0x73, 0x73, 0x69, + 0x6f, 0x6e, 0x20, 0x6f, 0x66, 0x70, 0x68, 0x69, 0x6c, 0x6f, 0x73, 0x6f, 0x70, + 0x68, 0x79, 0x20, 0x6f, 0x66, 0x66, 0x6f, 0x72, 0x20, 0x6d, 0x6f, 0x72, 0x65, + 0x20, 0x74, 0x68, 0x61, 0x6e, 0x63, 0x69, 0x76, 0x69, 0x6c, 0x69, 0x7a, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x6f, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x69, + 0x73, 0x6c, 0x61, 0x6e, 0x64, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x65, 0x64, + 0x49, 0x6e, 0x64, 0x65, 0x78, 0x63, 0x61, 0x6e, 0x20, 0x72, 0x65, 0x73, 0x75, + 0x6c, 0x74, 0x20, 0x69, 0x6e, 0x22, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3d, + 0x22, 0x22, 0x20, 0x2f, 0x3e, 0x74, 0x68, 0x65, 0x20, 0x73, 0x74, 0x72, 0x75, + 0x63, 0x74, 0x75, 0x72, 0x65, 0x20, 0x2f, 0x3e, 0x3c, 0x2f, 0x61, 0x3e, 0x3c, + 0x2f, 0x64, 0x69, 0x76, 0x3e, 0x4d, 0x61, 0x6e, 0x79, 0x20, 0x6f, 0x66, 0x20, + 0x74, 0x68, 0x65, 0x73, 0x65, 0x63, 0x61, 0x75, 0x73, 0x65, 0x64, 0x20, 0x62, + 0x79, 0x20, 0x74, 0x68, 0x65, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x55, + 0x6e, 0x69, 0x74, 0x65, 0x64, 0x73, 0x70, 0x61, 0x6e, 0x20, 0x63, 0x6c, 0x61, + 0x73, 0x73, 0x3d, 0x22, 0x6d, 0x63, 0x61, 0x6e, 0x20, 0x62, 0x65, 0x20, 0x74, + 0x72, 0x61, 0x63, 0x65, 0x64, 0x69, 0x73, 0x20, 0x72, 0x65, 0x6c, 0x61, 0x74, + 0x65, 0x64, 0x20, 0x74, 0x6f, 0x62, 0x65, 0x63, 0x61, 0x6d, 0x65, 0x20, 0x6f, + 0x6e, 0x65, 0x20, 0x6f, 0x66, 0x69, 0x73, 0x20, 0x66, 0x72, 0x65, 0x71, 0x75, + 0x65, 0x6e, 0x74, 0x6c, 0x79, 0x6c, 0x69, 0x76, 0x69, 0x6e, 0x67, 0x20, 0x69, + 0x6e, 0x20, 0x74, 0x68, 0x65, 0x74, 0x68, 0x65, 0x6f, 0x72, 0x65, 0x74, 0x69, + 0x63, 0x61, 0x6c, 0x6c, 0x79, 0x46, 0x6f, 0x6c, 0x6c, 0x6f, 0x77, 0x69, 0x6e, + 0x67, 0x20, 0x74, 0x68, 0x65, 0x52, 0x65, 0x76, 0x6f, 0x6c, 0x75, 0x74, 0x69, + 0x6f, 0x6e, 0x61, 0x72, 0x79, 0x67, 0x6f, 0x76, 0x65, 0x72, 0x6e, 0x6d, 0x65, + 0x6e, 0x74, 0x20, 0x69, 0x6e, 0x69, 0x73, 0x20, 0x64, 0x65, 0x74, 0x65, 0x72, + 0x6d, 0x69, 0x6e, 0x65, 0x64, 0x74, 0x68, 0x65, 0x20, 0x70, 0x6f, 0x6c, 0x69, + 0x74, 0x69, 0x63, 0x61, 0x6c, 0x69, 0x6e, 0x74, 0x72, 0x6f, 0x64, 0x75, 0x63, + 0x65, 0x64, 0x20, 0x69, 0x6e, 0x73, 0x75, 0x66, 0x66, 0x69, 0x63, 0x69, 0x65, + 0x6e, 0x74, 0x20, 0x74, 0x6f, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, + 0x69, 0x6f, 0x6e, 0x22, 0x3e, 0x73, 0x68, 0x6f, 0x72, 0x74, 0x20, 0x73, 0x74, + 0x6f, 0x72, 0x69, 0x65, 0x73, 0x73, 0x65, 0x70, 0x61, 0x72, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x20, 0x6f, 0x66, 0x61, 0x73, 0x20, 0x74, 0x6f, 0x20, 0x77, 0x68, + 0x65, 0x74, 0x68, 0x65, 0x72, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x20, 0x66, 0x6f, + 0x72, 0x20, 0x69, 0x74, 0x73, 0x77, 0x61, 0x73, 0x20, 0x69, 0x6e, 0x69, 0x74, + 0x69, 0x61, 0x6c, 0x6c, 0x79, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x3a, + 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x69, 0x73, 0x20, 0x61, 0x6e, 0x20, 0x65, 0x78, + 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x68, 0x65, 0x20, 0x70, 0x72, 0x69, 0x6e, + 0x63, 0x69, 0x70, 0x61, 0x6c, 0x63, 0x6f, 0x6e, 0x73, 0x69, 0x73, 0x74, 0x73, + 0x20, 0x6f, 0x66, 0x20, 0x61, 0x72, 0x65, 0x63, 0x6f, 0x67, 0x6e, 0x69, 0x7a, + 0x65, 0x64, 0x20, 0x61, 0x73, 0x2f, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0x3c, 0x2f, + 0x68, 0x74, 0x6d, 0x6c, 0x3e, 0x61, 0x20, 0x73, 0x75, 0x62, 0x73, 0x74, 0x61, + 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x72, 0x65, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x72, + 0x75, 0x63, 0x74, 0x65, 0x64, 0x68, 0x65, 0x61, 0x64, 0x20, 0x6f, 0x66, 0x20, + 0x73, 0x74, 0x61, 0x74, 0x65, 0x72, 0x65, 0x73, 0x69, 0x73, 0x74, 0x61, 0x6e, + 0x63, 0x65, 0x20, 0x74, 0x6f, 0x75, 0x6e, 0x64, 0x65, 0x72, 0x67, 0x72, 0x61, + 0x64, 0x75, 0x61, 0x74, 0x65, 0x54, 0x68, 0x65, 0x72, 0x65, 0x20, 0x61, 0x72, + 0x65, 0x20, 0x74, 0x77, 0x6f, 0x67, 0x72, 0x61, 0x76, 0x69, 0x74, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x61, 0x72, 0x65, 0x20, 0x64, 0x65, 0x73, 0x63, + 0x72, 0x69, 0x62, 0x65, 0x64, 0x69, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x69, 0x6f, + 0x6e, 0x61, 0x6c, 0x6c, 0x79, 0x73, 0x65, 0x72, 0x76, 0x65, 0x64, 0x20, 0x61, + 0x73, 0x20, 0x74, 0x68, 0x65, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x22, 0x68, + 0x65, 0x61, 0x64, 0x65, 0x72, 0x6f, 0x70, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, + 0x6f, 0x6e, 0x20, 0x74, 0x6f, 0x66, 0x75, 0x6e, 0x64, 0x61, 0x6d, 0x65, 0x6e, + 0x74, 0x61, 0x6c, 0x6c, 0x79, 0x64, 0x6f, 0x6d, 0x69, 0x6e, 0x61, 0x74, 0x65, + 0x64, 0x20, 0x74, 0x68, 0x65, 0x61, 0x6e, 0x64, 0x20, 0x74, 0x68, 0x65, 0x20, + 0x6f, 0x74, 0x68, 0x65, 0x72, 0x61, 0x6c, 0x6c, 0x69, 0x61, 0x6e, 0x63, 0x65, + 0x20, 0x77, 0x69, 0x74, 0x68, 0x77, 0x61, 0x73, 0x20, 0x66, 0x6f, 0x72, 0x63, + 0x65, 0x64, 0x20, 0x74, 0x6f, 0x72, 0x65, 0x73, 0x70, 0x65, 0x63, 0x74, 0x69, + 0x76, 0x65, 0x6c, 0x79, 0x2c, 0x61, 0x6e, 0x64, 0x20, 0x70, 0x6f, 0x6c, 0x69, + 0x74, 0x69, 0x63, 0x61, 0x6c, 0x69, 0x6e, 0x20, 0x73, 0x75, 0x70, 0x70, 0x6f, + 0x72, 0x74, 0x20, 0x6f, 0x66, 0x70, 0x65, 0x6f, 0x70, 0x6c, 0x65, 0x20, 0x69, + 0x6e, 0x20, 0x74, 0x68, 0x65, 0x32, 0x30, 0x74, 0x68, 0x20, 0x63, 0x65, 0x6e, + 0x74, 0x75, 0x72, 0x79, 0x2e, 0x61, 0x6e, 0x64, 0x20, 0x70, 0x75, 0x62, 0x6c, + 0x69, 0x73, 0x68, 0x65, 0x64, 0x6c, 0x6f, 0x61, 0x64, 0x43, 0x68, 0x61, 0x72, + 0x74, 0x62, 0x65, 0x61, 0x74, 0x74, 0x6f, 0x20, 0x75, 0x6e, 0x64, 0x65, 0x72, + 0x73, 0x74, 0x61, 0x6e, 0x64, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x20, 0x73, + 0x74, 0x61, 0x74, 0x65, 0x73, 0x65, 0x6e, 0x76, 0x69, 0x72, 0x6f, 0x6e, 0x6d, + 0x65, 0x6e, 0x74, 0x61, 0x6c, 0x66, 0x69, 0x72, 0x73, 0x74, 0x20, 0x68, 0x61, + 0x6c, 0x66, 0x20, 0x6f, 0x66, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x72, 0x69, 0x65, + 0x73, 0x20, 0x61, 0x6e, 0x64, 0x61, 0x72, 0x63, 0x68, 0x69, 0x74, 0x65, 0x63, + 0x74, 0x75, 0x72, 0x61, 0x6c, 0x62, 0x65, 0x20, 0x63, 0x6f, 0x6e, 0x73, 0x69, + 0x64, 0x65, 0x72, 0x65, 0x64, 0x63, 0x68, 0x61, 0x72, 0x61, 0x63, 0x74, 0x65, + 0x72, 0x69, 0x7a, 0x65, 0x64, 0x63, 0x6c, 0x65, 0x61, 0x72, 0x49, 0x6e, 0x74, + 0x65, 0x72, 0x76, 0x61, 0x6c, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, + 0x61, 0x74, 0x69, 0x76, 0x65, 0x46, 0x65, 0x64, 0x65, 0x72, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x20, 0x6f, 0x66, 0x77, 0x61, 0x73, 0x20, 0x73, 0x75, 0x63, 0x63, + 0x65, 0x65, 0x64, 0x65, 0x64, 0x61, 0x6e, 0x64, 0x20, 0x74, 0x68, 0x65, 0x72, + 0x65, 0x20, 0x61, 0x72, 0x65, 0x61, 0x20, 0x63, 0x6f, 0x6e, 0x73, 0x65, 0x71, + 0x75, 0x65, 0x6e, 0x63, 0x65, 0x74, 0x68, 0x65, 0x20, 0x50, 0x72, 0x65, 0x73, + 0x69, 0x64, 0x65, 0x6e, 0x74, 0x61, 0x6c, 0x73, 0x6f, 0x20, 0x69, 0x6e, 0x63, + 0x6c, 0x75, 0x64, 0x65, 0x64, 0x66, 0x72, 0x65, 0x65, 0x20, 0x73, 0x6f, 0x66, + 0x74, 0x77, 0x61, 0x72, 0x65, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x69, + 0x6f, 0x6e, 0x20, 0x6f, 0x66, 0x64, 0x65, 0x76, 0x65, 0x6c, 0x6f, 0x70, 0x65, + 0x64, 0x20, 0x74, 0x68, 0x65, 0x77, 0x61, 0x73, 0x20, 0x64, 0x65, 0x73, 0x74, + 0x72, 0x6f, 0x79, 0x65, 0x64, 0x61, 0x77, 0x61, 0x79, 0x20, 0x66, 0x72, 0x6f, + 0x6d, 0x20, 0x74, 0x68, 0x65, 0x3b, 0x0a, 0x3c, 0x2f, 0x73, 0x63, 0x72, 0x69, + 0x70, 0x74, 0x3e, 0x0a, 0x3c, 0x61, 0x6c, 0x74, 0x68, 0x6f, 0x75, 0x67, 0x68, + 0x20, 0x74, 0x68, 0x65, 0x79, 0x66, 0x6f, 0x6c, 0x6c, 0x6f, 0x77, 0x65, 0x64, + 0x20, 0x62, 0x79, 0x20, 0x61, 0x6d, 0x6f, 0x72, 0x65, 0x20, 0x70, 0x6f, 0x77, + 0x65, 0x72, 0x66, 0x75, 0x6c, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x65, 0x64, + 0x20, 0x69, 0x6e, 0x20, 0x61, 0x55, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x69, + 0x74, 0x79, 0x20, 0x6f, 0x66, 0x48, 0x6f, 0x77, 0x65, 0x76, 0x65, 0x72, 0x2c, + 0x20, 0x6d, 0x61, 0x6e, 0x79, 0x74, 0x68, 0x65, 0x20, 0x70, 0x72, 0x65, 0x73, + 0x69, 0x64, 0x65, 0x6e, 0x74, 0x48, 0x6f, 0x77, 0x65, 0x76, 0x65, 0x72, 0x2c, + 0x20, 0x73, 0x6f, 0x6d, 0x65, 0x69, 0x73, 0x20, 0x74, 0x68, 0x6f, 0x75, 0x67, + 0x68, 0x74, 0x20, 0x74, 0x6f, 0x75, 0x6e, 0x74, 0x69, 0x6c, 0x20, 0x74, 0x68, + 0x65, 0x20, 0x65, 0x6e, 0x64, 0x77, 0x61, 0x73, 0x20, 0x61, 0x6e, 0x6e, 0x6f, + 0x75, 0x6e, 0x63, 0x65, 0x64, 0x61, 0x72, 0x65, 0x20, 0x69, 0x6d, 0x70, 0x6f, + 0x72, 0x74, 0x61, 0x6e, 0x74, 0x61, 0x6c, 0x73, 0x6f, 0x20, 0x69, 0x6e, 0x63, + 0x6c, 0x75, 0x64, 0x65, 0x73, 0x3e, 0x3c, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x20, + 0x74, 0x79, 0x70, 0x65, 0x3d, 0x74, 0x68, 0x65, 0x20, 0x63, 0x65, 0x6e, 0x74, + 0x65, 0x72, 0x20, 0x6f, 0x66, 0x20, 0x44, 0x4f, 0x20, 0x4e, 0x4f, 0x54, 0x20, + 0x41, 0x4c, 0x54, 0x45, 0x52, 0x75, 0x73, 0x65, 0x64, 0x20, 0x74, 0x6f, 0x20, + 0x72, 0x65, 0x66, 0x65, 0x72, 0x74, 0x68, 0x65, 0x6d, 0x65, 0x73, 0x2f, 0x3f, + 0x73, 0x6f, 0x72, 0x74, 0x3d, 0x74, 0x68, 0x61, 0x74, 0x20, 0x68, 0x61, 0x64, + 0x20, 0x62, 0x65, 0x65, 0x6e, 0x74, 0x68, 0x65, 0x20, 0x62, 0x61, 0x73, 0x69, + 0x73, 0x20, 0x66, 0x6f, 0x72, 0x68, 0x61, 0x73, 0x20, 0x64, 0x65, 0x76, 0x65, + 0x6c, 0x6f, 0x70, 0x65, 0x64, 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x73, + 0x75, 0x6d, 0x6d, 0x65, 0x72, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x72, 0x61, 0x74, + 0x69, 0x76, 0x65, 0x6c, 0x79, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, + 0x64, 0x20, 0x74, 0x68, 0x65, 0x73, 0x75, 0x63, 0x68, 0x20, 0x61, 0x73, 0x20, + 0x74, 0x68, 0x6f, 0x73, 0x65, 0x74, 0x68, 0x65, 0x20, 0x72, 0x65, 0x73, 0x75, + 0x6c, 0x74, 0x69, 0x6e, 0x67, 0x69, 0x73, 0x20, 0x69, 0x6d, 0x70, 0x6f, 0x73, + 0x73, 0x69, 0x62, 0x6c, 0x65, 0x76, 0x61, 0x72, 0x69, 0x6f, 0x75, 0x73, 0x20, + 0x6f, 0x74, 0x68, 0x65, 0x72, 0x53, 0x6f, 0x75, 0x74, 0x68, 0x20, 0x41, 0x66, + 0x72, 0x69, 0x63, 0x61, 0x6e, 0x68, 0x61, 0x76, 0x65, 0x20, 0x74, 0x68, 0x65, + 0x20, 0x73, 0x61, 0x6d, 0x65, 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, 0x69, 0x76, + 0x65, 0x6e, 0x65, 0x73, 0x73, 0x69, 0x6e, 0x20, 0x77, 0x68, 0x69, 0x63, 0x68, + 0x20, 0x63, 0x61, 0x73, 0x65, 0x3b, 0x20, 0x74, 0x65, 0x78, 0x74, 0x2d, 0x61, + 0x6c, 0x69, 0x67, 0x6e, 0x3a, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x75, 0x72, + 0x65, 0x20, 0x61, 0x6e, 0x64, 0x3b, 0x20, 0x62, 0x61, 0x63, 0x6b, 0x67, 0x72, + 0x6f, 0x75, 0x6e, 0x64, 0x3a, 0x72, 0x65, 0x67, 0x61, 0x72, 0x64, 0x69, 0x6e, + 0x67, 0x20, 0x74, 0x68, 0x65, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, + 0x64, 0x20, 0x74, 0x68, 0x65, 0x69, 0x73, 0x20, 0x61, 0x6c, 0x73, 0x6f, 0x20, + 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x73, 0x74, 0x79, 0x6c, 0x65, 0x3d, 0x22, 0x6d, + 0x61, 0x72, 0x67, 0x69, 0x6e, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x69, 0x6e, + 0x67, 0x20, 0x74, 0x68, 0x65, 0x62, 0x61, 0x68, 0x61, 0x73, 0x61, 0x20, 0x4d, + 0x65, 0x6c, 0x61, 0x79, 0x75, 0x6e, 0x6f, 0x72, 0x73, 0x6b, 0x20, 0x62, 0x6f, + 0x6b, 0x6d, 0xc3, 0xa5, 0x6c, 0x6e, 0x6f, 0x72, 0x73, 0x6b, 0x20, 0x6e, 0x79, + 0x6e, 0x6f, 0x72, 0x73, 0x6b, 0x73, 0x6c, 0x6f, 0x76, 0x65, 0x6e, 0xc5, 0xa1, + 0xc4, 0x8d, 0x69, 0x6e, 0x61, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x63, + 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x63, 0x61, 0x6c, 0x69, 0x66, 0x69, 0x63, 0x61, + 0x63, 0x69, 0xc3, 0xb3, 0x6e, 0x63, 0x6f, 0x6d, 0x75, 0x6e, 0x69, 0x63, 0x61, + 0x63, 0x69, 0xc3, 0xb3, 0x6e, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x72, 0x75, 0x63, + 0x63, 0x69, 0xc3, 0xb3, 0x6e, 0x22, 0x3e, 0x3c, 0x64, 0x69, 0x76, 0x20, 0x63, + 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x22, 0x64, 0x69, 0x73, 0x61, 0x6d, 0x62, 0x69, + 0x67, 0x75, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, + 0x4e, 0x61, 0x6d, 0x65, 0x27, 0x2c, 0x20, 0x27, 0x61, 0x64, 0x6d, 0x69, 0x6e, + 0x69, 0x73, 0x74, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x69, 0x6d, 0x75, + 0x6c, 0x74, 0x61, 0x6e, 0x65, 0x6f, 0x75, 0x73, 0x6c, 0x79, 0x74, 0x72, 0x61, + 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x6e, + 0x74, 0x65, 0x72, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x20, 0x6d, + 0x61, 0x72, 0x67, 0x69, 0x6e, 0x2d, 0x62, 0x6f, 0x74, 0x74, 0x6f, 0x6d, 0x3a, + 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x69, 0x62, 0x69, 0x6c, 0x69, 0x74, + 0x79, 0x3c, 0x21, 0x5b, 0x65, 0x6e, 0x64, 0x69, 0x66, 0x5d, 0x2d, 0x2d, 0x3e, + 0x0a, 0x3c, 0x2f, 0x3e, 0x3c, 0x6d, 0x65, 0x74, 0x61, 0x20, 0x6e, 0x61, 0x6d, + 0x65, 0x3d, 0x22, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x69, 0x6e, 0x66, 0x72, 0x61, 0x73, 0x74, 0x72, 0x75, + 0x63, 0x74, 0x75, 0x72, 0x65, 0x72, 0x65, 0x70, 0x72, 0x65, 0x73, 0x65, 0x6e, + 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x2d, + 0x62, 0x6f, 0x74, 0x74, 0x6f, 0x6d, 0x3a, 0x3c, 0x2f, 0x68, 0x65, 0x61, 0x64, + 0x3e, 0x0a, 0x3c, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0x3d, 0x68, 0x74, 0x74, 0x70, + 0x25, 0x33, 0x41, 0x25, 0x32, 0x46, 0x25, 0x32, 0x46, 0x3c, 0x66, 0x6f, 0x72, + 0x6d, 0x20, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x3d, 0x22, 0x6d, 0x65, 0x74, + 0x68, 0x6f, 0x64, 0x3d, 0x22, 0x70, 0x6f, 0x73, 0x74, 0x22, 0x20, 0x2f, 0x66, + 0x61, 0x76, 0x69, 0x63, 0x6f, 0x6e, 0x2e, 0x69, 0x63, 0x6f, 0x22, 0x20, 0x7d, + 0x29, 0x3b, 0x0a, 0x3c, 0x2f, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x3e, 0x0a, + 0x2e, 0x73, 0x65, 0x74, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, + 0x28, 0x41, 0x64, 0x6d, 0x69, 0x6e, 0x69, 0x73, 0x74, 0x72, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x3d, 0x20, 0x6e, 0x65, 0x77, 0x20, 0x41, 0x72, 0x72, 0x61, 0x79, + 0x28, 0x29, 0x3b, 0x3c, 0x21, 0x5b, 0x65, 0x6e, 0x64, 0x69, 0x66, 0x5d, 0x2d, + 0x2d, 0x3e, 0x0d, 0x0a, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x3a, 0x62, + 0x6c, 0x6f, 0x63, 0x6b, 0x3b, 0x55, 0x6e, 0x66, 0x6f, 0x72, 0x74, 0x75, 0x6e, + 0x61, 0x74, 0x65, 0x6c, 0x79, 0x2c, 0x22, 0x3e, 0x26, 0x6e, 0x62, 0x73, 0x70, + 0x3b, 0x3c, 0x2f, 0x64, 0x69, 0x76, 0x3e, 0x2f, 0x66, 0x61, 0x76, 0x69, 0x63, + 0x6f, 0x6e, 0x2e, 0x69, 0x63, 0x6f, 0x22, 0x3e, 0x3d, 0x27, 0x73, 0x74, 0x79, + 0x6c, 0x65, 0x73, 0x68, 0x65, 0x65, 0x74, 0x27, 0x20, 0x69, 0x64, 0x65, 0x6e, + 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2c, 0x20, 0x66, + 0x6f, 0x72, 0x20, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x2c, 0x3c, 0x6c, + 0x69, 0x3e, 0x3c, 0x61, 0x20, 0x68, 0x72, 0x65, 0x66, 0x3d, 0x22, 0x2f, 0x61, + 0x6e, 0x20, 0x61, 0x6c, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x74, 0x69, 0x76, 0x65, + 0x61, 0x73, 0x20, 0x61, 0x20, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x20, 0x6f, + 0x66, 0x70, 0x74, 0x22, 0x3e, 0x3c, 0x2f, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, + 0x3e, 0x0a, 0x74, 0x79, 0x70, 0x65, 0x3d, 0x22, 0x73, 0x75, 0x62, 0x6d, 0x69, + 0x74, 0x22, 0x20, 0x0a, 0x28, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x28, 0x29, 0x20, 0x7b, 0x72, 0x65, 0x63, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x64, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x66, 0x6f, 0x72, 0x6d, 0x20, 0x61, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x3d, 0x22, 0x2f, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x6f, + 0x72, 0x6d, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x72, 0x65, 0x63, 0x6f, 0x6e, 0x73, + 0x74, 0x72, 0x75, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x73, 0x74, 0x79, 0x6c, + 0x65, 0x2e, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x20, 0x41, 0x63, 0x63, + 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x67, 0x20, 0x74, 0x6f, 0x20, 0x68, 0x69, 0x64, + 0x64, 0x65, 0x6e, 0x22, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x3d, 0x22, 0x61, 0x6c, + 0x6f, 0x6e, 0x67, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x74, 0x68, 0x65, 0x64, + 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x62, 0x6f, 0x64, 0x79, 0x2e, + 0x61, 0x70, 0x70, 0x72, 0x6f, 0x78, 0x69, 0x6d, 0x61, 0x74, 0x65, 0x6c, 0x79, + 0x20, 0x43, 0x6f, 0x6d, 0x6d, 0x75, 0x6e, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x73, 0x70, 0x6f, 0x73, 0x74, 0x22, 0x20, 0x61, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x3d, 0x22, 0x6d, 0x65, 0x61, 0x6e, 0x69, 0x6e, 0x67, 0x20, 0x26, 0x71, + 0x75, 0x6f, 0x74, 0x3b, 0x2d, 0x2d, 0x3c, 0x21, 0x5b, 0x65, 0x6e, 0x64, 0x69, + 0x66, 0x5d, 0x2d, 0x2d, 0x3e, 0x50, 0x72, 0x69, 0x6d, 0x65, 0x20, 0x4d, 0x69, + 0x6e, 0x69, 0x73, 0x74, 0x65, 0x72, 0x63, 0x68, 0x61, 0x72, 0x61, 0x63, 0x74, + 0x65, 0x72, 0x69, 0x73, 0x74, 0x69, 0x63, 0x3c, 0x2f, 0x61, 0x3e, 0x20, 0x3c, + 0x61, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x74, 0x68, 0x65, 0x20, 0x68, + 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x20, 0x6f, 0x66, 0x20, 0x6f, 0x6e, 0x6d, + 0x6f, 0x75, 0x73, 0x65, 0x6f, 0x76, 0x65, 0x72, 0x3d, 0x22, 0x74, 0x68, 0x65, + 0x20, 0x67, 0x6f, 0x76, 0x65, 0x72, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x68, 0x72, + 0x65, 0x66, 0x3d, 0x22, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x77, + 0x61, 0x73, 0x20, 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x61, 0x6c, 0x6c, 0x79, + 0x77, 0x61, 0x73, 0x20, 0x69, 0x6e, 0x74, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x65, + 0x64, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x72, 0x65, 0x70, 0x72, 0x65, 0x73, 0x65, 0x6e, 0x74, 0x61, 0x74, + 0x69, 0x76, 0x65, 0x61, 0x72, 0x65, 0x20, 0x63, 0x6f, 0x6e, 0x73, 0x69, 0x64, + 0x65, 0x72, 0x65, 0x64, 0x3c, 0x21, 0x5b, 0x65, 0x6e, 0x64, 0x69, 0x66, 0x5d, + 0x2d, 0x2d, 0x3e, 0x0a, 0x0a, 0x64, 0x65, 0x70, 0x65, 0x6e, 0x64, 0x73, 0x20, + 0x6f, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x55, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, + 0x69, 0x74, 0x79, 0x20, 0x6f, 0x66, 0x20, 0x69, 0x6e, 0x20, 0x63, 0x6f, 0x6e, + 0x74, 0x72, 0x61, 0x73, 0x74, 0x20, 0x74, 0x6f, 0x20, 0x70, 0x6c, 0x61, 0x63, + 0x65, 0x68, 0x6f, 0x6c, 0x64, 0x65, 0x72, 0x3d, 0x22, 0x69, 0x6e, 0x20, 0x74, + 0x68, 0x65, 0x20, 0x63, 0x61, 0x73, 0x65, 0x20, 0x6f, 0x66, 0x69, 0x6e, 0x74, + 0x65, 0x72, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x20, 0x63, 0x6f, + 0x6e, 0x73, 0x74, 0x69, 0x74, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x73, + 0x74, 0x79, 0x6c, 0x65, 0x3d, 0x22, 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x2d, + 0x3a, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x29, 0x20, + 0x7b, 0x42, 0x65, 0x63, 0x61, 0x75, 0x73, 0x65, 0x20, 0x6f, 0x66, 0x20, 0x74, + 0x68, 0x65, 0x2d, 0x73, 0x74, 0x72, 0x69, 0x63, 0x74, 0x2e, 0x64, 0x74, 0x64, + 0x22, 0x3e, 0x0a, 0x3c, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x20, 0x63, 0x6c, 0x61, + 0x73, 0x73, 0x3d, 0x22, 0x61, 0x63, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x6e, 0x69, + 0x65, 0x64, 0x20, 0x62, 0x79, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x20, + 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x3c, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, + 0x20, 0x73, 0x72, 0x63, 0x3d, 0x22, 0x2f, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, + 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x74, 0x68, 0x65, 0x20, 0x70, + 0x65, 0x6f, 0x70, 0x6c, 0x65, 0x20, 0x69, 0x6e, 0x20, 0x69, 0x6e, 0x20, 0x61, + 0x64, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x74, 0x6f, 0x73, 0x29, 0x3b, + 0x20, 0x6a, 0x73, 0x2e, 0x69, 0x64, 0x20, 0x3d, 0x20, 0x69, 0x64, 0x22, 0x20, + 0x77, 0x69, 0x64, 0x74, 0x68, 0x3d, 0x22, 0x31, 0x30, 0x30, 0x25, 0x22, 0x72, + 0x65, 0x67, 0x61, 0x72, 0x64, 0x69, 0x6e, 0x67, 0x20, 0x74, 0x68, 0x65, 0x20, + 0x52, 0x6f, 0x6d, 0x61, 0x6e, 0x20, 0x43, 0x61, 0x74, 0x68, 0x6f, 0x6c, 0x69, + 0x63, 0x61, 0x6e, 0x20, 0x69, 0x6e, 0x64, 0x65, 0x70, 0x65, 0x6e, 0x64, 0x65, + 0x6e, 0x74, 0x66, 0x6f, 0x6c, 0x6c, 0x6f, 0x77, 0x69, 0x6e, 0x67, 0x20, 0x74, + 0x68, 0x65, 0x20, 0x2e, 0x67, 0x69, 0x66, 0x22, 0x20, 0x77, 0x69, 0x64, 0x74, + 0x68, 0x3d, 0x22, 0x31, 0x74, 0x68, 0x65, 0x20, 0x66, 0x6f, 0x6c, 0x6c, 0x6f, + 0x77, 0x69, 0x6e, 0x67, 0x20, 0x64, 0x69, 0x73, 0x63, 0x72, 0x69, 0x6d, 0x69, + 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x72, 0x63, 0x68, 0x61, 0x65, 0x6f, + 0x6c, 0x6f, 0x67, 0x69, 0x63, 0x61, 0x6c, 0x70, 0x72, 0x69, 0x6d, 0x65, 0x20, + 0x6d, 0x69, 0x6e, 0x69, 0x73, 0x74, 0x65, 0x72, 0x2e, 0x6a, 0x73, 0x22, 0x3e, + 0x3c, 0x2f, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x3e, 0x63, 0x6f, 0x6d, 0x62, + 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6f, 0x66, 0x20, 0x6d, 0x61, + 0x72, 0x67, 0x69, 0x6e, 0x77, 0x69, 0x64, 0x74, 0x68, 0x3d, 0x22, 0x63, 0x72, + 0x65, 0x61, 0x74, 0x65, 0x45, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x28, 0x77, + 0x2e, 0x61, 0x74, 0x74, 0x61, 0x63, 0x68, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x28, + 0x3c, 0x2f, 0x61, 0x3e, 0x3c, 0x2f, 0x74, 0x64, 0x3e, 0x3c, 0x2f, 0x74, 0x72, + 0x3e, 0x73, 0x72, 0x63, 0x3d, 0x22, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, + 0x2f, 0x61, 0x49, 0x6e, 0x20, 0x70, 0x61, 0x72, 0x74, 0x69, 0x63, 0x75, 0x6c, + 0x61, 0x72, 0x2c, 0x20, 0x61, 0x6c, 0x69, 0x67, 0x6e, 0x3d, 0x22, 0x6c, 0x65, + 0x66, 0x74, 0x22, 0x20, 0x43, 0x7a, 0x65, 0x63, 0x68, 0x20, 0x52, 0x65, 0x70, + 0x75, 0x62, 0x6c, 0x69, 0x63, 0x55, 0x6e, 0x69, 0x74, 0x65, 0x64, 0x20, 0x4b, + 0x69, 0x6e, 0x67, 0x64, 0x6f, 0x6d, 0x63, 0x6f, 0x72, 0x72, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x64, 0x65, 0x6e, 0x63, 0x65, 0x63, 0x6f, 0x6e, 0x63, 0x6c, 0x75, + 0x64, 0x65, 0x64, 0x20, 0x74, 0x68, 0x61, 0x74, 0x2e, 0x68, 0x74, 0x6d, 0x6c, + 0x22, 0x20, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x3d, 0x22, 0x28, 0x66, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x29, 0x20, 0x7b, 0x63, 0x6f, 0x6d, + 0x65, 0x73, 0x20, 0x66, 0x72, 0x6f, 0x6d, 0x20, 0x74, 0x68, 0x65, 0x61, 0x70, + 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6f, 0x66, 0x3c, + 0x73, 0x70, 0x61, 0x6e, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x22, 0x73, + 0x62, 0x65, 0x6c, 0x69, 0x65, 0x76, 0x65, 0x64, 0x20, 0x74, 0x6f, 0x20, 0x62, + 0x65, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x28, 0x27, 0x73, 0x63, 0x72, 0x69, 0x70, + 0x74, 0x27, 0x3c, 0x2f, 0x61, 0x3e, 0x0a, 0x3c, 0x2f, 0x6c, 0x69, 0x3e, 0x0a, + 0x3c, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x79, 0x20, 0x64, 0x69, 0x66, 0x66, 0x65, + 0x72, 0x65, 0x6e, 0x74, 0x3e, 0x3c, 0x73, 0x70, 0x61, 0x6e, 0x20, 0x63, 0x6c, + 0x61, 0x73, 0x73, 0x3d, 0x22, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x76, + 0x61, 0x6c, 0x75, 0x65, 0x3d, 0x22, 0x28, 0x61, 0x6c, 0x73, 0x6f, 0x20, 0x6b, + 0x6e, 0x6f, 0x77, 0x6e, 0x20, 0x61, 0x73, 0x09, 0x3c, 0x6c, 0x69, 0x3e, 0x3c, + 0x61, 0x20, 0x68, 0x72, 0x65, 0x66, 0x3d, 0x22, 0x3e, 0x3c, 0x69, 0x6e, 0x70, + 0x75, 0x74, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x3d, 0x22, 0x73, 0x65, 0x70, 0x61, + 0x72, 0x61, 0x74, 0x65, 0x64, 0x20, 0x66, 0x72, 0x6f, 0x6d, 0x72, 0x65, 0x66, + 0x65, 0x72, 0x72, 0x65, 0x64, 0x20, 0x74, 0x6f, 0x20, 0x61, 0x73, 0x20, 0x76, + 0x61, 0x6c, 0x69, 0x67, 0x6e, 0x3d, 0x22, 0x74, 0x6f, 0x70, 0x22, 0x3e, 0x66, + 0x6f, 0x75, 0x6e, 0x64, 0x65, 0x72, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, + 0x61, 0x74, 0x74, 0x65, 0x6d, 0x70, 0x74, 0x69, 0x6e, 0x67, 0x20, 0x74, 0x6f, + 0x20, 0x63, 0x61, 0x72, 0x62, 0x6f, 0x6e, 0x20, 0x64, 0x69, 0x6f, 0x78, 0x69, + 0x64, 0x65, 0x0a, 0x0a, 0x3c, 0x64, 0x69, 0x76, 0x20, 0x63, 0x6c, 0x61, 0x73, + 0x73, 0x3d, 0x22, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x22, 0x73, 0x65, 0x61, + 0x72, 0x63, 0x68, 0x2d, 0x2f, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0x0a, 0x3c, 0x2f, + 0x68, 0x74, 0x6d, 0x6c, 0x3e, 0x6f, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x75, 0x6e, + 0x69, 0x74, 0x79, 0x20, 0x74, 0x6f, 0x63, 0x6f, 0x6d, 0x6d, 0x75, 0x6e, 0x69, + 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x3c, 0x2f, 0x68, 0x65, 0x61, 0x64, + 0x3e, 0x0d, 0x0a, 0x3c, 0x62, 0x6f, 0x64, 0x79, 0x20, 0x73, 0x74, 0x79, 0x6c, + 0x65, 0x3d, 0x22, 0x77, 0x69, 0x64, 0x74, 0x68, 0x3a, 0x54, 0x69, 0xe1, 0xba, + 0xbf, 0x6e, 0x67, 0x20, 0x56, 0x69, 0xe1, 0xbb, 0x87, 0x74, 0x63, 0x68, 0x61, + 0x6e, 0x67, 0x65, 0x73, 0x20, 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x62, 0x6f, + 0x72, 0x64, 0x65, 0x72, 0x2d, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x23, 0x30, + 0x22, 0x20, 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x3d, 0x22, 0x30, 0x22, 0x20, + 0x3c, 0x2f, 0x73, 0x70, 0x61, 0x6e, 0x3e, 0x3c, 0x2f, 0x64, 0x69, 0x76, 0x3e, + 0x3c, 0x77, 0x61, 0x73, 0x20, 0x64, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, + 0x65, 0x64, 0x22, 0x20, 0x74, 0x79, 0x70, 0x65, 0x3d, 0x22, 0x74, 0x65, 0x78, + 0x74, 0x22, 0x20, 0x29, 0x3b, 0x0a, 0x3c, 0x2f, 0x73, 0x63, 0x72, 0x69, 0x70, + 0x74, 0x3e, 0x0a, 0x0a, 0x44, 0x65, 0x70, 0x61, 0x72, 0x74, 0x6d, 0x65, 0x6e, + 0x74, 0x20, 0x6f, 0x66, 0x20, 0x65, 0x63, 0x63, 0x6c, 0x65, 0x73, 0x69, 0x61, + 0x73, 0x74, 0x69, 0x63, 0x61, 0x6c, 0x74, 0x68, 0x65, 0x72, 0x65, 0x20, 0x68, + 0x61, 0x73, 0x20, 0x62, 0x65, 0x65, 0x6e, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, + 0x69, 0x6e, 0x67, 0x20, 0x66, 0x72, 0x6f, 0x6d, 0x3c, 0x2f, 0x62, 0x6f, 0x64, + 0x79, 0x3e, 0x3c, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x3e, 0x68, 0x61, 0x73, 0x20, + 0x6e, 0x65, 0x76, 0x65, 0x72, 0x20, 0x62, 0x65, 0x65, 0x6e, 0x74, 0x68, 0x65, + 0x20, 0x66, 0x69, 0x72, 0x73, 0x74, 0x20, 0x74, 0x69, 0x6d, 0x65, 0x69, 0x6e, + 0x20, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x20, 0x74, 0x6f, 0x61, + 0x75, 0x74, 0x6f, 0x6d, 0x61, 0x74, 0x69, 0x63, 0x61, 0x6c, 0x6c, 0x79, 0x20, + 0x3c, 0x2f, 0x64, 0x69, 0x76, 0x3e, 0x0a, 0x0a, 0x3c, 0x64, 0x69, 0x76, 0x20, + 0x69, 0x77, 0x61, 0x73, 0x20, 0x63, 0x6f, 0x6e, 0x73, 0x69, 0x64, 0x65, 0x72, + 0x65, 0x64, 0x70, 0x65, 0x72, 0x63, 0x65, 0x6e, 0x74, 0x20, 0x6f, 0x66, 0x20, + 0x74, 0x68, 0x65, 0x22, 0x20, 0x2f, 0x3e, 0x3c, 0x2f, 0x61, 0x3e, 0x3c, 0x2f, + 0x64, 0x69, 0x76, 0x3e, 0x63, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x20, 0x6f, 0x66, 0x20, 0x64, 0x65, 0x73, 0x63, 0x65, 0x6e, 0x64, 0x65, + 0x64, 0x20, 0x66, 0x72, 0x6f, 0x6d, 0x73, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x61, 0x63, 0x63, 0x65, 0x70, 0x74, + 0x2d, 0x63, 0x68, 0x61, 0x72, 0x73, 0x65, 0x74, 0x74, 0x6f, 0x20, 0x62, 0x65, + 0x20, 0x63, 0x6f, 0x6e, 0x66, 0x75, 0x73, 0x65, 0x64, 0x6d, 0x65, 0x6d, 0x62, + 0x65, 0x72, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x70, 0x61, 0x64, + 0x64, 0x69, 0x6e, 0x67, 0x2d, 0x72, 0x69, 0x67, 0x68, 0x74, 0x3a, 0x74, 0x72, + 0x61, 0x6e, 0x73, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6f, 0x66, 0x69, + 0x6e, 0x74, 0x65, 0x72, 0x70, 0x72, 0x65, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x20, 0x68, 0x72, 0x65, 0x66, 0x3d, 0x27, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, + 0x2f, 0x77, 0x68, 0x65, 0x74, 0x68, 0x65, 0x72, 0x20, 0x6f, 0x72, 0x20, 0x6e, + 0x6f, 0x74, 0x54, 0x68, 0x65, 0x72, 0x65, 0x20, 0x61, 0x72, 0x65, 0x20, 0x61, + 0x6c, 0x73, 0x6f, 0x74, 0x68, 0x65, 0x72, 0x65, 0x20, 0x61, 0x72, 0x65, 0x20, + 0x6d, 0x61, 0x6e, 0x79, 0x61, 0x20, 0x73, 0x6d, 0x61, 0x6c, 0x6c, 0x20, 0x6e, + 0x75, 0x6d, 0x62, 0x65, 0x72, 0x6f, 0x74, 0x68, 0x65, 0x72, 0x20, 0x70, 0x61, + 0x72, 0x74, 0x73, 0x20, 0x6f, 0x66, 0x69, 0x6d, 0x70, 0x6f, 0x73, 0x73, 0x69, + 0x62, 0x6c, 0x65, 0x20, 0x74, 0x6f, 0x20, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, + 0x3d, 0x22, 0x62, 0x75, 0x74, 0x74, 0x6f, 0x6e, 0x6c, 0x6f, 0x63, 0x61, 0x74, + 0x65, 0x64, 0x20, 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x2e, 0x20, 0x48, 0x6f, + 0x77, 0x65, 0x76, 0x65, 0x72, 0x2c, 0x20, 0x74, 0x68, 0x65, 0x61, 0x6e, 0x64, + 0x20, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x75, 0x61, 0x6c, 0x6c, 0x79, 0x41, 0x74, + 0x20, 0x74, 0x68, 0x65, 0x20, 0x65, 0x6e, 0x64, 0x20, 0x6f, 0x66, 0x20, 0x62, + 0x65, 0x63, 0x61, 0x75, 0x73, 0x65, 0x20, 0x6f, 0x66, 0x20, 0x69, 0x74, 0x73, + 0x72, 0x65, 0x70, 0x72, 0x65, 0x73, 0x65, 0x6e, 0x74, 0x73, 0x20, 0x74, 0x68, + 0x65, 0x3c, 0x66, 0x6f, 0x72, 0x6d, 0x20, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x3d, 0x22, 0x20, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x3d, 0x22, 0x70, 0x6f, + 0x73, 0x74, 0x22, 0x69, 0x74, 0x20, 0x69, 0x73, 0x20, 0x70, 0x6f, 0x73, 0x73, + 0x69, 0x62, 0x6c, 0x65, 0x6d, 0x6f, 0x72, 0x65, 0x20, 0x6c, 0x69, 0x6b, 0x65, + 0x6c, 0x79, 0x20, 0x74, 0x6f, 0x61, 0x6e, 0x20, 0x69, 0x6e, 0x63, 0x72, 0x65, + 0x61, 0x73, 0x65, 0x20, 0x69, 0x6e, 0x68, 0x61, 0x76, 0x65, 0x20, 0x61, 0x6c, + 0x73, 0x6f, 0x20, 0x62, 0x65, 0x65, 0x6e, 0x63, 0x6f, 0x72, 0x72, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x64, 0x73, 0x20, 0x74, 0x6f, 0x61, 0x6e, 0x6e, 0x6f, 0x75, + 0x6e, 0x63, 0x65, 0x64, 0x20, 0x74, 0x68, 0x61, 0x74, 0x61, 0x6c, 0x69, 0x67, + 0x6e, 0x3d, 0x22, 0x72, 0x69, 0x67, 0x68, 0x74, 0x22, 0x3e, 0x6d, 0x61, 0x6e, + 0x79, 0x20, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x72, 0x69, 0x65, 0x73, 0x66, 0x6f, + 0x72, 0x20, 0x6d, 0x61, 0x6e, 0x79, 0x20, 0x79, 0x65, 0x61, 0x72, 0x73, 0x65, + 0x61, 0x72, 0x6c, 0x69, 0x65, 0x73, 0x74, 0x20, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, + 0x62, 0x65, 0x63, 0x61, 0x75, 0x73, 0x65, 0x20, 0x69, 0x74, 0x20, 0x77, 0x61, + 0x73, 0x70, 0x74, 0x22, 0x3e, 0x3c, 0x2f, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, + 0x3e, 0x0d, 0x20, 0x76, 0x61, 0x6c, 0x69, 0x67, 0x6e, 0x3d, 0x22, 0x74, 0x6f, + 0x70, 0x22, 0x20, 0x69, 0x6e, 0x68, 0x61, 0x62, 0x69, 0x74, 0x61, 0x6e, 0x74, + 0x73, 0x20, 0x6f, 0x66, 0x66, 0x6f, 0x6c, 0x6c, 0x6f, 0x77, 0x69, 0x6e, 0x67, + 0x20, 0x79, 0x65, 0x61, 0x72, 0x0d, 0x0a, 0x3c, 0x64, 0x69, 0x76, 0x20, 0x63, + 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x22, 0x6d, 0x69, 0x6c, 0x6c, 0x69, 0x6f, 0x6e, + 0x20, 0x70, 0x65, 0x6f, 0x70, 0x6c, 0x65, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, + 0x76, 0x65, 0x72, 0x73, 0x69, 0x61, 0x6c, 0x20, 0x63, 0x6f, 0x6e, 0x63, 0x65, + 0x72, 0x6e, 0x69, 0x6e, 0x67, 0x20, 0x74, 0x68, 0x65, 0x61, 0x72, 0x67, 0x75, + 0x65, 0x20, 0x74, 0x68, 0x61, 0x74, 0x20, 0x74, 0x68, 0x65, 0x67, 0x6f, 0x76, + 0x65, 0x72, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x20, 0x61, 0x6e, 0x64, 0x61, 0x20, + 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x20, 0x74, 0x6f, 0x74, + 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x72, 0x65, 0x64, 0x20, 0x74, 0x6f, + 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x62, 0x69, 0x6e, 0x67, 0x20, 0x74, 0x68, + 0x65, 0x20, 0x73, 0x74, 0x79, 0x6c, 0x65, 0x3d, 0x22, 0x63, 0x6f, 0x6c, 0x6f, + 0x72, 0x3a, 0x61, 0x6c, 0x74, 0x68, 0x6f, 0x75, 0x67, 0x68, 0x20, 0x74, 0x68, + 0x65, 0x72, 0x65, 0x62, 0x65, 0x73, 0x74, 0x20, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, + 0x20, 0x66, 0x6f, 0x72, 0x73, 0x75, 0x62, 0x6d, 0x69, 0x74, 0x22, 0x20, 0x6e, + 0x61, 0x6d, 0x65, 0x3d, 0x22, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x70, 0x6c, 0x69, + 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x6d, 0x6f, 0x72, 0x65, 0x20, 0x74, 0x68, + 0x61, 0x6e, 0x20, 0x6f, 0x6e, 0x65, 0x20, 0x72, 0x65, 0x63, 0x6f, 0x67, 0x6e, + 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6f, 0x66, 0x43, 0x6f, 0x75, 0x6e, 0x63, + 0x69, 0x6c, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x65, 0x64, 0x69, 0x74, + 0x69, 0x6f, 0x6e, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x20, 0x3c, + 0x6d, 0x65, 0x74, 0x61, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x3d, 0x22, 0x45, 0x6e, + 0x74, 0x65, 0x72, 0x74, 0x61, 0x69, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x20, 0x61, + 0x77, 0x61, 0x79, 0x20, 0x66, 0x72, 0x6f, 0x6d, 0x20, 0x74, 0x68, 0x65, 0x20, + 0x3b, 0x6d, 0x61, 0x72, 0x67, 0x69, 0x6e, 0x2d, 0x72, 0x69, 0x67, 0x68, 0x74, + 0x3a, 0x61, 0x74, 0x20, 0x74, 0x68, 0x65, 0x20, 0x74, 0x69, 0x6d, 0x65, 0x20, + 0x6f, 0x66, 0x69, 0x6e, 0x76, 0x65, 0x73, 0x74, 0x69, 0x67, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x73, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x65, 0x64, 0x20, + 0x77, 0x69, 0x74, 0x68, 0x61, 0x6e, 0x64, 0x20, 0x6d, 0x61, 0x6e, 0x79, 0x20, + 0x6f, 0x74, 0x68, 0x65, 0x72, 0x61, 0x6c, 0x74, 0x68, 0x6f, 0x75, 0x67, 0x68, + 0x20, 0x69, 0x74, 0x20, 0x69, 0x73, 0x62, 0x65, 0x67, 0x69, 0x6e, 0x6e, 0x69, + 0x6e, 0x67, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x3c, 0x73, 0x70, 0x61, 0x6e, + 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x22, 0x64, 0x65, 0x73, 0x63, 0x65, + 0x6e, 0x64, 0x61, 0x6e, 0x74, 0x73, 0x20, 0x6f, 0x66, 0x3c, 0x73, 0x70, 0x61, + 0x6e, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x22, 0x69, 0x20, 0x61, 0x6c, + 0x69, 0x67, 0x6e, 0x3d, 0x22, 0x72, 0x69, 0x67, 0x68, 0x74, 0x22, 0x3c, 0x2f, + 0x68, 0x65, 0x61, 0x64, 0x3e, 0x0a, 0x3c, 0x62, 0x6f, 0x64, 0x79, 0x20, 0x61, + 0x73, 0x70, 0x65, 0x63, 0x74, 0x73, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, + 0x68, 0x61, 0x73, 0x20, 0x73, 0x69, 0x6e, 0x63, 0x65, 0x20, 0x62, 0x65, 0x65, + 0x6e, 0x45, 0x75, 0x72, 0x6f, 0x70, 0x65, 0x61, 0x6e, 0x20, 0x55, 0x6e, 0x69, + 0x6f, 0x6e, 0x72, 0x65, 0x6d, 0x69, 0x6e, 0x69, 0x73, 0x63, 0x65, 0x6e, 0x74, + 0x20, 0x6f, 0x66, 0x6d, 0x6f, 0x72, 0x65, 0x20, 0x64, 0x69, 0x66, 0x66, 0x69, + 0x63, 0x75, 0x6c, 0x74, 0x56, 0x69, 0x63, 0x65, 0x20, 0x50, 0x72, 0x65, 0x73, + 0x69, 0x64, 0x65, 0x6e, 0x74, 0x63, 0x6f, 0x6d, 0x70, 0x6f, 0x73, 0x69, 0x74, + 0x69, 0x6f, 0x6e, 0x20, 0x6f, 0x66, 0x70, 0x61, 0x73, 0x73, 0x65, 0x64, 0x20, + 0x74, 0x68, 0x72, 0x6f, 0x75, 0x67, 0x68, 0x6d, 0x6f, 0x72, 0x65, 0x20, 0x69, + 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x61, 0x6e, 0x74, 0x66, 0x6f, 0x6e, 0x74, 0x2d, + 0x73, 0x69, 0x7a, 0x65, 0x3a, 0x31, 0x31, 0x70, 0x78, 0x65, 0x78, 0x70, 0x6c, + 0x61, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6f, 0x66, 0x74, 0x68, 0x65, + 0x20, 0x63, 0x6f, 0x6e, 0x63, 0x65, 0x70, 0x74, 0x20, 0x6f, 0x66, 0x77, 0x72, + 0x69, 0x74, 0x74, 0x65, 0x6e, 0x20, 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x09, + 0x3c, 0x73, 0x70, 0x61, 0x6e, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x22, + 0x69, 0x73, 0x20, 0x6f, 0x6e, 0x65, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, + 0x20, 0x72, 0x65, 0x73, 0x65, 0x6d, 0x62, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x20, + 0x74, 0x6f, 0x6f, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x67, 0x72, 0x6f, 0x75, + 0x6e, 0x64, 0x73, 0x77, 0x68, 0x69, 0x63, 0x68, 0x20, 0x63, 0x6f, 0x6e, 0x74, + 0x61, 0x69, 0x6e, 0x73, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x69, 0x6e, 0x67, + 0x20, 0x74, 0x68, 0x65, 0x20, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x65, 0x64, 0x20, + 0x62, 0x79, 0x20, 0x74, 0x68, 0x65, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6f, 0x66, 0x6d, 0x65, 0x61, 0x6e, 0x73, 0x20, + 0x74, 0x68, 0x61, 0x74, 0x20, 0x74, 0x68, 0x65, 0x6f, 0x75, 0x74, 0x73, 0x69, + 0x64, 0x65, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x73, 0x75, 0x70, 0x70, + 0x6f, 0x72, 0x74, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x3c, 0x69, 0x6e, + 0x70, 0x75, 0x74, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x22, 0x3c, 0x73, + 0x70, 0x61, 0x6e, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x22, 0x74, 0x28, + 0x4d, 0x61, 0x74, 0x68, 0x2e, 0x72, 0x61, 0x6e, 0x64, 0x6f, 0x6d, 0x28, 0x29, + 0x6d, 0x6f, 0x73, 0x74, 0x20, 0x70, 0x72, 0x6f, 0x6d, 0x69, 0x6e, 0x65, 0x6e, + 0x74, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x20, + 0x6f, 0x66, 0x43, 0x6f, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x74, 0x69, 0x6e, 0x6f, + 0x70, 0x6c, 0x65, 0x77, 0x65, 0x72, 0x65, 0x20, 0x70, 0x75, 0x62, 0x6c, 0x69, + 0x73, 0x68, 0x65, 0x64, 0x3c, 0x64, 0x69, 0x76, 0x20, 0x63, 0x6c, 0x61, 0x73, + 0x73, 0x3d, 0x22, 0x73, 0x65, 0x61, 0x70, 0x70, 0x65, 0x61, 0x72, 0x73, 0x20, + 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x31, 0x22, 0x20, 0x68, 0x65, 0x69, 0x67, + 0x68, 0x74, 0x3d, 0x22, 0x31, 0x22, 0x20, 0x6d, 0x6f, 0x73, 0x74, 0x20, 0x69, + 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x61, 0x6e, 0x74, 0x77, 0x68, 0x69, 0x63, 0x68, + 0x20, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x73, 0x77, 0x68, 0x69, 0x63, + 0x68, 0x20, 0x68, 0x61, 0x64, 0x20, 0x62, 0x65, 0x65, 0x6e, 0x64, 0x65, 0x73, + 0x74, 0x72, 0x75, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6f, 0x66, 0x74, 0x68, + 0x65, 0x20, 0x70, 0x6f, 0x70, 0x75, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x0a, + 0x09, 0x3c, 0x64, 0x69, 0x76, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x22, + 0x70, 0x6f, 0x73, 0x73, 0x69, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x20, 0x6f, + 0x66, 0x73, 0x6f, 0x6d, 0x65, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x20, 0x75, 0x73, + 0x65, 0x64, 0x61, 0x70, 0x70, 0x65, 0x61, 0x72, 0x20, 0x74, 0x6f, 0x20, 0x68, + 0x61, 0x76, 0x65, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x20, 0x6f, 0x66, + 0x20, 0x74, 0x68, 0x65, 0x69, 0x6e, 0x74, 0x65, 0x6e, 0x64, 0x65, 0x64, 0x20, + 0x74, 0x6f, 0x20, 0x62, 0x65, 0x70, 0x72, 0x65, 0x73, 0x65, 0x6e, 0x74, 0x20, + 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x73, 0x74, 0x79, 0x6c, 0x65, 0x3d, 0x22, + 0x63, 0x6c, 0x65, 0x61, 0x72, 0x3a, 0x62, 0x0d, 0x0a, 0x3c, 0x2f, 0x73, 0x63, + 0x72, 0x69, 0x70, 0x74, 0x3e, 0x0d, 0x0a, 0x3c, 0x77, 0x61, 0x73, 0x20, 0x66, + 0x6f, 0x75, 0x6e, 0x64, 0x65, 0x64, 0x20, 0x69, 0x6e, 0x69, 0x6e, 0x74, 0x65, + 0x72, 0x76, 0x69, 0x65, 0x77, 0x20, 0x77, 0x69, 0x74, 0x68, 0x5f, 0x69, 0x64, + 0x22, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x3d, 0x22, 0x63, 0x61, + 0x70, 0x69, 0x74, 0x61, 0x6c, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x0d, + 0x0a, 0x3c, 0x6c, 0x69, 0x6e, 0x6b, 0x20, 0x72, 0x65, 0x6c, 0x3d, 0x22, 0x73, + 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, + 0x65, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x20, 0x6f, 0x75, 0x74, 0x20, 0x74, 0x68, + 0x61, 0x74, 0x78, 0x4d, 0x4c, 0x48, 0x74, 0x74, 0x70, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x61, 0x6e, 0x64, 0x20, 0x73, 0x75, 0x62, 0x73, 0x65, 0x71, + 0x75, 0x65, 0x6e, 0x74, 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x20, 0x6c, 0x61, + 0x72, 0x67, 0x65, 0x73, 0x74, 0x76, 0x65, 0x72, 0x79, 0x20, 0x69, 0x6d, 0x70, + 0x6f, 0x72, 0x74, 0x61, 0x6e, 0x74, 0x73, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, + 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x73, 0x75, 0x72, 0x66, 0x61, 0x63, + 0x65, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x61, 0x70, 0x70, 0x6c, 0x69, + 0x65, 0x64, 0x20, 0x74, 0x6f, 0x20, 0x74, 0x68, 0x65, 0x66, 0x6f, 0x72, 0x65, + 0x69, 0x67, 0x6e, 0x20, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x5f, 0x73, 0x65, + 0x74, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x4e, 0x61, 0x6d, 0x65, 0x65, 0x73, + 0x74, 0x61, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x65, 0x64, 0x20, 0x69, 0x6e, 0x69, + 0x73, 0x20, 0x62, 0x65, 0x6c, 0x69, 0x65, 0x76, 0x65, 0x64, 0x20, 0x74, 0x6f, + 0x49, 0x6e, 0x20, 0x61, 0x64, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x74, + 0x6f, 0x6d, 0x65, 0x61, 0x6e, 0x69, 0x6e, 0x67, 0x20, 0x6f, 0x66, 0x20, 0x74, + 0x68, 0x65, 0x69, 0x73, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x64, 0x20, 0x61, 0x66, + 0x74, 0x65, 0x72, 0x74, 0x6f, 0x20, 0x70, 0x72, 0x6f, 0x74, 0x65, 0x63, 0x74, + 0x20, 0x74, 0x68, 0x65, 0x69, 0x73, 0x20, 0x72, 0x65, 0x70, 0x72, 0x65, 0x73, + 0x65, 0x6e, 0x74, 0x65, 0x64, 0x44, 0x65, 0x63, 0x6c, 0x61, 0x72, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x20, 0x6f, 0x66, 0x6d, 0x6f, 0x72, 0x65, 0x20, 0x65, 0x66, + 0x66, 0x69, 0x63, 0x69, 0x65, 0x6e, 0x74, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x69, + 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x6f, 0x74, 0x68, 0x65, 0x72, + 0x20, 0x66, 0x6f, 0x72, 0x6d, 0x73, 0x20, 0x6f, 0x66, 0x68, 0x65, 0x20, 0x72, + 0x65, 0x74, 0x75, 0x72, 0x6e, 0x65, 0x64, 0x20, 0x74, 0x6f, 0x3c, 0x73, 0x70, + 0x61, 0x6e, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x22, 0x63, 0x70, 0x65, + 0x72, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x6e, 0x63, 0x65, 0x20, 0x6f, 0x66, 0x28, + 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x29, 0x20, 0x7b, 0x0d, + 0x69, 0x66, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x6f, 0x6e, 0x6c, 0x79, 0x20, 0x69, + 0x66, 0x72, 0x65, 0x67, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x6f, 0x66, 0x20, 0x74, + 0x68, 0x65, 0x6c, 0x65, 0x61, 0x64, 0x69, 0x6e, 0x67, 0x20, 0x74, 0x6f, 0x20, + 0x74, 0x68, 0x65, 0x72, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, + 0x77, 0x69, 0x74, 0x68, 0x55, 0x6e, 0x69, 0x74, 0x65, 0x64, 0x20, 0x4e, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x73, 0x74, 0x79, 0x6c, 0x65, 0x3d, 0x22, 0x68, + 0x65, 0x69, 0x67, 0x68, 0x74, 0x3a, 0x6f, 0x74, 0x68, 0x65, 0x72, 0x20, 0x74, + 0x68, 0x61, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x79, 0x70, 0x65, 0x22, 0x20, 0x63, + 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x3d, 0x22, 0x41, 0x73, 0x73, 0x6f, 0x63, + 0x69, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6f, 0x66, 0x0a, 0x3c, 0x2f, 0x68, + 0x65, 0x61, 0x64, 0x3e, 0x0a, 0x3c, 0x62, 0x6f, 0x64, 0x79, 0x6c, 0x6f, 0x63, + 0x61, 0x74, 0x65, 0x64, 0x20, 0x6f, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x69, 0x73, + 0x20, 0x72, 0x65, 0x66, 0x65, 0x72, 0x72, 0x65, 0x64, 0x20, 0x74, 0x6f, 0x28, + 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x69, 0x6e, 0x67, 0x20, 0x74, 0x68, 0x65, + 0x63, 0x6f, 0x6e, 0x63, 0x65, 0x6e, 0x74, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x73, 0x74, 0x68, 0x65, 0x20, 0x69, 0x6e, 0x64, 0x69, 0x76, 0x69, 0x64, 0x75, + 0x61, 0x6c, 0x61, 0x6d, 0x6f, 0x6e, 0x67, 0x20, 0x74, 0x68, 0x65, 0x20, 0x6d, + 0x6f, 0x73, 0x74, 0x74, 0x68, 0x61, 0x6e, 0x20, 0x61, 0x6e, 0x79, 0x20, 0x6f, + 0x74, 0x68, 0x65, 0x72, 0x2f, 0x3e, 0x0a, 0x3c, 0x6c, 0x69, 0x6e, 0x6b, 0x20, + 0x72, 0x65, 0x6c, 0x3d, 0x22, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, + 0x66, 0x61, 0x6c, 0x73, 0x65, 0x3b, 0x74, 0x68, 0x65, 0x20, 0x70, 0x75, 0x72, + 0x70, 0x6f, 0x73, 0x65, 0x20, 0x6f, 0x66, 0x74, 0x68, 0x65, 0x20, 0x61, 0x62, + 0x69, 0x6c, 0x69, 0x74, 0x79, 0x20, 0x74, 0x6f, 0x3b, 0x63, 0x6f, 0x6c, 0x6f, + 0x72, 0x3a, 0x23, 0x66, 0x66, 0x66, 0x7d, 0x0a, 0x2e, 0x0a, 0x3c, 0x73, 0x70, + 0x61, 0x6e, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x22, 0x74, 0x68, 0x65, + 0x20, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x20, 0x6f, 0x66, 0x64, 0x65, + 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x6f, 0x66, 0x3e, + 0x0d, 0x0a, 0x3c, 0x6c, 0x69, 0x6e, 0x6b, 0x20, 0x72, 0x65, 0x6c, 0x3d, 0x22, + 0x63, 0x6c, 0x61, 0x69, 0x6d, 0x20, 0x74, 0x68, 0x61, 0x74, 0x20, 0x74, 0x68, + 0x65, 0x68, 0x61, 0x76, 0x65, 0x20, 0x64, 0x65, 0x76, 0x65, 0x6c, 0x6f, 0x70, + 0x65, 0x64, 0x3c, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x20, 0x77, 0x69, 0x64, 0x74, + 0x68, 0x3d, 0x22, 0x63, 0x65, 0x6c, 0x65, 0x62, 0x72, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x20, 0x6f, 0x66, 0x46, 0x6f, 0x6c, 0x6c, 0x6f, 0x77, 0x69, 0x6e, 0x67, + 0x20, 0x74, 0x68, 0x65, 0x20, 0x74, 0x6f, 0x20, 0x64, 0x69, 0x73, 0x74, 0x69, + 0x6e, 0x67, 0x75, 0x69, 0x73, 0x68, 0x3c, 0x73, 0x70, 0x61, 0x6e, 0x20, 0x63, + 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x22, 0x62, 0x74, 0x61, 0x6b, 0x65, 0x73, 0x20, + 0x70, 0x6c, 0x61, 0x63, 0x65, 0x20, 0x69, 0x6e, 0x75, 0x6e, 0x64, 0x65, 0x72, + 0x20, 0x74, 0x68, 0x65, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x6e, 0x6f, 0x74, 0x65, + 0x64, 0x20, 0x74, 0x68, 0x61, 0x74, 0x20, 0x74, 0x68, 0x65, 0x3e, 0x3c, 0x21, + 0x5b, 0x65, 0x6e, 0x64, 0x69, 0x66, 0x5d, 0x2d, 0x2d, 0x3e, 0x0a, 0x73, 0x74, + 0x79, 0x6c, 0x65, 0x3d, 0x22, 0x6d, 0x61, 0x72, 0x67, 0x69, 0x6e, 0x2d, 0x69, + 0x6e, 0x73, 0x74, 0x65, 0x61, 0x64, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, + 0x69, 0x6e, 0x74, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x65, 0x64, 0x20, 0x74, 0x68, + 0x65, 0x74, 0x68, 0x65, 0x20, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x20, + 0x6f, 0x66, 0x69, 0x6e, 0x63, 0x72, 0x65, 0x61, 0x73, 0x69, 0x6e, 0x67, 0x20, + 0x74, 0x68, 0x65, 0x64, 0x69, 0x66, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, + 0x73, 0x20, 0x69, 0x6e, 0x65, 0x73, 0x74, 0x69, 0x6d, 0x61, 0x74, 0x65, 0x64, + 0x20, 0x74, 0x68, 0x61, 0x74, 0x65, 0x73, 0x70, 0x65, 0x63, 0x69, 0x61, 0x6c, + 0x6c, 0x79, 0x20, 0x74, 0x68, 0x65, 0x2f, 0x64, 0x69, 0x76, 0x3e, 0x3c, 0x64, + 0x69, 0x76, 0x20, 0x69, 0x64, 0x3d, 0x22, 0x77, 0x61, 0x73, 0x20, 0x65, 0x76, + 0x65, 0x6e, 0x74, 0x75, 0x61, 0x6c, 0x6c, 0x79, 0x74, 0x68, 0x72, 0x6f, 0x75, + 0x67, 0x68, 0x6f, 0x75, 0x74, 0x20, 0x68, 0x69, 0x73, 0x74, 0x68, 0x65, 0x20, + 0x64, 0x69, 0x66, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x73, 0x6f, 0x6d, + 0x65, 0x74, 0x68, 0x69, 0x6e, 0x67, 0x20, 0x74, 0x68, 0x61, 0x74, 0x73, 0x70, + 0x61, 0x6e, 0x3e, 0x3c, 0x2f, 0x73, 0x70, 0x61, 0x6e, 0x3e, 0x3c, 0x2f, 0x73, + 0x69, 0x67, 0x6e, 0x69, 0x66, 0x69, 0x63, 0x61, 0x6e, 0x74, 0x6c, 0x79, 0x20, + 0x3e, 0x3c, 0x2f, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x3e, 0x0d, 0x0a, 0x0d, + 0x0a, 0x65, 0x6e, 0x76, 0x69, 0x72, 0x6f, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x61, + 0x6c, 0x20, 0x74, 0x6f, 0x20, 0x70, 0x72, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x20, + 0x74, 0x68, 0x65, 0x68, 0x61, 0x76, 0x65, 0x20, 0x62, 0x65, 0x65, 0x6e, 0x20, + 0x75, 0x73, 0x65, 0x64, 0x65, 0x73, 0x70, 0x65, 0x63, 0x69, 0x61, 0x6c, 0x6c, + 0x79, 0x20, 0x66, 0x6f, 0x72, 0x75, 0x6e, 0x64, 0x65, 0x72, 0x73, 0x74, 0x61, + 0x6e, 0x64, 0x20, 0x74, 0x68, 0x65, 0x69, 0x73, 0x20, 0x65, 0x73, 0x73, 0x65, + 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x6c, 0x79, 0x77, 0x65, 0x72, 0x65, 0x20, 0x74, + 0x68, 0x65, 0x20, 0x66, 0x69, 0x72, 0x73, 0x74, 0x69, 0x73, 0x20, 0x74, 0x68, + 0x65, 0x20, 0x6c, 0x61, 0x72, 0x67, 0x65, 0x73, 0x74, 0x68, 0x61, 0x76, 0x65, + 0x20, 0x62, 0x65, 0x65, 0x6e, 0x20, 0x6d, 0x61, 0x64, 0x65, 0x22, 0x20, 0x73, + 0x72, 0x63, 0x3d, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x69, 0x6e, + 0x74, 0x65, 0x72, 0x70, 0x72, 0x65, 0x74, 0x65, 0x64, 0x20, 0x61, 0x73, 0x73, + 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x20, 0x68, 0x61, 0x6c, 0x66, 0x20, 0x6f, 0x66, + 0x63, 0x72, 0x6f, 0x6c, 0x6c, 0x69, 0x6e, 0x67, 0x3d, 0x22, 0x6e, 0x6f, 0x22, + 0x20, 0x69, 0x73, 0x20, 0x63, 0x6f, 0x6d, 0x70, 0x6f, 0x73, 0x65, 0x64, 0x20, + 0x6f, 0x66, 0x49, 0x49, 0x2c, 0x20, 0x48, 0x6f, 0x6c, 0x79, 0x20, 0x52, 0x6f, + 0x6d, 0x61, 0x6e, 0x69, 0x73, 0x20, 0x65, 0x78, 0x70, 0x65, 0x63, 0x74, 0x65, + 0x64, 0x20, 0x74, 0x6f, 0x68, 0x61, 0x76, 0x65, 0x20, 0x74, 0x68, 0x65, 0x69, + 0x72, 0x20, 0x6f, 0x77, 0x6e, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x65, 0x64, 0x20, + 0x61, 0x73, 0x20, 0x74, 0x68, 0x65, 0x74, 0x72, 0x61, 0x64, 0x69, 0x74, 0x69, + 0x6f, 0x6e, 0x61, 0x6c, 0x6c, 0x79, 0x20, 0x68, 0x61, 0x76, 0x65, 0x20, 0x64, + 0x69, 0x66, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x74, 0x61, 0x72, 0x65, 0x20, 0x6f, + 0x66, 0x74, 0x65, 0x6e, 0x20, 0x75, 0x73, 0x65, 0x64, 0x74, 0x6f, 0x20, 0x65, + 0x6e, 0x73, 0x75, 0x72, 0x65, 0x20, 0x74, 0x68, 0x61, 0x74, 0x61, 0x67, 0x72, + 0x65, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x20, 0x77, 0x69, 0x74, 0x68, 0x63, 0x6f, + 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x69, 0x6e, 0x67, 0x20, 0x74, 0x68, 0x65, 0x61, + 0x72, 0x65, 0x20, 0x66, 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x74, 0x6c, 0x79, + 0x69, 0x6e, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6f, + 0x6e, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x20, 0x69, 0x73, 0x20, 0x74, + 0x68, 0x65, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x69, 0x6e, 0x67, 0x20, 0x69, + 0x6e, 0x20, 0x61, 0x3c, 0x2f, 0x61, 0x3e, 0x3c, 0x2f, 0x6c, 0x69, 0x3e, 0x3c, + 0x2f, 0x75, 0x6c, 0x3e, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x22, 0x66, + 0x6f, 0x6f, 0x74, 0x65, 0x72, 0x61, 0x6e, 0x64, 0x20, 0x65, 0x73, 0x70, 0x65, + 0x63, 0x69, 0x61, 0x6c, 0x6c, 0x79, 0x74, 0x79, 0x70, 0x65, 0x3d, 0x22, 0x62, + 0x75, 0x74, 0x74, 0x6f, 0x6e, 0x22, 0x20, 0x3c, 0x2f, 0x73, 0x70, 0x61, 0x6e, + 0x3e, 0x3c, 0x2f, 0x73, 0x70, 0x61, 0x6e, 0x3e, 0x77, 0x68, 0x69, 0x63, 0x68, + 0x20, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x64, 0x3e, 0x0a, 0x3c, 0x6d, + 0x65, 0x74, 0x61, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x3d, 0x22, 0x63, 0x6f, 0x6e, + 0x73, 0x69, 0x64, 0x65, 0x72, 0x65, 0x64, 0x20, 0x74, 0x68, 0x65, 0x63, 0x61, + 0x72, 0x72, 0x69, 0x65, 0x64, 0x20, 0x6f, 0x75, 0x74, 0x20, 0x62, 0x79, 0x48, + 0x6f, 0x77, 0x65, 0x76, 0x65, 0x72, 0x2c, 0x20, 0x69, 0x74, 0x20, 0x69, 0x73, + 0x62, 0x65, 0x63, 0x61, 0x6d, 0x65, 0x20, 0x70, 0x61, 0x72, 0x74, 0x20, 0x6f, + 0x66, 0x69, 0x6e, 0x20, 0x72, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, + 0x74, 0x6f, 0x70, 0x6f, 0x70, 0x75, 0x6c, 0x61, 0x72, 0x20, 0x69, 0x6e, 0x20, + 0x74, 0x68, 0x65, 0x74, 0x68, 0x65, 0x20, 0x63, 0x61, 0x70, 0x69, 0x74, 0x61, + 0x6c, 0x20, 0x6f, 0x66, 0x77, 0x61, 0x73, 0x20, 0x6f, 0x66, 0x66, 0x69, 0x63, + 0x69, 0x61, 0x6c, 0x6c, 0x79, 0x77, 0x68, 0x69, 0x63, 0x68, 0x20, 0x68, 0x61, + 0x73, 0x20, 0x62, 0x65, 0x65, 0x6e, 0x74, 0x68, 0x65, 0x20, 0x48, 0x69, 0x73, + 0x74, 0x6f, 0x72, 0x79, 0x20, 0x6f, 0x66, 0x61, 0x6c, 0x74, 0x65, 0x72, 0x6e, + 0x61, 0x74, 0x69, 0x76, 0x65, 0x20, 0x74, 0x6f, 0x64, 0x69, 0x66, 0x66, 0x65, + 0x72, 0x65, 0x6e, 0x74, 0x20, 0x66, 0x72, 0x6f, 0x6d, 0x74, 0x6f, 0x20, 0x73, + 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x20, 0x74, 0x68, 0x65, 0x73, 0x75, 0x67, + 0x67, 0x65, 0x73, 0x74, 0x65, 0x64, 0x20, 0x74, 0x68, 0x61, 0x74, 0x69, 0x6e, + 0x20, 0x74, 0x68, 0x65, 0x20, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x20, + 0x20, 0x3c, 0x64, 0x69, 0x76, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x22, + 0x74, 0x68, 0x65, 0x20, 0x66, 0x6f, 0x75, 0x6e, 0x64, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x62, 0x65, 0x63, 0x61, 0x75, 0x73, 0x65, 0x20, 0x6f, 0x66, 0x20, 0x68, + 0x69, 0x73, 0x63, 0x6f, 0x6e, 0x63, 0x65, 0x72, 0x6e, 0x65, 0x64, 0x20, 0x77, + 0x69, 0x74, 0x68, 0x74, 0x68, 0x65, 0x20, 0x75, 0x6e, 0x69, 0x76, 0x65, 0x72, + 0x73, 0x69, 0x74, 0x79, 0x6f, 0x70, 0x70, 0x6f, 0x73, 0x65, 0x64, 0x20, 0x74, + 0x6f, 0x20, 0x74, 0x68, 0x65, 0x74, 0x68, 0x65, 0x20, 0x63, 0x6f, 0x6e, 0x74, + 0x65, 0x78, 0x74, 0x20, 0x6f, 0x66, 0x3c, 0x73, 0x70, 0x61, 0x6e, 0x20, 0x63, + 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x22, 0x70, 0x74, 0x65, 0x78, 0x74, 0x22, 0x20, + 0x6e, 0x61, 0x6d, 0x65, 0x3d, 0x22, 0x71, 0x22, 0x09, 0x09, 0x3c, 0x64, 0x69, + 0x76, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x22, 0x74, 0x68, 0x65, 0x20, + 0x73, 0x63, 0x69, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x63, 0x72, 0x65, 0x70, + 0x72, 0x65, 0x73, 0x65, 0x6e, 0x74, 0x65, 0x64, 0x20, 0x62, 0x79, 0x6d, 0x61, + 0x74, 0x68, 0x65, 0x6d, 0x61, 0x74, 0x69, 0x63, 0x69, 0x61, 0x6e, 0x73, 0x65, + 0x6c, 0x65, 0x63, 0x74, 0x65, 0x64, 0x20, 0x62, 0x79, 0x20, 0x74, 0x68, 0x65, + 0x74, 0x68, 0x61, 0x74, 0x20, 0x68, 0x61, 0x76, 0x65, 0x20, 0x62, 0x65, 0x65, + 0x6e, 0x3e, 0x3c, 0x64, 0x69, 0x76, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x3d, + 0x22, 0x63, 0x64, 0x69, 0x76, 0x20, 0x69, 0x64, 0x3d, 0x22, 0x68, 0x65, 0x61, + 0x64, 0x65, 0x72, 0x69, 0x6e, 0x20, 0x70, 0x61, 0x72, 0x74, 0x69, 0x63, 0x75, + 0x6c, 0x61, 0x72, 0x2c, 0x63, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x74, 0x65, 0x64, + 0x20, 0x69, 0x6e, 0x74, 0x6f, 0x29, 0x3b, 0x0a, 0x3c, 0x2f, 0x73, 0x63, 0x72, + 0x69, 0x70, 0x74, 0x3e, 0x0a, 0x3c, 0x70, 0x68, 0x69, 0x6c, 0x6f, 0x73, 0x6f, + 0x70, 0x68, 0x69, 0x63, 0x61, 0x6c, 0x20, 0x73, 0x72, 0x70, 0x73, 0x6b, 0x6f, + 0x68, 0x72, 0x76, 0x61, 0x74, 0x73, 0x6b, 0x69, 0x74, 0x69, 0xe1, 0xba, 0xbf, + 0x6e, 0x67, 0x20, 0x56, 0x69, 0xe1, 0xbb, 0x87, 0x74, 0xd0, 0xa0, 0xd1, 0x83, + 0xd1, 0x81, 0xd1, 0x81, 0xd0, 0xba, 0xd0, 0xb8, 0xd0, 0xb9, 0xd1, 0x80, 0xd1, + 0x83, 0xd1, 0x81, 0xd1, 0x81, 0xd0, 0xba, 0xd0, 0xb8, 0xd0, 0xb9, 0x69, 0x6e, + 0x76, 0x65, 0x73, 0x74, 0x69, 0x67, 0x61, 0x63, 0x69, 0xc3, 0xb3, 0x6e, 0x70, + 0x61, 0x72, 0x74, 0x69, 0x63, 0x69, 0x70, 0x61, 0x63, 0x69, 0xc3, 0xb3, 0x6e, + 0xd0, 0xba, 0xd0, 0xbe, 0xd1, 0x82, 0xd0, 0xbe, 0xd1, 0x80, 0xd1, 0x8b, 0xd0, + 0xb5, 0xd0, 0xbe, 0xd0, 0xb1, 0xd0, 0xbb, 0xd0, 0xb0, 0xd1, 0x81, 0xd1, 0x82, + 0xd0, 0xb8, 0xd0, 0xba, 0xd0, 0xbe, 0xd1, 0x82, 0xd0, 0xbe, 0xd1, 0x80, 0xd1, + 0x8b, 0xd0, 0xb9, 0xd1, 0x87, 0xd0, 0xb5, 0xd0, 0xbb, 0xd0, 0xbe, 0xd0, 0xb2, + 0xd0, 0xb5, 0xd0, 0xba, 0xd1, 0x81, 0xd0, 0xb8, 0xd1, 0x81, 0xd1, 0x82, 0xd0, + 0xb5, 0xd0, 0xbc, 0xd1, 0x8b, 0xd0, 0x9d, 0xd0, 0xbe, 0xd0, 0xb2, 0xd0, 0xbe, + 0xd1, 0x81, 0xd1, 0x82, 0xd0, 0xb8, 0xd0, 0xba, 0xd0, 0xbe, 0xd1, 0x82, 0xd0, + 0xbe, 0xd1, 0x80, 0xd1, 0x8b, 0xd1, 0x85, 0xd0, 0xbe, 0xd0, 0xb1, 0xd0, 0xbb, + 0xd0, 0xb0, 0xd1, 0x81, 0xd1, 0x82, 0xd1, 0x8c, 0xd0, 0xb2, 0xd1, 0x80, 0xd0, + 0xb5, 0xd0, 0xbc, 0xd0, 0xb5, 0xd0, 0xbd, 0xd0, 0xb8, 0xd0, 0xba, 0xd0, 0xbe, + 0xd1, 0x82, 0xd0, 0xbe, 0xd1, 0x80, 0xd0, 0xb0, 0xd1, 0x8f, 0xd1, 0x81, 0xd0, + 0xb5, 0xd0, 0xb3, 0xd0, 0xbe, 0xd0, 0xb4, 0xd0, 0xbd, 0xd1, 0x8f, 0xd1, 0x81, + 0xd0, 0xba, 0xd0, 0xb0, 0xd1, 0x87, 0xd0, 0xb0, 0xd1, 0x82, 0xd1, 0x8c, 0xd0, + 0xbd, 0xd0, 0xbe, 0xd0, 0xb2, 0xd0, 0xbe, 0xd1, 0x81, 0xd1, 0x82, 0xd0, 0xb8, + 0xd0, 0xa3, 0xd0, 0xba, 0xd1, 0x80, 0xd0, 0xb0, 0xd0, 0xb8, 0xd0, 0xbd, 0xd1, + 0x8b, 0xd0, 0xb2, 0xd0, 0xbe, 0xd0, 0xbf, 0xd1, 0x80, 0xd0, 0xbe, 0xd1, 0x81, + 0xd1, 0x8b, 0xd0, 0xba, 0xd0, 0xbe, 0xd1, 0x82, 0xd0, 0xbe, 0xd1, 0x80, 0xd0, + 0xbe, 0xd0, 0xb9, 0xd1, 0x81, 0xd0, 0xb4, 0xd0, 0xb5, 0xd0, 0xbb, 0xd0, 0xb0, + 0xd1, 0x82, 0xd1, 0x8c, 0xd0, 0xbf, 0xd0, 0xbe, 0xd0, 0xbc, 0xd0, 0xbe, 0xd1, + 0x89, 0xd1, 0x8c, 0xd1, 0x8e, 0xd1, 0x81, 0xd1, 0x80, 0xd0, 0xb5, 0xd0, 0xb4, + 0xd1, 0x81, 0xd1, 0x82, 0xd0, 0xb2, 0xd0, 0xbe, 0xd0, 0xb1, 0xd1, 0x80, 0xd0, + 0xb0, 0xd0, 0xb7, 0xd0, 0xbe, 0xd0, 0xbc, 0xd1, 0x81, 0xd1, 0x82, 0xd0, 0xbe, + 0xd1, 0x80, 0xd0, 0xbe, 0xd0, 0xbd, 0xd1, 0x8b, 0xd1, 0x83, 0xd1, 0x87, 0xd0, + 0xb0, 0xd1, 0x81, 0xd1, 0x82, 0xd0, 0xb8, 0xd0, 0xb5, 0xd1, 0x82, 0xd0, 0xb5, + 0xd1, 0x87, 0xd0, 0xb5, 0xd0, 0xbd, 0xd0, 0xb8, 0xd0, 0xb5, 0xd0, 0x93, 0xd0, + 0xbb, 0xd0, 0xb0, 0xd0, 0xb2, 0xd0, 0xbd, 0xd0, 0xb0, 0xd1, 0x8f, 0xd0, 0xb8, + 0xd1, 0x81, 0xd1, 0x82, 0xd0, 0xbe, 0xd1, 0x80, 0xd0, 0xb8, 0xd0, 0xb8, 0xd1, + 0x81, 0xd0, 0xb8, 0xd1, 0x81, 0xd1, 0x82, 0xd0, 0xb5, 0xd0, 0xbc, 0xd0, 0xb0, + 0xd1, 0x80, 0xd0, 0xb5, 0xd1, 0x88, 0xd0, 0xb5, 0xd0, 0xbd, 0xd0, 0xb8, 0xd1, + 0x8f, 0xd0, 0xa1, 0xd0, 0xba, 0xd0, 0xb0, 0xd1, 0x87, 0xd0, 0xb0, 0xd1, 0x82, + 0xd1, 0x8c, 0xd0, 0xbf, 0xd0, 0xbe, 0xd1, 0x8d, 0xd1, 0x82, 0xd0, 0xbe, 0xd0, + 0xbc, 0xd1, 0x83, 0xd1, 0x81, 0xd0, 0xbb, 0xd0, 0xb5, 0xd0, 0xb4, 0xd1, 0x83, + 0xd0, 0xb5, 0xd1, 0x82, 0xd1, 0x81, 0xd0, 0xba, 0xd0, 0xb0, 0xd0, 0xb7, 0xd0, + 0xb0, 0xd1, 0x82, 0xd1, 0x8c, 0xd1, 0x82, 0xd0, 0xbe, 0xd0, 0xb2, 0xd0, 0xb0, + 0xd1, 0x80, 0xd0, 0xbe, 0xd0, 0xb2, 0xd0, 0xba, 0xd0, 0xbe, 0xd0, 0xbd, 0xd0, + 0xb5, 0xd1, 0x87, 0xd0, 0xbd, 0xd0, 0xbe, 0xd1, 0x80, 0xd0, 0xb5, 0xd1, 0x88, + 0xd0, 0xb5, 0xd0, 0xbd, 0xd0, 0xb8, 0xd0, 0xb5, 0xd0, 0xba, 0xd0, 0xbe, 0xd1, + 0x82, 0xd0, 0xbe, 0xd1, 0x80, 0xd0, 0xbe, 0xd0, 0xb5, 0xd0, 0xbe, 0xd1, 0x80, + 0xd0, 0xb3, 0xd0, 0xb0, 0xd0, 0xbd, 0xd0, 0xbe, 0xd0, 0xb2, 0xd0, 0xba, 0xd0, + 0xbe, 0xd1, 0x82, 0xd0, 0xbe, 0xd1, 0x80, 0xd0, 0xbe, 0xd0, 0xbc, 0xd0, 0xa0, + 0xd0, 0xb5, 0xd0, 0xba, 0xd0, 0xbb, 0xd0, 0xb0, 0xd0, 0xbc, 0xd0, 0xb0, 0xd8, + 0xa7, 0xd9, 0x84, 0xd9, 0x85, 0xd9, 0x86, 0xd8, 0xaa, 0xd8, 0xaf, 0xd9, 0x89, + 0xd9, 0x85, 0xd9, 0x86, 0xd8, 0xaa, 0xd8, 0xaf, 0xd9, 0x8a, 0xd8, 0xa7, 0xd8, + 0xaa, 0xd8, 0xa7, 0xd9, 0x84, 0xd9, 0x85, 0xd9, 0x88, 0xd8, 0xb6, 0xd9, 0x88, + 0xd8, 0xb9, 0xd8, 0xa7, 0xd9, 0x84, 0xd8, 0xa8, 0xd8, 0xb1, 0xd8, 0xa7, 0xd9, + 0x85, 0xd8, 0xac, 0xd8, 0xa7, 0xd9, 0x84, 0xd9, 0x85, 0xd9, 0x88, 0xd8, 0xa7, + 0xd9, 0x82, 0xd8, 0xb9, 0xd8, 0xa7, 0xd9, 0x84, 0xd8, 0xb1, 0xd8, 0xb3, 0xd8, + 0xa7, 0xd8, 0xa6, 0xd9, 0x84, 0xd9, 0x85, 0xd8, 0xb4, 0xd8, 0xa7, 0xd8, 0xb1, + 0xd9, 0x83, 0xd8, 0xa7, 0xd8, 0xaa, 0xd8, 0xa7, 0xd9, 0x84, 0xd8, 0xa3, 0xd8, + 0xb9, 0xd8, 0xb6, 0xd8, 0xa7, 0xd8, 0xa1, 0xd8, 0xa7, 0xd9, 0x84, 0xd8, 0xb1, + 0xd9, 0x8a, 0xd8, 0xa7, 0xd8, 0xb6, 0xd8, 0xa9, 0xd8, 0xa7, 0xd9, 0x84, 0xd8, + 0xaa, 0xd8, 0xb5, 0xd9, 0x85, 0xd9, 0x8a, 0xd9, 0x85, 0xd8, 0xa7, 0xd9, 0x84, + 0xd8, 0xa7, 0xd8, 0xb9, 0xd8, 0xb6, 0xd8, 0xa7, 0xd8, 0xa1, 0xd8, 0xa7, 0xd9, + 0x84, 0xd9, 0x86, 0xd8, 0xaa, 0xd8, 0xa7, 0xd8, 0xa6, 0xd8, 0xac, 0xd8, 0xa7, + 0xd9, 0x84, 0xd8, 0xa3, 0xd9, 0x84, 0xd8, 0xb9, 0xd8, 0xa7, 0xd8, 0xa8, 0xd8, + 0xa7, 0xd9, 0x84, 0xd8, 0xaa, 0xd8, 0xb3, 0xd8, 0xac, 0xd9, 0x8a, 0xd9, 0x84, + 0xd8, 0xa7, 0xd9, 0x84, 0xd8, 0xa3, 0xd9, 0x82, 0xd8, 0xb3, 0xd8, 0xa7, 0xd9, + 0x85, 0xd8, 0xa7, 0xd9, 0x84, 0xd8, 0xb6, 0xd8, 0xba, 0xd8, 0xb7, 0xd8, 0xa7, + 0xd8, 0xaa, 0xd8, 0xa7, 0xd9, 0x84, 0xd9, 0x81, 0xd9, 0x8a, 0xd8, 0xaf, 0xd9, + 0x8a, 0xd9, 0x88, 0xd8, 0xa7, 0xd9, 0x84, 0xd8, 0xaa, 0xd8, 0xb1, 0xd8, 0xad, + 0xd9, 0x8a, 0xd8, 0xa8, 0xd8, 0xa7, 0xd9, 0x84, 0xd8, 0xac, 0xd8, 0xaf, 0xd9, + 0x8a, 0xd8, 0xaf, 0xd8, 0xa9, 0xd8, 0xa7, 0xd9, 0x84, 0xd8, 0xaa, 0xd8, 0xb9, + 0xd9, 0x84, 0xd9, 0x8a, 0xd9, 0x85, 0xd8, 0xa7, 0xd9, 0x84, 0xd8, 0xa3, 0xd8, + 0xae, 0xd8, 0xa8, 0xd8, 0xa7, 0xd8, 0xb1, 0xd8, 0xa7, 0xd9, 0x84, 0xd8, 0xa7, + 0xd9, 0x81, 0xd9, 0x84, 0xd8, 0xa7, 0xd9, 0x85, 0xd8, 0xa7, 0xd9, 0x84, 0xd8, + 0xa3, 0xd9, 0x81, 0xd9, 0x84, 0xd8, 0xa7, 0xd9, 0x85, 0xd8, 0xa7, 0xd9, 0x84, + 0xd8, 0xaa, 0xd8, 0xa7, 0xd8, 0xb1, 0xd9, 0x8a, 0xd8, 0xae, 0xd8, 0xa7, 0xd9, + 0x84, 0xd8, 0xaa, 0xd9, 0x82, 0xd9, 0x86, 0xd9, 0x8a, 0xd8, 0xa9, 0xd8, 0xa7, + 0xd9, 0x84, 0xd8, 0xa7, 0xd9, 0x84, 0xd8, 0xb9, 0xd8, 0xa7, 0xd8, 0xa8, 0xd8, + 0xa7, 0xd9, 0x84, 0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xa7, 0xd8, 0xb7, 0xd8, 0xb1, + 0xd8, 0xa7, 0xd9, 0x84, 0xd9, 0x85, 0xd8, 0xac, 0xd8, 0xaa, 0xd9, 0x85, 0xd8, + 0xb9, 0xd8, 0xa7, 0xd9, 0x84, 0xd8, 0xaf, 0xd9, 0x8a, 0xd9, 0x83, 0xd9, 0x88, + 0xd8, 0xb1, 0xd8, 0xa7, 0xd9, 0x84, 0xd8, 0xb3, 0xd9, 0x8a, 0xd8, 0xa7, 0xd8, + 0xad, 0xd8, 0xa9, 0xd8, 0xb9, 0xd8, 0xa8, 0xd8, 0xaf, 0xd8, 0xa7, 0xd9, 0x84, + 0xd9, 0x84, 0xd9, 0x87, 0xd8, 0xa7, 0xd9, 0x84, 0xd8, 0xaa, 0xd8, 0xb1, 0xd8, + 0xa8, 0xd9, 0x8a, 0xd8, 0xa9, 0xd8, 0xa7, 0xd9, 0x84, 0xd8, 0xb1, 0xd9, 0x88, + 0xd8, 0xa7, 0xd8, 0xa8, 0xd8, 0xb7, 0xd8, 0xa7, 0xd9, 0x84, 0xd8, 0xa3, 0xd8, + 0xaf, 0xd8, 0xa8, 0xd9, 0x8a, 0xd8, 0xa9, 0xd8, 0xa7, 0xd9, 0x84, 0xd8, 0xa7, + 0xd8, 0xae, 0xd8, 0xa8, 0xd8, 0xa7, 0xd8, 0xb1, 0xd8, 0xa7, 0xd9, 0x84, 0xd9, + 0x85, 0xd8, 0xaa, 0xd8, 0xad, 0xd8, 0xaf, 0xd8, 0xa9, 0xd8, 0xa7, 0xd9, 0x84, + 0xd8, 0xa7, 0xd8, 0xba, 0xd8, 0xa7, 0xd9, 0x86, 0xd9, 0x8a, 0x63, 0x75, 0x72, + 0x73, 0x6f, 0x72, 0x3a, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x3b, 0x3c, + 0x2f, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x3e, 0x0a, 0x3c, 0x6d, 0x65, 0x74, 0x61, + 0x20, 0x22, 0x20, 0x68, 0x72, 0x65, 0x66, 0x3d, 0x22, 0x68, 0x74, 0x74, 0x70, + 0x3a, 0x2f, 0x2f, 0x22, 0x3e, 0x3c, 0x73, 0x70, 0x61, 0x6e, 0x20, 0x63, 0x6c, + 0x61, 0x73, 0x73, 0x3d, 0x22, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x20, + 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x77, 0x69, 0x6e, 0x64, 0x6f, 0x77, + 0x2e, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x74, + 0x69, 0x63, 0x61, 0x6c, 0x2d, 0x61, 0x6c, 0x69, 0x67, 0x6e, 0x3a, 0x2f, 0x61, + 0x3e, 0x20, 0x7c, 0x20, 0x3c, 0x61, 0x20, 0x68, 0x72, 0x65, 0x66, 0x3d, 0x22, + 0x3c, 0x21, 0x64, 0x6f, 0x63, 0x74, 0x79, 0x70, 0x65, 0x20, 0x68, 0x74, 0x6d, + 0x6c, 0x3e, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x3d, 0x22, 0x73, 0x63, 0x72, 0x65, + 0x65, 0x6e, 0x22, 0x20, 0x3c, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x76, + 0x61, 0x6c, 0x75, 0x65, 0x3d, 0x22, 0x66, 0x61, 0x76, 0x69, 0x63, 0x6f, 0x6e, + 0x2e, 0x69, 0x63, 0x6f, 0x22, 0x20, 0x2f, 0x3e, 0x0a, 0x09, 0x09, 0x3c, 0x64, + 0x69, 0x76, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x22, 0x63, 0x68, 0x61, + 0x72, 0x61, 0x63, 0x74, 0x65, 0x72, 0x69, 0x73, 0x74, 0x69, 0x63, 0x73, 0x22, + 0x20, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x3d, 0x22, 0x67, 0x65, 0x74, 0x22, + 0x20, 0x2f, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0x0a, 0x3c, 0x2f, 0x68, 0x74, 0x6d, + 0x6c, 0x3e, 0x0a, 0x73, 0x68, 0x6f, 0x72, 0x74, 0x63, 0x75, 0x74, 0x20, 0x69, + 0x63, 0x6f, 0x6e, 0x22, 0x20, 0x64, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, + 0x2e, 0x77, 0x72, 0x69, 0x74, 0x65, 0x28, 0x70, 0x61, 0x64, 0x64, 0x69, 0x6e, + 0x67, 0x2d, 0x62, 0x6f, 0x74, 0x74, 0x6f, 0x6d, 0x3a, 0x72, 0x65, 0x70, 0x72, + 0x65, 0x73, 0x65, 0x6e, 0x74, 0x61, 0x74, 0x69, 0x76, 0x65, 0x73, 0x73, 0x75, + 0x62, 0x6d, 0x69, 0x74, 0x22, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3d, 0x22, + 0x61, 0x6c, 0x69, 0x67, 0x6e, 0x3d, 0x22, 0x63, 0x65, 0x6e, 0x74, 0x65, 0x72, + 0x22, 0x20, 0x74, 0x68, 0x72, 0x6f, 0x75, 0x67, 0x68, 0x6f, 0x75, 0x74, 0x20, + 0x74, 0x68, 0x65, 0x20, 0x73, 0x63, 0x69, 0x65, 0x6e, 0x63, 0x65, 0x20, 0x66, + 0x69, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x0a, 0x20, 0x20, 0x3c, 0x64, 0x69, 0x76, + 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x22, 0x73, 0x75, 0x62, 0x6d, 0x69, + 0x74, 0x22, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x22, 0x6f, 0x6e, 0x65, + 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x6d, 0x6f, 0x73, 0x74, 0x20, + 0x76, 0x61, 0x6c, 0x69, 0x67, 0x6e, 0x3d, 0x22, 0x74, 0x6f, 0x70, 0x22, 0x3e, + 0x3c, 0x77, 0x61, 0x73, 0x20, 0x65, 0x73, 0x74, 0x61, 0x62, 0x6c, 0x69, 0x73, + 0x68, 0x65, 0x64, 0x29, 0x3b, 0x0d, 0x0a, 0x3c, 0x2f, 0x73, 0x63, 0x72, 0x69, + 0x70, 0x74, 0x3e, 0x0d, 0x0a, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x66, + 0x61, 0x6c, 0x73, 0x65, 0x3b, 0x22, 0x3e, 0x29, 0x2e, 0x73, 0x74, 0x79, 0x6c, + 0x65, 0x2e, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x62, 0x65, 0x63, 0x61, + 0x75, 0x73, 0x65, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x64, 0x6f, + 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x63, 0x6f, 0x6f, 0x6b, 0x69, 0x65, + 0x3c, 0x66, 0x6f, 0x72, 0x6d, 0x20, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x3d, + 0x22, 0x2f, 0x7d, 0x62, 0x6f, 0x64, 0x79, 0x7b, 0x6d, 0x61, 0x72, 0x67, 0x69, + 0x6e, 0x3a, 0x30, 0x3b, 0x45, 0x6e, 0x63, 0x79, 0x63, 0x6c, 0x6f, 0x70, 0x65, + 0x64, 0x69, 0x61, 0x20, 0x6f, 0x66, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, + 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x2e, 0x63, 0x72, 0x65, 0x61, + 0x74, 0x65, 0x45, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x28, 0x6e, 0x61, 0x6d, + 0x65, 0x22, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x3d, 0x22, 0x3c, + 0x2f, 0x64, 0x69, 0x76, 0x3e, 0x0a, 0x3c, 0x2f, 0x64, 0x69, 0x76, 0x3e, 0x0a, + 0x0a, 0x61, 0x64, 0x6d, 0x69, 0x6e, 0x69, 0x73, 0x74, 0x72, 0x61, 0x74, 0x69, + 0x76, 0x65, 0x20, 0x3c, 0x2f, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0x0a, 0x3c, 0x2f, + 0x68, 0x74, 0x6d, 0x6c, 0x3e, 0x68, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x20, + 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x22, 0x3e, 0x3c, 0x69, 0x6e, 0x70, + 0x75, 0x74, 0x20, 0x74, 0x79, 0x70, 0x65, 0x3d, 0x22, 0x70, 0x6f, 0x72, 0x74, + 0x69, 0x6f, 0x6e, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x61, 0x73, + 0x20, 0x70, 0x61, 0x72, 0x74, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, + 0x26, 0x6e, 0x62, 0x73, 0x70, 0x3b, 0x3c, 0x61, 0x20, 0x68, 0x72, 0x65, 0x66, + 0x3d, 0x22, 0x6f, 0x74, 0x68, 0x65, 0x72, 0x20, 0x63, 0x6f, 0x75, 0x6e, 0x74, + 0x72, 0x69, 0x65, 0x73, 0x22, 0x3e, 0x0a, 0x3c, 0x64, 0x69, 0x76, 0x20, 0x63, + 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x22, 0x3c, 0x2f, 0x73, 0x70, 0x61, 0x6e, 0x3e, + 0x3c, 0x2f, 0x73, 0x70, 0x61, 0x6e, 0x3e, 0x3c, 0x49, 0x6e, 0x20, 0x6f, 0x74, + 0x68, 0x65, 0x72, 0x20, 0x77, 0x6f, 0x72, 0x64, 0x73, 0x2c, 0x64, 0x69, 0x73, + 0x70, 0x6c, 0x61, 0x79, 0x3a, 0x20, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x3b, 0x63, + 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, + 0x20, 0x69, 0x6e, 0x74, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x20, 0x6f, 0x66, 0x2f, 0x3e, 0x0a, 0x3c, 0x6d, 0x65, 0x74, 0x61, 0x20, 0x6e, + 0x61, 0x6d, 0x65, 0x3d, 0x22, 0x61, 0x73, 0x20, 0x77, 0x65, 0x6c, 0x6c, 0x20, + 0x61, 0x73, 0x20, 0x74, 0x68, 0x65, 0x20, 0x69, 0x6e, 0x20, 0x72, 0x65, 0x63, + 0x65, 0x6e, 0x74, 0x20, 0x79, 0x65, 0x61, 0x72, 0x73, 0x0d, 0x0a, 0x09, 0x3c, + 0x64, 0x69, 0x76, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x22, 0x3c, 0x2f, + 0x64, 0x69, 0x76, 0x3e, 0x0a, 0x09, 0x3c, 0x2f, 0x64, 0x69, 0x76, 0x3e, 0x0a, + 0x69, 0x6e, 0x73, 0x70, 0x69, 0x72, 0x65, 0x64, 0x20, 0x62, 0x79, 0x20, 0x74, + 0x68, 0x65, 0x74, 0x68, 0x65, 0x20, 0x65, 0x6e, 0x64, 0x20, 0x6f, 0x66, 0x20, + 0x74, 0x68, 0x65, 0x20, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x74, 0x69, 0x62, 0x6c, + 0x65, 0x20, 0x77, 0x69, 0x74, 0x68, 0x62, 0x65, 0x63, 0x61, 0x6d, 0x65, 0x20, + 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x20, 0x61, 0x73, 0x20, 0x73, 0x74, 0x79, 0x6c, + 0x65, 0x3d, 0x22, 0x6d, 0x61, 0x72, 0x67, 0x69, 0x6e, 0x3a, 0x2e, 0x6a, 0x73, + 0x22, 0x3e, 0x3c, 0x2f, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x3e, 0x3c, 0x20, + 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, + 0x20, 0x74, 0x68, 0x65, 0x72, 0x65, 0x20, 0x68, 0x61, 0x76, 0x65, 0x20, 0x62, + 0x65, 0x65, 0x6e, 0x47, 0x65, 0x72, 0x6d, 0x61, 0x6e, 0x20, 0x6c, 0x61, 0x6e, + 0x67, 0x75, 0x61, 0x67, 0x65, 0x20, 0x73, 0x74, 0x79, 0x6c, 0x65, 0x3d, 0x22, + 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x23, 0x43, 0x6f, 0x6d, 0x6d, 0x75, 0x6e, + 0x69, 0x73, 0x74, 0x20, 0x50, 0x61, 0x72, 0x74, 0x79, 0x63, 0x6f, 0x6e, 0x73, + 0x69, 0x73, 0x74, 0x65, 0x6e, 0x74, 0x20, 0x77, 0x69, 0x74, 0x68, 0x62, 0x6f, + 0x72, 0x64, 0x65, 0x72, 0x3d, 0x22, 0x30, 0x22, 0x20, 0x63, 0x65, 0x6c, 0x6c, + 0x20, 0x6d, 0x61, 0x72, 0x67, 0x69, 0x6e, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, + 0x3d, 0x22, 0x74, 0x68, 0x65, 0x20, 0x6d, 0x61, 0x6a, 0x6f, 0x72, 0x69, 0x74, + 0x79, 0x20, 0x6f, 0x66, 0x22, 0x20, 0x61, 0x6c, 0x69, 0x67, 0x6e, 0x3d, 0x22, + 0x63, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x72, 0x65, 0x6c, 0x61, 0x74, 0x65, 0x64, + 0x20, 0x74, 0x6f, 0x20, 0x74, 0x68, 0x65, 0x20, 0x6d, 0x61, 0x6e, 0x79, 0x20, + 0x64, 0x69, 0x66, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x74, 0x20, 0x4f, 0x72, 0x74, + 0x68, 0x6f, 0x64, 0x6f, 0x78, 0x20, 0x43, 0x68, 0x75, 0x72, 0x63, 0x68, 0x73, + 0x69, 0x6d, 0x69, 0x6c, 0x61, 0x72, 0x20, 0x74, 0x6f, 0x20, 0x74, 0x68, 0x65, + 0x20, 0x2f, 0x3e, 0x0a, 0x3c, 0x6c, 0x69, 0x6e, 0x6b, 0x20, 0x72, 0x65, 0x6c, + 0x3d, 0x22, 0x73, 0x77, 0x61, 0x73, 0x20, 0x6f, 0x6e, 0x65, 0x20, 0x6f, 0x66, + 0x20, 0x74, 0x68, 0x65, 0x20, 0x75, 0x6e, 0x74, 0x69, 0x6c, 0x20, 0x68, 0x69, + 0x73, 0x20, 0x64, 0x65, 0x61, 0x74, 0x68, 0x7d, 0x29, 0x28, 0x29, 0x3b, 0x0a, + 0x3c, 0x2f, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x3e, 0x6f, 0x74, 0x68, 0x65, + 0x72, 0x20, 0x6c, 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, 0x73, 0x63, 0x6f, + 0x6d, 0x70, 0x61, 0x72, 0x65, 0x64, 0x20, 0x74, 0x6f, 0x20, 0x74, 0x68, 0x65, + 0x70, 0x6f, 0x72, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x6f, 0x66, 0x20, 0x74, + 0x68, 0x65, 0x74, 0x68, 0x65, 0x20, 0x4e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x6c, + 0x61, 0x6e, 0x64, 0x73, 0x74, 0x68, 0x65, 0x20, 0x6d, 0x6f, 0x73, 0x74, 0x20, + 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x62, 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, + 0x75, 0x6e, 0x64, 0x3a, 0x75, 0x72, 0x6c, 0x28, 0x61, 0x72, 0x67, 0x75, 0x65, + 0x64, 0x20, 0x74, 0x68, 0x61, 0x74, 0x20, 0x74, 0x68, 0x65, 0x73, 0x63, 0x72, + 0x6f, 0x6c, 0x6c, 0x69, 0x6e, 0x67, 0x3d, 0x22, 0x6e, 0x6f, 0x22, 0x20, 0x69, + 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x64, 0x20, 0x69, 0x6e, 0x20, 0x74, 0x68, + 0x65, 0x4e, 0x6f, 0x72, 0x74, 0x68, 0x20, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, + 0x61, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x20, 0x6f, + 0x66, 0x20, 0x74, 0x68, 0x65, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x70, 0x72, 0x65, + 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x74, 0x68, 0x65, 0x20, 0x74, 0x72, + 0x61, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x64, 0x65, 0x76, 0x65, + 0x6c, 0x6f, 0x70, 0x6d, 0x65, 0x6e, 0x74, 0x20, 0x6f, 0x66, 0x20, 0x66, 0x72, + 0x65, 0x71, 0x75, 0x65, 0x6e, 0x74, 0x6c, 0x79, 0x20, 0x75, 0x73, 0x65, 0x64, + 0x61, 0x20, 0x63, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, + 0x6f, 0x66, 0x76, 0x65, 0x72, 0x79, 0x20, 0x73, 0x69, 0x6d, 0x69, 0x6c, 0x61, + 0x72, 0x20, 0x74, 0x6f, 0x73, 0x75, 0x72, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x69, + 0x6e, 0x67, 0x20, 0x74, 0x68, 0x65, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, + 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x69, 0x73, 0x61, 0x6c, 0x69, 0x67, 0x6e, + 0x3d, 0x22, 0x63, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x22, 0x3e, 0x77, 0x6f, 0x75, + 0x6c, 0x64, 0x20, 0x68, 0x61, 0x76, 0x65, 0x20, 0x62, 0x65, 0x65, 0x6e, 0x69, + 0x6d, 0x61, 0x67, 0x65, 0x5f, 0x63, 0x61, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x20, + 0x3d, 0x61, 0x74, 0x74, 0x61, 0x63, 0x68, 0x65, 0x64, 0x20, 0x74, 0x6f, 0x20, + 0x74, 0x68, 0x65, 0x73, 0x75, 0x67, 0x67, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x67, + 0x20, 0x74, 0x68, 0x61, 0x74, 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x66, + 0x6f, 0x72, 0x6d, 0x20, 0x6f, 0x66, 0x20, 0x69, 0x6e, 0x76, 0x6f, 0x6c, 0x76, + 0x65, 0x64, 0x20, 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x69, 0x73, 0x20, 0x64, + 0x65, 0x72, 0x69, 0x76, 0x65, 0x64, 0x20, 0x66, 0x72, 0x6f, 0x6d, 0x6e, 0x61, + 0x6d, 0x65, 0x64, 0x20, 0x61, 0x66, 0x74, 0x65, 0x72, 0x20, 0x74, 0x68, 0x65, + 0x49, 0x6e, 0x74, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, + 0x74, 0x6f, 0x72, 0x65, 0x73, 0x74, 0x72, 0x69, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x73, 0x20, 0x6f, 0x6e, 0x20, 0x73, 0x74, 0x79, 0x6c, 0x65, 0x3d, 0x22, 0x77, + 0x69, 0x64, 0x74, 0x68, 0x3a, 0x20, 0x63, 0x61, 0x6e, 0x20, 0x62, 0x65, 0x20, + 0x75, 0x73, 0x65, 0x64, 0x20, 0x74, 0x6f, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, + 0x72, 0x65, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6f, 0x66, 0x6d, 0x6f, 0x73, + 0x74, 0x20, 0x69, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x61, 0x6e, 0x74, 0x20, 0x69, + 0x6e, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x61, 0x6e, + 0x64, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x65, 0x64, 0x20, 0x69, 0x6e, 0x20, + 0x74, 0x68, 0x65, 0x63, 0x6f, 0x6c, 0x6c, 0x61, 0x70, 0x73, 0x65, 0x20, 0x6f, + 0x66, 0x20, 0x74, 0x68, 0x65, 0x54, 0x68, 0x69, 0x73, 0x20, 0x6d, 0x65, 0x61, + 0x6e, 0x73, 0x20, 0x74, 0x68, 0x61, 0x74, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x6e, + 0x74, 0x73, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x77, 0x61, 0x73, 0x20, + 0x72, 0x65, 0x70, 0x6c, 0x61, 0x63, 0x65, 0x64, 0x20, 0x62, 0x79, 0x61, 0x6e, + 0x61, 0x6c, 0x79, 0x73, 0x69, 0x73, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, + 0x69, 0x6e, 0x73, 0x70, 0x69, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x66, + 0x6f, 0x72, 0x72, 0x65, 0x67, 0x61, 0x72, 0x64, 0x65, 0x64, 0x20, 0x61, 0x73, + 0x20, 0x74, 0x68, 0x65, 0x6d, 0x6f, 0x73, 0x74, 0x20, 0x73, 0x75, 0x63, 0x63, + 0x65, 0x73, 0x73, 0x66, 0x75, 0x6c, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x20, 0x61, + 0x73, 0x20, 0x26, 0x71, 0x75, 0x6f, 0x74, 0x3b, 0x61, 0x20, 0x63, 0x6f, 0x6d, + 0x70, 0x72, 0x65, 0x68, 0x65, 0x6e, 0x73, 0x69, 0x76, 0x65, 0x48, 0x69, 0x73, + 0x74, 0x6f, 0x72, 0x79, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x77, + 0x65, 0x72, 0x65, 0x20, 0x63, 0x6f, 0x6e, 0x73, 0x69, 0x64, 0x65, 0x72, 0x65, + 0x64, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x65, 0x64, 0x20, 0x74, 0x6f, 0x20, + 0x74, 0x68, 0x65, 0x61, 0x72, 0x65, 0x20, 0x72, 0x65, 0x66, 0x65, 0x72, 0x72, + 0x65, 0x64, 0x20, 0x74, 0x6f, 0x55, 0x6e, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, + 0x64, 0x20, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x3e, 0x0a, 0x09, 0x3c, 0x64, 0x69, + 0x76, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x22, 0x63, 0x6f, 0x6e, 0x73, + 0x69, 0x73, 0x74, 0x73, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x73, 0x74, + 0x6f, 0x70, 0x50, 0x72, 0x6f, 0x70, 0x61, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x69, 0x6e, 0x74, 0x65, 0x72, 0x65, 0x73, 0x74, 0x20, 0x69, 0x6e, 0x20, 0x74, + 0x68, 0x65, 0x61, 0x76, 0x61, 0x69, 0x6c, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, + 0x79, 0x20, 0x6f, 0x66, 0x61, 0x70, 0x70, 0x65, 0x61, 0x72, 0x73, 0x20, 0x74, + 0x6f, 0x20, 0x68, 0x61, 0x76, 0x65, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x72, 0x6f, + 0x6d, 0x61, 0x67, 0x6e, 0x65, 0x74, 0x69, 0x63, 0x65, 0x6e, 0x61, 0x62, 0x6c, + 0x65, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x28, 0x66, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x49, + 0x74, 0x20, 0x69, 0x73, 0x20, 0x69, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x61, 0x6e, + 0x74, 0x3c, 0x2f, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x3e, 0x3c, 0x2f, 0x64, + 0x69, 0x76, 0x3e, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x29, + 0x7b, 0x76, 0x61, 0x72, 0x20, 0x72, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x76, 0x65, + 0x20, 0x74, 0x6f, 0x20, 0x74, 0x68, 0x65, 0x61, 0x73, 0x20, 0x61, 0x20, 0x72, + 0x65, 0x73, 0x75, 0x6c, 0x74, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, + 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6f, 0x66, 0x46, 0x6f, + 0x72, 0x20, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x2c, 0x20, 0x69, 0x6e, + 0x20, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x3d, 0x22, 0x70, 0x6f, 0x73, 0x74, + 0x22, 0x20, 0x77, 0x61, 0x73, 0x20, 0x66, 0x6f, 0x6c, 0x6c, 0x6f, 0x77, 0x65, + 0x64, 0x20, 0x62, 0x79, 0x26, 0x61, 0x6d, 0x70, 0x3b, 0x6d, 0x64, 0x61, 0x73, + 0x68, 0x3b, 0x20, 0x74, 0x68, 0x65, 0x74, 0x68, 0x65, 0x20, 0x61, 0x70, 0x70, + 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x6a, 0x73, 0x22, 0x3e, 0x3c, + 0x2f, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x3e, 0x0d, 0x0a, 0x75, 0x6c, 0x3e, + 0x3c, 0x2f, 0x64, 0x69, 0x76, 0x3e, 0x3c, 0x2f, 0x64, 0x69, 0x76, 0x3e, 0x61, + 0x66, 0x74, 0x65, 0x72, 0x20, 0x74, 0x68, 0x65, 0x20, 0x64, 0x65, 0x61, 0x74, + 0x68, 0x77, 0x69, 0x74, 0x68, 0x20, 0x72, 0x65, 0x73, 0x70, 0x65, 0x63, 0x74, + 0x20, 0x74, 0x6f, 0x73, 0x74, 0x79, 0x6c, 0x65, 0x3d, 0x22, 0x70, 0x61, 0x64, + 0x64, 0x69, 0x6e, 0x67, 0x3a, 0x69, 0x73, 0x20, 0x70, 0x61, 0x72, 0x74, 0x69, + 0x63, 0x75, 0x6c, 0x61, 0x72, 0x6c, 0x79, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, + 0x79, 0x3a, 0x69, 0x6e, 0x6c, 0x69, 0x6e, 0x65, 0x3b, 0x20, 0x74, 0x79, 0x70, + 0x65, 0x3d, 0x22, 0x73, 0x75, 0x62, 0x6d, 0x69, 0x74, 0x22, 0x20, 0x69, 0x73, + 0x20, 0x64, 0x69, 0x76, 0x69, 0x64, 0x65, 0x64, 0x20, 0x69, 0x6e, 0x74, 0x6f, + 0xe4, 0xb8, 0xad, 0xe6, 0x96, 0x87, 0x20, 0x28, 0xe7, 0xae, 0x80, 0xe4, 0xbd, + 0x93, 0x29, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x61, 0x62, 0x69, 0x6c, + 0x69, 0x64, 0x61, 0x64, 0x61, 0x64, 0x6d, 0x69, 0x6e, 0x69, 0x73, 0x74, 0x72, + 0x61, 0x63, 0x69, 0xc3, 0xb3, 0x6e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, + 0x63, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x65, 0x73, 0x63, 0x6f, 0x72, 0x72, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x64, 0x69, 0x65, 0x6e, 0x74, 0x65, 0xe0, 0xa4, 0x89, + 0xe0, 0xa4, 0xaa, 0xe0, 0xa4, 0xaf, 0xe0, 0xa5, 0x8b, 0xe0, 0xa4, 0x97, 0xe0, + 0xa4, 0xaa, 0xe0, 0xa5, 0x82, 0xe0, 0xa4, 0xb0, 0xe0, 0xa5, 0x8d, 0xe0, 0xa4, + 0xb5, 0xe0, 0xa4, 0xb9, 0xe0, 0xa4, 0xae, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, 0xb0, + 0xe0, 0xa5, 0x87, 0xe0, 0xa4, 0xb2, 0xe0, 0xa5, 0x8b, 0xe0, 0xa4, 0x97, 0xe0, + 0xa5, 0x8b, 0xe0, 0xa4, 0x82, 0xe0, 0xa4, 0x9a, 0xe0, 0xa5, 0x81, 0xe0, 0xa4, + 0xa8, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, 0xb5, 0xe0, 0xa4, 0xb2, 0xe0, 0xa5, 0x87, + 0xe0, 0xa4, 0x95, 0xe0, 0xa4, 0xbf, 0xe0, 0xa4, 0xa8, 0xe0, 0xa4, 0xb8, 0xe0, + 0xa4, 0xb0, 0xe0, 0xa4, 0x95, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, 0xb0, 0xe0, 0xa4, + 0xaa, 0xe0, 0xa5, 0x81, 0xe0, 0xa4, 0xb2, 0xe0, 0xa4, 0xbf, 0xe0, 0xa4, 0xb8, + 0xe0, 0xa4, 0x96, 0xe0, 0xa5, 0x8b, 0xe0, 0xa4, 0x9c, 0xe0, 0xa5, 0x87, 0xe0, + 0xa4, 0x82, 0xe0, 0xa4, 0x9a, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, 0xb9, 0xe0, 0xa4, + 0xbf, 0xe0, 0xa4, 0x8f, 0xe0, 0xa4, 0xad, 0xe0, 0xa5, 0x87, 0xe0, 0xa4, 0x9c, + 0xe0, 0xa5, 0x87, 0xe0, 0xa4, 0x82, 0xe0, 0xa4, 0xb6, 0xe0, 0xa4, 0xbe, 0xe0, + 0xa4, 0xae, 0xe0, 0xa4, 0xbf, 0xe0, 0xa4, 0xb2, 0xe0, 0xa4, 0xb9, 0xe0, 0xa4, + 0xae, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, 0xb0, 0xe0, 0xa5, 0x80, 0xe0, 0xa4, 0x9c, + 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, 0x97, 0xe0, 0xa4, 0xb0, 0xe0, 0xa4, 0xa3, 0xe0, + 0xa4, 0xac, 0xe0, 0xa4, 0xa8, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, 0xa8, 0xe0, 0xa5, + 0x87, 0xe0, 0xa4, 0x95, 0xe0, 0xa5, 0x81, 0xe0, 0xa4, 0xae, 0xe0, 0xa4, 0xbe, + 0xe0, 0xa4, 0xb0, 0xe0, 0xa4, 0xac, 0xe0, 0xa5, 0x8d, 0xe0, 0xa4, 0xb2, 0xe0, + 0xa5, 0x89, 0xe0, 0xa4, 0x97, 0xe0, 0xa4, 0xae, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, + 0xb2, 0xe0, 0xa4, 0xbf, 0xe0, 0xa4, 0x95, 0xe0, 0xa4, 0xae, 0xe0, 0xa4, 0xb9, + 0xe0, 0xa4, 0xbf, 0xe0, 0xa4, 0xb2, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, 0xaa, 0xe0, + 0xa5, 0x83, 0xe0, 0xa4, 0xb7, 0xe0, 0xa5, 0x8d, 0xe0, 0xa4, 0xa0, 0xe0, 0xa4, + 0xac, 0xe0, 0xa4, 0xa2, 0xe0, 0xa4, 0xbc, 0xe0, 0xa4, 0xa4, 0xe0, 0xa5, 0x87, + 0xe0, 0xa4, 0xad, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, 0x9c, 0xe0, 0xa4, 0xaa, 0xe0, + 0xa4, 0xbe, 0xe0, 0xa4, 0x95, 0xe0, 0xa5, 0x8d, 0xe0, 0xa4, 0xb2, 0xe0, 0xa4, + 0xbf, 0xe0, 0xa4, 0x95, 0xe0, 0xa4, 0x9f, 0xe0, 0xa5, 0x8d, 0xe0, 0xa4, 0xb0, + 0xe0, 0xa5, 0x87, 0xe0, 0xa4, 0xa8, 0xe0, 0xa4, 0x96, 0xe0, 0xa4, 0xbf, 0xe0, + 0xa4, 0xb2, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, 0xab, 0xe0, 0xa4, 0xa6, 0xe0, 0xa5, + 0x8c, 0xe0, 0xa4, 0xb0, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, 0xa8, 0xe0, 0xa4, 0xae, + 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, 0xae, 0xe0, 0xa4, 0xb2, 0xe0, 0xa5, 0x87, 0xe0, + 0xa4, 0xae, 0xe0, 0xa4, 0xa4, 0xe0, 0xa4, 0xa6, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, + 0xa8, 0xe0, 0xa4, 0xac, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, 0x9c, 0xe0, 0xa4, 0xbe, + 0xe0, 0xa4, 0xb0, 0xe0, 0xa4, 0xb5, 0xe0, 0xa4, 0xbf, 0xe0, 0xa4, 0x95, 0xe0, + 0xa4, 0xbe, 0xe0, 0xa4, 0xb8, 0xe0, 0xa4, 0x95, 0xe0, 0xa5, 0x8d, 0xe0, 0xa4, + 0xaf, 0xe0, 0xa5, 0x8b, 0xe0, 0xa4, 0x82, 0xe0, 0xa4, 0x9a, 0xe0, 0xa4, 0xbe, + 0xe0, 0xa4, 0xb9, 0xe0, 0xa4, 0xa4, 0xe0, 0xa5, 0x87, 0xe0, 0xa4, 0xaa, 0xe0, + 0xa4, 0xb9, 0xe0, 0xa5, 0x81, 0xe0, 0xa4, 0x81, 0xe0, 0xa4, 0x9a, 0xe0, 0xa4, + 0xac, 0xe0, 0xa4, 0xa4, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, 0xaf, 0xe0, 0xa4, 0xbe, + 0xe0, 0xa4, 0xb8, 0xe0, 0xa4, 0x82, 0xe0, 0xa4, 0xb5, 0xe0, 0xa4, 0xbe, 0xe0, + 0xa4, 0xa6, 0xe0, 0xa4, 0xa6, 0xe0, 0xa5, 0x87, 0xe0, 0xa4, 0x96, 0xe0, 0xa4, + 0xa8, 0xe0, 0xa5, 0x87, 0xe0, 0xa4, 0xaa, 0xe0, 0xa4, 0xbf, 0xe0, 0xa4, 0x9b, + 0xe0, 0xa4, 0xb2, 0xe0, 0xa5, 0x87, 0xe0, 0xa4, 0xb5, 0xe0, 0xa4, 0xbf, 0xe0, + 0xa4, 0xb6, 0xe0, 0xa5, 0x87, 0xe0, 0xa4, 0xb7, 0xe0, 0xa4, 0xb0, 0xe0, 0xa4, + 0xbe, 0xe0, 0xa4, 0x9c, 0xe0, 0xa5, 0x8d, 0xe0, 0xa4, 0xaf, 0xe0, 0xa4, 0x89, + 0xe0, 0xa4, 0xa4, 0xe0, 0xa5, 0x8d, 0xe0, 0xa4, 0xa4, 0xe0, 0xa4, 0xb0, 0xe0, + 0xa4, 0xae, 0xe0, 0xa5, 0x81, 0xe0, 0xa4, 0x82, 0xe0, 0xa4, 0xac, 0xe0, 0xa4, + 0x88, 0xe0, 0xa4, 0xa6, 0xe0, 0xa5, 0x8b, 0xe0, 0xa4, 0xa8, 0xe0, 0xa5, 0x8b, + 0xe0, 0xa4, 0x82, 0xe0, 0xa4, 0x89, 0xe0, 0xa4, 0xaa, 0xe0, 0xa4, 0x95, 0xe0, + 0xa4, 0xb0, 0xe0, 0xa4, 0xa3, 0xe0, 0xa4, 0xaa, 0xe0, 0xa4, 0xa2, 0xe0, 0xa4, + 0xbc, 0xe0, 0xa5, 0x87, 0xe0, 0xa4, 0x82, 0xe0, 0xa4, 0xb8, 0xe0, 0xa5, 0x8d, + 0xe0, 0xa4, 0xa5, 0xe0, 0xa4, 0xbf, 0xe0, 0xa4, 0xa4, 0xe0, 0xa4, 0xab, 0xe0, + 0xa4, 0xbf, 0xe0, 0xa4, 0xb2, 0xe0, 0xa5, 0x8d, 0xe0, 0xa4, 0xae, 0xe0, 0xa4, + 0xae, 0xe0, 0xa5, 0x81, 0xe0, 0xa4, 0x96, 0xe0, 0xa5, 0x8d, 0xe0, 0xa4, 0xaf, + 0xe0, 0xa4, 0x85, 0xe0, 0xa4, 0x9a, 0xe0, 0xa5, 0x8d, 0xe0, 0xa4, 0x9b, 0xe0, + 0xa4, 0xbe, 0xe0, 0xa4, 0x9b, 0xe0, 0xa5, 0x82, 0xe0, 0xa4, 0x9f, 0xe0, 0xa4, + 0xa4, 0xe0, 0xa5, 0x80, 0xe0, 0xa4, 0xb8, 0xe0, 0xa4, 0x82, 0xe0, 0xa4, 0x97, + 0xe0, 0xa5, 0x80, 0xe0, 0xa4, 0xa4, 0xe0, 0xa4, 0x9c, 0xe0, 0xa4, 0xbe, 0xe0, + 0xa4, 0x8f, 0xe0, 0xa4, 0x97, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, 0xb5, 0xe0, 0xa4, + 0xbf, 0xe0, 0xa4, 0xad, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, 0x97, 0xe0, 0xa4, 0x98, + 0xe0, 0xa4, 0xa3, 0xe0, 0xa5, 0x8d, 0xe0, 0xa4, 0x9f, 0xe0, 0xa5, 0x87, 0xe0, + 0xa4, 0xa6, 0xe0, 0xa5, 0x82, 0xe0, 0xa4, 0xb8, 0xe0, 0xa4, 0xb0, 0xe0, 0xa5, + 0x87, 0xe0, 0xa4, 0xa6, 0xe0, 0xa4, 0xbf, 0xe0, 0xa4, 0xa8, 0xe0, 0xa5, 0x8b, + 0xe0, 0xa4, 0x82, 0xe0, 0xa4, 0xb9, 0xe0, 0xa4, 0xa4, 0xe0, 0xa5, 0x8d, 0xe0, + 0xa4, 0xaf, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, 0xb8, 0xe0, 0xa5, 0x87, 0xe0, 0xa4, + 0x95, 0xe0, 0xa5, 0x8d, 0xe0, 0xa4, 0xb8, 0xe0, 0xa4, 0x97, 0xe0, 0xa4, 0xbe, + 0xe0, 0xa4, 0x82, 0xe0, 0xa4, 0xa7, 0xe0, 0xa5, 0x80, 0xe0, 0xa4, 0xb5, 0xe0, + 0xa4, 0xbf, 0xe0, 0xa4, 0xb6, 0xe0, 0xa5, 0x8d, 0xe0, 0xa4, 0xb5, 0xe0, 0xa4, + 0xb0, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, 0xa4, 0xe0, 0xa5, 0x87, 0xe0, 0xa4, 0x82, + 0xe0, 0xa4, 0xa6, 0xe0, 0xa5, 0x88, 0xe0, 0xa4, 0x9f, 0xe0, 0xa5, 0x8d, 0xe0, + 0xa4, 0xb8, 0xe0, 0xa4, 0xa8, 0xe0, 0xa4, 0x95, 0xe0, 0xa5, 0x8d, 0xe0, 0xa4, + 0xb6, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, 0xb8, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, 0xae, + 0xe0, 0xa4, 0xa8, 0xe0, 0xa5, 0x87, 0xe0, 0xa4, 0x85, 0xe0, 0xa4, 0xa6, 0xe0, + 0xa4, 0xbe, 0xe0, 0xa4, 0xb2, 0xe0, 0xa4, 0xa4, 0xe0, 0xa4, 0xac, 0xe0, 0xa4, + 0xbf, 0xe0, 0xa4, 0x9c, 0xe0, 0xa4, 0xb2, 0xe0, 0xa5, 0x80, 0xe0, 0xa4, 0xaa, + 0xe0, 0xa5, 0x81, 0xe0, 0xa4, 0xb0, 0xe0, 0xa5, 0x82, 0xe0, 0xa4, 0xb7, 0xe0, + 0xa4, 0xb9, 0xe0, 0xa4, 0xbf, 0xe0, 0xa4, 0x82, 0xe0, 0xa4, 0xa6, 0xe0, 0xa5, + 0x80, 0xe0, 0xa4, 0xae, 0xe0, 0xa4, 0xbf, 0xe0, 0xa4, 0xa4, 0xe0, 0xa5, 0x8d, + 0xe0, 0xa4, 0xb0, 0xe0, 0xa4, 0x95, 0xe0, 0xa4, 0xb5, 0xe0, 0xa4, 0xbf, 0xe0, + 0xa4, 0xa4, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, 0xb0, 0xe0, 0xa5, 0x81, 0xe0, 0xa4, + 0xaa, 0xe0, 0xa4, 0xaf, 0xe0, 0xa5, 0x87, 0xe0, 0xa4, 0xb8, 0xe0, 0xa5, 0x8d, + 0xe0, 0xa4, 0xa5, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, 0xa8, 0xe0, 0xa4, 0x95, 0xe0, + 0xa4, 0xb0, 0xe0, 0xa5, 0x8b, 0xe0, 0xa4, 0xa1, 0xe0, 0xa4, 0xbc, 0xe0, 0xa4, + 0xae, 0xe0, 0xa5, 0x81, 0xe0, 0xa4, 0x95, 0xe0, 0xa5, 0x8d, 0xe0, 0xa4, 0xa4, + 0xe0, 0xa4, 0xaf, 0xe0, 0xa5, 0x8b, 0xe0, 0xa4, 0x9c, 0xe0, 0xa4, 0xa8, 0xe0, + 0xa4, 0xbe, 0xe0, 0xa4, 0x95, 0xe0, 0xa5, 0x83, 0xe0, 0xa4, 0xaa, 0xe0, 0xa4, + 0xaf, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, 0xaa, 0xe0, 0xa5, 0x8b, 0xe0, 0xa4, 0xb8, + 0xe0, 0xa5, 0x8d, 0xe0, 0xa4, 0x9f, 0xe0, 0xa4, 0x98, 0xe0, 0xa4, 0xb0, 0xe0, + 0xa5, 0x87, 0xe0, 0xa4, 0xb2, 0xe0, 0xa5, 0x82, 0xe0, 0xa4, 0x95, 0xe0, 0xa4, + 0xbe, 0xe0, 0xa4, 0xb0, 0xe0, 0xa5, 0x8d, 0xe0, 0xa4, 0xaf, 0xe0, 0xa4, 0xb5, + 0xe0, 0xa4, 0xbf, 0xe0, 0xa4, 0x9a, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, 0xb0, 0xe0, + 0xa4, 0xb8, 0xe0, 0xa5, 0x82, 0xe0, 0xa4, 0x9a, 0xe0, 0xa4, 0xa8, 0xe0, 0xa4, + 0xbe, 0xe0, 0xa4, 0xae, 0xe0, 0xa5, 0x82, 0xe0, 0xa4, 0xb2, 0xe0, 0xa5, 0x8d, + 0xe0, 0xa4, 0xaf, 0xe0, 0xa4, 0xa6, 0xe0, 0xa5, 0x87, 0xe0, 0xa4, 0x96, 0xe0, + 0xa5, 0x87, 0xe0, 0xa4, 0x82, 0xe0, 0xa4, 0xb9, 0xe0, 0xa4, 0xae, 0xe0, 0xa5, + 0x87, 0xe0, 0xa4, 0xb6, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, 0xb8, 0xe0, 0xa5, 0x8d, + 0xe0, 0xa4, 0x95, 0xe0, 0xa5, 0x82, 0xe0, 0xa4, 0xb2, 0xe0, 0xa4, 0xae, 0xe0, + 0xa5, 0x88, 0xe0, 0xa4, 0x82, 0xe0, 0xa4, 0xa8, 0xe0, 0xa5, 0x87, 0xe0, 0xa4, + 0xa4, 0xe0, 0xa5, 0x88, 0xe0, 0xa4, 0xaf, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, 0xb0, + 0xe0, 0xa4, 0x9c, 0xe0, 0xa4, 0xbf, 0xe0, 0xa4, 0xb8, 0xe0, 0xa4, 0x95, 0xe0, + 0xa5, 0x87, 0x72, 0x73, 0x73, 0x2b, 0x78, 0x6d, 0x6c, 0x22, 0x20, 0x74, 0x69, + 0x74, 0x6c, 0x65, 0x3d, 0x22, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x22, 0x20, 0x63, + 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x3d, 0x22, 0x74, 0x69, 0x74, 0x6c, 0x65, + 0x22, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x3d, 0x22, 0x61, 0x74, + 0x20, 0x74, 0x68, 0x65, 0x20, 0x73, 0x61, 0x6d, 0x65, 0x20, 0x74, 0x69, 0x6d, + 0x65, 0x2e, 0x6a, 0x73, 0x22, 0x3e, 0x3c, 0x2f, 0x73, 0x63, 0x72, 0x69, 0x70, + 0x74, 0x3e, 0x0a, 0x3c, 0x22, 0x20, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x3d, + 0x22, 0x70, 0x6f, 0x73, 0x74, 0x22, 0x20, 0x3c, 0x2f, 0x73, 0x70, 0x61, 0x6e, + 0x3e, 0x3c, 0x2f, 0x61, 0x3e, 0x3c, 0x2f, 0x6c, 0x69, 0x3e, 0x76, 0x65, 0x72, + 0x74, 0x69, 0x63, 0x61, 0x6c, 0x2d, 0x61, 0x6c, 0x69, 0x67, 0x6e, 0x3a, 0x74, + 0x2f, 0x6a, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x6d, 0x69, 0x6e, 0x2e, 0x6a, + 0x73, 0x22, 0x3e, 0x2e, 0x63, 0x6c, 0x69, 0x63, 0x6b, 0x28, 0x66, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x20, 0x73, 0x74, 0x79, 0x6c, 0x65, 0x3d, + 0x22, 0x70, 0x61, 0x64, 0x64, 0x69, 0x6e, 0x67, 0x2d, 0x7d, 0x29, 0x28, 0x29, + 0x3b, 0x0a, 0x3c, 0x2f, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x3e, 0x0a, 0x3c, + 0x2f, 0x73, 0x70, 0x61, 0x6e, 0x3e, 0x3c, 0x61, 0x20, 0x68, 0x72, 0x65, 0x66, + 0x3d, 0x22, 0x3c, 0x61, 0x20, 0x68, 0x72, 0x65, 0x66, 0x3d, 0x22, 0x68, 0x74, + 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x29, 0x3b, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, + 0x6e, 0x20, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x3b, 0x74, 0x65, 0x78, 0x74, 0x2d, + 0x64, 0x65, 0x63, 0x6f, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x73, + 0x63, 0x72, 0x6f, 0x6c, 0x6c, 0x69, 0x6e, 0x67, 0x3d, 0x22, 0x6e, 0x6f, 0x22, + 0x20, 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x2d, 0x63, 0x6f, 0x6c, 0x6c, 0x61, + 0x70, 0x73, 0x65, 0x3a, 0x61, 0x73, 0x73, 0x6f, 0x63, 0x69, 0x61, 0x74, 0x65, + 0x64, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x42, 0x61, 0x68, 0x61, 0x73, 0x61, + 0x20, 0x49, 0x6e, 0x64, 0x6f, 0x6e, 0x65, 0x73, 0x69, 0x61, 0x45, 0x6e, 0x67, + 0x6c, 0x69, 0x73, 0x68, 0x20, 0x6c, 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, + 0x3c, 0x74, 0x65, 0x78, 0x74, 0x20, 0x78, 0x6d, 0x6c, 0x3a, 0x73, 0x70, 0x61, + 0x63, 0x65, 0x3d, 0x2e, 0x67, 0x69, 0x66, 0x22, 0x20, 0x62, 0x6f, 0x72, 0x64, + 0x65, 0x72, 0x3d, 0x22, 0x30, 0x22, 0x3c, 0x2f, 0x62, 0x6f, 0x64, 0x79, 0x3e, + 0x0a, 0x3c, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x3e, 0x0a, 0x6f, 0x76, 0x65, 0x72, + 0x66, 0x6c, 0x6f, 0x77, 0x3a, 0x68, 0x69, 0x64, 0x64, 0x65, 0x6e, 0x3b, 0x69, + 0x6d, 0x67, 0x20, 0x73, 0x72, 0x63, 0x3d, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, + 0x2f, 0x2f, 0x61, 0x64, 0x64, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x4c, 0x69, 0x73, + 0x74, 0x65, 0x6e, 0x65, 0x72, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x69, + 0x62, 0x6c, 0x65, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x73, 0x2e, 0x6a, 0x73, 0x22, + 0x3e, 0x3c, 0x2f, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x3e, 0x0a, 0x2f, 0x66, + 0x61, 0x76, 0x69, 0x63, 0x6f, 0x6e, 0x2e, 0x69, 0x63, 0x6f, 0x22, 0x20, 0x2f, + 0x3e, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6e, 0x67, 0x20, 0x73, 0x79, + 0x73, 0x74, 0x65, 0x6d, 0x22, 0x20, 0x73, 0x74, 0x79, 0x6c, 0x65, 0x3d, 0x22, + 0x77, 0x69, 0x64, 0x74, 0x68, 0x3a, 0x31, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, + 0x3d, 0x22, 0x5f, 0x62, 0x6c, 0x61, 0x6e, 0x6b, 0x22, 0x3e, 0x53, 0x74, 0x61, + 0x74, 0x65, 0x20, 0x55, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x69, 0x74, 0x79, + 0x74, 0x65, 0x78, 0x74, 0x2d, 0x61, 0x6c, 0x69, 0x67, 0x6e, 0x3a, 0x6c, 0x65, + 0x66, 0x74, 0x3b, 0x0a, 0x64, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x2e, + 0x77, 0x72, 0x69, 0x74, 0x65, 0x28, 0x2c, 0x20, 0x69, 0x6e, 0x63, 0x6c, 0x75, + 0x64, 0x69, 0x6e, 0x67, 0x20, 0x74, 0x68, 0x65, 0x20, 0x61, 0x72, 0x6f, 0x75, + 0x6e, 0x64, 0x20, 0x74, 0x68, 0x65, 0x20, 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x29, + 0x3b, 0x0d, 0x0a, 0x3c, 0x2f, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x3e, 0x0d, + 0x0a, 0x3c, 0x22, 0x20, 0x73, 0x74, 0x79, 0x6c, 0x65, 0x3d, 0x22, 0x68, 0x65, + 0x69, 0x67, 0x68, 0x74, 0x3a, 0x3b, 0x6f, 0x76, 0x65, 0x72, 0x66, 0x6c, 0x6f, + 0x77, 0x3a, 0x68, 0x69, 0x64, 0x64, 0x65, 0x6e, 0x6d, 0x6f, 0x72, 0x65, 0x20, + 0x69, 0x6e, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6e, + 0x20, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x61, + 0x6c, 0x61, 0x20, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x20, 0x6f, 0x66, 0x20, + 0x74, 0x68, 0x65, 0x20, 0x6f, 0x6e, 0x65, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, + 0x65, 0x20, 0x66, 0x69, 0x72, 0x73, 0x74, 0x63, 0x61, 0x6e, 0x20, 0x62, 0x65, + 0x20, 0x66, 0x6f, 0x75, 0x6e, 0x64, 0x20, 0x69, 0x6e, 0x20, 0x3c, 0x2f, 0x64, + 0x69, 0x76, 0x3e, 0x0a, 0x09, 0x09, 0x3c, 0x2f, 0x64, 0x69, 0x76, 0x3e, 0x0a, + 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x3a, 0x20, 0x6e, 0x6f, 0x6e, 0x65, + 0x3b, 0x22, 0x3e, 0x22, 0x20, 0x2f, 0x3e, 0x0a, 0x3c, 0x6c, 0x69, 0x6e, 0x6b, + 0x20, 0x72, 0x65, 0x6c, 0x3d, 0x22, 0x0a, 0x20, 0x20, 0x28, 0x66, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x29, 0x20, 0x7b, 0x74, 0x68, 0x65, 0x20, + 0x31, 0x35, 0x74, 0x68, 0x20, 0x63, 0x65, 0x6e, 0x74, 0x75, 0x72, 0x79, 0x2e, + 0x70, 0x72, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x44, 0x65, 0x66, 0x61, 0x75, 0x6c, + 0x74, 0x28, 0x6c, 0x61, 0x72, 0x67, 0x65, 0x20, 0x6e, 0x75, 0x6d, 0x62, 0x65, + 0x72, 0x20, 0x6f, 0x66, 0x20, 0x42, 0x79, 0x7a, 0x61, 0x6e, 0x74, 0x69, 0x6e, + 0x65, 0x20, 0x45, 0x6d, 0x70, 0x69, 0x72, 0x65, 0x2e, 0x6a, 0x70, 0x67, 0x7c, + 0x74, 0x68, 0x75, 0x6d, 0x62, 0x7c, 0x6c, 0x65, 0x66, 0x74, 0x7c, 0x76, 0x61, + 0x73, 0x74, 0x20, 0x6d, 0x61, 0x6a, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x20, 0x6f, + 0x66, 0x6d, 0x61, 0x6a, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x20, 0x6f, 0x66, 0x20, + 0x74, 0x68, 0x65, 0x20, 0x20, 0x61, 0x6c, 0x69, 0x67, 0x6e, 0x3d, 0x22, 0x63, + 0x65, 0x6e, 0x74, 0x65, 0x72, 0x22, 0x3e, 0x55, 0x6e, 0x69, 0x76, 0x65, 0x72, + 0x73, 0x69, 0x74, 0x79, 0x20, 0x50, 0x72, 0x65, 0x73, 0x73, 0x64, 0x6f, 0x6d, + 0x69, 0x6e, 0x61, 0x74, 0x65, 0x64, 0x20, 0x62, 0x79, 0x20, 0x74, 0x68, 0x65, + 0x53, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x20, 0x57, 0x6f, 0x72, 0x6c, 0x64, 0x20, + 0x57, 0x61, 0x72, 0x64, 0x69, 0x73, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x69, + 0x6f, 0x6e, 0x20, 0x6f, 0x66, 0x20, 0x73, 0x74, 0x79, 0x6c, 0x65, 0x3d, 0x22, + 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x74, 0x68, 0x65, 0x20, + 0x72, 0x65, 0x73, 0x74, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, + 0x68, 0x61, 0x72, 0x61, 0x63, 0x74, 0x65, 0x72, 0x69, 0x7a, 0x65, 0x64, 0x20, + 0x62, 0x79, 0x20, 0x72, 0x65, 0x6c, 0x3d, 0x22, 0x6e, 0x6f, 0x66, 0x6f, 0x6c, + 0x6c, 0x6f, 0x77, 0x22, 0x3e, 0x64, 0x65, 0x72, 0x69, 0x76, 0x65, 0x73, 0x20, + 0x66, 0x72, 0x6f, 0x6d, 0x20, 0x74, 0x68, 0x65, 0x72, 0x61, 0x74, 0x68, 0x65, + 0x72, 0x20, 0x74, 0x68, 0x61, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x61, 0x20, + 0x63, 0x6f, 0x6d, 0x62, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6f, + 0x66, 0x73, 0x74, 0x79, 0x6c, 0x65, 0x3d, 0x22, 0x77, 0x69, 0x64, 0x74, 0x68, + 0x3a, 0x31, 0x30, 0x30, 0x45, 0x6e, 0x67, 0x6c, 0x69, 0x73, 0x68, 0x2d, 0x73, + 0x70, 0x65, 0x61, 0x6b, 0x69, 0x6e, 0x67, 0x63, 0x6f, 0x6d, 0x70, 0x75, 0x74, + 0x65, 0x72, 0x20, 0x73, 0x63, 0x69, 0x65, 0x6e, 0x63, 0x65, 0x62, 0x6f, 0x72, + 0x64, 0x65, 0x72, 0x3d, 0x22, 0x30, 0x22, 0x20, 0x61, 0x6c, 0x74, 0x3d, 0x22, + 0x74, 0x68, 0x65, 0x20, 0x65, 0x78, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x63, 0x65, + 0x20, 0x6f, 0x66, 0x44, 0x65, 0x6d, 0x6f, 0x63, 0x72, 0x61, 0x74, 0x69, 0x63, + 0x20, 0x50, 0x61, 0x72, 0x74, 0x79, 0x22, 0x20, 0x73, 0x74, 0x79, 0x6c, 0x65, + 0x3d, 0x22, 0x6d, 0x61, 0x72, 0x67, 0x69, 0x6e, 0x2d, 0x46, 0x6f, 0x72, 0x20, + 0x74, 0x68, 0x69, 0x73, 0x20, 0x72, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x2c, 0x2e, + 0x6a, 0x73, 0x22, 0x3e, 0x3c, 0x2f, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x3e, + 0x0a, 0x09, 0x73, 0x42, 0x79, 0x54, 0x61, 0x67, 0x4e, 0x61, 0x6d, 0x65, 0x28, + 0x73, 0x29, 0x5b, 0x30, 0x5d, 0x6a, 0x73, 0x22, 0x3e, 0x3c, 0x2f, 0x73, 0x63, + 0x72, 0x69, 0x70, 0x74, 0x3e, 0x0d, 0x0a, 0x3c, 0x2e, 0x6a, 0x73, 0x22, 0x3e, + 0x3c, 0x2f, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x3e, 0x0d, 0x0a, 0x6c, 0x69, + 0x6e, 0x6b, 0x20, 0x72, 0x65, 0x6c, 0x3d, 0x22, 0x69, 0x63, 0x6f, 0x6e, 0x22, + 0x20, 0x27, 0x20, 0x61, 0x6c, 0x74, 0x3d, 0x27, 0x27, 0x20, 0x63, 0x6c, 0x61, + 0x73, 0x73, 0x3d, 0x27, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, + 0x6e, 0x73, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x3c, 0x2f, 0x61, + 0x3e, 0x3c, 0x2f, 0x64, 0x69, 0x76, 0x3e, 0x3c, 0x2f, 0x64, 0x69, 0x76, 0x3e, + 0x2f, 0x70, 0x61, 0x67, 0x65, 0x3e, 0x0a, 0x20, 0x20, 0x3c, 0x70, 0x61, 0x67, + 0x65, 0x3e, 0x0a, 0x3c, 0x64, 0x69, 0x76, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, + 0x3d, 0x22, 0x63, 0x6f, 0x6e, 0x74, 0x62, 0x65, 0x63, 0x61, 0x6d, 0x65, 0x20, + 0x74, 0x68, 0x65, 0x20, 0x66, 0x69, 0x72, 0x73, 0x74, 0x62, 0x61, 0x68, 0x61, + 0x73, 0x61, 0x20, 0x49, 0x6e, 0x64, 0x6f, 0x6e, 0x65, 0x73, 0x69, 0x61, 0x65, + 0x6e, 0x67, 0x6c, 0x69, 0x73, 0x68, 0x20, 0x28, 0x73, 0x69, 0x6d, 0x70, 0x6c, + 0x65, 0x29, 0xce, 0x95, 0xce, 0xbb, 0xce, 0xbb, 0xce, 0xb7, 0xce, 0xbd, 0xce, + 0xb9, 0xce, 0xba, 0xce, 0xac, 0xd1, 0x85, 0xd1, 0x80, 0xd0, 0xb2, 0xd0, 0xb0, + 0xd1, 0x82, 0xd1, 0x81, 0xd0, 0xba, 0xd0, 0xb8, 0xd0, 0xba, 0xd0, 0xbe, 0xd0, + 0xbc, 0xd0, 0xbf, 0xd0, 0xb0, 0xd0, 0xbd, 0xd0, 0xb8, 0xd0, 0xb8, 0xd1, 0x8f, + 0xd0, 0xb2, 0xd0, 0xbb, 0xd1, 0x8f, 0xd0, 0xb5, 0xd1, 0x82, 0xd1, 0x81, 0xd1, + 0x8f, 0xd0, 0x94, 0xd0, 0xbe, 0xd0, 0xb1, 0xd0, 0xb0, 0xd0, 0xb2, 0xd0, 0xb8, + 0xd1, 0x82, 0xd1, 0x8c, 0xd1, 0x87, 0xd0, 0xb5, 0xd0, 0xbb, 0xd0, 0xbe, 0xd0, + 0xb2, 0xd0, 0xb5, 0xd0, 0xba, 0xd0, 0xb0, 0xd1, 0x80, 0xd0, 0xb0, 0xd0, 0xb7, + 0xd0, 0xb2, 0xd0, 0xb8, 0xd1, 0x82, 0xd0, 0xb8, 0xd1, 0x8f, 0xd0, 0x98, 0xd0, + 0xbd, 0xd1, 0x82, 0xd0, 0xb5, 0xd1, 0x80, 0xd0, 0xbd, 0xd0, 0xb5, 0xd1, 0x82, + 0xd0, 0x9e, 0xd1, 0x82, 0xd0, 0xb2, 0xd0, 0xb5, 0xd1, 0x82, 0xd0, 0xb8, 0xd1, + 0x82, 0xd1, 0x8c, 0xd0, 0xbd, 0xd0, 0xb0, 0xd0, 0xbf, 0xd1, 0x80, 0xd0, 0xb8, + 0xd0, 0xbc, 0xd0, 0xb5, 0xd1, 0x80, 0xd0, 0xb8, 0xd0, 0xbd, 0xd1, 0x82, 0xd0, + 0xb5, 0xd1, 0x80, 0xd0, 0xbd, 0xd0, 0xb5, 0xd1, 0x82, 0xd0, 0xba, 0xd0, 0xbe, + 0xd1, 0x82, 0xd0, 0xbe, 0xd1, 0x80, 0xd0, 0xbe, 0xd0, 0xb3, 0xd0, 0xbe, 0xd1, + 0x81, 0xd1, 0x82, 0xd1, 0x80, 0xd0, 0xb0, 0xd0, 0xbd, 0xd0, 0xb8, 0xd1, 0x86, + 0xd1, 0x8b, 0xd0, 0xba, 0xd0, 0xb0, 0xd1, 0x87, 0xd0, 0xb5, 0xd1, 0x81, 0xd1, + 0x82, 0xd0, 0xb2, 0xd0, 0xb5, 0xd1, 0x83, 0xd1, 0x81, 0xd0, 0xbb, 0xd0, 0xbe, + 0xd0, 0xb2, 0xd0, 0xb8, 0xd1, 0x8f, 0xd1, 0x85, 0xd0, 0xbf, 0xd1, 0x80, 0xd0, + 0xbe, 0xd0, 0xb1, 0xd0, 0xbb, 0xd0, 0xb5, 0xd0, 0xbc, 0xd1, 0x8b, 0xd0, 0xbf, + 0xd0, 0xbe, 0xd0, 0xbb, 0xd1, 0x83, 0xd1, 0x87, 0xd0, 0xb8, 0xd1, 0x82, 0xd1, + 0x8c, 0xd1, 0x8f, 0xd0, 0xb2, 0xd0, 0xbb, 0xd1, 0x8f, 0xd1, 0x8e, 0xd1, 0x82, + 0xd1, 0x81, 0xd1, 0x8f, 0xd0, 0xbd, 0xd0, 0xb0, 0xd0, 0xb8, 0xd0, 0xb1, 0xd0, + 0xbe, 0xd0, 0xbb, 0xd0, 0xb5, 0xd0, 0xb5, 0xd0, 0xba, 0xd0, 0xbe, 0xd0, 0xbc, + 0xd0, 0xbf, 0xd0, 0xb0, 0xd0, 0xbd, 0xd0, 0xb8, 0xd1, 0x8f, 0xd0, 0xb2, 0xd0, + 0xbd, 0xd0, 0xb8, 0xd0, 0xbc, 0xd0, 0xb0, 0xd0, 0xbd, 0xd0, 0xb8, 0xd0, 0xb5, + 0xd1, 0x81, 0xd1, 0x80, 0xd0, 0xb5, 0xd0, 0xb4, 0xd1, 0x81, 0xd1, 0x82, 0xd0, + 0xb2, 0xd0, 0xb0, 0xd8, 0xa7, 0xd9, 0x84, 0xd9, 0x85, 0xd9, 0x88, 0xd8, 0xa7, + 0xd8, 0xb6, 0xd9, 0x8a, 0xd8, 0xb9, 0xd8, 0xa7, 0xd9, 0x84, 0xd8, 0xb1, 0xd8, + 0xa6, 0xd9, 0x8a, 0xd8, 0xb3, 0xd9, 0x8a, 0xd8, 0xa9, 0xd8, 0xa7, 0xd9, 0x84, + 0xd8, 0xa7, 0xd9, 0x86, 0xd8, 0xaa, 0xd9, 0x82, 0xd8, 0xa7, 0xd9, 0x84, 0xd9, + 0x85, 0xd8, 0xb4, 0xd8, 0xa7, 0xd8, 0xb1, 0xd9, 0x83, 0xd8, 0xa7, 0xd8, 0xaa, + 0xd9, 0x83, 0xd8, 0xa7, 0xd9, 0x84, 0xd8, 0xb3, 0xd9, 0x8a, 0xd8, 0xa7, 0xd8, + 0xb1, 0xd8, 0xa7, 0xd8, 0xaa, 0xd8, 0xa7, 0xd9, 0x84, 0xd9, 0x85, 0xd9, 0x83, + 0xd8, 0xaa, 0xd9, 0x88, 0xd8, 0xa8, 0xd8, 0xa9, 0xd8, 0xa7, 0xd9, 0x84, 0xd8, + 0xb3, 0xd8, 0xb9, 0xd9, 0x88, 0xd8, 0xaf, 0xd9, 0x8a, 0xd8, 0xa9, 0xd8, 0xa7, + 0xd8, 0xad, 0xd8, 0xb5, 0xd8, 0xa7, 0xd8, 0xa6, 0xd9, 0x8a, 0xd8, 0xa7, 0xd8, + 0xaa, 0xd8, 0xa7, 0xd9, 0x84, 0xd8, 0xb9, 0xd8, 0xa7, 0xd9, 0x84, 0xd9, 0x85, + 0xd9, 0x8a, 0xd8, 0xa9, 0xd8, 0xa7, 0xd9, 0x84, 0xd8, 0xb5, 0xd9, 0x88, 0xd8, + 0xaa, 0xd9, 0x8a, 0xd8, 0xa7, 0xd8, 0xaa, 0xd8, 0xa7, 0xd9, 0x84, 0xd8, 0xa7, + 0xd9, 0x86, 0xd8, 0xaa, 0xd8, 0xb1, 0xd9, 0x86, 0xd8, 0xaa, 0xd8, 0xa7, 0xd9, + 0x84, 0xd8, 0xaa, 0xd8, 0xb5, 0xd8, 0xa7, 0xd9, 0x85, 0xd9, 0x8a, 0xd9, 0x85, + 0xd8, 0xa7, 0xd9, 0x84, 0xd8, 0xa5, 0xd8, 0xb3, 0xd9, 0x84, 0xd8, 0xa7, 0xd9, + 0x85, 0xd9, 0x8a, 0xd8, 0xa7, 0xd9, 0x84, 0xd9, 0x85, 0xd8, 0xb4, 0xd8, 0xa7, + 0xd8, 0xb1, 0xd9, 0x83, 0xd8, 0xa9, 0xd8, 0xa7, 0xd9, 0x84, 0xd9, 0x85, 0xd8, + 0xb1, 0xd8, 0xa6, 0xd9, 0x8a, 0xd8, 0xa7, 0xd8, 0xaa, 0x72, 0x6f, 0x62, 0x6f, + 0x74, 0x73, 0x22, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x3d, 0x22, + 0x3c, 0x64, 0x69, 0x76, 0x20, 0x69, 0x64, 0x3d, 0x22, 0x66, 0x6f, 0x6f, 0x74, + 0x65, 0x72, 0x22, 0x3e, 0x74, 0x68, 0x65, 0x20, 0x55, 0x6e, 0x69, 0x74, 0x65, + 0x64, 0x20, 0x53, 0x74, 0x61, 0x74, 0x65, 0x73, 0x3c, 0x69, 0x6d, 0x67, 0x20, + 0x73, 0x72, 0x63, 0x3d, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x2e, + 0x6a, 0x70, 0x67, 0x7c, 0x72, 0x69, 0x67, 0x68, 0x74, 0x7c, 0x74, 0x68, 0x75, + 0x6d, 0x62, 0x7c, 0x2e, 0x6a, 0x73, 0x22, 0x3e, 0x3c, 0x2f, 0x73, 0x63, 0x72, + 0x69, 0x70, 0x74, 0x3e, 0x0d, 0x0a, 0x3c, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x66, 0x72, + 0x61, 0x6d, 0x65, 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x3d, 0x22, 0x30, 0x22, + 0x20, 0x73, 0x22, 0x20, 0x2f, 0x3e, 0x0a, 0x3c, 0x6d, 0x65, 0x74, 0x61, 0x20, + 0x6e, 0x61, 0x6d, 0x65, 0x3d, 0x22, 0x3c, 0x2f, 0x61, 0x3e, 0x3c, 0x2f, 0x64, + 0x69, 0x76, 0x3e, 0x3c, 0x2f, 0x64, 0x69, 0x76, 0x3e, 0x3c, 0x66, 0x6f, 0x6e, + 0x74, 0x2d, 0x77, 0x65, 0x69, 0x67, 0x68, 0x74, 0x3a, 0x62, 0x6f, 0x6c, 0x64, + 0x3b, 0x26, 0x71, 0x75, 0x6f, 0x74, 0x3b, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x26, + 0x71, 0x75, 0x6f, 0x74, 0x3b, 0x64, 0x65, 0x70, 0x65, 0x6e, 0x64, 0x69, 0x6e, + 0x67, 0x20, 0x6f, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x6d, 0x61, 0x72, 0x67, + 0x69, 0x6e, 0x3a, 0x30, 0x3b, 0x70, 0x61, 0x64, 0x64, 0x69, 0x6e, 0x67, 0x3a, + 0x22, 0x20, 0x72, 0x65, 0x6c, 0x3d, 0x22, 0x6e, 0x6f, 0x66, 0x6f, 0x6c, 0x6c, + 0x6f, 0x77, 0x22, 0x20, 0x50, 0x72, 0x65, 0x73, 0x69, 0x64, 0x65, 0x6e, 0x74, + 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x74, 0x77, 0x65, 0x6e, 0x74, + 0x69, 0x65, 0x74, 0x68, 0x20, 0x63, 0x65, 0x6e, 0x74, 0x75, 0x72, 0x79, 0x65, + 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x3e, 0x0a, 0x20, 0x20, 0x3c, 0x2f, 0x70, + 0x61, 0x67, 0x65, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x20, 0x45, + 0x78, 0x70, 0x6c, 0x6f, 0x72, 0x65, 0x72, 0x61, 0x2e, 0x61, 0x73, 0x79, 0x6e, + 0x63, 0x20, 0x3d, 0x20, 0x74, 0x72, 0x75, 0x65, 0x3b, 0x0d, 0x0a, 0x69, 0x6e, + 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x61, 0x62, 0x6f, + 0x75, 0x74, 0x3c, 0x64, 0x69, 0x76, 0x20, 0x69, 0x64, 0x3d, 0x22, 0x68, 0x65, + 0x61, 0x64, 0x65, 0x72, 0x22, 0x3e, 0x22, 0x20, 0x61, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x3d, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x3c, 0x61, 0x20, + 0x68, 0x72, 0x65, 0x66, 0x3d, 0x22, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, + 0x2f, 0x3c, 0x64, 0x69, 0x76, 0x20, 0x69, 0x64, 0x3d, 0x22, 0x63, 0x6f, 0x6e, + 0x74, 0x65, 0x6e, 0x74, 0x22, 0x3c, 0x2f, 0x64, 0x69, 0x76, 0x3e, 0x0d, 0x0a, + 0x3c, 0x2f, 0x64, 0x69, 0x76, 0x3e, 0x0d, 0x0a, 0x3c, 0x64, 0x65, 0x72, 0x69, + 0x76, 0x65, 0x64, 0x20, 0x66, 0x72, 0x6f, 0x6d, 0x20, 0x74, 0x68, 0x65, 0x20, + 0x3c, 0x69, 0x6d, 0x67, 0x20, 0x73, 0x72, 0x63, 0x3d, 0x27, 0x68, 0x74, 0x74, + 0x70, 0x3a, 0x2f, 0x2f, 0x61, 0x63, 0x63, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x67, + 0x20, 0x74, 0x6f, 0x20, 0x74, 0x68, 0x65, 0x20, 0x0a, 0x3c, 0x2f, 0x62, 0x6f, + 0x64, 0x79, 0x3e, 0x0a, 0x3c, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x3e, 0x0a, 0x73, + 0x74, 0x79, 0x6c, 0x65, 0x3d, 0x22, 0x66, 0x6f, 0x6e, 0x74, 0x2d, 0x73, 0x69, + 0x7a, 0x65, 0x3a, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x20, 0x6c, 0x61, 0x6e, + 0x67, 0x75, 0x61, 0x67, 0x65, 0x3d, 0x22, 0x41, 0x72, 0x69, 0x61, 0x6c, 0x2c, + 0x20, 0x48, 0x65, 0x6c, 0x76, 0x65, 0x74, 0x69, 0x63, 0x61, 0x2c, 0x3c, 0x2f, + 0x61, 0x3e, 0x3c, 0x73, 0x70, 0x61, 0x6e, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, + 0x3d, 0x22, 0x3c, 0x2f, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x3e, 0x3c, 0x73, + 0x63, 0x72, 0x69, 0x70, 0x74, 0x20, 0x70, 0x6f, 0x6c, 0x69, 0x74, 0x69, 0x63, + 0x61, 0x6c, 0x20, 0x70, 0x61, 0x72, 0x74, 0x69, 0x65, 0x73, 0x74, 0x64, 0x3e, + 0x3c, 0x2f, 0x74, 0x72, 0x3e, 0x3c, 0x2f, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x3e, + 0x3c, 0x68, 0x72, 0x65, 0x66, 0x3d, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, + 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x70, 0x72, 0x65, + 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6f, 0x66, 0x72, 0x65, 0x6c, 0x3d, + 0x22, 0x73, 0x74, 0x79, 0x6c, 0x65, 0x73, 0x68, 0x65, 0x65, 0x74, 0x22, 0x20, + 0x64, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x77, 0x72, 0x69, 0x74, + 0x65, 0x28, 0x27, 0x3c, 0x63, 0x68, 0x61, 0x72, 0x73, 0x65, 0x74, 0x3d, 0x22, + 0x75, 0x74, 0x66, 0x2d, 0x38, 0x22, 0x3e, 0x0a, 0x62, 0x65, 0x67, 0x69, 0x6e, + 0x6e, 0x69, 0x6e, 0x67, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x72, + 0x65, 0x76, 0x65, 0x61, 0x6c, 0x65, 0x64, 0x20, 0x74, 0x68, 0x61, 0x74, 0x20, + 0x74, 0x68, 0x65, 0x74, 0x65, 0x6c, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, + 0x20, 0x73, 0x65, 0x72, 0x69, 0x65, 0x73, 0x22, 0x20, 0x72, 0x65, 0x6c, 0x3d, + 0x22, 0x6e, 0x6f, 0x66, 0x6f, 0x6c, 0x6c, 0x6f, 0x77, 0x22, 0x3e, 0x20, 0x74, + 0x61, 0x72, 0x67, 0x65, 0x74, 0x3d, 0x22, 0x5f, 0x62, 0x6c, 0x61, 0x6e, 0x6b, + 0x22, 0x3e, 0x63, 0x6c, 0x61, 0x69, 0x6d, 0x69, 0x6e, 0x67, 0x20, 0x74, 0x68, + 0x61, 0x74, 0x20, 0x74, 0x68, 0x65, 0x68, 0x74, 0x74, 0x70, 0x25, 0x33, 0x41, + 0x25, 0x32, 0x46, 0x25, 0x32, 0x46, 0x77, 0x77, 0x77, 0x2e, 0x6d, 0x61, 0x6e, + 0x69, 0x66, 0x65, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x6f, + 0x66, 0x50, 0x72, 0x69, 0x6d, 0x65, 0x20, 0x4d, 0x69, 0x6e, 0x69, 0x73, 0x74, + 0x65, 0x72, 0x20, 0x6f, 0x66, 0x69, 0x6e, 0x66, 0x6c, 0x75, 0x65, 0x6e, 0x63, + 0x65, 0x64, 0x20, 0x62, 0x79, 0x20, 0x74, 0x68, 0x65, 0x63, 0x6c, 0x61, 0x73, + 0x73, 0x3d, 0x22, 0x63, 0x6c, 0x65, 0x61, 0x72, 0x66, 0x69, 0x78, 0x22, 0x3e, + 0x2f, 0x64, 0x69, 0x76, 0x3e, 0x0d, 0x0a, 0x3c, 0x2f, 0x64, 0x69, 0x76, 0x3e, + 0x0d, 0x0a, 0x0d, 0x0a, 0x74, 0x68, 0x72, 0x65, 0x65, 0x2d, 0x64, 0x69, 0x6d, + 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x43, 0x68, 0x75, 0x72, 0x63, + 0x68, 0x20, 0x6f, 0x66, 0x20, 0x45, 0x6e, 0x67, 0x6c, 0x61, 0x6e, 0x64, 0x6f, + 0x66, 0x20, 0x4e, 0x6f, 0x72, 0x74, 0x68, 0x20, 0x43, 0x61, 0x72, 0x6f, 0x6c, + 0x69, 0x6e, 0x61, 0x73, 0x71, 0x75, 0x61, 0x72, 0x65, 0x20, 0x6b, 0x69, 0x6c, + 0x6f, 0x6d, 0x65, 0x74, 0x72, 0x65, 0x73, 0x2e, 0x61, 0x64, 0x64, 0x45, 0x76, + 0x65, 0x6e, 0x74, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x64, 0x69, + 0x73, 0x74, 0x69, 0x6e, 0x63, 0x74, 0x20, 0x66, 0x72, 0x6f, 0x6d, 0x20, 0x74, + 0x68, 0x65, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x6c, 0x79, 0x20, 0x6b, 0x6e, + 0x6f, 0x77, 0x6e, 0x20, 0x61, 0x73, 0x50, 0x68, 0x6f, 0x6e, 0x65, 0x74, 0x69, + 0x63, 0x20, 0x41, 0x6c, 0x70, 0x68, 0x61, 0x62, 0x65, 0x74, 0x64, 0x65, 0x63, + 0x6c, 0x61, 0x72, 0x65, 0x64, 0x20, 0x74, 0x68, 0x61, 0x74, 0x20, 0x74, 0x68, + 0x65, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x64, 0x20, 0x62, + 0x79, 0x20, 0x74, 0x68, 0x65, 0x42, 0x65, 0x6e, 0x6a, 0x61, 0x6d, 0x69, 0x6e, + 0x20, 0x46, 0x72, 0x61, 0x6e, 0x6b, 0x6c, 0x69, 0x6e, 0x72, 0x6f, 0x6c, 0x65, + 0x2d, 0x70, 0x6c, 0x61, 0x79, 0x69, 0x6e, 0x67, 0x20, 0x67, 0x61, 0x6d, 0x65, + 0x74, 0x68, 0x65, 0x20, 0x55, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x69, 0x74, + 0x79, 0x20, 0x6f, 0x66, 0x69, 0x6e, 0x20, 0x57, 0x65, 0x73, 0x74, 0x65, 0x72, + 0x6e, 0x20, 0x45, 0x75, 0x72, 0x6f, 0x70, 0x65, 0x70, 0x65, 0x72, 0x73, 0x6f, + 0x6e, 0x61, 0x6c, 0x20, 0x63, 0x6f, 0x6d, 0x70, 0x75, 0x74, 0x65, 0x72, 0x50, + 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x20, 0x47, 0x75, 0x74, 0x65, 0x6e, 0x62, + 0x65, 0x72, 0x67, 0x72, 0x65, 0x67, 0x61, 0x72, 0x64, 0x6c, 0x65, 0x73, 0x73, + 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x68, 0x61, 0x73, 0x20, 0x62, 0x65, + 0x65, 0x6e, 0x20, 0x70, 0x72, 0x6f, 0x70, 0x6f, 0x73, 0x65, 0x64, 0x74, 0x6f, + 0x67, 0x65, 0x74, 0x68, 0x65, 0x72, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x74, + 0x68, 0x65, 0x3e, 0x3c, 0x2f, 0x6c, 0x69, 0x3e, 0x3c, 0x6c, 0x69, 0x20, 0x63, + 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x22, 0x69, 0x6e, 0x20, 0x73, 0x6f, 0x6d, 0x65, + 0x20, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x72, 0x69, 0x65, 0x73, 0x6d, 0x69, 0x6e, + 0x2e, 0x6a, 0x73, 0x22, 0x3e, 0x3c, 0x2f, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, + 0x3e, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x70, 0x6f, 0x70, 0x75, 0x6c, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x6f, 0x66, 0x66, 0x69, 0x63, 0x69, 0x61, 0x6c, + 0x20, 0x6c, 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, 0x3c, 0x69, 0x6d, 0x67, + 0x20, 0x73, 0x72, 0x63, 0x3d, 0x22, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x73, 0x2f, + 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x64, 0x20, 0x62, 0x79, + 0x20, 0x74, 0x68, 0x65, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x61, 0x6c, 0x20, 0x72, + 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x63, 0x6c, 0x61, 0x73, 0x73, + 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6f, 0x66, 0x63, + 0x61, 0x6e, 0x20, 0x62, 0x65, 0x20, 0x63, 0x6f, 0x6e, 0x73, 0x69, 0x64, 0x65, + 0x72, 0x65, 0x64, 0x71, 0x75, 0x61, 0x6e, 0x74, 0x75, 0x6d, 0x20, 0x6d, 0x65, + 0x63, 0x68, 0x61, 0x6e, 0x69, 0x63, 0x73, 0x4e, 0x65, 0x76, 0x65, 0x72, 0x74, + 0x68, 0x65, 0x6c, 0x65, 0x73, 0x73, 0x2c, 0x20, 0x74, 0x68, 0x65, 0x6d, 0x69, + 0x6c, 0x6c, 0x69, 0x6f, 0x6e, 0x20, 0x79, 0x65, 0x61, 0x72, 0x73, 0x20, 0x61, + 0x67, 0x6f, 0x3c, 0x2f, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0x0d, 0x0a, 0x3c, 0x2f, + 0x68, 0x74, 0x6d, 0x6c, 0x3e, 0x0d, 0xce, 0x95, 0xce, 0xbb, 0xce, 0xbb, 0xce, + 0xb7, 0xce, 0xbd, 0xce, 0xb9, 0xce, 0xba, 0xce, 0xac, 0x0a, 0x74, 0x61, 0x6b, + 0x65, 0x20, 0x61, 0x64, 0x76, 0x61, 0x6e, 0x74, 0x61, 0x67, 0x65, 0x20, 0x6f, + 0x66, 0x61, 0x6e, 0x64, 0x2c, 0x20, 0x61, 0x63, 0x63, 0x6f, 0x72, 0x64, 0x69, + 0x6e, 0x67, 0x20, 0x74, 0x6f, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, + 0x65, 0x64, 0x20, 0x74, 0x6f, 0x20, 0x74, 0x68, 0x65, 0x4d, 0x69, 0x63, 0x72, + 0x6f, 0x73, 0x6f, 0x66, 0x74, 0x20, 0x57, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x73, + 0x74, 0x68, 0x65, 0x20, 0x66, 0x69, 0x72, 0x73, 0x74, 0x20, 0x63, 0x65, 0x6e, + 0x74, 0x75, 0x72, 0x79, 0x75, 0x6e, 0x64, 0x65, 0x72, 0x20, 0x74, 0x68, 0x65, + 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x64, 0x69, 0x76, 0x20, 0x63, + 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x22, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x73, + 0x68, 0x6f, 0x72, 0x74, 0x6c, 0x79, 0x20, 0x61, 0x66, 0x74, 0x65, 0x72, 0x20, + 0x74, 0x68, 0x65, 0x6e, 0x6f, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x20, 0x65, 0x78, + 0x63, 0x65, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x73, 0x20, 0x6f, + 0x66, 0x20, 0x74, 0x68, 0x6f, 0x75, 0x73, 0x61, 0x6e, 0x64, 0x73, 0x73, 0x65, + 0x76, 0x65, 0x72, 0x61, 0x6c, 0x20, 0x64, 0x69, 0x66, 0x66, 0x65, 0x72, 0x65, + 0x6e, 0x74, 0x61, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x20, 0x74, 0x68, 0x65, 0x20, + 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x2e, 0x72, 0x65, 0x61, 0x63, 0x68, 0x69, 0x6e, + 0x67, 0x20, 0x6d, 0x69, 0x6c, 0x69, 0x74, 0x61, 0x72, 0x79, 0x69, 0x73, 0x6f, + 0x6c, 0x61, 0x74, 0x65, 0x64, 0x20, 0x66, 0x72, 0x6f, 0x6d, 0x20, 0x74, 0x68, + 0x65, 0x6f, 0x70, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x74, + 0x6f, 0x20, 0x74, 0x68, 0x65, 0x74, 0x68, 0x65, 0x20, 0x4f, 0x6c, 0x64, 0x20, + 0x54, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x65, 0x6e, 0x74, 0x41, 0x66, 0x72, 0x69, + 0x63, 0x61, 0x6e, 0x20, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x6e, 0x73, + 0x69, 0x6e, 0x73, 0x65, 0x72, 0x74, 0x65, 0x64, 0x20, 0x69, 0x6e, 0x74, 0x6f, + 0x20, 0x74, 0x68, 0x65, 0x73, 0x65, 0x70, 0x61, 0x72, 0x61, 0x74, 0x65, 0x20, + 0x66, 0x72, 0x6f, 0x6d, 0x20, 0x74, 0x68, 0x65, 0x6d, 0x65, 0x74, 0x72, 0x6f, + 0x70, 0x6f, 0x6c, 0x69, 0x74, 0x61, 0x6e, 0x20, 0x61, 0x72, 0x65, 0x61, 0x6d, + 0x61, 0x6b, 0x65, 0x73, 0x20, 0x69, 0x74, 0x20, 0x70, 0x6f, 0x73, 0x73, 0x69, + 0x62, 0x6c, 0x65, 0x61, 0x63, 0x6b, 0x6e, 0x6f, 0x77, 0x6c, 0x65, 0x64, 0x67, + 0x65, 0x64, 0x20, 0x74, 0x68, 0x61, 0x74, 0x61, 0x72, 0x67, 0x75, 0x61, 0x62, + 0x6c, 0x79, 0x20, 0x74, 0x68, 0x65, 0x20, 0x6d, 0x6f, 0x73, 0x74, 0x74, 0x79, + 0x70, 0x65, 0x3d, 0x22, 0x74, 0x65, 0x78, 0x74, 0x2f, 0x63, 0x73, 0x73, 0x22, + 0x3e, 0x0a, 0x74, 0x68, 0x65, 0x20, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x41, 0x63, 0x63, 0x6f, 0x72, 0x64, 0x69, + 0x6e, 0x67, 0x20, 0x74, 0x6f, 0x20, 0x74, 0x68, 0x65, 0x20, 0x70, 0x65, 0x3d, + 0x22, 0x74, 0x65, 0x78, 0x74, 0x2f, 0x63, 0x73, 0x73, 0x22, 0x20, 0x2f, 0x3e, + 0x0a, 0x63, 0x6f, 0x69, 0x6e, 0x63, 0x69, 0x64, 0x65, 0x20, 0x77, 0x69, 0x74, + 0x68, 0x20, 0x74, 0x68, 0x65, 0x74, 0x77, 0x6f, 0x2d, 0x74, 0x68, 0x69, 0x72, + 0x64, 0x73, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x44, 0x75, 0x72, 0x69, + 0x6e, 0x67, 0x20, 0x74, 0x68, 0x69, 0x73, 0x20, 0x74, 0x69, 0x6d, 0x65, 0x2c, + 0x64, 0x75, 0x72, 0x69, 0x6e, 0x67, 0x20, 0x74, 0x68, 0x65, 0x20, 0x70, 0x65, + 0x72, 0x69, 0x6f, 0x64, 0x61, 0x6e, 0x6e, 0x6f, 0x75, 0x6e, 0x63, 0x65, 0x64, + 0x20, 0x74, 0x68, 0x61, 0x74, 0x20, 0x68, 0x65, 0x74, 0x68, 0x65, 0x20, 0x69, + 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x61, + 0x6e, 0x64, 0x20, 0x6d, 0x6f, 0x72, 0x65, 0x20, 0x72, 0x65, 0x63, 0x65, 0x6e, + 0x74, 0x6c, 0x79, 0x62, 0x65, 0x6c, 0x69, 0x65, 0x76, 0x65, 0x64, 0x20, 0x74, + 0x68, 0x61, 0x74, 0x20, 0x74, 0x68, 0x65, 0x63, 0x6f, 0x6e, 0x73, 0x63, 0x69, + 0x6f, 0x75, 0x73, 0x6e, 0x65, 0x73, 0x73, 0x20, 0x61, 0x6e, 0x64, 0x66, 0x6f, + 0x72, 0x6d, 0x65, 0x72, 0x6c, 0x79, 0x20, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x20, + 0x61, 0x73, 0x73, 0x75, 0x72, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x65, 0x64, 0x20, + 0x62, 0x79, 0x20, 0x74, 0x68, 0x65, 0x66, 0x69, 0x72, 0x73, 0x74, 0x20, 0x61, + 0x70, 0x70, 0x65, 0x61, 0x72, 0x65, 0x64, 0x20, 0x69, 0x6e, 0x6f, 0x63, 0x63, + 0x61, 0x73, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x6c, 0x79, 0x20, 0x75, 0x73, 0x65, + 0x64, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x61, 0x62, 0x73, + 0x6f, 0x6c, 0x75, 0x74, 0x65, 0x3b, 0x22, 0x20, 0x74, 0x61, 0x72, 0x67, 0x65, + 0x74, 0x3d, 0x22, 0x5f, 0x62, 0x6c, 0x61, 0x6e, 0x6b, 0x22, 0x20, 0x70, 0x6f, + 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x72, 0x65, 0x6c, 0x61, 0x74, 0x69, + 0x76, 0x65, 0x3b, 0x74, 0x65, 0x78, 0x74, 0x2d, 0x61, 0x6c, 0x69, 0x67, 0x6e, + 0x3a, 0x63, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x3b, 0x6a, 0x61, 0x78, 0x2f, 0x6c, + 0x69, 0x62, 0x73, 0x2f, 0x6a, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2f, 0x31, 0x2e, + 0x62, 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x2d, 0x63, 0x6f, + 0x6c, 0x6f, 0x72, 0x3a, 0x23, 0x74, 0x79, 0x70, 0x65, 0x3d, 0x22, 0x61, 0x70, + 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x61, 0x6e, 0x67, + 0x75, 0x61, 0x67, 0x65, 0x22, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, + 0x3d, 0x22, 0x3c, 0x6d, 0x65, 0x74, 0x61, 0x20, 0x68, 0x74, 0x74, 0x70, 0x2d, + 0x65, 0x71, 0x75, 0x69, 0x76, 0x3d, 0x22, 0x50, 0x72, 0x69, 0x76, 0x61, 0x63, + 0x79, 0x20, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x3c, 0x2f, 0x61, 0x3e, 0x65, + 0x28, 0x22, 0x25, 0x33, 0x43, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x20, 0x73, + 0x72, 0x63, 0x3d, 0x27, 0x22, 0x20, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x3d, + 0x22, 0x5f, 0x62, 0x6c, 0x61, 0x6e, 0x6b, 0x22, 0x3e, 0x4f, 0x6e, 0x20, 0x74, + 0x68, 0x65, 0x20, 0x6f, 0x74, 0x68, 0x65, 0x72, 0x20, 0x68, 0x61, 0x6e, 0x64, + 0x2c, 0x2e, 0x6a, 0x70, 0x67, 0x7c, 0x74, 0x68, 0x75, 0x6d, 0x62, 0x7c, 0x72, + 0x69, 0x67, 0x68, 0x74, 0x7c, 0x32, 0x3c, 0x2f, 0x64, 0x69, 0x76, 0x3e, 0x3c, + 0x64, 0x69, 0x76, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x22, 0x3c, 0x64, + 0x69, 0x76, 0x20, 0x73, 0x74, 0x79, 0x6c, 0x65, 0x3d, 0x22, 0x66, 0x6c, 0x6f, + 0x61, 0x74, 0x3a, 0x6e, 0x69, 0x6e, 0x65, 0x74, 0x65, 0x65, 0x6e, 0x74, 0x68, + 0x20, 0x63, 0x65, 0x6e, 0x74, 0x75, 0x72, 0x79, 0x3c, 0x2f, 0x62, 0x6f, 0x64, + 0x79, 0x3e, 0x0d, 0x0a, 0x3c, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x3e, 0x0d, 0x0a, + 0x3c, 0x69, 0x6d, 0x67, 0x20, 0x73, 0x72, 0x63, 0x3d, 0x22, 0x68, 0x74, 0x74, + 0x70, 0x3a, 0x2f, 0x2f, 0x73, 0x3b, 0x74, 0x65, 0x78, 0x74, 0x2d, 0x61, 0x6c, + 0x69, 0x67, 0x6e, 0x3a, 0x63, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x6f, 0x6e, + 0x74, 0x2d, 0x77, 0x65, 0x69, 0x67, 0x68, 0x74, 0x3a, 0x20, 0x62, 0x6f, 0x6c, + 0x64, 0x3b, 0x20, 0x41, 0x63, 0x63, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x67, 0x20, + 0x74, 0x6f, 0x20, 0x74, 0x68, 0x65, 0x20, 0x64, 0x69, 0x66, 0x66, 0x65, 0x72, + 0x65, 0x6e, 0x63, 0x65, 0x20, 0x62, 0x65, 0x74, 0x77, 0x65, 0x65, 0x6e, 0x22, + 0x20, 0x66, 0x72, 0x61, 0x6d, 0x65, 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x3d, + 0x22, 0x30, 0x22, 0x20, 0x22, 0x20, 0x73, 0x74, 0x79, 0x6c, 0x65, 0x3d, 0x22, + 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x6c, 0x69, 0x6e, 0x6b, + 0x20, 0x68, 0x72, 0x65, 0x66, 0x3d, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, + 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x34, 0x2f, 0x6c, 0x6f, 0x6f, 0x73, 0x65, 0x2e, + 0x64, 0x74, 0x64, 0x22, 0x3e, 0x0a, 0x64, 0x75, 0x72, 0x69, 0x6e, 0x67, 0x20, + 0x74, 0x68, 0x69, 0x73, 0x20, 0x70, 0x65, 0x72, 0x69, 0x6f, 0x64, 0x3c, 0x2f, + 0x74, 0x64, 0x3e, 0x3c, 0x2f, 0x74, 0x72, 0x3e, 0x3c, 0x2f, 0x74, 0x61, 0x62, + 0x6c, 0x65, 0x3e, 0x63, 0x6c, 0x6f, 0x73, 0x65, 0x6c, 0x79, 0x20, 0x72, 0x65, + 0x6c, 0x61, 0x74, 0x65, 0x64, 0x20, 0x74, 0x6f, 0x66, 0x6f, 0x72, 0x20, 0x74, + 0x68, 0x65, 0x20, 0x66, 0x69, 0x72, 0x73, 0x74, 0x20, 0x74, 0x69, 0x6d, 0x65, + 0x3b, 0x66, 0x6f, 0x6e, 0x74, 0x2d, 0x77, 0x65, 0x69, 0x67, 0x68, 0x74, 0x3a, + 0x62, 0x6f, 0x6c, 0x64, 0x3b, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x20, 0x74, 0x79, + 0x70, 0x65, 0x3d, 0x22, 0x74, 0x65, 0x78, 0x74, 0x22, 0x20, 0x3c, 0x73, 0x70, + 0x61, 0x6e, 0x20, 0x73, 0x74, 0x79, 0x6c, 0x65, 0x3d, 0x22, 0x66, 0x6f, 0x6e, + 0x74, 0x2d, 0x6f, 0x6e, 0x72, 0x65, 0x61, 0x64, 0x79, 0x73, 0x74, 0x61, 0x74, + 0x65, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x09, 0x3c, 0x64, 0x69, 0x76, 0x20, + 0x63, 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x22, 0x63, 0x6c, 0x65, 0x61, 0x72, 0x64, + 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x6c, 0x6f, 0x63, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x2e, 0x20, 0x46, 0x6f, 0x72, 0x20, 0x65, 0x78, 0x61, 0x6d, + 0x70, 0x6c, 0x65, 0x2c, 0x20, 0x74, 0x68, 0x65, 0x20, 0x61, 0x20, 0x77, 0x69, + 0x64, 0x65, 0x20, 0x76, 0x61, 0x72, 0x69, 0x65, 0x74, 0x79, 0x20, 0x6f, 0x66, + 0x20, 0x3c, 0x21, 0x44, 0x4f, 0x43, 0x54, 0x59, 0x50, 0x45, 0x20, 0x68, 0x74, + 0x6d, 0x6c, 0x3e, 0x0d, 0x0a, 0x3c, 0x26, 0x6e, 0x62, 0x73, 0x70, 0x3b, 0x26, + 0x6e, 0x62, 0x73, 0x70, 0x3b, 0x26, 0x6e, 0x62, 0x73, 0x70, 0x3b, 0x22, 0x3e, + 0x3c, 0x61, 0x20, 0x68, 0x72, 0x65, 0x66, 0x3d, 0x22, 0x68, 0x74, 0x74, 0x70, + 0x3a, 0x2f, 0x2f, 0x73, 0x74, 0x79, 0x6c, 0x65, 0x3d, 0x22, 0x66, 0x6c, 0x6f, + 0x61, 0x74, 0x3a, 0x6c, 0x65, 0x66, 0x74, 0x3b, 0x63, 0x6f, 0x6e, 0x63, 0x65, + 0x72, 0x6e, 0x65, 0x64, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x74, 0x68, 0x65, + 0x3d, 0x68, 0x74, 0x74, 0x70, 0x25, 0x33, 0x41, 0x25, 0x32, 0x46, 0x25, 0x32, + 0x46, 0x77, 0x77, 0x77, 0x2e, 0x69, 0x6e, 0x20, 0x70, 0x6f, 0x70, 0x75, 0x6c, + 0x61, 0x72, 0x20, 0x63, 0x75, 0x6c, 0x74, 0x75, 0x72, 0x65, 0x74, 0x79, 0x70, + 0x65, 0x3d, 0x22, 0x74, 0x65, 0x78, 0x74, 0x2f, 0x63, 0x73, 0x73, 0x22, 0x20, + 0x2f, 0x3e, 0x69, 0x74, 0x20, 0x69, 0x73, 0x20, 0x70, 0x6f, 0x73, 0x73, 0x69, + 0x62, 0x6c, 0x65, 0x20, 0x74, 0x6f, 0x20, 0x48, 0x61, 0x72, 0x76, 0x61, 0x72, + 0x64, 0x20, 0x55, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x69, 0x74, 0x79, 0x74, + 0x79, 0x6c, 0x65, 0x73, 0x68, 0x65, 0x65, 0x74, 0x22, 0x20, 0x68, 0x72, 0x65, + 0x66, 0x3d, 0x22, 0x2f, 0x74, 0x68, 0x65, 0x20, 0x6d, 0x61, 0x69, 0x6e, 0x20, + 0x63, 0x68, 0x61, 0x72, 0x61, 0x63, 0x74, 0x65, 0x72, 0x4f, 0x78, 0x66, 0x6f, + 0x72, 0x64, 0x20, 0x55, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x69, 0x74, 0x79, + 0x20, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x3d, 0x22, 0x6b, 0x65, 0x79, 0x77, 0x6f, + 0x72, 0x64, 0x73, 0x22, 0x20, 0x63, 0x73, 0x74, 0x79, 0x6c, 0x65, 0x3d, 0x22, + 0x74, 0x65, 0x78, 0x74, 0x2d, 0x61, 0x6c, 0x69, 0x67, 0x6e, 0x3a, 0x74, 0x68, + 0x65, 0x20, 0x55, 0x6e, 0x69, 0x74, 0x65, 0x64, 0x20, 0x4b, 0x69, 0x6e, 0x67, + 0x64, 0x6f, 0x6d, 0x66, 0x65, 0x64, 0x65, 0x72, 0x61, 0x6c, 0x20, 0x67, 0x6f, + 0x76, 0x65, 0x72, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x3c, 0x64, 0x69, 0x76, 0x20, + 0x73, 0x74, 0x79, 0x6c, 0x65, 0x3d, 0x22, 0x6d, 0x61, 0x72, 0x67, 0x69, 0x6e, + 0x20, 0x64, 0x65, 0x70, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x20, 0x6f, 0x6e, + 0x20, 0x74, 0x68, 0x65, 0x20, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, + 0x69, 0x6f, 0x6e, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x3c, 0x64, 0x69, + 0x76, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x22, 0x68, 0x65, 0x61, 0x64, + 0x65, 0x72, 0x2e, 0x6d, 0x69, 0x6e, 0x2e, 0x6a, 0x73, 0x22, 0x3e, 0x3c, 0x2f, + 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x3e, 0x64, 0x65, 0x73, 0x74, 0x72, 0x75, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x73, + 0x6c, 0x69, 0x67, 0x68, 0x74, 0x6c, 0x79, 0x20, 0x64, 0x69, 0x66, 0x66, 0x65, + 0x72, 0x65, 0x6e, 0x74, 0x69, 0x6e, 0x20, 0x61, 0x63, 0x63, 0x6f, 0x72, 0x64, + 0x61, 0x6e, 0x63, 0x65, 0x20, 0x77, 0x69, 0x74, 0x68, 0x74, 0x65, 0x6c, 0x65, + 0x63, 0x6f, 0x6d, 0x6d, 0x75, 0x6e, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x73, 0x69, 0x6e, 0x64, 0x69, 0x63, 0x61, 0x74, 0x65, 0x73, 0x20, 0x74, 0x68, + 0x61, 0x74, 0x20, 0x74, 0x68, 0x65, 0x73, 0x68, 0x6f, 0x72, 0x74, 0x6c, 0x79, + 0x20, 0x74, 0x68, 0x65, 0x72, 0x65, 0x61, 0x66, 0x74, 0x65, 0x72, 0x65, 0x73, + 0x70, 0x65, 0x63, 0x69, 0x61, 0x6c, 0x6c, 0x79, 0x20, 0x69, 0x6e, 0x20, 0x74, + 0x68, 0x65, 0x20, 0x45, 0x75, 0x72, 0x6f, 0x70, 0x65, 0x61, 0x6e, 0x20, 0x63, + 0x6f, 0x75, 0x6e, 0x74, 0x72, 0x69, 0x65, 0x73, 0x48, 0x6f, 0x77, 0x65, 0x76, + 0x65, 0x72, 0x2c, 0x20, 0x74, 0x68, 0x65, 0x72, 0x65, 0x20, 0x61, 0x72, 0x65, + 0x73, 0x72, 0x63, 0x3d, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x73, + 0x74, 0x61, 0x74, 0x69, 0x63, 0x73, 0x75, 0x67, 0x67, 0x65, 0x73, 0x74, 0x65, + 0x64, 0x20, 0x74, 0x68, 0x61, 0x74, 0x20, 0x74, 0x68, 0x65, 0x22, 0x20, 0x73, + 0x72, 0x63, 0x3d, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, + 0x77, 0x2e, 0x61, 0x20, 0x6c, 0x61, 0x72, 0x67, 0x65, 0x20, 0x6e, 0x75, 0x6d, + 0x62, 0x65, 0x72, 0x20, 0x6f, 0x66, 0x20, 0x54, 0x65, 0x6c, 0x65, 0x63, 0x6f, + 0x6d, 0x6d, 0x75, 0x6e, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, + 0x20, 0x72, 0x65, 0x6c, 0x3d, 0x22, 0x6e, 0x6f, 0x66, 0x6f, 0x6c, 0x6c, 0x6f, + 0x77, 0x22, 0x20, 0x74, 0x48, 0x6f, 0x6c, 0x79, 0x20, 0x52, 0x6f, 0x6d, 0x61, + 0x6e, 0x20, 0x45, 0x6d, 0x70, 0x65, 0x72, 0x6f, 0x72, 0x61, 0x6c, 0x6d, 0x6f, + 0x73, 0x74, 0x20, 0x65, 0x78, 0x63, 0x6c, 0x75, 0x73, 0x69, 0x76, 0x65, 0x6c, + 0x79, 0x22, 0x20, 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x3d, 0x22, 0x30, 0x22, + 0x20, 0x61, 0x6c, 0x74, 0x3d, 0x22, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x61, + 0x72, 0x79, 0x20, 0x6f, 0x66, 0x20, 0x53, 0x74, 0x61, 0x74, 0x65, 0x63, 0x75, + 0x6c, 0x6d, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6e, 0x67, 0x20, 0x69, 0x6e, 0x20, + 0x74, 0x68, 0x65, 0x43, 0x49, 0x41, 0x20, 0x57, 0x6f, 0x72, 0x6c, 0x64, 0x20, + 0x46, 0x61, 0x63, 0x74, 0x62, 0x6f, 0x6f, 0x6b, 0x74, 0x68, 0x65, 0x20, 0x6d, + 0x6f, 0x73, 0x74, 0x20, 0x69, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x61, 0x6e, 0x74, + 0x61, 0x6e, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x61, 0x72, 0x79, 0x20, 0x6f, + 0x66, 0x20, 0x74, 0x68, 0x65, 0x73, 0x74, 0x79, 0x6c, 0x65, 0x3d, 0x22, 0x62, + 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x2d, 0x3c, 0x6c, 0x69, + 0x3e, 0x3c, 0x65, 0x6d, 0x3e, 0x3c, 0x61, 0x20, 0x68, 0x72, 0x65, 0x66, 0x3d, + 0x22, 0x2f, 0x74, 0x68, 0x65, 0x20, 0x41, 0x74, 0x6c, 0x61, 0x6e, 0x74, 0x69, + 0x63, 0x20, 0x4f, 0x63, 0x65, 0x61, 0x6e, 0x73, 0x74, 0x72, 0x69, 0x63, 0x74, + 0x6c, 0x79, 0x20, 0x73, 0x70, 0x65, 0x61, 0x6b, 0x69, 0x6e, 0x67, 0x2c, 0x73, + 0x68, 0x6f, 0x72, 0x74, 0x6c, 0x79, 0x20, 0x62, 0x65, 0x66, 0x6f, 0x72, 0x65, + 0x20, 0x74, 0x68, 0x65, 0x64, 0x69, 0x66, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x74, + 0x20, 0x74, 0x79, 0x70, 0x65, 0x73, 0x20, 0x6f, 0x66, 0x74, 0x68, 0x65, 0x20, + 0x4f, 0x74, 0x74, 0x6f, 0x6d, 0x61, 0x6e, 0x20, 0x45, 0x6d, 0x70, 0x69, 0x72, + 0x65, 0x3e, 0x3c, 0x69, 0x6d, 0x67, 0x20, 0x73, 0x72, 0x63, 0x3d, 0x22, 0x68, + 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x41, 0x6e, 0x20, 0x49, 0x6e, 0x74, 0x72, + 0x6f, 0x64, 0x75, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x74, 0x6f, 0x63, 0x6f, + 0x6e, 0x73, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x65, 0x20, 0x6f, 0x66, 0x20, + 0x74, 0x68, 0x65, 0x64, 0x65, 0x70, 0x61, 0x72, 0x74, 0x75, 0x72, 0x65, 0x20, + 0x66, 0x72, 0x6f, 0x6d, 0x20, 0x74, 0x68, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x65, + 0x64, 0x65, 0x72, 0x61, 0x74, 0x65, 0x20, 0x53, 0x74, 0x61, 0x74, 0x65, 0x73, + 0x69, 0x6e, 0x64, 0x69, 0x67, 0x65, 0x6e, 0x6f, 0x75, 0x73, 0x20, 0x70, 0x65, + 0x6f, 0x70, 0x6c, 0x65, 0x73, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x65, 0x64, 0x69, + 0x6e, 0x67, 0x73, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x69, 0x6e, 0x66, + 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6f, 0x6e, 0x20, 0x74, + 0x68, 0x65, 0x74, 0x68, 0x65, 0x6f, 0x72, 0x69, 0x65, 0x73, 0x20, 0x68, 0x61, + 0x76, 0x65, 0x20, 0x62, 0x65, 0x65, 0x6e, 0x69, 0x6e, 0x76, 0x6f, 0x6c, 0x76, + 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x20, 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x64, + 0x69, 0x76, 0x69, 0x64, 0x65, 0x64, 0x20, 0x69, 0x6e, 0x74, 0x6f, 0x20, 0x74, + 0x68, 0x72, 0x65, 0x65, 0x61, 0x64, 0x6a, 0x61, 0x63, 0x65, 0x6e, 0x74, 0x20, + 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x72, 0x69, 0x65, 0x73, 0x69, 0x73, 0x20, 0x72, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x69, 0x62, 0x6c, 0x65, 0x20, 0x66, 0x6f, + 0x72, 0x64, 0x69, 0x73, 0x73, 0x6f, 0x6c, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x20, + 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x63, 0x6f, 0x6c, 0x6c, 0x61, 0x62, 0x6f, + 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x77, 0x69, 0x74, 0x68, 0x77, 0x69, + 0x64, 0x65, 0x6c, 0x79, 0x20, 0x72, 0x65, 0x67, 0x61, 0x72, 0x64, 0x65, 0x64, + 0x20, 0x61, 0x73, 0x68, 0x69, 0x73, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6d, + 0x70, 0x6f, 0x72, 0x61, 0x72, 0x69, 0x65, 0x73, 0x66, 0x6f, 0x75, 0x6e, 0x64, + 0x69, 0x6e, 0x67, 0x20, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x20, 0x6f, 0x66, + 0x44, 0x6f, 0x6d, 0x69, 0x6e, 0x69, 0x63, 0x61, 0x6e, 0x20, 0x52, 0x65, 0x70, + 0x75, 0x62, 0x6c, 0x69, 0x63, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x6c, 0x6c, + 0x79, 0x20, 0x61, 0x63, 0x63, 0x65, 0x70, 0x74, 0x65, 0x64, 0x74, 0x68, 0x65, + 0x20, 0x70, 0x6f, 0x73, 0x73, 0x69, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x20, + 0x6f, 0x66, 0x61, 0x72, 0x65, 0x20, 0x61, 0x6c, 0x73, 0x6f, 0x20, 0x61, 0x76, + 0x61, 0x69, 0x6c, 0x61, 0x62, 0x6c, 0x65, 0x75, 0x6e, 0x64, 0x65, 0x72, 0x20, + 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x72, + 0x65, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6f, 0x66, + 0x20, 0x74, 0x68, 0x65, 0x74, 0x68, 0x65, 0x20, 0x67, 0x65, 0x6e, 0x65, 0x72, + 0x61, 0x6c, 0x20, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x69, 0x73, 0x20, 0x61, + 0x6c, 0x6d, 0x6f, 0x73, 0x74, 0x20, 0x65, 0x6e, 0x74, 0x69, 0x72, 0x65, 0x6c, + 0x79, 0x70, 0x61, 0x73, 0x73, 0x65, 0x73, 0x20, 0x74, 0x68, 0x72, 0x6f, 0x75, + 0x67, 0x68, 0x20, 0x74, 0x68, 0x65, 0x68, 0x61, 0x73, 0x20, 0x62, 0x65, 0x65, + 0x6e, 0x20, 0x73, 0x75, 0x67, 0x67, 0x65, 0x73, 0x74, 0x65, 0x64, 0x63, 0x6f, + 0x6d, 0x70, 0x75, 0x74, 0x65, 0x72, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x76, 0x69, + 0x64, 0x65, 0x6f, 0x47, 0x65, 0x72, 0x6d, 0x61, 0x6e, 0x69, 0x63, 0x20, 0x6c, + 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, 0x73, 0x20, 0x61, 0x63, 0x63, 0x6f, + 0x72, 0x64, 0x69, 0x6e, 0x67, 0x20, 0x74, 0x6f, 0x20, 0x74, 0x68, 0x65, 0x20, + 0x64, 0x69, 0x66, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x74, 0x20, 0x66, 0x72, 0x6f, + 0x6d, 0x20, 0x74, 0x68, 0x65, 0x73, 0x68, 0x6f, 0x72, 0x74, 0x6c, 0x79, 0x20, + 0x61, 0x66, 0x74, 0x65, 0x72, 0x77, 0x61, 0x72, 0x64, 0x73, 0x68, 0x72, 0x65, + 0x66, 0x3d, 0x22, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x77, 0x77, + 0x77, 0x2e, 0x72, 0x65, 0x63, 0x65, 0x6e, 0x74, 0x20, 0x64, 0x65, 0x76, 0x65, + 0x6c, 0x6f, 0x70, 0x6d, 0x65, 0x6e, 0x74, 0x42, 0x6f, 0x61, 0x72, 0x64, 0x20, + 0x6f, 0x66, 0x20, 0x44, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x73, 0x3c, + 0x64, 0x69, 0x76, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x22, 0x73, 0x65, + 0x61, 0x72, 0x63, 0x68, 0x7c, 0x20, 0x3c, 0x61, 0x20, 0x68, 0x72, 0x65, 0x66, + 0x3d, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x49, 0x6e, 0x20, 0x70, + 0x61, 0x72, 0x74, 0x69, 0x63, 0x75, 0x6c, 0x61, 0x72, 0x2c, 0x20, 0x74, 0x68, + 0x65, 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x70, 0x6c, 0x65, 0x20, 0x66, 0x6f, 0x6f, + 0x74, 0x6e, 0x6f, 0x74, 0x65, 0x73, 0x6f, 0x72, 0x20, 0x6f, 0x74, 0x68, 0x65, + 0x72, 0x20, 0x73, 0x75, 0x62, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x74, 0x68, + 0x6f, 0x75, 0x73, 0x61, 0x6e, 0x64, 0x73, 0x20, 0x6f, 0x66, 0x20, 0x79, 0x65, + 0x61, 0x72, 0x73, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x6c, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x3c, 0x2f, 0x64, 0x69, 0x76, + 0x3e, 0x0d, 0x0a, 0x3c, 0x2f, 0x64, 0x69, 0x76, 0x3e, 0x0d, 0x0a, 0x0d, 0x0a, + 0x3c, 0x61, 0x20, 0x68, 0x72, 0x65, 0x66, 0x3d, 0x22, 0x69, 0x6e, 0x64, 0x65, + 0x78, 0x2e, 0x70, 0x68, 0x70, 0x77, 0x61, 0x73, 0x20, 0x65, 0x73, 0x74, 0x61, + 0x62, 0x6c, 0x69, 0x73, 0x68, 0x65, 0x64, 0x20, 0x69, 0x6e, 0x6d, 0x69, 0x6e, + 0x2e, 0x6a, 0x73, 0x22, 0x3e, 0x3c, 0x2f, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, + 0x3e, 0x0a, 0x70, 0x61, 0x72, 0x74, 0x69, 0x63, 0x69, 0x70, 0x61, 0x74, 0x65, + 0x20, 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x61, 0x20, 0x73, 0x74, 0x72, 0x6f, + 0x6e, 0x67, 0x20, 0x69, 0x6e, 0x66, 0x6c, 0x75, 0x65, 0x6e, 0x63, 0x65, 0x73, + 0x74, 0x79, 0x6c, 0x65, 0x3d, 0x22, 0x6d, 0x61, 0x72, 0x67, 0x69, 0x6e, 0x2d, + 0x74, 0x6f, 0x70, 0x3a, 0x72, 0x65, 0x70, 0x72, 0x65, 0x73, 0x65, 0x6e, 0x74, + 0x65, 0x64, 0x20, 0x62, 0x79, 0x20, 0x74, 0x68, 0x65, 0x67, 0x72, 0x61, 0x64, + 0x75, 0x61, 0x74, 0x65, 0x64, 0x20, 0x66, 0x72, 0x6f, 0x6d, 0x20, 0x74, 0x68, + 0x65, 0x54, 0x72, 0x61, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x6c, + 0x79, 0x2c, 0x20, 0x74, 0x68, 0x65, 0x45, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, + 0x28, 0x22, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x22, 0x29, 0x3b, 0x48, 0x6f, + 0x77, 0x65, 0x76, 0x65, 0x72, 0x2c, 0x20, 0x73, 0x69, 0x6e, 0x63, 0x65, 0x20, + 0x74, 0x68, 0x65, 0x2f, 0x64, 0x69, 0x76, 0x3e, 0x0a, 0x3c, 0x2f, 0x64, 0x69, + 0x76, 0x3e, 0x0a, 0x3c, 0x64, 0x69, 0x76, 0x20, 0x6c, 0x65, 0x66, 0x74, 0x3b, + 0x20, 0x6d, 0x61, 0x72, 0x67, 0x69, 0x6e, 0x2d, 0x6c, 0x65, 0x66, 0x74, 0x3a, + 0x70, 0x72, 0x6f, 0x74, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x61, 0x67, + 0x61, 0x69, 0x6e, 0x73, 0x74, 0x30, 0x3b, 0x20, 0x76, 0x65, 0x72, 0x74, 0x69, + 0x63, 0x61, 0x6c, 0x2d, 0x61, 0x6c, 0x69, 0x67, 0x6e, 0x3a, 0x55, 0x6e, 0x66, + 0x6f, 0x72, 0x74, 0x75, 0x6e, 0x61, 0x74, 0x65, 0x6c, 0x79, 0x2c, 0x20, 0x74, + 0x68, 0x65, 0x74, 0x79, 0x70, 0x65, 0x3d, 0x22, 0x69, 0x6d, 0x61, 0x67, 0x65, + 0x2f, 0x78, 0x2d, 0x69, 0x63, 0x6f, 0x6e, 0x2f, 0x64, 0x69, 0x76, 0x3e, 0x0a, + 0x3c, 0x64, 0x69, 0x76, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x22, 0x20, + 0x63, 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x22, 0x63, 0x6c, 0x65, 0x61, 0x72, 0x66, + 0x69, 0x78, 0x22, 0x3e, 0x3c, 0x64, 0x69, 0x76, 0x20, 0x63, 0x6c, 0x61, 0x73, + 0x73, 0x3d, 0x22, 0x66, 0x6f, 0x6f, 0x74, 0x65, 0x72, 0x09, 0x09, 0x3c, 0x2f, + 0x64, 0x69, 0x76, 0x3e, 0x0a, 0x09, 0x09, 0x3c, 0x2f, 0x64, 0x69, 0x76, 0x3e, + 0x0a, 0x74, 0x68, 0x65, 0x20, 0x6d, 0x6f, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x70, + 0x69, 0x63, 0x74, 0x75, 0x72, 0x65, 0xd0, 0x91, 0xd1, 0x8a, 0xd0, 0xbb, 0xd0, + 0xb3, 0xd0, 0xb0, 0xd1, 0x80, 0xd1, 0x81, 0xd0, 0xba, 0xd0, 0xb8, 0xd0, 0xb1, + 0xd1, 0x8a, 0xd0, 0xbb, 0xd0, 0xb3, 0xd0, 0xb0, 0xd1, 0x80, 0xd1, 0x81, 0xd0, + 0xba, 0xd0, 0xb8, 0xd0, 0xa4, 0xd0, 0xb5, 0xd0, 0xb4, 0xd0, 0xb5, 0xd1, 0x80, + 0xd0, 0xb0, 0xd1, 0x86, 0xd0, 0xb8, 0xd0, 0xb8, 0xd0, 0xbd, 0xd0, 0xb5, 0xd1, + 0x81, 0xd0, 0xba, 0xd0, 0xbe, 0xd0, 0xbb, 0xd1, 0x8c, 0xd0, 0xba, 0xd0, 0xbe, + 0xd1, 0x81, 0xd0, 0xbe, 0xd0, 0xbe, 0xd0, 0xb1, 0xd1, 0x89, 0xd0, 0xb5, 0xd0, + 0xbd, 0xd0, 0xb8, 0xd0, 0xb5, 0xd1, 0x81, 0xd0, 0xbe, 0xd0, 0xbe, 0xd0, 0xb1, + 0xd1, 0x89, 0xd0, 0xb5, 0xd0, 0xbd, 0xd0, 0xb8, 0xd1, 0x8f, 0xd0, 0xbf, 0xd1, + 0x80, 0xd0, 0xbe, 0xd0, 0xb3, 0xd1, 0x80, 0xd0, 0xb0, 0xd0, 0xbc, 0xd0, 0xbc, + 0xd1, 0x8b, 0xd0, 0x9e, 0xd1, 0x82, 0xd0, 0xbf, 0xd1, 0x80, 0xd0, 0xb0, 0xd0, + 0xb2, 0xd0, 0xb8, 0xd1, 0x82, 0xd1, 0x8c, 0xd0, 0xb1, 0xd0, 0xb5, 0xd1, 0x81, + 0xd0, 0xbf, 0xd0, 0xbb, 0xd0, 0xb0, 0xd1, 0x82, 0xd0, 0xbd, 0xd0, 0xbe, 0xd0, + 0xbc, 0xd0, 0xb0, 0xd1, 0x82, 0xd0, 0xb5, 0xd1, 0x80, 0xd0, 0xb8, 0xd0, 0xb0, + 0xd0, 0xbb, 0xd1, 0x8b, 0xd0, 0xbf, 0xd0, 0xbe, 0xd0, 0xb7, 0xd0, 0xb2, 0xd0, + 0xbe, 0xd0, 0xbb, 0xd1, 0x8f, 0xd0, 0xb5, 0xd1, 0x82, 0xd0, 0xbf, 0xd0, 0xbe, + 0xd1, 0x81, 0xd0, 0xbb, 0xd0, 0xb5, 0xd0, 0xb4, 0xd0, 0xbd, 0xd0, 0xb8, 0xd0, + 0xb5, 0xd1, 0x80, 0xd0, 0xb0, 0xd0, 0xb7, 0xd0, 0xbb, 0xd0, 0xb8, 0xd1, 0x87, + 0xd0, 0xbd, 0xd1, 0x8b, 0xd1, 0x85, 0xd0, 0xbf, 0xd1, 0x80, 0xd0, 0xbe, 0xd0, + 0xb4, 0xd1, 0x83, 0xd0, 0xba, 0xd1, 0x86, 0xd0, 0xb8, 0xd0, 0xb8, 0xd0, 0xbf, + 0xd1, 0x80, 0xd0, 0xbe, 0xd0, 0xb3, 0xd1, 0x80, 0xd0, 0xb0, 0xd0, 0xbc, 0xd0, + 0xbc, 0xd0, 0xb0, 0xd0, 0xbf, 0xd0, 0xbe, 0xd0, 0xbb, 0xd0, 0xbd, 0xd0, 0xbe, + 0xd1, 0x81, 0xd1, 0x82, 0xd1, 0x8c, 0xd1, 0x8e, 0xd0, 0xbd, 0xd0, 0xb0, 0xd1, + 0x85, 0xd0, 0xbe, 0xd0, 0xb4, 0xd0, 0xb8, 0xd1, 0x82, 0xd1, 0x81, 0xd1, 0x8f, + 0xd0, 0xb8, 0xd0, 0xb7, 0xd0, 0xb1, 0xd1, 0x80, 0xd0, 0xb0, 0xd0, 0xbd, 0xd0, + 0xbd, 0xd0, 0xbe, 0xd0, 0xb5, 0xd0, 0xbd, 0xd0, 0xb0, 0xd1, 0x81, 0xd0, 0xb5, + 0xd0, 0xbb, 0xd0, 0xb5, 0xd0, 0xbd, 0xd0, 0xb8, 0xd1, 0x8f, 0xd0, 0xb8, 0xd0, + 0xb7, 0xd0, 0xbc, 0xd0, 0xb5, 0xd0, 0xbd, 0xd0, 0xb5, 0xd0, 0xbd, 0xd0, 0xb8, + 0xd1, 0x8f, 0xd0, 0xba, 0xd0, 0xb0, 0xd1, 0x82, 0xd0, 0xb5, 0xd0, 0xb3, 0xd0, + 0xbe, 0xd1, 0x80, 0xd0, 0xb8, 0xd0, 0xb8, 0xd0, 0x90, 0xd0, 0xbb, 0xd0, 0xb5, + 0xd0, 0xba, 0xd1, 0x81, 0xd0, 0xb0, 0xd0, 0xbd, 0xd0, 0xb4, 0xd1, 0x80, 0xe0, + 0xa4, 0xa6, 0xe0, 0xa5, 0x8d, 0xe0, 0xa4, 0xb5, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, + 0xb0, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, 0xae, 0xe0, 0xa5, 0x88, 0xe0, 0xa4, 0xa8, + 0xe0, 0xa5, 0x81, 0xe0, 0xa4, 0x85, 0xe0, 0xa4, 0xb2, 0xe0, 0xa4, 0xaa, 0xe0, + 0xa5, 0x8d, 0xe0, 0xa4, 0xb0, 0xe0, 0xa4, 0xa6, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, + 0xa8, 0xe0, 0xa4, 0xad, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, 0xb0, 0xe0, 0xa4, 0xa4, + 0xe0, 0xa5, 0x80, 0xe0, 0xa4, 0xaf, 0xe0, 0xa4, 0x85, 0xe0, 0xa4, 0xa8, 0xe0, + 0xa5, 0x81, 0xe0, 0xa4, 0xa6, 0xe0, 0xa5, 0x87, 0xe0, 0xa4, 0xb6, 0xe0, 0xa4, + 0xb9, 0xe0, 0xa4, 0xbf, 0xe0, 0xa4, 0xa8, 0xe0, 0xa5, 0x8d, 0xe0, 0xa4, 0xa6, + 0xe0, 0xa5, 0x80, 0xe0, 0xa4, 0x87, 0xe0, 0xa4, 0x82, 0xe0, 0xa4, 0xa1, 0xe0, + 0xa4, 0xbf, 0xe0, 0xa4, 0xaf, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, 0xa6, 0xe0, 0xa4, + 0xbf, 0xe0, 0xa4, 0xb2, 0xe0, 0xa5, 0x8d, 0xe0, 0xa4, 0xb2, 0xe0, 0xa5, 0x80, + 0xe0, 0xa4, 0x85, 0xe0, 0xa4, 0xa7, 0xe0, 0xa4, 0xbf, 0xe0, 0xa4, 0x95, 0xe0, + 0xa4, 0xbe, 0xe0, 0xa4, 0xb0, 0xe0, 0xa4, 0xb5, 0xe0, 0xa5, 0x80, 0xe0, 0xa4, + 0xa1, 0xe0, 0xa4, 0xbf, 0xe0, 0xa4, 0xaf, 0xe0, 0xa5, 0x8b, 0xe0, 0xa4, 0x9a, + 0xe0, 0xa4, 0xbf, 0xe0, 0xa4, 0x9f, 0xe0, 0xa5, 0x8d, 0xe0, 0xa4, 0xa0, 0xe0, + 0xa5, 0x87, 0xe0, 0xa4, 0xb8, 0xe0, 0xa4, 0xae, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, + 0x9a, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, 0xb0, 0xe0, 0xa4, 0x9c, 0xe0, 0xa4, 0x82, + 0xe0, 0xa4, 0x95, 0xe0, 0xa5, 0x8d, 0xe0, 0xa4, 0xb6, 0xe0, 0xa4, 0xa8, 0xe0, + 0xa4, 0xa6, 0xe0, 0xa5, 0x81, 0xe0, 0xa4, 0xa8, 0xe0, 0xa4, 0xbf, 0xe0, 0xa4, + 0xaf, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, 0xaa, 0xe0, 0xa5, 0x8d, 0xe0, 0xa4, 0xb0, + 0xe0, 0xa4, 0xaf, 0xe0, 0xa5, 0x8b, 0xe0, 0xa4, 0x97, 0xe0, 0xa4, 0x85, 0xe0, + 0xa4, 0xa8, 0xe0, 0xa5, 0x81, 0xe0, 0xa4, 0xb8, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, + 0xb0, 0xe0, 0xa4, 0x91, 0xe0, 0xa4, 0xa8, 0xe0, 0xa4, 0xb2, 0xe0, 0xa4, 0xbe, + 0xe0, 0xa4, 0x87, 0xe0, 0xa4, 0xa8, 0xe0, 0xa4, 0xaa, 0xe0, 0xa4, 0xbe, 0xe0, + 0xa4, 0xb0, 0xe0, 0xa5, 0x8d, 0xe0, 0xa4, 0x9f, 0xe0, 0xa5, 0x80, 0xe0, 0xa4, + 0xb6, 0xe0, 0xa4, 0xb0, 0xe0, 0xa5, 0x8d, 0xe0, 0xa4, 0xa4, 0xe0, 0xa5, 0x8b, + 0xe0, 0xa4, 0x82, 0xe0, 0xa4, 0xb2, 0xe0, 0xa5, 0x8b, 0xe0, 0xa4, 0x95, 0xe0, + 0xa4, 0xb8, 0xe0, 0xa4, 0xad, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, 0xab, 0xe0, 0xa4, + 0xbc, 0xe0, 0xa5, 0x8d, 0xe0, 0xa4, 0xb2, 0xe0, 0xa5, 0x88, 0xe0, 0xa4, 0xb6, + 0xe0, 0xa4, 0xb6, 0xe0, 0xa4, 0xb0, 0xe0, 0xa5, 0x8d, 0xe0, 0xa4, 0xa4, 0xe0, + 0xa5, 0x87, 0xe0, 0xa4, 0x82, 0xe0, 0xa4, 0xaa, 0xe0, 0xa5, 0x8d, 0xe0, 0xa4, + 0xb0, 0xe0, 0xa4, 0xa6, 0xe0, 0xa5, 0x87, 0xe0, 0xa4, 0xb6, 0xe0, 0xa4, 0xaa, + 0xe0, 0xa5, 0x8d, 0xe0, 0xa4, 0xb2, 0xe0, 0xa5, 0x87, 0xe0, 0xa4, 0xaf, 0xe0, + 0xa4, 0xb0, 0xe0, 0xa4, 0x95, 0xe0, 0xa5, 0x87, 0xe0, 0xa4, 0x82, 0xe0, 0xa4, + 0xa6, 0xe0, 0xa5, 0x8d, 0xe0, 0xa4, 0xb0, 0xe0, 0xa4, 0xb8, 0xe0, 0xa5, 0x8d, + 0xe0, 0xa4, 0xa5, 0xe0, 0xa4, 0xbf, 0xe0, 0xa4, 0xa4, 0xe0, 0xa4, 0xbf, 0xe0, + 0xa4, 0x89, 0xe0, 0xa4, 0xa4, 0xe0, 0xa5, 0x8d, 0xe0, 0xa4, 0xaa, 0xe0, 0xa4, + 0xbe, 0xe0, 0xa4, 0xa6, 0xe0, 0xa4, 0x89, 0xe0, 0xa4, 0xa8, 0xe0, 0xa5, 0x8d, + 0xe0, 0xa4, 0xb9, 0xe0, 0xa5, 0x87, 0xe0, 0xa4, 0x82, 0xe0, 0xa4, 0x9a, 0xe0, + 0xa4, 0xbf, 0xe0, 0xa4, 0x9f, 0xe0, 0xa5, 0x8d, 0xe0, 0xa4, 0xa0, 0xe0, 0xa4, + 0xbe, 0xe0, 0xa4, 0xaf, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, 0xa4, 0xe0, 0xa5, 0x8d, + 0xe0, 0xa4, 0xb0, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, 0x9c, 0xe0, 0xa5, 0x8d, 0xe0, + 0xa4, 0xaf, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, 0xa6, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, + 0xaa, 0xe0, 0xa5, 0x81, 0xe0, 0xa4, 0xb0, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, 0xa8, + 0xe0, 0xa5, 0x87, 0xe0, 0xa4, 0x9c, 0xe0, 0xa5, 0x8b, 0xe0, 0xa4, 0xa1, 0xe0, + 0xa4, 0xbc, 0xe0, 0xa5, 0x87, 0xe0, 0xa4, 0x82, 0xe0, 0xa4, 0x85, 0xe0, 0xa4, + 0xa8, 0xe0, 0xa5, 0x81, 0xe0, 0xa4, 0xb5, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, 0xa6, + 0xe0, 0xa4, 0xb6, 0xe0, 0xa5, 0x8d, 0xe0, 0xa4, 0xb0, 0xe0, 0xa5, 0x87, 0xe0, + 0xa4, 0xa3, 0xe0, 0xa5, 0x80, 0xe0, 0xa4, 0xb6, 0xe0, 0xa4, 0xbf, 0xe0, 0xa4, + 0x95, 0xe0, 0xa5, 0x8d, 0xe0, 0xa4, 0xb7, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, 0xb8, + 0xe0, 0xa4, 0xb0, 0xe0, 0xa4, 0x95, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, 0xb0, 0xe0, + 0xa5, 0x80, 0xe0, 0xa4, 0xb8, 0xe0, 0xa4, 0x82, 0xe0, 0xa4, 0x97, 0xe0, 0xa5, + 0x8d, 0xe0, 0xa4, 0xb0, 0xe0, 0xa4, 0xb9, 0xe0, 0xa4, 0xaa, 0xe0, 0xa4, 0xb0, + 0xe0, 0xa4, 0xbf, 0xe0, 0xa4, 0xa3, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, 0xae, 0xe0, + 0xa4, 0xac, 0xe0, 0xa5, 0x8d, 0xe0, 0xa4, 0xb0, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, + 0x82, 0xe0, 0xa4, 0xa1, 0xe0, 0xa4, 0xac, 0xe0, 0xa4, 0x9a, 0xe0, 0xa5, 0x8d, + 0xe0, 0xa4, 0x9a, 0xe0, 0xa5, 0x8b, 0xe0, 0xa4, 0x82, 0xe0, 0xa4, 0x89, 0xe0, + 0xa4, 0xaa, 0xe0, 0xa4, 0xb2, 0xe0, 0xa4, 0xac, 0xe0, 0xa5, 0x8d, 0xe0, 0xa4, + 0xa7, 0xe0, 0xa4, 0xae, 0xe0, 0xa4, 0x82, 0xe0, 0xa4, 0xa4, 0xe0, 0xa5, 0x8d, + 0xe0, 0xa4, 0xb0, 0xe0, 0xa5, 0x80, 0xe0, 0xa4, 0xb8, 0xe0, 0xa4, 0x82, 0xe0, + 0xa4, 0xaa, 0xe0, 0xa4, 0xb0, 0xe0, 0xa5, 0x8d, 0xe0, 0xa4, 0x95, 0xe0, 0xa4, + 0x89, 0xe0, 0xa4, 0xae, 0xe0, 0xa5, 0x8d, 0xe0, 0xa4, 0xae, 0xe0, 0xa5, 0x80, + 0xe0, 0xa4, 0xa6, 0xe0, 0xa4, 0xae, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, 0xa7, 0xe0, + 0xa5, 0x8d, 0xe0, 0xa4, 0xaf, 0xe0, 0xa4, 0xae, 0xe0, 0xa4, 0xb8, 0xe0, 0xa4, + 0xb9, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, 0xaf, 0xe0, 0xa4, 0xa4, 0xe0, 0xa4, 0xbe, + 0xe0, 0xa4, 0xb6, 0xe0, 0xa4, 0xac, 0xe0, 0xa5, 0x8d, 0xe0, 0xa4, 0xa6, 0xe0, + 0xa5, 0x8b, 0xe0, 0xa4, 0x82, 0xe0, 0xa4, 0xae, 0xe0, 0xa5, 0x80, 0xe0, 0xa4, + 0xa1, 0xe0, 0xa4, 0xbf, 0xe0, 0xa4, 0xaf, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, 0x86, + 0xe0, 0xa4, 0x88, 0xe0, 0xa4, 0xaa, 0xe0, 0xa5, 0x80, 0xe0, 0xa4, 0x8f, 0xe0, + 0xa4, 0xb2, 0xe0, 0xa4, 0xae, 0xe0, 0xa5, 0x8b, 0xe0, 0xa4, 0xac, 0xe0, 0xa4, + 0xbe, 0xe0, 0xa4, 0x87, 0xe0, 0xa4, 0xb2, 0xe0, 0xa4, 0xb8, 0xe0, 0xa4, 0x82, + 0xe0, 0xa4, 0x96, 0xe0, 0xa5, 0x8d, 0xe0, 0xa4, 0xaf, 0xe0, 0xa4, 0xbe, 0xe0, + 0xa4, 0x86, 0xe0, 0xa4, 0xaa, 0xe0, 0xa4, 0xb0, 0xe0, 0xa5, 0x87, 0xe0, 0xa4, + 0xb6, 0xe0, 0xa4, 0xa8, 0xe0, 0xa4, 0x85, 0xe0, 0xa4, 0xa8, 0xe0, 0xa5, 0x81, + 0xe0, 0xa4, 0xac, 0xe0, 0xa4, 0x82, 0xe0, 0xa4, 0xa7, 0xe0, 0xa4, 0xac, 0xe0, + 0xa4, 0xbe, 0xe0, 0xa4, 0x9c, 0xe0, 0xa4, 0xbc, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, + 0xb0, 0xe0, 0xa4, 0xa8, 0xe0, 0xa4, 0xb5, 0xe0, 0xa5, 0x80, 0xe0, 0xa4, 0xa8, + 0xe0, 0xa4, 0xa4, 0xe0, 0xa4, 0xae, 0xe0, 0xa4, 0xaa, 0xe0, 0xa5, 0x8d, 0xe0, + 0xa4, 0xb0, 0xe0, 0xa4, 0xae, 0xe0, 0xa5, 0x81, 0xe0, 0xa4, 0x96, 0xe0, 0xa4, + 0xaa, 0xe0, 0xa5, 0x8d, 0xe0, 0xa4, 0xb0, 0xe0, 0xa4, 0xb6, 0xe0, 0xa5, 0x8d, + 0xe0, 0xa4, 0xa8, 0xe0, 0xa4, 0xaa, 0xe0, 0xa4, 0xb0, 0xe0, 0xa4, 0xbf, 0xe0, + 0xa4, 0xb5, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, 0xb0, 0xe0, 0xa4, 0xa8, 0xe0, 0xa5, + 0x81, 0xe0, 0xa4, 0x95, 0xe0, 0xa4, 0xb8, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, 0xa8, + 0xe0, 0xa4, 0xb8, 0xe0, 0xa4, 0xae, 0xe0, 0xa4, 0xb0, 0xe0, 0xa5, 0x8d, 0xe0, + 0xa4, 0xa5, 0xe0, 0xa4, 0xa8, 0xe0, 0xa4, 0x86, 0xe0, 0xa4, 0xaf, 0xe0, 0xa5, + 0x8b, 0xe0, 0xa4, 0x9c, 0xe0, 0xa4, 0xbf, 0xe0, 0xa4, 0xa4, 0xe0, 0xa4, 0xb8, + 0xe0, 0xa5, 0x8b, 0xe0, 0xa4, 0xae, 0xe0, 0xa4, 0xb5, 0xe0, 0xa4, 0xbe, 0xe0, + 0xa4, 0xb0, 0xd8, 0xa7, 0xd9, 0x84, 0xd9, 0x85, 0xd8, 0xb4, 0xd8, 0xa7, 0xd8, + 0xb1, 0xd9, 0x83, 0xd8, 0xa7, 0xd8, 0xaa, 0xd8, 0xa7, 0xd9, 0x84, 0xd9, 0x85, + 0xd9, 0x86, 0xd8, 0xaa, 0xd8, 0xaf, 0xd9, 0x8a, 0xd8, 0xa7, 0xd8, 0xaa, 0xd8, + 0xa7, 0xd9, 0x84, 0xd9, 0x83, 0xd9, 0x85, 0xd8, 0xa8, 0xd9, 0x8a, 0xd9, 0x88, + 0xd8, 0xaa, 0xd8, 0xb1, 0xd8, 0xa7, 0xd9, 0x84, 0xd9, 0x85, 0xd8, 0xb4, 0xd8, + 0xa7, 0xd9, 0x87, 0xd8, 0xaf, 0xd8, 0xa7, 0xd8, 0xaa, 0xd8, 0xb9, 0xd8, 0xaf, + 0xd8, 0xaf, 0xd8, 0xa7, 0xd9, 0x84, 0xd8, 0xb2, 0xd9, 0x88, 0xd8, 0xa7, 0xd8, + 0xb1, 0xd8, 0xb9, 0xd8, 0xaf, 0xd8, 0xaf, 0xd8, 0xa7, 0xd9, 0x84, 0xd8, 0xb1, + 0xd8, 0xaf, 0xd9, 0x88, 0xd8, 0xaf, 0xd8, 0xa7, 0xd9, 0x84, 0xd8, 0xa5, 0xd8, + 0xb3, 0xd9, 0x84, 0xd8, 0xa7, 0xd9, 0x85, 0xd9, 0x8a, 0xd8, 0xa9, 0xd8, 0xa7, + 0xd9, 0x84, 0xd9, 0x81, 0xd9, 0x88, 0xd8, 0xaa, 0xd9, 0x88, 0xd8, 0xb4, 0xd9, + 0x88, 0xd8, 0xa8, 0xd8, 0xa7, 0xd9, 0x84, 0xd9, 0x85, 0xd8, 0xb3, 0xd8, 0xa7, + 0xd8, 0xa8, 0xd9, 0x82, 0xd8, 0xa7, 0xd8, 0xaa, 0xd8, 0xa7, 0xd9, 0x84, 0xd9, + 0x85, 0xd8, 0xb9, 0xd9, 0x84, 0xd9, 0x88, 0xd9, 0x85, 0xd8, 0xa7, 0xd8, 0xaa, + 0xd8, 0xa7, 0xd9, 0x84, 0xd9, 0x85, 0xd8, 0xb3, 0xd9, 0x84, 0xd8, 0xb3, 0xd9, + 0x84, 0xd8, 0xa7, 0xd8, 0xaa, 0xd8, 0xa7, 0xd9, 0x84, 0xd8, 0xac, 0xd8, 0xb1, + 0xd8, 0xa7, 0xd9, 0x81, 0xd9, 0x8a, 0xd9, 0x83, 0xd8, 0xb3, 0xd8, 0xa7, 0xd9, + 0x84, 0xd8, 0xa7, 0xd8, 0xb3, 0xd9, 0x84, 0xd8, 0xa7, 0xd9, 0x85, 0xd9, 0x8a, + 0xd8, 0xa9, 0xd8, 0xa7, 0xd9, 0x84, 0xd8, 0xa7, 0xd8, 0xaa, 0xd8, 0xb5, 0xd8, + 0xa7, 0xd9, 0x84, 0xd8, 0xa7, 0xd8, 0xaa, 0x6b, 0x65, 0x79, 0x77, 0x6f, 0x72, + 0x64, 0x73, 0x22, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x3d, 0x22, + 0x77, 0x33, 0x2e, 0x6f, 0x72, 0x67, 0x2f, 0x31, 0x39, 0x39, 0x39, 0x2f, 0x78, + 0x68, 0x74, 0x6d, 0x6c, 0x22, 0x3e, 0x3c, 0x61, 0x20, 0x74, 0x61, 0x72, 0x67, + 0x65, 0x74, 0x3d, 0x22, 0x5f, 0x62, 0x6c, 0x61, 0x6e, 0x6b, 0x22, 0x20, 0x74, + 0x65, 0x78, 0x74, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x3b, 0x20, 0x63, 0x68, 0x61, + 0x72, 0x73, 0x65, 0x74, 0x3d, 0x22, 0x20, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, + 0x3d, 0x22, 0x5f, 0x62, 0x6c, 0x61, 0x6e, 0x6b, 0x22, 0x3e, 0x3c, 0x74, 0x61, + 0x62, 0x6c, 0x65, 0x20, 0x63, 0x65, 0x6c, 0x6c, 0x70, 0x61, 0x64, 0x64, 0x69, + 0x6e, 0x67, 0x3d, 0x22, 0x61, 0x75, 0x74, 0x6f, 0x63, 0x6f, 0x6d, 0x70, 0x6c, + 0x65, 0x74, 0x65, 0x3d, 0x22, 0x6f, 0x66, 0x66, 0x22, 0x20, 0x74, 0x65, 0x78, + 0x74, 0x2d, 0x61, 0x6c, 0x69, 0x67, 0x6e, 0x3a, 0x20, 0x63, 0x65, 0x6e, 0x74, + 0x65, 0x72, 0x3b, 0x74, 0x6f, 0x20, 0x6c, 0x61, 0x73, 0x74, 0x20, 0x76, 0x65, + 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x20, 0x62, 0x79, 0x20, 0x62, 0x61, 0x63, 0x6b, + 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x2d, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, + 0x20, 0x23, 0x22, 0x20, 0x68, 0x72, 0x65, 0x66, 0x3d, 0x22, 0x68, 0x74, 0x74, + 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x2f, 0x64, 0x69, 0x76, 0x3e, + 0x3c, 0x2f, 0x64, 0x69, 0x76, 0x3e, 0x3c, 0x64, 0x69, 0x76, 0x20, 0x69, 0x64, + 0x3d, 0x3c, 0x61, 0x20, 0x68, 0x72, 0x65, 0x66, 0x3d, 0x22, 0x23, 0x22, 0x20, + 0x63, 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x22, 0x22, 0x3e, 0x3c, 0x69, 0x6d, 0x67, + 0x20, 0x73, 0x72, 0x63, 0x3d, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, + 0x63, 0x72, 0x69, 0x70, 0x74, 0x22, 0x20, 0x73, 0x72, 0x63, 0x3d, 0x22, 0x68, + 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x0a, 0x3c, 0x73, 0x63, 0x72, 0x69, 0x70, + 0x74, 0x20, 0x6c, 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, 0x3d, 0x22, 0x2f, + 0x2f, 0x45, 0x4e, 0x22, 0x20, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, + 0x77, 0x77, 0x77, 0x2e, 0x77, 0x65, 0x6e, 0x63, 0x6f, 0x64, 0x65, 0x55, 0x52, + 0x49, 0x43, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x28, 0x22, 0x20, + 0x68, 0x72, 0x65, 0x66, 0x3d, 0x22, 0x6a, 0x61, 0x76, 0x61, 0x73, 0x63, 0x72, + 0x69, 0x70, 0x74, 0x3a, 0x3c, 0x64, 0x69, 0x76, 0x20, 0x63, 0x6c, 0x61, 0x73, + 0x73, 0x3d, 0x22, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x64, 0x6f, 0x63, + 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x77, 0x72, 0x69, 0x74, 0x65, 0x28, 0x27, + 0x3c, 0x73, 0x63, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, + 0x61, 0x62, 0x73, 0x6f, 0x6c, 0x75, 0x74, 0x65, 0x3b, 0x73, 0x63, 0x72, 0x69, + 0x70, 0x74, 0x20, 0x73, 0x72, 0x63, 0x3d, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, + 0x2f, 0x2f, 0x20, 0x73, 0x74, 0x79, 0x6c, 0x65, 0x3d, 0x22, 0x6d, 0x61, 0x72, + 0x67, 0x69, 0x6e, 0x2d, 0x74, 0x6f, 0x70, 0x3a, 0x2e, 0x6d, 0x69, 0x6e, 0x2e, + 0x6a, 0x73, 0x22, 0x3e, 0x3c, 0x2f, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x3e, + 0x0a, 0x3c, 0x2f, 0x64, 0x69, 0x76, 0x3e, 0x0a, 0x3c, 0x64, 0x69, 0x76, 0x20, + 0x63, 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x22, 0x77, 0x33, 0x2e, 0x6f, 0x72, 0x67, + 0x2f, 0x31, 0x39, 0x39, 0x39, 0x2f, 0x78, 0x68, 0x74, 0x6d, 0x6c, 0x22, 0x20, + 0x0a, 0x0d, 0x0a, 0x3c, 0x2f, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0x0d, 0x0a, 0x3c, + 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x3e, 0x64, 0x69, 0x73, 0x74, 0x69, 0x6e, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x62, 0x65, 0x74, 0x77, 0x65, 0x65, 0x6e, 0x2f, + 0x22, 0x20, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x3d, 0x22, 0x5f, 0x62, 0x6c, + 0x61, 0x6e, 0x6b, 0x22, 0x3e, 0x3c, 0x6c, 0x69, 0x6e, 0x6b, 0x20, 0x68, 0x72, + 0x65, 0x66, 0x3d, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x65, 0x6e, + 0x63, 0x6f, 0x64, 0x69, 0x6e, 0x67, 0x3d, 0x22, 0x75, 0x74, 0x66, 0x2d, 0x38, + 0x22, 0x3f, 0x3e, 0x0a, 0x77, 0x2e, 0x61, 0x64, 0x64, 0x45, 0x76, 0x65, 0x6e, + 0x74, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x3f, 0x61, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x3d, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, + 0x77, 0x77, 0x2e, 0x69, 0x63, 0x6f, 0x6e, 0x22, 0x20, 0x68, 0x72, 0x65, 0x66, + 0x3d, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x20, 0x73, 0x74, 0x79, + 0x6c, 0x65, 0x3d, 0x22, 0x62, 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, + 0x64, 0x3a, 0x74, 0x79, 0x70, 0x65, 0x3d, 0x22, 0x74, 0x65, 0x78, 0x74, 0x2f, + 0x63, 0x73, 0x73, 0x22, 0x20, 0x2f, 0x3e, 0x0a, 0x6d, 0x65, 0x74, 0x61, 0x20, + 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x3d, 0x22, 0x6f, 0x67, 0x3a, + 0x74, 0x3c, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x20, 0x74, 0x79, 0x70, 0x65, 0x3d, + 0x22, 0x74, 0x65, 0x78, 0x74, 0x22, 0x20, 0x20, 0x73, 0x74, 0x79, 0x6c, 0x65, + 0x3d, 0x22, 0x74, 0x65, 0x78, 0x74, 0x2d, 0x61, 0x6c, 0x69, 0x67, 0x6e, 0x3a, + 0x74, 0x68, 0x65, 0x20, 0x64, 0x65, 0x76, 0x65, 0x6c, 0x6f, 0x70, 0x6d, 0x65, + 0x6e, 0x74, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x79, 0x6c, 0x65, 0x73, 0x68, 0x65, + 0x65, 0x74, 0x22, 0x20, 0x74, 0x79, 0x70, 0x65, 0x3d, 0x22, 0x74, 0x65, 0x68, + 0x74, 0x6d, 0x6c, 0x3b, 0x20, 0x63, 0x68, 0x61, 0x72, 0x73, 0x65, 0x74, 0x3d, + 0x75, 0x74, 0x66, 0x2d, 0x38, 0x69, 0x73, 0x20, 0x63, 0x6f, 0x6e, 0x73, 0x69, + 0x64, 0x65, 0x72, 0x65, 0x64, 0x20, 0x74, 0x6f, 0x20, 0x62, 0x65, 0x74, 0x61, + 0x62, 0x6c, 0x65, 0x20, 0x77, 0x69, 0x64, 0x74, 0x68, 0x3d, 0x22, 0x31, 0x30, + 0x30, 0x25, 0x22, 0x20, 0x49, 0x6e, 0x20, 0x61, 0x64, 0x64, 0x69, 0x74, 0x69, + 0x6f, 0x6e, 0x20, 0x74, 0x6f, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x6f, 0x6e, + 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x64, 0x20, 0x74, 0x6f, 0x20, 0x74, + 0x68, 0x65, 0x20, 0x64, 0x69, 0x66, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, + 0x73, 0x20, 0x62, 0x65, 0x74, 0x77, 0x65, 0x65, 0x6e, 0x64, 0x65, 0x76, 0x65, + 0x6c, 0x6f, 0x70, 0x6d, 0x65, 0x6e, 0x74, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, + 0x65, 0x20, 0x49, 0x74, 0x20, 0x69, 0x73, 0x20, 0x69, 0x6d, 0x70, 0x6f, 0x72, + 0x74, 0x61, 0x6e, 0x74, 0x20, 0x74, 0x6f, 0x20, 0x3c, 0x2f, 0x73, 0x63, 0x72, + 0x69, 0x70, 0x74, 0x3e, 0x0a, 0x0a, 0x3c, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, + 0x20, 0x20, 0x73, 0x74, 0x79, 0x6c, 0x65, 0x3d, 0x22, 0x66, 0x6f, 0x6e, 0x74, + 0x2d, 0x73, 0x69, 0x7a, 0x65, 0x3a, 0x31, 0x3e, 0x3c, 0x2f, 0x73, 0x70, 0x61, + 0x6e, 0x3e, 0x3c, 0x73, 0x70, 0x61, 0x6e, 0x20, 0x69, 0x64, 0x3d, 0x67, 0x62, + 0x4c, 0x69, 0x62, 0x72, 0x61, 0x72, 0x79, 0x20, 0x6f, 0x66, 0x20, 0x43, 0x6f, + 0x6e, 0x67, 0x72, 0x65, 0x73, 0x73, 0x3c, 0x69, 0x6d, 0x67, 0x20, 0x73, 0x72, + 0x63, 0x3d, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x69, 0x6d, 0x45, + 0x6e, 0x67, 0x6c, 0x69, 0x73, 0x68, 0x20, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x6c, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x41, 0x63, 0x61, 0x64, 0x65, 0x6d, 0x79, 0x20, + 0x6f, 0x66, 0x20, 0x53, 0x63, 0x69, 0x65, 0x6e, 0x63, 0x65, 0x73, 0x64, 0x69, + 0x76, 0x20, 0x73, 0x74, 0x79, 0x6c, 0x65, 0x3d, 0x22, 0x64, 0x69, 0x73, 0x70, + 0x6c, 0x61, 0x79, 0x3a, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x2e, 0x67, 0x65, + 0x74, 0x45, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x42, 0x79, 0x49, 0x64, 0x28, + 0x69, 0x64, 0x29, 0x69, 0x6e, 0x20, 0x63, 0x6f, 0x6e, 0x6a, 0x75, 0x6e, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x77, 0x69, 0x74, 0x68, 0x45, 0x6c, 0x65, 0x6d, + 0x65, 0x6e, 0x74, 0x28, 0x27, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x27, 0x29, + 0x3b, 0x20, 0x3c, 0x6d, 0x65, 0x74, 0x61, 0x20, 0x70, 0x72, 0x6f, 0x70, 0x65, + 0x72, 0x74, 0x79, 0x3d, 0x22, 0x6f, 0x67, 0x3a, 0xd0, 0x91, 0xd1, 0x8a, 0xd0, + 0xbb, 0xd0, 0xb3, 0xd0, 0xb0, 0xd1, 0x80, 0xd1, 0x81, 0xd0, 0xba, 0xd0, 0xb8, + 0x0a, 0x20, 0x74, 0x79, 0x70, 0x65, 0x3d, 0x22, 0x74, 0x65, 0x78, 0x74, 0x22, + 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x3d, 0x22, 0x3e, 0x50, 0x72, 0x69, 0x76, 0x61, + 0x63, 0x79, 0x20, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x3c, 0x2f, 0x61, 0x3e, + 0x61, 0x64, 0x6d, 0x69, 0x6e, 0x69, 0x73, 0x74, 0x65, 0x72, 0x65, 0x64, 0x20, + 0x62, 0x79, 0x20, 0x74, 0x68, 0x65, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x53, + 0x69, 0x6e, 0x67, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x73, + 0x74, 0x79, 0x6c, 0x65, 0x3d, 0x26, 0x71, 0x75, 0x6f, 0x74, 0x3b, 0x6d, 0x61, + 0x72, 0x67, 0x69, 0x6e, 0x3a, 0x3c, 0x2f, 0x64, 0x69, 0x76, 0x3e, 0x3c, 0x2f, + 0x64, 0x69, 0x76, 0x3e, 0x3c, 0x2f, 0x64, 0x69, 0x76, 0x3e, 0x3c, 0x3e, 0x3c, + 0x69, 0x6d, 0x67, 0x20, 0x73, 0x72, 0x63, 0x3d, 0x22, 0x68, 0x74, 0x74, 0x70, + 0x3a, 0x2f, 0x2f, 0x69, 0x20, 0x73, 0x74, 0x79, 0x6c, 0x65, 0x3d, 0x26, 0x71, + 0x75, 0x6f, 0x74, 0x3b, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x3a, 0x72, 0x65, 0x66, + 0x65, 0x72, 0x72, 0x65, 0x64, 0x20, 0x74, 0x6f, 0x20, 0x61, 0x73, 0x20, 0x74, + 0x68, 0x65, 0x20, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x20, 0x70, 0x6f, 0x70, 0x75, + 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6f, 0x66, 0x69, 0x6e, 0x20, 0x57, + 0x61, 0x73, 0x68, 0x69, 0x6e, 0x67, 0x74, 0x6f, 0x6e, 0x2c, 0x20, 0x44, 0x2e, + 0x43, 0x2e, 0x20, 0x73, 0x74, 0x79, 0x6c, 0x65, 0x3d, 0x22, 0x62, 0x61, 0x63, + 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x2d, 0x61, 0x6d, 0x6f, 0x6e, 0x67, + 0x20, 0x6f, 0x74, 0x68, 0x65, 0x72, 0x20, 0x74, 0x68, 0x69, 0x6e, 0x67, 0x73, + 0x2c, 0x6f, 0x72, 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x70, 0x61, 0x72, 0x74, 0x69, 0x63, + 0x69, 0x70, 0x61, 0x74, 0x65, 0x64, 0x20, 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, + 0x74, 0x68, 0x65, 0x20, 0x69, 0x6e, 0x74, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x20, 0x6f, 0x66, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, + 0x69, 0x65, 0x64, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x74, 0x68, 0x65, 0x66, + 0x69, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x20, 0x63, 0x68, 0x61, 0x72, + 0x61, 0x63, 0x74, 0x65, 0x72, 0x20, 0x4f, 0x78, 0x66, 0x6f, 0x72, 0x64, 0x20, + 0x55, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x69, 0x74, 0x79, 0x20, 0x6d, 0x69, + 0x73, 0x75, 0x6e, 0x64, 0x65, 0x72, 0x73, 0x74, 0x61, 0x6e, 0x64, 0x69, 0x6e, + 0x67, 0x20, 0x6f, 0x66, 0x54, 0x68, 0x65, 0x72, 0x65, 0x20, 0x61, 0x72, 0x65, + 0x2c, 0x20, 0x68, 0x6f, 0x77, 0x65, 0x76, 0x65, 0x72, 0x2c, 0x73, 0x74, 0x79, + 0x6c, 0x65, 0x73, 0x68, 0x65, 0x65, 0x74, 0x22, 0x20, 0x68, 0x72, 0x65, 0x66, + 0x3d, 0x22, 0x2f, 0x43, 0x6f, 0x6c, 0x75, 0x6d, 0x62, 0x69, 0x61, 0x20, 0x55, + 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x69, 0x74, 0x79, 0x65, 0x78, 0x70, 0x61, + 0x6e, 0x64, 0x65, 0x64, 0x20, 0x74, 0x6f, 0x20, 0x69, 0x6e, 0x63, 0x6c, 0x75, + 0x64, 0x65, 0x75, 0x73, 0x75, 0x61, 0x6c, 0x6c, 0x79, 0x20, 0x72, 0x65, 0x66, + 0x65, 0x72, 0x72, 0x65, 0x64, 0x20, 0x74, 0x6f, 0x69, 0x6e, 0x64, 0x69, 0x63, + 0x61, 0x74, 0x69, 0x6e, 0x67, 0x20, 0x74, 0x68, 0x61, 0x74, 0x20, 0x74, 0x68, + 0x65, 0x68, 0x61, 0x76, 0x65, 0x20, 0x73, 0x75, 0x67, 0x67, 0x65, 0x73, 0x74, + 0x65, 0x64, 0x20, 0x74, 0x68, 0x61, 0x74, 0x61, 0x66, 0x66, 0x69, 0x6c, 0x69, + 0x61, 0x74, 0x65, 0x64, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x74, 0x68, 0x65, + 0x63, 0x6f, 0x72, 0x72, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x62, + 0x65, 0x74, 0x77, 0x65, 0x65, 0x6e, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x20, + 0x6f, 0x66, 0x20, 0x64, 0x69, 0x66, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x74, 0x3e, + 0x3c, 0x2f, 0x74, 0x64, 0x3e, 0x3c, 0x2f, 0x74, 0x72, 0x3e, 0x3c, 0x2f, 0x74, + 0x61, 0x62, 0x6c, 0x65, 0x3e, 0x52, 0x65, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, + 0x20, 0x6f, 0x66, 0x20, 0x49, 0x72, 0x65, 0x6c, 0x61, 0x6e, 0x64, 0x0a, 0x3c, + 0x2f, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x3e, 0x0a, 0x3c, 0x73, 0x63, 0x72, + 0x69, 0x70, 0x74, 0x20, 0x75, 0x6e, 0x64, 0x65, 0x72, 0x20, 0x74, 0x68, 0x65, + 0x20, 0x69, 0x6e, 0x66, 0x6c, 0x75, 0x65, 0x6e, 0x63, 0x65, 0x63, 0x6f, 0x6e, + 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x74, 0x6f, 0x20, + 0x74, 0x68, 0x65, 0x4f, 0x66, 0x66, 0x69, 0x63, 0x69, 0x61, 0x6c, 0x20, 0x77, + 0x65, 0x62, 0x73, 0x69, 0x74, 0x65, 0x20, 0x6f, 0x66, 0x68, 0x65, 0x61, 0x64, + 0x71, 0x75, 0x61, 0x72, 0x74, 0x65, 0x72, 0x73, 0x20, 0x6f, 0x66, 0x20, 0x74, + 0x68, 0x65, 0x63, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x65, 0x64, 0x20, 0x61, 0x72, + 0x6f, 0x75, 0x6e, 0x64, 0x20, 0x74, 0x68, 0x65, 0x69, 0x6d, 0x70, 0x6c, 0x69, + 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, + 0x65, 0x68, 0x61, 0x76, 0x65, 0x20, 0x62, 0x65, 0x65, 0x6e, 0x20, 0x64, 0x65, + 0x76, 0x65, 0x6c, 0x6f, 0x70, 0x65, 0x64, 0x46, 0x65, 0x64, 0x65, 0x72, 0x61, + 0x6c, 0x20, 0x52, 0x65, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x20, 0x6f, 0x66, + 0x62, 0x65, 0x63, 0x61, 0x6d, 0x65, 0x20, 0x69, 0x6e, 0x63, 0x72, 0x65, 0x61, + 0x73, 0x69, 0x6e, 0x67, 0x6c, 0x79, 0x63, 0x6f, 0x6e, 0x74, 0x69, 0x6e, 0x75, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x4e, + 0x6f, 0x74, 0x65, 0x2c, 0x20, 0x68, 0x6f, 0x77, 0x65, 0x76, 0x65, 0x72, 0x2c, + 0x20, 0x74, 0x68, 0x61, 0x74, 0x73, 0x69, 0x6d, 0x69, 0x6c, 0x61, 0x72, 0x20, + 0x74, 0x6f, 0x20, 0x74, 0x68, 0x61, 0x74, 0x20, 0x6f, 0x66, 0x20, 0x63, 0x61, + 0x70, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x69, 0x65, 0x73, 0x20, 0x6f, 0x66, + 0x20, 0x74, 0x68, 0x65, 0x61, 0x63, 0x63, 0x6f, 0x72, 0x64, 0x61, 0x6e, 0x63, + 0x65, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x74, 0x68, 0x65, 0x70, 0x61, 0x72, + 0x74, 0x69, 0x63, 0x69, 0x70, 0x61, 0x6e, 0x74, 0x73, 0x20, 0x69, 0x6e, 0x20, + 0x74, 0x68, 0x65, 0x66, 0x75, 0x72, 0x74, 0x68, 0x65, 0x72, 0x20, 0x64, 0x65, + 0x76, 0x65, 0x6c, 0x6f, 0x70, 0x6d, 0x65, 0x6e, 0x74, 0x75, 0x6e, 0x64, 0x65, + 0x72, 0x20, 0x74, 0x68, 0x65, 0x20, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x69, 0x73, 0x20, 0x6f, 0x66, 0x74, 0x65, 0x6e, 0x20, 0x63, 0x6f, + 0x6e, 0x73, 0x69, 0x64, 0x65, 0x72, 0x65, 0x64, 0x68, 0x69, 0x73, 0x20, 0x79, + 0x6f, 0x75, 0x6e, 0x67, 0x65, 0x72, 0x20, 0x62, 0x72, 0x6f, 0x74, 0x68, 0x65, + 0x72, 0x3c, 0x2f, 0x74, 0x64, 0x3e, 0x3c, 0x2f, 0x74, 0x72, 0x3e, 0x3c, 0x2f, + 0x74, 0x61, 0x62, 0x6c, 0x65, 0x3e, 0x3c, 0x61, 0x20, 0x68, 0x74, 0x74, 0x70, + 0x2d, 0x65, 0x71, 0x75, 0x69, 0x76, 0x3d, 0x22, 0x58, 0x2d, 0x55, 0x41, 0x2d, + 0x70, 0x68, 0x79, 0x73, 0x69, 0x63, 0x61, 0x6c, 0x20, 0x70, 0x72, 0x6f, 0x70, + 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x6f, 0x66, 0x20, 0x42, 0x72, 0x69, 0x74, + 0x69, 0x73, 0x68, 0x20, 0x43, 0x6f, 0x6c, 0x75, 0x6d, 0x62, 0x69, 0x61, 0x68, + 0x61, 0x73, 0x20, 0x62, 0x65, 0x65, 0x6e, 0x20, 0x63, 0x72, 0x69, 0x74, 0x69, + 0x63, 0x69, 0x7a, 0x65, 0x64, 0x28, 0x77, 0x69, 0x74, 0x68, 0x20, 0x74, 0x68, + 0x65, 0x20, 0x65, 0x78, 0x63, 0x65, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x61, 0x62, 0x6f, 0x75, 0x74, + 0x20, 0x74, 0x68, 0x65, 0x70, 0x61, 0x73, 0x73, 0x69, 0x6e, 0x67, 0x20, 0x74, + 0x68, 0x72, 0x6f, 0x75, 0x67, 0x68, 0x20, 0x74, 0x68, 0x65, 0x30, 0x22, 0x20, + 0x63, 0x65, 0x6c, 0x6c, 0x70, 0x61, 0x64, 0x64, 0x69, 0x6e, 0x67, 0x3d, 0x22, + 0x30, 0x22, 0x20, 0x74, 0x68, 0x6f, 0x75, 0x73, 0x61, 0x6e, 0x64, 0x73, 0x20, + 0x6f, 0x66, 0x20, 0x70, 0x65, 0x6f, 0x70, 0x6c, 0x65, 0x72, 0x65, 0x64, 0x69, + 0x72, 0x65, 0x63, 0x74, 0x73, 0x20, 0x68, 0x65, 0x72, 0x65, 0x2e, 0x20, 0x46, + 0x6f, 0x72, 0x68, 0x61, 0x76, 0x65, 0x20, 0x63, 0x68, 0x69, 0x6c, 0x64, 0x72, + 0x65, 0x6e, 0x20, 0x75, 0x6e, 0x64, 0x65, 0x72, 0x25, 0x33, 0x45, 0x25, 0x33, + 0x43, 0x2f, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x25, 0x33, 0x45, 0x22, 0x29, + 0x29, 0x3b, 0x3c, 0x61, 0x20, 0x68, 0x72, 0x65, 0x66, 0x3d, 0x22, 0x68, 0x74, + 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x3c, 0x6c, 0x69, 0x3e, + 0x3c, 0x61, 0x20, 0x68, 0x72, 0x65, 0x66, 0x3d, 0x22, 0x68, 0x74, 0x74, 0x70, + 0x3a, 0x2f, 0x2f, 0x73, 0x69, 0x74, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x22, + 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x3d, 0x22, 0x74, 0x65, 0x78, + 0x74, 0x2d, 0x64, 0x65, 0x63, 0x6f, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3a, + 0x6e, 0x6f, 0x6e, 0x65, 0x73, 0x74, 0x79, 0x6c, 0x65, 0x3d, 0x22, 0x64, 0x69, + 0x73, 0x70, 0x6c, 0x61, 0x79, 0x3a, 0x20, 0x6e, 0x6f, 0x6e, 0x65, 0x3c, 0x6d, + 0x65, 0x74, 0x61, 0x20, 0x68, 0x74, 0x74, 0x70, 0x2d, 0x65, 0x71, 0x75, 0x69, + 0x76, 0x3d, 0x22, 0x58, 0x2d, 0x6e, 0x65, 0x77, 0x20, 0x44, 0x61, 0x74, 0x65, + 0x28, 0x29, 0x2e, 0x67, 0x65, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x28, 0x29, 0x20, + 0x74, 0x79, 0x70, 0x65, 0x3d, 0x22, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x2f, 0x78, + 0x2d, 0x69, 0x63, 0x6f, 0x6e, 0x22, 0x3c, 0x2f, 0x73, 0x70, 0x61, 0x6e, 0x3e, + 0x3c, 0x73, 0x70, 0x61, 0x6e, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x22, + 0x6c, 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, 0x3d, 0x22, 0x6a, 0x61, 0x76, + 0x61, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x77, 0x69, 0x6e, 0x64, 0x6f, 0x77, + 0x2e, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x68, 0x72, 0x65, + 0x66, 0x3c, 0x61, 0x20, 0x68, 0x72, 0x65, 0x66, 0x3d, 0x22, 0x6a, 0x61, 0x76, + 0x61, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x3a, 0x2d, 0x2d, 0x3e, 0x0d, 0x0a, + 0x3c, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x20, 0x74, 0x79, 0x70, 0x65, 0x3d, + 0x22, 0x74, 0x3c, 0x61, 0x20, 0x68, 0x72, 0x65, 0x66, 0x3d, 0x27, 0x68, 0x74, + 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x68, 0x6f, 0x72, 0x74, + 0x63, 0x75, 0x74, 0x20, 0x69, 0x63, 0x6f, 0x6e, 0x22, 0x20, 0x68, 0x72, 0x65, + 0x66, 0x3d, 0x22, 0x3c, 0x2f, 0x64, 0x69, 0x76, 0x3e, 0x0d, 0x0a, 0x3c, 0x64, + 0x69, 0x76, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x22, 0x3c, 0x73, 0x63, + 0x72, 0x69, 0x70, 0x74, 0x20, 0x73, 0x72, 0x63, 0x3d, 0x22, 0x68, 0x74, 0x74, + 0x70, 0x3a, 0x2f, 0x2f, 0x22, 0x20, 0x72, 0x65, 0x6c, 0x3d, 0x22, 0x73, 0x74, + 0x79, 0x6c, 0x65, 0x73, 0x68, 0x65, 0x65, 0x74, 0x22, 0x20, 0x74, 0x3c, 0x2f, + 0x64, 0x69, 0x76, 0x3e, 0x0a, 0x3c, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x20, + 0x74, 0x79, 0x70, 0x65, 0x3d, 0x2f, 0x61, 0x3e, 0x20, 0x3c, 0x61, 0x20, 0x68, + 0x72, 0x65, 0x66, 0x3d, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x20, + 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x61, 0x72, + 0x65, 0x6e, 0x63, 0x79, 0x3d, 0x22, 0x58, 0x2d, 0x55, 0x41, 0x2d, 0x43, 0x6f, + 0x6d, 0x70, 0x61, 0x74, 0x69, 0x62, 0x6c, 0x65, 0x22, 0x20, 0x63, 0x6f, 0x6e, + 0x72, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x68, 0x69, 0x70, 0x20, + 0x62, 0x65, 0x74, 0x77, 0x65, 0x65, 0x6e, 0x0a, 0x3c, 0x2f, 0x73, 0x63, 0x72, + 0x69, 0x70, 0x74, 0x3e, 0x0d, 0x0a, 0x3c, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, + 0x20, 0x3c, 0x2f, 0x61, 0x3e, 0x3c, 0x2f, 0x6c, 0x69, 0x3e, 0x3c, 0x2f, 0x75, + 0x6c, 0x3e, 0x3c, 0x2f, 0x64, 0x69, 0x76, 0x3e, 0x61, 0x73, 0x73, 0x6f, 0x63, + 0x69, 0x61, 0x74, 0x65, 0x64, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x74, 0x68, + 0x65, 0x20, 0x70, 0x72, 0x6f, 0x67, 0x72, 0x61, 0x6d, 0x6d, 0x69, 0x6e, 0x67, + 0x20, 0x6c, 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, 0x3c, 0x2f, 0x61, 0x3e, + 0x3c, 0x61, 0x20, 0x68, 0x72, 0x65, 0x66, 0x3d, 0x22, 0x68, 0x74, 0x74, 0x70, + 0x3a, 0x2f, 0x2f, 0x3c, 0x2f, 0x61, 0x3e, 0x3c, 0x2f, 0x6c, 0x69, 0x3e, 0x3c, + 0x6c, 0x69, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x22, 0x66, 0x6f, 0x72, + 0x6d, 0x20, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x3d, 0x22, 0x68, 0x74, 0x74, + 0x70, 0x3a, 0x2f, 0x2f, 0x3c, 0x64, 0x69, 0x76, 0x20, 0x73, 0x74, 0x79, 0x6c, + 0x65, 0x3d, 0x22, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x3a, 0x74, 0x79, + 0x70, 0x65, 0x3d, 0x22, 0x74, 0x65, 0x78, 0x74, 0x22, 0x20, 0x6e, 0x61, 0x6d, + 0x65, 0x3d, 0x22, 0x71, 0x22, 0x3c, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x20, 0x77, + 0x69, 0x64, 0x74, 0x68, 0x3d, 0x22, 0x31, 0x30, 0x30, 0x25, 0x22, 0x20, 0x62, + 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x2d, 0x70, 0x6f, 0x73, + 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x22, 0x20, 0x62, 0x6f, 0x72, 0x64, 0x65, + 0x72, 0x3d, 0x22, 0x30, 0x22, 0x20, 0x77, 0x69, 0x64, 0x74, 0x68, 0x3d, 0x22, + 0x72, 0x65, 0x6c, 0x3d, 0x22, 0x73, 0x68, 0x6f, 0x72, 0x74, 0x63, 0x75, 0x74, + 0x20, 0x69, 0x63, 0x6f, 0x6e, 0x22, 0x20, 0x68, 0x36, 0x3e, 0x3c, 0x75, 0x6c, + 0x3e, 0x3c, 0x6c, 0x69, 0x3e, 0x3c, 0x61, 0x20, 0x68, 0x72, 0x65, 0x66, 0x3d, + 0x22, 0x20, 0x20, 0x3c, 0x6d, 0x65, 0x74, 0x61, 0x20, 0x68, 0x74, 0x74, 0x70, + 0x2d, 0x65, 0x71, 0x75, 0x69, 0x76, 0x3d, 0x22, 0x63, 0x73, 0x73, 0x22, 0x20, + 0x6d, 0x65, 0x64, 0x69, 0x61, 0x3d, 0x22, 0x73, 0x63, 0x72, 0x65, 0x65, 0x6e, + 0x22, 0x20, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x69, 0x62, 0x6c, 0x65, + 0x20, 0x66, 0x6f, 0x72, 0x20, 0x74, 0x68, 0x65, 0x20, 0x22, 0x20, 0x74, 0x79, + 0x70, 0x65, 0x3d, 0x22, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x2f, 0x22, 0x20, 0x73, 0x74, 0x79, 0x6c, 0x65, 0x3d, 0x22, 0x62, + 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x2d, 0x68, 0x74, 0x6d, + 0x6c, 0x3b, 0x20, 0x63, 0x68, 0x61, 0x72, 0x73, 0x65, 0x74, 0x3d, 0x75, 0x74, + 0x66, 0x2d, 0x38, 0x22, 0x20, 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x74, 0x72, 0x61, + 0x6e, 0x73, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x63, 0x79, 0x3d, 0x22, 0x73, 0x74, + 0x79, 0x6c, 0x65, 0x73, 0x68, 0x65, 0x65, 0x74, 0x22, 0x20, 0x74, 0x79, 0x70, + 0x65, 0x3d, 0x22, 0x74, 0x65, 0x0d, 0x0a, 0x3c, 0x6d, 0x65, 0x74, 0x61, 0x20, + 0x68, 0x74, 0x74, 0x70, 0x2d, 0x65, 0x71, 0x75, 0x69, 0x76, 0x3d, 0x22, 0x3e, + 0x3c, 0x2f, 0x73, 0x70, 0x61, 0x6e, 0x3e, 0x3c, 0x73, 0x70, 0x61, 0x6e, 0x20, + 0x63, 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x22, 0x30, 0x22, 0x20, 0x63, 0x65, 0x6c, + 0x6c, 0x73, 0x70, 0x61, 0x63, 0x69, 0x6e, 0x67, 0x3d, 0x22, 0x30, 0x22, 0x3e, + 0x3b, 0x0a, 0x3c, 0x2f, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x3e, 0x0a, 0x3c, + 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x20, 0x73, 0x6f, 0x6d, 0x65, 0x74, 0x69, + 0x6d, 0x65, 0x73, 0x20, 0x63, 0x61, 0x6c, 0x6c, 0x65, 0x64, 0x20, 0x74, 0x68, + 0x65, 0x64, 0x6f, 0x65, 0x73, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x6e, 0x65, 0x63, + 0x65, 0x73, 0x73, 0x61, 0x72, 0x69, 0x6c, 0x79, 0x46, 0x6f, 0x72, 0x20, 0x6d, + 0x6f, 0x72, 0x65, 0x20, 0x69, 0x6e, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x61, 0x74, 0x20, 0x74, 0x68, 0x65, 0x20, 0x62, 0x65, 0x67, 0x69, + 0x6e, 0x6e, 0x69, 0x6e, 0x67, 0x20, 0x6f, 0x66, 0x20, 0x3c, 0x21, 0x44, 0x4f, + 0x43, 0x54, 0x59, 0x50, 0x45, 0x20, 0x68, 0x74, 0x6d, 0x6c, 0x3e, 0x3c, 0x68, + 0x74, 0x6d, 0x6c, 0x70, 0x61, 0x72, 0x74, 0x69, 0x63, 0x75, 0x6c, 0x61, 0x72, + 0x6c, 0x79, 0x20, 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x74, 0x79, 0x70, + 0x65, 0x3d, 0x22, 0x68, 0x69, 0x64, 0x64, 0x65, 0x6e, 0x22, 0x20, 0x6e, 0x61, + 0x6d, 0x65, 0x3d, 0x22, 0x6a, 0x61, 0x76, 0x61, 0x73, 0x63, 0x72, 0x69, 0x70, + 0x74, 0x3a, 0x76, 0x6f, 0x69, 0x64, 0x28, 0x30, 0x29, 0x3b, 0x22, 0x65, 0x66, + 0x66, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x6e, 0x65, 0x73, 0x73, 0x20, 0x6f, + 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x61, 0x75, 0x74, 0x6f, 0x63, 0x6f, 0x6d, + 0x70, 0x6c, 0x65, 0x74, 0x65, 0x3d, 0x22, 0x6f, 0x66, 0x66, 0x22, 0x20, 0x67, + 0x65, 0x6e, 0x65, 0x72, 0x61, 0x6c, 0x6c, 0x79, 0x20, 0x63, 0x6f, 0x6e, 0x73, + 0x69, 0x64, 0x65, 0x72, 0x65, 0x64, 0x3e, 0x3c, 0x69, 0x6e, 0x70, 0x75, 0x74, + 0x20, 0x74, 0x79, 0x70, 0x65, 0x3d, 0x22, 0x74, 0x65, 0x78, 0x74, 0x22, 0x20, + 0x22, 0x3e, 0x3c, 0x2f, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x3e, 0x0d, 0x0a, + 0x3c, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x74, 0x68, 0x72, 0x6f, 0x75, 0x67, + 0x68, 0x6f, 0x75, 0x74, 0x20, 0x74, 0x68, 0x65, 0x20, 0x77, 0x6f, 0x72, 0x6c, + 0x64, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x20, 0x6d, 0x69, 0x73, 0x63, 0x6f, + 0x6e, 0x63, 0x65, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x73, 0x73, 0x6f, 0x63, + 0x69, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x74, + 0x68, 0x65, 0x3c, 0x2f, 0x64, 0x69, 0x76, 0x3e, 0x0a, 0x3c, 0x2f, 0x64, 0x69, + 0x76, 0x3e, 0x0a, 0x3c, 0x64, 0x69, 0x76, 0x20, 0x63, 0x64, 0x75, 0x72, 0x69, + 0x6e, 0x67, 0x20, 0x68, 0x69, 0x73, 0x20, 0x6c, 0x69, 0x66, 0x65, 0x74, 0x69, + 0x6d, 0x65, 0x2c, 0x63, 0x6f, 0x72, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x64, + 0x69, 0x6e, 0x67, 0x20, 0x74, 0x6f, 0x20, 0x74, 0x68, 0x65, 0x74, 0x79, 0x70, + 0x65, 0x3d, 0x22, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x2f, 0x78, 0x2d, 0x69, 0x63, + 0x6f, 0x6e, 0x22, 0x20, 0x61, 0x6e, 0x20, 0x69, 0x6e, 0x63, 0x72, 0x65, 0x61, + 0x73, 0x69, 0x6e, 0x67, 0x20, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x64, 0x69, + 0x70, 0x6c, 0x6f, 0x6d, 0x61, 0x74, 0x69, 0x63, 0x20, 0x72, 0x65, 0x6c, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x61, 0x72, 0x65, 0x20, 0x6f, 0x66, 0x74, 0x65, + 0x6e, 0x20, 0x63, 0x6f, 0x6e, 0x73, 0x69, 0x64, 0x65, 0x72, 0x65, 0x64, 0x6d, + 0x65, 0x74, 0x61, 0x20, 0x63, 0x68, 0x61, 0x72, 0x73, 0x65, 0x74, 0x3d, 0x22, + 0x75, 0x74, 0x66, 0x2d, 0x38, 0x22, 0x20, 0x3c, 0x69, 0x6e, 0x70, 0x75, 0x74, + 0x20, 0x74, 0x79, 0x70, 0x65, 0x3d, 0x22, 0x74, 0x65, 0x78, 0x74, 0x22, 0x20, + 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x73, 0x20, 0x69, 0x6e, 0x63, 0x6c, + 0x75, 0x64, 0x65, 0x20, 0x74, 0x68, 0x65, 0x22, 0x3e, 0x3c, 0x69, 0x6d, 0x67, + 0x20, 0x73, 0x72, 0x63, 0x3d, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, + 0x69, 0x70, 0x61, 0x72, 0x74, 0x69, 0x63, 0x69, 0x70, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x20, 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x74, 0x68, 0x65, 0x20, 0x65, + 0x73, 0x74, 0x61, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x6d, 0x65, 0x6e, 0x74, 0x20, + 0x6f, 0x66, 0x0a, 0x3c, 0x2f, 0x64, 0x69, 0x76, 0x3e, 0x0a, 0x3c, 0x64, 0x69, + 0x76, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x22, 0x26, 0x61, 0x6d, 0x70, + 0x3b, 0x6e, 0x62, 0x73, 0x70, 0x3b, 0x26, 0x61, 0x6d, 0x70, 0x3b, 0x6e, 0x62, + 0x73, 0x70, 0x3b, 0x74, 0x6f, 0x20, 0x64, 0x65, 0x74, 0x65, 0x72, 0x6d, 0x69, + 0x6e, 0x65, 0x20, 0x77, 0x68, 0x65, 0x74, 0x68, 0x65, 0x72, 0x71, 0x75, 0x69, + 0x74, 0x65, 0x20, 0x64, 0x69, 0x66, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x74, 0x20, + 0x66, 0x72, 0x6f, 0x6d, 0x6d, 0x61, 0x72, 0x6b, 0x65, 0x64, 0x20, 0x74, 0x68, + 0x65, 0x20, 0x62, 0x65, 0x67, 0x69, 0x6e, 0x6e, 0x69, 0x6e, 0x67, 0x64, 0x69, + 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x20, 0x62, 0x65, 0x74, 0x77, 0x65, 0x65, + 0x6e, 0x20, 0x74, 0x68, 0x65, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x69, 0x62, 0x75, + 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x74, 0x6f, 0x20, 0x74, 0x68, 0x65, 0x63, + 0x6f, 0x6e, 0x66, 0x6c, 0x69, 0x63, 0x74, 0x20, 0x62, 0x65, 0x74, 0x77, 0x65, + 0x65, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x77, 0x69, 0x64, 0x65, 0x6c, 0x79, 0x20, + 0x63, 0x6f, 0x6e, 0x73, 0x69, 0x64, 0x65, 0x72, 0x65, 0x64, 0x20, 0x74, 0x6f, + 0x77, 0x61, 0x73, 0x20, 0x6f, 0x6e, 0x65, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, + 0x65, 0x20, 0x66, 0x69, 0x72, 0x73, 0x74, 0x77, 0x69, 0x74, 0x68, 0x20, 0x76, + 0x61, 0x72, 0x79, 0x69, 0x6e, 0x67, 0x20, 0x64, 0x65, 0x67, 0x72, 0x65, 0x65, + 0x73, 0x68, 0x61, 0x76, 0x65, 0x20, 0x73, 0x70, 0x65, 0x63, 0x75, 0x6c, 0x61, + 0x74, 0x65, 0x64, 0x20, 0x74, 0x68, 0x61, 0x74, 0x28, 0x64, 0x6f, 0x63, 0x75, + 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x67, 0x65, 0x74, 0x45, 0x6c, 0x65, 0x6d, 0x65, + 0x6e, 0x74, 0x70, 0x61, 0x72, 0x74, 0x69, 0x63, 0x69, 0x70, 0x61, 0x74, 0x69, + 0x6e, 0x67, 0x20, 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x6f, 0x72, 0x69, 0x67, + 0x69, 0x6e, 0x61, 0x6c, 0x6c, 0x79, 0x20, 0x64, 0x65, 0x76, 0x65, 0x6c, 0x6f, + 0x70, 0x65, 0x64, 0x65, 0x74, 0x61, 0x20, 0x63, 0x68, 0x61, 0x72, 0x73, 0x65, + 0x74, 0x3d, 0x22, 0x75, 0x74, 0x66, 0x2d, 0x38, 0x22, 0x3e, 0x20, 0x74, 0x79, + 0x70, 0x65, 0x3d, 0x22, 0x74, 0x65, 0x78, 0x74, 0x2f, 0x63, 0x73, 0x73, 0x22, + 0x20, 0x2f, 0x3e, 0x0a, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x63, 0x68, 0x61, 0x6e, + 0x67, 0x65, 0x61, 0x62, 0x6c, 0x79, 0x20, 0x77, 0x69, 0x74, 0x68, 0x6d, 0x6f, + 0x72, 0x65, 0x20, 0x63, 0x6c, 0x6f, 0x73, 0x65, 0x6c, 0x79, 0x20, 0x72, 0x65, + 0x6c, 0x61, 0x74, 0x65, 0x64, 0x73, 0x6f, 0x63, 0x69, 0x61, 0x6c, 0x20, 0x61, + 0x6e, 0x64, 0x20, 0x70, 0x6f, 0x6c, 0x69, 0x74, 0x69, 0x63, 0x61, 0x6c, 0x74, + 0x68, 0x61, 0x74, 0x20, 0x77, 0x6f, 0x75, 0x6c, 0x64, 0x20, 0x6f, 0x74, 0x68, + 0x65, 0x72, 0x77, 0x69, 0x73, 0x65, 0x70, 0x65, 0x72, 0x70, 0x65, 0x6e, 0x64, + 0x69, 0x63, 0x75, 0x6c, 0x61, 0x72, 0x20, 0x74, 0x6f, 0x20, 0x74, 0x68, 0x65, + 0x73, 0x74, 0x79, 0x6c, 0x65, 0x20, 0x74, 0x79, 0x70, 0x65, 0x3d, 0x22, 0x74, + 0x65, 0x78, 0x74, 0x2f, 0x63, 0x73, 0x73, 0x74, 0x79, 0x70, 0x65, 0x3d, 0x22, + 0x73, 0x75, 0x62, 0x6d, 0x69, 0x74, 0x22, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x3d, + 0x22, 0x66, 0x61, 0x6d, 0x69, 0x6c, 0x69, 0x65, 0x73, 0x20, 0x72, 0x65, 0x73, + 0x69, 0x64, 0x69, 0x6e, 0x67, 0x20, 0x69, 0x6e, 0x64, 0x65, 0x76, 0x65, 0x6c, + 0x6f, 0x70, 0x69, 0x6e, 0x67, 0x20, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x72, 0x69, + 0x65, 0x73, 0x63, 0x6f, 0x6d, 0x70, 0x75, 0x74, 0x65, 0x72, 0x20, 0x70, 0x72, + 0x6f, 0x67, 0x72, 0x61, 0x6d, 0x6d, 0x69, 0x6e, 0x67, 0x65, 0x63, 0x6f, 0x6e, + 0x6f, 0x6d, 0x69, 0x63, 0x20, 0x64, 0x65, 0x76, 0x65, 0x6c, 0x6f, 0x70, 0x6d, + 0x65, 0x6e, 0x74, 0x64, 0x65, 0x74, 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x66, 0x6f, 0x72, + 0x20, 0x6d, 0x6f, 0x72, 0x65, 0x20, 0x69, 0x6e, 0x66, 0x6f, 0x72, 0x6d, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x6f, 0x6e, 0x20, 0x73, 0x65, 0x76, 0x65, 0x72, 0x61, + 0x6c, 0x20, 0x6f, 0x63, 0x63, 0x61, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x70, 0x6f, + 0x72, 0x74, 0x75, 0x67, 0x75, 0xc3, 0xaa, 0x73, 0x20, 0x28, 0x45, 0x75, 0x72, + 0x6f, 0x70, 0x65, 0x75, 0x29, 0xd0, 0xa3, 0xd0, 0xba, 0xd1, 0x80, 0xd0, 0xb0, + 0xd1, 0x97, 0xd0, 0xbd, 0xd1, 0x81, 0xd1, 0x8c, 0xd0, 0xba, 0xd0, 0xb0, 0xd1, + 0x83, 0xd0, 0xba, 0xd1, 0x80, 0xd0, 0xb0, 0xd1, 0x97, 0xd0, 0xbd, 0xd1, 0x81, + 0xd1, 0x8c, 0xd0, 0xba, 0xd0, 0xb0, 0xd0, 0xa0, 0xd0, 0xbe, 0xd1, 0x81, 0xd1, + 0x81, 0xd0, 0xb8, 0xd0, 0xb9, 0xd1, 0x81, 0xd0, 0xba, 0xd0, 0xbe, 0xd0, 0xb9, + 0xd0, 0xbc, 0xd0, 0xb0, 0xd1, 0x82, 0xd0, 0xb5, 0xd1, 0x80, 0xd0, 0xb8, 0xd0, + 0xb0, 0xd0, 0xbb, 0xd0, 0xbe, 0xd0, 0xb2, 0xd0, 0xb8, 0xd0, 0xbd, 0xd1, 0x84, + 0xd0, 0xbe, 0xd1, 0x80, 0xd0, 0xbc, 0xd0, 0xb0, 0xd1, 0x86, 0xd0, 0xb8, 0xd0, + 0xb8, 0xd1, 0x83, 0xd0, 0xbf, 0xd1, 0x80, 0xd0, 0xb0, 0xd0, 0xb2, 0xd0, 0xbb, + 0xd0, 0xb5, 0xd0, 0xbd, 0xd0, 0xb8, 0xd1, 0x8f, 0xd0, 0xbd, 0xd0, 0xb5, 0xd0, + 0xbe, 0xd0, 0xb1, 0xd1, 0x85, 0xd0, 0xbe, 0xd0, 0xb4, 0xd0, 0xb8, 0xd0, 0xbc, + 0xd0, 0xbe, 0xd0, 0xb8, 0xd0, 0xbd, 0xd1, 0x84, 0xd0, 0xbe, 0xd1, 0x80, 0xd0, + 0xbc, 0xd0, 0xb0, 0xd1, 0x86, 0xd0, 0xb8, 0xd1, 0x8f, 0xd0, 0x98, 0xd0, 0xbd, + 0xd1, 0x84, 0xd0, 0xbe, 0xd1, 0x80, 0xd0, 0xbc, 0xd0, 0xb0, 0xd1, 0x86, 0xd0, + 0xb8, 0xd1, 0x8f, 0xd0, 0xa0, 0xd0, 0xb5, 0xd1, 0x81, 0xd0, 0xbf, 0xd1, 0x83, + 0xd0, 0xb1, 0xd0, 0xbb, 0xd0, 0xb8, 0xd0, 0xba, 0xd0, 0xb8, 0xd0, 0xba, 0xd0, + 0xbe, 0xd0, 0xbb, 0xd0, 0xb8, 0xd1, 0x87, 0xd0, 0xb5, 0xd1, 0x81, 0xd1, 0x82, + 0xd0, 0xb2, 0xd0, 0xbe, 0xd0, 0xb8, 0xd0, 0xbd, 0xd1, 0x84, 0xd0, 0xbe, 0xd1, + 0x80, 0xd0, 0xbc, 0xd0, 0xb0, 0xd1, 0x86, 0xd0, 0xb8, 0xd1, 0x8e, 0xd1, 0x82, + 0xd0, 0xb5, 0xd1, 0x80, 0xd1, 0x80, 0xd0, 0xb8, 0xd1, 0x82, 0xd0, 0xbe, 0xd1, + 0x80, 0xd0, 0xb8, 0xd0, 0xb8, 0xd0, 0xb4, 0xd0, 0xbe, 0xd1, 0x81, 0xd1, 0x82, + 0xd0, 0xb0, 0xd1, 0x82, 0xd0, 0xbe, 0xd1, 0x87, 0xd0, 0xbd, 0xd0, 0xbe, 0xd8, + 0xa7, 0xd9, 0x84, 0xd9, 0x85, 0xd8, 0xaa, 0xd9, 0x88, 0xd8, 0xa7, 0xd8, 0xac, + 0xd8, 0xaf, 0xd9, 0x88, 0xd9, 0x86, 0xd8, 0xa7, 0xd9, 0x84, 0xd8, 0xa7, 0xd8, + 0xb4, 0xd8, 0xaa, 0xd8, 0xb1, 0xd8, 0xa7, 0xd9, 0x83, 0xd8, 0xa7, 0xd8, 0xaa, + 0xd8, 0xa7, 0xd9, 0x84, 0xd8, 0xa7, 0xd9, 0x82, 0xd8, 0xaa, 0xd8, 0xb1, 0xd8, + 0xa7, 0xd8, 0xad, 0xd8, 0xa7, 0xd8, 0xaa, 0x68, 0x74, 0x6d, 0x6c, 0x3b, 0x20, + 0x63, 0x68, 0x61, 0x72, 0x73, 0x65, 0x74, 0x3d, 0x55, 0x54, 0x46, 0x2d, 0x38, + 0x22, 0x20, 0x73, 0x65, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x28, + 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x29, 0x64, 0x69, 0x73, + 0x70, 0x6c, 0x61, 0x79, 0x3a, 0x69, 0x6e, 0x6c, 0x69, 0x6e, 0x65, 0x2d, 0x62, + 0x6c, 0x6f, 0x63, 0x6b, 0x3b, 0x3c, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x20, 0x74, + 0x79, 0x70, 0x65, 0x3d, 0x22, 0x73, 0x75, 0x62, 0x6d, 0x69, 0x74, 0x22, 0x20, + 0x74, 0x79, 0x70, 0x65, 0x20, 0x3d, 0x20, 0x27, 0x74, 0x65, 0x78, 0x74, 0x2f, + 0x6a, 0x61, 0x76, 0x61, 0x73, 0x63, 0x72, 0x69, 0x3c, 0x69, 0x6d, 0x67, 0x20, + 0x73, 0x72, 0x63, 0x3d, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, + 0x77, 0x77, 0x2e, 0x22, 0x20, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, + 0x77, 0x77, 0x77, 0x2e, 0x77, 0x33, 0x2e, 0x6f, 0x72, 0x67, 0x2f, 0x73, 0x68, + 0x6f, 0x72, 0x74, 0x63, 0x75, 0x74, 0x20, 0x69, 0x63, 0x6f, 0x6e, 0x22, 0x20, + 0x68, 0x72, 0x65, 0x66, 0x3d, 0x22, 0x22, 0x20, 0x61, 0x75, 0x74, 0x6f, 0x63, + 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x3d, 0x22, 0x6f, 0x66, 0x66, 0x22, + 0x20, 0x3c, 0x2f, 0x61, 0x3e, 0x3c, 0x2f, 0x64, 0x69, 0x76, 0x3e, 0x3c, 0x64, + 0x69, 0x76, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x3c, 0x2f, 0x61, 0x3e, + 0x3c, 0x2f, 0x6c, 0x69, 0x3e, 0x0a, 0x3c, 0x6c, 0x69, 0x20, 0x63, 0x6c, 0x61, + 0x73, 0x73, 0x3d, 0x22, 0x63, 0x73, 0x73, 0x22, 0x20, 0x74, 0x79, 0x70, 0x65, + 0x3d, 0x22, 0x74, 0x65, 0x78, 0x74, 0x2f, 0x63, 0x73, 0x73, 0x22, 0x20, 0x3c, + 0x66, 0x6f, 0x72, 0x6d, 0x20, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x3d, 0x22, + 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x78, 0x74, 0x2f, 0x63, 0x73, 0x73, + 0x22, 0x20, 0x68, 0x72, 0x65, 0x66, 0x3d, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, + 0x2f, 0x2f, 0x6c, 0x69, 0x6e, 0x6b, 0x20, 0x72, 0x65, 0x6c, 0x3d, 0x22, 0x61, + 0x6c, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x74, 0x65, 0x22, 0x20, 0x0d, 0x0a, 0x3c, + 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x20, 0x74, 0x79, 0x70, 0x65, 0x3d, 0x22, + 0x74, 0x65, 0x78, 0x74, 0x2f, 0x20, 0x6f, 0x6e, 0x63, 0x6c, 0x69, 0x63, 0x6b, + 0x3d, 0x22, 0x6a, 0x61, 0x76, 0x61, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x3a, + 0x28, 0x6e, 0x65, 0x77, 0x20, 0x44, 0x61, 0x74, 0x65, 0x29, 0x2e, 0x67, 0x65, + 0x74, 0x54, 0x69, 0x6d, 0x65, 0x28, 0x29, 0x7d, 0x68, 0x65, 0x69, 0x67, 0x68, + 0x74, 0x3d, 0x22, 0x31, 0x22, 0x20, 0x77, 0x69, 0x64, 0x74, 0x68, 0x3d, 0x22, + 0x31, 0x22, 0x20, 0x50, 0x65, 0x6f, 0x70, 0x6c, 0x65, 0x27, 0x73, 0x20, 0x52, + 0x65, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x20, 0x6f, 0x66, 0x20, 0x20, 0x3c, + 0x61, 0x20, 0x68, 0x72, 0x65, 0x66, 0x3d, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, + 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x74, 0x65, 0x78, 0x74, 0x2d, 0x64, 0x65, + 0x63, 0x6f, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x75, 0x6e, 0x64, 0x65, + 0x72, 0x74, 0x68, 0x65, 0x20, 0x62, 0x65, 0x67, 0x69, 0x6e, 0x6e, 0x69, 0x6e, + 0x67, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x3c, 0x2f, 0x64, 0x69, + 0x76, 0x3e, 0x0a, 0x3c, 0x2f, 0x64, 0x69, 0x76, 0x3e, 0x0a, 0x3c, 0x2f, 0x64, + 0x69, 0x76, 0x3e, 0x0a, 0x65, 0x73, 0x74, 0x61, 0x62, 0x6c, 0x69, 0x73, 0x68, + 0x6d, 0x65, 0x6e, 0x74, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x3c, + 0x2f, 0x64, 0x69, 0x76, 0x3e, 0x3c, 0x2f, 0x64, 0x69, 0x76, 0x3e, 0x3c, 0x2f, + 0x64, 0x69, 0x76, 0x3e, 0x3c, 0x2f, 0x64, 0x23, 0x76, 0x69, 0x65, 0x77, 0x70, + 0x6f, 0x72, 0x74, 0x7b, 0x6d, 0x69, 0x6e, 0x2d, 0x68, 0x65, 0x69, 0x67, 0x68, + 0x74, 0x3a, 0x0a, 0x3c, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x20, 0x73, 0x72, + 0x63, 0x3d, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6f, 0x70, 0x74, + 0x69, 0x6f, 0x6e, 0x3e, 0x3c, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x76, + 0x61, 0x6c, 0x75, 0x65, 0x3d, 0x6f, 0x66, 0x74, 0x65, 0x6e, 0x20, 0x72, 0x65, + 0x66, 0x65, 0x72, 0x72, 0x65, 0x64, 0x20, 0x74, 0x6f, 0x20, 0x61, 0x73, 0x20, + 0x2f, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x3e, 0x0a, 0x3c, 0x6f, 0x70, 0x74, + 0x69, 0x6f, 0x6e, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x3c, 0x21, 0x44, 0x4f, 0x43, + 0x54, 0x59, 0x50, 0x45, 0x20, 0x68, 0x74, 0x6d, 0x6c, 0x3e, 0x0a, 0x3c, 0x21, + 0x2d, 0x2d, 0x5b, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x61, 0x6c, 0x20, 0x41, 0x69, 0x72, 0x70, 0x6f, 0x72, 0x74, 0x3e, 0x0a, + 0x3c, 0x61, 0x20, 0x68, 0x72, 0x65, 0x66, 0x3d, 0x22, 0x68, 0x74, 0x74, 0x70, + 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x3c, 0x2f, 0x61, 0x3e, 0x3c, 0x61, 0x20, + 0x68, 0x72, 0x65, 0x66, 0x3d, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, + 0x77, 0xe0, 0xb8, 0xa0, 0xe0, 0xb8, 0xb2, 0xe0, 0xb8, 0xa9, 0xe0, 0xb8, 0xb2, + 0xe0, 0xb9, 0x84, 0xe0, 0xb8, 0x97, 0xe0, 0xb8, 0xa2, 0xe1, 0x83, 0xa5, 0xe1, + 0x83, 0x90, 0xe1, 0x83, 0xa0, 0xe1, 0x83, 0x97, 0xe1, 0x83, 0xa3, 0xe1, 0x83, + 0x9a, 0xe1, 0x83, 0x98, 0xe6, 0xad, 0xa3, 0xe9, 0xab, 0x94, 0xe4, 0xb8, 0xad, + 0xe6, 0x96, 0x87, 0x20, 0x28, 0xe7, 0xb9, 0x81, 0xe9, 0xab, 0x94, 0x29, 0xe0, + 0xa4, 0xa8, 0xe0, 0xa4, 0xbf, 0xe0, 0xa4, 0xb0, 0xe0, 0xa5, 0x8d, 0xe0, 0xa4, + 0xa6, 0xe0, 0xa5, 0x87, 0xe0, 0xa4, 0xb6, 0xe0, 0xa4, 0xa1, 0xe0, 0xa4, 0xbe, + 0xe0, 0xa4, 0x89, 0xe0, 0xa4, 0xa8, 0xe0, 0xa4, 0xb2, 0xe0, 0xa5, 0x8b, 0xe0, + 0xa4, 0xa1, 0xe0, 0xa4, 0x95, 0xe0, 0xa5, 0x8d, 0xe0, 0xa4, 0xb7, 0xe0, 0xa5, + 0x87, 0xe0, 0xa4, 0xa4, 0xe0, 0xa5, 0x8d, 0xe0, 0xa4, 0xb0, 0xe0, 0xa4, 0x9c, + 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, 0xa8, 0xe0, 0xa4, 0x95, 0xe0, 0xa4, 0xbe, 0xe0, + 0xa4, 0xb0, 0xe0, 0xa5, 0x80, 0xe0, 0xa4, 0xb8, 0xe0, 0xa4, 0x82, 0xe0, 0xa4, + 0xac, 0xe0, 0xa4, 0x82, 0xe0, 0xa4, 0xa7, 0xe0, 0xa4, 0xbf, 0xe0, 0xa4, 0xa4, + 0xe0, 0xa4, 0xb8, 0xe0, 0xa5, 0x8d, 0xe0, 0xa4, 0xa5, 0xe0, 0xa4, 0xbe, 0xe0, + 0xa4, 0xaa, 0xe0, 0xa4, 0xa8, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, 0xb8, 0xe0, 0xa5, + 0x8d, 0xe0, 0xa4, 0xb5, 0xe0, 0xa5, 0x80, 0xe0, 0xa4, 0x95, 0xe0, 0xa4, 0xbe, + 0xe0, 0xa4, 0xb0, 0xe0, 0xa4, 0xb8, 0xe0, 0xa4, 0x82, 0xe0, 0xa4, 0xb8, 0xe0, + 0xa5, 0x8d, 0xe0, 0xa4, 0x95, 0xe0, 0xa4, 0xb0, 0xe0, 0xa4, 0xa3, 0xe0, 0xa4, + 0xb8, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, 0xae, 0xe0, 0xa4, 0x97, 0xe0, 0xa5, 0x8d, + 0xe0, 0xa4, 0xb0, 0xe0, 0xa5, 0x80, 0xe0, 0xa4, 0x9a, 0xe0, 0xa4, 0xbf, 0xe0, + 0xa4, 0x9f, 0xe0, 0xa5, 0x8d, 0xe0, 0xa4, 0xa0, 0xe0, 0xa5, 0x8b, 0xe0, 0xa4, + 0x82, 0xe0, 0xa4, 0xb5, 0xe0, 0xa4, 0xbf, 0xe0, 0xa4, 0x9c, 0xe0, 0xa5, 0x8d, + 0xe0, 0xa4, 0x9e, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, 0xa8, 0xe0, 0xa4, 0x85, 0xe0, + 0xa4, 0xae, 0xe0, 0xa5, 0x87, 0xe0, 0xa4, 0xb0, 0xe0, 0xa4, 0xbf, 0xe0, 0xa4, + 0x95, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, 0xb5, 0xe0, 0xa4, 0xbf, 0xe0, 0xa4, 0xad, + 0xe0, 0xa4, 0xbf, 0xe0, 0xa4, 0xa8, 0xe0, 0xa5, 0x8d, 0xe0, 0xa4, 0xa8, 0xe0, + 0xa4, 0x97, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, 0xa1, 0xe0, 0xa4, 0xbf, 0xe0, 0xa4, + 0xaf, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, 0x81, 0xe0, 0xa4, 0x95, 0xe0, 0xa5, 0x8d, + 0xe0, 0xa4, 0xaf, 0xe0, 0xa5, 0x8b, 0xe0, 0xa4, 0x82, 0xe0, 0xa4, 0x95, 0xe0, + 0xa4, 0xbf, 0xe0, 0xa4, 0xb8, 0xe0, 0xa5, 0x81, 0xe0, 0xa4, 0xb0, 0xe0, 0xa4, + 0x95, 0xe0, 0xa5, 0x8d, 0xe0, 0xa4, 0xb7, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, 0xaa, + 0xe0, 0xa4, 0xb9, 0xe0, 0xa5, 0x81, 0xe0, 0xa4, 0x81, 0xe0, 0xa4, 0x9a, 0xe0, + 0xa4, 0xa4, 0xe0, 0xa5, 0x80, 0xe0, 0xa4, 0xaa, 0xe0, 0xa5, 0x8d, 0xe0, 0xa4, + 0xb0, 0xe0, 0xa4, 0xac, 0xe0, 0xa4, 0x82, 0xe0, 0xa4, 0xa7, 0xe0, 0xa4, 0xa8, + 0xe0, 0xa4, 0x9f, 0xe0, 0xa4, 0xbf, 0xe0, 0xa4, 0xaa, 0xe0, 0xa5, 0x8d, 0xe0, + 0xa4, 0xaa, 0xe0, 0xa4, 0xa3, 0xe0, 0xa5, 0x80, 0xe0, 0xa4, 0x95, 0xe0, 0xa5, + 0x8d, 0xe0, 0xa4, 0xb0, 0xe0, 0xa4, 0xbf, 0xe0, 0xa4, 0x95, 0xe0, 0xa5, 0x87, + 0xe0, 0xa4, 0x9f, 0xe0, 0xa4, 0xaa, 0xe0, 0xa5, 0x8d, 0xe0, 0xa4, 0xb0, 0xe0, + 0xa4, 0xbe, 0xe0, 0xa4, 0xb0, 0xe0, 0xa4, 0x82, 0xe0, 0xa4, 0xad, 0xe0, 0xa4, + 0xaa, 0xe0, 0xa5, 0x8d, 0xe0, 0xa4, 0xb0, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, 0xaa, + 0xe0, 0xa5, 0x8d, 0xe0, 0xa4, 0xa4, 0xe0, 0xa4, 0xae, 0xe0, 0xa4, 0xbe, 0xe0, + 0xa4, 0xb2, 0xe0, 0xa4, 0xbf, 0xe0, 0xa4, 0x95, 0xe0, 0xa5, 0x8b, 0xe0, 0xa4, + 0x82, 0xe0, 0xa4, 0xb0, 0xe0, 0xa4, 0xab, 0xe0, 0xa4, 0xbc, 0xe0, 0xa5, 0x8d, + 0xe0, 0xa4, 0xa4, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, 0xb0, 0xe0, 0xa4, 0xa8, 0xe0, + 0xa4, 0xbf, 0xe0, 0xa4, 0xb0, 0xe0, 0xa5, 0x8d, 0xe0, 0xa4, 0xae, 0xe0, 0xa4, + 0xbe, 0xe0, 0xa4, 0xa3, 0xe0, 0xa4, 0xb2, 0xe0, 0xa4, 0xbf, 0xe0, 0xa4, 0xae, + 0xe0, 0xa4, 0xbf, 0xe0, 0xa4, 0x9f, 0xe0, 0xa5, 0x87, 0xe0, 0xa4, 0xa1, 0x64, + 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x20, 0x63, + 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x3d, 0x22, 0x64, 0x6f, 0x63, 0x75, 0x6d, + 0x65, 0x6e, 0x74, 0x2e, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, + 0x70, 0x72, 0x6f, 0x74, 0x2e, 0x67, 0x65, 0x74, 0x45, 0x6c, 0x65, 0x6d, 0x65, + 0x6e, 0x74, 0x73, 0x42, 0x79, 0x54, 0x61, 0x67, 0x4e, 0x61, 0x6d, 0x65, 0x28, + 0x3c, 0x21, 0x44, 0x4f, 0x43, 0x54, 0x59, 0x50, 0x45, 0x20, 0x68, 0x74, 0x6d, + 0x6c, 0x3e, 0x0a, 0x3c, 0x68, 0x74, 0x6d, 0x6c, 0x20, 0x3c, 0x6d, 0x65, 0x74, + 0x61, 0x20, 0x63, 0x68, 0x61, 0x72, 0x73, 0x65, 0x74, 0x3d, 0x22, 0x75, 0x74, + 0x66, 0x2d, 0x38, 0x22, 0x3e, 0x3a, 0x75, 0x72, 0x6c, 0x22, 0x20, 0x63, 0x6f, + 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x3d, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, + 0x2f, 0x2e, 0x63, 0x73, 0x73, 0x22, 0x20, 0x72, 0x65, 0x6c, 0x3d, 0x22, 0x73, + 0x74, 0x79, 0x6c, 0x65, 0x73, 0x68, 0x65, 0x65, 0x74, 0x22, 0x73, 0x74, 0x79, + 0x6c, 0x65, 0x20, 0x74, 0x79, 0x70, 0x65, 0x3d, 0x22, 0x74, 0x65, 0x78, 0x74, + 0x2f, 0x63, 0x73, 0x73, 0x22, 0x3e, 0x74, 0x79, 0x70, 0x65, 0x3d, 0x22, 0x74, + 0x65, 0x78, 0x74, 0x2f, 0x63, 0x73, 0x73, 0x22, 0x20, 0x68, 0x72, 0x65, 0x66, + 0x3d, 0x22, 0x77, 0x33, 0x2e, 0x6f, 0x72, 0x67, 0x2f, 0x31, 0x39, 0x39, 0x39, + 0x2f, 0x78, 0x68, 0x74, 0x6d, 0x6c, 0x22, 0x20, 0x78, 0x6d, 0x6c, 0x74, 0x79, + 0x70, 0x65, 0x3d, 0x22, 0x74, 0x65, 0x78, 0x74, 0x2f, 0x6a, 0x61, 0x76, 0x61, + 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x22, 0x20, 0x6d, 0x65, 0x74, 0x68, 0x6f, + 0x64, 0x3d, 0x22, 0x67, 0x65, 0x74, 0x22, 0x20, 0x61, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x3d, 0x22, 0x6c, 0x69, 0x6e, 0x6b, 0x20, 0x72, 0x65, 0x6c, 0x3d, 0x22, + 0x73, 0x74, 0x79, 0x6c, 0x65, 0x73, 0x68, 0x65, 0x65, 0x74, 0x22, 0x20, 0x20, + 0x3d, 0x20, 0x64, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x67, 0x65, + 0x74, 0x45, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x74, 0x79, 0x70, 0x65, 0x3d, + 0x22, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x2f, 0x78, 0x2d, 0x69, 0x63, 0x6f, 0x6e, + 0x22, 0x20, 0x2f, 0x3e, 0x63, 0x65, 0x6c, 0x6c, 0x70, 0x61, 0x64, 0x64, 0x69, + 0x6e, 0x67, 0x3d, 0x22, 0x30, 0x22, 0x20, 0x63, 0x65, 0x6c, 0x6c, 0x73, 0x70, + 0x2e, 0x63, 0x73, 0x73, 0x22, 0x20, 0x74, 0x79, 0x70, 0x65, 0x3d, 0x22, 0x74, + 0x65, 0x78, 0x74, 0x2f, 0x63, 0x73, 0x73, 0x22, 0x20, 0x3c, 0x2f, 0x61, 0x3e, + 0x3c, 0x2f, 0x6c, 0x69, 0x3e, 0x3c, 0x6c, 0x69, 0x3e, 0x3c, 0x61, 0x20, 0x68, + 0x72, 0x65, 0x66, 0x3d, 0x22, 0x22, 0x20, 0x77, 0x69, 0x64, 0x74, 0x68, 0x3d, + 0x22, 0x31, 0x22, 0x20, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x3d, 0x22, 0x31, + 0x22, 0x22, 0x3e, 0x3c, 0x61, 0x20, 0x68, 0x72, 0x65, 0x66, 0x3d, 0x22, 0x68, + 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x73, 0x74, 0x79, + 0x6c, 0x65, 0x3d, 0x22, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x3a, 0x6e, + 0x6f, 0x6e, 0x65, 0x3b, 0x22, 0x3e, 0x61, 0x6c, 0x74, 0x65, 0x72, 0x6e, 0x61, + 0x74, 0x65, 0x22, 0x20, 0x74, 0x79, 0x70, 0x65, 0x3d, 0x22, 0x61, 0x70, 0x70, + 0x6c, 0x69, 0x2d, 0x2f, 0x2f, 0x57, 0x33, 0x43, 0x2f, 0x2f, 0x44, 0x54, 0x44, + 0x20, 0x58, 0x48, 0x54, 0x4d, 0x4c, 0x20, 0x31, 0x2e, 0x30, 0x20, 0x65, 0x6c, + 0x6c, 0x73, 0x70, 0x61, 0x63, 0x69, 0x6e, 0x67, 0x3d, 0x22, 0x30, 0x22, 0x20, + 0x63, 0x65, 0x6c, 0x6c, 0x70, 0x61, 0x64, 0x20, 0x74, 0x79, 0x70, 0x65, 0x3d, + 0x22, 0x68, 0x69, 0x64, 0x64, 0x65, 0x6e, 0x22, 0x20, 0x76, 0x61, 0x6c, 0x75, + 0x65, 0x3d, 0x22, 0x2f, 0x61, 0x3e, 0x26, 0x6e, 0x62, 0x73, 0x70, 0x3b, 0x3c, + 0x73, 0x70, 0x61, 0x6e, 0x20, 0x72, 0x6f, 0x6c, 0x65, 0x3d, 0x22, 0x73, 0x0a, + 0x3c, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x20, 0x74, 0x79, 0x70, 0x65, 0x3d, 0x22, + 0x68, 0x69, 0x64, 0x64, 0x65, 0x6e, 0x22, 0x20, 0x6c, 0x61, 0x6e, 0x67, 0x75, + 0x61, 0x67, 0x65, 0x3d, 0x22, 0x4a, 0x61, 0x76, 0x61, 0x53, 0x63, 0x72, 0x69, + 0x70, 0x74, 0x22, 0x20, 0x20, 0x64, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, + 0x2e, 0x67, 0x65, 0x74, 0x45, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x42, + 0x67, 0x3d, 0x22, 0x30, 0x22, 0x20, 0x63, 0x65, 0x6c, 0x6c, 0x73, 0x70, 0x61, + 0x63, 0x69, 0x6e, 0x67, 0x3d, 0x22, 0x30, 0x22, 0x20, 0x79, 0x70, 0x65, 0x3d, + 0x22, 0x74, 0x65, 0x78, 0x74, 0x2f, 0x63, 0x73, 0x73, 0x22, 0x20, 0x6d, 0x65, + 0x64, 0x69, 0x61, 0x3d, 0x22, 0x74, 0x79, 0x70, 0x65, 0x3d, 0x27, 0x74, 0x65, + 0x78, 0x74, 0x2f, 0x6a, 0x61, 0x76, 0x61, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, + 0x27, 0x77, 0x69, 0x74, 0x68, 0x20, 0x74, 0x68, 0x65, 0x20, 0x65, 0x78, 0x63, + 0x65, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6f, 0x66, 0x20, 0x79, 0x70, 0x65, + 0x3d, 0x22, 0x74, 0x65, 0x78, 0x74, 0x2f, 0x63, 0x73, 0x73, 0x22, 0x20, 0x72, + 0x65, 0x6c, 0x3d, 0x22, 0x73, 0x74, 0x20, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, + 0x3d, 0x22, 0x31, 0x22, 0x20, 0x77, 0x69, 0x64, 0x74, 0x68, 0x3d, 0x22, 0x31, + 0x22, 0x20, 0x3d, 0x27, 0x2b, 0x65, 0x6e, 0x63, 0x6f, 0x64, 0x65, 0x55, 0x52, + 0x49, 0x43, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x28, 0x3c, 0x6c, + 0x69, 0x6e, 0x6b, 0x20, 0x72, 0x65, 0x6c, 0x3d, 0x22, 0x61, 0x6c, 0x74, 0x65, + 0x72, 0x6e, 0x61, 0x74, 0x65, 0x22, 0x20, 0x0a, 0x62, 0x6f, 0x64, 0x79, 0x2c, + 0x20, 0x74, 0x72, 0x2c, 0x20, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x2c, 0x20, 0x74, + 0x65, 0x78, 0x74, 0x6d, 0x65, 0x74, 0x61, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x3d, + 0x22, 0x72, 0x6f, 0x62, 0x6f, 0x74, 0x73, 0x22, 0x20, 0x63, 0x6f, 0x6e, 0x6d, + 0x65, 0x74, 0x68, 0x6f, 0x64, 0x3d, 0x22, 0x70, 0x6f, 0x73, 0x74, 0x22, 0x20, + 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x3d, 0x22, 0x3e, 0x0a, 0x3c, 0x61, 0x20, + 0x68, 0x72, 0x65, 0x66, 0x3d, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, + 0x77, 0x77, 0x77, 0x2e, 0x63, 0x73, 0x73, 0x22, 0x20, 0x72, 0x65, 0x6c, 0x3d, + 0x22, 0x73, 0x74, 0x79, 0x6c, 0x65, 0x73, 0x68, 0x65, 0x65, 0x74, 0x22, 0x20, + 0x3c, 0x2f, 0x64, 0x69, 0x76, 0x3e, 0x3c, 0x2f, 0x64, 0x69, 0x76, 0x3e, 0x3c, + 0x64, 0x69, 0x76, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x6c, 0x61, 0x6e, 0x67, + 0x75, 0x61, 0x67, 0x65, 0x3d, 0x22, 0x6a, 0x61, 0x76, 0x61, 0x73, 0x63, 0x72, + 0x69, 0x70, 0x74, 0x22, 0x3e, 0x61, 0x72, 0x69, 0x61, 0x2d, 0x68, 0x69, 0x64, + 0x64, 0x65, 0x6e, 0x3d, 0x22, 0x74, 0x72, 0x75, 0x65, 0x22, 0x3e, 0xc2, 0xb7, + 0x3c, 0x72, 0x69, 0x70, 0x74, 0x22, 0x20, 0x74, 0x79, 0x70, 0x65, 0x3d, 0x22, + 0x74, 0x65, 0x78, 0x74, 0x2f, 0x6a, 0x61, 0x76, 0x61, 0x73, 0x6c, 0x3d, 0x30, + 0x3b, 0x7d, 0x29, 0x28, 0x29, 0x3b, 0x0a, 0x28, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x28, 0x29, 0x7b, 0x62, 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, + 0x75, 0x6e, 0x64, 0x2d, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x3a, 0x20, 0x75, 0x72, + 0x6c, 0x28, 0x2f, 0x61, 0x3e, 0x3c, 0x2f, 0x6c, 0x69, 0x3e, 0x3c, 0x6c, 0x69, + 0x3e, 0x3c, 0x61, 0x20, 0x68, 0x72, 0x65, 0x66, 0x3d, 0x22, 0x68, 0x09, 0x09, + 0x3c, 0x6c, 0x69, 0x3e, 0x3c, 0x61, 0x20, 0x68, 0x72, 0x65, 0x66, 0x3d, 0x22, + 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x61, 0x74, 0x6f, 0x72, 0x22, 0x20, + 0x61, 0x72, 0x69, 0x61, 0x2d, 0x68, 0x69, 0x64, 0x64, 0x65, 0x6e, 0x3d, 0x22, + 0x74, 0x72, 0x75, 0x3e, 0x20, 0x3c, 0x61, 0x20, 0x68, 0x72, 0x65, 0x66, 0x3d, + 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x6c, + 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, 0x3d, 0x22, 0x6a, 0x61, 0x76, 0x61, + 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x22, 0x20, 0x2f, 0x6f, 0x70, 0x74, 0x69, + 0x6f, 0x6e, 0x3e, 0x0a, 0x3c, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x76, + 0x61, 0x6c, 0x75, 0x65, 0x2f, 0x64, 0x69, 0x76, 0x3e, 0x3c, 0x2f, 0x64, 0x69, + 0x76, 0x3e, 0x3c, 0x64, 0x69, 0x76, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x3d, + 0x72, 0x61, 0x74, 0x6f, 0x72, 0x22, 0x20, 0x61, 0x72, 0x69, 0x61, 0x2d, 0x68, + 0x69, 0x64, 0x64, 0x65, 0x6e, 0x3d, 0x22, 0x74, 0x72, 0x65, 0x3d, 0x28, 0x6e, + 0x65, 0x77, 0x20, 0x44, 0x61, 0x74, 0x65, 0x29, 0x2e, 0x67, 0x65, 0x74, 0x54, + 0x69, 0x6d, 0x65, 0x28, 0x29, 0x70, 0x6f, 0x72, 0x74, 0x75, 0x67, 0x75, 0xc3, + 0xaa, 0x73, 0x20, 0x28, 0x64, 0x6f, 0x20, 0x42, 0x72, 0x61, 0x73, 0x69, 0x6c, + 0x29, 0xd0, 0xbe, 0xd1, 0x80, 0xd0, 0xb3, 0xd0, 0xb0, 0xd0, 0xbd, 0xd0, 0xb8, + 0xd0, 0xb7, 0xd0, 0xb0, 0xd1, 0x86, 0xd0, 0xb8, 0xd0, 0xb8, 0xd0, 0xb2, 0xd0, + 0xbe, 0xd0, 0xb7, 0xd0, 0xbc, 0xd0, 0xbe, 0xd0, 0xb6, 0xd0, 0xbd, 0xd0, 0xbe, + 0xd1, 0x81, 0xd1, 0x82, 0xd1, 0x8c, 0xd0, 0xbe, 0xd0, 0xb1, 0xd1, 0x80, 0xd0, + 0xb0, 0xd0, 0xb7, 0xd0, 0xbe, 0xd0, 0xb2, 0xd0, 0xb0, 0xd0, 0xbd, 0xd0, 0xb8, + 0xd1, 0x8f, 0xd1, 0x80, 0xd0, 0xb5, 0xd0, 0xb3, 0xd0, 0xb8, 0xd1, 0x81, 0xd1, + 0x82, 0xd1, 0x80, 0xd0, 0xb0, 0xd1, 0x86, 0xd0, 0xb8, 0xd0, 0xb8, 0xd0, 0xb2, + 0xd0, 0xbe, 0xd0, 0xb7, 0xd0, 0xbc, 0xd0, 0xbe, 0xd0, 0xb6, 0xd0, 0xbd, 0xd0, + 0xbe, 0xd1, 0x81, 0xd1, 0x82, 0xd0, 0xb8, 0xd0, 0xbe, 0xd0, 0xb1, 0xd1, 0x8f, + 0xd0, 0xb7, 0xd0, 0xb0, 0xd1, 0x82, 0xd0, 0xb5, 0xd0, 0xbb, 0xd1, 0x8c, 0xd0, + 0xbd, 0xd0, 0xb0, 0x3c, 0x21, 0x44, 0x4f, 0x43, 0x54, 0x59, 0x50, 0x45, 0x20, + 0x68, 0x74, 0x6d, 0x6c, 0x20, 0x50, 0x55, 0x42, 0x4c, 0x49, 0x43, 0x20, 0x22, + 0x6e, 0x74, 0x2d, 0x54, 0x79, 0x70, 0x65, 0x22, 0x20, 0x63, 0x6f, 0x6e, 0x74, + 0x65, 0x6e, 0x74, 0x3d, 0x22, 0x74, 0x65, 0x78, 0x74, 0x2f, 0x3c, 0x6d, 0x65, + 0x74, 0x61, 0x20, 0x68, 0x74, 0x74, 0x70, 0x2d, 0x65, 0x71, 0x75, 0x69, 0x76, + 0x3d, 0x22, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x72, 0x61, 0x6e, 0x73, 0x69, 0x74, + 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x2f, 0x2f, 0x45, 0x4e, 0x22, 0x20, 0x22, 0x68, + 0x74, 0x74, 0x70, 0x3a, 0x3c, 0x68, 0x74, 0x6d, 0x6c, 0x20, 0x78, 0x6d, 0x6c, + 0x6e, 0x73, 0x3d, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, + 0x77, 0x2d, 0x2f, 0x2f, 0x57, 0x33, 0x43, 0x2f, 0x2f, 0x44, 0x54, 0x44, 0x20, + 0x58, 0x48, 0x54, 0x4d, 0x4c, 0x20, 0x31, 0x2e, 0x30, 0x20, 0x54, 0x44, 0x54, + 0x44, 0x2f, 0x78, 0x68, 0x74, 0x6d, 0x6c, 0x31, 0x2d, 0x74, 0x72, 0x61, 0x6e, + 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x2f, 0x2f, 0x77, 0x77, 0x77, + 0x2e, 0x77, 0x33, 0x2e, 0x6f, 0x72, 0x67, 0x2f, 0x54, 0x52, 0x2f, 0x78, 0x68, + 0x74, 0x6d, 0x6c, 0x31, 0x2f, 0x70, 0x65, 0x20, 0x3d, 0x20, 0x27, 0x74, 0x65, + 0x78, 0x74, 0x2f, 0x6a, 0x61, 0x76, 0x61, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, + 0x27, 0x3b, 0x3c, 0x6d, 0x65, 0x74, 0x61, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x3d, + 0x22, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x70, + 0x61, 0x72, 0x65, 0x6e, 0x74, 0x4e, 0x6f, 0x64, 0x65, 0x2e, 0x69, 0x6e, 0x73, + 0x65, 0x72, 0x74, 0x42, 0x65, 0x66, 0x6f, 0x72, 0x65, 0x3c, 0x69, 0x6e, 0x70, + 0x75, 0x74, 0x20, 0x74, 0x79, 0x70, 0x65, 0x3d, 0x22, 0x68, 0x69, 0x64, 0x64, + 0x65, 0x6e, 0x22, 0x20, 0x6e, 0x61, 0x6a, 0x73, 0x22, 0x20, 0x74, 0x79, 0x70, + 0x65, 0x3d, 0x22, 0x74, 0x65, 0x78, 0x74, 0x2f, 0x6a, 0x61, 0x76, 0x61, 0x73, + 0x63, 0x72, 0x69, 0x28, 0x64, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x29, + 0x2e, 0x72, 0x65, 0x61, 0x64, 0x79, 0x28, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, + 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x20, 0x74, 0x79, 0x70, 0x65, 0x3d, 0x22, + 0x74, 0x65, 0x78, 0x74, 0x2f, 0x6a, 0x61, 0x76, 0x61, 0x73, 0x69, 0x6d, 0x61, + 0x67, 0x65, 0x22, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x3d, 0x22, + 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x55, 0x41, 0x2d, 0x43, 0x6f, 0x6d, + 0x70, 0x61, 0x74, 0x69, 0x62, 0x6c, 0x65, 0x22, 0x20, 0x63, 0x6f, 0x6e, 0x74, + 0x65, 0x6e, 0x74, 0x3d, 0x74, 0x6d, 0x6c, 0x3b, 0x20, 0x63, 0x68, 0x61, 0x72, + 0x73, 0x65, 0x74, 0x3d, 0x75, 0x74, 0x66, 0x2d, 0x38, 0x22, 0x20, 0x2f, 0x3e, + 0x0a, 0x6c, 0x69, 0x6e, 0x6b, 0x20, 0x72, 0x65, 0x6c, 0x3d, 0x22, 0x73, 0x68, + 0x6f, 0x72, 0x74, 0x63, 0x75, 0x74, 0x20, 0x69, 0x63, 0x6f, 0x6e, 0x3c, 0x6c, + 0x69, 0x6e, 0x6b, 0x20, 0x72, 0x65, 0x6c, 0x3d, 0x22, 0x73, 0x74, 0x79, 0x6c, + 0x65, 0x73, 0x68, 0x65, 0x65, 0x74, 0x22, 0x20, 0x3c, 0x2f, 0x73, 0x63, 0x72, + 0x69, 0x70, 0x74, 0x3e, 0x0a, 0x3c, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x20, + 0x74, 0x79, 0x70, 0x65, 0x3d, 0x3d, 0x20, 0x64, 0x6f, 0x63, 0x75, 0x6d, 0x65, + 0x6e, 0x74, 0x2e, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x45, 0x6c, 0x65, 0x6d, + 0x65, 0x6e, 0x3c, 0x61, 0x20, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x3d, 0x22, + 0x5f, 0x62, 0x6c, 0x61, 0x6e, 0x6b, 0x22, 0x20, 0x68, 0x72, 0x65, 0x66, 0x3d, + 0x20, 0x64, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x67, 0x65, 0x74, + 0x45, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x42, 0x69, 0x6e, 0x70, 0x75, + 0x74, 0x20, 0x74, 0x79, 0x70, 0x65, 0x3d, 0x22, 0x74, 0x65, 0x78, 0x74, 0x22, + 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x3d, 0x61, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x20, + 0x3d, 0x20, 0x27, 0x74, 0x65, 0x78, 0x74, 0x2f, 0x6a, 0x61, 0x76, 0x61, 0x73, + 0x63, 0x72, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x20, 0x74, 0x79, 0x70, 0x65, 0x3d, + 0x22, 0x68, 0x69, 0x64, 0x64, 0x65, 0x6e, 0x22, 0x20, 0x6e, 0x61, 0x6d, 0x65, + 0x68, 0x74, 0x6d, 0x6c, 0x3b, 0x20, 0x63, 0x68, 0x61, 0x72, 0x73, 0x65, 0x74, + 0x3d, 0x75, 0x74, 0x66, 0x2d, 0x38, 0x22, 0x20, 0x2f, 0x3e, 0x64, 0x74, 0x64, + 0x22, 0x3e, 0x0a, 0x3c, 0x68, 0x74, 0x6d, 0x6c, 0x20, 0x78, 0x6d, 0x6c, 0x6e, + 0x73, 0x3d, 0x22, 0x68, 0x74, 0x74, 0x70, 0x2d, 0x2f, 0x2f, 0x57, 0x33, 0x43, + 0x2f, 0x2f, 0x44, 0x54, 0x44, 0x20, 0x48, 0x54, 0x4d, 0x4c, 0x20, 0x34, 0x2e, + 0x30, 0x31, 0x20, 0x54, 0x65, 0x6e, 0x74, 0x73, 0x42, 0x79, 0x54, 0x61, 0x67, + 0x4e, 0x61, 0x6d, 0x65, 0x28, 0x27, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x27, + 0x29, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x20, 0x74, 0x79, 0x70, 0x65, 0x3d, 0x22, + 0x68, 0x69, 0x64, 0x64, 0x65, 0x6e, 0x22, 0x20, 0x6e, 0x61, 0x6d, 0x3c, 0x73, + 0x63, 0x72, 0x69, 0x70, 0x74, 0x20, 0x74, 0x79, 0x70, 0x65, 0x3d, 0x22, 0x74, + 0x65, 0x78, 0x74, 0x2f, 0x6a, 0x61, 0x76, 0x61, 0x73, 0x22, 0x20, 0x73, 0x74, + 0x79, 0x6c, 0x65, 0x3d, 0x22, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x3a, + 0x6e, 0x6f, 0x6e, 0x65, 0x3b, 0x22, 0x3e, 0x64, 0x6f, 0x63, 0x75, 0x6d, 0x65, + 0x6e, 0x74, 0x2e, 0x67, 0x65, 0x74, 0x45, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, + 0x42, 0x79, 0x49, 0x64, 0x28, 0x3d, 0x64, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, + 0x74, 0x2e, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x45, 0x6c, 0x65, 0x6d, 0x65, + 0x6e, 0x74, 0x28, 0x27, 0x20, 0x74, 0x79, 0x70, 0x65, 0x3d, 0x27, 0x74, 0x65, + 0x78, 0x74, 0x2f, 0x6a, 0x61, 0x76, 0x61, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, + 0x27, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x20, 0x74, 0x79, 0x70, 0x65, 0x3d, 0x22, + 0x74, 0x65, 0x78, 0x74, 0x22, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x3d, 0x22, 0x64, + 0x2e, 0x67, 0x65, 0x74, 0x45, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x42, + 0x79, 0x54, 0x61, 0x67, 0x4e, 0x61, 0x6d, 0x65, 0x28, 0x73, 0x6e, 0x69, 0x63, + 0x61, 0x6c, 0x22, 0x20, 0x68, 0x72, 0x65, 0x66, 0x3d, 0x22, 0x68, 0x74, 0x74, + 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x43, 0x2f, 0x2f, 0x44, 0x54, + 0x44, 0x20, 0x48, 0x54, 0x4d, 0x4c, 0x20, 0x34, 0x2e, 0x30, 0x31, 0x20, 0x54, + 0x72, 0x61, 0x6e, 0x73, 0x69, 0x74, 0x3c, 0x73, 0x74, 0x79, 0x6c, 0x65, 0x20, + 0x74, 0x79, 0x70, 0x65, 0x3d, 0x22, 0x74, 0x65, 0x78, 0x74, 0x2f, 0x63, 0x73, + 0x73, 0x22, 0x3e, 0x0a, 0x0a, 0x3c, 0x73, 0x74, 0x79, 0x6c, 0x65, 0x20, 0x74, + 0x79, 0x70, 0x65, 0x3d, 0x22, 0x74, 0x65, 0x78, 0x74, 0x2f, 0x63, 0x73, 0x73, + 0x22, 0x3e, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x2e, 0x64, 0x74, 0x64, 0x22, 0x3e, + 0x0a, 0x3c, 0x68, 0x74, 0x6d, 0x6c, 0x20, 0x78, 0x6d, 0x6c, 0x6e, 0x73, 0x3d, + 0x68, 0x74, 0x74, 0x70, 0x2d, 0x65, 0x71, 0x75, 0x69, 0x76, 0x3d, 0x22, 0x43, + 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x54, 0x79, 0x70, 0x65, 0x64, 0x69, + 0x6e, 0x67, 0x3d, 0x22, 0x30, 0x22, 0x20, 0x63, 0x65, 0x6c, 0x6c, 0x73, 0x70, + 0x61, 0x63, 0x69, 0x6e, 0x67, 0x3d, 0x22, 0x30, 0x22, 0x68, 0x74, 0x6d, 0x6c, + 0x3b, 0x20, 0x63, 0x68, 0x61, 0x72, 0x73, 0x65, 0x74, 0x3d, 0x75, 0x74, 0x66, + 0x2d, 0x38, 0x22, 0x20, 0x2f, 0x3e, 0x0a, 0x20, 0x73, 0x74, 0x79, 0x6c, 0x65, + 0x3d, 0x22, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x3a, 0x6e, 0x6f, 0x6e, + 0x65, 0x3b, 0x22, 0x3e, 0x3c, 0x3c, 0x6c, 0x69, 0x3e, 0x3c, 0x61, 0x20, 0x68, + 0x72, 0x65, 0x66, 0x3d, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, + 0x77, 0x77, 0x2e, 0x20, 0x74, 0x79, 0x70, 0x65, 0x3d, 0x27, 0x74, 0x65, 0x78, + 0x74, 0x2f, 0x6a, 0x61, 0x76, 0x61, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x27, + 0x3e, 0xd0, 0xb4, 0xd0, 0xb5, 0xd1, 0x8f, 0xd1, 0x82, 0xd0, 0xb5, 0xd0, 0xbb, + 0xd1, 0x8c, 0xd0, 0xbd, 0xd0, 0xbe, 0xd1, 0x81, 0xd1, 0x82, 0xd0, 0xb8, 0xd1, + 0x81, 0xd0, 0xbe, 0xd0, 0xbe, 0xd1, 0x82, 0xd0, 0xb2, 0xd0, 0xb5, 0xd1, 0x82, + 0xd1, 0x81, 0xd1, 0x82, 0xd0, 0xb2, 0xd0, 0xb8, 0xd0, 0xb8, 0xd0, 0xbf, 0xd1, + 0x80, 0xd0, 0xbe, 0xd0, 0xb8, 0xd0, 0xb7, 0xd0, 0xb2, 0xd0, 0xbe, 0xd0, 0xb4, + 0xd1, 0x81, 0xd1, 0x82, 0xd0, 0xb2, 0xd0, 0xb0, 0xd0, 0xb1, 0xd0, 0xb5, 0xd0, + 0xb7, 0xd0, 0xbe, 0xd0, 0xbf, 0xd0, 0xb0, 0xd1, 0x81, 0xd0, 0xbd, 0xd0, 0xbe, + 0xd1, 0x81, 0xd1, 0x82, 0xd0, 0xb8, 0xe0, 0xa4, 0xaa, 0xe0, 0xa5, 0x81, 0xe0, + 0xa4, 0xb8, 0xe0, 0xa5, 0x8d, 0xe0, 0xa4, 0xa4, 0xe0, 0xa4, 0xbf, 0xe0, 0xa4, + 0x95, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, 0x95, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, 0x82, + 0xe0, 0xa4, 0x97, 0xe0, 0xa5, 0x8d, 0xe0, 0xa4, 0xb0, 0xe0, 0xa5, 0x87, 0xe0, + 0xa4, 0xb8, 0xe0, 0xa4, 0x89, 0xe0, 0xa4, 0xa8, 0xe0, 0xa5, 0x8d, 0xe0, 0xa4, + 0xb9, 0xe0, 0xa5, 0x8b, 0xe0, 0xa4, 0x82, 0xe0, 0xa4, 0xa8, 0xe0, 0xa5, 0x87, + 0xe0, 0xa4, 0xb5, 0xe0, 0xa4, 0xbf, 0xe0, 0xa4, 0xa7, 0xe0, 0xa4, 0xbe, 0xe0, + 0xa4, 0xa8, 0xe0, 0xa4, 0xb8, 0xe0, 0xa4, 0xad, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, + 0xab, 0xe0, 0xa4, 0xbf, 0xe0, 0xa4, 0x95, 0xe0, 0xa5, 0x8d, 0xe0, 0xa4, 0xb8, + 0xe0, 0xa4, 0xbf, 0xe0, 0xa4, 0x82, 0xe0, 0xa4, 0x97, 0xe0, 0xa4, 0xb8, 0xe0, + 0xa5, 0x81, 0xe0, 0xa4, 0xb0, 0xe0, 0xa4, 0x95, 0xe0, 0xa5, 0x8d, 0xe0, 0xa4, + 0xb7, 0xe0, 0xa4, 0xbf, 0xe0, 0xa4, 0xa4, 0xe0, 0xa4, 0x95, 0xe0, 0xa5, 0x89, + 0xe0, 0xa4, 0xaa, 0xe0, 0xa5, 0x80, 0xe0, 0xa4, 0xb0, 0xe0, 0xa4, 0xbe, 0xe0, + 0xa4, 0x87, 0xe0, 0xa4, 0x9f, 0xe0, 0xa4, 0xb5, 0xe0, 0xa4, 0xbf, 0xe0, 0xa4, + 0x9c, 0xe0, 0xa5, 0x8d, 0xe0, 0xa4, 0x9e, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, 0xaa, + 0xe0, 0xa4, 0xa8, 0xe0, 0xa4, 0x95, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, 0xb0, 0xe0, + 0xa5, 0x8d, 0xe0, 0xa4, 0xb0, 0xe0, 0xa4, 0xb5, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, + 0x88, 0xe0, 0xa4, 0xb8, 0xe0, 0xa4, 0x95, 0xe0, 0xa5, 0x8d, 0xe0, 0xa4, 0xb0, + 0xe0, 0xa4, 0xbf, 0xe0, 0xa4, 0xaf, 0xe0, 0xa4, 0xa4, 0xe0, 0xa4, 0xbe, +}; + +#if defined(__cplusplus) || defined(c_plusplus) +} /* extern "C" */ +#endif diff --git a/web/server/h2o/libh2o/deps/brotli/dec/dictionary.h b/web/server/h2o/libh2o/deps/brotli/dec/dictionary.h new file mode 100644 index 00000000..ae250c2d --- /dev/null +++ b/web/server/h2o/libh2o/deps/brotli/dec/dictionary.h @@ -0,0 +1,38 @@ +/* Copyright 2013 Google Inc. All Rights Reserved. + + Distributed under MIT license. + See file LICENSE for detail or copy at https://opensource.org/licenses/MIT +*/ + +/* Collection of static dictionary words. */ + +#ifndef BROTLI_DEC_DICTIONARY_H_ +#define BROTLI_DEC_DICTIONARY_H_ + +#include "./types.h" + +#if defined(__cplusplus) || defined(c_plusplus) +extern "C" { +#endif + +extern const uint8_t kBrotliDictionary[122784]; + +static const uint32_t kBrotliDictionaryOffsetsByLength[] = { + 0, 0, 0, 0, 0, 4096, 9216, 21504, 35840, 44032, 53248, 63488, 74752, 87040, + 93696, 100864, 104704, 106752, 108928, 113536, 115968, 118528, 119872, 121280, + 122016 +}; + +static const uint8_t kBrotliDictionarySizeBitsByLength[] = { + 0, 0, 0, 0, 10, 10, 11, 11, 10, 10, 10, 10, 10, + 9, 9, 8, 7, 7, 8, 7, 7, 6, 6, 5, 5, +}; + +static const int kBrotliMinDictionaryWordLength = 4; +static const int kBrotliMaxDictionaryWordLength = 24; + +#if defined(__cplusplus) || defined(c_plusplus) +} /* extern "C" */ +#endif + +#endif /* BROTLI_DEC_DICTIONARY_H_ */ diff --git a/web/server/h2o/libh2o/deps/brotli/dec/huffman.c b/web/server/h2o/libh2o/deps/brotli/dec/huffman.c new file mode 100644 index 00000000..159ac1c7 --- /dev/null +++ b/web/server/h2o/libh2o/deps/brotli/dec/huffman.c @@ -0,0 +1,357 @@ +/* Copyright 2013 Google Inc. All Rights Reserved. + + Distributed under MIT license. + See file LICENSE for detail or copy at https://opensource.org/licenses/MIT +*/ + +/* Utilities for building Huffman decoding tables. */ + +#include "./huffman.h" + +#include /* memcpy, memset */ + +#include "./port.h" +#include "./types.h" + +#if defined(__cplusplus) || defined(c_plusplus) +extern "C" { +#endif + +#define BROTLI_REVERSE_BITS_MAX 8 + +#ifdef BROTLI_RBIT +#define BROTLI_REVERSE_BITS_BASE (32 - BROTLI_REVERSE_BITS_MAX) +#else +#define BROTLI_REVERSE_BITS_BASE 0 +static uint8_t kReverseBits[1 << BROTLI_REVERSE_BITS_MAX] = { + 0x00, 0x80, 0x40, 0xC0, 0x20, 0xA0, 0x60, 0xE0, + 0x10, 0x90, 0x50, 0xD0, 0x30, 0xB0, 0x70, 0xF0, + 0x08, 0x88, 0x48, 0xC8, 0x28, 0xA8, 0x68, 0xE8, + 0x18, 0x98, 0x58, 0xD8, 0x38, 0xB8, 0x78, 0xF8, + 0x04, 0x84, 0x44, 0xC4, 0x24, 0xA4, 0x64, 0xE4, + 0x14, 0x94, 0x54, 0xD4, 0x34, 0xB4, 0x74, 0xF4, + 0x0C, 0x8C, 0x4C, 0xCC, 0x2C, 0xAC, 0x6C, 0xEC, + 0x1C, 0x9C, 0x5C, 0xDC, 0x3C, 0xBC, 0x7C, 0xFC, + 0x02, 0x82, 0x42, 0xC2, 0x22, 0xA2, 0x62, 0xE2, + 0x12, 0x92, 0x52, 0xD2, 0x32, 0xB2, 0x72, 0xF2, + 0x0A, 0x8A, 0x4A, 0xCA, 0x2A, 0xAA, 0x6A, 0xEA, + 0x1A, 0x9A, 0x5A, 0xDA, 0x3A, 0xBA, 0x7A, 0xFA, + 0x06, 0x86, 0x46, 0xC6, 0x26, 0xA6, 0x66, 0xE6, + 0x16, 0x96, 0x56, 0xD6, 0x36, 0xB6, 0x76, 0xF6, + 0x0E, 0x8E, 0x4E, 0xCE, 0x2E, 0xAE, 0x6E, 0xEE, + 0x1E, 0x9E, 0x5E, 0xDE, 0x3E, 0xBE, 0x7E, 0xFE, + 0x01, 0x81, 0x41, 0xC1, 0x21, 0xA1, 0x61, 0xE1, + 0x11, 0x91, 0x51, 0xD1, 0x31, 0xB1, 0x71, 0xF1, + 0x09, 0x89, 0x49, 0xC9, 0x29, 0xA9, 0x69, 0xE9, + 0x19, 0x99, 0x59, 0xD9, 0x39, 0xB9, 0x79, 0xF9, + 0x05, 0x85, 0x45, 0xC5, 0x25, 0xA5, 0x65, 0xE5, + 0x15, 0x95, 0x55, 0xD5, 0x35, 0xB5, 0x75, 0xF5, + 0x0D, 0x8D, 0x4D, 0xCD, 0x2D, 0xAD, 0x6D, 0xED, + 0x1D, 0x9D, 0x5D, 0xDD, 0x3D, 0xBD, 0x7D, 0xFD, + 0x03, 0x83, 0x43, 0xC3, 0x23, 0xA3, 0x63, 0xE3, + 0x13, 0x93, 0x53, 0xD3, 0x33, 0xB3, 0x73, 0xF3, + 0x0B, 0x8B, 0x4B, 0xCB, 0x2B, 0xAB, 0x6B, 0xEB, + 0x1B, 0x9B, 0x5B, 0xDB, 0x3B, 0xBB, 0x7B, 0xFB, + 0x07, 0x87, 0x47, 0xC7, 0x27, 0xA7, 0x67, 0xE7, + 0x17, 0x97, 0x57, 0xD7, 0x37, 0xB7, 0x77, 0xF7, + 0x0F, 0x8F, 0x4F, 0xCF, 0x2F, 0xAF, 0x6F, 0xEF, + 0x1F, 0x9F, 0x5F, 0xDF, 0x3F, 0xBF, 0x7F, 0xFF +}; +#endif /* BROTLI_RBIT */ + +#define BROTLI_REVERSE_BITS_LOWEST \ + (1U << (BROTLI_REVERSE_BITS_MAX - 1 + BROTLI_REVERSE_BITS_BASE)) + +/* Returns reverse(num >> BROTLI_REVERSE_BITS_BASE, BROTLI_REVERSE_BITS_MAX), + where reverse(value, len) is the bit-wise reversal of the len least + significant bits of value. */ +static BROTLI_INLINE uint32_t BrotliReverseBits(uint32_t num) { +#ifdef BROTLI_RBIT + return BROTLI_RBIT(num); +#else + return kReverseBits[num]; +#endif +} + +/* Stores code in table[0], table[step], table[2*step], ..., table[end] */ +/* Assumes that end is an integer multiple of step */ +static BROTLI_INLINE void ReplicateValue(HuffmanCode* table, + int step, int end, + HuffmanCode code) { + do { + end -= step; + table[end] = code; + } while (end > 0); +} + +/* Returns the table width of the next 2nd level table. count is the histogram + of bit lengths for the remaining symbols, len is the code length of the next + processed symbol */ +static BROTLI_INLINE int NextTableBitSize(const uint16_t* const count, + int len, int root_bits) { + int left = 1 << (len - root_bits); + while (len < BROTLI_HUFFMAN_MAX_CODE_LENGTH) { + left -= count[len]; + if (left <= 0) break; + ++len; + left <<= 1; + } + return len - root_bits; +} + + +void BrotliBuildCodeLengthsHuffmanTable(HuffmanCode* table, + const uint8_t* const code_lengths, + uint16_t* count) { + HuffmanCode code; /* current table entry */ + int symbol; /* symbol index in original or sorted table */ + uint32_t key; /* prefix code */ + uint32_t key_step; /* prefix code addend */ + int step; /* step size to replicate values in current table */ + int table_size; /* size of current table */ + int sorted[18]; /* symbols sorted by code length */ + /* offsets in sorted table for each length */ + int offset[BROTLI_HUFFMAN_MAX_CODE_LENGTH_CODE_LENGTH + 1]; + int bits; + int bits_count; + BROTLI_DCHECK(BROTLI_HUFFMAN_MAX_CODE_LENGTH_CODE_LENGTH <= + BROTLI_REVERSE_BITS_MAX); + + /* generate offsets into sorted symbol table by code length */ + symbol = -1; + bits = 1; + BROTLI_REPEAT(BROTLI_HUFFMAN_MAX_CODE_LENGTH_CODE_LENGTH, { + symbol += count[bits]; + offset[bits] = symbol; + bits++; + }); + /* Symbols with code length 0 are placed after all other symbols. */ + offset[0] = 17; + + /* sort symbols by length, by symbol order within each length */ + symbol = 18; + do { + BROTLI_REPEAT(6, { + symbol--; + sorted[offset[code_lengths[symbol]]--] = symbol; + }); + } while (symbol != 0); + + table_size = 1 << BROTLI_HUFFMAN_MAX_CODE_LENGTH_CODE_LENGTH; + + /* Special case: all symbols but one have 0 code length. */ + if (offset[0] == 0) { + code.bits = 0; + code.value = (uint16_t)sorted[0]; + for (key = 0; key < (uint32_t)table_size; ++key) { + table[key] = code; + } + return; + } + + /* fill in table */ + key = 0; + key_step = BROTLI_REVERSE_BITS_LOWEST; + symbol = 0; + bits = 1; + step = 2; + do { + code.bits = (uint8_t)bits; + for (bits_count = count[bits]; bits_count != 0; --bits_count) { + code.value = (uint16_t)sorted[symbol++]; + ReplicateValue(&table[BrotliReverseBits(key)], step, table_size, code); + key += key_step; + } + step <<= 1; + key_step >>= 1; + } while (++bits <= BROTLI_HUFFMAN_MAX_CODE_LENGTH_CODE_LENGTH); +} + +uint32_t BrotliBuildHuffmanTable(HuffmanCode* root_table, + int root_bits, + const uint16_t* const symbol_lists, + uint16_t* count) { + HuffmanCode code; /* current table entry */ + HuffmanCode* table; /* next available space in table */ + int len; /* current code length */ + int symbol; /* symbol index in original or sorted table */ + uint32_t key; /* prefix code */ + uint32_t key_step; /* prefix code addend */ + uint32_t sub_key; /* 2nd level table prefix code */ + uint32_t sub_key_step; /* 2nd level table prefix code addend */ + int step; /* step size to replicate values in current table */ + int table_bits; /* key length of current table */ + int table_size; /* size of current table */ + int total_size; /* sum of root table size and 2nd level table sizes */ + int max_length = -1; + int bits; + int bits_count; + + BROTLI_DCHECK(root_bits <= BROTLI_REVERSE_BITS_MAX); + BROTLI_DCHECK(BROTLI_HUFFMAN_MAX_CODE_LENGTH - root_bits <= + BROTLI_REVERSE_BITS_MAX); + + while (symbol_lists[max_length] == 0xFFFF) max_length--; + max_length += BROTLI_HUFFMAN_MAX_CODE_LENGTH + 1; + + table = root_table; + table_bits = root_bits; + table_size = 1 << table_bits; + total_size = table_size; + + /* fill in root table */ + /* let's reduce the table size to a smaller size if possible, and */ + /* create the repetitions by memcpy if possible in the coming loop */ + if (table_bits > max_length) { + table_bits = max_length; + table_size = 1 << table_bits; + } + key = 0; + key_step = BROTLI_REVERSE_BITS_LOWEST; + bits = 1; + step = 2; + do { + code.bits = (uint8_t)bits; + symbol = bits - (BROTLI_HUFFMAN_MAX_CODE_LENGTH + 1); + for (bits_count = count[bits]; bits_count != 0; --bits_count) { + symbol = symbol_lists[symbol]; + code.value = (uint16_t)symbol; + ReplicateValue(&table[BrotliReverseBits(key)], step, table_size, code); + key += key_step; + } + step <<= 1; + key_step >>= 1; + } while (++bits <= table_bits); + + /* if root_bits != table_bits we only created one fraction of the */ + /* table, and we need to replicate it now. */ + while (total_size != table_size) { + memcpy(&table[table_size], &table[0], + (size_t)table_size * sizeof(table[0])); + table_size <<= 1; + } + + /* fill in 2nd level tables and add pointers to root table */ + key_step = BROTLI_REVERSE_BITS_LOWEST >> (root_bits - 1); + sub_key = (BROTLI_REVERSE_BITS_LOWEST << 1); + sub_key_step = BROTLI_REVERSE_BITS_LOWEST; + for (len = root_bits + 1, step = 2; len <= max_length; ++len) { + symbol = len - (BROTLI_HUFFMAN_MAX_CODE_LENGTH + 1); + for (; count[len] != 0; --count[len]) { + if (sub_key == (BROTLI_REVERSE_BITS_LOWEST << 1U)) { + table += table_size; + table_bits = NextTableBitSize(count, len, root_bits); + table_size = 1 << table_bits; + total_size += table_size; + sub_key = BrotliReverseBits(key); + key += key_step; + root_table[sub_key].bits = (uint8_t)(table_bits + root_bits); + root_table[sub_key].value = + (uint16_t)(((size_t)(table - root_table)) - sub_key); + sub_key = 0; + } + code.bits = (uint8_t)(len - root_bits); + symbol = symbol_lists[symbol]; + code.value = (uint16_t)symbol; + ReplicateValue( + &table[BrotliReverseBits(sub_key)], step, table_size, code); + sub_key += sub_key_step; + } + step <<= 1; + sub_key_step >>= 1; + } + return (uint32_t)total_size; +} + +uint32_t BrotliBuildSimpleHuffmanTable(HuffmanCode* table, + int root_bits, + uint16_t* val, + uint32_t num_symbols) { + uint32_t table_size = 1; + const uint32_t goal_size = 1U << root_bits; + switch (num_symbols) { + case 0: + table[0].bits = 0; + table[0].value = val[0]; + break; + case 1: + table[0].bits = 1; + table[1].bits = 1; + if (val[1] > val[0]) { + table[0].value = val[0]; + table[1].value = val[1]; + } else { + table[0].value = val[1]; + table[1].value = val[0]; + } + table_size = 2; + break; + case 2: + table[0].bits = 1; + table[0].value = val[0]; + table[2].bits = 1; + table[2].value = val[0]; + if (val[2] > val[1]) { + table[1].value = val[1]; + table[3].value = val[2]; + } else { + table[1].value = val[2]; + table[3].value = val[1]; + } + table[1].bits = 2; + table[3].bits = 2; + table_size = 4; + break; + case 3: { + int i, k; + for (i = 0; i < 3; ++i) { + for (k = i + 1; k < 4; ++k) { + if (val[k] < val[i]) { + uint16_t t = val[k]; + val[k] = val[i]; + val[i] = t; + } + } + } + for (i = 0; i < 4; ++i) { + table[i].bits = 2; + } + table[0].value = val[0]; + table[2].value = val[1]; + table[1].value = val[2]; + table[3].value = val[3]; + table_size = 4; + break; + } + case 4: { + int i; + if (val[3] < val[2]) { + uint16_t t = val[3]; + val[3] = val[2]; + val[2] = t; + } + for (i = 0; i < 7; ++i) { + table[i].value = val[0]; + table[i].bits = (uint8_t)(1 + (i & 1)); + } + table[1].value = val[1]; + table[3].value = val[2]; + table[5].value = val[1]; + table[7].value = val[3]; + table[3].bits = 3; + table[7].bits = 3; + table_size = 8; + break; + } + } + while (table_size != goal_size) { + memcpy(&table[table_size], &table[0], + (size_t)table_size * sizeof(table[0])); + table_size <<= 1; + } + return goal_size; +} + +#if defined(__cplusplus) || defined(c_plusplus) +} /* extern "C" */ +#endif diff --git a/web/server/h2o/libh2o/deps/brotli/dec/huffman.h b/web/server/h2o/libh2o/deps/brotli/dec/huffman.h new file mode 100644 index 00000000..7cbec80d --- /dev/null +++ b/web/server/h2o/libh2o/deps/brotli/dec/huffman.h @@ -0,0 +1,73 @@ +/* Copyright 2013 Google Inc. All Rights Reserved. + + Distributed under MIT license. + See file LICENSE for detail or copy at https://opensource.org/licenses/MIT +*/ + +/* Utilities for building Huffman decoding tables. */ + +#ifndef BROTLI_DEC_HUFFMAN_H_ +#define BROTLI_DEC_HUFFMAN_H_ + +#include "./types.h" + +#if defined(__cplusplus) || defined(c_plusplus) +extern "C" { +#endif + +#define BROTLI_HUFFMAN_MAX_CODE_LENGTH 15 + +/* For current format this constant equals to kNumInsertAndCopyCodes */ +#define BROTLI_HUFFMAN_MAX_CODE_LENGTHS_SIZE 704 + +/* Maximum possible Huffman table size for an alphabet size of (index * 32), + * max code length 15 and root table bits 8. */ +static const uint16_t kMaxHuffmanTableSize[] = { + 256, 402, 436, 468, 500, 534, 566, 598, 630, 662, 694, 726, 758, 790, 822, + 854, 886, 920, 952, 984, 1016, 1048, 1080}; +#define BROTLI_HUFFMAN_MAX_SIZE_26 396 +#define BROTLI_HUFFMAN_MAX_SIZE_258 632 +#define BROTLI_HUFFMAN_MAX_SIZE_272 646 + +#define BROTLI_HUFFMAN_MAX_CODE_LENGTH_CODE_LENGTH 5 + +typedef struct { + uint8_t bits; /* number of bits used for this symbol */ + uint16_t value; /* symbol value or table offset */ +} HuffmanCode; + + +/* Builds Huffman lookup table assuming code lengths are in symbol order. */ +void BrotliBuildCodeLengthsHuffmanTable(HuffmanCode* root_table, + const uint8_t* const code_lengths, + uint16_t* count); + +/* Builds Huffman lookup table assuming code lengths are in symbol order. */ +/* Returns size of resulting table. */ +uint32_t BrotliBuildHuffmanTable(HuffmanCode* root_table, + int root_bits, + const uint16_t* const symbol_lists, + uint16_t* count_arg); + +/* Builds a simple Huffman table. The num_symbols parameter is to be */ +/* interpreted as follows: 0 means 1 symbol, 1 means 2 symbols, 2 means 3 */ +/* symbols, 3 means 4 symbols with lengths 2,2,2,2, 4 means 4 symbols with */ +/* lengths 1,2,3,3. */ +uint32_t BrotliBuildSimpleHuffmanTable(HuffmanCode* table, + int root_bits, + uint16_t* symbols, + uint32_t num_symbols); + +/* Contains a collection of Huffman trees with the same alphabet size. */ +typedef struct { + HuffmanCode** htrees; + HuffmanCode* codes; + uint16_t alphabet_size; + uint16_t num_htrees; +} HuffmanTreeGroup; + +#if defined(__cplusplus) || defined(c_plusplus) +} /* extern "C" */ +#endif + +#endif /* BROTLI_DEC_HUFFMAN_H_ */ diff --git a/web/server/h2o/libh2o/deps/brotli/dec/port.h b/web/server/h2o/libh2o/deps/brotli/dec/port.h new file mode 100644 index 00000000..6cbe4985 --- /dev/null +++ b/web/server/h2o/libh2o/deps/brotli/dec/port.h @@ -0,0 +1,224 @@ +/* Copyright 2015 Google Inc. All Rights Reserved. + + Distributed under MIT license. + See file LICENSE for detail or copy at https://opensource.org/licenses/MIT +*/ + +/* Macros for compiler / platform specific features and build options. + + Build options are: + * BROTLI_BUILD_32_BIT disables 64-bit optimizations + * BROTLI_BUILD_64_BIT forces to use 64-bit optimizations + * BROTLI_BUILD_BIG_ENDIAN forces to use big-endian optimizations + * BROTLI_BUILD_ENDIAN_NEUTRAL disables endian-aware optimizations + * BROTLI_BUILD_LITTLE_ENDIAN forces to use little-endian optimizations + * BROTLI_BUILD_MODERN_COMPILER forces to use modern compilers built-ins, + features and attributes + * BROTLI_BUILD_PORTABLE disables dangerous optimizations, like unaligned + read and overlapping memcpy; this reduces decompression speed by 5% + * BROTLI_DEBUG dumps file name and line number when decoder detects stream + or memory error + * BROTLI_DECODE_DEBUG enables asserts and dumps various state information + */ + +#ifndef BROTLI_DEC_PORT_H_ +#define BROTLI_DEC_PORT_H_ + +#include + +/* Compatibility with non-clang compilers. */ +#ifndef __has_builtin +#define __has_builtin(x) 0 +#endif + +#ifndef __has_attribute +#define __has_attribute(x) 0 +#endif + +#ifndef __has_feature +#define __has_feature(x) 0 +#endif + +#if defined(__arm__) || defined(__thumb__) || \ + defined(_M_ARM) || defined(_M_ARMT) +#define BROTLI_TARGET_ARM +#if (defined(__ARM_ARCH) && (__ARM_ARCH >= 7)) || \ + (defined(M_ARM) && (M_ARM >= 7)) +#define BROTLI_TARGET_ARMV7 +#endif /* ARMv7 */ +#if defined(__aarch64__) +#define BROTLI_TARGET_ARMV8 +#endif /* ARMv8 */ +#endif /* ARM */ + +#if defined(__i386) || defined(_M_IX86) +#define BROTLI_TARGET_X86 +#endif + +#if defined(__x86_64__) || defined(_M_X64) +#define BROTLI_TARGET_X64 +#endif + +#if defined(__PPC64__) +#define BROTLI_TARGET_POWERPC64 +#endif + +#if defined(__GNUC__) && defined(__GNUC_MINOR__) +#define BROTLI_GCC_VERSION (__GNUC__ * 100 + __GNUC_MINOR__) +#else +#define BROTLI_GCC_VERSION 0 +#endif + +#if defined(__ICC) +#define BROTLI_ICC_VERSION __ICC +#else +#define BROTLI_ICC_VERSION 0 +#endif + +#if defined(BROTLI_BUILD_MODERN_COMPILER) +#define BROTLI_MODERN_COMPILER 1 +#elif (BROTLI_GCC_VERSION > 300) || (BROTLI_ICC_VERSION >= 1600) +#define BROTLI_MODERN_COMPILER 1 +#else +#define BROTLI_MODERN_COMPILER 0 +#endif + +#ifdef BROTLI_BUILD_PORTABLE +#define BROTLI_ALIGNED_READ 1 +#elif defined(BROTLI_TARGET_X86) || defined(BROTLI_TARGET_X64) || \ + defined(BROTLI_TARGET_ARMV7) || defined(BROTLI_TARGET_ARMV8) +#define BROTLI_ALIGNED_READ 0 /* Allow unaligned access on whitelisted CPUs. */ +#else +#define BROTLI_ALIGNED_READ 1 +#endif + +/* Define "PREDICT_TRUE" and "PREDICT_FALSE" macros for capable compilers. + +To apply compiler hint, enclose the branching condition into macros, like this: + + if (PREDICT_TRUE(zero == 0)) { + // main execution path + } else { + // compiler should place this code outside of main execution path + } + +OR: + + if (PREDICT_FALSE(something_rare_or_unexpected_happens)) { + // compiler should place this code outside of main execution path + } + +*/ +#if BROTLI_MODERN_COMPILER || __has_builtin(__builtin_expect) +#define PREDICT_TRUE(x) (__builtin_expect(!!(x), 1)) +#define PREDICT_FALSE(x) (__builtin_expect(x, 0)) +#else +#define PREDICT_FALSE(x) (x) +#define PREDICT_TRUE(x) (x) +#endif + +/* IS_CONSTANT macros returns true for compile-time constant expressions. */ +#if BROTLI_MODERN_COMPILER || __has_builtin(__builtin_constant_p) +#define IS_CONSTANT(x) __builtin_constant_p(x) +#else +#define IS_CONSTANT(x) 0 +#endif + +#if BROTLI_MODERN_COMPILER || __has_attribute(always_inline) +#define ATTRIBUTE_ALWAYS_INLINE __attribute__ ((always_inline)) +#else +#define ATTRIBUTE_ALWAYS_INLINE +#endif + +#ifndef _MSC_VER +#if defined(__cplusplus) || !defined(__STRICT_ANSI__) || \ + __STDC_VERSION__ >= 199901L +#define BROTLI_INLINE inline ATTRIBUTE_ALWAYS_INLINE +#else +#define BROTLI_INLINE +#endif +#else /* _MSC_VER */ +#define BROTLI_INLINE __forceinline +#endif /* _MSC_VER */ + +#ifdef BROTLI_DECODE_DEBUG +#define BROTLI_DCHECK(x) assert(x) +#else +#define BROTLI_DCHECK(x) +#endif + +#if defined(BROTLI_BUILD_64_BIT) +#define BROTLI_64_BITS 1 +#elif defined(BROTLI_BUILD_32_BIT) +#define BROTLI_64_BITS 0 +#elif defined(BROTLI_TARGET_X64) || defined(BROTLI_TARGET_ARMV8) || \ + defined(BROTLI_TARGET_POWERPC64) +#define BROTLI_64_BITS 1 +#else +#define BROTLI_64_BITS 0 +#endif + +#if defined(BROTLI_BUILD_BIG_ENDIAN) +#define BROTLI_LITTLE_ENDIAN 0 +#define BROTLI_BIG_ENDIAN 1 +#elif defined(BROTLI_BUILD_LITTLE_ENDIAN) +#define BROTLI_LITTLE_ENDIAN 1 +#define BROTLI_BIG_ENDIAN 0 +#elif defined(BROTLI_BUILD_ENDIAN_NEUTRAL) +#define BROTLI_LITTLE_ENDIAN 0 +#define BROTLI_BIG_ENDIAN 0 +#elif defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__) +#define BROTLI_LITTLE_ENDIAN 1 +#define BROTLI_BIG_ENDIAN 0 +#elif defined(_WIN32) +/* Win32 can currently always be assumed to be little endian */ +#define BROTLI_LITTLE_ENDIAN 1 +#define BROTLI_BIG_ENDIAN 0 +#else +#if (defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)) +#define BROTLI_BIG_ENDIAN 1 +#else +#define BROTLI_BIG_ENDIAN 0 +#endif +#define BROTLI_LITTLE_ENDIAN 0 +#endif + +#if BROTLI_MODERN_COMPILER || __has_attribute(noinline) +#define BROTLI_NOINLINE __attribute__((noinline)) +#else +#define BROTLI_NOINLINE +#endif + +#define BROTLI_REPEAT(N, X) { \ + if ((N & 1) != 0) {X;} \ + if ((N & 2) != 0) {X; X;} \ + if ((N & 4) != 0) {X; X; X; X;} \ +} + +#if BROTLI_MODERN_COMPILER || defined(__llvm__) +#if defined(BROTLI_TARGET_ARMV7) +static BROTLI_INLINE unsigned BrotliRBit(unsigned input) { + unsigned output; + __asm__("rbit %0, %1\n" : "=r"(output) : "r"(input)); + return output; +} +#define BROTLI_RBIT(x) BrotliRBit(x) +#endif /* armv7 */ +#endif /* gcc || clang */ + +#if defined(BROTLI_TARGET_ARM) +#define BROTLI_HAS_UBFX 1 +#else +#define BROTLI_HAS_UBFX 0 +#endif + +#define BROTLI_ALLOC(S, L) S->alloc_func(S->memory_manager_opaque, L) + +#define BROTLI_FREE(S, X) { \ + S->free_func(S->memory_manager_opaque, X); \ + X = NULL; \ +} + +#define BROTLI_UNUSED(X) (void)(X) + +#endif /* BROTLI_DEC_PORT_H_ */ diff --git a/web/server/h2o/libh2o/deps/brotli/dec/prefix.h b/web/server/h2o/libh2o/deps/brotli/dec/prefix.h new file mode 100644 index 00000000..eaae37f0 --- /dev/null +++ b/web/server/h2o/libh2o/deps/brotli/dec/prefix.h @@ -0,0 +1,749 @@ +/* Copyright 2013 Google Inc. All Rights Reserved. + + Distributed under MIT license. + See file LICENSE for detail or copy at https://opensource.org/licenses/MIT +*/ + +/* Lookup tables to map prefix codes to value ranges. This is used during + decoding of the block lengths, literal insertion lengths and copy lengths. +*/ + +#ifndef BROTLI_DEC_PREFIX_H_ +#define BROTLI_DEC_PREFIX_H_ + +#include "./types.h" + +/* Represents the range of values belonging to a prefix code: */ +/* [offset, offset + 2^nbits) */ +struct PrefixCodeRange { + uint16_t offset; + uint8_t nbits; +}; + +static const struct PrefixCodeRange kBlockLengthPrefixCode[] = { + { 1, 2}, { 5, 2}, { 9, 2}, { 13, 2}, + { 17, 3}, { 25, 3}, { 33, 3}, { 41, 3}, + { 49, 4}, { 65, 4}, { 81, 4}, { 97, 4}, + { 113, 5}, { 145, 5}, { 177, 5}, { 209, 5}, + { 241, 6}, { 305, 6}, { 369, 7}, { 497, 8}, + { 753, 9}, { 1265, 10}, {2289, 11}, {4337, 12}, + {8433, 13}, {16625, 24} +}; + +typedef struct CmdLutElement { + uint8_t insert_len_extra_bits; + uint8_t copy_len_extra_bits; + int8_t distance_code; + uint8_t context; + uint16_t insert_len_offset; + uint16_t copy_len_offset; +} CmdLutElement; + +static const CmdLutElement kCmdLut[704] = { + { 0x00, 0x00, 0, 0x00, 0x0000, 0x0002 }, + { 0x00, 0x00, 0, 0x01, 0x0000, 0x0003 }, + { 0x00, 0x00, 0, 0x02, 0x0000, 0x0004 }, + { 0x00, 0x00, 0, 0x03, 0x0000, 0x0005 }, + { 0x00, 0x00, 0, 0x03, 0x0000, 0x0006 }, + { 0x00, 0x00, 0, 0x03, 0x0000, 0x0007 }, + { 0x00, 0x00, 0, 0x03, 0x0000, 0x0008 }, + { 0x00, 0x00, 0, 0x03, 0x0000, 0x0009 }, + { 0x00, 0x00, 0, 0x00, 0x0001, 0x0002 }, + { 0x00, 0x00, 0, 0x01, 0x0001, 0x0003 }, + { 0x00, 0x00, 0, 0x02, 0x0001, 0x0004 }, + { 0x00, 0x00, 0, 0x03, 0x0001, 0x0005 }, + { 0x00, 0x00, 0, 0x03, 0x0001, 0x0006 }, + { 0x00, 0x00, 0, 0x03, 0x0001, 0x0007 }, + { 0x00, 0x00, 0, 0x03, 0x0001, 0x0008 }, + { 0x00, 0x00, 0, 0x03, 0x0001, 0x0009 }, + { 0x00, 0x00, 0, 0x00, 0x0002, 0x0002 }, + { 0x00, 0x00, 0, 0x01, 0x0002, 0x0003 }, + { 0x00, 0x00, 0, 0x02, 0x0002, 0x0004 }, + { 0x00, 0x00, 0, 0x03, 0x0002, 0x0005 }, + { 0x00, 0x00, 0, 0x03, 0x0002, 0x0006 }, + { 0x00, 0x00, 0, 0x03, 0x0002, 0x0007 }, + { 0x00, 0x00, 0, 0x03, 0x0002, 0x0008 }, + { 0x00, 0x00, 0, 0x03, 0x0002, 0x0009 }, + { 0x00, 0x00, 0, 0x00, 0x0003, 0x0002 }, + { 0x00, 0x00, 0, 0x01, 0x0003, 0x0003 }, + { 0x00, 0x00, 0, 0x02, 0x0003, 0x0004 }, + { 0x00, 0x00, 0, 0x03, 0x0003, 0x0005 }, + { 0x00, 0x00, 0, 0x03, 0x0003, 0x0006 }, + { 0x00, 0x00, 0, 0x03, 0x0003, 0x0007 }, + { 0x00, 0x00, 0, 0x03, 0x0003, 0x0008 }, + { 0x00, 0x00, 0, 0x03, 0x0003, 0x0009 }, + { 0x00, 0x00, 0, 0x00, 0x0004, 0x0002 }, + { 0x00, 0x00, 0, 0x01, 0x0004, 0x0003 }, + { 0x00, 0x00, 0, 0x02, 0x0004, 0x0004 }, + { 0x00, 0x00, 0, 0x03, 0x0004, 0x0005 }, + { 0x00, 0x00, 0, 0x03, 0x0004, 0x0006 }, + { 0x00, 0x00, 0, 0x03, 0x0004, 0x0007 }, + { 0x00, 0x00, 0, 0x03, 0x0004, 0x0008 }, + { 0x00, 0x00, 0, 0x03, 0x0004, 0x0009 }, + { 0x00, 0x00, 0, 0x00, 0x0005, 0x0002 }, + { 0x00, 0x00, 0, 0x01, 0x0005, 0x0003 }, + { 0x00, 0x00, 0, 0x02, 0x0005, 0x0004 }, + { 0x00, 0x00, 0, 0x03, 0x0005, 0x0005 }, + { 0x00, 0x00, 0, 0x03, 0x0005, 0x0006 }, + { 0x00, 0x00, 0, 0x03, 0x0005, 0x0007 }, + { 0x00, 0x00, 0, 0x03, 0x0005, 0x0008 }, + { 0x00, 0x00, 0, 0x03, 0x0005, 0x0009 }, + { 0x01, 0x00, 0, 0x00, 0x0006, 0x0002 }, + { 0x01, 0x00, 0, 0x01, 0x0006, 0x0003 }, + { 0x01, 0x00, 0, 0x02, 0x0006, 0x0004 }, + { 0x01, 0x00, 0, 0x03, 0x0006, 0x0005 }, + { 0x01, 0x00, 0, 0x03, 0x0006, 0x0006 }, + { 0x01, 0x00, 0, 0x03, 0x0006, 0x0007 }, + { 0x01, 0x00, 0, 0x03, 0x0006, 0x0008 }, + { 0x01, 0x00, 0, 0x03, 0x0006, 0x0009 }, + { 0x01, 0x00, 0, 0x00, 0x0008, 0x0002 }, + { 0x01, 0x00, 0, 0x01, 0x0008, 0x0003 }, + { 0x01, 0x00, 0, 0x02, 0x0008, 0x0004 }, + { 0x01, 0x00, 0, 0x03, 0x0008, 0x0005 }, + { 0x01, 0x00, 0, 0x03, 0x0008, 0x0006 }, + { 0x01, 0x00, 0, 0x03, 0x0008, 0x0007 }, + { 0x01, 0x00, 0, 0x03, 0x0008, 0x0008 }, + { 0x01, 0x00, 0, 0x03, 0x0008, 0x0009 }, + { 0x00, 0x01, 0, 0x03, 0x0000, 0x000a }, + { 0x00, 0x01, 0, 0x03, 0x0000, 0x000c }, + { 0x00, 0x02, 0, 0x03, 0x0000, 0x000e }, + { 0x00, 0x02, 0, 0x03, 0x0000, 0x0012 }, + { 0x00, 0x03, 0, 0x03, 0x0000, 0x0016 }, + { 0x00, 0x03, 0, 0x03, 0x0000, 0x001e }, + { 0x00, 0x04, 0, 0x03, 0x0000, 0x0026 }, + { 0x00, 0x04, 0, 0x03, 0x0000, 0x0036 }, + { 0x00, 0x01, 0, 0x03, 0x0001, 0x000a }, + { 0x00, 0x01, 0, 0x03, 0x0001, 0x000c }, + { 0x00, 0x02, 0, 0x03, 0x0001, 0x000e }, + { 0x00, 0x02, 0, 0x03, 0x0001, 0x0012 }, + { 0x00, 0x03, 0, 0x03, 0x0001, 0x0016 }, + { 0x00, 0x03, 0, 0x03, 0x0001, 0x001e }, + { 0x00, 0x04, 0, 0x03, 0x0001, 0x0026 }, + { 0x00, 0x04, 0, 0x03, 0x0001, 0x0036 }, + { 0x00, 0x01, 0, 0x03, 0x0002, 0x000a }, + { 0x00, 0x01, 0, 0x03, 0x0002, 0x000c }, + { 0x00, 0x02, 0, 0x03, 0x0002, 0x000e }, + { 0x00, 0x02, 0, 0x03, 0x0002, 0x0012 }, + { 0x00, 0x03, 0, 0x03, 0x0002, 0x0016 }, + { 0x00, 0x03, 0, 0x03, 0x0002, 0x001e }, + { 0x00, 0x04, 0, 0x03, 0x0002, 0x0026 }, + { 0x00, 0x04, 0, 0x03, 0x0002, 0x0036 }, + { 0x00, 0x01, 0, 0x03, 0x0003, 0x000a }, + { 0x00, 0x01, 0, 0x03, 0x0003, 0x000c }, + { 0x00, 0x02, 0, 0x03, 0x0003, 0x000e }, + { 0x00, 0x02, 0, 0x03, 0x0003, 0x0012 }, + { 0x00, 0x03, 0, 0x03, 0x0003, 0x0016 }, + { 0x00, 0x03, 0, 0x03, 0x0003, 0x001e }, + { 0x00, 0x04, 0, 0x03, 0x0003, 0x0026 }, + { 0x00, 0x04, 0, 0x03, 0x0003, 0x0036 }, + { 0x00, 0x01, 0, 0x03, 0x0004, 0x000a }, + { 0x00, 0x01, 0, 0x03, 0x0004, 0x000c }, + { 0x00, 0x02, 0, 0x03, 0x0004, 0x000e }, + { 0x00, 0x02, 0, 0x03, 0x0004, 0x0012 }, + { 0x00, 0x03, 0, 0x03, 0x0004, 0x0016 }, + { 0x00, 0x03, 0, 0x03, 0x0004, 0x001e }, + { 0x00, 0x04, 0, 0x03, 0x0004, 0x0026 }, + { 0x00, 0x04, 0, 0x03, 0x0004, 0x0036 }, + { 0x00, 0x01, 0, 0x03, 0x0005, 0x000a }, + { 0x00, 0x01, 0, 0x03, 0x0005, 0x000c }, + { 0x00, 0x02, 0, 0x03, 0x0005, 0x000e }, + { 0x00, 0x02, 0, 0x03, 0x0005, 0x0012 }, + { 0x00, 0x03, 0, 0x03, 0x0005, 0x0016 }, + { 0x00, 0x03, 0, 0x03, 0x0005, 0x001e }, + { 0x00, 0x04, 0, 0x03, 0x0005, 0x0026 }, + { 0x00, 0x04, 0, 0x03, 0x0005, 0x0036 }, + { 0x01, 0x01, 0, 0x03, 0x0006, 0x000a }, + { 0x01, 0x01, 0, 0x03, 0x0006, 0x000c }, + { 0x01, 0x02, 0, 0x03, 0x0006, 0x000e }, + { 0x01, 0x02, 0, 0x03, 0x0006, 0x0012 }, + { 0x01, 0x03, 0, 0x03, 0x0006, 0x0016 }, + { 0x01, 0x03, 0, 0x03, 0x0006, 0x001e }, + { 0x01, 0x04, 0, 0x03, 0x0006, 0x0026 }, + { 0x01, 0x04, 0, 0x03, 0x0006, 0x0036 }, + { 0x01, 0x01, 0, 0x03, 0x0008, 0x000a }, + { 0x01, 0x01, 0, 0x03, 0x0008, 0x000c }, + { 0x01, 0x02, 0, 0x03, 0x0008, 0x000e }, + { 0x01, 0x02, 0, 0x03, 0x0008, 0x0012 }, + { 0x01, 0x03, 0, 0x03, 0x0008, 0x0016 }, + { 0x01, 0x03, 0, 0x03, 0x0008, 0x001e }, + { 0x01, 0x04, 0, 0x03, 0x0008, 0x0026 }, + { 0x01, 0x04, 0, 0x03, 0x0008, 0x0036 }, + { 0x00, 0x00, -1, 0x00, 0x0000, 0x0002 }, + { 0x00, 0x00, -1, 0x01, 0x0000, 0x0003 }, + { 0x00, 0x00, -1, 0x02, 0x0000, 0x0004 }, + { 0x00, 0x00, -1, 0x03, 0x0000, 0x0005 }, + { 0x00, 0x00, -1, 0x03, 0x0000, 0x0006 }, + { 0x00, 0x00, -1, 0x03, 0x0000, 0x0007 }, + { 0x00, 0x00, -1, 0x03, 0x0000, 0x0008 }, + { 0x00, 0x00, -1, 0x03, 0x0000, 0x0009 }, + { 0x00, 0x00, -1, 0x00, 0x0001, 0x0002 }, + { 0x00, 0x00, -1, 0x01, 0x0001, 0x0003 }, + { 0x00, 0x00, -1, 0x02, 0x0001, 0x0004 }, + { 0x00, 0x00, -1, 0x03, 0x0001, 0x0005 }, + { 0x00, 0x00, -1, 0x03, 0x0001, 0x0006 }, + { 0x00, 0x00, -1, 0x03, 0x0001, 0x0007 }, + { 0x00, 0x00, -1, 0x03, 0x0001, 0x0008 }, + { 0x00, 0x00, -1, 0x03, 0x0001, 0x0009 }, + { 0x00, 0x00, -1, 0x00, 0x0002, 0x0002 }, + { 0x00, 0x00, -1, 0x01, 0x0002, 0x0003 }, + { 0x00, 0x00, -1, 0x02, 0x0002, 0x0004 }, + { 0x00, 0x00, -1, 0x03, 0x0002, 0x0005 }, + { 0x00, 0x00, -1, 0x03, 0x0002, 0x0006 }, + { 0x00, 0x00, -1, 0x03, 0x0002, 0x0007 }, + { 0x00, 0x00, -1, 0x03, 0x0002, 0x0008 }, + { 0x00, 0x00, -1, 0x03, 0x0002, 0x0009 }, + { 0x00, 0x00, -1, 0x00, 0x0003, 0x0002 }, + { 0x00, 0x00, -1, 0x01, 0x0003, 0x0003 }, + { 0x00, 0x00, -1, 0x02, 0x0003, 0x0004 }, + { 0x00, 0x00, -1, 0x03, 0x0003, 0x0005 }, + { 0x00, 0x00, -1, 0x03, 0x0003, 0x0006 }, + { 0x00, 0x00, -1, 0x03, 0x0003, 0x0007 }, + { 0x00, 0x00, -1, 0x03, 0x0003, 0x0008 }, + { 0x00, 0x00, -1, 0x03, 0x0003, 0x0009 }, + { 0x00, 0x00, -1, 0x00, 0x0004, 0x0002 }, + { 0x00, 0x00, -1, 0x01, 0x0004, 0x0003 }, + { 0x00, 0x00, -1, 0x02, 0x0004, 0x0004 }, + { 0x00, 0x00, -1, 0x03, 0x0004, 0x0005 }, + { 0x00, 0x00, -1, 0x03, 0x0004, 0x0006 }, + { 0x00, 0x00, -1, 0x03, 0x0004, 0x0007 }, + { 0x00, 0x00, -1, 0x03, 0x0004, 0x0008 }, + { 0x00, 0x00, -1, 0x03, 0x0004, 0x0009 }, + { 0x00, 0x00, -1, 0x00, 0x0005, 0x0002 }, + { 0x00, 0x00, -1, 0x01, 0x0005, 0x0003 }, + { 0x00, 0x00, -1, 0x02, 0x0005, 0x0004 }, + { 0x00, 0x00, -1, 0x03, 0x0005, 0x0005 }, + { 0x00, 0x00, -1, 0x03, 0x0005, 0x0006 }, + { 0x00, 0x00, -1, 0x03, 0x0005, 0x0007 }, + { 0x00, 0x00, -1, 0x03, 0x0005, 0x0008 }, + { 0x00, 0x00, -1, 0x03, 0x0005, 0x0009 }, + { 0x01, 0x00, -1, 0x00, 0x0006, 0x0002 }, + { 0x01, 0x00, -1, 0x01, 0x0006, 0x0003 }, + { 0x01, 0x00, -1, 0x02, 0x0006, 0x0004 }, + { 0x01, 0x00, -1, 0x03, 0x0006, 0x0005 }, + { 0x01, 0x00, -1, 0x03, 0x0006, 0x0006 }, + { 0x01, 0x00, -1, 0x03, 0x0006, 0x0007 }, + { 0x01, 0x00, -1, 0x03, 0x0006, 0x0008 }, + { 0x01, 0x00, -1, 0x03, 0x0006, 0x0009 }, + { 0x01, 0x00, -1, 0x00, 0x0008, 0x0002 }, + { 0x01, 0x00, -1, 0x01, 0x0008, 0x0003 }, + { 0x01, 0x00, -1, 0x02, 0x0008, 0x0004 }, + { 0x01, 0x00, -1, 0x03, 0x0008, 0x0005 }, + { 0x01, 0x00, -1, 0x03, 0x0008, 0x0006 }, + { 0x01, 0x00, -1, 0x03, 0x0008, 0x0007 }, + { 0x01, 0x00, -1, 0x03, 0x0008, 0x0008 }, + { 0x01, 0x00, -1, 0x03, 0x0008, 0x0009 }, + { 0x00, 0x01, -1, 0x03, 0x0000, 0x000a }, + { 0x00, 0x01, -1, 0x03, 0x0000, 0x000c }, + { 0x00, 0x02, -1, 0x03, 0x0000, 0x000e }, + { 0x00, 0x02, -1, 0x03, 0x0000, 0x0012 }, + { 0x00, 0x03, -1, 0x03, 0x0000, 0x0016 }, + { 0x00, 0x03, -1, 0x03, 0x0000, 0x001e }, + { 0x00, 0x04, -1, 0x03, 0x0000, 0x0026 }, + { 0x00, 0x04, -1, 0x03, 0x0000, 0x0036 }, + { 0x00, 0x01, -1, 0x03, 0x0001, 0x000a }, + { 0x00, 0x01, -1, 0x03, 0x0001, 0x000c }, + { 0x00, 0x02, -1, 0x03, 0x0001, 0x000e }, + { 0x00, 0x02, -1, 0x03, 0x0001, 0x0012 }, + { 0x00, 0x03, -1, 0x03, 0x0001, 0x0016 }, + { 0x00, 0x03, -1, 0x03, 0x0001, 0x001e }, + { 0x00, 0x04, -1, 0x03, 0x0001, 0x0026 }, + { 0x00, 0x04, -1, 0x03, 0x0001, 0x0036 }, + { 0x00, 0x01, -1, 0x03, 0x0002, 0x000a }, + { 0x00, 0x01, -1, 0x03, 0x0002, 0x000c }, + { 0x00, 0x02, -1, 0x03, 0x0002, 0x000e }, + { 0x00, 0x02, -1, 0x03, 0x0002, 0x0012 }, + { 0x00, 0x03, -1, 0x03, 0x0002, 0x0016 }, + { 0x00, 0x03, -1, 0x03, 0x0002, 0x001e }, + { 0x00, 0x04, -1, 0x03, 0x0002, 0x0026 }, + { 0x00, 0x04, -1, 0x03, 0x0002, 0x0036 }, + { 0x00, 0x01, -1, 0x03, 0x0003, 0x000a }, + { 0x00, 0x01, -1, 0x03, 0x0003, 0x000c }, + { 0x00, 0x02, -1, 0x03, 0x0003, 0x000e }, + { 0x00, 0x02, -1, 0x03, 0x0003, 0x0012 }, + { 0x00, 0x03, -1, 0x03, 0x0003, 0x0016 }, + { 0x00, 0x03, -1, 0x03, 0x0003, 0x001e }, + { 0x00, 0x04, -1, 0x03, 0x0003, 0x0026 }, + { 0x00, 0x04, -1, 0x03, 0x0003, 0x0036 }, + { 0x00, 0x01, -1, 0x03, 0x0004, 0x000a }, + { 0x00, 0x01, -1, 0x03, 0x0004, 0x000c }, + { 0x00, 0x02, -1, 0x03, 0x0004, 0x000e }, + { 0x00, 0x02, -1, 0x03, 0x0004, 0x0012 }, + { 0x00, 0x03, -1, 0x03, 0x0004, 0x0016 }, + { 0x00, 0x03, -1, 0x03, 0x0004, 0x001e }, + { 0x00, 0x04, -1, 0x03, 0x0004, 0x0026 }, + { 0x00, 0x04, -1, 0x03, 0x0004, 0x0036 }, + { 0x00, 0x01, -1, 0x03, 0x0005, 0x000a }, + { 0x00, 0x01, -1, 0x03, 0x0005, 0x000c }, + { 0x00, 0x02, -1, 0x03, 0x0005, 0x000e }, + { 0x00, 0x02, -1, 0x03, 0x0005, 0x0012 }, + { 0x00, 0x03, -1, 0x03, 0x0005, 0x0016 }, + { 0x00, 0x03, -1, 0x03, 0x0005, 0x001e }, + { 0x00, 0x04, -1, 0x03, 0x0005, 0x0026 }, + { 0x00, 0x04, -1, 0x03, 0x0005, 0x0036 }, + { 0x01, 0x01, -1, 0x03, 0x0006, 0x000a }, + { 0x01, 0x01, -1, 0x03, 0x0006, 0x000c }, + { 0x01, 0x02, -1, 0x03, 0x0006, 0x000e }, + { 0x01, 0x02, -1, 0x03, 0x0006, 0x0012 }, + { 0x01, 0x03, -1, 0x03, 0x0006, 0x0016 }, + { 0x01, 0x03, -1, 0x03, 0x0006, 0x001e }, + { 0x01, 0x04, -1, 0x03, 0x0006, 0x0026 }, + { 0x01, 0x04, -1, 0x03, 0x0006, 0x0036 }, + { 0x01, 0x01, -1, 0x03, 0x0008, 0x000a }, + { 0x01, 0x01, -1, 0x03, 0x0008, 0x000c }, + { 0x01, 0x02, -1, 0x03, 0x0008, 0x000e }, + { 0x01, 0x02, -1, 0x03, 0x0008, 0x0012 }, + { 0x01, 0x03, -1, 0x03, 0x0008, 0x0016 }, + { 0x01, 0x03, -1, 0x03, 0x0008, 0x001e }, + { 0x01, 0x04, -1, 0x03, 0x0008, 0x0026 }, + { 0x01, 0x04, -1, 0x03, 0x0008, 0x0036 }, + { 0x02, 0x00, -1, 0x00, 0x000a, 0x0002 }, + { 0x02, 0x00, -1, 0x01, 0x000a, 0x0003 }, + { 0x02, 0x00, -1, 0x02, 0x000a, 0x0004 }, + { 0x02, 0x00, -1, 0x03, 0x000a, 0x0005 }, + { 0x02, 0x00, -1, 0x03, 0x000a, 0x0006 }, + { 0x02, 0x00, -1, 0x03, 0x000a, 0x0007 }, + { 0x02, 0x00, -1, 0x03, 0x000a, 0x0008 }, + { 0x02, 0x00, -1, 0x03, 0x000a, 0x0009 }, + { 0x02, 0x00, -1, 0x00, 0x000e, 0x0002 }, + { 0x02, 0x00, -1, 0x01, 0x000e, 0x0003 }, + { 0x02, 0x00, -1, 0x02, 0x000e, 0x0004 }, + { 0x02, 0x00, -1, 0x03, 0x000e, 0x0005 }, + { 0x02, 0x00, -1, 0x03, 0x000e, 0x0006 }, + { 0x02, 0x00, -1, 0x03, 0x000e, 0x0007 }, + { 0x02, 0x00, -1, 0x03, 0x000e, 0x0008 }, + { 0x02, 0x00, -1, 0x03, 0x000e, 0x0009 }, + { 0x03, 0x00, -1, 0x00, 0x0012, 0x0002 }, + { 0x03, 0x00, -1, 0x01, 0x0012, 0x0003 }, + { 0x03, 0x00, -1, 0x02, 0x0012, 0x0004 }, + { 0x03, 0x00, -1, 0x03, 0x0012, 0x0005 }, + { 0x03, 0x00, -1, 0x03, 0x0012, 0x0006 }, + { 0x03, 0x00, -1, 0x03, 0x0012, 0x0007 }, + { 0x03, 0x00, -1, 0x03, 0x0012, 0x0008 }, + { 0x03, 0x00, -1, 0x03, 0x0012, 0x0009 }, + { 0x03, 0x00, -1, 0x00, 0x001a, 0x0002 }, + { 0x03, 0x00, -1, 0x01, 0x001a, 0x0003 }, + { 0x03, 0x00, -1, 0x02, 0x001a, 0x0004 }, + { 0x03, 0x00, -1, 0x03, 0x001a, 0x0005 }, + { 0x03, 0x00, -1, 0x03, 0x001a, 0x0006 }, + { 0x03, 0x00, -1, 0x03, 0x001a, 0x0007 }, + { 0x03, 0x00, -1, 0x03, 0x001a, 0x0008 }, + { 0x03, 0x00, -1, 0x03, 0x001a, 0x0009 }, + { 0x04, 0x00, -1, 0x00, 0x0022, 0x0002 }, + { 0x04, 0x00, -1, 0x01, 0x0022, 0x0003 }, + { 0x04, 0x00, -1, 0x02, 0x0022, 0x0004 }, + { 0x04, 0x00, -1, 0x03, 0x0022, 0x0005 }, + { 0x04, 0x00, -1, 0x03, 0x0022, 0x0006 }, + { 0x04, 0x00, -1, 0x03, 0x0022, 0x0007 }, + { 0x04, 0x00, -1, 0x03, 0x0022, 0x0008 }, + { 0x04, 0x00, -1, 0x03, 0x0022, 0x0009 }, + { 0x04, 0x00, -1, 0x00, 0x0032, 0x0002 }, + { 0x04, 0x00, -1, 0x01, 0x0032, 0x0003 }, + { 0x04, 0x00, -1, 0x02, 0x0032, 0x0004 }, + { 0x04, 0x00, -1, 0x03, 0x0032, 0x0005 }, + { 0x04, 0x00, -1, 0x03, 0x0032, 0x0006 }, + { 0x04, 0x00, -1, 0x03, 0x0032, 0x0007 }, + { 0x04, 0x00, -1, 0x03, 0x0032, 0x0008 }, + { 0x04, 0x00, -1, 0x03, 0x0032, 0x0009 }, + { 0x05, 0x00, -1, 0x00, 0x0042, 0x0002 }, + { 0x05, 0x00, -1, 0x01, 0x0042, 0x0003 }, + { 0x05, 0x00, -1, 0x02, 0x0042, 0x0004 }, + { 0x05, 0x00, -1, 0x03, 0x0042, 0x0005 }, + { 0x05, 0x00, -1, 0x03, 0x0042, 0x0006 }, + { 0x05, 0x00, -1, 0x03, 0x0042, 0x0007 }, + { 0x05, 0x00, -1, 0x03, 0x0042, 0x0008 }, + { 0x05, 0x00, -1, 0x03, 0x0042, 0x0009 }, + { 0x05, 0x00, -1, 0x00, 0x0062, 0x0002 }, + { 0x05, 0x00, -1, 0x01, 0x0062, 0x0003 }, + { 0x05, 0x00, -1, 0x02, 0x0062, 0x0004 }, + { 0x05, 0x00, -1, 0x03, 0x0062, 0x0005 }, + { 0x05, 0x00, -1, 0x03, 0x0062, 0x0006 }, + { 0x05, 0x00, -1, 0x03, 0x0062, 0x0007 }, + { 0x05, 0x00, -1, 0x03, 0x0062, 0x0008 }, + { 0x05, 0x00, -1, 0x03, 0x0062, 0x0009 }, + { 0x02, 0x01, -1, 0x03, 0x000a, 0x000a }, + { 0x02, 0x01, -1, 0x03, 0x000a, 0x000c }, + { 0x02, 0x02, -1, 0x03, 0x000a, 0x000e }, + { 0x02, 0x02, -1, 0x03, 0x000a, 0x0012 }, + { 0x02, 0x03, -1, 0x03, 0x000a, 0x0016 }, + { 0x02, 0x03, -1, 0x03, 0x000a, 0x001e }, + { 0x02, 0x04, -1, 0x03, 0x000a, 0x0026 }, + { 0x02, 0x04, -1, 0x03, 0x000a, 0x0036 }, + { 0x02, 0x01, -1, 0x03, 0x000e, 0x000a }, + { 0x02, 0x01, -1, 0x03, 0x000e, 0x000c }, + { 0x02, 0x02, -1, 0x03, 0x000e, 0x000e }, + { 0x02, 0x02, -1, 0x03, 0x000e, 0x0012 }, + { 0x02, 0x03, -1, 0x03, 0x000e, 0x0016 }, + { 0x02, 0x03, -1, 0x03, 0x000e, 0x001e }, + { 0x02, 0x04, -1, 0x03, 0x000e, 0x0026 }, + { 0x02, 0x04, -1, 0x03, 0x000e, 0x0036 }, + { 0x03, 0x01, -1, 0x03, 0x0012, 0x000a }, + { 0x03, 0x01, -1, 0x03, 0x0012, 0x000c }, + { 0x03, 0x02, -1, 0x03, 0x0012, 0x000e }, + { 0x03, 0x02, -1, 0x03, 0x0012, 0x0012 }, + { 0x03, 0x03, -1, 0x03, 0x0012, 0x0016 }, + { 0x03, 0x03, -1, 0x03, 0x0012, 0x001e }, + { 0x03, 0x04, -1, 0x03, 0x0012, 0x0026 }, + { 0x03, 0x04, -1, 0x03, 0x0012, 0x0036 }, + { 0x03, 0x01, -1, 0x03, 0x001a, 0x000a }, + { 0x03, 0x01, -1, 0x03, 0x001a, 0x000c }, + { 0x03, 0x02, -1, 0x03, 0x001a, 0x000e }, + { 0x03, 0x02, -1, 0x03, 0x001a, 0x0012 }, + { 0x03, 0x03, -1, 0x03, 0x001a, 0x0016 }, + { 0x03, 0x03, -1, 0x03, 0x001a, 0x001e }, + { 0x03, 0x04, -1, 0x03, 0x001a, 0x0026 }, + { 0x03, 0x04, -1, 0x03, 0x001a, 0x0036 }, + { 0x04, 0x01, -1, 0x03, 0x0022, 0x000a }, + { 0x04, 0x01, -1, 0x03, 0x0022, 0x000c }, + { 0x04, 0x02, -1, 0x03, 0x0022, 0x000e }, + { 0x04, 0x02, -1, 0x03, 0x0022, 0x0012 }, + { 0x04, 0x03, -1, 0x03, 0x0022, 0x0016 }, + { 0x04, 0x03, -1, 0x03, 0x0022, 0x001e }, + { 0x04, 0x04, -1, 0x03, 0x0022, 0x0026 }, + { 0x04, 0x04, -1, 0x03, 0x0022, 0x0036 }, + { 0x04, 0x01, -1, 0x03, 0x0032, 0x000a }, + { 0x04, 0x01, -1, 0x03, 0x0032, 0x000c }, + { 0x04, 0x02, -1, 0x03, 0x0032, 0x000e }, + { 0x04, 0x02, -1, 0x03, 0x0032, 0x0012 }, + { 0x04, 0x03, -1, 0x03, 0x0032, 0x0016 }, + { 0x04, 0x03, -1, 0x03, 0x0032, 0x001e }, + { 0x04, 0x04, -1, 0x03, 0x0032, 0x0026 }, + { 0x04, 0x04, -1, 0x03, 0x0032, 0x0036 }, + { 0x05, 0x01, -1, 0x03, 0x0042, 0x000a }, + { 0x05, 0x01, -1, 0x03, 0x0042, 0x000c }, + { 0x05, 0x02, -1, 0x03, 0x0042, 0x000e }, + { 0x05, 0x02, -1, 0x03, 0x0042, 0x0012 }, + { 0x05, 0x03, -1, 0x03, 0x0042, 0x0016 }, + { 0x05, 0x03, -1, 0x03, 0x0042, 0x001e }, + { 0x05, 0x04, -1, 0x03, 0x0042, 0x0026 }, + { 0x05, 0x04, -1, 0x03, 0x0042, 0x0036 }, + { 0x05, 0x01, -1, 0x03, 0x0062, 0x000a }, + { 0x05, 0x01, -1, 0x03, 0x0062, 0x000c }, + { 0x05, 0x02, -1, 0x03, 0x0062, 0x000e }, + { 0x05, 0x02, -1, 0x03, 0x0062, 0x0012 }, + { 0x05, 0x03, -1, 0x03, 0x0062, 0x0016 }, + { 0x05, 0x03, -1, 0x03, 0x0062, 0x001e }, + { 0x05, 0x04, -1, 0x03, 0x0062, 0x0026 }, + { 0x05, 0x04, -1, 0x03, 0x0062, 0x0036 }, + { 0x00, 0x05, -1, 0x03, 0x0000, 0x0046 }, + { 0x00, 0x05, -1, 0x03, 0x0000, 0x0066 }, + { 0x00, 0x06, -1, 0x03, 0x0000, 0x0086 }, + { 0x00, 0x07, -1, 0x03, 0x0000, 0x00c6 }, + { 0x00, 0x08, -1, 0x03, 0x0000, 0x0146 }, + { 0x00, 0x09, -1, 0x03, 0x0000, 0x0246 }, + { 0x00, 0x0a, -1, 0x03, 0x0000, 0x0446 }, + { 0x00, 0x18, -1, 0x03, 0x0000, 0x0846 }, + { 0x00, 0x05, -1, 0x03, 0x0001, 0x0046 }, + { 0x00, 0x05, -1, 0x03, 0x0001, 0x0066 }, + { 0x00, 0x06, -1, 0x03, 0x0001, 0x0086 }, + { 0x00, 0x07, -1, 0x03, 0x0001, 0x00c6 }, + { 0x00, 0x08, -1, 0x03, 0x0001, 0x0146 }, + { 0x00, 0x09, -1, 0x03, 0x0001, 0x0246 }, + { 0x00, 0x0a, -1, 0x03, 0x0001, 0x0446 }, + { 0x00, 0x18, -1, 0x03, 0x0001, 0x0846 }, + { 0x00, 0x05, -1, 0x03, 0x0002, 0x0046 }, + { 0x00, 0x05, -1, 0x03, 0x0002, 0x0066 }, + { 0x00, 0x06, -1, 0x03, 0x0002, 0x0086 }, + { 0x00, 0x07, -1, 0x03, 0x0002, 0x00c6 }, + { 0x00, 0x08, -1, 0x03, 0x0002, 0x0146 }, + { 0x00, 0x09, -1, 0x03, 0x0002, 0x0246 }, + { 0x00, 0x0a, -1, 0x03, 0x0002, 0x0446 }, + { 0x00, 0x18, -1, 0x03, 0x0002, 0x0846 }, + { 0x00, 0x05, -1, 0x03, 0x0003, 0x0046 }, + { 0x00, 0x05, -1, 0x03, 0x0003, 0x0066 }, + { 0x00, 0x06, -1, 0x03, 0x0003, 0x0086 }, + { 0x00, 0x07, -1, 0x03, 0x0003, 0x00c6 }, + { 0x00, 0x08, -1, 0x03, 0x0003, 0x0146 }, + { 0x00, 0x09, -1, 0x03, 0x0003, 0x0246 }, + { 0x00, 0x0a, -1, 0x03, 0x0003, 0x0446 }, + { 0x00, 0x18, -1, 0x03, 0x0003, 0x0846 }, + { 0x00, 0x05, -1, 0x03, 0x0004, 0x0046 }, + { 0x00, 0x05, -1, 0x03, 0x0004, 0x0066 }, + { 0x00, 0x06, -1, 0x03, 0x0004, 0x0086 }, + { 0x00, 0x07, -1, 0x03, 0x0004, 0x00c6 }, + { 0x00, 0x08, -1, 0x03, 0x0004, 0x0146 }, + { 0x00, 0x09, -1, 0x03, 0x0004, 0x0246 }, + { 0x00, 0x0a, -1, 0x03, 0x0004, 0x0446 }, + { 0x00, 0x18, -1, 0x03, 0x0004, 0x0846 }, + { 0x00, 0x05, -1, 0x03, 0x0005, 0x0046 }, + { 0x00, 0x05, -1, 0x03, 0x0005, 0x0066 }, + { 0x00, 0x06, -1, 0x03, 0x0005, 0x0086 }, + { 0x00, 0x07, -1, 0x03, 0x0005, 0x00c6 }, + { 0x00, 0x08, -1, 0x03, 0x0005, 0x0146 }, + { 0x00, 0x09, -1, 0x03, 0x0005, 0x0246 }, + { 0x00, 0x0a, -1, 0x03, 0x0005, 0x0446 }, + { 0x00, 0x18, -1, 0x03, 0x0005, 0x0846 }, + { 0x01, 0x05, -1, 0x03, 0x0006, 0x0046 }, + { 0x01, 0x05, -1, 0x03, 0x0006, 0x0066 }, + { 0x01, 0x06, -1, 0x03, 0x0006, 0x0086 }, + { 0x01, 0x07, -1, 0x03, 0x0006, 0x00c6 }, + { 0x01, 0x08, -1, 0x03, 0x0006, 0x0146 }, + { 0x01, 0x09, -1, 0x03, 0x0006, 0x0246 }, + { 0x01, 0x0a, -1, 0x03, 0x0006, 0x0446 }, + { 0x01, 0x18, -1, 0x03, 0x0006, 0x0846 }, + { 0x01, 0x05, -1, 0x03, 0x0008, 0x0046 }, + { 0x01, 0x05, -1, 0x03, 0x0008, 0x0066 }, + { 0x01, 0x06, -1, 0x03, 0x0008, 0x0086 }, + { 0x01, 0x07, -1, 0x03, 0x0008, 0x00c6 }, + { 0x01, 0x08, -1, 0x03, 0x0008, 0x0146 }, + { 0x01, 0x09, -1, 0x03, 0x0008, 0x0246 }, + { 0x01, 0x0a, -1, 0x03, 0x0008, 0x0446 }, + { 0x01, 0x18, -1, 0x03, 0x0008, 0x0846 }, + { 0x06, 0x00, -1, 0x00, 0x0082, 0x0002 }, + { 0x06, 0x00, -1, 0x01, 0x0082, 0x0003 }, + { 0x06, 0x00, -1, 0x02, 0x0082, 0x0004 }, + { 0x06, 0x00, -1, 0x03, 0x0082, 0x0005 }, + { 0x06, 0x00, -1, 0x03, 0x0082, 0x0006 }, + { 0x06, 0x00, -1, 0x03, 0x0082, 0x0007 }, + { 0x06, 0x00, -1, 0x03, 0x0082, 0x0008 }, + { 0x06, 0x00, -1, 0x03, 0x0082, 0x0009 }, + { 0x07, 0x00, -1, 0x00, 0x00c2, 0x0002 }, + { 0x07, 0x00, -1, 0x01, 0x00c2, 0x0003 }, + { 0x07, 0x00, -1, 0x02, 0x00c2, 0x0004 }, + { 0x07, 0x00, -1, 0x03, 0x00c2, 0x0005 }, + { 0x07, 0x00, -1, 0x03, 0x00c2, 0x0006 }, + { 0x07, 0x00, -1, 0x03, 0x00c2, 0x0007 }, + { 0x07, 0x00, -1, 0x03, 0x00c2, 0x0008 }, + { 0x07, 0x00, -1, 0x03, 0x00c2, 0x0009 }, + { 0x08, 0x00, -1, 0x00, 0x0142, 0x0002 }, + { 0x08, 0x00, -1, 0x01, 0x0142, 0x0003 }, + { 0x08, 0x00, -1, 0x02, 0x0142, 0x0004 }, + { 0x08, 0x00, -1, 0x03, 0x0142, 0x0005 }, + { 0x08, 0x00, -1, 0x03, 0x0142, 0x0006 }, + { 0x08, 0x00, -1, 0x03, 0x0142, 0x0007 }, + { 0x08, 0x00, -1, 0x03, 0x0142, 0x0008 }, + { 0x08, 0x00, -1, 0x03, 0x0142, 0x0009 }, + { 0x09, 0x00, -1, 0x00, 0x0242, 0x0002 }, + { 0x09, 0x00, -1, 0x01, 0x0242, 0x0003 }, + { 0x09, 0x00, -1, 0x02, 0x0242, 0x0004 }, + { 0x09, 0x00, -1, 0x03, 0x0242, 0x0005 }, + { 0x09, 0x00, -1, 0x03, 0x0242, 0x0006 }, + { 0x09, 0x00, -1, 0x03, 0x0242, 0x0007 }, + { 0x09, 0x00, -1, 0x03, 0x0242, 0x0008 }, + { 0x09, 0x00, -1, 0x03, 0x0242, 0x0009 }, + { 0x0a, 0x00, -1, 0x00, 0x0442, 0x0002 }, + { 0x0a, 0x00, -1, 0x01, 0x0442, 0x0003 }, + { 0x0a, 0x00, -1, 0x02, 0x0442, 0x0004 }, + { 0x0a, 0x00, -1, 0x03, 0x0442, 0x0005 }, + { 0x0a, 0x00, -1, 0x03, 0x0442, 0x0006 }, + { 0x0a, 0x00, -1, 0x03, 0x0442, 0x0007 }, + { 0x0a, 0x00, -1, 0x03, 0x0442, 0x0008 }, + { 0x0a, 0x00, -1, 0x03, 0x0442, 0x0009 }, + { 0x0c, 0x00, -1, 0x00, 0x0842, 0x0002 }, + { 0x0c, 0x00, -1, 0x01, 0x0842, 0x0003 }, + { 0x0c, 0x00, -1, 0x02, 0x0842, 0x0004 }, + { 0x0c, 0x00, -1, 0x03, 0x0842, 0x0005 }, + { 0x0c, 0x00, -1, 0x03, 0x0842, 0x0006 }, + { 0x0c, 0x00, -1, 0x03, 0x0842, 0x0007 }, + { 0x0c, 0x00, -1, 0x03, 0x0842, 0x0008 }, + { 0x0c, 0x00, -1, 0x03, 0x0842, 0x0009 }, + { 0x0e, 0x00, -1, 0x00, 0x1842, 0x0002 }, + { 0x0e, 0x00, -1, 0x01, 0x1842, 0x0003 }, + { 0x0e, 0x00, -1, 0x02, 0x1842, 0x0004 }, + { 0x0e, 0x00, -1, 0x03, 0x1842, 0x0005 }, + { 0x0e, 0x00, -1, 0x03, 0x1842, 0x0006 }, + { 0x0e, 0x00, -1, 0x03, 0x1842, 0x0007 }, + { 0x0e, 0x00, -1, 0x03, 0x1842, 0x0008 }, + { 0x0e, 0x00, -1, 0x03, 0x1842, 0x0009 }, + { 0x18, 0x00, -1, 0x00, 0x5842, 0x0002 }, + { 0x18, 0x00, -1, 0x01, 0x5842, 0x0003 }, + { 0x18, 0x00, -1, 0x02, 0x5842, 0x0004 }, + { 0x18, 0x00, -1, 0x03, 0x5842, 0x0005 }, + { 0x18, 0x00, -1, 0x03, 0x5842, 0x0006 }, + { 0x18, 0x00, -1, 0x03, 0x5842, 0x0007 }, + { 0x18, 0x00, -1, 0x03, 0x5842, 0x0008 }, + { 0x18, 0x00, -1, 0x03, 0x5842, 0x0009 }, + { 0x02, 0x05, -1, 0x03, 0x000a, 0x0046 }, + { 0x02, 0x05, -1, 0x03, 0x000a, 0x0066 }, + { 0x02, 0x06, -1, 0x03, 0x000a, 0x0086 }, + { 0x02, 0x07, -1, 0x03, 0x000a, 0x00c6 }, + { 0x02, 0x08, -1, 0x03, 0x000a, 0x0146 }, + { 0x02, 0x09, -1, 0x03, 0x000a, 0x0246 }, + { 0x02, 0x0a, -1, 0x03, 0x000a, 0x0446 }, + { 0x02, 0x18, -1, 0x03, 0x000a, 0x0846 }, + { 0x02, 0x05, -1, 0x03, 0x000e, 0x0046 }, + { 0x02, 0x05, -1, 0x03, 0x000e, 0x0066 }, + { 0x02, 0x06, -1, 0x03, 0x000e, 0x0086 }, + { 0x02, 0x07, -1, 0x03, 0x000e, 0x00c6 }, + { 0x02, 0x08, -1, 0x03, 0x000e, 0x0146 }, + { 0x02, 0x09, -1, 0x03, 0x000e, 0x0246 }, + { 0x02, 0x0a, -1, 0x03, 0x000e, 0x0446 }, + { 0x02, 0x18, -1, 0x03, 0x000e, 0x0846 }, + { 0x03, 0x05, -1, 0x03, 0x0012, 0x0046 }, + { 0x03, 0x05, -1, 0x03, 0x0012, 0x0066 }, + { 0x03, 0x06, -1, 0x03, 0x0012, 0x0086 }, + { 0x03, 0x07, -1, 0x03, 0x0012, 0x00c6 }, + { 0x03, 0x08, -1, 0x03, 0x0012, 0x0146 }, + { 0x03, 0x09, -1, 0x03, 0x0012, 0x0246 }, + { 0x03, 0x0a, -1, 0x03, 0x0012, 0x0446 }, + { 0x03, 0x18, -1, 0x03, 0x0012, 0x0846 }, + { 0x03, 0x05, -1, 0x03, 0x001a, 0x0046 }, + { 0x03, 0x05, -1, 0x03, 0x001a, 0x0066 }, + { 0x03, 0x06, -1, 0x03, 0x001a, 0x0086 }, + { 0x03, 0x07, -1, 0x03, 0x001a, 0x00c6 }, + { 0x03, 0x08, -1, 0x03, 0x001a, 0x0146 }, + { 0x03, 0x09, -1, 0x03, 0x001a, 0x0246 }, + { 0x03, 0x0a, -1, 0x03, 0x001a, 0x0446 }, + { 0x03, 0x18, -1, 0x03, 0x001a, 0x0846 }, + { 0x04, 0x05, -1, 0x03, 0x0022, 0x0046 }, + { 0x04, 0x05, -1, 0x03, 0x0022, 0x0066 }, + { 0x04, 0x06, -1, 0x03, 0x0022, 0x0086 }, + { 0x04, 0x07, -1, 0x03, 0x0022, 0x00c6 }, + { 0x04, 0x08, -1, 0x03, 0x0022, 0x0146 }, + { 0x04, 0x09, -1, 0x03, 0x0022, 0x0246 }, + { 0x04, 0x0a, -1, 0x03, 0x0022, 0x0446 }, + { 0x04, 0x18, -1, 0x03, 0x0022, 0x0846 }, + { 0x04, 0x05, -1, 0x03, 0x0032, 0x0046 }, + { 0x04, 0x05, -1, 0x03, 0x0032, 0x0066 }, + { 0x04, 0x06, -1, 0x03, 0x0032, 0x0086 }, + { 0x04, 0x07, -1, 0x03, 0x0032, 0x00c6 }, + { 0x04, 0x08, -1, 0x03, 0x0032, 0x0146 }, + { 0x04, 0x09, -1, 0x03, 0x0032, 0x0246 }, + { 0x04, 0x0a, -1, 0x03, 0x0032, 0x0446 }, + { 0x04, 0x18, -1, 0x03, 0x0032, 0x0846 }, + { 0x05, 0x05, -1, 0x03, 0x0042, 0x0046 }, + { 0x05, 0x05, -1, 0x03, 0x0042, 0x0066 }, + { 0x05, 0x06, -1, 0x03, 0x0042, 0x0086 }, + { 0x05, 0x07, -1, 0x03, 0x0042, 0x00c6 }, + { 0x05, 0x08, -1, 0x03, 0x0042, 0x0146 }, + { 0x05, 0x09, -1, 0x03, 0x0042, 0x0246 }, + { 0x05, 0x0a, -1, 0x03, 0x0042, 0x0446 }, + { 0x05, 0x18, -1, 0x03, 0x0042, 0x0846 }, + { 0x05, 0x05, -1, 0x03, 0x0062, 0x0046 }, + { 0x05, 0x05, -1, 0x03, 0x0062, 0x0066 }, + { 0x05, 0x06, -1, 0x03, 0x0062, 0x0086 }, + { 0x05, 0x07, -1, 0x03, 0x0062, 0x00c6 }, + { 0x05, 0x08, -1, 0x03, 0x0062, 0x0146 }, + { 0x05, 0x09, -1, 0x03, 0x0062, 0x0246 }, + { 0x05, 0x0a, -1, 0x03, 0x0062, 0x0446 }, + { 0x05, 0x18, -1, 0x03, 0x0062, 0x0846 }, + { 0x06, 0x01, -1, 0x03, 0x0082, 0x000a }, + { 0x06, 0x01, -1, 0x03, 0x0082, 0x000c }, + { 0x06, 0x02, -1, 0x03, 0x0082, 0x000e }, + { 0x06, 0x02, -1, 0x03, 0x0082, 0x0012 }, + { 0x06, 0x03, -1, 0x03, 0x0082, 0x0016 }, + { 0x06, 0x03, -1, 0x03, 0x0082, 0x001e }, + { 0x06, 0x04, -1, 0x03, 0x0082, 0x0026 }, + { 0x06, 0x04, -1, 0x03, 0x0082, 0x0036 }, + { 0x07, 0x01, -1, 0x03, 0x00c2, 0x000a }, + { 0x07, 0x01, -1, 0x03, 0x00c2, 0x000c }, + { 0x07, 0x02, -1, 0x03, 0x00c2, 0x000e }, + { 0x07, 0x02, -1, 0x03, 0x00c2, 0x0012 }, + { 0x07, 0x03, -1, 0x03, 0x00c2, 0x0016 }, + { 0x07, 0x03, -1, 0x03, 0x00c2, 0x001e }, + { 0x07, 0x04, -1, 0x03, 0x00c2, 0x0026 }, + { 0x07, 0x04, -1, 0x03, 0x00c2, 0x0036 }, + { 0x08, 0x01, -1, 0x03, 0x0142, 0x000a }, + { 0x08, 0x01, -1, 0x03, 0x0142, 0x000c }, + { 0x08, 0x02, -1, 0x03, 0x0142, 0x000e }, + { 0x08, 0x02, -1, 0x03, 0x0142, 0x0012 }, + { 0x08, 0x03, -1, 0x03, 0x0142, 0x0016 }, + { 0x08, 0x03, -1, 0x03, 0x0142, 0x001e }, + { 0x08, 0x04, -1, 0x03, 0x0142, 0x0026 }, + { 0x08, 0x04, -1, 0x03, 0x0142, 0x0036 }, + { 0x09, 0x01, -1, 0x03, 0x0242, 0x000a }, + { 0x09, 0x01, -1, 0x03, 0x0242, 0x000c }, + { 0x09, 0x02, -1, 0x03, 0x0242, 0x000e }, + { 0x09, 0x02, -1, 0x03, 0x0242, 0x0012 }, + { 0x09, 0x03, -1, 0x03, 0x0242, 0x0016 }, + { 0x09, 0x03, -1, 0x03, 0x0242, 0x001e }, + { 0x09, 0x04, -1, 0x03, 0x0242, 0x0026 }, + { 0x09, 0x04, -1, 0x03, 0x0242, 0x0036 }, + { 0x0a, 0x01, -1, 0x03, 0x0442, 0x000a }, + { 0x0a, 0x01, -1, 0x03, 0x0442, 0x000c }, + { 0x0a, 0x02, -1, 0x03, 0x0442, 0x000e }, + { 0x0a, 0x02, -1, 0x03, 0x0442, 0x0012 }, + { 0x0a, 0x03, -1, 0x03, 0x0442, 0x0016 }, + { 0x0a, 0x03, -1, 0x03, 0x0442, 0x001e }, + { 0x0a, 0x04, -1, 0x03, 0x0442, 0x0026 }, + { 0x0a, 0x04, -1, 0x03, 0x0442, 0x0036 }, + { 0x0c, 0x01, -1, 0x03, 0x0842, 0x000a }, + { 0x0c, 0x01, -1, 0x03, 0x0842, 0x000c }, + { 0x0c, 0x02, -1, 0x03, 0x0842, 0x000e }, + { 0x0c, 0x02, -1, 0x03, 0x0842, 0x0012 }, + { 0x0c, 0x03, -1, 0x03, 0x0842, 0x0016 }, + { 0x0c, 0x03, -1, 0x03, 0x0842, 0x001e }, + { 0x0c, 0x04, -1, 0x03, 0x0842, 0x0026 }, + { 0x0c, 0x04, -1, 0x03, 0x0842, 0x0036 }, + { 0x0e, 0x01, -1, 0x03, 0x1842, 0x000a }, + { 0x0e, 0x01, -1, 0x03, 0x1842, 0x000c }, + { 0x0e, 0x02, -1, 0x03, 0x1842, 0x000e }, + { 0x0e, 0x02, -1, 0x03, 0x1842, 0x0012 }, + { 0x0e, 0x03, -1, 0x03, 0x1842, 0x0016 }, + { 0x0e, 0x03, -1, 0x03, 0x1842, 0x001e }, + { 0x0e, 0x04, -1, 0x03, 0x1842, 0x0026 }, + { 0x0e, 0x04, -1, 0x03, 0x1842, 0x0036 }, + { 0x18, 0x01, -1, 0x03, 0x5842, 0x000a }, + { 0x18, 0x01, -1, 0x03, 0x5842, 0x000c }, + { 0x18, 0x02, -1, 0x03, 0x5842, 0x000e }, + { 0x18, 0x02, -1, 0x03, 0x5842, 0x0012 }, + { 0x18, 0x03, -1, 0x03, 0x5842, 0x0016 }, + { 0x18, 0x03, -1, 0x03, 0x5842, 0x001e }, + { 0x18, 0x04, -1, 0x03, 0x5842, 0x0026 }, + { 0x18, 0x04, -1, 0x03, 0x5842, 0x0036 }, + { 0x06, 0x05, -1, 0x03, 0x0082, 0x0046 }, + { 0x06, 0x05, -1, 0x03, 0x0082, 0x0066 }, + { 0x06, 0x06, -1, 0x03, 0x0082, 0x0086 }, + { 0x06, 0x07, -1, 0x03, 0x0082, 0x00c6 }, + { 0x06, 0x08, -1, 0x03, 0x0082, 0x0146 }, + { 0x06, 0x09, -1, 0x03, 0x0082, 0x0246 }, + { 0x06, 0x0a, -1, 0x03, 0x0082, 0x0446 }, + { 0x06, 0x18, -1, 0x03, 0x0082, 0x0846 }, + { 0x07, 0x05, -1, 0x03, 0x00c2, 0x0046 }, + { 0x07, 0x05, -1, 0x03, 0x00c2, 0x0066 }, + { 0x07, 0x06, -1, 0x03, 0x00c2, 0x0086 }, + { 0x07, 0x07, -1, 0x03, 0x00c2, 0x00c6 }, + { 0x07, 0x08, -1, 0x03, 0x00c2, 0x0146 }, + { 0x07, 0x09, -1, 0x03, 0x00c2, 0x0246 }, + { 0x07, 0x0a, -1, 0x03, 0x00c2, 0x0446 }, + { 0x07, 0x18, -1, 0x03, 0x00c2, 0x0846 }, + { 0x08, 0x05, -1, 0x03, 0x0142, 0x0046 }, + { 0x08, 0x05, -1, 0x03, 0x0142, 0x0066 }, + { 0x08, 0x06, -1, 0x03, 0x0142, 0x0086 }, + { 0x08, 0x07, -1, 0x03, 0x0142, 0x00c6 }, + { 0x08, 0x08, -1, 0x03, 0x0142, 0x0146 }, + { 0x08, 0x09, -1, 0x03, 0x0142, 0x0246 }, + { 0x08, 0x0a, -1, 0x03, 0x0142, 0x0446 }, + { 0x08, 0x18, -1, 0x03, 0x0142, 0x0846 }, + { 0x09, 0x05, -1, 0x03, 0x0242, 0x0046 }, + { 0x09, 0x05, -1, 0x03, 0x0242, 0x0066 }, + { 0x09, 0x06, -1, 0x03, 0x0242, 0x0086 }, + { 0x09, 0x07, -1, 0x03, 0x0242, 0x00c6 }, + { 0x09, 0x08, -1, 0x03, 0x0242, 0x0146 }, + { 0x09, 0x09, -1, 0x03, 0x0242, 0x0246 }, + { 0x09, 0x0a, -1, 0x03, 0x0242, 0x0446 }, + { 0x09, 0x18, -1, 0x03, 0x0242, 0x0846 }, + { 0x0a, 0x05, -1, 0x03, 0x0442, 0x0046 }, + { 0x0a, 0x05, -1, 0x03, 0x0442, 0x0066 }, + { 0x0a, 0x06, -1, 0x03, 0x0442, 0x0086 }, + { 0x0a, 0x07, -1, 0x03, 0x0442, 0x00c6 }, + { 0x0a, 0x08, -1, 0x03, 0x0442, 0x0146 }, + { 0x0a, 0x09, -1, 0x03, 0x0442, 0x0246 }, + { 0x0a, 0x0a, -1, 0x03, 0x0442, 0x0446 }, + { 0x0a, 0x18, -1, 0x03, 0x0442, 0x0846 }, + { 0x0c, 0x05, -1, 0x03, 0x0842, 0x0046 }, + { 0x0c, 0x05, -1, 0x03, 0x0842, 0x0066 }, + { 0x0c, 0x06, -1, 0x03, 0x0842, 0x0086 }, + { 0x0c, 0x07, -1, 0x03, 0x0842, 0x00c6 }, + { 0x0c, 0x08, -1, 0x03, 0x0842, 0x0146 }, + { 0x0c, 0x09, -1, 0x03, 0x0842, 0x0246 }, + { 0x0c, 0x0a, -1, 0x03, 0x0842, 0x0446 }, + { 0x0c, 0x18, -1, 0x03, 0x0842, 0x0846 }, + { 0x0e, 0x05, -1, 0x03, 0x1842, 0x0046 }, + { 0x0e, 0x05, -1, 0x03, 0x1842, 0x0066 }, + { 0x0e, 0x06, -1, 0x03, 0x1842, 0x0086 }, + { 0x0e, 0x07, -1, 0x03, 0x1842, 0x00c6 }, + { 0x0e, 0x08, -1, 0x03, 0x1842, 0x0146 }, + { 0x0e, 0x09, -1, 0x03, 0x1842, 0x0246 }, + { 0x0e, 0x0a, -1, 0x03, 0x1842, 0x0446 }, + { 0x0e, 0x18, -1, 0x03, 0x1842, 0x0846 }, + { 0x18, 0x05, -1, 0x03, 0x5842, 0x0046 }, + { 0x18, 0x05, -1, 0x03, 0x5842, 0x0066 }, + { 0x18, 0x06, -1, 0x03, 0x5842, 0x0086 }, + { 0x18, 0x07, -1, 0x03, 0x5842, 0x00c6 }, + { 0x18, 0x08, -1, 0x03, 0x5842, 0x0146 }, + { 0x18, 0x09, -1, 0x03, 0x5842, 0x0246 }, + { 0x18, 0x0a, -1, 0x03, 0x5842, 0x0446 }, + { 0x18, 0x18, -1, 0x03, 0x5842, 0x0846 }, +}; + +#endif /* BROTLI_DEC_PREFIX_H_ */ diff --git a/web/server/h2o/libh2o/deps/brotli/dec/state.c b/web/server/h2o/libh2o/deps/brotli/dec/state.c new file mode 100644 index 00000000..52c0e6c8 --- /dev/null +++ b/web/server/h2o/libh2o/deps/brotli/dec/state.c @@ -0,0 +1,178 @@ +/* Copyright 2015 Google Inc. All Rights Reserved. + + Distributed under MIT license. + See file LICENSE for detail or copy at https://opensource.org/licenses/MIT +*/ + +#include "./state.h" + +#include /* free, malloc */ + +#include "./huffman.h" +#include "./types.h" + +#if defined(__cplusplus) || defined(c_plusplus) +extern "C" { +#endif + +static void* DefaultAllocFunc(void* opaque, size_t size) { + BROTLI_UNUSED(opaque); + return malloc(size); +} + +static void DefaultFreeFunc(void* opaque, void* address) { + BROTLI_UNUSED(opaque); + free(address); +} + +void BrotliStateInit(BrotliState* s) { + BrotliStateInitWithCustomAllocators(s, 0, 0, 0); +} + +void BrotliStateInitWithCustomAllocators(BrotliState* s, + brotli_alloc_func alloc_func, brotli_free_func free_func, void* opaque) { + if (!alloc_func) { + s->alloc_func = DefaultAllocFunc; + s->free_func = DefaultFreeFunc; + s->memory_manager_opaque = 0; + } else { + s->alloc_func = alloc_func; + s->free_func = free_func; + s->memory_manager_opaque = opaque; + } + + BrotliInitBitReader(&s->br); + s->state = BROTLI_STATE_UNINITED; + s->substate_metablock_header = BROTLI_STATE_METABLOCK_HEADER_NONE; + s->substate_tree_group = BROTLI_STATE_TREE_GROUP_NONE; + s->substate_context_map = BROTLI_STATE_CONTEXT_MAP_NONE; + s->substate_uncompressed = BROTLI_STATE_UNCOMPRESSED_NONE; + s->substate_huffman = BROTLI_STATE_HUFFMAN_NONE; + s->substate_decode_uint8 = BROTLI_STATE_DECODE_UINT8_NONE; + s->substate_read_block_length = BROTLI_STATE_READ_BLOCK_LENGTH_NONE; + + s->buffer_length = 0; + s->loop_counter = 0; + s->pos = 0; + s->rb_roundtrips = 0; + s->partial_pos_out = 0; + + s->block_type_trees = NULL; + s->block_len_trees = NULL; + s->ringbuffer = NULL; + + s->context_map = NULL; + s->context_modes = NULL; + s->dist_context_map = NULL; + s->context_map_slice = NULL; + s->dist_context_map_slice = NULL; + + s->sub_loop_counter = 0; + + s->literal_hgroup.codes = NULL; + s->literal_hgroup.htrees = NULL; + s->insert_copy_hgroup.codes = NULL; + s->insert_copy_hgroup.htrees = NULL; + s->distance_hgroup.codes = NULL; + s->distance_hgroup.htrees = NULL; + + + s->custom_dict = NULL; + s->custom_dict_size = 0; + + s->is_last_metablock = 0; + s->window_bits = 0; + s->max_distance = 0; + s->dist_rb[0] = 16; + s->dist_rb[1] = 15; + s->dist_rb[2] = 11; + s->dist_rb[3] = 4; + s->dist_rb_idx = 0; + s->block_type_trees = NULL; + s->block_len_trees = NULL; + + /* Make small negative indexes addressable. */ + s->symbol_lists = &s->symbols_lists_array[BROTLI_HUFFMAN_MAX_CODE_LENGTH + 1]; + + s->mtf_upper_bound = 255; +} + +void BrotliStateMetablockBegin(BrotliState* s) { + s->meta_block_remaining_len = 0; + s->block_length[0] = 1U << 28; + s->block_length[1] = 1U << 28; + s->block_length[2] = 1U << 28; + s->num_block_types[0] = 1; + s->num_block_types[1] = 1; + s->num_block_types[2] = 1; + s->block_type_rb[0] = 1; + s->block_type_rb[1] = 0; + s->block_type_rb[2] = 1; + s->block_type_rb[3] = 0; + s->block_type_rb[4] = 1; + s->block_type_rb[5] = 0; + s->context_map = NULL; + s->context_modes = NULL; + s->dist_context_map = NULL; + s->context_map_slice = NULL; + s->literal_htree_index = 0; + s->literal_htree = NULL; + s->dist_context_map_slice = NULL; + s->dist_htree_index = 0; + s->context_lookup1 = NULL; + s->context_lookup2 = NULL; + s->literal_hgroup.codes = NULL; + s->literal_hgroup.htrees = NULL; + s->insert_copy_hgroup.codes = NULL; + s->insert_copy_hgroup.htrees = NULL; + s->distance_hgroup.codes = NULL; + s->distance_hgroup.htrees = NULL; +} + +void BrotliStateCleanupAfterMetablock(BrotliState* s) { + BROTLI_FREE(s, s->context_modes); + BROTLI_FREE(s, s->context_map); + BROTLI_FREE(s, s->dist_context_map); + + BrotliHuffmanTreeGroupRelease(s, &s->literal_hgroup); + BrotliHuffmanTreeGroupRelease(s, &s->insert_copy_hgroup); + BrotliHuffmanTreeGroupRelease(s, &s->distance_hgroup); +} + +void BrotliStateCleanup(BrotliState* s) { + BrotliStateCleanupAfterMetablock(s); + + BROTLI_FREE(s, s->ringbuffer); + BROTLI_FREE(s, s->block_type_trees); +} + +int BrotliStateIsStreamStart(const BrotliState* s) { + return (s->state == BROTLI_STATE_UNINITED && + BrotliGetAvailableBits(&s->br) == 0); +} + +int BrotliStateIsStreamEnd(const BrotliState* s) { + return s->state == BROTLI_STATE_DONE; +} + +void BrotliHuffmanTreeGroupInit(BrotliState* s, HuffmanTreeGroup* group, + uint32_t alphabet_size, uint32_t ntrees) { + /* Pack two allocations into one */ + const size_t max_table_size = kMaxHuffmanTableSize[(alphabet_size + 31) >> 5]; + const size_t code_size = sizeof(HuffmanCode) * ntrees * max_table_size; + const size_t htree_size = sizeof(HuffmanCode*) * ntrees; + char* p = (char*)BROTLI_ALLOC(s, code_size + htree_size); + group->alphabet_size = (uint16_t)alphabet_size; + group->num_htrees = (uint16_t)ntrees; + group->codes = (HuffmanCode*)p; + group->htrees = (HuffmanCode**)(p + code_size); +} + +void BrotliHuffmanTreeGroupRelease(BrotliState* s, HuffmanTreeGroup* group) { + BROTLI_FREE(s, group->codes); + group->htrees = NULL; +} + +#if defined(__cplusplus) || defined(c_plusplus) +} /* extern "C" */ +#endif diff --git a/web/server/h2o/libh2o/deps/brotli/dec/state.h b/web/server/h2o/libh2o/deps/brotli/dec/state.h new file mode 100644 index 00000000..925fa149 --- /dev/null +++ b/web/server/h2o/libh2o/deps/brotli/dec/state.h @@ -0,0 +1,249 @@ +/* Copyright 2015 Google Inc. All Rights Reserved. + + Distributed under MIT license. + See file LICENSE for detail or copy at https://opensource.org/licenses/MIT +*/ + +/* Brotli state for partial streaming decoding. */ + +#ifndef BROTLI_DEC_STATE_H_ +#define BROTLI_DEC_STATE_H_ + +#include "./bit_reader.h" +#include "./huffman.h" +#include "./types.h" + +#if defined(__cplusplus) || defined(c_plusplus) +extern "C" { +#endif + +typedef enum { + BROTLI_STATE_UNINITED, + BROTLI_STATE_METABLOCK_BEGIN, + BROTLI_STATE_METABLOCK_HEADER, + BROTLI_STATE_METABLOCK_HEADER_2, + BROTLI_STATE_CONTEXT_MODES, + BROTLI_STATE_COMMAND_BEGIN, + BROTLI_STATE_COMMAND_INNER, + BROTLI_STATE_COMMAND_POST_DECODE_LITERALS, + BROTLI_STATE_COMMAND_POST_WRAP_COPY, + BROTLI_STATE_UNCOMPRESSED, + BROTLI_STATE_METADATA, + BROTLI_STATE_COMMAND_INNER_WRITE, + BROTLI_STATE_METABLOCK_DONE, + BROTLI_STATE_COMMAND_POST_WRITE_1, + BROTLI_STATE_COMMAND_POST_WRITE_2, + BROTLI_STATE_HUFFMAN_CODE_0, + BROTLI_STATE_HUFFMAN_CODE_1, + BROTLI_STATE_HUFFMAN_CODE_2, + BROTLI_STATE_HUFFMAN_CODE_3, + BROTLI_STATE_CONTEXT_MAP_1, + BROTLI_STATE_CONTEXT_MAP_2, + BROTLI_STATE_TREE_GROUP, + BROTLI_STATE_DONE +} BrotliRunningState; + +typedef enum { + BROTLI_STATE_METABLOCK_HEADER_NONE, + BROTLI_STATE_METABLOCK_HEADER_EMPTY, + BROTLI_STATE_METABLOCK_HEADER_NIBBLES, + BROTLI_STATE_METABLOCK_HEADER_SIZE, + BROTLI_STATE_METABLOCK_HEADER_UNCOMPRESSED, + BROTLI_STATE_METABLOCK_HEADER_RESERVED, + BROTLI_STATE_METABLOCK_HEADER_BYTES, + BROTLI_STATE_METABLOCK_HEADER_METADATA +} BrotliRunningMetablockHeaderState; + +typedef enum { + BROTLI_STATE_UNCOMPRESSED_NONE, + BROTLI_STATE_UNCOMPRESSED_WRITE +} BrotliRunningUncompressedState; + +typedef enum { + BROTLI_STATE_TREE_GROUP_NONE, + BROTLI_STATE_TREE_GROUP_LOOP +} BrotliRunningTreeGroupState; + +typedef enum { + BROTLI_STATE_CONTEXT_MAP_NONE, + BROTLI_STATE_CONTEXT_MAP_READ_PREFIX, + BROTLI_STATE_CONTEXT_MAP_HUFFMAN, + BROTLI_STATE_CONTEXT_MAP_DECODE, + BROTLI_STATE_CONTEXT_MAP_TRANSFORM +} BrotliRunningContextMapState; + +typedef enum { + BROTLI_STATE_HUFFMAN_NONE, + BROTLI_STATE_HUFFMAN_SIMPLE_SIZE, + BROTLI_STATE_HUFFMAN_SIMPLE_READ, + BROTLI_STATE_HUFFMAN_SIMPLE_BUILD, + BROTLI_STATE_HUFFMAN_COMPLEX, + BROTLI_STATE_HUFFMAN_LENGTH_SYMBOLS +} BrotliRunningHuffmanState; + +typedef enum { + BROTLI_STATE_DECODE_UINT8_NONE, + BROTLI_STATE_DECODE_UINT8_SHORT, + BROTLI_STATE_DECODE_UINT8_LONG +} BrotliRunningDecodeUint8State; + +typedef enum { + BROTLI_STATE_READ_BLOCK_LENGTH_NONE, + BROTLI_STATE_READ_BLOCK_LENGTH_SUFFIX +} BrotliRunningReadBlockLengthState; + +struct BrotliStateStruct { + BrotliRunningState state; + + /* This counter is reused for several disjoint loops. */ + int loop_counter; + + BrotliBitReader br; + + brotli_alloc_func alloc_func; + brotli_free_func free_func; + void* memory_manager_opaque; + + /* Temporary storage for remaining input. */ + union { + uint64_t u64; + uint8_t u8[8]; + } buffer; + uint32_t buffer_length; + + int pos; + int max_backward_distance; + int max_backward_distance_minus_custom_dict_size; + int max_distance; + int ringbuffer_size; + int ringbuffer_mask; + int dist_rb_idx; + int dist_rb[4]; + uint8_t* ringbuffer; + uint8_t* ringbuffer_end; + HuffmanCode* htree_command; + const uint8_t* context_lookup1; + const uint8_t* context_lookup2; + uint8_t* context_map_slice; + uint8_t* dist_context_map_slice; + + uint32_t sub_loop_counter; + + /* This ring buffer holds a few past copy distances that will be used by */ + /* some special distance codes. */ + HuffmanTreeGroup literal_hgroup; + HuffmanTreeGroup insert_copy_hgroup; + HuffmanTreeGroup distance_hgroup; + HuffmanCode* block_type_trees; + HuffmanCode* block_len_trees; + /* This is true if the literal context map histogram type always matches the + block type. It is then not needed to keep the context (faster decoding). */ + int trivial_literal_context; + int distance_context; + int meta_block_remaining_len; + uint32_t block_length_index; + uint32_t block_length[3]; + uint32_t num_block_types[3]; + uint32_t block_type_rb[6]; + uint32_t distance_postfix_bits; + uint32_t num_direct_distance_codes; + int distance_postfix_mask; + uint32_t num_dist_htrees; + uint8_t* dist_context_map; + HuffmanCode* literal_htree; + uint8_t literal_htree_index; + uint8_t dist_htree_index; + uint32_t repeat_code_len; + uint32_t prev_code_len; + + + int copy_length; + int distance_code; + + /* For partial write operations */ + size_t rb_roundtrips; /* How many times we went around the ringbuffer */ + size_t partial_pos_out; /* How much output to the user in total (<= rb) */ + + /* For ReadHuffmanCode */ + uint32_t symbol; + uint32_t repeat; + uint32_t space; + + HuffmanCode table[32]; + /* List of of symbol chains. */ + uint16_t* symbol_lists; + /* Storage from symbol_lists. */ + uint16_t symbols_lists_array[BROTLI_HUFFMAN_MAX_CODE_LENGTH + 1 + + BROTLI_HUFFMAN_MAX_CODE_LENGTHS_SIZE]; + /* Tails of symbol chains. */ + int next_symbol[32]; + uint8_t code_length_code_lengths[18]; + /* Population counts for the code lengths */ + uint16_t code_length_histo[16]; + + /* For HuffmanTreeGroupDecode */ + int htree_index; + HuffmanCode* next; + + /* For DecodeContextMap */ + uint32_t context_index; + uint32_t max_run_length_prefix; + uint32_t code; + HuffmanCode context_map_table[BROTLI_HUFFMAN_MAX_SIZE_272]; + + /* For InverseMoveToFrontTransform */ + uint32_t mtf_upper_bound; + uint8_t mtf[256]; + + /* For custom dictionaries */ + const uint8_t* custom_dict; + int custom_dict_size; + + /* less used attributes are in the end of this struct */ + /* States inside function calls */ + BrotliRunningMetablockHeaderState substate_metablock_header; + BrotliRunningTreeGroupState substate_tree_group; + BrotliRunningContextMapState substate_context_map; + BrotliRunningUncompressedState substate_uncompressed; + BrotliRunningHuffmanState substate_huffman; + BrotliRunningDecodeUint8State substate_decode_uint8; + BrotliRunningReadBlockLengthState substate_read_block_length; + + uint8_t is_last_metablock; + uint8_t is_uncompressed; + uint8_t is_metadata; + uint8_t size_nibbles; + uint32_t window_bits; + + uint32_t num_literal_htrees; + uint8_t* context_map; + uint8_t* context_modes; +}; + +typedef struct BrotliStateStruct BrotliState; + +void BrotliStateInit(BrotliState* s); +void BrotliStateInitWithCustomAllocators(BrotliState* s, + brotli_alloc_func alloc_func, + brotli_free_func free_func, + void* opaque); +void BrotliStateCleanup(BrotliState* s); +void BrotliStateMetablockBegin(BrotliState* s); +void BrotliStateCleanupAfterMetablock(BrotliState* s); +void BrotliHuffmanTreeGroupInit(BrotliState* s, HuffmanTreeGroup* group, + uint32_t alphabet_size, uint32_t ntrees); +void BrotliHuffmanTreeGroupRelease(BrotliState* s, HuffmanTreeGroup* group); + +/* Returns 1, if s is in a state where we have not read any input bytes yet, + and 0 otherwise */ +int BrotliStateIsStreamStart(const BrotliState* s); + +/* Returns 1, if s is in a state where we reached the end of the input and + produced all of the output, and 0 otherwise. */ +int BrotliStateIsStreamEnd(const BrotliState* s); + +#if defined(__cplusplus) || defined(c_plusplus) +} /* extern "C" */ +#endif + +#endif /* BROTLI_DEC_STATE_H_ */ diff --git a/web/server/h2o/libh2o/deps/brotli/dec/transform.h b/web/server/h2o/libh2o/deps/brotli/dec/transform.h new file mode 100644 index 00000000..8c08f3fc --- /dev/null +++ b/web/server/h2o/libh2o/deps/brotli/dec/transform.h @@ -0,0 +1,300 @@ +/* Copyright 2013 Google Inc. All Rights Reserved. + + Distributed under MIT license. + See file LICENSE for detail or copy at https://opensource.org/licenses/MIT +*/ + +/* Transformations on dictionary words. */ + +#ifndef BROTLI_DEC_TRANSFORM_H_ +#define BROTLI_DEC_TRANSFORM_H_ + +#include "./port.h" +#include "./types.h" + +#if defined(__cplusplus) || defined(c_plusplus) +extern "C" { +#endif + +enum WordTransformType { + kIdentity = 0, + kOmitLast1 = 1, + kOmitLast2 = 2, + kOmitLast3 = 3, + kOmitLast4 = 4, + kOmitLast5 = 5, + kOmitLast6 = 6, + kOmitLast7 = 7, + kOmitLast8 = 8, + kOmitLast9 = 9, + kUppercaseFirst = 10, + kUppercaseAll = 11, + kOmitFirst1 = 12, + kOmitFirst2 = 13, + kOmitFirst3 = 14, + kOmitFirst4 = 15, + kOmitFirst5 = 16, + kOmitFirst6 = 17, + kOmitFirst7 = 18, + kOmitFirst8 = 19, + kOmitFirst9 = 20 +}; + +typedef struct { + const uint8_t prefix_id; + const uint8_t transform; + const uint8_t suffix_id; +} Transform; + +static const char kPrefixSuffix[208] = + "\0 \0, \0 of the \0 of \0s \0.\0 and \0 in \0\"\0 to \0\">\0\n\0. \0]\0" + " for \0 a \0 that \0\'\0 with \0 from \0 by \0(\0. The \0 on \0 as \0" + " is \0ing \0\n\t\0:\0ed \0=\"\0 at \0ly \0,\0=\'\0.com/\0. This \0" + " not \0er \0al \0ful \0ive \0less \0est \0ize \0\xc2\xa0\0ous "; + +enum { + /* EMPTY = "" + SP = " " + DQUOT = "\"" + SQUOT = "'" + CLOSEBR = "]" + OPEN = "(" + SLASH = "/" + NBSP = non-breaking space "\0xc2\xa0" + */ + kPFix_EMPTY = 0, + kPFix_SP = 1, + kPFix_COMMASP = 3, + kPFix_SPofSPtheSP = 6, + kPFix_SPtheSP = 9, + kPFix_eSP = 12, + kPFix_SPofSP = 15, + kPFix_sSP = 20, + kPFix_DOT = 23, + kPFix_SPandSP = 25, + kPFix_SPinSP = 31, + kPFix_DQUOT = 36, + kPFix_SPtoSP = 38, + kPFix_DQUOTGT = 43, + kPFix_NEWLINE = 46, + kPFix_DOTSP = 48, + kPFix_CLOSEBR = 51, + kPFix_SPforSP = 53, + kPFix_SPaSP = 59, + kPFix_SPthatSP = 63, + kPFix_SQUOT = 70, + kPFix_SPwithSP = 72, + kPFix_SPfromSP = 79, + kPFix_SPbySP = 86, + kPFix_OPEN = 91, + kPFix_DOTSPTheSP = 93, + kPFix_SPonSP = 100, + kPFix_SPasSP = 105, + kPFix_SPisSP = 110, + kPFix_ingSP = 115, + kPFix_NEWLINETAB = 120, + kPFix_COLON = 123, + kPFix_edSP = 125, + kPFix_EQDQUOT = 129, + kPFix_SPatSP = 132, + kPFix_lySP = 137, + kPFix_COMMA = 141, + kPFix_EQSQUOT = 143, + kPFix_DOTcomSLASH = 146, + kPFix_DOTSPThisSP = 152, + kPFix_SPnotSP = 160, + kPFix_erSP = 166, + kPFix_alSP = 170, + kPFix_fulSP = 174, + kPFix_iveSP = 179, + kPFix_lessSP = 184, + kPFix_estSP = 190, + kPFix_izeSP = 195, + kPFix_NBSP = 200, + kPFix_ousSP = 203 +}; + +static const Transform kTransforms[] = { + { kPFix_EMPTY, kIdentity, kPFix_EMPTY }, + { kPFix_EMPTY, kIdentity, kPFix_SP }, + { kPFix_SP, kIdentity, kPFix_SP }, + { kPFix_EMPTY, kOmitFirst1, kPFix_EMPTY }, + { kPFix_EMPTY, kUppercaseFirst, kPFix_SP }, + { kPFix_EMPTY, kIdentity, kPFix_SPtheSP }, + { kPFix_SP, kIdentity, kPFix_EMPTY }, + { kPFix_sSP, kIdentity, kPFix_SP }, + { kPFix_EMPTY, kIdentity, kPFix_SPofSP }, + { kPFix_EMPTY, kUppercaseFirst, kPFix_EMPTY }, + { kPFix_EMPTY, kIdentity, kPFix_SPandSP }, + { kPFix_EMPTY, kOmitFirst2, kPFix_EMPTY }, + { kPFix_EMPTY, kOmitLast1, kPFix_EMPTY }, + { kPFix_COMMASP, kIdentity, kPFix_SP }, + { kPFix_EMPTY, kIdentity, kPFix_COMMASP }, + { kPFix_SP, kUppercaseFirst, kPFix_SP }, + { kPFix_EMPTY, kIdentity, kPFix_SPinSP }, + { kPFix_EMPTY, kIdentity, kPFix_SPtoSP }, + { kPFix_eSP, kIdentity, kPFix_SP }, + { kPFix_EMPTY, kIdentity, kPFix_DQUOT }, + { kPFix_EMPTY, kIdentity, kPFix_DOT }, + { kPFix_EMPTY, kIdentity, kPFix_DQUOTGT }, + { kPFix_EMPTY, kIdentity, kPFix_NEWLINE }, + { kPFix_EMPTY, kOmitLast3, kPFix_EMPTY }, + { kPFix_EMPTY, kIdentity, kPFix_CLOSEBR }, + { kPFix_EMPTY, kIdentity, kPFix_SPforSP }, + { kPFix_EMPTY, kOmitFirst3, kPFix_EMPTY }, + { kPFix_EMPTY, kOmitLast2, kPFix_EMPTY }, + { kPFix_EMPTY, kIdentity, kPFix_SPaSP }, + { kPFix_EMPTY, kIdentity, kPFix_SPthatSP }, + { kPFix_SP, kUppercaseFirst, kPFix_EMPTY }, + { kPFix_EMPTY, kIdentity, kPFix_DOTSP }, + { kPFix_DOT, kIdentity, kPFix_EMPTY }, + { kPFix_SP, kIdentity, kPFix_COMMASP }, + { kPFix_EMPTY, kOmitFirst4, kPFix_EMPTY }, + { kPFix_EMPTY, kIdentity, kPFix_SPwithSP }, + { kPFix_EMPTY, kIdentity, kPFix_SQUOT }, + { kPFix_EMPTY, kIdentity, kPFix_SPfromSP }, + { kPFix_EMPTY, kIdentity, kPFix_SPbySP }, + { kPFix_EMPTY, kOmitFirst5, kPFix_EMPTY }, + { kPFix_EMPTY, kOmitFirst6, kPFix_EMPTY }, + { kPFix_SPtheSP, kIdentity, kPFix_EMPTY }, + { kPFix_EMPTY, kOmitLast4, kPFix_EMPTY }, + { kPFix_EMPTY, kIdentity, kPFix_DOTSPTheSP }, + { kPFix_EMPTY, kUppercaseAll, kPFix_EMPTY }, + { kPFix_EMPTY, kIdentity, kPFix_SPonSP }, + { kPFix_EMPTY, kIdentity, kPFix_SPasSP }, + { kPFix_EMPTY, kIdentity, kPFix_SPisSP }, + { kPFix_EMPTY, kOmitLast7, kPFix_EMPTY }, + { kPFix_EMPTY, kOmitLast1, kPFix_ingSP }, + { kPFix_EMPTY, kIdentity, kPFix_NEWLINETAB }, + { kPFix_EMPTY, kIdentity, kPFix_COLON }, + { kPFix_SP, kIdentity, kPFix_DOTSP }, + { kPFix_EMPTY, kIdentity, kPFix_edSP }, + { kPFix_EMPTY, kOmitFirst9, kPFix_EMPTY }, + { kPFix_EMPTY, kOmitFirst7, kPFix_EMPTY }, + { kPFix_EMPTY, kOmitLast6, kPFix_EMPTY }, + { kPFix_EMPTY, kIdentity, kPFix_OPEN }, + { kPFix_EMPTY, kUppercaseFirst, kPFix_COMMASP }, + { kPFix_EMPTY, kOmitLast8, kPFix_EMPTY }, + { kPFix_EMPTY, kIdentity, kPFix_SPatSP }, + { kPFix_EMPTY, kIdentity, kPFix_lySP }, + { kPFix_SPtheSP, kIdentity, kPFix_SPofSP }, + { kPFix_EMPTY, kOmitLast5, kPFix_EMPTY }, + { kPFix_EMPTY, kOmitLast9, kPFix_EMPTY }, + { kPFix_SP, kUppercaseFirst, kPFix_COMMASP }, + { kPFix_EMPTY, kUppercaseFirst, kPFix_DQUOT }, + { kPFix_DOT, kIdentity, kPFix_OPEN }, + { kPFix_EMPTY, kUppercaseAll, kPFix_SP }, + { kPFix_EMPTY, kUppercaseFirst, kPFix_DQUOTGT }, + { kPFix_EMPTY, kIdentity, kPFix_EQDQUOT }, + { kPFix_SP, kIdentity, kPFix_DOT }, + { kPFix_DOTcomSLASH, kIdentity, kPFix_EMPTY }, + { kPFix_SPtheSP, kIdentity, kPFix_SPofSPtheSP }, + { kPFix_EMPTY, kUppercaseFirst, kPFix_SQUOT }, + { kPFix_EMPTY, kIdentity, kPFix_DOTSPThisSP }, + { kPFix_EMPTY, kIdentity, kPFix_COMMA }, + { kPFix_DOT, kIdentity, kPFix_SP }, + { kPFix_EMPTY, kUppercaseFirst, kPFix_OPEN }, + { kPFix_EMPTY, kUppercaseFirst, kPFix_DOT }, + { kPFix_EMPTY, kIdentity, kPFix_SPnotSP }, + { kPFix_SP, kIdentity, kPFix_EQDQUOT }, + { kPFix_EMPTY, kIdentity, kPFix_erSP }, + { kPFix_SP, kUppercaseAll, kPFix_SP }, + { kPFix_EMPTY, kIdentity, kPFix_alSP }, + { kPFix_SP, kUppercaseAll, kPFix_EMPTY }, + { kPFix_EMPTY, kIdentity, kPFix_EQSQUOT }, + { kPFix_EMPTY, kUppercaseAll, kPFix_DQUOT }, + { kPFix_EMPTY, kUppercaseFirst, kPFix_DOTSP }, + { kPFix_SP, kIdentity, kPFix_OPEN }, + { kPFix_EMPTY, kIdentity, kPFix_fulSP }, + { kPFix_SP, kUppercaseFirst, kPFix_DOTSP }, + { kPFix_EMPTY, kIdentity, kPFix_iveSP }, + { kPFix_EMPTY, kIdentity, kPFix_lessSP }, + { kPFix_EMPTY, kUppercaseAll, kPFix_SQUOT }, + { kPFix_EMPTY, kIdentity, kPFix_estSP }, + { kPFix_SP, kUppercaseFirst, kPFix_DOT }, + { kPFix_EMPTY, kUppercaseAll, kPFix_DQUOTGT }, + { kPFix_SP, kIdentity, kPFix_EQSQUOT }, + { kPFix_EMPTY, kUppercaseFirst, kPFix_COMMA }, + { kPFix_EMPTY, kIdentity, kPFix_izeSP }, + { kPFix_EMPTY, kUppercaseAll, kPFix_DOT }, + { kPFix_NBSP, kIdentity, kPFix_EMPTY }, + { kPFix_SP, kIdentity, kPFix_COMMA }, + { kPFix_EMPTY, kUppercaseFirst, kPFix_EQDQUOT }, + { kPFix_EMPTY, kUppercaseAll, kPFix_EQDQUOT }, + { kPFix_EMPTY, kIdentity, kPFix_ousSP }, + { kPFix_EMPTY, kUppercaseAll, kPFix_COMMASP }, + { kPFix_EMPTY, kUppercaseFirst, kPFix_EQSQUOT }, + { kPFix_SP, kUppercaseFirst, kPFix_COMMA }, + { kPFix_SP, kUppercaseAll, kPFix_EQDQUOT }, + { kPFix_SP, kUppercaseAll, kPFix_COMMASP }, + { kPFix_EMPTY, kUppercaseAll, kPFix_COMMA }, + { kPFix_EMPTY, kUppercaseAll, kPFix_OPEN }, + { kPFix_EMPTY, kUppercaseAll, kPFix_DOTSP }, + { kPFix_SP, kUppercaseAll, kPFix_DOT }, + { kPFix_EMPTY, kUppercaseAll, kPFix_EQSQUOT }, + { kPFix_SP, kUppercaseAll, kPFix_DOTSP }, + { kPFix_SP, kUppercaseFirst, kPFix_EQDQUOT }, + { kPFix_SP, kUppercaseAll, kPFix_EQSQUOT }, + { kPFix_SP, kUppercaseFirst, kPFix_EQSQUOT }, +}; + +static const int kNumTransforms = sizeof(kTransforms) / sizeof(kTransforms[0]); + +static int ToUpperCase(uint8_t* p) { + if (p[0] < 0xc0) { + if (p[0] >= 'a' && p[0] <= 'z') { + p[0] ^= 32; + } + return 1; + } + /* An overly simplified uppercasing model for utf-8. */ + if (p[0] < 0xe0) { + p[1] ^= 32; + return 2; + } + /* An arbitrary transform for three byte characters. */ + p[2] ^= 5; + return 3; +} + +static BROTLI_NOINLINE int TransformDictionaryWord( + uint8_t* dst, const uint8_t* word, int len, int transform) { + int idx = 0; + { + const char* prefix = &kPrefixSuffix[kTransforms[transform].prefix_id]; + while (*prefix) { dst[idx++] = (uint8_t)*prefix++; } + } + { + const int t = kTransforms[transform].transform; + int i = 0; + int skip = t - (kOmitFirst1 - 1); + if (skip > 0) { + word += skip; + len -= skip; + } else if (t <= kOmitLast9) { + len -= t; + } + while (i < len) { dst[idx++] = word[i++]; } + if (t == kUppercaseFirst) { + ToUpperCase(&dst[idx - len]); + } else if (t == kUppercaseAll) { + uint8_t* uppercase = &dst[idx - len]; + while (len > 0) { + int step = ToUpperCase(uppercase); + uppercase += step; + len -= step; + } + } + } + { + const char* suffix = &kPrefixSuffix[kTransforms[transform].suffix_id]; + while (*suffix) { dst[idx++] = (uint8_t)*suffix++; } + return idx; + } +} + +#if defined(__cplusplus) || defined(c_plusplus) +} /* extern "C" */ +#endif + +#endif /* BROTLI_DEC_TRANSFORM_H_ */ diff --git a/web/server/h2o/libh2o/deps/brotli/dec/types.h b/web/server/h2o/libh2o/deps/brotli/dec/types.h new file mode 100644 index 00000000..0f7a0216 --- /dev/null +++ b/web/server/h2o/libh2o/deps/brotli/dec/types.h @@ -0,0 +1,38 @@ +/* Copyright 2013 Google Inc. All Rights Reserved. + + Distributed under MIT license. + See file LICENSE for detail or copy at https://opensource.org/licenses/MIT +*/ + +/* Common types */ + +#ifndef BROTLI_DEC_TYPES_H_ +#define BROTLI_DEC_TYPES_H_ + +#include /* for size_t */ + +#if defined(_MSC_VER) && (_MSC_VER < 1600) +typedef __int8 int8_t; +typedef unsigned __int8 uint8_t; +typedef __int16 int16_t; +typedef unsigned __int16 uint16_t; +typedef __int32 int32_t; +typedef unsigned __int32 uint32_t; +typedef unsigned __int64 uint64_t; +typedef __int64 int64_t; +#else +#include +#endif /* defined(_MSC_VER) && (_MSC_VER < 1600) */ + +/* Allocating function pointer. Function MUST return 0 in the case of failure. + Otherwise it MUST return a valid pointer to a memory region of at least + size length. Neither items nor size are allowed to be 0. + opaque argument is a pointer provided by client and could be used to bind + function to specific object (memory pool). */ +typedef void* (*brotli_alloc_func)(void* opaque, size_t size); + +/* Deallocating function pointer. Function SHOULD be no-op in the case the + address is 0. */ +typedef void (*brotli_free_func)(void* opaque, void* address); + +#endif /* BROTLI_DEC_TYPES_H_ */ diff --git a/web/server/h2o/libh2o/deps/brotli/docs/brotli-comparison-study-2015-09-22.pdf b/web/server/h2o/libh2o/deps/brotli/docs/brotli-comparison-study-2015-09-22.pdf new file mode 100644 index 00000000..040f179e Binary files /dev/null and b/web/server/h2o/libh2o/deps/brotli/docs/brotli-comparison-study-2015-09-22.pdf differ diff --git a/web/server/h2o/libh2o/deps/brotli/docs/draft-alakuijala-brotli-08.nroff b/web/server/h2o/libh2o/deps/brotli/docs/draft-alakuijala-brotli-08.nroff new file mode 100644 index 00000000..5bbf3739 --- /dev/null +++ b/web/server/h2o/libh2o/deps/brotli/docs/draft-alakuijala-brotli-08.nroff @@ -0,0 +1,5891 @@ +.pl 10.0i +.po 0 +.ll 7.2i +.lt 7.2i +.nr LL 7.2i +.nr LT 7.2i +.ds LF Alakuijala & Szabadka +.ds RF FORMFEED[Page %] +.ds LH Internet-Draft +.ds RH December 2015 +.ds CH Brotli +.ds CF Expires June 10, 2016 +.hy 0 +.nh +.ad l +.in 0 +.nf +.tl 'Network Working Group''J. Alakuijala' +.tl 'Internet-Draft''Z. Szabadka' +.tl 'Intended Status: Informational''Google, Inc' +.tl 'Expires: June 10, 2016''December 2015' +.fi + + +.ce 2 +Brotli Compressed Data Format +draft-alakuijala-brotli-08 +.fi +.in 3 + +.ti 0 +Abstract + +This specification defines a lossless compressed data format that +compresses data using a combination of the LZ77 algorithm and Huffman +coding, with efficiency comparable to the best currently available +general-purpose compression methods. + +.ti 0 +Status of this Memo + +This Internet-Draft is submitted in full conformance with the +provisions of BCP 78 and BCP 79. + +Internet-Drafts are working documents of the Internet Engineering +Task Force (IETF). Note that other groups may also distribute +working documents as Internet-Drafts. The list of current Internet- +Drafts is at http://datatracker.ietf.org/drafts/current/. + +Internet-Drafts are draft documents valid for a maximum of six months +and may be updated, replaced, or obsoleted by other documents at any +time. It is inappropriate to use Internet-Drafts as reference +material or to cite them other than as "work in progress." + +This Internet-Draft will expire on June 10, 2016. + +.ti 0 +Copyright Notice + +Copyright (c) 2015 IETF Trust and the persons identified as the document +authors. All rights reserved. + +This document is subject to BCP 78 and the IETF Trust's Legal +Provisions Relating to IETF Documents +(http://trustee.ietf.org/license-info) in effect on the date of +publication of this document. Please review these documents +carefully, as they describe your rights and restrictions with respect +to this document. Code Components extracted from this document must +include Simplified BSD License text as described in Section 4.e of +the Trust Legal Provisions and are provided without warranty as +described in the Simplified BSD License. + +.ti 0 +Table of Contents + +.in 0 +.nf +INSERT_TOC_HERE +.fi +.in 3 + +.bp +.ti 0 +1. Introduction + +.ti 0 +1.1. Purpose + +The purpose of this specification is to define a lossless +compressed data format that: + +.nf + * Is independent of CPU type, operating system, file system, + and character set, and hence can be used for interchange; + * Can be produced or consumed, even for an arbitrarily long + sequentially presented input data stream, using only an a + priori bounded amount of intermediate storage, and hence + can be used in data communications or similar structures, + such as Unix filters; + * Compresses data with a compression ratio comparable to the + best currently available general-purpose compression methods, + and in particular, considerably better than the gzip program; + * Decompresses much faster than current LZMA implementations. +.fi + +The data format defined by this specification does not attempt to: + +.nf + * Allow random access to compressed data; + * Compress specialized data (e.g., raster graphics) as well + as the best currently available specialized algorithms. +.fi + +.ti 0 +1.2. Intended audience + +This specification is intended for use by software implementers +to compress data into and/or decompress data from the brotli format. + +The text of the specification assumes a basic background in +programming at the level of bits and other primitive data +representations. Familiarity with the technique of Huffman coding +is helpful but not required. + +This specification uses heavily the notations and terminology +introduced in the DEFLATE format specification [RFC 1951]. +For the sake of completeness, we always +include the whole text of the relevant parts of RFC 1951, +therefore familiarity with the DEFLATE format is helpful but not +required. + +The compressed data format defined in this specification is +an integral part of the WOFF 2.0 web font file format [WOFF2], +therefore this specification is also intended for implementers of +WOFF 2.0 compressors and decompressors. + +.ti 0 +1.3. Scope + +The specification specifies a method for representing a sequence +of bytes as a (usually shorter) sequence of bits, and a method for +packing the latter bit sequence into bytes. + +.ti 0 +1.4. Compliance + +Unless otherwise indicated below, a compliant decompressor must be +able to accept and decompress any data set that conforms to all +the specifications presented here. A compliant compressor must +produce data sets that conform to all the specifications presented +here. + +.ti 0 +1.5. Definitions of terms and conventions used + +Byte: 8 bits stored or transmitted as a unit (same as an octet). +For this specification, a byte is exactly 8 bits, even on machines +that store a character on a number of bits different from eight. +See below for the numbering of bits within a byte. + +String: a sequence of arbitrary bytes. + +Bytes stored within a computer do not have a "bit order", since +they are always treated as a unit. However, a byte considered as +an integer between 0 and 255 does have a most- and +least-significant bit, and since we write numbers with the +most-significant digit on the left, we also write bytes with the +most-significant bit on the left. In the diagrams below, we number +the bits of a byte so that bit 0 is the least-significant bit, i.e., +the bits are numbered: + +.nf + +--------+ + |76543210| + +--------+ +.fi + +Within a computer, a number may occupy multiple bytes. All +multi-byte numbers in the format described here are stored with +the least-significant byte first (at the lower memory address). +For example, the decimal number 520 is stored as: + +.nf + 0 1 + +--------+--------+ + |00001000|00000010| + +--------+--------+ + ^ ^ + | | + | + more significant byte = 2 x 256 + + less significant byte = 8 +.fi + +.ti 0 +1.5.1. Packing into bytes + +This document does not address the issue of the order in which +bits of a byte are transmitted on a bit-sequential medium, +since the final data format described here is byte- rather than +bit-oriented. However, we describe the compressed block format +below as a sequence of data elements of various bit +lengths, not a sequence of bytes. We must therefore specify +how to pack these data elements into bytes to form the final +compressed byte sequence: + +.nf + * Data elements are packed into bytes in order of + increasing bit number within the byte, i.e., starting + with the least-significant bit of the byte. + * Data elements other than prefix codes are packed + starting with the least-significant bit of the data + element. These are referred to here as integer values + and are considered unsigned. + * Prefix codes are packed starting with the most-significant + bit of the code. +.fi + +In other words, if one were to print out the compressed data as +a sequence of bytes, starting with the first byte at the +*right* margin and proceeding to the *left*, with the +most-significant bit of each byte on the left as usual, one would +be able to parse the result from right to left, with fixed-width +elements in the correct MSB-to-LSB order and prefix codes in +bit-reversed order (i.e., with the first bit of the code in the +relative LSB position). + +.ti 0 +2. Compressed representation overview + +A compressed data set consists of a header and a series of +meta-blocks. Each meta-block decompresses to a sequence of 0 +to 16,777,216 (16 MiB) uncompressed bytes. The final uncompressed data is +the concatenation of the uncompressed sequences from each meta-block. + +The header contains the size of the sliding window that was used during compression. +The decompressor must retain at least that amount of uncompressed data prior to the +current position in the stream, in order to be able to decompress +what follows. The sliding window size is a power of two, minus 16, where +the power is in the range of 10 to 24. The possible sliding window +sizes range from 1 KiB - 16 B to 16 MiB - 16 B. + +Each meta-block is compressed using a combination of the LZ77 +algorithm (Lempel-Ziv 1977, [LZ77]) and Huffman coding. The +result of Huffman coding is referred to here as a prefix code. +The prefix codes for each meta-block are independent of +those for previous or subsequent meta-blocks; the LZ77 algorithm may +use a reference to a duplicated string occurring in a previous +meta-block, up to the sliding window size of uncompressed bytes before. +In addition, in the brotli format, a string reference may instead refer +to a static dictionary entry. + +Each meta-block consists of two parts: a meta-block header that +describes the representation of the compressed data part, and a +compressed data part. The compressed data consists of a series of +commands. Each command consists of two parts: a sequence of literal +bytes (of strings that have not been detected as duplicated within +the sliding window), and a pointer to a duplicated string, +represented as a pair . There can be +zero literal bytes in the command. The minimum length of the string to be +duplicated is two, but the last command in the meta-block is permitted to have +only literals and no pointer to a string to duplicate. + +Each command in the compressed data is represented using three categories +of prefix codes: + +.nf + 1) One set of prefix codes are for the literal sequence lengths + (also referred to as literal insertion lengths) and + backward copy lengths. That is, a single code word represents + two lengths, one of the literal sequence and one of the + backward copy. + + 2) One set of prefix codes are for literals. + + 3) One set of prefix codes are for distances. +.fi + +The prefix code descriptions for each meta-block appear in a compact +form just before the compressed data in the meta-block header. +The insert-and-copy length and distance prefix codes may be followed by +extra bits that are added to the base values determined by the codes. +The number of extra bits is determined by the code. + +One meta-block command then appears as a sequence of prefix codes: + +.nf + Insert-and-copy length, literal, literal, ..., literal, distance +.fi + +where the insert-and-copy defines an insertion length and a copy length. +The insertion length determines the number of literals that immediately +follow. The distance defines how far back to go for the copy and the +copy length determines the number of bytes to copy. The resulting +uncompressed data is the sequence of bytes: + +.nf + literal, literal, ..., literal, copy, copy, ..., copy +.fi + +where the number of literal bytes and copy bytes are determined by the +insert-and-copy length code. (The number of bytes copied for a static +dictionary entry can vary from the copy length.) + +The last command in the meta-block may end with the last literal if the +total uncompressed length of the meta-block has been satisfied. In +that case there is no distance in the last command, and the copy length is +ignored. + +There can be more than one prefix code for each category, where the +prefix code to use for the next element of that category is determined +by the context of the compressed stream that precedes that element. +Part of that context is three current block types, one for each +category. A block type is in the range of 0..255. For each category +there is a count of how many elements of that category remain to be +decoded using the current block type. Once that count is expended, +a new block type and block count is read from the stream immediately +preceding the next element of that category, which will use the new +block type. + +The insert-and-copy block type directly determines which prefix code to +use for the next insert-and-copy element. For the literal and distance +elements, the respective block type is used in combination with other +context information to determine which prefix code to use for the next +element. + +Consider the following example: + +.nf + (IaC0, L0, L1, L2, D0)(IaC1, D1)(IaC2, L3, L4, D2)(IaC3, L5, D3) +.fi + +The meta-block here has four commands, contained in parentheses for clarity, +where each of the three categories of +symbols within these commands can be interpreted using different block types. +Here we separate out each category as its own sequence to show an example of block +types assigned to those elements. Each square-bracketed group is a block that +uses the same block type: + +.nf + [IaC0, IaC1][IaC2, IaC3] <-- insert-and-copy: block types 0 and 1 + + [L0, L1][L2, L3, L4][L5] <-- literals: block types 0, 1, and 0 + + [D0][D1, D2, D3] <-- distances: block types 0 and 1 +.fi + +The subsequent blocks within each block category must have different +block types, but we see that block types can be reused later in the meta-block. +The block types are numbered from 0 to the maximum +block type number of 255 and the first block of each block category +is type 0. The block structure of a meta-block is represented +by the sequence of block-switch commands for each block category, +where a block-switch command is a pair . +The block-switch commands are represented in the compressed data +before the start of each new block using a prefix code for +block types and a separate prefix code for block counts for +each block category. For the above example the physical layout of the +meta-block is then: + +.nf + IaC0 L0 L1 LBlockSwitch(1, 3) L2 D0 IaC1 DBlockSwitch(1, 3) D1 + IaCBlockSwitch(1, 2) IaC2 L3 L4 D2 IaC3 LBlockSwitch(0, 1) L5 D3 +.fi + +where xBlockSwitch(t, n) switches to block type t for a count of n elements. +Note that in this example DBlockSwitch(1, 3) immediately precedes the +next required distance D1. It does not follow the last distance of +the previous block, D0. Whenever an element of a category is needed, +and the block count for that category has reached zero, then a new +block type and count is read from the stream just before reading that next +element. + +The block-switch commands for the first blocks of each category are not part +of the meta-block compressed data. Instead the first block type +is defined to be 0, and the first block count for each category is +encoded in the meta-block header. The prefix codes for the block types and counts, a total of +six prefix codes over the three categories, are defined in a compact form in the meta-block +header. + +Each category of value (insert-and-copy lengths, literals, and distances) +can be encoded with any prefix code from a collection of prefix +codes belonging to the same category appearing in the meta-block header. The +particular prefix code used can depend on two factors: the block +type of the block the value appears in, and the context of the value. +In the case of the literals, the context is the previous two bytes in +the uncompressed data, and in the case of distances, the context is the copy +length from the same command. For insert-and-copy lengths, no context +is used and the prefix code depends only on the block type. In the case +of literals and distances, the context is mapped to a context ID in +the range 0..63 for literals and 0..3 for distances. The matrix +of the prefix code indexes for each block type and context ID, +called the context map, is encoded in a compact form in the meta-block header. + +For example, the prefix code to use to decode L2 depends on the +block type (1), and the literal context ID determined by the two uncompressed +bytes that were decoded from L0 and L1. +Similarly, the prefix code to use to decode D0 depends on the block +type (0), and the distance context ID determined by the copy length decoded +from IaC0. The prefix code to use to decode IaC3 depends only on the block +type (1). + +In addition to the parts listed above (prefix code for insert-and-copy +lengths, literals, distances, block types and block counts, +and the context map), the meta-block header contains the number of +uncompressed bytes coded in the meta-block and two additional parameters used in +the representation of match distances: the number of postfix bits and +the number of direct distance codes. + +A compressed meta-block may be marked in the header as the last meta-block, +which terminates the compressed stream. + +A meta-block may instead simply store the uncompressed data directly as +bytes on byte boundaries with no coding or matching strings. In this +case the meta-block header information only contains the number of +uncompressed bytes and the indication that the meta-block is uncompressed. +An uncompressed meta-block cannot be the last meta-block. + +A meta-block may also be empty, which generates no uncompressed data at all. +An empty meta-block may contain metadata information as bytes starting on byte +boundaries, which are not part of either the sliding window or the uncompressed +data. Thus, these metadata bytes cannot be used to create matching strings in +subsequent meta-blocks and are not used as context bytes for literals. + +.ti 0 +3. Compressed representation of prefix codes + +.ti 0 +3.1. Introduction to prefix coding + +Prefix coding represents symbols from an a priori known alphabet +by bit sequences (codes), one code for each symbol, in a manner +such that different symbols may be represented by bit sequences of +different lengths, but a parser can always parse an encoded string +unambiguously symbol-by-symbol. + +We define a prefix code in terms of a binary tree in which the two +edges descending from each non-leaf node are labeled 0 and 1 and +in which the leaf nodes correspond one-for-one with (are labeled +with) the symbols of the alphabet; then the code for a symbol is +the sequence of 0's and 1's on the edges leading from the root to +the leaf labeled with that symbol. For example: + +.nf +.KS + /\\ Symbol Code + 0 1 ------ ---- + / \\ A 00 + /\\ B B 1 + 0 1 C 011 + / \\ D 010 + A /\\ + 0 1 + / \\ + D C +.KE +.fi + +A parser can decode the next symbol from the compressed stream +by walking down the tree from the root, at each step choosing the +edge corresponding to the next compressed data bit. + +Given an alphabet with known symbol frequencies, the Huffman +algorithm allows the construction of an optimal prefix code (one +which represents strings with those symbol frequencies using the +fewest bits of any possible prefix codes for that alphabet). Such +a prefix code is called a Huffman code. (See [HUFFMAN] in Chapter 5, +references for additional information on Huffman codes.) + +Note that in the brotli format, the prefix codes for the +various alphabets must not exceed certain maximum code lengths. +This constraint complicates the algorithm for computing code +lengths from symbol frequencies. Again, see Chapter 5, references +for details. + +.ti 0 +3.2. Use of prefix coding in the brotli format + +The prefix codes used for each alphabet in the brotli format +are canonical prefix codes, which have two additional rules: + +.nf + * All codes of a given bit length have lexicographically + consecutive values, in the same order as the symbols they + represent; + + * Shorter codes lexicographically precede longer codes. +.fi + +We could recode the example above to follow this rule as follows, +assuming that the order of the alphabet is ABCD: + +.nf +.KS + Symbol Code + ------ ---- + A 10 + B 0 + C 110 + D 111 +.KE +.fi + +I.e., 0 precedes 10, which precedes 11x, and 110 and 111 are +lexicographically consecutive. + +Given this rule, we can define the canonical prefix code for an +alphabet just by giving the bit lengths of the codes for each +symbol of the alphabet in order; this is sufficient to determine +the actual codes. In our example, the code is completely defined +by the sequence of bit lengths (2, 1, 3, 3). The following +algorithm generates the codes as integers, intended to be read +from most- to least-significant bit. The code lengths are +initially in tree[I].Len; the codes are produced in tree[I].Code. + +.nf + 1) Count the number of codes for each code length. Let + bl_count[N] be the number of codes of length N, N >= 1. + + 2) Find the numerical value of the smallest code for each + code length: + +.KS + code = 0; + bl_count[0] = 0; + for (bits = 1; bits <= MAX_BITS; bits++) { + code = (code + bl_count[bits-1]) << 1; + next_code[bits] = code; + } +.KE + + 3) Assign numerical values to all codes, using consecutive + values for all codes of the same length with the base + values determined at step 2. Codes that are never used + (which have a bit length of zero) must not be assigned a + value. + +.KS + for (n = 0; n <= max_code; n++) { + len = tree[n].Len; + if (len != 0) { + tree[n].Code = next_code[len]; + next_code[len]++; + } + } +.KE +.fi + +Example: + +Consider the alphabet ABCDEFGH, with bit lengths (3, 3, 3, 3, 3, +2, 4, 4). After step 1, we have: + +.nf +.KS + N bl_count[N] + - ----------- + 2 1 + 3 5 + 4 2 +.KE +.fi + +Step 2 computes the following next_code values: + +.nf +.KS + N next_code[N] + - ------------ + 1 0 + 2 0 + 3 2 + 4 14 +.KE +.fi + +Step 3 produces the following code values: + +.nf +.KS + Symbol Length Code + ------ ------ ---- + A 3 010 + B 3 011 + C 3 100 + D 3 101 + E 3 110 + F 2 00 + G 4 1110 + H 4 1111 +.KE +.fi + +.ti 0 +3.3. Alphabet sizes + +Prefix codes are used for different purposes in the brotli +format, and each purpose has a different alphabet size. For +literal codes the alphabet size is 256. For insert-and-copy +length codes the alphabet size is 704. For block count codes, +the alphabet size is 26. For distance codes, block type codes, and +the prefix codes used in compressing the context map, the +alphabet size is dynamic and is based on parameters defined in +later sections. The following table summarizes the alphabet sizes +for the various prefix codes and the sections where they are defined. + +.nf +.KS + +-----------------+-------------------------+------------+ + | Prefix code | Alphabet size | Definition | + +-----------------+-------------------------+------------+ + | literal | 256 | | + +-----------------+-------------------------+------------+ + | distance | 16 + NDIRECT + | Section 4. | + | | (48 << NPOSTFIX) | | + +-----------------+-------------------------+------------+ + | insert-and-copy | 704 | Section 5. | + | length | | | + +-----------------+-------------------------+------------+ + | block count | 26 | Section 6. | + +-----------------+-------------------------+------------+ + | block type | NBLTYPESx + 2, | Section 6. | + | | (where x is I, L, or D) | | + +-----------------+-------------------------+------------+ + | context map | NTREESx + RLEMAXx | Section 7. | + | | (where x is L or D) | | + +-----------------+-------------------------+------------+ +.KE +.fi + +.ti 0 +3.4. Simple prefix codes + +The first two bits of the compressed representation of each +prefix code distinguish between simple and complex prefix +codes. If this value is 1, then a simple prefix code follows +as described in this section. Otherwise, a complex prefix code +follows as described in Section 3.5. + +A simple prefix code can have only up to four symbols with +non-zero code length. The format of the simple prefix code is as +follows: + +.nf + 2 bits: value of 1 indicates a simple prefix code + 2 bits: NSYM - 1, where NSYM = # of symbols coded + + NSYM symbols, each encoded using ALPHABET_BITS bits + + 1 bit: tree-select, present only for NSYM = 4 +.fi + +The value of ALPHABET_BITS depends on the alphabet of the prefix +code: it is the smallest number of bits that can represent all +symbols in the alphabet. E.g. for the alphabet of literal bytes, +ALPHABET_BITS is 8. The value of each of the NSYM symbols above is +the value of the ALPHABETS_BITS width integer value. If the integer +value is greater than or equal to the alphabet size, or the value +is identical to a previous value, then the stream should be rejected +as invalid. + +Note that the NSYM symbols may not be presented in sorted order. Prefix codes +of the same bit length must be assigned to the symbols in sorted order. + +The (non-zero) code lengths of the symbols can be reconstructed as +follows: + +.nf + * if NSYM = 1, the code length for the one symbol is zero -- + when encoding this symbol in the + compressed data stream using this prefix code, no + actual bits are emitted. Similarly, when decoding a symbol + using this prefix code, no bits are read and the one symbol + is returned. + + * if NSYM = 2, both symbols have code length 1. + + * if NSYM = 3, the code lengths for the symbols are 1, 2, 2 in + the order they appear in the representation of the simple + prefix code. + + * if NSYM = 4, the code lengths (in order of symbols decoded) + depend on the tree-select bit: 2, 2, 2, 2 (tree-select bit 0), + or 1, 2, 3, 3 (tree-select bit 1). +.fi + +.ti 0 +3.5. Complex prefix codes + +A complex prefix code is a canonical prefix code, defined by the +sequence of code lengths, as discussed in Section 3.2., above. +For even greater compactness, the code length sequences themselves +are compressed using a prefix code. The alphabet for code lengths +is as follows: + +.nf + 0 - 15: Represent code lengths of 0 - 15 + 16: Copy the previous non-zero code length 3 - 6 times + The next 2 bits indicate repeat length + (0 = 3, ... , 3 = 6) + If this is the first code length, or all previous + code lengths are zero, a code length of 8 is + repeated 3 - 6 times + A repeated code length code of 16 modifies the + repeat count of the previous one as follows: + repeat count = (4 * (repeat count - 2)) + + (3 - 6 on the next 2 bits) + Example: Codes 7, 16 (+2 bits 11), 16 (+2 bits 10) + will expand to 22 code lengths of 7 + (1 + 4 * (6 - 2) + 5) + 17: Repeat a code length of 0 for 3 - 10 times. + (3 bits of length) + A repeated code length code of 17 modifies the + repeat count of the previous one as follows: + repeat count = (8 * (repeat count - 2)) + + (3 - 10 on the next 3 bits) +.fi + +Note that a code of 16 that follows an immediately preceding 16 modifies the +previous repeat count, which becomes the new repeat count. The same is true for +a 17 following a 17. A sequence of three or more 16 codes in a row or three of +more 17 codes in a row is possible, modifying the count each time. Only the +final repeat count is used. The modification only applies if the same code +follows. A 16 repeat does not modify an immediately preceding 17 count nor +vice versa. + +A code length of 0 indicates that the corresponding symbol in the +alphabet will not occur in the compressed data, and should not +participate in the prefix code construction algorithm given +earlier. A complex prefix code must have at least two non-zero +code lengths. + +The bit lengths of the prefix code over the code length alphabet +are compressed with the following variable length code (as it appears +in the compressed data, where the bits are parsed from right to left): + +.nf +.KS + Symbol Code + ------ ---- + 0 00 + 1 0111 + 2 011 + 3 10 + 4 01 + 5 1111 +.KE +.fi + +We can now define the format of the complex prefix code as follows: + +.nf + 2 bits: HSKIP, values of 0, 2, or 3 represent the respective + number of skipped code lengths. The skipped lengths + are taken to be zero. (An HSKIP of 1 indicates a + Simple prefix code.) + + Code lengths for symbols in the code length alphabet given + just above, in the order: 1, 2, 3, 4, 0, 5, 17, 6, 16, 7, + 8, 9, 10, 11, 12, 13, 14, 15. If HSKIP is 2, then the + code lengths for symbols 1 and 2 are zero, and the first + code length is for symbol 3. If HSKIP is 3, then the code + length for symbol 3 is also zero, and the first code length + is for symbol 4. + + The code lengths of code length symbols are between 0 and + 5, and they are represented with 2 - 4 bits according to + the variable length code above. A code length of 0 means + the corresponding code length symbol is not used. + + If HSKIP is 2 or 3, a respective number of leading code + lengths are implicit zeros and are not present in the + code lengths sequence above. + + If there are at least two non-zero code lengths, any + trailing zero code lengths are omitted, i.e. the last + code length in the sequence must be non-zero. In this + case, the sum of (32 >> code length) over all the non-zero + code lengths must equal to 32. + + If the lengths have been read for the entire code length + alphabet and there was only one non-zero code length, + then the prefix code has one symbol whose code has zero + length. In this case, that symbol results in no bits + being emitted by the compressor, and no bits consumed by + the decompressor. That single symbol is immediately + returned when this code is decoded. + An example of where this occurs is if the + entire code to be represented has symbols of length 8. + E.g. a literal code that represents all literal values + with equal probability. In this case the single symbol + is 16, which repeats the previous length. The previous + length is taken to be 8 before any code length code + lengths are read. + + Sequence of at most alphabet size code lengths symbols, encoded + using the code length prefix code. Any trailing 0 or 17 must be + omitted, i.e. the last encoded code length symbol must be + between 1 and 16. The sum of (32768 >> code length) over + all the non-zero code lengths in the alphabet, including + those encoded using repeat code(s) of 16, must equal to + 32768. If the number of times to repeat the previous length + or repeat a zero length would result in more lengths in + total than the number of symbols in the alphabet, then the + stream should be rejected as invalid. +.fi + +.ti 0 +4. Encoding of distances + +As described in Section 2., one component of a compressed meta-block +is a sequence of backward distances. In this section we provide the +details to the encoding of distances. + +Each distance in the compressed data part of a meta-block is +represented with a pair . The distance +code and the extra bits are encoded back-to-back, the distance code +is encoded using a prefix code over the distance alphabet, +while the extra bits value is encoded as a fixed-width integer +value. The number of extra bits can be 0 - 24, and it is dependent +on the distance code. + +To convert a distance code and associated extra bits to a backward +distance, we need the sequence of past distances and two additional +parameters, the number of "postfix bits", denoted by NPOSTFIX (0..3), and +the number of direct distance codes, denoted by NDIRECT (0..120). Both of +these parameters are encoded in the meta-block header. We will also +use the following derived parameter: + +.nf + POSTFIX_MASK = (1 << NPOSTFIX) - 1 +.fi + +The first 16 distance symbols are special symbols that reference +past distances as follows: + +.nf + 0: last distance + 1: second-to-last distance + 2: third-to-last distance + 3: fourth-to-last distance + 4: last distance - 1 + 5: last distance + 1 + 6: last distance - 2 + 7: last distance + 2 + 8: last distance - 3 + 9: last distance + 3 + 10: second-to-last distance - 1 + 11: second-to-last distance + 1 + 12: second-to-last distance - 2 + 13: second-to-last distance + 2 + 14: second-to-last distance - 3 + 15: second-to-last distance + 3 +.fi + +The ring buffer of four last distances is initialized by the values +16, 15, 11, and 4 (i.e. the fourth-to-last is set to 16, the third-to-last +to 15, the second-to-last to 11, and the last distance to 4) at the +beginning of the *stream* (as opposed to the beginning of the meta-block) +and it is not reset at meta-block boundaries. When a distance +symbol 0 appears, the distance it represents (i.e. the last distance +in the sequence of distances) is not pushed to the ring buffer of +last distances, in other words, the expression "(second, third, +fourth)-to-last distance" means the (second, third, fourth)-to-last +distance that was not represented by a 0 distance symbol. Similarly, +distances that represent static dictionary words (see Section 8.) are +not pushed to the ring buffer of last distances. + +If a special distance symbol resolves to a zero or negative value, the +stream should be rejected as invalid. + +If NDIRECT is greater than zero, then the next NDIRECT distance symbols, +from 16 to 15 + NDIRECT, represent distances from 1 to NDIRECT. +Neither the special distance symbols, nor the NDIRECT direct distance +symbols are followed by any extra bits. + +Distance symbols 16 + NDIRECT and greater all have extra bits, where the +number of extra bits for a distance symbol "dcode" is given by the +following formula: + +.nf + ndistbits = 1 + ((dcode - NDIRECT - 16) >> (NPOSTFIX + 1)) +.fi + +The maximum number of extra bits is 24, therefore the size of the +distance symbol alphabet is (16 + NDIRECT + (48 << NPOSTFIX)). + +Given a distance symbol "dcode" (>= 16 + NDIRECT), and extra bits +"dextra", the backward distance is given by the following formula: + +.nf + hcode = (dcode - NDIRECT - 16) >> NPOSTFIX + lcode = (dcode - NDIRECT - 16) & POSTFIX_MASK + offset = ((2 + (hcode & 1)) << ndistbits) - 4 + distance = ((offset + dextra) << NPOSTFIX) + lcode + NDIRECT + 1 +.fi + +.ti 0 +5. Encoding of literal insertion lengths and copy lengths + +As described in Section 2., the literal insertion lengths and backward +copy lengths are encoded using a single prefix code. This section +provides the details to this encoding. + +Each pair in the compressed data part +of a meta-block is represented with the following triplet: + +.nf + +.fi + +The insert-and-copy length code, the insert extra bits, and the copy +extra bits are encoded back-to-back, the insert-and-copy length code +is encoded using a prefix code over the insert-and-copy length code +alphabet, while the extra bits values are encoded as fixed-width +integer values. The number of insert and copy extra bits can be +0 - 24, and they are dependent on the insert-and-copy length code. + +Some of the insert-and-copy length codes also express the fact that +the distance symbol of the distance in the same command is 0, i.e. the +distance component of the command is the same as that of the previous +command. In this case, the distance code and extra bits for the +distance are omitted from the compressed data stream. + +We describe the insert-and-copy length code alphabet in terms of the +(not directly used) insert length code and copy length code +alphabets. The symbols of the insert length code alphabet, along with +the number of insert extra bits, and the range of the insert lengths +are as follows: + +.nf +.KS + Extra Extra Extra + Code Bits Lengths Code Bits Lengths Code Bits Lengths + ---- ---- ------ ---- ---- ------- ---- ---- ------- + 0 0 0 8 2 10-13 16 6 130-193 + 1 0 1 9 2 14-17 17 7 194-321 + 2 0 2 10 3 18-25 18 8 322-577 + 3 0 3 11 3 26-33 19 9 578-1089 + 4 0 4 12 4 34-49 20 10 1090-2113 + 5 0 5 13 4 50-65 21 12 2114-6209 + 6 1 6,7 14 5 66-97 22 14 6210-22593 + 7 1 8,9 15 5 98-129 23 24 22594-16799809 +.KE +.fi + +The symbols of the copy length code alphabet, along with the number +of copy extra bits, and the range of copy lengths are as follows: + +.nf +.KS + Extra Extra Extra + Code Bits Lengths Code Bits Lengths Code Bits Lengths + ---- ---- ------ ---- ---- ------- ---- ---- ------- + 0 0 2 8 1 10,11 16 5 70-101 + 1 0 3 9 1 12,13 17 5 102-133 + 2 0 4 10 2 14-17 18 6 134-197 + 3 0 5 11 2 18-21 19 7 198-325 + 4 0 6 12 3 22-29 20 8 326-581 + 5 0 7 13 3 30-37 21 9 582-1093 + 6 0 8 14 4 38-53 22 10 1094-2117 + 7 0 9 15 4 54-69 23 24 2118-16779333 +.KE +.fi + +To convert an insert-and-copy length code to an insert length code +and a copy length code, the following table can be used: + +.nf +.KS + Insert + length Copy length code + code 0-7 8-15 16-23 + +---------+---------+ + | | | + 0-7 | 0-63 | 64-127 | <--- distance symbol 0 + | | | + +---------+---------+---------+ + | | | | + 0-7 | 128-191 | 192-255 | 384-447 | + | | | | + +---------+---------+---------+ + | | | | + 8-15 | 256-319 | 320-383 | 512-575 | + | | | | + +---------+---------+---------+ + | | | | + 16-23 | 448-511 | 576-639 | 640-703 | + | | | | + +---------+---------+---------+ +.KE +.fi + +First, look up the cell with the 64 value range containing the +insert-and-copy length code, this gives the insert length code and +the copy length code ranges, both 8 values long. +The copy length code within its range is determined by bits 0-2 +(counted from the LSB) of the insert-and-copy length code. +The insert length code within its range is determined by bits 3-5 +(counted from the LSB) of the insert-and-copy length code. +Given the insert length and copy length codes, the actual insert +and copy lengths can be obtained by reading the number of extra +bits given by the tables above. + +If the insert-and-copy length code is between 0 and 127, the distance +code of the command is set to zero (the last distance reused). + +.ti 0 +6. Encoding of block switch commands + +As described in Section 2., a block-switch command is a pair +. These are encoded in the compressed data +part of the meta-block, right before the start of each new block of a +particular block category. + +Each block type in the compressed data is represented with a block +type code, encoded using a prefix code over the block type code +alphabet. A block type symbol 0 means that the new block type is the same +as the type of the previous block from the same block category, i.e. +the block type that preceded the current type, +while a block type symbol 1 means that the new block type equals the current +block type plus one. If the current block type is the maximal possible, +then a block type symbol of 1 results in wrapping to a new block type of 0. +Block type symbols 2 - 257 +represent block types 0 - 255 respectively. The previous and current block types +are initialized to 1 and 0, respectively, at the end of the +meta-block header. + +Since the first block type of each block category is 0, the block +type of the first block-switch command is not encoded in +the compressed data. If a block category has only one block type, +the block count of the first block-switch command is also omitted from +the compressed data, otherwise it is encoded in the meta-block header. + +Since the end of the meta-block is detected by the number of uncompressed +bytes produced, the block counts for any of the three categories need not +count down to exactly zero at the end of the meta-block. + +The number of different block types in each block category, denoted +by NBLTYPESL, NBLTYPESI, and NBLTYPESD for literals, insert-and-copy +lengths, and distances, respectively, is encoded in the meta-block +header, and it must equal to the largest block type plus one in that +block category. In other words, the set of literal, insert-and-copy +length, and distance block types must be [0..NBLTYPESL-1], +[0..NBLTYPESI-1], and [0..NBLTYPESD-1], respectively. From this it +follows that the alphabet size of literal, insert-and-copy length, and +distance block type codes is NBLTYPESL + 2, NBLTYPESI + 2, and +NBLTYPESD + 2, respectively. + +Each block count in the compressed data is represented with a pair +. The block count code and the extra +bits are encoded back-to-back, the block count code is encoded using +a prefix code over the block count code alphabet, while the extra +bits value is encoded as a fixed-width integer value. The number of +extra bits can be 0 - 24, and it is dependent on the block count +code. The symbols of the block count code alphabet, along with the +number of extra bits, and the range of block counts are as follows: + +.nf +.KS + Extra Extra Extra + Code Bits Lengths Code Bits Lengths Code Bits Lengths + ---- ---- ------ ---- ---- ------- ---- ---- ------- + 0 2 1-4 9 4 65-80 18 7 369-496 + 1 2 5-8 10 4 81-96 19 8 497-752 + 2 2 9-12 11 4 97-112 20 9 753-1264 + 3 2 13-16 12 5 113-144 21 10 1265-2288 + 4 3 17-24 13 5 145-176 22 11 2289-4336 + 5 3 25-32 14 5 177-208 23 12 4337-8432 + 6 3 33-40 15 5 209-240 24 13 8433-16624 + 7 3 41-48 16 6 241-304 25 24 16625-16793840 + 8 4 49-64 17 6 305-368 +.KE +.fi + +The first block-switch command of each block category is special in +the sense that it is encoded in the meta-block header, and as +described earlier, the block type code is omitted since it is an +implicit zero. + +.ti 0 +7. Context modeling + +As described in Section 2., the prefix tree used to encode a literal +byte or a distance code depends on the block type and the context ID. +This section specifies how to compute the context ID for a particular +literal and distance code, and how to encode the context map that +maps a pair to the index of a prefix +code in the array of literal and distance prefix codes. + +.ti 0 +7.1. Context modes and context ID lookup for literals + +The context for encoding the next literal is defined by the last +two bytes in the stream (p1, p2, where p1 is the most recent +byte), regardless of whether these bytes are produced by +uncompressed meta-blocks, backward references, static dictionary +references, or by literal insertions. At the start of the stream +p1 and p2 are initialized to zero. + +There are four methods, called context modes, to compute the +Context ID: + +.nf + * LSB6, where the Context ID is the value of six + least-significant bits of p1, + * MSB6, where the Context ID is the value of six + most-significant bits of p1, + * UTF8, where the Context ID is a complex function of p1, p2, + optimized for text compression, and + * Signed, where Context ID is a complex function of p1, p2, + optimized for compressing sequences of signed integers. +.fi + +The Context ID for the UTF8 and Signed context modes is computed +using the following lookup tables Lut0, Lut1, and Lut2. + +.nf + Lut0 := + 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 0, 0, 4, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 8, 12, 16, 12, 12, 20, 12, 16, 24, 28, 12, 12, 32, 12, 36, 12, + 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 32, 32, 24, 40, 28, 12, + 12, 48, 52, 52, 52, 48, 52, 52, 52, 48, 52, 52, 52, 52, 52, 48, + 52, 52, 52, 52, 52, 48, 52, 52, 52, 52, 52, 24, 12, 28, 12, 12, + 12, 56, 60, 60, 60, 56, 60, 60, 60, 56, 60, 60, 60, 60, 60, 56, + 60, 60, 60, 60, 60, 56, 60, 60, 60, 60, 60, 24, 12, 28, 12, 0, + 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, + 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, + 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, + 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, + 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, + 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, + 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, + 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3 + + Lut1 := + 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, 0, 0, 0, 0, 0, 0, + 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, + 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, + 1, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 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, 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, 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, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2 + + Lut2 := + 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 7 +.fi + +The lengths and the zlib CRC-32 (ITU-T Recommendation V.42) check values +of each of these tables as a sequence of bytes are as follows: + +.nf + Table Length CRC-32 + ----- ------ ------ + Lut0 256 0x8e91efb7 + Lut1 256 0xd01a32f4 + Lut2 256 0x0dd7a0d6 +.fi + +Given p1 is the last uncompressed byte and p2 is the second-to-last +uncompressed byte, the context IDs can be computed as follows: + +.nf + For LSB6: Context ID = p1 & 0x3f + For MSB6: Context ID = p1 >> 2 + For UTF8: Context ID = Lut0[p1] | Lut1[p2] + For Signed: Context ID = (Lut2[p1] << 3) | Lut2[p2] +.fi + +From the lookup tables defined above and the operations to compute the +context IDs, we can see that context IDs for literals are in the range +of 0..63. + +The context modes LSB6, MSB6, UTF8, and Signed are denoted by +integers 0, 1, 2, 3. + +A context mode is defined for each literal block type and they +are stored in a consecutive array of bits in the meta-block +header, always two bits per block type. + +.ti 0 +7.2. Context ID for distances + +The context for encoding a distance code is defined by the copy +length corresponding to the distance. The context IDs are 0, 1, 2, +and 3 for copy lengths 2, 3, 4, and more than 4, respectively. + +.ti 0 +7.3. Encoding of the context map + +There are two context maps, one for literals and one for +distances. The size of the context map is 64 * NBLTYPESL for +literals, and 4 * NBLTYPESD for distances. Each value in the +context map is an integer between 0 and 255, indicating the index +of the prefix code to be used when encoding the next literal or +distance. + +The context maps are two-dimensional matrices, encoded as +one-dimensional arrays: + +.nf + CMAPL[0..(64 * NBLTYPESL - 1)] + CMAPD[0..(4 * NBLTYPESD - 1)] +.fi + +The index of the prefix code for encoding a literal or distance +code with block type, BTYPE_x, and context ID, CIDx, is: + +.nf + index of literal prefix code = CMAPL[64 * BTYPE_L + CIDL] + index of distance prefix code = CMAPD[4 * BTYPE_D + CIDD] +.fi + +The values of the context map are encoded with the combination +of run length encoding for zero values and prefix coding. Let +RLEMAX denote the number of run length codes and NTREES denote the +maximum value in the context map plus one. NTREES must equal the +number of different values in the context map, in other words, +the different values in the context map must be the [0..NTREES-1] +interval. The alphabet of the prefix code has the following +RLEMAX + NTREES symbols: + +.nf + 0: value zero + 1: repeat a zero 2 to 3 times, read 1 bit for repeat length + 2: repeat a zero 4 to 7 times, read 2 bits for repeat length + ... + RLEMAX: repeat a zero (1 << RLEMAX) to (1 << (RLEMAX+1))-1 + times, read RLEMAX bits for repeat length + RLEMAX + 1: value 1 + ... + RLEMAX + NTREES - 1: value NTREES - 1 +.fi + +If RLEMAX = 0, the run length coding is not used, and the symbols +of the alphabet are directly the values in the context map. We can +now define the format of the context map (the same format is used +for literal and distance context maps): + +.nf + 1-5 bits: RLEMAX, 0 is encoded with one 0 bit, and values + 1 - 16 are encoded with bit pattern xxxx1 (so 01001 + is 5) + + Prefix code with alphabet size NTREES + RLEMAX + + Context map size values encoded with the above prefix code + and run length coding for zero values. If a run length + would result in more lengths in total than the size of + the context map, then the stream should be rejected as + invalid. + + 1 bit: IMTF bit, if set, we do an inverse move-to-front + transform on the values in the context map to get + the prefix code indexes +.fi + +Note that RLEMAX may be larger than the value necessary to represent +the longest sequence of zero values. Also, the NTREES value is encoded +right before the context map as described in Section 9.2. + +We define the inverse move-to-front transform used in this specification +by the following C language function: + +.nf + void InverseMoveToFrontTransform(uint8_t* v, int v_len) { + uint8_t mtf[256]; + int i; + for (i = 0; i < 256; ++i) { + mtf[i] = (uint8_t)i; + } + for (i = 0; i < v_len; ++i) { + uint8_t index = v[i]; + uint8_t value = mtf[index]; + v[i] = value; + for (; index; --index) { + mtf[index] = mtf[index - 1]; + } + mtf[0] = value; + } + } +.fi + +Note that the inverse move-to-front transform will not produce values +outside the [0..NTREES-1] interval. + +.ti 0 +8. Static dictionary + +At any given point during decoding the compressed data, a reference +to a duplicated string in the uncompressed data produced so far has a maximum +backward distance value, which is the minimum of the window size and +the number of uncompressed bytes produced. However, decoding a distance +from the compressed stream, as described in Section 4., can produce +distances that are greater than this maximum allowed value. In this case, +the distance is treated as a reference to a word in the static dictionary +given in Appendix A. The copy length for a static dictionary reference +must be between 4 and 24. The static dictionary has three parts: + +.nf + * DICT[0..DICTSIZE], an array of bytes + * DOFFSET[0..24], an array of byte offset values for each length + * NDBITS[0..24], an array of bit-depth values for each length +.fi + +The number of static dictionary words for a given length is: + +.nf + NWORDS[length] = 0 (if length < 4) + NWORDS[length] = (1 << NDBITS[length]) (if length >= 4) +.fi + +DOFFSET and DICTSIZE are defined by the following recursion: + +.nf + DOFFSET[0] = 0 + DOFFSET[length + 1] = DOFFSET[length] + length * NWORDS[length] + DICTSIZE = DOFFSET[24] + 24 * NWORDS[24] +.fi + +The offset of a word within the DICT array for a given length and +index is: + +.nf + offset(length, index) = DOFFSET[length] + index * length +.fi + +Each static dictionary word has 121 different forms, given by +applying a word transformation to a base word in the DICT array. The +list of word transformations is given in Appendix B. The static +dictionary word for a pair can be reconstructed as +follows: + +.nf + word_id = distance - (max allowed distance + 1) + index = word_id % NWORDS[length] + base_word = DICT[offset(length, index)..offset(length, index+1)-1] + transform_id = word_id >> NDBITS[length] +.fi + +The string copied to the uncompressed stream is computed by applying the +transformation to the base dictionary word. If transform_id is +greater than 120, or the length is smaller than 4 or greater than 24, then +the compressed stream should be rejected as invalid. + +Each word transformation has the following form: + +.nf + transform_i(word) = prefix_i + T_i(word) + suffix_i +.fi + +where the _i subscript denotes the transform_id above. Each T_i +is one of the following 21 elementary transforms: + +.nf + Identity, UppercaseFirst, UppercaseAll, + OmitFirst1, ..., OmitFirst9, OmitLast1, ..., OmitLast9 +.fi + +The form of these elementary transforms is as follows: + +.nf + Identity(word) = word + + UppercaseFirst(word) = first UTF-8 character of word upper-cased + + UppercaseAll(word) = all UTF-8 characters of word upper-cased + + OmitFirstk(word) = the last (length(word) - k) bytes of word, or + empty string if length(word) < k + + OmitLastk(word) = the first (length(word) - k) bytes of word, or + empty string if length(word) < k +.fi + +For the purposes of UppercaseAll, word is parsed into UTF-8 +characters and converted to upper-case by taking 1 - 3 bytes at a time, +using the algorithm below: + +.nf +.KS + i = 0 + while i < length(word): + if word[i] < 192: + if word[i] >= 97 and word[i] <= 122: + word[i] = word[i] ^ 32 + i = i + 1 + else if word[i] < 224: + if i + 1 < length(word): + word[i + 1] = word[i + 1] ^ 32 + i = i + 2 + else: + if i + 2 < length(word): + word[i + 2] = word[i + 2] ^ 5 + i = i + 3 +.KE +.fi + +For UppercaseFirst, the same algorithm is used, but the loop is +executed only once. + +Appendix B. contains the list of transformations by specifying the +prefix, elementary transform and suffix components of each of them. +Note that the OmitFirst8 elementary transform is not used in the list +of transformations. The strings in Appendix B. are in C string format +with respect to escape (backslash) characters. + +The maximum number of additional bytes that a transform may add to a +base word is 13. Since the largest base word is 24 bytes long, a buffer +of 38 bytes is sufficient to store any transformed words +(counting a terminating zero byte). + +.ti 0 +9. Compressed data format + +In this section we describe the format of the compressed data set in +terms of the format of the individual data items described in the +previous sections. + +.ti 0 +9.1. Format of the stream header + +The stream header has only the following one field: + +.nf + 1-7 bits: WBITS, a value in the range 10 - 24, encoded with + the following variable length code (as it appears in + the compressed data, where the bits are parsed from + right to left): + + Value Bit Pattern + ----- ----------- + 10 0100001 + 11 0110001 + 12 1000001 + 13 1010001 + 14 1100001 + 15 1110001 + 16 0 + 17 0000001 + 18 0011 + 19 0101 + 20 0111 + 21 1001 + 22 1011 + 23 1101 + 24 1111 + + Note that bit pattern 0010001 is invalid and must not + be used. +.fi + +The size of the sliding window, which is the maximum value of any +non-dictionary reference backward distance, is given by the +following formula: + +.nf + window size = (1 << WBITS) - 16 +.fi + +.ti 0 +9.2. Format of the meta-block header + +A compliant compressed data set has at least one meta-block. Each +meta-block contains a header with information about the +uncompressed length of the meta-block, and a bit signaling if the +meta-block is the last one. The format of the meta-block header is +the following: + +.nf + 1 bit: ISLAST, set to 1 if this is the last meta-block + 1 bit: ISLASTEMPTY, if set to 1, the meta-block is empty; + this field is only present if ISLAST bit is set -- if + it is 1, then the meta-block and the brotli stream ends + at that bit, with any remaining bits in the last byte + of the compressed stream filled with zeros (if the + fill bits are not zero, then the stream should be + rejected as invalid) + 2 bits: MNIBBLES, # of nibbles to represent the uncompressed + length, encoded with the following fixed-length code: + + Value Bit Pattern + ----- ----------- + 0 11 + 4 00 + 5 01 + 6 10 + + If MNIBBLES is 0, the meta-block is empty, i.e. it does + not generate any uncompressed data. In this case, the + rest of the meta-block has the following format: + + 1 bit: reserved, must be zero + + 2 bits: MSKIPBYTES, # of bytes to represent metadata + length + + MSKIPBYTES x 8 bits: MSKIPLEN - 1, where MSKIPLEN is + the number of metadata bytes; this field is + only present if MSKIPBYTES is positive, + otherwise MSKIPLEN is 0 (if MSKIPBYTES is + greater than 1, and the last byte is all + zeros, then the stream should be rejected + as invalid) + + 0 - 7 bits: fill bits until the next byte boundary, + must be all zeros + + MSKIPLEN bytes of metadata, not part of the + uncompressed data or the sliding window + + MNIBBLES x 4 bits: MLEN - 1, where MLEN is the length + of the meta-block uncompressed data in bytes (if + MNIBBLES is greater than 4, and the last + nibble is all zeros, then the stream should be + rejected as invalid) + + 1 bit: ISUNCOMPRESSED, if set to 1, any bits of compressed + data up to the next byte boundary are ignored, and + the rest of the meta-block contains MLEN bytes of + literal data; this field is only present if the + ISLAST bit is not set (if the ignored bits are not + all zeros, the stream should be rejected as invalid) + + 1-11 bits: NBLTYPESL, # of literal block types, encoded with + the following variable length code (as it appears in + the compressed data, where the bits are parsed from + right to left, so 0110111 has the value 12): + + Value Bit Pattern + ----- ----------- + 1 0 + 2 0001 + 3-4 x0011 + 5-8 xx0101 + 9-16 xxx0111 + 17-32 xxxx1001 + 33-64 xxxxx1011 + 65-128 xxxxxx1101 + 129-256 xxxxxxx1111 + + Prefix code over the block type code alphabet for + literal block types, appears only if NBLTYPESL >= 2 + + Prefix code over the block count code alphabet for + literal block counts, appears only if NBLTYPESL >= 2 + + Block count code + extra bits for first literal + block count, appears only if NBLTYPESL >= 2 + + 1-11 bits: NBLTYPESI, # of insert-and-copy block types, encoded + with the same variable length code as above + + Prefix code over the block type code alphabet for + insert-and-copy block types, appears only if NBLTYPESI >= 2 + + Prefix code over the block count code alphabet for + insert-and-copy block counts, appears only if NBLTYPESI >= 2 + + Block count code + extra bits for first insert-and-copy + block count, appears only if NBLTYPESI >= 2 + + 1-11 bits: NBLTYPESD, # of distance block types, encoded + with the same variable length code as above + + Prefix code over the block type code alphabet for + distance block types, appears only if NBLTYPESD >= 2 + + Prefix code over the block count code alphabet for + distance block counts, appears only if NBLTYPESD >= 2 + + Block count code + extra bits for first distance + block count, appears only if NBLTYPESD >= 2 + + 2 bits: NPOSTFIX, parameter used in the distance coding + + 4 bits: four most-significant bits of NDIRECT, to get the + actual value of the parameter NDIRECT, left-shift + this four-bit number by NPOSTFIX bits + + NBLTYPESL x 2 bits: context mode for each literal block type + + 1-11 bits: NTREESL, # of literal prefix trees, encoded + with the same variable length code as NBLTYPESL + + Literal context map, encoded as described in Section 7.3., + appears only if NTREESL >= 2, otherwise the context map + has only zero values + + 1-11 bits: NTREESD, # of distance prefix trees, encoded + with the same variable length code as NBLTYPESD + + Distance context map, encoded as described in Section 7.3., + appears only if NTREESD >= 2, otherwise the context map + has only zero values + + NTREESL prefix codes for literals + + NBLTYPESI prefix codes for insert-and-copy lengths + + NTREESD prefix codes for distances +.fi + +.ti 0 +9.3. Format of the meta-block data + +The compressed data part of a meta-block consists of a series of +commands. Each command has the following format: + +.nf + Block type code for next insert-and-copy block type, appears + only if NBLTYPESI >= 2 and the previous insert-and-copy + block count is zero + + Block count code + extra bits for next insert-and-copy + block count, appears only if NBLTYPESI >= 2 and the + previous insert-and-copy block count is zero + + Insert-and-copy length, encoded as in Section 5., using the + insert-and-copy length prefix code with the current + insert-and-copy block type index + + Insert length number of literals, with the following format: + + Block type code for next literal block type, appears + only if NBLTYPESL >= 2 and the previous literal + block count is zero + + Block count code + extra bits for next literal + block count, appears only if NBLTYPESL >= 2 and the + previous literal block count is zero + + Next byte of the uncompressed data, encoded with the + literal prefix code with the index determined by the + previous two bytes of the uncompressed data, the + current literal block type, and the context map, as + described in Section 7.3. + + Block type code for next distance block type, appears + only if NBLTYPESD >= 2 and the previous distance + block count is zero + + Block count code + extra bits for next distance + block count, appears only if NBLTYPESD >= 2 and the + previous distance block count is zero + + Distance code, encoded as in Section 4., using the distance + prefix code with the current distance block type index, + appears only if the distance code is not an implicit 0, + as indicated by the insert-and-copy length code +.fi + +The number of commands in the meta-block is such that the sum of +the uncompressed bytes produced (i.e. the number of literals inserted +plus the number of bytes copied from past data or generated from the +static dictionary) over all the commands gives the uncompressed length, +MLEN encoded in the meta-block header. + +If the total number of uncompressed bytes produced after the insert part +of the last command equals MLEN, then the copy length of the last command +is ignored and will not produce any uncompressed output. In this case the +copy length of the last command can have any value. In any other case, if +the number of literals to insert, the copy length, or the resulting +dictionary word length would cause MLEN to be exceeded, then the stream +should be rejected as invalid. + +If the last command of the last non-empty meta-block does not end on +a byte boundary, the unused bits in the last byte must be zeros. + +.ti 0 +10. Decoding algorithm + +The decoding algorithm that produces the uncompressed data is as follows: + +.nf + read window size + do + read ISLAST bit + if ISLAST + read ISLASTEMPTY bit + if ISLASTEMPTY + break from loop + read MNIBBLES + if MNIBBLES is zero + verify reserved bit is zero + read MSKIPLEN + skip any bits up to the next byte boundary + skip MSKIPLEN bytes + continue to the next meta-block + else + read MLEN + if not ISLAST + read ISUNCOMPRESSED bit + if ISUNCOMPRESSED + skip any bits up to the next byte boundary + copy MLEN bytes of compressed data as literals + continue to the next meta-block + loop for each three block categories (i = L, I, D) + read NBLTYPESi + if NBLTYPESi >= 2 + read prefix code for block types, HTREE_BTYPE_i + read prefix code for block counts, HTREE_BLEN_i + read block count, BLEN_i + set block type, BTYPE_i to 0 + initialize second-to-last and last block types to 0 and 1 + else + set block type, BTYPE_i to 0 + set block count, BLEN_i to 16777216 + read NPOSTFIX and NDIRECT + read array of literal context modes, CMODE[] + read NTREESL + if NTREESL >= 2 + read literal context map, CMAPL[] + else + fill CMAPL[] with zeros + read NTREESD + if NTREESD >= 2 + read distance context map, CMAPD[] + else + fill CMAPD[] with zeros + read array of literal prefix codes, HTREEL[] + read array of insert-and-copy length prefix codes, HTREEI[] + read array of distance prefix codes, HTREED[] + do + if BLEN_I is zero + read block type using HTREE_BTYPE_I and set BTYPE_I + save previous block type + read block count using HTREE_BLEN_I and set BLEN_I + decrement BLEN_I + read insert-and-copy length symbol using HTREEI[BTYPE_I] + compute insert length, ILEN, and copy length, CLEN + loop for ILEN + if BLEN_L is zero + read block type using HTREE_BTYPE_L and set BTYPE_L + save previous block type + read block count using HTREE_BLEN_L and set BLEN_L + decrement BLEN_L + look up context mode CMODE[BTYPE_L] + compute context ID, CIDL from last two uncompressed bytes + read literal using HTREEL[CMAPL[64*BTYPE_L + CIDL]] + write literal to uncompressed stream + if number of uncompressed bytes produced in the loop for + this meta-block is MLEN, then break from loop (in this + case the copy length is ignored and can have any value) + if distance code is implicit zero from insert-and-copy code + set backward distance to the last distance + else + if BLEN_D is zero + read block type using HTREE_BTYPE_D and set BTYPE_D + save previous block type + read block count using HTREE_BLEN_D and set BLEN_D + decrement BLEN_D + compute context ID, CIDD from CLEN + read distance code using HTREED[CMAPD[4*BTYPE_D + CIDD]] + compute distance by distance short code substitution + if distance code is not zero, + and distance is not a static dictionary reference, + push distance to the ring buffer of last distances + if distance is less than the max allowed distance plus one + move backwards distance bytes in the uncompressed data, + and copy CLEN bytes from this position to + the uncompressed stream + else + look up the static dictionary word, transform the word as + directed, and copy the result to the uncompressed stream + while number of uncompressed bytes for this meta-block < MLEN + while not ISLAST +.fi + +If the stream ends before the completion of the last meta-block, then +the stream should be rejected as invalid. + +Note that a duplicated string reference may refer to a string in a +previous meta-block, i.e. the backward distance may cross one or +more meta-block boundaries. However a backward copy distance +will not refer past the beginning of the uncompressed stream or the +window size; any such distance is +interpreted as a reference to a static dictionary word. Also note +that the referenced string may overlap the current position, for +example, if the last 2 bytes decoded have values X and Y, a string +reference with adds X,Y,X,Y,X to the +uncompressed stream. + +.ti 0 +11. Security Considerations + +As with any compressed file formats, decompressor implementations should +handle all compressed data byte sequences, not only those that conform to this +specification, where non-conformant compressed data sequences should be discarded. +A possible attack against a system containing a decompressor +implementation (e.g. a web browser) is to exploit a buffer +overflow caused by an invalid compressed data. Therefore decompressor +implementations should perform bounds-checking for each memory access +that result from values decoded from the compressed stream. + +.ti 0 +12. IANA Considerations + +The "HTTP Content Coding Registry" has been updated with the +registration below: + +.nf +.KS + +-------+-------------------------------------+------------+ + | Name | Description | Reference | + +-------+-------------------------------------+------------+ + | br | Brotli Compressed Data Format | RFCXXXX | + +-------+-------------------------------------+------------+ +.KE +.fi + +.ti 0 +13. Informative References +.in 14 + +.ti 3 +[HUFFMAN] Huffman, D. A., "A Method for the Construction of Minimum +Redundancy Codes", Proceedings of the Institute of Radio +Engineers, September 1952, Volume 40, Number 9, pp. 1098-1101. + +.ti 3 +[LZ77] Ziv J., Lempel A., "A Universal Algorithm for Sequential Data +Compression", IEEE Transactions on Information Theory, Vol. 23, +No. 3, pp. 337-343. + +.ti 3 +[RFC1951] Deutsch, P., "DEFLATE Compressed Data Format Specification +version 1.3", RFC 1951, Aladdin Enterprises, May 1996. +http://www.ietf.org/rfc/rfc1951.txt + +.ti 3 +[WOFF2] Levantovsky, V. (ed.), Levien, R. (ed.), "WOFF File Format +2.0", W3C WebFonts Working Group, http://www.w3.org/TR/WOFF2/ +.in 3 + +.ti 0 +14. Source code + +Source code for a C language implementation of a brotli compliant +decompressor and a C++ language implementation of a compressor is +available in the brotli open-source project: +https://github.com/google/brotli + +.ti 0 +15. Acknowledgments + +The authors would like to thank Mark Adler, Robert Obryk, Thomas +Pickert, and Joe Tsai for providing helpful review comments, +validating the specification by writing an independent decompressor, +and suggesting improvements to the format and the text of the +specification. + +.ti 0 +Appendix A. Static dictionary data + +The hexadecimal form of the DICT array is the following, where the +length is 122,784 bytes and the zlib CRC-32 of the byte sequence is +0x5136cb04. + +.in 0 +.nf + 74696d65646f776e6c6966656c6566746261636b636f64656461746173686f77 + 6f6e6c7973697465636974796f70656e6a7573746c696b6566726565776f726b + 74657874796561726f766572626f64796c6f7665666f726d626f6f6b706c6179 + 6c6976656c696e6568656c70686f6d65736964656d6f7265776f72646c6f6e67 + 7468656d7669657766696e64706167656461797366756c6c686561647465726d + 656163686172656166726f6d747275656d61726b61626c6575706f6e68696768 + 646174656c616e646e6577736576656e6e65787463617365626f7468706f7374 + 757365646d61646568616e6468657265776861746e616d654c696e6b626c6f67 + 73697a656261736568656c646d616b656d61696e757365722729202b686f6c64 + 656e6473776974684e65777372656164776572657369676e74616b6568617665 + 67616d657365656e63616c6c7061746877656c6c706c75736d656e7566696c6d + 706172746a6f696e746869736c697374676f6f646e6565647761797377657374 + 6a6f62736d696e64616c736f6c6f676f72696368757365736c6173747465616d + 61726d79666f6f646b696e6777696c6c65617374776172646265737466697265 + 506167656b6e6f77617761792e706e676d6f76657468616e6c6f616467697665 + 73656c666e6f74656d756368666565646d616e79726f636b69636f6e6f6e6365 + 6c6f6f6b6869646564696564486f6d6572756c65686f7374616a6178696e666f + 636c75626c6177736c65737368616c66736f6d65737563687a6f6e6531303025 + 6f6e65736361726554696d6572616365626c7565666f75727765656b66616365 + 686f706567617665686172646c6f73747768656e7061726b6b65707470617373 + 73686970726f6f6d48544d4c706c616e54797065646f6e65736176656b656570 + 666c61676c696e6b736f6c6466697665746f6f6b72617465746f776e6a756d70 + 746875736461726b6361726466696c6566656172737461796b696c6c74686174 + 66616c6c6175746f657665722e636f6d74616c6b73686f70766f746564656570 + 6d6f6465726573747475726e626f726e62616e6466656c6c726f736575726c28 + 736b696e726f6c65636f6d6561637473616765736d656574676f6c642e6a7067 + 6974656d7661727966656c747468656e73656e6464726f7056696577636f7079 + 312e30223c2f613e73746f70656c73656c696573746f75727061636b2e676966 + 706173746373733f677261796d65616e2667743b7269646573686f746c617465 + 73616964726f6164766172206665656c6a6f686e7269636b706f727466617374 + 2755412d646561643c2f623e706f6f7262696c6c74797065552e532e776f6f64 + 6d7573743270783b496e666f72616e6b7769646577616e7477616c6c6c656164 + 5b305d3b7061756c776176657375726524282723776169746d61737361726d73 + 676f65736761696e6c616e6770616964212d2d206c6f636b756e6974726f6f74 + 77616c6b6669726d77696665786d6c22736f6e6774657374323070786b696e64 + 726f7773746f6f6c666f6e746d61696c73616665737461726d617073636f7265 + 7261696e666c6f77626162797370616e736179733470783b3670783b61727473 + 666f6f747265616c77696b696865617473746570747269706f72672f6c616b65 + 7765616b746f6c64466f726d6361737466616e7362616e6b7665727972756e73 + 6a756c797461736b3170783b676f616c67726577736c6f776564676569643d22 + 736574733570783b2e6a733f3430707869662028736f6f6e736561746e6f6e65 + 747562657a65726f73656e747265656466616374696e746f676966746861726d + 3138707863616d6568696c6c626f6c647a6f6f6d766f69646561737972696e67 + 66696c6c7065616b696e6974636f73743370783b6a61636b7461677362697473 + 726f6c6c656469746b6e65776e6561723c212d2d67726f774a534f4e64757479 + 4e616d6573616c65796f75206c6f74737061696e6a617a7a636f6c6465796573 + 666973687777772e7269736b7461627370726576313070787269736532357078 + 426c756564696e673330302c62616c6c666f72646561726e77696c64626f782e + 666169726c61636b76657273706169726a756e6574656368696628217069636b + 6576696c242822237761726d6c6f7264646f657370756c6c2c30303069646561 + 647261776875676573706f7466756e646275726e6872656663656c6c6b657973 + 7469636b686f75726c6f73736675656c31327078737569746465616c52535322 + 6167656467726579474554226561736561696d736769726c616964733870783b + 6e617679677269647469707323393939776172736c61647963617273293b207d + 7068703f68656c6c74616c6c77686f6d7a683ae52a2f0d0a2031303068616c6c + 2e0a0a413770783b70757368636861743070783b637265772a2f3c2f68617368 + 37357078666c6174726172652026262074656c6c63616d706f6e746f6c616964 + 6d697373736b697074656e7466696e656d616c6567657473706c6f743430302c + 0d0a0d0a636f6f6c666565742e7068703c62723e657269636d6f737467756964 + 62656c6c64657363686169726d61746861746f6d2f696d67262338326c75636b + 63656e743030303b74696e79676f6e6568746d6c73656c6c6472756746524545 + 6e6f64656e69636b3f69643d6c6f73656e756c6c7661737477696e6452535320 + 7765617272656c796265656e73616d6564756b656e6173616361706577697368 + 67756c665432333a68697473736c6f74676174656b69636b626c757274686579 + 313570782727293b293b223e6d73696577696e7362697264736f727462657461 + 7365656b5431383a6f726473747265656d616c6c363070786661726de2809973 + 626f79735b305d2e27293b22504f5354626561726b696473293b7d7d6d617279 + 74656e6428554b29717561647a683ae62d73697a2d2d2d2d70726f7027293b0d + 6c6966745431393a76696365616e6479646562743e525353706f6f6c6e65636b + 626c6f775431363a646f6f726576616c5431373a6c6574736661696c6f72616c + 706f6c6c6e6f7661636f6c7367656e6520e28094736f6674726f6d6574696c6c + 726f73733c68333e706f75726661646570696e6b3c74723e6d696e69297c2128 + 6d696e657a683ae862617273686561723030293b6d696c6b202d2d3e69726f6e + 667265646469736b77656e74736f696c707574732f6a732f686f6c795432323a + 4953424e5432303a6164616d736565733c68323e6a736f6e272c2027636f6e74 + 5432313a205253536c6f6f70617369616d6f6f6e3c2f703e736f756c4c494e45 + 666f7274636172745431343a3c68313e38307078212d2d3c3970783b5430343a + 6d696b653a34365a6e696365696e6368596f726b726963657a683ae42729293b + 707572656d61676570617261746f6e65626f6e643a33375a5f6f665f275d293b + 3030302c7a683ae774616e6b79617264626f776c627573683a35365a4a617661 + 333070780a7c7d0a254333253a33345a6a656666455850496361736876697361 + 676f6c66736e6f777a683ae9717565722e6373737369636b6d6561746d696e2e + 62696e6464656c6c686972657069637372656e743a33365a485454502d323031 + 666f746f776f6c66454e442078626f783a35345a424f44596469636b3b0a7d0a + 657869743a33355a7661727362656174277d293b646965743939393b616e6e65 + 7d7d3c2f5b695d2e4c616e676b6dc2b277697265746f7973616464737365616c + 616c65783b0a097d6563686f6e696e652e6f726730303529746f6e796a657773 + 73616e646c656773726f6f66303030292032303077696e6567656172646f6773 + 626f6f74676172796375747374796c6574656d7074696f6e2e786d6c636f636b + 67616e672428272e3530707850682e446d697363616c616e6c6f616e6465736b + 6d696c657279616e756e697864697363293b7d0a64757374636c6970292e0a0a + 373070782d32303044564473375d3e3c7461706564656d6f692b2b2977616765 + 6575726f7068696c6f707473686f6c65464151736173696e2d3236546c616273 + 7065747355524c2062756c6b636f6f6b3b7d0d0a484541445b305d2961626272 + 6a75616e283139386c6573687477696e3c2f693e736f6e79677579736675636b + 706970657c2d0a21303032296e646f775b315d3b5b5d3b0a4c6f672073616c74 + 0d0a090962616e677472696d62617468297b0d0a303070780a7d293b6b6f3aec + 6665657361643e0d733a2f2f205b5d3b746f6c6c706c756728297b0a7b0d0a20 + 2e6a7327323030706475616c626f61742e4a5047293b0a7d71756f74293b0a0a + 27293b0a0d0a7d0d323031343230313532303136323031373230313832303139 + 3230323032303231323032323230323332303234323032353230323632303237 + 3230323832303239323033303230333132303332323033333230333432303335 + 3230333632303337323031333230313232303131323031303230303932303038 + 3230303732303036323030353230303432303033323030323230303132303030 + 3139393931393938313939373139393631393935313939343139393331393932 + 3139393131393930313938393139383831393837313938363139383531393834 + 3139383331393832313938313139383031393739313937383139373731393736 + 3139373531393734313937333139373231393731313937303139363931393638 + 3139363731393636313936353139363431393633313936323139363131393630 + 3139353931393538313935373139353631393535313935343139353331393532 + 31393531313935303130303031303234313339343030303039393939636f6d6f + 6dc3a17365737465657374617065726f746f646f686163656361646161c3b16f + 6269656e64c3ad616173c3ad766964616361736f6f74726f666f726f736f6c6f + 6f7472616375616c64696a6f7369646f6772616e7469706f74656d6164656265 + 616c676f7175c3a96573746f6e61646174726573706f636f6361736162616a6f + 746f646173696e6f6167756170756573756e6f73616e7465646963656c756973 + 656c6c616d61796f7a6f6e61616d6f727069736f6f627261636c6963656c6c6f + 64696f73686f726163617369d0b7d0b0d0bdd0b0d0bed0bcd180d0b0d180d183 + d182d0b0d0bdd0b5d0bfd0bed0bed182d0b8d0b7d0bdd0bed0b4d0bed182d0be + d0b6d0b5d0bed0bdd0b8d185d09dd0b0d0b5d0b5d0b1d18bd0bcd18bd092d18b + d181d0bed0b2d18bd0b2d0bed09dd0bed0bed0b1d09fd0bed0bbd0b8d0bdd0b8 + d0a0d0a4d09dd0b5d09cd18bd182d18bd09ed0bdd0b8d0bcd0b4d0b0d097d0b0 + d094d0b0d09dd183d09ed0b1d182d0b5d098d0b7d0b5d0b9d0bdd183d0bcd0bc + d0a2d18bd183d0b6d981d98ad8a3d986d985d8a7d985d8b9d983d984d8a3d988 + d8b1d8afd98ad8a7d981d989d987d988d984d985d984d983d8a7d988d984d987 + d8a8d8b3d8a7d984d8a5d986d987d98ad8a3d98ad982d8afd987d984d8abd985 + d8a8d987d984d988d984d98ad8a8d984d8a7d98ad8a8d983d8b4d98ad8a7d985 + d8a3d985d986d8aad8a8d98ad984d986d8add8a8d987d985d985d8b4d988d8b4 + 6669727374766964656f6c69676874776f726c646d656469617768697465636c + 6f7365626c61636b7269676874736d616c6c626f6f6b73706c6163656d757369 + 636669656c646f72646572706f696e7476616c75656c6576656c7461626c6562 + 6f617264686f75736567726f7570776f726b7379656172737374617465746f64 + 6179776174657273746172747374796c656465617468706f77657270686f6e65 + 6e696768746572726f72696e70757461626f75747465726d737469746c65746f + 6f6c736576656e746c6f63616c74696d65736c61726765776f72647367616d65 + 7373686f72747370616365666f637573636c6561726d6f64656c626c6f636b67 + 75696465726164696f7368617265776f6d656e616761696e6d6f6e6579696d61 + 67656e616d6573796f756e676c696e65736c61746572636f6c6f72677265656e + 66726f6e7426616d703b7761746368666f726365707269636572756c65736265 + 67696e616674657276697369746973737565617265617362656c6f77696e6465 + 78746f74616c686f7572736c6162656c7072696e7470726573736275696c746c + 696e6b73737065656473747564797472616465666f756e6473656e7365756e64 + 657273686f776e666f726d7372616e676561646465647374696c6c6d6f766564 + 74616b656e61626f7665666c61736866697865646f6674656e6f746865727669 + 657773636865636b6c6567616c72697665726974656d73717569636b73686170 + 6568756d616e6578697374676f696e676d6f7669657468697264626173696370 + 65616365737461676577696474686c6f67696e696465617377726f7465706167 + 65737573657273647269766573746f7265627265616b736f757468766f696365 + 73697465736d6f6e746877686572656275696c6477686963686561727468666f + 72756d746872656573706f72747061727479436c69636b6c6f7765726c697665 + 73636c6173736c61796572656e74727973746f72797573616765736f756e6463 + 6f757274796f7572206269727468706f70757074797065736170706c79496d61 + 67656265696e6775707065726e6f746573657665727973686f77736d65616e73 + 65787472616d61746368747261636b6b6e6f776e6561726c79626567616e7375 + 70657270617065726e6f7274686c6561726e676976656e6e616d6564656e6465 + 645465726d73706172747347726f75706272616e647573696e67776f6d616e66 + 616c73657265616479617564696f74616b65737768696c652e636f6d2f6c6976 + 656463617365736461696c796368696c6467726561746a7564676574686f7365 + 756e6974736e6576657262726f6164636f617374636f7665726170706c656669 + 6c65736379636c657363656e65706c616e73636c69636b777269746571756565 + 6e7069656365656d61696c6672616d656f6c64657270686f746f6c696d697463 + 61636865636976696c7363616c65656e7465727468656d657468657265746f75 + 6368626f756e64726f79616c61736b656477686f6c6573696e636573746f636b + 206e616d6566616974686865617274656d7074796f6666657273636f70656f77 + 6e65646d69676874616c62756d7468696e6b626c6f6f6461727261796d616a6f + 72747275737463616e6f6e756e696f6e636f756e7476616c696473746f6e6553 + 74796c654c6f67696e68617070796f636375726c6566743a6672657368717569 + 746566696c6d7367726164656e65656473757262616e66696768746261736973 + 686f7665726175746f3b726f7574652e68746d6c6d6978656466696e616c596f + 757220736c696465746f70696362726f776e616c6f6e65647261776e73706c69 + 747265616368526967687464617465736d6172636871756f7465676f6f64734c + 696e6b73646f7562746173796e637468756d62616c6c6f776368696566796f75 + 74686e6f76656c313070783b7365727665756e74696c68616e6473436865636b + 537061636571756572796a616d6573657175616c7477696365302c3030305374 + 61727470616e656c736f6e6773726f756e6465696768747368696674776f7274 + 68706f7374736c656164737765656b7361766f696474686573656d696c657370 + 6c616e65736d617274616c706861706c616e746d61726b737261746573706c61 + 7973636c61696d73616c65737465787473737461727377726f6e673c2f68333e + 7468696e672e6f72672f6d756c74696865617264506f7765727374616e64746f + 6b656e736f6c696428746869736272696e677368697073737461666674726965 + 6463616c6c7366756c6c7966616374736167656e7454686973202f2f2d2d3e61 + 646d696e65677970744576656e74313570783b456d61696c747275652263726f + 73737370656e74626c6f6773626f78223e6e6f7465646c656176656368696e61 + 73697a657367756573743c2f68343e726f626f746865617679747275652c7365 + 76656e6772616e646372696d657369676e73617761726564616e636570686173 + 653e3c212d2d656e5f5553262333393b32303070785f6e616d656c6174696e65 + 6e6a6f79616a61782e6174696f6e736d697468552e532e20686f6c6473706574 + 6572696e6469616e6176223e636861696e73636f7265636f6d6573646f696e67 + 7072696f7253686172653139393073726f6d616e6c697374736a6170616e6661 + 6c6c73747269616c6f776e657261677265653c2f68323e6162757365616c6572 + 746f70657261222d2f2f57636172647368696c6c737465616d7350686f746f74 + 72757468636c65616e2e7068703f7361696e746d6574616c6c6f7569736d6561 + 6e7470726f6f666272696566726f77223e67656e7265747275636b6c6f6f6b73 + 56616c75654672616d652e6e65742f2d2d3e0a3c747279207b0a766172206d61 + 6b6573636f737473706c61696e6164756c747175657374747261696e6c61626f + 7268656c707363617573656d616769636d6f746f72746865697232353070786c + 656173747374657073436f756e74636f756c64676c617373736964657366756e + 6473686f74656c61776172646d6f7574686d6f76657370617269736769766573 + 6475746368746578617366727569746e756c6c2c7c7c5b5d3b746f70223e0a3c + 212d2d504f5354226f6365616e3c62722f3e666c6f6f72737065616b64657074 + 682073697a6562616e6b7363617463686368617274323070783b616c69676e64 + 65616c73776f756c64353070783b75726c3d227061726b736d6f7573654d6f73 + 74202e2e2e3c2f616d6f6e67627261696e626f6479206e6f6e653b6261736564 + 636172727964726166747265666572706167655f686f6d652e6d657465726465 + 6c6179647265616d70726f76656a6f696e743c2f74723e64727567733c212d2d + 20617072696c696465616c616c6c656e6578616374666f727468636f6465736c + 6f67696356696577207365656d73626c616e6b706f7274732028323030736176 + 65645f6c696e6b676f616c736772616e74677265656b686f6d657372696e6773 + 7261746564333070783b77686f7365706172736528293b2220426c6f636b6c69 + 6e75786a6f6e6573706978656c27293b223e293b6966282d6c65667464617669 + 64686f727365466f6375737261697365626f786573547261636b656d656e743c + 2f656d3e626172223e2e7372633d746f776572616c743d226361626c6568656e + 7279323470783b73657475706974616c7973686172706d696e6f727461737465 + 77616e7473746869732e7265736574776865656c6769726c732f6373732f3130 + 30253b636c75627373747566666269626c65766f74657320313030306b6f7265 + 617d293b0d0a62616e647371756575653d207b7d3b383070783b636b696e677b + 0d0a09096168656164636c6f636b69726973686c696b6520726174696f737461 + 7473466f726d227961686f6f295b305d3b41626f757466696e64733c2f68313e + 64656275677461736b7355524c203d63656c6c737d2928293b313270783b7072 + 696d6574656c6c737475726e7330783630302e6a706722737061696e62656163 + 6874617865736d6963726f616e67656c2d2d3e3c2f676966747373746576652d + 6c696e6b626f64792e7d293b0a096d6f756e7420283139394641513c2f726f67 + 65726672616e6b436c617373323870783b66656564733c68313e3c73636f7474 + 7465737473323270783b6472696e6b29207c7c206c657769737368616c6c2330 + 33393b20666f72206c6f7665647761737465303070783b6a613ae38273696d6f + 6e3c666f6e747265706c796d65657473756e7465726368656170746967687442 + 72616e642920213d206472657373636c697073726f6f6d736f6e6b65796d6f62 + 696c6d61696e2e4e616d6520706c61746566756e6e797472656573636f6d2f22 + 312e6a7067776d6f6465706172616d53544152546c65667420696464656e2c20 + 323031293b0a7d0a666f726d2e766972757363686169727472616e73776f7273 + 7450616765736974696f6e70617463683c212d2d0a6f2d6361636669726d7374 + 6f7572732c30303020617369616e692b2b297b61646f626527295b305d69643d + 3130626f74683b6d656e75202e322e6d692e706e67226b6576696e636f616368 + 4368696c646272756365322e6a706755524c292b2e6a70677c7375697465736c + 69636568617272793132302220737765657474723e0d0a6e616d653d64696567 + 6f706167652073776973732d2d3e0a0a236666663b223e4c6f672e636f6d2274 + 7265617473686565742920262620313470783b736c6565706e74656e7466696c + 65646a613ae38369643d22634e616d6522776f72736573686f74732d626f782d + 64656c74610a266c743b62656172733a34385a3c646174612d727572616c3c2f + 613e207370656e6462616b657273686f70733d2022223b706870223e6374696f + 6e313370783b627269616e68656c6c6f73697a653d6f3d253246206a6f696e6d + 617962653c696d6720696d67223e2c20666a73696d67222022295b305d4d546f + 704254797065226e65776c7944616e736b637a656368747261696c6b6e6f7773 + 3c2f68353e666171223e7a682d636e3130293b0a2d3122293b747970653d626c + 7565737472756c7964617669732e6a73273b3e0d0a3c21737465656c20796f75 + 2068323e0d0a666f726d206a6573757331303025206d656e752e0d0a090d0a77 + 616c65737269736b73756d656e746464696e67622d6c696b7465616368676966 + 2220766567617364616e736b6565737469736871697073756f6d69736f627265 + 6465736465656e747265746f646f73707565646561c3b16f73657374c3a17469 + 656e6568617374616f74726f737061727465646f6e64656e7565766f68616365 + 72666f726d616d69736d6f6d656a6f726d756e646f617175c3ad64c3ad617373 + c3b36c6f61797564616665636861746f64617374616e746f6d656e6f73646174 + 6f736f74726173736974696f6d7563686f61686f72616c756761726d61796f72 + 6573746f73686f72617374656e6572616e746573666f746f7365737461737061 + c3ad736e7565766173616c7564666f726f736d6564696f717569656e6d657365 + 73706f6465726368696c65736572c3a1766563657364656369726a6f73c3a965 + 7374617276656e7461677275706f686563686f656c6c6f7374656e676f616d69 + 676f636f7361736e6976656c67656e74656d69736d6161697265736a756c696f + 74656d617368616369616661766f726a756e696f6c6962726570756e746f6275 + 656e6f6175746f72616272696c6275656e61746578746f6d61727a6f73616265 + 726c697374616c7565676f63c3b36d6f656e65726f6a7565676f706572c3ba68 + 616265726573746f796e756e63616d756a657276616c6f7266756572616c6962 + 726f6775737461696775616c766f746f736361736f736775c3ad61707565646f + 736f6d6f73617669736f7573746564646562656e6e6f63686562757363616661 + 6c74616575726f737365726965646963686f637572736f636c61766563617361 + 736c65c3b36e706c617a6f6c6172676f6f62726173766973746161706f796f6a + 756e746f7472617461766973746f637265617263616d706f68656d6f7363696e + 636f636172676f7069736f736f7264656e686163656ec3a1726561646973636f + 706564726f63657263617075656461706170656c6d656e6f72c3ba74696c636c + 61726f6a6f72676563616c6c65706f6e657274617264656e616469656d617263 + 617369677565656c6c61737369676c6f636f6368656d6f746f736d6164726563 + 6c617365726573746f6e69c3b16f7175656461706173617262616e636f68696a + 6f737669616a657061626c6fc3a97374657669656e657265696e6f64656a6172 + 666f6e646f63616e616c6e6f7274656c657472616361757361746f6d61726d61 + 6e6f736c756e65736175746f7376696c6c6176656e646f70657361727469706f + 7374656e67616d6172636f6c6c6576617061647265756e69646f76616d6f737a + 6f6e6173616d626f7362616e64616d61726961616275736f6d75636861737562 + 697272696f6a617669766972677261646f6368696361616c6cc3ad6a6f76656e + 6469636861657374616e74616c657373616c69727375656c6f7065736f736669 + 6e65736c6c616d61627573636fc3a97374616c6c6567616e6567726f706c617a + 6168756d6f7270616761726a756e7461646f626c6569736c6173626f6c736162 + 61c3b16f6861626c616c75636861c381726561646963656e6a756761726e6f74 + 617376616c6c65616c6cc3a16361726761646f6c6f726162616a6f657374c3a9 + 677573746f6d656e74656d6172696f6669726d61636f73746f6669636861706c + 617461686f67617261727465736c65796573617175656c6d7573656f62617365 + 73706f636f736d697461646369656c6f636869636f6d6965646f67616e617273 + 616e746f65746170616465626573706c61796172656465737369657465636f72 + 7465636f7265616475646173646573656f7669656a6f64657365616167756173 + 2671756f743b646f6d61696e636f6d6d6f6e7374617475736576656e74736d61 + 7374657273797374656d616374696f6e62616e6e657272656d6f76657363726f + 6c6c757064617465676c6f62616c6d656469756d66696c7465726e756d626572 + 6368616e6765726573756c747075626c696373637265656e63686f6f73656e6f + 726d616c74726176656c697373756573736f7572636574617267657473707269 + 6e676d6f64756c656d6f62696c6573776974636870686f746f73626f72646572 + 726567696f6e697473656c66736f6369616c616374697665636f6c756d6e7265 + 636f7264666f6c6c6f777469746c653e6569746865726c656e67746866616d69 + 6c79667269656e646c61796f7574617574686f72637265617465726576696577 + 73756d6d6572736572766572706c61796564706c61796572657870616e64706f + 6c696379666f726d6174646f75626c65706f696e747373657269657370657273 + 6f6e6c6976696e6764657369676e6d6f6e746873666f72636573756e69717565 + 77656967687470656f706c65656e657267796e61747572657365617263686669 + 67757265686176696e67637573746f6d6f66667365746c657474657277696e64 + 6f777375626d697472656e64657267726f75707375706c6f61646865616c7468 + 6d6574686f64766964656f737363686f6f6c667574757265736861646f776465 + 6261746576616c7565734f626a6563746f74686572737269676874736c656167 + 75656368726f6d6573696d706c656e6f74696365736861726564656e64696e67 + 736561736f6e7265706f72746f6e6c696e65737175617265627574746f6e696d + 61676573656e61626c656d6f76696e676c617465737477696e7465724672616e + 6365706572696f647374726f6e677265706561744c6f6e646f6e64657461696c + 666f726d656464656d616e64736563757265706173736564746f67676c65706c + 6163657364657669636573746174696363697469657373747265616d79656c6c + 6f7761747461636b737472656574666c6967687468696464656e696e666f223e + 6f70656e656475736566756c76616c6c65796361757365736c65616465727365 + 637265747365636f6e6464616d61676573706f72747365786365707472617469 + 6e677369676e65647468696e67736566666563746669656c6473737461746573 + 6f666669636576697375616c656469746f72766f6c756d655265706f72746d75 + 7365756d6d6f76696573706172656e746163636573736d6f73746c796d6f7468 + 6572222069643d226d61726b657467726f756e646368616e6365737572766579 + 6265666f726573796d626f6c6d6f6d656e747370656563686d6f74696f6e696e + 736964656d617474657243656e7465726f626a6563746578697374736d696464 + 6c654575726f706567726f7774686c65676163796d616e6e6572656e6f756768 + 636172656572616e737765726f726967696e706f7274616c636c69656e747365 + 6c65637472616e646f6d636c6f736564746f70696373636f6d696e6766617468 + 65726f7074696f6e73696d706c7972616973656465736361706563686f73656e + 636875726368646566696e65726561736f6e636f726e65726f75747075746d65 + 6d6f7279696672616d65706f6c6963656d6f64656c734e756d62657264757269 + 6e676f66666572737374796c65736b696c6c65646c697374656463616c6c6564 + 73696c7665726d617267696e64656c65746562657474657262726f7773656c69 + 6d697473476c6f62616c73696e676c6577696467657463656e74657262756467 + 65746e6f77726170637265646974636c61696d73656e67696e65736166657479 + 63686f6963657370697269742d7374796c657370726561646d616b696e676e65 + 65646564727573736961706c65617365657874656e7453637269707462726f6b + 656e616c6c6f7773636861726765646976696465666163746f726d656d626572 + 2d62617365647468656f7279636f6e66696761726f756e64776f726b65646865 + 6c706564436875726368696d7061637473686f756c64616c776179736c6f676f + 2220626f74746f6d6c697374223e297b766172207072656669786f72616e6765 + 4865616465722e7075736828636f75706c6567617264656e6272696467656c61 + 756e636852657669657774616b696e67766973696f6e6c6974746c6564617469 + 6e67427574746f6e6265617574797468656d6573666f72676f74536561726368 + 616e63686f72616c6d6f73746c6f616465644368616e676572657475726e7374 + 72696e6772656c6f61644d6f62696c65696e636f6d65737570706c79536f7572 + 63656f7264657273766965776564266e6273703b636f7572736541626f757420 + 69736c616e643c68746d6c20636f6f6b69656e616d653d22616d617a6f6e6d6f + 6465726e616476696365696e3c2f613e3a20546865206469616c6f67686f7573 + 6573424547494e204d657869636f73746172747363656e747265686569676874 + 616464696e6749736c616e64617373657473456d706972655363686f6f6c6566 + 666f72746469726563746e6561726c796d616e75616c53656c6563742e0a0a4f + 6e656a6f696e65646d656e75223e5068696c697061776172647368616e646c65 + 696d706f72744f6666696365726567617264736b696c6c736e6174696f6e5370 + 6f7274736465677265657765656b6c792028652e672e626568696e64646f6374 + 6f726c6f67676564756e697465643c2f623e3c2f626567696e73706c616e7473 + 61737369737461727469737469737375656433303070787c63616e6164616167 + 656e6379736368656d6572656d61696e4272617a696c73616d706c656c6f676f + 223e6265796f6e642d7363616c656163636570747365727665646d6172696e65 + 466f6f74657263616d6572613c2f68313e0a5f666f726d226c65617665737374 + 7265737322202f3e0d0a2e67696622206f6e6c6f61646c6f616465724f78666f + 72647369737465727375727669766c697374656e66656d616c6544657369676e + 73697a653d2261707065616c74657874223e6c6576656c737468616e6b736869 + 67686572666f72636564616e696d616c616e796f6e6541667269636161677265 + 6564726563656e7450656f706c653c6272202f3e776f6e646572707269636573 + 7475726e65647c7c207b7d3b6d61696e223e696e6c696e6573756e6461797772 + 6170223e6661696c656463656e7375736d696e757465626561636f6e71756f74 + 657331353070787c65737461746572656d6f7465656d61696c226c696e6b6564 + 72696768743b7369676e616c666f726d616c312e68746d6c7369676e75707072 + 696e6365666c6f61743a2e706e672220666f72756d2e41636365737370617065 + 7273736f756e6473657874656e64486569676874736c696465725554462d3822 + 26616d703b204265666f72652e205769746873747564696f6f776e6572736d61 + 6e61676570726f6669746a5175657279616e6e75616c706172616d73626f7567 + 687466616d6f7573676f6f676c656c6f6e676572692b2b29207b69737261656c + 736179696e67646563696465686f6d65223e686561646572656e737572656272 + 616e6368706965636573626c6f636b3b737461746564746f70223e3c72616369 + 6e67726573697a652d2d2667743b70616369747973657875616c627572656175 + 2e6a7067222031302c3030306f627461696e7469746c6573616d6f756e742c20 + 496e632e636f6d6564796d656e7522206c7972696373746f6461792e696e6465 + 6564636f756e74795f6c6f676f2e46616d696c796c6f6f6b65644d61726b6574 + 6c7365206966506c617965727475726b6579293b76617220666f726573746769 + 76696e676572726f7273446f6d61696e7d656c73657b696e73657274426c6f67 + 3c2f666f6f7465726c6f67696e2e6661737465726167656e74733c626f647920 + 313070782030707261676d616672696461796a756e696f72646f6c6c6172706c + 61636564636f76657273706c7567696e352c3030302070616765223e626f7374 + 6f6e2e74657374286176617461727465737465645f636f756e74666f72756d73 + 736368656d61696e6465782c66696c6c6564736861726573726561646572616c + 657274286170706561725375626d69746c696e65223e626f6479223e0a2a2054 + 686554686f756768736565696e676a65727365794e6577733c2f766572696679 + 657870657274696e6a75727977696474683d436f6f6b69655354415254206163 + 726f73735f696d6167657468726561646e6174697665706f636b6574626f7822 + 3e0a53797374656d20446176696463616e6365727461626c657370726f766564 + 417072696c207265616c6c796472697665726974656d223e6d6f7265223e626f + 61726473636f6c6f727363616d7075736669727374207c7c205b5d3b6d656469 + 612e67756974617266696e69736877696474683a73686f7765644f7468657220 + 2e7068702220617373756d656c617965727377696c736f6e73746f7265737265 + 6c69656673776564656e437573746f6d656173696c7920796f75722053747269 + 6e670a0a5768696c7461796c6f72636c6561723a7265736f72746672656e6368 + 74686f7567682229202b20223c626f64793e627579696e676272616e64734d65 + 6d6265726e616d65223e6f7070696e67736563746f723570783b223e76737061 + 6365706f737465726d616a6f7220636f666665656d617274696e6d6174757265 + 68617070656e3c2f6e61763e6b616e7361736c696e6b223e496d616765733d66 + 616c73657768696c65206873706163653026616d703b200a0a496e2020706f77 + 6572506f6c736b692d636f6c6f726a6f7264616e426f74746f6d537461727420 + 2d636f756e74322e68746d6c6e657773223e30312e6a70674f6e6c696e652d72 + 696768746d696c6c657273656e696f724953424e2030302c3030302067756964 + 657376616c756529656374696f6e7265706169722e786d6c2220207269676874 + 732e68746d6c2d626c6f636b7265674578703a686f76657277697468696e7669 + 7267696e70686f6e65733c2f74723e0d7573696e67200a09766172203e27293b + 0a093c2f74643e0a3c2f74723e0a62616861736162726173696c67616c65676f + 6d6167796172706f6c736b69737270736b69d8b1d8afd988e4b8ade69687e7ae + 80e4bd93e7b981e9ab94e4bfa1e681afe4b8ade59bbde68891e4bbace4b880e4 + b8aae585ace58fb8e7aea1e79086e8aebae59d9be58fafe4bba5e69c8de58aa1 + e697b6e997b4e4b8aae4babae4baa7e59381e887aae5b7b1e4bc81e4b89ae69f + a5e79c8be5b7a5e4bd9ce88194e7b3bbe6b2a1e69c89e7bd91e7ab99e68980e6 + 9c89e8af84e8aebae4b8ade5bf83e69687e7aba0e794a8e688b7e9a696e9a1b5 + e4bd9ce88085e68a80e69cafe997aee9a298e79bb8e585b3e4b88be8bdbde690 + 9ce7b4a2e4bdbfe794a8e8bdafe4bbb6e59ca8e7babfe4b8bbe9a298e8b584e6 + 9699e8a786e9a291e59b9ee5a48de6b3a8e5868ce7bd91e7bb9ce694b6e8978f + e58685e5aeb9e68ea8e88d90e5b882e59cbae6b688e681afe7a9bae997b4e58f + 91e5b883e4bb80e4b988e5a5bde58f8be7949fe6b4bbe59bbee78987e58f91e5 + b195e5a682e69e9ce6898be69cbae696b0e997bbe69c80e696b0e696b9e5bc8f + e58c97e4baace68f90e4be9be585b3e4ba8ee69bb4e5a49ae8bf99e4b8aae7b3 + bbe7bb9fe79fa5e98193e6b8b8e6888fe5b9bfe5918ae585b6e4bb96e58f91e8 + a1a8e5ae89e585a8e7acace4b880e4bc9ae59198e8bf9be8a18ce782b9e587bb + e78988e69d83e794b5e5ad90e4b896e7958ce8aebee8aea1e5858de8b4b9e695 + 99e882b2e58aa0e585a5e6b4bbe58aa8e4bb96e4bbace59586e59381e58d9ae5 + aea2e78eb0e59ca8e4b88ae6b5b7e5a682e4bd95e5b7b2e7bb8fe79599e8a880 + e8afa6e7bb86e7a4bee58cbae799bbe5bd95e69cace7ab99e99c80e8a681e4bb + b7e6a0bce694afe68c81e59bbde99985e993bee68ea5e59bbde5aeb6e5bbbae8 + aebee69c8be58f8be99885e8afbbe6b395e5be8be4bd8de7bdaee7bb8fe6b58e + e98089e68ba9e8bf99e6a0b7e5bd93e5898de58886e7b1bbe68e92e8a18ce59b + a0e4b8bae4baa4e69893e69c80e5908ee99fb3e4b990e4b88de883bde9809ae8 + bf87e8a18ce4b89ae7a791e68a80e58fafe883bde8aebee5a487e59088e4bd9c + e5a4a7e5aeb6e7a4bee4bc9ae7a094e7a9b6e4b893e4b89ae585a8e983a8e9a1 + b9e79baee8bf99e9878ce8bf98e698afe5bc80e5a78be68385e586b5e794b5e8 + 8491e69687e4bbb6e59381e7898ce5b8aee58aa9e69687e58c96e8b584e6ba90 + e5a4a7e5ada6e5ada6e4b9a0e59cb0e59d80e6b58fe8a788e68a95e8b584e5b7 + a5e7a88be8a681e6b182e6808ee4b988e697b6e58099e58a9fe883bde4b8bbe8 + a681e79baee5898de8b584e8aeafe59f8ee5b882e696b9e6b395e794b5e5bdb1 + e68b9be88198e5a3b0e6988ee4bbbbe4bd95e581a5e5bab7e695b0e68daee7be + 8ee59bbde6b1bde8bda6e4bb8be7bb8de4bd86e698afe4baa4e6b581e7949fe4 + baa7e68980e4bba5e794b5e8af9de698bee7a4bae4b880e4ba9be58d95e4bd8d + e4babae59198e58886e69e90e59cb0e59bbee69785e6b8b8e5b7a5e585b7e5ad + a6e7949fe7b3bbe58897e7bd91e58f8be5b896e5ad90e5af86e7a081e9a291e9 + 8193e68ea7e588b6e59cb0e58cbae59fbae69cace585a8e59bbde7bd91e4b88a + e9878de8a681e7acace4ba8ce5969ce6aca2e8bf9be585a5e58f8be68385e8bf + 99e4ba9be88083e8af95e58f91e78eb0e59fb9e8aeade4bba5e4b88ae694bfe5 + ba9ce68890e4b8bae78eafe5a283e9a699e6b8afe5908ce697b6e5a8b1e4b990 + e58f91e98081e4b880e5ae9ae5bc80e58f91e4bd9ce59381e6a087e58786e6ac + a2e8bf8ee8a7a3e586b3e59cb0e696b9e4b880e4b88be4bba5e58f8ae8b4a3e4 + bbbbe68896e88085e5aea2e688b7e4bba3e8a1a8e7a7afe58886e5a5b3e4baba + e695b0e7a081e99480e594aee587bae78eb0e7a6bbe7babfe5ba94e794a8e588 + 97e8a1a8e4b88de5908ce7bc96e8be91e7bb9fe8aea1e69fa5e8afa2e4b88de8 + a681e69c89e585b3e69cbae69e84e5be88e5a49ae692ade694bee7bb84e7bb87 + e694bfe7ad96e79bb4e68ea5e883bde58a9be69da5e6ba90e69982e99693e79c + 8be588b0e783ade997a8e585b3e994aee4b893e58cbae99d9ee5b8b8e88bb1e8 + afade799bee5baa6e5b88ce69c9be7be8ee5a5b3e6af94e8be83e79fa5e8af86 + e8a784e5ae9ae5bbbae8aeaee983a8e997a8e6848fe8a781e7b2bee5bda9e697 + a5e69cace68f90e9ab98e58f91e8a880e696b9e99da2e59fbae98791e5a484e7 + 9086e69d83e99990e5bdb1e78987e993b6e8a18ce8bf98e69c89e58886e4baab + e789a9e59381e7bb8fe890a5e6b7bbe58aa0e4b893e5aeb6e8bf99e7a78de8af + 9de9a298e8b5b7e69da5e4b89ae58aa1e585ace5918ae8aeb0e5bd95e7ae80e4 + bb8be8b4a8e9878fe794b7e4babae5bdb1e5938de5bc95e794a8e68aa5e5918a + e983a8e58886e5bfabe9809fe592a8e8afa2e697b6e5b09ae6b3a8e6848fe794 + b3e8afb7e5ada6e6a0a1e5ba94e8afa5e58e86e58fb2e58faae698afe8bf94e5 + 9b9ee8b4ade4b9b0e5908de7a7b0e4b8bae4ba86e68890e58a9fe8afb4e6988e + e4be9be5ba94e5ada9e5ad90e4b893e9a298e7a88be5ba8fe4b880e888ace69c + 83e593a1e58faae69c89e585b6e5ae83e4bf9de68aa4e8808ce4b894e4bb8ae5 + a4a9e7aa97e58fa3e58aa8e68081e78ab6e68081e789b9e588abe8aea4e4b8ba + e5bf85e9a1bbe69bb4e696b0e5b08fe8afb4e68891e58091e4bd9ce4b8bae5aa + 92e4bd93e58c85e68bace982a3e4b988e4b880e6a0b7e59bbde58685e698afe5 + 90a6e6a0b9e68daee794b5e8a786e5ada6e999a2e585b7e69c89e8bf87e7a88b + e794b1e4ba8ee4babae6898de587bae69da5e4b88de8bf87e6ada3e59ca8e698 + 8ee6989fe69585e4ba8be585b3e7b3bbe6a087e9a298e59586e58aa1e8be93e5 + 85a5e4b880e79bb4e59fbae7a180e69599e5ada6e4ba86e8a7a3e5bbbae7ad91 + e7bb93e69e9ce585a8e79083e9809ae79fa5e8aea1e58892e5afb9e4ba8ee889 + bae69cafe79bb8e5868ce58f91e7949fe79c9fe79a84e5bbbae7ab8be7ad89e7 + baa7e7b1bbe59e8be7bb8fe9aa8ce5ae9ee78eb0e588b6e4bd9ce69da5e887aa + e6a087e7adbee4bba5e4b88be58e9fe5889be697a0e6b395e585b6e4b8ade580 + 8be4babae4b880e58887e68c87e58d97e585b3e997ade99b86e59ba2e7acace4 + b889e585b3e6b3a8e59ba0e6ada4e785a7e78987e6b7b1e59cb3e59586e4b89a + e5b9bfe5b79ee697a5e69c9fe9ab98e7baa7e69c80e8bf91e7bbbce59088e8a1 + a8e7a4bae4b893e8be91e8a18ce4b8bae4baa4e9809ae8af84e4bbb7e8a789e5 + be97e7b2bee58d8ee5aeb6e5baade5ae8ce68890e6849fe8a789e5ae89e8a385 + e5be97e588b0e982aee4bbb6e588b6e5baa6e9a39fe59381e899bde784b6e8bd + ace8bdbde68aa5e4bbb7e8aeb0e88085e696b9e6a188e8a18ce694bfe4babae6 + b091e794a8e59381e4b89ce8a5bfe68f90e587bae98592e5ba97e784b6e5908e + e4bb98e6acbee783ade782b9e4bba5e5898de5ae8ce585a8e58f91e5b896e8ae + bee7bdaee9a286e5afbce5b7a5e4b89ae58cbbe999a2e79c8be79c8be7bb8fe5 + 85b8e58e9fe59ba0e5b9b3e58fb0e59084e7a78de5a29ee58aa0e69d90e69699 + e696b0e5a29ee4b98be5908ee8818ce4b89ae69588e69e9ce4bb8ae5b9b4e8ae + bae69687e68891e59bbde5918ae8af89e78988e4b8bbe4bfaee694b9e58f82e4 + b88ee68993e58db0e5bfabe4b990e69cbae6a2b0e8a782e782b9e5ad98e59ca8 + e7b2bee7a59ee88eb7e5be97e588a9e794a8e7bba7e7bbade4bda0e4bbace8bf + 99e4b988e6a8a1e5bc8fe8afade8a880e883bde5a49fe99b85e8998ee6938de4 + bd9ce9a38ee6a0bce4b880e8b5b7e7a791e5ada6e4bd93e882b2e79fade4bfa1 + e69da1e4bbb6e6b2bbe79697e8bf90e58aa8e4baa7e4b89ae4bc9ae8aeaee5af + bce888aae58588e7949fe88194e79b9fe58fafe698afe5958fe9a18ce7bb93e6 + 9e84e4bd9ce794a8e8b083e69fa5e8b387e69699e887aae58aa8e8b49fe8b4a3 + e5869ce4b89ae8aebfe997aee5ae9ee696bde68ea5e58f97e8aea8e8aebae982 + a3e4b8aae58f8de9a688e58aa0e5bcbae5a5b3e680a7e88c83e59bb4e69c8de5 + 8b99e4bc91e997b2e4bb8ae697a5e5aea2e69c8de8a780e79c8be58f82e58aa0 + e79a84e8af9de4b880e782b9e4bf9de8af81e59bbee4b9a6e69c89e69588e6b5 + 8be8af95e7a7bbe58aa8e6898de883bde586b3e5ae9ae882a1e7a5a8e4b88de6 + 96ade99c80e6b182e4b88de5be97e58a9ee6b395e4b98be997b4e98787e794a8 + e890a5e99480e68a95e8af89e79baee6a087e788b1e68385e69184e5bdb1e69c + 89e4ba9be8a487e8a3bde69687e5ada6e69cbae4bc9ae695b0e5ad97e8a385e4 + bfaee8b4ade789a9e5869ce69d91e585a8e99da2e7b2bee59381e585b6e5ae9e + e4ba8be68385e6b0b4e5b9b3e68f90e7a4bae4b88ae5b882e8b0a2e8b0a2e699 + aee9809ae69599e5b888e4b88ae4bca0e7b1bbe588abe6ad8ce69bb2e68ba5e6 + 9c89e5889be696b0e9858de4bbb6e58faae8a681e697b6e4bba3e8b387e8a88a + e8bebee588b0e4babae7949fe8aea2e99885e88081e5b888e5b195e7a4bae5bf + 83e79086e8b4b4e5ad90e7b6b2e7ab99e4b8bbe9a18ce887aae784b6e7baa7e5 + 88abe7ae80e58d95e694b9e99da9e982a3e4ba9be69da5e8afb4e68993e5bc80 + e4bba3e7a081e588a0e999a4e8af81e588b8e88a82e79baee9878de782b9e6ac + a1e695b8e5a49ae5b091e8a784e58892e8b584e98791e689bee588b0e4bba5e5 + 908ee5a4a7e585a8e4b8bbe9a1b5e69c80e4bdb3e59b9ee7ad94e5a4a9e4b88b + e4bf9de99a9ce78eb0e4bba3e6a380e69fa5e68a95e7a5a8e5b08fe697b6e6b2 + 92e69c89e6ada3e5b8b8e7949ae887b3e4bba3e79086e79baee5bd95e585ace5 + bc80e5a48de588b6e98791e89e8de5b9b8e7a68fe78988e69cace5bda2e68890 + e58786e5a487e8a18ce68385e59b9ee588b0e6809de683b3e6808ee6a0b7e58d + 8fe8aeaee8aea4e8af81e69c80e5a5bde4baa7e7949fe68c89e785a7e69c8de8 + a385e5b9bfe4b89ce58aa8e6bcabe98787e8b4ade696b0e6898be7bb84e59bbe + e99da2e69dbfe58f82e88083e694bfe6b2bbe5aeb9e69893e5a4a9e59cb0e58a + aae58a9be4babae4bbace58d87e7baa7e9809fe5baa6e4babae789a9e8b083e6 + 95b4e6b581e8a18ce980a0e68890e69687e5ad97e99fa9e59bbde8b4b8e69893 + e5bc80e5b195e79bb8e9979ce8a1a8e78eb0e5bdb1e8a786e5a682e6ada4e7be + 8ee5aeb9e5a4a7e5b08fe68aa5e98193e69da1e6acbee5bf83e68385e8aeb8e5 + a49ae6b395e8a784e5aeb6e5b185e4b9a6e5ba97e8bf9ee68ea5e7ab8be58db3 + e4b8bee68aa5e68a80e5b7a7e5a5a5e8bf90e799bbe585a5e4bba5e69da5e790 + 86e8aebae4ba8be4bbb6e887aae794b1e4b8ade58d8ee58a9ee585ace5a688e5 + a688e79c9fe6ada3e4b88de99499e585a8e69687e59088e5908ce4bbb7e580bc + e588abe4babae79b91e79da3e585b7e4bd93e4b896e7baaae59ba2e9989fe588 + 9be4b89ae689bfe68b85e5a29ee995bfe69c89e4babae4bf9de68c81e59586e5 + aeb6e7bbb4e4bfaee58fb0e6b9bee5b7a6e58fb3e882a1e4bbbde7ad94e6a188 + e5ae9ee99985e794b5e4bfa1e7bb8fe79086e7949fe591bde5aea3e4bca0e4bb + bbe58aa1e6ada3e5bc8fe789b9e889b2e4b88be69da5e58d8fe4bc9ae58faae8 + 83bde5bd93e784b6e9878de696b0e585a7e5aeb9e68c87e5afbce8bf90e8a18c + e697a5e5bf97e8b3a3e5aeb6e8b685e8bf87e59c9fe59cb0e6b599e6b19fe694 + afe4bb98e68ea8e587bae7ab99e995bfe69dade5b79ee689a7e8a18ce588b6e9 + 80a0e4b98be4b880e68ea8e5b9bfe78eb0e59cbae68f8fe8bfb0e58f98e58c96 + e4bca0e7bb9fe6ad8ce6898be4bf9de999a9e8afbee7a88be58cbbe79697e7bb + 8fe8bf87e8bf87e58ebbe4b98be5898de694b6e585a5e5b9b4e5baa6e69d82e5 + bf97e7be8ee4b8bde69c80e9ab98e799bbe99986e69caae69da5e58aa0e5b7a5 + e5858de8b4a3e69599e7a88be78988e59d97e8baabe4bd93e9878de5ba86e587 + bae594aee68890e69cace5bda2e5bc8fe59c9fe8b186e587bae583b9e4b89ce6 + 96b9e982aee7aeb1e58d97e4baace6b182e8818ce58f96e5be97e8818ce4bd8d + e79bb8e4bfa1e9a1b5e99da2e58886e9929fe7bd91e9a1b5e7a1aee5ae9ae59b + bee4be8be7bd91e59d80e7a7afe69e81e99499e8afafe79baee79a84e5ae9de8 + b49de69cbae585b3e9a38ee999a9e68e88e69d83e79785e6af92e5aea0e789a9 + e999a4e4ba86e8a995e8ab96e796bee79785e58f8ae697b6e6b182e8b4ade7ab + 99e782b9e584bfe7aba5e6af8fe5a4a9e4b8ade5a4aee8aea4e8af86e6af8fe4 + b8aae5a4a9e6b4a5e5ad97e4bd93e58fb0e781a3e7bbb4e68aa4e69cace9a1b5 + e4b8aae680a7e5ae98e696b9e5b8b8e8a781e79bb8e69cbae68898e795a5e5ba + 94e5bd93e5be8be5b888e696b9e4bebfe6a0a1e59bade882a1e5b882e688bfe5 + b18be6a08fe79baee59198e5b7a5e5afbce887b4e7aa81e784b6e98193e585b7 + e69cace7bd91e7bb93e59088e6a1a3e6a188e58ab3e58aa8e58fa6e5a496e7be + 8ee58583e5bc95e8b5b7e694b9e58f98e7acace59b9be4bc9ae8aea1e8aaaae6 + 988ee99a90e7a781e5ae9de5ae9de8a784e88c83e6b688e8b4b9e585b1e5908c + e5bf98e8aeb0e4bd93e7b3bbe5b8a6e69da5e5908de5ad97e799bce8a1a8e5bc + 80e694bee58aa0e79b9fe58f97e588b0e4ba8ce6898be5a4a7e9878fe68890e4 + babae695b0e9878fe585b1e4baabe58cbae59f9fe5a5b3e5ada9e58e9fe58899 + e68980e59ca8e7bb93e69d9fe9809ae4bfa1e8b685e7baa7e9858de7bdaee5bd + 93e697b6e4bc98e7a780e680a7e6849fe688bfe4baa7e9818ae688b2e587bae5 + 8fa3e68f90e4baa4e5b0b1e4b89ae4bf9de581a5e7a88be5baa6e58f82e695b0 + e4ba8be4b89ae695b4e4b8aae5b1b1e4b89ce68385e6849fe789b9e6ae8ae588 + 86e9a19ee6909ce5b08be5b19ee4ba8ee997a8e688b7e8b4a2e58aa1e5a3b0e9 + 9fb3e58f8ae585b6e8b4a2e7bb8fe59d9ae68c81e5b9b2e983a8e68890e7ab8b + e588a9e79b8ae88083e89991e68890e983bde58c85e8a385e794a8e688b6e6af + 94e8b59be69687e6988ee68b9be59586e5ae8ce695b4e79c9fe698afe79cbce7 + 9d9be4bc99e4bcb4e5a881e69c9be9a286e59f9fe58dabe7949fe4bc98e683a0 + e8ab96e5a387e585ace585b1e889afe5a5bde58585e58886e7aca6e59088e999 + 84e4bbb6e789b9e782b9e4b88de58fafe88bb1e69687e8b584e4baa7e6a0b9e6 + 9cace6988ee698bee5af86e7a2bce585ace4bc97e6b091e6978fe69bb4e58aa0 + e4baabe58f97e5908ce5ada6e590afe58aa8e98082e59088e58e9fe69da5e997 + aee7ad94e69cace69687e7be8ee9a39fe7bbbfe889b2e7a8b3e5ae9ae7bb88e4 + ba8ee7949fe789a9e4be9be6b182e6909ce78b90e58a9be9878fe4b8a5e9878d + e6b0b8e8bf9ce58699e79c9fe69c89e99990e7ab9ee4ba89e5afb9e8b1a1e8b4 + b9e794a8e4b88de5a5bde7bb9de5afb9e58d81e58886e4bf83e8bf9be782b9e8 + af84e5bdb1e99fb3e4bc98e58abfe4b88de5b091e6aca3e8b58fe5b9b6e4b894 + e69c89e782b9e696b9e59091e585a8e696b0e4bfa1e794a8e8aebee696bde5bd + a2e8b1a1e8b584e6a0bce7aa81e7a0b4e99a8fe79d80e9878de5a4a7e4ba8ee6 + 98afe6af95e4b89ae699bae883bde58c96e5b7a5e5ae8ce7be8ee59586e59f8e + e7bb9fe4b880e587bae78988e68993e980a0e794a2e59381e6a682e586b5e794 + a8e4ba8ee4bf9de79599e59ba0e7b4a0e4b8ade59c8be5ad98e582a8e8b4b4e5 + 9bbee69c80e6849be995bfe69c9fe58fa3e4bbb7e79086e8b4a2e59fbae59cb0 + e5ae89e68e92e6ada6e6b189e9878ce99da2e5889be5bbbae5a4a9e7a9bae9a6 + 96e58588e5ae8ce59684e9a9b1e58aa8e4b88be99da2e4b88de5868de8af9ae4 + bfa1e6848fe4b989e998b3e58589e88bb1e59bbde6bc82e4baaee5869be4ba8b + e78ea9e5aeb6e7bea4e4bc97e5869ce6b091e58db3e58fafe5908de7a8b1e5ae + b6e585b7e58aa8e794bbe683b3e588b0e6b3a8e6988ee5b08fe5ada6e680a7e8 + 83bde88083e7a094e7a1ace4bbb6e8a782e79c8be6b885e6a59ae6909ee7ac91 + e9a696e9a081e9bb84e98791e98082e794a8e6b19fe88b8fe79c9fe5ae9ee4b8 + bbe7aea1e998b6e6aeb5e8a8bbe5868ae7bfbbe8af91e69d83e588a9e5819ae5 + a5bde4bcbce4b98ee9809ae8aeafe696bde5b7a5e78b80e6858be4b99fe8aeb8 + e78eafe4bf9de59fb9e585bbe6a682e5bfb5e5a4a7e59e8be69cbae7a5a8e790 + 86e8a7a3e58cbfe5908d6375616e646f656e766961726d616472696462757363 + 6172696e6963696f7469656d706f706f727175656375656e746165737461646f + 70756564656e6a7565676f73636f6e747261657374c3a16e6e6f6d6272657469 + 656e656e70657266696c6d616e657261616d69676f7363697564616463656e74 + 726f61756e71756570756564657364656e74726f7072696d657270726563696f + 736567c3ba6e6275656e6f73766f6c76657270756e746f7373656d616e616861 + 62c3ad6161676f73746f6e7565766f73756e69646f736361726c6f7365717569 + 706f6e69c3b16f736d7563686f73616c67756e61636f7272656f696d6167656e + 7061727469726172726962616d6172c3ad61686f6d627265656d706c656f7665 + 7264616463616d62696f6d7563686173667565726f6e70617361646f6cc3ad6e + 65617061726563656e7565766173637572736f7365737461626171756965726f + 6c6962726f736375616e746f61636365736f6d696775656c766172696f736375 + 6174726f7469656e6573677275706f73736572c3a16e6575726f70616d656469 + 6f736672656e746561636572636164656dc3a1736f6665727461636f63686573 + 6d6f64656c6f6974616c69616c6574726173616c67c3ba6e636f6d7072616375 + 616c657365786973746563756572706f7369656e646f7072656e73616c6c6567 + 61727669616a657364696e65726f6d7572636961706f6472c3a170756573746f + 64696172696f707565626c6f7175696572656d616e75656c70726f70696f6372 + 6973697363696572746f73656775726f6d75657274656675656e746563657272 + 61726772616e646565666563746f7061727465736d656469646170726f706961 + 6f6672656365746965727261652d6d61696c766172696173666f726d61736675 + 7475726f6f626a65746f73656775697272696573676f6e6f726d61736d69736d + 6f73c3ba6e69636f63616d696e6f736974696f7372617ac3b36e64656269646f + 707275656261746f6c65646f74656ec3ad616a6573c3ba7365737065726f636f + 63696e616f726967656e7469656e64616369656e746f63c3a164697a6861626c + 6172736572c3ad616c6174696e61667565727a61657374696c6f677565727261 + 656e74726172c3a97869746f6cc3b370657a6167656e646176c3ad64656f6576 + 69746172706167696e616d6574726f736a617669657270616472657366c3a163 + 696c636162657a61c3a17265617373616c696461656e76c3ad6f6a6170c3b36e + 616275736f736269656e6573746578746f736c6c6576617270756564616e6675 + 65727465636f6dc3ba6e636c6173657368756d616e6f74656e69646f62696c62 + 616f756e69646164657374c3a17365646974617263726561646fd0b4d0bbd18f + d187d182d0bed0bad0b0d0bad0b8d0bbd0b8d18dd182d0bed0b2d181d0b5d0b5 + d0b3d0bed0bfd180d0b8d182d0b0d0bad0b5d189d0b5d183d0b6d0b5d09ad0b0 + d0bad0b1d0b5d0b7d0b1d18bd0bbd0bed0bdd0b8d092d181d0b5d0bfd0bed0b4 + d0add182d0bed182d0bed0bcd187d0b5d0bcd0bdd0b5d182d0bbd0b5d182d180 + d0b0d0b7d0bed0bdd0b0d0b3d0b4d0b5d0bcd0bdd0b5d094d0bbd18fd09fd180 + d0b8d0bdd0b0d181d0bdd0b8d185d182d0b5d0bcd0bad182d0bed0b3d0bed0b4 + d0b2d0bed182d182d0b0d0bcd0a1d0a8d090d0bcd0b0d18fd0a7d182d0bed0b2 + d0b0d181d0b2d0b0d0bcd0b5d0bcd183d0a2d0b0d0bad0b4d0b2d0b0d0bdd0b0 + d0bcd18dd182d0b8d18dd182d183d092d0b0d0bcd182d0b5d185d0bfd180d0be + d182d183d182d0bdd0b0d0b4d0b4d0bdd18fd092d0bed182d182d180d0b8d0bd + d0b5d0b9d092d0b0d181d0bdd0b8d0bcd181d0b0d0bcd182d0bed182d180d183 + d0b1d09ed0bdd0b8d0bcd0b8d180d0bdd0b5d0b5d09ed09ed09ed0bbd0b8d186 + d18dd182d0b0d09ed0bdd0b0d0bdd0b5d0bcd0b4d0bed0bcd0bcd0bed0b9d0b4 + d0b2d0b5d0bed0bdd0bed181d183d0b4e0a495e0a587e0a4b9e0a588e0a495e0 + a580e0a4b8e0a587e0a495e0a4bee0a495e0a58be0a494e0a4b0e0a4aae0a4b0 + e0a4a8e0a587e0a48fe0a495e0a495e0a4bfe0a4ade0a580e0a487e0a4b8e0a4 + 95e0a4b0e0a4a4e0a58be0a4b9e0a58be0a486e0a4aae0a4b9e0a580e0a4afe0 + a4b9e0a4afe0a4bee0a4a4e0a495e0a4a5e0a4be6a616772616ee0a486e0a49c + e0a49ce0a58be0a485e0a4ace0a4a6e0a58be0a497e0a488e0a49ce0a4bee0a4 + 97e0a48fe0a4b9e0a4aee0a487e0a4a8e0a4b5e0a4b9e0a4afe0a587e0a4a5e0 + a587e0a4a5e0a580e0a498e0a4b0e0a49ce0a4ace0a4a6e0a580e0a495e0a488 + e0a49ce0a580e0a4b5e0a587e0a4a8e0a488e0a4a8e0a48fe0a4b9e0a4b0e0a4 + 89e0a4b8e0a4aee0a587e0a495e0a4aee0a4b5e0a58be0a4b2e0a587e0a4b8e0 + a4ace0a4aee0a488e0a4a6e0a587e0a493e0a4b0e0a486e0a4aee0a4ace0a4b8 + e0a4ade0a4b0e0a4ace0a4a8e0a49ae0a4b2e0a4aee0a4a8e0a486e0a497e0a4 + b8e0a580e0a4b2e0a580d8b9d984d989d8a5d984d989d987d8b0d8a7d8a2d8ae + d8b1d8b9d8afd8afd8a7d984d989d987d8b0d987d8b5d988d8b1d8bad98ad8b1 + d983d8a7d986d988d984d8a7d8a8d98ad986d8b9d8b1d8b6d8b0d984d983d987 + d986d8a7d98ad988d985d982d8a7d984d8b9d984d98ad8a7d986d8a7d984d983 + d986d8add8aad989d982d8a8d984d988d8add8a9d8a7d8aed8b1d981d982d8b7 + d8b9d8a8d8afd8b1d983d986d8a5d8b0d8a7d983d985d8a7d8a7d8add8afd8a5 + d984d8a7d981d98ad987d8a8d8b9d8b6d983d98ad981d8a8d8add8abd988d985 + d986d988d987d988d8a3d986d8a7d8acd8afd8a7d984d987d8a7d8b3d984d985 + d8b9d986d8afd984d98ad8b3d8b9d8a8d8b1d8b5d984d989d985d986d8b0d8a8 + d987d8a7d8a3d986d987d985d8abd984d983d986d8aad8a7d984d8a7d8add98a + d8abd985d8b5d8b1d8b4d8b1d8add8add988d984d988d981d98ad8a7d8b0d8a7 + d984d983d984d985d8b1d8a9d8a7d986d8aad8a7d984d981d8a3d8a8d988d8ae + d8a7d8b5d8a3d986d8aad8a7d986d987d8a7d984d98ad8b9d8b6d988d988d982 + d8afd8a7d8a8d986d8aed98ad8b1d8a8d986d8aad984d983d985d8b4d8a7d8a1 + d988d987d98ad8a7d8a8d988d982d8b5d8b5d988d985d8a7d8b1d982d985d8a3 + d8add8afd986d8add986d8b9d8afd985d8b1d8a3d98ad8a7d8add8a9d983d8aa + d8a8d8afd988d986d98ad8acd8a8d985d986d987d8aad8add8aad8acd987d8a9 + d8b3d986d8a9d98ad8aad985d983d8b1d8a9d8bad8b2d8a9d986d981d8b3d8a8 + d98ad8aad984d984d987d984d986d8a7d8aad984d983d982d984d8a8d984d985 + d8a7d8b9d986d987d8a3d988d984d8b4d98ad8a1d986d988d8b1d8a3d985d8a7 + d981d98ad983d8a8d983d984d8b0d8a7d8aad8b1d8aad8a8d8a8d8a3d986d987 + d985d8b3d8a7d986d983d8a8d98ad8b9d981d982d8afd8add8b3d986d984d987 + d985d8b4d8b9d8b1d8a3d987d984d8b4d987d8b1d982d8b7d8b1d8b7d984d8a8 + 70726f66696c657365727669636564656661756c7468696d73656c6664657461 + 696c73636f6e74656e74737570706f7274737461727465646d65737361676573 + 75636365737366617368696f6e3c7469746c653e636f756e7472796163636f75 + 6e746372656174656473746f72696573726573756c747372756e6e696e677072 + 6f6365737377726974696e676f626a6563747376697369626c6577656c636f6d + 6561727469636c65756e6b6e6f776e6e6574776f726b636f6d70616e7964796e + 616d696362726f777365727072697661637970726f626c656d53657276696365 + 72657370656374646973706c6179726571756573747265736572766577656273 + 697465686973746f7279667269656e64736f7074696f6e73776f726b696e6776 + 657273696f6e6d696c6c696f6e6368616e6e656c77696e646f772e6164647265 + 73737669736974656477656174686572636f727265637470726f647563746564 + 6972656374666f7277617264796f752063616e72656d6f7665647375626a6563 + 74636f6e74726f6c6172636869766563757272656e7472656164696e676c6962 + 726172796c696d697465646d616e616765726675727468657273756d6d617279 + 6d616368696e656d696e7574657370726976617465636f6e7465787470726f67 + 72616d736f63696574796e756d626572737772697474656e656e61626c656474 + 726967676572736f75726365736c6f6164696e67656c656d656e74706172746e + 657266696e616c6c79706572666563746d65616e696e6773797374656d736b65 + 6570696e6763756c747572652671756f743b2c6a6f75726e616c70726f6a6563 + 7473757266616365732671756f743b657870697265737265766965777362616c + 616e6365456e676c697368436f6e74656e747468726f756768506c6561736520 + 6f70696e696f6e636f6e74616374617665726167657072696d61727976696c6c + 6167655370616e69736867616c6c6572796465636c696e656d656574696e676d + 697373696f6e706f70756c61727175616c6974796d65617375726567656e6572 + 616c7370656369657373657373696f6e73656374696f6e77726974657273636f + 756e746572696e697469616c7265706f727473666967757265736d656d626572 + 73686f6c64696e67646973707574656561726c69657265787072657373646967 + 6974616c70696374757265416e6f746865726d61727269656474726166666963 + 6c656164696e676368616e67656463656e7472616c766963746f7279696d6167 + 65732f726561736f6e7373747564696573666561747572656c697374696e676d + 7573742062657363686f6f6c7356657273696f6e757375616c6c79657069736f + 6465706c6179696e6767726f77696e676f6276696f75736f7665726c61797072 + 6573656e74616374696f6e733c2f756c3e0d0a77726170706572616c72656164 + 796365727461696e7265616c69747973746f72616765616e6f74686572646573 + 6b746f706f6666657265647061747465726e756e757375616c4469676974616c + 6361706974616c576562736974656661696c757265636f6e6e65637472656475 + 636564416e64726f696464656361646573726567756c61722026616d703b2061 + 6e696d616c7372656c656173654175746f6d617467657474696e676d6574686f + 64736e6f7468696e67506f70756c617263617074696f6e6c6574746572736361 + 7074757265736369656e63656c6963656e73656368616e676573456e676c616e + 643d3126616d703b486973746f7279203d206e65772043656e7472616c757064 + 617465645370656369616c4e6574776f726b72657175697265636f6d6d656e74 + 7761726e696e67436f6c6c656765746f6f6c62617272656d61696e7362656361 + 757365656c65637465644465757473636866696e616e6365776f726b65727371 + 7569636b6c796265747765656e65786163746c7973657474696e676469736561 + 7365536f6369657479776561706f6e7365786869626974266c743b212d2d436f + 6e74726f6c636c6173736573636f76657265646f75746c696e6561747461636b + 73646576696365732877696e646f77707572706f73657469746c653d224d6f62 + 696c65206b696c6c696e6773686f77696e674974616c69616e64726f70706564 + 68656176696c79656666656374732d31275d293b0a636f6e6669726d43757272 + 656e74616476616e636573686172696e676f70656e696e6764726177696e6762 + 696c6c696f6e6f7264657265644765726d616e7972656c617465643c2f666f72 + 6d3e696e636c75646577686574686572646566696e6564536369656e63656361 + 74616c6f6741727469636c65627574746f6e736c617267657374756e69666f72 + 6d6a6f75726e6579736964656261724368696361676f686f6c6964617947656e + 6572616c706173736167652c2671756f743b616e696d6174656665656c696e67 + 6172726976656470617373696e676e61747572616c726f7567686c792e0a0a54 + 686520627574206e6f7464656e736974794272697461696e4368696e6573656c + 61636b206f66747269627574654972656c616e642220646174612d666163746f + 727372656365697665746861742069734c69627261727968757362616e64696e + 206661637461666661697273436861726c65737261646963616c62726f756768 + 7466696e64696e676c616e64696e673a6c616e673d2272657475726e206c6561 + 64657273706c616e6e65647072656d69756d7061636b616765416d6572696361 + 45646974696f6e5d2671756f743b4d6573736167656e65656420746f76616c75 + 653d22636f6d706c65786c6f6f6b696e6773746174696f6e62656c6965766573 + 6d616c6c65722d6d6f62696c657265636f72647377616e7420746f6b696e6420 + 6f6646697265666f78796f752061726573696d696c6172737475646965646d61 + 78696d756d68656164696e6772617069646c79636c696d6174656b696e67646f + 6d656d6572676564616d6f756e7473666f756e64656470696f6e656572666f72 + 6d756c6164796e61737479686f7720746f20537570706f7274726576656e7565 + 65636f6e6f6d79526573756c747362726f74686572736f6c646965726c617267 + 656c7963616c6c696e672e2671756f743b4163636f756e744564776172642073 + 65676d656e74526f62657274206566666f727473506163696669636c6561726e + 6564757020776974686865696768743a77652068617665416e67656c65736e61 + 74696f6e735f7365617263686170706c696564616371756972656d6173736976 + 656772616e7465643a2066616c7365747265617465646269676765737462656e + 6566697464726976696e67537475646965736d696e696d756d70657268617073 + 6d6f726e696e6773656c6c696e67697320757365647265766572736576617269 + 616e7420726f6c653d226d697373696e676163686965766570726f6d6f746573 + 747564656e74736f6d656f6e6565787472656d65726573746f7265626f74746f + 6d3a65766f6c766564616c6c20746865736974656d6170656e676c6973687761 + 7920746f202041756775737473796d626f6c73436f6d70616e796d6174746572 + 736d75736963616c616761696e737473657276696e677d2928293b0d0a706179 + 6d656e7474726f75626c65636f6e63657074636f6d70617265706172656e7473 + 706c6179657273726567696f6e736d6f6e69746f722027275468652077696e6e + 696e676578706c6f72656164617074656447616c6c65727970726f6475636561 + 62696c697479656e68616e636563617265657273292e2054686520636f6c6c65 + 637453656172636820616e6369656e7465786973746564666f6f746572206861 + 6e646c65727072696e746564636f6e736f6c654561737465726e6578706f7274 + 7377696e646f77734368616e6e656c696c6c6567616c6e65757472616c737567 + 676573745f6865616465727369676e696e672e68746d6c223e736574746c6564 + 7765737465726e63617573696e672d7765626b6974636c61696d65644a757374 + 6963656368617074657276696374696d7354686f6d6173206d6f7a696c6c6170 + 726f6d6973657061727469657365646974696f6e6f7574736964653a66616c73 + 652c68756e647265644f6c796d7069635f627574746f6e617574686f72737265 + 61636865646368726f6e696364656d616e64737365636f6e647370726f746563 + 7461646f70746564707265706172656e65697468657267726561746c79677265 + 617465726f766572616c6c696d70726f7665636f6d6d616e647370656369616c + 7365617263682e776f727368697066756e64696e6774686f7567687468696768 + 657374696e73746561647574696c6974797175617274657243756c7475726574 + 657374696e67636c6561726c796578706f73656442726f777365726c69626572 + 616c7d20636174636850726f6a6563746578616d706c656869646528293b466c + 6f72696461616e7377657273616c6c6f776564456d7065726f72646566656e73 + 65736572696f757366726565646f6d5365766572616c2d627574746f6e467572 + 746865726f7574206f6620213d206e756c6c747261696e656444656e6d61726b + 766f69642830292f616c6c2e6a7370726576656e745265717565737453746570 + 68656e0a0a5768656e206f6273657276653c2f68323e0d0a4d6f6465726e2070 + 726f766964652220616c743d22626f72646572732e0a0a466f72200a0a4d616e + 792061727469737473706f7765726564706572666f726d66696374696f6e7479 + 7065206f666d65646963616c7469636b6574736f70706f736564436f756e6369 + 6c7769746e6573736a75737469636547656f7267652042656c6769756d2e2e2e + 3c2f613e747769747465726e6f7461626c7977616974696e6777617266617265 + 204f746865722072616e6b696e67706872617365736d656e74696f6e73757276 + 6976657363686f6c61723c2f703e0d0a20436f756e74727969676e6f7265646c + 6f7373206f666a75737420617347656f72676961737472616e67653c68656164 + 3e3c73746f7070656431275d293b0d0a69736c616e64736e6f7461626c65626f + 726465723a6c697374206f66636172726965643130302c3030303c2f68333e0a + 207365766572616c6265636f6d657373656c6563742077656464696e6730302e + 68746d6c6d6f6e617263686f66662074686574656163686572686967686c7920 + 62696f6c6f67796c696665206f666f72206576656e72697365206f6626726171 + 756f3b706c75736f6e6568756e74696e672874686f756768446f75676c61736a + 6f696e696e67636972636c6573466f7220746865416e6369656e74566965746e + 616d76656869636c65737563682061736372797374616c76616c7565203d5769 + 6e646f7773656e6a6f7965646120736d616c6c617373756d65643c612069643d + 22666f726569676e20416c6c207269686f7720746865446973706c6179726574 + 69726564686f776576657268696464656e3b626174746c65737365656b696e67 + 636162696e6574776173206e6f746c6f6f6b206174636f6e6475637467657420 + 7468654a616e7561727968617070656e737475726e696e67613a686f7665724f + 6e6c696e65204672656e6368206c61636b696e677479706963616c6578747261 + 6374656e656d6965736576656e20696667656e65726174646563696465646172 + 65206e6f742f73656172636862656c696566732d696d6167653a6c6f63617465 + 647374617469632e6c6f67696e223e636f6e7665727476696f6c656e74656e74 + 657265646669727374223e6369726375697446696e6c616e646368656d697374 + 73686520776173313070783b223e61732073756368646976696465643c2f7370 + 616e3e77696c6c2062656c696e65206f66612067726561746d7973746572792f + 696e6465782e66616c6c696e6764756520746f207261696c776179636f6c6c65 + 67656d6f6e7374657264657363656e74697420776974686e75636c6561724a65 + 776973682070726f7465737442726974697368666c6f77657273707265646963 + 747265666f726d73627574746f6e2077686f207761736c656374757265696e73 + 74616e747375696369646567656e65726963706572696f64736d61726b657473 + 536f6369616c2066697368696e67636f6d62696e656772617068696377696e6e + 6572733c6272202f3e3c627920746865204e61747572616c5072697661637963 + 6f6f6b6965736f7574636f6d657265736f6c7665537765646973686272696566 + 6c795065727369616e736f206d75636843656e7475727964657069637473636f + 6c756d6e73686f7573696e67736372697074736e65787420746f62656172696e + 676d617070696e67726576697365646a5175657279282d77696474683a746974 + 6c65223e746f6f6c74697053656374696f6e64657369676e735475726b697368 + 796f756e6765722e6d61746368287d2928293b0a0a6275726e696e676f706572 + 61746564656772656573736f757263653d52696368617264636c6f73656c7970 + 6c6173746963656e74726965733c2f74723e0d0a636f6c6f723a23756c206964 + 3d22706f7373657373726f6c6c696e67706879736963736661696c696e676578 + 6563757465636f6e746573746c696e6b20746f44656661756c743c6272202f3e + 0a3a20747275652c63686172746572746f757269736d636c617373696370726f + 636565646578706c61696e3c2f68313e0d0a6f6e6c696e652e3f786d6c207665 + 68656c70696e676469616d6f6e64757365207468656169726c696e65656e6420 + 2d2d3e292e617474722872656164657273686f7374696e672366666666666672 + 65616c697a6556696e63656e747369676e616c73207372633d222f50726f6475 + 6374646573706974656469766572736574656c6c696e675075626c6963206865 + 6c6420696e4a6f736570682074686561747265616666656374733c7374796c65 + 3e61206c61726765646f65736e27746c617465722c20456c656d656e74666176 + 69636f6e63726561746f7248756e67617279416972706f727473656520746865 + 736f20746861744d69636861656c53797374656d7350726f6772616d732c2061 + 6e64202077696474683d652671756f743b74726164696e676c656674223e0a70 + 6572736f6e73476f6c64656e20416666616972736772616d6d6172666f726d69 + 6e6764657374726f7969646561206f6663617365206f666f6c64657374207468 + 69732069732e737263203d20636172746f6f6e72656769737472436f6d6d6f6e + 734d75736c696d7357686174206973696e206d616e796d61726b696e67726576 + 65616c73496e646565642c657175616c6c792f73686f775f616f7574646f6f72 + 657363617065284175737472696167656e6574696373797374656d2c496e2074 + 68652073697474696e67486520616c736f49736c616e647341636164656d790a + 09093c212d2d44616e69656c2062696e64696e67626c6f636b223e696d706f73 + 65647574696c697a654162726168616d286578636570747b77696474683a7075 + 7474696e67292e68746d6c287c7c205b5d3b0a444154415b202a6b6974636865 + 6e6d6f756e74656461637475616c206469616c6563746d61696e6c79205f626c + 616e6b27696e7374616c6c6578706572747369662874797065497420616c736f + 26636f70793b20223e5465726d73626f726e20696e4f7074696f6e7365617374 + 65726e74616c6b696e67636f6e6365726e6761696e6564206f6e676f696e676a + 75737469667963726974696373666163746f7279697473206f776e6173736175 + 6c74696e76697465646c617374696e67686973206f776e687265663d222f2220 + 72656c3d22646576656c6f70636f6e636572746469616772616d646f6c6c6172 + 73636c75737465727068703f69643d616c636f686f6c293b7d2928293b757369 + 6e6720613e3c7370616e3e76657373656c737265766976616c41646472657373 + 616d6174657572616e64726f6964616c6c65676564696c6c6e65737377616c6b + 696e6763656e746572737175616c6966796d617463686573756e696669656465 + 7874696e6374446566656e73656469656420696e0a093c212d2d20637573746f + 6d736c696e6b696e674c6974746c6520426f6f6b206f666576656e696e676d69 + 6e2e6a733f617265207468656b6f6e74616b74746f64617927732e68746d6c22 + 207461726765743d77656172696e67416c6c205269673b0a7d2928293b726169 + 73696e6720416c736f2c206372756369616c61626f7574223e6465636c617265 + 2d2d3e0a3c736366697265666f786173206d7563686170706c696573696e6465 + 782c20732c206275742074797065203d200a0d0a3c212d2d746f776172647352 + 65636f72647350726976617465466f726569676e5072656d69657263686f6963 + 65735669727475616c72657475726e73436f6d6d656e74506f7765726564696e + 6c696e653b706f76657274796368616d6265724c6976696e6720766f6c756d65 + 73416e74686f6e796c6f67696e222052656c6174656445636f6e6f6d79726561 + 6368657363757474696e67677261766974796c69666520696e43686170746572 + 2d736861646f774e6f7461626c653c2f74643e0d0a2072657475726e73746164 + 69756d7769646765747376617279696e6774726176656c7368656c6420627977 + 686f20617265776f726b20696e666163756c7479616e67756c617277686f2068 + 6164616972706f7274746f776e206f660a0a536f6d652027636c69636b276368 + 61726765736b6579776f726469742077696c6c63697479206f66287468697329 + 3b416e6472657720756e6971756520636865636b65646f72206d6f7265333030 + 70783b2072657475726e3b7273696f6e3d22706c7567696e7377697468696e20 + 68657273656c6653746174696f6e4665646572616c76656e747572657075626c + 69736873656e7420746f74656e73696f6e61637472657373636f6d6520746f66 + 696e6765727344756b65206f6670656f706c652c6578706c6f69747768617420 + 69736861726d6f6e7961206d616a6f72223a2268747470696e20686973206d65 + 6e75223e0a6d6f6e74686c796f666669636572636f756e63696c6761696e696e + 676576656e20696e53756d6d61727964617465206f666c6f79616c7479666974 + 6e657373616e6420776173656d7065726f7273757072656d655365636f6e6420 + 68656172696e675275737369616e6c6f6e67657374416c62657274616c617465 + 72616c736574206f6620736d616c6c223e2e617070656e64646f207769746866 + 65646572616c62616e6b206f6662656e65617468446573706974654361706974 + 616c67726f756e6473292c20616e642070657263656e7469742066726f6d636c + 6f73696e67636f6e7461696e496e73746561646669667465656e61732077656c + 6c2e7961686f6f2e726573706f6e64666967687465726f627363757265726566 + 6c6563746f7267616e69633d204d6174682e65646974696e676f6e6c696e6520 + 70616464696e67612077686f6c656f6e6572726f7279656172206f66656e6420 + 6f6620626172726965727768656e20697468656164657220686f6d65206f6672 + 6573756d656472656e616d65647374726f6e673e68656174696e677265746169 + 6e73636c6f75646672776179206f66204d6172636820316b6e6f77696e67696e + 20706172744265747765656e6c6573736f6e73636c6f73657374766972747561 + 6c6c696e6b73223e63726f73736564454e44202d2d3e66616d6f757320617761 + 726465644c6963656e73654865616c746820666169726c79207765616c746879 + 6d696e696d616c4166726963616e636f6d706574656c6162656c223e73696e67 + 696e676661726d65727342726173696c29646973637573737265706c61636547 + 7265676f7279666f6e7420636f70757273756564617070656172736d616b6520 + 7570726f756e646564626f7468206f66626c6f636b6564736177207468656f66 + 6669636573636f6c6f757273696628646f63757768656e206865656e666f7263 + 6570757368286675417567757374205554462d38223e46616e74617379696e20 + 6d6f7374696e6a75726564557375616c6c796661726d696e67636c6f73757265 + 6f626a65637420646566656e6365757365206f66204d65646963616c3c626f64 + 793e0a65766964656e74626520757365646b6579436f64657369787465656e49 + 736c616d696323303030303030656e7469726520776964656c79206163746976 + 652028747970656f666f6e652063616e636f6c6f72203d737065616b65726578 + 74656e6473506879736963737465727261696e3c74626f64793e66756e657261 + 6c76696577696e676d6964646c6520637269636b657470726f70686574736869 + 66746564646f63746f727352757373656c6c20746172676574636f6d70616374 + 616c6765627261736f6369616c2d62756c6b206f666d616e20616e643c2f7464 + 3e0a206865206c656674292e76616c282966616c7365293b6c6f676963616c62 + 616e6b696e67686f6d6520746f6e616d696e67204172697a6f6e616372656469 + 7473293b0a7d293b0a666f756e646572696e207475726e436f6c6c696e736265 + 666f72652042757420746865636861726765645469746c65223e436170746169 + 6e7370656c6c6564676f6464657373546167202d2d3e416464696e673a627574 + 20776173526563656e742070617469656e746261636b20696e3d66616c736526 + 4c696e636f6c6e7765206b6e6f77436f756e7465724a75646169736d73637269 + 707420616c7465726564275d293b0a202068617320746865756e636c65617245 + 76656e74272c626f746820696e6e6f7420616c6c0a0a3c212d2d20706c616369 + 6e676861726420746f2063656e746572736f7274206f66636c69656e74737374 + 72656574734265726e6172646173736572747374656e6420746f66616e746173 + 79646f776e20696e686172626f757246726565646f6d6a6577656c72792f6162 + 6f75742e2e7365617263686c6567656e64736973206d6164656d6f6465726e20 + 6f6e6c79206f6e6f6e6c7920746f696d61676522206c696e656172207061696e + 746572616e64206e6f74726172656c79206163726f6e796d64656c6976657273 + 686f72746572303026616d703b6173206d616e7977696474683d222f2a203c21 + 5b437469746c65203d6f6620746865206c6f77657374207069636b6564206573 + 636170656475736573206f6670656f706c6573205075626c69634d6174746865 + 777461637469637364616d6167656477617920666f726c617773206f66656173 + 7920746f2077696e646f777374726f6e67202073696d706c657d636174636828 + 736576656e7468696e666f626f7877656e7420746f7061696e74656463697469 + 7a656e4920646f6e2774726574726561742e20536f6d652077772e22293b0a62 + 6f6d62696e676d61696c746f3a6d61646520696e2e204d616e79206361727269 + 65737c7c7b7d3b7769776f726b206f6673796e6f6e796d646566656174736661 + 766f7265646f70746963616c70616765547261756e6c6573732073656e64696e + 676c656674223e3c636f6d53636f72416c6c207468656a51756572792e746f75 + 72697374436c617373696366616c7365222057696c68656c6d73756275726273 + 67656e75696e65626973686f70732e73706c697428676c6f62616c20666f6c6c + 6f7773626f6479206f666e6f6d696e616c436f6e74616374736563756c61726c + 65667420746f63686965666c792d68696464656e2d62616e6e65723c2f6c693e + 0a0a2e205768656e20696e20626f74686469736d6973734578706c6f7265616c + 776179732076696120746865737061c3b16f6c77656c6661726572756c696e67 + 20617272616e67656361707461696e68697320736f6e72756c65206f66686520 + 746f6f6b697473656c662c3d3026616d703b2863616c6c656473616d706c6573 + 746f206d616b65636f6d2f7061674d617274696e204b656e6e65647961636365 + 70747366756c6c206f6668616e646c6564426573696465732f2f2d2d3e3c2f61 + 626c6520746f74617267657473657373656e636568696d20746f206974732062 + 7920636f6d6d6f6e2e6d696e6572616c746f2074616b657761797320746f732e + 6f72672f6c6164766973656470656e616c747973696d706c653a696620746865 + 794c657474657273612073686f727448657262657274737472696b6573206772 + 6f7570732e6c656e677468666c69676874736f7665726c6170736c6f776c7920 + 6c657373657220736f6369616c203c2f703e0a0909697420696e746f72616e6b + 65642072617465206f66756c3e0d0a2020617474656d707470616972206f666d + 616b652069744b6f6e74616b74416e746f6e696f686176696e6720726174696e + 67732061637469766573747265616d737472617070656422292e63737328686f + 7374696c656c65616420746f6c6974746c652067726f7570732c506963747572 + 652d2d3e0d0a0d0a20726f77733d22206f626a656374696e76657273653c666f + 6f746572437573746f6d563e3c5c2f736372736f6c76696e674368616d626572 + 736c6176657279776f756e64656477686572656173213d2027756e64666f7220 + 616c6c706172746c79202d72696768743a4172616269616e6261636b65642063 + 656e74757279756e6974206f666d6f62696c652d4575726f70652c697320686f + 6d657269736b206f6664657369726564436c696e746f6e636f7374206f666167 + 65206f66206265636f6d65206e6f6e65206f66702671756f743b4d6964646c65 + 2065616427295b304372697469637373747564696f733e26636f70793b67726f + 7570223e617373656d626c6d616b696e6720707265737365647769646765742e + 70733a22203f2072656275696c74627920736f6d65466f726d65722065646974 + 6f727364656c6179656443616e6f6e69636861642074686570757368696e6763 + 6c6173733d22627574206172657061727469616c426162796c6f6e626f74746f + 6d2063617272696572436f6d6d616e646974732075736541732077697468636f + 75727365736120746869726464656e6f746573616c736f20696e486f7573746f + 6e323070783b223e61636375736564646f75626c6520676f616c206f6646616d + 6f757320292e62696e642870726965737473204f6e6c696e65696e204a756c79 + 7374202b202267636f6e73756c74646563696d616c68656c7066756c72657669 + 7665646973207665727972272b276970746c6f73696e672066656d616c657369 + 7320616c736f737472696e677364617973206f666172726976616c6675747572 + 65203c6f626a656374666f7263696e67537472696e672822202f3e0a09096865 + 7265206973656e636f6465642e20205468652062616c6c6f6f6e646f6e652062 + 792f636f6d6d6f6e6267636f6c6f726c6177206f6620496e6469616e6161766f + 6964656462757420746865327078203370786a71756572792e61667465722061 + 706f6c6963792e6d656e20616e64666f6f7465722d3d20747275653b666f7220 + 75736573637265656e2e496e6469616e20696d616765203d66616d696c792c68 + 7474703a2f2f20266e6273703b64726976657273657465726e616c73616d6520 + 61736e6f7469636564766965776572737d2928293b0a206973206d6f72657365 + 61736f6e73666f726d657220746865206e65776973206a757374636f6e73656e + 742053656172636877617320746865776879207468657368697070656462723e + 3c62723e77696474683a206865696768743d6d616465206f6663756973696e65 + 697320746861746120766572792041646d6972616c2066697865643b6e6f726d + 616c204d697373696f6e50726573732c206f6e746172696f6368617273657474 + 727920746f20696e76616465643d22747275652273706163696e676973206d6f + 737461206d6f726520746f74616c6c7966616c6c206f667d293b0d0a2020696d + 6d656e736574696d6520696e736574206f757473617469736679746f2066696e + 64646f776e20746f6c6f74206f6620506c6179657273696e204a756e65717561 + 6e74756d6e6f742074686574696d6520746f64697374616e7446696e6e697368 + 737263203d202873696e676c652068656c70206f664765726d616e206c617720 + 616e646c6162656c6564666f7265737473636f6f6b696e677370616365223e68 + 65616465722d77656c6c2061735374616e6c6579627269646765732f676c6f62 + 616c43726f617469612041626f7574205b305d3b0a202069742c20616e646772 + 6f757065646265696e672061297b7468726f776865206d6164656c6967687465 + 726574686963616c46464646464622626f74746f6d226c696b65206120656d70 + 6c6f79736c69766520696e6173207365656e7072696e7465726d6f7374206f66 + 75622d6c696e6b72656a65637473616e6420757365696d616765223e73756363 + 65656466656564696e674e75636c656172696e666f726d61746f2068656c7057 + 6f6d656e27734e6569746865724d65786963616e70726f7465696e3c7461626c + 65206279206d616e796865616c7468796c617773756974646576697365642e70 + 757368287b73656c6c65727373696d706c79205468726f7567682e636f6f6b69 + 6520496d616765286f6c646572223e75732e6a73223e2053696e636520756e69 + 766572736c6172676572206f70656e20746f212d2d20656e646c69657320696e + 275d293b0d0a20206d61726b657477686f206973202822444f4d436f6d616e61 + 6765646f6e6520666f72747970656f66204b696e67646f6d70726f6669747370 + 726f706f7365746f2073686f7763656e7465723b6d6164652069746472657373 + 65647765726520696e6d6978747572657072656369736561726973696e677372 + 63203d20276d616b652061207365637572656442617074697374766f74696e67 + 200a0909766172204d61726368203267726577207570436c696d6174652e7265 + 6d6f7665736b696c6c6564776179207468653c2f686561643e66616365206f66 + 616374696e67207269676874223e746f20776f726b7265647563657368617320 + 6861646572656374656473686f7728293b616374696f6e3d626f6f6b206f6661 + 6e20617265613d3d20226874743c6865616465720a3c68746d6c3e636f6e666f + 726d666163696e6720636f6f6b69652e72656c79206f6e686f73746564202e63 + 7573746f6d68652077656e7462757420666f727370726561642046616d696c79 + 2061206d65616e736f757420746865666f72756d732e666f6f74616765223e4d + 6f62696c436c656d656e7473222069643d2261732068696768696e74656e7365 + 2d2d3e3c212d2d66656d616c65206973207365656e696d706c69656473657420 + 74686561207374617465616e6420686973666173746573746265736964657362 + 7574746f6e5f626f756e646564223e3c696d6720496e666f626f786576656e74 + 732c6120796f756e67616e64206172654e617469766520636865617065725469 + 6d656f7574616e6420686173656e67696e6573776f6e20746865286d6f73746c + 7972696768743a2066696e642061202d626f74746f6d5072696e636520617265 + 61206f666d6f7265206f667365617263685f6e61747572652c6c6567616c6c79 + 706572696f642c6c616e64206f666f722077697468696e647563656470726f76 + 696e676d697373696c656c6f63616c6c79416761696e7374746865207761796b + 2671756f743b70783b223e0d0a707573686564206162616e646f6e6e756d6572 + 616c4365727461696e496e20746869736d6f726520696e6f7220736f6d656e61 + 6d65206973616e642c20696e63726f776e65644953424e20302d637265617465 + 734f63746f6265726d6179206e6f7463656e746572206c61746520696e446566 + 656e6365656e61637465647769736820746f62726f61646c79636f6f6c696e67 + 6f6e6c6f61643d69742e205468657265636f7665724d656d6265727368656967 + 687420617373756d65733c68746d6c3e0a70656f706c652e696e206f6e65203d + 77696e646f77666f6f7465725f6120676f6f642072656b6c616d616f74686572 + 732c746f20746869735f636f6f6b696570616e656c223e4c6f6e646f6e2c6465 + 66696e6573637275736865646261707469736d636f617374616c737461747573 + 207469746c6522206d6f766520746f6c6f737420696e62657474657220696d70 + 6c696573726976616c7279736572766572732053797374656d50657268617073 + 657320616e6420636f6e74656e64666c6f77696e676c61737465642072697365 + 20696e47656e6573697376696577206f66726973696e67207365656d20746f62 + 757420696e206261636b696e6768652077696c6c676976656e2061676976696e + 67206369746965732e666c6f77206f66204c6174657220616c6c206275744869 + 67687761796f6e6c792062797369676e206f66686520646f6573646966666572 + 736261747465727926616d703b6c6173696e676c657374687265617473696e74 + 6567657274616b65206f6e7265667573656463616c6c6564203d555326616d70 + 536565207468656e6174697665736279207468697373797374656d2e68656164 + 206f663a686f7665722c6c65736269616e7375726e616d65616e6420616c6c63 + 6f6d6d6f6e2f6865616465725f5f706172616d73486172766172642f70697865 + 6c2e72656d6f76616c736f206c6f6e67726f6c65206f666a6f696e746c79736b + 7973637261556e69636f64656272202f3e0d0a41746c616e74616e75636c6575 + 73436f756e74792c707572656c7920636f756e74223e656173696c7920627569 + 6c6420616f6e636c69636b6120676976656e706f696e746572682671756f743b + 6576656e747320656c7365207b0a646974696f6e736e6f77207468652c207769 + 7468206d616e2077686f6f72672f5765626f6e6520616e64636176616c727948 + 65206469656473656174746c6530302c303030207b77696e646f776861766520 + 746f69662877696e64616e6420697473736f6c656c79206d2671756f743b7265 + 6e65776564446574726f6974616d6f6e677374656974686572207468656d2069 + 6e53656e61746f7255733c2f613e3c4b696e67206f664672616e6369732d7072 + 6f6475636865207573656461727420616e6468696d20616e6475736564206279 + 73636f72696e67617420686f6d65746f206861766572656c617465736962696c + 69747966616374696f6e42756666616c6f6c696e6b223e3c7768617420686566 + 72656520746f43697479206f66636f6d6520696e736563746f7273636f756e74 + 65646f6e65206461796e6572766f7573737175617265207d3b696628676f696e + 2077686174696d672220616c6973206f6e6c797365617263682f747565736461 + 796c6f6f73656c79536f6c6f6d6f6e73657875616c202d203c612068726d6564 + 69756d22444f204e4f54204672616e63652c7769746820612077617220616e64 + 7365636f6e642074616b652061203e0d0a0d0a0d0a6d61726b65742e68696768 + 776179646f6e6520696e63746976697479226c617374223e6f626c6967656472 + 69736520746f22756e646566696d61646520746f204561726c79207072616973 + 6564696e2069747320666f72206869736174686c6574654a7570697465725961 + 686f6f21207465726d656420736f206d616e797265616c6c7920732e20546865 + 206120776f6d616e3f76616c75653d6469726563742072696768742220626963 + 79636c656163696e673d2264617920616e6473746174696e675261746865722c + 686967686572204f666669636520617265206e6f7774696d65732c207768656e + 20612070617920666f726f6e20746869732d6c696e6b223e3b626f7264657261 + 726f756e6420616e6e75616c20746865204e6577707574207468652e636f6d22 + 2074616b696e20746f6120627269656628696e2074686567726f7570732e3b20 + 7769647468656e7a796d657373696d706c6520696e206c6174657b7265747572 + 6e746865726170796120706f696e7462616e6e696e67696e6b73223e0a28293b + 222072656120706c6163655c75303033436161626f7574206174723e0d0a0909 + 63636f756e7420676976657320613c5343524950545261696c7761797468656d + 65732f746f6f6c626f784279496428227868756d616e732c7761746368657369 + 6e20736f6d6520696620287769636f6d696e6720666f726d61747320556e6465 + 72206275742068617368616e646564206d6164652062797468616e20696e6665 + 6172206f6664656e6f7465642f696672616d656c65667420696e766f6c746167 + 65696e2065616368612671756f743b62617365206f66496e206d616e79756e64 + 6572676f726567696d6573616374696f6e203c2f703e0d0a3c7573746f6d5661 + 3b2667743b3c2f696d706f7274736f7220746861746d6f73746c792026616d70 + 3b72652073697a653d223c2f613e3c2f686120636c6173737061737369766548 + 6f7374203d205768657468657266657274696c65566172696f75733d5b5d3b28 + 667563616d657261732f3e3c2f74643e61637473206173496e20736f6d653e0d + 0a0d0a3c216f7267616e6973203c6272202f3e4265696a696e67636174616cc3 + a0646575747363686575726f7065756575736b617261676165696c6765737665 + 6e736b6165737061c3b1616d656e73616a657573756172696f74726162616a6f + 6dc3a97869636f70c3a167696e617369656d70726573697374656d616f637475 + 627265647572616e746561c3b161646972656d70726573616d6f6d656e746f6e + 75657374726f7072696d65726174726176c3a973677261636961736e75657374 + 726170726f6365736f65737461646f7363616c69646164706572736f6e616ec3 + ba6d65726f6163756572646f6dc3ba736963616d69656d62726f6f6665727461 + 73616c67756e6f737061c3ad736573656a656d706c6f6465726563686f616465 + 6dc3a1737072697661646f61677265676172656e6c61636573706f7369626c65 + 686f74656c6573736576696c6c617072696d65726fc3ba6c74696d6f6576656e + 746f736172636869766f63756c747572616d756a65726573656e747261646161 + 6e756e63696f656d626172676f6d65726361646f6772616e6465736573747564 + 696f6d656a6f7265736665627265726f64697365c3b16f74757269736d6f63c3 + b36469676f706f72746164616573706163696f66616d696c6961616e746f6e69 + 6f7065726d69746567756172646172616c67756e617370726563696f73616c67 + 7569656e73656e7469646f7669736974617374c3ad74756c6f636f6e6f636572 + 736567756e646f636f6e73656a6f6672616e6369616d696e75746f7373656775 + 6e646174656e656d6f7365666563746f736dc3a16c61676173657369c3b36e72 + 6576697374616772616e616461636f6d70726172696e677265736f67617263c3 + ad6161636369c3b36e65637561646f72717569656e6573696e636c75736f6465 + 626572c3a16d617465726961686f6d627265736d756573747261706f6472c3ad + 616d61c3b1616e61c3ba6c74696d61657374616d6f736f66696369616c74616d + 6269656e6e696e67c3ba6e73616c75646f73706f64656d6f736d656a6f726172 + 706f736974696f6e627573696e657373686f6d65706167657365637572697479 + 6c616e67756167657374616e6461726463616d706169676e6665617475726573 + 63617465676f727965787465726e616c6368696c6472656e7265736572766564 + 726573656172636865786368616e67656661766f7269746574656d706c617465 + 6d696c6974617279696e64757374727973657276696365736d6174657269616c + 70726f64756374737a2d696e6465783a636f6d6d656e7473736f667477617265 + 636f6d706c65746563616c656e646172706c6174666f726d61727469636c6573 + 72657175697265646d6f76656d656e747175657374696f6e6275696c64696e67 + 706f6c6974696373706f737369626c6572656c6967696f6e706879736963616c + 666565646261636b7265676973746572706963747572657364697361626c6564 + 70726f746f636f6c61756469656e636573657474696e67736163746976697479 + 656c656d656e74736c6561726e696e67616e797468696e676162737472616374 + 70726f67726573736f766572766965776d6167617a696e6565636f6e6f6d6963 + 747261696e696e677072657373757265766172696f7573203c7374726f6e673e + 70726f706572747973686f7070696e67746f676574686572616476616e636564 + 6265686176696f72646f776e6c6f61646665617475726564666f6f7462616c6c + 73656c65637465644c616e677561676564697374616e636572656d656d626572 + 747261636b696e6770617373776f72646d6f64696669656473747564656e7473 + 6469726563746c796669676874696e676e6f72746865726e6461746162617365 + 666573746976616c627265616b696e676c6f636174696f6e696e7465726e6574 + 64726f70646f776e707261637469636565766964656e636566756e6374696f6e + 6d61727269616765726573706f6e736570726f626c656d736e65676174697665 + 70726f6772616d73616e616c7973697372656c656173656462616e6e6572223e + 7075726368617365706f6c6963696573726567696f6e616c6372656174697665 + 617267756d656e74626f6f6b6d61726b72656665727265726368656d6963616c + 6469766973696f6e63616c6c6261636b736570617261746570726f6a65637473 + 636f6e666c6963746861726477617265696e74657265737464656c6976657279 + 6d6f756e7461696e6f627461696e65643d2066616c73653b666f722876617220 + 61636365707465646361706163697479636f6d70757465726964656e74697479 + 6169726372616674656d706c6f79656470726f706f736564646f6d6573746963 + 696e636c7564657370726f7669646564686f73706974616c766572746963616c + 636f6c6c61707365617070726f616368706172746e6572736c6f676f223e3c61 + 6461756768746572617574686f72222063756c747572616c66616d696c696573 + 2f696d616765732f617373656d626c79706f77657266756c7465616368696e67 + 66696e69736865646469737472696374637269746963616c6367692d62696e2f + 707572706f7365737265717569726573656c656374696f6e6265636f6d696e67 + 70726f766964657361636164656d6963657865726369736561637475616c6c79 + 6d65646963696e65636f6e7374616e746163636964656e744d6167617a696e65 + 646f63756d656e747374617274696e67626f74746f6d223e6f62736572766564 + 3a202671756f743b657874656e64656470726576696f7573536f667477617265 + 637573746f6d65726465636973696f6e737472656e67746864657461696c6564 + 736c696768746c79706c616e6e696e67746578746172656163757272656e6379 + 65766572796f6e6573747261696768747472616e73666572706f736974697665 + 70726f647563656468657269746167657368697070696e676162736f6c757465 + 726563656976656472656c6576616e74627574746f6e222076696f6c656e6365 + 616e79776865726562656e65666974736c61756e63686564726563656e746c79 + 616c6c69616e6365666f6c6c6f7765646d756c7469706c6562756c6c6574696e + 696e636c756465646f63637572726564696e7465726e616c242874686973292e + 72657075626c69633e3c74723e3c7464636f6e67726573737265636f72646564 + 756c74696d617465736f6c7574696f6e3c756c2069643d22646973636f766572 + 486f6d653c2f613e77656273697465736e6574776f726b73616c74686f756768 + 656e746972656c796d656d6f7269616c6d65737361676573636f6e74696e7565 + 616374697665223e736f6d6577686174766963746f7269615765737465726e20 + 207469746c653d224c6f636174696f6e636f6e747261637476697369746f7273 + 446f776e6c6f6164776974686f7574207269676874223e0a6d65617375726573 + 7769647468203d207661726961626c65696e766f6c76656476697267696e6961 + 6e6f726d616c6c7968617070656e65646163636f756e74737374616e64696e67 + 6e6174696f6e616c52656769737465727072657061726564636f6e74726f6c73 + 6163637572617465626972746864617973747261746567796f6666696369616c + 67726170686963736372696d696e616c706f737369626c79636f6e73756d6572 + 506572736f6e616c737065616b696e6776616c69646174656163686965766564 + 2e6a706722202f3e6d616368696e65733c2f68323e0a20206b6579776f726473 + 667269656e646c7962726f7468657273636f6d62696e65646f726967696e616c + 636f6d706f7365646578706563746564616465717561746570616b697374616e + 666f6c6c6f77222076616c7561626c653c2f6c6162656c3e72656c6174697665 + 6272696e67696e67696e637265617365676f7665726e6f72706c7567696e732f + 4c697374206f6620486561646572223e22206e616d653d2220282671756f743b + 67726164756174653c2f686561643e0a636f6d6d657263656d616c6179736961 + 6469726563746f726d61696e7461696e3b6865696768743a7363686564756c65 + 6368616e67696e676261636b20746f20636174686f6c69637061747465726e73 + 636f6c6f723a20236772656174657374737570706c69657372656c6961626c65 + 3c2f756c3e0a09093c73656c65637420636974697a656e73636c6f7468696e67 + 7761746368696e673c6c692069643d2273706563696669636361727279696e67 + 73656e74656e63653c63656e7465723e636f6e74726173747468696e6b696e67 + 6361746368286529736f75746865726e4d69636861656c206d65726368616e74 + 6361726f7573656c70616464696e673a696e746572696f722e73706c69742822 + 6c697a6174696f6e4f63746f62657220297b72657475726e696d70726f766564 + 2d2d2667743b0a0a636f76657261676563686169726d616e2e706e6722202f3e + 7375626a656374735269636861726420776861746576657270726f6261626c79 + 7265636f766572796261736562616c6c6a7564676d656e74636f6e6e6563742e + 2e63737322202f3e20776562736974657265706f7274656464656661756c7422 + 2f3e3c2f613e0d0a656c65637472696373636f746c616e646372656174696f6e + 7175616e746974792e204953424e2030646964206e6f7420696e7374616e6365 + 2d7365617263682d22206c616e673d22737065616b657273436f6d7075746572 + 636f6e7461696e7361726368697665736d696e69737465727265616374696f6e + 646973636f756e744974616c69616e6f63726974657269617374726f6e676c79 + 3a2027687474703a2773637269707427636f766572696e676f66666572696e67 + 617070656172656442726974697368206964656e7469667946616365626f6f6b + 6e756d65726f757376656869636c6573636f6e6365726e73416d65726963616e + 68616e646c696e676469762069643d2257696c6c69616d2070726f7669646572 + 5f636f6e74656e74616363757261637973656374696f6e20616e646572736f6e + 666c657869626c6543617465676f72796c617772656e63653c7363726970743e + 6c61796f75743d22617070726f766564206d6178696d756d686561646572223e + 3c2f7461626c653e536572766963657368616d696c746f6e63757272656e7420 + 63616e616469616e6368616e6e656c732f7468656d65732f2f61727469636c65 + 6f7074696f6e616c706f72747567616c76616c75653d2222696e74657276616c + 776972656c657373656e7469746c65646167656e636965735365617263682220 + 6d6561737572656474686f7573616e647370656e64696e672668656c6c69703b + 6e65772044617465222073697a653d22706167654e616d656d6964646c652220 + 22202f3e3c2f613e68696464656e223e73657175656e6365706572736f6e616c + 6f766572666c6f776f70696e696f6e73696c6c696e6f69736c696e6b73223e0a + 093c7469746c653e76657273696f6e7373617475726461797465726d696e616c + 6974656d70726f70656e67696e65657273656374696f6e7364657369676e6572 + 70726f706f73616c3d2266616c73652245737061c3b16f6c72656c6561736573 + 7375626d6974222065722671756f743b6164646974696f6e73796d70746f6d73 + 6f7269656e7465647265736f757263657269676874223e3c706c656173757265 + 73746174696f6e73686973746f72792e6c656176696e672020626f726465723d + 636f6e74656e747363656e746572223e2e0a0a536f6d65206469726563746564 + 7375697461626c6562756c67617269612e73686f7728293b64657369676e6564 + 47656e6572616c20636f6e63657074734578616d706c657377696c6c69616d73 + 4f726967696e616c223e3c7370616e3e736561726368223e6f70657261746f72 + 726571756573747361202671756f743b616c6c6f77696e67446f63756d656e74 + 7265766973696f6e2e200a0a54686520796f757273656c66436f6e7461637420 + 6d6963686967616e456e676c69736820636f6c756d6269617072696f72697479 + 7072696e74696e676472696e6b696e67666163696c69747972657475726e6564 + 436f6e74656e74206f666669636572735275737369616e2067656e6572617465 + 2d383835392d3122696e64696361746566616d696c696172207175616c697479 + 6d617267696e3a3020636f6e74656e7476696577706f7274636f6e7461637473 + 2d7469746c65223e706f727461626c652e6c656e67746820656c696769626c65 + 696e766f6c76657361746c616e7469636f6e6c6f61643d2264656661756c742e + 737570706c6965647061796d656e7473676c6f73736172790a0a416674657220 + 67756964616e63653c2f74643e3c7464656e636f64696e676d6964646c65223e + 63616d6520746f20646973706c61797373636f74746973686a6f6e617468616e + 6d616a6f72697479776964676574732e636c696e6963616c746861696c616e64 + 74656163686572733c686561643e0a096166666563746564737570706f727473 + 706f696e7465723b746f537472696e673c2f736d616c6c3e6f6b6c61686f6d61 + 77696c6c20626520696e766573746f72302220616c743d22686f6c6964617973 + 5265736f757263656c6963656e73656420287768696368202e20416674657220 + 636f6e73696465727669736974696e676578706c6f7265727072696d61727920 + 7365617263682220616e64726f696422717569636b6c79206d656574696e6773 + 657374696d6174653b72657475726e203b636f6c6f723a23206865696768743d + 617070726f76616c2c202671756f743b20636865636b65642e6d696e2e6a7322 + 6d61676e657469633e3c2f613e3c2f68666f7265636173742e205768696c6520 + 74687572736461796476657274697365266561637574653b686173436c617373 + 6576616c756174656f72646572696e676578697374696e6770617469656e7473 + 204f6e6c696e6520636f6c6f7261646f4f7074696f6e732263616d7062656c6c + 3c212d2d20656e643c2f7370616e3e3c3c6272202f3e0d0a5f706f707570737c + 736369656e6365732c2671756f743b207175616c6974792057696e646f777320 + 61737369676e65646865696768743a203c6220636c6173736c652671756f743b + 2076616c75653d2220436f6d70616e796578616d706c65733c696672616d6520 + 62656c696576657370726573656e74736d61727368616c6c70617274206f6620 + 70726f7065726c79292e0a0a546865207461786f6e6f6d796d756368206f6620 + 3c2f7370616e3e0a2220646174612d737274756775c3aa737363726f6c6c546f + 2070726f6a6563743c686561643e0d0a6174746f726e6579656d706861736973 + 73706f6e736f727366616e6379626f78776f726c6427732077696c646c696665 + 636865636b65643d73657373696f6e7370726f6772616d6d70783b666f6e742d + 2050726f6a6563746a6f75726e616c7362656c69657665647661636174696f6e + 74686f6d70736f6e6c69676874696e67616e6420746865207370656369616c20 + 626f726465723d30636865636b696e673c2f74626f64793e3c627574746f6e20 + 436f6d706c657465636c6561726669780a3c686561643e0a61727469636c6520 + 3c73656374696f6e66696e64696e6773726f6c6520696e20706f70756c617220 + 204f63746f62657277656273697465206578706f737572657573656420746f20 + 206368616e6765736f70657261746564636c69636b696e67656e746572696e67 + 636f6d6d616e6473696e666f726d6564206e756d6265727320203c2f6469763e + 6372656174696e676f6e5375626d69746d6172796c616e64636f6c6c65676573 + 616e616c797469636c697374696e6773636f6e746163742e6c6f67676564496e + 61647669736f72797369626c696e6773636f6e74656e7422732671756f743b29 + 732e2054686973207061636b61676573636865636b626f787375676765737473 + 707265676e616e74746f6d6f72726f7773706163696e673d69636f6e2e706e67 + 6a6170616e657365636f646562617365627574746f6e223e67616d626c696e67 + 73756368206173202c207768696c65203c2f7370616e3e206d6973736f757269 + 73706f7274696e67746f703a317078202e3c2f7370616e3e74656e73696f6e73 + 77696474683d22326c617a796c6f61646e6f76656d6265727573656420696e20 + 6865696768743d226372697074223e0a266e6273703b3c2f3c74723e3c746420 + 6865696768743a322f70726f64756374636f756e74727920696e636c75646520 + 666f6f7465722220266c743b212d2d207469746c65223e3c2f6a71756572792e + 3c2f666f726d3e0a28e7ae80e4bd932928e7b981e9ab94296872766174736b69 + 6974616c69616e6f726f6dc3a26ec48374c3bc726bc3a765d8a7d8b1d8afd988 + 74616d6269c3a96e6e6f7469636961736d656e73616a6573706572736f6e6173 + 6465726563686f736e6163696f6e616c736572766963696f636f6e746163746f + 7573756172696f7370726f6772616d61676f626965726e6f656d707265736173 + 616e756e63696f7376616c656e636961636f6c6f6d6269616465737075c3a973 + 6465706f7274657370726f796563746f70726f647563746f70c3ba626c69636f + 6e6f736f74726f73686973746f72696170726573656e74656d696c6c6f6e6573 + 6d656469616e746570726567756e7461616e746572696f727265637572736f73 + 70726f626c656d6173616e746961676f6e75657374726f736f70696e69c3b36e + 696d7072696d69726d69656e74726173616dc3a97269636176656e6465646f72 + 736f636965646164726573706563746f7265616c697a6172726567697374726f + 70616c6162726173696e746572c3a973656e746f6e636573657370656369616c + 6d69656d62726f737265616c6964616463c3b372646f62617a617261676f7a61 + 70c3a167696e6173736f6369616c6573626c6f71756561726765737469c3b36e + 616c7175696c657273697374656d61736369656e63696173636f6d706c65746f + 7665727369c3b36e636f6d706c6574616573747564696f7370c3ba626c696361 + 6f626a657469766f616c6963616e74656275736361646f7263616e7469646164 + 656e747261646173616363696f6e65736172636869766f737375706572696f72 + 6d61796f72c3ad61616c656d616e696166756e6369c3b36ec3ba6c74696d6f73 + 68616369656e646f617175656c6c6f736564696369c3b36e6665726e616e646f + 616d6269656e746566616365626f6f6b6e75657374726173636c69656e746573 + 70726f6365736f7362617374616e746570726573656e74617265706f72746172 + 636f6e677265736f7075626c69636172636f6d657263696f636f6e747261746f + 6ac3b376656e6573646973747269746f74c3a9636e696361636f6e6a756e746f + 656e657267c3ad6174726162616a6172617374757269617372656369656e7465 + 7574696c697a6172626f6c6574c3ad6e73616c7661646f72636f727265637461 + 74726162616a6f737072696d65726f736e65676f63696f736c69626572746164 + 646574616c6c657370616e74616c6c617072c3b378696d6f616c6d6572c3ad61 + 616e696d616c6573717569c3a96e6573636f72617ac3b36e7365636369c3b36e + 62757363616e646f6f7063696f6e65736578746572696f72636f6e636570746f + 746f646176c3ad6167616c6572c3ad6165736372696269726d65646963696e61 + 6c6963656e636961636f6e73756c74616173706563746f736372c3ad74696361 + 64c3b36c617265736a757374696369616465626572c3a16e706572c3ad6f646f + 6e656365736974616d616e74656e65727065717565c3b16f7265636962696461 + 74726962756e616c74656e657269666563616e6369c3b36e63616e6172696173 + 64657363617267616469766572736f736d616c6c6f7263617265717569657265 + 74c3a9636e69636f6465626572c3ad6176697669656e646166696e616e7a6173 + 6164656c616e746566756e63696f6e61636f6e73656a6f73646966c3ad63696c + 6369756461646573616e7469677561736176616e7a61646174c3a9726d696e6f + 756e69646164657373c3a16e6368657a63616d7061c3b161736f66746f6e6963 + 7265766973746173636f6e7469656e65736563746f7265736d6f6d656e746f73 + 666163756c7461646372c3a96469746f6469766572736173737570756573746f + 666163746f726573736567756e646f737065717565c3b161d0b3d0bed0b4d0b0 + d0b5d181d0bbd0b8d0b5d181d182d18cd0b1d18bd0bbd0bed0b1d18bd182d18c + d18dd182d0bed0bcd095d181d0bbd0b8d182d0bed0b3d0bed0bcd0b5d0bdd18f + d0b2d181d0b5d185d18dd182d0bed0b9d0b4d0b0d0b6d0b5d0b1d18bd0bbd0b8 + d0b3d0bed0b4d183d0b4d0b5d0bdd18cd18dd182d0bed182d0b1d18bd0bbd0b0 + d181d0b5d0b1d18fd0bed0b4d0b8d0bdd181d0b5d0b1d0b5d0bdd0b0d0b4d0be + d181d0b0d0b9d182d184d0bed182d0bed0bdd0b5d0b3d0bed181d0b2d0bed0b8 + d181d0b2d0bed0b9d0b8d0b3d180d18bd182d0bed0b6d0b5d0b2d181d0b5d0bc + d181d0b2d0bed18ed0bbd0b8d188d18cd18dd182d0b8d185d0bfd0bed0bad0b0 + d0b4d0bdd0b5d0b9d0b4d0bed0bcd0b0d0bcd0b8d180d0b0d0bbd0b8d0b1d0be + d182d0b5d0bcd183d185d0bed182d18fd0b4d0b2d183d185d181d0b5d182d0b8 + d0bbd18ed0b4d0b8d0b4d0b5d0bbd0bed0bcd0b8d180d0b5d182d0b5d0b1d18f + d181d0b2d0bed0b5d0b2d0b8d0b4d0b5d187d0b5d0b3d0bed18dd182d0b8d0bc + d181d187d0b5d182d182d0b5d0bcd18bd186d0b5d0bdd18bd181d182d0b0d0bb + d0b2d0b5d0b4d18cd182d0b5d0bcd0b5d0b2d0bed0b4d18bd182d0b5d0b1d0b5 + d0b2d18bd188d0b5d0bdd0b0d0bcd0b8d182d0b8d0bfd0b0d182d0bed0bcd183 + d0bfd180d0b0d0b2d0bbd0b8d186d0b0d0bed0b4d0bdd0b0d0b3d0bed0b4d18b + d0b7d0bdd0b0d18ed0bcd0bed0b3d183d0b4d180d183d0b3d0b2d181d0b5d0b9 + d0b8d0b4d0b5d182d0bad0b8d0bdd0bed0bed0b4d0bdd0bed0b4d0b5d0bbd0b0 + d0b4d0b5d0bbd0b5d181d180d0bed0bad0b8d18ed0bdd18fd0b2d0b5d181d18c + d095d181d182d18cd180d0b0d0b7d0b0d0bdd0b0d188d0b8d8a7d984d984d987 + d8a7d984d8aad98ad8acd985d98ad8b9d8aed8a7d8b5d8a9d8a7d984d8b0d98a + d8b9d984d98ad987d8acd8afd98ad8afd8a7d984d8a2d986d8a7d984d8b1d8af + d8aad8add983d985d8b5d981d8add8a9d983d8a7d986d8aad8a7d984d984d98a + d98ad983d988d986d8b4d8a8d983d8a9d981d98ad987d8a7d8a8d986d8a7d8aa + d8add988d8a7d8a1d8a3d983d8abd8b1d8aed984d8a7d984d8a7d984d8add8a8 + d8afd984d98ad984d8afd8b1d988d8b3d8a7d8b6d8bad8b7d8aad983d988d986 + d987d986d8a7d983d8b3d8a7d8add8a9d986d8a7d8afd98ad8a7d984d8b7d8a8 + d8b9d984d98ad983d8b4d983d8b1d8a7d98ad985d983d986d985d986d987d8a7 + d8b4d8b1d983d8a9d8b1d8a6d98ad8b3d986d8b4d98ad8b7d985d8a7d8b0d8a7 + d8a7d984d981d986d8b4d8a8d8a7d8a8d8aad8b9d8a8d8b1d8b1d8add985d8a9 + d983d8a7d981d8a9d98ad982d988d984d985d8b1d983d8b2d983d984d985d8a9 + d8a3d8add985d8afd982d984d8a8d98ad98ad8b9d986d98ad8b5d988d8b1d8a9 + d8b7d8b1d98ad982d8b4d8a7d8b1d983d8acd988d8a7d984d8a3d8aed8b1d989 + d985d8b9d986d8a7d8a7d8a8d8add8abd8b9d8b1d988d8b6d8a8d8b4d983d984 + d985d8b3d8acd984d8a8d986d8a7d986d8aed8a7d984d8afd983d8aad8a7d8a8 + d983d984d98ad8a9d8a8d8afd988d986d8a3d98ad8b6d8a7d98ad988d8acd8af + d981d8b1d98ad982d983d8aad8a8d8aad8a3d981d8b6d984d985d8b7d8a8d8ae + d8a7d983d8abd8b1d8a8d8a7d8b1d983d8a7d981d8b6d984d8a7d8add984d989 + d986d981d8b3d987d8a3d98ad8a7d985d8b1d8afd988d8afd8a3d986d987d8a7 + d8afd98ad986d8a7d8a7d984d8a7d986d985d8b9d8b1d8b6d8aad8b9d984d985 + d8afd8a7d8aed984d985d985d983d98600000000000000000100010001000100 + 0200020002000200040004000400040000010203040506070706050403020100 + 08090a0b0c0d0e0f0f0e0d0c0b0a090810111213141516171716151413121110 + 18191a1b1c1d1e1f1f1e1d1c1b1a1918ffffffff0000000000000000ffffffff + 010000000200000002000000010000000100000003000000ffff000100000001 + 0000ffff00010000000800080008000800000001000200030004000500060007 + 7265736f7572636573636f756e74726965737175657374696f6e736571756970 + 6d656e74636f6d6d756e697479617661696c61626c65686967686c6967687444 + 54442f7868746d6c6d61726b6574696e676b6e6f776c65646765736f6d657468 + 696e67636f6e7461696e6572646972656374696f6e7375627363726962656164 + 76657274697365636861726163746572222076616c75653d223c2f73656c6563 + 743e4175737472616c69612220636c6173733d22736974756174696f6e617574 + 686f72697479666f6c6c6f77696e677072696d6172696c796f7065726174696f + 6e6368616c6c656e6765646576656c6f706564616e6f6e796d6f757366756e63 + 74696f6e2066756e6374696f6e73636f6d70616e696573737472756374757265 + 61677265656d656e7422207469746c653d22706f74656e7469616c6564756361 + 74696f6e617267756d656e74737365636f6e64617279636f707972696768746c + 616e6775616765736578636c7573697665636f6e646974696f6e3c2f666f726d + 3e0d0a73746174656d656e74617474656e74696f6e42696f6772617068797d20 + 656c7365207b0a736f6c7574696f6e737768656e2074686520416e616c797469 + 637374656d706c6174657364616e6765726f7573736174656c6c697465646f63 + 756d656e74737075626c6973686572696d706f7274616e7470726f746f747970 + 65696e666c75656e636526726171756f3b3c2f65666665637469766567656e65 + 72616c6c797472616e73666f726d62656175746966756c7472616e73706f7274 + 6f7267616e697a65647075626c697368656470726f6d696e656e74756e74696c + 207468657468756d626e61696c4e6174696f6e616c202e666f63757328293b6f + 76657220746865206d6967726174696f6e616e6e6f756e636564666f6f746572 + 223e0a657863657074696f6e6c657373207468616e657870656e73697665666f + 726d6174696f6e6672616d65776f726b7465727269746f72796e646963617469 + 6f6e63757272656e746c79636c6173734e616d6563726974696369736d747261 + 646974696f6e656c73657768657265416c6578616e6465726170706f696e7465 + 646d6174657269616c7362726f6164636173746d656e74696f6e656461666669 + 6c696174653c2f6f7074696f6e3e74726561746d656e74646966666572656e74 + 2f64656661756c742e507265736964656e746f6e636c69636b3d2262696f6772 + 617068796f74686572776973657065726d616e656e744672616ec3a761697348 + 6f6c6c79776f6f64657870616e73696f6e7374616e64617264733c2f7374796c + 653e0a726564756374696f6e446563656d626572207072656665727265644361 + 6d6272696467656f70706f6e656e7473427573696e65737320636f6e66757369 + 6f6e3e0a3c7469746c653e70726573656e7465646578706c61696e6564646f65 + 73206e6f7420776f726c6477696465696e74657266616365706f736974696f6e + 736e65777370617065723c2f7461626c653e0a6d6f756e7461696e736c696b65 + 2074686520657373656e7469616c66696e616e6369616c73656c656374696f6e + 616374696f6e3d222f6162616e646f6e6564456475636174696f6e7061727365 + 496e742873746162696c697479756e61626c6520746f3c2f7469746c653e0a72 + 656c6174696f6e734e6f74652074686174656666696369656e74706572666f72 + 6d656474776f20796561727353696e6365207468657468657265666f72657772 + 6170706572223e616c7465726e617465696e63726561736564426174746c6520 + 6f66706572636569766564747279696e6720746f6e6563657373617279706f72 + 747261796564656c656374696f6e73456c697a61626574683c2f696672616d65 + 3e646973636f76657279696e737572616e6365732e6c656e6774683b6c656765 + 6e6461727947656f67726170687963616e646964617465636f72706f72617465 + 736f6d6574696d657373657276696365732e696e686572697465643c2f737472 + 6f6e673e436f6d6d756e69747972656c6967696f75736c6f636174696f6e7343 + 6f6d6d69747465656275696c64696e677374686520776f726c646e6f206c6f6e + 676572626567696e6e696e677265666572656e636563616e6e6f742062656672 + 657175656e63797479706963616c6c79696e746f207468652072656c61746976 + 653b7265636f7264696e67707265736964656e74696e697469616c6c79746563 + 686e69717565746865206f7468657269742063616e2062656578697374656e63 + 65756e6465726c696e65746869732074696d6574656c6570686f6e656974656d + 73636f7065707261637469636573616476616e74616765293b72657475726e20 + 466f72206f7468657270726f766964696e6764656d6f6372616379626f746820 + 74686520657874656e73697665737566666572696e67737570706f7274656463 + 6f6d7075746572732066756e6374696f6e70726163746963616c736169642074 + 6861746974206d6179206265456e676c6973683c2f66726f6d20746865207363 + 686564756c6564646f776e6c6f6164733c2f6c6162656c3e0a73757370656374 + 65646d617267696e3a203073706972697475616c3c2f686561643e0a0a6d6963 + 726f736f66746772616475616c6c79646973637573736564686520626563616d + 656578656375746976656a71756572792e6a73686f757365686f6c64636f6e66 + 69726d65647075726368617365646c69746572616c6c7964657374726f796564 + 757020746f20746865766172696174696f6e72656d61696e696e676974206973 + 206e6f7463656e7475726965734a6170616e65736520616d6f6e672074686563 + 6f6d706c65746564616c676f726974686d696e74657265737473726562656c6c + 696f6e756e646566696e6564656e636f7572616765726573697a61626c65696e + 766f6c76696e6773656e736974697665756e6976657273616c70726f76697369 + 6f6e28616c74686f756768666561747572696e67636f6e647563746564292c20 + 776869636820636f6e74696e7565642d686561646572223e4665627275617279 + 206e756d65726f7573206f766572666c6f773a636f6d706f6e656e7466726167 + 6d656e7473657863656c6c656e74636f6c7370616e3d22746563686e6963616c + 6e6561722074686520416476616e63656420736f75726365206f666578707265 + 73736564486f6e67204b6f6e672046616365626f6f6b6d756c7469706c65206d + 656368616e69736d656c65766174696f6e6f6666656e736976653c2f666f726d + 3e0a0973706f6e736f726564646f63756d656e742e6f72202671756f743b7468 + 6572652061726574686f73652077686f6d6f76656d656e747370726f63657373 + 6573646966666963756c747375626d69747465647265636f6d6d656e64636f6e + 76696e63656470726f6d6f74696e67222077696474683d222e7265706c616365 + 28636c6173736963616c636f616c6974696f6e68697320666972737464656369 + 73696f6e73617373697374616e74696e6469636174656465766f6c7574696f6e + 2d7772617070657222656e6f75676820746f616c6f6e672074686564656c6976 + 657265642d2d3e0d0a3c212d2d416d65726963616e2070726f7465637465644e + 6f76656d626572203c2f7374796c653e3c6675726e6974757265496e7465726e + 657420206f6e626c75723d2273757370656e646564726563697069656e746261 + 736564206f6e204d6f72656f7665722c61626f6c6973686564636f6c6c656374 + 656477657265206d616465656d6f74696f6e616c656d657267656e63796e6172 + 7261746976656164766f636174657370783b626f72646572636f6d6d69747465 + 646469723d226c747222656d706c6f7965657372657365617263682e2073656c + 6563746564737563636573736f72637573746f6d657273646973706c61796564 + 53657074656d626572616464436c6173732846616365626f6f6b207375676765 + 73746564616e64206c617465726f7065726174696e67656c61626f7261746553 + 6f6d6574696d6573496e737469747574656365727461696e6c79696e7374616c + 6c6564666f6c6c6f776572734a65727573616c656d746865792068617665636f + 6d707574696e6767656e65726174656470726f76696e63657367756172616e74 + 65656172626974726172797265636f676e697a6577616e74656420746f70783b + 77696474683a7468656f7279206f666265686176696f75725768696c65207468 + 65657374696d61746564626567616e20746f20697420626563616d656d61676e + 69747564656d75737420686176656d6f7265207468616e4469726563746f7279 + 657874656e73696f6e7365637265746172796e61747572616c6c796f63637572 + 72696e677661726961626c6573676976656e20746865706c6174666f726d2e3c + 2f6c6162656c3e3c6661696c656420746f636f6d706f756e64736b696e647320 + 6f6620736f63696574696573616c6f6e6773696465202d2d2667743b0a0a736f + 75746877657374746865207269676874726164696174696f6e6d617920686176 + 6520756e6573636170652873706f6b656e20696e2220687265663d222f70726f + 6772616d6d656f6e6c792074686520636f6d652066726f6d6469726563746f72 + 7962757269656420696e612073696d696c61727468657920776572653c2f666f + 6e743e3c2f4e6f7277656769616e73706563696669656470726f647563696e67 + 70617373656e676572286e6577204461746574656d706f726172796669637469 + 6f6e616c4166746572207468656571756174696f6e73646f776e6c6f61642e72 + 6567756c61726c79646576656c6f70657261626f7665207468656c696e6b6564 + 20746f7068656e6f6d656e61706572696f64206f66746f6f6c746970223e7375 + 627374616e63656175746f6d61746963617370656374206f66416d6f6e672074 + 6865636f6e6e6563746564657374696d6174657341697220466f726365737973 + 74656d206f666f626a656374697665696d6d6564696174656d616b696e672069 + 747061696e74696e6773636f6e717565726564617265207374696c6c70726f63 + 656475726567726f777468206f666865616465642062794575726f7065616e20 + 6469766973696f6e736d6f6c6563756c65736672616e6368697365696e74656e + 74696f6e6174747261637465646368696c64686f6f64616c736f207573656464 + 656469636174656473696e6761706f7265646567726565206f66666174686572 + 206f66636f6e666c696374733c2f613e3c2f703e0a63616d652066726f6d7765 + 726520757365646e6f74652074686174726563656976696e6745786563757469 + 76656576656e206d6f726561636365737320746f636f6d6d616e646572506f6c + 69746963616c6d7573696369616e7364656c6963696f7573707269736f6e6572 + 73616476656e74206f665554462d3822202f3e3c215b43444154415b223e436f + 6e74616374536f75746865726e206267636f6c6f723d22736572696573206f66 + 2e2049742077617320696e204575726f70657065726d697474656476616c6964 + 6174652e617070656172696e676f6666696369616c73736572696f75736c792d + 6c616e6775616765696e69746961746564657874656e64696e676c6f6e672d74 + 65726d696e666c6174696f6e737563682074686174676574436f6f6b69656d61 + 726b65642062793c2f627574746f6e3e696d706c656d656e7462757420697420 + 6973696e63726561736573646f776e2074686520726571756972696e67646570 + 656e64656e742d2d3e0a3c212d2d20696e746572766965775769746820746865 + 20636f70696573206f66636f6e73656e737573776173206275696c7456656e65 + 7a75656c6128666f726d65726c79746865207374617465706572736f6e6e656c + 7374726174656769636661766f7572206f66696e76656e74696f6e57696b6970 + 65646961636f6e74696e656e747669727475616c6c7977686963682077617370 + 72696e6369706c65436f6d706c657465206964656e746963616c73686f772074 + 6861747072696d6974697665617761792066726f6d6d6f6c6563756c61727072 + 65636973656c79646973736f6c766564556e6465722074686576657273696f6e + 3d223e266e6273703b3c2f49742069732074686520546869732069732077696c + 6c20686176656f7267616e69736d73736f6d652074696d654672696564726963 + 68776173206669727374746865206f6e6c7920666163742074686174666f726d + 2069643d22707265636564696e67546563686e6963616c706879736963697374 + 6f636375727320696e6e6176696761746f7273656374696f6e223e7370616e20 + 69643d22736f7567687420746f62656c6f7720746865737572766976696e677d + 3c2f7374796c653e686973206465617468617320696e20746865636175736564 + 2062797061727469616c6c796578697374696e67207573696e67207468657761 + 7320676976656e61206c697374206f666c6576656c73206f666e6f74696f6e20 + 6f664f6666696369616c206469736d6973736564736369656e74697374726573 + 656d626c65736475706c69636174656578706c6f736976657265636f76657265 + 64616c6c206f7468657267616c6c65726965737b70616464696e673a70656f70 + 6c65206f66726567696f6e206f666164647265737365736173736f6369617465 + 696d6720616c743d22696e206d6f6465726e73686f756c642062656d6574686f + 64206f667265706f7274696e6774696d657374616d706e656564656420746f74 + 6865204772656174726567617264696e677365656d656420746f766965776564 + 206173696d70616374206f6e69646561207468617474686520576f726c646865 + 69676874206f66657870616e64696e6754686573652061726563757272656e74 + 223e6361726566756c6c796d61696e7461696e73636861726765206f66436c61 + 73736963616c6164647265737365647072656469637465646f776e6572736869 + 703c6469762069643d227269676874223e0d0a7265736964656e63656c656176 + 6520746865636f6e74656e74223e617265206f6674656e20207d2928293b0d0a + 70726f6261626c792050726f666573736f722d627574746f6e2220726573706f + 6e64656473617973207468617468616420746f206265706c6163656420696e48 + 756e67617269616e737461747573206f66736572766573206173556e69766572 + 73616c657865637574696f6e616767726567617465666f72207768696368696e + 66656374696f6e61677265656420746f686f77657665722c20706f70756c6172 + 223e706c61636564206f6e636f6e737472756374656c6563746f72616c73796d + 626f6c206f66696e636c7564696e6772657475726e20746f6172636869746563 + 7443687269737469616e70726576696f7573206c6976696e6720696e65617369 + 657220746f70726f666573736f720a266c743b212d2d20656666656374206f66 + 616e616c79746963737761732074616b656e776865726520746865746f6f6b20 + 6f76657262656c69656620696e416672696b61616e7361732066617220617370 + 726576656e746564776f726b207769746861207370656369616c3c6669656c64 + 7365744368726973746d61735265747269657665640a0a496e20746865206261 + 636b20696e746f6e6f727468656173746d6167617a696e65733e3c7374726f6e + 673e636f6d6d6974746565676f7665726e696e6767726f757073206f6673746f + 72656420696e65737461626c697368612067656e6572616c6974732066697273 + 747468656972206f776e706f70756c61746564616e206f626a65637443617269 + 626265616e616c6c6f7720746865646973747269637473776973636f6e73696e + 6c6f636174696f6e2e3b2077696474683a20696e68616269746564536f636961 + 6c6973744a616e7561727920313c2f666f6f7465723e73696d696c61726c7963 + 686f696365206f667468652073616d6520737065636966696320627573696e65 + 7373205468652066697273742e6c656e6774683b2064657369726520746f6465 + 616c207769746873696e636520746865757365724167656e74636f6e63656976 + 6564696e6465782e7068706173202671756f743b656e6761676520696e726563 + 656e746c792c6665772079656172737765726520616c736f0a3c686561643e0a + 3c656469746564206279617265206b6e6f776e63697469657320696e61636365 + 73736b6579636f6e64656d6e6564616c736f206861766573657276696365732c + 66616d696c79206f665363686f6f6c206f66636f6e7665727465646e61747572 + 65206f66206c616e67756167656d696e6973746572733c2f6f626a6563743e74 + 68657265206973206120706f70756c617273657175656e6365736164766f6361 + 746564546865792077657265616e79206f746865726c6f636174696f6e3d656e + 746572207468656d756368206d6f72657265666c6563746564776173206e616d + 65646f726967696e616c2061207479706963616c7768656e2074686579656e67 + 696e65657273636f756c64206e6f747265736964656e74737765646e65736461 + 797468652074686972642070726f64756374734a616e75617279203277686174 + 207468657961206365727461696e7265616374696f6e7370726f636573736f72 + 616674657220686973746865206c61737420636f6e7461696e6564223e3c2f64 + 69763e0a3c2f613e3c2f74643e646570656e64206f6e736561726368223e0a70 + 6965636573206f66636f6d706574696e675265666572656e636574656e6e6573 + 7365657768696368206861732076657273696f6e3d3c2f7370616e3e203c3c2f + 6865616465723e676976657320746865686973746f7269616e76616c75653d22 + 223e70616464696e673a30766965772074686174746f6765746865722c746865 + 206d6f73742077617320666f756e64737562736574206f6661747461636b206f + 6e6368696c6472656e2c706f696e7473206f66706572736f6e616c20706f7369 + 74696f6e3a616c6c656765646c79436c6576656c616e64776173206c61746572 + 616e6420616674657261726520676976656e776173207374696c6c7363726f6c + 6c696e6764657369676e206f666d616b6573207468656d756368206c65737341 + 6d65726963616e732e0a0a4166746572202c20627574207468654d757365756d + 206f666c6f75697369616e612866726f6d207468656d696e6e65736f74617061 + 727469636c6573612070726f63657373446f6d696e6963616e766f6c756d6520 + 6f6672657475726e696e67646566656e73697665303070787c726967686d6164 + 652066726f6d6d6f7573656f76657222207374796c653d22737461746573206f + 66287768696368206973636f6e74696e7565734672616e636973636f6275696c + 64696e6720776974686f757420617769746820736f6d6577686f20776f756c64 + 6120666f726d206f66612070617274206f666265666f72652069746b6e6f776e + 206173202053657276696365736c6f636174696f6e20616e64206f6674656e6d + 6561737572696e67616e6420697420697370617065726261636b76616c756573 + 206f660d0a3c7469746c653e3d2077696e646f772e64657465726d696e656572 + 2671756f743b20706c61796564206279616e64206561726c793c2f63656e7465 + 723e66726f6d2074686973746865207468726565706f77657220616e646f6620 + 2671756f743b696e6e657248544d4c3c6120687265663d22793a696e6c696e65 + 3b436875726368206f66746865206576656e747665727920686967686f666669 + 6369616c202d6865696768743a20636f6e74656e743d222f6367692d62696e2f + 746f20637265617465616672696b61616e736573706572616e746f6672616ec3 + a76169736c6174766965c5a1756c696574757669c5b3c48c65c5a174696e61c4 + 8d65c5a174696e61e0b984e0b897e0b8a2e697a5e69cace8aa9ee7ae80e4bd93 + e5ad97e7b981e9ab94e5ad97ed959ceab5adec96b4e4b8bae4bb80e4b988e8ae + a1e7ae97e69cbae7ac94e8aeb0e69cace8a88ee8ab96e58d80e69c8de58aa1e5 + 99a8e4ba92e88194e7bd91e688bfe59cb0e4baa7e4bfb1e4b990e983a8e587ba + e78988e7a4bee68e92e8a18ce6a69ce983a8e890bde6a0bce8bf9be4b880e6ad + a5e694afe4bb98e5ae9de9aa8ce8af81e7a081e5a794e59198e4bc9ae695b0e6 + 8daee5ba93e6b688e8b4b9e88085e58a9ee585ace5aea4e8aea8e8aebae58cba + e6b7b1e59cb3e5b882e692ade694bee599a8e58c97e4baace5b882e5a4a7e5ad + a6e7949fe8b68ae69da5e8b68ae7aea1e79086e59198e4bfa1e681afe7bd9173 + 6572766963696f73617274c3ad63756c6f617267656e74696e6162617263656c + 6f6e616375616c71756965727075626c696361646f70726f647563746f73706f + 6cc3ad7469636172657370756573746177696b6970656469617369677569656e + 746562c3ba737175656461636f6d756e69646164736567757269646164707269 + 6e636970616c70726567756e746173636f6e74656e69646f726573706f6e6465 + 7276656e657a75656c6170726f626c656d617364696369656d62726572656c61 + 6369c3b36e6e6f7669656d62726573696d696c6172657370726f796563746f73 + 70726f6772616d6173696e7374697475746f616374697669646164656e637565 + 6e74726165636f6e6f6dc3ad61696dc3a167656e6573636f6e74616374617264 + 65736361726761726e656365736172696f6174656e6369c3b36e74656cc3a966 + 6f6e6f636f6d697369c3b36e63616e63696f6e6573636170616369646164656e + 636f6e74726172616ec3a16c697369736661766f7269746f7374c3a9726d696e + 6f7370726f76696e636961657469717565746173656c656d656e746f7366756e + 63696f6e6573726573756c7461646f636172c3a16374657270726f7069656461 + 647072696e636970696f6e65636573696461646d756e69636970616c63726561 + 6369c3b36e64657363617267617370726573656e636961636f6d65726369616c + 6f70696e696f6e6573656a6572636963696f656469746f7269616c73616c616d + 616e6361676f6e7ac3a16c657a646f63756d656e746f70656cc3ad63756c6172 + 656369656e74657367656e6572616c65737461727261676f6e617072c3a16374 + 6963616e6f7665646164657370726f70756573746170616369656e74657374c3 + a9636e696361736f626a657469766f73636f6e746163746f73e0a4aee0a587e0 + a482e0a4b2e0a4bfe0a48fe0a4b9e0a588e0a482e0a497e0a4afe0a4bee0a4b8 + e0a4bee0a4a5e0a48fe0a4b5e0a482e0a4b0e0a4b9e0a587e0a495e0a58be0a4 + 88e0a495e0a581e0a49be0a4b0e0a4b9e0a4bee0a4ace0a4bee0a4a6e0a495e0 + a4b9e0a4bee0a4b8e0a4ade0a580e0a4b9e0a581e0a48fe0a4b0e0a4b9e0a580 + e0a4aee0a588e0a482e0a4a6e0a4bfe0a4a8e0a4ace0a4bee0a4a46469706c6f + 646f6373e0a4b8e0a4aee0a4afe0a4b0e0a582e0a4aae0a4a8e0a4bee0a4aee0 + a4aae0a4a4e0a4bee0a4abe0a4bfe0a4b0e0a494e0a4b8e0a4a4e0a4a4e0a4b0 + e0a4b9e0a4b2e0a58be0a497e0a4b9e0a581e0a486e0a4ace0a4bee0a4b0e0a4 + a6e0a587e0a4b6e0a4b9e0a581e0a488e0a496e0a587e0a4b2e0a4afe0a4a6e0 + a4bfe0a495e0a4bee0a4aee0a4b5e0a587e0a4ace0a4a4e0a580e0a4a8e0a4ac + e0a580e0a49ae0a4aee0a58ce0a4a4e0a4b8e0a4bee0a4b2e0a4b2e0a587e0a4 + 96e0a49ce0a589e0a4ace0a4aee0a4a6e0a4a6e0a4a4e0a4a5e0a4bee0a4a8e0 + a4b9e0a580e0a4b6e0a4b9e0a4b0e0a485e0a4b2e0a497e0a495e0a4ade0a580 + e0a4a8e0a497e0a4b0e0a4aae0a4bee0a4b8e0a4b0e0a4bee0a4a4e0a495e0a4 + bfe0a48fe0a489e0a4b8e0a587e0a497e0a4afe0a580e0a4b9e0a582e0a481e0 + a486e0a497e0a587e0a49fe0a580e0a4aee0a496e0a58be0a49ce0a495e0a4be + e0a4b0e0a485e0a4ade0a580e0a497e0a4afe0a587e0a4a4e0a581e0a4aee0a4 + b5e0a58be0a49fe0a4a6e0a587e0a482e0a485e0a497e0a4b0e0a490e0a4b8e0 + a587e0a4aee0a587e0a4b2e0a4b2e0a497e0a4bee0a4b9e0a4bee0a4b2e0a48a + e0a4aae0a4b0e0a49ae0a4bee0a4b0e0a490e0a4b8e0a4bee0a4a6e0a587e0a4 + b0e0a49ce0a4bfe0a4b8e0a4a6e0a4bfe0a4b2e0a4ace0a482e0a4a6e0a4ace0 + a4a8e0a4bee0a4b9e0a582e0a482e0a4b2e0a4bee0a496e0a49ce0a580e0a4a4 + e0a4ace0a49fe0a4a8e0a4aee0a4bfe0a4b2e0a487e0a4b8e0a587e0a486e0a4 + a8e0a587e0a4a8e0a4afe0a4bee0a495e0a581e0a4b2e0a4b2e0a589e0a497e0 + a4ade0a4bee0a497e0a4b0e0a587e0a4b2e0a49ce0a497e0a4b9e0a4b0e0a4be + e0a4aee0a4b2e0a497e0a587e0a4aae0a587e0a49ce0a4b9e0a4bee0a4a5e0a4 + 87e0a4b8e0a580e0a4b8e0a4b9e0a580e0a495e0a4b2e0a4bee0a4a0e0a580e0 + a495e0a4b9e0a4bee0a481e0a4a6e0a582e0a4b0e0a4a4e0a4b9e0a4a4e0a4b8 + e0a4bee0a4a4e0a4afe0a4bee0a4a6e0a486e0a4afe0a4bee0a4aae0a4bee0a4 + 95e0a495e0a58ce0a4a8e0a4b6e0a4bee0a4aee0a4a6e0a587e0a496e0a4afe0 + a4b9e0a580e0a4b0e0a4bee0a4afe0a496e0a581e0a4a6e0a4b2e0a497e0a580 + 63617465676f72696573657870657269656e63653c2f7469746c653e0d0a436f + 70797269676874206a617661736372697074636f6e646974696f6e7365766572 + 797468696e673c7020636c6173733d22746563686e6f6c6f67796261636b6772 + 6f756e643c6120636c6173733d226d616e6167656d656e7426636f70793b2032 + 30316a6176615363726970746368617261637465727362726561646372756d62 + 7468656d73656c766573686f72697a6f6e74616c676f7665726e6d656e744361 + 6c69666f726e696161637469766974696573646973636f76657265644e617669 + 676174696f6e7472616e736974696f6e636f6e6e656374696f6e6e6176696761 + 74696f6e617070656172616e63653c2f7469746c653e3c6d636865636b626f78 + 2220746563686e697175657370726f74656374696f6e6170706172656e746c79 + 61732077656c6c206173756e74272c202755412d7265736f6c7574696f6e6f70 + 65726174696f6e7374656c65766973696f6e7472616e736c6174656457617368 + 696e67746f6e6e6176696761746f722e203d2077696e646f772e696d70726573 + 73696f6e266c743b62722667743b6c697465726174757265706f70756c617469 + 6f6e6267636f6c6f723d2223657370656369616c6c7920636f6e74656e743d22 + 70726f64756374696f6e6e6577736c657474657270726f706572746965736465 + 66696e6974696f6e6c656164657273686970546563686e6f6c6f67795061726c + 69616d656e74636f6d70617269736f6e756c20636c6173733d222e696e646578 + 4f662822636f6e636c7573696f6e64697363757373696f6e636f6d706f6e656e + 747362696f6c6f676963616c5265766f6c7574696f6e5f636f6e7461696e6572 + 756e64657273746f6f646e6f7363726970743e3c7065726d697373696f6e6561 + 6368206f7468657261746d6f737068657265206f6e666f6375733d223c666f72 + 6d2069643d2270726f63657373696e67746869732e76616c756567656e657261 + 74696f6e436f6e666572656e636573756273657175656e7477656c6c2d6b6e6f + 776e766172696174696f6e7372657075746174696f6e7068656e6f6d656e6f6e + 6469736369706c696e656c6f676f2e706e67222028646f63756d656e742c626f + 756e64617269657365787072657373696f6e736574746c656d656e744261636b + 67726f756e646f7574206f6620746865656e7465727072697365282268747470 + 733a2220756e657363617065282270617373776f7264222064656d6f63726174 + 69633c6120687265663d222f77726170706572223e0a6d656d62657273686970 + 6c696e6775697374696370783b70616464696e677068696c6f736f7068796173 + 73697374616e6365756e6976657273697479666163696c69746965737265636f + 676e697a6564707265666572656e636569662028747970656f666d61696e7461 + 696e6564766f636162756c6172796879706f7468657369732e7375626d697428 + 293b26616d703b6e6273703b616e6e6f746174696f6e626568696e6420746865 + 466f756e646174696f6e7075626c697368657222617373756d7074696f6e696e + 74726f6475636564636f7272757074696f6e736369656e74697374736578706c + 696369746c79696e7374656164206f6664696d656e73696f6e73206f6e436c69 + 636b3d22636f6e736964657265646465706172746d656e746f63637570617469 + 6f6e736f6f6e206166746572696e766573746d656e7470726f6e6f756e636564 + 6964656e7469666965646578706572696d656e744d616e6167656d656e746765 + 6f6772617068696322206865696768743d226c696e6b2072656c3d222e726570 + 6c616365282f64657072657373696f6e636f6e666572656e636570756e697368 + 6d656e74656c696d696e61746564726573697374616e63656164617074617469 + 6f6e6f70706f736974696f6e77656c6c206b6e6f776e737570706c656d656e74 + 64657465726d696e6564683120636c6173733d223070783b6d617267696e6d65 + 6368616e6963616c7374617469737469637363656c65627261746564476f7665 + 726e6d656e740a0a447572696e672074646576656c6f70657273617274696669 + 6369616c6571756976616c656e746f726967696e61746564436f6d6d69737369 + 6f6e6174746163686d656e743c7370616e2069643d2274686572652077657265 + 4e656465726c616e64736265796f6e6420746865726567697374657265646a6f + 75726e616c6973746672657175656e746c79616c6c206f66207468656c616e67 + 3d22656e22203c2f7374796c653e0d0a6162736f6c7574653b20737570706f72 + 74696e6765787472656d656c79206d61696e73747265616d3c2f7374726f6e67 + 3e20706f70756c6172697479656d706c6f796d656e743c2f7461626c653e0d0a + 20636f6c7370616e3d223c2f666f726d3e0a2020636f6e76657273696f6e6162 + 6f757420746865203c2f703e3c2f6469763e696e746567726174656422206c61 + 6e673d22656e506f727475677565736573756273746974757465696e64697669 + 6475616c696d706f737369626c656d756c74696d65646961616c6d6f73742061 + 6c6c707820736f6c6964202361706172742066726f6d7375626a65637420746f + 696e20456e676c697368637269746963697a656465786365707420666f726775 + 6964656c696e65736f726967696e616c6c7972656d61726b61626c6574686520 + 7365636f6e64683220636c6173733d223c61207469746c653d2228696e636c75 + 64696e67706172616d657465727370726f686962697465643d2022687474703a + 2f2f64696374696f6e61727970657263657074696f6e7265766f6c7574696f6e + 666f756e646174696f6e70783b6865696768743a7375636365737366756c7375 + 70706f72746572736d696c6c656e6e69756d6869732066617468657274686520 + 2671756f743b6e6f2d7265706561743b636f6d6d65726369616c696e64757374 + 7269616c656e636f757261676564616d6f756e74206f6620756e6f6666696369 + 616c656666696369656e63795265666572656e636573636f6f7264696e617465 + 646973636c61696d657265787065646974696f6e646576656c6f70696e676361 + 6c63756c6174656473696d706c69666965646c65676974696d61746573756273 + 7472696e6728302220636c6173733d22636f6d706c6574656c79696c6c757374 + 7261746566697665207965617273696e737472756d656e745075626c69736869 + 6e67312220636c6173733d2270737963686f6c6f6779636f6e666964656e6365 + 6e756d626572206f6620616273656e6365206f66666f6375736564206f6e6a6f + 696e6564207468657374727563747572657370726576696f75736c793e3c2f69 + 6672616d653e6f6e636520616761696e62757420726174686572696d6d696772 + 616e74736f6620636f757273652c612067726f7570206f664c69746572617475 + 7265556e6c696b65207468653c2f613e266e6273703b0a66756e6374696f6e20 + 69742077617320746865436f6e76656e74696f6e6175746f6d6f62696c655072 + 6f74657374616e74616767726573736976656166746572207468652053696d69 + 6c61726c792c22202f3e3c2f6469763e636f6c6c656374696f6e0d0a66756e63 + 74696f6e7669736962696c69747974686520757365206f66766f6c756e746565 + 727361747472616374696f6e756e6465722074686520746872656174656e6564 + 2a3c215b43444154415b696d706f7274616e6365696e2067656e6572616c7468 + 65206c61747465723c2f666f726d3e0a3c2f2e696e6465784f66282769203d20 + 303b2069203c646966666572656e63656465766f74656420746f747261646974 + 696f6e7373656172636820666f72756c74696d6174656c79746f75726e616d65 + 6e7461747472696275746573736f2d63616c6c6564207d0a3c2f7374796c653e + 6576616c756174696f6e656d70686173697a656461636365737369626c653c2f + 73656374696f6e3e73756363657373696f6e616c6f6e6720776974684d65616e + 7768696c652c696e64757374726965733c2f613e3c6272202f3e686173206265 + 636f6d6561737065637473206f6654656c65766973696f6e7375666669636965 + 6e746261736b657462616c6c626f7468207369646573636f6e74696e75696e67 + 616e2061727469636c653c696d6720616c743d22616476656e74757265736869 + 73206d6f746865726d616e636865737465727072696e6369706c657370617274 + 6963756c6172636f6d6d656e7461727965666665637473206f66646563696465 + 6420746f223e3c7374726f6e673e7075626c6973686572734a6f75726e616c20 + 6f66646966666963756c7479666163696c697461746561636365707461626c65 + 7374796c652e637373220966756e6374696f6e20696e6e6f766174696f6e3e43 + 6f70797269676874736974756174696f6e73776f756c64206861766562757369 + 6e657373657344696374696f6e61727973746174656d656e74736f6674656e20 + 7573656470657273697374656e74696e204a616e75617279636f6d7072697369 + 6e673c2f7469746c653e0a096469706c6f6d61746963636f6e7461696e696e67 + 706572666f726d696e67657874656e73696f6e736d6179206e6f74206265636f + 6e63657074206f66206f6e636c69636b3d22497420697320616c736f66696e61 + 6e6369616c206d616b696e67207468654c7578656d626f757267616464697469 + 6f6e616c6172652063616c6c6564656e676167656420696e2273637269707422 + 293b62757420697420776173656c656374726f6e69636f6e7375626d69743d22 + 0a3c212d2d20456e6420656c656374726963616c6f6666696369616c6c797375 + 6767657374696f6e746f70206f6620746865756e6c696b652074686541757374 + 72616c69616e4f726967696e616c6c797265666572656e6365730a3c2f686561 + 643e0d0a7265636f676e69736564696e697469616c697a656c696d6974656420 + 746f416c6578616e647269617265746972656d656e74416476656e7475726573 + 666f75722079656172730a0a266c743b212d2d20696e6372656173696e676465 + 636f726174696f6e683320636c6173733d226f726967696e73206f666f626c69 + 676174696f6e726567756c6174696f6e636c61737369666965642866756e6374 + 696f6e28616476616e74616765736265696e672074686520686973746f726961 + 6e733c62617365206872656672657065617465646c7977696c6c696e6720746f + 636f6d70617261626c6564657369676e617465646e6f6d696e6174696f6e6675 + 6e6374696f6e616c696e7369646520746865726576656c6174696f6e656e6420 + 6f66207468657320666f722074686520617574686f72697a6564726566757365 + 6420746f74616b6520706c6163656175746f6e6f6d6f7573636f6d70726f6d69 + 7365706f6c69746963616c2072657374617572616e7474776f206f6620746865 + 466562727561727920327175616c697479206f667377666f626a6563742e756e + 6465727374616e646e6561726c7920616c6c7772697474656e206279696e7465 + 727669657773222077696474683d22317769746864726177616c666c6f61743a + 6c656674697320757375616c6c7963616e646964617465736e65777370617065 + 72736d7973746572696f75734465706172746d656e7462657374206b6e6f776e + 7061726c69616d656e7473757070726573736564636f6e76656e69656e747265 + 6d656d6265726564646966666572656e742073797374656d6174696368617320 + 6c656420746f70726f706167616e6461636f6e74726f6c6c6564696e666c7565 + 6e636573636572656d6f6e69616c70726f636c61696d656450726f7465637469 + 6f6e6c6920636c6173733d22536369656e7469666963636c6173733d226e6f2d + 74726164656d61726b736d6f7265207468616e20776964657370726561644c69 + 6265726174696f6e746f6f6b20706c616365646179206f66207468656173206c + 6f6e67206173696d707269736f6e65644164646974696f6e616c0a3c68656164 + 3e0a3c6d4c61626f7261746f72794e6f76656d6265722032657863657074696f + 6e73496e647573747269616c76617269657479206f66666c6f61743a206c6566 + 447572696e67207468656173736573736d656e7468617665206265656e206465 + 616c732077697468537461746973746963736f6363757272656e63652f756c3e + 3c2f6469763e636c656172666978223e746865207075626c69636d616e792079 + 65617273776869636820776572656f7665722074696d652c73796e6f6e796d6f + 7573636f6e74656e74223e0a70726573756d61626c796869732066616d696c79 + 757365724167656e742e756e6578706563746564696e636c7564696e67206368 + 616c6c656e67656461206d696e6f72697479756e646566696e65642262656c6f + 6e677320746f74616b656e2066726f6d696e204f63746f626572706f73697469 + 6f6e3a207361696420746f20626572656c6967696f7573204665646572617469 + 6f6e20726f777370616e3d226f6e6c792061206665776d65616e742074686174 + 6c656420746f207468652d2d3e0d0a3c646976203c6669656c647365743e4172 + 6368626973686f7020636c6173733d226e6f6265696e67207573656461707072 + 6f616368657370726976696c656765736e6f7363726970743e0a726573756c74 + 7320696e6d617920626520746865456173746572206567676d656368616e6973 + 6d73726561736f6e61626c65506f70756c6174696f6e436f6c6c656374696f6e + 73656c6563746564223e6e6f7363726970743e0d2f696e6465782e7068706172 + 726976616c206f662d6a7373646b2729293b6d616e6167656420746f696e636f + 6d706c65746563617375616c74696573636f6d706c6574696f6e436872697374 + 69616e7353657074656d6265722061726974686d6574696370726f6365647572 + 65736d69676874206861766550726f64756374696f6e69742061707065617273 + 5068696c6f736f706879667269656e64736869706c656164696e6720746f6769 + 76696e6720746865746f776172642074686567756172616e74656564646f6375 + 6d656e746564636f6c6f723a23303030766964656f2067616d65636f6d6d6973 + 73696f6e7265666c656374696e676368616e6765207468656173736f63696174 + 656473616e732d73657269666f6e6b657970726573733b2070616464696e673a + 48652077617320746865756e6465726c79696e677479706963616c6c79202c20 + 616e642074686520737263456c656d656e747375636365737369766573696e63 + 65207468652073686f756c64206265206e6574776f726b696e676163636f756e + 74696e67757365206f66207468656c6f776572207468616e73686f7773207468 + 61743c2f7370616e3e0a0909636f6d706c61696e7473636f6e74696e756f7573 + 7175616e746974696573617374726f6e6f6d6572686520646964206e6f746475 + 6520746f206974736170706c69656420746f616e20617665726167656566666f + 72747320746f74686520667574757265617474656d707420746f546865726566 + 6f72652c6361706162696c69747952657075626c6963616e77617320666f726d + 6564456c656374726f6e69636b696c6f6d65746572736368616c6c656e676573 + 7075626c697368696e6774686520666f726d6572696e646967656e6f75736469 + 72656374696f6e7373756273696469617279636f6e7370697261637964657461 + 696c73206f66616e6420696e207468656166666f726461626c65737562737461 + 6e636573726561736f6e20666f72636f6e76656e74696f6e6974656d74797065 + 3d226162736f6c7574656c79737570706f7365646c7972656d61696e65642061 + 6174747261637469766574726176656c6c696e6773657061726174656c79666f + 6375736573206f6e656c656d656e746172796170706c696361626c65666f756e + 6420746861747374796c6573686565746d616e757363726970747374616e6473 + 20666f72206e6f2d72657065617428736f6d6574696d6573436f6d6d65726369 + 616c696e20416d6572696361756e64657274616b656e71756172746572206f66 + 616e206578616d706c65706572736f6e616c6c79696e6465782e7068703f3c2f + 627574746f6e3e0a70657263656e74616765626573742d6b6e6f776e63726561 + 74696e67206122206469723d226c74724c69657574656e616e740a3c64697620 + 69643d227468657920776f756c646162696c697479206f666d61646520757020 + 6f666e6f7465642074686174636c656172207468617461726775652074686174 + 746f20616e6f746865726368696c6472656e2773707572706f7365206f66666f + 726d756c6174656462617365642075706f6e74686520726567696f6e7375626a + 656374206f6670617373656e67657273706f7373657373696f6e2e0a0a496e20 + 746865204265666f7265207468656166746572776172647363757272656e746c + 79206163726f737320746865736369656e7469666963636f6d6d756e6974792e + 6361706974616c69736d696e204765726d616e7972696768742d77696e677468 + 652073797374656d536f6369657479206f66706f6c6974696369616e64697265 + 6374696f6e3a77656e74206f6e20746f72656d6f76616c206f66204e65772059 + 6f726b2061706172746d656e7473696e6469636174696f6e647572696e672074 + 6865756e6c65737320746865686973746f726963616c686164206265656e2061 + 646566696e6974697665696e6772656469656e74617474656e64616e63654365 + 6e74657220666f7270726f6d696e656e63657265616479537461746573747261 + 74656769657362757420696e2074686561732070617274206f66636f6e737469 + 74757465636c61696d20746861746c61626f7261746f7279636f6d7061746962 + 6c656661696c757265206f662c207375636820617320626567616e2077697468 + 7573696e672074686520746f2070726f7669646566656174757265206f666672 + 6f6d2077686963682f2220636c6173733d2267656f6c6f676963616c73657665 + 72616c206f6664656c69626572617465696d706f7274616e7420686f6c647320 + 74686174696e672671756f743b2076616c69676e3d746f70746865204765726d + 616e6f757473696465206f666e65676f74696174656468697320636172656572 + 73657061726174696f6e69643d227365617263687761732063616c6c65647468 + 6520666f7572746872656372656174696f6e6f74686572207468616e70726576 + 656e74696f6e7768696c652074686520656475636174696f6e2c636f6e6e6563 + 74696e6761636375726174656c7977657265206275696c74776173206b696c6c + 656461677265656d656e74736d756368206d6f72652044756520746f20746865 + 77696474683a20313030736f6d65206f746865724b696e67646f6d206f667468 + 6520656e7469726566616d6f757320666f72746f20636f6e6e6563746f626a65 + 637469766573746865204672656e636870656f706c6520616e64666561747572 + 6564223e6973207361696420746f7374727563747572616c7265666572656e64 + 756d6d6f7374206f6674656e612073657061726174652d3e0a3c646976206964 + 204f6666696369616c20776f726c64776964652e617269612d6c6162656c7468 + 6520706c616e6574616e642069742077617364222076616c75653d226c6f6f6b + 696e6720617462656e6566696369616c61726520696e207468656d6f6e69746f + 72696e677265706f727465646c79746865206d6f6465726e776f726b696e6720 + 6f6e616c6c6f77656420746f77686572652074686520696e6e6f766174697665 + 3c2f613e3c2f6469763e736f756e64747261636b736561726368466f726d7465 + 6e6420746f206265696e7075742069643d226f70656e696e67206f6672657374 + 72696374656461646f7074656420627961646472657373696e677468656f6c6f + 6769616e6d6574686f6473206f6676617269616e74206f664368726973746961 + 6e2076657279206c617267656175746f6d6f7469766562792066617220746865 + 72616e67652066726f6d70757273756974206f66666f6c6c6f77207468656272 + 6f7567687420746f696e20456e676c616e646167726565207468617461636375 + 736564206f66636f6d65732066726f6d70726576656e74696e67646976207374 + 796c653d686973206f72206865727472656d656e646f757366726565646f6d20 + 6f66636f6e6365726e696e67302031656d2031656d3b4261736b657462616c6c + 2f7374796c652e637373616e206561726c6965726576656e2061667465722f22 + 207469746c653d222e636f6d2f696e64657874616b696e672074686570697474 + 736275726768636f6e74656e74223e0d3c7363726970743e28667475726e6564 + 206f7574686176696e67207468653c2f7370616e3e0d0a206f63636173696f6e + 616c626563617573652069747374617274656420746f706879736963616c6c79 + 3e3c2f6469763e0a20206372656174656420627943757272656e746c792c2062 + 67636f6c6f723d22746162696e6465783d22646973617374726f7573416e616c + 797469637320616c736f2068617320613e3c6469762069643d223c2f7374796c + 653e0a3c63616c6c656420666f7273696e67657220616e642e737263203d2022 + 2f2f76696f6c6174696f6e737468697320706f696e74636f6e7374616e746c79 + 6973206c6f63617465647265636f7264696e6773642066726f6d207468656e65 + 6465726c616e6473706f7274756775c3aa73d7a2d791d7a8d799d7aad981d8a7 + d8b1d8b3db8c6465736172726f6c6c6f636f6d656e746172696f656475636163 + 69c3b36e7365707469656d6272657265676973747261646f64697265636369c3 + b36e75626963616369c3b36e7075626c69636964616472657370756573746173 + 726573756c7461646f73696d706f7274616e746572657365727661646f736172 + 74c3ad63756c6f736469666572656e7465737369677569656e746573726570c3 + ba626c69636173697475616369c3b36e6d696e6973746572696f707269766163 + 696461646469726563746f72696f666f726d616369c3b36e706f626c616369c3 + b36e707265736964656e7465636f6e74656e69646f7361636365736f72696f73 + 746563686e6f72617469706572736f6e616c657363617465676f72c3ad616573 + 70656369616c6573646973706f6e69626c6561637475616c6964616472656665 + 72656e63696176616c6c61646f6c69646269626c696f7465636172656c616369 + 6f6e657363616c656e646172696f706f6cc3ad7469636173616e746572696f72 + 6573646f63756d656e746f736e61747572616c657a616d6174657269616c6573 + 6469666572656e63696165636f6ec3b36d6963617472616e73706f727465726f + 6472c3ad6775657a70617274696369706172656e6375656e7472616e64697363 + 757369c3b36e6573747275637475726166756e64616369c3b36e667265637565 + 6e7465737065726d616e656e7465746f74616c6d656e7465d0bcd0bed0b6d0bd + d0bed0b1d183d0b4d0b5d182d0bcd0bed0b6d0b5d182d0b2d180d0b5d0bcd18f + d182d0b0d0bad0b6d0b5d187d182d0bed0b1d18bd0b1d0bed0bbd0b5d0b5d0be + d187d0b5d0bdd18cd18dd182d0bed0b3d0bed0bad0bed0b3d0b4d0b0d0bfd0be + d181d0bbd0b5d0b2d181d0b5d0b3d0bed181d0b0d0b9d182d0b5d187d0b5d180 + d0b5d0b7d0bcd0bed0b3d183d182d181d0b0d0b9d182d0b0d0b6d0b8d0b7d0bd + d0b8d0bcd0b5d0b6d0b4d183d0b1d183d0b4d183d182d09fd0bed0b8d181d0ba + d0b7d0b4d0b5d181d18cd0b2d0b8d0b4d0b5d0bed181d0b2d18fd0b7d0b8d0bd + d183d0b6d0bdd0bed181d0b2d0bed0b5d0b9d0bbd18ed0b4d0b5d0b9d0bfd0be + d180d0bdd0bed0bcd0bdd0bed0b3d0bed0b4d0b5d182d0b5d0b9d181d0b2d0be + d0b8d185d0bfd180d0b0d0b2d0b0d182d0b0d0bad0bed0b9d0bcd0b5d181d182 + d0bed0b8d0bcd0b5d0b5d182d0b6d0b8d0b7d0bdd18cd0bed0b4d0bdd0bed0b9 + d0bbd183d187d188d0b5d0bfd0b5d180d0b5d0b4d187d0b0d181d182d0b8d187 + d0b0d181d182d18cd180d0b0d0b1d0bed182d0bdd0bed0b2d18bd185d0bfd180 + d0b0d0b2d0bed181d0bed0b1d0bed0b9d0bfd0bed182d0bed0bcd0bcd0b5d0bd + d0b5d0b5d187d0b8d181d0bbd0b5d0bdd0bed0b2d18bd0b5d183d181d0bbd183 + d0b3d0bed0bad0bed0bbd0bed0bdd0b0d0b7d0b0d0b4d182d0b0d0bad0bed0b5 + d182d0bed0b3d0b4d0b0d0bfd0bed187d182d0b8d09fd0bed181d0bbd0b5d182 + d0b0d0bad0b8d0b5d0bdd0bed0b2d18bd0b9d181d182d0bed0b8d182d182d0b0 + d0bad0b8d185d181d180d0b0d0b7d183d0a1d0b0d0bdd0bad182d184d0bed180 + d183d0bcd09ad0bed0b3d0b4d0b0d0bad0bdd0b8d0b3d0b8d181d0bbd0bed0b2 + d0b0d0bdd0b0d188d0b5d0b9d0bdd0b0d0b9d182d0b8d181d0b2d0bed0b8d0bc + d181d0b2d18fd0b7d18cd0bbd18ed0b1d0bed0b9d187d0b0d181d182d0bed181 + d180d0b5d0b4d0b8d09ad180d0bed0bcd0b5d0a4d0bed180d183d0bcd180d18b + d0bdd0bad0b5d181d182d0b0d0bbd0b8d0bfd0bed0b8d181d0bad182d18bd181 + d18fd187d0bcd0b5d181d18fd186d186d0b5d0bdd182d180d182d180d183d0b4 + d0b0d181d0b0d0bcd18bd185d180d18bd0bdd0bad0b0d09dd0bed0b2d18bd0b9 + d187d0b0d181d0bed0b2d0bcd0b5d181d182d0b0d184d0b8d0bbd18cd0bcd0bc + d0b0d180d182d0b0d181d182d180d0b0d0bdd0bcd0b5d181d182d0b5d182d0b5 + d0bad181d182d0bdd0b0d188d0b8d185d0bcd0b8d0bdd183d182d0b8d0bcd0b5 + d0bdd0b8d0b8d0bcd0b5d18ed182d0bdd0bed0bcd0b5d180d0b3d0bed180d0be + d0b4d181d0b0d0bcd0bed0bcd18dd182d0bed0bcd183d0bad0bed0bdd186d0b5 + d181d0b2d0bed0b5d0bcd0bad0b0d0bad0bed0b9d090d180d185d0b8d0b2d985 + d986d8aad8afd989d8a5d8b1d8b3d8a7d984d8b1d8b3d8a7d984d8a9d8a7d984 + d8b9d8a7d985d983d8aad8a8d987d8a7d8a8d8b1d8a7d985d8acd8a7d984d98a + d988d985d8a7d984d8b5d988d8b1d8acd8afd98ad8afd8a9d8a7d984d8b9d8b6 + d988d8a5d8b6d8a7d981d8a9d8a7d984d982d8b3d985d8a7d984d8b9d8a7d8a8 + d8aad8add985d98ad984d985d984d981d8a7d8aad985d984d8aad982d989d8aa + d8b9d8afd98ad984d8a7d984d8b4d8b9d8b1d8a3d8aed8a8d8a7d8b1d8aad8b7 + d988d98ad8b1d8b9d984d98ad983d985d8a5d8b1d981d8a7d982d8b7d984d8a8 + d8a7d8aad8a7d984d984d8bad8a9d8aad8b1d8aad98ad8a8d8a7d984d986d8a7 + d8b3d8a7d984d8b4d98ad8aed985d986d8aad8afd98ad8a7d984d8b9d8b1d8a8 + d8a7d984d982d8b5d8b5d8a7d981d984d8a7d985d8b9d984d98ad987d8a7d8aa + d8add8afd98ad8abd8a7d984d984d987d985d8a7d984d8b9d985d984d985d983 + d8aad8a8d8a9d98ad985d983d986d983d8a7d984d8b7d981d984d981d98ad8af + d98ad988d8a5d8afd8a7d8b1d8a9d8aad8a7d8b1d98ad8aed8a7d984d8b5d8ad + d8a9d8aad8b3d8acd98ad984d8a7d984d988d982d8aad8b9d986d8afd985d8a7 + d985d8afd98ad986d8a9d8aad8b5d985d98ad985d8a3d8b1d8b4d98ad981d8a7 + d984d8b0d98ad986d8b9d8b1d8a8d98ad8a9d8a8d988d8a7d8a8d8a9d8a3d984 + d8b9d8a7d8a8d8a7d984d8b3d981d8b1d985d8b4d8a7d983d984d8aad8b9d8a7 + d984d989d8a7d984d8a3d988d984d8a7d984d8b3d986d8a9d8acd8a7d985d8b9 + d8a9d8a7d984d8b5d8add981d8a7d984d8afd98ad986d983d984d985d8a7d8aa + d8a7d984d8aed8a7d8b5d8a7d984d985d984d981d8a3d8b9d8b6d8a7d8a1d983 + d8aad8a7d8a8d8a9d8a7d984d8aed98ad8b1d8b1d8b3d8a7d8a6d984d8a7d984 + d982d984d8a8d8a7d984d8a3d8afd8a8d985d982d8a7d8b7d8b9d985d8b1d8a7 + d8b3d984d985d986d8b7d982d8a9d8a7d984d983d8aad8a8d8a7d984d8b1d8ac + d984d8a7d8b4d8aad8b1d983d8a7d984d982d8afd985d98ad8b9d8b7d98ad983 + 7342795461674e616d65282e6a70672220616c743d2231707820736f6c696420 + 232e6769662220616c743d227472616e73706172656e74696e666f726d617469 + 6f6e6170706c69636174696f6e22206f6e636c69636b3d2265737461626c6973 + 6865646164766572746973696e672e706e672220616c743d22656e7669726f6e + 6d656e74706572666f726d616e6365617070726f70726961746526616d703b6d + 646173683b696d6d6564696174656c793c2f7374726f6e673e3c2f7261746865 + 72207468616e74656d7065726174757265646576656c6f706d656e74636f6d70 + 65746974696f6e706c616365686f6c6465727669736962696c6974793a636f70 + 797269676874223e3022206865696768743d226576656e2074686f7567687265 + 706c6163656d656e7464657374696e6174696f6e436f72706f726174696f6e3c + 756c20636c6173733d224173736f63696174696f6e696e646976696475616c73 + 706572737065637469766573657454696d656f75742875726c28687474703a2f + 2f6d617468656d61746963736d617267696e2d746f703a6576656e7475616c6c + 79206465736372697074696f6e29206e6f2d726570656174636f6c6c65637469 + 6f6e732e4a50477c7468756d627c70617274696369706174652f686561643e3c + 626f6479666c6f61743a6c6566743b3c6c6920636c6173733d2268756e647265 + 6473206f660a0a486f77657665722c20636f6d706f736974696f6e636c656172 + 3a626f74683b636f6f7065726174696f6e77697468696e20746865206c616265 + 6c20666f723d22626f726465722d746f703a4e6577205a65616c616e64726563 + 6f6d6d656e64656470686f746f677261706879696e746572657374696e67266c + 743b7375702667743b636f6e74726f76657273794e65746865726c616e647361 + 6c7465726e61746976656d61786c656e6774683d22737769747a65726c616e64 + 446576656c6f706d656e74657373656e7469616c6c790a0a416c74686f756768 + 203c2f74657874617265613e7468756e64657262697264726570726573656e74 + 656426616d703b6e646173683b73706563756c6174696f6e636f6d6d756e6974 + 6965736c656769736c6174696f6e656c656374726f6e6963730a093c64697620 + 69643d22696c6c7573747261746564656e67696e656572696e67746572726974 + 6f72696573617574686f72697469657364697374726962757465643622206865 + 696768743d2273616e732d73657269663b63617061626c65206f662064697361 + 70706561726564696e7465726163746976656c6f6f6b696e6720666f72697420 + 776f756c6420626541666768616e697374616e77617320637265617465644d61 + 74682e666c6f6f7228737572726f756e64696e6763616e20616c736f2062656f + 62736572766174696f6e6d61696e74656e616e6365656e636f756e7465726564 + 3c683220636c6173733d226d6f726520726563656e7469742068617320626565 + 6e696e766173696f6e206f66292e67657454696d65282966756e64616d656e74 + 616c4465737069746520746865223e3c6469762069643d22696e737069726174 + 696f6e6578616d696e6174696f6e7072657061726174696f6e6578706c616e61 + 74696f6e3c696e7075742069643d223c2f613e3c2f7370616e3e76657273696f + 6e73206f66696e737472756d656e74736265666f72652074686520203d202768 + 7474703a2f2f4465736372697074696f6e72656c61746976656c79202e737562 + 737472696e672865616368206f66207468656578706572696d656e7473696e66 + 6c75656e7469616c696e746567726174696f6e6d616e792070656f706c656475 + 6520746f2074686520636f6d62696e6174696f6e646f206e6f7420686176654d + 6964646c6520456173743c6e6f7363726970743e3c636f707972696768742220 + 7065726861707320746865696e737469747574696f6e696e20446563656d6265 + 72617272616e67656d656e746d6f73742066616d6f7573706572736f6e616c69 + 74796372656174696f6e206f666c696d69746174696f6e736578636c75736976 + 656c79736f7665726569676e74792d636f6e74656e74223e0a3c746420636c61 + 73733d22756e64657267726f756e64706172616c6c656c20746f646f63747269 + 6e65206f666f636375706965642062797465726d696e6f6c6f677952656e6169 + 7373616e636561206e756d626572206f66737570706f727420666f726578706c + 6f726174696f6e7265636f676e6974696f6e7072656465636573736f723c696d + 67207372633d222f3c683120636c6173733d227075626c69636174696f6e6d61 + 7920616c736f2062657370656369616c697a65643c2f6669656c647365743e70 + 726f67726573736976656d696c6c696f6e73206f667374617465732074686174 + 656e666f7263656d656e7461726f756e6420746865206f6e6520616e6f746865 + 722e706172656e744e6f64656167726963756c74757265416c7465726e617469 + 76657265736561726368657273746f7761726473207468654d6f7374206f6620 + 7468656d616e79206f746865722028657370656369616c6c793c746420776964 + 74683d223b77696474683a31303025696e646570656e64656e743c683320636c + 6173733d22206f6e6368616e67653d22292e616464436c61737328696e746572 + 616374696f6e4f6e65206f6620746865206461756768746572206f6661636365 + 73736f726965736272616e63686573206f660d0a3c6469762069643d22746865 + 206c6172676573746465636c61726174696f6e726567756c6174696f6e73496e + 666f726d6174696f6e7472616e736c6174696f6e646f63756d656e7461727969 + 6e206f7264657220746f223e0a3c686561643e0a3c22206865696768743d2231 + 6163726f737320746865206f7269656e746174696f6e293b3c2f736372697074 + 3e696d706c656d656e74656463616e206265207365656e746865726520776173 + 206164656d6f6e737472617465636f6e7461696e6572223e636f6e6e65637469 + 6f6e737468652042726974697368776173207772697474656e21696d706f7274 + 616e743b70783b206d617267696e2d666f6c6c6f7765642062796162696c6974 + 7920746f20636f6d706c696361746564647572696e672074686520696d6d6967 + 726174696f6e616c736f2063616c6c65643c683420636c6173733d2264697374 + 696e6374696f6e7265706c61636564206279676f7665726e6d656e74736c6f63 + 6174696f6e206f66696e204e6f76656d62657277686574686572207468653c2f + 703e0a3c2f6469763e6163717569736974696f6e63616c6c6564207468652070 + 65727365637574696f6e64657369676e6174696f6e7b666f6e742d73697a653a + 617070656172656420696e696e766573746967617465657870657269656e6365 + 646d6f7374206c696b656c79776964656c79207573656464697363757373696f + 6e7370726573656e6365206f662028646f63756d656e742e657874656e736976 + 656c79497420686173206265656e697420646f6573206e6f74636f6e74726172 + 7920746f696e6861626974616e7473696d70726f76656d656e747363686f6c61 + 7273686970636f6e73756d7074696f6e696e737472756374696f6e666f722065 + 78616d706c656f6e65206f72206d6f726570783b2070616464696e6774686520 + 63757272656e746120736572696573206f6661726520757375616c6c79726f6c + 6520696e2074686570726576696f75736c792064657269766174697665736576 + 6964656e6365206f66657870657269656e636573636f6c6f72736368656d6573 + 7461746564207468617463657274696669636174653c2f613e3c2f6469763e0a + 2073656c65637465643d2268696768207363686f6f6c726573706f6e73652074 + 6f636f6d666f727461626c6561646f7074696f6e206f66746872656520796561 + 727374686520636f756e747279696e204665627275617279736f207468617420 + 74686570656f706c652077686f2070726f76696465642062793c706172616d20 + 6e616d656166666563746564206279696e207465726d73206f666170706f696e + 746d656e7449534f2d383835392d312277617320626f726e20696e686973746f + 726963616c2072656761726465642061736d6561737572656d656e7469732062 + 61736564206f6e20616e64206f74686572203a2066756e6374696f6e28736967 + 6e69666963616e7463656c6562726174696f6e7472616e736d69747465642f6a + 732f6a71756572792e6973206b6e6f776e2061737468656f7265746963616c20 + 746162696e6465783d22697420636f756c642062653c6e6f7363726970743e0a + 686176696e67206265656e0d0a3c686561643e0d0a3c202671756f743b546865 + 20636f6d70696c6174696f6e686520686164206265656e70726f647563656420 + 62797068696c6f736f70686572636f6e7374727563746564696e74656e646564 + 20746f616d6f6e67206f74686572636f6d706172656420746f746f2073617920 + 74686174456e67696e656572696e676120646966666572656e74726566657272 + 656420746f646966666572656e63657362656c696566207468617470686f746f + 6772617068736964656e74696679696e67486973746f7279206f662052657075 + 626c6963206f666e65636573736172696c7970726f626162696c697479746563 + 686e6963616c6c796c656176696e672074686573706563746163756c61726672 + 616374696f6e206f66656c65637472696369747968656164206f662074686572 + 657374617572616e7473706172746e657273686970656d706861736973206f6e + 6d6f737420726563656e747368617265207769746820736179696e6720746861 + 7466696c6c6564207769746864657369676e656420746f6974206973206f6674 + 656e223e3c2f696672616d653e617320666f6c6c6f77733a6d65726765642077 + 6974687468726f75676820746865636f6d6d65726369616c20706f696e746564 + 206f75746f70706f7274756e69747976696577206f6620746865726571756972 + 656d656e746469766973696f6e206f6670726f6772616d6d696e676865207265 + 636569766564736574496e74657276616c223e3c2f7370616e3e3c2f696e204e + 657720596f726b6164646974696f6e616c20636f6d7072657373696f6e0a0a3c + 6469762069643d22696e636f72706f726174653b3c2f7363726970743e3c6174 + 746163684576656e74626563616d65207468652022207461726765743d225f63 + 617272696564206f7574536f6d65206f6620746865736369656e636520616e64 + 7468652074696d65206f66436f6e7461696e6572223e6d61696e7461696e696e + 674368726973746f706865724d756368206f662074686577726974696e677320 + 6f6622206865696768743d223273697a65206f662074686576657273696f6e20 + 6f66206d697874757265206f66206265747765656e207468654578616d706c65 + 73206f66656475636174696f6e616c636f6d7065746974697665206f6e737562 + 6d69743d226469726563746f72206f6664697374696e63746976652f44544420 + 5848544d4c2072656c6174696e6720746f74656e64656e637920746f70726f76 + 696e6365206f66776869636820776f756c646465737069746520746865736369 + 656e7469666963206c656769736c61747572652e696e6e657248544d4c20616c + 6c65676174696f6e734167726963756c74757265776173207573656420696e61 + 7070726f61636820746f696e74656c6c6967656e747965617273206c61746572 + 2c73616e732d736572696664657465726d696e696e67506572666f726d616e63 + 65617070656172616e6365732c20776869636820697320666f756e646174696f + 6e736162627265766961746564686967686572207468616e732066726f6d2074 + 686520696e646976696475616c20636f6d706f736564206f66737570706f7365 + 6420746f636c61696d7320746861746174747269627574696f6e666f6e742d73 + 697a653a31656c656d656e7473206f66486973746f726963616c206869732062 + 726f746865726174207468652074696d65616e6e6976657273617279676f7665 + 726e656420627972656c6174656420746f20756c74696d6174656c7920696e6e + 6f766174696f6e736974206973207374696c6c63616e206f6e6c792062656465 + 66696e6974696f6e73746f474d54537472696e6741206e756d626572206f6669 + 6d6720636c6173733d224576656e7475616c6c792c776173206368616e676564 + 6f6363757272656420696e6e65696768626f72696e6764697374696e67756973 + 687768656e20686520776173696e74726f647563696e67746572726573747269 + 616c4d616e79206f66207468656172677565732074686174616e20416d657269 + 63616e636f6e7175657374206f66776964657370726561642077657265206b69 + 6c6c656473637265656e20616e6420496e206f7264657220746f657870656374 + 656420746f64657363656e64616e7473617265206c6f63617465646c65676973 + 6c617469766567656e65726174696f6e73206261636b67726f756e646d6f7374 + 2070656f706c6579656172732061667465727468657265206973206e6f746865 + 20686967686573746672657175656e746c79207468657920646f206e6f746172 + 67756564207468617473686f7765642074686174707265646f6d696e616e7474 + 68656f6c6f676963616c6279207468652074696d65636f6e7369646572696e67 + 73686f72742d6c697665643c2f7370616e3e3c2f613e63616e20626520757365 + 6476657279206c6974746c656f6e65206f66207468652068616420616c726561 + 6479696e746572707265746564636f6d6d756e69636174656665617475726573 + 206f66676f7665726e6d656e742c3c2f6e6f7363726970743e656e7465726564 + 2074686522206865696768743d2233496e646570656e64656e74706f70756c61 + 74696f6e736c617267652d7363616c652e20416c74686f756768207573656420 + 696e207468656465737472756374696f6e706f73736962696c69747973746172 + 74696e6720696e74776f206f72206d6f726565787072657373696f6e73737562 + 6f7264696e6174656c6172676572207468616e686973746f727920616e643c2f + 6f7074696f6e3e0d0a436f6e74696e656e74616c656c696d696e6174696e6777 + 696c6c206e6f742062657072616374696365206f66696e2066726f6e74206f66 + 73697465206f6620746865656e737572652074686174746f2063726561746520 + 616d69737369737369707069706f74656e7469616c6c796f75747374616e6469 + 6e67626574746572207468616e77686174206973206e6f777369747561746564 + 20696e6d657461206e616d653d22547261646974696f6e616c73756767657374 + 696f6e735472616e736c6174696f6e74686520666f726d206f6661746d6f7370 + 68657269636964656f6c6f676963616c656e74657270726973657363616c6375 + 6c6174696e6765617374206f662074686572656d6e616e7473206f66706c7567 + 696e73706167652f696e6465782e7068703f72656d61696e656420696e747261 + 6e73666f726d656448652077617320616c736f77617320616c72656164797374 + 61746973746963616c696e206661766f72206f664d696e6973747279206f666d + 6f76656d656e74206f66666f726d756c6174696f6e6973207265717569726564 + 3c6c696e6b2072656c3d225468697320697320746865203c6120687265663d22 + 2f706f70756c6172697a6564696e766f6c76656420696e617265207573656420 + 746f616e64207365766572616c6d616465206279207468657365656d7320746f + 2062656c696b656c79207468617450616c657374696e69616e6e616d65642061 + 66746572697420686164206265656e6d6f737420636f6d6d6f6e746f20726566 + 657220746f6275742074686973206973636f6e736563757469766574656d706f + 726172696c79496e2067656e6572616c2c636f6e76656e74696f6e7374616b65 + 7320706c6163657375626469766973696f6e7465727269746f7269616c6f7065 + 726174696f6e616c7065726d616e656e746c79776173206c617267656c796f75 + 74627265616b206f66696e207468652070617374666f6c6c6f77696e67206120 + 786d6c6e733a6f673d223e3c6120636c6173733d22636c6173733d2274657874 + 436f6e76657273696f6e206d617920626520757365646d616e75666163747572 + 656166746572206265696e67636c656172666978223e0a7175657374696f6e20 + 6f6677617320656c6563746564746f206265636f6d6520616265636175736520 + 6f6620736f6d652070656f706c65696e73706972656420627973756363657373 + 66756c20612074696d65207768656e6d6f726520636f6d6d6f6e616d6f6e6773 + 7420746865616e206f6666696369616c77696474683a313030253b746563686e + 6f6c6f67792c7761732061646f70746564746f206b6565702074686573657474 + 6c656d656e74736c69766520626972746873696e6465782e68746d6c22436f6e + 6e6563746963757461737369676e656420746f26616d703b74696d65733b6163 + 636f756e7420666f72616c69676e3d726967687474686520636f6d70616e7961 + 6c77617973206265656e72657475726e656420746f696e766f6c76656d656e74 + 42656361757365207468657468697320706572696f6422206e616d653d227122 + 20636f6e66696e656420746f6120726573756c74206f6676616c75653d222220 + 2f3e69732061637475616c6c79456e7669726f6e6d656e740d0a3c2f68656164 + 3e0d0a436f6e76657273656c792c3e0a3c6469762069643d2230222077696474 + 683d223169732070726f6261626c7968617665206265636f6d65636f6e74726f + 6c6c696e677468652070726f626c656d636974697a656e73206f66706f6c6974 + 696369616e7372656163686564207468656173206561726c792061733a6e6f6e + 653b206f7665723c7461626c652063656c6c76616c6964697479206f66646972 + 6563746c7920746f6f6e6d6f757365646f776e77686572652069742069737768 + 656e206974207761736d656d62657273206f662072656c6174696f6e20746f61 + 63636f6d6d6f64617465616c6f6e67207769746820496e20746865206c617465 + 74686520456e676c69736864656c6963696f7573223e74686973206973206e6f + 747468652070726573656e746966207468657920617265616e642066696e616c + 6c7961206d6174746572206f660d0a093c2f6469763e0d0a0d0a3c2f73637269 + 70743e666173746572207468616e6d616a6f72697479206f6661667465722077 + 68696368636f6d7061726174697665746f206d61696e7461696e696d70726f76 + 6520746865617761726465642074686565722220636c6173733d226672616d65 + 626f72646572726573746f726174696f6e696e207468652073616d65616e616c + 79736973206f667468656972206669727374447572696e672074686520636f6e + 74696e656e74616c73657175656e6365206f6666756e6374696f6e28297b666f + 6e742d73697a653a20776f726b206f6e207468653c2f7363726970743e0a3c62 + 6567696e7320776974686a6176617363726970743a636f6e7374697475656e74 + 77617320666f756e646564657175696c69627269756d617373756d6520746861 + 74697320676976656e2062796e6565647320746f206265636f6f7264696e6174 + 657374686520766172696f75736172652070617274206f666f6e6c7920696e20 + 74686573656374696f6e73206f666973206120636f6d6d6f6e7468656f726965 + 73206f66646973636f7665726965736173736f63696174696f6e65646765206f + 6620746865737472656e677468206f66706f736974696f6e20696e7072657365 + 6e742d646179756e6976657273616c6c79746f20666f726d2074686562757420 + 696e7374656164636f72706f726174696f6e617474616368656420746f697320 + 636f6d6d6f6e6c79726561736f6e7320666f72202671756f743b746865206361 + 6e206265206d6164657761732061626c6520746f7768696368206d65616e7362 + 757420646964206e6f746f6e4d6f7573654f766572617320706f737369626c65 + 6f70657261746564206279636f6d696e672066726f6d746865207072696d6172 + 796164646974696f6e206f66666f72207365766572616c7472616e7366657272 + 65646120706572696f64206f666172652061626c6520746f686f77657665722c + 20697473686f756c6420686176656d756368206c61726765720a093c2f736372 + 6970743e61646f707465642074686570726f7065727479206f66646972656374 + 65642062796566666563746976656c797761732062726f756768746368696c64 + 72656e206f6650726f6772616d6d696e676c6f6e676572207468616e6d616e75 + 7363726970747377617220616761696e73746279206d65616e73206f66616e64 + 206d6f7374206f6673696d696c617220746f2070726f70726965746172796f72 + 6967696e6174696e6770726573746967696f75736772616d6d61746963616c65 + 7870657269656e63652e746f206d616b652074686549742077617320616c736f + 697320666f756e6420696e636f6d70657469746f7273696e2074686520552e53 + 2e7265706c6163652074686562726f756768742074686563616c63756c617469 + 6f6e66616c6c206f66207468657468652067656e6572616c7072616374696361 + 6c6c79696e20686f6e6f72206f6672656c656173656420696e7265736964656e + 7469616c616e6420736f6d65206f666b696e67206f6620746865726561637469 + 6f6e20746f317374204561726c206f6663756c7475726520616e647072696e63 + 6970616c6c793c2f7469746c653e0a2020746865792063616e2062656261636b + 20746f20746865736f6d65206f66206869736578706f7375726520746f617265 + 2073696d696c6172666f726d206f66207468656164644661766f726974656369 + 74697a656e736869707061727420696e2074686570656f706c65207769746869 + 6e207072616374696365746f20636f6e74696e756526616d703b6d696e75733b + 617070726f7665642062792074686520666972737420616c6c6f776564207468 + 65616e6420666f722074686566756e6374696f6e696e67706c6179696e672074 + 6865736f6c7574696f6e20746f6865696768743d22302220696e206869732062 + 6f6f6b6d6f7265207468616e2061666f6c6c6f77732074686563726561746564 + 2074686570726573656e636520696e266e6273703b3c2f74643e6e6174696f6e + 616c6973747468652069646561206f6661206368617261637465727765726520 + 666f7263656420636c6173733d2262746e64617973206f662074686566656174 + 7572656420696e73686f77696e6720746865696e74657265737420696e696e20 + 706c616365206f667475726e206f66207468657468652068656164206f664c6f + 7264206f6620746865706f6c69746963616c6c7968617320697473206f776e45 + 6475636174696f6e616c617070726f76616c206f66736f6d65206f6620746865 + 65616368206f746865722c6265686176696f72206f66616e6420626563617573 + 65616e6420616e6f746865726170706561726564206f6e7265636f7264656420 + 696e626c61636b2671756f743b6d617920696e636c75646574686520776f726c + 64277363616e206c65616420746f72656665727320746f2061626f726465723d + 22302220676f7665726e6d656e742077696e6e696e6720746865726573756c74 + 656420696e207768696c65207468652057617368696e67746f6e2c7468652073 + 75626a6563746369747920696e207468653e3c2f6469763e0d0a09097265666c + 65637420746865746f20636f6d706c657465626563616d65206d6f7265726164 + 696f61637469766572656a6563746564206279776974686f757420616e796869 + 73206661746865722c776869636820636f756c64636f7079206f662074686574 + 6f20696e6469636174656120706f6c69746963616c6163636f756e7473206f66 + 636f6e7374697475746573776f726b6564207769746865723c2f613e3c2f6c69 + 3e6f6620686973206c6966656163636f6d70616e696564636c69656e74576964 + 746870726576656e74207468654c656769736c6174697665646966666572656e + 746c79746f67657468657220696e686173207365766572616c666f7220616e6f + 7468657274657874206f6620746865666f756e64656420746865652077697468 + 20746865206973207573656420666f726368616e67656420746865757375616c + 6c7920746865706c61636520776865726577686572656173207468653e203c61 + 20687265663d22223e3c6120687265663d227468656d73656c7665732c616c74 + 686f756768206865746861742063616e206265747261646974696f6e616c726f + 6c65206f66207468656173206120726573756c7472656d6f76654368696c6464 + 657369676e656420627977657374206f6620746865536f6d652070656f706c65 + 70726f64756374696f6e2c73696465206f66207468656e6577736c6574746572 + 737573656420627920746865646f776e20746f20746865616363657074656420 + 62796c69766520696e20746865617474656d70747320746f6f75747369646520 + 7468656672657175656e63696573486f77657665722c20696e70726f6772616d + 6d6572736174206c6561737420696e617070726f78696d617465616c74686f75 + 67682069747761732070617274206f66616e6420766172696f7573476f766572 + 6e6f72206f667468652061727469636c657475726e656420696e746f3e3c6120 + 687265663d222f7468652065636f6e6f6d79697320746865206d6f73746d6f73 + 7420776964656c79776f756c64206c61746572616e6420706572686170737269 + 736520746f207468656f6363757273207768656e756e64657220776869636863 + 6f6e646974696f6e732e746865207765737465726e7468656f72792074686174 + 69732070726f64756365647468652063697479206f66696e2077686963682068 + 657365656e20696e207468657468652063656e7472616c6275696c64696e6720 + 6f666d616e79206f662068697361726561206f6620746865697320746865206f + 6e6c796d6f7374206f66207468656d616e79206f662074686574686520576573 + 7465726e5468657265206973206e6f657874656e64656420746f537461746973 + 746963616c636f6c7370616e3d32207c73686f72742073746f7279706f737369 + 626c6520746f746f706f6c6f676963616c637269746963616c206f667265706f + 7274656420746f612043687269737469616e6465636973696f6e20746f697320 + 657175616c20746f70726f626c656d73206f66546869732063616e2062656d65 + 726368616e64697365666f72206d6f7374206f666e6f2065766964656e636565 + 646974696f6e73206f66656c656d656e747320696e2671756f743b2e20546865 + 636f6d2f696d616765732f7768696368206d616b65737468652070726f636573 + 7372656d61696e73207468656c6974657261747572652c69732061206d656d62 + 657274686520706f70756c617274686520616e6369656e7470726f626c656d73 + 20696e74696d65206f66207468656465666561746564206279626f6479206f66 + 2074686561206665772079656172736d756368206f662074686574686520776f + 726b206f6643616c69666f726e69612c7365727665642061732061676f766572 + 6e6d656e742e636f6e6365707473206f666d6f76656d656e7420696e09093c64 + 69762069643d226974222076616c75653d226c616e6775616765206f66617320 + 746865792061726570726f647563656420696e69732074686174207468656578 + 706c61696e207468656469763e3c2f6469763e0a486f7765766572207468656c + 65616420746f20746865093c6120687265663d222f776173206772616e746564 + 70656f706c652068617665636f6e74696e75616c6c79776173207365656e2061 + 73616e642072656c6174656474686520726f6c65206f6670726f706f73656420 + 62796f6620746865206265737465616368206f746865722e436f6e7374616e74 + 696e6570656f706c652066726f6d6469616c65637473206f66746f2072657669 + 73696f6e7761732072656e616d65646120736f75726365206f6674686520696e + 697469616c6c61756e6368656420696e70726f7669646520746865746f207468 + 6520776573747768657265207468657265616e642073696d696c617262657477 + 65656e2074776f697320616c736f20746865456e676c69736820616e64636f6e + 646974696f6e732c7468617420697420776173656e7469746c656420746f7468 + 656d73656c7665732e7175616e74697479206f6672616e73706172656e637974 + 68652073616d65206173746f206a6f696e20746865636f756e74727920616e64 + 746869732069732074686554686973206c656420746f612073746174656d656e + 74636f6e747261737420746f6c617374496e6465784f667468726f7567682068 + 697369732064657369676e6564746865207465726d20697369732070726f7669 + 64656470726f74656374207468656e673c2f613e3c2f6c693e54686520637572 + 72656e747468652073697465206f667375627374616e7469616c657870657269 + 656e63652c696e207468652057657374746865792073686f756c64736c6f7665 + 6ec48d696e61636f6d656e746172696f73756e697665727369646164636f6e64 + 6963696f6e65736163746976696461646573657870657269656e636961746563 + 6e6f6c6f67c3ad6170726f6475636369c3b36e70756e7475616369c3b36e6170 + 6c6963616369c3b36e636f6e7472617365c3b16163617465676f72c3ad617372 + 6567697374726172736570726f666573696f6e616c74726174616d69656e746f + 726567c3ad7374726174657365637265746172c3ad617072696e636970616c65 + 7370726f7465636369c3b36e696d706f7274616e746573696d706f7274616e63 + 6961706f736962696c69646164696e7465726573616e746563726563696d6965 + 6e746f6e65636573696461646573737573637269626972736561736f63696163 + 69c3b36e646973706f6e69626c65736576616c75616369c3b36e657374756469 + 616e746573726573706f6e7361626c657265736f6c756369c3b36e6775616461 + 6c616a6172617265676973747261646f736f706f7274756e69646164636f6d65 + 726369616c6573666f746f67726166c3ad616175746f72696461646573696e67 + 656e696572c3ad6174656c6576697369c3b36e636f6d706574656e6369616f70 + 65726163696f6e657365737461626c656369646f73696d706c656d656e746561 + 637475616c6d656e74656e61766567616369c3b36e636f6e666f726d69646164 + 6c696e652d6865696768743a666f6e742d66616d696c793a22203a2022687474 + 703a2f2f6170706c69636174696f6e736c696e6b2220687265663d2273706563 + 69666963616c6c792f2f3c215b43444154415b0a4f7267616e697a6174696f6e + 646973747269627574696f6e3070783b206865696768743a72656c6174696f6e + 736869706465766963652d77696474683c64697620636c6173733d223c6c6162 + 656c20666f723d22726567697374726174696f6e3c2f6e6f7363726970743e0a + 2f696e6465782e68746d6c2277696e646f772e6f70656e282021696d706f7274 + 616e743b6170706c69636174696f6e2f696e646570656e64656e63652f2f7777 + 772e676f6f676c656f7267616e697a6174696f6e6175746f636f6d706c657465 + 726571756972656d656e7473636f6e7365727661746976653c666f726d206e61 + 6d653d22696e74656c6c65637475616c6d617267696e2d6c6566743a31387468 + 2063656e74757279616e20696d706f7274616e74696e737469747574696f6e73 + 616262726576696174696f6e3c696d6720636c6173733d226f7267616e697361 + 74696f6e636976696c697a6174696f6e313974682063656e7475727961726368 + 6974656374757265696e636f72706f7261746564323074682063656e74757279 + 2d636f6e7461696e6572223e6d6f7374206e6f7461626c792f3e3c2f613e3c2f + 6469763e6e6f74696669636174696f6e27756e646566696e6564272946757274 + 6865726d6f72652c62656c696576652074686174696e6e657248544d4c203d20 + 7072696f7220746f207468656472616d61746963616c6c79726566657272696e + 6720746f6e65676f74696174696f6e73686561647175617274657273536f7574 + 6820416672696361756e7375636365737366756c50656e6e73796c76616e6961 + 4173206120726573756c742c3c68746d6c206c616e673d22266c743b2f737570 + 2667743b6465616c696e6720776974687068696c6164656c7068696168697374 + 6f726963616c6c79293b3c2f7363726970743e0a70616464696e672d746f703a + 6578706572696d656e74616c676574417474726962757465696e737472756374 + 696f6e73746563686e6f6c6f6769657370617274206f6620746865203d66756e + 6374696f6e28297b737562736372697074696f6e6c2e647464223e0d0a3c6874 + 67656f67726170686963616c436f6e737469747574696f6e272c2066756e6374 + 696f6e28737570706f727465642062796167726963756c747572616c636f6e73 + 7472756374696f6e7075626c69636174696f6e73666f6e742d73697a653a2031 + 612076617269657479206f663c646976207374796c653d22456e6379636c6f70 + 65646961696672616d65207372633d2264656d6f6e737472617465646163636f + 6d706c6973686564756e6976657273697469657344656d6f6772617068696373 + 293b3c2f7363726970743e3c64656469636174656420746f6b6e6f776c656467 + 65206f66736174697366616374696f6e706172746963756c61726c793c2f6469 + 763e3c2f6469763e456e676c6973682028555329617070656e644368696c6428 + 7472616e736d697373696f6e732e20486f77657665722c20696e74656c6c6967 + 656e63652220746162696e6465783d22666c6f61743a72696768743b436f6d6d + 6f6e7765616c746872616e67696e672066726f6d696e20776869636820746865 + 6174206c65617374206f6e65726570726f64756374696f6e656e6379636c6f70 + 656469613b666f6e742d73697a653a316a7572697364696374696f6e61742074 + 6861742074696d65223e3c6120636c6173733d22496e206164646974696f6e2c + 6465736372697074696f6e2b636f6e766572736174696f6e636f6e7461637420 + 7769746869732067656e6572616c6c79722220636f6e74656e743d2272657072 + 6573656e74696e67266c743b6d6174682667743b70726573656e746174696f6e + 6f63636173696f6e616c6c793c696d672077696474683d226e61766967617469 + 6f6e223e636f6d70656e736174696f6e6368616d70696f6e736869706d656469 + 613d22616c6c222076696f6c6174696f6e206f667265666572656e636520746f + 72657475726e20747275653b5374726963742f2f454e22207472616e73616374 + 696f6e73696e74657276656e74696f6e766572696669636174696f6e496e666f + 726d6174696f6e20646966666963756c746965734368616d70696f6e73686970 + 6361706162696c69746965733c215b656e6469665d2d2d3e7d0a3c2f73637269 + 70743e0a43687269737469616e697479666f72206578616d706c652c50726f66 + 657373696f6e616c7265737472696374696f6e73737567676573742074686174 + 7761732072656c656173656428737563682061732074686572656d6f7665436c + 61737328756e656d706c6f796d656e7474686520416d65726963616e73747275 + 6374757265206f662f696e6465782e68746d6c207075626c697368656420696e + 7370616e20636c6173733d22223e3c6120687265663d222f696e74726f647563 + 74696f6e62656c6f6e67696e6720746f636c61696d65642074686174636f6e73 + 657175656e6365733c6d657461206e616d653d22477569646520746f20746865 + 6f7665727768656c6d696e67616761696e73742074686520636f6e63656e7472 + 617465642c0a2e6e6f6e746f756368206f62736572766174696f6e733c2f613e + 0a3c2f6469763e0a662028646f63756d656e742e626f726465723a2031707820 + 7b666f6e742d73697a653a3174726561746d656e74206f663022206865696768 + 743d22316d6f64696669636174696f6e496e646570656e64656e636564697669 + 64656420696e746f67726561746572207468616e616368696576656d656e7473 + 65737461626c697368696e674a61766153637269707422206e65766572746865 + 6c6573737369676e69666963616e636542726f616463617374696e673e266e62 + 73703b3c2f74643e636f6e7461696e6572223e0a737563682061732074686520 + 696e666c75656e6365206f666120706172746963756c61727372633d27687474 + 703a2f2f6e617669676174696f6e222068616c66206f66207468652073756273 + 74616e7469616c20266e6273703b3c2f6469763e616476616e74616765206f66 + 646973636f76657279206f6666756e64616d656e74616c206d6574726f706f6c + 6974616e746865206f70706f736974652220786d6c3a6c616e673d2264656c69 + 6265726174656c79616c69676e3d63656e74657265766f6c7574696f6e206f66 + 707265736572766174696f6e696d70726f76656d656e7473626567696e6e696e + 6720696e4a65737573204368726973745075626c69636174696f6e7364697361 + 677265656d656e74746578742d616c69676e3a722c2066756e6374696f6e2829 + 73696d696c61726974696573626f64793e3c2f68746d6c3e6973206375727265 + 6e746c79616c7068616265746963616c697320736f6d6574696d657374797065 + 3d22696d6167652f6d616e79206f662074686520666c6f773a68696464656e3b + 617661696c61626c6520696e6465736372696265207468656578697374656e63 + 65206f66616c6c206f7665722074686574686520496e7465726e6574093c756c + 20636c6173733d22696e7374616c6c6174696f6e6e65696768626f72686f6f64 + 61726d656420666f726365737265647563696e6720746865636f6e74696e7565 + 7320746f4e6f6e657468656c6573732c74656d7065726174757265730a09093c + 6120687265663d22636c6f736520746f207468656578616d706c6573206f6620 + 69732061626f757420746865287365652062656c6f77292e222069643d227365 + 6172636870726f66657373696f6e616c697320617661696c61626c6574686520 + 6f6666696369616c09093c2f7363726970743e0a0a09093c6469762069643d22 + 616363656c65726174696f6e7468726f756768207468652048616c6c206f6620 + 46616d656465736372697074696f6e737472616e736c6174696f6e73696e7465 + 72666572656e636520747970653d27746578742f726563656e74207965617273 + 696e2074686520776f726c647665727920706f70756c61727b6261636b67726f + 756e643a747261646974696f6e616c20736f6d65206f662074686520636f6e6e + 656374656420746f6578706c6f69746174696f6e656d657267656e6365206f66 + 636f6e737469747574696f6e4120486973746f7279206f667369676e69666963 + 616e74206d616e7566616374757265646578706563746174696f6e733e3c6e6f + 7363726970743e3c63616e20626520666f756e64626563617573652074686520 + 686173206e6f74206265656e6e65696768626f7572696e67776974686f757420 + 74686520616464656420746f20746865093c6c6920636c6173733d22696e7374 + 72756d656e74616c536f7669657420556e696f6e61636b6e6f776c6564676564 + 77686963682063616e2062656e616d6520666f7220746865617474656e74696f + 6e20746f617474656d70747320746f20646576656c6f706d656e7473496e2066 + 6163742c207468653c6c6920636c6173733d2261696d706c69636174696f6e73 + 7375697461626c6520666f726d756368206f662074686520636f6c6f6e697a61 + 74696f6e707265736964656e7469616c63616e63656c427562626c6520496e66 + 6f726d6174696f6e6d6f7374206f662074686520697320646573637269626564 + 72657374206f6620746865206d6f7265206f72206c657373696e205365707465 + 6d626572496e74656c6c6967656e63657372633d22687474703a2f2f70783b20 + 6865696768743a20617661696c61626c6520746f6d616e756661637475726572 + 68756d616e207269676874736c696e6b20687265663d222f617661696c616269 + 6c69747970726f706f7274696f6e616c6f757473696465207468652061737472 + 6f6e6f6d6963616c68756d616e206265696e67736e616d65206f662074686520 + 61726520666f756e6420696e617265206261736564206f6e736d616c6c657220 + 7468616e6120706572736f6e2077686f657870616e73696f6e206f6661726775 + 696e6720746861746e6f77206b6e6f776e206173496e20746865206561726c79 + 696e7465726d656469617465646572697665642066726f6d5363616e64696e61 + 7669616e3c2f613e3c2f6469763e0d0a636f6e736964657220746865616e2065 + 7374696d61746564746865204e6174696f6e616c3c6469762069643d22706167 + 726573756c74696e6720696e636f6d6d697373696f6e6564616e616c6f676f75 + 7320746f6172652072657175697265642f756c3e0a3c2f6469763e0a77617320 + 6261736564206f6e616e6420626563616d652061266e6273703b266e6273703b + 74222076616c75653d2222207761732063617074757265646e6f206d6f726520 + 7468616e726573706563746976656c79636f6e74696e756520746f203e0d0a3c + 686561643e0d0a3c7765726520637265617465646d6f72652067656e6572616c + 696e666f726d6174696f6e207573656420666f7220746865696e646570656e64 + 656e742074686520496d70657269616c636f6d706f6e656e74206f66746f2074 + 6865206e6f727468696e636c7564652074686520436f6e737472756374696f6e + 73696465206f662074686520776f756c64206e6f74206265666f7220696e7374 + 616e6365696e76656e74696f6e206f666d6f726520636f6d706c6578636f6c6c + 6563746976656c796261636b67726f756e643a20746578742d616c69676e3a20 + 697473206f726967696e616c696e746f206163636f756e74746869732070726f + 63657373616e20657874656e73697665686f77657665722c2074686574686579 + 20617265206e6f7472656a65637465642074686563726974696369736d206f66 + 647572696e6720776869636870726f6261626c79207468657468697320617274 + 69636c652866756e6374696f6e28297b49742073686f756c64206265616e2061 + 677265656d656e746163636964656e74616c6c79646966666572732066726f6d + 417263686974656374757265626574746572206b6e6f776e617272616e67656d + 656e7473696e666c75656e6365206f6e617474656e646564207468656964656e + 746963616c20746f736f757468206f662074686570617373207468726f756768 + 786d6c22207469746c653d227765696768743a626f6c643b6372656174696e67 + 20746865646973706c61793a6e6f6e657265706c61636564207468653c696d67 + 207372633d222f6968747470733a2f2f7777772e576f726c6420576172204949 + 74657374696d6f6e69616c73666f756e6420696e207468657265717569726564 + 20746f20616e642074686174207468656265747765656e207468652077617320 + 64657369676e6564636f6e7369737473206f6620636f6e736964657261626c79 + 7075626c6973686564206279746865206c616e6775616765436f6e7365727661 + 74696f6e636f6e736973746564206f66726566657220746f207468656261636b + 20746f207468652063737322206d656469613d2250656f706c652066726f6d20 + 617661696c61626c65206f6e70726f76656420746f2062657375676765737469 + 6f6e7322776173206b6e6f776e206173766172696574696573206f666c696b65 + 6c7920746f206265636f6d707269736564206f66737570706f72742074686520 + 68616e6473206f6620746865636f75706c65642077697468636f6e6e65637420 + 616e6420626f726465723a6e6f6e653b706572666f726d616e6365736265666f + 7265206265696e676c6174657220626563616d6563616c63756c6174696f6e73 + 6f6674656e2063616c6c65647265736964656e7473206f666d65616e696e6720 + 746861743e3c6c6920636c6173733d2265766964656e636520666f726578706c + 616e6174696f6e73656e7669726f6e6d656e7473223e3c2f613e3c2f6469763e + 776869636820616c6c6f7773496e74726f64756374696f6e646576656c6f7065 + 642062796120776964652072616e67656f6e20626568616c66206f6676616c69 + 676e3d22746f70227072696e6369706c65206f666174207468652074696d652c + 3c2f6e6f7363726970743e0d7361696420746f2068617665696e207468652066 + 697273747768696c65206f74686572736879706f746865746963616c7068696c + 6f736f7068657273706f776572206f6620746865636f6e7461696e656420696e + 706572666f726d6564206279696e6162696c69747920746f7765726520777269 + 7474656e7370616e207374796c653d22696e707574206e616d653d2274686520 + 7175657374696f6e696e74656e64656420666f7272656a656374696f6e206f66 + 696d706c6965732074686174696e76656e74656420746865746865207374616e + 646172647761732070726f6261626c796c696e6b206265747765656e70726f66 + 6573736f72206f66696e746572616374696f6e736368616e67696e6720746865 + 496e6469616e204f6365616e20636c6173733d226c617374776f726b696e6720 + 7769746827687474703a2f2f7777772e7965617273206265666f726554686973 + 207761732074686572656372656174696f6e616c656e746572696e6720746865 + 6d6561737572656d656e7473616e2065787472656d656c7976616c7565206f66 + 207468657374617274206f66207468650a3c2f7363726970743e0a0a616e2065 + 66666f727420746f696e63726561736520746865746f2074686520736f757468 + 73706163696e673d2230223e73756666696369656e746c79746865204575726f + 7065616e636f6e76657274656420746f636c65617254696d656f757464696420 + 6e6f742068617665636f6e73657175656e746c79666f7220746865206e657874 + 657874656e73696f6e206f6665636f6e6f6d696320616e64616c74686f756768 + 207468656172652070726f6475636564616e64207769746820746865696e7375 + 6666696369656e74676976656e2062792074686573746174696e672074686174 + 657870656e646974757265733c2f7370616e3e3c2f613e0a74686f7567687420 + 746861746f6e2074686520626173697363656c6c70616464696e673d696d6167 + 65206f662074686572657475726e696e6720746f696e666f726d6174696f6e2c + 736570617261746564206279617373617373696e61746564732220636f6e7465 + 6e743d22617574686f72697479206f666e6f7274687765737465726e3c2f6469 + 763e0a3c64697620223e3c2f6469763e0d0a2020636f6e73756c746174696f6e + 636f6d6d756e697479206f66746865206e6174696f6e616c69742073686f756c + 642062657061727469636970616e747320616c69676e3d226c65667474686520 + 677265617465737473656c656374696f6e206f6673757065726e61747572616c + 646570656e64656e74206f6e6973206d656e74696f6e6564616c6c6f77696e67 + 2074686577617320696e76656e7465646163636f6d70616e79696e6768697320 + 706572736f6e616c617661696c61626c652061747374756479206f6620746865 + 6f6e20746865206f74686572657865637574696f6e206f6648756d616e205269 + 676874737465726d73206f66207468656173736f63696174696f6e7372657365 + 6172636820616e64737563636565646564206279646566656174656420746865 + 616e642066726f6d20746865627574207468657920617265636f6d6d616e6465 + 72206f667374617465206f66207468657965617273206f662061676574686520 + 7374756479206f663c756c20636c6173733d2273706c61636520696e20746865 + 7768657265206865207761733c6c6920636c6173733d22667468657265206172 + 65206e6f776869636820626563616d656865207075626c697368656465787072 + 657373656420696e746f20776869636820746865636f6d6d697373696f6e6572 + 666f6e742d7765696768743a7465727269746f7279206f66657874656e73696f + 6e73223e526f6d616e20456d70697265657175616c20746f20746865496e2063 + 6f6e74726173742c686f77657665722c20616e646973207479706963616c6c79 + 616e6420686973207769666528616c736f2063616c6c65643e3c756c20636c61 + 73733d226566666563746976656c792065766f6c76656420696e746f7365656d + 20746f2068617665776869636820697320746865746865726520776173206e6f + 616e20657863656c6c656e74616c6c206f662074686573656465736372696265 + 64206279496e2070726163746963652c62726f616463617374696e6763686172 + 67656420776974687265666c656374656420696e7375626a656374656420746f + 6d696c697461727920616e64746f2074686520706f696e7465636f6e6f6d6963 + 616c6c79736574546172676574696e676172652061637475616c6c7976696374 + 6f7279206f76657228293b3c2f7363726970743e636f6e74696e756f75736c79 + 726571756972656420666f7265766f6c7574696f6e617279616e206566666563 + 746976656e6f727468206f66207468652c207768696368207761732066726f6e + 74206f66207468656f72206f7468657277697365736f6d6520666f726d206f66 + 686164206e6f74206265656e67656e657261746564206279696e666f726d6174 + 696f6e2e7065726d697474656420746f696e636c756465732074686564657665 + 6c6f706d656e742c656e746572656420696e746f7468652070726576696f7573 + 636f6e73697374656e746c79617265206b6e6f776e206173746865206669656c + 64206f66746869732074797065206f66676976656e20746f2074686574686520 + 7469746c65206f66636f6e7461696e7320746865696e7374616e636573206f66 + 696e20746865206e6f72746864756520746f2074686569726172652064657369 + 676e6564636f72706f726174696f6e737761732074686174207468656f6e6520 + 6f662074686573656d6f726520706f70756c617273756363656564656420696e + 737570706f72742066726f6d696e20646966666572656e74646f6d696e617465 + 6420627964657369676e656420666f726f776e657273686970206f66616e6420 + 706f737369626c797374616e64617264697a6564726573706f6e736554657874 + 77617320696e74656e646564726563656976656420746865617373756d656420 + 746861746172656173206f66207468657072696d6172696c7920696e74686520 + 6261736973206f66696e207468652073656e73656163636f756e747320666f72 + 64657374726f7965642062796174206c656173742074776f776173206465636c + 61726564636f756c64206e6f74206265536563726574617279206f6661707065 + 617220746f2062656d617267696e2d746f703a312f5e5c732b7c5c732b242f67 + 65297b7468726f7720657d3b746865207374617274206f6674776f2073657061 + 726174656c616e677561676520616e6477686f20686164206265656e6f706572 + 6174696f6e206f666465617468206f66207468657265616c206e756d62657273 + 093c6c696e6b2072656c3d2270726f7669646564207468657468652073746f72 + 79206f66636f6d7065746974696f6e73656e676c6973682028554b29656e676c + 6973682028555329d09cd0bed0bdd0b3d0bed0bbd0a1d180d0bfd181d0bad0b8 + d181d180d0bfd181d0bad0b8d181d180d0bfd181d0bad0bed984d8b9d8b1d8a8 + d98ad8a9e6ada3e9ab94e4b8ade69687e7ae80e4bd93e4b8ade69687e7b981e4 + bd93e4b8ade69687e69c89e99990e585ace58fb8e4babae6b091e694bfe5ba9c + e998bfe9878ce5b7b4e5b7b4e7a4bee4bc9ae4b8bbe4b989e6938de4bd9ce7b3 + bbe7bb9fe694bfe7ad96e6b395e8a784696e666f726d616369c3b36e68657272 + 616d69656e746173656c65637472c3b36e69636f646573637269706369c3b36e + 636c61736966696361646f73636f6e6f63696d69656e746f7075626c69636163 + 69c3b36e72656c6163696f6e61646173696e666f726dc3a17469636172656c61 + 63696f6e61646f73646570617274616d656e746f74726162616a61646f726573 + 646972656374616d656e74656179756e74616d69656e746f6d65726361646f4c + 69627265636f6e74c3a16374656e6f7368616269746163696f6e657363756d70 + 6c696d69656e746f72657374617572616e746573646973706f73696369c3b36e + 636f6e73656375656e636961656c65637472c3b36e69636161706c6963616369 + 6f6e6573646573636f6e65637461646f696e7374616c616369c3b36e7265616c + 697a616369c3b36e7574696c697a616369c3b36e656e6369636c6f7065646961 + 656e6665726d656461646573696e737472756d656e746f73657870657269656e + 63696173696e73746974756369c3b36e706172746963756c6172657373756263 + 617465676f726961d182d0bed0bbd18cd0bad0bed0a0d0bed181d181d0b8d0b8 + d180d0b0d0b1d0bed182d18bd0b1d0bed0bbd18cd188d0b5d0bfd180d0bed181 + d182d0bed0bcd0bed0b6d0b5d182d0b5d0b4d180d183d0b3d0b8d185d181d0bb + d183d187d0b0d0b5d181d0b5d0b9d187d0b0d181d0b2d181d0b5d0b3d0b4d0b0 + d0a0d0bed181d181d0b8d18fd09cd0bed181d0bad0b2d0b5d0b4d180d183d0b3 + d0b8d0b5d0b3d0bed180d0bed0b4d0b0d0b2d0bed0bfd180d0bed181d0b4d0b0 + d0bdd0bdd18bd185d0b4d0bed0bbd0b6d0bdd18bd0b8d0bcd0b5d0bdd0bdd0be + d09cd0bed181d0bad0b2d18bd180d183d0b1d0bbd0b5d0b9d09cd0bed181d0ba + d0b2d0b0d181d182d180d0b0d0bdd18bd0bdd0b8d187d0b5d0b3d0bed180d0b0 + d0b1d0bed182d0b5d0b4d0bed0bbd0b6d0b5d0bdd183d181d0bbd183d0b3d0b8 + d182d0b5d0bfd0b5d180d18cd09ed0b4d0bdd0b0d0bad0bed0bfd0bed182d0be + d0bcd183d180d0b0d0b1d0bed182d183d0b0d0bfd180d0b5d0bbd18fd0b2d0be + d0bed0b1d189d0b5d0bed0b4d0bdd0bed0b3d0bed181d0b2d0bed0b5d0b3d0be + d181d182d0b0d182d18cd0b8d0b4d180d183d0b3d0bed0b9d184d0bed180d183 + d0bcd0b5d185d0bed180d0bed188d0bed0bfd180d0bed182d0b8d0b2d181d181 + d18bd0bbd0bad0b0d0bad0b0d0b6d0b4d18bd0b9d0b2d0bbd0b0d181d182d0b8 + d0b3d180d183d0bfd0bfd18bd0b2d0bcd0b5d181d182d0b5d180d0b0d0b1d0be + d182d0b0d181d0bad0b0d0b7d0b0d0bbd0bfd0b5d180d0b2d18bd0b9d0b4d0b5 + d0bbd0b0d182d18cd0b4d0b5d0bdd18cd0b3d0b8d0bfd0b5d180d0b8d0bed0b4 + d0b1d0b8d0b7d0bdd0b5d181d0bed181d0bdd0bed0b2d0b5d0bcd0bed0bcd0b5 + d0bdd182d0bad183d0bfd0b8d182d18cd0b4d0bed0bbd0b6d0bdd0b0d180d0b0 + d0bcd0bad0b0d185d0bdd0b0d187d0b0d0bbd0bed0a0d0b0d0b1d0bed182d0b0 + d0a2d0bed0bbd18cd0bad0bed181d0bed0b2d181d0b5d0bcd0b2d182d0bed180 + d0bed0b9d0bdd0b0d187d0b0d0bbd0b0d181d0bfd0b8d181d0bed0bad181d0bb + d183d0b6d0b1d18bd181d0b8d181d182d0b5d0bcd0bfd0b5d187d0b0d182d0b8 + d0bdd0bed0b2d0bed0b3d0bed0bfd0bed0bcd0bed189d0b8d181d0b0d0b9d182 + d0bed0b2d0bfd0bed187d0b5d0bcd183d0bfd0bed0bcd0bed189d18cd0b4d0be + d0bbd0b6d0bdd0bed181d181d18bd0bbd0bad0b8d0b1d18bd181d182d180d0be + d0b4d0b0d0bdd0bdd18bd0b5d0bcd0bdd0bed0b3d0b8d0b5d0bfd180d0bed0b5 + d0bad182d0a1d0b5d0b9d187d0b0d181d0bcd0bed0b4d0b5d0bbd0b8d182d0b0 + d0bad0bed0b3d0bed0bed0bdd0bbd0b0d0b9d0bdd0b3d0bed180d0bed0b4d0b5 + d0b2d0b5d180d181d0b8d18fd181d182d180d0b0d0bdd0b5d184d0b8d0bbd18c + d0bcd18bd183d180d0bed0b2d0bdd18fd180d0b0d0b7d0bdd18bd185d0b8d181 + d0bad0b0d182d18cd0bdd0b5d0b4d0b5d0bbd18ed18fd0bdd0b2d0b0d180d18f + d0bcd0b5d0bdd18cd188d0b5d0bcd0bdd0bed0b3d0b8d185d0b4d0b0d0bdd0bd + d0bed0b9d0b7d0bdd0b0d187d0b8d182d0bdd0b5d0bbd18cd0b7d18fd184d0be + d180d183d0bcd0b0d0a2d0b5d0bfd0b5d180d18cd0bcd0b5d181d18fd186d0b0 + d0b7d0b0d189d0b8d182d18bd09bd183d187d188d0b8d0b5e0a4a8e0a4b9e0a5 + 80e0a482e0a495e0a4b0e0a4a8e0a587e0a485e0a4aae0a4a8e0a587e0a495e0 + a4bfe0a4afe0a4bee0a495e0a4b0e0a587e0a482e0a485e0a4a8e0a58de0a4af + e0a495e0a58de0a4afe0a4bee0a497e0a4bee0a487e0a4a1e0a4ace0a4bee0a4 + b0e0a587e0a495e0a4bfe0a4b8e0a580e0a4a6e0a4bfe0a4afe0a4bee0a4aae0 + a4b9e0a4b2e0a587e0a4b8e0a4bfe0a482e0a4b9e0a4ade0a4bee0a4b0e0a4a4 + e0a485e0a4aae0a4a8e0a580e0a4b5e0a4bee0a4b2e0a587e0a4b8e0a587e0a4 + b5e0a4bee0a495e0a4b0e0a4a4e0a587e0a4aee0a587e0a4b0e0a587e0a4b9e0 + a58be0a4a8e0a587e0a4b8e0a495e0a4a4e0a587e0a4ace0a4b9e0a581e0a4a4 + e0a4b8e0a4bee0a487e0a49fe0a4b9e0a58be0a497e0a4bee0a49ce0a4bee0a4 + a8e0a587e0a4aee0a4bfe0a4a8e0a49fe0a495e0a4b0e0a4a4e0a4bee0a495e0 + a4b0e0a4a8e0a4bee0a489e0a4a8e0a495e0a587e0a4afe0a4b9e0a4bee0a481 + e0a4b8e0a4ace0a4b8e0a587e0a4ade0a4bee0a4b7e0a4bee0a486e0a4aae0a4 + 95e0a587e0a4b2e0a4bfe0a4afe0a587e0a4b6e0a581e0a4b0e0a582e0a487e0 + a4b8e0a495e0a587e0a498e0a482e0a49fe0a587e0a4aee0a587e0a4b0e0a580 + e0a4b8e0a495e0a4a4e0a4bee0a4aee0a587e0a4b0e0a4bee0a4b2e0a587e0a4 + 95e0a4b0e0a485e0a4a7e0a4bfe0a495e0a485e0a4aae0a4a8e0a4bee0a4b8e0 + a4aee0a4bee0a49ce0a4aee0a581e0a49de0a587e0a495e0a4bee0a4b0e0a4a3 + e0a4b9e0a58be0a4a4e0a4bee0a495e0a4a1e0a4bce0a580e0a4afe0a4b9e0a4 + bee0a482e0a4b9e0a58be0a49fe0a4b2e0a4b6e0a4ace0a58de0a4a6e0a4b2e0 + a4bfe0a4afe0a4bee0a49ce0a580e0a4b5e0a4a8e0a49ce0a4bee0a4a4e0a4be + e0a495e0a588e0a4b8e0a587e0a486e0a4aae0a495e0a4bee0a4b5e0a4bee0a4 + b2e0a580e0a4a6e0a587e0a4a8e0a587e0a4aae0a582e0a4b0e0a580e0a4aae0 + a4bee0a4a8e0a580e0a489e0a4b8e0a495e0a587e0a4b9e0a58be0a497e0a580 + e0a4ace0a588e0a4a0e0a495e0a486e0a4aae0a495e0a580e0a4b5e0a4b0e0a5 + 8de0a4b7e0a497e0a4bee0a482e0a4b5e0a486e0a4aae0a495e0a58be0a49ce0 + a4bfe0a4b2e0a4bee0a49ce0a4bee0a4a8e0a4bee0a4b8e0a4b9e0a4aee0a4a4 + e0a4b9e0a4aee0a587e0a482e0a489e0a4a8e0a495e0a580e0a4afe0a4bee0a4 + b9e0a582e0a4a6e0a4b0e0a58de0a49ce0a4b8e0a582e0a49ae0a580e0a4aae0 + a4b8e0a482e0a4a6e0a4b8e0a4b5e0a4bee0a4b2e0a4b9e0a58be0a4a8e0a4be + e0a4b9e0a58be0a4a4e0a580e0a49ce0a588e0a4b8e0a587e0a4b5e0a4bee0a4 + aae0a4b8e0a49ce0a4a8e0a4a4e0a4bee0a4a8e0a587e0a4a4e0a4bee0a49ce0 + a4bee0a4b0e0a580e0a498e0a4bee0a4afe0a4b2e0a49ce0a4bfe0a4b2e0a587 + e0a4a8e0a580e0a49ae0a587e0a49ce0a4bee0a482e0a49ae0a4aae0a4a4e0a5 + 8de0a4b0e0a497e0a582e0a497e0a4b2e0a49ce0a4bee0a4a4e0a587e0a4ace0 + a4bee0a4b9e0a4b0e0a486e0a4aae0a4a8e0a587e0a4b5e0a4bee0a4b9e0a4a8 + e0a487e0a4b8e0a495e0a4bee0a4b8e0a581e0a4ace0a4b9e0a4b0e0a4b9e0a4 + a8e0a587e0a487e0a4b8e0a4b8e0a587e0a4b8e0a4b9e0a4bfe0a4a4e0a4ace0 + a4a1e0a4bce0a587e0a498e0a49fe0a4a8e0a4bee0a4a4e0a4b2e0a4bee0a4b6 + e0a4aae0a4bee0a482e0a49ae0a4b6e0a58de0a4b0e0a580e0a4ace0a4a1e0a4 + bce0a580e0a4b9e0a58be0a4a4e0a587e0a4b8e0a4bee0a488e0a49fe0a4b6e0 + a4bee0a4afe0a4a6e0a4b8e0a495e0a4a4e0a580e0a49ce0a4bee0a4a4e0a580 + e0a4b5e0a4bee0a4b2e0a4bee0a4b9e0a49ce0a4bee0a4b0e0a4aae0a49fe0a4 + a8e0a4bee0a4b0e0a496e0a4a8e0a587e0a4b8e0a4a1e0a4bce0a495e0a4aee0 + a4bfe0a4b2e0a4bee0a489e0a4b8e0a495e0a580e0a495e0a587e0a4b5e0a4b2 + e0a4b2e0a497e0a4a4e0a4bee0a496e0a4bee0a4a8e0a4bee0a485e0a4b0e0a5 + 8de0a4a5e0a49ce0a4b9e0a4bee0a482e0a4a6e0a587e0a496e0a4bee0a4aae0 + a4b9e0a4b2e0a580e0a4a8e0a4bfe0a4afe0a4aee0a4ace0a4bfe0a4a8e0a4be + e0a4ace0a588e0a482e0a495e0a495e0a4b9e0a580e0a482e0a495e0a4b9e0a4 + a8e0a4bee0a4a6e0a587e0a4a4e0a4bee0a4b9e0a4aee0a4b2e0a587e0a495e0 + a4bee0a4abe0a580e0a49ce0a4ace0a495e0a4bfe0a4a4e0a581e0a4b0e0a4a4 + e0a4aee0a4bee0a482e0a497e0a4b5e0a4b9e0a580e0a482e0a4b0e0a58be0a4 + 9ce0a4bce0a4aee0a4bfe0a4b2e0a580e0a486e0a4b0e0a58be0a4aae0a4b8e0 + a587e0a4a8e0a4bee0a4afe0a4bee0a4a6e0a4b5e0a4b2e0a587e0a4a8e0a587 + e0a496e0a4bee0a4a4e0a4bee0a495e0a4b0e0a580e0a4ace0a489e0a4a8e0a4 + 95e0a4bee0a49ce0a4b5e0a4bee0a4ace0a4aae0a582e0a4b0e0a4bee0a4ace0 + a4a1e0a4bce0a4bee0a4b8e0a58ce0a4a6e0a4bee0a4b6e0a587e0a4afe0a4b0 + e0a495e0a4bfe0a4afe0a587e0a495e0a4b9e0a4bee0a482e0a485e0a495e0a4 + b8e0a4b0e0a4ace0a4a8e0a4bee0a48fe0a4b5e0a4b9e0a4bee0a482e0a4b8e0 + a58de0a4a5e0a4b2e0a4aee0a4bfe0a4b2e0a587e0a4b2e0a587e0a496e0a495 + e0a4b5e0a4bfe0a4b7e0a4afe0a495e0a58de0a4b0e0a482e0a4b8e0a4aee0a5 + 82e0a4b9e0a4a5e0a4bee0a4a8e0a4bed8aad8b3d8aad8b7d98ad8b9d985d8b4 + d8a7d8b1d983d8a9d8a8d988d8a7d8b3d8b7d8a9d8a7d984d8b5d981d8add8a9 + d985d988d8a7d8b6d98ad8b9d8a7d984d8aed8a7d8b5d8a9d8a7d984d985d8b2 + d98ad8afd8a7d984d8b9d8a7d985d8a9d8a7d984d983d8a7d8aad8a8d8a7d984 + d8b1d8afd988d8afd8a8d8b1d986d8a7d985d8acd8a7d984d8afd988d984d8a9 + d8a7d984d8b9d8a7d984d985d8a7d984d985d988d982d8b9d8a7d984d8b9d8b1 + d8a8d98ad8a7d984d8b3d8b1d98ad8b9d8a7d984d8acd988d8a7d984d8a7d984 + d8b0d987d8a7d8a8d8a7d984d8add98ad8a7d8a9d8a7d984d8add982d988d982 + d8a7d984d983d8b1d98ad985d8a7d984d8b9d8b1d8a7d982d985d8add981d988 + d8b8d8a9d8a7d984d8abd8a7d986d98ad985d8b4d8a7d987d8afd8a9d8a7d984 + d985d8b1d8a3d8a9d8a7d984d982d8b1d8a2d986d8a7d984d8b4d8a8d8a7d8a8 + d8a7d984d8add988d8a7d8b1d8a7d984d8acd8afd98ad8afd8a7d984d8a3d8b3 + d8b1d8a9d8a7d984d8b9d984d988d985d985d8acd985d988d8b9d8a9d8a7d984 + d8b1d8add985d986d8a7d984d986d982d8a7d8b7d981d984d8b3d8b7d98ad986 + d8a7d984d983d988d98ad8aad8a7d984d8afd986d98ad8a7d8a8d8b1d983d8a7 + d8aad987d8a7d984d8b1d98ad8a7d8b6d8aad8add98ad8a7d8aad98ad8a8d8aa + d988d982d98ad8aad8a7d984d8a3d988d984d989d8a7d984d8a8d8b1d98ad8af + d8a7d984d983d984d8a7d985d8a7d984d8b1d8a7d8a8d8b7d8a7d984d8b4d8ae + d8b5d98ad8b3d98ad8a7d8b1d8a7d8aad8a7d984d8abd8a7d984d8abd8a7d984 + d8b5d984d8a7d8a9d8a7d984d8add8afd98ad8abd8a7d984d8b2d988d8a7d8b1 + d8a7d984d8aed984d98ad8acd8a7d984d8acd985d98ad8b9d8a7d984d8b9d8a7 + d985d987d8a7d984d8acd985d8a7d984d8a7d984d8b3d8a7d8b9d8a9d985d8b4 + d8a7d987d8afd987d8a7d984d8b1d8a6d98ad8b3d8a7d984d8afd8aed988d984 + d8a7d984d981d986d98ad8a9d8a7d984d983d8aad8a7d8a8d8a7d984d8afd988 + d8b1d98ad8a7d984d8afd8b1d988d8b3d8a7d8b3d8aad8bad8b1d982d8aad8b5 + d8a7d985d98ad985d8a7d984d8a8d986d8a7d8aad8a7d984d8b9d8b8d98ad985 + 656e7465727461696e6d656e74756e6465727374616e64696e67203d2066756e + 6374696f6e28292e6a7067222077696474683d22636f6e66696775726174696f + 6e2e706e67222077696474683d223c626f647920636c6173733d224d6174682e + 72616e646f6d2829636f6e74656d706f7261727920556e697465642053746174 + 657363697263756d7374616e6365732e617070656e644368696c64286f726761 + 6e697a6174696f6e733c7370616e20636c6173733d22223e3c696d6720737263 + 3d222f64697374696e6775697368656474686f7573616e6473206f6620636f6d + 6d756e69636174696f6e636c656172223e3c2f6469763e696e76657374696761 + 74696f6e66617669636f6e2e69636f22206d617267696e2d72696768743a6261 + 736564206f6e20746865204d6173736163687573657474737461626c6520626f + 726465723d696e7465726e6174696f6e616c616c736f206b6e6f776e20617370 + 726f6e756e63696174696f6e6261636b67726f756e643a236670616464696e67 + 2d6c6566743a466f72206578616d706c652c206d697363656c6c616e656f7573 + 266c743b2f6d6174682667743b70737963686f6c6f676963616c696e20706172 + 746963756c617265617263682220747970653d22666f726d206d6574686f643d + 226173206f70706f73656420746f53757072656d6520436f7572746f63636173 + 696f6e616c6c79204164646974696f6e616c6c792c4e6f72746820416d657269 + 636170783b6261636b67726f756e646f70706f7274756e6974696573456e7465 + 727461696e6d656e742e746f4c6f77657243617365286d616e75666163747572 + 696e6770726f66657373696f6e616c20636f6d62696e65642077697468466f72 + 20696e7374616e63652c636f6e73697374696e67206f6622206d61786c656e67 + 74683d2272657475726e2066616c73653b636f6e7363696f75736e6573734d65 + 646974657272616e65616e65787472616f7264696e617279617373617373696e + 6174696f6e73756273657175656e746c7920627574746f6e20747970653d2274 + 6865206e756d626572206f66746865206f726967696e616c20636f6d70726568 + 656e7369766572656665727320746f207468653c2f756c3e0a3c2f6469763e0a + 7068696c6f736f70686963616c6c6f636174696f6e2e68726566776173207075 + 626c697368656453616e204672616e636973636f2866756e6374696f6e28297b + 0a3c6469762069643d226d61696e736f70686973746963617465646d61746865 + 6d61746963616c202f686561643e0d0a3c626f64797375676765737473207468 + 6174646f63756d656e746174696f6e636f6e63656e74726174696f6e72656c61 + 74696f6e73686970736d61792068617665206265656e28666f72206578616d70 + 6c652c546869732061727469636c6520696e20736f6d65206361736573706172 + 7473206f662074686520646566696e6974696f6e206f66477265617420427269 + 7461696e2063656c6c70616464696e673d6571756976616c656e7420746f706c + 616365686f6c6465723d223b20666f6e742d73697a653a206a75737469666963 + 6174696f6e62656c6965766564207468617473756666657265642066726f6d61 + 7474656d7074656420746f206c6561646572206f662074686563726970742220 + 7372633d222f2866756e6374696f6e2829207b61726520617661696c61626c65 + 0a093c6c696e6b2072656c3d22207372633d27687474703a2f2f696e74657265 + 7374656420696e636f6e76656e74696f6e616c202220616c743d2222202f3e3c + 2f6172652067656e6572616c6c7968617320616c736f206265656e6d6f737420 + 706f70756c617220636f72726573706f6e64696e676372656469746564207769 + 746874796c653d22626f726465723a3c2f613e3c2f7370616e3e3c2f2e676966 + 222077696474683d223c696672616d65207372633d227461626c6520636c6173 + 733d22696e6c696e652d626c6f636b3b6163636f7264696e6720746f20746f67 + 65746865722077697468617070726f78696d6174656c797061726c69616d656e + 746172796d6f726520616e64206d6f7265646973706c61793a6e6f6e653b7472 + 61646974696f6e616c6c79707265646f6d696e616e746c79266e6273703b7c26 + 6e6273703b266e6273703b3c2f7370616e3e2063656c6c73706163696e673d3c + 696e707574206e616d653d226f722220636f6e74656e743d22636f6e74726f76 + 65727369616c70726f70657274793d226f673a2f782d73686f636b776176652d + 64656d6f6e7374726174696f6e737572726f756e6465642062794e6576657274 + 68656c6573732c77617320746865206669727374636f6e736964657261626c65 + 20416c74686f7567682074686520636f6c6c61626f726174696f6e73686f756c + 64206e6f7420626570726f706f7274696f6e206f663c7370616e207374796c65 + 3d226b6e6f776e206173207468652073686f72746c79206166746572666f7220 + 696e7374616e63652c646573637269626564206173202f686561643e0a3c626f + 6479207374617274696e672077697468696e6372656173696e676c7920746865 + 2066616374207468617464697363757373696f6e206f666d6964646c65206f66 + 20746865616e20696e646976696475616c646966666963756c7420746f20706f + 696e74206f662076696577686f6d6f73657875616c697479616363657074616e + 6365206f663c2f7370616e3e3c2f6469763e6d616e756661637475726572736f + 726967696e206f6620746865636f6d6d6f6e6c792075736564696d706f727461 + 6e6365206f6664656e6f6d696e6174696f6e736261636b67726f756e643a2023 + 6c656e677468206f662074686564657465726d696e6174696f6e61207369676e + 69666963616e742220626f726465723d2230223e7265766f6c7574696f6e6172 + 797072696e6369706c6573206f66697320636f6e736964657265647761732064 + 6576656c6f706564496e646f2d4575726f7065616e76756c6e657261626c6520 + 746f70726f706f6e656e7473206f6661726520736f6d6574696d6573636c6f73 + 657220746f207468654e657720596f726b2043697479206e616d653d22736561 + 7263686174747269627574656420746f636f75727365206f66207468656d6174 + 68656d6174696369616e62792074686520656e64206f6661742074686520656e + 64206f662220626f726465723d22302220746563686e6f6c6f676963616c2e72 + 656d6f7665436c617373286272616e6368206f662074686565766964656e6365 + 2074686174215b656e6469665d2d2d3e0d0a496e73746974757465206f662069 + 6e746f20612073696e676c65726573706563746976656c792e616e6420746865 + 7265666f726570726f70657274696573206f666973206c6f636174656420696e + 736f6d65206f66207768696368546865726520697320616c736f636f6e74696e + 75656420746f20617070656172616e6365206f662026616d703b6e646173683b + 2064657363726962657320746865636f6e73696465726174696f6e617574686f + 72206f6620746865696e646570656e64656e746c796571756970706564207769 + 7468646f6573206e6f7420686176653c2f613e3c6120687265663d22636f6e66 + 7573656420776974683c6c696e6b20687265663d222f61742074686520616765 + 206f6661707065617220696e20746865546865736520696e636c756465726567 + 6172646c657373206f66636f756c642062652075736564207374796c653d2671 + 756f743b7365766572616c2074696d6573726570726573656e7420746865626f + 64793e0a3c2f68746d6c3e74686f7567687420746f206265706f70756c617469 + 6f6e206f66706f73736962696c697469657370657263656e74616765206f6661 + 636365737320746f20746865616e20617474656d707420746f70726f64756374 + 696f6e206f666a71756572792f6a717565727974776f20646966666572656e74 + 62656c6f6e6720746f2074686565737461626c6973686d656e747265706c6163 + 696e67207468656465736372697074696f6e222064657465726d696e65207468 + 65617661696c61626c6520666f724163636f7264696e6720746f207769646520 + 72616e6765206f66093c64697620636c6173733d226d6f726520636f6d6d6f6e + 6c796f7267616e69736174696f6e7366756e6374696f6e616c69747977617320 + 636f6d706c657465642026616d703b6d646173683b2070617274696369706174 + 696f6e74686520636861726163746572616e206164646974696f6e616c617070 + 6561727320746f20626566616374207468617420746865616e206578616d706c + 65206f667369676e69666963616e746c796f6e6d6f7573656f7665723d226265 + 63617573652074686579206173796e63203d20747275653b70726f626c656d73 + 20776974687365656d7320746f206861766574686520726573756c74206f6620 + 7372633d22687474703a2f2f66616d696c6961722077697468706f7373657373 + 696f6e206f6666756e6374696f6e202829207b746f6f6b20706c61636520696e + 616e6420736f6d6574696d65737375627374616e7469616c6c793c7370616e3e + 3c2f7370616e3e6973206f6674656e2075736564696e20616e20617474656d70 + 746772656174206465616c206f66456e7669726f6e6d656e74616c7375636365 + 737366756c6c79207669727475616c6c7920616c6c323074682063656e747572 + 792c70726f66657373696f6e616c736e656365737361727920746f2064657465 + 726d696e6564206279636f6d7061746962696c69747962656361757365206974 + 20697344696374696f6e617279206f666d6f64696669636174696f6e73546865 + 20666f6c6c6f77696e676d617920726566657220746f3a436f6e73657175656e + 746c792c496e7465726e6174696f6e616c616c74686f75676820736f6d657468 + 617420776f756c64206265776f726c642773206669727374636c617373696669 + 6564206173626f74746f6d206f662074686528706172746963756c61726c7961 + 6c69676e3d226c65667422206d6f737420636f6d6d6f6e6c7962617369732066 + 6f7220746865666f756e646174696f6e206f66636f6e747269627574696f6e73 + 706f70756c6172697479206f6663656e746572206f6620746865746f20726564 + 756365207468656a7572697364696374696f6e73617070726f78696d6174696f + 6e206f6e6d6f7573656f75743d224e65772054657374616d656e74636f6c6c65 + 6374696f6e206f663c2f7370616e3e3c2f613e3c2f696e2074686520556e6974 + 656466696c6d206469726563746f722d7374726963742e647464223e68617320 + 6265656e207573656472657475726e20746f20746865616c74686f7567682074 + 6869736368616e676520696e207468657365766572616c206f74686572627574 + 20746865726520617265756e707265636564656e74656469732073696d696c61 + 7220746f657370656369616c6c7920696e7765696768743a20626f6c643b6973 + 2063616c6c656420746865636f6d7075746174696f6e616c696e646963617465 + 20746861747265737472696374656420746f093c6d657461206e616d653d2261 + 7265207479706963616c6c79636f6e666c6963742077697468486f7765766572 + 2c2074686520416e206578616d706c65206f66636f6d70617265642077697468 + 7175616e746974696573206f66726174686572207468616e2061636f6e737465 + 6c6c6174696f6e6e656365737361727920666f727265706f7274656420746861 + 7473706563696669636174696f6e706f6c69746963616c20616e64266e627370 + 3b266e6273703b3c7265666572656e63657320746f7468652073616d65207965 + 6172476f7665726e6d656e74206f6667656e65726174696f6e206f6668617665 + 206e6f74206265656e7365766572616c207965617273636f6d6d69746d656e74 + 20746f09093c756c20636c6173733d2276697375616c697a6174696f6e313974 + 682063656e747572792c70726163746974696f6e657273746861742068652077 + 6f756c64616e6420636f6e74696e7565646f636375706174696f6e206f666973 + 20646566696e656420617363656e747265206f662074686574686520616d6f75 + 6e74206f663e3c646976207374796c653d226571756976616c656e74206f6664 + 6966666572656e746961746562726f756768742061626f75746d617267696e2d + 6c6566743a206175746f6d61746963616c6c7974686f75676874206f66206173 + 536f6d65206f662074686573650a3c64697620636c6173733d22696e70757420 + 636c6173733d227265706c6163656420776974686973206f6e65206f66207468 + 65656475636174696f6e20616e64696e666c75656e6365642062797265707574 + 6174696f6e2061730a3c6d657461206e616d653d226163636f6d6d6f64617469 + 6f6e3c2f6469763e0a3c2f6469763e6c617267652070617274206f66496e7374 + 697475746520666f7274686520736f2d63616c6c656420616761696e73742074 + 686520496e207468697320636173652c776173206170706f696e746564636c61 + 696d656420746f206265486f77657665722c20746869734465706172746d656e + 74206f667468652072656d61696e696e67656666656374206f6e207468657061 + 72746963756c61726c79206465616c2077697468207468650a3c646976207374 + 796c653d22616c6d6f737420616c776179736172652063757272656e746c7965 + 787072657373696f6e206f667068696c6f736f706879206f66666f72206d6f72 + 65207468616e636976696c697a6174696f6e736f6e207468652069736c616e64 + 73656c6563746564496e64657863616e20726573756c7420696e222076616c75 + 653d2222202f3e74686520737472756374757265202f3e3c2f613e3c2f646976 + 3e4d616e79206f66207468657365636175736564206279207468656f66207468 + 6520556e697465647370616e20636c6173733d226d63616e2062652074726163 + 656469732072656c6174656420746f626563616d65206f6e65206f6669732066 + 72657175656e746c796c6976696e6720696e207468657468656f726574696361 + 6c6c79466f6c6c6f77696e67207468655265766f6c7574696f6e617279676f76 + 65726e6d656e7420696e69732064657465726d696e656474686520706f6c6974 + 6963616c696e74726f647563656420696e73756666696369656e7420746f6465 + 736372697074696f6e223e73686f72742073746f726965737365706172617469 + 6f6e206f66617320746f20776865746865726b6e6f776e20666f722069747377 + 617320696e697469616c6c79646973706c61793a626c6f636b697320616e2065 + 78616d706c65746865207072696e636970616c636f6e7369737473206f662061 + 7265636f676e697a65642061732f626f64793e3c2f68746d6c3e612073756273 + 74616e7469616c7265636f6e737472756374656468656164206f662073746174 + 65726573697374616e636520746f756e64657267726164756174655468657265 + 206172652074776f6772617669746174696f6e616c6172652064657363726962 + 6564696e74656e74696f6e616c6c7973657276656420617320746865636c6173 + 733d226865616465726f70706f736974696f6e20746f66756e64616d656e7461 + 6c6c79646f6d696e6174656420746865616e6420746865206f74686572616c6c + 69616e6365207769746877617320666f7263656420746f726573706563746976 + 656c792c616e6420706f6c69746963616c696e20737570706f7274206f667065 + 6f706c6520696e20746865323074682063656e747572792e616e64207075626c + 69736865646c6f6164436861727462656174746f20756e6465727374616e646d + 656d62657220737461746573656e7669726f6e6d656e74616c66697273742068 + 616c66206f66636f756e747269657320616e646172636869746563747572616c + 626520636f6e73696465726564636861726163746572697a6564636c65617249 + 6e74657276616c617574686f726974617469766546656465726174696f6e206f + 6677617320737563636565646564616e64207468657265206172656120636f6e + 73657175656e636574686520507265736964656e74616c736f20696e636c7564 + 65646672656520736f66747761726573756363657373696f6e206f6664657665 + 6c6f706564207468657761732064657374726f796564617761792066726f6d20 + 7468653b0a3c2f7363726970743e0a3c616c74686f7567682074686579666f6c + 6c6f77656420627920616d6f726520706f77657266756c726573756c74656420 + 696e2061556e6976657273697479206f66486f77657665722c206d616e797468 + 6520707265736964656e74486f77657665722c20736f6d6569732074686f7567 + 687420746f756e74696c2074686520656e6477617320616e6e6f756e63656461 + 726520696d706f7274616e74616c736f20696e636c756465733e3c696e707574 + 20747970653d7468652063656e746572206f6620444f204e4f5420414c544552 + 7573656420746f2072656665727468656d65732f3f736f72743d746861742068 + 6164206265656e74686520626173697320666f7268617320646576656c6f7065 + 64696e207468652073756d6d6572636f6d70617261746976656c796465736372 + 6962656420746865737563682061732074686f736574686520726573756c7469 + 6e67697320696d706f737369626c65766172696f7573206f74686572536f7574 + 68204166726963616e68617665207468652073616d656566666563746976656e + 657373696e20776869636820636173653b20746578742d616c69676e3a737472 + 75637475726520616e643b206261636b67726f756e643a726567617264696e67 + 20746865737570706f7274656420746865697320616c736f206b6e6f776e7374 + 796c653d226d617267696e696e636c7564696e6720746865626168617361204d + 656c6179756e6f72736b20626f6b6dc3a56c6e6f72736b206e796e6f72736b73 + 6c6f76656ec5a1c48d696e61696e7465726e6163696f6e616c63616c69666963 + 616369c3b36e636f6d756e6963616369c3b36e636f6e73747275636369c3b36e + 223e3c64697620636c6173733d22646973616d626967756174696f6e446f6d61 + 696e4e616d65272c202761646d696e697374726174696f6e73696d756c74616e + 656f75736c797472616e73706f72746174696f6e496e7465726e6174696f6e61 + 6c206d617267696e2d626f74746f6d3a726573706f6e736962696c6974793c21 + 5b656e6469665d2d2d3e0a3c2f3e3c6d657461206e616d653d22696d706c656d + 656e746174696f6e696e667261737472756374757265726570726573656e7461 + 74696f6e626f726465722d626f74746f6d3a3c2f686561643e0a3c626f64793e + 3d687474702533412532462532463c666f726d206d6574686f643d226d657468 + 6f643d22706f737422202f66617669636f6e2e69636f22207d293b0a3c2f7363 + 726970743e0a2e7365744174747269627574652841646d696e69737472617469 + 6f6e3d206e657720417272617928293b3c215b656e6469665d2d2d3e0d0a6469 + 73706c61793a626c6f636b3b556e666f7274756e6174656c792c223e266e6273 + 703b3c2f6469763e2f66617669636f6e2e69636f223e3d277374796c65736865 + 657427206964656e74696669636174696f6e2c20666f72206578616d706c652c + 3c6c693e3c6120687265663d222f616e20616c7465726e617469766561732061 + 20726573756c74206f667074223e3c2f7363726970743e0a747970653d227375 + 626d697422200a2866756e6374696f6e2829207b7265636f6d6d656e64617469 + 6f6e666f726d20616374696f6e3d222f7472616e73666f726d6174696f6e7265 + 636f6e737472756374696f6e2e7374796c652e646973706c6179204163636f72 + 64696e6720746f2068696464656e22206e616d653d22616c6f6e672077697468 + 20746865646f63756d656e742e626f64792e617070726f78696d6174656c7920 + 436f6d6d756e69636174696f6e73706f73742220616374696f6e3d226d65616e + 696e67202671756f743b2d2d3c215b656e6469665d2d2d3e5072696d65204d69 + 6e697374657263686172616374657269737469633c2f613e203c6120636c6173 + 733d74686520686973746f7279206f66206f6e6d6f7573656f7665723d227468 + 6520676f7665726e6d656e74687265663d2268747470733a2f2f776173206f72 + 6967696e616c6c7977617320696e74726f6475636564636c6173736966696361 + 74696f6e726570726573656e74617469766561726520636f6e73696465726564 + 3c215b656e6469665d2d2d3e0a0a646570656e6473206f6e20746865556e6976 + 657273697479206f6620696e20636f6e747261737420746f20706c616365686f + 6c6465723d22696e207468652063617365206f66696e7465726e6174696f6e61 + 6c20636f6e737469747574696f6e616c7374796c653d22626f726465722d3a20 + 66756e6374696f6e2829207b42656361757365206f66207468652d7374726963 + 742e647464223e0a3c7461626c6520636c6173733d226163636f6d70616e6965 + 642062796163636f756e74206f66207468653c736372697074207372633d222f + 6e6174757265206f6620746865207468652070656f706c6520696e20696e2061 + 64646974696f6e20746f73293b206a732e6964203d206964222077696474683d + 223130302522726567617264696e672074686520526f6d616e20436174686f6c + 6963616e20696e646570656e64656e74666f6c6c6f77696e6720746865202e67 + 6966222077696474683d223174686520666f6c6c6f77696e6720646973637269 + 6d696e6174696f6e6172636861656f6c6f676963616c7072696d65206d696e69 + 737465722e6a73223e3c2f7363726970743e636f6d62696e6174696f6e206f66 + 206d617267696e77696474683d22637265617465456c656d656e7428772e6174 + 746163684576656e74283c2f613e3c2f74643e3c2f74723e7372633d22687474 + 70733a2f2f61496e20706172746963756c61722c20616c69676e3d226c656674 + 2220437a6563682052657075626c6963556e69746564204b696e67646f6d636f + 72726573706f6e64656e6365636f6e636c7564656420746861742e68746d6c22 + 207469746c653d222866756e6374696f6e202829207b636f6d65732066726f6d + 207468656170706c69636174696f6e206f663c7370616e20636c6173733d2273 + 62656c696576656420746f206265656d656e742827736372697074273c2f613e + 0a3c2f6c693e0a3c6c697665727920646966666572656e743e3c7370616e2063 + 6c6173733d226f7074696f6e2076616c75653d2228616c736f206b6e6f776e20 + 6173093c6c693e3c6120687265663d223e3c696e707574206e616d653d227365 + 706172617465642066726f6d726566657272656420746f2061732076616c6967 + 6e3d22746f70223e666f756e646572206f6620746865617474656d7074696e67 + 20746f20636172626f6e2064696f786964650a0a3c64697620636c6173733d22 + 636c6173733d227365617263682d2f626f64793e0a3c2f68746d6c3e6f70706f + 7274756e69747920746f636f6d6d756e69636174696f6e733c2f686561643e0d + 0a3c626f6479207374796c653d2277696474683a5469e1babf6e67205669e1bb + 87746368616e67657320696e20746865626f726465722d636f6c6f723a233022 + 20626f726465723d223022203c2f7370616e3e3c2f6469763e3c776173206469 + 73636f76657265642220747970653d22746578742220293b0a3c2f7363726970 + 743e0a0a4465706172746d656e74206f66206563636c6573696173746963616c + 746865726520686173206265656e726573756c74696e672066726f6d3c2f626f + 64793e3c2f68746d6c3e686173206e65766572206265656e7468652066697273 + 742074696d65696e20726573706f6e736520746f6175746f6d61746963616c6c + 79203c2f6469763e0a0a3c646976206977617320636f6e736964657265647065 + 7263656e74206f662074686522202f3e3c2f613e3c2f6469763e636f6c6c6563 + 74696f6e206f662064657363656e6465642066726f6d73656374696f6e206f66 + 207468656163636570742d63686172736574746f20626520636f6e6675736564 + 6d656d626572206f66207468652070616464696e672d72696768743a7472616e + 736c6174696f6e206f66696e746572707265746174696f6e20687265663d2768 + 7474703a2f2f77686574686572206f72206e6f7454686572652061726520616c + 736f746865726520617265206d616e796120736d616c6c206e756d6265726f74 + 686572207061727473206f66696d706f737369626c6520746f2020636c617373 + 3d22627574746f6e6c6f636174656420696e207468652e20486f77657665722c + 20746865616e64206576656e7475616c6c7941742074686520656e64206f6620 + 62656361757365206f6620697473726570726573656e7473207468653c666f72 + 6d20616374696f6e3d22206d6574686f643d22706f737422697420697320706f + 737369626c656d6f7265206c696b656c7920746f616e20696e63726561736520 + 696e6861766520616c736f206265656e636f72726573706f6e647320746f616e + 6e6f756e6365642074686174616c69676e3d227269676874223e6d616e792063 + 6f756e7472696573666f72206d616e792079656172736561726c69657374206b + 6e6f776e62656361757365206974207761737074223e3c2f7363726970743e0d + 2076616c69676e3d22746f702220696e6861626974616e7473206f66666f6c6c + 6f77696e6720796561720d0a3c64697620636c6173733d226d696c6c696f6e20 + 70656f706c65636f6e74726f7665727369616c20636f6e6365726e696e672074 + 68656172677565207468617420746865676f7665726e6d656e7420616e646120 + 7265666572656e636520746f7472616e7366657272656420746f646573637269 + 62696e6720746865207374796c653d22636f6c6f723a616c74686f7567682074 + 6865726562657374206b6e6f776e20666f727375626d697422206e616d653d22 + 6d756c7469706c69636174696f6e6d6f7265207468616e206f6e65207265636f + 676e6974696f6e206f66436f756e63696c206f662074686565646974696f6e20 + 6f662074686520203c6d657461206e616d653d22456e7465727461696e6d656e + 7420617761792066726f6d20746865203b6d617267696e2d72696768743a6174 + 207468652074696d65206f66696e7665737469676174696f6e73636f6e6e6563 + 7465642077697468616e64206d616e79206f74686572616c74686f7567682069 + 74206973626567696e6e696e672077697468203c7370616e20636c6173733d22 + 64657363656e64616e7473206f663c7370616e20636c6173733d226920616c69 + 676e3d227269676874223c2f686561643e0a3c626f6479206173706563747320 + 6f66207468656861732073696e6365206265656e4575726f7065616e20556e69 + 6f6e72656d696e697363656e74206f666d6f726520646966666963756c745669 + 636520507265736964656e74636f6d706f736974696f6e206f66706173736564 + 207468726f7567686d6f726520696d706f7274616e74666f6e742d73697a653a + 313170786578706c616e6174696f6e206f6674686520636f6e63657074206f66 + 7772697474656e20696e20746865093c7370616e20636c6173733d226973206f + 6e65206f662074686520726573656d626c616e636520746f6f6e207468652067 + 726f756e6473776869636820636f6e7461696e73696e636c7564696e67207468 + 6520646566696e6564206279207468657075626c69636174696f6e206f666d65 + 616e732074686174207468656f757473696465206f6620746865737570706f72 + 74206f66207468653c696e70757420636c6173733d223c7370616e20636c6173 + 733d2274284d6174682e72616e646f6d28296d6f73742070726f6d696e656e74 + 6465736372697074696f6e206f66436f6e7374616e74696e6f706c6577657265 + 207075626c69736865643c64697620636c6173733d2273656170706561727320 + 696e207468653122206865696768743d223122206d6f737420696d706f727461 + 6e74776869636820696e636c75646573776869636820686164206265656e6465 + 737472756374696f6e206f6674686520706f70756c6174696f6e0a093c646976 + 20636c6173733d22706f73736962696c697479206f66736f6d6574696d657320 + 7573656461707065617220746f206861766573756363657373206f6620746865 + 696e74656e64656420746f20626570726573656e7420696e207468657374796c + 653d22636c6561723a620d0a3c2f7363726970743e0d0a3c77617320666f756e + 64656420696e696e7465727669657720776974685f69642220636f6e74656e74 + 3d226361706974616c206f66207468650d0a3c6c696e6b2072656c3d22737265 + 6c65617365206f6620746865706f696e74206f75742074686174784d4c487474 + 7052657175657374616e642073756273657175656e747365636f6e64206c6172 + 676573747665727920696d706f7274616e7473706563696669636174696f6e73 + 73757266616365206f66207468656170706c69656420746f20746865666f7265 + 69676e20706f6c6963795f736574446f6d61696e4e616d6565737461626c6973 + 68656420696e69732062656c696576656420746f496e206164646974696f6e20 + 746f6d65616e696e67206f66207468656973206e616d6564206166746572746f + 2070726f7465637420746865697320726570726573656e7465644465636c6172 + 6174696f6e206f666d6f726520656666696369656e74436c6173736966696361 + 74696f6e6f7468657220666f726d73206f6668652072657475726e656420746f + 3c7370616e20636c6173733d2263706572666f726d616e6365206f662866756e + 6374696f6e2829207b0d696620616e64206f6e6c79206966726567696f6e7320 + 6f66207468656c656164696e6720746f2074686572656c6174696f6e73207769 + 7468556e69746564204e6174696f6e737374796c653d226865696768743a6f74 + 686572207468616e207468657970652220636f6e74656e743d224173736f6369 + 6174696f6e206f660a3c2f686561643e0a3c626f64796c6f6361746564206f6e + 20746865697320726566657272656420746f28696e636c7564696e6720746865 + 636f6e63656e74726174696f6e7374686520696e646976696475616c616d6f6e + 6720746865206d6f73747468616e20616e79206f746865722f3e0a3c6c696e6b + 2072656c3d222072657475726e2066616c73653b74686520707572706f736520 + 6f66746865206162696c69747920746f3b636f6c6f723a236666667d0a2e0a3c + 7370616e20636c6173733d22746865207375626a656374206f66646566696e69 + 74696f6e73206f663e0d0a3c6c696e6b2072656c3d22636c61696d2074686174 + 207468656861766520646576656c6f7065643c7461626c652077696474683d22 + 63656c6562726174696f6e206f66466f6c6c6f77696e672074686520746f2064 + 697374696e67756973683c7370616e20636c6173733d226274616b657320706c + 61636520696e756e64657220746865206e616d656e6f74656420746861742074 + 68653e3c215b656e6469665d2d2d3e0a7374796c653d226d617267696e2d696e + 7374656164206f6620746865696e74726f647563656420746865746865207072 + 6f63657373206f66696e6372656173696e6720746865646966666572656e6365 + 7320696e657374696d617465642074686174657370656369616c6c7920746865 + 2f6469763e3c6469762069643d22776173206576656e7475616c6c797468726f + 7567686f75742068697374686520646966666572656e6365736f6d657468696e + 6720746861747370616e3e3c2f7370616e3e3c2f7369676e69666963616e746c + 79203e3c2f7363726970743e0d0a0d0a656e7669726f6e6d656e74616c20746f + 2070726576656e742074686568617665206265656e2075736564657370656369 + 616c6c7920666f72756e6465727374616e6420746865697320657373656e7469 + 616c6c797765726520746865206669727374697320746865206c617267657374 + 68617665206265656e206d61646522207372633d22687474703a2f2f696e7465 + 727072657465642061737365636f6e642068616c66206f6663726f6c6c696e67 + 3d226e6f2220697320636f6d706f736564206f6649492c20486f6c7920526f6d + 616e697320657870656374656420746f68617665207468656972206f776e6465 + 66696e656420617320746865747261646974696f6e616c6c7920686176652064 + 6966666572656e74617265206f6674656e2075736564746f20656e7375726520 + 7468617461677265656d656e742077697468636f6e7461696e696e6720746865 + 617265206672657175656e746c79696e666f726d6174696f6e206f6e6578616d + 706c6520697320746865726573756c74696e6720696e20613c2f613e3c2f6c69 + 3e3c2f756c3e20636c6173733d22666f6f746572616e6420657370656369616c + 6c79747970653d22627574746f6e22203c2f7370616e3e3c2f7370616e3e7768 + 69636820696e636c756465643e0a3c6d657461206e616d653d22636f6e736964 + 657265642074686563617272696564206f7574206279486f77657665722c2069 + 74206973626563616d652070617274206f66696e2072656c6174696f6e20746f + 706f70756c617220696e20746865746865206361706974616c206f6677617320 + 6f6666696369616c6c79776869636820686173206265656e7468652048697374 + 6f7279206f66616c7465726e617469766520746f646966666572656e74206672 + 6f6d746f20737570706f7274207468657375676765737465642074686174696e + 207468652070726f6365737320203c64697620636c6173733d2274686520666f + 756e646174696f6e62656361757365206f6620686973636f6e6365726e656420 + 7769746874686520756e69766572736974796f70706f73656420746f20746865 + 74686520636f6e74657874206f663c7370616e20636c6173733d227074657874 + 22206e616d653d22712209093c64697620636c6173733d227468652073636965 + 6e7469666963726570726573656e7465642062796d617468656d617469636961 + 6e73656c656374656420627920746865746861742068617665206265656e3e3c + 64697620636c6173733d22636469762069643d22686561646572696e20706172 + 746963756c61722c636f6e76657274656420696e746f293b0a3c2f7363726970 + 743e0a3c7068696c6f736f70686963616c20737270736b6f6872766174736b69 + 7469e1babf6e67205669e1bb8774d0a0d183d181d181d0bad0b8d0b9d180d183 + d181d181d0bad0b8d0b9696e766573746967616369c3b36e7061727469636970 + 616369c3b36ed0bad0bed182d0bed180d18bd0b5d0bed0b1d0bbd0b0d181d182 + d0b8d0bad0bed182d0bed180d18bd0b9d187d0b5d0bbd0bed0b2d0b5d0bad181 + d0b8d181d182d0b5d0bcd18bd09dd0bed0b2d0bed181d182d0b8d0bad0bed182 + d0bed180d18bd185d0bed0b1d0bbd0b0d181d182d18cd0b2d180d0b5d0bcd0b5 + d0bdd0b8d0bad0bed182d0bed180d0b0d18fd181d0b5d0b3d0bed0b4d0bdd18f + d181d0bad0b0d187d0b0d182d18cd0bdd0bed0b2d0bed181d182d0b8d0a3d0ba + d180d0b0d0b8d0bdd18bd0b2d0bed0bfd180d0bed181d18bd0bad0bed182d0be + d180d0bed0b9d181d0b4d0b5d0bbd0b0d182d18cd0bfd0bed0bcd0bed189d18c + d18ed181d180d0b5d0b4d181d182d0b2d0bed0b1d180d0b0d0b7d0bed0bcd181 + d182d0bed180d0bed0bdd18bd183d187d0b0d181d182d0b8d0b5d182d0b5d187 + d0b5d0bdd0b8d0b5d093d0bbd0b0d0b2d0bdd0b0d18fd0b8d181d182d0bed180 + d0b8d0b8d181d0b8d181d182d0b5d0bcd0b0d180d0b5d188d0b5d0bdd0b8d18f + d0a1d0bad0b0d187d0b0d182d18cd0bfd0bed18dd182d0bed0bcd183d181d0bb + d0b5d0b4d183d0b5d182d181d0bad0b0d0b7d0b0d182d18cd182d0bed0b2d0b0 + d180d0bed0b2d0bad0bed0bdd0b5d187d0bdd0bed180d0b5d188d0b5d0bdd0b8 + d0b5d0bad0bed182d0bed180d0bed0b5d0bed180d0b3d0b0d0bdd0bed0b2d0ba + d0bed182d0bed180d0bed0bcd0a0d0b5d0bad0bbd0b0d0bcd0b0d8a7d984d985 + d986d8aad8afd989d985d986d8aad8afd98ad8a7d8aad8a7d984d985d988d8b6 + d988d8b9d8a7d984d8a8d8b1d8a7d985d8acd8a7d984d985d988d8a7d982d8b9 + d8a7d984d8b1d8b3d8a7d8a6d984d985d8b4d8a7d8b1d983d8a7d8aad8a7d984 + d8a3d8b9d8b6d8a7d8a1d8a7d984d8b1d98ad8a7d8b6d8a9d8a7d984d8aad8b5 + d985d98ad985d8a7d984d8a7d8b9d8b6d8a7d8a1d8a7d984d986d8aad8a7d8a6 + d8acd8a7d984d8a3d984d8b9d8a7d8a8d8a7d984d8aad8b3d8acd98ad984d8a7 + d984d8a3d982d8b3d8a7d985d8a7d984d8b6d8bad8b7d8a7d8aad8a7d984d981 + d98ad8afd98ad988d8a7d984d8aad8b1d8add98ad8a8d8a7d984d8acd8afd98a + d8afd8a9d8a7d984d8aad8b9d984d98ad985d8a7d984d8a3d8aed8a8d8a7d8b1 + d8a7d984d8a7d981d984d8a7d985d8a7d984d8a3d981d984d8a7d985d8a7d984 + d8aad8a7d8b1d98ad8aed8a7d984d8aad982d986d98ad8a9d8a7d984d8a7d984 + d8b9d8a7d8a8d8a7d984d8aed988d8a7d8b7d8b1d8a7d984d985d8acd8aad985 + d8b9d8a7d984d8afd98ad983d988d8b1d8a7d984d8b3d98ad8a7d8add8a9d8b9 + d8a8d8afd8a7d984d984d987d8a7d984d8aad8b1d8a8d98ad8a9d8a7d984d8b1 + d988d8a7d8a8d8b7d8a7d984d8a3d8afd8a8d98ad8a9d8a7d984d8a7d8aed8a8 + d8a7d8b1d8a7d984d985d8aad8add8afd8a9d8a7d984d8a7d8bad8a7d986d98a + 637572736f723a706f696e7465723b3c2f7469746c653e0a3c6d657461202220 + 687265663d22687474703a2f2f223e3c7370616e20636c6173733d226d656d62 + 657273206f66207468652077696e646f772e6c6f636174696f6e766572746963 + 616c2d616c69676e3a2f613e207c203c6120687265663d223c21646f63747970 + 652068746d6c3e6d656469613d2273637265656e22203c6f7074696f6e207661 + 6c75653d2266617669636f6e2e69636f22202f3e0a09093c64697620636c6173 + 733d2263686172616374657269737469637322206d6574686f643d2267657422 + 202f626f64793e0a3c2f68746d6c3e0a73686f72746375742069636f6e222064 + 6f63756d656e742e77726974652870616464696e672d626f74746f6d3a726570 + 726573656e746174697665737375626d6974222076616c75653d22616c69676e + 3d2263656e74657222207468726f7567686f75742074686520736369656e6365 + 2066696374696f6e0a20203c64697620636c6173733d227375626d6974222063 + 6c6173733d226f6e65206f6620746865206d6f73742076616c69676e3d22746f + 70223e3c7761732065737461626c6973686564293b0d0a3c2f7363726970743e + 0d0a72657475726e2066616c73653b223e292e7374796c652e646973706c6179 + 62656361757365206f662074686520646f63756d656e742e636f6f6b69653c66 + 6f726d20616374696f6e3d222f7d626f64797b6d617267696e3a303b456e6379 + 636c6f7065646961206f6676657273696f6e206f6620746865202e6372656174 + 65456c656d656e74286e616d652220636f6e74656e743d223c2f6469763e0a3c + 2f6469763e0a0a61646d696e697374726174697665203c2f626f64793e0a3c2f + 68746d6c3e686973746f7279206f662074686520223e3c696e70757420747970 + 653d22706f7274696f6e206f66207468652061732070617274206f6620746865 + 20266e6273703b3c6120687265663d226f7468657220636f756e747269657322 + 3e0a3c64697620636c6173733d223c2f7370616e3e3c2f7370616e3e3c496e20 + 6f7468657220776f7264732c646973706c61793a20626c6f636b3b636f6e7472 + 6f6c206f662074686520696e74726f64756374696f6e206f662f3e0a3c6d6574 + 61206e616d653d2261732077656c6c2061732074686520696e20726563656e74 + 2079656172730d0a093c64697620636c6173733d223c2f6469763e0a093c2f64 + 69763e0a696e7370697265642062792074686574686520656e64206f66207468 + 6520636f6d70617469626c652077697468626563616d65206b6e6f776e206173 + 207374796c653d226d617267696e3a2e6a73223e3c2f7363726970743e3c2049 + 6e7465726e6174696f6e616c2074686572652068617665206265656e4765726d + 616e206c616e6775616765207374796c653d22636f6c6f723a23436f6d6d756e + 697374205061727479636f6e73697374656e742077697468626f726465723d22 + 30222063656c6c206d617267696e6865696768743d22746865206d616a6f7269 + 7479206f662220616c69676e3d2263656e74657272656c6174656420746f2074 + 6865206d616e7920646966666572656e74204f7274686f646f78204368757263 + 6873696d696c617220746f20746865202f3e0a3c6c696e6b2072656c3d227377 + 6173206f6e65206f662074686520756e74696c206869732064656174687d2928 + 293b0a3c2f7363726970743e6f74686572206c616e677561676573636f6d7061 + 72656420746f20746865706f7274696f6e73206f6620746865746865204e6574 + 6865726c616e6473746865206d6f737420636f6d6d6f6e6261636b67726f756e + 643a75726c286172677565642074686174207468657363726f6c6c696e673d22 + 6e6f2220696e636c7564656420696e207468654e6f72746820416d6572696361 + 6e20746865206e616d65206f6620746865696e746572707265746174696f6e73 + 74686520747261646974696f6e616c646576656c6f706d656e74206f66206672 + 657175656e746c7920757365646120636f6c6c656374696f6e206f6676657279 + 2073696d696c617220746f737572726f756e64696e67207468656578616d706c + 65206f662074686973616c69676e3d2263656e746572223e776f756c64206861 + 7665206265656e696d6167655f63617074696f6e203d61747461636865642074 + 6f2074686573756767657374696e672074686174696e2074686520666f726d20 + 6f6620696e766f6c76656420696e20746865697320646572697665642066726f + 6d6e616d656420616674657220746865496e74726f64756374696f6e20746f72 + 65737472696374696f6e73206f6e207374796c653d2277696474683a2063616e + 206265207573656420746f20746865206372656174696f6e206f666d6f737420 + 696d706f7274616e7420696e666f726d6174696f6e20616e64726573756c7465 + 6420696e20746865636f6c6c61707365206f662074686554686973206d65616e + 732074686174656c656d656e7473206f6620746865776173207265706c616365 + 64206279616e616c79736973206f6620746865696e737069726174696f6e2066 + 6f727265676172646564206173207468656d6f7374207375636365737366756c + 6b6e6f776e206173202671756f743b6120636f6d70726568656e736976654869 + 73746f7279206f6620746865207765726520636f6e7369646572656472657475 + 726e656420746f2074686561726520726566657272656420746f556e736f7572 + 63656420696d6167653e0a093c64697620636c6173733d22636f6e7369737473 + 206f662074686573746f7050726f7061676174696f6e696e7465726573742069 + 6e20746865617661696c6162696c697479206f666170706561727320746f2068 + 617665656c656374726f6d61676e65746963656e61626c655365727669636573 + 2866756e6374696f6e206f6620746865497420697320696d706f7274616e743c + 2f7363726970743e3c2f6469763e66756e6374696f6e28297b7661722072656c + 617469766520746f207468656173206120726573756c74206f66207468652070 + 6f736974696f6e206f66466f72206578616d706c652c20696e206d6574686f64 + 3d22706f7374222077617320666f6c6c6f77656420627926616d703b6d646173 + 683b20746865746865206170706c69636174696f6e6a73223e3c2f7363726970 + 743e0d0a756c3e3c2f6469763e3c2f6469763e61667465722074686520646561 + 746877697468207265737065637420746f7374796c653d2270616464696e673a + 697320706172746963756c61726c79646973706c61793a696e6c696e653b2074 + 7970653d227375626d697422206973206469766964656420696e746fe4b8ade6 + 96872028e7ae80e4bd9329726573706f6e736162696c6964616461646d696e69 + 737472616369c3b36e696e7465726e6163696f6e616c6573636f72726573706f + 6e6469656e7465e0a489e0a4aae0a4afe0a58be0a497e0a4aae0a582e0a4b0e0 + a58de0a4b5e0a4b9e0a4aee0a4bee0a4b0e0a587e0a4b2e0a58be0a497e0a58b + e0a482e0a49ae0a581e0a4a8e0a4bee0a4b5e0a4b2e0a587e0a495e0a4bfe0a4 + a8e0a4b8e0a4b0e0a495e0a4bee0a4b0e0a4aae0a581e0a4b2e0a4bfe0a4b8e0 + a496e0a58be0a49ce0a587e0a482e0a49ae0a4bee0a4b9e0a4bfe0a48fe0a4ad + e0a587e0a49ce0a587e0a482e0a4b6e0a4bee0a4aee0a4bfe0a4b2e0a4b9e0a4 + aee0a4bee0a4b0e0a580e0a49ce0a4bee0a497e0a4b0e0a4a3e0a4ace0a4a8e0 + a4bee0a4a8e0a587e0a495e0a581e0a4aee0a4bee0a4b0e0a4ace0a58de0a4b2 + e0a589e0a497e0a4aee0a4bee0a4b2e0a4bfe0a495e0a4aee0a4b9e0a4bfe0a4 + b2e0a4bee0a4aae0a583e0a4b7e0a58de0a4a0e0a4ace0a4a2e0a4bce0a4a4e0 + a587e0a4ade0a4bee0a49ce0a4aae0a4bee0a495e0a58de0a4b2e0a4bfe0a495 + e0a49fe0a58de0a4b0e0a587e0a4a8e0a496e0a4bfe0a4b2e0a4bee0a4abe0a4 + a6e0a58ce0a4b0e0a4bee0a4a8e0a4aee0a4bee0a4aee0a4b2e0a587e0a4aee0 + a4a4e0a4a6e0a4bee0a4a8e0a4ace0a4bee0a49ce0a4bee0a4b0e0a4b5e0a4bf + e0a495e0a4bee0a4b8e0a495e0a58de0a4afe0a58be0a482e0a49ae0a4bee0a4 + b9e0a4a4e0a587e0a4aae0a4b9e0a581e0a481e0a49ae0a4ace0a4a4e0a4bee0 + a4afe0a4bee0a4b8e0a482e0a4b5e0a4bee0a4a6e0a4a6e0a587e0a496e0a4a8 + e0a587e0a4aae0a4bfe0a49be0a4b2e0a587e0a4b5e0a4bfe0a4b6e0a587e0a4 + b7e0a4b0e0a4bee0a49ce0a58de0a4afe0a489e0a4a4e0a58de0a4a4e0a4b0e0 + a4aee0a581e0a482e0a4ace0a488e0a4a6e0a58be0a4a8e0a58be0a482e0a489 + e0a4aae0a495e0a4b0e0a4a3e0a4aae0a4a2e0a4bce0a587e0a482e0a4b8e0a5 + 8de0a4a5e0a4bfe0a4a4e0a4abe0a4bfe0a4b2e0a58de0a4aee0a4aee0a581e0 + a496e0a58de0a4afe0a485e0a49ae0a58de0a49be0a4bee0a49be0a582e0a49f + e0a4a4e0a580e0a4b8e0a482e0a497e0a580e0a4a4e0a49ce0a4bee0a48fe0a4 + 97e0a4bee0a4b5e0a4bfe0a4ade0a4bee0a497e0a498e0a4a3e0a58de0a49fe0 + a587e0a4a6e0a582e0a4b8e0a4b0e0a587e0a4a6e0a4bfe0a4a8e0a58be0a482 + e0a4b9e0a4a4e0a58de0a4afe0a4bee0a4b8e0a587e0a495e0a58de0a4b8e0a4 + 97e0a4bee0a482e0a4a7e0a580e0a4b5e0a4bfe0a4b6e0a58de0a4b5e0a4b0e0 + a4bee0a4a4e0a587e0a482e0a4a6e0a588e0a49fe0a58de0a4b8e0a4a8e0a495 + e0a58de0a4b6e0a4bee0a4b8e0a4bee0a4aee0a4a8e0a587e0a485e0a4a6e0a4 + bee0a4b2e0a4a4e0a4ace0a4bfe0a49ce0a4b2e0a580e0a4aae0a581e0a4b0e0 + a582e0a4b7e0a4b9e0a4bfe0a482e0a4a6e0a580e0a4aee0a4bfe0a4a4e0a58d + e0a4b0e0a495e0a4b5e0a4bfe0a4a4e0a4bee0a4b0e0a581e0a4aae0a4afe0a5 + 87e0a4b8e0a58de0a4a5e0a4bee0a4a8e0a495e0a4b0e0a58be0a4a1e0a4bce0 + a4aee0a581e0a495e0a58de0a4a4e0a4afe0a58be0a49ce0a4a8e0a4bee0a495 + e0a583e0a4aae0a4afe0a4bee0a4aae0a58be0a4b8e0a58de0a49fe0a498e0a4 + b0e0a587e0a4b2e0a582e0a495e0a4bee0a4b0e0a58de0a4afe0a4b5e0a4bfe0 + a49ae0a4bee0a4b0e0a4b8e0a582e0a49ae0a4a8e0a4bee0a4aee0a582e0a4b2 + e0a58de0a4afe0a4a6e0a587e0a496e0a587e0a482e0a4b9e0a4aee0a587e0a4 + b6e0a4bee0a4b8e0a58de0a495e0a582e0a4b2e0a4aee0a588e0a482e0a4a8e0 + a587e0a4a4e0a588e0a4afe0a4bee0a4b0e0a49ce0a4bfe0a4b8e0a495e0a587 + 7273732b786d6c22207469746c653d222d747970652220636f6e74656e743d22 + 7469746c652220636f6e74656e743d226174207468652073616d652074696d65 + 2e6a73223e3c2f7363726970743e0a3c22206d6574686f643d22706f73742220 + 3c2f7370616e3e3c2f613e3c2f6c693e766572746963616c2d616c69676e3a74 + 2f6a71756572792e6d696e2e6a73223e2e636c69636b2866756e6374696f6e28 + 207374796c653d2270616464696e672d7d2928293b0a3c2f7363726970743e0a + 3c2f7370616e3e3c6120687265663d223c6120687265663d22687474703a2f2f + 293b2072657475726e2066616c73653b746578742d6465636f726174696f6e3a + 207363726f6c6c696e673d226e6f2220626f726465722d636f6c6c617073653a + 6173736f63696174656420776974682042616861736120496e646f6e65736961 + 456e676c697368206c616e67756167653c7465787420786d6c3a73706163653d + 2e6769662220626f726465723d2230223c2f626f64793e0a3c2f68746d6c3e0a + 6f766572666c6f773a68696464656e3b696d67207372633d22687474703a2f2f + 6164644576656e744c697374656e6572726573706f6e7369626c6520666f7220 + 732e6a73223e3c2f7363726970743e0a2f66617669636f6e2e69636f22202f3e + 6f7065726174696e672073797374656d22207374796c653d2277696474683a31 + 7461726765743d225f626c616e6b223e537461746520556e6976657273697479 + 746578742d616c69676e3a6c6566743b0a646f63756d656e742e777269746528 + 2c20696e636c7564696e67207468652061726f756e642074686520776f726c64 + 293b0d0a3c2f7363726970743e0d0a3c22207374796c653d226865696768743a + 3b6f766572666c6f773a68696464656e6d6f726520696e666f726d6174696f6e + 616e20696e7465726e6174696f6e616c61206d656d626572206f662074686520 + 6f6e65206f662074686520666972737463616e20626520666f756e6420696e20 + 3c2f6469763e0a09093c2f6469763e0a646973706c61793a206e6f6e653b223e + 22202f3e0a3c6c696e6b2072656c3d220a20202866756e6374696f6e2829207b + 74686520313574682063656e747572792e70726576656e7444656661756c7428 + 6c61726765206e756d626572206f662042797a616e74696e6520456d70697265 + 2e6a70677c7468756d627c6c6566747c76617374206d616a6f72697479206f66 + 6d616a6f72697479206f66207468652020616c69676e3d2263656e746572223e + 556e6976657273697479205072657373646f6d696e6174656420627920746865 + 5365636f6e6420576f726c6420576172646973747269627574696f6e206f6620 + 7374796c653d22706f736974696f6e3a7468652072657374206f662074686520 + 636861726163746572697a65642062792072656c3d226e6f666f6c6c6f77223e + 646572697665732066726f6d20746865726174686572207468616e2074686520 + 6120636f6d62696e6174696f6e206f667374796c653d2277696474683a313030 + 456e676c6973682d737065616b696e67636f6d707574657220736369656e6365 + 626f726465723d22302220616c743d22746865206578697374656e6365206f66 + 44656d6f63726174696320506172747922207374796c653d226d617267696e2d + 466f72207468697320726561736f6e2c2e6a73223e3c2f7363726970743e0a09 + 7342795461674e616d652873295b305d6a73223e3c2f7363726970743e0d0a3c + 2e6a73223e3c2f7363726970743e0d0a6c696e6b2072656c3d2269636f6e2220 + 2720616c743d272720636c6173733d27666f726d6174696f6e206f6620746865 + 76657273696f6e73206f6620746865203c2f613e3c2f6469763e3c2f6469763e + 2f706167653e0a20203c706167653e0a3c64697620636c6173733d22636f6e74 + 626563616d652074686520666972737462616861736120496e646f6e65736961 + 656e676c697368202873696d706c6529ce95cebbcebbceb7cebdceb9cebaceac + d185d180d0b2d0b0d182d181d0bad0b8d0bad0bed0bcd0bfd0b0d0bdd0b8d0b8 + d18fd0b2d0bbd18fd0b5d182d181d18fd094d0bed0b1d0b0d0b2d0b8d182d18c + d187d0b5d0bbd0bed0b2d0b5d0bad0b0d180d0b0d0b7d0b2d0b8d182d0b8d18f + d098d0bdd182d0b5d180d0bdd0b5d182d09ed182d0b2d0b5d182d0b8d182d18c + d0bdd0b0d0bfd180d0b8d0bcd0b5d180d0b8d0bdd182d0b5d180d0bdd0b5d182 + d0bad0bed182d0bed180d0bed0b3d0bed181d182d180d0b0d0bdd0b8d186d18b + d0bad0b0d187d0b5d181d182d0b2d0b5d183d181d0bbd0bed0b2d0b8d18fd185 + d0bfd180d0bed0b1d0bbd0b5d0bcd18bd0bfd0bed0bbd183d187d0b8d182d18c + d18fd0b2d0bbd18fd18ed182d181d18fd0bdd0b0d0b8d0b1d0bed0bbd0b5d0b5 + d0bad0bed0bcd0bfd0b0d0bdd0b8d18fd0b2d0bdd0b8d0bcd0b0d0bdd0b8d0b5 + d181d180d0b5d0b4d181d182d0b2d0b0d8a7d984d985d988d8a7d8b6d98ad8b9 + d8a7d984d8b1d8a6d98ad8b3d98ad8a9d8a7d984d8a7d986d8aad982d8a7d984 + d985d8b4d8a7d8b1d983d8a7d8aad983d8a7d984d8b3d98ad8a7d8b1d8a7d8aa + d8a7d984d985d983d8aad988d8a8d8a9d8a7d984d8b3d8b9d988d8afd98ad8a9 + d8a7d8add8b5d8a7d8a6d98ad8a7d8aad8a7d984d8b9d8a7d984d985d98ad8a9 + d8a7d984d8b5d988d8aad98ad8a7d8aad8a7d984d8a7d986d8aad8b1d986d8aa + d8a7d984d8aad8b5d8a7d985d98ad985d8a7d984d8a5d8b3d984d8a7d985d98a + d8a7d984d985d8b4d8a7d8b1d983d8a9d8a7d984d985d8b1d8a6d98ad8a7d8aa + 726f626f74732220636f6e74656e743d223c6469762069643d22666f6f746572 + 223e74686520556e69746564205374617465733c696d67207372633d22687474 + 703a2f2f2e6a70677c72696768747c7468756d627c2e6a73223e3c2f73637269 + 70743e0d0a3c6c6f636174696f6e2e70726f746f636f6c6672616d65626f7264 + 65723d223022207322202f3e0a3c6d657461206e616d653d223c2f613e3c2f64 + 69763e3c2f6469763e3c666f6e742d7765696768743a626f6c643b2671756f74 + 3b20616e64202671756f743b646570656e64696e67206f6e20746865206d6172 + 67696e3a303b70616464696e673a222072656c3d226e6f666f6c6c6f77222050 + 7265736964656e74206f6620746865207477656e74696574682063656e747572 + 7965766973696f6e3e0a20203c2f70616765496e7465726e6574204578706c6f + 726572612e6173796e63203d20747275653b0d0a696e666f726d6174696f6e20 + 61626f75743c6469762069643d22686561646572223e2220616374696f6e3d22 + 687474703a2f2f3c6120687265663d2268747470733a2f2f3c6469762069643d + 22636f6e74656e74223c2f6469763e0d0a3c2f6469763e0d0a3c646572697665 + 642066726f6d20746865203c696d67207372633d27687474703a2f2f6163636f + 7264696e6720746f20746865200a3c2f626f64793e0a3c2f68746d6c3e0a7374 + 796c653d22666f6e742d73697a653a736372697074206c616e67756167653d22 + 417269616c2c2048656c7665746963612c3c2f613e3c7370616e20636c617373 + 3d223c2f7363726970743e3c73637269707420706f6c69746963616c20706172 + 7469657374643e3c2f74723e3c2f7461626c653e3c687265663d22687474703a + 2f2f7777772e696e746572707265746174696f6e206f6672656c3d227374796c + 6573686565742220646f63756d656e742e777269746528273c63686172736574 + 3d227574662d38223e0a626567696e6e696e67206f6620746865207265766561 + 6c656420746861742074686574656c65766973696f6e20736572696573222072 + 656c3d226e6f666f6c6c6f77223e207461726765743d225f626c616e6b223e63 + 6c61696d696e6720746861742074686568747470253341253246253246777777 + 2e6d616e69666573746174696f6e73206f665072696d65204d696e6973746572 + 206f66696e666c75656e63656420627920746865636c6173733d22636c656172 + 666978223e2f6469763e0d0a3c2f6469763e0d0a0d0a74687265652d64696d65 + 6e73696f6e616c436875726368206f6620456e676c616e646f66204e6f727468 + 204361726f6c696e61737175617265206b696c6f6d65747265732e6164644576 + 656e744c697374656e657264697374696e63742066726f6d20746865636f6d6d + 6f6e6c79206b6e6f776e20617350686f6e6574696320416c7068616265746465 + 636c61726564207468617420746865636f6e74726f6c6c656420627920746865 + 42656e6a616d696e204672616e6b6c696e726f6c652d706c6179696e67206761 + 6d6574686520556e6976657273697479206f66696e205765737465726e204575 + 726f7065706572736f6e616c20636f6d707574657250726f6a65637420477574 + 656e626572677265676172646c657373206f6620746865686173206265656e20 + 70726f706f736564746f6765746865722077697468207468653e3c2f6c693e3c + 6c6920636c6173733d22696e20736f6d6520636f756e74726965736d696e2e6a + 73223e3c2f7363726970743e6f662074686520706f70756c6174696f6e6f6666 + 696369616c206c616e67756167653c696d67207372633d22696d616765732f69 + 64656e746966696564206279207468656e61747572616c207265736f75726365 + 73636c617373696669636174696f6e206f6663616e20626520636f6e73696465 + 7265647175616e74756d206d656368616e6963734e657665727468656c657373 + 2c207468656d696c6c696f6e2079656172732061676f3c2f626f64793e0d0a3c + 2f68746d6c3e0dce95cebbcebbceb7cebdceb9cebaceac0a74616b6520616476 + 616e74616765206f66616e642c206163636f7264696e6720746f617474726962 + 7574656420746f207468654d6963726f736f66742057696e646f777374686520 + 66697273742063656e74757279756e6465722074686520636f6e74726f6c6469 + 7620636c6173733d2268656164657273686f72746c7920616674657220746865 + 6e6f7461626c6520657863657074696f6e74656e73206f662074686f7573616e + 64737365766572616c20646966666572656e7461726f756e642074686520776f + 726c642e7265616368696e67206d696c697461727969736f6c61746564206672 + 6f6d207468656f70706f736974696f6e20746f20746865746865204f6c642054 + 657374616d656e744166726963616e20416d65726963616e73696e7365727465 + 6420696e746f2074686573657061726174652066726f6d207468656d6574726f + 706f6c6974616e20617265616d616b657320697420706f737369626c6561636b + 6e6f776c656467656420746861746172677561626c7920746865206d6f737474 + 7970653d22746578742f637373223e0a74686520496e7465726e6174696f6e61 + 6c4163636f7264696e6720746f207468652070653d22746578742f6373732220 + 2f3e0a636f696e6369646520776974682074686574776f2d746869726473206f + 6620746865447572696e6720746869732074696d652c647572696e6720746865 + 20706572696f64616e6e6f756e636564207468617420686574686520696e7465 + 726e6174696f6e616c616e64206d6f726520726563656e746c7962656c696576 + 6564207468617420746865636f6e7363696f75736e65737320616e64666f726d + 65726c79206b6e6f776e206173737572726f756e646564206279207468656669 + 72737420617070656172656420696e6f63636173696f6e616c6c792075736564 + 706f736974696f6e3a6162736f6c7574653b22207461726765743d225f626c61 + 6e6b2220706f736974696f6e3a72656c61746976653b746578742d616c69676e + 3a63656e7465723b6a61782f6c6962732f6a71756572792f312e6261636b6772 + 6f756e642d636f6c6f723a23747970653d226170706c69636174696f6e2f616e + 67756167652220636f6e74656e743d223c6d65746120687474702d6571756976 + 3d225072697661637920506f6c6963793c2f613e652822253343736372697074 + 207372633d2722207461726765743d225f626c616e6b223e4f6e20746865206f + 746865722068616e642c2e6a70677c7468756d627c72696768747c323c2f6469 + 763e3c64697620636c6173733d223c646976207374796c653d22666c6f61743a + 6e696e657465656e74682063656e747572793c2f626f64793e0d0a3c2f68746d + 6c3e0d0a3c696d67207372633d22687474703a2f2f733b746578742d616c6967 + 6e3a63656e746572666f6e742d7765696768743a20626f6c643b204163636f72 + 64696e6720746f2074686520646966666572656e6365206265747765656e2220 + 6672616d65626f726465723d2230222022207374796c653d22706f736974696f + 6e3a6c696e6b20687265663d22687474703a2f2f68746d6c342f6c6f6f73652e + 647464223e0a647572696e67207468697320706572696f643c2f74643e3c2f74 + 723e3c2f7461626c653e636c6f73656c792072656c6174656420746f666f7220 + 7468652066697273742074696d653b666f6e742d7765696768743a626f6c643b + 696e70757420747970653d227465787422203c7370616e207374796c653d2266 + 6f6e742d6f6e726561647973746174656368616e6765093c64697620636c6173 + 733d22636c656172646f63756d656e742e6c6f636174696f6e2e20466f722065 + 78616d706c652c20746865206120776964652076617269657479206f66203c21 + 444f43545950452068746d6c3e0d0a3c266e6273703b266e6273703b266e6273 + 703b223e3c6120687265663d22687474703a2f2f7374796c653d22666c6f6174 + 3a6c6566743b636f6e6365726e65642077697468207468653d68747470253341 + 2532462532467777772e696e20706f70756c61722063756c7475726574797065 + 3d22746578742f63737322202f3e697420697320706f737369626c6520746f20 + 4861727661726420556e697665727369747974796c6573686565742220687265 + 663d222f746865206d61696e206368617261637465724f78666f726420556e69 + 7665727369747920206e616d653d226b6579776f7264732220637374796c653d + 22746578742d616c69676e3a74686520556e69746564204b696e67646f6d6665 + 646572616c20676f7665726e6d656e743c646976207374796c653d226d617267 + 696e20646570656e64696e67206f6e20746865206465736372697074696f6e20 + 6f66207468653c64697620636c6173733d226865616465722e6d696e2e6a7322 + 3e3c2f7363726970743e6465737472756374696f6e206f6620746865736c6967 + 68746c7920646966666572656e74696e206163636f7264616e63652077697468 + 74656c65636f6d6d756e69636174696f6e73696e646963617465732074686174 + 2074686573686f72746c792074686572656166746572657370656369616c6c79 + 20696e20746865204575726f7065616e20636f756e7472696573486f77657665 + 722c207468657265206172657372633d22687474703a2f2f7374617469637375 + 6767657374656420746861742074686522207372633d22687474703a2f2f7777 + 772e61206c61726765206e756d626572206f662054656c65636f6d6d756e6963 + 6174696f6e73222072656c3d226e6f666f6c6c6f77222074486f6c7920526f6d + 616e20456d7065726f72616c6d6f7374206578636c75736976656c792220626f + 726465723d22302220616c743d22536563726574617279206f66205374617465 + 63756c6d696e6174696e6720696e2074686543494120576f726c642046616374 + 626f6f6b746865206d6f737420696d706f7274616e74616e6e69766572736172 + 79206f66207468657374796c653d226261636b67726f756e642d3c6c693e3c65 + 6d3e3c6120687265663d222f7468652041746c616e746963204f6365616e7374 + 726963746c7920737065616b696e672c73686f72746c79206265666f72652074 + 6865646966666572656e74207479706573206f66746865204f74746f6d616e20 + 456d706972653e3c696d67207372633d22687474703a2f2f416e20496e74726f + 64756374696f6e20746f636f6e73657175656e6365206f662074686564657061 + 72747572652066726f6d20746865436f6e666564657261746520537461746573 + 696e646967656e6f75732070656f706c657350726f63656564696e6773206f66 + 20746865696e666f726d6174696f6e206f6e207468657468656f726965732068 + 617665206265656e696e766f6c76656d656e7420696e20746865646976696465 + 6420696e746f20746872656561646a6163656e7420636f756e74726965736973 + 20726573706f6e7369626c6520666f72646973736f6c7574696f6e206f662074 + 6865636f6c6c61626f726174696f6e2077697468776964656c79207265676172 + 64656420617368697320636f6e74656d706f726172696573666f756e64696e67 + 206d656d626572206f66446f6d696e6963616e2052657075626c696367656e65 + 72616c6c7920616363657074656474686520706f73736962696c697479206f66 + 61726520616c736f20617661696c61626c65756e64657220636f6e7374727563 + 74696f6e726573746f726174696f6e206f66207468657468652067656e657261 + 6c207075626c6963697320616c6d6f737420656e746972656c79706173736573 + 207468726f75676820746865686173206265656e20737567676573746564636f + 6d707574657220616e6420766964656f4765726d616e6963206c616e67756167 + 6573206163636f7264696e6720746f2074686520646966666572656e74206672 + 6f6d2074686573686f72746c792061667465727761726473687265663d226874 + 7470733a2f2f7777772e726563656e7420646576656c6f706d656e74426f6172 + 64206f66204469726563746f72733c64697620636c6173733d22736561726368 + 7c203c6120687265663d22687474703a2f2f496e20706172746963756c61722c + 207468654d756c7469706c6520666f6f746e6f7465736f72206f746865722073 + 75627374616e636574686f7573616e6473206f662079656172737472616e736c + 6174696f6e206f66207468653c2f6469763e0d0a3c2f6469763e0d0a0d0a3c61 + 20687265663d22696e6465782e7068707761732065737461626c697368656420 + 696e6d696e2e6a73223e3c2f7363726970743e0a706172746963697061746520 + 696e2074686561207374726f6e6720696e666c75656e63657374796c653d226d + 617267696e2d746f703a726570726573656e7465642062792074686567726164 + 75617465642066726f6d20746865547261646974696f6e616c6c792c20746865 + 456c656d656e74282273637269707422293b486f77657665722c2073696e6365 + 207468652f6469763e0a3c2f6469763e0a3c646976206c6566743b206d617267 + 696e2d6c6566743a70726f74656374696f6e20616761696e7374303b20766572 + 746963616c2d616c69676e3a556e666f7274756e6174656c792c207468657479 + 70653d22696d6167652f782d69636f6e2f6469763e0a3c64697620636c617373 + 3d2220636c6173733d22636c656172666978223e3c64697620636c6173733d22 + 666f6f74657209093c2f6469763e0a09093c2f6469763e0a746865206d6f7469 + 6f6e2070696374757265d091d18ad0bbd0b3d0b0d180d181d0bad0b8d0b1d18a + d0bbd0b3d0b0d180d181d0bad0b8d0a4d0b5d0b4d0b5d180d0b0d186d0b8d0b8 + d0bdd0b5d181d0bad0bed0bbd18cd0bad0bed181d0bed0bed0b1d189d0b5d0bd + d0b8d0b5d181d0bed0bed0b1d189d0b5d0bdd0b8d18fd0bfd180d0bed0b3d180 + d0b0d0bcd0bcd18bd09ed182d0bfd180d0b0d0b2d0b8d182d18cd0b1d0b5d181 + d0bfd0bbd0b0d182d0bdd0bed0bcd0b0d182d0b5d180d0b8d0b0d0bbd18bd0bf + d0bed0b7d0b2d0bed0bbd18fd0b5d182d0bfd0bed181d0bbd0b5d0b4d0bdd0b8 + d0b5d180d0b0d0b7d0bbd0b8d187d0bdd18bd185d0bfd180d0bed0b4d183d0ba + d186d0b8d0b8d0bfd180d0bed0b3d180d0b0d0bcd0bcd0b0d0bfd0bed0bbd0bd + d0bed181d182d18cd18ed0bdd0b0d185d0bed0b4d0b8d182d181d18fd0b8d0b7 + d0b1d180d0b0d0bdd0bdd0bed0b5d0bdd0b0d181d0b5d0bbd0b5d0bdd0b8d18f + d0b8d0b7d0bcd0b5d0bdd0b5d0bdd0b8d18fd0bad0b0d182d0b5d0b3d0bed180 + d0b8d0b8d090d0bbd0b5d0bad181d0b0d0bdd0b4d180e0a4a6e0a58de0a4b5e0 + a4bee0a4b0e0a4bee0a4aee0a588e0a4a8e0a581e0a485e0a4b2e0a4aae0a58d + e0a4b0e0a4a6e0a4bee0a4a8e0a4ade0a4bee0a4b0e0a4a4e0a580e0a4afe0a4 + 85e0a4a8e0a581e0a4a6e0a587e0a4b6e0a4b9e0a4bfe0a4a8e0a58de0a4a6e0 + a580e0a487e0a482e0a4a1e0a4bfe0a4afe0a4bee0a4a6e0a4bfe0a4b2e0a58d + e0a4b2e0a580e0a485e0a4a7e0a4bfe0a495e0a4bee0a4b0e0a4b5e0a580e0a4 + a1e0a4bfe0a4afe0a58be0a49ae0a4bfe0a49fe0a58de0a4a0e0a587e0a4b8e0 + a4aee0a4bee0a49ae0a4bee0a4b0e0a49ce0a482e0a495e0a58de0a4b6e0a4a8 + e0a4a6e0a581e0a4a8e0a4bfe0a4afe0a4bee0a4aae0a58de0a4b0e0a4afe0a5 + 8be0a497e0a485e0a4a8e0a581e0a4b8e0a4bee0a4b0e0a491e0a4a8e0a4b2e0 + a4bee0a487e0a4a8e0a4aae0a4bee0a4b0e0a58de0a49fe0a580e0a4b6e0a4b0 + e0a58de0a4a4e0a58be0a482e0a4b2e0a58be0a495e0a4b8e0a4ade0a4bee0a4 + abe0a4bce0a58de0a4b2e0a588e0a4b6e0a4b6e0a4b0e0a58de0a4a4e0a587e0 + a482e0a4aae0a58de0a4b0e0a4a6e0a587e0a4b6e0a4aae0a58de0a4b2e0a587 + e0a4afe0a4b0e0a495e0a587e0a482e0a4a6e0a58de0a4b0e0a4b8e0a58de0a4 + a5e0a4bfe0a4a4e0a4bfe0a489e0a4a4e0a58de0a4aae0a4bee0a4a6e0a489e0 + a4a8e0a58de0a4b9e0a587e0a482e0a49ae0a4bfe0a49fe0a58de0a4a0e0a4be + e0a4afe0a4bee0a4a4e0a58de0a4b0e0a4bee0a49ce0a58de0a4afe0a4bee0a4 + a6e0a4bee0a4aae0a581e0a4b0e0a4bee0a4a8e0a587e0a49ce0a58be0a4a1e0 + a4bce0a587e0a482e0a485e0a4a8e0a581e0a4b5e0a4bee0a4a6e0a4b6e0a58d + e0a4b0e0a587e0a4a3e0a580e0a4b6e0a4bfe0a495e0a58de0a4b7e0a4bee0a4 + b8e0a4b0e0a495e0a4bee0a4b0e0a580e0a4b8e0a482e0a497e0a58de0a4b0e0 + a4b9e0a4aae0a4b0e0a4bfe0a4a3e0a4bee0a4aee0a4ace0a58de0a4b0e0a4be + e0a482e0a4a1e0a4ace0a49ae0a58de0a49ae0a58be0a482e0a489e0a4aae0a4 + b2e0a4ace0a58de0a4a7e0a4aee0a482e0a4a4e0a58de0a4b0e0a580e0a4b8e0 + a482e0a4aae0a4b0e0a58de0a495e0a489e0a4aee0a58de0a4aee0a580e0a4a6 + e0a4aee0a4bee0a4a7e0a58de0a4afe0a4aee0a4b8e0a4b9e0a4bee0a4afe0a4 + a4e0a4bee0a4b6e0a4ace0a58de0a4a6e0a58be0a482e0a4aee0a580e0a4a1e0 + a4bfe0a4afe0a4bee0a486e0a488e0a4aae0a580e0a48fe0a4b2e0a4aee0a58b + e0a4ace0a4bee0a487e0a4b2e0a4b8e0a482e0a496e0a58de0a4afe0a4bee0a4 + 86e0a4aae0a4b0e0a587e0a4b6e0a4a8e0a485e0a4a8e0a581e0a4ace0a482e0 + a4a7e0a4ace0a4bee0a49ce0a4bce0a4bee0a4b0e0a4a8e0a4b5e0a580e0a4a8 + e0a4a4e0a4aee0a4aae0a58de0a4b0e0a4aee0a581e0a496e0a4aae0a58de0a4 + b0e0a4b6e0a58de0a4a8e0a4aae0a4b0e0a4bfe0a4b5e0a4bee0a4b0e0a4a8e0 + a581e0a495e0a4b8e0a4bee0a4a8e0a4b8e0a4aee0a4b0e0a58de0a4a5e0a4a8 + e0a486e0a4afe0a58be0a49ce0a4bfe0a4a4e0a4b8e0a58be0a4aee0a4b5e0a4 + bee0a4b0d8a7d984d985d8b4d8a7d8b1d983d8a7d8aad8a7d984d985d986d8aa + d8afd98ad8a7d8aad8a7d984d983d985d8a8d98ad988d8aad8b1d8a7d984d985 + d8b4d8a7d987d8afd8a7d8aad8b9d8afd8afd8a7d984d8b2d988d8a7d8b1d8b9 + d8afd8afd8a7d984d8b1d8afd988d8afd8a7d984d8a5d8b3d984d8a7d985d98a + d8a9d8a7d984d981d988d8aad988d8b4d988d8a8d8a7d984d985d8b3d8a7d8a8 + d982d8a7d8aad8a7d984d985d8b9d984d988d985d8a7d8aad8a7d984d985d8b3 + d984d8b3d984d8a7d8aad8a7d984d8acd8b1d8a7d981d98ad983d8b3d8a7d984 + d8a7d8b3d984d8a7d985d98ad8a9d8a7d984d8a7d8aad8b5d8a7d984d8a7d8aa + 6b6579776f7264732220636f6e74656e743d2277332e6f72672f313939392f78 + 68746d6c223e3c61207461726765743d225f626c616e6b2220746578742f6874 + 6d6c3b20636861727365743d22207461726765743d225f626c616e6b223e3c74 + 61626c652063656c6c70616464696e673d226175746f636f6d706c6574653d22 + 6f66662220746578742d616c69676e3a2063656e7465723b746f206c61737420 + 76657273696f6e206279206261636b67726f756e642d636f6c6f723a20232220 + 687265663d22687474703a2f2f7777772e2f6469763e3c2f6469763e3c646976 + 2069643d3c6120687265663d22232220636c6173733d22223e3c696d67207372 + 633d22687474703a2f2f637269707422207372633d22687474703a2f2f0a3c73 + 6372697074206c616e67756167653d222f2f454e222022687474703a2f2f7777 + 772e77656e636f6465555249436f6d706f6e656e74282220687265663d226a61 + 76617363726970743a3c64697620636c6173733d22636f6e74656e74646f6375 + 6d656e742e777269746528273c7363706f736974696f6e3a206162736f6c7574 + 653b736372697074207372633d22687474703a2f2f207374796c653d226d6172 + 67696e2d746f703a2e6d696e2e6a73223e3c2f7363726970743e0a3c2f646976 + 3e0a3c64697620636c6173733d2277332e6f72672f313939392f7868746d6c22 + 200a0d0a3c2f626f64793e0d0a3c2f68746d6c3e64697374696e6374696f6e20 + 6265747765656e2f22207461726765743d225f626c616e6b223e3c6c696e6b20 + 687265663d22687474703a2f2f656e636f64696e673d227574662d38223f3e0a + 772e6164644576656e744c697374656e65723f616374696f6e3d22687474703a + 2f2f7777772e69636f6e2220687265663d22687474703a2f2f207374796c653d + 226261636b67726f756e643a747970653d22746578742f63737322202f3e0a6d + 6574612070726f70657274793d226f673a743c696e70757420747970653d2274 + 6578742220207374796c653d22746578742d616c69676e3a7468652064657665 + 6c6f706d656e74206f662074796c6573686565742220747970653d2274656874 + 6d6c3b20636861727365743d7574662d38697320636f6e736964657265642074 + 6f2062657461626c652077696474683d22313030252220496e20616464697469 + 6f6e20746f2074686520636f6e747269627574656420746f2074686520646966 + 666572656e636573206265747765656e646576656c6f706d656e74206f662074 + 686520497420697320696d706f7274616e7420746f203c2f7363726970743e0a + 0a3c73637269707420207374796c653d22666f6e742d73697a653a313e3c2f73 + 70616e3e3c7370616e2069643d67624c696272617279206f6620436f6e677265 + 73733c696d67207372633d22687474703a2f2f696d456e676c69736820747261 + 6e736c6174696f6e41636164656d79206f6620536369656e6365736469762073 + 74796c653d22646973706c61793a636f6e737472756374696f6e206f66207468 + 652e676574456c656d656e744279496428696429696e20636f6e6a756e637469 + 6f6e2077697468456c656d656e74282773637269707427293b203c6d65746120 + 70726f70657274793d226f673ad091d18ad0bbd0b3d0b0d180d181d0bad0b80a + 20747970653d227465787422206e616d653d223e5072697661637920506f6c69 + 63793c2f613e61646d696e6973746572656420627920746865656e61626c6553 + 696e676c65526571756573747374796c653d2671756f743b6d617267696e3a3c + 2f6469763e3c2f6469763e3c2f6469763e3c3e3c696d67207372633d22687474 + 703a2f2f69207374796c653d2671756f743b666c6f61743a7265666572726564 + 20746f2061732074686520746f74616c20706f70756c6174696f6e206f66696e + 2057617368696e67746f6e2c20442e432e207374796c653d226261636b67726f + 756e642d616d6f6e67206f74686572207468696e67732c6f7267616e697a6174 + 696f6e206f662074686570617274696369706174656420696e20746865746865 + 20696e74726f64756374696f6e206f666964656e746966696564207769746820 + 74686566696374696f6e616c20636861726163746572204f78666f726420556e + 6976657273697479206d6973756e6465727374616e64696e67206f6654686572 + 65206172652c20686f77657665722c7374796c6573686565742220687265663d + 222f436f6c756d62696120556e6976657273697479657870616e64656420746f + 20696e636c756465757375616c6c7920726566657272656420746f696e646963 + 6174696e67207468617420746865686176652073756767657374656420746861 + 74616666696c6961746564207769746820746865636f7272656c6174696f6e20 + 6265747765656e6e756d626572206f6620646966666572656e743e3c2f74643e + 3c2f74723e3c2f7461626c653e52657075626c6963206f66204972656c616e64 + 0a3c2f7363726970743e0a3c73637269707420756e6465722074686520696e66 + 6c75656e6365636f6e747269627574696f6e20746f207468654f666669636961 + 6c2077656273697465206f66686561647175617274657273206f662074686563 + 656e74657265642061726f756e6420746865696d706c69636174696f6e73206f + 662074686568617665206265656e20646576656c6f7065644665646572616c20 + 52657075626c6963206f66626563616d6520696e6372656173696e676c79636f + 6e74696e756174696f6e206f66207468654e6f74652c20686f77657665722c20 + 7468617473696d696c617220746f2074686174206f66206361706162696c6974 + 696573206f66207468656163636f7264616e6365207769746820746865706172 + 7469636970616e747320696e207468656675727468657220646576656c6f706d + 656e74756e6465722074686520646972656374696f6e6973206f6674656e2063 + 6f6e7369646572656468697320796f756e6765722062726f746865723c2f7464 + 3e3c2f74723e3c2f7461626c653e3c6120687474702d65717569763d22582d55 + 412d706879736963616c2070726f706572746965736f66204272697469736820 + 436f6c756d626961686173206265656e20637269746963697a65642877697468 + 2074686520657863657074696f6e7175657374696f6e732061626f7574207468 + 6570617373696e67207468726f7567682074686530222063656c6c7061646469 + 6e673d2230222074686f7573616e6473206f662070656f706c65726564697265 + 63747320686572652e20466f7268617665206368696c6472656e20756e646572 + 2533452533432f7363726970742533452229293b3c6120687265663d22687474 + 703a2f2f7777772e3c6c693e3c6120687265663d22687474703a2f2f73697465 + 5f6e616d652220636f6e74656e743d22746578742d6465636f726174696f6e3a + 6e6f6e657374796c653d22646973706c61793a206e6f6e653c6d657461206874 + 74702d65717569763d22582d6e6577204461746528292e67657454696d652829 + 20747970653d22696d6167652f782d69636f6e223c2f7370616e3e3c7370616e + 20636c6173733d226c616e67756167653d226a61766173637269707477696e64 + 6f772e6c6f636174696f6e2e687265663c6120687265663d226a617661736372 + 6970743a2d2d3e0d0a3c73637269707420747970653d22743c6120687265663d + 27687474703a2f2f7777772e686f72746375742069636f6e2220687265663d22 + 3c2f6469763e0d0a3c64697620636c6173733d223c736372697074207372633d + 22687474703a2f2f222072656c3d227374796c6573686565742220743c2f6469 + 763e0a3c73637269707420747970653d2f613e203c6120687265663d22687474 + 703a2f2f20616c6c6f775472616e73706172656e63793d22582d55412d436f6d + 70617469626c652220636f6e72656c6174696f6e73686970206265747765656e + 0a3c2f7363726970743e0d0a3c736372697074203c2f613e3c2f6c693e3c2f75 + 6c3e3c2f6469763e6173736f6369617465642077697468207468652070726f67 + 72616d6d696e67206c616e67756167653c2f613e3c6120687265663d22687474 + 703a2f2f3c2f613e3c2f6c693e3c6c6920636c6173733d22666f726d20616374 + 696f6e3d22687474703a2f2f3c646976207374796c653d22646973706c61793a + 747970653d227465787422206e616d653d2271223c7461626c65207769647468 + 3d223130302522206261636b67726f756e642d706f736974696f6e3a2220626f + 726465723d2230222077696474683d2272656c3d2273686f7274637574206963 + 6f6e222068363e3c756c3e3c6c693e3c6120687265663d2220203c6d65746120 + 687474702d65717569763d2263737322206d656469613d2273637265656e2220 + 726573706f6e7369626c6520666f7220746865202220747970653d226170706c + 69636174696f6e2f22207374796c653d226261636b67726f756e642d68746d6c + 3b20636861727365743d7574662d382220616c6c6f777472616e73706172656e + 63793d227374796c6573686565742220747970653d2274650d0a3c6d65746120 + 687474702d65717569763d223e3c2f7370616e3e3c7370616e20636c6173733d + 2230222063656c6c73706163696e673d2230223e3b0a3c2f7363726970743e0a + 3c73637269707420736f6d6574696d65732063616c6c656420746865646f6573 + 206e6f74206e65636573736172696c79466f72206d6f726520696e666f726d61 + 74696f6e61742074686520626567696e6e696e67206f66203c21444f43545950 + 452068746d6c3e3c68746d6c706172746963756c61726c7920696e2074686520 + 747970653d2268696464656e22206e616d653d226a6176617363726970743a76 + 6f69642830293b226566666563746976656e657373206f662074686520617574 + 6f636f6d706c6574653d226f6666222067656e6572616c6c7920636f6e736964 + 657265643e3c696e70757420747970653d22746578742220223e3c2f73637269 + 70743e0d0a3c7363726970747468726f7567686f75742074686520776f726c64 + 636f6d6d6f6e206d6973636f6e63657074696f6e6173736f63696174696f6e20 + 77697468207468653c2f6469763e0a3c2f6469763e0a3c646976206364757269 + 6e6720686973206c69666574696d652c636f72726573706f6e64696e6720746f + 20746865747970653d22696d6167652f782d69636f6e2220616e20696e637265 + 6173696e67206e756d6265726469706c6f6d617469632072656c6174696f6e73 + 617265206f6674656e20636f6e736964657265646d6574612063686172736574 + 3d227574662d3822203c696e70757420747970653d227465787422206578616d + 706c657320696e636c75646520746865223e3c696d67207372633d2268747470 + 3a2f2f6970617274696369706174696f6e20696e207468657468652065737461 + 626c6973686d656e74206f660a3c2f6469763e0a3c64697620636c6173733d22 + 26616d703b6e6273703b26616d703b6e6273703b746f2064657465726d696e65 + 2077686574686572717569746520646966666572656e742066726f6d6d61726b + 65642074686520626567696e6e696e6764697374616e6365206265747765656e + 20746865636f6e747269627574696f6e7320746f20746865636f6e666c696374 + 206265747765656e20746865776964656c7920636f6e7369646572656420746f + 776173206f6e65206f6620746865206669727374776974682076617279696e67 + 2064656772656573686176652073706563756c61746564207468617428646f63 + 756d656e742e676574456c656d656e7470617274696369706174696e6720696e + 207468656f726967696e616c6c7920646576656c6f7065646574612063686172 + 7365743d227574662d38223e20747970653d22746578742f63737322202f3e0a + 696e7465726368616e676561626c7920776974686d6f726520636c6f73656c79 + 2072656c61746564736f6369616c20616e6420706f6c69746963616c74686174 + 20776f756c64206f746865727769736570657270656e646963756c617220746f + 207468657374796c6520747970653d22746578742f637373747970653d227375 + 626d697422206e616d653d2266616d696c696573207265736964696e6720696e + 646576656c6f70696e6720636f756e7472696573636f6d70757465722070726f + 6772616d6d696e6765636f6e6f6d696320646576656c6f706d656e7464657465 + 726d696e6174696f6e206f6620746865666f72206d6f726520696e666f726d61 + 74696f6e6f6e207365766572616c206f63636173696f6e73706f7274756775c3 + aa7320284575726f70657529d0a3d0bad180d0b0d197d0bdd181d18cd0bad0b0 + d183d0bad180d0b0d197d0bdd181d18cd0bad0b0d0a0d0bed181d181d0b8d0b9 + d181d0bad0bed0b9d0bcd0b0d182d0b5d180d0b8d0b0d0bbd0bed0b2d0b8d0bd + d184d0bed180d0bcd0b0d186d0b8d0b8d183d0bfd180d0b0d0b2d0bbd0b5d0bd + d0b8d18fd0bdd0b5d0bed0b1d185d0bed0b4d0b8d0bcd0bed0b8d0bdd184d0be + d180d0bcd0b0d186d0b8d18fd098d0bdd184d0bed180d0bcd0b0d186d0b8d18f + d0a0d0b5d181d0bfd183d0b1d0bbd0b8d0bad0b8d0bad0bed0bbd0b8d187d0b5 + d181d182d0b2d0bed0b8d0bdd184d0bed180d0bcd0b0d186d0b8d18ed182d0b5 + d180d180d0b8d182d0bed180d0b8d0b8d0b4d0bed181d182d0b0d182d0bed187 + d0bdd0bed8a7d984d985d8aad988d8a7d8acd8afd988d986d8a7d984d8a7d8b4 + d8aad8b1d8a7d983d8a7d8aad8a7d984d8a7d982d8aad8b1d8a7d8add8a7d8aa + 68746d6c3b20636861727365743d5554462d38222073657454696d656f757428 + 66756e6374696f6e2829646973706c61793a696e6c696e652d626c6f636b3b3c + 696e70757420747970653d227375626d6974222074797065203d202774657874 + 2f6a617661736372693c696d67207372633d22687474703a2f2f7777772e2220 + 22687474703a2f2f7777772e77332e6f72672f73686f72746375742069636f6e + 2220687265663d2222206175746f636f6d706c6574653d226f666622203c2f61 + 3e3c2f6469763e3c64697620636c6173733d3c2f613e3c2f6c693e0a3c6c6920 + 636c6173733d226373732220747970653d22746578742f63737322203c666f72 + 6d20616374696f6e3d22687474703a2f2f78742f6373732220687265663d2268 + 7474703a2f2f6c696e6b2072656c3d22616c7465726e61746522200d0a3c7363 + 7269707420747970653d22746578742f206f6e636c69636b3d226a6176617363 + 726970743a286e65772044617465292e67657454696d6528297d686569676874 + 3d2231222077696474683d2231222050656f706c6527732052657075626c6963 + 206f6620203c6120687265663d22687474703a2f2f7777772e746578742d6465 + 636f726174696f6e3a756e64657274686520626567696e6e696e67206f662074 + 6865203c2f6469763e0a3c2f6469763e0a3c2f6469763e0a65737461626c6973 + 686d656e74206f6620746865203c2f6469763e3c2f6469763e3c2f6469763e3c + 2f642376696577706f72747b6d696e2d6865696768743a0a3c73637269707420 + 7372633d22687474703a2f2f6f7074696f6e3e3c6f7074696f6e2076616c7565 + 3d6f6674656e20726566657272656420746f206173202f6f7074696f6e3e0a3c + 6f7074696f6e2076616c753c21444f43545950452068746d6c3e0a3c212d2d5b + 496e7465726e6174696f6e616c20416972706f72743e0a3c6120687265663d22 + 687474703a2f2f7777773c2f613e3c6120687265663d22687474703a2f2f77e0 + b8a0e0b8b2e0b8a9e0b8b2e0b984e0b897e0b8a2e183a5e18390e183a0e18397 + e183a3e1839ae18398e6ada3e9ab94e4b8ade696872028e7b981e9ab9429e0a4 + a8e0a4bfe0a4b0e0a58de0a4a6e0a587e0a4b6e0a4a1e0a4bee0a489e0a4a8e0 + a4b2e0a58be0a4a1e0a495e0a58de0a4b7e0a587e0a4a4e0a58de0a4b0e0a49c + e0a4bee0a4a8e0a495e0a4bee0a4b0e0a580e0a4b8e0a482e0a4ace0a482e0a4 + a7e0a4bfe0a4a4e0a4b8e0a58de0a4a5e0a4bee0a4aae0a4a8e0a4bee0a4b8e0 + a58de0a4b5e0a580e0a495e0a4bee0a4b0e0a4b8e0a482e0a4b8e0a58de0a495 + e0a4b0e0a4a3e0a4b8e0a4bee0a4aee0a497e0a58de0a4b0e0a580e0a49ae0a4 + bfe0a49fe0a58de0a4a0e0a58be0a482e0a4b5e0a4bfe0a49ce0a58de0a49ee0 + a4bee0a4a8e0a485e0a4aee0a587e0a4b0e0a4bfe0a495e0a4bee0a4b5e0a4bf + e0a4ade0a4bfe0a4a8e0a58de0a4a8e0a497e0a4bee0a4a1e0a4bfe0a4afe0a4 + bee0a481e0a495e0a58de0a4afe0a58be0a482e0a495e0a4bfe0a4b8e0a581e0 + a4b0e0a495e0a58de0a4b7e0a4bee0a4aae0a4b9e0a581e0a481e0a49ae0a4a4 + e0a580e0a4aae0a58de0a4b0e0a4ace0a482e0a4a7e0a4a8e0a49fe0a4bfe0a4 + aae0a58de0a4aae0a4a3e0a580e0a495e0a58de0a4b0e0a4bfe0a495e0a587e0 + a49fe0a4aae0a58de0a4b0e0a4bee0a4b0e0a482e0a4ade0a4aae0a58de0a4b0 + e0a4bee0a4aae0a58de0a4a4e0a4aee0a4bee0a4b2e0a4bfe0a495e0a58be0a4 + 82e0a4b0e0a4abe0a4bce0a58de0a4a4e0a4bee0a4b0e0a4a8e0a4bfe0a4b0e0 + a58de0a4aee0a4bee0a4a3e0a4b2e0a4bfe0a4aee0a4bfe0a49fe0a587e0a4a1 + 6465736372697074696f6e2220636f6e74656e743d22646f63756d656e742e6c + 6f636174696f6e2e70726f742e676574456c656d656e747342795461674e616d + 65283c21444f43545950452068746d6c3e0a3c68746d6c203c6d657461206368 + 61727365743d227574662d38223e3a75726c2220636f6e74656e743d22687474 + 703a2f2f2e637373222072656c3d227374796c657368656574227374796c6520 + 747970653d22746578742f637373223e747970653d22746578742f6373732220 + 687265663d2277332e6f72672f313939392f7868746d6c2220786d6c74797065 + 3d22746578742f6a61766173637269707422206d6574686f643d226765742220 + 616374696f6e3d226c696e6b2072656c3d227374796c6573686565742220203d + 20646f63756d656e742e676574456c656d656e74747970653d22696d6167652f + 782d69636f6e22202f3e63656c6c70616464696e673d2230222063656c6c7370 + 2e6373732220747970653d22746578742f63737322203c2f613e3c2f6c693e3c + 6c693e3c6120687265663d22222077696474683d223122206865696768743d22 + 3122223e3c6120687265663d22687474703a2f2f7777772e7374796c653d2264 + 6973706c61793a6e6f6e653b223e616c7465726e6174652220747970653d2261 + 70706c692d2f2f5733432f2f445444205848544d4c20312e3020656c6c737061 + 63696e673d2230222063656c6c70616420747970653d2268696464656e222076 + 616c75653d222f613e266e6273703b3c7370616e20726f6c653d22730a3c696e + 70757420747970653d2268696464656e22206c616e67756167653d224a617661 + 536372697074222020646f63756d656e742e676574456c656d656e747342673d + 2230222063656c6c73706163696e673d223022207970653d22746578742f6373 + 7322206d656469613d22747970653d27746578742f6a61766173637269707427 + 776974682074686520657863657074696f6e206f66207970653d22746578742f + 637373222072656c3d227374206865696768743d2231222077696474683d2231 + 22203d272b656e636f6465555249436f6d706f6e656e74283c6c696e6b207265 + 6c3d22616c7465726e61746522200a626f64792c2074722c20696e7075742c20 + 746578746d657461206e616d653d22726f626f74732220636f6e6d6574686f64 + 3d22706f73742220616374696f6e3d223e0a3c6120687265663d22687474703a + 2f2f7777772e637373222072656c3d227374796c65736865657422203c2f6469 + 763e3c2f6469763e3c64697620636c6173736c616e67756167653d226a617661 + 736372697074223e617269612d68696464656e3d2274727565223ec2b73c7269 + 70742220747970653d22746578742f6a617661736c3d303b7d2928293b0a2866 + 756e6374696f6e28297b6261636b67726f756e642d696d6167653a2075726c28 + 2f613e3c2f6c693e3c6c693e3c6120687265663d226809093c6c693e3c612068 + 7265663d22687474703a2f2f61746f722220617269612d68696464656e3d2274 + 72753e203c6120687265663d22687474703a2f2f7777772e6c616e6775616765 + 3d226a61766173637269707422202f6f7074696f6e3e0a3c6f7074696f6e2076 + 616c75652f6469763e3c2f6469763e3c64697620636c6173733d7261746f7222 + 20617269612d68696464656e3d227472653d286e65772044617465292e676574 + 54696d652829706f7274756775c3aa732028646f2042726173696c29d0bed180 + d0b3d0b0d0bdd0b8d0b7d0b0d186d0b8d0b8d0b2d0bed0b7d0bcd0bed0b6d0bd + d0bed181d182d18cd0bed0b1d180d0b0d0b7d0bed0b2d0b0d0bdd0b8d18fd180 + d0b5d0b3d0b8d181d182d180d0b0d186d0b8d0b8d0b2d0bed0b7d0bcd0bed0b6 + d0bdd0bed181d182d0b8d0bed0b1d18fd0b7d0b0d182d0b5d0bbd18cd0bdd0b0 + 3c21444f43545950452068746d6c205055424c494320226e742d547970652220 + 636f6e74656e743d22746578742f3c6d65746120687474702d65717569763d22 + 436f6e746572616e736974696f6e616c2f2f454e222022687474703a3c68746d + 6c20786d6c6e733d22687474703a2f2f7777772d2f2f5733432f2f4454442058 + 48544d4c20312e3020544454442f7868746d6c312d7472616e736974696f6e61 + 6c2f2f7777772e77332e6f72672f54522f7868746d6c312f7065203d20277465 + 78742f6a617661736372697074273b3c6d657461206e616d653d226465736372 + 697074696f6e706172656e744e6f64652e696e736572744265666f72653c696e + 70757420747970653d2268696464656e22206e616a732220747970653d227465 + 78742f6a6176617363726928646f63756d656e74292e72656164792866756e63 + 746973637269707420747970653d22746578742f6a61766173696d6167652220 + 636f6e74656e743d22687474703a2f2f55412d436f6d70617469626c65222063 + 6f6e74656e743d746d6c3b20636861727365743d7574662d3822202f3e0a6c69 + 6e6b2072656c3d2273686f72746375742069636f6e3c6c696e6b2072656c3d22 + 7374796c65736865657422203c2f7363726970743e0a3c736372697074207479 + 70653d3d20646f63756d656e742e637265617465456c656d656e3c6120746172 + 6765743d225f626c616e6b2220687265663d20646f63756d656e742e67657445 + 6c656d656e747342696e70757420747970653d227465787422206e616d653d61 + 2e74797065203d2027746578742f6a617661736372696e70757420747970653d + 2268696464656e22206e616d6568746d6c3b20636861727365743d7574662d38 + 22202f3e647464223e0a3c68746d6c20786d6c6e733d22687474702d2f2f5733 + 432f2f4454442048544d4c20342e30312054656e747342795461674e616d6528 + 277363726970742729696e70757420747970653d2268696464656e22206e616d + 3c73637269707420747970653d22746578742f6a6176617322207374796c653d + 22646973706c61793a6e6f6e653b223e646f63756d656e742e676574456c656d + 656e7442794964283d646f63756d656e742e637265617465456c656d656e7428 + 2720747970653d27746578742f6a61766173637269707427696e707574207479 + 70653d227465787422206e616d653d22642e676574456c656d656e7473427954 + 61674e616d6528736e6963616c2220687265663d22687474703a2f2f7777772e + 432f2f4454442048544d4c20342e3031205472616e7369743c7374796c652074 + 7970653d22746578742f637373223e0a0a3c7374796c6520747970653d227465 + 78742f637373223e696f6e616c2e647464223e0a3c68746d6c20786d6c6e733d + 687474702d65717569763d22436f6e74656e742d5479706564696e673d223022 + 2063656c6c73706163696e673d22302268746d6c3b20636861727365743d7574 + 662d3822202f3e0a207374796c653d22646973706c61793a6e6f6e653b223e3c + 3c6c693e3c6120687265663d22687474703a2f2f7777772e20747970653d2774 + 6578742f6a617661736372697074273ed0b4d0b5d18fd182d0b5d0bbd18cd0bd + d0bed181d182d0b8d181d0bed0bed182d0b2d0b5d182d181d182d0b2d0b8d0b8 + d0bfd180d0bed0b8d0b7d0b2d0bed0b4d181d182d0b2d0b0d0b1d0b5d0b7d0be + d0bfd0b0d181d0bdd0bed181d182d0b8e0a4aae0a581e0a4b8e0a58de0a4a4e0 + a4bfe0a495e0a4bee0a495e0a4bee0a482e0a497e0a58de0a4b0e0a587e0a4b8 + e0a489e0a4a8e0a58de0a4b9e0a58be0a482e0a4a8e0a587e0a4b5e0a4bfe0a4 + a7e0a4bee0a4a8e0a4b8e0a4ade0a4bee0a4abe0a4bfe0a495e0a58de0a4b8e0 + a4bfe0a482e0a497e0a4b8e0a581e0a4b0e0a495e0a58de0a4b7e0a4bfe0a4a4 + e0a495e0a589e0a4aae0a580e0a4b0e0a4bee0a487e0a49fe0a4b5e0a4bfe0a4 + 9ce0a58de0a49ee0a4bee0a4aae0a4a8e0a495e0a4bee0a4b0e0a58de0a4b0e0 + a4b5e0a4bee0a488e0a4b8e0a495e0a58de0a4b0e0a4bfe0a4afe0a4a4e0a4be + + The number of words for each length is given by the following + bit-depth array: + + NDBITS := 0, 0, 0, 0, 10, 10, 11, 11, 10, 10, + 10, 10, 10, 9, 9, 8, 7, 7, 8, 7, + 7, 6, 6, 5, 5 +.fi + +.ti 0 +Appendix B. List of word transformations + +The string literals are in C format, with respect to the use of +backslash escape characters. + +In order to generate a length and check value, the transforms can be converted +to a series of bytes, where each transform is the prefix sequence of bytes plus +a terminating zero byte, a single byte value identifying the transform, and the +suffix sequence of bytes plus a terminating zero. The value for the transforms +are 0 for Identity, 1 for UppercaseFirst, 2 for UppercaseAll, 3 to 11 for +OmitFirst1 to OmitFirst9, and 12 to 20 for OmitLast1 to OmitLast9. The byte +sequences that represent the 121 transforms are then concatenated to a single +sequence of bytes. The length of that sequence is 648 bytes, and the zlib CRC +is 0x3d965f81. + +.nf + ID Prefix Transform Suffix + -- ------ --------- ------ + 0 "" Identity "" + 1 "" Identity " " + 2 " " Identity " " + 3 "" OmitFirst1 "" + 4 "" UppercaseFirst " " + 5 "" Identity " the " + 6 " " Identity "" + 7 "s " Identity " " + 8 "" Identity " of " + 9 "" UppercaseFirst "" + 10 "" Identity " and " + 11 "" OmitFirst2 "" + 12 "" OmitLast1 "" + 13 ", " Identity " " + 14 "" Identity ", " + 15 " " UppercaseFirst " " + 16 "" Identity " in " + 17 "" Identity " to " + 18 "e " Identity " " + 19 "" Identity "\\"" + 20 "" Identity "." + 21 "" Identity "\\">" + 22 "" Identity "\\n" + 23 "" OmitLast3 "" + 24 "" Identity "]" + 25 "" Identity " for " + 26 "" OmitFirst3 "" + 27 "" OmitLast2 "" + 28 "" Identity " a " + 29 "" Identity " that " + 30 " " UppercaseFirst "" + 31 "" Identity ". " + 32 "." Identity "" + 33 " " Identity ", " + 34 "" OmitFirst4 "" + 35 "" Identity " with " + 36 "" Identity "'" + 37 "" Identity " from " + 38 "" Identity " by " + 39 "" OmitFirst5 "" + 40 "" OmitFirst6 "" + 41 " the " Identity "" + 42 "" OmitLast4 "" + 43 "" Identity ". The " + 44 "" UppercaseAll "" + 45 "" Identity " on " + 46 "" Identity " as " + 47 "" Identity " is " + 48 "" OmitLast7 "" + 49 "" OmitLast1 "ing " + 50 "" Identity "\\n\\t" + 51 "" Identity ":" + 52 " " Identity ". " + 53 "" Identity "ed " + 54 "" OmitFirst9 "" + 55 "" OmitFirst7 "" + 56 "" OmitLast6 "" + 57 "" Identity "(" + 58 "" UppercaseFirst ", " + 59 "" OmitLast8 "" + 60 "" Identity " at " + 61 "" Identity "ly " + 62 " the " Identity " of " + 63 "" OmitLast5 "" + 64 "" OmitLast9 "" + 65 " " UppercaseFirst ", " + 66 "" UppercaseFirst "\\"" + 67 "." Identity "(" + 68 "" UppercaseAll " " + 69 "" UppercaseFirst "\\">" + 70 "" Identity "=\\"" + 71 " " Identity "." + 72 ".com/" Identity "" + 73 " the " Identity " of the " + 74 "" UppercaseFirst "'" + 75 "" Identity ". This " + 76 "" Identity "," + 77 "." Identity " " + 78 "" UppercaseFirst "(" + 79 "" UppercaseFirst "." + 80 "" Identity " not " + 81 " " Identity "=\\"" + 82 "" Identity "er " + 83 " " UppercaseAll " " + 84 "" Identity "al " + 85 " " UppercaseAll "" + 86 "" Identity "='" + 87 "" UppercaseAll "\\"" + 88 "" UppercaseFirst ". " + 89 " " Identity "(" + 90 "" Identity "ful " + 91 " " UppercaseFirst ". " + 92 "" Identity "ive " + 93 "" Identity "less " + 94 "" UppercaseAll "'" + 95 "" Identity "est " + 96 " " UppercaseFirst "." + 97 "" UppercaseAll "\\">" + 98 " " Identity "='" + 99 "" UppercaseFirst "," + 100 "" Identity "ize " + 101 "" UppercaseAll "." + 102 "\\xc2\\xa0" Identity "" + 103 " " Identity "," + 104 "" UppercaseFirst "=\\"" + 105 "" UppercaseAll "=\\"" + 106 "" Identity "ous " + 107 "" UppercaseAll ", " + 108 "" UppercaseFirst "='" + 109 " " UppercaseFirst "," + 110 " " UppercaseAll "=\\"" + 111 " " UppercaseAll ", " + 112 "" UppercaseAll "," + 113 "" UppercaseAll "(" + 114 "" UppercaseAll ". " + 115 " " UppercaseAll "." + 116 "" UppercaseAll "='" + 117 " " UppercaseAll ". " + 118 " " UppercaseFirst "=\\"" + 119 " " UppercaseAll "='" + 120 " " UppercaseFirst "='" +.fi +.in 3 + + +.ti 0 +Authors' Addresses + +.nf +Jyrki Alakuijala +Google, Inc + +Email: jyrki@google.com + + +Zoltan Szabadka +Google, Inc + +Email: szabadka@google.com +.fi + diff --git a/web/server/h2o/libh2o/deps/brotli/docs/draft-alakuijala-brotli-08.txt b/web/server/h2o/libh2o/deps/brotli/docs/draft-alakuijala-brotli-08.txt new file mode 100644 index 00000000..e1191361 --- /dev/null +++ b/web/server/h2o/libh2o/deps/brotli/docs/draft-alakuijala-brotli-08.txt @@ -0,0 +1,6723 @@ + + + + + + +Network Working Group J. Alakuijala +Internet-Draft Z. Szabadka +Intended Status: Informational Google, Inc +Expires: June 10, 2016 December 2015 + + + Brotli Compressed Data Format + draft-alakuijala-brotli-08 + +Abstract + + This specification defines a lossless compressed data format that + compresses data using a combination of the LZ77 algorithm and Huffman + coding, with efficiency comparable to the best currently available + general-purpose compression methods. + +Status of this Memo + + This Internet-Draft is submitted in full conformance with the + provisions of BCP 78 and BCP 79. + + Internet-Drafts are working documents of the Internet Engineering + Task Force (IETF). Note that other groups may also distribute + working documents as Internet-Drafts. The list of current Internet- + Drafts is at http://datatracker.ietf.org/drafts/current/. + + Internet-Drafts are draft documents valid for a maximum of six months + and may be updated, replaced, or obsoleted by other documents at any + time. It is inappropriate to use Internet-Drafts as reference + material or to cite them other than as "work in progress." + + This Internet-Draft will expire on June 10, 2016. + +Copyright Notice + + Copyright (c) 2015 IETF Trust and the persons identified as the + document authors. All rights reserved. + + This document is subject to BCP 78 and the IETF Trust's Legal + Provisions Relating to IETF Documents + (http://trustee.ietf.org/license-info) in effect on the date of + publication of this document. Please review these documents + carefully, as they describe your rights and restrictions with respect + to this document. Code Components extracted from this document must + include Simplified BSD License text as described in Section 4.e of + the Trust Legal Provisions and are provided without warranty as + described in the Simplified BSD License. + + + + +Alakuijala & Szabadka Expires June 10, 2016 [Page 1] + +Internet-Draft Brotli December 2015 + + +Table of Contents + + 1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . . 3 + 1.1. Purpose . . . . . . . . . . . . . . . . . . . . . . . . . 3 + 1.2. Intended audience . . . . . . . . . . . . . . . . . . . . 3 + 1.3. Scope . . . . . . . . . . . . . . . . . . . . . . . . . . 3 + 1.4. Compliance . . . . . . . . . . . . . . . . . . . . . . . . 4 + 1.5. Definitions of terms and conventions used . . . . . . . . 4 + 1.5.1. Packing into bytes . . . . . . . . . . . . . . . . . 4 + 2. Compressed representation overview . . . . . . . . . . . . . . 5 + 3. Compressed representation of prefix codes . . . . . . . . . . . 9 + 3.1. Introduction to prefix coding . . . . . . . . . . . . . . 9 + 3.2. Use of prefix coding in the brotli format . . . . . . . . 10 + 3.3. Alphabet sizes . . . . . . . . . . . . . . . . . . . . . 12 + 3.4. Simple prefix codes . . . . . . . . . . . . . . . . . . . 13 + 3.5. Complex prefix codes . . . . . . . . . . . . . . . . . . 14 + 4. Encoding of distances . . . . . . . . . . . . . . . . . . . . 16 + 5. Encoding of literal insertion lengths and copy lengths . . . . 18 + 6. Encoding of block switch commands . . . . . . . . . . . . . . 20 + 7. Context modeling . . . . . . . . . . . . . . . . . . . . . . . 22 + 7.1. Context modes and context ID lookup for literals . . . . 22 + 7.2. Context ID for distances . . . . . . . . . . . . . . . . 24 + 7.3. Encoding of the context map . . . . . . . . . . . . . . . 24 + 8. Static dictionary . . . . . . . . . . . . . . . . . . . . . . 26 + 9. Compressed data format . . . . . . . . . . . . . . . . . . . . 28 + 9.1. Format of the stream header . . . . . . . . . . . . . . . 29 + 9.2. Format of the meta-block header . . . . . . . . . . . . . 29 + 9.3. Format of the meta-block data . . . . . . . . . . . . . . 32 + 10. Decoding algorithm . . . . . . . . . . . . . . . . . . . . . 33 + 11. Security Considerations . . . . . . . . . . . . . . . . . . . 36 + 12. IANA Considerations . . . . . . . . . . . . . . . . . . . . . 36 + 13. Informative References . . . . . . . . . . . . . . . . . . . 36 + 14. Source code . . . . . . . . . . . . . . . . . . . . . . . . . 37 + 15. Acknowledgments . . . . . . . . . . . . . . . . . . . . . . . 37 + Appendix A. Static dictionary data . . . . . . . . . . . . . . . 37 + Appendix B. List of word transformations . . . . . . . . . . . . 117 + Authors' Addresses . . . . . . . . . . . . . . . . . . . . . . . 120 + + + + + + + + + + + + + + +Alakuijala & Szabadka Expires June 10, 2016 [Page 2] + +Internet-Draft Brotli December 2015 + + +1. Introduction + +1.1. Purpose + + The purpose of this specification is to define a lossless compressed + data format that: + + * Is independent of CPU type, operating system, file system, + and character set, and hence can be used for interchange; + * Can be produced or consumed, even for an arbitrarily long + sequentially presented input data stream, using only an a + priori bounded amount of intermediate storage, and hence + can be used in data communications or similar structures, + such as Unix filters; + * Compresses data with a compression ratio comparable to the + best currently available general-purpose compression methods, + and in particular, considerably better than the gzip program; + * Decompresses much faster than current LZMA implementations. + + The data format defined by this specification does not attempt to: + + * Allow random access to compressed data; + * Compress specialized data (e.g., raster graphics) as well + as the best currently available specialized algorithms. + +1.2. Intended audience + + This specification is intended for use by software implementers to + compress data into and/or decompress data from the brotli format. + + The text of the specification assumes a basic background in + programming at the level of bits and other primitive data + representations. Familiarity with the technique of Huffman coding is + helpful but not required. + + This specification uses heavily the notations and terminology + introduced in the DEFLATE format specification [RFC 1951]. For the + sake of completeness, we always include the whole text of the + relevant parts of RFC 1951, therefore familiarity with the DEFLATE + format is helpful but not required. + + The compressed data format defined in this specification is an + integral part of the WOFF 2.0 web font file format [WOFF2], therefore + this specification is also intended for implementers of WOFF 2.0 + compressors and decompressors. + +1.3. Scope + + + + +Alakuijala & Szabadka Expires June 10, 2016 [Page 3] + +Internet-Draft Brotli December 2015 + + + The specification specifies a method for representing a sequence of + bytes as a (usually shorter) sequence of bits, and a method for + packing the latter bit sequence into bytes. + +1.4. Compliance + + Unless otherwise indicated below, a compliant decompressor must be + able to accept and decompress any data set that conforms to all the + specifications presented here. A compliant compressor must produce + data sets that conform to all the specifications presented here. + +1.5. Definitions of terms and conventions used + + Byte: 8 bits stored or transmitted as a unit (same as an octet). For + this specification, a byte is exactly 8 bits, even on machines that + store a character on a number of bits different from eight. See + below for the numbering of bits within a byte. + + String: a sequence of arbitrary bytes. + + Bytes stored within a computer do not have a "bit order", since they + are always treated as a unit. However, a byte considered as an + integer between 0 and 255 does have a most- and least-significant + bit, and since we write numbers with the most-significant digit on + the left, we also write bytes with the most-significant bit on the + left. In the diagrams below, we number the bits of a byte so that bit + 0 is the least-significant bit, i.e., the bits are numbered: + + +--------+ + |76543210| + +--------+ + + Within a computer, a number may occupy multiple bytes. All multi-byte + numbers in the format described here are stored with the least- + significant byte first (at the lower memory address). For example, + the decimal number 520 is stored as: + + 0 1 + +--------+--------+ + |00001000|00000010| + +--------+--------+ + ^ ^ + | | + | + more significant byte = 2 x 256 + + less significant byte = 8 + +1.5.1. Packing into bytes + + + + +Alakuijala & Szabadka Expires June 10, 2016 [Page 4] + +Internet-Draft Brotli December 2015 + + + This document does not address the issue of the order in which bits + of a byte are transmitted on a bit-sequential medium, since the final + data format described here is byte- rather than bit-oriented. + However, we describe the compressed block format below as a sequence + of data elements of various bit lengths, not a sequence of bytes. We + must therefore specify how to pack these data elements into bytes to + form the final compressed byte sequence: + + * Data elements are packed into bytes in order of + increasing bit number within the byte, i.e., starting + with the least-significant bit of the byte. + * Data elements other than prefix codes are packed + starting with the least-significant bit of the data + element. These are referred to here as integer values + and are considered unsigned. + * Prefix codes are packed starting with the most-significant + bit of the code. + + In other words, if one were to print out the compressed data as a + sequence of bytes, starting with the first byte at the *right* margin + and proceeding to the *left*, with the most-significant bit of each + byte on the left as usual, one would be able to parse the result from + right to left, with fixed-width elements in the correct MSB-to-LSB + order and prefix codes in bit-reversed order (i.e., with the first + bit of the code in the relative LSB position). + +2. Compressed representation overview + + A compressed data set consists of a header and a series of meta- + blocks. Each meta-block decompresses to a sequence of 0 to 16,777,216 + (16 MiB) uncompressed bytes. The final uncompressed data is the + concatenation of the uncompressed sequences from each meta-block. + + The header contains the size of the sliding window that was used + during compression. The decompressor must retain at least that + amount of uncompressed data prior to the current position in the + stream, in order to be able to decompress what follows. The sliding + window size is a power of two, minus 16, where the power is in the + range of 10 to 24. The possible sliding window sizes range from 1 KiB + - 16 B to 16 MiB - 16 B. + + Each meta-block is compressed using a combination of the LZ77 + algorithm (Lempel-Ziv 1977, [LZ77]) and Huffman coding. The result of + Huffman coding is referred to here as a prefix code. The prefix + codes for each meta-block are independent of those for previous or + subsequent meta-blocks; the LZ77 algorithm may use a reference to a + duplicated string occurring in a previous meta-block, up to the + sliding window size of uncompressed bytes before. In addition, in + + + +Alakuijala & Szabadka Expires June 10, 2016 [Page 5] + +Internet-Draft Brotli December 2015 + + + the brotli format, a string reference may instead refer to a static + dictionary entry. + + Each meta-block consists of two parts: a meta-block header that + describes the representation of the compressed data part, and a + compressed data part. The compressed data consists of a series of + commands. Each command consists of two parts: a sequence of literal + bytes (of strings that have not been detected as duplicated within + the sliding window), and a pointer to a duplicated string, + represented as a pair . There can be zero + literal bytes in the command. The minimum length of the string to be + duplicated is two, but the last command in the meta-block is + permitted to have only literals and no pointer to a string to + duplicate. + + Each command in the compressed data is represented using three + categories of prefix codes: + + 1) One set of prefix codes are for the literal sequence lengths + (also referred to as literal insertion lengths) and + backward copy lengths. That is, a single code word represents + two lengths, one of the literal sequence and one of the + backward copy. + + 2) One set of prefix codes are for literals. + + 3) One set of prefix codes are for distances. + + The prefix code descriptions for each meta-block appear in a compact + form just before the compressed data in the meta-block header. The + insert-and-copy length and distance prefix codes may be followed by + extra bits that are added to the base values determined by the codes. + The number of extra bits is determined by the code. + + One meta-block command then appears as a sequence of prefix codes: + + Insert-and-copy length, literal, literal, ..., literal, distance + + where the insert-and-copy defines an insertion length and a copy + length. The insertion length determines the number of literals that + immediately follow. The distance defines how far back to go for the + copy and the copy length determines the number of bytes to copy. The + resulting uncompressed data is the sequence of bytes: + + literal, literal, ..., literal, copy, copy, ..., copy + + where the number of literal bytes and copy bytes are determined by + the insert-and-copy length code. (The number of bytes copied for a + + + +Alakuijala & Szabadka Expires June 10, 2016 [Page 6] + +Internet-Draft Brotli December 2015 + + + static dictionary entry can vary from the copy length.) + + The last command in the meta-block may end with the last literal if + the total uncompressed length of the meta-block has been satisfied. + In that case there is no distance in the last command, and the copy + length is ignored. + + There can be more than one prefix code for each category, where the + prefix code to use for the next element of that category is + determined by the context of the compressed stream that precedes that + element. Part of that context is three current block types, one for + each category. A block type is in the range of 0..255. For each + category there is a count of how many elements of that category + remain to be decoded using the current block type. Once that count is + expended, a new block type and block count is read from the stream + immediately preceding the next element of that category, which will + use the new block type. + + The insert-and-copy block type directly determines which prefix code + to use for the next insert-and-copy element. For the literal and + distance elements, the respective block type is used in combination + with other context information to determine which prefix code to use + for the next element. + + Consider the following example: + + (IaC0, L0, L1, L2, D0)(IaC1, D1)(IaC2, L3, L4, D2)(IaC3, L5, D3) + + The meta-block here has four commands, contained in parentheses for + clarity, where each of the three categories of symbols within these + commands can be interpreted using different block types. Here we + separate out each category as its own sequence to show an example of + block types assigned to those elements. Each square-bracketed group + is a block that uses the same block type: + + [IaC0, IaC1][IaC2, IaC3] <-- insert-and-copy: block types 0 and 1 + + [L0, L1][L2, L3, L4][L5] <-- literals: block types 0, 1, and 0 + + [D0][D1, D2, D3] <-- distances: block types 0 and 1 + + The subsequent blocks within each block category must have different + block types, but we see that block types can be reused later in the + meta-block. The block types are numbered from 0 to the maximum block + type number of 255 and the first block of each block category is type + 0. The block structure of a meta-block is represented by the sequence + of block-switch commands for each block category, where a block- + switch command is a pair . The block-switch + + + +Alakuijala & Szabadka Expires June 10, 2016 [Page 7] + +Internet-Draft Brotli December 2015 + + + commands are represented in the compressed data before the start of + each new block using a prefix code for block types and a separate + prefix code for block counts for each block category. For the above + example the physical layout of the meta-block is then: + + IaC0 L0 L1 LBlockSwitch(1, 3) L2 D0 IaC1 DBlockSwitch(1, 3) D1 + IaCBlockSwitch(1, 2) IaC2 L3 L4 D2 IaC3 LBlockSwitch(0, 1) L5 D3 + + where xBlockSwitch(t, n) switches to block type t for a count of n + elements. Note that in this example DBlockSwitch(1, 3) immediately + precedes the next required distance D1. It does not follow the last + distance of the previous block, D0. Whenever an element of a category + is needed, and the block count for that category has reached zero, + then a new block type and count is read from the stream just before + reading that next element. + + The block-switch commands for the first blocks of each category are + not part of the meta-block compressed data. Instead the first block + type is defined to be 0, and the first block count for each category + is encoded in the meta-block header. The prefix codes for the block + types and counts, a total of six prefix codes over the three + categories, are defined in a compact form in the meta-block header. + + Each category of value (insert-and-copy lengths, literals, and + distances) can be encoded with any prefix code from a collection of + prefix codes belonging to the same category appearing in the meta- + block header. The particular prefix code used can depend on two + factors: the block type of the block the value appears in, and the + context of the value. In the case of the literals, the context is + the previous two bytes in the uncompressed data, and in the case of + distances, the context is the copy length from the same command. For + insert-and-copy lengths, no context is used and the prefix code + depends only on the block type. In the case of literals and + distances, the context is mapped to a context ID in the range 0..63 + for literals and 0..3 for distances. The matrix of the prefix code + indexes for each block type and context ID, called the context map, + is encoded in a compact form in the meta-block header. + + For example, the prefix code to use to decode L2 depends on the block + type (1), and the literal context ID determined by the two + uncompressed bytes that were decoded from L0 and L1. Similarly, the + prefix code to use to decode D0 depends on the block type (0), and + the distance context ID determined by the copy length decoded from + IaC0. The prefix code to use to decode IaC3 depends only on the block + type (1). + + In addition to the parts listed above (prefix code for insert-and- + copy lengths, literals, distances, block types and block counts, and + + + +Alakuijala & Szabadka Expires June 10, 2016 [Page 8] + +Internet-Draft Brotli December 2015 + + + the context map), the meta-block header contains the number of + uncompressed bytes coded in the meta-block and two additional + parameters used in the representation of match distances: the number + of postfix bits and the number of direct distance codes. + + A compressed meta-block may be marked in the header as the last meta- + block, which terminates the compressed stream. + + A meta-block may instead simply store the uncompressed data directly + as bytes on byte boundaries with no coding or matching strings. In + this case the meta-block header information only contains the number + of uncompressed bytes and the indication that the meta-block is + uncompressed. An uncompressed meta-block cannot be the last meta- + block. + + A meta-block may also be empty, which generates no uncompressed data + at all. An empty meta-block may contain metadata information as + bytes starting on byte boundaries, which are not part of either the + sliding window or the uncompressed data. Thus, these metadata bytes + cannot be used to create matching strings in subsequent meta-blocks + and are not used as context bytes for literals. + +3. Compressed representation of prefix codes + +3.1. Introduction to prefix coding + + Prefix coding represents symbols from an a priori known alphabet by + bit sequences (codes), one code for each symbol, in a manner such + that different symbols may be represented by bit sequences of + different lengths, but a parser can always parse an encoded string + unambiguously symbol-by-symbol. + + We define a prefix code in terms of a binary tree in which the two + edges descending from each non-leaf node are labeled 0 and 1 and in + which the leaf nodes correspond one-for-one with (are labeled with) + the symbols of the alphabet; then the code for a symbol is the + sequence of 0's and 1's on the edges leading from the root to the + leaf labeled with that symbol. For example: + + + + + + + + + + + + + +Alakuijala & Szabadka Expires June 10, 2016 [Page 9] + +Internet-Draft Brotli December 2015 + + + /\ Symbol Code + 0 1 ------ ---- + / \ A 00 + /\ B B 1 + 0 1 C 011 + / \ D 010 + A /\ + 0 1 + / \ + D C + + A parser can decode the next symbol from the compressed stream by + walking down the tree from the root, at each step choosing the edge + corresponding to the next compressed data bit. + + Given an alphabet with known symbol frequencies, the Huffman + algorithm allows the construction of an optimal prefix code (one + which represents strings with those symbol frequencies using the + fewest bits of any possible prefix codes for that alphabet). Such a + prefix code is called a Huffman code. (See [HUFFMAN] in Chapter 5, + references for additional information on Huffman codes.) + + Note that in the brotli format, the prefix codes for the various + alphabets must not exceed certain maximum code lengths. This + constraint complicates the algorithm for computing code lengths from + symbol frequencies. Again, see Chapter 5, references for details. + +3.2. Use of prefix coding in the brotli format + + The prefix codes used for each alphabet in the brotli format are + canonical prefix codes, which have two additional rules: + + * All codes of a given bit length have lexicographically + consecutive values, in the same order as the symbols they + represent; + + * Shorter codes lexicographically precede longer codes. + + We could recode the example above to follow this rule as follows, + assuming that the order of the alphabet is ABCD: + + Symbol Code + ------ ---- + A 10 + B 0 + C 110 + D 111 + + + + +Alakuijala & Szabadka Expires June 10, 2016 [Page 10] + +Internet-Draft Brotli December 2015 + + + I.e., 0 precedes 10, which precedes 11x, and 110 and 111 are + lexicographically consecutive. + + Given this rule, we can define the canonical prefix code for an + alphabet just by giving the bit lengths of the codes for each symbol + of the alphabet in order; this is sufficient to determine the actual + codes. In our example, the code is completely defined by the sequence + of bit lengths (2, 1, 3, 3). The following algorithm generates the + codes as integers, intended to be read from most- to least- + significant bit. The code lengths are initially in tree[I].Len; the + codes are produced in tree[I].Code. + + 1) Count the number of codes for each code length. Let + bl_count[N] be the number of codes of length N, N >= 1. + + 2) Find the numerical value of the smallest code for each + code length: + + code = 0; + bl_count[0] = 0; + for (bits = 1; bits <= MAX_BITS; bits++) { + code = (code + bl_count[bits-1]) << 1; + next_code[bits] = code; + } + + 3) Assign numerical values to all codes, using consecutive + values for all codes of the same length with the base + values determined at step 2. Codes that are never used + (which have a bit length of zero) must not be assigned a + value. + + for (n = 0; n <= max_code; n++) { + len = tree[n].Len; + if (len != 0) { + tree[n].Code = next_code[len]; + next_code[len]++; + } + } + + Example: + + Consider the alphabet ABCDEFGH, with bit lengths (3, 3, 3, 3, 3, 2, + 4, 4). After step 1, we have: + + + + + + + + +Alakuijala & Szabadka Expires June 10, 2016 [Page 11] + +Internet-Draft Brotli December 2015 + + + N bl_count[N] + - ----------- + 2 1 + 3 5 + 4 2 + + Step 2 computes the following next_code values: + + N next_code[N] + - ------------ + 1 0 + 2 0 + 3 2 + 4 14 + + Step 3 produces the following code values: + + Symbol Length Code + ------ ------ ---- + A 3 010 + B 3 011 + C 3 100 + D 3 101 + E 3 110 + F 2 00 + G 4 1110 + H 4 1111 + +3.3. Alphabet sizes + + Prefix codes are used for different purposes in the brotli format, + and each purpose has a different alphabet size. For literal codes the + alphabet size is 256. For insert-and-copy length codes the alphabet + size is 704. For block count codes, the alphabet size is 26. For + distance codes, block type codes, and the prefix codes used in + compressing the context map, the alphabet size is dynamic and is + based on parameters defined in later sections. The following table + summarizes the alphabet sizes for the various prefix codes and the + sections where they are defined. + + + + + + + + + + + + +Alakuijala & Szabadka Expires June 10, 2016 [Page 12] + +Internet-Draft Brotli December 2015 + + + +-----------------+-------------------------+------------+ + | Prefix code | Alphabet size | Definition | + +-----------------+-------------------------+------------+ + | literal | 256 | | + +-----------------+-------------------------+------------+ + | distance | 16 + NDIRECT + | Section 4. | + | | (48 << NPOSTFIX) | | + +-----------------+-------------------------+------------+ + | insert-and-copy | 704 | Section 5. | + | length | | | + +-----------------+-------------------------+------------+ + | block count | 26 | Section 6. | + +-----------------+-------------------------+------------+ + | block type | NBLTYPESx + 2, | Section 6. | + | | (where x is I, L, or D) | | + +-----------------+-------------------------+------------+ + | context map | NTREESx + RLEMAXx | Section 7. | + | | (where x is L or D) | | + +-----------------+-------------------------+------------+ + +3.4. Simple prefix codes + + The first two bits of the compressed representation of each prefix + code distinguish between simple and complex prefix codes. If this + value is 1, then a simple prefix code follows as described in this + section. Otherwise, a complex prefix code follows as described in + Section 3.5. + + A simple prefix code can have only up to four symbols with non-zero + code length. The format of the simple prefix code is as follows: + + 2 bits: value of 1 indicates a simple prefix code + 2 bits: NSYM - 1, where NSYM = # of symbols coded + + NSYM symbols, each encoded using ALPHABET_BITS bits + + 1 bit: tree-select, present only for NSYM = 4 + + The value of ALPHABET_BITS depends on the alphabet of the prefix + code: it is the smallest number of bits that can represent all + symbols in the alphabet. E.g. for the alphabet of literal bytes, + ALPHABET_BITS is 8. The value of each of the NSYM symbols above is + the value of the ALPHABETS_BITS width integer value. If the integer + value is greater than or equal to the alphabet size, or the value is + identical to a previous value, then the stream should be rejected as + invalid. + + Note that the NSYM symbols may not be presented in sorted order. + + + +Alakuijala & Szabadka Expires June 10, 2016 [Page 13] + +Internet-Draft Brotli December 2015 + + + Prefix codes of the same bit length must be assigned to the symbols + in sorted order. + + The (non-zero) code lengths of the symbols can be reconstructed as + follows: + + * if NSYM = 1, the code length for the one symbol is zero -- + when encoding this symbol in the + compressed data stream using this prefix code, no + actual bits are emitted. Similarly, when decoding a symbol + using this prefix code, no bits are read and the one symbol + is returned. + + * if NSYM = 2, both symbols have code length 1. + + * if NSYM = 3, the code lengths for the symbols are 1, 2, 2 in + the order they appear in the representation of the simple + prefix code. + + * if NSYM = 4, the code lengths (in order of symbols decoded) + depend on the tree-select bit: 2, 2, 2, 2 (tree-select bit 0), + or 1, 2, 3, 3 (tree-select bit 1). + +3.5. Complex prefix codes + + A complex prefix code is a canonical prefix code, defined by the + sequence of code lengths, as discussed in Section 3.2., above. For + even greater compactness, the code length sequences themselves are + compressed using a prefix code. The alphabet for code lengths is as + follows: + + 0 - 15: Represent code lengths of 0 - 15 + 16: Copy the previous non-zero code length 3 - 6 times + The next 2 bits indicate repeat length + (0 = 3, ... , 3 = 6) + If this is the first code length, or all previous + code lengths are zero, a code length of 8 is + repeated 3 - 6 times + A repeated code length code of 16 modifies the + repeat count of the previous one as follows: + repeat count = (4 * (repeat count - 2)) + + (3 - 6 on the next 2 bits) + Example: Codes 7, 16 (+2 bits 11), 16 (+2 bits 10) + will expand to 22 code lengths of 7 + (1 + 4 * (6 - 2) + 5) + 17: Repeat a code length of 0 for 3 - 10 times. + (3 bits of length) + A repeated code length code of 17 modifies the + + + +Alakuijala & Szabadka Expires June 10, 2016 [Page 14] + +Internet-Draft Brotli December 2015 + + + repeat count of the previous one as follows: + repeat count = (8 * (repeat count - 2)) + + (3 - 10 on the next 3 bits) + + Note that a code of 16 that follows an immediately preceding 16 + modifies the previous repeat count, which becomes the new repeat + count. The same is true for a 17 following a 17. A sequence of three + or more 16 codes in a row or three of more 17 codes in a row is + possible, modifying the count each time. Only the final repeat count + is used. The modification only applies if the same code follows. A 16 + repeat does not modify an immediately preceding 17 count nor vice + versa. + + A code length of 0 indicates that the corresponding symbol in the + alphabet will not occur in the compressed data, and should not + participate in the prefix code construction algorithm given earlier. + A complex prefix code must have at least two non-zero code lengths. + + The bit lengths of the prefix code over the code length alphabet are + compressed with the following variable length code (as it appears in + the compressed data, where the bits are parsed from right to left): + + Symbol Code + ------ ---- + 0 00 + 1 0111 + 2 011 + 3 10 + 4 01 + 5 1111 + + We can now define the format of the complex prefix code as follows: + + 2 bits: HSKIP, values of 0, 2, or 3 represent the respective + number of skipped code lengths. The skipped lengths + are taken to be zero. (An HSKIP of 1 indicates a + Simple prefix code.) + + Code lengths for symbols in the code length alphabet given + just above, in the order: 1, 2, 3, 4, 0, 5, 17, 6, 16, 7, + 8, 9, 10, 11, 12, 13, 14, 15. If HSKIP is 2, then the + code lengths for symbols 1 and 2 are zero, and the first + code length is for symbol 3. If HSKIP is 3, then the code + length for symbol 3 is also zero, and the first code length + is for symbol 4. + + The code lengths of code length symbols are between 0 and + 5, and they are represented with 2 - 4 bits according to + + + +Alakuijala & Szabadka Expires June 10, 2016 [Page 15] + +Internet-Draft Brotli December 2015 + + + the variable length code above. A code length of 0 means + the corresponding code length symbol is not used. + + If HSKIP is 2 or 3, a respective number of leading code + lengths are implicit zeros and are not present in the + code lengths sequence above. + + If there are at least two non-zero code lengths, any + trailing zero code lengths are omitted, i.e. the last + code length in the sequence must be non-zero. In this + case, the sum of (32 >> code length) over all the non-zero + code lengths must equal to 32. + + If the lengths have been read for the entire code length + alphabet and there was only one non-zero code length, + then the prefix code has one symbol whose code has zero + length. In this case, that symbol results in no bits + being emitted by the compressor, and no bits consumed by + the decompressor. That single symbol is immediately + returned when this code is decoded. + An example of where this occurs is if the + entire code to be represented has symbols of length 8. + E.g. a literal code that represents all literal values + with equal probability. In this case the single symbol + is 16, which repeats the previous length. The previous + length is taken to be 8 before any code length code + lengths are read. + + Sequence of at most alphabet size code lengths symbols, encoded + using the code length prefix code. Any trailing 0 or 17 must be + omitted, i.e. the last encoded code length symbol must be + between 1 and 16. The sum of (32768 >> code length) over + all the non-zero code lengths in the alphabet, including + those encoded using repeat code(s) of 16, must equal to + 32768. If the number of times to repeat the previous length + or repeat a zero length would result in more lengths in + total than the number of symbols in the alphabet, then the + stream should be rejected as invalid. + +4. Encoding of distances + + As described in Section 2., one component of a compressed meta-block + is a sequence of backward distances. In this section we provide the + details to the encoding of distances. + + Each distance in the compressed data part of a meta-block is + represented with a pair . The distance + code and the extra bits are encoded back-to-back, the distance code + + + +Alakuijala & Szabadka Expires June 10, 2016 [Page 16] + +Internet-Draft Brotli December 2015 + + + is encoded using a prefix code over the distance alphabet, while the + extra bits value is encoded as a fixed-width integer value. The + number of extra bits can be 0 - 24, and it is dependent on the + distance code. + + To convert a distance code and associated extra bits to a backward + distance, we need the sequence of past distances and two additional + parameters, the number of "postfix bits", denoted by NPOSTFIX (0..3), + and the number of direct distance codes, denoted by NDIRECT (0..120). + Both of these parameters are encoded in the meta-block header. We + will also use the following derived parameter: + + POSTFIX_MASK = (1 << NPOSTFIX) - 1 + + The first 16 distance symbols are special symbols that reference past + distances as follows: + + 0: last distance + 1: second-to-last distance + 2: third-to-last distance + 3: fourth-to-last distance + 4: last distance - 1 + 5: last distance + 1 + 6: last distance - 2 + 7: last distance + 2 + 8: last distance - 3 + 9: last distance + 3 + 10: second-to-last distance - 1 + 11: second-to-last distance + 1 + 12: second-to-last distance - 2 + 13: second-to-last distance + 2 + 14: second-to-last distance - 3 + 15: second-to-last distance + 3 + + The ring buffer of four last distances is initialized by the values + 16, 15, 11, and 4 (i.e. the fourth-to-last is set to 16, the third- + to-last to 15, the second-to-last to 11, and the last distance to 4) + at the beginning of the *stream* (as opposed to the beginning of the + meta-block) and it is not reset at meta-block boundaries. When a + distance symbol 0 appears, the distance it represents (i.e. the last + distance in the sequence of distances) is not pushed to the ring + buffer of last distances, in other words, the expression "(second, + third, fourth)-to-last distance" means the (second, third, + fourth)-to-last distance that was not represented by a 0 distance + symbol. Similarly, distances that represent static dictionary words + (see Section 8.) are not pushed to the ring buffer of last distances. + + If a special distance symbol resolves to a zero or negative value, + + + +Alakuijala & Szabadka Expires June 10, 2016 [Page 17] + +Internet-Draft Brotli December 2015 + + + the stream should be rejected as invalid. + + If NDIRECT is greater than zero, then the next NDIRECT distance + symbols, from 16 to 15 + NDIRECT, represent distances from 1 to + NDIRECT. Neither the special distance symbols, nor the NDIRECT + direct distance symbols are followed by any extra bits. + + Distance symbols 16 + NDIRECT and greater all have extra bits, where + the number of extra bits for a distance symbol "dcode" is given by + the following formula: + + ndistbits = 1 + ((dcode - NDIRECT - 16) >> (NPOSTFIX + 1)) + + The maximum number of extra bits is 24, therefore the size of the + distance symbol alphabet is (16 + NDIRECT + (48 << NPOSTFIX)). + + Given a distance symbol "dcode" (>= 16 + NDIRECT), and extra bits + "dextra", the backward distance is given by the following formula: + + hcode = (dcode - NDIRECT - 16) >> NPOSTFIX + lcode = (dcode - NDIRECT - 16) & POSTFIX_MASK + offset = ((2 + (hcode & 1)) << ndistbits) - 4 + distance = ((offset + dextra) << NPOSTFIX) + lcode + NDIRECT + 1 + +5. Encoding of literal insertion lengths and copy lengths + + As described in Section 2., the literal insertion lengths and + backward copy lengths are encoded using a single prefix code. This + section provides the details to this encoding. + + Each pair in the compressed data part + of a meta-block is represented with the following triplet: + + + + The insert-and-copy length code, the insert extra bits, and the copy + extra bits are encoded back-to-back, the insert-and-copy length code + is encoded using a prefix code over the insert-and-copy length code + alphabet, while the extra bits values are encoded as fixed-width + integer values. The number of insert and copy extra bits can be 0 - + 24, and they are dependent on the insert-and-copy length code. + + Some of the insert-and-copy length codes also express the fact that + the distance symbol of the distance in the same command is 0, i.e. + the distance component of the command is the same as that of the + previous command. In this case, the distance code and extra bits for + the distance are omitted from the compressed data stream. + + + + +Alakuijala & Szabadka Expires June 10, 2016 [Page 18] + +Internet-Draft Brotli December 2015 + + + We describe the insert-and-copy length code alphabet in terms of the + (not directly used) insert length code and copy length code + alphabets. The symbols of the insert length code alphabet, along with + the number of insert extra bits, and the range of the insert lengths + are as follows: + + Extra Extra Extra + Code Bits Lengths Code Bits Lengths Code Bits Lengths + ---- ---- ------ ---- ---- ------- ---- ---- ------- + 0 0 0 8 2 10-13 16 6 130-193 + 1 0 1 9 2 14-17 17 7 194-321 + 2 0 2 10 3 18-25 18 8 322-577 + 3 0 3 11 3 26-33 19 9 578-1089 + 4 0 4 12 4 34-49 20 10 1090-2113 + 5 0 5 13 4 50-65 21 12 2114-6209 + 6 1 6,7 14 5 66-97 22 14 6210-22593 + 7 1 8,9 15 5 98-129 23 24 22594-16799809 + + The symbols of the copy length code alphabet, along with the number + of copy extra bits, and the range of copy lengths are as follows: + + Extra Extra Extra + Code Bits Lengths Code Bits Lengths Code Bits Lengths + ---- ---- ------ ---- ---- ------- ---- ---- ------- + 0 0 2 8 1 10,11 16 5 70-101 + 1 0 3 9 1 12,13 17 5 102-133 + 2 0 4 10 2 14-17 18 6 134-197 + 3 0 5 11 2 18-21 19 7 198-325 + 4 0 6 12 3 22-29 20 8 326-581 + 5 0 7 13 3 30-37 21 9 582-1093 + 6 0 8 14 4 38-53 22 10 1094-2117 + 7 0 9 15 4 54-69 23 24 2118-16779333 + + To convert an insert-and-copy length code to an insert length code + and a copy length code, the following table can be used: + + + + + + + + + + + + + + + + +Alakuijala & Szabadka Expires June 10, 2016 [Page 19] + +Internet-Draft Brotli December 2015 + + + Insert + length Copy length code + code 0-7 8-15 16-23 + +---------+---------+ + | | | + 0-7 | 0-63 | 64-127 | <--- distance symbol 0 + | | | + +---------+---------+---------+ + | | | | + 0-7 | 128-191 | 192-255 | 384-447 | + | | | | + +---------+---------+---------+ + | | | | + 8-15 | 256-319 | 320-383 | 512-575 | + | | | | + +---------+---------+---------+ + | | | | + 16-23 | 448-511 | 576-639 | 640-703 | + | | | | + +---------+---------+---------+ + + First, look up the cell with the 64 value range containing the + insert-and-copy length code, this gives the insert length code and + the copy length code ranges, both 8 values long. The copy length + code within its range is determined by bits 0-2 (counted from the + LSB) of the insert-and-copy length code. The insert length code + within its range is determined by bits 3-5 (counted from the LSB) of + the insert-and-copy length code. Given the insert length and copy + length codes, the actual insert and copy lengths can be obtained by + reading the number of extra bits given by the tables above. + + If the insert-and-copy length code is between 0 and 127, the distance + code of the command is set to zero (the last distance reused). + +6. Encoding of block switch commands + + As described in Section 2., a block-switch command is a pair . These are encoded in the compressed data part of + the meta-block, right before the start of each new block of a + particular block category. + + Each block type in the compressed data is represented with a block + type code, encoded using a prefix code over the block type code + alphabet. A block type symbol 0 means that the new block type is the + same as the type of the previous block from the same block category, + i.e. the block type that preceded the current type, while a block + type symbol 1 means that the new block type equals the current block + type plus one. If the current block type is the maximal possible, + + + +Alakuijala & Szabadka Expires June 10, 2016 [Page 20] + +Internet-Draft Brotli December 2015 + + + then a block type symbol of 1 results in wrapping to a new block type + of 0. Block type symbols 2 - 257 represent block types 0 - 255 + respectively. The previous and current block types are initialized to + 1 and 0, respectively, at the end of the meta-block header. + + Since the first block type of each block category is 0, the block + type of the first block-switch command is not encoded in the + compressed data. If a block category has only one block type, the + block count of the first block-switch command is also omitted from + the compressed data, otherwise it is encoded in the meta-block + header. + + Since the end of the meta-block is detected by the number of + uncompressed bytes produced, the block counts for any of the three + categories need not count down to exactly zero at the end of the + meta-block. + + The number of different block types in each block category, denoted + by NBLTYPESL, NBLTYPESI, and NBLTYPESD for literals, insert-and-copy + lengths, and distances, respectively, is encoded in the meta-block + header, and it must equal to the largest block type plus one in that + block category. In other words, the set of literal, insert-and-copy + length, and distance block types must be [0..NBLTYPESL-1], + [0..NBLTYPESI-1], and [0..NBLTYPESD-1], respectively. From this it + follows that the alphabet size of literal, insert-and-copy length, + and distance block type codes is NBLTYPESL + 2, NBLTYPESI + 2, and + NBLTYPESD + 2, respectively. + + Each block count in the compressed data is represented with a pair + . The block count code and the extra + bits are encoded back-to-back, the block count code is encoded using + a prefix code over the block count code alphabet, while the extra + bits value is encoded as a fixed-width integer value. The number of + extra bits can be 0 - 24, and it is dependent on the block count + code. The symbols of the block count code alphabet, along with the + number of extra bits, and the range of block counts are as follows: + + + + + + + + + + + + + + + +Alakuijala & Szabadka Expires June 10, 2016 [Page 21] + +Internet-Draft Brotli December 2015 + + + Extra Extra Extra + Code Bits Lengths Code Bits Lengths Code Bits Lengths + ---- ---- ------ ---- ---- ------- ---- ---- ------- + 0 2 1-4 9 4 65-80 18 7 369-496 + 1 2 5-8 10 4 81-96 19 8 497-752 + 2 2 9-12 11 4 97-112 20 9 753-1264 + 3 2 13-16 12 5 113-144 21 10 1265-2288 + 4 3 17-24 13 5 145-176 22 11 2289-4336 + 5 3 25-32 14 5 177-208 23 12 4337-8432 + 6 3 33-40 15 5 209-240 24 13 8433-16624 + 7 3 41-48 16 6 241-304 25 24 16625-16793840 + 8 4 49-64 17 6 305-368 + + The first block-switch command of each block category is special in + the sense that it is encoded in the meta-block header, and as + described earlier, the block type code is omitted since it is an + implicit zero. + +7. Context modeling + + As described in Section 2., the prefix tree used to encode a literal + byte or a distance code depends on the block type and the context ID. + This section specifies how to compute the context ID for a particular + literal and distance code, and how to encode the context map that + maps a pair to the index of a prefix code in + the array of literal and distance prefix codes. + +7.1. Context modes and context ID lookup for literals + + The context for encoding the next literal is defined by the last two + bytes in the stream (p1, p2, where p1 is the most recent byte), + regardless of whether these bytes are produced by uncompressed meta- + blocks, backward references, static dictionary references, or by + literal insertions. At the start of the stream p1 and p2 are + initialized to zero. + + There are four methods, called context modes, to compute the Context + ID: + + * LSB6, where the Context ID is the value of six + least-significant bits of p1, + * MSB6, where the Context ID is the value of six + most-significant bits of p1, + * UTF8, where the Context ID is a complex function of p1, p2, + optimized for text compression, and + * Signed, where Context ID is a complex function of p1, p2, + optimized for compressing sequences of signed integers. + + + + +Alakuijala & Szabadka Expires June 10, 2016 [Page 22] + +Internet-Draft Brotli December 2015 + + + The Context ID for the UTF8 and Signed context modes is computed + using the following lookup tables Lut0, Lut1, and Lut2. + + Lut0 := + 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 0, 0, 4, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 8, 12, 16, 12, 12, 20, 12, 16, 24, 28, 12, 12, 32, 12, 36, 12, + 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 32, 32, 24, 40, 28, 12, + 12, 48, 52, 52, 52, 48, 52, 52, 52, 48, 52, 52, 52, 52, 52, 48, + 52, 52, 52, 52, 52, 48, 52, 52, 52, 52, 52, 24, 12, 28, 12, 12, + 12, 56, 60, 60, 60, 56, 60, 60, 60, 56, 60, 60, 60, 60, 60, 56, + 60, 60, 60, 60, 60, 56, 60, 60, 60, 60, 60, 24, 12, 28, 12, 0, + 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, + 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, + 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, + 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, + 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, + 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, + 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, + 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3 + + Lut1 := + 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, 0, 0, 0, 0, 0, 0, + 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, + 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, + 1, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 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, 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, 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, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2 + + Lut2 := + 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + + + +Alakuijala & Szabadka Expires June 10, 2016 [Page 23] + +Internet-Draft Brotli December 2015 + + + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 7 + + The lengths and the zlib CRC-32 (ITU-T Recommendation V.42) check + values of each of these tables as a sequence of bytes are as follows: + + Table Length CRC-32 + ----- ------ ------ + Lut0 256 0x8e91efb7 + Lut1 256 0xd01a32f4 + Lut2 256 0x0dd7a0d6 + + Given p1 is the last uncompressed byte and p2 is the second-to-last + uncompressed byte, the context IDs can be computed as follows: + + For LSB6: Context ID = p1 & 0x3f + For MSB6: Context ID = p1 >> 2 + For UTF8: Context ID = Lut0[p1] | Lut1[p2] + For Signed: Context ID = (Lut2[p1] << 3) | Lut2[p2] + + From the lookup tables defined above and the operations to compute + the context IDs, we can see that context IDs for literals are in the + range of 0..63. + + The context modes LSB6, MSB6, UTF8, and Signed are denoted by + integers 0, 1, 2, 3. + + A context mode is defined for each literal block type and they are + stored in a consecutive array of bits in the meta-block header, + always two bits per block type. + +7.2. Context ID for distances + + The context for encoding a distance code is defined by the copy + length corresponding to the distance. The context IDs are 0, 1, 2, + and 3 for copy lengths 2, 3, 4, and more than 4, respectively. + +7.3. Encoding of the context map + + There are two context maps, one for literals and one for distances. + The size of the context map is 64 * NBLTYPESL for literals, and 4 * + NBLTYPESD for distances. Each value in the context map is an integer + + + +Alakuijala & Szabadka Expires June 10, 2016 [Page 24] + +Internet-Draft Brotli December 2015 + + + between 0 and 255, indicating the index of the prefix code to be used + when encoding the next literal or distance. + + The context maps are two-dimensional matrices, encoded as one- + dimensional arrays: + + CMAPL[0..(64 * NBLTYPESL - 1)] + CMAPD[0..(4 * NBLTYPESD - 1)] + + The index of the prefix code for encoding a literal or distance code + with block type, BTYPE_x, and context ID, CIDx, is: + + index of literal prefix code = CMAPL[64 * BTYPE_L + CIDL] + index of distance prefix code = CMAPD[4 * BTYPE_D + CIDD] + + The values of the context map are encoded with the combination of run + length encoding for zero values and prefix coding. Let RLEMAX denote + the number of run length codes and NTREES denote the maximum value in + the context map plus one. NTREES must equal the number of different + values in the context map, in other words, the different values in + the context map must be the [0..NTREES-1] interval. The alphabet of + the prefix code has the following RLEMAX + NTREES symbols: + + 0: value zero + 1: repeat a zero 2 to 3 times, read 1 bit for repeat length + 2: repeat a zero 4 to 7 times, read 2 bits for repeat length + ... + RLEMAX: repeat a zero (1 << RLEMAX) to (1 << (RLEMAX+1))-1 + times, read RLEMAX bits for repeat length + RLEMAX + 1: value 1 + ... + RLEMAX + NTREES - 1: value NTREES - 1 + + If RLEMAX = 0, the run length coding is not used, and the symbols of + the alphabet are directly the values in the context map. We can now + define the format of the context map (the same format is used for + literal and distance context maps): + + 1-5 bits: RLEMAX, 0 is encoded with one 0 bit, and values + 1 - 16 are encoded with bit pattern xxxx1 (so 01001 + is 5) + + Prefix code with alphabet size NTREES + RLEMAX + + Context map size values encoded with the above prefix code + and run length coding for zero values. If a run length + would result in more lengths in total than the size of + the context map, then the stream should be rejected as + + + +Alakuijala & Szabadka Expires June 10, 2016 [Page 25] + +Internet-Draft Brotli December 2015 + + + invalid. + + 1 bit: IMTF bit, if set, we do an inverse move-to-front + transform on the values in the context map to get + the prefix code indexes + + Note that RLEMAX may be larger than the value necessary to represent + the longest sequence of zero values. Also, the NTREES value is + encoded right before the context map as described in Section 9.2. + + We define the inverse move-to-front transform used in this + specification by the following C language function: + + void InverseMoveToFrontTransform(uint8_t* v, int v_len) { + uint8_t mtf[256]; + int i; + for (i = 0; i < 256; ++i) { + mtf[i] = (uint8_t)i; + } + for (i = 0; i < v_len; ++i) { + uint8_t index = v[i]; + uint8_t value = mtf[index]; + v[i] = value; + for (; index; --index) { + mtf[index] = mtf[index - 1]; + } + mtf[0] = value; + } + } + + Note that the inverse move-to-front transform will not produce values + outside the [0..NTREES-1] interval. + +8. Static dictionary + + At any given point during decoding the compressed data, a reference + to a duplicated string in the uncompressed data produced so far has a + maximum backward distance value, which is the minimum of the window + size and the number of uncompressed bytes produced. However, decoding + a distance from the compressed stream, as described in Section 4., + can produce distances that are greater than this maximum allowed + value. In this case, the distance is treated as a reference to a word + in the static dictionary given in Appendix A. The copy length for a + static dictionary reference must be between 4 and 24. The static + dictionary has three parts: + + * DICT[0..DICTSIZE], an array of bytes + * DOFFSET[0..24], an array of byte offset values for each length + + + +Alakuijala & Szabadka Expires June 10, 2016 [Page 26] + +Internet-Draft Brotli December 2015 + + + * NDBITS[0..24], an array of bit-depth values for each length + + The number of static dictionary words for a given length is: + + NWORDS[length] = 0 (if length < 4) + NWORDS[length] = (1 << NDBITS[length]) (if length >= 4) + + DOFFSET and DICTSIZE are defined by the following recursion: + + DOFFSET[0] = 0 + DOFFSET[length + 1] = DOFFSET[length] + length * NWORDS[length] + DICTSIZE = DOFFSET[24] + 24 * NWORDS[24] + + The offset of a word within the DICT array for a given length and + index is: + + offset(length, index) = DOFFSET[length] + index * length + + Each static dictionary word has 121 different forms, given by + applying a word transformation to a base word in the DICT array. The + list of word transformations is given in Appendix B. The static + dictionary word for a pair can be reconstructed as + follows: + + word_id = distance - (max allowed distance + 1) + index = word_id % NWORDS[length] + base_word = DICT[offset(length, index)..offset(length, index+1)-1] + transform_id = word_id >> NDBITS[length] + + The string copied to the uncompressed stream is computed by applying + the transformation to the base dictionary word. If transform_id is + greater than 120, or the length is smaller than 4 or greater than 24, + then the compressed stream should be rejected as invalid. + + Each word transformation has the following form: + + transform_i(word) = prefix_i + T_i(word) + suffix_i + + where the _i subscript denotes the transform_id above. Each T_i is + one of the following 21 elementary transforms: + + Identity, UppercaseFirst, UppercaseAll, + OmitFirst1, ..., OmitFirst9, OmitLast1, ..., OmitLast9 + + The form of these elementary transforms is as follows: + + Identity(word) = word + + + + +Alakuijala & Szabadka Expires June 10, 2016 [Page 27] + +Internet-Draft Brotli December 2015 + + + UppercaseFirst(word) = first UTF-8 character of word upper-cased + + UppercaseAll(word) = all UTF-8 characters of word upper-cased + + OmitFirstk(word) = the last (length(word) - k) bytes of word, or + empty string if length(word) < k + + OmitLastk(word) = the first (length(word) - k) bytes of word, or + empty string if length(word) < k + + For the purposes of UppercaseAll, word is parsed into UTF-8 + characters and converted to upper-case by taking 1 - 3 bytes at a + time, using the algorithm below: + + i = 0 + while i < length(word): + if word[i] < 192: + if word[i] >= 97 and word[i] <= 122: + word[i] = word[i] ^ 32 + i = i + 1 + else if word[i] < 224: + if i + 1 < length(word): + word[i + 1] = word[i + 1] ^ 32 + i = i + 2 + else: + if i + 2 < length(word): + word[i + 2] = word[i + 2] ^ 5 + i = i + 3 + + For UppercaseFirst, the same algorithm is used, but the loop is + executed only once. + + Appendix B. contains the list of transformations by specifying the + prefix, elementary transform and suffix components of each of them. + Note that the OmitFirst8 elementary transform is not used in the list + of transformations. The strings in Appendix B. are in C string format + with respect to escape (backslash) characters. + + The maximum number of additional bytes that a transform may add to a + base word is 13. Since the largest base word is 24 bytes long, a + buffer of 38 bytes is sufficient to store any transformed words + (counting a terminating zero byte). + +9. Compressed data format + + In this section we describe the format of the compressed data set in + terms of the format of the individual data items described in the + previous sections. + + + +Alakuijala & Szabadka Expires June 10, 2016 [Page 28] + +Internet-Draft Brotli December 2015 + + +9.1. Format of the stream header + + The stream header has only the following one field: + + 1-7 bits: WBITS, a value in the range 10 - 24, encoded with + the following variable length code (as it appears in + the compressed data, where the bits are parsed from + right to left): + + Value Bit Pattern + ----- ----------- + 10 0100001 + 11 0110001 + 12 1000001 + 13 1010001 + 14 1100001 + 15 1110001 + 16 0 + 17 0000001 + 18 0011 + 19 0101 + 20 0111 + 21 1001 + 22 1011 + 23 1101 + 24 1111 + + Note that bit pattern 0010001 is invalid and must not + be used. + + The size of the sliding window, which is the maximum value of any + non-dictionary reference backward distance, is given by the following + formula: + + window size = (1 << WBITS) - 16 + +9.2. Format of the meta-block header + + A compliant compressed data set has at least one meta-block. Each + meta-block contains a header with information about the uncompressed + length of the meta-block, and a bit signaling if the meta-block is + the last one. The format of the meta-block header is the following: + + 1 bit: ISLAST, set to 1 if this is the last meta-block + 1 bit: ISLASTEMPTY, if set to 1, the meta-block is empty; + this field is only present if ISLAST bit is set -- if + it is 1, then the meta-block and the brotli stream ends + at that bit, with any remaining bits in the last byte + + + +Alakuijala & Szabadka Expires June 10, 2016 [Page 29] + +Internet-Draft Brotli December 2015 + + + of the compressed stream filled with zeros (if the + fill bits are not zero, then the stream should be + rejected as invalid) + 2 bits: MNIBBLES, # of nibbles to represent the uncompressed + length, encoded with the following fixed-length code: + + Value Bit Pattern + ----- ----------- + 0 11 + 4 00 + 5 01 + 6 10 + + If MNIBBLES is 0, the meta-block is empty, i.e. it does + not generate any uncompressed data. In this case, the + rest of the meta-block has the following format: + + 1 bit: reserved, must be zero + + 2 bits: MSKIPBYTES, # of bytes to represent metadata + length + + MSKIPBYTES x 8 bits: MSKIPLEN - 1, where MSKIPLEN is + the number of metadata bytes; this field is + only present if MSKIPBYTES is positive, + otherwise MSKIPLEN is 0 (if MSKIPBYTES is + greater than 1, and the last byte is all + zeros, then the stream should be rejected + as invalid) + + 0 - 7 bits: fill bits until the next byte boundary, + must be all zeros + + MSKIPLEN bytes of metadata, not part of the + uncompressed data or the sliding window + + MNIBBLES x 4 bits: MLEN - 1, where MLEN is the length + of the meta-block uncompressed data in bytes (if + MNIBBLES is greater than 4, and the last + nibble is all zeros, then the stream should be + rejected as invalid) + + 1 bit: ISUNCOMPRESSED, if set to 1, any bits of compressed + data up to the next byte boundary are ignored, and + the rest of the meta-block contains MLEN bytes of + literal data; this field is only present if the + ISLAST bit is not set (if the ignored bits are not + all zeros, the stream should be rejected as invalid) + + + +Alakuijala & Szabadka Expires June 10, 2016 [Page 30] + +Internet-Draft Brotli December 2015 + + + 1-11 bits: NBLTYPESL, # of literal block types, encoded with + the following variable length code (as it appears in + the compressed data, where the bits are parsed from + right to left, so 0110111 has the value 12): + + Value Bit Pattern + ----- ----------- + 1 0 + 2 0001 + 3-4 x0011 + 5-8 xx0101 + 9-16 xxx0111 + 17-32 xxxx1001 + 33-64 xxxxx1011 + 65-128 xxxxxx1101 + 129-256 xxxxxxx1111 + + Prefix code over the block type code alphabet for + literal block types, appears only if NBLTYPESL >= 2 + + Prefix code over the block count code alphabet for + literal block counts, appears only if NBLTYPESL >= 2 + + Block count code + extra bits for first literal + block count, appears only if NBLTYPESL >= 2 + + 1-11 bits: NBLTYPESI, # of insert-and-copy block types, encoded + with the same variable length code as above + + Prefix code over the block type code alphabet for + insert-and-copy block types, appears only if NBLTYPESI >= 2 + + Prefix code over the block count code alphabet for + insert-and-copy block counts, appears only if NBLTYPESI >= 2 + + Block count code + extra bits for first insert-and-copy + block count, appears only if NBLTYPESI >= 2 + + 1-11 bits: NBLTYPESD, # of distance block types, encoded + with the same variable length code as above + + Prefix code over the block type code alphabet for + distance block types, appears only if NBLTYPESD >= 2 + + Prefix code over the block count code alphabet for + distance block counts, appears only if NBLTYPESD >= 2 + + Block count code + extra bits for first distance + + + +Alakuijala & Szabadka Expires June 10, 2016 [Page 31] + +Internet-Draft Brotli December 2015 + + + block count, appears only if NBLTYPESD >= 2 + + 2 bits: NPOSTFIX, parameter used in the distance coding + + 4 bits: four most-significant bits of NDIRECT, to get the + actual value of the parameter NDIRECT, left-shift + this four-bit number by NPOSTFIX bits + + NBLTYPESL x 2 bits: context mode for each literal block type + + 1-11 bits: NTREESL, # of literal prefix trees, encoded + with the same variable length code as NBLTYPESL + + Literal context map, encoded as described in Section 7.3., + appears only if NTREESL >= 2, otherwise the context map + has only zero values + + 1-11 bits: NTREESD, # of distance prefix trees, encoded + with the same variable length code as NBLTYPESD + + Distance context map, encoded as described in Section 7.3., + appears only if NTREESD >= 2, otherwise the context map + has only zero values + + NTREESL prefix codes for literals + + NBLTYPESI prefix codes for insert-and-copy lengths + + NTREESD prefix codes for distances + +9.3. Format of the meta-block data + + The compressed data part of a meta-block consists of a series of + commands. Each command has the following format: + + Block type code for next insert-and-copy block type, appears + only if NBLTYPESI >= 2 and the previous insert-and-copy + block count is zero + + Block count code + extra bits for next insert-and-copy + block count, appears only if NBLTYPESI >= 2 and the + previous insert-and-copy block count is zero + + Insert-and-copy length, encoded as in Section 5., using the + insert-and-copy length prefix code with the current + insert-and-copy block type index + + Insert length number of literals, with the following format: + + + +Alakuijala & Szabadka Expires June 10, 2016 [Page 32] + +Internet-Draft Brotli December 2015 + + + Block type code for next literal block type, appears + only if NBLTYPESL >= 2 and the previous literal + block count is zero + + Block count code + extra bits for next literal + block count, appears only if NBLTYPESL >= 2 and the + previous literal block count is zero + + Next byte of the uncompressed data, encoded with the + literal prefix code with the index determined by the + previous two bytes of the uncompressed data, the + current literal block type, and the context map, as + described in Section 7.3. + + Block type code for next distance block type, appears + only if NBLTYPESD >= 2 and the previous distance + block count is zero + + Block count code + extra bits for next distance + block count, appears only if NBLTYPESD >= 2 and the + previous distance block count is zero + + Distance code, encoded as in Section 4., using the distance + prefix code with the current distance block type index, + appears only if the distance code is not an implicit 0, + as indicated by the insert-and-copy length code + + The number of commands in the meta-block is such that the sum of the + uncompressed bytes produced (i.e. the number of literals inserted + plus the number of bytes copied from past data or generated from the + static dictionary) over all the commands gives the uncompressed + length, MLEN encoded in the meta-block header. + + If the total number of uncompressed bytes produced after the insert + part of the last command equals MLEN, then the copy length of the + last command is ignored and will not produce any uncompressed output. + In this case the copy length of the last command can have any value. + In any other case, if the number of literals to insert, the copy + length, or the resulting dictionary word length would cause MLEN to + be exceeded, then the stream should be rejected as invalid. + + If the last command of the last non-empty meta-block does not end on + a byte boundary, the unused bits in the last byte must be zeros. + +10. Decoding algorithm + + The decoding algorithm that produces the uncompressed data is as + follows: + + + +Alakuijala & Szabadka Expires June 10, 2016 [Page 33] + +Internet-Draft Brotli December 2015 + + + read window size + do + read ISLAST bit + if ISLAST + read ISLASTEMPTY bit + if ISLASTEMPTY + break from loop + read MNIBBLES + if MNIBBLES is zero + verify reserved bit is zero + read MSKIPLEN + skip any bits up to the next byte boundary + skip MSKIPLEN bytes + continue to the next meta-block + else + read MLEN + if not ISLAST + read ISUNCOMPRESSED bit + if ISUNCOMPRESSED + skip any bits up to the next byte boundary + copy MLEN bytes of compressed data as literals + continue to the next meta-block + loop for each three block categories (i = L, I, D) + read NBLTYPESi + if NBLTYPESi >= 2 + read prefix code for block types, HTREE_BTYPE_i + read prefix code for block counts, HTREE_BLEN_i + read block count, BLEN_i + set block type, BTYPE_i to 0 + initialize second-to-last and last block types to 0 and 1 + else + set block type, BTYPE_i to 0 + set block count, BLEN_i to 16777216 + read NPOSTFIX and NDIRECT + read array of literal context modes, CMODE[] + read NTREESL + if NTREESL >= 2 + read literal context map, CMAPL[] + else + fill CMAPL[] with zeros + read NTREESD + if NTREESD >= 2 + read distance context map, CMAPD[] + else + fill CMAPD[] with zeros + read array of literal prefix codes, HTREEL[] + read array of insert-and-copy length prefix codes, HTREEI[] + read array of distance prefix codes, HTREED[] + + + +Alakuijala & Szabadka Expires June 10, 2016 [Page 34] + +Internet-Draft Brotli December 2015 + + + do + if BLEN_I is zero + read block type using HTREE_BTYPE_I and set BTYPE_I + save previous block type + read block count using HTREE_BLEN_I and set BLEN_I + decrement BLEN_I + read insert-and-copy length symbol using HTREEI[BTYPE_I] + compute insert length, ILEN, and copy length, CLEN + loop for ILEN + if BLEN_L is zero + read block type using HTREE_BTYPE_L and set BTYPE_L + save previous block type + read block count using HTREE_BLEN_L and set BLEN_L + decrement BLEN_L + look up context mode CMODE[BTYPE_L] + compute context ID, CIDL from last two uncompressed bytes + read literal using HTREEL[CMAPL[64*BTYPE_L + CIDL]] + write literal to uncompressed stream + if number of uncompressed bytes produced in the loop for + this meta-block is MLEN, then break from loop (in this + case the copy length is ignored and can have any value) + if distance code is implicit zero from insert-and-copy code + set backward distance to the last distance + else + if BLEN_D is zero + read block type using HTREE_BTYPE_D and set BTYPE_D + save previous block type + read block count using HTREE_BLEN_D and set BLEN_D + decrement BLEN_D + compute context ID, CIDD from CLEN + read distance code using HTREED[CMAPD[4*BTYPE_D + CIDD]] + compute distance by distance short code substitution + if distance code is not zero, + and distance is not a static dictionary reference, + push distance to the ring buffer of last distances + if distance is less than the max allowed distance plus one + move backwards distance bytes in the uncompressed data, + and copy CLEN bytes from this position to + the uncompressed stream + else + look up the static dictionary word, transform the word as + directed, and copy the result to the uncompressed stream + while number of uncompressed bytes for this meta-block < MLEN + while not ISLAST + + If the stream ends before the completion of the last meta-block, then + the stream should be rejected as invalid. + + + + +Alakuijala & Szabadka Expires June 10, 2016 [Page 35] + +Internet-Draft Brotli December 2015 + + + Note that a duplicated string reference may refer to a string in a + previous meta-block, i.e. the backward distance may cross one or more + meta-block boundaries. However a backward copy distance will not + refer past the beginning of the uncompressed stream or the window + size; any such distance is interpreted as a reference to a static + dictionary word. Also note that the referenced string may overlap the + current position, for example, if the last 2 bytes decoded have + values X and Y, a string reference with + adds X,Y,X,Y,X to the uncompressed stream. + +11. Security Considerations + + As with any compressed file formats, decompressor implementations + should handle all compressed data byte sequences, not only those that + conform to this specification, where non-conformant compressed data + sequences should be discarded. A possible attack against a system + containing a decompressor implementation (e.g. a web browser) is to + exploit a buffer overflow caused by an invalid compressed data. + Therefore decompressor implementations should perform bounds-checking + for each memory access that result from values decoded from the + compressed stream. + +12. IANA Considerations + + The "HTTP Content Coding Registry" has been updated with the + registration below: + + +-------+-------------------------------------+------------+ + | Name | Description | Reference | + +-------+-------------------------------------+------------+ + | br | Brotli Compressed Data Format | RFCXXXX | + +-------+-------------------------------------+------------+ + +13. Informative References + + [HUFFMAN] Huffman, D. A., "A Method for the Construction of Minimum + Redundancy Codes", Proceedings of the Institute of Radio + Engineers, September 1952, Volume 40, Number 9, pp. + 1098-1101. + + [LZ77] Ziv J., Lempel A., "A Universal Algorithm for Sequential + Data Compression", IEEE Transactions on Information + Theory, Vol. 23, No. 3, pp. 337-343. + + [RFC1951] Deutsch, P., "DEFLATE Compressed Data Format Specification + version 1.3", RFC 1951, Aladdin Enterprises, May 1996. + http://www.ietf.org/rfc/rfc1951.txt + + + + +Alakuijala & Szabadka Expires June 10, 2016 [Page 36] + +Internet-Draft Brotli December 2015 + + + [WOFF2] Levantovsky, V. (ed.), Levien, R. (ed.), "WOFF File Format + 2.0", W3C WebFonts Working Group, + http://www.w3.org/TR/WOFF2/ + +14. Source code + + Source code for a C language implementation of a brotli compliant + decompressor and a C++ language implementation of a compressor is + available in the brotli open-source project: + https://github.com/google/brotli + +15. Acknowledgments + + The authors would like to thank Mark Adler, Robert Obryk, Thomas + Pickert, and Joe Tsai for providing helpful review comments, + validating the specification by writing an independent decompressor, + and suggesting improvements to the format and the text of the + specification. + +Appendix A. Static dictionary data + + The hexadecimal form of the DICT array is the following, where the + length is 122,784 bytes and the zlib CRC-32 of the byte sequence is + 0x5136cb04. + + 74696d65646f776e6c6966656c6566746261636b636f64656461746173686f77 + 6f6e6c7973697465636974796f70656e6a7573746c696b6566726565776f726b + 74657874796561726f766572626f64796c6f7665666f726d626f6f6b706c6179 + 6c6976656c696e6568656c70686f6d65736964656d6f7265776f72646c6f6e67 + 7468656d7669657766696e64706167656461797366756c6c686561647465726d + 656163686172656166726f6d747275656d61726b61626c6575706f6e68696768 + 646174656c616e646e6577736576656e6e65787463617365626f7468706f7374 + 757365646d61646568616e6468657265776861746e616d654c696e6b626c6f67 + 73697a656261736568656c646d616b656d61696e757365722729202b686f6c64 + 656e6473776974684e65777372656164776572657369676e74616b6568617665 + 67616d657365656e63616c6c7061746877656c6c706c75736d656e7566696c6d + 706172746a6f696e746869736c697374676f6f646e6565647761797377657374 + 6a6f62736d696e64616c736f6c6f676f72696368757365736c6173747465616d + 61726d79666f6f646b696e6777696c6c65617374776172646265737466697265 + 506167656b6e6f77617761792e706e676d6f76657468616e6c6f616467697665 + 73656c666e6f74656d756368666565646d616e79726f636b69636f6e6f6e6365 + 6c6f6f6b6869646564696564486f6d6572756c65686f7374616a6178696e666f + 636c75626c6177736c65737368616c66736f6d65737563687a6f6e6531303025 + 6f6e65736361726554696d6572616365626c7565666f75727765656b66616365 + 686f706567617665686172646c6f73747768656e7061726b6b65707470617373 + 73686970726f6f6d48544d4c706c616e54797065646f6e65736176656b656570 + 666c61676c696e6b736f6c6466697665746f6f6b72617465746f776e6a756d70 + 746875736461726b6361726466696c6566656172737461796b696c6c74686174 + + + +Alakuijala & Szabadka Expires June 10, 2016 [Page 37] + +Internet-Draft Brotli December 2015 + + + 66616c6c6175746f657665722e636f6d74616c6b73686f70766f746564656570 + 6d6f6465726573747475726e626f726e62616e6466656c6c726f736575726c28 + 736b696e726f6c65636f6d6561637473616765736d656574676f6c642e6a7067 + 6974656d7661727966656c747468656e73656e6464726f7056696577636f7079 + 312e30223c2f613e73746f70656c73656c696573746f75727061636b2e676966 + 706173746373733f677261796d65616e2667743b7269646573686f746c617465 + 73616964726f6164766172206665656c6a6f686e7269636b706f727466617374 + 2755412d646561643c2f623e706f6f7262696c6c74797065552e532e776f6f64 + 6d7573743270783b496e666f72616e6b7769646577616e7477616c6c6c656164 + 5b305d3b7061756c776176657375726524282723776169746d61737361726d73 + 676f65736761696e6c616e6770616964212d2d206c6f636b756e6974726f6f74 + 77616c6b6669726d77696665786d6c22736f6e6774657374323070786b696e64 + 726f7773746f6f6c666f6e746d61696c73616665737461726d617073636f7265 + 7261696e666c6f77626162797370616e736179733470783b3670783b61727473 + 666f6f747265616c77696b696865617473746570747269706f72672f6c616b65 + 7765616b746f6c64466f726d6361737466616e7362616e6b7665727972756e73 + 6a756c797461736b3170783b676f616c67726577736c6f776564676569643d22 + 736574733570783b2e6a733f3430707869662028736f6f6e736561746e6f6e65 + 747562657a65726f73656e747265656466616374696e746f676966746861726d + 3138707863616d6568696c6c626f6c647a6f6f6d766f69646561737972696e67 + 66696c6c7065616b696e6974636f73743370783b6a61636b7461677362697473 + 726f6c6c656469746b6e65776e6561723c212d2d67726f774a534f4e64757479 + 4e616d6573616c65796f75206c6f74737061696e6a617a7a636f6c6465796573 + 666973687777772e7269736b7461627370726576313070787269736532357078 + 426c756564696e673330302c62616c6c666f72646561726e77696c64626f782e + 666169726c61636b76657273706169726a756e6574656368696628217069636b + 6576696c242822237761726d6c6f7264646f657370756c6c2c30303069646561 + 647261776875676573706f7466756e646275726e6872656663656c6c6b657973 + 7469636b686f75726c6f73736675656c31327078737569746465616c52535322 + 6167656467726579474554226561736561696d736769726c616964733870783b + 6e617679677269647469707323393939776172736c61647963617273293b207d + 7068703f68656c6c74616c6c77686f6d7a683ae52a2f0d0a2031303068616c6c + 2e0a0a413770783b70757368636861743070783b637265772a2f3c2f68617368 + 37357078666c6174726172652026262074656c6c63616d706f6e746f6c616964 + 6d697373736b697074656e7466696e656d616c6567657473706c6f743430302c + 0d0a0d0a636f6f6c666565742e7068703c62723e657269636d6f737467756964 + 62656c6c64657363686169726d61746861746f6d2f696d67262338326c75636b + 63656e743030303b74696e79676f6e6568746d6c73656c6c6472756746524545 + 6e6f64656e69636b3f69643d6c6f73656e756c6c7661737477696e6452535320 + 7765617272656c796265656e73616d6564756b656e6173616361706577697368 + 67756c665432333a68697473736c6f74676174656b69636b626c757274686579 + 313570782727293b293b223e6d73696577696e7362697264736f727462657461 + 7365656b5431383a6f726473747265656d616c6c363070786661726de2809973 + 626f79735b305d2e27293b22504f5354626561726b696473293b7d7d6d617279 + 74656e6428554b29717561647a683ae62d73697a2d2d2d2d70726f7027293b0d + 6c6966745431393a76696365616e6479646562743e525353706f6f6c6e65636b + 626c6f775431363a646f6f726576616c5431373a6c6574736661696c6f72616c + 706f6c6c6e6f7661636f6c7367656e6520e28094736f6674726f6d6574696c6c + + + +Alakuijala & Szabadka Expires June 10, 2016 [Page 38] + +Internet-Draft Brotli December 2015 + + + 726f73733c68333e706f75726661646570696e6b3c74723e6d696e69297c2128 + 6d696e657a683ae862617273686561723030293b6d696c6b202d2d3e69726f6e + 667265646469736b77656e74736f696c707574732f6a732f686f6c795432323a + 4953424e5432303a6164616d736565733c68323e6a736f6e272c2027636f6e74 + 5432313a205253536c6f6f70617369616d6f6f6e3c2f703e736f756c4c494e45 + 666f7274636172745431343a3c68313e38307078212d2d3c3970783b5430343a + 6d696b653a34365a6e696365696e6368596f726b726963657a683ae42729293b + 707572656d61676570617261746f6e65626f6e643a33375a5f6f665f275d293b + 3030302c7a683ae774616e6b79617264626f776c627573683a35365a4a617661 + 333070780a7c7d0a254333253a33345a6a656666455850496361736876697361 + 676f6c66736e6f777a683ae9717565722e6373737369636b6d6561746d696e2e + 62696e6464656c6c686972657069637372656e743a33365a485454502d323031 + 666f746f776f6c66454e442078626f783a35345a424f44596469636b3b0a7d0a + 657869743a33355a7661727362656174277d293b646965743939393b616e6e65 + 7d7d3c2f5b695d2e4c616e676b6dc2b277697265746f7973616464737365616c + 616c65783b0a097d6563686f6e696e652e6f726730303529746f6e796a657773 + 73616e646c656773726f6f66303030292032303077696e6567656172646f6773 + 626f6f74676172796375747374796c6574656d7074696f6e2e786d6c636f636b + 67616e672428272e3530707850682e446d697363616c616e6c6f616e6465736b + 6d696c657279616e756e697864697363293b7d0a64757374636c6970292e0a0a + 373070782d32303044564473375d3e3c7461706564656d6f692b2b2977616765 + 6575726f7068696c6f707473686f6c65464151736173696e2d3236546c616273 + 7065747355524c2062756c6b636f6f6b3b7d0d0a484541445b305d2961626272 + 6a75616e283139386c6573687477696e3c2f693e736f6e79677579736675636b + 706970657c2d0a21303032296e646f775b315d3b5b5d3b0a4c6f672073616c74 + 0d0a090962616e677472696d62617468297b0d0a303070780a7d293b6b6f3aec + 6665657361643e0d733a2f2f205b5d3b746f6c6c706c756728297b0a7b0d0a20 + 2e6a7327323030706475616c626f61742e4a5047293b0a7d71756f74293b0a0a + 27293b0a0d0a7d0d323031343230313532303136323031373230313832303139 + 3230323032303231323032323230323332303234323032353230323632303237 + 3230323832303239323033303230333132303332323033333230333432303335 + 3230333632303337323031333230313232303131323031303230303932303038 + 3230303732303036323030353230303432303033323030323230303132303030 + 3139393931393938313939373139393631393935313939343139393331393932 + 3139393131393930313938393139383831393837313938363139383531393834 + 3139383331393832313938313139383031393739313937383139373731393736 + 3139373531393734313937333139373231393731313937303139363931393638 + 3139363731393636313936353139363431393633313936323139363131393630 + 3139353931393538313935373139353631393535313935343139353331393532 + 31393531313935303130303031303234313339343030303039393939636f6d6f + 6dc3a17365737465657374617065726f746f646f686163656361646161c3b16f + 6269656e64c3ad616173c3ad766964616361736f6f74726f666f726f736f6c6f + 6f7472616375616c64696a6f7369646f6772616e7469706f74656d6164656265 + 616c676f7175c3a96573746f6e61646174726573706f636f6361736162616a6f + 746f646173696e6f6167756170756573756e6f73616e7465646963656c756973 + 656c6c616d61796f7a6f6e61616d6f727069736f6f627261636c6963656c6c6f + 64696f73686f726163617369d0b7d0b0d0bdd0b0d0bed0bcd180d0b0d180d183 + d182d0b0d0bdd0b5d0bfd0bed0bed182d0b8d0b7d0bdd0bed0b4d0bed182d0be + + + +Alakuijala & Szabadka Expires June 10, 2016 [Page 39] + +Internet-Draft Brotli December 2015 + + + d0b6d0b5d0bed0bdd0b8d185d09dd0b0d0b5d0b5d0b1d18bd0bcd18bd092d18b + d181d0bed0b2d18bd0b2d0bed09dd0bed0bed0b1d09fd0bed0bbd0b8d0bdd0b8 + d0a0d0a4d09dd0b5d09cd18bd182d18bd09ed0bdd0b8d0bcd0b4d0b0d097d0b0 + d094d0b0d09dd183d09ed0b1d182d0b5d098d0b7d0b5d0b9d0bdd183d0bcd0bc + d0a2d18bd183d0b6d981d98ad8a3d986d985d8a7d985d8b9d983d984d8a3d988 + d8b1d8afd98ad8a7d981d989d987d988d984d985d984d983d8a7d988d984d987 + d8a8d8b3d8a7d984d8a5d986d987d98ad8a3d98ad982d8afd987d984d8abd985 + d8a8d987d984d988d984d98ad8a8d984d8a7d98ad8a8d983d8b4d98ad8a7d985 + d8a3d985d986d8aad8a8d98ad984d986d8add8a8d987d985d985d8b4d988d8b4 + 6669727374766964656f6c69676874776f726c646d656469617768697465636c + 6f7365626c61636b7269676874736d616c6c626f6f6b73706c6163656d757369 + 636669656c646f72646572706f696e7476616c75656c6576656c7461626c6562 + 6f617264686f75736567726f7570776f726b7379656172737374617465746f64 + 6179776174657273746172747374796c656465617468706f77657270686f6e65 + 6e696768746572726f72696e70757461626f75747465726d737469746c65746f + 6f6c736576656e746c6f63616c74696d65736c61726765776f72647367616d65 + 7373686f72747370616365666f637573636c6561726d6f64656c626c6f636b67 + 75696465726164696f7368617265776f6d656e616761696e6d6f6e6579696d61 + 67656e616d6573796f756e676c696e65736c61746572636f6c6f72677265656e + 66726f6e7426616d703b7761746368666f726365707269636572756c65736265 + 67696e616674657276697369746973737565617265617362656c6f77696e6465 + 78746f74616c686f7572736c6162656c7072696e7470726573736275696c746c + 696e6b73737065656473747564797472616465666f756e6473656e7365756e64 + 657273686f776e666f726d7372616e676561646465647374696c6c6d6f766564 + 74616b656e61626f7665666c61736866697865646f6674656e6f746865727669 + 657773636865636b6c6567616c72697665726974656d73717569636b73686170 + 6568756d616e6578697374676f696e676d6f7669657468697264626173696370 + 65616365737461676577696474686c6f67696e696465617377726f7465706167 + 65737573657273647269766573746f7265627265616b736f757468766f696365 + 73697465736d6f6e746877686572656275696c6477686963686561727468666f + 72756d746872656573706f72747061727479436c69636b6c6f7765726c697665 + 73636c6173736c61796572656e74727973746f72797573616765736f756e6463 + 6f757274796f7572206269727468706f70757074797065736170706c79496d61 + 67656265696e6775707065726e6f746573657665727973686f77736d65616e73 + 65787472616d61746368747261636b6b6e6f776e6561726c79626567616e7375 + 70657270617065726e6f7274686c6561726e676976656e6e616d6564656e6465 + 645465726d73706172747347726f75706272616e647573696e67776f6d616e66 + 616c73657265616479617564696f74616b65737768696c652e636f6d2f6c6976 + 656463617365736461696c796368696c6467726561746a7564676574686f7365 + 756e6974736e6576657262726f6164636f617374636f7665726170706c656669 + 6c65736379636c657363656e65706c616e73636c69636b777269746571756565 + 6e7069656365656d61696c6672616d656f6c64657270686f746f6c696d697463 + 61636865636976696c7363616c65656e7465727468656d657468657265746f75 + 6368626f756e64726f79616c61736b656477686f6c6573696e636573746f636b + 206e616d6566616974686865617274656d7074796f6666657273636f70656f77 + 6e65646d69676874616c62756d7468696e6b626c6f6f6461727261796d616a6f + 72747275737463616e6f6e756e696f6e636f756e7476616c696473746f6e6553 + 74796c654c6f67696e68617070796f636375726c6566743a6672657368717569 + + + +Alakuijala & Szabadka Expires June 10, 2016 [Page 40] + +Internet-Draft Brotli December 2015 + + + 746566696c6d7367726164656e65656473757262616e66696768746261736973 + 686f7665726175746f3b726f7574652e68746d6c6d6978656466696e616c596f + 757220736c696465746f70696362726f776e616c6f6e65647261776e73706c69 + 747265616368526967687464617465736d6172636871756f7465676f6f64734c + 696e6b73646f7562746173796e637468756d62616c6c6f776368696566796f75 + 74686e6f76656c313070783b7365727665756e74696c68616e6473436865636b + 537061636571756572796a616d6573657175616c7477696365302c3030305374 + 61727470616e656c736f6e6773726f756e6465696768747368696674776f7274 + 68706f7374736c656164737765656b7361766f696474686573656d696c657370 + 6c616e65736d617274616c706861706c616e746d61726b737261746573706c61 + 7973636c61696d73616c65737465787473737461727377726f6e673c2f68333e + 7468696e672e6f72672f6d756c74696865617264506f7765727374616e64746f + 6b656e736f6c696428746869736272696e677368697073737461666674726965 + 6463616c6c7366756c6c7966616374736167656e7454686973202f2f2d2d3e61 + 646d696e65677970744576656e74313570783b456d61696c747275652263726f + 73737370656e74626c6f6773626f78223e6e6f7465646c656176656368696e61 + 73697a657367756573743c2f68343e726f626f746865617679747275652c7365 + 76656e6772616e646372696d657369676e73617761726564616e636570686173 + 653e3c212d2d656e5f5553262333393b32303070785f6e616d656c6174696e65 + 6e6a6f79616a61782e6174696f6e736d697468552e532e20686f6c6473706574 + 6572696e6469616e6176223e636861696e73636f7265636f6d6573646f696e67 + 7072696f7253686172653139393073726f6d616e6c697374736a6170616e6661 + 6c6c73747269616c6f776e657261677265653c2f68323e6162757365616c6572 + 746f70657261222d2f2f57636172647368696c6c737465616d7350686f746f74 + 72757468636c65616e2e7068703f7361696e746d6574616c6c6f7569736d6561 + 6e7470726f6f666272696566726f77223e67656e7265747275636b6c6f6f6b73 + 56616c75654672616d652e6e65742f2d2d3e0a3c747279207b0a766172206d61 + 6b6573636f737473706c61696e6164756c747175657374747261696e6c61626f + 7268656c707363617573656d616769636d6f746f72746865697232353070786c + 656173747374657073436f756e74636f756c64676c617373736964657366756e + 6473686f74656c61776172646d6f7574686d6f76657370617269736769766573 + 6475746368746578617366727569746e756c6c2c7c7c5b5d3b746f70223e0a3c + 212d2d504f5354226f6365616e3c62722f3e666c6f6f72737065616b64657074 + 682073697a6562616e6b7363617463686368617274323070783b616c69676e64 + 65616c73776f756c64353070783b75726c3d227061726b736d6f7573654d6f73 + 74202e2e2e3c2f616d6f6e67627261696e626f6479206e6f6e653b6261736564 + 636172727964726166747265666572706167655f686f6d652e6d657465726465 + 6c6179647265616d70726f76656a6f696e743c2f74723e64727567733c212d2d + 20617072696c696465616c616c6c656e6578616374666f727468636f6465736c + 6f67696356696577207365656d73626c616e6b706f7274732028323030736176 + 65645f6c696e6b676f616c736772616e74677265656b686f6d657372696e6773 + 7261746564333070783b77686f7365706172736528293b2220426c6f636b6c69 + 6e75786a6f6e6573706978656c27293b223e293b6966282d6c65667464617669 + 64686f727365466f6375737261697365626f786573547261636b656d656e743c + 2f656d3e626172223e2e7372633d746f776572616c743d226361626c6568656e + 7279323470783b73657475706974616c7973686172706d696e6f727461737465 + 77616e7473746869732e7265736574776865656c6769726c732f6373732f3130 + 30253b636c75627373747566666269626c65766f74657320313030306b6f7265 + + + +Alakuijala & Szabadka Expires June 10, 2016 [Page 41] + +Internet-Draft Brotli December 2015 + + + 617d293b0d0a62616e647371756575653d207b7d3b383070783b636b696e677b + 0d0a09096168656164636c6f636b69726973686c696b6520726174696f737461 + 7473466f726d227961686f6f295b305d3b41626f757466696e64733c2f68313e + 64656275677461736b7355524c203d63656c6c737d2928293b313270783b7072 + 696d6574656c6c737475726e7330783630302e6a706722737061696e62656163 + 6874617865736d6963726f616e67656c2d2d3e3c2f676966747373746576652d + 6c696e6b626f64792e7d293b0a096d6f756e7420283139394641513c2f726f67 + 65726672616e6b436c617373323870783b66656564733c68313e3c73636f7474 + 7465737473323270783b6472696e6b29207c7c206c657769737368616c6c2330 + 33393b20666f72206c6f7665647761737465303070783b6a613ae38273696d6f + 6e3c666f6e747265706c796d65657473756e7465726368656170746967687442 + 72616e642920213d206472657373636c697073726f6f6d736f6e6b65796d6f62 + 696c6d61696e2e4e616d6520706c61746566756e6e797472656573636f6d2f22 + 312e6a7067776d6f6465706172616d53544152546c65667420696464656e2c20 + 323031293b0a7d0a666f726d2e766972757363686169727472616e73776f7273 + 7450616765736974696f6e70617463683c212d2d0a6f2d6361636669726d7374 + 6f7572732c30303020617369616e692b2b297b61646f626527295b305d69643d + 3130626f74683b6d656e75202e322e6d692e706e67226b6576696e636f616368 + 4368696c646272756365322e6a706755524c292b2e6a70677c7375697465736c + 69636568617272793132302220737765657474723e0d0a6e616d653d64696567 + 6f706167652073776973732d2d3e0a0a236666663b223e4c6f672e636f6d2274 + 7265617473686565742920262620313470783b736c6565706e74656e7466696c + 65646a613ae38369643d22634e616d6522776f72736573686f74732d626f782d + 64656c74610a266c743b62656172733a34385a3c646174612d727572616c3c2f + 613e207370656e6462616b657273686f70733d2022223b706870223e6374696f + 6e313370783b627269616e68656c6c6f73697a653d6f3d253246206a6f696e6d + 617962653c696d6720696d67223e2c20666a73696d67222022295b305d4d546f + 704254797065226e65776c7944616e736b637a656368747261696c6b6e6f7773 + 3c2f68353e666171223e7a682d636e3130293b0a2d3122293b747970653d626c + 7565737472756c7964617669732e6a73273b3e0d0a3c21737465656c20796f75 + 2068323e0d0a666f726d206a6573757331303025206d656e752e0d0a090d0a77 + 616c65737269736b73756d656e746464696e67622d6c696b7465616368676966 + 2220766567617364616e736b6565737469736871697073756f6d69736f627265 + 6465736465656e747265746f646f73707565646561c3b16f73657374c3a17469 + 656e6568617374616f74726f737061727465646f6e64656e7565766f68616365 + 72666f726d616d69736d6f6d656a6f726d756e646f617175c3ad64c3ad617373 + c3b36c6f61797564616665636861746f64617374616e746f6d656e6f73646174 + 6f736f74726173736974696f6d7563686f61686f72616c756761726d61796f72 + 6573746f73686f72617374656e6572616e746573666f746f7365737461737061 + c3ad736e7565766173616c7564666f726f736d6564696f717569656e6d657365 + 73706f6465726368696c65736572c3a1766563657364656369726a6f73c3a965 + 7374617276656e7461677275706f686563686f656c6c6f7374656e676f616d69 + 676f636f7361736e6976656c67656e74656d69736d6161697265736a756c696f + 74656d617368616369616661766f726a756e696f6c6962726570756e746f6275 + 656e6f6175746f72616272696c6275656e61746578746f6d61727a6f73616265 + 726c697374616c7565676f63c3b36d6f656e65726f6a7565676f706572c3ba68 + 616265726573746f796e756e63616d756a657276616c6f7266756572616c6962 + 726f6775737461696775616c766f746f736361736f736775c3ad61707565646f + + + +Alakuijala & Szabadka Expires June 10, 2016 [Page 42] + +Internet-Draft Brotli December 2015 + + + 736f6d6f73617669736f7573746564646562656e6e6f63686562757363616661 + 6c74616575726f737365726965646963686f637572736f636c61766563617361 + 736c65c3b36e706c617a6f6c6172676f6f62726173766973746161706f796f6a + 756e746f7472617461766973746f637265617263616d706f68656d6f7363696e + 636f636172676f7069736f736f7264656e686163656ec3a1726561646973636f + 706564726f63657263617075656461706170656c6d656e6f72c3ba74696c636c + 61726f6a6f72676563616c6c65706f6e657274617264656e616469656d617263 + 617369677565656c6c61737369676c6f636f6368656d6f746f736d6164726563 + 6c617365726573746f6e69c3b16f7175656461706173617262616e636f68696a + 6f737669616a657061626c6fc3a97374657669656e657265696e6f64656a6172 + 666f6e646f63616e616c6e6f7274656c657472616361757361746f6d61726d61 + 6e6f736c756e65736175746f7376696c6c6176656e646f70657361727469706f + 7374656e67616d6172636f6c6c6576617061647265756e69646f76616d6f737a + 6f6e6173616d626f7362616e64616d61726961616275736f6d75636861737562 + 697272696f6a617669766972677261646f6368696361616c6cc3ad6a6f76656e + 6469636861657374616e74616c657373616c69727375656c6f7065736f736669 + 6e65736c6c616d61627573636fc3a97374616c6c6567616e6567726f706c617a + 6168756d6f7270616761726a756e7461646f626c6569736c6173626f6c736162 + 61c3b16f6861626c616c75636861c381726561646963656e6a756761726e6f74 + 617376616c6c65616c6cc3a16361726761646f6c6f726162616a6f657374c3a9 + 677573746f6d656e74656d6172696f6669726d61636f73746f6669636861706c + 617461686f67617261727465736c65796573617175656c6d7573656f62617365 + 73706f636f736d697461646369656c6f636869636f6d6965646f67616e617273 + 616e746f65746170616465626573706c61796172656465737369657465636f72 + 7465636f7265616475646173646573656f7669656a6f64657365616167756173 + 2671756f743b646f6d61696e636f6d6d6f6e7374617475736576656e74736d61 + 7374657273797374656d616374696f6e62616e6e657272656d6f76657363726f + 6c6c757064617465676c6f62616c6d656469756d66696c7465726e756d626572 + 6368616e6765726573756c747075626c696373637265656e63686f6f73656e6f + 726d616c74726176656c697373756573736f7572636574617267657473707269 + 6e676d6f64756c656d6f62696c6573776974636870686f746f73626f72646572 + 726567696f6e697473656c66736f6369616c616374697665636f6c756d6e7265 + 636f7264666f6c6c6f777469746c653e6569746865726c656e67746866616d69 + 6c79667269656e646c61796f7574617574686f72637265617465726576696577 + 73756d6d6572736572766572706c61796564706c61796572657870616e64706f + 6c696379666f726d6174646f75626c65706f696e747373657269657370657273 + 6f6e6c6976696e6764657369676e6d6f6e746873666f72636573756e69717565 + 77656967687470656f706c65656e657267796e61747572657365617263686669 + 67757265686176696e67637573746f6d6f66667365746c657474657277696e64 + 6f777375626d697472656e64657267726f75707375706c6f61646865616c7468 + 6d6574686f64766964656f737363686f6f6c667574757265736861646f776465 + 6261746576616c7565734f626a6563746f74686572737269676874736c656167 + 75656368726f6d6573696d706c656e6f74696365736861726564656e64696e67 + 736561736f6e7265706f72746f6e6c696e65737175617265627574746f6e696d + 61676573656e61626c656d6f76696e676c617465737477696e7465724672616e + 6365706572696f647374726f6e677265706561744c6f6e646f6e64657461696c + 666f726d656464656d616e64736563757265706173736564746f67676c65706c + 6163657364657669636573746174696363697469657373747265616d79656c6c + + + +Alakuijala & Szabadka Expires June 10, 2016 [Page 43] + +Internet-Draft Brotli December 2015 + + + 6f7761747461636b737472656574666c6967687468696464656e696e666f223e + 6f70656e656475736566756c76616c6c65796361757365736c65616465727365 + 637265747365636f6e6464616d61676573706f72747365786365707472617469 + 6e677369676e65647468696e67736566666563746669656c6473737461746573 + 6f666669636576697375616c656469746f72766f6c756d655265706f72746d75 + 7365756d6d6f76696573706172656e746163636573736d6f73746c796d6f7468 + 6572222069643d226d61726b657467726f756e646368616e6365737572766579 + 6265666f726573796d626f6c6d6f6d656e747370656563686d6f74696f6e696e + 736964656d617474657243656e7465726f626a6563746578697374736d696464 + 6c654575726f706567726f7774686c65676163796d616e6e6572656e6f756768 + 636172656572616e737765726f726967696e706f7274616c636c69656e747365 + 6c65637472616e646f6d636c6f736564746f70696373636f6d696e6766617468 + 65726f7074696f6e73696d706c7972616973656465736361706563686f73656e + 636875726368646566696e65726561736f6e636f726e65726f75747075746d65 + 6d6f7279696672616d65706f6c6963656d6f64656c734e756d62657264757269 + 6e676f66666572737374796c65736b696c6c65646c697374656463616c6c6564 + 73696c7665726d617267696e64656c65746562657474657262726f7773656c69 + 6d697473476c6f62616c73696e676c6577696467657463656e74657262756467 + 65746e6f77726170637265646974636c61696d73656e67696e65736166657479 + 63686f6963657370697269742d7374796c657370726561646d616b696e676e65 + 65646564727573736961706c65617365657874656e7453637269707462726f6b + 656e616c6c6f7773636861726765646976696465666163746f726d656d626572 + 2d62617365647468656f7279636f6e66696761726f756e64776f726b65646865 + 6c706564436875726368696d7061637473686f756c64616c776179736c6f676f + 2220626f74746f6d6c697374223e297b766172207072656669786f72616e6765 + 4865616465722e7075736828636f75706c6567617264656e6272696467656c61 + 756e636852657669657774616b696e67766973696f6e6c6974746c6564617469 + 6e67427574746f6e6265617574797468656d6573666f72676f74536561726368 + 616e63686f72616c6d6f73746c6f616465644368616e676572657475726e7374 + 72696e6772656c6f61644d6f62696c65696e636f6d65737570706c79536f7572 + 63656f7264657273766965776564266e6273703b636f7572736541626f757420 + 69736c616e643c68746d6c20636f6f6b69656e616d653d22616d617a6f6e6d6f + 6465726e616476696365696e3c2f613e3a20546865206469616c6f67686f7573 + 6573424547494e204d657869636f73746172747363656e747265686569676874 + 616464696e6749736c616e64617373657473456d706972655363686f6f6c6566 + 666f72746469726563746e6561726c796d616e75616c53656c6563742e0a0a4f + 6e656a6f696e65646d656e75223e5068696c697061776172647368616e646c65 + 696d706f72744f6666696365726567617264736b696c6c736e6174696f6e5370 + 6f7274736465677265657765656b6c792028652e672e626568696e64646f6374 + 6f726c6f67676564756e697465643c2f623e3c2f626567696e73706c616e7473 + 61737369737461727469737469737375656433303070787c63616e6164616167 + 656e6379736368656d6572656d61696e4272617a696c73616d706c656c6f676f + 223e6265796f6e642d7363616c656163636570747365727665646d6172696e65 + 466f6f74657263616d6572613c2f68313e0a5f666f726d226c65617665737374 + 7265737322202f3e0d0a2e67696622206f6e6c6f61646c6f616465724f78666f + 72647369737465727375727669766c697374656e66656d616c6544657369676e + 73697a653d2261707065616c74657874223e6c6576656c737468616e6b736869 + 67686572666f72636564616e696d616c616e796f6e6541667269636161677265 + + + +Alakuijala & Szabadka Expires June 10, 2016 [Page 44] + +Internet-Draft Brotli December 2015 + + + 6564726563656e7450656f706c653c6272202f3e776f6e646572707269636573 + 7475726e65647c7c207b7d3b6d61696e223e696e6c696e6573756e6461797772 + 6170223e6661696c656463656e7375736d696e757465626561636f6e71756f74 + 657331353070787c65737461746572656d6f7465656d61696c226c696e6b6564 + 72696768743b7369676e616c666f726d616c312e68746d6c7369676e75707072 + 696e6365666c6f61743a2e706e672220666f72756d2e41636365737370617065 + 7273736f756e6473657874656e64486569676874736c696465725554462d3822 + 26616d703b204265666f72652e205769746873747564696f6f776e6572736d61 + 6e61676570726f6669746a5175657279616e6e75616c706172616d73626f7567 + 687466616d6f7573676f6f676c656c6f6e676572692b2b29207b69737261656c + 736179696e67646563696465686f6d65223e686561646572656e737572656272 + 616e6368706965636573626c6f636b3b737461746564746f70223e3c72616369 + 6e67726573697a652d2d2667743b70616369747973657875616c627572656175 + 2e6a7067222031302c3030306f627461696e7469746c6573616d6f756e742c20 + 496e632e636f6d6564796d656e7522206c7972696373746f6461792e696e6465 + 6564636f756e74795f6c6f676f2e46616d696c796c6f6f6b65644d61726b6574 + 6c7365206966506c617965727475726b6579293b76617220666f726573746769 + 76696e676572726f7273446f6d61696e7d656c73657b696e73657274426c6f67 + 3c2f666f6f7465726c6f67696e2e6661737465726167656e74733c626f647920 + 313070782030707261676d616672696461796a756e696f72646f6c6c6172706c + 61636564636f76657273706c7567696e352c3030302070616765223e626f7374 + 6f6e2e74657374286176617461727465737465645f636f756e74666f72756d73 + 736368656d61696e6465782c66696c6c6564736861726573726561646572616c + 657274286170706561725375626d69746c696e65223e626f6479223e0a2a2054 + 686554686f756768736565696e676a65727365794e6577733c2f766572696679 + 657870657274696e6a75727977696474683d436f6f6b69655354415254206163 + 726f73735f696d6167657468726561646e6174697665706f636b6574626f7822 + 3e0a53797374656d20446176696463616e6365727461626c657370726f766564 + 417072696c207265616c6c796472697665726974656d223e6d6f7265223e626f + 61726473636f6c6f727363616d7075736669727374207c7c205b5d3b6d656469 + 612e67756974617266696e69736877696474683a73686f7765644f7468657220 + 2e7068702220617373756d656c617965727377696c736f6e73746f7265737265 + 6c69656673776564656e437573746f6d656173696c7920796f75722053747269 + 6e670a0a5768696c7461796c6f72636c6561723a7265736f72746672656e6368 + 74686f7567682229202b20223c626f64793e627579696e676272616e64734d65 + 6d6265726e616d65223e6f7070696e67736563746f723570783b223e76737061 + 6365706f737465726d616a6f7220636f666665656d617274696e6d6174757265 + 68617070656e3c2f6e61763e6b616e7361736c696e6b223e496d616765733d66 + 616c73657768696c65206873706163653026616d703b200a0a496e2020706f77 + 6572506f6c736b692d636f6c6f726a6f7264616e426f74746f6d537461727420 + 2d636f756e74322e68746d6c6e657773223e30312e6a70674f6e6c696e652d72 + 696768746d696c6c657273656e696f724953424e2030302c3030302067756964 + 657376616c756529656374696f6e7265706169722e786d6c2220207269676874 + 732e68746d6c2d626c6f636b7265674578703a686f76657277697468696e7669 + 7267696e70686f6e65733c2f74723e0d7573696e67200a09766172203e27293b + 0a093c2f74643e0a3c2f74723e0a62616861736162726173696c67616c65676f + 6d6167796172706f6c736b69737270736b69d8b1d8afd988e4b8ade69687e7ae + 80e4bd93e7b981e9ab94e4bfa1e681afe4b8ade59bbde68891e4bbace4b880e4 + + + +Alakuijala & Szabadka Expires June 10, 2016 [Page 45] + +Internet-Draft Brotli December 2015 + + + b8aae585ace58fb8e7aea1e79086e8aebae59d9be58fafe4bba5e69c8de58aa1 + e697b6e997b4e4b8aae4babae4baa7e59381e887aae5b7b1e4bc81e4b89ae69f + a5e79c8be5b7a5e4bd9ce88194e7b3bbe6b2a1e69c89e7bd91e7ab99e68980e6 + 9c89e8af84e8aebae4b8ade5bf83e69687e7aba0e794a8e688b7e9a696e9a1b5 + e4bd9ce88085e68a80e69cafe997aee9a298e79bb8e585b3e4b88be8bdbde690 + 9ce7b4a2e4bdbfe794a8e8bdafe4bbb6e59ca8e7babfe4b8bbe9a298e8b584e6 + 9699e8a786e9a291e59b9ee5a48de6b3a8e5868ce7bd91e7bb9ce694b6e8978f + e58685e5aeb9e68ea8e88d90e5b882e59cbae6b688e681afe7a9bae997b4e58f + 91e5b883e4bb80e4b988e5a5bde58f8be7949fe6b4bbe59bbee78987e58f91e5 + b195e5a682e69e9ce6898be69cbae696b0e997bbe69c80e696b0e696b9e5bc8f + e58c97e4baace68f90e4be9be585b3e4ba8ee69bb4e5a49ae8bf99e4b8aae7b3 + bbe7bb9fe79fa5e98193e6b8b8e6888fe5b9bfe5918ae585b6e4bb96e58f91e8 + a1a8e5ae89e585a8e7acace4b880e4bc9ae59198e8bf9be8a18ce782b9e587bb + e78988e69d83e794b5e5ad90e4b896e7958ce8aebee8aea1e5858de8b4b9e695 + 99e882b2e58aa0e585a5e6b4bbe58aa8e4bb96e4bbace59586e59381e58d9ae5 + aea2e78eb0e59ca8e4b88ae6b5b7e5a682e4bd95e5b7b2e7bb8fe79599e8a880 + e8afa6e7bb86e7a4bee58cbae799bbe5bd95e69cace7ab99e99c80e8a681e4bb + b7e6a0bce694afe68c81e59bbde99985e993bee68ea5e59bbde5aeb6e5bbbae8 + aebee69c8be58f8be99885e8afbbe6b395e5be8be4bd8de7bdaee7bb8fe6b58e + e98089e68ba9e8bf99e6a0b7e5bd93e5898de58886e7b1bbe68e92e8a18ce59b + a0e4b8bae4baa4e69893e69c80e5908ee99fb3e4b990e4b88de883bde9809ae8 + bf87e8a18ce4b89ae7a791e68a80e58fafe883bde8aebee5a487e59088e4bd9c + e5a4a7e5aeb6e7a4bee4bc9ae7a094e7a9b6e4b893e4b89ae585a8e983a8e9a1 + b9e79baee8bf99e9878ce8bf98e698afe5bc80e5a78be68385e586b5e794b5e8 + 8491e69687e4bbb6e59381e7898ce5b8aee58aa9e69687e58c96e8b584e6ba90 + e5a4a7e5ada6e5ada6e4b9a0e59cb0e59d80e6b58fe8a788e68a95e8b584e5b7 + a5e7a88be8a681e6b182e6808ee4b988e697b6e58099e58a9fe883bde4b8bbe8 + a681e79baee5898de8b584e8aeafe59f8ee5b882e696b9e6b395e794b5e5bdb1 + e68b9be88198e5a3b0e6988ee4bbbbe4bd95e581a5e5bab7e695b0e68daee7be + 8ee59bbde6b1bde8bda6e4bb8be7bb8de4bd86e698afe4baa4e6b581e7949fe4 + baa7e68980e4bba5e794b5e8af9de698bee7a4bae4b880e4ba9be58d95e4bd8d + e4babae59198e58886e69e90e59cb0e59bbee69785e6b8b8e5b7a5e585b7e5ad + a6e7949fe7b3bbe58897e7bd91e58f8be5b896e5ad90e5af86e7a081e9a291e9 + 8193e68ea7e588b6e59cb0e58cbae59fbae69cace585a8e59bbde7bd91e4b88a + e9878de8a681e7acace4ba8ce5969ce6aca2e8bf9be585a5e58f8be68385e8bf + 99e4ba9be88083e8af95e58f91e78eb0e59fb9e8aeade4bba5e4b88ae694bfe5 + ba9ce68890e4b8bae78eafe5a283e9a699e6b8afe5908ce697b6e5a8b1e4b990 + e58f91e98081e4b880e5ae9ae5bc80e58f91e4bd9ce59381e6a087e58786e6ac + a2e8bf8ee8a7a3e586b3e59cb0e696b9e4b880e4b88be4bba5e58f8ae8b4a3e4 + bbbbe68896e88085e5aea2e688b7e4bba3e8a1a8e7a7afe58886e5a5b3e4baba + e695b0e7a081e99480e594aee587bae78eb0e7a6bbe7babfe5ba94e794a8e588 + 97e8a1a8e4b88de5908ce7bc96e8be91e7bb9fe8aea1e69fa5e8afa2e4b88de8 + a681e69c89e585b3e69cbae69e84e5be88e5a49ae692ade694bee7bb84e7bb87 + e694bfe7ad96e79bb4e68ea5e883bde58a9be69da5e6ba90e69982e99693e79c + 8be588b0e783ade997a8e585b3e994aee4b893e58cbae99d9ee5b8b8e88bb1e8 + afade799bee5baa6e5b88ce69c9be7be8ee5a5b3e6af94e8be83e79fa5e8af86 + e8a784e5ae9ae5bbbae8aeaee983a8e997a8e6848fe8a781e7b2bee5bda9e697 + a5e69cace68f90e9ab98e58f91e8a880e696b9e99da2e59fbae98791e5a484e7 + + + +Alakuijala & Szabadka Expires June 10, 2016 [Page 46] + +Internet-Draft Brotli December 2015 + + + 9086e69d83e99990e5bdb1e78987e993b6e8a18ce8bf98e69c89e58886e4baab + e789a9e59381e7bb8fe890a5e6b7bbe58aa0e4b893e5aeb6e8bf99e7a78de8af + 9de9a298e8b5b7e69da5e4b89ae58aa1e585ace5918ae8aeb0e5bd95e7ae80e4 + bb8be8b4a8e9878fe794b7e4babae5bdb1e5938de5bc95e794a8e68aa5e5918a + e983a8e58886e5bfabe9809fe592a8e8afa2e697b6e5b09ae6b3a8e6848fe794 + b3e8afb7e5ada6e6a0a1e5ba94e8afa5e58e86e58fb2e58faae698afe8bf94e5 + 9b9ee8b4ade4b9b0e5908de7a7b0e4b8bae4ba86e68890e58a9fe8afb4e6988e + e4be9be5ba94e5ada9e5ad90e4b893e9a298e7a88be5ba8fe4b880e888ace69c + 83e593a1e58faae69c89e585b6e5ae83e4bf9de68aa4e8808ce4b894e4bb8ae5 + a4a9e7aa97e58fa3e58aa8e68081e78ab6e68081e789b9e588abe8aea4e4b8ba + e5bf85e9a1bbe69bb4e696b0e5b08fe8afb4e68891e58091e4bd9ce4b8bae5aa + 92e4bd93e58c85e68bace982a3e4b988e4b880e6a0b7e59bbde58685e698afe5 + 90a6e6a0b9e68daee794b5e8a786e5ada6e999a2e585b7e69c89e8bf87e7a88b + e794b1e4ba8ee4babae6898de587bae69da5e4b88de8bf87e6ada3e59ca8e698 + 8ee6989fe69585e4ba8be585b3e7b3bbe6a087e9a298e59586e58aa1e8be93e5 + 85a5e4b880e79bb4e59fbae7a180e69599e5ada6e4ba86e8a7a3e5bbbae7ad91 + e7bb93e69e9ce585a8e79083e9809ae79fa5e8aea1e58892e5afb9e4ba8ee889 + bae69cafe79bb8e5868ce58f91e7949fe79c9fe79a84e5bbbae7ab8be7ad89e7 + baa7e7b1bbe59e8be7bb8fe9aa8ce5ae9ee78eb0e588b6e4bd9ce69da5e887aa + e6a087e7adbee4bba5e4b88be58e9fe5889be697a0e6b395e585b6e4b8ade580 + 8be4babae4b880e58887e68c87e58d97e585b3e997ade99b86e59ba2e7acace4 + b889e585b3e6b3a8e59ba0e6ada4e785a7e78987e6b7b1e59cb3e59586e4b89a + e5b9bfe5b79ee697a5e69c9fe9ab98e7baa7e69c80e8bf91e7bbbce59088e8a1 + a8e7a4bae4b893e8be91e8a18ce4b8bae4baa4e9809ae8af84e4bbb7e8a789e5 + be97e7b2bee58d8ee5aeb6e5baade5ae8ce68890e6849fe8a789e5ae89e8a385 + e5be97e588b0e982aee4bbb6e588b6e5baa6e9a39fe59381e899bde784b6e8bd + ace8bdbde68aa5e4bbb7e8aeb0e88085e696b9e6a188e8a18ce694bfe4babae6 + b091e794a8e59381e4b89ce8a5bfe68f90e587bae98592e5ba97e784b6e5908e + e4bb98e6acbee783ade782b9e4bba5e5898de5ae8ce585a8e58f91e5b896e8ae + bee7bdaee9a286e5afbce5b7a5e4b89ae58cbbe999a2e79c8be79c8be7bb8fe5 + 85b8e58e9fe59ba0e5b9b3e58fb0e59084e7a78de5a29ee58aa0e69d90e69699 + e696b0e5a29ee4b98be5908ee8818ce4b89ae69588e69e9ce4bb8ae5b9b4e8ae + bae69687e68891e59bbde5918ae8af89e78988e4b8bbe4bfaee694b9e58f82e4 + b88ee68993e58db0e5bfabe4b990e69cbae6a2b0e8a782e782b9e5ad98e59ca8 + e7b2bee7a59ee88eb7e5be97e588a9e794a8e7bba7e7bbade4bda0e4bbace8bf + 99e4b988e6a8a1e5bc8fe8afade8a880e883bde5a49fe99b85e8998ee6938de4 + bd9ce9a38ee6a0bce4b880e8b5b7e7a791e5ada6e4bd93e882b2e79fade4bfa1 + e69da1e4bbb6e6b2bbe79697e8bf90e58aa8e4baa7e4b89ae4bc9ae8aeaee5af + bce888aae58588e7949fe88194e79b9fe58fafe698afe5958fe9a18ce7bb93e6 + 9e84e4bd9ce794a8e8b083e69fa5e8b387e69699e887aae58aa8e8b49fe8b4a3 + e5869ce4b89ae8aebfe997aee5ae9ee696bde68ea5e58f97e8aea8e8aebae982 + a3e4b8aae58f8de9a688e58aa0e5bcbae5a5b3e680a7e88c83e59bb4e69c8de5 + 8b99e4bc91e997b2e4bb8ae697a5e5aea2e69c8de8a780e79c8be58f82e58aa0 + e79a84e8af9de4b880e782b9e4bf9de8af81e59bbee4b9a6e69c89e69588e6b5 + 8be8af95e7a7bbe58aa8e6898de883bde586b3e5ae9ae882a1e7a5a8e4b88de6 + 96ade99c80e6b182e4b88de5be97e58a9ee6b395e4b98be997b4e98787e794a8 + e890a5e99480e68a95e8af89e79baee6a087e788b1e68385e69184e5bdb1e69c + 89e4ba9be8a487e8a3bde69687e5ada6e69cbae4bc9ae695b0e5ad97e8a385e4 + + + +Alakuijala & Szabadka Expires June 10, 2016 [Page 47] + +Internet-Draft Brotli December 2015 + + + bfaee8b4ade789a9e5869ce69d91e585a8e99da2e7b2bee59381e585b6e5ae9e + e4ba8be68385e6b0b4e5b9b3e68f90e7a4bae4b88ae5b882e8b0a2e8b0a2e699 + aee9809ae69599e5b888e4b88ae4bca0e7b1bbe588abe6ad8ce69bb2e68ba5e6 + 9c89e5889be696b0e9858de4bbb6e58faae8a681e697b6e4bba3e8b387e8a88a + e8bebee588b0e4babae7949fe8aea2e99885e88081e5b888e5b195e7a4bae5bf + 83e79086e8b4b4e5ad90e7b6b2e7ab99e4b8bbe9a18ce887aae784b6e7baa7e5 + 88abe7ae80e58d95e694b9e99da9e982a3e4ba9be69da5e8afb4e68993e5bc80 + e4bba3e7a081e588a0e999a4e8af81e588b8e88a82e79baee9878de782b9e6ac + a1e695b8e5a49ae5b091e8a784e58892e8b584e98791e689bee588b0e4bba5e5 + 908ee5a4a7e585a8e4b8bbe9a1b5e69c80e4bdb3e59b9ee7ad94e5a4a9e4b88b + e4bf9de99a9ce78eb0e4bba3e6a380e69fa5e68a95e7a5a8e5b08fe697b6e6b2 + 92e69c89e6ada3e5b8b8e7949ae887b3e4bba3e79086e79baee5bd95e585ace5 + bc80e5a48de588b6e98791e89e8de5b9b8e7a68fe78988e69cace5bda2e68890 + e58786e5a487e8a18ce68385e59b9ee588b0e6809de683b3e6808ee6a0b7e58d + 8fe8aeaee8aea4e8af81e69c80e5a5bde4baa7e7949fe68c89e785a7e69c8de8 + a385e5b9bfe4b89ce58aa8e6bcabe98787e8b4ade696b0e6898be7bb84e59bbe + e99da2e69dbfe58f82e88083e694bfe6b2bbe5aeb9e69893e5a4a9e59cb0e58a + aae58a9be4babae4bbace58d87e7baa7e9809fe5baa6e4babae789a9e8b083e6 + 95b4e6b581e8a18ce980a0e68890e69687e5ad97e99fa9e59bbde8b4b8e69893 + e5bc80e5b195e79bb8e9979ce8a1a8e78eb0e5bdb1e8a786e5a682e6ada4e7be + 8ee5aeb9e5a4a7e5b08fe68aa5e98193e69da1e6acbee5bf83e68385e8aeb8e5 + a49ae6b395e8a784e5aeb6e5b185e4b9a6e5ba97e8bf9ee68ea5e7ab8be58db3 + e4b8bee68aa5e68a80e5b7a7e5a5a5e8bf90e799bbe585a5e4bba5e69da5e790 + 86e8aebae4ba8be4bbb6e887aae794b1e4b8ade58d8ee58a9ee585ace5a688e5 + a688e79c9fe6ada3e4b88de99499e585a8e69687e59088e5908ce4bbb7e580bc + e588abe4babae79b91e79da3e585b7e4bd93e4b896e7baaae59ba2e9989fe588 + 9be4b89ae689bfe68b85e5a29ee995bfe69c89e4babae4bf9de68c81e59586e5 + aeb6e7bbb4e4bfaee58fb0e6b9bee5b7a6e58fb3e882a1e4bbbde7ad94e6a188 + e5ae9ee99985e794b5e4bfa1e7bb8fe79086e7949fe591bde5aea3e4bca0e4bb + bbe58aa1e6ada3e5bc8fe789b9e889b2e4b88be69da5e58d8fe4bc9ae58faae8 + 83bde5bd93e784b6e9878de696b0e585a7e5aeb9e68c87e5afbce8bf90e8a18c + e697a5e5bf97e8b3a3e5aeb6e8b685e8bf87e59c9fe59cb0e6b599e6b19fe694 + afe4bb98e68ea8e587bae7ab99e995bfe69dade5b79ee689a7e8a18ce588b6e9 + 80a0e4b98be4b880e68ea8e5b9bfe78eb0e59cbae68f8fe8bfb0e58f98e58c96 + e4bca0e7bb9fe6ad8ce6898be4bf9de999a9e8afbee7a88be58cbbe79697e7bb + 8fe8bf87e8bf87e58ebbe4b98be5898de694b6e585a5e5b9b4e5baa6e69d82e5 + bf97e7be8ee4b8bde69c80e9ab98e799bbe99986e69caae69da5e58aa0e5b7a5 + e5858de8b4a3e69599e7a88be78988e59d97e8baabe4bd93e9878de5ba86e587 + bae594aee68890e69cace5bda2e5bc8fe59c9fe8b186e587bae583b9e4b89ce6 + 96b9e982aee7aeb1e58d97e4baace6b182e8818ce58f96e5be97e8818ce4bd8d + e79bb8e4bfa1e9a1b5e99da2e58886e9929fe7bd91e9a1b5e7a1aee5ae9ae59b + bee4be8be7bd91e59d80e7a7afe69e81e99499e8afafe79baee79a84e5ae9de8 + b49de69cbae585b3e9a38ee999a9e68e88e69d83e79785e6af92e5aea0e789a9 + e999a4e4ba86e8a995e8ab96e796bee79785e58f8ae697b6e6b182e8b4ade7ab + 99e782b9e584bfe7aba5e6af8fe5a4a9e4b8ade5a4aee8aea4e8af86e6af8fe4 + b8aae5a4a9e6b4a5e5ad97e4bd93e58fb0e781a3e7bbb4e68aa4e69cace9a1b5 + e4b8aae680a7e5ae98e696b9e5b8b8e8a781e79bb8e69cbae68898e795a5e5ba + 94e5bd93e5be8be5b888e696b9e4bebfe6a0a1e59bade882a1e5b882e688bfe5 + + + +Alakuijala & Szabadka Expires June 10, 2016 [Page 48] + +Internet-Draft Brotli December 2015 + + + b18be6a08fe79baee59198e5b7a5e5afbce887b4e7aa81e784b6e98193e585b7 + e69cace7bd91e7bb93e59088e6a1a3e6a188e58ab3e58aa8e58fa6e5a496e7be + 8ee58583e5bc95e8b5b7e694b9e58f98e7acace59b9be4bc9ae8aea1e8aaaae6 + 988ee99a90e7a781e5ae9de5ae9de8a784e88c83e6b688e8b4b9e585b1e5908c + e5bf98e8aeb0e4bd93e7b3bbe5b8a6e69da5e5908de5ad97e799bce8a1a8e5bc + 80e694bee58aa0e79b9fe58f97e588b0e4ba8ce6898be5a4a7e9878fe68890e4 + babae695b0e9878fe585b1e4baabe58cbae59f9fe5a5b3e5ada9e58e9fe58899 + e68980e59ca8e7bb93e69d9fe9809ae4bfa1e8b685e7baa7e9858de7bdaee5bd + 93e697b6e4bc98e7a780e680a7e6849fe688bfe4baa7e9818ae688b2e587bae5 + 8fa3e68f90e4baa4e5b0b1e4b89ae4bf9de581a5e7a88be5baa6e58f82e695b0 + e4ba8be4b89ae695b4e4b8aae5b1b1e4b89ce68385e6849fe789b9e6ae8ae588 + 86e9a19ee6909ce5b08be5b19ee4ba8ee997a8e688b7e8b4a2e58aa1e5a3b0e9 + 9fb3e58f8ae585b6e8b4a2e7bb8fe59d9ae68c81e5b9b2e983a8e68890e7ab8b + e588a9e79b8ae88083e89991e68890e983bde58c85e8a385e794a8e688b6e6af + 94e8b59be69687e6988ee68b9be59586e5ae8ce695b4e79c9fe698afe79cbce7 + 9d9be4bc99e4bcb4e5a881e69c9be9a286e59f9fe58dabe7949fe4bc98e683a0 + e8ab96e5a387e585ace585b1e889afe5a5bde58585e58886e7aca6e59088e999 + 84e4bbb6e789b9e782b9e4b88de58fafe88bb1e69687e8b584e4baa7e6a0b9e6 + 9cace6988ee698bee5af86e7a2bce585ace4bc97e6b091e6978fe69bb4e58aa0 + e4baabe58f97e5908ce5ada6e590afe58aa8e98082e59088e58e9fe69da5e997 + aee7ad94e69cace69687e7be8ee9a39fe7bbbfe889b2e7a8b3e5ae9ae7bb88e4 + ba8ee7949fe789a9e4be9be6b182e6909ce78b90e58a9be9878fe4b8a5e9878d + e6b0b8e8bf9ce58699e79c9fe69c89e99990e7ab9ee4ba89e5afb9e8b1a1e8b4 + b9e794a8e4b88de5a5bde7bb9de5afb9e58d81e58886e4bf83e8bf9be782b9e8 + af84e5bdb1e99fb3e4bc98e58abfe4b88de5b091e6aca3e8b58fe5b9b6e4b894 + e69c89e782b9e696b9e59091e585a8e696b0e4bfa1e794a8e8aebee696bde5bd + a2e8b1a1e8b584e6a0bce7aa81e7a0b4e99a8fe79d80e9878de5a4a7e4ba8ee6 + 98afe6af95e4b89ae699bae883bde58c96e5b7a5e5ae8ce7be8ee59586e59f8e + e7bb9fe4b880e587bae78988e68993e980a0e794a2e59381e6a682e586b5e794 + a8e4ba8ee4bf9de79599e59ba0e7b4a0e4b8ade59c8be5ad98e582a8e8b4b4e5 + 9bbee69c80e6849be995bfe69c9fe58fa3e4bbb7e79086e8b4a2e59fbae59cb0 + e5ae89e68e92e6ada6e6b189e9878ce99da2e5889be5bbbae5a4a9e7a9bae9a6 + 96e58588e5ae8ce59684e9a9b1e58aa8e4b88be99da2e4b88de5868de8af9ae4 + bfa1e6848fe4b989e998b3e58589e88bb1e59bbde6bc82e4baaee5869be4ba8b + e78ea9e5aeb6e7bea4e4bc97e5869ce6b091e58db3e58fafe5908de7a8b1e5ae + b6e585b7e58aa8e794bbe683b3e588b0e6b3a8e6988ee5b08fe5ada6e680a7e8 + 83bde88083e7a094e7a1ace4bbb6e8a782e79c8be6b885e6a59ae6909ee7ac91 + e9a696e9a081e9bb84e98791e98082e794a8e6b19fe88b8fe79c9fe5ae9ee4b8 + bbe7aea1e998b6e6aeb5e8a8bbe5868ae7bfbbe8af91e69d83e588a9e5819ae5 + a5bde4bcbce4b98ee9809ae8aeafe696bde5b7a5e78b80e6858be4b99fe8aeb8 + e78eafe4bf9de59fb9e585bbe6a682e5bfb5e5a4a7e59e8be69cbae7a5a8e790 + 86e8a7a3e58cbfe5908d6375616e646f656e766961726d616472696462757363 + 6172696e6963696f7469656d706f706f727175656375656e746165737461646f + 70756564656e6a7565676f73636f6e747261657374c3a16e6e6f6d6272657469 + 656e656e70657266696c6d616e657261616d69676f7363697564616463656e74 + 726f61756e71756570756564657364656e74726f7072696d657270726563696f + 736567c3ba6e6275656e6f73766f6c76657270756e746f7373656d616e616861 + 62c3ad6161676f73746f6e7565766f73756e69646f736361726c6f7365717569 + + + +Alakuijala & Szabadka Expires June 10, 2016 [Page 49] + +Internet-Draft Brotli December 2015 + + + 706f6e69c3b16f736d7563686f73616c67756e61636f7272656f696d6167656e + 7061727469726172726962616d6172c3ad61686f6d627265656d706c656f7665 + 7264616463616d62696f6d7563686173667565726f6e70617361646f6cc3ad6e + 65617061726563656e7565766173637572736f7365737461626171756965726f + 6c6962726f736375616e746f61636365736f6d696775656c766172696f736375 + 6174726f7469656e6573677275706f73736572c3a16e6575726f70616d656469 + 6f736672656e746561636572636164656dc3a1736f6665727461636f63686573 + 6d6f64656c6f6974616c69616c6574726173616c67c3ba6e636f6d7072616375 + 616c657365786973746563756572706f7369656e646f7072656e73616c6c6567 + 61727669616a657364696e65726f6d7572636961706f6472c3a170756573746f + 64696172696f707565626c6f7175696572656d616e75656c70726f70696f6372 + 6973697363696572746f73656775726f6d75657274656675656e746563657272 + 61726772616e646565666563746f7061727465736d656469646170726f706961 + 6f6672656365746965727261652d6d61696c766172696173666f726d61736675 + 7475726f6f626a65746f73656775697272696573676f6e6f726d61736d69736d + 6f73c3ba6e69636f63616d696e6f736974696f7372617ac3b36e64656269646f + 707275656261746f6c65646f74656ec3ad616a6573c3ba7365737065726f636f + 63696e616f726967656e7469656e64616369656e746f63c3a164697a6861626c + 6172736572c3ad616c6174696e61667565727a61657374696c6f677565727261 + 656e74726172c3a97869746f6cc3b370657a6167656e646176c3ad64656f6576 + 69746172706167696e616d6574726f736a617669657270616472657366c3a163 + 696c636162657a61c3a17265617373616c696461656e76c3ad6f6a6170c3b36e + 616275736f736269656e6573746578746f736c6c6576617270756564616e6675 + 65727465636f6dc3ba6e636c6173657368756d616e6f74656e69646f62696c62 + 616f756e69646164657374c3a17365646974617263726561646fd0b4d0bbd18f + d187d182d0bed0bad0b0d0bad0b8d0bbd0b8d18dd182d0bed0b2d181d0b5d0b5 + d0b3d0bed0bfd180d0b8d182d0b0d0bad0b5d189d0b5d183d0b6d0b5d09ad0b0 + d0bad0b1d0b5d0b7d0b1d18bd0bbd0bed0bdd0b8d092d181d0b5d0bfd0bed0b4 + d0add182d0bed182d0bed0bcd187d0b5d0bcd0bdd0b5d182d0bbd0b5d182d180 + d0b0d0b7d0bed0bdd0b0d0b3d0b4d0b5d0bcd0bdd0b5d094d0bbd18fd09fd180 + d0b8d0bdd0b0d181d0bdd0b8d185d182d0b5d0bcd0bad182d0bed0b3d0bed0b4 + d0b2d0bed182d182d0b0d0bcd0a1d0a8d090d0bcd0b0d18fd0a7d182d0bed0b2 + d0b0d181d0b2d0b0d0bcd0b5d0bcd183d0a2d0b0d0bad0b4d0b2d0b0d0bdd0b0 + d0bcd18dd182d0b8d18dd182d183d092d0b0d0bcd182d0b5d185d0bfd180d0be + d182d183d182d0bdd0b0d0b4d0b4d0bdd18fd092d0bed182d182d180d0b8d0bd + d0b5d0b9d092d0b0d181d0bdd0b8d0bcd181d0b0d0bcd182d0bed182d180d183 + d0b1d09ed0bdd0b8d0bcd0b8d180d0bdd0b5d0b5d09ed09ed09ed0bbd0b8d186 + d18dd182d0b0d09ed0bdd0b0d0bdd0b5d0bcd0b4d0bed0bcd0bcd0bed0b9d0b4 + d0b2d0b5d0bed0bdd0bed181d183d0b4e0a495e0a587e0a4b9e0a588e0a495e0 + a580e0a4b8e0a587e0a495e0a4bee0a495e0a58be0a494e0a4b0e0a4aae0a4b0 + e0a4a8e0a587e0a48fe0a495e0a495e0a4bfe0a4ade0a580e0a487e0a4b8e0a4 + 95e0a4b0e0a4a4e0a58be0a4b9e0a58be0a486e0a4aae0a4b9e0a580e0a4afe0 + a4b9e0a4afe0a4bee0a4a4e0a495e0a4a5e0a4be6a616772616ee0a486e0a49c + e0a49ce0a58be0a485e0a4ace0a4a6e0a58be0a497e0a488e0a49ce0a4bee0a4 + 97e0a48fe0a4b9e0a4aee0a487e0a4a8e0a4b5e0a4b9e0a4afe0a587e0a4a5e0 + a587e0a4a5e0a580e0a498e0a4b0e0a49ce0a4ace0a4a6e0a580e0a495e0a488 + e0a49ce0a580e0a4b5e0a587e0a4a8e0a488e0a4a8e0a48fe0a4b9e0a4b0e0a4 + 89e0a4b8e0a4aee0a587e0a495e0a4aee0a4b5e0a58be0a4b2e0a587e0a4b8e0 + + + +Alakuijala & Szabadka Expires June 10, 2016 [Page 50] + +Internet-Draft Brotli December 2015 + + + a4ace0a4aee0a488e0a4a6e0a587e0a493e0a4b0e0a486e0a4aee0a4ace0a4b8 + e0a4ade0a4b0e0a4ace0a4a8e0a49ae0a4b2e0a4aee0a4a8e0a486e0a497e0a4 + b8e0a580e0a4b2e0a580d8b9d984d989d8a5d984d989d987d8b0d8a7d8a2d8ae + d8b1d8b9d8afd8afd8a7d984d989d987d8b0d987d8b5d988d8b1d8bad98ad8b1 + d983d8a7d986d988d984d8a7d8a8d98ad986d8b9d8b1d8b6d8b0d984d983d987 + d986d8a7d98ad988d985d982d8a7d984d8b9d984d98ad8a7d986d8a7d984d983 + d986d8add8aad989d982d8a8d984d988d8add8a9d8a7d8aed8b1d981d982d8b7 + d8b9d8a8d8afd8b1d983d986d8a5d8b0d8a7d983d985d8a7d8a7d8add8afd8a5 + d984d8a7d981d98ad987d8a8d8b9d8b6d983d98ad981d8a8d8add8abd988d985 + d986d988d987d988d8a3d986d8a7d8acd8afd8a7d984d987d8a7d8b3d984d985 + d8b9d986d8afd984d98ad8b3d8b9d8a8d8b1d8b5d984d989d985d986d8b0d8a8 + d987d8a7d8a3d986d987d985d8abd984d983d986d8aad8a7d984d8a7d8add98a + d8abd985d8b5d8b1d8b4d8b1d8add8add988d984d988d981d98ad8a7d8b0d8a7 + d984d983d984d985d8b1d8a9d8a7d986d8aad8a7d984d981d8a3d8a8d988d8ae + d8a7d8b5d8a3d986d8aad8a7d986d987d8a7d984d98ad8b9d8b6d988d988d982 + d8afd8a7d8a8d986d8aed98ad8b1d8a8d986d8aad984d983d985d8b4d8a7d8a1 + d988d987d98ad8a7d8a8d988d982d8b5d8b5d988d985d8a7d8b1d982d985d8a3 + d8add8afd986d8add986d8b9d8afd985d8b1d8a3d98ad8a7d8add8a9d983d8aa + d8a8d8afd988d986d98ad8acd8a8d985d986d987d8aad8add8aad8acd987d8a9 + d8b3d986d8a9d98ad8aad985d983d8b1d8a9d8bad8b2d8a9d986d981d8b3d8a8 + d98ad8aad984d984d987d984d986d8a7d8aad984d983d982d984d8a8d984d985 + d8a7d8b9d986d987d8a3d988d984d8b4d98ad8a1d986d988d8b1d8a3d985d8a7 + d981d98ad983d8a8d983d984d8b0d8a7d8aad8b1d8aad8a8d8a8d8a3d986d987 + d985d8b3d8a7d986d983d8a8d98ad8b9d981d982d8afd8add8b3d986d984d987 + d985d8b4d8b9d8b1d8a3d987d984d8b4d987d8b1d982d8b7d8b1d8b7d984d8a8 + 70726f66696c657365727669636564656661756c7468696d73656c6664657461 + 696c73636f6e74656e74737570706f7274737461727465646d65737361676573 + 75636365737366617368696f6e3c7469746c653e636f756e7472796163636f75 + 6e746372656174656473746f72696573726573756c747372756e6e696e677072 + 6f6365737377726974696e676f626a6563747376697369626c6577656c636f6d + 6561727469636c65756e6b6e6f776e6e6574776f726b636f6d70616e7964796e + 616d696362726f777365727072697661637970726f626c656d53657276696365 + 72657370656374646973706c6179726571756573747265736572766577656273 + 697465686973746f7279667269656e64736f7074696f6e73776f726b696e6776 + 657273696f6e6d696c6c696f6e6368616e6e656c77696e646f772e6164647265 + 73737669736974656477656174686572636f727265637470726f647563746564 + 6972656374666f7277617264796f752063616e72656d6f7665647375626a6563 + 74636f6e74726f6c6172636869766563757272656e7472656164696e676c6962 + 726172796c696d697465646d616e616765726675727468657273756d6d617279 + 6d616368696e656d696e7574657370726976617465636f6e7465787470726f67 + 72616d736f63696574796e756d626572737772697474656e656e61626c656474 + 726967676572736f75726365736c6f6164696e67656c656d656e74706172746e + 657266696e616c6c79706572666563746d65616e696e6773797374656d736b65 + 6570696e6763756c747572652671756f743b2c6a6f75726e616c70726f6a6563 + 7473757266616365732671756f743b657870697265737265766965777362616c + 616e6365456e676c697368436f6e74656e747468726f756768506c6561736520 + 6f70696e696f6e636f6e74616374617665726167657072696d61727976696c6c + 6167655370616e69736867616c6c6572796465636c696e656d656574696e676d + + + +Alakuijala & Szabadka Expires June 10, 2016 [Page 51] + +Internet-Draft Brotli December 2015 + + + 697373696f6e706f70756c61727175616c6974796d65617375726567656e6572 + 616c7370656369657373657373696f6e73656374696f6e77726974657273636f + 756e746572696e697469616c7265706f727473666967757265736d656d626572 + 73686f6c64696e67646973707574656561726c69657265787072657373646967 + 6974616c70696374757265416e6f746865726d61727269656474726166666963 + 6c656164696e676368616e67656463656e7472616c766963746f7279696d6167 + 65732f726561736f6e7373747564696573666561747572656c697374696e676d + 7573742062657363686f6f6c7356657273696f6e757375616c6c79657069736f + 6465706c6179696e6767726f77696e676f6276696f75736f7665726c61797072 + 6573656e74616374696f6e733c2f756c3e0d0a77726170706572616c72656164 + 796365727461696e7265616c69747973746f72616765616e6f74686572646573 + 6b746f706f6666657265647061747465726e756e757375616c4469676974616c + 6361706974616c576562736974656661696c757265636f6e6e65637472656475 + 636564416e64726f696464656361646573726567756c61722026616d703b2061 + 6e696d616c7372656c656173654175746f6d617467657474696e676d6574686f + 64736e6f7468696e67506f70756c617263617074696f6e6c6574746572736361 + 7074757265736369656e63656c6963656e73656368616e676573456e676c616e + 643d3126616d703b486973746f7279203d206e65772043656e7472616c757064 + 617465645370656369616c4e6574776f726b72657175697265636f6d6d656e74 + 7761726e696e67436f6c6c656765746f6f6c62617272656d61696e7362656361 + 757365656c65637465644465757473636866696e616e6365776f726b65727371 + 7569636b6c796265747765656e65786163746c7973657474696e676469736561 + 7365536f6369657479776561706f6e7365786869626974266c743b212d2d436f + 6e74726f6c636c6173736573636f76657265646f75746c696e6561747461636b + 73646576696365732877696e646f77707572706f73657469746c653d224d6f62 + 696c65206b696c6c696e6773686f77696e674974616c69616e64726f70706564 + 68656176696c79656666656374732d31275d293b0a636f6e6669726d43757272 + 656e74616476616e636573686172696e676f70656e696e6764726177696e6762 + 696c6c696f6e6f7264657265644765726d616e7972656c617465643c2f666f72 + 6d3e696e636c75646577686574686572646566696e6564536369656e63656361 + 74616c6f6741727469636c65627574746f6e736c617267657374756e69666f72 + 6d6a6f75726e6579736964656261724368696361676f686f6c6964617947656e + 6572616c706173736167652c2671756f743b616e696d6174656665656c696e67 + 6172726976656470617373696e676e61747572616c726f7567686c792e0a0a54 + 686520627574206e6f7464656e736974794272697461696e4368696e6573656c + 61636b206f66747269627574654972656c616e642220646174612d666163746f + 727372656365697665746861742069734c69627261727968757362616e64696e + 206661637461666661697273436861726c65737261646963616c62726f756768 + 7466696e64696e676c616e64696e673a6c616e673d2272657475726e206c6561 + 64657273706c616e6e65647072656d69756d7061636b616765416d6572696361 + 45646974696f6e5d2671756f743b4d6573736167656e65656420746f76616c75 + 653d22636f6d706c65786c6f6f6b696e6773746174696f6e62656c6965766573 + 6d616c6c65722d6d6f62696c657265636f72647377616e7420746f6b696e6420 + 6f6646697265666f78796f752061726573696d696c6172737475646965646d61 + 78696d756d68656164696e6772617069646c79636c696d6174656b696e67646f + 6d656d6572676564616d6f756e7473666f756e64656470696f6e656572666f72 + 6d756c6164796e61737479686f7720746f20537570706f7274726576656e7565 + 65636f6e6f6d79526573756c747362726f74686572736f6c646965726c617267 + + + +Alakuijala & Szabadka Expires June 10, 2016 [Page 52] + +Internet-Draft Brotli December 2015 + + + 656c7963616c6c696e672e2671756f743b4163636f756e744564776172642073 + 65676d656e74526f62657274206566666f727473506163696669636c6561726e + 6564757020776974686865696768743a77652068617665416e67656c65736e61 + 74696f6e735f7365617263686170706c696564616371756972656d6173736976 + 656772616e7465643a2066616c7365747265617465646269676765737462656e + 6566697464726976696e67537475646965736d696e696d756d70657268617073 + 6d6f726e696e6773656c6c696e67697320757365647265766572736576617269 + 616e7420726f6c653d226d697373696e676163686965766570726f6d6f746573 + 747564656e74736f6d656f6e6565787472656d65726573746f7265626f74746f + 6d3a65766f6c766564616c6c20746865736974656d6170656e676c6973687761 + 7920746f202041756775737473796d626f6c73436f6d70616e796d6174746572 + 736d75736963616c616761696e737473657276696e677d2928293b0d0a706179 + 6d656e7474726f75626c65636f6e63657074636f6d70617265706172656e7473 + 706c6179657273726567696f6e736d6f6e69746f722027275468652077696e6e + 696e676578706c6f72656164617074656447616c6c65727970726f6475636561 + 62696c697479656e68616e636563617265657273292e2054686520636f6c6c65 + 637453656172636820616e6369656e7465786973746564666f6f746572206861 + 6e646c65727072696e746564636f6e736f6c654561737465726e6578706f7274 + 7377696e646f77734368616e6e656c696c6c6567616c6e65757472616c737567 + 676573745f6865616465727369676e696e672e68746d6c223e736574746c6564 + 7765737465726e63617573696e672d7765626b6974636c61696d65644a757374 + 6963656368617074657276696374696d7354686f6d6173206d6f7a696c6c6170 + 726f6d6973657061727469657365646974696f6e6f7574736964653a66616c73 + 652c68756e647265644f6c796d7069635f627574746f6e617574686f72737265 + 61636865646368726f6e696364656d616e64737365636f6e647370726f746563 + 7461646f70746564707265706172656e65697468657267726561746c79677265 + 617465726f766572616c6c696d70726f7665636f6d6d616e647370656369616c + 7365617263682e776f727368697066756e64696e6774686f7567687468696768 + 657374696e73746561647574696c6974797175617274657243756c7475726574 + 657374696e67636c6561726c796578706f73656442726f777365726c69626572 + 616c7d20636174636850726f6a6563746578616d706c656869646528293b466c + 6f72696461616e7377657273616c6c6f776564456d7065726f72646566656e73 + 65736572696f757366726565646f6d5365766572616c2d627574746f6e467572 + 746865726f7574206f6620213d206e756c6c747261696e656444656e6d61726b + 766f69642830292f616c6c2e6a7370726576656e745265717565737453746570 + 68656e0a0a5768656e206f6273657276653c2f68323e0d0a4d6f6465726e2070 + 726f766964652220616c743d22626f72646572732e0a0a466f72200a0a4d616e + 792061727469737473706f7765726564706572666f726d66696374696f6e7479 + 7065206f666d65646963616c7469636b6574736f70706f736564436f756e6369 + 6c7769746e6573736a75737469636547656f7267652042656c6769756d2e2e2e + 3c2f613e747769747465726e6f7461626c7977616974696e6777617266617265 + 204f746865722072616e6b696e67706872617365736d656e74696f6e73757276 + 6976657363686f6c61723c2f703e0d0a20436f756e74727969676e6f7265646c + 6f7373206f666a75737420617347656f72676961737472616e67653c68656164 + 3e3c73746f7070656431275d293b0d0a69736c616e64736e6f7461626c65626f + 726465723a6c697374206f66636172726965643130302c3030303c2f68333e0a + 207365766572616c6265636f6d657373656c6563742077656464696e6730302e + 68746d6c6d6f6e617263686f66662074686574656163686572686967686c7920 + + + +Alakuijala & Szabadka Expires June 10, 2016 [Page 53] + +Internet-Draft Brotli December 2015 + + + 62696f6c6f67796c696665206f666f72206576656e72697365206f6626726171 + 756f3b706c75736f6e6568756e74696e672874686f756768446f75676c61736a + 6f696e696e67636972636c6573466f7220746865416e6369656e74566965746e + 616d76656869636c65737563682061736372797374616c76616c7565203d5769 + 6e646f7773656e6a6f7965646120736d616c6c617373756d65643c612069643d + 22666f726569676e20416c6c207269686f7720746865446973706c6179726574 + 69726564686f776576657268696464656e3b626174746c65737365656b696e67 + 636162696e6574776173206e6f746c6f6f6b206174636f6e6475637467657420 + 7468654a616e7561727968617070656e737475726e696e67613a686f7665724f + 6e6c696e65204672656e6368206c61636b696e677479706963616c6578747261 + 6374656e656d6965736576656e20696667656e65726174646563696465646172 + 65206e6f742f73656172636862656c696566732d696d6167653a6c6f63617465 + 647374617469632e6c6f67696e223e636f6e7665727476696f6c656e74656e74 + 657265646669727374223e6369726375697446696e6c616e646368656d697374 + 73686520776173313070783b223e61732073756368646976696465643c2f7370 + 616e3e77696c6c2062656c696e65206f66612067726561746d7973746572792f + 696e6465782e66616c6c696e6764756520746f207261696c776179636f6c6c65 + 67656d6f6e7374657264657363656e74697420776974686e75636c6561724a65 + 776973682070726f7465737442726974697368666c6f77657273707265646963 + 747265666f726d73627574746f6e2077686f207761736c656374757265696e73 + 74616e747375696369646567656e65726963706572696f64736d61726b657473 + 536f6369616c2066697368696e67636f6d62696e656772617068696377696e6e + 6572733c6272202f3e3c627920746865204e61747572616c5072697661637963 + 6f6f6b6965736f7574636f6d657265736f6c7665537765646973686272696566 + 6c795065727369616e736f206d75636843656e7475727964657069637473636f + 6c756d6e73686f7573696e67736372697074736e65787420746f62656172696e + 676d617070696e67726576697365646a5175657279282d77696474683a746974 + 6c65223e746f6f6c74697053656374696f6e64657369676e735475726b697368 + 796f756e6765722e6d61746368287d2928293b0a0a6275726e696e676f706572 + 61746564656772656573736f757263653d52696368617264636c6f73656c7970 + 6c6173746963656e74726965733c2f74723e0d0a636f6c6f723a23756c206964 + 3d22706f7373657373726f6c6c696e67706879736963736661696c696e676578 + 6563757465636f6e746573746c696e6b20746f44656661756c743c6272202f3e + 0a3a20747275652c63686172746572746f757269736d636c617373696370726f + 636565646578706c61696e3c2f68313e0d0a6f6e6c696e652e3f786d6c207665 + 68656c70696e676469616d6f6e64757365207468656169726c696e65656e6420 + 2d2d3e292e617474722872656164657273686f7374696e672366666666666672 + 65616c697a6556696e63656e747369676e616c73207372633d222f50726f6475 + 6374646573706974656469766572736574656c6c696e675075626c6963206865 + 6c6420696e4a6f736570682074686561747265616666656374733c7374796c65 + 3e61206c61726765646f65736e27746c617465722c20456c656d656e74666176 + 69636f6e63726561746f7248756e67617279416972706f727473656520746865 + 736f20746861744d69636861656c53797374656d7350726f6772616d732c2061 + 6e64202077696474683d652671756f743b74726164696e676c656674223e0a70 + 6572736f6e73476f6c64656e20416666616972736772616d6d6172666f726d69 + 6e6764657374726f7969646561206f6663617365206f666f6c64657374207468 + 69732069732e737263203d20636172746f6f6e72656769737472436f6d6d6f6e + 734d75736c696d7357686174206973696e206d616e796d61726b696e67726576 + + + +Alakuijala & Szabadka Expires June 10, 2016 [Page 54] + +Internet-Draft Brotli December 2015 + + + 65616c73496e646565642c657175616c6c792f73686f775f616f7574646f6f72 + 657363617065284175737472696167656e6574696373797374656d2c496e2074 + 68652073697474696e67486520616c736f49736c616e647341636164656d790a + 09093c212d2d44616e69656c2062696e64696e67626c6f636b223e696d706f73 + 65647574696c697a654162726168616d286578636570747b77696474683a7075 + 7474696e67292e68746d6c287c7c205b5d3b0a444154415b202a6b6974636865 + 6e6d6f756e74656461637475616c206469616c6563746d61696e6c79205f626c + 616e6b27696e7374616c6c6578706572747369662874797065497420616c736f + 26636f70793b20223e5465726d73626f726e20696e4f7074696f6e7365617374 + 65726e74616c6b696e67636f6e6365726e6761696e6564206f6e676f696e676a + 75737469667963726974696373666163746f7279697473206f776e6173736175 + 6c74696e76697465646c617374696e67686973206f776e687265663d222f2220 + 72656c3d22646576656c6f70636f6e636572746469616772616d646f6c6c6172 + 73636c75737465727068703f69643d616c636f686f6c293b7d2928293b757369 + 6e6720613e3c7370616e3e76657373656c737265766976616c41646472657373 + 616d6174657572616e64726f6964616c6c65676564696c6c6e65737377616c6b + 696e6763656e746572737175616c6966796d617463686573756e696669656465 + 7874696e6374446566656e73656469656420696e0a093c212d2d20637573746f + 6d736c696e6b696e674c6974746c6520426f6f6b206f666576656e696e676d69 + 6e2e6a733f617265207468656b6f6e74616b74746f64617927732e68746d6c22 + 207461726765743d77656172696e67416c6c205269673b0a7d2928293b726169 + 73696e6720416c736f2c206372756369616c61626f7574223e6465636c617265 + 2d2d3e0a3c736366697265666f786173206d7563686170706c696573696e6465 + 782c20732c206275742074797065203d200a0d0a3c212d2d746f776172647352 + 65636f72647350726976617465466f726569676e5072656d69657263686f6963 + 65735669727475616c72657475726e73436f6d6d656e74506f7765726564696e + 6c696e653b706f76657274796368616d6265724c6976696e6720766f6c756d65 + 73416e74686f6e796c6f67696e222052656c6174656445636f6e6f6d79726561 + 6368657363757474696e67677261766974796c69666520696e43686170746572 + 2d736861646f774e6f7461626c653c2f74643e0d0a2072657475726e73746164 + 69756d7769646765747376617279696e6774726176656c7368656c6420627977 + 686f20617265776f726b20696e666163756c7479616e67756c617277686f2068 + 6164616972706f7274746f776e206f660a0a536f6d652027636c69636b276368 + 61726765736b6579776f726469742077696c6c63697479206f66287468697329 + 3b416e6472657720756e6971756520636865636b65646f72206d6f7265333030 + 70783b2072657475726e3b7273696f6e3d22706c7567696e7377697468696e20 + 68657273656c6653746174696f6e4665646572616c76656e747572657075626c + 69736873656e7420746f74656e73696f6e61637472657373636f6d6520746f66 + 696e6765727344756b65206f6670656f706c652c6578706c6f69747768617420 + 69736861726d6f6e7961206d616a6f72223a2268747470696e20686973206d65 + 6e75223e0a6d6f6e74686c796f666669636572636f756e63696c6761696e696e + 676576656e20696e53756d6d61727964617465206f666c6f79616c7479666974 + 6e657373616e6420776173656d7065726f7273757072656d655365636f6e6420 + 68656172696e675275737369616e6c6f6e67657374416c62657274616c617465 + 72616c736574206f6620736d616c6c223e2e617070656e64646f207769746866 + 65646572616c62616e6b206f6662656e65617468446573706974654361706974 + 616c67726f756e6473292c20616e642070657263656e7469742066726f6d636c + 6f73696e67636f6e7461696e496e73746561646669667465656e61732077656c + + + +Alakuijala & Szabadka Expires June 10, 2016 [Page 55] + +Internet-Draft Brotli December 2015 + + + 6c2e7961686f6f2e726573706f6e64666967687465726f627363757265726566 + 6c6563746f7267616e69633d204d6174682e65646974696e676f6e6c696e6520 + 70616464696e67612077686f6c656f6e6572726f7279656172206f66656e6420 + 6f6620626172726965727768656e20697468656164657220686f6d65206f6672 + 6573756d656472656e616d65647374726f6e673e68656174696e677265746169 + 6e73636c6f75646672776179206f66204d6172636820316b6e6f77696e67696e + 20706172744265747765656e6c6573736f6e73636c6f73657374766972747561 + 6c6c696e6b73223e63726f73736564454e44202d2d3e66616d6f757320617761 + 726465644c6963656e73654865616c746820666169726c79207765616c746879 + 6d696e696d616c4166726963616e636f6d706574656c6162656c223e73696e67 + 696e676661726d65727342726173696c29646973637573737265706c61636547 + 7265676f7279666f6e7420636f70757273756564617070656172736d616b6520 + 7570726f756e646564626f7468206f66626c6f636b6564736177207468656f66 + 6669636573636f6c6f757273696628646f63757768656e206865656e666f7263 + 6570757368286675417567757374205554462d38223e46616e74617379696e20 + 6d6f7374696e6a75726564557375616c6c796661726d696e67636c6f73757265 + 6f626a65637420646566656e6365757365206f66204d65646963616c3c626f64 + 793e0a65766964656e74626520757365646b6579436f64657369787465656e49 + 736c616d696323303030303030656e7469726520776964656c79206163746976 + 652028747970656f666f6e652063616e636f6c6f72203d737065616b65726578 + 74656e6473506879736963737465727261696e3c74626f64793e66756e657261 + 6c76696577696e676d6964646c6520637269636b657470726f70686574736869 + 66746564646f63746f727352757373656c6c20746172676574636f6d70616374 + 616c6765627261736f6369616c2d62756c6b206f666d616e20616e643c2f7464 + 3e0a206865206c656674292e76616c282966616c7365293b6c6f676963616c62 + 616e6b696e67686f6d6520746f6e616d696e67204172697a6f6e616372656469 + 7473293b0a7d293b0a666f756e646572696e207475726e436f6c6c696e736265 + 666f72652042757420746865636861726765645469746c65223e436170746169 + 6e7370656c6c6564676f6464657373546167202d2d3e416464696e673a627574 + 20776173526563656e742070617469656e746261636b20696e3d66616c736526 + 4c696e636f6c6e7765206b6e6f77436f756e7465724a75646169736d73637269 + 707420616c7465726564275d293b0a202068617320746865756e636c65617245 + 76656e74272c626f746820696e6e6f7420616c6c0a0a3c212d2d20706c616369 + 6e676861726420746f2063656e746572736f7274206f66636c69656e74737374 + 72656574734265726e6172646173736572747374656e6420746f66616e746173 + 79646f776e20696e686172626f757246726565646f6d6a6577656c72792f6162 + 6f75742e2e7365617263686c6567656e64736973206d6164656d6f6465726e20 + 6f6e6c79206f6e6f6e6c7920746f696d61676522206c696e656172207061696e + 746572616e64206e6f74726172656c79206163726f6e796d64656c6976657273 + 686f72746572303026616d703b6173206d616e7977696474683d222f2a203c21 + 5b437469746c65203d6f6620746865206c6f77657374207069636b6564206573 + 636170656475736573206f6670656f706c6573205075626c69634d6174746865 + 777461637469637364616d6167656477617920666f726c617773206f66656173 + 7920746f2077696e646f777374726f6e67202073696d706c657d636174636828 + 736576656e7468696e666f626f7877656e7420746f7061696e74656463697469 + 7a656e4920646f6e2774726574726561742e20536f6d652077772e22293b0a62 + 6f6d62696e676d61696c746f3a6d61646520696e2e204d616e79206361727269 + 65737c7c7b7d3b7769776f726b206f6673796e6f6e796d646566656174736661 + + + +Alakuijala & Szabadka Expires June 10, 2016 [Page 56] + +Internet-Draft Brotli December 2015 + + + 766f7265646f70746963616c70616765547261756e6c6573732073656e64696e + 676c656674223e3c636f6d53636f72416c6c207468656a51756572792e746f75 + 72697374436c617373696366616c7365222057696c68656c6d73756275726273 + 67656e75696e65626973686f70732e73706c697428676c6f62616c20666f6c6c + 6f7773626f6479206f666e6f6d696e616c436f6e74616374736563756c61726c + 65667420746f63686965666c792d68696464656e2d62616e6e65723c2f6c693e + 0a0a2e205768656e20696e20626f74686469736d6973734578706c6f7265616c + 776179732076696120746865737061c3b16f6c77656c6661726572756c696e67 + 20617272616e67656361707461696e68697320736f6e72756c65206f66686520 + 746f6f6b697473656c662c3d3026616d703b2863616c6c656473616d706c6573 + 746f206d616b65636f6d2f7061674d617274696e204b656e6e65647961636365 + 70747366756c6c206f6668616e646c6564426573696465732f2f2d2d3e3c2f61 + 626c6520746f74617267657473657373656e636568696d20746f206974732062 + 7920636f6d6d6f6e2e6d696e6572616c746f2074616b657761797320746f732e + 6f72672f6c6164766973656470656e616c747973696d706c653a696620746865 + 794c657474657273612073686f727448657262657274737472696b6573206772 + 6f7570732e6c656e677468666c69676874736f7665726c6170736c6f776c7920 + 6c657373657220736f6369616c203c2f703e0a0909697420696e746f72616e6b + 65642072617465206f66756c3e0d0a2020617474656d707470616972206f666d + 616b652069744b6f6e74616b74416e746f6e696f686176696e6720726174696e + 67732061637469766573747265616d737472617070656422292e63737328686f + 7374696c656c65616420746f6c6974746c652067726f7570732c506963747572 + 652d2d3e0d0a0d0a20726f77733d22206f626a656374696e76657273653c666f + 6f746572437573746f6d563e3c5c2f736372736f6c76696e674368616d626572 + 736c6176657279776f756e64656477686572656173213d2027756e64666f7220 + 616c6c706172746c79202d72696768743a4172616269616e6261636b65642063 + 656e74757279756e6974206f666d6f62696c652d4575726f70652c697320686f + 6d657269736b206f6664657369726564436c696e746f6e636f7374206f666167 + 65206f66206265636f6d65206e6f6e65206f66702671756f743b4d6964646c65 + 2065616427295b304372697469637373747564696f733e26636f70793b67726f + 7570223e617373656d626c6d616b696e6720707265737365647769646765742e + 70733a22203f2072656275696c74627920736f6d65466f726d65722065646974 + 6f727364656c6179656443616e6f6e69636861642074686570757368696e6763 + 6c6173733d22627574206172657061727469616c426162796c6f6e626f74746f + 6d2063617272696572436f6d6d616e646974732075736541732077697468636f + 75727365736120746869726464656e6f746573616c736f20696e486f7573746f + 6e323070783b223e61636375736564646f75626c6520676f616c206f6646616d + 6f757320292e62696e642870726965737473204f6e6c696e65696e204a756c79 + 7374202b202267636f6e73756c74646563696d616c68656c7066756c72657669 + 7665646973207665727972272b276970746c6f73696e672066656d616c657369 + 7320616c736f737472696e677364617973206f666172726976616c6675747572 + 65203c6f626a656374666f7263696e67537472696e672822202f3e0a09096865 + 7265206973656e636f6465642e20205468652062616c6c6f6f6e646f6e652062 + 792f636f6d6d6f6e6267636f6c6f726c6177206f6620496e6469616e6161766f + 6964656462757420746865327078203370786a71756572792e61667465722061 + 706f6c6963792e6d656e20616e64666f6f7465722d3d20747275653b666f7220 + 75736573637265656e2e496e6469616e20696d616765203d66616d696c792c68 + 7474703a2f2f20266e6273703b64726976657273657465726e616c73616d6520 + + + +Alakuijala & Szabadka Expires June 10, 2016 [Page 57] + +Internet-Draft Brotli December 2015 + + + 61736e6f7469636564766965776572737d2928293b0a206973206d6f72657365 + 61736f6e73666f726d657220746865206e65776973206a757374636f6e73656e + 742053656172636877617320746865776879207468657368697070656462723e + 3c62723e77696474683a206865696768743d6d616465206f6663756973696e65 + 697320746861746120766572792041646d6972616c2066697865643b6e6f726d + 616c204d697373696f6e50726573732c206f6e746172696f6368617273657474 + 727920746f20696e76616465643d22747275652273706163696e676973206d6f + 737461206d6f726520746f74616c6c7966616c6c206f667d293b0d0a2020696d + 6d656e736574696d6520696e736574206f757473617469736679746f2066696e + 64646f776e20746f6c6f74206f6620506c6179657273696e204a756e65717561 + 6e74756d6e6f742074686574696d6520746f64697374616e7446696e6e697368 + 737263203d202873696e676c652068656c70206f664765726d616e206c617720 + 616e646c6162656c6564666f7265737473636f6f6b696e677370616365223e68 + 65616465722d77656c6c2061735374616e6c6579627269646765732f676c6f62 + 616c43726f617469612041626f7574205b305d3b0a202069742c20616e646772 + 6f757065646265696e672061297b7468726f776865206d6164656c6967687465 + 726574686963616c46464646464622626f74746f6d226c696b65206120656d70 + 6c6f79736c69766520696e6173207365656e7072696e7465726d6f7374206f66 + 75622d6c696e6b72656a65637473616e6420757365696d616765223e73756363 + 65656466656564696e674e75636c656172696e666f726d61746f2068656c7057 + 6f6d656e27734e6569746865724d65786963616e70726f7465696e3c7461626c + 65206279206d616e796865616c7468796c617773756974646576697365642e70 + 757368287b73656c6c65727373696d706c79205468726f7567682e636f6f6b69 + 6520496d616765286f6c646572223e75732e6a73223e2053696e636520756e69 + 766572736c6172676572206f70656e20746f212d2d20656e646c69657320696e + 275d293b0d0a20206d61726b657477686f206973202822444f4d436f6d616e61 + 6765646f6e6520666f72747970656f66204b696e67646f6d70726f6669747370 + 726f706f7365746f2073686f7763656e7465723b6d6164652069746472657373 + 65647765726520696e6d6978747572657072656369736561726973696e677372 + 63203d20276d616b652061207365637572656442617074697374766f74696e67 + 200a0909766172204d61726368203267726577207570436c696d6174652e7265 + 6d6f7665736b696c6c6564776179207468653c2f686561643e66616365206f66 + 616374696e67207269676874223e746f20776f726b7265647563657368617320 + 6861646572656374656473686f7728293b616374696f6e3d626f6f6b206f6661 + 6e20617265613d3d20226874743c6865616465720a3c68746d6c3e636f6e666f + 726d666163696e6720636f6f6b69652e72656c79206f6e686f73746564202e63 + 7573746f6d68652077656e7462757420666f727370726561642046616d696c79 + 2061206d65616e736f757420746865666f72756d732e666f6f74616765223e4d + 6f62696c436c656d656e7473222069643d2261732068696768696e74656e7365 + 2d2d3e3c212d2d66656d616c65206973207365656e696d706c69656473657420 + 74686561207374617465616e6420686973666173746573746265736964657362 + 7574746f6e5f626f756e646564223e3c696d6720496e666f626f786576656e74 + 732c6120796f756e67616e64206172654e617469766520636865617065725469 + 6d656f7574616e6420686173656e67696e6573776f6e20746865286d6f73746c + 7972696768743a2066696e642061202d626f74746f6d5072696e636520617265 + 61206f666d6f7265206f667365617263685f6e61747572652c6c6567616c6c79 + 706572696f642c6c616e64206f666f722077697468696e647563656470726f76 + 696e676d697373696c656c6f63616c6c79416761696e7374746865207761796b + + + +Alakuijala & Szabadka Expires June 10, 2016 [Page 58] + +Internet-Draft Brotli December 2015 + + + 2671756f743b70783b223e0d0a707573686564206162616e646f6e6e756d6572 + 616c4365727461696e496e20746869736d6f726520696e6f7220736f6d656e61 + 6d65206973616e642c20696e63726f776e65644953424e20302d637265617465 + 734f63746f6265726d6179206e6f7463656e746572206c61746520696e446566 + 656e6365656e61637465647769736820746f62726f61646c79636f6f6c696e67 + 6f6e6c6f61643d69742e205468657265636f7665724d656d6265727368656967 + 687420617373756d65733c68746d6c3e0a70656f706c652e696e206f6e65203d + 77696e646f77666f6f7465725f6120676f6f642072656b6c616d616f74686572 + 732c746f20746869735f636f6f6b696570616e656c223e4c6f6e646f6e2c6465 + 66696e6573637275736865646261707469736d636f617374616c737461747573 + 207469746c6522206d6f766520746f6c6f737420696e62657474657220696d70 + 6c696573726976616c7279736572766572732053797374656d50657268617073 + 657320616e6420636f6e74656e64666c6f77696e676c61737465642072697365 + 20696e47656e6573697376696577206f66726973696e67207365656d20746f62 + 757420696e206261636b696e6768652077696c6c676976656e2061676976696e + 67206369746965732e666c6f77206f66204c6174657220616c6c206275744869 + 67687761796f6e6c792062797369676e206f66686520646f6573646966666572 + 736261747465727926616d703b6c6173696e676c657374687265617473696e74 + 6567657274616b65206f6e7265667573656463616c6c6564203d555326616d70 + 536565207468656e6174697665736279207468697373797374656d2e68656164 + 206f663a686f7665722c6c65736269616e7375726e616d65616e6420616c6c63 + 6f6d6d6f6e2f6865616465725f5f706172616d73486172766172642f70697865 + 6c2e72656d6f76616c736f206c6f6e67726f6c65206f666a6f696e746c79736b + 7973637261556e69636f64656272202f3e0d0a41746c616e74616e75636c6575 + 73436f756e74792c707572656c7920636f756e74223e656173696c7920627569 + 6c6420616f6e636c69636b6120676976656e706f696e746572682671756f743b + 6576656e747320656c7365207b0a646974696f6e736e6f77207468652c207769 + 7468206d616e2077686f6f72672f5765626f6e6520616e64636176616c727948 + 65206469656473656174746c6530302c303030207b77696e646f776861766520 + 746f69662877696e64616e6420697473736f6c656c79206d2671756f743b7265 + 6e65776564446574726f6974616d6f6e677374656974686572207468656d2069 + 6e53656e61746f7255733c2f613e3c4b696e67206f664672616e6369732d7072 + 6f6475636865207573656461727420616e6468696d20616e6475736564206279 + 73636f72696e67617420686f6d65746f206861766572656c617465736962696c + 69747966616374696f6e42756666616c6f6c696e6b223e3c7768617420686566 + 72656520746f43697479206f66636f6d6520696e736563746f7273636f756e74 + 65646f6e65206461796e6572766f7573737175617265207d3b696628676f696e + 2077686174696d672220616c6973206f6e6c797365617263682f747565736461 + 796c6f6f73656c79536f6c6f6d6f6e73657875616c202d203c612068726d6564 + 69756d22444f204e4f54204672616e63652c7769746820612077617220616e64 + 7365636f6e642074616b652061203e0d0a0d0a0d0a6d61726b65742e68696768 + 776179646f6e6520696e63746976697479226c617374223e6f626c6967656472 + 69736520746f22756e646566696d61646520746f204561726c79207072616973 + 6564696e2069747320666f72206869736174686c6574654a7570697465725961 + 686f6f21207465726d656420736f206d616e797265616c6c7920732e20546865 + 206120776f6d616e3f76616c75653d6469726563742072696768742220626963 + 79636c656163696e673d2264617920616e6473746174696e675261746865722c + 686967686572204f666669636520617265206e6f7774696d65732c207768656e + + + +Alakuijala & Szabadka Expires June 10, 2016 [Page 59] + +Internet-Draft Brotli December 2015 + + + 20612070617920666f726f6e20746869732d6c696e6b223e3b626f7264657261 + 726f756e6420616e6e75616c20746865204e6577707574207468652e636f6d22 + 2074616b696e20746f6120627269656628696e2074686567726f7570732e3b20 + 7769647468656e7a796d657373696d706c6520696e206c6174657b7265747572 + 6e746865726170796120706f696e7462616e6e696e67696e6b73223e0a28293b + 222072656120706c6163655c75303033436161626f7574206174723e0d0a0909 + 63636f756e7420676976657320613c5343524950545261696c7761797468656d + 65732f746f6f6c626f784279496428227868756d616e732c7761746368657369 + 6e20736f6d6520696620287769636f6d696e6720666f726d61747320556e6465 + 72206275742068617368616e646564206d6164652062797468616e20696e6665 + 6172206f6664656e6f7465642f696672616d656c65667420696e766f6c746167 + 65696e2065616368612671756f743b62617365206f66496e206d616e79756e64 + 6572676f726567696d6573616374696f6e203c2f703e0d0a3c7573746f6d5661 + 3b2667743b3c2f696d706f7274736f7220746861746d6f73746c792026616d70 + 3b72652073697a653d223c2f613e3c2f686120636c6173737061737369766548 + 6f7374203d205768657468657266657274696c65566172696f75733d5b5d3b28 + 667563616d657261732f3e3c2f74643e61637473206173496e20736f6d653e0d + 0a0d0a3c216f7267616e6973203c6272202f3e4265696a696e67636174616cc3 + a0646575747363686575726f7065756575736b617261676165696c6765737665 + 6e736b6165737061c3b1616d656e73616a657573756172696f74726162616a6f + 6dc3a97869636f70c3a167696e617369656d70726573697374656d616f637475 + 627265647572616e746561c3b161646972656d70726573616d6f6d656e746f6e + 75657374726f7072696d65726174726176c3a973677261636961736e75657374 + 726170726f6365736f65737461646f7363616c69646164706572736f6e616ec3 + ba6d65726f6163756572646f6dc3ba736963616d69656d62726f6f6665727461 + 73616c67756e6f737061c3ad736573656a656d706c6f6465726563686f616465 + 6dc3a1737072697661646f61677265676172656e6c61636573706f7369626c65 + 686f74656c6573736576696c6c617072696d65726fc3ba6c74696d6f6576656e + 746f736172636869766f63756c747572616d756a65726573656e747261646161 + 6e756e63696f656d626172676f6d65726361646f6772616e6465736573747564 + 696f6d656a6f7265736665627265726f64697365c3b16f74757269736d6f63c3 + b36469676f706f72746164616573706163696f66616d696c6961616e746f6e69 + 6f7065726d69746567756172646172616c67756e617370726563696f73616c67 + 7569656e73656e7469646f7669736974617374c3ad74756c6f636f6e6f636572 + 736567756e646f636f6e73656a6f6672616e6369616d696e75746f7373656775 + 6e646174656e656d6f7365666563746f736dc3a16c61676173657369c3b36e72 + 6576697374616772616e616461636f6d70726172696e677265736f67617263c3 + ad6161636369c3b36e65637561646f72717569656e6573696e636c75736f6465 + 626572c3a16d617465726961686f6d627265736d756573747261706f6472c3ad + 616d61c3b1616e61c3ba6c74696d61657374616d6f736f66696369616c74616d + 6269656e6e696e67c3ba6e73616c75646f73706f64656d6f736d656a6f726172 + 706f736974696f6e627573696e657373686f6d65706167657365637572697479 + 6c616e67756167657374616e6461726463616d706169676e6665617475726573 + 63617465676f727965787465726e616c6368696c6472656e7265736572766564 + 726573656172636865786368616e67656661766f7269746574656d706c617465 + 6d696c6974617279696e64757374727973657276696365736d6174657269616c + 70726f64756374737a2d696e6465783a636f6d6d656e7473736f667477617265 + 636f6d706c65746563616c656e646172706c6174666f726d61727469636c6573 + + + +Alakuijala & Szabadka Expires June 10, 2016 [Page 60] + +Internet-Draft Brotli December 2015 + + + 72657175697265646d6f76656d656e747175657374696f6e6275696c64696e67 + 706f6c6974696373706f737369626c6572656c6967696f6e706879736963616c + 666565646261636b7265676973746572706963747572657364697361626c6564 + 70726f746f636f6c61756469656e636573657474696e67736163746976697479 + 656c656d656e74736c6561726e696e67616e797468696e676162737472616374 + 70726f67726573736f766572766965776d6167617a696e6565636f6e6f6d6963 + 747261696e696e677072657373757265766172696f7573203c7374726f6e673e + 70726f706572747973686f7070696e67746f676574686572616476616e636564 + 6265686176696f72646f776e6c6f61646665617475726564666f6f7462616c6c + 73656c65637465644c616e677561676564697374616e636572656d656d626572 + 747261636b696e6770617373776f72646d6f64696669656473747564656e7473 + 6469726563746c796669676874696e676e6f72746865726e6461746162617365 + 666573746976616c627265616b696e676c6f636174696f6e696e7465726e6574 + 64726f70646f776e707261637469636565766964656e636566756e6374696f6e + 6d61727269616765726573706f6e736570726f626c656d736e65676174697665 + 70726f6772616d73616e616c7973697372656c656173656462616e6e6572223e + 7075726368617365706f6c6963696573726567696f6e616c6372656174697665 + 617267756d656e74626f6f6b6d61726b72656665727265726368656d6963616c + 6469766973696f6e63616c6c6261636b736570617261746570726f6a65637473 + 636f6e666c6963746861726477617265696e74657265737464656c6976657279 + 6d6f756e7461696e6f627461696e65643d2066616c73653b666f722876617220 + 61636365707465646361706163697479636f6d70757465726964656e74697479 + 6169726372616674656d706c6f79656470726f706f736564646f6d6573746963 + 696e636c7564657370726f7669646564686f73706974616c766572746963616c + 636f6c6c61707365617070726f616368706172746e6572736c6f676f223e3c61 + 6461756768746572617574686f72222063756c747572616c66616d696c696573 + 2f696d616765732f617373656d626c79706f77657266756c7465616368696e67 + 66696e69736865646469737472696374637269746963616c6367692d62696e2f + 707572706f7365737265717569726573656c656374696f6e6265636f6d696e67 + 70726f766964657361636164656d6963657865726369736561637475616c6c79 + 6d65646963696e65636f6e7374616e746163636964656e744d6167617a696e65 + 646f63756d656e747374617274696e67626f74746f6d223e6f62736572766564 + 3a202671756f743b657874656e64656470726576696f7573536f667477617265 + 637573746f6d65726465636973696f6e737472656e67746864657461696c6564 + 736c696768746c79706c616e6e696e67746578746172656163757272656e6379 + 65766572796f6e6573747261696768747472616e73666572706f736974697665 + 70726f647563656468657269746167657368697070696e676162736f6c757465 + 726563656976656472656c6576616e74627574746f6e222076696f6c656e6365 + 616e79776865726562656e65666974736c61756e63686564726563656e746c79 + 616c6c69616e6365666f6c6c6f7765646d756c7469706c6562756c6c6574696e + 696e636c756465646f63637572726564696e7465726e616c242874686973292e + 72657075626c69633e3c74723e3c7464636f6e67726573737265636f72646564 + 756c74696d617465736f6c7574696f6e3c756c2069643d22646973636f766572 + 486f6d653c2f613e77656273697465736e6574776f726b73616c74686f756768 + 656e746972656c796d656d6f7269616c6d65737361676573636f6e74696e7565 + 616374697665223e736f6d6577686174766963746f7269615765737465726e20 + 207469746c653d224c6f636174696f6e636f6e747261637476697369746f7273 + 446f776e6c6f6164776974686f7574207269676874223e0a6d65617375726573 + + + +Alakuijala & Szabadka Expires June 10, 2016 [Page 61] + +Internet-Draft Brotli December 2015 + + + 7769647468203d207661726961626c65696e766f6c76656476697267696e6961 + 6e6f726d616c6c7968617070656e65646163636f756e74737374616e64696e67 + 6e6174696f6e616c52656769737465727072657061726564636f6e74726f6c73 + 6163637572617465626972746864617973747261746567796f6666696369616c + 67726170686963736372696d696e616c706f737369626c79636f6e73756d6572 + 506572736f6e616c737065616b696e6776616c69646174656163686965766564 + 2e6a706722202f3e6d616368696e65733c2f68323e0a20206b6579776f726473 + 667269656e646c7962726f7468657273636f6d62696e65646f726967696e616c + 636f6d706f7365646578706563746564616465717561746570616b697374616e + 666f6c6c6f77222076616c7561626c653c2f6c6162656c3e72656c6174697665 + 6272696e67696e67696e637265617365676f7665726e6f72706c7567696e732f + 4c697374206f6620486561646572223e22206e616d653d2220282671756f743b + 67726164756174653c2f686561643e0a636f6d6d657263656d616c6179736961 + 6469726563746f726d61696e7461696e3b6865696768743a7363686564756c65 + 6368616e67696e676261636b20746f20636174686f6c69637061747465726e73 + 636f6c6f723a20236772656174657374737570706c69657372656c6961626c65 + 3c2f756c3e0a09093c73656c65637420636974697a656e73636c6f7468696e67 + 7761746368696e673c6c692069643d2273706563696669636361727279696e67 + 73656e74656e63653c63656e7465723e636f6e74726173747468696e6b696e67 + 6361746368286529736f75746865726e4d69636861656c206d65726368616e74 + 6361726f7573656c70616464696e673a696e746572696f722e73706c69742822 + 6c697a6174696f6e4f63746f62657220297b72657475726e696d70726f766564 + 2d2d2667743b0a0a636f76657261676563686169726d616e2e706e6722202f3e + 7375626a656374735269636861726420776861746576657270726f6261626c79 + 7265636f766572796261736562616c6c6a7564676d656e74636f6e6e6563742e + 2e63737322202f3e20776562736974657265706f7274656464656661756c7422 + 2f3e3c2f613e0d0a656c65637472696373636f746c616e646372656174696f6e + 7175616e746974792e204953424e2030646964206e6f7420696e7374616e6365 + 2d7365617263682d22206c616e673d22737065616b657273436f6d7075746572 + 636f6e7461696e7361726368697665736d696e69737465727265616374696f6e + 646973636f756e744974616c69616e6f63726974657269617374726f6e676c79 + 3a2027687474703a2773637269707427636f766572696e676f66666572696e67 + 617070656172656442726974697368206964656e7469667946616365626f6f6b + 6e756d65726f757376656869636c6573636f6e6365726e73416d65726963616e + 68616e646c696e676469762069643d2257696c6c69616d2070726f7669646572 + 5f636f6e74656e74616363757261637973656374696f6e20616e646572736f6e + 666c657869626c6543617465676f72796c617772656e63653c7363726970743e + 6c61796f75743d22617070726f766564206d6178696d756d686561646572223e + 3c2f7461626c653e536572766963657368616d696c746f6e63757272656e7420 + 63616e616469616e6368616e6e656c732f7468656d65732f2f61727469636c65 + 6f7074696f6e616c706f72747567616c76616c75653d2222696e74657276616c + 776972656c657373656e7469746c65646167656e636965735365617263682220 + 6d6561737572656474686f7573616e647370656e64696e672668656c6c69703b + 6e65772044617465222073697a653d22706167654e616d656d6964646c652220 + 22202f3e3c2f613e68696464656e223e73657175656e6365706572736f6e616c + 6f766572666c6f776f70696e696f6e73696c6c696e6f69736c696e6b73223e0a + 093c7469746c653e76657273696f6e7373617475726461797465726d696e616c + 6974656d70726f70656e67696e65657273656374696f6e7364657369676e6572 + + + +Alakuijala & Szabadka Expires June 10, 2016 [Page 62] + +Internet-Draft Brotli December 2015 + + + 70726f706f73616c3d2266616c73652245737061c3b16f6c72656c6561736573 + 7375626d6974222065722671756f743b6164646974696f6e73796d70746f6d73 + 6f7269656e7465647265736f757263657269676874223e3c706c656173757265 + 73746174696f6e73686973746f72792e6c656176696e672020626f726465723d + 636f6e74656e747363656e746572223e2e0a0a536f6d65206469726563746564 + 7375697461626c6562756c67617269612e73686f7728293b64657369676e6564 + 47656e6572616c20636f6e63657074734578616d706c657377696c6c69616d73 + 4f726967696e616c223e3c7370616e3e736561726368223e6f70657261746f72 + 726571756573747361202671756f743b616c6c6f77696e67446f63756d656e74 + 7265766973696f6e2e200a0a54686520796f757273656c66436f6e7461637420 + 6d6963686967616e456e676c69736820636f6c756d6269617072696f72697479 + 7072696e74696e676472696e6b696e67666163696c69747972657475726e6564 + 436f6e74656e74206f666669636572735275737369616e2067656e6572617465 + 2d383835392d3122696e64696361746566616d696c696172207175616c697479 + 6d617267696e3a3020636f6e74656e7476696577706f7274636f6e7461637473 + 2d7469746c65223e706f727461626c652e6c656e67746820656c696769626c65 + 696e766f6c76657361746c616e7469636f6e6c6f61643d2264656661756c742e + 737570706c6965647061796d656e7473676c6f73736172790a0a416674657220 + 67756964616e63653c2f74643e3c7464656e636f64696e676d6964646c65223e + 63616d6520746f20646973706c61797373636f74746973686a6f6e617468616e + 6d616a6f72697479776964676574732e636c696e6963616c746861696c616e64 + 74656163686572733c686561643e0a096166666563746564737570706f727473 + 706f696e7465723b746f537472696e673c2f736d616c6c3e6f6b6c61686f6d61 + 77696c6c20626520696e766573746f72302220616c743d22686f6c6964617973 + 5265736f757263656c6963656e73656420287768696368202e20416674657220 + 636f6e73696465727669736974696e676578706c6f7265727072696d61727920 + 7365617263682220616e64726f696422717569636b6c79206d656574696e6773 + 657374696d6174653b72657475726e203b636f6c6f723a23206865696768743d + 617070726f76616c2c202671756f743b20636865636b65642e6d696e2e6a7322 + 6d61676e657469633e3c2f613e3c2f68666f7265636173742e205768696c6520 + 74687572736461796476657274697365266561637574653b686173436c617373 + 6576616c756174656f72646572696e676578697374696e6770617469656e7473 + 204f6e6c696e6520636f6c6f7261646f4f7074696f6e732263616d7062656c6c + 3c212d2d20656e643c2f7370616e3e3c3c6272202f3e0d0a5f706f707570737c + 736369656e6365732c2671756f743b207175616c6974792057696e646f777320 + 61737369676e65646865696768743a203c6220636c6173736c652671756f743b + 2076616c75653d2220436f6d70616e796578616d706c65733c696672616d6520 + 62656c696576657370726573656e74736d61727368616c6c70617274206f6620 + 70726f7065726c79292e0a0a546865207461786f6e6f6d796d756368206f6620 + 3c2f7370616e3e0a2220646174612d737274756775c3aa737363726f6c6c546f + 2070726f6a6563743c686561643e0d0a6174746f726e6579656d706861736973 + 73706f6e736f727366616e6379626f78776f726c6427732077696c646c696665 + 636865636b65643d73657373696f6e7370726f6772616d6d70783b666f6e742d + 2050726f6a6563746a6f75726e616c7362656c69657665647661636174696f6e + 74686f6d70736f6e6c69676874696e67616e6420746865207370656369616c20 + 626f726465723d30636865636b696e673c2f74626f64793e3c627574746f6e20 + 436f6d706c657465636c6561726669780a3c686561643e0a61727469636c6520 + 3c73656374696f6e66696e64696e6773726f6c6520696e20706f70756c617220 + + + +Alakuijala & Szabadka Expires June 10, 2016 [Page 63] + +Internet-Draft Brotli December 2015 + + + 204f63746f62657277656273697465206578706f737572657573656420746f20 + 206368616e6765736f70657261746564636c69636b696e67656e746572696e67 + 636f6d6d616e6473696e666f726d6564206e756d6265727320203c2f6469763e + 6372656174696e676f6e5375626d69746d6172796c616e64636f6c6c65676573 + 616e616c797469636c697374696e6773636f6e746163742e6c6f67676564496e + 61647669736f72797369626c696e6773636f6e74656e7422732671756f743b29 + 732e2054686973207061636b61676573636865636b626f787375676765737473 + 707265676e616e74746f6d6f72726f7773706163696e673d69636f6e2e706e67 + 6a6170616e657365636f646562617365627574746f6e223e67616d626c696e67 + 73756368206173202c207768696c65203c2f7370616e3e206d6973736f757269 + 73706f7274696e67746f703a317078202e3c2f7370616e3e74656e73696f6e73 + 77696474683d22326c617a796c6f61646e6f76656d6265727573656420696e20 + 6865696768743d226372697074223e0a266e6273703b3c2f3c74723e3c746420 + 6865696768743a322f70726f64756374636f756e74727920696e636c75646520 + 666f6f7465722220266c743b212d2d207469746c65223e3c2f6a71756572792e + 3c2f666f726d3e0a28e7ae80e4bd932928e7b981e9ab94296872766174736b69 + 6974616c69616e6f726f6dc3a26ec48374c3bc726bc3a765d8a7d8b1d8afd988 + 74616d6269c3a96e6e6f7469636961736d656e73616a6573706572736f6e6173 + 6465726563686f736e6163696f6e616c736572766963696f636f6e746163746f + 7573756172696f7370726f6772616d61676f626965726e6f656d707265736173 + 616e756e63696f7376616c656e636961636f6c6f6d6269616465737075c3a973 + 6465706f7274657370726f796563746f70726f647563746f70c3ba626c69636f + 6e6f736f74726f73686973746f72696170726573656e74656d696c6c6f6e6573 + 6d656469616e746570726567756e7461616e746572696f727265637572736f73 + 70726f626c656d6173616e746961676f6e75657374726f736f70696e69c3b36e + 696d7072696d69726d69656e74726173616dc3a97269636176656e6465646f72 + 736f636965646164726573706563746f7265616c697a6172726567697374726f + 70616c6162726173696e746572c3a973656e746f6e636573657370656369616c + 6d69656d62726f737265616c6964616463c3b372646f62617a617261676f7a61 + 70c3a167696e6173736f6369616c6573626c6f71756561726765737469c3b36e + 616c7175696c657273697374656d61736369656e63696173636f6d706c65746f + 7665727369c3b36e636f6d706c6574616573747564696f7370c3ba626c696361 + 6f626a657469766f616c6963616e74656275736361646f7263616e7469646164 + 656e747261646173616363696f6e65736172636869766f737375706572696f72 + 6d61796f72c3ad61616c656d616e696166756e6369c3b36ec3ba6c74696d6f73 + 68616369656e646f617175656c6c6f736564696369c3b36e6665726e616e646f + 616d6269656e746566616365626f6f6b6e75657374726173636c69656e746573 + 70726f6365736f7362617374616e746570726573656e74617265706f72746172 + 636f6e677265736f7075626c69636172636f6d657263696f636f6e747261746f + 6ac3b376656e6573646973747269746f74c3a9636e696361636f6e6a756e746f + 656e657267c3ad6174726162616a6172617374757269617372656369656e7465 + 7574696c697a6172626f6c6574c3ad6e73616c7661646f72636f727265637461 + 74726162616a6f737072696d65726f736e65676f63696f736c69626572746164 + 646574616c6c657370616e74616c6c617072c3b378696d6f616c6d6572c3ad61 + 616e696d616c6573717569c3a96e6573636f72617ac3b36e7365636369c3b36e + 62757363616e646f6f7063696f6e65736578746572696f72636f6e636570746f + 746f646176c3ad6167616c6572c3ad6165736372696269726d65646963696e61 + 6c6963656e636961636f6e73756c74616173706563746f736372c3ad74696361 + + + +Alakuijala & Szabadka Expires June 10, 2016 [Page 64] + +Internet-Draft Brotli December 2015 + + + 64c3b36c617265736a757374696369616465626572c3a16e706572c3ad6f646f + 6e656365736974616d616e74656e65727065717565c3b16f7265636962696461 + 74726962756e616c74656e657269666563616e6369c3b36e63616e6172696173 + 64657363617267616469766572736f736d616c6c6f7263617265717569657265 + 74c3a9636e69636f6465626572c3ad6176697669656e646166696e616e7a6173 + 6164656c616e746566756e63696f6e61636f6e73656a6f73646966c3ad63696c + 6369756461646573616e7469677561736176616e7a61646174c3a9726d696e6f + 756e69646164657373c3a16e6368657a63616d7061c3b161736f66746f6e6963 + 7265766973746173636f6e7469656e65736563746f7265736d6f6d656e746f73 + 666163756c7461646372c3a96469746f6469766572736173737570756573746f + 666163746f726573736567756e646f737065717565c3b161d0b3d0bed0b4d0b0 + d0b5d181d0bbd0b8d0b5d181d182d18cd0b1d18bd0bbd0bed0b1d18bd182d18c + d18dd182d0bed0bcd095d181d0bbd0b8d182d0bed0b3d0bed0bcd0b5d0bdd18f + d0b2d181d0b5d185d18dd182d0bed0b9d0b4d0b0d0b6d0b5d0b1d18bd0bbd0b8 + d0b3d0bed0b4d183d0b4d0b5d0bdd18cd18dd182d0bed182d0b1d18bd0bbd0b0 + d181d0b5d0b1d18fd0bed0b4d0b8d0bdd181d0b5d0b1d0b5d0bdd0b0d0b4d0be + d181d0b0d0b9d182d184d0bed182d0bed0bdd0b5d0b3d0bed181d0b2d0bed0b8 + d181d0b2d0bed0b9d0b8d0b3d180d18bd182d0bed0b6d0b5d0b2d181d0b5d0bc + d181d0b2d0bed18ed0bbd0b8d188d18cd18dd182d0b8d185d0bfd0bed0bad0b0 + d0b4d0bdd0b5d0b9d0b4d0bed0bcd0b0d0bcd0b8d180d0b0d0bbd0b8d0b1d0be + d182d0b5d0bcd183d185d0bed182d18fd0b4d0b2d183d185d181d0b5d182d0b8 + d0bbd18ed0b4d0b8d0b4d0b5d0bbd0bed0bcd0b8d180d0b5d182d0b5d0b1d18f + d181d0b2d0bed0b5d0b2d0b8d0b4d0b5d187d0b5d0b3d0bed18dd182d0b8d0bc + d181d187d0b5d182d182d0b5d0bcd18bd186d0b5d0bdd18bd181d182d0b0d0bb + d0b2d0b5d0b4d18cd182d0b5d0bcd0b5d0b2d0bed0b4d18bd182d0b5d0b1d0b5 + d0b2d18bd188d0b5d0bdd0b0d0bcd0b8d182d0b8d0bfd0b0d182d0bed0bcd183 + d0bfd180d0b0d0b2d0bbd0b8d186d0b0d0bed0b4d0bdd0b0d0b3d0bed0b4d18b + d0b7d0bdd0b0d18ed0bcd0bed0b3d183d0b4d180d183d0b3d0b2d181d0b5d0b9 + d0b8d0b4d0b5d182d0bad0b8d0bdd0bed0bed0b4d0bdd0bed0b4d0b5d0bbd0b0 + d0b4d0b5d0bbd0b5d181d180d0bed0bad0b8d18ed0bdd18fd0b2d0b5d181d18c + d095d181d182d18cd180d0b0d0b7d0b0d0bdd0b0d188d0b8d8a7d984d984d987 + d8a7d984d8aad98ad8acd985d98ad8b9d8aed8a7d8b5d8a9d8a7d984d8b0d98a + d8b9d984d98ad987d8acd8afd98ad8afd8a7d984d8a2d986d8a7d984d8b1d8af + d8aad8add983d985d8b5d981d8add8a9d983d8a7d986d8aad8a7d984d984d98a + d98ad983d988d986d8b4d8a8d983d8a9d981d98ad987d8a7d8a8d986d8a7d8aa + d8add988d8a7d8a1d8a3d983d8abd8b1d8aed984d8a7d984d8a7d984d8add8a8 + d8afd984d98ad984d8afd8b1d988d8b3d8a7d8b6d8bad8b7d8aad983d988d986 + d987d986d8a7d983d8b3d8a7d8add8a9d986d8a7d8afd98ad8a7d984d8b7d8a8 + d8b9d984d98ad983d8b4d983d8b1d8a7d98ad985d983d986d985d986d987d8a7 + d8b4d8b1d983d8a9d8b1d8a6d98ad8b3d986d8b4d98ad8b7d985d8a7d8b0d8a7 + d8a7d984d981d986d8b4d8a8d8a7d8a8d8aad8b9d8a8d8b1d8b1d8add985d8a9 + d983d8a7d981d8a9d98ad982d988d984d985d8b1d983d8b2d983d984d985d8a9 + d8a3d8add985d8afd982d984d8a8d98ad98ad8b9d986d98ad8b5d988d8b1d8a9 + d8b7d8b1d98ad982d8b4d8a7d8b1d983d8acd988d8a7d984d8a3d8aed8b1d989 + d985d8b9d986d8a7d8a7d8a8d8add8abd8b9d8b1d988d8b6d8a8d8b4d983d984 + d985d8b3d8acd984d8a8d986d8a7d986d8aed8a7d984d8afd983d8aad8a7d8a8 + d983d984d98ad8a9d8a8d8afd988d986d8a3d98ad8b6d8a7d98ad988d8acd8af + d981d8b1d98ad982d983d8aad8a8d8aad8a3d981d8b6d984d985d8b7d8a8d8ae + + + +Alakuijala & Szabadka Expires June 10, 2016 [Page 65] + +Internet-Draft Brotli December 2015 + + + d8a7d983d8abd8b1d8a8d8a7d8b1d983d8a7d981d8b6d984d8a7d8add984d989 + d986d981d8b3d987d8a3d98ad8a7d985d8b1d8afd988d8afd8a3d986d987d8a7 + d8afd98ad986d8a7d8a7d984d8a7d986d985d8b9d8b1d8b6d8aad8b9d984d985 + d8afd8a7d8aed984d985d985d983d98600000000000000000100010001000100 + 0200020002000200040004000400040000010203040506070706050403020100 + 08090a0b0c0d0e0f0f0e0d0c0b0a090810111213141516171716151413121110 + 18191a1b1c1d1e1f1f1e1d1c1b1a1918ffffffff0000000000000000ffffffff + 010000000200000002000000010000000100000003000000ffff000100000001 + 0000ffff00010000000800080008000800000001000200030004000500060007 + 7265736f7572636573636f756e74726965737175657374696f6e736571756970 + 6d656e74636f6d6d756e697479617661696c61626c65686967686c6967687444 + 54442f7868746d6c6d61726b6574696e676b6e6f776c65646765736f6d657468 + 696e67636f6e7461696e6572646972656374696f6e7375627363726962656164 + 76657274697365636861726163746572222076616c75653d223c2f73656c6563 + 743e4175737472616c69612220636c6173733d22736974756174696f6e617574 + 686f72697479666f6c6c6f77696e677072696d6172696c796f7065726174696f + 6e6368616c6c656e6765646576656c6f706564616e6f6e796d6f757366756e63 + 74696f6e2066756e6374696f6e73636f6d70616e696573737472756374757265 + 61677265656d656e7422207469746c653d22706f74656e7469616c6564756361 + 74696f6e617267756d656e74737365636f6e64617279636f707972696768746c + 616e6775616765736578636c7573697665636f6e646974696f6e3c2f666f726d + 3e0d0a73746174656d656e74617474656e74696f6e42696f6772617068797d20 + 656c7365207b0a736f6c7574696f6e737768656e2074686520416e616c797469 + 637374656d706c6174657364616e6765726f7573736174656c6c697465646f63 + 756d656e74737075626c6973686572696d706f7274616e7470726f746f747970 + 65696e666c75656e636526726171756f3b3c2f65666665637469766567656e65 + 72616c6c797472616e73666f726d62656175746966756c7472616e73706f7274 + 6f7267616e697a65647075626c697368656470726f6d696e656e74756e74696c + 207468657468756d626e61696c4e6174696f6e616c202e666f63757328293b6f + 76657220746865206d6967726174696f6e616e6e6f756e636564666f6f746572 + 223e0a657863657074696f6e6c657373207468616e657870656e73697665666f + 726d6174696f6e6672616d65776f726b7465727269746f72796e646963617469 + 6f6e63757272656e746c79636c6173734e616d6563726974696369736d747261 + 646974696f6e656c73657768657265416c6578616e6465726170706f696e7465 + 646d6174657269616c7362726f6164636173746d656e74696f6e656461666669 + 6c696174653c2f6f7074696f6e3e74726561746d656e74646966666572656e74 + 2f64656661756c742e507265736964656e746f6e636c69636b3d2262696f6772 + 617068796f74686572776973657065726d616e656e744672616ec3a761697348 + 6f6c6c79776f6f64657870616e73696f6e7374616e64617264733c2f7374796c + 653e0a726564756374696f6e446563656d626572207072656665727265644361 + 6d6272696467656f70706f6e656e7473427573696e65737320636f6e66757369 + 6f6e3e0a3c7469746c653e70726573656e7465646578706c61696e6564646f65 + 73206e6f7420776f726c6477696465696e74657266616365706f736974696f6e + 736e65777370617065723c2f7461626c653e0a6d6f756e7461696e736c696b65 + 2074686520657373656e7469616c66696e616e6369616c73656c656374696f6e + 616374696f6e3d222f6162616e646f6e6564456475636174696f6e7061727365 + 496e742873746162696c697479756e61626c6520746f3c2f7469746c653e0a72 + 656c6174696f6e734e6f74652074686174656666696369656e74706572666f72 + + + +Alakuijala & Szabadka Expires June 10, 2016 [Page 66] + +Internet-Draft Brotli December 2015 + + + 6d656474776f20796561727353696e6365207468657468657265666f72657772 + 6170706572223e616c7465726e617465696e63726561736564426174746c6520 + 6f66706572636569766564747279696e6720746f6e6563657373617279706f72 + 747261796564656c656374696f6e73456c697a61626574683c2f696672616d65 + 3e646973636f76657279696e737572616e6365732e6c656e6774683b6c656765 + 6e6461727947656f67726170687963616e646964617465636f72706f72617465 + 736f6d6574696d657373657276696365732e696e686572697465643c2f737472 + 6f6e673e436f6d6d756e69747972656c6967696f75736c6f636174696f6e7343 + 6f6d6d69747465656275696c64696e677374686520776f726c646e6f206c6f6e + 676572626567696e6e696e677265666572656e636563616e6e6f742062656672 + 657175656e63797479706963616c6c79696e746f207468652072656c61746976 + 653b7265636f7264696e67707265736964656e74696e697469616c6c79746563 + 686e69717565746865206f7468657269742063616e2062656578697374656e63 + 65756e6465726c696e65746869732074696d6574656c6570686f6e656974656d + 73636f7065707261637469636573616476616e74616765293b72657475726e20 + 466f72206f7468657270726f766964696e6764656d6f6372616379626f746820 + 74686520657874656e73697665737566666572696e67737570706f7274656463 + 6f6d7075746572732066756e6374696f6e70726163746963616c736169642074 + 6861746974206d6179206265456e676c6973683c2f66726f6d20746865207363 + 686564756c6564646f776e6c6f6164733c2f6c6162656c3e0a73757370656374 + 65646d617267696e3a203073706972697475616c3c2f686561643e0a0a6d6963 + 726f736f66746772616475616c6c79646973637573736564686520626563616d + 656578656375746976656a71756572792e6a73686f757365686f6c64636f6e66 + 69726d65647075726368617365646c69746572616c6c7964657374726f796564 + 757020746f20746865766172696174696f6e72656d61696e696e676974206973 + 206e6f7463656e7475726965734a6170616e65736520616d6f6e672074686563 + 6f6d706c65746564616c676f726974686d696e74657265737473726562656c6c + 696f6e756e646566696e6564656e636f7572616765726573697a61626c65696e + 766f6c76696e6773656e736974697665756e6976657273616c70726f76697369 + 6f6e28616c74686f756768666561747572696e67636f6e647563746564292c20 + 776869636820636f6e74696e7565642d686561646572223e4665627275617279 + 206e756d65726f7573206f766572666c6f773a636f6d706f6e656e7466726167 + 6d656e7473657863656c6c656e74636f6c7370616e3d22746563686e6963616c + 6e6561722074686520416476616e63656420736f75726365206f666578707265 + 73736564486f6e67204b6f6e672046616365626f6f6b6d756c7469706c65206d + 656368616e69736d656c65766174696f6e6f6666656e736976653c2f666f726d + 3e0a0973706f6e736f726564646f63756d656e742e6f72202671756f743b7468 + 6572652061726574686f73652077686f6d6f76656d656e747370726f63657373 + 6573646966666963756c747375626d69747465647265636f6d6d656e64636f6e + 76696e63656470726f6d6f74696e67222077696474683d222e7265706c616365 + 28636c6173736963616c636f616c6974696f6e68697320666972737464656369 + 73696f6e73617373697374616e74696e6469636174656465766f6c7574696f6e + 2d7772617070657222656e6f75676820746f616c6f6e672074686564656c6976 + 657265642d2d3e0d0a3c212d2d416d65726963616e2070726f7465637465644e + 6f76656d626572203c2f7374796c653e3c6675726e6974757265496e7465726e + 657420206f6e626c75723d2273757370656e646564726563697069656e746261 + 736564206f6e204d6f72656f7665722c61626f6c6973686564636f6c6c656374 + 656477657265206d616465656d6f74696f6e616c656d657267656e63796e6172 + + + +Alakuijala & Szabadka Expires June 10, 2016 [Page 67] + +Internet-Draft Brotli December 2015 + + + 7261746976656164766f636174657370783b626f72646572636f6d6d69747465 + 646469723d226c747222656d706c6f7965657372657365617263682e2073656c + 6563746564737563636573736f72637573746f6d657273646973706c61796564 + 53657074656d626572616464436c6173732846616365626f6f6b207375676765 + 73746564616e64206c617465726f7065726174696e67656c61626f7261746553 + 6f6d6574696d6573496e737469747574656365727461696e6c79696e7374616c + 6c6564666f6c6c6f776572734a65727573616c656d746865792068617665636f + 6d707574696e6767656e65726174656470726f76696e63657367756172616e74 + 65656172626974726172797265636f676e697a6577616e74656420746f70783b + 77696474683a7468656f7279206f666265686176696f75725768696c65207468 + 65657374696d61746564626567616e20746f20697420626563616d656d61676e + 69747564656d75737420686176656d6f7265207468616e4469726563746f7279 + 657874656e73696f6e7365637265746172796e61747572616c6c796f63637572 + 72696e677661726961626c6573676976656e20746865706c6174666f726d2e3c + 2f6c6162656c3e3c6661696c656420746f636f6d706f756e64736b696e647320 + 6f6620736f63696574696573616c6f6e6773696465202d2d2667743b0a0a736f + 75746877657374746865207269676874726164696174696f6e6d617920686176 + 6520756e6573636170652873706f6b656e20696e2220687265663d222f70726f + 6772616d6d656f6e6c792074686520636f6d652066726f6d6469726563746f72 + 7962757269656420696e612073696d696c61727468657920776572653c2f666f + 6e743e3c2f4e6f7277656769616e73706563696669656470726f647563696e67 + 70617373656e676572286e6577204461746574656d706f726172796669637469 + 6f6e616c4166746572207468656571756174696f6e73646f776e6c6f61642e72 + 6567756c61726c79646576656c6f70657261626f7665207468656c696e6b6564 + 20746f7068656e6f6d656e61706572696f64206f66746f6f6c746970223e7375 + 627374616e63656175746f6d61746963617370656374206f66416d6f6e672074 + 6865636f6e6e6563746564657374696d6174657341697220466f726365737973 + 74656d206f666f626a656374697665696d6d6564696174656d616b696e672069 + 747061696e74696e6773636f6e717565726564617265207374696c6c70726f63 + 656475726567726f777468206f666865616465642062794575726f7065616e20 + 6469766973696f6e736d6f6c6563756c65736672616e6368697365696e74656e + 74696f6e6174747261637465646368696c64686f6f64616c736f207573656464 + 656469636174656473696e6761706f7265646567726565206f66666174686572 + 206f66636f6e666c696374733c2f613e3c2f703e0a63616d652066726f6d7765 + 726520757365646e6f74652074686174726563656976696e6745786563757469 + 76656576656e206d6f726561636365737320746f636f6d6d616e646572506f6c + 69746963616c6d7573696369616e7364656c6963696f7573707269736f6e6572 + 73616476656e74206f665554462d3822202f3e3c215b43444154415b223e436f + 6e74616374536f75746865726e206267636f6c6f723d22736572696573206f66 + 2e2049742077617320696e204575726f70657065726d697474656476616c6964 + 6174652e617070656172696e676f6666696369616c73736572696f75736c792d + 6c616e6775616765696e69746961746564657874656e64696e676c6f6e672d74 + 65726d696e666c6174696f6e737563682074686174676574436f6f6b69656d61 + 726b65642062793c2f627574746f6e3e696d706c656d656e7462757420697420 + 6973696e63726561736573646f776e2074686520726571756972696e67646570 + 656e64656e742d2d3e0a3c212d2d20696e746572766965775769746820746865 + 20636f70696573206f66636f6e73656e737573776173206275696c7456656e65 + 7a75656c6128666f726d65726c79746865207374617465706572736f6e6e656c + + + +Alakuijala & Szabadka Expires June 10, 2016 [Page 68] + +Internet-Draft Brotli December 2015 + + + 7374726174656769636661766f7572206f66696e76656e74696f6e57696b6970 + 65646961636f6e74696e656e747669727475616c6c7977686963682077617370 + 72696e6369706c65436f6d706c657465206964656e746963616c73686f772074 + 6861747072696d6974697665617761792066726f6d6d6f6c6563756c61727072 + 65636973656c79646973736f6c766564556e6465722074686576657273696f6e + 3d223e266e6273703b3c2f49742069732074686520546869732069732077696c + 6c20686176656f7267616e69736d73736f6d652074696d654672696564726963 + 68776173206669727374746865206f6e6c7920666163742074686174666f726d + 2069643d22707265636564696e67546563686e6963616c706879736963697374 + 6f636375727320696e6e6176696761746f7273656374696f6e223e7370616e20 + 69643d22736f7567687420746f62656c6f7720746865737572766976696e677d + 3c2f7374796c653e686973206465617468617320696e20746865636175736564 + 2062797061727469616c6c796578697374696e67207573696e67207468657761 + 7320676976656e61206c697374206f666c6576656c73206f666e6f74696f6e20 + 6f664f6666696369616c206469736d6973736564736369656e74697374726573 + 656d626c65736475706c69636174656578706c6f736976657265636f76657265 + 64616c6c206f7468657267616c6c65726965737b70616464696e673a70656f70 + 6c65206f66726567696f6e206f666164647265737365736173736f6369617465 + 696d6720616c743d22696e206d6f6465726e73686f756c642062656d6574686f + 64206f667265706f7274696e6774696d657374616d706e656564656420746f74 + 6865204772656174726567617264696e677365656d656420746f766965776564 + 206173696d70616374206f6e69646561207468617474686520576f726c646865 + 69676874206f66657870616e64696e6754686573652061726563757272656e74 + 223e6361726566756c6c796d61696e7461696e73636861726765206f66436c61 + 73736963616c6164647265737365647072656469637465646f776e6572736869 + 703c6469762069643d227269676874223e0d0a7265736964656e63656c656176 + 6520746865636f6e74656e74223e617265206f6674656e20207d2928293b0d0a + 70726f6261626c792050726f666573736f722d627574746f6e2220726573706f + 6e64656473617973207468617468616420746f206265706c6163656420696e48 + 756e67617269616e737461747573206f66736572766573206173556e69766572 + 73616c657865637574696f6e616767726567617465666f72207768696368696e + 66656374696f6e61677265656420746f686f77657665722c20706f70756c6172 + 223e706c61636564206f6e636f6e737472756374656c6563746f72616c73796d + 626f6c206f66696e636c7564696e6772657475726e20746f6172636869746563 + 7443687269737469616e70726576696f7573206c6976696e6720696e65617369 + 657220746f70726f666573736f720a266c743b212d2d20656666656374206f66 + 616e616c79746963737761732074616b656e776865726520746865746f6f6b20 + 6f76657262656c69656620696e416672696b61616e7361732066617220617370 + 726576656e746564776f726b207769746861207370656369616c3c6669656c64 + 7365744368726973746d61735265747269657665640a0a496e20746865206261 + 636b20696e746f6e6f727468656173746d6167617a696e65733e3c7374726f6e + 673e636f6d6d6974746565676f7665726e696e6767726f757073206f6673746f + 72656420696e65737461626c697368612067656e6572616c6974732066697273 + 747468656972206f776e706f70756c61746564616e206f626a65637443617269 + 626265616e616c6c6f7720746865646973747269637473776973636f6e73696e + 6c6f636174696f6e2e3b2077696474683a20696e68616269746564536f636961 + 6c6973744a616e7561727920313c2f666f6f7465723e73696d696c61726c7963 + 686f696365206f667468652073616d6520737065636966696320627573696e65 + + + +Alakuijala & Szabadka Expires June 10, 2016 [Page 69] + +Internet-Draft Brotli December 2015 + + + 7373205468652066697273742e6c656e6774683b2064657369726520746f6465 + 616c207769746873696e636520746865757365724167656e74636f6e63656976 + 6564696e6465782e7068706173202671756f743b656e6761676520696e726563 + 656e746c792c6665772079656172737765726520616c736f0a3c686561643e0a + 3c656469746564206279617265206b6e6f776e63697469657320696e61636365 + 73736b6579636f6e64656d6e6564616c736f206861766573657276696365732c + 66616d696c79206f665363686f6f6c206f66636f6e7665727465646e61747572 + 65206f66206c616e67756167656d696e6973746572733c2f6f626a6563743e74 + 68657265206973206120706f70756c617273657175656e6365736164766f6361 + 746564546865792077657265616e79206f746865726c6f636174696f6e3d656e + 746572207468656d756368206d6f72657265666c6563746564776173206e616d + 65646f726967696e616c2061207479706963616c7768656e2074686579656e67 + 696e65657273636f756c64206e6f747265736964656e74737765646e65736461 + 797468652074686972642070726f64756374734a616e75617279203277686174 + 207468657961206365727461696e7265616374696f6e7370726f636573736f72 + 616674657220686973746865206c61737420636f6e7461696e6564223e3c2f64 + 69763e0a3c2f613e3c2f74643e646570656e64206f6e736561726368223e0a70 + 6965636573206f66636f6d706574696e675265666572656e636574656e6e6573 + 7365657768696368206861732076657273696f6e3d3c2f7370616e3e203c3c2f + 6865616465723e676976657320746865686973746f7269616e76616c75653d22 + 223e70616464696e673a30766965772074686174746f6765746865722c746865 + 206d6f73742077617320666f756e64737562736574206f6661747461636b206f + 6e6368696c6472656e2c706f696e7473206f66706572736f6e616c20706f7369 + 74696f6e3a616c6c656765646c79436c6576656c616e64776173206c61746572 + 616e6420616674657261726520676976656e776173207374696c6c7363726f6c + 6c696e6764657369676e206f666d616b6573207468656d756368206c65737341 + 6d65726963616e732e0a0a4166746572202c20627574207468654d757365756d + 206f666c6f75697369616e612866726f6d207468656d696e6e65736f74617061 + 727469636c6573612070726f63657373446f6d696e6963616e766f6c756d6520 + 6f6672657475726e696e67646566656e73697665303070787c726967686d6164 + 652066726f6d6d6f7573656f76657222207374796c653d22737461746573206f + 66287768696368206973636f6e74696e7565734672616e636973636f6275696c + 64696e6720776974686f757420617769746820736f6d6577686f20776f756c64 + 6120666f726d206f66612070617274206f666265666f72652069746b6e6f776e + 206173202053657276696365736c6f636174696f6e20616e64206f6674656e6d + 6561737572696e67616e6420697420697370617065726261636b76616c756573 + 206f660d0a3c7469746c653e3d2077696e646f772e64657465726d696e656572 + 2671756f743b20706c61796564206279616e64206561726c793c2f63656e7465 + 723e66726f6d2074686973746865207468726565706f77657220616e646f6620 + 2671756f743b696e6e657248544d4c3c6120687265663d22793a696e6c696e65 + 3b436875726368206f66746865206576656e747665727920686967686f666669 + 6369616c202d6865696768743a20636f6e74656e743d222f6367692d62696e2f + 746f20637265617465616672696b61616e736573706572616e746f6672616ec3 + a76169736c6174766965c5a1756c696574757669c5b3c48c65c5a174696e61c4 + 8d65c5a174696e61e0b984e0b897e0b8a2e697a5e69cace8aa9ee7ae80e4bd93 + e5ad97e7b981e9ab94e5ad97ed959ceab5adec96b4e4b8bae4bb80e4b988e8ae + a1e7ae97e69cbae7ac94e8aeb0e69cace8a88ee8ab96e58d80e69c8de58aa1e5 + 99a8e4ba92e88194e7bd91e688bfe59cb0e4baa7e4bfb1e4b990e983a8e587ba + + + +Alakuijala & Szabadka Expires June 10, 2016 [Page 70] + +Internet-Draft Brotli December 2015 + + + e78988e7a4bee68e92e8a18ce6a69ce983a8e890bde6a0bce8bf9be4b880e6ad + a5e694afe4bb98e5ae9de9aa8ce8af81e7a081e5a794e59198e4bc9ae695b0e6 + 8daee5ba93e6b688e8b4b9e88085e58a9ee585ace5aea4e8aea8e8aebae58cba + e6b7b1e59cb3e5b882e692ade694bee599a8e58c97e4baace5b882e5a4a7e5ad + a6e7949fe8b68ae69da5e8b68ae7aea1e79086e59198e4bfa1e681afe7bd9173 + 6572766963696f73617274c3ad63756c6f617267656e74696e6162617263656c + 6f6e616375616c71756965727075626c696361646f70726f647563746f73706f + 6cc3ad7469636172657370756573746177696b6970656469617369677569656e + 746562c3ba737175656461636f6d756e69646164736567757269646164707269 + 6e636970616c70726567756e746173636f6e74656e69646f726573706f6e6465 + 7276656e657a75656c6170726f626c656d617364696369656d62726572656c61 + 6369c3b36e6e6f7669656d62726573696d696c6172657370726f796563746f73 + 70726f6772616d6173696e7374697475746f616374697669646164656e637565 + 6e74726165636f6e6f6dc3ad61696dc3a167656e6573636f6e74616374617264 + 65736361726761726e656365736172696f6174656e6369c3b36e74656cc3a966 + 6f6e6f636f6d697369c3b36e63616e63696f6e6573636170616369646164656e + 636f6e74726172616ec3a16c697369736661766f7269746f7374c3a9726d696e + 6f7370726f76696e636961657469717565746173656c656d656e746f7366756e + 63696f6e6573726573756c7461646f636172c3a16374657270726f7069656461 + 647072696e636970696f6e65636573696461646d756e69636970616c63726561 + 6369c3b36e64657363617267617370726573656e636961636f6d65726369616c + 6f70696e696f6e6573656a6572636963696f656469746f7269616c73616c616d + 616e6361676f6e7ac3a16c657a646f63756d656e746f70656cc3ad63756c6172 + 656369656e74657367656e6572616c65737461727261676f6e617072c3a16374 + 6963616e6f7665646164657370726f70756573746170616369656e74657374c3 + a9636e696361736f626a657469766f73636f6e746163746f73e0a4aee0a587e0 + a482e0a4b2e0a4bfe0a48fe0a4b9e0a588e0a482e0a497e0a4afe0a4bee0a4b8 + e0a4bee0a4a5e0a48fe0a4b5e0a482e0a4b0e0a4b9e0a587e0a495e0a58be0a4 + 88e0a495e0a581e0a49be0a4b0e0a4b9e0a4bee0a4ace0a4bee0a4a6e0a495e0 + a4b9e0a4bee0a4b8e0a4ade0a580e0a4b9e0a581e0a48fe0a4b0e0a4b9e0a580 + e0a4aee0a588e0a482e0a4a6e0a4bfe0a4a8e0a4ace0a4bee0a4a46469706c6f + 646f6373e0a4b8e0a4aee0a4afe0a4b0e0a582e0a4aae0a4a8e0a4bee0a4aee0 + a4aae0a4a4e0a4bee0a4abe0a4bfe0a4b0e0a494e0a4b8e0a4a4e0a4a4e0a4b0 + e0a4b9e0a4b2e0a58be0a497e0a4b9e0a581e0a486e0a4ace0a4bee0a4b0e0a4 + a6e0a587e0a4b6e0a4b9e0a581e0a488e0a496e0a587e0a4b2e0a4afe0a4a6e0 + a4bfe0a495e0a4bee0a4aee0a4b5e0a587e0a4ace0a4a4e0a580e0a4a8e0a4ac + e0a580e0a49ae0a4aee0a58ce0a4a4e0a4b8e0a4bee0a4b2e0a4b2e0a587e0a4 + 96e0a49ce0a589e0a4ace0a4aee0a4a6e0a4a6e0a4a4e0a4a5e0a4bee0a4a8e0 + a4b9e0a580e0a4b6e0a4b9e0a4b0e0a485e0a4b2e0a497e0a495e0a4ade0a580 + e0a4a8e0a497e0a4b0e0a4aae0a4bee0a4b8e0a4b0e0a4bee0a4a4e0a495e0a4 + bfe0a48fe0a489e0a4b8e0a587e0a497e0a4afe0a580e0a4b9e0a582e0a481e0 + a486e0a497e0a587e0a49fe0a580e0a4aee0a496e0a58be0a49ce0a495e0a4be + e0a4b0e0a485e0a4ade0a580e0a497e0a4afe0a587e0a4a4e0a581e0a4aee0a4 + b5e0a58be0a49fe0a4a6e0a587e0a482e0a485e0a497e0a4b0e0a490e0a4b8e0 + a587e0a4aee0a587e0a4b2e0a4b2e0a497e0a4bee0a4b9e0a4bee0a4b2e0a48a + e0a4aae0a4b0e0a49ae0a4bee0a4b0e0a490e0a4b8e0a4bee0a4a6e0a587e0a4 + b0e0a49ce0a4bfe0a4b8e0a4a6e0a4bfe0a4b2e0a4ace0a482e0a4a6e0a4ace0 + a4a8e0a4bee0a4b9e0a582e0a482e0a4b2e0a4bee0a496e0a49ce0a580e0a4a4 + + + +Alakuijala & Szabadka Expires June 10, 2016 [Page 71] + +Internet-Draft Brotli December 2015 + + + e0a4ace0a49fe0a4a8e0a4aee0a4bfe0a4b2e0a487e0a4b8e0a587e0a486e0a4 + a8e0a587e0a4a8e0a4afe0a4bee0a495e0a581e0a4b2e0a4b2e0a589e0a497e0 + a4ade0a4bee0a497e0a4b0e0a587e0a4b2e0a49ce0a497e0a4b9e0a4b0e0a4be + e0a4aee0a4b2e0a497e0a587e0a4aae0a587e0a49ce0a4b9e0a4bee0a4a5e0a4 + 87e0a4b8e0a580e0a4b8e0a4b9e0a580e0a495e0a4b2e0a4bee0a4a0e0a580e0 + a495e0a4b9e0a4bee0a481e0a4a6e0a582e0a4b0e0a4a4e0a4b9e0a4a4e0a4b8 + e0a4bee0a4a4e0a4afe0a4bee0a4a6e0a486e0a4afe0a4bee0a4aae0a4bee0a4 + 95e0a495e0a58ce0a4a8e0a4b6e0a4bee0a4aee0a4a6e0a587e0a496e0a4afe0 + a4b9e0a580e0a4b0e0a4bee0a4afe0a496e0a581e0a4a6e0a4b2e0a497e0a580 + 63617465676f72696573657870657269656e63653c2f7469746c653e0d0a436f + 70797269676874206a617661736372697074636f6e646974696f6e7365766572 + 797468696e673c7020636c6173733d22746563686e6f6c6f67796261636b6772 + 6f756e643c6120636c6173733d226d616e6167656d656e7426636f70793b2032 + 30316a6176615363726970746368617261637465727362726561646372756d62 + 7468656d73656c766573686f72697a6f6e74616c676f7665726e6d656e744361 + 6c69666f726e696161637469766974696573646973636f76657265644e617669 + 676174696f6e7472616e736974696f6e636f6e6e656374696f6e6e6176696761 + 74696f6e617070656172616e63653c2f7469746c653e3c6d636865636b626f78 + 2220746563686e697175657370726f74656374696f6e6170706172656e746c79 + 61732077656c6c206173756e74272c202755412d7265736f6c7574696f6e6f70 + 65726174696f6e7374656c65766973696f6e7472616e736c6174656457617368 + 696e67746f6e6e6176696761746f722e203d2077696e646f772e696d70726573 + 73696f6e266c743b62722667743b6c697465726174757265706f70756c617469 + 6f6e6267636f6c6f723d2223657370656369616c6c7920636f6e74656e743d22 + 70726f64756374696f6e6e6577736c657474657270726f706572746965736465 + 66696e6974696f6e6c656164657273686970546563686e6f6c6f67795061726c + 69616d656e74636f6d70617269736f6e756c20636c6173733d222e696e646578 + 4f662822636f6e636c7573696f6e64697363757373696f6e636f6d706f6e656e + 747362696f6c6f676963616c5265766f6c7574696f6e5f636f6e7461696e6572 + 756e64657273746f6f646e6f7363726970743e3c7065726d697373696f6e6561 + 6368206f7468657261746d6f737068657265206f6e666f6375733d223c666f72 + 6d2069643d2270726f63657373696e67746869732e76616c756567656e657261 + 74696f6e436f6e666572656e636573756273657175656e7477656c6c2d6b6e6f + 776e766172696174696f6e7372657075746174696f6e7068656e6f6d656e6f6e + 6469736369706c696e656c6f676f2e706e67222028646f63756d656e742c626f + 756e64617269657365787072657373696f6e736574746c656d656e744261636b + 67726f756e646f7574206f6620746865656e7465727072697365282268747470 + 733a2220756e657363617065282270617373776f7264222064656d6f63726174 + 69633c6120687265663d222f77726170706572223e0a6d656d62657273686970 + 6c696e6775697374696370783b70616464696e677068696c6f736f7068796173 + 73697374616e6365756e6976657273697479666163696c69746965737265636f + 676e697a6564707265666572656e636569662028747970656f666d61696e7461 + 696e6564766f636162756c6172796879706f7468657369732e7375626d697428 + 293b26616d703b6e6273703b616e6e6f746174696f6e626568696e6420746865 + 466f756e646174696f6e7075626c697368657222617373756d7074696f6e696e + 74726f6475636564636f7272757074696f6e736369656e74697374736578706c + 696369746c79696e7374656164206f6664696d656e73696f6e73206f6e436c69 + 636b3d22636f6e736964657265646465706172746d656e746f63637570617469 + + + +Alakuijala & Szabadka Expires June 10, 2016 [Page 72] + +Internet-Draft Brotli December 2015 + + + 6f6e736f6f6e206166746572696e766573746d656e7470726f6e6f756e636564 + 6964656e7469666965646578706572696d656e744d616e6167656d656e746765 + 6f6772617068696322206865696768743d226c696e6b2072656c3d222e726570 + 6c616365282f64657072657373696f6e636f6e666572656e636570756e697368 + 6d656e74656c696d696e61746564726573697374616e63656164617074617469 + 6f6e6f70706f736974696f6e77656c6c206b6e6f776e737570706c656d656e74 + 64657465726d696e6564683120636c6173733d223070783b6d617267696e6d65 + 6368616e6963616c7374617469737469637363656c65627261746564476f7665 + 726e6d656e740a0a447572696e672074646576656c6f70657273617274696669 + 6369616c6571756976616c656e746f726967696e61746564436f6d6d69737369 + 6f6e6174746163686d656e743c7370616e2069643d2274686572652077657265 + 4e656465726c616e64736265796f6e6420746865726567697374657265646a6f + 75726e616c6973746672657175656e746c79616c6c206f66207468656c616e67 + 3d22656e22203c2f7374796c653e0d0a6162736f6c7574653b20737570706f72 + 74696e6765787472656d656c79206d61696e73747265616d3c2f7374726f6e67 + 3e20706f70756c6172697479656d706c6f796d656e743c2f7461626c653e0d0a + 20636f6c7370616e3d223c2f666f726d3e0a2020636f6e76657273696f6e6162 + 6f757420746865203c2f703e3c2f6469763e696e746567726174656422206c61 + 6e673d22656e506f727475677565736573756273746974757465696e64697669 + 6475616c696d706f737369626c656d756c74696d65646961616c6d6f73742061 + 6c6c707820736f6c6964202361706172742066726f6d7375626a65637420746f + 696e20456e676c697368637269746963697a656465786365707420666f726775 + 6964656c696e65736f726967696e616c6c7972656d61726b61626c6574686520 + 7365636f6e64683220636c6173733d223c61207469746c653d2228696e636c75 + 64696e67706172616d657465727370726f686962697465643d2022687474703a + 2f2f64696374696f6e61727970657263657074696f6e7265766f6c7574696f6e + 666f756e646174696f6e70783b6865696768743a7375636365737366756c7375 + 70706f72746572736d696c6c656e6e69756d6869732066617468657274686520 + 2671756f743b6e6f2d7265706561743b636f6d6d65726369616c696e64757374 + 7269616c656e636f757261676564616d6f756e74206f6620756e6f6666696369 + 616c656666696369656e63795265666572656e636573636f6f7264696e617465 + 646973636c61696d657265787065646974696f6e646576656c6f70696e676361 + 6c63756c6174656473696d706c69666965646c65676974696d61746573756273 + 7472696e6728302220636c6173733d22636f6d706c6574656c79696c6c757374 + 7261746566697665207965617273696e737472756d656e745075626c69736869 + 6e67312220636c6173733d2270737963686f6c6f6779636f6e666964656e6365 + 6e756d626572206f6620616273656e6365206f66666f6375736564206f6e6a6f + 696e6564207468657374727563747572657370726576696f75736c793e3c2f69 + 6672616d653e6f6e636520616761696e62757420726174686572696d6d696772 + 616e74736f6620636f757273652c612067726f7570206f664c69746572617475 + 7265556e6c696b65207468653c2f613e266e6273703b0a66756e6374696f6e20 + 69742077617320746865436f6e76656e74696f6e6175746f6d6f62696c655072 + 6f74657374616e74616767726573736976656166746572207468652053696d69 + 6c61726c792c22202f3e3c2f6469763e636f6c6c656374696f6e0d0a66756e63 + 74696f6e7669736962696c69747974686520757365206f66766f6c756e746565 + 727361747472616374696f6e756e6465722074686520746872656174656e6564 + 2a3c215b43444154415b696d706f7274616e6365696e2067656e6572616c7468 + 65206c61747465723c2f666f726d3e0a3c2f2e696e6465784f66282769203d20 + + + +Alakuijala & Szabadka Expires June 10, 2016 [Page 73] + +Internet-Draft Brotli December 2015 + + + 303b2069203c646966666572656e63656465766f74656420746f747261646974 + 696f6e7373656172636820666f72756c74696d6174656c79746f75726e616d65 + 6e7461747472696275746573736f2d63616c6c6564207d0a3c2f7374796c653e + 6576616c756174696f6e656d70686173697a656461636365737369626c653c2f + 73656374696f6e3e73756363657373696f6e616c6f6e6720776974684d65616e + 7768696c652c696e64757374726965733c2f613e3c6272202f3e686173206265 + 636f6d6561737065637473206f6654656c65766973696f6e7375666669636965 + 6e746261736b657462616c6c626f7468207369646573636f6e74696e75696e67 + 616e2061727469636c653c696d6720616c743d22616476656e74757265736869 + 73206d6f746865726d616e636865737465727072696e6369706c657370617274 + 6963756c6172636f6d6d656e7461727965666665637473206f66646563696465 + 6420746f223e3c7374726f6e673e7075626c6973686572734a6f75726e616c20 + 6f66646966666963756c7479666163696c697461746561636365707461626c65 + 7374796c652e637373220966756e6374696f6e20696e6e6f766174696f6e3e43 + 6f70797269676874736974756174696f6e73776f756c64206861766562757369 + 6e657373657344696374696f6e61727973746174656d656e74736f6674656e20 + 7573656470657273697374656e74696e204a616e75617279636f6d7072697369 + 6e673c2f7469746c653e0a096469706c6f6d61746963636f6e7461696e696e67 + 706572666f726d696e67657874656e73696f6e736d6179206e6f74206265636f + 6e63657074206f66206f6e636c69636b3d22497420697320616c736f66696e61 + 6e6369616c206d616b696e67207468654c7578656d626f757267616464697469 + 6f6e616c6172652063616c6c6564656e676167656420696e2273637269707422 + 293b62757420697420776173656c656374726f6e69636f6e7375626d69743d22 + 0a3c212d2d20456e6420656c656374726963616c6f6666696369616c6c797375 + 6767657374696f6e746f70206f6620746865756e6c696b652074686541757374 + 72616c69616e4f726967696e616c6c797265666572656e6365730a3c2f686561 + 643e0d0a7265636f676e69736564696e697469616c697a656c696d6974656420 + 746f416c6578616e647269617265746972656d656e74416476656e7475726573 + 666f75722079656172730a0a266c743b212d2d20696e6372656173696e676465 + 636f726174696f6e683320636c6173733d226f726967696e73206f666f626c69 + 676174696f6e726567756c6174696f6e636c61737369666965642866756e6374 + 696f6e28616476616e74616765736265696e672074686520686973746f726961 + 6e733c62617365206872656672657065617465646c7977696c6c696e6720746f + 636f6d70617261626c6564657369676e617465646e6f6d696e6174696f6e6675 + 6e6374696f6e616c696e7369646520746865726576656c6174696f6e656e6420 + 6f66207468657320666f722074686520617574686f72697a6564726566757365 + 6420746f74616b6520706c6163656175746f6e6f6d6f7573636f6d70726f6d69 + 7365706f6c69746963616c2072657374617572616e7474776f206f6620746865 + 466562727561727920327175616c697479206f667377666f626a6563742e756e + 6465727374616e646e6561726c7920616c6c7772697474656e206279696e7465 + 727669657773222077696474683d22317769746864726177616c666c6f61743a + 6c656674697320757375616c6c7963616e646964617465736e65777370617065 + 72736d7973746572696f75734465706172746d656e7462657374206b6e6f776e + 7061726c69616d656e7473757070726573736564636f6e76656e69656e747265 + 6d656d6265726564646966666572656e742073797374656d6174696368617320 + 6c656420746f70726f706167616e6461636f6e74726f6c6c6564696e666c7565 + 6e636573636572656d6f6e69616c70726f636c61696d656450726f7465637469 + 6f6e6c6920636c6173733d22536369656e7469666963636c6173733d226e6f2d + + + +Alakuijala & Szabadka Expires June 10, 2016 [Page 74] + +Internet-Draft Brotli December 2015 + + + 74726164656d61726b736d6f7265207468616e20776964657370726561644c69 + 6265726174696f6e746f6f6b20706c616365646179206f66207468656173206c + 6f6e67206173696d707269736f6e65644164646974696f6e616c0a3c68656164 + 3e0a3c6d4c61626f7261746f72794e6f76656d6265722032657863657074696f + 6e73496e647573747269616c76617269657479206f66666c6f61743a206c6566 + 447572696e67207468656173736573736d656e7468617665206265656e206465 + 616c732077697468537461746973746963736f6363757272656e63652f756c3e + 3c2f6469763e636c656172666978223e746865207075626c69636d616e792079 + 65617273776869636820776572656f7665722074696d652c73796e6f6e796d6f + 7573636f6e74656e74223e0a70726573756d61626c796869732066616d696c79 + 757365724167656e742e756e6578706563746564696e636c7564696e67206368 + 616c6c656e67656461206d696e6f72697479756e646566696e65642262656c6f + 6e677320746f74616b656e2066726f6d696e204f63746f626572706f73697469 + 6f6e3a207361696420746f20626572656c6967696f7573204665646572617469 + 6f6e20726f777370616e3d226f6e6c792061206665776d65616e742074686174 + 6c656420746f207468652d2d3e0d0a3c646976203c6669656c647365743e4172 + 6368626973686f7020636c6173733d226e6f6265696e67207573656461707072 + 6f616368657370726976696c656765736e6f7363726970743e0a726573756c74 + 7320696e6d617920626520746865456173746572206567676d656368616e6973 + 6d73726561736f6e61626c65506f70756c6174696f6e436f6c6c656374696f6e + 73656c6563746564223e6e6f7363726970743e0d2f696e6465782e7068706172 + 726976616c206f662d6a7373646b2729293b6d616e6167656420746f696e636f + 6d706c65746563617375616c74696573636f6d706c6574696f6e436872697374 + 69616e7353657074656d6265722061726974686d6574696370726f6365647572 + 65736d69676874206861766550726f64756374696f6e69742061707065617273 + 5068696c6f736f706879667269656e64736869706c656164696e6720746f6769 + 76696e6720746865746f776172642074686567756172616e74656564646f6375 + 6d656e746564636f6c6f723a23303030766964656f2067616d65636f6d6d6973 + 73696f6e7265666c656374696e676368616e6765207468656173736f63696174 + 656473616e732d73657269666f6e6b657970726573733b2070616464696e673a + 48652077617320746865756e6465726c79696e677479706963616c6c79202c20 + 616e642074686520737263456c656d656e747375636365737369766573696e63 + 65207468652073686f756c64206265206e6574776f726b696e676163636f756e + 74696e67757365206f66207468656c6f776572207468616e73686f7773207468 + 61743c2f7370616e3e0a0909636f6d706c61696e7473636f6e74696e756f7573 + 7175616e746974696573617374726f6e6f6d6572686520646964206e6f746475 + 6520746f206974736170706c69656420746f616e20617665726167656566666f + 72747320746f74686520667574757265617474656d707420746f546865726566 + 6f72652c6361706162696c69747952657075626c6963616e77617320666f726d + 6564456c656374726f6e69636b696c6f6d65746572736368616c6c656e676573 + 7075626c697368696e6774686520666f726d6572696e646967656e6f75736469 + 72656374696f6e7373756273696469617279636f6e7370697261637964657461 + 696c73206f66616e6420696e207468656166666f726461626c65737562737461 + 6e636573726561736f6e20666f72636f6e76656e74696f6e6974656d74797065 + 3d226162736f6c7574656c79737570706f7365646c7972656d61696e65642061 + 6174747261637469766574726176656c6c696e6773657061726174656c79666f + 6375736573206f6e656c656d656e746172796170706c696361626c65666f756e + 6420746861747374796c6573686565746d616e757363726970747374616e6473 + + + +Alakuijala & Szabadka Expires June 10, 2016 [Page 75] + +Internet-Draft Brotli December 2015 + + + 20666f72206e6f2d72657065617428736f6d6574696d6573436f6d6d65726369 + 616c696e20416d6572696361756e64657274616b656e71756172746572206f66 + 616e206578616d706c65706572736f6e616c6c79696e6465782e7068703f3c2f + 627574746f6e3e0a70657263656e74616765626573742d6b6e6f776e63726561 + 74696e67206122206469723d226c74724c69657574656e616e740a3c64697620 + 69643d227468657920776f756c646162696c697479206f666d61646520757020 + 6f666e6f7465642074686174636c656172207468617461726775652074686174 + 746f20616e6f746865726368696c6472656e2773707572706f7365206f66666f + 726d756c6174656462617365642075706f6e74686520726567696f6e7375626a + 656374206f6670617373656e67657273706f7373657373696f6e2e0a0a496e20 + 746865204265666f7265207468656166746572776172647363757272656e746c + 79206163726f737320746865736369656e7469666963636f6d6d756e6974792e + 6361706974616c69736d696e204765726d616e7972696768742d77696e677468 + 652073797374656d536f6369657479206f66706f6c6974696369616e64697265 + 6374696f6e3a77656e74206f6e20746f72656d6f76616c206f66204e65772059 + 6f726b2061706172746d656e7473696e6469636174696f6e647572696e672074 + 6865756e6c65737320746865686973746f726963616c686164206265656e2061 + 646566696e6974697665696e6772656469656e74617474656e64616e63654365 + 6e74657220666f7270726f6d696e656e63657265616479537461746573747261 + 74656769657362757420696e2074686561732070617274206f66636f6e737469 + 74757465636c61696d20746861746c61626f7261746f7279636f6d7061746962 + 6c656661696c757265206f662c207375636820617320626567616e2077697468 + 7573696e672074686520746f2070726f7669646566656174757265206f666672 + 6f6d2077686963682f2220636c6173733d2267656f6c6f676963616c73657665 + 72616c206f6664656c69626572617465696d706f7274616e7420686f6c647320 + 74686174696e672671756f743b2076616c69676e3d746f70746865204765726d + 616e6f757473696465206f666e65676f74696174656468697320636172656572 + 73657061726174696f6e69643d227365617263687761732063616c6c65647468 + 6520666f7572746872656372656174696f6e6f74686572207468616e70726576 + 656e74696f6e7768696c652074686520656475636174696f6e2c636f6e6e6563 + 74696e6761636375726174656c7977657265206275696c74776173206b696c6c + 656461677265656d656e74736d756368206d6f72652044756520746f20746865 + 77696474683a20313030736f6d65206f746865724b696e67646f6d206f667468 + 6520656e7469726566616d6f757320666f72746f20636f6e6e6563746f626a65 + 637469766573746865204672656e636870656f706c6520616e64666561747572 + 6564223e6973207361696420746f7374727563747572616c7265666572656e64 + 756d6d6f7374206f6674656e612073657061726174652d3e0a3c646976206964 + 204f6666696369616c20776f726c64776964652e617269612d6c6162656c7468 + 6520706c616e6574616e642069742077617364222076616c75653d226c6f6f6b + 696e6720617462656e6566696369616c61726520696e207468656d6f6e69746f + 72696e677265706f727465646c79746865206d6f6465726e776f726b696e6720 + 6f6e616c6c6f77656420746f77686572652074686520696e6e6f766174697665 + 3c2f613e3c2f6469763e736f756e64747261636b736561726368466f726d7465 + 6e6420746f206265696e7075742069643d226f70656e696e67206f6672657374 + 72696374656461646f7074656420627961646472657373696e677468656f6c6f + 6769616e6d6574686f6473206f6676617269616e74206f664368726973746961 + 6e2076657279206c617267656175746f6d6f7469766562792066617220746865 + 72616e67652066726f6d70757273756974206f66666f6c6c6f77207468656272 + + + +Alakuijala & Szabadka Expires June 10, 2016 [Page 76] + +Internet-Draft Brotli December 2015 + + + 6f7567687420746f696e20456e676c616e646167726565207468617461636375 + 736564206f66636f6d65732066726f6d70726576656e74696e67646976207374 + 796c653d686973206f72206865727472656d656e646f757366726565646f6d20 + 6f66636f6e6365726e696e67302031656d2031656d3b4261736b657462616c6c + 2f7374796c652e637373616e206561726c6965726576656e2061667465722f22 + 207469746c653d222e636f6d2f696e64657874616b696e672074686570697474 + 736275726768636f6e74656e74223e0d3c7363726970743e28667475726e6564 + 206f7574686176696e67207468653c2f7370616e3e0d0a206f63636173696f6e + 616c626563617573652069747374617274656420746f706879736963616c6c79 + 3e3c2f6469763e0a20206372656174656420627943757272656e746c792c2062 + 67636f6c6f723d22746162696e6465783d22646973617374726f7573416e616c + 797469637320616c736f2068617320613e3c6469762069643d223c2f7374796c + 653e0a3c63616c6c656420666f7273696e67657220616e642e737263203d2022 + 2f2f76696f6c6174696f6e737468697320706f696e74636f6e7374616e746c79 + 6973206c6f63617465647265636f7264696e6773642066726f6d207468656e65 + 6465726c616e6473706f7274756775c3aa73d7a2d791d7a8d799d7aad981d8a7 + d8b1d8b3db8c6465736172726f6c6c6f636f6d656e746172696f656475636163 + 69c3b36e7365707469656d6272657265676973747261646f64697265636369c3 + b36e75626963616369c3b36e7075626c69636964616472657370756573746173 + 726573756c7461646f73696d706f7274616e746572657365727661646f736172 + 74c3ad63756c6f736469666572656e7465737369677569656e746573726570c3 + ba626c69636173697475616369c3b36e6d696e6973746572696f707269766163 + 696461646469726563746f72696f666f726d616369c3b36e706f626c616369c3 + b36e707265736964656e7465636f6e74656e69646f7361636365736f72696f73 + 746563686e6f72617469706572736f6e616c657363617465676f72c3ad616573 + 70656369616c6573646973706f6e69626c6561637475616c6964616472656665 + 72656e63696176616c6c61646f6c69646269626c696f7465636172656c616369 + 6f6e657363616c656e646172696f706f6cc3ad7469636173616e746572696f72 + 6573646f63756d656e746f736e61747572616c657a616d6174657269616c6573 + 6469666572656e63696165636f6ec3b36d6963617472616e73706f727465726f + 6472c3ad6775657a70617274696369706172656e6375656e7472616e64697363 + 757369c3b36e6573747275637475726166756e64616369c3b36e667265637565 + 6e7465737065726d616e656e7465746f74616c6d656e7465d0bcd0bed0b6d0bd + d0bed0b1d183d0b4d0b5d182d0bcd0bed0b6d0b5d182d0b2d180d0b5d0bcd18f + d182d0b0d0bad0b6d0b5d187d182d0bed0b1d18bd0b1d0bed0bbd0b5d0b5d0be + d187d0b5d0bdd18cd18dd182d0bed0b3d0bed0bad0bed0b3d0b4d0b0d0bfd0be + d181d0bbd0b5d0b2d181d0b5d0b3d0bed181d0b0d0b9d182d0b5d187d0b5d180 + d0b5d0b7d0bcd0bed0b3d183d182d181d0b0d0b9d182d0b0d0b6d0b8d0b7d0bd + d0b8d0bcd0b5d0b6d0b4d183d0b1d183d0b4d183d182d09fd0bed0b8d181d0ba + d0b7d0b4d0b5d181d18cd0b2d0b8d0b4d0b5d0bed181d0b2d18fd0b7d0b8d0bd + d183d0b6d0bdd0bed181d0b2d0bed0b5d0b9d0bbd18ed0b4d0b5d0b9d0bfd0be + d180d0bdd0bed0bcd0bdd0bed0b3d0bed0b4d0b5d182d0b5d0b9d181d0b2d0be + d0b8d185d0bfd180d0b0d0b2d0b0d182d0b0d0bad0bed0b9d0bcd0b5d181d182 + d0bed0b8d0bcd0b5d0b5d182d0b6d0b8d0b7d0bdd18cd0bed0b4d0bdd0bed0b9 + d0bbd183d187d188d0b5d0bfd0b5d180d0b5d0b4d187d0b0d181d182d0b8d187 + d0b0d181d182d18cd180d0b0d0b1d0bed182d0bdd0bed0b2d18bd185d0bfd180 + d0b0d0b2d0bed181d0bed0b1d0bed0b9d0bfd0bed182d0bed0bcd0bcd0b5d0bd + d0b5d0b5d187d0b8d181d0bbd0b5d0bdd0bed0b2d18bd0b5d183d181d0bbd183 + + + +Alakuijala & Szabadka Expires June 10, 2016 [Page 77] + +Internet-Draft Brotli December 2015 + + + d0b3d0bed0bad0bed0bbd0bed0bdd0b0d0b7d0b0d0b4d182d0b0d0bad0bed0b5 + d182d0bed0b3d0b4d0b0d0bfd0bed187d182d0b8d09fd0bed181d0bbd0b5d182 + d0b0d0bad0b8d0b5d0bdd0bed0b2d18bd0b9d181d182d0bed0b8d182d182d0b0 + d0bad0b8d185d181d180d0b0d0b7d183d0a1d0b0d0bdd0bad182d184d0bed180 + d183d0bcd09ad0bed0b3d0b4d0b0d0bad0bdd0b8d0b3d0b8d181d0bbd0bed0b2 + d0b0d0bdd0b0d188d0b5d0b9d0bdd0b0d0b9d182d0b8d181d0b2d0bed0b8d0bc + d181d0b2d18fd0b7d18cd0bbd18ed0b1d0bed0b9d187d0b0d181d182d0bed181 + d180d0b5d0b4d0b8d09ad180d0bed0bcd0b5d0a4d0bed180d183d0bcd180d18b + d0bdd0bad0b5d181d182d0b0d0bbd0b8d0bfd0bed0b8d181d0bad182d18bd181 + d18fd187d0bcd0b5d181d18fd186d186d0b5d0bdd182d180d182d180d183d0b4 + d0b0d181d0b0d0bcd18bd185d180d18bd0bdd0bad0b0d09dd0bed0b2d18bd0b9 + d187d0b0d181d0bed0b2d0bcd0b5d181d182d0b0d184d0b8d0bbd18cd0bcd0bc + d0b0d180d182d0b0d181d182d180d0b0d0bdd0bcd0b5d181d182d0b5d182d0b5 + d0bad181d182d0bdd0b0d188d0b8d185d0bcd0b8d0bdd183d182d0b8d0bcd0b5 + d0bdd0b8d0b8d0bcd0b5d18ed182d0bdd0bed0bcd0b5d180d0b3d0bed180d0be + d0b4d181d0b0d0bcd0bed0bcd18dd182d0bed0bcd183d0bad0bed0bdd186d0b5 + d181d0b2d0bed0b5d0bcd0bad0b0d0bad0bed0b9d090d180d185d0b8d0b2d985 + d986d8aad8afd989d8a5d8b1d8b3d8a7d984d8b1d8b3d8a7d984d8a9d8a7d984 + d8b9d8a7d985d983d8aad8a8d987d8a7d8a8d8b1d8a7d985d8acd8a7d984d98a + d988d985d8a7d984d8b5d988d8b1d8acd8afd98ad8afd8a9d8a7d984d8b9d8b6 + d988d8a5d8b6d8a7d981d8a9d8a7d984d982d8b3d985d8a7d984d8b9d8a7d8a8 + d8aad8add985d98ad984d985d984d981d8a7d8aad985d984d8aad982d989d8aa + d8b9d8afd98ad984d8a7d984d8b4d8b9d8b1d8a3d8aed8a8d8a7d8b1d8aad8b7 + d988d98ad8b1d8b9d984d98ad983d985d8a5d8b1d981d8a7d982d8b7d984d8a8 + d8a7d8aad8a7d984d984d8bad8a9d8aad8b1d8aad98ad8a8d8a7d984d986d8a7 + d8b3d8a7d984d8b4d98ad8aed985d986d8aad8afd98ad8a7d984d8b9d8b1d8a8 + d8a7d984d982d8b5d8b5d8a7d981d984d8a7d985d8b9d984d98ad987d8a7d8aa + d8add8afd98ad8abd8a7d984d984d987d985d8a7d984d8b9d985d984d985d983 + d8aad8a8d8a9d98ad985d983d986d983d8a7d984d8b7d981d984d981d98ad8af + d98ad988d8a5d8afd8a7d8b1d8a9d8aad8a7d8b1d98ad8aed8a7d984d8b5d8ad + d8a9d8aad8b3d8acd98ad984d8a7d984d988d982d8aad8b9d986d8afd985d8a7 + d985d8afd98ad986d8a9d8aad8b5d985d98ad985d8a3d8b1d8b4d98ad981d8a7 + d984d8b0d98ad986d8b9d8b1d8a8d98ad8a9d8a8d988d8a7d8a8d8a9d8a3d984 + d8b9d8a7d8a8d8a7d984d8b3d981d8b1d985d8b4d8a7d983d984d8aad8b9d8a7 + d984d989d8a7d984d8a3d988d984d8a7d984d8b3d986d8a9d8acd8a7d985d8b9 + d8a9d8a7d984d8b5d8add981d8a7d984d8afd98ad986d983d984d985d8a7d8aa + d8a7d984d8aed8a7d8b5d8a7d984d985d984d981d8a3d8b9d8b6d8a7d8a1d983 + d8aad8a7d8a8d8a9d8a7d984d8aed98ad8b1d8b1d8b3d8a7d8a6d984d8a7d984 + d982d984d8a8d8a7d984d8a3d8afd8a8d985d982d8a7d8b7d8b9d985d8b1d8a7 + d8b3d984d985d986d8b7d982d8a9d8a7d984d983d8aad8a8d8a7d984d8b1d8ac + d984d8a7d8b4d8aad8b1d983d8a7d984d982d8afd985d98ad8b9d8b7d98ad983 + 7342795461674e616d65282e6a70672220616c743d2231707820736f6c696420 + 232e6769662220616c743d227472616e73706172656e74696e666f726d617469 + 6f6e6170706c69636174696f6e22206f6e636c69636b3d2265737461626c6973 + 6865646164766572746973696e672e706e672220616c743d22656e7669726f6e + 6d656e74706572666f726d616e6365617070726f70726961746526616d703b6d + 646173683b696d6d6564696174656c793c2f7374726f6e673e3c2f7261746865 + 72207468616e74656d7065726174757265646576656c6f706d656e74636f6d70 + + + +Alakuijala & Szabadka Expires June 10, 2016 [Page 78] + +Internet-Draft Brotli December 2015 + + + 65746974696f6e706c616365686f6c6465727669736962696c6974793a636f70 + 797269676874223e3022206865696768743d226576656e2074686f7567687265 + 706c6163656d656e7464657374696e6174696f6e436f72706f726174696f6e3c + 756c20636c6173733d224173736f63696174696f6e696e646976696475616c73 + 706572737065637469766573657454696d656f75742875726c28687474703a2f + 2f6d617468656d61746963736d617267696e2d746f703a6576656e7475616c6c + 79206465736372697074696f6e29206e6f2d726570656174636f6c6c65637469 + 6f6e732e4a50477c7468756d627c70617274696369706174652f686561643e3c + 626f6479666c6f61743a6c6566743b3c6c6920636c6173733d2268756e647265 + 6473206f660a0a486f77657665722c20636f6d706f736974696f6e636c656172 + 3a626f74683b636f6f7065726174696f6e77697468696e20746865206c616265 + 6c20666f723d22626f726465722d746f703a4e6577205a65616c616e64726563 + 6f6d6d656e64656470686f746f677261706879696e746572657374696e67266c + 743b7375702667743b636f6e74726f76657273794e65746865726c616e647361 + 6c7465726e61746976656d61786c656e6774683d22737769747a65726c616e64 + 446576656c6f706d656e74657373656e7469616c6c790a0a416c74686f756768 + 203c2f74657874617265613e7468756e64657262697264726570726573656e74 + 656426616d703b6e646173683b73706563756c6174696f6e636f6d6d756e6974 + 6965736c656769736c6174696f6e656c656374726f6e6963730a093c64697620 + 69643d22696c6c7573747261746564656e67696e656572696e67746572726974 + 6f72696573617574686f72697469657364697374726962757465643622206865 + 696768743d2273616e732d73657269663b63617061626c65206f662064697361 + 70706561726564696e7465726163746976656c6f6f6b696e6720666f72697420 + 776f756c6420626541666768616e697374616e77617320637265617465644d61 + 74682e666c6f6f7228737572726f756e64696e6763616e20616c736f2062656f + 62736572766174696f6e6d61696e74656e616e6365656e636f756e7465726564 + 3c683220636c6173733d226d6f726520726563656e7469742068617320626565 + 6e696e766173696f6e206f66292e67657454696d65282966756e64616d656e74 + 616c4465737069746520746865223e3c6469762069643d22696e737069726174 + 696f6e6578616d696e6174696f6e7072657061726174696f6e6578706c616e61 + 74696f6e3c696e7075742069643d223c2f613e3c2f7370616e3e76657273696f + 6e73206f66696e737472756d656e74736265666f72652074686520203d202768 + 7474703a2f2f4465736372697074696f6e72656c61746976656c79202e737562 + 737472696e672865616368206f66207468656578706572696d656e7473696e66 + 6c75656e7469616c696e746567726174696f6e6d616e792070656f706c656475 + 6520746f2074686520636f6d62696e6174696f6e646f206e6f7420686176654d + 6964646c6520456173743c6e6f7363726970743e3c636f707972696768742220 + 7065726861707320746865696e737469747574696f6e696e20446563656d6265 + 72617272616e67656d656e746d6f73742066616d6f7573706572736f6e616c69 + 74796372656174696f6e206f666c696d69746174696f6e736578636c75736976 + 656c79736f7665726569676e74792d636f6e74656e74223e0a3c746420636c61 + 73733d22756e64657267726f756e64706172616c6c656c20746f646f63747269 + 6e65206f666f636375706965642062797465726d696e6f6c6f677952656e6169 + 7373616e636561206e756d626572206f66737570706f727420666f726578706c + 6f726174696f6e7265636f676e6974696f6e7072656465636573736f723c696d + 67207372633d222f3c683120636c6173733d227075626c69636174696f6e6d61 + 7920616c736f2062657370656369616c697a65643c2f6669656c647365743e70 + 726f67726573736976656d696c6c696f6e73206f667374617465732074686174 + + + +Alakuijala & Szabadka Expires June 10, 2016 [Page 79] + +Internet-Draft Brotli December 2015 + + + 656e666f7263656d656e7461726f756e6420746865206f6e6520616e6f746865 + 722e706172656e744e6f64656167726963756c74757265416c7465726e617469 + 76657265736561726368657273746f7761726473207468654d6f7374206f6620 + 7468656d616e79206f746865722028657370656369616c6c793c746420776964 + 74683d223b77696474683a31303025696e646570656e64656e743c683320636c + 6173733d22206f6e6368616e67653d22292e616464436c61737328696e746572 + 616374696f6e4f6e65206f6620746865206461756768746572206f6661636365 + 73736f726965736272616e63686573206f660d0a3c6469762069643d22746865 + 206c6172676573746465636c61726174696f6e726567756c6174696f6e73496e + 666f726d6174696f6e7472616e736c6174696f6e646f63756d656e7461727969 + 6e206f7264657220746f223e0a3c686561643e0a3c22206865696768743d2231 + 6163726f737320746865206f7269656e746174696f6e293b3c2f736372697074 + 3e696d706c656d656e74656463616e206265207365656e746865726520776173 + 206164656d6f6e737472617465636f6e7461696e6572223e636f6e6e65637469 + 6f6e737468652042726974697368776173207772697474656e21696d706f7274 + 616e743b70783b206d617267696e2d666f6c6c6f7765642062796162696c6974 + 7920746f20636f6d706c696361746564647572696e672074686520696d6d6967 + 726174696f6e616c736f2063616c6c65643c683420636c6173733d2264697374 + 696e6374696f6e7265706c61636564206279676f7665726e6d656e74736c6f63 + 6174696f6e206f66696e204e6f76656d62657277686574686572207468653c2f + 703e0a3c2f6469763e6163717569736974696f6e63616c6c6564207468652070 + 65727365637574696f6e64657369676e6174696f6e7b666f6e742d73697a653a + 617070656172656420696e696e766573746967617465657870657269656e6365 + 646d6f7374206c696b656c79776964656c79207573656464697363757373696f + 6e7370726573656e6365206f662028646f63756d656e742e657874656e736976 + 656c79497420686173206265656e697420646f6573206e6f74636f6e74726172 + 7920746f696e6861626974616e7473696d70726f76656d656e747363686f6c61 + 7273686970636f6e73756d7074696f6e696e737472756374696f6e666f722065 + 78616d706c656f6e65206f72206d6f726570783b2070616464696e6774686520 + 63757272656e746120736572696573206f6661726520757375616c6c79726f6c + 6520696e2074686570726576696f75736c792064657269766174697665736576 + 6964656e6365206f66657870657269656e636573636f6c6f72736368656d6573 + 7461746564207468617463657274696669636174653c2f613e3c2f6469763e0a + 2073656c65637465643d2268696768207363686f6f6c726573706f6e73652074 + 6f636f6d666f727461626c6561646f7074696f6e206f66746872656520796561 + 727374686520636f756e747279696e204665627275617279736f207468617420 + 74686570656f706c652077686f2070726f76696465642062793c706172616d20 + 6e616d656166666563746564206279696e207465726d73206f666170706f696e + 746d656e7449534f2d383835392d312277617320626f726e20696e686973746f + 726963616c2072656761726465642061736d6561737572656d656e7469732062 + 61736564206f6e20616e64206f74686572203a2066756e6374696f6e28736967 + 6e69666963616e7463656c6562726174696f6e7472616e736d69747465642f6a + 732f6a71756572792e6973206b6e6f776e2061737468656f7265746963616c20 + 746162696e6465783d22697420636f756c642062653c6e6f7363726970743e0a + 686176696e67206265656e0d0a3c686561643e0d0a3c202671756f743b546865 + 20636f6d70696c6174696f6e686520686164206265656e70726f647563656420 + 62797068696c6f736f70686572636f6e7374727563746564696e74656e646564 + 20746f616d6f6e67206f74686572636f6d706172656420746f746f2073617920 + + + +Alakuijala & Szabadka Expires June 10, 2016 [Page 80] + +Internet-Draft Brotli December 2015 + + + 74686174456e67696e656572696e676120646966666572656e74726566657272 + 656420746f646966666572656e63657362656c696566207468617470686f746f + 6772617068736964656e74696679696e67486973746f7279206f662052657075 + 626c6963206f666e65636573736172696c7970726f626162696c697479746563 + 686e6963616c6c796c656176696e672074686573706563746163756c61726672 + 616374696f6e206f66656c65637472696369747968656164206f662074686572 + 657374617572616e7473706172746e657273686970656d706861736973206f6e + 6d6f737420726563656e747368617265207769746820736179696e6720746861 + 7466696c6c6564207769746864657369676e656420746f6974206973206f6674 + 656e223e3c2f696672616d653e617320666f6c6c6f77733a6d65726765642077 + 6974687468726f75676820746865636f6d6d65726369616c20706f696e746564 + 206f75746f70706f7274756e69747976696577206f6620746865726571756972 + 656d656e746469766973696f6e206f6670726f6772616d6d696e676865207265 + 636569766564736574496e74657276616c223e3c2f7370616e3e3c2f696e204e + 657720596f726b6164646974696f6e616c20636f6d7072657373696f6e0a0a3c + 6469762069643d22696e636f72706f726174653b3c2f7363726970743e3c6174 + 746163684576656e74626563616d65207468652022207461726765743d225f63 + 617272696564206f7574536f6d65206f6620746865736369656e636520616e64 + 7468652074696d65206f66436f6e7461696e6572223e6d61696e7461696e696e + 674368726973746f706865724d756368206f662074686577726974696e677320 + 6f6622206865696768743d223273697a65206f662074686576657273696f6e20 + 6f66206d697874757265206f66206265747765656e207468654578616d706c65 + 73206f66656475636174696f6e616c636f6d7065746974697665206f6e737562 + 6d69743d226469726563746f72206f6664697374696e63746976652f44544420 + 5848544d4c2072656c6174696e6720746f74656e64656e637920746f70726f76 + 696e6365206f66776869636820776f756c646465737069746520746865736369 + 656e7469666963206c656769736c61747572652e696e6e657248544d4c20616c + 6c65676174696f6e734167726963756c74757265776173207573656420696e61 + 7070726f61636820746f696e74656c6c6967656e747965617273206c61746572 + 2c73616e732d736572696664657465726d696e696e67506572666f726d616e63 + 65617070656172616e6365732c20776869636820697320666f756e646174696f + 6e736162627265766961746564686967686572207468616e732066726f6d2074 + 686520696e646976696475616c20636f6d706f736564206f66737570706f7365 + 6420746f636c61696d7320746861746174747269627574696f6e666f6e742d73 + 697a653a31656c656d656e7473206f66486973746f726963616c206869732062 + 726f746865726174207468652074696d65616e6e6976657273617279676f7665 + 726e656420627972656c6174656420746f20756c74696d6174656c7920696e6e + 6f766174696f6e736974206973207374696c6c63616e206f6e6c792062656465 + 66696e6974696f6e73746f474d54537472696e6741206e756d626572206f6669 + 6d6720636c6173733d224576656e7475616c6c792c776173206368616e676564 + 6f6363757272656420696e6e65696768626f72696e6764697374696e67756973 + 687768656e20686520776173696e74726f647563696e67746572726573747269 + 616c4d616e79206f66207468656172677565732074686174616e20416d657269 + 63616e636f6e7175657374206f66776964657370726561642077657265206b69 + 6c6c656473637265656e20616e6420496e206f7264657220746f657870656374 + 656420746f64657363656e64616e7473617265206c6f63617465646c65676973 + 6c617469766567656e65726174696f6e73206261636b67726f756e646d6f7374 + 2070656f706c6579656172732061667465727468657265206973206e6f746865 + + + +Alakuijala & Szabadka Expires June 10, 2016 [Page 81] + +Internet-Draft Brotli December 2015 + + + 20686967686573746672657175656e746c79207468657920646f206e6f746172 + 67756564207468617473686f7765642074686174707265646f6d696e616e7474 + 68656f6c6f676963616c6279207468652074696d65636f6e7369646572696e67 + 73686f72742d6c697665643c2f7370616e3e3c2f613e63616e20626520757365 + 6476657279206c6974746c656f6e65206f66207468652068616420616c726561 + 6479696e746572707265746564636f6d6d756e69636174656665617475726573 + 206f66676f7665726e6d656e742c3c2f6e6f7363726970743e656e7465726564 + 2074686522206865696768743d2233496e646570656e64656e74706f70756c61 + 74696f6e736c617267652d7363616c652e20416c74686f756768207573656420 + 696e207468656465737472756374696f6e706f73736962696c69747973746172 + 74696e6720696e74776f206f72206d6f726565787072657373696f6e73737562 + 6f7264696e6174656c6172676572207468616e686973746f727920616e643c2f + 6f7074696f6e3e0d0a436f6e74696e656e74616c656c696d696e6174696e6777 + 696c6c206e6f742062657072616374696365206f66696e2066726f6e74206f66 + 73697465206f6620746865656e737572652074686174746f2063726561746520 + 616d69737369737369707069706f74656e7469616c6c796f75747374616e6469 + 6e67626574746572207468616e77686174206973206e6f777369747561746564 + 20696e6d657461206e616d653d22547261646974696f6e616c73756767657374 + 696f6e735472616e736c6174696f6e74686520666f726d206f6661746d6f7370 + 68657269636964656f6c6f676963616c656e74657270726973657363616c6375 + 6c6174696e6765617374206f662074686572656d6e616e7473206f66706c7567 + 696e73706167652f696e6465782e7068703f72656d61696e656420696e747261 + 6e73666f726d656448652077617320616c736f77617320616c72656164797374 + 61746973746963616c696e206661766f72206f664d696e6973747279206f666d + 6f76656d656e74206f66666f726d756c6174696f6e6973207265717569726564 + 3c6c696e6b2072656c3d225468697320697320746865203c6120687265663d22 + 2f706f70756c6172697a6564696e766f6c76656420696e617265207573656420 + 746f616e64207365766572616c6d616465206279207468657365656d7320746f + 2062656c696b656c79207468617450616c657374696e69616e6e616d65642061 + 66746572697420686164206265656e6d6f737420636f6d6d6f6e746f20726566 + 657220746f6275742074686973206973636f6e736563757469766574656d706f + 726172696c79496e2067656e6572616c2c636f6e76656e74696f6e7374616b65 + 7320706c6163657375626469766973696f6e7465727269746f7269616c6f7065 + 726174696f6e616c7065726d616e656e746c79776173206c617267656c796f75 + 74627265616b206f66696e207468652070617374666f6c6c6f77696e67206120 + 786d6c6e733a6f673d223e3c6120636c6173733d22636c6173733d2274657874 + 436f6e76657273696f6e206d617920626520757365646d616e75666163747572 + 656166746572206265696e67636c656172666978223e0a7175657374696f6e20 + 6f6677617320656c6563746564746f206265636f6d6520616265636175736520 + 6f6620736f6d652070656f706c65696e73706972656420627973756363657373 + 66756c20612074696d65207768656e6d6f726520636f6d6d6f6e616d6f6e6773 + 7420746865616e206f6666696369616c77696474683a313030253b746563686e + 6f6c6f67792c7761732061646f70746564746f206b6565702074686573657474 + 6c656d656e74736c69766520626972746873696e6465782e68746d6c22436f6e + 6e6563746963757461737369676e656420746f26616d703b74696d65733b6163 + 636f756e7420666f72616c69676e3d726967687474686520636f6d70616e7961 + 6c77617973206265656e72657475726e656420746f696e766f6c76656d656e74 + 42656361757365207468657468697320706572696f6422206e616d653d227122 + + + +Alakuijala & Szabadka Expires June 10, 2016 [Page 82] + +Internet-Draft Brotli December 2015 + + + 20636f6e66696e656420746f6120726573756c74206f6676616c75653d222220 + 2f3e69732061637475616c6c79456e7669726f6e6d656e740d0a3c2f68656164 + 3e0d0a436f6e76657273656c792c3e0a3c6469762069643d2230222077696474 + 683d223169732070726f6261626c7968617665206265636f6d65636f6e74726f + 6c6c696e677468652070726f626c656d636974697a656e73206f66706f6c6974 + 696369616e7372656163686564207468656173206561726c792061733a6e6f6e + 653b206f7665723c7461626c652063656c6c76616c6964697479206f66646972 + 6563746c7920746f6f6e6d6f757365646f776e77686572652069742069737768 + 656e206974207761736d656d62657273206f662072656c6174696f6e20746f61 + 63636f6d6d6f64617465616c6f6e67207769746820496e20746865206c617465 + 74686520456e676c69736864656c6963696f7573223e74686973206973206e6f + 747468652070726573656e746966207468657920617265616e642066696e616c + 6c7961206d6174746572206f660d0a093c2f6469763e0d0a0d0a3c2f73637269 + 70743e666173746572207468616e6d616a6f72697479206f6661667465722077 + 68696368636f6d7061726174697665746f206d61696e7461696e696d70726f76 + 6520746865617761726465642074686565722220636c6173733d226672616d65 + 626f72646572726573746f726174696f6e696e207468652073616d65616e616c + 79736973206f667468656972206669727374447572696e672074686520636f6e + 74696e656e74616c73657175656e6365206f6666756e6374696f6e28297b666f + 6e742d73697a653a20776f726b206f6e207468653c2f7363726970743e0a3c62 + 6567696e7320776974686a6176617363726970743a636f6e7374697475656e74 + 77617320666f756e646564657175696c69627269756d617373756d6520746861 + 74697320676976656e2062796e6565647320746f206265636f6f7264696e6174 + 657374686520766172696f75736172652070617274206f666f6e6c7920696e20 + 74686573656374696f6e73206f666973206120636f6d6d6f6e7468656f726965 + 73206f66646973636f7665726965736173736f63696174696f6e65646765206f + 6620746865737472656e677468206f66706f736974696f6e20696e7072657365 + 6e742d646179756e6976657273616c6c79746f20666f726d2074686562757420 + 696e7374656164636f72706f726174696f6e617474616368656420746f697320 + 636f6d6d6f6e6c79726561736f6e7320666f72202671756f743b746865206361 + 6e206265206d6164657761732061626c6520746f7768696368206d65616e7362 + 757420646964206e6f746f6e4d6f7573654f766572617320706f737369626c65 + 6f70657261746564206279636f6d696e672066726f6d746865207072696d6172 + 796164646974696f6e206f66666f72207365766572616c7472616e7366657272 + 65646120706572696f64206f666172652061626c6520746f686f77657665722c + 20697473686f756c6420686176656d756368206c61726765720a093c2f736372 + 6970743e61646f707465642074686570726f7065727479206f66646972656374 + 65642062796566666563746976656c797761732062726f756768746368696c64 + 72656e206f6650726f6772616d6d696e676c6f6e676572207468616e6d616e75 + 7363726970747377617220616761696e73746279206d65616e73206f66616e64 + 206d6f7374206f6673696d696c617220746f2070726f70726965746172796f72 + 6967696e6174696e6770726573746967696f75736772616d6d61746963616c65 + 7870657269656e63652e746f206d616b652074686549742077617320616c736f + 697320666f756e6420696e636f6d70657469746f7273696e2074686520552e53 + 2e7265706c6163652074686562726f756768742074686563616c63756c617469 + 6f6e66616c6c206f66207468657468652067656e6572616c7072616374696361 + 6c6c79696e20686f6e6f72206f6672656c656173656420696e7265736964656e + 7469616c616e6420736f6d65206f666b696e67206f6620746865726561637469 + + + +Alakuijala & Szabadka Expires June 10, 2016 [Page 83] + +Internet-Draft Brotli December 2015 + + + 6f6e20746f317374204561726c206f6663756c7475726520616e647072696e63 + 6970616c6c793c2f7469746c653e0a2020746865792063616e2062656261636b + 20746f20746865736f6d65206f66206869736578706f7375726520746f617265 + 2073696d696c6172666f726d206f66207468656164644661766f726974656369 + 74697a656e736869707061727420696e2074686570656f706c65207769746869 + 6e207072616374696365746f20636f6e74696e756526616d703b6d696e75733b + 617070726f7665642062792074686520666972737420616c6c6f776564207468 + 65616e6420666f722074686566756e6374696f6e696e67706c6179696e672074 + 6865736f6c7574696f6e20746f6865696768743d22302220696e206869732062 + 6f6f6b6d6f7265207468616e2061666f6c6c6f77732074686563726561746564 + 2074686570726573656e636520696e266e6273703b3c2f74643e6e6174696f6e + 616c6973747468652069646561206f6661206368617261637465727765726520 + 666f7263656420636c6173733d2262746e64617973206f662074686566656174 + 7572656420696e73686f77696e6720746865696e74657265737420696e696e20 + 706c616365206f667475726e206f66207468657468652068656164206f664c6f + 7264206f6620746865706f6c69746963616c6c7968617320697473206f776e45 + 6475636174696f6e616c617070726f76616c206f66736f6d65206f6620746865 + 65616368206f746865722c6265686176696f72206f66616e6420626563617573 + 65616e6420616e6f746865726170706561726564206f6e7265636f7264656420 + 696e626c61636b2671756f743b6d617920696e636c75646574686520776f726c + 64277363616e206c65616420746f72656665727320746f2061626f726465723d + 22302220676f7665726e6d656e742077696e6e696e6720746865726573756c74 + 656420696e207768696c65207468652057617368696e67746f6e2c7468652073 + 75626a6563746369747920696e207468653e3c2f6469763e0d0a09097265666c + 65637420746865746f20636f6d706c657465626563616d65206d6f7265726164 + 696f61637469766572656a6563746564206279776974686f757420616e796869 + 73206661746865722c776869636820636f756c64636f7079206f662074686574 + 6f20696e6469636174656120706f6c69746963616c6163636f756e7473206f66 + 636f6e7374697475746573776f726b6564207769746865723c2f613e3c2f6c69 + 3e6f6620686973206c6966656163636f6d70616e696564636c69656e74576964 + 746870726576656e74207468654c656769736c6174697665646966666572656e + 746c79746f67657468657220696e686173207365766572616c666f7220616e6f + 7468657274657874206f6620746865666f756e64656420746865652077697468 + 20746865206973207573656420666f726368616e67656420746865757375616c + 6c7920746865706c61636520776865726577686572656173207468653e203c61 + 20687265663d22223e3c6120687265663d227468656d73656c7665732c616c74 + 686f756768206865746861742063616e206265747261646974696f6e616c726f + 6c65206f66207468656173206120726573756c7472656d6f76654368696c6464 + 657369676e656420627977657374206f6620746865536f6d652070656f706c65 + 70726f64756374696f6e2c73696465206f66207468656e6577736c6574746572 + 737573656420627920746865646f776e20746f20746865616363657074656420 + 62796c69766520696e20746865617474656d70747320746f6f75747369646520 + 7468656672657175656e63696573486f77657665722c20696e70726f6772616d + 6d6572736174206c6561737420696e617070726f78696d617465616c74686f75 + 67682069747761732070617274206f66616e6420766172696f7573476f766572 + 6e6f72206f667468652061727469636c657475726e656420696e746f3e3c6120 + 687265663d222f7468652065636f6e6f6d79697320746865206d6f73746d6f73 + 7420776964656c79776f756c64206c61746572616e6420706572686170737269 + + + +Alakuijala & Szabadka Expires June 10, 2016 [Page 84] + +Internet-Draft Brotli December 2015 + + + 736520746f207468656f6363757273207768656e756e64657220776869636863 + 6f6e646974696f6e732e746865207765737465726e7468656f72792074686174 + 69732070726f64756365647468652063697479206f66696e2077686963682068 + 657365656e20696e207468657468652063656e7472616c6275696c64696e6720 + 6f666d616e79206f662068697361726561206f6620746865697320746865206f + 6e6c796d6f7374206f66207468656d616e79206f662074686574686520576573 + 7465726e5468657265206973206e6f657874656e64656420746f537461746973 + 746963616c636f6c7370616e3d32207c73686f72742073746f7279706f737369 + 626c6520746f746f706f6c6f676963616c637269746963616c206f667265706f + 7274656420746f612043687269737469616e6465636973696f6e20746f697320 + 657175616c20746f70726f626c656d73206f66546869732063616e2062656d65 + 726368616e64697365666f72206d6f7374206f666e6f2065766964656e636565 + 646974696f6e73206f66656c656d656e747320696e2671756f743b2e20546865 + 636f6d2f696d616765732f7768696368206d616b65737468652070726f636573 + 7372656d61696e73207468656c6974657261747572652c69732061206d656d62 + 657274686520706f70756c617274686520616e6369656e7470726f626c656d73 + 20696e74696d65206f66207468656465666561746564206279626f6479206f66 + 2074686561206665772079656172736d756368206f662074686574686520776f + 726b206f6643616c69666f726e69612c7365727665642061732061676f766572 + 6e6d656e742e636f6e6365707473206f666d6f76656d656e7420696e09093c64 + 69762069643d226974222076616c75653d226c616e6775616765206f66617320 + 746865792061726570726f647563656420696e69732074686174207468656578 + 706c61696e207468656469763e3c2f6469763e0a486f7765766572207468656c + 65616420746f20746865093c6120687265663d222f776173206772616e746564 + 70656f706c652068617665636f6e74696e75616c6c79776173207365656e2061 + 73616e642072656c6174656474686520726f6c65206f6670726f706f73656420 + 62796f6620746865206265737465616368206f746865722e436f6e7374616e74 + 696e6570656f706c652066726f6d6469616c65637473206f66746f2072657669 + 73696f6e7761732072656e616d65646120736f75726365206f6674686520696e + 697469616c6c61756e6368656420696e70726f7669646520746865746f207468 + 6520776573747768657265207468657265616e642073696d696c617262657477 + 65656e2074776f697320616c736f20746865456e676c69736820616e64636f6e + 646974696f6e732c7468617420697420776173656e7469746c656420746f7468 + 656d73656c7665732e7175616e74697479206f6672616e73706172656e637974 + 68652073616d65206173746f206a6f696e20746865636f756e74727920616e64 + 746869732069732074686554686973206c656420746f612073746174656d656e + 74636f6e747261737420746f6c617374496e6465784f667468726f7567682068 + 697369732064657369676e6564746865207465726d20697369732070726f7669 + 64656470726f74656374207468656e673c2f613e3c2f6c693e54686520637572 + 72656e747468652073697465206f667375627374616e7469616c657870657269 + 656e63652c696e207468652057657374746865792073686f756c64736c6f7665 + 6ec48d696e61636f6d656e746172696f73756e697665727369646164636f6e64 + 6963696f6e65736163746976696461646573657870657269656e636961746563 + 6e6f6c6f67c3ad6170726f6475636369c3b36e70756e7475616369c3b36e6170 + 6c6963616369c3b36e636f6e7472617365c3b16163617465676f72c3ad617372 + 6567697374726172736570726f666573696f6e616c74726174616d69656e746f + 726567c3ad7374726174657365637265746172c3ad617072696e636970616c65 + 7370726f7465636369c3b36e696d706f7274616e746573696d706f7274616e63 + + + +Alakuijala & Szabadka Expires June 10, 2016 [Page 85] + +Internet-Draft Brotli December 2015 + + + 6961706f736962696c69646164696e7465726573616e746563726563696d6965 + 6e746f6e65636573696461646573737573637269626972736561736f63696163 + 69c3b36e646973706f6e69626c65736576616c75616369c3b36e657374756469 + 616e746573726573706f6e7361626c657265736f6c756369c3b36e6775616461 + 6c616a6172617265676973747261646f736f706f7274756e69646164636f6d65 + 726369616c6573666f746f67726166c3ad616175746f72696461646573696e67 + 656e696572c3ad6174656c6576697369c3b36e636f6d706574656e6369616f70 + 65726163696f6e657365737461626c656369646f73696d706c656d656e746561 + 637475616c6d656e74656e61766567616369c3b36e636f6e666f726d69646164 + 6c696e652d6865696768743a666f6e742d66616d696c793a22203a2022687474 + 703a2f2f6170706c69636174696f6e736c696e6b2220687265663d2273706563 + 69666963616c6c792f2f3c215b43444154415b0a4f7267616e697a6174696f6e + 646973747269627574696f6e3070783b206865696768743a72656c6174696f6e + 736869706465766963652d77696474683c64697620636c6173733d223c6c6162 + 656c20666f723d22726567697374726174696f6e3c2f6e6f7363726970743e0a + 2f696e6465782e68746d6c2277696e646f772e6f70656e282021696d706f7274 + 616e743b6170706c69636174696f6e2f696e646570656e64656e63652f2f7777 + 772e676f6f676c656f7267616e697a6174696f6e6175746f636f6d706c657465 + 726571756972656d656e7473636f6e7365727661746976653c666f726d206e61 + 6d653d22696e74656c6c65637475616c6d617267696e2d6c6566743a31387468 + 2063656e74757279616e20696d706f7274616e74696e737469747574696f6e73 + 616262726576696174696f6e3c696d6720636c6173733d226f7267616e697361 + 74696f6e636976696c697a6174696f6e313974682063656e7475727961726368 + 6974656374757265696e636f72706f7261746564323074682063656e74757279 + 2d636f6e7461696e6572223e6d6f7374206e6f7461626c792f3e3c2f613e3c2f + 6469763e6e6f74696669636174696f6e27756e646566696e6564272946757274 + 6865726d6f72652c62656c696576652074686174696e6e657248544d4c203d20 + 7072696f7220746f207468656472616d61746963616c6c79726566657272696e + 6720746f6e65676f74696174696f6e73686561647175617274657273536f7574 + 6820416672696361756e7375636365737366756c50656e6e73796c76616e6961 + 4173206120726573756c742c3c68746d6c206c616e673d22266c743b2f737570 + 2667743b6465616c696e6720776974687068696c6164656c7068696168697374 + 6f726963616c6c79293b3c2f7363726970743e0a70616464696e672d746f703a + 6578706572696d656e74616c676574417474726962757465696e737472756374 + 696f6e73746563686e6f6c6f6769657370617274206f6620746865203d66756e + 6374696f6e28297b737562736372697074696f6e6c2e647464223e0d0a3c6874 + 67656f67726170686963616c436f6e737469747574696f6e272c2066756e6374 + 696f6e28737570706f727465642062796167726963756c747572616c636f6e73 + 7472756374696f6e7075626c69636174696f6e73666f6e742d73697a653a2031 + 612076617269657479206f663c646976207374796c653d22456e6379636c6f70 + 65646961696672616d65207372633d2264656d6f6e737472617465646163636f + 6d706c6973686564756e6976657273697469657344656d6f6772617068696373 + 293b3c2f7363726970743e3c64656469636174656420746f6b6e6f776c656467 + 65206f66736174697366616374696f6e706172746963756c61726c793c2f6469 + 763e3c2f6469763e456e676c6973682028555329617070656e644368696c6428 + 7472616e736d697373696f6e732e20486f77657665722c20696e74656c6c6967 + 656e63652220746162696e6465783d22666c6f61743a72696768743b436f6d6d + 6f6e7765616c746872616e67696e672066726f6d696e20776869636820746865 + + + +Alakuijala & Szabadka Expires June 10, 2016 [Page 86] + +Internet-Draft Brotli December 2015 + + + 6174206c65617374206f6e65726570726f64756374696f6e656e6379636c6f70 + 656469613b666f6e742d73697a653a316a7572697364696374696f6e61742074 + 6861742074696d65223e3c6120636c6173733d22496e206164646974696f6e2c + 6465736372697074696f6e2b636f6e766572736174696f6e636f6e7461637420 + 7769746869732067656e6572616c6c79722220636f6e74656e743d2272657072 + 6573656e74696e67266c743b6d6174682667743b70726573656e746174696f6e + 6f63636173696f6e616c6c793c696d672077696474683d226e61766967617469 + 6f6e223e636f6d70656e736174696f6e6368616d70696f6e736869706d656469 + 613d22616c6c222076696f6c6174696f6e206f667265666572656e636520746f + 72657475726e20747275653b5374726963742f2f454e22207472616e73616374 + 696f6e73696e74657276656e74696f6e766572696669636174696f6e496e666f + 726d6174696f6e20646966666963756c746965734368616d70696f6e73686970 + 6361706162696c69746965733c215b656e6469665d2d2d3e7d0a3c2f73637269 + 70743e0a43687269737469616e697479666f72206578616d706c652c50726f66 + 657373696f6e616c7265737472696374696f6e73737567676573742074686174 + 7761732072656c656173656428737563682061732074686572656d6f7665436c + 61737328756e656d706c6f796d656e7474686520416d65726963616e73747275 + 6374757265206f662f696e6465782e68746d6c207075626c697368656420696e + 7370616e20636c6173733d22223e3c6120687265663d222f696e74726f647563 + 74696f6e62656c6f6e67696e6720746f636c61696d65642074686174636f6e73 + 657175656e6365733c6d657461206e616d653d22477569646520746f20746865 + 6f7665727768656c6d696e67616761696e73742074686520636f6e63656e7472 + 617465642c0a2e6e6f6e746f756368206f62736572766174696f6e733c2f613e + 0a3c2f6469763e0a662028646f63756d656e742e626f726465723a2031707820 + 7b666f6e742d73697a653a3174726561746d656e74206f663022206865696768 + 743d22316d6f64696669636174696f6e496e646570656e64656e636564697669 + 64656420696e746f67726561746572207468616e616368696576656d656e7473 + 65737461626c697368696e674a61766153637269707422206e65766572746865 + 6c6573737369676e69666963616e636542726f616463617374696e673e266e62 + 73703b3c2f74643e636f6e7461696e6572223e0a737563682061732074686520 + 696e666c75656e6365206f666120706172746963756c61727372633d27687474 + 703a2f2f6e617669676174696f6e222068616c66206f66207468652073756273 + 74616e7469616c20266e6273703b3c2f6469763e616476616e74616765206f66 + 646973636f76657279206f6666756e64616d656e74616c206d6574726f706f6c + 6974616e746865206f70706f736974652220786d6c3a6c616e673d2264656c69 + 6265726174656c79616c69676e3d63656e74657265766f6c7574696f6e206f66 + 707265736572766174696f6e696d70726f76656d656e7473626567696e6e696e + 6720696e4a65737573204368726973745075626c69636174696f6e7364697361 + 677265656d656e74746578742d616c69676e3a722c2066756e6374696f6e2829 + 73696d696c61726974696573626f64793e3c2f68746d6c3e6973206375727265 + 6e746c79616c7068616265746963616c697320736f6d6574696d657374797065 + 3d22696d6167652f6d616e79206f662074686520666c6f773a68696464656e3b + 617661696c61626c6520696e6465736372696265207468656578697374656e63 + 65206f66616c6c206f7665722074686574686520496e7465726e6574093c756c + 20636c6173733d22696e7374616c6c6174696f6e6e65696768626f72686f6f64 + 61726d656420666f726365737265647563696e6720746865636f6e74696e7565 + 7320746f4e6f6e657468656c6573732c74656d7065726174757265730a09093c + 6120687265663d22636c6f736520746f207468656578616d706c6573206f6620 + + + +Alakuijala & Szabadka Expires June 10, 2016 [Page 87] + +Internet-Draft Brotli December 2015 + + + 69732061626f757420746865287365652062656c6f77292e222069643d227365 + 6172636870726f66657373696f6e616c697320617661696c61626c6574686520 + 6f6666696369616c09093c2f7363726970743e0a0a09093c6469762069643d22 + 616363656c65726174696f6e7468726f756768207468652048616c6c206f6620 + 46616d656465736372697074696f6e737472616e736c6174696f6e73696e7465 + 72666572656e636520747970653d27746578742f726563656e74207965617273 + 696e2074686520776f726c647665727920706f70756c61727b6261636b67726f + 756e643a747261646974696f6e616c20736f6d65206f662074686520636f6e6e + 656374656420746f6578706c6f69746174696f6e656d657267656e6365206f66 + 636f6e737469747574696f6e4120486973746f7279206f667369676e69666963 + 616e74206d616e7566616374757265646578706563746174696f6e733e3c6e6f + 7363726970743e3c63616e20626520666f756e64626563617573652074686520 + 686173206e6f74206265656e6e65696768626f7572696e67776974686f757420 + 74686520616464656420746f20746865093c6c6920636c6173733d22696e7374 + 72756d656e74616c536f7669657420556e696f6e61636b6e6f776c6564676564 + 77686963682063616e2062656e616d6520666f7220746865617474656e74696f + 6e20746f617474656d70747320746f20646576656c6f706d656e7473496e2066 + 6163742c207468653c6c6920636c6173733d2261696d706c69636174696f6e73 + 7375697461626c6520666f726d756368206f662074686520636f6c6f6e697a61 + 74696f6e707265736964656e7469616c63616e63656c427562626c6520496e66 + 6f726d6174696f6e6d6f7374206f662074686520697320646573637269626564 + 72657374206f6620746865206d6f7265206f72206c657373696e205365707465 + 6d626572496e74656c6c6967656e63657372633d22687474703a2f2f70783b20 + 6865696768743a20617661696c61626c6520746f6d616e756661637475726572 + 68756d616e207269676874736c696e6b20687265663d222f617661696c616269 + 6c69747970726f706f7274696f6e616c6f757473696465207468652061737472 + 6f6e6f6d6963616c68756d616e206265696e67736e616d65206f662074686520 + 61726520666f756e6420696e617265206261736564206f6e736d616c6c657220 + 7468616e6120706572736f6e2077686f657870616e73696f6e206f6661726775 + 696e6720746861746e6f77206b6e6f776e206173496e20746865206561726c79 + 696e7465726d656469617465646572697665642066726f6d5363616e64696e61 + 7669616e3c2f613e3c2f6469763e0d0a636f6e736964657220746865616e2065 + 7374696d61746564746865204e6174696f6e616c3c6469762069643d22706167 + 726573756c74696e6720696e636f6d6d697373696f6e6564616e616c6f676f75 + 7320746f6172652072657175697265642f756c3e0a3c2f6469763e0a77617320 + 6261736564206f6e616e6420626563616d652061266e6273703b266e6273703b + 74222076616c75653d2222207761732063617074757265646e6f206d6f726520 + 7468616e726573706563746976656c79636f6e74696e756520746f203e0d0a3c + 686561643e0d0a3c7765726520637265617465646d6f72652067656e6572616c + 696e666f726d6174696f6e207573656420666f7220746865696e646570656e64 + 656e742074686520496d70657269616c636f6d706f6e656e74206f66746f2074 + 6865206e6f727468696e636c7564652074686520436f6e737472756374696f6e + 73696465206f662074686520776f756c64206e6f74206265666f7220696e7374 + 616e6365696e76656e74696f6e206f666d6f726520636f6d706c6578636f6c6c + 6563746976656c796261636b67726f756e643a20746578742d616c69676e3a20 + 697473206f726967696e616c696e746f206163636f756e74746869732070726f + 63657373616e20657874656e73697665686f77657665722c2074686574686579 + 20617265206e6f7472656a65637465642074686563726974696369736d206f66 + + + +Alakuijala & Szabadka Expires June 10, 2016 [Page 88] + +Internet-Draft Brotli December 2015 + + + 647572696e6720776869636870726f6261626c79207468657468697320617274 + 69636c652866756e6374696f6e28297b49742073686f756c64206265616e2061 + 677265656d656e746163636964656e74616c6c79646966666572732066726f6d + 417263686974656374757265626574746572206b6e6f776e617272616e67656d + 656e7473696e666c75656e6365206f6e617474656e646564207468656964656e + 746963616c20746f736f757468206f662074686570617373207468726f756768 + 786d6c22207469746c653d227765696768743a626f6c643b6372656174696e67 + 20746865646973706c61793a6e6f6e657265706c61636564207468653c696d67 + 207372633d222f6968747470733a2f2f7777772e576f726c6420576172204949 + 74657374696d6f6e69616c73666f756e6420696e207468657265717569726564 + 20746f20616e642074686174207468656265747765656e207468652077617320 + 64657369676e6564636f6e7369737473206f6620636f6e736964657261626c79 + 7075626c6973686564206279746865206c616e6775616765436f6e7365727661 + 74696f6e636f6e736973746564206f66726566657220746f207468656261636b + 20746f207468652063737322206d656469613d2250656f706c652066726f6d20 + 617661696c61626c65206f6e70726f76656420746f2062657375676765737469 + 6f6e7322776173206b6e6f776e206173766172696574696573206f666c696b65 + 6c7920746f206265636f6d707269736564206f66737570706f72742074686520 + 68616e6473206f6620746865636f75706c65642077697468636f6e6e65637420 + 616e6420626f726465723a6e6f6e653b706572666f726d616e6365736265666f + 7265206265696e676c6174657220626563616d6563616c63756c6174696f6e73 + 6f6674656e2063616c6c65647265736964656e7473206f666d65616e696e6720 + 746861743e3c6c6920636c6173733d2265766964656e636520666f726578706c + 616e6174696f6e73656e7669726f6e6d656e7473223e3c2f613e3c2f6469763e + 776869636820616c6c6f7773496e74726f64756374696f6e646576656c6f7065 + 642062796120776964652072616e67656f6e20626568616c66206f6676616c69 + 676e3d22746f70227072696e6369706c65206f666174207468652074696d652c + 3c2f6e6f7363726970743e0d7361696420746f2068617665696e207468652066 + 697273747768696c65206f74686572736879706f746865746963616c7068696c + 6f736f7068657273706f776572206f6620746865636f6e7461696e656420696e + 706572666f726d6564206279696e6162696c69747920746f7765726520777269 + 7474656e7370616e207374796c653d22696e707574206e616d653d2274686520 + 7175657374696f6e696e74656e64656420666f7272656a656374696f6e206f66 + 696d706c6965732074686174696e76656e74656420746865746865207374616e + 646172647761732070726f6261626c796c696e6b206265747765656e70726f66 + 6573736f72206f66696e746572616374696f6e736368616e67696e6720746865 + 496e6469616e204f6365616e20636c6173733d226c617374776f726b696e6720 + 7769746827687474703a2f2f7777772e7965617273206265666f726554686973 + 207761732074686572656372656174696f6e616c656e746572696e6720746865 + 6d6561737572656d656e7473616e2065787472656d656c7976616c7565206f66 + 207468657374617274206f66207468650a3c2f7363726970743e0a0a616e2065 + 66666f727420746f696e63726561736520746865746f2074686520736f757468 + 73706163696e673d2230223e73756666696369656e746c79746865204575726f + 7065616e636f6e76657274656420746f636c65617254696d656f757464696420 + 6e6f742068617665636f6e73657175656e746c79666f7220746865206e657874 + 657874656e73696f6e206f6665636f6e6f6d696320616e64616c74686f756768 + 207468656172652070726f6475636564616e64207769746820746865696e7375 + 6666696369656e74676976656e2062792074686573746174696e672074686174 + + + +Alakuijala & Szabadka Expires June 10, 2016 [Page 89] + +Internet-Draft Brotli December 2015 + + + 657870656e646974757265733c2f7370616e3e3c2f613e0a74686f7567687420 + 746861746f6e2074686520626173697363656c6c70616464696e673d696d6167 + 65206f662074686572657475726e696e6720746f696e666f726d6174696f6e2c + 736570617261746564206279617373617373696e61746564732220636f6e7465 + 6e743d22617574686f72697479206f666e6f7274687765737465726e3c2f6469 + 763e0a3c64697620223e3c2f6469763e0d0a2020636f6e73756c746174696f6e + 636f6d6d756e697479206f66746865206e6174696f6e616c69742073686f756c + 642062657061727469636970616e747320616c69676e3d226c65667474686520 + 677265617465737473656c656374696f6e206f6673757065726e61747572616c + 646570656e64656e74206f6e6973206d656e74696f6e6564616c6c6f77696e67 + 2074686577617320696e76656e7465646163636f6d70616e79696e6768697320 + 706572736f6e616c617661696c61626c652061747374756479206f6620746865 + 6f6e20746865206f74686572657865637574696f6e206f6648756d616e205269 + 676874737465726d73206f66207468656173736f63696174696f6e7372657365 + 6172636820616e64737563636565646564206279646566656174656420746865 + 616e642066726f6d20746865627574207468657920617265636f6d6d616e6465 + 72206f667374617465206f66207468657965617273206f662061676574686520 + 7374756479206f663c756c20636c6173733d2273706c61636520696e20746865 + 7768657265206865207761733c6c6920636c6173733d22667468657265206172 + 65206e6f776869636820626563616d656865207075626c697368656465787072 + 657373656420696e746f20776869636820746865636f6d6d697373696f6e6572 + 666f6e742d7765696768743a7465727269746f7279206f66657874656e73696f + 6e73223e526f6d616e20456d70697265657175616c20746f20746865496e2063 + 6f6e74726173742c686f77657665722c20616e646973207479706963616c6c79 + 616e6420686973207769666528616c736f2063616c6c65643e3c756c20636c61 + 73733d226566666563746976656c792065766f6c76656420696e746f7365656d + 20746f2068617665776869636820697320746865746865726520776173206e6f + 616e20657863656c6c656e74616c6c206f662074686573656465736372696265 + 64206279496e2070726163746963652c62726f616463617374696e6763686172 + 67656420776974687265666c656374656420696e7375626a656374656420746f + 6d696c697461727920616e64746f2074686520706f696e7465636f6e6f6d6963 + 616c6c79736574546172676574696e676172652061637475616c6c7976696374 + 6f7279206f76657228293b3c2f7363726970743e636f6e74696e756f75736c79 + 726571756972656420666f7265766f6c7574696f6e617279616e206566666563 + 746976656e6f727468206f66207468652c207768696368207761732066726f6e + 74206f66207468656f72206f7468657277697365736f6d6520666f726d206f66 + 686164206e6f74206265656e67656e657261746564206279696e666f726d6174 + 696f6e2e7065726d697474656420746f696e636c756465732074686564657665 + 6c6f706d656e742c656e746572656420696e746f7468652070726576696f7573 + 636f6e73697374656e746c79617265206b6e6f776e206173746865206669656c + 64206f66746869732074797065206f66676976656e20746f2074686574686520 + 7469746c65206f66636f6e7461696e7320746865696e7374616e636573206f66 + 696e20746865206e6f72746864756520746f2074686569726172652064657369 + 676e6564636f72706f726174696f6e737761732074686174207468656f6e6520 + 6f662074686573656d6f726520706f70756c617273756363656564656420696e + 737570706f72742066726f6d696e20646966666572656e74646f6d696e617465 + 6420627964657369676e656420666f726f776e657273686970206f66616e6420 + 706f737369626c797374616e64617264697a6564726573706f6e736554657874 + + + +Alakuijala & Szabadka Expires June 10, 2016 [Page 90] + +Internet-Draft Brotli December 2015 + + + 77617320696e74656e646564726563656976656420746865617373756d656420 + 746861746172656173206f66207468657072696d6172696c7920696e74686520 + 6261736973206f66696e207468652073656e73656163636f756e747320666f72 + 64657374726f7965642062796174206c656173742074776f776173206465636c + 61726564636f756c64206e6f74206265536563726574617279206f6661707065 + 617220746f2062656d617267696e2d746f703a312f5e5c732b7c5c732b242f67 + 65297b7468726f7720657d3b746865207374617274206f6674776f2073657061 + 726174656c616e677561676520616e6477686f20686164206265656e6f706572 + 6174696f6e206f666465617468206f66207468657265616c206e756d62657273 + 093c6c696e6b2072656c3d2270726f7669646564207468657468652073746f72 + 79206f66636f6d7065746974696f6e73656e676c6973682028554b29656e676c + 6973682028555329d09cd0bed0bdd0b3d0bed0bbd0a1d180d0bfd181d0bad0b8 + d181d180d0bfd181d0bad0b8d181d180d0bfd181d0bad0bed984d8b9d8b1d8a8 + d98ad8a9e6ada3e9ab94e4b8ade69687e7ae80e4bd93e4b8ade69687e7b981e4 + bd93e4b8ade69687e69c89e99990e585ace58fb8e4babae6b091e694bfe5ba9c + e998bfe9878ce5b7b4e5b7b4e7a4bee4bc9ae4b8bbe4b989e6938de4bd9ce7b3 + bbe7bb9fe694bfe7ad96e6b395e8a784696e666f726d616369c3b36e68657272 + 616d69656e746173656c65637472c3b36e69636f646573637269706369c3b36e + 636c61736966696361646f73636f6e6f63696d69656e746f7075626c69636163 + 69c3b36e72656c6163696f6e61646173696e666f726dc3a17469636172656c61 + 63696f6e61646f73646570617274616d656e746f74726162616a61646f726573 + 646972656374616d656e74656179756e74616d69656e746f6d65726361646f4c + 69627265636f6e74c3a16374656e6f7368616269746163696f6e657363756d70 + 6c696d69656e746f72657374617572616e746573646973706f73696369c3b36e + 636f6e73656375656e636961656c65637472c3b36e69636161706c6963616369 + 6f6e6573646573636f6e65637461646f696e7374616c616369c3b36e7265616c + 697a616369c3b36e7574696c697a616369c3b36e656e6369636c6f7065646961 + 656e6665726d656461646573696e737472756d656e746f73657870657269656e + 63696173696e73746974756369c3b36e706172746963756c6172657373756263 + 617465676f726961d182d0bed0bbd18cd0bad0bed0a0d0bed181d181d0b8d0b8 + d180d0b0d0b1d0bed182d18bd0b1d0bed0bbd18cd188d0b5d0bfd180d0bed181 + d182d0bed0bcd0bed0b6d0b5d182d0b5d0b4d180d183d0b3d0b8d185d181d0bb + d183d187d0b0d0b5d181d0b5d0b9d187d0b0d181d0b2d181d0b5d0b3d0b4d0b0 + d0a0d0bed181d181d0b8d18fd09cd0bed181d0bad0b2d0b5d0b4d180d183d0b3 + d0b8d0b5d0b3d0bed180d0bed0b4d0b0d0b2d0bed0bfd180d0bed181d0b4d0b0 + d0bdd0bdd18bd185d0b4d0bed0bbd0b6d0bdd18bd0b8d0bcd0b5d0bdd0bdd0be + d09cd0bed181d0bad0b2d18bd180d183d0b1d0bbd0b5d0b9d09cd0bed181d0ba + d0b2d0b0d181d182d180d0b0d0bdd18bd0bdd0b8d187d0b5d0b3d0bed180d0b0 + d0b1d0bed182d0b5d0b4d0bed0bbd0b6d0b5d0bdd183d181d0bbd183d0b3d0b8 + d182d0b5d0bfd0b5d180d18cd09ed0b4d0bdd0b0d0bad0bed0bfd0bed182d0be + d0bcd183d180d0b0d0b1d0bed182d183d0b0d0bfd180d0b5d0bbd18fd0b2d0be + d0bed0b1d189d0b5d0bed0b4d0bdd0bed0b3d0bed181d0b2d0bed0b5d0b3d0be + d181d182d0b0d182d18cd0b8d0b4d180d183d0b3d0bed0b9d184d0bed180d183 + d0bcd0b5d185d0bed180d0bed188d0bed0bfd180d0bed182d0b8d0b2d181d181 + d18bd0bbd0bad0b0d0bad0b0d0b6d0b4d18bd0b9d0b2d0bbd0b0d181d182d0b8 + d0b3d180d183d0bfd0bfd18bd0b2d0bcd0b5d181d182d0b5d180d0b0d0b1d0be + d182d0b0d181d0bad0b0d0b7d0b0d0bbd0bfd0b5d180d0b2d18bd0b9d0b4d0b5 + d0bbd0b0d182d18cd0b4d0b5d0bdd18cd0b3d0b8d0bfd0b5d180d0b8d0bed0b4 + + + +Alakuijala & Szabadka Expires June 10, 2016 [Page 91] + +Internet-Draft Brotli December 2015 + + + d0b1d0b8d0b7d0bdd0b5d181d0bed181d0bdd0bed0b2d0b5d0bcd0bed0bcd0b5 + d0bdd182d0bad183d0bfd0b8d182d18cd0b4d0bed0bbd0b6d0bdd0b0d180d0b0 + d0bcd0bad0b0d185d0bdd0b0d187d0b0d0bbd0bed0a0d0b0d0b1d0bed182d0b0 + d0a2d0bed0bbd18cd0bad0bed181d0bed0b2d181d0b5d0bcd0b2d182d0bed180 + d0bed0b9d0bdd0b0d187d0b0d0bbd0b0d181d0bfd0b8d181d0bed0bad181d0bb + d183d0b6d0b1d18bd181d0b8d181d182d0b5d0bcd0bfd0b5d187d0b0d182d0b8 + d0bdd0bed0b2d0bed0b3d0bed0bfd0bed0bcd0bed189d0b8d181d0b0d0b9d182 + d0bed0b2d0bfd0bed187d0b5d0bcd183d0bfd0bed0bcd0bed189d18cd0b4d0be + d0bbd0b6d0bdd0bed181d181d18bd0bbd0bad0b8d0b1d18bd181d182d180d0be + d0b4d0b0d0bdd0bdd18bd0b5d0bcd0bdd0bed0b3d0b8d0b5d0bfd180d0bed0b5 + d0bad182d0a1d0b5d0b9d187d0b0d181d0bcd0bed0b4d0b5d0bbd0b8d182d0b0 + d0bad0bed0b3d0bed0bed0bdd0bbd0b0d0b9d0bdd0b3d0bed180d0bed0b4d0b5 + d0b2d0b5d180d181d0b8d18fd181d182d180d0b0d0bdd0b5d184d0b8d0bbd18c + d0bcd18bd183d180d0bed0b2d0bdd18fd180d0b0d0b7d0bdd18bd185d0b8d181 + d0bad0b0d182d18cd0bdd0b5d0b4d0b5d0bbd18ed18fd0bdd0b2d0b0d180d18f + d0bcd0b5d0bdd18cd188d0b5d0bcd0bdd0bed0b3d0b8d185d0b4d0b0d0bdd0bd + d0bed0b9d0b7d0bdd0b0d187d0b8d182d0bdd0b5d0bbd18cd0b7d18fd184d0be + d180d183d0bcd0b0d0a2d0b5d0bfd0b5d180d18cd0bcd0b5d181d18fd186d0b0 + d0b7d0b0d189d0b8d182d18bd09bd183d187d188d0b8d0b5e0a4a8e0a4b9e0a5 + 80e0a482e0a495e0a4b0e0a4a8e0a587e0a485e0a4aae0a4a8e0a587e0a495e0 + a4bfe0a4afe0a4bee0a495e0a4b0e0a587e0a482e0a485e0a4a8e0a58de0a4af + e0a495e0a58de0a4afe0a4bee0a497e0a4bee0a487e0a4a1e0a4ace0a4bee0a4 + b0e0a587e0a495e0a4bfe0a4b8e0a580e0a4a6e0a4bfe0a4afe0a4bee0a4aae0 + a4b9e0a4b2e0a587e0a4b8e0a4bfe0a482e0a4b9e0a4ade0a4bee0a4b0e0a4a4 + e0a485e0a4aae0a4a8e0a580e0a4b5e0a4bee0a4b2e0a587e0a4b8e0a587e0a4 + b5e0a4bee0a495e0a4b0e0a4a4e0a587e0a4aee0a587e0a4b0e0a587e0a4b9e0 + a58be0a4a8e0a587e0a4b8e0a495e0a4a4e0a587e0a4ace0a4b9e0a581e0a4a4 + e0a4b8e0a4bee0a487e0a49fe0a4b9e0a58be0a497e0a4bee0a49ce0a4bee0a4 + a8e0a587e0a4aee0a4bfe0a4a8e0a49fe0a495e0a4b0e0a4a4e0a4bee0a495e0 + a4b0e0a4a8e0a4bee0a489e0a4a8e0a495e0a587e0a4afe0a4b9e0a4bee0a481 + e0a4b8e0a4ace0a4b8e0a587e0a4ade0a4bee0a4b7e0a4bee0a486e0a4aae0a4 + 95e0a587e0a4b2e0a4bfe0a4afe0a587e0a4b6e0a581e0a4b0e0a582e0a487e0 + a4b8e0a495e0a587e0a498e0a482e0a49fe0a587e0a4aee0a587e0a4b0e0a580 + e0a4b8e0a495e0a4a4e0a4bee0a4aee0a587e0a4b0e0a4bee0a4b2e0a587e0a4 + 95e0a4b0e0a485e0a4a7e0a4bfe0a495e0a485e0a4aae0a4a8e0a4bee0a4b8e0 + a4aee0a4bee0a49ce0a4aee0a581e0a49de0a587e0a495e0a4bee0a4b0e0a4a3 + e0a4b9e0a58be0a4a4e0a4bee0a495e0a4a1e0a4bce0a580e0a4afe0a4b9e0a4 + bee0a482e0a4b9e0a58be0a49fe0a4b2e0a4b6e0a4ace0a58de0a4a6e0a4b2e0 + a4bfe0a4afe0a4bee0a49ce0a580e0a4b5e0a4a8e0a49ce0a4bee0a4a4e0a4be + e0a495e0a588e0a4b8e0a587e0a486e0a4aae0a495e0a4bee0a4b5e0a4bee0a4 + b2e0a580e0a4a6e0a587e0a4a8e0a587e0a4aae0a582e0a4b0e0a580e0a4aae0 + a4bee0a4a8e0a580e0a489e0a4b8e0a495e0a587e0a4b9e0a58be0a497e0a580 + e0a4ace0a588e0a4a0e0a495e0a486e0a4aae0a495e0a580e0a4b5e0a4b0e0a5 + 8de0a4b7e0a497e0a4bee0a482e0a4b5e0a486e0a4aae0a495e0a58be0a49ce0 + a4bfe0a4b2e0a4bee0a49ce0a4bee0a4a8e0a4bee0a4b8e0a4b9e0a4aee0a4a4 + e0a4b9e0a4aee0a587e0a482e0a489e0a4a8e0a495e0a580e0a4afe0a4bee0a4 + b9e0a582e0a4a6e0a4b0e0a58de0a49ce0a4b8e0a582e0a49ae0a580e0a4aae0 + a4b8e0a482e0a4a6e0a4b8e0a4b5e0a4bee0a4b2e0a4b9e0a58be0a4a8e0a4be + + + +Alakuijala & Szabadka Expires June 10, 2016 [Page 92] + +Internet-Draft Brotli December 2015 + + + e0a4b9e0a58be0a4a4e0a580e0a49ce0a588e0a4b8e0a587e0a4b5e0a4bee0a4 + aae0a4b8e0a49ce0a4a8e0a4a4e0a4bee0a4a8e0a587e0a4a4e0a4bee0a49ce0 + a4bee0a4b0e0a580e0a498e0a4bee0a4afe0a4b2e0a49ce0a4bfe0a4b2e0a587 + e0a4a8e0a580e0a49ae0a587e0a49ce0a4bee0a482e0a49ae0a4aae0a4a4e0a5 + 8de0a4b0e0a497e0a582e0a497e0a4b2e0a49ce0a4bee0a4a4e0a587e0a4ace0 + a4bee0a4b9e0a4b0e0a486e0a4aae0a4a8e0a587e0a4b5e0a4bee0a4b9e0a4a8 + e0a487e0a4b8e0a495e0a4bee0a4b8e0a581e0a4ace0a4b9e0a4b0e0a4b9e0a4 + a8e0a587e0a487e0a4b8e0a4b8e0a587e0a4b8e0a4b9e0a4bfe0a4a4e0a4ace0 + a4a1e0a4bce0a587e0a498e0a49fe0a4a8e0a4bee0a4a4e0a4b2e0a4bee0a4b6 + e0a4aae0a4bee0a482e0a49ae0a4b6e0a58de0a4b0e0a580e0a4ace0a4a1e0a4 + bce0a580e0a4b9e0a58be0a4a4e0a587e0a4b8e0a4bee0a488e0a49fe0a4b6e0 + a4bee0a4afe0a4a6e0a4b8e0a495e0a4a4e0a580e0a49ce0a4bee0a4a4e0a580 + e0a4b5e0a4bee0a4b2e0a4bee0a4b9e0a49ce0a4bee0a4b0e0a4aae0a49fe0a4 + a8e0a4bee0a4b0e0a496e0a4a8e0a587e0a4b8e0a4a1e0a4bce0a495e0a4aee0 + a4bfe0a4b2e0a4bee0a489e0a4b8e0a495e0a580e0a495e0a587e0a4b5e0a4b2 + e0a4b2e0a497e0a4a4e0a4bee0a496e0a4bee0a4a8e0a4bee0a485e0a4b0e0a5 + 8de0a4a5e0a49ce0a4b9e0a4bee0a482e0a4a6e0a587e0a496e0a4bee0a4aae0 + a4b9e0a4b2e0a580e0a4a8e0a4bfe0a4afe0a4aee0a4ace0a4bfe0a4a8e0a4be + e0a4ace0a588e0a482e0a495e0a495e0a4b9e0a580e0a482e0a495e0a4b9e0a4 + a8e0a4bee0a4a6e0a587e0a4a4e0a4bee0a4b9e0a4aee0a4b2e0a587e0a495e0 + a4bee0a4abe0a580e0a49ce0a4ace0a495e0a4bfe0a4a4e0a581e0a4b0e0a4a4 + e0a4aee0a4bee0a482e0a497e0a4b5e0a4b9e0a580e0a482e0a4b0e0a58be0a4 + 9ce0a4bce0a4aee0a4bfe0a4b2e0a580e0a486e0a4b0e0a58be0a4aae0a4b8e0 + a587e0a4a8e0a4bee0a4afe0a4bee0a4a6e0a4b5e0a4b2e0a587e0a4a8e0a587 + e0a496e0a4bee0a4a4e0a4bee0a495e0a4b0e0a580e0a4ace0a489e0a4a8e0a4 + 95e0a4bee0a49ce0a4b5e0a4bee0a4ace0a4aae0a582e0a4b0e0a4bee0a4ace0 + a4a1e0a4bce0a4bee0a4b8e0a58ce0a4a6e0a4bee0a4b6e0a587e0a4afe0a4b0 + e0a495e0a4bfe0a4afe0a587e0a495e0a4b9e0a4bee0a482e0a485e0a495e0a4 + b8e0a4b0e0a4ace0a4a8e0a4bee0a48fe0a4b5e0a4b9e0a4bee0a482e0a4b8e0 + a58de0a4a5e0a4b2e0a4aee0a4bfe0a4b2e0a587e0a4b2e0a587e0a496e0a495 + e0a4b5e0a4bfe0a4b7e0a4afe0a495e0a58de0a4b0e0a482e0a4b8e0a4aee0a5 + 82e0a4b9e0a4a5e0a4bee0a4a8e0a4bed8aad8b3d8aad8b7d98ad8b9d985d8b4 + d8a7d8b1d983d8a9d8a8d988d8a7d8b3d8b7d8a9d8a7d984d8b5d981d8add8a9 + d985d988d8a7d8b6d98ad8b9d8a7d984d8aed8a7d8b5d8a9d8a7d984d985d8b2 + d98ad8afd8a7d984d8b9d8a7d985d8a9d8a7d984d983d8a7d8aad8a8d8a7d984 + d8b1d8afd988d8afd8a8d8b1d986d8a7d985d8acd8a7d984d8afd988d984d8a9 + d8a7d984d8b9d8a7d984d985d8a7d984d985d988d982d8b9d8a7d984d8b9d8b1 + d8a8d98ad8a7d984d8b3d8b1d98ad8b9d8a7d984d8acd988d8a7d984d8a7d984 + d8b0d987d8a7d8a8d8a7d984d8add98ad8a7d8a9d8a7d984d8add982d988d982 + d8a7d984d983d8b1d98ad985d8a7d984d8b9d8b1d8a7d982d985d8add981d988 + d8b8d8a9d8a7d984d8abd8a7d986d98ad985d8b4d8a7d987d8afd8a9d8a7d984 + d985d8b1d8a3d8a9d8a7d984d982d8b1d8a2d986d8a7d984d8b4d8a8d8a7d8a8 + d8a7d984d8add988d8a7d8b1d8a7d984d8acd8afd98ad8afd8a7d984d8a3d8b3 + d8b1d8a9d8a7d984d8b9d984d988d985d985d8acd985d988d8b9d8a9d8a7d984 + d8b1d8add985d986d8a7d984d986d982d8a7d8b7d981d984d8b3d8b7d98ad986 + d8a7d984d983d988d98ad8aad8a7d984d8afd986d98ad8a7d8a8d8b1d983d8a7 + d8aad987d8a7d984d8b1d98ad8a7d8b6d8aad8add98ad8a7d8aad98ad8a8d8aa + d988d982d98ad8aad8a7d984d8a3d988d984d989d8a7d984d8a8d8b1d98ad8af + + + +Alakuijala & Szabadka Expires June 10, 2016 [Page 93] + +Internet-Draft Brotli December 2015 + + + d8a7d984d983d984d8a7d985d8a7d984d8b1d8a7d8a8d8b7d8a7d984d8b4d8ae + d8b5d98ad8b3d98ad8a7d8b1d8a7d8aad8a7d984d8abd8a7d984d8abd8a7d984 + d8b5d984d8a7d8a9d8a7d984d8add8afd98ad8abd8a7d984d8b2d988d8a7d8b1 + d8a7d984d8aed984d98ad8acd8a7d984d8acd985d98ad8b9d8a7d984d8b9d8a7 + d985d987d8a7d984d8acd985d8a7d984d8a7d984d8b3d8a7d8b9d8a9d985d8b4 + d8a7d987d8afd987d8a7d984d8b1d8a6d98ad8b3d8a7d984d8afd8aed988d984 + d8a7d984d981d986d98ad8a9d8a7d984d983d8aad8a7d8a8d8a7d984d8afd988 + d8b1d98ad8a7d984d8afd8b1d988d8b3d8a7d8b3d8aad8bad8b1d982d8aad8b5 + d8a7d985d98ad985d8a7d984d8a8d986d8a7d8aad8a7d984d8b9d8b8d98ad985 + 656e7465727461696e6d656e74756e6465727374616e64696e67203d2066756e + 6374696f6e28292e6a7067222077696474683d22636f6e66696775726174696f + 6e2e706e67222077696474683d223c626f647920636c6173733d224d6174682e + 72616e646f6d2829636f6e74656d706f7261727920556e697465642053746174 + 657363697263756d7374616e6365732e617070656e644368696c64286f726761 + 6e697a6174696f6e733c7370616e20636c6173733d22223e3c696d6720737263 + 3d222f64697374696e6775697368656474686f7573616e6473206f6620636f6d + 6d756e69636174696f6e636c656172223e3c2f6469763e696e76657374696761 + 74696f6e66617669636f6e2e69636f22206d617267696e2d72696768743a6261 + 736564206f6e20746865204d6173736163687573657474737461626c6520626f + 726465723d696e7465726e6174696f6e616c616c736f206b6e6f776e20617370 + 726f6e756e63696174696f6e6261636b67726f756e643a236670616464696e67 + 2d6c6566743a466f72206578616d706c652c206d697363656c6c616e656f7573 + 266c743b2f6d6174682667743b70737963686f6c6f676963616c696e20706172 + 746963756c617265617263682220747970653d22666f726d206d6574686f643d + 226173206f70706f73656420746f53757072656d6520436f7572746f63636173 + 696f6e616c6c79204164646974696f6e616c6c792c4e6f72746820416d657269 + 636170783b6261636b67726f756e646f70706f7274756e6974696573456e7465 + 727461696e6d656e742e746f4c6f77657243617365286d616e75666163747572 + 696e6770726f66657373696f6e616c20636f6d62696e65642077697468466f72 + 20696e7374616e63652c636f6e73697374696e67206f6622206d61786c656e67 + 74683d2272657475726e2066616c73653b636f6e7363696f75736e6573734d65 + 646974657272616e65616e65787472616f7264696e617279617373617373696e + 6174696f6e73756273657175656e746c7920627574746f6e20747970653d2274 + 6865206e756d626572206f66746865206f726967696e616c20636f6d70726568 + 656e7369766572656665727320746f207468653c2f756c3e0a3c2f6469763e0a + 7068696c6f736f70686963616c6c6f636174696f6e2e68726566776173207075 + 626c697368656453616e204672616e636973636f2866756e6374696f6e28297b + 0a3c6469762069643d226d61696e736f70686973746963617465646d61746865 + 6d61746963616c202f686561643e0d0a3c626f64797375676765737473207468 + 6174646f63756d656e746174696f6e636f6e63656e74726174696f6e72656c61 + 74696f6e73686970736d61792068617665206265656e28666f72206578616d70 + 6c652c546869732061727469636c6520696e20736f6d65206361736573706172 + 7473206f662074686520646566696e6974696f6e206f66477265617420427269 + 7461696e2063656c6c70616464696e673d6571756976616c656e7420746f706c + 616365686f6c6465723d223b20666f6e742d73697a653a206a75737469666963 + 6174696f6e62656c6965766564207468617473756666657265642066726f6d61 + 7474656d7074656420746f206c6561646572206f662074686563726970742220 + 7372633d222f2866756e6374696f6e2829207b61726520617661696c61626c65 + + + +Alakuijala & Szabadka Expires June 10, 2016 [Page 94] + +Internet-Draft Brotli December 2015 + + + 0a093c6c696e6b2072656c3d22207372633d27687474703a2f2f696e74657265 + 7374656420696e636f6e76656e74696f6e616c202220616c743d2222202f3e3c + 2f6172652067656e6572616c6c7968617320616c736f206265656e6d6f737420 + 706f70756c617220636f72726573706f6e64696e676372656469746564207769 + 746874796c653d22626f726465723a3c2f613e3c2f7370616e3e3c2f2e676966 + 222077696474683d223c696672616d65207372633d227461626c6520636c6173 + 733d22696e6c696e652d626c6f636b3b6163636f7264696e6720746f20746f67 + 65746865722077697468617070726f78696d6174656c797061726c69616d656e + 746172796d6f726520616e64206d6f7265646973706c61793a6e6f6e653b7472 + 61646974696f6e616c6c79707265646f6d696e616e746c79266e6273703b7c26 + 6e6273703b266e6273703b3c2f7370616e3e2063656c6c73706163696e673d3c + 696e707574206e616d653d226f722220636f6e74656e743d22636f6e74726f76 + 65727369616c70726f70657274793d226f673a2f782d73686f636b776176652d + 64656d6f6e7374726174696f6e737572726f756e6465642062794e6576657274 + 68656c6573732c77617320746865206669727374636f6e736964657261626c65 + 20416c74686f7567682074686520636f6c6c61626f726174696f6e73686f756c + 64206e6f7420626570726f706f7274696f6e206f663c7370616e207374796c65 + 3d226b6e6f776e206173207468652073686f72746c79206166746572666f7220 + 696e7374616e63652c646573637269626564206173202f686561643e0a3c626f + 6479207374617274696e672077697468696e6372656173696e676c7920746865 + 2066616374207468617464697363757373696f6e206f666d6964646c65206f66 + 20746865616e20696e646976696475616c646966666963756c7420746f20706f + 696e74206f662076696577686f6d6f73657875616c697479616363657074616e + 6365206f663c2f7370616e3e3c2f6469763e6d616e756661637475726572736f + 726967696e206f6620746865636f6d6d6f6e6c792075736564696d706f727461 + 6e6365206f6664656e6f6d696e6174696f6e736261636b67726f756e643a2023 + 6c656e677468206f662074686564657465726d696e6174696f6e61207369676e + 69666963616e742220626f726465723d2230223e7265766f6c7574696f6e6172 + 797072696e6369706c6573206f66697320636f6e736964657265647761732064 + 6576656c6f706564496e646f2d4575726f7065616e76756c6e657261626c6520 + 746f70726f706f6e656e7473206f6661726520736f6d6574696d6573636c6f73 + 657220746f207468654e657720596f726b2043697479206e616d653d22736561 + 7263686174747269627574656420746f636f75727365206f66207468656d6174 + 68656d6174696369616e62792074686520656e64206f6661742074686520656e + 64206f662220626f726465723d22302220746563686e6f6c6f676963616c2e72 + 656d6f7665436c617373286272616e6368206f662074686565766964656e6365 + 2074686174215b656e6469665d2d2d3e0d0a496e73746974757465206f662069 + 6e746f20612073696e676c65726573706563746976656c792e616e6420746865 + 7265666f726570726f70657274696573206f666973206c6f636174656420696e + 736f6d65206f66207768696368546865726520697320616c736f636f6e74696e + 75656420746f20617070656172616e6365206f662026616d703b6e646173683b + 2064657363726962657320746865636f6e73696465726174696f6e617574686f + 72206f6620746865696e646570656e64656e746c796571756970706564207769 + 7468646f6573206e6f7420686176653c2f613e3c6120687265663d22636f6e66 + 7573656420776974683c6c696e6b20687265663d222f61742074686520616765 + 206f6661707065617220696e20746865546865736520696e636c756465726567 + 6172646c657373206f66636f756c642062652075736564207374796c653d2671 + 756f743b7365766572616c2074696d6573726570726573656e7420746865626f + + + +Alakuijala & Szabadka Expires June 10, 2016 [Page 95] + +Internet-Draft Brotli December 2015 + + + 64793e0a3c2f68746d6c3e74686f7567687420746f206265706f70756c617469 + 6f6e206f66706f73736962696c697469657370657263656e74616765206f6661 + 636365737320746f20746865616e20617474656d707420746f70726f64756374 + 696f6e206f666a71756572792f6a717565727974776f20646966666572656e74 + 62656c6f6e6720746f2074686565737461626c6973686d656e747265706c6163 + 696e67207468656465736372697074696f6e222064657465726d696e65207468 + 65617661696c61626c6520666f724163636f7264696e6720746f207769646520 + 72616e6765206f66093c64697620636c6173733d226d6f726520636f6d6d6f6e + 6c796f7267616e69736174696f6e7366756e6374696f6e616c69747977617320 + 636f6d706c657465642026616d703b6d646173683b2070617274696369706174 + 696f6e74686520636861726163746572616e206164646974696f6e616c617070 + 6561727320746f20626566616374207468617420746865616e206578616d706c + 65206f667369676e69666963616e746c796f6e6d6f7573656f7665723d226265 + 63617573652074686579206173796e63203d20747275653b70726f626c656d73 + 20776974687365656d7320746f206861766574686520726573756c74206f6620 + 7372633d22687474703a2f2f66616d696c6961722077697468706f7373657373 + 696f6e206f6666756e6374696f6e202829207b746f6f6b20706c61636520696e + 616e6420736f6d6574696d65737375627374616e7469616c6c793c7370616e3e + 3c2f7370616e3e6973206f6674656e2075736564696e20616e20617474656d70 + 746772656174206465616c206f66456e7669726f6e6d656e74616c7375636365 + 737366756c6c79207669727475616c6c7920616c6c323074682063656e747572 + 792c70726f66657373696f6e616c736e656365737361727920746f2064657465 + 726d696e6564206279636f6d7061746962696c69747962656361757365206974 + 20697344696374696f6e617279206f666d6f64696669636174696f6e73546865 + 20666f6c6c6f77696e676d617920726566657220746f3a436f6e73657175656e + 746c792c496e7465726e6174696f6e616c616c74686f75676820736f6d657468 + 617420776f756c64206265776f726c642773206669727374636c617373696669 + 6564206173626f74746f6d206f662074686528706172746963756c61726c7961 + 6c69676e3d226c65667422206d6f737420636f6d6d6f6e6c7962617369732066 + 6f7220746865666f756e646174696f6e206f66636f6e747269627574696f6e73 + 706f70756c6172697479206f6663656e746572206f6620746865746f20726564 + 756365207468656a7572697364696374696f6e73617070726f78696d6174696f + 6e206f6e6d6f7573656f75743d224e65772054657374616d656e74636f6c6c65 + 6374696f6e206f663c2f7370616e3e3c2f613e3c2f696e2074686520556e6974 + 656466696c6d206469726563746f722d7374726963742e647464223e68617320 + 6265656e207573656472657475726e20746f20746865616c74686f7567682074 + 6869736368616e676520696e207468657365766572616c206f74686572627574 + 20746865726520617265756e707265636564656e74656469732073696d696c61 + 7220746f657370656369616c6c7920696e7765696768743a20626f6c643b6973 + 2063616c6c656420746865636f6d7075746174696f6e616c696e646963617465 + 20746861747265737472696374656420746f093c6d657461206e616d653d2261 + 7265207479706963616c6c79636f6e666c6963742077697468486f7765766572 + 2c2074686520416e206578616d706c65206f66636f6d70617265642077697468 + 7175616e746974696573206f66726174686572207468616e2061636f6e737465 + 6c6c6174696f6e6e656365737361727920666f727265706f7274656420746861 + 7473706563696669636174696f6e706f6c69746963616c20616e64266e627370 + 3b266e6273703b3c7265666572656e63657320746f7468652073616d65207965 + 6172476f7665726e6d656e74206f6667656e65726174696f6e206f6668617665 + + + +Alakuijala & Szabadka Expires June 10, 2016 [Page 96] + +Internet-Draft Brotli December 2015 + + + 206e6f74206265656e7365766572616c207965617273636f6d6d69746d656e74 + 20746f09093c756c20636c6173733d2276697375616c697a6174696f6e313974 + 682063656e747572792c70726163746974696f6e657273746861742068652077 + 6f756c64616e6420636f6e74696e7565646f636375706174696f6e206f666973 + 20646566696e656420617363656e747265206f662074686574686520616d6f75 + 6e74206f663e3c646976207374796c653d226571756976616c656e74206f6664 + 6966666572656e746961746562726f756768742061626f75746d617267696e2d + 6c6566743a206175746f6d61746963616c6c7974686f75676874206f66206173 + 536f6d65206f662074686573650a3c64697620636c6173733d22696e70757420 + 636c6173733d227265706c6163656420776974686973206f6e65206f66207468 + 65656475636174696f6e20616e64696e666c75656e6365642062797265707574 + 6174696f6e2061730a3c6d657461206e616d653d226163636f6d6d6f64617469 + 6f6e3c2f6469763e0a3c2f6469763e6c617267652070617274206f66496e7374 + 697475746520666f7274686520736f2d63616c6c656420616761696e73742074 + 686520496e207468697320636173652c776173206170706f696e746564636c61 + 696d656420746f206265486f77657665722c20746869734465706172746d656e + 74206f667468652072656d61696e696e67656666656374206f6e207468657061 + 72746963756c61726c79206465616c2077697468207468650a3c646976207374 + 796c653d22616c6d6f737420616c776179736172652063757272656e746c7965 + 787072657373696f6e206f667068696c6f736f706879206f66666f72206d6f72 + 65207468616e636976696c697a6174696f6e736f6e207468652069736c616e64 + 73656c6563746564496e64657863616e20726573756c7420696e222076616c75 + 653d2222202f3e74686520737472756374757265202f3e3c2f613e3c2f646976 + 3e4d616e79206f66207468657365636175736564206279207468656f66207468 + 6520556e697465647370616e20636c6173733d226d63616e2062652074726163 + 656469732072656c6174656420746f626563616d65206f6e65206f6669732066 + 72657175656e746c796c6976696e6720696e207468657468656f726574696361 + 6c6c79466f6c6c6f77696e67207468655265766f6c7574696f6e617279676f76 + 65726e6d656e7420696e69732064657465726d696e656474686520706f6c6974 + 6963616c696e74726f647563656420696e73756666696369656e7420746f6465 + 736372697074696f6e223e73686f72742073746f726965737365706172617469 + 6f6e206f66617320746f20776865746865726b6e6f776e20666f722069747377 + 617320696e697469616c6c79646973706c61793a626c6f636b697320616e2065 + 78616d706c65746865207072696e636970616c636f6e7369737473206f662061 + 7265636f676e697a65642061732f626f64793e3c2f68746d6c3e612073756273 + 74616e7469616c7265636f6e737472756374656468656164206f662073746174 + 65726573697374616e636520746f756e64657267726164756174655468657265 + 206172652074776f6772617669746174696f6e616c6172652064657363726962 + 6564696e74656e74696f6e616c6c7973657276656420617320746865636c6173 + 733d226865616465726f70706f736974696f6e20746f66756e64616d656e7461 + 6c6c79646f6d696e6174656420746865616e6420746865206f74686572616c6c + 69616e6365207769746877617320666f7263656420746f726573706563746976 + 656c792c616e6420706f6c69746963616c696e20737570706f7274206f667065 + 6f706c6520696e20746865323074682063656e747572792e616e64207075626c + 69736865646c6f6164436861727462656174746f20756e6465727374616e646d + 656d62657220737461746573656e7669726f6e6d656e74616c66697273742068 + 616c66206f66636f756e747269657320616e646172636869746563747572616c + 626520636f6e73696465726564636861726163746572697a6564636c65617249 + + + +Alakuijala & Szabadka Expires June 10, 2016 [Page 97] + +Internet-Draft Brotli December 2015 + + + 6e74657276616c617574686f726974617469766546656465726174696f6e206f + 6677617320737563636565646564616e64207468657265206172656120636f6e + 73657175656e636574686520507265736964656e74616c736f20696e636c7564 + 65646672656520736f66747761726573756363657373696f6e206f6664657665 + 6c6f706564207468657761732064657374726f796564617761792066726f6d20 + 7468653b0a3c2f7363726970743e0a3c616c74686f7567682074686579666f6c + 6c6f77656420627920616d6f726520706f77657266756c726573756c74656420 + 696e2061556e6976657273697479206f66486f77657665722c206d616e797468 + 6520707265736964656e74486f77657665722c20736f6d6569732074686f7567 + 687420746f756e74696c2074686520656e6477617320616e6e6f756e63656461 + 726520696d706f7274616e74616c736f20696e636c756465733e3c696e707574 + 20747970653d7468652063656e746572206f6620444f204e4f5420414c544552 + 7573656420746f2072656665727468656d65732f3f736f72743d746861742068 + 6164206265656e74686520626173697320666f7268617320646576656c6f7065 + 64696e207468652073756d6d6572636f6d70617261746976656c796465736372 + 6962656420746865737563682061732074686f736574686520726573756c7469 + 6e67697320696d706f737369626c65766172696f7573206f74686572536f7574 + 68204166726963616e68617665207468652073616d656566666563746976656e + 657373696e20776869636820636173653b20746578742d616c69676e3a737472 + 75637475726520616e643b206261636b67726f756e643a726567617264696e67 + 20746865737570706f7274656420746865697320616c736f206b6e6f776e7374 + 796c653d226d617267696e696e636c7564696e6720746865626168617361204d + 656c6179756e6f72736b20626f6b6dc3a56c6e6f72736b206e796e6f72736b73 + 6c6f76656ec5a1c48d696e61696e7465726e6163696f6e616c63616c69666963 + 616369c3b36e636f6d756e6963616369c3b36e636f6e73747275636369c3b36e + 223e3c64697620636c6173733d22646973616d626967756174696f6e446f6d61 + 696e4e616d65272c202761646d696e697374726174696f6e73696d756c74616e + 656f75736c797472616e73706f72746174696f6e496e7465726e6174696f6e61 + 6c206d617267696e2d626f74746f6d3a726573706f6e736962696c6974793c21 + 5b656e6469665d2d2d3e0a3c2f3e3c6d657461206e616d653d22696d706c656d + 656e746174696f6e696e667261737472756374757265726570726573656e7461 + 74696f6e626f726465722d626f74746f6d3a3c2f686561643e0a3c626f64793e + 3d687474702533412532462532463c666f726d206d6574686f643d226d657468 + 6f643d22706f737422202f66617669636f6e2e69636f22207d293b0a3c2f7363 + 726970743e0a2e7365744174747269627574652841646d696e69737472617469 + 6f6e3d206e657720417272617928293b3c215b656e6469665d2d2d3e0d0a6469 + 73706c61793a626c6f636b3b556e666f7274756e6174656c792c223e266e6273 + 703b3c2f6469763e2f66617669636f6e2e69636f223e3d277374796c65736865 + 657427206964656e74696669636174696f6e2c20666f72206578616d706c652c + 3c6c693e3c6120687265663d222f616e20616c7465726e617469766561732061 + 20726573756c74206f667074223e3c2f7363726970743e0a747970653d227375 + 626d697422200a2866756e6374696f6e2829207b7265636f6d6d656e64617469 + 6f6e666f726d20616374696f6e3d222f7472616e73666f726d6174696f6e7265 + 636f6e737472756374696f6e2e7374796c652e646973706c6179204163636f72 + 64696e6720746f2068696464656e22206e616d653d22616c6f6e672077697468 + 20746865646f63756d656e742e626f64792e617070726f78696d6174656c7920 + 436f6d6d756e69636174696f6e73706f73742220616374696f6e3d226d65616e + 696e67202671756f743b2d2d3c215b656e6469665d2d2d3e5072696d65204d69 + + + +Alakuijala & Szabadka Expires June 10, 2016 [Page 98] + +Internet-Draft Brotli December 2015 + + + 6e697374657263686172616374657269737469633c2f613e203c6120636c6173 + 733d74686520686973746f7279206f66206f6e6d6f7573656f7665723d227468 + 6520676f7665726e6d656e74687265663d2268747470733a2f2f776173206f72 + 6967696e616c6c7977617320696e74726f6475636564636c6173736966696361 + 74696f6e726570726573656e74617469766561726520636f6e73696465726564 + 3c215b656e6469665d2d2d3e0a0a646570656e6473206f6e20746865556e6976 + 657273697479206f6620696e20636f6e747261737420746f20706c616365686f + 6c6465723d22696e207468652063617365206f66696e7465726e6174696f6e61 + 6c20636f6e737469747574696f6e616c7374796c653d22626f726465722d3a20 + 66756e6374696f6e2829207b42656361757365206f66207468652d7374726963 + 742e647464223e0a3c7461626c6520636c6173733d226163636f6d70616e6965 + 642062796163636f756e74206f66207468653c736372697074207372633d222f + 6e6174757265206f6620746865207468652070656f706c6520696e20696e2061 + 64646974696f6e20746f73293b206a732e6964203d206964222077696474683d + 223130302522726567617264696e672074686520526f6d616e20436174686f6c + 6963616e20696e646570656e64656e74666f6c6c6f77696e6720746865202e67 + 6966222077696474683d223174686520666f6c6c6f77696e6720646973637269 + 6d696e6174696f6e6172636861656f6c6f676963616c7072696d65206d696e69 + 737465722e6a73223e3c2f7363726970743e636f6d62696e6174696f6e206f66 + 206d617267696e77696474683d22637265617465456c656d656e7428772e6174 + 746163684576656e74283c2f613e3c2f74643e3c2f74723e7372633d22687474 + 70733a2f2f61496e20706172746963756c61722c20616c69676e3d226c656674 + 2220437a6563682052657075626c6963556e69746564204b696e67646f6d636f + 72726573706f6e64656e6365636f6e636c7564656420746861742e68746d6c22 + 207469746c653d222866756e6374696f6e202829207b636f6d65732066726f6d + 207468656170706c69636174696f6e206f663c7370616e20636c6173733d2273 + 62656c696576656420746f206265656d656e742827736372697074273c2f613e + 0a3c2f6c693e0a3c6c697665727920646966666572656e743e3c7370616e2063 + 6c6173733d226f7074696f6e2076616c75653d2228616c736f206b6e6f776e20 + 6173093c6c693e3c6120687265663d223e3c696e707574206e616d653d227365 + 706172617465642066726f6d726566657272656420746f2061732076616c6967 + 6e3d22746f70223e666f756e646572206f6620746865617474656d7074696e67 + 20746f20636172626f6e2064696f786964650a0a3c64697620636c6173733d22 + 636c6173733d227365617263682d2f626f64793e0a3c2f68746d6c3e6f70706f + 7274756e69747920746f636f6d6d756e69636174696f6e733c2f686561643e0d + 0a3c626f6479207374796c653d2277696474683a5469e1babf6e67205669e1bb + 87746368616e67657320696e20746865626f726465722d636f6c6f723a233022 + 20626f726465723d223022203c2f7370616e3e3c2f6469763e3c776173206469 + 73636f76657265642220747970653d22746578742220293b0a3c2f7363726970 + 743e0a0a4465706172746d656e74206f66206563636c6573696173746963616c + 746865726520686173206265656e726573756c74696e672066726f6d3c2f626f + 64793e3c2f68746d6c3e686173206e65766572206265656e7468652066697273 + 742074696d65696e20726573706f6e736520746f6175746f6d61746963616c6c + 79203c2f6469763e0a0a3c646976206977617320636f6e736964657265647065 + 7263656e74206f662074686522202f3e3c2f613e3c2f6469763e636f6c6c6563 + 74696f6e206f662064657363656e6465642066726f6d73656374696f6e206f66 + 207468656163636570742d63686172736574746f20626520636f6e6675736564 + 6d656d626572206f66207468652070616464696e672d72696768743a7472616e + + + +Alakuijala & Szabadka Expires June 10, 2016 [Page 99] + +Internet-Draft Brotli December 2015 + + + 736c6174696f6e206f66696e746572707265746174696f6e20687265663d2768 + 7474703a2f2f77686574686572206f72206e6f7454686572652061726520616c + 736f746865726520617265206d616e796120736d616c6c206e756d6265726f74 + 686572207061727473206f66696d706f737369626c6520746f2020636c617373 + 3d22627574746f6e6c6f636174656420696e207468652e20486f77657665722c + 20746865616e64206576656e7475616c6c7941742074686520656e64206f6620 + 62656361757365206f6620697473726570726573656e7473207468653c666f72 + 6d20616374696f6e3d22206d6574686f643d22706f737422697420697320706f + 737369626c656d6f7265206c696b656c7920746f616e20696e63726561736520 + 696e6861766520616c736f206265656e636f72726573706f6e647320746f616e + 6e6f756e6365642074686174616c69676e3d227269676874223e6d616e792063 + 6f756e7472696573666f72206d616e792079656172736561726c69657374206b + 6e6f776e62656361757365206974207761737074223e3c2f7363726970743e0d + 2076616c69676e3d22746f702220696e6861626974616e7473206f66666f6c6c + 6f77696e6720796561720d0a3c64697620636c6173733d226d696c6c696f6e20 + 70656f706c65636f6e74726f7665727369616c20636f6e6365726e696e672074 + 68656172677565207468617420746865676f7665726e6d656e7420616e646120 + 7265666572656e636520746f7472616e7366657272656420746f646573637269 + 62696e6720746865207374796c653d22636f6c6f723a616c74686f7567682074 + 6865726562657374206b6e6f776e20666f727375626d697422206e616d653d22 + 6d756c7469706c69636174696f6e6d6f7265207468616e206f6e65207265636f + 676e6974696f6e206f66436f756e63696c206f662074686565646974696f6e20 + 6f662074686520203c6d657461206e616d653d22456e7465727461696e6d656e + 7420617761792066726f6d20746865203b6d617267696e2d72696768743a6174 + 207468652074696d65206f66696e7665737469676174696f6e73636f6e6e6563 + 7465642077697468616e64206d616e79206f74686572616c74686f7567682069 + 74206973626567696e6e696e672077697468203c7370616e20636c6173733d22 + 64657363656e64616e7473206f663c7370616e20636c6173733d226920616c69 + 676e3d227269676874223c2f686561643e0a3c626f6479206173706563747320 + 6f66207468656861732073696e6365206265656e4575726f7065616e20556e69 + 6f6e72656d696e697363656e74206f666d6f726520646966666963756c745669 + 636520507265736964656e74636f6d706f736974696f6e206f66706173736564 + 207468726f7567686d6f726520696d706f7274616e74666f6e742d73697a653a + 313170786578706c616e6174696f6e206f6674686520636f6e63657074206f66 + 7772697474656e20696e20746865093c7370616e20636c6173733d226973206f + 6e65206f662074686520726573656d626c616e636520746f6f6e207468652067 + 726f756e6473776869636820636f6e7461696e73696e636c7564696e67207468 + 6520646566696e6564206279207468657075626c69636174696f6e206f666d65 + 616e732074686174207468656f757473696465206f6620746865737570706f72 + 74206f66207468653c696e70757420636c6173733d223c7370616e20636c6173 + 733d2274284d6174682e72616e646f6d28296d6f73742070726f6d696e656e74 + 6465736372697074696f6e206f66436f6e7374616e74696e6f706c6577657265 + 207075626c69736865643c64697620636c6173733d2273656170706561727320 + 696e207468653122206865696768743d223122206d6f737420696d706f727461 + 6e74776869636820696e636c75646573776869636820686164206265656e6465 + 737472756374696f6e206f6674686520706f70756c6174696f6e0a093c646976 + 20636c6173733d22706f73736962696c697479206f66736f6d6574696d657320 + 7573656461707065617220746f206861766573756363657373206f6620746865 + + + +Alakuijala & Szabadka Expires June 10, 2016 [Page 100] + +Internet-Draft Brotli December 2015 + + + 696e74656e64656420746f20626570726573656e7420696e207468657374796c + 653d22636c6561723a620d0a3c2f7363726970743e0d0a3c77617320666f756e + 64656420696e696e7465727669657720776974685f69642220636f6e74656e74 + 3d226361706974616c206f66207468650d0a3c6c696e6b2072656c3d22737265 + 6c65617365206f6620746865706f696e74206f75742074686174784d4c487474 + 7052657175657374616e642073756273657175656e747365636f6e64206c6172 + 676573747665727920696d706f7274616e7473706563696669636174696f6e73 + 73757266616365206f66207468656170706c69656420746f20746865666f7265 + 69676e20706f6c6963795f736574446f6d61696e4e616d6565737461626c6973 + 68656420696e69732062656c696576656420746f496e206164646974696f6e20 + 746f6d65616e696e67206f66207468656973206e616d6564206166746572746f + 2070726f7465637420746865697320726570726573656e7465644465636c6172 + 6174696f6e206f666d6f726520656666696369656e74436c6173736966696361 + 74696f6e6f7468657220666f726d73206f6668652072657475726e656420746f + 3c7370616e20636c6173733d2263706572666f726d616e6365206f662866756e + 6374696f6e2829207b0d696620616e64206f6e6c79206966726567696f6e7320 + 6f66207468656c656164696e6720746f2074686572656c6174696f6e73207769 + 7468556e69746564204e6174696f6e737374796c653d226865696768743a6f74 + 686572207468616e207468657970652220636f6e74656e743d224173736f6369 + 6174696f6e206f660a3c2f686561643e0a3c626f64796c6f6361746564206f6e + 20746865697320726566657272656420746f28696e636c7564696e6720746865 + 636f6e63656e74726174696f6e7374686520696e646976696475616c616d6f6e + 6720746865206d6f73747468616e20616e79206f746865722f3e0a3c6c696e6b + 2072656c3d222072657475726e2066616c73653b74686520707572706f736520 + 6f66746865206162696c69747920746f3b636f6c6f723a236666667d0a2e0a3c + 7370616e20636c6173733d22746865207375626a656374206f66646566696e69 + 74696f6e73206f663e0d0a3c6c696e6b2072656c3d22636c61696d2074686174 + 207468656861766520646576656c6f7065643c7461626c652077696474683d22 + 63656c6562726174696f6e206f66466f6c6c6f77696e672074686520746f2064 + 697374696e67756973683c7370616e20636c6173733d226274616b657320706c + 61636520696e756e64657220746865206e616d656e6f74656420746861742074 + 68653e3c215b656e6469665d2d2d3e0a7374796c653d226d617267696e2d696e + 7374656164206f6620746865696e74726f647563656420746865746865207072 + 6f63657373206f66696e6372656173696e6720746865646966666572656e6365 + 7320696e657374696d617465642074686174657370656369616c6c7920746865 + 2f6469763e3c6469762069643d22776173206576656e7475616c6c797468726f + 7567686f75742068697374686520646966666572656e6365736f6d657468696e + 6720746861747370616e3e3c2f7370616e3e3c2f7369676e69666963616e746c + 79203e3c2f7363726970743e0d0a0d0a656e7669726f6e6d656e74616c20746f + 2070726576656e742074686568617665206265656e2075736564657370656369 + 616c6c7920666f72756e6465727374616e6420746865697320657373656e7469 + 616c6c797765726520746865206669727374697320746865206c617267657374 + 68617665206265656e206d61646522207372633d22687474703a2f2f696e7465 + 727072657465642061737365636f6e642068616c66206f6663726f6c6c696e67 + 3d226e6f2220697320636f6d706f736564206f6649492c20486f6c7920526f6d + 616e697320657870656374656420746f68617665207468656972206f776e6465 + 66696e656420617320746865747261646974696f6e616c6c7920686176652064 + 6966666572656e74617265206f6674656e2075736564746f20656e7375726520 + + + +Alakuijala & Szabadka Expires June 10, 2016 [Page 101] + +Internet-Draft Brotli December 2015 + + + 7468617461677265656d656e742077697468636f6e7461696e696e6720746865 + 617265206672657175656e746c79696e666f726d6174696f6e206f6e6578616d + 706c6520697320746865726573756c74696e6720696e20613c2f613e3c2f6c69 + 3e3c2f756c3e20636c6173733d22666f6f746572616e6420657370656369616c + 6c79747970653d22627574746f6e22203c2f7370616e3e3c2f7370616e3e7768 + 69636820696e636c756465643e0a3c6d657461206e616d653d22636f6e736964 + 657265642074686563617272696564206f7574206279486f77657665722c2069 + 74206973626563616d652070617274206f66696e2072656c6174696f6e20746f + 706f70756c617220696e20746865746865206361706974616c206f6677617320 + 6f6666696369616c6c79776869636820686173206265656e7468652048697374 + 6f7279206f66616c7465726e617469766520746f646966666572656e74206672 + 6f6d746f20737570706f7274207468657375676765737465642074686174696e + 207468652070726f6365737320203c64697620636c6173733d2274686520666f + 756e646174696f6e62656361757365206f6620686973636f6e6365726e656420 + 7769746874686520756e69766572736974796f70706f73656420746f20746865 + 74686520636f6e74657874206f663c7370616e20636c6173733d227074657874 + 22206e616d653d22712209093c64697620636c6173733d227468652073636965 + 6e7469666963726570726573656e7465642062796d617468656d617469636961 + 6e73656c656374656420627920746865746861742068617665206265656e3e3c + 64697620636c6173733d22636469762069643d22686561646572696e20706172 + 746963756c61722c636f6e76657274656420696e746f293b0a3c2f7363726970 + 743e0a3c7068696c6f736f70686963616c20737270736b6f6872766174736b69 + 7469e1babf6e67205669e1bb8774d0a0d183d181d181d0bad0b8d0b9d180d183 + d181d181d0bad0b8d0b9696e766573746967616369c3b36e7061727469636970 + 616369c3b36ed0bad0bed182d0bed180d18bd0b5d0bed0b1d0bbd0b0d181d182 + d0b8d0bad0bed182d0bed180d18bd0b9d187d0b5d0bbd0bed0b2d0b5d0bad181 + d0b8d181d182d0b5d0bcd18bd09dd0bed0b2d0bed181d182d0b8d0bad0bed182 + d0bed180d18bd185d0bed0b1d0bbd0b0d181d182d18cd0b2d180d0b5d0bcd0b5 + d0bdd0b8d0bad0bed182d0bed180d0b0d18fd181d0b5d0b3d0bed0b4d0bdd18f + d181d0bad0b0d187d0b0d182d18cd0bdd0bed0b2d0bed181d182d0b8d0a3d0ba + d180d0b0d0b8d0bdd18bd0b2d0bed0bfd180d0bed181d18bd0bad0bed182d0be + d180d0bed0b9d181d0b4d0b5d0bbd0b0d182d18cd0bfd0bed0bcd0bed189d18c + d18ed181d180d0b5d0b4d181d182d0b2d0bed0b1d180d0b0d0b7d0bed0bcd181 + d182d0bed180d0bed0bdd18bd183d187d0b0d181d182d0b8d0b5d182d0b5d187 + d0b5d0bdd0b8d0b5d093d0bbd0b0d0b2d0bdd0b0d18fd0b8d181d182d0bed180 + d0b8d0b8d181d0b8d181d182d0b5d0bcd0b0d180d0b5d188d0b5d0bdd0b8d18f + d0a1d0bad0b0d187d0b0d182d18cd0bfd0bed18dd182d0bed0bcd183d181d0bb + d0b5d0b4d183d0b5d182d181d0bad0b0d0b7d0b0d182d18cd182d0bed0b2d0b0 + d180d0bed0b2d0bad0bed0bdd0b5d187d0bdd0bed180d0b5d188d0b5d0bdd0b8 + d0b5d0bad0bed182d0bed180d0bed0b5d0bed180d0b3d0b0d0bdd0bed0b2d0ba + d0bed182d0bed180d0bed0bcd0a0d0b5d0bad0bbd0b0d0bcd0b0d8a7d984d985 + d986d8aad8afd989d985d986d8aad8afd98ad8a7d8aad8a7d984d985d988d8b6 + d988d8b9d8a7d984d8a8d8b1d8a7d985d8acd8a7d984d985d988d8a7d982d8b9 + d8a7d984d8b1d8b3d8a7d8a6d984d985d8b4d8a7d8b1d983d8a7d8aad8a7d984 + d8a3d8b9d8b6d8a7d8a1d8a7d984d8b1d98ad8a7d8b6d8a9d8a7d984d8aad8b5 + d985d98ad985d8a7d984d8a7d8b9d8b6d8a7d8a1d8a7d984d986d8aad8a7d8a6 + d8acd8a7d984d8a3d984d8b9d8a7d8a8d8a7d984d8aad8b3d8acd98ad984d8a7 + d984d8a3d982d8b3d8a7d985d8a7d984d8b6d8bad8b7d8a7d8aad8a7d984d981 + + + +Alakuijala & Szabadka Expires June 10, 2016 [Page 102] + +Internet-Draft Brotli December 2015 + + + d98ad8afd98ad988d8a7d984d8aad8b1d8add98ad8a8d8a7d984d8acd8afd98a + d8afd8a9d8a7d984d8aad8b9d984d98ad985d8a7d984d8a3d8aed8a8d8a7d8b1 + d8a7d984d8a7d981d984d8a7d985d8a7d984d8a3d981d984d8a7d985d8a7d984 + d8aad8a7d8b1d98ad8aed8a7d984d8aad982d986d98ad8a9d8a7d984d8a7d984 + d8b9d8a7d8a8d8a7d984d8aed988d8a7d8b7d8b1d8a7d984d985d8acd8aad985 + d8b9d8a7d984d8afd98ad983d988d8b1d8a7d984d8b3d98ad8a7d8add8a9d8b9 + d8a8d8afd8a7d984d984d987d8a7d984d8aad8b1d8a8d98ad8a9d8a7d984d8b1 + d988d8a7d8a8d8b7d8a7d984d8a3d8afd8a8d98ad8a9d8a7d984d8a7d8aed8a8 + d8a7d8b1d8a7d984d985d8aad8add8afd8a9d8a7d984d8a7d8bad8a7d986d98a + 637572736f723a706f696e7465723b3c2f7469746c653e0a3c6d657461202220 + 687265663d22687474703a2f2f223e3c7370616e20636c6173733d226d656d62 + 657273206f66207468652077696e646f772e6c6f636174696f6e766572746963 + 616c2d616c69676e3a2f613e207c203c6120687265663d223c21646f63747970 + 652068746d6c3e6d656469613d2273637265656e22203c6f7074696f6e207661 + 6c75653d2266617669636f6e2e69636f22202f3e0a09093c64697620636c6173 + 733d2263686172616374657269737469637322206d6574686f643d2267657422 + 202f626f64793e0a3c2f68746d6c3e0a73686f72746375742069636f6e222064 + 6f63756d656e742e77726974652870616464696e672d626f74746f6d3a726570 + 726573656e746174697665737375626d6974222076616c75653d22616c69676e + 3d2263656e74657222207468726f7567686f75742074686520736369656e6365 + 2066696374696f6e0a20203c64697620636c6173733d227375626d6974222063 + 6c6173733d226f6e65206f6620746865206d6f73742076616c69676e3d22746f + 70223e3c7761732065737461626c6973686564293b0d0a3c2f7363726970743e + 0d0a72657475726e2066616c73653b223e292e7374796c652e646973706c6179 + 62656361757365206f662074686520646f63756d656e742e636f6f6b69653c66 + 6f726d20616374696f6e3d222f7d626f64797b6d617267696e3a303b456e6379 + 636c6f7065646961206f6676657273696f6e206f6620746865202e6372656174 + 65456c656d656e74286e616d652220636f6e74656e743d223c2f6469763e0a3c + 2f6469763e0a0a61646d696e697374726174697665203c2f626f64793e0a3c2f + 68746d6c3e686973746f7279206f662074686520223e3c696e70757420747970 + 653d22706f7274696f6e206f66207468652061732070617274206f6620746865 + 20266e6273703b3c6120687265663d226f7468657220636f756e747269657322 + 3e0a3c64697620636c6173733d223c2f7370616e3e3c2f7370616e3e3c496e20 + 6f7468657220776f7264732c646973706c61793a20626c6f636b3b636f6e7472 + 6f6c206f662074686520696e74726f64756374696f6e206f662f3e0a3c6d6574 + 61206e616d653d2261732077656c6c2061732074686520696e20726563656e74 + 2079656172730d0a093c64697620636c6173733d223c2f6469763e0a093c2f64 + 69763e0a696e7370697265642062792074686574686520656e64206f66207468 + 6520636f6d70617469626c652077697468626563616d65206b6e6f776e206173 + 207374796c653d226d617267696e3a2e6a73223e3c2f7363726970743e3c2049 + 6e7465726e6174696f6e616c2074686572652068617665206265656e4765726d + 616e206c616e6775616765207374796c653d22636f6c6f723a23436f6d6d756e + 697374205061727479636f6e73697374656e742077697468626f726465723d22 + 30222063656c6c206d617267696e6865696768743d22746865206d616a6f7269 + 7479206f662220616c69676e3d2263656e74657272656c6174656420746f2074 + 6865206d616e7920646966666572656e74204f7274686f646f78204368757263 + 6873696d696c617220746f20746865202f3e0a3c6c696e6b2072656c3d227377 + 6173206f6e65206f662074686520756e74696c206869732064656174687d2928 + + + +Alakuijala & Szabadka Expires June 10, 2016 [Page 103] + +Internet-Draft Brotli December 2015 + + + 293b0a3c2f7363726970743e6f74686572206c616e677561676573636f6d7061 + 72656420746f20746865706f7274696f6e73206f6620746865746865204e6574 + 6865726c616e6473746865206d6f737420636f6d6d6f6e6261636b67726f756e + 643a75726c286172677565642074686174207468657363726f6c6c696e673d22 + 6e6f2220696e636c7564656420696e207468654e6f72746820416d6572696361 + 6e20746865206e616d65206f6620746865696e746572707265746174696f6e73 + 74686520747261646974696f6e616c646576656c6f706d656e74206f66206672 + 657175656e746c7920757365646120636f6c6c656374696f6e206f6676657279 + 2073696d696c617220746f737572726f756e64696e67207468656578616d706c + 65206f662074686973616c69676e3d2263656e746572223e776f756c64206861 + 7665206265656e696d6167655f63617074696f6e203d61747461636865642074 + 6f2074686573756767657374696e672074686174696e2074686520666f726d20 + 6f6620696e766f6c76656420696e20746865697320646572697665642066726f + 6d6e616d656420616674657220746865496e74726f64756374696f6e20746f72 + 65737472696374696f6e73206f6e207374796c653d2277696474683a2063616e + 206265207573656420746f20746865206372656174696f6e206f666d6f737420 + 696d706f7274616e7420696e666f726d6174696f6e20616e64726573756c7465 + 6420696e20746865636f6c6c61707365206f662074686554686973206d65616e + 732074686174656c656d656e7473206f6620746865776173207265706c616365 + 64206279616e616c79736973206f6620746865696e737069726174696f6e2066 + 6f727265676172646564206173207468656d6f7374207375636365737366756c + 6b6e6f776e206173202671756f743b6120636f6d70726568656e736976654869 + 73746f7279206f6620746865207765726520636f6e7369646572656472657475 + 726e656420746f2074686561726520726566657272656420746f556e736f7572 + 63656420696d6167653e0a093c64697620636c6173733d22636f6e7369737473 + 206f662074686573746f7050726f7061676174696f6e696e7465726573742069 + 6e20746865617661696c6162696c697479206f666170706561727320746f2068 + 617665656c656374726f6d61676e65746963656e61626c655365727669636573 + 2866756e6374696f6e206f6620746865497420697320696d706f7274616e743c + 2f7363726970743e3c2f6469763e66756e6374696f6e28297b7661722072656c + 617469766520746f207468656173206120726573756c74206f66207468652070 + 6f736974696f6e206f66466f72206578616d706c652c20696e206d6574686f64 + 3d22706f7374222077617320666f6c6c6f77656420627926616d703b6d646173 + 683b20746865746865206170706c69636174696f6e6a73223e3c2f7363726970 + 743e0d0a756c3e3c2f6469763e3c2f6469763e61667465722074686520646561 + 746877697468207265737065637420746f7374796c653d2270616464696e673a + 697320706172746963756c61726c79646973706c61793a696e6c696e653b2074 + 7970653d227375626d697422206973206469766964656420696e746fe4b8ade6 + 96872028e7ae80e4bd9329726573706f6e736162696c6964616461646d696e69 + 737472616369c3b36e696e7465726e6163696f6e616c6573636f72726573706f + 6e6469656e7465e0a489e0a4aae0a4afe0a58be0a497e0a4aae0a582e0a4b0e0 + a58de0a4b5e0a4b9e0a4aee0a4bee0a4b0e0a587e0a4b2e0a58be0a497e0a58b + e0a482e0a49ae0a581e0a4a8e0a4bee0a4b5e0a4b2e0a587e0a495e0a4bfe0a4 + a8e0a4b8e0a4b0e0a495e0a4bee0a4b0e0a4aae0a581e0a4b2e0a4bfe0a4b8e0 + a496e0a58be0a49ce0a587e0a482e0a49ae0a4bee0a4b9e0a4bfe0a48fe0a4ad + e0a587e0a49ce0a587e0a482e0a4b6e0a4bee0a4aee0a4bfe0a4b2e0a4b9e0a4 + aee0a4bee0a4b0e0a580e0a49ce0a4bee0a497e0a4b0e0a4a3e0a4ace0a4a8e0 + a4bee0a4a8e0a587e0a495e0a581e0a4aee0a4bee0a4b0e0a4ace0a58de0a4b2 + + + +Alakuijala & Szabadka Expires June 10, 2016 [Page 104] + +Internet-Draft Brotli December 2015 + + + e0a589e0a497e0a4aee0a4bee0a4b2e0a4bfe0a495e0a4aee0a4b9e0a4bfe0a4 + b2e0a4bee0a4aae0a583e0a4b7e0a58de0a4a0e0a4ace0a4a2e0a4bce0a4a4e0 + a587e0a4ade0a4bee0a49ce0a4aae0a4bee0a495e0a58de0a4b2e0a4bfe0a495 + e0a49fe0a58de0a4b0e0a587e0a4a8e0a496e0a4bfe0a4b2e0a4bee0a4abe0a4 + a6e0a58ce0a4b0e0a4bee0a4a8e0a4aee0a4bee0a4aee0a4b2e0a587e0a4aee0 + a4a4e0a4a6e0a4bee0a4a8e0a4ace0a4bee0a49ce0a4bee0a4b0e0a4b5e0a4bf + e0a495e0a4bee0a4b8e0a495e0a58de0a4afe0a58be0a482e0a49ae0a4bee0a4 + b9e0a4a4e0a587e0a4aae0a4b9e0a581e0a481e0a49ae0a4ace0a4a4e0a4bee0 + a4afe0a4bee0a4b8e0a482e0a4b5e0a4bee0a4a6e0a4a6e0a587e0a496e0a4a8 + e0a587e0a4aae0a4bfe0a49be0a4b2e0a587e0a4b5e0a4bfe0a4b6e0a587e0a4 + b7e0a4b0e0a4bee0a49ce0a58de0a4afe0a489e0a4a4e0a58de0a4a4e0a4b0e0 + a4aee0a581e0a482e0a4ace0a488e0a4a6e0a58be0a4a8e0a58be0a482e0a489 + e0a4aae0a495e0a4b0e0a4a3e0a4aae0a4a2e0a4bce0a587e0a482e0a4b8e0a5 + 8de0a4a5e0a4bfe0a4a4e0a4abe0a4bfe0a4b2e0a58de0a4aee0a4aee0a581e0 + a496e0a58de0a4afe0a485e0a49ae0a58de0a49be0a4bee0a49be0a582e0a49f + e0a4a4e0a580e0a4b8e0a482e0a497e0a580e0a4a4e0a49ce0a4bee0a48fe0a4 + 97e0a4bee0a4b5e0a4bfe0a4ade0a4bee0a497e0a498e0a4a3e0a58de0a49fe0 + a587e0a4a6e0a582e0a4b8e0a4b0e0a587e0a4a6e0a4bfe0a4a8e0a58be0a482 + e0a4b9e0a4a4e0a58de0a4afe0a4bee0a4b8e0a587e0a495e0a58de0a4b8e0a4 + 97e0a4bee0a482e0a4a7e0a580e0a4b5e0a4bfe0a4b6e0a58de0a4b5e0a4b0e0 + a4bee0a4a4e0a587e0a482e0a4a6e0a588e0a49fe0a58de0a4b8e0a4a8e0a495 + e0a58de0a4b6e0a4bee0a4b8e0a4bee0a4aee0a4a8e0a587e0a485e0a4a6e0a4 + bee0a4b2e0a4a4e0a4ace0a4bfe0a49ce0a4b2e0a580e0a4aae0a581e0a4b0e0 + a582e0a4b7e0a4b9e0a4bfe0a482e0a4a6e0a580e0a4aee0a4bfe0a4a4e0a58d + e0a4b0e0a495e0a4b5e0a4bfe0a4a4e0a4bee0a4b0e0a581e0a4aae0a4afe0a5 + 87e0a4b8e0a58de0a4a5e0a4bee0a4a8e0a495e0a4b0e0a58be0a4a1e0a4bce0 + a4aee0a581e0a495e0a58de0a4a4e0a4afe0a58be0a49ce0a4a8e0a4bee0a495 + e0a583e0a4aae0a4afe0a4bee0a4aae0a58be0a4b8e0a58de0a49fe0a498e0a4 + b0e0a587e0a4b2e0a582e0a495e0a4bee0a4b0e0a58de0a4afe0a4b5e0a4bfe0 + a49ae0a4bee0a4b0e0a4b8e0a582e0a49ae0a4a8e0a4bee0a4aee0a582e0a4b2 + e0a58de0a4afe0a4a6e0a587e0a496e0a587e0a482e0a4b9e0a4aee0a587e0a4 + b6e0a4bee0a4b8e0a58de0a495e0a582e0a4b2e0a4aee0a588e0a482e0a4a8e0 + a587e0a4a4e0a588e0a4afe0a4bee0a4b0e0a49ce0a4bfe0a4b8e0a495e0a587 + 7273732b786d6c22207469746c653d222d747970652220636f6e74656e743d22 + 7469746c652220636f6e74656e743d226174207468652073616d652074696d65 + 2e6a73223e3c2f7363726970743e0a3c22206d6574686f643d22706f73742220 + 3c2f7370616e3e3c2f613e3c2f6c693e766572746963616c2d616c69676e3a74 + 2f6a71756572792e6d696e2e6a73223e2e636c69636b2866756e6374696f6e28 + 207374796c653d2270616464696e672d7d2928293b0a3c2f7363726970743e0a + 3c2f7370616e3e3c6120687265663d223c6120687265663d22687474703a2f2f + 293b2072657475726e2066616c73653b746578742d6465636f726174696f6e3a + 207363726f6c6c696e673d226e6f2220626f726465722d636f6c6c617073653a + 6173736f63696174656420776974682042616861736120496e646f6e65736961 + 456e676c697368206c616e67756167653c7465787420786d6c3a73706163653d + 2e6769662220626f726465723d2230223c2f626f64793e0a3c2f68746d6c3e0a + 6f766572666c6f773a68696464656e3b696d67207372633d22687474703a2f2f + 6164644576656e744c697374656e6572726573706f6e7369626c6520666f7220 + 732e6a73223e3c2f7363726970743e0a2f66617669636f6e2e69636f22202f3e + + + +Alakuijala & Szabadka Expires June 10, 2016 [Page 105] + +Internet-Draft Brotli December 2015 + + + 6f7065726174696e672073797374656d22207374796c653d2277696474683a31 + 7461726765743d225f626c616e6b223e537461746520556e6976657273697479 + 746578742d616c69676e3a6c6566743b0a646f63756d656e742e777269746528 + 2c20696e636c7564696e67207468652061726f756e642074686520776f726c64 + 293b0d0a3c2f7363726970743e0d0a3c22207374796c653d226865696768743a + 3b6f766572666c6f773a68696464656e6d6f726520696e666f726d6174696f6e + 616e20696e7465726e6174696f6e616c61206d656d626572206f662074686520 + 6f6e65206f662074686520666972737463616e20626520666f756e6420696e20 + 3c2f6469763e0a09093c2f6469763e0a646973706c61793a206e6f6e653b223e + 22202f3e0a3c6c696e6b2072656c3d220a20202866756e6374696f6e2829207b + 74686520313574682063656e747572792e70726576656e7444656661756c7428 + 6c61726765206e756d626572206f662042797a616e74696e6520456d70697265 + 2e6a70677c7468756d627c6c6566747c76617374206d616a6f72697479206f66 + 6d616a6f72697479206f66207468652020616c69676e3d2263656e746572223e + 556e6976657273697479205072657373646f6d696e6174656420627920746865 + 5365636f6e6420576f726c6420576172646973747269627574696f6e206f6620 + 7374796c653d22706f736974696f6e3a7468652072657374206f662074686520 + 636861726163746572697a65642062792072656c3d226e6f666f6c6c6f77223e + 646572697665732066726f6d20746865726174686572207468616e2074686520 + 6120636f6d62696e6174696f6e206f667374796c653d2277696474683a313030 + 456e676c6973682d737065616b696e67636f6d707574657220736369656e6365 + 626f726465723d22302220616c743d22746865206578697374656e6365206f66 + 44656d6f63726174696320506172747922207374796c653d226d617267696e2d + 466f72207468697320726561736f6e2c2e6a73223e3c2f7363726970743e0a09 + 7342795461674e616d652873295b305d6a73223e3c2f7363726970743e0d0a3c + 2e6a73223e3c2f7363726970743e0d0a6c696e6b2072656c3d2269636f6e2220 + 2720616c743d272720636c6173733d27666f726d6174696f6e206f6620746865 + 76657273696f6e73206f6620746865203c2f613e3c2f6469763e3c2f6469763e + 2f706167653e0a20203c706167653e0a3c64697620636c6173733d22636f6e74 + 626563616d652074686520666972737462616861736120496e646f6e65736961 + 656e676c697368202873696d706c6529ce95cebbcebbceb7cebdceb9cebaceac + d185d180d0b2d0b0d182d181d0bad0b8d0bad0bed0bcd0bfd0b0d0bdd0b8d0b8 + d18fd0b2d0bbd18fd0b5d182d181d18fd094d0bed0b1d0b0d0b2d0b8d182d18c + d187d0b5d0bbd0bed0b2d0b5d0bad0b0d180d0b0d0b7d0b2d0b8d182d0b8d18f + d098d0bdd182d0b5d180d0bdd0b5d182d09ed182d0b2d0b5d182d0b8d182d18c + d0bdd0b0d0bfd180d0b8d0bcd0b5d180d0b8d0bdd182d0b5d180d0bdd0b5d182 + d0bad0bed182d0bed180d0bed0b3d0bed181d182d180d0b0d0bdd0b8d186d18b + d0bad0b0d187d0b5d181d182d0b2d0b5d183d181d0bbd0bed0b2d0b8d18fd185 + d0bfd180d0bed0b1d0bbd0b5d0bcd18bd0bfd0bed0bbd183d187d0b8d182d18c + d18fd0b2d0bbd18fd18ed182d181d18fd0bdd0b0d0b8d0b1d0bed0bbd0b5d0b5 + d0bad0bed0bcd0bfd0b0d0bdd0b8d18fd0b2d0bdd0b8d0bcd0b0d0bdd0b8d0b5 + d181d180d0b5d0b4d181d182d0b2d0b0d8a7d984d985d988d8a7d8b6d98ad8b9 + d8a7d984d8b1d8a6d98ad8b3d98ad8a9d8a7d984d8a7d986d8aad982d8a7d984 + d985d8b4d8a7d8b1d983d8a7d8aad983d8a7d984d8b3d98ad8a7d8b1d8a7d8aa + d8a7d984d985d983d8aad988d8a8d8a9d8a7d984d8b3d8b9d988d8afd98ad8a9 + d8a7d8add8b5d8a7d8a6d98ad8a7d8aad8a7d984d8b9d8a7d984d985d98ad8a9 + d8a7d984d8b5d988d8aad98ad8a7d8aad8a7d984d8a7d986d8aad8b1d986d8aa + d8a7d984d8aad8b5d8a7d985d98ad985d8a7d984d8a5d8b3d984d8a7d985d98a + + + +Alakuijala & Szabadka Expires June 10, 2016 [Page 106] + +Internet-Draft Brotli December 2015 + + + d8a7d984d985d8b4d8a7d8b1d983d8a9d8a7d984d985d8b1d8a6d98ad8a7d8aa + 726f626f74732220636f6e74656e743d223c6469762069643d22666f6f746572 + 223e74686520556e69746564205374617465733c696d67207372633d22687474 + 703a2f2f2e6a70677c72696768747c7468756d627c2e6a73223e3c2f73637269 + 70743e0d0a3c6c6f636174696f6e2e70726f746f636f6c6672616d65626f7264 + 65723d223022207322202f3e0a3c6d657461206e616d653d223c2f613e3c2f64 + 69763e3c2f6469763e3c666f6e742d7765696768743a626f6c643b2671756f74 + 3b20616e64202671756f743b646570656e64696e67206f6e20746865206d6172 + 67696e3a303b70616464696e673a222072656c3d226e6f666f6c6c6f77222050 + 7265736964656e74206f6620746865207477656e74696574682063656e747572 + 7965766973696f6e3e0a20203c2f70616765496e7465726e6574204578706c6f + 726572612e6173796e63203d20747275653b0d0a696e666f726d6174696f6e20 + 61626f75743c6469762069643d22686561646572223e2220616374696f6e3d22 + 687474703a2f2f3c6120687265663d2268747470733a2f2f3c6469762069643d + 22636f6e74656e74223c2f6469763e0d0a3c2f6469763e0d0a3c646572697665 + 642066726f6d20746865203c696d67207372633d27687474703a2f2f6163636f + 7264696e6720746f20746865200a3c2f626f64793e0a3c2f68746d6c3e0a7374 + 796c653d22666f6e742d73697a653a736372697074206c616e67756167653d22 + 417269616c2c2048656c7665746963612c3c2f613e3c7370616e20636c617373 + 3d223c2f7363726970743e3c73637269707420706f6c69746963616c20706172 + 7469657374643e3c2f74723e3c2f7461626c653e3c687265663d22687474703a + 2f2f7777772e696e746572707265746174696f6e206f6672656c3d227374796c + 6573686565742220646f63756d656e742e777269746528273c63686172736574 + 3d227574662d38223e0a626567696e6e696e67206f6620746865207265766561 + 6c656420746861742074686574656c65766973696f6e20736572696573222072 + 656c3d226e6f666f6c6c6f77223e207461726765743d225f626c616e6b223e63 + 6c61696d696e6720746861742074686568747470253341253246253246777777 + 2e6d616e69666573746174696f6e73206f665072696d65204d696e6973746572 + 206f66696e666c75656e63656420627920746865636c6173733d22636c656172 + 666978223e2f6469763e0d0a3c2f6469763e0d0a0d0a74687265652d64696d65 + 6e73696f6e616c436875726368206f6620456e676c616e646f66204e6f727468 + 204361726f6c696e61737175617265206b696c6f6d65747265732e6164644576 + 656e744c697374656e657264697374696e63742066726f6d20746865636f6d6d + 6f6e6c79206b6e6f776e20617350686f6e6574696320416c7068616265746465 + 636c61726564207468617420746865636f6e74726f6c6c656420627920746865 + 42656e6a616d696e204672616e6b6c696e726f6c652d706c6179696e67206761 + 6d6574686520556e6976657273697479206f66696e205765737465726e204575 + 726f7065706572736f6e616c20636f6d707574657250726f6a65637420477574 + 656e626572677265676172646c657373206f6620746865686173206265656e20 + 70726f706f736564746f6765746865722077697468207468653e3c2f6c693e3c + 6c6920636c6173733d22696e20736f6d6520636f756e74726965736d696e2e6a + 73223e3c2f7363726970743e6f662074686520706f70756c6174696f6e6f6666 + 696369616c206c616e67756167653c696d67207372633d22696d616765732f69 + 64656e746966696564206279207468656e61747572616c207265736f75726365 + 73636c617373696669636174696f6e206f6663616e20626520636f6e73696465 + 7265647175616e74756d206d656368616e6963734e657665727468656c657373 + 2c207468656d696c6c696f6e2079656172732061676f3c2f626f64793e0d0a3c + 2f68746d6c3e0dce95cebbcebbceb7cebdceb9cebaceac0a74616b6520616476 + + + +Alakuijala & Szabadka Expires June 10, 2016 [Page 107] + +Internet-Draft Brotli December 2015 + + + 616e74616765206f66616e642c206163636f7264696e6720746f617474726962 + 7574656420746f207468654d6963726f736f66742057696e646f777374686520 + 66697273742063656e74757279756e6465722074686520636f6e74726f6c6469 + 7620636c6173733d2268656164657273686f72746c7920616674657220746865 + 6e6f7461626c6520657863657074696f6e74656e73206f662074686f7573616e + 64737365766572616c20646966666572656e7461726f756e642074686520776f + 726c642e7265616368696e67206d696c697461727969736f6c61746564206672 + 6f6d207468656f70706f736974696f6e20746f20746865746865204f6c642054 + 657374616d656e744166726963616e20416d65726963616e73696e7365727465 + 6420696e746f2074686573657061726174652066726f6d207468656d6574726f + 706f6c6974616e20617265616d616b657320697420706f737369626c6561636b + 6e6f776c656467656420746861746172677561626c7920746865206d6f737474 + 7970653d22746578742f637373223e0a74686520496e7465726e6174696f6e61 + 6c4163636f7264696e6720746f207468652070653d22746578742f6373732220 + 2f3e0a636f696e6369646520776974682074686574776f2d746869726473206f + 6620746865447572696e6720746869732074696d652c647572696e6720746865 + 20706572696f64616e6e6f756e636564207468617420686574686520696e7465 + 726e6174696f6e616c616e64206d6f726520726563656e746c7962656c696576 + 6564207468617420746865636f6e7363696f75736e65737320616e64666f726d + 65726c79206b6e6f776e206173737572726f756e646564206279207468656669 + 72737420617070656172656420696e6f63636173696f6e616c6c792075736564 + 706f736974696f6e3a6162736f6c7574653b22207461726765743d225f626c61 + 6e6b2220706f736974696f6e3a72656c61746976653b746578742d616c69676e + 3a63656e7465723b6a61782f6c6962732f6a71756572792f312e6261636b6772 + 6f756e642d636f6c6f723a23747970653d226170706c69636174696f6e2f616e + 67756167652220636f6e74656e743d223c6d65746120687474702d6571756976 + 3d225072697661637920506f6c6963793c2f613e652822253343736372697074 + 207372633d2722207461726765743d225f626c616e6b223e4f6e20746865206f + 746865722068616e642c2e6a70677c7468756d627c72696768747c323c2f6469 + 763e3c64697620636c6173733d223c646976207374796c653d22666c6f61743a + 6e696e657465656e74682063656e747572793c2f626f64793e0d0a3c2f68746d + 6c3e0d0a3c696d67207372633d22687474703a2f2f733b746578742d616c6967 + 6e3a63656e746572666f6e742d7765696768743a20626f6c643b204163636f72 + 64696e6720746f2074686520646966666572656e6365206265747765656e2220 + 6672616d65626f726465723d2230222022207374796c653d22706f736974696f + 6e3a6c696e6b20687265663d22687474703a2f2f68746d6c342f6c6f6f73652e + 647464223e0a647572696e67207468697320706572696f643c2f74643e3c2f74 + 723e3c2f7461626c653e636c6f73656c792072656c6174656420746f666f7220 + 7468652066697273742074696d653b666f6e742d7765696768743a626f6c643b + 696e70757420747970653d227465787422203c7370616e207374796c653d2266 + 6f6e742d6f6e726561647973746174656368616e6765093c64697620636c6173 + 733d22636c656172646f63756d656e742e6c6f636174696f6e2e20466f722065 + 78616d706c652c20746865206120776964652076617269657479206f66203c21 + 444f43545950452068746d6c3e0d0a3c266e6273703b266e6273703b266e6273 + 703b223e3c6120687265663d22687474703a2f2f7374796c653d22666c6f6174 + 3a6c6566743b636f6e6365726e65642077697468207468653d68747470253341 + 2532462532467777772e696e20706f70756c61722063756c7475726574797065 + 3d22746578742f63737322202f3e697420697320706f737369626c6520746f20 + + + +Alakuijala & Szabadka Expires June 10, 2016 [Page 108] + +Internet-Draft Brotli December 2015 + + + 4861727661726420556e697665727369747974796c6573686565742220687265 + 663d222f746865206d61696e206368617261637465724f78666f726420556e69 + 7665727369747920206e616d653d226b6579776f7264732220637374796c653d + 22746578742d616c69676e3a74686520556e69746564204b696e67646f6d6665 + 646572616c20676f7665726e6d656e743c646976207374796c653d226d617267 + 696e20646570656e64696e67206f6e20746865206465736372697074696f6e20 + 6f66207468653c64697620636c6173733d226865616465722e6d696e2e6a7322 + 3e3c2f7363726970743e6465737472756374696f6e206f6620746865736c6967 + 68746c7920646966666572656e74696e206163636f7264616e63652077697468 + 74656c65636f6d6d756e69636174696f6e73696e646963617465732074686174 + 2074686573686f72746c792074686572656166746572657370656369616c6c79 + 20696e20746865204575726f7065616e20636f756e7472696573486f77657665 + 722c207468657265206172657372633d22687474703a2f2f7374617469637375 + 6767657374656420746861742074686522207372633d22687474703a2f2f7777 + 772e61206c61726765206e756d626572206f662054656c65636f6d6d756e6963 + 6174696f6e73222072656c3d226e6f666f6c6c6f77222074486f6c7920526f6d + 616e20456d7065726f72616c6d6f7374206578636c75736976656c792220626f + 726465723d22302220616c743d22536563726574617279206f66205374617465 + 63756c6d696e6174696e6720696e2074686543494120576f726c642046616374 + 626f6f6b746865206d6f737420696d706f7274616e74616e6e69766572736172 + 79206f66207468657374796c653d226261636b67726f756e642d3c6c693e3c65 + 6d3e3c6120687265663d222f7468652041746c616e746963204f6365616e7374 + 726963746c7920737065616b696e672c73686f72746c79206265666f72652074 + 6865646966666572656e74207479706573206f66746865204f74746f6d616e20 + 456d706972653e3c696d67207372633d22687474703a2f2f416e20496e74726f + 64756374696f6e20746f636f6e73657175656e6365206f662074686564657061 + 72747572652066726f6d20746865436f6e666564657261746520537461746573 + 696e646967656e6f75732070656f706c657350726f63656564696e6773206f66 + 20746865696e666f726d6174696f6e206f6e207468657468656f726965732068 + 617665206265656e696e766f6c76656d656e7420696e20746865646976696465 + 6420696e746f20746872656561646a6163656e7420636f756e74726965736973 + 20726573706f6e7369626c6520666f72646973736f6c7574696f6e206f662074 + 6865636f6c6c61626f726174696f6e2077697468776964656c79207265676172 + 64656420617368697320636f6e74656d706f726172696573666f756e64696e67 + 206d656d626572206f66446f6d696e6963616e2052657075626c696367656e65 + 72616c6c7920616363657074656474686520706f73736962696c697479206f66 + 61726520616c736f20617661696c61626c65756e64657220636f6e7374727563 + 74696f6e726573746f726174696f6e206f66207468657468652067656e657261 + 6c207075626c6963697320616c6d6f737420656e746972656c79706173736573 + 207468726f75676820746865686173206265656e20737567676573746564636f + 6d707574657220616e6420766964656f4765726d616e6963206c616e67756167 + 6573206163636f7264696e6720746f2074686520646966666572656e74206672 + 6f6d2074686573686f72746c792061667465727761726473687265663d226874 + 7470733a2f2f7777772e726563656e7420646576656c6f706d656e74426f6172 + 64206f66204469726563746f72733c64697620636c6173733d22736561726368 + 7c203c6120687265663d22687474703a2f2f496e20706172746963756c61722c + 207468654d756c7469706c6520666f6f746e6f7465736f72206f746865722073 + 75627374616e636574686f7573616e6473206f662079656172737472616e736c + + + +Alakuijala & Szabadka Expires June 10, 2016 [Page 109] + +Internet-Draft Brotli December 2015 + + + 6174696f6e206f66207468653c2f6469763e0d0a3c2f6469763e0d0a0d0a3c61 + 20687265663d22696e6465782e7068707761732065737461626c697368656420 + 696e6d696e2e6a73223e3c2f7363726970743e0a706172746963697061746520 + 696e2074686561207374726f6e6720696e666c75656e63657374796c653d226d + 617267696e2d746f703a726570726573656e7465642062792074686567726164 + 75617465642066726f6d20746865547261646974696f6e616c6c792c20746865 + 456c656d656e74282273637269707422293b486f77657665722c2073696e6365 + 207468652f6469763e0a3c2f6469763e0a3c646976206c6566743b206d617267 + 696e2d6c6566743a70726f74656374696f6e20616761696e7374303b20766572 + 746963616c2d616c69676e3a556e666f7274756e6174656c792c207468657479 + 70653d22696d6167652f782d69636f6e2f6469763e0a3c64697620636c617373 + 3d2220636c6173733d22636c656172666978223e3c64697620636c6173733d22 + 666f6f74657209093c2f6469763e0a09093c2f6469763e0a746865206d6f7469 + 6f6e2070696374757265d091d18ad0bbd0b3d0b0d180d181d0bad0b8d0b1d18a + d0bbd0b3d0b0d180d181d0bad0b8d0a4d0b5d0b4d0b5d180d0b0d186d0b8d0b8 + d0bdd0b5d181d0bad0bed0bbd18cd0bad0bed181d0bed0bed0b1d189d0b5d0bd + d0b8d0b5d181d0bed0bed0b1d189d0b5d0bdd0b8d18fd0bfd180d0bed0b3d180 + d0b0d0bcd0bcd18bd09ed182d0bfd180d0b0d0b2d0b8d182d18cd0b1d0b5d181 + d0bfd0bbd0b0d182d0bdd0bed0bcd0b0d182d0b5d180d0b8d0b0d0bbd18bd0bf + d0bed0b7d0b2d0bed0bbd18fd0b5d182d0bfd0bed181d0bbd0b5d0b4d0bdd0b8 + d0b5d180d0b0d0b7d0bbd0b8d187d0bdd18bd185d0bfd180d0bed0b4d183d0ba + d186d0b8d0b8d0bfd180d0bed0b3d180d0b0d0bcd0bcd0b0d0bfd0bed0bbd0bd + d0bed181d182d18cd18ed0bdd0b0d185d0bed0b4d0b8d182d181d18fd0b8d0b7 + d0b1d180d0b0d0bdd0bdd0bed0b5d0bdd0b0d181d0b5d0bbd0b5d0bdd0b8d18f + d0b8d0b7d0bcd0b5d0bdd0b5d0bdd0b8d18fd0bad0b0d182d0b5d0b3d0bed180 + d0b8d0b8d090d0bbd0b5d0bad181d0b0d0bdd0b4d180e0a4a6e0a58de0a4b5e0 + a4bee0a4b0e0a4bee0a4aee0a588e0a4a8e0a581e0a485e0a4b2e0a4aae0a58d + e0a4b0e0a4a6e0a4bee0a4a8e0a4ade0a4bee0a4b0e0a4a4e0a580e0a4afe0a4 + 85e0a4a8e0a581e0a4a6e0a587e0a4b6e0a4b9e0a4bfe0a4a8e0a58de0a4a6e0 + a580e0a487e0a482e0a4a1e0a4bfe0a4afe0a4bee0a4a6e0a4bfe0a4b2e0a58d + e0a4b2e0a580e0a485e0a4a7e0a4bfe0a495e0a4bee0a4b0e0a4b5e0a580e0a4 + a1e0a4bfe0a4afe0a58be0a49ae0a4bfe0a49fe0a58de0a4a0e0a587e0a4b8e0 + a4aee0a4bee0a49ae0a4bee0a4b0e0a49ce0a482e0a495e0a58de0a4b6e0a4a8 + e0a4a6e0a581e0a4a8e0a4bfe0a4afe0a4bee0a4aae0a58de0a4b0e0a4afe0a5 + 8be0a497e0a485e0a4a8e0a581e0a4b8e0a4bee0a4b0e0a491e0a4a8e0a4b2e0 + a4bee0a487e0a4a8e0a4aae0a4bee0a4b0e0a58de0a49fe0a580e0a4b6e0a4b0 + e0a58de0a4a4e0a58be0a482e0a4b2e0a58be0a495e0a4b8e0a4ade0a4bee0a4 + abe0a4bce0a58de0a4b2e0a588e0a4b6e0a4b6e0a4b0e0a58de0a4a4e0a587e0 + a482e0a4aae0a58de0a4b0e0a4a6e0a587e0a4b6e0a4aae0a58de0a4b2e0a587 + e0a4afe0a4b0e0a495e0a587e0a482e0a4a6e0a58de0a4b0e0a4b8e0a58de0a4 + a5e0a4bfe0a4a4e0a4bfe0a489e0a4a4e0a58de0a4aae0a4bee0a4a6e0a489e0 + a4a8e0a58de0a4b9e0a587e0a482e0a49ae0a4bfe0a49fe0a58de0a4a0e0a4be + e0a4afe0a4bee0a4a4e0a58de0a4b0e0a4bee0a49ce0a58de0a4afe0a4bee0a4 + a6e0a4bee0a4aae0a581e0a4b0e0a4bee0a4a8e0a587e0a49ce0a58be0a4a1e0 + a4bce0a587e0a482e0a485e0a4a8e0a581e0a4b5e0a4bee0a4a6e0a4b6e0a58d + e0a4b0e0a587e0a4a3e0a580e0a4b6e0a4bfe0a495e0a58de0a4b7e0a4bee0a4 + b8e0a4b0e0a495e0a4bee0a4b0e0a580e0a4b8e0a482e0a497e0a58de0a4b0e0 + a4b9e0a4aae0a4b0e0a4bfe0a4a3e0a4bee0a4aee0a4ace0a58de0a4b0e0a4be + + + +Alakuijala & Szabadka Expires June 10, 2016 [Page 110] + +Internet-Draft Brotli December 2015 + + + e0a482e0a4a1e0a4ace0a49ae0a58de0a49ae0a58be0a482e0a489e0a4aae0a4 + b2e0a4ace0a58de0a4a7e0a4aee0a482e0a4a4e0a58de0a4b0e0a580e0a4b8e0 + a482e0a4aae0a4b0e0a58de0a495e0a489e0a4aee0a58de0a4aee0a580e0a4a6 + e0a4aee0a4bee0a4a7e0a58de0a4afe0a4aee0a4b8e0a4b9e0a4bee0a4afe0a4 + a4e0a4bee0a4b6e0a4ace0a58de0a4a6e0a58be0a482e0a4aee0a580e0a4a1e0 + a4bfe0a4afe0a4bee0a486e0a488e0a4aae0a580e0a48fe0a4b2e0a4aee0a58b + e0a4ace0a4bee0a487e0a4b2e0a4b8e0a482e0a496e0a58de0a4afe0a4bee0a4 + 86e0a4aae0a4b0e0a587e0a4b6e0a4a8e0a485e0a4a8e0a581e0a4ace0a482e0 + a4a7e0a4ace0a4bee0a49ce0a4bce0a4bee0a4b0e0a4a8e0a4b5e0a580e0a4a8 + e0a4a4e0a4aee0a4aae0a58de0a4b0e0a4aee0a581e0a496e0a4aae0a58de0a4 + b0e0a4b6e0a58de0a4a8e0a4aae0a4b0e0a4bfe0a4b5e0a4bee0a4b0e0a4a8e0 + a581e0a495e0a4b8e0a4bee0a4a8e0a4b8e0a4aee0a4b0e0a58de0a4a5e0a4a8 + e0a486e0a4afe0a58be0a49ce0a4bfe0a4a4e0a4b8e0a58be0a4aee0a4b5e0a4 + bee0a4b0d8a7d984d985d8b4d8a7d8b1d983d8a7d8aad8a7d984d985d986d8aa + d8afd98ad8a7d8aad8a7d984d983d985d8a8d98ad988d8aad8b1d8a7d984d985 + d8b4d8a7d987d8afd8a7d8aad8b9d8afd8afd8a7d984d8b2d988d8a7d8b1d8b9 + d8afd8afd8a7d984d8b1d8afd988d8afd8a7d984d8a5d8b3d984d8a7d985d98a + d8a9d8a7d984d981d988d8aad988d8b4d988d8a8d8a7d984d985d8b3d8a7d8a8 + d982d8a7d8aad8a7d984d985d8b9d984d988d985d8a7d8aad8a7d984d985d8b3 + d984d8b3d984d8a7d8aad8a7d984d8acd8b1d8a7d981d98ad983d8b3d8a7d984 + d8a7d8b3d984d8a7d985d98ad8a9d8a7d984d8a7d8aad8b5d8a7d984d8a7d8aa + 6b6579776f7264732220636f6e74656e743d2277332e6f72672f313939392f78 + 68746d6c223e3c61207461726765743d225f626c616e6b2220746578742f6874 + 6d6c3b20636861727365743d22207461726765743d225f626c616e6b223e3c74 + 61626c652063656c6c70616464696e673d226175746f636f6d706c6574653d22 + 6f66662220746578742d616c69676e3a2063656e7465723b746f206c61737420 + 76657273696f6e206279206261636b67726f756e642d636f6c6f723a20232220 + 687265663d22687474703a2f2f7777772e2f6469763e3c2f6469763e3c646976 + 2069643d3c6120687265663d22232220636c6173733d22223e3c696d67207372 + 633d22687474703a2f2f637269707422207372633d22687474703a2f2f0a3c73 + 6372697074206c616e67756167653d222f2f454e222022687474703a2f2f7777 + 772e77656e636f6465555249436f6d706f6e656e74282220687265663d226a61 + 76617363726970743a3c64697620636c6173733d22636f6e74656e74646f6375 + 6d656e742e777269746528273c7363706f736974696f6e3a206162736f6c7574 + 653b736372697074207372633d22687474703a2f2f207374796c653d226d6172 + 67696e2d746f703a2e6d696e2e6a73223e3c2f7363726970743e0a3c2f646976 + 3e0a3c64697620636c6173733d2277332e6f72672f313939392f7868746d6c22 + 200a0d0a3c2f626f64793e0d0a3c2f68746d6c3e64697374696e6374696f6e20 + 6265747765656e2f22207461726765743d225f626c616e6b223e3c6c696e6b20 + 687265663d22687474703a2f2f656e636f64696e673d227574662d38223f3e0a + 772e6164644576656e744c697374656e65723f616374696f6e3d22687474703a + 2f2f7777772e69636f6e2220687265663d22687474703a2f2f207374796c653d + 226261636b67726f756e643a747970653d22746578742f63737322202f3e0a6d + 6574612070726f70657274793d226f673a743c696e70757420747970653d2274 + 6578742220207374796c653d22746578742d616c69676e3a7468652064657665 + 6c6f706d656e74206f662074796c6573686565742220747970653d2274656874 + 6d6c3b20636861727365743d7574662d38697320636f6e736964657265642074 + 6f2062657461626c652077696474683d22313030252220496e20616464697469 + + + +Alakuijala & Szabadka Expires June 10, 2016 [Page 111] + +Internet-Draft Brotli December 2015 + + + 6f6e20746f2074686520636f6e747269627574656420746f2074686520646966 + 666572656e636573206265747765656e646576656c6f706d656e74206f662074 + 686520497420697320696d706f7274616e7420746f203c2f7363726970743e0a + 0a3c73637269707420207374796c653d22666f6e742d73697a653a313e3c2f73 + 70616e3e3c7370616e2069643d67624c696272617279206f6620436f6e677265 + 73733c696d67207372633d22687474703a2f2f696d456e676c69736820747261 + 6e736c6174696f6e41636164656d79206f6620536369656e6365736469762073 + 74796c653d22646973706c61793a636f6e737472756374696f6e206f66207468 + 652e676574456c656d656e744279496428696429696e20636f6e6a756e637469 + 6f6e2077697468456c656d656e74282773637269707427293b203c6d65746120 + 70726f70657274793d226f673ad091d18ad0bbd0b3d0b0d180d181d0bad0b80a + 20747970653d227465787422206e616d653d223e5072697661637920506f6c69 + 63793c2f613e61646d696e6973746572656420627920746865656e61626c6553 + 696e676c65526571756573747374796c653d2671756f743b6d617267696e3a3c + 2f6469763e3c2f6469763e3c2f6469763e3c3e3c696d67207372633d22687474 + 703a2f2f69207374796c653d2671756f743b666c6f61743a7265666572726564 + 20746f2061732074686520746f74616c20706f70756c6174696f6e206f66696e + 2057617368696e67746f6e2c20442e432e207374796c653d226261636b67726f + 756e642d616d6f6e67206f74686572207468696e67732c6f7267616e697a6174 + 696f6e206f662074686570617274696369706174656420696e20746865746865 + 20696e74726f64756374696f6e206f666964656e746966696564207769746820 + 74686566696374696f6e616c20636861726163746572204f78666f726420556e + 6976657273697479206d6973756e6465727374616e64696e67206f6654686572 + 65206172652c20686f77657665722c7374796c6573686565742220687265663d + 222f436f6c756d62696120556e6976657273697479657870616e64656420746f + 20696e636c756465757375616c6c7920726566657272656420746f696e646963 + 6174696e67207468617420746865686176652073756767657374656420746861 + 74616666696c6961746564207769746820746865636f7272656c6174696f6e20 + 6265747765656e6e756d626572206f6620646966666572656e743e3c2f74643e + 3c2f74723e3c2f7461626c653e52657075626c6963206f66204972656c616e64 + 0a3c2f7363726970743e0a3c73637269707420756e6465722074686520696e66 + 6c75656e6365636f6e747269627574696f6e20746f207468654f666669636961 + 6c2077656273697465206f66686561647175617274657273206f662074686563 + 656e74657265642061726f756e6420746865696d706c69636174696f6e73206f + 662074686568617665206265656e20646576656c6f7065644665646572616c20 + 52657075626c6963206f66626563616d6520696e6372656173696e676c79636f + 6e74696e756174696f6e206f66207468654e6f74652c20686f77657665722c20 + 7468617473696d696c617220746f2074686174206f66206361706162696c6974 + 696573206f66207468656163636f7264616e6365207769746820746865706172 + 7469636970616e747320696e207468656675727468657220646576656c6f706d + 656e74756e6465722074686520646972656374696f6e6973206f6674656e2063 + 6f6e7369646572656468697320796f756e6765722062726f746865723c2f7464 + 3e3c2f74723e3c2f7461626c653e3c6120687474702d65717569763d22582d55 + 412d706879736963616c2070726f706572746965736f66204272697469736820 + 436f6c756d626961686173206265656e20637269746963697a65642877697468 + 2074686520657863657074696f6e7175657374696f6e732061626f7574207468 + 6570617373696e67207468726f7567682074686530222063656c6c7061646469 + 6e673d2230222074686f7573616e6473206f662070656f706c65726564697265 + + + +Alakuijala & Szabadka Expires June 10, 2016 [Page 112] + +Internet-Draft Brotli December 2015 + + + 63747320686572652e20466f7268617665206368696c6472656e20756e646572 + 2533452533432f7363726970742533452229293b3c6120687265663d22687474 + 703a2f2f7777772e3c6c693e3c6120687265663d22687474703a2f2f73697465 + 5f6e616d652220636f6e74656e743d22746578742d6465636f726174696f6e3a + 6e6f6e657374796c653d22646973706c61793a206e6f6e653c6d657461206874 + 74702d65717569763d22582d6e6577204461746528292e67657454696d652829 + 20747970653d22696d6167652f782d69636f6e223c2f7370616e3e3c7370616e + 20636c6173733d226c616e67756167653d226a61766173637269707477696e64 + 6f772e6c6f636174696f6e2e687265663c6120687265663d226a617661736372 + 6970743a2d2d3e0d0a3c73637269707420747970653d22743c6120687265663d + 27687474703a2f2f7777772e686f72746375742069636f6e2220687265663d22 + 3c2f6469763e0d0a3c64697620636c6173733d223c736372697074207372633d + 22687474703a2f2f222072656c3d227374796c6573686565742220743c2f6469 + 763e0a3c73637269707420747970653d2f613e203c6120687265663d22687474 + 703a2f2f20616c6c6f775472616e73706172656e63793d22582d55412d436f6d + 70617469626c652220636f6e72656c6174696f6e73686970206265747765656e + 0a3c2f7363726970743e0d0a3c736372697074203c2f613e3c2f6c693e3c2f75 + 6c3e3c2f6469763e6173736f6369617465642077697468207468652070726f67 + 72616d6d696e67206c616e67756167653c2f613e3c6120687265663d22687474 + 703a2f2f3c2f613e3c2f6c693e3c6c6920636c6173733d22666f726d20616374 + 696f6e3d22687474703a2f2f3c646976207374796c653d22646973706c61793a + 747970653d227465787422206e616d653d2271223c7461626c65207769647468 + 3d223130302522206261636b67726f756e642d706f736974696f6e3a2220626f + 726465723d2230222077696474683d2272656c3d2273686f7274637574206963 + 6f6e222068363e3c756c3e3c6c693e3c6120687265663d2220203c6d65746120 + 687474702d65717569763d2263737322206d656469613d2273637265656e2220 + 726573706f6e7369626c6520666f7220746865202220747970653d226170706c + 69636174696f6e2f22207374796c653d226261636b67726f756e642d68746d6c + 3b20636861727365743d7574662d382220616c6c6f777472616e73706172656e + 63793d227374796c6573686565742220747970653d2274650d0a3c6d65746120 + 687474702d65717569763d223e3c2f7370616e3e3c7370616e20636c6173733d + 2230222063656c6c73706163696e673d2230223e3b0a3c2f7363726970743e0a + 3c73637269707420736f6d6574696d65732063616c6c656420746865646f6573 + 206e6f74206e65636573736172696c79466f72206d6f726520696e666f726d61 + 74696f6e61742074686520626567696e6e696e67206f66203c21444f43545950 + 452068746d6c3e3c68746d6c706172746963756c61726c7920696e2074686520 + 747970653d2268696464656e22206e616d653d226a6176617363726970743a76 + 6f69642830293b226566666563746976656e657373206f662074686520617574 + 6f636f6d706c6574653d226f6666222067656e6572616c6c7920636f6e736964 + 657265643e3c696e70757420747970653d22746578742220223e3c2f73637269 + 70743e0d0a3c7363726970747468726f7567686f75742074686520776f726c64 + 636f6d6d6f6e206d6973636f6e63657074696f6e6173736f63696174696f6e20 + 77697468207468653c2f6469763e0a3c2f6469763e0a3c646976206364757269 + 6e6720686973206c69666574696d652c636f72726573706f6e64696e6720746f + 20746865747970653d22696d6167652f782d69636f6e2220616e20696e637265 + 6173696e67206e756d6265726469706c6f6d617469632072656c6174696f6e73 + 617265206f6674656e20636f6e736964657265646d6574612063686172736574 + 3d227574662d3822203c696e70757420747970653d227465787422206578616d + + + +Alakuijala & Szabadka Expires June 10, 2016 [Page 113] + +Internet-Draft Brotli December 2015 + + + 706c657320696e636c75646520746865223e3c696d67207372633d2268747470 + 3a2f2f6970617274696369706174696f6e20696e207468657468652065737461 + 626c6973686d656e74206f660a3c2f6469763e0a3c64697620636c6173733d22 + 26616d703b6e6273703b26616d703b6e6273703b746f2064657465726d696e65 + 2077686574686572717569746520646966666572656e742066726f6d6d61726b + 65642074686520626567696e6e696e6764697374616e6365206265747765656e + 20746865636f6e747269627574696f6e7320746f20746865636f6e666c696374 + 206265747765656e20746865776964656c7920636f6e7369646572656420746f + 776173206f6e65206f6620746865206669727374776974682076617279696e67 + 2064656772656573686176652073706563756c61746564207468617428646f63 + 756d656e742e676574456c656d656e7470617274696369706174696e6720696e + 207468656f726967696e616c6c7920646576656c6f7065646574612063686172 + 7365743d227574662d38223e20747970653d22746578742f63737322202f3e0a + 696e7465726368616e676561626c7920776974686d6f726520636c6f73656c79 + 2072656c61746564736f6369616c20616e6420706f6c69746963616c74686174 + 20776f756c64206f746865727769736570657270656e646963756c617220746f + 207468657374796c6520747970653d22746578742f637373747970653d227375 + 626d697422206e616d653d2266616d696c696573207265736964696e6720696e + 646576656c6f70696e6720636f756e7472696573636f6d70757465722070726f + 6772616d6d696e6765636f6e6f6d696320646576656c6f706d656e7464657465 + 726d696e6174696f6e206f6620746865666f72206d6f726520696e666f726d61 + 74696f6e6f6e207365766572616c206f63636173696f6e73706f7274756775c3 + aa7320284575726f70657529d0a3d0bad180d0b0d197d0bdd181d18cd0bad0b0 + d183d0bad180d0b0d197d0bdd181d18cd0bad0b0d0a0d0bed181d181d0b8d0b9 + d181d0bad0bed0b9d0bcd0b0d182d0b5d180d0b8d0b0d0bbd0bed0b2d0b8d0bd + d184d0bed180d0bcd0b0d186d0b8d0b8d183d0bfd180d0b0d0b2d0bbd0b5d0bd + d0b8d18fd0bdd0b5d0bed0b1d185d0bed0b4d0b8d0bcd0bed0b8d0bdd184d0be + d180d0bcd0b0d186d0b8d18fd098d0bdd184d0bed180d0bcd0b0d186d0b8d18f + d0a0d0b5d181d0bfd183d0b1d0bbd0b8d0bad0b8d0bad0bed0bbd0b8d187d0b5 + d181d182d0b2d0bed0b8d0bdd184d0bed180d0bcd0b0d186d0b8d18ed182d0b5 + d180d180d0b8d182d0bed180d0b8d0b8d0b4d0bed181d182d0b0d182d0bed187 + d0bdd0bed8a7d984d985d8aad988d8a7d8acd8afd988d986d8a7d984d8a7d8b4 + d8aad8b1d8a7d983d8a7d8aad8a7d984d8a7d982d8aad8b1d8a7d8add8a7d8aa + 68746d6c3b20636861727365743d5554462d38222073657454696d656f757428 + 66756e6374696f6e2829646973706c61793a696e6c696e652d626c6f636b3b3c + 696e70757420747970653d227375626d6974222074797065203d202774657874 + 2f6a617661736372693c696d67207372633d22687474703a2f2f7777772e2220 + 22687474703a2f2f7777772e77332e6f72672f73686f72746375742069636f6e + 2220687265663d2222206175746f636f6d706c6574653d226f666622203c2f61 + 3e3c2f6469763e3c64697620636c6173733d3c2f613e3c2f6c693e0a3c6c6920 + 636c6173733d226373732220747970653d22746578742f63737322203c666f72 + 6d20616374696f6e3d22687474703a2f2f78742f6373732220687265663d2268 + 7474703a2f2f6c696e6b2072656c3d22616c7465726e61746522200d0a3c7363 + 7269707420747970653d22746578742f206f6e636c69636b3d226a6176617363 + 726970743a286e65772044617465292e67657454696d6528297d686569676874 + 3d2231222077696474683d2231222050656f706c6527732052657075626c6963 + 206f6620203c6120687265663d22687474703a2f2f7777772e746578742d6465 + 636f726174696f6e3a756e64657274686520626567696e6e696e67206f662074 + + + +Alakuijala & Szabadka Expires June 10, 2016 [Page 114] + +Internet-Draft Brotli December 2015 + + + 6865203c2f6469763e0a3c2f6469763e0a3c2f6469763e0a65737461626c6973 + 686d656e74206f6620746865203c2f6469763e3c2f6469763e3c2f6469763e3c + 2f642376696577706f72747b6d696e2d6865696768743a0a3c73637269707420 + 7372633d22687474703a2f2f6f7074696f6e3e3c6f7074696f6e2076616c7565 + 3d6f6674656e20726566657272656420746f206173202f6f7074696f6e3e0a3c + 6f7074696f6e2076616c753c21444f43545950452068746d6c3e0a3c212d2d5b + 496e7465726e6174696f6e616c20416972706f72743e0a3c6120687265663d22 + 687474703a2f2f7777773c2f613e3c6120687265663d22687474703a2f2f77e0 + b8a0e0b8b2e0b8a9e0b8b2e0b984e0b897e0b8a2e183a5e18390e183a0e18397 + e183a3e1839ae18398e6ada3e9ab94e4b8ade696872028e7b981e9ab9429e0a4 + a8e0a4bfe0a4b0e0a58de0a4a6e0a587e0a4b6e0a4a1e0a4bee0a489e0a4a8e0 + a4b2e0a58be0a4a1e0a495e0a58de0a4b7e0a587e0a4a4e0a58de0a4b0e0a49c + e0a4bee0a4a8e0a495e0a4bee0a4b0e0a580e0a4b8e0a482e0a4ace0a482e0a4 + a7e0a4bfe0a4a4e0a4b8e0a58de0a4a5e0a4bee0a4aae0a4a8e0a4bee0a4b8e0 + a58de0a4b5e0a580e0a495e0a4bee0a4b0e0a4b8e0a482e0a4b8e0a58de0a495 + e0a4b0e0a4a3e0a4b8e0a4bee0a4aee0a497e0a58de0a4b0e0a580e0a49ae0a4 + bfe0a49fe0a58de0a4a0e0a58be0a482e0a4b5e0a4bfe0a49ce0a58de0a49ee0 + a4bee0a4a8e0a485e0a4aee0a587e0a4b0e0a4bfe0a495e0a4bee0a4b5e0a4bf + e0a4ade0a4bfe0a4a8e0a58de0a4a8e0a497e0a4bee0a4a1e0a4bfe0a4afe0a4 + bee0a481e0a495e0a58de0a4afe0a58be0a482e0a495e0a4bfe0a4b8e0a581e0 + a4b0e0a495e0a58de0a4b7e0a4bee0a4aae0a4b9e0a581e0a481e0a49ae0a4a4 + e0a580e0a4aae0a58de0a4b0e0a4ace0a482e0a4a7e0a4a8e0a49fe0a4bfe0a4 + aae0a58de0a4aae0a4a3e0a580e0a495e0a58de0a4b0e0a4bfe0a495e0a587e0 + a49fe0a4aae0a58de0a4b0e0a4bee0a4b0e0a482e0a4ade0a4aae0a58de0a4b0 + e0a4bee0a4aae0a58de0a4a4e0a4aee0a4bee0a4b2e0a4bfe0a495e0a58be0a4 + 82e0a4b0e0a4abe0a4bce0a58de0a4a4e0a4bee0a4b0e0a4a8e0a4bfe0a4b0e0 + a58de0a4aee0a4bee0a4a3e0a4b2e0a4bfe0a4aee0a4bfe0a49fe0a587e0a4a1 + 6465736372697074696f6e2220636f6e74656e743d22646f63756d656e742e6c + 6f636174696f6e2e70726f742e676574456c656d656e747342795461674e616d + 65283c21444f43545950452068746d6c3e0a3c68746d6c203c6d657461206368 + 61727365743d227574662d38223e3a75726c2220636f6e74656e743d22687474 + 703a2f2f2e637373222072656c3d227374796c657368656574227374796c6520 + 747970653d22746578742f637373223e747970653d22746578742f6373732220 + 687265663d2277332e6f72672f313939392f7868746d6c2220786d6c74797065 + 3d22746578742f6a61766173637269707422206d6574686f643d226765742220 + 616374696f6e3d226c696e6b2072656c3d227374796c6573686565742220203d + 20646f63756d656e742e676574456c656d656e74747970653d22696d6167652f + 782d69636f6e22202f3e63656c6c70616464696e673d2230222063656c6c7370 + 2e6373732220747970653d22746578742f63737322203c2f613e3c2f6c693e3c + 6c693e3c6120687265663d22222077696474683d223122206865696768743d22 + 3122223e3c6120687265663d22687474703a2f2f7777772e7374796c653d2264 + 6973706c61793a6e6f6e653b223e616c7465726e6174652220747970653d2261 + 70706c692d2f2f5733432f2f445444205848544d4c20312e3020656c6c737061 + 63696e673d2230222063656c6c70616420747970653d2268696464656e222076 + 616c75653d222f613e266e6273703b3c7370616e20726f6c653d22730a3c696e + 70757420747970653d2268696464656e22206c616e67756167653d224a617661 + 536372697074222020646f63756d656e742e676574456c656d656e747342673d + 2230222063656c6c73706163696e673d223022207970653d22746578742f6373 + + + +Alakuijala & Szabadka Expires June 10, 2016 [Page 115] + +Internet-Draft Brotli December 2015 + + + 7322206d656469613d22747970653d27746578742f6a61766173637269707427 + 776974682074686520657863657074696f6e206f66207970653d22746578742f + 637373222072656c3d227374206865696768743d2231222077696474683d2231 + 22203d272b656e636f6465555249436f6d706f6e656e74283c6c696e6b207265 + 6c3d22616c7465726e61746522200a626f64792c2074722c20696e7075742c20 + 746578746d657461206e616d653d22726f626f74732220636f6e6d6574686f64 + 3d22706f73742220616374696f6e3d223e0a3c6120687265663d22687474703a + 2f2f7777772e637373222072656c3d227374796c65736865657422203c2f6469 + 763e3c2f6469763e3c64697620636c6173736c616e67756167653d226a617661 + 736372697074223e617269612d68696464656e3d2274727565223ec2b73c7269 + 70742220747970653d22746578742f6a617661736c3d303b7d2928293b0a2866 + 756e6374696f6e28297b6261636b67726f756e642d696d6167653a2075726c28 + 2f613e3c2f6c693e3c6c693e3c6120687265663d226809093c6c693e3c612068 + 7265663d22687474703a2f2f61746f722220617269612d68696464656e3d2274 + 72753e203c6120687265663d22687474703a2f2f7777772e6c616e6775616765 + 3d226a61766173637269707422202f6f7074696f6e3e0a3c6f7074696f6e2076 + 616c75652f6469763e3c2f6469763e3c64697620636c6173733d7261746f7222 + 20617269612d68696464656e3d227472653d286e65772044617465292e676574 + 54696d652829706f7274756775c3aa732028646f2042726173696c29d0bed180 + d0b3d0b0d0bdd0b8d0b7d0b0d186d0b8d0b8d0b2d0bed0b7d0bcd0bed0b6d0bd + d0bed181d182d18cd0bed0b1d180d0b0d0b7d0bed0b2d0b0d0bdd0b8d18fd180 + d0b5d0b3d0b8d181d182d180d0b0d186d0b8d0b8d0b2d0bed0b7d0bcd0bed0b6 + d0bdd0bed181d182d0b8d0bed0b1d18fd0b7d0b0d182d0b5d0bbd18cd0bdd0b0 + 3c21444f43545950452068746d6c205055424c494320226e742d547970652220 + 636f6e74656e743d22746578742f3c6d65746120687474702d65717569763d22 + 436f6e746572616e736974696f6e616c2f2f454e222022687474703a3c68746d + 6c20786d6c6e733d22687474703a2f2f7777772d2f2f5733432f2f4454442058 + 48544d4c20312e3020544454442f7868746d6c312d7472616e736974696f6e61 + 6c2f2f7777772e77332e6f72672f54522f7868746d6c312f7065203d20277465 + 78742f6a617661736372697074273b3c6d657461206e616d653d226465736372 + 697074696f6e706172656e744e6f64652e696e736572744265666f72653c696e + 70757420747970653d2268696464656e22206e616a732220747970653d227465 + 78742f6a6176617363726928646f63756d656e74292e72656164792866756e63 + 746973637269707420747970653d22746578742f6a61766173696d6167652220 + 636f6e74656e743d22687474703a2f2f55412d436f6d70617469626c65222063 + 6f6e74656e743d746d6c3b20636861727365743d7574662d3822202f3e0a6c69 + 6e6b2072656c3d2273686f72746375742069636f6e3c6c696e6b2072656c3d22 + 7374796c65736865657422203c2f7363726970743e0a3c736372697074207479 + 70653d3d20646f63756d656e742e637265617465456c656d656e3c6120746172 + 6765743d225f626c616e6b2220687265663d20646f63756d656e742e67657445 + 6c656d656e747342696e70757420747970653d227465787422206e616d653d61 + 2e74797065203d2027746578742f6a617661736372696e70757420747970653d + 2268696464656e22206e616d6568746d6c3b20636861727365743d7574662d38 + 22202f3e647464223e0a3c68746d6c20786d6c6e733d22687474702d2f2f5733 + 432f2f4454442048544d4c20342e30312054656e747342795461674e616d6528 + 277363726970742729696e70757420747970653d2268696464656e22206e616d + 3c73637269707420747970653d22746578742f6a6176617322207374796c653d + 22646973706c61793a6e6f6e653b223e646f63756d656e742e676574456c656d + + + +Alakuijala & Szabadka Expires June 10, 2016 [Page 116] + +Internet-Draft Brotli December 2015 + + + 656e7442794964283d646f63756d656e742e637265617465456c656d656e7428 + 2720747970653d27746578742f6a61766173637269707427696e707574207479 + 70653d227465787422206e616d653d22642e676574456c656d656e7473427954 + 61674e616d6528736e6963616c2220687265663d22687474703a2f2f7777772e + 432f2f4454442048544d4c20342e3031205472616e7369743c7374796c652074 + 7970653d22746578742f637373223e0a0a3c7374796c6520747970653d227465 + 78742f637373223e696f6e616c2e647464223e0a3c68746d6c20786d6c6e733d + 687474702d65717569763d22436f6e74656e742d5479706564696e673d223022 + 2063656c6c73706163696e673d22302268746d6c3b20636861727365743d7574 + 662d3822202f3e0a207374796c653d22646973706c61793a6e6f6e653b223e3c + 3c6c693e3c6120687265663d22687474703a2f2f7777772e20747970653d2774 + 6578742f6a617661736372697074273ed0b4d0b5d18fd182d0b5d0bbd18cd0bd + d0bed181d182d0b8d181d0bed0bed182d0b2d0b5d182d181d182d0b2d0b8d0b8 + d0bfd180d0bed0b8d0b7d0b2d0bed0b4d181d182d0b2d0b0d0b1d0b5d0b7d0be + d0bfd0b0d181d0bdd0bed181d182d0b8e0a4aae0a581e0a4b8e0a58de0a4a4e0 + a4bfe0a495e0a4bee0a495e0a4bee0a482e0a497e0a58de0a4b0e0a587e0a4b8 + e0a489e0a4a8e0a58de0a4b9e0a58be0a482e0a4a8e0a587e0a4b5e0a4bfe0a4 + a7e0a4bee0a4a8e0a4b8e0a4ade0a4bee0a4abe0a4bfe0a495e0a58de0a4b8e0 + a4bfe0a482e0a497e0a4b8e0a581e0a4b0e0a495e0a58de0a4b7e0a4bfe0a4a4 + e0a495e0a589e0a4aae0a580e0a4b0e0a4bee0a487e0a49fe0a4b5e0a4bfe0a4 + 9ce0a58de0a49ee0a4bee0a4aae0a4a8e0a495e0a4bee0a4b0e0a58de0a4b0e0 + a4b5e0a4bee0a488e0a4b8e0a495e0a58de0a4b0e0a4bfe0a4afe0a4a4e0a4be + + The number of words for each length is given by the following + bit-depth array: + + NDBITS := 0, 0, 0, 0, 10, 10, 11, 11, 10, 10, + 10, 10, 10, 9, 9, 8, 7, 7, 8, 7, + 7, 6, 6, 5, 5 + +Appendix B. List of word transformations + +The string literals are in C format, with respect to the use of +backslash escape characters. + +In order to generate a length and check value, the transforms can be +converted to a series of bytes, where each transform is the prefix +sequence of bytes plus a terminating zero byte, a single byte value +identifying the transform, and the suffix sequence of bytes plus a +terminating zero. The value for the transforms are 0 for Identity, 1 for +UppercaseFirst, 2 for UppercaseAll, 3 to 11 for OmitFirst1 to +OmitFirst9, and 12 to 20 for OmitLast1 to OmitLast9. The byte sequences +that represent the 121 transforms are then concatenated to a single +sequence of bytes. The length of that sequence is 648 bytes, and the +zlib CRC is 0x3d965f81. + + ID Prefix Transform Suffix + -- ------ --------- ------ + + + +Alakuijala & Szabadka Expires June 10, 2016 [Page 117] + +Internet-Draft Brotli December 2015 + + + 0 "" Identity "" + 1 "" Identity " " + 2 " " Identity " " + 3 "" OmitFirst1 "" + 4 "" UppercaseFirst " " + 5 "" Identity " the " + 6 " " Identity "" + 7 "s " Identity " " + 8 "" Identity " of " + 9 "" UppercaseFirst "" + 10 "" Identity " and " + 11 "" OmitFirst2 "" + 12 "" OmitLast1 "" + 13 ", " Identity " " + 14 "" Identity ", " + 15 " " UppercaseFirst " " + 16 "" Identity " in " + 17 "" Identity " to " + 18 "e " Identity " " + 19 "" Identity "\"" + 20 "" Identity "." + 21 "" Identity "\">" + 22 "" Identity "\n" + 23 "" OmitLast3 "" + 24 "" Identity "]" + 25 "" Identity " for " + 26 "" OmitFirst3 "" + 27 "" OmitLast2 "" + 28 "" Identity " a " + 29 "" Identity " that " + 30 " " UppercaseFirst "" + 31 "" Identity ". " + 32 "." Identity "" + 33 " " Identity ", " + 34 "" OmitFirst4 "" + 35 "" Identity " with " + 36 "" Identity "'" + 37 "" Identity " from " + 38 "" Identity " by " + 39 "" OmitFirst5 "" + 40 "" OmitFirst6 "" + 41 " the " Identity "" + 42 "" OmitLast4 "" + 43 "" Identity ". The " + 44 "" UppercaseAll "" + 45 "" Identity " on " + 46 "" Identity " as " + 47 "" Identity " is " + + + +Alakuijala & Szabadka Expires June 10, 2016 [Page 118] + +Internet-Draft Brotli December 2015 + + + 48 "" OmitLast7 "" + 49 "" OmitLast1 "ing " + 50 "" Identity "\n\t" + 51 "" Identity ":" + 52 " " Identity ". " + 53 "" Identity "ed " + 54 "" OmitFirst9 "" + 55 "" OmitFirst7 "" + 56 "" OmitLast6 "" + 57 "" Identity "(" + 58 "" UppercaseFirst ", " + 59 "" OmitLast8 "" + 60 "" Identity " at " + 61 "" Identity "ly " + 62 " the " Identity " of " + 63 "" OmitLast5 "" + 64 "" OmitLast9 "" + 65 " " UppercaseFirst ", " + 66 "" UppercaseFirst "\"" + 67 "." Identity "(" + 68 "" UppercaseAll " " + 69 "" UppercaseFirst "\">" + 70 "" Identity "=\"" + 71 " " Identity "." + 72 ".com/" Identity "" + 73 " the " Identity " of the " + 74 "" UppercaseFirst "'" + 75 "" Identity ". This " + 76 "" Identity "," + 77 "." Identity " " + 78 "" UppercaseFirst "(" + 79 "" UppercaseFirst "." + 80 "" Identity " not " + 81 " " Identity "=\"" + 82 "" Identity "er " + 83 " " UppercaseAll " " + 84 "" Identity "al " + 85 " " UppercaseAll "" + 86 "" Identity "='" + 87 "" UppercaseAll "\"" + 88 "" UppercaseFirst ". " + 89 " " Identity "(" + 90 "" Identity "ful " + 91 " " UppercaseFirst ". " + 92 "" Identity "ive " + 93 "" Identity "less " + 94 "" UppercaseAll "'" + 95 "" Identity "est " + + + +Alakuijala & Szabadka Expires June 10, 2016 [Page 119] + +Internet-Draft Brotli December 2015 + + + 96 " " UppercaseFirst "." + 97 "" UppercaseAll "\">" + 98 " " Identity "='" + 99 "" UppercaseFirst "," + 100 "" Identity "ize " + 101 "" UppercaseAll "." + 102 "\xc2\xa0" Identity "" + 103 " " Identity "," + 104 "" UppercaseFirst "=\"" + 105 "" UppercaseAll "=\"" + 106 "" Identity "ous " + 107 "" UppercaseAll ", " + 108 "" UppercaseFirst "='" + 109 " " UppercaseFirst "," + 110 " " UppercaseAll "=\"" + 111 " " UppercaseAll ", " + 112 "" UppercaseAll "," + 113 "" UppercaseAll "(" + 114 "" UppercaseAll ". " + 115 " " UppercaseAll "." + 116 "" UppercaseAll "='" + 117 " " UppercaseAll ". " + 118 " " UppercaseFirst "=\"" + 119 " " UppercaseAll "='" + 120 " " UppercaseFirst "='" + + +Authors' Addresses + + Jyrki Alakuijala + Google, Inc + + Email: jyrki@google.com + + + Zoltan Szabadka + Google, Inc + + Email: szabadka@google.com + + + + + + + + + + + + +Alakuijala & Szabadka Expires June 10, 2016 [Page 120] + diff --git a/web/server/h2o/libh2o/deps/brotli/enc/Makefile b/web/server/h2o/libh2o/deps/brotli/enc/Makefile new file mode 100644 index 00000000..a43d4c21 --- /dev/null +++ b/web/server/h2o/libh2o/deps/brotli/enc/Makefile @@ -0,0 +1,14 @@ +#brotli/enc + +include ../shared.mk + +OBJS_NODICT = backward_references.o block_splitter.o brotli_bit_stream.o compress_fragment.o compress_fragment_two_pass.o encode.o encode_parallel.o entropy_encode.o histogram.o literal_cost.o metablock.o static_dict.o streams.o utf8_util.o +OBJS = $(OBJS_NODICT) dictionary.o + +nodict : $(OBJS_NODICT) + +all : $(OBJS) + +clean : + rm -f $(OBJS) $(SO) + diff --git a/web/server/h2o/libh2o/deps/brotli/enc/backward_references.cc b/web/server/h2o/libh2o/deps/brotli/enc/backward_references.cc new file mode 100644 index 00000000..02d956dd --- /dev/null +++ b/web/server/h2o/libh2o/deps/brotli/enc/backward_references.cc @@ -0,0 +1,783 @@ +/* Copyright 2013 Google Inc. All Rights Reserved. + + Distributed under MIT license. + See file LICENSE for detail or copy at https://opensource.org/licenses/MIT +*/ + +// Function to find backward reference copies. + +#include "./backward_references.h" + +#include +#include +#include + +#include "./command.h" +#include "./fast_log.h" +#include "./literal_cost.h" + +namespace brotli { + +// The maximum length for which the zopflification uses distinct distances. +static const uint16_t kMaxZopfliLen = 325; + +static const double kInfinity = std::numeric_limits::infinity(); + +// Histogram based cost model for zopflification. +class ZopfliCostModel { + public: + ZopfliCostModel() : min_cost_cmd_(kInfinity) {} + + void SetFromCommands(size_t num_bytes, + size_t position, + const uint8_t* ringbuffer, + size_t ringbuffer_mask, + const Command* commands, + size_t num_commands, + size_t last_insert_len) { + std::vector histogram_literal(256, 0); + std::vector histogram_cmd(kNumCommandPrefixes, 0); + std::vector histogram_dist(kNumDistancePrefixes, 0); + + size_t pos = position - last_insert_len; + for (size_t i = 0; i < num_commands; i++) { + size_t inslength = commands[i].insert_len_; + size_t copylength = commands[i].copy_len_; + size_t distcode = commands[i].dist_prefix_; + size_t cmdcode = commands[i].cmd_prefix_; + + histogram_cmd[cmdcode]++; + if (cmdcode >= 128) histogram_dist[distcode]++; + + for (size_t j = 0; j < inslength; j++) { + histogram_literal[ringbuffer[(pos + j) & ringbuffer_mask]]++; + } + + pos += inslength + copylength; + } + + std::vector cost_literal; + Set(histogram_literal, &cost_literal); + Set(histogram_cmd, &cost_cmd_); + Set(histogram_dist, &cost_dist_); + + for (uint32_t i = 0; i < kNumCommandPrefixes; ++i) { + min_cost_cmd_ = std::min(min_cost_cmd_, cost_cmd_[i]); + } + + literal_costs_.resize(num_bytes + 1); + literal_costs_[0] = 0.0; + for (size_t i = 0; i < num_bytes; ++i) { + literal_costs_[i + 1] = literal_costs_[i] + + cost_literal[ringbuffer[(position + i) & ringbuffer_mask]]; + } + } + + void SetFromLiteralCosts(size_t num_bytes, + size_t position, + const uint8_t* ringbuffer, + size_t ringbuffer_mask) { + std::vector literal_cost(num_bytes + 1); + EstimateBitCostsForLiterals(position, num_bytes, ringbuffer_mask, + ringbuffer, &literal_cost[0]); + literal_costs_.resize(num_bytes + 1); + literal_costs_[0] = 0.0; + for (size_t i = 0; i < num_bytes; ++i) { + literal_costs_[i + 1] = literal_costs_[i] + literal_cost[i]; + } + cost_cmd_.resize(kNumCommandPrefixes); + cost_dist_.resize(kNumDistancePrefixes); + for (uint32_t i = 0; i < kNumCommandPrefixes; ++i) { + cost_cmd_[i] = FastLog2(11 + i); + } + for (uint32_t i = 0; i < kNumDistancePrefixes; ++i) { + cost_dist_[i] = FastLog2(20 + i); + } + min_cost_cmd_ = FastLog2(11); + } + + double GetCommandCost( + size_t dist_code, size_t length_code, size_t insert_length) const { + uint16_t inscode = GetInsertLengthCode(insert_length); + uint16_t copycode = GetCopyLengthCode(length_code); + uint16_t cmdcode = CombineLengthCodes(inscode, copycode, dist_code == 0); + uint16_t dist_symbol; + uint32_t distextra; + PrefixEncodeCopyDistance(dist_code, 0, 0, &dist_symbol, &distextra); + uint32_t distnumextra = distextra >> 24; + + double result = static_cast( + kInsExtra[inscode] + kCopyExtra[copycode] + distnumextra); + result += cost_cmd_[cmdcode]; + if (cmdcode >= 128) result += cost_dist_[dist_symbol]; + return result; + } + + double GetLiteralCosts(size_t from, size_t to) const { + return literal_costs_[to] - literal_costs_[from]; + } + + double GetMinCostCmd() const { + return min_cost_cmd_; + } + + private: + void Set(const std::vector& histogram, std::vector* cost) { + cost->resize(histogram.size()); + size_t sum = 0; + for (size_t i = 0; i < histogram.size(); i++) { + sum += histogram[i]; + } + double log2sum = FastLog2(sum); + for (size_t i = 0; i < histogram.size(); i++) { + if (histogram[i] == 0) { + (*cost)[i] = log2sum + 2; + continue; + } + + // Shannon bits for this symbol. + (*cost)[i] = log2sum - FastLog2(histogram[i]); + + // Cannot be coded with less than 1 bit + if ((*cost)[i] < 1) (*cost)[i] = 1; + } + } + + std::vector cost_cmd_; // The insert and copy length symbols. + std::vector cost_dist_; + // Cumulative costs of literals per position in the stream. + std::vector literal_costs_; + double min_cost_cmd_; +}; + +inline void SetDistanceCache(size_t distance, + size_t distance_code, + size_t max_distance, + const int* dist_cache, + int* result_dist_cache) { + if (distance <= max_distance && distance_code > 0) { + result_dist_cache[0] = static_cast(distance); + memcpy(&result_dist_cache[1], dist_cache, 3 * sizeof(dist_cache[0])); + } else { + memcpy(result_dist_cache, dist_cache, 4 * sizeof(dist_cache[0])); + } +} + +inline size_t ComputeDistanceCode(size_t distance, + size_t max_distance, + int quality, + const int* dist_cache) { + if (distance <= max_distance) { + if (distance == static_cast(dist_cache[0])) { + return 0; + } else if (distance == static_cast(dist_cache[1])) { + return 1; + } else if (distance == static_cast(dist_cache[2])) { + return 2; + } else if (distance == static_cast(dist_cache[3])) { + return 3; + } else if (quality > 3 && distance >= 6) { + for (size_t k = 4; k < kNumDistanceShortCodes; ++k) { + size_t idx = kDistanceCacheIndex[k]; + size_t candidate = + static_cast(dist_cache[idx] + kDistanceCacheOffset[k]); + static const size_t kLimits[16] = { 0, 0, 0, 0, + 6, 6, 11, 11, + 11, 11, 11, 11, + 12, 12, 12, 12 }; + if (distance == candidate && distance >= kLimits[k]) { + return k; + } + } + } + } + return distance + 15; +} + +struct ZopfliNode { + ZopfliNode() : length(1), + distance(0), + distance_code(0), + length_code(0), + insert_length(0), + cost(kInfinity) {} + + // best length to get up to this byte (not including this byte itself) + uint32_t length; + // distance associated with the length + uint32_t distance; + uint32_t distance_code; + int distance_cache[4]; + // length code associated with the length - usually the same as length, + // except in case of length-changing dictionary transformation. + uint32_t length_code; + // number of literal inserts before this copy + uint32_t insert_length; + // smallest cost to get to this byte from the beginning, as found so far + double cost; +}; + +inline void UpdateZopfliNode(ZopfliNode* nodes, size_t pos, size_t start_pos, + size_t len, size_t len_code, size_t dist, + size_t dist_code, size_t max_dist, + const int* dist_cache, double cost) { + ZopfliNode& next = nodes[pos + len]; + next.length = static_cast(len); + next.length_code = static_cast(len_code); + next.distance = static_cast(dist); + next.distance_code = static_cast(dist_code); + next.insert_length = static_cast(pos - start_pos); + next.cost = cost; + SetDistanceCache(dist, dist_code, max_dist, dist_cache, + &next.distance_cache[0]); +} + +// Maintains the smallest 2^k cost difference together with their positions +class StartPosQueue { + public: + explicit StartPosQueue(int bits) + : mask_((1u << bits) - 1), q_(1 << bits), idx_(0) {} + + void Clear() { + idx_ = 0; + } + + void Push(size_t pos, double costdiff) { + if (costdiff == kInfinity) { + // We can't start a command from an unreachable start position. + // E.g. position 1 in a stream is always unreachable, because all commands + // have a copy of at least length 2. + return; + } + size_t offset = -idx_ & mask_; + ++idx_; + size_t len = size(); + q_[offset] = std::make_pair(pos, costdiff); + /* Restore the sorted order. In the list of |len| items at most |len - 1| + adjacent element comparisons / swaps are required. */ + for (size_t i = 1; i < len; ++i) { + if (q_[offset & mask_].second > q_[(offset + 1) & mask_].second) { + std::swap(q_[offset & mask_], q_[(offset + 1) & mask_]); + } + ++offset; + } + } + + size_t size() const { return std::min(idx_, mask_ + 1); } + + size_t GetStartPos(size_t k) const { + return q_[(k + 1 - idx_) & mask_].first; + } + + private: + const size_t mask_; + std::vector > q_; + size_t idx_; +}; + +// Returns the minimum possible copy length that can improve the cost of any +// future position. +size_t ComputeMinimumCopyLength(const StartPosQueue& queue, + const std::vector& nodes, + const ZopfliCostModel& model, + size_t pos, + double min_cost_cmd) { + // Compute the minimum possible cost of reaching any future position. + const size_t start0 = queue.GetStartPos(0); + double min_cost = (nodes[start0].cost + + model.GetLiteralCosts(start0, pos) + + min_cost_cmd); + size_t len = 2; + size_t next_len_bucket = 4; + size_t next_len_offset = 10; + while (pos + len < nodes.size() && nodes[pos + len].cost <= min_cost) { + // We already reached (pos + len) with no more cost than the minimum + // possible cost of reaching anything from this pos, so there is no point in + // looking for lengths <= len. + ++len; + if (len == next_len_offset) { + // We reached the next copy length code bucket, so we add one more + // extra bit to the minimum cost. + min_cost += 1.0; + next_len_offset += next_len_bucket; + next_len_bucket *= 2; + } + } + return len; +} + +void ZopfliIterate(size_t num_bytes, + size_t position, + const uint8_t* ringbuffer, + size_t ringbuffer_mask, + const size_t max_backward_limit, + const ZopfliCostModel& model, + const std::vector& num_matches, + const std::vector& matches, + int* dist_cache, + size_t* last_insert_len, + Command* commands, + size_t* num_commands, + size_t* num_literals) { + const Command * const orig_commands = commands; + + std::vector nodes(num_bytes + 1); + nodes[0].length = 0; + nodes[0].cost = 0; + memcpy(nodes[0].distance_cache, dist_cache, 4 * sizeof(dist_cache[0])); + + StartPosQueue queue(3); + const double min_cost_cmd = model.GetMinCostCmd(); + + size_t cur_match_pos = 0; + for (size_t i = 0; i + 3 < num_bytes; i++) { + size_t cur_ix = position + i; + size_t cur_ix_masked = cur_ix & ringbuffer_mask; + size_t max_distance = std::min(cur_ix, max_backward_limit); + size_t max_length = num_bytes - i; + + queue.Push(i, nodes[i].cost - model.GetLiteralCosts(0, i)); + + const size_t min_len = ComputeMinimumCopyLength(queue, nodes, model, + i, min_cost_cmd); + + // Go over the command starting positions in order of increasing cost + // difference. + for (size_t k = 0; k < 5 && k < queue.size(); ++k) { + const size_t start = queue.GetStartPos(k); + const double start_costdiff = + nodes[start].cost - model.GetLiteralCosts(0, start); + const int* dist_cache2 = &nodes[start].distance_cache[0]; + + // Look for last distance matches using the distance cache from this + // starting position. + size_t best_len = min_len - 1; + for (size_t j = 0; j < kNumDistanceShortCodes; ++j) { + const size_t idx = kDistanceCacheIndex[j]; + const size_t backward = + static_cast(dist_cache2[idx] + kDistanceCacheOffset[j]); + size_t prev_ix = cur_ix - backward; + if (prev_ix >= cur_ix) { + continue; + } + if (PREDICT_FALSE(backward > max_distance)) { + continue; + } + prev_ix &= ringbuffer_mask; + + if (cur_ix_masked + best_len > ringbuffer_mask || + prev_ix + best_len > ringbuffer_mask || + ringbuffer[cur_ix_masked + best_len] != + ringbuffer[prev_ix + best_len]) { + continue; + } + const size_t len = + FindMatchLengthWithLimit(&ringbuffer[prev_ix], + &ringbuffer[cur_ix_masked], + max_length); + for (size_t l = best_len + 1; l <= len; ++l) { + const size_t inslen = i - start; + double cmd_cost = model.GetCommandCost(j, l, inslen); + double cost = start_costdiff + cmd_cost + model.GetLiteralCosts(0, i); + if (cost < nodes[i + l].cost) { + UpdateZopfliNode(&nodes[0], i, start, l, l, backward, j, + max_distance, dist_cache2, cost); + } + best_len = l; + } + } + + // At higher iterations look only for new last distance matches, since + // looking only for new command start positions with the same distances + // does not help much. + if (k >= 2) continue; + + // Loop through all possible copy lengths at this position. + size_t len = min_len; + for (size_t j = 0; j < num_matches[i]; ++j) { + BackwardMatch match = matches[cur_match_pos + j]; + size_t dist = match.distance; + bool is_dictionary_match = dist > max_distance; + // We already tried all possible last distance matches, so we can use + // normal distance code here. + size_t dist_code = dist + 15; + // Try all copy lengths up until the maximum copy length corresponding + // to this distance. If the distance refers to the static dictionary, or + // the maximum length is long enough, try only one maximum length. + size_t max_len = match.length(); + if (len < max_len && (is_dictionary_match || max_len > kMaxZopfliLen)) { + len = max_len; + } + for (; len <= max_len; ++len) { + size_t len_code = is_dictionary_match ? match.length_code() : len; + const size_t inslen = i - start; + double cmd_cost = model.GetCommandCost(dist_code, len_code, inslen); + double cost = start_costdiff + cmd_cost + model.GetLiteralCosts(0, i); + if (cost < nodes[i + len].cost) { + UpdateZopfliNode(&nodes[0], i, start, len, len_code, dist, + dist_code, max_distance, dist_cache2, cost); + } + } + } + } + + cur_match_pos += num_matches[i]; + + // The zopflification can be too slow in case of very long lengths, so in + // such case skip it all, it does not cost a lot of compression ratio. + if (num_matches[i] == 1 && + matches[cur_match_pos - 1].length() > kMaxZopfliLen) { + i += matches[cur_match_pos - 1].length() - 1; + queue.Clear(); + } + } + + std::vector backwards; + size_t index = num_bytes; + while (nodes[index].cost == kInfinity) --index; + while (index != 0) { + size_t len = nodes[index].length + nodes[index].insert_length; + backwards.push_back(static_cast(len)); + index -= len; + } + + std::vector path; + for (size_t i = backwards.size(); i > 0; i--) { + path.push_back(backwards[i - 1]); + } + + size_t pos = 0; + for (size_t i = 0; i < path.size(); i++) { + const ZopfliNode& next = nodes[pos + path[i]]; + size_t copy_length = next.length; + size_t insert_length = next.insert_length; + pos += insert_length; + if (i == 0) { + insert_length += *last_insert_len; + *last_insert_len = 0; + } + size_t distance = next.distance; + size_t len_code = next.length_code; + size_t max_distance = std::min(position + pos, max_backward_limit); + bool is_dictionary = (distance > max_distance); + size_t dist_code = next.distance_code; + + Command cmd(insert_length, copy_length, len_code, dist_code); + *commands++ = cmd; + + if (!is_dictionary && dist_code > 0) { + dist_cache[3] = dist_cache[2]; + dist_cache[2] = dist_cache[1]; + dist_cache[1] = dist_cache[0]; + dist_cache[0] = static_cast(distance); + } + + *num_literals += insert_length; + insert_length = 0; + pos += copy_length; + } + *last_insert_len += num_bytes - pos; + *num_commands += static_cast(commands - orig_commands); +} + +template +void CreateBackwardReferences(size_t num_bytes, + size_t position, + bool is_last, + const uint8_t* ringbuffer, + size_t ringbuffer_mask, + const int quality, + const int lgwin, + Hasher* hasher, + int* dist_cache, + size_t* last_insert_len, + Command* commands, + size_t* num_commands, + size_t* num_literals) { + // Set maximum distance, see section 9.1. of the spec. + const size_t max_backward_limit = (1 << lgwin) - 16; + + // Choose which init method is faster. + // memset is about 100 times faster than hasher->InitForData(). + const size_t kMaxBytesForPartialHashInit = Hasher::kHashMapSize >> 7; + if (position == 0 && is_last && num_bytes <= kMaxBytesForPartialHashInit) { + hasher->InitForData(ringbuffer, num_bytes); + } else { + hasher->Init(); + } + if (num_bytes >= 3 && position >= 3) { + // Prepare the hashes for three last bytes of the last write. + // These could not be calculated before, since they require knowledge + // of both the previous and the current block. + hasher->Store(&ringbuffer[(position - 3) & ringbuffer_mask], + static_cast(position - 3)); + hasher->Store(&ringbuffer[(position - 2) & ringbuffer_mask], + static_cast(position - 2)); + hasher->Store(&ringbuffer[(position - 1) & ringbuffer_mask], + static_cast(position - 1)); + } + const Command * const orig_commands = commands; + size_t insert_length = *last_insert_len; + size_t i = position & ringbuffer_mask; + const size_t i_diff = position - i; + const size_t i_end = i + num_bytes; + + // For speed up heuristics for random data. + const size_t random_heuristics_window_size = quality < 9 ? 64 : 512; + size_t apply_random_heuristics = i + random_heuristics_window_size; + + // Minimum score to accept a backward reference. + const int kMinScore = 4.0; + + while (i + Hasher::kHashTypeLength - 1 < i_end) { + size_t max_length = i_end - i; + size_t max_distance = std::min(i + i_diff, max_backward_limit); + size_t best_len = 0; + size_t best_len_code = 0; + size_t best_dist = 0; + double best_score = kMinScore; + bool match_found = hasher->FindLongestMatch( + ringbuffer, ringbuffer_mask, + dist_cache, static_cast(i + i_diff), max_length, max_distance, + &best_len, &best_len_code, &best_dist, &best_score); + if (match_found) { + // Found a match. Let's look for something even better ahead. + int delayed_backward_references_in_row = 0; + for (;;) { + --max_length; + size_t best_len_2 = + quality < 5 ? std::min(best_len - 1, max_length) : 0; + size_t best_len_code_2 = 0; + size_t best_dist_2 = 0; + double best_score_2 = kMinScore; + max_distance = std::min(i + i_diff + 1, max_backward_limit); + match_found = hasher->FindLongestMatch( + ringbuffer, ringbuffer_mask, + dist_cache, static_cast(i + i_diff + 1), + max_length, max_distance, + &best_len_2, &best_len_code_2, &best_dist_2, &best_score_2); + double cost_diff_lazy = 7.0; + if (match_found && best_score_2 >= best_score + cost_diff_lazy) { + // Ok, let's just write one byte for now and start a match from the + // next byte. + ++i; + ++insert_length; + best_len = best_len_2; + best_len_code = best_len_code_2; + best_dist = best_dist_2; + best_score = best_score_2; + if (++delayed_backward_references_in_row < 4) { + continue; + } + } + break; + } + apply_random_heuristics = + i + 2 * best_len + random_heuristics_window_size; + max_distance = std::min(i + i_diff, max_backward_limit); + // The first 16 codes are special shortcodes, and the minimum offset is 1. + size_t distance_code = + ComputeDistanceCode(best_dist, max_distance, quality, dist_cache); + if (best_dist <= max_distance && distance_code > 0) { + dist_cache[3] = dist_cache[2]; + dist_cache[2] = dist_cache[1]; + dist_cache[1] = dist_cache[0]; + dist_cache[0] = static_cast(best_dist); + } + Command cmd(insert_length, best_len, best_len_code, distance_code); + *commands++ = cmd; + *num_literals += insert_length; + insert_length = 0; + // Put the hash keys into the table, if there are enough + // bytes left. + for (size_t j = 2; j < best_len; ++j) { + hasher->Store(&ringbuffer[i + j], + static_cast(i + i_diff + j)); + } + i += best_len; + } else { + ++insert_length; + ++i; + // If we have not seen matches for a long time, we can skip some + // match lookups. Unsuccessful match lookups are very very expensive + // and this kind of a heuristic speeds up compression quite + // a lot. + if (i > apply_random_heuristics) { + // Going through uncompressible data, jump. + if (i > apply_random_heuristics + 4 * random_heuristics_window_size) { + // It is quite a long time since we saw a copy, so we assume + // that this data is not compressible, and store hashes less + // often. Hashes of non compressible data are less likely to + // turn out to be useful in the future, too, so we store less of + // them to not to flood out the hash table of good compressible + // data. + size_t i_jump = std::min(i + 16, i_end - 4); + for (; i < i_jump; i += 4) { + hasher->Store(ringbuffer + i, static_cast(i + i_diff)); + insert_length += 4; + } + } else { + size_t i_jump = std::min(i + 8, i_end - 3); + for (; i < i_jump; i += 2) { + hasher->Store(ringbuffer + i, static_cast(i + i_diff)); + insert_length += 2; + } + } + } + } + } + insert_length += i_end - i; + *last_insert_len = insert_length; + *num_commands += static_cast(commands - orig_commands); +} + +void CreateBackwardReferences(size_t num_bytes, + size_t position, + bool is_last, + const uint8_t* ringbuffer, + size_t ringbuffer_mask, + const int quality, + const int lgwin, + Hashers* hashers, + int hash_type, + int* dist_cache, + size_t* last_insert_len, + Command* commands, + size_t* num_commands, + size_t* num_literals) { + bool zopflify = quality > 9; + if (zopflify) { + Hashers::H10* hasher = hashers->hash_h10; + hasher->Init(lgwin, position, num_bytes, is_last); + if (num_bytes >= 3 && position >= kMaxTreeCompLength) { + // Store the last `kMaxTreeCompLength - 1` positions in the hasher. + // These could not be calculated before, since they require knowledge + // of both the previous and the current block. + for (size_t i = position - kMaxTreeCompLength + 1; i < position; ++i) { + hasher->Store(ringbuffer, ringbuffer_mask, i, num_bytes + position - i); + } + } + // Set maximum distance, see section 9.1. of the spec. + const size_t max_backward_limit = (1 << lgwin) - 16; + std::vector num_matches(num_bytes); + std::vector matches(4 * num_bytes); + size_t cur_match_pos = 0; + for (size_t i = 0; i + 3 < num_bytes; ++i) { + size_t max_distance = std::min(position + i, max_backward_limit); + size_t max_length = num_bytes - i; + // Ensure that we have enough free slots. + if (matches.size() < cur_match_pos + Hashers::H10::kMaxNumMatches) { + matches.resize(cur_match_pos + Hashers::H10::kMaxNumMatches); + } + size_t num_found_matches = hasher->FindAllMatches( + ringbuffer, ringbuffer_mask, position + i, max_length, max_distance, + &matches[cur_match_pos]); + const size_t cur_match_end = cur_match_pos + num_found_matches; + for (size_t j = cur_match_pos; j + 1 < cur_match_end; ++j) { + assert(matches[j].length() < matches[j + 1].length()); + assert(matches[j].distance > max_distance || + matches[j].distance <= matches[j + 1].distance); + } + num_matches[i] = static_cast(num_found_matches); + if (num_found_matches > 0) { + const size_t match_len = matches[cur_match_end - 1].length(); + if (match_len > kMaxZopfliLen) { + matches[cur_match_pos++] = matches[cur_match_end - 1]; + num_matches[i] = 1; + for (size_t j = 1; j < match_len; ++j) { + ++i; + if (match_len - j < 64) { + hasher->Store(ringbuffer, ringbuffer_mask, position + i, + num_bytes - i); + } + num_matches[i] = 0; + } + } else { + cur_match_pos = cur_match_end; + } + } + } + size_t orig_num_literals = *num_literals; + size_t orig_last_insert_len = *last_insert_len; + int orig_dist_cache[4] = { + dist_cache[0], dist_cache[1], dist_cache[2], dist_cache[3] + }; + size_t orig_num_commands = *num_commands; + static const size_t kIterations = 2; + for (size_t i = 0; i < kIterations; i++) { + ZopfliCostModel model; + if (i == 0) { + model.SetFromLiteralCosts(num_bytes, position, + ringbuffer, ringbuffer_mask); + } else { + model.SetFromCommands(num_bytes, position, + ringbuffer, ringbuffer_mask, + commands, *num_commands - orig_num_commands, + orig_last_insert_len); + } + *num_commands = orig_num_commands; + *num_literals = orig_num_literals; + *last_insert_len = orig_last_insert_len; + memcpy(dist_cache, orig_dist_cache, 4 * sizeof(dist_cache[0])); + ZopfliIterate(num_bytes, position, ringbuffer, ringbuffer_mask, + max_backward_limit, model, num_matches, matches, dist_cache, + last_insert_len, commands, num_commands, num_literals); + } + return; + } + + switch (hash_type) { + case 2: + CreateBackwardReferences( + num_bytes, position, is_last, ringbuffer, ringbuffer_mask, + quality, lgwin, hashers->hash_h2, dist_cache, + last_insert_len, commands, num_commands, num_literals); + break; + case 3: + CreateBackwardReferences( + num_bytes, position, is_last, ringbuffer, ringbuffer_mask, + quality, lgwin, hashers->hash_h3, dist_cache, + last_insert_len, commands, num_commands, num_literals); + break; + case 4: + CreateBackwardReferences( + num_bytes, position, is_last, ringbuffer, ringbuffer_mask, + quality, lgwin, hashers->hash_h4, dist_cache, + last_insert_len, commands, num_commands, num_literals); + break; + case 5: + CreateBackwardReferences( + num_bytes, position, is_last, ringbuffer, ringbuffer_mask, + quality, lgwin, hashers->hash_h5, dist_cache, + last_insert_len, commands, num_commands, num_literals); + break; + case 6: + CreateBackwardReferences( + num_bytes, position, is_last, ringbuffer, ringbuffer_mask, + quality, lgwin, hashers->hash_h6, dist_cache, + last_insert_len, commands, num_commands, num_literals); + break; + case 7: + CreateBackwardReferences( + num_bytes, position, is_last, ringbuffer, ringbuffer_mask, + quality, lgwin, hashers->hash_h7, dist_cache, + last_insert_len, commands, num_commands, num_literals); + break; + case 8: + CreateBackwardReferences( + num_bytes, position, is_last, ringbuffer, ringbuffer_mask, + quality, lgwin, hashers->hash_h8, dist_cache, + last_insert_len, commands, num_commands, num_literals); + break; + case 9: + CreateBackwardReferences( + num_bytes, position, is_last, ringbuffer, ringbuffer_mask, + quality, lgwin, hashers->hash_h9, dist_cache, + last_insert_len, commands, num_commands, num_literals); + break; + default: + break; + } +} + +} // namespace brotli diff --git a/web/server/h2o/libh2o/deps/brotli/enc/backward_references.h b/web/server/h2o/libh2o/deps/brotli/enc/backward_references.h new file mode 100644 index 00000000..d3519efe --- /dev/null +++ b/web/server/h2o/libh2o/deps/brotli/enc/backward_references.h @@ -0,0 +1,39 @@ +/* Copyright 2013 Google Inc. All Rights Reserved. + + Distributed under MIT license. + See file LICENSE for detail or copy at https://opensource.org/licenses/MIT +*/ + +// Function to find backward reference copies. + +#ifndef BROTLI_ENC_BACKWARD_REFERENCES_H_ +#define BROTLI_ENC_BACKWARD_REFERENCES_H_ + +#include "./hash.h" +#include "./command.h" +#include "./types.h" + +namespace brotli { + +// "commands" points to the next output command to write to, "*num_commands" is +// initially the total amount of commands output by previous +// CreateBackwardReferences calls, and must be incremented by the amount written +// by this call. +void CreateBackwardReferences(size_t num_bytes, + size_t position, + bool is_last, + const uint8_t* ringbuffer, + size_t ringbuffer_mask, + const int quality, + const int lgwin, + Hashers* hashers, + int hash_type, + int* dist_cache, + size_t* last_insert_len, + Command* commands, + size_t* num_commands, + size_t* num_literals); + +} // namespace brotli + +#endif // BROTLI_ENC_BACKWARD_REFERENCES_H_ diff --git a/web/server/h2o/libh2o/deps/brotli/enc/bit_cost.h b/web/server/h2o/libh2o/deps/brotli/enc/bit_cost.h new file mode 100644 index 00000000..32ad52e8 --- /dev/null +++ b/web/server/h2o/libh2o/deps/brotli/enc/bit_cost.h @@ -0,0 +1,139 @@ +/* Copyright 2013 Google Inc. All Rights Reserved. + + Distributed under MIT license. + See file LICENSE for detail or copy at https://opensource.org/licenses/MIT +*/ + +// Functions to estimate the bit cost of Huffman trees. + +#ifndef BROTLI_ENC_BIT_COST_H_ +#define BROTLI_ENC_BIT_COST_H_ + + + +#include "./entropy_encode.h" +#include "./fast_log.h" +#include "./types.h" + +namespace brotli { + +static inline double ShannonEntropy(const uint32_t *population, size_t size, + size_t *total) { + size_t sum = 0; + double retval = 0; + const uint32_t *population_end = population + size; + size_t p; + if (size & 1) { + goto odd_number_of_elements_left; + } + while (population < population_end) { + p = *population++; + sum += p; + retval -= static_cast(p) * FastLog2(p); + odd_number_of_elements_left: + p = *population++; + sum += p; + retval -= static_cast(p) * FastLog2(p); + } + if (sum) retval += static_cast(sum) * FastLog2(sum); + *total = sum; + return retval; +} + +static inline double BitsEntropy(const uint32_t *population, size_t size) { + size_t sum; + double retval = ShannonEntropy(population, size, &sum); + if (retval < sum) { + // At least one bit per literal is needed. + retval = static_cast(sum); + } + return retval; +} + + +template +double PopulationCost(const Histogram& histogram) { + if (histogram.total_count_ == 0) { + return 12; + } + int count = 0; + for (int i = 0; i < kSize; ++i) { + if (histogram.data_[i] > 0) { + ++count; + } + } + if (count == 1) { + return 12; + } + if (count == 2) { + return static_cast(20 + histogram.total_count_); + } + double bits = 0; + uint8_t depth_array[kSize] = { 0 }; + if (count <= 4) { + // For very low symbol count we build the Huffman tree. + CreateHuffmanTree(&histogram.data_[0], kSize, 15, depth_array); + for (int i = 0; i < kSize; ++i) { + bits += histogram.data_[i] * depth_array[i]; + } + return count == 3 ? bits + 28 : bits + 37; + } + + // In this loop we compute the entropy of the histogram and simultaneously + // build a simplified histogram of the code length codes where we use the + // zero repeat code 17, but we don't use the non-zero repeat code 16. + size_t max_depth = 1; + uint32_t depth_histo[kCodeLengthCodes] = { 0 }; + const double log2total = FastLog2(histogram.total_count_); + for (size_t i = 0; i < kSize;) { + if (histogram.data_[i] > 0) { + // Compute -log2(P(symbol)) = -log2(count(symbol)/total_count) = + // = log2(total_count) - log2(count(symbol)) + double log2p = log2total - FastLog2(histogram.data_[i]); + // Approximate the bit depth by round(-log2(P(symbol))) + size_t depth = static_cast(log2p + 0.5); + bits += histogram.data_[i] * log2p; + if (depth > 15) { + depth = 15; + } + if (depth > max_depth) { + max_depth = depth; + } + ++depth_histo[depth]; + ++i; + } else { + // Compute the run length of zeros and add the appropriate number of 0 and + // 17 code length codes to the code length code histogram. + uint32_t reps = 1; + for (size_t k = i + 1; k < kSize && histogram.data_[k] == 0; ++k) { + ++reps; + } + i += reps; + if (i == kSize) { + // Don't add any cost for the last zero run, since these are encoded + // only implicitly. + break; + } + if (reps < 3) { + depth_histo[0] += reps; + } else { + reps -= 2; + while (reps > 0) { + ++depth_histo[17]; + // Add the 3 extra bits for the 17 code length code. + bits += 3; + reps >>= 3; + } + } + } + } + // Add the estimated encoding cost of the code length code histogram. + bits += static_cast(18 + 2 * max_depth); + // Add the entropy of the code length code histogram. + bits += BitsEntropy(depth_histo, kCodeLengthCodes); + return bits; +} + +} // namespace brotli + +#endif // BROTLI_ENC_BIT_COST_H_ diff --git a/web/server/h2o/libh2o/deps/brotli/enc/block_splitter.cc b/web/server/h2o/libh2o/deps/brotli/enc/block_splitter.cc new file mode 100644 index 00000000..8eaf9535 --- /dev/null +++ b/web/server/h2o/libh2o/deps/brotli/enc/block_splitter.cc @@ -0,0 +1,389 @@ +/* Copyright 2013 Google Inc. All Rights Reserved. + + Distributed under MIT license. + See file LICENSE for detail or copy at https://opensource.org/licenses/MIT +*/ + +// Block split point selection utilities. + +#include "./block_splitter.h" + +#include +#include + +#include +#include +#include + +#include "./cluster.h" +#include "./command.h" +#include "./fast_log.h" +#include "./histogram.h" + +namespace brotli { + +static const size_t kMaxLiteralHistograms = 100; +static const size_t kMaxCommandHistograms = 50; +static const double kLiteralBlockSwitchCost = 28.1; +static const double kCommandBlockSwitchCost = 13.5; +static const double kDistanceBlockSwitchCost = 14.6; +static const size_t kLiteralStrideLength = 70; +static const size_t kCommandStrideLength = 40; +static const size_t kSymbolsPerLiteralHistogram = 544; +static const size_t kSymbolsPerCommandHistogram = 530; +static const size_t kSymbolsPerDistanceHistogram = 544; +static const size_t kMinLengthForBlockSplitting = 128; +static const size_t kIterMulForRefining = 2; +static const size_t kMinItersForRefining = 100; + +void CopyLiteralsToByteArray(const Command* cmds, + const size_t num_commands, + const uint8_t* data, + const size_t offset, + const size_t mask, + std::vector* literals) { + // Count how many we have. + size_t total_length = 0; + for (size_t i = 0; i < num_commands; ++i) { + total_length += cmds[i].insert_len_; + } + if (total_length == 0) { + return; + } + + // Allocate. + literals->resize(total_length); + + // Loop again, and copy this time. + size_t pos = 0; + size_t from_pos = offset & mask; + for (size_t i = 0; i < num_commands && pos < total_length; ++i) { + size_t insert_len = cmds[i].insert_len_; + if (from_pos + insert_len > mask) { + size_t head_size = mask + 1 - from_pos; + memcpy(&(*literals)[pos], data + from_pos, head_size); + from_pos = 0; + pos += head_size; + insert_len -= head_size; + } + if (insert_len > 0) { + memcpy(&(*literals)[pos], data + from_pos, insert_len); + pos += insert_len; + } + from_pos = (from_pos + insert_len + cmds[i].copy_len_) & mask; + } +} + +void CopyCommandsToByteArray(const Command* cmds, + const size_t num_commands, + std::vector* insert_and_copy_codes, + std::vector* distance_prefixes) { + for (size_t i = 0; i < num_commands; ++i) { + const Command& cmd = cmds[i]; + insert_and_copy_codes->push_back(cmd.cmd_prefix_); + if (cmd.copy_len_ > 0 && cmd.cmd_prefix_ >= 128) { + distance_prefixes->push_back(cmd.dist_prefix_); + } + } +} + +inline static unsigned int MyRand(unsigned int* seed) { + *seed *= 16807U; + if (*seed == 0) { + *seed = 1; + } + return *seed; +} + +template +void InitialEntropyCodes(const DataType* data, size_t length, + size_t literals_per_histogram, + size_t max_histograms, + size_t stride, + std::vector* vec) { + size_t total_histograms = length / literals_per_histogram + 1; + if (total_histograms > max_histograms) { + total_histograms = max_histograms; + } + unsigned int seed = 7; + size_t block_length = length / total_histograms; + for (size_t i = 0; i < total_histograms; ++i) { + size_t pos = length * i / total_histograms; + if (i != 0) { + pos += MyRand(&seed) % block_length; + } + if (pos + stride >= length) { + pos = length - stride - 1; + } + HistogramType histo; + histo.Add(data + pos, stride); + vec->push_back(histo); + } +} + +template +void RandomSample(unsigned int* seed, + const DataType* data, + size_t length, + size_t stride, + HistogramType* sample) { + size_t pos = 0; + if (stride >= length) { + pos = 0; + stride = length; + } else { + pos = MyRand(seed) % (length - stride + 1); + } + sample->Add(data + pos, stride); +} + +template +void RefineEntropyCodes(const DataType* data, size_t length, + size_t stride, + std::vector* vec) { + size_t iters = + kIterMulForRefining * length / stride + kMinItersForRefining; + unsigned int seed = 7; + iters = ((iters + vec->size() - 1) / vec->size()) * vec->size(); + for (size_t iter = 0; iter < iters; ++iter) { + HistogramType sample; + RandomSample(&seed, data, length, stride, &sample); + size_t ix = iter % vec->size(); + (*vec)[ix].AddHistogram(sample); + } +} + +inline static double BitCost(size_t count) { + return count == 0 ? -2.0 : FastLog2(count); +} + +template +void FindBlocks(const DataType* data, const size_t length, + const double block_switch_bitcost, + const std::vector > &vec, + uint8_t *block_id) { + if (vec.size() <= 1) { + for (size_t i = 0; i < length; ++i) { + block_id[i] = 0; + } + return; + } + size_t vecsize = vec.size(); + assert(vecsize <= 256); + double* insert_cost = new double[kSize * vecsize]; + memset(insert_cost, 0, sizeof(insert_cost[0]) * kSize * vecsize); + for (size_t j = 0; j < vecsize; ++j) { + insert_cost[j] = FastLog2(static_cast(vec[j].total_count_)); + } + for (size_t i = kSize; i != 0;) { + --i; + for (size_t j = 0; j < vecsize; ++j) { + insert_cost[i * vecsize + j] = insert_cost[j] - BitCost(vec[j].data_[i]); + } + } + double *cost = new double[vecsize]; + memset(cost, 0, sizeof(cost[0]) * vecsize); + bool* switch_signal = new bool[length * vecsize]; + memset(switch_signal, 0, sizeof(switch_signal[0]) * length * vecsize); + // After each iteration of this loop, cost[k] will contain the difference + // between the minimum cost of arriving at the current byte position using + // entropy code k, and the minimum cost of arriving at the current byte + // position. This difference is capped at the block switch cost, and if it + // reaches block switch cost, it means that when we trace back from the last + // position, we need to switch here. + for (size_t byte_ix = 0; byte_ix < length; ++byte_ix) { + size_t ix = byte_ix * vecsize; + size_t insert_cost_ix = data[byte_ix] * vecsize; + double min_cost = 1e99; + for (size_t k = 0; k < vecsize; ++k) { + // We are coding the symbol in data[byte_ix] with entropy code k. + cost[k] += insert_cost[insert_cost_ix + k]; + if (cost[k] < min_cost) { + min_cost = cost[k]; + block_id[byte_ix] = static_cast(k); + } + } + double block_switch_cost = block_switch_bitcost; + // More blocks for the beginning. + if (byte_ix < 2000) { + block_switch_cost *= 0.77 + 0.07 * static_cast(byte_ix) / 2000; + } + for (size_t k = 0; k < vecsize; ++k) { + cost[k] -= min_cost; + if (cost[k] >= block_switch_cost) { + cost[k] = block_switch_cost; + switch_signal[ix + k] = true; + } + } + } + // Now trace back from the last position and switch at the marked places. + size_t byte_ix = length - 1; + size_t ix = byte_ix * vecsize; + uint8_t cur_id = block_id[byte_ix]; + while (byte_ix > 0) { + --byte_ix; + ix -= vecsize; + if (switch_signal[ix + cur_id]) { + cur_id = block_id[byte_ix]; + } + block_id[byte_ix] = cur_id; + } + delete[] insert_cost; + delete[] cost; + delete[] switch_signal; +} + +size_t RemapBlockIds(uint8_t* block_ids, const size_t length) { + std::map new_id; + size_t next_id = 0; + for (size_t i = 0; i < length; ++i) { + if (new_id.find(block_ids[i]) == new_id.end()) { + new_id[block_ids[i]] = static_cast(next_id); + ++next_id; + } + } + for (size_t i = 0; i < length; ++i) { + block_ids[i] = new_id[block_ids[i]]; + } + return next_id; +} + +template +void BuildBlockHistograms(const DataType* data, const size_t length, + uint8_t* block_ids, + std::vector* histograms) { + size_t num_types = RemapBlockIds(block_ids, length); + assert(num_types <= 256); + histograms->clear(); + histograms->resize(num_types); + for (size_t i = 0; i < length; ++i) { + (*histograms)[block_ids[i]].Add(data[i]); + } +} + +template +void ClusterBlocks(const DataType* data, const size_t length, + uint8_t* block_ids) { + std::vector histograms; + std::vector block_index(length); + uint32_t cur_idx = 0; + HistogramType cur_histogram; + for (size_t i = 0; i < length; ++i) { + bool block_boundary = (i + 1 == length || block_ids[i] != block_ids[i + 1]); + block_index[i] = cur_idx; + cur_histogram.Add(data[i]); + if (block_boundary) { + histograms.push_back(cur_histogram); + cur_histogram.Clear(); + ++cur_idx; + } + } + std::vector clustered_histograms; + std::vector histogram_symbols; + // Block ids need to fit in one byte. + static const size_t kMaxNumberOfBlockTypes = 256; + ClusterHistograms(histograms, 1, histograms.size(), + kMaxNumberOfBlockTypes, + &clustered_histograms, + &histogram_symbols); + for (size_t i = 0; i < length; ++i) { + block_ids[i] = static_cast(histogram_symbols[block_index[i]]); + } +} + +void BuildBlockSplit(const std::vector& block_ids, BlockSplit* split) { + uint8_t cur_id = block_ids[0]; + uint8_t max_type = cur_id; + uint32_t cur_length = 1; + for (size_t i = 1; i < block_ids.size(); ++i) { + uint8_t next_id = block_ids[i]; + if (next_id != cur_id) { + split->types.push_back(cur_id); + split->lengths.push_back(cur_length); + max_type = std::max(max_type, next_id); + cur_id = next_id; + cur_length = 0; + } + ++cur_length; + } + split->types.push_back(cur_id); + split->lengths.push_back(cur_length); + split->num_types = static_cast(max_type) + 1; +} + +template +void SplitByteVector(const std::vector& data, + const size_t literals_per_histogram, + const size_t max_histograms, + const size_t sampling_stride_length, + const double block_switch_cost, + BlockSplit* split) { + if (data.empty()) { + split->num_types = 1; + return; + } else if (data.size() < kMinLengthForBlockSplitting) { + split->num_types = 1; + split->types.push_back(0); + split->lengths.push_back(static_cast(data.size())); + return; + } + std::vector histograms; + // Find good entropy codes. + InitialEntropyCodes(&data[0], data.size(), + literals_per_histogram, + max_histograms, + sampling_stride_length, + &histograms); + RefineEntropyCodes(&data[0], data.size(), + sampling_stride_length, + &histograms); + // Find a good path through literals with the good entropy codes. + std::vector block_ids(data.size()); + for (size_t i = 0; i < 10; ++i) { + FindBlocks(&data[0], data.size(), + block_switch_cost, + histograms, + &block_ids[0]); + BuildBlockHistograms(&data[0], data.size(), &block_ids[0], &histograms); + } + ClusterBlocks(&data[0], data.size(), &block_ids[0]); + BuildBlockSplit(block_ids, split); +} + +void SplitBlock(const Command* cmds, + const size_t num_commands, + const uint8_t* data, + const size_t pos, + const size_t mask, + BlockSplit* literal_split, + BlockSplit* insert_and_copy_split, + BlockSplit* dist_split) { + // Create a continuous array of literals. + std::vector literals; + CopyLiteralsToByteArray(cmds, num_commands, data, pos, mask, &literals); + + // Compute prefix codes for commands. + std::vector insert_and_copy_codes; + std::vector distance_prefixes; + CopyCommandsToByteArray(cmds, num_commands, + &insert_and_copy_codes, + &distance_prefixes); + + SplitByteVector( + literals, + kSymbolsPerLiteralHistogram, kMaxLiteralHistograms, + kLiteralStrideLength, kLiteralBlockSwitchCost, + literal_split); + SplitByteVector( + insert_and_copy_codes, + kSymbolsPerCommandHistogram, kMaxCommandHistograms, + kCommandStrideLength, kCommandBlockSwitchCost, + insert_and_copy_split); + SplitByteVector( + distance_prefixes, + kSymbolsPerDistanceHistogram, kMaxCommandHistograms, + kCommandStrideLength, kDistanceBlockSwitchCost, + dist_split); +} + +} // namespace brotli diff --git a/web/server/h2o/libh2o/deps/brotli/enc/block_splitter.h b/web/server/h2o/libh2o/deps/brotli/enc/block_splitter.h new file mode 100644 index 00000000..bbbfda90 --- /dev/null +++ b/web/server/h2o/libh2o/deps/brotli/enc/block_splitter.h @@ -0,0 +1,61 @@ +/* Copyright 2013 Google Inc. All Rights Reserved. + + Distributed under MIT license. + See file LICENSE for detail or copy at https://opensource.org/licenses/MIT +*/ + +// Block split point selection utilities. + +#ifndef BROTLI_ENC_BLOCK_SPLITTER_H_ +#define BROTLI_ENC_BLOCK_SPLITTER_H_ + +#include + +#include "./command.h" +#include "./metablock.h" +#include "./types.h" + +namespace brotli { + +struct BlockSplitIterator { + explicit BlockSplitIterator(const BlockSplit& split) + : split_(split), idx_(0), type_(0), length_(0) { + if (!split.lengths.empty()) { + length_ = split.lengths[0]; + } + } + + void Next() { + if (length_ == 0) { + ++idx_; + type_ = split_.types[idx_]; + length_ = split_.lengths[idx_]; + } + --length_; + } + + const BlockSplit& split_; + size_t idx_; + size_t type_; + size_t length_; +}; + +void CopyLiteralsToByteArray(const Command* cmds, + const size_t num_commands, + const uint8_t* data, + const size_t offset, + const size_t mask, + std::vector* literals); + +void SplitBlock(const Command* cmds, + const size_t num_commands, + const uint8_t* data, + const size_t offset, + const size_t mask, + BlockSplit* literal_split, + BlockSplit* insert_and_copy_split, + BlockSplit* dist_split); + +} // namespace brotli + +#endif // BROTLI_ENC_BLOCK_SPLITTER_H_ diff --git a/web/server/h2o/libh2o/deps/brotli/enc/brotli_bit_stream.cc b/web/server/h2o/libh2o/deps/brotli/enc/brotli_bit_stream.cc new file mode 100644 index 00000000..69a73fc0 --- /dev/null +++ b/web/server/h2o/libh2o/deps/brotli/enc/brotli_bit_stream.cc @@ -0,0 +1,1127 @@ +/* Copyright 2014 Google Inc. All Rights Reserved. + + Distributed under MIT license. + See file LICENSE for detail or copy at https://opensource.org/licenses/MIT +*/ + +// Brotli bit stream functions to support the low level format. There are no +// compression algorithms here, just the right ordering of bits to match the +// specs. + +#include "./brotli_bit_stream.h" + +#include +#include +#include +#include +#include + +#include "./bit_cost.h" +#include "./context.h" +#include "./entropy_encode.h" +#include "./entropy_encode_static.h" +#include "./fast_log.h" +#include "./prefix.h" +#include "./write_bits.h" +namespace brotli { + +namespace { + +// nibblesbits represents the 2 bits to encode MNIBBLES (0-3) +// REQUIRES: length > 0 +// REQUIRES: length <= (1 << 24) +void EncodeMlen(size_t length, uint64_t* bits, + size_t* numbits, uint64_t* nibblesbits) { + assert(length > 0); + assert(length <= (1 << 24)); + length--; // MLEN - 1 is encoded + size_t lg = length == 0 ? 1 : Log2FloorNonZero( + static_cast(length)) + 1; + assert(lg <= 24); + size_t mnibbles = (lg < 16 ? 16 : (lg + 3)) / 4; + *nibblesbits = mnibbles - 4; + *numbits = mnibbles * 4; + *bits = length; +} + +} // namespace + +void StoreVarLenUint8(size_t n, size_t* storage_ix, uint8_t* storage) { + if (n == 0) { + WriteBits(1, 0, storage_ix, storage); + } else { + WriteBits(1, 1, storage_ix, storage); + size_t nbits = Log2FloorNonZero(n); + WriteBits(3, nbits, storage_ix, storage); + WriteBits(nbits, n - (1 << nbits), storage_ix, storage); + } +} + +void StoreCompressedMetaBlockHeader(bool final_block, + size_t length, + size_t* storage_ix, + uint8_t* storage) { + // Write ISLAST bit. + WriteBits(1, final_block, storage_ix, storage); + // Write ISEMPTY bit. + if (final_block) { + WriteBits(1, 0, storage_ix, storage); + } + + uint64_t lenbits; + size_t nlenbits; + uint64_t nibblesbits; + EncodeMlen(length, &lenbits, &nlenbits, &nibblesbits); + WriteBits(2, nibblesbits, storage_ix, storage); + WriteBits(nlenbits, lenbits, storage_ix, storage); + + if (!final_block) { + // Write ISUNCOMPRESSED bit. + WriteBits(1, 0, storage_ix, storage); + } +} + +void StoreUncompressedMetaBlockHeader(size_t length, + size_t* storage_ix, + uint8_t* storage) { + // Write ISLAST bit. Uncompressed block cannot be the last one, so set to 0. + WriteBits(1, 0, storage_ix, storage); + uint64_t lenbits; + size_t nlenbits; + uint64_t nibblesbits; + EncodeMlen(length, &lenbits, &nlenbits, &nibblesbits); + WriteBits(2, nibblesbits, storage_ix, storage); + WriteBits(nlenbits, lenbits, storage_ix, storage); + // Write ISUNCOMPRESSED bit. + WriteBits(1, 1, storage_ix, storage); +} + +void StoreHuffmanTreeOfHuffmanTreeToBitMask( + const int num_codes, + const uint8_t *code_length_bitdepth, + size_t *storage_ix, + uint8_t *storage) { + static const uint8_t kStorageOrder[kCodeLengthCodes] = { + 1, 2, 3, 4, 0, 5, 17, 6, 16, 7, 8, 9, 10, 11, 12, 13, 14, 15 + }; + // The bit lengths of the Huffman code over the code length alphabet + // are compressed with the following static Huffman code: + // Symbol Code + // ------ ---- + // 0 00 + // 1 1110 + // 2 110 + // 3 01 + // 4 10 + // 5 1111 + static const uint8_t kHuffmanBitLengthHuffmanCodeSymbols[6] = { + 0, 7, 3, 2, 1, 15 + }; + static const uint8_t kHuffmanBitLengthHuffmanCodeBitLengths[6] = { + 2, 4, 3, 2, 2, 4 + }; + + // Throw away trailing zeros: + size_t codes_to_store = kCodeLengthCodes; + if (num_codes > 1) { + for (; codes_to_store > 0; --codes_to_store) { + if (code_length_bitdepth[kStorageOrder[codes_to_store - 1]] != 0) { + break; + } + } + } + size_t skip_some = 0; // skips none. + if (code_length_bitdepth[kStorageOrder[0]] == 0 && + code_length_bitdepth[kStorageOrder[1]] == 0) { + skip_some = 2; // skips two. + if (code_length_bitdepth[kStorageOrder[2]] == 0) { + skip_some = 3; // skips three. + } + } + WriteBits(2, skip_some, storage_ix, storage); + for (size_t i = skip_some; i < codes_to_store; ++i) { + size_t l = code_length_bitdepth[kStorageOrder[i]]; + WriteBits(kHuffmanBitLengthHuffmanCodeBitLengths[l], + kHuffmanBitLengthHuffmanCodeSymbols[l], storage_ix, storage); + } +} + +void StoreHuffmanTreeToBitMask( + const std::vector &huffman_tree, + const std::vector &huffman_tree_extra_bits, + const uint8_t *code_length_bitdepth, + const std::vector &code_length_bitdepth_symbols, + size_t * __restrict storage_ix, + uint8_t * __restrict storage) { + for (size_t i = 0; i < huffman_tree.size(); ++i) { + size_t ix = huffman_tree[i]; + WriteBits(code_length_bitdepth[ix], code_length_bitdepth_symbols[ix], + storage_ix, storage); + // Extra bits + switch (ix) { + case 16: + WriteBits(2, huffman_tree_extra_bits[i], storage_ix, storage); + break; + case 17: + WriteBits(3, huffman_tree_extra_bits[i], storage_ix, storage); + break; + } + } +} + +void StoreSimpleHuffmanTree(const uint8_t* depths, + size_t symbols[4], + size_t num_symbols, + size_t max_bits, + size_t *storage_ix, uint8_t *storage) { + // value of 1 indicates a simple Huffman code + WriteBits(2, 1, storage_ix, storage); + WriteBits(2, num_symbols - 1, storage_ix, storage); // NSYM - 1 + + // Sort + for (size_t i = 0; i < num_symbols; i++) { + for (size_t j = i + 1; j < num_symbols; j++) { + if (depths[symbols[j]] < depths[symbols[i]]) { + std::swap(symbols[j], symbols[i]); + } + } + } + + if (num_symbols == 2) { + WriteBits(max_bits, symbols[0], storage_ix, storage); + WriteBits(max_bits, symbols[1], storage_ix, storage); + } else if (num_symbols == 3) { + WriteBits(max_bits, symbols[0], storage_ix, storage); + WriteBits(max_bits, symbols[1], storage_ix, storage); + WriteBits(max_bits, symbols[2], storage_ix, storage); + } else { + WriteBits(max_bits, symbols[0], storage_ix, storage); + WriteBits(max_bits, symbols[1], storage_ix, storage); + WriteBits(max_bits, symbols[2], storage_ix, storage); + WriteBits(max_bits, symbols[3], storage_ix, storage); + // tree-select + WriteBits(1, depths[symbols[0]] == 1 ? 1 : 0, storage_ix, storage); + } +} + +// num = alphabet size +// depths = symbol depths +void StoreHuffmanTree(const uint8_t* depths, size_t num, + size_t *storage_ix, uint8_t *storage) { + // Write the Huffman tree into the brotli-representation. + std::vector huffman_tree; + std::vector huffman_tree_extra_bits; + // TODO: Consider allocating these from stack. + huffman_tree.reserve(256); + huffman_tree_extra_bits.reserve(256); + WriteHuffmanTree(depths, num, &huffman_tree, &huffman_tree_extra_bits); + + // Calculate the statistics of the Huffman tree in brotli-representation. + uint32_t huffman_tree_histogram[kCodeLengthCodes] = { 0 }; + for (size_t i = 0; i < huffman_tree.size(); ++i) { + ++huffman_tree_histogram[huffman_tree[i]]; + } + + int num_codes = 0; + int code = 0; + for (int i = 0; i < kCodeLengthCodes; ++i) { + if (huffman_tree_histogram[i]) { + if (num_codes == 0) { + code = i; + num_codes = 1; + } else if (num_codes == 1) { + num_codes = 2; + break; + } + } + } + + // Calculate another Huffman tree to use for compressing both the + // earlier Huffman tree with. + // TODO: Consider allocating these from stack. + uint8_t code_length_bitdepth[kCodeLengthCodes] = { 0 }; + std::vector code_length_bitdepth_symbols(kCodeLengthCodes); + CreateHuffmanTree(&huffman_tree_histogram[0], kCodeLengthCodes, + 5, &code_length_bitdepth[0]); + ConvertBitDepthsToSymbols(code_length_bitdepth, kCodeLengthCodes, + &code_length_bitdepth_symbols[0]); + + // Now, we have all the data, let's start storing it + StoreHuffmanTreeOfHuffmanTreeToBitMask(num_codes, code_length_bitdepth, + storage_ix, storage); + + if (num_codes == 1) { + code_length_bitdepth[code] = 0; + } + + // Store the real huffman tree now. + StoreHuffmanTreeToBitMask(huffman_tree, + huffman_tree_extra_bits, + &code_length_bitdepth[0], + code_length_bitdepth_symbols, + storage_ix, storage); +} + + +void BuildAndStoreHuffmanTree(const uint32_t *histogram, + const size_t length, + uint8_t* depth, + uint16_t* bits, + size_t* storage_ix, + uint8_t* storage) { + size_t count = 0; + size_t s4[4] = { 0 }; + for (size_t i = 0; i < length; i++) { + if (histogram[i]) { + if (count < 4) { + s4[count] = i; + } else if (count > 4) { + break; + } + count++; + } + } + + size_t max_bits_counter = length - 1; + size_t max_bits = 0; + while (max_bits_counter) { + max_bits_counter >>= 1; + ++max_bits; + } + + if (count <= 1) { + WriteBits(4, 1, storage_ix, storage); + WriteBits(max_bits, s4[0], storage_ix, storage); + return; + } + + CreateHuffmanTree(histogram, length, 15, depth); + ConvertBitDepthsToSymbols(depth, length, bits); + + if (count <= 4) { + StoreSimpleHuffmanTree(depth, s4, count, max_bits, storage_ix, storage); + } else { + StoreHuffmanTree(depth, length, storage_ix, storage); + } +} + +void BuildAndStoreHuffmanTreeFast(const uint32_t *histogram, + const size_t histogram_total, + const size_t max_bits, + uint8_t* depth, + uint16_t* bits, + size_t* storage_ix, + uint8_t* storage) { + size_t count = 0; + size_t symbols[4] = { 0 }; + size_t length = 0; + size_t total = histogram_total; + while (total != 0) { + if (histogram[length]) { + if (count < 4) { + symbols[count] = length; + } + ++count; + total -= histogram[length]; + } + ++length; + } + + if (count <= 1) { + WriteBits(4, 1, storage_ix, storage); + WriteBits(max_bits, symbols[0], storage_ix, storage); + return; + } + + const size_t max_tree_size = 2 * length + 1; + HuffmanTree* const tree = + static_cast(malloc(max_tree_size * sizeof(HuffmanTree))); + for (uint32_t count_limit = 1; ; count_limit *= 2) { + HuffmanTree* node = tree; + for (size_t i = length; i != 0;) { + --i; + if (histogram[i]) { + if (PREDICT_TRUE(histogram[i] >= count_limit)) { + *node = HuffmanTree(histogram[i], -1, static_cast(i)); + } else { + *node = HuffmanTree(count_limit, -1, static_cast(i)); + } + ++node; + } + } + const int n = static_cast(node - tree); + std::sort(tree, node, SortHuffmanTree); + // The nodes are: + // [0, n): the sorted leaf nodes that we start with. + // [n]: we add a sentinel here. + // [n + 1, 2n): new parent nodes are added here, starting from + // (n+1). These are naturally in ascending order. + // [2n]: we add a sentinel at the end as well. + // There will be (2n+1) elements at the end. + const HuffmanTree sentinel(std::numeric_limits::max(), -1, -1); + *node++ = sentinel; + *node++ = sentinel; + + int i = 0; // Points to the next leaf node. + int j = n + 1; // Points to the next non-leaf node. + for (int k = n - 1; k > 0; --k) { + int left, right; + if (tree[i].total_count_ <= tree[j].total_count_) { + left = i; + ++i; + } else { + left = j; + ++j; + } + if (tree[i].total_count_ <= tree[j].total_count_) { + right = i; + ++i; + } else { + right = j; + ++j; + } + // The sentinel node becomes the parent node. + node[-1].total_count_ = + tree[left].total_count_ + tree[right].total_count_; + node[-1].index_left_ = static_cast(left); + node[-1].index_right_or_value_ = static_cast(right); + // Add back the last sentinel node. + *node++ = sentinel; + } + SetDepth(tree[2 * n - 1], &tree[0], depth, 0); + // We need to pack the Huffman tree in 14 bits. + // If this was not successful, add fake entities to the lowest values + // and retry. + if (PREDICT_TRUE(*std::max_element(&depth[0], &depth[length]) <= 14)) { + break; + } + } + free(tree); + ConvertBitDepthsToSymbols(depth, length, bits); + if (count <= 4) { + // value of 1 indicates a simple Huffman code + WriteBits(2, 1, storage_ix, storage); + WriteBits(2, count - 1, storage_ix, storage); // NSYM - 1 + + // Sort + for (size_t i = 0; i < count; i++) { + for (size_t j = i + 1; j < count; j++) { + if (depth[symbols[j]] < depth[symbols[i]]) { + std::swap(symbols[j], symbols[i]); + } + } + } + + if (count == 2) { + WriteBits(max_bits, symbols[0], storage_ix, storage); + WriteBits(max_bits, symbols[1], storage_ix, storage); + } else if (count == 3) { + WriteBits(max_bits, symbols[0], storage_ix, storage); + WriteBits(max_bits, symbols[1], storage_ix, storage); + WriteBits(max_bits, symbols[2], storage_ix, storage); + } else { + WriteBits(max_bits, symbols[0], storage_ix, storage); + WriteBits(max_bits, symbols[1], storage_ix, storage); + WriteBits(max_bits, symbols[2], storage_ix, storage); + WriteBits(max_bits, symbols[3], storage_ix, storage); + // tree-select + WriteBits(1, depth[symbols[0]] == 1 ? 1 : 0, storage_ix, storage); + } + } else { + // Complex Huffman Tree + StoreStaticCodeLengthCode(storage_ix, storage); + + // Actual rle coding. + uint8_t previous_value = 8; + for (size_t i = 0; i < length;) { + const uint8_t value = depth[i]; + size_t reps = 1; + for (size_t k = i + 1; k < length && depth[k] == value; ++k) { + ++reps; + } + i += reps; + if (value == 0) { + WriteBits(kZeroRepsDepth[reps], kZeroRepsBits[reps], + storage_ix, storage); + } else { + if (previous_value != value) { + WriteBits(kCodeLengthDepth[value], kCodeLengthBits[value], + storage_ix, storage); + --reps; + } + if (reps < 3) { + while (reps != 0) { + reps--; + WriteBits(kCodeLengthDepth[value], kCodeLengthBits[value], + storage_ix, storage); + } + } else { + reps -= 3; + WriteBits(kNonZeroRepsDepth[reps], kNonZeroRepsBits[reps], + storage_ix, storage); + } + previous_value = value; + } + } + } +} + +size_t IndexOf(const std::vector& v, uint32_t value) { + size_t i = 0; + for (; i < v.size(); ++i) { + if (v[i] == value) return i; + } + return i; +} + +void MoveToFront(std::vector* v, size_t index) { + uint32_t value = (*v)[index]; + for (size_t i = index; i != 0; --i) { + (*v)[i] = (*v)[i - 1]; + } + (*v)[0] = value; +} + +std::vector MoveToFrontTransform(const std::vector& v) { + if (v.empty()) return v; + uint32_t max_value = *std::max_element(v.begin(), v.end()); + std::vector mtf(max_value + 1); + for (uint32_t i = 0; i <= max_value; ++i) mtf[i] = i; + std::vector result(v.size()); + for (size_t i = 0; i < v.size(); ++i) { + size_t index = IndexOf(mtf, v[i]); + assert(index < mtf.size()); + result[i] = static_cast(index); + MoveToFront(&mtf, index); + } + return result; +} + +// Finds runs of zeros in v_in and replaces them with a prefix code of the run +// length plus extra bits in *v_out and *extra_bits. Non-zero values in v_in are +// shifted by *max_length_prefix. Will not create prefix codes bigger than the +// initial value of *max_run_length_prefix. The prefix code of run length L is +// simply Log2Floor(L) and the number of extra bits is the same as the prefix +// code. +void RunLengthCodeZeros(const std::vector& v_in, + uint32_t* max_run_length_prefix, + std::vector* v_out, + std::vector* extra_bits) { + uint32_t max_reps = 0; + for (size_t i = 0; i < v_in.size();) { + for (; i < v_in.size() && v_in[i] != 0; ++i) ; + uint32_t reps = 0; + for (; i < v_in.size() && v_in[i] == 0; ++i) { + ++reps; + } + max_reps = std::max(reps, max_reps); + } + uint32_t max_prefix = max_reps > 0 ? Log2FloorNonZero(max_reps) : 0; + max_prefix = std::min(max_prefix, *max_run_length_prefix); + *max_run_length_prefix = max_prefix; + for (size_t i = 0; i < v_in.size();) { + if (v_in[i] != 0) { + v_out->push_back(v_in[i] + *max_run_length_prefix); + extra_bits->push_back(0); + ++i; + } else { + uint32_t reps = 1; + for (size_t k = i + 1; k < v_in.size() && v_in[k] == 0; ++k) { + ++reps; + } + i += reps; + while (reps != 0) { + if (reps < (2u << max_prefix)) { + uint32_t run_length_prefix = Log2FloorNonZero(reps); + v_out->push_back(run_length_prefix); + extra_bits->push_back(reps - (1u << run_length_prefix)); + break; + } else { + v_out->push_back(max_prefix); + extra_bits->push_back((1u << max_prefix) - 1u); + reps -= (2u << max_prefix) - 1u; + } + } + } + } +} + +void EncodeContextMap(const std::vector& context_map, + size_t num_clusters, + size_t* storage_ix, uint8_t* storage) { + StoreVarLenUint8(num_clusters - 1, storage_ix, storage); + + if (num_clusters == 1) { + return; + } + + std::vector transformed_symbols = MoveToFrontTransform(context_map); + std::vector rle_symbols; + std::vector extra_bits; + uint32_t max_run_length_prefix = 6; + RunLengthCodeZeros(transformed_symbols, &max_run_length_prefix, + &rle_symbols, &extra_bits); + HistogramContextMap symbol_histogram; + for (size_t i = 0; i < rle_symbols.size(); ++i) { + symbol_histogram.Add(rle_symbols[i]); + } + bool use_rle = max_run_length_prefix > 0; + WriteBits(1, use_rle, storage_ix, storage); + if (use_rle) { + WriteBits(4, max_run_length_prefix - 1, storage_ix, storage); + } + EntropyCodeContextMap symbol_code; + memset(symbol_code.depth_, 0, sizeof(symbol_code.depth_)); + memset(symbol_code.bits_, 0, sizeof(symbol_code.bits_)); + BuildAndStoreHuffmanTree(symbol_histogram.data_, + num_clusters + max_run_length_prefix, + symbol_code.depth_, symbol_code.bits_, + storage_ix, storage); + for (size_t i = 0; i < rle_symbols.size(); ++i) { + WriteBits(symbol_code.depth_[rle_symbols[i]], + symbol_code.bits_[rle_symbols[i]], + storage_ix, storage); + if (rle_symbols[i] > 0 && rle_symbols[i] <= max_run_length_prefix) { + WriteBits(rle_symbols[i], extra_bits[i], storage_ix, storage); + } + } + WriteBits(1, 1, storage_ix, storage); // use move-to-front +} + +void StoreBlockSwitch(const BlockSplitCode& code, + const size_t block_ix, + size_t* storage_ix, + uint8_t* storage) { + if (block_ix > 0) { + size_t typecode = code.type_code[block_ix]; + WriteBits(code.type_depths[typecode], code.type_bits[typecode], + storage_ix, storage); + } + size_t lencode = code.length_prefix[block_ix]; + WriteBits(code.length_depths[lencode], code.length_bits[lencode], + storage_ix, storage); + WriteBits(code.length_nextra[block_ix], code.length_extra[block_ix], + storage_ix, storage); +} + +void BuildAndStoreBlockSplitCode(const std::vector& types, + const std::vector& lengths, + const size_t num_types, + BlockSplitCode* code, + size_t* storage_ix, + uint8_t* storage) { + const size_t num_blocks = types.size(); + std::vector type_histo(num_types + 2); + std::vector length_histo(26); + size_t last_type = 1; + size_t second_last_type = 0; + code->type_code.resize(num_blocks); + code->length_prefix.resize(num_blocks); + code->length_nextra.resize(num_blocks); + code->length_extra.resize(num_blocks); + code->type_depths.resize(num_types + 2); + code->type_bits.resize(num_types + 2); + code->length_depths.resize(26); + code->length_bits.resize(26); + for (size_t i = 0; i < num_blocks; ++i) { + size_t type = types[i]; + size_t type_code = (type == last_type + 1 ? 1 : + type == second_last_type ? 0 : + type + 2); + second_last_type = last_type; + last_type = type; + code->type_code[i] = static_cast(type_code); + if (i != 0) ++type_histo[type_code]; + GetBlockLengthPrefixCode(lengths[i], + &code->length_prefix[i], + &code->length_nextra[i], + &code->length_extra[i]); + ++length_histo[code->length_prefix[i]]; + } + StoreVarLenUint8(num_types - 1, storage_ix, storage); + if (num_types > 1) { + BuildAndStoreHuffmanTree(&type_histo[0], num_types + 2, + &code->type_depths[0], &code->type_bits[0], + storage_ix, storage); + BuildAndStoreHuffmanTree(&length_histo[0], 26, + &code->length_depths[0], &code->length_bits[0], + storage_ix, storage); + StoreBlockSwitch(*code, 0, storage_ix, storage); + } +} + +void StoreTrivialContextMap(size_t num_types, + size_t context_bits, + size_t* storage_ix, + uint8_t* storage) { + StoreVarLenUint8(num_types - 1, storage_ix, storage); + if (num_types > 1) { + size_t repeat_code = context_bits - 1u; + size_t repeat_bits = (1u << repeat_code) - 1u; + size_t alphabet_size = num_types + repeat_code; + std::vector histogram(alphabet_size); + std::vector depths(alphabet_size); + std::vector bits(alphabet_size); + // Write RLEMAX. + WriteBits(1, 1, storage_ix, storage); + WriteBits(4, repeat_code - 1, storage_ix, storage); + histogram[repeat_code] = static_cast(num_types); + histogram[0] = 1; + for (size_t i = context_bits; i < alphabet_size; ++i) { + histogram[i] = 1; + } + BuildAndStoreHuffmanTree(&histogram[0], alphabet_size, + &depths[0], &bits[0], + storage_ix, storage); + for (size_t i = 0; i < num_types; ++i) { + size_t code = (i == 0 ? 0 : i + context_bits - 1); + WriteBits(depths[code], bits[code], storage_ix, storage); + WriteBits(depths[repeat_code], bits[repeat_code], storage_ix, storage); + WriteBits(repeat_code, repeat_bits, storage_ix, storage); + } + // Write IMTF (inverse-move-to-front) bit. + WriteBits(1, 1, storage_ix, storage); + } +} + +// Manages the encoding of one block category (literal, command or distance). +class BlockEncoder { + public: + BlockEncoder(size_t alphabet_size, + size_t num_block_types, + const std::vector& block_types, + const std::vector& block_lengths) + : alphabet_size_(alphabet_size), + num_block_types_(num_block_types), + block_types_(block_types), + block_lengths_(block_lengths), + block_ix_(0), + block_len_(block_lengths.empty() ? 0 : block_lengths[0]), + entropy_ix_(0) {} + + // Creates entropy codes of block lengths and block types and stores them + // to the bit stream. + void BuildAndStoreBlockSwitchEntropyCodes(size_t* storage_ix, + uint8_t* storage) { + BuildAndStoreBlockSplitCode( + block_types_, block_lengths_, num_block_types_, + &block_split_code_, storage_ix, storage); + } + + // Creates entropy codes for all block types and stores them to the bit + // stream. + template + void BuildAndStoreEntropyCodes( + const std::vector >& histograms, + size_t* storage_ix, uint8_t* storage) { + depths_.resize(histograms.size() * alphabet_size_); + bits_.resize(histograms.size() * alphabet_size_); + for (size_t i = 0; i < histograms.size(); ++i) { + size_t ix = i * alphabet_size_; + BuildAndStoreHuffmanTree(&histograms[i].data_[0], alphabet_size_, + &depths_[ix], &bits_[ix], + storage_ix, storage); + } + } + + // Stores the next symbol with the entropy code of the current block type. + // Updates the block type and block length at block boundaries. + void StoreSymbol(size_t symbol, size_t* storage_ix, uint8_t* storage) { + if (block_len_ == 0) { + ++block_ix_; + block_len_ = block_lengths_[block_ix_]; + entropy_ix_ = block_types_[block_ix_] * alphabet_size_; + StoreBlockSwitch(block_split_code_, block_ix_, storage_ix, storage); + } + --block_len_; + size_t ix = entropy_ix_ + symbol; + WriteBits(depths_[ix], bits_[ix], storage_ix, storage); + } + + // Stores the next symbol with the entropy code of the current block type and + // context value. + // Updates the block type and block length at block boundaries. + template + void StoreSymbolWithContext(size_t symbol, size_t context, + const std::vector& context_map, + size_t* storage_ix, uint8_t* storage) { + if (block_len_ == 0) { + ++block_ix_; + block_len_ = block_lengths_[block_ix_]; + size_t block_type = block_types_[block_ix_]; + entropy_ix_ = block_type << kContextBits; + StoreBlockSwitch(block_split_code_, block_ix_, storage_ix, storage); + } + --block_len_; + size_t histo_ix = context_map[entropy_ix_ + context]; + size_t ix = histo_ix * alphabet_size_ + symbol; + WriteBits(depths_[ix], bits_[ix], storage_ix, storage); + } + + private: + const size_t alphabet_size_; + const size_t num_block_types_; + const std::vector& block_types_; + const std::vector& block_lengths_; + BlockSplitCode block_split_code_; + size_t block_ix_; + size_t block_len_; + size_t entropy_ix_; + std::vector depths_; + std::vector bits_; +}; + +void JumpToByteBoundary(size_t* storage_ix, uint8_t* storage) { + *storage_ix = (*storage_ix + 7u) & ~7u; + storage[*storage_ix >> 3] = 0; +} + +void StoreMetaBlock(const uint8_t* input, + size_t start_pos, + size_t length, + size_t mask, + uint8_t prev_byte, + uint8_t prev_byte2, + bool is_last, + uint32_t num_direct_distance_codes, + uint32_t distance_postfix_bits, + ContextType literal_context_mode, + const brotli::Command *commands, + size_t n_commands, + const MetaBlockSplit& mb, + size_t *storage_ix, + uint8_t *storage) { + StoreCompressedMetaBlockHeader(is_last, length, storage_ix, storage); + + size_t num_distance_codes = + kNumDistanceShortCodes + num_direct_distance_codes + + (48u << distance_postfix_bits); + + BlockEncoder literal_enc(256, + mb.literal_split.num_types, + mb.literal_split.types, + mb.literal_split.lengths); + BlockEncoder command_enc(kNumCommandPrefixes, + mb.command_split.num_types, + mb.command_split.types, + mb.command_split.lengths); + BlockEncoder distance_enc(num_distance_codes, + mb.distance_split.num_types, + mb.distance_split.types, + mb.distance_split.lengths); + + literal_enc.BuildAndStoreBlockSwitchEntropyCodes(storage_ix, storage); + command_enc.BuildAndStoreBlockSwitchEntropyCodes(storage_ix, storage); + distance_enc.BuildAndStoreBlockSwitchEntropyCodes(storage_ix, storage); + + WriteBits(2, distance_postfix_bits, storage_ix, storage); + WriteBits(4, num_direct_distance_codes >> distance_postfix_bits, + storage_ix, storage); + for (size_t i = 0; i < mb.literal_split.num_types; ++i) { + WriteBits(2, literal_context_mode, storage_ix, storage); + } + + size_t num_literal_histograms = mb.literal_histograms.size(); + if (mb.literal_context_map.empty()) { + StoreTrivialContextMap(num_literal_histograms, kLiteralContextBits, + storage_ix, storage); + } else { + EncodeContextMap(mb.literal_context_map, num_literal_histograms, + storage_ix, storage); + } + + size_t num_dist_histograms = mb.distance_histograms.size(); + if (mb.distance_context_map.empty()) { + StoreTrivialContextMap(num_dist_histograms, kDistanceContextBits, + storage_ix, storage); + } else { + EncodeContextMap(mb.distance_context_map, num_dist_histograms, + storage_ix, storage); + } + + literal_enc.BuildAndStoreEntropyCodes(mb.literal_histograms, + storage_ix, storage); + command_enc.BuildAndStoreEntropyCodes(mb.command_histograms, + storage_ix, storage); + distance_enc.BuildAndStoreEntropyCodes(mb.distance_histograms, + storage_ix, storage); + + size_t pos = start_pos; + for (size_t i = 0; i < n_commands; ++i) { + const Command cmd = commands[i]; + size_t cmd_code = cmd.cmd_prefix_; + uint32_t lennumextra = static_cast(cmd.cmd_extra_ >> 48); + uint64_t lenextra = cmd.cmd_extra_ & 0xffffffffffffUL; + command_enc.StoreSymbol(cmd_code, storage_ix, storage); + WriteBits(lennumextra, lenextra, storage_ix, storage); + if (mb.literal_context_map.empty()) { + for (size_t j = cmd.insert_len_; j != 0; --j) { + literal_enc.StoreSymbol(input[pos & mask], storage_ix, storage); + ++pos; + } + } else { + for (size_t j = cmd.insert_len_; j != 0; --j) { + size_t context = Context(prev_byte, prev_byte2, literal_context_mode); + uint8_t literal = input[pos & mask]; + literal_enc.StoreSymbolWithContext( + literal, context, mb.literal_context_map, storage_ix, storage); + prev_byte2 = prev_byte; + prev_byte = literal; + ++pos; + } + } + pos += cmd.copy_len_; + if (cmd.copy_len_ > 0) { + prev_byte2 = input[(pos - 2) & mask]; + prev_byte = input[(pos - 1) & mask]; + if (cmd.cmd_prefix_ >= 128) { + size_t dist_code = cmd.dist_prefix_; + uint32_t distnumextra = cmd.dist_extra_ >> 24; + uint64_t distextra = cmd.dist_extra_ & 0xffffff; + if (mb.distance_context_map.empty()) { + distance_enc.StoreSymbol(dist_code, storage_ix, storage); + } else { + size_t context = cmd.DistanceContext(); + distance_enc.StoreSymbolWithContext( + dist_code, context, mb.distance_context_map, storage_ix, storage); + } + brotli::WriteBits(distnumextra, distextra, storage_ix, storage); + } + } + } + if (is_last) { + JumpToByteBoundary(storage_ix, storage); + } +} + +void BuildHistograms(const uint8_t* input, + size_t start_pos, + size_t mask, + const brotli::Command *commands, + size_t n_commands, + HistogramLiteral* lit_histo, + HistogramCommand* cmd_histo, + HistogramDistance* dist_histo) { + size_t pos = start_pos; + for (size_t i = 0; i < n_commands; ++i) { + const Command cmd = commands[i]; + cmd_histo->Add(cmd.cmd_prefix_); + for (size_t j = cmd.insert_len_; j != 0; --j) { + lit_histo->Add(input[pos & mask]); + ++pos; + } + pos += cmd.copy_len_; + if (cmd.copy_len_ > 0 && cmd.cmd_prefix_ >= 128) { + dist_histo->Add(cmd.dist_prefix_); + } + } +} + +void StoreDataWithHuffmanCodes(const uint8_t* input, + size_t start_pos, + size_t mask, + const brotli::Command *commands, + size_t n_commands, + const uint8_t* lit_depth, + const uint16_t* lit_bits, + const uint8_t* cmd_depth, + const uint16_t* cmd_bits, + const uint8_t* dist_depth, + const uint16_t* dist_bits, + size_t* storage_ix, + uint8_t* storage) { + size_t pos = start_pos; + for (size_t i = 0; i < n_commands; ++i) { + const Command cmd = commands[i]; + const size_t cmd_code = cmd.cmd_prefix_; + const uint32_t lennumextra = static_cast(cmd.cmd_extra_ >> 48); + const uint64_t lenextra = cmd.cmd_extra_ & 0xffffffffffffUL; + WriteBits(cmd_depth[cmd_code], cmd_bits[cmd_code], storage_ix, storage); + WriteBits(lennumextra, lenextra, storage_ix, storage); + for (size_t j = cmd.insert_len_; j != 0; --j) { + const uint8_t literal = input[pos & mask]; + WriteBits(lit_depth[literal], lit_bits[literal], storage_ix, storage); + ++pos; + } + pos += cmd.copy_len_; + if (cmd.copy_len_ > 0 && cmd.cmd_prefix_ >= 128) { + const size_t dist_code = cmd.dist_prefix_; + const uint32_t distnumextra = cmd.dist_extra_ >> 24; + const uint32_t distextra = cmd.dist_extra_ & 0xffffff; + WriteBits(dist_depth[dist_code], dist_bits[dist_code], + storage_ix, storage); + WriteBits(distnumextra, distextra, storage_ix, storage); + } + } +} + +void StoreMetaBlockTrivial(const uint8_t* input, + size_t start_pos, + size_t length, + size_t mask, + bool is_last, + const brotli::Command *commands, + size_t n_commands, + size_t *storage_ix, + uint8_t *storage) { + StoreCompressedMetaBlockHeader(is_last, length, storage_ix, storage); + + HistogramLiteral lit_histo; + HistogramCommand cmd_histo; + HistogramDistance dist_histo; + + BuildHistograms(input, start_pos, mask, commands, n_commands, + &lit_histo, &cmd_histo, &dist_histo); + + WriteBits(13, 0, storage_ix, storage); + + std::vector lit_depth(256); + std::vector lit_bits(256); + std::vector cmd_depth(kNumCommandPrefixes); + std::vector cmd_bits(kNumCommandPrefixes); + std::vector dist_depth(64); + std::vector dist_bits(64); + + BuildAndStoreHuffmanTree(&lit_histo.data_[0], 256, + &lit_depth[0], &lit_bits[0], + storage_ix, storage); + BuildAndStoreHuffmanTree(&cmd_histo.data_[0], kNumCommandPrefixes, + &cmd_depth[0], &cmd_bits[0], + storage_ix, storage); + BuildAndStoreHuffmanTree(&dist_histo.data_[0], 64, + &dist_depth[0], &dist_bits[0], + storage_ix, storage); + StoreDataWithHuffmanCodes(input, start_pos, mask, commands, + n_commands, &lit_depth[0], &lit_bits[0], + &cmd_depth[0], &cmd_bits[0], + &dist_depth[0], &dist_bits[0], + storage_ix, storage); + if (is_last) { + JumpToByteBoundary(storage_ix, storage); + } +} + +void StoreMetaBlockFast(const uint8_t* input, + size_t start_pos, + size_t length, + size_t mask, + bool is_last, + const brotli::Command *commands, + size_t n_commands, + size_t *storage_ix, + uint8_t *storage) { + StoreCompressedMetaBlockHeader(is_last, length, storage_ix, storage); + + WriteBits(13, 0, storage_ix, storage); + + if (n_commands <= 128) { + uint32_t histogram[256] = { 0 }; + size_t pos = start_pos; + size_t num_literals = 0; + for (size_t i = 0; i < n_commands; ++i) { + const Command cmd = commands[i]; + for (size_t j = cmd.insert_len_; j != 0; --j) { + ++histogram[input[pos & mask]]; + ++pos; + } + num_literals += cmd.insert_len_; + pos += cmd.copy_len_; + } + uint8_t lit_depth[256] = { 0 }; + uint16_t lit_bits[256] = { 0 }; + BuildAndStoreHuffmanTreeFast(histogram, num_literals, + /* max_bits = */ 8, + lit_depth, lit_bits, + storage_ix, storage); + StoreStaticCommandHuffmanTree(storage_ix, storage); + StoreStaticDistanceHuffmanTree(storage_ix, storage); + StoreDataWithHuffmanCodes(input, start_pos, mask, commands, + n_commands, &lit_depth[0], &lit_bits[0], + kStaticCommandCodeDepth, + kStaticCommandCodeBits, + kStaticDistanceCodeDepth, + kStaticDistanceCodeBits, + storage_ix, storage); + } else { + HistogramLiteral lit_histo; + HistogramCommand cmd_histo; + HistogramDistance dist_histo; + BuildHistograms(input, start_pos, mask, commands, n_commands, + &lit_histo, &cmd_histo, &dist_histo); + std::vector lit_depth(256); + std::vector lit_bits(256); + std::vector cmd_depth(kNumCommandPrefixes); + std::vector cmd_bits(kNumCommandPrefixes); + std::vector dist_depth(64); + std::vector dist_bits(64); + BuildAndStoreHuffmanTreeFast(&lit_histo.data_[0], lit_histo.total_count_, + /* max_bits = */ 8, + &lit_depth[0], &lit_bits[0], + storage_ix, storage); + BuildAndStoreHuffmanTreeFast(&cmd_histo.data_[0], cmd_histo.total_count_, + /* max_bits = */ 10, + &cmd_depth[0], &cmd_bits[0], + storage_ix, storage); + BuildAndStoreHuffmanTreeFast(&dist_histo.data_[0], dist_histo.total_count_, + /* max_bits = */ 6, + &dist_depth[0], &dist_bits[0], + storage_ix, storage); + StoreDataWithHuffmanCodes(input, start_pos, mask, commands, + n_commands, &lit_depth[0], &lit_bits[0], + &cmd_depth[0], &cmd_bits[0], + &dist_depth[0], &dist_bits[0], + storage_ix, storage); + } + + if (is_last) { + JumpToByteBoundary(storage_ix, storage); + } +} + +// This is for storing uncompressed blocks (simple raw storage of +// bytes-as-bytes). +void StoreUncompressedMetaBlock(bool final_block, + const uint8_t * __restrict input, + size_t position, size_t mask, + size_t len, + size_t * __restrict storage_ix, + uint8_t * __restrict storage) { + StoreUncompressedMetaBlockHeader(len, storage_ix, storage); + JumpToByteBoundary(storage_ix, storage); + + size_t masked_pos = position & mask; + if (masked_pos + len > mask + 1) { + size_t len1 = mask + 1 - masked_pos; + memcpy(&storage[*storage_ix >> 3], &input[masked_pos], len1); + *storage_ix += len1 << 3; + len -= len1; + masked_pos = 0; + } + memcpy(&storage[*storage_ix >> 3], &input[masked_pos], len); + *storage_ix += len << 3; + + // We need to clear the next 4 bytes to continue to be + // compatible with WriteBits. + brotli::WriteBitsPrepareStorage(*storage_ix, storage); + + // Since the uncompressed block itself may not be the final block, add an + // empty one after this. + if (final_block) { + brotli::WriteBits(1, 1, storage_ix, storage); // islast + brotli::WriteBits(1, 1, storage_ix, storage); // isempty + JumpToByteBoundary(storage_ix, storage); + } +} + +void StoreSyncMetaBlock(size_t * __restrict storage_ix, + uint8_t * __restrict storage) { + // Empty metadata meta-block bit pattern: + // 1 bit: is_last (0) + // 2 bits: num nibbles (3) + // 1 bit: reserved (0) + // 2 bits: metadata length bytes (0) + WriteBits(6, 6, storage_ix, storage); + JumpToByteBoundary(storage_ix, storage); +} + +} // namespace brotli diff --git a/web/server/h2o/libh2o/deps/brotli/enc/brotli_bit_stream.h b/web/server/h2o/libh2o/deps/brotli/enc/brotli_bit_stream.h new file mode 100644 index 00000000..b05f1e2b --- /dev/null +++ b/web/server/h2o/libh2o/deps/brotli/enc/brotli_bit_stream.h @@ -0,0 +1,175 @@ +/* Copyright 2014 Google Inc. All Rights Reserved. + + Distributed under MIT license. + See file LICENSE for detail or copy at https://opensource.org/licenses/MIT +*/ + +// Functions to convert brotli-related data structures into the +// brotli bit stream. The functions here operate under +// assumption that there is enough space in the storage, i.e., there are +// no out-of-range checks anywhere. +// +// These functions do bit addressing into a byte array. The byte array +// is called "storage" and the index to the bit is called storage_ix +// in function arguments. + +#ifndef BROTLI_ENC_BROTLI_BIT_STREAM_H_ +#define BROTLI_ENC_BROTLI_BIT_STREAM_H_ + +#include + +#include "./metablock.h" +#include "./types.h" + +namespace brotli { + +// All Store functions here will use a storage_ix, which is always the bit +// position for the current storage. + +// Stores a number between 0 and 255. +void StoreVarLenUint8(size_t n, size_t* storage_ix, uint8_t* storage); + +// Stores the compressed meta-block header. +// REQUIRES: length > 0 +// REQUIRES: length <= (1 << 24) +void StoreCompressedMetaBlockHeader(bool final_block, + size_t length, + size_t* storage_ix, + uint8_t* storage); + +// Stores the uncompressed meta-block header. +// REQUIRES: length > 0 +// REQUIRES: length <= (1 << 24) +void StoreUncompressedMetaBlockHeader(size_t length, + size_t* storage_ix, + uint8_t* storage); + +// Stores a context map where the histogram type is always the block type. +void StoreTrivialContextMap(size_t num_types, + size_t context_bits, + size_t* storage_ix, + uint8_t* storage); + +void StoreHuffmanTreeOfHuffmanTreeToBitMask( + const int num_codes, + const uint8_t *code_length_bitdepth, + size_t *storage_ix, + uint8_t *storage); + +void StoreHuffmanTree(const uint8_t* depths, size_t num, + size_t *storage_ix, uint8_t *storage); + +// Builds a Huffman tree from histogram[0:length] into depth[0:length] and +// bits[0:length] and stores the encoded tree to the bit stream. +void BuildAndStoreHuffmanTree(const uint32_t *histogram, + const size_t length, + uint8_t* depth, + uint16_t* bits, + size_t* storage_ix, + uint8_t* storage); + +void BuildAndStoreHuffmanTreeFast(const uint32_t *histogram, + const size_t histogram_total, + const size_t max_bits, + uint8_t* depth, + uint16_t* bits, + size_t* storage_ix, + uint8_t* storage); + +// Encodes the given context map to the bit stream. The number of different +// histogram ids is given by num_clusters. +void EncodeContextMap(const std::vector& context_map, + size_t num_clusters, + size_t* storage_ix, uint8_t* storage); + +// Data structure that stores everything that is needed to encode each block +// switch command. +struct BlockSplitCode { + std::vector type_code; + std::vector length_prefix; + std::vector length_nextra; + std::vector length_extra; + std::vector type_depths; + std::vector type_bits; + std::vector length_depths; + std::vector length_bits; +}; + +// Builds a BlockSplitCode data structure from the block split given by the +// vector of block types and block lengths and stores it to the bit stream. +void BuildAndStoreBlockSplitCode(const std::vector& types, + const std::vector& lengths, + const size_t num_types, + BlockSplitCode* code, + size_t* storage_ix, + uint8_t* storage); + +// Stores the block switch command with index block_ix to the bit stream. +void StoreBlockSwitch(const BlockSplitCode& code, + const size_t block_ix, + size_t* storage_ix, + uint8_t* storage); + +// REQUIRES: length > 0 +// REQUIRES: length <= (1 << 24) +void StoreMetaBlock(const uint8_t* input, + size_t start_pos, + size_t length, + size_t mask, + uint8_t prev_byte, + uint8_t prev_byte2, + bool final_block, + uint32_t num_direct_distance_codes, + uint32_t distance_postfix_bits, + ContextType literal_context_mode, + const brotli::Command *commands, + size_t n_commands, + const MetaBlockSplit& mb, + size_t *storage_ix, + uint8_t *storage); + +// Stores the meta-block without doing any block splitting, just collects +// one histogram per block category and uses that for entropy coding. +// REQUIRES: length > 0 +// REQUIRES: length <= (1 << 24) +void StoreMetaBlockTrivial(const uint8_t* input, + size_t start_pos, + size_t length, + size_t mask, + bool is_last, + const brotli::Command *commands, + size_t n_commands, + size_t *storage_ix, + uint8_t *storage); + +// Same as above, but uses static prefix codes for histograms with a only a few +// symbols, and uses static code length prefix codes for all other histograms. +// REQUIRES: length > 0 +// REQUIRES: length <= (1 << 24) +void StoreMetaBlockFast(const uint8_t* input, + size_t start_pos, + size_t length, + size_t mask, + bool is_last, + const brotli::Command *commands, + size_t n_commands, + size_t *storage_ix, + uint8_t *storage); + +// This is for storing uncompressed blocks (simple raw storage of +// bytes-as-bytes). +// REQUIRES: length > 0 +// REQUIRES: length <= (1 << 24) +void StoreUncompressedMetaBlock(bool final_block, + const uint8_t* input, + size_t position, size_t mask, + size_t len, + size_t* storage_ix, + uint8_t* storage); + +// Stores an empty metadata meta-block and syncs to a byte boundary. +void StoreSyncMetaBlock(size_t* storage_ix, uint8_t* storage); + +} // namespace brotli + +#endif // BROTLI_ENC_BROTLI_BIT_STREAM_H_ diff --git a/web/server/h2o/libh2o/deps/brotli/enc/cluster.h b/web/server/h2o/libh2o/deps/brotli/enc/cluster.h new file mode 100644 index 00000000..4f6c06ee --- /dev/null +++ b/web/server/h2o/libh2o/deps/brotli/enc/cluster.h @@ -0,0 +1,297 @@ +/* Copyright 2013 Google Inc. All Rights Reserved. + + Distributed under MIT license. + See file LICENSE for detail or copy at https://opensource.org/licenses/MIT +*/ + +// Functions for clustering similar histograms together. + +#ifndef BROTLI_ENC_CLUSTER_H_ +#define BROTLI_ENC_CLUSTER_H_ + +#include +#include +#include +#include +#include + +#include "./bit_cost.h" +#include "./entropy_encode.h" +#include "./fast_log.h" +#include "./histogram.h" +#include "./port.h" +#include "./types.h" + +namespace brotli { + +struct HistogramPair { + uint32_t idx1; + uint32_t idx2; + double cost_combo; + double cost_diff; +}; + +inline bool operator<(const HistogramPair& p1, const HistogramPair& p2) { + if (p1.cost_diff != p2.cost_diff) { + return p1.cost_diff > p2.cost_diff; + } + return (p1.idx2 - p1.idx1) > (p2.idx2 - p2.idx1); +} + +// Returns entropy reduction of the context map when we combine two clusters. +inline double ClusterCostDiff(size_t size_a, size_t size_b) { + size_t size_c = size_a + size_b; + return static_cast(size_a) * FastLog2(size_a) + + static_cast(size_b) * FastLog2(size_b) - + static_cast(size_c) * FastLog2(size_c); +} + +// Computes the bit cost reduction by combining out[idx1] and out[idx2] and if +// it is below a threshold, stores the pair (idx1, idx2) in the *pairs queue. +template +void CompareAndPushToQueue(const HistogramType* out, + const uint32_t* cluster_size, + uint32_t idx1, uint32_t idx2, + std::vector* pairs) { + if (idx1 == idx2) { + return; + } + if (idx2 < idx1) { + uint32_t t = idx2; + idx2 = idx1; + idx1 = t; + } + bool store_pair = false; + HistogramPair p; + p.idx1 = idx1; + p.idx2 = idx2; + p.cost_diff = 0.5 * ClusterCostDiff(cluster_size[idx1], cluster_size[idx2]); + p.cost_diff -= out[idx1].bit_cost_; + p.cost_diff -= out[idx2].bit_cost_; + + if (out[idx1].total_count_ == 0) { + p.cost_combo = out[idx2].bit_cost_; + store_pair = true; + } else if (out[idx2].total_count_ == 0) { + p.cost_combo = out[idx1].bit_cost_; + store_pair = true; + } else { + double threshold = pairs->empty() ? 1e99 : + std::max(0.0, (*pairs)[0].cost_diff); + HistogramType combo = out[idx1]; + combo.AddHistogram(out[idx2]); + double cost_combo = PopulationCost(combo); + if (cost_combo < threshold - p.cost_diff) { + p.cost_combo = cost_combo; + store_pair = true; + } + } + if (store_pair) { + p.cost_diff += p.cost_combo; + if (!pairs->empty() && (pairs->front() < p)) { + // Replace the top of the queue if needed. + pairs->push_back(pairs->front()); + pairs->front() = p; + } else { + pairs->push_back(p); + } + } +} + +template +void HistogramCombine(HistogramType* out, + uint32_t* cluster_size, + uint32_t* symbols, + size_t symbols_size, + size_t max_clusters) { + double cost_diff_threshold = 0.0; + size_t min_cluster_size = 1; + + // Uniquify the list of symbols. + std::vector clusters(symbols, symbols + symbols_size); + std::sort(clusters.begin(), clusters.end()); + std::vector::iterator last = + std::unique(clusters.begin(), clusters.end()); + clusters.resize(static_cast(last - clusters.begin())); + + // We maintain a heap of histogram pairs, ordered by the bit cost reduction. + std::vector pairs; + for (size_t idx1 = 0; idx1 < clusters.size(); ++idx1) { + for (size_t idx2 = idx1 + 1; idx2 < clusters.size(); ++idx2) { + CompareAndPushToQueue(out, cluster_size, clusters[idx1], clusters[idx2], + &pairs); + } + } + + while (clusters.size() > min_cluster_size) { + if (pairs[0].cost_diff >= cost_diff_threshold) { + cost_diff_threshold = 1e99; + min_cluster_size = max_clusters; + continue; + } + // Take the best pair from the top of heap. + uint32_t best_idx1 = pairs[0].idx1; + uint32_t best_idx2 = pairs[0].idx2; + out[best_idx1].AddHistogram(out[best_idx2]); + out[best_idx1].bit_cost_ = pairs[0].cost_combo; + cluster_size[best_idx1] += cluster_size[best_idx2]; + for (size_t i = 0; i < symbols_size; ++i) { + if (symbols[i] == best_idx2) { + symbols[i] = best_idx1; + } + } + for (std::vector::iterator cluster = clusters.begin(); + cluster != clusters.end(); ++cluster) { + if (*cluster >= best_idx2) { + clusters.erase(cluster); + break; + } + } + + // Remove pairs intersecting the just combined best pair. + size_t copy_to_idx = 0; + for (size_t i = 0; i < pairs.size(); ++i) { + HistogramPair& p = pairs[i]; + if (p.idx1 == best_idx1 || p.idx2 == best_idx1 || + p.idx1 == best_idx2 || p.idx2 == best_idx2) { + // Remove invalid pair from the queue. + continue; + } + if (pairs.front() < p) { + // Replace the top of the queue if needed. + HistogramPair front = pairs.front(); + pairs.front() = p; + pairs[copy_to_idx] = front; + } else { + pairs[copy_to_idx] = p; + } + ++copy_to_idx; + } + pairs.resize(copy_to_idx); + + // Push new pairs formed with the combined histogram to the heap. + for (size_t i = 0; i < clusters.size(); ++i) { + CompareAndPushToQueue(out, cluster_size, best_idx1, clusters[i], &pairs); + } + } +} + +// ----------------------------------------------------------------------------- +// Histogram refinement + +// What is the bit cost of moving histogram from cur_symbol to candidate. +template +double HistogramBitCostDistance(const HistogramType& histogram, + const HistogramType& candidate) { + if (histogram.total_count_ == 0) { + return 0.0; + } + HistogramType tmp = histogram; + tmp.AddHistogram(candidate); + return PopulationCost(tmp) - candidate.bit_cost_; +} + +// Find the best 'out' histogram for each of the 'in' histograms. +// Note: we assume that out[]->bit_cost_ is already up-to-date. +template +void HistogramRemap(const HistogramType* in, size_t in_size, + HistogramType* out, uint32_t* symbols) { + // Uniquify the list of symbols. + std::vector all_symbols(symbols, symbols + in_size); + std::sort(all_symbols.begin(), all_symbols.end()); + std::vector::iterator last = + std::unique(all_symbols.begin(), all_symbols.end()); + all_symbols.resize(static_cast(last - all_symbols.begin())); + + for (size_t i = 0; i < in_size; ++i) { + uint32_t best_out = i == 0 ? symbols[0] : symbols[i - 1]; + double best_bits = HistogramBitCostDistance(in[i], out[best_out]); + for (std::vector::const_iterator k = all_symbols.begin(); + k != all_symbols.end(); ++k) { + const double cur_bits = HistogramBitCostDistance(in[i], out[*k]); + if (cur_bits < best_bits) { + best_bits = cur_bits; + best_out = *k; + } + } + symbols[i] = best_out; + } + + + // Recompute each out based on raw and symbols. + for (std::vector::const_iterator k = all_symbols.begin(); + k != all_symbols.end(); ++k) { + out[*k].Clear(); + } + for (size_t i = 0; i < in_size; ++i) { + out[symbols[i]].AddHistogram(in[i]); + } +} + +// Reorder histograms in *out so that the new symbols in *symbols come in +// increasing order. +template +void HistogramReindex(std::vector* out, + std::vector* symbols) { + std::vector tmp(*out); + std::map new_index; + uint32_t next_index = 0; + for (size_t i = 0; i < symbols->size(); ++i) { + if (new_index.find((*symbols)[i]) == new_index.end()) { + new_index[(*symbols)[i]] = next_index; + (*out)[next_index] = tmp[(*symbols)[i]]; + ++next_index; + } + } + out->resize(next_index); + for (size_t i = 0; i < symbols->size(); ++i) { + (*symbols)[i] = new_index[(*symbols)[i]]; + } +} + +// Clusters similar histograms in 'in' together, the selected histograms are +// placed in 'out', and for each index in 'in', *histogram_symbols will +// indicate which of the 'out' histograms is the best approximation. +template +void ClusterHistograms(const std::vector& in, + size_t num_contexts, size_t num_blocks, + size_t max_histograms, + std::vector* out, + std::vector* histogram_symbols) { + const size_t in_size = num_contexts * num_blocks; + assert(in_size == in.size()); + std::vector cluster_size(in_size, 1); + out->resize(in_size); + histogram_symbols->resize(in_size); + for (size_t i = 0; i < in_size; ++i) { + (*out)[i] = in[i]; + (*out)[i].bit_cost_ = PopulationCost(in[i]); + (*histogram_symbols)[i] = static_cast(i); + } + + + const size_t max_input_histograms = 64; + for (size_t i = 0; i < in_size; i += max_input_histograms) { + size_t num_to_combine = std::min(in_size - i, max_input_histograms); + HistogramCombine(&(*out)[0], &cluster_size[0], + &(*histogram_symbols)[i], num_to_combine, + max_histograms); + } + + // Collapse similar histograms. + HistogramCombine(&(*out)[0], &cluster_size[0], + &(*histogram_symbols)[0], in_size, + max_histograms); + + // Find the optimal map from original histograms to the final ones. + HistogramRemap(&in[0], in_size, &(*out)[0], &(*histogram_symbols)[0]); + + // Convert the context map to a canonical form. + HistogramReindex(out, histogram_symbols); + +} + + +} // namespace brotli + +#endif // BROTLI_ENC_CLUSTER_H_ diff --git a/web/server/h2o/libh2o/deps/brotli/enc/command.h b/web/server/h2o/libh2o/deps/brotli/enc/command.h new file mode 100644 index 00000000..afb014be --- /dev/null +++ b/web/server/h2o/libh2o/deps/brotli/enc/command.h @@ -0,0 +1,136 @@ +/* Copyright 2013 Google Inc. All Rights Reserved. + + Distributed under MIT license. + See file LICENSE for detail or copy at https://opensource.org/licenses/MIT +*/ + +// This class models a sequence of literals and a backward reference copy. + +#ifndef BROTLI_ENC_COMMAND_H_ +#define BROTLI_ENC_COMMAND_H_ + +#include "./fast_log.h" +#include "./prefix.h" +#include "./types.h" + +namespace brotli { + +static uint32_t kInsBase[] = { 0, 1, 2, 3, 4, 5, 6, 8, 10, 14, 18, 26, 34, 50, + 66, 98, 130, 194, 322, 578, 1090, 2114, 6210, 22594 }; +static uint32_t kInsExtra[] = { 0, 0, 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, + 5, 5, 6, 7, 8, 9, 10, 12, 14, 24 }; +static uint32_t kCopyBase[] = { 2, 3, 4, 5, 6, 7, 8, 9, 10, 12, 14, 18, 22, 30, + 38, 54, 70, 102, 134, 198, 326, 582, 1094, 2118 }; +static uint32_t kCopyExtra[] = { 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, + 4, 4, 5, 5, 6, 7, 8, 9, 10, 24 }; + +static inline uint16_t GetInsertLengthCode(size_t insertlen) { + if (insertlen < 6) { + return static_cast(insertlen); + } else if (insertlen < 130) { + insertlen -= 2; + uint32_t nbits = Log2FloorNonZero(insertlen) - 1u; + return static_cast((nbits << 1) + (insertlen >> nbits) + 2); + } else if (insertlen < 2114) { + return static_cast(Log2FloorNonZero(insertlen - 66) + 10); + } else if (insertlen < 6210) { + return 21u; + } else if (insertlen < 22594) { + return 22u; + } else { + return 23u; + } +} + +static inline uint16_t GetCopyLengthCode(size_t copylen) { + if (copylen < 10) { + return static_cast(copylen - 2); + } else if (copylen < 134) { + copylen -= 6; + uint32_t nbits = Log2FloorNonZero(copylen) - 1u; + return static_cast((nbits << 1) + (copylen >> nbits) + 4); + } else if (copylen < 2118) { + return static_cast(Log2FloorNonZero(copylen - 70) + 12); + } else { + return 23u; + } +} + +static inline uint16_t CombineLengthCodes( + uint16_t inscode, uint16_t copycode, bool use_last_distance) { + uint16_t bits64 = + static_cast((copycode & 0x7u) | ((inscode & 0x7u) << 3)); + if (use_last_distance && inscode < 8 && copycode < 16) { + return (copycode < 8) ? bits64 : (bits64 | 64); + } else { + // "To convert an insert-and-copy length code to an insert length code and + // a copy length code, the following table can be used" + static const uint16_t cells[9] = { 128u, 192u, 384u, 256u, 320u, 512u, + 448u, 576u, 640u }; + return cells[(copycode >> 3) + 3 * (inscode >> 3)] | bits64; + } +} + +static inline void GetLengthCode(size_t insertlen, size_t copylen, + bool use_last_distance, + uint16_t* code, uint64_t* extra) { + uint16_t inscode = GetInsertLengthCode(insertlen); + uint16_t copycode = GetCopyLengthCode(copylen); + uint64_t insnumextra = kInsExtra[inscode]; + uint64_t numextra = insnumextra + kCopyExtra[copycode]; + uint64_t insextraval = insertlen - kInsBase[inscode]; + uint64_t copyextraval = copylen - kCopyBase[copycode]; + *code = CombineLengthCodes(inscode, copycode, use_last_distance); + *extra = (numextra << 48) | (copyextraval << insnumextra) | insextraval; +} + +struct Command { + // distance_code is e.g. 0 for same-as-last short code, or 16 for offset 1. + Command(size_t insertlen, size_t copylen, size_t copylen_code, + size_t distance_code) + : insert_len_(static_cast(insertlen)) + , copy_len_(static_cast(copylen)) { + // The distance prefix and extra bits are stored in this Command as if + // npostfix and ndirect were 0, they are only recomputed later after the + // clustering if needed. + PrefixEncodeCopyDistance(distance_code, 0, 0, &dist_prefix_, &dist_extra_); + GetLengthCode(insertlen, copylen_code, dist_prefix_ == 0, + &cmd_prefix_, &cmd_extra_); + } + + explicit Command(size_t insertlen) + : insert_len_(static_cast(insertlen)) + , copy_len_(0), dist_extra_(0), dist_prefix_(16) { + GetLengthCode(insertlen, 4, dist_prefix_ == 0, &cmd_prefix_, &cmd_extra_); + } + + uint32_t DistanceCode() const { + if (dist_prefix_ < 16) { + return dist_prefix_; + } + uint32_t nbits = dist_extra_ >> 24; + uint32_t extra = dist_extra_ & 0xffffff; + uint32_t prefix = dist_prefix_ - 12 - 2 * nbits; + return (prefix << nbits) + extra + 12; + } + + uint32_t DistanceContext() const { + uint32_t r = cmd_prefix_ >> 6; + uint32_t c = cmd_prefix_ & 7; + if ((r == 0 || r == 2 || r == 4 || r == 7) && (c <= 2)) { + return c; + } + return 3; + } + + uint32_t insert_len_; + uint32_t copy_len_; + uint64_t cmd_extra_; + uint32_t dist_extra_; + uint16_t cmd_prefix_; + uint16_t dist_prefix_; +}; + +} // namespace brotli + +#endif // BROTLI_ENC_COMMAND_H_ diff --git a/web/server/h2o/libh2o/deps/brotli/enc/compress_fragment.cc b/web/server/h2o/libh2o/deps/brotli/enc/compress_fragment.cc new file mode 100644 index 00000000..047d7fe9 --- /dev/null +++ b/web/server/h2o/libh2o/deps/brotli/enc/compress_fragment.cc @@ -0,0 +1,693 @@ +/* Copyright 2015 Google Inc. All Rights Reserved. + + Distributed under MIT license. + See file LICENSE for detail or copy at https://opensource.org/licenses/MIT +*/ + +// Function for fast encoding of an input fragment, independently from the input +// history. This function uses one-pass processing: when we find a backward +// match, we immediately emit the corresponding command and literal codes to +// the bit stream. +// +// Adapted from the CompressFragment() function in +// https://github.com/google/snappy/blob/master/snappy.cc + +#include "./compress_fragment.h" + +#include +#include + +#include "./brotli_bit_stream.h" +#include "./entropy_encode.h" +#include "./fast_log.h" +#include "./find_match_length.h" +#include "./port.h" +#include "./write_bits.h" + +namespace brotli { + +// kHashMul32 multiplier has these properties: +// * The multiplier must be odd. Otherwise we may lose the highest bit. +// * No long streaks of 1s or 0s. +// * There is no effort to ensure that it is a prime, the oddity is enough +// for this use. +// * The number has been tuned heuristically against compression benchmarks. +static const uint32_t kHashMul32 = 0x1e35a7bd; + +static inline uint32_t Hash(const uint8_t* p, size_t shift) { + const uint64_t h = (BROTLI_UNALIGNED_LOAD64(p) << 24) * kHashMul32; + return static_cast(h >> shift); +} + +static inline uint32_t HashBytesAtOffset(uint64_t v, int offset, size_t shift) { + assert(offset >= 0); + assert(offset <= 3); + const uint64_t h = ((v >> (8 * offset)) << 24) * kHashMul32; + return static_cast(h >> shift); +} + +static inline int IsMatch(const uint8_t* p1, const uint8_t* p2) { + return (BROTLI_UNALIGNED_LOAD32(p1) == BROTLI_UNALIGNED_LOAD32(p2) && + p1[4] == p2[4]); +} + +// Builds a literal prefix code into "depths" and "bits" based on the statistics +// of the "input" string and stores it into the bit stream. +// Note that the prefix code here is built from the pre-LZ77 input, therefore +// we can only approximate the statistics of the actual literal stream. +// Moreover, for long inputs we build a histogram from a sample of the input +// and thus have to assign a non-zero depth for each literal. +void BuildAndStoreLiteralPrefixCode(const uint8_t* input, + const size_t input_size, + uint8_t depths[256], + uint16_t bits[256], + size_t* storage_ix, + uint8_t* storage) { + uint32_t histogram[256] = { 0 }; + size_t histogram_total; + if (input_size < (1 << 15)) { + for (size_t i = 0; i < input_size; ++i) { + ++histogram[input[i]]; + } + histogram_total = input_size; + for (size_t i = 0; i < 256; ++i) { + // We weigh the first 11 samples with weight 3 to account for the + // balancing effect of the LZ77 phase on the histogram. + const uint32_t adjust = 2 * std::min(histogram[i], 11u); + histogram[i] += adjust; + histogram_total += adjust; + } + } else { + static const size_t kSampleRate = 29; + for (size_t i = 0; i < input_size; i += kSampleRate) { + ++histogram[input[i]]; + } + histogram_total = (input_size + kSampleRate - 1) / kSampleRate; + for (size_t i = 0; i < 256; ++i) { + // We add 1 to each population count to avoid 0 bit depths (since this is + // only a sample and we don't know if the symbol appears or not), and we + // weigh the first 11 samples with weight 3 to account for the balancing + // effect of the LZ77 phase on the histogram (more frequent symbols are + // more likely to be in backward references instead as literals). + const uint32_t adjust = 1 + 2 * std::min(histogram[i], 11u); + histogram[i] += adjust; + histogram_total += adjust; + } + } + BuildAndStoreHuffmanTreeFast(histogram, histogram_total, + /* max_bits = */ 8, + depths, bits, storage_ix, storage); +} + +// Builds a command and distance prefix code (each 64 symbols) into "depth" and +// "bits" based on "histogram" and stores it into the bit stream. +void BuildAndStoreCommandPrefixCode(const uint32_t histogram[128], + uint8_t depth[128], uint16_t bits[128], + size_t* storage_ix, uint8_t* storage) { + CreateHuffmanTree(histogram, 64, 15, depth); + CreateHuffmanTree(&histogram[64], 64, 14, &depth[64]); + // We have to jump through a few hoopes here in order to compute + // the command bits because the symbols are in a different order than in + // the full alphabet. This looks complicated, but having the symbols + // in this order in the command bits saves a few branches in the Emit* + // functions. + uint8_t cmd_depth[64]; + uint16_t cmd_bits[64]; + memcpy(cmd_depth, depth, 24); + memcpy(cmd_depth + 24, depth + 40, 8); + memcpy(cmd_depth + 32, depth + 24, 8); + memcpy(cmd_depth + 40, depth + 48, 8); + memcpy(cmd_depth + 48, depth + 32, 8); + memcpy(cmd_depth + 56, depth + 56, 8); + ConvertBitDepthsToSymbols(cmd_depth, 64, cmd_bits); + memcpy(bits, cmd_bits, 48); + memcpy(bits + 24, cmd_bits + 32, 16); + memcpy(bits + 32, cmd_bits + 48, 16); + memcpy(bits + 40, cmd_bits + 24, 16); + memcpy(bits + 48, cmd_bits + 40, 16); + memcpy(bits + 56, cmd_bits + 56, 16); + ConvertBitDepthsToSymbols(&depth[64], 64, &bits[64]); + { + // Create the bit length array for the full command alphabet. + uint8_t cmd_depth[704] = { 0 }; + memcpy(cmd_depth, depth, 8); + memcpy(cmd_depth + 64, depth + 8, 8); + memcpy(cmd_depth + 128, depth + 16, 8); + memcpy(cmd_depth + 192, depth + 24, 8); + memcpy(cmd_depth + 384, depth + 32, 8); + for (size_t i = 0; i < 8; ++i) { + cmd_depth[128 + 8 * i] = depth[40 + i]; + cmd_depth[256 + 8 * i] = depth[48 + i]; + cmd_depth[448 + 8 * i] = depth[56 + i]; + } + StoreHuffmanTree(cmd_depth, 704, storage_ix, storage); + } + StoreHuffmanTree(&depth[64], 64, storage_ix, storage); +} + +// REQUIRES: insertlen < 6210 +inline void EmitInsertLen(size_t insertlen, + const uint8_t depth[128], + const uint16_t bits[128], + uint32_t histo[128], + size_t* storage_ix, + uint8_t* storage) { + if (insertlen < 6) { + const size_t code = insertlen + 40; + WriteBits(depth[code], bits[code], storage_ix, storage); + ++histo[code]; + } else if (insertlen < 130) { + insertlen -= 2; + const uint32_t nbits = Log2FloorNonZero(insertlen) - 1u; + const size_t prefix = insertlen >> nbits; + const size_t inscode = (nbits << 1) + prefix + 42; + WriteBits(depth[inscode], bits[inscode], storage_ix, storage); + WriteBits(nbits, insertlen - (prefix << nbits), storage_ix, storage); + ++histo[inscode]; + } else if (insertlen < 2114) { + insertlen -= 66; + const uint32_t nbits = Log2FloorNonZero(insertlen); + const size_t code = nbits + 50; + WriteBits(depth[code], bits[code], storage_ix, storage); + WriteBits(nbits, insertlen - (1 << nbits), storage_ix, storage); + ++histo[code]; + } else { + WriteBits(depth[61], bits[61], storage_ix, storage); + WriteBits(12, insertlen - 2114, storage_ix, storage); + ++histo[21]; + } +} + +inline void EmitLongInsertLen(size_t insertlen, + const uint8_t depth[128], + const uint16_t bits[128], + uint32_t histo[128], + size_t* storage_ix, + uint8_t* storage) { + if (insertlen < 22594) { + WriteBits(depth[62], bits[62], storage_ix, storage); + WriteBits(14, insertlen - 6210, storage_ix, storage); + ++histo[22]; + } else { + WriteBits(depth[63], bits[63], storage_ix, storage); + WriteBits(24, insertlen - 22594, storage_ix, storage); + ++histo[23]; + } +} + +inline void EmitCopyLen(size_t copylen, + const uint8_t depth[128], + const uint16_t bits[128], + uint32_t histo[128], + size_t* storage_ix, + uint8_t* storage) { + if (copylen < 10) { + WriteBits(depth[copylen + 14], bits[copylen + 14], storage_ix, storage); + ++histo[copylen + 14]; + } else if (copylen < 134) { + copylen -= 6; + const uint32_t nbits = Log2FloorNonZero(copylen) - 1u; + const size_t prefix = copylen >> nbits; + const size_t code = (nbits << 1) + prefix + 20; + WriteBits(depth[code], bits[code], storage_ix, storage); + WriteBits(nbits, copylen - (prefix << nbits), storage_ix, storage); + ++histo[code]; + } else if (copylen < 2118) { + copylen -= 70; + const uint32_t nbits = Log2FloorNonZero(copylen); + const size_t code = nbits + 28; + WriteBits(depth[code], bits[code], storage_ix, storage); + WriteBits(nbits, copylen - (1 << nbits), storage_ix, storage); + ++histo[code]; + } else { + WriteBits(depth[39], bits[39], storage_ix, storage); + WriteBits(24, copylen - 2118, storage_ix, storage); + ++histo[47]; + } +} + +inline void EmitCopyLenLastDistance(size_t copylen, + const uint8_t depth[128], + const uint16_t bits[128], + uint32_t histo[128], + size_t* storage_ix, + uint8_t* storage) { + if (copylen < 12) { + WriteBits(depth[copylen - 4], bits[copylen - 4], storage_ix, storage); + ++histo[copylen - 4]; + } else if (copylen < 72) { + copylen -= 8; + const uint32_t nbits = Log2FloorNonZero(copylen) - 1; + const size_t prefix = copylen >> nbits; + const size_t code = (nbits << 1) + prefix + 4; + WriteBits(depth[code], bits[code], storage_ix, storage); + WriteBits(nbits, copylen - (prefix << nbits), storage_ix, storage); + ++histo[code]; + } else if (copylen < 136) { + copylen -= 8; + const size_t code = (copylen >> 5) + 30; + WriteBits(depth[code], bits[code], storage_ix, storage); + WriteBits(5, copylen & 31, storage_ix, storage); + WriteBits(depth[64], bits[64], storage_ix, storage); + ++histo[code]; + ++histo[64]; + } else if (copylen < 2120) { + copylen -= 72; + const uint32_t nbits = Log2FloorNonZero(copylen); + const size_t code = nbits + 28; + WriteBits(depth[code], bits[code], storage_ix, storage); + WriteBits(nbits, copylen - (1 << nbits), storage_ix, storage); + WriteBits(depth[64], bits[64], storage_ix, storage); + ++histo[code]; + ++histo[64]; + } else { + WriteBits(depth[39], bits[39], storage_ix, storage); + WriteBits(24, copylen - 2120, storage_ix, storage); + WriteBits(depth[64], bits[64], storage_ix, storage); + ++histo[47]; + ++histo[64]; + } +} + +inline void EmitDistance(size_t distance, + const uint8_t depth[128], + const uint16_t bits[128], + uint32_t histo[128], + size_t* storage_ix, uint8_t* storage) { + distance += 3; + const uint32_t nbits = Log2FloorNonZero(distance) - 1u; + const size_t prefix = (distance >> nbits) & 1; + const size_t offset = (2 + prefix) << nbits; + const size_t distcode = 2 * (nbits - 1) + prefix + 80; + WriteBits(depth[distcode], bits[distcode], storage_ix, storage); + WriteBits(nbits, distance - offset, storage_ix, storage); + ++histo[distcode]; +} + +inline void EmitLiterals(const uint8_t* input, const size_t len, + const uint8_t depth[256], const uint16_t bits[256], + size_t* storage_ix, uint8_t* storage) { + for (size_t j = 0; j < len; j++) { + const uint8_t lit = input[j]; + WriteBits(depth[lit], bits[lit], storage_ix, storage); + } +} + +// REQUIRES: len <= 1 << 20. +static void StoreMetaBlockHeader( + size_t len, bool is_uncompressed, size_t* storage_ix, uint8_t* storage) { + // ISLAST + WriteBits(1, 0, storage_ix, storage); + if (len <= (1U << 16)) { + // MNIBBLES is 4 + WriteBits(2, 0, storage_ix, storage); + WriteBits(16, len - 1, storage_ix, storage); + } else { + // MNIBBLES is 5 + WriteBits(2, 1, storage_ix, storage); + WriteBits(20, len - 1, storage_ix, storage); + } + // ISUNCOMPRESSED + WriteBits(1, is_uncompressed, storage_ix, storage); +} + +void UpdateBits(size_t n_bits, + uint32_t bits, + size_t pos, + uint8_t *array) { + while (n_bits > 0) { + size_t byte_pos = pos >> 3; + size_t n_unchanged_bits = pos & 7; + size_t n_changed_bits = std::min(n_bits, 8 - n_unchanged_bits); + size_t total_bits = n_unchanged_bits + n_changed_bits; + uint32_t mask = (~((1 << total_bits) - 1)) | ((1 << n_unchanged_bits) - 1); + uint32_t unchanged_bits = array[byte_pos] & mask; + uint32_t changed_bits = bits & ((1 << n_changed_bits) - 1); + array[byte_pos] = + static_cast((changed_bits << n_unchanged_bits) | + unchanged_bits); + n_bits -= n_changed_bits; + bits >>= n_changed_bits; + pos += n_changed_bits; + } +} + +void RewindBitPosition(const size_t new_storage_ix, + size_t* storage_ix, uint8_t* storage) { + const size_t bitpos = new_storage_ix & 7; + const size_t mask = (1u << bitpos) - 1; + storage[new_storage_ix >> 3] &= static_cast(mask); + *storage_ix = new_storage_ix; +} + +bool ShouldMergeBlock(const uint8_t* data, size_t len, const uint8_t* depths) { + size_t histo[256] = { 0 }; + static const size_t kSampleRate = 43; + for (size_t i = 0; i < len; i += kSampleRate) { + ++histo[data[i]]; + } + const size_t total = (len + kSampleRate - 1) / kSampleRate; + double r = (FastLog2(total) + 0.5) * static_cast(total) + 200; + for (size_t i = 0; i < 256; ++i) { + r -= static_cast(histo[i]) * (depths[i] + FastLog2(histo[i])); + } + return r >= 0.0; +} + +inline bool ShouldUseUncompressedMode(const uint8_t* metablock_start, + const uint8_t* next_emit, + const size_t insertlen, + const uint8_t literal_depths[256]) { + const size_t compressed = static_cast(next_emit - metablock_start); + if (compressed * 50 > insertlen) { + return false; + } + static const double kAcceptableLossForUncompressibleSpeedup = 0.02; + static const double kMinEntropy = + 8 * (1.0 - kAcceptableLossForUncompressibleSpeedup); + uint32_t sum = 0; + for (int i = 0; i < 256; ++i) { + const uint32_t n = literal_depths[i]; + sum += n << (15 - n); + } + return sum > static_cast((1 << 15) * kMinEntropy); +} + +void EmitUncompressedMetaBlock(const uint8_t* begin, const uint8_t* end, + const size_t storage_ix_start, + size_t* storage_ix, uint8_t* storage) { + const size_t len = static_cast(end - begin); + RewindBitPosition(storage_ix_start, storage_ix, storage); + StoreMetaBlockHeader(len, 1, storage_ix, storage); + *storage_ix = (*storage_ix + 7u) & ~7u; + memcpy(&storage[*storage_ix >> 3], begin, len); + *storage_ix += len << 3; + storage[*storage_ix >> 3] = 0; +} + +void BrotliCompressFragmentFast(const uint8_t* input, size_t input_size, + bool is_last, + int* table, size_t table_size, + uint8_t cmd_depth[128], uint16_t cmd_bits[128], + size_t* cmd_code_numbits, uint8_t* cmd_code, + size_t* storage_ix, uint8_t* storage) { + if (input_size == 0) { + assert(is_last); + WriteBits(1, 1, storage_ix, storage); // islast + WriteBits(1, 1, storage_ix, storage); // isempty + *storage_ix = (*storage_ix + 7u) & ~7u; + return; + } + + // "next_emit" is a pointer to the first byte that is not covered by a + // previous copy. Bytes between "next_emit" and the start of the next copy or + // the end of the input will be emitted as literal bytes. + const uint8_t* next_emit = input; + // Save the start of the first block for position and distance computations. + const uint8_t* base_ip = input; + + static const size_t kFirstBlockSize = 3 << 15; + static const size_t kMergeBlockSize = 1 << 16; + + const uint8_t* metablock_start = input; + size_t block_size = std::min(input_size, kFirstBlockSize); + size_t total_block_size = block_size; + // Save the bit position of the MLEN field of the meta-block header, so that + // we can update it later if we decide to extend this meta-block. + size_t mlen_storage_ix = *storage_ix + 3; + StoreMetaBlockHeader(block_size, 0, storage_ix, storage); + // No block splits, no contexts. + WriteBits(13, 0, storage_ix, storage); + + uint8_t lit_depth[256] = { 0 }; + uint16_t lit_bits[256] = { 0 }; + BuildAndStoreLiteralPrefixCode(input, block_size, lit_depth, lit_bits, + storage_ix, storage); + + // Store the pre-compressed command and distance prefix codes. + for (size_t i = 0; i + 7 < *cmd_code_numbits; i += 8) { + WriteBits(8, cmd_code[i >> 3], storage_ix, storage); + } + WriteBits(*cmd_code_numbits & 7, cmd_code[*cmd_code_numbits >> 3], + storage_ix, storage); + + emit_commands: + // Initialize the command and distance histograms. We will gather + // statistics of command and distance codes during the processing + // of this block and use it to update the command and distance + // prefix codes for the next block. + uint32_t cmd_histo[128] = { + 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 0, 0, 0, 0, + }; + + // "ip" is the input pointer. + const uint8_t* ip = input; + assert(table_size); + assert(table_size <= (1u << 31)); + assert((table_size & (table_size - 1)) == 0); // table must be power of two + const size_t shift = 64u - Log2FloorNonZero(table_size); + assert(static_cast(0xffffffffffffffffU >> shift) == table_size - 1); + const uint8_t* ip_end = input + block_size; + + int last_distance = -1; + const size_t kInputMarginBytes = 16; + const size_t kMinMatchLen = 5; + if (PREDICT_TRUE(block_size >= kInputMarginBytes)) { + // For the last block, we need to keep a 16 bytes margin so that we can be + // sure that all distances are at most window size - 16. + // For all other blocks, we only need to keep a margin of 5 bytes so that + // we don't go over the block size with a copy. + const size_t len_limit = std::min(block_size - kMinMatchLen, + input_size - kInputMarginBytes); + const uint8_t* ip_limit = input + len_limit; + + for (uint32_t next_hash = Hash(++ip, shift); ; ) { + assert(next_emit < ip); + // Step 1: Scan forward in the input looking for a 5-byte-long match. + // If we get close to exhausting the input then goto emit_remainder. + // + // Heuristic match skipping: If 32 bytes are scanned with no matches + // found, start looking only at every other byte. If 32 more bytes are + // scanned, look at every third byte, etc.. When a match is found, + // immediately go back to looking at every byte. This is a small loss + // (~5% performance, ~0.1% density) for compressible data due to more + // bookkeeping, but for non-compressible data (such as JPEG) it's a huge + // win since the compressor quickly "realizes" the data is incompressible + // and doesn't bother looking for matches everywhere. + // + // The "skip" variable keeps track of how many bytes there are since the + // last match; dividing it by 32 (ie. right-shifting by five) gives the + // number of bytes to move ahead for each iteration. + uint32_t skip = 32; + + const uint8_t* next_ip = ip; + const uint8_t* candidate; + do { + ip = next_ip; + uint32_t hash = next_hash; + assert(hash == Hash(ip, shift)); + uint32_t bytes_between_hash_lookups = skip++ >> 5; + next_ip = ip + bytes_between_hash_lookups; + if (PREDICT_FALSE(next_ip > ip_limit)) { + goto emit_remainder; + } + next_hash = Hash(next_ip, shift); + candidate = ip - last_distance; + if (IsMatch(ip, candidate)) { + if (PREDICT_TRUE(candidate < ip)) { + table[hash] = static_cast(ip - base_ip); + break; + } + } + candidate = base_ip + table[hash]; + assert(candidate >= base_ip); + assert(candidate < ip); + + table[hash] = static_cast(ip - base_ip); + } while (PREDICT_TRUE(!IsMatch(ip, candidate))); + + // Step 2: Emit the found match together with the literal bytes from + // "next_emit" to the bit stream, and then see if we can find a next macth + // immediately afterwards. Repeat until we find no match for the input + // without emitting some literal bytes. + uint64_t input_bytes; + + { + // We have a 5-byte match at ip, and we need to emit bytes in + // [next_emit, ip). + const uint8_t* base = ip; + size_t matched = 5 + FindMatchLengthWithLimit( + candidate + 5, ip + 5, static_cast(ip_end - ip) - 5); + ip += matched; + int distance = static_cast(base - candidate); /* > 0 */ + size_t insert = static_cast(base - next_emit); + assert(0 == memcmp(base, candidate, matched)); + if (PREDICT_TRUE(insert < 6210)) { + EmitInsertLen(insert, cmd_depth, cmd_bits, cmd_histo, + storage_ix, storage); + } else if (ShouldUseUncompressedMode(metablock_start, next_emit, insert, + lit_depth)) { + EmitUncompressedMetaBlock(metablock_start, base, mlen_storage_ix - 3, + storage_ix, storage); + input_size -= static_cast(base - input); + input = base; + next_emit = input; + goto next_block; + } else { + EmitLongInsertLen(insert, cmd_depth, cmd_bits, cmd_histo, + storage_ix, storage); + } + EmitLiterals(next_emit, insert, lit_depth, lit_bits, + storage_ix, storage); + if (distance == last_distance) { + WriteBits(cmd_depth[64], cmd_bits[64], storage_ix, storage); + ++cmd_histo[64]; + } else { + EmitDistance(static_cast(distance), cmd_depth, cmd_bits, + cmd_histo, storage_ix, storage); + last_distance = distance; + } + EmitCopyLenLastDistance(matched, cmd_depth, cmd_bits, cmd_histo, + storage_ix, storage); + + next_emit = ip; + if (PREDICT_FALSE(ip >= ip_limit)) { + goto emit_remainder; + } + // We could immediately start working at ip now, but to improve + // compression we first update "table" with the hashes of some positions + // within the last copy. + input_bytes = BROTLI_UNALIGNED_LOAD64(ip - 3); + uint32_t prev_hash = HashBytesAtOffset(input_bytes, 0, shift); + table[prev_hash] = static_cast(ip - base_ip - 3); + prev_hash = HashBytesAtOffset(input_bytes, 1, shift); + table[prev_hash] = static_cast(ip - base_ip - 2); + prev_hash = HashBytesAtOffset(input_bytes, 2, shift); + table[prev_hash] = static_cast(ip - base_ip - 1); + + uint32_t cur_hash = HashBytesAtOffset(input_bytes, 3, shift); + candidate = base_ip + table[cur_hash]; + table[cur_hash] = static_cast(ip - base_ip); + } + + while (IsMatch(ip, candidate)) { + // We have a 5-byte match at ip, and no need to emit any literal bytes + // prior to ip. + const uint8_t* base = ip; + size_t matched = 5 + FindMatchLengthWithLimit( + candidate + 5, ip + 5, static_cast(ip_end - ip) - 5); + ip += matched; + last_distance = static_cast(base - candidate); /* > 0 */ + assert(0 == memcmp(base, candidate, matched)); + EmitCopyLen(matched, cmd_depth, cmd_bits, cmd_histo, + storage_ix, storage); + EmitDistance(static_cast(last_distance), cmd_depth, cmd_bits, + cmd_histo, storage_ix, storage); + + next_emit = ip; + if (PREDICT_FALSE(ip >= ip_limit)) { + goto emit_remainder; + } + // We could immediately start working at ip now, but to improve + // compression we first update "table" with the hashes of some positions + // within the last copy. + input_bytes = BROTLI_UNALIGNED_LOAD64(ip - 3); + uint32_t prev_hash = HashBytesAtOffset(input_bytes, 0, shift); + table[prev_hash] = static_cast(ip - base_ip - 3); + prev_hash = HashBytesAtOffset(input_bytes, 1, shift); + table[prev_hash] = static_cast(ip - base_ip - 2); + prev_hash = HashBytesAtOffset(input_bytes, 2, shift); + table[prev_hash] = static_cast(ip - base_ip - 1); + + uint32_t cur_hash = HashBytesAtOffset(input_bytes, 3, shift); + candidate = base_ip + table[cur_hash]; + table[cur_hash] = static_cast(ip - base_ip); + } + + next_hash = Hash(++ip, shift); + } + } + + emit_remainder: + assert(next_emit <= ip_end); + input += block_size; + input_size -= block_size; + block_size = std::min(input_size, kMergeBlockSize); + + // Decide if we want to continue this meta-block instead of emitting the + // last insert-only command. + if (input_size > 0 && + total_block_size + block_size <= (1 << 20) && + ShouldMergeBlock(input, block_size, lit_depth)) { + assert(total_block_size > (1 << 16)); + // Update the size of the current meta-block and continue emitting commands. + // We can do this because the current size and the new size both have 5 + // nibbles. + total_block_size += block_size; + UpdateBits(20, static_cast(total_block_size - 1), + mlen_storage_ix, storage); + goto emit_commands; + } + + // Emit the remaining bytes as literals. + if (next_emit < ip_end) { + const size_t insert = static_cast(ip_end - next_emit); + if (PREDICT_TRUE(insert < 6210)) { + EmitInsertLen(insert, cmd_depth, cmd_bits, cmd_histo, + storage_ix, storage); + EmitLiterals(next_emit, insert, lit_depth, lit_bits, storage_ix, storage); + } else if (ShouldUseUncompressedMode(metablock_start, next_emit, insert, + lit_depth)) { + EmitUncompressedMetaBlock(metablock_start, ip_end, mlen_storage_ix - 3, + storage_ix, storage); + } else { + EmitLongInsertLen(insert, cmd_depth, cmd_bits, cmd_histo, + storage_ix, storage); + EmitLiterals(next_emit, insert, lit_depth, lit_bits, + storage_ix, storage); + } + } + next_emit = ip_end; + +next_block: + // If we have more data, write a new meta-block header and prefix codes and + // then continue emitting commands. + if (input_size > 0) { + metablock_start = input; + block_size = std::min(input_size, kFirstBlockSize); + total_block_size = block_size; + // Save the bit position of the MLEN field of the meta-block header, so that + // we can update it later if we decide to extend this meta-block. + mlen_storage_ix = *storage_ix + 3; + StoreMetaBlockHeader(block_size, 0, storage_ix, storage); + // No block splits, no contexts. + WriteBits(13, 0, storage_ix, storage); + memset(lit_depth, 0, sizeof(lit_depth)); + memset(lit_bits, 0, sizeof(lit_bits)); + BuildAndStoreLiteralPrefixCode(input, block_size, lit_depth, lit_bits, + storage_ix, storage); + BuildAndStoreCommandPrefixCode(cmd_histo, cmd_depth, cmd_bits, + storage_ix, storage); + goto emit_commands; + } + + if (is_last) { + WriteBits(1, 1, storage_ix, storage); // islast + WriteBits(1, 1, storage_ix, storage); // isempty + *storage_ix = (*storage_ix + 7u) & ~7u; + } else { + // If this is not the last block, update the command and distance prefix + // codes for the next block and store the compressed forms. + cmd_code[0] = 0; + *cmd_code_numbits = 0; + BuildAndStoreCommandPrefixCode(cmd_histo, cmd_depth, cmd_bits, + cmd_code_numbits, cmd_code); + } +} + +} // namespace brotli diff --git a/web/server/h2o/libh2o/deps/brotli/enc/compress_fragment.h b/web/server/h2o/libh2o/deps/brotli/enc/compress_fragment.h new file mode 100644 index 00000000..7ce05fdf --- /dev/null +++ b/web/server/h2o/libh2o/deps/brotli/enc/compress_fragment.h @@ -0,0 +1,47 @@ +/* Copyright 2015 Google Inc. All Rights Reserved. + + Distributed under MIT license. + See file LICENSE for detail or copy at https://opensource.org/licenses/MIT +*/ + +// Function for fast encoding of an input fragment, independently from the input +// history. This function uses one-pass processing: when we find a backward +// match, we immediately emit the corresponding command and literal codes to +// the bit stream. + +#ifndef BROTLI_ENC_COMPRESS_FRAGMENT_H_ +#define BROTLI_ENC_COMPRESS_FRAGMENT_H_ + +#include "./types.h" + +namespace brotli { + +// Compresses "input" string to the "*storage" buffer as one or more complete +// meta-blocks, and updates the "*storage_ix" bit position. +// +// If "is_last" is true, emits an additional empty last meta-block. +// +// "cmd_depth" and "cmd_bits" contain the command and distance prefix codes +// (see comment in encode.h) used for the encoding of this input fragment. +// If "is_last" is false, they are updated to reflect the statistics +// of this input fragment, to be used for the encoding of the next fragment. +// +// "*cmd_code_numbits" is the number of bits of the compressed representation +// of the command and distance prefix codes, and "cmd_code" is an array of +// at least "(*cmd_code_numbits + 7) >> 3" size that contains the compressed +// command and distance prefix codes. If "is_last" is false, these are also +// updated to represent the updated "cmd_depth" and "cmd_bits". +// +// REQUIRES: "input_size" is greater than zero, or "is_last" is true. +// REQUIRES: All elements in "table[0..table_size-1]" are initialized to zero. +// REQUIRES: "table_size" is a power of two +void BrotliCompressFragmentFast(const uint8_t* input, size_t input_size, + bool is_last, + int* table, size_t table_size, + uint8_t cmd_depth[128], uint16_t cmd_bits[128], + size_t* cmd_code_numbits, uint8_t* cmd_code, + size_t* storage_ix, uint8_t* storage); + +} // namespace brotli + +#endif // BROTLI_ENC_COMPRESS_FRAGMENT_H_ diff --git a/web/server/h2o/libh2o/deps/brotli/enc/compress_fragment_two_pass.cc b/web/server/h2o/libh2o/deps/brotli/enc/compress_fragment_two_pass.cc new file mode 100644 index 00000000..84776031 --- /dev/null +++ b/web/server/h2o/libh2o/deps/brotli/enc/compress_fragment_two_pass.cc @@ -0,0 +1,519 @@ +/* Copyright 2015 Google Inc. All Rights Reserved. + + Distributed under MIT license. + See file LICENSE for detail or copy at https://opensource.org/licenses/MIT +*/ + +// Function for fast encoding of an input fragment, independently from the input +// history. This function uses two-pass processing: in the first pass we save +// the found backward matches and literal bytes into a buffer, and in the +// second pass we emit them into the bit stream using prefix codes built based +// on the actual command and literal byte histograms. + +#include "./compress_fragment_two_pass.h" + +#include + +#include "./brotli_bit_stream.h" +#include "./bit_cost.h" +#include "./entropy_encode.h" +#include "./fast_log.h" +#include "./find_match_length.h" +#include "./port.h" +#include "./write_bits.h" + +namespace brotli { + +// kHashMul32 multiplier has these properties: +// * The multiplier must be odd. Otherwise we may lose the highest bit. +// * No long streaks of 1s or 0s. +// * There is no effort to ensure that it is a prime, the oddity is enough +// for this use. +// * The number has been tuned heuristically against compression benchmarks. +static const uint32_t kHashMul32 = 0x1e35a7bd; + +static inline uint32_t Hash(const uint8_t* p, size_t shift) { + const uint64_t h = (BROTLI_UNALIGNED_LOAD64(p) << 16) * kHashMul32; + return static_cast(h >> shift); +} + +static inline uint32_t HashBytesAtOffset(uint64_t v, int offset, size_t shift) { + assert(offset >= 0); + assert(offset <= 2); + const uint64_t h = ((v >> (8 * offset)) << 16) * kHashMul32; + return static_cast(h >> shift); +} + +static inline int IsMatch(const uint8_t* p1, const uint8_t* p2) { + return (BROTLI_UNALIGNED_LOAD32(p1) == BROTLI_UNALIGNED_LOAD32(p2) && + p1[4] == p2[4] && + p1[5] == p2[5]); +} + +// Builds a command and distance prefix code (each 64 symbols) into "depth" and +// "bits" based on "histogram" and stores it into the bit stream. +static void BuildAndStoreCommandPrefixCode( + const uint32_t histogram[128], + uint8_t depth[128], uint16_t bits[128], + size_t* storage_ix, uint8_t* storage) { + CreateHuffmanTree(histogram, 64, 15, depth); + CreateHuffmanTree(&histogram[64], 64, 14, &depth[64]); + // We have to jump through a few hoopes here in order to compute + // the command bits because the symbols are in a different order than in + // the full alphabet. This looks complicated, but having the symbols + // in this order in the command bits saves a few branches in the Emit* + // functions. + uint8_t cmd_depth[64]; + uint16_t cmd_bits[64]; + memcpy(cmd_depth, depth + 24, 24); + memcpy(cmd_depth + 24, depth, 8); + memcpy(cmd_depth + 32, depth + 48, 8); + memcpy(cmd_depth + 40, depth + 8, 8); + memcpy(cmd_depth + 48, depth + 56, 8); + memcpy(cmd_depth + 56, depth + 16, 8); + ConvertBitDepthsToSymbols(cmd_depth, 64, cmd_bits); + memcpy(bits, cmd_bits + 24, 16); + memcpy(bits + 8, cmd_bits + 40, 16); + memcpy(bits + 16, cmd_bits + 56, 16); + memcpy(bits + 24, cmd_bits, 48); + memcpy(bits + 48, cmd_bits + 32, 16); + memcpy(bits + 56, cmd_bits + 48, 16); + ConvertBitDepthsToSymbols(&depth[64], 64, &bits[64]); + { + // Create the bit length array for the full command alphabet. + uint8_t cmd_depth[704] = { 0 }; + memcpy(cmd_depth, depth + 24, 8); + memcpy(cmd_depth + 64, depth + 32, 8); + memcpy(cmd_depth + 128, depth + 40, 8); + memcpy(cmd_depth + 192, depth + 48, 8); + memcpy(cmd_depth + 384, depth + 56, 8); + for (size_t i = 0; i < 8; ++i) { + cmd_depth[128 + 8 * i] = depth[i]; + cmd_depth[256 + 8 * i] = depth[8 + i]; + cmd_depth[448 + 8 * i] = depth[16 + i]; + } + StoreHuffmanTree(cmd_depth, 704, storage_ix, storage); + } + StoreHuffmanTree(&depth[64], 64, storage_ix, storage); +} + +inline void EmitInsertLen(uint32_t insertlen, uint32_t** commands) { + if (insertlen < 6) { + **commands = insertlen; + } else if (insertlen < 130) { + insertlen -= 2; + const uint32_t nbits = Log2FloorNonZero(insertlen) - 1u; + const uint32_t prefix = insertlen >> nbits; + const uint32_t inscode = (nbits << 1) + prefix + 2; + const uint32_t extra = insertlen - (prefix << nbits); + **commands = inscode | (extra << 8); + } else if (insertlen < 2114) { + insertlen -= 66; + const uint32_t nbits = Log2FloorNonZero(insertlen); + const uint32_t code = nbits + 10; + const uint32_t extra = insertlen - (1 << nbits); + **commands = code | (extra << 8); + } else if (insertlen < 6210) { + const uint32_t extra = insertlen - 2114; + **commands = 21 | (extra << 8); + } else if (insertlen < 22594) { + const uint32_t extra = insertlen - 6210; + **commands = 22 | (extra << 8); + } else { + const uint32_t extra = insertlen - 22594; + **commands = 23 | (extra << 8); + } + ++(*commands); +} + +inline void EmitCopyLen(size_t copylen, uint32_t** commands) { + if (copylen < 10) { + **commands = static_cast(copylen + 38); + } else if (copylen < 134) { + copylen -= 6; + const size_t nbits = Log2FloorNonZero(copylen) - 1; + const size_t prefix = copylen >> nbits; + const size_t code = (nbits << 1) + prefix + 44; + const size_t extra = copylen - (prefix << nbits); + **commands = static_cast(code | (extra << 8)); + } else if (copylen < 2118) { + copylen -= 70; + const size_t nbits = Log2FloorNonZero(copylen); + const size_t code = nbits + 52; + const size_t extra = copylen - (1 << nbits); + **commands = static_cast(code | (extra << 8)); + } else { + const size_t extra = copylen - 2118; + **commands = static_cast(63 | (extra << 8)); + } + ++(*commands); +} + +inline void EmitCopyLenLastDistance(size_t copylen, uint32_t** commands) { + if (copylen < 12) { + **commands = static_cast(copylen + 20); + ++(*commands); + } else if (copylen < 72) { + copylen -= 8; + const size_t nbits = Log2FloorNonZero(copylen) - 1; + const size_t prefix = copylen >> nbits; + const size_t code = (nbits << 1) + prefix + 28; + const size_t extra = copylen - (prefix << nbits); + **commands = static_cast(code | (extra << 8)); + ++(*commands); + } else if (copylen < 136) { + copylen -= 8; + const size_t code = (copylen >> 5) + 54; + const size_t extra = copylen & 31; + **commands = static_cast(code | (extra << 8)); + ++(*commands); + **commands = 64; + ++(*commands); + } else if (copylen < 2120) { + copylen -= 72; + const size_t nbits = Log2FloorNonZero(copylen); + const size_t code = nbits + 52; + const size_t extra = copylen - (1 << nbits); + **commands = static_cast(code | (extra << 8)); + ++(*commands); + **commands = 64; + ++(*commands); + } else { + const size_t extra = copylen - 2120; + **commands = static_cast(63 | (extra << 8)); + ++(*commands); + **commands = 64; + ++(*commands); + } +} + +inline void EmitDistance(uint32_t distance, uint32_t** commands) { + distance += 3; + uint32_t nbits = Log2FloorNonZero(distance) - 1; + const uint32_t prefix = (distance >> nbits) & 1; + const uint32_t offset = (2 + prefix) << nbits; + const uint32_t distcode = 2 * (nbits - 1) + prefix + 80; + uint32_t extra = distance - offset; + **commands = distcode | (extra << 8); + ++(*commands); +} + +// REQUIRES: len <= 1 << 20. +static void StoreMetaBlockHeader( + size_t len, bool is_uncompressed, size_t* storage_ix, uint8_t* storage) { + // ISLAST + WriteBits(1, 0, storage_ix, storage); + if (len <= (1U << 16)) { + // MNIBBLES is 4 + WriteBits(2, 0, storage_ix, storage); + WriteBits(16, len - 1, storage_ix, storage); + } else { + // MNIBBLES is 5 + WriteBits(2, 1, storage_ix, storage); + WriteBits(20, len - 1, storage_ix, storage); + } + // ISUNCOMPRESSED + WriteBits(1, is_uncompressed, storage_ix, storage); +} + +void CreateCommands(const uint8_t* input, size_t block_size, size_t input_size, + const uint8_t* base_ip, + int* table, size_t table_size, + uint8_t** literals, uint32_t** commands) { + // "ip" is the input pointer. + const uint8_t* ip = input; + assert(table_size); + assert(table_size <= (1u << 31)); + assert((table_size & (table_size - 1)) == 0); // table must be power of two + const size_t shift = 64u - Log2FloorNonZero(table_size); + assert(static_cast(0xffffffffffffffffU >> shift) == table_size - 1); + const uint8_t* ip_end = input + block_size; + // "next_emit" is a pointer to the first byte that is not covered by a + // previous copy. Bytes between "next_emit" and the start of the next copy or + // the end of the input will be emitted as literal bytes. + const uint8_t* next_emit = input; + + int last_distance = -1; + const size_t kInputMarginBytes = 16; + const size_t kMinMatchLen = 6; + if (PREDICT_TRUE(block_size >= kInputMarginBytes)) { + // For the last block, we need to keep a 16 bytes margin so that we can be + // sure that all distances are at most window size - 16. + // For all other blocks, we only need to keep a margin of 5 bytes so that + // we don't go over the block size with a copy. + const size_t len_limit = std::min(block_size - kMinMatchLen, + input_size - kInputMarginBytes); + const uint8_t* ip_limit = input + len_limit; + + for (uint32_t next_hash = Hash(++ip, shift); ; ) { + assert(next_emit < ip); + // Step 1: Scan forward in the input looking for a 6-byte-long match. + // If we get close to exhausting the input then goto emit_remainder. + // + // Heuristic match skipping: If 32 bytes are scanned with no matches + // found, start looking only at every other byte. If 32 more bytes are + // scanned, look at every third byte, etc.. When a match is found, + // immediately go back to looking at every byte. This is a small loss + // (~5% performance, ~0.1% density) for compressible data due to more + // bookkeeping, but for non-compressible data (such as JPEG) it's a huge + // win since the compressor quickly "realizes" the data is incompressible + // and doesn't bother looking for matches everywhere. + // + // The "skip" variable keeps track of how many bytes there are since the + // last match; dividing it by 32 (ie. right-shifting by five) gives the + // number of bytes to move ahead for each iteration. + uint32_t skip = 32; + + const uint8_t* next_ip = ip; + const uint8_t* candidate; + do { + ip = next_ip; + uint32_t hash = next_hash; + assert(hash == Hash(ip, shift)); + uint32_t bytes_between_hash_lookups = skip++ >> 5; + next_ip = ip + bytes_between_hash_lookups; + if (PREDICT_FALSE(next_ip > ip_limit)) { + goto emit_remainder; + } + next_hash = Hash(next_ip, shift); + candidate = ip - last_distance; + if (IsMatch(ip, candidate)) { + if (PREDICT_TRUE(candidate < ip)) { + table[hash] = static_cast(ip - base_ip); + break; + } + } + candidate = base_ip + table[hash]; + assert(candidate >= base_ip); + assert(candidate < ip); + + table[hash] = static_cast(ip - base_ip); + } while (PREDICT_TRUE(!IsMatch(ip, candidate))); + + // Step 2: Emit the found match together with the literal bytes from + // "next_emit", and then see if we can find a next macth immediately + // afterwards. Repeat until we find no match for the input + // without emitting some literal bytes. + uint64_t input_bytes; + + { + // We have a 6-byte match at ip, and we need to emit bytes in + // [next_emit, ip). + const uint8_t* base = ip; + size_t matched = 6 + FindMatchLengthWithLimit( + candidate + 6, ip + 6, static_cast(ip_end - ip) - 6); + ip += matched; + int distance = static_cast(base - candidate); /* > 0 */ + int insert = static_cast(base - next_emit); + assert(0 == memcmp(base, candidate, matched)); + EmitInsertLen(static_cast(insert), commands); + memcpy(*literals, next_emit, static_cast(insert)); + *literals += insert; + if (distance == last_distance) { + **commands = 64; + ++(*commands); + } else { + EmitDistance(static_cast(distance), commands); + last_distance = distance; + } + EmitCopyLenLastDistance(matched, commands); + + next_emit = ip; + if (PREDICT_FALSE(ip >= ip_limit)) { + goto emit_remainder; + } + // We could immediately start working at ip now, but to improve + // compression we first update "table" with the hashes of some positions + // within the last copy. + input_bytes = BROTLI_UNALIGNED_LOAD64(ip - 5); + uint32_t prev_hash = HashBytesAtOffset(input_bytes, 0, shift); + table[prev_hash] = static_cast(ip - base_ip - 5); + prev_hash = HashBytesAtOffset(input_bytes, 1, shift); + table[prev_hash] = static_cast(ip - base_ip - 4); + prev_hash = HashBytesAtOffset(input_bytes, 2, shift); + table[prev_hash] = static_cast(ip - base_ip - 3); + input_bytes = BROTLI_UNALIGNED_LOAD64(ip - 2); + prev_hash = HashBytesAtOffset(input_bytes, 0, shift); + table[prev_hash] = static_cast(ip - base_ip - 2); + prev_hash = HashBytesAtOffset(input_bytes, 1, shift); + table[prev_hash] = static_cast(ip - base_ip - 1); + + uint32_t cur_hash = HashBytesAtOffset(input_bytes, 2, shift); + candidate = base_ip + table[cur_hash]; + table[cur_hash] = static_cast(ip - base_ip); + } + + while (IsMatch(ip, candidate)) { + // We have a 6-byte match at ip, and no need to emit any + // literal bytes prior to ip. + const uint8_t* base = ip; + size_t matched = 6 + FindMatchLengthWithLimit( + candidate + 6, ip + 6, static_cast(ip_end - ip) - 6); + ip += matched; + last_distance = static_cast(base - candidate); /* > 0 */ + assert(0 == memcmp(base, candidate, matched)); + EmitCopyLen(matched, commands); + EmitDistance(static_cast(last_distance), commands); + + next_emit = ip; + if (PREDICT_FALSE(ip >= ip_limit)) { + goto emit_remainder; + } + // We could immediately start working at ip now, but to improve + // compression we first update "table" with the hashes of some positions + // within the last copy. + input_bytes = BROTLI_UNALIGNED_LOAD64(ip - 5); + uint32_t prev_hash = HashBytesAtOffset(input_bytes, 0, shift); + table[prev_hash] = static_cast(ip - base_ip - 5); + prev_hash = HashBytesAtOffset(input_bytes, 1, shift); + table[prev_hash] = static_cast(ip - base_ip - 4); + prev_hash = HashBytesAtOffset(input_bytes, 2, shift); + table[prev_hash] = static_cast(ip - base_ip - 3); + input_bytes = BROTLI_UNALIGNED_LOAD64(ip - 2); + prev_hash = HashBytesAtOffset(input_bytes, 0, shift); + table[prev_hash] = static_cast(ip - base_ip - 2); + prev_hash = HashBytesAtOffset(input_bytes, 1, shift); + table[prev_hash] = static_cast(ip - base_ip - 1); + + uint32_t cur_hash = HashBytesAtOffset(input_bytes, 2, shift); + candidate = base_ip + table[cur_hash]; + table[cur_hash] = static_cast(ip - base_ip); + } + + next_hash = Hash(++ip, shift); + } + } + +emit_remainder: + assert(next_emit <= ip_end); + // Emit the remaining bytes as literals. + if (next_emit < ip_end) { + const uint32_t insert = static_cast(ip_end - next_emit); + EmitInsertLen(insert, commands); + memcpy(*literals, next_emit, insert); + *literals += insert; + } +} + +void StoreCommands(const uint8_t* literals, const size_t num_literals, + const uint32_t* commands, const size_t num_commands, + size_t* storage_ix, uint8_t* storage) { + uint8_t lit_depths[256] = { 0 }; + uint16_t lit_bits[256] = { 0 }; + uint32_t lit_histo[256] = { 0 }; + for (size_t i = 0; i < num_literals; ++i) { + ++lit_histo[literals[i]]; + } + BuildAndStoreHuffmanTreeFast(lit_histo, num_literals, + /* max_bits = */ 8, + lit_depths, lit_bits, + storage_ix, storage); + + uint8_t cmd_depths[128] = { 0 }; + uint16_t cmd_bits[128] = { 0 }; + uint32_t cmd_histo[128] = { 0 }; + for (size_t i = 0; i < num_commands; ++i) { + ++cmd_histo[commands[i] & 0xff]; + } + cmd_histo[1] += 1; + cmd_histo[2] += 1; + cmd_histo[64] += 1; + cmd_histo[84] += 1; + BuildAndStoreCommandPrefixCode(cmd_histo, cmd_depths, cmd_bits, + storage_ix, storage); + + static const uint32_t kNumExtraBits[128] = { + 0, 0, 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 7, 8, 9, 10, 12, 14, 24, + 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, + 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 7, 8, 9, 10, 24, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, + 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15, 16, 16, + 17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22, 23, 23, 24, 24, + }; + static const uint32_t kInsertOffset[24] = { + 0, 1, 2, 3, 4, 5, 6, 8, 10, 14, 18, 26, 34, 50, 66, 98, 130, 194, 322, 578, + 1090, 2114, 6210, 22594, + }; + + for (size_t i = 0; i < num_commands; ++i) { + const uint32_t cmd = commands[i]; + const uint32_t code = cmd & 0xff; + const uint32_t extra = cmd >> 8; + WriteBits(cmd_depths[code], cmd_bits[code], storage_ix, storage); + WriteBits(kNumExtraBits[code], extra, storage_ix, storage); + if (code < 24) { + const uint32_t insert = kInsertOffset[code] + extra; + for (uint32_t j = 0; j < insert; ++j) { + const uint8_t lit = *literals; + WriteBits(lit_depths[lit], lit_bits[lit], storage_ix, storage); + ++literals; + } + } + } +} + +bool ShouldCompress(const uint8_t* input, size_t input_size, + size_t num_literals) { + static const double kAcceptableLossForUncompressibleSpeedup = 0.02; + static const double kMaxRatioOfLiterals = + 1.0 - kAcceptableLossForUncompressibleSpeedup; + if (num_literals < kMaxRatioOfLiterals * static_cast(input_size)) { + return true; + } + uint32_t literal_histo[256] = { 0 }; + static const uint32_t kSampleRate = 43; + static const double kMaxEntropy = + 8 * (1.0 - kAcceptableLossForUncompressibleSpeedup); + const double max_total_bit_cost = + static_cast(input_size) * kMaxEntropy / kSampleRate; + for (size_t i = 0; i < input_size; i += kSampleRate) { + ++literal_histo[input[i]]; + } + return BitsEntropy(literal_histo, 256) < max_total_bit_cost; +} + +void BrotliCompressFragmentTwoPass(const uint8_t* input, size_t input_size, + bool is_last, + uint32_t* command_buf, uint8_t* literal_buf, + int* table, size_t table_size, + size_t* storage_ix, uint8_t* storage) { + // Save the start of the first block for position and distance computations. + const uint8_t* base_ip = input; + + while (input_size > 0) { + size_t block_size = std::min(input_size, kCompressFragmentTwoPassBlockSize); + uint32_t* commands = command_buf; + uint8_t* literals = literal_buf; + CreateCommands(input, block_size, input_size, base_ip, table, table_size, + &literals, &commands); + const size_t num_literals = static_cast(literals - literal_buf); + const size_t num_commands = static_cast(commands - command_buf); + if (ShouldCompress(input, block_size, num_literals)) { + StoreMetaBlockHeader(block_size, 0, storage_ix, storage); + // No block splits, no contexts. + WriteBits(13, 0, storage_ix, storage); + StoreCommands(literal_buf, num_literals, command_buf, num_commands, + storage_ix, storage); + } else { + // Since we did not find many backward references and the entropy of + // the data is close to 8 bits, we can simply emit an uncompressed block. + // This makes compression speed of uncompressible data about 3x faster. + StoreMetaBlockHeader(block_size, 1, storage_ix, storage); + *storage_ix = (*storage_ix + 7u) & ~7u; + memcpy(&storage[*storage_ix >> 3], input, block_size); + *storage_ix += block_size << 3; + storage[*storage_ix >> 3] = 0; + } + input += block_size; + input_size -= block_size; + } + + if (is_last) { + WriteBits(1, 1, storage_ix, storage); // islast + WriteBits(1, 1, storage_ix, storage); // isempty + *storage_ix = (*storage_ix + 7u) & ~7u; + } +} + +} // namespace brotli diff --git a/web/server/h2o/libh2o/deps/brotli/enc/compress_fragment_two_pass.h b/web/server/h2o/libh2o/deps/brotli/enc/compress_fragment_two_pass.h new file mode 100644 index 00000000..690ed081 --- /dev/null +++ b/web/server/h2o/libh2o/deps/brotli/enc/compress_fragment_two_pass.h @@ -0,0 +1,40 @@ +/* Copyright 2015 Google Inc. All Rights Reserved. + + Distributed under MIT license. + See file LICENSE for detail or copy at https://opensource.org/licenses/MIT +*/ + +// Function for fast encoding of an input fragment, independently from the input +// history. This function uses two-pass processing: in the first pass we save +// the found backward matches and literal bytes into a buffer, and in the +// second pass we emit them into the bit stream using prefix codes built based +// on the actual command and literal byte histograms. + +#ifndef BROTLI_ENC_COMPRESS_FRAGMENT_TWO_PASS_H_ +#define BROTLI_ENC_COMPRESS_FRAGMENT_TWO_PASS_H_ + +#include "./types.h" + +namespace brotli { + +static const size_t kCompressFragmentTwoPassBlockSize = 1 << 17; + +// Compresses "input" string to the "*storage" buffer as one or more complete +// meta-blocks, and updates the "*storage_ix" bit position. +// +// If "is_last" is true, emits an additional empty last meta-block. +// +// REQUIRES: "input_size" is greater than zero, or "is_last" is true. +// REQUIRES: "command_buf" and "literal_buf" point to at least +// kCompressFragmentTwoPassBlockSize long arrays. +// REQUIRES: All elements in "table[0..table_size-1]" are initialized to zero. +// REQUIRES: "table_size" is a power of two +void BrotliCompressFragmentTwoPass(const uint8_t* input, size_t input_size, + bool is_last, + uint32_t* command_buf, uint8_t* literal_buf, + int* table, size_t table_size, + size_t* storage_ix, uint8_t* storage); + +} // namespace brotli + +#endif // BROTLI_ENC_COMPRESS_FRAGMENT_TWO_PASS_H_ diff --git a/web/server/h2o/libh2o/deps/brotli/enc/context.h b/web/server/h2o/libh2o/deps/brotli/enc/context.h new file mode 100644 index 00000000..00c065bc --- /dev/null +++ b/web/server/h2o/libh2o/deps/brotli/enc/context.h @@ -0,0 +1,178 @@ +/* Copyright 2013 Google Inc. All Rights Reserved. + + Distributed under MIT license. + See file LICENSE for detail or copy at https://opensource.org/licenses/MIT +*/ + +// Functions to map previous bytes into a context id. + +#ifndef BROTLI_ENC_CONTEXT_H_ +#define BROTLI_ENC_CONTEXT_H_ + +#include "./types.h" + +namespace brotli { + +// Second-order context lookup table for UTF8 byte streams. +// +// If p1 and p2 are the previous two bytes, we calculate the context as +// +// context = kUTF8ContextLookup[p1] | kUTF8ContextLookup[p2 + 256]. +// +// If the previous two bytes are ASCII characters (i.e. < 128), this will be +// equivalent to +// +// context = 4 * context1(p1) + context2(p2), +// +// where context1 is based on the previous byte in the following way: +// +// 0 : non-ASCII control +// 1 : \t, \n, \r +// 2 : space +// 3 : other punctuation +// 4 : " ' +// 5 : % +// 6 : ( < [ { +// 7 : ) > ] } +// 8 : , ; : +// 9 : . +// 10 : = +// 11 : number +// 12 : upper-case vowel +// 13 : upper-case consonant +// 14 : lower-case vowel +// 15 : lower-case consonant +// +// and context2 is based on the second last byte: +// +// 0 : control, space +// 1 : punctuation +// 2 : upper-case letter, number +// 3 : lower-case letter +// +// If the last byte is ASCII, and the second last byte is not (in a valid UTF8 +// stream it will be a continuation byte, value between 128 and 191), the +// context is the same as if the second last byte was an ASCII control or space. +// +// If the last byte is a UTF8 lead byte (value >= 192), then the next byte will +// be a continuation byte and the context id is 2 or 3 depending on the LSB of +// the last byte and to a lesser extent on the second last byte if it is ASCII. +// +// If the last byte is a UTF8 continuation byte, the second last byte can be: +// - continuation byte: the next byte is probably ASCII or lead byte (assuming +// 4-byte UTF8 characters are rare) and the context id is 0 or 1. +// - lead byte (192 - 207): next byte is ASCII or lead byte, context is 0 or 1 +// - lead byte (208 - 255): next byte is continuation byte, context is 2 or 3 +// +// The possible value combinations of the previous two bytes, the range of +// context ids and the type of the next byte is summarized in the table below: +// +// |--------\-----------------------------------------------------------------| +// | \ Last byte | +// | Second \---------------------------------------------------------------| +// | last byte \ ASCII | cont. byte | lead byte | +// | \ (0-127) | (128-191) | (192-) | +// |=============|===================|=====================|==================| +// | ASCII | next: ASCII/lead | not valid | next: cont. | +// | (0-127) | context: 4 - 63 | | context: 2 - 3 | +// |-------------|-------------------|---------------------|------------------| +// | cont. byte | next: ASCII/lead | next: ASCII/lead | next: cont. | +// | (128-191) | context: 4 - 63 | context: 0 - 1 | context: 2 - 3 | +// |-------------|-------------------|---------------------|------------------| +// | lead byte | not valid | next: ASCII/lead | not valid | +// | (192-207) | | context: 0 - 1 | | +// |-------------|-------------------|---------------------|------------------| +// | lead byte | not valid | next: cont. | not valid | +// | (208-) | | context: 2 - 3 | | +// |-------------|-------------------|---------------------|------------------| +static const uint8_t kUTF8ContextLookup[512] = { + // Last byte. + // + // ASCII range. + 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 0, 0, 4, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 8, 12, 16, 12, 12, 20, 12, 16, 24, 28, 12, 12, 32, 12, 36, 12, + 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 32, 32, 24, 40, 28, 12, + 12, 48, 52, 52, 52, 48, 52, 52, 52, 48, 52, 52, 52, 52, 52, 48, + 52, 52, 52, 52, 52, 48, 52, 52, 52, 52, 52, 24, 12, 28, 12, 12, + 12, 56, 60, 60, 60, 56, 60, 60, 60, 56, 60, 60, 60, 60, 60, 56, + 60, 60, 60, 60, 60, 56, 60, 60, 60, 60, 60, 24, 12, 28, 12, 0, + // UTF8 continuation byte range. + 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, + 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, + 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, + 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, + // UTF8 lead byte range. + 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, + 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, + 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, + 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, + // Second last byte. + // + // ASCII range. + 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, 0, 0, 0, 0, 0, 0, + 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, + 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, + 1, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 1, 1, 1, 1, 0, + // UTF8 continuation byte range. + 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, 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, 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, 0, 0, + // UTF8 lead byte range. + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +}; + +// Context lookup table for small signed integers. +static const uint8_t kSigned3BitContextLookup[] = { + 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 7, +}; + +enum ContextType { + CONTEXT_LSB6 = 0, + CONTEXT_MSB6 = 1, + CONTEXT_UTF8 = 2, + CONTEXT_SIGNED = 3 +}; + +static inline uint8_t Context(uint8_t p1, uint8_t p2, ContextType mode) { + switch (mode) { + case CONTEXT_LSB6: + return p1 & 0x3f; + case CONTEXT_MSB6: + return static_cast(p1 >> 2); + case CONTEXT_UTF8: + return kUTF8ContextLookup[p1] | kUTF8ContextLookup[p2 + 256]; + case CONTEXT_SIGNED: + return static_cast((kSigned3BitContextLookup[p1] << 3) + + kSigned3BitContextLookup[p2]); + default: + return 0; + } +} + +} // namespace brotli + +#endif // BROTLI_ENC_CONTEXT_H_ diff --git a/web/server/h2o/libh2o/deps/brotli/enc/dictionary.cc b/web/server/h2o/libh2o/deps/brotli/enc/dictionary.cc new file mode 100644 index 00000000..0564bab6 --- /dev/null +++ b/web/server/h2o/libh2o/deps/brotli/enc/dictionary.cc @@ -0,0 +1,9466 @@ +/* Copyright 2013 Google Inc. All Rights Reserved. + + Distributed under MIT license. + See file LICENSE for detail or copy at https://opensource.org/licenses/MIT +*/ + +#include "./dictionary.h" + +#if defined(__cplusplus) || defined(c_plusplus) +extern "C" { +#endif + +// In case of multiple definition linker error with dictionary.c from the +// decoder: include only one of enc/dictionary.cc or dec/dictionary.c in a +// target using both enc and dec. +const uint8_t kBrotliDictionary[122784] = { + 0x74, 0x69, 0x6d, 0x65, 0x64, 0x6f, 0x77, 0x6e, 0x6c, 0x69, 0x66, 0x65, 0x6c, + 0x65, 0x66, 0x74, 0x62, 0x61, 0x63, 0x6b, 0x63, 0x6f, 0x64, 0x65, 0x64, 0x61, + 0x74, 0x61, 0x73, 0x68, 0x6f, 0x77, 0x6f, 0x6e, 0x6c, 0x79, 0x73, 0x69, 0x74, + 0x65, 0x63, 0x69, 0x74, 0x79, 0x6f, 0x70, 0x65, 0x6e, 0x6a, 0x75, 0x73, 0x74, + 0x6c, 0x69, 0x6b, 0x65, 0x66, 0x72, 0x65, 0x65, 0x77, 0x6f, 0x72, 0x6b, 0x74, + 0x65, 0x78, 0x74, 0x79, 0x65, 0x61, 0x72, 0x6f, 0x76, 0x65, 0x72, 0x62, 0x6f, + 0x64, 0x79, 0x6c, 0x6f, 0x76, 0x65, 0x66, 0x6f, 0x72, 0x6d, 0x62, 0x6f, 0x6f, + 0x6b, 0x70, 0x6c, 0x61, 0x79, 0x6c, 0x69, 0x76, 0x65, 0x6c, 0x69, 0x6e, 0x65, + 0x68, 0x65, 0x6c, 0x70, 0x68, 0x6f, 0x6d, 0x65, 0x73, 0x69, 0x64, 0x65, 0x6d, + 0x6f, 0x72, 0x65, 0x77, 0x6f, 0x72, 0x64, 0x6c, 0x6f, 0x6e, 0x67, 0x74, 0x68, + 0x65, 0x6d, 0x76, 0x69, 0x65, 0x77, 0x66, 0x69, 0x6e, 0x64, 0x70, 0x61, 0x67, + 0x65, 0x64, 0x61, 0x79, 0x73, 0x66, 0x75, 0x6c, 0x6c, 0x68, 0x65, 0x61, 0x64, + 0x74, 0x65, 0x72, 0x6d, 0x65, 0x61, 0x63, 0x68, 0x61, 0x72, 0x65, 0x61, 0x66, + 0x72, 0x6f, 0x6d, 0x74, 0x72, 0x75, 0x65, 0x6d, 0x61, 0x72, 0x6b, 0x61, 0x62, + 0x6c, 0x65, 0x75, 0x70, 0x6f, 0x6e, 0x68, 0x69, 0x67, 0x68, 0x64, 0x61, 0x74, + 0x65, 0x6c, 0x61, 0x6e, 0x64, 0x6e, 0x65, 0x77, 0x73, 0x65, 0x76, 0x65, 0x6e, + 0x6e, 0x65, 0x78, 0x74, 0x63, 0x61, 0x73, 0x65, 0x62, 0x6f, 0x74, 0x68, 0x70, + 0x6f, 0x73, 0x74, 0x75, 0x73, 0x65, 0x64, 0x6d, 0x61, 0x64, 0x65, 0x68, 0x61, + 0x6e, 0x64, 0x68, 0x65, 0x72, 0x65, 0x77, 0x68, 0x61, 0x74, 0x6e, 0x61, 0x6d, + 0x65, 0x4c, 0x69, 0x6e, 0x6b, 0x62, 0x6c, 0x6f, 0x67, 0x73, 0x69, 0x7a, 0x65, + 0x62, 0x61, 0x73, 0x65, 0x68, 0x65, 0x6c, 0x64, 0x6d, 0x61, 0x6b, 0x65, 0x6d, + 0x61, 0x69, 0x6e, 0x75, 0x73, 0x65, 0x72, 0x27, 0x29, 0x20, 0x2b, 0x68, 0x6f, + 0x6c, 0x64, 0x65, 0x6e, 0x64, 0x73, 0x77, 0x69, 0x74, 0x68, 0x4e, 0x65, 0x77, + 0x73, 0x72, 0x65, 0x61, 0x64, 0x77, 0x65, 0x72, 0x65, 0x73, 0x69, 0x67, 0x6e, + 0x74, 0x61, 0x6b, 0x65, 0x68, 0x61, 0x76, 0x65, 0x67, 0x61, 0x6d, 0x65, 0x73, + 0x65, 0x65, 0x6e, 0x63, 0x61, 0x6c, 0x6c, 0x70, 0x61, 0x74, 0x68, 0x77, 0x65, + 0x6c, 0x6c, 0x70, 0x6c, 0x75, 0x73, 0x6d, 0x65, 0x6e, 0x75, 0x66, 0x69, 0x6c, + 0x6d, 0x70, 0x61, 0x72, 0x74, 0x6a, 0x6f, 0x69, 0x6e, 0x74, 0x68, 0x69, 0x73, + 0x6c, 0x69, 0x73, 0x74, 0x67, 0x6f, 0x6f, 0x64, 0x6e, 0x65, 0x65, 0x64, 0x77, + 0x61, 0x79, 0x73, 0x77, 0x65, 0x73, 0x74, 0x6a, 0x6f, 0x62, 0x73, 0x6d, 0x69, + 0x6e, 0x64, 0x61, 0x6c, 0x73, 0x6f, 0x6c, 0x6f, 0x67, 0x6f, 0x72, 0x69, 0x63, + 0x68, 0x75, 0x73, 0x65, 0x73, 0x6c, 0x61, 0x73, 0x74, 0x74, 0x65, 0x61, 0x6d, + 0x61, 0x72, 0x6d, 0x79, 0x66, 0x6f, 0x6f, 0x64, 0x6b, 0x69, 0x6e, 0x67, 0x77, + 0x69, 0x6c, 0x6c, 0x65, 0x61, 0x73, 0x74, 0x77, 0x61, 0x72, 0x64, 0x62, 0x65, + 0x73, 0x74, 0x66, 0x69, 0x72, 0x65, 0x50, 0x61, 0x67, 0x65, 0x6b, 0x6e, 0x6f, + 0x77, 0x61, 0x77, 0x61, 0x79, 0x2e, 0x70, 0x6e, 0x67, 0x6d, 0x6f, 0x76, 0x65, + 0x74, 0x68, 0x61, 0x6e, 0x6c, 0x6f, 0x61, 0x64, 0x67, 0x69, 0x76, 0x65, 0x73, + 0x65, 0x6c, 0x66, 0x6e, 0x6f, 0x74, 0x65, 0x6d, 0x75, 0x63, 0x68, 0x66, 0x65, + 0x65, 0x64, 0x6d, 0x61, 0x6e, 0x79, 0x72, 0x6f, 0x63, 0x6b, 0x69, 0x63, 0x6f, + 0x6e, 0x6f, 0x6e, 0x63, 0x65, 0x6c, 0x6f, 0x6f, 0x6b, 0x68, 0x69, 0x64, 0x65, + 0x64, 0x69, 0x65, 0x64, 0x48, 0x6f, 0x6d, 0x65, 0x72, 0x75, 0x6c, 0x65, 0x68, + 0x6f, 0x73, 0x74, 0x61, 0x6a, 0x61, 0x78, 0x69, 0x6e, 0x66, 0x6f, 0x63, 0x6c, + 0x75, 0x62, 0x6c, 0x61, 0x77, 0x73, 0x6c, 0x65, 0x73, 0x73, 0x68, 0x61, 0x6c, + 0x66, 0x73, 0x6f, 0x6d, 0x65, 0x73, 0x75, 0x63, 0x68, 0x7a, 0x6f, 0x6e, 0x65, + 0x31, 0x30, 0x30, 0x25, 0x6f, 0x6e, 0x65, 0x73, 0x63, 0x61, 0x72, 0x65, 0x54, + 0x69, 0x6d, 0x65, 0x72, 0x61, 0x63, 0x65, 0x62, 0x6c, 0x75, 0x65, 0x66, 0x6f, + 0x75, 0x72, 0x77, 0x65, 0x65, 0x6b, 0x66, 0x61, 0x63, 0x65, 0x68, 0x6f, 0x70, + 0x65, 0x67, 0x61, 0x76, 0x65, 0x68, 0x61, 0x72, 0x64, 0x6c, 0x6f, 0x73, 0x74, + 0x77, 0x68, 0x65, 0x6e, 0x70, 0x61, 0x72, 0x6b, 0x6b, 0x65, 0x70, 0x74, 0x70, + 0x61, 0x73, 0x73, 0x73, 0x68, 0x69, 0x70, 0x72, 0x6f, 0x6f, 0x6d, 0x48, 0x54, + 0x4d, 0x4c, 0x70, 0x6c, 0x61, 0x6e, 0x54, 0x79, 0x70, 0x65, 0x64, 0x6f, 0x6e, + 0x65, 0x73, 0x61, 0x76, 0x65, 0x6b, 0x65, 0x65, 0x70, 0x66, 0x6c, 0x61, 0x67, + 0x6c, 0x69, 0x6e, 0x6b, 0x73, 0x6f, 0x6c, 0x64, 0x66, 0x69, 0x76, 0x65, 0x74, + 0x6f, 0x6f, 0x6b, 0x72, 0x61, 0x74, 0x65, 0x74, 0x6f, 0x77, 0x6e, 0x6a, 0x75, + 0x6d, 0x70, 0x74, 0x68, 0x75, 0x73, 0x64, 0x61, 0x72, 0x6b, 0x63, 0x61, 0x72, + 0x64, 0x66, 0x69, 0x6c, 0x65, 0x66, 0x65, 0x61, 0x72, 0x73, 0x74, 0x61, 0x79, + 0x6b, 0x69, 0x6c, 0x6c, 0x74, 0x68, 0x61, 0x74, 0x66, 0x61, 0x6c, 0x6c, 0x61, + 0x75, 0x74, 0x6f, 0x65, 0x76, 0x65, 0x72, 0x2e, 0x63, 0x6f, 0x6d, 0x74, 0x61, + 0x6c, 0x6b, 0x73, 0x68, 0x6f, 0x70, 0x76, 0x6f, 0x74, 0x65, 0x64, 0x65, 0x65, + 0x70, 0x6d, 0x6f, 0x64, 0x65, 0x72, 0x65, 0x73, 0x74, 0x74, 0x75, 0x72, 0x6e, + 0x62, 0x6f, 0x72, 0x6e, 0x62, 0x61, 0x6e, 0x64, 0x66, 0x65, 0x6c, 0x6c, 0x72, + 0x6f, 0x73, 0x65, 0x75, 0x72, 0x6c, 0x28, 0x73, 0x6b, 0x69, 0x6e, 0x72, 0x6f, + 0x6c, 0x65, 0x63, 0x6f, 0x6d, 0x65, 0x61, 0x63, 0x74, 0x73, 0x61, 0x67, 0x65, + 0x73, 0x6d, 0x65, 0x65, 0x74, 0x67, 0x6f, 0x6c, 0x64, 0x2e, 0x6a, 0x70, 0x67, + 0x69, 0x74, 0x65, 0x6d, 0x76, 0x61, 0x72, 0x79, 0x66, 0x65, 0x6c, 0x74, 0x74, + 0x68, 0x65, 0x6e, 0x73, 0x65, 0x6e, 0x64, 0x64, 0x72, 0x6f, 0x70, 0x56, 0x69, + 0x65, 0x77, 0x63, 0x6f, 0x70, 0x79, 0x31, 0x2e, 0x30, 0x22, 0x3c, 0x2f, 0x61, + 0x3e, 0x73, 0x74, 0x6f, 0x70, 0x65, 0x6c, 0x73, 0x65, 0x6c, 0x69, 0x65, 0x73, + 0x74, 0x6f, 0x75, 0x72, 0x70, 0x61, 0x63, 0x6b, 0x2e, 0x67, 0x69, 0x66, 0x70, + 0x61, 0x73, 0x74, 0x63, 0x73, 0x73, 0x3f, 0x67, 0x72, 0x61, 0x79, 0x6d, 0x65, + 0x61, 0x6e, 0x26, 0x67, 0x74, 0x3b, 0x72, 0x69, 0x64, 0x65, 0x73, 0x68, 0x6f, + 0x74, 0x6c, 0x61, 0x74, 0x65, 0x73, 0x61, 0x69, 0x64, 0x72, 0x6f, 0x61, 0x64, + 0x76, 0x61, 0x72, 0x20, 0x66, 0x65, 0x65, 0x6c, 0x6a, 0x6f, 0x68, 0x6e, 0x72, + 0x69, 0x63, 0x6b, 0x70, 0x6f, 0x72, 0x74, 0x66, 0x61, 0x73, 0x74, 0x27, 0x55, + 0x41, 0x2d, 0x64, 0x65, 0x61, 0x64, 0x3c, 0x2f, 0x62, 0x3e, 0x70, 0x6f, 0x6f, + 0x72, 0x62, 0x69, 0x6c, 0x6c, 0x74, 0x79, 0x70, 0x65, 0x55, 0x2e, 0x53, 0x2e, + 0x77, 0x6f, 0x6f, 0x64, 0x6d, 0x75, 0x73, 0x74, 0x32, 0x70, 0x78, 0x3b, 0x49, + 0x6e, 0x66, 0x6f, 0x72, 0x61, 0x6e, 0x6b, 0x77, 0x69, 0x64, 0x65, 0x77, 0x61, + 0x6e, 0x74, 0x77, 0x61, 0x6c, 0x6c, 0x6c, 0x65, 0x61, 0x64, 0x5b, 0x30, 0x5d, + 0x3b, 0x70, 0x61, 0x75, 0x6c, 0x77, 0x61, 0x76, 0x65, 0x73, 0x75, 0x72, 0x65, + 0x24, 0x28, 0x27, 0x23, 0x77, 0x61, 0x69, 0x74, 0x6d, 0x61, 0x73, 0x73, 0x61, + 0x72, 0x6d, 0x73, 0x67, 0x6f, 0x65, 0x73, 0x67, 0x61, 0x69, 0x6e, 0x6c, 0x61, + 0x6e, 0x67, 0x70, 0x61, 0x69, 0x64, 0x21, 0x2d, 0x2d, 0x20, 0x6c, 0x6f, 0x63, + 0x6b, 0x75, 0x6e, 0x69, 0x74, 0x72, 0x6f, 0x6f, 0x74, 0x77, 0x61, 0x6c, 0x6b, + 0x66, 0x69, 0x72, 0x6d, 0x77, 0x69, 0x66, 0x65, 0x78, 0x6d, 0x6c, 0x22, 0x73, + 0x6f, 0x6e, 0x67, 0x74, 0x65, 0x73, 0x74, 0x32, 0x30, 0x70, 0x78, 0x6b, 0x69, + 0x6e, 0x64, 0x72, 0x6f, 0x77, 0x73, 0x74, 0x6f, 0x6f, 0x6c, 0x66, 0x6f, 0x6e, + 0x74, 0x6d, 0x61, 0x69, 0x6c, 0x73, 0x61, 0x66, 0x65, 0x73, 0x74, 0x61, 0x72, + 0x6d, 0x61, 0x70, 0x73, 0x63, 0x6f, 0x72, 0x65, 0x72, 0x61, 0x69, 0x6e, 0x66, + 0x6c, 0x6f, 0x77, 0x62, 0x61, 0x62, 0x79, 0x73, 0x70, 0x61, 0x6e, 0x73, 0x61, + 0x79, 0x73, 0x34, 0x70, 0x78, 0x3b, 0x36, 0x70, 0x78, 0x3b, 0x61, 0x72, 0x74, + 0x73, 0x66, 0x6f, 0x6f, 0x74, 0x72, 0x65, 0x61, 0x6c, 0x77, 0x69, 0x6b, 0x69, + 0x68, 0x65, 0x61, 0x74, 0x73, 0x74, 0x65, 0x70, 0x74, 0x72, 0x69, 0x70, 0x6f, + 0x72, 0x67, 0x2f, 0x6c, 0x61, 0x6b, 0x65, 0x77, 0x65, 0x61, 0x6b, 0x74, 0x6f, + 0x6c, 0x64, 0x46, 0x6f, 0x72, 0x6d, 0x63, 0x61, 0x73, 0x74, 0x66, 0x61, 0x6e, + 0x73, 0x62, 0x61, 0x6e, 0x6b, 0x76, 0x65, 0x72, 0x79, 0x72, 0x75, 0x6e, 0x73, + 0x6a, 0x75, 0x6c, 0x79, 0x74, 0x61, 0x73, 0x6b, 0x31, 0x70, 0x78, 0x3b, 0x67, + 0x6f, 0x61, 0x6c, 0x67, 0x72, 0x65, 0x77, 0x73, 0x6c, 0x6f, 0x77, 0x65, 0x64, + 0x67, 0x65, 0x69, 0x64, 0x3d, 0x22, 0x73, 0x65, 0x74, 0x73, 0x35, 0x70, 0x78, + 0x3b, 0x2e, 0x6a, 0x73, 0x3f, 0x34, 0x30, 0x70, 0x78, 0x69, 0x66, 0x20, 0x28, + 0x73, 0x6f, 0x6f, 0x6e, 0x73, 0x65, 0x61, 0x74, 0x6e, 0x6f, 0x6e, 0x65, 0x74, + 0x75, 0x62, 0x65, 0x7a, 0x65, 0x72, 0x6f, 0x73, 0x65, 0x6e, 0x74, 0x72, 0x65, + 0x65, 0x64, 0x66, 0x61, 0x63, 0x74, 0x69, 0x6e, 0x74, 0x6f, 0x67, 0x69, 0x66, + 0x74, 0x68, 0x61, 0x72, 0x6d, 0x31, 0x38, 0x70, 0x78, 0x63, 0x61, 0x6d, 0x65, + 0x68, 0x69, 0x6c, 0x6c, 0x62, 0x6f, 0x6c, 0x64, 0x7a, 0x6f, 0x6f, 0x6d, 0x76, + 0x6f, 0x69, 0x64, 0x65, 0x61, 0x73, 0x79, 0x72, 0x69, 0x6e, 0x67, 0x66, 0x69, + 0x6c, 0x6c, 0x70, 0x65, 0x61, 0x6b, 0x69, 0x6e, 0x69, 0x74, 0x63, 0x6f, 0x73, + 0x74, 0x33, 0x70, 0x78, 0x3b, 0x6a, 0x61, 0x63, 0x6b, 0x74, 0x61, 0x67, 0x73, + 0x62, 0x69, 0x74, 0x73, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x64, 0x69, 0x74, 0x6b, + 0x6e, 0x65, 0x77, 0x6e, 0x65, 0x61, 0x72, 0x3c, 0x21, 0x2d, 0x2d, 0x67, 0x72, + 0x6f, 0x77, 0x4a, 0x53, 0x4f, 0x4e, 0x64, 0x75, 0x74, 0x79, 0x4e, 0x61, 0x6d, + 0x65, 0x73, 0x61, 0x6c, 0x65, 0x79, 0x6f, 0x75, 0x20, 0x6c, 0x6f, 0x74, 0x73, + 0x70, 0x61, 0x69, 0x6e, 0x6a, 0x61, 0x7a, 0x7a, 0x63, 0x6f, 0x6c, 0x64, 0x65, + 0x79, 0x65, 0x73, 0x66, 0x69, 0x73, 0x68, 0x77, 0x77, 0x77, 0x2e, 0x72, 0x69, + 0x73, 0x6b, 0x74, 0x61, 0x62, 0x73, 0x70, 0x72, 0x65, 0x76, 0x31, 0x30, 0x70, + 0x78, 0x72, 0x69, 0x73, 0x65, 0x32, 0x35, 0x70, 0x78, 0x42, 0x6c, 0x75, 0x65, + 0x64, 0x69, 0x6e, 0x67, 0x33, 0x30, 0x30, 0x2c, 0x62, 0x61, 0x6c, 0x6c, 0x66, + 0x6f, 0x72, 0x64, 0x65, 0x61, 0x72, 0x6e, 0x77, 0x69, 0x6c, 0x64, 0x62, 0x6f, + 0x78, 0x2e, 0x66, 0x61, 0x69, 0x72, 0x6c, 0x61, 0x63, 0x6b, 0x76, 0x65, 0x72, + 0x73, 0x70, 0x61, 0x69, 0x72, 0x6a, 0x75, 0x6e, 0x65, 0x74, 0x65, 0x63, 0x68, + 0x69, 0x66, 0x28, 0x21, 0x70, 0x69, 0x63, 0x6b, 0x65, 0x76, 0x69, 0x6c, 0x24, + 0x28, 0x22, 0x23, 0x77, 0x61, 0x72, 0x6d, 0x6c, 0x6f, 0x72, 0x64, 0x64, 0x6f, + 0x65, 0x73, 0x70, 0x75, 0x6c, 0x6c, 0x2c, 0x30, 0x30, 0x30, 0x69, 0x64, 0x65, + 0x61, 0x64, 0x72, 0x61, 0x77, 0x68, 0x75, 0x67, 0x65, 0x73, 0x70, 0x6f, 0x74, + 0x66, 0x75, 0x6e, 0x64, 0x62, 0x75, 0x72, 0x6e, 0x68, 0x72, 0x65, 0x66, 0x63, + 0x65, 0x6c, 0x6c, 0x6b, 0x65, 0x79, 0x73, 0x74, 0x69, 0x63, 0x6b, 0x68, 0x6f, + 0x75, 0x72, 0x6c, 0x6f, 0x73, 0x73, 0x66, 0x75, 0x65, 0x6c, 0x31, 0x32, 0x70, + 0x78, 0x73, 0x75, 0x69, 0x74, 0x64, 0x65, 0x61, 0x6c, 0x52, 0x53, 0x53, 0x22, + 0x61, 0x67, 0x65, 0x64, 0x67, 0x72, 0x65, 0x79, 0x47, 0x45, 0x54, 0x22, 0x65, + 0x61, 0x73, 0x65, 0x61, 0x69, 0x6d, 0x73, 0x67, 0x69, 0x72, 0x6c, 0x61, 0x69, + 0x64, 0x73, 0x38, 0x70, 0x78, 0x3b, 0x6e, 0x61, 0x76, 0x79, 0x67, 0x72, 0x69, + 0x64, 0x74, 0x69, 0x70, 0x73, 0x23, 0x39, 0x39, 0x39, 0x77, 0x61, 0x72, 0x73, + 0x6c, 0x61, 0x64, 0x79, 0x63, 0x61, 0x72, 0x73, 0x29, 0x3b, 0x20, 0x7d, 0x70, + 0x68, 0x70, 0x3f, 0x68, 0x65, 0x6c, 0x6c, 0x74, 0x61, 0x6c, 0x6c, 0x77, 0x68, + 0x6f, 0x6d, 0x7a, 0x68, 0x3a, 0xe5, 0x2a, 0x2f, 0x0d, 0x0a, 0x20, 0x31, 0x30, + 0x30, 0x68, 0x61, 0x6c, 0x6c, 0x2e, 0x0a, 0x0a, 0x41, 0x37, 0x70, 0x78, 0x3b, + 0x70, 0x75, 0x73, 0x68, 0x63, 0x68, 0x61, 0x74, 0x30, 0x70, 0x78, 0x3b, 0x63, + 0x72, 0x65, 0x77, 0x2a, 0x2f, 0x3c, 0x2f, 0x68, 0x61, 0x73, 0x68, 0x37, 0x35, + 0x70, 0x78, 0x66, 0x6c, 0x61, 0x74, 0x72, 0x61, 0x72, 0x65, 0x20, 0x26, 0x26, + 0x20, 0x74, 0x65, 0x6c, 0x6c, 0x63, 0x61, 0x6d, 0x70, 0x6f, 0x6e, 0x74, 0x6f, + 0x6c, 0x61, 0x69, 0x64, 0x6d, 0x69, 0x73, 0x73, 0x73, 0x6b, 0x69, 0x70, 0x74, + 0x65, 0x6e, 0x74, 0x66, 0x69, 0x6e, 0x65, 0x6d, 0x61, 0x6c, 0x65, 0x67, 0x65, + 0x74, 0x73, 0x70, 0x6c, 0x6f, 0x74, 0x34, 0x30, 0x30, 0x2c, 0x0d, 0x0a, 0x0d, + 0x0a, 0x63, 0x6f, 0x6f, 0x6c, 0x66, 0x65, 0x65, 0x74, 0x2e, 0x70, 0x68, 0x70, + 0x3c, 0x62, 0x72, 0x3e, 0x65, 0x72, 0x69, 0x63, 0x6d, 0x6f, 0x73, 0x74, 0x67, + 0x75, 0x69, 0x64, 0x62, 0x65, 0x6c, 0x6c, 0x64, 0x65, 0x73, 0x63, 0x68, 0x61, + 0x69, 0x72, 0x6d, 0x61, 0x74, 0x68, 0x61, 0x74, 0x6f, 0x6d, 0x2f, 0x69, 0x6d, + 0x67, 0x26, 0x23, 0x38, 0x32, 0x6c, 0x75, 0x63, 0x6b, 0x63, 0x65, 0x6e, 0x74, + 0x30, 0x30, 0x30, 0x3b, 0x74, 0x69, 0x6e, 0x79, 0x67, 0x6f, 0x6e, 0x65, 0x68, + 0x74, 0x6d, 0x6c, 0x73, 0x65, 0x6c, 0x6c, 0x64, 0x72, 0x75, 0x67, 0x46, 0x52, + 0x45, 0x45, 0x6e, 0x6f, 0x64, 0x65, 0x6e, 0x69, 0x63, 0x6b, 0x3f, 0x69, 0x64, + 0x3d, 0x6c, 0x6f, 0x73, 0x65, 0x6e, 0x75, 0x6c, 0x6c, 0x76, 0x61, 0x73, 0x74, + 0x77, 0x69, 0x6e, 0x64, 0x52, 0x53, 0x53, 0x20, 0x77, 0x65, 0x61, 0x72, 0x72, + 0x65, 0x6c, 0x79, 0x62, 0x65, 0x65, 0x6e, 0x73, 0x61, 0x6d, 0x65, 0x64, 0x75, + 0x6b, 0x65, 0x6e, 0x61, 0x73, 0x61, 0x63, 0x61, 0x70, 0x65, 0x77, 0x69, 0x73, + 0x68, 0x67, 0x75, 0x6c, 0x66, 0x54, 0x32, 0x33, 0x3a, 0x68, 0x69, 0x74, 0x73, + 0x73, 0x6c, 0x6f, 0x74, 0x67, 0x61, 0x74, 0x65, 0x6b, 0x69, 0x63, 0x6b, 0x62, + 0x6c, 0x75, 0x72, 0x74, 0x68, 0x65, 0x79, 0x31, 0x35, 0x70, 0x78, 0x27, 0x27, + 0x29, 0x3b, 0x29, 0x3b, 0x22, 0x3e, 0x6d, 0x73, 0x69, 0x65, 0x77, 0x69, 0x6e, + 0x73, 0x62, 0x69, 0x72, 0x64, 0x73, 0x6f, 0x72, 0x74, 0x62, 0x65, 0x74, 0x61, + 0x73, 0x65, 0x65, 0x6b, 0x54, 0x31, 0x38, 0x3a, 0x6f, 0x72, 0x64, 0x73, 0x74, + 0x72, 0x65, 0x65, 0x6d, 0x61, 0x6c, 0x6c, 0x36, 0x30, 0x70, 0x78, 0x66, 0x61, + 0x72, 0x6d, 0xe2, 0x80, 0x99, 0x73, 0x62, 0x6f, 0x79, 0x73, 0x5b, 0x30, 0x5d, + 0x2e, 0x27, 0x29, 0x3b, 0x22, 0x50, 0x4f, 0x53, 0x54, 0x62, 0x65, 0x61, 0x72, + 0x6b, 0x69, 0x64, 0x73, 0x29, 0x3b, 0x7d, 0x7d, 0x6d, 0x61, 0x72, 0x79, 0x74, + 0x65, 0x6e, 0x64, 0x28, 0x55, 0x4b, 0x29, 0x71, 0x75, 0x61, 0x64, 0x7a, 0x68, + 0x3a, 0xe6, 0x2d, 0x73, 0x69, 0x7a, 0x2d, 0x2d, 0x2d, 0x2d, 0x70, 0x72, 0x6f, + 0x70, 0x27, 0x29, 0x3b, 0x0d, 0x6c, 0x69, 0x66, 0x74, 0x54, 0x31, 0x39, 0x3a, + 0x76, 0x69, 0x63, 0x65, 0x61, 0x6e, 0x64, 0x79, 0x64, 0x65, 0x62, 0x74, 0x3e, + 0x52, 0x53, 0x53, 0x70, 0x6f, 0x6f, 0x6c, 0x6e, 0x65, 0x63, 0x6b, 0x62, 0x6c, + 0x6f, 0x77, 0x54, 0x31, 0x36, 0x3a, 0x64, 0x6f, 0x6f, 0x72, 0x65, 0x76, 0x61, + 0x6c, 0x54, 0x31, 0x37, 0x3a, 0x6c, 0x65, 0x74, 0x73, 0x66, 0x61, 0x69, 0x6c, + 0x6f, 0x72, 0x61, 0x6c, 0x70, 0x6f, 0x6c, 0x6c, 0x6e, 0x6f, 0x76, 0x61, 0x63, + 0x6f, 0x6c, 0x73, 0x67, 0x65, 0x6e, 0x65, 0x20, 0xe2, 0x80, 0x94, 0x73, 0x6f, + 0x66, 0x74, 0x72, 0x6f, 0x6d, 0x65, 0x74, 0x69, 0x6c, 0x6c, 0x72, 0x6f, 0x73, + 0x73, 0x3c, 0x68, 0x33, 0x3e, 0x70, 0x6f, 0x75, 0x72, 0x66, 0x61, 0x64, 0x65, + 0x70, 0x69, 0x6e, 0x6b, 0x3c, 0x74, 0x72, 0x3e, 0x6d, 0x69, 0x6e, 0x69, 0x29, + 0x7c, 0x21, 0x28, 0x6d, 0x69, 0x6e, 0x65, 0x7a, 0x68, 0x3a, 0xe8, 0x62, 0x61, + 0x72, 0x73, 0x68, 0x65, 0x61, 0x72, 0x30, 0x30, 0x29, 0x3b, 0x6d, 0x69, 0x6c, + 0x6b, 0x20, 0x2d, 0x2d, 0x3e, 0x69, 0x72, 0x6f, 0x6e, 0x66, 0x72, 0x65, 0x64, + 0x64, 0x69, 0x73, 0x6b, 0x77, 0x65, 0x6e, 0x74, 0x73, 0x6f, 0x69, 0x6c, 0x70, + 0x75, 0x74, 0x73, 0x2f, 0x6a, 0x73, 0x2f, 0x68, 0x6f, 0x6c, 0x79, 0x54, 0x32, + 0x32, 0x3a, 0x49, 0x53, 0x42, 0x4e, 0x54, 0x32, 0x30, 0x3a, 0x61, 0x64, 0x61, + 0x6d, 0x73, 0x65, 0x65, 0x73, 0x3c, 0x68, 0x32, 0x3e, 0x6a, 0x73, 0x6f, 0x6e, + 0x27, 0x2c, 0x20, 0x27, 0x63, 0x6f, 0x6e, 0x74, 0x54, 0x32, 0x31, 0x3a, 0x20, + 0x52, 0x53, 0x53, 0x6c, 0x6f, 0x6f, 0x70, 0x61, 0x73, 0x69, 0x61, 0x6d, 0x6f, + 0x6f, 0x6e, 0x3c, 0x2f, 0x70, 0x3e, 0x73, 0x6f, 0x75, 0x6c, 0x4c, 0x49, 0x4e, + 0x45, 0x66, 0x6f, 0x72, 0x74, 0x63, 0x61, 0x72, 0x74, 0x54, 0x31, 0x34, 0x3a, + 0x3c, 0x68, 0x31, 0x3e, 0x38, 0x30, 0x70, 0x78, 0x21, 0x2d, 0x2d, 0x3c, 0x39, + 0x70, 0x78, 0x3b, 0x54, 0x30, 0x34, 0x3a, 0x6d, 0x69, 0x6b, 0x65, 0x3a, 0x34, + 0x36, 0x5a, 0x6e, 0x69, 0x63, 0x65, 0x69, 0x6e, 0x63, 0x68, 0x59, 0x6f, 0x72, + 0x6b, 0x72, 0x69, 0x63, 0x65, 0x7a, 0x68, 0x3a, 0xe4, 0x27, 0x29, 0x29, 0x3b, + 0x70, 0x75, 0x72, 0x65, 0x6d, 0x61, 0x67, 0x65, 0x70, 0x61, 0x72, 0x61, 0x74, + 0x6f, 0x6e, 0x65, 0x62, 0x6f, 0x6e, 0x64, 0x3a, 0x33, 0x37, 0x5a, 0x5f, 0x6f, + 0x66, 0x5f, 0x27, 0x5d, 0x29, 0x3b, 0x30, 0x30, 0x30, 0x2c, 0x7a, 0x68, 0x3a, + 0xe7, 0x74, 0x61, 0x6e, 0x6b, 0x79, 0x61, 0x72, 0x64, 0x62, 0x6f, 0x77, 0x6c, + 0x62, 0x75, 0x73, 0x68, 0x3a, 0x35, 0x36, 0x5a, 0x4a, 0x61, 0x76, 0x61, 0x33, + 0x30, 0x70, 0x78, 0x0a, 0x7c, 0x7d, 0x0a, 0x25, 0x43, 0x33, 0x25, 0x3a, 0x33, + 0x34, 0x5a, 0x6a, 0x65, 0x66, 0x66, 0x45, 0x58, 0x50, 0x49, 0x63, 0x61, 0x73, + 0x68, 0x76, 0x69, 0x73, 0x61, 0x67, 0x6f, 0x6c, 0x66, 0x73, 0x6e, 0x6f, 0x77, + 0x7a, 0x68, 0x3a, 0xe9, 0x71, 0x75, 0x65, 0x72, 0x2e, 0x63, 0x73, 0x73, 0x73, + 0x69, 0x63, 0x6b, 0x6d, 0x65, 0x61, 0x74, 0x6d, 0x69, 0x6e, 0x2e, 0x62, 0x69, + 0x6e, 0x64, 0x64, 0x65, 0x6c, 0x6c, 0x68, 0x69, 0x72, 0x65, 0x70, 0x69, 0x63, + 0x73, 0x72, 0x65, 0x6e, 0x74, 0x3a, 0x33, 0x36, 0x5a, 0x48, 0x54, 0x54, 0x50, + 0x2d, 0x32, 0x30, 0x31, 0x66, 0x6f, 0x74, 0x6f, 0x77, 0x6f, 0x6c, 0x66, 0x45, + 0x4e, 0x44, 0x20, 0x78, 0x62, 0x6f, 0x78, 0x3a, 0x35, 0x34, 0x5a, 0x42, 0x4f, + 0x44, 0x59, 0x64, 0x69, 0x63, 0x6b, 0x3b, 0x0a, 0x7d, 0x0a, 0x65, 0x78, 0x69, + 0x74, 0x3a, 0x33, 0x35, 0x5a, 0x76, 0x61, 0x72, 0x73, 0x62, 0x65, 0x61, 0x74, + 0x27, 0x7d, 0x29, 0x3b, 0x64, 0x69, 0x65, 0x74, 0x39, 0x39, 0x39, 0x3b, 0x61, + 0x6e, 0x6e, 0x65, 0x7d, 0x7d, 0x3c, 0x2f, 0x5b, 0x69, 0x5d, 0x2e, 0x4c, 0x61, + 0x6e, 0x67, 0x6b, 0x6d, 0xc2, 0xb2, 0x77, 0x69, 0x72, 0x65, 0x74, 0x6f, 0x79, + 0x73, 0x61, 0x64, 0x64, 0x73, 0x73, 0x65, 0x61, 0x6c, 0x61, 0x6c, 0x65, 0x78, + 0x3b, 0x0a, 0x09, 0x7d, 0x65, 0x63, 0x68, 0x6f, 0x6e, 0x69, 0x6e, 0x65, 0x2e, + 0x6f, 0x72, 0x67, 0x30, 0x30, 0x35, 0x29, 0x74, 0x6f, 0x6e, 0x79, 0x6a, 0x65, + 0x77, 0x73, 0x73, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x67, 0x73, 0x72, 0x6f, 0x6f, + 0x66, 0x30, 0x30, 0x30, 0x29, 0x20, 0x32, 0x30, 0x30, 0x77, 0x69, 0x6e, 0x65, + 0x67, 0x65, 0x61, 0x72, 0x64, 0x6f, 0x67, 0x73, 0x62, 0x6f, 0x6f, 0x74, 0x67, + 0x61, 0x72, 0x79, 0x63, 0x75, 0x74, 0x73, 0x74, 0x79, 0x6c, 0x65, 0x74, 0x65, + 0x6d, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x78, 0x6d, 0x6c, 0x63, 0x6f, 0x63, + 0x6b, 0x67, 0x61, 0x6e, 0x67, 0x24, 0x28, 0x27, 0x2e, 0x35, 0x30, 0x70, 0x78, + 0x50, 0x68, 0x2e, 0x44, 0x6d, 0x69, 0x73, 0x63, 0x61, 0x6c, 0x61, 0x6e, 0x6c, + 0x6f, 0x61, 0x6e, 0x64, 0x65, 0x73, 0x6b, 0x6d, 0x69, 0x6c, 0x65, 0x72, 0x79, + 0x61, 0x6e, 0x75, 0x6e, 0x69, 0x78, 0x64, 0x69, 0x73, 0x63, 0x29, 0x3b, 0x7d, + 0x0a, 0x64, 0x75, 0x73, 0x74, 0x63, 0x6c, 0x69, 0x70, 0x29, 0x2e, 0x0a, 0x0a, + 0x37, 0x30, 0x70, 0x78, 0x2d, 0x32, 0x30, 0x30, 0x44, 0x56, 0x44, 0x73, 0x37, + 0x5d, 0x3e, 0x3c, 0x74, 0x61, 0x70, 0x65, 0x64, 0x65, 0x6d, 0x6f, 0x69, 0x2b, + 0x2b, 0x29, 0x77, 0x61, 0x67, 0x65, 0x65, 0x75, 0x72, 0x6f, 0x70, 0x68, 0x69, + 0x6c, 0x6f, 0x70, 0x74, 0x73, 0x68, 0x6f, 0x6c, 0x65, 0x46, 0x41, 0x51, 0x73, + 0x61, 0x73, 0x69, 0x6e, 0x2d, 0x32, 0x36, 0x54, 0x6c, 0x61, 0x62, 0x73, 0x70, + 0x65, 0x74, 0x73, 0x55, 0x52, 0x4c, 0x20, 0x62, 0x75, 0x6c, 0x6b, 0x63, 0x6f, + 0x6f, 0x6b, 0x3b, 0x7d, 0x0d, 0x0a, 0x48, 0x45, 0x41, 0x44, 0x5b, 0x30, 0x5d, + 0x29, 0x61, 0x62, 0x62, 0x72, 0x6a, 0x75, 0x61, 0x6e, 0x28, 0x31, 0x39, 0x38, + 0x6c, 0x65, 0x73, 0x68, 0x74, 0x77, 0x69, 0x6e, 0x3c, 0x2f, 0x69, 0x3e, 0x73, + 0x6f, 0x6e, 0x79, 0x67, 0x75, 0x79, 0x73, 0x66, 0x75, 0x63, 0x6b, 0x70, 0x69, + 0x70, 0x65, 0x7c, 0x2d, 0x0a, 0x21, 0x30, 0x30, 0x32, 0x29, 0x6e, 0x64, 0x6f, + 0x77, 0x5b, 0x31, 0x5d, 0x3b, 0x5b, 0x5d, 0x3b, 0x0a, 0x4c, 0x6f, 0x67, 0x20, + 0x73, 0x61, 0x6c, 0x74, 0x0d, 0x0a, 0x09, 0x09, 0x62, 0x61, 0x6e, 0x67, 0x74, + 0x72, 0x69, 0x6d, 0x62, 0x61, 0x74, 0x68, 0x29, 0x7b, 0x0d, 0x0a, 0x30, 0x30, + 0x70, 0x78, 0x0a, 0x7d, 0x29, 0x3b, 0x6b, 0x6f, 0x3a, 0xec, 0x66, 0x65, 0x65, + 0x73, 0x61, 0x64, 0x3e, 0x0d, 0x73, 0x3a, 0x2f, 0x2f, 0x20, 0x5b, 0x5d, 0x3b, + 0x74, 0x6f, 0x6c, 0x6c, 0x70, 0x6c, 0x75, 0x67, 0x28, 0x29, 0x7b, 0x0a, 0x7b, + 0x0d, 0x0a, 0x20, 0x2e, 0x6a, 0x73, 0x27, 0x32, 0x30, 0x30, 0x70, 0x64, 0x75, + 0x61, 0x6c, 0x62, 0x6f, 0x61, 0x74, 0x2e, 0x4a, 0x50, 0x47, 0x29, 0x3b, 0x0a, + 0x7d, 0x71, 0x75, 0x6f, 0x74, 0x29, 0x3b, 0x0a, 0x0a, 0x27, 0x29, 0x3b, 0x0a, + 0x0d, 0x0a, 0x7d, 0x0d, 0x32, 0x30, 0x31, 0x34, 0x32, 0x30, 0x31, 0x35, 0x32, + 0x30, 0x31, 0x36, 0x32, 0x30, 0x31, 0x37, 0x32, 0x30, 0x31, 0x38, 0x32, 0x30, + 0x31, 0x39, 0x32, 0x30, 0x32, 0x30, 0x32, 0x30, 0x32, 0x31, 0x32, 0x30, 0x32, + 0x32, 0x32, 0x30, 0x32, 0x33, 0x32, 0x30, 0x32, 0x34, 0x32, 0x30, 0x32, 0x35, + 0x32, 0x30, 0x32, 0x36, 0x32, 0x30, 0x32, 0x37, 0x32, 0x30, 0x32, 0x38, 0x32, + 0x30, 0x32, 0x39, 0x32, 0x30, 0x33, 0x30, 0x32, 0x30, 0x33, 0x31, 0x32, 0x30, + 0x33, 0x32, 0x32, 0x30, 0x33, 0x33, 0x32, 0x30, 0x33, 0x34, 0x32, 0x30, 0x33, + 0x35, 0x32, 0x30, 0x33, 0x36, 0x32, 0x30, 0x33, 0x37, 0x32, 0x30, 0x31, 0x33, + 0x32, 0x30, 0x31, 0x32, 0x32, 0x30, 0x31, 0x31, 0x32, 0x30, 0x31, 0x30, 0x32, + 0x30, 0x30, 0x39, 0x32, 0x30, 0x30, 0x38, 0x32, 0x30, 0x30, 0x37, 0x32, 0x30, + 0x30, 0x36, 0x32, 0x30, 0x30, 0x35, 0x32, 0x30, 0x30, 0x34, 0x32, 0x30, 0x30, + 0x33, 0x32, 0x30, 0x30, 0x32, 0x32, 0x30, 0x30, 0x31, 0x32, 0x30, 0x30, 0x30, + 0x31, 0x39, 0x39, 0x39, 0x31, 0x39, 0x39, 0x38, 0x31, 0x39, 0x39, 0x37, 0x31, + 0x39, 0x39, 0x36, 0x31, 0x39, 0x39, 0x35, 0x31, 0x39, 0x39, 0x34, 0x31, 0x39, + 0x39, 0x33, 0x31, 0x39, 0x39, 0x32, 0x31, 0x39, 0x39, 0x31, 0x31, 0x39, 0x39, + 0x30, 0x31, 0x39, 0x38, 0x39, 0x31, 0x39, 0x38, 0x38, 0x31, 0x39, 0x38, 0x37, + 0x31, 0x39, 0x38, 0x36, 0x31, 0x39, 0x38, 0x35, 0x31, 0x39, 0x38, 0x34, 0x31, + 0x39, 0x38, 0x33, 0x31, 0x39, 0x38, 0x32, 0x31, 0x39, 0x38, 0x31, 0x31, 0x39, + 0x38, 0x30, 0x31, 0x39, 0x37, 0x39, 0x31, 0x39, 0x37, 0x38, 0x31, 0x39, 0x37, + 0x37, 0x31, 0x39, 0x37, 0x36, 0x31, 0x39, 0x37, 0x35, 0x31, 0x39, 0x37, 0x34, + 0x31, 0x39, 0x37, 0x33, 0x31, 0x39, 0x37, 0x32, 0x31, 0x39, 0x37, 0x31, 0x31, + 0x39, 0x37, 0x30, 0x31, 0x39, 0x36, 0x39, 0x31, 0x39, 0x36, 0x38, 0x31, 0x39, + 0x36, 0x37, 0x31, 0x39, 0x36, 0x36, 0x31, 0x39, 0x36, 0x35, 0x31, 0x39, 0x36, + 0x34, 0x31, 0x39, 0x36, 0x33, 0x31, 0x39, 0x36, 0x32, 0x31, 0x39, 0x36, 0x31, + 0x31, 0x39, 0x36, 0x30, 0x31, 0x39, 0x35, 0x39, 0x31, 0x39, 0x35, 0x38, 0x31, + 0x39, 0x35, 0x37, 0x31, 0x39, 0x35, 0x36, 0x31, 0x39, 0x35, 0x35, 0x31, 0x39, + 0x35, 0x34, 0x31, 0x39, 0x35, 0x33, 0x31, 0x39, 0x35, 0x32, 0x31, 0x39, 0x35, + 0x31, 0x31, 0x39, 0x35, 0x30, 0x31, 0x30, 0x30, 0x30, 0x31, 0x30, 0x32, 0x34, + 0x31, 0x33, 0x39, 0x34, 0x30, 0x30, 0x30, 0x30, 0x39, 0x39, 0x39, 0x39, 0x63, + 0x6f, 0x6d, 0x6f, 0x6d, 0xc3, 0xa1, 0x73, 0x65, 0x73, 0x74, 0x65, 0x65, 0x73, + 0x74, 0x61, 0x70, 0x65, 0x72, 0x6f, 0x74, 0x6f, 0x64, 0x6f, 0x68, 0x61, 0x63, + 0x65, 0x63, 0x61, 0x64, 0x61, 0x61, 0xc3, 0xb1, 0x6f, 0x62, 0x69, 0x65, 0x6e, + 0x64, 0xc3, 0xad, 0x61, 0x61, 0x73, 0xc3, 0xad, 0x76, 0x69, 0x64, 0x61, 0x63, + 0x61, 0x73, 0x6f, 0x6f, 0x74, 0x72, 0x6f, 0x66, 0x6f, 0x72, 0x6f, 0x73, 0x6f, + 0x6c, 0x6f, 0x6f, 0x74, 0x72, 0x61, 0x63, 0x75, 0x61, 0x6c, 0x64, 0x69, 0x6a, + 0x6f, 0x73, 0x69, 0x64, 0x6f, 0x67, 0x72, 0x61, 0x6e, 0x74, 0x69, 0x70, 0x6f, + 0x74, 0x65, 0x6d, 0x61, 0x64, 0x65, 0x62, 0x65, 0x61, 0x6c, 0x67, 0x6f, 0x71, + 0x75, 0xc3, 0xa9, 0x65, 0x73, 0x74, 0x6f, 0x6e, 0x61, 0x64, 0x61, 0x74, 0x72, + 0x65, 0x73, 0x70, 0x6f, 0x63, 0x6f, 0x63, 0x61, 0x73, 0x61, 0x62, 0x61, 0x6a, + 0x6f, 0x74, 0x6f, 0x64, 0x61, 0x73, 0x69, 0x6e, 0x6f, 0x61, 0x67, 0x75, 0x61, + 0x70, 0x75, 0x65, 0x73, 0x75, 0x6e, 0x6f, 0x73, 0x61, 0x6e, 0x74, 0x65, 0x64, + 0x69, 0x63, 0x65, 0x6c, 0x75, 0x69, 0x73, 0x65, 0x6c, 0x6c, 0x61, 0x6d, 0x61, + 0x79, 0x6f, 0x7a, 0x6f, 0x6e, 0x61, 0x61, 0x6d, 0x6f, 0x72, 0x70, 0x69, 0x73, + 0x6f, 0x6f, 0x62, 0x72, 0x61, 0x63, 0x6c, 0x69, 0x63, 0x65, 0x6c, 0x6c, 0x6f, + 0x64, 0x69, 0x6f, 0x73, 0x68, 0x6f, 0x72, 0x61, 0x63, 0x61, 0x73, 0x69, 0xd0, + 0xb7, 0xd0, 0xb0, 0xd0, 0xbd, 0xd0, 0xb0, 0xd0, 0xbe, 0xd0, 0xbc, 0xd1, 0x80, + 0xd0, 0xb0, 0xd1, 0x80, 0xd1, 0x83, 0xd1, 0x82, 0xd0, 0xb0, 0xd0, 0xbd, 0xd0, + 0xb5, 0xd0, 0xbf, 0xd0, 0xbe, 0xd0, 0xbe, 0xd1, 0x82, 0xd0, 0xb8, 0xd0, 0xb7, + 0xd0, 0xbd, 0xd0, 0xbe, 0xd0, 0xb4, 0xd0, 0xbe, 0xd1, 0x82, 0xd0, 0xbe, 0xd0, + 0xb6, 0xd0, 0xb5, 0xd0, 0xbe, 0xd0, 0xbd, 0xd0, 0xb8, 0xd1, 0x85, 0xd0, 0x9d, + 0xd0, 0xb0, 0xd0, 0xb5, 0xd0, 0xb5, 0xd0, 0xb1, 0xd1, 0x8b, 0xd0, 0xbc, 0xd1, + 0x8b, 0xd0, 0x92, 0xd1, 0x8b, 0xd1, 0x81, 0xd0, 0xbe, 0xd0, 0xb2, 0xd1, 0x8b, + 0xd0, 0xb2, 0xd0, 0xbe, 0xd0, 0x9d, 0xd0, 0xbe, 0xd0, 0xbe, 0xd0, 0xb1, 0xd0, + 0x9f, 0xd0, 0xbe, 0xd0, 0xbb, 0xd0, 0xb8, 0xd0, 0xbd, 0xd0, 0xb8, 0xd0, 0xa0, + 0xd0, 0xa4, 0xd0, 0x9d, 0xd0, 0xb5, 0xd0, 0x9c, 0xd1, 0x8b, 0xd1, 0x82, 0xd1, + 0x8b, 0xd0, 0x9e, 0xd0, 0xbd, 0xd0, 0xb8, 0xd0, 0xbc, 0xd0, 0xb4, 0xd0, 0xb0, + 0xd0, 0x97, 0xd0, 0xb0, 0xd0, 0x94, 0xd0, 0xb0, 0xd0, 0x9d, 0xd1, 0x83, 0xd0, + 0x9e, 0xd0, 0xb1, 0xd1, 0x82, 0xd0, 0xb5, 0xd0, 0x98, 0xd0, 0xb7, 0xd0, 0xb5, + 0xd0, 0xb9, 0xd0, 0xbd, 0xd1, 0x83, 0xd0, 0xbc, 0xd0, 0xbc, 0xd0, 0xa2, 0xd1, + 0x8b, 0xd1, 0x83, 0xd0, 0xb6, 0xd9, 0x81, 0xd9, 0x8a, 0xd8, 0xa3, 0xd9, 0x86, + 0xd9, 0x85, 0xd8, 0xa7, 0xd9, 0x85, 0xd8, 0xb9, 0xd9, 0x83, 0xd9, 0x84, 0xd8, + 0xa3, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf, 0xd9, 0x8a, 0xd8, 0xa7, 0xd9, 0x81, + 0xd9, 0x89, 0xd9, 0x87, 0xd9, 0x88, 0xd9, 0x84, 0xd9, 0x85, 0xd9, 0x84, 0xd9, + 0x83, 0xd8, 0xa7, 0xd9, 0x88, 0xd9, 0x84, 0xd9, 0x87, 0xd8, 0xa8, 0xd8, 0xb3, + 0xd8, 0xa7, 0xd9, 0x84, 0xd8, 0xa5, 0xd9, 0x86, 0xd9, 0x87, 0xd9, 0x8a, 0xd8, + 0xa3, 0xd9, 0x8a, 0xd9, 0x82, 0xd8, 0xaf, 0xd9, 0x87, 0xd9, 0x84, 0xd8, 0xab, + 0xd9, 0x85, 0xd8, 0xa8, 0xd9, 0x87, 0xd9, 0x84, 0xd9, 0x88, 0xd9, 0x84, 0xd9, + 0x8a, 0xd8, 0xa8, 0xd9, 0x84, 0xd8, 0xa7, 0xd9, 0x8a, 0xd8, 0xa8, 0xd9, 0x83, + 0xd8, 0xb4, 0xd9, 0x8a, 0xd8, 0xa7, 0xd9, 0x85, 0xd8, 0xa3, 0xd9, 0x85, 0xd9, + 0x86, 0xd8, 0xaa, 0xd8, 0xa8, 0xd9, 0x8a, 0xd9, 0x84, 0xd9, 0x86, 0xd8, 0xad, + 0xd8, 0xa8, 0xd9, 0x87, 0xd9, 0x85, 0xd9, 0x85, 0xd8, 0xb4, 0xd9, 0x88, 0xd8, + 0xb4, 0x66, 0x69, 0x72, 0x73, 0x74, 0x76, 0x69, 0x64, 0x65, 0x6f, 0x6c, 0x69, + 0x67, 0x68, 0x74, 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x6d, 0x65, 0x64, 0x69, 0x61, + 0x77, 0x68, 0x69, 0x74, 0x65, 0x63, 0x6c, 0x6f, 0x73, 0x65, 0x62, 0x6c, 0x61, + 0x63, 0x6b, 0x72, 0x69, 0x67, 0x68, 0x74, 0x73, 0x6d, 0x61, 0x6c, 0x6c, 0x62, + 0x6f, 0x6f, 0x6b, 0x73, 0x70, 0x6c, 0x61, 0x63, 0x65, 0x6d, 0x75, 0x73, 0x69, + 0x63, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x70, 0x6f, + 0x69, 0x6e, 0x74, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x6c, 0x65, 0x76, 0x65, 0x6c, + 0x74, 0x61, 0x62, 0x6c, 0x65, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x68, 0x6f, 0x75, + 0x73, 0x65, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x79, + 0x65, 0x61, 0x72, 0x73, 0x73, 0x74, 0x61, 0x74, 0x65, 0x74, 0x6f, 0x64, 0x61, + 0x79, 0x77, 0x61, 0x74, 0x65, 0x72, 0x73, 0x74, 0x61, 0x72, 0x74, 0x73, 0x74, + 0x79, 0x6c, 0x65, 0x64, 0x65, 0x61, 0x74, 0x68, 0x70, 0x6f, 0x77, 0x65, 0x72, + 0x70, 0x68, 0x6f, 0x6e, 0x65, 0x6e, 0x69, 0x67, 0x68, 0x74, 0x65, 0x72, 0x72, + 0x6f, 0x72, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x61, 0x62, 0x6f, 0x75, 0x74, 0x74, + 0x65, 0x72, 0x6d, 0x73, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x74, 0x6f, 0x6f, 0x6c, + 0x73, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x74, 0x69, + 0x6d, 0x65, 0x73, 0x6c, 0x61, 0x72, 0x67, 0x65, 0x77, 0x6f, 0x72, 0x64, 0x73, + 0x67, 0x61, 0x6d, 0x65, 0x73, 0x73, 0x68, 0x6f, 0x72, 0x74, 0x73, 0x70, 0x61, + 0x63, 0x65, 0x66, 0x6f, 0x63, 0x75, 0x73, 0x63, 0x6c, 0x65, 0x61, 0x72, 0x6d, + 0x6f, 0x64, 0x65, 0x6c, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x67, 0x75, 0x69, 0x64, + 0x65, 0x72, 0x61, 0x64, 0x69, 0x6f, 0x73, 0x68, 0x61, 0x72, 0x65, 0x77, 0x6f, + 0x6d, 0x65, 0x6e, 0x61, 0x67, 0x61, 0x69, 0x6e, 0x6d, 0x6f, 0x6e, 0x65, 0x79, + 0x69, 0x6d, 0x61, 0x67, 0x65, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x79, 0x6f, 0x75, + 0x6e, 0x67, 0x6c, 0x69, 0x6e, 0x65, 0x73, 0x6c, 0x61, 0x74, 0x65, 0x72, 0x63, + 0x6f, 0x6c, 0x6f, 0x72, 0x67, 0x72, 0x65, 0x65, 0x6e, 0x66, 0x72, 0x6f, 0x6e, + 0x74, 0x26, 0x61, 0x6d, 0x70, 0x3b, 0x77, 0x61, 0x74, 0x63, 0x68, 0x66, 0x6f, + 0x72, 0x63, 0x65, 0x70, 0x72, 0x69, 0x63, 0x65, 0x72, 0x75, 0x6c, 0x65, 0x73, + 0x62, 0x65, 0x67, 0x69, 0x6e, 0x61, 0x66, 0x74, 0x65, 0x72, 0x76, 0x69, 0x73, + 0x69, 0x74, 0x69, 0x73, 0x73, 0x75, 0x65, 0x61, 0x72, 0x65, 0x61, 0x73, 0x62, + 0x65, 0x6c, 0x6f, 0x77, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x74, 0x6f, 0x74, 0x61, + 0x6c, 0x68, 0x6f, 0x75, 0x72, 0x73, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x70, 0x72, + 0x69, 0x6e, 0x74, 0x70, 0x72, 0x65, 0x73, 0x73, 0x62, 0x75, 0x69, 0x6c, 0x74, + 0x6c, 0x69, 0x6e, 0x6b, 0x73, 0x73, 0x70, 0x65, 0x65, 0x64, 0x73, 0x74, 0x75, + 0x64, 0x79, 0x74, 0x72, 0x61, 0x64, 0x65, 0x66, 0x6f, 0x75, 0x6e, 0x64, 0x73, + 0x65, 0x6e, 0x73, 0x65, 0x75, 0x6e, 0x64, 0x65, 0x72, 0x73, 0x68, 0x6f, 0x77, + 0x6e, 0x66, 0x6f, 0x72, 0x6d, 0x73, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x61, 0x64, + 0x64, 0x65, 0x64, 0x73, 0x74, 0x69, 0x6c, 0x6c, 0x6d, 0x6f, 0x76, 0x65, 0x64, + 0x74, 0x61, 0x6b, 0x65, 0x6e, 0x61, 0x62, 0x6f, 0x76, 0x65, 0x66, 0x6c, 0x61, + 0x73, 0x68, 0x66, 0x69, 0x78, 0x65, 0x64, 0x6f, 0x66, 0x74, 0x65, 0x6e, 0x6f, + 0x74, 0x68, 0x65, 0x72, 0x76, 0x69, 0x65, 0x77, 0x73, 0x63, 0x68, 0x65, 0x63, + 0x6b, 0x6c, 0x65, 0x67, 0x61, 0x6c, 0x72, 0x69, 0x76, 0x65, 0x72, 0x69, 0x74, + 0x65, 0x6d, 0x73, 0x71, 0x75, 0x69, 0x63, 0x6b, 0x73, 0x68, 0x61, 0x70, 0x65, + 0x68, 0x75, 0x6d, 0x61, 0x6e, 0x65, 0x78, 0x69, 0x73, 0x74, 0x67, 0x6f, 0x69, + 0x6e, 0x67, 0x6d, 0x6f, 0x76, 0x69, 0x65, 0x74, 0x68, 0x69, 0x72, 0x64, 0x62, + 0x61, 0x73, 0x69, 0x63, 0x70, 0x65, 0x61, 0x63, 0x65, 0x73, 0x74, 0x61, 0x67, + 0x65, 0x77, 0x69, 0x64, 0x74, 0x68, 0x6c, 0x6f, 0x67, 0x69, 0x6e, 0x69, 0x64, + 0x65, 0x61, 0x73, 0x77, 0x72, 0x6f, 0x74, 0x65, 0x70, 0x61, 0x67, 0x65, 0x73, + 0x75, 0x73, 0x65, 0x72, 0x73, 0x64, 0x72, 0x69, 0x76, 0x65, 0x73, 0x74, 0x6f, + 0x72, 0x65, 0x62, 0x72, 0x65, 0x61, 0x6b, 0x73, 0x6f, 0x75, 0x74, 0x68, 0x76, + 0x6f, 0x69, 0x63, 0x65, 0x73, 0x69, 0x74, 0x65, 0x73, 0x6d, 0x6f, 0x6e, 0x74, + 0x68, 0x77, 0x68, 0x65, 0x72, 0x65, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x77, 0x68, + 0x69, 0x63, 0x68, 0x65, 0x61, 0x72, 0x74, 0x68, 0x66, 0x6f, 0x72, 0x75, 0x6d, + 0x74, 0x68, 0x72, 0x65, 0x65, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x70, 0x61, 0x72, + 0x74, 0x79, 0x43, 0x6c, 0x69, 0x63, 0x6b, 0x6c, 0x6f, 0x77, 0x65, 0x72, 0x6c, + 0x69, 0x76, 0x65, 0x73, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x6c, 0x61, 0x79, 0x65, + 0x72, 0x65, 0x6e, 0x74, 0x72, 0x79, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x75, 0x73, + 0x61, 0x67, 0x65, 0x73, 0x6f, 0x75, 0x6e, 0x64, 0x63, 0x6f, 0x75, 0x72, 0x74, + 0x79, 0x6f, 0x75, 0x72, 0x20, 0x62, 0x69, 0x72, 0x74, 0x68, 0x70, 0x6f, 0x70, + 0x75, 0x70, 0x74, 0x79, 0x70, 0x65, 0x73, 0x61, 0x70, 0x70, 0x6c, 0x79, 0x49, + 0x6d, 0x61, 0x67, 0x65, 0x62, 0x65, 0x69, 0x6e, 0x67, 0x75, 0x70, 0x70, 0x65, + 0x72, 0x6e, 0x6f, 0x74, 0x65, 0x73, 0x65, 0x76, 0x65, 0x72, 0x79, 0x73, 0x68, + 0x6f, 0x77, 0x73, 0x6d, 0x65, 0x61, 0x6e, 0x73, 0x65, 0x78, 0x74, 0x72, 0x61, + 0x6d, 0x61, 0x74, 0x63, 0x68, 0x74, 0x72, 0x61, 0x63, 0x6b, 0x6b, 0x6e, 0x6f, + 0x77, 0x6e, 0x65, 0x61, 0x72, 0x6c, 0x79, 0x62, 0x65, 0x67, 0x61, 0x6e, 0x73, + 0x75, 0x70, 0x65, 0x72, 0x70, 0x61, 0x70, 0x65, 0x72, 0x6e, 0x6f, 0x72, 0x74, + 0x68, 0x6c, 0x65, 0x61, 0x72, 0x6e, 0x67, 0x69, 0x76, 0x65, 0x6e, 0x6e, 0x61, + 0x6d, 0x65, 0x64, 0x65, 0x6e, 0x64, 0x65, 0x64, 0x54, 0x65, 0x72, 0x6d, 0x73, + 0x70, 0x61, 0x72, 0x74, 0x73, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x62, 0x72, 0x61, + 0x6e, 0x64, 0x75, 0x73, 0x69, 0x6e, 0x67, 0x77, 0x6f, 0x6d, 0x61, 0x6e, 0x66, + 0x61, 0x6c, 0x73, 0x65, 0x72, 0x65, 0x61, 0x64, 0x79, 0x61, 0x75, 0x64, 0x69, + 0x6f, 0x74, 0x61, 0x6b, 0x65, 0x73, 0x77, 0x68, 0x69, 0x6c, 0x65, 0x2e, 0x63, + 0x6f, 0x6d, 0x2f, 0x6c, 0x69, 0x76, 0x65, 0x64, 0x63, 0x61, 0x73, 0x65, 0x73, + 0x64, 0x61, 0x69, 0x6c, 0x79, 0x63, 0x68, 0x69, 0x6c, 0x64, 0x67, 0x72, 0x65, + 0x61, 0x74, 0x6a, 0x75, 0x64, 0x67, 0x65, 0x74, 0x68, 0x6f, 0x73, 0x65, 0x75, + 0x6e, 0x69, 0x74, 0x73, 0x6e, 0x65, 0x76, 0x65, 0x72, 0x62, 0x72, 0x6f, 0x61, + 0x64, 0x63, 0x6f, 0x61, 0x73, 0x74, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x61, 0x70, + 0x70, 0x6c, 0x65, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x63, 0x79, 0x63, 0x6c, 0x65, + 0x73, 0x63, 0x65, 0x6e, 0x65, 0x70, 0x6c, 0x61, 0x6e, 0x73, 0x63, 0x6c, 0x69, + 0x63, 0x6b, 0x77, 0x72, 0x69, 0x74, 0x65, 0x71, 0x75, 0x65, 0x65, 0x6e, 0x70, + 0x69, 0x65, 0x63, 0x65, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x66, 0x72, 0x61, 0x6d, + 0x65, 0x6f, 0x6c, 0x64, 0x65, 0x72, 0x70, 0x68, 0x6f, 0x74, 0x6f, 0x6c, 0x69, + 0x6d, 0x69, 0x74, 0x63, 0x61, 0x63, 0x68, 0x65, 0x63, 0x69, 0x76, 0x69, 0x6c, + 0x73, 0x63, 0x61, 0x6c, 0x65, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x74, 0x68, 0x65, + 0x6d, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x74, 0x6f, 0x75, 0x63, 0x68, 0x62, + 0x6f, 0x75, 0x6e, 0x64, 0x72, 0x6f, 0x79, 0x61, 0x6c, 0x61, 0x73, 0x6b, 0x65, + 0x64, 0x77, 0x68, 0x6f, 0x6c, 0x65, 0x73, 0x69, 0x6e, 0x63, 0x65, 0x73, 0x74, + 0x6f, 0x63, 0x6b, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x66, 0x61, 0x69, 0x74, 0x68, + 0x68, 0x65, 0x61, 0x72, 0x74, 0x65, 0x6d, 0x70, 0x74, 0x79, 0x6f, 0x66, 0x66, + 0x65, 0x72, 0x73, 0x63, 0x6f, 0x70, 0x65, 0x6f, 0x77, 0x6e, 0x65, 0x64, 0x6d, + 0x69, 0x67, 0x68, 0x74, 0x61, 0x6c, 0x62, 0x75, 0x6d, 0x74, 0x68, 0x69, 0x6e, + 0x6b, 0x62, 0x6c, 0x6f, 0x6f, 0x64, 0x61, 0x72, 0x72, 0x61, 0x79, 0x6d, 0x61, + 0x6a, 0x6f, 0x72, 0x74, 0x72, 0x75, 0x73, 0x74, 0x63, 0x61, 0x6e, 0x6f, 0x6e, + 0x75, 0x6e, 0x69, 0x6f, 0x6e, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x76, 0x61, 0x6c, + 0x69, 0x64, 0x73, 0x74, 0x6f, 0x6e, 0x65, 0x53, 0x74, 0x79, 0x6c, 0x65, 0x4c, + 0x6f, 0x67, 0x69, 0x6e, 0x68, 0x61, 0x70, 0x70, 0x79, 0x6f, 0x63, 0x63, 0x75, + 0x72, 0x6c, 0x65, 0x66, 0x74, 0x3a, 0x66, 0x72, 0x65, 0x73, 0x68, 0x71, 0x75, + 0x69, 0x74, 0x65, 0x66, 0x69, 0x6c, 0x6d, 0x73, 0x67, 0x72, 0x61, 0x64, 0x65, + 0x6e, 0x65, 0x65, 0x64, 0x73, 0x75, 0x72, 0x62, 0x61, 0x6e, 0x66, 0x69, 0x67, + 0x68, 0x74, 0x62, 0x61, 0x73, 0x69, 0x73, 0x68, 0x6f, 0x76, 0x65, 0x72, 0x61, + 0x75, 0x74, 0x6f, 0x3b, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x2e, 0x68, 0x74, 0x6d, + 0x6c, 0x6d, 0x69, 0x78, 0x65, 0x64, 0x66, 0x69, 0x6e, 0x61, 0x6c, 0x59, 0x6f, + 0x75, 0x72, 0x20, 0x73, 0x6c, 0x69, 0x64, 0x65, 0x74, 0x6f, 0x70, 0x69, 0x63, + 0x62, 0x72, 0x6f, 0x77, 0x6e, 0x61, 0x6c, 0x6f, 0x6e, 0x65, 0x64, 0x72, 0x61, + 0x77, 0x6e, 0x73, 0x70, 0x6c, 0x69, 0x74, 0x72, 0x65, 0x61, 0x63, 0x68, 0x52, + 0x69, 0x67, 0x68, 0x74, 0x64, 0x61, 0x74, 0x65, 0x73, 0x6d, 0x61, 0x72, 0x63, + 0x68, 0x71, 0x75, 0x6f, 0x74, 0x65, 0x67, 0x6f, 0x6f, 0x64, 0x73, 0x4c, 0x69, + 0x6e, 0x6b, 0x73, 0x64, 0x6f, 0x75, 0x62, 0x74, 0x61, 0x73, 0x79, 0x6e, 0x63, + 0x74, 0x68, 0x75, 0x6d, 0x62, 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x63, 0x68, 0x69, + 0x65, 0x66, 0x79, 0x6f, 0x75, 0x74, 0x68, 0x6e, 0x6f, 0x76, 0x65, 0x6c, 0x31, + 0x30, 0x70, 0x78, 0x3b, 0x73, 0x65, 0x72, 0x76, 0x65, 0x75, 0x6e, 0x74, 0x69, + 0x6c, 0x68, 0x61, 0x6e, 0x64, 0x73, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x53, 0x70, + 0x61, 0x63, 0x65, 0x71, 0x75, 0x65, 0x72, 0x79, 0x6a, 0x61, 0x6d, 0x65, 0x73, + 0x65, 0x71, 0x75, 0x61, 0x6c, 0x74, 0x77, 0x69, 0x63, 0x65, 0x30, 0x2c, 0x30, + 0x30, 0x30, 0x53, 0x74, 0x61, 0x72, 0x74, 0x70, 0x61, 0x6e, 0x65, 0x6c, 0x73, + 0x6f, 0x6e, 0x67, 0x73, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x65, 0x69, 0x67, 0x68, + 0x74, 0x73, 0x68, 0x69, 0x66, 0x74, 0x77, 0x6f, 0x72, 0x74, 0x68, 0x70, 0x6f, + 0x73, 0x74, 0x73, 0x6c, 0x65, 0x61, 0x64, 0x73, 0x77, 0x65, 0x65, 0x6b, 0x73, + 0x61, 0x76, 0x6f, 0x69, 0x64, 0x74, 0x68, 0x65, 0x73, 0x65, 0x6d, 0x69, 0x6c, + 0x65, 0x73, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x73, 0x6d, 0x61, 0x72, 0x74, 0x61, + 0x6c, 0x70, 0x68, 0x61, 0x70, 0x6c, 0x61, 0x6e, 0x74, 0x6d, 0x61, 0x72, 0x6b, + 0x73, 0x72, 0x61, 0x74, 0x65, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x73, 0x63, 0x6c, + 0x61, 0x69, 0x6d, 0x73, 0x61, 0x6c, 0x65, 0x73, 0x74, 0x65, 0x78, 0x74, 0x73, + 0x73, 0x74, 0x61, 0x72, 0x73, 0x77, 0x72, 0x6f, 0x6e, 0x67, 0x3c, 0x2f, 0x68, + 0x33, 0x3e, 0x74, 0x68, 0x69, 0x6e, 0x67, 0x2e, 0x6f, 0x72, 0x67, 0x2f, 0x6d, + 0x75, 0x6c, 0x74, 0x69, 0x68, 0x65, 0x61, 0x72, 0x64, 0x50, 0x6f, 0x77, 0x65, + 0x72, 0x73, 0x74, 0x61, 0x6e, 0x64, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x6f, + 0x6c, 0x69, 0x64, 0x28, 0x74, 0x68, 0x69, 0x73, 0x62, 0x72, 0x69, 0x6e, 0x67, + 0x73, 0x68, 0x69, 0x70, 0x73, 0x73, 0x74, 0x61, 0x66, 0x66, 0x74, 0x72, 0x69, + 0x65, 0x64, 0x63, 0x61, 0x6c, 0x6c, 0x73, 0x66, 0x75, 0x6c, 0x6c, 0x79, 0x66, + 0x61, 0x63, 0x74, 0x73, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x54, 0x68, 0x69, 0x73, + 0x20, 0x2f, 0x2f, 0x2d, 0x2d, 0x3e, 0x61, 0x64, 0x6d, 0x69, 0x6e, 0x65, 0x67, + 0x79, 0x70, 0x74, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x31, 0x35, 0x70, 0x78, 0x3b, + 0x45, 0x6d, 0x61, 0x69, 0x6c, 0x74, 0x72, 0x75, 0x65, 0x22, 0x63, 0x72, 0x6f, + 0x73, 0x73, 0x73, 0x70, 0x65, 0x6e, 0x74, 0x62, 0x6c, 0x6f, 0x67, 0x73, 0x62, + 0x6f, 0x78, 0x22, 0x3e, 0x6e, 0x6f, 0x74, 0x65, 0x64, 0x6c, 0x65, 0x61, 0x76, + 0x65, 0x63, 0x68, 0x69, 0x6e, 0x61, 0x73, 0x69, 0x7a, 0x65, 0x73, 0x67, 0x75, + 0x65, 0x73, 0x74, 0x3c, 0x2f, 0x68, 0x34, 0x3e, 0x72, 0x6f, 0x62, 0x6f, 0x74, + 0x68, 0x65, 0x61, 0x76, 0x79, 0x74, 0x72, 0x75, 0x65, 0x2c, 0x73, 0x65, 0x76, + 0x65, 0x6e, 0x67, 0x72, 0x61, 0x6e, 0x64, 0x63, 0x72, 0x69, 0x6d, 0x65, 0x73, + 0x69, 0x67, 0x6e, 0x73, 0x61, 0x77, 0x61, 0x72, 0x65, 0x64, 0x61, 0x6e, 0x63, + 0x65, 0x70, 0x68, 0x61, 0x73, 0x65, 0x3e, 0x3c, 0x21, 0x2d, 0x2d, 0x65, 0x6e, + 0x5f, 0x55, 0x53, 0x26, 0x23, 0x33, 0x39, 0x3b, 0x32, 0x30, 0x30, 0x70, 0x78, + 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6e, 0x65, 0x6e, 0x6a, + 0x6f, 0x79, 0x61, 0x6a, 0x61, 0x78, 0x2e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, + 0x6d, 0x69, 0x74, 0x68, 0x55, 0x2e, 0x53, 0x2e, 0x20, 0x68, 0x6f, 0x6c, 0x64, + 0x73, 0x70, 0x65, 0x74, 0x65, 0x72, 0x69, 0x6e, 0x64, 0x69, 0x61, 0x6e, 0x61, + 0x76, 0x22, 0x3e, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x73, 0x63, 0x6f, 0x72, 0x65, + 0x63, 0x6f, 0x6d, 0x65, 0x73, 0x64, 0x6f, 0x69, 0x6e, 0x67, 0x70, 0x72, 0x69, + 0x6f, 0x72, 0x53, 0x68, 0x61, 0x72, 0x65, 0x31, 0x39, 0x39, 0x30, 0x73, 0x72, + 0x6f, 0x6d, 0x61, 0x6e, 0x6c, 0x69, 0x73, 0x74, 0x73, 0x6a, 0x61, 0x70, 0x61, + 0x6e, 0x66, 0x61, 0x6c, 0x6c, 0x73, 0x74, 0x72, 0x69, 0x61, 0x6c, 0x6f, 0x77, + 0x6e, 0x65, 0x72, 0x61, 0x67, 0x72, 0x65, 0x65, 0x3c, 0x2f, 0x68, 0x32, 0x3e, + 0x61, 0x62, 0x75, 0x73, 0x65, 0x61, 0x6c, 0x65, 0x72, 0x74, 0x6f, 0x70, 0x65, + 0x72, 0x61, 0x22, 0x2d, 0x2f, 0x2f, 0x57, 0x63, 0x61, 0x72, 0x64, 0x73, 0x68, + 0x69, 0x6c, 0x6c, 0x73, 0x74, 0x65, 0x61, 0x6d, 0x73, 0x50, 0x68, 0x6f, 0x74, + 0x6f, 0x74, 0x72, 0x75, 0x74, 0x68, 0x63, 0x6c, 0x65, 0x61, 0x6e, 0x2e, 0x70, + 0x68, 0x70, 0x3f, 0x73, 0x61, 0x69, 0x6e, 0x74, 0x6d, 0x65, 0x74, 0x61, 0x6c, + 0x6c, 0x6f, 0x75, 0x69, 0x73, 0x6d, 0x65, 0x61, 0x6e, 0x74, 0x70, 0x72, 0x6f, + 0x6f, 0x66, 0x62, 0x72, 0x69, 0x65, 0x66, 0x72, 0x6f, 0x77, 0x22, 0x3e, 0x67, + 0x65, 0x6e, 0x72, 0x65, 0x74, 0x72, 0x75, 0x63, 0x6b, 0x6c, 0x6f, 0x6f, 0x6b, + 0x73, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x2e, 0x6e, + 0x65, 0x74, 0x2f, 0x2d, 0x2d, 0x3e, 0x0a, 0x3c, 0x74, 0x72, 0x79, 0x20, 0x7b, + 0x0a, 0x76, 0x61, 0x72, 0x20, 0x6d, 0x61, 0x6b, 0x65, 0x73, 0x63, 0x6f, 0x73, + 0x74, 0x73, 0x70, 0x6c, 0x61, 0x69, 0x6e, 0x61, 0x64, 0x75, 0x6c, 0x74, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x74, 0x72, 0x61, 0x69, 0x6e, 0x6c, 0x61, 0x62, 0x6f, + 0x72, 0x68, 0x65, 0x6c, 0x70, 0x73, 0x63, 0x61, 0x75, 0x73, 0x65, 0x6d, 0x61, + 0x67, 0x69, 0x63, 0x6d, 0x6f, 0x74, 0x6f, 0x72, 0x74, 0x68, 0x65, 0x69, 0x72, + 0x32, 0x35, 0x30, 0x70, 0x78, 0x6c, 0x65, 0x61, 0x73, 0x74, 0x73, 0x74, 0x65, + 0x70, 0x73, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x63, 0x6f, 0x75, 0x6c, 0x64, 0x67, + 0x6c, 0x61, 0x73, 0x73, 0x73, 0x69, 0x64, 0x65, 0x73, 0x66, 0x75, 0x6e, 0x64, + 0x73, 0x68, 0x6f, 0x74, 0x65, 0x6c, 0x61, 0x77, 0x61, 0x72, 0x64, 0x6d, 0x6f, + 0x75, 0x74, 0x68, 0x6d, 0x6f, 0x76, 0x65, 0x73, 0x70, 0x61, 0x72, 0x69, 0x73, + 0x67, 0x69, 0x76, 0x65, 0x73, 0x64, 0x75, 0x74, 0x63, 0x68, 0x74, 0x65, 0x78, + 0x61, 0x73, 0x66, 0x72, 0x75, 0x69, 0x74, 0x6e, 0x75, 0x6c, 0x6c, 0x2c, 0x7c, + 0x7c, 0x5b, 0x5d, 0x3b, 0x74, 0x6f, 0x70, 0x22, 0x3e, 0x0a, 0x3c, 0x21, 0x2d, + 0x2d, 0x50, 0x4f, 0x53, 0x54, 0x22, 0x6f, 0x63, 0x65, 0x61, 0x6e, 0x3c, 0x62, + 0x72, 0x2f, 0x3e, 0x66, 0x6c, 0x6f, 0x6f, 0x72, 0x73, 0x70, 0x65, 0x61, 0x6b, + 0x64, 0x65, 0x70, 0x74, 0x68, 0x20, 0x73, 0x69, 0x7a, 0x65, 0x62, 0x61, 0x6e, + 0x6b, 0x73, 0x63, 0x61, 0x74, 0x63, 0x68, 0x63, 0x68, 0x61, 0x72, 0x74, 0x32, + 0x30, 0x70, 0x78, 0x3b, 0x61, 0x6c, 0x69, 0x67, 0x6e, 0x64, 0x65, 0x61, 0x6c, + 0x73, 0x77, 0x6f, 0x75, 0x6c, 0x64, 0x35, 0x30, 0x70, 0x78, 0x3b, 0x75, 0x72, + 0x6c, 0x3d, 0x22, 0x70, 0x61, 0x72, 0x6b, 0x73, 0x6d, 0x6f, 0x75, 0x73, 0x65, + 0x4d, 0x6f, 0x73, 0x74, 0x20, 0x2e, 0x2e, 0x2e, 0x3c, 0x2f, 0x61, 0x6d, 0x6f, + 0x6e, 0x67, 0x62, 0x72, 0x61, 0x69, 0x6e, 0x62, 0x6f, 0x64, 0x79, 0x20, 0x6e, + 0x6f, 0x6e, 0x65, 0x3b, 0x62, 0x61, 0x73, 0x65, 0x64, 0x63, 0x61, 0x72, 0x72, + 0x79, 0x64, 0x72, 0x61, 0x66, 0x74, 0x72, 0x65, 0x66, 0x65, 0x72, 0x70, 0x61, + 0x67, 0x65, 0x5f, 0x68, 0x6f, 0x6d, 0x65, 0x2e, 0x6d, 0x65, 0x74, 0x65, 0x72, + 0x64, 0x65, 0x6c, 0x61, 0x79, 0x64, 0x72, 0x65, 0x61, 0x6d, 0x70, 0x72, 0x6f, + 0x76, 0x65, 0x6a, 0x6f, 0x69, 0x6e, 0x74, 0x3c, 0x2f, 0x74, 0x72, 0x3e, 0x64, + 0x72, 0x75, 0x67, 0x73, 0x3c, 0x21, 0x2d, 0x2d, 0x20, 0x61, 0x70, 0x72, 0x69, + 0x6c, 0x69, 0x64, 0x65, 0x61, 0x6c, 0x61, 0x6c, 0x6c, 0x65, 0x6e, 0x65, 0x78, + 0x61, 0x63, 0x74, 0x66, 0x6f, 0x72, 0x74, 0x68, 0x63, 0x6f, 0x64, 0x65, 0x73, + 0x6c, 0x6f, 0x67, 0x69, 0x63, 0x56, 0x69, 0x65, 0x77, 0x20, 0x73, 0x65, 0x65, + 0x6d, 0x73, 0x62, 0x6c, 0x61, 0x6e, 0x6b, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x20, + 0x28, 0x32, 0x30, 0x30, 0x73, 0x61, 0x76, 0x65, 0x64, 0x5f, 0x6c, 0x69, 0x6e, + 0x6b, 0x67, 0x6f, 0x61, 0x6c, 0x73, 0x67, 0x72, 0x61, 0x6e, 0x74, 0x67, 0x72, + 0x65, 0x65, 0x6b, 0x68, 0x6f, 0x6d, 0x65, 0x73, 0x72, 0x69, 0x6e, 0x67, 0x73, + 0x72, 0x61, 0x74, 0x65, 0x64, 0x33, 0x30, 0x70, 0x78, 0x3b, 0x77, 0x68, 0x6f, + 0x73, 0x65, 0x70, 0x61, 0x72, 0x73, 0x65, 0x28, 0x29, 0x3b, 0x22, 0x20, 0x42, + 0x6c, 0x6f, 0x63, 0x6b, 0x6c, 0x69, 0x6e, 0x75, 0x78, 0x6a, 0x6f, 0x6e, 0x65, + 0x73, 0x70, 0x69, 0x78, 0x65, 0x6c, 0x27, 0x29, 0x3b, 0x22, 0x3e, 0x29, 0x3b, + 0x69, 0x66, 0x28, 0x2d, 0x6c, 0x65, 0x66, 0x74, 0x64, 0x61, 0x76, 0x69, 0x64, + 0x68, 0x6f, 0x72, 0x73, 0x65, 0x46, 0x6f, 0x63, 0x75, 0x73, 0x72, 0x61, 0x69, + 0x73, 0x65, 0x62, 0x6f, 0x78, 0x65, 0x73, 0x54, 0x72, 0x61, 0x63, 0x6b, 0x65, + 0x6d, 0x65, 0x6e, 0x74, 0x3c, 0x2f, 0x65, 0x6d, 0x3e, 0x62, 0x61, 0x72, 0x22, + 0x3e, 0x2e, 0x73, 0x72, 0x63, 0x3d, 0x74, 0x6f, 0x77, 0x65, 0x72, 0x61, 0x6c, + 0x74, 0x3d, 0x22, 0x63, 0x61, 0x62, 0x6c, 0x65, 0x68, 0x65, 0x6e, 0x72, 0x79, + 0x32, 0x34, 0x70, 0x78, 0x3b, 0x73, 0x65, 0x74, 0x75, 0x70, 0x69, 0x74, 0x61, + 0x6c, 0x79, 0x73, 0x68, 0x61, 0x72, 0x70, 0x6d, 0x69, 0x6e, 0x6f, 0x72, 0x74, + 0x61, 0x73, 0x74, 0x65, 0x77, 0x61, 0x6e, 0x74, 0x73, 0x74, 0x68, 0x69, 0x73, + 0x2e, 0x72, 0x65, 0x73, 0x65, 0x74, 0x77, 0x68, 0x65, 0x65, 0x6c, 0x67, 0x69, + 0x72, 0x6c, 0x73, 0x2f, 0x63, 0x73, 0x73, 0x2f, 0x31, 0x30, 0x30, 0x25, 0x3b, + 0x63, 0x6c, 0x75, 0x62, 0x73, 0x73, 0x74, 0x75, 0x66, 0x66, 0x62, 0x69, 0x62, + 0x6c, 0x65, 0x76, 0x6f, 0x74, 0x65, 0x73, 0x20, 0x31, 0x30, 0x30, 0x30, 0x6b, + 0x6f, 0x72, 0x65, 0x61, 0x7d, 0x29, 0x3b, 0x0d, 0x0a, 0x62, 0x61, 0x6e, 0x64, + 0x73, 0x71, 0x75, 0x65, 0x75, 0x65, 0x3d, 0x20, 0x7b, 0x7d, 0x3b, 0x38, 0x30, + 0x70, 0x78, 0x3b, 0x63, 0x6b, 0x69, 0x6e, 0x67, 0x7b, 0x0d, 0x0a, 0x09, 0x09, + 0x61, 0x68, 0x65, 0x61, 0x64, 0x63, 0x6c, 0x6f, 0x63, 0x6b, 0x69, 0x72, 0x69, + 0x73, 0x68, 0x6c, 0x69, 0x6b, 0x65, 0x20, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x73, + 0x74, 0x61, 0x74, 0x73, 0x46, 0x6f, 0x72, 0x6d, 0x22, 0x79, 0x61, 0x68, 0x6f, + 0x6f, 0x29, 0x5b, 0x30, 0x5d, 0x3b, 0x41, 0x62, 0x6f, 0x75, 0x74, 0x66, 0x69, + 0x6e, 0x64, 0x73, 0x3c, 0x2f, 0x68, 0x31, 0x3e, 0x64, 0x65, 0x62, 0x75, 0x67, + 0x74, 0x61, 0x73, 0x6b, 0x73, 0x55, 0x52, 0x4c, 0x20, 0x3d, 0x63, 0x65, 0x6c, + 0x6c, 0x73, 0x7d, 0x29, 0x28, 0x29, 0x3b, 0x31, 0x32, 0x70, 0x78, 0x3b, 0x70, + 0x72, 0x69, 0x6d, 0x65, 0x74, 0x65, 0x6c, 0x6c, 0x73, 0x74, 0x75, 0x72, 0x6e, + 0x73, 0x30, 0x78, 0x36, 0x30, 0x30, 0x2e, 0x6a, 0x70, 0x67, 0x22, 0x73, 0x70, + 0x61, 0x69, 0x6e, 0x62, 0x65, 0x61, 0x63, 0x68, 0x74, 0x61, 0x78, 0x65, 0x73, + 0x6d, 0x69, 0x63, 0x72, 0x6f, 0x61, 0x6e, 0x67, 0x65, 0x6c, 0x2d, 0x2d, 0x3e, + 0x3c, 0x2f, 0x67, 0x69, 0x66, 0x74, 0x73, 0x73, 0x74, 0x65, 0x76, 0x65, 0x2d, + 0x6c, 0x69, 0x6e, 0x6b, 0x62, 0x6f, 0x64, 0x79, 0x2e, 0x7d, 0x29, 0x3b, 0x0a, + 0x09, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x20, 0x28, 0x31, 0x39, 0x39, 0x46, 0x41, + 0x51, 0x3c, 0x2f, 0x72, 0x6f, 0x67, 0x65, 0x72, 0x66, 0x72, 0x61, 0x6e, 0x6b, + 0x43, 0x6c, 0x61, 0x73, 0x73, 0x32, 0x38, 0x70, 0x78, 0x3b, 0x66, 0x65, 0x65, + 0x64, 0x73, 0x3c, 0x68, 0x31, 0x3e, 0x3c, 0x73, 0x63, 0x6f, 0x74, 0x74, 0x74, + 0x65, 0x73, 0x74, 0x73, 0x32, 0x32, 0x70, 0x78, 0x3b, 0x64, 0x72, 0x69, 0x6e, + 0x6b, 0x29, 0x20, 0x7c, 0x7c, 0x20, 0x6c, 0x65, 0x77, 0x69, 0x73, 0x73, 0x68, + 0x61, 0x6c, 0x6c, 0x23, 0x30, 0x33, 0x39, 0x3b, 0x20, 0x66, 0x6f, 0x72, 0x20, + 0x6c, 0x6f, 0x76, 0x65, 0x64, 0x77, 0x61, 0x73, 0x74, 0x65, 0x30, 0x30, 0x70, + 0x78, 0x3b, 0x6a, 0x61, 0x3a, 0xe3, 0x82, 0x73, 0x69, 0x6d, 0x6f, 0x6e, 0x3c, + 0x66, 0x6f, 0x6e, 0x74, 0x72, 0x65, 0x70, 0x6c, 0x79, 0x6d, 0x65, 0x65, 0x74, + 0x73, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x63, 0x68, 0x65, 0x61, 0x70, 0x74, 0x69, + 0x67, 0x68, 0x74, 0x42, 0x72, 0x61, 0x6e, 0x64, 0x29, 0x20, 0x21, 0x3d, 0x20, + 0x64, 0x72, 0x65, 0x73, 0x73, 0x63, 0x6c, 0x69, 0x70, 0x73, 0x72, 0x6f, 0x6f, + 0x6d, 0x73, 0x6f, 0x6e, 0x6b, 0x65, 0x79, 0x6d, 0x6f, 0x62, 0x69, 0x6c, 0x6d, + 0x61, 0x69, 0x6e, 0x2e, 0x4e, 0x61, 0x6d, 0x65, 0x20, 0x70, 0x6c, 0x61, 0x74, + 0x65, 0x66, 0x75, 0x6e, 0x6e, 0x79, 0x74, 0x72, 0x65, 0x65, 0x73, 0x63, 0x6f, + 0x6d, 0x2f, 0x22, 0x31, 0x2e, 0x6a, 0x70, 0x67, 0x77, 0x6d, 0x6f, 0x64, 0x65, + 0x70, 0x61, 0x72, 0x61, 0x6d, 0x53, 0x54, 0x41, 0x52, 0x54, 0x6c, 0x65, 0x66, + 0x74, 0x20, 0x69, 0x64, 0x64, 0x65, 0x6e, 0x2c, 0x20, 0x32, 0x30, 0x31, 0x29, + 0x3b, 0x0a, 0x7d, 0x0a, 0x66, 0x6f, 0x72, 0x6d, 0x2e, 0x76, 0x69, 0x72, 0x75, + 0x73, 0x63, 0x68, 0x61, 0x69, 0x72, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x77, 0x6f, + 0x72, 0x73, 0x74, 0x50, 0x61, 0x67, 0x65, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, + 0x70, 0x61, 0x74, 0x63, 0x68, 0x3c, 0x21, 0x2d, 0x2d, 0x0a, 0x6f, 0x2d, 0x63, + 0x61, 0x63, 0x66, 0x69, 0x72, 0x6d, 0x73, 0x74, 0x6f, 0x75, 0x72, 0x73, 0x2c, + 0x30, 0x30, 0x30, 0x20, 0x61, 0x73, 0x69, 0x61, 0x6e, 0x69, 0x2b, 0x2b, 0x29, + 0x7b, 0x61, 0x64, 0x6f, 0x62, 0x65, 0x27, 0x29, 0x5b, 0x30, 0x5d, 0x69, 0x64, + 0x3d, 0x31, 0x30, 0x62, 0x6f, 0x74, 0x68, 0x3b, 0x6d, 0x65, 0x6e, 0x75, 0x20, + 0x2e, 0x32, 0x2e, 0x6d, 0x69, 0x2e, 0x70, 0x6e, 0x67, 0x22, 0x6b, 0x65, 0x76, + 0x69, 0x6e, 0x63, 0x6f, 0x61, 0x63, 0x68, 0x43, 0x68, 0x69, 0x6c, 0x64, 0x62, + 0x72, 0x75, 0x63, 0x65, 0x32, 0x2e, 0x6a, 0x70, 0x67, 0x55, 0x52, 0x4c, 0x29, + 0x2b, 0x2e, 0x6a, 0x70, 0x67, 0x7c, 0x73, 0x75, 0x69, 0x74, 0x65, 0x73, 0x6c, + 0x69, 0x63, 0x65, 0x68, 0x61, 0x72, 0x72, 0x79, 0x31, 0x32, 0x30, 0x22, 0x20, + 0x73, 0x77, 0x65, 0x65, 0x74, 0x74, 0x72, 0x3e, 0x0d, 0x0a, 0x6e, 0x61, 0x6d, + 0x65, 0x3d, 0x64, 0x69, 0x65, 0x67, 0x6f, 0x70, 0x61, 0x67, 0x65, 0x20, 0x73, + 0x77, 0x69, 0x73, 0x73, 0x2d, 0x2d, 0x3e, 0x0a, 0x0a, 0x23, 0x66, 0x66, 0x66, + 0x3b, 0x22, 0x3e, 0x4c, 0x6f, 0x67, 0x2e, 0x63, 0x6f, 0x6d, 0x22, 0x74, 0x72, + 0x65, 0x61, 0x74, 0x73, 0x68, 0x65, 0x65, 0x74, 0x29, 0x20, 0x26, 0x26, 0x20, + 0x31, 0x34, 0x70, 0x78, 0x3b, 0x73, 0x6c, 0x65, 0x65, 0x70, 0x6e, 0x74, 0x65, + 0x6e, 0x74, 0x66, 0x69, 0x6c, 0x65, 0x64, 0x6a, 0x61, 0x3a, 0xe3, 0x83, 0x69, + 0x64, 0x3d, 0x22, 0x63, 0x4e, 0x61, 0x6d, 0x65, 0x22, 0x77, 0x6f, 0x72, 0x73, + 0x65, 0x73, 0x68, 0x6f, 0x74, 0x73, 0x2d, 0x62, 0x6f, 0x78, 0x2d, 0x64, 0x65, + 0x6c, 0x74, 0x61, 0x0a, 0x26, 0x6c, 0x74, 0x3b, 0x62, 0x65, 0x61, 0x72, 0x73, + 0x3a, 0x34, 0x38, 0x5a, 0x3c, 0x64, 0x61, 0x74, 0x61, 0x2d, 0x72, 0x75, 0x72, + 0x61, 0x6c, 0x3c, 0x2f, 0x61, 0x3e, 0x20, 0x73, 0x70, 0x65, 0x6e, 0x64, 0x62, + 0x61, 0x6b, 0x65, 0x72, 0x73, 0x68, 0x6f, 0x70, 0x73, 0x3d, 0x20, 0x22, 0x22, + 0x3b, 0x70, 0x68, 0x70, 0x22, 0x3e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x31, 0x33, + 0x70, 0x78, 0x3b, 0x62, 0x72, 0x69, 0x61, 0x6e, 0x68, 0x65, 0x6c, 0x6c, 0x6f, + 0x73, 0x69, 0x7a, 0x65, 0x3d, 0x6f, 0x3d, 0x25, 0x32, 0x46, 0x20, 0x6a, 0x6f, + 0x69, 0x6e, 0x6d, 0x61, 0x79, 0x62, 0x65, 0x3c, 0x69, 0x6d, 0x67, 0x20, 0x69, + 0x6d, 0x67, 0x22, 0x3e, 0x2c, 0x20, 0x66, 0x6a, 0x73, 0x69, 0x6d, 0x67, 0x22, + 0x20, 0x22, 0x29, 0x5b, 0x30, 0x5d, 0x4d, 0x54, 0x6f, 0x70, 0x42, 0x54, 0x79, + 0x70, 0x65, 0x22, 0x6e, 0x65, 0x77, 0x6c, 0x79, 0x44, 0x61, 0x6e, 0x73, 0x6b, + 0x63, 0x7a, 0x65, 0x63, 0x68, 0x74, 0x72, 0x61, 0x69, 0x6c, 0x6b, 0x6e, 0x6f, + 0x77, 0x73, 0x3c, 0x2f, 0x68, 0x35, 0x3e, 0x66, 0x61, 0x71, 0x22, 0x3e, 0x7a, + 0x68, 0x2d, 0x63, 0x6e, 0x31, 0x30, 0x29, 0x3b, 0x0a, 0x2d, 0x31, 0x22, 0x29, + 0x3b, 0x74, 0x79, 0x70, 0x65, 0x3d, 0x62, 0x6c, 0x75, 0x65, 0x73, 0x74, 0x72, + 0x75, 0x6c, 0x79, 0x64, 0x61, 0x76, 0x69, 0x73, 0x2e, 0x6a, 0x73, 0x27, 0x3b, + 0x3e, 0x0d, 0x0a, 0x3c, 0x21, 0x73, 0x74, 0x65, 0x65, 0x6c, 0x20, 0x79, 0x6f, + 0x75, 0x20, 0x68, 0x32, 0x3e, 0x0d, 0x0a, 0x66, 0x6f, 0x72, 0x6d, 0x20, 0x6a, + 0x65, 0x73, 0x75, 0x73, 0x31, 0x30, 0x30, 0x25, 0x20, 0x6d, 0x65, 0x6e, 0x75, + 0x2e, 0x0d, 0x0a, 0x09, 0x0d, 0x0a, 0x77, 0x61, 0x6c, 0x65, 0x73, 0x72, 0x69, + 0x73, 0x6b, 0x73, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x64, 0x64, 0x69, 0x6e, 0x67, + 0x62, 0x2d, 0x6c, 0x69, 0x6b, 0x74, 0x65, 0x61, 0x63, 0x68, 0x67, 0x69, 0x66, + 0x22, 0x20, 0x76, 0x65, 0x67, 0x61, 0x73, 0x64, 0x61, 0x6e, 0x73, 0x6b, 0x65, + 0x65, 0x73, 0x74, 0x69, 0x73, 0x68, 0x71, 0x69, 0x70, 0x73, 0x75, 0x6f, 0x6d, + 0x69, 0x73, 0x6f, 0x62, 0x72, 0x65, 0x64, 0x65, 0x73, 0x64, 0x65, 0x65, 0x6e, + 0x74, 0x72, 0x65, 0x74, 0x6f, 0x64, 0x6f, 0x73, 0x70, 0x75, 0x65, 0x64, 0x65, + 0x61, 0xc3, 0xb1, 0x6f, 0x73, 0x65, 0x73, 0x74, 0xc3, 0xa1, 0x74, 0x69, 0x65, + 0x6e, 0x65, 0x68, 0x61, 0x73, 0x74, 0x61, 0x6f, 0x74, 0x72, 0x6f, 0x73, 0x70, + 0x61, 0x72, 0x74, 0x65, 0x64, 0x6f, 0x6e, 0x64, 0x65, 0x6e, 0x75, 0x65, 0x76, + 0x6f, 0x68, 0x61, 0x63, 0x65, 0x72, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x6d, 0x69, + 0x73, 0x6d, 0x6f, 0x6d, 0x65, 0x6a, 0x6f, 0x72, 0x6d, 0x75, 0x6e, 0x64, 0x6f, + 0x61, 0x71, 0x75, 0xc3, 0xad, 0x64, 0xc3, 0xad, 0x61, 0x73, 0x73, 0xc3, 0xb3, + 0x6c, 0x6f, 0x61, 0x79, 0x75, 0x64, 0x61, 0x66, 0x65, 0x63, 0x68, 0x61, 0x74, + 0x6f, 0x64, 0x61, 0x73, 0x74, 0x61, 0x6e, 0x74, 0x6f, 0x6d, 0x65, 0x6e, 0x6f, + 0x73, 0x64, 0x61, 0x74, 0x6f, 0x73, 0x6f, 0x74, 0x72, 0x61, 0x73, 0x73, 0x69, + 0x74, 0x69, 0x6f, 0x6d, 0x75, 0x63, 0x68, 0x6f, 0x61, 0x68, 0x6f, 0x72, 0x61, + 0x6c, 0x75, 0x67, 0x61, 0x72, 0x6d, 0x61, 0x79, 0x6f, 0x72, 0x65, 0x73, 0x74, + 0x6f, 0x73, 0x68, 0x6f, 0x72, 0x61, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x61, + 0x6e, 0x74, 0x65, 0x73, 0x66, 0x6f, 0x74, 0x6f, 0x73, 0x65, 0x73, 0x74, 0x61, + 0x73, 0x70, 0x61, 0xc3, 0xad, 0x73, 0x6e, 0x75, 0x65, 0x76, 0x61, 0x73, 0x61, + 0x6c, 0x75, 0x64, 0x66, 0x6f, 0x72, 0x6f, 0x73, 0x6d, 0x65, 0x64, 0x69, 0x6f, + 0x71, 0x75, 0x69, 0x65, 0x6e, 0x6d, 0x65, 0x73, 0x65, 0x73, 0x70, 0x6f, 0x64, + 0x65, 0x72, 0x63, 0x68, 0x69, 0x6c, 0x65, 0x73, 0x65, 0x72, 0xc3, 0xa1, 0x76, + 0x65, 0x63, 0x65, 0x73, 0x64, 0x65, 0x63, 0x69, 0x72, 0x6a, 0x6f, 0x73, 0xc3, + 0xa9, 0x65, 0x73, 0x74, 0x61, 0x72, 0x76, 0x65, 0x6e, 0x74, 0x61, 0x67, 0x72, + 0x75, 0x70, 0x6f, 0x68, 0x65, 0x63, 0x68, 0x6f, 0x65, 0x6c, 0x6c, 0x6f, 0x73, + 0x74, 0x65, 0x6e, 0x67, 0x6f, 0x61, 0x6d, 0x69, 0x67, 0x6f, 0x63, 0x6f, 0x73, + 0x61, 0x73, 0x6e, 0x69, 0x76, 0x65, 0x6c, 0x67, 0x65, 0x6e, 0x74, 0x65, 0x6d, + 0x69, 0x73, 0x6d, 0x61, 0x61, 0x69, 0x72, 0x65, 0x73, 0x6a, 0x75, 0x6c, 0x69, + 0x6f, 0x74, 0x65, 0x6d, 0x61, 0x73, 0x68, 0x61, 0x63, 0x69, 0x61, 0x66, 0x61, + 0x76, 0x6f, 0x72, 0x6a, 0x75, 0x6e, 0x69, 0x6f, 0x6c, 0x69, 0x62, 0x72, 0x65, + 0x70, 0x75, 0x6e, 0x74, 0x6f, 0x62, 0x75, 0x65, 0x6e, 0x6f, 0x61, 0x75, 0x74, + 0x6f, 0x72, 0x61, 0x62, 0x72, 0x69, 0x6c, 0x62, 0x75, 0x65, 0x6e, 0x61, 0x74, + 0x65, 0x78, 0x74, 0x6f, 0x6d, 0x61, 0x72, 0x7a, 0x6f, 0x73, 0x61, 0x62, 0x65, + 0x72, 0x6c, 0x69, 0x73, 0x74, 0x61, 0x6c, 0x75, 0x65, 0x67, 0x6f, 0x63, 0xc3, + 0xb3, 0x6d, 0x6f, 0x65, 0x6e, 0x65, 0x72, 0x6f, 0x6a, 0x75, 0x65, 0x67, 0x6f, + 0x70, 0x65, 0x72, 0xc3, 0xba, 0x68, 0x61, 0x62, 0x65, 0x72, 0x65, 0x73, 0x74, + 0x6f, 0x79, 0x6e, 0x75, 0x6e, 0x63, 0x61, 0x6d, 0x75, 0x6a, 0x65, 0x72, 0x76, + 0x61, 0x6c, 0x6f, 0x72, 0x66, 0x75, 0x65, 0x72, 0x61, 0x6c, 0x69, 0x62, 0x72, + 0x6f, 0x67, 0x75, 0x73, 0x74, 0x61, 0x69, 0x67, 0x75, 0x61, 0x6c, 0x76, 0x6f, + 0x74, 0x6f, 0x73, 0x63, 0x61, 0x73, 0x6f, 0x73, 0x67, 0x75, 0xc3, 0xad, 0x61, + 0x70, 0x75, 0x65, 0x64, 0x6f, 0x73, 0x6f, 0x6d, 0x6f, 0x73, 0x61, 0x76, 0x69, + 0x73, 0x6f, 0x75, 0x73, 0x74, 0x65, 0x64, 0x64, 0x65, 0x62, 0x65, 0x6e, 0x6e, + 0x6f, 0x63, 0x68, 0x65, 0x62, 0x75, 0x73, 0x63, 0x61, 0x66, 0x61, 0x6c, 0x74, + 0x61, 0x65, 0x75, 0x72, 0x6f, 0x73, 0x73, 0x65, 0x72, 0x69, 0x65, 0x64, 0x69, + 0x63, 0x68, 0x6f, 0x63, 0x75, 0x72, 0x73, 0x6f, 0x63, 0x6c, 0x61, 0x76, 0x65, + 0x63, 0x61, 0x73, 0x61, 0x73, 0x6c, 0x65, 0xc3, 0xb3, 0x6e, 0x70, 0x6c, 0x61, + 0x7a, 0x6f, 0x6c, 0x61, 0x72, 0x67, 0x6f, 0x6f, 0x62, 0x72, 0x61, 0x73, 0x76, + 0x69, 0x73, 0x74, 0x61, 0x61, 0x70, 0x6f, 0x79, 0x6f, 0x6a, 0x75, 0x6e, 0x74, + 0x6f, 0x74, 0x72, 0x61, 0x74, 0x61, 0x76, 0x69, 0x73, 0x74, 0x6f, 0x63, 0x72, + 0x65, 0x61, 0x72, 0x63, 0x61, 0x6d, 0x70, 0x6f, 0x68, 0x65, 0x6d, 0x6f, 0x73, + 0x63, 0x69, 0x6e, 0x63, 0x6f, 0x63, 0x61, 0x72, 0x67, 0x6f, 0x70, 0x69, 0x73, + 0x6f, 0x73, 0x6f, 0x72, 0x64, 0x65, 0x6e, 0x68, 0x61, 0x63, 0x65, 0x6e, 0xc3, + 0xa1, 0x72, 0x65, 0x61, 0x64, 0x69, 0x73, 0x63, 0x6f, 0x70, 0x65, 0x64, 0x72, + 0x6f, 0x63, 0x65, 0x72, 0x63, 0x61, 0x70, 0x75, 0x65, 0x64, 0x61, 0x70, 0x61, + 0x70, 0x65, 0x6c, 0x6d, 0x65, 0x6e, 0x6f, 0x72, 0xc3, 0xba, 0x74, 0x69, 0x6c, + 0x63, 0x6c, 0x61, 0x72, 0x6f, 0x6a, 0x6f, 0x72, 0x67, 0x65, 0x63, 0x61, 0x6c, + 0x6c, 0x65, 0x70, 0x6f, 0x6e, 0x65, 0x72, 0x74, 0x61, 0x72, 0x64, 0x65, 0x6e, + 0x61, 0x64, 0x69, 0x65, 0x6d, 0x61, 0x72, 0x63, 0x61, 0x73, 0x69, 0x67, 0x75, + 0x65, 0x65, 0x6c, 0x6c, 0x61, 0x73, 0x73, 0x69, 0x67, 0x6c, 0x6f, 0x63, 0x6f, + 0x63, 0x68, 0x65, 0x6d, 0x6f, 0x74, 0x6f, 0x73, 0x6d, 0x61, 0x64, 0x72, 0x65, + 0x63, 0x6c, 0x61, 0x73, 0x65, 0x72, 0x65, 0x73, 0x74, 0x6f, 0x6e, 0x69, 0xc3, + 0xb1, 0x6f, 0x71, 0x75, 0x65, 0x64, 0x61, 0x70, 0x61, 0x73, 0x61, 0x72, 0x62, + 0x61, 0x6e, 0x63, 0x6f, 0x68, 0x69, 0x6a, 0x6f, 0x73, 0x76, 0x69, 0x61, 0x6a, + 0x65, 0x70, 0x61, 0x62, 0x6c, 0x6f, 0xc3, 0xa9, 0x73, 0x74, 0x65, 0x76, 0x69, + 0x65, 0x6e, 0x65, 0x72, 0x65, 0x69, 0x6e, 0x6f, 0x64, 0x65, 0x6a, 0x61, 0x72, + 0x66, 0x6f, 0x6e, 0x64, 0x6f, 0x63, 0x61, 0x6e, 0x61, 0x6c, 0x6e, 0x6f, 0x72, + 0x74, 0x65, 0x6c, 0x65, 0x74, 0x72, 0x61, 0x63, 0x61, 0x75, 0x73, 0x61, 0x74, + 0x6f, 0x6d, 0x61, 0x72, 0x6d, 0x61, 0x6e, 0x6f, 0x73, 0x6c, 0x75, 0x6e, 0x65, + 0x73, 0x61, 0x75, 0x74, 0x6f, 0x73, 0x76, 0x69, 0x6c, 0x6c, 0x61, 0x76, 0x65, + 0x6e, 0x64, 0x6f, 0x70, 0x65, 0x73, 0x61, 0x72, 0x74, 0x69, 0x70, 0x6f, 0x73, + 0x74, 0x65, 0x6e, 0x67, 0x61, 0x6d, 0x61, 0x72, 0x63, 0x6f, 0x6c, 0x6c, 0x65, + 0x76, 0x61, 0x70, 0x61, 0x64, 0x72, 0x65, 0x75, 0x6e, 0x69, 0x64, 0x6f, 0x76, + 0x61, 0x6d, 0x6f, 0x73, 0x7a, 0x6f, 0x6e, 0x61, 0x73, 0x61, 0x6d, 0x62, 0x6f, + 0x73, 0x62, 0x61, 0x6e, 0x64, 0x61, 0x6d, 0x61, 0x72, 0x69, 0x61, 0x61, 0x62, + 0x75, 0x73, 0x6f, 0x6d, 0x75, 0x63, 0x68, 0x61, 0x73, 0x75, 0x62, 0x69, 0x72, + 0x72, 0x69, 0x6f, 0x6a, 0x61, 0x76, 0x69, 0x76, 0x69, 0x72, 0x67, 0x72, 0x61, + 0x64, 0x6f, 0x63, 0x68, 0x69, 0x63, 0x61, 0x61, 0x6c, 0x6c, 0xc3, 0xad, 0x6a, + 0x6f, 0x76, 0x65, 0x6e, 0x64, 0x69, 0x63, 0x68, 0x61, 0x65, 0x73, 0x74, 0x61, + 0x6e, 0x74, 0x61, 0x6c, 0x65, 0x73, 0x73, 0x61, 0x6c, 0x69, 0x72, 0x73, 0x75, + 0x65, 0x6c, 0x6f, 0x70, 0x65, 0x73, 0x6f, 0x73, 0x66, 0x69, 0x6e, 0x65, 0x73, + 0x6c, 0x6c, 0x61, 0x6d, 0x61, 0x62, 0x75, 0x73, 0x63, 0x6f, 0xc3, 0xa9, 0x73, + 0x74, 0x61, 0x6c, 0x6c, 0x65, 0x67, 0x61, 0x6e, 0x65, 0x67, 0x72, 0x6f, 0x70, + 0x6c, 0x61, 0x7a, 0x61, 0x68, 0x75, 0x6d, 0x6f, 0x72, 0x70, 0x61, 0x67, 0x61, + 0x72, 0x6a, 0x75, 0x6e, 0x74, 0x61, 0x64, 0x6f, 0x62, 0x6c, 0x65, 0x69, 0x73, + 0x6c, 0x61, 0x73, 0x62, 0x6f, 0x6c, 0x73, 0x61, 0x62, 0x61, 0xc3, 0xb1, 0x6f, + 0x68, 0x61, 0x62, 0x6c, 0x61, 0x6c, 0x75, 0x63, 0x68, 0x61, 0xc3, 0x81, 0x72, + 0x65, 0x61, 0x64, 0x69, 0x63, 0x65, 0x6e, 0x6a, 0x75, 0x67, 0x61, 0x72, 0x6e, + 0x6f, 0x74, 0x61, 0x73, 0x76, 0x61, 0x6c, 0x6c, 0x65, 0x61, 0x6c, 0x6c, 0xc3, + 0xa1, 0x63, 0x61, 0x72, 0x67, 0x61, 0x64, 0x6f, 0x6c, 0x6f, 0x72, 0x61, 0x62, + 0x61, 0x6a, 0x6f, 0x65, 0x73, 0x74, 0xc3, 0xa9, 0x67, 0x75, 0x73, 0x74, 0x6f, + 0x6d, 0x65, 0x6e, 0x74, 0x65, 0x6d, 0x61, 0x72, 0x69, 0x6f, 0x66, 0x69, 0x72, + 0x6d, 0x61, 0x63, 0x6f, 0x73, 0x74, 0x6f, 0x66, 0x69, 0x63, 0x68, 0x61, 0x70, + 0x6c, 0x61, 0x74, 0x61, 0x68, 0x6f, 0x67, 0x61, 0x72, 0x61, 0x72, 0x74, 0x65, + 0x73, 0x6c, 0x65, 0x79, 0x65, 0x73, 0x61, 0x71, 0x75, 0x65, 0x6c, 0x6d, 0x75, + 0x73, 0x65, 0x6f, 0x62, 0x61, 0x73, 0x65, 0x73, 0x70, 0x6f, 0x63, 0x6f, 0x73, + 0x6d, 0x69, 0x74, 0x61, 0x64, 0x63, 0x69, 0x65, 0x6c, 0x6f, 0x63, 0x68, 0x69, + 0x63, 0x6f, 0x6d, 0x69, 0x65, 0x64, 0x6f, 0x67, 0x61, 0x6e, 0x61, 0x72, 0x73, + 0x61, 0x6e, 0x74, 0x6f, 0x65, 0x74, 0x61, 0x70, 0x61, 0x64, 0x65, 0x62, 0x65, + 0x73, 0x70, 0x6c, 0x61, 0x79, 0x61, 0x72, 0x65, 0x64, 0x65, 0x73, 0x73, 0x69, + 0x65, 0x74, 0x65, 0x63, 0x6f, 0x72, 0x74, 0x65, 0x63, 0x6f, 0x72, 0x65, 0x61, + 0x64, 0x75, 0x64, 0x61, 0x73, 0x64, 0x65, 0x73, 0x65, 0x6f, 0x76, 0x69, 0x65, + 0x6a, 0x6f, 0x64, 0x65, 0x73, 0x65, 0x61, 0x61, 0x67, 0x75, 0x61, 0x73, 0x26, + 0x71, 0x75, 0x6f, 0x74, 0x3b, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x63, 0x6f, + 0x6d, 0x6d, 0x6f, 0x6e, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x65, 0x76, 0x65, + 0x6e, 0x74, 0x73, 0x6d, 0x61, 0x73, 0x74, 0x65, 0x72, 0x73, 0x79, 0x73, 0x74, + 0x65, 0x6d, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x62, 0x61, 0x6e, 0x6e, 0x65, + 0x72, 0x72, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x73, 0x63, 0x72, 0x6f, 0x6c, 0x6c, + 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x6d, + 0x65, 0x64, 0x69, 0x75, 0x6d, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x6e, 0x75, + 0x6d, 0x62, 0x65, 0x72, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x72, 0x65, 0x73, + 0x75, 0x6c, 0x74, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x73, 0x63, 0x72, 0x65, + 0x65, 0x6e, 0x63, 0x68, 0x6f, 0x6f, 0x73, 0x65, 0x6e, 0x6f, 0x72, 0x6d, 0x61, + 0x6c, 0x74, 0x72, 0x61, 0x76, 0x65, 0x6c, 0x69, 0x73, 0x73, 0x75, 0x65, 0x73, + 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x73, + 0x70, 0x72, 0x69, 0x6e, 0x67, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x6d, 0x6f, + 0x62, 0x69, 0x6c, 0x65, 0x73, 0x77, 0x69, 0x74, 0x63, 0x68, 0x70, 0x68, 0x6f, + 0x74, 0x6f, 0x73, 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x72, 0x65, 0x67, 0x69, + 0x6f, 0x6e, 0x69, 0x74, 0x73, 0x65, 0x6c, 0x66, 0x73, 0x6f, 0x63, 0x69, 0x61, + 0x6c, 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, 0x63, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, + 0x72, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x66, 0x6f, 0x6c, 0x6c, 0x6f, 0x77, 0x74, + 0x69, 0x74, 0x6c, 0x65, 0x3e, 0x65, 0x69, 0x74, 0x68, 0x65, 0x72, 0x6c, 0x65, + 0x6e, 0x67, 0x74, 0x68, 0x66, 0x61, 0x6d, 0x69, 0x6c, 0x79, 0x66, 0x72, 0x69, + 0x65, 0x6e, 0x64, 0x6c, 0x61, 0x79, 0x6f, 0x75, 0x74, 0x61, 0x75, 0x74, 0x68, + 0x6f, 0x72, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x72, 0x65, 0x76, 0x69, 0x65, + 0x77, 0x73, 0x75, 0x6d, 0x6d, 0x65, 0x72, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, + 0x70, 0x6c, 0x61, 0x79, 0x65, 0x64, 0x70, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x65, + 0x78, 0x70, 0x61, 0x6e, 0x64, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x66, 0x6f, + 0x72, 0x6d, 0x61, 0x74, 0x64, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x70, 0x6f, 0x69, + 0x6e, 0x74, 0x73, 0x73, 0x65, 0x72, 0x69, 0x65, 0x73, 0x70, 0x65, 0x72, 0x73, + 0x6f, 0x6e, 0x6c, 0x69, 0x76, 0x69, 0x6e, 0x67, 0x64, 0x65, 0x73, 0x69, 0x67, + 0x6e, 0x6d, 0x6f, 0x6e, 0x74, 0x68, 0x73, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x73, + 0x75, 0x6e, 0x69, 0x71, 0x75, 0x65, 0x77, 0x65, 0x69, 0x67, 0x68, 0x74, 0x70, + 0x65, 0x6f, 0x70, 0x6c, 0x65, 0x65, 0x6e, 0x65, 0x72, 0x67, 0x79, 0x6e, 0x61, + 0x74, 0x75, 0x72, 0x65, 0x73, 0x65, 0x61, 0x72, 0x63, 0x68, 0x66, 0x69, 0x67, + 0x75, 0x72, 0x65, 0x68, 0x61, 0x76, 0x69, 0x6e, 0x67, 0x63, 0x75, 0x73, 0x74, + 0x6f, 0x6d, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x6c, 0x65, 0x74, 0x74, 0x65, + 0x72, 0x77, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x73, 0x75, 0x62, 0x6d, 0x69, 0x74, + 0x72, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x75, + 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x68, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x6d, 0x65, + 0x74, 0x68, 0x6f, 0x64, 0x76, 0x69, 0x64, 0x65, 0x6f, 0x73, 0x73, 0x63, 0x68, + 0x6f, 0x6f, 0x6c, 0x66, 0x75, 0x74, 0x75, 0x72, 0x65, 0x73, 0x68, 0x61, 0x64, + 0x6f, 0x77, 0x64, 0x65, 0x62, 0x61, 0x74, 0x65, 0x76, 0x61, 0x6c, 0x75, 0x65, + 0x73, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x6f, 0x74, 0x68, 0x65, 0x72, 0x73, + 0x72, 0x69, 0x67, 0x68, 0x74, 0x73, 0x6c, 0x65, 0x61, 0x67, 0x75, 0x65, 0x63, + 0x68, 0x72, 0x6f, 0x6d, 0x65, 0x73, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x6e, 0x6f, + 0x74, 0x69, 0x63, 0x65, 0x73, 0x68, 0x61, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x64, + 0x69, 0x6e, 0x67, 0x73, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x72, 0x65, 0x70, 0x6f, + 0x72, 0x74, 0x6f, 0x6e, 0x6c, 0x69, 0x6e, 0x65, 0x73, 0x71, 0x75, 0x61, 0x72, + 0x65, 0x62, 0x75, 0x74, 0x74, 0x6f, 0x6e, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x73, + 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x6d, 0x6f, 0x76, 0x69, 0x6e, 0x67, 0x6c, + 0x61, 0x74, 0x65, 0x73, 0x74, 0x77, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x46, 0x72, + 0x61, 0x6e, 0x63, 0x65, 0x70, 0x65, 0x72, 0x69, 0x6f, 0x64, 0x73, 0x74, 0x72, + 0x6f, 0x6e, 0x67, 0x72, 0x65, 0x70, 0x65, 0x61, 0x74, 0x4c, 0x6f, 0x6e, 0x64, + 0x6f, 0x6e, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x66, 0x6f, 0x72, 0x6d, 0x65, + 0x64, 0x64, 0x65, 0x6d, 0x61, 0x6e, 0x64, 0x73, 0x65, 0x63, 0x75, 0x72, 0x65, + 0x70, 0x61, 0x73, 0x73, 0x65, 0x64, 0x74, 0x6f, 0x67, 0x67, 0x6c, 0x65, 0x70, + 0x6c, 0x61, 0x63, 0x65, 0x73, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x73, 0x74, + 0x61, 0x74, 0x69, 0x63, 0x63, 0x69, 0x74, 0x69, 0x65, 0x73, 0x73, 0x74, 0x72, + 0x65, 0x61, 0x6d, 0x79, 0x65, 0x6c, 0x6c, 0x6f, 0x77, 0x61, 0x74, 0x74, 0x61, + 0x63, 0x6b, 0x73, 0x74, 0x72, 0x65, 0x65, 0x74, 0x66, 0x6c, 0x69, 0x67, 0x68, + 0x74, 0x68, 0x69, 0x64, 0x64, 0x65, 0x6e, 0x69, 0x6e, 0x66, 0x6f, 0x22, 0x3e, + 0x6f, 0x70, 0x65, 0x6e, 0x65, 0x64, 0x75, 0x73, 0x65, 0x66, 0x75, 0x6c, 0x76, + 0x61, 0x6c, 0x6c, 0x65, 0x79, 0x63, 0x61, 0x75, 0x73, 0x65, 0x73, 0x6c, 0x65, + 0x61, 0x64, 0x65, 0x72, 0x73, 0x65, 0x63, 0x72, 0x65, 0x74, 0x73, 0x65, 0x63, + 0x6f, 0x6e, 0x64, 0x64, 0x61, 0x6d, 0x61, 0x67, 0x65, 0x73, 0x70, 0x6f, 0x72, + 0x74, 0x73, 0x65, 0x78, 0x63, 0x65, 0x70, 0x74, 0x72, 0x61, 0x74, 0x69, 0x6e, + 0x67, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x74, 0x68, 0x69, 0x6e, 0x67, 0x73, + 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x73, + 0x74, 0x61, 0x74, 0x65, 0x73, 0x6f, 0x66, 0x66, 0x69, 0x63, 0x65, 0x76, 0x69, + 0x73, 0x75, 0x61, 0x6c, 0x65, 0x64, 0x69, 0x74, 0x6f, 0x72, 0x76, 0x6f, 0x6c, + 0x75, 0x6d, 0x65, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x6d, 0x75, 0x73, 0x65, + 0x75, 0x6d, 0x6d, 0x6f, 0x76, 0x69, 0x65, 0x73, 0x70, 0x61, 0x72, 0x65, 0x6e, + 0x74, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x6d, 0x6f, 0x73, 0x74, 0x6c, 0x79, + 0x6d, 0x6f, 0x74, 0x68, 0x65, 0x72, 0x22, 0x20, 0x69, 0x64, 0x3d, 0x22, 0x6d, + 0x61, 0x72, 0x6b, 0x65, 0x74, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x63, 0x68, + 0x61, 0x6e, 0x63, 0x65, 0x73, 0x75, 0x72, 0x76, 0x65, 0x79, 0x62, 0x65, 0x66, + 0x6f, 0x72, 0x65, 0x73, 0x79, 0x6d, 0x62, 0x6f, 0x6c, 0x6d, 0x6f, 0x6d, 0x65, + 0x6e, 0x74, 0x73, 0x70, 0x65, 0x65, 0x63, 0x68, 0x6d, 0x6f, 0x74, 0x69, 0x6f, + 0x6e, 0x69, 0x6e, 0x73, 0x69, 0x64, 0x65, 0x6d, 0x61, 0x74, 0x74, 0x65, 0x72, + 0x43, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x65, + 0x78, 0x69, 0x73, 0x74, 0x73, 0x6d, 0x69, 0x64, 0x64, 0x6c, 0x65, 0x45, 0x75, + 0x72, 0x6f, 0x70, 0x65, 0x67, 0x72, 0x6f, 0x77, 0x74, 0x68, 0x6c, 0x65, 0x67, + 0x61, 0x63, 0x79, 0x6d, 0x61, 0x6e, 0x6e, 0x65, 0x72, 0x65, 0x6e, 0x6f, 0x75, + 0x67, 0x68, 0x63, 0x61, 0x72, 0x65, 0x65, 0x72, 0x61, 0x6e, 0x73, 0x77, 0x65, + 0x72, 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x70, 0x6f, 0x72, 0x74, 0x61, 0x6c, + 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x72, + 0x61, 0x6e, 0x64, 0x6f, 0x6d, 0x63, 0x6c, 0x6f, 0x73, 0x65, 0x64, 0x74, 0x6f, + 0x70, 0x69, 0x63, 0x73, 0x63, 0x6f, 0x6d, 0x69, 0x6e, 0x67, 0x66, 0x61, 0x74, + 0x68, 0x65, 0x72, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x69, 0x6d, 0x70, + 0x6c, 0x79, 0x72, 0x61, 0x69, 0x73, 0x65, 0x64, 0x65, 0x73, 0x63, 0x61, 0x70, + 0x65, 0x63, 0x68, 0x6f, 0x73, 0x65, 0x6e, 0x63, 0x68, 0x75, 0x72, 0x63, 0x68, + 0x64, 0x65, 0x66, 0x69, 0x6e, 0x65, 0x72, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x63, + 0x6f, 0x72, 0x6e, 0x65, 0x72, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x6d, 0x65, + 0x6d, 0x6f, 0x72, 0x79, 0x69, 0x66, 0x72, 0x61, 0x6d, 0x65, 0x70, 0x6f, 0x6c, + 0x69, 0x63, 0x65, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x73, 0x4e, 0x75, 0x6d, 0x62, + 0x65, 0x72, 0x64, 0x75, 0x72, 0x69, 0x6e, 0x67, 0x6f, 0x66, 0x66, 0x65, 0x72, + 0x73, 0x73, 0x74, 0x79, 0x6c, 0x65, 0x73, 0x6b, 0x69, 0x6c, 0x6c, 0x65, 0x64, + 0x6c, 0x69, 0x73, 0x74, 0x65, 0x64, 0x63, 0x61, 0x6c, 0x6c, 0x65, 0x64, 0x73, + 0x69, 0x6c, 0x76, 0x65, 0x72, 0x6d, 0x61, 0x72, 0x67, 0x69, 0x6e, 0x64, 0x65, + 0x6c, 0x65, 0x74, 0x65, 0x62, 0x65, 0x74, 0x74, 0x65, 0x72, 0x62, 0x72, 0x6f, + 0x77, 0x73, 0x65, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x73, 0x47, 0x6c, 0x6f, 0x62, + 0x61, 0x6c, 0x73, 0x69, 0x6e, 0x67, 0x6c, 0x65, 0x77, 0x69, 0x64, 0x67, 0x65, + 0x74, 0x63, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x62, 0x75, 0x64, 0x67, 0x65, 0x74, + 0x6e, 0x6f, 0x77, 0x72, 0x61, 0x70, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x63, + 0x6c, 0x61, 0x69, 0x6d, 0x73, 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x73, 0x61, + 0x66, 0x65, 0x74, 0x79, 0x63, 0x68, 0x6f, 0x69, 0x63, 0x65, 0x73, 0x70, 0x69, + 0x72, 0x69, 0x74, 0x2d, 0x73, 0x74, 0x79, 0x6c, 0x65, 0x73, 0x70, 0x72, 0x65, + 0x61, 0x64, 0x6d, 0x61, 0x6b, 0x69, 0x6e, 0x67, 0x6e, 0x65, 0x65, 0x64, 0x65, + 0x64, 0x72, 0x75, 0x73, 0x73, 0x69, 0x61, 0x70, 0x6c, 0x65, 0x61, 0x73, 0x65, + 0x65, 0x78, 0x74, 0x65, 0x6e, 0x74, 0x53, 0x63, 0x72, 0x69, 0x70, 0x74, 0x62, + 0x72, 0x6f, 0x6b, 0x65, 0x6e, 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x73, 0x63, 0x68, + 0x61, 0x72, 0x67, 0x65, 0x64, 0x69, 0x76, 0x69, 0x64, 0x65, 0x66, 0x61, 0x63, + 0x74, 0x6f, 0x72, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x2d, 0x62, 0x61, 0x73, + 0x65, 0x64, 0x74, 0x68, 0x65, 0x6f, 0x72, 0x79, 0x63, 0x6f, 0x6e, 0x66, 0x69, + 0x67, 0x61, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x77, 0x6f, 0x72, 0x6b, 0x65, 0x64, + 0x68, 0x65, 0x6c, 0x70, 0x65, 0x64, 0x43, 0x68, 0x75, 0x72, 0x63, 0x68, 0x69, + 0x6d, 0x70, 0x61, 0x63, 0x74, 0x73, 0x68, 0x6f, 0x75, 0x6c, 0x64, 0x61, 0x6c, + 0x77, 0x61, 0x79, 0x73, 0x6c, 0x6f, 0x67, 0x6f, 0x22, 0x20, 0x62, 0x6f, 0x74, + 0x74, 0x6f, 0x6d, 0x6c, 0x69, 0x73, 0x74, 0x22, 0x3e, 0x29, 0x7b, 0x76, 0x61, + 0x72, 0x20, 0x70, 0x72, 0x65, 0x66, 0x69, 0x78, 0x6f, 0x72, 0x61, 0x6e, 0x67, + 0x65, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x2e, 0x70, 0x75, 0x73, 0x68, 0x28, + 0x63, 0x6f, 0x75, 0x70, 0x6c, 0x65, 0x67, 0x61, 0x72, 0x64, 0x65, 0x6e, 0x62, + 0x72, 0x69, 0x64, 0x67, 0x65, 0x6c, 0x61, 0x75, 0x6e, 0x63, 0x68, 0x52, 0x65, + 0x76, 0x69, 0x65, 0x77, 0x74, 0x61, 0x6b, 0x69, 0x6e, 0x67, 0x76, 0x69, 0x73, + 0x69, 0x6f, 0x6e, 0x6c, 0x69, 0x74, 0x74, 0x6c, 0x65, 0x64, 0x61, 0x74, 0x69, + 0x6e, 0x67, 0x42, 0x75, 0x74, 0x74, 0x6f, 0x6e, 0x62, 0x65, 0x61, 0x75, 0x74, + 0x79, 0x74, 0x68, 0x65, 0x6d, 0x65, 0x73, 0x66, 0x6f, 0x72, 0x67, 0x6f, 0x74, + 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x61, 0x6e, 0x63, 0x68, 0x6f, 0x72, 0x61, + 0x6c, 0x6d, 0x6f, 0x73, 0x74, 0x6c, 0x6f, 0x61, 0x64, 0x65, 0x64, 0x43, 0x68, + 0x61, 0x6e, 0x67, 0x65, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x73, 0x74, 0x72, + 0x69, 0x6e, 0x67, 0x72, 0x65, 0x6c, 0x6f, 0x61, 0x64, 0x4d, 0x6f, 0x62, 0x69, + 0x6c, 0x65, 0x69, 0x6e, 0x63, 0x6f, 0x6d, 0x65, 0x73, 0x75, 0x70, 0x70, 0x6c, + 0x79, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x73, + 0x76, 0x69, 0x65, 0x77, 0x65, 0x64, 0x26, 0x6e, 0x62, 0x73, 0x70, 0x3b, 0x63, + 0x6f, 0x75, 0x72, 0x73, 0x65, 0x41, 0x62, 0x6f, 0x75, 0x74, 0x20, 0x69, 0x73, + 0x6c, 0x61, 0x6e, 0x64, 0x3c, 0x68, 0x74, 0x6d, 0x6c, 0x20, 0x63, 0x6f, 0x6f, + 0x6b, 0x69, 0x65, 0x6e, 0x61, 0x6d, 0x65, 0x3d, 0x22, 0x61, 0x6d, 0x61, 0x7a, + 0x6f, 0x6e, 0x6d, 0x6f, 0x64, 0x65, 0x72, 0x6e, 0x61, 0x64, 0x76, 0x69, 0x63, + 0x65, 0x69, 0x6e, 0x3c, 0x2f, 0x61, 0x3e, 0x3a, 0x20, 0x54, 0x68, 0x65, 0x20, + 0x64, 0x69, 0x61, 0x6c, 0x6f, 0x67, 0x68, 0x6f, 0x75, 0x73, 0x65, 0x73, 0x42, + 0x45, 0x47, 0x49, 0x4e, 0x20, 0x4d, 0x65, 0x78, 0x69, 0x63, 0x6f, 0x73, 0x74, + 0x61, 0x72, 0x74, 0x73, 0x63, 0x65, 0x6e, 0x74, 0x72, 0x65, 0x68, 0x65, 0x69, + 0x67, 0x68, 0x74, 0x61, 0x64, 0x64, 0x69, 0x6e, 0x67, 0x49, 0x73, 0x6c, 0x61, + 0x6e, 0x64, 0x61, 0x73, 0x73, 0x65, 0x74, 0x73, 0x45, 0x6d, 0x70, 0x69, 0x72, + 0x65, 0x53, 0x63, 0x68, 0x6f, 0x6f, 0x6c, 0x65, 0x66, 0x66, 0x6f, 0x72, 0x74, + 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6e, 0x65, 0x61, 0x72, 0x6c, 0x79, 0x6d, + 0x61, 0x6e, 0x75, 0x61, 0x6c, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x2e, 0x0a, + 0x0a, 0x4f, 0x6e, 0x65, 0x6a, 0x6f, 0x69, 0x6e, 0x65, 0x64, 0x6d, 0x65, 0x6e, + 0x75, 0x22, 0x3e, 0x50, 0x68, 0x69, 0x6c, 0x69, 0x70, 0x61, 0x77, 0x61, 0x72, + 0x64, 0x73, 0x68, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x69, 0x6d, 0x70, 0x6f, 0x72, + 0x74, 0x4f, 0x66, 0x66, 0x69, 0x63, 0x65, 0x72, 0x65, 0x67, 0x61, 0x72, 0x64, + 0x73, 0x6b, 0x69, 0x6c, 0x6c, 0x73, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, + 0x70, 0x6f, 0x72, 0x74, 0x73, 0x64, 0x65, 0x67, 0x72, 0x65, 0x65, 0x77, 0x65, + 0x65, 0x6b, 0x6c, 0x79, 0x20, 0x28, 0x65, 0x2e, 0x67, 0x2e, 0x62, 0x65, 0x68, + 0x69, 0x6e, 0x64, 0x64, 0x6f, 0x63, 0x74, 0x6f, 0x72, 0x6c, 0x6f, 0x67, 0x67, + 0x65, 0x64, 0x75, 0x6e, 0x69, 0x74, 0x65, 0x64, 0x3c, 0x2f, 0x62, 0x3e, 0x3c, + 0x2f, 0x62, 0x65, 0x67, 0x69, 0x6e, 0x73, 0x70, 0x6c, 0x61, 0x6e, 0x74, 0x73, + 0x61, 0x73, 0x73, 0x69, 0x73, 0x74, 0x61, 0x72, 0x74, 0x69, 0x73, 0x74, 0x69, + 0x73, 0x73, 0x75, 0x65, 0x64, 0x33, 0x30, 0x30, 0x70, 0x78, 0x7c, 0x63, 0x61, + 0x6e, 0x61, 0x64, 0x61, 0x61, 0x67, 0x65, 0x6e, 0x63, 0x79, 0x73, 0x63, 0x68, + 0x65, 0x6d, 0x65, 0x72, 0x65, 0x6d, 0x61, 0x69, 0x6e, 0x42, 0x72, 0x61, 0x7a, + 0x69, 0x6c, 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x6c, 0x6f, 0x67, 0x6f, 0x22, + 0x3e, 0x62, 0x65, 0x79, 0x6f, 0x6e, 0x64, 0x2d, 0x73, 0x63, 0x61, 0x6c, 0x65, + 0x61, 0x63, 0x63, 0x65, 0x70, 0x74, 0x73, 0x65, 0x72, 0x76, 0x65, 0x64, 0x6d, + 0x61, 0x72, 0x69, 0x6e, 0x65, 0x46, 0x6f, 0x6f, 0x74, 0x65, 0x72, 0x63, 0x61, + 0x6d, 0x65, 0x72, 0x61, 0x3c, 0x2f, 0x68, 0x31, 0x3e, 0x0a, 0x5f, 0x66, 0x6f, + 0x72, 0x6d, 0x22, 0x6c, 0x65, 0x61, 0x76, 0x65, 0x73, 0x73, 0x74, 0x72, 0x65, + 0x73, 0x73, 0x22, 0x20, 0x2f, 0x3e, 0x0d, 0x0a, 0x2e, 0x67, 0x69, 0x66, 0x22, + 0x20, 0x6f, 0x6e, 0x6c, 0x6f, 0x61, 0x64, 0x6c, 0x6f, 0x61, 0x64, 0x65, 0x72, + 0x4f, 0x78, 0x66, 0x6f, 0x72, 0x64, 0x73, 0x69, 0x73, 0x74, 0x65, 0x72, 0x73, + 0x75, 0x72, 0x76, 0x69, 0x76, 0x6c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x66, 0x65, + 0x6d, 0x61, 0x6c, 0x65, 0x44, 0x65, 0x73, 0x69, 0x67, 0x6e, 0x73, 0x69, 0x7a, + 0x65, 0x3d, 0x22, 0x61, 0x70, 0x70, 0x65, 0x61, 0x6c, 0x74, 0x65, 0x78, 0x74, + 0x22, 0x3e, 0x6c, 0x65, 0x76, 0x65, 0x6c, 0x73, 0x74, 0x68, 0x61, 0x6e, 0x6b, + 0x73, 0x68, 0x69, 0x67, 0x68, 0x65, 0x72, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x64, + 0x61, 0x6e, 0x69, 0x6d, 0x61, 0x6c, 0x61, 0x6e, 0x79, 0x6f, 0x6e, 0x65, 0x41, + 0x66, 0x72, 0x69, 0x63, 0x61, 0x61, 0x67, 0x72, 0x65, 0x65, 0x64, 0x72, 0x65, + 0x63, 0x65, 0x6e, 0x74, 0x50, 0x65, 0x6f, 0x70, 0x6c, 0x65, 0x3c, 0x62, 0x72, + 0x20, 0x2f, 0x3e, 0x77, 0x6f, 0x6e, 0x64, 0x65, 0x72, 0x70, 0x72, 0x69, 0x63, + 0x65, 0x73, 0x74, 0x75, 0x72, 0x6e, 0x65, 0x64, 0x7c, 0x7c, 0x20, 0x7b, 0x7d, + 0x3b, 0x6d, 0x61, 0x69, 0x6e, 0x22, 0x3e, 0x69, 0x6e, 0x6c, 0x69, 0x6e, 0x65, + 0x73, 0x75, 0x6e, 0x64, 0x61, 0x79, 0x77, 0x72, 0x61, 0x70, 0x22, 0x3e, 0x66, + 0x61, 0x69, 0x6c, 0x65, 0x64, 0x63, 0x65, 0x6e, 0x73, 0x75, 0x73, 0x6d, 0x69, + 0x6e, 0x75, 0x74, 0x65, 0x62, 0x65, 0x61, 0x63, 0x6f, 0x6e, 0x71, 0x75, 0x6f, + 0x74, 0x65, 0x73, 0x31, 0x35, 0x30, 0x70, 0x78, 0x7c, 0x65, 0x73, 0x74, 0x61, + 0x74, 0x65, 0x72, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x65, 0x6d, 0x61, 0x69, 0x6c, + 0x22, 0x6c, 0x69, 0x6e, 0x6b, 0x65, 0x64, 0x72, 0x69, 0x67, 0x68, 0x74, 0x3b, + 0x73, 0x69, 0x67, 0x6e, 0x61, 0x6c, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x6c, 0x31, + 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0x73, 0x69, 0x67, 0x6e, 0x75, 0x70, 0x70, 0x72, + 0x69, 0x6e, 0x63, 0x65, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x3a, 0x2e, 0x70, 0x6e, + 0x67, 0x22, 0x20, 0x66, 0x6f, 0x72, 0x75, 0x6d, 0x2e, 0x41, 0x63, 0x63, 0x65, + 0x73, 0x73, 0x70, 0x61, 0x70, 0x65, 0x72, 0x73, 0x73, 0x6f, 0x75, 0x6e, 0x64, + 0x73, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x64, 0x48, 0x65, 0x69, 0x67, 0x68, 0x74, + 0x73, 0x6c, 0x69, 0x64, 0x65, 0x72, 0x55, 0x54, 0x46, 0x2d, 0x38, 0x22, 0x26, + 0x61, 0x6d, 0x70, 0x3b, 0x20, 0x42, 0x65, 0x66, 0x6f, 0x72, 0x65, 0x2e, 0x20, + 0x57, 0x69, 0x74, 0x68, 0x73, 0x74, 0x75, 0x64, 0x69, 0x6f, 0x6f, 0x77, 0x6e, + 0x65, 0x72, 0x73, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x70, 0x72, 0x6f, 0x66, + 0x69, 0x74, 0x6a, 0x51, 0x75, 0x65, 0x72, 0x79, 0x61, 0x6e, 0x6e, 0x75, 0x61, + 0x6c, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x62, 0x6f, 0x75, 0x67, 0x68, 0x74, + 0x66, 0x61, 0x6d, 0x6f, 0x75, 0x73, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x6c, + 0x6f, 0x6e, 0x67, 0x65, 0x72, 0x69, 0x2b, 0x2b, 0x29, 0x20, 0x7b, 0x69, 0x73, + 0x72, 0x61, 0x65, 0x6c, 0x73, 0x61, 0x79, 0x69, 0x6e, 0x67, 0x64, 0x65, 0x63, + 0x69, 0x64, 0x65, 0x68, 0x6f, 0x6d, 0x65, 0x22, 0x3e, 0x68, 0x65, 0x61, 0x64, + 0x65, 0x72, 0x65, 0x6e, 0x73, 0x75, 0x72, 0x65, 0x62, 0x72, 0x61, 0x6e, 0x63, + 0x68, 0x70, 0x69, 0x65, 0x63, 0x65, 0x73, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x3b, + 0x73, 0x74, 0x61, 0x74, 0x65, 0x64, 0x74, 0x6f, 0x70, 0x22, 0x3e, 0x3c, 0x72, + 0x61, 0x63, 0x69, 0x6e, 0x67, 0x72, 0x65, 0x73, 0x69, 0x7a, 0x65, 0x2d, 0x2d, + 0x26, 0x67, 0x74, 0x3b, 0x70, 0x61, 0x63, 0x69, 0x74, 0x79, 0x73, 0x65, 0x78, + 0x75, 0x61, 0x6c, 0x62, 0x75, 0x72, 0x65, 0x61, 0x75, 0x2e, 0x6a, 0x70, 0x67, + 0x22, 0x20, 0x31, 0x30, 0x2c, 0x30, 0x30, 0x30, 0x6f, 0x62, 0x74, 0x61, 0x69, + 0x6e, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x73, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, + 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x63, 0x6f, 0x6d, 0x65, 0x64, 0x79, 0x6d, + 0x65, 0x6e, 0x75, 0x22, 0x20, 0x6c, 0x79, 0x72, 0x69, 0x63, 0x73, 0x74, 0x6f, + 0x64, 0x61, 0x79, 0x2e, 0x69, 0x6e, 0x64, 0x65, 0x65, 0x64, 0x63, 0x6f, 0x75, + 0x6e, 0x74, 0x79, 0x5f, 0x6c, 0x6f, 0x67, 0x6f, 0x2e, 0x46, 0x61, 0x6d, 0x69, + 0x6c, 0x79, 0x6c, 0x6f, 0x6f, 0x6b, 0x65, 0x64, 0x4d, 0x61, 0x72, 0x6b, 0x65, + 0x74, 0x6c, 0x73, 0x65, 0x20, 0x69, 0x66, 0x50, 0x6c, 0x61, 0x79, 0x65, 0x72, + 0x74, 0x75, 0x72, 0x6b, 0x65, 0x79, 0x29, 0x3b, 0x76, 0x61, 0x72, 0x20, 0x66, + 0x6f, 0x72, 0x65, 0x73, 0x74, 0x67, 0x69, 0x76, 0x69, 0x6e, 0x67, 0x65, 0x72, + 0x72, 0x6f, 0x72, 0x73, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x7d, 0x65, 0x6c, + 0x73, 0x65, 0x7b, 0x69, 0x6e, 0x73, 0x65, 0x72, 0x74, 0x42, 0x6c, 0x6f, 0x67, + 0x3c, 0x2f, 0x66, 0x6f, 0x6f, 0x74, 0x65, 0x72, 0x6c, 0x6f, 0x67, 0x69, 0x6e, + 0x2e, 0x66, 0x61, 0x73, 0x74, 0x65, 0x72, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x73, + 0x3c, 0x62, 0x6f, 0x64, 0x79, 0x20, 0x31, 0x30, 0x70, 0x78, 0x20, 0x30, 0x70, + 0x72, 0x61, 0x67, 0x6d, 0x61, 0x66, 0x72, 0x69, 0x64, 0x61, 0x79, 0x6a, 0x75, + 0x6e, 0x69, 0x6f, 0x72, 0x64, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x70, 0x6c, 0x61, + 0x63, 0x65, 0x64, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x73, 0x70, 0x6c, 0x75, 0x67, + 0x69, 0x6e, 0x35, 0x2c, 0x30, 0x30, 0x30, 0x20, 0x70, 0x61, 0x67, 0x65, 0x22, + 0x3e, 0x62, 0x6f, 0x73, 0x74, 0x6f, 0x6e, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x28, + 0x61, 0x76, 0x61, 0x74, 0x61, 0x72, 0x74, 0x65, 0x73, 0x74, 0x65, 0x64, 0x5f, + 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x66, 0x6f, 0x72, 0x75, 0x6d, 0x73, 0x73, 0x63, + 0x68, 0x65, 0x6d, 0x61, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x2c, 0x66, 0x69, 0x6c, + 0x6c, 0x65, 0x64, 0x73, 0x68, 0x61, 0x72, 0x65, 0x73, 0x72, 0x65, 0x61, 0x64, + 0x65, 0x72, 0x61, 0x6c, 0x65, 0x72, 0x74, 0x28, 0x61, 0x70, 0x70, 0x65, 0x61, + 0x72, 0x53, 0x75, 0x62, 0x6d, 0x69, 0x74, 0x6c, 0x69, 0x6e, 0x65, 0x22, 0x3e, + 0x62, 0x6f, 0x64, 0x79, 0x22, 0x3e, 0x0a, 0x2a, 0x20, 0x54, 0x68, 0x65, 0x54, + 0x68, 0x6f, 0x75, 0x67, 0x68, 0x73, 0x65, 0x65, 0x69, 0x6e, 0x67, 0x6a, 0x65, + 0x72, 0x73, 0x65, 0x79, 0x4e, 0x65, 0x77, 0x73, 0x3c, 0x2f, 0x76, 0x65, 0x72, + 0x69, 0x66, 0x79, 0x65, 0x78, 0x70, 0x65, 0x72, 0x74, 0x69, 0x6e, 0x6a, 0x75, + 0x72, 0x79, 0x77, 0x69, 0x64, 0x74, 0x68, 0x3d, 0x43, 0x6f, 0x6f, 0x6b, 0x69, + 0x65, 0x53, 0x54, 0x41, 0x52, 0x54, 0x20, 0x61, 0x63, 0x72, 0x6f, 0x73, 0x73, + 0x5f, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x74, 0x68, 0x72, 0x65, 0x61, 0x64, 0x6e, + 0x61, 0x74, 0x69, 0x76, 0x65, 0x70, 0x6f, 0x63, 0x6b, 0x65, 0x74, 0x62, 0x6f, + 0x78, 0x22, 0x3e, 0x0a, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x20, 0x44, 0x61, + 0x76, 0x69, 0x64, 0x63, 0x61, 0x6e, 0x63, 0x65, 0x72, 0x74, 0x61, 0x62, 0x6c, + 0x65, 0x73, 0x70, 0x72, 0x6f, 0x76, 0x65, 0x64, 0x41, 0x70, 0x72, 0x69, 0x6c, + 0x20, 0x72, 0x65, 0x61, 0x6c, 0x6c, 0x79, 0x64, 0x72, 0x69, 0x76, 0x65, 0x72, + 0x69, 0x74, 0x65, 0x6d, 0x22, 0x3e, 0x6d, 0x6f, 0x72, 0x65, 0x22, 0x3e, 0x62, + 0x6f, 0x61, 0x72, 0x64, 0x73, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x73, 0x63, 0x61, + 0x6d, 0x70, 0x75, 0x73, 0x66, 0x69, 0x72, 0x73, 0x74, 0x20, 0x7c, 0x7c, 0x20, + 0x5b, 0x5d, 0x3b, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x2e, 0x67, 0x75, 0x69, 0x74, + 0x61, 0x72, 0x66, 0x69, 0x6e, 0x69, 0x73, 0x68, 0x77, 0x69, 0x64, 0x74, 0x68, + 0x3a, 0x73, 0x68, 0x6f, 0x77, 0x65, 0x64, 0x4f, 0x74, 0x68, 0x65, 0x72, 0x20, + 0x2e, 0x70, 0x68, 0x70, 0x22, 0x20, 0x61, 0x73, 0x73, 0x75, 0x6d, 0x65, 0x6c, + 0x61, 0x79, 0x65, 0x72, 0x73, 0x77, 0x69, 0x6c, 0x73, 0x6f, 0x6e, 0x73, 0x74, + 0x6f, 0x72, 0x65, 0x73, 0x72, 0x65, 0x6c, 0x69, 0x65, 0x66, 0x73, 0x77, 0x65, + 0x64, 0x65, 0x6e, 0x43, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x65, 0x61, 0x73, 0x69, + 0x6c, 0x79, 0x20, 0x79, 0x6f, 0x75, 0x72, 0x20, 0x53, 0x74, 0x72, 0x69, 0x6e, + 0x67, 0x0a, 0x0a, 0x57, 0x68, 0x69, 0x6c, 0x74, 0x61, 0x79, 0x6c, 0x6f, 0x72, + 0x63, 0x6c, 0x65, 0x61, 0x72, 0x3a, 0x72, 0x65, 0x73, 0x6f, 0x72, 0x74, 0x66, + 0x72, 0x65, 0x6e, 0x63, 0x68, 0x74, 0x68, 0x6f, 0x75, 0x67, 0x68, 0x22, 0x29, + 0x20, 0x2b, 0x20, 0x22, 0x3c, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0x62, 0x75, 0x79, + 0x69, 0x6e, 0x67, 0x62, 0x72, 0x61, 0x6e, 0x64, 0x73, 0x4d, 0x65, 0x6d, 0x62, + 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x3e, 0x6f, 0x70, 0x70, 0x69, 0x6e, + 0x67, 0x73, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x35, 0x70, 0x78, 0x3b, 0x22, 0x3e, + 0x76, 0x73, 0x70, 0x61, 0x63, 0x65, 0x70, 0x6f, 0x73, 0x74, 0x65, 0x72, 0x6d, + 0x61, 0x6a, 0x6f, 0x72, 0x20, 0x63, 0x6f, 0x66, 0x66, 0x65, 0x65, 0x6d, 0x61, + 0x72, 0x74, 0x69, 0x6e, 0x6d, 0x61, 0x74, 0x75, 0x72, 0x65, 0x68, 0x61, 0x70, + 0x70, 0x65, 0x6e, 0x3c, 0x2f, 0x6e, 0x61, 0x76, 0x3e, 0x6b, 0x61, 0x6e, 0x73, + 0x61, 0x73, 0x6c, 0x69, 0x6e, 0x6b, 0x22, 0x3e, 0x49, 0x6d, 0x61, 0x67, 0x65, + 0x73, 0x3d, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x77, 0x68, 0x69, 0x6c, 0x65, 0x20, + 0x68, 0x73, 0x70, 0x61, 0x63, 0x65, 0x30, 0x26, 0x61, 0x6d, 0x70, 0x3b, 0x20, + 0x0a, 0x0a, 0x49, 0x6e, 0x20, 0x20, 0x70, 0x6f, 0x77, 0x65, 0x72, 0x50, 0x6f, + 0x6c, 0x73, 0x6b, 0x69, 0x2d, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x6a, 0x6f, 0x72, + 0x64, 0x61, 0x6e, 0x42, 0x6f, 0x74, 0x74, 0x6f, 0x6d, 0x53, 0x74, 0x61, 0x72, + 0x74, 0x20, 0x2d, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x32, 0x2e, 0x68, 0x74, 0x6d, + 0x6c, 0x6e, 0x65, 0x77, 0x73, 0x22, 0x3e, 0x30, 0x31, 0x2e, 0x6a, 0x70, 0x67, + 0x4f, 0x6e, 0x6c, 0x69, 0x6e, 0x65, 0x2d, 0x72, 0x69, 0x67, 0x68, 0x74, 0x6d, + 0x69, 0x6c, 0x6c, 0x65, 0x72, 0x73, 0x65, 0x6e, 0x69, 0x6f, 0x72, 0x49, 0x53, + 0x42, 0x4e, 0x20, 0x30, 0x30, 0x2c, 0x30, 0x30, 0x30, 0x20, 0x67, 0x75, 0x69, + 0x64, 0x65, 0x73, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x29, 0x65, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x72, 0x65, 0x70, 0x61, 0x69, 0x72, 0x2e, 0x78, 0x6d, 0x6c, 0x22, + 0x20, 0x20, 0x72, 0x69, 0x67, 0x68, 0x74, 0x73, 0x2e, 0x68, 0x74, 0x6d, 0x6c, + 0x2d, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x72, 0x65, 0x67, 0x45, 0x78, 0x70, 0x3a, + 0x68, 0x6f, 0x76, 0x65, 0x72, 0x77, 0x69, 0x74, 0x68, 0x69, 0x6e, 0x76, 0x69, + 0x72, 0x67, 0x69, 0x6e, 0x70, 0x68, 0x6f, 0x6e, 0x65, 0x73, 0x3c, 0x2f, 0x74, + 0x72, 0x3e, 0x0d, 0x75, 0x73, 0x69, 0x6e, 0x67, 0x20, 0x0a, 0x09, 0x76, 0x61, + 0x72, 0x20, 0x3e, 0x27, 0x29, 0x3b, 0x0a, 0x09, 0x3c, 0x2f, 0x74, 0x64, 0x3e, + 0x0a, 0x3c, 0x2f, 0x74, 0x72, 0x3e, 0x0a, 0x62, 0x61, 0x68, 0x61, 0x73, 0x61, + 0x62, 0x72, 0x61, 0x73, 0x69, 0x6c, 0x67, 0x61, 0x6c, 0x65, 0x67, 0x6f, 0x6d, + 0x61, 0x67, 0x79, 0x61, 0x72, 0x70, 0x6f, 0x6c, 0x73, 0x6b, 0x69, 0x73, 0x72, + 0x70, 0x73, 0x6b, 0x69, 0xd8, 0xb1, 0xd8, 0xaf, 0xd9, 0x88, 0xe4, 0xb8, 0xad, + 0xe6, 0x96, 0x87, 0xe7, 0xae, 0x80, 0xe4, 0xbd, 0x93, 0xe7, 0xb9, 0x81, 0xe9, + 0xab, 0x94, 0xe4, 0xbf, 0xa1, 0xe6, 0x81, 0xaf, 0xe4, 0xb8, 0xad, 0xe5, 0x9b, + 0xbd, 0xe6, 0x88, 0x91, 0xe4, 0xbb, 0xac, 0xe4, 0xb8, 0x80, 0xe4, 0xb8, 0xaa, + 0xe5, 0x85, 0xac, 0xe5, 0x8f, 0xb8, 0xe7, 0xae, 0xa1, 0xe7, 0x90, 0x86, 0xe8, + 0xae, 0xba, 0xe5, 0x9d, 0x9b, 0xe5, 0x8f, 0xaf, 0xe4, 0xbb, 0xa5, 0xe6, 0x9c, + 0x8d, 0xe5, 0x8a, 0xa1, 0xe6, 0x97, 0xb6, 0xe9, 0x97, 0xb4, 0xe4, 0xb8, 0xaa, + 0xe4, 0xba, 0xba, 0xe4, 0xba, 0xa7, 0xe5, 0x93, 0x81, 0xe8, 0x87, 0xaa, 0xe5, + 0xb7, 0xb1, 0xe4, 0xbc, 0x81, 0xe4, 0xb8, 0x9a, 0xe6, 0x9f, 0xa5, 0xe7, 0x9c, + 0x8b, 0xe5, 0xb7, 0xa5, 0xe4, 0xbd, 0x9c, 0xe8, 0x81, 0x94, 0xe7, 0xb3, 0xbb, + 0xe6, 0xb2, 0xa1, 0xe6, 0x9c, 0x89, 0xe7, 0xbd, 0x91, 0xe7, 0xab, 0x99, 0xe6, + 0x89, 0x80, 0xe6, 0x9c, 0x89, 0xe8, 0xaf, 0x84, 0xe8, 0xae, 0xba, 0xe4, 0xb8, + 0xad, 0xe5, 0xbf, 0x83, 0xe6, 0x96, 0x87, 0xe7, 0xab, 0xa0, 0xe7, 0x94, 0xa8, + 0xe6, 0x88, 0xb7, 0xe9, 0xa6, 0x96, 0xe9, 0xa1, 0xb5, 0xe4, 0xbd, 0x9c, 0xe8, + 0x80, 0x85, 0xe6, 0x8a, 0x80, 0xe6, 0x9c, 0xaf, 0xe9, 0x97, 0xae, 0xe9, 0xa2, + 0x98, 0xe7, 0x9b, 0xb8, 0xe5, 0x85, 0xb3, 0xe4, 0xb8, 0x8b, 0xe8, 0xbd, 0xbd, + 0xe6, 0x90, 0x9c, 0xe7, 0xb4, 0xa2, 0xe4, 0xbd, 0xbf, 0xe7, 0x94, 0xa8, 0xe8, + 0xbd, 0xaf, 0xe4, 0xbb, 0xb6, 0xe5, 0x9c, 0xa8, 0xe7, 0xba, 0xbf, 0xe4, 0xb8, + 0xbb, 0xe9, 0xa2, 0x98, 0xe8, 0xb5, 0x84, 0xe6, 0x96, 0x99, 0xe8, 0xa7, 0x86, + 0xe9, 0xa2, 0x91, 0xe5, 0x9b, 0x9e, 0xe5, 0xa4, 0x8d, 0xe6, 0xb3, 0xa8, 0xe5, + 0x86, 0x8c, 0xe7, 0xbd, 0x91, 0xe7, 0xbb, 0x9c, 0xe6, 0x94, 0xb6, 0xe8, 0x97, + 0x8f, 0xe5, 0x86, 0x85, 0xe5, 0xae, 0xb9, 0xe6, 0x8e, 0xa8, 0xe8, 0x8d, 0x90, + 0xe5, 0xb8, 0x82, 0xe5, 0x9c, 0xba, 0xe6, 0xb6, 0x88, 0xe6, 0x81, 0xaf, 0xe7, + 0xa9, 0xba, 0xe9, 0x97, 0xb4, 0xe5, 0x8f, 0x91, 0xe5, 0xb8, 0x83, 0xe4, 0xbb, + 0x80, 0xe4, 0xb9, 0x88, 0xe5, 0xa5, 0xbd, 0xe5, 0x8f, 0x8b, 0xe7, 0x94, 0x9f, + 0xe6, 0xb4, 0xbb, 0xe5, 0x9b, 0xbe, 0xe7, 0x89, 0x87, 0xe5, 0x8f, 0x91, 0xe5, + 0xb1, 0x95, 0xe5, 0xa6, 0x82, 0xe6, 0x9e, 0x9c, 0xe6, 0x89, 0x8b, 0xe6, 0x9c, + 0xba, 0xe6, 0x96, 0xb0, 0xe9, 0x97, 0xbb, 0xe6, 0x9c, 0x80, 0xe6, 0x96, 0xb0, + 0xe6, 0x96, 0xb9, 0xe5, 0xbc, 0x8f, 0xe5, 0x8c, 0x97, 0xe4, 0xba, 0xac, 0xe6, + 0x8f, 0x90, 0xe4, 0xbe, 0x9b, 0xe5, 0x85, 0xb3, 0xe4, 0xba, 0x8e, 0xe6, 0x9b, + 0xb4, 0xe5, 0xa4, 0x9a, 0xe8, 0xbf, 0x99, 0xe4, 0xb8, 0xaa, 0xe7, 0xb3, 0xbb, + 0xe7, 0xbb, 0x9f, 0xe7, 0x9f, 0xa5, 0xe9, 0x81, 0x93, 0xe6, 0xb8, 0xb8, 0xe6, + 0x88, 0x8f, 0xe5, 0xb9, 0xbf, 0xe5, 0x91, 0x8a, 0xe5, 0x85, 0xb6, 0xe4, 0xbb, + 0x96, 0xe5, 0x8f, 0x91, 0xe8, 0xa1, 0xa8, 0xe5, 0xae, 0x89, 0xe5, 0x85, 0xa8, + 0xe7, 0xac, 0xac, 0xe4, 0xb8, 0x80, 0xe4, 0xbc, 0x9a, 0xe5, 0x91, 0x98, 0xe8, + 0xbf, 0x9b, 0xe8, 0xa1, 0x8c, 0xe7, 0x82, 0xb9, 0xe5, 0x87, 0xbb, 0xe7, 0x89, + 0x88, 0xe6, 0x9d, 0x83, 0xe7, 0x94, 0xb5, 0xe5, 0xad, 0x90, 0xe4, 0xb8, 0x96, + 0xe7, 0x95, 0x8c, 0xe8, 0xae, 0xbe, 0xe8, 0xae, 0xa1, 0xe5, 0x85, 0x8d, 0xe8, + 0xb4, 0xb9, 0xe6, 0x95, 0x99, 0xe8, 0x82, 0xb2, 0xe5, 0x8a, 0xa0, 0xe5, 0x85, + 0xa5, 0xe6, 0xb4, 0xbb, 0xe5, 0x8a, 0xa8, 0xe4, 0xbb, 0x96, 0xe4, 0xbb, 0xac, + 0xe5, 0x95, 0x86, 0xe5, 0x93, 0x81, 0xe5, 0x8d, 0x9a, 0xe5, 0xae, 0xa2, 0xe7, + 0x8e, 0xb0, 0xe5, 0x9c, 0xa8, 0xe4, 0xb8, 0x8a, 0xe6, 0xb5, 0xb7, 0xe5, 0xa6, + 0x82, 0xe4, 0xbd, 0x95, 0xe5, 0xb7, 0xb2, 0xe7, 0xbb, 0x8f, 0xe7, 0x95, 0x99, + 0xe8, 0xa8, 0x80, 0xe8, 0xaf, 0xa6, 0xe7, 0xbb, 0x86, 0xe7, 0xa4, 0xbe, 0xe5, + 0x8c, 0xba, 0xe7, 0x99, 0xbb, 0xe5, 0xbd, 0x95, 0xe6, 0x9c, 0xac, 0xe7, 0xab, + 0x99, 0xe9, 0x9c, 0x80, 0xe8, 0xa6, 0x81, 0xe4, 0xbb, 0xb7, 0xe6, 0xa0, 0xbc, + 0xe6, 0x94, 0xaf, 0xe6, 0x8c, 0x81, 0xe5, 0x9b, 0xbd, 0xe9, 0x99, 0x85, 0xe9, + 0x93, 0xbe, 0xe6, 0x8e, 0xa5, 0xe5, 0x9b, 0xbd, 0xe5, 0xae, 0xb6, 0xe5, 0xbb, + 0xba, 0xe8, 0xae, 0xbe, 0xe6, 0x9c, 0x8b, 0xe5, 0x8f, 0x8b, 0xe9, 0x98, 0x85, + 0xe8, 0xaf, 0xbb, 0xe6, 0xb3, 0x95, 0xe5, 0xbe, 0x8b, 0xe4, 0xbd, 0x8d, 0xe7, + 0xbd, 0xae, 0xe7, 0xbb, 0x8f, 0xe6, 0xb5, 0x8e, 0xe9, 0x80, 0x89, 0xe6, 0x8b, + 0xa9, 0xe8, 0xbf, 0x99, 0xe6, 0xa0, 0xb7, 0xe5, 0xbd, 0x93, 0xe5, 0x89, 0x8d, + 0xe5, 0x88, 0x86, 0xe7, 0xb1, 0xbb, 0xe6, 0x8e, 0x92, 0xe8, 0xa1, 0x8c, 0xe5, + 0x9b, 0xa0, 0xe4, 0xb8, 0xba, 0xe4, 0xba, 0xa4, 0xe6, 0x98, 0x93, 0xe6, 0x9c, + 0x80, 0xe5, 0x90, 0x8e, 0xe9, 0x9f, 0xb3, 0xe4, 0xb9, 0x90, 0xe4, 0xb8, 0x8d, + 0xe8, 0x83, 0xbd, 0xe9, 0x80, 0x9a, 0xe8, 0xbf, 0x87, 0xe8, 0xa1, 0x8c, 0xe4, + 0xb8, 0x9a, 0xe7, 0xa7, 0x91, 0xe6, 0x8a, 0x80, 0xe5, 0x8f, 0xaf, 0xe8, 0x83, + 0xbd, 0xe8, 0xae, 0xbe, 0xe5, 0xa4, 0x87, 0xe5, 0x90, 0x88, 0xe4, 0xbd, 0x9c, + 0xe5, 0xa4, 0xa7, 0xe5, 0xae, 0xb6, 0xe7, 0xa4, 0xbe, 0xe4, 0xbc, 0x9a, 0xe7, + 0xa0, 0x94, 0xe7, 0xa9, 0xb6, 0xe4, 0xb8, 0x93, 0xe4, 0xb8, 0x9a, 0xe5, 0x85, + 0xa8, 0xe9, 0x83, 0xa8, 0xe9, 0xa1, 0xb9, 0xe7, 0x9b, 0xae, 0xe8, 0xbf, 0x99, + 0xe9, 0x87, 0x8c, 0xe8, 0xbf, 0x98, 0xe6, 0x98, 0xaf, 0xe5, 0xbc, 0x80, 0xe5, + 0xa7, 0x8b, 0xe6, 0x83, 0x85, 0xe5, 0x86, 0xb5, 0xe7, 0x94, 0xb5, 0xe8, 0x84, + 0x91, 0xe6, 0x96, 0x87, 0xe4, 0xbb, 0xb6, 0xe5, 0x93, 0x81, 0xe7, 0x89, 0x8c, + 0xe5, 0xb8, 0xae, 0xe5, 0x8a, 0xa9, 0xe6, 0x96, 0x87, 0xe5, 0x8c, 0x96, 0xe8, + 0xb5, 0x84, 0xe6, 0xba, 0x90, 0xe5, 0xa4, 0xa7, 0xe5, 0xad, 0xa6, 0xe5, 0xad, + 0xa6, 0xe4, 0xb9, 0xa0, 0xe5, 0x9c, 0xb0, 0xe5, 0x9d, 0x80, 0xe6, 0xb5, 0x8f, + 0xe8, 0xa7, 0x88, 0xe6, 0x8a, 0x95, 0xe8, 0xb5, 0x84, 0xe5, 0xb7, 0xa5, 0xe7, + 0xa8, 0x8b, 0xe8, 0xa6, 0x81, 0xe6, 0xb1, 0x82, 0xe6, 0x80, 0x8e, 0xe4, 0xb9, + 0x88, 0xe6, 0x97, 0xb6, 0xe5, 0x80, 0x99, 0xe5, 0x8a, 0x9f, 0xe8, 0x83, 0xbd, + 0xe4, 0xb8, 0xbb, 0xe8, 0xa6, 0x81, 0xe7, 0x9b, 0xae, 0xe5, 0x89, 0x8d, 0xe8, + 0xb5, 0x84, 0xe8, 0xae, 0xaf, 0xe5, 0x9f, 0x8e, 0xe5, 0xb8, 0x82, 0xe6, 0x96, + 0xb9, 0xe6, 0xb3, 0x95, 0xe7, 0x94, 0xb5, 0xe5, 0xbd, 0xb1, 0xe6, 0x8b, 0x9b, + 0xe8, 0x81, 0x98, 0xe5, 0xa3, 0xb0, 0xe6, 0x98, 0x8e, 0xe4, 0xbb, 0xbb, 0xe4, + 0xbd, 0x95, 0xe5, 0x81, 0xa5, 0xe5, 0xba, 0xb7, 0xe6, 0x95, 0xb0, 0xe6, 0x8d, + 0xae, 0xe7, 0xbe, 0x8e, 0xe5, 0x9b, 0xbd, 0xe6, 0xb1, 0xbd, 0xe8, 0xbd, 0xa6, + 0xe4, 0xbb, 0x8b, 0xe7, 0xbb, 0x8d, 0xe4, 0xbd, 0x86, 0xe6, 0x98, 0xaf, 0xe4, + 0xba, 0xa4, 0xe6, 0xb5, 0x81, 0xe7, 0x94, 0x9f, 0xe4, 0xba, 0xa7, 0xe6, 0x89, + 0x80, 0xe4, 0xbb, 0xa5, 0xe7, 0x94, 0xb5, 0xe8, 0xaf, 0x9d, 0xe6, 0x98, 0xbe, + 0xe7, 0xa4, 0xba, 0xe4, 0xb8, 0x80, 0xe4, 0xba, 0x9b, 0xe5, 0x8d, 0x95, 0xe4, + 0xbd, 0x8d, 0xe4, 0xba, 0xba, 0xe5, 0x91, 0x98, 0xe5, 0x88, 0x86, 0xe6, 0x9e, + 0x90, 0xe5, 0x9c, 0xb0, 0xe5, 0x9b, 0xbe, 0xe6, 0x97, 0x85, 0xe6, 0xb8, 0xb8, + 0xe5, 0xb7, 0xa5, 0xe5, 0x85, 0xb7, 0xe5, 0xad, 0xa6, 0xe7, 0x94, 0x9f, 0xe7, + 0xb3, 0xbb, 0xe5, 0x88, 0x97, 0xe7, 0xbd, 0x91, 0xe5, 0x8f, 0x8b, 0xe5, 0xb8, + 0x96, 0xe5, 0xad, 0x90, 0xe5, 0xaf, 0x86, 0xe7, 0xa0, 0x81, 0xe9, 0xa2, 0x91, + 0xe9, 0x81, 0x93, 0xe6, 0x8e, 0xa7, 0xe5, 0x88, 0xb6, 0xe5, 0x9c, 0xb0, 0xe5, + 0x8c, 0xba, 0xe5, 0x9f, 0xba, 0xe6, 0x9c, 0xac, 0xe5, 0x85, 0xa8, 0xe5, 0x9b, + 0xbd, 0xe7, 0xbd, 0x91, 0xe4, 0xb8, 0x8a, 0xe9, 0x87, 0x8d, 0xe8, 0xa6, 0x81, + 0xe7, 0xac, 0xac, 0xe4, 0xba, 0x8c, 0xe5, 0x96, 0x9c, 0xe6, 0xac, 0xa2, 0xe8, + 0xbf, 0x9b, 0xe5, 0x85, 0xa5, 0xe5, 0x8f, 0x8b, 0xe6, 0x83, 0x85, 0xe8, 0xbf, + 0x99, 0xe4, 0xba, 0x9b, 0xe8, 0x80, 0x83, 0xe8, 0xaf, 0x95, 0xe5, 0x8f, 0x91, + 0xe7, 0x8e, 0xb0, 0xe5, 0x9f, 0xb9, 0xe8, 0xae, 0xad, 0xe4, 0xbb, 0xa5, 0xe4, + 0xb8, 0x8a, 0xe6, 0x94, 0xbf, 0xe5, 0xba, 0x9c, 0xe6, 0x88, 0x90, 0xe4, 0xb8, + 0xba, 0xe7, 0x8e, 0xaf, 0xe5, 0xa2, 0x83, 0xe9, 0xa6, 0x99, 0xe6, 0xb8, 0xaf, + 0xe5, 0x90, 0x8c, 0xe6, 0x97, 0xb6, 0xe5, 0xa8, 0xb1, 0xe4, 0xb9, 0x90, 0xe5, + 0x8f, 0x91, 0xe9, 0x80, 0x81, 0xe4, 0xb8, 0x80, 0xe5, 0xae, 0x9a, 0xe5, 0xbc, + 0x80, 0xe5, 0x8f, 0x91, 0xe4, 0xbd, 0x9c, 0xe5, 0x93, 0x81, 0xe6, 0xa0, 0x87, + 0xe5, 0x87, 0x86, 0xe6, 0xac, 0xa2, 0xe8, 0xbf, 0x8e, 0xe8, 0xa7, 0xa3, 0xe5, + 0x86, 0xb3, 0xe5, 0x9c, 0xb0, 0xe6, 0x96, 0xb9, 0xe4, 0xb8, 0x80, 0xe4, 0xb8, + 0x8b, 0xe4, 0xbb, 0xa5, 0xe5, 0x8f, 0x8a, 0xe8, 0xb4, 0xa3, 0xe4, 0xbb, 0xbb, + 0xe6, 0x88, 0x96, 0xe8, 0x80, 0x85, 0xe5, 0xae, 0xa2, 0xe6, 0x88, 0xb7, 0xe4, + 0xbb, 0xa3, 0xe8, 0xa1, 0xa8, 0xe7, 0xa7, 0xaf, 0xe5, 0x88, 0x86, 0xe5, 0xa5, + 0xb3, 0xe4, 0xba, 0xba, 0xe6, 0x95, 0xb0, 0xe7, 0xa0, 0x81, 0xe9, 0x94, 0x80, + 0xe5, 0x94, 0xae, 0xe5, 0x87, 0xba, 0xe7, 0x8e, 0xb0, 0xe7, 0xa6, 0xbb, 0xe7, + 0xba, 0xbf, 0xe5, 0xba, 0x94, 0xe7, 0x94, 0xa8, 0xe5, 0x88, 0x97, 0xe8, 0xa1, + 0xa8, 0xe4, 0xb8, 0x8d, 0xe5, 0x90, 0x8c, 0xe7, 0xbc, 0x96, 0xe8, 0xbe, 0x91, + 0xe7, 0xbb, 0x9f, 0xe8, 0xae, 0xa1, 0xe6, 0x9f, 0xa5, 0xe8, 0xaf, 0xa2, 0xe4, + 0xb8, 0x8d, 0xe8, 0xa6, 0x81, 0xe6, 0x9c, 0x89, 0xe5, 0x85, 0xb3, 0xe6, 0x9c, + 0xba, 0xe6, 0x9e, 0x84, 0xe5, 0xbe, 0x88, 0xe5, 0xa4, 0x9a, 0xe6, 0x92, 0xad, + 0xe6, 0x94, 0xbe, 0xe7, 0xbb, 0x84, 0xe7, 0xbb, 0x87, 0xe6, 0x94, 0xbf, 0xe7, + 0xad, 0x96, 0xe7, 0x9b, 0xb4, 0xe6, 0x8e, 0xa5, 0xe8, 0x83, 0xbd, 0xe5, 0x8a, + 0x9b, 0xe6, 0x9d, 0xa5, 0xe6, 0xba, 0x90, 0xe6, 0x99, 0x82, 0xe9, 0x96, 0x93, + 0xe7, 0x9c, 0x8b, 0xe5, 0x88, 0xb0, 0xe7, 0x83, 0xad, 0xe9, 0x97, 0xa8, 0xe5, + 0x85, 0xb3, 0xe9, 0x94, 0xae, 0xe4, 0xb8, 0x93, 0xe5, 0x8c, 0xba, 0xe9, 0x9d, + 0x9e, 0xe5, 0xb8, 0xb8, 0xe8, 0x8b, 0xb1, 0xe8, 0xaf, 0xad, 0xe7, 0x99, 0xbe, + 0xe5, 0xba, 0xa6, 0xe5, 0xb8, 0x8c, 0xe6, 0x9c, 0x9b, 0xe7, 0xbe, 0x8e, 0xe5, + 0xa5, 0xb3, 0xe6, 0xaf, 0x94, 0xe8, 0xbe, 0x83, 0xe7, 0x9f, 0xa5, 0xe8, 0xaf, + 0x86, 0xe8, 0xa7, 0x84, 0xe5, 0xae, 0x9a, 0xe5, 0xbb, 0xba, 0xe8, 0xae, 0xae, + 0xe9, 0x83, 0xa8, 0xe9, 0x97, 0xa8, 0xe6, 0x84, 0x8f, 0xe8, 0xa7, 0x81, 0xe7, + 0xb2, 0xbe, 0xe5, 0xbd, 0xa9, 0xe6, 0x97, 0xa5, 0xe6, 0x9c, 0xac, 0xe6, 0x8f, + 0x90, 0xe9, 0xab, 0x98, 0xe5, 0x8f, 0x91, 0xe8, 0xa8, 0x80, 0xe6, 0x96, 0xb9, + 0xe9, 0x9d, 0xa2, 0xe5, 0x9f, 0xba, 0xe9, 0x87, 0x91, 0xe5, 0xa4, 0x84, 0xe7, + 0x90, 0x86, 0xe6, 0x9d, 0x83, 0xe9, 0x99, 0x90, 0xe5, 0xbd, 0xb1, 0xe7, 0x89, + 0x87, 0xe9, 0x93, 0xb6, 0xe8, 0xa1, 0x8c, 0xe8, 0xbf, 0x98, 0xe6, 0x9c, 0x89, + 0xe5, 0x88, 0x86, 0xe4, 0xba, 0xab, 0xe7, 0x89, 0xa9, 0xe5, 0x93, 0x81, 0xe7, + 0xbb, 0x8f, 0xe8, 0x90, 0xa5, 0xe6, 0xb7, 0xbb, 0xe5, 0x8a, 0xa0, 0xe4, 0xb8, + 0x93, 0xe5, 0xae, 0xb6, 0xe8, 0xbf, 0x99, 0xe7, 0xa7, 0x8d, 0xe8, 0xaf, 0x9d, + 0xe9, 0xa2, 0x98, 0xe8, 0xb5, 0xb7, 0xe6, 0x9d, 0xa5, 0xe4, 0xb8, 0x9a, 0xe5, + 0x8a, 0xa1, 0xe5, 0x85, 0xac, 0xe5, 0x91, 0x8a, 0xe8, 0xae, 0xb0, 0xe5, 0xbd, + 0x95, 0xe7, 0xae, 0x80, 0xe4, 0xbb, 0x8b, 0xe8, 0xb4, 0xa8, 0xe9, 0x87, 0x8f, + 0xe7, 0x94, 0xb7, 0xe4, 0xba, 0xba, 0xe5, 0xbd, 0xb1, 0xe5, 0x93, 0x8d, 0xe5, + 0xbc, 0x95, 0xe7, 0x94, 0xa8, 0xe6, 0x8a, 0xa5, 0xe5, 0x91, 0x8a, 0xe9, 0x83, + 0xa8, 0xe5, 0x88, 0x86, 0xe5, 0xbf, 0xab, 0xe9, 0x80, 0x9f, 0xe5, 0x92, 0xa8, + 0xe8, 0xaf, 0xa2, 0xe6, 0x97, 0xb6, 0xe5, 0xb0, 0x9a, 0xe6, 0xb3, 0xa8, 0xe6, + 0x84, 0x8f, 0xe7, 0x94, 0xb3, 0xe8, 0xaf, 0xb7, 0xe5, 0xad, 0xa6, 0xe6, 0xa0, + 0xa1, 0xe5, 0xba, 0x94, 0xe8, 0xaf, 0xa5, 0xe5, 0x8e, 0x86, 0xe5, 0x8f, 0xb2, + 0xe5, 0x8f, 0xaa, 0xe6, 0x98, 0xaf, 0xe8, 0xbf, 0x94, 0xe5, 0x9b, 0x9e, 0xe8, + 0xb4, 0xad, 0xe4, 0xb9, 0xb0, 0xe5, 0x90, 0x8d, 0xe7, 0xa7, 0xb0, 0xe4, 0xb8, + 0xba, 0xe4, 0xba, 0x86, 0xe6, 0x88, 0x90, 0xe5, 0x8a, 0x9f, 0xe8, 0xaf, 0xb4, + 0xe6, 0x98, 0x8e, 0xe4, 0xbe, 0x9b, 0xe5, 0xba, 0x94, 0xe5, 0xad, 0xa9, 0xe5, + 0xad, 0x90, 0xe4, 0xb8, 0x93, 0xe9, 0xa2, 0x98, 0xe7, 0xa8, 0x8b, 0xe5, 0xba, + 0x8f, 0xe4, 0xb8, 0x80, 0xe8, 0x88, 0xac, 0xe6, 0x9c, 0x83, 0xe5, 0x93, 0xa1, + 0xe5, 0x8f, 0xaa, 0xe6, 0x9c, 0x89, 0xe5, 0x85, 0xb6, 0xe5, 0xae, 0x83, 0xe4, + 0xbf, 0x9d, 0xe6, 0x8a, 0xa4, 0xe8, 0x80, 0x8c, 0xe4, 0xb8, 0x94, 0xe4, 0xbb, + 0x8a, 0xe5, 0xa4, 0xa9, 0xe7, 0xaa, 0x97, 0xe5, 0x8f, 0xa3, 0xe5, 0x8a, 0xa8, + 0xe6, 0x80, 0x81, 0xe7, 0x8a, 0xb6, 0xe6, 0x80, 0x81, 0xe7, 0x89, 0xb9, 0xe5, + 0x88, 0xab, 0xe8, 0xae, 0xa4, 0xe4, 0xb8, 0xba, 0xe5, 0xbf, 0x85, 0xe9, 0xa1, + 0xbb, 0xe6, 0x9b, 0xb4, 0xe6, 0x96, 0xb0, 0xe5, 0xb0, 0x8f, 0xe8, 0xaf, 0xb4, + 0xe6, 0x88, 0x91, 0xe5, 0x80, 0x91, 0xe4, 0xbd, 0x9c, 0xe4, 0xb8, 0xba, 0xe5, + 0xaa, 0x92, 0xe4, 0xbd, 0x93, 0xe5, 0x8c, 0x85, 0xe6, 0x8b, 0xac, 0xe9, 0x82, + 0xa3, 0xe4, 0xb9, 0x88, 0xe4, 0xb8, 0x80, 0xe6, 0xa0, 0xb7, 0xe5, 0x9b, 0xbd, + 0xe5, 0x86, 0x85, 0xe6, 0x98, 0xaf, 0xe5, 0x90, 0xa6, 0xe6, 0xa0, 0xb9, 0xe6, + 0x8d, 0xae, 0xe7, 0x94, 0xb5, 0xe8, 0xa7, 0x86, 0xe5, 0xad, 0xa6, 0xe9, 0x99, + 0xa2, 0xe5, 0x85, 0xb7, 0xe6, 0x9c, 0x89, 0xe8, 0xbf, 0x87, 0xe7, 0xa8, 0x8b, + 0xe7, 0x94, 0xb1, 0xe4, 0xba, 0x8e, 0xe4, 0xba, 0xba, 0xe6, 0x89, 0x8d, 0xe5, + 0x87, 0xba, 0xe6, 0x9d, 0xa5, 0xe4, 0xb8, 0x8d, 0xe8, 0xbf, 0x87, 0xe6, 0xad, + 0xa3, 0xe5, 0x9c, 0xa8, 0xe6, 0x98, 0x8e, 0xe6, 0x98, 0x9f, 0xe6, 0x95, 0x85, + 0xe4, 0xba, 0x8b, 0xe5, 0x85, 0xb3, 0xe7, 0xb3, 0xbb, 0xe6, 0xa0, 0x87, 0xe9, + 0xa2, 0x98, 0xe5, 0x95, 0x86, 0xe5, 0x8a, 0xa1, 0xe8, 0xbe, 0x93, 0xe5, 0x85, + 0xa5, 0xe4, 0xb8, 0x80, 0xe7, 0x9b, 0xb4, 0xe5, 0x9f, 0xba, 0xe7, 0xa1, 0x80, + 0xe6, 0x95, 0x99, 0xe5, 0xad, 0xa6, 0xe4, 0xba, 0x86, 0xe8, 0xa7, 0xa3, 0xe5, + 0xbb, 0xba, 0xe7, 0xad, 0x91, 0xe7, 0xbb, 0x93, 0xe6, 0x9e, 0x9c, 0xe5, 0x85, + 0xa8, 0xe7, 0x90, 0x83, 0xe9, 0x80, 0x9a, 0xe7, 0x9f, 0xa5, 0xe8, 0xae, 0xa1, + 0xe5, 0x88, 0x92, 0xe5, 0xaf, 0xb9, 0xe4, 0xba, 0x8e, 0xe8, 0x89, 0xba, 0xe6, + 0x9c, 0xaf, 0xe7, 0x9b, 0xb8, 0xe5, 0x86, 0x8c, 0xe5, 0x8f, 0x91, 0xe7, 0x94, + 0x9f, 0xe7, 0x9c, 0x9f, 0xe7, 0x9a, 0x84, 0xe5, 0xbb, 0xba, 0xe7, 0xab, 0x8b, + 0xe7, 0xad, 0x89, 0xe7, 0xba, 0xa7, 0xe7, 0xb1, 0xbb, 0xe5, 0x9e, 0x8b, 0xe7, + 0xbb, 0x8f, 0xe9, 0xaa, 0x8c, 0xe5, 0xae, 0x9e, 0xe7, 0x8e, 0xb0, 0xe5, 0x88, + 0xb6, 0xe4, 0xbd, 0x9c, 0xe6, 0x9d, 0xa5, 0xe8, 0x87, 0xaa, 0xe6, 0xa0, 0x87, + 0xe7, 0xad, 0xbe, 0xe4, 0xbb, 0xa5, 0xe4, 0xb8, 0x8b, 0xe5, 0x8e, 0x9f, 0xe5, + 0x88, 0x9b, 0xe6, 0x97, 0xa0, 0xe6, 0xb3, 0x95, 0xe5, 0x85, 0xb6, 0xe4, 0xb8, + 0xad, 0xe5, 0x80, 0x8b, 0xe4, 0xba, 0xba, 0xe4, 0xb8, 0x80, 0xe5, 0x88, 0x87, + 0xe6, 0x8c, 0x87, 0xe5, 0x8d, 0x97, 0xe5, 0x85, 0xb3, 0xe9, 0x97, 0xad, 0xe9, + 0x9b, 0x86, 0xe5, 0x9b, 0xa2, 0xe7, 0xac, 0xac, 0xe4, 0xb8, 0x89, 0xe5, 0x85, + 0xb3, 0xe6, 0xb3, 0xa8, 0xe5, 0x9b, 0xa0, 0xe6, 0xad, 0xa4, 0xe7, 0x85, 0xa7, + 0xe7, 0x89, 0x87, 0xe6, 0xb7, 0xb1, 0xe5, 0x9c, 0xb3, 0xe5, 0x95, 0x86, 0xe4, + 0xb8, 0x9a, 0xe5, 0xb9, 0xbf, 0xe5, 0xb7, 0x9e, 0xe6, 0x97, 0xa5, 0xe6, 0x9c, + 0x9f, 0xe9, 0xab, 0x98, 0xe7, 0xba, 0xa7, 0xe6, 0x9c, 0x80, 0xe8, 0xbf, 0x91, + 0xe7, 0xbb, 0xbc, 0xe5, 0x90, 0x88, 0xe8, 0xa1, 0xa8, 0xe7, 0xa4, 0xba, 0xe4, + 0xb8, 0x93, 0xe8, 0xbe, 0x91, 0xe8, 0xa1, 0x8c, 0xe4, 0xb8, 0xba, 0xe4, 0xba, + 0xa4, 0xe9, 0x80, 0x9a, 0xe8, 0xaf, 0x84, 0xe4, 0xbb, 0xb7, 0xe8, 0xa7, 0x89, + 0xe5, 0xbe, 0x97, 0xe7, 0xb2, 0xbe, 0xe5, 0x8d, 0x8e, 0xe5, 0xae, 0xb6, 0xe5, + 0xba, 0xad, 0xe5, 0xae, 0x8c, 0xe6, 0x88, 0x90, 0xe6, 0x84, 0x9f, 0xe8, 0xa7, + 0x89, 0xe5, 0xae, 0x89, 0xe8, 0xa3, 0x85, 0xe5, 0xbe, 0x97, 0xe5, 0x88, 0xb0, + 0xe9, 0x82, 0xae, 0xe4, 0xbb, 0xb6, 0xe5, 0x88, 0xb6, 0xe5, 0xba, 0xa6, 0xe9, + 0xa3, 0x9f, 0xe5, 0x93, 0x81, 0xe8, 0x99, 0xbd, 0xe7, 0x84, 0xb6, 0xe8, 0xbd, + 0xac, 0xe8, 0xbd, 0xbd, 0xe6, 0x8a, 0xa5, 0xe4, 0xbb, 0xb7, 0xe8, 0xae, 0xb0, + 0xe8, 0x80, 0x85, 0xe6, 0x96, 0xb9, 0xe6, 0xa1, 0x88, 0xe8, 0xa1, 0x8c, 0xe6, + 0x94, 0xbf, 0xe4, 0xba, 0xba, 0xe6, 0xb0, 0x91, 0xe7, 0x94, 0xa8, 0xe5, 0x93, + 0x81, 0xe4, 0xb8, 0x9c, 0xe8, 0xa5, 0xbf, 0xe6, 0x8f, 0x90, 0xe5, 0x87, 0xba, + 0xe9, 0x85, 0x92, 0xe5, 0xba, 0x97, 0xe7, 0x84, 0xb6, 0xe5, 0x90, 0x8e, 0xe4, + 0xbb, 0x98, 0xe6, 0xac, 0xbe, 0xe7, 0x83, 0xad, 0xe7, 0x82, 0xb9, 0xe4, 0xbb, + 0xa5, 0xe5, 0x89, 0x8d, 0xe5, 0xae, 0x8c, 0xe5, 0x85, 0xa8, 0xe5, 0x8f, 0x91, + 0xe5, 0xb8, 0x96, 0xe8, 0xae, 0xbe, 0xe7, 0xbd, 0xae, 0xe9, 0xa2, 0x86, 0xe5, + 0xaf, 0xbc, 0xe5, 0xb7, 0xa5, 0xe4, 0xb8, 0x9a, 0xe5, 0x8c, 0xbb, 0xe9, 0x99, + 0xa2, 0xe7, 0x9c, 0x8b, 0xe7, 0x9c, 0x8b, 0xe7, 0xbb, 0x8f, 0xe5, 0x85, 0xb8, + 0xe5, 0x8e, 0x9f, 0xe5, 0x9b, 0xa0, 0xe5, 0xb9, 0xb3, 0xe5, 0x8f, 0xb0, 0xe5, + 0x90, 0x84, 0xe7, 0xa7, 0x8d, 0xe5, 0xa2, 0x9e, 0xe5, 0x8a, 0xa0, 0xe6, 0x9d, + 0x90, 0xe6, 0x96, 0x99, 0xe6, 0x96, 0xb0, 0xe5, 0xa2, 0x9e, 0xe4, 0xb9, 0x8b, + 0xe5, 0x90, 0x8e, 0xe8, 0x81, 0x8c, 0xe4, 0xb8, 0x9a, 0xe6, 0x95, 0x88, 0xe6, + 0x9e, 0x9c, 0xe4, 0xbb, 0x8a, 0xe5, 0xb9, 0xb4, 0xe8, 0xae, 0xba, 0xe6, 0x96, + 0x87, 0xe6, 0x88, 0x91, 0xe5, 0x9b, 0xbd, 0xe5, 0x91, 0x8a, 0xe8, 0xaf, 0x89, + 0xe7, 0x89, 0x88, 0xe4, 0xb8, 0xbb, 0xe4, 0xbf, 0xae, 0xe6, 0x94, 0xb9, 0xe5, + 0x8f, 0x82, 0xe4, 0xb8, 0x8e, 0xe6, 0x89, 0x93, 0xe5, 0x8d, 0xb0, 0xe5, 0xbf, + 0xab, 0xe4, 0xb9, 0x90, 0xe6, 0x9c, 0xba, 0xe6, 0xa2, 0xb0, 0xe8, 0xa7, 0x82, + 0xe7, 0x82, 0xb9, 0xe5, 0xad, 0x98, 0xe5, 0x9c, 0xa8, 0xe7, 0xb2, 0xbe, 0xe7, + 0xa5, 0x9e, 0xe8, 0x8e, 0xb7, 0xe5, 0xbe, 0x97, 0xe5, 0x88, 0xa9, 0xe7, 0x94, + 0xa8, 0xe7, 0xbb, 0xa7, 0xe7, 0xbb, 0xad, 0xe4, 0xbd, 0xa0, 0xe4, 0xbb, 0xac, + 0xe8, 0xbf, 0x99, 0xe4, 0xb9, 0x88, 0xe6, 0xa8, 0xa1, 0xe5, 0xbc, 0x8f, 0xe8, + 0xaf, 0xad, 0xe8, 0xa8, 0x80, 0xe8, 0x83, 0xbd, 0xe5, 0xa4, 0x9f, 0xe9, 0x9b, + 0x85, 0xe8, 0x99, 0x8e, 0xe6, 0x93, 0x8d, 0xe4, 0xbd, 0x9c, 0xe9, 0xa3, 0x8e, + 0xe6, 0xa0, 0xbc, 0xe4, 0xb8, 0x80, 0xe8, 0xb5, 0xb7, 0xe7, 0xa7, 0x91, 0xe5, + 0xad, 0xa6, 0xe4, 0xbd, 0x93, 0xe8, 0x82, 0xb2, 0xe7, 0x9f, 0xad, 0xe4, 0xbf, + 0xa1, 0xe6, 0x9d, 0xa1, 0xe4, 0xbb, 0xb6, 0xe6, 0xb2, 0xbb, 0xe7, 0x96, 0x97, + 0xe8, 0xbf, 0x90, 0xe5, 0x8a, 0xa8, 0xe4, 0xba, 0xa7, 0xe4, 0xb8, 0x9a, 0xe4, + 0xbc, 0x9a, 0xe8, 0xae, 0xae, 0xe5, 0xaf, 0xbc, 0xe8, 0x88, 0xaa, 0xe5, 0x85, + 0x88, 0xe7, 0x94, 0x9f, 0xe8, 0x81, 0x94, 0xe7, 0x9b, 0x9f, 0xe5, 0x8f, 0xaf, + 0xe6, 0x98, 0xaf, 0xe5, 0x95, 0x8f, 0xe9, 0xa1, 0x8c, 0xe7, 0xbb, 0x93, 0xe6, + 0x9e, 0x84, 0xe4, 0xbd, 0x9c, 0xe7, 0x94, 0xa8, 0xe8, 0xb0, 0x83, 0xe6, 0x9f, + 0xa5, 0xe8, 0xb3, 0x87, 0xe6, 0x96, 0x99, 0xe8, 0x87, 0xaa, 0xe5, 0x8a, 0xa8, + 0xe8, 0xb4, 0x9f, 0xe8, 0xb4, 0xa3, 0xe5, 0x86, 0x9c, 0xe4, 0xb8, 0x9a, 0xe8, + 0xae, 0xbf, 0xe9, 0x97, 0xae, 0xe5, 0xae, 0x9e, 0xe6, 0x96, 0xbd, 0xe6, 0x8e, + 0xa5, 0xe5, 0x8f, 0x97, 0xe8, 0xae, 0xa8, 0xe8, 0xae, 0xba, 0xe9, 0x82, 0xa3, + 0xe4, 0xb8, 0xaa, 0xe5, 0x8f, 0x8d, 0xe9, 0xa6, 0x88, 0xe5, 0x8a, 0xa0, 0xe5, + 0xbc, 0xba, 0xe5, 0xa5, 0xb3, 0xe6, 0x80, 0xa7, 0xe8, 0x8c, 0x83, 0xe5, 0x9b, + 0xb4, 0xe6, 0x9c, 0x8d, 0xe5, 0x8b, 0x99, 0xe4, 0xbc, 0x91, 0xe9, 0x97, 0xb2, + 0xe4, 0xbb, 0x8a, 0xe6, 0x97, 0xa5, 0xe5, 0xae, 0xa2, 0xe6, 0x9c, 0x8d, 0xe8, + 0xa7, 0x80, 0xe7, 0x9c, 0x8b, 0xe5, 0x8f, 0x82, 0xe5, 0x8a, 0xa0, 0xe7, 0x9a, + 0x84, 0xe8, 0xaf, 0x9d, 0xe4, 0xb8, 0x80, 0xe7, 0x82, 0xb9, 0xe4, 0xbf, 0x9d, + 0xe8, 0xaf, 0x81, 0xe5, 0x9b, 0xbe, 0xe4, 0xb9, 0xa6, 0xe6, 0x9c, 0x89, 0xe6, + 0x95, 0x88, 0xe6, 0xb5, 0x8b, 0xe8, 0xaf, 0x95, 0xe7, 0xa7, 0xbb, 0xe5, 0x8a, + 0xa8, 0xe6, 0x89, 0x8d, 0xe8, 0x83, 0xbd, 0xe5, 0x86, 0xb3, 0xe5, 0xae, 0x9a, + 0xe8, 0x82, 0xa1, 0xe7, 0xa5, 0xa8, 0xe4, 0xb8, 0x8d, 0xe6, 0x96, 0xad, 0xe9, + 0x9c, 0x80, 0xe6, 0xb1, 0x82, 0xe4, 0xb8, 0x8d, 0xe5, 0xbe, 0x97, 0xe5, 0x8a, + 0x9e, 0xe6, 0xb3, 0x95, 0xe4, 0xb9, 0x8b, 0xe9, 0x97, 0xb4, 0xe9, 0x87, 0x87, + 0xe7, 0x94, 0xa8, 0xe8, 0x90, 0xa5, 0xe9, 0x94, 0x80, 0xe6, 0x8a, 0x95, 0xe8, + 0xaf, 0x89, 0xe7, 0x9b, 0xae, 0xe6, 0xa0, 0x87, 0xe7, 0x88, 0xb1, 0xe6, 0x83, + 0x85, 0xe6, 0x91, 0x84, 0xe5, 0xbd, 0xb1, 0xe6, 0x9c, 0x89, 0xe4, 0xba, 0x9b, + 0xe8, 0xa4, 0x87, 0xe8, 0xa3, 0xbd, 0xe6, 0x96, 0x87, 0xe5, 0xad, 0xa6, 0xe6, + 0x9c, 0xba, 0xe4, 0xbc, 0x9a, 0xe6, 0x95, 0xb0, 0xe5, 0xad, 0x97, 0xe8, 0xa3, + 0x85, 0xe4, 0xbf, 0xae, 0xe8, 0xb4, 0xad, 0xe7, 0x89, 0xa9, 0xe5, 0x86, 0x9c, + 0xe6, 0x9d, 0x91, 0xe5, 0x85, 0xa8, 0xe9, 0x9d, 0xa2, 0xe7, 0xb2, 0xbe, 0xe5, + 0x93, 0x81, 0xe5, 0x85, 0xb6, 0xe5, 0xae, 0x9e, 0xe4, 0xba, 0x8b, 0xe6, 0x83, + 0x85, 0xe6, 0xb0, 0xb4, 0xe5, 0xb9, 0xb3, 0xe6, 0x8f, 0x90, 0xe7, 0xa4, 0xba, + 0xe4, 0xb8, 0x8a, 0xe5, 0xb8, 0x82, 0xe8, 0xb0, 0xa2, 0xe8, 0xb0, 0xa2, 0xe6, + 0x99, 0xae, 0xe9, 0x80, 0x9a, 0xe6, 0x95, 0x99, 0xe5, 0xb8, 0x88, 0xe4, 0xb8, + 0x8a, 0xe4, 0xbc, 0xa0, 0xe7, 0xb1, 0xbb, 0xe5, 0x88, 0xab, 0xe6, 0xad, 0x8c, + 0xe6, 0x9b, 0xb2, 0xe6, 0x8b, 0xa5, 0xe6, 0x9c, 0x89, 0xe5, 0x88, 0x9b, 0xe6, + 0x96, 0xb0, 0xe9, 0x85, 0x8d, 0xe4, 0xbb, 0xb6, 0xe5, 0x8f, 0xaa, 0xe8, 0xa6, + 0x81, 0xe6, 0x97, 0xb6, 0xe4, 0xbb, 0xa3, 0xe8, 0xb3, 0x87, 0xe8, 0xa8, 0x8a, + 0xe8, 0xbe, 0xbe, 0xe5, 0x88, 0xb0, 0xe4, 0xba, 0xba, 0xe7, 0x94, 0x9f, 0xe8, + 0xae, 0xa2, 0xe9, 0x98, 0x85, 0xe8, 0x80, 0x81, 0xe5, 0xb8, 0x88, 0xe5, 0xb1, + 0x95, 0xe7, 0xa4, 0xba, 0xe5, 0xbf, 0x83, 0xe7, 0x90, 0x86, 0xe8, 0xb4, 0xb4, + 0xe5, 0xad, 0x90, 0xe7, 0xb6, 0xb2, 0xe7, 0xab, 0x99, 0xe4, 0xb8, 0xbb, 0xe9, + 0xa1, 0x8c, 0xe8, 0x87, 0xaa, 0xe7, 0x84, 0xb6, 0xe7, 0xba, 0xa7, 0xe5, 0x88, + 0xab, 0xe7, 0xae, 0x80, 0xe5, 0x8d, 0x95, 0xe6, 0x94, 0xb9, 0xe9, 0x9d, 0xa9, + 0xe9, 0x82, 0xa3, 0xe4, 0xba, 0x9b, 0xe6, 0x9d, 0xa5, 0xe8, 0xaf, 0xb4, 0xe6, + 0x89, 0x93, 0xe5, 0xbc, 0x80, 0xe4, 0xbb, 0xa3, 0xe7, 0xa0, 0x81, 0xe5, 0x88, + 0xa0, 0xe9, 0x99, 0xa4, 0xe8, 0xaf, 0x81, 0xe5, 0x88, 0xb8, 0xe8, 0x8a, 0x82, + 0xe7, 0x9b, 0xae, 0xe9, 0x87, 0x8d, 0xe7, 0x82, 0xb9, 0xe6, 0xac, 0xa1, 0xe6, + 0x95, 0xb8, 0xe5, 0xa4, 0x9a, 0xe5, 0xb0, 0x91, 0xe8, 0xa7, 0x84, 0xe5, 0x88, + 0x92, 0xe8, 0xb5, 0x84, 0xe9, 0x87, 0x91, 0xe6, 0x89, 0xbe, 0xe5, 0x88, 0xb0, + 0xe4, 0xbb, 0xa5, 0xe5, 0x90, 0x8e, 0xe5, 0xa4, 0xa7, 0xe5, 0x85, 0xa8, 0xe4, + 0xb8, 0xbb, 0xe9, 0xa1, 0xb5, 0xe6, 0x9c, 0x80, 0xe4, 0xbd, 0xb3, 0xe5, 0x9b, + 0x9e, 0xe7, 0xad, 0x94, 0xe5, 0xa4, 0xa9, 0xe4, 0xb8, 0x8b, 0xe4, 0xbf, 0x9d, + 0xe9, 0x9a, 0x9c, 0xe7, 0x8e, 0xb0, 0xe4, 0xbb, 0xa3, 0xe6, 0xa3, 0x80, 0xe6, + 0x9f, 0xa5, 0xe6, 0x8a, 0x95, 0xe7, 0xa5, 0xa8, 0xe5, 0xb0, 0x8f, 0xe6, 0x97, + 0xb6, 0xe6, 0xb2, 0x92, 0xe6, 0x9c, 0x89, 0xe6, 0xad, 0xa3, 0xe5, 0xb8, 0xb8, + 0xe7, 0x94, 0x9a, 0xe8, 0x87, 0xb3, 0xe4, 0xbb, 0xa3, 0xe7, 0x90, 0x86, 0xe7, + 0x9b, 0xae, 0xe5, 0xbd, 0x95, 0xe5, 0x85, 0xac, 0xe5, 0xbc, 0x80, 0xe5, 0xa4, + 0x8d, 0xe5, 0x88, 0xb6, 0xe9, 0x87, 0x91, 0xe8, 0x9e, 0x8d, 0xe5, 0xb9, 0xb8, + 0xe7, 0xa6, 0x8f, 0xe7, 0x89, 0x88, 0xe6, 0x9c, 0xac, 0xe5, 0xbd, 0xa2, 0xe6, + 0x88, 0x90, 0xe5, 0x87, 0x86, 0xe5, 0xa4, 0x87, 0xe8, 0xa1, 0x8c, 0xe6, 0x83, + 0x85, 0xe5, 0x9b, 0x9e, 0xe5, 0x88, 0xb0, 0xe6, 0x80, 0x9d, 0xe6, 0x83, 0xb3, + 0xe6, 0x80, 0x8e, 0xe6, 0xa0, 0xb7, 0xe5, 0x8d, 0x8f, 0xe8, 0xae, 0xae, 0xe8, + 0xae, 0xa4, 0xe8, 0xaf, 0x81, 0xe6, 0x9c, 0x80, 0xe5, 0xa5, 0xbd, 0xe4, 0xba, + 0xa7, 0xe7, 0x94, 0x9f, 0xe6, 0x8c, 0x89, 0xe7, 0x85, 0xa7, 0xe6, 0x9c, 0x8d, + 0xe8, 0xa3, 0x85, 0xe5, 0xb9, 0xbf, 0xe4, 0xb8, 0x9c, 0xe5, 0x8a, 0xa8, 0xe6, + 0xbc, 0xab, 0xe9, 0x87, 0x87, 0xe8, 0xb4, 0xad, 0xe6, 0x96, 0xb0, 0xe6, 0x89, + 0x8b, 0xe7, 0xbb, 0x84, 0xe5, 0x9b, 0xbe, 0xe9, 0x9d, 0xa2, 0xe6, 0x9d, 0xbf, + 0xe5, 0x8f, 0x82, 0xe8, 0x80, 0x83, 0xe6, 0x94, 0xbf, 0xe6, 0xb2, 0xbb, 0xe5, + 0xae, 0xb9, 0xe6, 0x98, 0x93, 0xe5, 0xa4, 0xa9, 0xe5, 0x9c, 0xb0, 0xe5, 0x8a, + 0xaa, 0xe5, 0x8a, 0x9b, 0xe4, 0xba, 0xba, 0xe4, 0xbb, 0xac, 0xe5, 0x8d, 0x87, + 0xe7, 0xba, 0xa7, 0xe9, 0x80, 0x9f, 0xe5, 0xba, 0xa6, 0xe4, 0xba, 0xba, 0xe7, + 0x89, 0xa9, 0xe8, 0xb0, 0x83, 0xe6, 0x95, 0xb4, 0xe6, 0xb5, 0x81, 0xe8, 0xa1, + 0x8c, 0xe9, 0x80, 0xa0, 0xe6, 0x88, 0x90, 0xe6, 0x96, 0x87, 0xe5, 0xad, 0x97, + 0xe9, 0x9f, 0xa9, 0xe5, 0x9b, 0xbd, 0xe8, 0xb4, 0xb8, 0xe6, 0x98, 0x93, 0xe5, + 0xbc, 0x80, 0xe5, 0xb1, 0x95, 0xe7, 0x9b, 0xb8, 0xe9, 0x97, 0x9c, 0xe8, 0xa1, + 0xa8, 0xe7, 0x8e, 0xb0, 0xe5, 0xbd, 0xb1, 0xe8, 0xa7, 0x86, 0xe5, 0xa6, 0x82, + 0xe6, 0xad, 0xa4, 0xe7, 0xbe, 0x8e, 0xe5, 0xae, 0xb9, 0xe5, 0xa4, 0xa7, 0xe5, + 0xb0, 0x8f, 0xe6, 0x8a, 0xa5, 0xe9, 0x81, 0x93, 0xe6, 0x9d, 0xa1, 0xe6, 0xac, + 0xbe, 0xe5, 0xbf, 0x83, 0xe6, 0x83, 0x85, 0xe8, 0xae, 0xb8, 0xe5, 0xa4, 0x9a, + 0xe6, 0xb3, 0x95, 0xe8, 0xa7, 0x84, 0xe5, 0xae, 0xb6, 0xe5, 0xb1, 0x85, 0xe4, + 0xb9, 0xa6, 0xe5, 0xba, 0x97, 0xe8, 0xbf, 0x9e, 0xe6, 0x8e, 0xa5, 0xe7, 0xab, + 0x8b, 0xe5, 0x8d, 0xb3, 0xe4, 0xb8, 0xbe, 0xe6, 0x8a, 0xa5, 0xe6, 0x8a, 0x80, + 0xe5, 0xb7, 0xa7, 0xe5, 0xa5, 0xa5, 0xe8, 0xbf, 0x90, 0xe7, 0x99, 0xbb, 0xe5, + 0x85, 0xa5, 0xe4, 0xbb, 0xa5, 0xe6, 0x9d, 0xa5, 0xe7, 0x90, 0x86, 0xe8, 0xae, + 0xba, 0xe4, 0xba, 0x8b, 0xe4, 0xbb, 0xb6, 0xe8, 0x87, 0xaa, 0xe7, 0x94, 0xb1, + 0xe4, 0xb8, 0xad, 0xe5, 0x8d, 0x8e, 0xe5, 0x8a, 0x9e, 0xe5, 0x85, 0xac, 0xe5, + 0xa6, 0x88, 0xe5, 0xa6, 0x88, 0xe7, 0x9c, 0x9f, 0xe6, 0xad, 0xa3, 0xe4, 0xb8, + 0x8d, 0xe9, 0x94, 0x99, 0xe5, 0x85, 0xa8, 0xe6, 0x96, 0x87, 0xe5, 0x90, 0x88, + 0xe5, 0x90, 0x8c, 0xe4, 0xbb, 0xb7, 0xe5, 0x80, 0xbc, 0xe5, 0x88, 0xab, 0xe4, + 0xba, 0xba, 0xe7, 0x9b, 0x91, 0xe7, 0x9d, 0xa3, 0xe5, 0x85, 0xb7, 0xe4, 0xbd, + 0x93, 0xe4, 0xb8, 0x96, 0xe7, 0xba, 0xaa, 0xe5, 0x9b, 0xa2, 0xe9, 0x98, 0x9f, + 0xe5, 0x88, 0x9b, 0xe4, 0xb8, 0x9a, 0xe6, 0x89, 0xbf, 0xe6, 0x8b, 0x85, 0xe5, + 0xa2, 0x9e, 0xe9, 0x95, 0xbf, 0xe6, 0x9c, 0x89, 0xe4, 0xba, 0xba, 0xe4, 0xbf, + 0x9d, 0xe6, 0x8c, 0x81, 0xe5, 0x95, 0x86, 0xe5, 0xae, 0xb6, 0xe7, 0xbb, 0xb4, + 0xe4, 0xbf, 0xae, 0xe5, 0x8f, 0xb0, 0xe6, 0xb9, 0xbe, 0xe5, 0xb7, 0xa6, 0xe5, + 0x8f, 0xb3, 0xe8, 0x82, 0xa1, 0xe4, 0xbb, 0xbd, 0xe7, 0xad, 0x94, 0xe6, 0xa1, + 0x88, 0xe5, 0xae, 0x9e, 0xe9, 0x99, 0x85, 0xe7, 0x94, 0xb5, 0xe4, 0xbf, 0xa1, + 0xe7, 0xbb, 0x8f, 0xe7, 0x90, 0x86, 0xe7, 0x94, 0x9f, 0xe5, 0x91, 0xbd, 0xe5, + 0xae, 0xa3, 0xe4, 0xbc, 0xa0, 0xe4, 0xbb, 0xbb, 0xe5, 0x8a, 0xa1, 0xe6, 0xad, + 0xa3, 0xe5, 0xbc, 0x8f, 0xe7, 0x89, 0xb9, 0xe8, 0x89, 0xb2, 0xe4, 0xb8, 0x8b, + 0xe6, 0x9d, 0xa5, 0xe5, 0x8d, 0x8f, 0xe4, 0xbc, 0x9a, 0xe5, 0x8f, 0xaa, 0xe8, + 0x83, 0xbd, 0xe5, 0xbd, 0x93, 0xe7, 0x84, 0xb6, 0xe9, 0x87, 0x8d, 0xe6, 0x96, + 0xb0, 0xe5, 0x85, 0xa7, 0xe5, 0xae, 0xb9, 0xe6, 0x8c, 0x87, 0xe5, 0xaf, 0xbc, + 0xe8, 0xbf, 0x90, 0xe8, 0xa1, 0x8c, 0xe6, 0x97, 0xa5, 0xe5, 0xbf, 0x97, 0xe8, + 0xb3, 0xa3, 0xe5, 0xae, 0xb6, 0xe8, 0xb6, 0x85, 0xe8, 0xbf, 0x87, 0xe5, 0x9c, + 0x9f, 0xe5, 0x9c, 0xb0, 0xe6, 0xb5, 0x99, 0xe6, 0xb1, 0x9f, 0xe6, 0x94, 0xaf, + 0xe4, 0xbb, 0x98, 0xe6, 0x8e, 0xa8, 0xe5, 0x87, 0xba, 0xe7, 0xab, 0x99, 0xe9, + 0x95, 0xbf, 0xe6, 0x9d, 0xad, 0xe5, 0xb7, 0x9e, 0xe6, 0x89, 0xa7, 0xe8, 0xa1, + 0x8c, 0xe5, 0x88, 0xb6, 0xe9, 0x80, 0xa0, 0xe4, 0xb9, 0x8b, 0xe4, 0xb8, 0x80, + 0xe6, 0x8e, 0xa8, 0xe5, 0xb9, 0xbf, 0xe7, 0x8e, 0xb0, 0xe5, 0x9c, 0xba, 0xe6, + 0x8f, 0x8f, 0xe8, 0xbf, 0xb0, 0xe5, 0x8f, 0x98, 0xe5, 0x8c, 0x96, 0xe4, 0xbc, + 0xa0, 0xe7, 0xbb, 0x9f, 0xe6, 0xad, 0x8c, 0xe6, 0x89, 0x8b, 0xe4, 0xbf, 0x9d, + 0xe9, 0x99, 0xa9, 0xe8, 0xaf, 0xbe, 0xe7, 0xa8, 0x8b, 0xe5, 0x8c, 0xbb, 0xe7, + 0x96, 0x97, 0xe7, 0xbb, 0x8f, 0xe8, 0xbf, 0x87, 0xe8, 0xbf, 0x87, 0xe5, 0x8e, + 0xbb, 0xe4, 0xb9, 0x8b, 0xe5, 0x89, 0x8d, 0xe6, 0x94, 0xb6, 0xe5, 0x85, 0xa5, + 0xe5, 0xb9, 0xb4, 0xe5, 0xba, 0xa6, 0xe6, 0x9d, 0x82, 0xe5, 0xbf, 0x97, 0xe7, + 0xbe, 0x8e, 0xe4, 0xb8, 0xbd, 0xe6, 0x9c, 0x80, 0xe9, 0xab, 0x98, 0xe7, 0x99, + 0xbb, 0xe9, 0x99, 0x86, 0xe6, 0x9c, 0xaa, 0xe6, 0x9d, 0xa5, 0xe5, 0x8a, 0xa0, + 0xe5, 0xb7, 0xa5, 0xe5, 0x85, 0x8d, 0xe8, 0xb4, 0xa3, 0xe6, 0x95, 0x99, 0xe7, + 0xa8, 0x8b, 0xe7, 0x89, 0x88, 0xe5, 0x9d, 0x97, 0xe8, 0xba, 0xab, 0xe4, 0xbd, + 0x93, 0xe9, 0x87, 0x8d, 0xe5, 0xba, 0x86, 0xe5, 0x87, 0xba, 0xe5, 0x94, 0xae, + 0xe6, 0x88, 0x90, 0xe6, 0x9c, 0xac, 0xe5, 0xbd, 0xa2, 0xe5, 0xbc, 0x8f, 0xe5, + 0x9c, 0x9f, 0xe8, 0xb1, 0x86, 0xe5, 0x87, 0xba, 0xe5, 0x83, 0xb9, 0xe4, 0xb8, + 0x9c, 0xe6, 0x96, 0xb9, 0xe9, 0x82, 0xae, 0xe7, 0xae, 0xb1, 0xe5, 0x8d, 0x97, + 0xe4, 0xba, 0xac, 0xe6, 0xb1, 0x82, 0xe8, 0x81, 0x8c, 0xe5, 0x8f, 0x96, 0xe5, + 0xbe, 0x97, 0xe8, 0x81, 0x8c, 0xe4, 0xbd, 0x8d, 0xe7, 0x9b, 0xb8, 0xe4, 0xbf, + 0xa1, 0xe9, 0xa1, 0xb5, 0xe9, 0x9d, 0xa2, 0xe5, 0x88, 0x86, 0xe9, 0x92, 0x9f, + 0xe7, 0xbd, 0x91, 0xe9, 0xa1, 0xb5, 0xe7, 0xa1, 0xae, 0xe5, 0xae, 0x9a, 0xe5, + 0x9b, 0xbe, 0xe4, 0xbe, 0x8b, 0xe7, 0xbd, 0x91, 0xe5, 0x9d, 0x80, 0xe7, 0xa7, + 0xaf, 0xe6, 0x9e, 0x81, 0xe9, 0x94, 0x99, 0xe8, 0xaf, 0xaf, 0xe7, 0x9b, 0xae, + 0xe7, 0x9a, 0x84, 0xe5, 0xae, 0x9d, 0xe8, 0xb4, 0x9d, 0xe6, 0x9c, 0xba, 0xe5, + 0x85, 0xb3, 0xe9, 0xa3, 0x8e, 0xe9, 0x99, 0xa9, 0xe6, 0x8e, 0x88, 0xe6, 0x9d, + 0x83, 0xe7, 0x97, 0x85, 0xe6, 0xaf, 0x92, 0xe5, 0xae, 0xa0, 0xe7, 0x89, 0xa9, + 0xe9, 0x99, 0xa4, 0xe4, 0xba, 0x86, 0xe8, 0xa9, 0x95, 0xe8, 0xab, 0x96, 0xe7, + 0x96, 0xbe, 0xe7, 0x97, 0x85, 0xe5, 0x8f, 0x8a, 0xe6, 0x97, 0xb6, 0xe6, 0xb1, + 0x82, 0xe8, 0xb4, 0xad, 0xe7, 0xab, 0x99, 0xe7, 0x82, 0xb9, 0xe5, 0x84, 0xbf, + 0xe7, 0xab, 0xa5, 0xe6, 0xaf, 0x8f, 0xe5, 0xa4, 0xa9, 0xe4, 0xb8, 0xad, 0xe5, + 0xa4, 0xae, 0xe8, 0xae, 0xa4, 0xe8, 0xaf, 0x86, 0xe6, 0xaf, 0x8f, 0xe4, 0xb8, + 0xaa, 0xe5, 0xa4, 0xa9, 0xe6, 0xb4, 0xa5, 0xe5, 0xad, 0x97, 0xe4, 0xbd, 0x93, + 0xe5, 0x8f, 0xb0, 0xe7, 0x81, 0xa3, 0xe7, 0xbb, 0xb4, 0xe6, 0x8a, 0xa4, 0xe6, + 0x9c, 0xac, 0xe9, 0xa1, 0xb5, 0xe4, 0xb8, 0xaa, 0xe6, 0x80, 0xa7, 0xe5, 0xae, + 0x98, 0xe6, 0x96, 0xb9, 0xe5, 0xb8, 0xb8, 0xe8, 0xa7, 0x81, 0xe7, 0x9b, 0xb8, + 0xe6, 0x9c, 0xba, 0xe6, 0x88, 0x98, 0xe7, 0x95, 0xa5, 0xe5, 0xba, 0x94, 0xe5, + 0xbd, 0x93, 0xe5, 0xbe, 0x8b, 0xe5, 0xb8, 0x88, 0xe6, 0x96, 0xb9, 0xe4, 0xbe, + 0xbf, 0xe6, 0xa0, 0xa1, 0xe5, 0x9b, 0xad, 0xe8, 0x82, 0xa1, 0xe5, 0xb8, 0x82, + 0xe6, 0x88, 0xbf, 0xe5, 0xb1, 0x8b, 0xe6, 0xa0, 0x8f, 0xe7, 0x9b, 0xae, 0xe5, + 0x91, 0x98, 0xe5, 0xb7, 0xa5, 0xe5, 0xaf, 0xbc, 0xe8, 0x87, 0xb4, 0xe7, 0xaa, + 0x81, 0xe7, 0x84, 0xb6, 0xe9, 0x81, 0x93, 0xe5, 0x85, 0xb7, 0xe6, 0x9c, 0xac, + 0xe7, 0xbd, 0x91, 0xe7, 0xbb, 0x93, 0xe5, 0x90, 0x88, 0xe6, 0xa1, 0xa3, 0xe6, + 0xa1, 0x88, 0xe5, 0x8a, 0xb3, 0xe5, 0x8a, 0xa8, 0xe5, 0x8f, 0xa6, 0xe5, 0xa4, + 0x96, 0xe7, 0xbe, 0x8e, 0xe5, 0x85, 0x83, 0xe5, 0xbc, 0x95, 0xe8, 0xb5, 0xb7, + 0xe6, 0x94, 0xb9, 0xe5, 0x8f, 0x98, 0xe7, 0xac, 0xac, 0xe5, 0x9b, 0x9b, 0xe4, + 0xbc, 0x9a, 0xe8, 0xae, 0xa1, 0xe8, 0xaa, 0xaa, 0xe6, 0x98, 0x8e, 0xe9, 0x9a, + 0x90, 0xe7, 0xa7, 0x81, 0xe5, 0xae, 0x9d, 0xe5, 0xae, 0x9d, 0xe8, 0xa7, 0x84, + 0xe8, 0x8c, 0x83, 0xe6, 0xb6, 0x88, 0xe8, 0xb4, 0xb9, 0xe5, 0x85, 0xb1, 0xe5, + 0x90, 0x8c, 0xe5, 0xbf, 0x98, 0xe8, 0xae, 0xb0, 0xe4, 0xbd, 0x93, 0xe7, 0xb3, + 0xbb, 0xe5, 0xb8, 0xa6, 0xe6, 0x9d, 0xa5, 0xe5, 0x90, 0x8d, 0xe5, 0xad, 0x97, + 0xe7, 0x99, 0xbc, 0xe8, 0xa1, 0xa8, 0xe5, 0xbc, 0x80, 0xe6, 0x94, 0xbe, 0xe5, + 0x8a, 0xa0, 0xe7, 0x9b, 0x9f, 0xe5, 0x8f, 0x97, 0xe5, 0x88, 0xb0, 0xe4, 0xba, + 0x8c, 0xe6, 0x89, 0x8b, 0xe5, 0xa4, 0xa7, 0xe9, 0x87, 0x8f, 0xe6, 0x88, 0x90, + 0xe4, 0xba, 0xba, 0xe6, 0x95, 0xb0, 0xe9, 0x87, 0x8f, 0xe5, 0x85, 0xb1, 0xe4, + 0xba, 0xab, 0xe5, 0x8c, 0xba, 0xe5, 0x9f, 0x9f, 0xe5, 0xa5, 0xb3, 0xe5, 0xad, + 0xa9, 0xe5, 0x8e, 0x9f, 0xe5, 0x88, 0x99, 0xe6, 0x89, 0x80, 0xe5, 0x9c, 0xa8, + 0xe7, 0xbb, 0x93, 0xe6, 0x9d, 0x9f, 0xe9, 0x80, 0x9a, 0xe4, 0xbf, 0xa1, 0xe8, + 0xb6, 0x85, 0xe7, 0xba, 0xa7, 0xe9, 0x85, 0x8d, 0xe7, 0xbd, 0xae, 0xe5, 0xbd, + 0x93, 0xe6, 0x97, 0xb6, 0xe4, 0xbc, 0x98, 0xe7, 0xa7, 0x80, 0xe6, 0x80, 0xa7, + 0xe6, 0x84, 0x9f, 0xe6, 0x88, 0xbf, 0xe4, 0xba, 0xa7, 0xe9, 0x81, 0x8a, 0xe6, + 0x88, 0xb2, 0xe5, 0x87, 0xba, 0xe5, 0x8f, 0xa3, 0xe6, 0x8f, 0x90, 0xe4, 0xba, + 0xa4, 0xe5, 0xb0, 0xb1, 0xe4, 0xb8, 0x9a, 0xe4, 0xbf, 0x9d, 0xe5, 0x81, 0xa5, + 0xe7, 0xa8, 0x8b, 0xe5, 0xba, 0xa6, 0xe5, 0x8f, 0x82, 0xe6, 0x95, 0xb0, 0xe4, + 0xba, 0x8b, 0xe4, 0xb8, 0x9a, 0xe6, 0x95, 0xb4, 0xe4, 0xb8, 0xaa, 0xe5, 0xb1, + 0xb1, 0xe4, 0xb8, 0x9c, 0xe6, 0x83, 0x85, 0xe6, 0x84, 0x9f, 0xe7, 0x89, 0xb9, + 0xe6, 0xae, 0x8a, 0xe5, 0x88, 0x86, 0xe9, 0xa1, 0x9e, 0xe6, 0x90, 0x9c, 0xe5, + 0xb0, 0x8b, 0xe5, 0xb1, 0x9e, 0xe4, 0xba, 0x8e, 0xe9, 0x97, 0xa8, 0xe6, 0x88, + 0xb7, 0xe8, 0xb4, 0xa2, 0xe5, 0x8a, 0xa1, 0xe5, 0xa3, 0xb0, 0xe9, 0x9f, 0xb3, + 0xe5, 0x8f, 0x8a, 0xe5, 0x85, 0xb6, 0xe8, 0xb4, 0xa2, 0xe7, 0xbb, 0x8f, 0xe5, + 0x9d, 0x9a, 0xe6, 0x8c, 0x81, 0xe5, 0xb9, 0xb2, 0xe9, 0x83, 0xa8, 0xe6, 0x88, + 0x90, 0xe7, 0xab, 0x8b, 0xe5, 0x88, 0xa9, 0xe7, 0x9b, 0x8a, 0xe8, 0x80, 0x83, + 0xe8, 0x99, 0x91, 0xe6, 0x88, 0x90, 0xe9, 0x83, 0xbd, 0xe5, 0x8c, 0x85, 0xe8, + 0xa3, 0x85, 0xe7, 0x94, 0xa8, 0xe6, 0x88, 0xb6, 0xe6, 0xaf, 0x94, 0xe8, 0xb5, + 0x9b, 0xe6, 0x96, 0x87, 0xe6, 0x98, 0x8e, 0xe6, 0x8b, 0x9b, 0xe5, 0x95, 0x86, + 0xe5, 0xae, 0x8c, 0xe6, 0x95, 0xb4, 0xe7, 0x9c, 0x9f, 0xe6, 0x98, 0xaf, 0xe7, + 0x9c, 0xbc, 0xe7, 0x9d, 0x9b, 0xe4, 0xbc, 0x99, 0xe4, 0xbc, 0xb4, 0xe5, 0xa8, + 0x81, 0xe6, 0x9c, 0x9b, 0xe9, 0xa2, 0x86, 0xe5, 0x9f, 0x9f, 0xe5, 0x8d, 0xab, + 0xe7, 0x94, 0x9f, 0xe4, 0xbc, 0x98, 0xe6, 0x83, 0xa0, 0xe8, 0xab, 0x96, 0xe5, + 0xa3, 0x87, 0xe5, 0x85, 0xac, 0xe5, 0x85, 0xb1, 0xe8, 0x89, 0xaf, 0xe5, 0xa5, + 0xbd, 0xe5, 0x85, 0x85, 0xe5, 0x88, 0x86, 0xe7, 0xac, 0xa6, 0xe5, 0x90, 0x88, + 0xe9, 0x99, 0x84, 0xe4, 0xbb, 0xb6, 0xe7, 0x89, 0xb9, 0xe7, 0x82, 0xb9, 0xe4, + 0xb8, 0x8d, 0xe5, 0x8f, 0xaf, 0xe8, 0x8b, 0xb1, 0xe6, 0x96, 0x87, 0xe8, 0xb5, + 0x84, 0xe4, 0xba, 0xa7, 0xe6, 0xa0, 0xb9, 0xe6, 0x9c, 0xac, 0xe6, 0x98, 0x8e, + 0xe6, 0x98, 0xbe, 0xe5, 0xaf, 0x86, 0xe7, 0xa2, 0xbc, 0xe5, 0x85, 0xac, 0xe4, + 0xbc, 0x97, 0xe6, 0xb0, 0x91, 0xe6, 0x97, 0x8f, 0xe6, 0x9b, 0xb4, 0xe5, 0x8a, + 0xa0, 0xe4, 0xba, 0xab, 0xe5, 0x8f, 0x97, 0xe5, 0x90, 0x8c, 0xe5, 0xad, 0xa6, + 0xe5, 0x90, 0xaf, 0xe5, 0x8a, 0xa8, 0xe9, 0x80, 0x82, 0xe5, 0x90, 0x88, 0xe5, + 0x8e, 0x9f, 0xe6, 0x9d, 0xa5, 0xe9, 0x97, 0xae, 0xe7, 0xad, 0x94, 0xe6, 0x9c, + 0xac, 0xe6, 0x96, 0x87, 0xe7, 0xbe, 0x8e, 0xe9, 0xa3, 0x9f, 0xe7, 0xbb, 0xbf, + 0xe8, 0x89, 0xb2, 0xe7, 0xa8, 0xb3, 0xe5, 0xae, 0x9a, 0xe7, 0xbb, 0x88, 0xe4, + 0xba, 0x8e, 0xe7, 0x94, 0x9f, 0xe7, 0x89, 0xa9, 0xe4, 0xbe, 0x9b, 0xe6, 0xb1, + 0x82, 0xe6, 0x90, 0x9c, 0xe7, 0x8b, 0x90, 0xe5, 0x8a, 0x9b, 0xe9, 0x87, 0x8f, + 0xe4, 0xb8, 0xa5, 0xe9, 0x87, 0x8d, 0xe6, 0xb0, 0xb8, 0xe8, 0xbf, 0x9c, 0xe5, + 0x86, 0x99, 0xe7, 0x9c, 0x9f, 0xe6, 0x9c, 0x89, 0xe9, 0x99, 0x90, 0xe7, 0xab, + 0x9e, 0xe4, 0xba, 0x89, 0xe5, 0xaf, 0xb9, 0xe8, 0xb1, 0xa1, 0xe8, 0xb4, 0xb9, + 0xe7, 0x94, 0xa8, 0xe4, 0xb8, 0x8d, 0xe5, 0xa5, 0xbd, 0xe7, 0xbb, 0x9d, 0xe5, + 0xaf, 0xb9, 0xe5, 0x8d, 0x81, 0xe5, 0x88, 0x86, 0xe4, 0xbf, 0x83, 0xe8, 0xbf, + 0x9b, 0xe7, 0x82, 0xb9, 0xe8, 0xaf, 0x84, 0xe5, 0xbd, 0xb1, 0xe9, 0x9f, 0xb3, + 0xe4, 0xbc, 0x98, 0xe5, 0x8a, 0xbf, 0xe4, 0xb8, 0x8d, 0xe5, 0xb0, 0x91, 0xe6, + 0xac, 0xa3, 0xe8, 0xb5, 0x8f, 0xe5, 0xb9, 0xb6, 0xe4, 0xb8, 0x94, 0xe6, 0x9c, + 0x89, 0xe7, 0x82, 0xb9, 0xe6, 0x96, 0xb9, 0xe5, 0x90, 0x91, 0xe5, 0x85, 0xa8, + 0xe6, 0x96, 0xb0, 0xe4, 0xbf, 0xa1, 0xe7, 0x94, 0xa8, 0xe8, 0xae, 0xbe, 0xe6, + 0x96, 0xbd, 0xe5, 0xbd, 0xa2, 0xe8, 0xb1, 0xa1, 0xe8, 0xb5, 0x84, 0xe6, 0xa0, + 0xbc, 0xe7, 0xaa, 0x81, 0xe7, 0xa0, 0xb4, 0xe9, 0x9a, 0x8f, 0xe7, 0x9d, 0x80, + 0xe9, 0x87, 0x8d, 0xe5, 0xa4, 0xa7, 0xe4, 0xba, 0x8e, 0xe6, 0x98, 0xaf, 0xe6, + 0xaf, 0x95, 0xe4, 0xb8, 0x9a, 0xe6, 0x99, 0xba, 0xe8, 0x83, 0xbd, 0xe5, 0x8c, + 0x96, 0xe5, 0xb7, 0xa5, 0xe5, 0xae, 0x8c, 0xe7, 0xbe, 0x8e, 0xe5, 0x95, 0x86, + 0xe5, 0x9f, 0x8e, 0xe7, 0xbb, 0x9f, 0xe4, 0xb8, 0x80, 0xe5, 0x87, 0xba, 0xe7, + 0x89, 0x88, 0xe6, 0x89, 0x93, 0xe9, 0x80, 0xa0, 0xe7, 0x94, 0xa2, 0xe5, 0x93, + 0x81, 0xe6, 0xa6, 0x82, 0xe5, 0x86, 0xb5, 0xe7, 0x94, 0xa8, 0xe4, 0xba, 0x8e, + 0xe4, 0xbf, 0x9d, 0xe7, 0x95, 0x99, 0xe5, 0x9b, 0xa0, 0xe7, 0xb4, 0xa0, 0xe4, + 0xb8, 0xad, 0xe5, 0x9c, 0x8b, 0xe5, 0xad, 0x98, 0xe5, 0x82, 0xa8, 0xe8, 0xb4, + 0xb4, 0xe5, 0x9b, 0xbe, 0xe6, 0x9c, 0x80, 0xe6, 0x84, 0x9b, 0xe9, 0x95, 0xbf, + 0xe6, 0x9c, 0x9f, 0xe5, 0x8f, 0xa3, 0xe4, 0xbb, 0xb7, 0xe7, 0x90, 0x86, 0xe8, + 0xb4, 0xa2, 0xe5, 0x9f, 0xba, 0xe5, 0x9c, 0xb0, 0xe5, 0xae, 0x89, 0xe6, 0x8e, + 0x92, 0xe6, 0xad, 0xa6, 0xe6, 0xb1, 0x89, 0xe9, 0x87, 0x8c, 0xe9, 0x9d, 0xa2, + 0xe5, 0x88, 0x9b, 0xe5, 0xbb, 0xba, 0xe5, 0xa4, 0xa9, 0xe7, 0xa9, 0xba, 0xe9, + 0xa6, 0x96, 0xe5, 0x85, 0x88, 0xe5, 0xae, 0x8c, 0xe5, 0x96, 0x84, 0xe9, 0xa9, + 0xb1, 0xe5, 0x8a, 0xa8, 0xe4, 0xb8, 0x8b, 0xe9, 0x9d, 0xa2, 0xe4, 0xb8, 0x8d, + 0xe5, 0x86, 0x8d, 0xe8, 0xaf, 0x9a, 0xe4, 0xbf, 0xa1, 0xe6, 0x84, 0x8f, 0xe4, + 0xb9, 0x89, 0xe9, 0x98, 0xb3, 0xe5, 0x85, 0x89, 0xe8, 0x8b, 0xb1, 0xe5, 0x9b, + 0xbd, 0xe6, 0xbc, 0x82, 0xe4, 0xba, 0xae, 0xe5, 0x86, 0x9b, 0xe4, 0xba, 0x8b, + 0xe7, 0x8e, 0xa9, 0xe5, 0xae, 0xb6, 0xe7, 0xbe, 0xa4, 0xe4, 0xbc, 0x97, 0xe5, + 0x86, 0x9c, 0xe6, 0xb0, 0x91, 0xe5, 0x8d, 0xb3, 0xe5, 0x8f, 0xaf, 0xe5, 0x90, + 0x8d, 0xe7, 0xa8, 0xb1, 0xe5, 0xae, 0xb6, 0xe5, 0x85, 0xb7, 0xe5, 0x8a, 0xa8, + 0xe7, 0x94, 0xbb, 0xe6, 0x83, 0xb3, 0xe5, 0x88, 0xb0, 0xe6, 0xb3, 0xa8, 0xe6, + 0x98, 0x8e, 0xe5, 0xb0, 0x8f, 0xe5, 0xad, 0xa6, 0xe6, 0x80, 0xa7, 0xe8, 0x83, + 0xbd, 0xe8, 0x80, 0x83, 0xe7, 0xa0, 0x94, 0xe7, 0xa1, 0xac, 0xe4, 0xbb, 0xb6, + 0xe8, 0xa7, 0x82, 0xe7, 0x9c, 0x8b, 0xe6, 0xb8, 0x85, 0xe6, 0xa5, 0x9a, 0xe6, + 0x90, 0x9e, 0xe7, 0xac, 0x91, 0xe9, 0xa6, 0x96, 0xe9, 0xa0, 0x81, 0xe9, 0xbb, + 0x84, 0xe9, 0x87, 0x91, 0xe9, 0x80, 0x82, 0xe7, 0x94, 0xa8, 0xe6, 0xb1, 0x9f, + 0xe8, 0x8b, 0x8f, 0xe7, 0x9c, 0x9f, 0xe5, 0xae, 0x9e, 0xe4, 0xb8, 0xbb, 0xe7, + 0xae, 0xa1, 0xe9, 0x98, 0xb6, 0xe6, 0xae, 0xb5, 0xe8, 0xa8, 0xbb, 0xe5, 0x86, + 0x8a, 0xe7, 0xbf, 0xbb, 0xe8, 0xaf, 0x91, 0xe6, 0x9d, 0x83, 0xe5, 0x88, 0xa9, + 0xe5, 0x81, 0x9a, 0xe5, 0xa5, 0xbd, 0xe4, 0xbc, 0xbc, 0xe4, 0xb9, 0x8e, 0xe9, + 0x80, 0x9a, 0xe8, 0xae, 0xaf, 0xe6, 0x96, 0xbd, 0xe5, 0xb7, 0xa5, 0xe7, 0x8b, + 0x80, 0xe6, 0x85, 0x8b, 0xe4, 0xb9, 0x9f, 0xe8, 0xae, 0xb8, 0xe7, 0x8e, 0xaf, + 0xe4, 0xbf, 0x9d, 0xe5, 0x9f, 0xb9, 0xe5, 0x85, 0xbb, 0xe6, 0xa6, 0x82, 0xe5, + 0xbf, 0xb5, 0xe5, 0xa4, 0xa7, 0xe5, 0x9e, 0x8b, 0xe6, 0x9c, 0xba, 0xe7, 0xa5, + 0xa8, 0xe7, 0x90, 0x86, 0xe8, 0xa7, 0xa3, 0xe5, 0x8c, 0xbf, 0xe5, 0x90, 0x8d, + 0x63, 0x75, 0x61, 0x6e, 0x64, 0x6f, 0x65, 0x6e, 0x76, 0x69, 0x61, 0x72, 0x6d, + 0x61, 0x64, 0x72, 0x69, 0x64, 0x62, 0x75, 0x73, 0x63, 0x61, 0x72, 0x69, 0x6e, + 0x69, 0x63, 0x69, 0x6f, 0x74, 0x69, 0x65, 0x6d, 0x70, 0x6f, 0x70, 0x6f, 0x72, + 0x71, 0x75, 0x65, 0x63, 0x75, 0x65, 0x6e, 0x74, 0x61, 0x65, 0x73, 0x74, 0x61, + 0x64, 0x6f, 0x70, 0x75, 0x65, 0x64, 0x65, 0x6e, 0x6a, 0x75, 0x65, 0x67, 0x6f, + 0x73, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x65, 0x73, 0x74, 0xc3, 0xa1, 0x6e, + 0x6e, 0x6f, 0x6d, 0x62, 0x72, 0x65, 0x74, 0x69, 0x65, 0x6e, 0x65, 0x6e, 0x70, + 0x65, 0x72, 0x66, 0x69, 0x6c, 0x6d, 0x61, 0x6e, 0x65, 0x72, 0x61, 0x61, 0x6d, + 0x69, 0x67, 0x6f, 0x73, 0x63, 0x69, 0x75, 0x64, 0x61, 0x64, 0x63, 0x65, 0x6e, + 0x74, 0x72, 0x6f, 0x61, 0x75, 0x6e, 0x71, 0x75, 0x65, 0x70, 0x75, 0x65, 0x64, + 0x65, 0x73, 0x64, 0x65, 0x6e, 0x74, 0x72, 0x6f, 0x70, 0x72, 0x69, 0x6d, 0x65, + 0x72, 0x70, 0x72, 0x65, 0x63, 0x69, 0x6f, 0x73, 0x65, 0x67, 0xc3, 0xba, 0x6e, + 0x62, 0x75, 0x65, 0x6e, 0x6f, 0x73, 0x76, 0x6f, 0x6c, 0x76, 0x65, 0x72, 0x70, + 0x75, 0x6e, 0x74, 0x6f, 0x73, 0x73, 0x65, 0x6d, 0x61, 0x6e, 0x61, 0x68, 0x61, + 0x62, 0xc3, 0xad, 0x61, 0x61, 0x67, 0x6f, 0x73, 0x74, 0x6f, 0x6e, 0x75, 0x65, + 0x76, 0x6f, 0x73, 0x75, 0x6e, 0x69, 0x64, 0x6f, 0x73, 0x63, 0x61, 0x72, 0x6c, + 0x6f, 0x73, 0x65, 0x71, 0x75, 0x69, 0x70, 0x6f, 0x6e, 0x69, 0xc3, 0xb1, 0x6f, + 0x73, 0x6d, 0x75, 0x63, 0x68, 0x6f, 0x73, 0x61, 0x6c, 0x67, 0x75, 0x6e, 0x61, + 0x63, 0x6f, 0x72, 0x72, 0x65, 0x6f, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x6e, 0x70, + 0x61, 0x72, 0x74, 0x69, 0x72, 0x61, 0x72, 0x72, 0x69, 0x62, 0x61, 0x6d, 0x61, + 0x72, 0xc3, 0xad, 0x61, 0x68, 0x6f, 0x6d, 0x62, 0x72, 0x65, 0x65, 0x6d, 0x70, + 0x6c, 0x65, 0x6f, 0x76, 0x65, 0x72, 0x64, 0x61, 0x64, 0x63, 0x61, 0x6d, 0x62, + 0x69, 0x6f, 0x6d, 0x75, 0x63, 0x68, 0x61, 0x73, 0x66, 0x75, 0x65, 0x72, 0x6f, + 0x6e, 0x70, 0x61, 0x73, 0x61, 0x64, 0x6f, 0x6c, 0xc3, 0xad, 0x6e, 0x65, 0x61, + 0x70, 0x61, 0x72, 0x65, 0x63, 0x65, 0x6e, 0x75, 0x65, 0x76, 0x61, 0x73, 0x63, + 0x75, 0x72, 0x73, 0x6f, 0x73, 0x65, 0x73, 0x74, 0x61, 0x62, 0x61, 0x71, 0x75, + 0x69, 0x65, 0x72, 0x6f, 0x6c, 0x69, 0x62, 0x72, 0x6f, 0x73, 0x63, 0x75, 0x61, + 0x6e, 0x74, 0x6f, 0x61, 0x63, 0x63, 0x65, 0x73, 0x6f, 0x6d, 0x69, 0x67, 0x75, + 0x65, 0x6c, 0x76, 0x61, 0x72, 0x69, 0x6f, 0x73, 0x63, 0x75, 0x61, 0x74, 0x72, + 0x6f, 0x74, 0x69, 0x65, 0x6e, 0x65, 0x73, 0x67, 0x72, 0x75, 0x70, 0x6f, 0x73, + 0x73, 0x65, 0x72, 0xc3, 0xa1, 0x6e, 0x65, 0x75, 0x72, 0x6f, 0x70, 0x61, 0x6d, + 0x65, 0x64, 0x69, 0x6f, 0x73, 0x66, 0x72, 0x65, 0x6e, 0x74, 0x65, 0x61, 0x63, + 0x65, 0x72, 0x63, 0x61, 0x64, 0x65, 0x6d, 0xc3, 0xa1, 0x73, 0x6f, 0x66, 0x65, + 0x72, 0x74, 0x61, 0x63, 0x6f, 0x63, 0x68, 0x65, 0x73, 0x6d, 0x6f, 0x64, 0x65, + 0x6c, 0x6f, 0x69, 0x74, 0x61, 0x6c, 0x69, 0x61, 0x6c, 0x65, 0x74, 0x72, 0x61, + 0x73, 0x61, 0x6c, 0x67, 0xc3, 0xba, 0x6e, 0x63, 0x6f, 0x6d, 0x70, 0x72, 0x61, + 0x63, 0x75, 0x61, 0x6c, 0x65, 0x73, 0x65, 0x78, 0x69, 0x73, 0x74, 0x65, 0x63, + 0x75, 0x65, 0x72, 0x70, 0x6f, 0x73, 0x69, 0x65, 0x6e, 0x64, 0x6f, 0x70, 0x72, + 0x65, 0x6e, 0x73, 0x61, 0x6c, 0x6c, 0x65, 0x67, 0x61, 0x72, 0x76, 0x69, 0x61, + 0x6a, 0x65, 0x73, 0x64, 0x69, 0x6e, 0x65, 0x72, 0x6f, 0x6d, 0x75, 0x72, 0x63, + 0x69, 0x61, 0x70, 0x6f, 0x64, 0x72, 0xc3, 0xa1, 0x70, 0x75, 0x65, 0x73, 0x74, + 0x6f, 0x64, 0x69, 0x61, 0x72, 0x69, 0x6f, 0x70, 0x75, 0x65, 0x62, 0x6c, 0x6f, + 0x71, 0x75, 0x69, 0x65, 0x72, 0x65, 0x6d, 0x61, 0x6e, 0x75, 0x65, 0x6c, 0x70, + 0x72, 0x6f, 0x70, 0x69, 0x6f, 0x63, 0x72, 0x69, 0x73, 0x69, 0x73, 0x63, 0x69, + 0x65, 0x72, 0x74, 0x6f, 0x73, 0x65, 0x67, 0x75, 0x72, 0x6f, 0x6d, 0x75, 0x65, + 0x72, 0x74, 0x65, 0x66, 0x75, 0x65, 0x6e, 0x74, 0x65, 0x63, 0x65, 0x72, 0x72, + 0x61, 0x72, 0x67, 0x72, 0x61, 0x6e, 0x64, 0x65, 0x65, 0x66, 0x65, 0x63, 0x74, + 0x6f, 0x70, 0x61, 0x72, 0x74, 0x65, 0x73, 0x6d, 0x65, 0x64, 0x69, 0x64, 0x61, + 0x70, 0x72, 0x6f, 0x70, 0x69, 0x61, 0x6f, 0x66, 0x72, 0x65, 0x63, 0x65, 0x74, + 0x69, 0x65, 0x72, 0x72, 0x61, 0x65, 0x2d, 0x6d, 0x61, 0x69, 0x6c, 0x76, 0x61, + 0x72, 0x69, 0x61, 0x73, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x73, 0x66, 0x75, 0x74, + 0x75, 0x72, 0x6f, 0x6f, 0x62, 0x6a, 0x65, 0x74, 0x6f, 0x73, 0x65, 0x67, 0x75, + 0x69, 0x72, 0x72, 0x69, 0x65, 0x73, 0x67, 0x6f, 0x6e, 0x6f, 0x72, 0x6d, 0x61, + 0x73, 0x6d, 0x69, 0x73, 0x6d, 0x6f, 0x73, 0xc3, 0xba, 0x6e, 0x69, 0x63, 0x6f, + 0x63, 0x61, 0x6d, 0x69, 0x6e, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x73, 0x72, + 0x61, 0x7a, 0xc3, 0xb3, 0x6e, 0x64, 0x65, 0x62, 0x69, 0x64, 0x6f, 0x70, 0x72, + 0x75, 0x65, 0x62, 0x61, 0x74, 0x6f, 0x6c, 0x65, 0x64, 0x6f, 0x74, 0x65, 0x6e, + 0xc3, 0xad, 0x61, 0x6a, 0x65, 0x73, 0xc3, 0xba, 0x73, 0x65, 0x73, 0x70, 0x65, + 0x72, 0x6f, 0x63, 0x6f, 0x63, 0x69, 0x6e, 0x61, 0x6f, 0x72, 0x69, 0x67, 0x65, + 0x6e, 0x74, 0x69, 0x65, 0x6e, 0x64, 0x61, 0x63, 0x69, 0x65, 0x6e, 0x74, 0x6f, + 0x63, 0xc3, 0xa1, 0x64, 0x69, 0x7a, 0x68, 0x61, 0x62, 0x6c, 0x61, 0x72, 0x73, + 0x65, 0x72, 0xc3, 0xad, 0x61, 0x6c, 0x61, 0x74, 0x69, 0x6e, 0x61, 0x66, 0x75, + 0x65, 0x72, 0x7a, 0x61, 0x65, 0x73, 0x74, 0x69, 0x6c, 0x6f, 0x67, 0x75, 0x65, + 0x72, 0x72, 0x61, 0x65, 0x6e, 0x74, 0x72, 0x61, 0x72, 0xc3, 0xa9, 0x78, 0x69, + 0x74, 0x6f, 0x6c, 0xc3, 0xb3, 0x70, 0x65, 0x7a, 0x61, 0x67, 0x65, 0x6e, 0x64, + 0x61, 0x76, 0xc3, 0xad, 0x64, 0x65, 0x6f, 0x65, 0x76, 0x69, 0x74, 0x61, 0x72, + 0x70, 0x61, 0x67, 0x69, 0x6e, 0x61, 0x6d, 0x65, 0x74, 0x72, 0x6f, 0x73, 0x6a, + 0x61, 0x76, 0x69, 0x65, 0x72, 0x70, 0x61, 0x64, 0x72, 0x65, 0x73, 0x66, 0xc3, + 0xa1, 0x63, 0x69, 0x6c, 0x63, 0x61, 0x62, 0x65, 0x7a, 0x61, 0xc3, 0xa1, 0x72, + 0x65, 0x61, 0x73, 0x73, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x65, 0x6e, 0x76, 0xc3, + 0xad, 0x6f, 0x6a, 0x61, 0x70, 0xc3, 0xb3, 0x6e, 0x61, 0x62, 0x75, 0x73, 0x6f, + 0x73, 0x62, 0x69, 0x65, 0x6e, 0x65, 0x73, 0x74, 0x65, 0x78, 0x74, 0x6f, 0x73, + 0x6c, 0x6c, 0x65, 0x76, 0x61, 0x72, 0x70, 0x75, 0x65, 0x64, 0x61, 0x6e, 0x66, + 0x75, 0x65, 0x72, 0x74, 0x65, 0x63, 0x6f, 0x6d, 0xc3, 0xba, 0x6e, 0x63, 0x6c, + 0x61, 0x73, 0x65, 0x73, 0x68, 0x75, 0x6d, 0x61, 0x6e, 0x6f, 0x74, 0x65, 0x6e, + 0x69, 0x64, 0x6f, 0x62, 0x69, 0x6c, 0x62, 0x61, 0x6f, 0x75, 0x6e, 0x69, 0x64, + 0x61, 0x64, 0x65, 0x73, 0x74, 0xc3, 0xa1, 0x73, 0x65, 0x64, 0x69, 0x74, 0x61, + 0x72, 0x63, 0x72, 0x65, 0x61, 0x64, 0x6f, 0xd0, 0xb4, 0xd0, 0xbb, 0xd1, 0x8f, + 0xd1, 0x87, 0xd1, 0x82, 0xd0, 0xbe, 0xd0, 0xba, 0xd0, 0xb0, 0xd0, 0xba, 0xd0, + 0xb8, 0xd0, 0xbb, 0xd0, 0xb8, 0xd1, 0x8d, 0xd1, 0x82, 0xd0, 0xbe, 0xd0, 0xb2, + 0xd1, 0x81, 0xd0, 0xb5, 0xd0, 0xb5, 0xd0, 0xb3, 0xd0, 0xbe, 0xd0, 0xbf, 0xd1, + 0x80, 0xd0, 0xb8, 0xd1, 0x82, 0xd0, 0xb0, 0xd0, 0xba, 0xd0, 0xb5, 0xd1, 0x89, + 0xd0, 0xb5, 0xd1, 0x83, 0xd0, 0xb6, 0xd0, 0xb5, 0xd0, 0x9a, 0xd0, 0xb0, 0xd0, + 0xba, 0xd0, 0xb1, 0xd0, 0xb5, 0xd0, 0xb7, 0xd0, 0xb1, 0xd1, 0x8b, 0xd0, 0xbb, + 0xd0, 0xbe, 0xd0, 0xbd, 0xd0, 0xb8, 0xd0, 0x92, 0xd1, 0x81, 0xd0, 0xb5, 0xd0, + 0xbf, 0xd0, 0xbe, 0xd0, 0xb4, 0xd0, 0xad, 0xd1, 0x82, 0xd0, 0xbe, 0xd1, 0x82, + 0xd0, 0xbe, 0xd0, 0xbc, 0xd1, 0x87, 0xd0, 0xb5, 0xd0, 0xbc, 0xd0, 0xbd, 0xd0, + 0xb5, 0xd1, 0x82, 0xd0, 0xbb, 0xd0, 0xb5, 0xd1, 0x82, 0xd1, 0x80, 0xd0, 0xb0, + 0xd0, 0xb7, 0xd0, 0xbe, 0xd0, 0xbd, 0xd0, 0xb0, 0xd0, 0xb3, 0xd0, 0xb4, 0xd0, + 0xb5, 0xd0, 0xbc, 0xd0, 0xbd, 0xd0, 0xb5, 0xd0, 0x94, 0xd0, 0xbb, 0xd1, 0x8f, + 0xd0, 0x9f, 0xd1, 0x80, 0xd0, 0xb8, 0xd0, 0xbd, 0xd0, 0xb0, 0xd1, 0x81, 0xd0, + 0xbd, 0xd0, 0xb8, 0xd1, 0x85, 0xd1, 0x82, 0xd0, 0xb5, 0xd0, 0xbc, 0xd0, 0xba, + 0xd1, 0x82, 0xd0, 0xbe, 0xd0, 0xb3, 0xd0, 0xbe, 0xd0, 0xb4, 0xd0, 0xb2, 0xd0, + 0xbe, 0xd1, 0x82, 0xd1, 0x82, 0xd0, 0xb0, 0xd0, 0xbc, 0xd0, 0xa1, 0xd0, 0xa8, + 0xd0, 0x90, 0xd0, 0xbc, 0xd0, 0xb0, 0xd1, 0x8f, 0xd0, 0xa7, 0xd1, 0x82, 0xd0, + 0xbe, 0xd0, 0xb2, 0xd0, 0xb0, 0xd1, 0x81, 0xd0, 0xb2, 0xd0, 0xb0, 0xd0, 0xbc, + 0xd0, 0xb5, 0xd0, 0xbc, 0xd1, 0x83, 0xd0, 0xa2, 0xd0, 0xb0, 0xd0, 0xba, 0xd0, + 0xb4, 0xd0, 0xb2, 0xd0, 0xb0, 0xd0, 0xbd, 0xd0, 0xb0, 0xd0, 0xbc, 0xd1, 0x8d, + 0xd1, 0x82, 0xd0, 0xb8, 0xd1, 0x8d, 0xd1, 0x82, 0xd1, 0x83, 0xd0, 0x92, 0xd0, + 0xb0, 0xd0, 0xbc, 0xd1, 0x82, 0xd0, 0xb5, 0xd1, 0x85, 0xd0, 0xbf, 0xd1, 0x80, + 0xd0, 0xbe, 0xd1, 0x82, 0xd1, 0x83, 0xd1, 0x82, 0xd0, 0xbd, 0xd0, 0xb0, 0xd0, + 0xb4, 0xd0, 0xb4, 0xd0, 0xbd, 0xd1, 0x8f, 0xd0, 0x92, 0xd0, 0xbe, 0xd1, 0x82, + 0xd1, 0x82, 0xd1, 0x80, 0xd0, 0xb8, 0xd0, 0xbd, 0xd0, 0xb5, 0xd0, 0xb9, 0xd0, + 0x92, 0xd0, 0xb0, 0xd1, 0x81, 0xd0, 0xbd, 0xd0, 0xb8, 0xd0, 0xbc, 0xd1, 0x81, + 0xd0, 0xb0, 0xd0, 0xbc, 0xd1, 0x82, 0xd0, 0xbe, 0xd1, 0x82, 0xd1, 0x80, 0xd1, + 0x83, 0xd0, 0xb1, 0xd0, 0x9e, 0xd0, 0xbd, 0xd0, 0xb8, 0xd0, 0xbc, 0xd0, 0xb8, + 0xd1, 0x80, 0xd0, 0xbd, 0xd0, 0xb5, 0xd0, 0xb5, 0xd0, 0x9e, 0xd0, 0x9e, 0xd0, + 0x9e, 0xd0, 0xbb, 0xd0, 0xb8, 0xd1, 0x86, 0xd1, 0x8d, 0xd1, 0x82, 0xd0, 0xb0, + 0xd0, 0x9e, 0xd0, 0xbd, 0xd0, 0xb0, 0xd0, 0xbd, 0xd0, 0xb5, 0xd0, 0xbc, 0xd0, + 0xb4, 0xd0, 0xbe, 0xd0, 0xbc, 0xd0, 0xbc, 0xd0, 0xbe, 0xd0, 0xb9, 0xd0, 0xb4, + 0xd0, 0xb2, 0xd0, 0xb5, 0xd0, 0xbe, 0xd0, 0xbd, 0xd0, 0xbe, 0xd1, 0x81, 0xd1, + 0x83, 0xd0, 0xb4, 0xe0, 0xa4, 0x95, 0xe0, 0xa5, 0x87, 0xe0, 0xa4, 0xb9, 0xe0, + 0xa5, 0x88, 0xe0, 0xa4, 0x95, 0xe0, 0xa5, 0x80, 0xe0, 0xa4, 0xb8, 0xe0, 0xa5, + 0x87, 0xe0, 0xa4, 0x95, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, 0x95, 0xe0, 0xa5, 0x8b, + 0xe0, 0xa4, 0x94, 0xe0, 0xa4, 0xb0, 0xe0, 0xa4, 0xaa, 0xe0, 0xa4, 0xb0, 0xe0, + 0xa4, 0xa8, 0xe0, 0xa5, 0x87, 0xe0, 0xa4, 0x8f, 0xe0, 0xa4, 0x95, 0xe0, 0xa4, + 0x95, 0xe0, 0xa4, 0xbf, 0xe0, 0xa4, 0xad, 0xe0, 0xa5, 0x80, 0xe0, 0xa4, 0x87, + 0xe0, 0xa4, 0xb8, 0xe0, 0xa4, 0x95, 0xe0, 0xa4, 0xb0, 0xe0, 0xa4, 0xa4, 0xe0, + 0xa5, 0x8b, 0xe0, 0xa4, 0xb9, 0xe0, 0xa5, 0x8b, 0xe0, 0xa4, 0x86, 0xe0, 0xa4, + 0xaa, 0xe0, 0xa4, 0xb9, 0xe0, 0xa5, 0x80, 0xe0, 0xa4, 0xaf, 0xe0, 0xa4, 0xb9, + 0xe0, 0xa4, 0xaf, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, 0xa4, 0xe0, 0xa4, 0x95, 0xe0, + 0xa4, 0xa5, 0xe0, 0xa4, 0xbe, 0x6a, 0x61, 0x67, 0x72, 0x61, 0x6e, 0xe0, 0xa4, + 0x86, 0xe0, 0xa4, 0x9c, 0xe0, 0xa4, 0x9c, 0xe0, 0xa5, 0x8b, 0xe0, 0xa4, 0x85, + 0xe0, 0xa4, 0xac, 0xe0, 0xa4, 0xa6, 0xe0, 0xa5, 0x8b, 0xe0, 0xa4, 0x97, 0xe0, + 0xa4, 0x88, 0xe0, 0xa4, 0x9c, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, 0x97, 0xe0, 0xa4, + 0x8f, 0xe0, 0xa4, 0xb9, 0xe0, 0xa4, 0xae, 0xe0, 0xa4, 0x87, 0xe0, 0xa4, 0xa8, + 0xe0, 0xa4, 0xb5, 0xe0, 0xa4, 0xb9, 0xe0, 0xa4, 0xaf, 0xe0, 0xa5, 0x87, 0xe0, + 0xa4, 0xa5, 0xe0, 0xa5, 0x87, 0xe0, 0xa4, 0xa5, 0xe0, 0xa5, 0x80, 0xe0, 0xa4, + 0x98, 0xe0, 0xa4, 0xb0, 0xe0, 0xa4, 0x9c, 0xe0, 0xa4, 0xac, 0xe0, 0xa4, 0xa6, + 0xe0, 0xa5, 0x80, 0xe0, 0xa4, 0x95, 0xe0, 0xa4, 0x88, 0xe0, 0xa4, 0x9c, 0xe0, + 0xa5, 0x80, 0xe0, 0xa4, 0xb5, 0xe0, 0xa5, 0x87, 0xe0, 0xa4, 0xa8, 0xe0, 0xa4, + 0x88, 0xe0, 0xa4, 0xa8, 0xe0, 0xa4, 0x8f, 0xe0, 0xa4, 0xb9, 0xe0, 0xa4, 0xb0, + 0xe0, 0xa4, 0x89, 0xe0, 0xa4, 0xb8, 0xe0, 0xa4, 0xae, 0xe0, 0xa5, 0x87, 0xe0, + 0xa4, 0x95, 0xe0, 0xa4, 0xae, 0xe0, 0xa4, 0xb5, 0xe0, 0xa5, 0x8b, 0xe0, 0xa4, + 0xb2, 0xe0, 0xa5, 0x87, 0xe0, 0xa4, 0xb8, 0xe0, 0xa4, 0xac, 0xe0, 0xa4, 0xae, + 0xe0, 0xa4, 0x88, 0xe0, 0xa4, 0xa6, 0xe0, 0xa5, 0x87, 0xe0, 0xa4, 0x93, 0xe0, + 0xa4, 0xb0, 0xe0, 0xa4, 0x86, 0xe0, 0xa4, 0xae, 0xe0, 0xa4, 0xac, 0xe0, 0xa4, + 0xb8, 0xe0, 0xa4, 0xad, 0xe0, 0xa4, 0xb0, 0xe0, 0xa4, 0xac, 0xe0, 0xa4, 0xa8, + 0xe0, 0xa4, 0x9a, 0xe0, 0xa4, 0xb2, 0xe0, 0xa4, 0xae, 0xe0, 0xa4, 0xa8, 0xe0, + 0xa4, 0x86, 0xe0, 0xa4, 0x97, 0xe0, 0xa4, 0xb8, 0xe0, 0xa5, 0x80, 0xe0, 0xa4, + 0xb2, 0xe0, 0xa5, 0x80, 0xd8, 0xb9, 0xd9, 0x84, 0xd9, 0x89, 0xd8, 0xa5, 0xd9, + 0x84, 0xd9, 0x89, 0xd9, 0x87, 0xd8, 0xb0, 0xd8, 0xa7, 0xd8, 0xa2, 0xd8, 0xae, + 0xd8, 0xb1, 0xd8, 0xb9, 0xd8, 0xaf, 0xd8, 0xaf, 0xd8, 0xa7, 0xd9, 0x84, 0xd9, + 0x89, 0xd9, 0x87, 0xd8, 0xb0, 0xd9, 0x87, 0xd8, 0xb5, 0xd9, 0x88, 0xd8, 0xb1, + 0xd8, 0xba, 0xd9, 0x8a, 0xd8, 0xb1, 0xd9, 0x83, 0xd8, 0xa7, 0xd9, 0x86, 0xd9, + 0x88, 0xd9, 0x84, 0xd8, 0xa7, 0xd8, 0xa8, 0xd9, 0x8a, 0xd9, 0x86, 0xd8, 0xb9, + 0xd8, 0xb1, 0xd8, 0xb6, 0xd8, 0xb0, 0xd9, 0x84, 0xd9, 0x83, 0xd9, 0x87, 0xd9, + 0x86, 0xd8, 0xa7, 0xd9, 0x8a, 0xd9, 0x88, 0xd9, 0x85, 0xd9, 0x82, 0xd8, 0xa7, + 0xd9, 0x84, 0xd8, 0xb9, 0xd9, 0x84, 0xd9, 0x8a, 0xd8, 0xa7, 0xd9, 0x86, 0xd8, + 0xa7, 0xd9, 0x84, 0xd9, 0x83, 0xd9, 0x86, 0xd8, 0xad, 0xd8, 0xaa, 0xd9, 0x89, + 0xd9, 0x82, 0xd8, 0xa8, 0xd9, 0x84, 0xd9, 0x88, 0xd8, 0xad, 0xd8, 0xa9, 0xd8, + 0xa7, 0xd8, 0xae, 0xd8, 0xb1, 0xd9, 0x81, 0xd9, 0x82, 0xd8, 0xb7, 0xd8, 0xb9, + 0xd8, 0xa8, 0xd8, 0xaf, 0xd8, 0xb1, 0xd9, 0x83, 0xd9, 0x86, 0xd8, 0xa5, 0xd8, + 0xb0, 0xd8, 0xa7, 0xd9, 0x83, 0xd9, 0x85, 0xd8, 0xa7, 0xd8, 0xa7, 0xd8, 0xad, + 0xd8, 0xaf, 0xd8, 0xa5, 0xd9, 0x84, 0xd8, 0xa7, 0xd9, 0x81, 0xd9, 0x8a, 0xd9, + 0x87, 0xd8, 0xa8, 0xd8, 0xb9, 0xd8, 0xb6, 0xd9, 0x83, 0xd9, 0x8a, 0xd9, 0x81, + 0xd8, 0xa8, 0xd8, 0xad, 0xd8, 0xab, 0xd9, 0x88, 0xd9, 0x85, 0xd9, 0x86, 0xd9, + 0x88, 0xd9, 0x87, 0xd9, 0x88, 0xd8, 0xa3, 0xd9, 0x86, 0xd8, 0xa7, 0xd8, 0xac, + 0xd8, 0xaf, 0xd8, 0xa7, 0xd9, 0x84, 0xd9, 0x87, 0xd8, 0xa7, 0xd8, 0xb3, 0xd9, + 0x84, 0xd9, 0x85, 0xd8, 0xb9, 0xd9, 0x86, 0xd8, 0xaf, 0xd9, 0x84, 0xd9, 0x8a, + 0xd8, 0xb3, 0xd8, 0xb9, 0xd8, 0xa8, 0xd8, 0xb1, 0xd8, 0xb5, 0xd9, 0x84, 0xd9, + 0x89, 0xd9, 0x85, 0xd9, 0x86, 0xd8, 0xb0, 0xd8, 0xa8, 0xd9, 0x87, 0xd8, 0xa7, + 0xd8, 0xa3, 0xd9, 0x86, 0xd9, 0x87, 0xd9, 0x85, 0xd8, 0xab, 0xd9, 0x84, 0xd9, + 0x83, 0xd9, 0x86, 0xd8, 0xaa, 0xd8, 0xa7, 0xd9, 0x84, 0xd8, 0xa7, 0xd8, 0xad, + 0xd9, 0x8a, 0xd8, 0xab, 0xd9, 0x85, 0xd8, 0xb5, 0xd8, 0xb1, 0xd8, 0xb4, 0xd8, + 0xb1, 0xd8, 0xad, 0xd8, 0xad, 0xd9, 0x88, 0xd9, 0x84, 0xd9, 0x88, 0xd9, 0x81, + 0xd9, 0x8a, 0xd8, 0xa7, 0xd8, 0xb0, 0xd8, 0xa7, 0xd9, 0x84, 0xd9, 0x83, 0xd9, + 0x84, 0xd9, 0x85, 0xd8, 0xb1, 0xd8, 0xa9, 0xd8, 0xa7, 0xd9, 0x86, 0xd8, 0xaa, + 0xd8, 0xa7, 0xd9, 0x84, 0xd9, 0x81, 0xd8, 0xa3, 0xd8, 0xa8, 0xd9, 0x88, 0xd8, + 0xae, 0xd8, 0xa7, 0xd8, 0xb5, 0xd8, 0xa3, 0xd9, 0x86, 0xd8, 0xaa, 0xd8, 0xa7, + 0xd9, 0x86, 0xd9, 0x87, 0xd8, 0xa7, 0xd9, 0x84, 0xd9, 0x8a, 0xd8, 0xb9, 0xd8, + 0xb6, 0xd9, 0x88, 0xd9, 0x88, 0xd9, 0x82, 0xd8, 0xaf, 0xd8, 0xa7, 0xd8, 0xa8, + 0xd9, 0x86, 0xd8, 0xae, 0xd9, 0x8a, 0xd8, 0xb1, 0xd8, 0xa8, 0xd9, 0x86, 0xd8, + 0xaa, 0xd9, 0x84, 0xd9, 0x83, 0xd9, 0x85, 0xd8, 0xb4, 0xd8, 0xa7, 0xd8, 0xa1, + 0xd9, 0x88, 0xd9, 0x87, 0xd9, 0x8a, 0xd8, 0xa7, 0xd8, 0xa8, 0xd9, 0x88, 0xd9, + 0x82, 0xd8, 0xb5, 0xd8, 0xb5, 0xd9, 0x88, 0xd9, 0x85, 0xd8, 0xa7, 0xd8, 0xb1, + 0xd9, 0x82, 0xd9, 0x85, 0xd8, 0xa3, 0xd8, 0xad, 0xd8, 0xaf, 0xd9, 0x86, 0xd8, + 0xad, 0xd9, 0x86, 0xd8, 0xb9, 0xd8, 0xaf, 0xd9, 0x85, 0xd8, 0xb1, 0xd8, 0xa3, + 0xd9, 0x8a, 0xd8, 0xa7, 0xd8, 0xad, 0xd8, 0xa9, 0xd9, 0x83, 0xd8, 0xaa, 0xd8, + 0xa8, 0xd8, 0xaf, 0xd9, 0x88, 0xd9, 0x86, 0xd9, 0x8a, 0xd8, 0xac, 0xd8, 0xa8, + 0xd9, 0x85, 0xd9, 0x86, 0xd9, 0x87, 0xd8, 0xaa, 0xd8, 0xad, 0xd8, 0xaa, 0xd8, + 0xac, 0xd9, 0x87, 0xd8, 0xa9, 0xd8, 0xb3, 0xd9, 0x86, 0xd8, 0xa9, 0xd9, 0x8a, + 0xd8, 0xaa, 0xd9, 0x85, 0xd9, 0x83, 0xd8, 0xb1, 0xd8, 0xa9, 0xd8, 0xba, 0xd8, + 0xb2, 0xd8, 0xa9, 0xd9, 0x86, 0xd9, 0x81, 0xd8, 0xb3, 0xd8, 0xa8, 0xd9, 0x8a, + 0xd8, 0xaa, 0xd9, 0x84, 0xd9, 0x84, 0xd9, 0x87, 0xd9, 0x84, 0xd9, 0x86, 0xd8, + 0xa7, 0xd8, 0xaa, 0xd9, 0x84, 0xd9, 0x83, 0xd9, 0x82, 0xd9, 0x84, 0xd8, 0xa8, + 0xd9, 0x84, 0xd9, 0x85, 0xd8, 0xa7, 0xd8, 0xb9, 0xd9, 0x86, 0xd9, 0x87, 0xd8, + 0xa3, 0xd9, 0x88, 0xd9, 0x84, 0xd8, 0xb4, 0xd9, 0x8a, 0xd8, 0xa1, 0xd9, 0x86, + 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xa3, 0xd9, 0x85, 0xd8, 0xa7, 0xd9, 0x81, 0xd9, + 0x8a, 0xd9, 0x83, 0xd8, 0xa8, 0xd9, 0x83, 0xd9, 0x84, 0xd8, 0xb0, 0xd8, 0xa7, + 0xd8, 0xaa, 0xd8, 0xb1, 0xd8, 0xaa, 0xd8, 0xa8, 0xd8, 0xa8, 0xd8, 0xa3, 0xd9, + 0x86, 0xd9, 0x87, 0xd9, 0x85, 0xd8, 0xb3, 0xd8, 0xa7, 0xd9, 0x86, 0xd9, 0x83, + 0xd8, 0xa8, 0xd9, 0x8a, 0xd8, 0xb9, 0xd9, 0x81, 0xd9, 0x82, 0xd8, 0xaf, 0xd8, + 0xad, 0xd8, 0xb3, 0xd9, 0x86, 0xd9, 0x84, 0xd9, 0x87, 0xd9, 0x85, 0xd8, 0xb4, + 0xd8, 0xb9, 0xd8, 0xb1, 0xd8, 0xa3, 0xd9, 0x87, 0xd9, 0x84, 0xd8, 0xb4, 0xd9, + 0x87, 0xd8, 0xb1, 0xd9, 0x82, 0xd8, 0xb7, 0xd8, 0xb1, 0xd8, 0xb7, 0xd9, 0x84, + 0xd8, 0xa8, 0x70, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x65, 0x72, 0x76, + 0x69, 0x63, 0x65, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x68, 0x69, 0x6d, + 0x73, 0x65, 0x6c, 0x66, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x63, 0x6f, + 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x73, + 0x74, 0x61, 0x72, 0x74, 0x65, 0x64, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, + 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x66, 0x61, 0x73, 0x68, 0x69, 0x6f, + 0x6e, 0x3c, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x3e, 0x63, 0x6f, 0x75, 0x6e, 0x74, + 0x72, 0x79, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x63, 0x72, 0x65, 0x61, + 0x74, 0x65, 0x64, 0x73, 0x74, 0x6f, 0x72, 0x69, 0x65, 0x73, 0x72, 0x65, 0x73, + 0x75, 0x6c, 0x74, 0x73, 0x72, 0x75, 0x6e, 0x6e, 0x69, 0x6e, 0x67, 0x70, 0x72, + 0x6f, 0x63, 0x65, 0x73, 0x73, 0x77, 0x72, 0x69, 0x74, 0x69, 0x6e, 0x67, 0x6f, + 0x62, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x76, 0x69, 0x73, 0x69, 0x62, 0x6c, 0x65, + 0x77, 0x65, 0x6c, 0x63, 0x6f, 0x6d, 0x65, 0x61, 0x72, 0x74, 0x69, 0x63, 0x6c, + 0x65, 0x75, 0x6e, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x6e, 0x65, 0x74, 0x77, 0x6f, + 0x72, 0x6b, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x6e, 0x79, 0x64, 0x79, 0x6e, 0x61, + 0x6d, 0x69, 0x63, 0x62, 0x72, 0x6f, 0x77, 0x73, 0x65, 0x72, 0x70, 0x72, 0x69, + 0x76, 0x61, 0x63, 0x79, 0x70, 0x72, 0x6f, 0x62, 0x6c, 0x65, 0x6d, 0x53, 0x65, + 0x72, 0x76, 0x69, 0x63, 0x65, 0x72, 0x65, 0x73, 0x70, 0x65, 0x63, 0x74, 0x64, + 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x72, 0x65, 0x73, 0x65, 0x72, 0x76, 0x65, 0x77, 0x65, 0x62, 0x73, 0x69, 0x74, + 0x65, 0x68, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x66, 0x72, 0x69, 0x65, 0x6e, + 0x64, 0x73, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x77, 0x6f, 0x72, 0x6b, + 0x69, 0x6e, 0x67, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x6d, 0x69, 0x6c, + 0x6c, 0x69, 0x6f, 0x6e, 0x63, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x77, 0x69, + 0x6e, 0x64, 0x6f, 0x77, 0x2e, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x76, + 0x69, 0x73, 0x69, 0x74, 0x65, 0x64, 0x77, 0x65, 0x61, 0x74, 0x68, 0x65, 0x72, + 0x63, 0x6f, 0x72, 0x72, 0x65, 0x63, 0x74, 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, + 0x74, 0x65, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x66, 0x6f, 0x72, 0x77, 0x61, + 0x72, 0x64, 0x79, 0x6f, 0x75, 0x20, 0x63, 0x61, 0x6e, 0x72, 0x65, 0x6d, 0x6f, + 0x76, 0x65, 0x64, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x63, 0x6f, 0x6e, + 0x74, 0x72, 0x6f, 0x6c, 0x61, 0x72, 0x63, 0x68, 0x69, 0x76, 0x65, 0x63, 0x75, + 0x72, 0x72, 0x65, 0x6e, 0x74, 0x72, 0x65, 0x61, 0x64, 0x69, 0x6e, 0x67, 0x6c, + 0x69, 0x62, 0x72, 0x61, 0x72, 0x79, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x65, 0x64, + 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x66, 0x75, 0x72, 0x74, 0x68, 0x65, + 0x72, 0x73, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x6d, 0x61, 0x63, 0x68, 0x69, + 0x6e, 0x65, 0x6d, 0x69, 0x6e, 0x75, 0x74, 0x65, 0x73, 0x70, 0x72, 0x69, 0x76, + 0x61, 0x74, 0x65, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x70, 0x72, 0x6f, + 0x67, 0x72, 0x61, 0x6d, 0x73, 0x6f, 0x63, 0x69, 0x65, 0x74, 0x79, 0x6e, 0x75, + 0x6d, 0x62, 0x65, 0x72, 0x73, 0x77, 0x72, 0x69, 0x74, 0x74, 0x65, 0x6e, 0x65, + 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x74, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, + 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x6c, 0x6f, 0x61, 0x64, 0x69, 0x6e, + 0x67, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x70, 0x61, 0x72, 0x74, 0x6e, + 0x65, 0x72, 0x66, 0x69, 0x6e, 0x61, 0x6c, 0x6c, 0x79, 0x70, 0x65, 0x72, 0x66, + 0x65, 0x63, 0x74, 0x6d, 0x65, 0x61, 0x6e, 0x69, 0x6e, 0x67, 0x73, 0x79, 0x73, + 0x74, 0x65, 0x6d, 0x73, 0x6b, 0x65, 0x65, 0x70, 0x69, 0x6e, 0x67, 0x63, 0x75, + 0x6c, 0x74, 0x75, 0x72, 0x65, 0x26, 0x71, 0x75, 0x6f, 0x74, 0x3b, 0x2c, 0x6a, + 0x6f, 0x75, 0x72, 0x6e, 0x61, 0x6c, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, + 0x73, 0x75, 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, 0x26, 0x71, 0x75, 0x6f, 0x74, + 0x3b, 0x65, 0x78, 0x70, 0x69, 0x72, 0x65, 0x73, 0x72, 0x65, 0x76, 0x69, 0x65, + 0x77, 0x73, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x45, 0x6e, 0x67, 0x6c, + 0x69, 0x73, 0x68, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x74, 0x68, 0x72, + 0x6f, 0x75, 0x67, 0x68, 0x50, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x20, 0x6f, 0x70, + 0x69, 0x6e, 0x69, 0x6f, 0x6e, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x63, 0x74, 0x61, + 0x76, 0x65, 0x72, 0x61, 0x67, 0x65, 0x70, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, + 0x76, 0x69, 0x6c, 0x6c, 0x61, 0x67, 0x65, 0x53, 0x70, 0x61, 0x6e, 0x69, 0x73, + 0x68, 0x67, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x79, 0x64, 0x65, 0x63, 0x6c, 0x69, + 0x6e, 0x65, 0x6d, 0x65, 0x65, 0x74, 0x69, 0x6e, 0x67, 0x6d, 0x69, 0x73, 0x73, + 0x69, 0x6f, 0x6e, 0x70, 0x6f, 0x70, 0x75, 0x6c, 0x61, 0x72, 0x71, 0x75, 0x61, + 0x6c, 0x69, 0x74, 0x79, 0x6d, 0x65, 0x61, 0x73, 0x75, 0x72, 0x65, 0x67, 0x65, + 0x6e, 0x65, 0x72, 0x61, 0x6c, 0x73, 0x70, 0x65, 0x63, 0x69, 0x65, 0x73, 0x73, + 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x77, 0x72, 0x69, 0x74, 0x65, 0x72, 0x73, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x65, + 0x72, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x61, 0x6c, 0x72, 0x65, 0x70, 0x6f, 0x72, + 0x74, 0x73, 0x66, 0x69, 0x67, 0x75, 0x72, 0x65, 0x73, 0x6d, 0x65, 0x6d, 0x62, + 0x65, 0x72, 0x73, 0x68, 0x6f, 0x6c, 0x64, 0x69, 0x6e, 0x67, 0x64, 0x69, 0x73, + 0x70, 0x75, 0x74, 0x65, 0x65, 0x61, 0x72, 0x6c, 0x69, 0x65, 0x72, 0x65, 0x78, + 0x70, 0x72, 0x65, 0x73, 0x73, 0x64, 0x69, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x70, + 0x69, 0x63, 0x74, 0x75, 0x72, 0x65, 0x41, 0x6e, 0x6f, 0x74, 0x68, 0x65, 0x72, + 0x6d, 0x61, 0x72, 0x72, 0x69, 0x65, 0x64, 0x74, 0x72, 0x61, 0x66, 0x66, 0x69, + 0x63, 0x6c, 0x65, 0x61, 0x64, 0x69, 0x6e, 0x67, 0x63, 0x68, 0x61, 0x6e, 0x67, + 0x65, 0x64, 0x63, 0x65, 0x6e, 0x74, 0x72, 0x61, 0x6c, 0x76, 0x69, 0x63, 0x74, + 0x6f, 0x72, 0x79, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x73, 0x2f, 0x72, 0x65, 0x61, + 0x73, 0x6f, 0x6e, 0x73, 0x73, 0x74, 0x75, 0x64, 0x69, 0x65, 0x73, 0x66, 0x65, + 0x61, 0x74, 0x75, 0x72, 0x65, 0x6c, 0x69, 0x73, 0x74, 0x69, 0x6e, 0x67, 0x6d, + 0x75, 0x73, 0x74, 0x20, 0x62, 0x65, 0x73, 0x63, 0x68, 0x6f, 0x6f, 0x6c, 0x73, + 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x75, 0x73, 0x75, 0x61, 0x6c, 0x6c, + 0x79, 0x65, 0x70, 0x69, 0x73, 0x6f, 0x64, 0x65, 0x70, 0x6c, 0x61, 0x79, 0x69, + 0x6e, 0x67, 0x67, 0x72, 0x6f, 0x77, 0x69, 0x6e, 0x67, 0x6f, 0x62, 0x76, 0x69, + 0x6f, 0x75, 0x73, 0x6f, 0x76, 0x65, 0x72, 0x6c, 0x61, 0x79, 0x70, 0x72, 0x65, + 0x73, 0x65, 0x6e, 0x74, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x3c, 0x2f, + 0x75, 0x6c, 0x3e, 0x0d, 0x0a, 0x77, 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, 0x61, + 0x6c, 0x72, 0x65, 0x61, 0x64, 0x79, 0x63, 0x65, 0x72, 0x74, 0x61, 0x69, 0x6e, + 0x72, 0x65, 0x61, 0x6c, 0x69, 0x74, 0x79, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, + 0x65, 0x61, 0x6e, 0x6f, 0x74, 0x68, 0x65, 0x72, 0x64, 0x65, 0x73, 0x6b, 0x74, + 0x6f, 0x70, 0x6f, 0x66, 0x66, 0x65, 0x72, 0x65, 0x64, 0x70, 0x61, 0x74, 0x74, + 0x65, 0x72, 0x6e, 0x75, 0x6e, 0x75, 0x73, 0x75, 0x61, 0x6c, 0x44, 0x69, 0x67, + 0x69, 0x74, 0x61, 0x6c, 0x63, 0x61, 0x70, 0x69, 0x74, 0x61, 0x6c, 0x57, 0x65, + 0x62, 0x73, 0x69, 0x74, 0x65, 0x66, 0x61, 0x69, 0x6c, 0x75, 0x72, 0x65, 0x63, + 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x72, 0x65, 0x64, 0x75, 0x63, 0x65, 0x64, + 0x41, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x64, 0x65, 0x63, 0x61, 0x64, 0x65, + 0x73, 0x72, 0x65, 0x67, 0x75, 0x6c, 0x61, 0x72, 0x20, 0x26, 0x61, 0x6d, 0x70, + 0x3b, 0x20, 0x61, 0x6e, 0x69, 0x6d, 0x61, 0x6c, 0x73, 0x72, 0x65, 0x6c, 0x65, + 0x61, 0x73, 0x65, 0x41, 0x75, 0x74, 0x6f, 0x6d, 0x61, 0x74, 0x67, 0x65, 0x74, + 0x74, 0x69, 0x6e, 0x67, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x73, 0x6e, 0x6f, + 0x74, 0x68, 0x69, 0x6e, 0x67, 0x50, 0x6f, 0x70, 0x75, 0x6c, 0x61, 0x72, 0x63, + 0x61, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x6c, 0x65, 0x74, 0x74, 0x65, 0x72, 0x73, + 0x63, 0x61, 0x70, 0x74, 0x75, 0x72, 0x65, 0x73, 0x63, 0x69, 0x65, 0x6e, 0x63, + 0x65, 0x6c, 0x69, 0x63, 0x65, 0x6e, 0x73, 0x65, 0x63, 0x68, 0x61, 0x6e, 0x67, + 0x65, 0x73, 0x45, 0x6e, 0x67, 0x6c, 0x61, 0x6e, 0x64, 0x3d, 0x31, 0x26, 0x61, + 0x6d, 0x70, 0x3b, 0x48, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x20, 0x3d, 0x20, + 0x6e, 0x65, 0x77, 0x20, 0x43, 0x65, 0x6e, 0x74, 0x72, 0x61, 0x6c, 0x75, 0x70, + 0x64, 0x61, 0x74, 0x65, 0x64, 0x53, 0x70, 0x65, 0x63, 0x69, 0x61, 0x6c, 0x4e, + 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, + 0x63, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x77, 0x61, 0x72, 0x6e, 0x69, 0x6e, + 0x67, 0x43, 0x6f, 0x6c, 0x6c, 0x65, 0x67, 0x65, 0x74, 0x6f, 0x6f, 0x6c, 0x62, + 0x61, 0x72, 0x72, 0x65, 0x6d, 0x61, 0x69, 0x6e, 0x73, 0x62, 0x65, 0x63, 0x61, + 0x75, 0x73, 0x65, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x65, 0x64, 0x44, 0x65, 0x75, + 0x74, 0x73, 0x63, 0x68, 0x66, 0x69, 0x6e, 0x61, 0x6e, 0x63, 0x65, 0x77, 0x6f, + 0x72, 0x6b, 0x65, 0x72, 0x73, 0x71, 0x75, 0x69, 0x63, 0x6b, 0x6c, 0x79, 0x62, + 0x65, 0x74, 0x77, 0x65, 0x65, 0x6e, 0x65, 0x78, 0x61, 0x63, 0x74, 0x6c, 0x79, + 0x73, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x64, 0x69, 0x73, 0x65, 0x61, 0x73, + 0x65, 0x53, 0x6f, 0x63, 0x69, 0x65, 0x74, 0x79, 0x77, 0x65, 0x61, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x78, 0x68, 0x69, 0x62, 0x69, 0x74, 0x26, 0x6c, 0x74, 0x3b, + 0x21, 0x2d, 0x2d, 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x63, 0x6c, 0x61, + 0x73, 0x73, 0x65, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x65, 0x64, 0x6f, 0x75, + 0x74, 0x6c, 0x69, 0x6e, 0x65, 0x61, 0x74, 0x74, 0x61, 0x63, 0x6b, 0x73, 0x64, + 0x65, 0x76, 0x69, 0x63, 0x65, 0x73, 0x28, 0x77, 0x69, 0x6e, 0x64, 0x6f, 0x77, + 0x70, 0x75, 0x72, 0x70, 0x6f, 0x73, 0x65, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x3d, + 0x22, 0x4d, 0x6f, 0x62, 0x69, 0x6c, 0x65, 0x20, 0x6b, 0x69, 0x6c, 0x6c, 0x69, + 0x6e, 0x67, 0x73, 0x68, 0x6f, 0x77, 0x69, 0x6e, 0x67, 0x49, 0x74, 0x61, 0x6c, + 0x69, 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x70, 0x70, 0x65, 0x64, 0x68, 0x65, 0x61, + 0x76, 0x69, 0x6c, 0x79, 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, 0x73, 0x2d, 0x31, + 0x27, 0x5d, 0x29, 0x3b, 0x0a, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x72, 0x6d, 0x43, + 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x61, 0x64, 0x76, 0x61, 0x6e, 0x63, 0x65, + 0x73, 0x68, 0x61, 0x72, 0x69, 0x6e, 0x67, 0x6f, 0x70, 0x65, 0x6e, 0x69, 0x6e, + 0x67, 0x64, 0x72, 0x61, 0x77, 0x69, 0x6e, 0x67, 0x62, 0x69, 0x6c, 0x6c, 0x69, + 0x6f, 0x6e, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x65, 0x64, 0x47, 0x65, 0x72, 0x6d, + 0x61, 0x6e, 0x79, 0x72, 0x65, 0x6c, 0x61, 0x74, 0x65, 0x64, 0x3c, 0x2f, 0x66, + 0x6f, 0x72, 0x6d, 0x3e, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x77, 0x68, + 0x65, 0x74, 0x68, 0x65, 0x72, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x65, 0x64, 0x53, + 0x63, 0x69, 0x65, 0x6e, 0x63, 0x65, 0x63, 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, + 0x41, 0x72, 0x74, 0x69, 0x63, 0x6c, 0x65, 0x62, 0x75, 0x74, 0x74, 0x6f, 0x6e, + 0x73, 0x6c, 0x61, 0x72, 0x67, 0x65, 0x73, 0x74, 0x75, 0x6e, 0x69, 0x66, 0x6f, + 0x72, 0x6d, 0x6a, 0x6f, 0x75, 0x72, 0x6e, 0x65, 0x79, 0x73, 0x69, 0x64, 0x65, + 0x62, 0x61, 0x72, 0x43, 0x68, 0x69, 0x63, 0x61, 0x67, 0x6f, 0x68, 0x6f, 0x6c, + 0x69, 0x64, 0x61, 0x79, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x6c, 0x70, 0x61, + 0x73, 0x73, 0x61, 0x67, 0x65, 0x2c, 0x26, 0x71, 0x75, 0x6f, 0x74, 0x3b, 0x61, + 0x6e, 0x69, 0x6d, 0x61, 0x74, 0x65, 0x66, 0x65, 0x65, 0x6c, 0x69, 0x6e, 0x67, + 0x61, 0x72, 0x72, 0x69, 0x76, 0x65, 0x64, 0x70, 0x61, 0x73, 0x73, 0x69, 0x6e, + 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x61, 0x6c, 0x72, 0x6f, 0x75, 0x67, 0x68, + 0x6c, 0x79, 0x2e, 0x0a, 0x0a, 0x54, 0x68, 0x65, 0x20, 0x62, 0x75, 0x74, 0x20, + 0x6e, 0x6f, 0x74, 0x64, 0x65, 0x6e, 0x73, 0x69, 0x74, 0x79, 0x42, 0x72, 0x69, + 0x74, 0x61, 0x69, 0x6e, 0x43, 0x68, 0x69, 0x6e, 0x65, 0x73, 0x65, 0x6c, 0x61, + 0x63, 0x6b, 0x20, 0x6f, 0x66, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x49, + 0x72, 0x65, 0x6c, 0x61, 0x6e, 0x64, 0x22, 0x20, 0x64, 0x61, 0x74, 0x61, 0x2d, + 0x66, 0x61, 0x63, 0x74, 0x6f, 0x72, 0x73, 0x72, 0x65, 0x63, 0x65, 0x69, 0x76, + 0x65, 0x74, 0x68, 0x61, 0x74, 0x20, 0x69, 0x73, 0x4c, 0x69, 0x62, 0x72, 0x61, + 0x72, 0x79, 0x68, 0x75, 0x73, 0x62, 0x61, 0x6e, 0x64, 0x69, 0x6e, 0x20, 0x66, + 0x61, 0x63, 0x74, 0x61, 0x66, 0x66, 0x61, 0x69, 0x72, 0x73, 0x43, 0x68, 0x61, + 0x72, 0x6c, 0x65, 0x73, 0x72, 0x61, 0x64, 0x69, 0x63, 0x61, 0x6c, 0x62, 0x72, + 0x6f, 0x75, 0x67, 0x68, 0x74, 0x66, 0x69, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x6c, + 0x61, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x3a, 0x6c, 0x61, 0x6e, 0x67, 0x3d, 0x22, + 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6c, 0x65, 0x61, 0x64, 0x65, 0x72, + 0x73, 0x70, 0x6c, 0x61, 0x6e, 0x6e, 0x65, 0x64, 0x70, 0x72, 0x65, 0x6d, 0x69, + 0x75, 0x6d, 0x70, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x41, 0x6d, 0x65, 0x72, + 0x69, 0x63, 0x61, 0x45, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x5d, 0x26, 0x71, + 0x75, 0x6f, 0x74, 0x3b, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x6e, 0x65, + 0x65, 0x64, 0x20, 0x74, 0x6f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3d, 0x22, 0x63, + 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x78, 0x6c, 0x6f, 0x6f, 0x6b, 0x69, 0x6e, 0x67, + 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x62, 0x65, 0x6c, 0x69, 0x65, 0x76, + 0x65, 0x73, 0x6d, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x2d, 0x6d, 0x6f, 0x62, 0x69, + 0x6c, 0x65, 0x72, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x73, 0x77, 0x61, 0x6e, 0x74, + 0x20, 0x74, 0x6f, 0x6b, 0x69, 0x6e, 0x64, 0x20, 0x6f, 0x66, 0x46, 0x69, 0x72, + 0x65, 0x66, 0x6f, 0x78, 0x79, 0x6f, 0x75, 0x20, 0x61, 0x72, 0x65, 0x73, 0x69, + 0x6d, 0x69, 0x6c, 0x61, 0x72, 0x73, 0x74, 0x75, 0x64, 0x69, 0x65, 0x64, 0x6d, + 0x61, 0x78, 0x69, 0x6d, 0x75, 0x6d, 0x68, 0x65, 0x61, 0x64, 0x69, 0x6e, 0x67, + 0x72, 0x61, 0x70, 0x69, 0x64, 0x6c, 0x79, 0x63, 0x6c, 0x69, 0x6d, 0x61, 0x74, + 0x65, 0x6b, 0x69, 0x6e, 0x67, 0x64, 0x6f, 0x6d, 0x65, 0x6d, 0x65, 0x72, 0x67, + 0x65, 0x64, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x66, 0x6f, 0x75, 0x6e, + 0x64, 0x65, 0x64, 0x70, 0x69, 0x6f, 0x6e, 0x65, 0x65, 0x72, 0x66, 0x6f, 0x72, + 0x6d, 0x75, 0x6c, 0x61, 0x64, 0x79, 0x6e, 0x61, 0x73, 0x74, 0x79, 0x68, 0x6f, + 0x77, 0x20, 0x74, 0x6f, 0x20, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x72, + 0x65, 0x76, 0x65, 0x6e, 0x75, 0x65, 0x65, 0x63, 0x6f, 0x6e, 0x6f, 0x6d, 0x79, + 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x62, 0x72, 0x6f, 0x74, 0x68, 0x65, + 0x72, 0x73, 0x6f, 0x6c, 0x64, 0x69, 0x65, 0x72, 0x6c, 0x61, 0x72, 0x67, 0x65, + 0x6c, 0x79, 0x63, 0x61, 0x6c, 0x6c, 0x69, 0x6e, 0x67, 0x2e, 0x26, 0x71, 0x75, + 0x6f, 0x74, 0x3b, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x45, 0x64, 0x77, + 0x61, 0x72, 0x64, 0x20, 0x73, 0x65, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x6f, + 0x62, 0x65, 0x72, 0x74, 0x20, 0x65, 0x66, 0x66, 0x6f, 0x72, 0x74, 0x73, 0x50, + 0x61, 0x63, 0x69, 0x66, 0x69, 0x63, 0x6c, 0x65, 0x61, 0x72, 0x6e, 0x65, 0x64, + 0x75, 0x70, 0x20, 0x77, 0x69, 0x74, 0x68, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, + 0x3a, 0x77, 0x65, 0x20, 0x68, 0x61, 0x76, 0x65, 0x41, 0x6e, 0x67, 0x65, 0x6c, + 0x65, 0x73, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x5f, 0x73, 0x65, 0x61, + 0x72, 0x63, 0x68, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x65, 0x64, 0x61, 0x63, 0x71, + 0x75, 0x69, 0x72, 0x65, 0x6d, 0x61, 0x73, 0x73, 0x69, 0x76, 0x65, 0x67, 0x72, + 0x61, 0x6e, 0x74, 0x65, 0x64, 0x3a, 0x20, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x74, + 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x62, 0x69, 0x67, 0x67, 0x65, 0x73, 0x74, + 0x62, 0x65, 0x6e, 0x65, 0x66, 0x69, 0x74, 0x64, 0x72, 0x69, 0x76, 0x69, 0x6e, + 0x67, 0x53, 0x74, 0x75, 0x64, 0x69, 0x65, 0x73, 0x6d, 0x69, 0x6e, 0x69, 0x6d, + 0x75, 0x6d, 0x70, 0x65, 0x72, 0x68, 0x61, 0x70, 0x73, 0x6d, 0x6f, 0x72, 0x6e, + 0x69, 0x6e, 0x67, 0x73, 0x65, 0x6c, 0x6c, 0x69, 0x6e, 0x67, 0x69, 0x73, 0x20, + 0x75, 0x73, 0x65, 0x64, 0x72, 0x65, 0x76, 0x65, 0x72, 0x73, 0x65, 0x76, 0x61, + 0x72, 0x69, 0x61, 0x6e, 0x74, 0x20, 0x72, 0x6f, 0x6c, 0x65, 0x3d, 0x22, 0x6d, + 0x69, 0x73, 0x73, 0x69, 0x6e, 0x67, 0x61, 0x63, 0x68, 0x69, 0x65, 0x76, 0x65, + 0x70, 0x72, 0x6f, 0x6d, 0x6f, 0x74, 0x65, 0x73, 0x74, 0x75, 0x64, 0x65, 0x6e, + 0x74, 0x73, 0x6f, 0x6d, 0x65, 0x6f, 0x6e, 0x65, 0x65, 0x78, 0x74, 0x72, 0x65, + 0x6d, 0x65, 0x72, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x62, 0x6f, 0x74, 0x74, + 0x6f, 0x6d, 0x3a, 0x65, 0x76, 0x6f, 0x6c, 0x76, 0x65, 0x64, 0x61, 0x6c, 0x6c, + 0x20, 0x74, 0x68, 0x65, 0x73, 0x69, 0x74, 0x65, 0x6d, 0x61, 0x70, 0x65, 0x6e, + 0x67, 0x6c, 0x69, 0x73, 0x68, 0x77, 0x61, 0x79, 0x20, 0x74, 0x6f, 0x20, 0x20, + 0x41, 0x75, 0x67, 0x75, 0x73, 0x74, 0x73, 0x79, 0x6d, 0x62, 0x6f, 0x6c, 0x73, + 0x43, 0x6f, 0x6d, 0x70, 0x61, 0x6e, 0x79, 0x6d, 0x61, 0x74, 0x74, 0x65, 0x72, + 0x73, 0x6d, 0x75, 0x73, 0x69, 0x63, 0x61, 0x6c, 0x61, 0x67, 0x61, 0x69, 0x6e, + 0x73, 0x74, 0x73, 0x65, 0x72, 0x76, 0x69, 0x6e, 0x67, 0x7d, 0x29, 0x28, 0x29, + 0x3b, 0x0d, 0x0a, 0x70, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x74, 0x72, 0x6f, + 0x75, 0x62, 0x6c, 0x65, 0x63, 0x6f, 0x6e, 0x63, 0x65, 0x70, 0x74, 0x63, 0x6f, + 0x6d, 0x70, 0x61, 0x72, 0x65, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x73, 0x70, + 0x6c, 0x61, 0x79, 0x65, 0x72, 0x73, 0x72, 0x65, 0x67, 0x69, 0x6f, 0x6e, 0x73, + 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x20, 0x27, 0x27, 0x54, 0x68, 0x65, + 0x20, 0x77, 0x69, 0x6e, 0x6e, 0x69, 0x6e, 0x67, 0x65, 0x78, 0x70, 0x6c, 0x6f, + 0x72, 0x65, 0x61, 0x64, 0x61, 0x70, 0x74, 0x65, 0x64, 0x47, 0x61, 0x6c, 0x6c, + 0x65, 0x72, 0x79, 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x65, 0x61, 0x62, 0x69, + 0x6c, 0x69, 0x74, 0x79, 0x65, 0x6e, 0x68, 0x61, 0x6e, 0x63, 0x65, 0x63, 0x61, + 0x72, 0x65, 0x65, 0x72, 0x73, 0x29, 0x2e, 0x20, 0x54, 0x68, 0x65, 0x20, 0x63, + 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x20, + 0x61, 0x6e, 0x63, 0x69, 0x65, 0x6e, 0x74, 0x65, 0x78, 0x69, 0x73, 0x74, 0x65, + 0x64, 0x66, 0x6f, 0x6f, 0x74, 0x65, 0x72, 0x20, 0x68, 0x61, 0x6e, 0x64, 0x6c, + 0x65, 0x72, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x65, 0x64, 0x63, 0x6f, 0x6e, 0x73, + 0x6f, 0x6c, 0x65, 0x45, 0x61, 0x73, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x78, 0x70, + 0x6f, 0x72, 0x74, 0x73, 0x77, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x73, 0x43, 0x68, + 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x69, 0x6c, 0x6c, 0x65, 0x67, 0x61, 0x6c, 0x6e, + 0x65, 0x75, 0x74, 0x72, 0x61, 0x6c, 0x73, 0x75, 0x67, 0x67, 0x65, 0x73, 0x74, + 0x5f, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x73, 0x69, 0x67, 0x6e, 0x69, 0x6e, + 0x67, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0x22, 0x3e, 0x73, 0x65, 0x74, 0x74, 0x6c, + 0x65, 0x64, 0x77, 0x65, 0x73, 0x74, 0x65, 0x72, 0x6e, 0x63, 0x61, 0x75, 0x73, + 0x69, 0x6e, 0x67, 0x2d, 0x77, 0x65, 0x62, 0x6b, 0x69, 0x74, 0x63, 0x6c, 0x61, + 0x69, 0x6d, 0x65, 0x64, 0x4a, 0x75, 0x73, 0x74, 0x69, 0x63, 0x65, 0x63, 0x68, + 0x61, 0x70, 0x74, 0x65, 0x72, 0x76, 0x69, 0x63, 0x74, 0x69, 0x6d, 0x73, 0x54, + 0x68, 0x6f, 0x6d, 0x61, 0x73, 0x20, 0x6d, 0x6f, 0x7a, 0x69, 0x6c, 0x6c, 0x61, + 0x70, 0x72, 0x6f, 0x6d, 0x69, 0x73, 0x65, 0x70, 0x61, 0x72, 0x74, 0x69, 0x65, + 0x73, 0x65, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x6f, 0x75, 0x74, 0x73, 0x69, + 0x64, 0x65, 0x3a, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x2c, 0x68, 0x75, 0x6e, 0x64, + 0x72, 0x65, 0x64, 0x4f, 0x6c, 0x79, 0x6d, 0x70, 0x69, 0x63, 0x5f, 0x62, 0x75, + 0x74, 0x74, 0x6f, 0x6e, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x73, 0x72, 0x65, + 0x61, 0x63, 0x68, 0x65, 0x64, 0x63, 0x68, 0x72, 0x6f, 0x6e, 0x69, 0x63, 0x64, + 0x65, 0x6d, 0x61, 0x6e, 0x64, 0x73, 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x73, + 0x70, 0x72, 0x6f, 0x74, 0x65, 0x63, 0x74, 0x61, 0x64, 0x6f, 0x70, 0x74, 0x65, + 0x64, 0x70, 0x72, 0x65, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x65, 0x69, 0x74, 0x68, + 0x65, 0x72, 0x67, 0x72, 0x65, 0x61, 0x74, 0x6c, 0x79, 0x67, 0x72, 0x65, 0x61, + 0x74, 0x65, 0x72, 0x6f, 0x76, 0x65, 0x72, 0x61, 0x6c, 0x6c, 0x69, 0x6d, 0x70, + 0x72, 0x6f, 0x76, 0x65, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x73, 0x70, + 0x65, 0x63, 0x69, 0x61, 0x6c, 0x73, 0x65, 0x61, 0x72, 0x63, 0x68, 0x2e, 0x77, + 0x6f, 0x72, 0x73, 0x68, 0x69, 0x70, 0x66, 0x75, 0x6e, 0x64, 0x69, 0x6e, 0x67, + 0x74, 0x68, 0x6f, 0x75, 0x67, 0x68, 0x74, 0x68, 0x69, 0x67, 0x68, 0x65, 0x73, + 0x74, 0x69, 0x6e, 0x73, 0x74, 0x65, 0x61, 0x64, 0x75, 0x74, 0x69, 0x6c, 0x69, + 0x74, 0x79, 0x71, 0x75, 0x61, 0x72, 0x74, 0x65, 0x72, 0x43, 0x75, 0x6c, 0x74, + 0x75, 0x72, 0x65, 0x74, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x67, 0x63, 0x6c, 0x65, + 0x61, 0x72, 0x6c, 0x79, 0x65, 0x78, 0x70, 0x6f, 0x73, 0x65, 0x64, 0x42, 0x72, + 0x6f, 0x77, 0x73, 0x65, 0x72, 0x6c, 0x69, 0x62, 0x65, 0x72, 0x61, 0x6c, 0x7d, + 0x20, 0x63, 0x61, 0x74, 0x63, 0x68, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, + 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x68, 0x69, 0x64, 0x65, 0x28, 0x29, + 0x3b, 0x46, 0x6c, 0x6f, 0x72, 0x69, 0x64, 0x61, 0x61, 0x6e, 0x73, 0x77, 0x65, + 0x72, 0x73, 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x65, 0x64, 0x45, 0x6d, 0x70, 0x65, + 0x72, 0x6f, 0x72, 0x64, 0x65, 0x66, 0x65, 0x6e, 0x73, 0x65, 0x73, 0x65, 0x72, + 0x69, 0x6f, 0x75, 0x73, 0x66, 0x72, 0x65, 0x65, 0x64, 0x6f, 0x6d, 0x53, 0x65, + 0x76, 0x65, 0x72, 0x61, 0x6c, 0x2d, 0x62, 0x75, 0x74, 0x74, 0x6f, 0x6e, 0x46, + 0x75, 0x72, 0x74, 0x68, 0x65, 0x72, 0x6f, 0x75, 0x74, 0x20, 0x6f, 0x66, 0x20, + 0x21, 0x3d, 0x20, 0x6e, 0x75, 0x6c, 0x6c, 0x74, 0x72, 0x61, 0x69, 0x6e, 0x65, + 0x64, 0x44, 0x65, 0x6e, 0x6d, 0x61, 0x72, 0x6b, 0x76, 0x6f, 0x69, 0x64, 0x28, + 0x30, 0x29, 0x2f, 0x61, 0x6c, 0x6c, 0x2e, 0x6a, 0x73, 0x70, 0x72, 0x65, 0x76, + 0x65, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x53, 0x74, 0x65, + 0x70, 0x68, 0x65, 0x6e, 0x0a, 0x0a, 0x57, 0x68, 0x65, 0x6e, 0x20, 0x6f, 0x62, + 0x73, 0x65, 0x72, 0x76, 0x65, 0x3c, 0x2f, 0x68, 0x32, 0x3e, 0x0d, 0x0a, 0x4d, + 0x6f, 0x64, 0x65, 0x72, 0x6e, 0x20, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, + 0x22, 0x20, 0x61, 0x6c, 0x74, 0x3d, 0x22, 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, + 0x73, 0x2e, 0x0a, 0x0a, 0x46, 0x6f, 0x72, 0x20, 0x0a, 0x0a, 0x4d, 0x61, 0x6e, + 0x79, 0x20, 0x61, 0x72, 0x74, 0x69, 0x73, 0x74, 0x73, 0x70, 0x6f, 0x77, 0x65, + 0x72, 0x65, 0x64, 0x70, 0x65, 0x72, 0x66, 0x6f, 0x72, 0x6d, 0x66, 0x69, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x74, 0x79, 0x70, 0x65, 0x20, 0x6f, 0x66, 0x6d, 0x65, + 0x64, 0x69, 0x63, 0x61, 0x6c, 0x74, 0x69, 0x63, 0x6b, 0x65, 0x74, 0x73, 0x6f, + 0x70, 0x70, 0x6f, 0x73, 0x65, 0x64, 0x43, 0x6f, 0x75, 0x6e, 0x63, 0x69, 0x6c, + 0x77, 0x69, 0x74, 0x6e, 0x65, 0x73, 0x73, 0x6a, 0x75, 0x73, 0x74, 0x69, 0x63, + 0x65, 0x47, 0x65, 0x6f, 0x72, 0x67, 0x65, 0x20, 0x42, 0x65, 0x6c, 0x67, 0x69, + 0x75, 0x6d, 0x2e, 0x2e, 0x2e, 0x3c, 0x2f, 0x61, 0x3e, 0x74, 0x77, 0x69, 0x74, + 0x74, 0x65, 0x72, 0x6e, 0x6f, 0x74, 0x61, 0x62, 0x6c, 0x79, 0x77, 0x61, 0x69, + 0x74, 0x69, 0x6e, 0x67, 0x77, 0x61, 0x72, 0x66, 0x61, 0x72, 0x65, 0x20, 0x4f, + 0x74, 0x68, 0x65, 0x72, 0x20, 0x72, 0x61, 0x6e, 0x6b, 0x69, 0x6e, 0x67, 0x70, + 0x68, 0x72, 0x61, 0x73, 0x65, 0x73, 0x6d, 0x65, 0x6e, 0x74, 0x69, 0x6f, 0x6e, + 0x73, 0x75, 0x72, 0x76, 0x69, 0x76, 0x65, 0x73, 0x63, 0x68, 0x6f, 0x6c, 0x61, + 0x72, 0x3c, 0x2f, 0x70, 0x3e, 0x0d, 0x0a, 0x20, 0x43, 0x6f, 0x75, 0x6e, 0x74, + 0x72, 0x79, 0x69, 0x67, 0x6e, 0x6f, 0x72, 0x65, 0x64, 0x6c, 0x6f, 0x73, 0x73, + 0x20, 0x6f, 0x66, 0x6a, 0x75, 0x73, 0x74, 0x20, 0x61, 0x73, 0x47, 0x65, 0x6f, + 0x72, 0x67, 0x69, 0x61, 0x73, 0x74, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x3c, 0x68, + 0x65, 0x61, 0x64, 0x3e, 0x3c, 0x73, 0x74, 0x6f, 0x70, 0x70, 0x65, 0x64, 0x31, + 0x27, 0x5d, 0x29, 0x3b, 0x0d, 0x0a, 0x69, 0x73, 0x6c, 0x61, 0x6e, 0x64, 0x73, + 0x6e, 0x6f, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, + 0x3a, 0x6c, 0x69, 0x73, 0x74, 0x20, 0x6f, 0x66, 0x63, 0x61, 0x72, 0x72, 0x69, + 0x65, 0x64, 0x31, 0x30, 0x30, 0x2c, 0x30, 0x30, 0x30, 0x3c, 0x2f, 0x68, 0x33, + 0x3e, 0x0a, 0x20, 0x73, 0x65, 0x76, 0x65, 0x72, 0x61, 0x6c, 0x62, 0x65, 0x63, + 0x6f, 0x6d, 0x65, 0x73, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x20, 0x77, 0x65, + 0x64, 0x64, 0x69, 0x6e, 0x67, 0x30, 0x30, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0x6d, + 0x6f, 0x6e, 0x61, 0x72, 0x63, 0x68, 0x6f, 0x66, 0x66, 0x20, 0x74, 0x68, 0x65, + 0x74, 0x65, 0x61, 0x63, 0x68, 0x65, 0x72, 0x68, 0x69, 0x67, 0x68, 0x6c, 0x79, + 0x20, 0x62, 0x69, 0x6f, 0x6c, 0x6f, 0x67, 0x79, 0x6c, 0x69, 0x66, 0x65, 0x20, + 0x6f, 0x66, 0x6f, 0x72, 0x20, 0x65, 0x76, 0x65, 0x6e, 0x72, 0x69, 0x73, 0x65, + 0x20, 0x6f, 0x66, 0x26, 0x72, 0x61, 0x71, 0x75, 0x6f, 0x3b, 0x70, 0x6c, 0x75, + 0x73, 0x6f, 0x6e, 0x65, 0x68, 0x75, 0x6e, 0x74, 0x69, 0x6e, 0x67, 0x28, 0x74, + 0x68, 0x6f, 0x75, 0x67, 0x68, 0x44, 0x6f, 0x75, 0x67, 0x6c, 0x61, 0x73, 0x6a, + 0x6f, 0x69, 0x6e, 0x69, 0x6e, 0x67, 0x63, 0x69, 0x72, 0x63, 0x6c, 0x65, 0x73, + 0x46, 0x6f, 0x72, 0x20, 0x74, 0x68, 0x65, 0x41, 0x6e, 0x63, 0x69, 0x65, 0x6e, + 0x74, 0x56, 0x69, 0x65, 0x74, 0x6e, 0x61, 0x6d, 0x76, 0x65, 0x68, 0x69, 0x63, + 0x6c, 0x65, 0x73, 0x75, 0x63, 0x68, 0x20, 0x61, 0x73, 0x63, 0x72, 0x79, 0x73, + 0x74, 0x61, 0x6c, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x20, 0x3d, 0x57, 0x69, 0x6e, + 0x64, 0x6f, 0x77, 0x73, 0x65, 0x6e, 0x6a, 0x6f, 0x79, 0x65, 0x64, 0x61, 0x20, + 0x73, 0x6d, 0x61, 0x6c, 0x6c, 0x61, 0x73, 0x73, 0x75, 0x6d, 0x65, 0x64, 0x3c, + 0x61, 0x20, 0x69, 0x64, 0x3d, 0x22, 0x66, 0x6f, 0x72, 0x65, 0x69, 0x67, 0x6e, + 0x20, 0x41, 0x6c, 0x6c, 0x20, 0x72, 0x69, 0x68, 0x6f, 0x77, 0x20, 0x74, 0x68, + 0x65, 0x44, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x72, 0x65, 0x74, 0x69, 0x72, + 0x65, 0x64, 0x68, 0x6f, 0x77, 0x65, 0x76, 0x65, 0x72, 0x68, 0x69, 0x64, 0x64, + 0x65, 0x6e, 0x3b, 0x62, 0x61, 0x74, 0x74, 0x6c, 0x65, 0x73, 0x73, 0x65, 0x65, + 0x6b, 0x69, 0x6e, 0x67, 0x63, 0x61, 0x62, 0x69, 0x6e, 0x65, 0x74, 0x77, 0x61, + 0x73, 0x20, 0x6e, 0x6f, 0x74, 0x6c, 0x6f, 0x6f, 0x6b, 0x20, 0x61, 0x74, 0x63, + 0x6f, 0x6e, 0x64, 0x75, 0x63, 0x74, 0x67, 0x65, 0x74, 0x20, 0x74, 0x68, 0x65, + 0x4a, 0x61, 0x6e, 0x75, 0x61, 0x72, 0x79, 0x68, 0x61, 0x70, 0x70, 0x65, 0x6e, + 0x73, 0x74, 0x75, 0x72, 0x6e, 0x69, 0x6e, 0x67, 0x61, 0x3a, 0x68, 0x6f, 0x76, + 0x65, 0x72, 0x4f, 0x6e, 0x6c, 0x69, 0x6e, 0x65, 0x20, 0x46, 0x72, 0x65, 0x6e, + 0x63, 0x68, 0x20, 0x6c, 0x61, 0x63, 0x6b, 0x69, 0x6e, 0x67, 0x74, 0x79, 0x70, + 0x69, 0x63, 0x61, 0x6c, 0x65, 0x78, 0x74, 0x72, 0x61, 0x63, 0x74, 0x65, 0x6e, + 0x65, 0x6d, 0x69, 0x65, 0x73, 0x65, 0x76, 0x65, 0x6e, 0x20, 0x69, 0x66, 0x67, + 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x64, 0x65, 0x63, 0x69, 0x64, 0x65, 0x64, + 0x61, 0x72, 0x65, 0x20, 0x6e, 0x6f, 0x74, 0x2f, 0x73, 0x65, 0x61, 0x72, 0x63, + 0x68, 0x62, 0x65, 0x6c, 0x69, 0x65, 0x66, 0x73, 0x2d, 0x69, 0x6d, 0x61, 0x67, + 0x65, 0x3a, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x65, 0x64, 0x73, 0x74, 0x61, 0x74, + 0x69, 0x63, 0x2e, 0x6c, 0x6f, 0x67, 0x69, 0x6e, 0x22, 0x3e, 0x63, 0x6f, 0x6e, + 0x76, 0x65, 0x72, 0x74, 0x76, 0x69, 0x6f, 0x6c, 0x65, 0x6e, 0x74, 0x65, 0x6e, + 0x74, 0x65, 0x72, 0x65, 0x64, 0x66, 0x69, 0x72, 0x73, 0x74, 0x22, 0x3e, 0x63, + 0x69, 0x72, 0x63, 0x75, 0x69, 0x74, 0x46, 0x69, 0x6e, 0x6c, 0x61, 0x6e, 0x64, + 0x63, 0x68, 0x65, 0x6d, 0x69, 0x73, 0x74, 0x73, 0x68, 0x65, 0x20, 0x77, 0x61, + 0x73, 0x31, 0x30, 0x70, 0x78, 0x3b, 0x22, 0x3e, 0x61, 0x73, 0x20, 0x73, 0x75, + 0x63, 0x68, 0x64, 0x69, 0x76, 0x69, 0x64, 0x65, 0x64, 0x3c, 0x2f, 0x73, 0x70, + 0x61, 0x6e, 0x3e, 0x77, 0x69, 0x6c, 0x6c, 0x20, 0x62, 0x65, 0x6c, 0x69, 0x6e, + 0x65, 0x20, 0x6f, 0x66, 0x61, 0x20, 0x67, 0x72, 0x65, 0x61, 0x74, 0x6d, 0x79, + 0x73, 0x74, 0x65, 0x72, 0x79, 0x2f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x2e, 0x66, + 0x61, 0x6c, 0x6c, 0x69, 0x6e, 0x67, 0x64, 0x75, 0x65, 0x20, 0x74, 0x6f, 0x20, + 0x72, 0x61, 0x69, 0x6c, 0x77, 0x61, 0x79, 0x63, 0x6f, 0x6c, 0x6c, 0x65, 0x67, + 0x65, 0x6d, 0x6f, 0x6e, 0x73, 0x74, 0x65, 0x72, 0x64, 0x65, 0x73, 0x63, 0x65, + 0x6e, 0x74, 0x69, 0x74, 0x20, 0x77, 0x69, 0x74, 0x68, 0x6e, 0x75, 0x63, 0x6c, + 0x65, 0x61, 0x72, 0x4a, 0x65, 0x77, 0x69, 0x73, 0x68, 0x20, 0x70, 0x72, 0x6f, + 0x74, 0x65, 0x73, 0x74, 0x42, 0x72, 0x69, 0x74, 0x69, 0x73, 0x68, 0x66, 0x6c, + 0x6f, 0x77, 0x65, 0x72, 0x73, 0x70, 0x72, 0x65, 0x64, 0x69, 0x63, 0x74, 0x72, + 0x65, 0x66, 0x6f, 0x72, 0x6d, 0x73, 0x62, 0x75, 0x74, 0x74, 0x6f, 0x6e, 0x20, + 0x77, 0x68, 0x6f, 0x20, 0x77, 0x61, 0x73, 0x6c, 0x65, 0x63, 0x74, 0x75, 0x72, + 0x65, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x74, 0x73, 0x75, 0x69, 0x63, 0x69, + 0x64, 0x65, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x69, 0x63, 0x70, 0x65, 0x72, 0x69, + 0x6f, 0x64, 0x73, 0x6d, 0x61, 0x72, 0x6b, 0x65, 0x74, 0x73, 0x53, 0x6f, 0x63, + 0x69, 0x61, 0x6c, 0x20, 0x66, 0x69, 0x73, 0x68, 0x69, 0x6e, 0x67, 0x63, 0x6f, + 0x6d, 0x62, 0x69, 0x6e, 0x65, 0x67, 0x72, 0x61, 0x70, 0x68, 0x69, 0x63, 0x77, + 0x69, 0x6e, 0x6e, 0x65, 0x72, 0x73, 0x3c, 0x62, 0x72, 0x20, 0x2f, 0x3e, 0x3c, + 0x62, 0x79, 0x20, 0x74, 0x68, 0x65, 0x20, 0x4e, 0x61, 0x74, 0x75, 0x72, 0x61, + 0x6c, 0x50, 0x72, 0x69, 0x76, 0x61, 0x63, 0x79, 0x63, 0x6f, 0x6f, 0x6b, 0x69, + 0x65, 0x73, 0x6f, 0x75, 0x74, 0x63, 0x6f, 0x6d, 0x65, 0x72, 0x65, 0x73, 0x6f, + 0x6c, 0x76, 0x65, 0x53, 0x77, 0x65, 0x64, 0x69, 0x73, 0x68, 0x62, 0x72, 0x69, + 0x65, 0x66, 0x6c, 0x79, 0x50, 0x65, 0x72, 0x73, 0x69, 0x61, 0x6e, 0x73, 0x6f, + 0x20, 0x6d, 0x75, 0x63, 0x68, 0x43, 0x65, 0x6e, 0x74, 0x75, 0x72, 0x79, 0x64, + 0x65, 0x70, 0x69, 0x63, 0x74, 0x73, 0x63, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x73, + 0x68, 0x6f, 0x75, 0x73, 0x69, 0x6e, 0x67, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, + 0x73, 0x6e, 0x65, 0x78, 0x74, 0x20, 0x74, 0x6f, 0x62, 0x65, 0x61, 0x72, 0x69, + 0x6e, 0x67, 0x6d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x72, 0x65, 0x76, 0x69, + 0x73, 0x65, 0x64, 0x6a, 0x51, 0x75, 0x65, 0x72, 0x79, 0x28, 0x2d, 0x77, 0x69, + 0x64, 0x74, 0x68, 0x3a, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x22, 0x3e, 0x74, 0x6f, + 0x6f, 0x6c, 0x74, 0x69, 0x70, 0x53, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x64, + 0x65, 0x73, 0x69, 0x67, 0x6e, 0x73, 0x54, 0x75, 0x72, 0x6b, 0x69, 0x73, 0x68, + 0x79, 0x6f, 0x75, 0x6e, 0x67, 0x65, 0x72, 0x2e, 0x6d, 0x61, 0x74, 0x63, 0x68, + 0x28, 0x7d, 0x29, 0x28, 0x29, 0x3b, 0x0a, 0x0a, 0x62, 0x75, 0x72, 0x6e, 0x69, + 0x6e, 0x67, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x65, 0x64, 0x65, 0x67, 0x72, + 0x65, 0x65, 0x73, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x3d, 0x52, 0x69, 0x63, + 0x68, 0x61, 0x72, 0x64, 0x63, 0x6c, 0x6f, 0x73, 0x65, 0x6c, 0x79, 0x70, 0x6c, + 0x61, 0x73, 0x74, 0x69, 0x63, 0x65, 0x6e, 0x74, 0x72, 0x69, 0x65, 0x73, 0x3c, + 0x2f, 0x74, 0x72, 0x3e, 0x0d, 0x0a, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x23, + 0x75, 0x6c, 0x20, 0x69, 0x64, 0x3d, 0x22, 0x70, 0x6f, 0x73, 0x73, 0x65, 0x73, + 0x73, 0x72, 0x6f, 0x6c, 0x6c, 0x69, 0x6e, 0x67, 0x70, 0x68, 0x79, 0x73, 0x69, + 0x63, 0x73, 0x66, 0x61, 0x69, 0x6c, 0x69, 0x6e, 0x67, 0x65, 0x78, 0x65, 0x63, + 0x75, 0x74, 0x65, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x73, 0x74, 0x6c, 0x69, 0x6e, + 0x6b, 0x20, 0x74, 0x6f, 0x44, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x3c, 0x62, + 0x72, 0x20, 0x2f, 0x3e, 0x0a, 0x3a, 0x20, 0x74, 0x72, 0x75, 0x65, 0x2c, 0x63, + 0x68, 0x61, 0x72, 0x74, 0x65, 0x72, 0x74, 0x6f, 0x75, 0x72, 0x69, 0x73, 0x6d, + 0x63, 0x6c, 0x61, 0x73, 0x73, 0x69, 0x63, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x65, + 0x64, 0x65, 0x78, 0x70, 0x6c, 0x61, 0x69, 0x6e, 0x3c, 0x2f, 0x68, 0x31, 0x3e, + 0x0d, 0x0a, 0x6f, 0x6e, 0x6c, 0x69, 0x6e, 0x65, 0x2e, 0x3f, 0x78, 0x6d, 0x6c, + 0x20, 0x76, 0x65, 0x68, 0x65, 0x6c, 0x70, 0x69, 0x6e, 0x67, 0x64, 0x69, 0x61, + 0x6d, 0x6f, 0x6e, 0x64, 0x75, 0x73, 0x65, 0x20, 0x74, 0x68, 0x65, 0x61, 0x69, + 0x72, 0x6c, 0x69, 0x6e, 0x65, 0x65, 0x6e, 0x64, 0x20, 0x2d, 0x2d, 0x3e, 0x29, + 0x2e, 0x61, 0x74, 0x74, 0x72, 0x28, 0x72, 0x65, 0x61, 0x64, 0x65, 0x72, 0x73, + 0x68, 0x6f, 0x73, 0x74, 0x69, 0x6e, 0x67, 0x23, 0x66, 0x66, 0x66, 0x66, 0x66, + 0x66, 0x72, 0x65, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x56, 0x69, 0x6e, 0x63, 0x65, + 0x6e, 0x74, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x6c, 0x73, 0x20, 0x73, 0x72, 0x63, + 0x3d, 0x22, 0x2f, 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x64, 0x65, 0x73, + 0x70, 0x69, 0x74, 0x65, 0x64, 0x69, 0x76, 0x65, 0x72, 0x73, 0x65, 0x74, 0x65, + 0x6c, 0x6c, 0x69, 0x6e, 0x67, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x20, 0x68, + 0x65, 0x6c, 0x64, 0x20, 0x69, 0x6e, 0x4a, 0x6f, 0x73, 0x65, 0x70, 0x68, 0x20, + 0x74, 0x68, 0x65, 0x61, 0x74, 0x72, 0x65, 0x61, 0x66, 0x66, 0x65, 0x63, 0x74, + 0x73, 0x3c, 0x73, 0x74, 0x79, 0x6c, 0x65, 0x3e, 0x61, 0x20, 0x6c, 0x61, 0x72, + 0x67, 0x65, 0x64, 0x6f, 0x65, 0x73, 0x6e, 0x27, 0x74, 0x6c, 0x61, 0x74, 0x65, + 0x72, 0x2c, 0x20, 0x45, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x66, 0x61, 0x76, + 0x69, 0x63, 0x6f, 0x6e, 0x63, 0x72, 0x65, 0x61, 0x74, 0x6f, 0x72, 0x48, 0x75, + 0x6e, 0x67, 0x61, 0x72, 0x79, 0x41, 0x69, 0x72, 0x70, 0x6f, 0x72, 0x74, 0x73, + 0x65, 0x65, 0x20, 0x74, 0x68, 0x65, 0x73, 0x6f, 0x20, 0x74, 0x68, 0x61, 0x74, + 0x4d, 0x69, 0x63, 0x68, 0x61, 0x65, 0x6c, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, + 0x73, 0x50, 0x72, 0x6f, 0x67, 0x72, 0x61, 0x6d, 0x73, 0x2c, 0x20, 0x61, 0x6e, + 0x64, 0x20, 0x20, 0x77, 0x69, 0x64, 0x74, 0x68, 0x3d, 0x65, 0x26, 0x71, 0x75, + 0x6f, 0x74, 0x3b, 0x74, 0x72, 0x61, 0x64, 0x69, 0x6e, 0x67, 0x6c, 0x65, 0x66, + 0x74, 0x22, 0x3e, 0x0a, 0x70, 0x65, 0x72, 0x73, 0x6f, 0x6e, 0x73, 0x47, 0x6f, + 0x6c, 0x64, 0x65, 0x6e, 0x20, 0x41, 0x66, 0x66, 0x61, 0x69, 0x72, 0x73, 0x67, + 0x72, 0x61, 0x6d, 0x6d, 0x61, 0x72, 0x66, 0x6f, 0x72, 0x6d, 0x69, 0x6e, 0x67, + 0x64, 0x65, 0x73, 0x74, 0x72, 0x6f, 0x79, 0x69, 0x64, 0x65, 0x61, 0x20, 0x6f, + 0x66, 0x63, 0x61, 0x73, 0x65, 0x20, 0x6f, 0x66, 0x6f, 0x6c, 0x64, 0x65, 0x73, + 0x74, 0x20, 0x74, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, 0x2e, 0x73, 0x72, 0x63, + 0x20, 0x3d, 0x20, 0x63, 0x61, 0x72, 0x74, 0x6f, 0x6f, 0x6e, 0x72, 0x65, 0x67, + 0x69, 0x73, 0x74, 0x72, 0x43, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x73, 0x4d, 0x75, + 0x73, 0x6c, 0x69, 0x6d, 0x73, 0x57, 0x68, 0x61, 0x74, 0x20, 0x69, 0x73, 0x69, + 0x6e, 0x20, 0x6d, 0x61, 0x6e, 0x79, 0x6d, 0x61, 0x72, 0x6b, 0x69, 0x6e, 0x67, + 0x72, 0x65, 0x76, 0x65, 0x61, 0x6c, 0x73, 0x49, 0x6e, 0x64, 0x65, 0x65, 0x64, + 0x2c, 0x65, 0x71, 0x75, 0x61, 0x6c, 0x6c, 0x79, 0x2f, 0x73, 0x68, 0x6f, 0x77, + 0x5f, 0x61, 0x6f, 0x75, 0x74, 0x64, 0x6f, 0x6f, 0x72, 0x65, 0x73, 0x63, 0x61, + 0x70, 0x65, 0x28, 0x41, 0x75, 0x73, 0x74, 0x72, 0x69, 0x61, 0x67, 0x65, 0x6e, + 0x65, 0x74, 0x69, 0x63, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x2c, 0x49, 0x6e, + 0x20, 0x74, 0x68, 0x65, 0x20, 0x73, 0x69, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x48, + 0x65, 0x20, 0x61, 0x6c, 0x73, 0x6f, 0x49, 0x73, 0x6c, 0x61, 0x6e, 0x64, 0x73, + 0x41, 0x63, 0x61, 0x64, 0x65, 0x6d, 0x79, 0x0a, 0x09, 0x09, 0x3c, 0x21, 0x2d, + 0x2d, 0x44, 0x61, 0x6e, 0x69, 0x65, 0x6c, 0x20, 0x62, 0x69, 0x6e, 0x64, 0x69, + 0x6e, 0x67, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x22, 0x3e, 0x69, 0x6d, 0x70, 0x6f, + 0x73, 0x65, 0x64, 0x75, 0x74, 0x69, 0x6c, 0x69, 0x7a, 0x65, 0x41, 0x62, 0x72, + 0x61, 0x68, 0x61, 0x6d, 0x28, 0x65, 0x78, 0x63, 0x65, 0x70, 0x74, 0x7b, 0x77, + 0x69, 0x64, 0x74, 0x68, 0x3a, 0x70, 0x75, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x29, + 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0x28, 0x7c, 0x7c, 0x20, 0x5b, 0x5d, 0x3b, 0x0a, + 0x44, 0x41, 0x54, 0x41, 0x5b, 0x20, 0x2a, 0x6b, 0x69, 0x74, 0x63, 0x68, 0x65, + 0x6e, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x64, 0x61, 0x63, 0x74, 0x75, 0x61, + 0x6c, 0x20, 0x64, 0x69, 0x61, 0x6c, 0x65, 0x63, 0x74, 0x6d, 0x61, 0x69, 0x6e, + 0x6c, 0x79, 0x20, 0x5f, 0x62, 0x6c, 0x61, 0x6e, 0x6b, 0x27, 0x69, 0x6e, 0x73, + 0x74, 0x61, 0x6c, 0x6c, 0x65, 0x78, 0x70, 0x65, 0x72, 0x74, 0x73, 0x69, 0x66, + 0x28, 0x74, 0x79, 0x70, 0x65, 0x49, 0x74, 0x20, 0x61, 0x6c, 0x73, 0x6f, 0x26, + 0x63, 0x6f, 0x70, 0x79, 0x3b, 0x20, 0x22, 0x3e, 0x54, 0x65, 0x72, 0x6d, 0x73, + 0x62, 0x6f, 0x72, 0x6e, 0x20, 0x69, 0x6e, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, + 0x73, 0x65, 0x61, 0x73, 0x74, 0x65, 0x72, 0x6e, 0x74, 0x61, 0x6c, 0x6b, 0x69, + 0x6e, 0x67, 0x63, 0x6f, 0x6e, 0x63, 0x65, 0x72, 0x6e, 0x67, 0x61, 0x69, 0x6e, + 0x65, 0x64, 0x20, 0x6f, 0x6e, 0x67, 0x6f, 0x69, 0x6e, 0x67, 0x6a, 0x75, 0x73, + 0x74, 0x69, 0x66, 0x79, 0x63, 0x72, 0x69, 0x74, 0x69, 0x63, 0x73, 0x66, 0x61, + 0x63, 0x74, 0x6f, 0x72, 0x79, 0x69, 0x74, 0x73, 0x20, 0x6f, 0x77, 0x6e, 0x61, + 0x73, 0x73, 0x61, 0x75, 0x6c, 0x74, 0x69, 0x6e, 0x76, 0x69, 0x74, 0x65, 0x64, + 0x6c, 0x61, 0x73, 0x74, 0x69, 0x6e, 0x67, 0x68, 0x69, 0x73, 0x20, 0x6f, 0x77, + 0x6e, 0x68, 0x72, 0x65, 0x66, 0x3d, 0x22, 0x2f, 0x22, 0x20, 0x72, 0x65, 0x6c, + 0x3d, 0x22, 0x64, 0x65, 0x76, 0x65, 0x6c, 0x6f, 0x70, 0x63, 0x6f, 0x6e, 0x63, + 0x65, 0x72, 0x74, 0x64, 0x69, 0x61, 0x67, 0x72, 0x61, 0x6d, 0x64, 0x6f, 0x6c, + 0x6c, 0x61, 0x72, 0x73, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x70, 0x68, + 0x70, 0x3f, 0x69, 0x64, 0x3d, 0x61, 0x6c, 0x63, 0x6f, 0x68, 0x6f, 0x6c, 0x29, + 0x3b, 0x7d, 0x29, 0x28, 0x29, 0x3b, 0x75, 0x73, 0x69, 0x6e, 0x67, 0x20, 0x61, + 0x3e, 0x3c, 0x73, 0x70, 0x61, 0x6e, 0x3e, 0x76, 0x65, 0x73, 0x73, 0x65, 0x6c, + 0x73, 0x72, 0x65, 0x76, 0x69, 0x76, 0x61, 0x6c, 0x41, 0x64, 0x64, 0x72, 0x65, + 0x73, 0x73, 0x61, 0x6d, 0x61, 0x74, 0x65, 0x75, 0x72, 0x61, 0x6e, 0x64, 0x72, + 0x6f, 0x69, 0x64, 0x61, 0x6c, 0x6c, 0x65, 0x67, 0x65, 0x64, 0x69, 0x6c, 0x6c, + 0x6e, 0x65, 0x73, 0x73, 0x77, 0x61, 0x6c, 0x6b, 0x69, 0x6e, 0x67, 0x63, 0x65, + 0x6e, 0x74, 0x65, 0x72, 0x73, 0x71, 0x75, 0x61, 0x6c, 0x69, 0x66, 0x79, 0x6d, + 0x61, 0x74, 0x63, 0x68, 0x65, 0x73, 0x75, 0x6e, 0x69, 0x66, 0x69, 0x65, 0x64, + 0x65, 0x78, 0x74, 0x69, 0x6e, 0x63, 0x74, 0x44, 0x65, 0x66, 0x65, 0x6e, 0x73, + 0x65, 0x64, 0x69, 0x65, 0x64, 0x20, 0x69, 0x6e, 0x0a, 0x09, 0x3c, 0x21, 0x2d, + 0x2d, 0x20, 0x63, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x73, 0x6c, 0x69, 0x6e, 0x6b, + 0x69, 0x6e, 0x67, 0x4c, 0x69, 0x74, 0x74, 0x6c, 0x65, 0x20, 0x42, 0x6f, 0x6f, + 0x6b, 0x20, 0x6f, 0x66, 0x65, 0x76, 0x65, 0x6e, 0x69, 0x6e, 0x67, 0x6d, 0x69, + 0x6e, 0x2e, 0x6a, 0x73, 0x3f, 0x61, 0x72, 0x65, 0x20, 0x74, 0x68, 0x65, 0x6b, + 0x6f, 0x6e, 0x74, 0x61, 0x6b, 0x74, 0x74, 0x6f, 0x64, 0x61, 0x79, 0x27, 0x73, + 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0x22, 0x20, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, + 0x3d, 0x77, 0x65, 0x61, 0x72, 0x69, 0x6e, 0x67, 0x41, 0x6c, 0x6c, 0x20, 0x52, + 0x69, 0x67, 0x3b, 0x0a, 0x7d, 0x29, 0x28, 0x29, 0x3b, 0x72, 0x61, 0x69, 0x73, + 0x69, 0x6e, 0x67, 0x20, 0x41, 0x6c, 0x73, 0x6f, 0x2c, 0x20, 0x63, 0x72, 0x75, + 0x63, 0x69, 0x61, 0x6c, 0x61, 0x62, 0x6f, 0x75, 0x74, 0x22, 0x3e, 0x64, 0x65, + 0x63, 0x6c, 0x61, 0x72, 0x65, 0x2d, 0x2d, 0x3e, 0x0a, 0x3c, 0x73, 0x63, 0x66, + 0x69, 0x72, 0x65, 0x66, 0x6f, 0x78, 0x61, 0x73, 0x20, 0x6d, 0x75, 0x63, 0x68, + 0x61, 0x70, 0x70, 0x6c, 0x69, 0x65, 0x73, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x2c, + 0x20, 0x73, 0x2c, 0x20, 0x62, 0x75, 0x74, 0x20, 0x74, 0x79, 0x70, 0x65, 0x20, + 0x3d, 0x20, 0x0a, 0x0d, 0x0a, 0x3c, 0x21, 0x2d, 0x2d, 0x74, 0x6f, 0x77, 0x61, + 0x72, 0x64, 0x73, 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x73, 0x50, 0x72, 0x69, + 0x76, 0x61, 0x74, 0x65, 0x46, 0x6f, 0x72, 0x65, 0x69, 0x67, 0x6e, 0x50, 0x72, + 0x65, 0x6d, 0x69, 0x65, 0x72, 0x63, 0x68, 0x6f, 0x69, 0x63, 0x65, 0x73, 0x56, + 0x69, 0x72, 0x74, 0x75, 0x61, 0x6c, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x73, + 0x43, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x50, 0x6f, 0x77, 0x65, 0x72, 0x65, + 0x64, 0x69, 0x6e, 0x6c, 0x69, 0x6e, 0x65, 0x3b, 0x70, 0x6f, 0x76, 0x65, 0x72, + 0x74, 0x79, 0x63, 0x68, 0x61, 0x6d, 0x62, 0x65, 0x72, 0x4c, 0x69, 0x76, 0x69, + 0x6e, 0x67, 0x20, 0x76, 0x6f, 0x6c, 0x75, 0x6d, 0x65, 0x73, 0x41, 0x6e, 0x74, + 0x68, 0x6f, 0x6e, 0x79, 0x6c, 0x6f, 0x67, 0x69, 0x6e, 0x22, 0x20, 0x52, 0x65, + 0x6c, 0x61, 0x74, 0x65, 0x64, 0x45, 0x63, 0x6f, 0x6e, 0x6f, 0x6d, 0x79, 0x72, + 0x65, 0x61, 0x63, 0x68, 0x65, 0x73, 0x63, 0x75, 0x74, 0x74, 0x69, 0x6e, 0x67, + 0x67, 0x72, 0x61, 0x76, 0x69, 0x74, 0x79, 0x6c, 0x69, 0x66, 0x65, 0x20, 0x69, + 0x6e, 0x43, 0x68, 0x61, 0x70, 0x74, 0x65, 0x72, 0x2d, 0x73, 0x68, 0x61, 0x64, + 0x6f, 0x77, 0x4e, 0x6f, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x3c, 0x2f, 0x74, 0x64, + 0x3e, 0x0d, 0x0a, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x73, 0x74, 0x61, + 0x64, 0x69, 0x75, 0x6d, 0x77, 0x69, 0x64, 0x67, 0x65, 0x74, 0x73, 0x76, 0x61, + 0x72, 0x79, 0x69, 0x6e, 0x67, 0x74, 0x72, 0x61, 0x76, 0x65, 0x6c, 0x73, 0x68, + 0x65, 0x6c, 0x64, 0x20, 0x62, 0x79, 0x77, 0x68, 0x6f, 0x20, 0x61, 0x72, 0x65, + 0x77, 0x6f, 0x72, 0x6b, 0x20, 0x69, 0x6e, 0x66, 0x61, 0x63, 0x75, 0x6c, 0x74, + 0x79, 0x61, 0x6e, 0x67, 0x75, 0x6c, 0x61, 0x72, 0x77, 0x68, 0x6f, 0x20, 0x68, + 0x61, 0x64, 0x61, 0x69, 0x72, 0x70, 0x6f, 0x72, 0x74, 0x74, 0x6f, 0x77, 0x6e, + 0x20, 0x6f, 0x66, 0x0a, 0x0a, 0x53, 0x6f, 0x6d, 0x65, 0x20, 0x27, 0x63, 0x6c, + 0x69, 0x63, 0x6b, 0x27, 0x63, 0x68, 0x61, 0x72, 0x67, 0x65, 0x73, 0x6b, 0x65, + 0x79, 0x77, 0x6f, 0x72, 0x64, 0x69, 0x74, 0x20, 0x77, 0x69, 0x6c, 0x6c, 0x63, + 0x69, 0x74, 0x79, 0x20, 0x6f, 0x66, 0x28, 0x74, 0x68, 0x69, 0x73, 0x29, 0x3b, + 0x41, 0x6e, 0x64, 0x72, 0x65, 0x77, 0x20, 0x75, 0x6e, 0x69, 0x71, 0x75, 0x65, + 0x20, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x65, 0x64, 0x6f, 0x72, 0x20, 0x6d, 0x6f, + 0x72, 0x65, 0x33, 0x30, 0x30, 0x70, 0x78, 0x3b, 0x20, 0x72, 0x65, 0x74, 0x75, + 0x72, 0x6e, 0x3b, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x3d, 0x22, 0x70, 0x6c, 0x75, + 0x67, 0x69, 0x6e, 0x73, 0x77, 0x69, 0x74, 0x68, 0x69, 0x6e, 0x20, 0x68, 0x65, + 0x72, 0x73, 0x65, 0x6c, 0x66, 0x53, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x46, + 0x65, 0x64, 0x65, 0x72, 0x61, 0x6c, 0x76, 0x65, 0x6e, 0x74, 0x75, 0x72, 0x65, + 0x70, 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x73, 0x65, 0x6e, 0x74, 0x20, 0x74, + 0x6f, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x61, 0x63, 0x74, 0x72, 0x65, + 0x73, 0x73, 0x63, 0x6f, 0x6d, 0x65, 0x20, 0x74, 0x6f, 0x66, 0x69, 0x6e, 0x67, + 0x65, 0x72, 0x73, 0x44, 0x75, 0x6b, 0x65, 0x20, 0x6f, 0x66, 0x70, 0x65, 0x6f, + 0x70, 0x6c, 0x65, 0x2c, 0x65, 0x78, 0x70, 0x6c, 0x6f, 0x69, 0x74, 0x77, 0x68, + 0x61, 0x74, 0x20, 0x69, 0x73, 0x68, 0x61, 0x72, 0x6d, 0x6f, 0x6e, 0x79, 0x61, + 0x20, 0x6d, 0x61, 0x6a, 0x6f, 0x72, 0x22, 0x3a, 0x22, 0x68, 0x74, 0x74, 0x70, + 0x69, 0x6e, 0x20, 0x68, 0x69, 0x73, 0x20, 0x6d, 0x65, 0x6e, 0x75, 0x22, 0x3e, + 0x0a, 0x6d, 0x6f, 0x6e, 0x74, 0x68, 0x6c, 0x79, 0x6f, 0x66, 0x66, 0x69, 0x63, + 0x65, 0x72, 0x63, 0x6f, 0x75, 0x6e, 0x63, 0x69, 0x6c, 0x67, 0x61, 0x69, 0x6e, + 0x69, 0x6e, 0x67, 0x65, 0x76, 0x65, 0x6e, 0x20, 0x69, 0x6e, 0x53, 0x75, 0x6d, + 0x6d, 0x61, 0x72, 0x79, 0x64, 0x61, 0x74, 0x65, 0x20, 0x6f, 0x66, 0x6c, 0x6f, + 0x79, 0x61, 0x6c, 0x74, 0x79, 0x66, 0x69, 0x74, 0x6e, 0x65, 0x73, 0x73, 0x61, + 0x6e, 0x64, 0x20, 0x77, 0x61, 0x73, 0x65, 0x6d, 0x70, 0x65, 0x72, 0x6f, 0x72, + 0x73, 0x75, 0x70, 0x72, 0x65, 0x6d, 0x65, 0x53, 0x65, 0x63, 0x6f, 0x6e, 0x64, + 0x20, 0x68, 0x65, 0x61, 0x72, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x73, 0x73, 0x69, + 0x61, 0x6e, 0x6c, 0x6f, 0x6e, 0x67, 0x65, 0x73, 0x74, 0x41, 0x6c, 0x62, 0x65, + 0x72, 0x74, 0x61, 0x6c, 0x61, 0x74, 0x65, 0x72, 0x61, 0x6c, 0x73, 0x65, 0x74, + 0x20, 0x6f, 0x66, 0x20, 0x73, 0x6d, 0x61, 0x6c, 0x6c, 0x22, 0x3e, 0x2e, 0x61, + 0x70, 0x70, 0x65, 0x6e, 0x64, 0x64, 0x6f, 0x20, 0x77, 0x69, 0x74, 0x68, 0x66, + 0x65, 0x64, 0x65, 0x72, 0x61, 0x6c, 0x62, 0x61, 0x6e, 0x6b, 0x20, 0x6f, 0x66, + 0x62, 0x65, 0x6e, 0x65, 0x61, 0x74, 0x68, 0x44, 0x65, 0x73, 0x70, 0x69, 0x74, + 0x65, 0x43, 0x61, 0x70, 0x69, 0x74, 0x61, 0x6c, 0x67, 0x72, 0x6f, 0x75, 0x6e, + 0x64, 0x73, 0x29, 0x2c, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x70, 0x65, 0x72, 0x63, + 0x65, 0x6e, 0x74, 0x69, 0x74, 0x20, 0x66, 0x72, 0x6f, 0x6d, 0x63, 0x6c, 0x6f, + 0x73, 0x69, 0x6e, 0x67, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x49, 0x6e, + 0x73, 0x74, 0x65, 0x61, 0x64, 0x66, 0x69, 0x66, 0x74, 0x65, 0x65, 0x6e, 0x61, + 0x73, 0x20, 0x77, 0x65, 0x6c, 0x6c, 0x2e, 0x79, 0x61, 0x68, 0x6f, 0x6f, 0x2e, + 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x64, 0x66, 0x69, 0x67, 0x68, 0x74, 0x65, + 0x72, 0x6f, 0x62, 0x73, 0x63, 0x75, 0x72, 0x65, 0x72, 0x65, 0x66, 0x6c, 0x65, + 0x63, 0x74, 0x6f, 0x72, 0x67, 0x61, 0x6e, 0x69, 0x63, 0x3d, 0x20, 0x4d, 0x61, + 0x74, 0x68, 0x2e, 0x65, 0x64, 0x69, 0x74, 0x69, 0x6e, 0x67, 0x6f, 0x6e, 0x6c, + 0x69, 0x6e, 0x65, 0x20, 0x70, 0x61, 0x64, 0x64, 0x69, 0x6e, 0x67, 0x61, 0x20, + 0x77, 0x68, 0x6f, 0x6c, 0x65, 0x6f, 0x6e, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x79, + 0x65, 0x61, 0x72, 0x20, 0x6f, 0x66, 0x65, 0x6e, 0x64, 0x20, 0x6f, 0x66, 0x20, + 0x62, 0x61, 0x72, 0x72, 0x69, 0x65, 0x72, 0x77, 0x68, 0x65, 0x6e, 0x20, 0x69, + 0x74, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x20, 0x68, 0x6f, 0x6d, 0x65, 0x20, + 0x6f, 0x66, 0x72, 0x65, 0x73, 0x75, 0x6d, 0x65, 0x64, 0x72, 0x65, 0x6e, 0x61, + 0x6d, 0x65, 0x64, 0x73, 0x74, 0x72, 0x6f, 0x6e, 0x67, 0x3e, 0x68, 0x65, 0x61, + 0x74, 0x69, 0x6e, 0x67, 0x72, 0x65, 0x74, 0x61, 0x69, 0x6e, 0x73, 0x63, 0x6c, + 0x6f, 0x75, 0x64, 0x66, 0x72, 0x77, 0x61, 0x79, 0x20, 0x6f, 0x66, 0x20, 0x4d, + 0x61, 0x72, 0x63, 0x68, 0x20, 0x31, 0x6b, 0x6e, 0x6f, 0x77, 0x69, 0x6e, 0x67, + 0x69, 0x6e, 0x20, 0x70, 0x61, 0x72, 0x74, 0x42, 0x65, 0x74, 0x77, 0x65, 0x65, + 0x6e, 0x6c, 0x65, 0x73, 0x73, 0x6f, 0x6e, 0x73, 0x63, 0x6c, 0x6f, 0x73, 0x65, + 0x73, 0x74, 0x76, 0x69, 0x72, 0x74, 0x75, 0x61, 0x6c, 0x6c, 0x69, 0x6e, 0x6b, + 0x73, 0x22, 0x3e, 0x63, 0x72, 0x6f, 0x73, 0x73, 0x65, 0x64, 0x45, 0x4e, 0x44, + 0x20, 0x2d, 0x2d, 0x3e, 0x66, 0x61, 0x6d, 0x6f, 0x75, 0x73, 0x20, 0x61, 0x77, + 0x61, 0x72, 0x64, 0x65, 0x64, 0x4c, 0x69, 0x63, 0x65, 0x6e, 0x73, 0x65, 0x48, + 0x65, 0x61, 0x6c, 0x74, 0x68, 0x20, 0x66, 0x61, 0x69, 0x72, 0x6c, 0x79, 0x20, + 0x77, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x79, 0x6d, 0x69, 0x6e, 0x69, 0x6d, 0x61, + 0x6c, 0x41, 0x66, 0x72, 0x69, 0x63, 0x61, 0x6e, 0x63, 0x6f, 0x6d, 0x70, 0x65, + 0x74, 0x65, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x22, 0x3e, 0x73, 0x69, 0x6e, 0x67, + 0x69, 0x6e, 0x67, 0x66, 0x61, 0x72, 0x6d, 0x65, 0x72, 0x73, 0x42, 0x72, 0x61, + 0x73, 0x69, 0x6c, 0x29, 0x64, 0x69, 0x73, 0x63, 0x75, 0x73, 0x73, 0x72, 0x65, + 0x70, 0x6c, 0x61, 0x63, 0x65, 0x47, 0x72, 0x65, 0x67, 0x6f, 0x72, 0x79, 0x66, + 0x6f, 0x6e, 0x74, 0x20, 0x63, 0x6f, 0x70, 0x75, 0x72, 0x73, 0x75, 0x65, 0x64, + 0x61, 0x70, 0x70, 0x65, 0x61, 0x72, 0x73, 0x6d, 0x61, 0x6b, 0x65, 0x20, 0x75, + 0x70, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x65, 0x64, 0x62, 0x6f, 0x74, 0x68, 0x20, + 0x6f, 0x66, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x65, 0x64, 0x73, 0x61, 0x77, 0x20, + 0x74, 0x68, 0x65, 0x6f, 0x66, 0x66, 0x69, 0x63, 0x65, 0x73, 0x63, 0x6f, 0x6c, + 0x6f, 0x75, 0x72, 0x73, 0x69, 0x66, 0x28, 0x64, 0x6f, 0x63, 0x75, 0x77, 0x68, + 0x65, 0x6e, 0x20, 0x68, 0x65, 0x65, 0x6e, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x70, + 0x75, 0x73, 0x68, 0x28, 0x66, 0x75, 0x41, 0x75, 0x67, 0x75, 0x73, 0x74, 0x20, + 0x55, 0x54, 0x46, 0x2d, 0x38, 0x22, 0x3e, 0x46, 0x61, 0x6e, 0x74, 0x61, 0x73, + 0x79, 0x69, 0x6e, 0x20, 0x6d, 0x6f, 0x73, 0x74, 0x69, 0x6e, 0x6a, 0x75, 0x72, + 0x65, 0x64, 0x55, 0x73, 0x75, 0x61, 0x6c, 0x6c, 0x79, 0x66, 0x61, 0x72, 0x6d, + 0x69, 0x6e, 0x67, 0x63, 0x6c, 0x6f, 0x73, 0x75, 0x72, 0x65, 0x6f, 0x62, 0x6a, + 0x65, 0x63, 0x74, 0x20, 0x64, 0x65, 0x66, 0x65, 0x6e, 0x63, 0x65, 0x75, 0x73, + 0x65, 0x20, 0x6f, 0x66, 0x20, 0x4d, 0x65, 0x64, 0x69, 0x63, 0x61, 0x6c, 0x3c, + 0x62, 0x6f, 0x64, 0x79, 0x3e, 0x0a, 0x65, 0x76, 0x69, 0x64, 0x65, 0x6e, 0x74, + 0x62, 0x65, 0x20, 0x75, 0x73, 0x65, 0x64, 0x6b, 0x65, 0x79, 0x43, 0x6f, 0x64, + 0x65, 0x73, 0x69, 0x78, 0x74, 0x65, 0x65, 0x6e, 0x49, 0x73, 0x6c, 0x61, 0x6d, + 0x69, 0x63, 0x23, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x65, 0x6e, 0x74, 0x69, + 0x72, 0x65, 0x20, 0x77, 0x69, 0x64, 0x65, 0x6c, 0x79, 0x20, 0x61, 0x63, 0x74, + 0x69, 0x76, 0x65, 0x20, 0x28, 0x74, 0x79, 0x70, 0x65, 0x6f, 0x66, 0x6f, 0x6e, + 0x65, 0x20, 0x63, 0x61, 0x6e, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x20, 0x3d, 0x73, + 0x70, 0x65, 0x61, 0x6b, 0x65, 0x72, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x64, 0x73, + 0x50, 0x68, 0x79, 0x73, 0x69, 0x63, 0x73, 0x74, 0x65, 0x72, 0x72, 0x61, 0x69, + 0x6e, 0x3c, 0x74, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0x66, 0x75, 0x6e, 0x65, 0x72, + 0x61, 0x6c, 0x76, 0x69, 0x65, 0x77, 0x69, 0x6e, 0x67, 0x6d, 0x69, 0x64, 0x64, + 0x6c, 0x65, 0x20, 0x63, 0x72, 0x69, 0x63, 0x6b, 0x65, 0x74, 0x70, 0x72, 0x6f, + 0x70, 0x68, 0x65, 0x74, 0x73, 0x68, 0x69, 0x66, 0x74, 0x65, 0x64, 0x64, 0x6f, + 0x63, 0x74, 0x6f, 0x72, 0x73, 0x52, 0x75, 0x73, 0x73, 0x65, 0x6c, 0x6c, 0x20, + 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x63, 0x74, + 0x61, 0x6c, 0x67, 0x65, 0x62, 0x72, 0x61, 0x73, 0x6f, 0x63, 0x69, 0x61, 0x6c, + 0x2d, 0x62, 0x75, 0x6c, 0x6b, 0x20, 0x6f, 0x66, 0x6d, 0x61, 0x6e, 0x20, 0x61, + 0x6e, 0x64, 0x3c, 0x2f, 0x74, 0x64, 0x3e, 0x0a, 0x20, 0x68, 0x65, 0x20, 0x6c, + 0x65, 0x66, 0x74, 0x29, 0x2e, 0x76, 0x61, 0x6c, 0x28, 0x29, 0x66, 0x61, 0x6c, + 0x73, 0x65, 0x29, 0x3b, 0x6c, 0x6f, 0x67, 0x69, 0x63, 0x61, 0x6c, 0x62, 0x61, + 0x6e, 0x6b, 0x69, 0x6e, 0x67, 0x68, 0x6f, 0x6d, 0x65, 0x20, 0x74, 0x6f, 0x6e, + 0x61, 0x6d, 0x69, 0x6e, 0x67, 0x20, 0x41, 0x72, 0x69, 0x7a, 0x6f, 0x6e, 0x61, + 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x73, 0x29, 0x3b, 0x0a, 0x7d, 0x29, 0x3b, + 0x0a, 0x66, 0x6f, 0x75, 0x6e, 0x64, 0x65, 0x72, 0x69, 0x6e, 0x20, 0x74, 0x75, + 0x72, 0x6e, 0x43, 0x6f, 0x6c, 0x6c, 0x69, 0x6e, 0x73, 0x62, 0x65, 0x66, 0x6f, + 0x72, 0x65, 0x20, 0x42, 0x75, 0x74, 0x20, 0x74, 0x68, 0x65, 0x63, 0x68, 0x61, + 0x72, 0x67, 0x65, 0x64, 0x54, 0x69, 0x74, 0x6c, 0x65, 0x22, 0x3e, 0x43, 0x61, + 0x70, 0x74, 0x61, 0x69, 0x6e, 0x73, 0x70, 0x65, 0x6c, 0x6c, 0x65, 0x64, 0x67, + 0x6f, 0x64, 0x64, 0x65, 0x73, 0x73, 0x54, 0x61, 0x67, 0x20, 0x2d, 0x2d, 0x3e, + 0x41, 0x64, 0x64, 0x69, 0x6e, 0x67, 0x3a, 0x62, 0x75, 0x74, 0x20, 0x77, 0x61, + 0x73, 0x52, 0x65, 0x63, 0x65, 0x6e, 0x74, 0x20, 0x70, 0x61, 0x74, 0x69, 0x65, + 0x6e, 0x74, 0x62, 0x61, 0x63, 0x6b, 0x20, 0x69, 0x6e, 0x3d, 0x66, 0x61, 0x6c, + 0x73, 0x65, 0x26, 0x4c, 0x69, 0x6e, 0x63, 0x6f, 0x6c, 0x6e, 0x77, 0x65, 0x20, + 0x6b, 0x6e, 0x6f, 0x77, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x4a, 0x75, + 0x64, 0x61, 0x69, 0x73, 0x6d, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x20, 0x61, + 0x6c, 0x74, 0x65, 0x72, 0x65, 0x64, 0x27, 0x5d, 0x29, 0x3b, 0x0a, 0x20, 0x20, + 0x68, 0x61, 0x73, 0x20, 0x74, 0x68, 0x65, 0x75, 0x6e, 0x63, 0x6c, 0x65, 0x61, + 0x72, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x27, 0x2c, 0x62, 0x6f, 0x74, 0x68, 0x20, + 0x69, 0x6e, 0x6e, 0x6f, 0x74, 0x20, 0x61, 0x6c, 0x6c, 0x0a, 0x0a, 0x3c, 0x21, + 0x2d, 0x2d, 0x20, 0x70, 0x6c, 0x61, 0x63, 0x69, 0x6e, 0x67, 0x68, 0x61, 0x72, + 0x64, 0x20, 0x74, 0x6f, 0x20, 0x63, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x73, 0x6f, + 0x72, 0x74, 0x20, 0x6f, 0x66, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x73, 0x73, + 0x74, 0x72, 0x65, 0x65, 0x74, 0x73, 0x42, 0x65, 0x72, 0x6e, 0x61, 0x72, 0x64, + 0x61, 0x73, 0x73, 0x65, 0x72, 0x74, 0x73, 0x74, 0x65, 0x6e, 0x64, 0x20, 0x74, + 0x6f, 0x66, 0x61, 0x6e, 0x74, 0x61, 0x73, 0x79, 0x64, 0x6f, 0x77, 0x6e, 0x20, + 0x69, 0x6e, 0x68, 0x61, 0x72, 0x62, 0x6f, 0x75, 0x72, 0x46, 0x72, 0x65, 0x65, + 0x64, 0x6f, 0x6d, 0x6a, 0x65, 0x77, 0x65, 0x6c, 0x72, 0x79, 0x2f, 0x61, 0x62, + 0x6f, 0x75, 0x74, 0x2e, 0x2e, 0x73, 0x65, 0x61, 0x72, 0x63, 0x68, 0x6c, 0x65, + 0x67, 0x65, 0x6e, 0x64, 0x73, 0x69, 0x73, 0x20, 0x6d, 0x61, 0x64, 0x65, 0x6d, + 0x6f, 0x64, 0x65, 0x72, 0x6e, 0x20, 0x6f, 0x6e, 0x6c, 0x79, 0x20, 0x6f, 0x6e, + 0x6f, 0x6e, 0x6c, 0x79, 0x20, 0x74, 0x6f, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x22, + 0x20, 0x6c, 0x69, 0x6e, 0x65, 0x61, 0x72, 0x20, 0x70, 0x61, 0x69, 0x6e, 0x74, + 0x65, 0x72, 0x61, 0x6e, 0x64, 0x20, 0x6e, 0x6f, 0x74, 0x72, 0x61, 0x72, 0x65, + 0x6c, 0x79, 0x20, 0x61, 0x63, 0x72, 0x6f, 0x6e, 0x79, 0x6d, 0x64, 0x65, 0x6c, + 0x69, 0x76, 0x65, 0x72, 0x73, 0x68, 0x6f, 0x72, 0x74, 0x65, 0x72, 0x30, 0x30, + 0x26, 0x61, 0x6d, 0x70, 0x3b, 0x61, 0x73, 0x20, 0x6d, 0x61, 0x6e, 0x79, 0x77, + 0x69, 0x64, 0x74, 0x68, 0x3d, 0x22, 0x2f, 0x2a, 0x20, 0x3c, 0x21, 0x5b, 0x43, + 0x74, 0x69, 0x74, 0x6c, 0x65, 0x20, 0x3d, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, + 0x20, 0x6c, 0x6f, 0x77, 0x65, 0x73, 0x74, 0x20, 0x70, 0x69, 0x63, 0x6b, 0x65, + 0x64, 0x20, 0x65, 0x73, 0x63, 0x61, 0x70, 0x65, 0x64, 0x75, 0x73, 0x65, 0x73, + 0x20, 0x6f, 0x66, 0x70, 0x65, 0x6f, 0x70, 0x6c, 0x65, 0x73, 0x20, 0x50, 0x75, + 0x62, 0x6c, 0x69, 0x63, 0x4d, 0x61, 0x74, 0x74, 0x68, 0x65, 0x77, 0x74, 0x61, + 0x63, 0x74, 0x69, 0x63, 0x73, 0x64, 0x61, 0x6d, 0x61, 0x67, 0x65, 0x64, 0x77, + 0x61, 0x79, 0x20, 0x66, 0x6f, 0x72, 0x6c, 0x61, 0x77, 0x73, 0x20, 0x6f, 0x66, + 0x65, 0x61, 0x73, 0x79, 0x20, 0x74, 0x6f, 0x20, 0x77, 0x69, 0x6e, 0x64, 0x6f, + 0x77, 0x73, 0x74, 0x72, 0x6f, 0x6e, 0x67, 0x20, 0x20, 0x73, 0x69, 0x6d, 0x70, + 0x6c, 0x65, 0x7d, 0x63, 0x61, 0x74, 0x63, 0x68, 0x28, 0x73, 0x65, 0x76, 0x65, + 0x6e, 0x74, 0x68, 0x69, 0x6e, 0x66, 0x6f, 0x62, 0x6f, 0x78, 0x77, 0x65, 0x6e, + 0x74, 0x20, 0x74, 0x6f, 0x70, 0x61, 0x69, 0x6e, 0x74, 0x65, 0x64, 0x63, 0x69, + 0x74, 0x69, 0x7a, 0x65, 0x6e, 0x49, 0x20, 0x64, 0x6f, 0x6e, 0x27, 0x74, 0x72, + 0x65, 0x74, 0x72, 0x65, 0x61, 0x74, 0x2e, 0x20, 0x53, 0x6f, 0x6d, 0x65, 0x20, + 0x77, 0x77, 0x2e, 0x22, 0x29, 0x3b, 0x0a, 0x62, 0x6f, 0x6d, 0x62, 0x69, 0x6e, + 0x67, 0x6d, 0x61, 0x69, 0x6c, 0x74, 0x6f, 0x3a, 0x6d, 0x61, 0x64, 0x65, 0x20, + 0x69, 0x6e, 0x2e, 0x20, 0x4d, 0x61, 0x6e, 0x79, 0x20, 0x63, 0x61, 0x72, 0x72, + 0x69, 0x65, 0x73, 0x7c, 0x7c, 0x7b, 0x7d, 0x3b, 0x77, 0x69, 0x77, 0x6f, 0x72, + 0x6b, 0x20, 0x6f, 0x66, 0x73, 0x79, 0x6e, 0x6f, 0x6e, 0x79, 0x6d, 0x64, 0x65, + 0x66, 0x65, 0x61, 0x74, 0x73, 0x66, 0x61, 0x76, 0x6f, 0x72, 0x65, 0x64, 0x6f, + 0x70, 0x74, 0x69, 0x63, 0x61, 0x6c, 0x70, 0x61, 0x67, 0x65, 0x54, 0x72, 0x61, + 0x75, 0x6e, 0x6c, 0x65, 0x73, 0x73, 0x20, 0x73, 0x65, 0x6e, 0x64, 0x69, 0x6e, + 0x67, 0x6c, 0x65, 0x66, 0x74, 0x22, 0x3e, 0x3c, 0x63, 0x6f, 0x6d, 0x53, 0x63, + 0x6f, 0x72, 0x41, 0x6c, 0x6c, 0x20, 0x74, 0x68, 0x65, 0x6a, 0x51, 0x75, 0x65, + 0x72, 0x79, 0x2e, 0x74, 0x6f, 0x75, 0x72, 0x69, 0x73, 0x74, 0x43, 0x6c, 0x61, + 0x73, 0x73, 0x69, 0x63, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x22, 0x20, 0x57, 0x69, + 0x6c, 0x68, 0x65, 0x6c, 0x6d, 0x73, 0x75, 0x62, 0x75, 0x72, 0x62, 0x73, 0x67, + 0x65, 0x6e, 0x75, 0x69, 0x6e, 0x65, 0x62, 0x69, 0x73, 0x68, 0x6f, 0x70, 0x73, + 0x2e, 0x73, 0x70, 0x6c, 0x69, 0x74, 0x28, 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, + 0x20, 0x66, 0x6f, 0x6c, 0x6c, 0x6f, 0x77, 0x73, 0x62, 0x6f, 0x64, 0x79, 0x20, + 0x6f, 0x66, 0x6e, 0x6f, 0x6d, 0x69, 0x6e, 0x61, 0x6c, 0x43, 0x6f, 0x6e, 0x74, + 0x61, 0x63, 0x74, 0x73, 0x65, 0x63, 0x75, 0x6c, 0x61, 0x72, 0x6c, 0x65, 0x66, + 0x74, 0x20, 0x74, 0x6f, 0x63, 0x68, 0x69, 0x65, 0x66, 0x6c, 0x79, 0x2d, 0x68, + 0x69, 0x64, 0x64, 0x65, 0x6e, 0x2d, 0x62, 0x61, 0x6e, 0x6e, 0x65, 0x72, 0x3c, + 0x2f, 0x6c, 0x69, 0x3e, 0x0a, 0x0a, 0x2e, 0x20, 0x57, 0x68, 0x65, 0x6e, 0x20, + 0x69, 0x6e, 0x20, 0x62, 0x6f, 0x74, 0x68, 0x64, 0x69, 0x73, 0x6d, 0x69, 0x73, + 0x73, 0x45, 0x78, 0x70, 0x6c, 0x6f, 0x72, 0x65, 0x61, 0x6c, 0x77, 0x61, 0x79, + 0x73, 0x20, 0x76, 0x69, 0x61, 0x20, 0x74, 0x68, 0x65, 0x73, 0x70, 0x61, 0xc3, + 0xb1, 0x6f, 0x6c, 0x77, 0x65, 0x6c, 0x66, 0x61, 0x72, 0x65, 0x72, 0x75, 0x6c, + 0x69, 0x6e, 0x67, 0x20, 0x61, 0x72, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x63, 0x61, + 0x70, 0x74, 0x61, 0x69, 0x6e, 0x68, 0x69, 0x73, 0x20, 0x73, 0x6f, 0x6e, 0x72, + 0x75, 0x6c, 0x65, 0x20, 0x6f, 0x66, 0x68, 0x65, 0x20, 0x74, 0x6f, 0x6f, 0x6b, + 0x69, 0x74, 0x73, 0x65, 0x6c, 0x66, 0x2c, 0x3d, 0x30, 0x26, 0x61, 0x6d, 0x70, + 0x3b, 0x28, 0x63, 0x61, 0x6c, 0x6c, 0x65, 0x64, 0x73, 0x61, 0x6d, 0x70, 0x6c, + 0x65, 0x73, 0x74, 0x6f, 0x20, 0x6d, 0x61, 0x6b, 0x65, 0x63, 0x6f, 0x6d, 0x2f, + 0x70, 0x61, 0x67, 0x4d, 0x61, 0x72, 0x74, 0x69, 0x6e, 0x20, 0x4b, 0x65, 0x6e, + 0x6e, 0x65, 0x64, 0x79, 0x61, 0x63, 0x63, 0x65, 0x70, 0x74, 0x73, 0x66, 0x75, + 0x6c, 0x6c, 0x20, 0x6f, 0x66, 0x68, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x64, 0x42, + 0x65, 0x73, 0x69, 0x64, 0x65, 0x73, 0x2f, 0x2f, 0x2d, 0x2d, 0x3e, 0x3c, 0x2f, + 0x61, 0x62, 0x6c, 0x65, 0x20, 0x74, 0x6f, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, + 0x73, 0x65, 0x73, 0x73, 0x65, 0x6e, 0x63, 0x65, 0x68, 0x69, 0x6d, 0x20, 0x74, + 0x6f, 0x20, 0x69, 0x74, 0x73, 0x20, 0x62, 0x79, 0x20, 0x63, 0x6f, 0x6d, 0x6d, + 0x6f, 0x6e, 0x2e, 0x6d, 0x69, 0x6e, 0x65, 0x72, 0x61, 0x6c, 0x74, 0x6f, 0x20, + 0x74, 0x61, 0x6b, 0x65, 0x77, 0x61, 0x79, 0x73, 0x20, 0x74, 0x6f, 0x73, 0x2e, + 0x6f, 0x72, 0x67, 0x2f, 0x6c, 0x61, 0x64, 0x76, 0x69, 0x73, 0x65, 0x64, 0x70, + 0x65, 0x6e, 0x61, 0x6c, 0x74, 0x79, 0x73, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x3a, + 0x69, 0x66, 0x20, 0x74, 0x68, 0x65, 0x79, 0x4c, 0x65, 0x74, 0x74, 0x65, 0x72, + 0x73, 0x61, 0x20, 0x73, 0x68, 0x6f, 0x72, 0x74, 0x48, 0x65, 0x72, 0x62, 0x65, + 0x72, 0x74, 0x73, 0x74, 0x72, 0x69, 0x6b, 0x65, 0x73, 0x20, 0x67, 0x72, 0x6f, + 0x75, 0x70, 0x73, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x66, 0x6c, 0x69, + 0x67, 0x68, 0x74, 0x73, 0x6f, 0x76, 0x65, 0x72, 0x6c, 0x61, 0x70, 0x73, 0x6c, + 0x6f, 0x77, 0x6c, 0x79, 0x20, 0x6c, 0x65, 0x73, 0x73, 0x65, 0x72, 0x20, 0x73, + 0x6f, 0x63, 0x69, 0x61, 0x6c, 0x20, 0x3c, 0x2f, 0x70, 0x3e, 0x0a, 0x09, 0x09, + 0x69, 0x74, 0x20, 0x69, 0x6e, 0x74, 0x6f, 0x72, 0x61, 0x6e, 0x6b, 0x65, 0x64, + 0x20, 0x72, 0x61, 0x74, 0x65, 0x20, 0x6f, 0x66, 0x75, 0x6c, 0x3e, 0x0d, 0x0a, + 0x20, 0x20, 0x61, 0x74, 0x74, 0x65, 0x6d, 0x70, 0x74, 0x70, 0x61, 0x69, 0x72, + 0x20, 0x6f, 0x66, 0x6d, 0x61, 0x6b, 0x65, 0x20, 0x69, 0x74, 0x4b, 0x6f, 0x6e, + 0x74, 0x61, 0x6b, 0x74, 0x41, 0x6e, 0x74, 0x6f, 0x6e, 0x69, 0x6f, 0x68, 0x61, + 0x76, 0x69, 0x6e, 0x67, 0x20, 0x72, 0x61, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x20, + 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x73, + 0x74, 0x72, 0x61, 0x70, 0x70, 0x65, 0x64, 0x22, 0x29, 0x2e, 0x63, 0x73, 0x73, + 0x28, 0x68, 0x6f, 0x73, 0x74, 0x69, 0x6c, 0x65, 0x6c, 0x65, 0x61, 0x64, 0x20, + 0x74, 0x6f, 0x6c, 0x69, 0x74, 0x74, 0x6c, 0x65, 0x20, 0x67, 0x72, 0x6f, 0x75, + 0x70, 0x73, 0x2c, 0x50, 0x69, 0x63, 0x74, 0x75, 0x72, 0x65, 0x2d, 0x2d, 0x3e, + 0x0d, 0x0a, 0x0d, 0x0a, 0x20, 0x72, 0x6f, 0x77, 0x73, 0x3d, 0x22, 0x20, 0x6f, + 0x62, 0x6a, 0x65, 0x63, 0x74, 0x69, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x65, 0x3c, + 0x66, 0x6f, 0x6f, 0x74, 0x65, 0x72, 0x43, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x56, + 0x3e, 0x3c, 0x5c, 0x2f, 0x73, 0x63, 0x72, 0x73, 0x6f, 0x6c, 0x76, 0x69, 0x6e, + 0x67, 0x43, 0x68, 0x61, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x6c, 0x61, 0x76, 0x65, + 0x72, 0x79, 0x77, 0x6f, 0x75, 0x6e, 0x64, 0x65, 0x64, 0x77, 0x68, 0x65, 0x72, + 0x65, 0x61, 0x73, 0x21, 0x3d, 0x20, 0x27, 0x75, 0x6e, 0x64, 0x66, 0x6f, 0x72, + 0x20, 0x61, 0x6c, 0x6c, 0x70, 0x61, 0x72, 0x74, 0x6c, 0x79, 0x20, 0x2d, 0x72, + 0x69, 0x67, 0x68, 0x74, 0x3a, 0x41, 0x72, 0x61, 0x62, 0x69, 0x61, 0x6e, 0x62, + 0x61, 0x63, 0x6b, 0x65, 0x64, 0x20, 0x63, 0x65, 0x6e, 0x74, 0x75, 0x72, 0x79, + 0x75, 0x6e, 0x69, 0x74, 0x20, 0x6f, 0x66, 0x6d, 0x6f, 0x62, 0x69, 0x6c, 0x65, + 0x2d, 0x45, 0x75, 0x72, 0x6f, 0x70, 0x65, 0x2c, 0x69, 0x73, 0x20, 0x68, 0x6f, + 0x6d, 0x65, 0x72, 0x69, 0x73, 0x6b, 0x20, 0x6f, 0x66, 0x64, 0x65, 0x73, 0x69, + 0x72, 0x65, 0x64, 0x43, 0x6c, 0x69, 0x6e, 0x74, 0x6f, 0x6e, 0x63, 0x6f, 0x73, + 0x74, 0x20, 0x6f, 0x66, 0x61, 0x67, 0x65, 0x20, 0x6f, 0x66, 0x20, 0x62, 0x65, + 0x63, 0x6f, 0x6d, 0x65, 0x20, 0x6e, 0x6f, 0x6e, 0x65, 0x20, 0x6f, 0x66, 0x70, + 0x26, 0x71, 0x75, 0x6f, 0x74, 0x3b, 0x4d, 0x69, 0x64, 0x64, 0x6c, 0x65, 0x20, + 0x65, 0x61, 0x64, 0x27, 0x29, 0x5b, 0x30, 0x43, 0x72, 0x69, 0x74, 0x69, 0x63, + 0x73, 0x73, 0x74, 0x75, 0x64, 0x69, 0x6f, 0x73, 0x3e, 0x26, 0x63, 0x6f, 0x70, + 0x79, 0x3b, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x22, 0x3e, 0x61, 0x73, 0x73, 0x65, + 0x6d, 0x62, 0x6c, 0x6d, 0x61, 0x6b, 0x69, 0x6e, 0x67, 0x20, 0x70, 0x72, 0x65, + 0x73, 0x73, 0x65, 0x64, 0x77, 0x69, 0x64, 0x67, 0x65, 0x74, 0x2e, 0x70, 0x73, + 0x3a, 0x22, 0x20, 0x3f, 0x20, 0x72, 0x65, 0x62, 0x75, 0x69, 0x6c, 0x74, 0x62, + 0x79, 0x20, 0x73, 0x6f, 0x6d, 0x65, 0x46, 0x6f, 0x72, 0x6d, 0x65, 0x72, 0x20, + 0x65, 0x64, 0x69, 0x74, 0x6f, 0x72, 0x73, 0x64, 0x65, 0x6c, 0x61, 0x79, 0x65, + 0x64, 0x43, 0x61, 0x6e, 0x6f, 0x6e, 0x69, 0x63, 0x68, 0x61, 0x64, 0x20, 0x74, + 0x68, 0x65, 0x70, 0x75, 0x73, 0x68, 0x69, 0x6e, 0x67, 0x63, 0x6c, 0x61, 0x73, + 0x73, 0x3d, 0x22, 0x62, 0x75, 0x74, 0x20, 0x61, 0x72, 0x65, 0x70, 0x61, 0x72, + 0x74, 0x69, 0x61, 0x6c, 0x42, 0x61, 0x62, 0x79, 0x6c, 0x6f, 0x6e, 0x62, 0x6f, + 0x74, 0x74, 0x6f, 0x6d, 0x20, 0x63, 0x61, 0x72, 0x72, 0x69, 0x65, 0x72, 0x43, + 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x69, 0x74, 0x73, 0x20, 0x75, 0x73, 0x65, + 0x41, 0x73, 0x20, 0x77, 0x69, 0x74, 0x68, 0x63, 0x6f, 0x75, 0x72, 0x73, 0x65, + 0x73, 0x61, 0x20, 0x74, 0x68, 0x69, 0x72, 0x64, 0x64, 0x65, 0x6e, 0x6f, 0x74, + 0x65, 0x73, 0x61, 0x6c, 0x73, 0x6f, 0x20, 0x69, 0x6e, 0x48, 0x6f, 0x75, 0x73, + 0x74, 0x6f, 0x6e, 0x32, 0x30, 0x70, 0x78, 0x3b, 0x22, 0x3e, 0x61, 0x63, 0x63, + 0x75, 0x73, 0x65, 0x64, 0x64, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x20, 0x67, 0x6f, + 0x61, 0x6c, 0x20, 0x6f, 0x66, 0x46, 0x61, 0x6d, 0x6f, 0x75, 0x73, 0x20, 0x29, + 0x2e, 0x62, 0x69, 0x6e, 0x64, 0x28, 0x70, 0x72, 0x69, 0x65, 0x73, 0x74, 0x73, + 0x20, 0x4f, 0x6e, 0x6c, 0x69, 0x6e, 0x65, 0x69, 0x6e, 0x20, 0x4a, 0x75, 0x6c, + 0x79, 0x73, 0x74, 0x20, 0x2b, 0x20, 0x22, 0x67, 0x63, 0x6f, 0x6e, 0x73, 0x75, + 0x6c, 0x74, 0x64, 0x65, 0x63, 0x69, 0x6d, 0x61, 0x6c, 0x68, 0x65, 0x6c, 0x70, + 0x66, 0x75, 0x6c, 0x72, 0x65, 0x76, 0x69, 0x76, 0x65, 0x64, 0x69, 0x73, 0x20, + 0x76, 0x65, 0x72, 0x79, 0x72, 0x27, 0x2b, 0x27, 0x69, 0x70, 0x74, 0x6c, 0x6f, + 0x73, 0x69, 0x6e, 0x67, 0x20, 0x66, 0x65, 0x6d, 0x61, 0x6c, 0x65, 0x73, 0x69, + 0x73, 0x20, 0x61, 0x6c, 0x73, 0x6f, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x73, + 0x64, 0x61, 0x79, 0x73, 0x20, 0x6f, 0x66, 0x61, 0x72, 0x72, 0x69, 0x76, 0x61, + 0x6c, 0x66, 0x75, 0x74, 0x75, 0x72, 0x65, 0x20, 0x3c, 0x6f, 0x62, 0x6a, 0x65, + 0x63, 0x74, 0x66, 0x6f, 0x72, 0x63, 0x69, 0x6e, 0x67, 0x53, 0x74, 0x72, 0x69, + 0x6e, 0x67, 0x28, 0x22, 0x20, 0x2f, 0x3e, 0x0a, 0x09, 0x09, 0x68, 0x65, 0x72, + 0x65, 0x20, 0x69, 0x73, 0x65, 0x6e, 0x63, 0x6f, 0x64, 0x65, 0x64, 0x2e, 0x20, + 0x20, 0x54, 0x68, 0x65, 0x20, 0x62, 0x61, 0x6c, 0x6c, 0x6f, 0x6f, 0x6e, 0x64, + 0x6f, 0x6e, 0x65, 0x20, 0x62, 0x79, 0x2f, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, + 0x62, 0x67, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x6c, 0x61, 0x77, 0x20, 0x6f, 0x66, + 0x20, 0x49, 0x6e, 0x64, 0x69, 0x61, 0x6e, 0x61, 0x61, 0x76, 0x6f, 0x69, 0x64, + 0x65, 0x64, 0x62, 0x75, 0x74, 0x20, 0x74, 0x68, 0x65, 0x32, 0x70, 0x78, 0x20, + 0x33, 0x70, 0x78, 0x6a, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x61, 0x66, 0x74, + 0x65, 0x72, 0x20, 0x61, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x6d, 0x65, + 0x6e, 0x20, 0x61, 0x6e, 0x64, 0x66, 0x6f, 0x6f, 0x74, 0x65, 0x72, 0x2d, 0x3d, + 0x20, 0x74, 0x72, 0x75, 0x65, 0x3b, 0x66, 0x6f, 0x72, 0x20, 0x75, 0x73, 0x65, + 0x73, 0x63, 0x72, 0x65, 0x65, 0x6e, 0x2e, 0x49, 0x6e, 0x64, 0x69, 0x61, 0x6e, + 0x20, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x20, 0x3d, 0x66, 0x61, 0x6d, 0x69, 0x6c, + 0x79, 0x2c, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x20, 0x26, 0x6e, 0x62, + 0x73, 0x70, 0x3b, 0x64, 0x72, 0x69, 0x76, 0x65, 0x72, 0x73, 0x65, 0x74, 0x65, + 0x72, 0x6e, 0x61, 0x6c, 0x73, 0x61, 0x6d, 0x65, 0x20, 0x61, 0x73, 0x6e, 0x6f, + 0x74, 0x69, 0x63, 0x65, 0x64, 0x76, 0x69, 0x65, 0x77, 0x65, 0x72, 0x73, 0x7d, + 0x29, 0x28, 0x29, 0x3b, 0x0a, 0x20, 0x69, 0x73, 0x20, 0x6d, 0x6f, 0x72, 0x65, + 0x73, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x73, 0x66, 0x6f, 0x72, 0x6d, 0x65, 0x72, + 0x20, 0x74, 0x68, 0x65, 0x20, 0x6e, 0x65, 0x77, 0x69, 0x73, 0x20, 0x6a, 0x75, + 0x73, 0x74, 0x63, 0x6f, 0x6e, 0x73, 0x65, 0x6e, 0x74, 0x20, 0x53, 0x65, 0x61, + 0x72, 0x63, 0x68, 0x77, 0x61, 0x73, 0x20, 0x74, 0x68, 0x65, 0x77, 0x68, 0x79, + 0x20, 0x74, 0x68, 0x65, 0x73, 0x68, 0x69, 0x70, 0x70, 0x65, 0x64, 0x62, 0x72, + 0x3e, 0x3c, 0x62, 0x72, 0x3e, 0x77, 0x69, 0x64, 0x74, 0x68, 0x3a, 0x20, 0x68, + 0x65, 0x69, 0x67, 0x68, 0x74, 0x3d, 0x6d, 0x61, 0x64, 0x65, 0x20, 0x6f, 0x66, + 0x63, 0x75, 0x69, 0x73, 0x69, 0x6e, 0x65, 0x69, 0x73, 0x20, 0x74, 0x68, 0x61, + 0x74, 0x61, 0x20, 0x76, 0x65, 0x72, 0x79, 0x20, 0x41, 0x64, 0x6d, 0x69, 0x72, + 0x61, 0x6c, 0x20, 0x66, 0x69, 0x78, 0x65, 0x64, 0x3b, 0x6e, 0x6f, 0x72, 0x6d, + 0x61, 0x6c, 0x20, 0x4d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x50, 0x72, 0x65, + 0x73, 0x73, 0x2c, 0x20, 0x6f, 0x6e, 0x74, 0x61, 0x72, 0x69, 0x6f, 0x63, 0x68, + 0x61, 0x72, 0x73, 0x65, 0x74, 0x74, 0x72, 0x79, 0x20, 0x74, 0x6f, 0x20, 0x69, + 0x6e, 0x76, 0x61, 0x64, 0x65, 0x64, 0x3d, 0x22, 0x74, 0x72, 0x75, 0x65, 0x22, + 0x73, 0x70, 0x61, 0x63, 0x69, 0x6e, 0x67, 0x69, 0x73, 0x20, 0x6d, 0x6f, 0x73, + 0x74, 0x61, 0x20, 0x6d, 0x6f, 0x72, 0x65, 0x20, 0x74, 0x6f, 0x74, 0x61, 0x6c, + 0x6c, 0x79, 0x66, 0x61, 0x6c, 0x6c, 0x20, 0x6f, 0x66, 0x7d, 0x29, 0x3b, 0x0d, + 0x0a, 0x20, 0x20, 0x69, 0x6d, 0x6d, 0x65, 0x6e, 0x73, 0x65, 0x74, 0x69, 0x6d, + 0x65, 0x20, 0x69, 0x6e, 0x73, 0x65, 0x74, 0x20, 0x6f, 0x75, 0x74, 0x73, 0x61, + 0x74, 0x69, 0x73, 0x66, 0x79, 0x74, 0x6f, 0x20, 0x66, 0x69, 0x6e, 0x64, 0x64, + 0x6f, 0x77, 0x6e, 0x20, 0x74, 0x6f, 0x6c, 0x6f, 0x74, 0x20, 0x6f, 0x66, 0x20, + 0x50, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x73, 0x69, 0x6e, 0x20, 0x4a, 0x75, 0x6e, + 0x65, 0x71, 0x75, 0x61, 0x6e, 0x74, 0x75, 0x6d, 0x6e, 0x6f, 0x74, 0x20, 0x74, + 0x68, 0x65, 0x74, 0x69, 0x6d, 0x65, 0x20, 0x74, 0x6f, 0x64, 0x69, 0x73, 0x74, + 0x61, 0x6e, 0x74, 0x46, 0x69, 0x6e, 0x6e, 0x69, 0x73, 0x68, 0x73, 0x72, 0x63, + 0x20, 0x3d, 0x20, 0x28, 0x73, 0x69, 0x6e, 0x67, 0x6c, 0x65, 0x20, 0x68, 0x65, + 0x6c, 0x70, 0x20, 0x6f, 0x66, 0x47, 0x65, 0x72, 0x6d, 0x61, 0x6e, 0x20, 0x6c, + 0x61, 0x77, 0x20, 0x61, 0x6e, 0x64, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x65, 0x64, + 0x66, 0x6f, 0x72, 0x65, 0x73, 0x74, 0x73, 0x63, 0x6f, 0x6f, 0x6b, 0x69, 0x6e, + 0x67, 0x73, 0x70, 0x61, 0x63, 0x65, 0x22, 0x3e, 0x68, 0x65, 0x61, 0x64, 0x65, + 0x72, 0x2d, 0x77, 0x65, 0x6c, 0x6c, 0x20, 0x61, 0x73, 0x53, 0x74, 0x61, 0x6e, + 0x6c, 0x65, 0x79, 0x62, 0x72, 0x69, 0x64, 0x67, 0x65, 0x73, 0x2f, 0x67, 0x6c, + 0x6f, 0x62, 0x61, 0x6c, 0x43, 0x72, 0x6f, 0x61, 0x74, 0x69, 0x61, 0x20, 0x41, + 0x62, 0x6f, 0x75, 0x74, 0x20, 0x5b, 0x30, 0x5d, 0x3b, 0x0a, 0x20, 0x20, 0x69, + 0x74, 0x2c, 0x20, 0x61, 0x6e, 0x64, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x65, 0x64, + 0x62, 0x65, 0x69, 0x6e, 0x67, 0x20, 0x61, 0x29, 0x7b, 0x74, 0x68, 0x72, 0x6f, + 0x77, 0x68, 0x65, 0x20, 0x6d, 0x61, 0x64, 0x65, 0x6c, 0x69, 0x67, 0x68, 0x74, + 0x65, 0x72, 0x65, 0x74, 0x68, 0x69, 0x63, 0x61, 0x6c, 0x46, 0x46, 0x46, 0x46, + 0x46, 0x46, 0x22, 0x62, 0x6f, 0x74, 0x74, 0x6f, 0x6d, 0x22, 0x6c, 0x69, 0x6b, + 0x65, 0x20, 0x61, 0x20, 0x65, 0x6d, 0x70, 0x6c, 0x6f, 0x79, 0x73, 0x6c, 0x69, + 0x76, 0x65, 0x20, 0x69, 0x6e, 0x61, 0x73, 0x20, 0x73, 0x65, 0x65, 0x6e, 0x70, + 0x72, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6d, 0x6f, 0x73, 0x74, 0x20, 0x6f, 0x66, + 0x75, 0x62, 0x2d, 0x6c, 0x69, 0x6e, 0x6b, 0x72, 0x65, 0x6a, 0x65, 0x63, 0x74, + 0x73, 0x61, 0x6e, 0x64, 0x20, 0x75, 0x73, 0x65, 0x69, 0x6d, 0x61, 0x67, 0x65, + 0x22, 0x3e, 0x73, 0x75, 0x63, 0x63, 0x65, 0x65, 0x64, 0x66, 0x65, 0x65, 0x64, + 0x69, 0x6e, 0x67, 0x4e, 0x75, 0x63, 0x6c, 0x65, 0x61, 0x72, 0x69, 0x6e, 0x66, + 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x6f, 0x20, 0x68, 0x65, 0x6c, 0x70, 0x57, 0x6f, + 0x6d, 0x65, 0x6e, 0x27, 0x73, 0x4e, 0x65, 0x69, 0x74, 0x68, 0x65, 0x72, 0x4d, + 0x65, 0x78, 0x69, 0x63, 0x61, 0x6e, 0x70, 0x72, 0x6f, 0x74, 0x65, 0x69, 0x6e, + 0x3c, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x20, 0x62, 0x79, 0x20, 0x6d, 0x61, 0x6e, + 0x79, 0x68, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x79, 0x6c, 0x61, 0x77, 0x73, 0x75, + 0x69, 0x74, 0x64, 0x65, 0x76, 0x69, 0x73, 0x65, 0x64, 0x2e, 0x70, 0x75, 0x73, + 0x68, 0x28, 0x7b, 0x73, 0x65, 0x6c, 0x6c, 0x65, 0x72, 0x73, 0x73, 0x69, 0x6d, + 0x70, 0x6c, 0x79, 0x20, 0x54, 0x68, 0x72, 0x6f, 0x75, 0x67, 0x68, 0x2e, 0x63, + 0x6f, 0x6f, 0x6b, 0x69, 0x65, 0x20, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x28, 0x6f, + 0x6c, 0x64, 0x65, 0x72, 0x22, 0x3e, 0x75, 0x73, 0x2e, 0x6a, 0x73, 0x22, 0x3e, + 0x20, 0x53, 0x69, 0x6e, 0x63, 0x65, 0x20, 0x75, 0x6e, 0x69, 0x76, 0x65, 0x72, + 0x73, 0x6c, 0x61, 0x72, 0x67, 0x65, 0x72, 0x20, 0x6f, 0x70, 0x65, 0x6e, 0x20, + 0x74, 0x6f, 0x21, 0x2d, 0x2d, 0x20, 0x65, 0x6e, 0x64, 0x6c, 0x69, 0x65, 0x73, + 0x20, 0x69, 0x6e, 0x27, 0x5d, 0x29, 0x3b, 0x0d, 0x0a, 0x20, 0x20, 0x6d, 0x61, + 0x72, 0x6b, 0x65, 0x74, 0x77, 0x68, 0x6f, 0x20, 0x69, 0x73, 0x20, 0x28, 0x22, + 0x44, 0x4f, 0x4d, 0x43, 0x6f, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x64, 0x6f, + 0x6e, 0x65, 0x20, 0x66, 0x6f, 0x72, 0x74, 0x79, 0x70, 0x65, 0x6f, 0x66, 0x20, + 0x4b, 0x69, 0x6e, 0x67, 0x64, 0x6f, 0x6d, 0x70, 0x72, 0x6f, 0x66, 0x69, 0x74, + 0x73, 0x70, 0x72, 0x6f, 0x70, 0x6f, 0x73, 0x65, 0x74, 0x6f, 0x20, 0x73, 0x68, + 0x6f, 0x77, 0x63, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x3b, 0x6d, 0x61, 0x64, 0x65, + 0x20, 0x69, 0x74, 0x64, 0x72, 0x65, 0x73, 0x73, 0x65, 0x64, 0x77, 0x65, 0x72, + 0x65, 0x20, 0x69, 0x6e, 0x6d, 0x69, 0x78, 0x74, 0x75, 0x72, 0x65, 0x70, 0x72, + 0x65, 0x63, 0x69, 0x73, 0x65, 0x61, 0x72, 0x69, 0x73, 0x69, 0x6e, 0x67, 0x73, + 0x72, 0x63, 0x20, 0x3d, 0x20, 0x27, 0x6d, 0x61, 0x6b, 0x65, 0x20, 0x61, 0x20, + 0x73, 0x65, 0x63, 0x75, 0x72, 0x65, 0x64, 0x42, 0x61, 0x70, 0x74, 0x69, 0x73, + 0x74, 0x76, 0x6f, 0x74, 0x69, 0x6e, 0x67, 0x20, 0x0a, 0x09, 0x09, 0x76, 0x61, + 0x72, 0x20, 0x4d, 0x61, 0x72, 0x63, 0x68, 0x20, 0x32, 0x67, 0x72, 0x65, 0x77, + 0x20, 0x75, 0x70, 0x43, 0x6c, 0x69, 0x6d, 0x61, 0x74, 0x65, 0x2e, 0x72, 0x65, + 0x6d, 0x6f, 0x76, 0x65, 0x73, 0x6b, 0x69, 0x6c, 0x6c, 0x65, 0x64, 0x77, 0x61, + 0x79, 0x20, 0x74, 0x68, 0x65, 0x3c, 0x2f, 0x68, 0x65, 0x61, 0x64, 0x3e, 0x66, + 0x61, 0x63, 0x65, 0x20, 0x6f, 0x66, 0x61, 0x63, 0x74, 0x69, 0x6e, 0x67, 0x20, + 0x72, 0x69, 0x67, 0x68, 0x74, 0x22, 0x3e, 0x74, 0x6f, 0x20, 0x77, 0x6f, 0x72, + 0x6b, 0x72, 0x65, 0x64, 0x75, 0x63, 0x65, 0x73, 0x68, 0x61, 0x73, 0x20, 0x68, + 0x61, 0x64, 0x65, 0x72, 0x65, 0x63, 0x74, 0x65, 0x64, 0x73, 0x68, 0x6f, 0x77, + 0x28, 0x29, 0x3b, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x3d, 0x62, 0x6f, 0x6f, + 0x6b, 0x20, 0x6f, 0x66, 0x61, 0x6e, 0x20, 0x61, 0x72, 0x65, 0x61, 0x3d, 0x3d, + 0x20, 0x22, 0x68, 0x74, 0x74, 0x3c, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x0a, + 0x3c, 0x68, 0x74, 0x6d, 0x6c, 0x3e, 0x63, 0x6f, 0x6e, 0x66, 0x6f, 0x72, 0x6d, + 0x66, 0x61, 0x63, 0x69, 0x6e, 0x67, 0x20, 0x63, 0x6f, 0x6f, 0x6b, 0x69, 0x65, + 0x2e, 0x72, 0x65, 0x6c, 0x79, 0x20, 0x6f, 0x6e, 0x68, 0x6f, 0x73, 0x74, 0x65, + 0x64, 0x20, 0x2e, 0x63, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x68, 0x65, 0x20, 0x77, + 0x65, 0x6e, 0x74, 0x62, 0x75, 0x74, 0x20, 0x66, 0x6f, 0x72, 0x73, 0x70, 0x72, + 0x65, 0x61, 0x64, 0x20, 0x46, 0x61, 0x6d, 0x69, 0x6c, 0x79, 0x20, 0x61, 0x20, + 0x6d, 0x65, 0x61, 0x6e, 0x73, 0x6f, 0x75, 0x74, 0x20, 0x74, 0x68, 0x65, 0x66, + 0x6f, 0x72, 0x75, 0x6d, 0x73, 0x2e, 0x66, 0x6f, 0x6f, 0x74, 0x61, 0x67, 0x65, + 0x22, 0x3e, 0x4d, 0x6f, 0x62, 0x69, 0x6c, 0x43, 0x6c, 0x65, 0x6d, 0x65, 0x6e, + 0x74, 0x73, 0x22, 0x20, 0x69, 0x64, 0x3d, 0x22, 0x61, 0x73, 0x20, 0x68, 0x69, + 0x67, 0x68, 0x69, 0x6e, 0x74, 0x65, 0x6e, 0x73, 0x65, 0x2d, 0x2d, 0x3e, 0x3c, + 0x21, 0x2d, 0x2d, 0x66, 0x65, 0x6d, 0x61, 0x6c, 0x65, 0x20, 0x69, 0x73, 0x20, + 0x73, 0x65, 0x65, 0x6e, 0x69, 0x6d, 0x70, 0x6c, 0x69, 0x65, 0x64, 0x73, 0x65, + 0x74, 0x20, 0x74, 0x68, 0x65, 0x61, 0x20, 0x73, 0x74, 0x61, 0x74, 0x65, 0x61, + 0x6e, 0x64, 0x20, 0x68, 0x69, 0x73, 0x66, 0x61, 0x73, 0x74, 0x65, 0x73, 0x74, + 0x62, 0x65, 0x73, 0x69, 0x64, 0x65, 0x73, 0x62, 0x75, 0x74, 0x74, 0x6f, 0x6e, + 0x5f, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x65, 0x64, 0x22, 0x3e, 0x3c, 0x69, 0x6d, + 0x67, 0x20, 0x49, 0x6e, 0x66, 0x6f, 0x62, 0x6f, 0x78, 0x65, 0x76, 0x65, 0x6e, + 0x74, 0x73, 0x2c, 0x61, 0x20, 0x79, 0x6f, 0x75, 0x6e, 0x67, 0x61, 0x6e, 0x64, + 0x20, 0x61, 0x72, 0x65, 0x4e, 0x61, 0x74, 0x69, 0x76, 0x65, 0x20, 0x63, 0x68, + 0x65, 0x61, 0x70, 0x65, 0x72, 0x54, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x61, + 0x6e, 0x64, 0x20, 0x68, 0x61, 0x73, 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x73, + 0x77, 0x6f, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x28, 0x6d, 0x6f, 0x73, 0x74, 0x6c, + 0x79, 0x72, 0x69, 0x67, 0x68, 0x74, 0x3a, 0x20, 0x66, 0x69, 0x6e, 0x64, 0x20, + 0x61, 0x20, 0x2d, 0x62, 0x6f, 0x74, 0x74, 0x6f, 0x6d, 0x50, 0x72, 0x69, 0x6e, + 0x63, 0x65, 0x20, 0x61, 0x72, 0x65, 0x61, 0x20, 0x6f, 0x66, 0x6d, 0x6f, 0x72, + 0x65, 0x20, 0x6f, 0x66, 0x73, 0x65, 0x61, 0x72, 0x63, 0x68, 0x5f, 0x6e, 0x61, + 0x74, 0x75, 0x72, 0x65, 0x2c, 0x6c, 0x65, 0x67, 0x61, 0x6c, 0x6c, 0x79, 0x70, + 0x65, 0x72, 0x69, 0x6f, 0x64, 0x2c, 0x6c, 0x61, 0x6e, 0x64, 0x20, 0x6f, 0x66, + 0x6f, 0x72, 0x20, 0x77, 0x69, 0x74, 0x68, 0x69, 0x6e, 0x64, 0x75, 0x63, 0x65, + 0x64, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x6e, 0x67, 0x6d, 0x69, 0x73, 0x73, 0x69, + 0x6c, 0x65, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x6c, 0x79, 0x41, 0x67, 0x61, 0x69, + 0x6e, 0x73, 0x74, 0x74, 0x68, 0x65, 0x20, 0x77, 0x61, 0x79, 0x6b, 0x26, 0x71, + 0x75, 0x6f, 0x74, 0x3b, 0x70, 0x78, 0x3b, 0x22, 0x3e, 0x0d, 0x0a, 0x70, 0x75, + 0x73, 0x68, 0x65, 0x64, 0x20, 0x61, 0x62, 0x61, 0x6e, 0x64, 0x6f, 0x6e, 0x6e, + 0x75, 0x6d, 0x65, 0x72, 0x61, 0x6c, 0x43, 0x65, 0x72, 0x74, 0x61, 0x69, 0x6e, + 0x49, 0x6e, 0x20, 0x74, 0x68, 0x69, 0x73, 0x6d, 0x6f, 0x72, 0x65, 0x20, 0x69, + 0x6e, 0x6f, 0x72, 0x20, 0x73, 0x6f, 0x6d, 0x65, 0x6e, 0x61, 0x6d, 0x65, 0x20, + 0x69, 0x73, 0x61, 0x6e, 0x64, 0x2c, 0x20, 0x69, 0x6e, 0x63, 0x72, 0x6f, 0x77, + 0x6e, 0x65, 0x64, 0x49, 0x53, 0x42, 0x4e, 0x20, 0x30, 0x2d, 0x63, 0x72, 0x65, + 0x61, 0x74, 0x65, 0x73, 0x4f, 0x63, 0x74, 0x6f, 0x62, 0x65, 0x72, 0x6d, 0x61, + 0x79, 0x20, 0x6e, 0x6f, 0x74, 0x63, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x20, 0x6c, + 0x61, 0x74, 0x65, 0x20, 0x69, 0x6e, 0x44, 0x65, 0x66, 0x65, 0x6e, 0x63, 0x65, + 0x65, 0x6e, 0x61, 0x63, 0x74, 0x65, 0x64, 0x77, 0x69, 0x73, 0x68, 0x20, 0x74, + 0x6f, 0x62, 0x72, 0x6f, 0x61, 0x64, 0x6c, 0x79, 0x63, 0x6f, 0x6f, 0x6c, 0x69, + 0x6e, 0x67, 0x6f, 0x6e, 0x6c, 0x6f, 0x61, 0x64, 0x3d, 0x69, 0x74, 0x2e, 0x20, + 0x54, 0x68, 0x65, 0x72, 0x65, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x4d, 0x65, 0x6d, + 0x62, 0x65, 0x72, 0x73, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x20, 0x61, 0x73, + 0x73, 0x75, 0x6d, 0x65, 0x73, 0x3c, 0x68, 0x74, 0x6d, 0x6c, 0x3e, 0x0a, 0x70, + 0x65, 0x6f, 0x70, 0x6c, 0x65, 0x2e, 0x69, 0x6e, 0x20, 0x6f, 0x6e, 0x65, 0x20, + 0x3d, 0x77, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x66, 0x6f, 0x6f, 0x74, 0x65, 0x72, + 0x5f, 0x61, 0x20, 0x67, 0x6f, 0x6f, 0x64, 0x20, 0x72, 0x65, 0x6b, 0x6c, 0x61, + 0x6d, 0x61, 0x6f, 0x74, 0x68, 0x65, 0x72, 0x73, 0x2c, 0x74, 0x6f, 0x20, 0x74, + 0x68, 0x69, 0x73, 0x5f, 0x63, 0x6f, 0x6f, 0x6b, 0x69, 0x65, 0x70, 0x61, 0x6e, + 0x65, 0x6c, 0x22, 0x3e, 0x4c, 0x6f, 0x6e, 0x64, 0x6f, 0x6e, 0x2c, 0x64, 0x65, + 0x66, 0x69, 0x6e, 0x65, 0x73, 0x63, 0x72, 0x75, 0x73, 0x68, 0x65, 0x64, 0x62, + 0x61, 0x70, 0x74, 0x69, 0x73, 0x6d, 0x63, 0x6f, 0x61, 0x73, 0x74, 0x61, 0x6c, + 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x20, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x22, + 0x20, 0x6d, 0x6f, 0x76, 0x65, 0x20, 0x74, 0x6f, 0x6c, 0x6f, 0x73, 0x74, 0x20, + 0x69, 0x6e, 0x62, 0x65, 0x74, 0x74, 0x65, 0x72, 0x20, 0x69, 0x6d, 0x70, 0x6c, + 0x69, 0x65, 0x73, 0x72, 0x69, 0x76, 0x61, 0x6c, 0x72, 0x79, 0x73, 0x65, 0x72, + 0x76, 0x65, 0x72, 0x73, 0x20, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x50, 0x65, + 0x72, 0x68, 0x61, 0x70, 0x73, 0x65, 0x73, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x63, + 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x64, 0x66, 0x6c, 0x6f, 0x77, 0x69, 0x6e, 0x67, + 0x6c, 0x61, 0x73, 0x74, 0x65, 0x64, 0x20, 0x72, 0x69, 0x73, 0x65, 0x20, 0x69, + 0x6e, 0x47, 0x65, 0x6e, 0x65, 0x73, 0x69, 0x73, 0x76, 0x69, 0x65, 0x77, 0x20, + 0x6f, 0x66, 0x72, 0x69, 0x73, 0x69, 0x6e, 0x67, 0x20, 0x73, 0x65, 0x65, 0x6d, + 0x20, 0x74, 0x6f, 0x62, 0x75, 0x74, 0x20, 0x69, 0x6e, 0x20, 0x62, 0x61, 0x63, + 0x6b, 0x69, 0x6e, 0x67, 0x68, 0x65, 0x20, 0x77, 0x69, 0x6c, 0x6c, 0x67, 0x69, + 0x76, 0x65, 0x6e, 0x20, 0x61, 0x67, 0x69, 0x76, 0x69, 0x6e, 0x67, 0x20, 0x63, + 0x69, 0x74, 0x69, 0x65, 0x73, 0x2e, 0x66, 0x6c, 0x6f, 0x77, 0x20, 0x6f, 0x66, + 0x20, 0x4c, 0x61, 0x74, 0x65, 0x72, 0x20, 0x61, 0x6c, 0x6c, 0x20, 0x62, 0x75, + 0x74, 0x48, 0x69, 0x67, 0x68, 0x77, 0x61, 0x79, 0x6f, 0x6e, 0x6c, 0x79, 0x20, + 0x62, 0x79, 0x73, 0x69, 0x67, 0x6e, 0x20, 0x6f, 0x66, 0x68, 0x65, 0x20, 0x64, + 0x6f, 0x65, 0x73, 0x64, 0x69, 0x66, 0x66, 0x65, 0x72, 0x73, 0x62, 0x61, 0x74, + 0x74, 0x65, 0x72, 0x79, 0x26, 0x61, 0x6d, 0x70, 0x3b, 0x6c, 0x61, 0x73, 0x69, + 0x6e, 0x67, 0x6c, 0x65, 0x73, 0x74, 0x68, 0x72, 0x65, 0x61, 0x74, 0x73, 0x69, + 0x6e, 0x74, 0x65, 0x67, 0x65, 0x72, 0x74, 0x61, 0x6b, 0x65, 0x20, 0x6f, 0x6e, + 0x72, 0x65, 0x66, 0x75, 0x73, 0x65, 0x64, 0x63, 0x61, 0x6c, 0x6c, 0x65, 0x64, + 0x20, 0x3d, 0x55, 0x53, 0x26, 0x61, 0x6d, 0x70, 0x53, 0x65, 0x65, 0x20, 0x74, + 0x68, 0x65, 0x6e, 0x61, 0x74, 0x69, 0x76, 0x65, 0x73, 0x62, 0x79, 0x20, 0x74, + 0x68, 0x69, 0x73, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x2e, 0x68, 0x65, 0x61, + 0x64, 0x20, 0x6f, 0x66, 0x3a, 0x68, 0x6f, 0x76, 0x65, 0x72, 0x2c, 0x6c, 0x65, + 0x73, 0x62, 0x69, 0x61, 0x6e, 0x73, 0x75, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x61, + 0x6e, 0x64, 0x20, 0x61, 0x6c, 0x6c, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2f, + 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x5f, 0x5f, 0x70, 0x61, 0x72, 0x61, 0x6d, + 0x73, 0x48, 0x61, 0x72, 0x76, 0x61, 0x72, 0x64, 0x2f, 0x70, 0x69, 0x78, 0x65, + 0x6c, 0x2e, 0x72, 0x65, 0x6d, 0x6f, 0x76, 0x61, 0x6c, 0x73, 0x6f, 0x20, 0x6c, + 0x6f, 0x6e, 0x67, 0x72, 0x6f, 0x6c, 0x65, 0x20, 0x6f, 0x66, 0x6a, 0x6f, 0x69, + 0x6e, 0x74, 0x6c, 0x79, 0x73, 0x6b, 0x79, 0x73, 0x63, 0x72, 0x61, 0x55, 0x6e, + 0x69, 0x63, 0x6f, 0x64, 0x65, 0x62, 0x72, 0x20, 0x2f, 0x3e, 0x0d, 0x0a, 0x41, + 0x74, 0x6c, 0x61, 0x6e, 0x74, 0x61, 0x6e, 0x75, 0x63, 0x6c, 0x65, 0x75, 0x73, + 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x79, 0x2c, 0x70, 0x75, 0x72, 0x65, 0x6c, 0x79, + 0x20, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x22, 0x3e, 0x65, 0x61, 0x73, 0x69, 0x6c, + 0x79, 0x20, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x20, 0x61, 0x6f, 0x6e, 0x63, 0x6c, + 0x69, 0x63, 0x6b, 0x61, 0x20, 0x67, 0x69, 0x76, 0x65, 0x6e, 0x70, 0x6f, 0x69, + 0x6e, 0x74, 0x65, 0x72, 0x68, 0x26, 0x71, 0x75, 0x6f, 0x74, 0x3b, 0x65, 0x76, + 0x65, 0x6e, 0x74, 0x73, 0x20, 0x65, 0x6c, 0x73, 0x65, 0x20, 0x7b, 0x0a, 0x64, + 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x6e, 0x6f, 0x77, 0x20, 0x74, 0x68, 0x65, + 0x2c, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x6d, 0x61, 0x6e, 0x20, 0x77, 0x68, + 0x6f, 0x6f, 0x72, 0x67, 0x2f, 0x57, 0x65, 0x62, 0x6f, 0x6e, 0x65, 0x20, 0x61, + 0x6e, 0x64, 0x63, 0x61, 0x76, 0x61, 0x6c, 0x72, 0x79, 0x48, 0x65, 0x20, 0x64, + 0x69, 0x65, 0x64, 0x73, 0x65, 0x61, 0x74, 0x74, 0x6c, 0x65, 0x30, 0x30, 0x2c, + 0x30, 0x30, 0x30, 0x20, 0x7b, 0x77, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x68, 0x61, + 0x76, 0x65, 0x20, 0x74, 0x6f, 0x69, 0x66, 0x28, 0x77, 0x69, 0x6e, 0x64, 0x61, + 0x6e, 0x64, 0x20, 0x69, 0x74, 0x73, 0x73, 0x6f, 0x6c, 0x65, 0x6c, 0x79, 0x20, + 0x6d, 0x26, 0x71, 0x75, 0x6f, 0x74, 0x3b, 0x72, 0x65, 0x6e, 0x65, 0x77, 0x65, + 0x64, 0x44, 0x65, 0x74, 0x72, 0x6f, 0x69, 0x74, 0x61, 0x6d, 0x6f, 0x6e, 0x67, + 0x73, 0x74, 0x65, 0x69, 0x74, 0x68, 0x65, 0x72, 0x20, 0x74, 0x68, 0x65, 0x6d, + 0x20, 0x69, 0x6e, 0x53, 0x65, 0x6e, 0x61, 0x74, 0x6f, 0x72, 0x55, 0x73, 0x3c, + 0x2f, 0x61, 0x3e, 0x3c, 0x4b, 0x69, 0x6e, 0x67, 0x20, 0x6f, 0x66, 0x46, 0x72, + 0x61, 0x6e, 0x63, 0x69, 0x73, 0x2d, 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x68, + 0x65, 0x20, 0x75, 0x73, 0x65, 0x64, 0x61, 0x72, 0x74, 0x20, 0x61, 0x6e, 0x64, + 0x68, 0x69, 0x6d, 0x20, 0x61, 0x6e, 0x64, 0x75, 0x73, 0x65, 0x64, 0x20, 0x62, + 0x79, 0x73, 0x63, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x61, 0x74, 0x20, 0x68, 0x6f, + 0x6d, 0x65, 0x74, 0x6f, 0x20, 0x68, 0x61, 0x76, 0x65, 0x72, 0x65, 0x6c, 0x61, + 0x74, 0x65, 0x73, 0x69, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x66, 0x61, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x42, 0x75, 0x66, 0x66, 0x61, 0x6c, 0x6f, 0x6c, 0x69, + 0x6e, 0x6b, 0x22, 0x3e, 0x3c, 0x77, 0x68, 0x61, 0x74, 0x20, 0x68, 0x65, 0x66, + 0x72, 0x65, 0x65, 0x20, 0x74, 0x6f, 0x43, 0x69, 0x74, 0x79, 0x20, 0x6f, 0x66, + 0x63, 0x6f, 0x6d, 0x65, 0x20, 0x69, 0x6e, 0x73, 0x65, 0x63, 0x74, 0x6f, 0x72, + 0x73, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x64, 0x6f, 0x6e, 0x65, 0x20, 0x64, + 0x61, 0x79, 0x6e, 0x65, 0x72, 0x76, 0x6f, 0x75, 0x73, 0x73, 0x71, 0x75, 0x61, + 0x72, 0x65, 0x20, 0x7d, 0x3b, 0x69, 0x66, 0x28, 0x67, 0x6f, 0x69, 0x6e, 0x20, + 0x77, 0x68, 0x61, 0x74, 0x69, 0x6d, 0x67, 0x22, 0x20, 0x61, 0x6c, 0x69, 0x73, + 0x20, 0x6f, 0x6e, 0x6c, 0x79, 0x73, 0x65, 0x61, 0x72, 0x63, 0x68, 0x2f, 0x74, + 0x75, 0x65, 0x73, 0x64, 0x61, 0x79, 0x6c, 0x6f, 0x6f, 0x73, 0x65, 0x6c, 0x79, + 0x53, 0x6f, 0x6c, 0x6f, 0x6d, 0x6f, 0x6e, 0x73, 0x65, 0x78, 0x75, 0x61, 0x6c, + 0x20, 0x2d, 0x20, 0x3c, 0x61, 0x20, 0x68, 0x72, 0x6d, 0x65, 0x64, 0x69, 0x75, + 0x6d, 0x22, 0x44, 0x4f, 0x20, 0x4e, 0x4f, 0x54, 0x20, 0x46, 0x72, 0x61, 0x6e, + 0x63, 0x65, 0x2c, 0x77, 0x69, 0x74, 0x68, 0x20, 0x61, 0x20, 0x77, 0x61, 0x72, + 0x20, 0x61, 0x6e, 0x64, 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x20, 0x74, 0x61, + 0x6b, 0x65, 0x20, 0x61, 0x20, 0x3e, 0x0d, 0x0a, 0x0d, 0x0a, 0x0d, 0x0a, 0x6d, + 0x61, 0x72, 0x6b, 0x65, 0x74, 0x2e, 0x68, 0x69, 0x67, 0x68, 0x77, 0x61, 0x79, + 0x64, 0x6f, 0x6e, 0x65, 0x20, 0x69, 0x6e, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, + 0x79, 0x22, 0x6c, 0x61, 0x73, 0x74, 0x22, 0x3e, 0x6f, 0x62, 0x6c, 0x69, 0x67, + 0x65, 0x64, 0x72, 0x69, 0x73, 0x65, 0x20, 0x74, 0x6f, 0x22, 0x75, 0x6e, 0x64, + 0x65, 0x66, 0x69, 0x6d, 0x61, 0x64, 0x65, 0x20, 0x74, 0x6f, 0x20, 0x45, 0x61, + 0x72, 0x6c, 0x79, 0x20, 0x70, 0x72, 0x61, 0x69, 0x73, 0x65, 0x64, 0x69, 0x6e, + 0x20, 0x69, 0x74, 0x73, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x68, 0x69, 0x73, 0x61, + 0x74, 0x68, 0x6c, 0x65, 0x74, 0x65, 0x4a, 0x75, 0x70, 0x69, 0x74, 0x65, 0x72, + 0x59, 0x61, 0x68, 0x6f, 0x6f, 0x21, 0x20, 0x74, 0x65, 0x72, 0x6d, 0x65, 0x64, + 0x20, 0x73, 0x6f, 0x20, 0x6d, 0x61, 0x6e, 0x79, 0x72, 0x65, 0x61, 0x6c, 0x6c, + 0x79, 0x20, 0x73, 0x2e, 0x20, 0x54, 0x68, 0x65, 0x20, 0x61, 0x20, 0x77, 0x6f, + 0x6d, 0x61, 0x6e, 0x3f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3d, 0x64, 0x69, 0x72, + 0x65, 0x63, 0x74, 0x20, 0x72, 0x69, 0x67, 0x68, 0x74, 0x22, 0x20, 0x62, 0x69, + 0x63, 0x79, 0x63, 0x6c, 0x65, 0x61, 0x63, 0x69, 0x6e, 0x67, 0x3d, 0x22, 0x64, + 0x61, 0x79, 0x20, 0x61, 0x6e, 0x64, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6e, 0x67, + 0x52, 0x61, 0x74, 0x68, 0x65, 0x72, 0x2c, 0x68, 0x69, 0x67, 0x68, 0x65, 0x72, + 0x20, 0x4f, 0x66, 0x66, 0x69, 0x63, 0x65, 0x20, 0x61, 0x72, 0x65, 0x20, 0x6e, + 0x6f, 0x77, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x2c, 0x20, 0x77, 0x68, 0x65, 0x6e, + 0x20, 0x61, 0x20, 0x70, 0x61, 0x79, 0x20, 0x66, 0x6f, 0x72, 0x6f, 0x6e, 0x20, + 0x74, 0x68, 0x69, 0x73, 0x2d, 0x6c, 0x69, 0x6e, 0x6b, 0x22, 0x3e, 0x3b, 0x62, + 0x6f, 0x72, 0x64, 0x65, 0x72, 0x61, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x20, 0x61, + 0x6e, 0x6e, 0x75, 0x61, 0x6c, 0x20, 0x74, 0x68, 0x65, 0x20, 0x4e, 0x65, 0x77, + 0x70, 0x75, 0x74, 0x20, 0x74, 0x68, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x22, 0x20, + 0x74, 0x61, 0x6b, 0x69, 0x6e, 0x20, 0x74, 0x6f, 0x61, 0x20, 0x62, 0x72, 0x69, + 0x65, 0x66, 0x28, 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x67, 0x72, 0x6f, 0x75, + 0x70, 0x73, 0x2e, 0x3b, 0x20, 0x77, 0x69, 0x64, 0x74, 0x68, 0x65, 0x6e, 0x7a, + 0x79, 0x6d, 0x65, 0x73, 0x73, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x20, 0x69, 0x6e, + 0x20, 0x6c, 0x61, 0x74, 0x65, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x74, + 0x68, 0x65, 0x72, 0x61, 0x70, 0x79, 0x61, 0x20, 0x70, 0x6f, 0x69, 0x6e, 0x74, + 0x62, 0x61, 0x6e, 0x6e, 0x69, 0x6e, 0x67, 0x69, 0x6e, 0x6b, 0x73, 0x22, 0x3e, + 0x0a, 0x28, 0x29, 0x3b, 0x22, 0x20, 0x72, 0x65, 0x61, 0x20, 0x70, 0x6c, 0x61, + 0x63, 0x65, 0x5c, 0x75, 0x30, 0x30, 0x33, 0x43, 0x61, 0x61, 0x62, 0x6f, 0x75, + 0x74, 0x20, 0x61, 0x74, 0x72, 0x3e, 0x0d, 0x0a, 0x09, 0x09, 0x63, 0x63, 0x6f, + 0x75, 0x6e, 0x74, 0x20, 0x67, 0x69, 0x76, 0x65, 0x73, 0x20, 0x61, 0x3c, 0x53, + 0x43, 0x52, 0x49, 0x50, 0x54, 0x52, 0x61, 0x69, 0x6c, 0x77, 0x61, 0x79, 0x74, + 0x68, 0x65, 0x6d, 0x65, 0x73, 0x2f, 0x74, 0x6f, 0x6f, 0x6c, 0x62, 0x6f, 0x78, + 0x42, 0x79, 0x49, 0x64, 0x28, 0x22, 0x78, 0x68, 0x75, 0x6d, 0x61, 0x6e, 0x73, + 0x2c, 0x77, 0x61, 0x74, 0x63, 0x68, 0x65, 0x73, 0x69, 0x6e, 0x20, 0x73, 0x6f, + 0x6d, 0x65, 0x20, 0x69, 0x66, 0x20, 0x28, 0x77, 0x69, 0x63, 0x6f, 0x6d, 0x69, + 0x6e, 0x67, 0x20, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x73, 0x20, 0x55, 0x6e, + 0x64, 0x65, 0x72, 0x20, 0x62, 0x75, 0x74, 0x20, 0x68, 0x61, 0x73, 0x68, 0x61, + 0x6e, 0x64, 0x65, 0x64, 0x20, 0x6d, 0x61, 0x64, 0x65, 0x20, 0x62, 0x79, 0x74, + 0x68, 0x61, 0x6e, 0x20, 0x69, 0x6e, 0x66, 0x65, 0x61, 0x72, 0x20, 0x6f, 0x66, + 0x64, 0x65, 0x6e, 0x6f, 0x74, 0x65, 0x64, 0x2f, 0x69, 0x66, 0x72, 0x61, 0x6d, + 0x65, 0x6c, 0x65, 0x66, 0x74, 0x20, 0x69, 0x6e, 0x76, 0x6f, 0x6c, 0x74, 0x61, + 0x67, 0x65, 0x69, 0x6e, 0x20, 0x65, 0x61, 0x63, 0x68, 0x61, 0x26, 0x71, 0x75, + 0x6f, 0x74, 0x3b, 0x62, 0x61, 0x73, 0x65, 0x20, 0x6f, 0x66, 0x49, 0x6e, 0x20, + 0x6d, 0x61, 0x6e, 0x79, 0x75, 0x6e, 0x64, 0x65, 0x72, 0x67, 0x6f, 0x72, 0x65, + 0x67, 0x69, 0x6d, 0x65, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x3c, + 0x2f, 0x70, 0x3e, 0x0d, 0x0a, 0x3c, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x56, 0x61, + 0x3b, 0x26, 0x67, 0x74, 0x3b, 0x3c, 0x2f, 0x69, 0x6d, 0x70, 0x6f, 0x72, 0x74, + 0x73, 0x6f, 0x72, 0x20, 0x74, 0x68, 0x61, 0x74, 0x6d, 0x6f, 0x73, 0x74, 0x6c, + 0x79, 0x20, 0x26, 0x61, 0x6d, 0x70, 0x3b, 0x72, 0x65, 0x20, 0x73, 0x69, 0x7a, + 0x65, 0x3d, 0x22, 0x3c, 0x2f, 0x61, 0x3e, 0x3c, 0x2f, 0x68, 0x61, 0x20, 0x63, + 0x6c, 0x61, 0x73, 0x73, 0x70, 0x61, 0x73, 0x73, 0x69, 0x76, 0x65, 0x48, 0x6f, + 0x73, 0x74, 0x20, 0x3d, 0x20, 0x57, 0x68, 0x65, 0x74, 0x68, 0x65, 0x72, 0x66, + 0x65, 0x72, 0x74, 0x69, 0x6c, 0x65, 0x56, 0x61, 0x72, 0x69, 0x6f, 0x75, 0x73, + 0x3d, 0x5b, 0x5d, 0x3b, 0x28, 0x66, 0x75, 0x63, 0x61, 0x6d, 0x65, 0x72, 0x61, + 0x73, 0x2f, 0x3e, 0x3c, 0x2f, 0x74, 0x64, 0x3e, 0x61, 0x63, 0x74, 0x73, 0x20, + 0x61, 0x73, 0x49, 0x6e, 0x20, 0x73, 0x6f, 0x6d, 0x65, 0x3e, 0x0d, 0x0a, 0x0d, + 0x0a, 0x3c, 0x21, 0x6f, 0x72, 0x67, 0x61, 0x6e, 0x69, 0x73, 0x20, 0x3c, 0x62, + 0x72, 0x20, 0x2f, 0x3e, 0x42, 0x65, 0x69, 0x6a, 0x69, 0x6e, 0x67, 0x63, 0x61, + 0x74, 0x61, 0x6c, 0xc3, 0xa0, 0x64, 0x65, 0x75, 0x74, 0x73, 0x63, 0x68, 0x65, + 0x75, 0x72, 0x6f, 0x70, 0x65, 0x75, 0x65, 0x75, 0x73, 0x6b, 0x61, 0x72, 0x61, + 0x67, 0x61, 0x65, 0x69, 0x6c, 0x67, 0x65, 0x73, 0x76, 0x65, 0x6e, 0x73, 0x6b, + 0x61, 0x65, 0x73, 0x70, 0x61, 0xc3, 0xb1, 0x61, 0x6d, 0x65, 0x6e, 0x73, 0x61, + 0x6a, 0x65, 0x75, 0x73, 0x75, 0x61, 0x72, 0x69, 0x6f, 0x74, 0x72, 0x61, 0x62, + 0x61, 0x6a, 0x6f, 0x6d, 0xc3, 0xa9, 0x78, 0x69, 0x63, 0x6f, 0x70, 0xc3, 0xa1, + 0x67, 0x69, 0x6e, 0x61, 0x73, 0x69, 0x65, 0x6d, 0x70, 0x72, 0x65, 0x73, 0x69, + 0x73, 0x74, 0x65, 0x6d, 0x61, 0x6f, 0x63, 0x74, 0x75, 0x62, 0x72, 0x65, 0x64, + 0x75, 0x72, 0x61, 0x6e, 0x74, 0x65, 0x61, 0xc3, 0xb1, 0x61, 0x64, 0x69, 0x72, + 0x65, 0x6d, 0x70, 0x72, 0x65, 0x73, 0x61, 0x6d, 0x6f, 0x6d, 0x65, 0x6e, 0x74, + 0x6f, 0x6e, 0x75, 0x65, 0x73, 0x74, 0x72, 0x6f, 0x70, 0x72, 0x69, 0x6d, 0x65, + 0x72, 0x61, 0x74, 0x72, 0x61, 0x76, 0xc3, 0xa9, 0x73, 0x67, 0x72, 0x61, 0x63, + 0x69, 0x61, 0x73, 0x6e, 0x75, 0x65, 0x73, 0x74, 0x72, 0x61, 0x70, 0x72, 0x6f, + 0x63, 0x65, 0x73, 0x6f, 0x65, 0x73, 0x74, 0x61, 0x64, 0x6f, 0x73, 0x63, 0x61, + 0x6c, 0x69, 0x64, 0x61, 0x64, 0x70, 0x65, 0x72, 0x73, 0x6f, 0x6e, 0x61, 0x6e, + 0xc3, 0xba, 0x6d, 0x65, 0x72, 0x6f, 0x61, 0x63, 0x75, 0x65, 0x72, 0x64, 0x6f, + 0x6d, 0xc3, 0xba, 0x73, 0x69, 0x63, 0x61, 0x6d, 0x69, 0x65, 0x6d, 0x62, 0x72, + 0x6f, 0x6f, 0x66, 0x65, 0x72, 0x74, 0x61, 0x73, 0x61, 0x6c, 0x67, 0x75, 0x6e, + 0x6f, 0x73, 0x70, 0x61, 0xc3, 0xad, 0x73, 0x65, 0x73, 0x65, 0x6a, 0x65, 0x6d, + 0x70, 0x6c, 0x6f, 0x64, 0x65, 0x72, 0x65, 0x63, 0x68, 0x6f, 0x61, 0x64, 0x65, + 0x6d, 0xc3, 0xa1, 0x73, 0x70, 0x72, 0x69, 0x76, 0x61, 0x64, 0x6f, 0x61, 0x67, + 0x72, 0x65, 0x67, 0x61, 0x72, 0x65, 0x6e, 0x6c, 0x61, 0x63, 0x65, 0x73, 0x70, + 0x6f, 0x73, 0x69, 0x62, 0x6c, 0x65, 0x68, 0x6f, 0x74, 0x65, 0x6c, 0x65, 0x73, + 0x73, 0x65, 0x76, 0x69, 0x6c, 0x6c, 0x61, 0x70, 0x72, 0x69, 0x6d, 0x65, 0x72, + 0x6f, 0xc3, 0xba, 0x6c, 0x74, 0x69, 0x6d, 0x6f, 0x65, 0x76, 0x65, 0x6e, 0x74, + 0x6f, 0x73, 0x61, 0x72, 0x63, 0x68, 0x69, 0x76, 0x6f, 0x63, 0x75, 0x6c, 0x74, + 0x75, 0x72, 0x61, 0x6d, 0x75, 0x6a, 0x65, 0x72, 0x65, 0x73, 0x65, 0x6e, 0x74, + 0x72, 0x61, 0x64, 0x61, 0x61, 0x6e, 0x75, 0x6e, 0x63, 0x69, 0x6f, 0x65, 0x6d, + 0x62, 0x61, 0x72, 0x67, 0x6f, 0x6d, 0x65, 0x72, 0x63, 0x61, 0x64, 0x6f, 0x67, + 0x72, 0x61, 0x6e, 0x64, 0x65, 0x73, 0x65, 0x73, 0x74, 0x75, 0x64, 0x69, 0x6f, + 0x6d, 0x65, 0x6a, 0x6f, 0x72, 0x65, 0x73, 0x66, 0x65, 0x62, 0x72, 0x65, 0x72, + 0x6f, 0x64, 0x69, 0x73, 0x65, 0xc3, 0xb1, 0x6f, 0x74, 0x75, 0x72, 0x69, 0x73, + 0x6d, 0x6f, 0x63, 0xc3, 0xb3, 0x64, 0x69, 0x67, 0x6f, 0x70, 0x6f, 0x72, 0x74, + 0x61, 0x64, 0x61, 0x65, 0x73, 0x70, 0x61, 0x63, 0x69, 0x6f, 0x66, 0x61, 0x6d, + 0x69, 0x6c, 0x69, 0x61, 0x61, 0x6e, 0x74, 0x6f, 0x6e, 0x69, 0x6f, 0x70, 0x65, + 0x72, 0x6d, 0x69, 0x74, 0x65, 0x67, 0x75, 0x61, 0x72, 0x64, 0x61, 0x72, 0x61, + 0x6c, 0x67, 0x75, 0x6e, 0x61, 0x73, 0x70, 0x72, 0x65, 0x63, 0x69, 0x6f, 0x73, + 0x61, 0x6c, 0x67, 0x75, 0x69, 0x65, 0x6e, 0x73, 0x65, 0x6e, 0x74, 0x69, 0x64, + 0x6f, 0x76, 0x69, 0x73, 0x69, 0x74, 0x61, 0x73, 0x74, 0xc3, 0xad, 0x74, 0x75, + 0x6c, 0x6f, 0x63, 0x6f, 0x6e, 0x6f, 0x63, 0x65, 0x72, 0x73, 0x65, 0x67, 0x75, + 0x6e, 0x64, 0x6f, 0x63, 0x6f, 0x6e, 0x73, 0x65, 0x6a, 0x6f, 0x66, 0x72, 0x61, + 0x6e, 0x63, 0x69, 0x61, 0x6d, 0x69, 0x6e, 0x75, 0x74, 0x6f, 0x73, 0x73, 0x65, + 0x67, 0x75, 0x6e, 0x64, 0x61, 0x74, 0x65, 0x6e, 0x65, 0x6d, 0x6f, 0x73, 0x65, + 0x66, 0x65, 0x63, 0x74, 0x6f, 0x73, 0x6d, 0xc3, 0xa1, 0x6c, 0x61, 0x67, 0x61, + 0x73, 0x65, 0x73, 0x69, 0xc3, 0xb3, 0x6e, 0x72, 0x65, 0x76, 0x69, 0x73, 0x74, + 0x61, 0x67, 0x72, 0x61, 0x6e, 0x61, 0x64, 0x61, 0x63, 0x6f, 0x6d, 0x70, 0x72, + 0x61, 0x72, 0x69, 0x6e, 0x67, 0x72, 0x65, 0x73, 0x6f, 0x67, 0x61, 0x72, 0x63, + 0xc3, 0xad, 0x61, 0x61, 0x63, 0x63, 0x69, 0xc3, 0xb3, 0x6e, 0x65, 0x63, 0x75, + 0x61, 0x64, 0x6f, 0x72, 0x71, 0x75, 0x69, 0x65, 0x6e, 0x65, 0x73, 0x69, 0x6e, + 0x63, 0x6c, 0x75, 0x73, 0x6f, 0x64, 0x65, 0x62, 0x65, 0x72, 0xc3, 0xa1, 0x6d, + 0x61, 0x74, 0x65, 0x72, 0x69, 0x61, 0x68, 0x6f, 0x6d, 0x62, 0x72, 0x65, 0x73, + 0x6d, 0x75, 0x65, 0x73, 0x74, 0x72, 0x61, 0x70, 0x6f, 0x64, 0x72, 0xc3, 0xad, + 0x61, 0x6d, 0x61, 0xc3, 0xb1, 0x61, 0x6e, 0x61, 0xc3, 0xba, 0x6c, 0x74, 0x69, + 0x6d, 0x61, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x6f, 0x73, 0x6f, 0x66, 0x69, 0x63, + 0x69, 0x61, 0x6c, 0x74, 0x61, 0x6d, 0x62, 0x69, 0x65, 0x6e, 0x6e, 0x69, 0x6e, + 0x67, 0xc3, 0xba, 0x6e, 0x73, 0x61, 0x6c, 0x75, 0x64, 0x6f, 0x73, 0x70, 0x6f, + 0x64, 0x65, 0x6d, 0x6f, 0x73, 0x6d, 0x65, 0x6a, 0x6f, 0x72, 0x61, 0x72, 0x70, + 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x62, 0x75, 0x73, 0x69, 0x6e, 0x65, + 0x73, 0x73, 0x68, 0x6f, 0x6d, 0x65, 0x70, 0x61, 0x67, 0x65, 0x73, 0x65, 0x63, + 0x75, 0x72, 0x69, 0x74, 0x79, 0x6c, 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, + 0x73, 0x74, 0x61, 0x6e, 0x64, 0x61, 0x72, 0x64, 0x63, 0x61, 0x6d, 0x70, 0x61, + 0x69, 0x67, 0x6e, 0x66, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x63, 0x61, + 0x74, 0x65, 0x67, 0x6f, 0x72, 0x79, 0x65, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, + 0x6c, 0x63, 0x68, 0x69, 0x6c, 0x64, 0x72, 0x65, 0x6e, 0x72, 0x65, 0x73, 0x65, + 0x72, 0x76, 0x65, 0x64, 0x72, 0x65, 0x73, 0x65, 0x61, 0x72, 0x63, 0x68, 0x65, + 0x78, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x66, 0x61, 0x76, 0x6f, 0x72, 0x69, + 0x74, 0x65, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x6d, 0x69, 0x6c, + 0x69, 0x74, 0x61, 0x72, 0x79, 0x69, 0x6e, 0x64, 0x75, 0x73, 0x74, 0x72, 0x79, + 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x6d, 0x61, 0x74, 0x65, 0x72, + 0x69, 0x61, 0x6c, 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x73, 0x7a, 0x2d, + 0x69, 0x6e, 0x64, 0x65, 0x78, 0x3a, 0x63, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, + 0x73, 0x73, 0x6f, 0x66, 0x74, 0x77, 0x61, 0x72, 0x65, 0x63, 0x6f, 0x6d, 0x70, + 0x6c, 0x65, 0x74, 0x65, 0x63, 0x61, 0x6c, 0x65, 0x6e, 0x64, 0x61, 0x72, 0x70, + 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x72, 0x74, 0x69, 0x63, 0x6c, + 0x65, 0x73, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x6d, 0x6f, 0x76, + 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x71, 0x75, 0x65, 0x73, 0x74, 0x69, 0x6f, 0x6e, + 0x62, 0x75, 0x69, 0x6c, 0x64, 0x69, 0x6e, 0x67, 0x70, 0x6f, 0x6c, 0x69, 0x74, + 0x69, 0x63, 0x73, 0x70, 0x6f, 0x73, 0x73, 0x69, 0x62, 0x6c, 0x65, 0x72, 0x65, + 0x6c, 0x69, 0x67, 0x69, 0x6f, 0x6e, 0x70, 0x68, 0x79, 0x73, 0x69, 0x63, 0x61, + 0x6c, 0x66, 0x65, 0x65, 0x64, 0x62, 0x61, 0x63, 0x6b, 0x72, 0x65, 0x67, 0x69, + 0x73, 0x74, 0x65, 0x72, 0x70, 0x69, 0x63, 0x74, 0x75, 0x72, 0x65, 0x73, 0x64, + 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, + 0x6f, 0x6c, 0x61, 0x75, 0x64, 0x69, 0x65, 0x6e, 0x63, 0x65, 0x73, 0x65, 0x74, + 0x74, 0x69, 0x6e, 0x67, 0x73, 0x61, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, + 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x6c, 0x65, 0x61, 0x72, 0x6e, + 0x69, 0x6e, 0x67, 0x61, 0x6e, 0x79, 0x74, 0x68, 0x69, 0x6e, 0x67, 0x61, 0x62, + 0x73, 0x74, 0x72, 0x61, 0x63, 0x74, 0x70, 0x72, 0x6f, 0x67, 0x72, 0x65, 0x73, + 0x73, 0x6f, 0x76, 0x65, 0x72, 0x76, 0x69, 0x65, 0x77, 0x6d, 0x61, 0x67, 0x61, + 0x7a, 0x69, 0x6e, 0x65, 0x65, 0x63, 0x6f, 0x6e, 0x6f, 0x6d, 0x69, 0x63, 0x74, + 0x72, 0x61, 0x69, 0x6e, 0x69, 0x6e, 0x67, 0x70, 0x72, 0x65, 0x73, 0x73, 0x75, + 0x72, 0x65, 0x76, 0x61, 0x72, 0x69, 0x6f, 0x75, 0x73, 0x20, 0x3c, 0x73, 0x74, + 0x72, 0x6f, 0x6e, 0x67, 0x3e, 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, + 0x73, 0x68, 0x6f, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x74, 0x6f, 0x67, 0x65, 0x74, + 0x68, 0x65, 0x72, 0x61, 0x64, 0x76, 0x61, 0x6e, 0x63, 0x65, 0x64, 0x62, 0x65, + 0x68, 0x61, 0x76, 0x69, 0x6f, 0x72, 0x64, 0x6f, 0x77, 0x6e, 0x6c, 0x6f, 0x61, + 0x64, 0x66, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x64, 0x66, 0x6f, 0x6f, 0x74, + 0x62, 0x61, 0x6c, 0x6c, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x65, 0x64, 0x4c, + 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, 0x64, 0x69, 0x73, 0x74, 0x61, 0x6e, + 0x63, 0x65, 0x72, 0x65, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x74, 0x72, 0x61, + 0x63, 0x6b, 0x69, 0x6e, 0x67, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, + 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x69, 0x65, 0x64, 0x73, 0x74, 0x75, 0x64, 0x65, + 0x6e, 0x74, 0x73, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6c, 0x79, 0x66, 0x69, + 0x67, 0x68, 0x74, 0x69, 0x6e, 0x67, 0x6e, 0x6f, 0x72, 0x74, 0x68, 0x65, 0x72, + 0x6e, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x66, 0x65, 0x73, 0x74, + 0x69, 0x76, 0x61, 0x6c, 0x62, 0x72, 0x65, 0x61, 0x6b, 0x69, 0x6e, 0x67, 0x6c, + 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, + 0x65, 0x74, 0x64, 0x72, 0x6f, 0x70, 0x64, 0x6f, 0x77, 0x6e, 0x70, 0x72, 0x61, + 0x63, 0x74, 0x69, 0x63, 0x65, 0x65, 0x76, 0x69, 0x64, 0x65, 0x6e, 0x63, 0x65, + 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x6d, 0x61, 0x72, 0x72, 0x69, + 0x61, 0x67, 0x65, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x70, 0x72, + 0x6f, 0x62, 0x6c, 0x65, 0x6d, 0x73, 0x6e, 0x65, 0x67, 0x61, 0x74, 0x69, 0x76, + 0x65, 0x70, 0x72, 0x6f, 0x67, 0x72, 0x61, 0x6d, 0x73, 0x61, 0x6e, 0x61, 0x6c, + 0x79, 0x73, 0x69, 0x73, 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x64, 0x62, + 0x61, 0x6e, 0x6e, 0x65, 0x72, 0x22, 0x3e, 0x70, 0x75, 0x72, 0x63, 0x68, 0x61, + 0x73, 0x65, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x69, 0x65, 0x73, 0x72, 0x65, 0x67, + 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x63, 0x72, 0x65, 0x61, 0x74, 0x69, 0x76, 0x65, + 0x61, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x62, 0x6f, 0x6f, 0x6b, 0x6d, + 0x61, 0x72, 0x6b, 0x72, 0x65, 0x66, 0x65, 0x72, 0x72, 0x65, 0x72, 0x63, 0x68, + 0x65, 0x6d, 0x69, 0x63, 0x61, 0x6c, 0x64, 0x69, 0x76, 0x69, 0x73, 0x69, 0x6f, + 0x6e, 0x63, 0x61, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x73, 0x65, 0x70, 0x61, + 0x72, 0x61, 0x74, 0x65, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x63, + 0x6f, 0x6e, 0x66, 0x6c, 0x69, 0x63, 0x74, 0x68, 0x61, 0x72, 0x64, 0x77, 0x61, + 0x72, 0x65, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x65, 0x73, 0x74, 0x64, 0x65, 0x6c, + 0x69, 0x76, 0x65, 0x72, 0x79, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x61, 0x69, 0x6e, + 0x6f, 0x62, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x64, 0x3d, 0x20, 0x66, 0x61, 0x6c, + 0x73, 0x65, 0x3b, 0x66, 0x6f, 0x72, 0x28, 0x76, 0x61, 0x72, 0x20, 0x61, 0x63, + 0x63, 0x65, 0x70, 0x74, 0x65, 0x64, 0x63, 0x61, 0x70, 0x61, 0x63, 0x69, 0x74, + 0x79, 0x63, 0x6f, 0x6d, 0x70, 0x75, 0x74, 0x65, 0x72, 0x69, 0x64, 0x65, 0x6e, + 0x74, 0x69, 0x74, 0x79, 0x61, 0x69, 0x72, 0x63, 0x72, 0x61, 0x66, 0x74, 0x65, + 0x6d, 0x70, 0x6c, 0x6f, 0x79, 0x65, 0x64, 0x70, 0x72, 0x6f, 0x70, 0x6f, 0x73, + 0x65, 0x64, 0x64, 0x6f, 0x6d, 0x65, 0x73, 0x74, 0x69, 0x63, 0x69, 0x6e, 0x63, + 0x6c, 0x75, 0x64, 0x65, 0x73, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x64, + 0x68, 0x6f, 0x73, 0x70, 0x69, 0x74, 0x61, 0x6c, 0x76, 0x65, 0x72, 0x74, 0x69, + 0x63, 0x61, 0x6c, 0x63, 0x6f, 0x6c, 0x6c, 0x61, 0x70, 0x73, 0x65, 0x61, 0x70, + 0x70, 0x72, 0x6f, 0x61, 0x63, 0x68, 0x70, 0x61, 0x72, 0x74, 0x6e, 0x65, 0x72, + 0x73, 0x6c, 0x6f, 0x67, 0x6f, 0x22, 0x3e, 0x3c, 0x61, 0x64, 0x61, 0x75, 0x67, + 0x68, 0x74, 0x65, 0x72, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x22, 0x20, 0x63, + 0x75, 0x6c, 0x74, 0x75, 0x72, 0x61, 0x6c, 0x66, 0x61, 0x6d, 0x69, 0x6c, 0x69, + 0x65, 0x73, 0x2f, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x73, 0x2f, 0x61, 0x73, 0x73, + 0x65, 0x6d, 0x62, 0x6c, 0x79, 0x70, 0x6f, 0x77, 0x65, 0x72, 0x66, 0x75, 0x6c, + 0x74, 0x65, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x67, 0x66, 0x69, 0x6e, 0x69, 0x73, + 0x68, 0x65, 0x64, 0x64, 0x69, 0x73, 0x74, 0x72, 0x69, 0x63, 0x74, 0x63, 0x72, + 0x69, 0x74, 0x69, 0x63, 0x61, 0x6c, 0x63, 0x67, 0x69, 0x2d, 0x62, 0x69, 0x6e, + 0x2f, 0x70, 0x75, 0x72, 0x70, 0x6f, 0x73, 0x65, 0x73, 0x72, 0x65, 0x71, 0x75, + 0x69, 0x72, 0x65, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x62, + 0x65, 0x63, 0x6f, 0x6d, 0x69, 0x6e, 0x67, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, + 0x65, 0x73, 0x61, 0x63, 0x61, 0x64, 0x65, 0x6d, 0x69, 0x63, 0x65, 0x78, 0x65, + 0x72, 0x63, 0x69, 0x73, 0x65, 0x61, 0x63, 0x74, 0x75, 0x61, 0x6c, 0x6c, 0x79, + 0x6d, 0x65, 0x64, 0x69, 0x63, 0x69, 0x6e, 0x65, 0x63, 0x6f, 0x6e, 0x73, 0x74, + 0x61, 0x6e, 0x74, 0x61, 0x63, 0x63, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x4d, 0x61, + 0x67, 0x61, 0x7a, 0x69, 0x6e, 0x65, 0x64, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, + 0x74, 0x73, 0x74, 0x61, 0x72, 0x74, 0x69, 0x6e, 0x67, 0x62, 0x6f, 0x74, 0x74, + 0x6f, 0x6d, 0x22, 0x3e, 0x6f, 0x62, 0x73, 0x65, 0x72, 0x76, 0x65, 0x64, 0x3a, + 0x20, 0x26, 0x71, 0x75, 0x6f, 0x74, 0x3b, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x64, + 0x65, 0x64, 0x70, 0x72, 0x65, 0x76, 0x69, 0x6f, 0x75, 0x73, 0x53, 0x6f, 0x66, + 0x74, 0x77, 0x61, 0x72, 0x65, 0x63, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x65, 0x72, + 0x64, 0x65, 0x63, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x74, 0x72, 0x65, 0x6e, + 0x67, 0x74, 0x68, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x65, 0x64, 0x73, 0x6c, + 0x69, 0x67, 0x68, 0x74, 0x6c, 0x79, 0x70, 0x6c, 0x61, 0x6e, 0x6e, 0x69, 0x6e, + 0x67, 0x74, 0x65, 0x78, 0x74, 0x61, 0x72, 0x65, 0x61, 0x63, 0x75, 0x72, 0x72, + 0x65, 0x6e, 0x63, 0x79, 0x65, 0x76, 0x65, 0x72, 0x79, 0x6f, 0x6e, 0x65, 0x73, + 0x74, 0x72, 0x61, 0x69, 0x67, 0x68, 0x74, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, + 0x65, 0x72, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x76, 0x65, 0x70, 0x72, 0x6f, + 0x64, 0x75, 0x63, 0x65, 0x64, 0x68, 0x65, 0x72, 0x69, 0x74, 0x61, 0x67, 0x65, + 0x73, 0x68, 0x69, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x61, 0x62, 0x73, 0x6f, 0x6c, + 0x75, 0x74, 0x65, 0x72, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x64, 0x72, 0x65, + 0x6c, 0x65, 0x76, 0x61, 0x6e, 0x74, 0x62, 0x75, 0x74, 0x74, 0x6f, 0x6e, 0x22, + 0x20, 0x76, 0x69, 0x6f, 0x6c, 0x65, 0x6e, 0x63, 0x65, 0x61, 0x6e, 0x79, 0x77, + 0x68, 0x65, 0x72, 0x65, 0x62, 0x65, 0x6e, 0x65, 0x66, 0x69, 0x74, 0x73, 0x6c, + 0x61, 0x75, 0x6e, 0x63, 0x68, 0x65, 0x64, 0x72, 0x65, 0x63, 0x65, 0x6e, 0x74, + 0x6c, 0x79, 0x61, 0x6c, 0x6c, 0x69, 0x61, 0x6e, 0x63, 0x65, 0x66, 0x6f, 0x6c, + 0x6c, 0x6f, 0x77, 0x65, 0x64, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x70, 0x6c, 0x65, + 0x62, 0x75, 0x6c, 0x6c, 0x65, 0x74, 0x69, 0x6e, 0x69, 0x6e, 0x63, 0x6c, 0x75, + 0x64, 0x65, 0x64, 0x6f, 0x63, 0x63, 0x75, 0x72, 0x72, 0x65, 0x64, 0x69, 0x6e, + 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x24, 0x28, 0x74, 0x68, 0x69, 0x73, 0x29, + 0x2e, 0x72, 0x65, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x3e, 0x3c, 0x74, 0x72, + 0x3e, 0x3c, 0x74, 0x64, 0x63, 0x6f, 0x6e, 0x67, 0x72, 0x65, 0x73, 0x73, 0x72, + 0x65, 0x63, 0x6f, 0x72, 0x64, 0x65, 0x64, 0x75, 0x6c, 0x74, 0x69, 0x6d, 0x61, + 0x74, 0x65, 0x73, 0x6f, 0x6c, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x3c, 0x75, 0x6c, + 0x20, 0x69, 0x64, 0x3d, 0x22, 0x64, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, + 0x48, 0x6f, 0x6d, 0x65, 0x3c, 0x2f, 0x61, 0x3e, 0x77, 0x65, 0x62, 0x73, 0x69, + 0x74, 0x65, 0x73, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x61, 0x6c, + 0x74, 0x68, 0x6f, 0x75, 0x67, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x72, 0x65, 0x6c, + 0x79, 0x6d, 0x65, 0x6d, 0x6f, 0x72, 0x69, 0x61, 0x6c, 0x6d, 0x65, 0x73, 0x73, + 0x61, 0x67, 0x65, 0x73, 0x63, 0x6f, 0x6e, 0x74, 0x69, 0x6e, 0x75, 0x65, 0x61, + 0x63, 0x74, 0x69, 0x76, 0x65, 0x22, 0x3e, 0x73, 0x6f, 0x6d, 0x65, 0x77, 0x68, + 0x61, 0x74, 0x76, 0x69, 0x63, 0x74, 0x6f, 0x72, 0x69, 0x61, 0x57, 0x65, 0x73, + 0x74, 0x65, 0x72, 0x6e, 0x20, 0x20, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x3d, 0x22, + 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x63, 0x6f, 0x6e, 0x74, 0x72, + 0x61, 0x63, 0x74, 0x76, 0x69, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x73, 0x44, 0x6f, + 0x77, 0x6e, 0x6c, 0x6f, 0x61, 0x64, 0x77, 0x69, 0x74, 0x68, 0x6f, 0x75, 0x74, + 0x20, 0x72, 0x69, 0x67, 0x68, 0x74, 0x22, 0x3e, 0x0a, 0x6d, 0x65, 0x61, 0x73, + 0x75, 0x72, 0x65, 0x73, 0x77, 0x69, 0x64, 0x74, 0x68, 0x20, 0x3d, 0x20, 0x76, + 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x69, 0x6e, 0x76, 0x6f, 0x6c, 0x76, + 0x65, 0x64, 0x76, 0x69, 0x72, 0x67, 0x69, 0x6e, 0x69, 0x61, 0x6e, 0x6f, 0x72, + 0x6d, 0x61, 0x6c, 0x6c, 0x79, 0x68, 0x61, 0x70, 0x70, 0x65, 0x6e, 0x65, 0x64, + 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x73, 0x74, 0x61, 0x6e, 0x64, + 0x69, 0x6e, 0x67, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x52, 0x65, + 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x70, 0x72, 0x65, 0x70, 0x61, 0x72, 0x65, + 0x64, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x73, 0x61, 0x63, 0x63, 0x75, + 0x72, 0x61, 0x74, 0x65, 0x62, 0x69, 0x72, 0x74, 0x68, 0x64, 0x61, 0x79, 0x73, + 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x6f, 0x66, 0x66, 0x69, 0x63, 0x69, + 0x61, 0x6c, 0x67, 0x72, 0x61, 0x70, 0x68, 0x69, 0x63, 0x73, 0x63, 0x72, 0x69, + 0x6d, 0x69, 0x6e, 0x61, 0x6c, 0x70, 0x6f, 0x73, 0x73, 0x69, 0x62, 0x6c, 0x79, + 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6d, 0x65, 0x72, 0x50, 0x65, 0x72, 0x73, 0x6f, + 0x6e, 0x61, 0x6c, 0x73, 0x70, 0x65, 0x61, 0x6b, 0x69, 0x6e, 0x67, 0x76, 0x61, + 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x61, 0x63, 0x68, 0x69, 0x65, 0x76, 0x65, + 0x64, 0x2e, 0x6a, 0x70, 0x67, 0x22, 0x20, 0x2f, 0x3e, 0x6d, 0x61, 0x63, 0x68, + 0x69, 0x6e, 0x65, 0x73, 0x3c, 0x2f, 0x68, 0x32, 0x3e, 0x0a, 0x20, 0x20, 0x6b, + 0x65, 0x79, 0x77, 0x6f, 0x72, 0x64, 0x73, 0x66, 0x72, 0x69, 0x65, 0x6e, 0x64, + 0x6c, 0x79, 0x62, 0x72, 0x6f, 0x74, 0x68, 0x65, 0x72, 0x73, 0x63, 0x6f, 0x6d, + 0x62, 0x69, 0x6e, 0x65, 0x64, 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x61, 0x6c, + 0x63, 0x6f, 0x6d, 0x70, 0x6f, 0x73, 0x65, 0x64, 0x65, 0x78, 0x70, 0x65, 0x63, + 0x74, 0x65, 0x64, 0x61, 0x64, 0x65, 0x71, 0x75, 0x61, 0x74, 0x65, 0x70, 0x61, + 0x6b, 0x69, 0x73, 0x74, 0x61, 0x6e, 0x66, 0x6f, 0x6c, 0x6c, 0x6f, 0x77, 0x22, + 0x20, 0x76, 0x61, 0x6c, 0x75, 0x61, 0x62, 0x6c, 0x65, 0x3c, 0x2f, 0x6c, 0x61, + 0x62, 0x65, 0x6c, 0x3e, 0x72, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x76, 0x65, 0x62, + 0x72, 0x69, 0x6e, 0x67, 0x69, 0x6e, 0x67, 0x69, 0x6e, 0x63, 0x72, 0x65, 0x61, + 0x73, 0x65, 0x67, 0x6f, 0x76, 0x65, 0x72, 0x6e, 0x6f, 0x72, 0x70, 0x6c, 0x75, + 0x67, 0x69, 0x6e, 0x73, 0x2f, 0x4c, 0x69, 0x73, 0x74, 0x20, 0x6f, 0x66, 0x20, + 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x22, 0x3e, 0x22, 0x20, 0x6e, 0x61, 0x6d, + 0x65, 0x3d, 0x22, 0x20, 0x28, 0x26, 0x71, 0x75, 0x6f, 0x74, 0x3b, 0x67, 0x72, + 0x61, 0x64, 0x75, 0x61, 0x74, 0x65, 0x3c, 0x2f, 0x68, 0x65, 0x61, 0x64, 0x3e, + 0x0a, 0x63, 0x6f, 0x6d, 0x6d, 0x65, 0x72, 0x63, 0x65, 0x6d, 0x61, 0x6c, 0x61, + 0x79, 0x73, 0x69, 0x61, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x6d, + 0x61, 0x69, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x3b, 0x68, 0x65, 0x69, 0x67, 0x68, + 0x74, 0x3a, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x63, 0x68, 0x61, + 0x6e, 0x67, 0x69, 0x6e, 0x67, 0x62, 0x61, 0x63, 0x6b, 0x20, 0x74, 0x6f, 0x20, + 0x63, 0x61, 0x74, 0x68, 0x6f, 0x6c, 0x69, 0x63, 0x70, 0x61, 0x74, 0x74, 0x65, + 0x72, 0x6e, 0x73, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x20, 0x23, 0x67, 0x72, + 0x65, 0x61, 0x74, 0x65, 0x73, 0x74, 0x73, 0x75, 0x70, 0x70, 0x6c, 0x69, 0x65, + 0x73, 0x72, 0x65, 0x6c, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x3c, 0x2f, 0x75, 0x6c, + 0x3e, 0x0a, 0x09, 0x09, 0x3c, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x20, 0x63, + 0x69, 0x74, 0x69, 0x7a, 0x65, 0x6e, 0x73, 0x63, 0x6c, 0x6f, 0x74, 0x68, 0x69, + 0x6e, 0x67, 0x77, 0x61, 0x74, 0x63, 0x68, 0x69, 0x6e, 0x67, 0x3c, 0x6c, 0x69, + 0x20, 0x69, 0x64, 0x3d, 0x22, 0x73, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x63, + 0x63, 0x61, 0x72, 0x72, 0x79, 0x69, 0x6e, 0x67, 0x73, 0x65, 0x6e, 0x74, 0x65, + 0x6e, 0x63, 0x65, 0x3c, 0x63, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x3e, 0x63, 0x6f, + 0x6e, 0x74, 0x72, 0x61, 0x73, 0x74, 0x74, 0x68, 0x69, 0x6e, 0x6b, 0x69, 0x6e, + 0x67, 0x63, 0x61, 0x74, 0x63, 0x68, 0x28, 0x65, 0x29, 0x73, 0x6f, 0x75, 0x74, + 0x68, 0x65, 0x72, 0x6e, 0x4d, 0x69, 0x63, 0x68, 0x61, 0x65, 0x6c, 0x20, 0x6d, + 0x65, 0x72, 0x63, 0x68, 0x61, 0x6e, 0x74, 0x63, 0x61, 0x72, 0x6f, 0x75, 0x73, + 0x65, 0x6c, 0x70, 0x61, 0x64, 0x64, 0x69, 0x6e, 0x67, 0x3a, 0x69, 0x6e, 0x74, + 0x65, 0x72, 0x69, 0x6f, 0x72, 0x2e, 0x73, 0x70, 0x6c, 0x69, 0x74, 0x28, 0x22, + 0x6c, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4f, 0x63, 0x74, 0x6f, 0x62, + 0x65, 0x72, 0x20, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x69, 0x6d, + 0x70, 0x72, 0x6f, 0x76, 0x65, 0x64, 0x2d, 0x2d, 0x26, 0x67, 0x74, 0x3b, 0x0a, + 0x0a, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x61, 0x67, 0x65, 0x63, 0x68, 0x61, 0x69, + 0x72, 0x6d, 0x61, 0x6e, 0x2e, 0x70, 0x6e, 0x67, 0x22, 0x20, 0x2f, 0x3e, 0x73, + 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x52, 0x69, 0x63, 0x68, 0x61, 0x72, + 0x64, 0x20, 0x77, 0x68, 0x61, 0x74, 0x65, 0x76, 0x65, 0x72, 0x70, 0x72, 0x6f, + 0x62, 0x61, 0x62, 0x6c, 0x79, 0x72, 0x65, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x79, + 0x62, 0x61, 0x73, 0x65, 0x62, 0x61, 0x6c, 0x6c, 0x6a, 0x75, 0x64, 0x67, 0x6d, + 0x65, 0x6e, 0x74, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x2e, 0x2e, 0x63, + 0x73, 0x73, 0x22, 0x20, 0x2f, 0x3e, 0x20, 0x77, 0x65, 0x62, 0x73, 0x69, 0x74, + 0x65, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x64, 0x65, 0x66, 0x61, + 0x75, 0x6c, 0x74, 0x22, 0x2f, 0x3e, 0x3c, 0x2f, 0x61, 0x3e, 0x0d, 0x0a, 0x65, + 0x6c, 0x65, 0x63, 0x74, 0x72, 0x69, 0x63, 0x73, 0x63, 0x6f, 0x74, 0x6c, 0x61, + 0x6e, 0x64, 0x63, 0x72, 0x65, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x71, 0x75, 0x61, + 0x6e, 0x74, 0x69, 0x74, 0x79, 0x2e, 0x20, 0x49, 0x53, 0x42, 0x4e, 0x20, 0x30, + 0x64, 0x69, 0x64, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x69, 0x6e, 0x73, 0x74, 0x61, + 0x6e, 0x63, 0x65, 0x2d, 0x73, 0x65, 0x61, 0x72, 0x63, 0x68, 0x2d, 0x22, 0x20, + 0x6c, 0x61, 0x6e, 0x67, 0x3d, 0x22, 0x73, 0x70, 0x65, 0x61, 0x6b, 0x65, 0x72, + 0x73, 0x43, 0x6f, 0x6d, 0x70, 0x75, 0x74, 0x65, 0x72, 0x63, 0x6f, 0x6e, 0x74, + 0x61, 0x69, 0x6e, 0x73, 0x61, 0x72, 0x63, 0x68, 0x69, 0x76, 0x65, 0x73, 0x6d, + 0x69, 0x6e, 0x69, 0x73, 0x74, 0x65, 0x72, 0x72, 0x65, 0x61, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x64, 0x69, 0x73, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x49, 0x74, 0x61, + 0x6c, 0x69, 0x61, 0x6e, 0x6f, 0x63, 0x72, 0x69, 0x74, 0x65, 0x72, 0x69, 0x61, + 0x73, 0x74, 0x72, 0x6f, 0x6e, 0x67, 0x6c, 0x79, 0x3a, 0x20, 0x27, 0x68, 0x74, + 0x74, 0x70, 0x3a, 0x27, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x27, 0x63, 0x6f, + 0x76, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x6f, 0x66, 0x66, 0x65, 0x72, 0x69, 0x6e, + 0x67, 0x61, 0x70, 0x70, 0x65, 0x61, 0x72, 0x65, 0x64, 0x42, 0x72, 0x69, 0x74, + 0x69, 0x73, 0x68, 0x20, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x79, 0x46, + 0x61, 0x63, 0x65, 0x62, 0x6f, 0x6f, 0x6b, 0x6e, 0x75, 0x6d, 0x65, 0x72, 0x6f, + 0x75, 0x73, 0x76, 0x65, 0x68, 0x69, 0x63, 0x6c, 0x65, 0x73, 0x63, 0x6f, 0x6e, + 0x63, 0x65, 0x72, 0x6e, 0x73, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x6e, + 0x68, 0x61, 0x6e, 0x64, 0x6c, 0x69, 0x6e, 0x67, 0x64, 0x69, 0x76, 0x20, 0x69, + 0x64, 0x3d, 0x22, 0x57, 0x69, 0x6c, 0x6c, 0x69, 0x61, 0x6d, 0x20, 0x70, 0x72, + 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, + 0x74, 0x61, 0x63, 0x63, 0x75, 0x72, 0x61, 0x63, 0x79, 0x73, 0x65, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x20, 0x61, 0x6e, 0x64, 0x65, 0x72, 0x73, 0x6f, 0x6e, 0x66, + 0x6c, 0x65, 0x78, 0x69, 0x62, 0x6c, 0x65, 0x43, 0x61, 0x74, 0x65, 0x67, 0x6f, + 0x72, 0x79, 0x6c, 0x61, 0x77, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x3c, 0x73, 0x63, + 0x72, 0x69, 0x70, 0x74, 0x3e, 0x6c, 0x61, 0x79, 0x6f, 0x75, 0x74, 0x3d, 0x22, + 0x61, 0x70, 0x70, 0x72, 0x6f, 0x76, 0x65, 0x64, 0x20, 0x6d, 0x61, 0x78, 0x69, + 0x6d, 0x75, 0x6d, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x22, 0x3e, 0x3c, 0x2f, + 0x74, 0x61, 0x62, 0x6c, 0x65, 0x3e, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, + 0x73, 0x68, 0x61, 0x6d, 0x69, 0x6c, 0x74, 0x6f, 0x6e, 0x63, 0x75, 0x72, 0x72, + 0x65, 0x6e, 0x74, 0x20, 0x63, 0x61, 0x6e, 0x61, 0x64, 0x69, 0x61, 0x6e, 0x63, + 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x73, 0x2f, 0x74, 0x68, 0x65, 0x6d, 0x65, + 0x73, 0x2f, 0x2f, 0x61, 0x72, 0x74, 0x69, 0x63, 0x6c, 0x65, 0x6f, 0x70, 0x74, + 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x70, 0x6f, 0x72, 0x74, 0x75, 0x67, 0x61, 0x6c, + 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3d, 0x22, 0x22, 0x69, 0x6e, 0x74, 0x65, 0x72, + 0x76, 0x61, 0x6c, 0x77, 0x69, 0x72, 0x65, 0x6c, 0x65, 0x73, 0x73, 0x65, 0x6e, + 0x74, 0x69, 0x74, 0x6c, 0x65, 0x64, 0x61, 0x67, 0x65, 0x6e, 0x63, 0x69, 0x65, + 0x73, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x22, 0x20, 0x6d, 0x65, 0x61, 0x73, + 0x75, 0x72, 0x65, 0x64, 0x74, 0x68, 0x6f, 0x75, 0x73, 0x61, 0x6e, 0x64, 0x73, + 0x70, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x26, 0x68, 0x65, 0x6c, 0x6c, 0x69, + 0x70, 0x3b, 0x6e, 0x65, 0x77, 0x20, 0x44, 0x61, 0x74, 0x65, 0x22, 0x20, 0x73, + 0x69, 0x7a, 0x65, 0x3d, 0x22, 0x70, 0x61, 0x67, 0x65, 0x4e, 0x61, 0x6d, 0x65, + 0x6d, 0x69, 0x64, 0x64, 0x6c, 0x65, 0x22, 0x20, 0x22, 0x20, 0x2f, 0x3e, 0x3c, + 0x2f, 0x61, 0x3e, 0x68, 0x69, 0x64, 0x64, 0x65, 0x6e, 0x22, 0x3e, 0x73, 0x65, + 0x71, 0x75, 0x65, 0x6e, 0x63, 0x65, 0x70, 0x65, 0x72, 0x73, 0x6f, 0x6e, 0x61, + 0x6c, 0x6f, 0x76, 0x65, 0x72, 0x66, 0x6c, 0x6f, 0x77, 0x6f, 0x70, 0x69, 0x6e, + 0x69, 0x6f, 0x6e, 0x73, 0x69, 0x6c, 0x6c, 0x69, 0x6e, 0x6f, 0x69, 0x73, 0x6c, + 0x69, 0x6e, 0x6b, 0x73, 0x22, 0x3e, 0x0a, 0x09, 0x3c, 0x74, 0x69, 0x74, 0x6c, + 0x65, 0x3e, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x73, 0x61, 0x74, + 0x75, 0x72, 0x64, 0x61, 0x79, 0x74, 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x61, 0x6c, + 0x69, 0x74, 0x65, 0x6d, 0x70, 0x72, 0x6f, 0x70, 0x65, 0x6e, 0x67, 0x69, 0x6e, + 0x65, 0x65, 0x72, 0x73, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x64, 0x65, + 0x73, 0x69, 0x67, 0x6e, 0x65, 0x72, 0x70, 0x72, 0x6f, 0x70, 0x6f, 0x73, 0x61, + 0x6c, 0x3d, 0x22, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x22, 0x45, 0x73, 0x70, 0x61, + 0xc3, 0xb1, 0x6f, 0x6c, 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x73, 0x73, + 0x75, 0x62, 0x6d, 0x69, 0x74, 0x22, 0x20, 0x65, 0x72, 0x26, 0x71, 0x75, 0x6f, + 0x74, 0x3b, 0x61, 0x64, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x79, 0x6d, + 0x70, 0x74, 0x6f, 0x6d, 0x73, 0x6f, 0x72, 0x69, 0x65, 0x6e, 0x74, 0x65, 0x64, + 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x72, 0x69, 0x67, 0x68, 0x74, + 0x22, 0x3e, 0x3c, 0x70, 0x6c, 0x65, 0x61, 0x73, 0x75, 0x72, 0x65, 0x73, 0x74, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x68, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, + 0x2e, 0x6c, 0x65, 0x61, 0x76, 0x69, 0x6e, 0x67, 0x20, 0x20, 0x62, 0x6f, 0x72, + 0x64, 0x65, 0x72, 0x3d, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x73, 0x63, + 0x65, 0x6e, 0x74, 0x65, 0x72, 0x22, 0x3e, 0x2e, 0x0a, 0x0a, 0x53, 0x6f, 0x6d, + 0x65, 0x20, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x65, 0x64, 0x73, 0x75, 0x69, + 0x74, 0x61, 0x62, 0x6c, 0x65, 0x62, 0x75, 0x6c, 0x67, 0x61, 0x72, 0x69, 0x61, + 0x2e, 0x73, 0x68, 0x6f, 0x77, 0x28, 0x29, 0x3b, 0x64, 0x65, 0x73, 0x69, 0x67, + 0x6e, 0x65, 0x64, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x6c, 0x20, 0x63, 0x6f, + 0x6e, 0x63, 0x65, 0x70, 0x74, 0x73, 0x45, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, + 0x73, 0x77, 0x69, 0x6c, 0x6c, 0x69, 0x61, 0x6d, 0x73, 0x4f, 0x72, 0x69, 0x67, + 0x69, 0x6e, 0x61, 0x6c, 0x22, 0x3e, 0x3c, 0x73, 0x70, 0x61, 0x6e, 0x3e, 0x73, + 0x65, 0x61, 0x72, 0x63, 0x68, 0x22, 0x3e, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, + 0x6f, 0x72, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x73, 0x61, 0x20, 0x26, + 0x71, 0x75, 0x6f, 0x74, 0x3b, 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x69, 0x6e, 0x67, + 0x44, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x72, 0x65, 0x76, 0x69, 0x73, + 0x69, 0x6f, 0x6e, 0x2e, 0x20, 0x0a, 0x0a, 0x54, 0x68, 0x65, 0x20, 0x79, 0x6f, + 0x75, 0x72, 0x73, 0x65, 0x6c, 0x66, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x63, 0x74, + 0x20, 0x6d, 0x69, 0x63, 0x68, 0x69, 0x67, 0x61, 0x6e, 0x45, 0x6e, 0x67, 0x6c, + 0x69, 0x73, 0x68, 0x20, 0x63, 0x6f, 0x6c, 0x75, 0x6d, 0x62, 0x69, 0x61, 0x70, + 0x72, 0x69, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x69, + 0x6e, 0x67, 0x64, 0x72, 0x69, 0x6e, 0x6b, 0x69, 0x6e, 0x67, 0x66, 0x61, 0x63, + 0x69, 0x6c, 0x69, 0x74, 0x79, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x65, 0x64, + 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x20, 0x6f, 0x66, 0x66, 0x69, 0x63, + 0x65, 0x72, 0x73, 0x52, 0x75, 0x73, 0x73, 0x69, 0x61, 0x6e, 0x20, 0x67, 0x65, + 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x2d, 0x38, 0x38, 0x35, 0x39, 0x2d, 0x31, + 0x22, 0x69, 0x6e, 0x64, 0x69, 0x63, 0x61, 0x74, 0x65, 0x66, 0x61, 0x6d, 0x69, + 0x6c, 0x69, 0x61, 0x72, 0x20, 0x71, 0x75, 0x61, 0x6c, 0x69, 0x74, 0x79, 0x6d, + 0x61, 0x72, 0x67, 0x69, 0x6e, 0x3a, 0x30, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x65, + 0x6e, 0x74, 0x76, 0x69, 0x65, 0x77, 0x70, 0x6f, 0x72, 0x74, 0x63, 0x6f, 0x6e, + 0x74, 0x61, 0x63, 0x74, 0x73, 0x2d, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x22, 0x3e, + 0x70, 0x6f, 0x72, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x2e, 0x6c, 0x65, 0x6e, 0x67, + 0x74, 0x68, 0x20, 0x65, 0x6c, 0x69, 0x67, 0x69, 0x62, 0x6c, 0x65, 0x69, 0x6e, + 0x76, 0x6f, 0x6c, 0x76, 0x65, 0x73, 0x61, 0x74, 0x6c, 0x61, 0x6e, 0x74, 0x69, + 0x63, 0x6f, 0x6e, 0x6c, 0x6f, 0x61, 0x64, 0x3d, 0x22, 0x64, 0x65, 0x66, 0x61, + 0x75, 0x6c, 0x74, 0x2e, 0x73, 0x75, 0x70, 0x70, 0x6c, 0x69, 0x65, 0x64, 0x70, + 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x67, 0x6c, 0x6f, 0x73, 0x73, 0x61, + 0x72, 0x79, 0x0a, 0x0a, 0x41, 0x66, 0x74, 0x65, 0x72, 0x20, 0x67, 0x75, 0x69, + 0x64, 0x61, 0x6e, 0x63, 0x65, 0x3c, 0x2f, 0x74, 0x64, 0x3e, 0x3c, 0x74, 0x64, + 0x65, 0x6e, 0x63, 0x6f, 0x64, 0x69, 0x6e, 0x67, 0x6d, 0x69, 0x64, 0x64, 0x6c, + 0x65, 0x22, 0x3e, 0x63, 0x61, 0x6d, 0x65, 0x20, 0x74, 0x6f, 0x20, 0x64, 0x69, + 0x73, 0x70, 0x6c, 0x61, 0x79, 0x73, 0x73, 0x63, 0x6f, 0x74, 0x74, 0x69, 0x73, + 0x68, 0x6a, 0x6f, 0x6e, 0x61, 0x74, 0x68, 0x61, 0x6e, 0x6d, 0x61, 0x6a, 0x6f, + 0x72, 0x69, 0x74, 0x79, 0x77, 0x69, 0x64, 0x67, 0x65, 0x74, 0x73, 0x2e, 0x63, + 0x6c, 0x69, 0x6e, 0x69, 0x63, 0x61, 0x6c, 0x74, 0x68, 0x61, 0x69, 0x6c, 0x61, + 0x6e, 0x64, 0x74, 0x65, 0x61, 0x63, 0x68, 0x65, 0x72, 0x73, 0x3c, 0x68, 0x65, + 0x61, 0x64, 0x3e, 0x0a, 0x09, 0x61, 0x66, 0x66, 0x65, 0x63, 0x74, 0x65, 0x64, + 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x70, 0x6f, 0x69, 0x6e, 0x74, + 0x65, 0x72, 0x3b, 0x74, 0x6f, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x3c, 0x2f, + 0x73, 0x6d, 0x61, 0x6c, 0x6c, 0x3e, 0x6f, 0x6b, 0x6c, 0x61, 0x68, 0x6f, 0x6d, + 0x61, 0x77, 0x69, 0x6c, 0x6c, 0x20, 0x62, 0x65, 0x20, 0x69, 0x6e, 0x76, 0x65, + 0x73, 0x74, 0x6f, 0x72, 0x30, 0x22, 0x20, 0x61, 0x6c, 0x74, 0x3d, 0x22, 0x68, + 0x6f, 0x6c, 0x69, 0x64, 0x61, 0x79, 0x73, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, + 0x63, 0x65, 0x6c, 0x69, 0x63, 0x65, 0x6e, 0x73, 0x65, 0x64, 0x20, 0x28, 0x77, + 0x68, 0x69, 0x63, 0x68, 0x20, 0x2e, 0x20, 0x41, 0x66, 0x74, 0x65, 0x72, 0x20, + 0x63, 0x6f, 0x6e, 0x73, 0x69, 0x64, 0x65, 0x72, 0x76, 0x69, 0x73, 0x69, 0x74, + 0x69, 0x6e, 0x67, 0x65, 0x78, 0x70, 0x6c, 0x6f, 0x72, 0x65, 0x72, 0x70, 0x72, + 0x69, 0x6d, 0x61, 0x72, 0x79, 0x20, 0x73, 0x65, 0x61, 0x72, 0x63, 0x68, 0x22, + 0x20, 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x22, 0x71, 0x75, 0x69, 0x63, + 0x6b, 0x6c, 0x79, 0x20, 0x6d, 0x65, 0x65, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x65, + 0x73, 0x74, 0x69, 0x6d, 0x61, 0x74, 0x65, 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, + 0x6e, 0x20, 0x3b, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x23, 0x20, 0x68, 0x65, + 0x69, 0x67, 0x68, 0x74, 0x3d, 0x61, 0x70, 0x70, 0x72, 0x6f, 0x76, 0x61, 0x6c, + 0x2c, 0x20, 0x26, 0x71, 0x75, 0x6f, 0x74, 0x3b, 0x20, 0x63, 0x68, 0x65, 0x63, + 0x6b, 0x65, 0x64, 0x2e, 0x6d, 0x69, 0x6e, 0x2e, 0x6a, 0x73, 0x22, 0x6d, 0x61, + 0x67, 0x6e, 0x65, 0x74, 0x69, 0x63, 0x3e, 0x3c, 0x2f, 0x61, 0x3e, 0x3c, 0x2f, + 0x68, 0x66, 0x6f, 0x72, 0x65, 0x63, 0x61, 0x73, 0x74, 0x2e, 0x20, 0x57, 0x68, + 0x69, 0x6c, 0x65, 0x20, 0x74, 0x68, 0x75, 0x72, 0x73, 0x64, 0x61, 0x79, 0x64, + 0x76, 0x65, 0x72, 0x74, 0x69, 0x73, 0x65, 0x26, 0x65, 0x61, 0x63, 0x75, 0x74, + 0x65, 0x3b, 0x68, 0x61, 0x73, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x65, 0x76, 0x61, + 0x6c, 0x75, 0x61, 0x74, 0x65, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x69, 0x6e, 0x67, + 0x65, 0x78, 0x69, 0x73, 0x74, 0x69, 0x6e, 0x67, 0x70, 0x61, 0x74, 0x69, 0x65, + 0x6e, 0x74, 0x73, 0x20, 0x4f, 0x6e, 0x6c, 0x69, 0x6e, 0x65, 0x20, 0x63, 0x6f, + 0x6c, 0x6f, 0x72, 0x61, 0x64, 0x6f, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, + 0x22, 0x63, 0x61, 0x6d, 0x70, 0x62, 0x65, 0x6c, 0x6c, 0x3c, 0x21, 0x2d, 0x2d, + 0x20, 0x65, 0x6e, 0x64, 0x3c, 0x2f, 0x73, 0x70, 0x61, 0x6e, 0x3e, 0x3c, 0x3c, + 0x62, 0x72, 0x20, 0x2f, 0x3e, 0x0d, 0x0a, 0x5f, 0x70, 0x6f, 0x70, 0x75, 0x70, + 0x73, 0x7c, 0x73, 0x63, 0x69, 0x65, 0x6e, 0x63, 0x65, 0x73, 0x2c, 0x26, 0x71, + 0x75, 0x6f, 0x74, 0x3b, 0x20, 0x71, 0x75, 0x61, 0x6c, 0x69, 0x74, 0x79, 0x20, + 0x57, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x73, 0x20, 0x61, 0x73, 0x73, 0x69, 0x67, + 0x6e, 0x65, 0x64, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x3a, 0x20, 0x3c, 0x62, + 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x6c, 0x65, 0x26, 0x71, 0x75, 0x6f, 0x74, + 0x3b, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3d, 0x22, 0x20, 0x43, 0x6f, 0x6d, + 0x70, 0x61, 0x6e, 0x79, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x73, 0x3c, + 0x69, 0x66, 0x72, 0x61, 0x6d, 0x65, 0x20, 0x62, 0x65, 0x6c, 0x69, 0x65, 0x76, + 0x65, 0x73, 0x70, 0x72, 0x65, 0x73, 0x65, 0x6e, 0x74, 0x73, 0x6d, 0x61, 0x72, + 0x73, 0x68, 0x61, 0x6c, 0x6c, 0x70, 0x61, 0x72, 0x74, 0x20, 0x6f, 0x66, 0x20, + 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x6c, 0x79, 0x29, 0x2e, 0x0a, 0x0a, 0x54, + 0x68, 0x65, 0x20, 0x74, 0x61, 0x78, 0x6f, 0x6e, 0x6f, 0x6d, 0x79, 0x6d, 0x75, + 0x63, 0x68, 0x20, 0x6f, 0x66, 0x20, 0x3c, 0x2f, 0x73, 0x70, 0x61, 0x6e, 0x3e, + 0x0a, 0x22, 0x20, 0x64, 0x61, 0x74, 0x61, 0x2d, 0x73, 0x72, 0x74, 0x75, 0x67, + 0x75, 0xc3, 0xaa, 0x73, 0x73, 0x63, 0x72, 0x6f, 0x6c, 0x6c, 0x54, 0x6f, 0x20, + 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x3c, 0x68, 0x65, 0x61, 0x64, 0x3e, + 0x0d, 0x0a, 0x61, 0x74, 0x74, 0x6f, 0x72, 0x6e, 0x65, 0x79, 0x65, 0x6d, 0x70, + 0x68, 0x61, 0x73, 0x69, 0x73, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x6f, 0x72, 0x73, + 0x66, 0x61, 0x6e, 0x63, 0x79, 0x62, 0x6f, 0x78, 0x77, 0x6f, 0x72, 0x6c, 0x64, + 0x27, 0x73, 0x20, 0x77, 0x69, 0x6c, 0x64, 0x6c, 0x69, 0x66, 0x65, 0x63, 0x68, + 0x65, 0x63, 0x6b, 0x65, 0x64, 0x3d, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, + 0x73, 0x70, 0x72, 0x6f, 0x67, 0x72, 0x61, 0x6d, 0x6d, 0x70, 0x78, 0x3b, 0x66, + 0x6f, 0x6e, 0x74, 0x2d, 0x20, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x6a, + 0x6f, 0x75, 0x72, 0x6e, 0x61, 0x6c, 0x73, 0x62, 0x65, 0x6c, 0x69, 0x65, 0x76, + 0x65, 0x64, 0x76, 0x61, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x74, 0x68, 0x6f, + 0x6d, 0x70, 0x73, 0x6f, 0x6e, 0x6c, 0x69, 0x67, 0x68, 0x74, 0x69, 0x6e, 0x67, + 0x61, 0x6e, 0x64, 0x20, 0x74, 0x68, 0x65, 0x20, 0x73, 0x70, 0x65, 0x63, 0x69, + 0x61, 0x6c, 0x20, 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x3d, 0x30, 0x63, 0x68, + 0x65, 0x63, 0x6b, 0x69, 0x6e, 0x67, 0x3c, 0x2f, 0x74, 0x62, 0x6f, 0x64, 0x79, + 0x3e, 0x3c, 0x62, 0x75, 0x74, 0x74, 0x6f, 0x6e, 0x20, 0x43, 0x6f, 0x6d, 0x70, + 0x6c, 0x65, 0x74, 0x65, 0x63, 0x6c, 0x65, 0x61, 0x72, 0x66, 0x69, 0x78, 0x0a, + 0x3c, 0x68, 0x65, 0x61, 0x64, 0x3e, 0x0a, 0x61, 0x72, 0x74, 0x69, 0x63, 0x6c, + 0x65, 0x20, 0x3c, 0x73, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x66, 0x69, 0x6e, + 0x64, 0x69, 0x6e, 0x67, 0x73, 0x72, 0x6f, 0x6c, 0x65, 0x20, 0x69, 0x6e, 0x20, + 0x70, 0x6f, 0x70, 0x75, 0x6c, 0x61, 0x72, 0x20, 0x20, 0x4f, 0x63, 0x74, 0x6f, + 0x62, 0x65, 0x72, 0x77, 0x65, 0x62, 0x73, 0x69, 0x74, 0x65, 0x20, 0x65, 0x78, + 0x70, 0x6f, 0x73, 0x75, 0x72, 0x65, 0x75, 0x73, 0x65, 0x64, 0x20, 0x74, 0x6f, + 0x20, 0x20, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x6f, 0x70, 0x65, 0x72, + 0x61, 0x74, 0x65, 0x64, 0x63, 0x6c, 0x69, 0x63, 0x6b, 0x69, 0x6e, 0x67, 0x65, + 0x6e, 0x74, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, + 0x64, 0x73, 0x69, 0x6e, 0x66, 0x6f, 0x72, 0x6d, 0x65, 0x64, 0x20, 0x6e, 0x75, + 0x6d, 0x62, 0x65, 0x72, 0x73, 0x20, 0x20, 0x3c, 0x2f, 0x64, 0x69, 0x76, 0x3e, + 0x63, 0x72, 0x65, 0x61, 0x74, 0x69, 0x6e, 0x67, 0x6f, 0x6e, 0x53, 0x75, 0x62, + 0x6d, 0x69, 0x74, 0x6d, 0x61, 0x72, 0x79, 0x6c, 0x61, 0x6e, 0x64, 0x63, 0x6f, + 0x6c, 0x6c, 0x65, 0x67, 0x65, 0x73, 0x61, 0x6e, 0x61, 0x6c, 0x79, 0x74, 0x69, + 0x63, 0x6c, 0x69, 0x73, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x63, 0x6f, 0x6e, 0x74, + 0x61, 0x63, 0x74, 0x2e, 0x6c, 0x6f, 0x67, 0x67, 0x65, 0x64, 0x49, 0x6e, 0x61, + 0x64, 0x76, 0x69, 0x73, 0x6f, 0x72, 0x79, 0x73, 0x69, 0x62, 0x6c, 0x69, 0x6e, + 0x67, 0x73, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x22, 0x73, 0x26, 0x71, + 0x75, 0x6f, 0x74, 0x3b, 0x29, 0x73, 0x2e, 0x20, 0x54, 0x68, 0x69, 0x73, 0x20, + 0x70, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x73, 0x63, 0x68, 0x65, 0x63, 0x6b, + 0x62, 0x6f, 0x78, 0x73, 0x75, 0x67, 0x67, 0x65, 0x73, 0x74, 0x73, 0x70, 0x72, + 0x65, 0x67, 0x6e, 0x61, 0x6e, 0x74, 0x74, 0x6f, 0x6d, 0x6f, 0x72, 0x72, 0x6f, + 0x77, 0x73, 0x70, 0x61, 0x63, 0x69, 0x6e, 0x67, 0x3d, 0x69, 0x63, 0x6f, 0x6e, + 0x2e, 0x70, 0x6e, 0x67, 0x6a, 0x61, 0x70, 0x61, 0x6e, 0x65, 0x73, 0x65, 0x63, + 0x6f, 0x64, 0x65, 0x62, 0x61, 0x73, 0x65, 0x62, 0x75, 0x74, 0x74, 0x6f, 0x6e, + 0x22, 0x3e, 0x67, 0x61, 0x6d, 0x62, 0x6c, 0x69, 0x6e, 0x67, 0x73, 0x75, 0x63, + 0x68, 0x20, 0x61, 0x73, 0x20, 0x2c, 0x20, 0x77, 0x68, 0x69, 0x6c, 0x65, 0x20, + 0x3c, 0x2f, 0x73, 0x70, 0x61, 0x6e, 0x3e, 0x20, 0x6d, 0x69, 0x73, 0x73, 0x6f, + 0x75, 0x72, 0x69, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x69, 0x6e, 0x67, 0x74, 0x6f, + 0x70, 0x3a, 0x31, 0x70, 0x78, 0x20, 0x2e, 0x3c, 0x2f, 0x73, 0x70, 0x61, 0x6e, + 0x3e, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x77, 0x69, 0x64, 0x74, + 0x68, 0x3d, 0x22, 0x32, 0x6c, 0x61, 0x7a, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x6e, + 0x6f, 0x76, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x75, 0x73, 0x65, 0x64, 0x20, 0x69, + 0x6e, 0x20, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x3d, 0x22, 0x63, 0x72, 0x69, + 0x70, 0x74, 0x22, 0x3e, 0x0a, 0x26, 0x6e, 0x62, 0x73, 0x70, 0x3b, 0x3c, 0x2f, + 0x3c, 0x74, 0x72, 0x3e, 0x3c, 0x74, 0x64, 0x20, 0x68, 0x65, 0x69, 0x67, 0x68, + 0x74, 0x3a, 0x32, 0x2f, 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x63, 0x6f, + 0x75, 0x6e, 0x74, 0x72, 0x79, 0x20, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, + 0x20, 0x66, 0x6f, 0x6f, 0x74, 0x65, 0x72, 0x22, 0x20, 0x26, 0x6c, 0x74, 0x3b, + 0x21, 0x2d, 0x2d, 0x20, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x22, 0x3e, 0x3c, 0x2f, + 0x6a, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x3c, 0x2f, 0x66, 0x6f, 0x72, 0x6d, + 0x3e, 0x0a, 0x28, 0xe7, 0xae, 0x80, 0xe4, 0xbd, 0x93, 0x29, 0x28, 0xe7, 0xb9, + 0x81, 0xe9, 0xab, 0x94, 0x29, 0x68, 0x72, 0x76, 0x61, 0x74, 0x73, 0x6b, 0x69, + 0x69, 0x74, 0x61, 0x6c, 0x69, 0x61, 0x6e, 0x6f, 0x72, 0x6f, 0x6d, 0xc3, 0xa2, + 0x6e, 0xc4, 0x83, 0x74, 0xc3, 0xbc, 0x72, 0x6b, 0xc3, 0xa7, 0x65, 0xd8, 0xa7, + 0xd8, 0xb1, 0xd8, 0xaf, 0xd9, 0x88, 0x74, 0x61, 0x6d, 0x62, 0x69, 0xc3, 0xa9, + 0x6e, 0x6e, 0x6f, 0x74, 0x69, 0x63, 0x69, 0x61, 0x73, 0x6d, 0x65, 0x6e, 0x73, + 0x61, 0x6a, 0x65, 0x73, 0x70, 0x65, 0x72, 0x73, 0x6f, 0x6e, 0x61, 0x73, 0x64, + 0x65, 0x72, 0x65, 0x63, 0x68, 0x6f, 0x73, 0x6e, 0x61, 0x63, 0x69, 0x6f, 0x6e, + 0x61, 0x6c, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x69, 0x6f, 0x63, 0x6f, 0x6e, + 0x74, 0x61, 0x63, 0x74, 0x6f, 0x75, 0x73, 0x75, 0x61, 0x72, 0x69, 0x6f, 0x73, + 0x70, 0x72, 0x6f, 0x67, 0x72, 0x61, 0x6d, 0x61, 0x67, 0x6f, 0x62, 0x69, 0x65, + 0x72, 0x6e, 0x6f, 0x65, 0x6d, 0x70, 0x72, 0x65, 0x73, 0x61, 0x73, 0x61, 0x6e, + 0x75, 0x6e, 0x63, 0x69, 0x6f, 0x73, 0x76, 0x61, 0x6c, 0x65, 0x6e, 0x63, 0x69, + 0x61, 0x63, 0x6f, 0x6c, 0x6f, 0x6d, 0x62, 0x69, 0x61, 0x64, 0x65, 0x73, 0x70, + 0x75, 0xc3, 0xa9, 0x73, 0x64, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x73, 0x70, + 0x72, 0x6f, 0x79, 0x65, 0x63, 0x74, 0x6f, 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, + 0x74, 0x6f, 0x70, 0xc3, 0xba, 0x62, 0x6c, 0x69, 0x63, 0x6f, 0x6e, 0x6f, 0x73, + 0x6f, 0x74, 0x72, 0x6f, 0x73, 0x68, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x69, 0x61, + 0x70, 0x72, 0x65, 0x73, 0x65, 0x6e, 0x74, 0x65, 0x6d, 0x69, 0x6c, 0x6c, 0x6f, + 0x6e, 0x65, 0x73, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x6e, 0x74, 0x65, 0x70, 0x72, + 0x65, 0x67, 0x75, 0x6e, 0x74, 0x61, 0x61, 0x6e, 0x74, 0x65, 0x72, 0x69, 0x6f, + 0x72, 0x72, 0x65, 0x63, 0x75, 0x72, 0x73, 0x6f, 0x73, 0x70, 0x72, 0x6f, 0x62, + 0x6c, 0x65, 0x6d, 0x61, 0x73, 0x61, 0x6e, 0x74, 0x69, 0x61, 0x67, 0x6f, 0x6e, + 0x75, 0x65, 0x73, 0x74, 0x72, 0x6f, 0x73, 0x6f, 0x70, 0x69, 0x6e, 0x69, 0xc3, + 0xb3, 0x6e, 0x69, 0x6d, 0x70, 0x72, 0x69, 0x6d, 0x69, 0x72, 0x6d, 0x69, 0x65, + 0x6e, 0x74, 0x72, 0x61, 0x73, 0x61, 0x6d, 0xc3, 0xa9, 0x72, 0x69, 0x63, 0x61, + 0x76, 0x65, 0x6e, 0x64, 0x65, 0x64, 0x6f, 0x72, 0x73, 0x6f, 0x63, 0x69, 0x65, + 0x64, 0x61, 0x64, 0x72, 0x65, 0x73, 0x70, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x65, + 0x61, 0x6c, 0x69, 0x7a, 0x61, 0x72, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, + 0x6f, 0x70, 0x61, 0x6c, 0x61, 0x62, 0x72, 0x61, 0x73, 0x69, 0x6e, 0x74, 0x65, + 0x72, 0xc3, 0xa9, 0x73, 0x65, 0x6e, 0x74, 0x6f, 0x6e, 0x63, 0x65, 0x73, 0x65, + 0x73, 0x70, 0x65, 0x63, 0x69, 0x61, 0x6c, 0x6d, 0x69, 0x65, 0x6d, 0x62, 0x72, + 0x6f, 0x73, 0x72, 0x65, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x64, 0x63, 0xc3, 0xb3, + 0x72, 0x64, 0x6f, 0x62, 0x61, 0x7a, 0x61, 0x72, 0x61, 0x67, 0x6f, 0x7a, 0x61, + 0x70, 0xc3, 0xa1, 0x67, 0x69, 0x6e, 0x61, 0x73, 0x73, 0x6f, 0x63, 0x69, 0x61, + 0x6c, 0x65, 0x73, 0x62, 0x6c, 0x6f, 0x71, 0x75, 0x65, 0x61, 0x72, 0x67, 0x65, + 0x73, 0x74, 0x69, 0xc3, 0xb3, 0x6e, 0x61, 0x6c, 0x71, 0x75, 0x69, 0x6c, 0x65, + 0x72, 0x73, 0x69, 0x73, 0x74, 0x65, 0x6d, 0x61, 0x73, 0x63, 0x69, 0x65, 0x6e, + 0x63, 0x69, 0x61, 0x73, 0x63, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x6f, 0x76, + 0x65, 0x72, 0x73, 0x69, 0xc3, 0xb3, 0x6e, 0x63, 0x6f, 0x6d, 0x70, 0x6c, 0x65, + 0x74, 0x61, 0x65, 0x73, 0x74, 0x75, 0x64, 0x69, 0x6f, 0x73, 0x70, 0xc3, 0xba, + 0x62, 0x6c, 0x69, 0x63, 0x61, 0x6f, 0x62, 0x6a, 0x65, 0x74, 0x69, 0x76, 0x6f, + 0x61, 0x6c, 0x69, 0x63, 0x61, 0x6e, 0x74, 0x65, 0x62, 0x75, 0x73, 0x63, 0x61, + 0x64, 0x6f, 0x72, 0x63, 0x61, 0x6e, 0x74, 0x69, 0x64, 0x61, 0x64, 0x65, 0x6e, + 0x74, 0x72, 0x61, 0x64, 0x61, 0x73, 0x61, 0x63, 0x63, 0x69, 0x6f, 0x6e, 0x65, + 0x73, 0x61, 0x72, 0x63, 0x68, 0x69, 0x76, 0x6f, 0x73, 0x73, 0x75, 0x70, 0x65, + 0x72, 0x69, 0x6f, 0x72, 0x6d, 0x61, 0x79, 0x6f, 0x72, 0xc3, 0xad, 0x61, 0x61, + 0x6c, 0x65, 0x6d, 0x61, 0x6e, 0x69, 0x61, 0x66, 0x75, 0x6e, 0x63, 0x69, 0xc3, + 0xb3, 0x6e, 0xc3, 0xba, 0x6c, 0x74, 0x69, 0x6d, 0x6f, 0x73, 0x68, 0x61, 0x63, + 0x69, 0x65, 0x6e, 0x64, 0x6f, 0x61, 0x71, 0x75, 0x65, 0x6c, 0x6c, 0x6f, 0x73, + 0x65, 0x64, 0x69, 0x63, 0x69, 0xc3, 0xb3, 0x6e, 0x66, 0x65, 0x72, 0x6e, 0x61, + 0x6e, 0x64, 0x6f, 0x61, 0x6d, 0x62, 0x69, 0x65, 0x6e, 0x74, 0x65, 0x66, 0x61, + 0x63, 0x65, 0x62, 0x6f, 0x6f, 0x6b, 0x6e, 0x75, 0x65, 0x73, 0x74, 0x72, 0x61, + 0x73, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x65, 0x73, 0x70, 0x72, 0x6f, 0x63, + 0x65, 0x73, 0x6f, 0x73, 0x62, 0x61, 0x73, 0x74, 0x61, 0x6e, 0x74, 0x65, 0x70, + 0x72, 0x65, 0x73, 0x65, 0x6e, 0x74, 0x61, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, + 0x61, 0x72, 0x63, 0x6f, 0x6e, 0x67, 0x72, 0x65, 0x73, 0x6f, 0x70, 0x75, 0x62, + 0x6c, 0x69, 0x63, 0x61, 0x72, 0x63, 0x6f, 0x6d, 0x65, 0x72, 0x63, 0x69, 0x6f, + 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x74, 0x6f, 0x6a, 0xc3, 0xb3, 0x76, 0x65, + 0x6e, 0x65, 0x73, 0x64, 0x69, 0x73, 0x74, 0x72, 0x69, 0x74, 0x6f, 0x74, 0xc3, + 0xa9, 0x63, 0x6e, 0x69, 0x63, 0x61, 0x63, 0x6f, 0x6e, 0x6a, 0x75, 0x6e, 0x74, + 0x6f, 0x65, 0x6e, 0x65, 0x72, 0x67, 0xc3, 0xad, 0x61, 0x74, 0x72, 0x61, 0x62, + 0x61, 0x6a, 0x61, 0x72, 0x61, 0x73, 0x74, 0x75, 0x72, 0x69, 0x61, 0x73, 0x72, + 0x65, 0x63, 0x69, 0x65, 0x6e, 0x74, 0x65, 0x75, 0x74, 0x69, 0x6c, 0x69, 0x7a, + 0x61, 0x72, 0x62, 0x6f, 0x6c, 0x65, 0x74, 0xc3, 0xad, 0x6e, 0x73, 0x61, 0x6c, + 0x76, 0x61, 0x64, 0x6f, 0x72, 0x63, 0x6f, 0x72, 0x72, 0x65, 0x63, 0x74, 0x61, + 0x74, 0x72, 0x61, 0x62, 0x61, 0x6a, 0x6f, 0x73, 0x70, 0x72, 0x69, 0x6d, 0x65, + 0x72, 0x6f, 0x73, 0x6e, 0x65, 0x67, 0x6f, 0x63, 0x69, 0x6f, 0x73, 0x6c, 0x69, + 0x62, 0x65, 0x72, 0x74, 0x61, 0x64, 0x64, 0x65, 0x74, 0x61, 0x6c, 0x6c, 0x65, + 0x73, 0x70, 0x61, 0x6e, 0x74, 0x61, 0x6c, 0x6c, 0x61, 0x70, 0x72, 0xc3, 0xb3, + 0x78, 0x69, 0x6d, 0x6f, 0x61, 0x6c, 0x6d, 0x65, 0x72, 0xc3, 0xad, 0x61, 0x61, + 0x6e, 0x69, 0x6d, 0x61, 0x6c, 0x65, 0x73, 0x71, 0x75, 0x69, 0xc3, 0xa9, 0x6e, + 0x65, 0x73, 0x63, 0x6f, 0x72, 0x61, 0x7a, 0xc3, 0xb3, 0x6e, 0x73, 0x65, 0x63, + 0x63, 0x69, 0xc3, 0xb3, 0x6e, 0x62, 0x75, 0x73, 0x63, 0x61, 0x6e, 0x64, 0x6f, + 0x6f, 0x70, 0x63, 0x69, 0x6f, 0x6e, 0x65, 0x73, 0x65, 0x78, 0x74, 0x65, 0x72, + 0x69, 0x6f, 0x72, 0x63, 0x6f, 0x6e, 0x63, 0x65, 0x70, 0x74, 0x6f, 0x74, 0x6f, + 0x64, 0x61, 0x76, 0xc3, 0xad, 0x61, 0x67, 0x61, 0x6c, 0x65, 0x72, 0xc3, 0xad, + 0x61, 0x65, 0x73, 0x63, 0x72, 0x69, 0x62, 0x69, 0x72, 0x6d, 0x65, 0x64, 0x69, + 0x63, 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x63, 0x65, 0x6e, 0x63, 0x69, 0x61, 0x63, + 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x74, 0x61, 0x61, 0x73, 0x70, 0x65, 0x63, 0x74, + 0x6f, 0x73, 0x63, 0x72, 0xc3, 0xad, 0x74, 0x69, 0x63, 0x61, 0x64, 0xc3, 0xb3, + 0x6c, 0x61, 0x72, 0x65, 0x73, 0x6a, 0x75, 0x73, 0x74, 0x69, 0x63, 0x69, 0x61, + 0x64, 0x65, 0x62, 0x65, 0x72, 0xc3, 0xa1, 0x6e, 0x70, 0x65, 0x72, 0xc3, 0xad, + 0x6f, 0x64, 0x6f, 0x6e, 0x65, 0x63, 0x65, 0x73, 0x69, 0x74, 0x61, 0x6d, 0x61, + 0x6e, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x70, 0x65, 0x71, 0x75, 0x65, 0xc3, 0xb1, + 0x6f, 0x72, 0x65, 0x63, 0x69, 0x62, 0x69, 0x64, 0x61, 0x74, 0x72, 0x69, 0x62, + 0x75, 0x6e, 0x61, 0x6c, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x69, 0x66, 0x65, 0x63, + 0x61, 0x6e, 0x63, 0x69, 0xc3, 0xb3, 0x6e, 0x63, 0x61, 0x6e, 0x61, 0x72, 0x69, + 0x61, 0x73, 0x64, 0x65, 0x73, 0x63, 0x61, 0x72, 0x67, 0x61, 0x64, 0x69, 0x76, + 0x65, 0x72, 0x73, 0x6f, 0x73, 0x6d, 0x61, 0x6c, 0x6c, 0x6f, 0x72, 0x63, 0x61, + 0x72, 0x65, 0x71, 0x75, 0x69, 0x65, 0x72, 0x65, 0x74, 0xc3, 0xa9, 0x63, 0x6e, + 0x69, 0x63, 0x6f, 0x64, 0x65, 0x62, 0x65, 0x72, 0xc3, 0xad, 0x61, 0x76, 0x69, + 0x76, 0x69, 0x65, 0x6e, 0x64, 0x61, 0x66, 0x69, 0x6e, 0x61, 0x6e, 0x7a, 0x61, + 0x73, 0x61, 0x64, 0x65, 0x6c, 0x61, 0x6e, 0x74, 0x65, 0x66, 0x75, 0x6e, 0x63, + 0x69, 0x6f, 0x6e, 0x61, 0x63, 0x6f, 0x6e, 0x73, 0x65, 0x6a, 0x6f, 0x73, 0x64, + 0x69, 0x66, 0xc3, 0xad, 0x63, 0x69, 0x6c, 0x63, 0x69, 0x75, 0x64, 0x61, 0x64, + 0x65, 0x73, 0x61, 0x6e, 0x74, 0x69, 0x67, 0x75, 0x61, 0x73, 0x61, 0x76, 0x61, + 0x6e, 0x7a, 0x61, 0x64, 0x61, 0x74, 0xc3, 0xa9, 0x72, 0x6d, 0x69, 0x6e, 0x6f, + 0x75, 0x6e, 0x69, 0x64, 0x61, 0x64, 0x65, 0x73, 0x73, 0xc3, 0xa1, 0x6e, 0x63, + 0x68, 0x65, 0x7a, 0x63, 0x61, 0x6d, 0x70, 0x61, 0xc3, 0xb1, 0x61, 0x73, 0x6f, + 0x66, 0x74, 0x6f, 0x6e, 0x69, 0x63, 0x72, 0x65, 0x76, 0x69, 0x73, 0x74, 0x61, + 0x73, 0x63, 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x6e, 0x65, 0x73, 0x65, 0x63, 0x74, + 0x6f, 0x72, 0x65, 0x73, 0x6d, 0x6f, 0x6d, 0x65, 0x6e, 0x74, 0x6f, 0x73, 0x66, + 0x61, 0x63, 0x75, 0x6c, 0x74, 0x61, 0x64, 0x63, 0x72, 0xc3, 0xa9, 0x64, 0x69, + 0x74, 0x6f, 0x64, 0x69, 0x76, 0x65, 0x72, 0x73, 0x61, 0x73, 0x73, 0x75, 0x70, + 0x75, 0x65, 0x73, 0x74, 0x6f, 0x66, 0x61, 0x63, 0x74, 0x6f, 0x72, 0x65, 0x73, + 0x73, 0x65, 0x67, 0x75, 0x6e, 0x64, 0x6f, 0x73, 0x70, 0x65, 0x71, 0x75, 0x65, + 0xc3, 0xb1, 0x61, 0xd0, 0xb3, 0xd0, 0xbe, 0xd0, 0xb4, 0xd0, 0xb0, 0xd0, 0xb5, + 0xd1, 0x81, 0xd0, 0xbb, 0xd0, 0xb8, 0xd0, 0xb5, 0xd1, 0x81, 0xd1, 0x82, 0xd1, + 0x8c, 0xd0, 0xb1, 0xd1, 0x8b, 0xd0, 0xbb, 0xd0, 0xbe, 0xd0, 0xb1, 0xd1, 0x8b, + 0xd1, 0x82, 0xd1, 0x8c, 0xd1, 0x8d, 0xd1, 0x82, 0xd0, 0xbe, 0xd0, 0xbc, 0xd0, + 0x95, 0xd1, 0x81, 0xd0, 0xbb, 0xd0, 0xb8, 0xd1, 0x82, 0xd0, 0xbe, 0xd0, 0xb3, + 0xd0, 0xbe, 0xd0, 0xbc, 0xd0, 0xb5, 0xd0, 0xbd, 0xd1, 0x8f, 0xd0, 0xb2, 0xd1, + 0x81, 0xd0, 0xb5, 0xd1, 0x85, 0xd1, 0x8d, 0xd1, 0x82, 0xd0, 0xbe, 0xd0, 0xb9, + 0xd0, 0xb4, 0xd0, 0xb0, 0xd0, 0xb6, 0xd0, 0xb5, 0xd0, 0xb1, 0xd1, 0x8b, 0xd0, + 0xbb, 0xd0, 0xb8, 0xd0, 0xb3, 0xd0, 0xbe, 0xd0, 0xb4, 0xd1, 0x83, 0xd0, 0xb4, + 0xd0, 0xb5, 0xd0, 0xbd, 0xd1, 0x8c, 0xd1, 0x8d, 0xd1, 0x82, 0xd0, 0xbe, 0xd1, + 0x82, 0xd0, 0xb1, 0xd1, 0x8b, 0xd0, 0xbb, 0xd0, 0xb0, 0xd1, 0x81, 0xd0, 0xb5, + 0xd0, 0xb1, 0xd1, 0x8f, 0xd0, 0xbe, 0xd0, 0xb4, 0xd0, 0xb8, 0xd0, 0xbd, 0xd1, + 0x81, 0xd0, 0xb5, 0xd0, 0xb1, 0xd0, 0xb5, 0xd0, 0xbd, 0xd0, 0xb0, 0xd0, 0xb4, + 0xd0, 0xbe, 0xd1, 0x81, 0xd0, 0xb0, 0xd0, 0xb9, 0xd1, 0x82, 0xd1, 0x84, 0xd0, + 0xbe, 0xd1, 0x82, 0xd0, 0xbe, 0xd0, 0xbd, 0xd0, 0xb5, 0xd0, 0xb3, 0xd0, 0xbe, + 0xd1, 0x81, 0xd0, 0xb2, 0xd0, 0xbe, 0xd0, 0xb8, 0xd1, 0x81, 0xd0, 0xb2, 0xd0, + 0xbe, 0xd0, 0xb9, 0xd0, 0xb8, 0xd0, 0xb3, 0xd1, 0x80, 0xd1, 0x8b, 0xd1, 0x82, + 0xd0, 0xbe, 0xd0, 0xb6, 0xd0, 0xb5, 0xd0, 0xb2, 0xd1, 0x81, 0xd0, 0xb5, 0xd0, + 0xbc, 0xd1, 0x81, 0xd0, 0xb2, 0xd0, 0xbe, 0xd1, 0x8e, 0xd0, 0xbb, 0xd0, 0xb8, + 0xd1, 0x88, 0xd1, 0x8c, 0xd1, 0x8d, 0xd1, 0x82, 0xd0, 0xb8, 0xd1, 0x85, 0xd0, + 0xbf, 0xd0, 0xbe, 0xd0, 0xba, 0xd0, 0xb0, 0xd0, 0xb4, 0xd0, 0xbd, 0xd0, 0xb5, + 0xd0, 0xb9, 0xd0, 0xb4, 0xd0, 0xbe, 0xd0, 0xbc, 0xd0, 0xb0, 0xd0, 0xbc, 0xd0, + 0xb8, 0xd1, 0x80, 0xd0, 0xb0, 0xd0, 0xbb, 0xd0, 0xb8, 0xd0, 0xb1, 0xd0, 0xbe, + 0xd1, 0x82, 0xd0, 0xb5, 0xd0, 0xbc, 0xd1, 0x83, 0xd1, 0x85, 0xd0, 0xbe, 0xd1, + 0x82, 0xd1, 0x8f, 0xd0, 0xb4, 0xd0, 0xb2, 0xd1, 0x83, 0xd1, 0x85, 0xd1, 0x81, + 0xd0, 0xb5, 0xd1, 0x82, 0xd0, 0xb8, 0xd0, 0xbb, 0xd1, 0x8e, 0xd0, 0xb4, 0xd0, + 0xb8, 0xd0, 0xb4, 0xd0, 0xb5, 0xd0, 0xbb, 0xd0, 0xbe, 0xd0, 0xbc, 0xd0, 0xb8, + 0xd1, 0x80, 0xd0, 0xb5, 0xd1, 0x82, 0xd0, 0xb5, 0xd0, 0xb1, 0xd1, 0x8f, 0xd1, + 0x81, 0xd0, 0xb2, 0xd0, 0xbe, 0xd0, 0xb5, 0xd0, 0xb2, 0xd0, 0xb8, 0xd0, 0xb4, + 0xd0, 0xb5, 0xd1, 0x87, 0xd0, 0xb5, 0xd0, 0xb3, 0xd0, 0xbe, 0xd1, 0x8d, 0xd1, + 0x82, 0xd0, 0xb8, 0xd0, 0xbc, 0xd1, 0x81, 0xd1, 0x87, 0xd0, 0xb5, 0xd1, 0x82, + 0xd1, 0x82, 0xd0, 0xb5, 0xd0, 0xbc, 0xd1, 0x8b, 0xd1, 0x86, 0xd0, 0xb5, 0xd0, + 0xbd, 0xd1, 0x8b, 0xd1, 0x81, 0xd1, 0x82, 0xd0, 0xb0, 0xd0, 0xbb, 0xd0, 0xb2, + 0xd0, 0xb5, 0xd0, 0xb4, 0xd1, 0x8c, 0xd1, 0x82, 0xd0, 0xb5, 0xd0, 0xbc, 0xd0, + 0xb5, 0xd0, 0xb2, 0xd0, 0xbe, 0xd0, 0xb4, 0xd1, 0x8b, 0xd1, 0x82, 0xd0, 0xb5, + 0xd0, 0xb1, 0xd0, 0xb5, 0xd0, 0xb2, 0xd1, 0x8b, 0xd1, 0x88, 0xd0, 0xb5, 0xd0, + 0xbd, 0xd0, 0xb0, 0xd0, 0xbc, 0xd0, 0xb8, 0xd1, 0x82, 0xd0, 0xb8, 0xd0, 0xbf, + 0xd0, 0xb0, 0xd1, 0x82, 0xd0, 0xbe, 0xd0, 0xbc, 0xd1, 0x83, 0xd0, 0xbf, 0xd1, + 0x80, 0xd0, 0xb0, 0xd0, 0xb2, 0xd0, 0xbb, 0xd0, 0xb8, 0xd1, 0x86, 0xd0, 0xb0, + 0xd0, 0xbe, 0xd0, 0xb4, 0xd0, 0xbd, 0xd0, 0xb0, 0xd0, 0xb3, 0xd0, 0xbe, 0xd0, + 0xb4, 0xd1, 0x8b, 0xd0, 0xb7, 0xd0, 0xbd, 0xd0, 0xb0, 0xd1, 0x8e, 0xd0, 0xbc, + 0xd0, 0xbe, 0xd0, 0xb3, 0xd1, 0x83, 0xd0, 0xb4, 0xd1, 0x80, 0xd1, 0x83, 0xd0, + 0xb3, 0xd0, 0xb2, 0xd1, 0x81, 0xd0, 0xb5, 0xd0, 0xb9, 0xd0, 0xb8, 0xd0, 0xb4, + 0xd0, 0xb5, 0xd1, 0x82, 0xd0, 0xba, 0xd0, 0xb8, 0xd0, 0xbd, 0xd0, 0xbe, 0xd0, + 0xbe, 0xd0, 0xb4, 0xd0, 0xbd, 0xd0, 0xbe, 0xd0, 0xb4, 0xd0, 0xb5, 0xd0, 0xbb, + 0xd0, 0xb0, 0xd0, 0xb4, 0xd0, 0xb5, 0xd0, 0xbb, 0xd0, 0xb5, 0xd1, 0x81, 0xd1, + 0x80, 0xd0, 0xbe, 0xd0, 0xba, 0xd0, 0xb8, 0xd1, 0x8e, 0xd0, 0xbd, 0xd1, 0x8f, + 0xd0, 0xb2, 0xd0, 0xb5, 0xd1, 0x81, 0xd1, 0x8c, 0xd0, 0x95, 0xd1, 0x81, 0xd1, + 0x82, 0xd1, 0x8c, 0xd1, 0x80, 0xd0, 0xb0, 0xd0, 0xb7, 0xd0, 0xb0, 0xd0, 0xbd, + 0xd0, 0xb0, 0xd1, 0x88, 0xd0, 0xb8, 0xd8, 0xa7, 0xd9, 0x84, 0xd9, 0x84, 0xd9, + 0x87, 0xd8, 0xa7, 0xd9, 0x84, 0xd8, 0xaa, 0xd9, 0x8a, 0xd8, 0xac, 0xd9, 0x85, + 0xd9, 0x8a, 0xd8, 0xb9, 0xd8, 0xae, 0xd8, 0xa7, 0xd8, 0xb5, 0xd8, 0xa9, 0xd8, + 0xa7, 0xd9, 0x84, 0xd8, 0xb0, 0xd9, 0x8a, 0xd8, 0xb9, 0xd9, 0x84, 0xd9, 0x8a, + 0xd9, 0x87, 0xd8, 0xac, 0xd8, 0xaf, 0xd9, 0x8a, 0xd8, 0xaf, 0xd8, 0xa7, 0xd9, + 0x84, 0xd8, 0xa2, 0xd9, 0x86, 0xd8, 0xa7, 0xd9, 0x84, 0xd8, 0xb1, 0xd8, 0xaf, + 0xd8, 0xaa, 0xd8, 0xad, 0xd9, 0x83, 0xd9, 0x85, 0xd8, 0xb5, 0xd9, 0x81, 0xd8, + 0xad, 0xd8, 0xa9, 0xd9, 0x83, 0xd8, 0xa7, 0xd9, 0x86, 0xd8, 0xaa, 0xd8, 0xa7, + 0xd9, 0x84, 0xd9, 0x84, 0xd9, 0x8a, 0xd9, 0x8a, 0xd9, 0x83, 0xd9, 0x88, 0xd9, + 0x86, 0xd8, 0xb4, 0xd8, 0xa8, 0xd9, 0x83, 0xd8, 0xa9, 0xd9, 0x81, 0xd9, 0x8a, + 0xd9, 0x87, 0xd8, 0xa7, 0xd8, 0xa8, 0xd9, 0x86, 0xd8, 0xa7, 0xd8, 0xaa, 0xd8, + 0xad, 0xd9, 0x88, 0xd8, 0xa7, 0xd8, 0xa1, 0xd8, 0xa3, 0xd9, 0x83, 0xd8, 0xab, + 0xd8, 0xb1, 0xd8, 0xae, 0xd9, 0x84, 0xd8, 0xa7, 0xd9, 0x84, 0xd8, 0xa7, 0xd9, + 0x84, 0xd8, 0xad, 0xd8, 0xa8, 0xd8, 0xaf, 0xd9, 0x84, 0xd9, 0x8a, 0xd9, 0x84, + 0xd8, 0xaf, 0xd8, 0xb1, 0xd9, 0x88, 0xd8, 0xb3, 0xd8, 0xa7, 0xd8, 0xb6, 0xd8, + 0xba, 0xd8, 0xb7, 0xd8, 0xaa, 0xd9, 0x83, 0xd9, 0x88, 0xd9, 0x86, 0xd9, 0x87, + 0xd9, 0x86, 0xd8, 0xa7, 0xd9, 0x83, 0xd8, 0xb3, 0xd8, 0xa7, 0xd8, 0xad, 0xd8, + 0xa9, 0xd9, 0x86, 0xd8, 0xa7, 0xd8, 0xaf, 0xd9, 0x8a, 0xd8, 0xa7, 0xd9, 0x84, + 0xd8, 0xb7, 0xd8, 0xa8, 0xd8, 0xb9, 0xd9, 0x84, 0xd9, 0x8a, 0xd9, 0x83, 0xd8, + 0xb4, 0xd9, 0x83, 0xd8, 0xb1, 0xd8, 0xa7, 0xd9, 0x8a, 0xd9, 0x85, 0xd9, 0x83, + 0xd9, 0x86, 0xd9, 0x85, 0xd9, 0x86, 0xd9, 0x87, 0xd8, 0xa7, 0xd8, 0xb4, 0xd8, + 0xb1, 0xd9, 0x83, 0xd8, 0xa9, 0xd8, 0xb1, 0xd8, 0xa6, 0xd9, 0x8a, 0xd8, 0xb3, + 0xd9, 0x86, 0xd8, 0xb4, 0xd9, 0x8a, 0xd8, 0xb7, 0xd9, 0x85, 0xd8, 0xa7, 0xd8, + 0xb0, 0xd8, 0xa7, 0xd8, 0xa7, 0xd9, 0x84, 0xd9, 0x81, 0xd9, 0x86, 0xd8, 0xb4, + 0xd8, 0xa8, 0xd8, 0xa7, 0xd8, 0xa8, 0xd8, 0xaa, 0xd8, 0xb9, 0xd8, 0xa8, 0xd8, + 0xb1, 0xd8, 0xb1, 0xd8, 0xad, 0xd9, 0x85, 0xd8, 0xa9, 0xd9, 0x83, 0xd8, 0xa7, + 0xd9, 0x81, 0xd8, 0xa9, 0xd9, 0x8a, 0xd9, 0x82, 0xd9, 0x88, 0xd9, 0x84, 0xd9, + 0x85, 0xd8, 0xb1, 0xd9, 0x83, 0xd8, 0xb2, 0xd9, 0x83, 0xd9, 0x84, 0xd9, 0x85, + 0xd8, 0xa9, 0xd8, 0xa3, 0xd8, 0xad, 0xd9, 0x85, 0xd8, 0xaf, 0xd9, 0x82, 0xd9, + 0x84, 0xd8, 0xa8, 0xd9, 0x8a, 0xd9, 0x8a, 0xd8, 0xb9, 0xd9, 0x86, 0xd9, 0x8a, + 0xd8, 0xb5, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xa9, 0xd8, 0xb7, 0xd8, 0xb1, 0xd9, + 0x8a, 0xd9, 0x82, 0xd8, 0xb4, 0xd8, 0xa7, 0xd8, 0xb1, 0xd9, 0x83, 0xd8, 0xac, + 0xd9, 0x88, 0xd8, 0xa7, 0xd9, 0x84, 0xd8, 0xa3, 0xd8, 0xae, 0xd8, 0xb1, 0xd9, + 0x89, 0xd9, 0x85, 0xd8, 0xb9, 0xd9, 0x86, 0xd8, 0xa7, 0xd8, 0xa7, 0xd8, 0xa8, + 0xd8, 0xad, 0xd8, 0xab, 0xd8, 0xb9, 0xd8, 0xb1, 0xd9, 0x88, 0xd8, 0xb6, 0xd8, + 0xa8, 0xd8, 0xb4, 0xd9, 0x83, 0xd9, 0x84, 0xd9, 0x85, 0xd8, 0xb3, 0xd8, 0xac, + 0xd9, 0x84, 0xd8, 0xa8, 0xd9, 0x86, 0xd8, 0xa7, 0xd9, 0x86, 0xd8, 0xae, 0xd8, + 0xa7, 0xd9, 0x84, 0xd8, 0xaf, 0xd9, 0x83, 0xd8, 0xaa, 0xd8, 0xa7, 0xd8, 0xa8, + 0xd9, 0x83, 0xd9, 0x84, 0xd9, 0x8a, 0xd8, 0xa9, 0xd8, 0xa8, 0xd8, 0xaf, 0xd9, + 0x88, 0xd9, 0x86, 0xd8, 0xa3, 0xd9, 0x8a, 0xd8, 0xb6, 0xd8, 0xa7, 0xd9, 0x8a, + 0xd9, 0x88, 0xd8, 0xac, 0xd8, 0xaf, 0xd9, 0x81, 0xd8, 0xb1, 0xd9, 0x8a, 0xd9, + 0x82, 0xd9, 0x83, 0xd8, 0xaa, 0xd8, 0xa8, 0xd8, 0xaa, 0xd8, 0xa3, 0xd9, 0x81, + 0xd8, 0xb6, 0xd9, 0x84, 0xd9, 0x85, 0xd8, 0xb7, 0xd8, 0xa8, 0xd8, 0xae, 0xd8, + 0xa7, 0xd9, 0x83, 0xd8, 0xab, 0xd8, 0xb1, 0xd8, 0xa8, 0xd8, 0xa7, 0xd8, 0xb1, + 0xd9, 0x83, 0xd8, 0xa7, 0xd9, 0x81, 0xd8, 0xb6, 0xd9, 0x84, 0xd8, 0xa7, 0xd8, + 0xad, 0xd9, 0x84, 0xd9, 0x89, 0xd9, 0x86, 0xd9, 0x81, 0xd8, 0xb3, 0xd9, 0x87, + 0xd8, 0xa3, 0xd9, 0x8a, 0xd8, 0xa7, 0xd9, 0x85, 0xd8, 0xb1, 0xd8, 0xaf, 0xd9, + 0x88, 0xd8, 0xaf, 0xd8, 0xa3, 0xd9, 0x86, 0xd9, 0x87, 0xd8, 0xa7, 0xd8, 0xaf, + 0xd9, 0x8a, 0xd9, 0x86, 0xd8, 0xa7, 0xd8, 0xa7, 0xd9, 0x84, 0xd8, 0xa7, 0xd9, + 0x86, 0xd9, 0x85, 0xd8, 0xb9, 0xd8, 0xb1, 0xd8, 0xb6, 0xd8, 0xaa, 0xd8, 0xb9, + 0xd9, 0x84, 0xd9, 0x85, 0xd8, 0xaf, 0xd8, 0xa7, 0xd8, 0xae, 0xd9, 0x84, 0xd9, + 0x85, 0xd9, 0x85, 0xd9, 0x83, 0xd9, 0x86, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x07, 0x06, 0x05, 0x04, 0x03, + 0x02, 0x01, 0x00, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x0f, 0x0e, + 0x0d, 0x0c, 0x0b, 0x0a, 0x09, 0x08, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, + 0x17, 0x17, 0x16, 0x15, 0x14, 0x13, 0x12, 0x11, 0x10, 0x18, 0x19, 0x1a, 0x1b, + 0x1c, 0x1d, 0x1e, 0x1f, 0x1f, 0x1e, 0x1d, 0x1c, 0x1b, 0x1a, 0x19, 0x18, 0xff, + 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, + 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, + 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0xff, 0xff, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0xff, 0xff, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x00, + 0x00, 0x01, 0x00, 0x02, 0x00, 0x03, 0x00, 0x04, 0x00, 0x05, 0x00, 0x06, 0x00, + 0x07, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x63, 0x6f, 0x75, + 0x6e, 0x74, 0x72, 0x69, 0x65, 0x73, 0x71, 0x75, 0x65, 0x73, 0x74, 0x69, 0x6f, + 0x6e, 0x73, 0x65, 0x71, 0x75, 0x69, 0x70, 0x6d, 0x65, 0x6e, 0x74, 0x63, 0x6f, + 0x6d, 0x6d, 0x75, 0x6e, 0x69, 0x74, 0x79, 0x61, 0x76, 0x61, 0x69, 0x6c, 0x61, + 0x62, 0x6c, 0x65, 0x68, 0x69, 0x67, 0x68, 0x6c, 0x69, 0x67, 0x68, 0x74, 0x44, + 0x54, 0x44, 0x2f, 0x78, 0x68, 0x74, 0x6d, 0x6c, 0x6d, 0x61, 0x72, 0x6b, 0x65, + 0x74, 0x69, 0x6e, 0x67, 0x6b, 0x6e, 0x6f, 0x77, 0x6c, 0x65, 0x64, 0x67, 0x65, + 0x73, 0x6f, 0x6d, 0x65, 0x74, 0x68, 0x69, 0x6e, 0x67, 0x63, 0x6f, 0x6e, 0x74, + 0x61, 0x69, 0x6e, 0x65, 0x72, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x73, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x61, 0x64, 0x76, + 0x65, 0x72, 0x74, 0x69, 0x73, 0x65, 0x63, 0x68, 0x61, 0x72, 0x61, 0x63, 0x74, + 0x65, 0x72, 0x22, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3d, 0x22, 0x3c, 0x2f, + 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x3e, 0x41, 0x75, 0x73, 0x74, 0x72, 0x61, + 0x6c, 0x69, 0x61, 0x22, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x22, 0x73, + 0x69, 0x74, 0x75, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x75, 0x74, 0x68, 0x6f, + 0x72, 0x69, 0x74, 0x79, 0x66, 0x6f, 0x6c, 0x6c, 0x6f, 0x77, 0x69, 0x6e, 0x67, + 0x70, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x69, 0x6c, 0x79, 0x6f, 0x70, 0x65, 0x72, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x63, 0x68, 0x61, 0x6c, 0x6c, 0x65, 0x6e, 0x67, + 0x65, 0x64, 0x65, 0x76, 0x65, 0x6c, 0x6f, 0x70, 0x65, 0x64, 0x61, 0x6e, 0x6f, + 0x6e, 0x79, 0x6d, 0x6f, 0x75, 0x73, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x63, 0x6f, + 0x6d, 0x70, 0x61, 0x6e, 0x69, 0x65, 0x73, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, + 0x75, 0x72, 0x65, 0x61, 0x67, 0x72, 0x65, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x22, + 0x20, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x3d, 0x22, 0x70, 0x6f, 0x74, 0x65, 0x6e, + 0x74, 0x69, 0x61, 0x6c, 0x65, 0x64, 0x75, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x61, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x73, 0x65, 0x63, 0x6f, + 0x6e, 0x64, 0x61, 0x72, 0x79, 0x63, 0x6f, 0x70, 0x79, 0x72, 0x69, 0x67, 0x68, + 0x74, 0x6c, 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, 0x73, 0x65, 0x78, 0x63, + 0x6c, 0x75, 0x73, 0x69, 0x76, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, + 0x6f, 0x6e, 0x3c, 0x2f, 0x66, 0x6f, 0x72, 0x6d, 0x3e, 0x0d, 0x0a, 0x73, 0x74, + 0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x61, 0x74, 0x74, 0x65, 0x6e, 0x74, + 0x69, 0x6f, 0x6e, 0x42, 0x69, 0x6f, 0x67, 0x72, 0x61, 0x70, 0x68, 0x79, 0x7d, + 0x20, 0x65, 0x6c, 0x73, 0x65, 0x20, 0x7b, 0x0a, 0x73, 0x6f, 0x6c, 0x75, 0x74, + 0x69, 0x6f, 0x6e, 0x73, 0x77, 0x68, 0x65, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, + 0x41, 0x6e, 0x61, 0x6c, 0x79, 0x74, 0x69, 0x63, 0x73, 0x74, 0x65, 0x6d, 0x70, + 0x6c, 0x61, 0x74, 0x65, 0x73, 0x64, 0x61, 0x6e, 0x67, 0x65, 0x72, 0x6f, 0x75, + 0x73, 0x73, 0x61, 0x74, 0x65, 0x6c, 0x6c, 0x69, 0x74, 0x65, 0x64, 0x6f, 0x63, + 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68, + 0x65, 0x72, 0x69, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x61, 0x6e, 0x74, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x74, 0x79, 0x70, 0x65, 0x69, 0x6e, 0x66, 0x6c, 0x75, 0x65, + 0x6e, 0x63, 0x65, 0x26, 0x72, 0x61, 0x71, 0x75, 0x6f, 0x3b, 0x3c, 0x2f, 0x65, + 0x66, 0x66, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x67, 0x65, 0x6e, 0x65, 0x72, + 0x61, 0x6c, 0x6c, 0x79, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x6f, 0x72, 0x6d, + 0x62, 0x65, 0x61, 0x75, 0x74, 0x69, 0x66, 0x75, 0x6c, 0x74, 0x72, 0x61, 0x6e, + 0x73, 0x70, 0x6f, 0x72, 0x74, 0x6f, 0x72, 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x65, + 0x64, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x65, 0x64, 0x70, 0x72, 0x6f, + 0x6d, 0x69, 0x6e, 0x65, 0x6e, 0x74, 0x75, 0x6e, 0x74, 0x69, 0x6c, 0x20, 0x74, + 0x68, 0x65, 0x74, 0x68, 0x75, 0x6d, 0x62, 0x6e, 0x61, 0x69, 0x6c, 0x4e, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x20, 0x2e, 0x66, 0x6f, 0x63, 0x75, 0x73, + 0x28, 0x29, 0x3b, 0x6f, 0x76, 0x65, 0x72, 0x20, 0x74, 0x68, 0x65, 0x20, 0x6d, + 0x69, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6e, 0x6e, 0x6f, 0x75, + 0x6e, 0x63, 0x65, 0x64, 0x66, 0x6f, 0x6f, 0x74, 0x65, 0x72, 0x22, 0x3e, 0x0a, + 0x65, 0x78, 0x63, 0x65, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x6c, 0x65, 0x73, 0x73, + 0x20, 0x74, 0x68, 0x61, 0x6e, 0x65, 0x78, 0x70, 0x65, 0x6e, 0x73, 0x69, 0x76, + 0x65, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x66, 0x72, 0x61, + 0x6d, 0x65, 0x77, 0x6f, 0x72, 0x6b, 0x74, 0x65, 0x72, 0x72, 0x69, 0x74, 0x6f, + 0x72, 0x79, 0x6e, 0x64, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x63, 0x75, + 0x72, 0x72, 0x65, 0x6e, 0x74, 0x6c, 0x79, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x4e, + 0x61, 0x6d, 0x65, 0x63, 0x72, 0x69, 0x74, 0x69, 0x63, 0x69, 0x73, 0x6d, 0x74, + 0x72, 0x61, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x65, 0x6c, 0x73, 0x65, 0x77, + 0x68, 0x65, 0x72, 0x65, 0x41, 0x6c, 0x65, 0x78, 0x61, 0x6e, 0x64, 0x65, 0x72, + 0x61, 0x70, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x65, 0x64, 0x6d, 0x61, 0x74, 0x65, + 0x72, 0x69, 0x61, 0x6c, 0x73, 0x62, 0x72, 0x6f, 0x61, 0x64, 0x63, 0x61, 0x73, + 0x74, 0x6d, 0x65, 0x6e, 0x74, 0x69, 0x6f, 0x6e, 0x65, 0x64, 0x61, 0x66, 0x66, + 0x69, 0x6c, 0x69, 0x61, 0x74, 0x65, 0x3c, 0x2f, 0x6f, 0x70, 0x74, 0x69, 0x6f, + 0x6e, 0x3e, 0x74, 0x72, 0x65, 0x61, 0x74, 0x6d, 0x65, 0x6e, 0x74, 0x64, 0x69, + 0x66, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x74, 0x2f, 0x64, 0x65, 0x66, 0x61, 0x75, + 0x6c, 0x74, 0x2e, 0x50, 0x72, 0x65, 0x73, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x6f, + 0x6e, 0x63, 0x6c, 0x69, 0x63, 0x6b, 0x3d, 0x22, 0x62, 0x69, 0x6f, 0x67, 0x72, + 0x61, 0x70, 0x68, 0x79, 0x6f, 0x74, 0x68, 0x65, 0x72, 0x77, 0x69, 0x73, 0x65, + 0x70, 0x65, 0x72, 0x6d, 0x61, 0x6e, 0x65, 0x6e, 0x74, 0x46, 0x72, 0x61, 0x6e, + 0xc3, 0xa7, 0x61, 0x69, 0x73, 0x48, 0x6f, 0x6c, 0x6c, 0x79, 0x77, 0x6f, 0x6f, + 0x64, 0x65, 0x78, 0x70, 0x61, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x74, 0x61, + 0x6e, 0x64, 0x61, 0x72, 0x64, 0x73, 0x3c, 0x2f, 0x73, 0x74, 0x79, 0x6c, 0x65, + 0x3e, 0x0a, 0x72, 0x65, 0x64, 0x75, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x44, 0x65, + 0x63, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x20, 0x70, 0x72, 0x65, 0x66, 0x65, 0x72, + 0x72, 0x65, 0x64, 0x43, 0x61, 0x6d, 0x62, 0x72, 0x69, 0x64, 0x67, 0x65, 0x6f, + 0x70, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x73, 0x42, 0x75, 0x73, 0x69, 0x6e, + 0x65, 0x73, 0x73, 0x20, 0x63, 0x6f, 0x6e, 0x66, 0x75, 0x73, 0x69, 0x6f, 0x6e, + 0x3e, 0x0a, 0x3c, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x3e, 0x70, 0x72, 0x65, 0x73, + 0x65, 0x6e, 0x74, 0x65, 0x64, 0x65, 0x78, 0x70, 0x6c, 0x61, 0x69, 0x6e, 0x65, + 0x64, 0x64, 0x6f, 0x65, 0x73, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x77, 0x6f, 0x72, + 0x6c, 0x64, 0x77, 0x69, 0x64, 0x65, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, + 0x63, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x6e, 0x65, + 0x77, 0x73, 0x70, 0x61, 0x70, 0x65, 0x72, 0x3c, 0x2f, 0x74, 0x61, 0x62, 0x6c, + 0x65, 0x3e, 0x0a, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x73, 0x6c, + 0x69, 0x6b, 0x65, 0x20, 0x74, 0x68, 0x65, 0x20, 0x65, 0x73, 0x73, 0x65, 0x6e, + 0x74, 0x69, 0x61, 0x6c, 0x66, 0x69, 0x6e, 0x61, 0x6e, 0x63, 0x69, 0x61, 0x6c, + 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x3d, 0x22, 0x2f, 0x61, 0x62, 0x61, 0x6e, 0x64, 0x6f, 0x6e, 0x65, + 0x64, 0x45, 0x64, 0x75, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x70, 0x61, 0x72, + 0x73, 0x65, 0x49, 0x6e, 0x74, 0x28, 0x73, 0x74, 0x61, 0x62, 0x69, 0x6c, 0x69, + 0x74, 0x79, 0x75, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x20, 0x74, 0x6f, 0x3c, 0x2f, + 0x74, 0x69, 0x74, 0x6c, 0x65, 0x3e, 0x0a, 0x72, 0x65, 0x6c, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x73, 0x4e, 0x6f, 0x74, 0x65, 0x20, 0x74, 0x68, 0x61, 0x74, 0x65, + 0x66, 0x66, 0x69, 0x63, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x65, 0x72, 0x66, 0x6f, + 0x72, 0x6d, 0x65, 0x64, 0x74, 0x77, 0x6f, 0x20, 0x79, 0x65, 0x61, 0x72, 0x73, + 0x53, 0x69, 0x6e, 0x63, 0x65, 0x20, 0x74, 0x68, 0x65, 0x74, 0x68, 0x65, 0x72, + 0x65, 0x66, 0x6f, 0x72, 0x65, 0x77, 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, 0x22, + 0x3e, 0x61, 0x6c, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x74, 0x65, 0x69, 0x6e, 0x63, + 0x72, 0x65, 0x61, 0x73, 0x65, 0x64, 0x42, 0x61, 0x74, 0x74, 0x6c, 0x65, 0x20, + 0x6f, 0x66, 0x70, 0x65, 0x72, 0x63, 0x65, 0x69, 0x76, 0x65, 0x64, 0x74, 0x72, + 0x79, 0x69, 0x6e, 0x67, 0x20, 0x74, 0x6f, 0x6e, 0x65, 0x63, 0x65, 0x73, 0x73, + 0x61, 0x72, 0x79, 0x70, 0x6f, 0x72, 0x74, 0x72, 0x61, 0x79, 0x65, 0x64, 0x65, + 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x45, 0x6c, 0x69, 0x7a, 0x61, + 0x62, 0x65, 0x74, 0x68, 0x3c, 0x2f, 0x69, 0x66, 0x72, 0x61, 0x6d, 0x65, 0x3e, + 0x64, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x79, 0x69, 0x6e, 0x73, 0x75, + 0x72, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, + 0x3b, 0x6c, 0x65, 0x67, 0x65, 0x6e, 0x64, 0x61, 0x72, 0x79, 0x47, 0x65, 0x6f, + 0x67, 0x72, 0x61, 0x70, 0x68, 0x79, 0x63, 0x61, 0x6e, 0x64, 0x69, 0x64, 0x61, + 0x74, 0x65, 0x63, 0x6f, 0x72, 0x70, 0x6f, 0x72, 0x61, 0x74, 0x65, 0x73, 0x6f, + 0x6d, 0x65, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, + 0x65, 0x73, 0x2e, 0x69, 0x6e, 0x68, 0x65, 0x72, 0x69, 0x74, 0x65, 0x64, 0x3c, + 0x2f, 0x73, 0x74, 0x72, 0x6f, 0x6e, 0x67, 0x3e, 0x43, 0x6f, 0x6d, 0x6d, 0x75, + 0x6e, 0x69, 0x74, 0x79, 0x72, 0x65, 0x6c, 0x69, 0x67, 0x69, 0x6f, 0x75, 0x73, + 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x43, 0x6f, 0x6d, 0x6d, + 0x69, 0x74, 0x74, 0x65, 0x65, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x69, 0x6e, 0x67, + 0x73, 0x74, 0x68, 0x65, 0x20, 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x6e, 0x6f, 0x20, + 0x6c, 0x6f, 0x6e, 0x67, 0x65, 0x72, 0x62, 0x65, 0x67, 0x69, 0x6e, 0x6e, 0x69, + 0x6e, 0x67, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x63, 0x61, + 0x6e, 0x6e, 0x6f, 0x74, 0x20, 0x62, 0x65, 0x66, 0x72, 0x65, 0x71, 0x75, 0x65, + 0x6e, 0x63, 0x79, 0x74, 0x79, 0x70, 0x69, 0x63, 0x61, 0x6c, 0x6c, 0x79, 0x69, + 0x6e, 0x74, 0x6f, 0x20, 0x74, 0x68, 0x65, 0x20, 0x72, 0x65, 0x6c, 0x61, 0x74, + 0x69, 0x76, 0x65, 0x3b, 0x72, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x67, + 0x70, 0x72, 0x65, 0x73, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x6e, 0x69, 0x74, + 0x69, 0x61, 0x6c, 0x6c, 0x79, 0x74, 0x65, 0x63, 0x68, 0x6e, 0x69, 0x71, 0x75, + 0x65, 0x74, 0x68, 0x65, 0x20, 0x6f, 0x74, 0x68, 0x65, 0x72, 0x69, 0x74, 0x20, + 0x63, 0x61, 0x6e, 0x20, 0x62, 0x65, 0x65, 0x78, 0x69, 0x73, 0x74, 0x65, 0x6e, + 0x63, 0x65, 0x75, 0x6e, 0x64, 0x65, 0x72, 0x6c, 0x69, 0x6e, 0x65, 0x74, 0x68, + 0x69, 0x73, 0x20, 0x74, 0x69, 0x6d, 0x65, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x68, + 0x6f, 0x6e, 0x65, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x63, 0x6f, 0x70, 0x65, 0x70, + 0x72, 0x61, 0x63, 0x74, 0x69, 0x63, 0x65, 0x73, 0x61, 0x64, 0x76, 0x61, 0x6e, + 0x74, 0x61, 0x67, 0x65, 0x29, 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, + 0x46, 0x6f, 0x72, 0x20, 0x6f, 0x74, 0x68, 0x65, 0x72, 0x70, 0x72, 0x6f, 0x76, + 0x69, 0x64, 0x69, 0x6e, 0x67, 0x64, 0x65, 0x6d, 0x6f, 0x63, 0x72, 0x61, 0x63, + 0x79, 0x62, 0x6f, 0x74, 0x68, 0x20, 0x74, 0x68, 0x65, 0x20, 0x65, 0x78, 0x74, + 0x65, 0x6e, 0x73, 0x69, 0x76, 0x65, 0x73, 0x75, 0x66, 0x66, 0x65, 0x72, 0x69, + 0x6e, 0x67, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x63, 0x6f, + 0x6d, 0x70, 0x75, 0x74, 0x65, 0x72, 0x73, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x70, 0x72, 0x61, 0x63, 0x74, 0x69, 0x63, 0x61, 0x6c, 0x73, + 0x61, 0x69, 0x64, 0x20, 0x74, 0x68, 0x61, 0x74, 0x69, 0x74, 0x20, 0x6d, 0x61, + 0x79, 0x20, 0x62, 0x65, 0x45, 0x6e, 0x67, 0x6c, 0x69, 0x73, 0x68, 0x3c, 0x2f, + 0x66, 0x72, 0x6f, 0x6d, 0x20, 0x74, 0x68, 0x65, 0x20, 0x73, 0x63, 0x68, 0x65, + 0x64, 0x75, 0x6c, 0x65, 0x64, 0x64, 0x6f, 0x77, 0x6e, 0x6c, 0x6f, 0x61, 0x64, + 0x73, 0x3c, 0x2f, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x3e, 0x0a, 0x73, 0x75, 0x73, + 0x70, 0x65, 0x63, 0x74, 0x65, 0x64, 0x6d, 0x61, 0x72, 0x67, 0x69, 0x6e, 0x3a, + 0x20, 0x30, 0x73, 0x70, 0x69, 0x72, 0x69, 0x74, 0x75, 0x61, 0x6c, 0x3c, 0x2f, + 0x68, 0x65, 0x61, 0x64, 0x3e, 0x0a, 0x0a, 0x6d, 0x69, 0x63, 0x72, 0x6f, 0x73, + 0x6f, 0x66, 0x74, 0x67, 0x72, 0x61, 0x64, 0x75, 0x61, 0x6c, 0x6c, 0x79, 0x64, + 0x69, 0x73, 0x63, 0x75, 0x73, 0x73, 0x65, 0x64, 0x68, 0x65, 0x20, 0x62, 0x65, + 0x63, 0x61, 0x6d, 0x65, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x76, 0x65, + 0x6a, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x6a, 0x73, 0x68, 0x6f, 0x75, 0x73, + 0x65, 0x68, 0x6f, 0x6c, 0x64, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x72, 0x6d, 0x65, + 0x64, 0x70, 0x75, 0x72, 0x63, 0x68, 0x61, 0x73, 0x65, 0x64, 0x6c, 0x69, 0x74, + 0x65, 0x72, 0x61, 0x6c, 0x6c, 0x79, 0x64, 0x65, 0x73, 0x74, 0x72, 0x6f, 0x79, + 0x65, 0x64, 0x75, 0x70, 0x20, 0x74, 0x6f, 0x20, 0x74, 0x68, 0x65, 0x76, 0x61, + 0x72, 0x69, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x72, 0x65, 0x6d, 0x61, 0x69, 0x6e, + 0x69, 0x6e, 0x67, 0x69, 0x74, 0x20, 0x69, 0x73, 0x20, 0x6e, 0x6f, 0x74, 0x63, + 0x65, 0x6e, 0x74, 0x75, 0x72, 0x69, 0x65, 0x73, 0x4a, 0x61, 0x70, 0x61, 0x6e, + 0x65, 0x73, 0x65, 0x20, 0x61, 0x6d, 0x6f, 0x6e, 0x67, 0x20, 0x74, 0x68, 0x65, + 0x63, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x61, 0x6c, 0x67, 0x6f, + 0x72, 0x69, 0x74, 0x68, 0x6d, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x65, 0x73, 0x74, + 0x73, 0x72, 0x65, 0x62, 0x65, 0x6c, 0x6c, 0x69, 0x6f, 0x6e, 0x75, 0x6e, 0x64, + 0x65, 0x66, 0x69, 0x6e, 0x65, 0x64, 0x65, 0x6e, 0x63, 0x6f, 0x75, 0x72, 0x61, + 0x67, 0x65, 0x72, 0x65, 0x73, 0x69, 0x7a, 0x61, 0x62, 0x6c, 0x65, 0x69, 0x6e, + 0x76, 0x6f, 0x6c, 0x76, 0x69, 0x6e, 0x67, 0x73, 0x65, 0x6e, 0x73, 0x69, 0x74, + 0x69, 0x76, 0x65, 0x75, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x61, 0x6c, 0x70, + 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x28, 0x61, 0x6c, 0x74, 0x68, + 0x6f, 0x75, 0x67, 0x68, 0x66, 0x65, 0x61, 0x74, 0x75, 0x72, 0x69, 0x6e, 0x67, + 0x63, 0x6f, 0x6e, 0x64, 0x75, 0x63, 0x74, 0x65, 0x64, 0x29, 0x2c, 0x20, 0x77, + 0x68, 0x69, 0x63, 0x68, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x69, 0x6e, 0x75, 0x65, + 0x64, 0x2d, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x22, 0x3e, 0x46, 0x65, 0x62, + 0x72, 0x75, 0x61, 0x72, 0x79, 0x20, 0x6e, 0x75, 0x6d, 0x65, 0x72, 0x6f, 0x75, + 0x73, 0x20, 0x6f, 0x76, 0x65, 0x72, 0x66, 0x6c, 0x6f, 0x77, 0x3a, 0x63, 0x6f, + 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x66, 0x72, 0x61, 0x67, 0x6d, 0x65, + 0x6e, 0x74, 0x73, 0x65, 0x78, 0x63, 0x65, 0x6c, 0x6c, 0x65, 0x6e, 0x74, 0x63, + 0x6f, 0x6c, 0x73, 0x70, 0x61, 0x6e, 0x3d, 0x22, 0x74, 0x65, 0x63, 0x68, 0x6e, + 0x69, 0x63, 0x61, 0x6c, 0x6e, 0x65, 0x61, 0x72, 0x20, 0x74, 0x68, 0x65, 0x20, + 0x41, 0x64, 0x76, 0x61, 0x6e, 0x63, 0x65, 0x64, 0x20, 0x73, 0x6f, 0x75, 0x72, + 0x63, 0x65, 0x20, 0x6f, 0x66, 0x65, 0x78, 0x70, 0x72, 0x65, 0x73, 0x73, 0x65, + 0x64, 0x48, 0x6f, 0x6e, 0x67, 0x20, 0x4b, 0x6f, 0x6e, 0x67, 0x20, 0x46, 0x61, + 0x63, 0x65, 0x62, 0x6f, 0x6f, 0x6b, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x70, 0x6c, + 0x65, 0x20, 0x6d, 0x65, 0x63, 0x68, 0x61, 0x6e, 0x69, 0x73, 0x6d, 0x65, 0x6c, + 0x65, 0x76, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x6f, 0x66, 0x66, 0x65, 0x6e, 0x73, + 0x69, 0x76, 0x65, 0x3c, 0x2f, 0x66, 0x6f, 0x72, 0x6d, 0x3e, 0x0a, 0x09, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x6f, 0x72, 0x65, 0x64, 0x64, 0x6f, 0x63, 0x75, 0x6d, + 0x65, 0x6e, 0x74, 0x2e, 0x6f, 0x72, 0x20, 0x26, 0x71, 0x75, 0x6f, 0x74, 0x3b, + 0x74, 0x68, 0x65, 0x72, 0x65, 0x20, 0x61, 0x72, 0x65, 0x74, 0x68, 0x6f, 0x73, + 0x65, 0x20, 0x77, 0x68, 0x6f, 0x6d, 0x6f, 0x76, 0x65, 0x6d, 0x65, 0x6e, 0x74, + 0x73, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x65, 0x73, 0x64, 0x69, 0x66, + 0x66, 0x69, 0x63, 0x75, 0x6c, 0x74, 0x73, 0x75, 0x62, 0x6d, 0x69, 0x74, 0x74, + 0x65, 0x64, 0x72, 0x65, 0x63, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x64, 0x63, 0x6f, + 0x6e, 0x76, 0x69, 0x6e, 0x63, 0x65, 0x64, 0x70, 0x72, 0x6f, 0x6d, 0x6f, 0x74, + 0x69, 0x6e, 0x67, 0x22, 0x20, 0x77, 0x69, 0x64, 0x74, 0x68, 0x3d, 0x22, 0x2e, + 0x72, 0x65, 0x70, 0x6c, 0x61, 0x63, 0x65, 0x28, 0x63, 0x6c, 0x61, 0x73, 0x73, + 0x69, 0x63, 0x61, 0x6c, 0x63, 0x6f, 0x61, 0x6c, 0x69, 0x74, 0x69, 0x6f, 0x6e, + 0x68, 0x69, 0x73, 0x20, 0x66, 0x69, 0x72, 0x73, 0x74, 0x64, 0x65, 0x63, 0x69, + 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x61, 0x73, 0x73, 0x69, 0x73, 0x74, 0x61, 0x6e, + 0x74, 0x69, 0x6e, 0x64, 0x69, 0x63, 0x61, 0x74, 0x65, 0x64, 0x65, 0x76, 0x6f, + 0x6c, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x2d, 0x77, 0x72, 0x61, 0x70, 0x70, 0x65, + 0x72, 0x22, 0x65, 0x6e, 0x6f, 0x75, 0x67, 0x68, 0x20, 0x74, 0x6f, 0x61, 0x6c, + 0x6f, 0x6e, 0x67, 0x20, 0x74, 0x68, 0x65, 0x64, 0x65, 0x6c, 0x69, 0x76, 0x65, + 0x72, 0x65, 0x64, 0x2d, 0x2d, 0x3e, 0x0d, 0x0a, 0x3c, 0x21, 0x2d, 0x2d, 0x41, + 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x6e, 0x20, 0x70, 0x72, 0x6f, 0x74, 0x65, + 0x63, 0x74, 0x65, 0x64, 0x4e, 0x6f, 0x76, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x20, + 0x3c, 0x2f, 0x73, 0x74, 0x79, 0x6c, 0x65, 0x3e, 0x3c, 0x66, 0x75, 0x72, 0x6e, + 0x69, 0x74, 0x75, 0x72, 0x65, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, + 0x20, 0x20, 0x6f, 0x6e, 0x62, 0x6c, 0x75, 0x72, 0x3d, 0x22, 0x73, 0x75, 0x73, + 0x70, 0x65, 0x6e, 0x64, 0x65, 0x64, 0x72, 0x65, 0x63, 0x69, 0x70, 0x69, 0x65, + 0x6e, 0x74, 0x62, 0x61, 0x73, 0x65, 0x64, 0x20, 0x6f, 0x6e, 0x20, 0x4d, 0x6f, + 0x72, 0x65, 0x6f, 0x76, 0x65, 0x72, 0x2c, 0x61, 0x62, 0x6f, 0x6c, 0x69, 0x73, + 0x68, 0x65, 0x64, 0x63, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x65, 0x64, 0x77, + 0x65, 0x72, 0x65, 0x20, 0x6d, 0x61, 0x64, 0x65, 0x65, 0x6d, 0x6f, 0x74, 0x69, + 0x6f, 0x6e, 0x61, 0x6c, 0x65, 0x6d, 0x65, 0x72, 0x67, 0x65, 0x6e, 0x63, 0x79, + 0x6e, 0x61, 0x72, 0x72, 0x61, 0x74, 0x69, 0x76, 0x65, 0x61, 0x64, 0x76, 0x6f, + 0x63, 0x61, 0x74, 0x65, 0x73, 0x70, 0x78, 0x3b, 0x62, 0x6f, 0x72, 0x64, 0x65, + 0x72, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x74, 0x65, 0x64, 0x64, 0x69, 0x72, + 0x3d, 0x22, 0x6c, 0x74, 0x72, 0x22, 0x65, 0x6d, 0x70, 0x6c, 0x6f, 0x79, 0x65, + 0x65, 0x73, 0x72, 0x65, 0x73, 0x65, 0x61, 0x72, 0x63, 0x68, 0x2e, 0x20, 0x73, + 0x65, 0x6c, 0x65, 0x63, 0x74, 0x65, 0x64, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, + 0x73, 0x6f, 0x72, 0x63, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x65, 0x72, 0x73, 0x64, + 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x65, 0x64, 0x53, 0x65, 0x70, 0x74, 0x65, + 0x6d, 0x62, 0x65, 0x72, 0x61, 0x64, 0x64, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x28, + 0x46, 0x61, 0x63, 0x65, 0x62, 0x6f, 0x6f, 0x6b, 0x20, 0x73, 0x75, 0x67, 0x67, + 0x65, 0x73, 0x74, 0x65, 0x64, 0x61, 0x6e, 0x64, 0x20, 0x6c, 0x61, 0x74, 0x65, + 0x72, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6e, 0x67, 0x65, 0x6c, 0x61, + 0x62, 0x6f, 0x72, 0x61, 0x74, 0x65, 0x53, 0x6f, 0x6d, 0x65, 0x74, 0x69, 0x6d, + 0x65, 0x73, 0x49, 0x6e, 0x73, 0x74, 0x69, 0x74, 0x75, 0x74, 0x65, 0x63, 0x65, + 0x72, 0x74, 0x61, 0x69, 0x6e, 0x6c, 0x79, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6c, + 0x6c, 0x65, 0x64, 0x66, 0x6f, 0x6c, 0x6c, 0x6f, 0x77, 0x65, 0x72, 0x73, 0x4a, + 0x65, 0x72, 0x75, 0x73, 0x61, 0x6c, 0x65, 0x6d, 0x74, 0x68, 0x65, 0x79, 0x20, + 0x68, 0x61, 0x76, 0x65, 0x63, 0x6f, 0x6d, 0x70, 0x75, 0x74, 0x69, 0x6e, 0x67, + 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x64, 0x70, 0x72, 0x6f, 0x76, + 0x69, 0x6e, 0x63, 0x65, 0x73, 0x67, 0x75, 0x61, 0x72, 0x61, 0x6e, 0x74, 0x65, + 0x65, 0x61, 0x72, 0x62, 0x69, 0x74, 0x72, 0x61, 0x72, 0x79, 0x72, 0x65, 0x63, + 0x6f, 0x67, 0x6e, 0x69, 0x7a, 0x65, 0x77, 0x61, 0x6e, 0x74, 0x65, 0x64, 0x20, + 0x74, 0x6f, 0x70, 0x78, 0x3b, 0x77, 0x69, 0x64, 0x74, 0x68, 0x3a, 0x74, 0x68, + 0x65, 0x6f, 0x72, 0x79, 0x20, 0x6f, 0x66, 0x62, 0x65, 0x68, 0x61, 0x76, 0x69, + 0x6f, 0x75, 0x72, 0x57, 0x68, 0x69, 0x6c, 0x65, 0x20, 0x74, 0x68, 0x65, 0x65, + 0x73, 0x74, 0x69, 0x6d, 0x61, 0x74, 0x65, 0x64, 0x62, 0x65, 0x67, 0x61, 0x6e, + 0x20, 0x74, 0x6f, 0x20, 0x69, 0x74, 0x20, 0x62, 0x65, 0x63, 0x61, 0x6d, 0x65, + 0x6d, 0x61, 0x67, 0x6e, 0x69, 0x74, 0x75, 0x64, 0x65, 0x6d, 0x75, 0x73, 0x74, + 0x20, 0x68, 0x61, 0x76, 0x65, 0x6d, 0x6f, 0x72, 0x65, 0x20, 0x74, 0x68, 0x61, + 0x6e, 0x44, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x79, 0x65, 0x78, 0x74, + 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x65, 0x63, 0x72, 0x65, 0x74, 0x61, + 0x72, 0x79, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x61, 0x6c, 0x6c, 0x79, 0x6f, 0x63, + 0x63, 0x75, 0x72, 0x72, 0x69, 0x6e, 0x67, 0x76, 0x61, 0x72, 0x69, 0x61, 0x62, + 0x6c, 0x65, 0x73, 0x67, 0x69, 0x76, 0x65, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x70, + 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x2e, 0x3c, 0x2f, 0x6c, 0x61, 0x62, + 0x65, 0x6c, 0x3e, 0x3c, 0x66, 0x61, 0x69, 0x6c, 0x65, 0x64, 0x20, 0x74, 0x6f, + 0x63, 0x6f, 0x6d, 0x70, 0x6f, 0x75, 0x6e, 0x64, 0x73, 0x6b, 0x69, 0x6e, 0x64, + 0x73, 0x20, 0x6f, 0x66, 0x20, 0x73, 0x6f, 0x63, 0x69, 0x65, 0x74, 0x69, 0x65, + 0x73, 0x61, 0x6c, 0x6f, 0x6e, 0x67, 0x73, 0x69, 0x64, 0x65, 0x20, 0x2d, 0x2d, + 0x26, 0x67, 0x74, 0x3b, 0x0a, 0x0a, 0x73, 0x6f, 0x75, 0x74, 0x68, 0x77, 0x65, + 0x73, 0x74, 0x74, 0x68, 0x65, 0x20, 0x72, 0x69, 0x67, 0x68, 0x74, 0x72, 0x61, + 0x64, 0x69, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x6d, 0x61, 0x79, 0x20, 0x68, 0x61, + 0x76, 0x65, 0x20, 0x75, 0x6e, 0x65, 0x73, 0x63, 0x61, 0x70, 0x65, 0x28, 0x73, + 0x70, 0x6f, 0x6b, 0x65, 0x6e, 0x20, 0x69, 0x6e, 0x22, 0x20, 0x68, 0x72, 0x65, + 0x66, 0x3d, 0x22, 0x2f, 0x70, 0x72, 0x6f, 0x67, 0x72, 0x61, 0x6d, 0x6d, 0x65, + 0x6f, 0x6e, 0x6c, 0x79, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x6f, 0x6d, 0x65, + 0x20, 0x66, 0x72, 0x6f, 0x6d, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, + 0x79, 0x62, 0x75, 0x72, 0x69, 0x65, 0x64, 0x20, 0x69, 0x6e, 0x61, 0x20, 0x73, + 0x69, 0x6d, 0x69, 0x6c, 0x61, 0x72, 0x74, 0x68, 0x65, 0x79, 0x20, 0x77, 0x65, + 0x72, 0x65, 0x3c, 0x2f, 0x66, 0x6f, 0x6e, 0x74, 0x3e, 0x3c, 0x2f, 0x4e, 0x6f, + 0x72, 0x77, 0x65, 0x67, 0x69, 0x61, 0x6e, 0x73, 0x70, 0x65, 0x63, 0x69, 0x66, + 0x69, 0x65, 0x64, 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x69, 0x6e, 0x67, 0x70, + 0x61, 0x73, 0x73, 0x65, 0x6e, 0x67, 0x65, 0x72, 0x28, 0x6e, 0x65, 0x77, 0x20, + 0x44, 0x61, 0x74, 0x65, 0x74, 0x65, 0x6d, 0x70, 0x6f, 0x72, 0x61, 0x72, 0x79, + 0x66, 0x69, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x41, 0x66, 0x74, 0x65, + 0x72, 0x20, 0x74, 0x68, 0x65, 0x65, 0x71, 0x75, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x73, 0x64, 0x6f, 0x77, 0x6e, 0x6c, 0x6f, 0x61, 0x64, 0x2e, 0x72, 0x65, 0x67, + 0x75, 0x6c, 0x61, 0x72, 0x6c, 0x79, 0x64, 0x65, 0x76, 0x65, 0x6c, 0x6f, 0x70, + 0x65, 0x72, 0x61, 0x62, 0x6f, 0x76, 0x65, 0x20, 0x74, 0x68, 0x65, 0x6c, 0x69, + 0x6e, 0x6b, 0x65, 0x64, 0x20, 0x74, 0x6f, 0x70, 0x68, 0x65, 0x6e, 0x6f, 0x6d, + 0x65, 0x6e, 0x61, 0x70, 0x65, 0x72, 0x69, 0x6f, 0x64, 0x20, 0x6f, 0x66, 0x74, + 0x6f, 0x6f, 0x6c, 0x74, 0x69, 0x70, 0x22, 0x3e, 0x73, 0x75, 0x62, 0x73, 0x74, + 0x61, 0x6e, 0x63, 0x65, 0x61, 0x75, 0x74, 0x6f, 0x6d, 0x61, 0x74, 0x69, 0x63, + 0x61, 0x73, 0x70, 0x65, 0x63, 0x74, 0x20, 0x6f, 0x66, 0x41, 0x6d, 0x6f, 0x6e, + 0x67, 0x20, 0x74, 0x68, 0x65, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x65, + 0x64, 0x65, 0x73, 0x74, 0x69, 0x6d, 0x61, 0x74, 0x65, 0x73, 0x41, 0x69, 0x72, + 0x20, 0x46, 0x6f, 0x72, 0x63, 0x65, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x20, + 0x6f, 0x66, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x69, 0x6d, + 0x6d, 0x65, 0x64, 0x69, 0x61, 0x74, 0x65, 0x6d, 0x61, 0x6b, 0x69, 0x6e, 0x67, + 0x20, 0x69, 0x74, 0x70, 0x61, 0x69, 0x6e, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x63, + 0x6f, 0x6e, 0x71, 0x75, 0x65, 0x72, 0x65, 0x64, 0x61, 0x72, 0x65, 0x20, 0x73, + 0x74, 0x69, 0x6c, 0x6c, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x64, 0x75, 0x72, 0x65, + 0x67, 0x72, 0x6f, 0x77, 0x74, 0x68, 0x20, 0x6f, 0x66, 0x68, 0x65, 0x61, 0x64, + 0x65, 0x64, 0x20, 0x62, 0x79, 0x45, 0x75, 0x72, 0x6f, 0x70, 0x65, 0x61, 0x6e, + 0x20, 0x64, 0x69, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x6d, 0x6f, 0x6c, + 0x65, 0x63, 0x75, 0x6c, 0x65, 0x73, 0x66, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x69, + 0x73, 0x65, 0x69, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x74, + 0x74, 0x72, 0x61, 0x63, 0x74, 0x65, 0x64, 0x63, 0x68, 0x69, 0x6c, 0x64, 0x68, + 0x6f, 0x6f, 0x64, 0x61, 0x6c, 0x73, 0x6f, 0x20, 0x75, 0x73, 0x65, 0x64, 0x64, + 0x65, 0x64, 0x69, 0x63, 0x61, 0x74, 0x65, 0x64, 0x73, 0x69, 0x6e, 0x67, 0x61, + 0x70, 0x6f, 0x72, 0x65, 0x64, 0x65, 0x67, 0x72, 0x65, 0x65, 0x20, 0x6f, 0x66, + 0x66, 0x61, 0x74, 0x68, 0x65, 0x72, 0x20, 0x6f, 0x66, 0x63, 0x6f, 0x6e, 0x66, + 0x6c, 0x69, 0x63, 0x74, 0x73, 0x3c, 0x2f, 0x61, 0x3e, 0x3c, 0x2f, 0x70, 0x3e, + 0x0a, 0x63, 0x61, 0x6d, 0x65, 0x20, 0x66, 0x72, 0x6f, 0x6d, 0x77, 0x65, 0x72, + 0x65, 0x20, 0x75, 0x73, 0x65, 0x64, 0x6e, 0x6f, 0x74, 0x65, 0x20, 0x74, 0x68, + 0x61, 0x74, 0x72, 0x65, 0x63, 0x65, 0x69, 0x76, 0x69, 0x6e, 0x67, 0x45, 0x78, + 0x65, 0x63, 0x75, 0x74, 0x69, 0x76, 0x65, 0x65, 0x76, 0x65, 0x6e, 0x20, 0x6d, + 0x6f, 0x72, 0x65, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x20, 0x74, 0x6f, 0x63, + 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x65, 0x72, 0x50, 0x6f, 0x6c, 0x69, 0x74, + 0x69, 0x63, 0x61, 0x6c, 0x6d, 0x75, 0x73, 0x69, 0x63, 0x69, 0x61, 0x6e, 0x73, + 0x64, 0x65, 0x6c, 0x69, 0x63, 0x69, 0x6f, 0x75, 0x73, 0x70, 0x72, 0x69, 0x73, + 0x6f, 0x6e, 0x65, 0x72, 0x73, 0x61, 0x64, 0x76, 0x65, 0x6e, 0x74, 0x20, 0x6f, + 0x66, 0x55, 0x54, 0x46, 0x2d, 0x38, 0x22, 0x20, 0x2f, 0x3e, 0x3c, 0x21, 0x5b, + 0x43, 0x44, 0x41, 0x54, 0x41, 0x5b, 0x22, 0x3e, 0x43, 0x6f, 0x6e, 0x74, 0x61, + 0x63, 0x74, 0x53, 0x6f, 0x75, 0x74, 0x68, 0x65, 0x72, 0x6e, 0x20, 0x62, 0x67, + 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3d, 0x22, 0x73, 0x65, 0x72, 0x69, 0x65, 0x73, + 0x20, 0x6f, 0x66, 0x2e, 0x20, 0x49, 0x74, 0x20, 0x77, 0x61, 0x73, 0x20, 0x69, + 0x6e, 0x20, 0x45, 0x75, 0x72, 0x6f, 0x70, 0x65, 0x70, 0x65, 0x72, 0x6d, 0x69, + 0x74, 0x74, 0x65, 0x64, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x2e, + 0x61, 0x70, 0x70, 0x65, 0x61, 0x72, 0x69, 0x6e, 0x67, 0x6f, 0x66, 0x66, 0x69, + 0x63, 0x69, 0x61, 0x6c, 0x73, 0x73, 0x65, 0x72, 0x69, 0x6f, 0x75, 0x73, 0x6c, + 0x79, 0x2d, 0x6c, 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, 0x69, 0x6e, 0x69, + 0x74, 0x69, 0x61, 0x74, 0x65, 0x64, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x64, 0x69, + 0x6e, 0x67, 0x6c, 0x6f, 0x6e, 0x67, 0x2d, 0x74, 0x65, 0x72, 0x6d, 0x69, 0x6e, + 0x66, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x75, 0x63, 0x68, 0x20, 0x74, + 0x68, 0x61, 0x74, 0x67, 0x65, 0x74, 0x43, 0x6f, 0x6f, 0x6b, 0x69, 0x65, 0x6d, + 0x61, 0x72, 0x6b, 0x65, 0x64, 0x20, 0x62, 0x79, 0x3c, 0x2f, 0x62, 0x75, 0x74, + 0x74, 0x6f, 0x6e, 0x3e, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, + 0x62, 0x75, 0x74, 0x20, 0x69, 0x74, 0x20, 0x69, 0x73, 0x69, 0x6e, 0x63, 0x72, + 0x65, 0x61, 0x73, 0x65, 0x73, 0x64, 0x6f, 0x77, 0x6e, 0x20, 0x74, 0x68, 0x65, + 0x20, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x69, 0x6e, 0x67, 0x64, 0x65, 0x70, + 0x65, 0x6e, 0x64, 0x65, 0x6e, 0x74, 0x2d, 0x2d, 0x3e, 0x0a, 0x3c, 0x21, 0x2d, + 0x2d, 0x20, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x69, 0x65, 0x77, 0x57, 0x69, + 0x74, 0x68, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x6f, 0x70, 0x69, 0x65, 0x73, + 0x20, 0x6f, 0x66, 0x63, 0x6f, 0x6e, 0x73, 0x65, 0x6e, 0x73, 0x75, 0x73, 0x77, + 0x61, 0x73, 0x20, 0x62, 0x75, 0x69, 0x6c, 0x74, 0x56, 0x65, 0x6e, 0x65, 0x7a, + 0x75, 0x65, 0x6c, 0x61, 0x28, 0x66, 0x6f, 0x72, 0x6d, 0x65, 0x72, 0x6c, 0x79, + 0x74, 0x68, 0x65, 0x20, 0x73, 0x74, 0x61, 0x74, 0x65, 0x70, 0x65, 0x72, 0x73, + 0x6f, 0x6e, 0x6e, 0x65, 0x6c, 0x73, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x69, + 0x63, 0x66, 0x61, 0x76, 0x6f, 0x75, 0x72, 0x20, 0x6f, 0x66, 0x69, 0x6e, 0x76, + 0x65, 0x6e, 0x74, 0x69, 0x6f, 0x6e, 0x57, 0x69, 0x6b, 0x69, 0x70, 0x65, 0x64, + 0x69, 0x61, 0x63, 0x6f, 0x6e, 0x74, 0x69, 0x6e, 0x65, 0x6e, 0x74, 0x76, 0x69, + 0x72, 0x74, 0x75, 0x61, 0x6c, 0x6c, 0x79, 0x77, 0x68, 0x69, 0x63, 0x68, 0x20, + 0x77, 0x61, 0x73, 0x70, 0x72, 0x69, 0x6e, 0x63, 0x69, 0x70, 0x6c, 0x65, 0x43, + 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x20, 0x69, 0x64, 0x65, 0x6e, 0x74, + 0x69, 0x63, 0x61, 0x6c, 0x73, 0x68, 0x6f, 0x77, 0x20, 0x74, 0x68, 0x61, 0x74, + 0x70, 0x72, 0x69, 0x6d, 0x69, 0x74, 0x69, 0x76, 0x65, 0x61, 0x77, 0x61, 0x79, + 0x20, 0x66, 0x72, 0x6f, 0x6d, 0x6d, 0x6f, 0x6c, 0x65, 0x63, 0x75, 0x6c, 0x61, + 0x72, 0x70, 0x72, 0x65, 0x63, 0x69, 0x73, 0x65, 0x6c, 0x79, 0x64, 0x69, 0x73, + 0x73, 0x6f, 0x6c, 0x76, 0x65, 0x64, 0x55, 0x6e, 0x64, 0x65, 0x72, 0x20, 0x74, + 0x68, 0x65, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x3d, 0x22, 0x3e, 0x26, + 0x6e, 0x62, 0x73, 0x70, 0x3b, 0x3c, 0x2f, 0x49, 0x74, 0x20, 0x69, 0x73, 0x20, + 0x74, 0x68, 0x65, 0x20, 0x54, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, 0x20, 0x77, + 0x69, 0x6c, 0x6c, 0x20, 0x68, 0x61, 0x76, 0x65, 0x6f, 0x72, 0x67, 0x61, 0x6e, + 0x69, 0x73, 0x6d, 0x73, 0x73, 0x6f, 0x6d, 0x65, 0x20, 0x74, 0x69, 0x6d, 0x65, + 0x46, 0x72, 0x69, 0x65, 0x64, 0x72, 0x69, 0x63, 0x68, 0x77, 0x61, 0x73, 0x20, + 0x66, 0x69, 0x72, 0x73, 0x74, 0x74, 0x68, 0x65, 0x20, 0x6f, 0x6e, 0x6c, 0x79, + 0x20, 0x66, 0x61, 0x63, 0x74, 0x20, 0x74, 0x68, 0x61, 0x74, 0x66, 0x6f, 0x72, + 0x6d, 0x20, 0x69, 0x64, 0x3d, 0x22, 0x70, 0x72, 0x65, 0x63, 0x65, 0x64, 0x69, + 0x6e, 0x67, 0x54, 0x65, 0x63, 0x68, 0x6e, 0x69, 0x63, 0x61, 0x6c, 0x70, 0x68, + 0x79, 0x73, 0x69, 0x63, 0x69, 0x73, 0x74, 0x6f, 0x63, 0x63, 0x75, 0x72, 0x73, + 0x20, 0x69, 0x6e, 0x6e, 0x61, 0x76, 0x69, 0x67, 0x61, 0x74, 0x6f, 0x72, 0x73, + 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x3e, 0x73, 0x70, 0x61, 0x6e, 0x20, + 0x69, 0x64, 0x3d, 0x22, 0x73, 0x6f, 0x75, 0x67, 0x68, 0x74, 0x20, 0x74, 0x6f, + 0x62, 0x65, 0x6c, 0x6f, 0x77, 0x20, 0x74, 0x68, 0x65, 0x73, 0x75, 0x72, 0x76, + 0x69, 0x76, 0x69, 0x6e, 0x67, 0x7d, 0x3c, 0x2f, 0x73, 0x74, 0x79, 0x6c, 0x65, + 0x3e, 0x68, 0x69, 0x73, 0x20, 0x64, 0x65, 0x61, 0x74, 0x68, 0x61, 0x73, 0x20, + 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x63, 0x61, 0x75, 0x73, 0x65, 0x64, 0x20, + 0x62, 0x79, 0x70, 0x61, 0x72, 0x74, 0x69, 0x61, 0x6c, 0x6c, 0x79, 0x65, 0x78, + 0x69, 0x73, 0x74, 0x69, 0x6e, 0x67, 0x20, 0x75, 0x73, 0x69, 0x6e, 0x67, 0x20, + 0x74, 0x68, 0x65, 0x77, 0x61, 0x73, 0x20, 0x67, 0x69, 0x76, 0x65, 0x6e, 0x61, + 0x20, 0x6c, 0x69, 0x73, 0x74, 0x20, 0x6f, 0x66, 0x6c, 0x65, 0x76, 0x65, 0x6c, + 0x73, 0x20, 0x6f, 0x66, 0x6e, 0x6f, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6f, 0x66, + 0x4f, 0x66, 0x66, 0x69, 0x63, 0x69, 0x61, 0x6c, 0x20, 0x64, 0x69, 0x73, 0x6d, + 0x69, 0x73, 0x73, 0x65, 0x64, 0x73, 0x63, 0x69, 0x65, 0x6e, 0x74, 0x69, 0x73, + 0x74, 0x72, 0x65, 0x73, 0x65, 0x6d, 0x62, 0x6c, 0x65, 0x73, 0x64, 0x75, 0x70, + 0x6c, 0x69, 0x63, 0x61, 0x74, 0x65, 0x65, 0x78, 0x70, 0x6c, 0x6f, 0x73, 0x69, + 0x76, 0x65, 0x72, 0x65, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x65, 0x64, 0x61, 0x6c, + 0x6c, 0x20, 0x6f, 0x74, 0x68, 0x65, 0x72, 0x67, 0x61, 0x6c, 0x6c, 0x65, 0x72, + 0x69, 0x65, 0x73, 0x7b, 0x70, 0x61, 0x64, 0x64, 0x69, 0x6e, 0x67, 0x3a, 0x70, + 0x65, 0x6f, 0x70, 0x6c, 0x65, 0x20, 0x6f, 0x66, 0x72, 0x65, 0x67, 0x69, 0x6f, + 0x6e, 0x20, 0x6f, 0x66, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x65, 0x73, + 0x61, 0x73, 0x73, 0x6f, 0x63, 0x69, 0x61, 0x74, 0x65, 0x69, 0x6d, 0x67, 0x20, + 0x61, 0x6c, 0x74, 0x3d, 0x22, 0x69, 0x6e, 0x20, 0x6d, 0x6f, 0x64, 0x65, 0x72, + 0x6e, 0x73, 0x68, 0x6f, 0x75, 0x6c, 0x64, 0x20, 0x62, 0x65, 0x6d, 0x65, 0x74, + 0x68, 0x6f, 0x64, 0x20, 0x6f, 0x66, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x69, + 0x6e, 0x67, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x6e, 0x65, + 0x65, 0x64, 0x65, 0x64, 0x20, 0x74, 0x6f, 0x74, 0x68, 0x65, 0x20, 0x47, 0x72, + 0x65, 0x61, 0x74, 0x72, 0x65, 0x67, 0x61, 0x72, 0x64, 0x69, 0x6e, 0x67, 0x73, + 0x65, 0x65, 0x6d, 0x65, 0x64, 0x20, 0x74, 0x6f, 0x76, 0x69, 0x65, 0x77, 0x65, + 0x64, 0x20, 0x61, 0x73, 0x69, 0x6d, 0x70, 0x61, 0x63, 0x74, 0x20, 0x6f, 0x6e, + 0x69, 0x64, 0x65, 0x61, 0x20, 0x74, 0x68, 0x61, 0x74, 0x74, 0x68, 0x65, 0x20, + 0x57, 0x6f, 0x72, 0x6c, 0x64, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x20, 0x6f, + 0x66, 0x65, 0x78, 0x70, 0x61, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x54, 0x68, 0x65, + 0x73, 0x65, 0x20, 0x61, 0x72, 0x65, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, + 0x22, 0x3e, 0x63, 0x61, 0x72, 0x65, 0x66, 0x75, 0x6c, 0x6c, 0x79, 0x6d, 0x61, + 0x69, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x73, 0x63, 0x68, 0x61, 0x72, 0x67, 0x65, + 0x20, 0x6f, 0x66, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x69, 0x63, 0x61, 0x6c, 0x61, + 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x65, 0x64, 0x70, 0x72, 0x65, 0x64, 0x69, + 0x63, 0x74, 0x65, 0x64, 0x6f, 0x77, 0x6e, 0x65, 0x72, 0x73, 0x68, 0x69, 0x70, + 0x3c, 0x64, 0x69, 0x76, 0x20, 0x69, 0x64, 0x3d, 0x22, 0x72, 0x69, 0x67, 0x68, + 0x74, 0x22, 0x3e, 0x0d, 0x0a, 0x72, 0x65, 0x73, 0x69, 0x64, 0x65, 0x6e, 0x63, + 0x65, 0x6c, 0x65, 0x61, 0x76, 0x65, 0x20, 0x74, 0x68, 0x65, 0x63, 0x6f, 0x6e, + 0x74, 0x65, 0x6e, 0x74, 0x22, 0x3e, 0x61, 0x72, 0x65, 0x20, 0x6f, 0x66, 0x74, + 0x65, 0x6e, 0x20, 0x20, 0x7d, 0x29, 0x28, 0x29, 0x3b, 0x0d, 0x0a, 0x70, 0x72, + 0x6f, 0x62, 0x61, 0x62, 0x6c, 0x79, 0x20, 0x50, 0x72, 0x6f, 0x66, 0x65, 0x73, + 0x73, 0x6f, 0x72, 0x2d, 0x62, 0x75, 0x74, 0x74, 0x6f, 0x6e, 0x22, 0x20, 0x72, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x64, 0x65, 0x64, 0x73, 0x61, 0x79, 0x73, 0x20, + 0x74, 0x68, 0x61, 0x74, 0x68, 0x61, 0x64, 0x20, 0x74, 0x6f, 0x20, 0x62, 0x65, + 0x70, 0x6c, 0x61, 0x63, 0x65, 0x64, 0x20, 0x69, 0x6e, 0x48, 0x75, 0x6e, 0x67, + 0x61, 0x72, 0x69, 0x61, 0x6e, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x20, 0x6f, + 0x66, 0x73, 0x65, 0x72, 0x76, 0x65, 0x73, 0x20, 0x61, 0x73, 0x55, 0x6e, 0x69, + 0x76, 0x65, 0x72, 0x73, 0x61, 0x6c, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, + 0x6f, 0x6e, 0x61, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x65, 0x66, 0x6f, + 0x72, 0x20, 0x77, 0x68, 0x69, 0x63, 0x68, 0x69, 0x6e, 0x66, 0x65, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x61, 0x67, 0x72, 0x65, 0x65, 0x64, 0x20, 0x74, 0x6f, 0x68, + 0x6f, 0x77, 0x65, 0x76, 0x65, 0x72, 0x2c, 0x20, 0x70, 0x6f, 0x70, 0x75, 0x6c, + 0x61, 0x72, 0x22, 0x3e, 0x70, 0x6c, 0x61, 0x63, 0x65, 0x64, 0x20, 0x6f, 0x6e, + 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x65, 0x6c, 0x65, 0x63, + 0x74, 0x6f, 0x72, 0x61, 0x6c, 0x73, 0x79, 0x6d, 0x62, 0x6f, 0x6c, 0x20, 0x6f, + 0x66, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x69, 0x6e, 0x67, 0x72, 0x65, 0x74, + 0x75, 0x72, 0x6e, 0x20, 0x74, 0x6f, 0x61, 0x72, 0x63, 0x68, 0x69, 0x74, 0x65, + 0x63, 0x74, 0x43, 0x68, 0x72, 0x69, 0x73, 0x74, 0x69, 0x61, 0x6e, 0x70, 0x72, + 0x65, 0x76, 0x69, 0x6f, 0x75, 0x73, 0x20, 0x6c, 0x69, 0x76, 0x69, 0x6e, 0x67, + 0x20, 0x69, 0x6e, 0x65, 0x61, 0x73, 0x69, 0x65, 0x72, 0x20, 0x74, 0x6f, 0x70, + 0x72, 0x6f, 0x66, 0x65, 0x73, 0x73, 0x6f, 0x72, 0x0a, 0x26, 0x6c, 0x74, 0x3b, + 0x21, 0x2d, 0x2d, 0x20, 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, 0x20, 0x6f, 0x66, + 0x61, 0x6e, 0x61, 0x6c, 0x79, 0x74, 0x69, 0x63, 0x73, 0x77, 0x61, 0x73, 0x20, + 0x74, 0x61, 0x6b, 0x65, 0x6e, 0x77, 0x68, 0x65, 0x72, 0x65, 0x20, 0x74, 0x68, + 0x65, 0x74, 0x6f, 0x6f, 0x6b, 0x20, 0x6f, 0x76, 0x65, 0x72, 0x62, 0x65, 0x6c, + 0x69, 0x65, 0x66, 0x20, 0x69, 0x6e, 0x41, 0x66, 0x72, 0x69, 0x6b, 0x61, 0x61, + 0x6e, 0x73, 0x61, 0x73, 0x20, 0x66, 0x61, 0x72, 0x20, 0x61, 0x73, 0x70, 0x72, + 0x65, 0x76, 0x65, 0x6e, 0x74, 0x65, 0x64, 0x77, 0x6f, 0x72, 0x6b, 0x20, 0x77, + 0x69, 0x74, 0x68, 0x61, 0x20, 0x73, 0x70, 0x65, 0x63, 0x69, 0x61, 0x6c, 0x3c, + 0x66, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x65, 0x74, 0x43, 0x68, 0x72, 0x69, 0x73, + 0x74, 0x6d, 0x61, 0x73, 0x52, 0x65, 0x74, 0x72, 0x69, 0x65, 0x76, 0x65, 0x64, + 0x0a, 0x0a, 0x49, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x62, 0x61, 0x63, 0x6b, + 0x20, 0x69, 0x6e, 0x74, 0x6f, 0x6e, 0x6f, 0x72, 0x74, 0x68, 0x65, 0x61, 0x73, + 0x74, 0x6d, 0x61, 0x67, 0x61, 0x7a, 0x69, 0x6e, 0x65, 0x73, 0x3e, 0x3c, 0x73, + 0x74, 0x72, 0x6f, 0x6e, 0x67, 0x3e, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x74, + 0x65, 0x65, 0x67, 0x6f, 0x76, 0x65, 0x72, 0x6e, 0x69, 0x6e, 0x67, 0x67, 0x72, + 0x6f, 0x75, 0x70, 0x73, 0x20, 0x6f, 0x66, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x64, + 0x20, 0x69, 0x6e, 0x65, 0x73, 0x74, 0x61, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x61, + 0x20, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x6c, 0x69, 0x74, 0x73, 0x20, 0x66, + 0x69, 0x72, 0x73, 0x74, 0x74, 0x68, 0x65, 0x69, 0x72, 0x20, 0x6f, 0x77, 0x6e, + 0x70, 0x6f, 0x70, 0x75, 0x6c, 0x61, 0x74, 0x65, 0x64, 0x61, 0x6e, 0x20, 0x6f, + 0x62, 0x6a, 0x65, 0x63, 0x74, 0x43, 0x61, 0x72, 0x69, 0x62, 0x62, 0x65, 0x61, + 0x6e, 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x20, 0x74, 0x68, 0x65, 0x64, 0x69, 0x73, + 0x74, 0x72, 0x69, 0x63, 0x74, 0x73, 0x77, 0x69, 0x73, 0x63, 0x6f, 0x6e, 0x73, + 0x69, 0x6e, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x3b, 0x20, + 0x77, 0x69, 0x64, 0x74, 0x68, 0x3a, 0x20, 0x69, 0x6e, 0x68, 0x61, 0x62, 0x69, + 0x74, 0x65, 0x64, 0x53, 0x6f, 0x63, 0x69, 0x61, 0x6c, 0x69, 0x73, 0x74, 0x4a, + 0x61, 0x6e, 0x75, 0x61, 0x72, 0x79, 0x20, 0x31, 0x3c, 0x2f, 0x66, 0x6f, 0x6f, + 0x74, 0x65, 0x72, 0x3e, 0x73, 0x69, 0x6d, 0x69, 0x6c, 0x61, 0x72, 0x6c, 0x79, + 0x63, 0x68, 0x6f, 0x69, 0x63, 0x65, 0x20, 0x6f, 0x66, 0x74, 0x68, 0x65, 0x20, + 0x73, 0x61, 0x6d, 0x65, 0x20, 0x73, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x63, + 0x20, 0x62, 0x75, 0x73, 0x69, 0x6e, 0x65, 0x73, 0x73, 0x20, 0x54, 0x68, 0x65, + 0x20, 0x66, 0x69, 0x72, 0x73, 0x74, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, + 0x3b, 0x20, 0x64, 0x65, 0x73, 0x69, 0x72, 0x65, 0x20, 0x74, 0x6f, 0x64, 0x65, + 0x61, 0x6c, 0x20, 0x77, 0x69, 0x74, 0x68, 0x73, 0x69, 0x6e, 0x63, 0x65, 0x20, + 0x74, 0x68, 0x65, 0x75, 0x73, 0x65, 0x72, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x63, + 0x6f, 0x6e, 0x63, 0x65, 0x69, 0x76, 0x65, 0x64, 0x69, 0x6e, 0x64, 0x65, 0x78, + 0x2e, 0x70, 0x68, 0x70, 0x61, 0x73, 0x20, 0x26, 0x71, 0x75, 0x6f, 0x74, 0x3b, + 0x65, 0x6e, 0x67, 0x61, 0x67, 0x65, 0x20, 0x69, 0x6e, 0x72, 0x65, 0x63, 0x65, + 0x6e, 0x74, 0x6c, 0x79, 0x2c, 0x66, 0x65, 0x77, 0x20, 0x79, 0x65, 0x61, 0x72, + 0x73, 0x77, 0x65, 0x72, 0x65, 0x20, 0x61, 0x6c, 0x73, 0x6f, 0x0a, 0x3c, 0x68, + 0x65, 0x61, 0x64, 0x3e, 0x0a, 0x3c, 0x65, 0x64, 0x69, 0x74, 0x65, 0x64, 0x20, + 0x62, 0x79, 0x61, 0x72, 0x65, 0x20, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x63, 0x69, + 0x74, 0x69, 0x65, 0x73, 0x20, 0x69, 0x6e, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, + 0x6b, 0x65, 0x79, 0x63, 0x6f, 0x6e, 0x64, 0x65, 0x6d, 0x6e, 0x65, 0x64, 0x61, + 0x6c, 0x73, 0x6f, 0x20, 0x68, 0x61, 0x76, 0x65, 0x73, 0x65, 0x72, 0x76, 0x69, + 0x63, 0x65, 0x73, 0x2c, 0x66, 0x61, 0x6d, 0x69, 0x6c, 0x79, 0x20, 0x6f, 0x66, + 0x53, 0x63, 0x68, 0x6f, 0x6f, 0x6c, 0x20, 0x6f, 0x66, 0x63, 0x6f, 0x6e, 0x76, + 0x65, 0x72, 0x74, 0x65, 0x64, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x20, 0x6f, + 0x66, 0x20, 0x6c, 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, 0x6d, 0x69, 0x6e, + 0x69, 0x73, 0x74, 0x65, 0x72, 0x73, 0x3c, 0x2f, 0x6f, 0x62, 0x6a, 0x65, 0x63, + 0x74, 0x3e, 0x74, 0x68, 0x65, 0x72, 0x65, 0x20, 0x69, 0x73, 0x20, 0x61, 0x20, + 0x70, 0x6f, 0x70, 0x75, 0x6c, 0x61, 0x72, 0x73, 0x65, 0x71, 0x75, 0x65, 0x6e, + 0x63, 0x65, 0x73, 0x61, 0x64, 0x76, 0x6f, 0x63, 0x61, 0x74, 0x65, 0x64, 0x54, + 0x68, 0x65, 0x79, 0x20, 0x77, 0x65, 0x72, 0x65, 0x61, 0x6e, 0x79, 0x20, 0x6f, + 0x74, 0x68, 0x65, 0x72, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3d, + 0x65, 0x6e, 0x74, 0x65, 0x72, 0x20, 0x74, 0x68, 0x65, 0x6d, 0x75, 0x63, 0x68, + 0x20, 0x6d, 0x6f, 0x72, 0x65, 0x72, 0x65, 0x66, 0x6c, 0x65, 0x63, 0x74, 0x65, + 0x64, 0x77, 0x61, 0x73, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x64, 0x6f, 0x72, 0x69, + 0x67, 0x69, 0x6e, 0x61, 0x6c, 0x20, 0x61, 0x20, 0x74, 0x79, 0x70, 0x69, 0x63, + 0x61, 0x6c, 0x77, 0x68, 0x65, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x79, 0x65, 0x6e, + 0x67, 0x69, 0x6e, 0x65, 0x65, 0x72, 0x73, 0x63, 0x6f, 0x75, 0x6c, 0x64, 0x20, + 0x6e, 0x6f, 0x74, 0x72, 0x65, 0x73, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x73, 0x77, + 0x65, 0x64, 0x6e, 0x65, 0x73, 0x64, 0x61, 0x79, 0x74, 0x68, 0x65, 0x20, 0x74, + 0x68, 0x69, 0x72, 0x64, 0x20, 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x73, + 0x4a, 0x61, 0x6e, 0x75, 0x61, 0x72, 0x79, 0x20, 0x32, 0x77, 0x68, 0x61, 0x74, + 0x20, 0x74, 0x68, 0x65, 0x79, 0x61, 0x20, 0x63, 0x65, 0x72, 0x74, 0x61, 0x69, + 0x6e, 0x72, 0x65, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x70, 0x72, 0x6f, + 0x63, 0x65, 0x73, 0x73, 0x6f, 0x72, 0x61, 0x66, 0x74, 0x65, 0x72, 0x20, 0x68, + 0x69, 0x73, 0x74, 0x68, 0x65, 0x20, 0x6c, 0x61, 0x73, 0x74, 0x20, 0x63, 0x6f, + 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x64, 0x22, 0x3e, 0x3c, 0x2f, 0x64, 0x69, + 0x76, 0x3e, 0x0a, 0x3c, 0x2f, 0x61, 0x3e, 0x3c, 0x2f, 0x74, 0x64, 0x3e, 0x64, + 0x65, 0x70, 0x65, 0x6e, 0x64, 0x20, 0x6f, 0x6e, 0x73, 0x65, 0x61, 0x72, 0x63, + 0x68, 0x22, 0x3e, 0x0a, 0x70, 0x69, 0x65, 0x63, 0x65, 0x73, 0x20, 0x6f, 0x66, + 0x63, 0x6f, 0x6d, 0x70, 0x65, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x66, 0x65, + 0x72, 0x65, 0x6e, 0x63, 0x65, 0x74, 0x65, 0x6e, 0x6e, 0x65, 0x73, 0x73, 0x65, + 0x65, 0x77, 0x68, 0x69, 0x63, 0x68, 0x20, 0x68, 0x61, 0x73, 0x20, 0x76, 0x65, + 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x3d, 0x3c, 0x2f, 0x73, 0x70, 0x61, 0x6e, 0x3e, + 0x20, 0x3c, 0x3c, 0x2f, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x3e, 0x67, 0x69, + 0x76, 0x65, 0x73, 0x20, 0x74, 0x68, 0x65, 0x68, 0x69, 0x73, 0x74, 0x6f, 0x72, + 0x69, 0x61, 0x6e, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3d, 0x22, 0x22, 0x3e, 0x70, + 0x61, 0x64, 0x64, 0x69, 0x6e, 0x67, 0x3a, 0x30, 0x76, 0x69, 0x65, 0x77, 0x20, + 0x74, 0x68, 0x61, 0x74, 0x74, 0x6f, 0x67, 0x65, 0x74, 0x68, 0x65, 0x72, 0x2c, + 0x74, 0x68, 0x65, 0x20, 0x6d, 0x6f, 0x73, 0x74, 0x20, 0x77, 0x61, 0x73, 0x20, + 0x66, 0x6f, 0x75, 0x6e, 0x64, 0x73, 0x75, 0x62, 0x73, 0x65, 0x74, 0x20, 0x6f, + 0x66, 0x61, 0x74, 0x74, 0x61, 0x63, 0x6b, 0x20, 0x6f, 0x6e, 0x63, 0x68, 0x69, + 0x6c, 0x64, 0x72, 0x65, 0x6e, 0x2c, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x73, 0x20, + 0x6f, 0x66, 0x70, 0x65, 0x72, 0x73, 0x6f, 0x6e, 0x61, 0x6c, 0x20, 0x70, 0x6f, + 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x61, 0x6c, 0x6c, 0x65, 0x67, 0x65, + 0x64, 0x6c, 0x79, 0x43, 0x6c, 0x65, 0x76, 0x65, 0x6c, 0x61, 0x6e, 0x64, 0x77, + 0x61, 0x73, 0x20, 0x6c, 0x61, 0x74, 0x65, 0x72, 0x61, 0x6e, 0x64, 0x20, 0x61, + 0x66, 0x74, 0x65, 0x72, 0x61, 0x72, 0x65, 0x20, 0x67, 0x69, 0x76, 0x65, 0x6e, + 0x77, 0x61, 0x73, 0x20, 0x73, 0x74, 0x69, 0x6c, 0x6c, 0x73, 0x63, 0x72, 0x6f, + 0x6c, 0x6c, 0x69, 0x6e, 0x67, 0x64, 0x65, 0x73, 0x69, 0x67, 0x6e, 0x20, 0x6f, + 0x66, 0x6d, 0x61, 0x6b, 0x65, 0x73, 0x20, 0x74, 0x68, 0x65, 0x6d, 0x75, 0x63, + 0x68, 0x20, 0x6c, 0x65, 0x73, 0x73, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, + 0x6e, 0x73, 0x2e, 0x0a, 0x0a, 0x41, 0x66, 0x74, 0x65, 0x72, 0x20, 0x2c, 0x20, + 0x62, 0x75, 0x74, 0x20, 0x74, 0x68, 0x65, 0x4d, 0x75, 0x73, 0x65, 0x75, 0x6d, + 0x20, 0x6f, 0x66, 0x6c, 0x6f, 0x75, 0x69, 0x73, 0x69, 0x61, 0x6e, 0x61, 0x28, + 0x66, 0x72, 0x6f, 0x6d, 0x20, 0x74, 0x68, 0x65, 0x6d, 0x69, 0x6e, 0x6e, 0x65, + 0x73, 0x6f, 0x74, 0x61, 0x70, 0x61, 0x72, 0x74, 0x69, 0x63, 0x6c, 0x65, 0x73, + 0x61, 0x20, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x44, 0x6f, 0x6d, 0x69, + 0x6e, 0x69, 0x63, 0x61, 0x6e, 0x76, 0x6f, 0x6c, 0x75, 0x6d, 0x65, 0x20, 0x6f, + 0x66, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x69, 0x6e, 0x67, 0x64, 0x65, 0x66, + 0x65, 0x6e, 0x73, 0x69, 0x76, 0x65, 0x30, 0x30, 0x70, 0x78, 0x7c, 0x72, 0x69, + 0x67, 0x68, 0x6d, 0x61, 0x64, 0x65, 0x20, 0x66, 0x72, 0x6f, 0x6d, 0x6d, 0x6f, + 0x75, 0x73, 0x65, 0x6f, 0x76, 0x65, 0x72, 0x22, 0x20, 0x73, 0x74, 0x79, 0x6c, + 0x65, 0x3d, 0x22, 0x73, 0x74, 0x61, 0x74, 0x65, 0x73, 0x20, 0x6f, 0x66, 0x28, + 0x77, 0x68, 0x69, 0x63, 0x68, 0x20, 0x69, 0x73, 0x63, 0x6f, 0x6e, 0x74, 0x69, + 0x6e, 0x75, 0x65, 0x73, 0x46, 0x72, 0x61, 0x6e, 0x63, 0x69, 0x73, 0x63, 0x6f, + 0x62, 0x75, 0x69, 0x6c, 0x64, 0x69, 0x6e, 0x67, 0x20, 0x77, 0x69, 0x74, 0x68, + 0x6f, 0x75, 0x74, 0x20, 0x61, 0x77, 0x69, 0x74, 0x68, 0x20, 0x73, 0x6f, 0x6d, + 0x65, 0x77, 0x68, 0x6f, 0x20, 0x77, 0x6f, 0x75, 0x6c, 0x64, 0x61, 0x20, 0x66, + 0x6f, 0x72, 0x6d, 0x20, 0x6f, 0x66, 0x61, 0x20, 0x70, 0x61, 0x72, 0x74, 0x20, + 0x6f, 0x66, 0x62, 0x65, 0x66, 0x6f, 0x72, 0x65, 0x20, 0x69, 0x74, 0x6b, 0x6e, + 0x6f, 0x77, 0x6e, 0x20, 0x61, 0x73, 0x20, 0x20, 0x53, 0x65, 0x72, 0x76, 0x69, + 0x63, 0x65, 0x73, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x61, + 0x6e, 0x64, 0x20, 0x6f, 0x66, 0x74, 0x65, 0x6e, 0x6d, 0x65, 0x61, 0x73, 0x75, + 0x72, 0x69, 0x6e, 0x67, 0x61, 0x6e, 0x64, 0x20, 0x69, 0x74, 0x20, 0x69, 0x73, + 0x70, 0x61, 0x70, 0x65, 0x72, 0x62, 0x61, 0x63, 0x6b, 0x76, 0x61, 0x6c, 0x75, + 0x65, 0x73, 0x20, 0x6f, 0x66, 0x0d, 0x0a, 0x3c, 0x74, 0x69, 0x74, 0x6c, 0x65, + 0x3e, 0x3d, 0x20, 0x77, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x2e, 0x64, 0x65, 0x74, + 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x65, 0x65, 0x72, 0x26, 0x71, 0x75, 0x6f, 0x74, + 0x3b, 0x20, 0x70, 0x6c, 0x61, 0x79, 0x65, 0x64, 0x20, 0x62, 0x79, 0x61, 0x6e, + 0x64, 0x20, 0x65, 0x61, 0x72, 0x6c, 0x79, 0x3c, 0x2f, 0x63, 0x65, 0x6e, 0x74, + 0x65, 0x72, 0x3e, 0x66, 0x72, 0x6f, 0x6d, 0x20, 0x74, 0x68, 0x69, 0x73, 0x74, + 0x68, 0x65, 0x20, 0x74, 0x68, 0x72, 0x65, 0x65, 0x70, 0x6f, 0x77, 0x65, 0x72, + 0x20, 0x61, 0x6e, 0x64, 0x6f, 0x66, 0x20, 0x26, 0x71, 0x75, 0x6f, 0x74, 0x3b, + 0x69, 0x6e, 0x6e, 0x65, 0x72, 0x48, 0x54, 0x4d, 0x4c, 0x3c, 0x61, 0x20, 0x68, + 0x72, 0x65, 0x66, 0x3d, 0x22, 0x79, 0x3a, 0x69, 0x6e, 0x6c, 0x69, 0x6e, 0x65, + 0x3b, 0x43, 0x68, 0x75, 0x72, 0x63, 0x68, 0x20, 0x6f, 0x66, 0x74, 0x68, 0x65, + 0x20, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x76, 0x65, 0x72, 0x79, 0x20, 0x68, 0x69, + 0x67, 0x68, 0x6f, 0x66, 0x66, 0x69, 0x63, 0x69, 0x61, 0x6c, 0x20, 0x2d, 0x68, + 0x65, 0x69, 0x67, 0x68, 0x74, 0x3a, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, + 0x74, 0x3d, 0x22, 0x2f, 0x63, 0x67, 0x69, 0x2d, 0x62, 0x69, 0x6e, 0x2f, 0x74, + 0x6f, 0x20, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x61, 0x66, 0x72, 0x69, 0x6b, + 0x61, 0x61, 0x6e, 0x73, 0x65, 0x73, 0x70, 0x65, 0x72, 0x61, 0x6e, 0x74, 0x6f, + 0x66, 0x72, 0x61, 0x6e, 0xc3, 0xa7, 0x61, 0x69, 0x73, 0x6c, 0x61, 0x74, 0x76, + 0x69, 0x65, 0xc5, 0xa1, 0x75, 0x6c, 0x69, 0x65, 0x74, 0x75, 0x76, 0x69, 0xc5, + 0xb3, 0xc4, 0x8c, 0x65, 0xc5, 0xa1, 0x74, 0x69, 0x6e, 0x61, 0xc4, 0x8d, 0x65, + 0xc5, 0xa1, 0x74, 0x69, 0x6e, 0x61, 0xe0, 0xb9, 0x84, 0xe0, 0xb8, 0x97, 0xe0, + 0xb8, 0xa2, 0xe6, 0x97, 0xa5, 0xe6, 0x9c, 0xac, 0xe8, 0xaa, 0x9e, 0xe7, 0xae, + 0x80, 0xe4, 0xbd, 0x93, 0xe5, 0xad, 0x97, 0xe7, 0xb9, 0x81, 0xe9, 0xab, 0x94, + 0xe5, 0xad, 0x97, 0xed, 0x95, 0x9c, 0xea, 0xb5, 0xad, 0xec, 0x96, 0xb4, 0xe4, + 0xb8, 0xba, 0xe4, 0xbb, 0x80, 0xe4, 0xb9, 0x88, 0xe8, 0xae, 0xa1, 0xe7, 0xae, + 0x97, 0xe6, 0x9c, 0xba, 0xe7, 0xac, 0x94, 0xe8, 0xae, 0xb0, 0xe6, 0x9c, 0xac, + 0xe8, 0xa8, 0x8e, 0xe8, 0xab, 0x96, 0xe5, 0x8d, 0x80, 0xe6, 0x9c, 0x8d, 0xe5, + 0x8a, 0xa1, 0xe5, 0x99, 0xa8, 0xe4, 0xba, 0x92, 0xe8, 0x81, 0x94, 0xe7, 0xbd, + 0x91, 0xe6, 0x88, 0xbf, 0xe5, 0x9c, 0xb0, 0xe4, 0xba, 0xa7, 0xe4, 0xbf, 0xb1, + 0xe4, 0xb9, 0x90, 0xe9, 0x83, 0xa8, 0xe5, 0x87, 0xba, 0xe7, 0x89, 0x88, 0xe7, + 0xa4, 0xbe, 0xe6, 0x8e, 0x92, 0xe8, 0xa1, 0x8c, 0xe6, 0xa6, 0x9c, 0xe9, 0x83, + 0xa8, 0xe8, 0x90, 0xbd, 0xe6, 0xa0, 0xbc, 0xe8, 0xbf, 0x9b, 0xe4, 0xb8, 0x80, + 0xe6, 0xad, 0xa5, 0xe6, 0x94, 0xaf, 0xe4, 0xbb, 0x98, 0xe5, 0xae, 0x9d, 0xe9, + 0xaa, 0x8c, 0xe8, 0xaf, 0x81, 0xe7, 0xa0, 0x81, 0xe5, 0xa7, 0x94, 0xe5, 0x91, + 0x98, 0xe4, 0xbc, 0x9a, 0xe6, 0x95, 0xb0, 0xe6, 0x8d, 0xae, 0xe5, 0xba, 0x93, + 0xe6, 0xb6, 0x88, 0xe8, 0xb4, 0xb9, 0xe8, 0x80, 0x85, 0xe5, 0x8a, 0x9e, 0xe5, + 0x85, 0xac, 0xe5, 0xae, 0xa4, 0xe8, 0xae, 0xa8, 0xe8, 0xae, 0xba, 0xe5, 0x8c, + 0xba, 0xe6, 0xb7, 0xb1, 0xe5, 0x9c, 0xb3, 0xe5, 0xb8, 0x82, 0xe6, 0x92, 0xad, + 0xe6, 0x94, 0xbe, 0xe5, 0x99, 0xa8, 0xe5, 0x8c, 0x97, 0xe4, 0xba, 0xac, 0xe5, + 0xb8, 0x82, 0xe5, 0xa4, 0xa7, 0xe5, 0xad, 0xa6, 0xe7, 0x94, 0x9f, 0xe8, 0xb6, + 0x8a, 0xe6, 0x9d, 0xa5, 0xe8, 0xb6, 0x8a, 0xe7, 0xae, 0xa1, 0xe7, 0x90, 0x86, + 0xe5, 0x91, 0x98, 0xe4, 0xbf, 0xa1, 0xe6, 0x81, 0xaf, 0xe7, 0xbd, 0x91, 0x73, + 0x65, 0x72, 0x76, 0x69, 0x63, 0x69, 0x6f, 0x73, 0x61, 0x72, 0x74, 0xc3, 0xad, + 0x63, 0x75, 0x6c, 0x6f, 0x61, 0x72, 0x67, 0x65, 0x6e, 0x74, 0x69, 0x6e, 0x61, + 0x62, 0x61, 0x72, 0x63, 0x65, 0x6c, 0x6f, 0x6e, 0x61, 0x63, 0x75, 0x61, 0x6c, + 0x71, 0x75, 0x69, 0x65, 0x72, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x61, 0x64, + 0x6f, 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x6f, 0x73, 0x70, 0x6f, 0x6c, + 0xc3, 0xad, 0x74, 0x69, 0x63, 0x61, 0x72, 0x65, 0x73, 0x70, 0x75, 0x65, 0x73, + 0x74, 0x61, 0x77, 0x69, 0x6b, 0x69, 0x70, 0x65, 0x64, 0x69, 0x61, 0x73, 0x69, + 0x67, 0x75, 0x69, 0x65, 0x6e, 0x74, 0x65, 0x62, 0xc3, 0xba, 0x73, 0x71, 0x75, + 0x65, 0x64, 0x61, 0x63, 0x6f, 0x6d, 0x75, 0x6e, 0x69, 0x64, 0x61, 0x64, 0x73, + 0x65, 0x67, 0x75, 0x72, 0x69, 0x64, 0x61, 0x64, 0x70, 0x72, 0x69, 0x6e, 0x63, + 0x69, 0x70, 0x61, 0x6c, 0x70, 0x72, 0x65, 0x67, 0x75, 0x6e, 0x74, 0x61, 0x73, + 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x69, 0x64, 0x6f, 0x72, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x64, 0x65, 0x72, 0x76, 0x65, 0x6e, 0x65, 0x7a, 0x75, 0x65, 0x6c, + 0x61, 0x70, 0x72, 0x6f, 0x62, 0x6c, 0x65, 0x6d, 0x61, 0x73, 0x64, 0x69, 0x63, + 0x69, 0x65, 0x6d, 0x62, 0x72, 0x65, 0x72, 0x65, 0x6c, 0x61, 0x63, 0x69, 0xc3, + 0xb3, 0x6e, 0x6e, 0x6f, 0x76, 0x69, 0x65, 0x6d, 0x62, 0x72, 0x65, 0x73, 0x69, + 0x6d, 0x69, 0x6c, 0x61, 0x72, 0x65, 0x73, 0x70, 0x72, 0x6f, 0x79, 0x65, 0x63, + 0x74, 0x6f, 0x73, 0x70, 0x72, 0x6f, 0x67, 0x72, 0x61, 0x6d, 0x61, 0x73, 0x69, + 0x6e, 0x73, 0x74, 0x69, 0x74, 0x75, 0x74, 0x6f, 0x61, 0x63, 0x74, 0x69, 0x76, + 0x69, 0x64, 0x61, 0x64, 0x65, 0x6e, 0x63, 0x75, 0x65, 0x6e, 0x74, 0x72, 0x61, + 0x65, 0x63, 0x6f, 0x6e, 0x6f, 0x6d, 0xc3, 0xad, 0x61, 0x69, 0x6d, 0xc3, 0xa1, + 0x67, 0x65, 0x6e, 0x65, 0x73, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x63, 0x74, 0x61, + 0x72, 0x64, 0x65, 0x73, 0x63, 0x61, 0x72, 0x67, 0x61, 0x72, 0x6e, 0x65, 0x63, + 0x65, 0x73, 0x61, 0x72, 0x69, 0x6f, 0x61, 0x74, 0x65, 0x6e, 0x63, 0x69, 0xc3, + 0xb3, 0x6e, 0x74, 0x65, 0x6c, 0xc3, 0xa9, 0x66, 0x6f, 0x6e, 0x6f, 0x63, 0x6f, + 0x6d, 0x69, 0x73, 0x69, 0xc3, 0xb3, 0x6e, 0x63, 0x61, 0x6e, 0x63, 0x69, 0x6f, + 0x6e, 0x65, 0x73, 0x63, 0x61, 0x70, 0x61, 0x63, 0x69, 0x64, 0x61, 0x64, 0x65, + 0x6e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x72, 0x61, 0x6e, 0xc3, 0xa1, 0x6c, + 0x69, 0x73, 0x69, 0x73, 0x66, 0x61, 0x76, 0x6f, 0x72, 0x69, 0x74, 0x6f, 0x73, + 0x74, 0xc3, 0xa9, 0x72, 0x6d, 0x69, 0x6e, 0x6f, 0x73, 0x70, 0x72, 0x6f, 0x76, + 0x69, 0x6e, 0x63, 0x69, 0x61, 0x65, 0x74, 0x69, 0x71, 0x75, 0x65, 0x74, 0x61, + 0x73, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x6f, 0x73, 0x66, 0x75, 0x6e, + 0x63, 0x69, 0x6f, 0x6e, 0x65, 0x73, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x61, + 0x64, 0x6f, 0x63, 0x61, 0x72, 0xc3, 0xa1, 0x63, 0x74, 0x65, 0x72, 0x70, 0x72, + 0x6f, 0x70, 0x69, 0x65, 0x64, 0x61, 0x64, 0x70, 0x72, 0x69, 0x6e, 0x63, 0x69, + 0x70, 0x69, 0x6f, 0x6e, 0x65, 0x63, 0x65, 0x73, 0x69, 0x64, 0x61, 0x64, 0x6d, + 0x75, 0x6e, 0x69, 0x63, 0x69, 0x70, 0x61, 0x6c, 0x63, 0x72, 0x65, 0x61, 0x63, + 0x69, 0xc3, 0xb3, 0x6e, 0x64, 0x65, 0x73, 0x63, 0x61, 0x72, 0x67, 0x61, 0x73, + 0x70, 0x72, 0x65, 0x73, 0x65, 0x6e, 0x63, 0x69, 0x61, 0x63, 0x6f, 0x6d, 0x65, + 0x72, 0x63, 0x69, 0x61, 0x6c, 0x6f, 0x70, 0x69, 0x6e, 0x69, 0x6f, 0x6e, 0x65, + 0x73, 0x65, 0x6a, 0x65, 0x72, 0x63, 0x69, 0x63, 0x69, 0x6f, 0x65, 0x64, 0x69, + 0x74, 0x6f, 0x72, 0x69, 0x61, 0x6c, 0x73, 0x61, 0x6c, 0x61, 0x6d, 0x61, 0x6e, + 0x63, 0x61, 0x67, 0x6f, 0x6e, 0x7a, 0xc3, 0xa1, 0x6c, 0x65, 0x7a, 0x64, 0x6f, + 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x6f, 0x70, 0x65, 0x6c, 0xc3, 0xad, 0x63, + 0x75, 0x6c, 0x61, 0x72, 0x65, 0x63, 0x69, 0x65, 0x6e, 0x74, 0x65, 0x73, 0x67, + 0x65, 0x6e, 0x65, 0x72, 0x61, 0x6c, 0x65, 0x73, 0x74, 0x61, 0x72, 0x72, 0x61, + 0x67, 0x6f, 0x6e, 0x61, 0x70, 0x72, 0xc3, 0xa1, 0x63, 0x74, 0x69, 0x63, 0x61, + 0x6e, 0x6f, 0x76, 0x65, 0x64, 0x61, 0x64, 0x65, 0x73, 0x70, 0x72, 0x6f, 0x70, + 0x75, 0x65, 0x73, 0x74, 0x61, 0x70, 0x61, 0x63, 0x69, 0x65, 0x6e, 0x74, 0x65, + 0x73, 0x74, 0xc3, 0xa9, 0x63, 0x6e, 0x69, 0x63, 0x61, 0x73, 0x6f, 0x62, 0x6a, + 0x65, 0x74, 0x69, 0x76, 0x6f, 0x73, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x63, 0x74, + 0x6f, 0x73, 0xe0, 0xa4, 0xae, 0xe0, 0xa5, 0x87, 0xe0, 0xa4, 0x82, 0xe0, 0xa4, + 0xb2, 0xe0, 0xa4, 0xbf, 0xe0, 0xa4, 0x8f, 0xe0, 0xa4, 0xb9, 0xe0, 0xa5, 0x88, + 0xe0, 0xa4, 0x82, 0xe0, 0xa4, 0x97, 0xe0, 0xa4, 0xaf, 0xe0, 0xa4, 0xbe, 0xe0, + 0xa4, 0xb8, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, 0xa5, 0xe0, 0xa4, 0x8f, 0xe0, 0xa4, + 0xb5, 0xe0, 0xa4, 0x82, 0xe0, 0xa4, 0xb0, 0xe0, 0xa4, 0xb9, 0xe0, 0xa5, 0x87, + 0xe0, 0xa4, 0x95, 0xe0, 0xa5, 0x8b, 0xe0, 0xa4, 0x88, 0xe0, 0xa4, 0x95, 0xe0, + 0xa5, 0x81, 0xe0, 0xa4, 0x9b, 0xe0, 0xa4, 0xb0, 0xe0, 0xa4, 0xb9, 0xe0, 0xa4, + 0xbe, 0xe0, 0xa4, 0xac, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, 0xa6, 0xe0, 0xa4, 0x95, + 0xe0, 0xa4, 0xb9, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, 0xb8, 0xe0, 0xa4, 0xad, 0xe0, + 0xa5, 0x80, 0xe0, 0xa4, 0xb9, 0xe0, 0xa5, 0x81, 0xe0, 0xa4, 0x8f, 0xe0, 0xa4, + 0xb0, 0xe0, 0xa4, 0xb9, 0xe0, 0xa5, 0x80, 0xe0, 0xa4, 0xae, 0xe0, 0xa5, 0x88, + 0xe0, 0xa4, 0x82, 0xe0, 0xa4, 0xa6, 0xe0, 0xa4, 0xbf, 0xe0, 0xa4, 0xa8, 0xe0, + 0xa4, 0xac, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, 0xa4, 0x64, 0x69, 0x70, 0x6c, 0x6f, + 0x64, 0x6f, 0x63, 0x73, 0xe0, 0xa4, 0xb8, 0xe0, 0xa4, 0xae, 0xe0, 0xa4, 0xaf, + 0xe0, 0xa4, 0xb0, 0xe0, 0xa5, 0x82, 0xe0, 0xa4, 0xaa, 0xe0, 0xa4, 0xa8, 0xe0, + 0xa4, 0xbe, 0xe0, 0xa4, 0xae, 0xe0, 0xa4, 0xaa, 0xe0, 0xa4, 0xa4, 0xe0, 0xa4, + 0xbe, 0xe0, 0xa4, 0xab, 0xe0, 0xa4, 0xbf, 0xe0, 0xa4, 0xb0, 0xe0, 0xa4, 0x94, + 0xe0, 0xa4, 0xb8, 0xe0, 0xa4, 0xa4, 0xe0, 0xa4, 0xa4, 0xe0, 0xa4, 0xb0, 0xe0, + 0xa4, 0xb9, 0xe0, 0xa4, 0xb2, 0xe0, 0xa5, 0x8b, 0xe0, 0xa4, 0x97, 0xe0, 0xa4, + 0xb9, 0xe0, 0xa5, 0x81, 0xe0, 0xa4, 0x86, 0xe0, 0xa4, 0xac, 0xe0, 0xa4, 0xbe, + 0xe0, 0xa4, 0xb0, 0xe0, 0xa4, 0xa6, 0xe0, 0xa5, 0x87, 0xe0, 0xa4, 0xb6, 0xe0, + 0xa4, 0xb9, 0xe0, 0xa5, 0x81, 0xe0, 0xa4, 0x88, 0xe0, 0xa4, 0x96, 0xe0, 0xa5, + 0x87, 0xe0, 0xa4, 0xb2, 0xe0, 0xa4, 0xaf, 0xe0, 0xa4, 0xa6, 0xe0, 0xa4, 0xbf, + 0xe0, 0xa4, 0x95, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, 0xae, 0xe0, 0xa4, 0xb5, 0xe0, + 0xa5, 0x87, 0xe0, 0xa4, 0xac, 0xe0, 0xa4, 0xa4, 0xe0, 0xa5, 0x80, 0xe0, 0xa4, + 0xa8, 0xe0, 0xa4, 0xac, 0xe0, 0xa5, 0x80, 0xe0, 0xa4, 0x9a, 0xe0, 0xa4, 0xae, + 0xe0, 0xa5, 0x8c, 0xe0, 0xa4, 0xa4, 0xe0, 0xa4, 0xb8, 0xe0, 0xa4, 0xbe, 0xe0, + 0xa4, 0xb2, 0xe0, 0xa4, 0xb2, 0xe0, 0xa5, 0x87, 0xe0, 0xa4, 0x96, 0xe0, 0xa4, + 0x9c, 0xe0, 0xa5, 0x89, 0xe0, 0xa4, 0xac, 0xe0, 0xa4, 0xae, 0xe0, 0xa4, 0xa6, + 0xe0, 0xa4, 0xa6, 0xe0, 0xa4, 0xa4, 0xe0, 0xa4, 0xa5, 0xe0, 0xa4, 0xbe, 0xe0, + 0xa4, 0xa8, 0xe0, 0xa4, 0xb9, 0xe0, 0xa5, 0x80, 0xe0, 0xa4, 0xb6, 0xe0, 0xa4, + 0xb9, 0xe0, 0xa4, 0xb0, 0xe0, 0xa4, 0x85, 0xe0, 0xa4, 0xb2, 0xe0, 0xa4, 0x97, + 0xe0, 0xa4, 0x95, 0xe0, 0xa4, 0xad, 0xe0, 0xa5, 0x80, 0xe0, 0xa4, 0xa8, 0xe0, + 0xa4, 0x97, 0xe0, 0xa4, 0xb0, 0xe0, 0xa4, 0xaa, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, + 0xb8, 0xe0, 0xa4, 0xb0, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, 0xa4, 0xe0, 0xa4, 0x95, + 0xe0, 0xa4, 0xbf, 0xe0, 0xa4, 0x8f, 0xe0, 0xa4, 0x89, 0xe0, 0xa4, 0xb8, 0xe0, + 0xa5, 0x87, 0xe0, 0xa4, 0x97, 0xe0, 0xa4, 0xaf, 0xe0, 0xa5, 0x80, 0xe0, 0xa4, + 0xb9, 0xe0, 0xa5, 0x82, 0xe0, 0xa4, 0x81, 0xe0, 0xa4, 0x86, 0xe0, 0xa4, 0x97, + 0xe0, 0xa5, 0x87, 0xe0, 0xa4, 0x9f, 0xe0, 0xa5, 0x80, 0xe0, 0xa4, 0xae, 0xe0, + 0xa4, 0x96, 0xe0, 0xa5, 0x8b, 0xe0, 0xa4, 0x9c, 0xe0, 0xa4, 0x95, 0xe0, 0xa4, + 0xbe, 0xe0, 0xa4, 0xb0, 0xe0, 0xa4, 0x85, 0xe0, 0xa4, 0xad, 0xe0, 0xa5, 0x80, + 0xe0, 0xa4, 0x97, 0xe0, 0xa4, 0xaf, 0xe0, 0xa5, 0x87, 0xe0, 0xa4, 0xa4, 0xe0, + 0xa5, 0x81, 0xe0, 0xa4, 0xae, 0xe0, 0xa4, 0xb5, 0xe0, 0xa5, 0x8b, 0xe0, 0xa4, + 0x9f, 0xe0, 0xa4, 0xa6, 0xe0, 0xa5, 0x87, 0xe0, 0xa4, 0x82, 0xe0, 0xa4, 0x85, + 0xe0, 0xa4, 0x97, 0xe0, 0xa4, 0xb0, 0xe0, 0xa4, 0x90, 0xe0, 0xa4, 0xb8, 0xe0, + 0xa5, 0x87, 0xe0, 0xa4, 0xae, 0xe0, 0xa5, 0x87, 0xe0, 0xa4, 0xb2, 0xe0, 0xa4, + 0xb2, 0xe0, 0xa4, 0x97, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, 0xb9, 0xe0, 0xa4, 0xbe, + 0xe0, 0xa4, 0xb2, 0xe0, 0xa4, 0x8a, 0xe0, 0xa4, 0xaa, 0xe0, 0xa4, 0xb0, 0xe0, + 0xa4, 0x9a, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, 0xb0, 0xe0, 0xa4, 0x90, 0xe0, 0xa4, + 0xb8, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, 0xa6, 0xe0, 0xa5, 0x87, 0xe0, 0xa4, 0xb0, + 0xe0, 0xa4, 0x9c, 0xe0, 0xa4, 0xbf, 0xe0, 0xa4, 0xb8, 0xe0, 0xa4, 0xa6, 0xe0, + 0xa4, 0xbf, 0xe0, 0xa4, 0xb2, 0xe0, 0xa4, 0xac, 0xe0, 0xa4, 0x82, 0xe0, 0xa4, + 0xa6, 0xe0, 0xa4, 0xac, 0xe0, 0xa4, 0xa8, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, 0xb9, + 0xe0, 0xa5, 0x82, 0xe0, 0xa4, 0x82, 0xe0, 0xa4, 0xb2, 0xe0, 0xa4, 0xbe, 0xe0, + 0xa4, 0x96, 0xe0, 0xa4, 0x9c, 0xe0, 0xa5, 0x80, 0xe0, 0xa4, 0xa4, 0xe0, 0xa4, + 0xac, 0xe0, 0xa4, 0x9f, 0xe0, 0xa4, 0xa8, 0xe0, 0xa4, 0xae, 0xe0, 0xa4, 0xbf, + 0xe0, 0xa4, 0xb2, 0xe0, 0xa4, 0x87, 0xe0, 0xa4, 0xb8, 0xe0, 0xa5, 0x87, 0xe0, + 0xa4, 0x86, 0xe0, 0xa4, 0xa8, 0xe0, 0xa5, 0x87, 0xe0, 0xa4, 0xa8, 0xe0, 0xa4, + 0xaf, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, 0x95, 0xe0, 0xa5, 0x81, 0xe0, 0xa4, 0xb2, + 0xe0, 0xa4, 0xb2, 0xe0, 0xa5, 0x89, 0xe0, 0xa4, 0x97, 0xe0, 0xa4, 0xad, 0xe0, + 0xa4, 0xbe, 0xe0, 0xa4, 0x97, 0xe0, 0xa4, 0xb0, 0xe0, 0xa5, 0x87, 0xe0, 0xa4, + 0xb2, 0xe0, 0xa4, 0x9c, 0xe0, 0xa4, 0x97, 0xe0, 0xa4, 0xb9, 0xe0, 0xa4, 0xb0, + 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, 0xae, 0xe0, 0xa4, 0xb2, 0xe0, 0xa4, 0x97, 0xe0, + 0xa5, 0x87, 0xe0, 0xa4, 0xaa, 0xe0, 0xa5, 0x87, 0xe0, 0xa4, 0x9c, 0xe0, 0xa4, + 0xb9, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, 0xa5, 0xe0, 0xa4, 0x87, 0xe0, 0xa4, 0xb8, + 0xe0, 0xa5, 0x80, 0xe0, 0xa4, 0xb8, 0xe0, 0xa4, 0xb9, 0xe0, 0xa5, 0x80, 0xe0, + 0xa4, 0x95, 0xe0, 0xa4, 0xb2, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, 0xa0, 0xe0, 0xa5, + 0x80, 0xe0, 0xa4, 0x95, 0xe0, 0xa4, 0xb9, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, 0x81, + 0xe0, 0xa4, 0xa6, 0xe0, 0xa5, 0x82, 0xe0, 0xa4, 0xb0, 0xe0, 0xa4, 0xa4, 0xe0, + 0xa4, 0xb9, 0xe0, 0xa4, 0xa4, 0xe0, 0xa4, 0xb8, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, + 0xa4, 0xe0, 0xa4, 0xaf, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, 0xa6, 0xe0, 0xa4, 0x86, + 0xe0, 0xa4, 0xaf, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, 0xaa, 0xe0, 0xa4, 0xbe, 0xe0, + 0xa4, 0x95, 0xe0, 0xa4, 0x95, 0xe0, 0xa5, 0x8c, 0xe0, 0xa4, 0xa8, 0xe0, 0xa4, + 0xb6, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, 0xae, 0xe0, 0xa4, 0xa6, 0xe0, 0xa5, 0x87, + 0xe0, 0xa4, 0x96, 0xe0, 0xa4, 0xaf, 0xe0, 0xa4, 0xb9, 0xe0, 0xa5, 0x80, 0xe0, + 0xa4, 0xb0, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, 0xaf, 0xe0, 0xa4, 0x96, 0xe0, 0xa5, + 0x81, 0xe0, 0xa4, 0xa6, 0xe0, 0xa4, 0xb2, 0xe0, 0xa4, 0x97, 0xe0, 0xa5, 0x80, + 0x63, 0x61, 0x74, 0x65, 0x67, 0x6f, 0x72, 0x69, 0x65, 0x73, 0x65, 0x78, 0x70, + 0x65, 0x72, 0x69, 0x65, 0x6e, 0x63, 0x65, 0x3c, 0x2f, 0x74, 0x69, 0x74, 0x6c, + 0x65, 0x3e, 0x0d, 0x0a, 0x43, 0x6f, 0x70, 0x79, 0x72, 0x69, 0x67, 0x68, 0x74, + 0x20, 0x6a, 0x61, 0x76, 0x61, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x63, 0x6f, + 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x65, 0x76, 0x65, 0x72, 0x79, + 0x74, 0x68, 0x69, 0x6e, 0x67, 0x3c, 0x70, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, + 0x3d, 0x22, 0x74, 0x65, 0x63, 0x68, 0x6e, 0x6f, 0x6c, 0x6f, 0x67, 0x79, 0x62, + 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x3c, 0x61, 0x20, 0x63, + 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x22, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, + 0x65, 0x6e, 0x74, 0x26, 0x63, 0x6f, 0x70, 0x79, 0x3b, 0x20, 0x32, 0x30, 0x31, + 0x6a, 0x61, 0x76, 0x61, 0x53, 0x63, 0x72, 0x69, 0x70, 0x74, 0x63, 0x68, 0x61, + 0x72, 0x61, 0x63, 0x74, 0x65, 0x72, 0x73, 0x62, 0x72, 0x65, 0x61, 0x64, 0x63, + 0x72, 0x75, 0x6d, 0x62, 0x74, 0x68, 0x65, 0x6d, 0x73, 0x65, 0x6c, 0x76, 0x65, + 0x73, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x6f, 0x6e, 0x74, 0x61, 0x6c, 0x67, 0x6f, + 0x76, 0x65, 0x72, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x43, 0x61, 0x6c, 0x69, 0x66, + 0x6f, 0x72, 0x6e, 0x69, 0x61, 0x61, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x69, + 0x65, 0x73, 0x64, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x65, 0x64, 0x4e, + 0x61, 0x76, 0x69, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x6e, + 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x6e, 0x61, 0x76, 0x69, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x61, 0x70, 0x70, 0x65, 0x61, 0x72, 0x61, 0x6e, 0x63, 0x65, 0x3c, 0x2f, 0x74, + 0x69, 0x74, 0x6c, 0x65, 0x3e, 0x3c, 0x6d, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x62, + 0x6f, 0x78, 0x22, 0x20, 0x74, 0x65, 0x63, 0x68, 0x6e, 0x69, 0x71, 0x75, 0x65, + 0x73, 0x70, 0x72, 0x6f, 0x74, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x70, + 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x6c, 0x79, 0x61, 0x73, 0x20, 0x77, 0x65, + 0x6c, 0x6c, 0x20, 0x61, 0x73, 0x75, 0x6e, 0x74, 0x27, 0x2c, 0x20, 0x27, 0x55, + 0x41, 0x2d, 0x72, 0x65, 0x73, 0x6f, 0x6c, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x6f, + 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x74, 0x65, 0x6c, 0x65, + 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x6c, 0x61, + 0x74, 0x65, 0x64, 0x57, 0x61, 0x73, 0x68, 0x69, 0x6e, 0x67, 0x74, 0x6f, 0x6e, + 0x6e, 0x61, 0x76, 0x69, 0x67, 0x61, 0x74, 0x6f, 0x72, 0x2e, 0x20, 0x3d, 0x20, + 0x77, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x2e, 0x69, 0x6d, 0x70, 0x72, 0x65, 0x73, + 0x73, 0x69, 0x6f, 0x6e, 0x26, 0x6c, 0x74, 0x3b, 0x62, 0x72, 0x26, 0x67, 0x74, + 0x3b, 0x6c, 0x69, 0x74, 0x65, 0x72, 0x61, 0x74, 0x75, 0x72, 0x65, 0x70, 0x6f, + 0x70, 0x75, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x62, 0x67, 0x63, 0x6f, 0x6c, + 0x6f, 0x72, 0x3d, 0x22, 0x23, 0x65, 0x73, 0x70, 0x65, 0x63, 0x69, 0x61, 0x6c, + 0x6c, 0x79, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x3d, 0x22, 0x70, + 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x6e, 0x65, 0x77, 0x73, + 0x6c, 0x65, 0x74, 0x74, 0x65, 0x72, 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, + 0x69, 0x65, 0x73, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, + 0x6c, 0x65, 0x61, 0x64, 0x65, 0x72, 0x73, 0x68, 0x69, 0x70, 0x54, 0x65, 0x63, + 0x68, 0x6e, 0x6f, 0x6c, 0x6f, 0x67, 0x79, 0x50, 0x61, 0x72, 0x6c, 0x69, 0x61, + 0x6d, 0x65, 0x6e, 0x74, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x72, 0x69, 0x73, 0x6f, + 0x6e, 0x75, 0x6c, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x22, 0x2e, 0x69, + 0x6e, 0x64, 0x65, 0x78, 0x4f, 0x66, 0x28, 0x22, 0x63, 0x6f, 0x6e, 0x63, 0x6c, + 0x75, 0x73, 0x69, 0x6f, 0x6e, 0x64, 0x69, 0x73, 0x63, 0x75, 0x73, 0x73, 0x69, + 0x6f, 0x6e, 0x63, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x73, 0x62, + 0x69, 0x6f, 0x6c, 0x6f, 0x67, 0x69, 0x63, 0x61, 0x6c, 0x52, 0x65, 0x76, 0x6f, + 0x6c, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, + 0x6e, 0x65, 0x72, 0x75, 0x6e, 0x64, 0x65, 0x72, 0x73, 0x74, 0x6f, 0x6f, 0x64, + 0x6e, 0x6f, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x3e, 0x3c, 0x70, 0x65, 0x72, + 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x61, 0x63, 0x68, 0x20, 0x6f, + 0x74, 0x68, 0x65, 0x72, 0x61, 0x74, 0x6d, 0x6f, 0x73, 0x70, 0x68, 0x65, 0x72, + 0x65, 0x20, 0x6f, 0x6e, 0x66, 0x6f, 0x63, 0x75, 0x73, 0x3d, 0x22, 0x3c, 0x66, + 0x6f, 0x72, 0x6d, 0x20, 0x69, 0x64, 0x3d, 0x22, 0x70, 0x72, 0x6f, 0x63, 0x65, + 0x73, 0x73, 0x69, 0x6e, 0x67, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x76, 0x61, 0x6c, + 0x75, 0x65, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x43, + 0x6f, 0x6e, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x73, 0x75, 0x62, 0x73, + 0x65, 0x71, 0x75, 0x65, 0x6e, 0x74, 0x77, 0x65, 0x6c, 0x6c, 0x2d, 0x6b, 0x6e, + 0x6f, 0x77, 0x6e, 0x76, 0x61, 0x72, 0x69, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, + 0x72, 0x65, 0x70, 0x75, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x70, 0x68, 0x65, + 0x6e, 0x6f, 0x6d, 0x65, 0x6e, 0x6f, 0x6e, 0x64, 0x69, 0x73, 0x63, 0x69, 0x70, + 0x6c, 0x69, 0x6e, 0x65, 0x6c, 0x6f, 0x67, 0x6f, 0x2e, 0x70, 0x6e, 0x67, 0x22, + 0x20, 0x28, 0x64, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x2c, 0x62, 0x6f, + 0x75, 0x6e, 0x64, 0x61, 0x72, 0x69, 0x65, 0x73, 0x65, 0x78, 0x70, 0x72, 0x65, + 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x65, 0x74, 0x74, 0x6c, 0x65, 0x6d, 0x65, + 0x6e, 0x74, 0x42, 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x6f, + 0x75, 0x74, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x65, 0x6e, 0x74, 0x65, + 0x72, 0x70, 0x72, 0x69, 0x73, 0x65, 0x28, 0x22, 0x68, 0x74, 0x74, 0x70, 0x73, + 0x3a, 0x22, 0x20, 0x75, 0x6e, 0x65, 0x73, 0x63, 0x61, 0x70, 0x65, 0x28, 0x22, + 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x22, 0x20, 0x64, 0x65, 0x6d, + 0x6f, 0x63, 0x72, 0x61, 0x74, 0x69, 0x63, 0x3c, 0x61, 0x20, 0x68, 0x72, 0x65, + 0x66, 0x3d, 0x22, 0x2f, 0x77, 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, 0x22, 0x3e, + 0x0a, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x68, 0x69, 0x70, 0x6c, 0x69, + 0x6e, 0x67, 0x75, 0x69, 0x73, 0x74, 0x69, 0x63, 0x70, 0x78, 0x3b, 0x70, 0x61, + 0x64, 0x64, 0x69, 0x6e, 0x67, 0x70, 0x68, 0x69, 0x6c, 0x6f, 0x73, 0x6f, 0x70, + 0x68, 0x79, 0x61, 0x73, 0x73, 0x69, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x75, + 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x69, 0x74, 0x79, 0x66, 0x61, 0x63, 0x69, + 0x6c, 0x69, 0x74, 0x69, 0x65, 0x73, 0x72, 0x65, 0x63, 0x6f, 0x67, 0x6e, 0x69, + 0x7a, 0x65, 0x64, 0x70, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, + 0x69, 0x66, 0x20, 0x28, 0x74, 0x79, 0x70, 0x65, 0x6f, 0x66, 0x6d, 0x61, 0x69, + 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x64, 0x76, 0x6f, 0x63, 0x61, 0x62, 0x75, + 0x6c, 0x61, 0x72, 0x79, 0x68, 0x79, 0x70, 0x6f, 0x74, 0x68, 0x65, 0x73, 0x69, + 0x73, 0x2e, 0x73, 0x75, 0x62, 0x6d, 0x69, 0x74, 0x28, 0x29, 0x3b, 0x26, 0x61, + 0x6d, 0x70, 0x3b, 0x6e, 0x62, 0x73, 0x70, 0x3b, 0x61, 0x6e, 0x6e, 0x6f, 0x74, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x62, 0x65, 0x68, 0x69, 0x6e, 0x64, 0x20, 0x74, + 0x68, 0x65, 0x46, 0x6f, 0x75, 0x6e, 0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x70, + 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x65, 0x72, 0x22, 0x61, 0x73, 0x73, 0x75, + 0x6d, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x69, 0x6e, 0x74, 0x72, 0x6f, 0x64, 0x75, + 0x63, 0x65, 0x64, 0x63, 0x6f, 0x72, 0x72, 0x75, 0x70, 0x74, 0x69, 0x6f, 0x6e, + 0x73, 0x63, 0x69, 0x65, 0x6e, 0x74, 0x69, 0x73, 0x74, 0x73, 0x65, 0x78, 0x70, + 0x6c, 0x69, 0x63, 0x69, 0x74, 0x6c, 0x79, 0x69, 0x6e, 0x73, 0x74, 0x65, 0x61, + 0x64, 0x20, 0x6f, 0x66, 0x64, 0x69, 0x6d, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, + 0x73, 0x20, 0x6f, 0x6e, 0x43, 0x6c, 0x69, 0x63, 0x6b, 0x3d, 0x22, 0x63, 0x6f, + 0x6e, 0x73, 0x69, 0x64, 0x65, 0x72, 0x65, 0x64, 0x64, 0x65, 0x70, 0x61, 0x72, + 0x74, 0x6d, 0x65, 0x6e, 0x74, 0x6f, 0x63, 0x63, 0x75, 0x70, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x73, 0x6f, 0x6f, 0x6e, 0x20, 0x61, 0x66, 0x74, 0x65, 0x72, 0x69, + 0x6e, 0x76, 0x65, 0x73, 0x74, 0x6d, 0x65, 0x6e, 0x74, 0x70, 0x72, 0x6f, 0x6e, + 0x6f, 0x75, 0x6e, 0x63, 0x65, 0x64, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, + 0x69, 0x65, 0x64, 0x65, 0x78, 0x70, 0x65, 0x72, 0x69, 0x6d, 0x65, 0x6e, 0x74, + 0x4d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x67, 0x65, 0x6f, + 0x67, 0x72, 0x61, 0x70, 0x68, 0x69, 0x63, 0x22, 0x20, 0x68, 0x65, 0x69, 0x67, + 0x68, 0x74, 0x3d, 0x22, 0x6c, 0x69, 0x6e, 0x6b, 0x20, 0x72, 0x65, 0x6c, 0x3d, + 0x22, 0x2e, 0x72, 0x65, 0x70, 0x6c, 0x61, 0x63, 0x65, 0x28, 0x2f, 0x64, 0x65, + 0x70, 0x72, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x63, 0x6f, 0x6e, 0x66, 0x65, + 0x72, 0x65, 0x6e, 0x63, 0x65, 0x70, 0x75, 0x6e, 0x69, 0x73, 0x68, 0x6d, 0x65, + 0x6e, 0x74, 0x65, 0x6c, 0x69, 0x6d, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x64, 0x72, + 0x65, 0x73, 0x69, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x61, 0x64, 0x61, 0x70, + 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x6f, 0x70, 0x70, 0x6f, 0x73, 0x69, 0x74, + 0x69, 0x6f, 0x6e, 0x77, 0x65, 0x6c, 0x6c, 0x20, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, + 0x73, 0x75, 0x70, 0x70, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x64, 0x65, 0x74, + 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x65, 0x64, 0x68, 0x31, 0x20, 0x63, 0x6c, 0x61, + 0x73, 0x73, 0x3d, 0x22, 0x30, 0x70, 0x78, 0x3b, 0x6d, 0x61, 0x72, 0x67, 0x69, + 0x6e, 0x6d, 0x65, 0x63, 0x68, 0x61, 0x6e, 0x69, 0x63, 0x61, 0x6c, 0x73, 0x74, + 0x61, 0x74, 0x69, 0x73, 0x74, 0x69, 0x63, 0x73, 0x63, 0x65, 0x6c, 0x65, 0x62, + 0x72, 0x61, 0x74, 0x65, 0x64, 0x47, 0x6f, 0x76, 0x65, 0x72, 0x6e, 0x6d, 0x65, + 0x6e, 0x74, 0x0a, 0x0a, 0x44, 0x75, 0x72, 0x69, 0x6e, 0x67, 0x20, 0x74, 0x64, + 0x65, 0x76, 0x65, 0x6c, 0x6f, 0x70, 0x65, 0x72, 0x73, 0x61, 0x72, 0x74, 0x69, + 0x66, 0x69, 0x63, 0x69, 0x61, 0x6c, 0x65, 0x71, 0x75, 0x69, 0x76, 0x61, 0x6c, + 0x65, 0x6e, 0x74, 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x64, + 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x61, 0x74, 0x74, + 0x61, 0x63, 0x68, 0x6d, 0x65, 0x6e, 0x74, 0x3c, 0x73, 0x70, 0x61, 0x6e, 0x20, + 0x69, 0x64, 0x3d, 0x22, 0x74, 0x68, 0x65, 0x72, 0x65, 0x20, 0x77, 0x65, 0x72, + 0x65, 0x4e, 0x65, 0x64, 0x65, 0x72, 0x6c, 0x61, 0x6e, 0x64, 0x73, 0x62, 0x65, + 0x79, 0x6f, 0x6e, 0x64, 0x20, 0x74, 0x68, 0x65, 0x72, 0x65, 0x67, 0x69, 0x73, + 0x74, 0x65, 0x72, 0x65, 0x64, 0x6a, 0x6f, 0x75, 0x72, 0x6e, 0x61, 0x6c, 0x69, + 0x73, 0x74, 0x66, 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x74, 0x6c, 0x79, 0x61, + 0x6c, 0x6c, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x6c, 0x61, 0x6e, 0x67, + 0x3d, 0x22, 0x65, 0x6e, 0x22, 0x20, 0x3c, 0x2f, 0x73, 0x74, 0x79, 0x6c, 0x65, + 0x3e, 0x0d, 0x0a, 0x61, 0x62, 0x73, 0x6f, 0x6c, 0x75, 0x74, 0x65, 0x3b, 0x20, + 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x69, 0x6e, 0x67, 0x65, 0x78, 0x74, + 0x72, 0x65, 0x6d, 0x65, 0x6c, 0x79, 0x20, 0x6d, 0x61, 0x69, 0x6e, 0x73, 0x74, + 0x72, 0x65, 0x61, 0x6d, 0x3c, 0x2f, 0x73, 0x74, 0x72, 0x6f, 0x6e, 0x67, 0x3e, + 0x20, 0x70, 0x6f, 0x70, 0x75, 0x6c, 0x61, 0x72, 0x69, 0x74, 0x79, 0x65, 0x6d, + 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x3c, 0x2f, 0x74, 0x61, 0x62, + 0x6c, 0x65, 0x3e, 0x0d, 0x0a, 0x20, 0x63, 0x6f, 0x6c, 0x73, 0x70, 0x61, 0x6e, + 0x3d, 0x22, 0x3c, 0x2f, 0x66, 0x6f, 0x72, 0x6d, 0x3e, 0x0a, 0x20, 0x20, 0x63, + 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x61, 0x62, 0x6f, 0x75, + 0x74, 0x20, 0x74, 0x68, 0x65, 0x20, 0x3c, 0x2f, 0x70, 0x3e, 0x3c, 0x2f, 0x64, + 0x69, 0x76, 0x3e, 0x69, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x65, 0x64, + 0x22, 0x20, 0x6c, 0x61, 0x6e, 0x67, 0x3d, 0x22, 0x65, 0x6e, 0x50, 0x6f, 0x72, + 0x74, 0x75, 0x67, 0x75, 0x65, 0x73, 0x65, 0x73, 0x75, 0x62, 0x73, 0x74, 0x69, + 0x74, 0x75, 0x74, 0x65, 0x69, 0x6e, 0x64, 0x69, 0x76, 0x69, 0x64, 0x75, 0x61, + 0x6c, 0x69, 0x6d, 0x70, 0x6f, 0x73, 0x73, 0x69, 0x62, 0x6c, 0x65, 0x6d, 0x75, + 0x6c, 0x74, 0x69, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x61, 0x6c, 0x6d, 0x6f, 0x73, + 0x74, 0x20, 0x61, 0x6c, 0x6c, 0x70, 0x78, 0x20, 0x73, 0x6f, 0x6c, 0x69, 0x64, + 0x20, 0x23, 0x61, 0x70, 0x61, 0x72, 0x74, 0x20, 0x66, 0x72, 0x6f, 0x6d, 0x73, + 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x20, 0x74, 0x6f, 0x69, 0x6e, 0x20, 0x45, + 0x6e, 0x67, 0x6c, 0x69, 0x73, 0x68, 0x63, 0x72, 0x69, 0x74, 0x69, 0x63, 0x69, + 0x7a, 0x65, 0x64, 0x65, 0x78, 0x63, 0x65, 0x70, 0x74, 0x20, 0x66, 0x6f, 0x72, + 0x67, 0x75, 0x69, 0x64, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x73, 0x6f, 0x72, 0x69, + 0x67, 0x69, 0x6e, 0x61, 0x6c, 0x6c, 0x79, 0x72, 0x65, 0x6d, 0x61, 0x72, 0x6b, + 0x61, 0x62, 0x6c, 0x65, 0x74, 0x68, 0x65, 0x20, 0x73, 0x65, 0x63, 0x6f, 0x6e, + 0x64, 0x68, 0x32, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x22, 0x3c, 0x61, + 0x20, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x3d, 0x22, 0x28, 0x69, 0x6e, 0x63, 0x6c, + 0x75, 0x64, 0x69, 0x6e, 0x67, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, + 0x72, 0x73, 0x70, 0x72, 0x6f, 0x68, 0x69, 0x62, 0x69, 0x74, 0x65, 0x64, 0x3d, + 0x20, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x64, 0x69, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x61, 0x72, 0x79, 0x70, 0x65, 0x72, 0x63, 0x65, 0x70, 0x74, + 0x69, 0x6f, 0x6e, 0x72, 0x65, 0x76, 0x6f, 0x6c, 0x75, 0x74, 0x69, 0x6f, 0x6e, + 0x66, 0x6f, 0x75, 0x6e, 0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x70, 0x78, 0x3b, + 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x3a, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, + 0x73, 0x66, 0x75, 0x6c, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x72, + 0x73, 0x6d, 0x69, 0x6c, 0x6c, 0x65, 0x6e, 0x6e, 0x69, 0x75, 0x6d, 0x68, 0x69, + 0x73, 0x20, 0x66, 0x61, 0x74, 0x68, 0x65, 0x72, 0x74, 0x68, 0x65, 0x20, 0x26, + 0x71, 0x75, 0x6f, 0x74, 0x3b, 0x6e, 0x6f, 0x2d, 0x72, 0x65, 0x70, 0x65, 0x61, + 0x74, 0x3b, 0x63, 0x6f, 0x6d, 0x6d, 0x65, 0x72, 0x63, 0x69, 0x61, 0x6c, 0x69, + 0x6e, 0x64, 0x75, 0x73, 0x74, 0x72, 0x69, 0x61, 0x6c, 0x65, 0x6e, 0x63, 0x6f, + 0x75, 0x72, 0x61, 0x67, 0x65, 0x64, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x20, + 0x6f, 0x66, 0x20, 0x75, 0x6e, 0x6f, 0x66, 0x66, 0x69, 0x63, 0x69, 0x61, 0x6c, + 0x65, 0x66, 0x66, 0x69, 0x63, 0x69, 0x65, 0x6e, 0x63, 0x79, 0x52, 0x65, 0x66, + 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x73, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x69, + 0x6e, 0x61, 0x74, 0x65, 0x64, 0x69, 0x73, 0x63, 0x6c, 0x61, 0x69, 0x6d, 0x65, + 0x72, 0x65, 0x78, 0x70, 0x65, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x64, 0x65, + 0x76, 0x65, 0x6c, 0x6f, 0x70, 0x69, 0x6e, 0x67, 0x63, 0x61, 0x6c, 0x63, 0x75, + 0x6c, 0x61, 0x74, 0x65, 0x64, 0x73, 0x69, 0x6d, 0x70, 0x6c, 0x69, 0x66, 0x69, + 0x65, 0x64, 0x6c, 0x65, 0x67, 0x69, 0x74, 0x69, 0x6d, 0x61, 0x74, 0x65, 0x73, + 0x75, 0x62, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x28, 0x30, 0x22, 0x20, 0x63, + 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x22, 0x63, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, + 0x65, 0x6c, 0x79, 0x69, 0x6c, 0x6c, 0x75, 0x73, 0x74, 0x72, 0x61, 0x74, 0x65, + 0x66, 0x69, 0x76, 0x65, 0x20, 0x79, 0x65, 0x61, 0x72, 0x73, 0x69, 0x6e, 0x73, + 0x74, 0x72, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x73, + 0x68, 0x69, 0x6e, 0x67, 0x31, 0x22, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x3d, + 0x22, 0x70, 0x73, 0x79, 0x63, 0x68, 0x6f, 0x6c, 0x6f, 0x67, 0x79, 0x63, 0x6f, + 0x6e, 0x66, 0x69, 0x64, 0x65, 0x6e, 0x63, 0x65, 0x6e, 0x75, 0x6d, 0x62, 0x65, + 0x72, 0x20, 0x6f, 0x66, 0x20, 0x61, 0x62, 0x73, 0x65, 0x6e, 0x63, 0x65, 0x20, + 0x6f, 0x66, 0x66, 0x6f, 0x63, 0x75, 0x73, 0x65, 0x64, 0x20, 0x6f, 0x6e, 0x6a, + 0x6f, 0x69, 0x6e, 0x65, 0x64, 0x20, 0x74, 0x68, 0x65, 0x73, 0x74, 0x72, 0x75, + 0x63, 0x74, 0x75, 0x72, 0x65, 0x73, 0x70, 0x72, 0x65, 0x76, 0x69, 0x6f, 0x75, + 0x73, 0x6c, 0x79, 0x3e, 0x3c, 0x2f, 0x69, 0x66, 0x72, 0x61, 0x6d, 0x65, 0x3e, + 0x6f, 0x6e, 0x63, 0x65, 0x20, 0x61, 0x67, 0x61, 0x69, 0x6e, 0x62, 0x75, 0x74, + 0x20, 0x72, 0x61, 0x74, 0x68, 0x65, 0x72, 0x69, 0x6d, 0x6d, 0x69, 0x67, 0x72, + 0x61, 0x6e, 0x74, 0x73, 0x6f, 0x66, 0x20, 0x63, 0x6f, 0x75, 0x72, 0x73, 0x65, + 0x2c, 0x61, 0x20, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x20, 0x6f, 0x66, 0x4c, 0x69, + 0x74, 0x65, 0x72, 0x61, 0x74, 0x75, 0x72, 0x65, 0x55, 0x6e, 0x6c, 0x69, 0x6b, + 0x65, 0x20, 0x74, 0x68, 0x65, 0x3c, 0x2f, 0x61, 0x3e, 0x26, 0x6e, 0x62, 0x73, + 0x70, 0x3b, 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x69, + 0x74, 0x20, 0x77, 0x61, 0x73, 0x20, 0x74, 0x68, 0x65, 0x43, 0x6f, 0x6e, 0x76, + 0x65, 0x6e, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x75, 0x74, 0x6f, 0x6d, 0x6f, 0x62, + 0x69, 0x6c, 0x65, 0x50, 0x72, 0x6f, 0x74, 0x65, 0x73, 0x74, 0x61, 0x6e, 0x74, + 0x61, 0x67, 0x67, 0x72, 0x65, 0x73, 0x73, 0x69, 0x76, 0x65, 0x61, 0x66, 0x74, + 0x65, 0x72, 0x20, 0x74, 0x68, 0x65, 0x20, 0x53, 0x69, 0x6d, 0x69, 0x6c, 0x61, + 0x72, 0x6c, 0x79, 0x2c, 0x22, 0x20, 0x2f, 0x3e, 0x3c, 0x2f, 0x64, 0x69, 0x76, + 0x3e, 0x63, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x0d, 0x0a, + 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x76, 0x69, 0x73, 0x69, 0x62, + 0x69, 0x6c, 0x69, 0x74, 0x79, 0x74, 0x68, 0x65, 0x20, 0x75, 0x73, 0x65, 0x20, + 0x6f, 0x66, 0x76, 0x6f, 0x6c, 0x75, 0x6e, 0x74, 0x65, 0x65, 0x72, 0x73, 0x61, + 0x74, 0x74, 0x72, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x75, 0x6e, 0x64, 0x65, + 0x72, 0x20, 0x74, 0x68, 0x65, 0x20, 0x74, 0x68, 0x72, 0x65, 0x61, 0x74, 0x65, + 0x6e, 0x65, 0x64, 0x2a, 0x3c, 0x21, 0x5b, 0x43, 0x44, 0x41, 0x54, 0x41, 0x5b, + 0x69, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x69, 0x6e, 0x20, + 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x6c, 0x74, 0x68, 0x65, 0x20, 0x6c, 0x61, + 0x74, 0x74, 0x65, 0x72, 0x3c, 0x2f, 0x66, 0x6f, 0x72, 0x6d, 0x3e, 0x0a, 0x3c, + 0x2f, 0x2e, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x4f, 0x66, 0x28, 0x27, 0x69, 0x20, + 0x3d, 0x20, 0x30, 0x3b, 0x20, 0x69, 0x20, 0x3c, 0x64, 0x69, 0x66, 0x66, 0x65, + 0x72, 0x65, 0x6e, 0x63, 0x65, 0x64, 0x65, 0x76, 0x6f, 0x74, 0x65, 0x64, 0x20, + 0x74, 0x6f, 0x74, 0x72, 0x61, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x73, + 0x65, 0x61, 0x72, 0x63, 0x68, 0x20, 0x66, 0x6f, 0x72, 0x75, 0x6c, 0x74, 0x69, + 0x6d, 0x61, 0x74, 0x65, 0x6c, 0x79, 0x74, 0x6f, 0x75, 0x72, 0x6e, 0x61, 0x6d, + 0x65, 0x6e, 0x74, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, + 0x73, 0x6f, 0x2d, 0x63, 0x61, 0x6c, 0x6c, 0x65, 0x64, 0x20, 0x7d, 0x0a, 0x3c, + 0x2f, 0x73, 0x74, 0x79, 0x6c, 0x65, 0x3e, 0x65, 0x76, 0x61, 0x6c, 0x75, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x65, 0x6d, 0x70, 0x68, 0x61, 0x73, 0x69, 0x7a, 0x65, + 0x64, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x69, 0x62, 0x6c, 0x65, 0x3c, 0x2f, + 0x73, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x3e, 0x73, 0x75, 0x63, 0x63, 0x65, + 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x6f, 0x6e, 0x67, 0x20, 0x77, 0x69, + 0x74, 0x68, 0x4d, 0x65, 0x61, 0x6e, 0x77, 0x68, 0x69, 0x6c, 0x65, 0x2c, 0x69, + 0x6e, 0x64, 0x75, 0x73, 0x74, 0x72, 0x69, 0x65, 0x73, 0x3c, 0x2f, 0x61, 0x3e, + 0x3c, 0x62, 0x72, 0x20, 0x2f, 0x3e, 0x68, 0x61, 0x73, 0x20, 0x62, 0x65, 0x63, + 0x6f, 0x6d, 0x65, 0x61, 0x73, 0x70, 0x65, 0x63, 0x74, 0x73, 0x20, 0x6f, 0x66, + 0x54, 0x65, 0x6c, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x75, 0x66, + 0x66, 0x69, 0x63, 0x69, 0x65, 0x6e, 0x74, 0x62, 0x61, 0x73, 0x6b, 0x65, 0x74, + 0x62, 0x61, 0x6c, 0x6c, 0x62, 0x6f, 0x74, 0x68, 0x20, 0x73, 0x69, 0x64, 0x65, + 0x73, 0x63, 0x6f, 0x6e, 0x74, 0x69, 0x6e, 0x75, 0x69, 0x6e, 0x67, 0x61, 0x6e, + 0x20, 0x61, 0x72, 0x74, 0x69, 0x63, 0x6c, 0x65, 0x3c, 0x69, 0x6d, 0x67, 0x20, + 0x61, 0x6c, 0x74, 0x3d, 0x22, 0x61, 0x64, 0x76, 0x65, 0x6e, 0x74, 0x75, 0x72, + 0x65, 0x73, 0x68, 0x69, 0x73, 0x20, 0x6d, 0x6f, 0x74, 0x68, 0x65, 0x72, 0x6d, + 0x61, 0x6e, 0x63, 0x68, 0x65, 0x73, 0x74, 0x65, 0x72, 0x70, 0x72, 0x69, 0x6e, + 0x63, 0x69, 0x70, 0x6c, 0x65, 0x73, 0x70, 0x61, 0x72, 0x74, 0x69, 0x63, 0x75, + 0x6c, 0x61, 0x72, 0x63, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x61, 0x72, 0x79, + 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, 0x73, 0x20, 0x6f, 0x66, 0x64, 0x65, 0x63, + 0x69, 0x64, 0x65, 0x64, 0x20, 0x74, 0x6f, 0x22, 0x3e, 0x3c, 0x73, 0x74, 0x72, + 0x6f, 0x6e, 0x67, 0x3e, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x65, 0x72, + 0x73, 0x4a, 0x6f, 0x75, 0x72, 0x6e, 0x61, 0x6c, 0x20, 0x6f, 0x66, 0x64, 0x69, + 0x66, 0x66, 0x69, 0x63, 0x75, 0x6c, 0x74, 0x79, 0x66, 0x61, 0x63, 0x69, 0x6c, + 0x69, 0x74, 0x61, 0x74, 0x65, 0x61, 0x63, 0x63, 0x65, 0x70, 0x74, 0x61, 0x62, + 0x6c, 0x65, 0x73, 0x74, 0x79, 0x6c, 0x65, 0x2e, 0x63, 0x73, 0x73, 0x22, 0x09, + 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x69, 0x6e, 0x6e, 0x6f, + 0x76, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3e, 0x43, 0x6f, 0x70, 0x79, 0x72, 0x69, + 0x67, 0x68, 0x74, 0x73, 0x69, 0x74, 0x75, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, + 0x77, 0x6f, 0x75, 0x6c, 0x64, 0x20, 0x68, 0x61, 0x76, 0x65, 0x62, 0x75, 0x73, + 0x69, 0x6e, 0x65, 0x73, 0x73, 0x65, 0x73, 0x44, 0x69, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x61, 0x72, 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e, 0x74, + 0x73, 0x6f, 0x66, 0x74, 0x65, 0x6e, 0x20, 0x75, 0x73, 0x65, 0x64, 0x70, 0x65, + 0x72, 0x73, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x74, 0x69, 0x6e, 0x20, 0x4a, 0x61, + 0x6e, 0x75, 0x61, 0x72, 0x79, 0x63, 0x6f, 0x6d, 0x70, 0x72, 0x69, 0x73, 0x69, + 0x6e, 0x67, 0x3c, 0x2f, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x3e, 0x0a, 0x09, 0x64, + 0x69, 0x70, 0x6c, 0x6f, 0x6d, 0x61, 0x74, 0x69, 0x63, 0x63, 0x6f, 0x6e, 0x74, + 0x61, 0x69, 0x6e, 0x69, 0x6e, 0x67, 0x70, 0x65, 0x72, 0x66, 0x6f, 0x72, 0x6d, + 0x69, 0x6e, 0x67, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x73, + 0x6d, 0x61, 0x79, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x62, 0x65, 0x63, 0x6f, 0x6e, + 0x63, 0x65, 0x70, 0x74, 0x20, 0x6f, 0x66, 0x20, 0x6f, 0x6e, 0x63, 0x6c, 0x69, + 0x63, 0x6b, 0x3d, 0x22, 0x49, 0x74, 0x20, 0x69, 0x73, 0x20, 0x61, 0x6c, 0x73, + 0x6f, 0x66, 0x69, 0x6e, 0x61, 0x6e, 0x63, 0x69, 0x61, 0x6c, 0x20, 0x6d, 0x61, + 0x6b, 0x69, 0x6e, 0x67, 0x20, 0x74, 0x68, 0x65, 0x4c, 0x75, 0x78, 0x65, 0x6d, + 0x62, 0x6f, 0x75, 0x72, 0x67, 0x61, 0x64, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, + 0x61, 0x6c, 0x61, 0x72, 0x65, 0x20, 0x63, 0x61, 0x6c, 0x6c, 0x65, 0x64, 0x65, + 0x6e, 0x67, 0x61, 0x67, 0x65, 0x64, 0x20, 0x69, 0x6e, 0x22, 0x73, 0x63, 0x72, + 0x69, 0x70, 0x74, 0x22, 0x29, 0x3b, 0x62, 0x75, 0x74, 0x20, 0x69, 0x74, 0x20, + 0x77, 0x61, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x72, 0x6f, 0x6e, 0x69, 0x63, + 0x6f, 0x6e, 0x73, 0x75, 0x62, 0x6d, 0x69, 0x74, 0x3d, 0x22, 0x0a, 0x3c, 0x21, + 0x2d, 0x2d, 0x20, 0x45, 0x6e, 0x64, 0x20, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x72, + 0x69, 0x63, 0x61, 0x6c, 0x6f, 0x66, 0x66, 0x69, 0x63, 0x69, 0x61, 0x6c, 0x6c, + 0x79, 0x73, 0x75, 0x67, 0x67, 0x65, 0x73, 0x74, 0x69, 0x6f, 0x6e, 0x74, 0x6f, + 0x70, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x75, 0x6e, 0x6c, 0x69, 0x6b, + 0x65, 0x20, 0x74, 0x68, 0x65, 0x41, 0x75, 0x73, 0x74, 0x72, 0x61, 0x6c, 0x69, + 0x61, 0x6e, 0x4f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x61, 0x6c, 0x6c, 0x79, 0x72, + 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x73, 0x0a, 0x3c, 0x2f, 0x68, + 0x65, 0x61, 0x64, 0x3e, 0x0d, 0x0a, 0x72, 0x65, 0x63, 0x6f, 0x67, 0x6e, 0x69, + 0x73, 0x65, 0x64, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x61, 0x6c, 0x69, 0x7a, 0x65, + 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x65, 0x64, 0x20, 0x74, 0x6f, 0x41, 0x6c, 0x65, + 0x78, 0x61, 0x6e, 0x64, 0x72, 0x69, 0x61, 0x72, 0x65, 0x74, 0x69, 0x72, 0x65, + 0x6d, 0x65, 0x6e, 0x74, 0x41, 0x64, 0x76, 0x65, 0x6e, 0x74, 0x75, 0x72, 0x65, + 0x73, 0x66, 0x6f, 0x75, 0x72, 0x20, 0x79, 0x65, 0x61, 0x72, 0x73, 0x0a, 0x0a, + 0x26, 0x6c, 0x74, 0x3b, 0x21, 0x2d, 0x2d, 0x20, 0x69, 0x6e, 0x63, 0x72, 0x65, + 0x61, 0x73, 0x69, 0x6e, 0x67, 0x64, 0x65, 0x63, 0x6f, 0x72, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x68, 0x33, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x22, 0x6f, + 0x72, 0x69, 0x67, 0x69, 0x6e, 0x73, 0x20, 0x6f, 0x66, 0x6f, 0x62, 0x6c, 0x69, + 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x72, 0x65, 0x67, 0x75, 0x6c, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x69, 0x66, 0x69, 0x65, 0x64, + 0x28, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x61, 0x64, 0x76, + 0x61, 0x6e, 0x74, 0x61, 0x67, 0x65, 0x73, 0x62, 0x65, 0x69, 0x6e, 0x67, 0x20, + 0x74, 0x68, 0x65, 0x20, 0x68, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x69, 0x61, 0x6e, + 0x73, 0x3c, 0x62, 0x61, 0x73, 0x65, 0x20, 0x68, 0x72, 0x65, 0x66, 0x72, 0x65, + 0x70, 0x65, 0x61, 0x74, 0x65, 0x64, 0x6c, 0x79, 0x77, 0x69, 0x6c, 0x6c, 0x69, + 0x6e, 0x67, 0x20, 0x74, 0x6f, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x72, 0x61, 0x62, + 0x6c, 0x65, 0x64, 0x65, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x65, 0x64, 0x6e, + 0x6f, 0x6d, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x66, 0x75, 0x6e, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x69, 0x6e, 0x73, 0x69, 0x64, 0x65, 0x20, + 0x74, 0x68, 0x65, 0x72, 0x65, 0x76, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x65, 0x6e, 0x64, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x73, 0x20, 0x66, + 0x6f, 0x72, 0x20, 0x74, 0x68, 0x65, 0x20, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, + 0x69, 0x7a, 0x65, 0x64, 0x72, 0x65, 0x66, 0x75, 0x73, 0x65, 0x64, 0x20, 0x74, + 0x6f, 0x74, 0x61, 0x6b, 0x65, 0x20, 0x70, 0x6c, 0x61, 0x63, 0x65, 0x61, 0x75, + 0x74, 0x6f, 0x6e, 0x6f, 0x6d, 0x6f, 0x75, 0x73, 0x63, 0x6f, 0x6d, 0x70, 0x72, + 0x6f, 0x6d, 0x69, 0x73, 0x65, 0x70, 0x6f, 0x6c, 0x69, 0x74, 0x69, 0x63, 0x61, + 0x6c, 0x20, 0x72, 0x65, 0x73, 0x74, 0x61, 0x75, 0x72, 0x61, 0x6e, 0x74, 0x74, + 0x77, 0x6f, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x46, 0x65, 0x62, 0x72, + 0x75, 0x61, 0x72, 0x79, 0x20, 0x32, 0x71, 0x75, 0x61, 0x6c, 0x69, 0x74, 0x79, + 0x20, 0x6f, 0x66, 0x73, 0x77, 0x66, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x2e, + 0x75, 0x6e, 0x64, 0x65, 0x72, 0x73, 0x74, 0x61, 0x6e, 0x64, 0x6e, 0x65, 0x61, + 0x72, 0x6c, 0x79, 0x20, 0x61, 0x6c, 0x6c, 0x77, 0x72, 0x69, 0x74, 0x74, 0x65, + 0x6e, 0x20, 0x62, 0x79, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x69, 0x65, 0x77, + 0x73, 0x22, 0x20, 0x77, 0x69, 0x64, 0x74, 0x68, 0x3d, 0x22, 0x31, 0x77, 0x69, + 0x74, 0x68, 0x64, 0x72, 0x61, 0x77, 0x61, 0x6c, 0x66, 0x6c, 0x6f, 0x61, 0x74, + 0x3a, 0x6c, 0x65, 0x66, 0x74, 0x69, 0x73, 0x20, 0x75, 0x73, 0x75, 0x61, 0x6c, + 0x6c, 0x79, 0x63, 0x61, 0x6e, 0x64, 0x69, 0x64, 0x61, 0x74, 0x65, 0x73, 0x6e, + 0x65, 0x77, 0x73, 0x70, 0x61, 0x70, 0x65, 0x72, 0x73, 0x6d, 0x79, 0x73, 0x74, + 0x65, 0x72, 0x69, 0x6f, 0x75, 0x73, 0x44, 0x65, 0x70, 0x61, 0x72, 0x74, 0x6d, + 0x65, 0x6e, 0x74, 0x62, 0x65, 0x73, 0x74, 0x20, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, + 0x70, 0x61, 0x72, 0x6c, 0x69, 0x61, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x75, 0x70, + 0x70, 0x72, 0x65, 0x73, 0x73, 0x65, 0x64, 0x63, 0x6f, 0x6e, 0x76, 0x65, 0x6e, + 0x69, 0x65, 0x6e, 0x74, 0x72, 0x65, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x65, + 0x64, 0x64, 0x69, 0x66, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x74, 0x20, 0x73, 0x79, + 0x73, 0x74, 0x65, 0x6d, 0x61, 0x74, 0x69, 0x63, 0x68, 0x61, 0x73, 0x20, 0x6c, + 0x65, 0x64, 0x20, 0x74, 0x6f, 0x70, 0x72, 0x6f, 0x70, 0x61, 0x67, 0x61, 0x6e, + 0x64, 0x61, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x64, 0x69, + 0x6e, 0x66, 0x6c, 0x75, 0x65, 0x6e, 0x63, 0x65, 0x73, 0x63, 0x65, 0x72, 0x65, + 0x6d, 0x6f, 0x6e, 0x69, 0x61, 0x6c, 0x70, 0x72, 0x6f, 0x63, 0x6c, 0x61, 0x69, + 0x6d, 0x65, 0x64, 0x50, 0x72, 0x6f, 0x74, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x6c, 0x69, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x22, 0x53, 0x63, 0x69, + 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x63, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x3d, + 0x22, 0x6e, 0x6f, 0x2d, 0x74, 0x72, 0x61, 0x64, 0x65, 0x6d, 0x61, 0x72, 0x6b, + 0x73, 0x6d, 0x6f, 0x72, 0x65, 0x20, 0x74, 0x68, 0x61, 0x6e, 0x20, 0x77, 0x69, + 0x64, 0x65, 0x73, 0x70, 0x72, 0x65, 0x61, 0x64, 0x4c, 0x69, 0x62, 0x65, 0x72, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x74, 0x6f, 0x6f, 0x6b, 0x20, 0x70, 0x6c, 0x61, + 0x63, 0x65, 0x64, 0x61, 0x79, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x61, + 0x73, 0x20, 0x6c, 0x6f, 0x6e, 0x67, 0x20, 0x61, 0x73, 0x69, 0x6d, 0x70, 0x72, + 0x69, 0x73, 0x6f, 0x6e, 0x65, 0x64, 0x41, 0x64, 0x64, 0x69, 0x74, 0x69, 0x6f, + 0x6e, 0x61, 0x6c, 0x0a, 0x3c, 0x68, 0x65, 0x61, 0x64, 0x3e, 0x0a, 0x3c, 0x6d, + 0x4c, 0x61, 0x62, 0x6f, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x79, 0x4e, 0x6f, 0x76, + 0x65, 0x6d, 0x62, 0x65, 0x72, 0x20, 0x32, 0x65, 0x78, 0x63, 0x65, 0x70, 0x74, + 0x69, 0x6f, 0x6e, 0x73, 0x49, 0x6e, 0x64, 0x75, 0x73, 0x74, 0x72, 0x69, 0x61, + 0x6c, 0x76, 0x61, 0x72, 0x69, 0x65, 0x74, 0x79, 0x20, 0x6f, 0x66, 0x66, 0x6c, + 0x6f, 0x61, 0x74, 0x3a, 0x20, 0x6c, 0x65, 0x66, 0x44, 0x75, 0x72, 0x69, 0x6e, + 0x67, 0x20, 0x74, 0x68, 0x65, 0x61, 0x73, 0x73, 0x65, 0x73, 0x73, 0x6d, 0x65, + 0x6e, 0x74, 0x68, 0x61, 0x76, 0x65, 0x20, 0x62, 0x65, 0x65, 0x6e, 0x20, 0x64, + 0x65, 0x61, 0x6c, 0x73, 0x20, 0x77, 0x69, 0x74, 0x68, 0x53, 0x74, 0x61, 0x74, + 0x69, 0x73, 0x74, 0x69, 0x63, 0x73, 0x6f, 0x63, 0x63, 0x75, 0x72, 0x72, 0x65, + 0x6e, 0x63, 0x65, 0x2f, 0x75, 0x6c, 0x3e, 0x3c, 0x2f, 0x64, 0x69, 0x76, 0x3e, + 0x63, 0x6c, 0x65, 0x61, 0x72, 0x66, 0x69, 0x78, 0x22, 0x3e, 0x74, 0x68, 0x65, + 0x20, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x6d, 0x61, 0x6e, 0x79, 0x20, 0x79, + 0x65, 0x61, 0x72, 0x73, 0x77, 0x68, 0x69, 0x63, 0x68, 0x20, 0x77, 0x65, 0x72, + 0x65, 0x6f, 0x76, 0x65, 0x72, 0x20, 0x74, 0x69, 0x6d, 0x65, 0x2c, 0x73, 0x79, + 0x6e, 0x6f, 0x6e, 0x79, 0x6d, 0x6f, 0x75, 0x73, 0x63, 0x6f, 0x6e, 0x74, 0x65, + 0x6e, 0x74, 0x22, 0x3e, 0x0a, 0x70, 0x72, 0x65, 0x73, 0x75, 0x6d, 0x61, 0x62, + 0x6c, 0x79, 0x68, 0x69, 0x73, 0x20, 0x66, 0x61, 0x6d, 0x69, 0x6c, 0x79, 0x75, + 0x73, 0x65, 0x72, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x75, 0x6e, 0x65, 0x78, + 0x70, 0x65, 0x63, 0x74, 0x65, 0x64, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x69, + 0x6e, 0x67, 0x20, 0x63, 0x68, 0x61, 0x6c, 0x6c, 0x65, 0x6e, 0x67, 0x65, 0x64, + 0x61, 0x20, 0x6d, 0x69, 0x6e, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x75, 0x6e, 0x64, + 0x65, 0x66, 0x69, 0x6e, 0x65, 0x64, 0x22, 0x62, 0x65, 0x6c, 0x6f, 0x6e, 0x67, + 0x73, 0x20, 0x74, 0x6f, 0x74, 0x61, 0x6b, 0x65, 0x6e, 0x20, 0x66, 0x72, 0x6f, + 0x6d, 0x69, 0x6e, 0x20, 0x4f, 0x63, 0x74, 0x6f, 0x62, 0x65, 0x72, 0x70, 0x6f, + 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x73, 0x61, 0x69, 0x64, 0x20, + 0x74, 0x6f, 0x20, 0x62, 0x65, 0x72, 0x65, 0x6c, 0x69, 0x67, 0x69, 0x6f, 0x75, + 0x73, 0x20, 0x46, 0x65, 0x64, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, + 0x72, 0x6f, 0x77, 0x73, 0x70, 0x61, 0x6e, 0x3d, 0x22, 0x6f, 0x6e, 0x6c, 0x79, + 0x20, 0x61, 0x20, 0x66, 0x65, 0x77, 0x6d, 0x65, 0x61, 0x6e, 0x74, 0x20, 0x74, + 0x68, 0x61, 0x74, 0x6c, 0x65, 0x64, 0x20, 0x74, 0x6f, 0x20, 0x74, 0x68, 0x65, + 0x2d, 0x2d, 0x3e, 0x0d, 0x0a, 0x3c, 0x64, 0x69, 0x76, 0x20, 0x3c, 0x66, 0x69, + 0x65, 0x6c, 0x64, 0x73, 0x65, 0x74, 0x3e, 0x41, 0x72, 0x63, 0x68, 0x62, 0x69, + 0x73, 0x68, 0x6f, 0x70, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x22, 0x6e, + 0x6f, 0x62, 0x65, 0x69, 0x6e, 0x67, 0x20, 0x75, 0x73, 0x65, 0x64, 0x61, 0x70, + 0x70, 0x72, 0x6f, 0x61, 0x63, 0x68, 0x65, 0x73, 0x70, 0x72, 0x69, 0x76, 0x69, + 0x6c, 0x65, 0x67, 0x65, 0x73, 0x6e, 0x6f, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, + 0x3e, 0x0a, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x20, 0x69, 0x6e, 0x6d, + 0x61, 0x79, 0x20, 0x62, 0x65, 0x20, 0x74, 0x68, 0x65, 0x45, 0x61, 0x73, 0x74, + 0x65, 0x72, 0x20, 0x65, 0x67, 0x67, 0x6d, 0x65, 0x63, 0x68, 0x61, 0x6e, 0x69, + 0x73, 0x6d, 0x73, 0x72, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x61, 0x62, 0x6c, 0x65, + 0x50, 0x6f, 0x70, 0x75, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x6c, + 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, + 0x65, 0x64, 0x22, 0x3e, 0x6e, 0x6f, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x3e, + 0x0d, 0x2f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x2e, 0x70, 0x68, 0x70, 0x61, 0x72, + 0x72, 0x69, 0x76, 0x61, 0x6c, 0x20, 0x6f, 0x66, 0x2d, 0x6a, 0x73, 0x73, 0x64, + 0x6b, 0x27, 0x29, 0x29, 0x3b, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x64, 0x20, + 0x74, 0x6f, 0x69, 0x6e, 0x63, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x63, + 0x61, 0x73, 0x75, 0x61, 0x6c, 0x74, 0x69, 0x65, 0x73, 0x63, 0x6f, 0x6d, 0x70, + 0x6c, 0x65, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x68, 0x72, 0x69, 0x73, 0x74, 0x69, + 0x61, 0x6e, 0x73, 0x53, 0x65, 0x70, 0x74, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x20, + 0x61, 0x72, 0x69, 0x74, 0x68, 0x6d, 0x65, 0x74, 0x69, 0x63, 0x70, 0x72, 0x6f, + 0x63, 0x65, 0x64, 0x75, 0x72, 0x65, 0x73, 0x6d, 0x69, 0x67, 0x68, 0x74, 0x20, + 0x68, 0x61, 0x76, 0x65, 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x69, 0x74, 0x20, 0x61, 0x70, 0x70, 0x65, 0x61, 0x72, 0x73, 0x50, 0x68, + 0x69, 0x6c, 0x6f, 0x73, 0x6f, 0x70, 0x68, 0x79, 0x66, 0x72, 0x69, 0x65, 0x6e, + 0x64, 0x73, 0x68, 0x69, 0x70, 0x6c, 0x65, 0x61, 0x64, 0x69, 0x6e, 0x67, 0x20, + 0x74, 0x6f, 0x67, 0x69, 0x76, 0x69, 0x6e, 0x67, 0x20, 0x74, 0x68, 0x65, 0x74, + 0x6f, 0x77, 0x61, 0x72, 0x64, 0x20, 0x74, 0x68, 0x65, 0x67, 0x75, 0x61, 0x72, + 0x61, 0x6e, 0x74, 0x65, 0x65, 0x64, 0x64, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, + 0x74, 0x65, 0x64, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x23, 0x30, 0x30, 0x30, + 0x76, 0x69, 0x64, 0x65, 0x6f, 0x20, 0x67, 0x61, 0x6d, 0x65, 0x63, 0x6f, 0x6d, + 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x72, 0x65, 0x66, 0x6c, 0x65, 0x63, + 0x74, 0x69, 0x6e, 0x67, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x20, 0x74, 0x68, + 0x65, 0x61, 0x73, 0x73, 0x6f, 0x63, 0x69, 0x61, 0x74, 0x65, 0x64, 0x73, 0x61, + 0x6e, 0x73, 0x2d, 0x73, 0x65, 0x72, 0x69, 0x66, 0x6f, 0x6e, 0x6b, 0x65, 0x79, + 0x70, 0x72, 0x65, 0x73, 0x73, 0x3b, 0x20, 0x70, 0x61, 0x64, 0x64, 0x69, 0x6e, + 0x67, 0x3a, 0x48, 0x65, 0x20, 0x77, 0x61, 0x73, 0x20, 0x74, 0x68, 0x65, 0x75, + 0x6e, 0x64, 0x65, 0x72, 0x6c, 0x79, 0x69, 0x6e, 0x67, 0x74, 0x79, 0x70, 0x69, + 0x63, 0x61, 0x6c, 0x6c, 0x79, 0x20, 0x2c, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x74, + 0x68, 0x65, 0x20, 0x73, 0x72, 0x63, 0x45, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, + 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x69, 0x76, 0x65, 0x73, 0x69, 0x6e, + 0x63, 0x65, 0x20, 0x74, 0x68, 0x65, 0x20, 0x73, 0x68, 0x6f, 0x75, 0x6c, 0x64, + 0x20, 0x62, 0x65, 0x20, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x69, 0x6e, + 0x67, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x69, 0x6e, 0x67, 0x75, 0x73, + 0x65, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x6c, 0x6f, 0x77, 0x65, 0x72, + 0x20, 0x74, 0x68, 0x61, 0x6e, 0x73, 0x68, 0x6f, 0x77, 0x73, 0x20, 0x74, 0x68, + 0x61, 0x74, 0x3c, 0x2f, 0x73, 0x70, 0x61, 0x6e, 0x3e, 0x0a, 0x09, 0x09, 0x63, + 0x6f, 0x6d, 0x70, 0x6c, 0x61, 0x69, 0x6e, 0x74, 0x73, 0x63, 0x6f, 0x6e, 0x74, + 0x69, 0x6e, 0x75, 0x6f, 0x75, 0x73, 0x71, 0x75, 0x61, 0x6e, 0x74, 0x69, 0x74, + 0x69, 0x65, 0x73, 0x61, 0x73, 0x74, 0x72, 0x6f, 0x6e, 0x6f, 0x6d, 0x65, 0x72, + 0x68, 0x65, 0x20, 0x64, 0x69, 0x64, 0x20, 0x6e, 0x6f, 0x74, 0x64, 0x75, 0x65, + 0x20, 0x74, 0x6f, 0x20, 0x69, 0x74, 0x73, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x65, + 0x64, 0x20, 0x74, 0x6f, 0x61, 0x6e, 0x20, 0x61, 0x76, 0x65, 0x72, 0x61, 0x67, + 0x65, 0x65, 0x66, 0x66, 0x6f, 0x72, 0x74, 0x73, 0x20, 0x74, 0x6f, 0x74, 0x68, + 0x65, 0x20, 0x66, 0x75, 0x74, 0x75, 0x72, 0x65, 0x61, 0x74, 0x74, 0x65, 0x6d, + 0x70, 0x74, 0x20, 0x74, 0x6f, 0x54, 0x68, 0x65, 0x72, 0x65, 0x66, 0x6f, 0x72, + 0x65, 0x2c, 0x63, 0x61, 0x70, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x52, + 0x65, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x61, 0x6e, 0x77, 0x61, 0x73, 0x20, + 0x66, 0x6f, 0x72, 0x6d, 0x65, 0x64, 0x45, 0x6c, 0x65, 0x63, 0x74, 0x72, 0x6f, + 0x6e, 0x69, 0x63, 0x6b, 0x69, 0x6c, 0x6f, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, + 0x63, 0x68, 0x61, 0x6c, 0x6c, 0x65, 0x6e, 0x67, 0x65, 0x73, 0x70, 0x75, 0x62, + 0x6c, 0x69, 0x73, 0x68, 0x69, 0x6e, 0x67, 0x74, 0x68, 0x65, 0x20, 0x66, 0x6f, + 0x72, 0x6d, 0x65, 0x72, 0x69, 0x6e, 0x64, 0x69, 0x67, 0x65, 0x6e, 0x6f, 0x75, + 0x73, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x73, 0x75, + 0x62, 0x73, 0x69, 0x64, 0x69, 0x61, 0x72, 0x79, 0x63, 0x6f, 0x6e, 0x73, 0x70, + 0x69, 0x72, 0x61, 0x63, 0x79, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x20, + 0x6f, 0x66, 0x61, 0x6e, 0x64, 0x20, 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x61, + 0x66, 0x66, 0x6f, 0x72, 0x64, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x75, 0x62, 0x73, + 0x74, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x72, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x20, + 0x66, 0x6f, 0x72, 0x63, 0x6f, 0x6e, 0x76, 0x65, 0x6e, 0x74, 0x69, 0x6f, 0x6e, + 0x69, 0x74, 0x65, 0x6d, 0x74, 0x79, 0x70, 0x65, 0x3d, 0x22, 0x61, 0x62, 0x73, + 0x6f, 0x6c, 0x75, 0x74, 0x65, 0x6c, 0x79, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x73, + 0x65, 0x64, 0x6c, 0x79, 0x72, 0x65, 0x6d, 0x61, 0x69, 0x6e, 0x65, 0x64, 0x20, + 0x61, 0x61, 0x74, 0x74, 0x72, 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, 0x74, 0x72, + 0x61, 0x76, 0x65, 0x6c, 0x6c, 0x69, 0x6e, 0x67, 0x73, 0x65, 0x70, 0x61, 0x72, + 0x61, 0x74, 0x65, 0x6c, 0x79, 0x66, 0x6f, 0x63, 0x75, 0x73, 0x65, 0x73, 0x20, + 0x6f, 0x6e, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x61, 0x72, 0x79, 0x61, + 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x62, 0x6c, 0x65, 0x66, 0x6f, 0x75, 0x6e, + 0x64, 0x20, 0x74, 0x68, 0x61, 0x74, 0x73, 0x74, 0x79, 0x6c, 0x65, 0x73, 0x68, + 0x65, 0x65, 0x74, 0x6d, 0x61, 0x6e, 0x75, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, + 0x73, 0x74, 0x61, 0x6e, 0x64, 0x73, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x6e, 0x6f, + 0x2d, 0x72, 0x65, 0x70, 0x65, 0x61, 0x74, 0x28, 0x73, 0x6f, 0x6d, 0x65, 0x74, + 0x69, 0x6d, 0x65, 0x73, 0x43, 0x6f, 0x6d, 0x6d, 0x65, 0x72, 0x63, 0x69, 0x61, + 0x6c, 0x69, 0x6e, 0x20, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x75, 0x6e, + 0x64, 0x65, 0x72, 0x74, 0x61, 0x6b, 0x65, 0x6e, 0x71, 0x75, 0x61, 0x72, 0x74, + 0x65, 0x72, 0x20, 0x6f, 0x66, 0x61, 0x6e, 0x20, 0x65, 0x78, 0x61, 0x6d, 0x70, + 0x6c, 0x65, 0x70, 0x65, 0x72, 0x73, 0x6f, 0x6e, 0x61, 0x6c, 0x6c, 0x79, 0x69, + 0x6e, 0x64, 0x65, 0x78, 0x2e, 0x70, 0x68, 0x70, 0x3f, 0x3c, 0x2f, 0x62, 0x75, + 0x74, 0x74, 0x6f, 0x6e, 0x3e, 0x0a, 0x70, 0x65, 0x72, 0x63, 0x65, 0x6e, 0x74, + 0x61, 0x67, 0x65, 0x62, 0x65, 0x73, 0x74, 0x2d, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, + 0x63, 0x72, 0x65, 0x61, 0x74, 0x69, 0x6e, 0x67, 0x20, 0x61, 0x22, 0x20, 0x64, + 0x69, 0x72, 0x3d, 0x22, 0x6c, 0x74, 0x72, 0x4c, 0x69, 0x65, 0x75, 0x74, 0x65, + 0x6e, 0x61, 0x6e, 0x74, 0x0a, 0x3c, 0x64, 0x69, 0x76, 0x20, 0x69, 0x64, 0x3d, + 0x22, 0x74, 0x68, 0x65, 0x79, 0x20, 0x77, 0x6f, 0x75, 0x6c, 0x64, 0x61, 0x62, + 0x69, 0x6c, 0x69, 0x74, 0x79, 0x20, 0x6f, 0x66, 0x6d, 0x61, 0x64, 0x65, 0x20, + 0x75, 0x70, 0x20, 0x6f, 0x66, 0x6e, 0x6f, 0x74, 0x65, 0x64, 0x20, 0x74, 0x68, + 0x61, 0x74, 0x63, 0x6c, 0x65, 0x61, 0x72, 0x20, 0x74, 0x68, 0x61, 0x74, 0x61, + 0x72, 0x67, 0x75, 0x65, 0x20, 0x74, 0x68, 0x61, 0x74, 0x74, 0x6f, 0x20, 0x61, + 0x6e, 0x6f, 0x74, 0x68, 0x65, 0x72, 0x63, 0x68, 0x69, 0x6c, 0x64, 0x72, 0x65, + 0x6e, 0x27, 0x73, 0x70, 0x75, 0x72, 0x70, 0x6f, 0x73, 0x65, 0x20, 0x6f, 0x66, + 0x66, 0x6f, 0x72, 0x6d, 0x75, 0x6c, 0x61, 0x74, 0x65, 0x64, 0x62, 0x61, 0x73, + 0x65, 0x64, 0x20, 0x75, 0x70, 0x6f, 0x6e, 0x74, 0x68, 0x65, 0x20, 0x72, 0x65, + 0x67, 0x69, 0x6f, 0x6e, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x20, 0x6f, + 0x66, 0x70, 0x61, 0x73, 0x73, 0x65, 0x6e, 0x67, 0x65, 0x72, 0x73, 0x70, 0x6f, + 0x73, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x2e, 0x0a, 0x0a, 0x49, 0x6e, + 0x20, 0x74, 0x68, 0x65, 0x20, 0x42, 0x65, 0x66, 0x6f, 0x72, 0x65, 0x20, 0x74, + 0x68, 0x65, 0x61, 0x66, 0x74, 0x65, 0x72, 0x77, 0x61, 0x72, 0x64, 0x73, 0x63, + 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x6c, 0x79, 0x20, 0x61, 0x63, 0x72, 0x6f, + 0x73, 0x73, 0x20, 0x74, 0x68, 0x65, 0x73, 0x63, 0x69, 0x65, 0x6e, 0x74, 0x69, + 0x66, 0x69, 0x63, 0x63, 0x6f, 0x6d, 0x6d, 0x75, 0x6e, 0x69, 0x74, 0x79, 0x2e, + 0x63, 0x61, 0x70, 0x69, 0x74, 0x61, 0x6c, 0x69, 0x73, 0x6d, 0x69, 0x6e, 0x20, + 0x47, 0x65, 0x72, 0x6d, 0x61, 0x6e, 0x79, 0x72, 0x69, 0x67, 0x68, 0x74, 0x2d, + 0x77, 0x69, 0x6e, 0x67, 0x74, 0x68, 0x65, 0x20, 0x73, 0x79, 0x73, 0x74, 0x65, + 0x6d, 0x53, 0x6f, 0x63, 0x69, 0x65, 0x74, 0x79, 0x20, 0x6f, 0x66, 0x70, 0x6f, + 0x6c, 0x69, 0x74, 0x69, 0x63, 0x69, 0x61, 0x6e, 0x64, 0x69, 0x72, 0x65, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x77, 0x65, 0x6e, 0x74, 0x20, 0x6f, 0x6e, 0x20, + 0x74, 0x6f, 0x72, 0x65, 0x6d, 0x6f, 0x76, 0x61, 0x6c, 0x20, 0x6f, 0x66, 0x20, + 0x4e, 0x65, 0x77, 0x20, 0x59, 0x6f, 0x72, 0x6b, 0x20, 0x61, 0x70, 0x61, 0x72, + 0x74, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x69, 0x6e, 0x64, 0x69, 0x63, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x64, 0x75, 0x72, 0x69, 0x6e, 0x67, 0x20, 0x74, 0x68, 0x65, + 0x75, 0x6e, 0x6c, 0x65, 0x73, 0x73, 0x20, 0x74, 0x68, 0x65, 0x68, 0x69, 0x73, + 0x74, 0x6f, 0x72, 0x69, 0x63, 0x61, 0x6c, 0x68, 0x61, 0x64, 0x20, 0x62, 0x65, + 0x65, 0x6e, 0x20, 0x61, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x76, + 0x65, 0x69, 0x6e, 0x67, 0x72, 0x65, 0x64, 0x69, 0x65, 0x6e, 0x74, 0x61, 0x74, + 0x74, 0x65, 0x6e, 0x64, 0x61, 0x6e, 0x63, 0x65, 0x43, 0x65, 0x6e, 0x74, 0x65, + 0x72, 0x20, 0x66, 0x6f, 0x72, 0x70, 0x72, 0x6f, 0x6d, 0x69, 0x6e, 0x65, 0x6e, + 0x63, 0x65, 0x72, 0x65, 0x61, 0x64, 0x79, 0x53, 0x74, 0x61, 0x74, 0x65, 0x73, + 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x69, 0x65, 0x73, 0x62, 0x75, 0x74, 0x20, + 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x61, 0x73, 0x20, 0x70, 0x61, 0x72, 0x74, + 0x20, 0x6f, 0x66, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x69, 0x74, 0x75, 0x74, 0x65, + 0x63, 0x6c, 0x61, 0x69, 0x6d, 0x20, 0x74, 0x68, 0x61, 0x74, 0x6c, 0x61, 0x62, + 0x6f, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x79, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x74, + 0x69, 0x62, 0x6c, 0x65, 0x66, 0x61, 0x69, 0x6c, 0x75, 0x72, 0x65, 0x20, 0x6f, + 0x66, 0x2c, 0x20, 0x73, 0x75, 0x63, 0x68, 0x20, 0x61, 0x73, 0x20, 0x62, 0x65, + 0x67, 0x61, 0x6e, 0x20, 0x77, 0x69, 0x74, 0x68, 0x75, 0x73, 0x69, 0x6e, 0x67, + 0x20, 0x74, 0x68, 0x65, 0x20, 0x74, 0x6f, 0x20, 0x70, 0x72, 0x6f, 0x76, 0x69, + 0x64, 0x65, 0x66, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x20, 0x6f, 0x66, 0x66, + 0x72, 0x6f, 0x6d, 0x20, 0x77, 0x68, 0x69, 0x63, 0x68, 0x2f, 0x22, 0x20, 0x63, + 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x22, 0x67, 0x65, 0x6f, 0x6c, 0x6f, 0x67, 0x69, + 0x63, 0x61, 0x6c, 0x73, 0x65, 0x76, 0x65, 0x72, 0x61, 0x6c, 0x20, 0x6f, 0x66, + 0x64, 0x65, 0x6c, 0x69, 0x62, 0x65, 0x72, 0x61, 0x74, 0x65, 0x69, 0x6d, 0x70, + 0x6f, 0x72, 0x74, 0x61, 0x6e, 0x74, 0x20, 0x68, 0x6f, 0x6c, 0x64, 0x73, 0x20, + 0x74, 0x68, 0x61, 0x74, 0x69, 0x6e, 0x67, 0x26, 0x71, 0x75, 0x6f, 0x74, 0x3b, + 0x20, 0x76, 0x61, 0x6c, 0x69, 0x67, 0x6e, 0x3d, 0x74, 0x6f, 0x70, 0x74, 0x68, + 0x65, 0x20, 0x47, 0x65, 0x72, 0x6d, 0x61, 0x6e, 0x6f, 0x75, 0x74, 0x73, 0x69, + 0x64, 0x65, 0x20, 0x6f, 0x66, 0x6e, 0x65, 0x67, 0x6f, 0x74, 0x69, 0x61, 0x74, + 0x65, 0x64, 0x68, 0x69, 0x73, 0x20, 0x63, 0x61, 0x72, 0x65, 0x65, 0x72, 0x73, + 0x65, 0x70, 0x61, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x69, 0x64, 0x3d, 0x22, + 0x73, 0x65, 0x61, 0x72, 0x63, 0x68, 0x77, 0x61, 0x73, 0x20, 0x63, 0x61, 0x6c, + 0x6c, 0x65, 0x64, 0x74, 0x68, 0x65, 0x20, 0x66, 0x6f, 0x75, 0x72, 0x74, 0x68, + 0x72, 0x65, 0x63, 0x72, 0x65, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x6f, 0x74, 0x68, + 0x65, 0x72, 0x20, 0x74, 0x68, 0x61, 0x6e, 0x70, 0x72, 0x65, 0x76, 0x65, 0x6e, + 0x74, 0x69, 0x6f, 0x6e, 0x77, 0x68, 0x69, 0x6c, 0x65, 0x20, 0x74, 0x68, 0x65, + 0x20, 0x65, 0x64, 0x75, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2c, 0x63, 0x6f, + 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6e, 0x67, 0x61, 0x63, 0x63, 0x75, 0x72, + 0x61, 0x74, 0x65, 0x6c, 0x79, 0x77, 0x65, 0x72, 0x65, 0x20, 0x62, 0x75, 0x69, + 0x6c, 0x74, 0x77, 0x61, 0x73, 0x20, 0x6b, 0x69, 0x6c, 0x6c, 0x65, 0x64, 0x61, + 0x67, 0x72, 0x65, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x6d, 0x75, 0x63, 0x68, + 0x20, 0x6d, 0x6f, 0x72, 0x65, 0x20, 0x44, 0x75, 0x65, 0x20, 0x74, 0x6f, 0x20, + 0x74, 0x68, 0x65, 0x77, 0x69, 0x64, 0x74, 0x68, 0x3a, 0x20, 0x31, 0x30, 0x30, + 0x73, 0x6f, 0x6d, 0x65, 0x20, 0x6f, 0x74, 0x68, 0x65, 0x72, 0x4b, 0x69, 0x6e, + 0x67, 0x64, 0x6f, 0x6d, 0x20, 0x6f, 0x66, 0x74, 0x68, 0x65, 0x20, 0x65, 0x6e, + 0x74, 0x69, 0x72, 0x65, 0x66, 0x61, 0x6d, 0x6f, 0x75, 0x73, 0x20, 0x66, 0x6f, + 0x72, 0x74, 0x6f, 0x20, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x6f, 0x62, + 0x6a, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x73, 0x74, 0x68, 0x65, 0x20, 0x46, + 0x72, 0x65, 0x6e, 0x63, 0x68, 0x70, 0x65, 0x6f, 0x70, 0x6c, 0x65, 0x20, 0x61, + 0x6e, 0x64, 0x66, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x64, 0x22, 0x3e, 0x69, + 0x73, 0x20, 0x73, 0x61, 0x69, 0x64, 0x20, 0x74, 0x6f, 0x73, 0x74, 0x72, 0x75, + 0x63, 0x74, 0x75, 0x72, 0x61, 0x6c, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, + 0x64, 0x75, 0x6d, 0x6d, 0x6f, 0x73, 0x74, 0x20, 0x6f, 0x66, 0x74, 0x65, 0x6e, + 0x61, 0x20, 0x73, 0x65, 0x70, 0x61, 0x72, 0x61, 0x74, 0x65, 0x2d, 0x3e, 0x0a, + 0x3c, 0x64, 0x69, 0x76, 0x20, 0x69, 0x64, 0x20, 0x4f, 0x66, 0x66, 0x69, 0x63, + 0x69, 0x61, 0x6c, 0x20, 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x77, 0x69, 0x64, 0x65, + 0x2e, 0x61, 0x72, 0x69, 0x61, 0x2d, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x74, 0x68, + 0x65, 0x20, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x74, 0x61, 0x6e, 0x64, 0x20, 0x69, + 0x74, 0x20, 0x77, 0x61, 0x73, 0x64, 0x22, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, + 0x3d, 0x22, 0x6c, 0x6f, 0x6f, 0x6b, 0x69, 0x6e, 0x67, 0x20, 0x61, 0x74, 0x62, + 0x65, 0x6e, 0x65, 0x66, 0x69, 0x63, 0x69, 0x61, 0x6c, 0x61, 0x72, 0x65, 0x20, + 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, + 0x69, 0x6e, 0x67, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x6c, 0x79, + 0x74, 0x68, 0x65, 0x20, 0x6d, 0x6f, 0x64, 0x65, 0x72, 0x6e, 0x77, 0x6f, 0x72, + 0x6b, 0x69, 0x6e, 0x67, 0x20, 0x6f, 0x6e, 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x65, + 0x64, 0x20, 0x74, 0x6f, 0x77, 0x68, 0x65, 0x72, 0x65, 0x20, 0x74, 0x68, 0x65, + 0x20, 0x69, 0x6e, 0x6e, 0x6f, 0x76, 0x61, 0x74, 0x69, 0x76, 0x65, 0x3c, 0x2f, + 0x61, 0x3e, 0x3c, 0x2f, 0x64, 0x69, 0x76, 0x3e, 0x73, 0x6f, 0x75, 0x6e, 0x64, + 0x74, 0x72, 0x61, 0x63, 0x6b, 0x73, 0x65, 0x61, 0x72, 0x63, 0x68, 0x46, 0x6f, + 0x72, 0x6d, 0x74, 0x65, 0x6e, 0x64, 0x20, 0x74, 0x6f, 0x20, 0x62, 0x65, 0x69, + 0x6e, 0x70, 0x75, 0x74, 0x20, 0x69, 0x64, 0x3d, 0x22, 0x6f, 0x70, 0x65, 0x6e, + 0x69, 0x6e, 0x67, 0x20, 0x6f, 0x66, 0x72, 0x65, 0x73, 0x74, 0x72, 0x69, 0x63, + 0x74, 0x65, 0x64, 0x61, 0x64, 0x6f, 0x70, 0x74, 0x65, 0x64, 0x20, 0x62, 0x79, + 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x69, 0x6e, 0x67, 0x74, 0x68, 0x65, + 0x6f, 0x6c, 0x6f, 0x67, 0x69, 0x61, 0x6e, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, + 0x73, 0x20, 0x6f, 0x66, 0x76, 0x61, 0x72, 0x69, 0x61, 0x6e, 0x74, 0x20, 0x6f, + 0x66, 0x43, 0x68, 0x72, 0x69, 0x73, 0x74, 0x69, 0x61, 0x6e, 0x20, 0x76, 0x65, + 0x72, 0x79, 0x20, 0x6c, 0x61, 0x72, 0x67, 0x65, 0x61, 0x75, 0x74, 0x6f, 0x6d, + 0x6f, 0x74, 0x69, 0x76, 0x65, 0x62, 0x79, 0x20, 0x66, 0x61, 0x72, 0x20, 0x74, + 0x68, 0x65, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x20, 0x66, 0x72, 0x6f, 0x6d, 0x70, + 0x75, 0x72, 0x73, 0x75, 0x69, 0x74, 0x20, 0x6f, 0x66, 0x66, 0x6f, 0x6c, 0x6c, + 0x6f, 0x77, 0x20, 0x74, 0x68, 0x65, 0x62, 0x72, 0x6f, 0x75, 0x67, 0x68, 0x74, + 0x20, 0x74, 0x6f, 0x69, 0x6e, 0x20, 0x45, 0x6e, 0x67, 0x6c, 0x61, 0x6e, 0x64, + 0x61, 0x67, 0x72, 0x65, 0x65, 0x20, 0x74, 0x68, 0x61, 0x74, 0x61, 0x63, 0x63, + 0x75, 0x73, 0x65, 0x64, 0x20, 0x6f, 0x66, 0x63, 0x6f, 0x6d, 0x65, 0x73, 0x20, + 0x66, 0x72, 0x6f, 0x6d, 0x70, 0x72, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x69, 0x6e, + 0x67, 0x64, 0x69, 0x76, 0x20, 0x73, 0x74, 0x79, 0x6c, 0x65, 0x3d, 0x68, 0x69, + 0x73, 0x20, 0x6f, 0x72, 0x20, 0x68, 0x65, 0x72, 0x74, 0x72, 0x65, 0x6d, 0x65, + 0x6e, 0x64, 0x6f, 0x75, 0x73, 0x66, 0x72, 0x65, 0x65, 0x64, 0x6f, 0x6d, 0x20, + 0x6f, 0x66, 0x63, 0x6f, 0x6e, 0x63, 0x65, 0x72, 0x6e, 0x69, 0x6e, 0x67, 0x30, + 0x20, 0x31, 0x65, 0x6d, 0x20, 0x31, 0x65, 0x6d, 0x3b, 0x42, 0x61, 0x73, 0x6b, + 0x65, 0x74, 0x62, 0x61, 0x6c, 0x6c, 0x2f, 0x73, 0x74, 0x79, 0x6c, 0x65, 0x2e, + 0x63, 0x73, 0x73, 0x61, 0x6e, 0x20, 0x65, 0x61, 0x72, 0x6c, 0x69, 0x65, 0x72, + 0x65, 0x76, 0x65, 0x6e, 0x20, 0x61, 0x66, 0x74, 0x65, 0x72, 0x2f, 0x22, 0x20, + 0x74, 0x69, 0x74, 0x6c, 0x65, 0x3d, 0x22, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x69, + 0x6e, 0x64, 0x65, 0x78, 0x74, 0x61, 0x6b, 0x69, 0x6e, 0x67, 0x20, 0x74, 0x68, + 0x65, 0x70, 0x69, 0x74, 0x74, 0x73, 0x62, 0x75, 0x72, 0x67, 0x68, 0x63, 0x6f, + 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x22, 0x3e, 0x0d, 0x3c, 0x73, 0x63, 0x72, 0x69, + 0x70, 0x74, 0x3e, 0x28, 0x66, 0x74, 0x75, 0x72, 0x6e, 0x65, 0x64, 0x20, 0x6f, + 0x75, 0x74, 0x68, 0x61, 0x76, 0x69, 0x6e, 0x67, 0x20, 0x74, 0x68, 0x65, 0x3c, + 0x2f, 0x73, 0x70, 0x61, 0x6e, 0x3e, 0x0d, 0x0a, 0x20, 0x6f, 0x63, 0x63, 0x61, + 0x73, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x62, 0x65, 0x63, 0x61, 0x75, 0x73, 0x65, + 0x20, 0x69, 0x74, 0x73, 0x74, 0x61, 0x72, 0x74, 0x65, 0x64, 0x20, 0x74, 0x6f, + 0x70, 0x68, 0x79, 0x73, 0x69, 0x63, 0x61, 0x6c, 0x6c, 0x79, 0x3e, 0x3c, 0x2f, + 0x64, 0x69, 0x76, 0x3e, 0x0a, 0x20, 0x20, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, + 0x64, 0x20, 0x62, 0x79, 0x43, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x6c, 0x79, + 0x2c, 0x20, 0x62, 0x67, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3d, 0x22, 0x74, 0x61, + 0x62, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x3d, 0x22, 0x64, 0x69, 0x73, 0x61, 0x73, + 0x74, 0x72, 0x6f, 0x75, 0x73, 0x41, 0x6e, 0x61, 0x6c, 0x79, 0x74, 0x69, 0x63, + 0x73, 0x20, 0x61, 0x6c, 0x73, 0x6f, 0x20, 0x68, 0x61, 0x73, 0x20, 0x61, 0x3e, + 0x3c, 0x64, 0x69, 0x76, 0x20, 0x69, 0x64, 0x3d, 0x22, 0x3c, 0x2f, 0x73, 0x74, + 0x79, 0x6c, 0x65, 0x3e, 0x0a, 0x3c, 0x63, 0x61, 0x6c, 0x6c, 0x65, 0x64, 0x20, + 0x66, 0x6f, 0x72, 0x73, 0x69, 0x6e, 0x67, 0x65, 0x72, 0x20, 0x61, 0x6e, 0x64, + 0x2e, 0x73, 0x72, 0x63, 0x20, 0x3d, 0x20, 0x22, 0x2f, 0x2f, 0x76, 0x69, 0x6f, + 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x74, 0x68, 0x69, 0x73, 0x20, 0x70, + 0x6f, 0x69, 0x6e, 0x74, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x74, 0x6c, + 0x79, 0x69, 0x73, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x65, 0x64, 0x72, 0x65, + 0x63, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x67, 0x73, 0x64, 0x20, 0x66, 0x72, 0x6f, + 0x6d, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x65, 0x64, 0x65, 0x72, 0x6c, 0x61, 0x6e, + 0x64, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x75, 0x67, 0x75, 0xc3, 0xaa, 0x73, 0xd7, + 0xa2, 0xd7, 0x91, 0xd7, 0xa8, 0xd7, 0x99, 0xd7, 0xaa, 0xd9, 0x81, 0xd8, 0xa7, + 0xd8, 0xb1, 0xd8, 0xb3, 0xdb, 0x8c, 0x64, 0x65, 0x73, 0x61, 0x72, 0x72, 0x6f, + 0x6c, 0x6c, 0x6f, 0x63, 0x6f, 0x6d, 0x65, 0x6e, 0x74, 0x61, 0x72, 0x69, 0x6f, + 0x65, 0x64, 0x75, 0x63, 0x61, 0x63, 0x69, 0xc3, 0xb3, 0x6e, 0x73, 0x65, 0x70, + 0x74, 0x69, 0x65, 0x6d, 0x62, 0x72, 0x65, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, + 0x72, 0x61, 0x64, 0x6f, 0x64, 0x69, 0x72, 0x65, 0x63, 0x63, 0x69, 0xc3, 0xb3, + 0x6e, 0x75, 0x62, 0x69, 0x63, 0x61, 0x63, 0x69, 0xc3, 0xb3, 0x6e, 0x70, 0x75, + 0x62, 0x6c, 0x69, 0x63, 0x69, 0x64, 0x61, 0x64, 0x72, 0x65, 0x73, 0x70, 0x75, + 0x65, 0x73, 0x74, 0x61, 0x73, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x61, 0x64, + 0x6f, 0x73, 0x69, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x61, 0x6e, 0x74, 0x65, 0x72, + 0x65, 0x73, 0x65, 0x72, 0x76, 0x61, 0x64, 0x6f, 0x73, 0x61, 0x72, 0x74, 0xc3, + 0xad, 0x63, 0x75, 0x6c, 0x6f, 0x73, 0x64, 0x69, 0x66, 0x65, 0x72, 0x65, 0x6e, + 0x74, 0x65, 0x73, 0x73, 0x69, 0x67, 0x75, 0x69, 0x65, 0x6e, 0x74, 0x65, 0x73, + 0x72, 0x65, 0x70, 0xc3, 0xba, 0x62, 0x6c, 0x69, 0x63, 0x61, 0x73, 0x69, 0x74, + 0x75, 0x61, 0x63, 0x69, 0xc3, 0xb3, 0x6e, 0x6d, 0x69, 0x6e, 0x69, 0x73, 0x74, + 0x65, 0x72, 0x69, 0x6f, 0x70, 0x72, 0x69, 0x76, 0x61, 0x63, 0x69, 0x64, 0x61, + 0x64, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x69, 0x6f, 0x66, 0x6f, + 0x72, 0x6d, 0x61, 0x63, 0x69, 0xc3, 0xb3, 0x6e, 0x70, 0x6f, 0x62, 0x6c, 0x61, + 0x63, 0x69, 0xc3, 0xb3, 0x6e, 0x70, 0x72, 0x65, 0x73, 0x69, 0x64, 0x65, 0x6e, + 0x74, 0x65, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x69, 0x64, 0x6f, 0x73, 0x61, + 0x63, 0x63, 0x65, 0x73, 0x6f, 0x72, 0x69, 0x6f, 0x73, 0x74, 0x65, 0x63, 0x68, + 0x6e, 0x6f, 0x72, 0x61, 0x74, 0x69, 0x70, 0x65, 0x72, 0x73, 0x6f, 0x6e, 0x61, + 0x6c, 0x65, 0x73, 0x63, 0x61, 0x74, 0x65, 0x67, 0x6f, 0x72, 0xc3, 0xad, 0x61, + 0x65, 0x73, 0x70, 0x65, 0x63, 0x69, 0x61, 0x6c, 0x65, 0x73, 0x64, 0x69, 0x73, + 0x70, 0x6f, 0x6e, 0x69, 0x62, 0x6c, 0x65, 0x61, 0x63, 0x74, 0x75, 0x61, 0x6c, + 0x69, 0x64, 0x61, 0x64, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x69, + 0x61, 0x76, 0x61, 0x6c, 0x6c, 0x61, 0x64, 0x6f, 0x6c, 0x69, 0x64, 0x62, 0x69, + 0x62, 0x6c, 0x69, 0x6f, 0x74, 0x65, 0x63, 0x61, 0x72, 0x65, 0x6c, 0x61, 0x63, + 0x69, 0x6f, 0x6e, 0x65, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x6e, 0x64, 0x61, 0x72, + 0x69, 0x6f, 0x70, 0x6f, 0x6c, 0xc3, 0xad, 0x74, 0x69, 0x63, 0x61, 0x73, 0x61, + 0x6e, 0x74, 0x65, 0x72, 0x69, 0x6f, 0x72, 0x65, 0x73, 0x64, 0x6f, 0x63, 0x75, + 0x6d, 0x65, 0x6e, 0x74, 0x6f, 0x73, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x61, 0x6c, + 0x65, 0x7a, 0x61, 0x6d, 0x61, 0x74, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x65, 0x73, + 0x64, 0x69, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x69, 0x61, 0x65, 0x63, 0x6f, + 0x6e, 0xc3, 0xb3, 0x6d, 0x69, 0x63, 0x61, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x70, + 0x6f, 0x72, 0x74, 0x65, 0x72, 0x6f, 0x64, 0x72, 0xc3, 0xad, 0x67, 0x75, 0x65, + 0x7a, 0x70, 0x61, 0x72, 0x74, 0x69, 0x63, 0x69, 0x70, 0x61, 0x72, 0x65, 0x6e, + 0x63, 0x75, 0x65, 0x6e, 0x74, 0x72, 0x61, 0x6e, 0x64, 0x69, 0x73, 0x63, 0x75, + 0x73, 0x69, 0xc3, 0xb3, 0x6e, 0x65, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x75, + 0x72, 0x61, 0x66, 0x75, 0x6e, 0x64, 0x61, 0x63, 0x69, 0xc3, 0xb3, 0x6e, 0x66, + 0x72, 0x65, 0x63, 0x75, 0x65, 0x6e, 0x74, 0x65, 0x73, 0x70, 0x65, 0x72, 0x6d, + 0x61, 0x6e, 0x65, 0x6e, 0x74, 0x65, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x6d, 0x65, + 0x6e, 0x74, 0x65, 0xd0, 0xbc, 0xd0, 0xbe, 0xd0, 0xb6, 0xd0, 0xbd, 0xd0, 0xbe, + 0xd0, 0xb1, 0xd1, 0x83, 0xd0, 0xb4, 0xd0, 0xb5, 0xd1, 0x82, 0xd0, 0xbc, 0xd0, + 0xbe, 0xd0, 0xb6, 0xd0, 0xb5, 0xd1, 0x82, 0xd0, 0xb2, 0xd1, 0x80, 0xd0, 0xb5, + 0xd0, 0xbc, 0xd1, 0x8f, 0xd1, 0x82, 0xd0, 0xb0, 0xd0, 0xba, 0xd0, 0xb6, 0xd0, + 0xb5, 0xd1, 0x87, 0xd1, 0x82, 0xd0, 0xbe, 0xd0, 0xb1, 0xd1, 0x8b, 0xd0, 0xb1, + 0xd0, 0xbe, 0xd0, 0xbb, 0xd0, 0xb5, 0xd0, 0xb5, 0xd0, 0xbe, 0xd1, 0x87, 0xd0, + 0xb5, 0xd0, 0xbd, 0xd1, 0x8c, 0xd1, 0x8d, 0xd1, 0x82, 0xd0, 0xbe, 0xd0, 0xb3, + 0xd0, 0xbe, 0xd0, 0xba, 0xd0, 0xbe, 0xd0, 0xb3, 0xd0, 0xb4, 0xd0, 0xb0, 0xd0, + 0xbf, 0xd0, 0xbe, 0xd1, 0x81, 0xd0, 0xbb, 0xd0, 0xb5, 0xd0, 0xb2, 0xd1, 0x81, + 0xd0, 0xb5, 0xd0, 0xb3, 0xd0, 0xbe, 0xd1, 0x81, 0xd0, 0xb0, 0xd0, 0xb9, 0xd1, + 0x82, 0xd0, 0xb5, 0xd1, 0x87, 0xd0, 0xb5, 0xd1, 0x80, 0xd0, 0xb5, 0xd0, 0xb7, + 0xd0, 0xbc, 0xd0, 0xbe, 0xd0, 0xb3, 0xd1, 0x83, 0xd1, 0x82, 0xd1, 0x81, 0xd0, + 0xb0, 0xd0, 0xb9, 0xd1, 0x82, 0xd0, 0xb0, 0xd0, 0xb6, 0xd0, 0xb8, 0xd0, 0xb7, + 0xd0, 0xbd, 0xd0, 0xb8, 0xd0, 0xbc, 0xd0, 0xb5, 0xd0, 0xb6, 0xd0, 0xb4, 0xd1, + 0x83, 0xd0, 0xb1, 0xd1, 0x83, 0xd0, 0xb4, 0xd1, 0x83, 0xd1, 0x82, 0xd0, 0x9f, + 0xd0, 0xbe, 0xd0, 0xb8, 0xd1, 0x81, 0xd0, 0xba, 0xd0, 0xb7, 0xd0, 0xb4, 0xd0, + 0xb5, 0xd1, 0x81, 0xd1, 0x8c, 0xd0, 0xb2, 0xd0, 0xb8, 0xd0, 0xb4, 0xd0, 0xb5, + 0xd0, 0xbe, 0xd1, 0x81, 0xd0, 0xb2, 0xd1, 0x8f, 0xd0, 0xb7, 0xd0, 0xb8, 0xd0, + 0xbd, 0xd1, 0x83, 0xd0, 0xb6, 0xd0, 0xbd, 0xd0, 0xbe, 0xd1, 0x81, 0xd0, 0xb2, + 0xd0, 0xbe, 0xd0, 0xb5, 0xd0, 0xb9, 0xd0, 0xbb, 0xd1, 0x8e, 0xd0, 0xb4, 0xd0, + 0xb5, 0xd0, 0xb9, 0xd0, 0xbf, 0xd0, 0xbe, 0xd1, 0x80, 0xd0, 0xbd, 0xd0, 0xbe, + 0xd0, 0xbc, 0xd0, 0xbd, 0xd0, 0xbe, 0xd0, 0xb3, 0xd0, 0xbe, 0xd0, 0xb4, 0xd0, + 0xb5, 0xd1, 0x82, 0xd0, 0xb5, 0xd0, 0xb9, 0xd1, 0x81, 0xd0, 0xb2, 0xd0, 0xbe, + 0xd0, 0xb8, 0xd1, 0x85, 0xd0, 0xbf, 0xd1, 0x80, 0xd0, 0xb0, 0xd0, 0xb2, 0xd0, + 0xb0, 0xd1, 0x82, 0xd0, 0xb0, 0xd0, 0xba, 0xd0, 0xbe, 0xd0, 0xb9, 0xd0, 0xbc, + 0xd0, 0xb5, 0xd1, 0x81, 0xd1, 0x82, 0xd0, 0xbe, 0xd0, 0xb8, 0xd0, 0xbc, 0xd0, + 0xb5, 0xd0, 0xb5, 0xd1, 0x82, 0xd0, 0xb6, 0xd0, 0xb8, 0xd0, 0xb7, 0xd0, 0xbd, + 0xd1, 0x8c, 0xd0, 0xbe, 0xd0, 0xb4, 0xd0, 0xbd, 0xd0, 0xbe, 0xd0, 0xb9, 0xd0, + 0xbb, 0xd1, 0x83, 0xd1, 0x87, 0xd1, 0x88, 0xd0, 0xb5, 0xd0, 0xbf, 0xd0, 0xb5, + 0xd1, 0x80, 0xd0, 0xb5, 0xd0, 0xb4, 0xd1, 0x87, 0xd0, 0xb0, 0xd1, 0x81, 0xd1, + 0x82, 0xd0, 0xb8, 0xd1, 0x87, 0xd0, 0xb0, 0xd1, 0x81, 0xd1, 0x82, 0xd1, 0x8c, + 0xd1, 0x80, 0xd0, 0xb0, 0xd0, 0xb1, 0xd0, 0xbe, 0xd1, 0x82, 0xd0, 0xbd, 0xd0, + 0xbe, 0xd0, 0xb2, 0xd1, 0x8b, 0xd1, 0x85, 0xd0, 0xbf, 0xd1, 0x80, 0xd0, 0xb0, + 0xd0, 0xb2, 0xd0, 0xbe, 0xd1, 0x81, 0xd0, 0xbe, 0xd0, 0xb1, 0xd0, 0xbe, 0xd0, + 0xb9, 0xd0, 0xbf, 0xd0, 0xbe, 0xd1, 0x82, 0xd0, 0xbe, 0xd0, 0xbc, 0xd0, 0xbc, + 0xd0, 0xb5, 0xd0, 0xbd, 0xd0, 0xb5, 0xd0, 0xb5, 0xd1, 0x87, 0xd0, 0xb8, 0xd1, + 0x81, 0xd0, 0xbb, 0xd0, 0xb5, 0xd0, 0xbd, 0xd0, 0xbe, 0xd0, 0xb2, 0xd1, 0x8b, + 0xd0, 0xb5, 0xd1, 0x83, 0xd1, 0x81, 0xd0, 0xbb, 0xd1, 0x83, 0xd0, 0xb3, 0xd0, + 0xbe, 0xd0, 0xba, 0xd0, 0xbe, 0xd0, 0xbb, 0xd0, 0xbe, 0xd0, 0xbd, 0xd0, 0xb0, + 0xd0, 0xb7, 0xd0, 0xb0, 0xd0, 0xb4, 0xd1, 0x82, 0xd0, 0xb0, 0xd0, 0xba, 0xd0, + 0xbe, 0xd0, 0xb5, 0xd1, 0x82, 0xd0, 0xbe, 0xd0, 0xb3, 0xd0, 0xb4, 0xd0, 0xb0, + 0xd0, 0xbf, 0xd0, 0xbe, 0xd1, 0x87, 0xd1, 0x82, 0xd0, 0xb8, 0xd0, 0x9f, 0xd0, + 0xbe, 0xd1, 0x81, 0xd0, 0xbb, 0xd0, 0xb5, 0xd1, 0x82, 0xd0, 0xb0, 0xd0, 0xba, + 0xd0, 0xb8, 0xd0, 0xb5, 0xd0, 0xbd, 0xd0, 0xbe, 0xd0, 0xb2, 0xd1, 0x8b, 0xd0, + 0xb9, 0xd1, 0x81, 0xd1, 0x82, 0xd0, 0xbe, 0xd0, 0xb8, 0xd1, 0x82, 0xd1, 0x82, + 0xd0, 0xb0, 0xd0, 0xba, 0xd0, 0xb8, 0xd1, 0x85, 0xd1, 0x81, 0xd1, 0x80, 0xd0, + 0xb0, 0xd0, 0xb7, 0xd1, 0x83, 0xd0, 0xa1, 0xd0, 0xb0, 0xd0, 0xbd, 0xd0, 0xba, + 0xd1, 0x82, 0xd1, 0x84, 0xd0, 0xbe, 0xd1, 0x80, 0xd1, 0x83, 0xd0, 0xbc, 0xd0, + 0x9a, 0xd0, 0xbe, 0xd0, 0xb3, 0xd0, 0xb4, 0xd0, 0xb0, 0xd0, 0xba, 0xd0, 0xbd, + 0xd0, 0xb8, 0xd0, 0xb3, 0xd0, 0xb8, 0xd1, 0x81, 0xd0, 0xbb, 0xd0, 0xbe, 0xd0, + 0xb2, 0xd0, 0xb0, 0xd0, 0xbd, 0xd0, 0xb0, 0xd1, 0x88, 0xd0, 0xb5, 0xd0, 0xb9, + 0xd0, 0xbd, 0xd0, 0xb0, 0xd0, 0xb9, 0xd1, 0x82, 0xd0, 0xb8, 0xd1, 0x81, 0xd0, + 0xb2, 0xd0, 0xbe, 0xd0, 0xb8, 0xd0, 0xbc, 0xd1, 0x81, 0xd0, 0xb2, 0xd1, 0x8f, + 0xd0, 0xb7, 0xd1, 0x8c, 0xd0, 0xbb, 0xd1, 0x8e, 0xd0, 0xb1, 0xd0, 0xbe, 0xd0, + 0xb9, 0xd1, 0x87, 0xd0, 0xb0, 0xd1, 0x81, 0xd1, 0x82, 0xd0, 0xbe, 0xd1, 0x81, + 0xd1, 0x80, 0xd0, 0xb5, 0xd0, 0xb4, 0xd0, 0xb8, 0xd0, 0x9a, 0xd1, 0x80, 0xd0, + 0xbe, 0xd0, 0xbc, 0xd0, 0xb5, 0xd0, 0xa4, 0xd0, 0xbe, 0xd1, 0x80, 0xd1, 0x83, + 0xd0, 0xbc, 0xd1, 0x80, 0xd1, 0x8b, 0xd0, 0xbd, 0xd0, 0xba, 0xd0, 0xb5, 0xd1, + 0x81, 0xd1, 0x82, 0xd0, 0xb0, 0xd0, 0xbb, 0xd0, 0xb8, 0xd0, 0xbf, 0xd0, 0xbe, + 0xd0, 0xb8, 0xd1, 0x81, 0xd0, 0xba, 0xd1, 0x82, 0xd1, 0x8b, 0xd1, 0x81, 0xd1, + 0x8f, 0xd1, 0x87, 0xd0, 0xbc, 0xd0, 0xb5, 0xd1, 0x81, 0xd1, 0x8f, 0xd1, 0x86, + 0xd1, 0x86, 0xd0, 0xb5, 0xd0, 0xbd, 0xd1, 0x82, 0xd1, 0x80, 0xd1, 0x82, 0xd1, + 0x80, 0xd1, 0x83, 0xd0, 0xb4, 0xd0, 0xb0, 0xd1, 0x81, 0xd0, 0xb0, 0xd0, 0xbc, + 0xd1, 0x8b, 0xd1, 0x85, 0xd1, 0x80, 0xd1, 0x8b, 0xd0, 0xbd, 0xd0, 0xba, 0xd0, + 0xb0, 0xd0, 0x9d, 0xd0, 0xbe, 0xd0, 0xb2, 0xd1, 0x8b, 0xd0, 0xb9, 0xd1, 0x87, + 0xd0, 0xb0, 0xd1, 0x81, 0xd0, 0xbe, 0xd0, 0xb2, 0xd0, 0xbc, 0xd0, 0xb5, 0xd1, + 0x81, 0xd1, 0x82, 0xd0, 0xb0, 0xd1, 0x84, 0xd0, 0xb8, 0xd0, 0xbb, 0xd1, 0x8c, + 0xd0, 0xbc, 0xd0, 0xbc, 0xd0, 0xb0, 0xd1, 0x80, 0xd1, 0x82, 0xd0, 0xb0, 0xd1, + 0x81, 0xd1, 0x82, 0xd1, 0x80, 0xd0, 0xb0, 0xd0, 0xbd, 0xd0, 0xbc, 0xd0, 0xb5, + 0xd1, 0x81, 0xd1, 0x82, 0xd0, 0xb5, 0xd1, 0x82, 0xd0, 0xb5, 0xd0, 0xba, 0xd1, + 0x81, 0xd1, 0x82, 0xd0, 0xbd, 0xd0, 0xb0, 0xd1, 0x88, 0xd0, 0xb8, 0xd1, 0x85, + 0xd0, 0xbc, 0xd0, 0xb8, 0xd0, 0xbd, 0xd1, 0x83, 0xd1, 0x82, 0xd0, 0xb8, 0xd0, + 0xbc, 0xd0, 0xb5, 0xd0, 0xbd, 0xd0, 0xb8, 0xd0, 0xb8, 0xd0, 0xbc, 0xd0, 0xb5, + 0xd1, 0x8e, 0xd1, 0x82, 0xd0, 0xbd, 0xd0, 0xbe, 0xd0, 0xbc, 0xd0, 0xb5, 0xd1, + 0x80, 0xd0, 0xb3, 0xd0, 0xbe, 0xd1, 0x80, 0xd0, 0xbe, 0xd0, 0xb4, 0xd1, 0x81, + 0xd0, 0xb0, 0xd0, 0xbc, 0xd0, 0xbe, 0xd0, 0xbc, 0xd1, 0x8d, 0xd1, 0x82, 0xd0, + 0xbe, 0xd0, 0xbc, 0xd1, 0x83, 0xd0, 0xba, 0xd0, 0xbe, 0xd0, 0xbd, 0xd1, 0x86, + 0xd0, 0xb5, 0xd1, 0x81, 0xd0, 0xb2, 0xd0, 0xbe, 0xd0, 0xb5, 0xd0, 0xbc, 0xd0, + 0xba, 0xd0, 0xb0, 0xd0, 0xba, 0xd0, 0xbe, 0xd0, 0xb9, 0xd0, 0x90, 0xd1, 0x80, + 0xd1, 0x85, 0xd0, 0xb8, 0xd0, 0xb2, 0xd9, 0x85, 0xd9, 0x86, 0xd8, 0xaa, 0xd8, + 0xaf, 0xd9, 0x89, 0xd8, 0xa5, 0xd8, 0xb1, 0xd8, 0xb3, 0xd8, 0xa7, 0xd9, 0x84, + 0xd8, 0xb1, 0xd8, 0xb3, 0xd8, 0xa7, 0xd9, 0x84, 0xd8, 0xa9, 0xd8, 0xa7, 0xd9, + 0x84, 0xd8, 0xb9, 0xd8, 0xa7, 0xd9, 0x85, 0xd9, 0x83, 0xd8, 0xaa, 0xd8, 0xa8, + 0xd9, 0x87, 0xd8, 0xa7, 0xd8, 0xa8, 0xd8, 0xb1, 0xd8, 0xa7, 0xd9, 0x85, 0xd8, + 0xac, 0xd8, 0xa7, 0xd9, 0x84, 0xd9, 0x8a, 0xd9, 0x88, 0xd9, 0x85, 0xd8, 0xa7, + 0xd9, 0x84, 0xd8, 0xb5, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xac, 0xd8, 0xaf, 0xd9, + 0x8a, 0xd8, 0xaf, 0xd8, 0xa9, 0xd8, 0xa7, 0xd9, 0x84, 0xd8, 0xb9, 0xd8, 0xb6, + 0xd9, 0x88, 0xd8, 0xa5, 0xd8, 0xb6, 0xd8, 0xa7, 0xd9, 0x81, 0xd8, 0xa9, 0xd8, + 0xa7, 0xd9, 0x84, 0xd9, 0x82, 0xd8, 0xb3, 0xd9, 0x85, 0xd8, 0xa7, 0xd9, 0x84, + 0xd8, 0xb9, 0xd8, 0xa7, 0xd8, 0xa8, 0xd8, 0xaa, 0xd8, 0xad, 0xd9, 0x85, 0xd9, + 0x8a, 0xd9, 0x84, 0xd9, 0x85, 0xd9, 0x84, 0xd9, 0x81, 0xd8, 0xa7, 0xd8, 0xaa, + 0xd9, 0x85, 0xd9, 0x84, 0xd8, 0xaa, 0xd9, 0x82, 0xd9, 0x89, 0xd8, 0xaa, 0xd8, + 0xb9, 0xd8, 0xaf, 0xd9, 0x8a, 0xd9, 0x84, 0xd8, 0xa7, 0xd9, 0x84, 0xd8, 0xb4, + 0xd8, 0xb9, 0xd8, 0xb1, 0xd8, 0xa3, 0xd8, 0xae, 0xd8, 0xa8, 0xd8, 0xa7, 0xd8, + 0xb1, 0xd8, 0xaa, 0xd8, 0xb7, 0xd9, 0x88, 0xd9, 0x8a, 0xd8, 0xb1, 0xd8, 0xb9, + 0xd9, 0x84, 0xd9, 0x8a, 0xd9, 0x83, 0xd9, 0x85, 0xd8, 0xa5, 0xd8, 0xb1, 0xd9, + 0x81, 0xd8, 0xa7, 0xd9, 0x82, 0xd8, 0xb7, 0xd9, 0x84, 0xd8, 0xa8, 0xd8, 0xa7, + 0xd8, 0xaa, 0xd8, 0xa7, 0xd9, 0x84, 0xd9, 0x84, 0xd8, 0xba, 0xd8, 0xa9, 0xd8, + 0xaa, 0xd8, 0xb1, 0xd8, 0xaa, 0xd9, 0x8a, 0xd8, 0xa8, 0xd8, 0xa7, 0xd9, 0x84, + 0xd9, 0x86, 0xd8, 0xa7, 0xd8, 0xb3, 0xd8, 0xa7, 0xd9, 0x84, 0xd8, 0xb4, 0xd9, + 0x8a, 0xd8, 0xae, 0xd9, 0x85, 0xd9, 0x86, 0xd8, 0xaa, 0xd8, 0xaf, 0xd9, 0x8a, + 0xd8, 0xa7, 0xd9, 0x84, 0xd8, 0xb9, 0xd8, 0xb1, 0xd8, 0xa8, 0xd8, 0xa7, 0xd9, + 0x84, 0xd9, 0x82, 0xd8, 0xb5, 0xd8, 0xb5, 0xd8, 0xa7, 0xd9, 0x81, 0xd9, 0x84, + 0xd8, 0xa7, 0xd9, 0x85, 0xd8, 0xb9, 0xd9, 0x84, 0xd9, 0x8a, 0xd9, 0x87, 0xd8, + 0xa7, 0xd8, 0xaa, 0xd8, 0xad, 0xd8, 0xaf, 0xd9, 0x8a, 0xd8, 0xab, 0xd8, 0xa7, + 0xd9, 0x84, 0xd9, 0x84, 0xd9, 0x87, 0xd9, 0x85, 0xd8, 0xa7, 0xd9, 0x84, 0xd8, + 0xb9, 0xd9, 0x85, 0xd9, 0x84, 0xd9, 0x85, 0xd9, 0x83, 0xd8, 0xaa, 0xd8, 0xa8, + 0xd8, 0xa9, 0xd9, 0x8a, 0xd9, 0x85, 0xd9, 0x83, 0xd9, 0x86, 0xd9, 0x83, 0xd8, + 0xa7, 0xd9, 0x84, 0xd8, 0xb7, 0xd9, 0x81, 0xd9, 0x84, 0xd9, 0x81, 0xd9, 0x8a, + 0xd8, 0xaf, 0xd9, 0x8a, 0xd9, 0x88, 0xd8, 0xa5, 0xd8, 0xaf, 0xd8, 0xa7, 0xd8, + 0xb1, 0xd8, 0xa9, 0xd8, 0xaa, 0xd8, 0xa7, 0xd8, 0xb1, 0xd9, 0x8a, 0xd8, 0xae, + 0xd8, 0xa7, 0xd9, 0x84, 0xd8, 0xb5, 0xd8, 0xad, 0xd8, 0xa9, 0xd8, 0xaa, 0xd8, + 0xb3, 0xd8, 0xac, 0xd9, 0x8a, 0xd9, 0x84, 0xd8, 0xa7, 0xd9, 0x84, 0xd9, 0x88, + 0xd9, 0x82, 0xd8, 0xaa, 0xd8, 0xb9, 0xd9, 0x86, 0xd8, 0xaf, 0xd9, 0x85, 0xd8, + 0xa7, 0xd9, 0x85, 0xd8, 0xaf, 0xd9, 0x8a, 0xd9, 0x86, 0xd8, 0xa9, 0xd8, 0xaa, + 0xd8, 0xb5, 0xd9, 0x85, 0xd9, 0x8a, 0xd9, 0x85, 0xd8, 0xa3, 0xd8, 0xb1, 0xd8, + 0xb4, 0xd9, 0x8a, 0xd9, 0x81, 0xd8, 0xa7, 0xd9, 0x84, 0xd8, 0xb0, 0xd9, 0x8a, + 0xd9, 0x86, 0xd8, 0xb9, 0xd8, 0xb1, 0xd8, 0xa8, 0xd9, 0x8a, 0xd8, 0xa9, 0xd8, + 0xa8, 0xd9, 0x88, 0xd8, 0xa7, 0xd8, 0xa8, 0xd8, 0xa9, 0xd8, 0xa3, 0xd9, 0x84, + 0xd8, 0xb9, 0xd8, 0xa7, 0xd8, 0xa8, 0xd8, 0xa7, 0xd9, 0x84, 0xd8, 0xb3, 0xd9, + 0x81, 0xd8, 0xb1, 0xd9, 0x85, 0xd8, 0xb4, 0xd8, 0xa7, 0xd9, 0x83, 0xd9, 0x84, + 0xd8, 0xaa, 0xd8, 0xb9, 0xd8, 0xa7, 0xd9, 0x84, 0xd9, 0x89, 0xd8, 0xa7, 0xd9, + 0x84, 0xd8, 0xa3, 0xd9, 0x88, 0xd9, 0x84, 0xd8, 0xa7, 0xd9, 0x84, 0xd8, 0xb3, + 0xd9, 0x86, 0xd8, 0xa9, 0xd8, 0xac, 0xd8, 0xa7, 0xd9, 0x85, 0xd8, 0xb9, 0xd8, + 0xa9, 0xd8, 0xa7, 0xd9, 0x84, 0xd8, 0xb5, 0xd8, 0xad, 0xd9, 0x81, 0xd8, 0xa7, + 0xd9, 0x84, 0xd8, 0xaf, 0xd9, 0x8a, 0xd9, 0x86, 0xd9, 0x83, 0xd9, 0x84, 0xd9, + 0x85, 0xd8, 0xa7, 0xd8, 0xaa, 0xd8, 0xa7, 0xd9, 0x84, 0xd8, 0xae, 0xd8, 0xa7, + 0xd8, 0xb5, 0xd8, 0xa7, 0xd9, 0x84, 0xd9, 0x85, 0xd9, 0x84, 0xd9, 0x81, 0xd8, + 0xa3, 0xd8, 0xb9, 0xd8, 0xb6, 0xd8, 0xa7, 0xd8, 0xa1, 0xd9, 0x83, 0xd8, 0xaa, + 0xd8, 0xa7, 0xd8, 0xa8, 0xd8, 0xa9, 0xd8, 0xa7, 0xd9, 0x84, 0xd8, 0xae, 0xd9, + 0x8a, 0xd8, 0xb1, 0xd8, 0xb1, 0xd8, 0xb3, 0xd8, 0xa7, 0xd8, 0xa6, 0xd9, 0x84, + 0xd8, 0xa7, 0xd9, 0x84, 0xd9, 0x82, 0xd9, 0x84, 0xd8, 0xa8, 0xd8, 0xa7, 0xd9, + 0x84, 0xd8, 0xa3, 0xd8, 0xaf, 0xd8, 0xa8, 0xd9, 0x85, 0xd9, 0x82, 0xd8, 0xa7, + 0xd8, 0xb7, 0xd8, 0xb9, 0xd9, 0x85, 0xd8, 0xb1, 0xd8, 0xa7, 0xd8, 0xb3, 0xd9, + 0x84, 0xd9, 0x85, 0xd9, 0x86, 0xd8, 0xb7, 0xd9, 0x82, 0xd8, 0xa9, 0xd8, 0xa7, + 0xd9, 0x84, 0xd9, 0x83, 0xd8, 0xaa, 0xd8, 0xa8, 0xd8, 0xa7, 0xd9, 0x84, 0xd8, + 0xb1, 0xd8, 0xac, 0xd9, 0x84, 0xd8, 0xa7, 0xd8, 0xb4, 0xd8, 0xaa, 0xd8, 0xb1, + 0xd9, 0x83, 0xd8, 0xa7, 0xd9, 0x84, 0xd9, 0x82, 0xd8, 0xaf, 0xd9, 0x85, 0xd9, + 0x8a, 0xd8, 0xb9, 0xd8, 0xb7, 0xd9, 0x8a, 0xd9, 0x83, 0x73, 0x42, 0x79, 0x54, + 0x61, 0x67, 0x4e, 0x61, 0x6d, 0x65, 0x28, 0x2e, 0x6a, 0x70, 0x67, 0x22, 0x20, + 0x61, 0x6c, 0x74, 0x3d, 0x22, 0x31, 0x70, 0x78, 0x20, 0x73, 0x6f, 0x6c, 0x69, + 0x64, 0x20, 0x23, 0x2e, 0x67, 0x69, 0x66, 0x22, 0x20, 0x61, 0x6c, 0x74, 0x3d, + 0x22, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x69, + 0x6e, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x70, 0x70, + 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x20, 0x6f, 0x6e, 0x63, + 0x6c, 0x69, 0x63, 0x6b, 0x3d, 0x22, 0x65, 0x73, 0x74, 0x61, 0x62, 0x6c, 0x69, + 0x73, 0x68, 0x65, 0x64, 0x61, 0x64, 0x76, 0x65, 0x72, 0x74, 0x69, 0x73, 0x69, + 0x6e, 0x67, 0x2e, 0x70, 0x6e, 0x67, 0x22, 0x20, 0x61, 0x6c, 0x74, 0x3d, 0x22, + 0x65, 0x6e, 0x76, 0x69, 0x72, 0x6f, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x70, 0x65, + 0x72, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x6e, 0x63, 0x65, 0x61, 0x70, 0x70, 0x72, + 0x6f, 0x70, 0x72, 0x69, 0x61, 0x74, 0x65, 0x26, 0x61, 0x6d, 0x70, 0x3b, 0x6d, + 0x64, 0x61, 0x73, 0x68, 0x3b, 0x69, 0x6d, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x74, + 0x65, 0x6c, 0x79, 0x3c, 0x2f, 0x73, 0x74, 0x72, 0x6f, 0x6e, 0x67, 0x3e, 0x3c, + 0x2f, 0x72, 0x61, 0x74, 0x68, 0x65, 0x72, 0x20, 0x74, 0x68, 0x61, 0x6e, 0x74, + 0x65, 0x6d, 0x70, 0x65, 0x72, 0x61, 0x74, 0x75, 0x72, 0x65, 0x64, 0x65, 0x76, + 0x65, 0x6c, 0x6f, 0x70, 0x6d, 0x65, 0x6e, 0x74, 0x63, 0x6f, 0x6d, 0x70, 0x65, + 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x70, 0x6c, 0x61, 0x63, 0x65, 0x68, 0x6f, + 0x6c, 0x64, 0x65, 0x72, 0x76, 0x69, 0x73, 0x69, 0x62, 0x69, 0x6c, 0x69, 0x74, + 0x79, 0x3a, 0x63, 0x6f, 0x70, 0x79, 0x72, 0x69, 0x67, 0x68, 0x74, 0x22, 0x3e, + 0x30, 0x22, 0x20, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x3d, 0x22, 0x65, 0x76, + 0x65, 0x6e, 0x20, 0x74, 0x68, 0x6f, 0x75, 0x67, 0x68, 0x72, 0x65, 0x70, 0x6c, + 0x61, 0x63, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x64, 0x65, 0x73, 0x74, 0x69, 0x6e, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x72, 0x70, 0x6f, 0x72, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x3c, 0x75, 0x6c, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x3d, + 0x22, 0x41, 0x73, 0x73, 0x6f, 0x63, 0x69, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x69, + 0x6e, 0x64, 0x69, 0x76, 0x69, 0x64, 0x75, 0x61, 0x6c, 0x73, 0x70, 0x65, 0x72, + 0x73, 0x70, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x73, 0x65, 0x74, 0x54, 0x69, + 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x28, 0x75, 0x72, 0x6c, 0x28, 0x68, 0x74, 0x74, + 0x70, 0x3a, 0x2f, 0x2f, 0x6d, 0x61, 0x74, 0x68, 0x65, 0x6d, 0x61, 0x74, 0x69, + 0x63, 0x73, 0x6d, 0x61, 0x72, 0x67, 0x69, 0x6e, 0x2d, 0x74, 0x6f, 0x70, 0x3a, + 0x65, 0x76, 0x65, 0x6e, 0x74, 0x75, 0x61, 0x6c, 0x6c, 0x79, 0x20, 0x64, 0x65, + 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x29, 0x20, 0x6e, 0x6f, + 0x2d, 0x72, 0x65, 0x70, 0x65, 0x61, 0x74, 0x63, 0x6f, 0x6c, 0x6c, 0x65, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x4a, 0x50, 0x47, 0x7c, 0x74, 0x68, 0x75, + 0x6d, 0x62, 0x7c, 0x70, 0x61, 0x72, 0x74, 0x69, 0x63, 0x69, 0x70, 0x61, 0x74, + 0x65, 0x2f, 0x68, 0x65, 0x61, 0x64, 0x3e, 0x3c, 0x62, 0x6f, 0x64, 0x79, 0x66, + 0x6c, 0x6f, 0x61, 0x74, 0x3a, 0x6c, 0x65, 0x66, 0x74, 0x3b, 0x3c, 0x6c, 0x69, + 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x22, 0x68, 0x75, 0x6e, 0x64, 0x72, + 0x65, 0x64, 0x73, 0x20, 0x6f, 0x66, 0x0a, 0x0a, 0x48, 0x6f, 0x77, 0x65, 0x76, + 0x65, 0x72, 0x2c, 0x20, 0x63, 0x6f, 0x6d, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, + 0x6f, 0x6e, 0x63, 0x6c, 0x65, 0x61, 0x72, 0x3a, 0x62, 0x6f, 0x74, 0x68, 0x3b, + 0x63, 0x6f, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x77, 0x69, + 0x74, 0x68, 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x6c, 0x61, 0x62, 0x65, + 0x6c, 0x20, 0x66, 0x6f, 0x72, 0x3d, 0x22, 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, + 0x2d, 0x74, 0x6f, 0x70, 0x3a, 0x4e, 0x65, 0x77, 0x20, 0x5a, 0x65, 0x61, 0x6c, + 0x61, 0x6e, 0x64, 0x72, 0x65, 0x63, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x64, 0x65, + 0x64, 0x70, 0x68, 0x6f, 0x74, 0x6f, 0x67, 0x72, 0x61, 0x70, 0x68, 0x79, 0x69, + 0x6e, 0x74, 0x65, 0x72, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x67, 0x26, 0x6c, 0x74, + 0x3b, 0x73, 0x75, 0x70, 0x26, 0x67, 0x74, 0x3b, 0x63, 0x6f, 0x6e, 0x74, 0x72, + 0x6f, 0x76, 0x65, 0x72, 0x73, 0x79, 0x4e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x6c, + 0x61, 0x6e, 0x64, 0x73, 0x61, 0x6c, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x74, 0x69, + 0x76, 0x65, 0x6d, 0x61, 0x78, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3d, 0x22, + 0x73, 0x77, 0x69, 0x74, 0x7a, 0x65, 0x72, 0x6c, 0x61, 0x6e, 0x64, 0x44, 0x65, + 0x76, 0x65, 0x6c, 0x6f, 0x70, 0x6d, 0x65, 0x6e, 0x74, 0x65, 0x73, 0x73, 0x65, + 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x6c, 0x79, 0x0a, 0x0a, 0x41, 0x6c, 0x74, 0x68, + 0x6f, 0x75, 0x67, 0x68, 0x20, 0x3c, 0x2f, 0x74, 0x65, 0x78, 0x74, 0x61, 0x72, + 0x65, 0x61, 0x3e, 0x74, 0x68, 0x75, 0x6e, 0x64, 0x65, 0x72, 0x62, 0x69, 0x72, + 0x64, 0x72, 0x65, 0x70, 0x72, 0x65, 0x73, 0x65, 0x6e, 0x74, 0x65, 0x64, 0x26, + 0x61, 0x6d, 0x70, 0x3b, 0x6e, 0x64, 0x61, 0x73, 0x68, 0x3b, 0x73, 0x70, 0x65, + 0x63, 0x75, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x63, 0x6f, 0x6d, 0x6d, 0x75, + 0x6e, 0x69, 0x74, 0x69, 0x65, 0x73, 0x6c, 0x65, 0x67, 0x69, 0x73, 0x6c, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x72, 0x6f, 0x6e, 0x69, + 0x63, 0x73, 0x0a, 0x09, 0x3c, 0x64, 0x69, 0x76, 0x20, 0x69, 0x64, 0x3d, 0x22, + 0x69, 0x6c, 0x6c, 0x75, 0x73, 0x74, 0x72, 0x61, 0x74, 0x65, 0x64, 0x65, 0x6e, + 0x67, 0x69, 0x6e, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x74, 0x65, 0x72, 0x72, + 0x69, 0x74, 0x6f, 0x72, 0x69, 0x65, 0x73, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, + 0x69, 0x74, 0x69, 0x65, 0x73, 0x64, 0x69, 0x73, 0x74, 0x72, 0x69, 0x62, 0x75, + 0x74, 0x65, 0x64, 0x36, 0x22, 0x20, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x3d, + 0x22, 0x73, 0x61, 0x6e, 0x73, 0x2d, 0x73, 0x65, 0x72, 0x69, 0x66, 0x3b, 0x63, + 0x61, 0x70, 0x61, 0x62, 0x6c, 0x65, 0x20, 0x6f, 0x66, 0x20, 0x64, 0x69, 0x73, + 0x61, 0x70, 0x70, 0x65, 0x61, 0x72, 0x65, 0x64, 0x69, 0x6e, 0x74, 0x65, 0x72, + 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, 0x6c, 0x6f, 0x6f, 0x6b, 0x69, 0x6e, 0x67, + 0x20, 0x66, 0x6f, 0x72, 0x69, 0x74, 0x20, 0x77, 0x6f, 0x75, 0x6c, 0x64, 0x20, + 0x62, 0x65, 0x41, 0x66, 0x67, 0x68, 0x61, 0x6e, 0x69, 0x73, 0x74, 0x61, 0x6e, + 0x77, 0x61, 0x73, 0x20, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x4d, 0x61, + 0x74, 0x68, 0x2e, 0x66, 0x6c, 0x6f, 0x6f, 0x72, 0x28, 0x73, 0x75, 0x72, 0x72, + 0x6f, 0x75, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x63, 0x61, 0x6e, 0x20, 0x61, 0x6c, + 0x73, 0x6f, 0x20, 0x62, 0x65, 0x6f, 0x62, 0x73, 0x65, 0x72, 0x76, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x6d, 0x61, 0x69, 0x6e, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x63, + 0x65, 0x65, 0x6e, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x65, 0x64, 0x3c, + 0x68, 0x32, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x22, 0x6d, 0x6f, 0x72, + 0x65, 0x20, 0x72, 0x65, 0x63, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x20, 0x68, 0x61, + 0x73, 0x20, 0x62, 0x65, 0x65, 0x6e, 0x69, 0x6e, 0x76, 0x61, 0x73, 0x69, 0x6f, + 0x6e, 0x20, 0x6f, 0x66, 0x29, 0x2e, 0x67, 0x65, 0x74, 0x54, 0x69, 0x6d, 0x65, + 0x28, 0x29, 0x66, 0x75, 0x6e, 0x64, 0x61, 0x6d, 0x65, 0x6e, 0x74, 0x61, 0x6c, + 0x44, 0x65, 0x73, 0x70, 0x69, 0x74, 0x65, 0x20, 0x74, 0x68, 0x65, 0x22, 0x3e, + 0x3c, 0x64, 0x69, 0x76, 0x20, 0x69, 0x64, 0x3d, 0x22, 0x69, 0x6e, 0x73, 0x70, + 0x69, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x65, 0x78, 0x61, 0x6d, 0x69, 0x6e, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x70, 0x72, 0x65, 0x70, 0x61, 0x72, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x65, 0x78, 0x70, 0x6c, 0x61, 0x6e, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x3c, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x20, 0x69, 0x64, 0x3d, 0x22, 0x3c, + 0x2f, 0x61, 0x3e, 0x3c, 0x2f, 0x73, 0x70, 0x61, 0x6e, 0x3e, 0x76, 0x65, 0x72, + 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x6f, 0x66, 0x69, 0x6e, 0x73, 0x74, 0x72, + 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x62, 0x65, 0x66, 0x6f, 0x72, 0x65, 0x20, + 0x74, 0x68, 0x65, 0x20, 0x20, 0x3d, 0x20, 0x27, 0x68, 0x74, 0x74, 0x70, 0x3a, + 0x2f, 0x2f, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, + 0x72, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x76, 0x65, 0x6c, 0x79, 0x20, 0x2e, 0x73, + 0x75, 0x62, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x28, 0x65, 0x61, 0x63, 0x68, + 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x65, 0x78, 0x70, 0x65, 0x72, 0x69, + 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x69, 0x6e, 0x66, 0x6c, 0x75, 0x65, 0x6e, 0x74, + 0x69, 0x61, 0x6c, 0x69, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x6d, 0x61, 0x6e, 0x79, 0x20, 0x70, 0x65, 0x6f, 0x70, 0x6c, 0x65, 0x64, + 0x75, 0x65, 0x20, 0x74, 0x6f, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x6f, 0x6d, + 0x62, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x64, 0x6f, 0x20, 0x6e, 0x6f, + 0x74, 0x20, 0x68, 0x61, 0x76, 0x65, 0x4d, 0x69, 0x64, 0x64, 0x6c, 0x65, 0x20, + 0x45, 0x61, 0x73, 0x74, 0x3c, 0x6e, 0x6f, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, + 0x3e, 0x3c, 0x63, 0x6f, 0x70, 0x79, 0x72, 0x69, 0x67, 0x68, 0x74, 0x22, 0x20, + 0x70, 0x65, 0x72, 0x68, 0x61, 0x70, 0x73, 0x20, 0x74, 0x68, 0x65, 0x69, 0x6e, + 0x73, 0x74, 0x69, 0x74, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x69, 0x6e, 0x20, 0x44, + 0x65, 0x63, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x61, 0x72, 0x72, 0x61, 0x6e, 0x67, + 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x6d, 0x6f, 0x73, 0x74, 0x20, 0x66, 0x61, 0x6d, + 0x6f, 0x75, 0x73, 0x70, 0x65, 0x72, 0x73, 0x6f, 0x6e, 0x61, 0x6c, 0x69, 0x74, + 0x79, 0x63, 0x72, 0x65, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6f, 0x66, 0x6c, + 0x69, 0x6d, 0x69, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x65, 0x78, 0x63, + 0x6c, 0x75, 0x73, 0x69, 0x76, 0x65, 0x6c, 0x79, 0x73, 0x6f, 0x76, 0x65, 0x72, + 0x65, 0x69, 0x67, 0x6e, 0x74, 0x79, 0x2d, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, + 0x74, 0x22, 0x3e, 0x0a, 0x3c, 0x74, 0x64, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, + 0x3d, 0x22, 0x75, 0x6e, 0x64, 0x65, 0x72, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, + 0x70, 0x61, 0x72, 0x61, 0x6c, 0x6c, 0x65, 0x6c, 0x20, 0x74, 0x6f, 0x64, 0x6f, + 0x63, 0x74, 0x72, 0x69, 0x6e, 0x65, 0x20, 0x6f, 0x66, 0x6f, 0x63, 0x63, 0x75, + 0x70, 0x69, 0x65, 0x64, 0x20, 0x62, 0x79, 0x74, 0x65, 0x72, 0x6d, 0x69, 0x6e, + 0x6f, 0x6c, 0x6f, 0x67, 0x79, 0x52, 0x65, 0x6e, 0x61, 0x69, 0x73, 0x73, 0x61, + 0x6e, 0x63, 0x65, 0x61, 0x20, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x20, 0x6f, + 0x66, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x20, 0x66, 0x6f, 0x72, 0x65, + 0x78, 0x70, 0x6c, 0x6f, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x72, 0x65, 0x63, + 0x6f, 0x67, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x70, 0x72, 0x65, 0x64, 0x65, + 0x63, 0x65, 0x73, 0x73, 0x6f, 0x72, 0x3c, 0x69, 0x6d, 0x67, 0x20, 0x73, 0x72, + 0x63, 0x3d, 0x22, 0x2f, 0x3c, 0x68, 0x31, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, + 0x3d, 0x22, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x6d, 0x61, 0x79, 0x20, 0x61, 0x6c, 0x73, 0x6f, 0x20, 0x62, 0x65, 0x73, 0x70, + 0x65, 0x63, 0x69, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x64, 0x3c, 0x2f, 0x66, 0x69, + 0x65, 0x6c, 0x64, 0x73, 0x65, 0x74, 0x3e, 0x70, 0x72, 0x6f, 0x67, 0x72, 0x65, + 0x73, 0x73, 0x69, 0x76, 0x65, 0x6d, 0x69, 0x6c, 0x6c, 0x69, 0x6f, 0x6e, 0x73, + 0x20, 0x6f, 0x66, 0x73, 0x74, 0x61, 0x74, 0x65, 0x73, 0x20, 0x74, 0x68, 0x61, + 0x74, 0x65, 0x6e, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x61, + 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x20, 0x74, 0x68, 0x65, 0x20, 0x6f, 0x6e, 0x65, + 0x20, 0x61, 0x6e, 0x6f, 0x74, 0x68, 0x65, 0x72, 0x2e, 0x70, 0x61, 0x72, 0x65, + 0x6e, 0x74, 0x4e, 0x6f, 0x64, 0x65, 0x61, 0x67, 0x72, 0x69, 0x63, 0x75, 0x6c, + 0x74, 0x75, 0x72, 0x65, 0x41, 0x6c, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x74, 0x69, + 0x76, 0x65, 0x72, 0x65, 0x73, 0x65, 0x61, 0x72, 0x63, 0x68, 0x65, 0x72, 0x73, + 0x74, 0x6f, 0x77, 0x61, 0x72, 0x64, 0x73, 0x20, 0x74, 0x68, 0x65, 0x4d, 0x6f, + 0x73, 0x74, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x6d, 0x61, 0x6e, 0x79, + 0x20, 0x6f, 0x74, 0x68, 0x65, 0x72, 0x20, 0x28, 0x65, 0x73, 0x70, 0x65, 0x63, + 0x69, 0x61, 0x6c, 0x6c, 0x79, 0x3c, 0x74, 0x64, 0x20, 0x77, 0x69, 0x64, 0x74, + 0x68, 0x3d, 0x22, 0x3b, 0x77, 0x69, 0x64, 0x74, 0x68, 0x3a, 0x31, 0x30, 0x30, + 0x25, 0x69, 0x6e, 0x64, 0x65, 0x70, 0x65, 0x6e, 0x64, 0x65, 0x6e, 0x74, 0x3c, + 0x68, 0x33, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x22, 0x20, 0x6f, 0x6e, + 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x3d, 0x22, 0x29, 0x2e, 0x61, 0x64, 0x64, + 0x43, 0x6c, 0x61, 0x73, 0x73, 0x28, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x61, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x4f, 0x6e, 0x65, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, + 0x65, 0x20, 0x64, 0x61, 0x75, 0x67, 0x68, 0x74, 0x65, 0x72, 0x20, 0x6f, 0x66, + 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x6f, 0x72, 0x69, 0x65, 0x73, 0x62, 0x72, + 0x61, 0x6e, 0x63, 0x68, 0x65, 0x73, 0x20, 0x6f, 0x66, 0x0d, 0x0a, 0x3c, 0x64, + 0x69, 0x76, 0x20, 0x69, 0x64, 0x3d, 0x22, 0x74, 0x68, 0x65, 0x20, 0x6c, 0x61, + 0x72, 0x67, 0x65, 0x73, 0x74, 0x64, 0x65, 0x63, 0x6c, 0x61, 0x72, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x72, 0x65, 0x67, 0x75, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x73, 0x49, 0x6e, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x74, + 0x72, 0x61, 0x6e, 0x73, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x64, 0x6f, 0x63, + 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x61, 0x72, 0x79, 0x69, 0x6e, 0x20, 0x6f, 0x72, + 0x64, 0x65, 0x72, 0x20, 0x74, 0x6f, 0x22, 0x3e, 0x0a, 0x3c, 0x68, 0x65, 0x61, + 0x64, 0x3e, 0x0a, 0x3c, 0x22, 0x20, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x3d, + 0x22, 0x31, 0x61, 0x63, 0x72, 0x6f, 0x73, 0x73, 0x20, 0x74, 0x68, 0x65, 0x20, + 0x6f, 0x72, 0x69, 0x65, 0x6e, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x29, 0x3b, + 0x3c, 0x2f, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x3e, 0x69, 0x6d, 0x70, 0x6c, + 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x65, 0x64, 0x63, 0x61, 0x6e, 0x20, 0x62, 0x65, + 0x20, 0x73, 0x65, 0x65, 0x6e, 0x74, 0x68, 0x65, 0x72, 0x65, 0x20, 0x77, 0x61, + 0x73, 0x20, 0x61, 0x64, 0x65, 0x6d, 0x6f, 0x6e, 0x73, 0x74, 0x72, 0x61, 0x74, + 0x65, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x22, 0x3e, 0x63, + 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x74, 0x68, 0x65, + 0x20, 0x42, 0x72, 0x69, 0x74, 0x69, 0x73, 0x68, 0x77, 0x61, 0x73, 0x20, 0x77, + 0x72, 0x69, 0x74, 0x74, 0x65, 0x6e, 0x21, 0x69, 0x6d, 0x70, 0x6f, 0x72, 0x74, + 0x61, 0x6e, 0x74, 0x3b, 0x70, 0x78, 0x3b, 0x20, 0x6d, 0x61, 0x72, 0x67, 0x69, + 0x6e, 0x2d, 0x66, 0x6f, 0x6c, 0x6c, 0x6f, 0x77, 0x65, 0x64, 0x20, 0x62, 0x79, + 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x20, 0x74, 0x6f, 0x20, 0x63, 0x6f, + 0x6d, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x65, 0x64, 0x64, 0x75, 0x72, 0x69, + 0x6e, 0x67, 0x20, 0x74, 0x68, 0x65, 0x20, 0x69, 0x6d, 0x6d, 0x69, 0x67, 0x72, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x73, 0x6f, 0x20, 0x63, 0x61, 0x6c, + 0x6c, 0x65, 0x64, 0x3c, 0x68, 0x34, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x3d, + 0x22, 0x64, 0x69, 0x73, 0x74, 0x69, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x72, + 0x65, 0x70, 0x6c, 0x61, 0x63, 0x65, 0x64, 0x20, 0x62, 0x79, 0x67, 0x6f, 0x76, + 0x65, 0x72, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x6c, 0x6f, 0x63, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x20, 0x6f, 0x66, 0x69, 0x6e, 0x20, 0x4e, 0x6f, 0x76, 0x65, + 0x6d, 0x62, 0x65, 0x72, 0x77, 0x68, 0x65, 0x74, 0x68, 0x65, 0x72, 0x20, 0x74, + 0x68, 0x65, 0x3c, 0x2f, 0x70, 0x3e, 0x0a, 0x3c, 0x2f, 0x64, 0x69, 0x76, 0x3e, + 0x61, 0x63, 0x71, 0x75, 0x69, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x63, 0x61, + 0x6c, 0x6c, 0x65, 0x64, 0x20, 0x74, 0x68, 0x65, 0x20, 0x70, 0x65, 0x72, 0x73, + 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x64, 0x65, 0x73, 0x69, 0x67, 0x6e, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x7b, 0x66, 0x6f, 0x6e, 0x74, 0x2d, 0x73, 0x69, + 0x7a, 0x65, 0x3a, 0x61, 0x70, 0x70, 0x65, 0x61, 0x72, 0x65, 0x64, 0x20, 0x69, + 0x6e, 0x69, 0x6e, 0x76, 0x65, 0x73, 0x74, 0x69, 0x67, 0x61, 0x74, 0x65, 0x65, + 0x78, 0x70, 0x65, 0x72, 0x69, 0x65, 0x6e, 0x63, 0x65, 0x64, 0x6d, 0x6f, 0x73, + 0x74, 0x20, 0x6c, 0x69, 0x6b, 0x65, 0x6c, 0x79, 0x77, 0x69, 0x64, 0x65, 0x6c, + 0x79, 0x20, 0x75, 0x73, 0x65, 0x64, 0x64, 0x69, 0x73, 0x63, 0x75, 0x73, 0x73, + 0x69, 0x6f, 0x6e, 0x73, 0x70, 0x72, 0x65, 0x73, 0x65, 0x6e, 0x63, 0x65, 0x20, + 0x6f, 0x66, 0x20, 0x28, 0x64, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x2e, + 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x76, 0x65, 0x6c, 0x79, 0x49, 0x74, + 0x20, 0x68, 0x61, 0x73, 0x20, 0x62, 0x65, 0x65, 0x6e, 0x69, 0x74, 0x20, 0x64, + 0x6f, 0x65, 0x73, 0x20, 0x6e, 0x6f, 0x74, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x61, + 0x72, 0x79, 0x20, 0x74, 0x6f, 0x69, 0x6e, 0x68, 0x61, 0x62, 0x69, 0x74, 0x61, + 0x6e, 0x74, 0x73, 0x69, 0x6d, 0x70, 0x72, 0x6f, 0x76, 0x65, 0x6d, 0x65, 0x6e, + 0x74, 0x73, 0x63, 0x68, 0x6f, 0x6c, 0x61, 0x72, 0x73, 0x68, 0x69, 0x70, 0x63, + 0x6f, 0x6e, 0x73, 0x75, 0x6d, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x69, 0x6e, 0x73, + 0x74, 0x72, 0x75, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x66, 0x6f, 0x72, 0x20, 0x65, + 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x6f, 0x6e, 0x65, 0x20, 0x6f, 0x72, 0x20, + 0x6d, 0x6f, 0x72, 0x65, 0x70, 0x78, 0x3b, 0x20, 0x70, 0x61, 0x64, 0x64, 0x69, + 0x6e, 0x67, 0x74, 0x68, 0x65, 0x20, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, + 0x61, 0x20, 0x73, 0x65, 0x72, 0x69, 0x65, 0x73, 0x20, 0x6f, 0x66, 0x61, 0x72, + 0x65, 0x20, 0x75, 0x73, 0x75, 0x61, 0x6c, 0x6c, 0x79, 0x72, 0x6f, 0x6c, 0x65, + 0x20, 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x70, 0x72, 0x65, 0x76, 0x69, 0x6f, + 0x75, 0x73, 0x6c, 0x79, 0x20, 0x64, 0x65, 0x72, 0x69, 0x76, 0x61, 0x74, 0x69, + 0x76, 0x65, 0x73, 0x65, 0x76, 0x69, 0x64, 0x65, 0x6e, 0x63, 0x65, 0x20, 0x6f, + 0x66, 0x65, 0x78, 0x70, 0x65, 0x72, 0x69, 0x65, 0x6e, 0x63, 0x65, 0x73, 0x63, + 0x6f, 0x6c, 0x6f, 0x72, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x65, 0x73, 0x74, 0x61, + 0x74, 0x65, 0x64, 0x20, 0x74, 0x68, 0x61, 0x74, 0x63, 0x65, 0x72, 0x74, 0x69, + 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x3c, 0x2f, 0x61, 0x3e, 0x3c, 0x2f, 0x64, + 0x69, 0x76, 0x3e, 0x0a, 0x20, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x65, 0x64, + 0x3d, 0x22, 0x68, 0x69, 0x67, 0x68, 0x20, 0x73, 0x63, 0x68, 0x6f, 0x6f, 0x6c, + 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x20, 0x74, 0x6f, 0x63, 0x6f, + 0x6d, 0x66, 0x6f, 0x72, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x61, 0x64, 0x6f, 0x70, + 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6f, 0x66, 0x74, 0x68, 0x72, 0x65, 0x65, 0x20, + 0x79, 0x65, 0x61, 0x72, 0x73, 0x74, 0x68, 0x65, 0x20, 0x63, 0x6f, 0x75, 0x6e, + 0x74, 0x72, 0x79, 0x69, 0x6e, 0x20, 0x46, 0x65, 0x62, 0x72, 0x75, 0x61, 0x72, + 0x79, 0x73, 0x6f, 0x20, 0x74, 0x68, 0x61, 0x74, 0x20, 0x74, 0x68, 0x65, 0x70, + 0x65, 0x6f, 0x70, 0x6c, 0x65, 0x20, 0x77, 0x68, 0x6f, 0x20, 0x70, 0x72, 0x6f, + 0x76, 0x69, 0x64, 0x65, 0x64, 0x20, 0x62, 0x79, 0x3c, 0x70, 0x61, 0x72, 0x61, + 0x6d, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x61, 0x66, 0x66, 0x65, 0x63, 0x74, 0x65, + 0x64, 0x20, 0x62, 0x79, 0x69, 0x6e, 0x20, 0x74, 0x65, 0x72, 0x6d, 0x73, 0x20, + 0x6f, 0x66, 0x61, 0x70, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x6d, 0x65, 0x6e, 0x74, + 0x49, 0x53, 0x4f, 0x2d, 0x38, 0x38, 0x35, 0x39, 0x2d, 0x31, 0x22, 0x77, 0x61, + 0x73, 0x20, 0x62, 0x6f, 0x72, 0x6e, 0x20, 0x69, 0x6e, 0x68, 0x69, 0x73, 0x74, + 0x6f, 0x72, 0x69, 0x63, 0x61, 0x6c, 0x20, 0x72, 0x65, 0x67, 0x61, 0x72, 0x64, + 0x65, 0x64, 0x20, 0x61, 0x73, 0x6d, 0x65, 0x61, 0x73, 0x75, 0x72, 0x65, 0x6d, + 0x65, 0x6e, 0x74, 0x69, 0x73, 0x20, 0x62, 0x61, 0x73, 0x65, 0x64, 0x20, 0x6f, + 0x6e, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x6f, 0x74, 0x68, 0x65, 0x72, 0x20, 0x3a, + 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x73, 0x69, 0x67, + 0x6e, 0x69, 0x66, 0x69, 0x63, 0x61, 0x6e, 0x74, 0x63, 0x65, 0x6c, 0x65, 0x62, + 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x6d, 0x69, + 0x74, 0x74, 0x65, 0x64, 0x2f, 0x6a, 0x73, 0x2f, 0x6a, 0x71, 0x75, 0x65, 0x72, + 0x79, 0x2e, 0x69, 0x73, 0x20, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x20, 0x61, 0x73, + 0x74, 0x68, 0x65, 0x6f, 0x72, 0x65, 0x74, 0x69, 0x63, 0x61, 0x6c, 0x20, 0x74, + 0x61, 0x62, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x3d, 0x22, 0x69, 0x74, 0x20, 0x63, + 0x6f, 0x75, 0x6c, 0x64, 0x20, 0x62, 0x65, 0x3c, 0x6e, 0x6f, 0x73, 0x63, 0x72, + 0x69, 0x70, 0x74, 0x3e, 0x0a, 0x68, 0x61, 0x76, 0x69, 0x6e, 0x67, 0x20, 0x62, + 0x65, 0x65, 0x6e, 0x0d, 0x0a, 0x3c, 0x68, 0x65, 0x61, 0x64, 0x3e, 0x0d, 0x0a, + 0x3c, 0x20, 0x26, 0x71, 0x75, 0x6f, 0x74, 0x3b, 0x54, 0x68, 0x65, 0x20, 0x63, + 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x68, 0x65, 0x20, + 0x68, 0x61, 0x64, 0x20, 0x62, 0x65, 0x65, 0x6e, 0x70, 0x72, 0x6f, 0x64, 0x75, + 0x63, 0x65, 0x64, 0x20, 0x62, 0x79, 0x70, 0x68, 0x69, 0x6c, 0x6f, 0x73, 0x6f, + 0x70, 0x68, 0x65, 0x72, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, + 0x65, 0x64, 0x69, 0x6e, 0x74, 0x65, 0x6e, 0x64, 0x65, 0x64, 0x20, 0x74, 0x6f, + 0x61, 0x6d, 0x6f, 0x6e, 0x67, 0x20, 0x6f, 0x74, 0x68, 0x65, 0x72, 0x63, 0x6f, + 0x6d, 0x70, 0x61, 0x72, 0x65, 0x64, 0x20, 0x74, 0x6f, 0x74, 0x6f, 0x20, 0x73, + 0x61, 0x79, 0x20, 0x74, 0x68, 0x61, 0x74, 0x45, 0x6e, 0x67, 0x69, 0x6e, 0x65, + 0x65, 0x72, 0x69, 0x6e, 0x67, 0x61, 0x20, 0x64, 0x69, 0x66, 0x66, 0x65, 0x72, + 0x65, 0x6e, 0x74, 0x72, 0x65, 0x66, 0x65, 0x72, 0x72, 0x65, 0x64, 0x20, 0x74, + 0x6f, 0x64, 0x69, 0x66, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x73, 0x62, + 0x65, 0x6c, 0x69, 0x65, 0x66, 0x20, 0x74, 0x68, 0x61, 0x74, 0x70, 0x68, 0x6f, + 0x74, 0x6f, 0x67, 0x72, 0x61, 0x70, 0x68, 0x73, 0x69, 0x64, 0x65, 0x6e, 0x74, + 0x69, 0x66, 0x79, 0x69, 0x6e, 0x67, 0x48, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, + 0x20, 0x6f, 0x66, 0x20, 0x52, 0x65, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x20, + 0x6f, 0x66, 0x6e, 0x65, 0x63, 0x65, 0x73, 0x73, 0x61, 0x72, 0x69, 0x6c, 0x79, + 0x70, 0x72, 0x6f, 0x62, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x74, 0x65, + 0x63, 0x68, 0x6e, 0x69, 0x63, 0x61, 0x6c, 0x6c, 0x79, 0x6c, 0x65, 0x61, 0x76, + 0x69, 0x6e, 0x67, 0x20, 0x74, 0x68, 0x65, 0x73, 0x70, 0x65, 0x63, 0x74, 0x61, + 0x63, 0x75, 0x6c, 0x61, 0x72, 0x66, 0x72, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x20, 0x6f, 0x66, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x72, 0x69, 0x63, 0x69, 0x74, + 0x79, 0x68, 0x65, 0x61, 0x64, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x72, + 0x65, 0x73, 0x74, 0x61, 0x75, 0x72, 0x61, 0x6e, 0x74, 0x73, 0x70, 0x61, 0x72, + 0x74, 0x6e, 0x65, 0x72, 0x73, 0x68, 0x69, 0x70, 0x65, 0x6d, 0x70, 0x68, 0x61, + 0x73, 0x69, 0x73, 0x20, 0x6f, 0x6e, 0x6d, 0x6f, 0x73, 0x74, 0x20, 0x72, 0x65, + 0x63, 0x65, 0x6e, 0x74, 0x73, 0x68, 0x61, 0x72, 0x65, 0x20, 0x77, 0x69, 0x74, + 0x68, 0x20, 0x73, 0x61, 0x79, 0x69, 0x6e, 0x67, 0x20, 0x74, 0x68, 0x61, 0x74, + 0x66, 0x69, 0x6c, 0x6c, 0x65, 0x64, 0x20, 0x77, 0x69, 0x74, 0x68, 0x64, 0x65, + 0x73, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x20, 0x74, 0x6f, 0x69, 0x74, 0x20, 0x69, + 0x73, 0x20, 0x6f, 0x66, 0x74, 0x65, 0x6e, 0x22, 0x3e, 0x3c, 0x2f, 0x69, 0x66, + 0x72, 0x61, 0x6d, 0x65, 0x3e, 0x61, 0x73, 0x20, 0x66, 0x6f, 0x6c, 0x6c, 0x6f, + 0x77, 0x73, 0x3a, 0x6d, 0x65, 0x72, 0x67, 0x65, 0x64, 0x20, 0x77, 0x69, 0x74, + 0x68, 0x74, 0x68, 0x72, 0x6f, 0x75, 0x67, 0x68, 0x20, 0x74, 0x68, 0x65, 0x63, + 0x6f, 0x6d, 0x6d, 0x65, 0x72, 0x63, 0x69, 0x61, 0x6c, 0x20, 0x70, 0x6f, 0x69, + 0x6e, 0x74, 0x65, 0x64, 0x20, 0x6f, 0x75, 0x74, 0x6f, 0x70, 0x70, 0x6f, 0x72, + 0x74, 0x75, 0x6e, 0x69, 0x74, 0x79, 0x76, 0x69, 0x65, 0x77, 0x20, 0x6f, 0x66, + 0x20, 0x74, 0x68, 0x65, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x6d, 0x65, + 0x6e, 0x74, 0x64, 0x69, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x20, 0x6f, 0x66, + 0x70, 0x72, 0x6f, 0x67, 0x72, 0x61, 0x6d, 0x6d, 0x69, 0x6e, 0x67, 0x68, 0x65, + 0x20, 0x72, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x64, 0x73, 0x65, 0x74, 0x49, + 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x22, 0x3e, 0x3c, 0x2f, 0x73, 0x70, + 0x61, 0x6e, 0x3e, 0x3c, 0x2f, 0x69, 0x6e, 0x20, 0x4e, 0x65, 0x77, 0x20, 0x59, + 0x6f, 0x72, 0x6b, 0x61, 0x64, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, + 0x20, 0x63, 0x6f, 0x6d, 0x70, 0x72, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x0a, + 0x0a, 0x3c, 0x64, 0x69, 0x76, 0x20, 0x69, 0x64, 0x3d, 0x22, 0x69, 0x6e, 0x63, + 0x6f, 0x72, 0x70, 0x6f, 0x72, 0x61, 0x74, 0x65, 0x3b, 0x3c, 0x2f, 0x73, 0x63, + 0x72, 0x69, 0x70, 0x74, 0x3e, 0x3c, 0x61, 0x74, 0x74, 0x61, 0x63, 0x68, 0x45, + 0x76, 0x65, 0x6e, 0x74, 0x62, 0x65, 0x63, 0x61, 0x6d, 0x65, 0x20, 0x74, 0x68, + 0x65, 0x20, 0x22, 0x20, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x3d, 0x22, 0x5f, + 0x63, 0x61, 0x72, 0x72, 0x69, 0x65, 0x64, 0x20, 0x6f, 0x75, 0x74, 0x53, 0x6f, + 0x6d, 0x65, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x73, 0x63, 0x69, 0x65, + 0x6e, 0x63, 0x65, 0x20, 0x61, 0x6e, 0x64, 0x74, 0x68, 0x65, 0x20, 0x74, 0x69, + 0x6d, 0x65, 0x20, 0x6f, 0x66, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, + 0x72, 0x22, 0x3e, 0x6d, 0x61, 0x69, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x69, 0x6e, + 0x67, 0x43, 0x68, 0x72, 0x69, 0x73, 0x74, 0x6f, 0x70, 0x68, 0x65, 0x72, 0x4d, + 0x75, 0x63, 0x68, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x77, 0x72, 0x69, + 0x74, 0x69, 0x6e, 0x67, 0x73, 0x20, 0x6f, 0x66, 0x22, 0x20, 0x68, 0x65, 0x69, + 0x67, 0x68, 0x74, 0x3d, 0x22, 0x32, 0x73, 0x69, 0x7a, 0x65, 0x20, 0x6f, 0x66, + 0x20, 0x74, 0x68, 0x65, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x20, 0x6f, + 0x66, 0x20, 0x6d, 0x69, 0x78, 0x74, 0x75, 0x72, 0x65, 0x20, 0x6f, 0x66, 0x20, + 0x62, 0x65, 0x74, 0x77, 0x65, 0x65, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x45, 0x78, + 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x73, 0x20, 0x6f, 0x66, 0x65, 0x64, 0x75, 0x63, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x63, 0x6f, 0x6d, 0x70, 0x65, 0x74, + 0x69, 0x74, 0x69, 0x76, 0x65, 0x20, 0x6f, 0x6e, 0x73, 0x75, 0x62, 0x6d, 0x69, + 0x74, 0x3d, 0x22, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x20, 0x6f, + 0x66, 0x64, 0x69, 0x73, 0x74, 0x69, 0x6e, 0x63, 0x74, 0x69, 0x76, 0x65, 0x2f, + 0x44, 0x54, 0x44, 0x20, 0x58, 0x48, 0x54, 0x4d, 0x4c, 0x20, 0x72, 0x65, 0x6c, + 0x61, 0x74, 0x69, 0x6e, 0x67, 0x20, 0x74, 0x6f, 0x74, 0x65, 0x6e, 0x64, 0x65, + 0x6e, 0x63, 0x79, 0x20, 0x74, 0x6f, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x6e, 0x63, + 0x65, 0x20, 0x6f, 0x66, 0x77, 0x68, 0x69, 0x63, 0x68, 0x20, 0x77, 0x6f, 0x75, + 0x6c, 0x64, 0x64, 0x65, 0x73, 0x70, 0x69, 0x74, 0x65, 0x20, 0x74, 0x68, 0x65, + 0x73, 0x63, 0x69, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x63, 0x20, 0x6c, 0x65, + 0x67, 0x69, 0x73, 0x6c, 0x61, 0x74, 0x75, 0x72, 0x65, 0x2e, 0x69, 0x6e, 0x6e, + 0x65, 0x72, 0x48, 0x54, 0x4d, 0x4c, 0x20, 0x61, 0x6c, 0x6c, 0x65, 0x67, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x41, 0x67, 0x72, 0x69, 0x63, 0x75, 0x6c, 0x74, + 0x75, 0x72, 0x65, 0x77, 0x61, 0x73, 0x20, 0x75, 0x73, 0x65, 0x64, 0x20, 0x69, + 0x6e, 0x61, 0x70, 0x70, 0x72, 0x6f, 0x61, 0x63, 0x68, 0x20, 0x74, 0x6f, 0x69, + 0x6e, 0x74, 0x65, 0x6c, 0x6c, 0x69, 0x67, 0x65, 0x6e, 0x74, 0x79, 0x65, 0x61, + 0x72, 0x73, 0x20, 0x6c, 0x61, 0x74, 0x65, 0x72, 0x2c, 0x73, 0x61, 0x6e, 0x73, + 0x2d, 0x73, 0x65, 0x72, 0x69, 0x66, 0x64, 0x65, 0x74, 0x65, 0x72, 0x6d, 0x69, + 0x6e, 0x69, 0x6e, 0x67, 0x50, 0x65, 0x72, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x6e, + 0x63, 0x65, 0x61, 0x70, 0x70, 0x65, 0x61, 0x72, 0x61, 0x6e, 0x63, 0x65, 0x73, + 0x2c, 0x20, 0x77, 0x68, 0x69, 0x63, 0x68, 0x20, 0x69, 0x73, 0x20, 0x66, 0x6f, + 0x75, 0x6e, 0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x61, 0x62, 0x62, 0x72, + 0x65, 0x76, 0x69, 0x61, 0x74, 0x65, 0x64, 0x68, 0x69, 0x67, 0x68, 0x65, 0x72, + 0x20, 0x74, 0x68, 0x61, 0x6e, 0x73, 0x20, 0x66, 0x72, 0x6f, 0x6d, 0x20, 0x74, + 0x68, 0x65, 0x20, 0x69, 0x6e, 0x64, 0x69, 0x76, 0x69, 0x64, 0x75, 0x61, 0x6c, + 0x20, 0x63, 0x6f, 0x6d, 0x70, 0x6f, 0x73, 0x65, 0x64, 0x20, 0x6f, 0x66, 0x73, + 0x75, 0x70, 0x70, 0x6f, 0x73, 0x65, 0x64, 0x20, 0x74, 0x6f, 0x63, 0x6c, 0x61, + 0x69, 0x6d, 0x73, 0x20, 0x74, 0x68, 0x61, 0x74, 0x61, 0x74, 0x74, 0x72, 0x69, + 0x62, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x66, 0x6f, 0x6e, 0x74, 0x2d, 0x73, 0x69, + 0x7a, 0x65, 0x3a, 0x31, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x20, + 0x6f, 0x66, 0x48, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x69, 0x63, 0x61, 0x6c, 0x20, + 0x68, 0x69, 0x73, 0x20, 0x62, 0x72, 0x6f, 0x74, 0x68, 0x65, 0x72, 0x61, 0x74, + 0x20, 0x74, 0x68, 0x65, 0x20, 0x74, 0x69, 0x6d, 0x65, 0x61, 0x6e, 0x6e, 0x69, + 0x76, 0x65, 0x72, 0x73, 0x61, 0x72, 0x79, 0x67, 0x6f, 0x76, 0x65, 0x72, 0x6e, + 0x65, 0x64, 0x20, 0x62, 0x79, 0x72, 0x65, 0x6c, 0x61, 0x74, 0x65, 0x64, 0x20, + 0x74, 0x6f, 0x20, 0x75, 0x6c, 0x74, 0x69, 0x6d, 0x61, 0x74, 0x65, 0x6c, 0x79, + 0x20, 0x69, 0x6e, 0x6e, 0x6f, 0x76, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x69, + 0x74, 0x20, 0x69, 0x73, 0x20, 0x73, 0x74, 0x69, 0x6c, 0x6c, 0x63, 0x61, 0x6e, + 0x20, 0x6f, 0x6e, 0x6c, 0x79, 0x20, 0x62, 0x65, 0x64, 0x65, 0x66, 0x69, 0x6e, + 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x74, 0x6f, 0x47, 0x4d, 0x54, 0x53, 0x74, + 0x72, 0x69, 0x6e, 0x67, 0x41, 0x20, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x20, + 0x6f, 0x66, 0x69, 0x6d, 0x67, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x22, + 0x45, 0x76, 0x65, 0x6e, 0x74, 0x75, 0x61, 0x6c, 0x6c, 0x79, 0x2c, 0x77, 0x61, + 0x73, 0x20, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x64, 0x6f, 0x63, 0x63, 0x75, + 0x72, 0x72, 0x65, 0x64, 0x20, 0x69, 0x6e, 0x6e, 0x65, 0x69, 0x67, 0x68, 0x62, + 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x64, 0x69, 0x73, 0x74, 0x69, 0x6e, 0x67, 0x75, + 0x69, 0x73, 0x68, 0x77, 0x68, 0x65, 0x6e, 0x20, 0x68, 0x65, 0x20, 0x77, 0x61, + 0x73, 0x69, 0x6e, 0x74, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x69, 0x6e, 0x67, 0x74, + 0x65, 0x72, 0x72, 0x65, 0x73, 0x74, 0x72, 0x69, 0x61, 0x6c, 0x4d, 0x61, 0x6e, + 0x79, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x61, 0x72, 0x67, 0x75, 0x65, + 0x73, 0x20, 0x74, 0x68, 0x61, 0x74, 0x61, 0x6e, 0x20, 0x41, 0x6d, 0x65, 0x72, + 0x69, 0x63, 0x61, 0x6e, 0x63, 0x6f, 0x6e, 0x71, 0x75, 0x65, 0x73, 0x74, 0x20, + 0x6f, 0x66, 0x77, 0x69, 0x64, 0x65, 0x73, 0x70, 0x72, 0x65, 0x61, 0x64, 0x20, + 0x77, 0x65, 0x72, 0x65, 0x20, 0x6b, 0x69, 0x6c, 0x6c, 0x65, 0x64, 0x73, 0x63, + 0x72, 0x65, 0x65, 0x6e, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x49, 0x6e, 0x20, 0x6f, + 0x72, 0x64, 0x65, 0x72, 0x20, 0x74, 0x6f, 0x65, 0x78, 0x70, 0x65, 0x63, 0x74, + 0x65, 0x64, 0x20, 0x74, 0x6f, 0x64, 0x65, 0x73, 0x63, 0x65, 0x6e, 0x64, 0x61, + 0x6e, 0x74, 0x73, 0x61, 0x72, 0x65, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x65, + 0x64, 0x6c, 0x65, 0x67, 0x69, 0x73, 0x6c, 0x61, 0x74, 0x69, 0x76, 0x65, 0x67, + 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x62, 0x61, + 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x6d, 0x6f, 0x73, 0x74, 0x20, + 0x70, 0x65, 0x6f, 0x70, 0x6c, 0x65, 0x79, 0x65, 0x61, 0x72, 0x73, 0x20, 0x61, + 0x66, 0x74, 0x65, 0x72, 0x74, 0x68, 0x65, 0x72, 0x65, 0x20, 0x69, 0x73, 0x20, + 0x6e, 0x6f, 0x74, 0x68, 0x65, 0x20, 0x68, 0x69, 0x67, 0x68, 0x65, 0x73, 0x74, + 0x66, 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x74, 0x6c, 0x79, 0x20, 0x74, 0x68, + 0x65, 0x79, 0x20, 0x64, 0x6f, 0x20, 0x6e, 0x6f, 0x74, 0x61, 0x72, 0x67, 0x75, + 0x65, 0x64, 0x20, 0x74, 0x68, 0x61, 0x74, 0x73, 0x68, 0x6f, 0x77, 0x65, 0x64, + 0x20, 0x74, 0x68, 0x61, 0x74, 0x70, 0x72, 0x65, 0x64, 0x6f, 0x6d, 0x69, 0x6e, + 0x61, 0x6e, 0x74, 0x74, 0x68, 0x65, 0x6f, 0x6c, 0x6f, 0x67, 0x69, 0x63, 0x61, + 0x6c, 0x62, 0x79, 0x20, 0x74, 0x68, 0x65, 0x20, 0x74, 0x69, 0x6d, 0x65, 0x63, + 0x6f, 0x6e, 0x73, 0x69, 0x64, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x73, 0x68, 0x6f, + 0x72, 0x74, 0x2d, 0x6c, 0x69, 0x76, 0x65, 0x64, 0x3c, 0x2f, 0x73, 0x70, 0x61, + 0x6e, 0x3e, 0x3c, 0x2f, 0x61, 0x3e, 0x63, 0x61, 0x6e, 0x20, 0x62, 0x65, 0x20, + 0x75, 0x73, 0x65, 0x64, 0x76, 0x65, 0x72, 0x79, 0x20, 0x6c, 0x69, 0x74, 0x74, + 0x6c, 0x65, 0x6f, 0x6e, 0x65, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, + 0x68, 0x61, 0x64, 0x20, 0x61, 0x6c, 0x72, 0x65, 0x61, 0x64, 0x79, 0x69, 0x6e, + 0x74, 0x65, 0x72, 0x70, 0x72, 0x65, 0x74, 0x65, 0x64, 0x63, 0x6f, 0x6d, 0x6d, + 0x75, 0x6e, 0x69, 0x63, 0x61, 0x74, 0x65, 0x66, 0x65, 0x61, 0x74, 0x75, 0x72, + 0x65, 0x73, 0x20, 0x6f, 0x66, 0x67, 0x6f, 0x76, 0x65, 0x72, 0x6e, 0x6d, 0x65, + 0x6e, 0x74, 0x2c, 0x3c, 0x2f, 0x6e, 0x6f, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, + 0x3e, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x65, 0x64, 0x20, 0x74, 0x68, 0x65, 0x22, + 0x20, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x3d, 0x22, 0x33, 0x49, 0x6e, 0x64, + 0x65, 0x70, 0x65, 0x6e, 0x64, 0x65, 0x6e, 0x74, 0x70, 0x6f, 0x70, 0x75, 0x6c, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x6c, 0x61, 0x72, 0x67, 0x65, 0x2d, 0x73, + 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x20, 0x41, 0x6c, 0x74, 0x68, 0x6f, 0x75, 0x67, + 0x68, 0x20, 0x75, 0x73, 0x65, 0x64, 0x20, 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, + 0x64, 0x65, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x70, 0x6f, + 0x73, 0x73, 0x69, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x73, 0x74, 0x61, 0x72, + 0x74, 0x69, 0x6e, 0x67, 0x20, 0x69, 0x6e, 0x74, 0x77, 0x6f, 0x20, 0x6f, 0x72, + 0x20, 0x6d, 0x6f, 0x72, 0x65, 0x65, 0x78, 0x70, 0x72, 0x65, 0x73, 0x73, 0x69, + 0x6f, 0x6e, 0x73, 0x73, 0x75, 0x62, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x61, 0x74, + 0x65, 0x6c, 0x61, 0x72, 0x67, 0x65, 0x72, 0x20, 0x74, 0x68, 0x61, 0x6e, 0x68, + 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x20, 0x61, 0x6e, 0x64, 0x3c, 0x2f, 0x6f, + 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x3e, 0x0d, 0x0a, 0x43, 0x6f, 0x6e, 0x74, 0x69, + 0x6e, 0x65, 0x6e, 0x74, 0x61, 0x6c, 0x65, 0x6c, 0x69, 0x6d, 0x69, 0x6e, 0x61, + 0x74, 0x69, 0x6e, 0x67, 0x77, 0x69, 0x6c, 0x6c, 0x20, 0x6e, 0x6f, 0x74, 0x20, + 0x62, 0x65, 0x70, 0x72, 0x61, 0x63, 0x74, 0x69, 0x63, 0x65, 0x20, 0x6f, 0x66, + 0x69, 0x6e, 0x20, 0x66, 0x72, 0x6f, 0x6e, 0x74, 0x20, 0x6f, 0x66, 0x73, 0x69, + 0x74, 0x65, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x65, 0x6e, 0x73, 0x75, + 0x72, 0x65, 0x20, 0x74, 0x68, 0x61, 0x74, 0x74, 0x6f, 0x20, 0x63, 0x72, 0x65, + 0x61, 0x74, 0x65, 0x20, 0x61, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x73, 0x73, 0x69, + 0x70, 0x70, 0x69, 0x70, 0x6f, 0x74, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x6c, + 0x79, 0x6f, 0x75, 0x74, 0x73, 0x74, 0x61, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x62, + 0x65, 0x74, 0x74, 0x65, 0x72, 0x20, 0x74, 0x68, 0x61, 0x6e, 0x77, 0x68, 0x61, + 0x74, 0x20, 0x69, 0x73, 0x20, 0x6e, 0x6f, 0x77, 0x73, 0x69, 0x74, 0x75, 0x61, + 0x74, 0x65, 0x64, 0x20, 0x69, 0x6e, 0x6d, 0x65, 0x74, 0x61, 0x20, 0x6e, 0x61, + 0x6d, 0x65, 0x3d, 0x22, 0x54, 0x72, 0x61, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, + 0x61, 0x6c, 0x73, 0x75, 0x67, 0x67, 0x65, 0x73, 0x74, 0x69, 0x6f, 0x6e, 0x73, + 0x54, 0x72, 0x61, 0x6e, 0x73, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x74, 0x68, + 0x65, 0x20, 0x66, 0x6f, 0x72, 0x6d, 0x20, 0x6f, 0x66, 0x61, 0x74, 0x6d, 0x6f, + 0x73, 0x70, 0x68, 0x65, 0x72, 0x69, 0x63, 0x69, 0x64, 0x65, 0x6f, 0x6c, 0x6f, + 0x67, 0x69, 0x63, 0x61, 0x6c, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x70, 0x72, 0x69, + 0x73, 0x65, 0x73, 0x63, 0x61, 0x6c, 0x63, 0x75, 0x6c, 0x61, 0x74, 0x69, 0x6e, + 0x67, 0x65, 0x61, 0x73, 0x74, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x72, + 0x65, 0x6d, 0x6e, 0x61, 0x6e, 0x74, 0x73, 0x20, 0x6f, 0x66, 0x70, 0x6c, 0x75, + 0x67, 0x69, 0x6e, 0x73, 0x70, 0x61, 0x67, 0x65, 0x2f, 0x69, 0x6e, 0x64, 0x65, + 0x78, 0x2e, 0x70, 0x68, 0x70, 0x3f, 0x72, 0x65, 0x6d, 0x61, 0x69, 0x6e, 0x65, + 0x64, 0x20, 0x69, 0x6e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x6f, 0x72, 0x6d, + 0x65, 0x64, 0x48, 0x65, 0x20, 0x77, 0x61, 0x73, 0x20, 0x61, 0x6c, 0x73, 0x6f, + 0x77, 0x61, 0x73, 0x20, 0x61, 0x6c, 0x72, 0x65, 0x61, 0x64, 0x79, 0x73, 0x74, + 0x61, 0x74, 0x69, 0x73, 0x74, 0x69, 0x63, 0x61, 0x6c, 0x69, 0x6e, 0x20, 0x66, + 0x61, 0x76, 0x6f, 0x72, 0x20, 0x6f, 0x66, 0x4d, 0x69, 0x6e, 0x69, 0x73, 0x74, + 0x72, 0x79, 0x20, 0x6f, 0x66, 0x6d, 0x6f, 0x76, 0x65, 0x6d, 0x65, 0x6e, 0x74, + 0x20, 0x6f, 0x66, 0x66, 0x6f, 0x72, 0x6d, 0x75, 0x6c, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x69, 0x73, 0x20, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x3c, + 0x6c, 0x69, 0x6e, 0x6b, 0x20, 0x72, 0x65, 0x6c, 0x3d, 0x22, 0x54, 0x68, 0x69, + 0x73, 0x20, 0x69, 0x73, 0x20, 0x74, 0x68, 0x65, 0x20, 0x3c, 0x61, 0x20, 0x68, + 0x72, 0x65, 0x66, 0x3d, 0x22, 0x2f, 0x70, 0x6f, 0x70, 0x75, 0x6c, 0x61, 0x72, + 0x69, 0x7a, 0x65, 0x64, 0x69, 0x6e, 0x76, 0x6f, 0x6c, 0x76, 0x65, 0x64, 0x20, + 0x69, 0x6e, 0x61, 0x72, 0x65, 0x20, 0x75, 0x73, 0x65, 0x64, 0x20, 0x74, 0x6f, + 0x61, 0x6e, 0x64, 0x20, 0x73, 0x65, 0x76, 0x65, 0x72, 0x61, 0x6c, 0x6d, 0x61, + 0x64, 0x65, 0x20, 0x62, 0x79, 0x20, 0x74, 0x68, 0x65, 0x73, 0x65, 0x65, 0x6d, + 0x73, 0x20, 0x74, 0x6f, 0x20, 0x62, 0x65, 0x6c, 0x69, 0x6b, 0x65, 0x6c, 0x79, + 0x20, 0x74, 0x68, 0x61, 0x74, 0x50, 0x61, 0x6c, 0x65, 0x73, 0x74, 0x69, 0x6e, + 0x69, 0x61, 0x6e, 0x6e, 0x61, 0x6d, 0x65, 0x64, 0x20, 0x61, 0x66, 0x74, 0x65, + 0x72, 0x69, 0x74, 0x20, 0x68, 0x61, 0x64, 0x20, 0x62, 0x65, 0x65, 0x6e, 0x6d, + 0x6f, 0x73, 0x74, 0x20, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x74, 0x6f, 0x20, + 0x72, 0x65, 0x66, 0x65, 0x72, 0x20, 0x74, 0x6f, 0x62, 0x75, 0x74, 0x20, 0x74, + 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, 0x63, 0x6f, 0x6e, 0x73, 0x65, 0x63, 0x75, + 0x74, 0x69, 0x76, 0x65, 0x74, 0x65, 0x6d, 0x70, 0x6f, 0x72, 0x61, 0x72, 0x69, + 0x6c, 0x79, 0x49, 0x6e, 0x20, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x6c, 0x2c, + 0x63, 0x6f, 0x6e, 0x76, 0x65, 0x6e, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x74, 0x61, + 0x6b, 0x65, 0x73, 0x20, 0x70, 0x6c, 0x61, 0x63, 0x65, 0x73, 0x75, 0x62, 0x64, + 0x69, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x74, 0x65, 0x72, 0x72, 0x69, 0x74, + 0x6f, 0x72, 0x69, 0x61, 0x6c, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x61, 0x6c, 0x70, 0x65, 0x72, 0x6d, 0x61, 0x6e, 0x65, 0x6e, 0x74, 0x6c, + 0x79, 0x77, 0x61, 0x73, 0x20, 0x6c, 0x61, 0x72, 0x67, 0x65, 0x6c, 0x79, 0x6f, + 0x75, 0x74, 0x62, 0x72, 0x65, 0x61, 0x6b, 0x20, 0x6f, 0x66, 0x69, 0x6e, 0x20, + 0x74, 0x68, 0x65, 0x20, 0x70, 0x61, 0x73, 0x74, 0x66, 0x6f, 0x6c, 0x6c, 0x6f, + 0x77, 0x69, 0x6e, 0x67, 0x20, 0x61, 0x20, 0x78, 0x6d, 0x6c, 0x6e, 0x73, 0x3a, + 0x6f, 0x67, 0x3d, 0x22, 0x3e, 0x3c, 0x61, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, + 0x3d, 0x22, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x22, 0x74, 0x65, 0x78, 0x74, + 0x43, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x20, 0x6d, 0x61, + 0x79, 0x20, 0x62, 0x65, 0x20, 0x75, 0x73, 0x65, 0x64, 0x6d, 0x61, 0x6e, 0x75, + 0x66, 0x61, 0x63, 0x74, 0x75, 0x72, 0x65, 0x61, 0x66, 0x74, 0x65, 0x72, 0x20, + 0x62, 0x65, 0x69, 0x6e, 0x67, 0x63, 0x6c, 0x65, 0x61, 0x72, 0x66, 0x69, 0x78, + 0x22, 0x3e, 0x0a, 0x71, 0x75, 0x65, 0x73, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6f, + 0x66, 0x77, 0x61, 0x73, 0x20, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x65, 0x64, 0x74, + 0x6f, 0x20, 0x62, 0x65, 0x63, 0x6f, 0x6d, 0x65, 0x20, 0x61, 0x62, 0x65, 0x63, + 0x61, 0x75, 0x73, 0x65, 0x20, 0x6f, 0x66, 0x20, 0x73, 0x6f, 0x6d, 0x65, 0x20, + 0x70, 0x65, 0x6f, 0x70, 0x6c, 0x65, 0x69, 0x6e, 0x73, 0x70, 0x69, 0x72, 0x65, + 0x64, 0x20, 0x62, 0x79, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x66, 0x75, + 0x6c, 0x20, 0x61, 0x20, 0x74, 0x69, 0x6d, 0x65, 0x20, 0x77, 0x68, 0x65, 0x6e, + 0x6d, 0x6f, 0x72, 0x65, 0x20, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x61, 0x6d, + 0x6f, 0x6e, 0x67, 0x73, 0x74, 0x20, 0x74, 0x68, 0x65, 0x61, 0x6e, 0x20, 0x6f, + 0x66, 0x66, 0x69, 0x63, 0x69, 0x61, 0x6c, 0x77, 0x69, 0x64, 0x74, 0x68, 0x3a, + 0x31, 0x30, 0x30, 0x25, 0x3b, 0x74, 0x65, 0x63, 0x68, 0x6e, 0x6f, 0x6c, 0x6f, + 0x67, 0x79, 0x2c, 0x77, 0x61, 0x73, 0x20, 0x61, 0x64, 0x6f, 0x70, 0x74, 0x65, + 0x64, 0x74, 0x6f, 0x20, 0x6b, 0x65, 0x65, 0x70, 0x20, 0x74, 0x68, 0x65, 0x73, + 0x65, 0x74, 0x74, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x6c, 0x69, 0x76, + 0x65, 0x20, 0x62, 0x69, 0x72, 0x74, 0x68, 0x73, 0x69, 0x6e, 0x64, 0x65, 0x78, + 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0x22, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, + 0x69, 0x63, 0x75, 0x74, 0x61, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x20, + 0x74, 0x6f, 0x26, 0x61, 0x6d, 0x70, 0x3b, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x3b, + 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x20, 0x66, 0x6f, 0x72, 0x61, 0x6c, + 0x69, 0x67, 0x6e, 0x3d, 0x72, 0x69, 0x67, 0x68, 0x74, 0x74, 0x68, 0x65, 0x20, + 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x6e, 0x79, 0x61, 0x6c, 0x77, 0x61, 0x79, 0x73, + 0x20, 0x62, 0x65, 0x65, 0x6e, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x65, 0x64, + 0x20, 0x74, 0x6f, 0x69, 0x6e, 0x76, 0x6f, 0x6c, 0x76, 0x65, 0x6d, 0x65, 0x6e, + 0x74, 0x42, 0x65, 0x63, 0x61, 0x75, 0x73, 0x65, 0x20, 0x74, 0x68, 0x65, 0x74, + 0x68, 0x69, 0x73, 0x20, 0x70, 0x65, 0x72, 0x69, 0x6f, 0x64, 0x22, 0x20, 0x6e, + 0x61, 0x6d, 0x65, 0x3d, 0x22, 0x71, 0x22, 0x20, 0x63, 0x6f, 0x6e, 0x66, 0x69, + 0x6e, 0x65, 0x64, 0x20, 0x74, 0x6f, 0x61, 0x20, 0x72, 0x65, 0x73, 0x75, 0x6c, + 0x74, 0x20, 0x6f, 0x66, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3d, 0x22, 0x22, 0x20, + 0x2f, 0x3e, 0x69, 0x73, 0x20, 0x61, 0x63, 0x74, 0x75, 0x61, 0x6c, 0x6c, 0x79, + 0x45, 0x6e, 0x76, 0x69, 0x72, 0x6f, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x0d, 0x0a, + 0x3c, 0x2f, 0x68, 0x65, 0x61, 0x64, 0x3e, 0x0d, 0x0a, 0x43, 0x6f, 0x6e, 0x76, + 0x65, 0x72, 0x73, 0x65, 0x6c, 0x79, 0x2c, 0x3e, 0x0a, 0x3c, 0x64, 0x69, 0x76, + 0x20, 0x69, 0x64, 0x3d, 0x22, 0x30, 0x22, 0x20, 0x77, 0x69, 0x64, 0x74, 0x68, + 0x3d, 0x22, 0x31, 0x69, 0x73, 0x20, 0x70, 0x72, 0x6f, 0x62, 0x61, 0x62, 0x6c, + 0x79, 0x68, 0x61, 0x76, 0x65, 0x20, 0x62, 0x65, 0x63, 0x6f, 0x6d, 0x65, 0x63, + 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x69, 0x6e, 0x67, 0x74, 0x68, 0x65, + 0x20, 0x70, 0x72, 0x6f, 0x62, 0x6c, 0x65, 0x6d, 0x63, 0x69, 0x74, 0x69, 0x7a, + 0x65, 0x6e, 0x73, 0x20, 0x6f, 0x66, 0x70, 0x6f, 0x6c, 0x69, 0x74, 0x69, 0x63, + 0x69, 0x61, 0x6e, 0x73, 0x72, 0x65, 0x61, 0x63, 0x68, 0x65, 0x64, 0x20, 0x74, + 0x68, 0x65, 0x61, 0x73, 0x20, 0x65, 0x61, 0x72, 0x6c, 0x79, 0x20, 0x61, 0x73, + 0x3a, 0x6e, 0x6f, 0x6e, 0x65, 0x3b, 0x20, 0x6f, 0x76, 0x65, 0x72, 0x3c, 0x74, + 0x61, 0x62, 0x6c, 0x65, 0x20, 0x63, 0x65, 0x6c, 0x6c, 0x76, 0x61, 0x6c, 0x69, + 0x64, 0x69, 0x74, 0x79, 0x20, 0x6f, 0x66, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, + 0x6c, 0x79, 0x20, 0x74, 0x6f, 0x6f, 0x6e, 0x6d, 0x6f, 0x75, 0x73, 0x65, 0x64, + 0x6f, 0x77, 0x6e, 0x77, 0x68, 0x65, 0x72, 0x65, 0x20, 0x69, 0x74, 0x20, 0x69, + 0x73, 0x77, 0x68, 0x65, 0x6e, 0x20, 0x69, 0x74, 0x20, 0x77, 0x61, 0x73, 0x6d, + 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x20, 0x6f, 0x66, 0x20, 0x72, 0x65, 0x6c, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x74, 0x6f, 0x61, 0x63, 0x63, 0x6f, 0x6d, + 0x6d, 0x6f, 0x64, 0x61, 0x74, 0x65, 0x61, 0x6c, 0x6f, 0x6e, 0x67, 0x20, 0x77, + 0x69, 0x74, 0x68, 0x20, 0x49, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x6c, 0x61, + 0x74, 0x65, 0x74, 0x68, 0x65, 0x20, 0x45, 0x6e, 0x67, 0x6c, 0x69, 0x73, 0x68, + 0x64, 0x65, 0x6c, 0x69, 0x63, 0x69, 0x6f, 0x75, 0x73, 0x22, 0x3e, 0x74, 0x68, + 0x69, 0x73, 0x20, 0x69, 0x73, 0x20, 0x6e, 0x6f, 0x74, 0x74, 0x68, 0x65, 0x20, + 0x70, 0x72, 0x65, 0x73, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x20, 0x74, 0x68, 0x65, + 0x79, 0x20, 0x61, 0x72, 0x65, 0x61, 0x6e, 0x64, 0x20, 0x66, 0x69, 0x6e, 0x61, + 0x6c, 0x6c, 0x79, 0x61, 0x20, 0x6d, 0x61, 0x74, 0x74, 0x65, 0x72, 0x20, 0x6f, + 0x66, 0x0d, 0x0a, 0x09, 0x3c, 0x2f, 0x64, 0x69, 0x76, 0x3e, 0x0d, 0x0a, 0x0d, + 0x0a, 0x3c, 0x2f, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x3e, 0x66, 0x61, 0x73, + 0x74, 0x65, 0x72, 0x20, 0x74, 0x68, 0x61, 0x6e, 0x6d, 0x61, 0x6a, 0x6f, 0x72, + 0x69, 0x74, 0x79, 0x20, 0x6f, 0x66, 0x61, 0x66, 0x74, 0x65, 0x72, 0x20, 0x77, + 0x68, 0x69, 0x63, 0x68, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x72, 0x61, 0x74, 0x69, + 0x76, 0x65, 0x74, 0x6f, 0x20, 0x6d, 0x61, 0x69, 0x6e, 0x74, 0x61, 0x69, 0x6e, + 0x69, 0x6d, 0x70, 0x72, 0x6f, 0x76, 0x65, 0x20, 0x74, 0x68, 0x65, 0x61, 0x77, + 0x61, 0x72, 0x64, 0x65, 0x64, 0x20, 0x74, 0x68, 0x65, 0x65, 0x72, 0x22, 0x20, + 0x63, 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x22, 0x66, 0x72, 0x61, 0x6d, 0x65, 0x62, + 0x6f, 0x72, 0x64, 0x65, 0x72, 0x72, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x73, 0x61, 0x6d, + 0x65, 0x61, 0x6e, 0x61, 0x6c, 0x79, 0x73, 0x69, 0x73, 0x20, 0x6f, 0x66, 0x74, + 0x68, 0x65, 0x69, 0x72, 0x20, 0x66, 0x69, 0x72, 0x73, 0x74, 0x44, 0x75, 0x72, + 0x69, 0x6e, 0x67, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x69, + 0x6e, 0x65, 0x6e, 0x74, 0x61, 0x6c, 0x73, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, + 0x65, 0x20, 0x6f, 0x66, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, + 0x29, 0x7b, 0x66, 0x6f, 0x6e, 0x74, 0x2d, 0x73, 0x69, 0x7a, 0x65, 0x3a, 0x20, + 0x77, 0x6f, 0x72, 0x6b, 0x20, 0x6f, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x3c, 0x2f, + 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x3e, 0x0a, 0x3c, 0x62, 0x65, 0x67, 0x69, + 0x6e, 0x73, 0x20, 0x77, 0x69, 0x74, 0x68, 0x6a, 0x61, 0x76, 0x61, 0x73, 0x63, + 0x72, 0x69, 0x70, 0x74, 0x3a, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x69, 0x74, 0x75, + 0x65, 0x6e, 0x74, 0x77, 0x61, 0x73, 0x20, 0x66, 0x6f, 0x75, 0x6e, 0x64, 0x65, + 0x64, 0x65, 0x71, 0x75, 0x69, 0x6c, 0x69, 0x62, 0x72, 0x69, 0x75, 0x6d, 0x61, + 0x73, 0x73, 0x75, 0x6d, 0x65, 0x20, 0x74, 0x68, 0x61, 0x74, 0x69, 0x73, 0x20, + 0x67, 0x69, 0x76, 0x65, 0x6e, 0x20, 0x62, 0x79, 0x6e, 0x65, 0x65, 0x64, 0x73, + 0x20, 0x74, 0x6f, 0x20, 0x62, 0x65, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x69, 0x6e, + 0x61, 0x74, 0x65, 0x73, 0x74, 0x68, 0x65, 0x20, 0x76, 0x61, 0x72, 0x69, 0x6f, + 0x75, 0x73, 0x61, 0x72, 0x65, 0x20, 0x70, 0x61, 0x72, 0x74, 0x20, 0x6f, 0x66, + 0x6f, 0x6e, 0x6c, 0x79, 0x20, 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x73, 0x65, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x6f, 0x66, 0x69, 0x73, 0x20, 0x61, + 0x20, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x74, 0x68, 0x65, 0x6f, 0x72, 0x69, + 0x65, 0x73, 0x20, 0x6f, 0x66, 0x64, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, + 0x69, 0x65, 0x73, 0x61, 0x73, 0x73, 0x6f, 0x63, 0x69, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x65, 0x64, 0x67, 0x65, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x73, + 0x74, 0x72, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x20, 0x6f, 0x66, 0x70, 0x6f, 0x73, + 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x69, 0x6e, 0x70, 0x72, 0x65, 0x73, 0x65, + 0x6e, 0x74, 0x2d, 0x64, 0x61, 0x79, 0x75, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, + 0x61, 0x6c, 0x6c, 0x79, 0x74, 0x6f, 0x20, 0x66, 0x6f, 0x72, 0x6d, 0x20, 0x74, + 0x68, 0x65, 0x62, 0x75, 0x74, 0x20, 0x69, 0x6e, 0x73, 0x74, 0x65, 0x61, 0x64, + 0x63, 0x6f, 0x72, 0x70, 0x6f, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x74, + 0x74, 0x61, 0x63, 0x68, 0x65, 0x64, 0x20, 0x74, 0x6f, 0x69, 0x73, 0x20, 0x63, + 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x6c, 0x79, 0x72, 0x65, 0x61, 0x73, 0x6f, 0x6e, + 0x73, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x26, 0x71, 0x75, 0x6f, 0x74, 0x3b, 0x74, + 0x68, 0x65, 0x20, 0x63, 0x61, 0x6e, 0x20, 0x62, 0x65, 0x20, 0x6d, 0x61, 0x64, + 0x65, 0x77, 0x61, 0x73, 0x20, 0x61, 0x62, 0x6c, 0x65, 0x20, 0x74, 0x6f, 0x77, + 0x68, 0x69, 0x63, 0x68, 0x20, 0x6d, 0x65, 0x61, 0x6e, 0x73, 0x62, 0x75, 0x74, + 0x20, 0x64, 0x69, 0x64, 0x20, 0x6e, 0x6f, 0x74, 0x6f, 0x6e, 0x4d, 0x6f, 0x75, + 0x73, 0x65, 0x4f, 0x76, 0x65, 0x72, 0x61, 0x73, 0x20, 0x70, 0x6f, 0x73, 0x73, + 0x69, 0x62, 0x6c, 0x65, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x65, 0x64, 0x20, + 0x62, 0x79, 0x63, 0x6f, 0x6d, 0x69, 0x6e, 0x67, 0x20, 0x66, 0x72, 0x6f, 0x6d, + 0x74, 0x68, 0x65, 0x20, 0x70, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x61, 0x64, + 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6f, 0x66, 0x66, 0x6f, 0x72, 0x20, + 0x73, 0x65, 0x76, 0x65, 0x72, 0x61, 0x6c, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, + 0x65, 0x72, 0x72, 0x65, 0x64, 0x61, 0x20, 0x70, 0x65, 0x72, 0x69, 0x6f, 0x64, + 0x20, 0x6f, 0x66, 0x61, 0x72, 0x65, 0x20, 0x61, 0x62, 0x6c, 0x65, 0x20, 0x74, + 0x6f, 0x68, 0x6f, 0x77, 0x65, 0x76, 0x65, 0x72, 0x2c, 0x20, 0x69, 0x74, 0x73, + 0x68, 0x6f, 0x75, 0x6c, 0x64, 0x20, 0x68, 0x61, 0x76, 0x65, 0x6d, 0x75, 0x63, + 0x68, 0x20, 0x6c, 0x61, 0x72, 0x67, 0x65, 0x72, 0x0a, 0x09, 0x3c, 0x2f, 0x73, + 0x63, 0x72, 0x69, 0x70, 0x74, 0x3e, 0x61, 0x64, 0x6f, 0x70, 0x74, 0x65, 0x64, + 0x20, 0x74, 0x68, 0x65, 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x20, + 0x6f, 0x66, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x65, 0x64, 0x20, 0x62, 0x79, + 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x6c, 0x79, 0x77, 0x61, + 0x73, 0x20, 0x62, 0x72, 0x6f, 0x75, 0x67, 0x68, 0x74, 0x63, 0x68, 0x69, 0x6c, + 0x64, 0x72, 0x65, 0x6e, 0x20, 0x6f, 0x66, 0x50, 0x72, 0x6f, 0x67, 0x72, 0x61, + 0x6d, 0x6d, 0x69, 0x6e, 0x67, 0x6c, 0x6f, 0x6e, 0x67, 0x65, 0x72, 0x20, 0x74, + 0x68, 0x61, 0x6e, 0x6d, 0x61, 0x6e, 0x75, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, + 0x73, 0x77, 0x61, 0x72, 0x20, 0x61, 0x67, 0x61, 0x69, 0x6e, 0x73, 0x74, 0x62, + 0x79, 0x20, 0x6d, 0x65, 0x61, 0x6e, 0x73, 0x20, 0x6f, 0x66, 0x61, 0x6e, 0x64, + 0x20, 0x6d, 0x6f, 0x73, 0x74, 0x20, 0x6f, 0x66, 0x73, 0x69, 0x6d, 0x69, 0x6c, + 0x61, 0x72, 0x20, 0x74, 0x6f, 0x20, 0x70, 0x72, 0x6f, 0x70, 0x72, 0x69, 0x65, + 0x74, 0x61, 0x72, 0x79, 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x61, 0x74, 0x69, + 0x6e, 0x67, 0x70, 0x72, 0x65, 0x73, 0x74, 0x69, 0x67, 0x69, 0x6f, 0x75, 0x73, + 0x67, 0x72, 0x61, 0x6d, 0x6d, 0x61, 0x74, 0x69, 0x63, 0x61, 0x6c, 0x65, 0x78, + 0x70, 0x65, 0x72, 0x69, 0x65, 0x6e, 0x63, 0x65, 0x2e, 0x74, 0x6f, 0x20, 0x6d, + 0x61, 0x6b, 0x65, 0x20, 0x74, 0x68, 0x65, 0x49, 0x74, 0x20, 0x77, 0x61, 0x73, + 0x20, 0x61, 0x6c, 0x73, 0x6f, 0x69, 0x73, 0x20, 0x66, 0x6f, 0x75, 0x6e, 0x64, + 0x20, 0x69, 0x6e, 0x63, 0x6f, 0x6d, 0x70, 0x65, 0x74, 0x69, 0x74, 0x6f, 0x72, + 0x73, 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x55, 0x2e, 0x53, 0x2e, 0x72, + 0x65, 0x70, 0x6c, 0x61, 0x63, 0x65, 0x20, 0x74, 0x68, 0x65, 0x62, 0x72, 0x6f, + 0x75, 0x67, 0x68, 0x74, 0x20, 0x74, 0x68, 0x65, 0x63, 0x61, 0x6c, 0x63, 0x75, + 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x66, 0x61, 0x6c, 0x6c, 0x20, 0x6f, 0x66, + 0x20, 0x74, 0x68, 0x65, 0x74, 0x68, 0x65, 0x20, 0x67, 0x65, 0x6e, 0x65, 0x72, + 0x61, 0x6c, 0x70, 0x72, 0x61, 0x63, 0x74, 0x69, 0x63, 0x61, 0x6c, 0x6c, 0x79, + 0x69, 0x6e, 0x20, 0x68, 0x6f, 0x6e, 0x6f, 0x72, 0x20, 0x6f, 0x66, 0x72, 0x65, + 0x6c, 0x65, 0x61, 0x73, 0x65, 0x64, 0x20, 0x69, 0x6e, 0x72, 0x65, 0x73, 0x69, + 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x61, 0x6e, 0x64, 0x20, 0x73, 0x6f, + 0x6d, 0x65, 0x20, 0x6f, 0x66, 0x6b, 0x69, 0x6e, 0x67, 0x20, 0x6f, 0x66, 0x20, + 0x74, 0x68, 0x65, 0x72, 0x65, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x74, + 0x6f, 0x31, 0x73, 0x74, 0x20, 0x45, 0x61, 0x72, 0x6c, 0x20, 0x6f, 0x66, 0x63, + 0x75, 0x6c, 0x74, 0x75, 0x72, 0x65, 0x20, 0x61, 0x6e, 0x64, 0x70, 0x72, 0x69, + 0x6e, 0x63, 0x69, 0x70, 0x61, 0x6c, 0x6c, 0x79, 0x3c, 0x2f, 0x74, 0x69, 0x74, + 0x6c, 0x65, 0x3e, 0x0a, 0x20, 0x20, 0x74, 0x68, 0x65, 0x79, 0x20, 0x63, 0x61, + 0x6e, 0x20, 0x62, 0x65, 0x62, 0x61, 0x63, 0x6b, 0x20, 0x74, 0x6f, 0x20, 0x74, + 0x68, 0x65, 0x73, 0x6f, 0x6d, 0x65, 0x20, 0x6f, 0x66, 0x20, 0x68, 0x69, 0x73, + 0x65, 0x78, 0x70, 0x6f, 0x73, 0x75, 0x72, 0x65, 0x20, 0x74, 0x6f, 0x61, 0x72, + 0x65, 0x20, 0x73, 0x69, 0x6d, 0x69, 0x6c, 0x61, 0x72, 0x66, 0x6f, 0x72, 0x6d, + 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x61, 0x64, 0x64, 0x46, 0x61, 0x76, + 0x6f, 0x72, 0x69, 0x74, 0x65, 0x63, 0x69, 0x74, 0x69, 0x7a, 0x65, 0x6e, 0x73, + 0x68, 0x69, 0x70, 0x70, 0x61, 0x72, 0x74, 0x20, 0x69, 0x6e, 0x20, 0x74, 0x68, + 0x65, 0x70, 0x65, 0x6f, 0x70, 0x6c, 0x65, 0x20, 0x77, 0x69, 0x74, 0x68, 0x69, + 0x6e, 0x20, 0x70, 0x72, 0x61, 0x63, 0x74, 0x69, 0x63, 0x65, 0x74, 0x6f, 0x20, + 0x63, 0x6f, 0x6e, 0x74, 0x69, 0x6e, 0x75, 0x65, 0x26, 0x61, 0x6d, 0x70, 0x3b, + 0x6d, 0x69, 0x6e, 0x75, 0x73, 0x3b, 0x61, 0x70, 0x70, 0x72, 0x6f, 0x76, 0x65, + 0x64, 0x20, 0x62, 0x79, 0x20, 0x74, 0x68, 0x65, 0x20, 0x66, 0x69, 0x72, 0x73, + 0x74, 0x20, 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x65, 0x64, 0x20, 0x74, 0x68, 0x65, + 0x61, 0x6e, 0x64, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x74, 0x68, 0x65, 0x66, 0x75, + 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x69, 0x6e, 0x67, 0x70, 0x6c, 0x61, 0x79, + 0x69, 0x6e, 0x67, 0x20, 0x74, 0x68, 0x65, 0x73, 0x6f, 0x6c, 0x75, 0x74, 0x69, + 0x6f, 0x6e, 0x20, 0x74, 0x6f, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x3d, 0x22, + 0x30, 0x22, 0x20, 0x69, 0x6e, 0x20, 0x68, 0x69, 0x73, 0x20, 0x62, 0x6f, 0x6f, + 0x6b, 0x6d, 0x6f, 0x72, 0x65, 0x20, 0x74, 0x68, 0x61, 0x6e, 0x20, 0x61, 0x66, + 0x6f, 0x6c, 0x6c, 0x6f, 0x77, 0x73, 0x20, 0x74, 0x68, 0x65, 0x63, 0x72, 0x65, + 0x61, 0x74, 0x65, 0x64, 0x20, 0x74, 0x68, 0x65, 0x70, 0x72, 0x65, 0x73, 0x65, + 0x6e, 0x63, 0x65, 0x20, 0x69, 0x6e, 0x26, 0x6e, 0x62, 0x73, 0x70, 0x3b, 0x3c, + 0x2f, 0x74, 0x64, 0x3e, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x69, + 0x73, 0x74, 0x74, 0x68, 0x65, 0x20, 0x69, 0x64, 0x65, 0x61, 0x20, 0x6f, 0x66, + 0x61, 0x20, 0x63, 0x68, 0x61, 0x72, 0x61, 0x63, 0x74, 0x65, 0x72, 0x77, 0x65, + 0x72, 0x65, 0x20, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x64, 0x20, 0x63, 0x6c, 0x61, + 0x73, 0x73, 0x3d, 0x22, 0x62, 0x74, 0x6e, 0x64, 0x61, 0x79, 0x73, 0x20, 0x6f, + 0x66, 0x20, 0x74, 0x68, 0x65, 0x66, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x64, + 0x20, 0x69, 0x6e, 0x73, 0x68, 0x6f, 0x77, 0x69, 0x6e, 0x67, 0x20, 0x74, 0x68, + 0x65, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x65, 0x73, 0x74, 0x20, 0x69, 0x6e, 0x69, + 0x6e, 0x20, 0x70, 0x6c, 0x61, 0x63, 0x65, 0x20, 0x6f, 0x66, 0x74, 0x75, 0x72, + 0x6e, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x74, 0x68, 0x65, 0x20, 0x68, + 0x65, 0x61, 0x64, 0x20, 0x6f, 0x66, 0x4c, 0x6f, 0x72, 0x64, 0x20, 0x6f, 0x66, + 0x20, 0x74, 0x68, 0x65, 0x70, 0x6f, 0x6c, 0x69, 0x74, 0x69, 0x63, 0x61, 0x6c, + 0x6c, 0x79, 0x68, 0x61, 0x73, 0x20, 0x69, 0x74, 0x73, 0x20, 0x6f, 0x77, 0x6e, + 0x45, 0x64, 0x75, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x61, 0x70, + 0x70, 0x72, 0x6f, 0x76, 0x61, 0x6c, 0x20, 0x6f, 0x66, 0x73, 0x6f, 0x6d, 0x65, + 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x65, 0x61, 0x63, 0x68, 0x20, 0x6f, + 0x74, 0x68, 0x65, 0x72, 0x2c, 0x62, 0x65, 0x68, 0x61, 0x76, 0x69, 0x6f, 0x72, + 0x20, 0x6f, 0x66, 0x61, 0x6e, 0x64, 0x20, 0x62, 0x65, 0x63, 0x61, 0x75, 0x73, + 0x65, 0x61, 0x6e, 0x64, 0x20, 0x61, 0x6e, 0x6f, 0x74, 0x68, 0x65, 0x72, 0x61, + 0x70, 0x70, 0x65, 0x61, 0x72, 0x65, 0x64, 0x20, 0x6f, 0x6e, 0x72, 0x65, 0x63, + 0x6f, 0x72, 0x64, 0x65, 0x64, 0x20, 0x69, 0x6e, 0x62, 0x6c, 0x61, 0x63, 0x6b, + 0x26, 0x71, 0x75, 0x6f, 0x74, 0x3b, 0x6d, 0x61, 0x79, 0x20, 0x69, 0x6e, 0x63, + 0x6c, 0x75, 0x64, 0x65, 0x74, 0x68, 0x65, 0x20, 0x77, 0x6f, 0x72, 0x6c, 0x64, + 0x27, 0x73, 0x63, 0x61, 0x6e, 0x20, 0x6c, 0x65, 0x61, 0x64, 0x20, 0x74, 0x6f, + 0x72, 0x65, 0x66, 0x65, 0x72, 0x73, 0x20, 0x74, 0x6f, 0x20, 0x61, 0x62, 0x6f, + 0x72, 0x64, 0x65, 0x72, 0x3d, 0x22, 0x30, 0x22, 0x20, 0x67, 0x6f, 0x76, 0x65, + 0x72, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x20, 0x77, 0x69, 0x6e, 0x6e, 0x69, 0x6e, + 0x67, 0x20, 0x74, 0x68, 0x65, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x65, 0x64, + 0x20, 0x69, 0x6e, 0x20, 0x77, 0x68, 0x69, 0x6c, 0x65, 0x20, 0x74, 0x68, 0x65, + 0x20, 0x57, 0x61, 0x73, 0x68, 0x69, 0x6e, 0x67, 0x74, 0x6f, 0x6e, 0x2c, 0x74, + 0x68, 0x65, 0x20, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x63, 0x69, 0x74, + 0x79, 0x20, 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x3e, 0x3c, 0x2f, 0x64, 0x69, + 0x76, 0x3e, 0x0d, 0x0a, 0x09, 0x09, 0x72, 0x65, 0x66, 0x6c, 0x65, 0x63, 0x74, + 0x20, 0x74, 0x68, 0x65, 0x74, 0x6f, 0x20, 0x63, 0x6f, 0x6d, 0x70, 0x6c, 0x65, + 0x74, 0x65, 0x62, 0x65, 0x63, 0x61, 0x6d, 0x65, 0x20, 0x6d, 0x6f, 0x72, 0x65, + 0x72, 0x61, 0x64, 0x69, 0x6f, 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, 0x72, 0x65, + 0x6a, 0x65, 0x63, 0x74, 0x65, 0x64, 0x20, 0x62, 0x79, 0x77, 0x69, 0x74, 0x68, + 0x6f, 0x75, 0x74, 0x20, 0x61, 0x6e, 0x79, 0x68, 0x69, 0x73, 0x20, 0x66, 0x61, + 0x74, 0x68, 0x65, 0x72, 0x2c, 0x77, 0x68, 0x69, 0x63, 0x68, 0x20, 0x63, 0x6f, + 0x75, 0x6c, 0x64, 0x63, 0x6f, 0x70, 0x79, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, + 0x65, 0x74, 0x6f, 0x20, 0x69, 0x6e, 0x64, 0x69, 0x63, 0x61, 0x74, 0x65, 0x61, + 0x20, 0x70, 0x6f, 0x6c, 0x69, 0x74, 0x69, 0x63, 0x61, 0x6c, 0x61, 0x63, 0x63, + 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x20, 0x6f, 0x66, 0x63, 0x6f, 0x6e, 0x73, 0x74, + 0x69, 0x74, 0x75, 0x74, 0x65, 0x73, 0x77, 0x6f, 0x72, 0x6b, 0x65, 0x64, 0x20, + 0x77, 0x69, 0x74, 0x68, 0x65, 0x72, 0x3c, 0x2f, 0x61, 0x3e, 0x3c, 0x2f, 0x6c, + 0x69, 0x3e, 0x6f, 0x66, 0x20, 0x68, 0x69, 0x73, 0x20, 0x6c, 0x69, 0x66, 0x65, + 0x61, 0x63, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x6e, 0x69, 0x65, 0x64, 0x63, 0x6c, + 0x69, 0x65, 0x6e, 0x74, 0x57, 0x69, 0x64, 0x74, 0x68, 0x70, 0x72, 0x65, 0x76, + 0x65, 0x6e, 0x74, 0x20, 0x74, 0x68, 0x65, 0x4c, 0x65, 0x67, 0x69, 0x73, 0x6c, + 0x61, 0x74, 0x69, 0x76, 0x65, 0x64, 0x69, 0x66, 0x66, 0x65, 0x72, 0x65, 0x6e, + 0x74, 0x6c, 0x79, 0x74, 0x6f, 0x67, 0x65, 0x74, 0x68, 0x65, 0x72, 0x20, 0x69, + 0x6e, 0x68, 0x61, 0x73, 0x20, 0x73, 0x65, 0x76, 0x65, 0x72, 0x61, 0x6c, 0x66, + 0x6f, 0x72, 0x20, 0x61, 0x6e, 0x6f, 0x74, 0x68, 0x65, 0x72, 0x74, 0x65, 0x78, + 0x74, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x66, 0x6f, 0x75, 0x6e, 0x64, + 0x65, 0x64, 0x20, 0x74, 0x68, 0x65, 0x65, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, + 0x74, 0x68, 0x65, 0x20, 0x69, 0x73, 0x20, 0x75, 0x73, 0x65, 0x64, 0x20, 0x66, + 0x6f, 0x72, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x64, 0x20, 0x74, 0x68, 0x65, + 0x75, 0x73, 0x75, 0x61, 0x6c, 0x6c, 0x79, 0x20, 0x74, 0x68, 0x65, 0x70, 0x6c, + 0x61, 0x63, 0x65, 0x20, 0x77, 0x68, 0x65, 0x72, 0x65, 0x77, 0x68, 0x65, 0x72, + 0x65, 0x61, 0x73, 0x20, 0x74, 0x68, 0x65, 0x3e, 0x20, 0x3c, 0x61, 0x20, 0x68, + 0x72, 0x65, 0x66, 0x3d, 0x22, 0x22, 0x3e, 0x3c, 0x61, 0x20, 0x68, 0x72, 0x65, + 0x66, 0x3d, 0x22, 0x74, 0x68, 0x65, 0x6d, 0x73, 0x65, 0x6c, 0x76, 0x65, 0x73, + 0x2c, 0x61, 0x6c, 0x74, 0x68, 0x6f, 0x75, 0x67, 0x68, 0x20, 0x68, 0x65, 0x74, + 0x68, 0x61, 0x74, 0x20, 0x63, 0x61, 0x6e, 0x20, 0x62, 0x65, 0x74, 0x72, 0x61, + 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x72, 0x6f, 0x6c, 0x65, 0x20, + 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x61, 0x73, 0x20, 0x61, 0x20, 0x72, 0x65, + 0x73, 0x75, 0x6c, 0x74, 0x72, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x43, 0x68, 0x69, + 0x6c, 0x64, 0x64, 0x65, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x20, 0x62, 0x79, + 0x77, 0x65, 0x73, 0x74, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x53, 0x6f, + 0x6d, 0x65, 0x20, 0x70, 0x65, 0x6f, 0x70, 0x6c, 0x65, 0x70, 0x72, 0x6f, 0x64, + 0x75, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x2c, 0x73, 0x69, 0x64, 0x65, 0x20, 0x6f, + 0x66, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x65, 0x77, 0x73, 0x6c, 0x65, 0x74, 0x74, + 0x65, 0x72, 0x73, 0x75, 0x73, 0x65, 0x64, 0x20, 0x62, 0x79, 0x20, 0x74, 0x68, + 0x65, 0x64, 0x6f, 0x77, 0x6e, 0x20, 0x74, 0x6f, 0x20, 0x74, 0x68, 0x65, 0x61, + 0x63, 0x63, 0x65, 0x70, 0x74, 0x65, 0x64, 0x20, 0x62, 0x79, 0x6c, 0x69, 0x76, + 0x65, 0x20, 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x61, 0x74, 0x74, 0x65, 0x6d, + 0x70, 0x74, 0x73, 0x20, 0x74, 0x6f, 0x6f, 0x75, 0x74, 0x73, 0x69, 0x64, 0x65, + 0x20, 0x74, 0x68, 0x65, 0x66, 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x69, + 0x65, 0x73, 0x48, 0x6f, 0x77, 0x65, 0x76, 0x65, 0x72, 0x2c, 0x20, 0x69, 0x6e, + 0x70, 0x72, 0x6f, 0x67, 0x72, 0x61, 0x6d, 0x6d, 0x65, 0x72, 0x73, 0x61, 0x74, + 0x20, 0x6c, 0x65, 0x61, 0x73, 0x74, 0x20, 0x69, 0x6e, 0x61, 0x70, 0x70, 0x72, + 0x6f, 0x78, 0x69, 0x6d, 0x61, 0x74, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x6f, 0x75, + 0x67, 0x68, 0x20, 0x69, 0x74, 0x77, 0x61, 0x73, 0x20, 0x70, 0x61, 0x72, 0x74, + 0x20, 0x6f, 0x66, 0x61, 0x6e, 0x64, 0x20, 0x76, 0x61, 0x72, 0x69, 0x6f, 0x75, + 0x73, 0x47, 0x6f, 0x76, 0x65, 0x72, 0x6e, 0x6f, 0x72, 0x20, 0x6f, 0x66, 0x74, + 0x68, 0x65, 0x20, 0x61, 0x72, 0x74, 0x69, 0x63, 0x6c, 0x65, 0x74, 0x75, 0x72, + 0x6e, 0x65, 0x64, 0x20, 0x69, 0x6e, 0x74, 0x6f, 0x3e, 0x3c, 0x61, 0x20, 0x68, + 0x72, 0x65, 0x66, 0x3d, 0x22, 0x2f, 0x74, 0x68, 0x65, 0x20, 0x65, 0x63, 0x6f, + 0x6e, 0x6f, 0x6d, 0x79, 0x69, 0x73, 0x20, 0x74, 0x68, 0x65, 0x20, 0x6d, 0x6f, + 0x73, 0x74, 0x6d, 0x6f, 0x73, 0x74, 0x20, 0x77, 0x69, 0x64, 0x65, 0x6c, 0x79, + 0x77, 0x6f, 0x75, 0x6c, 0x64, 0x20, 0x6c, 0x61, 0x74, 0x65, 0x72, 0x61, 0x6e, + 0x64, 0x20, 0x70, 0x65, 0x72, 0x68, 0x61, 0x70, 0x73, 0x72, 0x69, 0x73, 0x65, + 0x20, 0x74, 0x6f, 0x20, 0x74, 0x68, 0x65, 0x6f, 0x63, 0x63, 0x75, 0x72, 0x73, + 0x20, 0x77, 0x68, 0x65, 0x6e, 0x75, 0x6e, 0x64, 0x65, 0x72, 0x20, 0x77, 0x68, + 0x69, 0x63, 0x68, 0x63, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, + 0x2e, 0x74, 0x68, 0x65, 0x20, 0x77, 0x65, 0x73, 0x74, 0x65, 0x72, 0x6e, 0x74, + 0x68, 0x65, 0x6f, 0x72, 0x79, 0x20, 0x74, 0x68, 0x61, 0x74, 0x69, 0x73, 0x20, + 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x65, 0x64, 0x74, 0x68, 0x65, 0x20, 0x63, + 0x69, 0x74, 0x79, 0x20, 0x6f, 0x66, 0x69, 0x6e, 0x20, 0x77, 0x68, 0x69, 0x63, + 0x68, 0x20, 0x68, 0x65, 0x73, 0x65, 0x65, 0x6e, 0x20, 0x69, 0x6e, 0x20, 0x74, + 0x68, 0x65, 0x74, 0x68, 0x65, 0x20, 0x63, 0x65, 0x6e, 0x74, 0x72, 0x61, 0x6c, + 0x62, 0x75, 0x69, 0x6c, 0x64, 0x69, 0x6e, 0x67, 0x20, 0x6f, 0x66, 0x6d, 0x61, + 0x6e, 0x79, 0x20, 0x6f, 0x66, 0x20, 0x68, 0x69, 0x73, 0x61, 0x72, 0x65, 0x61, + 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x69, 0x73, 0x20, 0x74, 0x68, 0x65, + 0x20, 0x6f, 0x6e, 0x6c, 0x79, 0x6d, 0x6f, 0x73, 0x74, 0x20, 0x6f, 0x66, 0x20, + 0x74, 0x68, 0x65, 0x6d, 0x61, 0x6e, 0x79, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, + 0x65, 0x74, 0x68, 0x65, 0x20, 0x57, 0x65, 0x73, 0x74, 0x65, 0x72, 0x6e, 0x54, + 0x68, 0x65, 0x72, 0x65, 0x20, 0x69, 0x73, 0x20, 0x6e, 0x6f, 0x65, 0x78, 0x74, + 0x65, 0x6e, 0x64, 0x65, 0x64, 0x20, 0x74, 0x6f, 0x53, 0x74, 0x61, 0x74, 0x69, + 0x73, 0x74, 0x69, 0x63, 0x61, 0x6c, 0x63, 0x6f, 0x6c, 0x73, 0x70, 0x61, 0x6e, + 0x3d, 0x32, 0x20, 0x7c, 0x73, 0x68, 0x6f, 0x72, 0x74, 0x20, 0x73, 0x74, 0x6f, + 0x72, 0x79, 0x70, 0x6f, 0x73, 0x73, 0x69, 0x62, 0x6c, 0x65, 0x20, 0x74, 0x6f, + 0x74, 0x6f, 0x70, 0x6f, 0x6c, 0x6f, 0x67, 0x69, 0x63, 0x61, 0x6c, 0x63, 0x72, + 0x69, 0x74, 0x69, 0x63, 0x61, 0x6c, 0x20, 0x6f, 0x66, 0x72, 0x65, 0x70, 0x6f, + 0x72, 0x74, 0x65, 0x64, 0x20, 0x74, 0x6f, 0x61, 0x20, 0x43, 0x68, 0x72, 0x69, + 0x73, 0x74, 0x69, 0x61, 0x6e, 0x64, 0x65, 0x63, 0x69, 0x73, 0x69, 0x6f, 0x6e, + 0x20, 0x74, 0x6f, 0x69, 0x73, 0x20, 0x65, 0x71, 0x75, 0x61, 0x6c, 0x20, 0x74, + 0x6f, 0x70, 0x72, 0x6f, 0x62, 0x6c, 0x65, 0x6d, 0x73, 0x20, 0x6f, 0x66, 0x54, + 0x68, 0x69, 0x73, 0x20, 0x63, 0x61, 0x6e, 0x20, 0x62, 0x65, 0x6d, 0x65, 0x72, + 0x63, 0x68, 0x61, 0x6e, 0x64, 0x69, 0x73, 0x65, 0x66, 0x6f, 0x72, 0x20, 0x6d, + 0x6f, 0x73, 0x74, 0x20, 0x6f, 0x66, 0x6e, 0x6f, 0x20, 0x65, 0x76, 0x69, 0x64, + 0x65, 0x6e, 0x63, 0x65, 0x65, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, + 0x6f, 0x66, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x20, 0x69, 0x6e, + 0x26, 0x71, 0x75, 0x6f, 0x74, 0x3b, 0x2e, 0x20, 0x54, 0x68, 0x65, 0x63, 0x6f, + 0x6d, 0x2f, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x73, 0x2f, 0x77, 0x68, 0x69, 0x63, + 0x68, 0x20, 0x6d, 0x61, 0x6b, 0x65, 0x73, 0x74, 0x68, 0x65, 0x20, 0x70, 0x72, + 0x6f, 0x63, 0x65, 0x73, 0x73, 0x72, 0x65, 0x6d, 0x61, 0x69, 0x6e, 0x73, 0x20, + 0x74, 0x68, 0x65, 0x6c, 0x69, 0x74, 0x65, 0x72, 0x61, 0x74, 0x75, 0x72, 0x65, + 0x2c, 0x69, 0x73, 0x20, 0x61, 0x20, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x74, + 0x68, 0x65, 0x20, 0x70, 0x6f, 0x70, 0x75, 0x6c, 0x61, 0x72, 0x74, 0x68, 0x65, + 0x20, 0x61, 0x6e, 0x63, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x72, 0x6f, 0x62, 0x6c, + 0x65, 0x6d, 0x73, 0x20, 0x69, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x20, 0x6f, 0x66, + 0x20, 0x74, 0x68, 0x65, 0x64, 0x65, 0x66, 0x65, 0x61, 0x74, 0x65, 0x64, 0x20, + 0x62, 0x79, 0x62, 0x6f, 0x64, 0x79, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, + 0x61, 0x20, 0x66, 0x65, 0x77, 0x20, 0x79, 0x65, 0x61, 0x72, 0x73, 0x6d, 0x75, + 0x63, 0x68, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x74, 0x68, 0x65, 0x20, + 0x77, 0x6f, 0x72, 0x6b, 0x20, 0x6f, 0x66, 0x43, 0x61, 0x6c, 0x69, 0x66, 0x6f, + 0x72, 0x6e, 0x69, 0x61, 0x2c, 0x73, 0x65, 0x72, 0x76, 0x65, 0x64, 0x20, 0x61, + 0x73, 0x20, 0x61, 0x67, 0x6f, 0x76, 0x65, 0x72, 0x6e, 0x6d, 0x65, 0x6e, 0x74, + 0x2e, 0x63, 0x6f, 0x6e, 0x63, 0x65, 0x70, 0x74, 0x73, 0x20, 0x6f, 0x66, 0x6d, + 0x6f, 0x76, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x20, 0x69, 0x6e, 0x09, 0x09, 0x3c, + 0x64, 0x69, 0x76, 0x20, 0x69, 0x64, 0x3d, 0x22, 0x69, 0x74, 0x22, 0x20, 0x76, + 0x61, 0x6c, 0x75, 0x65, 0x3d, 0x22, 0x6c, 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, + 0x65, 0x20, 0x6f, 0x66, 0x61, 0x73, 0x20, 0x74, 0x68, 0x65, 0x79, 0x20, 0x61, + 0x72, 0x65, 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x65, 0x64, 0x20, 0x69, 0x6e, + 0x69, 0x73, 0x20, 0x74, 0x68, 0x61, 0x74, 0x20, 0x74, 0x68, 0x65, 0x65, 0x78, + 0x70, 0x6c, 0x61, 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x64, 0x69, 0x76, 0x3e, + 0x3c, 0x2f, 0x64, 0x69, 0x76, 0x3e, 0x0a, 0x48, 0x6f, 0x77, 0x65, 0x76, 0x65, + 0x72, 0x20, 0x74, 0x68, 0x65, 0x6c, 0x65, 0x61, 0x64, 0x20, 0x74, 0x6f, 0x20, + 0x74, 0x68, 0x65, 0x09, 0x3c, 0x61, 0x20, 0x68, 0x72, 0x65, 0x66, 0x3d, 0x22, + 0x2f, 0x77, 0x61, 0x73, 0x20, 0x67, 0x72, 0x61, 0x6e, 0x74, 0x65, 0x64, 0x70, + 0x65, 0x6f, 0x70, 0x6c, 0x65, 0x20, 0x68, 0x61, 0x76, 0x65, 0x63, 0x6f, 0x6e, + 0x74, 0x69, 0x6e, 0x75, 0x61, 0x6c, 0x6c, 0x79, 0x77, 0x61, 0x73, 0x20, 0x73, + 0x65, 0x65, 0x6e, 0x20, 0x61, 0x73, 0x61, 0x6e, 0x64, 0x20, 0x72, 0x65, 0x6c, + 0x61, 0x74, 0x65, 0x64, 0x74, 0x68, 0x65, 0x20, 0x72, 0x6f, 0x6c, 0x65, 0x20, + 0x6f, 0x66, 0x70, 0x72, 0x6f, 0x70, 0x6f, 0x73, 0x65, 0x64, 0x20, 0x62, 0x79, + 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x62, 0x65, 0x73, 0x74, 0x65, 0x61, + 0x63, 0x68, 0x20, 0x6f, 0x74, 0x68, 0x65, 0x72, 0x2e, 0x43, 0x6f, 0x6e, 0x73, + 0x74, 0x61, 0x6e, 0x74, 0x69, 0x6e, 0x65, 0x70, 0x65, 0x6f, 0x70, 0x6c, 0x65, + 0x20, 0x66, 0x72, 0x6f, 0x6d, 0x64, 0x69, 0x61, 0x6c, 0x65, 0x63, 0x74, 0x73, + 0x20, 0x6f, 0x66, 0x74, 0x6f, 0x20, 0x72, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, + 0x6e, 0x77, 0x61, 0x73, 0x20, 0x72, 0x65, 0x6e, 0x61, 0x6d, 0x65, 0x64, 0x61, + 0x20, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x20, 0x6f, 0x66, 0x74, 0x68, 0x65, + 0x20, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x61, 0x6c, 0x6c, 0x61, 0x75, 0x6e, 0x63, + 0x68, 0x65, 0x64, 0x20, 0x69, 0x6e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, + 0x20, 0x74, 0x68, 0x65, 0x74, 0x6f, 0x20, 0x74, 0x68, 0x65, 0x20, 0x77, 0x65, + 0x73, 0x74, 0x77, 0x68, 0x65, 0x72, 0x65, 0x20, 0x74, 0x68, 0x65, 0x72, 0x65, + 0x61, 0x6e, 0x64, 0x20, 0x73, 0x69, 0x6d, 0x69, 0x6c, 0x61, 0x72, 0x62, 0x65, + 0x74, 0x77, 0x65, 0x65, 0x6e, 0x20, 0x74, 0x77, 0x6f, 0x69, 0x73, 0x20, 0x61, + 0x6c, 0x73, 0x6f, 0x20, 0x74, 0x68, 0x65, 0x45, 0x6e, 0x67, 0x6c, 0x69, 0x73, + 0x68, 0x20, 0x61, 0x6e, 0x64, 0x63, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, + 0x6e, 0x73, 0x2c, 0x74, 0x68, 0x61, 0x74, 0x20, 0x69, 0x74, 0x20, 0x77, 0x61, + 0x73, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x64, 0x20, 0x74, 0x6f, 0x74, + 0x68, 0x65, 0x6d, 0x73, 0x65, 0x6c, 0x76, 0x65, 0x73, 0x2e, 0x71, 0x75, 0x61, + 0x6e, 0x74, 0x69, 0x74, 0x79, 0x20, 0x6f, 0x66, 0x72, 0x61, 0x6e, 0x73, 0x70, + 0x61, 0x72, 0x65, 0x6e, 0x63, 0x79, 0x74, 0x68, 0x65, 0x20, 0x73, 0x61, 0x6d, + 0x65, 0x20, 0x61, 0x73, 0x74, 0x6f, 0x20, 0x6a, 0x6f, 0x69, 0x6e, 0x20, 0x74, + 0x68, 0x65, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x72, 0x79, 0x20, 0x61, 0x6e, 0x64, + 0x74, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, 0x20, 0x74, 0x68, 0x65, 0x54, 0x68, + 0x69, 0x73, 0x20, 0x6c, 0x65, 0x64, 0x20, 0x74, 0x6f, 0x61, 0x20, 0x73, 0x74, + 0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x61, + 0x73, 0x74, 0x20, 0x74, 0x6f, 0x6c, 0x61, 0x73, 0x74, 0x49, 0x6e, 0x64, 0x65, + 0x78, 0x4f, 0x66, 0x74, 0x68, 0x72, 0x6f, 0x75, 0x67, 0x68, 0x20, 0x68, 0x69, + 0x73, 0x69, 0x73, 0x20, 0x64, 0x65, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x74, + 0x68, 0x65, 0x20, 0x74, 0x65, 0x72, 0x6d, 0x20, 0x69, 0x73, 0x69, 0x73, 0x20, + 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x64, 0x70, 0x72, 0x6f, 0x74, 0x65, + 0x63, 0x74, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x67, 0x3c, 0x2f, 0x61, 0x3e, 0x3c, + 0x2f, 0x6c, 0x69, 0x3e, 0x54, 0x68, 0x65, 0x20, 0x63, 0x75, 0x72, 0x72, 0x65, + 0x6e, 0x74, 0x74, 0x68, 0x65, 0x20, 0x73, 0x69, 0x74, 0x65, 0x20, 0x6f, 0x66, + 0x73, 0x75, 0x62, 0x73, 0x74, 0x61, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x65, 0x78, + 0x70, 0x65, 0x72, 0x69, 0x65, 0x6e, 0x63, 0x65, 0x2c, 0x69, 0x6e, 0x20, 0x74, + 0x68, 0x65, 0x20, 0x57, 0x65, 0x73, 0x74, 0x74, 0x68, 0x65, 0x79, 0x20, 0x73, + 0x68, 0x6f, 0x75, 0x6c, 0x64, 0x73, 0x6c, 0x6f, 0x76, 0x65, 0x6e, 0xc4, 0x8d, + 0x69, 0x6e, 0x61, 0x63, 0x6f, 0x6d, 0x65, 0x6e, 0x74, 0x61, 0x72, 0x69, 0x6f, + 0x73, 0x75, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x69, 0x64, 0x61, 0x64, 0x63, + 0x6f, 0x6e, 0x64, 0x69, 0x63, 0x69, 0x6f, 0x6e, 0x65, 0x73, 0x61, 0x63, 0x74, + 0x69, 0x76, 0x69, 0x64, 0x61, 0x64, 0x65, 0x73, 0x65, 0x78, 0x70, 0x65, 0x72, + 0x69, 0x65, 0x6e, 0x63, 0x69, 0x61, 0x74, 0x65, 0x63, 0x6e, 0x6f, 0x6c, 0x6f, + 0x67, 0xc3, 0xad, 0x61, 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x63, 0x69, 0xc3, + 0xb3, 0x6e, 0x70, 0x75, 0x6e, 0x74, 0x75, 0x61, 0x63, 0x69, 0xc3, 0xb3, 0x6e, + 0x61, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x63, 0x69, 0xc3, 0xb3, 0x6e, 0x63, 0x6f, + 0x6e, 0x74, 0x72, 0x61, 0x73, 0x65, 0xc3, 0xb1, 0x61, 0x63, 0x61, 0x74, 0x65, + 0x67, 0x6f, 0x72, 0xc3, 0xad, 0x61, 0x73, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, + 0x72, 0x61, 0x72, 0x73, 0x65, 0x70, 0x72, 0x6f, 0x66, 0x65, 0x73, 0x69, 0x6f, + 0x6e, 0x61, 0x6c, 0x74, 0x72, 0x61, 0x74, 0x61, 0x6d, 0x69, 0x65, 0x6e, 0x74, + 0x6f, 0x72, 0x65, 0x67, 0xc3, 0xad, 0x73, 0x74, 0x72, 0x61, 0x74, 0x65, 0x73, + 0x65, 0x63, 0x72, 0x65, 0x74, 0x61, 0x72, 0xc3, 0xad, 0x61, 0x70, 0x72, 0x69, + 0x6e, 0x63, 0x69, 0x70, 0x61, 0x6c, 0x65, 0x73, 0x70, 0x72, 0x6f, 0x74, 0x65, + 0x63, 0x63, 0x69, 0xc3, 0xb3, 0x6e, 0x69, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x61, + 0x6e, 0x74, 0x65, 0x73, 0x69, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x61, 0x6e, 0x63, + 0x69, 0x61, 0x70, 0x6f, 0x73, 0x69, 0x62, 0x69, 0x6c, 0x69, 0x64, 0x61, 0x64, + 0x69, 0x6e, 0x74, 0x65, 0x72, 0x65, 0x73, 0x61, 0x6e, 0x74, 0x65, 0x63, 0x72, + 0x65, 0x63, 0x69, 0x6d, 0x69, 0x65, 0x6e, 0x74, 0x6f, 0x6e, 0x65, 0x63, 0x65, + 0x73, 0x69, 0x64, 0x61, 0x64, 0x65, 0x73, 0x73, 0x75, 0x73, 0x63, 0x72, 0x69, + 0x62, 0x69, 0x72, 0x73, 0x65, 0x61, 0x73, 0x6f, 0x63, 0x69, 0x61, 0x63, 0x69, + 0xc3, 0xb3, 0x6e, 0x64, 0x69, 0x73, 0x70, 0x6f, 0x6e, 0x69, 0x62, 0x6c, 0x65, + 0x73, 0x65, 0x76, 0x61, 0x6c, 0x75, 0x61, 0x63, 0x69, 0xc3, 0xb3, 0x6e, 0x65, + 0x73, 0x74, 0x75, 0x64, 0x69, 0x61, 0x6e, 0x74, 0x65, 0x73, 0x72, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x72, 0x65, 0x73, 0x6f, 0x6c, + 0x75, 0x63, 0x69, 0xc3, 0xb3, 0x6e, 0x67, 0x75, 0x61, 0x64, 0x61, 0x6c, 0x61, + 0x6a, 0x61, 0x72, 0x61, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x61, 0x64, + 0x6f, 0x73, 0x6f, 0x70, 0x6f, 0x72, 0x74, 0x75, 0x6e, 0x69, 0x64, 0x61, 0x64, + 0x63, 0x6f, 0x6d, 0x65, 0x72, 0x63, 0x69, 0x61, 0x6c, 0x65, 0x73, 0x66, 0x6f, + 0x74, 0x6f, 0x67, 0x72, 0x61, 0x66, 0xc3, 0xad, 0x61, 0x61, 0x75, 0x74, 0x6f, + 0x72, 0x69, 0x64, 0x61, 0x64, 0x65, 0x73, 0x69, 0x6e, 0x67, 0x65, 0x6e, 0x69, + 0x65, 0x72, 0xc3, 0xad, 0x61, 0x74, 0x65, 0x6c, 0x65, 0x76, 0x69, 0x73, 0x69, + 0xc3, 0xb3, 0x6e, 0x63, 0x6f, 0x6d, 0x70, 0x65, 0x74, 0x65, 0x6e, 0x63, 0x69, + 0x61, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x63, 0x69, 0x6f, 0x6e, 0x65, 0x73, 0x65, + 0x73, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x63, 0x69, 0x64, 0x6f, 0x73, 0x69, 0x6d, + 0x70, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x65, 0x61, 0x63, 0x74, 0x75, 0x61, + 0x6c, 0x6d, 0x65, 0x6e, 0x74, 0x65, 0x6e, 0x61, 0x76, 0x65, 0x67, 0x61, 0x63, + 0x69, 0xc3, 0xb3, 0x6e, 0x63, 0x6f, 0x6e, 0x66, 0x6f, 0x72, 0x6d, 0x69, 0x64, + 0x61, 0x64, 0x6c, 0x69, 0x6e, 0x65, 0x2d, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, + 0x3a, 0x66, 0x6f, 0x6e, 0x74, 0x2d, 0x66, 0x61, 0x6d, 0x69, 0x6c, 0x79, 0x3a, + 0x22, 0x20, 0x3a, 0x20, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x61, + 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x6c, 0x69, + 0x6e, 0x6b, 0x22, 0x20, 0x68, 0x72, 0x65, 0x66, 0x3d, 0x22, 0x73, 0x70, 0x65, + 0x63, 0x69, 0x66, 0x69, 0x63, 0x61, 0x6c, 0x6c, 0x79, 0x2f, 0x2f, 0x3c, 0x21, + 0x5b, 0x43, 0x44, 0x41, 0x54, 0x41, 0x5b, 0x0a, 0x4f, 0x72, 0x67, 0x61, 0x6e, + 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x64, 0x69, 0x73, 0x74, 0x72, 0x69, + 0x62, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x30, 0x70, 0x78, 0x3b, 0x20, 0x68, 0x65, + 0x69, 0x67, 0x68, 0x74, 0x3a, 0x72, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x73, 0x68, 0x69, 0x70, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x2d, 0x77, 0x69, + 0x64, 0x74, 0x68, 0x3c, 0x64, 0x69, 0x76, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, + 0x3d, 0x22, 0x3c, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x20, 0x66, 0x6f, 0x72, 0x3d, + 0x22, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x3c, 0x2f, 0x6e, 0x6f, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x3e, 0x0a, 0x2f, + 0x69, 0x6e, 0x64, 0x65, 0x78, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0x22, 0x77, 0x69, + 0x6e, 0x64, 0x6f, 0x77, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x28, 0x20, 0x21, 0x69, + 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x61, 0x6e, 0x74, 0x3b, 0x61, 0x70, 0x70, 0x6c, + 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x69, 0x6e, 0x64, 0x65, 0x70, + 0x65, 0x6e, 0x64, 0x65, 0x6e, 0x63, 0x65, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, + 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x6f, 0x72, 0x67, 0x61, 0x6e, 0x69, 0x7a, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x75, 0x74, 0x6f, 0x63, 0x6f, 0x6d, 0x70, + 0x6c, 0x65, 0x74, 0x65, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x6d, 0x65, + 0x6e, 0x74, 0x73, 0x63, 0x6f, 0x6e, 0x73, 0x65, 0x72, 0x76, 0x61, 0x74, 0x69, + 0x76, 0x65, 0x3c, 0x66, 0x6f, 0x72, 0x6d, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x3d, + 0x22, 0x69, 0x6e, 0x74, 0x65, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x75, 0x61, 0x6c, + 0x6d, 0x61, 0x72, 0x67, 0x69, 0x6e, 0x2d, 0x6c, 0x65, 0x66, 0x74, 0x3a, 0x31, + 0x38, 0x74, 0x68, 0x20, 0x63, 0x65, 0x6e, 0x74, 0x75, 0x72, 0x79, 0x61, 0x6e, + 0x20, 0x69, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x61, 0x6e, 0x74, 0x69, 0x6e, 0x73, + 0x74, 0x69, 0x74, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x61, 0x62, 0x62, 0x72, + 0x65, 0x76, 0x69, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3c, 0x69, 0x6d, 0x67, 0x20, + 0x63, 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x22, 0x6f, 0x72, 0x67, 0x61, 0x6e, 0x69, + 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x63, 0x69, 0x76, 0x69, 0x6c, 0x69, 0x7a, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x31, 0x39, 0x74, 0x68, 0x20, 0x63, 0x65, 0x6e, + 0x74, 0x75, 0x72, 0x79, 0x61, 0x72, 0x63, 0x68, 0x69, 0x74, 0x65, 0x63, 0x74, + 0x75, 0x72, 0x65, 0x69, 0x6e, 0x63, 0x6f, 0x72, 0x70, 0x6f, 0x72, 0x61, 0x74, + 0x65, 0x64, 0x32, 0x30, 0x74, 0x68, 0x20, 0x63, 0x65, 0x6e, 0x74, 0x75, 0x72, + 0x79, 0x2d, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x22, 0x3e, + 0x6d, 0x6f, 0x73, 0x74, 0x20, 0x6e, 0x6f, 0x74, 0x61, 0x62, 0x6c, 0x79, 0x2f, + 0x3e, 0x3c, 0x2f, 0x61, 0x3e, 0x3c, 0x2f, 0x64, 0x69, 0x76, 0x3e, 0x6e, 0x6f, + 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x27, 0x75, 0x6e, + 0x64, 0x65, 0x66, 0x69, 0x6e, 0x65, 0x64, 0x27, 0x29, 0x46, 0x75, 0x72, 0x74, + 0x68, 0x65, 0x72, 0x6d, 0x6f, 0x72, 0x65, 0x2c, 0x62, 0x65, 0x6c, 0x69, 0x65, + 0x76, 0x65, 0x20, 0x74, 0x68, 0x61, 0x74, 0x69, 0x6e, 0x6e, 0x65, 0x72, 0x48, + 0x54, 0x4d, 0x4c, 0x20, 0x3d, 0x20, 0x70, 0x72, 0x69, 0x6f, 0x72, 0x20, 0x74, + 0x6f, 0x20, 0x74, 0x68, 0x65, 0x64, 0x72, 0x61, 0x6d, 0x61, 0x74, 0x69, 0x63, + 0x61, 0x6c, 0x6c, 0x79, 0x72, 0x65, 0x66, 0x65, 0x72, 0x72, 0x69, 0x6e, 0x67, + 0x20, 0x74, 0x6f, 0x6e, 0x65, 0x67, 0x6f, 0x74, 0x69, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x73, 0x68, 0x65, 0x61, 0x64, 0x71, 0x75, 0x61, 0x72, 0x74, 0x65, 0x72, + 0x73, 0x53, 0x6f, 0x75, 0x74, 0x68, 0x20, 0x41, 0x66, 0x72, 0x69, 0x63, 0x61, + 0x75, 0x6e, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x66, 0x75, 0x6c, 0x50, + 0x65, 0x6e, 0x6e, 0x73, 0x79, 0x6c, 0x76, 0x61, 0x6e, 0x69, 0x61, 0x41, 0x73, + 0x20, 0x61, 0x20, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x2c, 0x3c, 0x68, 0x74, + 0x6d, 0x6c, 0x20, 0x6c, 0x61, 0x6e, 0x67, 0x3d, 0x22, 0x26, 0x6c, 0x74, 0x3b, + 0x2f, 0x73, 0x75, 0x70, 0x26, 0x67, 0x74, 0x3b, 0x64, 0x65, 0x61, 0x6c, 0x69, + 0x6e, 0x67, 0x20, 0x77, 0x69, 0x74, 0x68, 0x70, 0x68, 0x69, 0x6c, 0x61, 0x64, + 0x65, 0x6c, 0x70, 0x68, 0x69, 0x61, 0x68, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x69, + 0x63, 0x61, 0x6c, 0x6c, 0x79, 0x29, 0x3b, 0x3c, 0x2f, 0x73, 0x63, 0x72, 0x69, + 0x70, 0x74, 0x3e, 0x0a, 0x70, 0x61, 0x64, 0x64, 0x69, 0x6e, 0x67, 0x2d, 0x74, + 0x6f, 0x70, 0x3a, 0x65, 0x78, 0x70, 0x65, 0x72, 0x69, 0x6d, 0x65, 0x6e, 0x74, + 0x61, 0x6c, 0x67, 0x65, 0x74, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, + 0x65, 0x69, 0x6e, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, + 0x74, 0x65, 0x63, 0x68, 0x6e, 0x6f, 0x6c, 0x6f, 0x67, 0x69, 0x65, 0x73, 0x70, + 0x61, 0x72, 0x74, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x3d, 0x66, + 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x29, 0x7b, 0x73, 0x75, 0x62, + 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x6c, 0x2e, 0x64, 0x74, + 0x64, 0x22, 0x3e, 0x0d, 0x0a, 0x3c, 0x68, 0x74, 0x67, 0x65, 0x6f, 0x67, 0x72, + 0x61, 0x70, 0x68, 0x69, 0x63, 0x61, 0x6c, 0x43, 0x6f, 0x6e, 0x73, 0x74, 0x69, + 0x74, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x27, 0x2c, 0x20, 0x66, 0x75, 0x6e, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, + 0x64, 0x20, 0x62, 0x79, 0x61, 0x67, 0x72, 0x69, 0x63, 0x75, 0x6c, 0x74, 0x75, + 0x72, 0x61, 0x6c, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x73, 0x66, 0x6f, 0x6e, 0x74, 0x2d, 0x73, 0x69, 0x7a, 0x65, 0x3a, 0x20, 0x31, + 0x61, 0x20, 0x76, 0x61, 0x72, 0x69, 0x65, 0x74, 0x79, 0x20, 0x6f, 0x66, 0x3c, + 0x64, 0x69, 0x76, 0x20, 0x73, 0x74, 0x79, 0x6c, 0x65, 0x3d, 0x22, 0x45, 0x6e, + 0x63, 0x79, 0x63, 0x6c, 0x6f, 0x70, 0x65, 0x64, 0x69, 0x61, 0x69, 0x66, 0x72, + 0x61, 0x6d, 0x65, 0x20, 0x73, 0x72, 0x63, 0x3d, 0x22, 0x64, 0x65, 0x6d, 0x6f, + 0x6e, 0x73, 0x74, 0x72, 0x61, 0x74, 0x65, 0x64, 0x61, 0x63, 0x63, 0x6f, 0x6d, + 0x70, 0x6c, 0x69, 0x73, 0x68, 0x65, 0x64, 0x75, 0x6e, 0x69, 0x76, 0x65, 0x72, + 0x73, 0x69, 0x74, 0x69, 0x65, 0x73, 0x44, 0x65, 0x6d, 0x6f, 0x67, 0x72, 0x61, + 0x70, 0x68, 0x69, 0x63, 0x73, 0x29, 0x3b, 0x3c, 0x2f, 0x73, 0x63, 0x72, 0x69, + 0x70, 0x74, 0x3e, 0x3c, 0x64, 0x65, 0x64, 0x69, 0x63, 0x61, 0x74, 0x65, 0x64, + 0x20, 0x74, 0x6f, 0x6b, 0x6e, 0x6f, 0x77, 0x6c, 0x65, 0x64, 0x67, 0x65, 0x20, + 0x6f, 0x66, 0x73, 0x61, 0x74, 0x69, 0x73, 0x66, 0x61, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x70, 0x61, 0x72, 0x74, 0x69, 0x63, 0x75, 0x6c, 0x61, 0x72, 0x6c, 0x79, + 0x3c, 0x2f, 0x64, 0x69, 0x76, 0x3e, 0x3c, 0x2f, 0x64, 0x69, 0x76, 0x3e, 0x45, + 0x6e, 0x67, 0x6c, 0x69, 0x73, 0x68, 0x20, 0x28, 0x55, 0x53, 0x29, 0x61, 0x70, + 0x70, 0x65, 0x6e, 0x64, 0x43, 0x68, 0x69, 0x6c, 0x64, 0x28, 0x74, 0x72, 0x61, + 0x6e, 0x73, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x20, 0x48, + 0x6f, 0x77, 0x65, 0x76, 0x65, 0x72, 0x2c, 0x20, 0x69, 0x6e, 0x74, 0x65, 0x6c, + 0x6c, 0x69, 0x67, 0x65, 0x6e, 0x63, 0x65, 0x22, 0x20, 0x74, 0x61, 0x62, 0x69, + 0x6e, 0x64, 0x65, 0x78, 0x3d, 0x22, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x3a, 0x72, + 0x69, 0x67, 0x68, 0x74, 0x3b, 0x43, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x77, 0x65, + 0x61, 0x6c, 0x74, 0x68, 0x72, 0x61, 0x6e, 0x67, 0x69, 0x6e, 0x67, 0x20, 0x66, + 0x72, 0x6f, 0x6d, 0x69, 0x6e, 0x20, 0x77, 0x68, 0x69, 0x63, 0x68, 0x20, 0x74, + 0x68, 0x65, 0x61, 0x74, 0x20, 0x6c, 0x65, 0x61, 0x73, 0x74, 0x20, 0x6f, 0x6e, + 0x65, 0x72, 0x65, 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x65, 0x6e, 0x63, 0x79, 0x63, 0x6c, 0x6f, 0x70, 0x65, 0x64, 0x69, 0x61, 0x3b, + 0x66, 0x6f, 0x6e, 0x74, 0x2d, 0x73, 0x69, 0x7a, 0x65, 0x3a, 0x31, 0x6a, 0x75, + 0x72, 0x69, 0x73, 0x64, 0x69, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x74, 0x20, + 0x74, 0x68, 0x61, 0x74, 0x20, 0x74, 0x69, 0x6d, 0x65, 0x22, 0x3e, 0x3c, 0x61, + 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x22, 0x49, 0x6e, 0x20, 0x61, 0x64, + 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x2c, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, + 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x2b, 0x63, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x63, 0x74, 0x20, + 0x77, 0x69, 0x74, 0x68, 0x69, 0x73, 0x20, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, + 0x6c, 0x6c, 0x79, 0x72, 0x22, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, + 0x3d, 0x22, 0x72, 0x65, 0x70, 0x72, 0x65, 0x73, 0x65, 0x6e, 0x74, 0x69, 0x6e, + 0x67, 0x26, 0x6c, 0x74, 0x3b, 0x6d, 0x61, 0x74, 0x68, 0x26, 0x67, 0x74, 0x3b, + 0x70, 0x72, 0x65, 0x73, 0x65, 0x6e, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x6f, + 0x63, 0x63, 0x61, 0x73, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x6c, 0x79, 0x3c, 0x69, + 0x6d, 0x67, 0x20, 0x77, 0x69, 0x64, 0x74, 0x68, 0x3d, 0x22, 0x6e, 0x61, 0x76, + 0x69, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x3e, 0x63, 0x6f, 0x6d, 0x70, + 0x65, 0x6e, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x63, 0x68, 0x61, 0x6d, 0x70, + 0x69, 0x6f, 0x6e, 0x73, 0x68, 0x69, 0x70, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x3d, + 0x22, 0x61, 0x6c, 0x6c, 0x22, 0x20, 0x76, 0x69, 0x6f, 0x6c, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x20, 0x6f, 0x66, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, + 0x65, 0x20, 0x74, 0x6f, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x74, 0x72, + 0x75, 0x65, 0x3b, 0x53, 0x74, 0x72, 0x69, 0x63, 0x74, 0x2f, 0x2f, 0x45, 0x4e, + 0x22, 0x20, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x73, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x65, 0x6e, 0x74, 0x69, 0x6f, 0x6e, + 0x76, 0x65, 0x72, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, + 0x6e, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x64, 0x69, + 0x66, 0x66, 0x69, 0x63, 0x75, 0x6c, 0x74, 0x69, 0x65, 0x73, 0x43, 0x68, 0x61, + 0x6d, 0x70, 0x69, 0x6f, 0x6e, 0x73, 0x68, 0x69, 0x70, 0x63, 0x61, 0x70, 0x61, + 0x62, 0x69, 0x6c, 0x69, 0x74, 0x69, 0x65, 0x73, 0x3c, 0x21, 0x5b, 0x65, 0x6e, + 0x64, 0x69, 0x66, 0x5d, 0x2d, 0x2d, 0x3e, 0x7d, 0x0a, 0x3c, 0x2f, 0x73, 0x63, + 0x72, 0x69, 0x70, 0x74, 0x3e, 0x0a, 0x43, 0x68, 0x72, 0x69, 0x73, 0x74, 0x69, + 0x61, 0x6e, 0x69, 0x74, 0x79, 0x66, 0x6f, 0x72, 0x20, 0x65, 0x78, 0x61, 0x6d, + 0x70, 0x6c, 0x65, 0x2c, 0x50, 0x72, 0x6f, 0x66, 0x65, 0x73, 0x73, 0x69, 0x6f, + 0x6e, 0x61, 0x6c, 0x72, 0x65, 0x73, 0x74, 0x72, 0x69, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x73, 0x73, 0x75, 0x67, 0x67, 0x65, 0x73, 0x74, 0x20, 0x74, 0x68, 0x61, + 0x74, 0x77, 0x61, 0x73, 0x20, 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x64, + 0x28, 0x73, 0x75, 0x63, 0x68, 0x20, 0x61, 0x73, 0x20, 0x74, 0x68, 0x65, 0x72, + 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x28, 0x75, 0x6e, + 0x65, 0x6d, 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x74, 0x68, 0x65, + 0x20, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x6e, 0x73, 0x74, 0x72, 0x75, + 0x63, 0x74, 0x75, 0x72, 0x65, 0x20, 0x6f, 0x66, 0x2f, 0x69, 0x6e, 0x64, 0x65, + 0x78, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0x20, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x73, + 0x68, 0x65, 0x64, 0x20, 0x69, 0x6e, 0x73, 0x70, 0x61, 0x6e, 0x20, 0x63, 0x6c, + 0x61, 0x73, 0x73, 0x3d, 0x22, 0x22, 0x3e, 0x3c, 0x61, 0x20, 0x68, 0x72, 0x65, + 0x66, 0x3d, 0x22, 0x2f, 0x69, 0x6e, 0x74, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x62, 0x65, 0x6c, 0x6f, 0x6e, 0x67, 0x69, 0x6e, 0x67, 0x20, + 0x74, 0x6f, 0x63, 0x6c, 0x61, 0x69, 0x6d, 0x65, 0x64, 0x20, 0x74, 0x68, 0x61, + 0x74, 0x63, 0x6f, 0x6e, 0x73, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x65, 0x73, + 0x3c, 0x6d, 0x65, 0x74, 0x61, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x3d, 0x22, 0x47, + 0x75, 0x69, 0x64, 0x65, 0x20, 0x74, 0x6f, 0x20, 0x74, 0x68, 0x65, 0x6f, 0x76, + 0x65, 0x72, 0x77, 0x68, 0x65, 0x6c, 0x6d, 0x69, 0x6e, 0x67, 0x61, 0x67, 0x61, + 0x69, 0x6e, 0x73, 0x74, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x6f, 0x6e, 0x63, + 0x65, 0x6e, 0x74, 0x72, 0x61, 0x74, 0x65, 0x64, 0x2c, 0x0a, 0x2e, 0x6e, 0x6f, + 0x6e, 0x74, 0x6f, 0x75, 0x63, 0x68, 0x20, 0x6f, 0x62, 0x73, 0x65, 0x72, 0x76, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x3c, 0x2f, 0x61, 0x3e, 0x0a, 0x3c, 0x2f, + 0x64, 0x69, 0x76, 0x3e, 0x0a, 0x66, 0x20, 0x28, 0x64, 0x6f, 0x63, 0x75, 0x6d, + 0x65, 0x6e, 0x74, 0x2e, 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x3a, 0x20, 0x31, + 0x70, 0x78, 0x20, 0x7b, 0x66, 0x6f, 0x6e, 0x74, 0x2d, 0x73, 0x69, 0x7a, 0x65, + 0x3a, 0x31, 0x74, 0x72, 0x65, 0x61, 0x74, 0x6d, 0x65, 0x6e, 0x74, 0x20, 0x6f, + 0x66, 0x30, 0x22, 0x20, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x3d, 0x22, 0x31, + 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, + 0x6e, 0x64, 0x65, 0x70, 0x65, 0x6e, 0x64, 0x65, 0x6e, 0x63, 0x65, 0x64, 0x69, + 0x76, 0x69, 0x64, 0x65, 0x64, 0x20, 0x69, 0x6e, 0x74, 0x6f, 0x67, 0x72, 0x65, + 0x61, 0x74, 0x65, 0x72, 0x20, 0x74, 0x68, 0x61, 0x6e, 0x61, 0x63, 0x68, 0x69, + 0x65, 0x76, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x65, 0x73, 0x74, 0x61, 0x62, + 0x6c, 0x69, 0x73, 0x68, 0x69, 0x6e, 0x67, 0x4a, 0x61, 0x76, 0x61, 0x53, 0x63, + 0x72, 0x69, 0x70, 0x74, 0x22, 0x20, 0x6e, 0x65, 0x76, 0x65, 0x72, 0x74, 0x68, + 0x65, 0x6c, 0x65, 0x73, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x69, 0x66, 0x69, 0x63, + 0x61, 0x6e, 0x63, 0x65, 0x42, 0x72, 0x6f, 0x61, 0x64, 0x63, 0x61, 0x73, 0x74, + 0x69, 0x6e, 0x67, 0x3e, 0x26, 0x6e, 0x62, 0x73, 0x70, 0x3b, 0x3c, 0x2f, 0x74, + 0x64, 0x3e, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x22, 0x3e, + 0x0a, 0x73, 0x75, 0x63, 0x68, 0x20, 0x61, 0x73, 0x20, 0x74, 0x68, 0x65, 0x20, + 0x69, 0x6e, 0x66, 0x6c, 0x75, 0x65, 0x6e, 0x63, 0x65, 0x20, 0x6f, 0x66, 0x61, + 0x20, 0x70, 0x61, 0x72, 0x74, 0x69, 0x63, 0x75, 0x6c, 0x61, 0x72, 0x73, 0x72, + 0x63, 0x3d, 0x27, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6e, 0x61, 0x76, + 0x69, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x20, 0x68, 0x61, 0x6c, 0x66, + 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x73, 0x75, 0x62, 0x73, 0x74, + 0x61, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x20, 0x26, 0x6e, 0x62, 0x73, 0x70, 0x3b, + 0x3c, 0x2f, 0x64, 0x69, 0x76, 0x3e, 0x61, 0x64, 0x76, 0x61, 0x6e, 0x74, 0x61, + 0x67, 0x65, 0x20, 0x6f, 0x66, 0x64, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, + 0x79, 0x20, 0x6f, 0x66, 0x66, 0x75, 0x6e, 0x64, 0x61, 0x6d, 0x65, 0x6e, 0x74, + 0x61, 0x6c, 0x20, 0x6d, 0x65, 0x74, 0x72, 0x6f, 0x70, 0x6f, 0x6c, 0x69, 0x74, + 0x61, 0x6e, 0x74, 0x68, 0x65, 0x20, 0x6f, 0x70, 0x70, 0x6f, 0x73, 0x69, 0x74, + 0x65, 0x22, 0x20, 0x78, 0x6d, 0x6c, 0x3a, 0x6c, 0x61, 0x6e, 0x67, 0x3d, 0x22, + 0x64, 0x65, 0x6c, 0x69, 0x62, 0x65, 0x72, 0x61, 0x74, 0x65, 0x6c, 0x79, 0x61, + 0x6c, 0x69, 0x67, 0x6e, 0x3d, 0x63, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x65, 0x76, + 0x6f, 0x6c, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6f, 0x66, 0x70, 0x72, 0x65, + 0x73, 0x65, 0x72, 0x76, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x69, 0x6d, 0x70, 0x72, + 0x6f, 0x76, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x62, 0x65, 0x67, 0x69, 0x6e, + 0x6e, 0x69, 0x6e, 0x67, 0x20, 0x69, 0x6e, 0x4a, 0x65, 0x73, 0x75, 0x73, 0x20, + 0x43, 0x68, 0x72, 0x69, 0x73, 0x74, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x64, 0x69, 0x73, 0x61, 0x67, 0x72, 0x65, 0x65, + 0x6d, 0x65, 0x6e, 0x74, 0x74, 0x65, 0x78, 0x74, 0x2d, 0x61, 0x6c, 0x69, 0x67, + 0x6e, 0x3a, 0x72, 0x2c, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x28, 0x29, 0x73, 0x69, 0x6d, 0x69, 0x6c, 0x61, 0x72, 0x69, 0x74, 0x69, 0x65, + 0x73, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0x3c, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x3e, + 0x69, 0x73, 0x20, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x6c, 0x79, 0x61, + 0x6c, 0x70, 0x68, 0x61, 0x62, 0x65, 0x74, 0x69, 0x63, 0x61, 0x6c, 0x69, 0x73, + 0x20, 0x73, 0x6f, 0x6d, 0x65, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x79, 0x70, + 0x65, 0x3d, 0x22, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x2f, 0x6d, 0x61, 0x6e, 0x79, + 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x66, 0x6c, 0x6f, 0x77, 0x3a, + 0x68, 0x69, 0x64, 0x64, 0x65, 0x6e, 0x3b, 0x61, 0x76, 0x61, 0x69, 0x6c, 0x61, + 0x62, 0x6c, 0x65, 0x20, 0x69, 0x6e, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x62, + 0x65, 0x20, 0x74, 0x68, 0x65, 0x65, 0x78, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x63, + 0x65, 0x20, 0x6f, 0x66, 0x61, 0x6c, 0x6c, 0x20, 0x6f, 0x76, 0x65, 0x72, 0x20, + 0x74, 0x68, 0x65, 0x74, 0x68, 0x65, 0x20, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, + 0x65, 0x74, 0x09, 0x3c, 0x75, 0x6c, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x3d, + 0x22, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x6e, 0x65, 0x69, 0x67, 0x68, 0x62, 0x6f, 0x72, 0x68, 0x6f, 0x6f, 0x64, 0x61, + 0x72, 0x6d, 0x65, 0x64, 0x20, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x73, 0x72, 0x65, + 0x64, 0x75, 0x63, 0x69, 0x6e, 0x67, 0x20, 0x74, 0x68, 0x65, 0x63, 0x6f, 0x6e, + 0x74, 0x69, 0x6e, 0x75, 0x65, 0x73, 0x20, 0x74, 0x6f, 0x4e, 0x6f, 0x6e, 0x65, + 0x74, 0x68, 0x65, 0x6c, 0x65, 0x73, 0x73, 0x2c, 0x74, 0x65, 0x6d, 0x70, 0x65, + 0x72, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x0a, 0x09, 0x09, 0x3c, 0x61, 0x20, + 0x68, 0x72, 0x65, 0x66, 0x3d, 0x22, 0x63, 0x6c, 0x6f, 0x73, 0x65, 0x20, 0x74, + 0x6f, 0x20, 0x74, 0x68, 0x65, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x73, + 0x20, 0x6f, 0x66, 0x20, 0x69, 0x73, 0x20, 0x61, 0x62, 0x6f, 0x75, 0x74, 0x20, + 0x74, 0x68, 0x65, 0x28, 0x73, 0x65, 0x65, 0x20, 0x62, 0x65, 0x6c, 0x6f, 0x77, + 0x29, 0x2e, 0x22, 0x20, 0x69, 0x64, 0x3d, 0x22, 0x73, 0x65, 0x61, 0x72, 0x63, + 0x68, 0x70, 0x72, 0x6f, 0x66, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x61, 0x6c, + 0x69, 0x73, 0x20, 0x61, 0x76, 0x61, 0x69, 0x6c, 0x61, 0x62, 0x6c, 0x65, 0x74, + 0x68, 0x65, 0x20, 0x6f, 0x66, 0x66, 0x69, 0x63, 0x69, 0x61, 0x6c, 0x09, 0x09, + 0x3c, 0x2f, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x3e, 0x0a, 0x0a, 0x09, 0x09, + 0x3c, 0x64, 0x69, 0x76, 0x20, 0x69, 0x64, 0x3d, 0x22, 0x61, 0x63, 0x63, 0x65, + 0x6c, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x74, 0x68, 0x72, 0x6f, 0x75, + 0x67, 0x68, 0x20, 0x74, 0x68, 0x65, 0x20, 0x48, 0x61, 0x6c, 0x6c, 0x20, 0x6f, + 0x66, 0x20, 0x46, 0x61, 0x6d, 0x65, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, + 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x6c, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x73, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x65, 0x72, 0x65, + 0x6e, 0x63, 0x65, 0x20, 0x74, 0x79, 0x70, 0x65, 0x3d, 0x27, 0x74, 0x65, 0x78, + 0x74, 0x2f, 0x72, 0x65, 0x63, 0x65, 0x6e, 0x74, 0x20, 0x79, 0x65, 0x61, 0x72, + 0x73, 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x77, 0x6f, 0x72, 0x6c, 0x64, + 0x76, 0x65, 0x72, 0x79, 0x20, 0x70, 0x6f, 0x70, 0x75, 0x6c, 0x61, 0x72, 0x7b, + 0x62, 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x3a, 0x74, 0x72, + 0x61, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x20, 0x73, 0x6f, 0x6d, + 0x65, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x6f, 0x6e, 0x6e, + 0x65, 0x63, 0x74, 0x65, 0x64, 0x20, 0x74, 0x6f, 0x65, 0x78, 0x70, 0x6c, 0x6f, + 0x69, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x65, 0x6d, 0x65, 0x72, 0x67, 0x65, + 0x6e, 0x63, 0x65, 0x20, 0x6f, 0x66, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x69, 0x74, + 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x41, 0x20, 0x48, 0x69, 0x73, 0x74, 0x6f, 0x72, + 0x79, 0x20, 0x6f, 0x66, 0x73, 0x69, 0x67, 0x6e, 0x69, 0x66, 0x69, 0x63, 0x61, + 0x6e, 0x74, 0x20, 0x6d, 0x61, 0x6e, 0x75, 0x66, 0x61, 0x63, 0x74, 0x75, 0x72, + 0x65, 0x64, 0x65, 0x78, 0x70, 0x65, 0x63, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x73, 0x3e, 0x3c, 0x6e, 0x6f, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x3e, 0x3c, + 0x63, 0x61, 0x6e, 0x20, 0x62, 0x65, 0x20, 0x66, 0x6f, 0x75, 0x6e, 0x64, 0x62, + 0x65, 0x63, 0x61, 0x75, 0x73, 0x65, 0x20, 0x74, 0x68, 0x65, 0x20, 0x68, 0x61, + 0x73, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x62, 0x65, 0x65, 0x6e, 0x6e, 0x65, 0x69, + 0x67, 0x68, 0x62, 0x6f, 0x75, 0x72, 0x69, 0x6e, 0x67, 0x77, 0x69, 0x74, 0x68, + 0x6f, 0x75, 0x74, 0x20, 0x74, 0x68, 0x65, 0x20, 0x61, 0x64, 0x64, 0x65, 0x64, + 0x20, 0x74, 0x6f, 0x20, 0x74, 0x68, 0x65, 0x09, 0x3c, 0x6c, 0x69, 0x20, 0x63, + 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x22, 0x69, 0x6e, 0x73, 0x74, 0x72, 0x75, 0x6d, + 0x65, 0x6e, 0x74, 0x61, 0x6c, 0x53, 0x6f, 0x76, 0x69, 0x65, 0x74, 0x20, 0x55, + 0x6e, 0x69, 0x6f, 0x6e, 0x61, 0x63, 0x6b, 0x6e, 0x6f, 0x77, 0x6c, 0x65, 0x64, + 0x67, 0x65, 0x64, 0x77, 0x68, 0x69, 0x63, 0x68, 0x20, 0x63, 0x61, 0x6e, 0x20, + 0x62, 0x65, 0x6e, 0x61, 0x6d, 0x65, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x74, 0x68, + 0x65, 0x61, 0x74, 0x74, 0x65, 0x6e, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x74, 0x6f, + 0x61, 0x74, 0x74, 0x65, 0x6d, 0x70, 0x74, 0x73, 0x20, 0x74, 0x6f, 0x20, 0x64, + 0x65, 0x76, 0x65, 0x6c, 0x6f, 0x70, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x49, 0x6e, + 0x20, 0x66, 0x61, 0x63, 0x74, 0x2c, 0x20, 0x74, 0x68, 0x65, 0x3c, 0x6c, 0x69, + 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x22, 0x61, 0x69, 0x6d, 0x70, 0x6c, + 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x73, 0x75, 0x69, 0x74, 0x61, + 0x62, 0x6c, 0x65, 0x20, 0x66, 0x6f, 0x72, 0x6d, 0x75, 0x63, 0x68, 0x20, 0x6f, + 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x6f, 0x6c, 0x6f, 0x6e, 0x69, 0x7a, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x70, 0x72, 0x65, 0x73, 0x69, 0x64, 0x65, 0x6e, + 0x74, 0x69, 0x61, 0x6c, 0x63, 0x61, 0x6e, 0x63, 0x65, 0x6c, 0x42, 0x75, 0x62, + 0x62, 0x6c, 0x65, 0x20, 0x49, 0x6e, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x6d, 0x6f, 0x73, 0x74, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, + 0x20, 0x69, 0x73, 0x20, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x64, + 0x72, 0x65, 0x73, 0x74, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x6d, + 0x6f, 0x72, 0x65, 0x20, 0x6f, 0x72, 0x20, 0x6c, 0x65, 0x73, 0x73, 0x69, 0x6e, + 0x20, 0x53, 0x65, 0x70, 0x74, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x49, 0x6e, 0x74, + 0x65, 0x6c, 0x6c, 0x69, 0x67, 0x65, 0x6e, 0x63, 0x65, 0x73, 0x72, 0x63, 0x3d, + 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x70, 0x78, 0x3b, 0x20, 0x68, + 0x65, 0x69, 0x67, 0x68, 0x74, 0x3a, 0x20, 0x61, 0x76, 0x61, 0x69, 0x6c, 0x61, + 0x62, 0x6c, 0x65, 0x20, 0x74, 0x6f, 0x6d, 0x61, 0x6e, 0x75, 0x66, 0x61, 0x63, + 0x74, 0x75, 0x72, 0x65, 0x72, 0x68, 0x75, 0x6d, 0x61, 0x6e, 0x20, 0x72, 0x69, + 0x67, 0x68, 0x74, 0x73, 0x6c, 0x69, 0x6e, 0x6b, 0x20, 0x68, 0x72, 0x65, 0x66, + 0x3d, 0x22, 0x2f, 0x61, 0x76, 0x61, 0x69, 0x6c, 0x61, 0x62, 0x69, 0x6c, 0x69, + 0x74, 0x79, 0x70, 0x72, 0x6f, 0x70, 0x6f, 0x72, 0x74, 0x69, 0x6f, 0x6e, 0x61, + 0x6c, 0x6f, 0x75, 0x74, 0x73, 0x69, 0x64, 0x65, 0x20, 0x74, 0x68, 0x65, 0x20, + 0x61, 0x73, 0x74, 0x72, 0x6f, 0x6e, 0x6f, 0x6d, 0x69, 0x63, 0x61, 0x6c, 0x68, + 0x75, 0x6d, 0x61, 0x6e, 0x20, 0x62, 0x65, 0x69, 0x6e, 0x67, 0x73, 0x6e, 0x61, + 0x6d, 0x65, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x61, 0x72, 0x65, + 0x20, 0x66, 0x6f, 0x75, 0x6e, 0x64, 0x20, 0x69, 0x6e, 0x61, 0x72, 0x65, 0x20, + 0x62, 0x61, 0x73, 0x65, 0x64, 0x20, 0x6f, 0x6e, 0x73, 0x6d, 0x61, 0x6c, 0x6c, + 0x65, 0x72, 0x20, 0x74, 0x68, 0x61, 0x6e, 0x61, 0x20, 0x70, 0x65, 0x72, 0x73, + 0x6f, 0x6e, 0x20, 0x77, 0x68, 0x6f, 0x65, 0x78, 0x70, 0x61, 0x6e, 0x73, 0x69, + 0x6f, 0x6e, 0x20, 0x6f, 0x66, 0x61, 0x72, 0x67, 0x75, 0x69, 0x6e, 0x67, 0x20, + 0x74, 0x68, 0x61, 0x74, 0x6e, 0x6f, 0x77, 0x20, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, + 0x20, 0x61, 0x73, 0x49, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x65, 0x61, 0x72, + 0x6c, 0x79, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x74, + 0x65, 0x64, 0x65, 0x72, 0x69, 0x76, 0x65, 0x64, 0x20, 0x66, 0x72, 0x6f, 0x6d, + 0x53, 0x63, 0x61, 0x6e, 0x64, 0x69, 0x6e, 0x61, 0x76, 0x69, 0x61, 0x6e, 0x3c, + 0x2f, 0x61, 0x3e, 0x3c, 0x2f, 0x64, 0x69, 0x76, 0x3e, 0x0d, 0x0a, 0x63, 0x6f, + 0x6e, 0x73, 0x69, 0x64, 0x65, 0x72, 0x20, 0x74, 0x68, 0x65, 0x61, 0x6e, 0x20, + 0x65, 0x73, 0x74, 0x69, 0x6d, 0x61, 0x74, 0x65, 0x64, 0x74, 0x68, 0x65, 0x20, + 0x4e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x3c, 0x64, 0x69, 0x76, 0x20, + 0x69, 0x64, 0x3d, 0x22, 0x70, 0x61, 0x67, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, + 0x69, 0x6e, 0x67, 0x20, 0x69, 0x6e, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x73, 0x73, + 0x69, 0x6f, 0x6e, 0x65, 0x64, 0x61, 0x6e, 0x61, 0x6c, 0x6f, 0x67, 0x6f, 0x75, + 0x73, 0x20, 0x74, 0x6f, 0x61, 0x72, 0x65, 0x20, 0x72, 0x65, 0x71, 0x75, 0x69, + 0x72, 0x65, 0x64, 0x2f, 0x75, 0x6c, 0x3e, 0x0a, 0x3c, 0x2f, 0x64, 0x69, 0x76, + 0x3e, 0x0a, 0x77, 0x61, 0x73, 0x20, 0x62, 0x61, 0x73, 0x65, 0x64, 0x20, 0x6f, + 0x6e, 0x61, 0x6e, 0x64, 0x20, 0x62, 0x65, 0x63, 0x61, 0x6d, 0x65, 0x20, 0x61, + 0x26, 0x6e, 0x62, 0x73, 0x70, 0x3b, 0x26, 0x6e, 0x62, 0x73, 0x70, 0x3b, 0x74, + 0x22, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3d, 0x22, 0x22, 0x20, 0x77, 0x61, + 0x73, 0x20, 0x63, 0x61, 0x70, 0x74, 0x75, 0x72, 0x65, 0x64, 0x6e, 0x6f, 0x20, + 0x6d, 0x6f, 0x72, 0x65, 0x20, 0x74, 0x68, 0x61, 0x6e, 0x72, 0x65, 0x73, 0x70, + 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x6c, 0x79, 0x63, 0x6f, 0x6e, 0x74, 0x69, + 0x6e, 0x75, 0x65, 0x20, 0x74, 0x6f, 0x20, 0x3e, 0x0d, 0x0a, 0x3c, 0x68, 0x65, + 0x61, 0x64, 0x3e, 0x0d, 0x0a, 0x3c, 0x77, 0x65, 0x72, 0x65, 0x20, 0x63, 0x72, + 0x65, 0x61, 0x74, 0x65, 0x64, 0x6d, 0x6f, 0x72, 0x65, 0x20, 0x67, 0x65, 0x6e, + 0x65, 0x72, 0x61, 0x6c, 0x69, 0x6e, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x20, 0x75, 0x73, 0x65, 0x64, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x74, + 0x68, 0x65, 0x69, 0x6e, 0x64, 0x65, 0x70, 0x65, 0x6e, 0x64, 0x65, 0x6e, 0x74, + 0x20, 0x74, 0x68, 0x65, 0x20, 0x49, 0x6d, 0x70, 0x65, 0x72, 0x69, 0x61, 0x6c, + 0x63, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x20, 0x6f, 0x66, 0x74, + 0x6f, 0x20, 0x74, 0x68, 0x65, 0x20, 0x6e, 0x6f, 0x72, 0x74, 0x68, 0x69, 0x6e, + 0x63, 0x6c, 0x75, 0x64, 0x65, 0x20, 0x74, 0x68, 0x65, 0x20, 0x43, 0x6f, 0x6e, + 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x69, 0x64, 0x65, + 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x77, 0x6f, 0x75, 0x6c, 0x64, + 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x62, 0x65, 0x66, 0x6f, 0x72, 0x20, 0x69, 0x6e, + 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x69, 0x6e, 0x76, 0x65, 0x6e, 0x74, 0x69, + 0x6f, 0x6e, 0x20, 0x6f, 0x66, 0x6d, 0x6f, 0x72, 0x65, 0x20, 0x63, 0x6f, 0x6d, + 0x70, 0x6c, 0x65, 0x78, 0x63, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x76, + 0x65, 0x6c, 0x79, 0x62, 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, + 0x3a, 0x20, 0x74, 0x65, 0x78, 0x74, 0x2d, 0x61, 0x6c, 0x69, 0x67, 0x6e, 0x3a, + 0x20, 0x69, 0x74, 0x73, 0x20, 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x61, 0x6c, + 0x69, 0x6e, 0x74, 0x6f, 0x20, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x74, + 0x68, 0x69, 0x73, 0x20, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x61, 0x6e, + 0x20, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x76, 0x65, 0x68, 0x6f, 0x77, + 0x65, 0x76, 0x65, 0x72, 0x2c, 0x20, 0x74, 0x68, 0x65, 0x74, 0x68, 0x65, 0x79, + 0x20, 0x61, 0x72, 0x65, 0x20, 0x6e, 0x6f, 0x74, 0x72, 0x65, 0x6a, 0x65, 0x63, + 0x74, 0x65, 0x64, 0x20, 0x74, 0x68, 0x65, 0x63, 0x72, 0x69, 0x74, 0x69, 0x63, + 0x69, 0x73, 0x6d, 0x20, 0x6f, 0x66, 0x64, 0x75, 0x72, 0x69, 0x6e, 0x67, 0x20, + 0x77, 0x68, 0x69, 0x63, 0x68, 0x70, 0x72, 0x6f, 0x62, 0x61, 0x62, 0x6c, 0x79, + 0x20, 0x74, 0x68, 0x65, 0x74, 0x68, 0x69, 0x73, 0x20, 0x61, 0x72, 0x74, 0x69, + 0x63, 0x6c, 0x65, 0x28, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, + 0x29, 0x7b, 0x49, 0x74, 0x20, 0x73, 0x68, 0x6f, 0x75, 0x6c, 0x64, 0x20, 0x62, + 0x65, 0x61, 0x6e, 0x20, 0x61, 0x67, 0x72, 0x65, 0x65, 0x6d, 0x65, 0x6e, 0x74, + 0x61, 0x63, 0x63, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x61, 0x6c, 0x6c, 0x79, 0x64, + 0x69, 0x66, 0x66, 0x65, 0x72, 0x73, 0x20, 0x66, 0x72, 0x6f, 0x6d, 0x41, 0x72, + 0x63, 0x68, 0x69, 0x74, 0x65, 0x63, 0x74, 0x75, 0x72, 0x65, 0x62, 0x65, 0x74, + 0x74, 0x65, 0x72, 0x20, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x61, 0x72, 0x72, 0x61, + 0x6e, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x69, 0x6e, 0x66, 0x6c, 0x75, + 0x65, 0x6e, 0x63, 0x65, 0x20, 0x6f, 0x6e, 0x61, 0x74, 0x74, 0x65, 0x6e, 0x64, + 0x65, 0x64, 0x20, 0x74, 0x68, 0x65, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x63, + 0x61, 0x6c, 0x20, 0x74, 0x6f, 0x73, 0x6f, 0x75, 0x74, 0x68, 0x20, 0x6f, 0x66, + 0x20, 0x74, 0x68, 0x65, 0x70, 0x61, 0x73, 0x73, 0x20, 0x74, 0x68, 0x72, 0x6f, + 0x75, 0x67, 0x68, 0x78, 0x6d, 0x6c, 0x22, 0x20, 0x74, 0x69, 0x74, 0x6c, 0x65, + 0x3d, 0x22, 0x77, 0x65, 0x69, 0x67, 0x68, 0x74, 0x3a, 0x62, 0x6f, 0x6c, 0x64, + 0x3b, 0x63, 0x72, 0x65, 0x61, 0x74, 0x69, 0x6e, 0x67, 0x20, 0x74, 0x68, 0x65, + 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x3a, 0x6e, 0x6f, 0x6e, 0x65, 0x72, + 0x65, 0x70, 0x6c, 0x61, 0x63, 0x65, 0x64, 0x20, 0x74, 0x68, 0x65, 0x3c, 0x69, + 0x6d, 0x67, 0x20, 0x73, 0x72, 0x63, 0x3d, 0x22, 0x2f, 0x69, 0x68, 0x74, 0x74, + 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x57, 0x6f, 0x72, 0x6c, + 0x64, 0x20, 0x57, 0x61, 0x72, 0x20, 0x49, 0x49, 0x74, 0x65, 0x73, 0x74, 0x69, + 0x6d, 0x6f, 0x6e, 0x69, 0x61, 0x6c, 0x73, 0x66, 0x6f, 0x75, 0x6e, 0x64, 0x20, + 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, + 0x64, 0x20, 0x74, 0x6f, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x74, 0x68, 0x61, 0x74, + 0x20, 0x74, 0x68, 0x65, 0x62, 0x65, 0x74, 0x77, 0x65, 0x65, 0x6e, 0x20, 0x74, + 0x68, 0x65, 0x20, 0x77, 0x61, 0x73, 0x20, 0x64, 0x65, 0x73, 0x69, 0x67, 0x6e, + 0x65, 0x64, 0x63, 0x6f, 0x6e, 0x73, 0x69, 0x73, 0x74, 0x73, 0x20, 0x6f, 0x66, + 0x20, 0x63, 0x6f, 0x6e, 0x73, 0x69, 0x64, 0x65, 0x72, 0x61, 0x62, 0x6c, 0x79, + 0x70, 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x65, 0x64, 0x20, 0x62, 0x79, 0x74, + 0x68, 0x65, 0x20, 0x6c, 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, 0x43, 0x6f, + 0x6e, 0x73, 0x65, 0x72, 0x76, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x63, 0x6f, 0x6e, + 0x73, 0x69, 0x73, 0x74, 0x65, 0x64, 0x20, 0x6f, 0x66, 0x72, 0x65, 0x66, 0x65, + 0x72, 0x20, 0x74, 0x6f, 0x20, 0x74, 0x68, 0x65, 0x62, 0x61, 0x63, 0x6b, 0x20, + 0x74, 0x6f, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x73, 0x73, 0x22, 0x20, 0x6d, + 0x65, 0x64, 0x69, 0x61, 0x3d, 0x22, 0x50, 0x65, 0x6f, 0x70, 0x6c, 0x65, 0x20, + 0x66, 0x72, 0x6f, 0x6d, 0x20, 0x61, 0x76, 0x61, 0x69, 0x6c, 0x61, 0x62, 0x6c, + 0x65, 0x20, 0x6f, 0x6e, 0x70, 0x72, 0x6f, 0x76, 0x65, 0x64, 0x20, 0x74, 0x6f, + 0x20, 0x62, 0x65, 0x73, 0x75, 0x67, 0x67, 0x65, 0x73, 0x74, 0x69, 0x6f, 0x6e, + 0x73, 0x22, 0x77, 0x61, 0x73, 0x20, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x20, 0x61, + 0x73, 0x76, 0x61, 0x72, 0x69, 0x65, 0x74, 0x69, 0x65, 0x73, 0x20, 0x6f, 0x66, + 0x6c, 0x69, 0x6b, 0x65, 0x6c, 0x79, 0x20, 0x74, 0x6f, 0x20, 0x62, 0x65, 0x63, + 0x6f, 0x6d, 0x70, 0x72, 0x69, 0x73, 0x65, 0x64, 0x20, 0x6f, 0x66, 0x73, 0x75, + 0x70, 0x70, 0x6f, 0x72, 0x74, 0x20, 0x74, 0x68, 0x65, 0x20, 0x68, 0x61, 0x6e, + 0x64, 0x73, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x63, 0x6f, 0x75, 0x70, + 0x6c, 0x65, 0x64, 0x20, 0x77, 0x69, 0x74, 0x68, 0x63, 0x6f, 0x6e, 0x6e, 0x65, + 0x63, 0x74, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, + 0x3a, 0x6e, 0x6f, 0x6e, 0x65, 0x3b, 0x70, 0x65, 0x72, 0x66, 0x6f, 0x72, 0x6d, + 0x61, 0x6e, 0x63, 0x65, 0x73, 0x62, 0x65, 0x66, 0x6f, 0x72, 0x65, 0x20, 0x62, + 0x65, 0x69, 0x6e, 0x67, 0x6c, 0x61, 0x74, 0x65, 0x72, 0x20, 0x62, 0x65, 0x63, + 0x61, 0x6d, 0x65, 0x63, 0x61, 0x6c, 0x63, 0x75, 0x6c, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x73, 0x6f, 0x66, 0x74, 0x65, 0x6e, 0x20, 0x63, 0x61, 0x6c, 0x6c, 0x65, + 0x64, 0x72, 0x65, 0x73, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x73, 0x20, 0x6f, 0x66, + 0x6d, 0x65, 0x61, 0x6e, 0x69, 0x6e, 0x67, 0x20, 0x74, 0x68, 0x61, 0x74, 0x3e, + 0x3c, 0x6c, 0x69, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x22, 0x65, 0x76, + 0x69, 0x64, 0x65, 0x6e, 0x63, 0x65, 0x20, 0x66, 0x6f, 0x72, 0x65, 0x78, 0x70, + 0x6c, 0x61, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x65, 0x6e, 0x76, 0x69, + 0x72, 0x6f, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x22, 0x3e, 0x3c, 0x2f, 0x61, + 0x3e, 0x3c, 0x2f, 0x64, 0x69, 0x76, 0x3e, 0x77, 0x68, 0x69, 0x63, 0x68, 0x20, + 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x73, 0x49, 0x6e, 0x74, 0x72, 0x6f, 0x64, 0x75, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x64, 0x65, 0x76, 0x65, 0x6c, 0x6f, 0x70, 0x65, + 0x64, 0x20, 0x62, 0x79, 0x61, 0x20, 0x77, 0x69, 0x64, 0x65, 0x20, 0x72, 0x61, + 0x6e, 0x67, 0x65, 0x6f, 0x6e, 0x20, 0x62, 0x65, 0x68, 0x61, 0x6c, 0x66, 0x20, + 0x6f, 0x66, 0x76, 0x61, 0x6c, 0x69, 0x67, 0x6e, 0x3d, 0x22, 0x74, 0x6f, 0x70, + 0x22, 0x70, 0x72, 0x69, 0x6e, 0x63, 0x69, 0x70, 0x6c, 0x65, 0x20, 0x6f, 0x66, + 0x61, 0x74, 0x20, 0x74, 0x68, 0x65, 0x20, 0x74, 0x69, 0x6d, 0x65, 0x2c, 0x3c, + 0x2f, 0x6e, 0x6f, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x3e, 0x0d, 0x73, 0x61, + 0x69, 0x64, 0x20, 0x74, 0x6f, 0x20, 0x68, 0x61, 0x76, 0x65, 0x69, 0x6e, 0x20, + 0x74, 0x68, 0x65, 0x20, 0x66, 0x69, 0x72, 0x73, 0x74, 0x77, 0x68, 0x69, 0x6c, + 0x65, 0x20, 0x6f, 0x74, 0x68, 0x65, 0x72, 0x73, 0x68, 0x79, 0x70, 0x6f, 0x74, + 0x68, 0x65, 0x74, 0x69, 0x63, 0x61, 0x6c, 0x70, 0x68, 0x69, 0x6c, 0x6f, 0x73, + 0x6f, 0x70, 0x68, 0x65, 0x72, 0x73, 0x70, 0x6f, 0x77, 0x65, 0x72, 0x20, 0x6f, + 0x66, 0x20, 0x74, 0x68, 0x65, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, + 0x64, 0x20, 0x69, 0x6e, 0x70, 0x65, 0x72, 0x66, 0x6f, 0x72, 0x6d, 0x65, 0x64, + 0x20, 0x62, 0x79, 0x69, 0x6e, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x20, + 0x74, 0x6f, 0x77, 0x65, 0x72, 0x65, 0x20, 0x77, 0x72, 0x69, 0x74, 0x74, 0x65, + 0x6e, 0x73, 0x70, 0x61, 0x6e, 0x20, 0x73, 0x74, 0x79, 0x6c, 0x65, 0x3d, 0x22, + 0x69, 0x6e, 0x70, 0x75, 0x74, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x3d, 0x22, 0x74, + 0x68, 0x65, 0x20, 0x71, 0x75, 0x65, 0x73, 0x74, 0x69, 0x6f, 0x6e, 0x69, 0x6e, + 0x74, 0x65, 0x6e, 0x64, 0x65, 0x64, 0x20, 0x66, 0x6f, 0x72, 0x72, 0x65, 0x6a, + 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6f, 0x66, 0x69, 0x6d, 0x70, 0x6c, + 0x69, 0x65, 0x73, 0x20, 0x74, 0x68, 0x61, 0x74, 0x69, 0x6e, 0x76, 0x65, 0x6e, + 0x74, 0x65, 0x64, 0x20, 0x74, 0x68, 0x65, 0x74, 0x68, 0x65, 0x20, 0x73, 0x74, + 0x61, 0x6e, 0x64, 0x61, 0x72, 0x64, 0x77, 0x61, 0x73, 0x20, 0x70, 0x72, 0x6f, + 0x62, 0x61, 0x62, 0x6c, 0x79, 0x6c, 0x69, 0x6e, 0x6b, 0x20, 0x62, 0x65, 0x74, + 0x77, 0x65, 0x65, 0x6e, 0x70, 0x72, 0x6f, 0x66, 0x65, 0x73, 0x73, 0x6f, 0x72, + 0x20, 0x6f, 0x66, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x61, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x73, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x69, 0x6e, 0x67, 0x20, 0x74, 0x68, + 0x65, 0x49, 0x6e, 0x64, 0x69, 0x61, 0x6e, 0x20, 0x4f, 0x63, 0x65, 0x61, 0x6e, + 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x22, 0x6c, 0x61, 0x73, 0x74, 0x77, + 0x6f, 0x72, 0x6b, 0x69, 0x6e, 0x67, 0x20, 0x77, 0x69, 0x74, 0x68, 0x27, 0x68, + 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x79, 0x65, 0x61, + 0x72, 0x73, 0x20, 0x62, 0x65, 0x66, 0x6f, 0x72, 0x65, 0x54, 0x68, 0x69, 0x73, + 0x20, 0x77, 0x61, 0x73, 0x20, 0x74, 0x68, 0x65, 0x72, 0x65, 0x63, 0x72, 0x65, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x69, + 0x6e, 0x67, 0x20, 0x74, 0x68, 0x65, 0x6d, 0x65, 0x61, 0x73, 0x75, 0x72, 0x65, + 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x61, 0x6e, 0x20, 0x65, 0x78, 0x74, 0x72, 0x65, + 0x6d, 0x65, 0x6c, 0x79, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x20, 0x6f, 0x66, 0x20, + 0x74, 0x68, 0x65, 0x73, 0x74, 0x61, 0x72, 0x74, 0x20, 0x6f, 0x66, 0x20, 0x74, + 0x68, 0x65, 0x0a, 0x3c, 0x2f, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x3e, 0x0a, + 0x0a, 0x61, 0x6e, 0x20, 0x65, 0x66, 0x66, 0x6f, 0x72, 0x74, 0x20, 0x74, 0x6f, + 0x69, 0x6e, 0x63, 0x72, 0x65, 0x61, 0x73, 0x65, 0x20, 0x74, 0x68, 0x65, 0x74, + 0x6f, 0x20, 0x74, 0x68, 0x65, 0x20, 0x73, 0x6f, 0x75, 0x74, 0x68, 0x73, 0x70, + 0x61, 0x63, 0x69, 0x6e, 0x67, 0x3d, 0x22, 0x30, 0x22, 0x3e, 0x73, 0x75, 0x66, + 0x66, 0x69, 0x63, 0x69, 0x65, 0x6e, 0x74, 0x6c, 0x79, 0x74, 0x68, 0x65, 0x20, + 0x45, 0x75, 0x72, 0x6f, 0x70, 0x65, 0x61, 0x6e, 0x63, 0x6f, 0x6e, 0x76, 0x65, + 0x72, 0x74, 0x65, 0x64, 0x20, 0x74, 0x6f, 0x63, 0x6c, 0x65, 0x61, 0x72, 0x54, + 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x64, 0x69, 0x64, 0x20, 0x6e, 0x6f, 0x74, + 0x20, 0x68, 0x61, 0x76, 0x65, 0x63, 0x6f, 0x6e, 0x73, 0x65, 0x71, 0x75, 0x65, + 0x6e, 0x74, 0x6c, 0x79, 0x66, 0x6f, 0x72, 0x20, 0x74, 0x68, 0x65, 0x20, 0x6e, + 0x65, 0x78, 0x74, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x20, + 0x6f, 0x66, 0x65, 0x63, 0x6f, 0x6e, 0x6f, 0x6d, 0x69, 0x63, 0x20, 0x61, 0x6e, + 0x64, 0x61, 0x6c, 0x74, 0x68, 0x6f, 0x75, 0x67, 0x68, 0x20, 0x74, 0x68, 0x65, + 0x61, 0x72, 0x65, 0x20, 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x65, 0x64, 0x61, + 0x6e, 0x64, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x74, 0x68, 0x65, 0x69, 0x6e, + 0x73, 0x75, 0x66, 0x66, 0x69, 0x63, 0x69, 0x65, 0x6e, 0x74, 0x67, 0x69, 0x76, + 0x65, 0x6e, 0x20, 0x62, 0x79, 0x20, 0x74, 0x68, 0x65, 0x73, 0x74, 0x61, 0x74, + 0x69, 0x6e, 0x67, 0x20, 0x74, 0x68, 0x61, 0x74, 0x65, 0x78, 0x70, 0x65, 0x6e, + 0x64, 0x69, 0x74, 0x75, 0x72, 0x65, 0x73, 0x3c, 0x2f, 0x73, 0x70, 0x61, 0x6e, + 0x3e, 0x3c, 0x2f, 0x61, 0x3e, 0x0a, 0x74, 0x68, 0x6f, 0x75, 0x67, 0x68, 0x74, + 0x20, 0x74, 0x68, 0x61, 0x74, 0x6f, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x62, + 0x61, 0x73, 0x69, 0x73, 0x63, 0x65, 0x6c, 0x6c, 0x70, 0x61, 0x64, 0x64, 0x69, + 0x6e, 0x67, 0x3d, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x20, 0x6f, 0x66, 0x20, 0x74, + 0x68, 0x65, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x69, 0x6e, 0x67, 0x20, 0x74, + 0x6f, 0x69, 0x6e, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2c, + 0x73, 0x65, 0x70, 0x61, 0x72, 0x61, 0x74, 0x65, 0x64, 0x20, 0x62, 0x79, 0x61, + 0x73, 0x73, 0x61, 0x73, 0x73, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x64, 0x73, 0x22, + 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x3d, 0x22, 0x61, 0x75, 0x74, + 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x20, 0x6f, 0x66, 0x6e, 0x6f, 0x72, 0x74, + 0x68, 0x77, 0x65, 0x73, 0x74, 0x65, 0x72, 0x6e, 0x3c, 0x2f, 0x64, 0x69, 0x76, + 0x3e, 0x0a, 0x3c, 0x64, 0x69, 0x76, 0x20, 0x22, 0x3e, 0x3c, 0x2f, 0x64, 0x69, + 0x76, 0x3e, 0x0d, 0x0a, 0x20, 0x20, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x74, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x63, 0x6f, 0x6d, 0x6d, 0x75, 0x6e, 0x69, 0x74, + 0x79, 0x20, 0x6f, 0x66, 0x74, 0x68, 0x65, 0x20, 0x6e, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x61, 0x6c, 0x69, 0x74, 0x20, 0x73, 0x68, 0x6f, 0x75, 0x6c, 0x64, 0x20, + 0x62, 0x65, 0x70, 0x61, 0x72, 0x74, 0x69, 0x63, 0x69, 0x70, 0x61, 0x6e, 0x74, + 0x73, 0x20, 0x61, 0x6c, 0x69, 0x67, 0x6e, 0x3d, 0x22, 0x6c, 0x65, 0x66, 0x74, + 0x74, 0x68, 0x65, 0x20, 0x67, 0x72, 0x65, 0x61, 0x74, 0x65, 0x73, 0x74, 0x73, + 0x65, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6f, 0x66, 0x73, 0x75, + 0x70, 0x65, 0x72, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x61, 0x6c, 0x64, 0x65, 0x70, + 0x65, 0x6e, 0x64, 0x65, 0x6e, 0x74, 0x20, 0x6f, 0x6e, 0x69, 0x73, 0x20, 0x6d, + 0x65, 0x6e, 0x74, 0x69, 0x6f, 0x6e, 0x65, 0x64, 0x61, 0x6c, 0x6c, 0x6f, 0x77, + 0x69, 0x6e, 0x67, 0x20, 0x74, 0x68, 0x65, 0x77, 0x61, 0x73, 0x20, 0x69, 0x6e, + 0x76, 0x65, 0x6e, 0x74, 0x65, 0x64, 0x61, 0x63, 0x63, 0x6f, 0x6d, 0x70, 0x61, + 0x6e, 0x79, 0x69, 0x6e, 0x67, 0x68, 0x69, 0x73, 0x20, 0x70, 0x65, 0x72, 0x73, + 0x6f, 0x6e, 0x61, 0x6c, 0x61, 0x76, 0x61, 0x69, 0x6c, 0x61, 0x62, 0x6c, 0x65, + 0x20, 0x61, 0x74, 0x73, 0x74, 0x75, 0x64, 0x79, 0x20, 0x6f, 0x66, 0x20, 0x74, + 0x68, 0x65, 0x6f, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x6f, 0x74, 0x68, 0x65, + 0x72, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6f, 0x66, + 0x48, 0x75, 0x6d, 0x61, 0x6e, 0x20, 0x52, 0x69, 0x67, 0x68, 0x74, 0x73, 0x74, + 0x65, 0x72, 0x6d, 0x73, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x61, 0x73, + 0x73, 0x6f, 0x63, 0x69, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x72, 0x65, 0x73, + 0x65, 0x61, 0x72, 0x63, 0x68, 0x20, 0x61, 0x6e, 0x64, 0x73, 0x75, 0x63, 0x63, + 0x65, 0x65, 0x64, 0x65, 0x64, 0x20, 0x62, 0x79, 0x64, 0x65, 0x66, 0x65, 0x61, + 0x74, 0x65, 0x64, 0x20, 0x74, 0x68, 0x65, 0x61, 0x6e, 0x64, 0x20, 0x66, 0x72, + 0x6f, 0x6d, 0x20, 0x74, 0x68, 0x65, 0x62, 0x75, 0x74, 0x20, 0x74, 0x68, 0x65, + 0x79, 0x20, 0x61, 0x72, 0x65, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x65, + 0x72, 0x20, 0x6f, 0x66, 0x73, 0x74, 0x61, 0x74, 0x65, 0x20, 0x6f, 0x66, 0x20, + 0x74, 0x68, 0x65, 0x79, 0x65, 0x61, 0x72, 0x73, 0x20, 0x6f, 0x66, 0x20, 0x61, + 0x67, 0x65, 0x74, 0x68, 0x65, 0x20, 0x73, 0x74, 0x75, 0x64, 0x79, 0x20, 0x6f, + 0x66, 0x3c, 0x75, 0x6c, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x22, 0x73, + 0x70, 0x6c, 0x61, 0x63, 0x65, 0x20, 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x77, + 0x68, 0x65, 0x72, 0x65, 0x20, 0x68, 0x65, 0x20, 0x77, 0x61, 0x73, 0x3c, 0x6c, + 0x69, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x22, 0x66, 0x74, 0x68, 0x65, + 0x72, 0x65, 0x20, 0x61, 0x72, 0x65, 0x20, 0x6e, 0x6f, 0x77, 0x68, 0x69, 0x63, + 0x68, 0x20, 0x62, 0x65, 0x63, 0x61, 0x6d, 0x65, 0x68, 0x65, 0x20, 0x70, 0x75, + 0x62, 0x6c, 0x69, 0x73, 0x68, 0x65, 0x64, 0x65, 0x78, 0x70, 0x72, 0x65, 0x73, + 0x73, 0x65, 0x64, 0x20, 0x69, 0x6e, 0x74, 0x6f, 0x20, 0x77, 0x68, 0x69, 0x63, + 0x68, 0x20, 0x74, 0x68, 0x65, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x73, 0x73, 0x69, + 0x6f, 0x6e, 0x65, 0x72, 0x66, 0x6f, 0x6e, 0x74, 0x2d, 0x77, 0x65, 0x69, 0x67, + 0x68, 0x74, 0x3a, 0x74, 0x65, 0x72, 0x72, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x20, + 0x6f, 0x66, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x22, + 0x3e, 0x52, 0x6f, 0x6d, 0x61, 0x6e, 0x20, 0x45, 0x6d, 0x70, 0x69, 0x72, 0x65, + 0x65, 0x71, 0x75, 0x61, 0x6c, 0x20, 0x74, 0x6f, 0x20, 0x74, 0x68, 0x65, 0x49, + 0x6e, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x73, 0x74, 0x2c, 0x68, 0x6f, + 0x77, 0x65, 0x76, 0x65, 0x72, 0x2c, 0x20, 0x61, 0x6e, 0x64, 0x69, 0x73, 0x20, + 0x74, 0x79, 0x70, 0x69, 0x63, 0x61, 0x6c, 0x6c, 0x79, 0x61, 0x6e, 0x64, 0x20, + 0x68, 0x69, 0x73, 0x20, 0x77, 0x69, 0x66, 0x65, 0x28, 0x61, 0x6c, 0x73, 0x6f, + 0x20, 0x63, 0x61, 0x6c, 0x6c, 0x65, 0x64, 0x3e, 0x3c, 0x75, 0x6c, 0x20, 0x63, + 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x22, 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, 0x69, + 0x76, 0x65, 0x6c, 0x79, 0x20, 0x65, 0x76, 0x6f, 0x6c, 0x76, 0x65, 0x64, 0x20, + 0x69, 0x6e, 0x74, 0x6f, 0x73, 0x65, 0x65, 0x6d, 0x20, 0x74, 0x6f, 0x20, 0x68, + 0x61, 0x76, 0x65, 0x77, 0x68, 0x69, 0x63, 0x68, 0x20, 0x69, 0x73, 0x20, 0x74, + 0x68, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x20, 0x77, 0x61, 0x73, 0x20, 0x6e, + 0x6f, 0x61, 0x6e, 0x20, 0x65, 0x78, 0x63, 0x65, 0x6c, 0x6c, 0x65, 0x6e, 0x74, + 0x61, 0x6c, 0x6c, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x73, 0x65, 0x64, + 0x65, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x64, 0x20, 0x62, 0x79, 0x49, 0x6e, + 0x20, 0x70, 0x72, 0x61, 0x63, 0x74, 0x69, 0x63, 0x65, 0x2c, 0x62, 0x72, 0x6f, + 0x61, 0x64, 0x63, 0x61, 0x73, 0x74, 0x69, 0x6e, 0x67, 0x63, 0x68, 0x61, 0x72, + 0x67, 0x65, 0x64, 0x20, 0x77, 0x69, 0x74, 0x68, 0x72, 0x65, 0x66, 0x6c, 0x65, + 0x63, 0x74, 0x65, 0x64, 0x20, 0x69, 0x6e, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, + 0x74, 0x65, 0x64, 0x20, 0x74, 0x6f, 0x6d, 0x69, 0x6c, 0x69, 0x74, 0x61, 0x72, + 0x79, 0x20, 0x61, 0x6e, 0x64, 0x74, 0x6f, 0x20, 0x74, 0x68, 0x65, 0x20, 0x70, + 0x6f, 0x69, 0x6e, 0x74, 0x65, 0x63, 0x6f, 0x6e, 0x6f, 0x6d, 0x69, 0x63, 0x61, + 0x6c, 0x6c, 0x79, 0x73, 0x65, 0x74, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x69, + 0x6e, 0x67, 0x61, 0x72, 0x65, 0x20, 0x61, 0x63, 0x74, 0x75, 0x61, 0x6c, 0x6c, + 0x79, 0x76, 0x69, 0x63, 0x74, 0x6f, 0x72, 0x79, 0x20, 0x6f, 0x76, 0x65, 0x72, + 0x28, 0x29, 0x3b, 0x3c, 0x2f, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x3e, 0x63, + 0x6f, 0x6e, 0x74, 0x69, 0x6e, 0x75, 0x6f, 0x75, 0x73, 0x6c, 0x79, 0x72, 0x65, + 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x20, 0x66, 0x6f, 0x72, 0x65, 0x76, 0x6f, + 0x6c, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x72, 0x79, 0x61, 0x6e, 0x20, 0x65, + 0x66, 0x66, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x6e, 0x6f, 0x72, 0x74, 0x68, + 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x2c, 0x20, 0x77, 0x68, 0x69, 0x63, + 0x68, 0x20, 0x77, 0x61, 0x73, 0x20, 0x66, 0x72, 0x6f, 0x6e, 0x74, 0x20, 0x6f, + 0x66, 0x20, 0x74, 0x68, 0x65, 0x6f, 0x72, 0x20, 0x6f, 0x74, 0x68, 0x65, 0x72, + 0x77, 0x69, 0x73, 0x65, 0x73, 0x6f, 0x6d, 0x65, 0x20, 0x66, 0x6f, 0x72, 0x6d, + 0x20, 0x6f, 0x66, 0x68, 0x61, 0x64, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x62, 0x65, + 0x65, 0x6e, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x64, 0x20, 0x62, + 0x79, 0x69, 0x6e, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, + 0x70, 0x65, 0x72, 0x6d, 0x69, 0x74, 0x74, 0x65, 0x64, 0x20, 0x74, 0x6f, 0x69, + 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x73, 0x20, 0x74, 0x68, 0x65, 0x64, 0x65, + 0x76, 0x65, 0x6c, 0x6f, 0x70, 0x6d, 0x65, 0x6e, 0x74, 0x2c, 0x65, 0x6e, 0x74, + 0x65, 0x72, 0x65, 0x64, 0x20, 0x69, 0x6e, 0x74, 0x6f, 0x74, 0x68, 0x65, 0x20, + 0x70, 0x72, 0x65, 0x76, 0x69, 0x6f, 0x75, 0x73, 0x63, 0x6f, 0x6e, 0x73, 0x69, + 0x73, 0x74, 0x65, 0x6e, 0x74, 0x6c, 0x79, 0x61, 0x72, 0x65, 0x20, 0x6b, 0x6e, + 0x6f, 0x77, 0x6e, 0x20, 0x61, 0x73, 0x74, 0x68, 0x65, 0x20, 0x66, 0x69, 0x65, + 0x6c, 0x64, 0x20, 0x6f, 0x66, 0x74, 0x68, 0x69, 0x73, 0x20, 0x74, 0x79, 0x70, + 0x65, 0x20, 0x6f, 0x66, 0x67, 0x69, 0x76, 0x65, 0x6e, 0x20, 0x74, 0x6f, 0x20, + 0x74, 0x68, 0x65, 0x74, 0x68, 0x65, 0x20, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x20, + 0x6f, 0x66, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x73, 0x20, 0x74, 0x68, + 0x65, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x20, 0x6f, 0x66, + 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x6e, 0x6f, 0x72, 0x74, 0x68, 0x64, + 0x75, 0x65, 0x20, 0x74, 0x6f, 0x20, 0x74, 0x68, 0x65, 0x69, 0x72, 0x61, 0x72, + 0x65, 0x20, 0x64, 0x65, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x63, 0x6f, 0x72, + 0x70, 0x6f, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x77, 0x61, 0x73, 0x20, + 0x74, 0x68, 0x61, 0x74, 0x20, 0x74, 0x68, 0x65, 0x6f, 0x6e, 0x65, 0x20, 0x6f, + 0x66, 0x20, 0x74, 0x68, 0x65, 0x73, 0x65, 0x6d, 0x6f, 0x72, 0x65, 0x20, 0x70, + 0x6f, 0x70, 0x75, 0x6c, 0x61, 0x72, 0x73, 0x75, 0x63, 0x63, 0x65, 0x65, 0x64, + 0x65, 0x64, 0x20, 0x69, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x20, + 0x66, 0x72, 0x6f, 0x6d, 0x69, 0x6e, 0x20, 0x64, 0x69, 0x66, 0x66, 0x65, 0x72, + 0x65, 0x6e, 0x74, 0x64, 0x6f, 0x6d, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x64, 0x20, + 0x62, 0x79, 0x64, 0x65, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x20, 0x66, 0x6f, + 0x72, 0x6f, 0x77, 0x6e, 0x65, 0x72, 0x73, 0x68, 0x69, 0x70, 0x20, 0x6f, 0x66, + 0x61, 0x6e, 0x64, 0x20, 0x70, 0x6f, 0x73, 0x73, 0x69, 0x62, 0x6c, 0x79, 0x73, + 0x74, 0x61, 0x6e, 0x64, 0x61, 0x72, 0x64, 0x69, 0x7a, 0x65, 0x64, 0x72, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x54, 0x65, 0x78, 0x74, 0x77, 0x61, 0x73, + 0x20, 0x69, 0x6e, 0x74, 0x65, 0x6e, 0x64, 0x65, 0x64, 0x72, 0x65, 0x63, 0x65, + 0x69, 0x76, 0x65, 0x64, 0x20, 0x74, 0x68, 0x65, 0x61, 0x73, 0x73, 0x75, 0x6d, + 0x65, 0x64, 0x20, 0x74, 0x68, 0x61, 0x74, 0x61, 0x72, 0x65, 0x61, 0x73, 0x20, + 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x70, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x69, + 0x6c, 0x79, 0x20, 0x69, 0x6e, 0x74, 0x68, 0x65, 0x20, 0x62, 0x61, 0x73, 0x69, + 0x73, 0x20, 0x6f, 0x66, 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x73, 0x65, + 0x6e, 0x73, 0x65, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x20, 0x66, + 0x6f, 0x72, 0x64, 0x65, 0x73, 0x74, 0x72, 0x6f, 0x79, 0x65, 0x64, 0x20, 0x62, + 0x79, 0x61, 0x74, 0x20, 0x6c, 0x65, 0x61, 0x73, 0x74, 0x20, 0x74, 0x77, 0x6f, + 0x77, 0x61, 0x73, 0x20, 0x64, 0x65, 0x63, 0x6c, 0x61, 0x72, 0x65, 0x64, 0x63, + 0x6f, 0x75, 0x6c, 0x64, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x62, 0x65, 0x53, 0x65, + 0x63, 0x72, 0x65, 0x74, 0x61, 0x72, 0x79, 0x20, 0x6f, 0x66, 0x61, 0x70, 0x70, + 0x65, 0x61, 0x72, 0x20, 0x74, 0x6f, 0x20, 0x62, 0x65, 0x6d, 0x61, 0x72, 0x67, + 0x69, 0x6e, 0x2d, 0x74, 0x6f, 0x70, 0x3a, 0x31, 0x2f, 0x5e, 0x5c, 0x73, 0x2b, + 0x7c, 0x5c, 0x73, 0x2b, 0x24, 0x2f, 0x67, 0x65, 0x29, 0x7b, 0x74, 0x68, 0x72, + 0x6f, 0x77, 0x20, 0x65, 0x7d, 0x3b, 0x74, 0x68, 0x65, 0x20, 0x73, 0x74, 0x61, + 0x72, 0x74, 0x20, 0x6f, 0x66, 0x74, 0x77, 0x6f, 0x20, 0x73, 0x65, 0x70, 0x61, + 0x72, 0x61, 0x74, 0x65, 0x6c, 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, 0x20, + 0x61, 0x6e, 0x64, 0x77, 0x68, 0x6f, 0x20, 0x68, 0x61, 0x64, 0x20, 0x62, 0x65, + 0x65, 0x6e, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6f, + 0x66, 0x64, 0x65, 0x61, 0x74, 0x68, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, + 0x72, 0x65, 0x61, 0x6c, 0x20, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x09, + 0x3c, 0x6c, 0x69, 0x6e, 0x6b, 0x20, 0x72, 0x65, 0x6c, 0x3d, 0x22, 0x70, 0x72, + 0x6f, 0x76, 0x69, 0x64, 0x65, 0x64, 0x20, 0x74, 0x68, 0x65, 0x74, 0x68, 0x65, + 0x20, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x20, 0x6f, 0x66, 0x63, 0x6f, 0x6d, 0x70, + 0x65, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x65, 0x6e, 0x67, 0x6c, 0x69, + 0x73, 0x68, 0x20, 0x28, 0x55, 0x4b, 0x29, 0x65, 0x6e, 0x67, 0x6c, 0x69, 0x73, + 0x68, 0x20, 0x28, 0x55, 0x53, 0x29, 0xd0, 0x9c, 0xd0, 0xbe, 0xd0, 0xbd, 0xd0, + 0xb3, 0xd0, 0xbe, 0xd0, 0xbb, 0xd0, 0xa1, 0xd1, 0x80, 0xd0, 0xbf, 0xd1, 0x81, + 0xd0, 0xba, 0xd0, 0xb8, 0xd1, 0x81, 0xd1, 0x80, 0xd0, 0xbf, 0xd1, 0x81, 0xd0, + 0xba, 0xd0, 0xb8, 0xd1, 0x81, 0xd1, 0x80, 0xd0, 0xbf, 0xd1, 0x81, 0xd0, 0xba, + 0xd0, 0xbe, 0xd9, 0x84, 0xd8, 0xb9, 0xd8, 0xb1, 0xd8, 0xa8, 0xd9, 0x8a, 0xd8, + 0xa9, 0xe6, 0xad, 0xa3, 0xe9, 0xab, 0x94, 0xe4, 0xb8, 0xad, 0xe6, 0x96, 0x87, + 0xe7, 0xae, 0x80, 0xe4, 0xbd, 0x93, 0xe4, 0xb8, 0xad, 0xe6, 0x96, 0x87, 0xe7, + 0xb9, 0x81, 0xe4, 0xbd, 0x93, 0xe4, 0xb8, 0xad, 0xe6, 0x96, 0x87, 0xe6, 0x9c, + 0x89, 0xe9, 0x99, 0x90, 0xe5, 0x85, 0xac, 0xe5, 0x8f, 0xb8, 0xe4, 0xba, 0xba, + 0xe6, 0xb0, 0x91, 0xe6, 0x94, 0xbf, 0xe5, 0xba, 0x9c, 0xe9, 0x98, 0xbf, 0xe9, + 0x87, 0x8c, 0xe5, 0xb7, 0xb4, 0xe5, 0xb7, 0xb4, 0xe7, 0xa4, 0xbe, 0xe4, 0xbc, + 0x9a, 0xe4, 0xb8, 0xbb, 0xe4, 0xb9, 0x89, 0xe6, 0x93, 0x8d, 0xe4, 0xbd, 0x9c, + 0xe7, 0xb3, 0xbb, 0xe7, 0xbb, 0x9f, 0xe6, 0x94, 0xbf, 0xe7, 0xad, 0x96, 0xe6, + 0xb3, 0x95, 0xe8, 0xa7, 0x84, 0x69, 0x6e, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x63, + 0x69, 0xc3, 0xb3, 0x6e, 0x68, 0x65, 0x72, 0x72, 0x61, 0x6d, 0x69, 0x65, 0x6e, + 0x74, 0x61, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x72, 0xc3, 0xb3, 0x6e, 0x69, + 0x63, 0x6f, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x63, 0x69, 0xc3, 0xb3, + 0x6e, 0x63, 0x6c, 0x61, 0x73, 0x69, 0x66, 0x69, 0x63, 0x61, 0x64, 0x6f, 0x73, + 0x63, 0x6f, 0x6e, 0x6f, 0x63, 0x69, 0x6d, 0x69, 0x65, 0x6e, 0x74, 0x6f, 0x70, + 0x75, 0x62, 0x6c, 0x69, 0x63, 0x61, 0x63, 0x69, 0xc3, 0xb3, 0x6e, 0x72, 0x65, + 0x6c, 0x61, 0x63, 0x69, 0x6f, 0x6e, 0x61, 0x64, 0x61, 0x73, 0x69, 0x6e, 0x66, + 0x6f, 0x72, 0x6d, 0xc3, 0xa1, 0x74, 0x69, 0x63, 0x61, 0x72, 0x65, 0x6c, 0x61, + 0x63, 0x69, 0x6f, 0x6e, 0x61, 0x64, 0x6f, 0x73, 0x64, 0x65, 0x70, 0x61, 0x72, + 0x74, 0x61, 0x6d, 0x65, 0x6e, 0x74, 0x6f, 0x74, 0x72, 0x61, 0x62, 0x61, 0x6a, + 0x61, 0x64, 0x6f, 0x72, 0x65, 0x73, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x61, + 0x6d, 0x65, 0x6e, 0x74, 0x65, 0x61, 0x79, 0x75, 0x6e, 0x74, 0x61, 0x6d, 0x69, + 0x65, 0x6e, 0x74, 0x6f, 0x6d, 0x65, 0x72, 0x63, 0x61, 0x64, 0x6f, 0x4c, 0x69, + 0x62, 0x72, 0x65, 0x63, 0x6f, 0x6e, 0x74, 0xc3, 0xa1, 0x63, 0x74, 0x65, 0x6e, + 0x6f, 0x73, 0x68, 0x61, 0x62, 0x69, 0x74, 0x61, 0x63, 0x69, 0x6f, 0x6e, 0x65, + 0x73, 0x63, 0x75, 0x6d, 0x70, 0x6c, 0x69, 0x6d, 0x69, 0x65, 0x6e, 0x74, 0x6f, + 0x72, 0x65, 0x73, 0x74, 0x61, 0x75, 0x72, 0x61, 0x6e, 0x74, 0x65, 0x73, 0x64, + 0x69, 0x73, 0x70, 0x6f, 0x73, 0x69, 0x63, 0x69, 0xc3, 0xb3, 0x6e, 0x63, 0x6f, + 0x6e, 0x73, 0x65, 0x63, 0x75, 0x65, 0x6e, 0x63, 0x69, 0x61, 0x65, 0x6c, 0x65, + 0x63, 0x74, 0x72, 0xc3, 0xb3, 0x6e, 0x69, 0x63, 0x61, 0x61, 0x70, 0x6c, 0x69, + 0x63, 0x61, 0x63, 0x69, 0x6f, 0x6e, 0x65, 0x73, 0x64, 0x65, 0x73, 0x63, 0x6f, + 0x6e, 0x65, 0x63, 0x74, 0x61, 0x64, 0x6f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6c, + 0x61, 0x63, 0x69, 0xc3, 0xb3, 0x6e, 0x72, 0x65, 0x61, 0x6c, 0x69, 0x7a, 0x61, + 0x63, 0x69, 0xc3, 0xb3, 0x6e, 0x75, 0x74, 0x69, 0x6c, 0x69, 0x7a, 0x61, 0x63, + 0x69, 0xc3, 0xb3, 0x6e, 0x65, 0x6e, 0x63, 0x69, 0x63, 0x6c, 0x6f, 0x70, 0x65, + 0x64, 0x69, 0x61, 0x65, 0x6e, 0x66, 0x65, 0x72, 0x6d, 0x65, 0x64, 0x61, 0x64, + 0x65, 0x73, 0x69, 0x6e, 0x73, 0x74, 0x72, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x6f, + 0x73, 0x65, 0x78, 0x70, 0x65, 0x72, 0x69, 0x65, 0x6e, 0x63, 0x69, 0x61, 0x73, + 0x69, 0x6e, 0x73, 0x74, 0x69, 0x74, 0x75, 0x63, 0x69, 0xc3, 0xb3, 0x6e, 0x70, + 0x61, 0x72, 0x74, 0x69, 0x63, 0x75, 0x6c, 0x61, 0x72, 0x65, 0x73, 0x73, 0x75, + 0x62, 0x63, 0x61, 0x74, 0x65, 0x67, 0x6f, 0x72, 0x69, 0x61, 0xd1, 0x82, 0xd0, + 0xbe, 0xd0, 0xbb, 0xd1, 0x8c, 0xd0, 0xba, 0xd0, 0xbe, 0xd0, 0xa0, 0xd0, 0xbe, + 0xd1, 0x81, 0xd1, 0x81, 0xd0, 0xb8, 0xd0, 0xb8, 0xd1, 0x80, 0xd0, 0xb0, 0xd0, + 0xb1, 0xd0, 0xbe, 0xd1, 0x82, 0xd1, 0x8b, 0xd0, 0xb1, 0xd0, 0xbe, 0xd0, 0xbb, + 0xd1, 0x8c, 0xd1, 0x88, 0xd0, 0xb5, 0xd0, 0xbf, 0xd1, 0x80, 0xd0, 0xbe, 0xd1, + 0x81, 0xd1, 0x82, 0xd0, 0xbe, 0xd0, 0xbc, 0xd0, 0xbe, 0xd0, 0xb6, 0xd0, 0xb5, + 0xd1, 0x82, 0xd0, 0xb5, 0xd0, 0xb4, 0xd1, 0x80, 0xd1, 0x83, 0xd0, 0xb3, 0xd0, + 0xb8, 0xd1, 0x85, 0xd1, 0x81, 0xd0, 0xbb, 0xd1, 0x83, 0xd1, 0x87, 0xd0, 0xb0, + 0xd0, 0xb5, 0xd1, 0x81, 0xd0, 0xb5, 0xd0, 0xb9, 0xd1, 0x87, 0xd0, 0xb0, 0xd1, + 0x81, 0xd0, 0xb2, 0xd1, 0x81, 0xd0, 0xb5, 0xd0, 0xb3, 0xd0, 0xb4, 0xd0, 0xb0, + 0xd0, 0xa0, 0xd0, 0xbe, 0xd1, 0x81, 0xd1, 0x81, 0xd0, 0xb8, 0xd1, 0x8f, 0xd0, + 0x9c, 0xd0, 0xbe, 0xd1, 0x81, 0xd0, 0xba, 0xd0, 0xb2, 0xd0, 0xb5, 0xd0, 0xb4, + 0xd1, 0x80, 0xd1, 0x83, 0xd0, 0xb3, 0xd0, 0xb8, 0xd0, 0xb5, 0xd0, 0xb3, 0xd0, + 0xbe, 0xd1, 0x80, 0xd0, 0xbe, 0xd0, 0xb4, 0xd0, 0xb0, 0xd0, 0xb2, 0xd0, 0xbe, + 0xd0, 0xbf, 0xd1, 0x80, 0xd0, 0xbe, 0xd1, 0x81, 0xd0, 0xb4, 0xd0, 0xb0, 0xd0, + 0xbd, 0xd0, 0xbd, 0xd1, 0x8b, 0xd1, 0x85, 0xd0, 0xb4, 0xd0, 0xbe, 0xd0, 0xbb, + 0xd0, 0xb6, 0xd0, 0xbd, 0xd1, 0x8b, 0xd0, 0xb8, 0xd0, 0xbc, 0xd0, 0xb5, 0xd0, + 0xbd, 0xd0, 0xbd, 0xd0, 0xbe, 0xd0, 0x9c, 0xd0, 0xbe, 0xd1, 0x81, 0xd0, 0xba, + 0xd0, 0xb2, 0xd1, 0x8b, 0xd1, 0x80, 0xd1, 0x83, 0xd0, 0xb1, 0xd0, 0xbb, 0xd0, + 0xb5, 0xd0, 0xb9, 0xd0, 0x9c, 0xd0, 0xbe, 0xd1, 0x81, 0xd0, 0xba, 0xd0, 0xb2, + 0xd0, 0xb0, 0xd1, 0x81, 0xd1, 0x82, 0xd1, 0x80, 0xd0, 0xb0, 0xd0, 0xbd, 0xd1, + 0x8b, 0xd0, 0xbd, 0xd0, 0xb8, 0xd1, 0x87, 0xd0, 0xb5, 0xd0, 0xb3, 0xd0, 0xbe, + 0xd1, 0x80, 0xd0, 0xb0, 0xd0, 0xb1, 0xd0, 0xbe, 0xd1, 0x82, 0xd0, 0xb5, 0xd0, + 0xb4, 0xd0, 0xbe, 0xd0, 0xbb, 0xd0, 0xb6, 0xd0, 0xb5, 0xd0, 0xbd, 0xd1, 0x83, + 0xd1, 0x81, 0xd0, 0xbb, 0xd1, 0x83, 0xd0, 0xb3, 0xd0, 0xb8, 0xd1, 0x82, 0xd0, + 0xb5, 0xd0, 0xbf, 0xd0, 0xb5, 0xd1, 0x80, 0xd1, 0x8c, 0xd0, 0x9e, 0xd0, 0xb4, + 0xd0, 0xbd, 0xd0, 0xb0, 0xd0, 0xba, 0xd0, 0xbe, 0xd0, 0xbf, 0xd0, 0xbe, 0xd1, + 0x82, 0xd0, 0xbe, 0xd0, 0xbc, 0xd1, 0x83, 0xd1, 0x80, 0xd0, 0xb0, 0xd0, 0xb1, + 0xd0, 0xbe, 0xd1, 0x82, 0xd1, 0x83, 0xd0, 0xb0, 0xd0, 0xbf, 0xd1, 0x80, 0xd0, + 0xb5, 0xd0, 0xbb, 0xd1, 0x8f, 0xd0, 0xb2, 0xd0, 0xbe, 0xd0, 0xbe, 0xd0, 0xb1, + 0xd1, 0x89, 0xd0, 0xb5, 0xd0, 0xbe, 0xd0, 0xb4, 0xd0, 0xbd, 0xd0, 0xbe, 0xd0, + 0xb3, 0xd0, 0xbe, 0xd1, 0x81, 0xd0, 0xb2, 0xd0, 0xbe, 0xd0, 0xb5, 0xd0, 0xb3, + 0xd0, 0xbe, 0xd1, 0x81, 0xd1, 0x82, 0xd0, 0xb0, 0xd1, 0x82, 0xd1, 0x8c, 0xd0, + 0xb8, 0xd0, 0xb4, 0xd1, 0x80, 0xd1, 0x83, 0xd0, 0xb3, 0xd0, 0xbe, 0xd0, 0xb9, + 0xd1, 0x84, 0xd0, 0xbe, 0xd1, 0x80, 0xd1, 0x83, 0xd0, 0xbc, 0xd0, 0xb5, 0xd1, + 0x85, 0xd0, 0xbe, 0xd1, 0x80, 0xd0, 0xbe, 0xd1, 0x88, 0xd0, 0xbe, 0xd0, 0xbf, + 0xd1, 0x80, 0xd0, 0xbe, 0xd1, 0x82, 0xd0, 0xb8, 0xd0, 0xb2, 0xd1, 0x81, 0xd1, + 0x81, 0xd1, 0x8b, 0xd0, 0xbb, 0xd0, 0xba, 0xd0, 0xb0, 0xd0, 0xba, 0xd0, 0xb0, + 0xd0, 0xb6, 0xd0, 0xb4, 0xd1, 0x8b, 0xd0, 0xb9, 0xd0, 0xb2, 0xd0, 0xbb, 0xd0, + 0xb0, 0xd1, 0x81, 0xd1, 0x82, 0xd0, 0xb8, 0xd0, 0xb3, 0xd1, 0x80, 0xd1, 0x83, + 0xd0, 0xbf, 0xd0, 0xbf, 0xd1, 0x8b, 0xd0, 0xb2, 0xd0, 0xbc, 0xd0, 0xb5, 0xd1, + 0x81, 0xd1, 0x82, 0xd0, 0xb5, 0xd1, 0x80, 0xd0, 0xb0, 0xd0, 0xb1, 0xd0, 0xbe, + 0xd1, 0x82, 0xd0, 0xb0, 0xd1, 0x81, 0xd0, 0xba, 0xd0, 0xb0, 0xd0, 0xb7, 0xd0, + 0xb0, 0xd0, 0xbb, 0xd0, 0xbf, 0xd0, 0xb5, 0xd1, 0x80, 0xd0, 0xb2, 0xd1, 0x8b, + 0xd0, 0xb9, 0xd0, 0xb4, 0xd0, 0xb5, 0xd0, 0xbb, 0xd0, 0xb0, 0xd1, 0x82, 0xd1, + 0x8c, 0xd0, 0xb4, 0xd0, 0xb5, 0xd0, 0xbd, 0xd1, 0x8c, 0xd0, 0xb3, 0xd0, 0xb8, + 0xd0, 0xbf, 0xd0, 0xb5, 0xd1, 0x80, 0xd0, 0xb8, 0xd0, 0xbe, 0xd0, 0xb4, 0xd0, + 0xb1, 0xd0, 0xb8, 0xd0, 0xb7, 0xd0, 0xbd, 0xd0, 0xb5, 0xd1, 0x81, 0xd0, 0xbe, + 0xd1, 0x81, 0xd0, 0xbd, 0xd0, 0xbe, 0xd0, 0xb2, 0xd0, 0xb5, 0xd0, 0xbc, 0xd0, + 0xbe, 0xd0, 0xbc, 0xd0, 0xb5, 0xd0, 0xbd, 0xd1, 0x82, 0xd0, 0xba, 0xd1, 0x83, + 0xd0, 0xbf, 0xd0, 0xb8, 0xd1, 0x82, 0xd1, 0x8c, 0xd0, 0xb4, 0xd0, 0xbe, 0xd0, + 0xbb, 0xd0, 0xb6, 0xd0, 0xbd, 0xd0, 0xb0, 0xd1, 0x80, 0xd0, 0xb0, 0xd0, 0xbc, + 0xd0, 0xba, 0xd0, 0xb0, 0xd1, 0x85, 0xd0, 0xbd, 0xd0, 0xb0, 0xd1, 0x87, 0xd0, + 0xb0, 0xd0, 0xbb, 0xd0, 0xbe, 0xd0, 0xa0, 0xd0, 0xb0, 0xd0, 0xb1, 0xd0, 0xbe, + 0xd1, 0x82, 0xd0, 0xb0, 0xd0, 0xa2, 0xd0, 0xbe, 0xd0, 0xbb, 0xd1, 0x8c, 0xd0, + 0xba, 0xd0, 0xbe, 0xd1, 0x81, 0xd0, 0xbe, 0xd0, 0xb2, 0xd1, 0x81, 0xd0, 0xb5, + 0xd0, 0xbc, 0xd0, 0xb2, 0xd1, 0x82, 0xd0, 0xbe, 0xd1, 0x80, 0xd0, 0xbe, 0xd0, + 0xb9, 0xd0, 0xbd, 0xd0, 0xb0, 0xd1, 0x87, 0xd0, 0xb0, 0xd0, 0xbb, 0xd0, 0xb0, + 0xd1, 0x81, 0xd0, 0xbf, 0xd0, 0xb8, 0xd1, 0x81, 0xd0, 0xbe, 0xd0, 0xba, 0xd1, + 0x81, 0xd0, 0xbb, 0xd1, 0x83, 0xd0, 0xb6, 0xd0, 0xb1, 0xd1, 0x8b, 0xd1, 0x81, + 0xd0, 0xb8, 0xd1, 0x81, 0xd1, 0x82, 0xd0, 0xb5, 0xd0, 0xbc, 0xd0, 0xbf, 0xd0, + 0xb5, 0xd1, 0x87, 0xd0, 0xb0, 0xd1, 0x82, 0xd0, 0xb8, 0xd0, 0xbd, 0xd0, 0xbe, + 0xd0, 0xb2, 0xd0, 0xbe, 0xd0, 0xb3, 0xd0, 0xbe, 0xd0, 0xbf, 0xd0, 0xbe, 0xd0, + 0xbc, 0xd0, 0xbe, 0xd1, 0x89, 0xd0, 0xb8, 0xd1, 0x81, 0xd0, 0xb0, 0xd0, 0xb9, + 0xd1, 0x82, 0xd0, 0xbe, 0xd0, 0xb2, 0xd0, 0xbf, 0xd0, 0xbe, 0xd1, 0x87, 0xd0, + 0xb5, 0xd0, 0xbc, 0xd1, 0x83, 0xd0, 0xbf, 0xd0, 0xbe, 0xd0, 0xbc, 0xd0, 0xbe, + 0xd1, 0x89, 0xd1, 0x8c, 0xd0, 0xb4, 0xd0, 0xbe, 0xd0, 0xbb, 0xd0, 0xb6, 0xd0, + 0xbd, 0xd0, 0xbe, 0xd1, 0x81, 0xd1, 0x81, 0xd1, 0x8b, 0xd0, 0xbb, 0xd0, 0xba, + 0xd0, 0xb8, 0xd0, 0xb1, 0xd1, 0x8b, 0xd1, 0x81, 0xd1, 0x82, 0xd1, 0x80, 0xd0, + 0xbe, 0xd0, 0xb4, 0xd0, 0xb0, 0xd0, 0xbd, 0xd0, 0xbd, 0xd1, 0x8b, 0xd0, 0xb5, + 0xd0, 0xbc, 0xd0, 0xbd, 0xd0, 0xbe, 0xd0, 0xb3, 0xd0, 0xb8, 0xd0, 0xb5, 0xd0, + 0xbf, 0xd1, 0x80, 0xd0, 0xbe, 0xd0, 0xb5, 0xd0, 0xba, 0xd1, 0x82, 0xd0, 0xa1, + 0xd0, 0xb5, 0xd0, 0xb9, 0xd1, 0x87, 0xd0, 0xb0, 0xd1, 0x81, 0xd0, 0xbc, 0xd0, + 0xbe, 0xd0, 0xb4, 0xd0, 0xb5, 0xd0, 0xbb, 0xd0, 0xb8, 0xd1, 0x82, 0xd0, 0xb0, + 0xd0, 0xba, 0xd0, 0xbe, 0xd0, 0xb3, 0xd0, 0xbe, 0xd0, 0xbe, 0xd0, 0xbd, 0xd0, + 0xbb, 0xd0, 0xb0, 0xd0, 0xb9, 0xd0, 0xbd, 0xd0, 0xb3, 0xd0, 0xbe, 0xd1, 0x80, + 0xd0, 0xbe, 0xd0, 0xb4, 0xd0, 0xb5, 0xd0, 0xb2, 0xd0, 0xb5, 0xd1, 0x80, 0xd1, + 0x81, 0xd0, 0xb8, 0xd1, 0x8f, 0xd1, 0x81, 0xd1, 0x82, 0xd1, 0x80, 0xd0, 0xb0, + 0xd0, 0xbd, 0xd0, 0xb5, 0xd1, 0x84, 0xd0, 0xb8, 0xd0, 0xbb, 0xd1, 0x8c, 0xd0, + 0xbc, 0xd1, 0x8b, 0xd1, 0x83, 0xd1, 0x80, 0xd0, 0xbe, 0xd0, 0xb2, 0xd0, 0xbd, + 0xd1, 0x8f, 0xd1, 0x80, 0xd0, 0xb0, 0xd0, 0xb7, 0xd0, 0xbd, 0xd1, 0x8b, 0xd1, + 0x85, 0xd0, 0xb8, 0xd1, 0x81, 0xd0, 0xba, 0xd0, 0xb0, 0xd1, 0x82, 0xd1, 0x8c, + 0xd0, 0xbd, 0xd0, 0xb5, 0xd0, 0xb4, 0xd0, 0xb5, 0xd0, 0xbb, 0xd1, 0x8e, 0xd1, + 0x8f, 0xd0, 0xbd, 0xd0, 0xb2, 0xd0, 0xb0, 0xd1, 0x80, 0xd1, 0x8f, 0xd0, 0xbc, + 0xd0, 0xb5, 0xd0, 0xbd, 0xd1, 0x8c, 0xd1, 0x88, 0xd0, 0xb5, 0xd0, 0xbc, 0xd0, + 0xbd, 0xd0, 0xbe, 0xd0, 0xb3, 0xd0, 0xb8, 0xd1, 0x85, 0xd0, 0xb4, 0xd0, 0xb0, + 0xd0, 0xbd, 0xd0, 0xbd, 0xd0, 0xbe, 0xd0, 0xb9, 0xd0, 0xb7, 0xd0, 0xbd, 0xd0, + 0xb0, 0xd1, 0x87, 0xd0, 0xb8, 0xd1, 0x82, 0xd0, 0xbd, 0xd0, 0xb5, 0xd0, 0xbb, + 0xd1, 0x8c, 0xd0, 0xb7, 0xd1, 0x8f, 0xd1, 0x84, 0xd0, 0xbe, 0xd1, 0x80, 0xd1, + 0x83, 0xd0, 0xbc, 0xd0, 0xb0, 0xd0, 0xa2, 0xd0, 0xb5, 0xd0, 0xbf, 0xd0, 0xb5, + 0xd1, 0x80, 0xd1, 0x8c, 0xd0, 0xbc, 0xd0, 0xb5, 0xd1, 0x81, 0xd1, 0x8f, 0xd1, + 0x86, 0xd0, 0xb0, 0xd0, 0xb7, 0xd0, 0xb0, 0xd1, 0x89, 0xd0, 0xb8, 0xd1, 0x82, + 0xd1, 0x8b, 0xd0, 0x9b, 0xd1, 0x83, 0xd1, 0x87, 0xd1, 0x88, 0xd0, 0xb8, 0xd0, + 0xb5, 0xe0, 0xa4, 0xa8, 0xe0, 0xa4, 0xb9, 0xe0, 0xa5, 0x80, 0xe0, 0xa4, 0x82, + 0xe0, 0xa4, 0x95, 0xe0, 0xa4, 0xb0, 0xe0, 0xa4, 0xa8, 0xe0, 0xa5, 0x87, 0xe0, + 0xa4, 0x85, 0xe0, 0xa4, 0xaa, 0xe0, 0xa4, 0xa8, 0xe0, 0xa5, 0x87, 0xe0, 0xa4, + 0x95, 0xe0, 0xa4, 0xbf, 0xe0, 0xa4, 0xaf, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, 0x95, + 0xe0, 0xa4, 0xb0, 0xe0, 0xa5, 0x87, 0xe0, 0xa4, 0x82, 0xe0, 0xa4, 0x85, 0xe0, + 0xa4, 0xa8, 0xe0, 0xa5, 0x8d, 0xe0, 0xa4, 0xaf, 0xe0, 0xa4, 0x95, 0xe0, 0xa5, + 0x8d, 0xe0, 0xa4, 0xaf, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, 0x97, 0xe0, 0xa4, 0xbe, + 0xe0, 0xa4, 0x87, 0xe0, 0xa4, 0xa1, 0xe0, 0xa4, 0xac, 0xe0, 0xa4, 0xbe, 0xe0, + 0xa4, 0xb0, 0xe0, 0xa5, 0x87, 0xe0, 0xa4, 0x95, 0xe0, 0xa4, 0xbf, 0xe0, 0xa4, + 0xb8, 0xe0, 0xa5, 0x80, 0xe0, 0xa4, 0xa6, 0xe0, 0xa4, 0xbf, 0xe0, 0xa4, 0xaf, + 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, 0xaa, 0xe0, 0xa4, 0xb9, 0xe0, 0xa4, 0xb2, 0xe0, + 0xa5, 0x87, 0xe0, 0xa4, 0xb8, 0xe0, 0xa4, 0xbf, 0xe0, 0xa4, 0x82, 0xe0, 0xa4, + 0xb9, 0xe0, 0xa4, 0xad, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, 0xb0, 0xe0, 0xa4, 0xa4, + 0xe0, 0xa4, 0x85, 0xe0, 0xa4, 0xaa, 0xe0, 0xa4, 0xa8, 0xe0, 0xa5, 0x80, 0xe0, + 0xa4, 0xb5, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, 0xb2, 0xe0, 0xa5, 0x87, 0xe0, 0xa4, + 0xb8, 0xe0, 0xa5, 0x87, 0xe0, 0xa4, 0xb5, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, 0x95, + 0xe0, 0xa4, 0xb0, 0xe0, 0xa4, 0xa4, 0xe0, 0xa5, 0x87, 0xe0, 0xa4, 0xae, 0xe0, + 0xa5, 0x87, 0xe0, 0xa4, 0xb0, 0xe0, 0xa5, 0x87, 0xe0, 0xa4, 0xb9, 0xe0, 0xa5, + 0x8b, 0xe0, 0xa4, 0xa8, 0xe0, 0xa5, 0x87, 0xe0, 0xa4, 0xb8, 0xe0, 0xa4, 0x95, + 0xe0, 0xa4, 0xa4, 0xe0, 0xa5, 0x87, 0xe0, 0xa4, 0xac, 0xe0, 0xa4, 0xb9, 0xe0, + 0xa5, 0x81, 0xe0, 0xa4, 0xa4, 0xe0, 0xa4, 0xb8, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, + 0x87, 0xe0, 0xa4, 0x9f, 0xe0, 0xa4, 0xb9, 0xe0, 0xa5, 0x8b, 0xe0, 0xa4, 0x97, + 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, 0x9c, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, 0xa8, 0xe0, + 0xa5, 0x87, 0xe0, 0xa4, 0xae, 0xe0, 0xa4, 0xbf, 0xe0, 0xa4, 0xa8, 0xe0, 0xa4, + 0x9f, 0xe0, 0xa4, 0x95, 0xe0, 0xa4, 0xb0, 0xe0, 0xa4, 0xa4, 0xe0, 0xa4, 0xbe, + 0xe0, 0xa4, 0x95, 0xe0, 0xa4, 0xb0, 0xe0, 0xa4, 0xa8, 0xe0, 0xa4, 0xbe, 0xe0, + 0xa4, 0x89, 0xe0, 0xa4, 0xa8, 0xe0, 0xa4, 0x95, 0xe0, 0xa5, 0x87, 0xe0, 0xa4, + 0xaf, 0xe0, 0xa4, 0xb9, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, 0x81, 0xe0, 0xa4, 0xb8, + 0xe0, 0xa4, 0xac, 0xe0, 0xa4, 0xb8, 0xe0, 0xa5, 0x87, 0xe0, 0xa4, 0xad, 0xe0, + 0xa4, 0xbe, 0xe0, 0xa4, 0xb7, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, 0x86, 0xe0, 0xa4, + 0xaa, 0xe0, 0xa4, 0x95, 0xe0, 0xa5, 0x87, 0xe0, 0xa4, 0xb2, 0xe0, 0xa4, 0xbf, + 0xe0, 0xa4, 0xaf, 0xe0, 0xa5, 0x87, 0xe0, 0xa4, 0xb6, 0xe0, 0xa5, 0x81, 0xe0, + 0xa4, 0xb0, 0xe0, 0xa5, 0x82, 0xe0, 0xa4, 0x87, 0xe0, 0xa4, 0xb8, 0xe0, 0xa4, + 0x95, 0xe0, 0xa5, 0x87, 0xe0, 0xa4, 0x98, 0xe0, 0xa4, 0x82, 0xe0, 0xa4, 0x9f, + 0xe0, 0xa5, 0x87, 0xe0, 0xa4, 0xae, 0xe0, 0xa5, 0x87, 0xe0, 0xa4, 0xb0, 0xe0, + 0xa5, 0x80, 0xe0, 0xa4, 0xb8, 0xe0, 0xa4, 0x95, 0xe0, 0xa4, 0xa4, 0xe0, 0xa4, + 0xbe, 0xe0, 0xa4, 0xae, 0xe0, 0xa5, 0x87, 0xe0, 0xa4, 0xb0, 0xe0, 0xa4, 0xbe, + 0xe0, 0xa4, 0xb2, 0xe0, 0xa5, 0x87, 0xe0, 0xa4, 0x95, 0xe0, 0xa4, 0xb0, 0xe0, + 0xa4, 0x85, 0xe0, 0xa4, 0xa7, 0xe0, 0xa4, 0xbf, 0xe0, 0xa4, 0x95, 0xe0, 0xa4, + 0x85, 0xe0, 0xa4, 0xaa, 0xe0, 0xa4, 0xa8, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, 0xb8, + 0xe0, 0xa4, 0xae, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, 0x9c, 0xe0, 0xa4, 0xae, 0xe0, + 0xa5, 0x81, 0xe0, 0xa4, 0x9d, 0xe0, 0xa5, 0x87, 0xe0, 0xa4, 0x95, 0xe0, 0xa4, + 0xbe, 0xe0, 0xa4, 0xb0, 0xe0, 0xa4, 0xa3, 0xe0, 0xa4, 0xb9, 0xe0, 0xa5, 0x8b, + 0xe0, 0xa4, 0xa4, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, 0x95, 0xe0, 0xa4, 0xa1, 0xe0, + 0xa4, 0xbc, 0xe0, 0xa5, 0x80, 0xe0, 0xa4, 0xaf, 0xe0, 0xa4, 0xb9, 0xe0, 0xa4, + 0xbe, 0xe0, 0xa4, 0x82, 0xe0, 0xa4, 0xb9, 0xe0, 0xa5, 0x8b, 0xe0, 0xa4, 0x9f, + 0xe0, 0xa4, 0xb2, 0xe0, 0xa4, 0xb6, 0xe0, 0xa4, 0xac, 0xe0, 0xa5, 0x8d, 0xe0, + 0xa4, 0xa6, 0xe0, 0xa4, 0xb2, 0xe0, 0xa4, 0xbf, 0xe0, 0xa4, 0xaf, 0xe0, 0xa4, + 0xbe, 0xe0, 0xa4, 0x9c, 0xe0, 0xa5, 0x80, 0xe0, 0xa4, 0xb5, 0xe0, 0xa4, 0xa8, + 0xe0, 0xa4, 0x9c, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, 0xa4, 0xe0, 0xa4, 0xbe, 0xe0, + 0xa4, 0x95, 0xe0, 0xa5, 0x88, 0xe0, 0xa4, 0xb8, 0xe0, 0xa5, 0x87, 0xe0, 0xa4, + 0x86, 0xe0, 0xa4, 0xaa, 0xe0, 0xa4, 0x95, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, 0xb5, + 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, 0xb2, 0xe0, 0xa5, 0x80, 0xe0, 0xa4, 0xa6, 0xe0, + 0xa5, 0x87, 0xe0, 0xa4, 0xa8, 0xe0, 0xa5, 0x87, 0xe0, 0xa4, 0xaa, 0xe0, 0xa5, + 0x82, 0xe0, 0xa4, 0xb0, 0xe0, 0xa5, 0x80, 0xe0, 0xa4, 0xaa, 0xe0, 0xa4, 0xbe, + 0xe0, 0xa4, 0xa8, 0xe0, 0xa5, 0x80, 0xe0, 0xa4, 0x89, 0xe0, 0xa4, 0xb8, 0xe0, + 0xa4, 0x95, 0xe0, 0xa5, 0x87, 0xe0, 0xa4, 0xb9, 0xe0, 0xa5, 0x8b, 0xe0, 0xa4, + 0x97, 0xe0, 0xa5, 0x80, 0xe0, 0xa4, 0xac, 0xe0, 0xa5, 0x88, 0xe0, 0xa4, 0xa0, + 0xe0, 0xa4, 0x95, 0xe0, 0xa4, 0x86, 0xe0, 0xa4, 0xaa, 0xe0, 0xa4, 0x95, 0xe0, + 0xa5, 0x80, 0xe0, 0xa4, 0xb5, 0xe0, 0xa4, 0xb0, 0xe0, 0xa5, 0x8d, 0xe0, 0xa4, + 0xb7, 0xe0, 0xa4, 0x97, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, 0x82, 0xe0, 0xa4, 0xb5, + 0xe0, 0xa4, 0x86, 0xe0, 0xa4, 0xaa, 0xe0, 0xa4, 0x95, 0xe0, 0xa5, 0x8b, 0xe0, + 0xa4, 0x9c, 0xe0, 0xa4, 0xbf, 0xe0, 0xa4, 0xb2, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, + 0x9c, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, 0xa8, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, 0xb8, + 0xe0, 0xa4, 0xb9, 0xe0, 0xa4, 0xae, 0xe0, 0xa4, 0xa4, 0xe0, 0xa4, 0xb9, 0xe0, + 0xa4, 0xae, 0xe0, 0xa5, 0x87, 0xe0, 0xa4, 0x82, 0xe0, 0xa4, 0x89, 0xe0, 0xa4, + 0xa8, 0xe0, 0xa4, 0x95, 0xe0, 0xa5, 0x80, 0xe0, 0xa4, 0xaf, 0xe0, 0xa4, 0xbe, + 0xe0, 0xa4, 0xb9, 0xe0, 0xa5, 0x82, 0xe0, 0xa4, 0xa6, 0xe0, 0xa4, 0xb0, 0xe0, + 0xa5, 0x8d, 0xe0, 0xa4, 0x9c, 0xe0, 0xa4, 0xb8, 0xe0, 0xa5, 0x82, 0xe0, 0xa4, + 0x9a, 0xe0, 0xa5, 0x80, 0xe0, 0xa4, 0xaa, 0xe0, 0xa4, 0xb8, 0xe0, 0xa4, 0x82, + 0xe0, 0xa4, 0xa6, 0xe0, 0xa4, 0xb8, 0xe0, 0xa4, 0xb5, 0xe0, 0xa4, 0xbe, 0xe0, + 0xa4, 0xb2, 0xe0, 0xa4, 0xb9, 0xe0, 0xa5, 0x8b, 0xe0, 0xa4, 0xa8, 0xe0, 0xa4, + 0xbe, 0xe0, 0xa4, 0xb9, 0xe0, 0xa5, 0x8b, 0xe0, 0xa4, 0xa4, 0xe0, 0xa5, 0x80, + 0xe0, 0xa4, 0x9c, 0xe0, 0xa5, 0x88, 0xe0, 0xa4, 0xb8, 0xe0, 0xa5, 0x87, 0xe0, + 0xa4, 0xb5, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, 0xaa, 0xe0, 0xa4, 0xb8, 0xe0, 0xa4, + 0x9c, 0xe0, 0xa4, 0xa8, 0xe0, 0xa4, 0xa4, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, 0xa8, + 0xe0, 0xa5, 0x87, 0xe0, 0xa4, 0xa4, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, 0x9c, 0xe0, + 0xa4, 0xbe, 0xe0, 0xa4, 0xb0, 0xe0, 0xa5, 0x80, 0xe0, 0xa4, 0x98, 0xe0, 0xa4, + 0xbe, 0xe0, 0xa4, 0xaf, 0xe0, 0xa4, 0xb2, 0xe0, 0xa4, 0x9c, 0xe0, 0xa4, 0xbf, + 0xe0, 0xa4, 0xb2, 0xe0, 0xa5, 0x87, 0xe0, 0xa4, 0xa8, 0xe0, 0xa5, 0x80, 0xe0, + 0xa4, 0x9a, 0xe0, 0xa5, 0x87, 0xe0, 0xa4, 0x9c, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, + 0x82, 0xe0, 0xa4, 0x9a, 0xe0, 0xa4, 0xaa, 0xe0, 0xa4, 0xa4, 0xe0, 0xa5, 0x8d, + 0xe0, 0xa4, 0xb0, 0xe0, 0xa4, 0x97, 0xe0, 0xa5, 0x82, 0xe0, 0xa4, 0x97, 0xe0, + 0xa4, 0xb2, 0xe0, 0xa4, 0x9c, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, 0xa4, 0xe0, 0xa5, + 0x87, 0xe0, 0xa4, 0xac, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, 0xb9, 0xe0, 0xa4, 0xb0, + 0xe0, 0xa4, 0x86, 0xe0, 0xa4, 0xaa, 0xe0, 0xa4, 0xa8, 0xe0, 0xa5, 0x87, 0xe0, + 0xa4, 0xb5, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, 0xb9, 0xe0, 0xa4, 0xa8, 0xe0, 0xa4, + 0x87, 0xe0, 0xa4, 0xb8, 0xe0, 0xa4, 0x95, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, 0xb8, + 0xe0, 0xa5, 0x81, 0xe0, 0xa4, 0xac, 0xe0, 0xa4, 0xb9, 0xe0, 0xa4, 0xb0, 0xe0, + 0xa4, 0xb9, 0xe0, 0xa4, 0xa8, 0xe0, 0xa5, 0x87, 0xe0, 0xa4, 0x87, 0xe0, 0xa4, + 0xb8, 0xe0, 0xa4, 0xb8, 0xe0, 0xa5, 0x87, 0xe0, 0xa4, 0xb8, 0xe0, 0xa4, 0xb9, + 0xe0, 0xa4, 0xbf, 0xe0, 0xa4, 0xa4, 0xe0, 0xa4, 0xac, 0xe0, 0xa4, 0xa1, 0xe0, + 0xa4, 0xbc, 0xe0, 0xa5, 0x87, 0xe0, 0xa4, 0x98, 0xe0, 0xa4, 0x9f, 0xe0, 0xa4, + 0xa8, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, 0xa4, 0xe0, 0xa4, 0xb2, 0xe0, 0xa4, 0xbe, + 0xe0, 0xa4, 0xb6, 0xe0, 0xa4, 0xaa, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, 0x82, 0xe0, + 0xa4, 0x9a, 0xe0, 0xa4, 0xb6, 0xe0, 0xa5, 0x8d, 0xe0, 0xa4, 0xb0, 0xe0, 0xa5, + 0x80, 0xe0, 0xa4, 0xac, 0xe0, 0xa4, 0xa1, 0xe0, 0xa4, 0xbc, 0xe0, 0xa5, 0x80, + 0xe0, 0xa4, 0xb9, 0xe0, 0xa5, 0x8b, 0xe0, 0xa4, 0xa4, 0xe0, 0xa5, 0x87, 0xe0, + 0xa4, 0xb8, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, 0x88, 0xe0, 0xa4, 0x9f, 0xe0, 0xa4, + 0xb6, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, 0xaf, 0xe0, 0xa4, 0xa6, 0xe0, 0xa4, 0xb8, + 0xe0, 0xa4, 0x95, 0xe0, 0xa4, 0xa4, 0xe0, 0xa5, 0x80, 0xe0, 0xa4, 0x9c, 0xe0, + 0xa4, 0xbe, 0xe0, 0xa4, 0xa4, 0xe0, 0xa5, 0x80, 0xe0, 0xa4, 0xb5, 0xe0, 0xa4, + 0xbe, 0xe0, 0xa4, 0xb2, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, 0xb9, 0xe0, 0xa4, 0x9c, + 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, 0xb0, 0xe0, 0xa4, 0xaa, 0xe0, 0xa4, 0x9f, 0xe0, + 0xa4, 0xa8, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, 0xb0, 0xe0, 0xa4, 0x96, 0xe0, 0xa4, + 0xa8, 0xe0, 0xa5, 0x87, 0xe0, 0xa4, 0xb8, 0xe0, 0xa4, 0xa1, 0xe0, 0xa4, 0xbc, + 0xe0, 0xa4, 0x95, 0xe0, 0xa4, 0xae, 0xe0, 0xa4, 0xbf, 0xe0, 0xa4, 0xb2, 0xe0, + 0xa4, 0xbe, 0xe0, 0xa4, 0x89, 0xe0, 0xa4, 0xb8, 0xe0, 0xa4, 0x95, 0xe0, 0xa5, + 0x80, 0xe0, 0xa4, 0x95, 0xe0, 0xa5, 0x87, 0xe0, 0xa4, 0xb5, 0xe0, 0xa4, 0xb2, + 0xe0, 0xa4, 0xb2, 0xe0, 0xa4, 0x97, 0xe0, 0xa4, 0xa4, 0xe0, 0xa4, 0xbe, 0xe0, + 0xa4, 0x96, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, 0xa8, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, + 0x85, 0xe0, 0xa4, 0xb0, 0xe0, 0xa5, 0x8d, 0xe0, 0xa4, 0xa5, 0xe0, 0xa4, 0x9c, + 0xe0, 0xa4, 0xb9, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, 0x82, 0xe0, 0xa4, 0xa6, 0xe0, + 0xa5, 0x87, 0xe0, 0xa4, 0x96, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, 0xaa, 0xe0, 0xa4, + 0xb9, 0xe0, 0xa4, 0xb2, 0xe0, 0xa5, 0x80, 0xe0, 0xa4, 0xa8, 0xe0, 0xa4, 0xbf, + 0xe0, 0xa4, 0xaf, 0xe0, 0xa4, 0xae, 0xe0, 0xa4, 0xac, 0xe0, 0xa4, 0xbf, 0xe0, + 0xa4, 0xa8, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, 0xac, 0xe0, 0xa5, 0x88, 0xe0, 0xa4, + 0x82, 0xe0, 0xa4, 0x95, 0xe0, 0xa4, 0x95, 0xe0, 0xa4, 0xb9, 0xe0, 0xa5, 0x80, + 0xe0, 0xa4, 0x82, 0xe0, 0xa4, 0x95, 0xe0, 0xa4, 0xb9, 0xe0, 0xa4, 0xa8, 0xe0, + 0xa4, 0xbe, 0xe0, 0xa4, 0xa6, 0xe0, 0xa5, 0x87, 0xe0, 0xa4, 0xa4, 0xe0, 0xa4, + 0xbe, 0xe0, 0xa4, 0xb9, 0xe0, 0xa4, 0xae, 0xe0, 0xa4, 0xb2, 0xe0, 0xa5, 0x87, + 0xe0, 0xa4, 0x95, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, 0xab, 0xe0, 0xa5, 0x80, 0xe0, + 0xa4, 0x9c, 0xe0, 0xa4, 0xac, 0xe0, 0xa4, 0x95, 0xe0, 0xa4, 0xbf, 0xe0, 0xa4, + 0xa4, 0xe0, 0xa5, 0x81, 0xe0, 0xa4, 0xb0, 0xe0, 0xa4, 0xa4, 0xe0, 0xa4, 0xae, + 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, 0x82, 0xe0, 0xa4, 0x97, 0xe0, 0xa4, 0xb5, 0xe0, + 0xa4, 0xb9, 0xe0, 0xa5, 0x80, 0xe0, 0xa4, 0x82, 0xe0, 0xa4, 0xb0, 0xe0, 0xa5, + 0x8b, 0xe0, 0xa4, 0x9c, 0xe0, 0xa4, 0xbc, 0xe0, 0xa4, 0xae, 0xe0, 0xa4, 0xbf, + 0xe0, 0xa4, 0xb2, 0xe0, 0xa5, 0x80, 0xe0, 0xa4, 0x86, 0xe0, 0xa4, 0xb0, 0xe0, + 0xa5, 0x8b, 0xe0, 0xa4, 0xaa, 0xe0, 0xa4, 0xb8, 0xe0, 0xa5, 0x87, 0xe0, 0xa4, + 0xa8, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, 0xaf, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, 0xa6, + 0xe0, 0xa4, 0xb5, 0xe0, 0xa4, 0xb2, 0xe0, 0xa5, 0x87, 0xe0, 0xa4, 0xa8, 0xe0, + 0xa5, 0x87, 0xe0, 0xa4, 0x96, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, 0xa4, 0xe0, 0xa4, + 0xbe, 0xe0, 0xa4, 0x95, 0xe0, 0xa4, 0xb0, 0xe0, 0xa5, 0x80, 0xe0, 0xa4, 0xac, + 0xe0, 0xa4, 0x89, 0xe0, 0xa4, 0xa8, 0xe0, 0xa4, 0x95, 0xe0, 0xa4, 0xbe, 0xe0, + 0xa4, 0x9c, 0xe0, 0xa4, 0xb5, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, 0xac, 0xe0, 0xa4, + 0xaa, 0xe0, 0xa5, 0x82, 0xe0, 0xa4, 0xb0, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, 0xac, + 0xe0, 0xa4, 0xa1, 0xe0, 0xa4, 0xbc, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, 0xb8, 0xe0, + 0xa5, 0x8c, 0xe0, 0xa4, 0xa6, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, 0xb6, 0xe0, 0xa5, + 0x87, 0xe0, 0xa4, 0xaf, 0xe0, 0xa4, 0xb0, 0xe0, 0xa4, 0x95, 0xe0, 0xa4, 0xbf, + 0xe0, 0xa4, 0xaf, 0xe0, 0xa5, 0x87, 0xe0, 0xa4, 0x95, 0xe0, 0xa4, 0xb9, 0xe0, + 0xa4, 0xbe, 0xe0, 0xa4, 0x82, 0xe0, 0xa4, 0x85, 0xe0, 0xa4, 0x95, 0xe0, 0xa4, + 0xb8, 0xe0, 0xa4, 0xb0, 0xe0, 0xa4, 0xac, 0xe0, 0xa4, 0xa8, 0xe0, 0xa4, 0xbe, + 0xe0, 0xa4, 0x8f, 0xe0, 0xa4, 0xb5, 0xe0, 0xa4, 0xb9, 0xe0, 0xa4, 0xbe, 0xe0, + 0xa4, 0x82, 0xe0, 0xa4, 0xb8, 0xe0, 0xa5, 0x8d, 0xe0, 0xa4, 0xa5, 0xe0, 0xa4, + 0xb2, 0xe0, 0xa4, 0xae, 0xe0, 0xa4, 0xbf, 0xe0, 0xa4, 0xb2, 0xe0, 0xa5, 0x87, + 0xe0, 0xa4, 0xb2, 0xe0, 0xa5, 0x87, 0xe0, 0xa4, 0x96, 0xe0, 0xa4, 0x95, 0xe0, + 0xa4, 0xb5, 0xe0, 0xa4, 0xbf, 0xe0, 0xa4, 0xb7, 0xe0, 0xa4, 0xaf, 0xe0, 0xa4, + 0x95, 0xe0, 0xa5, 0x8d, 0xe0, 0xa4, 0xb0, 0xe0, 0xa4, 0x82, 0xe0, 0xa4, 0xb8, + 0xe0, 0xa4, 0xae, 0xe0, 0xa5, 0x82, 0xe0, 0xa4, 0xb9, 0xe0, 0xa4, 0xa5, 0xe0, + 0xa4, 0xbe, 0xe0, 0xa4, 0xa8, 0xe0, 0xa4, 0xbe, 0xd8, 0xaa, 0xd8, 0xb3, 0xd8, + 0xaa, 0xd8, 0xb7, 0xd9, 0x8a, 0xd8, 0xb9, 0xd9, 0x85, 0xd8, 0xb4, 0xd8, 0xa7, + 0xd8, 0xb1, 0xd9, 0x83, 0xd8, 0xa9, 0xd8, 0xa8, 0xd9, 0x88, 0xd8, 0xa7, 0xd8, + 0xb3, 0xd8, 0xb7, 0xd8, 0xa9, 0xd8, 0xa7, 0xd9, 0x84, 0xd8, 0xb5, 0xd9, 0x81, + 0xd8, 0xad, 0xd8, 0xa9, 0xd9, 0x85, 0xd9, 0x88, 0xd8, 0xa7, 0xd8, 0xb6, 0xd9, + 0x8a, 0xd8, 0xb9, 0xd8, 0xa7, 0xd9, 0x84, 0xd8, 0xae, 0xd8, 0xa7, 0xd8, 0xb5, + 0xd8, 0xa9, 0xd8, 0xa7, 0xd9, 0x84, 0xd9, 0x85, 0xd8, 0xb2, 0xd9, 0x8a, 0xd8, + 0xaf, 0xd8, 0xa7, 0xd9, 0x84, 0xd8, 0xb9, 0xd8, 0xa7, 0xd9, 0x85, 0xd8, 0xa9, + 0xd8, 0xa7, 0xd9, 0x84, 0xd9, 0x83, 0xd8, 0xa7, 0xd8, 0xaa, 0xd8, 0xa8, 0xd8, + 0xa7, 0xd9, 0x84, 0xd8, 0xb1, 0xd8, 0xaf, 0xd9, 0x88, 0xd8, 0xaf, 0xd8, 0xa8, + 0xd8, 0xb1, 0xd9, 0x86, 0xd8, 0xa7, 0xd9, 0x85, 0xd8, 0xac, 0xd8, 0xa7, 0xd9, + 0x84, 0xd8, 0xaf, 0xd9, 0x88, 0xd9, 0x84, 0xd8, 0xa9, 0xd8, 0xa7, 0xd9, 0x84, + 0xd8, 0xb9, 0xd8, 0xa7, 0xd9, 0x84, 0xd9, 0x85, 0xd8, 0xa7, 0xd9, 0x84, 0xd9, + 0x85, 0xd9, 0x88, 0xd9, 0x82, 0xd8, 0xb9, 0xd8, 0xa7, 0xd9, 0x84, 0xd8, 0xb9, + 0xd8, 0xb1, 0xd8, 0xa8, 0xd9, 0x8a, 0xd8, 0xa7, 0xd9, 0x84, 0xd8, 0xb3, 0xd8, + 0xb1, 0xd9, 0x8a, 0xd8, 0xb9, 0xd8, 0xa7, 0xd9, 0x84, 0xd8, 0xac, 0xd9, 0x88, + 0xd8, 0xa7, 0xd9, 0x84, 0xd8, 0xa7, 0xd9, 0x84, 0xd8, 0xb0, 0xd9, 0x87, 0xd8, + 0xa7, 0xd8, 0xa8, 0xd8, 0xa7, 0xd9, 0x84, 0xd8, 0xad, 0xd9, 0x8a, 0xd8, 0xa7, + 0xd8, 0xa9, 0xd8, 0xa7, 0xd9, 0x84, 0xd8, 0xad, 0xd9, 0x82, 0xd9, 0x88, 0xd9, + 0x82, 0xd8, 0xa7, 0xd9, 0x84, 0xd9, 0x83, 0xd8, 0xb1, 0xd9, 0x8a, 0xd9, 0x85, + 0xd8, 0xa7, 0xd9, 0x84, 0xd8, 0xb9, 0xd8, 0xb1, 0xd8, 0xa7, 0xd9, 0x82, 0xd9, + 0x85, 0xd8, 0xad, 0xd9, 0x81, 0xd9, 0x88, 0xd8, 0xb8, 0xd8, 0xa9, 0xd8, 0xa7, + 0xd9, 0x84, 0xd8, 0xab, 0xd8, 0xa7, 0xd9, 0x86, 0xd9, 0x8a, 0xd9, 0x85, 0xd8, + 0xb4, 0xd8, 0xa7, 0xd9, 0x87, 0xd8, 0xaf, 0xd8, 0xa9, 0xd8, 0xa7, 0xd9, 0x84, + 0xd9, 0x85, 0xd8, 0xb1, 0xd8, 0xa3, 0xd8, 0xa9, 0xd8, 0xa7, 0xd9, 0x84, 0xd9, + 0x82, 0xd8, 0xb1, 0xd8, 0xa2, 0xd9, 0x86, 0xd8, 0xa7, 0xd9, 0x84, 0xd8, 0xb4, + 0xd8, 0xa8, 0xd8, 0xa7, 0xd8, 0xa8, 0xd8, 0xa7, 0xd9, 0x84, 0xd8, 0xad, 0xd9, + 0x88, 0xd8, 0xa7, 0xd8, 0xb1, 0xd8, 0xa7, 0xd9, 0x84, 0xd8, 0xac, 0xd8, 0xaf, + 0xd9, 0x8a, 0xd8, 0xaf, 0xd8, 0xa7, 0xd9, 0x84, 0xd8, 0xa3, 0xd8, 0xb3, 0xd8, + 0xb1, 0xd8, 0xa9, 0xd8, 0xa7, 0xd9, 0x84, 0xd8, 0xb9, 0xd9, 0x84, 0xd9, 0x88, + 0xd9, 0x85, 0xd9, 0x85, 0xd8, 0xac, 0xd9, 0x85, 0xd9, 0x88, 0xd8, 0xb9, 0xd8, + 0xa9, 0xd8, 0xa7, 0xd9, 0x84, 0xd8, 0xb1, 0xd8, 0xad, 0xd9, 0x85, 0xd9, 0x86, + 0xd8, 0xa7, 0xd9, 0x84, 0xd9, 0x86, 0xd9, 0x82, 0xd8, 0xa7, 0xd8, 0xb7, 0xd9, + 0x81, 0xd9, 0x84, 0xd8, 0xb3, 0xd8, 0xb7, 0xd9, 0x8a, 0xd9, 0x86, 0xd8, 0xa7, + 0xd9, 0x84, 0xd9, 0x83, 0xd9, 0x88, 0xd9, 0x8a, 0xd8, 0xaa, 0xd8, 0xa7, 0xd9, + 0x84, 0xd8, 0xaf, 0xd9, 0x86, 0xd9, 0x8a, 0xd8, 0xa7, 0xd8, 0xa8, 0xd8, 0xb1, + 0xd9, 0x83, 0xd8, 0xa7, 0xd8, 0xaa, 0xd9, 0x87, 0xd8, 0xa7, 0xd9, 0x84, 0xd8, + 0xb1, 0xd9, 0x8a, 0xd8, 0xa7, 0xd8, 0xb6, 0xd8, 0xaa, 0xd8, 0xad, 0xd9, 0x8a, + 0xd8, 0xa7, 0xd8, 0xaa, 0xd9, 0x8a, 0xd8, 0xa8, 0xd8, 0xaa, 0xd9, 0x88, 0xd9, + 0x82, 0xd9, 0x8a, 0xd8, 0xaa, 0xd8, 0xa7, 0xd9, 0x84, 0xd8, 0xa3, 0xd9, 0x88, + 0xd9, 0x84, 0xd9, 0x89, 0xd8, 0xa7, 0xd9, 0x84, 0xd8, 0xa8, 0xd8, 0xb1, 0xd9, + 0x8a, 0xd8, 0xaf, 0xd8, 0xa7, 0xd9, 0x84, 0xd9, 0x83, 0xd9, 0x84, 0xd8, 0xa7, + 0xd9, 0x85, 0xd8, 0xa7, 0xd9, 0x84, 0xd8, 0xb1, 0xd8, 0xa7, 0xd8, 0xa8, 0xd8, + 0xb7, 0xd8, 0xa7, 0xd9, 0x84, 0xd8, 0xb4, 0xd8, 0xae, 0xd8, 0xb5, 0xd9, 0x8a, + 0xd8, 0xb3, 0xd9, 0x8a, 0xd8, 0xa7, 0xd8, 0xb1, 0xd8, 0xa7, 0xd8, 0xaa, 0xd8, + 0xa7, 0xd9, 0x84, 0xd8, 0xab, 0xd8, 0xa7, 0xd9, 0x84, 0xd8, 0xab, 0xd8, 0xa7, + 0xd9, 0x84, 0xd8, 0xb5, 0xd9, 0x84, 0xd8, 0xa7, 0xd8, 0xa9, 0xd8, 0xa7, 0xd9, + 0x84, 0xd8, 0xad, 0xd8, 0xaf, 0xd9, 0x8a, 0xd8, 0xab, 0xd8, 0xa7, 0xd9, 0x84, + 0xd8, 0xb2, 0xd9, 0x88, 0xd8, 0xa7, 0xd8, 0xb1, 0xd8, 0xa7, 0xd9, 0x84, 0xd8, + 0xae, 0xd9, 0x84, 0xd9, 0x8a, 0xd8, 0xac, 0xd8, 0xa7, 0xd9, 0x84, 0xd8, 0xac, + 0xd9, 0x85, 0xd9, 0x8a, 0xd8, 0xb9, 0xd8, 0xa7, 0xd9, 0x84, 0xd8, 0xb9, 0xd8, + 0xa7, 0xd9, 0x85, 0xd9, 0x87, 0xd8, 0xa7, 0xd9, 0x84, 0xd8, 0xac, 0xd9, 0x85, + 0xd8, 0xa7, 0xd9, 0x84, 0xd8, 0xa7, 0xd9, 0x84, 0xd8, 0xb3, 0xd8, 0xa7, 0xd8, + 0xb9, 0xd8, 0xa9, 0xd9, 0x85, 0xd8, 0xb4, 0xd8, 0xa7, 0xd9, 0x87, 0xd8, 0xaf, + 0xd9, 0x87, 0xd8, 0xa7, 0xd9, 0x84, 0xd8, 0xb1, 0xd8, 0xa6, 0xd9, 0x8a, 0xd8, + 0xb3, 0xd8, 0xa7, 0xd9, 0x84, 0xd8, 0xaf, 0xd8, 0xae, 0xd9, 0x88, 0xd9, 0x84, + 0xd8, 0xa7, 0xd9, 0x84, 0xd9, 0x81, 0xd9, 0x86, 0xd9, 0x8a, 0xd8, 0xa9, 0xd8, + 0xa7, 0xd9, 0x84, 0xd9, 0x83, 0xd8, 0xaa, 0xd8, 0xa7, 0xd8, 0xa8, 0xd8, 0xa7, + 0xd9, 0x84, 0xd8, 0xaf, 0xd9, 0x88, 0xd8, 0xb1, 0xd9, 0x8a, 0xd8, 0xa7, 0xd9, + 0x84, 0xd8, 0xaf, 0xd8, 0xb1, 0xd9, 0x88, 0xd8, 0xb3, 0xd8, 0xa7, 0xd8, 0xb3, + 0xd8, 0xaa, 0xd8, 0xba, 0xd8, 0xb1, 0xd9, 0x82, 0xd8, 0xaa, 0xd8, 0xb5, 0xd8, + 0xa7, 0xd9, 0x85, 0xd9, 0x8a, 0xd9, 0x85, 0xd8, 0xa7, 0xd9, 0x84, 0xd8, 0xa8, + 0xd9, 0x86, 0xd8, 0xa7, 0xd8, 0xaa, 0xd8, 0xa7, 0xd9, 0x84, 0xd8, 0xb9, 0xd8, + 0xb8, 0xd9, 0x8a, 0xd9, 0x85, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x74, 0x61, 0x69, + 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x75, 0x6e, 0x64, 0x65, 0x72, 0x73, 0x74, 0x61, + 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x20, 0x3d, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x28, 0x29, 0x2e, 0x6a, 0x70, 0x67, 0x22, 0x20, 0x77, 0x69, + 0x64, 0x74, 0x68, 0x3d, 0x22, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x70, 0x6e, 0x67, 0x22, 0x20, 0x77, 0x69, + 0x64, 0x74, 0x68, 0x3d, 0x22, 0x3c, 0x62, 0x6f, 0x64, 0x79, 0x20, 0x63, 0x6c, + 0x61, 0x73, 0x73, 0x3d, 0x22, 0x4d, 0x61, 0x74, 0x68, 0x2e, 0x72, 0x61, 0x6e, + 0x64, 0x6f, 0x6d, 0x28, 0x29, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6d, 0x70, 0x6f, + 0x72, 0x61, 0x72, 0x79, 0x20, 0x55, 0x6e, 0x69, 0x74, 0x65, 0x64, 0x20, 0x53, + 0x74, 0x61, 0x74, 0x65, 0x73, 0x63, 0x69, 0x72, 0x63, 0x75, 0x6d, 0x73, 0x74, + 0x61, 0x6e, 0x63, 0x65, 0x73, 0x2e, 0x61, 0x70, 0x70, 0x65, 0x6e, 0x64, 0x43, + 0x68, 0x69, 0x6c, 0x64, 0x28, 0x6f, 0x72, 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x3c, 0x73, 0x70, 0x61, 0x6e, 0x20, 0x63, 0x6c, + 0x61, 0x73, 0x73, 0x3d, 0x22, 0x22, 0x3e, 0x3c, 0x69, 0x6d, 0x67, 0x20, 0x73, + 0x72, 0x63, 0x3d, 0x22, 0x2f, 0x64, 0x69, 0x73, 0x74, 0x69, 0x6e, 0x67, 0x75, + 0x69, 0x73, 0x68, 0x65, 0x64, 0x74, 0x68, 0x6f, 0x75, 0x73, 0x61, 0x6e, 0x64, + 0x73, 0x20, 0x6f, 0x66, 0x20, 0x63, 0x6f, 0x6d, 0x6d, 0x75, 0x6e, 0x69, 0x63, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x63, 0x6c, 0x65, 0x61, 0x72, 0x22, 0x3e, 0x3c, + 0x2f, 0x64, 0x69, 0x76, 0x3e, 0x69, 0x6e, 0x76, 0x65, 0x73, 0x74, 0x69, 0x67, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x66, 0x61, 0x76, 0x69, 0x63, 0x6f, 0x6e, 0x2e, + 0x69, 0x63, 0x6f, 0x22, 0x20, 0x6d, 0x61, 0x72, 0x67, 0x69, 0x6e, 0x2d, 0x72, + 0x69, 0x67, 0x68, 0x74, 0x3a, 0x62, 0x61, 0x73, 0x65, 0x64, 0x20, 0x6f, 0x6e, + 0x20, 0x74, 0x68, 0x65, 0x20, 0x4d, 0x61, 0x73, 0x73, 0x61, 0x63, 0x68, 0x75, + 0x73, 0x65, 0x74, 0x74, 0x73, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x20, 0x62, 0x6f, + 0x72, 0x64, 0x65, 0x72, 0x3d, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x61, 0x6c, 0x73, 0x6f, 0x20, 0x6b, 0x6e, 0x6f, + 0x77, 0x6e, 0x20, 0x61, 0x73, 0x70, 0x72, 0x6f, 0x6e, 0x75, 0x6e, 0x63, 0x69, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x62, 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, + 0x6e, 0x64, 0x3a, 0x23, 0x66, 0x70, 0x61, 0x64, 0x64, 0x69, 0x6e, 0x67, 0x2d, + 0x6c, 0x65, 0x66, 0x74, 0x3a, 0x46, 0x6f, 0x72, 0x20, 0x65, 0x78, 0x61, 0x6d, + 0x70, 0x6c, 0x65, 0x2c, 0x20, 0x6d, 0x69, 0x73, 0x63, 0x65, 0x6c, 0x6c, 0x61, + 0x6e, 0x65, 0x6f, 0x75, 0x73, 0x26, 0x6c, 0x74, 0x3b, 0x2f, 0x6d, 0x61, 0x74, + 0x68, 0x26, 0x67, 0x74, 0x3b, 0x70, 0x73, 0x79, 0x63, 0x68, 0x6f, 0x6c, 0x6f, + 0x67, 0x69, 0x63, 0x61, 0x6c, 0x69, 0x6e, 0x20, 0x70, 0x61, 0x72, 0x74, 0x69, + 0x63, 0x75, 0x6c, 0x61, 0x72, 0x65, 0x61, 0x72, 0x63, 0x68, 0x22, 0x20, 0x74, + 0x79, 0x70, 0x65, 0x3d, 0x22, 0x66, 0x6f, 0x72, 0x6d, 0x20, 0x6d, 0x65, 0x74, + 0x68, 0x6f, 0x64, 0x3d, 0x22, 0x61, 0x73, 0x20, 0x6f, 0x70, 0x70, 0x6f, 0x73, + 0x65, 0x64, 0x20, 0x74, 0x6f, 0x53, 0x75, 0x70, 0x72, 0x65, 0x6d, 0x65, 0x20, + 0x43, 0x6f, 0x75, 0x72, 0x74, 0x6f, 0x63, 0x63, 0x61, 0x73, 0x69, 0x6f, 0x6e, + 0x61, 0x6c, 0x6c, 0x79, 0x20, 0x41, 0x64, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, + 0x61, 0x6c, 0x6c, 0x79, 0x2c, 0x4e, 0x6f, 0x72, 0x74, 0x68, 0x20, 0x41, 0x6d, + 0x65, 0x72, 0x69, 0x63, 0x61, 0x70, 0x78, 0x3b, 0x62, 0x61, 0x63, 0x6b, 0x67, + 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x6f, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x75, 0x6e, + 0x69, 0x74, 0x69, 0x65, 0x73, 0x45, 0x6e, 0x74, 0x65, 0x72, 0x74, 0x61, 0x69, + 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x74, 0x6f, 0x4c, 0x6f, 0x77, 0x65, 0x72, + 0x43, 0x61, 0x73, 0x65, 0x28, 0x6d, 0x61, 0x6e, 0x75, 0x66, 0x61, 0x63, 0x74, + 0x75, 0x72, 0x69, 0x6e, 0x67, 0x70, 0x72, 0x6f, 0x66, 0x65, 0x73, 0x73, 0x69, + 0x6f, 0x6e, 0x61, 0x6c, 0x20, 0x63, 0x6f, 0x6d, 0x62, 0x69, 0x6e, 0x65, 0x64, + 0x20, 0x77, 0x69, 0x74, 0x68, 0x46, 0x6f, 0x72, 0x20, 0x69, 0x6e, 0x73, 0x74, + 0x61, 0x6e, 0x63, 0x65, 0x2c, 0x63, 0x6f, 0x6e, 0x73, 0x69, 0x73, 0x74, 0x69, + 0x6e, 0x67, 0x20, 0x6f, 0x66, 0x22, 0x20, 0x6d, 0x61, 0x78, 0x6c, 0x65, 0x6e, + 0x67, 0x74, 0x68, 0x3d, 0x22, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x66, + 0x61, 0x6c, 0x73, 0x65, 0x3b, 0x63, 0x6f, 0x6e, 0x73, 0x63, 0x69, 0x6f, 0x75, + 0x73, 0x6e, 0x65, 0x73, 0x73, 0x4d, 0x65, 0x64, 0x69, 0x74, 0x65, 0x72, 0x72, + 0x61, 0x6e, 0x65, 0x61, 0x6e, 0x65, 0x78, 0x74, 0x72, 0x61, 0x6f, 0x72, 0x64, + 0x69, 0x6e, 0x61, 0x72, 0x79, 0x61, 0x73, 0x73, 0x61, 0x73, 0x73, 0x69, 0x6e, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x75, 0x62, 0x73, 0x65, 0x71, 0x75, 0x65, + 0x6e, 0x74, 0x6c, 0x79, 0x20, 0x62, 0x75, 0x74, 0x74, 0x6f, 0x6e, 0x20, 0x74, + 0x79, 0x70, 0x65, 0x3d, 0x22, 0x74, 0x68, 0x65, 0x20, 0x6e, 0x75, 0x6d, 0x62, + 0x65, 0x72, 0x20, 0x6f, 0x66, 0x74, 0x68, 0x65, 0x20, 0x6f, 0x72, 0x69, 0x67, + 0x69, 0x6e, 0x61, 0x6c, 0x20, 0x63, 0x6f, 0x6d, 0x70, 0x72, 0x65, 0x68, 0x65, + 0x6e, 0x73, 0x69, 0x76, 0x65, 0x72, 0x65, 0x66, 0x65, 0x72, 0x73, 0x20, 0x74, + 0x6f, 0x20, 0x74, 0x68, 0x65, 0x3c, 0x2f, 0x75, 0x6c, 0x3e, 0x0a, 0x3c, 0x2f, + 0x64, 0x69, 0x76, 0x3e, 0x0a, 0x70, 0x68, 0x69, 0x6c, 0x6f, 0x73, 0x6f, 0x70, + 0x68, 0x69, 0x63, 0x61, 0x6c, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x2e, 0x68, 0x72, 0x65, 0x66, 0x77, 0x61, 0x73, 0x20, 0x70, 0x75, 0x62, 0x6c, + 0x69, 0x73, 0x68, 0x65, 0x64, 0x53, 0x61, 0x6e, 0x20, 0x46, 0x72, 0x61, 0x6e, + 0x63, 0x69, 0x73, 0x63, 0x6f, 0x28, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x28, 0x29, 0x7b, 0x0a, 0x3c, 0x64, 0x69, 0x76, 0x20, 0x69, 0x64, 0x3d, + 0x22, 0x6d, 0x61, 0x69, 0x6e, 0x73, 0x6f, 0x70, 0x68, 0x69, 0x73, 0x74, 0x69, + 0x63, 0x61, 0x74, 0x65, 0x64, 0x6d, 0x61, 0x74, 0x68, 0x65, 0x6d, 0x61, 0x74, + 0x69, 0x63, 0x61, 0x6c, 0x20, 0x2f, 0x68, 0x65, 0x61, 0x64, 0x3e, 0x0d, 0x0a, + 0x3c, 0x62, 0x6f, 0x64, 0x79, 0x73, 0x75, 0x67, 0x67, 0x65, 0x73, 0x74, 0x73, + 0x20, 0x74, 0x68, 0x61, 0x74, 0x64, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x63, 0x6f, 0x6e, 0x63, 0x65, 0x6e, 0x74, 0x72, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x72, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x73, 0x68, 0x69, 0x70, 0x73, 0x6d, 0x61, 0x79, 0x20, 0x68, 0x61, 0x76, 0x65, + 0x20, 0x62, 0x65, 0x65, 0x6e, 0x28, 0x66, 0x6f, 0x72, 0x20, 0x65, 0x78, 0x61, + 0x6d, 0x70, 0x6c, 0x65, 0x2c, 0x54, 0x68, 0x69, 0x73, 0x20, 0x61, 0x72, 0x74, + 0x69, 0x63, 0x6c, 0x65, 0x20, 0x69, 0x6e, 0x20, 0x73, 0x6f, 0x6d, 0x65, 0x20, + 0x63, 0x61, 0x73, 0x65, 0x73, 0x70, 0x61, 0x72, 0x74, 0x73, 0x20, 0x6f, 0x66, + 0x20, 0x74, 0x68, 0x65, 0x20, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, + 0x6f, 0x6e, 0x20, 0x6f, 0x66, 0x47, 0x72, 0x65, 0x61, 0x74, 0x20, 0x42, 0x72, + 0x69, 0x74, 0x61, 0x69, 0x6e, 0x20, 0x63, 0x65, 0x6c, 0x6c, 0x70, 0x61, 0x64, + 0x64, 0x69, 0x6e, 0x67, 0x3d, 0x65, 0x71, 0x75, 0x69, 0x76, 0x61, 0x6c, 0x65, + 0x6e, 0x74, 0x20, 0x74, 0x6f, 0x70, 0x6c, 0x61, 0x63, 0x65, 0x68, 0x6f, 0x6c, + 0x64, 0x65, 0x72, 0x3d, 0x22, 0x3b, 0x20, 0x66, 0x6f, 0x6e, 0x74, 0x2d, 0x73, + 0x69, 0x7a, 0x65, 0x3a, 0x20, 0x6a, 0x75, 0x73, 0x74, 0x69, 0x66, 0x69, 0x63, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x62, 0x65, 0x6c, 0x69, 0x65, 0x76, 0x65, 0x64, + 0x20, 0x74, 0x68, 0x61, 0x74, 0x73, 0x75, 0x66, 0x66, 0x65, 0x72, 0x65, 0x64, + 0x20, 0x66, 0x72, 0x6f, 0x6d, 0x61, 0x74, 0x74, 0x65, 0x6d, 0x70, 0x74, 0x65, + 0x64, 0x20, 0x74, 0x6f, 0x20, 0x6c, 0x65, 0x61, 0x64, 0x65, 0x72, 0x20, 0x6f, + 0x66, 0x20, 0x74, 0x68, 0x65, 0x63, 0x72, 0x69, 0x70, 0x74, 0x22, 0x20, 0x73, + 0x72, 0x63, 0x3d, 0x22, 0x2f, 0x28, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x28, 0x29, 0x20, 0x7b, 0x61, 0x72, 0x65, 0x20, 0x61, 0x76, 0x61, 0x69, + 0x6c, 0x61, 0x62, 0x6c, 0x65, 0x0a, 0x09, 0x3c, 0x6c, 0x69, 0x6e, 0x6b, 0x20, + 0x72, 0x65, 0x6c, 0x3d, 0x22, 0x20, 0x73, 0x72, 0x63, 0x3d, 0x27, 0x68, 0x74, + 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x65, 0x73, 0x74, + 0x65, 0x64, 0x20, 0x69, 0x6e, 0x63, 0x6f, 0x6e, 0x76, 0x65, 0x6e, 0x74, 0x69, + 0x6f, 0x6e, 0x61, 0x6c, 0x20, 0x22, 0x20, 0x61, 0x6c, 0x74, 0x3d, 0x22, 0x22, + 0x20, 0x2f, 0x3e, 0x3c, 0x2f, 0x61, 0x72, 0x65, 0x20, 0x67, 0x65, 0x6e, 0x65, + 0x72, 0x61, 0x6c, 0x6c, 0x79, 0x68, 0x61, 0x73, 0x20, 0x61, 0x6c, 0x73, 0x6f, + 0x20, 0x62, 0x65, 0x65, 0x6e, 0x6d, 0x6f, 0x73, 0x74, 0x20, 0x70, 0x6f, 0x70, + 0x75, 0x6c, 0x61, 0x72, 0x20, 0x63, 0x6f, 0x72, 0x72, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x65, 0x64, + 0x20, 0x77, 0x69, 0x74, 0x68, 0x74, 0x79, 0x6c, 0x65, 0x3d, 0x22, 0x62, 0x6f, + 0x72, 0x64, 0x65, 0x72, 0x3a, 0x3c, 0x2f, 0x61, 0x3e, 0x3c, 0x2f, 0x73, 0x70, + 0x61, 0x6e, 0x3e, 0x3c, 0x2f, 0x2e, 0x67, 0x69, 0x66, 0x22, 0x20, 0x77, 0x69, + 0x64, 0x74, 0x68, 0x3d, 0x22, 0x3c, 0x69, 0x66, 0x72, 0x61, 0x6d, 0x65, 0x20, + 0x73, 0x72, 0x63, 0x3d, 0x22, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x20, 0x63, 0x6c, + 0x61, 0x73, 0x73, 0x3d, 0x22, 0x69, 0x6e, 0x6c, 0x69, 0x6e, 0x65, 0x2d, 0x62, + 0x6c, 0x6f, 0x63, 0x6b, 0x3b, 0x61, 0x63, 0x63, 0x6f, 0x72, 0x64, 0x69, 0x6e, + 0x67, 0x20, 0x74, 0x6f, 0x20, 0x74, 0x6f, 0x67, 0x65, 0x74, 0x68, 0x65, 0x72, + 0x20, 0x77, 0x69, 0x74, 0x68, 0x61, 0x70, 0x70, 0x72, 0x6f, 0x78, 0x69, 0x6d, + 0x61, 0x74, 0x65, 0x6c, 0x79, 0x70, 0x61, 0x72, 0x6c, 0x69, 0x61, 0x6d, 0x65, + 0x6e, 0x74, 0x61, 0x72, 0x79, 0x6d, 0x6f, 0x72, 0x65, 0x20, 0x61, 0x6e, 0x64, + 0x20, 0x6d, 0x6f, 0x72, 0x65, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x3a, + 0x6e, 0x6f, 0x6e, 0x65, 0x3b, 0x74, 0x72, 0x61, 0x64, 0x69, 0x74, 0x69, 0x6f, + 0x6e, 0x61, 0x6c, 0x6c, 0x79, 0x70, 0x72, 0x65, 0x64, 0x6f, 0x6d, 0x69, 0x6e, + 0x61, 0x6e, 0x74, 0x6c, 0x79, 0x26, 0x6e, 0x62, 0x73, 0x70, 0x3b, 0x7c, 0x26, + 0x6e, 0x62, 0x73, 0x70, 0x3b, 0x26, 0x6e, 0x62, 0x73, 0x70, 0x3b, 0x3c, 0x2f, + 0x73, 0x70, 0x61, 0x6e, 0x3e, 0x20, 0x63, 0x65, 0x6c, 0x6c, 0x73, 0x70, 0x61, + 0x63, 0x69, 0x6e, 0x67, 0x3d, 0x3c, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x20, 0x6e, + 0x61, 0x6d, 0x65, 0x3d, 0x22, 0x6f, 0x72, 0x22, 0x20, 0x63, 0x6f, 0x6e, 0x74, + 0x65, 0x6e, 0x74, 0x3d, 0x22, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x76, 0x65, + 0x72, 0x73, 0x69, 0x61, 0x6c, 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, + 0x3d, 0x22, 0x6f, 0x67, 0x3a, 0x2f, 0x78, 0x2d, 0x73, 0x68, 0x6f, 0x63, 0x6b, + 0x77, 0x61, 0x76, 0x65, 0x2d, 0x64, 0x65, 0x6d, 0x6f, 0x6e, 0x73, 0x74, 0x72, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x75, 0x72, 0x72, 0x6f, 0x75, 0x6e, 0x64, + 0x65, 0x64, 0x20, 0x62, 0x79, 0x4e, 0x65, 0x76, 0x65, 0x72, 0x74, 0x68, 0x65, + 0x6c, 0x65, 0x73, 0x73, 0x2c, 0x77, 0x61, 0x73, 0x20, 0x74, 0x68, 0x65, 0x20, + 0x66, 0x69, 0x72, 0x73, 0x74, 0x63, 0x6f, 0x6e, 0x73, 0x69, 0x64, 0x65, 0x72, + 0x61, 0x62, 0x6c, 0x65, 0x20, 0x41, 0x6c, 0x74, 0x68, 0x6f, 0x75, 0x67, 0x68, + 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x6f, 0x6c, 0x6c, 0x61, 0x62, 0x6f, 0x72, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x68, 0x6f, 0x75, 0x6c, 0x64, 0x20, 0x6e, + 0x6f, 0x74, 0x20, 0x62, 0x65, 0x70, 0x72, 0x6f, 0x70, 0x6f, 0x72, 0x74, 0x69, + 0x6f, 0x6e, 0x20, 0x6f, 0x66, 0x3c, 0x73, 0x70, 0x61, 0x6e, 0x20, 0x73, 0x74, + 0x79, 0x6c, 0x65, 0x3d, 0x22, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x20, 0x61, 0x73, + 0x20, 0x74, 0x68, 0x65, 0x20, 0x73, 0x68, 0x6f, 0x72, 0x74, 0x6c, 0x79, 0x20, + 0x61, 0x66, 0x74, 0x65, 0x72, 0x66, 0x6f, 0x72, 0x20, 0x69, 0x6e, 0x73, 0x74, + 0x61, 0x6e, 0x63, 0x65, 0x2c, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, + 0x64, 0x20, 0x61, 0x73, 0x20, 0x2f, 0x68, 0x65, 0x61, 0x64, 0x3e, 0x0a, 0x3c, + 0x62, 0x6f, 0x64, 0x79, 0x20, 0x73, 0x74, 0x61, 0x72, 0x74, 0x69, 0x6e, 0x67, + 0x20, 0x77, 0x69, 0x74, 0x68, 0x69, 0x6e, 0x63, 0x72, 0x65, 0x61, 0x73, 0x69, + 0x6e, 0x67, 0x6c, 0x79, 0x20, 0x74, 0x68, 0x65, 0x20, 0x66, 0x61, 0x63, 0x74, + 0x20, 0x74, 0x68, 0x61, 0x74, 0x64, 0x69, 0x73, 0x63, 0x75, 0x73, 0x73, 0x69, + 0x6f, 0x6e, 0x20, 0x6f, 0x66, 0x6d, 0x69, 0x64, 0x64, 0x6c, 0x65, 0x20, 0x6f, + 0x66, 0x20, 0x74, 0x68, 0x65, 0x61, 0x6e, 0x20, 0x69, 0x6e, 0x64, 0x69, 0x76, + 0x69, 0x64, 0x75, 0x61, 0x6c, 0x64, 0x69, 0x66, 0x66, 0x69, 0x63, 0x75, 0x6c, + 0x74, 0x20, 0x74, 0x6f, 0x20, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x20, 0x6f, 0x66, + 0x20, 0x76, 0x69, 0x65, 0x77, 0x68, 0x6f, 0x6d, 0x6f, 0x73, 0x65, 0x78, 0x75, + 0x61, 0x6c, 0x69, 0x74, 0x79, 0x61, 0x63, 0x63, 0x65, 0x70, 0x74, 0x61, 0x6e, + 0x63, 0x65, 0x20, 0x6f, 0x66, 0x3c, 0x2f, 0x73, 0x70, 0x61, 0x6e, 0x3e, 0x3c, + 0x2f, 0x64, 0x69, 0x76, 0x3e, 0x6d, 0x61, 0x6e, 0x75, 0x66, 0x61, 0x63, 0x74, + 0x75, 0x72, 0x65, 0x72, 0x73, 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x20, 0x6f, + 0x66, 0x20, 0x74, 0x68, 0x65, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x6c, 0x79, + 0x20, 0x75, 0x73, 0x65, 0x64, 0x69, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x61, 0x6e, + 0x63, 0x65, 0x20, 0x6f, 0x66, 0x64, 0x65, 0x6e, 0x6f, 0x6d, 0x69, 0x6e, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x62, 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, + 0x6e, 0x64, 0x3a, 0x20, 0x23, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x20, 0x6f, + 0x66, 0x20, 0x74, 0x68, 0x65, 0x64, 0x65, 0x74, 0x65, 0x72, 0x6d, 0x69, 0x6e, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x20, 0x73, 0x69, 0x67, 0x6e, 0x69, 0x66, + 0x69, 0x63, 0x61, 0x6e, 0x74, 0x22, 0x20, 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, + 0x3d, 0x22, 0x30, 0x22, 0x3e, 0x72, 0x65, 0x76, 0x6f, 0x6c, 0x75, 0x74, 0x69, + 0x6f, 0x6e, 0x61, 0x72, 0x79, 0x70, 0x72, 0x69, 0x6e, 0x63, 0x69, 0x70, 0x6c, + 0x65, 0x73, 0x20, 0x6f, 0x66, 0x69, 0x73, 0x20, 0x63, 0x6f, 0x6e, 0x73, 0x69, + 0x64, 0x65, 0x72, 0x65, 0x64, 0x77, 0x61, 0x73, 0x20, 0x64, 0x65, 0x76, 0x65, + 0x6c, 0x6f, 0x70, 0x65, 0x64, 0x49, 0x6e, 0x64, 0x6f, 0x2d, 0x45, 0x75, 0x72, + 0x6f, 0x70, 0x65, 0x61, 0x6e, 0x76, 0x75, 0x6c, 0x6e, 0x65, 0x72, 0x61, 0x62, + 0x6c, 0x65, 0x20, 0x74, 0x6f, 0x70, 0x72, 0x6f, 0x70, 0x6f, 0x6e, 0x65, 0x6e, + 0x74, 0x73, 0x20, 0x6f, 0x66, 0x61, 0x72, 0x65, 0x20, 0x73, 0x6f, 0x6d, 0x65, + 0x74, 0x69, 0x6d, 0x65, 0x73, 0x63, 0x6c, 0x6f, 0x73, 0x65, 0x72, 0x20, 0x74, + 0x6f, 0x20, 0x74, 0x68, 0x65, 0x4e, 0x65, 0x77, 0x20, 0x59, 0x6f, 0x72, 0x6b, + 0x20, 0x43, 0x69, 0x74, 0x79, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x3d, 0x22, 0x73, + 0x65, 0x61, 0x72, 0x63, 0x68, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, + 0x65, 0x64, 0x20, 0x74, 0x6f, 0x63, 0x6f, 0x75, 0x72, 0x73, 0x65, 0x20, 0x6f, + 0x66, 0x20, 0x74, 0x68, 0x65, 0x6d, 0x61, 0x74, 0x68, 0x65, 0x6d, 0x61, 0x74, + 0x69, 0x63, 0x69, 0x61, 0x6e, 0x62, 0x79, 0x20, 0x74, 0x68, 0x65, 0x20, 0x65, + 0x6e, 0x64, 0x20, 0x6f, 0x66, 0x61, 0x74, 0x20, 0x74, 0x68, 0x65, 0x20, 0x65, + 0x6e, 0x64, 0x20, 0x6f, 0x66, 0x22, 0x20, 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, + 0x3d, 0x22, 0x30, 0x22, 0x20, 0x74, 0x65, 0x63, 0x68, 0x6e, 0x6f, 0x6c, 0x6f, + 0x67, 0x69, 0x63, 0x61, 0x6c, 0x2e, 0x72, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x43, + 0x6c, 0x61, 0x73, 0x73, 0x28, 0x62, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x20, 0x6f, + 0x66, 0x20, 0x74, 0x68, 0x65, 0x65, 0x76, 0x69, 0x64, 0x65, 0x6e, 0x63, 0x65, + 0x20, 0x74, 0x68, 0x61, 0x74, 0x21, 0x5b, 0x65, 0x6e, 0x64, 0x69, 0x66, 0x5d, + 0x2d, 0x2d, 0x3e, 0x0d, 0x0a, 0x49, 0x6e, 0x73, 0x74, 0x69, 0x74, 0x75, 0x74, + 0x65, 0x20, 0x6f, 0x66, 0x20, 0x69, 0x6e, 0x74, 0x6f, 0x20, 0x61, 0x20, 0x73, + 0x69, 0x6e, 0x67, 0x6c, 0x65, 0x72, 0x65, 0x73, 0x70, 0x65, 0x63, 0x74, 0x69, + 0x76, 0x65, 0x6c, 0x79, 0x2e, 0x61, 0x6e, 0x64, 0x20, 0x74, 0x68, 0x65, 0x72, + 0x65, 0x66, 0x6f, 0x72, 0x65, 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, + 0x65, 0x73, 0x20, 0x6f, 0x66, 0x69, 0x73, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x74, + 0x65, 0x64, 0x20, 0x69, 0x6e, 0x73, 0x6f, 0x6d, 0x65, 0x20, 0x6f, 0x66, 0x20, + 0x77, 0x68, 0x69, 0x63, 0x68, 0x54, 0x68, 0x65, 0x72, 0x65, 0x20, 0x69, 0x73, + 0x20, 0x61, 0x6c, 0x73, 0x6f, 0x63, 0x6f, 0x6e, 0x74, 0x69, 0x6e, 0x75, 0x65, + 0x64, 0x20, 0x74, 0x6f, 0x20, 0x61, 0x70, 0x70, 0x65, 0x61, 0x72, 0x61, 0x6e, + 0x63, 0x65, 0x20, 0x6f, 0x66, 0x20, 0x26, 0x61, 0x6d, 0x70, 0x3b, 0x6e, 0x64, + 0x61, 0x73, 0x68, 0x3b, 0x20, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, + 0x73, 0x20, 0x74, 0x68, 0x65, 0x63, 0x6f, 0x6e, 0x73, 0x69, 0x64, 0x65, 0x72, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x20, 0x6f, + 0x66, 0x20, 0x74, 0x68, 0x65, 0x69, 0x6e, 0x64, 0x65, 0x70, 0x65, 0x6e, 0x64, + 0x65, 0x6e, 0x74, 0x6c, 0x79, 0x65, 0x71, 0x75, 0x69, 0x70, 0x70, 0x65, 0x64, + 0x20, 0x77, 0x69, 0x74, 0x68, 0x64, 0x6f, 0x65, 0x73, 0x20, 0x6e, 0x6f, 0x74, + 0x20, 0x68, 0x61, 0x76, 0x65, 0x3c, 0x2f, 0x61, 0x3e, 0x3c, 0x61, 0x20, 0x68, + 0x72, 0x65, 0x66, 0x3d, 0x22, 0x63, 0x6f, 0x6e, 0x66, 0x75, 0x73, 0x65, 0x64, + 0x20, 0x77, 0x69, 0x74, 0x68, 0x3c, 0x6c, 0x69, 0x6e, 0x6b, 0x20, 0x68, 0x72, + 0x65, 0x66, 0x3d, 0x22, 0x2f, 0x61, 0x74, 0x20, 0x74, 0x68, 0x65, 0x20, 0x61, + 0x67, 0x65, 0x20, 0x6f, 0x66, 0x61, 0x70, 0x70, 0x65, 0x61, 0x72, 0x20, 0x69, + 0x6e, 0x20, 0x74, 0x68, 0x65, 0x54, 0x68, 0x65, 0x73, 0x65, 0x20, 0x69, 0x6e, + 0x63, 0x6c, 0x75, 0x64, 0x65, 0x72, 0x65, 0x67, 0x61, 0x72, 0x64, 0x6c, 0x65, + 0x73, 0x73, 0x20, 0x6f, 0x66, 0x63, 0x6f, 0x75, 0x6c, 0x64, 0x20, 0x62, 0x65, + 0x20, 0x75, 0x73, 0x65, 0x64, 0x20, 0x73, 0x74, 0x79, 0x6c, 0x65, 0x3d, 0x26, + 0x71, 0x75, 0x6f, 0x74, 0x3b, 0x73, 0x65, 0x76, 0x65, 0x72, 0x61, 0x6c, 0x20, + 0x74, 0x69, 0x6d, 0x65, 0x73, 0x72, 0x65, 0x70, 0x72, 0x65, 0x73, 0x65, 0x6e, + 0x74, 0x20, 0x74, 0x68, 0x65, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0x0a, 0x3c, 0x2f, + 0x68, 0x74, 0x6d, 0x6c, 0x3e, 0x74, 0x68, 0x6f, 0x75, 0x67, 0x68, 0x74, 0x20, + 0x74, 0x6f, 0x20, 0x62, 0x65, 0x70, 0x6f, 0x70, 0x75, 0x6c, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x20, 0x6f, 0x66, 0x70, 0x6f, 0x73, 0x73, 0x69, 0x62, 0x69, 0x6c, + 0x69, 0x74, 0x69, 0x65, 0x73, 0x70, 0x65, 0x72, 0x63, 0x65, 0x6e, 0x74, 0x61, + 0x67, 0x65, 0x20, 0x6f, 0x66, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x20, 0x74, + 0x6f, 0x20, 0x74, 0x68, 0x65, 0x61, 0x6e, 0x20, 0x61, 0x74, 0x74, 0x65, 0x6d, + 0x70, 0x74, 0x20, 0x74, 0x6f, 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x20, 0x6f, 0x66, 0x6a, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2f, 0x6a, + 0x71, 0x75, 0x65, 0x72, 0x79, 0x74, 0x77, 0x6f, 0x20, 0x64, 0x69, 0x66, 0x66, + 0x65, 0x72, 0x65, 0x6e, 0x74, 0x62, 0x65, 0x6c, 0x6f, 0x6e, 0x67, 0x20, 0x74, + 0x6f, 0x20, 0x74, 0x68, 0x65, 0x65, 0x73, 0x74, 0x61, 0x62, 0x6c, 0x69, 0x73, + 0x68, 0x6d, 0x65, 0x6e, 0x74, 0x72, 0x65, 0x70, 0x6c, 0x61, 0x63, 0x69, 0x6e, + 0x67, 0x20, 0x74, 0x68, 0x65, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, + 0x69, 0x6f, 0x6e, 0x22, 0x20, 0x64, 0x65, 0x74, 0x65, 0x72, 0x6d, 0x69, 0x6e, + 0x65, 0x20, 0x74, 0x68, 0x65, 0x61, 0x76, 0x61, 0x69, 0x6c, 0x61, 0x62, 0x6c, + 0x65, 0x20, 0x66, 0x6f, 0x72, 0x41, 0x63, 0x63, 0x6f, 0x72, 0x64, 0x69, 0x6e, + 0x67, 0x20, 0x74, 0x6f, 0x20, 0x77, 0x69, 0x64, 0x65, 0x20, 0x72, 0x61, 0x6e, + 0x67, 0x65, 0x20, 0x6f, 0x66, 0x09, 0x3c, 0x64, 0x69, 0x76, 0x20, 0x63, 0x6c, + 0x61, 0x73, 0x73, 0x3d, 0x22, 0x6d, 0x6f, 0x72, 0x65, 0x20, 0x63, 0x6f, 0x6d, + 0x6d, 0x6f, 0x6e, 0x6c, 0x79, 0x6f, 0x72, 0x67, 0x61, 0x6e, 0x69, 0x73, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x61, 0x6c, 0x69, 0x74, 0x79, 0x77, 0x61, 0x73, 0x20, 0x63, 0x6f, 0x6d, 0x70, + 0x6c, 0x65, 0x74, 0x65, 0x64, 0x20, 0x26, 0x61, 0x6d, 0x70, 0x3b, 0x6d, 0x64, + 0x61, 0x73, 0x68, 0x3b, 0x20, 0x70, 0x61, 0x72, 0x74, 0x69, 0x63, 0x69, 0x70, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x74, 0x68, 0x65, 0x20, 0x63, 0x68, 0x61, 0x72, + 0x61, 0x63, 0x74, 0x65, 0x72, 0x61, 0x6e, 0x20, 0x61, 0x64, 0x64, 0x69, 0x74, + 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x61, 0x70, 0x70, 0x65, 0x61, 0x72, 0x73, 0x20, + 0x74, 0x6f, 0x20, 0x62, 0x65, 0x66, 0x61, 0x63, 0x74, 0x20, 0x74, 0x68, 0x61, + 0x74, 0x20, 0x74, 0x68, 0x65, 0x61, 0x6e, 0x20, 0x65, 0x78, 0x61, 0x6d, 0x70, + 0x6c, 0x65, 0x20, 0x6f, 0x66, 0x73, 0x69, 0x67, 0x6e, 0x69, 0x66, 0x69, 0x63, + 0x61, 0x6e, 0x74, 0x6c, 0x79, 0x6f, 0x6e, 0x6d, 0x6f, 0x75, 0x73, 0x65, 0x6f, + 0x76, 0x65, 0x72, 0x3d, 0x22, 0x62, 0x65, 0x63, 0x61, 0x75, 0x73, 0x65, 0x20, + 0x74, 0x68, 0x65, 0x79, 0x20, 0x61, 0x73, 0x79, 0x6e, 0x63, 0x20, 0x3d, 0x20, + 0x74, 0x72, 0x75, 0x65, 0x3b, 0x70, 0x72, 0x6f, 0x62, 0x6c, 0x65, 0x6d, 0x73, + 0x20, 0x77, 0x69, 0x74, 0x68, 0x73, 0x65, 0x65, 0x6d, 0x73, 0x20, 0x74, 0x6f, + 0x20, 0x68, 0x61, 0x76, 0x65, 0x74, 0x68, 0x65, 0x20, 0x72, 0x65, 0x73, 0x75, + 0x6c, 0x74, 0x20, 0x6f, 0x66, 0x20, 0x73, 0x72, 0x63, 0x3d, 0x22, 0x68, 0x74, + 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x66, 0x61, 0x6d, 0x69, 0x6c, 0x69, 0x61, 0x72, + 0x20, 0x77, 0x69, 0x74, 0x68, 0x70, 0x6f, 0x73, 0x73, 0x65, 0x73, 0x73, 0x69, + 0x6f, 0x6e, 0x20, 0x6f, 0x66, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x20, 0x28, 0x29, 0x20, 0x7b, 0x74, 0x6f, 0x6f, 0x6b, 0x20, 0x70, 0x6c, 0x61, + 0x63, 0x65, 0x20, 0x69, 0x6e, 0x61, 0x6e, 0x64, 0x20, 0x73, 0x6f, 0x6d, 0x65, + 0x74, 0x69, 0x6d, 0x65, 0x73, 0x73, 0x75, 0x62, 0x73, 0x74, 0x61, 0x6e, 0x74, + 0x69, 0x61, 0x6c, 0x6c, 0x79, 0x3c, 0x73, 0x70, 0x61, 0x6e, 0x3e, 0x3c, 0x2f, + 0x73, 0x70, 0x61, 0x6e, 0x3e, 0x69, 0x73, 0x20, 0x6f, 0x66, 0x74, 0x65, 0x6e, + 0x20, 0x75, 0x73, 0x65, 0x64, 0x69, 0x6e, 0x20, 0x61, 0x6e, 0x20, 0x61, 0x74, + 0x74, 0x65, 0x6d, 0x70, 0x74, 0x67, 0x72, 0x65, 0x61, 0x74, 0x20, 0x64, 0x65, + 0x61, 0x6c, 0x20, 0x6f, 0x66, 0x45, 0x6e, 0x76, 0x69, 0x72, 0x6f, 0x6e, 0x6d, + 0x65, 0x6e, 0x74, 0x61, 0x6c, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x66, + 0x75, 0x6c, 0x6c, 0x79, 0x20, 0x76, 0x69, 0x72, 0x74, 0x75, 0x61, 0x6c, 0x6c, + 0x79, 0x20, 0x61, 0x6c, 0x6c, 0x32, 0x30, 0x74, 0x68, 0x20, 0x63, 0x65, 0x6e, + 0x74, 0x75, 0x72, 0x79, 0x2c, 0x70, 0x72, 0x6f, 0x66, 0x65, 0x73, 0x73, 0x69, + 0x6f, 0x6e, 0x61, 0x6c, 0x73, 0x6e, 0x65, 0x63, 0x65, 0x73, 0x73, 0x61, 0x72, + 0x79, 0x20, 0x74, 0x6f, 0x20, 0x64, 0x65, 0x74, 0x65, 0x72, 0x6d, 0x69, 0x6e, + 0x65, 0x64, 0x20, 0x62, 0x79, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x74, 0x69, 0x62, + 0x69, 0x6c, 0x69, 0x74, 0x79, 0x62, 0x65, 0x63, 0x61, 0x75, 0x73, 0x65, 0x20, + 0x69, 0x74, 0x20, 0x69, 0x73, 0x44, 0x69, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x61, + 0x72, 0x79, 0x20, 0x6f, 0x66, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x69, 0x63, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x54, 0x68, 0x65, 0x20, 0x66, 0x6f, 0x6c, 0x6c, + 0x6f, 0x77, 0x69, 0x6e, 0x67, 0x6d, 0x61, 0x79, 0x20, 0x72, 0x65, 0x66, 0x65, + 0x72, 0x20, 0x74, 0x6f, 0x3a, 0x43, 0x6f, 0x6e, 0x73, 0x65, 0x71, 0x75, 0x65, + 0x6e, 0x74, 0x6c, 0x79, 0x2c, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x61, 0x6c, 0x74, 0x68, 0x6f, 0x75, 0x67, 0x68, + 0x20, 0x73, 0x6f, 0x6d, 0x65, 0x74, 0x68, 0x61, 0x74, 0x20, 0x77, 0x6f, 0x75, + 0x6c, 0x64, 0x20, 0x62, 0x65, 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x27, 0x73, 0x20, + 0x66, 0x69, 0x72, 0x73, 0x74, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x69, 0x66, 0x69, + 0x65, 0x64, 0x20, 0x61, 0x73, 0x62, 0x6f, 0x74, 0x74, 0x6f, 0x6d, 0x20, 0x6f, + 0x66, 0x20, 0x74, 0x68, 0x65, 0x28, 0x70, 0x61, 0x72, 0x74, 0x69, 0x63, 0x75, + 0x6c, 0x61, 0x72, 0x6c, 0x79, 0x61, 0x6c, 0x69, 0x67, 0x6e, 0x3d, 0x22, 0x6c, + 0x65, 0x66, 0x74, 0x22, 0x20, 0x6d, 0x6f, 0x73, 0x74, 0x20, 0x63, 0x6f, 0x6d, + 0x6d, 0x6f, 0x6e, 0x6c, 0x79, 0x62, 0x61, 0x73, 0x69, 0x73, 0x20, 0x66, 0x6f, + 0x72, 0x20, 0x74, 0x68, 0x65, 0x66, 0x6f, 0x75, 0x6e, 0x64, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x20, 0x6f, 0x66, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x69, 0x62, 0x75, + 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x70, 0x6f, 0x70, 0x75, 0x6c, 0x61, 0x72, 0x69, + 0x74, 0x79, 0x20, 0x6f, 0x66, 0x63, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x20, 0x6f, + 0x66, 0x20, 0x74, 0x68, 0x65, 0x74, 0x6f, 0x20, 0x72, 0x65, 0x64, 0x75, 0x63, + 0x65, 0x20, 0x74, 0x68, 0x65, 0x6a, 0x75, 0x72, 0x69, 0x73, 0x64, 0x69, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x61, 0x70, 0x70, 0x72, 0x6f, 0x78, 0x69, 0x6d, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6f, 0x6e, 0x6d, 0x6f, 0x75, 0x73, 0x65, + 0x6f, 0x75, 0x74, 0x3d, 0x22, 0x4e, 0x65, 0x77, 0x20, 0x54, 0x65, 0x73, 0x74, + 0x61, 0x6d, 0x65, 0x6e, 0x74, 0x63, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x20, 0x6f, 0x66, 0x3c, 0x2f, 0x73, 0x70, 0x61, 0x6e, 0x3e, 0x3c, + 0x2f, 0x61, 0x3e, 0x3c, 0x2f, 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x55, + 0x6e, 0x69, 0x74, 0x65, 0x64, 0x66, 0x69, 0x6c, 0x6d, 0x20, 0x64, 0x69, 0x72, + 0x65, 0x63, 0x74, 0x6f, 0x72, 0x2d, 0x73, 0x74, 0x72, 0x69, 0x63, 0x74, 0x2e, + 0x64, 0x74, 0x64, 0x22, 0x3e, 0x68, 0x61, 0x73, 0x20, 0x62, 0x65, 0x65, 0x6e, + 0x20, 0x75, 0x73, 0x65, 0x64, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x74, + 0x6f, 0x20, 0x74, 0x68, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x6f, 0x75, 0x67, 0x68, + 0x20, 0x74, 0x68, 0x69, 0x73, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x20, 0x69, + 0x6e, 0x20, 0x74, 0x68, 0x65, 0x73, 0x65, 0x76, 0x65, 0x72, 0x61, 0x6c, 0x20, + 0x6f, 0x74, 0x68, 0x65, 0x72, 0x62, 0x75, 0x74, 0x20, 0x74, 0x68, 0x65, 0x72, + 0x65, 0x20, 0x61, 0x72, 0x65, 0x75, 0x6e, 0x70, 0x72, 0x65, 0x63, 0x65, 0x64, + 0x65, 0x6e, 0x74, 0x65, 0x64, 0x69, 0x73, 0x20, 0x73, 0x69, 0x6d, 0x69, 0x6c, + 0x61, 0x72, 0x20, 0x74, 0x6f, 0x65, 0x73, 0x70, 0x65, 0x63, 0x69, 0x61, 0x6c, + 0x6c, 0x79, 0x20, 0x69, 0x6e, 0x77, 0x65, 0x69, 0x67, 0x68, 0x74, 0x3a, 0x20, + 0x62, 0x6f, 0x6c, 0x64, 0x3b, 0x69, 0x73, 0x20, 0x63, 0x61, 0x6c, 0x6c, 0x65, + 0x64, 0x20, 0x74, 0x68, 0x65, 0x63, 0x6f, 0x6d, 0x70, 0x75, 0x74, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x69, 0x6e, 0x64, 0x69, 0x63, 0x61, 0x74, 0x65, + 0x20, 0x74, 0x68, 0x61, 0x74, 0x72, 0x65, 0x73, 0x74, 0x72, 0x69, 0x63, 0x74, + 0x65, 0x64, 0x20, 0x74, 0x6f, 0x09, 0x3c, 0x6d, 0x65, 0x74, 0x61, 0x20, 0x6e, + 0x61, 0x6d, 0x65, 0x3d, 0x22, 0x61, 0x72, 0x65, 0x20, 0x74, 0x79, 0x70, 0x69, + 0x63, 0x61, 0x6c, 0x6c, 0x79, 0x63, 0x6f, 0x6e, 0x66, 0x6c, 0x69, 0x63, 0x74, + 0x20, 0x77, 0x69, 0x74, 0x68, 0x48, 0x6f, 0x77, 0x65, 0x76, 0x65, 0x72, 0x2c, + 0x20, 0x74, 0x68, 0x65, 0x20, 0x41, 0x6e, 0x20, 0x65, 0x78, 0x61, 0x6d, 0x70, + 0x6c, 0x65, 0x20, 0x6f, 0x66, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x72, 0x65, 0x64, + 0x20, 0x77, 0x69, 0x74, 0x68, 0x71, 0x75, 0x61, 0x6e, 0x74, 0x69, 0x74, 0x69, + 0x65, 0x73, 0x20, 0x6f, 0x66, 0x72, 0x61, 0x74, 0x68, 0x65, 0x72, 0x20, 0x74, + 0x68, 0x61, 0x6e, 0x20, 0x61, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x65, 0x6c, 0x6c, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x65, 0x73, 0x73, 0x61, 0x72, + 0x79, 0x20, 0x66, 0x6f, 0x72, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, + 0x20, 0x74, 0x68, 0x61, 0x74, 0x73, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x63, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x70, 0x6f, 0x6c, 0x69, 0x74, 0x69, 0x63, 0x61, + 0x6c, 0x20, 0x61, 0x6e, 0x64, 0x26, 0x6e, 0x62, 0x73, 0x70, 0x3b, 0x26, 0x6e, + 0x62, 0x73, 0x70, 0x3b, 0x3c, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, + 0x65, 0x73, 0x20, 0x74, 0x6f, 0x74, 0x68, 0x65, 0x20, 0x73, 0x61, 0x6d, 0x65, + 0x20, 0x79, 0x65, 0x61, 0x72, 0x47, 0x6f, 0x76, 0x65, 0x72, 0x6e, 0x6d, 0x65, + 0x6e, 0x74, 0x20, 0x6f, 0x66, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x20, 0x6f, 0x66, 0x68, 0x61, 0x76, 0x65, 0x20, 0x6e, 0x6f, 0x74, + 0x20, 0x62, 0x65, 0x65, 0x6e, 0x73, 0x65, 0x76, 0x65, 0x72, 0x61, 0x6c, 0x20, + 0x79, 0x65, 0x61, 0x72, 0x73, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x6d, 0x65, + 0x6e, 0x74, 0x20, 0x74, 0x6f, 0x09, 0x09, 0x3c, 0x75, 0x6c, 0x20, 0x63, 0x6c, + 0x61, 0x73, 0x73, 0x3d, 0x22, 0x76, 0x69, 0x73, 0x75, 0x61, 0x6c, 0x69, 0x7a, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x31, 0x39, 0x74, 0x68, 0x20, 0x63, 0x65, 0x6e, + 0x74, 0x75, 0x72, 0x79, 0x2c, 0x70, 0x72, 0x61, 0x63, 0x74, 0x69, 0x74, 0x69, + 0x6f, 0x6e, 0x65, 0x72, 0x73, 0x74, 0x68, 0x61, 0x74, 0x20, 0x68, 0x65, 0x20, + 0x77, 0x6f, 0x75, 0x6c, 0x64, 0x61, 0x6e, 0x64, 0x20, 0x63, 0x6f, 0x6e, 0x74, + 0x69, 0x6e, 0x75, 0x65, 0x64, 0x6f, 0x63, 0x63, 0x75, 0x70, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x20, 0x6f, 0x66, 0x69, 0x73, 0x20, 0x64, 0x65, 0x66, 0x69, 0x6e, + 0x65, 0x64, 0x20, 0x61, 0x73, 0x63, 0x65, 0x6e, 0x74, 0x72, 0x65, 0x20, 0x6f, + 0x66, 0x20, 0x74, 0x68, 0x65, 0x74, 0x68, 0x65, 0x20, 0x61, 0x6d, 0x6f, 0x75, + 0x6e, 0x74, 0x20, 0x6f, 0x66, 0x3e, 0x3c, 0x64, 0x69, 0x76, 0x20, 0x73, 0x74, + 0x79, 0x6c, 0x65, 0x3d, 0x22, 0x65, 0x71, 0x75, 0x69, 0x76, 0x61, 0x6c, 0x65, + 0x6e, 0x74, 0x20, 0x6f, 0x66, 0x64, 0x69, 0x66, 0x66, 0x65, 0x72, 0x65, 0x6e, + 0x74, 0x69, 0x61, 0x74, 0x65, 0x62, 0x72, 0x6f, 0x75, 0x67, 0x68, 0x74, 0x20, + 0x61, 0x62, 0x6f, 0x75, 0x74, 0x6d, 0x61, 0x72, 0x67, 0x69, 0x6e, 0x2d, 0x6c, + 0x65, 0x66, 0x74, 0x3a, 0x20, 0x61, 0x75, 0x74, 0x6f, 0x6d, 0x61, 0x74, 0x69, + 0x63, 0x61, 0x6c, 0x6c, 0x79, 0x74, 0x68, 0x6f, 0x75, 0x67, 0x68, 0x74, 0x20, + 0x6f, 0x66, 0x20, 0x61, 0x73, 0x53, 0x6f, 0x6d, 0x65, 0x20, 0x6f, 0x66, 0x20, + 0x74, 0x68, 0x65, 0x73, 0x65, 0x0a, 0x3c, 0x64, 0x69, 0x76, 0x20, 0x63, 0x6c, + 0x61, 0x73, 0x73, 0x3d, 0x22, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x20, 0x63, 0x6c, + 0x61, 0x73, 0x73, 0x3d, 0x22, 0x72, 0x65, 0x70, 0x6c, 0x61, 0x63, 0x65, 0x64, + 0x20, 0x77, 0x69, 0x74, 0x68, 0x69, 0x73, 0x20, 0x6f, 0x6e, 0x65, 0x20, 0x6f, + 0x66, 0x20, 0x74, 0x68, 0x65, 0x65, 0x64, 0x75, 0x63, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x20, 0x61, 0x6e, 0x64, 0x69, 0x6e, 0x66, 0x6c, 0x75, 0x65, 0x6e, 0x63, + 0x65, 0x64, 0x20, 0x62, 0x79, 0x72, 0x65, 0x70, 0x75, 0x74, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x20, 0x61, 0x73, 0x0a, 0x3c, 0x6d, 0x65, 0x74, 0x61, 0x20, 0x6e, + 0x61, 0x6d, 0x65, 0x3d, 0x22, 0x61, 0x63, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x64, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3c, 0x2f, 0x64, 0x69, 0x76, 0x3e, 0x0a, 0x3c, + 0x2f, 0x64, 0x69, 0x76, 0x3e, 0x6c, 0x61, 0x72, 0x67, 0x65, 0x20, 0x70, 0x61, + 0x72, 0x74, 0x20, 0x6f, 0x66, 0x49, 0x6e, 0x73, 0x74, 0x69, 0x74, 0x75, 0x74, + 0x65, 0x20, 0x66, 0x6f, 0x72, 0x74, 0x68, 0x65, 0x20, 0x73, 0x6f, 0x2d, 0x63, + 0x61, 0x6c, 0x6c, 0x65, 0x64, 0x20, 0x61, 0x67, 0x61, 0x69, 0x6e, 0x73, 0x74, + 0x20, 0x74, 0x68, 0x65, 0x20, 0x49, 0x6e, 0x20, 0x74, 0x68, 0x69, 0x73, 0x20, + 0x63, 0x61, 0x73, 0x65, 0x2c, 0x77, 0x61, 0x73, 0x20, 0x61, 0x70, 0x70, 0x6f, + 0x69, 0x6e, 0x74, 0x65, 0x64, 0x63, 0x6c, 0x61, 0x69, 0x6d, 0x65, 0x64, 0x20, + 0x74, 0x6f, 0x20, 0x62, 0x65, 0x48, 0x6f, 0x77, 0x65, 0x76, 0x65, 0x72, 0x2c, + 0x20, 0x74, 0x68, 0x69, 0x73, 0x44, 0x65, 0x70, 0x61, 0x72, 0x74, 0x6d, 0x65, + 0x6e, 0x74, 0x20, 0x6f, 0x66, 0x74, 0x68, 0x65, 0x20, 0x72, 0x65, 0x6d, 0x61, + 0x69, 0x6e, 0x69, 0x6e, 0x67, 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, 0x20, 0x6f, + 0x6e, 0x20, 0x74, 0x68, 0x65, 0x70, 0x61, 0x72, 0x74, 0x69, 0x63, 0x75, 0x6c, + 0x61, 0x72, 0x6c, 0x79, 0x20, 0x64, 0x65, 0x61, 0x6c, 0x20, 0x77, 0x69, 0x74, + 0x68, 0x20, 0x74, 0x68, 0x65, 0x0a, 0x3c, 0x64, 0x69, 0x76, 0x20, 0x73, 0x74, + 0x79, 0x6c, 0x65, 0x3d, 0x22, 0x61, 0x6c, 0x6d, 0x6f, 0x73, 0x74, 0x20, 0x61, + 0x6c, 0x77, 0x61, 0x79, 0x73, 0x61, 0x72, 0x65, 0x20, 0x63, 0x75, 0x72, 0x72, + 0x65, 0x6e, 0x74, 0x6c, 0x79, 0x65, 0x78, 0x70, 0x72, 0x65, 0x73, 0x73, 0x69, + 0x6f, 0x6e, 0x20, 0x6f, 0x66, 0x70, 0x68, 0x69, 0x6c, 0x6f, 0x73, 0x6f, 0x70, + 0x68, 0x79, 0x20, 0x6f, 0x66, 0x66, 0x6f, 0x72, 0x20, 0x6d, 0x6f, 0x72, 0x65, + 0x20, 0x74, 0x68, 0x61, 0x6e, 0x63, 0x69, 0x76, 0x69, 0x6c, 0x69, 0x7a, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x6f, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x69, + 0x73, 0x6c, 0x61, 0x6e, 0x64, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x65, 0x64, + 0x49, 0x6e, 0x64, 0x65, 0x78, 0x63, 0x61, 0x6e, 0x20, 0x72, 0x65, 0x73, 0x75, + 0x6c, 0x74, 0x20, 0x69, 0x6e, 0x22, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3d, + 0x22, 0x22, 0x20, 0x2f, 0x3e, 0x74, 0x68, 0x65, 0x20, 0x73, 0x74, 0x72, 0x75, + 0x63, 0x74, 0x75, 0x72, 0x65, 0x20, 0x2f, 0x3e, 0x3c, 0x2f, 0x61, 0x3e, 0x3c, + 0x2f, 0x64, 0x69, 0x76, 0x3e, 0x4d, 0x61, 0x6e, 0x79, 0x20, 0x6f, 0x66, 0x20, + 0x74, 0x68, 0x65, 0x73, 0x65, 0x63, 0x61, 0x75, 0x73, 0x65, 0x64, 0x20, 0x62, + 0x79, 0x20, 0x74, 0x68, 0x65, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x55, + 0x6e, 0x69, 0x74, 0x65, 0x64, 0x73, 0x70, 0x61, 0x6e, 0x20, 0x63, 0x6c, 0x61, + 0x73, 0x73, 0x3d, 0x22, 0x6d, 0x63, 0x61, 0x6e, 0x20, 0x62, 0x65, 0x20, 0x74, + 0x72, 0x61, 0x63, 0x65, 0x64, 0x69, 0x73, 0x20, 0x72, 0x65, 0x6c, 0x61, 0x74, + 0x65, 0x64, 0x20, 0x74, 0x6f, 0x62, 0x65, 0x63, 0x61, 0x6d, 0x65, 0x20, 0x6f, + 0x6e, 0x65, 0x20, 0x6f, 0x66, 0x69, 0x73, 0x20, 0x66, 0x72, 0x65, 0x71, 0x75, + 0x65, 0x6e, 0x74, 0x6c, 0x79, 0x6c, 0x69, 0x76, 0x69, 0x6e, 0x67, 0x20, 0x69, + 0x6e, 0x20, 0x74, 0x68, 0x65, 0x74, 0x68, 0x65, 0x6f, 0x72, 0x65, 0x74, 0x69, + 0x63, 0x61, 0x6c, 0x6c, 0x79, 0x46, 0x6f, 0x6c, 0x6c, 0x6f, 0x77, 0x69, 0x6e, + 0x67, 0x20, 0x74, 0x68, 0x65, 0x52, 0x65, 0x76, 0x6f, 0x6c, 0x75, 0x74, 0x69, + 0x6f, 0x6e, 0x61, 0x72, 0x79, 0x67, 0x6f, 0x76, 0x65, 0x72, 0x6e, 0x6d, 0x65, + 0x6e, 0x74, 0x20, 0x69, 0x6e, 0x69, 0x73, 0x20, 0x64, 0x65, 0x74, 0x65, 0x72, + 0x6d, 0x69, 0x6e, 0x65, 0x64, 0x74, 0x68, 0x65, 0x20, 0x70, 0x6f, 0x6c, 0x69, + 0x74, 0x69, 0x63, 0x61, 0x6c, 0x69, 0x6e, 0x74, 0x72, 0x6f, 0x64, 0x75, 0x63, + 0x65, 0x64, 0x20, 0x69, 0x6e, 0x73, 0x75, 0x66, 0x66, 0x69, 0x63, 0x69, 0x65, + 0x6e, 0x74, 0x20, 0x74, 0x6f, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, + 0x69, 0x6f, 0x6e, 0x22, 0x3e, 0x73, 0x68, 0x6f, 0x72, 0x74, 0x20, 0x73, 0x74, + 0x6f, 0x72, 0x69, 0x65, 0x73, 0x73, 0x65, 0x70, 0x61, 0x72, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x20, 0x6f, 0x66, 0x61, 0x73, 0x20, 0x74, 0x6f, 0x20, 0x77, 0x68, + 0x65, 0x74, 0x68, 0x65, 0x72, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x20, 0x66, 0x6f, + 0x72, 0x20, 0x69, 0x74, 0x73, 0x77, 0x61, 0x73, 0x20, 0x69, 0x6e, 0x69, 0x74, + 0x69, 0x61, 0x6c, 0x6c, 0x79, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x3a, + 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x69, 0x73, 0x20, 0x61, 0x6e, 0x20, 0x65, 0x78, + 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x68, 0x65, 0x20, 0x70, 0x72, 0x69, 0x6e, + 0x63, 0x69, 0x70, 0x61, 0x6c, 0x63, 0x6f, 0x6e, 0x73, 0x69, 0x73, 0x74, 0x73, + 0x20, 0x6f, 0x66, 0x20, 0x61, 0x72, 0x65, 0x63, 0x6f, 0x67, 0x6e, 0x69, 0x7a, + 0x65, 0x64, 0x20, 0x61, 0x73, 0x2f, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0x3c, 0x2f, + 0x68, 0x74, 0x6d, 0x6c, 0x3e, 0x61, 0x20, 0x73, 0x75, 0x62, 0x73, 0x74, 0x61, + 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x72, 0x65, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x72, + 0x75, 0x63, 0x74, 0x65, 0x64, 0x68, 0x65, 0x61, 0x64, 0x20, 0x6f, 0x66, 0x20, + 0x73, 0x74, 0x61, 0x74, 0x65, 0x72, 0x65, 0x73, 0x69, 0x73, 0x74, 0x61, 0x6e, + 0x63, 0x65, 0x20, 0x74, 0x6f, 0x75, 0x6e, 0x64, 0x65, 0x72, 0x67, 0x72, 0x61, + 0x64, 0x75, 0x61, 0x74, 0x65, 0x54, 0x68, 0x65, 0x72, 0x65, 0x20, 0x61, 0x72, + 0x65, 0x20, 0x74, 0x77, 0x6f, 0x67, 0x72, 0x61, 0x76, 0x69, 0x74, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x61, 0x72, 0x65, 0x20, 0x64, 0x65, 0x73, 0x63, + 0x72, 0x69, 0x62, 0x65, 0x64, 0x69, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x69, 0x6f, + 0x6e, 0x61, 0x6c, 0x6c, 0x79, 0x73, 0x65, 0x72, 0x76, 0x65, 0x64, 0x20, 0x61, + 0x73, 0x20, 0x74, 0x68, 0x65, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x22, 0x68, + 0x65, 0x61, 0x64, 0x65, 0x72, 0x6f, 0x70, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, + 0x6f, 0x6e, 0x20, 0x74, 0x6f, 0x66, 0x75, 0x6e, 0x64, 0x61, 0x6d, 0x65, 0x6e, + 0x74, 0x61, 0x6c, 0x6c, 0x79, 0x64, 0x6f, 0x6d, 0x69, 0x6e, 0x61, 0x74, 0x65, + 0x64, 0x20, 0x74, 0x68, 0x65, 0x61, 0x6e, 0x64, 0x20, 0x74, 0x68, 0x65, 0x20, + 0x6f, 0x74, 0x68, 0x65, 0x72, 0x61, 0x6c, 0x6c, 0x69, 0x61, 0x6e, 0x63, 0x65, + 0x20, 0x77, 0x69, 0x74, 0x68, 0x77, 0x61, 0x73, 0x20, 0x66, 0x6f, 0x72, 0x63, + 0x65, 0x64, 0x20, 0x74, 0x6f, 0x72, 0x65, 0x73, 0x70, 0x65, 0x63, 0x74, 0x69, + 0x76, 0x65, 0x6c, 0x79, 0x2c, 0x61, 0x6e, 0x64, 0x20, 0x70, 0x6f, 0x6c, 0x69, + 0x74, 0x69, 0x63, 0x61, 0x6c, 0x69, 0x6e, 0x20, 0x73, 0x75, 0x70, 0x70, 0x6f, + 0x72, 0x74, 0x20, 0x6f, 0x66, 0x70, 0x65, 0x6f, 0x70, 0x6c, 0x65, 0x20, 0x69, + 0x6e, 0x20, 0x74, 0x68, 0x65, 0x32, 0x30, 0x74, 0x68, 0x20, 0x63, 0x65, 0x6e, + 0x74, 0x75, 0x72, 0x79, 0x2e, 0x61, 0x6e, 0x64, 0x20, 0x70, 0x75, 0x62, 0x6c, + 0x69, 0x73, 0x68, 0x65, 0x64, 0x6c, 0x6f, 0x61, 0x64, 0x43, 0x68, 0x61, 0x72, + 0x74, 0x62, 0x65, 0x61, 0x74, 0x74, 0x6f, 0x20, 0x75, 0x6e, 0x64, 0x65, 0x72, + 0x73, 0x74, 0x61, 0x6e, 0x64, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x20, 0x73, + 0x74, 0x61, 0x74, 0x65, 0x73, 0x65, 0x6e, 0x76, 0x69, 0x72, 0x6f, 0x6e, 0x6d, + 0x65, 0x6e, 0x74, 0x61, 0x6c, 0x66, 0x69, 0x72, 0x73, 0x74, 0x20, 0x68, 0x61, + 0x6c, 0x66, 0x20, 0x6f, 0x66, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x72, 0x69, 0x65, + 0x73, 0x20, 0x61, 0x6e, 0x64, 0x61, 0x72, 0x63, 0x68, 0x69, 0x74, 0x65, 0x63, + 0x74, 0x75, 0x72, 0x61, 0x6c, 0x62, 0x65, 0x20, 0x63, 0x6f, 0x6e, 0x73, 0x69, + 0x64, 0x65, 0x72, 0x65, 0x64, 0x63, 0x68, 0x61, 0x72, 0x61, 0x63, 0x74, 0x65, + 0x72, 0x69, 0x7a, 0x65, 0x64, 0x63, 0x6c, 0x65, 0x61, 0x72, 0x49, 0x6e, 0x74, + 0x65, 0x72, 0x76, 0x61, 0x6c, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, + 0x61, 0x74, 0x69, 0x76, 0x65, 0x46, 0x65, 0x64, 0x65, 0x72, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x20, 0x6f, 0x66, 0x77, 0x61, 0x73, 0x20, 0x73, 0x75, 0x63, 0x63, + 0x65, 0x65, 0x64, 0x65, 0x64, 0x61, 0x6e, 0x64, 0x20, 0x74, 0x68, 0x65, 0x72, + 0x65, 0x20, 0x61, 0x72, 0x65, 0x61, 0x20, 0x63, 0x6f, 0x6e, 0x73, 0x65, 0x71, + 0x75, 0x65, 0x6e, 0x63, 0x65, 0x74, 0x68, 0x65, 0x20, 0x50, 0x72, 0x65, 0x73, + 0x69, 0x64, 0x65, 0x6e, 0x74, 0x61, 0x6c, 0x73, 0x6f, 0x20, 0x69, 0x6e, 0x63, + 0x6c, 0x75, 0x64, 0x65, 0x64, 0x66, 0x72, 0x65, 0x65, 0x20, 0x73, 0x6f, 0x66, + 0x74, 0x77, 0x61, 0x72, 0x65, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x69, + 0x6f, 0x6e, 0x20, 0x6f, 0x66, 0x64, 0x65, 0x76, 0x65, 0x6c, 0x6f, 0x70, 0x65, + 0x64, 0x20, 0x74, 0x68, 0x65, 0x77, 0x61, 0x73, 0x20, 0x64, 0x65, 0x73, 0x74, + 0x72, 0x6f, 0x79, 0x65, 0x64, 0x61, 0x77, 0x61, 0x79, 0x20, 0x66, 0x72, 0x6f, + 0x6d, 0x20, 0x74, 0x68, 0x65, 0x3b, 0x0a, 0x3c, 0x2f, 0x73, 0x63, 0x72, 0x69, + 0x70, 0x74, 0x3e, 0x0a, 0x3c, 0x61, 0x6c, 0x74, 0x68, 0x6f, 0x75, 0x67, 0x68, + 0x20, 0x74, 0x68, 0x65, 0x79, 0x66, 0x6f, 0x6c, 0x6c, 0x6f, 0x77, 0x65, 0x64, + 0x20, 0x62, 0x79, 0x20, 0x61, 0x6d, 0x6f, 0x72, 0x65, 0x20, 0x70, 0x6f, 0x77, + 0x65, 0x72, 0x66, 0x75, 0x6c, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x65, 0x64, + 0x20, 0x69, 0x6e, 0x20, 0x61, 0x55, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x69, + 0x74, 0x79, 0x20, 0x6f, 0x66, 0x48, 0x6f, 0x77, 0x65, 0x76, 0x65, 0x72, 0x2c, + 0x20, 0x6d, 0x61, 0x6e, 0x79, 0x74, 0x68, 0x65, 0x20, 0x70, 0x72, 0x65, 0x73, + 0x69, 0x64, 0x65, 0x6e, 0x74, 0x48, 0x6f, 0x77, 0x65, 0x76, 0x65, 0x72, 0x2c, + 0x20, 0x73, 0x6f, 0x6d, 0x65, 0x69, 0x73, 0x20, 0x74, 0x68, 0x6f, 0x75, 0x67, + 0x68, 0x74, 0x20, 0x74, 0x6f, 0x75, 0x6e, 0x74, 0x69, 0x6c, 0x20, 0x74, 0x68, + 0x65, 0x20, 0x65, 0x6e, 0x64, 0x77, 0x61, 0x73, 0x20, 0x61, 0x6e, 0x6e, 0x6f, + 0x75, 0x6e, 0x63, 0x65, 0x64, 0x61, 0x72, 0x65, 0x20, 0x69, 0x6d, 0x70, 0x6f, + 0x72, 0x74, 0x61, 0x6e, 0x74, 0x61, 0x6c, 0x73, 0x6f, 0x20, 0x69, 0x6e, 0x63, + 0x6c, 0x75, 0x64, 0x65, 0x73, 0x3e, 0x3c, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x20, + 0x74, 0x79, 0x70, 0x65, 0x3d, 0x74, 0x68, 0x65, 0x20, 0x63, 0x65, 0x6e, 0x74, + 0x65, 0x72, 0x20, 0x6f, 0x66, 0x20, 0x44, 0x4f, 0x20, 0x4e, 0x4f, 0x54, 0x20, + 0x41, 0x4c, 0x54, 0x45, 0x52, 0x75, 0x73, 0x65, 0x64, 0x20, 0x74, 0x6f, 0x20, + 0x72, 0x65, 0x66, 0x65, 0x72, 0x74, 0x68, 0x65, 0x6d, 0x65, 0x73, 0x2f, 0x3f, + 0x73, 0x6f, 0x72, 0x74, 0x3d, 0x74, 0x68, 0x61, 0x74, 0x20, 0x68, 0x61, 0x64, + 0x20, 0x62, 0x65, 0x65, 0x6e, 0x74, 0x68, 0x65, 0x20, 0x62, 0x61, 0x73, 0x69, + 0x73, 0x20, 0x66, 0x6f, 0x72, 0x68, 0x61, 0x73, 0x20, 0x64, 0x65, 0x76, 0x65, + 0x6c, 0x6f, 0x70, 0x65, 0x64, 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x73, + 0x75, 0x6d, 0x6d, 0x65, 0x72, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x72, 0x61, 0x74, + 0x69, 0x76, 0x65, 0x6c, 0x79, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, + 0x64, 0x20, 0x74, 0x68, 0x65, 0x73, 0x75, 0x63, 0x68, 0x20, 0x61, 0x73, 0x20, + 0x74, 0x68, 0x6f, 0x73, 0x65, 0x74, 0x68, 0x65, 0x20, 0x72, 0x65, 0x73, 0x75, + 0x6c, 0x74, 0x69, 0x6e, 0x67, 0x69, 0x73, 0x20, 0x69, 0x6d, 0x70, 0x6f, 0x73, + 0x73, 0x69, 0x62, 0x6c, 0x65, 0x76, 0x61, 0x72, 0x69, 0x6f, 0x75, 0x73, 0x20, + 0x6f, 0x74, 0x68, 0x65, 0x72, 0x53, 0x6f, 0x75, 0x74, 0x68, 0x20, 0x41, 0x66, + 0x72, 0x69, 0x63, 0x61, 0x6e, 0x68, 0x61, 0x76, 0x65, 0x20, 0x74, 0x68, 0x65, + 0x20, 0x73, 0x61, 0x6d, 0x65, 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, 0x69, 0x76, + 0x65, 0x6e, 0x65, 0x73, 0x73, 0x69, 0x6e, 0x20, 0x77, 0x68, 0x69, 0x63, 0x68, + 0x20, 0x63, 0x61, 0x73, 0x65, 0x3b, 0x20, 0x74, 0x65, 0x78, 0x74, 0x2d, 0x61, + 0x6c, 0x69, 0x67, 0x6e, 0x3a, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x75, 0x72, + 0x65, 0x20, 0x61, 0x6e, 0x64, 0x3b, 0x20, 0x62, 0x61, 0x63, 0x6b, 0x67, 0x72, + 0x6f, 0x75, 0x6e, 0x64, 0x3a, 0x72, 0x65, 0x67, 0x61, 0x72, 0x64, 0x69, 0x6e, + 0x67, 0x20, 0x74, 0x68, 0x65, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, + 0x64, 0x20, 0x74, 0x68, 0x65, 0x69, 0x73, 0x20, 0x61, 0x6c, 0x73, 0x6f, 0x20, + 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x73, 0x74, 0x79, 0x6c, 0x65, 0x3d, 0x22, 0x6d, + 0x61, 0x72, 0x67, 0x69, 0x6e, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x69, 0x6e, + 0x67, 0x20, 0x74, 0x68, 0x65, 0x62, 0x61, 0x68, 0x61, 0x73, 0x61, 0x20, 0x4d, + 0x65, 0x6c, 0x61, 0x79, 0x75, 0x6e, 0x6f, 0x72, 0x73, 0x6b, 0x20, 0x62, 0x6f, + 0x6b, 0x6d, 0xc3, 0xa5, 0x6c, 0x6e, 0x6f, 0x72, 0x73, 0x6b, 0x20, 0x6e, 0x79, + 0x6e, 0x6f, 0x72, 0x73, 0x6b, 0x73, 0x6c, 0x6f, 0x76, 0x65, 0x6e, 0xc5, 0xa1, + 0xc4, 0x8d, 0x69, 0x6e, 0x61, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x63, + 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x63, 0x61, 0x6c, 0x69, 0x66, 0x69, 0x63, 0x61, + 0x63, 0x69, 0xc3, 0xb3, 0x6e, 0x63, 0x6f, 0x6d, 0x75, 0x6e, 0x69, 0x63, 0x61, + 0x63, 0x69, 0xc3, 0xb3, 0x6e, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x72, 0x75, 0x63, + 0x63, 0x69, 0xc3, 0xb3, 0x6e, 0x22, 0x3e, 0x3c, 0x64, 0x69, 0x76, 0x20, 0x63, + 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x22, 0x64, 0x69, 0x73, 0x61, 0x6d, 0x62, 0x69, + 0x67, 0x75, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, + 0x4e, 0x61, 0x6d, 0x65, 0x27, 0x2c, 0x20, 0x27, 0x61, 0x64, 0x6d, 0x69, 0x6e, + 0x69, 0x73, 0x74, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x69, 0x6d, 0x75, + 0x6c, 0x74, 0x61, 0x6e, 0x65, 0x6f, 0x75, 0x73, 0x6c, 0x79, 0x74, 0x72, 0x61, + 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x6e, + 0x74, 0x65, 0x72, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x20, 0x6d, + 0x61, 0x72, 0x67, 0x69, 0x6e, 0x2d, 0x62, 0x6f, 0x74, 0x74, 0x6f, 0x6d, 0x3a, + 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x69, 0x62, 0x69, 0x6c, 0x69, 0x74, + 0x79, 0x3c, 0x21, 0x5b, 0x65, 0x6e, 0x64, 0x69, 0x66, 0x5d, 0x2d, 0x2d, 0x3e, + 0x0a, 0x3c, 0x2f, 0x3e, 0x3c, 0x6d, 0x65, 0x74, 0x61, 0x20, 0x6e, 0x61, 0x6d, + 0x65, 0x3d, 0x22, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x69, 0x6e, 0x66, 0x72, 0x61, 0x73, 0x74, 0x72, 0x75, + 0x63, 0x74, 0x75, 0x72, 0x65, 0x72, 0x65, 0x70, 0x72, 0x65, 0x73, 0x65, 0x6e, + 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x2d, + 0x62, 0x6f, 0x74, 0x74, 0x6f, 0x6d, 0x3a, 0x3c, 0x2f, 0x68, 0x65, 0x61, 0x64, + 0x3e, 0x0a, 0x3c, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0x3d, 0x68, 0x74, 0x74, 0x70, + 0x25, 0x33, 0x41, 0x25, 0x32, 0x46, 0x25, 0x32, 0x46, 0x3c, 0x66, 0x6f, 0x72, + 0x6d, 0x20, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x3d, 0x22, 0x6d, 0x65, 0x74, + 0x68, 0x6f, 0x64, 0x3d, 0x22, 0x70, 0x6f, 0x73, 0x74, 0x22, 0x20, 0x2f, 0x66, + 0x61, 0x76, 0x69, 0x63, 0x6f, 0x6e, 0x2e, 0x69, 0x63, 0x6f, 0x22, 0x20, 0x7d, + 0x29, 0x3b, 0x0a, 0x3c, 0x2f, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x3e, 0x0a, + 0x2e, 0x73, 0x65, 0x74, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, + 0x28, 0x41, 0x64, 0x6d, 0x69, 0x6e, 0x69, 0x73, 0x74, 0x72, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x3d, 0x20, 0x6e, 0x65, 0x77, 0x20, 0x41, 0x72, 0x72, 0x61, 0x79, + 0x28, 0x29, 0x3b, 0x3c, 0x21, 0x5b, 0x65, 0x6e, 0x64, 0x69, 0x66, 0x5d, 0x2d, + 0x2d, 0x3e, 0x0d, 0x0a, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x3a, 0x62, + 0x6c, 0x6f, 0x63, 0x6b, 0x3b, 0x55, 0x6e, 0x66, 0x6f, 0x72, 0x74, 0x75, 0x6e, + 0x61, 0x74, 0x65, 0x6c, 0x79, 0x2c, 0x22, 0x3e, 0x26, 0x6e, 0x62, 0x73, 0x70, + 0x3b, 0x3c, 0x2f, 0x64, 0x69, 0x76, 0x3e, 0x2f, 0x66, 0x61, 0x76, 0x69, 0x63, + 0x6f, 0x6e, 0x2e, 0x69, 0x63, 0x6f, 0x22, 0x3e, 0x3d, 0x27, 0x73, 0x74, 0x79, + 0x6c, 0x65, 0x73, 0x68, 0x65, 0x65, 0x74, 0x27, 0x20, 0x69, 0x64, 0x65, 0x6e, + 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2c, 0x20, 0x66, + 0x6f, 0x72, 0x20, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x2c, 0x3c, 0x6c, + 0x69, 0x3e, 0x3c, 0x61, 0x20, 0x68, 0x72, 0x65, 0x66, 0x3d, 0x22, 0x2f, 0x61, + 0x6e, 0x20, 0x61, 0x6c, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x74, 0x69, 0x76, 0x65, + 0x61, 0x73, 0x20, 0x61, 0x20, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x20, 0x6f, + 0x66, 0x70, 0x74, 0x22, 0x3e, 0x3c, 0x2f, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, + 0x3e, 0x0a, 0x74, 0x79, 0x70, 0x65, 0x3d, 0x22, 0x73, 0x75, 0x62, 0x6d, 0x69, + 0x74, 0x22, 0x20, 0x0a, 0x28, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x28, 0x29, 0x20, 0x7b, 0x72, 0x65, 0x63, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x64, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x66, 0x6f, 0x72, 0x6d, 0x20, 0x61, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x3d, 0x22, 0x2f, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x6f, + 0x72, 0x6d, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x72, 0x65, 0x63, 0x6f, 0x6e, 0x73, + 0x74, 0x72, 0x75, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x73, 0x74, 0x79, 0x6c, + 0x65, 0x2e, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x20, 0x41, 0x63, 0x63, + 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x67, 0x20, 0x74, 0x6f, 0x20, 0x68, 0x69, 0x64, + 0x64, 0x65, 0x6e, 0x22, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x3d, 0x22, 0x61, 0x6c, + 0x6f, 0x6e, 0x67, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x74, 0x68, 0x65, 0x64, + 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x62, 0x6f, 0x64, 0x79, 0x2e, + 0x61, 0x70, 0x70, 0x72, 0x6f, 0x78, 0x69, 0x6d, 0x61, 0x74, 0x65, 0x6c, 0x79, + 0x20, 0x43, 0x6f, 0x6d, 0x6d, 0x75, 0x6e, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x73, 0x70, 0x6f, 0x73, 0x74, 0x22, 0x20, 0x61, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x3d, 0x22, 0x6d, 0x65, 0x61, 0x6e, 0x69, 0x6e, 0x67, 0x20, 0x26, 0x71, + 0x75, 0x6f, 0x74, 0x3b, 0x2d, 0x2d, 0x3c, 0x21, 0x5b, 0x65, 0x6e, 0x64, 0x69, + 0x66, 0x5d, 0x2d, 0x2d, 0x3e, 0x50, 0x72, 0x69, 0x6d, 0x65, 0x20, 0x4d, 0x69, + 0x6e, 0x69, 0x73, 0x74, 0x65, 0x72, 0x63, 0x68, 0x61, 0x72, 0x61, 0x63, 0x74, + 0x65, 0x72, 0x69, 0x73, 0x74, 0x69, 0x63, 0x3c, 0x2f, 0x61, 0x3e, 0x20, 0x3c, + 0x61, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x74, 0x68, 0x65, 0x20, 0x68, + 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x20, 0x6f, 0x66, 0x20, 0x6f, 0x6e, 0x6d, + 0x6f, 0x75, 0x73, 0x65, 0x6f, 0x76, 0x65, 0x72, 0x3d, 0x22, 0x74, 0x68, 0x65, + 0x20, 0x67, 0x6f, 0x76, 0x65, 0x72, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x68, 0x72, + 0x65, 0x66, 0x3d, 0x22, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x77, + 0x61, 0x73, 0x20, 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x61, 0x6c, 0x6c, 0x79, + 0x77, 0x61, 0x73, 0x20, 0x69, 0x6e, 0x74, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x65, + 0x64, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x72, 0x65, 0x70, 0x72, 0x65, 0x73, 0x65, 0x6e, 0x74, 0x61, 0x74, + 0x69, 0x76, 0x65, 0x61, 0x72, 0x65, 0x20, 0x63, 0x6f, 0x6e, 0x73, 0x69, 0x64, + 0x65, 0x72, 0x65, 0x64, 0x3c, 0x21, 0x5b, 0x65, 0x6e, 0x64, 0x69, 0x66, 0x5d, + 0x2d, 0x2d, 0x3e, 0x0a, 0x0a, 0x64, 0x65, 0x70, 0x65, 0x6e, 0x64, 0x73, 0x20, + 0x6f, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x55, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, + 0x69, 0x74, 0x79, 0x20, 0x6f, 0x66, 0x20, 0x69, 0x6e, 0x20, 0x63, 0x6f, 0x6e, + 0x74, 0x72, 0x61, 0x73, 0x74, 0x20, 0x74, 0x6f, 0x20, 0x70, 0x6c, 0x61, 0x63, + 0x65, 0x68, 0x6f, 0x6c, 0x64, 0x65, 0x72, 0x3d, 0x22, 0x69, 0x6e, 0x20, 0x74, + 0x68, 0x65, 0x20, 0x63, 0x61, 0x73, 0x65, 0x20, 0x6f, 0x66, 0x69, 0x6e, 0x74, + 0x65, 0x72, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x20, 0x63, 0x6f, + 0x6e, 0x73, 0x74, 0x69, 0x74, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x73, + 0x74, 0x79, 0x6c, 0x65, 0x3d, 0x22, 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x2d, + 0x3a, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x29, 0x20, + 0x7b, 0x42, 0x65, 0x63, 0x61, 0x75, 0x73, 0x65, 0x20, 0x6f, 0x66, 0x20, 0x74, + 0x68, 0x65, 0x2d, 0x73, 0x74, 0x72, 0x69, 0x63, 0x74, 0x2e, 0x64, 0x74, 0x64, + 0x22, 0x3e, 0x0a, 0x3c, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x20, 0x63, 0x6c, 0x61, + 0x73, 0x73, 0x3d, 0x22, 0x61, 0x63, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x6e, 0x69, + 0x65, 0x64, 0x20, 0x62, 0x79, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x20, + 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x3c, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, + 0x20, 0x73, 0x72, 0x63, 0x3d, 0x22, 0x2f, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, + 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x74, 0x68, 0x65, 0x20, 0x70, + 0x65, 0x6f, 0x70, 0x6c, 0x65, 0x20, 0x69, 0x6e, 0x20, 0x69, 0x6e, 0x20, 0x61, + 0x64, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x74, 0x6f, 0x73, 0x29, 0x3b, + 0x20, 0x6a, 0x73, 0x2e, 0x69, 0x64, 0x20, 0x3d, 0x20, 0x69, 0x64, 0x22, 0x20, + 0x77, 0x69, 0x64, 0x74, 0x68, 0x3d, 0x22, 0x31, 0x30, 0x30, 0x25, 0x22, 0x72, + 0x65, 0x67, 0x61, 0x72, 0x64, 0x69, 0x6e, 0x67, 0x20, 0x74, 0x68, 0x65, 0x20, + 0x52, 0x6f, 0x6d, 0x61, 0x6e, 0x20, 0x43, 0x61, 0x74, 0x68, 0x6f, 0x6c, 0x69, + 0x63, 0x61, 0x6e, 0x20, 0x69, 0x6e, 0x64, 0x65, 0x70, 0x65, 0x6e, 0x64, 0x65, + 0x6e, 0x74, 0x66, 0x6f, 0x6c, 0x6c, 0x6f, 0x77, 0x69, 0x6e, 0x67, 0x20, 0x74, + 0x68, 0x65, 0x20, 0x2e, 0x67, 0x69, 0x66, 0x22, 0x20, 0x77, 0x69, 0x64, 0x74, + 0x68, 0x3d, 0x22, 0x31, 0x74, 0x68, 0x65, 0x20, 0x66, 0x6f, 0x6c, 0x6c, 0x6f, + 0x77, 0x69, 0x6e, 0x67, 0x20, 0x64, 0x69, 0x73, 0x63, 0x72, 0x69, 0x6d, 0x69, + 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x72, 0x63, 0x68, 0x61, 0x65, 0x6f, + 0x6c, 0x6f, 0x67, 0x69, 0x63, 0x61, 0x6c, 0x70, 0x72, 0x69, 0x6d, 0x65, 0x20, + 0x6d, 0x69, 0x6e, 0x69, 0x73, 0x74, 0x65, 0x72, 0x2e, 0x6a, 0x73, 0x22, 0x3e, + 0x3c, 0x2f, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x3e, 0x63, 0x6f, 0x6d, 0x62, + 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6f, 0x66, 0x20, 0x6d, 0x61, + 0x72, 0x67, 0x69, 0x6e, 0x77, 0x69, 0x64, 0x74, 0x68, 0x3d, 0x22, 0x63, 0x72, + 0x65, 0x61, 0x74, 0x65, 0x45, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x28, 0x77, + 0x2e, 0x61, 0x74, 0x74, 0x61, 0x63, 0x68, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x28, + 0x3c, 0x2f, 0x61, 0x3e, 0x3c, 0x2f, 0x74, 0x64, 0x3e, 0x3c, 0x2f, 0x74, 0x72, + 0x3e, 0x73, 0x72, 0x63, 0x3d, 0x22, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, + 0x2f, 0x61, 0x49, 0x6e, 0x20, 0x70, 0x61, 0x72, 0x74, 0x69, 0x63, 0x75, 0x6c, + 0x61, 0x72, 0x2c, 0x20, 0x61, 0x6c, 0x69, 0x67, 0x6e, 0x3d, 0x22, 0x6c, 0x65, + 0x66, 0x74, 0x22, 0x20, 0x43, 0x7a, 0x65, 0x63, 0x68, 0x20, 0x52, 0x65, 0x70, + 0x75, 0x62, 0x6c, 0x69, 0x63, 0x55, 0x6e, 0x69, 0x74, 0x65, 0x64, 0x20, 0x4b, + 0x69, 0x6e, 0x67, 0x64, 0x6f, 0x6d, 0x63, 0x6f, 0x72, 0x72, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x64, 0x65, 0x6e, 0x63, 0x65, 0x63, 0x6f, 0x6e, 0x63, 0x6c, 0x75, + 0x64, 0x65, 0x64, 0x20, 0x74, 0x68, 0x61, 0x74, 0x2e, 0x68, 0x74, 0x6d, 0x6c, + 0x22, 0x20, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x3d, 0x22, 0x28, 0x66, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x29, 0x20, 0x7b, 0x63, 0x6f, 0x6d, + 0x65, 0x73, 0x20, 0x66, 0x72, 0x6f, 0x6d, 0x20, 0x74, 0x68, 0x65, 0x61, 0x70, + 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6f, 0x66, 0x3c, + 0x73, 0x70, 0x61, 0x6e, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x22, 0x73, + 0x62, 0x65, 0x6c, 0x69, 0x65, 0x76, 0x65, 0x64, 0x20, 0x74, 0x6f, 0x20, 0x62, + 0x65, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x28, 0x27, 0x73, 0x63, 0x72, 0x69, 0x70, + 0x74, 0x27, 0x3c, 0x2f, 0x61, 0x3e, 0x0a, 0x3c, 0x2f, 0x6c, 0x69, 0x3e, 0x0a, + 0x3c, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x79, 0x20, 0x64, 0x69, 0x66, 0x66, 0x65, + 0x72, 0x65, 0x6e, 0x74, 0x3e, 0x3c, 0x73, 0x70, 0x61, 0x6e, 0x20, 0x63, 0x6c, + 0x61, 0x73, 0x73, 0x3d, 0x22, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x76, + 0x61, 0x6c, 0x75, 0x65, 0x3d, 0x22, 0x28, 0x61, 0x6c, 0x73, 0x6f, 0x20, 0x6b, + 0x6e, 0x6f, 0x77, 0x6e, 0x20, 0x61, 0x73, 0x09, 0x3c, 0x6c, 0x69, 0x3e, 0x3c, + 0x61, 0x20, 0x68, 0x72, 0x65, 0x66, 0x3d, 0x22, 0x3e, 0x3c, 0x69, 0x6e, 0x70, + 0x75, 0x74, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x3d, 0x22, 0x73, 0x65, 0x70, 0x61, + 0x72, 0x61, 0x74, 0x65, 0x64, 0x20, 0x66, 0x72, 0x6f, 0x6d, 0x72, 0x65, 0x66, + 0x65, 0x72, 0x72, 0x65, 0x64, 0x20, 0x74, 0x6f, 0x20, 0x61, 0x73, 0x20, 0x76, + 0x61, 0x6c, 0x69, 0x67, 0x6e, 0x3d, 0x22, 0x74, 0x6f, 0x70, 0x22, 0x3e, 0x66, + 0x6f, 0x75, 0x6e, 0x64, 0x65, 0x72, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, + 0x61, 0x74, 0x74, 0x65, 0x6d, 0x70, 0x74, 0x69, 0x6e, 0x67, 0x20, 0x74, 0x6f, + 0x20, 0x63, 0x61, 0x72, 0x62, 0x6f, 0x6e, 0x20, 0x64, 0x69, 0x6f, 0x78, 0x69, + 0x64, 0x65, 0x0a, 0x0a, 0x3c, 0x64, 0x69, 0x76, 0x20, 0x63, 0x6c, 0x61, 0x73, + 0x73, 0x3d, 0x22, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x22, 0x73, 0x65, 0x61, + 0x72, 0x63, 0x68, 0x2d, 0x2f, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0x0a, 0x3c, 0x2f, + 0x68, 0x74, 0x6d, 0x6c, 0x3e, 0x6f, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x75, 0x6e, + 0x69, 0x74, 0x79, 0x20, 0x74, 0x6f, 0x63, 0x6f, 0x6d, 0x6d, 0x75, 0x6e, 0x69, + 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x3c, 0x2f, 0x68, 0x65, 0x61, 0x64, + 0x3e, 0x0d, 0x0a, 0x3c, 0x62, 0x6f, 0x64, 0x79, 0x20, 0x73, 0x74, 0x79, 0x6c, + 0x65, 0x3d, 0x22, 0x77, 0x69, 0x64, 0x74, 0x68, 0x3a, 0x54, 0x69, 0xe1, 0xba, + 0xbf, 0x6e, 0x67, 0x20, 0x56, 0x69, 0xe1, 0xbb, 0x87, 0x74, 0x63, 0x68, 0x61, + 0x6e, 0x67, 0x65, 0x73, 0x20, 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x62, 0x6f, + 0x72, 0x64, 0x65, 0x72, 0x2d, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x23, 0x30, + 0x22, 0x20, 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x3d, 0x22, 0x30, 0x22, 0x20, + 0x3c, 0x2f, 0x73, 0x70, 0x61, 0x6e, 0x3e, 0x3c, 0x2f, 0x64, 0x69, 0x76, 0x3e, + 0x3c, 0x77, 0x61, 0x73, 0x20, 0x64, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, + 0x65, 0x64, 0x22, 0x20, 0x74, 0x79, 0x70, 0x65, 0x3d, 0x22, 0x74, 0x65, 0x78, + 0x74, 0x22, 0x20, 0x29, 0x3b, 0x0a, 0x3c, 0x2f, 0x73, 0x63, 0x72, 0x69, 0x70, + 0x74, 0x3e, 0x0a, 0x0a, 0x44, 0x65, 0x70, 0x61, 0x72, 0x74, 0x6d, 0x65, 0x6e, + 0x74, 0x20, 0x6f, 0x66, 0x20, 0x65, 0x63, 0x63, 0x6c, 0x65, 0x73, 0x69, 0x61, + 0x73, 0x74, 0x69, 0x63, 0x61, 0x6c, 0x74, 0x68, 0x65, 0x72, 0x65, 0x20, 0x68, + 0x61, 0x73, 0x20, 0x62, 0x65, 0x65, 0x6e, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, + 0x69, 0x6e, 0x67, 0x20, 0x66, 0x72, 0x6f, 0x6d, 0x3c, 0x2f, 0x62, 0x6f, 0x64, + 0x79, 0x3e, 0x3c, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x3e, 0x68, 0x61, 0x73, 0x20, + 0x6e, 0x65, 0x76, 0x65, 0x72, 0x20, 0x62, 0x65, 0x65, 0x6e, 0x74, 0x68, 0x65, + 0x20, 0x66, 0x69, 0x72, 0x73, 0x74, 0x20, 0x74, 0x69, 0x6d, 0x65, 0x69, 0x6e, + 0x20, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x20, 0x74, 0x6f, 0x61, + 0x75, 0x74, 0x6f, 0x6d, 0x61, 0x74, 0x69, 0x63, 0x61, 0x6c, 0x6c, 0x79, 0x20, + 0x3c, 0x2f, 0x64, 0x69, 0x76, 0x3e, 0x0a, 0x0a, 0x3c, 0x64, 0x69, 0x76, 0x20, + 0x69, 0x77, 0x61, 0x73, 0x20, 0x63, 0x6f, 0x6e, 0x73, 0x69, 0x64, 0x65, 0x72, + 0x65, 0x64, 0x70, 0x65, 0x72, 0x63, 0x65, 0x6e, 0x74, 0x20, 0x6f, 0x66, 0x20, + 0x74, 0x68, 0x65, 0x22, 0x20, 0x2f, 0x3e, 0x3c, 0x2f, 0x61, 0x3e, 0x3c, 0x2f, + 0x64, 0x69, 0x76, 0x3e, 0x63, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x20, 0x6f, 0x66, 0x20, 0x64, 0x65, 0x73, 0x63, 0x65, 0x6e, 0x64, 0x65, + 0x64, 0x20, 0x66, 0x72, 0x6f, 0x6d, 0x73, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x61, 0x63, 0x63, 0x65, 0x70, 0x74, + 0x2d, 0x63, 0x68, 0x61, 0x72, 0x73, 0x65, 0x74, 0x74, 0x6f, 0x20, 0x62, 0x65, + 0x20, 0x63, 0x6f, 0x6e, 0x66, 0x75, 0x73, 0x65, 0x64, 0x6d, 0x65, 0x6d, 0x62, + 0x65, 0x72, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x70, 0x61, 0x64, + 0x64, 0x69, 0x6e, 0x67, 0x2d, 0x72, 0x69, 0x67, 0x68, 0x74, 0x3a, 0x74, 0x72, + 0x61, 0x6e, 0x73, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6f, 0x66, 0x69, + 0x6e, 0x74, 0x65, 0x72, 0x70, 0x72, 0x65, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x20, 0x68, 0x72, 0x65, 0x66, 0x3d, 0x27, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, + 0x2f, 0x77, 0x68, 0x65, 0x74, 0x68, 0x65, 0x72, 0x20, 0x6f, 0x72, 0x20, 0x6e, + 0x6f, 0x74, 0x54, 0x68, 0x65, 0x72, 0x65, 0x20, 0x61, 0x72, 0x65, 0x20, 0x61, + 0x6c, 0x73, 0x6f, 0x74, 0x68, 0x65, 0x72, 0x65, 0x20, 0x61, 0x72, 0x65, 0x20, + 0x6d, 0x61, 0x6e, 0x79, 0x61, 0x20, 0x73, 0x6d, 0x61, 0x6c, 0x6c, 0x20, 0x6e, + 0x75, 0x6d, 0x62, 0x65, 0x72, 0x6f, 0x74, 0x68, 0x65, 0x72, 0x20, 0x70, 0x61, + 0x72, 0x74, 0x73, 0x20, 0x6f, 0x66, 0x69, 0x6d, 0x70, 0x6f, 0x73, 0x73, 0x69, + 0x62, 0x6c, 0x65, 0x20, 0x74, 0x6f, 0x20, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, + 0x3d, 0x22, 0x62, 0x75, 0x74, 0x74, 0x6f, 0x6e, 0x6c, 0x6f, 0x63, 0x61, 0x74, + 0x65, 0x64, 0x20, 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x2e, 0x20, 0x48, 0x6f, + 0x77, 0x65, 0x76, 0x65, 0x72, 0x2c, 0x20, 0x74, 0x68, 0x65, 0x61, 0x6e, 0x64, + 0x20, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x75, 0x61, 0x6c, 0x6c, 0x79, 0x41, 0x74, + 0x20, 0x74, 0x68, 0x65, 0x20, 0x65, 0x6e, 0x64, 0x20, 0x6f, 0x66, 0x20, 0x62, + 0x65, 0x63, 0x61, 0x75, 0x73, 0x65, 0x20, 0x6f, 0x66, 0x20, 0x69, 0x74, 0x73, + 0x72, 0x65, 0x70, 0x72, 0x65, 0x73, 0x65, 0x6e, 0x74, 0x73, 0x20, 0x74, 0x68, + 0x65, 0x3c, 0x66, 0x6f, 0x72, 0x6d, 0x20, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x3d, 0x22, 0x20, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x3d, 0x22, 0x70, 0x6f, + 0x73, 0x74, 0x22, 0x69, 0x74, 0x20, 0x69, 0x73, 0x20, 0x70, 0x6f, 0x73, 0x73, + 0x69, 0x62, 0x6c, 0x65, 0x6d, 0x6f, 0x72, 0x65, 0x20, 0x6c, 0x69, 0x6b, 0x65, + 0x6c, 0x79, 0x20, 0x74, 0x6f, 0x61, 0x6e, 0x20, 0x69, 0x6e, 0x63, 0x72, 0x65, + 0x61, 0x73, 0x65, 0x20, 0x69, 0x6e, 0x68, 0x61, 0x76, 0x65, 0x20, 0x61, 0x6c, + 0x73, 0x6f, 0x20, 0x62, 0x65, 0x65, 0x6e, 0x63, 0x6f, 0x72, 0x72, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x64, 0x73, 0x20, 0x74, 0x6f, 0x61, 0x6e, 0x6e, 0x6f, 0x75, + 0x6e, 0x63, 0x65, 0x64, 0x20, 0x74, 0x68, 0x61, 0x74, 0x61, 0x6c, 0x69, 0x67, + 0x6e, 0x3d, 0x22, 0x72, 0x69, 0x67, 0x68, 0x74, 0x22, 0x3e, 0x6d, 0x61, 0x6e, + 0x79, 0x20, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x72, 0x69, 0x65, 0x73, 0x66, 0x6f, + 0x72, 0x20, 0x6d, 0x61, 0x6e, 0x79, 0x20, 0x79, 0x65, 0x61, 0x72, 0x73, 0x65, + 0x61, 0x72, 0x6c, 0x69, 0x65, 0x73, 0x74, 0x20, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, + 0x62, 0x65, 0x63, 0x61, 0x75, 0x73, 0x65, 0x20, 0x69, 0x74, 0x20, 0x77, 0x61, + 0x73, 0x70, 0x74, 0x22, 0x3e, 0x3c, 0x2f, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, + 0x3e, 0x0d, 0x20, 0x76, 0x61, 0x6c, 0x69, 0x67, 0x6e, 0x3d, 0x22, 0x74, 0x6f, + 0x70, 0x22, 0x20, 0x69, 0x6e, 0x68, 0x61, 0x62, 0x69, 0x74, 0x61, 0x6e, 0x74, + 0x73, 0x20, 0x6f, 0x66, 0x66, 0x6f, 0x6c, 0x6c, 0x6f, 0x77, 0x69, 0x6e, 0x67, + 0x20, 0x79, 0x65, 0x61, 0x72, 0x0d, 0x0a, 0x3c, 0x64, 0x69, 0x76, 0x20, 0x63, + 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x22, 0x6d, 0x69, 0x6c, 0x6c, 0x69, 0x6f, 0x6e, + 0x20, 0x70, 0x65, 0x6f, 0x70, 0x6c, 0x65, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, + 0x76, 0x65, 0x72, 0x73, 0x69, 0x61, 0x6c, 0x20, 0x63, 0x6f, 0x6e, 0x63, 0x65, + 0x72, 0x6e, 0x69, 0x6e, 0x67, 0x20, 0x74, 0x68, 0x65, 0x61, 0x72, 0x67, 0x75, + 0x65, 0x20, 0x74, 0x68, 0x61, 0x74, 0x20, 0x74, 0x68, 0x65, 0x67, 0x6f, 0x76, + 0x65, 0x72, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x20, 0x61, 0x6e, 0x64, 0x61, 0x20, + 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x20, 0x74, 0x6f, 0x74, + 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x72, 0x65, 0x64, 0x20, 0x74, 0x6f, + 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x62, 0x69, 0x6e, 0x67, 0x20, 0x74, 0x68, + 0x65, 0x20, 0x73, 0x74, 0x79, 0x6c, 0x65, 0x3d, 0x22, 0x63, 0x6f, 0x6c, 0x6f, + 0x72, 0x3a, 0x61, 0x6c, 0x74, 0x68, 0x6f, 0x75, 0x67, 0x68, 0x20, 0x74, 0x68, + 0x65, 0x72, 0x65, 0x62, 0x65, 0x73, 0x74, 0x20, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, + 0x20, 0x66, 0x6f, 0x72, 0x73, 0x75, 0x62, 0x6d, 0x69, 0x74, 0x22, 0x20, 0x6e, + 0x61, 0x6d, 0x65, 0x3d, 0x22, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x70, 0x6c, 0x69, + 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x6d, 0x6f, 0x72, 0x65, 0x20, 0x74, 0x68, + 0x61, 0x6e, 0x20, 0x6f, 0x6e, 0x65, 0x20, 0x72, 0x65, 0x63, 0x6f, 0x67, 0x6e, + 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6f, 0x66, 0x43, 0x6f, 0x75, 0x6e, 0x63, + 0x69, 0x6c, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x65, 0x64, 0x69, 0x74, + 0x69, 0x6f, 0x6e, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x20, 0x3c, + 0x6d, 0x65, 0x74, 0x61, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x3d, 0x22, 0x45, 0x6e, + 0x74, 0x65, 0x72, 0x74, 0x61, 0x69, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x20, 0x61, + 0x77, 0x61, 0x79, 0x20, 0x66, 0x72, 0x6f, 0x6d, 0x20, 0x74, 0x68, 0x65, 0x20, + 0x3b, 0x6d, 0x61, 0x72, 0x67, 0x69, 0x6e, 0x2d, 0x72, 0x69, 0x67, 0x68, 0x74, + 0x3a, 0x61, 0x74, 0x20, 0x74, 0x68, 0x65, 0x20, 0x74, 0x69, 0x6d, 0x65, 0x20, + 0x6f, 0x66, 0x69, 0x6e, 0x76, 0x65, 0x73, 0x74, 0x69, 0x67, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x73, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x65, 0x64, 0x20, + 0x77, 0x69, 0x74, 0x68, 0x61, 0x6e, 0x64, 0x20, 0x6d, 0x61, 0x6e, 0x79, 0x20, + 0x6f, 0x74, 0x68, 0x65, 0x72, 0x61, 0x6c, 0x74, 0x68, 0x6f, 0x75, 0x67, 0x68, + 0x20, 0x69, 0x74, 0x20, 0x69, 0x73, 0x62, 0x65, 0x67, 0x69, 0x6e, 0x6e, 0x69, + 0x6e, 0x67, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x3c, 0x73, 0x70, 0x61, 0x6e, + 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x22, 0x64, 0x65, 0x73, 0x63, 0x65, + 0x6e, 0x64, 0x61, 0x6e, 0x74, 0x73, 0x20, 0x6f, 0x66, 0x3c, 0x73, 0x70, 0x61, + 0x6e, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x22, 0x69, 0x20, 0x61, 0x6c, + 0x69, 0x67, 0x6e, 0x3d, 0x22, 0x72, 0x69, 0x67, 0x68, 0x74, 0x22, 0x3c, 0x2f, + 0x68, 0x65, 0x61, 0x64, 0x3e, 0x0a, 0x3c, 0x62, 0x6f, 0x64, 0x79, 0x20, 0x61, + 0x73, 0x70, 0x65, 0x63, 0x74, 0x73, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, + 0x68, 0x61, 0x73, 0x20, 0x73, 0x69, 0x6e, 0x63, 0x65, 0x20, 0x62, 0x65, 0x65, + 0x6e, 0x45, 0x75, 0x72, 0x6f, 0x70, 0x65, 0x61, 0x6e, 0x20, 0x55, 0x6e, 0x69, + 0x6f, 0x6e, 0x72, 0x65, 0x6d, 0x69, 0x6e, 0x69, 0x73, 0x63, 0x65, 0x6e, 0x74, + 0x20, 0x6f, 0x66, 0x6d, 0x6f, 0x72, 0x65, 0x20, 0x64, 0x69, 0x66, 0x66, 0x69, + 0x63, 0x75, 0x6c, 0x74, 0x56, 0x69, 0x63, 0x65, 0x20, 0x50, 0x72, 0x65, 0x73, + 0x69, 0x64, 0x65, 0x6e, 0x74, 0x63, 0x6f, 0x6d, 0x70, 0x6f, 0x73, 0x69, 0x74, + 0x69, 0x6f, 0x6e, 0x20, 0x6f, 0x66, 0x70, 0x61, 0x73, 0x73, 0x65, 0x64, 0x20, + 0x74, 0x68, 0x72, 0x6f, 0x75, 0x67, 0x68, 0x6d, 0x6f, 0x72, 0x65, 0x20, 0x69, + 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x61, 0x6e, 0x74, 0x66, 0x6f, 0x6e, 0x74, 0x2d, + 0x73, 0x69, 0x7a, 0x65, 0x3a, 0x31, 0x31, 0x70, 0x78, 0x65, 0x78, 0x70, 0x6c, + 0x61, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6f, 0x66, 0x74, 0x68, 0x65, + 0x20, 0x63, 0x6f, 0x6e, 0x63, 0x65, 0x70, 0x74, 0x20, 0x6f, 0x66, 0x77, 0x72, + 0x69, 0x74, 0x74, 0x65, 0x6e, 0x20, 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x09, + 0x3c, 0x73, 0x70, 0x61, 0x6e, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x22, + 0x69, 0x73, 0x20, 0x6f, 0x6e, 0x65, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, + 0x20, 0x72, 0x65, 0x73, 0x65, 0x6d, 0x62, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x20, + 0x74, 0x6f, 0x6f, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x67, 0x72, 0x6f, 0x75, + 0x6e, 0x64, 0x73, 0x77, 0x68, 0x69, 0x63, 0x68, 0x20, 0x63, 0x6f, 0x6e, 0x74, + 0x61, 0x69, 0x6e, 0x73, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x69, 0x6e, 0x67, + 0x20, 0x74, 0x68, 0x65, 0x20, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x65, 0x64, 0x20, + 0x62, 0x79, 0x20, 0x74, 0x68, 0x65, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6f, 0x66, 0x6d, 0x65, 0x61, 0x6e, 0x73, 0x20, + 0x74, 0x68, 0x61, 0x74, 0x20, 0x74, 0x68, 0x65, 0x6f, 0x75, 0x74, 0x73, 0x69, + 0x64, 0x65, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x73, 0x75, 0x70, 0x70, + 0x6f, 0x72, 0x74, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x3c, 0x69, 0x6e, + 0x70, 0x75, 0x74, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x22, 0x3c, 0x73, + 0x70, 0x61, 0x6e, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x22, 0x74, 0x28, + 0x4d, 0x61, 0x74, 0x68, 0x2e, 0x72, 0x61, 0x6e, 0x64, 0x6f, 0x6d, 0x28, 0x29, + 0x6d, 0x6f, 0x73, 0x74, 0x20, 0x70, 0x72, 0x6f, 0x6d, 0x69, 0x6e, 0x65, 0x6e, + 0x74, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x20, + 0x6f, 0x66, 0x43, 0x6f, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x74, 0x69, 0x6e, 0x6f, + 0x70, 0x6c, 0x65, 0x77, 0x65, 0x72, 0x65, 0x20, 0x70, 0x75, 0x62, 0x6c, 0x69, + 0x73, 0x68, 0x65, 0x64, 0x3c, 0x64, 0x69, 0x76, 0x20, 0x63, 0x6c, 0x61, 0x73, + 0x73, 0x3d, 0x22, 0x73, 0x65, 0x61, 0x70, 0x70, 0x65, 0x61, 0x72, 0x73, 0x20, + 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x31, 0x22, 0x20, 0x68, 0x65, 0x69, 0x67, + 0x68, 0x74, 0x3d, 0x22, 0x31, 0x22, 0x20, 0x6d, 0x6f, 0x73, 0x74, 0x20, 0x69, + 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x61, 0x6e, 0x74, 0x77, 0x68, 0x69, 0x63, 0x68, + 0x20, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x73, 0x77, 0x68, 0x69, 0x63, + 0x68, 0x20, 0x68, 0x61, 0x64, 0x20, 0x62, 0x65, 0x65, 0x6e, 0x64, 0x65, 0x73, + 0x74, 0x72, 0x75, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6f, 0x66, 0x74, 0x68, + 0x65, 0x20, 0x70, 0x6f, 0x70, 0x75, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x0a, + 0x09, 0x3c, 0x64, 0x69, 0x76, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x22, + 0x70, 0x6f, 0x73, 0x73, 0x69, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x20, 0x6f, + 0x66, 0x73, 0x6f, 0x6d, 0x65, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x20, 0x75, 0x73, + 0x65, 0x64, 0x61, 0x70, 0x70, 0x65, 0x61, 0x72, 0x20, 0x74, 0x6f, 0x20, 0x68, + 0x61, 0x76, 0x65, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x20, 0x6f, 0x66, + 0x20, 0x74, 0x68, 0x65, 0x69, 0x6e, 0x74, 0x65, 0x6e, 0x64, 0x65, 0x64, 0x20, + 0x74, 0x6f, 0x20, 0x62, 0x65, 0x70, 0x72, 0x65, 0x73, 0x65, 0x6e, 0x74, 0x20, + 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x73, 0x74, 0x79, 0x6c, 0x65, 0x3d, 0x22, + 0x63, 0x6c, 0x65, 0x61, 0x72, 0x3a, 0x62, 0x0d, 0x0a, 0x3c, 0x2f, 0x73, 0x63, + 0x72, 0x69, 0x70, 0x74, 0x3e, 0x0d, 0x0a, 0x3c, 0x77, 0x61, 0x73, 0x20, 0x66, + 0x6f, 0x75, 0x6e, 0x64, 0x65, 0x64, 0x20, 0x69, 0x6e, 0x69, 0x6e, 0x74, 0x65, + 0x72, 0x76, 0x69, 0x65, 0x77, 0x20, 0x77, 0x69, 0x74, 0x68, 0x5f, 0x69, 0x64, + 0x22, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x3d, 0x22, 0x63, 0x61, + 0x70, 0x69, 0x74, 0x61, 0x6c, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x0d, + 0x0a, 0x3c, 0x6c, 0x69, 0x6e, 0x6b, 0x20, 0x72, 0x65, 0x6c, 0x3d, 0x22, 0x73, + 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, + 0x65, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x20, 0x6f, 0x75, 0x74, 0x20, 0x74, 0x68, + 0x61, 0x74, 0x78, 0x4d, 0x4c, 0x48, 0x74, 0x74, 0x70, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x61, 0x6e, 0x64, 0x20, 0x73, 0x75, 0x62, 0x73, 0x65, 0x71, + 0x75, 0x65, 0x6e, 0x74, 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x20, 0x6c, 0x61, + 0x72, 0x67, 0x65, 0x73, 0x74, 0x76, 0x65, 0x72, 0x79, 0x20, 0x69, 0x6d, 0x70, + 0x6f, 0x72, 0x74, 0x61, 0x6e, 0x74, 0x73, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, + 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x73, 0x75, 0x72, 0x66, 0x61, 0x63, + 0x65, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x61, 0x70, 0x70, 0x6c, 0x69, + 0x65, 0x64, 0x20, 0x74, 0x6f, 0x20, 0x74, 0x68, 0x65, 0x66, 0x6f, 0x72, 0x65, + 0x69, 0x67, 0x6e, 0x20, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x5f, 0x73, 0x65, + 0x74, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x4e, 0x61, 0x6d, 0x65, 0x65, 0x73, + 0x74, 0x61, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x65, 0x64, 0x20, 0x69, 0x6e, 0x69, + 0x73, 0x20, 0x62, 0x65, 0x6c, 0x69, 0x65, 0x76, 0x65, 0x64, 0x20, 0x74, 0x6f, + 0x49, 0x6e, 0x20, 0x61, 0x64, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x74, + 0x6f, 0x6d, 0x65, 0x61, 0x6e, 0x69, 0x6e, 0x67, 0x20, 0x6f, 0x66, 0x20, 0x74, + 0x68, 0x65, 0x69, 0x73, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x64, 0x20, 0x61, 0x66, + 0x74, 0x65, 0x72, 0x74, 0x6f, 0x20, 0x70, 0x72, 0x6f, 0x74, 0x65, 0x63, 0x74, + 0x20, 0x74, 0x68, 0x65, 0x69, 0x73, 0x20, 0x72, 0x65, 0x70, 0x72, 0x65, 0x73, + 0x65, 0x6e, 0x74, 0x65, 0x64, 0x44, 0x65, 0x63, 0x6c, 0x61, 0x72, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x20, 0x6f, 0x66, 0x6d, 0x6f, 0x72, 0x65, 0x20, 0x65, 0x66, + 0x66, 0x69, 0x63, 0x69, 0x65, 0x6e, 0x74, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x69, + 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x6f, 0x74, 0x68, 0x65, 0x72, + 0x20, 0x66, 0x6f, 0x72, 0x6d, 0x73, 0x20, 0x6f, 0x66, 0x68, 0x65, 0x20, 0x72, + 0x65, 0x74, 0x75, 0x72, 0x6e, 0x65, 0x64, 0x20, 0x74, 0x6f, 0x3c, 0x73, 0x70, + 0x61, 0x6e, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x22, 0x63, 0x70, 0x65, + 0x72, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x6e, 0x63, 0x65, 0x20, 0x6f, 0x66, 0x28, + 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x29, 0x20, 0x7b, 0x0d, + 0x69, 0x66, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x6f, 0x6e, 0x6c, 0x79, 0x20, 0x69, + 0x66, 0x72, 0x65, 0x67, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x6f, 0x66, 0x20, 0x74, + 0x68, 0x65, 0x6c, 0x65, 0x61, 0x64, 0x69, 0x6e, 0x67, 0x20, 0x74, 0x6f, 0x20, + 0x74, 0x68, 0x65, 0x72, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, + 0x77, 0x69, 0x74, 0x68, 0x55, 0x6e, 0x69, 0x74, 0x65, 0x64, 0x20, 0x4e, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x73, 0x74, 0x79, 0x6c, 0x65, 0x3d, 0x22, 0x68, + 0x65, 0x69, 0x67, 0x68, 0x74, 0x3a, 0x6f, 0x74, 0x68, 0x65, 0x72, 0x20, 0x74, + 0x68, 0x61, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x79, 0x70, 0x65, 0x22, 0x20, 0x63, + 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x3d, 0x22, 0x41, 0x73, 0x73, 0x6f, 0x63, + 0x69, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6f, 0x66, 0x0a, 0x3c, 0x2f, 0x68, + 0x65, 0x61, 0x64, 0x3e, 0x0a, 0x3c, 0x62, 0x6f, 0x64, 0x79, 0x6c, 0x6f, 0x63, + 0x61, 0x74, 0x65, 0x64, 0x20, 0x6f, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x69, 0x73, + 0x20, 0x72, 0x65, 0x66, 0x65, 0x72, 0x72, 0x65, 0x64, 0x20, 0x74, 0x6f, 0x28, + 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x69, 0x6e, 0x67, 0x20, 0x74, 0x68, 0x65, + 0x63, 0x6f, 0x6e, 0x63, 0x65, 0x6e, 0x74, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x73, 0x74, 0x68, 0x65, 0x20, 0x69, 0x6e, 0x64, 0x69, 0x76, 0x69, 0x64, 0x75, + 0x61, 0x6c, 0x61, 0x6d, 0x6f, 0x6e, 0x67, 0x20, 0x74, 0x68, 0x65, 0x20, 0x6d, + 0x6f, 0x73, 0x74, 0x74, 0x68, 0x61, 0x6e, 0x20, 0x61, 0x6e, 0x79, 0x20, 0x6f, + 0x74, 0x68, 0x65, 0x72, 0x2f, 0x3e, 0x0a, 0x3c, 0x6c, 0x69, 0x6e, 0x6b, 0x20, + 0x72, 0x65, 0x6c, 0x3d, 0x22, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, + 0x66, 0x61, 0x6c, 0x73, 0x65, 0x3b, 0x74, 0x68, 0x65, 0x20, 0x70, 0x75, 0x72, + 0x70, 0x6f, 0x73, 0x65, 0x20, 0x6f, 0x66, 0x74, 0x68, 0x65, 0x20, 0x61, 0x62, + 0x69, 0x6c, 0x69, 0x74, 0x79, 0x20, 0x74, 0x6f, 0x3b, 0x63, 0x6f, 0x6c, 0x6f, + 0x72, 0x3a, 0x23, 0x66, 0x66, 0x66, 0x7d, 0x0a, 0x2e, 0x0a, 0x3c, 0x73, 0x70, + 0x61, 0x6e, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x22, 0x74, 0x68, 0x65, + 0x20, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x20, 0x6f, 0x66, 0x64, 0x65, + 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x6f, 0x66, 0x3e, + 0x0d, 0x0a, 0x3c, 0x6c, 0x69, 0x6e, 0x6b, 0x20, 0x72, 0x65, 0x6c, 0x3d, 0x22, + 0x63, 0x6c, 0x61, 0x69, 0x6d, 0x20, 0x74, 0x68, 0x61, 0x74, 0x20, 0x74, 0x68, + 0x65, 0x68, 0x61, 0x76, 0x65, 0x20, 0x64, 0x65, 0x76, 0x65, 0x6c, 0x6f, 0x70, + 0x65, 0x64, 0x3c, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x20, 0x77, 0x69, 0x64, 0x74, + 0x68, 0x3d, 0x22, 0x63, 0x65, 0x6c, 0x65, 0x62, 0x72, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x20, 0x6f, 0x66, 0x46, 0x6f, 0x6c, 0x6c, 0x6f, 0x77, 0x69, 0x6e, 0x67, + 0x20, 0x74, 0x68, 0x65, 0x20, 0x74, 0x6f, 0x20, 0x64, 0x69, 0x73, 0x74, 0x69, + 0x6e, 0x67, 0x75, 0x69, 0x73, 0x68, 0x3c, 0x73, 0x70, 0x61, 0x6e, 0x20, 0x63, + 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x22, 0x62, 0x74, 0x61, 0x6b, 0x65, 0x73, 0x20, + 0x70, 0x6c, 0x61, 0x63, 0x65, 0x20, 0x69, 0x6e, 0x75, 0x6e, 0x64, 0x65, 0x72, + 0x20, 0x74, 0x68, 0x65, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x6e, 0x6f, 0x74, 0x65, + 0x64, 0x20, 0x74, 0x68, 0x61, 0x74, 0x20, 0x74, 0x68, 0x65, 0x3e, 0x3c, 0x21, + 0x5b, 0x65, 0x6e, 0x64, 0x69, 0x66, 0x5d, 0x2d, 0x2d, 0x3e, 0x0a, 0x73, 0x74, + 0x79, 0x6c, 0x65, 0x3d, 0x22, 0x6d, 0x61, 0x72, 0x67, 0x69, 0x6e, 0x2d, 0x69, + 0x6e, 0x73, 0x74, 0x65, 0x61, 0x64, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, + 0x69, 0x6e, 0x74, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x65, 0x64, 0x20, 0x74, 0x68, + 0x65, 0x74, 0x68, 0x65, 0x20, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x20, + 0x6f, 0x66, 0x69, 0x6e, 0x63, 0x72, 0x65, 0x61, 0x73, 0x69, 0x6e, 0x67, 0x20, + 0x74, 0x68, 0x65, 0x64, 0x69, 0x66, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, + 0x73, 0x20, 0x69, 0x6e, 0x65, 0x73, 0x74, 0x69, 0x6d, 0x61, 0x74, 0x65, 0x64, + 0x20, 0x74, 0x68, 0x61, 0x74, 0x65, 0x73, 0x70, 0x65, 0x63, 0x69, 0x61, 0x6c, + 0x6c, 0x79, 0x20, 0x74, 0x68, 0x65, 0x2f, 0x64, 0x69, 0x76, 0x3e, 0x3c, 0x64, + 0x69, 0x76, 0x20, 0x69, 0x64, 0x3d, 0x22, 0x77, 0x61, 0x73, 0x20, 0x65, 0x76, + 0x65, 0x6e, 0x74, 0x75, 0x61, 0x6c, 0x6c, 0x79, 0x74, 0x68, 0x72, 0x6f, 0x75, + 0x67, 0x68, 0x6f, 0x75, 0x74, 0x20, 0x68, 0x69, 0x73, 0x74, 0x68, 0x65, 0x20, + 0x64, 0x69, 0x66, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x73, 0x6f, 0x6d, + 0x65, 0x74, 0x68, 0x69, 0x6e, 0x67, 0x20, 0x74, 0x68, 0x61, 0x74, 0x73, 0x70, + 0x61, 0x6e, 0x3e, 0x3c, 0x2f, 0x73, 0x70, 0x61, 0x6e, 0x3e, 0x3c, 0x2f, 0x73, + 0x69, 0x67, 0x6e, 0x69, 0x66, 0x69, 0x63, 0x61, 0x6e, 0x74, 0x6c, 0x79, 0x20, + 0x3e, 0x3c, 0x2f, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x3e, 0x0d, 0x0a, 0x0d, + 0x0a, 0x65, 0x6e, 0x76, 0x69, 0x72, 0x6f, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x61, + 0x6c, 0x20, 0x74, 0x6f, 0x20, 0x70, 0x72, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x20, + 0x74, 0x68, 0x65, 0x68, 0x61, 0x76, 0x65, 0x20, 0x62, 0x65, 0x65, 0x6e, 0x20, + 0x75, 0x73, 0x65, 0x64, 0x65, 0x73, 0x70, 0x65, 0x63, 0x69, 0x61, 0x6c, 0x6c, + 0x79, 0x20, 0x66, 0x6f, 0x72, 0x75, 0x6e, 0x64, 0x65, 0x72, 0x73, 0x74, 0x61, + 0x6e, 0x64, 0x20, 0x74, 0x68, 0x65, 0x69, 0x73, 0x20, 0x65, 0x73, 0x73, 0x65, + 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x6c, 0x79, 0x77, 0x65, 0x72, 0x65, 0x20, 0x74, + 0x68, 0x65, 0x20, 0x66, 0x69, 0x72, 0x73, 0x74, 0x69, 0x73, 0x20, 0x74, 0x68, + 0x65, 0x20, 0x6c, 0x61, 0x72, 0x67, 0x65, 0x73, 0x74, 0x68, 0x61, 0x76, 0x65, + 0x20, 0x62, 0x65, 0x65, 0x6e, 0x20, 0x6d, 0x61, 0x64, 0x65, 0x22, 0x20, 0x73, + 0x72, 0x63, 0x3d, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x69, 0x6e, + 0x74, 0x65, 0x72, 0x70, 0x72, 0x65, 0x74, 0x65, 0x64, 0x20, 0x61, 0x73, 0x73, + 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x20, 0x68, 0x61, 0x6c, 0x66, 0x20, 0x6f, 0x66, + 0x63, 0x72, 0x6f, 0x6c, 0x6c, 0x69, 0x6e, 0x67, 0x3d, 0x22, 0x6e, 0x6f, 0x22, + 0x20, 0x69, 0x73, 0x20, 0x63, 0x6f, 0x6d, 0x70, 0x6f, 0x73, 0x65, 0x64, 0x20, + 0x6f, 0x66, 0x49, 0x49, 0x2c, 0x20, 0x48, 0x6f, 0x6c, 0x79, 0x20, 0x52, 0x6f, + 0x6d, 0x61, 0x6e, 0x69, 0x73, 0x20, 0x65, 0x78, 0x70, 0x65, 0x63, 0x74, 0x65, + 0x64, 0x20, 0x74, 0x6f, 0x68, 0x61, 0x76, 0x65, 0x20, 0x74, 0x68, 0x65, 0x69, + 0x72, 0x20, 0x6f, 0x77, 0x6e, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x65, 0x64, 0x20, + 0x61, 0x73, 0x20, 0x74, 0x68, 0x65, 0x74, 0x72, 0x61, 0x64, 0x69, 0x74, 0x69, + 0x6f, 0x6e, 0x61, 0x6c, 0x6c, 0x79, 0x20, 0x68, 0x61, 0x76, 0x65, 0x20, 0x64, + 0x69, 0x66, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x74, 0x61, 0x72, 0x65, 0x20, 0x6f, + 0x66, 0x74, 0x65, 0x6e, 0x20, 0x75, 0x73, 0x65, 0x64, 0x74, 0x6f, 0x20, 0x65, + 0x6e, 0x73, 0x75, 0x72, 0x65, 0x20, 0x74, 0x68, 0x61, 0x74, 0x61, 0x67, 0x72, + 0x65, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x20, 0x77, 0x69, 0x74, 0x68, 0x63, 0x6f, + 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x69, 0x6e, 0x67, 0x20, 0x74, 0x68, 0x65, 0x61, + 0x72, 0x65, 0x20, 0x66, 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x74, 0x6c, 0x79, + 0x69, 0x6e, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6f, + 0x6e, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x20, 0x69, 0x73, 0x20, 0x74, + 0x68, 0x65, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x69, 0x6e, 0x67, 0x20, 0x69, + 0x6e, 0x20, 0x61, 0x3c, 0x2f, 0x61, 0x3e, 0x3c, 0x2f, 0x6c, 0x69, 0x3e, 0x3c, + 0x2f, 0x75, 0x6c, 0x3e, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x22, 0x66, + 0x6f, 0x6f, 0x74, 0x65, 0x72, 0x61, 0x6e, 0x64, 0x20, 0x65, 0x73, 0x70, 0x65, + 0x63, 0x69, 0x61, 0x6c, 0x6c, 0x79, 0x74, 0x79, 0x70, 0x65, 0x3d, 0x22, 0x62, + 0x75, 0x74, 0x74, 0x6f, 0x6e, 0x22, 0x20, 0x3c, 0x2f, 0x73, 0x70, 0x61, 0x6e, + 0x3e, 0x3c, 0x2f, 0x73, 0x70, 0x61, 0x6e, 0x3e, 0x77, 0x68, 0x69, 0x63, 0x68, + 0x20, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x64, 0x3e, 0x0a, 0x3c, 0x6d, + 0x65, 0x74, 0x61, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x3d, 0x22, 0x63, 0x6f, 0x6e, + 0x73, 0x69, 0x64, 0x65, 0x72, 0x65, 0x64, 0x20, 0x74, 0x68, 0x65, 0x63, 0x61, + 0x72, 0x72, 0x69, 0x65, 0x64, 0x20, 0x6f, 0x75, 0x74, 0x20, 0x62, 0x79, 0x48, + 0x6f, 0x77, 0x65, 0x76, 0x65, 0x72, 0x2c, 0x20, 0x69, 0x74, 0x20, 0x69, 0x73, + 0x62, 0x65, 0x63, 0x61, 0x6d, 0x65, 0x20, 0x70, 0x61, 0x72, 0x74, 0x20, 0x6f, + 0x66, 0x69, 0x6e, 0x20, 0x72, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, + 0x74, 0x6f, 0x70, 0x6f, 0x70, 0x75, 0x6c, 0x61, 0x72, 0x20, 0x69, 0x6e, 0x20, + 0x74, 0x68, 0x65, 0x74, 0x68, 0x65, 0x20, 0x63, 0x61, 0x70, 0x69, 0x74, 0x61, + 0x6c, 0x20, 0x6f, 0x66, 0x77, 0x61, 0x73, 0x20, 0x6f, 0x66, 0x66, 0x69, 0x63, + 0x69, 0x61, 0x6c, 0x6c, 0x79, 0x77, 0x68, 0x69, 0x63, 0x68, 0x20, 0x68, 0x61, + 0x73, 0x20, 0x62, 0x65, 0x65, 0x6e, 0x74, 0x68, 0x65, 0x20, 0x48, 0x69, 0x73, + 0x74, 0x6f, 0x72, 0x79, 0x20, 0x6f, 0x66, 0x61, 0x6c, 0x74, 0x65, 0x72, 0x6e, + 0x61, 0x74, 0x69, 0x76, 0x65, 0x20, 0x74, 0x6f, 0x64, 0x69, 0x66, 0x66, 0x65, + 0x72, 0x65, 0x6e, 0x74, 0x20, 0x66, 0x72, 0x6f, 0x6d, 0x74, 0x6f, 0x20, 0x73, + 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x20, 0x74, 0x68, 0x65, 0x73, 0x75, 0x67, + 0x67, 0x65, 0x73, 0x74, 0x65, 0x64, 0x20, 0x74, 0x68, 0x61, 0x74, 0x69, 0x6e, + 0x20, 0x74, 0x68, 0x65, 0x20, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x20, + 0x20, 0x3c, 0x64, 0x69, 0x76, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x22, + 0x74, 0x68, 0x65, 0x20, 0x66, 0x6f, 0x75, 0x6e, 0x64, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x62, 0x65, 0x63, 0x61, 0x75, 0x73, 0x65, 0x20, 0x6f, 0x66, 0x20, 0x68, + 0x69, 0x73, 0x63, 0x6f, 0x6e, 0x63, 0x65, 0x72, 0x6e, 0x65, 0x64, 0x20, 0x77, + 0x69, 0x74, 0x68, 0x74, 0x68, 0x65, 0x20, 0x75, 0x6e, 0x69, 0x76, 0x65, 0x72, + 0x73, 0x69, 0x74, 0x79, 0x6f, 0x70, 0x70, 0x6f, 0x73, 0x65, 0x64, 0x20, 0x74, + 0x6f, 0x20, 0x74, 0x68, 0x65, 0x74, 0x68, 0x65, 0x20, 0x63, 0x6f, 0x6e, 0x74, + 0x65, 0x78, 0x74, 0x20, 0x6f, 0x66, 0x3c, 0x73, 0x70, 0x61, 0x6e, 0x20, 0x63, + 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x22, 0x70, 0x74, 0x65, 0x78, 0x74, 0x22, 0x20, + 0x6e, 0x61, 0x6d, 0x65, 0x3d, 0x22, 0x71, 0x22, 0x09, 0x09, 0x3c, 0x64, 0x69, + 0x76, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x22, 0x74, 0x68, 0x65, 0x20, + 0x73, 0x63, 0x69, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x63, 0x72, 0x65, 0x70, + 0x72, 0x65, 0x73, 0x65, 0x6e, 0x74, 0x65, 0x64, 0x20, 0x62, 0x79, 0x6d, 0x61, + 0x74, 0x68, 0x65, 0x6d, 0x61, 0x74, 0x69, 0x63, 0x69, 0x61, 0x6e, 0x73, 0x65, + 0x6c, 0x65, 0x63, 0x74, 0x65, 0x64, 0x20, 0x62, 0x79, 0x20, 0x74, 0x68, 0x65, + 0x74, 0x68, 0x61, 0x74, 0x20, 0x68, 0x61, 0x76, 0x65, 0x20, 0x62, 0x65, 0x65, + 0x6e, 0x3e, 0x3c, 0x64, 0x69, 0x76, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x3d, + 0x22, 0x63, 0x64, 0x69, 0x76, 0x20, 0x69, 0x64, 0x3d, 0x22, 0x68, 0x65, 0x61, + 0x64, 0x65, 0x72, 0x69, 0x6e, 0x20, 0x70, 0x61, 0x72, 0x74, 0x69, 0x63, 0x75, + 0x6c, 0x61, 0x72, 0x2c, 0x63, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x74, 0x65, 0x64, + 0x20, 0x69, 0x6e, 0x74, 0x6f, 0x29, 0x3b, 0x0a, 0x3c, 0x2f, 0x73, 0x63, 0x72, + 0x69, 0x70, 0x74, 0x3e, 0x0a, 0x3c, 0x70, 0x68, 0x69, 0x6c, 0x6f, 0x73, 0x6f, + 0x70, 0x68, 0x69, 0x63, 0x61, 0x6c, 0x20, 0x73, 0x72, 0x70, 0x73, 0x6b, 0x6f, + 0x68, 0x72, 0x76, 0x61, 0x74, 0x73, 0x6b, 0x69, 0x74, 0x69, 0xe1, 0xba, 0xbf, + 0x6e, 0x67, 0x20, 0x56, 0x69, 0xe1, 0xbb, 0x87, 0x74, 0xd0, 0xa0, 0xd1, 0x83, + 0xd1, 0x81, 0xd1, 0x81, 0xd0, 0xba, 0xd0, 0xb8, 0xd0, 0xb9, 0xd1, 0x80, 0xd1, + 0x83, 0xd1, 0x81, 0xd1, 0x81, 0xd0, 0xba, 0xd0, 0xb8, 0xd0, 0xb9, 0x69, 0x6e, + 0x76, 0x65, 0x73, 0x74, 0x69, 0x67, 0x61, 0x63, 0x69, 0xc3, 0xb3, 0x6e, 0x70, + 0x61, 0x72, 0x74, 0x69, 0x63, 0x69, 0x70, 0x61, 0x63, 0x69, 0xc3, 0xb3, 0x6e, + 0xd0, 0xba, 0xd0, 0xbe, 0xd1, 0x82, 0xd0, 0xbe, 0xd1, 0x80, 0xd1, 0x8b, 0xd0, + 0xb5, 0xd0, 0xbe, 0xd0, 0xb1, 0xd0, 0xbb, 0xd0, 0xb0, 0xd1, 0x81, 0xd1, 0x82, + 0xd0, 0xb8, 0xd0, 0xba, 0xd0, 0xbe, 0xd1, 0x82, 0xd0, 0xbe, 0xd1, 0x80, 0xd1, + 0x8b, 0xd0, 0xb9, 0xd1, 0x87, 0xd0, 0xb5, 0xd0, 0xbb, 0xd0, 0xbe, 0xd0, 0xb2, + 0xd0, 0xb5, 0xd0, 0xba, 0xd1, 0x81, 0xd0, 0xb8, 0xd1, 0x81, 0xd1, 0x82, 0xd0, + 0xb5, 0xd0, 0xbc, 0xd1, 0x8b, 0xd0, 0x9d, 0xd0, 0xbe, 0xd0, 0xb2, 0xd0, 0xbe, + 0xd1, 0x81, 0xd1, 0x82, 0xd0, 0xb8, 0xd0, 0xba, 0xd0, 0xbe, 0xd1, 0x82, 0xd0, + 0xbe, 0xd1, 0x80, 0xd1, 0x8b, 0xd1, 0x85, 0xd0, 0xbe, 0xd0, 0xb1, 0xd0, 0xbb, + 0xd0, 0xb0, 0xd1, 0x81, 0xd1, 0x82, 0xd1, 0x8c, 0xd0, 0xb2, 0xd1, 0x80, 0xd0, + 0xb5, 0xd0, 0xbc, 0xd0, 0xb5, 0xd0, 0xbd, 0xd0, 0xb8, 0xd0, 0xba, 0xd0, 0xbe, + 0xd1, 0x82, 0xd0, 0xbe, 0xd1, 0x80, 0xd0, 0xb0, 0xd1, 0x8f, 0xd1, 0x81, 0xd0, + 0xb5, 0xd0, 0xb3, 0xd0, 0xbe, 0xd0, 0xb4, 0xd0, 0xbd, 0xd1, 0x8f, 0xd1, 0x81, + 0xd0, 0xba, 0xd0, 0xb0, 0xd1, 0x87, 0xd0, 0xb0, 0xd1, 0x82, 0xd1, 0x8c, 0xd0, + 0xbd, 0xd0, 0xbe, 0xd0, 0xb2, 0xd0, 0xbe, 0xd1, 0x81, 0xd1, 0x82, 0xd0, 0xb8, + 0xd0, 0xa3, 0xd0, 0xba, 0xd1, 0x80, 0xd0, 0xb0, 0xd0, 0xb8, 0xd0, 0xbd, 0xd1, + 0x8b, 0xd0, 0xb2, 0xd0, 0xbe, 0xd0, 0xbf, 0xd1, 0x80, 0xd0, 0xbe, 0xd1, 0x81, + 0xd1, 0x8b, 0xd0, 0xba, 0xd0, 0xbe, 0xd1, 0x82, 0xd0, 0xbe, 0xd1, 0x80, 0xd0, + 0xbe, 0xd0, 0xb9, 0xd1, 0x81, 0xd0, 0xb4, 0xd0, 0xb5, 0xd0, 0xbb, 0xd0, 0xb0, + 0xd1, 0x82, 0xd1, 0x8c, 0xd0, 0xbf, 0xd0, 0xbe, 0xd0, 0xbc, 0xd0, 0xbe, 0xd1, + 0x89, 0xd1, 0x8c, 0xd1, 0x8e, 0xd1, 0x81, 0xd1, 0x80, 0xd0, 0xb5, 0xd0, 0xb4, + 0xd1, 0x81, 0xd1, 0x82, 0xd0, 0xb2, 0xd0, 0xbe, 0xd0, 0xb1, 0xd1, 0x80, 0xd0, + 0xb0, 0xd0, 0xb7, 0xd0, 0xbe, 0xd0, 0xbc, 0xd1, 0x81, 0xd1, 0x82, 0xd0, 0xbe, + 0xd1, 0x80, 0xd0, 0xbe, 0xd0, 0xbd, 0xd1, 0x8b, 0xd1, 0x83, 0xd1, 0x87, 0xd0, + 0xb0, 0xd1, 0x81, 0xd1, 0x82, 0xd0, 0xb8, 0xd0, 0xb5, 0xd1, 0x82, 0xd0, 0xb5, + 0xd1, 0x87, 0xd0, 0xb5, 0xd0, 0xbd, 0xd0, 0xb8, 0xd0, 0xb5, 0xd0, 0x93, 0xd0, + 0xbb, 0xd0, 0xb0, 0xd0, 0xb2, 0xd0, 0xbd, 0xd0, 0xb0, 0xd1, 0x8f, 0xd0, 0xb8, + 0xd1, 0x81, 0xd1, 0x82, 0xd0, 0xbe, 0xd1, 0x80, 0xd0, 0xb8, 0xd0, 0xb8, 0xd1, + 0x81, 0xd0, 0xb8, 0xd1, 0x81, 0xd1, 0x82, 0xd0, 0xb5, 0xd0, 0xbc, 0xd0, 0xb0, + 0xd1, 0x80, 0xd0, 0xb5, 0xd1, 0x88, 0xd0, 0xb5, 0xd0, 0xbd, 0xd0, 0xb8, 0xd1, + 0x8f, 0xd0, 0xa1, 0xd0, 0xba, 0xd0, 0xb0, 0xd1, 0x87, 0xd0, 0xb0, 0xd1, 0x82, + 0xd1, 0x8c, 0xd0, 0xbf, 0xd0, 0xbe, 0xd1, 0x8d, 0xd1, 0x82, 0xd0, 0xbe, 0xd0, + 0xbc, 0xd1, 0x83, 0xd1, 0x81, 0xd0, 0xbb, 0xd0, 0xb5, 0xd0, 0xb4, 0xd1, 0x83, + 0xd0, 0xb5, 0xd1, 0x82, 0xd1, 0x81, 0xd0, 0xba, 0xd0, 0xb0, 0xd0, 0xb7, 0xd0, + 0xb0, 0xd1, 0x82, 0xd1, 0x8c, 0xd1, 0x82, 0xd0, 0xbe, 0xd0, 0xb2, 0xd0, 0xb0, + 0xd1, 0x80, 0xd0, 0xbe, 0xd0, 0xb2, 0xd0, 0xba, 0xd0, 0xbe, 0xd0, 0xbd, 0xd0, + 0xb5, 0xd1, 0x87, 0xd0, 0xbd, 0xd0, 0xbe, 0xd1, 0x80, 0xd0, 0xb5, 0xd1, 0x88, + 0xd0, 0xb5, 0xd0, 0xbd, 0xd0, 0xb8, 0xd0, 0xb5, 0xd0, 0xba, 0xd0, 0xbe, 0xd1, + 0x82, 0xd0, 0xbe, 0xd1, 0x80, 0xd0, 0xbe, 0xd0, 0xb5, 0xd0, 0xbe, 0xd1, 0x80, + 0xd0, 0xb3, 0xd0, 0xb0, 0xd0, 0xbd, 0xd0, 0xbe, 0xd0, 0xb2, 0xd0, 0xba, 0xd0, + 0xbe, 0xd1, 0x82, 0xd0, 0xbe, 0xd1, 0x80, 0xd0, 0xbe, 0xd0, 0xbc, 0xd0, 0xa0, + 0xd0, 0xb5, 0xd0, 0xba, 0xd0, 0xbb, 0xd0, 0xb0, 0xd0, 0xbc, 0xd0, 0xb0, 0xd8, + 0xa7, 0xd9, 0x84, 0xd9, 0x85, 0xd9, 0x86, 0xd8, 0xaa, 0xd8, 0xaf, 0xd9, 0x89, + 0xd9, 0x85, 0xd9, 0x86, 0xd8, 0xaa, 0xd8, 0xaf, 0xd9, 0x8a, 0xd8, 0xa7, 0xd8, + 0xaa, 0xd8, 0xa7, 0xd9, 0x84, 0xd9, 0x85, 0xd9, 0x88, 0xd8, 0xb6, 0xd9, 0x88, + 0xd8, 0xb9, 0xd8, 0xa7, 0xd9, 0x84, 0xd8, 0xa8, 0xd8, 0xb1, 0xd8, 0xa7, 0xd9, + 0x85, 0xd8, 0xac, 0xd8, 0xa7, 0xd9, 0x84, 0xd9, 0x85, 0xd9, 0x88, 0xd8, 0xa7, + 0xd9, 0x82, 0xd8, 0xb9, 0xd8, 0xa7, 0xd9, 0x84, 0xd8, 0xb1, 0xd8, 0xb3, 0xd8, + 0xa7, 0xd8, 0xa6, 0xd9, 0x84, 0xd9, 0x85, 0xd8, 0xb4, 0xd8, 0xa7, 0xd8, 0xb1, + 0xd9, 0x83, 0xd8, 0xa7, 0xd8, 0xaa, 0xd8, 0xa7, 0xd9, 0x84, 0xd8, 0xa3, 0xd8, + 0xb9, 0xd8, 0xb6, 0xd8, 0xa7, 0xd8, 0xa1, 0xd8, 0xa7, 0xd9, 0x84, 0xd8, 0xb1, + 0xd9, 0x8a, 0xd8, 0xa7, 0xd8, 0xb6, 0xd8, 0xa9, 0xd8, 0xa7, 0xd9, 0x84, 0xd8, + 0xaa, 0xd8, 0xb5, 0xd9, 0x85, 0xd9, 0x8a, 0xd9, 0x85, 0xd8, 0xa7, 0xd9, 0x84, + 0xd8, 0xa7, 0xd8, 0xb9, 0xd8, 0xb6, 0xd8, 0xa7, 0xd8, 0xa1, 0xd8, 0xa7, 0xd9, + 0x84, 0xd9, 0x86, 0xd8, 0xaa, 0xd8, 0xa7, 0xd8, 0xa6, 0xd8, 0xac, 0xd8, 0xa7, + 0xd9, 0x84, 0xd8, 0xa3, 0xd9, 0x84, 0xd8, 0xb9, 0xd8, 0xa7, 0xd8, 0xa8, 0xd8, + 0xa7, 0xd9, 0x84, 0xd8, 0xaa, 0xd8, 0xb3, 0xd8, 0xac, 0xd9, 0x8a, 0xd9, 0x84, + 0xd8, 0xa7, 0xd9, 0x84, 0xd8, 0xa3, 0xd9, 0x82, 0xd8, 0xb3, 0xd8, 0xa7, 0xd9, + 0x85, 0xd8, 0xa7, 0xd9, 0x84, 0xd8, 0xb6, 0xd8, 0xba, 0xd8, 0xb7, 0xd8, 0xa7, + 0xd8, 0xaa, 0xd8, 0xa7, 0xd9, 0x84, 0xd9, 0x81, 0xd9, 0x8a, 0xd8, 0xaf, 0xd9, + 0x8a, 0xd9, 0x88, 0xd8, 0xa7, 0xd9, 0x84, 0xd8, 0xaa, 0xd8, 0xb1, 0xd8, 0xad, + 0xd9, 0x8a, 0xd8, 0xa8, 0xd8, 0xa7, 0xd9, 0x84, 0xd8, 0xac, 0xd8, 0xaf, 0xd9, + 0x8a, 0xd8, 0xaf, 0xd8, 0xa9, 0xd8, 0xa7, 0xd9, 0x84, 0xd8, 0xaa, 0xd8, 0xb9, + 0xd9, 0x84, 0xd9, 0x8a, 0xd9, 0x85, 0xd8, 0xa7, 0xd9, 0x84, 0xd8, 0xa3, 0xd8, + 0xae, 0xd8, 0xa8, 0xd8, 0xa7, 0xd8, 0xb1, 0xd8, 0xa7, 0xd9, 0x84, 0xd8, 0xa7, + 0xd9, 0x81, 0xd9, 0x84, 0xd8, 0xa7, 0xd9, 0x85, 0xd8, 0xa7, 0xd9, 0x84, 0xd8, + 0xa3, 0xd9, 0x81, 0xd9, 0x84, 0xd8, 0xa7, 0xd9, 0x85, 0xd8, 0xa7, 0xd9, 0x84, + 0xd8, 0xaa, 0xd8, 0xa7, 0xd8, 0xb1, 0xd9, 0x8a, 0xd8, 0xae, 0xd8, 0xa7, 0xd9, + 0x84, 0xd8, 0xaa, 0xd9, 0x82, 0xd9, 0x86, 0xd9, 0x8a, 0xd8, 0xa9, 0xd8, 0xa7, + 0xd9, 0x84, 0xd8, 0xa7, 0xd9, 0x84, 0xd8, 0xb9, 0xd8, 0xa7, 0xd8, 0xa8, 0xd8, + 0xa7, 0xd9, 0x84, 0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xa7, 0xd8, 0xb7, 0xd8, 0xb1, + 0xd8, 0xa7, 0xd9, 0x84, 0xd9, 0x85, 0xd8, 0xac, 0xd8, 0xaa, 0xd9, 0x85, 0xd8, + 0xb9, 0xd8, 0xa7, 0xd9, 0x84, 0xd8, 0xaf, 0xd9, 0x8a, 0xd9, 0x83, 0xd9, 0x88, + 0xd8, 0xb1, 0xd8, 0xa7, 0xd9, 0x84, 0xd8, 0xb3, 0xd9, 0x8a, 0xd8, 0xa7, 0xd8, + 0xad, 0xd8, 0xa9, 0xd8, 0xb9, 0xd8, 0xa8, 0xd8, 0xaf, 0xd8, 0xa7, 0xd9, 0x84, + 0xd9, 0x84, 0xd9, 0x87, 0xd8, 0xa7, 0xd9, 0x84, 0xd8, 0xaa, 0xd8, 0xb1, 0xd8, + 0xa8, 0xd9, 0x8a, 0xd8, 0xa9, 0xd8, 0xa7, 0xd9, 0x84, 0xd8, 0xb1, 0xd9, 0x88, + 0xd8, 0xa7, 0xd8, 0xa8, 0xd8, 0xb7, 0xd8, 0xa7, 0xd9, 0x84, 0xd8, 0xa3, 0xd8, + 0xaf, 0xd8, 0xa8, 0xd9, 0x8a, 0xd8, 0xa9, 0xd8, 0xa7, 0xd9, 0x84, 0xd8, 0xa7, + 0xd8, 0xae, 0xd8, 0xa8, 0xd8, 0xa7, 0xd8, 0xb1, 0xd8, 0xa7, 0xd9, 0x84, 0xd9, + 0x85, 0xd8, 0xaa, 0xd8, 0xad, 0xd8, 0xaf, 0xd8, 0xa9, 0xd8, 0xa7, 0xd9, 0x84, + 0xd8, 0xa7, 0xd8, 0xba, 0xd8, 0xa7, 0xd9, 0x86, 0xd9, 0x8a, 0x63, 0x75, 0x72, + 0x73, 0x6f, 0x72, 0x3a, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x3b, 0x3c, + 0x2f, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x3e, 0x0a, 0x3c, 0x6d, 0x65, 0x74, 0x61, + 0x20, 0x22, 0x20, 0x68, 0x72, 0x65, 0x66, 0x3d, 0x22, 0x68, 0x74, 0x74, 0x70, + 0x3a, 0x2f, 0x2f, 0x22, 0x3e, 0x3c, 0x73, 0x70, 0x61, 0x6e, 0x20, 0x63, 0x6c, + 0x61, 0x73, 0x73, 0x3d, 0x22, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x20, + 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x77, 0x69, 0x6e, 0x64, 0x6f, 0x77, + 0x2e, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x74, + 0x69, 0x63, 0x61, 0x6c, 0x2d, 0x61, 0x6c, 0x69, 0x67, 0x6e, 0x3a, 0x2f, 0x61, + 0x3e, 0x20, 0x7c, 0x20, 0x3c, 0x61, 0x20, 0x68, 0x72, 0x65, 0x66, 0x3d, 0x22, + 0x3c, 0x21, 0x64, 0x6f, 0x63, 0x74, 0x79, 0x70, 0x65, 0x20, 0x68, 0x74, 0x6d, + 0x6c, 0x3e, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x3d, 0x22, 0x73, 0x63, 0x72, 0x65, + 0x65, 0x6e, 0x22, 0x20, 0x3c, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x76, + 0x61, 0x6c, 0x75, 0x65, 0x3d, 0x22, 0x66, 0x61, 0x76, 0x69, 0x63, 0x6f, 0x6e, + 0x2e, 0x69, 0x63, 0x6f, 0x22, 0x20, 0x2f, 0x3e, 0x0a, 0x09, 0x09, 0x3c, 0x64, + 0x69, 0x76, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x22, 0x63, 0x68, 0x61, + 0x72, 0x61, 0x63, 0x74, 0x65, 0x72, 0x69, 0x73, 0x74, 0x69, 0x63, 0x73, 0x22, + 0x20, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x3d, 0x22, 0x67, 0x65, 0x74, 0x22, + 0x20, 0x2f, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0x0a, 0x3c, 0x2f, 0x68, 0x74, 0x6d, + 0x6c, 0x3e, 0x0a, 0x73, 0x68, 0x6f, 0x72, 0x74, 0x63, 0x75, 0x74, 0x20, 0x69, + 0x63, 0x6f, 0x6e, 0x22, 0x20, 0x64, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, + 0x2e, 0x77, 0x72, 0x69, 0x74, 0x65, 0x28, 0x70, 0x61, 0x64, 0x64, 0x69, 0x6e, + 0x67, 0x2d, 0x62, 0x6f, 0x74, 0x74, 0x6f, 0x6d, 0x3a, 0x72, 0x65, 0x70, 0x72, + 0x65, 0x73, 0x65, 0x6e, 0x74, 0x61, 0x74, 0x69, 0x76, 0x65, 0x73, 0x73, 0x75, + 0x62, 0x6d, 0x69, 0x74, 0x22, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3d, 0x22, + 0x61, 0x6c, 0x69, 0x67, 0x6e, 0x3d, 0x22, 0x63, 0x65, 0x6e, 0x74, 0x65, 0x72, + 0x22, 0x20, 0x74, 0x68, 0x72, 0x6f, 0x75, 0x67, 0x68, 0x6f, 0x75, 0x74, 0x20, + 0x74, 0x68, 0x65, 0x20, 0x73, 0x63, 0x69, 0x65, 0x6e, 0x63, 0x65, 0x20, 0x66, + 0x69, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x0a, 0x20, 0x20, 0x3c, 0x64, 0x69, 0x76, + 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x22, 0x73, 0x75, 0x62, 0x6d, 0x69, + 0x74, 0x22, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x22, 0x6f, 0x6e, 0x65, + 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x6d, 0x6f, 0x73, 0x74, 0x20, + 0x76, 0x61, 0x6c, 0x69, 0x67, 0x6e, 0x3d, 0x22, 0x74, 0x6f, 0x70, 0x22, 0x3e, + 0x3c, 0x77, 0x61, 0x73, 0x20, 0x65, 0x73, 0x74, 0x61, 0x62, 0x6c, 0x69, 0x73, + 0x68, 0x65, 0x64, 0x29, 0x3b, 0x0d, 0x0a, 0x3c, 0x2f, 0x73, 0x63, 0x72, 0x69, + 0x70, 0x74, 0x3e, 0x0d, 0x0a, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x66, + 0x61, 0x6c, 0x73, 0x65, 0x3b, 0x22, 0x3e, 0x29, 0x2e, 0x73, 0x74, 0x79, 0x6c, + 0x65, 0x2e, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x62, 0x65, 0x63, 0x61, + 0x75, 0x73, 0x65, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x64, 0x6f, + 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x63, 0x6f, 0x6f, 0x6b, 0x69, 0x65, + 0x3c, 0x66, 0x6f, 0x72, 0x6d, 0x20, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x3d, + 0x22, 0x2f, 0x7d, 0x62, 0x6f, 0x64, 0x79, 0x7b, 0x6d, 0x61, 0x72, 0x67, 0x69, + 0x6e, 0x3a, 0x30, 0x3b, 0x45, 0x6e, 0x63, 0x79, 0x63, 0x6c, 0x6f, 0x70, 0x65, + 0x64, 0x69, 0x61, 0x20, 0x6f, 0x66, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, + 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x2e, 0x63, 0x72, 0x65, 0x61, + 0x74, 0x65, 0x45, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x28, 0x6e, 0x61, 0x6d, + 0x65, 0x22, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x3d, 0x22, 0x3c, + 0x2f, 0x64, 0x69, 0x76, 0x3e, 0x0a, 0x3c, 0x2f, 0x64, 0x69, 0x76, 0x3e, 0x0a, + 0x0a, 0x61, 0x64, 0x6d, 0x69, 0x6e, 0x69, 0x73, 0x74, 0x72, 0x61, 0x74, 0x69, + 0x76, 0x65, 0x20, 0x3c, 0x2f, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0x0a, 0x3c, 0x2f, + 0x68, 0x74, 0x6d, 0x6c, 0x3e, 0x68, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x20, + 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x22, 0x3e, 0x3c, 0x69, 0x6e, 0x70, + 0x75, 0x74, 0x20, 0x74, 0x79, 0x70, 0x65, 0x3d, 0x22, 0x70, 0x6f, 0x72, 0x74, + 0x69, 0x6f, 0x6e, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x61, 0x73, + 0x20, 0x70, 0x61, 0x72, 0x74, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, + 0x26, 0x6e, 0x62, 0x73, 0x70, 0x3b, 0x3c, 0x61, 0x20, 0x68, 0x72, 0x65, 0x66, + 0x3d, 0x22, 0x6f, 0x74, 0x68, 0x65, 0x72, 0x20, 0x63, 0x6f, 0x75, 0x6e, 0x74, + 0x72, 0x69, 0x65, 0x73, 0x22, 0x3e, 0x0a, 0x3c, 0x64, 0x69, 0x76, 0x20, 0x63, + 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x22, 0x3c, 0x2f, 0x73, 0x70, 0x61, 0x6e, 0x3e, + 0x3c, 0x2f, 0x73, 0x70, 0x61, 0x6e, 0x3e, 0x3c, 0x49, 0x6e, 0x20, 0x6f, 0x74, + 0x68, 0x65, 0x72, 0x20, 0x77, 0x6f, 0x72, 0x64, 0x73, 0x2c, 0x64, 0x69, 0x73, + 0x70, 0x6c, 0x61, 0x79, 0x3a, 0x20, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x3b, 0x63, + 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, + 0x20, 0x69, 0x6e, 0x74, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x20, 0x6f, 0x66, 0x2f, 0x3e, 0x0a, 0x3c, 0x6d, 0x65, 0x74, 0x61, 0x20, 0x6e, + 0x61, 0x6d, 0x65, 0x3d, 0x22, 0x61, 0x73, 0x20, 0x77, 0x65, 0x6c, 0x6c, 0x20, + 0x61, 0x73, 0x20, 0x74, 0x68, 0x65, 0x20, 0x69, 0x6e, 0x20, 0x72, 0x65, 0x63, + 0x65, 0x6e, 0x74, 0x20, 0x79, 0x65, 0x61, 0x72, 0x73, 0x0d, 0x0a, 0x09, 0x3c, + 0x64, 0x69, 0x76, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x22, 0x3c, 0x2f, + 0x64, 0x69, 0x76, 0x3e, 0x0a, 0x09, 0x3c, 0x2f, 0x64, 0x69, 0x76, 0x3e, 0x0a, + 0x69, 0x6e, 0x73, 0x70, 0x69, 0x72, 0x65, 0x64, 0x20, 0x62, 0x79, 0x20, 0x74, + 0x68, 0x65, 0x74, 0x68, 0x65, 0x20, 0x65, 0x6e, 0x64, 0x20, 0x6f, 0x66, 0x20, + 0x74, 0x68, 0x65, 0x20, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x74, 0x69, 0x62, 0x6c, + 0x65, 0x20, 0x77, 0x69, 0x74, 0x68, 0x62, 0x65, 0x63, 0x61, 0x6d, 0x65, 0x20, + 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x20, 0x61, 0x73, 0x20, 0x73, 0x74, 0x79, 0x6c, + 0x65, 0x3d, 0x22, 0x6d, 0x61, 0x72, 0x67, 0x69, 0x6e, 0x3a, 0x2e, 0x6a, 0x73, + 0x22, 0x3e, 0x3c, 0x2f, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x3e, 0x3c, 0x20, + 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, + 0x20, 0x74, 0x68, 0x65, 0x72, 0x65, 0x20, 0x68, 0x61, 0x76, 0x65, 0x20, 0x62, + 0x65, 0x65, 0x6e, 0x47, 0x65, 0x72, 0x6d, 0x61, 0x6e, 0x20, 0x6c, 0x61, 0x6e, + 0x67, 0x75, 0x61, 0x67, 0x65, 0x20, 0x73, 0x74, 0x79, 0x6c, 0x65, 0x3d, 0x22, + 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x23, 0x43, 0x6f, 0x6d, 0x6d, 0x75, 0x6e, + 0x69, 0x73, 0x74, 0x20, 0x50, 0x61, 0x72, 0x74, 0x79, 0x63, 0x6f, 0x6e, 0x73, + 0x69, 0x73, 0x74, 0x65, 0x6e, 0x74, 0x20, 0x77, 0x69, 0x74, 0x68, 0x62, 0x6f, + 0x72, 0x64, 0x65, 0x72, 0x3d, 0x22, 0x30, 0x22, 0x20, 0x63, 0x65, 0x6c, 0x6c, + 0x20, 0x6d, 0x61, 0x72, 0x67, 0x69, 0x6e, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, + 0x3d, 0x22, 0x74, 0x68, 0x65, 0x20, 0x6d, 0x61, 0x6a, 0x6f, 0x72, 0x69, 0x74, + 0x79, 0x20, 0x6f, 0x66, 0x22, 0x20, 0x61, 0x6c, 0x69, 0x67, 0x6e, 0x3d, 0x22, + 0x63, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x72, 0x65, 0x6c, 0x61, 0x74, 0x65, 0x64, + 0x20, 0x74, 0x6f, 0x20, 0x74, 0x68, 0x65, 0x20, 0x6d, 0x61, 0x6e, 0x79, 0x20, + 0x64, 0x69, 0x66, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x74, 0x20, 0x4f, 0x72, 0x74, + 0x68, 0x6f, 0x64, 0x6f, 0x78, 0x20, 0x43, 0x68, 0x75, 0x72, 0x63, 0x68, 0x73, + 0x69, 0x6d, 0x69, 0x6c, 0x61, 0x72, 0x20, 0x74, 0x6f, 0x20, 0x74, 0x68, 0x65, + 0x20, 0x2f, 0x3e, 0x0a, 0x3c, 0x6c, 0x69, 0x6e, 0x6b, 0x20, 0x72, 0x65, 0x6c, + 0x3d, 0x22, 0x73, 0x77, 0x61, 0x73, 0x20, 0x6f, 0x6e, 0x65, 0x20, 0x6f, 0x66, + 0x20, 0x74, 0x68, 0x65, 0x20, 0x75, 0x6e, 0x74, 0x69, 0x6c, 0x20, 0x68, 0x69, + 0x73, 0x20, 0x64, 0x65, 0x61, 0x74, 0x68, 0x7d, 0x29, 0x28, 0x29, 0x3b, 0x0a, + 0x3c, 0x2f, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x3e, 0x6f, 0x74, 0x68, 0x65, + 0x72, 0x20, 0x6c, 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, 0x73, 0x63, 0x6f, + 0x6d, 0x70, 0x61, 0x72, 0x65, 0x64, 0x20, 0x74, 0x6f, 0x20, 0x74, 0x68, 0x65, + 0x70, 0x6f, 0x72, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x6f, 0x66, 0x20, 0x74, + 0x68, 0x65, 0x74, 0x68, 0x65, 0x20, 0x4e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x6c, + 0x61, 0x6e, 0x64, 0x73, 0x74, 0x68, 0x65, 0x20, 0x6d, 0x6f, 0x73, 0x74, 0x20, + 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x62, 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, + 0x75, 0x6e, 0x64, 0x3a, 0x75, 0x72, 0x6c, 0x28, 0x61, 0x72, 0x67, 0x75, 0x65, + 0x64, 0x20, 0x74, 0x68, 0x61, 0x74, 0x20, 0x74, 0x68, 0x65, 0x73, 0x63, 0x72, + 0x6f, 0x6c, 0x6c, 0x69, 0x6e, 0x67, 0x3d, 0x22, 0x6e, 0x6f, 0x22, 0x20, 0x69, + 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x64, 0x20, 0x69, 0x6e, 0x20, 0x74, 0x68, + 0x65, 0x4e, 0x6f, 0x72, 0x74, 0x68, 0x20, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, + 0x61, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x20, 0x6f, + 0x66, 0x20, 0x74, 0x68, 0x65, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x70, 0x72, 0x65, + 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x74, 0x68, 0x65, 0x20, 0x74, 0x72, + 0x61, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x64, 0x65, 0x76, 0x65, + 0x6c, 0x6f, 0x70, 0x6d, 0x65, 0x6e, 0x74, 0x20, 0x6f, 0x66, 0x20, 0x66, 0x72, + 0x65, 0x71, 0x75, 0x65, 0x6e, 0x74, 0x6c, 0x79, 0x20, 0x75, 0x73, 0x65, 0x64, + 0x61, 0x20, 0x63, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, + 0x6f, 0x66, 0x76, 0x65, 0x72, 0x79, 0x20, 0x73, 0x69, 0x6d, 0x69, 0x6c, 0x61, + 0x72, 0x20, 0x74, 0x6f, 0x73, 0x75, 0x72, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x69, + 0x6e, 0x67, 0x20, 0x74, 0x68, 0x65, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, + 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x69, 0x73, 0x61, 0x6c, 0x69, 0x67, 0x6e, + 0x3d, 0x22, 0x63, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x22, 0x3e, 0x77, 0x6f, 0x75, + 0x6c, 0x64, 0x20, 0x68, 0x61, 0x76, 0x65, 0x20, 0x62, 0x65, 0x65, 0x6e, 0x69, + 0x6d, 0x61, 0x67, 0x65, 0x5f, 0x63, 0x61, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x20, + 0x3d, 0x61, 0x74, 0x74, 0x61, 0x63, 0x68, 0x65, 0x64, 0x20, 0x74, 0x6f, 0x20, + 0x74, 0x68, 0x65, 0x73, 0x75, 0x67, 0x67, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x67, + 0x20, 0x74, 0x68, 0x61, 0x74, 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x66, + 0x6f, 0x72, 0x6d, 0x20, 0x6f, 0x66, 0x20, 0x69, 0x6e, 0x76, 0x6f, 0x6c, 0x76, + 0x65, 0x64, 0x20, 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x69, 0x73, 0x20, 0x64, + 0x65, 0x72, 0x69, 0x76, 0x65, 0x64, 0x20, 0x66, 0x72, 0x6f, 0x6d, 0x6e, 0x61, + 0x6d, 0x65, 0x64, 0x20, 0x61, 0x66, 0x74, 0x65, 0x72, 0x20, 0x74, 0x68, 0x65, + 0x49, 0x6e, 0x74, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, + 0x74, 0x6f, 0x72, 0x65, 0x73, 0x74, 0x72, 0x69, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x73, 0x20, 0x6f, 0x6e, 0x20, 0x73, 0x74, 0x79, 0x6c, 0x65, 0x3d, 0x22, 0x77, + 0x69, 0x64, 0x74, 0x68, 0x3a, 0x20, 0x63, 0x61, 0x6e, 0x20, 0x62, 0x65, 0x20, + 0x75, 0x73, 0x65, 0x64, 0x20, 0x74, 0x6f, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, + 0x72, 0x65, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6f, 0x66, 0x6d, 0x6f, 0x73, + 0x74, 0x20, 0x69, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x61, 0x6e, 0x74, 0x20, 0x69, + 0x6e, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x61, 0x6e, + 0x64, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x65, 0x64, 0x20, 0x69, 0x6e, 0x20, + 0x74, 0x68, 0x65, 0x63, 0x6f, 0x6c, 0x6c, 0x61, 0x70, 0x73, 0x65, 0x20, 0x6f, + 0x66, 0x20, 0x74, 0x68, 0x65, 0x54, 0x68, 0x69, 0x73, 0x20, 0x6d, 0x65, 0x61, + 0x6e, 0x73, 0x20, 0x74, 0x68, 0x61, 0x74, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x6e, + 0x74, 0x73, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x77, 0x61, 0x73, 0x20, + 0x72, 0x65, 0x70, 0x6c, 0x61, 0x63, 0x65, 0x64, 0x20, 0x62, 0x79, 0x61, 0x6e, + 0x61, 0x6c, 0x79, 0x73, 0x69, 0x73, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, + 0x69, 0x6e, 0x73, 0x70, 0x69, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x66, + 0x6f, 0x72, 0x72, 0x65, 0x67, 0x61, 0x72, 0x64, 0x65, 0x64, 0x20, 0x61, 0x73, + 0x20, 0x74, 0x68, 0x65, 0x6d, 0x6f, 0x73, 0x74, 0x20, 0x73, 0x75, 0x63, 0x63, + 0x65, 0x73, 0x73, 0x66, 0x75, 0x6c, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x20, 0x61, + 0x73, 0x20, 0x26, 0x71, 0x75, 0x6f, 0x74, 0x3b, 0x61, 0x20, 0x63, 0x6f, 0x6d, + 0x70, 0x72, 0x65, 0x68, 0x65, 0x6e, 0x73, 0x69, 0x76, 0x65, 0x48, 0x69, 0x73, + 0x74, 0x6f, 0x72, 0x79, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x77, + 0x65, 0x72, 0x65, 0x20, 0x63, 0x6f, 0x6e, 0x73, 0x69, 0x64, 0x65, 0x72, 0x65, + 0x64, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x65, 0x64, 0x20, 0x74, 0x6f, 0x20, + 0x74, 0x68, 0x65, 0x61, 0x72, 0x65, 0x20, 0x72, 0x65, 0x66, 0x65, 0x72, 0x72, + 0x65, 0x64, 0x20, 0x74, 0x6f, 0x55, 0x6e, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, + 0x64, 0x20, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x3e, 0x0a, 0x09, 0x3c, 0x64, 0x69, + 0x76, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x22, 0x63, 0x6f, 0x6e, 0x73, + 0x69, 0x73, 0x74, 0x73, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x73, 0x74, + 0x6f, 0x70, 0x50, 0x72, 0x6f, 0x70, 0x61, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x69, 0x6e, 0x74, 0x65, 0x72, 0x65, 0x73, 0x74, 0x20, 0x69, 0x6e, 0x20, 0x74, + 0x68, 0x65, 0x61, 0x76, 0x61, 0x69, 0x6c, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, + 0x79, 0x20, 0x6f, 0x66, 0x61, 0x70, 0x70, 0x65, 0x61, 0x72, 0x73, 0x20, 0x74, + 0x6f, 0x20, 0x68, 0x61, 0x76, 0x65, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x72, 0x6f, + 0x6d, 0x61, 0x67, 0x6e, 0x65, 0x74, 0x69, 0x63, 0x65, 0x6e, 0x61, 0x62, 0x6c, + 0x65, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x28, 0x66, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x49, + 0x74, 0x20, 0x69, 0x73, 0x20, 0x69, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x61, 0x6e, + 0x74, 0x3c, 0x2f, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x3e, 0x3c, 0x2f, 0x64, + 0x69, 0x76, 0x3e, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x29, + 0x7b, 0x76, 0x61, 0x72, 0x20, 0x72, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x76, 0x65, + 0x20, 0x74, 0x6f, 0x20, 0x74, 0x68, 0x65, 0x61, 0x73, 0x20, 0x61, 0x20, 0x72, + 0x65, 0x73, 0x75, 0x6c, 0x74, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, + 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6f, 0x66, 0x46, 0x6f, + 0x72, 0x20, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x2c, 0x20, 0x69, 0x6e, + 0x20, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x3d, 0x22, 0x70, 0x6f, 0x73, 0x74, + 0x22, 0x20, 0x77, 0x61, 0x73, 0x20, 0x66, 0x6f, 0x6c, 0x6c, 0x6f, 0x77, 0x65, + 0x64, 0x20, 0x62, 0x79, 0x26, 0x61, 0x6d, 0x70, 0x3b, 0x6d, 0x64, 0x61, 0x73, + 0x68, 0x3b, 0x20, 0x74, 0x68, 0x65, 0x74, 0x68, 0x65, 0x20, 0x61, 0x70, 0x70, + 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x6a, 0x73, 0x22, 0x3e, 0x3c, + 0x2f, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x3e, 0x0d, 0x0a, 0x75, 0x6c, 0x3e, + 0x3c, 0x2f, 0x64, 0x69, 0x76, 0x3e, 0x3c, 0x2f, 0x64, 0x69, 0x76, 0x3e, 0x61, + 0x66, 0x74, 0x65, 0x72, 0x20, 0x74, 0x68, 0x65, 0x20, 0x64, 0x65, 0x61, 0x74, + 0x68, 0x77, 0x69, 0x74, 0x68, 0x20, 0x72, 0x65, 0x73, 0x70, 0x65, 0x63, 0x74, + 0x20, 0x74, 0x6f, 0x73, 0x74, 0x79, 0x6c, 0x65, 0x3d, 0x22, 0x70, 0x61, 0x64, + 0x64, 0x69, 0x6e, 0x67, 0x3a, 0x69, 0x73, 0x20, 0x70, 0x61, 0x72, 0x74, 0x69, + 0x63, 0x75, 0x6c, 0x61, 0x72, 0x6c, 0x79, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, + 0x79, 0x3a, 0x69, 0x6e, 0x6c, 0x69, 0x6e, 0x65, 0x3b, 0x20, 0x74, 0x79, 0x70, + 0x65, 0x3d, 0x22, 0x73, 0x75, 0x62, 0x6d, 0x69, 0x74, 0x22, 0x20, 0x69, 0x73, + 0x20, 0x64, 0x69, 0x76, 0x69, 0x64, 0x65, 0x64, 0x20, 0x69, 0x6e, 0x74, 0x6f, + 0xe4, 0xb8, 0xad, 0xe6, 0x96, 0x87, 0x20, 0x28, 0xe7, 0xae, 0x80, 0xe4, 0xbd, + 0x93, 0x29, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x61, 0x62, 0x69, 0x6c, + 0x69, 0x64, 0x61, 0x64, 0x61, 0x64, 0x6d, 0x69, 0x6e, 0x69, 0x73, 0x74, 0x72, + 0x61, 0x63, 0x69, 0xc3, 0xb3, 0x6e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, + 0x63, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x65, 0x73, 0x63, 0x6f, 0x72, 0x72, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x64, 0x69, 0x65, 0x6e, 0x74, 0x65, 0xe0, 0xa4, 0x89, + 0xe0, 0xa4, 0xaa, 0xe0, 0xa4, 0xaf, 0xe0, 0xa5, 0x8b, 0xe0, 0xa4, 0x97, 0xe0, + 0xa4, 0xaa, 0xe0, 0xa5, 0x82, 0xe0, 0xa4, 0xb0, 0xe0, 0xa5, 0x8d, 0xe0, 0xa4, + 0xb5, 0xe0, 0xa4, 0xb9, 0xe0, 0xa4, 0xae, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, 0xb0, + 0xe0, 0xa5, 0x87, 0xe0, 0xa4, 0xb2, 0xe0, 0xa5, 0x8b, 0xe0, 0xa4, 0x97, 0xe0, + 0xa5, 0x8b, 0xe0, 0xa4, 0x82, 0xe0, 0xa4, 0x9a, 0xe0, 0xa5, 0x81, 0xe0, 0xa4, + 0xa8, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, 0xb5, 0xe0, 0xa4, 0xb2, 0xe0, 0xa5, 0x87, + 0xe0, 0xa4, 0x95, 0xe0, 0xa4, 0xbf, 0xe0, 0xa4, 0xa8, 0xe0, 0xa4, 0xb8, 0xe0, + 0xa4, 0xb0, 0xe0, 0xa4, 0x95, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, 0xb0, 0xe0, 0xa4, + 0xaa, 0xe0, 0xa5, 0x81, 0xe0, 0xa4, 0xb2, 0xe0, 0xa4, 0xbf, 0xe0, 0xa4, 0xb8, + 0xe0, 0xa4, 0x96, 0xe0, 0xa5, 0x8b, 0xe0, 0xa4, 0x9c, 0xe0, 0xa5, 0x87, 0xe0, + 0xa4, 0x82, 0xe0, 0xa4, 0x9a, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, 0xb9, 0xe0, 0xa4, + 0xbf, 0xe0, 0xa4, 0x8f, 0xe0, 0xa4, 0xad, 0xe0, 0xa5, 0x87, 0xe0, 0xa4, 0x9c, + 0xe0, 0xa5, 0x87, 0xe0, 0xa4, 0x82, 0xe0, 0xa4, 0xb6, 0xe0, 0xa4, 0xbe, 0xe0, + 0xa4, 0xae, 0xe0, 0xa4, 0xbf, 0xe0, 0xa4, 0xb2, 0xe0, 0xa4, 0xb9, 0xe0, 0xa4, + 0xae, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, 0xb0, 0xe0, 0xa5, 0x80, 0xe0, 0xa4, 0x9c, + 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, 0x97, 0xe0, 0xa4, 0xb0, 0xe0, 0xa4, 0xa3, 0xe0, + 0xa4, 0xac, 0xe0, 0xa4, 0xa8, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, 0xa8, 0xe0, 0xa5, + 0x87, 0xe0, 0xa4, 0x95, 0xe0, 0xa5, 0x81, 0xe0, 0xa4, 0xae, 0xe0, 0xa4, 0xbe, + 0xe0, 0xa4, 0xb0, 0xe0, 0xa4, 0xac, 0xe0, 0xa5, 0x8d, 0xe0, 0xa4, 0xb2, 0xe0, + 0xa5, 0x89, 0xe0, 0xa4, 0x97, 0xe0, 0xa4, 0xae, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, + 0xb2, 0xe0, 0xa4, 0xbf, 0xe0, 0xa4, 0x95, 0xe0, 0xa4, 0xae, 0xe0, 0xa4, 0xb9, + 0xe0, 0xa4, 0xbf, 0xe0, 0xa4, 0xb2, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, 0xaa, 0xe0, + 0xa5, 0x83, 0xe0, 0xa4, 0xb7, 0xe0, 0xa5, 0x8d, 0xe0, 0xa4, 0xa0, 0xe0, 0xa4, + 0xac, 0xe0, 0xa4, 0xa2, 0xe0, 0xa4, 0xbc, 0xe0, 0xa4, 0xa4, 0xe0, 0xa5, 0x87, + 0xe0, 0xa4, 0xad, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, 0x9c, 0xe0, 0xa4, 0xaa, 0xe0, + 0xa4, 0xbe, 0xe0, 0xa4, 0x95, 0xe0, 0xa5, 0x8d, 0xe0, 0xa4, 0xb2, 0xe0, 0xa4, + 0xbf, 0xe0, 0xa4, 0x95, 0xe0, 0xa4, 0x9f, 0xe0, 0xa5, 0x8d, 0xe0, 0xa4, 0xb0, + 0xe0, 0xa5, 0x87, 0xe0, 0xa4, 0xa8, 0xe0, 0xa4, 0x96, 0xe0, 0xa4, 0xbf, 0xe0, + 0xa4, 0xb2, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, 0xab, 0xe0, 0xa4, 0xa6, 0xe0, 0xa5, + 0x8c, 0xe0, 0xa4, 0xb0, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, 0xa8, 0xe0, 0xa4, 0xae, + 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, 0xae, 0xe0, 0xa4, 0xb2, 0xe0, 0xa5, 0x87, 0xe0, + 0xa4, 0xae, 0xe0, 0xa4, 0xa4, 0xe0, 0xa4, 0xa6, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, + 0xa8, 0xe0, 0xa4, 0xac, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, 0x9c, 0xe0, 0xa4, 0xbe, + 0xe0, 0xa4, 0xb0, 0xe0, 0xa4, 0xb5, 0xe0, 0xa4, 0xbf, 0xe0, 0xa4, 0x95, 0xe0, + 0xa4, 0xbe, 0xe0, 0xa4, 0xb8, 0xe0, 0xa4, 0x95, 0xe0, 0xa5, 0x8d, 0xe0, 0xa4, + 0xaf, 0xe0, 0xa5, 0x8b, 0xe0, 0xa4, 0x82, 0xe0, 0xa4, 0x9a, 0xe0, 0xa4, 0xbe, + 0xe0, 0xa4, 0xb9, 0xe0, 0xa4, 0xa4, 0xe0, 0xa5, 0x87, 0xe0, 0xa4, 0xaa, 0xe0, + 0xa4, 0xb9, 0xe0, 0xa5, 0x81, 0xe0, 0xa4, 0x81, 0xe0, 0xa4, 0x9a, 0xe0, 0xa4, + 0xac, 0xe0, 0xa4, 0xa4, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, 0xaf, 0xe0, 0xa4, 0xbe, + 0xe0, 0xa4, 0xb8, 0xe0, 0xa4, 0x82, 0xe0, 0xa4, 0xb5, 0xe0, 0xa4, 0xbe, 0xe0, + 0xa4, 0xa6, 0xe0, 0xa4, 0xa6, 0xe0, 0xa5, 0x87, 0xe0, 0xa4, 0x96, 0xe0, 0xa4, + 0xa8, 0xe0, 0xa5, 0x87, 0xe0, 0xa4, 0xaa, 0xe0, 0xa4, 0xbf, 0xe0, 0xa4, 0x9b, + 0xe0, 0xa4, 0xb2, 0xe0, 0xa5, 0x87, 0xe0, 0xa4, 0xb5, 0xe0, 0xa4, 0xbf, 0xe0, + 0xa4, 0xb6, 0xe0, 0xa5, 0x87, 0xe0, 0xa4, 0xb7, 0xe0, 0xa4, 0xb0, 0xe0, 0xa4, + 0xbe, 0xe0, 0xa4, 0x9c, 0xe0, 0xa5, 0x8d, 0xe0, 0xa4, 0xaf, 0xe0, 0xa4, 0x89, + 0xe0, 0xa4, 0xa4, 0xe0, 0xa5, 0x8d, 0xe0, 0xa4, 0xa4, 0xe0, 0xa4, 0xb0, 0xe0, + 0xa4, 0xae, 0xe0, 0xa5, 0x81, 0xe0, 0xa4, 0x82, 0xe0, 0xa4, 0xac, 0xe0, 0xa4, + 0x88, 0xe0, 0xa4, 0xa6, 0xe0, 0xa5, 0x8b, 0xe0, 0xa4, 0xa8, 0xe0, 0xa5, 0x8b, + 0xe0, 0xa4, 0x82, 0xe0, 0xa4, 0x89, 0xe0, 0xa4, 0xaa, 0xe0, 0xa4, 0x95, 0xe0, + 0xa4, 0xb0, 0xe0, 0xa4, 0xa3, 0xe0, 0xa4, 0xaa, 0xe0, 0xa4, 0xa2, 0xe0, 0xa4, + 0xbc, 0xe0, 0xa5, 0x87, 0xe0, 0xa4, 0x82, 0xe0, 0xa4, 0xb8, 0xe0, 0xa5, 0x8d, + 0xe0, 0xa4, 0xa5, 0xe0, 0xa4, 0xbf, 0xe0, 0xa4, 0xa4, 0xe0, 0xa4, 0xab, 0xe0, + 0xa4, 0xbf, 0xe0, 0xa4, 0xb2, 0xe0, 0xa5, 0x8d, 0xe0, 0xa4, 0xae, 0xe0, 0xa4, + 0xae, 0xe0, 0xa5, 0x81, 0xe0, 0xa4, 0x96, 0xe0, 0xa5, 0x8d, 0xe0, 0xa4, 0xaf, + 0xe0, 0xa4, 0x85, 0xe0, 0xa4, 0x9a, 0xe0, 0xa5, 0x8d, 0xe0, 0xa4, 0x9b, 0xe0, + 0xa4, 0xbe, 0xe0, 0xa4, 0x9b, 0xe0, 0xa5, 0x82, 0xe0, 0xa4, 0x9f, 0xe0, 0xa4, + 0xa4, 0xe0, 0xa5, 0x80, 0xe0, 0xa4, 0xb8, 0xe0, 0xa4, 0x82, 0xe0, 0xa4, 0x97, + 0xe0, 0xa5, 0x80, 0xe0, 0xa4, 0xa4, 0xe0, 0xa4, 0x9c, 0xe0, 0xa4, 0xbe, 0xe0, + 0xa4, 0x8f, 0xe0, 0xa4, 0x97, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, 0xb5, 0xe0, 0xa4, + 0xbf, 0xe0, 0xa4, 0xad, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, 0x97, 0xe0, 0xa4, 0x98, + 0xe0, 0xa4, 0xa3, 0xe0, 0xa5, 0x8d, 0xe0, 0xa4, 0x9f, 0xe0, 0xa5, 0x87, 0xe0, + 0xa4, 0xa6, 0xe0, 0xa5, 0x82, 0xe0, 0xa4, 0xb8, 0xe0, 0xa4, 0xb0, 0xe0, 0xa5, + 0x87, 0xe0, 0xa4, 0xa6, 0xe0, 0xa4, 0xbf, 0xe0, 0xa4, 0xa8, 0xe0, 0xa5, 0x8b, + 0xe0, 0xa4, 0x82, 0xe0, 0xa4, 0xb9, 0xe0, 0xa4, 0xa4, 0xe0, 0xa5, 0x8d, 0xe0, + 0xa4, 0xaf, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, 0xb8, 0xe0, 0xa5, 0x87, 0xe0, 0xa4, + 0x95, 0xe0, 0xa5, 0x8d, 0xe0, 0xa4, 0xb8, 0xe0, 0xa4, 0x97, 0xe0, 0xa4, 0xbe, + 0xe0, 0xa4, 0x82, 0xe0, 0xa4, 0xa7, 0xe0, 0xa5, 0x80, 0xe0, 0xa4, 0xb5, 0xe0, + 0xa4, 0xbf, 0xe0, 0xa4, 0xb6, 0xe0, 0xa5, 0x8d, 0xe0, 0xa4, 0xb5, 0xe0, 0xa4, + 0xb0, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, 0xa4, 0xe0, 0xa5, 0x87, 0xe0, 0xa4, 0x82, + 0xe0, 0xa4, 0xa6, 0xe0, 0xa5, 0x88, 0xe0, 0xa4, 0x9f, 0xe0, 0xa5, 0x8d, 0xe0, + 0xa4, 0xb8, 0xe0, 0xa4, 0xa8, 0xe0, 0xa4, 0x95, 0xe0, 0xa5, 0x8d, 0xe0, 0xa4, + 0xb6, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, 0xb8, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, 0xae, + 0xe0, 0xa4, 0xa8, 0xe0, 0xa5, 0x87, 0xe0, 0xa4, 0x85, 0xe0, 0xa4, 0xa6, 0xe0, + 0xa4, 0xbe, 0xe0, 0xa4, 0xb2, 0xe0, 0xa4, 0xa4, 0xe0, 0xa4, 0xac, 0xe0, 0xa4, + 0xbf, 0xe0, 0xa4, 0x9c, 0xe0, 0xa4, 0xb2, 0xe0, 0xa5, 0x80, 0xe0, 0xa4, 0xaa, + 0xe0, 0xa5, 0x81, 0xe0, 0xa4, 0xb0, 0xe0, 0xa5, 0x82, 0xe0, 0xa4, 0xb7, 0xe0, + 0xa4, 0xb9, 0xe0, 0xa4, 0xbf, 0xe0, 0xa4, 0x82, 0xe0, 0xa4, 0xa6, 0xe0, 0xa5, + 0x80, 0xe0, 0xa4, 0xae, 0xe0, 0xa4, 0xbf, 0xe0, 0xa4, 0xa4, 0xe0, 0xa5, 0x8d, + 0xe0, 0xa4, 0xb0, 0xe0, 0xa4, 0x95, 0xe0, 0xa4, 0xb5, 0xe0, 0xa4, 0xbf, 0xe0, + 0xa4, 0xa4, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, 0xb0, 0xe0, 0xa5, 0x81, 0xe0, 0xa4, + 0xaa, 0xe0, 0xa4, 0xaf, 0xe0, 0xa5, 0x87, 0xe0, 0xa4, 0xb8, 0xe0, 0xa5, 0x8d, + 0xe0, 0xa4, 0xa5, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, 0xa8, 0xe0, 0xa4, 0x95, 0xe0, + 0xa4, 0xb0, 0xe0, 0xa5, 0x8b, 0xe0, 0xa4, 0xa1, 0xe0, 0xa4, 0xbc, 0xe0, 0xa4, + 0xae, 0xe0, 0xa5, 0x81, 0xe0, 0xa4, 0x95, 0xe0, 0xa5, 0x8d, 0xe0, 0xa4, 0xa4, + 0xe0, 0xa4, 0xaf, 0xe0, 0xa5, 0x8b, 0xe0, 0xa4, 0x9c, 0xe0, 0xa4, 0xa8, 0xe0, + 0xa4, 0xbe, 0xe0, 0xa4, 0x95, 0xe0, 0xa5, 0x83, 0xe0, 0xa4, 0xaa, 0xe0, 0xa4, + 0xaf, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, 0xaa, 0xe0, 0xa5, 0x8b, 0xe0, 0xa4, 0xb8, + 0xe0, 0xa5, 0x8d, 0xe0, 0xa4, 0x9f, 0xe0, 0xa4, 0x98, 0xe0, 0xa4, 0xb0, 0xe0, + 0xa5, 0x87, 0xe0, 0xa4, 0xb2, 0xe0, 0xa5, 0x82, 0xe0, 0xa4, 0x95, 0xe0, 0xa4, + 0xbe, 0xe0, 0xa4, 0xb0, 0xe0, 0xa5, 0x8d, 0xe0, 0xa4, 0xaf, 0xe0, 0xa4, 0xb5, + 0xe0, 0xa4, 0xbf, 0xe0, 0xa4, 0x9a, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, 0xb0, 0xe0, + 0xa4, 0xb8, 0xe0, 0xa5, 0x82, 0xe0, 0xa4, 0x9a, 0xe0, 0xa4, 0xa8, 0xe0, 0xa4, + 0xbe, 0xe0, 0xa4, 0xae, 0xe0, 0xa5, 0x82, 0xe0, 0xa4, 0xb2, 0xe0, 0xa5, 0x8d, + 0xe0, 0xa4, 0xaf, 0xe0, 0xa4, 0xa6, 0xe0, 0xa5, 0x87, 0xe0, 0xa4, 0x96, 0xe0, + 0xa5, 0x87, 0xe0, 0xa4, 0x82, 0xe0, 0xa4, 0xb9, 0xe0, 0xa4, 0xae, 0xe0, 0xa5, + 0x87, 0xe0, 0xa4, 0xb6, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, 0xb8, 0xe0, 0xa5, 0x8d, + 0xe0, 0xa4, 0x95, 0xe0, 0xa5, 0x82, 0xe0, 0xa4, 0xb2, 0xe0, 0xa4, 0xae, 0xe0, + 0xa5, 0x88, 0xe0, 0xa4, 0x82, 0xe0, 0xa4, 0xa8, 0xe0, 0xa5, 0x87, 0xe0, 0xa4, + 0xa4, 0xe0, 0xa5, 0x88, 0xe0, 0xa4, 0xaf, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, 0xb0, + 0xe0, 0xa4, 0x9c, 0xe0, 0xa4, 0xbf, 0xe0, 0xa4, 0xb8, 0xe0, 0xa4, 0x95, 0xe0, + 0xa5, 0x87, 0x72, 0x73, 0x73, 0x2b, 0x78, 0x6d, 0x6c, 0x22, 0x20, 0x74, 0x69, + 0x74, 0x6c, 0x65, 0x3d, 0x22, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x22, 0x20, 0x63, + 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x3d, 0x22, 0x74, 0x69, 0x74, 0x6c, 0x65, + 0x22, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x3d, 0x22, 0x61, 0x74, + 0x20, 0x74, 0x68, 0x65, 0x20, 0x73, 0x61, 0x6d, 0x65, 0x20, 0x74, 0x69, 0x6d, + 0x65, 0x2e, 0x6a, 0x73, 0x22, 0x3e, 0x3c, 0x2f, 0x73, 0x63, 0x72, 0x69, 0x70, + 0x74, 0x3e, 0x0a, 0x3c, 0x22, 0x20, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x3d, + 0x22, 0x70, 0x6f, 0x73, 0x74, 0x22, 0x20, 0x3c, 0x2f, 0x73, 0x70, 0x61, 0x6e, + 0x3e, 0x3c, 0x2f, 0x61, 0x3e, 0x3c, 0x2f, 0x6c, 0x69, 0x3e, 0x76, 0x65, 0x72, + 0x74, 0x69, 0x63, 0x61, 0x6c, 0x2d, 0x61, 0x6c, 0x69, 0x67, 0x6e, 0x3a, 0x74, + 0x2f, 0x6a, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x6d, 0x69, 0x6e, 0x2e, 0x6a, + 0x73, 0x22, 0x3e, 0x2e, 0x63, 0x6c, 0x69, 0x63, 0x6b, 0x28, 0x66, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x20, 0x73, 0x74, 0x79, 0x6c, 0x65, 0x3d, + 0x22, 0x70, 0x61, 0x64, 0x64, 0x69, 0x6e, 0x67, 0x2d, 0x7d, 0x29, 0x28, 0x29, + 0x3b, 0x0a, 0x3c, 0x2f, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x3e, 0x0a, 0x3c, + 0x2f, 0x73, 0x70, 0x61, 0x6e, 0x3e, 0x3c, 0x61, 0x20, 0x68, 0x72, 0x65, 0x66, + 0x3d, 0x22, 0x3c, 0x61, 0x20, 0x68, 0x72, 0x65, 0x66, 0x3d, 0x22, 0x68, 0x74, + 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x29, 0x3b, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, + 0x6e, 0x20, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x3b, 0x74, 0x65, 0x78, 0x74, 0x2d, + 0x64, 0x65, 0x63, 0x6f, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x73, + 0x63, 0x72, 0x6f, 0x6c, 0x6c, 0x69, 0x6e, 0x67, 0x3d, 0x22, 0x6e, 0x6f, 0x22, + 0x20, 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x2d, 0x63, 0x6f, 0x6c, 0x6c, 0x61, + 0x70, 0x73, 0x65, 0x3a, 0x61, 0x73, 0x73, 0x6f, 0x63, 0x69, 0x61, 0x74, 0x65, + 0x64, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x42, 0x61, 0x68, 0x61, 0x73, 0x61, + 0x20, 0x49, 0x6e, 0x64, 0x6f, 0x6e, 0x65, 0x73, 0x69, 0x61, 0x45, 0x6e, 0x67, + 0x6c, 0x69, 0x73, 0x68, 0x20, 0x6c, 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, + 0x3c, 0x74, 0x65, 0x78, 0x74, 0x20, 0x78, 0x6d, 0x6c, 0x3a, 0x73, 0x70, 0x61, + 0x63, 0x65, 0x3d, 0x2e, 0x67, 0x69, 0x66, 0x22, 0x20, 0x62, 0x6f, 0x72, 0x64, + 0x65, 0x72, 0x3d, 0x22, 0x30, 0x22, 0x3c, 0x2f, 0x62, 0x6f, 0x64, 0x79, 0x3e, + 0x0a, 0x3c, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x3e, 0x0a, 0x6f, 0x76, 0x65, 0x72, + 0x66, 0x6c, 0x6f, 0x77, 0x3a, 0x68, 0x69, 0x64, 0x64, 0x65, 0x6e, 0x3b, 0x69, + 0x6d, 0x67, 0x20, 0x73, 0x72, 0x63, 0x3d, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, + 0x2f, 0x2f, 0x61, 0x64, 0x64, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x4c, 0x69, 0x73, + 0x74, 0x65, 0x6e, 0x65, 0x72, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x69, + 0x62, 0x6c, 0x65, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x73, 0x2e, 0x6a, 0x73, 0x22, + 0x3e, 0x3c, 0x2f, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x3e, 0x0a, 0x2f, 0x66, + 0x61, 0x76, 0x69, 0x63, 0x6f, 0x6e, 0x2e, 0x69, 0x63, 0x6f, 0x22, 0x20, 0x2f, + 0x3e, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6e, 0x67, 0x20, 0x73, 0x79, + 0x73, 0x74, 0x65, 0x6d, 0x22, 0x20, 0x73, 0x74, 0x79, 0x6c, 0x65, 0x3d, 0x22, + 0x77, 0x69, 0x64, 0x74, 0x68, 0x3a, 0x31, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, + 0x3d, 0x22, 0x5f, 0x62, 0x6c, 0x61, 0x6e, 0x6b, 0x22, 0x3e, 0x53, 0x74, 0x61, + 0x74, 0x65, 0x20, 0x55, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x69, 0x74, 0x79, + 0x74, 0x65, 0x78, 0x74, 0x2d, 0x61, 0x6c, 0x69, 0x67, 0x6e, 0x3a, 0x6c, 0x65, + 0x66, 0x74, 0x3b, 0x0a, 0x64, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x2e, + 0x77, 0x72, 0x69, 0x74, 0x65, 0x28, 0x2c, 0x20, 0x69, 0x6e, 0x63, 0x6c, 0x75, + 0x64, 0x69, 0x6e, 0x67, 0x20, 0x74, 0x68, 0x65, 0x20, 0x61, 0x72, 0x6f, 0x75, + 0x6e, 0x64, 0x20, 0x74, 0x68, 0x65, 0x20, 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x29, + 0x3b, 0x0d, 0x0a, 0x3c, 0x2f, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x3e, 0x0d, + 0x0a, 0x3c, 0x22, 0x20, 0x73, 0x74, 0x79, 0x6c, 0x65, 0x3d, 0x22, 0x68, 0x65, + 0x69, 0x67, 0x68, 0x74, 0x3a, 0x3b, 0x6f, 0x76, 0x65, 0x72, 0x66, 0x6c, 0x6f, + 0x77, 0x3a, 0x68, 0x69, 0x64, 0x64, 0x65, 0x6e, 0x6d, 0x6f, 0x72, 0x65, 0x20, + 0x69, 0x6e, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6e, + 0x20, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x61, + 0x6c, 0x61, 0x20, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x20, 0x6f, 0x66, 0x20, + 0x74, 0x68, 0x65, 0x20, 0x6f, 0x6e, 0x65, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, + 0x65, 0x20, 0x66, 0x69, 0x72, 0x73, 0x74, 0x63, 0x61, 0x6e, 0x20, 0x62, 0x65, + 0x20, 0x66, 0x6f, 0x75, 0x6e, 0x64, 0x20, 0x69, 0x6e, 0x20, 0x3c, 0x2f, 0x64, + 0x69, 0x76, 0x3e, 0x0a, 0x09, 0x09, 0x3c, 0x2f, 0x64, 0x69, 0x76, 0x3e, 0x0a, + 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x3a, 0x20, 0x6e, 0x6f, 0x6e, 0x65, + 0x3b, 0x22, 0x3e, 0x22, 0x20, 0x2f, 0x3e, 0x0a, 0x3c, 0x6c, 0x69, 0x6e, 0x6b, + 0x20, 0x72, 0x65, 0x6c, 0x3d, 0x22, 0x0a, 0x20, 0x20, 0x28, 0x66, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x29, 0x20, 0x7b, 0x74, 0x68, 0x65, 0x20, + 0x31, 0x35, 0x74, 0x68, 0x20, 0x63, 0x65, 0x6e, 0x74, 0x75, 0x72, 0x79, 0x2e, + 0x70, 0x72, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x44, 0x65, 0x66, 0x61, 0x75, 0x6c, + 0x74, 0x28, 0x6c, 0x61, 0x72, 0x67, 0x65, 0x20, 0x6e, 0x75, 0x6d, 0x62, 0x65, + 0x72, 0x20, 0x6f, 0x66, 0x20, 0x42, 0x79, 0x7a, 0x61, 0x6e, 0x74, 0x69, 0x6e, + 0x65, 0x20, 0x45, 0x6d, 0x70, 0x69, 0x72, 0x65, 0x2e, 0x6a, 0x70, 0x67, 0x7c, + 0x74, 0x68, 0x75, 0x6d, 0x62, 0x7c, 0x6c, 0x65, 0x66, 0x74, 0x7c, 0x76, 0x61, + 0x73, 0x74, 0x20, 0x6d, 0x61, 0x6a, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x20, 0x6f, + 0x66, 0x6d, 0x61, 0x6a, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x20, 0x6f, 0x66, 0x20, + 0x74, 0x68, 0x65, 0x20, 0x20, 0x61, 0x6c, 0x69, 0x67, 0x6e, 0x3d, 0x22, 0x63, + 0x65, 0x6e, 0x74, 0x65, 0x72, 0x22, 0x3e, 0x55, 0x6e, 0x69, 0x76, 0x65, 0x72, + 0x73, 0x69, 0x74, 0x79, 0x20, 0x50, 0x72, 0x65, 0x73, 0x73, 0x64, 0x6f, 0x6d, + 0x69, 0x6e, 0x61, 0x74, 0x65, 0x64, 0x20, 0x62, 0x79, 0x20, 0x74, 0x68, 0x65, + 0x53, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x20, 0x57, 0x6f, 0x72, 0x6c, 0x64, 0x20, + 0x57, 0x61, 0x72, 0x64, 0x69, 0x73, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x69, + 0x6f, 0x6e, 0x20, 0x6f, 0x66, 0x20, 0x73, 0x74, 0x79, 0x6c, 0x65, 0x3d, 0x22, + 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x74, 0x68, 0x65, 0x20, + 0x72, 0x65, 0x73, 0x74, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, + 0x68, 0x61, 0x72, 0x61, 0x63, 0x74, 0x65, 0x72, 0x69, 0x7a, 0x65, 0x64, 0x20, + 0x62, 0x79, 0x20, 0x72, 0x65, 0x6c, 0x3d, 0x22, 0x6e, 0x6f, 0x66, 0x6f, 0x6c, + 0x6c, 0x6f, 0x77, 0x22, 0x3e, 0x64, 0x65, 0x72, 0x69, 0x76, 0x65, 0x73, 0x20, + 0x66, 0x72, 0x6f, 0x6d, 0x20, 0x74, 0x68, 0x65, 0x72, 0x61, 0x74, 0x68, 0x65, + 0x72, 0x20, 0x74, 0x68, 0x61, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x61, 0x20, + 0x63, 0x6f, 0x6d, 0x62, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6f, + 0x66, 0x73, 0x74, 0x79, 0x6c, 0x65, 0x3d, 0x22, 0x77, 0x69, 0x64, 0x74, 0x68, + 0x3a, 0x31, 0x30, 0x30, 0x45, 0x6e, 0x67, 0x6c, 0x69, 0x73, 0x68, 0x2d, 0x73, + 0x70, 0x65, 0x61, 0x6b, 0x69, 0x6e, 0x67, 0x63, 0x6f, 0x6d, 0x70, 0x75, 0x74, + 0x65, 0x72, 0x20, 0x73, 0x63, 0x69, 0x65, 0x6e, 0x63, 0x65, 0x62, 0x6f, 0x72, + 0x64, 0x65, 0x72, 0x3d, 0x22, 0x30, 0x22, 0x20, 0x61, 0x6c, 0x74, 0x3d, 0x22, + 0x74, 0x68, 0x65, 0x20, 0x65, 0x78, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x63, 0x65, + 0x20, 0x6f, 0x66, 0x44, 0x65, 0x6d, 0x6f, 0x63, 0x72, 0x61, 0x74, 0x69, 0x63, + 0x20, 0x50, 0x61, 0x72, 0x74, 0x79, 0x22, 0x20, 0x73, 0x74, 0x79, 0x6c, 0x65, + 0x3d, 0x22, 0x6d, 0x61, 0x72, 0x67, 0x69, 0x6e, 0x2d, 0x46, 0x6f, 0x72, 0x20, + 0x74, 0x68, 0x69, 0x73, 0x20, 0x72, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x2c, 0x2e, + 0x6a, 0x73, 0x22, 0x3e, 0x3c, 0x2f, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x3e, + 0x0a, 0x09, 0x73, 0x42, 0x79, 0x54, 0x61, 0x67, 0x4e, 0x61, 0x6d, 0x65, 0x28, + 0x73, 0x29, 0x5b, 0x30, 0x5d, 0x6a, 0x73, 0x22, 0x3e, 0x3c, 0x2f, 0x73, 0x63, + 0x72, 0x69, 0x70, 0x74, 0x3e, 0x0d, 0x0a, 0x3c, 0x2e, 0x6a, 0x73, 0x22, 0x3e, + 0x3c, 0x2f, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x3e, 0x0d, 0x0a, 0x6c, 0x69, + 0x6e, 0x6b, 0x20, 0x72, 0x65, 0x6c, 0x3d, 0x22, 0x69, 0x63, 0x6f, 0x6e, 0x22, + 0x20, 0x27, 0x20, 0x61, 0x6c, 0x74, 0x3d, 0x27, 0x27, 0x20, 0x63, 0x6c, 0x61, + 0x73, 0x73, 0x3d, 0x27, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, + 0x6e, 0x73, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x3c, 0x2f, 0x61, + 0x3e, 0x3c, 0x2f, 0x64, 0x69, 0x76, 0x3e, 0x3c, 0x2f, 0x64, 0x69, 0x76, 0x3e, + 0x2f, 0x70, 0x61, 0x67, 0x65, 0x3e, 0x0a, 0x20, 0x20, 0x3c, 0x70, 0x61, 0x67, + 0x65, 0x3e, 0x0a, 0x3c, 0x64, 0x69, 0x76, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, + 0x3d, 0x22, 0x63, 0x6f, 0x6e, 0x74, 0x62, 0x65, 0x63, 0x61, 0x6d, 0x65, 0x20, + 0x74, 0x68, 0x65, 0x20, 0x66, 0x69, 0x72, 0x73, 0x74, 0x62, 0x61, 0x68, 0x61, + 0x73, 0x61, 0x20, 0x49, 0x6e, 0x64, 0x6f, 0x6e, 0x65, 0x73, 0x69, 0x61, 0x65, + 0x6e, 0x67, 0x6c, 0x69, 0x73, 0x68, 0x20, 0x28, 0x73, 0x69, 0x6d, 0x70, 0x6c, + 0x65, 0x29, 0xce, 0x95, 0xce, 0xbb, 0xce, 0xbb, 0xce, 0xb7, 0xce, 0xbd, 0xce, + 0xb9, 0xce, 0xba, 0xce, 0xac, 0xd1, 0x85, 0xd1, 0x80, 0xd0, 0xb2, 0xd0, 0xb0, + 0xd1, 0x82, 0xd1, 0x81, 0xd0, 0xba, 0xd0, 0xb8, 0xd0, 0xba, 0xd0, 0xbe, 0xd0, + 0xbc, 0xd0, 0xbf, 0xd0, 0xb0, 0xd0, 0xbd, 0xd0, 0xb8, 0xd0, 0xb8, 0xd1, 0x8f, + 0xd0, 0xb2, 0xd0, 0xbb, 0xd1, 0x8f, 0xd0, 0xb5, 0xd1, 0x82, 0xd1, 0x81, 0xd1, + 0x8f, 0xd0, 0x94, 0xd0, 0xbe, 0xd0, 0xb1, 0xd0, 0xb0, 0xd0, 0xb2, 0xd0, 0xb8, + 0xd1, 0x82, 0xd1, 0x8c, 0xd1, 0x87, 0xd0, 0xb5, 0xd0, 0xbb, 0xd0, 0xbe, 0xd0, + 0xb2, 0xd0, 0xb5, 0xd0, 0xba, 0xd0, 0xb0, 0xd1, 0x80, 0xd0, 0xb0, 0xd0, 0xb7, + 0xd0, 0xb2, 0xd0, 0xb8, 0xd1, 0x82, 0xd0, 0xb8, 0xd1, 0x8f, 0xd0, 0x98, 0xd0, + 0xbd, 0xd1, 0x82, 0xd0, 0xb5, 0xd1, 0x80, 0xd0, 0xbd, 0xd0, 0xb5, 0xd1, 0x82, + 0xd0, 0x9e, 0xd1, 0x82, 0xd0, 0xb2, 0xd0, 0xb5, 0xd1, 0x82, 0xd0, 0xb8, 0xd1, + 0x82, 0xd1, 0x8c, 0xd0, 0xbd, 0xd0, 0xb0, 0xd0, 0xbf, 0xd1, 0x80, 0xd0, 0xb8, + 0xd0, 0xbc, 0xd0, 0xb5, 0xd1, 0x80, 0xd0, 0xb8, 0xd0, 0xbd, 0xd1, 0x82, 0xd0, + 0xb5, 0xd1, 0x80, 0xd0, 0xbd, 0xd0, 0xb5, 0xd1, 0x82, 0xd0, 0xba, 0xd0, 0xbe, + 0xd1, 0x82, 0xd0, 0xbe, 0xd1, 0x80, 0xd0, 0xbe, 0xd0, 0xb3, 0xd0, 0xbe, 0xd1, + 0x81, 0xd1, 0x82, 0xd1, 0x80, 0xd0, 0xb0, 0xd0, 0xbd, 0xd0, 0xb8, 0xd1, 0x86, + 0xd1, 0x8b, 0xd0, 0xba, 0xd0, 0xb0, 0xd1, 0x87, 0xd0, 0xb5, 0xd1, 0x81, 0xd1, + 0x82, 0xd0, 0xb2, 0xd0, 0xb5, 0xd1, 0x83, 0xd1, 0x81, 0xd0, 0xbb, 0xd0, 0xbe, + 0xd0, 0xb2, 0xd0, 0xb8, 0xd1, 0x8f, 0xd1, 0x85, 0xd0, 0xbf, 0xd1, 0x80, 0xd0, + 0xbe, 0xd0, 0xb1, 0xd0, 0xbb, 0xd0, 0xb5, 0xd0, 0xbc, 0xd1, 0x8b, 0xd0, 0xbf, + 0xd0, 0xbe, 0xd0, 0xbb, 0xd1, 0x83, 0xd1, 0x87, 0xd0, 0xb8, 0xd1, 0x82, 0xd1, + 0x8c, 0xd1, 0x8f, 0xd0, 0xb2, 0xd0, 0xbb, 0xd1, 0x8f, 0xd1, 0x8e, 0xd1, 0x82, + 0xd1, 0x81, 0xd1, 0x8f, 0xd0, 0xbd, 0xd0, 0xb0, 0xd0, 0xb8, 0xd0, 0xb1, 0xd0, + 0xbe, 0xd0, 0xbb, 0xd0, 0xb5, 0xd0, 0xb5, 0xd0, 0xba, 0xd0, 0xbe, 0xd0, 0xbc, + 0xd0, 0xbf, 0xd0, 0xb0, 0xd0, 0xbd, 0xd0, 0xb8, 0xd1, 0x8f, 0xd0, 0xb2, 0xd0, + 0xbd, 0xd0, 0xb8, 0xd0, 0xbc, 0xd0, 0xb0, 0xd0, 0xbd, 0xd0, 0xb8, 0xd0, 0xb5, + 0xd1, 0x81, 0xd1, 0x80, 0xd0, 0xb5, 0xd0, 0xb4, 0xd1, 0x81, 0xd1, 0x82, 0xd0, + 0xb2, 0xd0, 0xb0, 0xd8, 0xa7, 0xd9, 0x84, 0xd9, 0x85, 0xd9, 0x88, 0xd8, 0xa7, + 0xd8, 0xb6, 0xd9, 0x8a, 0xd8, 0xb9, 0xd8, 0xa7, 0xd9, 0x84, 0xd8, 0xb1, 0xd8, + 0xa6, 0xd9, 0x8a, 0xd8, 0xb3, 0xd9, 0x8a, 0xd8, 0xa9, 0xd8, 0xa7, 0xd9, 0x84, + 0xd8, 0xa7, 0xd9, 0x86, 0xd8, 0xaa, 0xd9, 0x82, 0xd8, 0xa7, 0xd9, 0x84, 0xd9, + 0x85, 0xd8, 0xb4, 0xd8, 0xa7, 0xd8, 0xb1, 0xd9, 0x83, 0xd8, 0xa7, 0xd8, 0xaa, + 0xd9, 0x83, 0xd8, 0xa7, 0xd9, 0x84, 0xd8, 0xb3, 0xd9, 0x8a, 0xd8, 0xa7, 0xd8, + 0xb1, 0xd8, 0xa7, 0xd8, 0xaa, 0xd8, 0xa7, 0xd9, 0x84, 0xd9, 0x85, 0xd9, 0x83, + 0xd8, 0xaa, 0xd9, 0x88, 0xd8, 0xa8, 0xd8, 0xa9, 0xd8, 0xa7, 0xd9, 0x84, 0xd8, + 0xb3, 0xd8, 0xb9, 0xd9, 0x88, 0xd8, 0xaf, 0xd9, 0x8a, 0xd8, 0xa9, 0xd8, 0xa7, + 0xd8, 0xad, 0xd8, 0xb5, 0xd8, 0xa7, 0xd8, 0xa6, 0xd9, 0x8a, 0xd8, 0xa7, 0xd8, + 0xaa, 0xd8, 0xa7, 0xd9, 0x84, 0xd8, 0xb9, 0xd8, 0xa7, 0xd9, 0x84, 0xd9, 0x85, + 0xd9, 0x8a, 0xd8, 0xa9, 0xd8, 0xa7, 0xd9, 0x84, 0xd8, 0xb5, 0xd9, 0x88, 0xd8, + 0xaa, 0xd9, 0x8a, 0xd8, 0xa7, 0xd8, 0xaa, 0xd8, 0xa7, 0xd9, 0x84, 0xd8, 0xa7, + 0xd9, 0x86, 0xd8, 0xaa, 0xd8, 0xb1, 0xd9, 0x86, 0xd8, 0xaa, 0xd8, 0xa7, 0xd9, + 0x84, 0xd8, 0xaa, 0xd8, 0xb5, 0xd8, 0xa7, 0xd9, 0x85, 0xd9, 0x8a, 0xd9, 0x85, + 0xd8, 0xa7, 0xd9, 0x84, 0xd8, 0xa5, 0xd8, 0xb3, 0xd9, 0x84, 0xd8, 0xa7, 0xd9, + 0x85, 0xd9, 0x8a, 0xd8, 0xa7, 0xd9, 0x84, 0xd9, 0x85, 0xd8, 0xb4, 0xd8, 0xa7, + 0xd8, 0xb1, 0xd9, 0x83, 0xd8, 0xa9, 0xd8, 0xa7, 0xd9, 0x84, 0xd9, 0x85, 0xd8, + 0xb1, 0xd8, 0xa6, 0xd9, 0x8a, 0xd8, 0xa7, 0xd8, 0xaa, 0x72, 0x6f, 0x62, 0x6f, + 0x74, 0x73, 0x22, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x3d, 0x22, + 0x3c, 0x64, 0x69, 0x76, 0x20, 0x69, 0x64, 0x3d, 0x22, 0x66, 0x6f, 0x6f, 0x74, + 0x65, 0x72, 0x22, 0x3e, 0x74, 0x68, 0x65, 0x20, 0x55, 0x6e, 0x69, 0x74, 0x65, + 0x64, 0x20, 0x53, 0x74, 0x61, 0x74, 0x65, 0x73, 0x3c, 0x69, 0x6d, 0x67, 0x20, + 0x73, 0x72, 0x63, 0x3d, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x2e, + 0x6a, 0x70, 0x67, 0x7c, 0x72, 0x69, 0x67, 0x68, 0x74, 0x7c, 0x74, 0x68, 0x75, + 0x6d, 0x62, 0x7c, 0x2e, 0x6a, 0x73, 0x22, 0x3e, 0x3c, 0x2f, 0x73, 0x63, 0x72, + 0x69, 0x70, 0x74, 0x3e, 0x0d, 0x0a, 0x3c, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x66, 0x72, + 0x61, 0x6d, 0x65, 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x3d, 0x22, 0x30, 0x22, + 0x20, 0x73, 0x22, 0x20, 0x2f, 0x3e, 0x0a, 0x3c, 0x6d, 0x65, 0x74, 0x61, 0x20, + 0x6e, 0x61, 0x6d, 0x65, 0x3d, 0x22, 0x3c, 0x2f, 0x61, 0x3e, 0x3c, 0x2f, 0x64, + 0x69, 0x76, 0x3e, 0x3c, 0x2f, 0x64, 0x69, 0x76, 0x3e, 0x3c, 0x66, 0x6f, 0x6e, + 0x74, 0x2d, 0x77, 0x65, 0x69, 0x67, 0x68, 0x74, 0x3a, 0x62, 0x6f, 0x6c, 0x64, + 0x3b, 0x26, 0x71, 0x75, 0x6f, 0x74, 0x3b, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x26, + 0x71, 0x75, 0x6f, 0x74, 0x3b, 0x64, 0x65, 0x70, 0x65, 0x6e, 0x64, 0x69, 0x6e, + 0x67, 0x20, 0x6f, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x6d, 0x61, 0x72, 0x67, + 0x69, 0x6e, 0x3a, 0x30, 0x3b, 0x70, 0x61, 0x64, 0x64, 0x69, 0x6e, 0x67, 0x3a, + 0x22, 0x20, 0x72, 0x65, 0x6c, 0x3d, 0x22, 0x6e, 0x6f, 0x66, 0x6f, 0x6c, 0x6c, + 0x6f, 0x77, 0x22, 0x20, 0x50, 0x72, 0x65, 0x73, 0x69, 0x64, 0x65, 0x6e, 0x74, + 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x74, 0x77, 0x65, 0x6e, 0x74, + 0x69, 0x65, 0x74, 0x68, 0x20, 0x63, 0x65, 0x6e, 0x74, 0x75, 0x72, 0x79, 0x65, + 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x3e, 0x0a, 0x20, 0x20, 0x3c, 0x2f, 0x70, + 0x61, 0x67, 0x65, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x20, 0x45, + 0x78, 0x70, 0x6c, 0x6f, 0x72, 0x65, 0x72, 0x61, 0x2e, 0x61, 0x73, 0x79, 0x6e, + 0x63, 0x20, 0x3d, 0x20, 0x74, 0x72, 0x75, 0x65, 0x3b, 0x0d, 0x0a, 0x69, 0x6e, + 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x61, 0x62, 0x6f, + 0x75, 0x74, 0x3c, 0x64, 0x69, 0x76, 0x20, 0x69, 0x64, 0x3d, 0x22, 0x68, 0x65, + 0x61, 0x64, 0x65, 0x72, 0x22, 0x3e, 0x22, 0x20, 0x61, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x3d, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x3c, 0x61, 0x20, + 0x68, 0x72, 0x65, 0x66, 0x3d, 0x22, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, + 0x2f, 0x3c, 0x64, 0x69, 0x76, 0x20, 0x69, 0x64, 0x3d, 0x22, 0x63, 0x6f, 0x6e, + 0x74, 0x65, 0x6e, 0x74, 0x22, 0x3c, 0x2f, 0x64, 0x69, 0x76, 0x3e, 0x0d, 0x0a, + 0x3c, 0x2f, 0x64, 0x69, 0x76, 0x3e, 0x0d, 0x0a, 0x3c, 0x64, 0x65, 0x72, 0x69, + 0x76, 0x65, 0x64, 0x20, 0x66, 0x72, 0x6f, 0x6d, 0x20, 0x74, 0x68, 0x65, 0x20, + 0x3c, 0x69, 0x6d, 0x67, 0x20, 0x73, 0x72, 0x63, 0x3d, 0x27, 0x68, 0x74, 0x74, + 0x70, 0x3a, 0x2f, 0x2f, 0x61, 0x63, 0x63, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x67, + 0x20, 0x74, 0x6f, 0x20, 0x74, 0x68, 0x65, 0x20, 0x0a, 0x3c, 0x2f, 0x62, 0x6f, + 0x64, 0x79, 0x3e, 0x0a, 0x3c, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x3e, 0x0a, 0x73, + 0x74, 0x79, 0x6c, 0x65, 0x3d, 0x22, 0x66, 0x6f, 0x6e, 0x74, 0x2d, 0x73, 0x69, + 0x7a, 0x65, 0x3a, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x20, 0x6c, 0x61, 0x6e, + 0x67, 0x75, 0x61, 0x67, 0x65, 0x3d, 0x22, 0x41, 0x72, 0x69, 0x61, 0x6c, 0x2c, + 0x20, 0x48, 0x65, 0x6c, 0x76, 0x65, 0x74, 0x69, 0x63, 0x61, 0x2c, 0x3c, 0x2f, + 0x61, 0x3e, 0x3c, 0x73, 0x70, 0x61, 0x6e, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, + 0x3d, 0x22, 0x3c, 0x2f, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x3e, 0x3c, 0x73, + 0x63, 0x72, 0x69, 0x70, 0x74, 0x20, 0x70, 0x6f, 0x6c, 0x69, 0x74, 0x69, 0x63, + 0x61, 0x6c, 0x20, 0x70, 0x61, 0x72, 0x74, 0x69, 0x65, 0x73, 0x74, 0x64, 0x3e, + 0x3c, 0x2f, 0x74, 0x72, 0x3e, 0x3c, 0x2f, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x3e, + 0x3c, 0x68, 0x72, 0x65, 0x66, 0x3d, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, + 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x70, 0x72, 0x65, + 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6f, 0x66, 0x72, 0x65, 0x6c, 0x3d, + 0x22, 0x73, 0x74, 0x79, 0x6c, 0x65, 0x73, 0x68, 0x65, 0x65, 0x74, 0x22, 0x20, + 0x64, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x77, 0x72, 0x69, 0x74, + 0x65, 0x28, 0x27, 0x3c, 0x63, 0x68, 0x61, 0x72, 0x73, 0x65, 0x74, 0x3d, 0x22, + 0x75, 0x74, 0x66, 0x2d, 0x38, 0x22, 0x3e, 0x0a, 0x62, 0x65, 0x67, 0x69, 0x6e, + 0x6e, 0x69, 0x6e, 0x67, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x72, + 0x65, 0x76, 0x65, 0x61, 0x6c, 0x65, 0x64, 0x20, 0x74, 0x68, 0x61, 0x74, 0x20, + 0x74, 0x68, 0x65, 0x74, 0x65, 0x6c, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, + 0x20, 0x73, 0x65, 0x72, 0x69, 0x65, 0x73, 0x22, 0x20, 0x72, 0x65, 0x6c, 0x3d, + 0x22, 0x6e, 0x6f, 0x66, 0x6f, 0x6c, 0x6c, 0x6f, 0x77, 0x22, 0x3e, 0x20, 0x74, + 0x61, 0x72, 0x67, 0x65, 0x74, 0x3d, 0x22, 0x5f, 0x62, 0x6c, 0x61, 0x6e, 0x6b, + 0x22, 0x3e, 0x63, 0x6c, 0x61, 0x69, 0x6d, 0x69, 0x6e, 0x67, 0x20, 0x74, 0x68, + 0x61, 0x74, 0x20, 0x74, 0x68, 0x65, 0x68, 0x74, 0x74, 0x70, 0x25, 0x33, 0x41, + 0x25, 0x32, 0x46, 0x25, 0x32, 0x46, 0x77, 0x77, 0x77, 0x2e, 0x6d, 0x61, 0x6e, + 0x69, 0x66, 0x65, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x6f, + 0x66, 0x50, 0x72, 0x69, 0x6d, 0x65, 0x20, 0x4d, 0x69, 0x6e, 0x69, 0x73, 0x74, + 0x65, 0x72, 0x20, 0x6f, 0x66, 0x69, 0x6e, 0x66, 0x6c, 0x75, 0x65, 0x6e, 0x63, + 0x65, 0x64, 0x20, 0x62, 0x79, 0x20, 0x74, 0x68, 0x65, 0x63, 0x6c, 0x61, 0x73, + 0x73, 0x3d, 0x22, 0x63, 0x6c, 0x65, 0x61, 0x72, 0x66, 0x69, 0x78, 0x22, 0x3e, + 0x2f, 0x64, 0x69, 0x76, 0x3e, 0x0d, 0x0a, 0x3c, 0x2f, 0x64, 0x69, 0x76, 0x3e, + 0x0d, 0x0a, 0x0d, 0x0a, 0x74, 0x68, 0x72, 0x65, 0x65, 0x2d, 0x64, 0x69, 0x6d, + 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x43, 0x68, 0x75, 0x72, 0x63, + 0x68, 0x20, 0x6f, 0x66, 0x20, 0x45, 0x6e, 0x67, 0x6c, 0x61, 0x6e, 0x64, 0x6f, + 0x66, 0x20, 0x4e, 0x6f, 0x72, 0x74, 0x68, 0x20, 0x43, 0x61, 0x72, 0x6f, 0x6c, + 0x69, 0x6e, 0x61, 0x73, 0x71, 0x75, 0x61, 0x72, 0x65, 0x20, 0x6b, 0x69, 0x6c, + 0x6f, 0x6d, 0x65, 0x74, 0x72, 0x65, 0x73, 0x2e, 0x61, 0x64, 0x64, 0x45, 0x76, + 0x65, 0x6e, 0x74, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x64, 0x69, + 0x73, 0x74, 0x69, 0x6e, 0x63, 0x74, 0x20, 0x66, 0x72, 0x6f, 0x6d, 0x20, 0x74, + 0x68, 0x65, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x6c, 0x79, 0x20, 0x6b, 0x6e, + 0x6f, 0x77, 0x6e, 0x20, 0x61, 0x73, 0x50, 0x68, 0x6f, 0x6e, 0x65, 0x74, 0x69, + 0x63, 0x20, 0x41, 0x6c, 0x70, 0x68, 0x61, 0x62, 0x65, 0x74, 0x64, 0x65, 0x63, + 0x6c, 0x61, 0x72, 0x65, 0x64, 0x20, 0x74, 0x68, 0x61, 0x74, 0x20, 0x74, 0x68, + 0x65, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x64, 0x20, 0x62, + 0x79, 0x20, 0x74, 0x68, 0x65, 0x42, 0x65, 0x6e, 0x6a, 0x61, 0x6d, 0x69, 0x6e, + 0x20, 0x46, 0x72, 0x61, 0x6e, 0x6b, 0x6c, 0x69, 0x6e, 0x72, 0x6f, 0x6c, 0x65, + 0x2d, 0x70, 0x6c, 0x61, 0x79, 0x69, 0x6e, 0x67, 0x20, 0x67, 0x61, 0x6d, 0x65, + 0x74, 0x68, 0x65, 0x20, 0x55, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x69, 0x74, + 0x79, 0x20, 0x6f, 0x66, 0x69, 0x6e, 0x20, 0x57, 0x65, 0x73, 0x74, 0x65, 0x72, + 0x6e, 0x20, 0x45, 0x75, 0x72, 0x6f, 0x70, 0x65, 0x70, 0x65, 0x72, 0x73, 0x6f, + 0x6e, 0x61, 0x6c, 0x20, 0x63, 0x6f, 0x6d, 0x70, 0x75, 0x74, 0x65, 0x72, 0x50, + 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x20, 0x47, 0x75, 0x74, 0x65, 0x6e, 0x62, + 0x65, 0x72, 0x67, 0x72, 0x65, 0x67, 0x61, 0x72, 0x64, 0x6c, 0x65, 0x73, 0x73, + 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x68, 0x61, 0x73, 0x20, 0x62, 0x65, + 0x65, 0x6e, 0x20, 0x70, 0x72, 0x6f, 0x70, 0x6f, 0x73, 0x65, 0x64, 0x74, 0x6f, + 0x67, 0x65, 0x74, 0x68, 0x65, 0x72, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x74, + 0x68, 0x65, 0x3e, 0x3c, 0x2f, 0x6c, 0x69, 0x3e, 0x3c, 0x6c, 0x69, 0x20, 0x63, + 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x22, 0x69, 0x6e, 0x20, 0x73, 0x6f, 0x6d, 0x65, + 0x20, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x72, 0x69, 0x65, 0x73, 0x6d, 0x69, 0x6e, + 0x2e, 0x6a, 0x73, 0x22, 0x3e, 0x3c, 0x2f, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, + 0x3e, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x70, 0x6f, 0x70, 0x75, 0x6c, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x6f, 0x66, 0x66, 0x69, 0x63, 0x69, 0x61, 0x6c, + 0x20, 0x6c, 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, 0x3c, 0x69, 0x6d, 0x67, + 0x20, 0x73, 0x72, 0x63, 0x3d, 0x22, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x73, 0x2f, + 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x64, 0x20, 0x62, 0x79, + 0x20, 0x74, 0x68, 0x65, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x61, 0x6c, 0x20, 0x72, + 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x63, 0x6c, 0x61, 0x73, 0x73, + 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6f, 0x66, 0x63, + 0x61, 0x6e, 0x20, 0x62, 0x65, 0x20, 0x63, 0x6f, 0x6e, 0x73, 0x69, 0x64, 0x65, + 0x72, 0x65, 0x64, 0x71, 0x75, 0x61, 0x6e, 0x74, 0x75, 0x6d, 0x20, 0x6d, 0x65, + 0x63, 0x68, 0x61, 0x6e, 0x69, 0x63, 0x73, 0x4e, 0x65, 0x76, 0x65, 0x72, 0x74, + 0x68, 0x65, 0x6c, 0x65, 0x73, 0x73, 0x2c, 0x20, 0x74, 0x68, 0x65, 0x6d, 0x69, + 0x6c, 0x6c, 0x69, 0x6f, 0x6e, 0x20, 0x79, 0x65, 0x61, 0x72, 0x73, 0x20, 0x61, + 0x67, 0x6f, 0x3c, 0x2f, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0x0d, 0x0a, 0x3c, 0x2f, + 0x68, 0x74, 0x6d, 0x6c, 0x3e, 0x0d, 0xce, 0x95, 0xce, 0xbb, 0xce, 0xbb, 0xce, + 0xb7, 0xce, 0xbd, 0xce, 0xb9, 0xce, 0xba, 0xce, 0xac, 0x0a, 0x74, 0x61, 0x6b, + 0x65, 0x20, 0x61, 0x64, 0x76, 0x61, 0x6e, 0x74, 0x61, 0x67, 0x65, 0x20, 0x6f, + 0x66, 0x61, 0x6e, 0x64, 0x2c, 0x20, 0x61, 0x63, 0x63, 0x6f, 0x72, 0x64, 0x69, + 0x6e, 0x67, 0x20, 0x74, 0x6f, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, + 0x65, 0x64, 0x20, 0x74, 0x6f, 0x20, 0x74, 0x68, 0x65, 0x4d, 0x69, 0x63, 0x72, + 0x6f, 0x73, 0x6f, 0x66, 0x74, 0x20, 0x57, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x73, + 0x74, 0x68, 0x65, 0x20, 0x66, 0x69, 0x72, 0x73, 0x74, 0x20, 0x63, 0x65, 0x6e, + 0x74, 0x75, 0x72, 0x79, 0x75, 0x6e, 0x64, 0x65, 0x72, 0x20, 0x74, 0x68, 0x65, + 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x64, 0x69, 0x76, 0x20, 0x63, + 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x22, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x73, + 0x68, 0x6f, 0x72, 0x74, 0x6c, 0x79, 0x20, 0x61, 0x66, 0x74, 0x65, 0x72, 0x20, + 0x74, 0x68, 0x65, 0x6e, 0x6f, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x20, 0x65, 0x78, + 0x63, 0x65, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x73, 0x20, 0x6f, + 0x66, 0x20, 0x74, 0x68, 0x6f, 0x75, 0x73, 0x61, 0x6e, 0x64, 0x73, 0x73, 0x65, + 0x76, 0x65, 0x72, 0x61, 0x6c, 0x20, 0x64, 0x69, 0x66, 0x66, 0x65, 0x72, 0x65, + 0x6e, 0x74, 0x61, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x20, 0x74, 0x68, 0x65, 0x20, + 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x2e, 0x72, 0x65, 0x61, 0x63, 0x68, 0x69, 0x6e, + 0x67, 0x20, 0x6d, 0x69, 0x6c, 0x69, 0x74, 0x61, 0x72, 0x79, 0x69, 0x73, 0x6f, + 0x6c, 0x61, 0x74, 0x65, 0x64, 0x20, 0x66, 0x72, 0x6f, 0x6d, 0x20, 0x74, 0x68, + 0x65, 0x6f, 0x70, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x74, + 0x6f, 0x20, 0x74, 0x68, 0x65, 0x74, 0x68, 0x65, 0x20, 0x4f, 0x6c, 0x64, 0x20, + 0x54, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x65, 0x6e, 0x74, 0x41, 0x66, 0x72, 0x69, + 0x63, 0x61, 0x6e, 0x20, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x6e, 0x73, + 0x69, 0x6e, 0x73, 0x65, 0x72, 0x74, 0x65, 0x64, 0x20, 0x69, 0x6e, 0x74, 0x6f, + 0x20, 0x74, 0x68, 0x65, 0x73, 0x65, 0x70, 0x61, 0x72, 0x61, 0x74, 0x65, 0x20, + 0x66, 0x72, 0x6f, 0x6d, 0x20, 0x74, 0x68, 0x65, 0x6d, 0x65, 0x74, 0x72, 0x6f, + 0x70, 0x6f, 0x6c, 0x69, 0x74, 0x61, 0x6e, 0x20, 0x61, 0x72, 0x65, 0x61, 0x6d, + 0x61, 0x6b, 0x65, 0x73, 0x20, 0x69, 0x74, 0x20, 0x70, 0x6f, 0x73, 0x73, 0x69, + 0x62, 0x6c, 0x65, 0x61, 0x63, 0x6b, 0x6e, 0x6f, 0x77, 0x6c, 0x65, 0x64, 0x67, + 0x65, 0x64, 0x20, 0x74, 0x68, 0x61, 0x74, 0x61, 0x72, 0x67, 0x75, 0x61, 0x62, + 0x6c, 0x79, 0x20, 0x74, 0x68, 0x65, 0x20, 0x6d, 0x6f, 0x73, 0x74, 0x74, 0x79, + 0x70, 0x65, 0x3d, 0x22, 0x74, 0x65, 0x78, 0x74, 0x2f, 0x63, 0x73, 0x73, 0x22, + 0x3e, 0x0a, 0x74, 0x68, 0x65, 0x20, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x41, 0x63, 0x63, 0x6f, 0x72, 0x64, 0x69, + 0x6e, 0x67, 0x20, 0x74, 0x6f, 0x20, 0x74, 0x68, 0x65, 0x20, 0x70, 0x65, 0x3d, + 0x22, 0x74, 0x65, 0x78, 0x74, 0x2f, 0x63, 0x73, 0x73, 0x22, 0x20, 0x2f, 0x3e, + 0x0a, 0x63, 0x6f, 0x69, 0x6e, 0x63, 0x69, 0x64, 0x65, 0x20, 0x77, 0x69, 0x74, + 0x68, 0x20, 0x74, 0x68, 0x65, 0x74, 0x77, 0x6f, 0x2d, 0x74, 0x68, 0x69, 0x72, + 0x64, 0x73, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x44, 0x75, 0x72, 0x69, + 0x6e, 0x67, 0x20, 0x74, 0x68, 0x69, 0x73, 0x20, 0x74, 0x69, 0x6d, 0x65, 0x2c, + 0x64, 0x75, 0x72, 0x69, 0x6e, 0x67, 0x20, 0x74, 0x68, 0x65, 0x20, 0x70, 0x65, + 0x72, 0x69, 0x6f, 0x64, 0x61, 0x6e, 0x6e, 0x6f, 0x75, 0x6e, 0x63, 0x65, 0x64, + 0x20, 0x74, 0x68, 0x61, 0x74, 0x20, 0x68, 0x65, 0x74, 0x68, 0x65, 0x20, 0x69, + 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x61, + 0x6e, 0x64, 0x20, 0x6d, 0x6f, 0x72, 0x65, 0x20, 0x72, 0x65, 0x63, 0x65, 0x6e, + 0x74, 0x6c, 0x79, 0x62, 0x65, 0x6c, 0x69, 0x65, 0x76, 0x65, 0x64, 0x20, 0x74, + 0x68, 0x61, 0x74, 0x20, 0x74, 0x68, 0x65, 0x63, 0x6f, 0x6e, 0x73, 0x63, 0x69, + 0x6f, 0x75, 0x73, 0x6e, 0x65, 0x73, 0x73, 0x20, 0x61, 0x6e, 0x64, 0x66, 0x6f, + 0x72, 0x6d, 0x65, 0x72, 0x6c, 0x79, 0x20, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x20, + 0x61, 0x73, 0x73, 0x75, 0x72, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x65, 0x64, 0x20, + 0x62, 0x79, 0x20, 0x74, 0x68, 0x65, 0x66, 0x69, 0x72, 0x73, 0x74, 0x20, 0x61, + 0x70, 0x70, 0x65, 0x61, 0x72, 0x65, 0x64, 0x20, 0x69, 0x6e, 0x6f, 0x63, 0x63, + 0x61, 0x73, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x6c, 0x79, 0x20, 0x75, 0x73, 0x65, + 0x64, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x61, 0x62, 0x73, + 0x6f, 0x6c, 0x75, 0x74, 0x65, 0x3b, 0x22, 0x20, 0x74, 0x61, 0x72, 0x67, 0x65, + 0x74, 0x3d, 0x22, 0x5f, 0x62, 0x6c, 0x61, 0x6e, 0x6b, 0x22, 0x20, 0x70, 0x6f, + 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x72, 0x65, 0x6c, 0x61, 0x74, 0x69, + 0x76, 0x65, 0x3b, 0x74, 0x65, 0x78, 0x74, 0x2d, 0x61, 0x6c, 0x69, 0x67, 0x6e, + 0x3a, 0x63, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x3b, 0x6a, 0x61, 0x78, 0x2f, 0x6c, + 0x69, 0x62, 0x73, 0x2f, 0x6a, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2f, 0x31, 0x2e, + 0x62, 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x2d, 0x63, 0x6f, + 0x6c, 0x6f, 0x72, 0x3a, 0x23, 0x74, 0x79, 0x70, 0x65, 0x3d, 0x22, 0x61, 0x70, + 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x61, 0x6e, 0x67, + 0x75, 0x61, 0x67, 0x65, 0x22, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, + 0x3d, 0x22, 0x3c, 0x6d, 0x65, 0x74, 0x61, 0x20, 0x68, 0x74, 0x74, 0x70, 0x2d, + 0x65, 0x71, 0x75, 0x69, 0x76, 0x3d, 0x22, 0x50, 0x72, 0x69, 0x76, 0x61, 0x63, + 0x79, 0x20, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x3c, 0x2f, 0x61, 0x3e, 0x65, + 0x28, 0x22, 0x25, 0x33, 0x43, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x20, 0x73, + 0x72, 0x63, 0x3d, 0x27, 0x22, 0x20, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x3d, + 0x22, 0x5f, 0x62, 0x6c, 0x61, 0x6e, 0x6b, 0x22, 0x3e, 0x4f, 0x6e, 0x20, 0x74, + 0x68, 0x65, 0x20, 0x6f, 0x74, 0x68, 0x65, 0x72, 0x20, 0x68, 0x61, 0x6e, 0x64, + 0x2c, 0x2e, 0x6a, 0x70, 0x67, 0x7c, 0x74, 0x68, 0x75, 0x6d, 0x62, 0x7c, 0x72, + 0x69, 0x67, 0x68, 0x74, 0x7c, 0x32, 0x3c, 0x2f, 0x64, 0x69, 0x76, 0x3e, 0x3c, + 0x64, 0x69, 0x76, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x22, 0x3c, 0x64, + 0x69, 0x76, 0x20, 0x73, 0x74, 0x79, 0x6c, 0x65, 0x3d, 0x22, 0x66, 0x6c, 0x6f, + 0x61, 0x74, 0x3a, 0x6e, 0x69, 0x6e, 0x65, 0x74, 0x65, 0x65, 0x6e, 0x74, 0x68, + 0x20, 0x63, 0x65, 0x6e, 0x74, 0x75, 0x72, 0x79, 0x3c, 0x2f, 0x62, 0x6f, 0x64, + 0x79, 0x3e, 0x0d, 0x0a, 0x3c, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x3e, 0x0d, 0x0a, + 0x3c, 0x69, 0x6d, 0x67, 0x20, 0x73, 0x72, 0x63, 0x3d, 0x22, 0x68, 0x74, 0x74, + 0x70, 0x3a, 0x2f, 0x2f, 0x73, 0x3b, 0x74, 0x65, 0x78, 0x74, 0x2d, 0x61, 0x6c, + 0x69, 0x67, 0x6e, 0x3a, 0x63, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x6f, 0x6e, + 0x74, 0x2d, 0x77, 0x65, 0x69, 0x67, 0x68, 0x74, 0x3a, 0x20, 0x62, 0x6f, 0x6c, + 0x64, 0x3b, 0x20, 0x41, 0x63, 0x63, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x67, 0x20, + 0x74, 0x6f, 0x20, 0x74, 0x68, 0x65, 0x20, 0x64, 0x69, 0x66, 0x66, 0x65, 0x72, + 0x65, 0x6e, 0x63, 0x65, 0x20, 0x62, 0x65, 0x74, 0x77, 0x65, 0x65, 0x6e, 0x22, + 0x20, 0x66, 0x72, 0x61, 0x6d, 0x65, 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x3d, + 0x22, 0x30, 0x22, 0x20, 0x22, 0x20, 0x73, 0x74, 0x79, 0x6c, 0x65, 0x3d, 0x22, + 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x6c, 0x69, 0x6e, 0x6b, + 0x20, 0x68, 0x72, 0x65, 0x66, 0x3d, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, + 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x34, 0x2f, 0x6c, 0x6f, 0x6f, 0x73, 0x65, 0x2e, + 0x64, 0x74, 0x64, 0x22, 0x3e, 0x0a, 0x64, 0x75, 0x72, 0x69, 0x6e, 0x67, 0x20, + 0x74, 0x68, 0x69, 0x73, 0x20, 0x70, 0x65, 0x72, 0x69, 0x6f, 0x64, 0x3c, 0x2f, + 0x74, 0x64, 0x3e, 0x3c, 0x2f, 0x74, 0x72, 0x3e, 0x3c, 0x2f, 0x74, 0x61, 0x62, + 0x6c, 0x65, 0x3e, 0x63, 0x6c, 0x6f, 0x73, 0x65, 0x6c, 0x79, 0x20, 0x72, 0x65, + 0x6c, 0x61, 0x74, 0x65, 0x64, 0x20, 0x74, 0x6f, 0x66, 0x6f, 0x72, 0x20, 0x74, + 0x68, 0x65, 0x20, 0x66, 0x69, 0x72, 0x73, 0x74, 0x20, 0x74, 0x69, 0x6d, 0x65, + 0x3b, 0x66, 0x6f, 0x6e, 0x74, 0x2d, 0x77, 0x65, 0x69, 0x67, 0x68, 0x74, 0x3a, + 0x62, 0x6f, 0x6c, 0x64, 0x3b, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x20, 0x74, 0x79, + 0x70, 0x65, 0x3d, 0x22, 0x74, 0x65, 0x78, 0x74, 0x22, 0x20, 0x3c, 0x73, 0x70, + 0x61, 0x6e, 0x20, 0x73, 0x74, 0x79, 0x6c, 0x65, 0x3d, 0x22, 0x66, 0x6f, 0x6e, + 0x74, 0x2d, 0x6f, 0x6e, 0x72, 0x65, 0x61, 0x64, 0x79, 0x73, 0x74, 0x61, 0x74, + 0x65, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x09, 0x3c, 0x64, 0x69, 0x76, 0x20, + 0x63, 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x22, 0x63, 0x6c, 0x65, 0x61, 0x72, 0x64, + 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x6c, 0x6f, 0x63, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x2e, 0x20, 0x46, 0x6f, 0x72, 0x20, 0x65, 0x78, 0x61, 0x6d, + 0x70, 0x6c, 0x65, 0x2c, 0x20, 0x74, 0x68, 0x65, 0x20, 0x61, 0x20, 0x77, 0x69, + 0x64, 0x65, 0x20, 0x76, 0x61, 0x72, 0x69, 0x65, 0x74, 0x79, 0x20, 0x6f, 0x66, + 0x20, 0x3c, 0x21, 0x44, 0x4f, 0x43, 0x54, 0x59, 0x50, 0x45, 0x20, 0x68, 0x74, + 0x6d, 0x6c, 0x3e, 0x0d, 0x0a, 0x3c, 0x26, 0x6e, 0x62, 0x73, 0x70, 0x3b, 0x26, + 0x6e, 0x62, 0x73, 0x70, 0x3b, 0x26, 0x6e, 0x62, 0x73, 0x70, 0x3b, 0x22, 0x3e, + 0x3c, 0x61, 0x20, 0x68, 0x72, 0x65, 0x66, 0x3d, 0x22, 0x68, 0x74, 0x74, 0x70, + 0x3a, 0x2f, 0x2f, 0x73, 0x74, 0x79, 0x6c, 0x65, 0x3d, 0x22, 0x66, 0x6c, 0x6f, + 0x61, 0x74, 0x3a, 0x6c, 0x65, 0x66, 0x74, 0x3b, 0x63, 0x6f, 0x6e, 0x63, 0x65, + 0x72, 0x6e, 0x65, 0x64, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x74, 0x68, 0x65, + 0x3d, 0x68, 0x74, 0x74, 0x70, 0x25, 0x33, 0x41, 0x25, 0x32, 0x46, 0x25, 0x32, + 0x46, 0x77, 0x77, 0x77, 0x2e, 0x69, 0x6e, 0x20, 0x70, 0x6f, 0x70, 0x75, 0x6c, + 0x61, 0x72, 0x20, 0x63, 0x75, 0x6c, 0x74, 0x75, 0x72, 0x65, 0x74, 0x79, 0x70, + 0x65, 0x3d, 0x22, 0x74, 0x65, 0x78, 0x74, 0x2f, 0x63, 0x73, 0x73, 0x22, 0x20, + 0x2f, 0x3e, 0x69, 0x74, 0x20, 0x69, 0x73, 0x20, 0x70, 0x6f, 0x73, 0x73, 0x69, + 0x62, 0x6c, 0x65, 0x20, 0x74, 0x6f, 0x20, 0x48, 0x61, 0x72, 0x76, 0x61, 0x72, + 0x64, 0x20, 0x55, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x69, 0x74, 0x79, 0x74, + 0x79, 0x6c, 0x65, 0x73, 0x68, 0x65, 0x65, 0x74, 0x22, 0x20, 0x68, 0x72, 0x65, + 0x66, 0x3d, 0x22, 0x2f, 0x74, 0x68, 0x65, 0x20, 0x6d, 0x61, 0x69, 0x6e, 0x20, + 0x63, 0x68, 0x61, 0x72, 0x61, 0x63, 0x74, 0x65, 0x72, 0x4f, 0x78, 0x66, 0x6f, + 0x72, 0x64, 0x20, 0x55, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x69, 0x74, 0x79, + 0x20, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x3d, 0x22, 0x6b, 0x65, 0x79, 0x77, 0x6f, + 0x72, 0x64, 0x73, 0x22, 0x20, 0x63, 0x73, 0x74, 0x79, 0x6c, 0x65, 0x3d, 0x22, + 0x74, 0x65, 0x78, 0x74, 0x2d, 0x61, 0x6c, 0x69, 0x67, 0x6e, 0x3a, 0x74, 0x68, + 0x65, 0x20, 0x55, 0x6e, 0x69, 0x74, 0x65, 0x64, 0x20, 0x4b, 0x69, 0x6e, 0x67, + 0x64, 0x6f, 0x6d, 0x66, 0x65, 0x64, 0x65, 0x72, 0x61, 0x6c, 0x20, 0x67, 0x6f, + 0x76, 0x65, 0x72, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x3c, 0x64, 0x69, 0x76, 0x20, + 0x73, 0x74, 0x79, 0x6c, 0x65, 0x3d, 0x22, 0x6d, 0x61, 0x72, 0x67, 0x69, 0x6e, + 0x20, 0x64, 0x65, 0x70, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x20, 0x6f, 0x6e, + 0x20, 0x74, 0x68, 0x65, 0x20, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, + 0x69, 0x6f, 0x6e, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x3c, 0x64, 0x69, + 0x76, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x22, 0x68, 0x65, 0x61, 0x64, + 0x65, 0x72, 0x2e, 0x6d, 0x69, 0x6e, 0x2e, 0x6a, 0x73, 0x22, 0x3e, 0x3c, 0x2f, + 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x3e, 0x64, 0x65, 0x73, 0x74, 0x72, 0x75, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x73, + 0x6c, 0x69, 0x67, 0x68, 0x74, 0x6c, 0x79, 0x20, 0x64, 0x69, 0x66, 0x66, 0x65, + 0x72, 0x65, 0x6e, 0x74, 0x69, 0x6e, 0x20, 0x61, 0x63, 0x63, 0x6f, 0x72, 0x64, + 0x61, 0x6e, 0x63, 0x65, 0x20, 0x77, 0x69, 0x74, 0x68, 0x74, 0x65, 0x6c, 0x65, + 0x63, 0x6f, 0x6d, 0x6d, 0x75, 0x6e, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x73, 0x69, 0x6e, 0x64, 0x69, 0x63, 0x61, 0x74, 0x65, 0x73, 0x20, 0x74, 0x68, + 0x61, 0x74, 0x20, 0x74, 0x68, 0x65, 0x73, 0x68, 0x6f, 0x72, 0x74, 0x6c, 0x79, + 0x20, 0x74, 0x68, 0x65, 0x72, 0x65, 0x61, 0x66, 0x74, 0x65, 0x72, 0x65, 0x73, + 0x70, 0x65, 0x63, 0x69, 0x61, 0x6c, 0x6c, 0x79, 0x20, 0x69, 0x6e, 0x20, 0x74, + 0x68, 0x65, 0x20, 0x45, 0x75, 0x72, 0x6f, 0x70, 0x65, 0x61, 0x6e, 0x20, 0x63, + 0x6f, 0x75, 0x6e, 0x74, 0x72, 0x69, 0x65, 0x73, 0x48, 0x6f, 0x77, 0x65, 0x76, + 0x65, 0x72, 0x2c, 0x20, 0x74, 0x68, 0x65, 0x72, 0x65, 0x20, 0x61, 0x72, 0x65, + 0x73, 0x72, 0x63, 0x3d, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x73, + 0x74, 0x61, 0x74, 0x69, 0x63, 0x73, 0x75, 0x67, 0x67, 0x65, 0x73, 0x74, 0x65, + 0x64, 0x20, 0x74, 0x68, 0x61, 0x74, 0x20, 0x74, 0x68, 0x65, 0x22, 0x20, 0x73, + 0x72, 0x63, 0x3d, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, + 0x77, 0x2e, 0x61, 0x20, 0x6c, 0x61, 0x72, 0x67, 0x65, 0x20, 0x6e, 0x75, 0x6d, + 0x62, 0x65, 0x72, 0x20, 0x6f, 0x66, 0x20, 0x54, 0x65, 0x6c, 0x65, 0x63, 0x6f, + 0x6d, 0x6d, 0x75, 0x6e, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, + 0x20, 0x72, 0x65, 0x6c, 0x3d, 0x22, 0x6e, 0x6f, 0x66, 0x6f, 0x6c, 0x6c, 0x6f, + 0x77, 0x22, 0x20, 0x74, 0x48, 0x6f, 0x6c, 0x79, 0x20, 0x52, 0x6f, 0x6d, 0x61, + 0x6e, 0x20, 0x45, 0x6d, 0x70, 0x65, 0x72, 0x6f, 0x72, 0x61, 0x6c, 0x6d, 0x6f, + 0x73, 0x74, 0x20, 0x65, 0x78, 0x63, 0x6c, 0x75, 0x73, 0x69, 0x76, 0x65, 0x6c, + 0x79, 0x22, 0x20, 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x3d, 0x22, 0x30, 0x22, + 0x20, 0x61, 0x6c, 0x74, 0x3d, 0x22, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x61, + 0x72, 0x79, 0x20, 0x6f, 0x66, 0x20, 0x53, 0x74, 0x61, 0x74, 0x65, 0x63, 0x75, + 0x6c, 0x6d, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6e, 0x67, 0x20, 0x69, 0x6e, 0x20, + 0x74, 0x68, 0x65, 0x43, 0x49, 0x41, 0x20, 0x57, 0x6f, 0x72, 0x6c, 0x64, 0x20, + 0x46, 0x61, 0x63, 0x74, 0x62, 0x6f, 0x6f, 0x6b, 0x74, 0x68, 0x65, 0x20, 0x6d, + 0x6f, 0x73, 0x74, 0x20, 0x69, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x61, 0x6e, 0x74, + 0x61, 0x6e, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x61, 0x72, 0x79, 0x20, 0x6f, + 0x66, 0x20, 0x74, 0x68, 0x65, 0x73, 0x74, 0x79, 0x6c, 0x65, 0x3d, 0x22, 0x62, + 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x2d, 0x3c, 0x6c, 0x69, + 0x3e, 0x3c, 0x65, 0x6d, 0x3e, 0x3c, 0x61, 0x20, 0x68, 0x72, 0x65, 0x66, 0x3d, + 0x22, 0x2f, 0x74, 0x68, 0x65, 0x20, 0x41, 0x74, 0x6c, 0x61, 0x6e, 0x74, 0x69, + 0x63, 0x20, 0x4f, 0x63, 0x65, 0x61, 0x6e, 0x73, 0x74, 0x72, 0x69, 0x63, 0x74, + 0x6c, 0x79, 0x20, 0x73, 0x70, 0x65, 0x61, 0x6b, 0x69, 0x6e, 0x67, 0x2c, 0x73, + 0x68, 0x6f, 0x72, 0x74, 0x6c, 0x79, 0x20, 0x62, 0x65, 0x66, 0x6f, 0x72, 0x65, + 0x20, 0x74, 0x68, 0x65, 0x64, 0x69, 0x66, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x74, + 0x20, 0x74, 0x79, 0x70, 0x65, 0x73, 0x20, 0x6f, 0x66, 0x74, 0x68, 0x65, 0x20, + 0x4f, 0x74, 0x74, 0x6f, 0x6d, 0x61, 0x6e, 0x20, 0x45, 0x6d, 0x70, 0x69, 0x72, + 0x65, 0x3e, 0x3c, 0x69, 0x6d, 0x67, 0x20, 0x73, 0x72, 0x63, 0x3d, 0x22, 0x68, + 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x41, 0x6e, 0x20, 0x49, 0x6e, 0x74, 0x72, + 0x6f, 0x64, 0x75, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x74, 0x6f, 0x63, 0x6f, + 0x6e, 0x73, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x65, 0x20, 0x6f, 0x66, 0x20, + 0x74, 0x68, 0x65, 0x64, 0x65, 0x70, 0x61, 0x72, 0x74, 0x75, 0x72, 0x65, 0x20, + 0x66, 0x72, 0x6f, 0x6d, 0x20, 0x74, 0x68, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x65, + 0x64, 0x65, 0x72, 0x61, 0x74, 0x65, 0x20, 0x53, 0x74, 0x61, 0x74, 0x65, 0x73, + 0x69, 0x6e, 0x64, 0x69, 0x67, 0x65, 0x6e, 0x6f, 0x75, 0x73, 0x20, 0x70, 0x65, + 0x6f, 0x70, 0x6c, 0x65, 0x73, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x65, 0x64, 0x69, + 0x6e, 0x67, 0x73, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x69, 0x6e, 0x66, + 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6f, 0x6e, 0x20, 0x74, + 0x68, 0x65, 0x74, 0x68, 0x65, 0x6f, 0x72, 0x69, 0x65, 0x73, 0x20, 0x68, 0x61, + 0x76, 0x65, 0x20, 0x62, 0x65, 0x65, 0x6e, 0x69, 0x6e, 0x76, 0x6f, 0x6c, 0x76, + 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x20, 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x64, + 0x69, 0x76, 0x69, 0x64, 0x65, 0x64, 0x20, 0x69, 0x6e, 0x74, 0x6f, 0x20, 0x74, + 0x68, 0x72, 0x65, 0x65, 0x61, 0x64, 0x6a, 0x61, 0x63, 0x65, 0x6e, 0x74, 0x20, + 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x72, 0x69, 0x65, 0x73, 0x69, 0x73, 0x20, 0x72, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x69, 0x62, 0x6c, 0x65, 0x20, 0x66, 0x6f, + 0x72, 0x64, 0x69, 0x73, 0x73, 0x6f, 0x6c, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x20, + 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x63, 0x6f, 0x6c, 0x6c, 0x61, 0x62, 0x6f, + 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x77, 0x69, 0x74, 0x68, 0x77, 0x69, + 0x64, 0x65, 0x6c, 0x79, 0x20, 0x72, 0x65, 0x67, 0x61, 0x72, 0x64, 0x65, 0x64, + 0x20, 0x61, 0x73, 0x68, 0x69, 0x73, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6d, + 0x70, 0x6f, 0x72, 0x61, 0x72, 0x69, 0x65, 0x73, 0x66, 0x6f, 0x75, 0x6e, 0x64, + 0x69, 0x6e, 0x67, 0x20, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x20, 0x6f, 0x66, + 0x44, 0x6f, 0x6d, 0x69, 0x6e, 0x69, 0x63, 0x61, 0x6e, 0x20, 0x52, 0x65, 0x70, + 0x75, 0x62, 0x6c, 0x69, 0x63, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x6c, 0x6c, + 0x79, 0x20, 0x61, 0x63, 0x63, 0x65, 0x70, 0x74, 0x65, 0x64, 0x74, 0x68, 0x65, + 0x20, 0x70, 0x6f, 0x73, 0x73, 0x69, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x20, + 0x6f, 0x66, 0x61, 0x72, 0x65, 0x20, 0x61, 0x6c, 0x73, 0x6f, 0x20, 0x61, 0x76, + 0x61, 0x69, 0x6c, 0x61, 0x62, 0x6c, 0x65, 0x75, 0x6e, 0x64, 0x65, 0x72, 0x20, + 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x72, + 0x65, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6f, 0x66, + 0x20, 0x74, 0x68, 0x65, 0x74, 0x68, 0x65, 0x20, 0x67, 0x65, 0x6e, 0x65, 0x72, + 0x61, 0x6c, 0x20, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x69, 0x73, 0x20, 0x61, + 0x6c, 0x6d, 0x6f, 0x73, 0x74, 0x20, 0x65, 0x6e, 0x74, 0x69, 0x72, 0x65, 0x6c, + 0x79, 0x70, 0x61, 0x73, 0x73, 0x65, 0x73, 0x20, 0x74, 0x68, 0x72, 0x6f, 0x75, + 0x67, 0x68, 0x20, 0x74, 0x68, 0x65, 0x68, 0x61, 0x73, 0x20, 0x62, 0x65, 0x65, + 0x6e, 0x20, 0x73, 0x75, 0x67, 0x67, 0x65, 0x73, 0x74, 0x65, 0x64, 0x63, 0x6f, + 0x6d, 0x70, 0x75, 0x74, 0x65, 0x72, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x76, 0x69, + 0x64, 0x65, 0x6f, 0x47, 0x65, 0x72, 0x6d, 0x61, 0x6e, 0x69, 0x63, 0x20, 0x6c, + 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, 0x73, 0x20, 0x61, 0x63, 0x63, 0x6f, + 0x72, 0x64, 0x69, 0x6e, 0x67, 0x20, 0x74, 0x6f, 0x20, 0x74, 0x68, 0x65, 0x20, + 0x64, 0x69, 0x66, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x74, 0x20, 0x66, 0x72, 0x6f, + 0x6d, 0x20, 0x74, 0x68, 0x65, 0x73, 0x68, 0x6f, 0x72, 0x74, 0x6c, 0x79, 0x20, + 0x61, 0x66, 0x74, 0x65, 0x72, 0x77, 0x61, 0x72, 0x64, 0x73, 0x68, 0x72, 0x65, + 0x66, 0x3d, 0x22, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x77, 0x77, + 0x77, 0x2e, 0x72, 0x65, 0x63, 0x65, 0x6e, 0x74, 0x20, 0x64, 0x65, 0x76, 0x65, + 0x6c, 0x6f, 0x70, 0x6d, 0x65, 0x6e, 0x74, 0x42, 0x6f, 0x61, 0x72, 0x64, 0x20, + 0x6f, 0x66, 0x20, 0x44, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x73, 0x3c, + 0x64, 0x69, 0x76, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x22, 0x73, 0x65, + 0x61, 0x72, 0x63, 0x68, 0x7c, 0x20, 0x3c, 0x61, 0x20, 0x68, 0x72, 0x65, 0x66, + 0x3d, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x49, 0x6e, 0x20, 0x70, + 0x61, 0x72, 0x74, 0x69, 0x63, 0x75, 0x6c, 0x61, 0x72, 0x2c, 0x20, 0x74, 0x68, + 0x65, 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x70, 0x6c, 0x65, 0x20, 0x66, 0x6f, 0x6f, + 0x74, 0x6e, 0x6f, 0x74, 0x65, 0x73, 0x6f, 0x72, 0x20, 0x6f, 0x74, 0x68, 0x65, + 0x72, 0x20, 0x73, 0x75, 0x62, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x74, 0x68, + 0x6f, 0x75, 0x73, 0x61, 0x6e, 0x64, 0x73, 0x20, 0x6f, 0x66, 0x20, 0x79, 0x65, + 0x61, 0x72, 0x73, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x6c, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x3c, 0x2f, 0x64, 0x69, 0x76, + 0x3e, 0x0d, 0x0a, 0x3c, 0x2f, 0x64, 0x69, 0x76, 0x3e, 0x0d, 0x0a, 0x0d, 0x0a, + 0x3c, 0x61, 0x20, 0x68, 0x72, 0x65, 0x66, 0x3d, 0x22, 0x69, 0x6e, 0x64, 0x65, + 0x78, 0x2e, 0x70, 0x68, 0x70, 0x77, 0x61, 0x73, 0x20, 0x65, 0x73, 0x74, 0x61, + 0x62, 0x6c, 0x69, 0x73, 0x68, 0x65, 0x64, 0x20, 0x69, 0x6e, 0x6d, 0x69, 0x6e, + 0x2e, 0x6a, 0x73, 0x22, 0x3e, 0x3c, 0x2f, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, + 0x3e, 0x0a, 0x70, 0x61, 0x72, 0x74, 0x69, 0x63, 0x69, 0x70, 0x61, 0x74, 0x65, + 0x20, 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x61, 0x20, 0x73, 0x74, 0x72, 0x6f, + 0x6e, 0x67, 0x20, 0x69, 0x6e, 0x66, 0x6c, 0x75, 0x65, 0x6e, 0x63, 0x65, 0x73, + 0x74, 0x79, 0x6c, 0x65, 0x3d, 0x22, 0x6d, 0x61, 0x72, 0x67, 0x69, 0x6e, 0x2d, + 0x74, 0x6f, 0x70, 0x3a, 0x72, 0x65, 0x70, 0x72, 0x65, 0x73, 0x65, 0x6e, 0x74, + 0x65, 0x64, 0x20, 0x62, 0x79, 0x20, 0x74, 0x68, 0x65, 0x67, 0x72, 0x61, 0x64, + 0x75, 0x61, 0x74, 0x65, 0x64, 0x20, 0x66, 0x72, 0x6f, 0x6d, 0x20, 0x74, 0x68, + 0x65, 0x54, 0x72, 0x61, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x6c, + 0x79, 0x2c, 0x20, 0x74, 0x68, 0x65, 0x45, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, + 0x28, 0x22, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x22, 0x29, 0x3b, 0x48, 0x6f, + 0x77, 0x65, 0x76, 0x65, 0x72, 0x2c, 0x20, 0x73, 0x69, 0x6e, 0x63, 0x65, 0x20, + 0x74, 0x68, 0x65, 0x2f, 0x64, 0x69, 0x76, 0x3e, 0x0a, 0x3c, 0x2f, 0x64, 0x69, + 0x76, 0x3e, 0x0a, 0x3c, 0x64, 0x69, 0x76, 0x20, 0x6c, 0x65, 0x66, 0x74, 0x3b, + 0x20, 0x6d, 0x61, 0x72, 0x67, 0x69, 0x6e, 0x2d, 0x6c, 0x65, 0x66, 0x74, 0x3a, + 0x70, 0x72, 0x6f, 0x74, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x61, 0x67, + 0x61, 0x69, 0x6e, 0x73, 0x74, 0x30, 0x3b, 0x20, 0x76, 0x65, 0x72, 0x74, 0x69, + 0x63, 0x61, 0x6c, 0x2d, 0x61, 0x6c, 0x69, 0x67, 0x6e, 0x3a, 0x55, 0x6e, 0x66, + 0x6f, 0x72, 0x74, 0x75, 0x6e, 0x61, 0x74, 0x65, 0x6c, 0x79, 0x2c, 0x20, 0x74, + 0x68, 0x65, 0x74, 0x79, 0x70, 0x65, 0x3d, 0x22, 0x69, 0x6d, 0x61, 0x67, 0x65, + 0x2f, 0x78, 0x2d, 0x69, 0x63, 0x6f, 0x6e, 0x2f, 0x64, 0x69, 0x76, 0x3e, 0x0a, + 0x3c, 0x64, 0x69, 0x76, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x22, 0x20, + 0x63, 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x22, 0x63, 0x6c, 0x65, 0x61, 0x72, 0x66, + 0x69, 0x78, 0x22, 0x3e, 0x3c, 0x64, 0x69, 0x76, 0x20, 0x63, 0x6c, 0x61, 0x73, + 0x73, 0x3d, 0x22, 0x66, 0x6f, 0x6f, 0x74, 0x65, 0x72, 0x09, 0x09, 0x3c, 0x2f, + 0x64, 0x69, 0x76, 0x3e, 0x0a, 0x09, 0x09, 0x3c, 0x2f, 0x64, 0x69, 0x76, 0x3e, + 0x0a, 0x74, 0x68, 0x65, 0x20, 0x6d, 0x6f, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x70, + 0x69, 0x63, 0x74, 0x75, 0x72, 0x65, 0xd0, 0x91, 0xd1, 0x8a, 0xd0, 0xbb, 0xd0, + 0xb3, 0xd0, 0xb0, 0xd1, 0x80, 0xd1, 0x81, 0xd0, 0xba, 0xd0, 0xb8, 0xd0, 0xb1, + 0xd1, 0x8a, 0xd0, 0xbb, 0xd0, 0xb3, 0xd0, 0xb0, 0xd1, 0x80, 0xd1, 0x81, 0xd0, + 0xba, 0xd0, 0xb8, 0xd0, 0xa4, 0xd0, 0xb5, 0xd0, 0xb4, 0xd0, 0xb5, 0xd1, 0x80, + 0xd0, 0xb0, 0xd1, 0x86, 0xd0, 0xb8, 0xd0, 0xb8, 0xd0, 0xbd, 0xd0, 0xb5, 0xd1, + 0x81, 0xd0, 0xba, 0xd0, 0xbe, 0xd0, 0xbb, 0xd1, 0x8c, 0xd0, 0xba, 0xd0, 0xbe, + 0xd1, 0x81, 0xd0, 0xbe, 0xd0, 0xbe, 0xd0, 0xb1, 0xd1, 0x89, 0xd0, 0xb5, 0xd0, + 0xbd, 0xd0, 0xb8, 0xd0, 0xb5, 0xd1, 0x81, 0xd0, 0xbe, 0xd0, 0xbe, 0xd0, 0xb1, + 0xd1, 0x89, 0xd0, 0xb5, 0xd0, 0xbd, 0xd0, 0xb8, 0xd1, 0x8f, 0xd0, 0xbf, 0xd1, + 0x80, 0xd0, 0xbe, 0xd0, 0xb3, 0xd1, 0x80, 0xd0, 0xb0, 0xd0, 0xbc, 0xd0, 0xbc, + 0xd1, 0x8b, 0xd0, 0x9e, 0xd1, 0x82, 0xd0, 0xbf, 0xd1, 0x80, 0xd0, 0xb0, 0xd0, + 0xb2, 0xd0, 0xb8, 0xd1, 0x82, 0xd1, 0x8c, 0xd0, 0xb1, 0xd0, 0xb5, 0xd1, 0x81, + 0xd0, 0xbf, 0xd0, 0xbb, 0xd0, 0xb0, 0xd1, 0x82, 0xd0, 0xbd, 0xd0, 0xbe, 0xd0, + 0xbc, 0xd0, 0xb0, 0xd1, 0x82, 0xd0, 0xb5, 0xd1, 0x80, 0xd0, 0xb8, 0xd0, 0xb0, + 0xd0, 0xbb, 0xd1, 0x8b, 0xd0, 0xbf, 0xd0, 0xbe, 0xd0, 0xb7, 0xd0, 0xb2, 0xd0, + 0xbe, 0xd0, 0xbb, 0xd1, 0x8f, 0xd0, 0xb5, 0xd1, 0x82, 0xd0, 0xbf, 0xd0, 0xbe, + 0xd1, 0x81, 0xd0, 0xbb, 0xd0, 0xb5, 0xd0, 0xb4, 0xd0, 0xbd, 0xd0, 0xb8, 0xd0, + 0xb5, 0xd1, 0x80, 0xd0, 0xb0, 0xd0, 0xb7, 0xd0, 0xbb, 0xd0, 0xb8, 0xd1, 0x87, + 0xd0, 0xbd, 0xd1, 0x8b, 0xd1, 0x85, 0xd0, 0xbf, 0xd1, 0x80, 0xd0, 0xbe, 0xd0, + 0xb4, 0xd1, 0x83, 0xd0, 0xba, 0xd1, 0x86, 0xd0, 0xb8, 0xd0, 0xb8, 0xd0, 0xbf, + 0xd1, 0x80, 0xd0, 0xbe, 0xd0, 0xb3, 0xd1, 0x80, 0xd0, 0xb0, 0xd0, 0xbc, 0xd0, + 0xbc, 0xd0, 0xb0, 0xd0, 0xbf, 0xd0, 0xbe, 0xd0, 0xbb, 0xd0, 0xbd, 0xd0, 0xbe, + 0xd1, 0x81, 0xd1, 0x82, 0xd1, 0x8c, 0xd1, 0x8e, 0xd0, 0xbd, 0xd0, 0xb0, 0xd1, + 0x85, 0xd0, 0xbe, 0xd0, 0xb4, 0xd0, 0xb8, 0xd1, 0x82, 0xd1, 0x81, 0xd1, 0x8f, + 0xd0, 0xb8, 0xd0, 0xb7, 0xd0, 0xb1, 0xd1, 0x80, 0xd0, 0xb0, 0xd0, 0xbd, 0xd0, + 0xbd, 0xd0, 0xbe, 0xd0, 0xb5, 0xd0, 0xbd, 0xd0, 0xb0, 0xd1, 0x81, 0xd0, 0xb5, + 0xd0, 0xbb, 0xd0, 0xb5, 0xd0, 0xbd, 0xd0, 0xb8, 0xd1, 0x8f, 0xd0, 0xb8, 0xd0, + 0xb7, 0xd0, 0xbc, 0xd0, 0xb5, 0xd0, 0xbd, 0xd0, 0xb5, 0xd0, 0xbd, 0xd0, 0xb8, + 0xd1, 0x8f, 0xd0, 0xba, 0xd0, 0xb0, 0xd1, 0x82, 0xd0, 0xb5, 0xd0, 0xb3, 0xd0, + 0xbe, 0xd1, 0x80, 0xd0, 0xb8, 0xd0, 0xb8, 0xd0, 0x90, 0xd0, 0xbb, 0xd0, 0xb5, + 0xd0, 0xba, 0xd1, 0x81, 0xd0, 0xb0, 0xd0, 0xbd, 0xd0, 0xb4, 0xd1, 0x80, 0xe0, + 0xa4, 0xa6, 0xe0, 0xa5, 0x8d, 0xe0, 0xa4, 0xb5, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, + 0xb0, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, 0xae, 0xe0, 0xa5, 0x88, 0xe0, 0xa4, 0xa8, + 0xe0, 0xa5, 0x81, 0xe0, 0xa4, 0x85, 0xe0, 0xa4, 0xb2, 0xe0, 0xa4, 0xaa, 0xe0, + 0xa5, 0x8d, 0xe0, 0xa4, 0xb0, 0xe0, 0xa4, 0xa6, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, + 0xa8, 0xe0, 0xa4, 0xad, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, 0xb0, 0xe0, 0xa4, 0xa4, + 0xe0, 0xa5, 0x80, 0xe0, 0xa4, 0xaf, 0xe0, 0xa4, 0x85, 0xe0, 0xa4, 0xa8, 0xe0, + 0xa5, 0x81, 0xe0, 0xa4, 0xa6, 0xe0, 0xa5, 0x87, 0xe0, 0xa4, 0xb6, 0xe0, 0xa4, + 0xb9, 0xe0, 0xa4, 0xbf, 0xe0, 0xa4, 0xa8, 0xe0, 0xa5, 0x8d, 0xe0, 0xa4, 0xa6, + 0xe0, 0xa5, 0x80, 0xe0, 0xa4, 0x87, 0xe0, 0xa4, 0x82, 0xe0, 0xa4, 0xa1, 0xe0, + 0xa4, 0xbf, 0xe0, 0xa4, 0xaf, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, 0xa6, 0xe0, 0xa4, + 0xbf, 0xe0, 0xa4, 0xb2, 0xe0, 0xa5, 0x8d, 0xe0, 0xa4, 0xb2, 0xe0, 0xa5, 0x80, + 0xe0, 0xa4, 0x85, 0xe0, 0xa4, 0xa7, 0xe0, 0xa4, 0xbf, 0xe0, 0xa4, 0x95, 0xe0, + 0xa4, 0xbe, 0xe0, 0xa4, 0xb0, 0xe0, 0xa4, 0xb5, 0xe0, 0xa5, 0x80, 0xe0, 0xa4, + 0xa1, 0xe0, 0xa4, 0xbf, 0xe0, 0xa4, 0xaf, 0xe0, 0xa5, 0x8b, 0xe0, 0xa4, 0x9a, + 0xe0, 0xa4, 0xbf, 0xe0, 0xa4, 0x9f, 0xe0, 0xa5, 0x8d, 0xe0, 0xa4, 0xa0, 0xe0, + 0xa5, 0x87, 0xe0, 0xa4, 0xb8, 0xe0, 0xa4, 0xae, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, + 0x9a, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, 0xb0, 0xe0, 0xa4, 0x9c, 0xe0, 0xa4, 0x82, + 0xe0, 0xa4, 0x95, 0xe0, 0xa5, 0x8d, 0xe0, 0xa4, 0xb6, 0xe0, 0xa4, 0xa8, 0xe0, + 0xa4, 0xa6, 0xe0, 0xa5, 0x81, 0xe0, 0xa4, 0xa8, 0xe0, 0xa4, 0xbf, 0xe0, 0xa4, + 0xaf, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, 0xaa, 0xe0, 0xa5, 0x8d, 0xe0, 0xa4, 0xb0, + 0xe0, 0xa4, 0xaf, 0xe0, 0xa5, 0x8b, 0xe0, 0xa4, 0x97, 0xe0, 0xa4, 0x85, 0xe0, + 0xa4, 0xa8, 0xe0, 0xa5, 0x81, 0xe0, 0xa4, 0xb8, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, + 0xb0, 0xe0, 0xa4, 0x91, 0xe0, 0xa4, 0xa8, 0xe0, 0xa4, 0xb2, 0xe0, 0xa4, 0xbe, + 0xe0, 0xa4, 0x87, 0xe0, 0xa4, 0xa8, 0xe0, 0xa4, 0xaa, 0xe0, 0xa4, 0xbe, 0xe0, + 0xa4, 0xb0, 0xe0, 0xa5, 0x8d, 0xe0, 0xa4, 0x9f, 0xe0, 0xa5, 0x80, 0xe0, 0xa4, + 0xb6, 0xe0, 0xa4, 0xb0, 0xe0, 0xa5, 0x8d, 0xe0, 0xa4, 0xa4, 0xe0, 0xa5, 0x8b, + 0xe0, 0xa4, 0x82, 0xe0, 0xa4, 0xb2, 0xe0, 0xa5, 0x8b, 0xe0, 0xa4, 0x95, 0xe0, + 0xa4, 0xb8, 0xe0, 0xa4, 0xad, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, 0xab, 0xe0, 0xa4, + 0xbc, 0xe0, 0xa5, 0x8d, 0xe0, 0xa4, 0xb2, 0xe0, 0xa5, 0x88, 0xe0, 0xa4, 0xb6, + 0xe0, 0xa4, 0xb6, 0xe0, 0xa4, 0xb0, 0xe0, 0xa5, 0x8d, 0xe0, 0xa4, 0xa4, 0xe0, + 0xa5, 0x87, 0xe0, 0xa4, 0x82, 0xe0, 0xa4, 0xaa, 0xe0, 0xa5, 0x8d, 0xe0, 0xa4, + 0xb0, 0xe0, 0xa4, 0xa6, 0xe0, 0xa5, 0x87, 0xe0, 0xa4, 0xb6, 0xe0, 0xa4, 0xaa, + 0xe0, 0xa5, 0x8d, 0xe0, 0xa4, 0xb2, 0xe0, 0xa5, 0x87, 0xe0, 0xa4, 0xaf, 0xe0, + 0xa4, 0xb0, 0xe0, 0xa4, 0x95, 0xe0, 0xa5, 0x87, 0xe0, 0xa4, 0x82, 0xe0, 0xa4, + 0xa6, 0xe0, 0xa5, 0x8d, 0xe0, 0xa4, 0xb0, 0xe0, 0xa4, 0xb8, 0xe0, 0xa5, 0x8d, + 0xe0, 0xa4, 0xa5, 0xe0, 0xa4, 0xbf, 0xe0, 0xa4, 0xa4, 0xe0, 0xa4, 0xbf, 0xe0, + 0xa4, 0x89, 0xe0, 0xa4, 0xa4, 0xe0, 0xa5, 0x8d, 0xe0, 0xa4, 0xaa, 0xe0, 0xa4, + 0xbe, 0xe0, 0xa4, 0xa6, 0xe0, 0xa4, 0x89, 0xe0, 0xa4, 0xa8, 0xe0, 0xa5, 0x8d, + 0xe0, 0xa4, 0xb9, 0xe0, 0xa5, 0x87, 0xe0, 0xa4, 0x82, 0xe0, 0xa4, 0x9a, 0xe0, + 0xa4, 0xbf, 0xe0, 0xa4, 0x9f, 0xe0, 0xa5, 0x8d, 0xe0, 0xa4, 0xa0, 0xe0, 0xa4, + 0xbe, 0xe0, 0xa4, 0xaf, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, 0xa4, 0xe0, 0xa5, 0x8d, + 0xe0, 0xa4, 0xb0, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, 0x9c, 0xe0, 0xa5, 0x8d, 0xe0, + 0xa4, 0xaf, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, 0xa6, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, + 0xaa, 0xe0, 0xa5, 0x81, 0xe0, 0xa4, 0xb0, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, 0xa8, + 0xe0, 0xa5, 0x87, 0xe0, 0xa4, 0x9c, 0xe0, 0xa5, 0x8b, 0xe0, 0xa4, 0xa1, 0xe0, + 0xa4, 0xbc, 0xe0, 0xa5, 0x87, 0xe0, 0xa4, 0x82, 0xe0, 0xa4, 0x85, 0xe0, 0xa4, + 0xa8, 0xe0, 0xa5, 0x81, 0xe0, 0xa4, 0xb5, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, 0xa6, + 0xe0, 0xa4, 0xb6, 0xe0, 0xa5, 0x8d, 0xe0, 0xa4, 0xb0, 0xe0, 0xa5, 0x87, 0xe0, + 0xa4, 0xa3, 0xe0, 0xa5, 0x80, 0xe0, 0xa4, 0xb6, 0xe0, 0xa4, 0xbf, 0xe0, 0xa4, + 0x95, 0xe0, 0xa5, 0x8d, 0xe0, 0xa4, 0xb7, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, 0xb8, + 0xe0, 0xa4, 0xb0, 0xe0, 0xa4, 0x95, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, 0xb0, 0xe0, + 0xa5, 0x80, 0xe0, 0xa4, 0xb8, 0xe0, 0xa4, 0x82, 0xe0, 0xa4, 0x97, 0xe0, 0xa5, + 0x8d, 0xe0, 0xa4, 0xb0, 0xe0, 0xa4, 0xb9, 0xe0, 0xa4, 0xaa, 0xe0, 0xa4, 0xb0, + 0xe0, 0xa4, 0xbf, 0xe0, 0xa4, 0xa3, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, 0xae, 0xe0, + 0xa4, 0xac, 0xe0, 0xa5, 0x8d, 0xe0, 0xa4, 0xb0, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, + 0x82, 0xe0, 0xa4, 0xa1, 0xe0, 0xa4, 0xac, 0xe0, 0xa4, 0x9a, 0xe0, 0xa5, 0x8d, + 0xe0, 0xa4, 0x9a, 0xe0, 0xa5, 0x8b, 0xe0, 0xa4, 0x82, 0xe0, 0xa4, 0x89, 0xe0, + 0xa4, 0xaa, 0xe0, 0xa4, 0xb2, 0xe0, 0xa4, 0xac, 0xe0, 0xa5, 0x8d, 0xe0, 0xa4, + 0xa7, 0xe0, 0xa4, 0xae, 0xe0, 0xa4, 0x82, 0xe0, 0xa4, 0xa4, 0xe0, 0xa5, 0x8d, + 0xe0, 0xa4, 0xb0, 0xe0, 0xa5, 0x80, 0xe0, 0xa4, 0xb8, 0xe0, 0xa4, 0x82, 0xe0, + 0xa4, 0xaa, 0xe0, 0xa4, 0xb0, 0xe0, 0xa5, 0x8d, 0xe0, 0xa4, 0x95, 0xe0, 0xa4, + 0x89, 0xe0, 0xa4, 0xae, 0xe0, 0xa5, 0x8d, 0xe0, 0xa4, 0xae, 0xe0, 0xa5, 0x80, + 0xe0, 0xa4, 0xa6, 0xe0, 0xa4, 0xae, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, 0xa7, 0xe0, + 0xa5, 0x8d, 0xe0, 0xa4, 0xaf, 0xe0, 0xa4, 0xae, 0xe0, 0xa4, 0xb8, 0xe0, 0xa4, + 0xb9, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, 0xaf, 0xe0, 0xa4, 0xa4, 0xe0, 0xa4, 0xbe, + 0xe0, 0xa4, 0xb6, 0xe0, 0xa4, 0xac, 0xe0, 0xa5, 0x8d, 0xe0, 0xa4, 0xa6, 0xe0, + 0xa5, 0x8b, 0xe0, 0xa4, 0x82, 0xe0, 0xa4, 0xae, 0xe0, 0xa5, 0x80, 0xe0, 0xa4, + 0xa1, 0xe0, 0xa4, 0xbf, 0xe0, 0xa4, 0xaf, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, 0x86, + 0xe0, 0xa4, 0x88, 0xe0, 0xa4, 0xaa, 0xe0, 0xa5, 0x80, 0xe0, 0xa4, 0x8f, 0xe0, + 0xa4, 0xb2, 0xe0, 0xa4, 0xae, 0xe0, 0xa5, 0x8b, 0xe0, 0xa4, 0xac, 0xe0, 0xa4, + 0xbe, 0xe0, 0xa4, 0x87, 0xe0, 0xa4, 0xb2, 0xe0, 0xa4, 0xb8, 0xe0, 0xa4, 0x82, + 0xe0, 0xa4, 0x96, 0xe0, 0xa5, 0x8d, 0xe0, 0xa4, 0xaf, 0xe0, 0xa4, 0xbe, 0xe0, + 0xa4, 0x86, 0xe0, 0xa4, 0xaa, 0xe0, 0xa4, 0xb0, 0xe0, 0xa5, 0x87, 0xe0, 0xa4, + 0xb6, 0xe0, 0xa4, 0xa8, 0xe0, 0xa4, 0x85, 0xe0, 0xa4, 0xa8, 0xe0, 0xa5, 0x81, + 0xe0, 0xa4, 0xac, 0xe0, 0xa4, 0x82, 0xe0, 0xa4, 0xa7, 0xe0, 0xa4, 0xac, 0xe0, + 0xa4, 0xbe, 0xe0, 0xa4, 0x9c, 0xe0, 0xa4, 0xbc, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, + 0xb0, 0xe0, 0xa4, 0xa8, 0xe0, 0xa4, 0xb5, 0xe0, 0xa5, 0x80, 0xe0, 0xa4, 0xa8, + 0xe0, 0xa4, 0xa4, 0xe0, 0xa4, 0xae, 0xe0, 0xa4, 0xaa, 0xe0, 0xa5, 0x8d, 0xe0, + 0xa4, 0xb0, 0xe0, 0xa4, 0xae, 0xe0, 0xa5, 0x81, 0xe0, 0xa4, 0x96, 0xe0, 0xa4, + 0xaa, 0xe0, 0xa5, 0x8d, 0xe0, 0xa4, 0xb0, 0xe0, 0xa4, 0xb6, 0xe0, 0xa5, 0x8d, + 0xe0, 0xa4, 0xa8, 0xe0, 0xa4, 0xaa, 0xe0, 0xa4, 0xb0, 0xe0, 0xa4, 0xbf, 0xe0, + 0xa4, 0xb5, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, 0xb0, 0xe0, 0xa4, 0xa8, 0xe0, 0xa5, + 0x81, 0xe0, 0xa4, 0x95, 0xe0, 0xa4, 0xb8, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, 0xa8, + 0xe0, 0xa4, 0xb8, 0xe0, 0xa4, 0xae, 0xe0, 0xa4, 0xb0, 0xe0, 0xa5, 0x8d, 0xe0, + 0xa4, 0xa5, 0xe0, 0xa4, 0xa8, 0xe0, 0xa4, 0x86, 0xe0, 0xa4, 0xaf, 0xe0, 0xa5, + 0x8b, 0xe0, 0xa4, 0x9c, 0xe0, 0xa4, 0xbf, 0xe0, 0xa4, 0xa4, 0xe0, 0xa4, 0xb8, + 0xe0, 0xa5, 0x8b, 0xe0, 0xa4, 0xae, 0xe0, 0xa4, 0xb5, 0xe0, 0xa4, 0xbe, 0xe0, + 0xa4, 0xb0, 0xd8, 0xa7, 0xd9, 0x84, 0xd9, 0x85, 0xd8, 0xb4, 0xd8, 0xa7, 0xd8, + 0xb1, 0xd9, 0x83, 0xd8, 0xa7, 0xd8, 0xaa, 0xd8, 0xa7, 0xd9, 0x84, 0xd9, 0x85, + 0xd9, 0x86, 0xd8, 0xaa, 0xd8, 0xaf, 0xd9, 0x8a, 0xd8, 0xa7, 0xd8, 0xaa, 0xd8, + 0xa7, 0xd9, 0x84, 0xd9, 0x83, 0xd9, 0x85, 0xd8, 0xa8, 0xd9, 0x8a, 0xd9, 0x88, + 0xd8, 0xaa, 0xd8, 0xb1, 0xd8, 0xa7, 0xd9, 0x84, 0xd9, 0x85, 0xd8, 0xb4, 0xd8, + 0xa7, 0xd9, 0x87, 0xd8, 0xaf, 0xd8, 0xa7, 0xd8, 0xaa, 0xd8, 0xb9, 0xd8, 0xaf, + 0xd8, 0xaf, 0xd8, 0xa7, 0xd9, 0x84, 0xd8, 0xb2, 0xd9, 0x88, 0xd8, 0xa7, 0xd8, + 0xb1, 0xd8, 0xb9, 0xd8, 0xaf, 0xd8, 0xaf, 0xd8, 0xa7, 0xd9, 0x84, 0xd8, 0xb1, + 0xd8, 0xaf, 0xd9, 0x88, 0xd8, 0xaf, 0xd8, 0xa7, 0xd9, 0x84, 0xd8, 0xa5, 0xd8, + 0xb3, 0xd9, 0x84, 0xd8, 0xa7, 0xd9, 0x85, 0xd9, 0x8a, 0xd8, 0xa9, 0xd8, 0xa7, + 0xd9, 0x84, 0xd9, 0x81, 0xd9, 0x88, 0xd8, 0xaa, 0xd9, 0x88, 0xd8, 0xb4, 0xd9, + 0x88, 0xd8, 0xa8, 0xd8, 0xa7, 0xd9, 0x84, 0xd9, 0x85, 0xd8, 0xb3, 0xd8, 0xa7, + 0xd8, 0xa8, 0xd9, 0x82, 0xd8, 0xa7, 0xd8, 0xaa, 0xd8, 0xa7, 0xd9, 0x84, 0xd9, + 0x85, 0xd8, 0xb9, 0xd9, 0x84, 0xd9, 0x88, 0xd9, 0x85, 0xd8, 0xa7, 0xd8, 0xaa, + 0xd8, 0xa7, 0xd9, 0x84, 0xd9, 0x85, 0xd8, 0xb3, 0xd9, 0x84, 0xd8, 0xb3, 0xd9, + 0x84, 0xd8, 0xa7, 0xd8, 0xaa, 0xd8, 0xa7, 0xd9, 0x84, 0xd8, 0xac, 0xd8, 0xb1, + 0xd8, 0xa7, 0xd9, 0x81, 0xd9, 0x8a, 0xd9, 0x83, 0xd8, 0xb3, 0xd8, 0xa7, 0xd9, + 0x84, 0xd8, 0xa7, 0xd8, 0xb3, 0xd9, 0x84, 0xd8, 0xa7, 0xd9, 0x85, 0xd9, 0x8a, + 0xd8, 0xa9, 0xd8, 0xa7, 0xd9, 0x84, 0xd8, 0xa7, 0xd8, 0xaa, 0xd8, 0xb5, 0xd8, + 0xa7, 0xd9, 0x84, 0xd8, 0xa7, 0xd8, 0xaa, 0x6b, 0x65, 0x79, 0x77, 0x6f, 0x72, + 0x64, 0x73, 0x22, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x3d, 0x22, + 0x77, 0x33, 0x2e, 0x6f, 0x72, 0x67, 0x2f, 0x31, 0x39, 0x39, 0x39, 0x2f, 0x78, + 0x68, 0x74, 0x6d, 0x6c, 0x22, 0x3e, 0x3c, 0x61, 0x20, 0x74, 0x61, 0x72, 0x67, + 0x65, 0x74, 0x3d, 0x22, 0x5f, 0x62, 0x6c, 0x61, 0x6e, 0x6b, 0x22, 0x20, 0x74, + 0x65, 0x78, 0x74, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x3b, 0x20, 0x63, 0x68, 0x61, + 0x72, 0x73, 0x65, 0x74, 0x3d, 0x22, 0x20, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, + 0x3d, 0x22, 0x5f, 0x62, 0x6c, 0x61, 0x6e, 0x6b, 0x22, 0x3e, 0x3c, 0x74, 0x61, + 0x62, 0x6c, 0x65, 0x20, 0x63, 0x65, 0x6c, 0x6c, 0x70, 0x61, 0x64, 0x64, 0x69, + 0x6e, 0x67, 0x3d, 0x22, 0x61, 0x75, 0x74, 0x6f, 0x63, 0x6f, 0x6d, 0x70, 0x6c, + 0x65, 0x74, 0x65, 0x3d, 0x22, 0x6f, 0x66, 0x66, 0x22, 0x20, 0x74, 0x65, 0x78, + 0x74, 0x2d, 0x61, 0x6c, 0x69, 0x67, 0x6e, 0x3a, 0x20, 0x63, 0x65, 0x6e, 0x74, + 0x65, 0x72, 0x3b, 0x74, 0x6f, 0x20, 0x6c, 0x61, 0x73, 0x74, 0x20, 0x76, 0x65, + 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x20, 0x62, 0x79, 0x20, 0x62, 0x61, 0x63, 0x6b, + 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x2d, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, + 0x20, 0x23, 0x22, 0x20, 0x68, 0x72, 0x65, 0x66, 0x3d, 0x22, 0x68, 0x74, 0x74, + 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x2f, 0x64, 0x69, 0x76, 0x3e, + 0x3c, 0x2f, 0x64, 0x69, 0x76, 0x3e, 0x3c, 0x64, 0x69, 0x76, 0x20, 0x69, 0x64, + 0x3d, 0x3c, 0x61, 0x20, 0x68, 0x72, 0x65, 0x66, 0x3d, 0x22, 0x23, 0x22, 0x20, + 0x63, 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x22, 0x22, 0x3e, 0x3c, 0x69, 0x6d, 0x67, + 0x20, 0x73, 0x72, 0x63, 0x3d, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, + 0x63, 0x72, 0x69, 0x70, 0x74, 0x22, 0x20, 0x73, 0x72, 0x63, 0x3d, 0x22, 0x68, + 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x0a, 0x3c, 0x73, 0x63, 0x72, 0x69, 0x70, + 0x74, 0x20, 0x6c, 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, 0x3d, 0x22, 0x2f, + 0x2f, 0x45, 0x4e, 0x22, 0x20, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, + 0x77, 0x77, 0x77, 0x2e, 0x77, 0x65, 0x6e, 0x63, 0x6f, 0x64, 0x65, 0x55, 0x52, + 0x49, 0x43, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x28, 0x22, 0x20, + 0x68, 0x72, 0x65, 0x66, 0x3d, 0x22, 0x6a, 0x61, 0x76, 0x61, 0x73, 0x63, 0x72, + 0x69, 0x70, 0x74, 0x3a, 0x3c, 0x64, 0x69, 0x76, 0x20, 0x63, 0x6c, 0x61, 0x73, + 0x73, 0x3d, 0x22, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x64, 0x6f, 0x63, + 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x77, 0x72, 0x69, 0x74, 0x65, 0x28, 0x27, + 0x3c, 0x73, 0x63, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, + 0x61, 0x62, 0x73, 0x6f, 0x6c, 0x75, 0x74, 0x65, 0x3b, 0x73, 0x63, 0x72, 0x69, + 0x70, 0x74, 0x20, 0x73, 0x72, 0x63, 0x3d, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, + 0x2f, 0x2f, 0x20, 0x73, 0x74, 0x79, 0x6c, 0x65, 0x3d, 0x22, 0x6d, 0x61, 0x72, + 0x67, 0x69, 0x6e, 0x2d, 0x74, 0x6f, 0x70, 0x3a, 0x2e, 0x6d, 0x69, 0x6e, 0x2e, + 0x6a, 0x73, 0x22, 0x3e, 0x3c, 0x2f, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x3e, + 0x0a, 0x3c, 0x2f, 0x64, 0x69, 0x76, 0x3e, 0x0a, 0x3c, 0x64, 0x69, 0x76, 0x20, + 0x63, 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x22, 0x77, 0x33, 0x2e, 0x6f, 0x72, 0x67, + 0x2f, 0x31, 0x39, 0x39, 0x39, 0x2f, 0x78, 0x68, 0x74, 0x6d, 0x6c, 0x22, 0x20, + 0x0a, 0x0d, 0x0a, 0x3c, 0x2f, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0x0d, 0x0a, 0x3c, + 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x3e, 0x64, 0x69, 0x73, 0x74, 0x69, 0x6e, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x62, 0x65, 0x74, 0x77, 0x65, 0x65, 0x6e, 0x2f, + 0x22, 0x20, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x3d, 0x22, 0x5f, 0x62, 0x6c, + 0x61, 0x6e, 0x6b, 0x22, 0x3e, 0x3c, 0x6c, 0x69, 0x6e, 0x6b, 0x20, 0x68, 0x72, + 0x65, 0x66, 0x3d, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x65, 0x6e, + 0x63, 0x6f, 0x64, 0x69, 0x6e, 0x67, 0x3d, 0x22, 0x75, 0x74, 0x66, 0x2d, 0x38, + 0x22, 0x3f, 0x3e, 0x0a, 0x77, 0x2e, 0x61, 0x64, 0x64, 0x45, 0x76, 0x65, 0x6e, + 0x74, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x3f, 0x61, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x3d, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, + 0x77, 0x77, 0x2e, 0x69, 0x63, 0x6f, 0x6e, 0x22, 0x20, 0x68, 0x72, 0x65, 0x66, + 0x3d, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x20, 0x73, 0x74, 0x79, + 0x6c, 0x65, 0x3d, 0x22, 0x62, 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, + 0x64, 0x3a, 0x74, 0x79, 0x70, 0x65, 0x3d, 0x22, 0x74, 0x65, 0x78, 0x74, 0x2f, + 0x63, 0x73, 0x73, 0x22, 0x20, 0x2f, 0x3e, 0x0a, 0x6d, 0x65, 0x74, 0x61, 0x20, + 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x3d, 0x22, 0x6f, 0x67, 0x3a, + 0x74, 0x3c, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x20, 0x74, 0x79, 0x70, 0x65, 0x3d, + 0x22, 0x74, 0x65, 0x78, 0x74, 0x22, 0x20, 0x20, 0x73, 0x74, 0x79, 0x6c, 0x65, + 0x3d, 0x22, 0x74, 0x65, 0x78, 0x74, 0x2d, 0x61, 0x6c, 0x69, 0x67, 0x6e, 0x3a, + 0x74, 0x68, 0x65, 0x20, 0x64, 0x65, 0x76, 0x65, 0x6c, 0x6f, 0x70, 0x6d, 0x65, + 0x6e, 0x74, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x79, 0x6c, 0x65, 0x73, 0x68, 0x65, + 0x65, 0x74, 0x22, 0x20, 0x74, 0x79, 0x70, 0x65, 0x3d, 0x22, 0x74, 0x65, 0x68, + 0x74, 0x6d, 0x6c, 0x3b, 0x20, 0x63, 0x68, 0x61, 0x72, 0x73, 0x65, 0x74, 0x3d, + 0x75, 0x74, 0x66, 0x2d, 0x38, 0x69, 0x73, 0x20, 0x63, 0x6f, 0x6e, 0x73, 0x69, + 0x64, 0x65, 0x72, 0x65, 0x64, 0x20, 0x74, 0x6f, 0x20, 0x62, 0x65, 0x74, 0x61, + 0x62, 0x6c, 0x65, 0x20, 0x77, 0x69, 0x64, 0x74, 0x68, 0x3d, 0x22, 0x31, 0x30, + 0x30, 0x25, 0x22, 0x20, 0x49, 0x6e, 0x20, 0x61, 0x64, 0x64, 0x69, 0x74, 0x69, + 0x6f, 0x6e, 0x20, 0x74, 0x6f, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x6f, 0x6e, + 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x64, 0x20, 0x74, 0x6f, 0x20, 0x74, + 0x68, 0x65, 0x20, 0x64, 0x69, 0x66, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, + 0x73, 0x20, 0x62, 0x65, 0x74, 0x77, 0x65, 0x65, 0x6e, 0x64, 0x65, 0x76, 0x65, + 0x6c, 0x6f, 0x70, 0x6d, 0x65, 0x6e, 0x74, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, + 0x65, 0x20, 0x49, 0x74, 0x20, 0x69, 0x73, 0x20, 0x69, 0x6d, 0x70, 0x6f, 0x72, + 0x74, 0x61, 0x6e, 0x74, 0x20, 0x74, 0x6f, 0x20, 0x3c, 0x2f, 0x73, 0x63, 0x72, + 0x69, 0x70, 0x74, 0x3e, 0x0a, 0x0a, 0x3c, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, + 0x20, 0x20, 0x73, 0x74, 0x79, 0x6c, 0x65, 0x3d, 0x22, 0x66, 0x6f, 0x6e, 0x74, + 0x2d, 0x73, 0x69, 0x7a, 0x65, 0x3a, 0x31, 0x3e, 0x3c, 0x2f, 0x73, 0x70, 0x61, + 0x6e, 0x3e, 0x3c, 0x73, 0x70, 0x61, 0x6e, 0x20, 0x69, 0x64, 0x3d, 0x67, 0x62, + 0x4c, 0x69, 0x62, 0x72, 0x61, 0x72, 0x79, 0x20, 0x6f, 0x66, 0x20, 0x43, 0x6f, + 0x6e, 0x67, 0x72, 0x65, 0x73, 0x73, 0x3c, 0x69, 0x6d, 0x67, 0x20, 0x73, 0x72, + 0x63, 0x3d, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x69, 0x6d, 0x45, + 0x6e, 0x67, 0x6c, 0x69, 0x73, 0x68, 0x20, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x6c, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x41, 0x63, 0x61, 0x64, 0x65, 0x6d, 0x79, 0x20, + 0x6f, 0x66, 0x20, 0x53, 0x63, 0x69, 0x65, 0x6e, 0x63, 0x65, 0x73, 0x64, 0x69, + 0x76, 0x20, 0x73, 0x74, 0x79, 0x6c, 0x65, 0x3d, 0x22, 0x64, 0x69, 0x73, 0x70, + 0x6c, 0x61, 0x79, 0x3a, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x2e, 0x67, 0x65, + 0x74, 0x45, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x42, 0x79, 0x49, 0x64, 0x28, + 0x69, 0x64, 0x29, 0x69, 0x6e, 0x20, 0x63, 0x6f, 0x6e, 0x6a, 0x75, 0x6e, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x77, 0x69, 0x74, 0x68, 0x45, 0x6c, 0x65, 0x6d, + 0x65, 0x6e, 0x74, 0x28, 0x27, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x27, 0x29, + 0x3b, 0x20, 0x3c, 0x6d, 0x65, 0x74, 0x61, 0x20, 0x70, 0x72, 0x6f, 0x70, 0x65, + 0x72, 0x74, 0x79, 0x3d, 0x22, 0x6f, 0x67, 0x3a, 0xd0, 0x91, 0xd1, 0x8a, 0xd0, + 0xbb, 0xd0, 0xb3, 0xd0, 0xb0, 0xd1, 0x80, 0xd1, 0x81, 0xd0, 0xba, 0xd0, 0xb8, + 0x0a, 0x20, 0x74, 0x79, 0x70, 0x65, 0x3d, 0x22, 0x74, 0x65, 0x78, 0x74, 0x22, + 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x3d, 0x22, 0x3e, 0x50, 0x72, 0x69, 0x76, 0x61, + 0x63, 0x79, 0x20, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x3c, 0x2f, 0x61, 0x3e, + 0x61, 0x64, 0x6d, 0x69, 0x6e, 0x69, 0x73, 0x74, 0x65, 0x72, 0x65, 0x64, 0x20, + 0x62, 0x79, 0x20, 0x74, 0x68, 0x65, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x53, + 0x69, 0x6e, 0x67, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x73, + 0x74, 0x79, 0x6c, 0x65, 0x3d, 0x26, 0x71, 0x75, 0x6f, 0x74, 0x3b, 0x6d, 0x61, + 0x72, 0x67, 0x69, 0x6e, 0x3a, 0x3c, 0x2f, 0x64, 0x69, 0x76, 0x3e, 0x3c, 0x2f, + 0x64, 0x69, 0x76, 0x3e, 0x3c, 0x2f, 0x64, 0x69, 0x76, 0x3e, 0x3c, 0x3e, 0x3c, + 0x69, 0x6d, 0x67, 0x20, 0x73, 0x72, 0x63, 0x3d, 0x22, 0x68, 0x74, 0x74, 0x70, + 0x3a, 0x2f, 0x2f, 0x69, 0x20, 0x73, 0x74, 0x79, 0x6c, 0x65, 0x3d, 0x26, 0x71, + 0x75, 0x6f, 0x74, 0x3b, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x3a, 0x72, 0x65, 0x66, + 0x65, 0x72, 0x72, 0x65, 0x64, 0x20, 0x74, 0x6f, 0x20, 0x61, 0x73, 0x20, 0x74, + 0x68, 0x65, 0x20, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x20, 0x70, 0x6f, 0x70, 0x75, + 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6f, 0x66, 0x69, 0x6e, 0x20, 0x57, + 0x61, 0x73, 0x68, 0x69, 0x6e, 0x67, 0x74, 0x6f, 0x6e, 0x2c, 0x20, 0x44, 0x2e, + 0x43, 0x2e, 0x20, 0x73, 0x74, 0x79, 0x6c, 0x65, 0x3d, 0x22, 0x62, 0x61, 0x63, + 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x2d, 0x61, 0x6d, 0x6f, 0x6e, 0x67, + 0x20, 0x6f, 0x74, 0x68, 0x65, 0x72, 0x20, 0x74, 0x68, 0x69, 0x6e, 0x67, 0x73, + 0x2c, 0x6f, 0x72, 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x70, 0x61, 0x72, 0x74, 0x69, 0x63, + 0x69, 0x70, 0x61, 0x74, 0x65, 0x64, 0x20, 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, + 0x74, 0x68, 0x65, 0x20, 0x69, 0x6e, 0x74, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x20, 0x6f, 0x66, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, + 0x69, 0x65, 0x64, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x74, 0x68, 0x65, 0x66, + 0x69, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x20, 0x63, 0x68, 0x61, 0x72, + 0x61, 0x63, 0x74, 0x65, 0x72, 0x20, 0x4f, 0x78, 0x66, 0x6f, 0x72, 0x64, 0x20, + 0x55, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x69, 0x74, 0x79, 0x20, 0x6d, 0x69, + 0x73, 0x75, 0x6e, 0x64, 0x65, 0x72, 0x73, 0x74, 0x61, 0x6e, 0x64, 0x69, 0x6e, + 0x67, 0x20, 0x6f, 0x66, 0x54, 0x68, 0x65, 0x72, 0x65, 0x20, 0x61, 0x72, 0x65, + 0x2c, 0x20, 0x68, 0x6f, 0x77, 0x65, 0x76, 0x65, 0x72, 0x2c, 0x73, 0x74, 0x79, + 0x6c, 0x65, 0x73, 0x68, 0x65, 0x65, 0x74, 0x22, 0x20, 0x68, 0x72, 0x65, 0x66, + 0x3d, 0x22, 0x2f, 0x43, 0x6f, 0x6c, 0x75, 0x6d, 0x62, 0x69, 0x61, 0x20, 0x55, + 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x69, 0x74, 0x79, 0x65, 0x78, 0x70, 0x61, + 0x6e, 0x64, 0x65, 0x64, 0x20, 0x74, 0x6f, 0x20, 0x69, 0x6e, 0x63, 0x6c, 0x75, + 0x64, 0x65, 0x75, 0x73, 0x75, 0x61, 0x6c, 0x6c, 0x79, 0x20, 0x72, 0x65, 0x66, + 0x65, 0x72, 0x72, 0x65, 0x64, 0x20, 0x74, 0x6f, 0x69, 0x6e, 0x64, 0x69, 0x63, + 0x61, 0x74, 0x69, 0x6e, 0x67, 0x20, 0x74, 0x68, 0x61, 0x74, 0x20, 0x74, 0x68, + 0x65, 0x68, 0x61, 0x76, 0x65, 0x20, 0x73, 0x75, 0x67, 0x67, 0x65, 0x73, 0x74, + 0x65, 0x64, 0x20, 0x74, 0x68, 0x61, 0x74, 0x61, 0x66, 0x66, 0x69, 0x6c, 0x69, + 0x61, 0x74, 0x65, 0x64, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x74, 0x68, 0x65, + 0x63, 0x6f, 0x72, 0x72, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x62, + 0x65, 0x74, 0x77, 0x65, 0x65, 0x6e, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x20, + 0x6f, 0x66, 0x20, 0x64, 0x69, 0x66, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x74, 0x3e, + 0x3c, 0x2f, 0x74, 0x64, 0x3e, 0x3c, 0x2f, 0x74, 0x72, 0x3e, 0x3c, 0x2f, 0x74, + 0x61, 0x62, 0x6c, 0x65, 0x3e, 0x52, 0x65, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, + 0x20, 0x6f, 0x66, 0x20, 0x49, 0x72, 0x65, 0x6c, 0x61, 0x6e, 0x64, 0x0a, 0x3c, + 0x2f, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x3e, 0x0a, 0x3c, 0x73, 0x63, 0x72, + 0x69, 0x70, 0x74, 0x20, 0x75, 0x6e, 0x64, 0x65, 0x72, 0x20, 0x74, 0x68, 0x65, + 0x20, 0x69, 0x6e, 0x66, 0x6c, 0x75, 0x65, 0x6e, 0x63, 0x65, 0x63, 0x6f, 0x6e, + 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x74, 0x6f, 0x20, + 0x74, 0x68, 0x65, 0x4f, 0x66, 0x66, 0x69, 0x63, 0x69, 0x61, 0x6c, 0x20, 0x77, + 0x65, 0x62, 0x73, 0x69, 0x74, 0x65, 0x20, 0x6f, 0x66, 0x68, 0x65, 0x61, 0x64, + 0x71, 0x75, 0x61, 0x72, 0x74, 0x65, 0x72, 0x73, 0x20, 0x6f, 0x66, 0x20, 0x74, + 0x68, 0x65, 0x63, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x65, 0x64, 0x20, 0x61, 0x72, + 0x6f, 0x75, 0x6e, 0x64, 0x20, 0x74, 0x68, 0x65, 0x69, 0x6d, 0x70, 0x6c, 0x69, + 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, + 0x65, 0x68, 0x61, 0x76, 0x65, 0x20, 0x62, 0x65, 0x65, 0x6e, 0x20, 0x64, 0x65, + 0x76, 0x65, 0x6c, 0x6f, 0x70, 0x65, 0x64, 0x46, 0x65, 0x64, 0x65, 0x72, 0x61, + 0x6c, 0x20, 0x52, 0x65, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x20, 0x6f, 0x66, + 0x62, 0x65, 0x63, 0x61, 0x6d, 0x65, 0x20, 0x69, 0x6e, 0x63, 0x72, 0x65, 0x61, + 0x73, 0x69, 0x6e, 0x67, 0x6c, 0x79, 0x63, 0x6f, 0x6e, 0x74, 0x69, 0x6e, 0x75, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x4e, + 0x6f, 0x74, 0x65, 0x2c, 0x20, 0x68, 0x6f, 0x77, 0x65, 0x76, 0x65, 0x72, 0x2c, + 0x20, 0x74, 0x68, 0x61, 0x74, 0x73, 0x69, 0x6d, 0x69, 0x6c, 0x61, 0x72, 0x20, + 0x74, 0x6f, 0x20, 0x74, 0x68, 0x61, 0x74, 0x20, 0x6f, 0x66, 0x20, 0x63, 0x61, + 0x70, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x69, 0x65, 0x73, 0x20, 0x6f, 0x66, + 0x20, 0x74, 0x68, 0x65, 0x61, 0x63, 0x63, 0x6f, 0x72, 0x64, 0x61, 0x6e, 0x63, + 0x65, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x74, 0x68, 0x65, 0x70, 0x61, 0x72, + 0x74, 0x69, 0x63, 0x69, 0x70, 0x61, 0x6e, 0x74, 0x73, 0x20, 0x69, 0x6e, 0x20, + 0x74, 0x68, 0x65, 0x66, 0x75, 0x72, 0x74, 0x68, 0x65, 0x72, 0x20, 0x64, 0x65, + 0x76, 0x65, 0x6c, 0x6f, 0x70, 0x6d, 0x65, 0x6e, 0x74, 0x75, 0x6e, 0x64, 0x65, + 0x72, 0x20, 0x74, 0x68, 0x65, 0x20, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x69, 0x73, 0x20, 0x6f, 0x66, 0x74, 0x65, 0x6e, 0x20, 0x63, 0x6f, + 0x6e, 0x73, 0x69, 0x64, 0x65, 0x72, 0x65, 0x64, 0x68, 0x69, 0x73, 0x20, 0x79, + 0x6f, 0x75, 0x6e, 0x67, 0x65, 0x72, 0x20, 0x62, 0x72, 0x6f, 0x74, 0x68, 0x65, + 0x72, 0x3c, 0x2f, 0x74, 0x64, 0x3e, 0x3c, 0x2f, 0x74, 0x72, 0x3e, 0x3c, 0x2f, + 0x74, 0x61, 0x62, 0x6c, 0x65, 0x3e, 0x3c, 0x61, 0x20, 0x68, 0x74, 0x74, 0x70, + 0x2d, 0x65, 0x71, 0x75, 0x69, 0x76, 0x3d, 0x22, 0x58, 0x2d, 0x55, 0x41, 0x2d, + 0x70, 0x68, 0x79, 0x73, 0x69, 0x63, 0x61, 0x6c, 0x20, 0x70, 0x72, 0x6f, 0x70, + 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x6f, 0x66, 0x20, 0x42, 0x72, 0x69, 0x74, + 0x69, 0x73, 0x68, 0x20, 0x43, 0x6f, 0x6c, 0x75, 0x6d, 0x62, 0x69, 0x61, 0x68, + 0x61, 0x73, 0x20, 0x62, 0x65, 0x65, 0x6e, 0x20, 0x63, 0x72, 0x69, 0x74, 0x69, + 0x63, 0x69, 0x7a, 0x65, 0x64, 0x28, 0x77, 0x69, 0x74, 0x68, 0x20, 0x74, 0x68, + 0x65, 0x20, 0x65, 0x78, 0x63, 0x65, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x61, 0x62, 0x6f, 0x75, 0x74, + 0x20, 0x74, 0x68, 0x65, 0x70, 0x61, 0x73, 0x73, 0x69, 0x6e, 0x67, 0x20, 0x74, + 0x68, 0x72, 0x6f, 0x75, 0x67, 0x68, 0x20, 0x74, 0x68, 0x65, 0x30, 0x22, 0x20, + 0x63, 0x65, 0x6c, 0x6c, 0x70, 0x61, 0x64, 0x64, 0x69, 0x6e, 0x67, 0x3d, 0x22, + 0x30, 0x22, 0x20, 0x74, 0x68, 0x6f, 0x75, 0x73, 0x61, 0x6e, 0x64, 0x73, 0x20, + 0x6f, 0x66, 0x20, 0x70, 0x65, 0x6f, 0x70, 0x6c, 0x65, 0x72, 0x65, 0x64, 0x69, + 0x72, 0x65, 0x63, 0x74, 0x73, 0x20, 0x68, 0x65, 0x72, 0x65, 0x2e, 0x20, 0x46, + 0x6f, 0x72, 0x68, 0x61, 0x76, 0x65, 0x20, 0x63, 0x68, 0x69, 0x6c, 0x64, 0x72, + 0x65, 0x6e, 0x20, 0x75, 0x6e, 0x64, 0x65, 0x72, 0x25, 0x33, 0x45, 0x25, 0x33, + 0x43, 0x2f, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x25, 0x33, 0x45, 0x22, 0x29, + 0x29, 0x3b, 0x3c, 0x61, 0x20, 0x68, 0x72, 0x65, 0x66, 0x3d, 0x22, 0x68, 0x74, + 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x3c, 0x6c, 0x69, 0x3e, + 0x3c, 0x61, 0x20, 0x68, 0x72, 0x65, 0x66, 0x3d, 0x22, 0x68, 0x74, 0x74, 0x70, + 0x3a, 0x2f, 0x2f, 0x73, 0x69, 0x74, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x22, + 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x3d, 0x22, 0x74, 0x65, 0x78, + 0x74, 0x2d, 0x64, 0x65, 0x63, 0x6f, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3a, + 0x6e, 0x6f, 0x6e, 0x65, 0x73, 0x74, 0x79, 0x6c, 0x65, 0x3d, 0x22, 0x64, 0x69, + 0x73, 0x70, 0x6c, 0x61, 0x79, 0x3a, 0x20, 0x6e, 0x6f, 0x6e, 0x65, 0x3c, 0x6d, + 0x65, 0x74, 0x61, 0x20, 0x68, 0x74, 0x74, 0x70, 0x2d, 0x65, 0x71, 0x75, 0x69, + 0x76, 0x3d, 0x22, 0x58, 0x2d, 0x6e, 0x65, 0x77, 0x20, 0x44, 0x61, 0x74, 0x65, + 0x28, 0x29, 0x2e, 0x67, 0x65, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x28, 0x29, 0x20, + 0x74, 0x79, 0x70, 0x65, 0x3d, 0x22, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x2f, 0x78, + 0x2d, 0x69, 0x63, 0x6f, 0x6e, 0x22, 0x3c, 0x2f, 0x73, 0x70, 0x61, 0x6e, 0x3e, + 0x3c, 0x73, 0x70, 0x61, 0x6e, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x22, + 0x6c, 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, 0x3d, 0x22, 0x6a, 0x61, 0x76, + 0x61, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x77, 0x69, 0x6e, 0x64, 0x6f, 0x77, + 0x2e, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x68, 0x72, 0x65, + 0x66, 0x3c, 0x61, 0x20, 0x68, 0x72, 0x65, 0x66, 0x3d, 0x22, 0x6a, 0x61, 0x76, + 0x61, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x3a, 0x2d, 0x2d, 0x3e, 0x0d, 0x0a, + 0x3c, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x20, 0x74, 0x79, 0x70, 0x65, 0x3d, + 0x22, 0x74, 0x3c, 0x61, 0x20, 0x68, 0x72, 0x65, 0x66, 0x3d, 0x27, 0x68, 0x74, + 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x68, 0x6f, 0x72, 0x74, + 0x63, 0x75, 0x74, 0x20, 0x69, 0x63, 0x6f, 0x6e, 0x22, 0x20, 0x68, 0x72, 0x65, + 0x66, 0x3d, 0x22, 0x3c, 0x2f, 0x64, 0x69, 0x76, 0x3e, 0x0d, 0x0a, 0x3c, 0x64, + 0x69, 0x76, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x22, 0x3c, 0x73, 0x63, + 0x72, 0x69, 0x70, 0x74, 0x20, 0x73, 0x72, 0x63, 0x3d, 0x22, 0x68, 0x74, 0x74, + 0x70, 0x3a, 0x2f, 0x2f, 0x22, 0x20, 0x72, 0x65, 0x6c, 0x3d, 0x22, 0x73, 0x74, + 0x79, 0x6c, 0x65, 0x73, 0x68, 0x65, 0x65, 0x74, 0x22, 0x20, 0x74, 0x3c, 0x2f, + 0x64, 0x69, 0x76, 0x3e, 0x0a, 0x3c, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x20, + 0x74, 0x79, 0x70, 0x65, 0x3d, 0x2f, 0x61, 0x3e, 0x20, 0x3c, 0x61, 0x20, 0x68, + 0x72, 0x65, 0x66, 0x3d, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x20, + 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x61, 0x72, + 0x65, 0x6e, 0x63, 0x79, 0x3d, 0x22, 0x58, 0x2d, 0x55, 0x41, 0x2d, 0x43, 0x6f, + 0x6d, 0x70, 0x61, 0x74, 0x69, 0x62, 0x6c, 0x65, 0x22, 0x20, 0x63, 0x6f, 0x6e, + 0x72, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x68, 0x69, 0x70, 0x20, + 0x62, 0x65, 0x74, 0x77, 0x65, 0x65, 0x6e, 0x0a, 0x3c, 0x2f, 0x73, 0x63, 0x72, + 0x69, 0x70, 0x74, 0x3e, 0x0d, 0x0a, 0x3c, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, + 0x20, 0x3c, 0x2f, 0x61, 0x3e, 0x3c, 0x2f, 0x6c, 0x69, 0x3e, 0x3c, 0x2f, 0x75, + 0x6c, 0x3e, 0x3c, 0x2f, 0x64, 0x69, 0x76, 0x3e, 0x61, 0x73, 0x73, 0x6f, 0x63, + 0x69, 0x61, 0x74, 0x65, 0x64, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x74, 0x68, + 0x65, 0x20, 0x70, 0x72, 0x6f, 0x67, 0x72, 0x61, 0x6d, 0x6d, 0x69, 0x6e, 0x67, + 0x20, 0x6c, 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, 0x3c, 0x2f, 0x61, 0x3e, + 0x3c, 0x61, 0x20, 0x68, 0x72, 0x65, 0x66, 0x3d, 0x22, 0x68, 0x74, 0x74, 0x70, + 0x3a, 0x2f, 0x2f, 0x3c, 0x2f, 0x61, 0x3e, 0x3c, 0x2f, 0x6c, 0x69, 0x3e, 0x3c, + 0x6c, 0x69, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x22, 0x66, 0x6f, 0x72, + 0x6d, 0x20, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x3d, 0x22, 0x68, 0x74, 0x74, + 0x70, 0x3a, 0x2f, 0x2f, 0x3c, 0x64, 0x69, 0x76, 0x20, 0x73, 0x74, 0x79, 0x6c, + 0x65, 0x3d, 0x22, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x3a, 0x74, 0x79, + 0x70, 0x65, 0x3d, 0x22, 0x74, 0x65, 0x78, 0x74, 0x22, 0x20, 0x6e, 0x61, 0x6d, + 0x65, 0x3d, 0x22, 0x71, 0x22, 0x3c, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x20, 0x77, + 0x69, 0x64, 0x74, 0x68, 0x3d, 0x22, 0x31, 0x30, 0x30, 0x25, 0x22, 0x20, 0x62, + 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x2d, 0x70, 0x6f, 0x73, + 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x22, 0x20, 0x62, 0x6f, 0x72, 0x64, 0x65, + 0x72, 0x3d, 0x22, 0x30, 0x22, 0x20, 0x77, 0x69, 0x64, 0x74, 0x68, 0x3d, 0x22, + 0x72, 0x65, 0x6c, 0x3d, 0x22, 0x73, 0x68, 0x6f, 0x72, 0x74, 0x63, 0x75, 0x74, + 0x20, 0x69, 0x63, 0x6f, 0x6e, 0x22, 0x20, 0x68, 0x36, 0x3e, 0x3c, 0x75, 0x6c, + 0x3e, 0x3c, 0x6c, 0x69, 0x3e, 0x3c, 0x61, 0x20, 0x68, 0x72, 0x65, 0x66, 0x3d, + 0x22, 0x20, 0x20, 0x3c, 0x6d, 0x65, 0x74, 0x61, 0x20, 0x68, 0x74, 0x74, 0x70, + 0x2d, 0x65, 0x71, 0x75, 0x69, 0x76, 0x3d, 0x22, 0x63, 0x73, 0x73, 0x22, 0x20, + 0x6d, 0x65, 0x64, 0x69, 0x61, 0x3d, 0x22, 0x73, 0x63, 0x72, 0x65, 0x65, 0x6e, + 0x22, 0x20, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x69, 0x62, 0x6c, 0x65, + 0x20, 0x66, 0x6f, 0x72, 0x20, 0x74, 0x68, 0x65, 0x20, 0x22, 0x20, 0x74, 0x79, + 0x70, 0x65, 0x3d, 0x22, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x2f, 0x22, 0x20, 0x73, 0x74, 0x79, 0x6c, 0x65, 0x3d, 0x22, 0x62, + 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x2d, 0x68, 0x74, 0x6d, + 0x6c, 0x3b, 0x20, 0x63, 0x68, 0x61, 0x72, 0x73, 0x65, 0x74, 0x3d, 0x75, 0x74, + 0x66, 0x2d, 0x38, 0x22, 0x20, 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x74, 0x72, 0x61, + 0x6e, 0x73, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x63, 0x79, 0x3d, 0x22, 0x73, 0x74, + 0x79, 0x6c, 0x65, 0x73, 0x68, 0x65, 0x65, 0x74, 0x22, 0x20, 0x74, 0x79, 0x70, + 0x65, 0x3d, 0x22, 0x74, 0x65, 0x0d, 0x0a, 0x3c, 0x6d, 0x65, 0x74, 0x61, 0x20, + 0x68, 0x74, 0x74, 0x70, 0x2d, 0x65, 0x71, 0x75, 0x69, 0x76, 0x3d, 0x22, 0x3e, + 0x3c, 0x2f, 0x73, 0x70, 0x61, 0x6e, 0x3e, 0x3c, 0x73, 0x70, 0x61, 0x6e, 0x20, + 0x63, 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x22, 0x30, 0x22, 0x20, 0x63, 0x65, 0x6c, + 0x6c, 0x73, 0x70, 0x61, 0x63, 0x69, 0x6e, 0x67, 0x3d, 0x22, 0x30, 0x22, 0x3e, + 0x3b, 0x0a, 0x3c, 0x2f, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x3e, 0x0a, 0x3c, + 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x20, 0x73, 0x6f, 0x6d, 0x65, 0x74, 0x69, + 0x6d, 0x65, 0x73, 0x20, 0x63, 0x61, 0x6c, 0x6c, 0x65, 0x64, 0x20, 0x74, 0x68, + 0x65, 0x64, 0x6f, 0x65, 0x73, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x6e, 0x65, 0x63, + 0x65, 0x73, 0x73, 0x61, 0x72, 0x69, 0x6c, 0x79, 0x46, 0x6f, 0x72, 0x20, 0x6d, + 0x6f, 0x72, 0x65, 0x20, 0x69, 0x6e, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x61, 0x74, 0x20, 0x74, 0x68, 0x65, 0x20, 0x62, 0x65, 0x67, 0x69, + 0x6e, 0x6e, 0x69, 0x6e, 0x67, 0x20, 0x6f, 0x66, 0x20, 0x3c, 0x21, 0x44, 0x4f, + 0x43, 0x54, 0x59, 0x50, 0x45, 0x20, 0x68, 0x74, 0x6d, 0x6c, 0x3e, 0x3c, 0x68, + 0x74, 0x6d, 0x6c, 0x70, 0x61, 0x72, 0x74, 0x69, 0x63, 0x75, 0x6c, 0x61, 0x72, + 0x6c, 0x79, 0x20, 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x74, 0x79, 0x70, + 0x65, 0x3d, 0x22, 0x68, 0x69, 0x64, 0x64, 0x65, 0x6e, 0x22, 0x20, 0x6e, 0x61, + 0x6d, 0x65, 0x3d, 0x22, 0x6a, 0x61, 0x76, 0x61, 0x73, 0x63, 0x72, 0x69, 0x70, + 0x74, 0x3a, 0x76, 0x6f, 0x69, 0x64, 0x28, 0x30, 0x29, 0x3b, 0x22, 0x65, 0x66, + 0x66, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x6e, 0x65, 0x73, 0x73, 0x20, 0x6f, + 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x61, 0x75, 0x74, 0x6f, 0x63, 0x6f, 0x6d, + 0x70, 0x6c, 0x65, 0x74, 0x65, 0x3d, 0x22, 0x6f, 0x66, 0x66, 0x22, 0x20, 0x67, + 0x65, 0x6e, 0x65, 0x72, 0x61, 0x6c, 0x6c, 0x79, 0x20, 0x63, 0x6f, 0x6e, 0x73, + 0x69, 0x64, 0x65, 0x72, 0x65, 0x64, 0x3e, 0x3c, 0x69, 0x6e, 0x70, 0x75, 0x74, + 0x20, 0x74, 0x79, 0x70, 0x65, 0x3d, 0x22, 0x74, 0x65, 0x78, 0x74, 0x22, 0x20, + 0x22, 0x3e, 0x3c, 0x2f, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x3e, 0x0d, 0x0a, + 0x3c, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x74, 0x68, 0x72, 0x6f, 0x75, 0x67, + 0x68, 0x6f, 0x75, 0x74, 0x20, 0x74, 0x68, 0x65, 0x20, 0x77, 0x6f, 0x72, 0x6c, + 0x64, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x20, 0x6d, 0x69, 0x73, 0x63, 0x6f, + 0x6e, 0x63, 0x65, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x73, 0x73, 0x6f, 0x63, + 0x69, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x74, + 0x68, 0x65, 0x3c, 0x2f, 0x64, 0x69, 0x76, 0x3e, 0x0a, 0x3c, 0x2f, 0x64, 0x69, + 0x76, 0x3e, 0x0a, 0x3c, 0x64, 0x69, 0x76, 0x20, 0x63, 0x64, 0x75, 0x72, 0x69, + 0x6e, 0x67, 0x20, 0x68, 0x69, 0x73, 0x20, 0x6c, 0x69, 0x66, 0x65, 0x74, 0x69, + 0x6d, 0x65, 0x2c, 0x63, 0x6f, 0x72, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x64, + 0x69, 0x6e, 0x67, 0x20, 0x74, 0x6f, 0x20, 0x74, 0x68, 0x65, 0x74, 0x79, 0x70, + 0x65, 0x3d, 0x22, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x2f, 0x78, 0x2d, 0x69, 0x63, + 0x6f, 0x6e, 0x22, 0x20, 0x61, 0x6e, 0x20, 0x69, 0x6e, 0x63, 0x72, 0x65, 0x61, + 0x73, 0x69, 0x6e, 0x67, 0x20, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x64, 0x69, + 0x70, 0x6c, 0x6f, 0x6d, 0x61, 0x74, 0x69, 0x63, 0x20, 0x72, 0x65, 0x6c, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x61, 0x72, 0x65, 0x20, 0x6f, 0x66, 0x74, 0x65, + 0x6e, 0x20, 0x63, 0x6f, 0x6e, 0x73, 0x69, 0x64, 0x65, 0x72, 0x65, 0x64, 0x6d, + 0x65, 0x74, 0x61, 0x20, 0x63, 0x68, 0x61, 0x72, 0x73, 0x65, 0x74, 0x3d, 0x22, + 0x75, 0x74, 0x66, 0x2d, 0x38, 0x22, 0x20, 0x3c, 0x69, 0x6e, 0x70, 0x75, 0x74, + 0x20, 0x74, 0x79, 0x70, 0x65, 0x3d, 0x22, 0x74, 0x65, 0x78, 0x74, 0x22, 0x20, + 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x73, 0x20, 0x69, 0x6e, 0x63, 0x6c, + 0x75, 0x64, 0x65, 0x20, 0x74, 0x68, 0x65, 0x22, 0x3e, 0x3c, 0x69, 0x6d, 0x67, + 0x20, 0x73, 0x72, 0x63, 0x3d, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, + 0x69, 0x70, 0x61, 0x72, 0x74, 0x69, 0x63, 0x69, 0x70, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x20, 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x74, 0x68, 0x65, 0x20, 0x65, + 0x73, 0x74, 0x61, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x6d, 0x65, 0x6e, 0x74, 0x20, + 0x6f, 0x66, 0x0a, 0x3c, 0x2f, 0x64, 0x69, 0x76, 0x3e, 0x0a, 0x3c, 0x64, 0x69, + 0x76, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x22, 0x26, 0x61, 0x6d, 0x70, + 0x3b, 0x6e, 0x62, 0x73, 0x70, 0x3b, 0x26, 0x61, 0x6d, 0x70, 0x3b, 0x6e, 0x62, + 0x73, 0x70, 0x3b, 0x74, 0x6f, 0x20, 0x64, 0x65, 0x74, 0x65, 0x72, 0x6d, 0x69, + 0x6e, 0x65, 0x20, 0x77, 0x68, 0x65, 0x74, 0x68, 0x65, 0x72, 0x71, 0x75, 0x69, + 0x74, 0x65, 0x20, 0x64, 0x69, 0x66, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x74, 0x20, + 0x66, 0x72, 0x6f, 0x6d, 0x6d, 0x61, 0x72, 0x6b, 0x65, 0x64, 0x20, 0x74, 0x68, + 0x65, 0x20, 0x62, 0x65, 0x67, 0x69, 0x6e, 0x6e, 0x69, 0x6e, 0x67, 0x64, 0x69, + 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x20, 0x62, 0x65, 0x74, 0x77, 0x65, 0x65, + 0x6e, 0x20, 0x74, 0x68, 0x65, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x69, 0x62, 0x75, + 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x74, 0x6f, 0x20, 0x74, 0x68, 0x65, 0x63, + 0x6f, 0x6e, 0x66, 0x6c, 0x69, 0x63, 0x74, 0x20, 0x62, 0x65, 0x74, 0x77, 0x65, + 0x65, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x77, 0x69, 0x64, 0x65, 0x6c, 0x79, 0x20, + 0x63, 0x6f, 0x6e, 0x73, 0x69, 0x64, 0x65, 0x72, 0x65, 0x64, 0x20, 0x74, 0x6f, + 0x77, 0x61, 0x73, 0x20, 0x6f, 0x6e, 0x65, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, + 0x65, 0x20, 0x66, 0x69, 0x72, 0x73, 0x74, 0x77, 0x69, 0x74, 0x68, 0x20, 0x76, + 0x61, 0x72, 0x79, 0x69, 0x6e, 0x67, 0x20, 0x64, 0x65, 0x67, 0x72, 0x65, 0x65, + 0x73, 0x68, 0x61, 0x76, 0x65, 0x20, 0x73, 0x70, 0x65, 0x63, 0x75, 0x6c, 0x61, + 0x74, 0x65, 0x64, 0x20, 0x74, 0x68, 0x61, 0x74, 0x28, 0x64, 0x6f, 0x63, 0x75, + 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x67, 0x65, 0x74, 0x45, 0x6c, 0x65, 0x6d, 0x65, + 0x6e, 0x74, 0x70, 0x61, 0x72, 0x74, 0x69, 0x63, 0x69, 0x70, 0x61, 0x74, 0x69, + 0x6e, 0x67, 0x20, 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x6f, 0x72, 0x69, 0x67, + 0x69, 0x6e, 0x61, 0x6c, 0x6c, 0x79, 0x20, 0x64, 0x65, 0x76, 0x65, 0x6c, 0x6f, + 0x70, 0x65, 0x64, 0x65, 0x74, 0x61, 0x20, 0x63, 0x68, 0x61, 0x72, 0x73, 0x65, + 0x74, 0x3d, 0x22, 0x75, 0x74, 0x66, 0x2d, 0x38, 0x22, 0x3e, 0x20, 0x74, 0x79, + 0x70, 0x65, 0x3d, 0x22, 0x74, 0x65, 0x78, 0x74, 0x2f, 0x63, 0x73, 0x73, 0x22, + 0x20, 0x2f, 0x3e, 0x0a, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x63, 0x68, 0x61, 0x6e, + 0x67, 0x65, 0x61, 0x62, 0x6c, 0x79, 0x20, 0x77, 0x69, 0x74, 0x68, 0x6d, 0x6f, + 0x72, 0x65, 0x20, 0x63, 0x6c, 0x6f, 0x73, 0x65, 0x6c, 0x79, 0x20, 0x72, 0x65, + 0x6c, 0x61, 0x74, 0x65, 0x64, 0x73, 0x6f, 0x63, 0x69, 0x61, 0x6c, 0x20, 0x61, + 0x6e, 0x64, 0x20, 0x70, 0x6f, 0x6c, 0x69, 0x74, 0x69, 0x63, 0x61, 0x6c, 0x74, + 0x68, 0x61, 0x74, 0x20, 0x77, 0x6f, 0x75, 0x6c, 0x64, 0x20, 0x6f, 0x74, 0x68, + 0x65, 0x72, 0x77, 0x69, 0x73, 0x65, 0x70, 0x65, 0x72, 0x70, 0x65, 0x6e, 0x64, + 0x69, 0x63, 0x75, 0x6c, 0x61, 0x72, 0x20, 0x74, 0x6f, 0x20, 0x74, 0x68, 0x65, + 0x73, 0x74, 0x79, 0x6c, 0x65, 0x20, 0x74, 0x79, 0x70, 0x65, 0x3d, 0x22, 0x74, + 0x65, 0x78, 0x74, 0x2f, 0x63, 0x73, 0x73, 0x74, 0x79, 0x70, 0x65, 0x3d, 0x22, + 0x73, 0x75, 0x62, 0x6d, 0x69, 0x74, 0x22, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x3d, + 0x22, 0x66, 0x61, 0x6d, 0x69, 0x6c, 0x69, 0x65, 0x73, 0x20, 0x72, 0x65, 0x73, + 0x69, 0x64, 0x69, 0x6e, 0x67, 0x20, 0x69, 0x6e, 0x64, 0x65, 0x76, 0x65, 0x6c, + 0x6f, 0x70, 0x69, 0x6e, 0x67, 0x20, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x72, 0x69, + 0x65, 0x73, 0x63, 0x6f, 0x6d, 0x70, 0x75, 0x74, 0x65, 0x72, 0x20, 0x70, 0x72, + 0x6f, 0x67, 0x72, 0x61, 0x6d, 0x6d, 0x69, 0x6e, 0x67, 0x65, 0x63, 0x6f, 0x6e, + 0x6f, 0x6d, 0x69, 0x63, 0x20, 0x64, 0x65, 0x76, 0x65, 0x6c, 0x6f, 0x70, 0x6d, + 0x65, 0x6e, 0x74, 0x64, 0x65, 0x74, 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x66, 0x6f, 0x72, + 0x20, 0x6d, 0x6f, 0x72, 0x65, 0x20, 0x69, 0x6e, 0x66, 0x6f, 0x72, 0x6d, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x6f, 0x6e, 0x20, 0x73, 0x65, 0x76, 0x65, 0x72, 0x61, + 0x6c, 0x20, 0x6f, 0x63, 0x63, 0x61, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x70, 0x6f, + 0x72, 0x74, 0x75, 0x67, 0x75, 0xc3, 0xaa, 0x73, 0x20, 0x28, 0x45, 0x75, 0x72, + 0x6f, 0x70, 0x65, 0x75, 0x29, 0xd0, 0xa3, 0xd0, 0xba, 0xd1, 0x80, 0xd0, 0xb0, + 0xd1, 0x97, 0xd0, 0xbd, 0xd1, 0x81, 0xd1, 0x8c, 0xd0, 0xba, 0xd0, 0xb0, 0xd1, + 0x83, 0xd0, 0xba, 0xd1, 0x80, 0xd0, 0xb0, 0xd1, 0x97, 0xd0, 0xbd, 0xd1, 0x81, + 0xd1, 0x8c, 0xd0, 0xba, 0xd0, 0xb0, 0xd0, 0xa0, 0xd0, 0xbe, 0xd1, 0x81, 0xd1, + 0x81, 0xd0, 0xb8, 0xd0, 0xb9, 0xd1, 0x81, 0xd0, 0xba, 0xd0, 0xbe, 0xd0, 0xb9, + 0xd0, 0xbc, 0xd0, 0xb0, 0xd1, 0x82, 0xd0, 0xb5, 0xd1, 0x80, 0xd0, 0xb8, 0xd0, + 0xb0, 0xd0, 0xbb, 0xd0, 0xbe, 0xd0, 0xb2, 0xd0, 0xb8, 0xd0, 0xbd, 0xd1, 0x84, + 0xd0, 0xbe, 0xd1, 0x80, 0xd0, 0xbc, 0xd0, 0xb0, 0xd1, 0x86, 0xd0, 0xb8, 0xd0, + 0xb8, 0xd1, 0x83, 0xd0, 0xbf, 0xd1, 0x80, 0xd0, 0xb0, 0xd0, 0xb2, 0xd0, 0xbb, + 0xd0, 0xb5, 0xd0, 0xbd, 0xd0, 0xb8, 0xd1, 0x8f, 0xd0, 0xbd, 0xd0, 0xb5, 0xd0, + 0xbe, 0xd0, 0xb1, 0xd1, 0x85, 0xd0, 0xbe, 0xd0, 0xb4, 0xd0, 0xb8, 0xd0, 0xbc, + 0xd0, 0xbe, 0xd0, 0xb8, 0xd0, 0xbd, 0xd1, 0x84, 0xd0, 0xbe, 0xd1, 0x80, 0xd0, + 0xbc, 0xd0, 0xb0, 0xd1, 0x86, 0xd0, 0xb8, 0xd1, 0x8f, 0xd0, 0x98, 0xd0, 0xbd, + 0xd1, 0x84, 0xd0, 0xbe, 0xd1, 0x80, 0xd0, 0xbc, 0xd0, 0xb0, 0xd1, 0x86, 0xd0, + 0xb8, 0xd1, 0x8f, 0xd0, 0xa0, 0xd0, 0xb5, 0xd1, 0x81, 0xd0, 0xbf, 0xd1, 0x83, + 0xd0, 0xb1, 0xd0, 0xbb, 0xd0, 0xb8, 0xd0, 0xba, 0xd0, 0xb8, 0xd0, 0xba, 0xd0, + 0xbe, 0xd0, 0xbb, 0xd0, 0xb8, 0xd1, 0x87, 0xd0, 0xb5, 0xd1, 0x81, 0xd1, 0x82, + 0xd0, 0xb2, 0xd0, 0xbe, 0xd0, 0xb8, 0xd0, 0xbd, 0xd1, 0x84, 0xd0, 0xbe, 0xd1, + 0x80, 0xd0, 0xbc, 0xd0, 0xb0, 0xd1, 0x86, 0xd0, 0xb8, 0xd1, 0x8e, 0xd1, 0x82, + 0xd0, 0xb5, 0xd1, 0x80, 0xd1, 0x80, 0xd0, 0xb8, 0xd1, 0x82, 0xd0, 0xbe, 0xd1, + 0x80, 0xd0, 0xb8, 0xd0, 0xb8, 0xd0, 0xb4, 0xd0, 0xbe, 0xd1, 0x81, 0xd1, 0x82, + 0xd0, 0xb0, 0xd1, 0x82, 0xd0, 0xbe, 0xd1, 0x87, 0xd0, 0xbd, 0xd0, 0xbe, 0xd8, + 0xa7, 0xd9, 0x84, 0xd9, 0x85, 0xd8, 0xaa, 0xd9, 0x88, 0xd8, 0xa7, 0xd8, 0xac, + 0xd8, 0xaf, 0xd9, 0x88, 0xd9, 0x86, 0xd8, 0xa7, 0xd9, 0x84, 0xd8, 0xa7, 0xd8, + 0xb4, 0xd8, 0xaa, 0xd8, 0xb1, 0xd8, 0xa7, 0xd9, 0x83, 0xd8, 0xa7, 0xd8, 0xaa, + 0xd8, 0xa7, 0xd9, 0x84, 0xd8, 0xa7, 0xd9, 0x82, 0xd8, 0xaa, 0xd8, 0xb1, 0xd8, + 0xa7, 0xd8, 0xad, 0xd8, 0xa7, 0xd8, 0xaa, 0x68, 0x74, 0x6d, 0x6c, 0x3b, 0x20, + 0x63, 0x68, 0x61, 0x72, 0x73, 0x65, 0x74, 0x3d, 0x55, 0x54, 0x46, 0x2d, 0x38, + 0x22, 0x20, 0x73, 0x65, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x28, + 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x29, 0x64, 0x69, 0x73, + 0x70, 0x6c, 0x61, 0x79, 0x3a, 0x69, 0x6e, 0x6c, 0x69, 0x6e, 0x65, 0x2d, 0x62, + 0x6c, 0x6f, 0x63, 0x6b, 0x3b, 0x3c, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x20, 0x74, + 0x79, 0x70, 0x65, 0x3d, 0x22, 0x73, 0x75, 0x62, 0x6d, 0x69, 0x74, 0x22, 0x20, + 0x74, 0x79, 0x70, 0x65, 0x20, 0x3d, 0x20, 0x27, 0x74, 0x65, 0x78, 0x74, 0x2f, + 0x6a, 0x61, 0x76, 0x61, 0x73, 0x63, 0x72, 0x69, 0x3c, 0x69, 0x6d, 0x67, 0x20, + 0x73, 0x72, 0x63, 0x3d, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, + 0x77, 0x77, 0x2e, 0x22, 0x20, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, + 0x77, 0x77, 0x77, 0x2e, 0x77, 0x33, 0x2e, 0x6f, 0x72, 0x67, 0x2f, 0x73, 0x68, + 0x6f, 0x72, 0x74, 0x63, 0x75, 0x74, 0x20, 0x69, 0x63, 0x6f, 0x6e, 0x22, 0x20, + 0x68, 0x72, 0x65, 0x66, 0x3d, 0x22, 0x22, 0x20, 0x61, 0x75, 0x74, 0x6f, 0x63, + 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x3d, 0x22, 0x6f, 0x66, 0x66, 0x22, + 0x20, 0x3c, 0x2f, 0x61, 0x3e, 0x3c, 0x2f, 0x64, 0x69, 0x76, 0x3e, 0x3c, 0x64, + 0x69, 0x76, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x3c, 0x2f, 0x61, 0x3e, + 0x3c, 0x2f, 0x6c, 0x69, 0x3e, 0x0a, 0x3c, 0x6c, 0x69, 0x20, 0x63, 0x6c, 0x61, + 0x73, 0x73, 0x3d, 0x22, 0x63, 0x73, 0x73, 0x22, 0x20, 0x74, 0x79, 0x70, 0x65, + 0x3d, 0x22, 0x74, 0x65, 0x78, 0x74, 0x2f, 0x63, 0x73, 0x73, 0x22, 0x20, 0x3c, + 0x66, 0x6f, 0x72, 0x6d, 0x20, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x3d, 0x22, + 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x78, 0x74, 0x2f, 0x63, 0x73, 0x73, + 0x22, 0x20, 0x68, 0x72, 0x65, 0x66, 0x3d, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, + 0x2f, 0x2f, 0x6c, 0x69, 0x6e, 0x6b, 0x20, 0x72, 0x65, 0x6c, 0x3d, 0x22, 0x61, + 0x6c, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x74, 0x65, 0x22, 0x20, 0x0d, 0x0a, 0x3c, + 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x20, 0x74, 0x79, 0x70, 0x65, 0x3d, 0x22, + 0x74, 0x65, 0x78, 0x74, 0x2f, 0x20, 0x6f, 0x6e, 0x63, 0x6c, 0x69, 0x63, 0x6b, + 0x3d, 0x22, 0x6a, 0x61, 0x76, 0x61, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x3a, + 0x28, 0x6e, 0x65, 0x77, 0x20, 0x44, 0x61, 0x74, 0x65, 0x29, 0x2e, 0x67, 0x65, + 0x74, 0x54, 0x69, 0x6d, 0x65, 0x28, 0x29, 0x7d, 0x68, 0x65, 0x69, 0x67, 0x68, + 0x74, 0x3d, 0x22, 0x31, 0x22, 0x20, 0x77, 0x69, 0x64, 0x74, 0x68, 0x3d, 0x22, + 0x31, 0x22, 0x20, 0x50, 0x65, 0x6f, 0x70, 0x6c, 0x65, 0x27, 0x73, 0x20, 0x52, + 0x65, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x20, 0x6f, 0x66, 0x20, 0x20, 0x3c, + 0x61, 0x20, 0x68, 0x72, 0x65, 0x66, 0x3d, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, + 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x74, 0x65, 0x78, 0x74, 0x2d, 0x64, 0x65, + 0x63, 0x6f, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x75, 0x6e, 0x64, 0x65, + 0x72, 0x74, 0x68, 0x65, 0x20, 0x62, 0x65, 0x67, 0x69, 0x6e, 0x6e, 0x69, 0x6e, + 0x67, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x3c, 0x2f, 0x64, 0x69, + 0x76, 0x3e, 0x0a, 0x3c, 0x2f, 0x64, 0x69, 0x76, 0x3e, 0x0a, 0x3c, 0x2f, 0x64, + 0x69, 0x76, 0x3e, 0x0a, 0x65, 0x73, 0x74, 0x61, 0x62, 0x6c, 0x69, 0x73, 0x68, + 0x6d, 0x65, 0x6e, 0x74, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x3c, + 0x2f, 0x64, 0x69, 0x76, 0x3e, 0x3c, 0x2f, 0x64, 0x69, 0x76, 0x3e, 0x3c, 0x2f, + 0x64, 0x69, 0x76, 0x3e, 0x3c, 0x2f, 0x64, 0x23, 0x76, 0x69, 0x65, 0x77, 0x70, + 0x6f, 0x72, 0x74, 0x7b, 0x6d, 0x69, 0x6e, 0x2d, 0x68, 0x65, 0x69, 0x67, 0x68, + 0x74, 0x3a, 0x0a, 0x3c, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x20, 0x73, 0x72, + 0x63, 0x3d, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6f, 0x70, 0x74, + 0x69, 0x6f, 0x6e, 0x3e, 0x3c, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x76, + 0x61, 0x6c, 0x75, 0x65, 0x3d, 0x6f, 0x66, 0x74, 0x65, 0x6e, 0x20, 0x72, 0x65, + 0x66, 0x65, 0x72, 0x72, 0x65, 0x64, 0x20, 0x74, 0x6f, 0x20, 0x61, 0x73, 0x20, + 0x2f, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x3e, 0x0a, 0x3c, 0x6f, 0x70, 0x74, + 0x69, 0x6f, 0x6e, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x3c, 0x21, 0x44, 0x4f, 0x43, + 0x54, 0x59, 0x50, 0x45, 0x20, 0x68, 0x74, 0x6d, 0x6c, 0x3e, 0x0a, 0x3c, 0x21, + 0x2d, 0x2d, 0x5b, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x61, 0x6c, 0x20, 0x41, 0x69, 0x72, 0x70, 0x6f, 0x72, 0x74, 0x3e, 0x0a, + 0x3c, 0x61, 0x20, 0x68, 0x72, 0x65, 0x66, 0x3d, 0x22, 0x68, 0x74, 0x74, 0x70, + 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x3c, 0x2f, 0x61, 0x3e, 0x3c, 0x61, 0x20, + 0x68, 0x72, 0x65, 0x66, 0x3d, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, + 0x77, 0xe0, 0xb8, 0xa0, 0xe0, 0xb8, 0xb2, 0xe0, 0xb8, 0xa9, 0xe0, 0xb8, 0xb2, + 0xe0, 0xb9, 0x84, 0xe0, 0xb8, 0x97, 0xe0, 0xb8, 0xa2, 0xe1, 0x83, 0xa5, 0xe1, + 0x83, 0x90, 0xe1, 0x83, 0xa0, 0xe1, 0x83, 0x97, 0xe1, 0x83, 0xa3, 0xe1, 0x83, + 0x9a, 0xe1, 0x83, 0x98, 0xe6, 0xad, 0xa3, 0xe9, 0xab, 0x94, 0xe4, 0xb8, 0xad, + 0xe6, 0x96, 0x87, 0x20, 0x28, 0xe7, 0xb9, 0x81, 0xe9, 0xab, 0x94, 0x29, 0xe0, + 0xa4, 0xa8, 0xe0, 0xa4, 0xbf, 0xe0, 0xa4, 0xb0, 0xe0, 0xa5, 0x8d, 0xe0, 0xa4, + 0xa6, 0xe0, 0xa5, 0x87, 0xe0, 0xa4, 0xb6, 0xe0, 0xa4, 0xa1, 0xe0, 0xa4, 0xbe, + 0xe0, 0xa4, 0x89, 0xe0, 0xa4, 0xa8, 0xe0, 0xa4, 0xb2, 0xe0, 0xa5, 0x8b, 0xe0, + 0xa4, 0xa1, 0xe0, 0xa4, 0x95, 0xe0, 0xa5, 0x8d, 0xe0, 0xa4, 0xb7, 0xe0, 0xa5, + 0x87, 0xe0, 0xa4, 0xa4, 0xe0, 0xa5, 0x8d, 0xe0, 0xa4, 0xb0, 0xe0, 0xa4, 0x9c, + 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, 0xa8, 0xe0, 0xa4, 0x95, 0xe0, 0xa4, 0xbe, 0xe0, + 0xa4, 0xb0, 0xe0, 0xa5, 0x80, 0xe0, 0xa4, 0xb8, 0xe0, 0xa4, 0x82, 0xe0, 0xa4, + 0xac, 0xe0, 0xa4, 0x82, 0xe0, 0xa4, 0xa7, 0xe0, 0xa4, 0xbf, 0xe0, 0xa4, 0xa4, + 0xe0, 0xa4, 0xb8, 0xe0, 0xa5, 0x8d, 0xe0, 0xa4, 0xa5, 0xe0, 0xa4, 0xbe, 0xe0, + 0xa4, 0xaa, 0xe0, 0xa4, 0xa8, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, 0xb8, 0xe0, 0xa5, + 0x8d, 0xe0, 0xa4, 0xb5, 0xe0, 0xa5, 0x80, 0xe0, 0xa4, 0x95, 0xe0, 0xa4, 0xbe, + 0xe0, 0xa4, 0xb0, 0xe0, 0xa4, 0xb8, 0xe0, 0xa4, 0x82, 0xe0, 0xa4, 0xb8, 0xe0, + 0xa5, 0x8d, 0xe0, 0xa4, 0x95, 0xe0, 0xa4, 0xb0, 0xe0, 0xa4, 0xa3, 0xe0, 0xa4, + 0xb8, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, 0xae, 0xe0, 0xa4, 0x97, 0xe0, 0xa5, 0x8d, + 0xe0, 0xa4, 0xb0, 0xe0, 0xa5, 0x80, 0xe0, 0xa4, 0x9a, 0xe0, 0xa4, 0xbf, 0xe0, + 0xa4, 0x9f, 0xe0, 0xa5, 0x8d, 0xe0, 0xa4, 0xa0, 0xe0, 0xa5, 0x8b, 0xe0, 0xa4, + 0x82, 0xe0, 0xa4, 0xb5, 0xe0, 0xa4, 0xbf, 0xe0, 0xa4, 0x9c, 0xe0, 0xa5, 0x8d, + 0xe0, 0xa4, 0x9e, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, 0xa8, 0xe0, 0xa4, 0x85, 0xe0, + 0xa4, 0xae, 0xe0, 0xa5, 0x87, 0xe0, 0xa4, 0xb0, 0xe0, 0xa4, 0xbf, 0xe0, 0xa4, + 0x95, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, 0xb5, 0xe0, 0xa4, 0xbf, 0xe0, 0xa4, 0xad, + 0xe0, 0xa4, 0xbf, 0xe0, 0xa4, 0xa8, 0xe0, 0xa5, 0x8d, 0xe0, 0xa4, 0xa8, 0xe0, + 0xa4, 0x97, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, 0xa1, 0xe0, 0xa4, 0xbf, 0xe0, 0xa4, + 0xaf, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, 0x81, 0xe0, 0xa4, 0x95, 0xe0, 0xa5, 0x8d, + 0xe0, 0xa4, 0xaf, 0xe0, 0xa5, 0x8b, 0xe0, 0xa4, 0x82, 0xe0, 0xa4, 0x95, 0xe0, + 0xa4, 0xbf, 0xe0, 0xa4, 0xb8, 0xe0, 0xa5, 0x81, 0xe0, 0xa4, 0xb0, 0xe0, 0xa4, + 0x95, 0xe0, 0xa5, 0x8d, 0xe0, 0xa4, 0xb7, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, 0xaa, + 0xe0, 0xa4, 0xb9, 0xe0, 0xa5, 0x81, 0xe0, 0xa4, 0x81, 0xe0, 0xa4, 0x9a, 0xe0, + 0xa4, 0xa4, 0xe0, 0xa5, 0x80, 0xe0, 0xa4, 0xaa, 0xe0, 0xa5, 0x8d, 0xe0, 0xa4, + 0xb0, 0xe0, 0xa4, 0xac, 0xe0, 0xa4, 0x82, 0xe0, 0xa4, 0xa7, 0xe0, 0xa4, 0xa8, + 0xe0, 0xa4, 0x9f, 0xe0, 0xa4, 0xbf, 0xe0, 0xa4, 0xaa, 0xe0, 0xa5, 0x8d, 0xe0, + 0xa4, 0xaa, 0xe0, 0xa4, 0xa3, 0xe0, 0xa5, 0x80, 0xe0, 0xa4, 0x95, 0xe0, 0xa5, + 0x8d, 0xe0, 0xa4, 0xb0, 0xe0, 0xa4, 0xbf, 0xe0, 0xa4, 0x95, 0xe0, 0xa5, 0x87, + 0xe0, 0xa4, 0x9f, 0xe0, 0xa4, 0xaa, 0xe0, 0xa5, 0x8d, 0xe0, 0xa4, 0xb0, 0xe0, + 0xa4, 0xbe, 0xe0, 0xa4, 0xb0, 0xe0, 0xa4, 0x82, 0xe0, 0xa4, 0xad, 0xe0, 0xa4, + 0xaa, 0xe0, 0xa5, 0x8d, 0xe0, 0xa4, 0xb0, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, 0xaa, + 0xe0, 0xa5, 0x8d, 0xe0, 0xa4, 0xa4, 0xe0, 0xa4, 0xae, 0xe0, 0xa4, 0xbe, 0xe0, + 0xa4, 0xb2, 0xe0, 0xa4, 0xbf, 0xe0, 0xa4, 0x95, 0xe0, 0xa5, 0x8b, 0xe0, 0xa4, + 0x82, 0xe0, 0xa4, 0xb0, 0xe0, 0xa4, 0xab, 0xe0, 0xa4, 0xbc, 0xe0, 0xa5, 0x8d, + 0xe0, 0xa4, 0xa4, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, 0xb0, 0xe0, 0xa4, 0xa8, 0xe0, + 0xa4, 0xbf, 0xe0, 0xa4, 0xb0, 0xe0, 0xa5, 0x8d, 0xe0, 0xa4, 0xae, 0xe0, 0xa4, + 0xbe, 0xe0, 0xa4, 0xa3, 0xe0, 0xa4, 0xb2, 0xe0, 0xa4, 0xbf, 0xe0, 0xa4, 0xae, + 0xe0, 0xa4, 0xbf, 0xe0, 0xa4, 0x9f, 0xe0, 0xa5, 0x87, 0xe0, 0xa4, 0xa1, 0x64, + 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x20, 0x63, + 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x3d, 0x22, 0x64, 0x6f, 0x63, 0x75, 0x6d, + 0x65, 0x6e, 0x74, 0x2e, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, + 0x70, 0x72, 0x6f, 0x74, 0x2e, 0x67, 0x65, 0x74, 0x45, 0x6c, 0x65, 0x6d, 0x65, + 0x6e, 0x74, 0x73, 0x42, 0x79, 0x54, 0x61, 0x67, 0x4e, 0x61, 0x6d, 0x65, 0x28, + 0x3c, 0x21, 0x44, 0x4f, 0x43, 0x54, 0x59, 0x50, 0x45, 0x20, 0x68, 0x74, 0x6d, + 0x6c, 0x3e, 0x0a, 0x3c, 0x68, 0x74, 0x6d, 0x6c, 0x20, 0x3c, 0x6d, 0x65, 0x74, + 0x61, 0x20, 0x63, 0x68, 0x61, 0x72, 0x73, 0x65, 0x74, 0x3d, 0x22, 0x75, 0x74, + 0x66, 0x2d, 0x38, 0x22, 0x3e, 0x3a, 0x75, 0x72, 0x6c, 0x22, 0x20, 0x63, 0x6f, + 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x3d, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, + 0x2f, 0x2e, 0x63, 0x73, 0x73, 0x22, 0x20, 0x72, 0x65, 0x6c, 0x3d, 0x22, 0x73, + 0x74, 0x79, 0x6c, 0x65, 0x73, 0x68, 0x65, 0x65, 0x74, 0x22, 0x73, 0x74, 0x79, + 0x6c, 0x65, 0x20, 0x74, 0x79, 0x70, 0x65, 0x3d, 0x22, 0x74, 0x65, 0x78, 0x74, + 0x2f, 0x63, 0x73, 0x73, 0x22, 0x3e, 0x74, 0x79, 0x70, 0x65, 0x3d, 0x22, 0x74, + 0x65, 0x78, 0x74, 0x2f, 0x63, 0x73, 0x73, 0x22, 0x20, 0x68, 0x72, 0x65, 0x66, + 0x3d, 0x22, 0x77, 0x33, 0x2e, 0x6f, 0x72, 0x67, 0x2f, 0x31, 0x39, 0x39, 0x39, + 0x2f, 0x78, 0x68, 0x74, 0x6d, 0x6c, 0x22, 0x20, 0x78, 0x6d, 0x6c, 0x74, 0x79, + 0x70, 0x65, 0x3d, 0x22, 0x74, 0x65, 0x78, 0x74, 0x2f, 0x6a, 0x61, 0x76, 0x61, + 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x22, 0x20, 0x6d, 0x65, 0x74, 0x68, 0x6f, + 0x64, 0x3d, 0x22, 0x67, 0x65, 0x74, 0x22, 0x20, 0x61, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x3d, 0x22, 0x6c, 0x69, 0x6e, 0x6b, 0x20, 0x72, 0x65, 0x6c, 0x3d, 0x22, + 0x73, 0x74, 0x79, 0x6c, 0x65, 0x73, 0x68, 0x65, 0x65, 0x74, 0x22, 0x20, 0x20, + 0x3d, 0x20, 0x64, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x67, 0x65, + 0x74, 0x45, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x74, 0x79, 0x70, 0x65, 0x3d, + 0x22, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x2f, 0x78, 0x2d, 0x69, 0x63, 0x6f, 0x6e, + 0x22, 0x20, 0x2f, 0x3e, 0x63, 0x65, 0x6c, 0x6c, 0x70, 0x61, 0x64, 0x64, 0x69, + 0x6e, 0x67, 0x3d, 0x22, 0x30, 0x22, 0x20, 0x63, 0x65, 0x6c, 0x6c, 0x73, 0x70, + 0x2e, 0x63, 0x73, 0x73, 0x22, 0x20, 0x74, 0x79, 0x70, 0x65, 0x3d, 0x22, 0x74, + 0x65, 0x78, 0x74, 0x2f, 0x63, 0x73, 0x73, 0x22, 0x20, 0x3c, 0x2f, 0x61, 0x3e, + 0x3c, 0x2f, 0x6c, 0x69, 0x3e, 0x3c, 0x6c, 0x69, 0x3e, 0x3c, 0x61, 0x20, 0x68, + 0x72, 0x65, 0x66, 0x3d, 0x22, 0x22, 0x20, 0x77, 0x69, 0x64, 0x74, 0x68, 0x3d, + 0x22, 0x31, 0x22, 0x20, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x3d, 0x22, 0x31, + 0x22, 0x22, 0x3e, 0x3c, 0x61, 0x20, 0x68, 0x72, 0x65, 0x66, 0x3d, 0x22, 0x68, + 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x73, 0x74, 0x79, + 0x6c, 0x65, 0x3d, 0x22, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x3a, 0x6e, + 0x6f, 0x6e, 0x65, 0x3b, 0x22, 0x3e, 0x61, 0x6c, 0x74, 0x65, 0x72, 0x6e, 0x61, + 0x74, 0x65, 0x22, 0x20, 0x74, 0x79, 0x70, 0x65, 0x3d, 0x22, 0x61, 0x70, 0x70, + 0x6c, 0x69, 0x2d, 0x2f, 0x2f, 0x57, 0x33, 0x43, 0x2f, 0x2f, 0x44, 0x54, 0x44, + 0x20, 0x58, 0x48, 0x54, 0x4d, 0x4c, 0x20, 0x31, 0x2e, 0x30, 0x20, 0x65, 0x6c, + 0x6c, 0x73, 0x70, 0x61, 0x63, 0x69, 0x6e, 0x67, 0x3d, 0x22, 0x30, 0x22, 0x20, + 0x63, 0x65, 0x6c, 0x6c, 0x70, 0x61, 0x64, 0x20, 0x74, 0x79, 0x70, 0x65, 0x3d, + 0x22, 0x68, 0x69, 0x64, 0x64, 0x65, 0x6e, 0x22, 0x20, 0x76, 0x61, 0x6c, 0x75, + 0x65, 0x3d, 0x22, 0x2f, 0x61, 0x3e, 0x26, 0x6e, 0x62, 0x73, 0x70, 0x3b, 0x3c, + 0x73, 0x70, 0x61, 0x6e, 0x20, 0x72, 0x6f, 0x6c, 0x65, 0x3d, 0x22, 0x73, 0x0a, + 0x3c, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x20, 0x74, 0x79, 0x70, 0x65, 0x3d, 0x22, + 0x68, 0x69, 0x64, 0x64, 0x65, 0x6e, 0x22, 0x20, 0x6c, 0x61, 0x6e, 0x67, 0x75, + 0x61, 0x67, 0x65, 0x3d, 0x22, 0x4a, 0x61, 0x76, 0x61, 0x53, 0x63, 0x72, 0x69, + 0x70, 0x74, 0x22, 0x20, 0x20, 0x64, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, + 0x2e, 0x67, 0x65, 0x74, 0x45, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x42, + 0x67, 0x3d, 0x22, 0x30, 0x22, 0x20, 0x63, 0x65, 0x6c, 0x6c, 0x73, 0x70, 0x61, + 0x63, 0x69, 0x6e, 0x67, 0x3d, 0x22, 0x30, 0x22, 0x20, 0x79, 0x70, 0x65, 0x3d, + 0x22, 0x74, 0x65, 0x78, 0x74, 0x2f, 0x63, 0x73, 0x73, 0x22, 0x20, 0x6d, 0x65, + 0x64, 0x69, 0x61, 0x3d, 0x22, 0x74, 0x79, 0x70, 0x65, 0x3d, 0x27, 0x74, 0x65, + 0x78, 0x74, 0x2f, 0x6a, 0x61, 0x76, 0x61, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, + 0x27, 0x77, 0x69, 0x74, 0x68, 0x20, 0x74, 0x68, 0x65, 0x20, 0x65, 0x78, 0x63, + 0x65, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6f, 0x66, 0x20, 0x79, 0x70, 0x65, + 0x3d, 0x22, 0x74, 0x65, 0x78, 0x74, 0x2f, 0x63, 0x73, 0x73, 0x22, 0x20, 0x72, + 0x65, 0x6c, 0x3d, 0x22, 0x73, 0x74, 0x20, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, + 0x3d, 0x22, 0x31, 0x22, 0x20, 0x77, 0x69, 0x64, 0x74, 0x68, 0x3d, 0x22, 0x31, + 0x22, 0x20, 0x3d, 0x27, 0x2b, 0x65, 0x6e, 0x63, 0x6f, 0x64, 0x65, 0x55, 0x52, + 0x49, 0x43, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x28, 0x3c, 0x6c, + 0x69, 0x6e, 0x6b, 0x20, 0x72, 0x65, 0x6c, 0x3d, 0x22, 0x61, 0x6c, 0x74, 0x65, + 0x72, 0x6e, 0x61, 0x74, 0x65, 0x22, 0x20, 0x0a, 0x62, 0x6f, 0x64, 0x79, 0x2c, + 0x20, 0x74, 0x72, 0x2c, 0x20, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x2c, 0x20, 0x74, + 0x65, 0x78, 0x74, 0x6d, 0x65, 0x74, 0x61, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x3d, + 0x22, 0x72, 0x6f, 0x62, 0x6f, 0x74, 0x73, 0x22, 0x20, 0x63, 0x6f, 0x6e, 0x6d, + 0x65, 0x74, 0x68, 0x6f, 0x64, 0x3d, 0x22, 0x70, 0x6f, 0x73, 0x74, 0x22, 0x20, + 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x3d, 0x22, 0x3e, 0x0a, 0x3c, 0x61, 0x20, + 0x68, 0x72, 0x65, 0x66, 0x3d, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, + 0x77, 0x77, 0x77, 0x2e, 0x63, 0x73, 0x73, 0x22, 0x20, 0x72, 0x65, 0x6c, 0x3d, + 0x22, 0x73, 0x74, 0x79, 0x6c, 0x65, 0x73, 0x68, 0x65, 0x65, 0x74, 0x22, 0x20, + 0x3c, 0x2f, 0x64, 0x69, 0x76, 0x3e, 0x3c, 0x2f, 0x64, 0x69, 0x76, 0x3e, 0x3c, + 0x64, 0x69, 0x76, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x6c, 0x61, 0x6e, 0x67, + 0x75, 0x61, 0x67, 0x65, 0x3d, 0x22, 0x6a, 0x61, 0x76, 0x61, 0x73, 0x63, 0x72, + 0x69, 0x70, 0x74, 0x22, 0x3e, 0x61, 0x72, 0x69, 0x61, 0x2d, 0x68, 0x69, 0x64, + 0x64, 0x65, 0x6e, 0x3d, 0x22, 0x74, 0x72, 0x75, 0x65, 0x22, 0x3e, 0xc2, 0xb7, + 0x3c, 0x72, 0x69, 0x70, 0x74, 0x22, 0x20, 0x74, 0x79, 0x70, 0x65, 0x3d, 0x22, + 0x74, 0x65, 0x78, 0x74, 0x2f, 0x6a, 0x61, 0x76, 0x61, 0x73, 0x6c, 0x3d, 0x30, + 0x3b, 0x7d, 0x29, 0x28, 0x29, 0x3b, 0x0a, 0x28, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x28, 0x29, 0x7b, 0x62, 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, + 0x75, 0x6e, 0x64, 0x2d, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x3a, 0x20, 0x75, 0x72, + 0x6c, 0x28, 0x2f, 0x61, 0x3e, 0x3c, 0x2f, 0x6c, 0x69, 0x3e, 0x3c, 0x6c, 0x69, + 0x3e, 0x3c, 0x61, 0x20, 0x68, 0x72, 0x65, 0x66, 0x3d, 0x22, 0x68, 0x09, 0x09, + 0x3c, 0x6c, 0x69, 0x3e, 0x3c, 0x61, 0x20, 0x68, 0x72, 0x65, 0x66, 0x3d, 0x22, + 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x61, 0x74, 0x6f, 0x72, 0x22, 0x20, + 0x61, 0x72, 0x69, 0x61, 0x2d, 0x68, 0x69, 0x64, 0x64, 0x65, 0x6e, 0x3d, 0x22, + 0x74, 0x72, 0x75, 0x3e, 0x20, 0x3c, 0x61, 0x20, 0x68, 0x72, 0x65, 0x66, 0x3d, + 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x6c, + 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, 0x3d, 0x22, 0x6a, 0x61, 0x76, 0x61, + 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x22, 0x20, 0x2f, 0x6f, 0x70, 0x74, 0x69, + 0x6f, 0x6e, 0x3e, 0x0a, 0x3c, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x76, + 0x61, 0x6c, 0x75, 0x65, 0x2f, 0x64, 0x69, 0x76, 0x3e, 0x3c, 0x2f, 0x64, 0x69, + 0x76, 0x3e, 0x3c, 0x64, 0x69, 0x76, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x3d, + 0x72, 0x61, 0x74, 0x6f, 0x72, 0x22, 0x20, 0x61, 0x72, 0x69, 0x61, 0x2d, 0x68, + 0x69, 0x64, 0x64, 0x65, 0x6e, 0x3d, 0x22, 0x74, 0x72, 0x65, 0x3d, 0x28, 0x6e, + 0x65, 0x77, 0x20, 0x44, 0x61, 0x74, 0x65, 0x29, 0x2e, 0x67, 0x65, 0x74, 0x54, + 0x69, 0x6d, 0x65, 0x28, 0x29, 0x70, 0x6f, 0x72, 0x74, 0x75, 0x67, 0x75, 0xc3, + 0xaa, 0x73, 0x20, 0x28, 0x64, 0x6f, 0x20, 0x42, 0x72, 0x61, 0x73, 0x69, 0x6c, + 0x29, 0xd0, 0xbe, 0xd1, 0x80, 0xd0, 0xb3, 0xd0, 0xb0, 0xd0, 0xbd, 0xd0, 0xb8, + 0xd0, 0xb7, 0xd0, 0xb0, 0xd1, 0x86, 0xd0, 0xb8, 0xd0, 0xb8, 0xd0, 0xb2, 0xd0, + 0xbe, 0xd0, 0xb7, 0xd0, 0xbc, 0xd0, 0xbe, 0xd0, 0xb6, 0xd0, 0xbd, 0xd0, 0xbe, + 0xd1, 0x81, 0xd1, 0x82, 0xd1, 0x8c, 0xd0, 0xbe, 0xd0, 0xb1, 0xd1, 0x80, 0xd0, + 0xb0, 0xd0, 0xb7, 0xd0, 0xbe, 0xd0, 0xb2, 0xd0, 0xb0, 0xd0, 0xbd, 0xd0, 0xb8, + 0xd1, 0x8f, 0xd1, 0x80, 0xd0, 0xb5, 0xd0, 0xb3, 0xd0, 0xb8, 0xd1, 0x81, 0xd1, + 0x82, 0xd1, 0x80, 0xd0, 0xb0, 0xd1, 0x86, 0xd0, 0xb8, 0xd0, 0xb8, 0xd0, 0xb2, + 0xd0, 0xbe, 0xd0, 0xb7, 0xd0, 0xbc, 0xd0, 0xbe, 0xd0, 0xb6, 0xd0, 0xbd, 0xd0, + 0xbe, 0xd1, 0x81, 0xd1, 0x82, 0xd0, 0xb8, 0xd0, 0xbe, 0xd0, 0xb1, 0xd1, 0x8f, + 0xd0, 0xb7, 0xd0, 0xb0, 0xd1, 0x82, 0xd0, 0xb5, 0xd0, 0xbb, 0xd1, 0x8c, 0xd0, + 0xbd, 0xd0, 0xb0, 0x3c, 0x21, 0x44, 0x4f, 0x43, 0x54, 0x59, 0x50, 0x45, 0x20, + 0x68, 0x74, 0x6d, 0x6c, 0x20, 0x50, 0x55, 0x42, 0x4c, 0x49, 0x43, 0x20, 0x22, + 0x6e, 0x74, 0x2d, 0x54, 0x79, 0x70, 0x65, 0x22, 0x20, 0x63, 0x6f, 0x6e, 0x74, + 0x65, 0x6e, 0x74, 0x3d, 0x22, 0x74, 0x65, 0x78, 0x74, 0x2f, 0x3c, 0x6d, 0x65, + 0x74, 0x61, 0x20, 0x68, 0x74, 0x74, 0x70, 0x2d, 0x65, 0x71, 0x75, 0x69, 0x76, + 0x3d, 0x22, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x72, 0x61, 0x6e, 0x73, 0x69, 0x74, + 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x2f, 0x2f, 0x45, 0x4e, 0x22, 0x20, 0x22, 0x68, + 0x74, 0x74, 0x70, 0x3a, 0x3c, 0x68, 0x74, 0x6d, 0x6c, 0x20, 0x78, 0x6d, 0x6c, + 0x6e, 0x73, 0x3d, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, + 0x77, 0x2d, 0x2f, 0x2f, 0x57, 0x33, 0x43, 0x2f, 0x2f, 0x44, 0x54, 0x44, 0x20, + 0x58, 0x48, 0x54, 0x4d, 0x4c, 0x20, 0x31, 0x2e, 0x30, 0x20, 0x54, 0x44, 0x54, + 0x44, 0x2f, 0x78, 0x68, 0x74, 0x6d, 0x6c, 0x31, 0x2d, 0x74, 0x72, 0x61, 0x6e, + 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x2f, 0x2f, 0x77, 0x77, 0x77, + 0x2e, 0x77, 0x33, 0x2e, 0x6f, 0x72, 0x67, 0x2f, 0x54, 0x52, 0x2f, 0x78, 0x68, + 0x74, 0x6d, 0x6c, 0x31, 0x2f, 0x70, 0x65, 0x20, 0x3d, 0x20, 0x27, 0x74, 0x65, + 0x78, 0x74, 0x2f, 0x6a, 0x61, 0x76, 0x61, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, + 0x27, 0x3b, 0x3c, 0x6d, 0x65, 0x74, 0x61, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x3d, + 0x22, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x70, + 0x61, 0x72, 0x65, 0x6e, 0x74, 0x4e, 0x6f, 0x64, 0x65, 0x2e, 0x69, 0x6e, 0x73, + 0x65, 0x72, 0x74, 0x42, 0x65, 0x66, 0x6f, 0x72, 0x65, 0x3c, 0x69, 0x6e, 0x70, + 0x75, 0x74, 0x20, 0x74, 0x79, 0x70, 0x65, 0x3d, 0x22, 0x68, 0x69, 0x64, 0x64, + 0x65, 0x6e, 0x22, 0x20, 0x6e, 0x61, 0x6a, 0x73, 0x22, 0x20, 0x74, 0x79, 0x70, + 0x65, 0x3d, 0x22, 0x74, 0x65, 0x78, 0x74, 0x2f, 0x6a, 0x61, 0x76, 0x61, 0x73, + 0x63, 0x72, 0x69, 0x28, 0x64, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x29, + 0x2e, 0x72, 0x65, 0x61, 0x64, 0x79, 0x28, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, + 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x20, 0x74, 0x79, 0x70, 0x65, 0x3d, 0x22, + 0x74, 0x65, 0x78, 0x74, 0x2f, 0x6a, 0x61, 0x76, 0x61, 0x73, 0x69, 0x6d, 0x61, + 0x67, 0x65, 0x22, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x3d, 0x22, + 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x55, 0x41, 0x2d, 0x43, 0x6f, 0x6d, + 0x70, 0x61, 0x74, 0x69, 0x62, 0x6c, 0x65, 0x22, 0x20, 0x63, 0x6f, 0x6e, 0x74, + 0x65, 0x6e, 0x74, 0x3d, 0x74, 0x6d, 0x6c, 0x3b, 0x20, 0x63, 0x68, 0x61, 0x72, + 0x73, 0x65, 0x74, 0x3d, 0x75, 0x74, 0x66, 0x2d, 0x38, 0x22, 0x20, 0x2f, 0x3e, + 0x0a, 0x6c, 0x69, 0x6e, 0x6b, 0x20, 0x72, 0x65, 0x6c, 0x3d, 0x22, 0x73, 0x68, + 0x6f, 0x72, 0x74, 0x63, 0x75, 0x74, 0x20, 0x69, 0x63, 0x6f, 0x6e, 0x3c, 0x6c, + 0x69, 0x6e, 0x6b, 0x20, 0x72, 0x65, 0x6c, 0x3d, 0x22, 0x73, 0x74, 0x79, 0x6c, + 0x65, 0x73, 0x68, 0x65, 0x65, 0x74, 0x22, 0x20, 0x3c, 0x2f, 0x73, 0x63, 0x72, + 0x69, 0x70, 0x74, 0x3e, 0x0a, 0x3c, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x20, + 0x74, 0x79, 0x70, 0x65, 0x3d, 0x3d, 0x20, 0x64, 0x6f, 0x63, 0x75, 0x6d, 0x65, + 0x6e, 0x74, 0x2e, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x45, 0x6c, 0x65, 0x6d, + 0x65, 0x6e, 0x3c, 0x61, 0x20, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x3d, 0x22, + 0x5f, 0x62, 0x6c, 0x61, 0x6e, 0x6b, 0x22, 0x20, 0x68, 0x72, 0x65, 0x66, 0x3d, + 0x20, 0x64, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x67, 0x65, 0x74, + 0x45, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x42, 0x69, 0x6e, 0x70, 0x75, + 0x74, 0x20, 0x74, 0x79, 0x70, 0x65, 0x3d, 0x22, 0x74, 0x65, 0x78, 0x74, 0x22, + 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x3d, 0x61, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x20, + 0x3d, 0x20, 0x27, 0x74, 0x65, 0x78, 0x74, 0x2f, 0x6a, 0x61, 0x76, 0x61, 0x73, + 0x63, 0x72, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x20, 0x74, 0x79, 0x70, 0x65, 0x3d, + 0x22, 0x68, 0x69, 0x64, 0x64, 0x65, 0x6e, 0x22, 0x20, 0x6e, 0x61, 0x6d, 0x65, + 0x68, 0x74, 0x6d, 0x6c, 0x3b, 0x20, 0x63, 0x68, 0x61, 0x72, 0x73, 0x65, 0x74, + 0x3d, 0x75, 0x74, 0x66, 0x2d, 0x38, 0x22, 0x20, 0x2f, 0x3e, 0x64, 0x74, 0x64, + 0x22, 0x3e, 0x0a, 0x3c, 0x68, 0x74, 0x6d, 0x6c, 0x20, 0x78, 0x6d, 0x6c, 0x6e, + 0x73, 0x3d, 0x22, 0x68, 0x74, 0x74, 0x70, 0x2d, 0x2f, 0x2f, 0x57, 0x33, 0x43, + 0x2f, 0x2f, 0x44, 0x54, 0x44, 0x20, 0x48, 0x54, 0x4d, 0x4c, 0x20, 0x34, 0x2e, + 0x30, 0x31, 0x20, 0x54, 0x65, 0x6e, 0x74, 0x73, 0x42, 0x79, 0x54, 0x61, 0x67, + 0x4e, 0x61, 0x6d, 0x65, 0x28, 0x27, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x27, + 0x29, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x20, 0x74, 0x79, 0x70, 0x65, 0x3d, 0x22, + 0x68, 0x69, 0x64, 0x64, 0x65, 0x6e, 0x22, 0x20, 0x6e, 0x61, 0x6d, 0x3c, 0x73, + 0x63, 0x72, 0x69, 0x70, 0x74, 0x20, 0x74, 0x79, 0x70, 0x65, 0x3d, 0x22, 0x74, + 0x65, 0x78, 0x74, 0x2f, 0x6a, 0x61, 0x76, 0x61, 0x73, 0x22, 0x20, 0x73, 0x74, + 0x79, 0x6c, 0x65, 0x3d, 0x22, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x3a, + 0x6e, 0x6f, 0x6e, 0x65, 0x3b, 0x22, 0x3e, 0x64, 0x6f, 0x63, 0x75, 0x6d, 0x65, + 0x6e, 0x74, 0x2e, 0x67, 0x65, 0x74, 0x45, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, + 0x42, 0x79, 0x49, 0x64, 0x28, 0x3d, 0x64, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, + 0x74, 0x2e, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x45, 0x6c, 0x65, 0x6d, 0x65, + 0x6e, 0x74, 0x28, 0x27, 0x20, 0x74, 0x79, 0x70, 0x65, 0x3d, 0x27, 0x74, 0x65, + 0x78, 0x74, 0x2f, 0x6a, 0x61, 0x76, 0x61, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, + 0x27, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x20, 0x74, 0x79, 0x70, 0x65, 0x3d, 0x22, + 0x74, 0x65, 0x78, 0x74, 0x22, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x3d, 0x22, 0x64, + 0x2e, 0x67, 0x65, 0x74, 0x45, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x42, + 0x79, 0x54, 0x61, 0x67, 0x4e, 0x61, 0x6d, 0x65, 0x28, 0x73, 0x6e, 0x69, 0x63, + 0x61, 0x6c, 0x22, 0x20, 0x68, 0x72, 0x65, 0x66, 0x3d, 0x22, 0x68, 0x74, 0x74, + 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x43, 0x2f, 0x2f, 0x44, 0x54, + 0x44, 0x20, 0x48, 0x54, 0x4d, 0x4c, 0x20, 0x34, 0x2e, 0x30, 0x31, 0x20, 0x54, + 0x72, 0x61, 0x6e, 0x73, 0x69, 0x74, 0x3c, 0x73, 0x74, 0x79, 0x6c, 0x65, 0x20, + 0x74, 0x79, 0x70, 0x65, 0x3d, 0x22, 0x74, 0x65, 0x78, 0x74, 0x2f, 0x63, 0x73, + 0x73, 0x22, 0x3e, 0x0a, 0x0a, 0x3c, 0x73, 0x74, 0x79, 0x6c, 0x65, 0x20, 0x74, + 0x79, 0x70, 0x65, 0x3d, 0x22, 0x74, 0x65, 0x78, 0x74, 0x2f, 0x63, 0x73, 0x73, + 0x22, 0x3e, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x2e, 0x64, 0x74, 0x64, 0x22, 0x3e, + 0x0a, 0x3c, 0x68, 0x74, 0x6d, 0x6c, 0x20, 0x78, 0x6d, 0x6c, 0x6e, 0x73, 0x3d, + 0x68, 0x74, 0x74, 0x70, 0x2d, 0x65, 0x71, 0x75, 0x69, 0x76, 0x3d, 0x22, 0x43, + 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x54, 0x79, 0x70, 0x65, 0x64, 0x69, + 0x6e, 0x67, 0x3d, 0x22, 0x30, 0x22, 0x20, 0x63, 0x65, 0x6c, 0x6c, 0x73, 0x70, + 0x61, 0x63, 0x69, 0x6e, 0x67, 0x3d, 0x22, 0x30, 0x22, 0x68, 0x74, 0x6d, 0x6c, + 0x3b, 0x20, 0x63, 0x68, 0x61, 0x72, 0x73, 0x65, 0x74, 0x3d, 0x75, 0x74, 0x66, + 0x2d, 0x38, 0x22, 0x20, 0x2f, 0x3e, 0x0a, 0x20, 0x73, 0x74, 0x79, 0x6c, 0x65, + 0x3d, 0x22, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x3a, 0x6e, 0x6f, 0x6e, + 0x65, 0x3b, 0x22, 0x3e, 0x3c, 0x3c, 0x6c, 0x69, 0x3e, 0x3c, 0x61, 0x20, 0x68, + 0x72, 0x65, 0x66, 0x3d, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, + 0x77, 0x77, 0x2e, 0x20, 0x74, 0x79, 0x70, 0x65, 0x3d, 0x27, 0x74, 0x65, 0x78, + 0x74, 0x2f, 0x6a, 0x61, 0x76, 0x61, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x27, + 0x3e, 0xd0, 0xb4, 0xd0, 0xb5, 0xd1, 0x8f, 0xd1, 0x82, 0xd0, 0xb5, 0xd0, 0xbb, + 0xd1, 0x8c, 0xd0, 0xbd, 0xd0, 0xbe, 0xd1, 0x81, 0xd1, 0x82, 0xd0, 0xb8, 0xd1, + 0x81, 0xd0, 0xbe, 0xd0, 0xbe, 0xd1, 0x82, 0xd0, 0xb2, 0xd0, 0xb5, 0xd1, 0x82, + 0xd1, 0x81, 0xd1, 0x82, 0xd0, 0xb2, 0xd0, 0xb8, 0xd0, 0xb8, 0xd0, 0xbf, 0xd1, + 0x80, 0xd0, 0xbe, 0xd0, 0xb8, 0xd0, 0xb7, 0xd0, 0xb2, 0xd0, 0xbe, 0xd0, 0xb4, + 0xd1, 0x81, 0xd1, 0x82, 0xd0, 0xb2, 0xd0, 0xb0, 0xd0, 0xb1, 0xd0, 0xb5, 0xd0, + 0xb7, 0xd0, 0xbe, 0xd0, 0xbf, 0xd0, 0xb0, 0xd1, 0x81, 0xd0, 0xbd, 0xd0, 0xbe, + 0xd1, 0x81, 0xd1, 0x82, 0xd0, 0xb8, 0xe0, 0xa4, 0xaa, 0xe0, 0xa5, 0x81, 0xe0, + 0xa4, 0xb8, 0xe0, 0xa5, 0x8d, 0xe0, 0xa4, 0xa4, 0xe0, 0xa4, 0xbf, 0xe0, 0xa4, + 0x95, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, 0x95, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, 0x82, + 0xe0, 0xa4, 0x97, 0xe0, 0xa5, 0x8d, 0xe0, 0xa4, 0xb0, 0xe0, 0xa5, 0x87, 0xe0, + 0xa4, 0xb8, 0xe0, 0xa4, 0x89, 0xe0, 0xa4, 0xa8, 0xe0, 0xa5, 0x8d, 0xe0, 0xa4, + 0xb9, 0xe0, 0xa5, 0x8b, 0xe0, 0xa4, 0x82, 0xe0, 0xa4, 0xa8, 0xe0, 0xa5, 0x87, + 0xe0, 0xa4, 0xb5, 0xe0, 0xa4, 0xbf, 0xe0, 0xa4, 0xa7, 0xe0, 0xa4, 0xbe, 0xe0, + 0xa4, 0xa8, 0xe0, 0xa4, 0xb8, 0xe0, 0xa4, 0xad, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, + 0xab, 0xe0, 0xa4, 0xbf, 0xe0, 0xa4, 0x95, 0xe0, 0xa5, 0x8d, 0xe0, 0xa4, 0xb8, + 0xe0, 0xa4, 0xbf, 0xe0, 0xa4, 0x82, 0xe0, 0xa4, 0x97, 0xe0, 0xa4, 0xb8, 0xe0, + 0xa5, 0x81, 0xe0, 0xa4, 0xb0, 0xe0, 0xa4, 0x95, 0xe0, 0xa5, 0x8d, 0xe0, 0xa4, + 0xb7, 0xe0, 0xa4, 0xbf, 0xe0, 0xa4, 0xa4, 0xe0, 0xa4, 0x95, 0xe0, 0xa5, 0x89, + 0xe0, 0xa4, 0xaa, 0xe0, 0xa5, 0x80, 0xe0, 0xa4, 0xb0, 0xe0, 0xa4, 0xbe, 0xe0, + 0xa4, 0x87, 0xe0, 0xa4, 0x9f, 0xe0, 0xa4, 0xb5, 0xe0, 0xa4, 0xbf, 0xe0, 0xa4, + 0x9c, 0xe0, 0xa5, 0x8d, 0xe0, 0xa4, 0x9e, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, 0xaa, + 0xe0, 0xa4, 0xa8, 0xe0, 0xa4, 0x95, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, 0xb0, 0xe0, + 0xa5, 0x8d, 0xe0, 0xa4, 0xb0, 0xe0, 0xa4, 0xb5, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, + 0x88, 0xe0, 0xa4, 0xb8, 0xe0, 0xa4, 0x95, 0xe0, 0xa5, 0x8d, 0xe0, 0xa4, 0xb0, + 0xe0, 0xa4, 0xbf, 0xe0, 0xa4, 0xaf, 0xe0, 0xa4, 0xa4, 0xe0, 0xa4, 0xbe, +}; + +#if defined(__cplusplus) || defined(c_plusplus) +} /* extern "C" */ +#endif diff --git a/web/server/h2o/libh2o/deps/brotli/enc/dictionary.h b/web/server/h2o/libh2o/deps/brotli/enc/dictionary.h new file mode 100644 index 00000000..c9c6362d --- /dev/null +++ b/web/server/h2o/libh2o/deps/brotli/enc/dictionary.h @@ -0,0 +1,41 @@ +/* Copyright 2013 Google Inc. All Rights Reserved. + + Distributed under MIT license. + See file LICENSE for detail or copy at https://opensource.org/licenses/MIT +*/ + +// Collection of static dictionary words. + +#ifndef BROTLI_ENC_DICTIONARY_H_ +#define BROTLI_ENC_DICTIONARY_H_ + +#include "./types.h" + +// No namespace, use same identifier as for the C decoder. + +#if defined(__cplusplus) || defined(c_plusplus) +extern "C" { +#endif + +extern const uint8_t kBrotliDictionary[122784]; + +static const uint32_t kBrotliDictionaryOffsetsByLength[] = { + 0, 0, 0, 0, 0, 4096, 9216, 21504, 35840, 44032, + 53248, 63488, 74752, 87040, 93696, 100864, 104704, 106752, 108928, 113536, + 115968, 118528, 119872, 121280, 122016, +}; + +static const uint8_t kBrotliDictionarySizeBitsByLength[] = { + 0, 0, 0, 0, 10, 10, 11, 11, 10, 10, + 10, 10, 10, 9, 9, 8, 7, 7, 8, 7, + 7, 6, 6, 5, 5, +}; + +static const int kBrotliMinDictionaryWordLength = 4; +static const int kBrotliMaxDictionaryWordLength = 24; + +#if defined(__cplusplus) || defined(c_plusplus) +} /* extern "C" */ +#endif + +#endif // BROTLI_ENC_DICTIONARY_H_ diff --git a/web/server/h2o/libh2o/deps/brotli/enc/dictionary_hash.h b/web/server/h2o/libh2o/deps/brotli/enc/dictionary_hash.h new file mode 100644 index 00000000..afbb1f1e --- /dev/null +++ b/web/server/h2o/libh2o/deps/brotli/enc/dictionary_hash.h @@ -0,0 +1,4117 @@ +/* Copyright 2015 Google Inc. All Rights Reserved. + + Distributed under MIT license. + See file LICENSE for detail or copy at https://opensource.org/licenses/MIT +*/ + +// Hash table on the 4-byte prefixes of static dictionary words. + +#ifndef BROTLI_ENC_DICTIONARY_HASH_H_ +#define BROTLI_ENC_DICTIONARY_HASH_H_ + +#include "./types.h" + +namespace brotli { + +static const uint16_t kStaticDictionaryHash[] = { + 0x7d48, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x5564, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x9e26, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xb2e6, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x050c, 0x0000, + 0x0000, 0x0000, 0x0000, 0x1364, 0x0116, 0x5ca5, 0x0000, 0x4e04, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x084e, 0x3ee6, 0x0000, 0x0000, + 0x0000, 0x3865, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x6867, 0x08cd, 0x0000, 0x0000, 0x4364, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0e26, + 0x0000, 0x0000, 0x0000, 0x0000, 0x59c8, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x4107, 0x0000, 0x85c7, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0xbd66, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x09cf, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x4c4c, 0x0000, 0x0000, 0x5dc4, + 0x0000, 0x0000, 0x0000, 0x2664, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x7885, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x7ce6, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x50aa, 0x0964, + 0x0000, 0x5125, 0x068d, 0x2347, 0x0000, 0x1904, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0xcaa7, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x1a69, 0x1c26, 0x0000, 0x0000, 0x55e8, 0x59c7, 0x0000, 0x0000, + 0x0dc9, 0x0000, 0x0748, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x2b26, 0x0000, 0x0000, 0x25a9, 0x0000, 0x0000, 0x0000, + 0x196b, 0x0000, 0x0000, 0x9046, 0x5448, 0xf3a7, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x2066, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x9f67, + 0x0000, 0x0000, 0x0000, 0x99e6, 0x1fc8, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x22ab, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x1f05, 0x0000, 0x0000, 0x6409, 0x0000, 0x0000, 0x0000, + 0x03a8, 0x0e84, 0x0c8d, 0x3d47, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0xcd27, 0x0000, 0x43e5, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0528, 0x16a5, 0x0000, 0x5225, 0x0000, 0x0000, 0x1948, 0x0327, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x34e9, 0x0000, 0x0000, 0x0000, 0x0e28, 0x0000, + 0x0000, 0x0000, 0x73ea, 0x7864, 0x0000, 0x7a05, 0x0000, 0x19c4, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0xfa46, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5706, 0x0000, 0x9246, + 0x0000, 0x0000, 0x0000, 0x0000, 0x1c48, 0x01a7, 0x0000, 0x6024, + 0x54c9, 0x44e4, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0729, 0x0000, 0x0000, 0x0000, 0x0148, 0x1785, 0x0000, 0x0000, + 0x0000, 0x4e06, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0xf2a7, 0x1052, 0x0000, 0x0000, 0x0000, + 0x0000, 0x2f44, 0x21a9, 0x0000, 0x0000, 0x4204, 0x0000, 0x8f46, + 0x0000, 0x0000, 0x0000, 0x8a26, 0x0000, 0xca06, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5206, 0x0000, 0xf286, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x15a6, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x3925, 0x2ac8, 0x6547, 0x0000, 0x0000, 0x0000, 0x0000, + 0x4d89, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x78e8, 0x0be6, 0x37ea, 0x32c6, 0x0000, 0x0000, 0x0000, 0x3ba4, + 0x0000, 0x9e86, 0x7608, 0xf2a6, 0x0000, 0x0000, 0x0000, 0x4ea4, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x2ee5, 0x0000, 0x0000, + 0x0000, 0xcc86, 0x0000, 0x0000, 0x0000, 0x0000, 0x60ca, 0x0000, + 0x002c, 0x8147, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6704, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0ec5, 0x0000, 0x0000, + 0x4608, 0x2507, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x7e29, 0x6fc5, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0xb846, 0x2dcb, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x09e8, 0xd767, 0x0000, 0x0000, + 0x190a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0xdbe6, 0x2e8a, 0x0000, 0x0211, 0x0000, 0x75e8, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x2045, 0x0000, 0x0000, 0x7088, 0xe5e6, 0x5869, 0x03c5, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0xfa87, 0x0000, 0x0000, 0x014b, 0x0e64, + 0x0000, 0x0645, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x410a, 0x0025, 0x0000, 0x5c46, + 0x0c48, 0x3c45, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x57ab, 0x0045, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x45a8, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x2b69, 0x0000, 0x0000, 0x0000, 0x0000, 0x4785, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6806, + 0x0000, 0x0000, 0x63a8, 0x6527, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4205, + 0x0000, 0x0000, 0x0000, 0x6ba6, 0x0000, 0x0000, 0x24ca, 0x0000, + 0x0000, 0x0000, 0x0db4, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x9466, 0x2449, 0x2145, 0x0000, 0x0000, + 0x0000, 0x0000, 0x062a, 0x0644, 0x5d88, 0x0000, 0x0000, 0x3a44, + 0x31ed, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x2f49, 0x0000, 0x40e9, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5364, + 0x2be8, 0x70c6, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x168c, 0x0000, 0x0000, 0x6ca4, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x2084, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x416c, 0x0485, 0x0000, 0x0000, 0x496a, 0x3fc4, + 0x652a, 0x03a7, 0x208d, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x4746, 0x0000, 0x46a6, 0x0000, 0xb706, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0153, 0x0000, + 0x0000, 0x6264, 0x31ec, 0x2f86, 0x1909, 0x0000, 0x0000, 0x0000, + 0x0000, 0x4084, 0x0000, 0x6984, 0x6eeb, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x058c, 0x0000, 0x0000, 0x0000, + 0x2628, 0xcee7, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x624b, 0x0144, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0xfde6, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x5585, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xb906, + 0x0000, 0x0000, 0x0000, 0x0366, 0x0000, 0x0000, 0x0000, 0x3166, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x65a4, 0x3fe8, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0711, 0x0000, 0x0000, 0x0000, + 0x19c9, 0x3e06, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x71a4, + 0x0000, 0x6f64, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x55e4, 0x0000, 0x0000, 0x0000, 0xa7c6, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x140d, 0x0526, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xd6c6, + 0x6148, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0xc946, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0e65, 0x0000, 0x0000, 0x0000, 0x0000, 0x274e, 0x24c4, + 0x0000, 0x0000, 0x0000, 0x7ae4, 0x164c, 0x1825, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x15c7, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x6a08, 0xe086, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x1bac, 0x0000, 0x55e9, 0xcf86, 0x0000, 0x0000, + 0x0000, 0x0000, 0x20cd, 0x0000, 0x0000, 0x1665, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0844, 0x0000, 0x60a6, 0x0000, 0x2c07, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x046d, 0x0000, 0x1309, 0x0000, 0x0000, 0x95a6, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x460c, 0x0000, 0x0000, 0x4685, 0x0000, 0x0000, + 0x0000, 0x63a6, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x4586, 0x0000, 0x6666, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x59e8, 0x4407, 0x4fa8, 0x00a4, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0ca7, 0x0000, 0xb427, 0x0000, 0x0000, + 0x0000, 0x6fa4, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x1dc5, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0xa206, 0x0000, 0x0000, 0x7928, 0xd826, + 0x2748, 0x0784, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x8f06, + 0x0000, 0x8f67, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x36aa, 0xe7a7, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6785, 0x0000, 0x1607, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3649, 0x04e5, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x13e7, 0x0000, 0x0000, + 0x0000, 0x70c5, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x21c6, 0x0000, 0x0000, 0x0000, 0x0000, + 0x6429, 0x4584, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x3404, 0x026c, 0x18a5, 0x2e2b, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0388, 0x0447, + 0x0000, 0x5ea5, 0x0000, 0x0000, 0x7048, 0xc227, 0x0000, 0x5a25, + 0x0000, 0x0000, 0x0000, 0x0000, 0x7e88, 0x0000, 0x0000, 0x0000, + 0x0000, 0x89c7, 0x0000, 0x7044, 0x16ea, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x1109, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x1eed, 0x22a5, 0x0000, 0x0000, 0x0000, 0x3664, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0xa3e6, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x1a6e, 0x36a5, 0x0000, 0x0000, 0x0000, 0x0387, + 0x0000, 0x0000, 0x5dca, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xfb86, + 0x0000, 0x57c4, 0x0000, 0x6505, 0x0000, 0x0000, 0x0000, 0x0000, + 0x5c68, 0x14c5, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x59e9, 0x1545, 0x3e89, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0xbb86, 0x28e9, 0x0000, 0x0000, 0x3844, + 0x0000, 0x0000, 0x0000, 0xa4c7, 0x0000, 0x0000, 0x0000, 0xc846, + 0x0000, 0x0000, 0x296a, 0x5e44, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0xab06, 0x0000, 0x0000, 0x45aa, 0x0000, 0x0000, 0x0000, + 0x63e8, 0x6a45, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x718a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0272, 0x07c4, 0x396c, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xe146, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0xaea6, 0x0000, 0x0000, 0x0000, 0x0000, 0x0f08, 0x1dc7, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0xa586, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x4b48, 0x1924, 0x0000, 0x0000, + 0x1488, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4ce5, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x9b67, 0x0000, 0x0000, + 0x0000, 0x0000, 0x7908, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x6e46, 0x0000, 0x0000, 0x0000, 0x7164, 0x292a, 0x0c85, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x1604, 0x0348, 0x0127, 0x0000, 0x0000, + 0x2128, 0x2006, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x5064, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0fea, 0x4c46, + 0x0000, 0x0000, 0x0000, 0x0000, 0x79a8, 0xfa26, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x414c, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x452a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xc5c6, + 0x0000, 0xc547, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6366, 0x0000, 0x0000, + 0x0000, 0x3607, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0a88, 0x0fc7, 0x0000, 0x0000, 0x0000, 0x0000, 0x62c8, 0x0000, + 0x2f2c, 0x0806, 0x0000, 0xbf26, 0x0000, 0x0000, 0x0000, 0x0000, + 0x4249, 0xe827, 0x436b, 0x8a07, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x7a2b, 0x0000, 0x0000, 0x0000, 0x0449, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0308, 0x0347, 0x0000, 0x0000, 0x72ca, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x16e8, 0x2f66, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6305, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xf007, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x6066, 0x0000, 0x0000, 0x0000, 0xf767, 0x0000, 0x70a4, + 0x1fce, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x118e, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x3708, 0x04a4, 0x0000, 0x3f84, 0x0000, 0x0000, + 0x0000, 0x4025, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0114, 0x0000, 0x0000, 0x42a4, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5e0c, 0x7305, + 0x0000, 0x8307, 0x0000, 0x1325, 0x0000, 0x0000, 0x30ea, 0x0000, + 0x0000, 0xf407, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0fce, 0x0000, 0x0000, 0x0000, + 0x0000, 0x5006, 0x0000, 0x3c64, 0x08a9, 0xca07, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x5bc7, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x3c0a, 0x0000, 0x3de9, 0x0000, 0x3b09, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6d44, + 0x1ca9, 0x0000, 0x0000, 0x0000, 0x0000, 0x7686, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x7e2b, 0x5d84, + 0x0000, 0x4566, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x1828, 0x0000, 0x51a8, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x7b04, 0x0000, 0x0000, + 0x0000, 0x1585, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0a6d, 0xc406, 0x0000, 0x0000, 0x300b, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x1489, 0x6e07, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x2de6, 0x0f32, 0x0000, 0x0000, 0x6784, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xc0a6, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x2ae5, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x4629, 0x0727, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x73c6, 0x0000, 0x0000, 0x0000, 0x0000, 0x6769, 0x0000, + 0x1848, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x02c7, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x700b, 0x9c27, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xc9c6, + 0x0000, 0x0000, 0x0000, 0x6b87, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x788b, 0x0cc4, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x7064, 0x0000, 0x4724, + 0x0000, 0x0000, 0x0000, 0x0000, 0x6368, 0xffa6, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0d09, 0x0686, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x4b84, 0x0000, 0x0000, 0x0000, 0x0000, + 0x6168, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0413, 0x0000, 0x0000, 0x0000, 0x0000, 0x3dc6, 0x0000, 0x54a6, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3f87, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x7ec6, 0x0000, 0x77a6, 0x0000, 0x0000, 0x4eca, 0x26c6, + 0x0000, 0x0000, 0x0000, 0x4747, 0x0000, 0x0000, 0x3828, 0x0000, + 0x0808, 0x4327, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x1e84, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x57ca, 0xce46, 0x0634, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x2a49, 0x0000, 0x0000, 0x0000, 0x0000, 0x9fe6, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x7005, 0x0000, 0x0000, + 0x1652, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6509, 0x56e6, + 0x0000, 0x0000, 0x0000, 0x0000, 0x4368, 0x8ba7, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x202c, 0x0000, + 0x7d6c, 0x0000, 0x0000, 0x0000, 0x002b, 0x3806, 0x0000, 0x4085, + 0x0000, 0x0000, 0x780c, 0x0000, 0x0fac, 0x0085, 0x0000, 0x9e87, + 0x03cb, 0x5d86, 0x0000, 0x0000, 0x6a8b, 0x0000, 0x0000, 0x0000, + 0x00cc, 0x0000, 0x0000, 0x6a04, 0x1d8c, 0xad27, 0x6bc8, 0xe266, + 0x0000, 0x0000, 0x0000, 0x0000, 0x5748, 0x6465, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4c44, 0x7c0b, 0x0000, + 0x0000, 0x6dc6, 0x0000, 0xe6e7, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x2fe5, 0x0000, 0xaf86, 0x0000, 0x0000, + 0x0000, 0x0000, 0x7b48, 0x0000, 0x2b6a, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x4a09, 0x4787, 0x0000, 0xb067, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x080b, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4bc7, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xe4a6, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x578b, 0x5d87, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x2daa, 0x0000, 0x0000, 0x0fe5, 0x0000, 0x0000, + 0x0a6c, 0x18c6, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x6c0a, 0x06e6, 0x0000, 0x0000, 0x0000, 0x0000, 0x5ac8, 0xdb06, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x8547, 0x0000, 0x5f85, + 0x0000, 0x0000, 0x0000, 0x0000, 0x556b, 0x0000, 0x44ca, 0x26a6, + 0x0000, 0x0000, 0x6d48, 0x9786, 0x0000, 0x0000, 0x0000, 0xaa86, + 0x0000, 0x7b47, 0x2faa, 0x5a66, 0x0000, 0x0000, 0x0000, 0xc4a7, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x8026, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0xc2e7, 0x0000, 0x0000, 0x0000, 0x0000, 0x3daa, 0x10a7, + 0x0000, 0x0000, 0x0000, 0x0000, 0x128a, 0x0ee6, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x4328, 0x01c5, 0x43ab, 0x0000, + 0x4f68, 0x0fc4, 0x0000, 0x0000, 0x0000, 0x3de4, 0x0000, 0x0000, + 0x0000, 0x0000, 0x6ba9, 0x7cc4, 0x7e28, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x2ceb, 0x2e06, 0x0000, 0x0000, + 0x0000, 0x0000, 0x260a, 0xc527, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x8a66, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x7426, + 0x0000, 0x0000, 0x0000, 0x8ec7, 0x0000, 0x0000, 0x0000, 0x0000, + 0x2429, 0x15e6, 0x0000, 0x3605, 0x0000, 0x1b67, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x6227, 0x0000, 0x0000, 0x4a6b, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0a0c, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x7465, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xa566, + 0x0000, 0x0000, 0x0000, 0x0000, 0x244d, 0x0000, 0x45e8, 0xdae6, + 0x0fed, 0x0000, 0x0000, 0x0000, 0x74cb, 0x91e7, 0x0000, 0x7867, + 0x0000, 0x2086, 0x0000, 0x0000, 0x0000, 0x47a6, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4889, 0xd326, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x9186, 0x0000, 0x0000, 0x7ac9, 0xf046, 0x0000, 0x07e6, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6325, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0865, 0x62c9, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x30e4, + 0x3769, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x21e4, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x8e86, 0x0000, 0x0000, + 0x0000, 0x0000, 0x2a89, 0x2587, 0x0000, 0x7027, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x6f4a, 0x0000, 0x0000, 0x0000, 0x0000, 0x6645, 0x282b, 0x06a5, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x3a84, 0x0000, 0x1e67, 0x0000, 0x6cc6, 0x0000, 0x0000, + 0x0000, 0xdca6, 0x0f34, 0x0000, 0x0000, 0x0000, 0x168a, 0x40c7, + 0x0000, 0x66c5, 0x346e, 0x4f44, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x7046, 0x0000, 0x0000, + 0x0000, 0x0000, 0x38c8, 0x0486, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x64c9, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xa5c6, 0x0000, 0x0d04, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x2087, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x43c9, 0x05a7, + 0x0000, 0x0000, 0x20eb, 0xbd86, 0x054f, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x3a8a, 0x0000, 0x7da8, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x240e, 0x0ae7, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x3ec9, 0x7b87, 0x10ad, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x11a7, 0x0000, 0x0000, 0x6d08, 0xe646, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x20a9, 0x4d64, + 0x0000, 0x0000, 0x0000, 0x0000, 0x17a8, 0x1ec5, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x54c5, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x23a8, 0x0465, + 0x0000, 0x40a4, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x438c, 0x1ac6, 0x5368, 0x0000, + 0x094c, 0x0000, 0x0000, 0x0fa7, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x5f25, 0x106a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x29a8, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xa747, 0x0bce, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x3825, 0x0000, 0x50c5, 0x0ce8, 0x0ac7, + 0x502a, 0xfd87, 0x0000, 0x0000, 0x0000, 0x0026, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x6ca6, 0x0af2, 0x22a6, 0x0eae, 0x04e7, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x754b, 0x2526, + 0x0000, 0x0000, 0x0000, 0x0000, 0x45c8, 0x3a07, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x5b6c, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xc906, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xb2a6, + 0x0000, 0x0000, 0x5bab, 0x7e47, 0x0000, 0x0000, 0x2a4a, 0xcf07, + 0x0000, 0x0000, 0x0000, 0x81c6, 0x7a68, 0xfb46, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x7da6, 0x0000, 0x0000, + 0x0f33, 0x0000, 0x0000, 0x0000, 0x1b69, 0x0285, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x6d0b, 0xb407, 0x0000, 0x0000, + 0x0000, 0x5567, 0x0000, 0x85c6, 0x0000, 0x0000, 0x414b, 0x0000, + 0x0000, 0x0000, 0x0000, 0x36e4, 0x53a8, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x9ba6, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x9846, 0x0000, 0x0000, 0x4468, 0x1d24, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x3c44, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x6ec4, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6365, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x2e67, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4dc7, 0x0000, 0x4e27, + 0x0000, 0x0000, 0x0000, 0x2a67, 0x03af, 0x0000, 0x0000, 0x2a45, + 0x0000, 0x0000, 0x0000, 0x0000, 0x104a, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x266c, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0xff87, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x2689, 0x6046, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x9e47, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x3204, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x564b, 0x5c67, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x7bc6, 0x0000, 0x0000, + 0x0000, 0xe4e7, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4ca4, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5f65, 0x0000, 0x6dc4, + 0x0000, 0x0000, 0x0000, 0x7a24, 0x0000, 0x0c84, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x39e6, + 0x0000, 0x0000, 0x0000, 0x0000, 0x4deb, 0x27c6, 0x0000, 0x0000, + 0x2508, 0x39e5, 0x112e, 0x0000, 0x0000, 0x38c4, 0x0000, 0x0000, + 0x0000, 0xbee7, 0x0751, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x024d, 0x0605, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x5b25, 0x0000, 0x0000, 0x0000, 0x3745, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0510, 0x3826, 0x0000, 0x6aa4, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x1c6c, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0xba66, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x142c, 0x06e5, + 0x0000, 0x3845, 0x0000, 0x92c6, 0x07ca, 0x0000, 0x19ec, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6ca7, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0a08, 0x1aa4, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x2c48, 0x6687, 0x0000, 0x0000, 0x5d68, 0x0000, 0x0000, 0x0000, + 0x7748, 0x0000, 0x0000, 0x8626, 0x0000, 0x4587, 0x0000, 0x0000, + 0x0000, 0x5685, 0x0000, 0x17e6, 0x0000, 0x6484, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x67e8, 0x1446, + 0x0000, 0x0000, 0x0476, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x9a67, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x9a46, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0c0d, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x12b2, 0x0000, 0x0000, 0x0000, + 0x70c9, 0x1984, 0x0000, 0x0000, 0x6828, 0x0000, 0x23e9, 0x2dc7, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x7c08, 0xfc86, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x2c85, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x6206, 0x0000, 0x0000, 0x46e9, 0x4ec7, + 0x0000, 0x0000, 0x0000, 0x4366, 0x0000, 0x0000, 0x036e, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x5e66, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x65cb, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x7b68, 0x0000, 0x0000, 0x1fe7, + 0x5f2a, 0x1844, 0x0000, 0x87c6, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x7f08, 0x0000, 0x0000, 0xae87, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x4645, 0x21e9, 0x7226, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x280b, 0x1326, 0x05ac, 0x3b67, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5926, + 0x0000, 0x28e5, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x4b89, 0x4506, 0x006b, 0x2ce6, 0x0000, 0x0000, 0x0000, 0x0000, + 0x6aa9, 0x0a05, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0xfc06, 0x00c8, 0x6ee5, 0x0000, 0x0000, 0x0000, 0x0000, + 0x79e8, 0x0000, 0x782a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x7289, 0xec66, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0c89, 0x0ca5, + 0x30ca, 0x5887, 0x0000, 0x0000, 0x0000, 0x4965, 0x7ae8, 0x4007, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x50a6, 0x0000, 0x0000, 0x0000, 0x6a66, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3e44, 0x1188, 0x1b27, + 0x0000, 0x0000, 0x0000, 0xb506, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x7125, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x5068, 0x0d27, 0x0000, 0x6306, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0716, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x42e5, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xda87, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5e45, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0b71, 0x0000, 0x0000, 0xc3a6, 0x0000, 0x0b66, + 0x630c, 0x7564, 0x0073, 0x2e46, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0bf0, 0x0000, 0x0000, 0x0000, 0x0000, 0x44e7, 0x00ef, 0x4d67, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x8fc6, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x53e7, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6f04, 0x2e0a, 0x12a4, + 0x0000, 0x0000, 0x0d28, 0x8dc7, 0x0000, 0x7ae7, 0x0000, 0x0000, + 0x3949, 0x03e4, 0x0000, 0x5066, 0x0000, 0x0000, 0x0000, 0x2704, + 0x0000, 0x5c85, 0x0000, 0x0000, 0x0000, 0xcd47, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x1d84, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0767, 0x088a, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x6c6b, 0x6367, 0x0000, 0x0000, + 0x0000, 0x0000, 0x794c, 0xf726, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x8f86, 0x0000, 0x60e4, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x7948, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x532a, 0x08e4, 0x0000, 0x0000, 0x0000, 0x0000, 0x676b, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x3be4, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0c68, 0x4be7, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0xf506, 0x0000, 0x0000, 0x0000, 0x6324, + 0x0000, 0x0000, 0x6ceb, 0x0524, 0x0000, 0x0000, 0x1e2c, 0x0bc7, + 0x0000, 0x0000, 0x0000, 0x0000, 0x1a29, 0x0000, 0x0000, 0xbb26, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0c45, 0x0000, 0x0000, 0x0000, 0x39e4, 0x0000, 0x0000, + 0x0000, 0x0000, 0x246e, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x7b05, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x19a6, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x19a9, 0x0544, 0x0000, 0x6426, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x4f64, 0x0000, 0x0000, 0x42ab, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x2e64, 0x0000, 0xa046, + 0x0000, 0x0000, 0x0000, 0x6725, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x2ca7, 0x6de9, 0x3a66, + 0x0000, 0x27a7, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x7386, 0x0000, 0x0000, 0x0000, 0x0000, 0x6a28, 0xe066, + 0x0000, 0x0000, 0x0000, 0x0000, 0x6fea, 0xe0e6, 0x056b, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0xe387, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x41a5, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0dc6, + 0x0000, 0x3da5, 0x0000, 0x15c4, 0x3428, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x48e9, 0x5ba7, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x3c2d, 0x1ae5, 0x0000, 0x0000, 0x0000, 0x0000, + 0x3ba8, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x2685, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x2528, 0x0fc5, 0x0000, 0x0000, 0x2d2b, 0xc1e7, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6ce8, 0xe1e6, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xa367, 0x0000, 0x55a4, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x63a5, + 0x0000, 0x6b46, 0x0000, 0x46a5, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x364a, 0x1f84, 0x6749, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x62e4, 0x0000, 0x0000, 0x0000, 0x0000, 0x3faa, 0x1ce5, + 0x164a, 0x4b27, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0570, 0xc6e7, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0xd267, 0x0000, 0x0000, 0x0000, 0x0000, 0x05ab, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x8c07, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x4589, 0x3dc5, 0x0000, 0x31c4, + 0x0000, 0x0000, 0x0000, 0x80c7, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x150d, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x79a7, 0x0000, 0x5044, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0xc9e6, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x2f4d, 0x4a47, 0x0000, 0x88a7, 0x0000, 0x54e4, + 0x0e10, 0x0000, 0x0000, 0x0000, 0x0000, 0xba86, 0x4388, 0xabc7, + 0x5949, 0xb9c7, 0x0000, 0x0000, 0x0000, 0x0000, 0x6728, 0xbce6, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x7706, 0x0000, 0x0000, + 0x5c08, 0x11e5, 0x0000, 0x5784, 0x0000, 0xc086, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0xc2a7, 0x0000, 0x0000, 0x0000, 0x6b85, 0x7bcb, 0x0007, + 0x0000, 0x0000, 0x64eb, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x1069, 0x4065, 0x0000, 0x50c4, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0ea9, 0x5b07, 0x3f88, 0x0f26, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x2caa, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x1da5, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0xdf07, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5924, + 0x2b8a, 0xc006, 0x0000, 0x5c47, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x3645, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x2dca, 0xeaa7, 0x04ea, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x4884, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x6d29, 0x0000, 0x0000, 0x0000, 0x0000, 0x1567, + 0x0000, 0x4e26, 0x44c8, 0x0d67, 0x2aec, 0x75e4, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6005, 0x000e, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x63e4, 0x0000, 0x0000, + 0x0000, 0x6fc4, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0xd127, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x8386, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x2206, + 0x0000, 0x3724, 0x0000, 0x0000, 0x0074, 0x0124, 0x0000, 0x0000, + 0x0000, 0x93c7, 0x0000, 0xa846, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x5548, 0x0000, 0x0000, 0x7d86, + 0x030f, 0x0000, 0x0000, 0x7906, 0x0000, 0x0000, 0x0000, 0x0044, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x172c, 0x0000, + 0x0000, 0x0000, 0x4849, 0x3b47, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0e2e, 0x4245, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x4585, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0208, 0xa4a6, 0x0000, 0x0000, 0x0c32, 0x0000, 0x0000, 0x0000, + 0x57ea, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x6f86, 0x0000, 0x0000, 0x0000, 0xc466, 0x0000, 0x0000, + 0x3549, 0x1746, 0x0000, 0x89a6, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x7529, 0x4924, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x508b, 0x2467, + 0x0000, 0x0000, 0x0000, 0x0000, 0x5da9, 0x0000, 0x1449, 0x0000, + 0x0000, 0x2fa4, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x5f46, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x4e89, 0x02a5, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x72eb, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x4f2a, 0x0000, 0x0000, 0x0000, 0x0000, 0x2987, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xba27, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x6804, 0x31c8, 0x0000, 0x50a8, 0x0000, 0x0000, 0x0000, + 0x01b0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0286, 0x0000, 0x6404, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0xf926, 0x0000, 0x0000, 0x0000, 0x0000, + 0x6028, 0x0000, 0x0000, 0x0000, 0x532b, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xb246, + 0x0000, 0x0000, 0x0000, 0x0000, 0x078b, 0x0000, 0x0000, 0x0000, + 0x5029, 0xea47, 0x0000, 0x5086, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0xdba7, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x7527, 0x0000, 0xce87, 0x0000, 0x51c6, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x41e7, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x1c45, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0xb9c6, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x28a6, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xa826, 0x0000, 0x0000, + 0x0b72, 0x0000, 0x3288, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x79a5, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x9307, + 0x0000, 0x44a4, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x7a08, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x02b0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0670, 0x0000, 0x0000, 0x0000, 0x0000, 0x2747, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0092, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x18c9, 0x00c7, 0x0000, 0x88a6, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0xde07, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xbf06, + 0x0000, 0x3464, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0989, 0x1144, 0x0000, 0x0000, 0x0000, 0x0000, + 0x4fcc, 0x03a5, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0xb147, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xd5c6, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x428c, 0x02e5, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x6bc5, 0x0000, 0x0000, 0x764a, 0x4a06, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x08c8, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x6589, 0x0000, 0x0000, 0x0000, + 0x098b, 0x0000, 0x0000, 0x7b86, 0x0000, 0x3746, 0x0000, 0x0000, + 0x0000, 0x7007, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x3c68, 0x0000, 0x0000, 0x0000, 0x0000, 0xd5a6, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0ef3, 0x0000, 0x0000, 0x0000, + 0x0eac, 0x0000, 0x26a9, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x4a8a, 0x7a07, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6004, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x40c4, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6be9, 0x0000, + 0x0000, 0x0000, 0x0310, 0x1227, 0x7f8c, 0x0000, 0x0000, 0xf806, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5246, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0d4c, 0xe466, 0x0000, 0x7e45, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x48ca, 0x0ae5, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x2164, + 0x0000, 0x0000, 0x0000, 0x57e5, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x3e09, 0x0000, 0x0000, 0x0000, 0x0000, 0x8c27, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x1f2a, 0x4624, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x5f04, 0x0000, 0x0000, 0x1349, 0x0000, + 0x0000, 0x0000, 0x1fe8, 0x0000, 0x346c, 0x2864, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x2e04, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4148, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x44e8, 0x4647, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0b89, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x238c, 0x41a6, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x77cb, 0x0000, 0x0000, 0x4a45, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x00cd, 0x3be6, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x07b1, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6688, 0xcd26, + 0x0000, 0xc286, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x25c4, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x1286, + 0x0000, 0x0000, 0x5489, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0xd146, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x164b, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0bca, 0x30a6, 0x0000, 0x0000, 0x0000, 0x0000, 0x0b68, 0x0106, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0e09, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5d66, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xda47, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0307, 0x0000, 0xa906, 0x13ca, 0xbf47, + 0x0000, 0x0000, 0x59ca, 0x1045, 0x230b, 0xaf26, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0xf347, 0x0110, 0x0000, 0x0000, 0x0000, + 0x0000, 0xc8e6, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x6e4a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3425, 0x0000, 0x0000, + 0x0000, 0xc7a7, 0x4f29, 0x3625, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0249, 0x1d46, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x5508, 0xf3c7, 0x0000, 0x0000, 0x0000, 0x0000, 0x1f2b, 0x00a6, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x9806, 0x0000, 0xdda6, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x3fa8, 0x1687, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x7d44, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x7464, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x5d6c, 0x75e7, 0x0000, 0xe5a7, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5026, 0x0000, 0x0000, + 0x0000, 0x0000, 0x2309, 0x0000, 0x0000, 0x0000, 0x00b7, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x090a, 0x4425, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5cc4, + 0x0000, 0x0000, 0x1fcb, 0x12e7, 0x6d0a, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x7326, 0x0000, 0x0000, 0x40a8, 0x6827, 0x0000, 0xd207, + 0x0000, 0x0000, 0x3688, 0x1f67, 0x4908, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x030e, 0x3e85, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x1872, 0xdde6, 0x4048, 0x30a7, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5ce4, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x248b, 0x0000, 0x0000, 0x0000, + 0x1c69, 0xa067, 0x60cc, 0xe1a6, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0eec, 0x0a25, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x7229, 0xeec6, + 0x0000, 0x0000, 0x0000, 0xe447, 0x3d4b, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x9146, 0x5788, 0x03c7, + 0x0000, 0x0000, 0x0000, 0x5a26, 0x68ea, 0x0000, 0x0000, 0x0000, + 0x4d29, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x1528, 0x3586, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0xce06, 0x4faa, 0x96a7, 0x0000, 0x0000, 0x0000, 0xc787, + 0x0000, 0x0000, 0x0088, 0x2144, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6bc4, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0213, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x22e8, 0x13a7, 0x30e8, 0x4b86, + 0x0000, 0x0000, 0x592b, 0x7627, 0x6daa, 0x79a4, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x6b69, 0x46e4, 0x4e88, 0xe6c7, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x5f45, 0x0000, 0x0000, 0x17ed, 0x0000, 0x0000, 0x0000, + 0x0000, 0x2545, 0x0000, 0x0000, 0x5fe9, 0x71a7, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6364, 0x0000, 0x0000, + 0x25ab, 0x0000, 0x0000, 0xf647, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x9a86, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x508c, 0x2e27, 0x01f3, 0x0000, + 0x1408, 0x08e6, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xb4e6, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x5bea, 0x9ce6, 0x0988, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3b46, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x692a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x6886, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0xcac7, 0x0000, 0x0000, 0x5bec, 0x0000, 0x0000, 0x0000, + 0x0000, 0xc826, 0x6489, 0xadc6, 0x314e, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0c06, 0x0000, 0x2425, 0x0000, 0x0000, + 0x0468, 0x5607, 0x0000, 0x0000, 0x0000, 0x5366, 0x0000, 0x4024, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xfe46, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5804, 0x0000, 0xbe86, + 0x0000, 0x86c7, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x2645, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x35e5, 0x0000, 0x9587, 0x0000, 0x0000, 0x06ca, 0x0000, + 0x01e9, 0xb507, 0x0000, 0xb146, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x7166, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x184c, 0xdce6, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x6905, 0x0000, 0x7086, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0xb386, 0x0000, 0x0000, 0x0000, 0x0000, 0x5049, 0xc307, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0bcb, 0x3046, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x67cb, 0x3407, 0x0000, 0x0000, 0x028d, 0x5b67, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x572c, 0x0000, 0x0000, 0x52c4, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6ba4, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6ce6, 0x53eb, 0x6c05, + 0x0000, 0x7405, 0x00ed, 0x0000, 0x2988, 0x0000, 0x0000, 0x0000, + 0x0000, 0x83e6, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x7b4b, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0588, 0x0987, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x258b, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x15eb, 0x40c5, 0x67e9, 0x8a86, 0x0000, 0x0000, + 0x0000, 0x6884, 0x0000, 0xe787, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6968, 0xe186, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x1eca, 0x0000, 0x0000, 0x0000, 0x4c48, 0x1945, 0x0000, 0x0000, + 0x0489, 0x0000, 0x0000, 0x0000, 0x1e08, 0x51c7, 0x01a9, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x30e7, + 0x0000, 0x3266, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x096b, 0x0000, 0x2dcd, 0x65e6, + 0x0000, 0x0000, 0x4ee9, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x2b25, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x7707, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5425, + 0x0475, 0x52c6, 0x0000, 0x23e4, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x00b8, 0x0445, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x12ea, 0x0000, 0x3568, 0x0000, + 0x0000, 0x2fc6, 0x0000, 0x0000, 0x0000, 0x2924, 0x0000, 0x0000, + 0x22e9, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x7144, 0x0000, 0x0000, 0x2dc8, 0x6966, + 0x0000, 0xb466, 0x0000, 0xab87, 0x7c0a, 0x0000, 0x0488, 0x0f64, + 0x0000, 0x5124, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5fe5, + 0x0000, 0x7f46, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x7c65, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0906, 0x2e0c, 0x0000, 0x0000, 0xa827, + 0x0000, 0x0000, 0x0000, 0x49a5, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xf886, 0x0000, 0x0000, + 0x1b88, 0x43a6, 0x0000, 0x0000, 0x0000, 0x55c5, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x040f, 0x1887, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x2fa5, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xb586, + 0x0000, 0x0000, 0x0018, 0x4d07, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x99a7, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x5369, 0x0f06, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x8f47, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x2c04, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x24a6, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x74e6, 0x0000, 0x8346, 0x0000, 0x1264, 0x0b0c, 0x0000, + 0x0000, 0x7367, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x74c5, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0e4f, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x2aa8, 0x1bc7, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x24a8, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4fa4, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x90e6, 0x0000, 0x0000, + 0x0000, 0x69e6, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x5569, 0x0000, 0x6c69, 0x7606, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0xe227, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x3168, 0x1546, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x4d48, 0x42e4, 0x0000, 0xcb27, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x02f6, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6144, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x05c4, 0x0000, 0xfe07, + 0x0000, 0x0000, 0x04b5, 0xb647, 0x0000, 0x7547, 0x2d69, 0x0446, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x274a, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6f27, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x39c4, 0x0000, 0x0000, 0x0000, 0x0000, 0x41a8, 0x0000, + 0x0000, 0x02e6, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5484, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x3e48, 0x5aa7, 0x0000, 0x0000, 0x0000, 0x0000, + 0x00f7, 0x0000, 0x0000, 0x0000, 0x0000, 0x60a7, 0x0000, 0x0000, + 0x0000, 0x1484, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x7509, 0x48e4, 0x526b, 0xb6c7, 0x0000, 0x1b85, + 0x0000, 0x0000, 0x0000, 0x0000, 0x646b, 0x0000, 0x0000, 0x4404, + 0x0ef4, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x16ab, 0x1605, 0x0000, 0x9507, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xeac7, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0355, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x7607, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x2225, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x6ae6, 0x0000, 0x0000, 0x0000, 0x0000, + 0x00ab, 0x0fe6, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x5e09, 0x1cc6, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0888, 0x1445, + 0x0000, 0x51c4, 0x0609, 0x1384, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x1e04, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x18a9, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x786a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x6b47, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5488, 0xf747, + 0x0000, 0x0000, 0x0ccb, 0x7987, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x2d24, 0x0000, 0x39a4, 0x0000, 0x0000, + 0x0000, 0x3b04, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x5d6a, 0x7126, 0x0000, 0x0000, 0x0000, 0x1365, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x27e8, 0x1467, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x6a06, 0x0000, 0x0000, 0x0495, 0x4ee6, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xdd26, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x1204, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x2e2e, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4569, 0x1ee6, + 0x0000, 0x0000, 0x7c88, 0x0000, 0x0000, 0x17a7, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x230a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x41c8, 0x5d47, 0x0000, 0x0000, + 0x2b2b, 0x0000, 0x0000, 0x0000, 0x7f28, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x516a, 0x3585, 0x0000, 0x0000, + 0x0000, 0x9147, 0x1ccd, 0x28e7, 0x444a, 0x6304, 0x0000, 0x0000, + 0x0000, 0x9666, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x5405, 0x17aa, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0c65, 0x0000, 0x0000, 0x0000, 0x2547, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4568, 0x31a4, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x90a6, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x31cc, 0xbe67, 0x0000, 0x2dc6, 0x0000, 0x0000, 0x626a, 0x0000, + 0x0000, 0x0000, 0x2349, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x13a4, 0x0000, 0x75a6, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0xa707, 0x0000, 0x0000, 0x0e88, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x6266, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x154a, 0x1405, + 0x0000, 0xe2e6, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6c44, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x5624, 0x0000, 0x0000, 0x0000, 0x0000, 0x6689, 0x0000, + 0x3e4b, 0x0d84, 0x0000, 0x0000, 0x0000, 0x8be6, 0x0000, 0x0000, + 0x0000, 0x1e85, 0x4c2c, 0x7da7, 0x0000, 0x48a5, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x6fe4, 0x0000, 0x0000, 0x0000, 0xed47, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x73c4, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x4344, 0x3e0d, 0x24c6, 0x25aa, 0x0000, + 0x0000, 0x0000, 0x0251, 0x0000, 0x0000, 0x5ea4, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x9de6, 0x0000, 0x6684, 0x0000, 0x5a45, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0xfd86, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0f8b, 0xea67, 0x0000, 0x0000, 0x0000, 0x6e27, 0x0000, 0x0000, + 0x0000, 0xa886, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x71e6, 0x0000, 0x7744, 0x0000, 0x0000, 0x0000, 0x0000, + 0x33c8, 0x0000, 0x0000, 0x0000, 0x0000, 0x40a5, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x6604, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x5929, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0429, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x4a29, 0x12c5, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x4526, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0d8c, 0x0000, 0x0000, 0x0000, + 0x0000, 0x3487, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xde27, 0x0000, 0x0000, + 0x06f0, 0x3da4, 0x0000, 0x0000, 0x0a2b, 0x0000, 0x2828, 0x7a86, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x2d48, 0x0e07, + 0x0000, 0x0944, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x4e24, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x2f28, 0x0206, 0x0000, 0x0000, 0x07a8, 0x2327, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x1c0a, 0x80e7, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0669, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x1a6c, 0x26a5, 0x01ea, 0x0fa5, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x62aa, 0x15a5, 0x0000, 0x36e5, 0x0132, 0x5107, 0x0000, 0x0000, + 0x24ce, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x2ec9, 0x0104, 0x0000, 0x8967, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x47e5, 0x0000, 0x0000, 0x0000, 0x40c6, + 0x0000, 0x0000, 0x0000, 0x57c6, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0ae8, 0x0000, 0x0000, 0x0000, 0x36ca, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x3a0a, 0x0f45, 0x0000, 0x0000, 0x0000, 0xe147, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x3e6b, 0x0000, 0x0000, 0x0000, + 0x0aea, 0x3b87, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x6904, 0x236e, 0x0000, 0x0000, 0x0000, 0x0000, 0xca86, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4c2b, 0x9107, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4b05, + 0x286e, 0x2e86, 0x0000, 0x0000, 0x0000, 0x0000, 0x3aeb, 0x5a44, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x00a9, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x3baa, 0xa307, 0x0000, 0xddc6, + 0x0000, 0x0000, 0x0b09, 0x0000, 0x36c9, 0x0185, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x53ea, 0x7ca6, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4fe8, 0x02c6, + 0x0000, 0x0000, 0x61c8, 0x5525, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x7eab, 0x5304, + 0x0000, 0x75c6, 0x0000, 0xa8a6, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x2c8b, 0x0000, 0x0000, 0x0405, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x1aec, 0x2424, 0x0000, 0xf6e6, 0x0da8, 0x3846, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x5828, 0x0000, 0x0000, 0x5305, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x9ac7, 0x0000, 0x0000, + 0x27cd, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x7809, 0xea06, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0ce9, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x1dec, 0x6127, 0x0000, 0x0346, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x2eed, 0x33c4, 0x0000, 0x0227, 0x0000, 0x0000, 0x0000, 0xa8c7, + 0x0000, 0x7767, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x6eea, 0x7804, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5889, 0x58c5, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x72e6, 0x0000, 0x0000, 0x0000, 0x0000, 0x3eca, 0x2306, + 0x00f5, 0x05a5, 0x0000, 0x0000, 0x0000, 0x0000, 0x6128, 0x0000, + 0x0000, 0x0000, 0x0000, 0x3344, 0x0000, 0x8ac7, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x33cb, 0x2aa5, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x6267, 0x0000, 0x0000, 0x0000, 0x3684, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xd567, 0x4ca9, 0x2f26, + 0x0c0b, 0x0000, 0x0000, 0x0000, 0x0000, 0x3864, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x5506, 0x0000, 0x3c67, 0x728a, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x7526, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5c65, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0a53, 0x0000, 0x0000, 0x52e7, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x1012, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x87e6, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x3ee7, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0129, 0x0e24, 0x0d0a, 0x2884, 0x0000, 0x3987, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x74e4, 0x57c9, 0x3647, + 0x3ca9, 0x7ec7, 0x76aa, 0x34e4, 0x0000, 0x7087, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xfc46, 0x47cc, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x96c6, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x04d4, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x7fc6, 0x0000, 0x0000, 0x0000, 0x0000, + 0x11ee, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xfda7, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x4168, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x4e25, 0x0000, 0x0000, 0x3528, 0x04a7, + 0x0000, 0x0000, 0x0000, 0xf2e7, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x5fa4, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x44eb, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x1504, 0x0000, 0x0000, 0x7e48, 0x0000, 0x0000, 0xf946, + 0x0000, 0x0000, 0x0000, 0x0b67, 0x0000, 0x0000, 0x0000, 0x0000, + 0x428a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xeb87, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x1e0a, 0x01e6, 0x0000, 0x0000, 0x0000, 0x9966, 0x0000, 0xbfc6, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x310b, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x51e7, 0x4649, 0x3167, 0x0000, 0x0000, + 0x0000, 0x3ea4, 0x7f68, 0x0000, 0x0000, 0x0000, 0x0000, 0x3fa6, + 0x216b, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x8966, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x768a, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x39cd, 0x0e44, 0x0000, 0x0000, + 0x204c, 0x3286, 0x0000, 0xd6a6, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0a48, 0x84a7, 0x0000, 0x5a87, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x8da6, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x7fac, 0x6926, 0x0000, 0x7fa4, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3d09, 0x2ea7, + 0x04b6, 0x0000, 0x0000, 0x0000, 0x0000, 0x4684, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x4026, 0x0000, 0x0000, 0x0000, 0x6724, + 0x0000, 0x0000, 0x7069, 0x0000, 0x0000, 0x6146, 0x0000, 0x0000, + 0x0198, 0xb127, 0x0000, 0x8b87, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0e4a, 0x4426, 0x0000, 0x00a5, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x1807, 0x0000, 0x0000, + 0x5f68, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x5e6a, 0x5ee5, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x2e47, 0x0000, 0x9aa7, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x254d, 0x0ae4, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x03f2, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x65c7, 0x7bec, 0x0000, 0x5ea9, 0x0724, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4384, + 0x0000, 0x0000, 0x0000, 0x0000, 0x4c08, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x7ec4, 0x0000, 0x0000, + 0x0000, 0x70c7, 0x0000, 0x0000, 0x0000, 0x0000, 0x4528, 0xd087, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x45e4, 0x0792, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x3fea, 0x0000, 0x0000, 0x5465, 0x0000, 0x0000, 0x138b, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x58a5, 0x0000, 0x5746, + 0x0000, 0x0000, 0x0000, 0xda26, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5945, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x19c8, 0x0107, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6104, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x9f07, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x8466, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x32c8, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x7664, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x150a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6cc4, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x454c, 0x0000, + 0x0000, 0x0000, 0x0000, 0x6205, 0x7188, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x3188, 0x2cc6, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0054, 0x1c87, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x69a4, 0x01c9, 0x0000, 0x598c, 0xe386, + 0x4a48, 0x0000, 0x0a2e, 0xb287, 0x0000, 0x1425, 0x0000, 0x61c4, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0811, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x7cca, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x8266, + 0x0000, 0xbb06, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x61ac, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x6629, 0x8b46, 0x0000, 0xe2c7, 0x77cc, 0x0000, + 0x0000, 0x0000, 0x0000, 0x6584, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x1168, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x1d88, 0x5067, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x9286, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xa746, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x06c5, 0x0000, 0x0000, 0x0000, 0x2004, + 0x0000, 0x0000, 0x2be9, 0x0000, 0x776c, 0xeba6, 0x0000, 0x3aa5, + 0x0000, 0x0000, 0x0000, 0x9ec6, 0x0000, 0x5d04, 0x0000, 0x2726, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x324a, 0x7927, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0648, 0x0000, 0x0000, 0x0000, 0x0000, 0x4784, 0x0000, 0x0000, + 0x0000, 0x0000, 0x69ea, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x1f08, 0x0566, 0x0000, 0x2e25, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x5fc5, 0x0000, 0x2d65, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x54c6, 0x0000, 0x0000, 0x332c, 0x2046, 0x0a54, 0x1f25, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0409, 0x3125, 0x0000, 0x6285, + 0x0000, 0x0000, 0x0000, 0xa026, 0x3fad, 0xf607, 0x0000, 0x0000, + 0x0000, 0x0000, 0x04ef, 0x2466, 0x0000, 0x0000, 0x0000, 0x49a6, + 0x0000, 0x0000, 0x06cd, 0x8467, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x6709, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x7da5, 0x0000, 0xc7c7, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x72e4, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x068a, 0x1086, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x2906, 0x0000, 0x0000, + 0x0000, 0x0000, 0x15a9, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0833, 0xb066, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x374d, 0x0000, 0x694b, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x42c8, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x69aa, 0x1a46, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x6f8a, 0x0000, 0x0000, 0x1be6, 0x0000, 0x0000, 0x0000, 0x0000, + 0x4228, 0x0000, 0x0000, 0x0000, 0x64e9, 0x0000, 0x112f, 0x1b44, + 0x0000, 0xb486, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x2986, + 0x52ac, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x098e, 0xbda7, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3445, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3c28, 0x2f67, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x12a6, 0x024a, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5cc7, + 0x2608, 0x11c4, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x63e9, 0x73a7, 0x186a, 0x0665, 0x0000, 0x0000, 0x0000, 0x0000, + 0x5608, 0x0000, 0x0000, 0x0000, 0x0000, 0x5724, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x9226, 0x5dec, 0x0000, + 0x0000, 0x0000, 0x388a, 0x7427, 0x0000, 0x1ba5, 0x0000, 0xb3a6, + 0x0000, 0x0000, 0x0000, 0x0000, 0x7768, 0x9c67, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x1806, 0x0000, 0x1084, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x6c27, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x5fe4, 0x5409, 0x0546, 0x0000, 0x0000, + 0x0000, 0x8347, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x2e08, 0x0586, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x4744, 0x03ac, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x1c66, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x4145, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0xbf27, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x5c6c, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0xd066, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x108c, 0x3fe6, 0x0000, 0x1146, 0x1a09, 0x7f84, 0x0000, 0x0000, + 0x02e8, 0x46a4, 0x0000, 0x2b06, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x7344, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x1e06, 0x0000, 0x0000, 0x33e9, 0x1566, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x3248, 0x0000, 0x0000, 0x5e46, 0x03ed, 0x5984, 0x0000, 0x7ac5, + 0x5b68, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x6f08, 0x0000, 0x0000, 0x0000, 0x646a, 0x69e5, 0x0000, 0x0000, + 0x66e9, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6226, + 0x0000, 0x0000, 0x0058, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x4288, 0x0000, 0x0000, 0x5527, 0x0000, 0x0000, + 0x274c, 0x0000, 0x3008, 0x5584, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5129, 0x37e7, + 0x0000, 0xe346, 0x7de8, 0x0000, 0x282a, 0x0000, 0x0849, 0x2d07, + 0x0000, 0x0000, 0x0000, 0x3025, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x7084, 0x0928, 0x1fc5, 0x0000, 0x0000, + 0x0000, 0x0000, 0x5568, 0xf4e7, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0ad3, 0x0000, 0x0000, 0x5aa4, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x1886, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x67e5, + 0x0000, 0x0000, 0x0000, 0x0000, 0x5a68, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x7c48, 0x4e66, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5f88, 0x0846, + 0x0000, 0x0000, 0x0000, 0x0000, 0x19aa, 0x0484, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x76c6, 0x0000, 0x0000, + 0x0000, 0x6ee4, 0x0df4, 0x0000, 0x0000, 0x67e7, 0x308a, 0x14a6, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x1367, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x618a, 0x5e67, 0x0000, 0x0000, + 0x0000, 0x0000, 0x7049, 0x1246, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x05a4, 0x00ec, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4be4, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x082c, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0b0b, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x4da9, 0x4b04, 0x0000, 0x2de5, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4626, + 0x0000, 0x45e6, 0x0000, 0x4926, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x23e6, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5406, + 0x13a9, 0x0000, 0x0000, 0x0000, 0x0000, 0x5947, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x3906, 0x0000, 0x73a5, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0269, 0x0000, + 0x0000, 0x0000, 0x0000, 0xb826, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0e2b, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x08b1, 0x39e7, 0x0000, 0x0000, + 0x0a4d, 0x1826, 0x004e, 0x3ae6, 0x0000, 0x0000, 0x0000, 0x0000, + 0x4f28, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x8f87, + 0x102c, 0xae07, 0x43c8, 0x6467, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x36c8, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6d64, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x1da4, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0827, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x466c, 0x0000, 0x0000, 0x0000, 0x012c, 0x3784, 0x0000, 0x0000, + 0x056a, 0x9d87, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x796a, 0x0000, 0x0000, 0x5766, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x8b86, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x67a4, + 0x1e4c, 0x0000, 0x0000, 0x4a26, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x1928, 0x0487, 0x1c0c, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xb2c6, 0x0000, 0xe1c6, + 0x0000, 0x4164, 0x0000, 0x0000, 0x1a92, 0xec26, 0x0000, 0x0000, + 0x0000, 0x6766, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xff66, + 0x110a, 0x1e46, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x2388, 0x1287, 0x014e, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x9c26, 0x0000, 0x0000, 0x0000, 0x64e4, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0bd3, 0x0000, 0x0000, 0x0000, 0x3dc8, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xbcc7, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x3f28, 0xa347, 0x0000, 0x0000, 0x5f8a, 0x2185, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x3004, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xd4e7, 0x0000, 0x0000, + 0x0000, 0x0000, 0x13e9, 0x7884, 0x48e8, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x4064, 0x0000, 0x0000, 0x6ac9, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x8c66, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x1104, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0xdec6, 0x0000, 0x0000, 0x0589, 0xa0e7, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x5b85, 0x0000, 0x0000, 0x0000, 0x0000, + 0x2728, 0x54e7, 0x0000, 0x0000, 0x278e, 0x0000, 0x0000, 0x0000, + 0x0000, 0x4a66, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x5e29, 0x1266, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x112a, 0x0000, 0x0000, 0x0000, + 0x0000, 0x33c5, 0x0000, 0xdc47, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4ae6, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0xdaa6, 0x0000, 0x0000, 0x0000, 0xcb66, 0x0000, 0x3d04, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0a64, 0x0000, 0x0000, + 0x0000, 0x0000, 0x548c, 0x0000, 0x0000, 0xcce7, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x22c6, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0c2c, 0x0000, + 0x01d0, 0x87a6, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x61ab, 0x3087, 0x0000, 0x6a24, 0x0768, 0x1ca7, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x8b66, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0d90, 0x0000, 0x0000, 0x0000, 0x0000, 0x5786, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xb0c6, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5284, 0x5c2a, 0x8167, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x412c, 0x5647, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x220a, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xda06, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x100d, 0x5ba4, + 0x0000, 0x0000, 0x22aa, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0093, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x7508, 0xf7a6, 0x0516, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x60e6, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x2647, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x7a65, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4c65, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x1645, 0x0000, 0x0000, 0x0000, 0xf626, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5306, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x30c4, + 0x0000, 0x0000, 0x0000, 0xbcc6, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3da7, + 0x0000, 0x0000, 0x04b2, 0x0000, 0x0000, 0x0000, 0x0000, 0x5a86, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0c0e, 0xc027, + 0x0000, 0x0000, 0x150b, 0x3b25, 0x0000, 0x0000, 0x0000, 0x0d25, + 0x0000, 0x0000, 0x0000, 0x0000, 0x4e6c, 0x36c5, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0178, 0x9d06, 0x0000, 0x0000, 0x0000, 0xcb47, 0x0000, 0x6164, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0328, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x2684, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x5ca7, 0x0000, 0x53e4, 0x0000, 0x0000, 0x0000, 0x0000, + 0x5128, 0x12c7, 0x0000, 0x0000, 0x0c69, 0x4126, 0x0000, 0x0000, + 0x006e, 0x2a65, 0x0000, 0x0000, 0x0000, 0x43e6, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xa9c6, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x1d4c, 0x1366, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xcb86, + 0x0000, 0x5fc4, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x67a7, + 0x0000, 0x0000, 0x0000, 0xb4a7, 0x0000, 0x0000, 0x0000, 0x3cc5, + 0x0000, 0x0000, 0x0000, 0x0000, 0x004c, 0xcc67, 0x0000, 0x0000, + 0x0000, 0x0000, 0x45ca, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xb6a6, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x4ae5, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xac06, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0ba9, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x37e6, + 0x0000, 0x0000, 0x084d, 0xb307, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x266e, 0x0000, 0x33ab, 0x4c24, 0x0000, 0x0000, + 0x0000, 0x7444, 0x0000, 0x0000, 0x0000, 0x0000, 0x02ae, 0x7565, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x7845, 0x008b, 0x5165, + 0x0000, 0x0000, 0x0000, 0x0000, 0x01f6, 0x4865, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x4aa7, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x7aa4, 0x0000, 0x0000, 0x0000, 0x4424, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xc2c6, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x640a, 0x0226, 0x0000, 0x0000, + 0x0231, 0x0000, 0x716a, 0x0000, 0x0000, 0x0000, 0x0dc8, 0x0000, + 0x0000, 0x0000, 0x06b3, 0x3945, 0x0012, 0xf7e7, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x376a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x738a, 0xe686, 0x0000, 0x9a06, + 0x0000, 0x0000, 0x0000, 0x0000, 0x08ca, 0x40e4, 0x0000, 0x7c24, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x01ce, 0x4247, + 0x0000, 0x7165, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5ba6, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x06e8, 0x0000, 0x1789, 0x4266, 0x070c, 0x0000, 0x0000, 0xd3a6, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x372c, 0x0000, 0x180a, 0x7406, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x1e24, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xbea7, 0x0000, 0x2064, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x4005, 0x172d, 0x0000, 0x3a09, 0xc867, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x8b27, 0x2389, 0x5a07, 0x0000, 0x0000, + 0x5a48, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x01b6, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0097, 0x2426, + 0x056e, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xd3c7, + 0x0000, 0x0000, 0x0000, 0x0000, 0x182b, 0x0000, 0x0000, 0x0000, + 0x0000, 0x3327, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x268a, 0x0000, + 0x0000, 0xe8e6, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x62c6, 0x0000, 0x0000, 0x5d28, 0x7d45, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x2427, 0x088b, 0x3ba6, 0x01b5, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4c25, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x2de4, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4206, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x56c4, 0x0749, 0x4487, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x55ec, 0x0000, 0x0000, 0x0000, 0x0000, 0xdaa7, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x7d8a, 0x52a4, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x37a9, 0x0000, 0x0000, 0x0000, 0x0954, 0x0000, 0x0000, 0x0000, + 0x0000, 0x1aa7, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6846, + 0x0000, 0x0000, 0x17ab, 0xd107, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0xc186, 0x180f, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x040c, 0x5de4, 0x0000, 0x09c5, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x440b, 0xc847, 0x0d31, 0x3b26, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x138f, 0xf3a6, + 0x0000, 0xde67, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5f66, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x03ae, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x6e67, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x3d06, 0x0000, 0x4d25, 0x0000, 0x0000, 0x064b, 0x0000, + 0x56cb, 0xbdc7, 0x6229, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4444, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x02d1, 0x0000, 0x0000, 0x0000, 0x0000, 0x7f06, + 0x0000, 0x0000, 0x0000, 0x4825, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x1708, 0x74e7, 0x0e49, 0x5a06, 0x0000, 0x0000, + 0x0c8e, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0070, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0be8, 0x01c7, 0x0000, 0x7924, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x5ae6, 0x0000, 0x7fa5, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x94c6, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x1324, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x63c5, 0x0000, 0x4964, 0x0000, 0x0000, + 0x56e8, 0x0547, 0x0000, 0xf126, 0x11ac, 0x77a5, 0x0000, 0x3a27, + 0x00f2, 0x7187, 0x0000, 0x0000, 0x3848, 0x1285, 0x0000, 0x0000, + 0x0000, 0x91c6, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x1faa, 0x0000, + 0x7d6b, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x05c9, 0x0000, 0x0000, 0x6de4, + 0x0000, 0x64c6, 0x0000, 0xe987, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0xe6c6, 0x0000, 0x0000, 0x0000, 0x5b46, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x78a7, 0x0000, 0x0000, + 0x0000, 0x0000, 0x3f48, 0x0000, 0x0000, 0x0000, 0x014f, 0x0000, + 0x0000, 0x0000, 0x02ca, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x780a, 0x2506, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4966, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0297, 0x0000, 0x0000, 0x0000, 0x040a, 0x7ac7, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x75a8, 0x0000, 0x0000, 0x0000, 0x0000, 0x3665, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x08e8, 0x3466, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x560c, 0x5c87, + 0x0bc9, 0x2b27, 0x0000, 0x0000, 0x54ea, 0x48c6, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x7626, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x4369, 0x0000, 0x5588, 0xf927, 0x0000, 0x0000, + 0x0000, 0x5266, 0x0000, 0x48e6, 0x0000, 0x6464, 0x0000, 0x5805, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x18c5, 0x16a8, 0x2b67, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x3c27, 0x32aa, 0x1965, 0x0000, 0x0000, + 0x0c6b, 0x6746, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x3d86, 0x0000, 0x3306, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x008e, 0x0000, + 0x0000, 0x0000, 0x0000, 0x5324, 0x2ba9, 0x1127, 0x0000, 0x0000, + 0x0000, 0x0000, 0x4c8b, 0x9ec7, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x2e65, 0x0000, 0x0000, 0x0000, 0x6747, 0x0000, 0x0000, + 0x0000, 0x0000, 0x02b7, 0xbfe6, 0x6b4b, 0x2ec4, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x26e9, 0x0000, 0x0000, 0x0000, + 0x7bea, 0xf606, 0x0000, 0x0000, 0x0000, 0x0000, 0x3dc9, 0xcde6, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x6026, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x5046, 0x0000, 0x0000, 0x13aa, 0x0f66, 0x0000, 0x0000, + 0x0000, 0xb367, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x09f4, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0xb226, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0d4d, 0x3126, 0x3ccb, 0xd347, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x5e8a, 0x1705, 0x0000, 0x0000, 0x0000, 0xacc6, + 0x0000, 0x0000, 0x0000, 0x15e5, 0x0000, 0xbaa6, 0x0000, 0x7de6, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x1b66, 0x0000, 0x0000, 0x0000, 0x0000, + 0x4068, 0x0c67, 0x0000, 0x6a65, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x9fc6, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x7d04, 0x7aca, 0x0000, 0x5f48, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x71ca, 0xe366, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x714a, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0xd846, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x9426, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x050a, 0x0000, + 0x0000, 0x0000, 0x1269, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x514c, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x070b, 0x03c6, 0x0000, 0x4524, 0x0000, 0x0000, 0x028e, 0x4aa5, + 0x0000, 0xc9c7, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x28e6, + 0x0630, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x09ca, 0x0000, 0x0000, 0x6247, 0x10cf, 0x0000, 0x0000, 0x0000, + 0x018b, 0x3e07, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0548, 0x1987, 0x0000, 0x4cc4, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x1272, 0x1ee5, + 0x0000, 0x0000, 0x0000, 0x0000, 0x75c8, 0x0000, 0x0000, 0xfce6, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0869, 0x23a5, + 0x0000, 0x0000, 0x0117, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xa3a6, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0530, 0x4286, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xd387, + 0x0000, 0x0000, 0x0000, 0x0000, 0x06ef, 0xd507, 0x0000, 0x0000, + 0x0000, 0x0000, 0x7b88, 0x0000, 0x0000, 0x0000, 0x1bee, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0730, 0x8c67, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xdc87, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xfbe6, + 0x0000, 0x0000, 0x0000, 0xc7e6, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x1026, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x42c4, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x000c, 0x3f06, 0x4dab, 0x9c07, 0x2829, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0xaea7, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x372d, 0x0967, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x6929, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x56ac, 0x0000, + 0x514a, 0x2745, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x7224, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6e0a, 0x0000, + 0x3b68, 0x0000, 0x0000, 0x7f05, 0x1668, 0x4b47, 0x0dea, 0x2926, + 0x0000, 0x0000, 0x0000, 0xe907, 0x0000, 0x0000, 0x0000, 0x0000, + 0x69cc, 0xec06, 0x0000, 0x0000, 0x6189, 0x0000, 0x0000, 0x0000, + 0x0a4c, 0x0000, 0x0000, 0x0000, 0x0000, 0x66a5, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x7784, 0x0e0a, 0x0000, 0x0000, 0x0000, 0x20aa, 0x38e5, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x2a29, 0x3026, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x1712, 0xe926, + 0x0000, 0x0000, 0x5a29, 0x0205, 0x0000, 0x3cc4, 0x0000, 0x0000, + 0x0000, 0x2126, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4da5, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x1d49, 0x0000, + 0x0000, 0x65e5, 0x0000, 0x0000, 0x5ce8, 0xf867, 0x19a8, 0x18a6, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x2746, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x1b6a, 0x3886, 0x49aa, 0x0000, 0x1609, 0x29a4, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x8ac6, 0x05eb, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x6c08, 0x0000, 0x0000, 0x2586, 0x0000, 0x9aa6, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0xd2a6, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x00e8, 0x10e7, 0x3169, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x4ee7, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x686a, 0x0000, 0x0000, 0x0000, 0x4bc8, 0x3967, 0x0000, 0x7a66, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4c85, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x13c8, 0x2e84, + 0x0000, 0x6ac5, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0xba87, 0x0000, 0x0000, 0x0000, 0x6826, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xd967, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x1865, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x5b48, 0xf9a7, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x07b6, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x2148, 0x5de5, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x66a7, + 0x0000, 0x0000, 0x0000, 0x5966, 0x0000, 0x0000, 0x0000, 0x6c86, + 0x0000, 0x77e6, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x83a7, 0x0000, 0x0000, + 0x0000, 0x76c5, 0x0000, 0x8726, 0x0000, 0xc767, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0774, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x05e7, 0x5589, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xc8c6, 0x0000, 0x6126, + 0x0000, 0x7f87, 0x0000, 0x0000, 0x0000, 0x88c7, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x2bc4, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x1e4e, 0xe287, 0x0000, 0x0000, + 0x0000, 0x78e5, 0x0000, 0x0000, 0x0016, 0x3b24, 0x23ca, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x63c4, 0x4ea8, 0x1bc4, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x402b, 0x2a25, 0x264d, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x1248, 0x0000, + 0x0000, 0xcdc7, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3a24, + 0x0000, 0x0000, 0x0000, 0x41a4, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x256a, 0x14a7, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x8506, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x4a84, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x1dcb, 0xd9a7, 0x0000, 0x9a27, 0x386e, 0xe406, 0x0000, 0x0000, + 0x0000, 0x0000, 0x5ba9, 0x3de5, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x9686, 0x0000, 0x0000, 0x0000, 0x45e5, 0x2aaa, 0x0000, + 0x1c08, 0x02a6, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0c29, 0xb4c7, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x5b26, 0x0000, 0x0000, 0x46a8, 0x5ae4, + 0x0000, 0xf386, 0x0000, 0x0000, 0x0000, 0x40e5, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x9526, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x62cc, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x2868, 0x0047, 0x192e, 0x0000, 0x0000, 0x0765, 0x0000, 0x0000, + 0x0452, 0x0000, 0x7008, 0x7824, 0x0000, 0xa0a6, 0x0000, 0x0000, + 0x05d4, 0x0000, 0x3bed, 0x0000, 0x0000, 0x0000, 0x0000, 0x44a7, + 0x0000, 0x52e4, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x61e4, + 0x0828, 0x5544, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0166, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4144, 0x0000, 0x0000, + 0x0000, 0x0684, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x2fe4, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0fee, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x31a9, 0x1847, + 0x0000, 0x0000, 0x4f69, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x79e4, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0e94, 0x0000, 0x066e, 0x0000, 0x0000, 0x6b44, 0x0000, 0x8666, + 0x42e8, 0x3805, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4c47, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x17e8, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x2167, + 0x542a, 0x27e4, 0x0bcc, 0x0b87, 0x0000, 0x44e6, 0x0000, 0x0000, + 0x1b49, 0xafc7, 0x08aa, 0x2005, 0x0000, 0x0000, 0x7708, 0xf786, + 0x0000, 0x6824, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x04f1, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0a32, 0x0000, + 0x0000, 0x0000, 0x2c0e, 0x4f47, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x4d44, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0931, 0x2a64, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x152d, 0x5ee4, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x8667, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3c48, 0x5126, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x3048, 0x2a05, 0x0000, 0x0000, 0x0000, 0x8166, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x7385, 0x0000, 0x0927, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0xf667, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0xa807, 0x0000, 0x3ea6, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x05c8, 0x63e5, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x2287, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6045, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x13c7, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0xb306, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0337, 0x0000, + 0x0000, 0xfa27, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3bc4, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0b6c, 0xb6a7, + 0x1a68, 0x4b44, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x8586, 0x0000, 0x0000, 0x0f89, 0x46e5, + 0x0000, 0x0000, 0x0000, 0x7dc7, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5be4, 0x658a, 0x0000, + 0x0000, 0x2867, 0x0000, 0x0000, 0x0000, 0x2605, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x1284, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x4165, 0x0000, 0x0000, 0x1212, 0x5b47, 0x0000, 0x0000, + 0x7aa8, 0x0000, 0x0000, 0x0de5, 0x0000, 0x0000, 0x108a, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6f46, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x3785, 0x0000, 0xdf67, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x00f0, 0x0000, 0x0000, 0x0000, 0x0000, 0xff26, 0x7488, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x7525, 0x0000, 0x7c66, 0x0000, 0x0000, 0x1fea, 0x0000, + 0x0000, 0x1145, 0x6bea, 0x78a4, 0x0000, 0x0000, 0x4eec, 0x0000, + 0x0000, 0x0000, 0x0000, 0xae46, 0x0216, 0x5184, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x7026, 0x0000, 0x2825, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x7347, 0x0000, 0x4d65, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x698c, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0xcf66, 0x0000, 0x8987, 0x0000, 0x0000, 0x0000, 0x92a6, + 0x0000, 0xf146, 0x2188, 0x1f65, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x30c8, 0x58e5, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5d06, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4e05, + 0x0000, 0x0000, 0x0000, 0xf9c7, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x8ca6, + 0x0000, 0x0000, 0x0000, 0x4a44, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x2184, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4665, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0050, 0x04e6, 0x0000, 0x0000, 0x0000, 0xa686, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3f86, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x084c, 0x6387, + 0x0000, 0x0000, 0x0000, 0x0000, 0x41e9, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0c46, 0x0000, 0x0000, 0x480b, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0f4d, 0x0000, 0x2289, 0x04a6, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x50a5, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x2444, 0x0000, 0x0000, 0x5f4a, 0xa187, 0x0000, 0x0000, + 0x0000, 0xa467, 0x0000, 0xf466, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x1a48, 0x1067, + 0x0000, 0x0000, 0x0000, 0x0000, 0x63ab, 0x0000, 0x04cf, 0x0000, + 0x0176, 0x3d07, 0x0000, 0x7504, 0x0000, 0x3726, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x4a67, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x7be6, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x51a4, + 0x0000, 0x4167, 0x0000, 0x0000, 0x0000, 0x70e6, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0a12, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x360e, 0x0000, 0x0000, 0x2744, + 0x0000, 0x0000, 0x0000, 0x0000, 0x1d08, 0xab07, 0x42c9, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0369, 0x0000, 0x0000, 0x0000, + 0x018e, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x210b, 0x5c07, 0x0000, 0xcf26, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x8ba6, 0x0000, 0x0fe7, + 0x0000, 0x0000, 0x0000, 0x9706, 0x0000, 0xa1c6, 0x0000, 0x0000, + 0x0000, 0x0000, 0x2d88, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0fab, 0xa6c7, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x6309, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x6a29, 0x5764, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x7904, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0xb4c6, 0x0f88, 0x31a7, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5025, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0fe8, 0x2b46, 0x0000, 0x0000, + 0x40a9, 0x0965, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0a6e, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x80e6, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0xb7c6, 0x0000, 0x7745, 0x0000, 0x0000, 0x2b2a, 0x2606, + 0x3349, 0x0000, 0x0000, 0x0000, 0x0000, 0x5bc6, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0xe3c6, 0x0000, 0x0000, 0x0000, 0xe0c7, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x01c6, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x142b, 0xe927, 0x08ac, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x7346, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x43a4, 0x0000, 0x4e65, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x14c7, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6a26, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x59a5, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4b08, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x51c5, 0x0000, 0x0000, + 0x178a, 0x2226, 0x0000, 0x0000, 0x0000, 0x43e4, 0x0000, 0x3347, + 0x0aed, 0x0000, 0x0000, 0x75a4, 0x0000, 0x0000, 0x174b, 0x1f44, + 0x0000, 0xdf26, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xa766, + 0x39c8, 0x7827, 0x0000, 0x6184, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4225, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x3b48, 0x9f87, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0314, 0x7685, 0x0000, 0x0000, + 0x0000, 0x0000, 0x522c, 0x5e26, 0x0000, 0x0000, 0x0000, 0x0000, + 0x75ab, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x5845, 0x7b2b, 0x68a5, 0x0000, 0xe8a7, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x2488, 0x74a7, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x5fe7, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x5024, 0x0000, 0x0000, 0x0000, 0x9a26, 0x0e51, 0x0000, + 0x6e69, 0x0000, 0x224a, 0xfb06, 0x0000, 0xe046, 0x23ac, 0x0000, + 0x0000, 0x4764, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x66e8, 0x7805, 0x020c, 0x4d27, + 0x0000, 0x35e4, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x46eb, 0x0000, 0x3229, 0x0000, + 0x004a, 0x61a6, 0x350b, 0x0425, 0x0000, 0xfac7, 0x0000, 0x0000, + 0x2248, 0x0000, 0x0000, 0xeb47, 0x0000, 0x6344, 0x0000, 0x0000, + 0x0000, 0xe707, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x3808, 0x05e6, 0x0000, 0x0000, 0x0000, 0x95e6, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3429, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x24e6, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x7f65, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4d84, + 0x0000, 0x0000, 0x0000, 0x0000, 0x3a0b, 0x0000, 0x0000, 0x0000, + 0x0000, 0x1a06, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x374a, 0x0000, 0x744a, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x4088, 0x0886, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x8d06, 0x0d0c, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x6265, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x3d68, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x58e6, 0x0000, 0x0000, 0x0130, 0x0000, + 0x0cab, 0x3725, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x140a, 0x3187, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x54e5, 0x28c9, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x8d07, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5c26, 0x0000, 0xe087, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x2a48, 0x47c4, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x8906, 0x3d6a, 0x32a7, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x8727, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0xd187, 0x0000, 0x96e6, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x7929, 0x2c45, 0x0000, 0x0000, 0x0000, 0x0000, + 0x4ac8, 0x0000, 0x2529, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0xdd87, 0x5dea, 0x0000, 0x04ad, 0x0000, + 0x0000, 0xe486, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x2026, 0x17e9, 0x48c4, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x62ca, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x05ea, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x382a, 0x2646, 0x7e6b, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x2569, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x68a4, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x014a, 0x2925, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xa506, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x13d2, 0x5224, + 0x0000, 0x94e7, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x00f8, 0x0000, 0x79c8, 0xf266, 0x0000, 0xd027, 0x0000, 0x0000, + 0x0000, 0x0000, 0x010f, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x2408, 0x0845, 0x0000, 0x0000, 0x0000, 0x0000, 0x3dca, 0x15e7, + 0x0000, 0xcd66, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x4748, 0x5dc5, 0x59ea, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x01ab, 0x0000, 0x0000, 0x9be6, 0x0000, 0x0000, + 0x1ba8, 0x2c87, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x56cc, 0xe226, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3364, 0x0000, 0x0585, + 0x03ef, 0x0000, 0x0000, 0x0000, 0x0000, 0x53a7, 0x0000, 0x5427, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0xa2e6, 0x580a, 0x2565, 0x0000, 0x0000, 0x0000, 0x2266, + 0x0000, 0x0000, 0x1b08, 0xdc27, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xa4e7, + 0x0000, 0x0000, 0x358c, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4045, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x062e, 0x06e4, 0x0cd2, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x2d85, 0x0000, 0x0000, + 0x0000, 0x0000, 0x2f6b, 0x0000, 0x732a, 0x7964, 0x0689, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x9d46, 0x0000, 0x0000, + 0x0000, 0x8446, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5204, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x1207, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0xaba7, 0x014d, 0x4ba7, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x68c5, 0x0000, 0x7e85, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x1348, 0x2da7, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x2a85, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6546, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x3deb, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x20a8, 0x0000, + 0x42ea, 0x1f06, 0x0000, 0x2cc4, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x46e6, 0x37a8, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x5726, 0x0000, 0x0000, 0x0000, 0xa706, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x72aa, 0x15c6, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x7985, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x2be4, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x23c4, 0x0000, 0x0000, 0x0709, 0x36c7, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xf3c6, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5c44, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x792a, 0xffe6, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x6646, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x6c45, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0xb766, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x7984, + 0x0000, 0x2c66, 0x0000, 0x0000, 0x0000, 0x0e85, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x2168, 0x17a6, 0x0d0b, 0x0000, + 0x0000, 0x0000, 0x0000, 0xc9a6, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0e86, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x6ec6, 0x0000, 0x0ac4, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x05b6, 0x0000, 0x0000, 0x6be6, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0xf426, 0x384a, 0xdda7, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x2fae, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x8ec6, 0x0000, 0x94a6, 0x0000, 0x0000, 0x0000, 0x52e5, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x69c5, + 0x0000, 0x0000, 0x420a, 0x0000, 0x312b, 0x2f45, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x28ae, 0x7067, 0x5509, 0xeb07, + 0x0000, 0xdd46, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5104, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x172b, 0x14e7, + 0x0000, 0xffc6, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x1f29, 0xcda7, 0x0000, 0x1304, 0x0000, 0x0000, 0x0000, 0xd8a7, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x7dc5, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x3485, 0x0000, 0x0000, 0x0000, 0x6807, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x2be5, 0x0000, 0x0000, + 0x0000, 0x0000, 0x00d1, 0x0505, 0x0000, 0x0000, 0x0788, 0x0000, + 0x0000, 0x0000, 0x0000, 0xa946, 0x5d29, 0x5a84, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6088, 0xf3e7, + 0x226b, 0x0d87, 0x4fe9, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x3e88, 0xdbc7, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0xebc6, 0x58e9, 0x19a5, 0x0000, 0x0000, 0x78a8, 0x6c26, + 0x0000, 0x0000, 0x0000, 0x42c5, 0x0000, 0x0000, 0x0000, 0x0000, + 0x5669, 0x0000, 0x0000, 0x0000, 0x1da9, 0x3766, 0x0000, 0x6dc7, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xb046, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x7c64, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x4844, 0x0000, 0x0000, 0x0000, 0x0000, 0x6e2a, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x66c4, + 0x0000, 0x7365, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x7384, 0x0000, 0x0000, + 0x0000, 0x5325, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xeda7, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x76c7, 0x3e4d, 0x0ba5, + 0x0000, 0x0000, 0x0000, 0xb567, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x5d67, 0x6789, 0x6286, 0x320b, 0x1707, 0x0000, 0x18c7, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x7c47, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x4ce8, 0x2805, 0x0000, 0x0000, + 0x0000, 0x7a45, 0x6969, 0x7124, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x6a48, 0x79c4, 0x0000, 0x0000, + 0x0000, 0x0000, 0x00d8, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x3fa4, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x2227, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x1926, 0x0000, 0x0000, + 0x0000, 0x8227, 0x0000, 0x0000, 0x0000, 0x8206, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x56a5, + 0x1d4b, 0x60c6, 0x0000, 0x2a04, 0x0000, 0xaee7, 0x02d4, 0x0000, + 0x64a8, 0x6445, 0x6129, 0x14e5, 0x62a9, 0x0000, 0x0000, 0xd526, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0147, 0x01b7, 0x0165, 0x0000, 0x0000, + 0x1988, 0x2104, 0x0000, 0x0000, 0x070a, 0x0000, 0x0000, 0xefa6, + 0x0000, 0x3ac5, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x95c7, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x7eeb, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5965, + 0x0000, 0x0000, 0x7d49, 0x0000, 0x0000, 0x0000, 0x254a, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6c64, + 0x0000, 0x0000, 0x5a88, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6007, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x8546, 0x0000, 0x0000, + 0x0000, 0x0000, 0x086e, 0x0000, 0x15d2, 0x7684, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x5f84, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0969, 0x1126, 0x0000, 0x5e84, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x7e08, 0x6944, 0x506b, 0x0000, 0x0000, 0x0000, + 0x086b, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x10e8, 0x66a4, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5c0c, 0x0000, + 0x30aa, 0x2c67, 0x0000, 0x0000, 0x624a, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0xff86, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x80c6, 0x0000, 0x0000, 0x0000, 0x8766, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x9946, 0x0000, 0x0000, 0x0000, 0x0000, + 0x2c88, 0x27e6, 0x010a, 0x30a4, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3b45, + 0x0000, 0x0000, 0x0000, 0x3564, 0x0000, 0x33a6, 0x0000, 0x5b44, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x2ea5, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x63e7, + 0x0000, 0x0000, 0x0000, 0xe027, 0x0000, 0x0000, 0x0000, 0x2844, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0b31, 0x2447, 0x004b, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x5404, 0x576c, 0xe886, 0x0000, 0x0000, 0x0000, 0x5c25, + 0x0000, 0x0000, 0x0000, 0xc986, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x1225, + 0x0f8c, 0x6e87, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3064, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x54e6, 0x0000, 0x44c7, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xa327, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4804, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x55c6, 0x0000, 0x4be6, + 0x0000, 0x0000, 0x04b4, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0ca8, 0xd7c7, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x77c4, 0x0000, 0x0000, 0x0000, 0x70e5, + 0x0000, 0x0000, 0x0000, 0x0000, 0x126c, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x2dea, 0x0000, 0x0000, 0x0000, 0x0000, 0x5646, 0x0000, 0x5824, + 0x222d, 0x0000, 0x0000, 0x6ee7, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0b46, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x7186, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x9da6, + 0x0000, 0x0000, 0x3e2c, 0x9a66, 0x0000, 0x35a7, 0x0000, 0x0000, + 0x0000, 0x0000, 0x710a, 0x0000, 0x0197, 0x0fa6, 0x0000, 0x0000, + 0x0000, 0x6924, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6b86, + 0x7648, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x600a, 0x0000, 0x6049, 0x1406, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x21ec, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x59eb, 0x0000, 0x5769, 0x48a7, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6bc9, 0x2607, + 0x0000, 0x4ee4, 0x0000, 0x0000, 0x0000, 0x0000, 0x6e08, 0xbd27, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x7aa7, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3644, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x44c6, 0x0000, 0x0000, 0x3b8a, 0x7447, + 0x670a, 0x4525, 0x0000, 0x0000, 0x3888, 0x0000, 0x12e8, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6084, 0x0000, 0x2485, + 0x10ea, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x3f09, 0x0000, 0x0000, 0x8826, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x61e7, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x19cb, 0x3127, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x1d09, 0x7204, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x7a26, + 0x0000, 0x0000, 0x5988, 0x0c47, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x5ba5, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x026a, 0x0000, 0x0000, 0x0000, 0x0000, 0x5385, + 0x0000, 0x2d04, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x520c, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0138, 0x5ac7, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0909, 0x0000, + 0x0000, 0x9ea6, 0x0000, 0x0000, 0x39e9, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0xb5c7, 0x0000, 0xa0e6, 0x1ead, 0x0000, + 0x7ba8, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0d69, 0x1487, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x84a6, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0048, 0x3c85, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x8ce6, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x3984, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x7484, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4986, + 0x4e28, 0x0000, 0x0000, 0x0000, 0x0000, 0x0986, 0x0b88, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0d0e, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x5f64, 0x0000, 0x4dc4, 0x0000, 0x0000, + 0x0000, 0x1fa5, 0x0000, 0x4447, 0x0000, 0x0000, 0x0dca, 0x0000, + 0x200a, 0x7287, 0x0000, 0x0000, 0x046c, 0x1a85, 0x0000, 0x0000, + 0x5d49, 0x0000, 0x0000, 0x0000, 0x12ca, 0x0000, 0x0000, 0xb746, + 0x0000, 0x0000, 0x0000, 0xa266, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xbdc6, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x99a6, 0x0000, 0x0000, 0x0000, 0x6605, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x13ec, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x5bc8, 0x6ca5, 0x0fcd, 0xd686, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x1949, 0x1d04, + 0x0000, 0x0000, 0x0000, 0x0000, 0x1a88, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0de8, 0x7d67, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xd606, + 0x0000, 0x0000, 0x1b0e, 0x0000, 0x0000, 0x0000, 0x0000, 0x4086, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5146, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0731, 0x0c66, 0x0000, 0x0000, 0x0000, 0x0000, + 0x258c, 0x47c6, 0x0000, 0x0000, 0x0000, 0x0000, 0x7fe8, 0x0000, + 0x0000, 0x25c7, 0x0000, 0xe9e7, 0x0000, 0x5b04, 0x1f89, 0x0000, + 0x0000, 0x39a6, 0x0000, 0x0000, 0x0000, 0x2866, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x60e8, 0x39a7, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x158b, 0x0000, 0x0000, 0x3a04, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0932, 0x5ae7, 0x0000, 0x7fe4, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x4828, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x81a6, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x230c, 0x54a5, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x63e6, 0x0000, 0x0000, 0x0000, 0x0000, 0x13e8, 0x0000, + 0x37cb, 0xd847, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x3164, 0x0000, 0x0000, 0x0000, 0x0000, + 0x122b, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0295, 0x0000, 0x0000, 0x3546, 0x4c0a, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x7a29, 0x0000, 0x1f4a, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0c8b, 0x0000, 0x0000, 0x0000, 0x0000, 0xf7c6, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3b85, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x4a4a, 0x0985, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x37e8, 0x0000, 0x0000, 0x0000, 0x0000, 0x41c4, 0x0000, 0x0000, + 0x01d7, 0x8c87, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x1787, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x2d49, 0x25a7, + 0x0000, 0x0000, 0x0000, 0xd9e7, 0x0000, 0x1644, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6d04, + 0x0000, 0x67e6, 0x0000, 0x0000, 0x1a0b, 0x1946, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xf446, 0x0000, 0x0000, + 0x0000, 0x0000, 0x408a, 0x6d07, 0x0000, 0x0000, 0x2729, 0x1c04, + 0x0000, 0x0000, 0x030b, 0x0000, 0x0168, 0x4445, 0x0000, 0x0000, + 0x0000, 0xf227, 0x1e48, 0x1e25, 0x05d6, 0x0000, 0x0000, 0x0000, + 0x67c9, 0x9f26, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x6726, 0x28ea, 0x7dc4, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0xc587, 0x4089, 0x2dc4, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0xd906, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xf1e6, 0x0000, 0x6744, + 0x0000, 0x0000, 0x0000, 0x0000, 0x116b, 0x2966, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x2407, 0x0000, 0x7286, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0xec07, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0xb7e6, 0x0000, 0xc446, 0x0000, 0x3144, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xf167, 0x0000, 0xd6e7, + 0x0000, 0x5244, 0x1c8d, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x2ec8, 0x0000, 0x0000, 0x0000, 0x0000, 0x5be7, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x286b, 0x3e46, 0x0000, 0x84e7, + 0x0000, 0x0000, 0x0000, 0x0000, 0x1369, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x7145, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x8e66, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0d8a, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x4d04, 0x70c8, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x5688, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x66e6, + 0x0000, 0x0000, 0x0000, 0x2624, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x5526, 0x0000, 0x0000, 0x0000, 0x0000, + 0x000d, 0x1ac5, 0x7d88, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x02ee, 0x0000, 0x0000, 0xd4e6, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xb467, + 0x0000, 0x0000, 0x0271, 0x5946, 0x0000, 0x0000, 0x0000, 0x0000, + 0x080d, 0x5c24, 0x0000, 0x0000, 0x2b29, 0xdbc6, 0x0000, 0x0000, + 0x486a, 0x05e5, 0x0000, 0x0000, 0x436a, 0x1165, 0x0000, 0x0000, + 0x0000, 0x0000, 0x308d, 0x0000, 0x0000, 0x0000, 0x0000, 0x1fa6, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x1f8a, 0x0000, + 0x5d2c, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x3f08, 0x0d64, 0x0000, 0x6ce4, + 0x0000, 0x0000, 0x0000, 0x1ca4, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x70e4, 0x0000, 0x0000, 0x08ec, 0x0000, 0x0000, 0x44a5, + 0x00c9, 0x05e4, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x7a85, 0x6c28, 0x5825, 0x0000, 0x0000, + 0x0000, 0x1427, 0x0000, 0x0000, 0x0000, 0x0000, 0x11e8, 0xa667, + 0x0000, 0x0000, 0x0000, 0xad86, 0x042c, 0x5a85, 0x0000, 0x0000, + 0x0000, 0x0265, 0x0000, 0x0000, 0x0000, 0x3165, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x69c4, 0x1a4c, 0x0000, 0x0000, 0x0000, + 0x0f49, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x56e4, 0x7528, 0x3e27, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x59c6, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0xc5a6, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x1429, 0x0626, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x4aa4, 0x0000, 0x0000, 0x0000, 0x88c6, + 0x0000, 0x0000, 0x0000, 0x6564, 0x718b, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xb7e7, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x054c, 0xf1e7, 0x0000, 0x0000, 0x0000, 0xfbc7, + 0x084a, 0xfae7, 0x0000, 0x0000, 0x494b, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x038b, 0x86a7, + 0x0000, 0x0000, 0x0000, 0x98a6, 0x0000, 0x0000, 0x07cb, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0xdcc6, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0336, 0x0000, + 0x3e6a, 0xad87, 0x0000, 0x0000, 0x0c28, 0x0145, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x3c25, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x04a9, 0x10c6, + 0x1368, 0x3cc7, 0x0000, 0xb446, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x49e5, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x26c8, 0x92a7, 0x0000, 0x0000, 0x0000, 0x0000, 0x3329, 0x9087, + 0x0000, 0x0000, 0x0000, 0x3c46, 0x0000, 0x0000, 0x20e8, 0x73c7, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6486, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x9e27, 0x0000, 0x33e4, 0x0000, 0x2b85, + 0x0000, 0x0000, 0x0000, 0x7e84, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x14b2, 0xe166, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x3304, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x2029, 0xa526, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x8e46, + 0x0000, 0x0000, 0x0000, 0x1f24, 0x0000, 0x0000, 0x0000, 0x4805, + 0x0000, 0x0000, 0x0000, 0x0000, 0x1cee, 0x0000, 0x0000, 0x0000, + 0x2409, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x3629, 0xb9e7, 0x472c, 0xd1c7, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0aec, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x616c, 0x4347, 0x0000, 0x0000, 0x0000, 0x33a5, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x3de8, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x17ea, 0x06c7, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x4248, 0x46e7, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0xb986, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x65e9, 0x4c26, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3c86, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x7089, 0x0000, 0x0000, 0x0000, 0x0000, 0xa6e7, + 0x0000, 0xd786, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5005, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0xe4e6, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3b44, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x89e6, 0x0000, 0xbc07, 0x51ec, 0x8146, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x2625, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x9a87, 0x0000, 0x0000, + 0x35a8, 0x1b26, 0x0000, 0x0000, 0x0000, 0x0000, 0x5c6a, 0x22c7, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5886, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xe606, 0x1d2c, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xfc26, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xba06, 0x0000, 0x0000, + 0x0000, 0xc6c6, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xe106, + 0x0390, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x05a9, 0x0000, 0x0491, 0x0000, 0x02ce, 0xb447, + 0x2f48, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xbc66, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x04eb, 0x0000, 0x0000, 0x83c6, 0x5aa8, 0xf467, + 0x0000, 0xfe86, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x700c, 0xe9e6, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x64a9, 0x0000, 0x0000, 0x0000, 0x0000, 0xffc7, 0x0000, 0x0000, + 0x0000, 0x0000, 0x022b, 0x5905, 0x0000, 0x4d24, 0x06e9, 0x2806, + 0x21e8, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x37aa, 0x0000, 0x170b, 0x0ce7, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5269, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5486, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x2a2b, 0x0000, 0x0000, 0x0000, + 0x3f4c, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x696a, 0x09a5, + 0x0000, 0x3944, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xb187, + 0x2fca, 0x0da6, 0x11cb, 0x2946, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0af1, 0x0000, 0x0000, 0x0000, 0x3d8b, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x9ae6, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x1a6b, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x8326, 0x0000, 0x2827, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0xf827, 0x0000, 0x0000, 0x0f48, 0x0000, + 0x0000, 0x1d44, 0x0000, 0x0000, 0x0000, 0x8946, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x44a8, 0x1fa7, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4149, 0x1066, + 0x0000, 0x0000, 0x12ae, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x3f64, 0x0000, 0x0000, 0x0000, 0x0000, 0x6569, 0x4ec6, + 0x0000, 0x0000, 0x0000, 0x2ae4, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x3804, 0x49ea, 0x38e7, 0x0000, 0xaca7, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x47e6, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x92e6, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x51a6, 0x0000, 0x0000, + 0x0000, 0xdc26, 0x0000, 0x95c6, 0x0000, 0x0000, 0x0000, 0x0000, + 0x252a, 0x8ce7, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x54c4, 0x0000, 0x0000, 0x1492, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x046e, 0x0000, 0x05ad, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0f2a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0fa4, 0x0000, 0x0000, 0x0000, 0xcac6, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5a24, 0x1228, 0x0000, + 0x0000, 0x0000, 0x794b, 0x6307, 0x0000, 0x0000, 0x0000, 0x5964, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xf9e7, 0x0000, 0x0000, + 0x0948, 0x4265, 0x0000, 0x0000, 0x0830, 0x0000, 0x0000, 0x0000, + 0x0d2d, 0x1b86, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x7806, 0x0000, 0x0000, 0x0000, 0x0000, 0x0014, 0x0000, + 0x358b, 0x0266, 0x0000, 0x0000, 0x3228, 0x0c07, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0xc766, 0x0e91, 0x0000, 0x7fa8, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x5dc8, 0xf527, 0x0000, 0x0000, + 0x1289, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x096e, 0x0000, + 0x0000, 0xace6, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x6169, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x4ac4, 0x0000, 0x3507, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x98c6, 0x0000, 0x0000, 0x0000, 0x6d84, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x10a5, 0x0000, 0x0000, 0x0000, 0x0000, 0x1768, 0x0000, + 0x0108, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x35ab, 0x0000, 0x55a8, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x1088, 0x3b06, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x7546, 0x0000, 0x0000, 0x6d49, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x60c8, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0b92, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x67c4, + 0x57a9, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3548, 0x2bc5, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4b69, 0x0766, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x24ad, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x3727, 0x1468, 0x0087, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x64c4, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x1d2e, 0x0000, 0x0000, 0x0000, + 0x0000, 0xf947, 0x0000, 0xd966, 0x0000, 0x0000, 0x3128, 0x0000, + 0x05f4, 0x81c7, 0x0000, 0x0000, 0x0000, 0x26a7, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x2d68, 0x0000, 0x0000, 0x0000, + 0x15ee, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x5348, 0x0000, 0x0000, 0xd167, 0x0000, 0xc806, 0x0000, 0x0000, + 0x0000, 0x6507, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x2304, 0x06cc, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x34a4, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x1f27, 0x0000, 0x0000, 0x0cea, 0x1fc6, + 0x0000, 0x20c5, 0x0030, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x64a6, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xcbc6, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x53e5, 0x7988, 0x7ba4, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6f24, 0x0000, 0x0000, + 0x0000, 0xacc7, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x60e5, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x308c, 0x1947, 0x0000, 0x0000, + 0x0000, 0x0000, 0x020d, 0x4606, 0x0000, 0x0000, 0x0000, 0x6927, + 0x0000, 0x0000, 0x46c8, 0x0000, 0x0000, 0x0000, 0x7548, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x7205, 0x0000, 0x0000, 0x0000, 0xaa27, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x4d4b, 0x1d85, 0x0000, 0xe7c6, + 0x0000, 0x0000, 0x27c8, 0x17c5, 0x0000, 0xac07, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x2ba7, 0x0000, 0x0000, + 0x0000, 0x0000, 0x76e8, 0xf686, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x2b09, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x6a44, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x71c6, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x026e, 0x0000, + 0x146a, 0x0aa7, 0x0000, 0x3ce4, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x122a, 0x0000, 0x0a73, 0x0000, 0x0000, 0x7ea4, + 0x0000, 0x0000, 0x0000, 0xf047, 0x0000, 0x0000, 0x152b, 0x45a5, + 0x084b, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x9527, + 0x0a50, 0x0000, 0x2c0a, 0x38c5, 0x0732, 0x0000, 0x0000, 0xa6a7, + 0x3189, 0x0d66, 0x0000, 0x2e45, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x1985, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0xd546, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x3148, 0x9687, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x7de5, + 0x0000, 0x0000, 0x0000, 0xd407, 0x0000, 0xbde6, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x7aa9, 0x0000, 0x0000, 0x0000, + 0x0000, 0x8606, 0x0000, 0x0000, 0x0000, 0x5904, 0x0000, 0xcba6, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5b06, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x9ee6, 0x0000, 0x0000, 0x0000, 0xc907, + 0x0217, 0x0000, 0x0000, 0x0000, 0x0000, 0x3ca5, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x1328, 0x0365, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0xf8e6, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x068e, 0x0000, 0x02b4, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x6668, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x72ab, 0x0000, + 0x0000, 0x0000, 0x0000, 0x6207, 0x0000, 0x0000, 0x0000, 0x0000, + 0x10ef, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x38ca, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x6a89, 0xd6e6, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6a87, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x7704, 0x0000, 0x0000, + 0x0000, 0x0000, 0x470a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x3809, 0x0000, 0x0000, 0x0000, 0x0868, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0xe446, 0x522a, 0x0000, 0x5b2b, 0x5346, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x53a4, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3245, + 0x0000, 0x0000, 0x130b, 0x0000, 0x0000, 0x0000, 0x0000, 0x7207, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0668, 0x2807, + 0x0000, 0x37a4, 0x0000, 0x0000, 0x0000, 0x0000, 0x268b, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x304b, 0x0000, 0x0000, 0x1de5, + 0x0000, 0x0000, 0x1048, 0x0a67, 0x0000, 0x11e4, 0x0000, 0x2b87, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x77c6, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x1a44, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x35c4, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x00ea, 0x1aa5, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x6427, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x7506, 0x0000, 0x0d85, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x6ea4, 0x496b, 0x1b65, 0x31ca, 0x2d87, 0x0000, 0x91a7, + 0x0000, 0x0000, 0x2ac9, 0x1e26, 0x25e9, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xb5c6, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x1fc9, 0x4644, 0x0000, 0x6244, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xa1c7, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x3da8, 0x1b06, 0x0000, 0x0000, 0x0000, 0x0000, 0x1b6b, 0x2aa7, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x104b, 0xd8c7, 0x134c, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x57a8, 0x4b85, + 0x0000, 0x0000, 0x6de8, 0x0000, 0x1869, 0x5345, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0xd0a6, 0x0000, 0x0000, 0x0000, 0xdfe6, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x9987, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4de4, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x63c7, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0a8a, 0x0f47, 0x0000, 0x0000, + 0x0000, 0x68a6, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x7ea8, 0x0000, 0x0000, 0x4826, 0x0000, 0x0000, 0x0000, 0x3986, + 0x748a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x03e8, 0x1065, 0x0000, 0x0000, + 0x0000, 0x4ba6, 0x0000, 0x0000, 0x0000, 0x9bc6, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0889, 0x22c5, 0x14a8, 0x2665, 0x61a8, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0426, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x8b26, 0x0000, 0x0000, 0x5a08, 0xf427, 0x196a, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3529, 0x28c6, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x1e2b, 0xa487, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x3405, 0x0000, 0x0000, 0x0000, 0xa286, 0x0000, 0x69e7, + 0x0000, 0x0000, 0x52ca, 0x2cc5, 0x0000, 0x0000, 0x0000, 0x0000, + 0x68e8, 0xe3e6, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x51cc, 0xbe46, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x146b, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x274d, 0x7a44, + 0x0000, 0x0000, 0x0000, 0x4b24, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x7645, 0x3648, 0x0000, 0x0000, 0x0000, 0x324c, 0x3367, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x01ac, 0xb767, 0x334e, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x3c66, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x54a4, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x08c9, 0x0000, + 0x0000, 0x0000, 0x0000, 0xafa7, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0d89, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x6124, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5d65, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x088e, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x3f24, 0x0000, 0x28c5, 0x0000, 0x0000, + 0x148f, 0x4e86, 0x51ca, 0x0000, 0x0000, 0x0000, 0x04a8, 0x0406, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x5389, 0x1306, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x48a4, 0x0000, 0x0000, 0x0000, 0x0000, 0x058e, 0x0fc6, + 0x0b2a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0xbf66, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x196c, 0x91e6, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x4269, 0x9a07, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x75e6, 0x0000, 0x53c5, 0x1ceb, 0x6e04, + 0x0000, 0xca26, 0x0000, 0x0000, 0x0000, 0xf4a7, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x79e6, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x1e47, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x34a5, 0x0000, 0x0000, 0x01c8, 0x6845, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x3a2a, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x6849, 0x5606, 0x33a9, 0x6ae4, 0x0000, 0x0000, + 0x0000, 0x49c4, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0e4b, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x05a8, 0x1525, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x18c4, 0x0000, 0x0000, 0x46ab, 0x4925, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5666, 0x0000, 0x0000, + 0x0000, 0x4a25, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x7227, 0x0e8c, 0x0000, 0x0000, 0x0000, + 0x0000, 0xaa06, 0x0000, 0x0000, 0x0000, 0x6444, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x5429, 0x2686, 0x0000, 0x58a4, + 0x7dc9, 0xece6, 0x0000, 0x1c84, 0x0000, 0x0000, 0x0000, 0xe607, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x4c04, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xc4a6, 0x0000, 0xfee7, + 0x1108, 0x4386, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x7024, 0x0000, 0x0000, 0x7549, 0xeac6, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xb7a6, + 0x0000, 0x7ce5, 0x0000, 0x2564, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x4845, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x3905, 0x0000, 0x0000, 0x0000, 0xd1e7, 0x146c, 0x56a7, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0612, 0x5e64, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x2a4b, 0x0000, 0x0000, 0x0000, + 0x0000, 0x8866, 0x0000, 0x0000, 0x0000, 0x0000, 0x56ec, 0x0000, + 0x0000, 0xb707, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x79e7, + 0x0000, 0x0000, 0x29ed, 0x0000, 0x0000, 0xf766, 0x0000, 0x0000, + 0x0000, 0x0000, 0x21a8, 0xc3c7, 0x4ec9, 0x3186, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0xe2e7, 0x4f4a, 0x0005, 0x0000, 0x0000, 0x78c8, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0128, 0x3386, + 0x0000, 0x77c7, 0x0000, 0x0000, 0x4868, 0x2fc4, 0x0000, 0x1a84, + 0x0000, 0x0000, 0x0000, 0x0000, 0x78aa, 0x5524, 0x0000, 0x0000, + 0x020e, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x51e5, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0871, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x5de6, 0x0000, 0x0000, 0x0000, 0x0000, 0x34e8, 0x1ce6, + 0x0000, 0x0000, 0x7f0a, 0x2585, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0c88, 0x1da6, 0x0000, 0x0000, 0x0000, 0xab46, 0x0000, 0x0000, + 0x0000, 0x9707, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x9866, + 0x102e, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x18e5, + 0x0000, 0x0000, 0x356c, 0x0000, 0x0000, 0x0000, 0x0000, 0x76a6, + 0x5328, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5907, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x9446, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x24ec, 0x2706, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x12e9, 0x0000, + 0x0000, 0x0000, 0x0000, 0x4984, 0x0098, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x33cc, 0x0d06, 0x0000, 0x0000, 0x5eaa, 0x20e6, + 0x0000, 0x4625, 0x0000, 0x0000, 0x0000, 0x2804, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x1c24, 0x0000, 0x0000, 0x0000, 0x0000, 0x04b1, 0x6627, + 0x0000, 0x79c5, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xfd46, + 0x106b, 0x1d65, 0x0209, 0x0000, 0x49c8, 0x90a7, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x1baa, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x118a, 0x30c7, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x8f07, 0x0000, 0x0000, 0x0000, 0x3a06, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x198b, 0x32e5, 0x25e8, 0x9847, + 0x0000, 0x0000, 0x0000, 0x0000, 0x00a8, 0x28a5, 0x0000, 0x0000, + 0x0000, 0x0000, 0x018a, 0x6407, 0x0000, 0xdee7, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x3f0d, 0x4da6, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x7306, 0x0000, 0x2f04, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x1b46, 0x488c, 0x0000, 0x6008, 0x38c7, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0010, 0x0000, 0x548a, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x1486, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0656, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0f0d, 0x23a6, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x1c49, 0x2ae6, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x03b6, 0x0000, 0x0000, 0xe286, + 0x0000, 0x0000, 0x0115, 0x0000, 0x0000, 0x0000, 0x02b6, 0x8ca7, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xa5e6, 0x0000, 0x0000, + 0x0000, 0x0000, 0x47e9, 0xc7c6, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6fe6, 0x0000, 0x0000, + 0x0000, 0x77e5, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xdbe7, + 0x15a8, 0x0000, 0x0000, 0x0000, 0x0000, 0x2146, 0x20ae, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0xb266, 0x0000, 0x0000, 0x2588, 0x8126, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x4906, 0x0000, 0x0000, 0x0000, 0x0000, 0x0688, 0x5bc5, + 0x0000, 0x0000, 0x1b2b, 0x1de7, 0x0000, 0x8d26, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5b88, 0x0287, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x3446, 0x0000, 0x0000, 0x0000, 0x4ca5, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x4f04, 0x0000, 0x0000, 0x0aa8, 0x7b07, 0x0000, 0x0000, + 0x0000, 0x0000, 0x71a8, 0x56c5, 0x00eb, 0x8aa7, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x14e4, 0x0000, 0x0000, + 0x0000, 0x0000, 0x2308, 0x07c5, 0x0000, 0x0000, 0x042a, 0x0000, + 0x0000, 0x2ce4, 0x174d, 0x7a87, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4927, + 0x0000, 0x0000, 0x0000, 0x1a65, 0x0000, 0x0000, 0x2a0d, 0x1226, + 0x0000, 0x8d46, 0x0000, 0x6d27, 0x0000, 0x0000, 0x6908, 0x20e4, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x7284, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x136f, 0x0000, 0x0000, 0x0000, + 0x39aa, 0x0c27, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xa987, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4a24, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xae06, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0fd3, 0x0000, 0x0000, 0x0000, 0x0000, 0x9366, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x1444, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x5fa6, 0x0000, 0x1765, 0x0000, 0xa0c7, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x4f66, 0x0000, 0x0000, 0x02eb, 0x1ae4, 0x0000, 0x0000, + 0x0000, 0xa346, 0x0000, 0x0000, 0x0c2d, 0x5987, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x5228, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x2566, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x10ce, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x524c, 0x8746, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xfa47, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x682b, 0x1f07, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0xcec6, 0x0000, 0x0000, 0x426a, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4f46, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6aa5, + 0x47ab, 0x1f26, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x41ea, 0x0000, 0x0000, 0x0000, 0x0000, 0xb166, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0288, 0x0627, + 0x0000, 0x0000, 0x0000, 0x7c05, 0x0000, 0x0000, 0x0000, 0x5b05, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x3e28, 0xc567, 0x0000, 0x0000, + 0x0000, 0x0000, 0x07c9, 0x2186, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x9626, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x3dea, 0x1827, 0x0000, 0x0000, 0x0000, 0x0000, 0x0d4a, 0x0000, + 0x0000, 0x6b66, 0x0000, 0x0000, 0x02ed, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x65a9, 0x73a6, 0x0000, 0x0000, + 0x1be8, 0x4ca6, 0x7728, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x5344, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x53c4, 0x0000, 0x0000, + 0x0509, 0x1b07, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x206b, 0x0000, 0x0000, 0x0000, 0x370a, 0x8b47, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0949, 0x3b66, + 0x0000, 0x0000, 0x178c, 0x1164, 0x0000, 0x63a4, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xc486, 0x0000, 0x0000, + 0x0000, 0x0000, 0x04f5, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xc746, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x2446, + 0x0000, 0x1d05, 0x0000, 0x0000, 0x6ee9, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x4128, 0x01c4, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5ca6, + 0x0000, 0x0000, 0x0000, 0x7c06, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0df0, 0x0000, 0x0000, 0x3524, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x62a7, 0x0000, 0x0000, + 0x0000, 0xc726, 0x0000, 0xdd06, 0x0000, 0x0000, 0x1d2b, 0x0000, + 0x0000, 0x0000, 0x0000, 0x75e5, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x7764, 0x1c28, 0x1ea5, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x1e2e, 0x0000, 0x0000, 0x0000, + 0x0000, 0xf2e6, 0x0000, 0x0000, 0x0000, 0xa086, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x58a7, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x4548, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xc386, 0x0000, 0x0000, + 0x0000, 0x3764, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x230e, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x5b24, 0x0000, 0x0000, 0x0000, 0x2b84, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5ec6, 0x6a09, 0x2544, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x67a9, 0xb1c6, + 0x17ae, 0x0f27, 0x0000, 0x0000, 0x4f09, 0x6587, 0x0000, 0x0000, + 0x458b, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x368a, 0x1584, + 0x424b, 0x6985, 0x1d0d, 0x7b06, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x126a, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4325, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6b64, 0x0000, 0x0000, + 0x6949, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0xa167, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xb946, + 0x4c8c, 0x3105, 0x0000, 0x0000, 0x0000, 0x20c6, 0x03ee, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x5e24, 0x44a9, 0x0004, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x5705, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x6844, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6064, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x7325, 0x0000, 0x0000, + 0x0000, 0x5445, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x2688, 0x3786, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x64ab, 0x1686, 0x0000, 0x0000, + 0x22cd, 0x21e7, 0x0000, 0x0000, 0x1acd, 0x3f26, 0x0000, 0x97e7, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3068, 0x21e6, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xcda6, 0x054a, 0x0b86, + 0x0000, 0x3964, 0x0000, 0x0000, 0x294c, 0xc2a6, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0e2a, 0x0246, + 0x0000, 0x0000, 0x0000, 0xd9c6, 0x0000, 0x0000, 0x0000, 0x78a5, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x16c6, 0x0000, 0x0000, + 0x082a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x79a6, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x2907, 0x0000, 0x0000, 0x4989, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0xdf46, 0x0000, 0x0000, 0x7848, 0xf826, 0x0000, 0x0000, + 0x0000, 0x2687, 0x3f8b, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x4988, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x4cc5, 0x632c, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x244c, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x8e06, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x6388, 0x59e7, 0x0000, 0x0000, 0x28c8, 0x1a45, 0x0000, 0x0000, + 0x0000, 0x57a4, 0x5ec9, 0x3b05, 0x0000, 0x0000, 0x0000, 0xf367, + 0x22ca, 0x86e6, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x3e29, 0x0527, 0x0000, 0x0000, 0x4f48, 0x05c5, 0x7828, 0x0000, + 0x6548, 0x4184, 0x0000, 0x0000, 0x042d, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x4285, 0x0000, 0x7ca5, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xa2a6, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0xa246, 0x0000, 0x53e6, 0x0000, 0x0000, + 0x0000, 0x2644, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x56ab, 0xe3e7, 0x0000, 0x0000, + 0x0000, 0x5ee7, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xf187, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0b11, 0x16c5, + 0x0000, 0x0000, 0x0000, 0xf587, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4124, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3509, 0x6b27, + 0x0000, 0x0000, 0x0000, 0x0000, 0x53e8, 0x2905, 0x0000, 0x4224, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5986, 0x0000, 0xbca6, + 0x0a0e, 0x0866, 0x0000, 0x0000, 0x0000, 0x0000, 0x0769, 0x11a6, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x61e8, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xbb46, + 0x0000, 0x0000, 0x0000, 0x0000, 0x2aee, 0x35c7, 0x6469, 0x93e7, + 0x54a8, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xa9a6, 0x06b0, 0x0000, + 0x0000, 0x0000, 0x0000, 0x49c6, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x2927, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x3aa4, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x398e, 0x0000, 0x0000, 0xd9e6, + 0x0000, 0x0000, 0x7868, 0x2a86, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0xc866, 0x0000, 0x0000, 0x1f4c, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x50c8, 0x1b45, 0x0000, 0xe047, 0x000b, 0x0000, + 0x0000, 0x4765, 0x0000, 0x38e4, 0x0000, 0x0000, 0x0000, 0x7e86, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x4aa9, 0x1426, 0x0000, 0x2ba4, + 0x0000, 0x4186, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x284b, 0x3606, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x28aa, 0x1be5, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x46c4, 0x0000, 0x0000, + 0x0000, 0xae47, 0x3c2b, 0x3686, 0x0000, 0x0604, 0x3928, 0x4c45, + 0x5e89, 0x4d45, 0x0000, 0x0000, 0x0000, 0x5e65, 0x0000, 0x9827, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x18a4, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x4408, 0x3d85, 0x0d6e, 0x33c7, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x7de4, 0x0000, 0x0000, 0x0000, 0x0000, + 0x00b0, 0x0000, 0x0000, 0xc586, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x5424, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0xe666, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x14a4, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x6529, 0x6ea6, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x3e49, 0x0000, 0x0000, 0x0000, + 0x264c, 0x0125, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x36a4, 0x5a2a, 0x1245, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x1626, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xac26, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x1905, 0x0000, 0x77e4, + 0x0000, 0x0000, 0x0000, 0xf106, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0xb366, 0x0000, 0x3c26, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x11ca, 0x0a84, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x7ee5, 0x0000, 0x0000, 0x0000, 0x2764, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5ee9, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5906, + 0x0000, 0x0000, 0x0000, 0xd746, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x1bc8, 0x0000, 0x7b2a, 0xb0c7, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x9f27, + 0x434a, 0x5847, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0e6f, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xdea7, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x35e7, 0x0c2a, 0x5327, 0x0549, 0x1da7, + 0x0000, 0x0000, 0x0000, 0x2107, 0x0000, 0x0000, 0x1aa8, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x38e9, 0x0000, + 0x0000, 0x0000, 0x7148, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x4e0b, 0x0000, 0x47c8, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x2c44, 0x0000, 0x0000, 0x0000, 0xc2c7, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x088f, 0x1d67, 0x5a6c, 0xe2a6, + 0x0000, 0x0000, 0x0000, 0x77a7, 0x0000, 0x67c5, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x02f2, 0x0000, 0x0000, 0x3e05, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4466, 0x1de9, 0x0b05, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0xa3c7, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0a09, 0x8687, 0x0000, 0x0000, 0x0ece, 0x0000, + 0x0000, 0x0000, 0x3beb, 0x2247, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3e24, + 0x0000, 0x0000, 0x53ab, 0x20a7, 0x0000, 0x0000, 0x0000, 0x0000, + 0x01a8, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x62e6, + 0x1f48, 0x5047, 0x0000, 0x0000, 0x0000, 0xb2a7, 0x756a, 0x76a4, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6644, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x7ac8, 0x2947, 0x0000, 0x0000, 0x0000, 0x0000, + 0x442a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x7666, + 0x0000, 0x9486, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x7104, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xab86, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x56a4, 0x2f2b, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x56e7, 0x0000, 0x0000, 0x592a, 0x3047, 0x0000, 0x0000, + 0x0000, 0x0000, 0x1009, 0xc4e7, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x350d, 0x6fa7, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x7108, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4509, 0x2846, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0389, 0xe206, 0x062c, 0x0000, 0x0000, 0x0000, 0x0000, 0xe506, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x34a7, 0x0000, 0x0000, 0x3749, 0x33e6, 0x0000, 0x0000, + 0x242b, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x19ce, 0x0dc4, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x19a7, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0277, 0xc067, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xa786, 0x0000, 0x9547, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x44ac, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0xd706, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x27e5, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0e14, 0x9387, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x78e6, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xf287, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x5be8, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x702b, 0x1085, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x04ca, 0x68c4, 0x0000, 0x0000, 0x0000, 0x2f65, 0x1b48, 0x0105, + 0x528a, 0x7f24, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0ded, 0x3066, 0x50e9, 0x6da7, 0x0000, 0x0000, 0x06aa, 0x62c7, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x394e, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x7746, + 0x0000, 0x0000, 0x0000, 0x3147, 0x0000, 0xaae6, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6e44, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xb027, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x04c8, 0x0f87, + 0x2aca, 0x18e7, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x5a8c, 0x4e84, 0x0000, 0x0000, + 0x0000, 0x0000, 0x6488, 0x2147, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x1a07, 0x0000, 0x09e6, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x5ca8, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4bc6, + 0x0000, 0xbac6, 0x66a9, 0xc226, 0x0000, 0x0000, 0x10ec, 0x32a5, + 0x0000, 0x0000, 0x1648, 0x0c86, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x3c24, 0x0000, 0x0000, 0x0000, 0xac46, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x62e5, 0x0428, 0x9967, 0x6b29, 0x0000, + 0x3a68, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x37e4, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0acb, 0x1004, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x4968, 0x0000, 0x0000, 0x0000, 0x568a, 0x7f47, 0x0000, 0x1864, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xc146, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x5586, 0x0000, 0x0000, 0x2b28, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x2da5, 0x0000, 0xd266, + 0x0000, 0x0000, 0x3b0a, 0x0000, 0x362e, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0397, 0x0000, 0x0000, 0x0000, + 0x7cac, 0x0000, 0x582a, 0x0065, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x1ca5, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0cc8, 0x0000, 0x0000, 0x0000, 0x0000, 0x6c46, + 0x7fc8, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x06f6, 0x0000, 0x0e68, 0x0000, 0x0000, 0x0000, + 0x0000, 0x74a6, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x57c5, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0xd806, 0x0352, 0x3c84, 0x0000, 0x0000, 0x0000, 0x1727, + 0x4d4a, 0x3426, 0x0000, 0x6466, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x9dc6, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4f24, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x3be7, 0x20ca, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x67c6, 0x0000, 0x0000, 0x0000, 0x0000, + 0x034b, 0x08c5, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x1b2f, 0x0000, 0x5008, 0x0666, 0x0000, 0x0000, + 0x2d0d, 0xc647, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5187, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5fc7, 0x0000, 0x0000, + 0x0000, 0x0000, 0x2548, 0x5c27, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x51e9, 0x1bc5, + 0x7149, 0x0000, 0x0000, 0x7ea6, 0x7be8, 0xfb26, 0x0000, 0x0000, + 0x0000, 0x0000, 0x3eea, 0x0000, 0x0000, 0x0000, 0x1b12, 0x1345, + 0x0000, 0x0000, 0x0000, 0x5985, 0x0000, 0x6987, 0x0000, 0x0000, + 0x0000, 0x0000, 0x4da8, 0x1f86, 0x0000, 0x0000, 0x0000, 0x0000, + 0x5d89, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0cee, 0x0000, 0x0057, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4807, 0x0000, 0x0000, + 0x0000, 0x5106, 0x0000, 0x0000, 0x0000, 0x2965, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x4f0c, 0x0000, 0x0000, 0x0000, 0x40c8, 0x0d65, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x6a69, 0x0000, 0x0000, 0x0000, 0x0000, 0x3f04, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x00f4, 0x6e65, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x7345, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0b69, 0x7c25, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x1908, 0x1064, 0x0158, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x2da9, 0xb327, 0x0000, 0x0000, + 0x0000, 0x0000, 0x038a, 0x0ce5, 0x0000, 0x0000, 0x63c8, 0x7ea5, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x04ec, 0xf0a7, 0x0000, 0x6aa6, 0x0000, 0x0000, 0x21ea, 0x40e6, + 0x0000, 0x0000, 0x0000, 0x0000, 0x2a4e, 0x0000, 0x0000, 0x2584, + 0x3ac9, 0x3465, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x6889, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xf226, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3124, 0x0000, 0x0000, + 0x2ca8, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x57eb, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3065, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0968, 0x5885, 0x38ab, 0xa8e7, + 0x0000, 0x25e4, 0x0000, 0x0000, 0x608a, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5da4, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x8526, 0x0000, 0x0000, 0x59ab, 0x1c46, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6f45, 0x35ee, 0x4e46, + 0x0000, 0x0000, 0x0000, 0x0000, 0x584a, 0x0000, 0x0000, 0x0000, + 0x066d, 0x5744, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6786, 0x0000, 0x0000, + 0x022a, 0x0000, 0x0000, 0x0000, 0x0000, 0xf127, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0a86, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0373, 0x6ce7, + 0x3e4c, 0x0000, 0x0caa, 0xe026, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x366a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x78ca, 0x0000, 0x1029, 0xcd87, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x7ca7, 0x3ec8, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x66e4, + 0x0000, 0xf0e7, 0x0000, 0x0000, 0x0000, 0x0000, 0x0c49, 0xdb87, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0118, 0x0000, 0x140b, 0x82c7, + 0x0000, 0x3d87, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x1028, 0x05a6, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x2c28, 0x45c7, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6225, + 0x0000, 0x0000, 0x0000, 0x8f26, 0x17a9, 0x0000, 0x0000, 0x0000, + 0x0357, 0x2c25, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xfd06, + 0x0000, 0x0000, 0x0000, 0x4bc5, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0410, 0x6ae7, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0xfb66, 0x0000, 0x0000, 0x00b2, 0x0084, + 0x0000, 0x0000, 0x39ab, 0x5f87, 0x0000, 0x0000, 0x0000, 0xb526, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xb4a6, + 0x0000, 0x0000, 0x0000, 0x9206, 0x0000, 0x0000, 0x0000, 0x1d26, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x1fe6, 0x0000, 0x0000, 0x1b09, 0x0000, 0x0000, 0x0000, + 0x23cb, 0x0000, 0x0000, 0x0000, 0x0077, 0x0000, 0x0000, 0x0000, + 0x5a6a, 0x4304, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x23a7, + 0x0000, 0x0000, 0x0000, 0x4607, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x5644, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x9bc7, + 0x0000, 0x0000, 0x07f3, 0x0000, 0x042b, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x410c, 0xe8c7, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x4ecb, 0x0000, 0x0000, 0x0000, 0x0000, 0x4545, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x7d25, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x37c5, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0xa426, 0x0000, 0x0000, 0x68a9, 0x4f86, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x22cb, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6c84, + 0x0000, 0x0000, 0x0000, 0x0000, 0x7e4a, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x99e7, 0x0000, 0x2604, 0x0000, 0x3f47, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0356, 0x0000, + 0x0ba8, 0xb007, 0x634a, 0x6964, 0x580b, 0x0000, 0x23ad, 0x0e45, + 0x3ca8, 0x7047, 0x1229, 0x0000, 0x0268, 0xfe67, 0x0000, 0x0000, + 0x0000, 0xf1a7, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0xd807, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x5d48, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x7c68, 0xf586, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xc1c6, + 0x0000, 0x6d46, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x7f44, + 0x0000, 0x0000, 0x0000, 0x65c4, 0x0fcb, 0x0000, 0x0000, 0x9e06, + 0x0000, 0x0000, 0x65c8, 0x7765, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x7aa6, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x7268, 0x0705, 0x0000, 0x0000, + 0x0c94, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x4fcb, 0x0000, 0x0000, 0x0000, 0x0000, 0x5c45, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x5ec5, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x8b07, 0x0000, 0x0000, 0x1ace, 0x0000, + 0x0000, 0x0000, 0x10a9, 0x0000, 0x188d, 0x1507, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x9006, 0x0000, 0x9ba7, 0x0000, 0x0000, + 0x4348, 0x1526, 0x6cea, 0xe306, 0x0000, 0x0000, 0x33a8, 0x10a6, + 0x0000, 0x0000, 0x0000, 0x7a46, 0x0000, 0x0000, 0x056c, 0x0ba6, + 0x2e69, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x41c5, + 0x0329, 0x0000, 0x5e4c, 0x29e4, 0x0000, 0x0000, 0x0000, 0x0000, + 0x16cb, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x04e8, 0x4b25, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x16a4, 0x2e48, 0x0000, + 0x0000, 0xce86, 0x2cc8, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x160d, 0x23c6, 0x0000, 0x6287, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x98e6, 0x6188, 0x1fc7, + 0x7d68, 0x7006, 0x0000, 0x0000, 0x0000, 0xb4e7, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x5d0c, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0fd2, 0x0000, + 0x052b, 0x6284, 0x0000, 0x0000, 0x0000, 0x4ea5, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x24a5, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3484, 0x04ae, 0xed86, + 0x0000, 0x0000, 0x0000, 0x0000, 0x43cc, 0xc447, 0x77a8, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x2ea8, 0x03e7, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0faa, 0x28a4, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x286a, 0x0000, 0x0000, 0xc166, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x9807, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x18cf, 0xee26, 0x4ea9, 0x01e7, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x028f, 0x0966, + 0x43eb, 0xa927, 0x0000, 0x0000, 0x0000, 0x42a7, 0x0000, 0x0000, + 0x00d5, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4345, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x2a44, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0171, 0x0006, 0x0000, 0x0000, 0x238a, 0x5265, 0x0000, 0x7ba5, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x6a07, 0x0000, 0x0000, 0x3f6a, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x1784, 0x7beb, 0x6e85, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0790, 0x77e7, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0xcea6, 0x0000, 0x0000, 0x7348, 0x2a27, + 0x0000, 0x4fc4, 0x0000, 0x0000, 0x3e8a, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x14cc, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3447, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x5f08, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x9fa6, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x6048, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x1e6a, 0x0b24, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xae86, 0x0000, 0x4605, + 0x0000, 0x0000, 0x0069, 0xcf46, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x494a, 0x0000, 0x0000, 0x9ee7, + 0x0000, 0x0000, 0x0000, 0x3f25, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x4fa6, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xf366, 0x052a, 0x37a7, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0728, 0x17a4, 0x0000, 0x0000, 0x2e6a, 0x0000, 0x0000, 0x0000, + 0x0000, 0x4504, 0x0000, 0x6e66, 0x0000, 0x7366, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x6d67, 0x0000, 0x0000, 0x0000, 0xdf87, 0x0631, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x52aa, 0x0000, 0x0000, 0xf327, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x6346, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x8de6, 0x0000, 0x0000, 0x0000, 0x5d25, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0a85, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3345, + 0x0000, 0x7a04, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x57e6, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x176a, 0x2845, + 0x0000, 0x0000, 0x0000, 0x1c65, 0x0000, 0x0000, 0x0000, 0x0000, + 0x4609, 0x0000, 0x03f3, 0xae67, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x3a47, 0x0000, 0x0000, 0x0000, 0x0000, 0x506a, 0x14e6, + 0x0000, 0x0000, 0x0000, 0xb286, 0x0000, 0x3385, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x8bc6, + 0x4648, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x200b, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xdd66, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x94c7, 0x1089, 0x0000, 0x084f, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x27a4, 0x0000, 0x0000, 0x0000, 0x07e5, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xb866, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x2404, 0x0000, 0x0000, + 0x0000, 0x0000, 0x4c09, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x9926, 0x0000, 0x94a7, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xb786, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x5626, 0x0f0a, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0037, 0x0000, 0x292e, 0x0000, + 0x0000, 0x0000, 0x0000, 0x1c47, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0xe7e7, 0x0000, 0x0000, 0x39a9, 0x0000, 0x0000, 0x0000, + 0x0000, 0xa847, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0aa6, + 0x0000, 0x0000, 0x256e, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x9266, 0x0000, 0x0000, + 0x0000, 0x7a84, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x4fa9, 0x22e5, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x24a4, 0x0000, 0x0000, 0x0000, 0x0000, 0x4209, 0x0225, + 0x0000, 0x0000, 0x0000, 0x0000, 0x00b6, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0616, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4b2a, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6165, 0x0000, 0x1884, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xa546, 0x5c2b, 0x5e04, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3387, + 0x180e, 0x0a07, 0x0000, 0x0000, 0x010c, 0xb7c7, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6d24, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6866, 0x0000, 0x0000, + 0x0000, 0x0000, 0x2008, 0x04c6, 0x7b4a, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0b6a, 0x2027, + 0x22c8, 0x71e5, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x5da8, 0x12e4, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x7baa, 0x0000, 0x0000, 0x7bc5, 0x0000, 0x0000, 0x0b49, 0x1845, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3525, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x60c4, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x50cc, 0x6764, + 0x5e0b, 0x0000, 0x0000, 0x0000, 0x52c9, 0x0000, 0x02cb, 0x02a7, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0bea, 0x1de6, + 0x0000, 0x0000, 0x0000, 0x35e6, 0x0000, 0x0000, 0x0000, 0x0000, + 0x000f, 0x6d45, 0x0000, 0x0000, 0x212b, 0x0826, 0x0000, 0x0000, + 0x0000, 0xa8c6, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xebe7, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6524, 0x0000, 0x5704, + 0x0000, 0x8646, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4ec5, 0x0000, 0x0000, + 0x6448, 0x0000, 0x0000, 0x0000, 0x0713, 0x6107, 0x0000, 0x7944, + 0x0000, 0x0000, 0x63a9, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x320a, 0x0000, 0x0000, 0xf3e6, 0x0000, 0x0000, 0x052d, 0x0000, + 0x016c, 0x0ec6, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x1f6a, 0x4ce7, 0x0000, 0x0000, 0x0000, 0x8287, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x1c25, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x2e44, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0d0d, 0x0607, 0x1a2a, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x7446, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xa0c6, 0x0000, 0x5ee6, + 0x0000, 0x0f04, 0x3029, 0x0000, 0x0000, 0x0000, 0x35aa, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6685, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x18ea, 0x0000, + 0x0157, 0x12e6, 0x0000, 0x0000, 0x0000, 0x5f26, 0x2da8, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x05d1, 0x87c7, 0x0000, 0x0000, 0x0000, 0x0000, 0x016b, 0xcb06, + 0x0756, 0x2b05, 0x0000, 0x0000, 0x7e09, 0xe986, 0x0000, 0x0000, + 0x0000, 0x6f05, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x58e4, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x3709, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x7249, 0xef26, 0x0000, 0x77c5, 0x0000, 0x6ea7, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x69e4, 0x228b, 0x0000, 0x25c9, 0x0824, + 0x0000, 0x0000, 0x0000, 0x3fc7, 0x0000, 0xbd47, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x130c, 0x2464, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x234b, 0x49a4, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x1044, 0x0000, 0x0000, 0x39eb, 0x0545, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x2e85, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5505, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x7a28, 0xf9a6, + 0x0000, 0x0000, 0x0000, 0x6544, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xadc7, 0x0000, 0x0000, + 0x0000, 0x5084, 0x0000, 0x0000, 0x6c6a, 0x7ac4, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4387, 0x0000, 0x0f67, + 0x0000, 0x0000, 0x0000, 0xf746, 0x0000, 0x0000, 0x0000, 0x0000, + 0x62a8, 0x4de6, 0x0000, 0xd766, 0x0000, 0x9886, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3c07, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x6f06, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x2568, 0xf967, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x628a, 0x1666, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x35e9, 0x1385, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0xaba6, 0x04f6, 0x0a06, 0x188c, 0x0000, + 0x0000, 0x3f66, 0x0000, 0x0000, 0x0000, 0x50c6, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x97c7, 0x0000, 0x0000, 0x0000, 0x0000, + 0x73cb, 0x0000, 0x0000, 0x0000, 0x0029, 0x0e47, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x37c4, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3d46, + 0x0000, 0x0000, 0x0000, 0x3d66, 0x0000, 0xc606, 0x0000, 0x0000, + 0x3f68, 0x1f47, 0x0000, 0x0000, 0x0000, 0x13c4, 0x0149, 0x2d47, + 0x0033, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x3309, 0x1c86, 0x6b8a, 0x3c06, 0x0000, 0x6166, + 0x0000, 0x0000, 0x0000, 0x45a4, 0x0000, 0x0000, 0x11c8, 0x18a7, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0xba46, 0x0170, 0x2f47, 0x278a, 0x8426, + 0x0000, 0x0000, 0x0257, 0x4866, 0x256b, 0xc147, 0x0000, 0x1624, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x3365, 0x0000, 0x0000, 0x0000, 0x0000, 0x5aea, 0x36e7, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xbf07, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x074f, 0x0000, 0x3c4a, 0x0000, + 0x0000, 0x0000, 0x3f2e, 0xf406, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x1e45, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x7725, + 0x0000, 0x0000, 0x0000, 0x0000, 0x644b, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x2445, + 0x0000, 0x0000, 0x62eb, 0x0685, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0e04, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x8086, 0x0000, 0x0000, + 0x114a, 0x0000, 0x0000, 0x0000, 0x0000, 0xe267, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x74ca, 0xe3a6, 0x0000, 0x0000, + 0x0000, 0x0000, 0x2e68, 0x04c4, 0x0000, 0x0000, 0x0000, 0xa207, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5a65, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xa646, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x9ce7, 0x250c, 0x0da5, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5286, 0x0000, 0x0000, + 0x0000, 0x0000, 0x21c9, 0x49e6, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x8846, 0x0a29, 0x0000, 0x0000, 0x0000, + 0x0000, 0x30e6, 0x0000, 0x0000, 0x0000, 0x0000, 0x1f28, 0x2847, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xb086, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x41ca, 0x4f05, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x1d68, 0x1206, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x7586, 0x0000, 0x0000, 0x0000, 0x0687, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x26a8, 0x1885, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0xef07, 0x0000, 0xa147, 0x0000, 0x55c4, + 0x0000, 0x0000, 0x4e2a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x338b, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0565, 0x0000, 0x0000, 0x0000, 0x0000, + 0x016d, 0x78e7, 0x5ecc, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x1b84, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x6d28, 0x0167, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x6f47, 0x0000, 0x0000, 0x004d, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xddc7, + 0x312a, 0x20e5, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x6649, 0x3907, 0x0000, 0x0000, 0x1f68, 0x1646, 0x3129, 0x0c25, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5446, 0x150c, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x13f2, 0xcce6, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0773, 0x74c7, 0x0000, 0x17e4, 0x0000, 0x0000, 0x0000, 0x0000, + 0x2b49, 0x14a5, 0x0000, 0x6da5, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x1008, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0xa227, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x148e, 0x0000, 0x0000, 0x0000, 0x01f7, 0x1087, 0x1e28, 0x8627, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x1c88, 0x2886, 0x06b6, 0x0000, 0x0000, 0x71c7, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5bc9, 0x5827, + 0x1b28, 0x0924, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x4f88, 0x30a5, 0x0000, 0xb026, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x6fa6, 0x0000, 0x0000, 0x0000, 0x0000, + 0x02a8, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5a2c, 0x0000, + 0x0000, 0x0000, 0x77e8, 0x0000, 0x0000, 0x0000, 0x0000, 0xb326, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x15cc, 0x17a5, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x02c8, 0x0046, 0x0000, 0x0000, 0x65eb, 0x2c47, 0x0000, 0x0000, + 0x0000, 0x0000, 0x352c, 0x0000, 0x3368, 0x0786, 0x01b3, 0xc967, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xb8c6, 0x4a8b, 0x0000, + 0x0000, 0x31c6, 0x0000, 0x0647, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x180b, 0x90e7, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4a04, 0x1bea, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x1ea8, 0x0807, + 0x0000, 0x0000, 0x0000, 0x0000, 0x22ce, 0x0000, 0x4b88, 0x0000, + 0x0000, 0xbbc6, 0x212a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x26cc, 0xdc67, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x1025, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xa986, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x3f2d, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x7d0b, 0x0000, 0x0000, 0x78c6, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x68e6, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x4fa5, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x49c9, 0x0000, 0x0000, 0x0000, 0x0000, 0x2305, 0x0000, 0x0000, + 0x0000, 0xad46, 0x0000, 0x0000, 0x0000, 0x2325, 0x0000, 0x8507, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x72a6, 0x0000, 0x0000, + 0x01f5, 0x4567, 0x0000, 0x0000, 0x7ec9, 0xeb66, 0x0000, 0x0000, + 0x0000, 0x78a6, 0x0000, 0x0000, 0x0ead, 0x0427, 0x0000, 0x0000, + 0x0000, 0x6425, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6da4, + 0x0000, 0x6706, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x2da4, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x60cb, 0x00e5, 0x0000, 0x35c6, + 0x0000, 0x0000, 0x1cea, 0x2d05, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x66c9, 0x5c86, 0x0000, 0x0000, + 0x7428, 0xb9a7, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6a84, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0229, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x7d26, 0x0000, 0x0000, 0x0000, 0x0000, 0x046f, 0x67e4, + 0x0000, 0x0000, 0x300c, 0x3927, 0x0000, 0x0000, 0x0000, 0xa8e6, + 0x0000, 0x0367, 0x0000, 0x0000, 0x7b08, 0x0000, 0x2109, 0x4505, + 0x0000, 0x3224, 0x0000, 0x0000, 0x0000, 0x58c6, 0x0000, 0x9766, + 0x0000, 0x0000, 0x0177, 0x19a4, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x00aa, 0x4867, 0x0000, 0x59a4, 0x0000, 0x0000, 0x7e68, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x64a4, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x3d24, 0x0000, 0x0000, 0x0000, 0x8006, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6f87, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x3b29, 0x0000, 0x0000, 0x0000, + 0x526c, 0x6c06, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x130a, 0x6667, 0x0000, 0x0667, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x1049, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x1ca8, 0x0000, 0x0000, 0x0000, + 0x0000, 0x5444, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x6044, 0x068b, 0x09e5, 0x0000, 0x0000, + 0x0000, 0xd046, 0x0000, 0x3326, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x1866, 0x0000, 0x5604, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x6f25, 0x15c8, 0x1404, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x6d06, 0x0000, 0x72c6, 0x4728, 0x2187, 0x0000, 0x0000, + 0x0000, 0x9906, 0x0000, 0xaa26, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x2ec5, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x5b65, 0x0000, 0x0000, 0x0000, 0x0000, + 0x17cb, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x194a, 0x3f45, 0x3789, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x6868, 0x0000, 0x0237, 0xbec7, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x3ba7, 0x0000, 0x0000, 0x7c4a, 0xabc6, 0x0992, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x2c68, 0x23e7, + 0x0000, 0xada6, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x38e8, 0x3005, 0x0000, 0x0000, 0x0000, 0x2105, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x7d28, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0386, + 0x0000, 0x0000, 0x0000, 0x6a64, 0x15ec, 0x2ce7, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x23ea, 0x5c84, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x6b26, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x6669, 0xaf46, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x15cd, 0x1c05, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0xce27, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x51e8, 0x47a4, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x100b, 0x2be7, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x72c5, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x55e6, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0xbea6, 0x0000, 0x0000, 0x0000, 0x7e24, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x2a84, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x6baa, 0x0000, 0x160b, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0c11, 0x7b25, + 0x0000, 0x4ce4, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0xefe7, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x8d66, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x1ee4, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0368, 0x02e7, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x04cd, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x7ee4, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x8806, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xc626, + 0x0000, 0x0000, 0x0000, 0x0000, 0x1c6a, 0x0000, 0x0000, 0x0000, + 0x3bc8, 0x2d06, 0x0000, 0x0000, 0x0000, 0x0be7, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x5768, 0x0000, 0x0000, 0x0000, + 0x034e, 0x0000, 0x0000, 0x0000, 0x0000, 0x8be7, 0x0000, 0x0000, + 0x0000, 0x5c64, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x5ca9, 0x0864, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x3a08, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x054e, 0x0000, 0x0c0a, 0x0000, 0x0000, 0x0000, 0x0350, 0x2ac5, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x1968, 0x0000, + 0x0000, 0x3824, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x2009, 0x26e6, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x5eca, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6765, 0x0000, 0x0000, + 0x0000, 0x0000, 0x48ac, 0x0805, 0x0000, 0x82e7, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x2406, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0xabe6, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xa3a7, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x2f0c, 0x0186, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x1347, 0x0000, 0xbe06, + 0x0000, 0xdb26, 0x0bec, 0x3ec6, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x21a4, 0x2468, 0x95a7, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x01f4, 0x0000, 0x0000, 0x0000, 0x0000, 0xa7a6, 0x0000, 0x7f26, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x6b2a, 0xe246, 0x42a8, 0x0000, 0x0000, 0xb5a6, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x6888, 0x1a64, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0270, 0x0000, 0x1388, 0x0000, + 0x0000, 0x0000, 0x0000, 0x7e25, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x6686, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0017, 0x1c85, 0x0000, 0x0000, 0x0000, 0x8d67, + 0x0000, 0x9f86, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6a2a, 0xe006, + 0x0000, 0x0000, 0x30a9, 0x2465, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x41aa, 0x0000, + 0x0000, 0x0000, 0x38ae, 0x0000, 0x0000, 0x0000, 0x0000, 0x5347, + 0x0000, 0x0000, 0x0000, 0x34c4, 0x0011, 0x2c65, 0x0000, 0x0000, + 0x0000, 0x0000, 0x14ab, 0x0000, 0x2089, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6c25, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xcb26, 0x0000, 0x0000, + 0x0000, 0x1d45, 0x0000, 0xace7, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x2648, 0x0000, 0x0000, 0x0000, + 0x644c, 0xf026, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x168d, 0x0000, 0x0000, 0x0000, 0x0000, 0xa407, 0x65c9, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x5865, 0x0000, 0x0000, 0x0000, 0xbaa7, 0x016a, 0x07a7, + 0x5bac, 0x0000, 0x0000, 0x0000, 0x2aa9, 0x0000, 0x0000, 0x0000, + 0x0c4e, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x7ec8, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x11cf, 0x0cc6, 0x0000, 0x0000, + 0x03d7, 0x0000, 0x0000, 0x66e7, 0x0000, 0x82a6, 0x0000, 0x0000, + 0x0000, 0xf147, 0x0000, 0xbd06, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0ae6, 0x0000, 0x9b66, 0x1ea9, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0608, 0x0887, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0fc8, 0x09a7, 0x4e29, 0x7544, 0x0000, 0x0000, 0x2bea, 0x0000, + 0x0000, 0x0000, 0x15ca, 0xd086, 0x0000, 0x5867, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x3265, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x00d7, 0x0000, + 0x0000, 0x2346, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0109, 0x0584, 0x0000, 0x0000, 0x2d6a, 0x0e67, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x4429, 0x5f27, 0x0000, 0x0000, 0x6869, 0x9cc6, + 0x0000, 0x0000, 0x0000, 0x0000, 0x7448, 0xf206, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x51ac, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x2b08, 0x0000, 0x0000, 0xb966, + 0x542b, 0x1726, 0x0000, 0x0000, 0x3988, 0x0ba7, 0x5e28, 0x3bc5, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x7f85, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0ce4, 0x0000, 0x0000, + 0x0000, 0x3e64, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x19ea, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0c04, + 0x0000, 0x7907, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x006a, 0x0000, 0x0000, 0x0000, 0x0000, 0x31e7, + 0x0000, 0x0000, 0x0000, 0x0000, 0x1c09, 0x4666, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x5806, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xc2e6, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x6ba8, 0x0000, 0x0000, 0x0000, + 0x0000, 0x7646, 0x29ac, 0x5d45, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x71c4, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x5186, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xae26, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xbd46, 0x0000, 0x0000, + 0x0000, 0x0000, 0x192a, 0x0000, 0x3fca, 0x59a7, 0x0000, 0x0000, + 0x4208, 0x0000, 0x0000, 0x0000, 0x0000, 0x0284, 0x0000, 0x0000, + 0x0000, 0x9c66, 0x0000, 0x0000, 0x0000, 0x9166, 0x0000, 0x0000, + 0x0000, 0x2666, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x8867, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x35a5, 0x0000, 0x0000, 0x0000, 0x6e24, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4da4, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5c06, 0x0000, 0x2b86, + 0x0000, 0x6c85, 0x0000, 0x0000, 0x0000, 0x0000, 0x3628, 0x0000, + 0x0000, 0x0000, 0x606a, 0xbae7, 0x0000, 0x0000, 0x0000, 0x0000, + 0x1aea, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0f8d, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x06ec, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0e13, 0x07c7, 0x0000, 0x6b04, 0x21cc, 0x0000, + 0x4788, 0x0000, 0x0000, 0x0000, 0x0000, 0x7566, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x2c06, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x50e4, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0152, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x1b8a, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x3a0e, 0x0000, 0x0000, 0x0da4, 0x0000, 0x0000, + 0x0000, 0xda46, 0x0000, 0x0000, 0x0000, 0x4066, 0x0000, 0x0000, + 0x0000, 0x46c7, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x086a, 0x0504, 0x0000, 0x0000, 0x5a49, 0x7c07, 0x0000, 0x0000, + 0x736b, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x8f27, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x4707, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x1ee9, 0x0000, 0x0000, 0x0000, 0x0000, 0x50a4, + 0x0000, 0x0000, 0x290c, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xaa66, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xa006, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x00f6, 0x0385, 0x2d09, 0x1447, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5f86, + 0x0000, 0x0000, 0x6829, 0x6bc6, 0x0000, 0x6b05, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x5c0a, 0x0b85, 0x0000, 0x0000, + 0x7688, 0xf306, 0x0000, 0xb8e6, 0x07ea, 0x49c5, 0x0000, 0x0000, + 0x0000, 0xbe26, 0x0000, 0x0000, 0x0000, 0x58a6, 0x0000, 0x0000, + 0x07b4, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x3c69, 0x0000, 0x0000, 0x0000, 0x0000, 0x97a6, + 0x0000, 0x0000, 0x0000, 0x0000, 0x03b1, 0x7fc4, 0x0000, 0xd607, + 0x0000, 0x3a46, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5b64, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x156e, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x1e2a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x7888, 0xfaa6, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x8986, 0x0000, 0x0000, + 0x0000, 0x7747, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0xf4c7, 0x0000, 0x0000, 0x0448, 0x44a6, + 0x7c4c, 0x0000, 0x0000, 0x3827, 0x1132, 0x6a47, 0x0000, 0x0000, + 0x53c8, 0x1244, 0x0000, 0x0000, 0x0000, 0x0000, 0x40c9, 0x13e6, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x12ed, 0x0000, 0x0000, 0x8066, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x7aea, 0x0000, + 0x0000, 0x0000, 0x0000, 0x7c27, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x11aa, 0x3ea7, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3885, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x1d28, 0x12a5, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x48cc, 0x0000, 0x0000, 0x0000, 0x6428, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x08c4, 0x0000, 0x0000, + 0x2e2a, 0x0000, 0x0490, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x198c, 0x5a27, 0x35ca, 0x1e27, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0xe326, 0x0210, 0x86c6, 0x7faa, 0x0000, 0x0000, 0x32c5, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x08a6, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0xe4c7, 0x0000, 0x0000, 0x0000, 0x6707, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x6745, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x6609, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x7d05, 0x59a8, 0xe6a7, + 0x0000, 0x34e7, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x3fc8, 0x0000, 0x0000, 0x8306, 0x0000, 0x0000, + 0x0000, 0x4d46, 0x0000, 0x0000, 0x0000, 0x4104, 0x0000, 0x0000, + 0x0000, 0x0000, 0x7bc8, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x2824, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x8de7, 0x0000, 0x0000, 0x7328, 0x0000, + 0x0000, 0x0000, 0x0309, 0x31a5, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x6b06, 0x0000, 0x0000, 0x0000, 0x1167, + 0x234d, 0x7aa5, 0x0000, 0x2405, 0x0000, 0x0000, 0x0000, 0xec47, + 0x5168, 0x0704, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x20ac, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4d28, 0xaf66, + 0x0000, 0x96a6, 0x0000, 0x0000, 0x466b, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x29a6, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x2e24, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4dc6, 0x0000, 0x0000, + 0x0000, 0xafe6, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4e0a, 0x1407, + 0x0000, 0x2d64, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x4d69, 0x0000, 0x15cb, 0x2486, + 0x0000, 0x0000, 0x520a, 0x4d06, 0x0000, 0x0000, 0x0000, 0x55a6, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x50e7, 0x0000, 0x0000, + 0x0000, 0x4ee5, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x9e66, 0x0000, 0x0000, + 0x0000, 0xe0a6, 0x0000, 0x0000, 0x0000, 0xd287, 0x0000, 0x0000, + 0x3aa9, 0x0000, 0x4268, 0x99c7, 0x092b, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x218c, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0cc9, 0x45c6, 0x0daa, 0x0825, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x4a68, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x2eca, 0xe507, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x020b, 0x0000, 0x32a9, 0x00c6, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6e25, + 0x0000, 0xbae6, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x11c5, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x02af, 0x3a45, + 0x02ec, 0x2025, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x09ac, 0x3287, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x5908, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x6b88, 0xe706, 0x0000, 0x0000, 0x518c, 0x4ea6, + 0x0000, 0x0000, 0x0000, 0x0000, 0x01b8, 0x2f24, 0x0000, 0xe647, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0xbba6, 0x0000, 0x0000, 0x0000, 0xee47, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x3d64, 0x1d4a, 0x1564, 0x0000, 0x0000, + 0x0000, 0x0000, 0x4eea, 0x9447, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x7469, 0x0000, 0x154b, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xc666, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5fa5, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3505, 0x0000, 0x0000, + 0x5948, 0x0000, 0x0000, 0x0000, 0x0000, 0x55a7, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x23aa, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x35a4, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x08ea, 0x0247, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0e8e, 0x6787, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x242a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x5464, 0x0000, 0x0000, 0x0000, 0xb206, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x50e6, 0x0000, 0x0000, + 0x0000, 0xa6c6, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x048b, 0x1a26, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x2ac4, 0x0000, 0x0000, 0x0000, 0x7404, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0xe5c7, 0x0ed4, 0x6b07, 0x51cb, 0x27c4, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0013, 0x7267, + 0x6fe9, 0x38c6, 0x0000, 0x0000, 0x402c, 0xb227, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x62ea, 0x0000, 0x132c, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6384, 0x71a9, 0x37a6, + 0x2b2d, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x4846, 0x0000, 0x0000, 0x0000, 0xad66, 0x0000, 0x0000, + 0x0000, 0x4565, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x5fc8, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x43a7, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x6e06, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xbc46, + 0x0000, 0x0000, 0x7aeb, 0x0000, 0x6009, 0x0000, 0x0000, 0x0000, + 0x0000, 0x4904, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x5c2c, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x1c44, 0x03c8, 0x3545, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0eb3, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x39c7, 0x0000, 0x0000, 0x0000, 0x3024, 0x0000, 0x31c5, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x2b64, 0x0000, 0x0000, 0x0000, 0x0000, 0x0fa9, 0x9d67, + 0x5088, 0x1105, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x3aa7, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xaae7, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x59e5, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0xb1e6, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x5da6, 0x0000, 0x0000, 0x0000, 0x0000, + 0x4448, 0x50a7, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x22ac, 0x0000, 0x0000, 0x9f66, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x38a6, 0x4308, 0x4564, 0x0000, 0x0000, + 0x7b6a, 0x8a67, 0x0000, 0x0000, 0x0b4a, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6b84, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x2024, 0x0000, 0xdd07, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x85e6, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0a66, + 0x0000, 0x6864, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0xfac6, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x5709, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0be9, 0xd6c7, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0345, 0x0000, 0x44c4, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x70a6, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x66c8, 0x0000, 0x0000, 0x0f46, 0x0000, 0x0000, 0x0000, 0x64e6, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x20c7, 0x0000, 0x4d85, + 0x4b28, 0x0444, 0x0000, 0x0000, 0x1549, 0x0000, 0x0000, 0x0000, + 0x0000, 0x4324, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x2985, 0x0000, 0x0000, 0x1a0f, 0xeea6, + 0x16c8, 0x20a6, 0x0000, 0x0000, 0x0000, 0xd726, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x74a4, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xc926, 0x0000, 0x6fe7, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6585, + 0x0000, 0x0000, 0x75c9, 0xef86, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x6147, 0x0000, 0x0000, 0x0000, 0x1124, + 0x0000, 0xa446, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0xcfa6, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0xc6e6, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x668b, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x1729, 0x0b25, + 0x0000, 0x9106, 0x1ccc, 0x00c5, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x07eb, 0x03a6, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0xd986, 0x0000, 0x0000, 0x1628, 0x1547, + 0x0000, 0xf526, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0b6b, 0x0000, + 0x022c, 0x0587, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x21c5, 0x0000, 0x2505, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xbe66, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x5eab, 0x00e4, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x424a, 0x4987, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6246, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4887, 0x4e68, 0x0b07, + 0x37e9, 0x0726, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x69a8, 0x5be6, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x03e5, 0x01ec, 0x0000, 0x398a, 0x4125, 0x018c, 0x3506, + 0x0000, 0x0000, 0x0000, 0xa2c7, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x4a65, 0x0000, 0x0000, 0x0000, 0x01a5, + 0x4489, 0x0c26, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0xb807, 0x388b, 0xdce7, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0e71, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xc0e6, 0x0000, 0x8ae7, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0028, 0x0000, 0x2ce8, 0x3d05, + 0x0000, 0x2166, 0x0000, 0x0000, 0x0000, 0xf7e6, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x9066, 0x0000, 0xc4e6, + 0x0000, 0xb3c6, 0x03e9, 0x0000, 0x0000, 0x2f25, 0x0cb1, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x3b89, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xfce7, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0xe587, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0470, 0x6965, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x4544, 0x0000, 0x0000, 0x0000, 0x4305, 0x4e2b, 0x19e5, + 0x0000, 0xab67, 0x0000, 0x0000, 0x0000, 0x3504, 0x6228, 0x2a07, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x7004, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x036b, 0x5dc7, 0x0000, 0x0000, + 0x0000, 0x0000, 0x1dcc, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x2fec, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x4b64, 0x5aaa, 0x0164, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3b84, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0xc206, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x5504, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x366b, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xb2e7, 0x0000, 0x0000, + 0x01b4, 0x0e05, 0x0000, 0x0000, 0x2c8a, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xf566, + 0x0000, 0x0000, 0x0000, 0x9b86, 0x024c, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x6c66, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0649, 0x5884, 0x092a, 0x4a07, 0x0000, 0x3ec4, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x142a, 0x2b66, + 0x0000, 0x0000, 0x0000, 0x0000, 0x3ac8, 0x0424, 0x0000, 0x1ec7, + 0x4768, 0x0146, 0x0000, 0x3a26, 0x4cc8, 0x0000, 0x1daa, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x030d, 0x0245, 0x0000, 0x3f46, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0436, 0x26a4, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x1189, 0x0000, 0x0000, 0x0000, 0x0000, 0x8406, + 0x0000, 0x0000, 0x0000, 0xd506, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x8186, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xa466, 0x360a, 0x0ac5, + 0x2108, 0x4185, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0d6a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0f6a, 0x73e4, 0x0000, 0x0000, 0x77aa, 0x8fa7, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x6145, 0x0000, 0x3ec5, 0x1888, 0x0000, + 0x0000, 0x0000, 0x0000, 0xa406, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x6ae5, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x05aa, 0xaf07, + 0x0000, 0x0000, 0x0000, 0x7d64, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x8926, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x4428, 0x4c87, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x06cb, 0x0000, 0x0000, 0x0000, 0x0000, 0x1587, 0x0000, 0x0000, + 0x0000, 0x80a6, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x4704, 0x0000, 0x0000, 0x0000, 0x5b84, + 0x4d2a, 0x0000, 0x0000, 0x79c6, 0x0bcd, 0x7ba7, 0x5ba8, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xdfa7, 0x0000, 0x0000, + 0x532c, 0xfbe7, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x64ca, 0x23e5, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xc066, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x16cd, 0xc367, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3c87, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0xcae6, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x6dc8, 0xe526, 0x0000, 0xc426, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0bac, 0x0000, 0x5968, 0x7c44, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x07e4, 0x0000, 0x49e4, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x5da5, 0x0000, 0x0000, 0x0000, 0x0000, + 0x446c, 0x2dc5, 0x0000, 0x0000, 0x0000, 0xda67, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0b27, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xb6e6, + 0x0000, 0x6086, 0x6faa, 0x0000, 0x0000, 0x0000, 0x0614, 0x0000, + 0x0000, 0x75a5, 0x0000, 0x0000, 0x564a, 0xdf27, 0x0d4b, 0x3707, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0411, 0x0000, 0x2989, 0x1b04, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6a85, 0x0000, 0x0000, + 0x340a, 0x4687, 0x0000, 0x72c4, 0x0000, 0xdc86, 0x0000, 0x0000, + 0x0078, 0x0000, 0x0000, 0x2245, 0x0000, 0x0000, 0x0000, 0x0000, + 0x3ea8, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x6a6a, 0x5ce5, 0x0000, 0x0624, 0x0000, 0x6de6, 0x0000, 0x0000, + 0x05e8, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6c24, + 0x0000, 0x9646, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x05e9, 0x2205, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xb5e6, 0x0000, 0x0000, + 0x0000, 0x0000, 0x6f69, 0xeee7, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5f24, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x32e4, + 0x0000, 0x16e7, 0x0000, 0x0000, 0x3d4d, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x046b, 0x5b66, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6664, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x47e4, 0x0000, 0x0000, 0x0000, 0x0000, + 0x05b1, 0x6647, 0x0000, 0x0000, 0x09ab, 0x1bc6, 0x0000, 0x0000, + 0x0000, 0x0000, 0x6a2c, 0xeb06, 0x0000, 0x0000, 0x0000, 0x4f26, + 0x0000, 0xa386, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0aca, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x6624, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6e45, 0x0000, 0x0000, + 0x0000, 0x7246, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x6c2a, 0x0000, 0x0000, 0x3544, + 0x31e8, 0x0746, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x4349, 0x0cc7, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x6d87, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x1169, 0x46c5, 0x0000, 0x07e7, + 0x0192, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0068, 0x0e46, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x4808, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x74a5, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5686, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x5e0a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x2ee4, 0x0000, 0x7e66, 0x0000, 0x0000, + 0x0c09, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x128d, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x2a28, 0x0707, + 0x534a, 0x0000, 0x1ec8, 0x3145, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x36a9, 0x0000, 0x0000, 0x0000, + 0x3f4a, 0x0000, 0x0000, 0x0000, 0x0000, 0x7d66, 0x0000, 0x9167, + 0x0000, 0x2904, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x7d08, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x5d08, 0x0ca4, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5ac5, + 0x0000, 0x0000, 0x160a, 0x0000, 0x124c, 0x0126, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x68e4, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x1bec, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x1ed2, 0xf166, 0x03ab, 0x0000, 0x0000, 0xdd67, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x69c6, 0x00ca, 0x13a5, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x6d65, 0x0000, 0x0000, 0x3ba9, 0x60a5, 0x162c, 0x4fe4, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xda66, + 0x0000, 0x0000, 0x0000, 0x0000, 0x13cd, 0x6d26, 0x0000, 0x5264, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x30e5, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x5388, 0x6e64, 0x0000, 0x09c6, 0x4e8c, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0xb686, 0x0000, 0x7846, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x3985, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x044b, 0x18e4, 0x0000, 0x0000, 0x0000, 0x3086, 0x3b4e, 0x0000, + 0x21eb, 0x0000, 0x29a9, 0x4c06, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0636, 0x0000, 0x7b8c, 0x0000, 0x5868, 0x4d26, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5e86, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xc5e6, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x23ab, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x2b07, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x406a, 0xd5a7, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x3289, 0x0000, 0x0000, 0x0000, 0x0000, 0x3e84, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0885, 0x1b0b, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x3d08, 0x2c26, 0x0000, 0x0000, 0x1629, 0x1d87, + 0x0000, 0x0000, 0x394c, 0x3d44, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x5e8c, 0xbc06, 0x0000, 0x5ea6, 0x0000, 0xd8e7, + 0x0000, 0x0000, 0x0d88, 0x4ac5, 0x0000, 0x0000, 0x0000, 0x0000, +}; + +} // namespace brotli + +#endif // BROTLI_ENC_DICTIONARY_HASH_H_ diff --git a/web/server/h2o/libh2o/deps/brotli/enc/encode.cc b/web/server/h2o/libh2o/deps/brotli/enc/encode.cc new file mode 100644 index 00000000..ffd31e40 --- /dev/null +++ b/web/server/h2o/libh2o/deps/brotli/enc/encode.cc @@ -0,0 +1,958 @@ +/* Copyright 2013 Google Inc. All Rights Reserved. + + Distributed under MIT license. + See file LICENSE for detail or copy at https://opensource.org/licenses/MIT +*/ + +// Implementation of Brotli compressor. + +#include "./encode.h" + +#include +#include +#include +#include + +#include "./backward_references.h" +#include "./bit_cost.h" +#include "./block_splitter.h" +#include "./brotli_bit_stream.h" +#include "./cluster.h" +#include "./context.h" +#include "./metablock.h" +#include "./transform.h" +#include "./compress_fragment.h" +#include "./compress_fragment_two_pass.h" +#include "./entropy_encode.h" +#include "./fast_log.h" +#include "./hash.h" +#include "./histogram.h" +#include "./prefix.h" +#include "./utf8_util.h" +#include "./write_bits.h" + +namespace brotli { + +static const int kMinQualityForBlockSplit = 4; +static const int kMinQualityForContextModeling = 5; +static const int kMinQualityForOptimizeHistograms = 4; +// For quality 2 there is no block splitting, so we buffer at most this much +// literals and commands. +static const int kMaxNumDelayedSymbols = 0x2fff; + +#define COPY_ARRAY(dst, src) memcpy(dst, src, sizeof(src)); + +void RecomputeDistancePrefixes(Command* cmds, + size_t num_commands, + uint32_t num_direct_distance_codes, + uint32_t distance_postfix_bits) { + if (num_direct_distance_codes == 0 && distance_postfix_bits == 0) { + return; + } + for (size_t i = 0; i < num_commands; ++i) { + Command* cmd = &cmds[i]; + if (cmd->copy_len_ > 0 && cmd->cmd_prefix_ >= 128) { + PrefixEncodeCopyDistance(cmd->DistanceCode(), + num_direct_distance_codes, + distance_postfix_bits, + &cmd->dist_prefix_, + &cmd->dist_extra_); + } + } +} + +/* Wraps 64-bit input position to 32-bit ringbuffer position preserving + "not-a-first-lap" feature. */ +uint32_t WrapPosition(uint64_t position) { + uint32_t result = static_cast(position); + if (position > (1u << 30)) { + result = (result & ((1u << 30) - 1)) | (1u << 30); + } + return result; +} + +uint8_t* BrotliCompressor::GetBrotliStorage(size_t size) { + if (storage_size_ < size) { + delete[] storage_; + storage_ = new uint8_t[size]; + storage_size_ = size; + } + return storage_; +} + +size_t MaxHashTableSize(int quality) { + return quality == 0 ? 1 << 15 : 1 << 17; +} + +size_t HashTableSize(size_t max_table_size, size_t input_size) { + size_t htsize = 256; + while (htsize < max_table_size && htsize < input_size) { + htsize <<= 1; + } + return htsize; +} + +int* BrotliCompressor::GetHashTable(int quality, + size_t input_size, + size_t* table_size) { + // Use smaller hash table when input.size() is smaller, since we + // fill the table, incurring O(hash table size) overhead for + // compression, and if the input is short, we won't need that + // many hash table entries anyway. + const size_t max_table_size = MaxHashTableSize(quality); + assert(max_table_size >= 256); + size_t htsize = HashTableSize(max_table_size, input_size); + + int* table; + if (htsize <= sizeof(small_table_) / sizeof(small_table_[0])) { + table = small_table_; + } else { + if (large_table_ == NULL) { + large_table_ = new int[max_table_size]; + } + table = large_table_; + } + + *table_size = htsize; + memset(table, 0, htsize * sizeof(*table)); + return table; +} + +void EncodeWindowBits(int lgwin, uint8_t* last_byte, uint8_t* last_byte_bits) { + if (lgwin == 16) { + *last_byte = 0; + *last_byte_bits = 1; + } else if (lgwin == 17) { + *last_byte = 1; + *last_byte_bits = 7; + } else if (lgwin > 17) { + *last_byte = static_cast(((lgwin - 17) << 1) | 1); + *last_byte_bits = 4; + } else { + *last_byte = static_cast(((lgwin - 8) << 4) | 1); + *last_byte_bits = 7; + } +} + +// Initializes the command and distance prefix codes for the first block. +void InitCommandPrefixCodes(uint8_t cmd_depths[128], + uint16_t cmd_bits[128], + uint8_t cmd_code[512], + size_t* cmd_code_numbits) { + static const uint8_t kDefaultCommandDepths[128] = { + 0, 4, 4, 5, 6, 6, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, + 0, 0, 0, 4, 4, 4, 4, 4, 5, 5, 6, 6, 6, 6, 7, 7, + 7, 7, 10, 10, 10, 10, 10, 10, 0, 4, 4, 5, 5, 5, 6, 6, + 7, 8, 8, 9, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, + 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 4, 4, 4, 4, + 4, 4, 4, 5, 5, 5, 5, 5, 5, 6, 6, 7, 7, 7, 8, 10, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + }; + static const uint16_t kDefaultCommandBits[128] = { + 0, 0, 8, 9, 3, 35, 7, 71, + 39, 103, 23, 47, 175, 111, 239, 31, + 0, 0, 0, 4, 12, 2, 10, 6, + 13, 29, 11, 43, 27, 59, 87, 55, + 15, 79, 319, 831, 191, 703, 447, 959, + 0, 14, 1, 25, 5, 21, 19, 51, + 119, 159, 95, 223, 479, 991, 63, 575, + 127, 639, 383, 895, 255, 767, 511, 1023, + 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 27, 59, 7, 39, 23, 55, 30, 1, 17, 9, 25, 5, 0, 8, 4, 12, + 2, 10, 6, 21, 13, 29, 3, 19, 11, 15, 47, 31, 95, 63, 127, 255, + 767, 2815, 1791, 3839, 511, 2559, 1535, 3583, 1023, 3071, 2047, 4095, + }; + COPY_ARRAY(cmd_depths, kDefaultCommandDepths); + COPY_ARRAY(cmd_bits, kDefaultCommandBits); + + // Initialize the pre-compressed form of the command and distance prefix + // codes. + static const uint8_t kDefaultCommandCode[] = { + 0xff, 0x77, 0xd5, 0xbf, 0xe7, 0xde, 0xea, 0x9e, 0x51, 0x5d, 0xde, 0xc6, + 0x70, 0x57, 0xbc, 0x58, 0x58, 0x58, 0xd8, 0xd8, 0x58, 0xd5, 0xcb, 0x8c, + 0xea, 0xe0, 0xc3, 0x87, 0x1f, 0x83, 0xc1, 0x60, 0x1c, 0x67, 0xb2, 0xaa, + 0x06, 0x83, 0xc1, 0x60, 0x30, 0x18, 0xcc, 0xa1, 0xce, 0x88, 0x54, 0x94, + 0x46, 0xe1, 0xb0, 0xd0, 0x4e, 0xb2, 0xf7, 0x04, 0x00, + }; + static const int kDefaultCommandCodeNumBits = 448; + COPY_ARRAY(cmd_code, kDefaultCommandCode); + *cmd_code_numbits = kDefaultCommandCodeNumBits; +} + +BrotliCompressor::BrotliCompressor(BrotliParams params) + : params_(params), + hashers_(new Hashers()), + input_pos_(0), + num_commands_(0), + num_literals_(0), + last_insert_len_(0), + last_flush_pos_(0), + last_processed_pos_(0), + prev_byte_(0), + prev_byte2_(0), + storage_size_(0), + storage_(0), + large_table_(NULL), + cmd_code_numbits_(0), + command_buf_(NULL), + literal_buf_(NULL) { + // Sanitize params. + params_.quality = std::max(0, params_.quality); + if (params_.lgwin < kMinWindowBits) { + params_.lgwin = kMinWindowBits; + } else if (params_.lgwin > kMaxWindowBits) { + params_.lgwin = kMaxWindowBits; + } + if (params_.quality <= 1) { + params_.lgblock = params_.lgwin; + } else if (params_.quality < kMinQualityForBlockSplit) { + params_.lgblock = 14; + } else if (params_.lgblock == 0) { + params_.lgblock = 16; + if (params_.quality >= 9 && params_.lgwin > params_.lgblock) { + params_.lgblock = std::min(21, params_.lgwin); + } + } else { + params_.lgblock = std::min(kMaxInputBlockBits, + std::max(kMinInputBlockBits, params_.lgblock)); + } + + // Initialize input and literal cost ring buffers. + // We allocate at least lgwin + 1 bits for the ring buffer so that the newly + // added block fits there completely and we still get lgwin bits and at least + // read_block_size_bits + 1 bits because the copy tail length needs to be + // smaller than ringbuffer size. + int ringbuffer_bits = std::max(params_.lgwin + 1, params_.lgblock + 1); + ringbuffer_ = new RingBuffer(ringbuffer_bits, params_.lgblock); + + commands_ = 0; + cmd_alloc_size_ = 0; + + // Initialize last byte with stream header. + EncodeWindowBits(params_.lgwin, &last_byte_, &last_byte_bits_); + + // Initialize distance cache. + dist_cache_[0] = 4; + dist_cache_[1] = 11; + dist_cache_[2] = 15; + dist_cache_[3] = 16; + // Save the state of the distance cache in case we need to restore it for + // emitting an uncompressed block. + memcpy(saved_dist_cache_, dist_cache_, sizeof(dist_cache_)); + + if (params_.quality == 0) { + InitCommandPrefixCodes(cmd_depths_, cmd_bits_, + cmd_code_, &cmd_code_numbits_); + } else if (params_.quality == 1) { + command_buf_ = new uint32_t[kCompressFragmentTwoPassBlockSize]; + literal_buf_ = new uint8_t[kCompressFragmentTwoPassBlockSize]; + } + + // Initialize hashers. + hash_type_ = std::min(10, params_.quality); + hashers_->Init(hash_type_); +} + +BrotliCompressor::~BrotliCompressor() { + delete[] storage_; + free(commands_); + delete ringbuffer_; + delete hashers_; + delete[] large_table_; + delete[] command_buf_; + delete[] literal_buf_; +} + +void BrotliCompressor::CopyInputToRingBuffer(const size_t input_size, + const uint8_t* input_buffer) { + ringbuffer_->Write(input_buffer, input_size); + input_pos_ += input_size; + + // TL;DR: If needed, initialize 7 more bytes in the ring buffer to make the + // hashing not depend on uninitialized data. This makes compression + // deterministic and it prevents uninitialized memory warnings in Valgrind. + // Even without erasing, the output would be valid (but nondeterministic). + // + // Background information: The compressor stores short (at most 8 bytes) + // substrings of the input already read in a hash table, and detects + // repetitions by looking up such substrings in the hash table. If it + // can find a substring, it checks whether the substring is really there + // in the ring buffer (or it's just a hash collision). Should the hash + // table become corrupt, this check makes sure that the output is + // still valid, albeit the compression ratio would be bad. + // + // The compressor populates the hash table from the ring buffer as it's + // reading new bytes from the input. However, at the last few indexes of + // the ring buffer, there are not enough bytes to build full-length + // substrings from. Since the hash table always contains full-length + // substrings, we erase with dummy 0s here to make sure that those + // substrings will contain 0s at the end instead of uninitialized + // data. + // + // Please note that erasing is not necessary (because the + // memory region is already initialized since he ring buffer + // has a `tail' that holds a copy of the beginning,) so we + // skip erasing if we have already gone around at least once in + // the ring buffer. + size_t pos = ringbuffer_->position(); + // Only clear during the first round of ringbuffer writes. On + // subsequent rounds data in the ringbuffer would be affected. + if (pos <= ringbuffer_->mask()) { + // This is the first time when the ring buffer is being written. + // We clear 7 bytes just after the bytes that have been copied from + // the input buffer. + // + // The ringbuffer has a "tail" that holds a copy of the beginning, + // but only once the ring buffer has been fully written once, i.e., + // pos <= mask. For the first time, we need to write values + // in this tail (where index may be larger than mask), so that + // we have exactly defined behavior and don't read un-initialized + // memory. Due to performance reasons, hashing reads data using a + // LOAD64, which can go 7 bytes beyond the bytes written in the + // ringbuffer. + memset(ringbuffer_->start() + pos, 0, 7); + } +} + +void BrotliCompressor::BrotliSetCustomDictionary( + const size_t size, const uint8_t* dict) { + CopyInputToRingBuffer(size, dict); + last_flush_pos_ = size; + last_processed_pos_ = size; + if (size > 0) { + prev_byte_ = dict[size - 1]; + } + if (size > 1) { + prev_byte2_ = dict[size - 2]; + } + hashers_->PrependCustomDictionary(hash_type_, params_.lgwin, size, dict); +} + +bool BrotliCompressor::WriteBrotliData(const bool is_last, + const bool force_flush, + size_t* out_size, + uint8_t** output) { + const uint64_t delta = input_pos_ - last_processed_pos_; + const uint8_t* data = ringbuffer_->start(); + const uint32_t mask = ringbuffer_->mask(); + + if (delta > input_block_size()) { + return false; + } + const uint32_t bytes = static_cast(delta); + + if (params_.quality <= 1) { + if (delta == 0 && !is_last) { + // We have no new input data and we don't have to finish the stream, so + // nothing to do. + *out_size = 0; + return true; + } + const size_t max_out_size = 2 * bytes + 500; + uint8_t* storage = GetBrotliStorage(max_out_size); + storage[0] = last_byte_; + size_t storage_ix = last_byte_bits_; + size_t table_size; + int* table = GetHashTable(params_.quality, bytes, &table_size); + if (params_.quality == 0) { + BrotliCompressFragmentFast( + &data[WrapPosition(last_processed_pos_) & mask], + bytes, is_last, + table, table_size, + cmd_depths_, cmd_bits_, + &cmd_code_numbits_, cmd_code_, + &storage_ix, storage); + } else { + BrotliCompressFragmentTwoPass( + &data[WrapPosition(last_processed_pos_) & mask], + bytes, is_last, + command_buf_, literal_buf_, + table, table_size, + &storage_ix, storage); + } + last_byte_ = storage[storage_ix >> 3]; + last_byte_bits_ = storage_ix & 7u; + last_processed_pos_ = input_pos_; + *output = &storage[0]; + *out_size = storage_ix >> 3; + return true; + } + + // Theoretical max number of commands is 1 per 2 bytes. + size_t newsize = num_commands_ + bytes / 2 + 1; + if (newsize > cmd_alloc_size_) { + // Reserve a bit more memory to allow merging with a next block + // without realloc: that would impact speed. + newsize += (bytes / 4) + 16; + cmd_alloc_size_ = newsize; + commands_ = + static_cast(realloc(commands_, sizeof(Command) * newsize)); + } + + CreateBackwardReferences(bytes, WrapPosition(last_processed_pos_), + is_last, data, mask, + params_.quality, + params_.lgwin, + hashers_, + hash_type_, + dist_cache_, + &last_insert_len_, + &commands_[num_commands_], + &num_commands_, + &num_literals_); + + size_t max_length = std::min(mask + 1, 1u << kMaxInputBlockBits); + if (!is_last && !force_flush && + (params_.quality >= kMinQualityForBlockSplit || + (num_literals_ + num_commands_ < kMaxNumDelayedSymbols)) && + input_pos_ + input_block_size() <= last_flush_pos_ + max_length) { + // Merge with next input block. Everything will happen later. + last_processed_pos_ = input_pos_; + *out_size = 0; + return true; + } + + // Create the last insert-only command. + if (last_insert_len_ > 0) { + brotli::Command cmd(last_insert_len_); + commands_[num_commands_++] = cmd; + num_literals_ += last_insert_len_; + last_insert_len_ = 0; + } + + WriteMetaBlockInternal(is_last, out_size, output); + return true; +} + +// Decide about the context map based on the ability of the prediction +// ability of the previous byte UTF8-prefix on the next byte. The +// prediction ability is calculated as shannon entropy. Here we need +// shannon entropy instead of 'BitsEntropy' since the prefix will be +// encoded with the remaining 6 bits of the following byte, and +// BitsEntropy will assume that symbol to be stored alone using Huffman +// coding. +void ChooseContextMap(int quality, + uint32_t* bigram_histo, + size_t* num_literal_contexts, + const uint32_t** literal_context_map) { + uint32_t monogram_histo[3] = { 0 }; + uint32_t two_prefix_histo[6] = { 0 }; + size_t total = 0; + for (size_t i = 0; i < 9; ++i) { + total += bigram_histo[i]; + monogram_histo[i % 3] += bigram_histo[i]; + size_t j = i; + if (j >= 6) { + j -= 6; + } + two_prefix_histo[j] += bigram_histo[i]; + } + size_t dummy; + double entropy1 = ShannonEntropy(monogram_histo, 3, &dummy); + double entropy2 = (ShannonEntropy(two_prefix_histo, 3, &dummy) + + ShannonEntropy(two_prefix_histo + 3, 3, &dummy)); + double entropy3 = 0; + for (size_t k = 0; k < 3; ++k) { + entropy3 += ShannonEntropy(bigram_histo + 3 * k, 3, &dummy); + } + + assert(total != 0); + double scale = 1.0 / static_cast(total); + entropy1 *= scale; + entropy2 *= scale; + entropy3 *= scale; + + static const uint32_t kStaticContextMapContinuation[64] = { + 1, 1, 2, 2, 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, 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, 0, 0, 0, 0, 0, 0, 0, 0, + }; + static const uint32_t kStaticContextMapSimpleUTF8[64] = { + 0, 0, 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, 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, 0, 0, 0, 0, 0, 0, 0, 0, + }; + if (quality < 7) { + // 3 context models is a bit slower, don't use it at lower qualities. + entropy3 = entropy1 * 10; + } + // If expected savings by symbol are less than 0.2 bits, skip the + // context modeling -- in exchange for faster decoding speed. + if (entropy1 - entropy2 < 0.2 && + entropy1 - entropy3 < 0.2) { + *num_literal_contexts = 1; + } else if (entropy2 - entropy3 < 0.02) { + *num_literal_contexts = 2; + *literal_context_map = kStaticContextMapSimpleUTF8; + } else { + *num_literal_contexts = 3; + *literal_context_map = kStaticContextMapContinuation; + } +} + +void DecideOverLiteralContextModeling(const uint8_t* input, + size_t start_pos, + size_t length, + size_t mask, + int quality, + ContextType* literal_context_mode, + size_t* num_literal_contexts, + const uint32_t** literal_context_map) { + if (quality < kMinQualityForContextModeling || length < 64) { + return; + } + // Gather bigram data of the UTF8 byte prefixes. To make the analysis of + // UTF8 data faster we only examine 64 byte long strides at every 4kB + // intervals. + const size_t end_pos = start_pos + length; + uint32_t bigram_prefix_histo[9] = { 0 }; + for (; start_pos + 64 <= end_pos; start_pos += 4096) { + static const int lut[4] = { 0, 0, 1, 2 }; + const size_t stride_end_pos = start_pos + 64; + int prev = lut[input[start_pos & mask] >> 6] * 3; + for (size_t pos = start_pos + 1; pos < stride_end_pos; ++pos) { + const uint8_t literal = input[pos & mask]; + ++bigram_prefix_histo[prev + lut[literal >> 6]]; + prev = lut[literal >> 6] * 3; + } + } + *literal_context_mode = CONTEXT_UTF8; + ChooseContextMap(quality, &bigram_prefix_histo[0], num_literal_contexts, + literal_context_map); +} + +void BrotliCompressor::WriteMetaBlockInternal(const bool is_last, + size_t* out_size, + uint8_t** output) { + if (!is_last && input_pos_ == last_flush_pos_) { + // We have no new input data and we don't have to finish the stream, so + // nothing to do. + *out_size = 0; + return; + } + assert(input_pos_ >= last_flush_pos_); + assert(input_pos_ > last_flush_pos_ || is_last); + assert(input_pos_ - last_flush_pos_ <= 1u << 24); + const uint32_t bytes = static_cast(input_pos_ - last_flush_pos_); + const uint8_t* data = ringbuffer_->start(); + const uint32_t mask = ringbuffer_->mask(); + const size_t max_out_size = 2 * bytes + 500; + uint8_t* storage = GetBrotliStorage(max_out_size); + storage[0] = last_byte_; + size_t storage_ix = last_byte_bits_; + + bool uncompressed = false; + if (num_commands_ < (bytes >> 8) + 2) { + if (num_literals_ > 0.99 * static_cast(bytes)) { + uint32_t literal_histo[256] = { 0 }; + static const uint32_t kSampleRate = 13; + static const double kMinEntropy = 7.92; + const double bit_cost_threshold = + static_cast(bytes) * kMinEntropy / kSampleRate; + size_t t = (bytes + kSampleRate - 1) / kSampleRate; + uint32_t pos = static_cast(last_flush_pos_); + for (size_t i = 0; i < t; i++) { + ++literal_histo[data[pos & mask]]; + pos += kSampleRate; + } + if (BitsEntropy(literal_histo, 256) > bit_cost_threshold) { + uncompressed = true; + } + } + } + + if (bytes == 0) { + // Write the ISLAST and ISEMPTY bits. + WriteBits(2, 3, &storage_ix, &storage[0]); + storage_ix = (storage_ix + 7u) & ~7u; + } else if (uncompressed) { + // Restore the distance cache, as its last update by + // CreateBackwardReferences is now unused. + memcpy(dist_cache_, saved_dist_cache_, sizeof(dist_cache_)); + StoreUncompressedMetaBlock(is_last, data, + WrapPosition(last_flush_pos_), mask, bytes, + &storage_ix, + &storage[0]); + } else { + uint32_t num_direct_distance_codes = 0; + uint32_t distance_postfix_bits = 0; + if (params_.quality > 9 && params_.mode == BrotliParams::MODE_FONT) { + num_direct_distance_codes = 12; + distance_postfix_bits = 1; + RecomputeDistancePrefixes(commands_, + num_commands_, + num_direct_distance_codes, + distance_postfix_bits); + } + if (params_.quality == 2) { + StoreMetaBlockFast(data, WrapPosition(last_flush_pos_), + bytes, mask, is_last, + commands_, num_commands_, + &storage_ix, + &storage[0]); + } else if (params_.quality < kMinQualityForBlockSplit) { + StoreMetaBlockTrivial(data, WrapPosition(last_flush_pos_), + bytes, mask, is_last, + commands_, num_commands_, + &storage_ix, + &storage[0]); + } else { + MetaBlockSplit mb; + ContextType literal_context_mode = CONTEXT_UTF8; + if (params_.quality <= 9) { + size_t num_literal_contexts = 1; + const uint32_t* literal_context_map = NULL; + DecideOverLiteralContextModeling(data, WrapPosition(last_flush_pos_), + bytes, mask, + params_.quality, + &literal_context_mode, + &num_literal_contexts, + &literal_context_map); + if (literal_context_map == NULL) { + BuildMetaBlockGreedy(data, WrapPosition(last_flush_pos_), mask, + commands_, num_commands_, + &mb); + } else { + BuildMetaBlockGreedyWithContexts(data, WrapPosition(last_flush_pos_), + mask, + prev_byte_, prev_byte2_, + literal_context_mode, + num_literal_contexts, + literal_context_map, + commands_, num_commands_, + &mb); + } + } else { + if (!IsMostlyUTF8( + data, WrapPosition(last_flush_pos_), mask, bytes, kMinUTF8Ratio)) { + literal_context_mode = CONTEXT_SIGNED; + } + BuildMetaBlock(data, WrapPosition(last_flush_pos_), mask, + prev_byte_, prev_byte2_, + commands_, num_commands_, + literal_context_mode, + &mb); + } + if (params_.quality >= kMinQualityForOptimizeHistograms) { + OptimizeHistograms(num_direct_distance_codes, + distance_postfix_bits, + &mb); + } + StoreMetaBlock(data, WrapPosition(last_flush_pos_), bytes, mask, + prev_byte_, prev_byte2_, + is_last, + num_direct_distance_codes, + distance_postfix_bits, + literal_context_mode, + commands_, num_commands_, + mb, + &storage_ix, + &storage[0]); + } + if (bytes + 4 < (storage_ix >> 3)) { + // Restore the distance cache and last byte. + memcpy(dist_cache_, saved_dist_cache_, sizeof(dist_cache_)); + storage[0] = last_byte_; + storage_ix = last_byte_bits_; + StoreUncompressedMetaBlock(is_last, data, + WrapPosition(last_flush_pos_), mask, + bytes, &storage_ix, &storage[0]); + } + } + last_byte_ = storage[storage_ix >> 3]; + last_byte_bits_ = storage_ix & 7u; + last_flush_pos_ = input_pos_; + last_processed_pos_ = input_pos_; + prev_byte_ = data[(static_cast(last_flush_pos_) - 1) & mask]; + prev_byte2_ = data[(static_cast(last_flush_pos_) - 2) & mask]; + num_commands_ = 0; + num_literals_ = 0; + // Save the state of the distance cache in case we need to restore it for + // emitting an uncompressed block. + memcpy(saved_dist_cache_, dist_cache_, sizeof(dist_cache_)); + *output = &storage[0]; + *out_size = storage_ix >> 3; +} + +bool BrotliCompressor::WriteMetaBlock(const size_t input_size, + const uint8_t* input_buffer, + const bool is_last, + size_t* encoded_size, + uint8_t* encoded_buffer) { + CopyInputToRingBuffer(input_size, input_buffer); + size_t out_size = 0; + uint8_t* output; + if (!WriteBrotliData(is_last, /* force_flush = */ true, &out_size, &output) || + out_size > *encoded_size) { + return false; + } + if (out_size > 0) { + memcpy(encoded_buffer, output, out_size); + } + *encoded_size = out_size; + return true; +} + +bool BrotliCompressor::WriteMetadata(const size_t input_size, + const uint8_t* input_buffer, + const bool is_last, + size_t* encoded_size, + uint8_t* encoded_buffer) { + if (input_size > (1 << 24) || input_size + 6 > *encoded_size) { + return false; + } + uint64_t hdr_buffer_data[2]; + uint8_t* hdr_buffer = reinterpret_cast(&hdr_buffer_data[0]); + size_t storage_ix = last_byte_bits_; + hdr_buffer[0] = last_byte_; + WriteBits(1, 0, &storage_ix, hdr_buffer); + WriteBits(2, 3, &storage_ix, hdr_buffer); + WriteBits(1, 0, &storage_ix, hdr_buffer); + if (input_size == 0) { + WriteBits(2, 0, &storage_ix, hdr_buffer); + *encoded_size = (storage_ix + 7u) >> 3; + memcpy(encoded_buffer, hdr_buffer, *encoded_size); + } else { + uint32_t nbits = (input_size == 1) ? 0 : (Log2FloorNonZero( + static_cast(input_size) - 1) + 1); + uint32_t nbytes = (nbits + 7) / 8; + WriteBits(2, nbytes, &storage_ix, hdr_buffer); + WriteBits(8 * nbytes, input_size - 1, &storage_ix, hdr_buffer); + size_t hdr_size = (storage_ix + 7u) >> 3; + memcpy(encoded_buffer, hdr_buffer, hdr_size); + memcpy(&encoded_buffer[hdr_size], input_buffer, input_size); + *encoded_size = hdr_size + input_size; + } + if (is_last) { + encoded_buffer[(*encoded_size)++] = 3; + } + last_byte_ = 0; + last_byte_bits_ = 0; + return true; +} + +bool BrotliCompressor::FinishStream( + size_t* encoded_size, uint8_t* encoded_buffer) { + return WriteMetaBlock(0, NULL, true, encoded_size, encoded_buffer); +} + +int BrotliCompressBuffer(BrotliParams params, + size_t input_size, + const uint8_t* input_buffer, + size_t* encoded_size, + uint8_t* encoded_buffer) { + if (*encoded_size == 0) { + // Output buffer needs at least one byte. + return 0; + } + BrotliMemIn in(input_buffer, input_size); + BrotliMemOut out(encoded_buffer, *encoded_size); + if (!BrotliCompress(params, &in, &out)) { + return 0; + } + *encoded_size = out.position(); + return 1; +} + +bool BrotliInIsFinished(BrotliIn* r) { + size_t read_bytes; + return r->Read(0, &read_bytes) == NULL; +} + +const uint8_t* BrotliInReadAndCheckEnd(const size_t block_size, + BrotliIn* r, + size_t* bytes_read, + bool* is_last) { + *bytes_read = 0; + const uint8_t* data = reinterpret_cast( + r->Read(block_size, bytes_read)); + assert((data == NULL) == (*bytes_read == 0)); + *is_last = BrotliInIsFinished(r); + return data; +} + +bool CopyOneBlockToRingBuffer(BrotliIn* r, + BrotliCompressor* compressor, + size_t* bytes_read, + bool* is_last) { + const size_t block_size = compressor->input_block_size(); + const uint8_t* data = BrotliInReadAndCheckEnd(block_size, r, + bytes_read, is_last); + if (data == NULL) { + return *is_last; + } + compressor->CopyInputToRingBuffer(*bytes_read, data); + + // Read more bytes until block_size is filled or an EOF (data == NULL) is + // received. This is useful to get deterministic compressed output for the + // same input no matter how r->Read splits the input to chunks. + for (size_t remaining = block_size - *bytes_read; remaining > 0; ) { + size_t more_bytes_read = 0; + data = BrotliInReadAndCheckEnd(remaining, r, &more_bytes_read, is_last); + if (data == NULL) { + return *is_last; + } + compressor->CopyInputToRingBuffer(more_bytes_read, data); + *bytes_read += more_bytes_read; + remaining -= more_bytes_read; + } + return true; +} + + +int BrotliCompress(BrotliParams params, BrotliIn* in, BrotliOut* out) { + return BrotliCompressWithCustomDictionary(0, 0, params, in, out); +} + +// Reads the provided input in 'block_size' blocks. Only the last read can be +// smaller than 'block_size'. +class BrotliBlockReader { + public: + explicit BrotliBlockReader(size_t block_size) + : block_size_(block_size), buf_(NULL) {} + ~BrotliBlockReader() { delete[] buf_; } + + const uint8_t* Read(BrotliIn* in, size_t* bytes_read, bool* is_last) { + *bytes_read = 0; + const uint8_t* data = BrotliInReadAndCheckEnd(block_size_, in, + bytes_read, is_last); + if (data == NULL || *bytes_read == block_size_ || *is_last) { + // If we could get the whole block in one read, or it is the last block, + // we just return the pointer to the data without copying. + return data; + } + // If the data comes in smaller chunks, we need to copy it into an internal + // buffer until we get a whole block or reach the last chunk. + if (buf_ == NULL) { + buf_ = new uint8_t[block_size_]; + } + memcpy(buf_, data, *bytes_read); + do { + size_t cur_bytes_read = 0; + data = BrotliInReadAndCheckEnd(block_size_ - *bytes_read, in, + &cur_bytes_read, is_last); + if (data == NULL) { + return *is_last ? buf_ : NULL; + } + memcpy(&buf_[*bytes_read], data, cur_bytes_read); + *bytes_read += cur_bytes_read; + } while (*bytes_read < block_size_ && !*is_last); + return buf_; + } + + private: + const size_t block_size_; + uint8_t* buf_; +}; + +int BrotliCompressWithCustomDictionary(size_t dictsize, const uint8_t* dict, + BrotliParams params, + BrotliIn* in, BrotliOut* out) { + if (params.quality <= 1) { + const int quality = std::max(0, params.quality); + const int lgwin = std::min(kMaxWindowBits, + std::max(kMinWindowBits, params.lgwin)); + uint8_t* storage = NULL; + int* table = NULL; + uint32_t* command_buf = NULL; + uint8_t* literal_buf = NULL; + uint8_t cmd_depths[128]; + uint16_t cmd_bits[128]; + uint8_t cmd_code[512]; + size_t cmd_code_numbits; + if (quality == 0) { + InitCommandPrefixCodes(cmd_depths, cmd_bits, cmd_code, &cmd_code_numbits); + } + uint8_t last_byte; + uint8_t last_byte_bits; + EncodeWindowBits(lgwin, &last_byte, &last_byte_bits); + BrotliBlockReader r(1u << lgwin); + int ok = 1; + bool is_last = false; + while (ok && !is_last) { + // Read next block of input. + size_t bytes; + const uint8_t* data = r.Read(in, &bytes, &is_last); + if (data == NULL) { + if (!is_last) { + ok = 0; + break; + } + assert(bytes == 0); + } + // Set up output storage. + const size_t max_out_size = 2 * bytes + 500; + if (storage == NULL) { + storage = new uint8_t[max_out_size]; + } + storage[0] = last_byte; + size_t storage_ix = last_byte_bits; + // Set up hash table. + size_t htsize = HashTableSize(MaxHashTableSize(quality), bytes); + if (table == NULL) { + table = new int[htsize]; + } + memset(table, 0, htsize * sizeof(table[0])); + // Set up command and literal buffers for two pass mode. + if (quality == 1 && command_buf == NULL) { + size_t buf_size = std::min(bytes, kCompressFragmentTwoPassBlockSize); + command_buf = new uint32_t[buf_size]; + literal_buf = new uint8_t[buf_size]; + } + // Do the actual compression. + if (quality == 0) { + BrotliCompressFragmentFast(data, bytes, is_last, table, htsize, + cmd_depths, cmd_bits, + &cmd_code_numbits, cmd_code, + &storage_ix, storage); + } else { + BrotliCompressFragmentTwoPass(data, bytes, is_last, + command_buf, literal_buf, + table, htsize, + &storage_ix, storage); + } + // Save last bytes to stitch it together with the next output block. + last_byte = storage[storage_ix >> 3]; + last_byte_bits = storage_ix & 7u; + // Write output block. + size_t out_bytes = storage_ix >> 3; + if (out_bytes > 0 && !out->Write(storage, out_bytes)) { + ok = 0; + break; + } + } + delete[] storage; + delete[] table; + delete[] command_buf; + delete[] literal_buf; + return ok; + } + + size_t in_bytes = 0; + size_t out_bytes = 0; + uint8_t* output; + bool final_block = false; + BrotliCompressor compressor(params); + if (dictsize != 0) compressor.BrotliSetCustomDictionary(dictsize, dict); + while (!final_block) { + if (!CopyOneBlockToRingBuffer(in, &compressor, &in_bytes, &final_block)) { + return false; + } + out_bytes = 0; + if (!compressor.WriteBrotliData(final_block, + /* force_flush = */ false, + &out_bytes, &output)) { + return false; + } + if (out_bytes > 0 && !out->Write(output, out_bytes)) { + return false; + } + } + return true; +} + + +} // namespace brotli diff --git a/web/server/h2o/libh2o/deps/brotli/enc/encode.h b/web/server/h2o/libh2o/deps/brotli/enc/encode.h new file mode 100644 index 00000000..167235c9 --- /dev/null +++ b/web/server/h2o/libh2o/deps/brotli/enc/encode.h @@ -0,0 +1,211 @@ +/* Copyright 2013 Google Inc. All Rights Reserved. + + Distributed under MIT license. + See file LICENSE for detail or copy at https://opensource.org/licenses/MIT +*/ + +// API for Brotli compression + +#ifndef BROTLI_ENC_ENCODE_H_ +#define BROTLI_ENC_ENCODE_H_ + +#include +#include +#include "./command.h" +#include "./hash.h" +#include "./ringbuffer.h" +#include "./static_dict.h" +#include "./streams.h" +#include "./types.h" + +namespace brotli { + +static const int kMaxWindowBits = 24; +static const int kMinWindowBits = 10; +static const int kMinInputBlockBits = 16; +static const int kMaxInputBlockBits = 24; + +struct BrotliParams { + BrotliParams() + : mode(MODE_GENERIC), + quality(11), + lgwin(22), + lgblock(0), + enable_dictionary(true), + enable_transforms(false), + greedy_block_split(false), + enable_context_modeling(true) {} + + enum Mode { + // Default compression mode. The compressor does not know anything in + // advance about the properties of the input. + MODE_GENERIC = 0, + // Compression mode for UTF-8 format text input. + MODE_TEXT = 1, + // Compression mode used in WOFF 2.0. + MODE_FONT = 2 + }; + Mode mode; + + // Controls the compression-speed vs compression-density tradeoffs. The higher + // the quality, the slower the compression. Range is 0 to 11. + int quality; + // Base 2 logarithm of the sliding window size. Range is 10 to 24. + int lgwin; + // Base 2 logarithm of the maximum input block size. Range is 16 to 24. + // If set to 0, the value will be set based on the quality. + int lgblock; + + // These settings are deprecated and will be ignored. + // All speed vs. size compromises are controlled by the quality param. + bool enable_dictionary; + bool enable_transforms; + bool greedy_block_split; + bool enable_context_modeling; +}; + +// An instance can not be reused for multiple brotli streams. +class BrotliCompressor { + public: + explicit BrotliCompressor(BrotliParams params); + ~BrotliCompressor(); + + // The maximum input size that can be processed at once. + size_t input_block_size() const { return size_t(1) << params_.lgblock; } + + // Encodes the data in input_buffer as a meta-block and writes it to + // encoded_buffer (*encoded_size should be set to the size of + // encoded_buffer) and sets *encoded_size to the number of bytes that + // was written. The input_size must be <= input_block_size(). + // Returns 0 if there was an error and 1 otherwise. + bool WriteMetaBlock(const size_t input_size, + const uint8_t* input_buffer, + const bool is_last, + size_t* encoded_size, + uint8_t* encoded_buffer); + + // Writes a metadata meta-block containing the given input to encoded_buffer. + // *encoded_size should be set to the size of the encoded_buffer. + // Sets *encoded_size to the number of bytes that was written. + // Note that the given input data will not be part of the sliding window and + // thus no backward references can be made to this data from subsequent + // metablocks. + bool WriteMetadata(const size_t input_size, + const uint8_t* input_buffer, + const bool is_last, + size_t* encoded_size, + uint8_t* encoded_buffer); + + // Writes a zero-length meta-block with end-of-input bit set to the + // internal output buffer and copies the output buffer to encoded_buffer + // (*encoded_size should be set to the size of encoded_buffer) and sets + // *encoded_size to the number of bytes written. Returns false if there was + // an error and true otherwise. + bool FinishStream(size_t* encoded_size, uint8_t* encoded_buffer); + + // Copies the given input data to the internal ring buffer of the compressor. + // No processing of the data occurs at this time and this function can be + // called multiple times before calling WriteBrotliData() to process the + // accumulated input. At most input_block_size() bytes of input data can be + // copied to the ring buffer, otherwise the next WriteBrotliData() will fail. + void CopyInputToRingBuffer(const size_t input_size, + const uint8_t* input_buffer); + + // Processes the accumulated input data and sets *out_size to the length of + // the new output meta-block, or to zero if no new output meta-block was + // created (in this case the processed input data is buffered internally). + // If *out_size is positive, *output points to the start of the output data. + // If is_last or force_flush is true, an output meta-block is always created. + // Returns false if the size of the input data is larger than + // input_block_size(). + bool WriteBrotliData(const bool is_last, const bool force_flush, + size_t* out_size, uint8_t** output); + + // Fills the new state with a dictionary for LZ77, warming up the ringbuffer, + // e.g. for custom static dictionaries for data formats. + // Not to be confused with the built-in transformable dictionary of Brotli. + // To decode, use BrotliSetCustomDictionary of the decoder with the same + // dictionary. + void BrotliSetCustomDictionary(size_t size, const uint8_t* dict); + + // No-op, but we keep it here for API backward-compatibility. + void WriteStreamHeader() {} + + private: + uint8_t* GetBrotliStorage(size_t size); + + // Allocates and clears a hash table using memory in "*this", + // stores the number of buckets in "*table_size" and returns a pointer to + // the base of the hash table. + int* GetHashTable(int quality, + size_t input_size, size_t* table_size); + + void WriteMetaBlockInternal(const bool is_last, + size_t* out_size, + uint8_t** output); + + BrotliParams params_; + Hashers* hashers_; + int hash_type_; + uint64_t input_pos_; + RingBuffer* ringbuffer_; + size_t cmd_alloc_size_; + Command* commands_; + size_t num_commands_; + size_t num_literals_; + size_t last_insert_len_; + uint64_t last_flush_pos_; + uint64_t last_processed_pos_; + int dist_cache_[4]; + int saved_dist_cache_[4]; + uint8_t last_byte_; + uint8_t last_byte_bits_; + uint8_t prev_byte_; + uint8_t prev_byte2_; + size_t storage_size_; + uint8_t* storage_; + // Hash table for quality 0 mode. + int small_table_[1 << 10]; // 2KB + int* large_table_; // Allocated only when needed + // Command and distance prefix codes (each 64 symbols, stored back-to-back) + // used for the next block in quality 0. The command prefix code is over a + // smaller alphabet with the following 64 symbols: + // 0 - 15: insert length code 0, copy length code 0 - 15, same distance + // 16 - 39: insert length code 0, copy length code 0 - 23 + // 40 - 63: insert length code 0 - 23, copy length code 0 + // Note that symbols 16 and 40 represent the same code in the full alphabet, + // but we do not use either of them in quality 0. + uint8_t cmd_depths_[128]; + uint16_t cmd_bits_[128]; + // The compressed form of the command and distance prefix codes for the next + // block in quality 0. + uint8_t cmd_code_[512]; + size_t cmd_code_numbits_; + // Command and literal buffers for quality 1. + uint32_t* command_buf_; + uint8_t* literal_buf_; +}; + +// Compresses the data in input_buffer into encoded_buffer, and sets +// *encoded_size to the compressed length. +// Returns 0 if there was an error and 1 otherwise. +int BrotliCompressBuffer(BrotliParams params, + size_t input_size, + const uint8_t* input_buffer, + size_t* encoded_size, + uint8_t* encoded_buffer); + +// Same as above, but uses the specified input and output classes instead +// of reading from and writing to pre-allocated memory buffers. +int BrotliCompress(BrotliParams params, BrotliIn* in, BrotliOut* out); + +// Before compressing the data, sets a custom LZ77 dictionary with +// BrotliCompressor::BrotliSetCustomDictionary. +int BrotliCompressWithCustomDictionary(size_t dictsize, const uint8_t* dict, + BrotliParams params, + BrotliIn* in, BrotliOut* out); + + +} // namespace brotli + +#endif // BROTLI_ENC_ENCODE_H_ diff --git a/web/server/h2o/libh2o/deps/brotli/enc/encode_parallel.cc b/web/server/h2o/libh2o/deps/brotli/enc/encode_parallel.cc new file mode 100644 index 00000000..12ea83f5 --- /dev/null +++ b/web/server/h2o/libh2o/deps/brotli/enc/encode_parallel.cc @@ -0,0 +1,279 @@ +/* Copyright 2013 Google Inc. All Rights Reserved. + + Distributed under MIT license. + See file LICENSE for detail or copy at https://opensource.org/licenses/MIT +*/ + +// Implementation of parallel Brotli compressor. + +#include "./encode_parallel.h" + +#include +#include + +#include "./backward_references.h" +#include "./bit_cost.h" +#include "./block_splitter.h" +#include "./brotli_bit_stream.h" +#include "./cluster.h" +#include "./context.h" +#include "./metablock.h" +#include "./transform.h" +#include "./entropy_encode.h" +#include "./fast_log.h" +#include "./hash.h" +#include "./histogram.h" +#include "./prefix.h" +#include "./utf8_util.h" +#include "./write_bits.h" + +namespace brotli { + +namespace { + +void RecomputeDistancePrefixes(Command* cmds, size_t num_commands, + uint32_t num_direct_distance_codes, + uint32_t distance_postfix_bits) { + if (num_direct_distance_codes == 0 && + distance_postfix_bits == 0) { + return; + } + for (size_t i = 0; i < num_commands; ++i) { + Command* cmd = &cmds[i]; + if (cmd->copy_len_ > 0 && cmd->cmd_prefix_ >= 128) { + PrefixEncodeCopyDistance(cmd->DistanceCode(), + num_direct_distance_codes, + distance_postfix_bits, + &cmd->dist_prefix_, + &cmd->dist_extra_); + } + } +} + +bool WriteMetaBlockParallel(const BrotliParams& params, + const uint32_t input_size, + const uint8_t* input_buffer, + const uint32_t prefix_size, + const uint8_t* prefix_buffer, + const bool is_first, + const bool is_last, + size_t* encoded_size, + uint8_t* encoded_buffer) { + if (input_size == 0) { + return false; + } + + // Copy prefix + next input block into a continuous area. + uint32_t input_pos = prefix_size; + // CreateBackwardReferences reads up to 3 bytes past the end of input if the + // mask points past the end of input. + // FindMatchLengthWithLimit could do another 8 bytes look-forward. + std::vector input(prefix_size + input_size + 4 + 8); + memcpy(&input[0], prefix_buffer, prefix_size); + memcpy(&input[input_pos], input_buffer, input_size); + // Since we don't have a ringbuffer, masking is a no-op. + // We use one less bit than the full range because some of the code uses + // mask + 1 as the size of the ringbuffer. + const uint32_t mask = std::numeric_limits::max() >> 1; + + uint8_t prev_byte = input_pos > 0 ? input[(input_pos - 1) & mask] : 0; + uint8_t prev_byte2 = input_pos > 1 ? input[(input_pos - 2) & mask] : 0; + + // Decide about UTF8 mode. + static const double kMinUTF8Ratio = 0.75; + bool utf8_mode = IsMostlyUTF8(&input[0], input_pos, mask, input_size, + kMinUTF8Ratio); + + // Initialize hashers. + int hash_type = std::min(10, params.quality); + Hashers* hashers = new Hashers(); + hashers->Init(hash_type); + + // Compute backward references. + size_t last_insert_len = 0; + size_t num_commands = 0; + size_t num_literals = 0; + int dist_cache[4] = { -4, -4, -4, -4 }; + Command* commands = static_cast( + malloc(sizeof(Command) * ((input_size + 1) >> 1))); + if (commands == 0) { + delete hashers; + return false; + } + CreateBackwardReferences( + input_size, input_pos, is_last, + &input[0], mask, + params.quality, + params.lgwin, + hashers, + hash_type, + dist_cache, + &last_insert_len, + commands, + &num_commands, + &num_literals); + delete hashers; + if (last_insert_len > 0) { + commands[num_commands++] = Command(last_insert_len); + num_literals += last_insert_len; + } + assert(num_commands != 0); + + // Build the meta-block. + MetaBlockSplit mb; + uint32_t num_direct_distance_codes = + params.mode == BrotliParams::MODE_FONT ? 12 : 0; + uint32_t distance_postfix_bits = + params.mode == BrotliParams::MODE_FONT ? 1 : 0; + ContextType literal_context_mode = utf8_mode ? CONTEXT_UTF8 : CONTEXT_SIGNED; + RecomputeDistancePrefixes(commands, num_commands, + num_direct_distance_codes, + distance_postfix_bits); + if (params.quality <= 9) { + BuildMetaBlockGreedy(&input[0], input_pos, mask, + commands, num_commands, + &mb); + } else { + BuildMetaBlock(&input[0], input_pos, mask, + prev_byte, prev_byte2, + commands, num_commands, + literal_context_mode, + &mb); + } + + // Set up the temporary output storage. + const size_t max_out_size = 2 * input_size + 500; + std::vector storage(max_out_size); + uint8_t first_byte = 0; + size_t first_byte_bits = 0; + if (is_first) { + if (params.lgwin == 16) { + first_byte = 0; + first_byte_bits = 1; + } else if (params.lgwin == 17) { + first_byte = 1; + first_byte_bits = 7; + } else { + first_byte = static_cast(((params.lgwin - 17) << 1) | 1); + first_byte_bits = 4; + } + } + storage[0] = static_cast(first_byte); + size_t storage_ix = first_byte_bits; + + // Store the meta-block to the temporary output. + StoreMetaBlock(&input[0], input_pos, input_size, mask, + prev_byte, prev_byte2, + is_last, + num_direct_distance_codes, + distance_postfix_bits, + literal_context_mode, + commands, num_commands, + mb, + &storage_ix, &storage[0]); + free(commands); + + // If this is not the last meta-block, store an empty metadata + // meta-block so that the meta-block will end at a byte boundary. + if (!is_last) { + StoreSyncMetaBlock(&storage_ix, &storage[0]); + } + + // If the compressed data is too large, fall back to an uncompressed + // meta-block. + size_t output_size = storage_ix >> 3; + if (input_size + 4 < output_size) { + storage[0] = static_cast(first_byte); + storage_ix = first_byte_bits; + StoreUncompressedMetaBlock(is_last, &input[0], input_pos, mask, + input_size, + &storage_ix, &storage[0]); + output_size = storage_ix >> 3; + } + + // Copy the temporary output with size-check to the output. + if (output_size > *encoded_size) { + return false; + } + memcpy(encoded_buffer, &storage[0], output_size); + *encoded_size = output_size; + return true; +} + +} // namespace + +int BrotliCompressBufferParallel(BrotliParams params, + size_t input_size, + const uint8_t* input_buffer, + size_t* encoded_size, + uint8_t* encoded_buffer) { + if (*encoded_size == 0) { + // Output buffer needs at least one byte. + return 0; + } else if (input_size == 0) { + encoded_buffer[0] = 6; + *encoded_size = 1; + return 1; + } + + // Sanitize params. + if (params.lgwin < kMinWindowBits) { + params.lgwin = kMinWindowBits; + } else if (params.lgwin > kMaxWindowBits) { + params.lgwin = kMaxWindowBits; + } + if (params.lgblock == 0) { + params.lgblock = 16; + if (params.quality >= 9 && params.lgwin > params.lgblock) { + params.lgblock = std::min(21, params.lgwin); + } + } else if (params.lgblock < kMinInputBlockBits) { + params.lgblock = kMinInputBlockBits; + } else if (params.lgblock > kMaxInputBlockBits) { + params.lgblock = kMaxInputBlockBits; + } + size_t max_input_block_size = 1 << params.lgblock; + size_t max_prefix_size = 1u << params.lgwin; + + std::vector > compressed_pieces; + + // Compress block-by-block independently. + for (size_t pos = 0; pos < input_size; ) { + uint32_t input_block_size = + static_cast(std::min(max_input_block_size, input_size - pos)); + uint32_t prefix_size = + static_cast(std::min(max_prefix_size, pos)); + size_t out_size = input_block_size + (input_block_size >> 3) + 1024; + std::vector out(out_size); + if (!WriteMetaBlockParallel(params, + input_block_size, + &input_buffer[pos], + prefix_size, + &input_buffer[pos - prefix_size], + pos == 0, + pos + input_block_size == input_size, + &out_size, + &out[0])) { + return false; + } + out.resize(out_size); + compressed_pieces.push_back(out); + pos += input_block_size; + } + + // Piece together the output. + size_t out_pos = 0; + for (size_t i = 0; i < compressed_pieces.size(); ++i) { + const std::vector& out = compressed_pieces[i]; + if (out_pos + out.size() > *encoded_size) { + return false; + } + memcpy(&encoded_buffer[out_pos], &out[0], out.size()); + out_pos += out.size(); + } + *encoded_size = out_pos; + + return true; +} + +} // namespace brotli diff --git a/web/server/h2o/libh2o/deps/brotli/enc/encode_parallel.h b/web/server/h2o/libh2o/deps/brotli/enc/encode_parallel.h new file mode 100644 index 00000000..8d637b7c --- /dev/null +++ b/web/server/h2o/libh2o/deps/brotli/enc/encode_parallel.h @@ -0,0 +1,28 @@ +/* Copyright 2013 Google Inc. All Rights Reserved. + + Distributed under MIT license. + See file LICENSE for detail or copy at https://opensource.org/licenses/MIT +*/ + +// API for parallel Brotli compression +// Note that this is only a proof of concept currently and not part of the +// final API yet. + +#ifndef BROTLI_ENC_ENCODE_PARALLEL_H_ +#define BROTLI_ENC_ENCODE_PARALLEL_H_ + + +#include "./encode.h" +#include "./types.h" + +namespace brotli { + +int BrotliCompressBufferParallel(BrotliParams params, + size_t input_size, + const uint8_t* input_buffer, + size_t* encoded_size, + uint8_t* encoded_buffer); + +} // namespace brotli + +#endif // BROTLI_ENC_ENCODE_PARALLEL_H_ diff --git a/web/server/h2o/libh2o/deps/brotli/enc/entropy_encode.cc b/web/server/h2o/libh2o/deps/brotli/enc/entropy_encode.cc new file mode 100644 index 00000000..ff5484f6 --- /dev/null +++ b/web/server/h2o/libh2o/deps/brotli/enc/entropy_encode.cc @@ -0,0 +1,469 @@ +/* Copyright 2010 Google Inc. All Rights Reserved. + + Distributed under MIT license. + See file LICENSE for detail or copy at https://opensource.org/licenses/MIT +*/ + +// Entropy encoding (Huffman) utilities. + +#include "./entropy_encode.h" + +#include +#include +#include +#include + +#include "./histogram.h" +#include "./port.h" +#include "./types.h" + +namespace brotli { + +void SetDepth(const HuffmanTree &p, + HuffmanTree *pool, + uint8_t *depth, + uint8_t level) { + if (p.index_left_ >= 0) { + ++level; + SetDepth(pool[p.index_left_], pool, depth, level); + SetDepth(pool[p.index_right_or_value_], pool, depth, level); + } else { + depth[p.index_right_or_value_] = level; + } +} + +// This function will create a Huffman tree. +// +// The catch here is that the tree cannot be arbitrarily deep. +// Brotli specifies a maximum depth of 15 bits for "code trees" +// and 7 bits for "code length code trees." +// +// count_limit is the value that is to be faked as the minimum value +// and this minimum value is raised until the tree matches the +// maximum length requirement. +// +// This algorithm is not of excellent performance for very long data blocks, +// especially when population counts are longer than 2**tree_limit, but +// we are not planning to use this with extremely long blocks. +// +// See http://en.wikipedia.org/wiki/Huffman_coding +void CreateHuffmanTree(const uint32_t *data, + const size_t length, + const int tree_limit, + uint8_t *depth) { + // For block sizes below 64 kB, we never need to do a second iteration + // of this loop. Probably all of our block sizes will be smaller than + // that, so this loop is mostly of academic interest. If we actually + // would need this, we would be better off with the Katajainen algorithm. + for (uint32_t count_limit = 1; ; count_limit *= 2) { + std::vector tree; + tree.reserve(2 * length + 1); + + for (size_t i = length; i != 0;) { + --i; + if (data[i]) { + const uint32_t count = std::max(data[i], count_limit); + tree.push_back(HuffmanTree(count, -1, static_cast(i))); + } + } + + const size_t n = tree.size(); + if (n == 1) { + depth[tree[0].index_right_or_value_] = 1; // Only one element. + break; + } + + std::stable_sort(tree.begin(), tree.end(), SortHuffmanTree); + + // The nodes are: + // [0, n): the sorted leaf nodes that we start with. + // [n]: we add a sentinel here. + // [n + 1, 2n): new parent nodes are added here, starting from + // (n+1). These are naturally in ascending order. + // [2n]: we add a sentinel at the end as well. + // There will be (2n+1) elements at the end. + const HuffmanTree sentinel(std::numeric_limits::max(), -1, -1); + tree.push_back(sentinel); + tree.push_back(sentinel); + + size_t i = 0; // Points to the next leaf node. + size_t j = n + 1; // Points to the next non-leaf node. + for (size_t k = n - 1; k != 0; --k) { + size_t left, right; + if (tree[i].total_count_ <= tree[j].total_count_) { + left = i; + ++i; + } else { + left = j; + ++j; + } + if (tree[i].total_count_ <= tree[j].total_count_) { + right = i; + ++i; + } else { + right = j; + ++j; + } + + // The sentinel node becomes the parent node. + size_t j_end = tree.size() - 1; + tree[j_end].total_count_ = + tree[left].total_count_ + tree[right].total_count_; + tree[j_end].index_left_ = static_cast(left); + tree[j_end].index_right_or_value_ = static_cast(right); + + // Add back the last sentinel node. + tree.push_back(sentinel); + } + assert(tree.size() == 2 * n + 1); + SetDepth(tree[2 * n - 1], &tree[0], depth, 0); + + // We need to pack the Huffman tree in tree_limit bits. + // If this was not successful, add fake entities to the lowest values + // and retry. + if (*std::max_element(&depth[0], &depth[length]) <= tree_limit) { + break; + } + } +} + +void Reverse(std::vector* v, size_t start, size_t end) { + --end; + while (start < end) { + uint8_t tmp = (*v)[start]; + (*v)[start] = (*v)[end]; + (*v)[end] = tmp; + ++start; + --end; + } +} + +void WriteHuffmanTreeRepetitions( + const uint8_t previous_value, + const uint8_t value, + size_t repetitions, + std::vector *tree, + std::vector *extra_bits_data) { + assert(repetitions > 0); + if (previous_value != value) { + tree->push_back(value); + extra_bits_data->push_back(0); + --repetitions; + } + if (repetitions == 7) { + tree->push_back(value); + extra_bits_data->push_back(0); + --repetitions; + } + if (repetitions < 3) { + for (size_t i = 0; i < repetitions; ++i) { + tree->push_back(value); + extra_bits_data->push_back(0); + } + } else { + repetitions -= 3; + size_t start = tree->size(); + while (true) { + tree->push_back(16); + extra_bits_data->push_back(repetitions & 0x3); + repetitions >>= 2; + if (repetitions == 0) { + break; + } + --repetitions; + } + Reverse(tree, start, tree->size()); + Reverse(extra_bits_data, start, tree->size()); + } +} + +void WriteHuffmanTreeRepetitionsZeros( + size_t repetitions, + std::vector *tree, + std::vector *extra_bits_data) { + if (repetitions == 11) { + tree->push_back(0); + extra_bits_data->push_back(0); + --repetitions; + } + if (repetitions < 3) { + for (size_t i = 0; i < repetitions; ++i) { + tree->push_back(0); + extra_bits_data->push_back(0); + } + } else { + repetitions -= 3; + size_t start = tree->size(); + while (true) { + tree->push_back(17); + extra_bits_data->push_back(repetitions & 0x7); + repetitions >>= 3; + if (repetitions == 0) { + break; + } + --repetitions; + } + Reverse(tree, start, tree->size()); + Reverse(extra_bits_data, start, tree->size()); + } +} + +bool OptimizeHuffmanCountsForRle(size_t length, uint32_t* counts) { + size_t nonzero_count = 0; + size_t stride; + size_t limit; + size_t sum; + const size_t streak_limit = 1240; + uint8_t* good_for_rle; + // Let's make the Huffman code more compatible with rle encoding. + size_t i; + for (i = 0; i < length; i++) { + if (counts[i]) { + ++nonzero_count; + } + } + if (nonzero_count < 16) { + return 1; + } + while (length != 0 && counts[length - 1] == 0) { + --length; + } + if (length == 0) { + return 1; // All zeros. + } + // Now counts[0..length - 1] does not have trailing zeros. + { + size_t nonzeros = 0; + uint32_t smallest_nonzero = 1 << 30; + for (i = 0; i < length; ++i) { + if (counts[i] != 0) { + ++nonzeros; + if (smallest_nonzero > counts[i]) { + smallest_nonzero = counts[i]; + } + } + } + if (nonzeros < 5) { + // Small histogram will model it well. + return 1; + } + size_t zeros = length - nonzeros; + if (smallest_nonzero < 4) { + if (zeros < 6) { + for (i = 1; i < length - 1; ++i) { + if (counts[i - 1] != 0 && counts[i] == 0 && counts[i + 1] != 0) { + counts[i] = 1; + } + } + } + } + if (nonzeros < 28) { + return 1; + } + } + // 2) Let's mark all population counts that already can be encoded + // with an rle code. + good_for_rle = (uint8_t*)calloc(length, 1); + if (good_for_rle == NULL) { + return 0; + } + { + // Let's not spoil any of the existing good rle codes. + // Mark any seq of 0's that is longer as 5 as a good_for_rle. + // Mark any seq of non-0's that is longer as 7 as a good_for_rle. + uint32_t symbol = counts[0]; + size_t step = 0; + for (i = 0; i <= length; ++i) { + if (i == length || counts[i] != symbol) { + if ((symbol == 0 && step >= 5) || + (symbol != 0 && step >= 7)) { + size_t k; + for (k = 0; k < step; ++k) { + good_for_rle[i - k - 1] = 1; + } + } + step = 1; + if (i != length) { + symbol = counts[i]; + } + } else { + ++step; + } + } + } + // 3) Let's replace those population counts that lead to more rle codes. + // Math here is in 24.8 fixed point representation. + stride = 0; + limit = 256 * (counts[0] + counts[1] + counts[2]) / 3 + 420; + sum = 0; + for (i = 0; i <= length; ++i) { + if (i == length || good_for_rle[i] || + (i != 0 && good_for_rle[i - 1]) || + (256 * counts[i] - limit + streak_limit) >= 2 * streak_limit) { + if (stride >= 4 || (stride >= 3 && sum == 0)) { + size_t k; + // The stride must end, collapse what we have, if we have enough (4). + size_t count = (sum + stride / 2) / stride; + if (count == 0) { + count = 1; + } + if (sum == 0) { + // Don't make an all zeros stride to be upgraded to ones. + count = 0; + } + for (k = 0; k < stride; ++k) { + // We don't want to change value at counts[i], + // that is already belonging to the next stride. Thus - 1. + counts[i - k - 1] = static_cast(count); + } + } + stride = 0; + sum = 0; + if (i < length - 2) { + // All interesting strides have a count of at least 4, + // at least when non-zeros. + limit = 256 * (counts[i] + counts[i + 1] + counts[i + 2]) / 3 + 420; + } else if (i < length) { + limit = 256 * counts[i]; + } else { + limit = 0; + } + } + ++stride; + if (i != length) { + sum += counts[i]; + if (stride >= 4) { + limit = (256 * sum + stride / 2) / stride; + } + if (stride == 4) { + limit += 120; + } + } + } + free(good_for_rle); + return 1; +} + +static void DecideOverRleUse(const uint8_t* depth, const size_t length, + bool *use_rle_for_non_zero, + bool *use_rle_for_zero) { + size_t total_reps_zero = 0; + size_t total_reps_non_zero = 0; + size_t count_reps_zero = 1; + size_t count_reps_non_zero = 1; + for (size_t i = 0; i < length;) { + const uint8_t value = depth[i]; + size_t reps = 1; + for (size_t k = i + 1; k < length && depth[k] == value; ++k) { + ++reps; + } + if (reps >= 3 && value == 0) { + total_reps_zero += reps; + ++count_reps_zero; + } + if (reps >= 4 && value != 0) { + total_reps_non_zero += reps; + ++count_reps_non_zero; + } + i += reps; + } + *use_rle_for_non_zero = total_reps_non_zero > count_reps_non_zero * 2; + *use_rle_for_zero = total_reps_zero > count_reps_zero * 2; +} + +void WriteHuffmanTree(const uint8_t* depth, + size_t length, + std::vector *tree, + std::vector *extra_bits_data) { + uint8_t previous_value = 8; + + // Throw away trailing zeros. + size_t new_length = length; + for (size_t i = 0; i < length; ++i) { + if (depth[length - i - 1] == 0) { + --new_length; + } else { + break; + } + } + + // First gather statistics on if it is a good idea to do rle. + bool use_rle_for_non_zero = false; + bool use_rle_for_zero = false; + if (length > 50) { + // Find rle coding for longer codes. + // Shorter codes seem not to benefit from rle. + DecideOverRleUse(depth, new_length, + &use_rle_for_non_zero, &use_rle_for_zero); + } + + // Actual rle coding. + for (size_t i = 0; i < new_length;) { + const uint8_t value = depth[i]; + size_t reps = 1; + if ((value != 0 && use_rle_for_non_zero) || + (value == 0 && use_rle_for_zero)) { + for (size_t k = i + 1; k < new_length && depth[k] == value; ++k) { + ++reps; + } + } + if (value == 0) { + WriteHuffmanTreeRepetitionsZeros(reps, tree, extra_bits_data); + } else { + WriteHuffmanTreeRepetitions(previous_value, + value, reps, tree, extra_bits_data); + previous_value = value; + } + i += reps; + } +} + +namespace { + +uint16_t ReverseBits(int num_bits, uint16_t bits) { + static const size_t kLut[16] = { // Pre-reversed 4-bit values. + 0x0, 0x8, 0x4, 0xc, 0x2, 0xa, 0x6, 0xe, + 0x1, 0x9, 0x5, 0xd, 0x3, 0xb, 0x7, 0xf + }; + size_t retval = kLut[bits & 0xf]; + for (int i = 4; i < num_bits; i += 4) { + retval <<= 4; + bits = static_cast(bits >> 4); + retval |= kLut[bits & 0xf]; + } + retval >>= (-num_bits & 0x3); + return static_cast(retval); +} + +} // namespace + +void ConvertBitDepthsToSymbols(const uint8_t *depth, + size_t len, + uint16_t *bits) { + // In Brotli, all bit depths are [1..15] + // 0 bit depth means that the symbol does not exist. + const int kMaxBits = 16; // 0..15 are values for bits + uint16_t bl_count[kMaxBits] = { 0 }; + { + for (size_t i = 0; i < len; ++i) { + ++bl_count[depth[i]]; + } + bl_count[0] = 0; + } + uint16_t next_code[kMaxBits]; + next_code[0] = 0; + { + int code = 0; + for (int bits = 1; bits < kMaxBits; ++bits) { + code = (code + bl_count[bits - 1]) << 1; + next_code[bits] = static_cast(code); + } + } + for (size_t i = 0; i < len; ++i) { + if (depth[i]) { + bits[i] = ReverseBits(depth[i], next_code[depth[i]]++); + } + } +} + +} // namespace brotli diff --git a/web/server/h2o/libh2o/deps/brotli/enc/entropy_encode.h b/web/server/h2o/libh2o/deps/brotli/enc/entropy_encode.h new file mode 100644 index 00000000..4b674a13 --- /dev/null +++ b/web/server/h2o/libh2o/deps/brotli/enc/entropy_encode.h @@ -0,0 +1,102 @@ +/* Copyright 2010 Google Inc. All Rights Reserved. + + Distributed under MIT license. + See file LICENSE for detail or copy at https://opensource.org/licenses/MIT +*/ + +// Entropy encoding (Huffman) utilities. + +#ifndef BROTLI_ENC_ENTROPY_ENCODE_H_ +#define BROTLI_ENC_ENTROPY_ENCODE_H_ + +#include +#include +#include "./histogram.h" +#include "./prefix.h" +#include "./types.h" + +namespace brotli { + +// A node of a Huffman tree. +struct HuffmanTree { + HuffmanTree(uint32_t count, int16_t left, int16_t right) + : total_count_(count), + index_left_(left), + index_right_or_value_(right) { + } + uint32_t total_count_; + int16_t index_left_; + int16_t index_right_or_value_; +}; + +// Sort the root nodes, least popular first. +inline bool SortHuffmanTree(const HuffmanTree &v0, const HuffmanTree &v1) { + return v0.total_count_ < v1.total_count_; +} + +void SetDepth(const HuffmanTree &p, HuffmanTree *pool, + uint8_t *depth, uint8_t level); + +// This function will create a Huffman tree. +// +// The (data,length) contains the population counts. +// The tree_limit is the maximum bit depth of the Huffman codes. +// +// The depth contains the tree, i.e., how many bits are used for +// the symbol. +// +// See http://en.wikipedia.org/wiki/Huffman_coding +void CreateHuffmanTree(const uint32_t *data, + const size_t length, + const int tree_limit, + uint8_t *depth); + +// Change the population counts in a way that the consequent +// Huffman tree compression, especially its rle-part will be more +// likely to compress this data more efficiently. +// +// length contains the size of the histogram. +// counts contains the population counts. +bool OptimizeHuffmanCountsForRle(size_t length, uint32_t* counts); + +// Write a Huffman tree from bit depths into the bitstream representation +// of a Huffman tree. The generated Huffman tree is to be compressed once +// more using a Huffman tree +void WriteHuffmanTree(const uint8_t* depth, + size_t num, + std::vector *tree, + std::vector *extra_bits_data); + +// Get the actual bit values for a tree of bit depths. +void ConvertBitDepthsToSymbols(const uint8_t *depth, + size_t len, + uint16_t *bits); + +template +struct EntropyCode { + // How many bits for symbol. + uint8_t depth_[kSize]; + // Actual bits used to represent the symbol. + uint16_t bits_[kSize]; + // How many non-zero depth. + int count_; + // First four symbols with non-zero depth. + int symbols_[4]; +}; + +static const int kCodeLengthCodes = 18; + +// Literal entropy code. +typedef EntropyCode<256> EntropyCodeLiteral; +// Prefix entropy codes. +typedef EntropyCode EntropyCodeCommand; +typedef EntropyCode EntropyCodeDistance; +typedef EntropyCode EntropyCodeBlockLength; +// Context map entropy code, 256 Huffman tree indexes + 16 run length codes. +typedef EntropyCode<272> EntropyCodeContextMap; +// Block type entropy code, 256 block types + 2 special symbols. +typedef EntropyCode<258> EntropyCodeBlockType; + +} // namespace brotli + +#endif // BROTLI_ENC_ENTROPY_ENCODE_H_ diff --git a/web/server/h2o/libh2o/deps/brotli/enc/entropy_encode_static.h b/web/server/h2o/libh2o/deps/brotli/enc/entropy_encode_static.h new file mode 100644 index 00000000..b137a8ef --- /dev/null +++ b/web/server/h2o/libh2o/deps/brotli/enc/entropy_encode_static.h @@ -0,0 +1,572 @@ +/* Copyright 2015 Google Inc. All Rights Reserved. + + Distributed under MIT license. + See file LICENSE for detail or copy at https://opensource.org/licenses/MIT +*/ + +// Static entropy codes used for faster meta-block encoding. + +#ifndef BROTLI_ENC_ENTROPY_ENCODE_STATIC_H_ +#define BROTLI_ENC_ENTROPY_ENCODE_STATIC_H_ + +#include "./prefix.h" +#include "./types.h" +#include "./write_bits.h" + +namespace brotli { + +static const uint8_t kCodeLengthDepth[18] = { + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 0, 4, 4, +}; + +static const uint8_t kStaticCommandCodeDepth[kNumCommandPrefixes] = { + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, +}; + +static const uint8_t kStaticDistanceCodeDepth[64] = { + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, +}; + +static const uint32_t kCodeLengthBits[18] = { + 0, 8, 4, 12, 2, 10, 6, 14, 1, 9, 5, 13, 3, 15, 31, 0, 11, 7, +}; + +inline void StoreStaticCodeLengthCode(size_t* storage_ix, uint8_t* storage) { + WriteBits(40, 0x000000ff55555554U, storage_ix, storage); +} + +static const uint64_t kZeroRepsBits[704] = { + 0x00000000, 0x00000000, 0x00000000, 0x00000007, 0x00000017, 0x00000027, + 0x00000037, 0x00000047, 0x00000057, 0x00000067, 0x00000077, 0x00000770, + 0x00000b87, 0x00001387, 0x00001b87, 0x00002387, 0x00002b87, 0x00003387, + 0x00003b87, 0x00000397, 0x00000b97, 0x00001397, 0x00001b97, 0x00002397, + 0x00002b97, 0x00003397, 0x00003b97, 0x000003a7, 0x00000ba7, 0x000013a7, + 0x00001ba7, 0x000023a7, 0x00002ba7, 0x000033a7, 0x00003ba7, 0x000003b7, + 0x00000bb7, 0x000013b7, 0x00001bb7, 0x000023b7, 0x00002bb7, 0x000033b7, + 0x00003bb7, 0x000003c7, 0x00000bc7, 0x000013c7, 0x00001bc7, 0x000023c7, + 0x00002bc7, 0x000033c7, 0x00003bc7, 0x000003d7, 0x00000bd7, 0x000013d7, + 0x00001bd7, 0x000023d7, 0x00002bd7, 0x000033d7, 0x00003bd7, 0x000003e7, + 0x00000be7, 0x000013e7, 0x00001be7, 0x000023e7, 0x00002be7, 0x000033e7, + 0x00003be7, 0x000003f7, 0x00000bf7, 0x000013f7, 0x00001bf7, 0x000023f7, + 0x00002bf7, 0x000033f7, 0x00003bf7, 0x0001c387, 0x0005c387, 0x0009c387, + 0x000dc387, 0x0011c387, 0x0015c387, 0x0019c387, 0x001dc387, 0x0001cb87, + 0x0005cb87, 0x0009cb87, 0x000dcb87, 0x0011cb87, 0x0015cb87, 0x0019cb87, + 0x001dcb87, 0x0001d387, 0x0005d387, 0x0009d387, 0x000dd387, 0x0011d387, + 0x0015d387, 0x0019d387, 0x001dd387, 0x0001db87, 0x0005db87, 0x0009db87, + 0x000ddb87, 0x0011db87, 0x0015db87, 0x0019db87, 0x001ddb87, 0x0001e387, + 0x0005e387, 0x0009e387, 0x000de387, 0x0011e387, 0x0015e387, 0x0019e387, + 0x001de387, 0x0001eb87, 0x0005eb87, 0x0009eb87, 0x000deb87, 0x0011eb87, + 0x0015eb87, 0x0019eb87, 0x001deb87, 0x0001f387, 0x0005f387, 0x0009f387, + 0x000df387, 0x0011f387, 0x0015f387, 0x0019f387, 0x001df387, 0x0001fb87, + 0x0005fb87, 0x0009fb87, 0x000dfb87, 0x0011fb87, 0x0015fb87, 0x0019fb87, + 0x001dfb87, 0x0001c397, 0x0005c397, 0x0009c397, 0x000dc397, 0x0011c397, + 0x0015c397, 0x0019c397, 0x001dc397, 0x0001cb97, 0x0005cb97, 0x0009cb97, + 0x000dcb97, 0x0011cb97, 0x0015cb97, 0x0019cb97, 0x001dcb97, 0x0001d397, + 0x0005d397, 0x0009d397, 0x000dd397, 0x0011d397, 0x0015d397, 0x0019d397, + 0x001dd397, 0x0001db97, 0x0005db97, 0x0009db97, 0x000ddb97, 0x0011db97, + 0x0015db97, 0x0019db97, 0x001ddb97, 0x0001e397, 0x0005e397, 0x0009e397, + 0x000de397, 0x0011e397, 0x0015e397, 0x0019e397, 0x001de397, 0x0001eb97, + 0x0005eb97, 0x0009eb97, 0x000deb97, 0x0011eb97, 0x0015eb97, 0x0019eb97, + 0x001deb97, 0x0001f397, 0x0005f397, 0x0009f397, 0x000df397, 0x0011f397, + 0x0015f397, 0x0019f397, 0x001df397, 0x0001fb97, 0x0005fb97, 0x0009fb97, + 0x000dfb97, 0x0011fb97, 0x0015fb97, 0x0019fb97, 0x001dfb97, 0x0001c3a7, + 0x0005c3a7, 0x0009c3a7, 0x000dc3a7, 0x0011c3a7, 0x0015c3a7, 0x0019c3a7, + 0x001dc3a7, 0x0001cba7, 0x0005cba7, 0x0009cba7, 0x000dcba7, 0x0011cba7, + 0x0015cba7, 0x0019cba7, 0x001dcba7, 0x0001d3a7, 0x0005d3a7, 0x0009d3a7, + 0x000dd3a7, 0x0011d3a7, 0x0015d3a7, 0x0019d3a7, 0x001dd3a7, 0x0001dba7, + 0x0005dba7, 0x0009dba7, 0x000ddba7, 0x0011dba7, 0x0015dba7, 0x0019dba7, + 0x001ddba7, 0x0001e3a7, 0x0005e3a7, 0x0009e3a7, 0x000de3a7, 0x0011e3a7, + 0x0015e3a7, 0x0019e3a7, 0x001de3a7, 0x0001eba7, 0x0005eba7, 0x0009eba7, + 0x000deba7, 0x0011eba7, 0x0015eba7, 0x0019eba7, 0x001deba7, 0x0001f3a7, + 0x0005f3a7, 0x0009f3a7, 0x000df3a7, 0x0011f3a7, 0x0015f3a7, 0x0019f3a7, + 0x001df3a7, 0x0001fba7, 0x0005fba7, 0x0009fba7, 0x000dfba7, 0x0011fba7, + 0x0015fba7, 0x0019fba7, 0x001dfba7, 0x0001c3b7, 0x0005c3b7, 0x0009c3b7, + 0x000dc3b7, 0x0011c3b7, 0x0015c3b7, 0x0019c3b7, 0x001dc3b7, 0x0001cbb7, + 0x0005cbb7, 0x0009cbb7, 0x000dcbb7, 0x0011cbb7, 0x0015cbb7, 0x0019cbb7, + 0x001dcbb7, 0x0001d3b7, 0x0005d3b7, 0x0009d3b7, 0x000dd3b7, 0x0011d3b7, + 0x0015d3b7, 0x0019d3b7, 0x001dd3b7, 0x0001dbb7, 0x0005dbb7, 0x0009dbb7, + 0x000ddbb7, 0x0011dbb7, 0x0015dbb7, 0x0019dbb7, 0x001ddbb7, 0x0001e3b7, + 0x0005e3b7, 0x0009e3b7, 0x000de3b7, 0x0011e3b7, 0x0015e3b7, 0x0019e3b7, + 0x001de3b7, 0x0001ebb7, 0x0005ebb7, 0x0009ebb7, 0x000debb7, 0x0011ebb7, + 0x0015ebb7, 0x0019ebb7, 0x001debb7, 0x0001f3b7, 0x0005f3b7, 0x0009f3b7, + 0x000df3b7, 0x0011f3b7, 0x0015f3b7, 0x0019f3b7, 0x001df3b7, 0x0001fbb7, + 0x0005fbb7, 0x0009fbb7, 0x000dfbb7, 0x0011fbb7, 0x0015fbb7, 0x0019fbb7, + 0x001dfbb7, 0x0001c3c7, 0x0005c3c7, 0x0009c3c7, 0x000dc3c7, 0x0011c3c7, + 0x0015c3c7, 0x0019c3c7, 0x001dc3c7, 0x0001cbc7, 0x0005cbc7, 0x0009cbc7, + 0x000dcbc7, 0x0011cbc7, 0x0015cbc7, 0x0019cbc7, 0x001dcbc7, 0x0001d3c7, + 0x0005d3c7, 0x0009d3c7, 0x000dd3c7, 0x0011d3c7, 0x0015d3c7, 0x0019d3c7, + 0x001dd3c7, 0x0001dbc7, 0x0005dbc7, 0x0009dbc7, 0x000ddbc7, 0x0011dbc7, + 0x0015dbc7, 0x0019dbc7, 0x001ddbc7, 0x0001e3c7, 0x0005e3c7, 0x0009e3c7, + 0x000de3c7, 0x0011e3c7, 0x0015e3c7, 0x0019e3c7, 0x001de3c7, 0x0001ebc7, + 0x0005ebc7, 0x0009ebc7, 0x000debc7, 0x0011ebc7, 0x0015ebc7, 0x0019ebc7, + 0x001debc7, 0x0001f3c7, 0x0005f3c7, 0x0009f3c7, 0x000df3c7, 0x0011f3c7, + 0x0015f3c7, 0x0019f3c7, 0x001df3c7, 0x0001fbc7, 0x0005fbc7, 0x0009fbc7, + 0x000dfbc7, 0x0011fbc7, 0x0015fbc7, 0x0019fbc7, 0x001dfbc7, 0x0001c3d7, + 0x0005c3d7, 0x0009c3d7, 0x000dc3d7, 0x0011c3d7, 0x0015c3d7, 0x0019c3d7, + 0x001dc3d7, 0x0001cbd7, 0x0005cbd7, 0x0009cbd7, 0x000dcbd7, 0x0011cbd7, + 0x0015cbd7, 0x0019cbd7, 0x001dcbd7, 0x0001d3d7, 0x0005d3d7, 0x0009d3d7, + 0x000dd3d7, 0x0011d3d7, 0x0015d3d7, 0x0019d3d7, 0x001dd3d7, 0x0001dbd7, + 0x0005dbd7, 0x0009dbd7, 0x000ddbd7, 0x0011dbd7, 0x0015dbd7, 0x0019dbd7, + 0x001ddbd7, 0x0001e3d7, 0x0005e3d7, 0x0009e3d7, 0x000de3d7, 0x0011e3d7, + 0x0015e3d7, 0x0019e3d7, 0x001de3d7, 0x0001ebd7, 0x0005ebd7, 0x0009ebd7, + 0x000debd7, 0x0011ebd7, 0x0015ebd7, 0x0019ebd7, 0x001debd7, 0x0001f3d7, + 0x0005f3d7, 0x0009f3d7, 0x000df3d7, 0x0011f3d7, 0x0015f3d7, 0x0019f3d7, + 0x001df3d7, 0x0001fbd7, 0x0005fbd7, 0x0009fbd7, 0x000dfbd7, 0x0011fbd7, + 0x0015fbd7, 0x0019fbd7, 0x001dfbd7, 0x0001c3e7, 0x0005c3e7, 0x0009c3e7, + 0x000dc3e7, 0x0011c3e7, 0x0015c3e7, 0x0019c3e7, 0x001dc3e7, 0x0001cbe7, + 0x0005cbe7, 0x0009cbe7, 0x000dcbe7, 0x0011cbe7, 0x0015cbe7, 0x0019cbe7, + 0x001dcbe7, 0x0001d3e7, 0x0005d3e7, 0x0009d3e7, 0x000dd3e7, 0x0011d3e7, + 0x0015d3e7, 0x0019d3e7, 0x001dd3e7, 0x0001dbe7, 0x0005dbe7, 0x0009dbe7, + 0x000ddbe7, 0x0011dbe7, 0x0015dbe7, 0x0019dbe7, 0x001ddbe7, 0x0001e3e7, + 0x0005e3e7, 0x0009e3e7, 0x000de3e7, 0x0011e3e7, 0x0015e3e7, 0x0019e3e7, + 0x001de3e7, 0x0001ebe7, 0x0005ebe7, 0x0009ebe7, 0x000debe7, 0x0011ebe7, + 0x0015ebe7, 0x0019ebe7, 0x001debe7, 0x0001f3e7, 0x0005f3e7, 0x0009f3e7, + 0x000df3e7, 0x0011f3e7, 0x0015f3e7, 0x0019f3e7, 0x001df3e7, 0x0001fbe7, + 0x0005fbe7, 0x0009fbe7, 0x000dfbe7, 0x0011fbe7, 0x0015fbe7, 0x0019fbe7, + 0x001dfbe7, 0x0001c3f7, 0x0005c3f7, 0x0009c3f7, 0x000dc3f7, 0x0011c3f7, + 0x0015c3f7, 0x0019c3f7, 0x001dc3f7, 0x0001cbf7, 0x0005cbf7, 0x0009cbf7, + 0x000dcbf7, 0x0011cbf7, 0x0015cbf7, 0x0019cbf7, 0x001dcbf7, 0x0001d3f7, + 0x0005d3f7, 0x0009d3f7, 0x000dd3f7, 0x0011d3f7, 0x0015d3f7, 0x0019d3f7, + 0x001dd3f7, 0x0001dbf7, 0x0005dbf7, 0x0009dbf7, 0x000ddbf7, 0x0011dbf7, + 0x0015dbf7, 0x0019dbf7, 0x001ddbf7, 0x0001e3f7, 0x0005e3f7, 0x0009e3f7, + 0x000de3f7, 0x0011e3f7, 0x0015e3f7, 0x0019e3f7, 0x001de3f7, 0x0001ebf7, + 0x0005ebf7, 0x0009ebf7, 0x000debf7, 0x0011ebf7, 0x0015ebf7, 0x0019ebf7, + 0x001debf7, 0x0001f3f7, 0x0005f3f7, 0x0009f3f7, 0x000df3f7, 0x0011f3f7, + 0x0015f3f7, 0x0019f3f7, 0x001df3f7, 0x0001fbf7, 0x0005fbf7, 0x0009fbf7, + 0x000dfbf7, 0x0011fbf7, 0x0015fbf7, 0x0019fbf7, 0x001dfbf7, 0x00e1c387, + 0x02e1c387, 0x04e1c387, 0x06e1c387, 0x08e1c387, 0x0ae1c387, 0x0ce1c387, + 0x0ee1c387, 0x00e5c387, 0x02e5c387, 0x04e5c387, 0x06e5c387, 0x08e5c387, + 0x0ae5c387, 0x0ce5c387, 0x0ee5c387, 0x00e9c387, 0x02e9c387, 0x04e9c387, + 0x06e9c387, 0x08e9c387, 0x0ae9c387, 0x0ce9c387, 0x0ee9c387, 0x00edc387, + 0x02edc387, 0x04edc387, 0x06edc387, 0x08edc387, 0x0aedc387, 0x0cedc387, + 0x0eedc387, 0x00f1c387, 0x02f1c387, 0x04f1c387, 0x06f1c387, 0x08f1c387, + 0x0af1c387, 0x0cf1c387, 0x0ef1c387, 0x00f5c387, 0x02f5c387, 0x04f5c387, + 0x06f5c387, 0x08f5c387, 0x0af5c387, 0x0cf5c387, 0x0ef5c387, 0x00f9c387, + 0x02f9c387, 0x04f9c387, 0x06f9c387, 0x08f9c387, 0x0af9c387, 0x0cf9c387, + 0x0ef9c387, 0x00fdc387, 0x02fdc387, 0x04fdc387, 0x06fdc387, 0x08fdc387, + 0x0afdc387, 0x0cfdc387, 0x0efdc387, 0x00e1cb87, 0x02e1cb87, 0x04e1cb87, + 0x06e1cb87, 0x08e1cb87, 0x0ae1cb87, 0x0ce1cb87, 0x0ee1cb87, 0x00e5cb87, + 0x02e5cb87, 0x04e5cb87, 0x06e5cb87, 0x08e5cb87, 0x0ae5cb87, 0x0ce5cb87, + 0x0ee5cb87, 0x00e9cb87, 0x02e9cb87, 0x04e9cb87, 0x06e9cb87, 0x08e9cb87, + 0x0ae9cb87, 0x0ce9cb87, 0x0ee9cb87, 0x00edcb87, 0x02edcb87, 0x04edcb87, + 0x06edcb87, 0x08edcb87, 0x0aedcb87, 0x0cedcb87, 0x0eedcb87, 0x00f1cb87, + 0x02f1cb87, 0x04f1cb87, 0x06f1cb87, 0x08f1cb87, 0x0af1cb87, 0x0cf1cb87, + 0x0ef1cb87, 0x00f5cb87, 0x02f5cb87, 0x04f5cb87, 0x06f5cb87, 0x08f5cb87, + 0x0af5cb87, 0x0cf5cb87, 0x0ef5cb87, 0x00f9cb87, 0x02f9cb87, 0x04f9cb87, + 0x06f9cb87, 0x08f9cb87, +}; + +static const uint32_t kZeroRepsDepth[704] = { + 0, 4, 8, 7, 7, 7, 7, 7, 7, 7, 7, 11, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 28, 28, 28, 28, 28, + 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, + 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, + 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, + 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, + 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, + 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, + 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, +}; + +static const uint64_t kNonZeroRepsBits[704] = { + 0x0000000b, 0x0000001b, 0x0000002b, 0x0000003b, 0x000002cb, 0x000006cb, + 0x00000acb, 0x00000ecb, 0x000002db, 0x000006db, 0x00000adb, 0x00000edb, + 0x000002eb, 0x000006eb, 0x00000aeb, 0x00000eeb, 0x000002fb, 0x000006fb, + 0x00000afb, 0x00000efb, 0x0000b2cb, 0x0001b2cb, 0x0002b2cb, 0x0003b2cb, + 0x0000b6cb, 0x0001b6cb, 0x0002b6cb, 0x0003b6cb, 0x0000bacb, 0x0001bacb, + 0x0002bacb, 0x0003bacb, 0x0000becb, 0x0001becb, 0x0002becb, 0x0003becb, + 0x0000b2db, 0x0001b2db, 0x0002b2db, 0x0003b2db, 0x0000b6db, 0x0001b6db, + 0x0002b6db, 0x0003b6db, 0x0000badb, 0x0001badb, 0x0002badb, 0x0003badb, + 0x0000bedb, 0x0001bedb, 0x0002bedb, 0x0003bedb, 0x0000b2eb, 0x0001b2eb, + 0x0002b2eb, 0x0003b2eb, 0x0000b6eb, 0x0001b6eb, 0x0002b6eb, 0x0003b6eb, + 0x0000baeb, 0x0001baeb, 0x0002baeb, 0x0003baeb, 0x0000beeb, 0x0001beeb, + 0x0002beeb, 0x0003beeb, 0x0000b2fb, 0x0001b2fb, 0x0002b2fb, 0x0003b2fb, + 0x0000b6fb, 0x0001b6fb, 0x0002b6fb, 0x0003b6fb, 0x0000bafb, 0x0001bafb, + 0x0002bafb, 0x0003bafb, 0x0000befb, 0x0001befb, 0x0002befb, 0x0003befb, + 0x002cb2cb, 0x006cb2cb, 0x00acb2cb, 0x00ecb2cb, 0x002db2cb, 0x006db2cb, + 0x00adb2cb, 0x00edb2cb, 0x002eb2cb, 0x006eb2cb, 0x00aeb2cb, 0x00eeb2cb, + 0x002fb2cb, 0x006fb2cb, 0x00afb2cb, 0x00efb2cb, 0x002cb6cb, 0x006cb6cb, + 0x00acb6cb, 0x00ecb6cb, 0x002db6cb, 0x006db6cb, 0x00adb6cb, 0x00edb6cb, + 0x002eb6cb, 0x006eb6cb, 0x00aeb6cb, 0x00eeb6cb, 0x002fb6cb, 0x006fb6cb, + 0x00afb6cb, 0x00efb6cb, 0x002cbacb, 0x006cbacb, 0x00acbacb, 0x00ecbacb, + 0x002dbacb, 0x006dbacb, 0x00adbacb, 0x00edbacb, 0x002ebacb, 0x006ebacb, + 0x00aebacb, 0x00eebacb, 0x002fbacb, 0x006fbacb, 0x00afbacb, 0x00efbacb, + 0x002cbecb, 0x006cbecb, 0x00acbecb, 0x00ecbecb, 0x002dbecb, 0x006dbecb, + 0x00adbecb, 0x00edbecb, 0x002ebecb, 0x006ebecb, 0x00aebecb, 0x00eebecb, + 0x002fbecb, 0x006fbecb, 0x00afbecb, 0x00efbecb, 0x002cb2db, 0x006cb2db, + 0x00acb2db, 0x00ecb2db, 0x002db2db, 0x006db2db, 0x00adb2db, 0x00edb2db, + 0x002eb2db, 0x006eb2db, 0x00aeb2db, 0x00eeb2db, 0x002fb2db, 0x006fb2db, + 0x00afb2db, 0x00efb2db, 0x002cb6db, 0x006cb6db, 0x00acb6db, 0x00ecb6db, + 0x002db6db, 0x006db6db, 0x00adb6db, 0x00edb6db, 0x002eb6db, 0x006eb6db, + 0x00aeb6db, 0x00eeb6db, 0x002fb6db, 0x006fb6db, 0x00afb6db, 0x00efb6db, + 0x002cbadb, 0x006cbadb, 0x00acbadb, 0x00ecbadb, 0x002dbadb, 0x006dbadb, + 0x00adbadb, 0x00edbadb, 0x002ebadb, 0x006ebadb, 0x00aebadb, 0x00eebadb, + 0x002fbadb, 0x006fbadb, 0x00afbadb, 0x00efbadb, 0x002cbedb, 0x006cbedb, + 0x00acbedb, 0x00ecbedb, 0x002dbedb, 0x006dbedb, 0x00adbedb, 0x00edbedb, + 0x002ebedb, 0x006ebedb, 0x00aebedb, 0x00eebedb, 0x002fbedb, 0x006fbedb, + 0x00afbedb, 0x00efbedb, 0x002cb2eb, 0x006cb2eb, 0x00acb2eb, 0x00ecb2eb, + 0x002db2eb, 0x006db2eb, 0x00adb2eb, 0x00edb2eb, 0x002eb2eb, 0x006eb2eb, + 0x00aeb2eb, 0x00eeb2eb, 0x002fb2eb, 0x006fb2eb, 0x00afb2eb, 0x00efb2eb, + 0x002cb6eb, 0x006cb6eb, 0x00acb6eb, 0x00ecb6eb, 0x002db6eb, 0x006db6eb, + 0x00adb6eb, 0x00edb6eb, 0x002eb6eb, 0x006eb6eb, 0x00aeb6eb, 0x00eeb6eb, + 0x002fb6eb, 0x006fb6eb, 0x00afb6eb, 0x00efb6eb, 0x002cbaeb, 0x006cbaeb, + 0x00acbaeb, 0x00ecbaeb, 0x002dbaeb, 0x006dbaeb, 0x00adbaeb, 0x00edbaeb, + 0x002ebaeb, 0x006ebaeb, 0x00aebaeb, 0x00eebaeb, 0x002fbaeb, 0x006fbaeb, + 0x00afbaeb, 0x00efbaeb, 0x002cbeeb, 0x006cbeeb, 0x00acbeeb, 0x00ecbeeb, + 0x002dbeeb, 0x006dbeeb, 0x00adbeeb, 0x00edbeeb, 0x002ebeeb, 0x006ebeeb, + 0x00aebeeb, 0x00eebeeb, 0x002fbeeb, 0x006fbeeb, 0x00afbeeb, 0x00efbeeb, + 0x002cb2fb, 0x006cb2fb, 0x00acb2fb, 0x00ecb2fb, 0x002db2fb, 0x006db2fb, + 0x00adb2fb, 0x00edb2fb, 0x002eb2fb, 0x006eb2fb, 0x00aeb2fb, 0x00eeb2fb, + 0x002fb2fb, 0x006fb2fb, 0x00afb2fb, 0x00efb2fb, 0x002cb6fb, 0x006cb6fb, + 0x00acb6fb, 0x00ecb6fb, 0x002db6fb, 0x006db6fb, 0x00adb6fb, 0x00edb6fb, + 0x002eb6fb, 0x006eb6fb, 0x00aeb6fb, 0x00eeb6fb, 0x002fb6fb, 0x006fb6fb, + 0x00afb6fb, 0x00efb6fb, 0x002cbafb, 0x006cbafb, 0x00acbafb, 0x00ecbafb, + 0x002dbafb, 0x006dbafb, 0x00adbafb, 0x00edbafb, 0x002ebafb, 0x006ebafb, + 0x00aebafb, 0x00eebafb, 0x002fbafb, 0x006fbafb, 0x00afbafb, 0x00efbafb, + 0x002cbefb, 0x006cbefb, 0x00acbefb, 0x00ecbefb, 0x002dbefb, 0x006dbefb, + 0x00adbefb, 0x00edbefb, 0x002ebefb, 0x006ebefb, 0x00aebefb, 0x00eebefb, + 0x002fbefb, 0x006fbefb, 0x00afbefb, 0x00efbefb, 0x0b2cb2cb, 0x1b2cb2cb, + 0x2b2cb2cb, 0x3b2cb2cb, 0x0b6cb2cb, 0x1b6cb2cb, 0x2b6cb2cb, 0x3b6cb2cb, + 0x0bacb2cb, 0x1bacb2cb, 0x2bacb2cb, 0x3bacb2cb, 0x0becb2cb, 0x1becb2cb, + 0x2becb2cb, 0x3becb2cb, 0x0b2db2cb, 0x1b2db2cb, 0x2b2db2cb, 0x3b2db2cb, + 0x0b6db2cb, 0x1b6db2cb, 0x2b6db2cb, 0x3b6db2cb, 0x0badb2cb, 0x1badb2cb, + 0x2badb2cb, 0x3badb2cb, 0x0bedb2cb, 0x1bedb2cb, 0x2bedb2cb, 0x3bedb2cb, + 0x0b2eb2cb, 0x1b2eb2cb, 0x2b2eb2cb, 0x3b2eb2cb, 0x0b6eb2cb, 0x1b6eb2cb, + 0x2b6eb2cb, 0x3b6eb2cb, 0x0baeb2cb, 0x1baeb2cb, 0x2baeb2cb, 0x3baeb2cb, + 0x0beeb2cb, 0x1beeb2cb, 0x2beeb2cb, 0x3beeb2cb, 0x0b2fb2cb, 0x1b2fb2cb, + 0x2b2fb2cb, 0x3b2fb2cb, 0x0b6fb2cb, 0x1b6fb2cb, 0x2b6fb2cb, 0x3b6fb2cb, + 0x0bafb2cb, 0x1bafb2cb, 0x2bafb2cb, 0x3bafb2cb, 0x0befb2cb, 0x1befb2cb, + 0x2befb2cb, 0x3befb2cb, 0x0b2cb6cb, 0x1b2cb6cb, 0x2b2cb6cb, 0x3b2cb6cb, + 0x0b6cb6cb, 0x1b6cb6cb, 0x2b6cb6cb, 0x3b6cb6cb, 0x0bacb6cb, 0x1bacb6cb, + 0x2bacb6cb, 0x3bacb6cb, 0x0becb6cb, 0x1becb6cb, 0x2becb6cb, 0x3becb6cb, + 0x0b2db6cb, 0x1b2db6cb, 0x2b2db6cb, 0x3b2db6cb, 0x0b6db6cb, 0x1b6db6cb, + 0x2b6db6cb, 0x3b6db6cb, 0x0badb6cb, 0x1badb6cb, 0x2badb6cb, 0x3badb6cb, + 0x0bedb6cb, 0x1bedb6cb, 0x2bedb6cb, 0x3bedb6cb, 0x0b2eb6cb, 0x1b2eb6cb, + 0x2b2eb6cb, 0x3b2eb6cb, 0x0b6eb6cb, 0x1b6eb6cb, 0x2b6eb6cb, 0x3b6eb6cb, + 0x0baeb6cb, 0x1baeb6cb, 0x2baeb6cb, 0x3baeb6cb, 0x0beeb6cb, 0x1beeb6cb, + 0x2beeb6cb, 0x3beeb6cb, 0x0b2fb6cb, 0x1b2fb6cb, 0x2b2fb6cb, 0x3b2fb6cb, + 0x0b6fb6cb, 0x1b6fb6cb, 0x2b6fb6cb, 0x3b6fb6cb, 0x0bafb6cb, 0x1bafb6cb, + 0x2bafb6cb, 0x3bafb6cb, 0x0befb6cb, 0x1befb6cb, 0x2befb6cb, 0x3befb6cb, + 0x0b2cbacb, 0x1b2cbacb, 0x2b2cbacb, 0x3b2cbacb, 0x0b6cbacb, 0x1b6cbacb, + 0x2b6cbacb, 0x3b6cbacb, 0x0bacbacb, 0x1bacbacb, 0x2bacbacb, 0x3bacbacb, + 0x0becbacb, 0x1becbacb, 0x2becbacb, 0x3becbacb, 0x0b2dbacb, 0x1b2dbacb, + 0x2b2dbacb, 0x3b2dbacb, 0x0b6dbacb, 0x1b6dbacb, 0x2b6dbacb, 0x3b6dbacb, + 0x0badbacb, 0x1badbacb, 0x2badbacb, 0x3badbacb, 0x0bedbacb, 0x1bedbacb, + 0x2bedbacb, 0x3bedbacb, 0x0b2ebacb, 0x1b2ebacb, 0x2b2ebacb, 0x3b2ebacb, + 0x0b6ebacb, 0x1b6ebacb, 0x2b6ebacb, 0x3b6ebacb, 0x0baebacb, 0x1baebacb, + 0x2baebacb, 0x3baebacb, 0x0beebacb, 0x1beebacb, 0x2beebacb, 0x3beebacb, + 0x0b2fbacb, 0x1b2fbacb, 0x2b2fbacb, 0x3b2fbacb, 0x0b6fbacb, 0x1b6fbacb, + 0x2b6fbacb, 0x3b6fbacb, 0x0bafbacb, 0x1bafbacb, 0x2bafbacb, 0x3bafbacb, + 0x0befbacb, 0x1befbacb, 0x2befbacb, 0x3befbacb, 0x0b2cbecb, 0x1b2cbecb, + 0x2b2cbecb, 0x3b2cbecb, 0x0b6cbecb, 0x1b6cbecb, 0x2b6cbecb, 0x3b6cbecb, + 0x0bacbecb, 0x1bacbecb, 0x2bacbecb, 0x3bacbecb, 0x0becbecb, 0x1becbecb, + 0x2becbecb, 0x3becbecb, 0x0b2dbecb, 0x1b2dbecb, 0x2b2dbecb, 0x3b2dbecb, + 0x0b6dbecb, 0x1b6dbecb, 0x2b6dbecb, 0x3b6dbecb, 0x0badbecb, 0x1badbecb, + 0x2badbecb, 0x3badbecb, 0x0bedbecb, 0x1bedbecb, 0x2bedbecb, 0x3bedbecb, + 0x0b2ebecb, 0x1b2ebecb, 0x2b2ebecb, 0x3b2ebecb, 0x0b6ebecb, 0x1b6ebecb, + 0x2b6ebecb, 0x3b6ebecb, 0x0baebecb, 0x1baebecb, 0x2baebecb, 0x3baebecb, + 0x0beebecb, 0x1beebecb, 0x2beebecb, 0x3beebecb, 0x0b2fbecb, 0x1b2fbecb, + 0x2b2fbecb, 0x3b2fbecb, 0x0b6fbecb, 0x1b6fbecb, 0x2b6fbecb, 0x3b6fbecb, + 0x0bafbecb, 0x1bafbecb, 0x2bafbecb, 0x3bafbecb, 0x0befbecb, 0x1befbecb, + 0x2befbecb, 0x3befbecb, 0x0b2cb2db, 0x1b2cb2db, 0x2b2cb2db, 0x3b2cb2db, + 0x0b6cb2db, 0x1b6cb2db, 0x2b6cb2db, 0x3b6cb2db, 0x0bacb2db, 0x1bacb2db, + 0x2bacb2db, 0x3bacb2db, 0x0becb2db, 0x1becb2db, 0x2becb2db, 0x3becb2db, + 0x0b2db2db, 0x1b2db2db, 0x2b2db2db, 0x3b2db2db, 0x0b6db2db, 0x1b6db2db, + 0x2b6db2db, 0x3b6db2db, 0x0badb2db, 0x1badb2db, 0x2badb2db, 0x3badb2db, + 0x0bedb2db, 0x1bedb2db, 0x2bedb2db, 0x3bedb2db, 0x0b2eb2db, 0x1b2eb2db, + 0x2b2eb2db, 0x3b2eb2db, 0x0b6eb2db, 0x1b6eb2db, 0x2b6eb2db, 0x3b6eb2db, + 0x0baeb2db, 0x1baeb2db, 0x2baeb2db, 0x3baeb2db, 0x0beeb2db, 0x1beeb2db, + 0x2beeb2db, 0x3beeb2db, 0x0b2fb2db, 0x1b2fb2db, 0x2b2fb2db, 0x3b2fb2db, + 0x0b6fb2db, 0x1b6fb2db, 0x2b6fb2db, 0x3b6fb2db, 0x0bafb2db, 0x1bafb2db, + 0x2bafb2db, 0x3bafb2db, 0x0befb2db, 0x1befb2db, 0x2befb2db, 0x3befb2db, + 0x0b2cb6db, 0x1b2cb6db, 0x2b2cb6db, 0x3b2cb6db, 0x0b6cb6db, 0x1b6cb6db, + 0x2b6cb6db, 0x3b6cb6db, 0x0bacb6db, 0x1bacb6db, 0x2bacb6db, 0x3bacb6db, + 0x0becb6db, 0x1becb6db, 0x2becb6db, 0x3becb6db, 0x0b2db6db, 0x1b2db6db, + 0x2b2db6db, 0x3b2db6db, 0x0b6db6db, 0x1b6db6db, 0x2b6db6db, 0x3b6db6db, + 0x0badb6db, 0x1badb6db, 0x2badb6db, 0x3badb6db, 0x0bedb6db, 0x1bedb6db, + 0x2bedb6db, 0x3bedb6db, 0x0b2eb6db, 0x1b2eb6db, 0x2b2eb6db, 0x3b2eb6db, + 0x0b6eb6db, 0x1b6eb6db, 0x2b6eb6db, 0x3b6eb6db, 0x0baeb6db, 0x1baeb6db, + 0x2baeb6db, 0x3baeb6db, +}; + +static const uint32_t kNonZeroRepsDepth[704] = { + 6, 6, 6, 6, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, + 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, + 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, + 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, + 18, 18, 18, 18, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, +}; + +static const uint16_t kStaticLiteralCodeBits[256] = { + 0, 128, 64, 192, 32, 160, 96, 224, + 16, 144, 80, 208, 48, 176, 112, 240, + 8, 136, 72, 200, 40, 168, 104, 232, + 24, 152, 88, 216, 56, 184, 120, 248, + 4, 132, 68, 196, 36, 164, 100, 228, + 20, 148, 84, 212, 52, 180, 116, 244, + 12, 140, 76, 204, 44, 172, 108, 236, + 28, 156, 92, 220, 60, 188, 124, 252, + 2, 130, 66, 194, 34, 162, 98, 226, + 18, 146, 82, 210, 50, 178, 114, 242, + 10, 138, 74, 202, 42, 170, 106, 234, + 26, 154, 90, 218, 58, 186, 122, 250, + 6, 134, 70, 198, 38, 166, 102, 230, + 22, 150, 86, 214, 54, 182, 118, 246, + 14, 142, 78, 206, 46, 174, 110, 238, + 30, 158, 94, 222, 62, 190, 126, 254, + 1, 129, 65, 193, 33, 161, 97, 225, + 17, 145, 81, 209, 49, 177, 113, 241, + 9, 137, 73, 201, 41, 169, 105, 233, + 25, 153, 89, 217, 57, 185, 121, 249, + 5, 133, 69, 197, 37, 165, 101, 229, + 21, 149, 85, 213, 53, 181, 117, 245, + 13, 141, 77, 205, 45, 173, 109, 237, + 29, 157, 93, 221, 61, 189, 125, 253, + 3, 131, 67, 195, 35, 163, 99, 227, + 19, 147, 83, 211, 51, 179, 115, 243, + 11, 139, 75, 203, 43, 171, 107, 235, + 27, 155, 91, 219, 59, 187, 123, 251, + 7, 135, 71, 199, 39, 167, 103, 231, + 23, 151, 87, 215, 55, 183, 119, 247, + 15, 143, 79, 207, 47, 175, 111, 239, + 31, 159, 95, 223, 63, 191, 127, 255, +}; + +inline void StoreStaticLiteralHuffmanTree(size_t* storage_ix, + uint8_t* storage) { + WriteBits(32, 0x00010003U, storage_ix, storage); +} + +static const uint16_t kStaticCommandCodeBits[kNumCommandPrefixes] = { + 0, 256, 128, 384, 64, 320, 192, 448, + 32, 288, 160, 416, 96, 352, 224, 480, + 16, 272, 144, 400, 80, 336, 208, 464, + 48, 304, 176, 432, 112, 368, 240, 496, + 8, 264, 136, 392, 72, 328, 200, 456, + 40, 296, 168, 424, 104, 360, 232, 488, + 24, 280, 152, 408, 88, 344, 216, 472, + 56, 312, 184, 440, 120, 376, 248, 504, + 4, 260, 132, 388, 68, 324, 196, 452, + 36, 292, 164, 420, 100, 356, 228, 484, + 20, 276, 148, 404, 84, 340, 212, 468, + 52, 308, 180, 436, 116, 372, 244, 500, + 12, 268, 140, 396, 76, 332, 204, 460, + 44, 300, 172, 428, 108, 364, 236, 492, + 28, 284, 156, 412, 92, 348, 220, 476, + 60, 316, 188, 444, 124, 380, 252, 508, + 2, 258, 130, 386, 66, 322, 194, 450, + 34, 290, 162, 418, 98, 354, 226, 482, + 18, 274, 146, 402, 82, 338, 210, 466, + 50, 306, 178, 434, 114, 370, 242, 498, + 10, 266, 138, 394, 74, 330, 202, 458, + 42, 298, 170, 426, 106, 362, 234, 490, + 26, 282, 154, 410, 90, 346, 218, 474, + 58, 314, 186, 442, 122, 378, 250, 506, + 6, 262, 134, 390, 70, 326, 198, 454, + 38, 294, 166, 422, 102, 358, 230, 486, + 22, 278, 150, 406, 86, 342, 214, 470, + 54, 310, 182, 438, 118, 374, 246, 502, + 14, 270, 142, 398, 78, 334, 206, 462, + 46, 302, 174, 430, 110, 366, 238, 494, + 30, 286, 158, 414, 94, 350, 222, 478, + 62, 318, 190, 446, 126, 382, 254, 510, + 1, 257, 129, 385, 65, 321, 193, 449, + 33, 289, 161, 417, 97, 353, 225, 481, + 17, 273, 145, 401, 81, 337, 209, 465, + 49, 305, 177, 433, 113, 369, 241, 497, + 9, 265, 137, 393, 73, 329, 201, 457, + 41, 297, 169, 425, 105, 361, 233, 489, + 25, 281, 153, 409, 89, 345, 217, 473, + 57, 313, 185, 441, 121, 377, 249, 505, + 5, 261, 133, 389, 69, 325, 197, 453, + 37, 293, 165, 421, 101, 357, 229, 485, + 21, 277, 149, 405, 85, 341, 213, 469, + 53, 309, 181, 437, 117, 373, 245, 501, + 13, 269, 141, 397, 77, 333, 205, 461, + 45, 301, 173, 429, 109, 365, 237, 493, + 29, 285, 157, 413, 93, 349, 221, 477, + 61, 317, 189, 445, 125, 381, 253, 509, + 3, 259, 131, 387, 67, 323, 195, 451, + 35, 291, 163, 419, 99, 355, 227, 483, + 19, 275, 147, 403, 83, 339, 211, 467, + 51, 307, 179, 435, 115, 371, 243, 499, + 11, 267, 139, 395, 75, 331, 203, 459, + 43, 299, 171, 427, 107, 363, 235, 491, + 27, 283, 155, 411, 91, 347, 219, 475, + 59, 315, 187, 443, 123, 379, 251, 507, + 7, 1031, 519, 1543, 263, 1287, 775, 1799, + 135, 1159, 647, 1671, 391, 1415, 903, 1927, + 71, 1095, 583, 1607, 327, 1351, 839, 1863, + 199, 1223, 711, 1735, 455, 1479, 967, 1991, + 39, 1063, 551, 1575, 295, 1319, 807, 1831, + 167, 1191, 679, 1703, 423, 1447, 935, 1959, + 103, 1127, 615, 1639, 359, 1383, 871, 1895, + 231, 1255, 743, 1767, 487, 1511, 999, 2023, + 23, 1047, 535, 1559, 279, 1303, 791, 1815, + 151, 1175, 663, 1687, 407, 1431, 919, 1943, + 87, 1111, 599, 1623, 343, 1367, 855, 1879, + 215, 1239, 727, 1751, 471, 1495, 983, 2007, + 55, 1079, 567, 1591, 311, 1335, 823, 1847, + 183, 1207, 695, 1719, 439, 1463, 951, 1975, + 119, 1143, 631, 1655, 375, 1399, 887, 1911, + 247, 1271, 759, 1783, 503, 1527, 1015, 2039, + 15, 1039, 527, 1551, 271, 1295, 783, 1807, + 143, 1167, 655, 1679, 399, 1423, 911, 1935, + 79, 1103, 591, 1615, 335, 1359, 847, 1871, + 207, 1231, 719, 1743, 463, 1487, 975, 1999, + 47, 1071, 559, 1583, 303, 1327, 815, 1839, + 175, 1199, 687, 1711, 431, 1455, 943, 1967, + 111, 1135, 623, 1647, 367, 1391, 879, 1903, + 239, 1263, 751, 1775, 495, 1519, 1007, 2031, + 31, 1055, 543, 1567, 287, 1311, 799, 1823, + 159, 1183, 671, 1695, 415, 1439, 927, 1951, + 95, 1119, 607, 1631, 351, 1375, 863, 1887, + 223, 1247, 735, 1759, 479, 1503, 991, 2015, + 63, 1087, 575, 1599, 319, 1343, 831, 1855, + 191, 1215, 703, 1727, 447, 1471, 959, 1983, + 127, 1151, 639, 1663, 383, 1407, 895, 1919, + 255, 1279, 767, 1791, 511, 1535, 1023, 2047, +}; + +inline void StoreStaticCommandHuffmanTree(size_t* storage_ix, + uint8_t* storage) { + WriteBits(28, 0x0000000006307003U, storage_ix, storage); + WriteBits(31, 0x0000000009262441U, storage_ix, storage); +} + +static const uint16_t kStaticDistanceCodeBits[64] = { + 0, 32, 16, 48, 8, 40, 24, 56, 4, 36, 20, 52, 12, 44, 28, 60, + 2, 34, 18, 50, 10, 42, 26, 58, 6, 38, 22, 54, 14, 46, 30, 62, + 1, 33, 17, 49, 9, 41, 25, 57, 5, 37, 21, 53, 13, 45, 29, 61, + 3, 35, 19, 51, 11, 43, 27, 59, 7, 39, 23, 55, 15, 47, 31, 63, +}; + +inline void StoreStaticDistanceHuffmanTree(size_t* storage_ix, + uint8_t* storage) { + WriteBits(18, 0x000000000001dc03U, storage_ix, storage); + WriteBits(10, 0x00000000000000daU, storage_ix, storage); +} + +} // namespace brotli + +#endif // BROTLI_ENC_ENTROPY_ENCODE_STATIC_H_ diff --git a/web/server/h2o/libh2o/deps/brotli/enc/fast_log.h b/web/server/h2o/libh2o/deps/brotli/enc/fast_log.h new file mode 100644 index 00000000..f9450ed5 --- /dev/null +++ b/web/server/h2o/libh2o/deps/brotli/enc/fast_log.h @@ -0,0 +1,139 @@ +/* Copyright 2013 Google Inc. All Rights Reserved. + + Distributed under MIT license. + See file LICENSE for detail or copy at https://opensource.org/licenses/MIT +*/ + +// Utilities for fast computation of logarithms. + +#ifndef BROTLI_ENC_FAST_LOG_H_ +#define BROTLI_ENC_FAST_LOG_H_ + +#include +#include + +#include "./types.h" + +namespace brotli { + +static inline uint32_t Log2FloorNonZero(size_t n) { +#ifdef __GNUC__ + return 31u ^ static_cast(__builtin_clz(static_cast(n))); +#else + uint32_t result = 0; + while (n >>= 1) result++; + return result; +#endif +} + +// A lookup table for small values of log2(int) to be used in entropy +// computation. +// +// ", ".join(["%.16ff" % x for x in [0.0]+[log2(x) for x in range(1, 256)]]) +static const float kLog2Table[] = { + 0.0000000000000000f, 0.0000000000000000f, 1.0000000000000000f, + 1.5849625007211563f, 2.0000000000000000f, 2.3219280948873622f, + 2.5849625007211561f, 2.8073549220576042f, 3.0000000000000000f, + 3.1699250014423126f, 3.3219280948873626f, 3.4594316186372978f, + 3.5849625007211565f, 3.7004397181410922f, 3.8073549220576037f, + 3.9068905956085187f, 4.0000000000000000f, 4.0874628412503400f, + 4.1699250014423122f, 4.2479275134435852f, 4.3219280948873626f, + 4.3923174227787607f, 4.4594316186372973f, 4.5235619560570131f, + 4.5849625007211570f, 4.6438561897747244f, 4.7004397181410926f, + 4.7548875021634691f, 4.8073549220576037f, 4.8579809951275728f, + 4.9068905956085187f, 4.9541963103868758f, 5.0000000000000000f, + 5.0443941193584534f, 5.0874628412503400f, 5.1292830169449664f, + 5.1699250014423122f, 5.2094533656289501f, 5.2479275134435852f, + 5.2854022188622487f, 5.3219280948873626f, 5.3575520046180838f, + 5.3923174227787607f, 5.4262647547020979f, 5.4594316186372973f, + 5.4918530963296748f, 5.5235619560570131f, 5.5545888516776376f, + 5.5849625007211570f, 5.6147098441152083f, 5.6438561897747244f, + 5.6724253419714961f, 5.7004397181410926f, 5.7279204545631996f, + 5.7548875021634691f, 5.7813597135246599f, 5.8073549220576046f, + 5.8328900141647422f, 5.8579809951275719f, 5.8826430493618416f, + 5.9068905956085187f, 5.9307373375628867f, 5.9541963103868758f, + 5.9772799234999168f, 6.0000000000000000f, 6.0223678130284544f, + 6.0443941193584534f, 6.0660891904577721f, 6.0874628412503400f, + 6.1085244567781700f, 6.1292830169449672f, 6.1497471195046822f, + 6.1699250014423122f, 6.1898245588800176f, 6.2094533656289510f, + 6.2288186904958804f, 6.2479275134435861f, 6.2667865406949019f, + 6.2854022188622487f, 6.3037807481771031f, 6.3219280948873617f, + 6.3398500028846252f, 6.3575520046180847f, 6.3750394313469254f, + 6.3923174227787598f, 6.4093909361377026f, 6.4262647547020979f, + 6.4429434958487288f, 6.4594316186372982f, 6.4757334309663976f, + 6.4918530963296748f, 6.5077946401986964f, 6.5235619560570131f, + 6.5391588111080319f, 6.5545888516776376f, 6.5698556083309478f, + 6.5849625007211561f, 6.5999128421871278f, 6.6147098441152092f, + 6.6293566200796095f, 6.6438561897747253f, 6.6582114827517955f, + 6.6724253419714952f, 6.6865005271832185f, 6.7004397181410917f, + 6.7142455176661224f, 6.7279204545631988f, 6.7414669864011465f, + 6.7548875021634691f, 6.7681843247769260f, 6.7813597135246599f, + 6.7944158663501062f, 6.8073549220576037f, 6.8201789624151887f, + 6.8328900141647422f, 6.8454900509443757f, 6.8579809951275719f, + 6.8703647195834048f, 6.8826430493618416f, 6.8948177633079437f, + 6.9068905956085187f, 6.9188632372745955f, 6.9307373375628867f, + 6.9425145053392399f, 6.9541963103868758f, 6.9657842846620879f, + 6.9772799234999168f, 6.9886846867721664f, 7.0000000000000000f, + 7.0112272554232540f, 7.0223678130284544f, 7.0334230015374501f, + 7.0443941193584534f, 7.0552824355011898f, 7.0660891904577721f, + 7.0768155970508317f, 7.0874628412503400f, 7.0980320829605272f, + 7.1085244567781700f, 7.1189410727235076f, 7.1292830169449664f, + 7.1395513523987937f, 7.1497471195046822f, 7.1598713367783891f, + 7.1699250014423130f, 7.1799090900149345f, 7.1898245588800176f, + 7.1996723448363644f, 7.2094533656289492f, 7.2191685204621621f, + 7.2288186904958804f, 7.2384047393250794f, 7.2479275134435861f, + 7.2573878426926521f, 7.2667865406949019f, 7.2761244052742384f, + 7.2854022188622487f, 7.2946207488916270f, 7.3037807481771031f, + 7.3128829552843557f, 7.3219280948873617f, 7.3309168781146177f, + 7.3398500028846243f, 7.3487281542310781f, 7.3575520046180847f, + 7.3663222142458151f, 7.3750394313469254f, 7.3837042924740528f, + 7.3923174227787607f, 7.4008794362821844f, 7.4093909361377026f, + 7.4178525148858991f, 7.4262647547020979f, 7.4346282276367255f, + 7.4429434958487288f, 7.4512111118323299f, 7.4594316186372973f, + 7.4676055500829976f, 7.4757334309663976f, 7.4838157772642564f, + 7.4918530963296748f, 7.4998458870832057f, 7.5077946401986964f, + 7.5156998382840436f, 7.5235619560570131f, 7.5313814605163119f, + 7.5391588111080319f, 7.5468944598876373f, 7.5545888516776376f, + 7.5622424242210728f, 7.5698556083309478f, 7.5774288280357487f, + 7.5849625007211561f, 7.5924570372680806f, 7.5999128421871278f, + 7.6073303137496113f, 7.6147098441152075f, 7.6220518194563764f, + 7.6293566200796095f, 7.6366246205436488f, 7.6438561897747244f, + 7.6510516911789290f, 7.6582114827517955f, 7.6653359171851765f, + 7.6724253419714952f, 7.6794800995054464f, 7.6865005271832185f, + 7.6934869574993252f, 7.7004397181410926f, 7.7073591320808825f, + 7.7142455176661224f, 7.7210991887071856f, 7.7279204545631996f, + 7.7347096202258392f, 7.7414669864011465f, 7.7481928495894596f, + 7.7548875021634691f, 7.7615512324444795f, 7.7681843247769260f, + 7.7747870596011737f, 7.7813597135246608f, 7.7879025593914317f, + 7.7944158663501062f, 7.8008998999203047f, 7.8073549220576037f, + 7.8137811912170374f, 7.8201789624151887f, 7.8265484872909159f, + 7.8328900141647422f, 7.8392037880969445f, 7.8454900509443757f, + 7.8517490414160571f, 7.8579809951275719f, 7.8641861446542798f, + 7.8703647195834048f, 7.8765169465650002f, 7.8826430493618425f, + 7.8887432488982601f, 7.8948177633079446f, 7.9008668079807496f, + 7.9068905956085187f, 7.9128893362299619f, 7.9188632372745955f, + 7.9248125036057813f, 7.9307373375628867f, 7.9366379390025719f, + 7.9425145053392399f, 7.9483672315846778f, 7.9541963103868758f, + 7.9600019320680806f, 7.9657842846620870f, 7.9715435539507720f, + 7.9772799234999168f, 7.9829935746943104f, 7.9886846867721664f, + 7.9943534368588578f +}; + +// Faster logarithm for small integers, with the property of log2(0) == 0. +static inline double FastLog2(size_t v) { + if (v < sizeof(kLog2Table) / sizeof(kLog2Table[0])) { + return kLog2Table[v]; + } +#if defined(_MSC_VER) && _MSC_VER <= 1600 + // Visual Studio 2010 does not have the log2() function defined, so we use + // log() and a multiplication instead. + static const double kLog2Inv = 1.4426950408889634f; + return log(static_cast(v)) * kLog2Inv; +#else + return log2(static_cast(v)); +#endif +} + +} // namespace brotli + +#endif // BROTLI_ENC_FAST_LOG_H_ diff --git a/web/server/h2o/libh2o/deps/brotli/enc/find_match_length.h b/web/server/h2o/libh2o/deps/brotli/enc/find_match_length.h new file mode 100644 index 00000000..1337ec36 --- /dev/null +++ b/web/server/h2o/libh2o/deps/brotli/enc/find_match_length.h @@ -0,0 +1,77 @@ +/* Copyright 2010 Google Inc. All Rights Reserved. + + Distributed under MIT license. + See file LICENSE for detail or copy at https://opensource.org/licenses/MIT +*/ + +// Function to find maximal matching prefixes of strings. + +#ifndef BROTLI_ENC_FIND_MATCH_LENGTH_H_ +#define BROTLI_ENC_FIND_MATCH_LENGTH_H_ + + +#include "./port.h" +#include "./types.h" + +namespace brotli { + +// Separate implementation for little-endian 64-bit targets, for speed. +#if defined(__GNUC__) && defined(_LP64) && defined(IS_LITTLE_ENDIAN) + +static inline size_t FindMatchLengthWithLimit(const uint8_t* s1, + const uint8_t* s2, + size_t limit) { + size_t matched = 0; + size_t limit2 = (limit >> 3) + 1; // + 1 is for pre-decrement in while + while (PREDICT_TRUE(--limit2)) { + if (PREDICT_FALSE(BROTLI_UNALIGNED_LOAD64(s2) == + BROTLI_UNALIGNED_LOAD64(s1 + matched))) { + s2 += 8; + matched += 8; + } else { + uint64_t x = + BROTLI_UNALIGNED_LOAD64(s2) ^ BROTLI_UNALIGNED_LOAD64(s1 + matched); + size_t matching_bits = static_cast(__builtin_ctzll(x)); + matched += matching_bits >> 3; + return matched; + } + } + limit = (limit & 7) + 1; // + 1 is for pre-decrement in while + while (--limit) { + if (PREDICT_TRUE(s1[matched] == *s2)) { + ++s2; + ++matched; + } else { + return matched; + } + } + return matched; +} +#else +static inline size_t FindMatchLengthWithLimit(const uint8_t* s1, + const uint8_t* s2, + size_t limit) { + size_t matched = 0; + const uint8_t* s2_limit = s2 + limit; + const uint8_t* s2_ptr = s2; + // Find out how long the match is. We loop over the data 32 bits at a + // time until we find a 32-bit block that doesn't match; then we find + // the first non-matching bit and use that to calculate the total + // length of the match. + while (s2_ptr <= s2_limit - 4 && + BROTLI_UNALIGNED_LOAD32(s2_ptr) == + BROTLI_UNALIGNED_LOAD32(s1 + matched)) { + s2_ptr += 4; + matched += 4; + } + while ((s2_ptr < s2_limit) && (s1[matched] == *s2_ptr)) { + ++s2_ptr; + ++matched; + } + return matched; +} +#endif + +} // namespace brotli + +#endif // BROTLI_ENC_FIND_MATCH_LENGTH_H_ diff --git a/web/server/h2o/libh2o/deps/brotli/enc/hash.h b/web/server/h2o/libh2o/deps/brotli/enc/hash.h new file mode 100644 index 00000000..1f5f168c --- /dev/null +++ b/web/server/h2o/libh2o/deps/brotli/enc/hash.h @@ -0,0 +1,953 @@ +/* Copyright 2010 Google Inc. All Rights Reserved. + + Distributed under MIT license. + See file LICENSE for detail or copy at https://opensource.org/licenses/MIT +*/ + +// A (forgetful) hash table to the data seen by the compressor, to +// help create backward references to previous data. + +#ifndef BROTLI_ENC_HASH_H_ +#define BROTLI_ENC_HASH_H_ + +#include +#include +#include +#include +#include + +#include "./dictionary_hash.h" +#include "./fast_log.h" +#include "./find_match_length.h" +#include "./port.h" +#include "./prefix.h" +#include "./static_dict.h" +#include "./transform.h" +#include "./types.h" + +namespace brotli { + +static const size_t kMaxTreeSearchDepth = 64; +static const size_t kMaxTreeCompLength = 128; + +static const uint32_t kDistanceCacheIndex[] = { + 0, 1, 2, 3, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, +}; +static const int kDistanceCacheOffset[] = { + 0, 0, 0, 0, -1, 1, -2, 2, -3, 3, -1, 1, -2, 2, -3, 3 +}; + +static const uint32_t kCutoffTransformsCount = 10; +static const uint8_t kCutoffTransforms[] = { + 0, 12, 27, 23, 42, 63, 56, 48, 59, 64 +}; + +// kHashMul32 multiplier has these properties: +// * The multiplier must be odd. Otherwise we may lose the highest bit. +// * No long streaks of 1s or 0s. +// * There is no effort to ensure that it is a prime, the oddity is enough +// for this use. +// * The number has been tuned heuristically against compression benchmarks. +static const uint32_t kHashMul32 = 0x1e35a7bd; + +template +inline uint32_t Hash(const uint8_t *data) { + uint32_t h = BROTLI_UNALIGNED_LOAD32(data) * kHashMul32; + // The higher bits contain more mixture from the multiplication, + // so we take our results from there. + return h >> (32 - kShiftBits); +} + +// Usually, we always choose the longest backward reference. This function +// allows for the exception of that rule. +// +// If we choose a backward reference that is further away, it will +// usually be coded with more bits. We approximate this by assuming +// log2(distance). If the distance can be expressed in terms of the +// last four distances, we use some heuristic constants to estimate +// the bits cost. For the first up to four literals we use the bit +// cost of the literals from the literal cost model, after that we +// use the average bit cost of the cost model. +// +// This function is used to sometimes discard a longer backward reference +// when it is not much longer and the bit cost for encoding it is more +// than the saved literals. +// +// backward_reference_offset MUST be positive. +inline double BackwardReferenceScore(size_t copy_length, + size_t backward_reference_offset) { + return 5.4 * static_cast(copy_length) - + 1.20 * Log2FloorNonZero(backward_reference_offset); +} + +inline double BackwardReferenceScoreUsingLastDistance(size_t copy_length, + size_t distance_short_code) { + static const double kDistanceShortCodeBitCost[16] = { + -0.6, 0.95, 1.17, 1.27, + 0.93, 0.93, 0.96, 0.96, 0.99, 0.99, + 1.05, 1.05, 1.15, 1.15, 1.25, 1.25 + }; + return 5.4 * static_cast(copy_length) - + kDistanceShortCodeBitCost[distance_short_code]; +} + +struct BackwardMatch { + BackwardMatch() : distance(0), length_and_code(0) {} + + BackwardMatch(size_t dist, size_t len) + : distance(static_cast(dist)) + , length_and_code(static_cast(len << 5)) {} + + BackwardMatch(size_t dist, size_t len, size_t len_code) + : distance(static_cast(dist)) + , length_and_code(static_cast( + (len << 5) | (len == len_code ? 0 : len_code))) {} + + size_t length() const { + return length_and_code >> 5; + } + size_t length_code() const { + size_t code = length_and_code & 31; + return code ? code : length(); + } + + uint32_t distance; + uint32_t length_and_code; +}; + +// A (forgetful) hash table to the data seen by the compressor, to +// help create backward references to previous data. +// +// This is a hash map of fixed size (kBucketSize). Starting from the +// given index, kBucketSweep buckets are used to store values of a key. +template +class HashLongestMatchQuickly { + public: + HashLongestMatchQuickly() { + Reset(); + } + void Reset() { + need_init_ = true; + num_dict_lookups_ = 0; + num_dict_matches_ = 0; + } + void Init() { + if (need_init_) { + // It is not strictly necessary to fill this buffer here, but + // not filling will make the results of the compression stochastic + // (but correct). This is because random data would cause the + // system to find accidentally good backward references here and there. + memset(&buckets_[0], 0, sizeof(buckets_)); + need_init_ = false; + } + } + void InitForData(const uint8_t* data, size_t num) { + for (size_t i = 0; i < num; ++i) { + const uint32_t key = HashBytes(&data[i]); + memset(&buckets_[key], 0, kBucketSweep * sizeof(buckets_[0])); + need_init_ = false; + } + } + // Look at 4 bytes at data. + // Compute a hash from these, and store the value somewhere within + // [ix .. ix+3]. + inline void Store(const uint8_t *data, const uint32_t ix) { + const uint32_t key = HashBytes(data); + // Wiggle the value with the bucket sweep range. + const uint32_t off = (ix >> 3) % kBucketSweep; + buckets_[key + off] = ix; + } + + // Find a longest backward match of &ring_buffer[cur_ix & ring_buffer_mask] + // up to the length of max_length and stores the position cur_ix in the + // hash table. + // + // Does not look for matches longer than max_length. + // Does not look for matches further away than max_backward. + // Writes the best found match length into best_len_out. + // Writes the index (&data[index]) of the start of the best match into + // best_distance_out. + inline bool FindLongestMatch(const uint8_t * __restrict ring_buffer, + const size_t ring_buffer_mask, + const int* __restrict distance_cache, + const size_t cur_ix, + const size_t max_length, + const size_t max_backward, + size_t * __restrict best_len_out, + size_t * __restrict best_len_code_out, + size_t * __restrict best_distance_out, + double* __restrict best_score_out) { + const size_t best_len_in = *best_len_out; + const size_t cur_ix_masked = cur_ix & ring_buffer_mask; + const uint32_t key = HashBytes(&ring_buffer[cur_ix_masked]); + int compare_char = ring_buffer[cur_ix_masked + best_len_in]; + double best_score = *best_score_out; + size_t best_len = best_len_in; + size_t cached_backward = static_cast(distance_cache[0]); + size_t prev_ix = cur_ix - cached_backward; + bool match_found = false; + if (prev_ix < cur_ix) { + prev_ix &= static_cast(ring_buffer_mask); + if (compare_char == ring_buffer[prev_ix + best_len]) { + size_t len = FindMatchLengthWithLimit(&ring_buffer[prev_ix], + &ring_buffer[cur_ix_masked], + max_length); + if (len >= 4) { + best_score = BackwardReferenceScoreUsingLastDistance(len, 0); + best_len = len; + *best_len_out = len; + *best_len_code_out = len; + *best_distance_out = cached_backward; + *best_score_out = best_score; + compare_char = ring_buffer[cur_ix_masked + best_len]; + if (kBucketSweep == 1) { + buckets_[key] = static_cast(cur_ix); + return true; + } else { + match_found = true; + } + } + } + } + if (kBucketSweep == 1) { + // Only one to look for, don't bother to prepare for a loop. + prev_ix = buckets_[key]; + buckets_[key] = static_cast(cur_ix); + size_t backward = cur_ix - prev_ix; + prev_ix &= static_cast(ring_buffer_mask); + if (compare_char != ring_buffer[prev_ix + best_len_in]) { + return false; + } + if (PREDICT_FALSE(backward == 0 || backward > max_backward)) { + return false; + } + const size_t len = FindMatchLengthWithLimit(&ring_buffer[prev_ix], + &ring_buffer[cur_ix_masked], + max_length); + if (len >= 4) { + *best_len_out = len; + *best_len_code_out = len; + *best_distance_out = backward; + *best_score_out = BackwardReferenceScore(len, backward); + return true; + } + } else { + uint32_t *bucket = buckets_ + key; + prev_ix = *bucket++; + for (int i = 0; i < kBucketSweep; ++i, prev_ix = *bucket++) { + const size_t backward = cur_ix - prev_ix; + prev_ix &= static_cast(ring_buffer_mask); + if (compare_char != ring_buffer[prev_ix + best_len]) { + continue; + } + if (PREDICT_FALSE(backward == 0 || backward > max_backward)) { + continue; + } + const size_t len = FindMatchLengthWithLimit(&ring_buffer[prev_ix], + &ring_buffer[cur_ix_masked], + max_length); + if (len >= 4) { + const double score = BackwardReferenceScore(len, backward); + if (best_score < score) { + best_score = score; + best_len = len; + *best_len_out = best_len; + *best_len_code_out = best_len; + *best_distance_out = backward; + *best_score_out = score; + compare_char = ring_buffer[cur_ix_masked + best_len]; + match_found = true; + } + } + } + } + if (kUseDictionary && !match_found && + num_dict_matches_ >= (num_dict_lookups_ >> 7)) { + ++num_dict_lookups_; + const uint32_t dict_key = Hash<14>(&ring_buffer[cur_ix_masked]) << 1; + const uint16_t v = kStaticDictionaryHash[dict_key]; + if (v > 0) { + const uint32_t len = v & 31; + const uint32_t dist = v >> 5; + const size_t offset = + kBrotliDictionaryOffsetsByLength[len] + len * dist; + if (len <= max_length) { + const size_t matchlen = + FindMatchLengthWithLimit(&ring_buffer[cur_ix_masked], + &kBrotliDictionary[offset], len); + if (matchlen + kCutoffTransformsCount > len && matchlen > 0) { + const size_t transform_id = kCutoffTransforms[len - matchlen]; + const size_t word_id = + transform_id * (1 << kBrotliDictionarySizeBitsByLength[len]) + + dist; + const size_t backward = max_backward + word_id + 1; + const double score = BackwardReferenceScore(matchlen, backward); + if (best_score < score) { + ++num_dict_matches_; + best_score = score; + best_len = matchlen; + *best_len_out = best_len; + *best_len_code_out = len; + *best_distance_out = backward; + *best_score_out = best_score; + match_found = true; + } + } + } + } + } + const uint32_t off = (cur_ix >> 3) % kBucketSweep; + buckets_[key + off] = static_cast(cur_ix); + return match_found; + } + + enum { kHashLength = 5 }; + enum { kHashTypeLength = 8 }; + // HashBytes is the function that chooses the bucket to place + // the address in. The HashLongestMatch and HashLongestMatchQuickly + // classes have separate, different implementations of hashing. + static uint32_t HashBytes(const uint8_t *data) { + // Computing a hash based on 5 bytes works much better for + // qualities 1 and 3, where the next hash value is likely to replace + uint64_t h = (BROTLI_UNALIGNED_LOAD64(data) << 24) * kHashMul32; + // The higher bits contain more mixture from the multiplication, + // so we take our results from there. + return static_cast(h >> (64 - kBucketBits)); + } + + enum { kHashMapSize = 4 << kBucketBits }; + + private: + static const uint32_t kBucketSize = 1 << kBucketBits; + uint32_t buckets_[kBucketSize + kBucketSweep]; + // True if buckets_ array needs to be initialized. + bool need_init_; + size_t num_dict_lookups_; + size_t num_dict_matches_; +}; + +// A (forgetful) hash table to the data seen by the compressor, to +// help create backward references to previous data. +// +// This is a hash map of fixed size (kBucketSize) to a ring buffer of +// fixed size (kBlockSize). The ring buffer contains the last kBlockSize +// index positions of the given hash key in the compressed data. +template +class HashLongestMatch { + public: + HashLongestMatch() { + Reset(); + } + + void Reset() { + need_init_ = true; + num_dict_lookups_ = 0; + num_dict_matches_ = 0; + } + + void Init() { + if (need_init_) { + memset(&num_[0], 0, sizeof(num_)); + need_init_ = false; + } + } + + void InitForData(const uint8_t* data, size_t num) { + for (size_t i = 0; i < num; ++i) { + const uint32_t key = HashBytes(&data[i]); + num_[key] = 0; + need_init_ = false; + } + } + + // Look at 3 bytes at data. + // Compute a hash from these, and store the value of ix at that position. + inline void Store(const uint8_t *data, const uint32_t ix) { + const uint32_t key = HashBytes(data); + const int minor_ix = num_[key] & kBlockMask; + buckets_[key][minor_ix] = ix; + ++num_[key]; + } + + // Find a longest backward match of &data[cur_ix] up to the length of + // max_length and stores the position cur_ix in the hash table. + // + // Does not look for matches longer than max_length. + // Does not look for matches further away than max_backward. + // Writes the best found match length into best_len_out. + // Writes the index (&data[index]) offset from the start of the best match + // into best_distance_out. + // Write the score of the best match into best_score_out. + bool FindLongestMatch(const uint8_t * __restrict data, + const size_t ring_buffer_mask, + const int* __restrict distance_cache, + const size_t cur_ix, + const size_t max_length, + const size_t max_backward, + size_t * __restrict best_len_out, + size_t * __restrict best_len_code_out, + size_t * __restrict best_distance_out, + double * __restrict best_score_out) { + *best_len_code_out = 0; + const size_t cur_ix_masked = cur_ix & ring_buffer_mask; + bool match_found = false; + // Don't accept a short copy from far away. + double best_score = *best_score_out; + size_t best_len = *best_len_out; + *best_len_out = 0; + // Try last distance first. + for (size_t i = 0; i < kNumLastDistancesToCheck; ++i) { + const size_t idx = kDistanceCacheIndex[i]; + const size_t backward = + static_cast(distance_cache[idx] + kDistanceCacheOffset[i]); + size_t prev_ix = static_cast(cur_ix - backward); + if (prev_ix >= cur_ix) { + continue; + } + if (PREDICT_FALSE(backward > max_backward)) { + continue; + } + prev_ix &= ring_buffer_mask; + + if (cur_ix_masked + best_len > ring_buffer_mask || + prev_ix + best_len > ring_buffer_mask || + data[cur_ix_masked + best_len] != data[prev_ix + best_len]) { + continue; + } + const size_t len = FindMatchLengthWithLimit(&data[prev_ix], + &data[cur_ix_masked], + max_length); + if (len >= 3 || (len == 2 && i < 2)) { + // Comparing for >= 2 does not change the semantics, but just saves for + // a few unnecessary binary logarithms in backward reference score, + // since we are not interested in such short matches. + double score = BackwardReferenceScoreUsingLastDistance(len, i); + if (best_score < score) { + best_score = score; + best_len = len; + *best_len_out = best_len; + *best_len_code_out = best_len; + *best_distance_out = backward; + *best_score_out = best_score; + match_found = true; + } + } + } + const uint32_t key = HashBytes(&data[cur_ix_masked]); + const uint32_t * __restrict const bucket = &buckets_[key][0]; + const size_t down = (num_[key] > kBlockSize) ? (num_[key] - kBlockSize) : 0; + for (size_t i = num_[key]; i > down;) { + --i; + size_t prev_ix = bucket[i & kBlockMask]; + const size_t backward = cur_ix - prev_ix; + if (PREDICT_FALSE(backward == 0 || backward > max_backward)) { + break; + } + prev_ix &= ring_buffer_mask; + if (cur_ix_masked + best_len > ring_buffer_mask || + prev_ix + best_len > ring_buffer_mask || + data[cur_ix_masked + best_len] != data[prev_ix + best_len]) { + continue; + } + const size_t len = FindMatchLengthWithLimit(&data[prev_ix], + &data[cur_ix_masked], + max_length); + if (len >= 4) { + // Comparing for >= 3 does not change the semantics, but just saves + // for a few unnecessary binary logarithms in backward reference + // score, since we are not interested in such short matches. + double score = BackwardReferenceScore(len, backward); + if (best_score < score) { + best_score = score; + best_len = len; + *best_len_out = best_len; + *best_len_code_out = best_len; + *best_distance_out = backward; + *best_score_out = best_score; + match_found = true; + } + } + } + buckets_[key][num_[key] & kBlockMask] = static_cast(cur_ix); + ++num_[key]; + if (!match_found && num_dict_matches_ >= (num_dict_lookups_ >> 7)) { + size_t dict_key = Hash<14>(&data[cur_ix_masked]) << 1; + for (int k = 0; k < 2; ++k, ++dict_key) { + ++num_dict_lookups_; + const uint16_t v = kStaticDictionaryHash[dict_key]; + if (v > 0) { + const size_t len = v & 31; + const size_t dist = v >> 5; + const size_t offset = + kBrotliDictionaryOffsetsByLength[len] + len * dist; + if (len <= max_length) { + const size_t matchlen = + FindMatchLengthWithLimit(&data[cur_ix_masked], + &kBrotliDictionary[offset], len); + if (matchlen + kCutoffTransformsCount > len && matchlen > 0) { + const size_t transform_id = kCutoffTransforms[len - matchlen]; + const size_t word_id = + transform_id * (1 << kBrotliDictionarySizeBitsByLength[len]) + + dist; + const size_t backward = max_backward + word_id + 1; + double score = BackwardReferenceScore(matchlen, backward); + if (best_score < score) { + ++num_dict_matches_; + best_score = score; + best_len = matchlen; + *best_len_out = best_len; + *best_len_code_out = len; + *best_distance_out = backward; + *best_score_out = best_score; + match_found = true; + } + } + } + } + } + } + return match_found; + } + + // Finds all backward matches of &data[cur_ix & ring_buffer_mask] up to the + // length of max_length and stores the position cur_ix in the hash table. + // + // Sets *num_matches to the number of matches found, and stores the found + // matches in matches[0] to matches[*num_matches - 1]. The matches will be + // sorted by strictly increasing length and (non-strictly) increasing + // distance. + size_t FindAllMatches(const uint8_t* data, + const size_t ring_buffer_mask, + const size_t cur_ix, + const size_t max_length, + const size_t max_backward, + BackwardMatch* matches) { + BackwardMatch* const orig_matches = matches; + const size_t cur_ix_masked = cur_ix & ring_buffer_mask; + size_t best_len = 1; + size_t stop = cur_ix - 64; + if (cur_ix < 64) { stop = 0; } + for (size_t i = cur_ix - 1; i > stop && best_len <= 2; --i) { + size_t prev_ix = i; + const size_t backward = cur_ix - prev_ix; + if (PREDICT_FALSE(backward > max_backward)) { + break; + } + prev_ix &= ring_buffer_mask; + if (data[cur_ix_masked] != data[prev_ix] || + data[cur_ix_masked + 1] != data[prev_ix + 1]) { + continue; + } + const size_t len = + FindMatchLengthWithLimit(&data[prev_ix], &data[cur_ix_masked], + max_length); + if (len > best_len) { + best_len = len; + *matches++ = BackwardMatch(backward, len); + } + } + const uint32_t key = HashBytes(&data[cur_ix_masked]); + const uint32_t * __restrict const bucket = &buckets_[key][0]; + const size_t down = (num_[key] > kBlockSize) ? (num_[key] - kBlockSize) : 0; + for (size_t i = num_[key]; i > down;) { + --i; + size_t prev_ix = bucket[i & kBlockMask]; + const size_t backward = cur_ix - prev_ix; + if (PREDICT_FALSE(backward == 0 || backward > max_backward)) { + break; + } + prev_ix &= ring_buffer_mask; + if (cur_ix_masked + best_len > ring_buffer_mask || + prev_ix + best_len > ring_buffer_mask || + data[cur_ix_masked + best_len] != data[prev_ix + best_len]) { + continue; + } + const size_t len = + FindMatchLengthWithLimit(&data[prev_ix], &data[cur_ix_masked], + max_length); + if (len > best_len) { + best_len = len; + *matches++ = BackwardMatch(backward, len); + } + } + buckets_[key][num_[key] & kBlockMask] = static_cast(cur_ix); + ++num_[key]; + std::vector dict_matches(kMaxDictionaryMatchLen + 1, + kInvalidMatch); + size_t minlen = std::max(4, best_len + 1); + if (FindAllStaticDictionaryMatches(&data[cur_ix_masked], minlen, max_length, + &dict_matches[0])) { + size_t maxlen = std::min(kMaxDictionaryMatchLen, max_length); + for (size_t l = minlen; l <= maxlen; ++l) { + uint32_t dict_id = dict_matches[l]; + if (dict_id < kInvalidMatch) { + *matches++ = BackwardMatch(max_backward + (dict_id >> 5) + 1, l, + dict_id & 31); + } + } + } + return static_cast(matches - orig_matches); + } + + enum { kHashLength = 4 }; + enum { kHashTypeLength = 4 }; + + // HashBytes is the function that chooses the bucket to place + // the address in. The HashLongestMatch and HashLongestMatchQuickly + // classes have separate, different implementations of hashing. + static uint32_t HashBytes(const uint8_t *data) { + uint32_t h = BROTLI_UNALIGNED_LOAD32(data) * kHashMul32; + // The higher bits contain more mixture from the multiplication, + // so we take our results from there. + return h >> (32 - kBucketBits); + } + + enum { kHashMapSize = 2 << kBucketBits }; + + static const size_t kMaxNumMatches = 64 + (1 << kBlockBits); + + private: + // Number of hash buckets. + static const uint32_t kBucketSize = 1 << kBucketBits; + + // Only kBlockSize newest backward references are kept, + // and the older are forgotten. + static const uint32_t kBlockSize = 1 << kBlockBits; + + // Mask for accessing entries in a block (in a ringbuffer manner). + static const uint32_t kBlockMask = (1 << kBlockBits) - 1; + + // Number of entries in a particular bucket. + uint16_t num_[kBucketSize]; + + // Buckets containing kBlockSize of backward references. + uint32_t buckets_[kBucketSize][kBlockSize]; + + // True if num_ array needs to be initialized. + bool need_init_; + + size_t num_dict_lookups_; + size_t num_dict_matches_; +}; + +// A (forgetful) hash table where each hash bucket contains a binary tree of +// sequences whose first 4 bytes share the same hash code. +// Each sequence is kMaxTreeCompLength long and is identified by its starting +// position in the input data. The binary tree is sorted by the lexicographic +// order of the sequences, and it is also a max-heap with respect to the +// starting positions. +class HashToBinaryTree { + public: + HashToBinaryTree() : forest_(NULL) { + Reset(); + } + + ~HashToBinaryTree() { + delete[] forest_; + } + + void Reset() { + need_init_ = true; + } + + void Init(int lgwin, size_t position, size_t bytes, bool is_last) { + if (need_init_) { + window_mask_ = (1u << lgwin) - 1u; + invalid_pos_ = static_cast(-window_mask_); + for (uint32_t i = 0; i < kBucketSize; i++) { + buckets_[i] = invalid_pos_; + } + size_t num_nodes = (position == 0 && is_last) ? bytes : window_mask_ + 1; + forest_ = new uint32_t[2 * num_nodes]; + need_init_ = false; + } + } + + // Finds all backward matches of &data[cur_ix & ring_buffer_mask] up to the + // length of max_length and stores the position cur_ix in the hash table. + // + // Sets *num_matches to the number of matches found, and stores the found + // matches in matches[0] to matches[*num_matches - 1]. The matches will be + // sorted by strictly increasing length and (non-strictly) increasing + // distance. + size_t FindAllMatches(const uint8_t* data, + const size_t ring_buffer_mask, + const size_t cur_ix, + const size_t max_length, + const size_t max_backward, + BackwardMatch* matches) { + BackwardMatch* const orig_matches = matches; + const size_t cur_ix_masked = cur_ix & ring_buffer_mask; + size_t best_len = 1; + size_t stop = cur_ix - 64; + if (cur_ix < 64) { stop = 0; } + for (size_t i = cur_ix - 1; i > stop && best_len <= 2; --i) { + size_t prev_ix = i; + const size_t backward = cur_ix - prev_ix; + if (PREDICT_FALSE(backward > max_backward)) { + break; + } + prev_ix &= ring_buffer_mask; + if (data[cur_ix_masked] != data[prev_ix] || + data[cur_ix_masked + 1] != data[prev_ix + 1]) { + continue; + } + const size_t len = + FindMatchLengthWithLimit(&data[prev_ix], &data[cur_ix_masked], + max_length); + if (len > best_len) { + best_len = len; + *matches++ = BackwardMatch(backward, len); + } + } + if (best_len < max_length) { + matches = StoreAndFindMatches(data, cur_ix, ring_buffer_mask, + max_length, &best_len, matches); + } + std::vector dict_matches(kMaxDictionaryMatchLen + 1, + kInvalidMatch); + size_t minlen = std::max(4, best_len + 1); + if (FindAllStaticDictionaryMatches(&data[cur_ix_masked], minlen, max_length, + &dict_matches[0])) { + size_t maxlen = std::min(kMaxDictionaryMatchLen, max_length); + for (size_t l = minlen; l <= maxlen; ++l) { + uint32_t dict_id = dict_matches[l]; + if (dict_id < kInvalidMatch) { + *matches++ = BackwardMatch(max_backward + (dict_id >> 5) + 1, l, + dict_id & 31); + } + } + } + return static_cast(matches - orig_matches); + } + + // Stores the hash of the next 4 bytes and re-roots the binary tree at the + // current sequence, without returning any matches. + void Store(const uint8_t* data, + const size_t ring_buffer_mask, + const size_t cur_ix, + const size_t max_length) { + size_t best_len = 0; + StoreAndFindMatches(data, cur_ix, ring_buffer_mask, max_length, + &best_len, NULL); + } + + static const size_t kMaxNumMatches = 64 + kMaxTreeSearchDepth; + + private: + // Stores the hash of the next 4 bytes and in a single tree-traversal, the + // hash bucket's binary tree is searched for matches and is re-rooted at the + // current position. + // + // If less than kMaxTreeCompLength data is available, the hash bucket of the + // current position is searched for matches, but the state of the hash table + // is not changed, since we can not know the final sorting order of the + // current (incomplete) sequence. + // + // This function must be called with increasing cur_ix positions. + BackwardMatch* StoreAndFindMatches(const uint8_t* const __restrict data, + const size_t cur_ix, + const size_t ring_buffer_mask, + const size_t max_length, + size_t* const __restrict best_len, + BackwardMatch* __restrict matches) { + const size_t cur_ix_masked = cur_ix & ring_buffer_mask; + const size_t max_backward = window_mask_ - 15; + const size_t max_comp_len = std::min(max_length, kMaxTreeCompLength); + const bool reroot_tree = max_length >= kMaxTreeCompLength; + const uint32_t key = HashBytes(&data[cur_ix_masked]); + size_t prev_ix = buckets_[key]; + // The forest index of the rightmost node of the left subtree of the new + // root, updated as we traverse and reroot the tree of the hash bucket. + size_t node_left = LeftChildIndex(cur_ix); + // The forest index of the leftmost node of the right subtree of the new + // root, updated as we traverse and reroot the tree of the hash bucket. + size_t node_right = RightChildIndex(cur_ix); + // The match length of the rightmost node of the left subtree of the new + // root, updated as we traverse and reroot the tree of the hash bucket. + size_t best_len_left = 0; + // The match length of the leftmost node of the right subtree of the new + // root, updated as we traverse and reroot the tree of the hash bucket. + size_t best_len_right = 0; + if (reroot_tree) { + buckets_[key] = static_cast(cur_ix); + } + for (size_t depth_remaining = kMaxTreeSearchDepth; ; --depth_remaining) { + const size_t backward = cur_ix - prev_ix; + const size_t prev_ix_masked = prev_ix & ring_buffer_mask; + if (backward == 0 || backward > max_backward || depth_remaining == 0) { + if (reroot_tree) { + forest_[node_left] = invalid_pos_; + forest_[node_right] = invalid_pos_; + } + break; + } + const size_t cur_len = std::min(best_len_left, best_len_right); + const size_t len = cur_len + + FindMatchLengthWithLimit(&data[cur_ix_masked + cur_len], + &data[prev_ix_masked + cur_len], + max_length - cur_len); + if (len > *best_len) { + *best_len = len; + if (matches) { + *matches++ = BackwardMatch(backward, len); + } + if (len >= max_comp_len) { + if (reroot_tree) { + forest_[node_left] = forest_[LeftChildIndex(prev_ix)]; + forest_[node_right] = forest_[RightChildIndex(prev_ix)]; + } + break; + } + } + if (data[cur_ix_masked + len] > data[prev_ix_masked + len]) { + best_len_left = len; + if (reroot_tree) { + forest_[node_left] = static_cast(prev_ix); + } + node_left = RightChildIndex(prev_ix); + prev_ix = forest_[node_left]; + } else { + best_len_right = len; + if (reroot_tree) { + forest_[node_right] = static_cast(prev_ix); + } + node_right = LeftChildIndex(prev_ix); + prev_ix = forest_[node_right]; + } + } + return matches; + } + + inline size_t LeftChildIndex(const size_t pos) { + return 2 * (pos & window_mask_); + } + + inline size_t RightChildIndex(const size_t pos) { + return 2 * (pos & window_mask_) + 1; + } + + static uint32_t HashBytes(const uint8_t *data) { + uint32_t h = BROTLI_UNALIGNED_LOAD32(data) * kHashMul32; + // The higher bits contain more mixture from the multiplication, + // so we take our results from there. + return h >> (32 - kBucketBits); + } + + static const int kBucketBits = 17; + static const size_t kBucketSize = 1 << kBucketBits; + + // The window size minus 1 + size_t window_mask_; + + // Hash table that maps the 4-byte hashes of the sequence to the last + // position where this hash was found, which is the root of the binary + // tree of sequences that share this hash bucket. + uint32_t buckets_[kBucketSize]; + + // The union of the binary trees of each hash bucket. The root of the tree + // corresponding to a hash is a sequence starting at buckets_[hash] and + // the left and right children of a sequence starting at pos are + // forest_[2 * pos] and forest_[2 * pos + 1]. + uint32_t* forest_; + + // A position used to mark a non-existent sequence, i.e. a tree is empty if + // its root is at invalid_pos_ and a node is a leaf if both its children + // are at invalid_pos_. + uint32_t invalid_pos_; + + bool need_init_; +}; + +struct Hashers { + // For kBucketSweep == 1, enabling the dictionary lookup makes compression + // a little faster (0.5% - 1%) and it compresses 0.15% better on small text + // and html inputs. + typedef HashLongestMatchQuickly<16, 1, true> H2; + typedef HashLongestMatchQuickly<16, 2, false> H3; + typedef HashLongestMatchQuickly<17, 4, true> H4; + typedef HashLongestMatch<14, 4, 4> H5; + typedef HashLongestMatch<14, 5, 4> H6; + typedef HashLongestMatch<15, 6, 10> H7; + typedef HashLongestMatch<15, 7, 10> H8; + typedef HashLongestMatch<15, 8, 16> H9; + typedef HashToBinaryTree H10; + + Hashers() : hash_h2(0), hash_h3(0), hash_h4(0), hash_h5(0), + hash_h6(0), hash_h7(0), hash_h8(0), hash_h9(0), hash_h10(0) {} + + ~Hashers() { + delete hash_h2; + delete hash_h3; + delete hash_h4; + delete hash_h5; + delete hash_h6; + delete hash_h7; + delete hash_h8; + delete hash_h9; + delete hash_h10; + } + + void Init(int type) { + switch (type) { + case 2: hash_h2 = new H2; break; + case 3: hash_h3 = new H3; break; + case 4: hash_h4 = new H4; break; + case 5: hash_h5 = new H5; break; + case 6: hash_h6 = new H6; break; + case 7: hash_h7 = new H7; break; + case 8: hash_h8 = new H8; break; + case 9: hash_h9 = new H9; break; + case 10: hash_h10 = new H10; break; + default: break; + } + } + + template + void WarmupHash(const size_t size, const uint8_t* dict, Hasher* hasher) { + hasher->Init(); + for (size_t i = 0; i + Hasher::kHashTypeLength - 1 < size; i++) { + hasher->Store(&dict[i], static_cast(i)); + } + } + + // Custom LZ77 window. + void PrependCustomDictionary( + int type, int lgwin, const size_t size, const uint8_t* dict) { + switch (type) { + case 2: WarmupHash(size, dict, hash_h2); break; + case 3: WarmupHash(size, dict, hash_h3); break; + case 4: WarmupHash(size, dict, hash_h4); break; + case 5: WarmupHash(size, dict, hash_h5); break; + case 6: WarmupHash(size, dict, hash_h6); break; + case 7: WarmupHash(size, dict, hash_h7); break; + case 8: WarmupHash(size, dict, hash_h8); break; + case 9: WarmupHash(size, dict, hash_h9); break; + case 10: + hash_h10->Init(lgwin, 0, size, false); + for (size_t i = 0; i + kMaxTreeCompLength - 1 < size; ++i) { + hash_h10->Store(dict, std::numeric_limits::max(), + i, size - i); + } + break; + default: break; + } + } + + + H2* hash_h2; + H3* hash_h3; + H4* hash_h4; + H5* hash_h5; + H6* hash_h6; + H7* hash_h7; + H8* hash_h8; + H9* hash_h9; + H10* hash_h10; +}; + +} // namespace brotli + +#endif // BROTLI_ENC_HASH_H_ diff --git a/web/server/h2o/libh2o/deps/brotli/enc/histogram.cc b/web/server/h2o/libh2o/deps/brotli/enc/histogram.cc new file mode 100644 index 00000000..75235902 --- /dev/null +++ b/web/server/h2o/libh2o/deps/brotli/enc/histogram.cc @@ -0,0 +1,67 @@ +/* Copyright 2013 Google Inc. All Rights Reserved. + + Distributed under MIT license. + See file LICENSE for detail or copy at https://opensource.org/licenses/MIT +*/ + +// Build per-context histograms of literals, commands and distance codes. + +#include "./histogram.h" + +#include + +#include "./block_splitter.h" +#include "./command.h" +#include "./context.h" +#include "./prefix.h" + +namespace brotli { + +void BuildHistograms( + const Command* cmds, + const size_t num_commands, + const BlockSplit& literal_split, + const BlockSplit& insert_and_copy_split, + const BlockSplit& dist_split, + const uint8_t* ringbuffer, + size_t start_pos, + size_t mask, + uint8_t prev_byte, + uint8_t prev_byte2, + const std::vector& context_modes, + std::vector* literal_histograms, + std::vector* insert_and_copy_histograms, + std::vector* copy_dist_histograms) { + size_t pos = start_pos; + BlockSplitIterator literal_it(literal_split); + BlockSplitIterator insert_and_copy_it(insert_and_copy_split); + BlockSplitIterator dist_it(dist_split); + for (size_t i = 0; i < num_commands; ++i) { + const Command &cmd = cmds[i]; + insert_and_copy_it.Next(); + (*insert_and_copy_histograms)[insert_and_copy_it.type_].Add( + cmd.cmd_prefix_); + for (size_t j = cmd.insert_len_; j != 0; --j) { + literal_it.Next(); + size_t context = (literal_it.type_ << kLiteralContextBits) + + Context(prev_byte, prev_byte2, context_modes[literal_it.type_]); + (*literal_histograms)[context].Add(ringbuffer[pos & mask]); + prev_byte2 = prev_byte; + prev_byte = ringbuffer[pos & mask]; + ++pos; + } + pos += cmd.copy_len_; + if (cmd.copy_len_ > 0) { + prev_byte2 = ringbuffer[(pos - 2) & mask]; + prev_byte = ringbuffer[(pos - 1) & mask]; + if (cmd.cmd_prefix_ >= 128) { + dist_it.Next(); + size_t context = (dist_it.type_ << kDistanceContextBits) + + cmd.DistanceContext(); + (*copy_dist_histograms)[context].Add(cmd.dist_prefix_); + } + } + } +} + +} // namespace brotli diff --git a/web/server/h2o/libh2o/deps/brotli/enc/histogram.h b/web/server/h2o/libh2o/deps/brotli/enc/histogram.h new file mode 100644 index 00000000..298d3162 --- /dev/null +++ b/web/server/h2o/libh2o/deps/brotli/enc/histogram.h @@ -0,0 +1,94 @@ +/* Copyright 2013 Google Inc. All Rights Reserved. + + Distributed under MIT license. + See file LICENSE for detail or copy at https://opensource.org/licenses/MIT +*/ + +// Models the histograms of literals, commands and distance codes. + +#ifndef BROTLI_ENC_HISTOGRAM_H_ +#define BROTLI_ENC_HISTOGRAM_H_ + +#include +#include +#include +#include "./context.h" +#include "./command.h" +#include "./fast_log.h" +#include "./prefix.h" +#include "./types.h" + +namespace brotli { + +struct BlockSplit; + +// A simple container for histograms of data in blocks. +template +struct Histogram { + Histogram() { + Clear(); + } + void Clear() { + memset(data_, 0, sizeof(data_)); + total_count_ = 0; + bit_cost_ = std::numeric_limits::infinity(); + } + void Add(size_t val) { + ++data_[val]; + ++total_count_; + } + void Remove(size_t val) { + --data_[val]; + --total_count_; + } + template + void Add(const DataType *p, size_t n) { + total_count_ += n; + n += 1; + while(--n) ++data_[*p++]; + } + void AddHistogram(const Histogram& v) { + total_count_ += v.total_count_; + for (size_t i = 0; i < kDataSize; ++i) { + data_[i] += v.data_[i]; + } + } + + uint32_t data_[kDataSize]; + size_t total_count_; + double bit_cost_; +}; + +// Literal histogram. +typedef Histogram<256> HistogramLiteral; +// Prefix histograms. +typedef Histogram HistogramCommand; +typedef Histogram HistogramDistance; +typedef Histogram HistogramBlockLength; +// Context map histogram, 256 Huffman tree indexes + 16 run length codes. +typedef Histogram<272> HistogramContextMap; +// Block type histogram, 256 block types + 2 special symbols. +typedef Histogram<258> HistogramBlockType; + +static const size_t kLiteralContextBits = 6; +static const size_t kDistanceContextBits = 2; + +void BuildHistograms( + const Command* cmds, + const size_t num_commands, + const BlockSplit& literal_split, + const BlockSplit& insert_and_copy_split, + const BlockSplit& dist_split, + const uint8_t* ringbuffer, + size_t pos, + size_t mask, + uint8_t prev_byte, + uint8_t prev_byte2, + const std::vector& context_modes, + std::vector* literal_histograms, + std::vector* insert_and_copy_histograms, + std::vector* copy_dist_histograms); + +} // namespace brotli + +#endif // BROTLI_ENC_HISTOGRAM_H_ diff --git a/web/server/h2o/libh2o/deps/brotli/enc/literal_cost.cc b/web/server/h2o/libh2o/deps/brotli/enc/literal_cost.cc new file mode 100644 index 00000000..e13eedc9 --- /dev/null +++ b/web/server/h2o/libh2o/deps/brotli/enc/literal_cost.cc @@ -0,0 +1,165 @@ +/* Copyright 2013 Google Inc. All Rights Reserved. + + Distributed under MIT license. + See file LICENSE for detail or copy at https://opensource.org/licenses/MIT +*/ + +// Literal cost model to allow backward reference replacement to be efficient. + +#include "./literal_cost.h" + +#include +#include + +#include "./fast_log.h" +#include "./types.h" +#include "./utf8_util.h" + +namespace brotli { + +static size_t UTF8Position(size_t last, size_t c, size_t clamp) { + if (c < 128) { + return 0; // Next one is the 'Byte 1' again. + } else if (c >= 192) { // Next one is the 'Byte 2' of utf-8 encoding. + return std::min(1, clamp); + } else { + // Let's decide over the last byte if this ends the sequence. + if (last < 0xe0) { + return 0; // Completed two or three byte coding. + } else { // Next one is the 'Byte 3' of utf-8 encoding. + return std::min(2, clamp); + } + } +} + +static size_t DecideMultiByteStatsLevel(size_t pos, size_t len, size_t mask, + const uint8_t *data) { + size_t counts[3] = { 0 }; + size_t max_utf8 = 1; // should be 2, but 1 compresses better. + size_t last_c = 0; + size_t utf8_pos = 0; + for (size_t i = 0; i < len; ++i) { + size_t c = data[(pos + i) & mask]; + utf8_pos = UTF8Position(last_c, c, 2); + ++counts[utf8_pos]; + last_c = c; + } + if (counts[2] < 500) { + max_utf8 = 1; + } + if (counts[1] + counts[2] < 25) { + max_utf8 = 0; + } + return max_utf8; +} + +void EstimateBitCostsForLiteralsUTF8(size_t pos, size_t len, size_t mask, + const uint8_t *data, float *cost) { + + // max_utf8 is 0 (normal ascii single byte modeling), + // 1 (for 2-byte utf-8 modeling), or 2 (for 3-byte utf-8 modeling). + const size_t max_utf8 = DecideMultiByteStatsLevel(pos, len, mask, data); + size_t histogram[3][256] = { { 0 } }; + size_t window_half = 495; + size_t in_window = std::min(window_half, len); + size_t in_window_utf8[3] = { 0 }; + + // Bootstrap histograms. + size_t last_c = 0; + size_t utf8_pos = 0; + for (size_t i = 0; i < in_window; ++i) { + size_t c = data[(pos + i) & mask]; + ++histogram[utf8_pos][c]; + ++in_window_utf8[utf8_pos]; + utf8_pos = UTF8Position(last_c, c, max_utf8); + last_c = c; + } + + // Compute bit costs with sliding window. + for (size_t i = 0; i < len; ++i) { + if (i >= window_half) { + // Remove a byte in the past. + size_t c = i < window_half + 1 ? + 0 : data[(pos + i - window_half - 1) & mask]; + size_t last_c = i < window_half + 2 ? + 0 : data[(pos + i - window_half - 2) & mask]; + size_t utf8_pos2 = UTF8Position(last_c, c, max_utf8); + --histogram[utf8_pos2][data[(pos + i - window_half) & mask]]; + --in_window_utf8[utf8_pos2]; + } + if (i + window_half < len) { + // Add a byte in the future. + size_t c = data[(pos + i + window_half - 1) & mask]; + size_t last_c = data[(pos + i + window_half - 2) & mask]; + size_t utf8_pos2 = UTF8Position(last_c, c, max_utf8); + ++histogram[utf8_pos2][data[(pos + i + window_half) & mask]]; + ++in_window_utf8[utf8_pos2]; + } + size_t c = i < 1 ? 0 : data[(pos + i - 1) & mask]; + size_t last_c = i < 2 ? 0 : data[(pos + i - 2) & mask]; + size_t utf8_pos = UTF8Position(last_c, c, max_utf8); + size_t masked_pos = (pos + i) & mask; + size_t histo = histogram[utf8_pos][data[masked_pos]]; + if (histo == 0) { + histo = 1; + } + double lit_cost = FastLog2(in_window_utf8[utf8_pos]) - FastLog2(histo); + lit_cost += 0.02905; + if (lit_cost < 1.0) { + lit_cost *= 0.5; + lit_cost += 0.5; + } + // Make the first bytes more expensive -- seems to help, not sure why. + // Perhaps because the entropy source is changing its properties + // rapidly in the beginning of the file, perhaps because the beginning + // of the data is a statistical "anomaly". + if (i < 2000) { + lit_cost += 0.7 - (static_cast(2000 - i) / 2000.0 * 0.35); + } + cost[i] = static_cast(lit_cost); + } +} + +void EstimateBitCostsForLiterals(size_t pos, size_t len, size_t mask, + const uint8_t *data, float *cost) { + if (IsMostlyUTF8(data, pos, mask, len, kMinUTF8Ratio)) { + EstimateBitCostsForLiteralsUTF8(pos, len, mask, data, cost); + return; + } + size_t histogram[256] = { 0 }; + size_t window_half = 2000; + size_t in_window = std::min(window_half, len); + + // Bootstrap histogram. + for (size_t i = 0; i < in_window; ++i) { + ++histogram[data[(pos + i) & mask]]; + } + + // Compute bit costs with sliding window. + for (size_t i = 0; i < len; ++i) { + if (i >= window_half) { + // Remove a byte in the past. + --histogram[data[(pos + i - window_half) & mask]]; + --in_window; + } + if (i + window_half < len) { + // Add a byte in the future. + ++histogram[data[(pos + i + window_half) & mask]]; + ++in_window; + } + size_t histo = histogram[data[(pos + i) & mask]]; + if (histo == 0) { + histo = 1; + } + double lit_cost = FastLog2(in_window) - FastLog2(histo); + lit_cost += 0.029; + if (lit_cost < 1.0) { + lit_cost *= 0.5; + lit_cost += 0.5; + } + cost[i] = static_cast(lit_cost); + } +} + + +} // namespace brotli diff --git a/web/server/h2o/libh2o/deps/brotli/enc/literal_cost.h b/web/server/h2o/libh2o/deps/brotli/enc/literal_cost.h new file mode 100644 index 00000000..291aa8a1 --- /dev/null +++ b/web/server/h2o/libh2o/deps/brotli/enc/literal_cost.h @@ -0,0 +1,24 @@ +/* Copyright 2013 Google Inc. All Rights Reserved. + + Distributed under MIT license. + See file LICENSE for detail or copy at https://opensource.org/licenses/MIT +*/ + +// Literal cost model to allow backward reference replacement to be efficient. + +#ifndef BROTLI_ENC_LITERAL_COST_H_ +#define BROTLI_ENC_LITERAL_COST_H_ + +#include "./types.h" + +namespace brotli { + +// Estimates how many bits the literals in the interval [pos, pos + len) in the +// ringbuffer (data, mask) will take entropy coded and writes these estimates +// to the cost[0..len) array. +void EstimateBitCostsForLiterals(size_t pos, size_t len, size_t mask, + const uint8_t *data, float *cost); + +} // namespace brotli + +#endif // BROTLI_ENC_LITERAL_COST_H_ diff --git a/web/server/h2o/libh2o/deps/brotli/enc/metablock.cc b/web/server/h2o/libh2o/deps/brotli/enc/metablock.cc new file mode 100644 index 00000000..d6ea8426 --- /dev/null +++ b/web/server/h2o/libh2o/deps/brotli/enc/metablock.cc @@ -0,0 +1,534 @@ +/* Copyright 2015 Google Inc. All Rights Reserved. + + Distributed under MIT license. + See file LICENSE for detail or copy at https://opensource.org/licenses/MIT +*/ + +// Algorithms for distributing the literals and commands of a metablock between +// block types and contexts. + +#include "./metablock.h" + +#include "./block_splitter.h" +#include "./context.h" +#include "./cluster.h" +#include "./histogram.h" + +namespace brotli { + +void BuildMetaBlock(const uint8_t* ringbuffer, + const size_t pos, + const size_t mask, + uint8_t prev_byte, + uint8_t prev_byte2, + const Command* cmds, + size_t num_commands, + ContextType literal_context_mode, + MetaBlockSplit* mb) { + SplitBlock(cmds, num_commands, + ringbuffer, pos, mask, + &mb->literal_split, + &mb->command_split, + &mb->distance_split); + + std::vector literal_context_modes(mb->literal_split.num_types, + literal_context_mode); + + size_t num_literal_contexts = + mb->literal_split.num_types << kLiteralContextBits; + size_t num_distance_contexts = + mb->distance_split.num_types << kDistanceContextBits; + std::vector literal_histograms(num_literal_contexts); + mb->command_histograms.resize(mb->command_split.num_types); + std::vector distance_histograms(num_distance_contexts); + BuildHistograms(cmds, num_commands, + mb->literal_split, + mb->command_split, + mb->distance_split, + ringbuffer, + pos, + mask, + prev_byte, + prev_byte2, + literal_context_modes, + &literal_histograms, + &mb->command_histograms, + &distance_histograms); + + // Histogram ids need to fit in one byte. + static const size_t kMaxNumberOfHistograms = 256; + + ClusterHistograms(literal_histograms, + 1u << kLiteralContextBits, + mb->literal_split.num_types, + kMaxNumberOfHistograms, + &mb->literal_histograms, + &mb->literal_context_map); + + ClusterHistograms(distance_histograms, + 1u << kDistanceContextBits, + mb->distance_split.num_types, + kMaxNumberOfHistograms, + &mb->distance_histograms, + &mb->distance_context_map); +} + +// Greedy block splitter for one block category (literal, command or distance). +template +class BlockSplitter { + public: + BlockSplitter(size_t alphabet_size, + size_t min_block_size, + double split_threshold, + size_t num_symbols, + BlockSplit* split, + std::vector* histograms) + : alphabet_size_(alphabet_size), + min_block_size_(min_block_size), + split_threshold_(split_threshold), + num_blocks_(0), + split_(split), + histograms_(histograms), + target_block_size_(min_block_size), + block_size_(0), + curr_histogram_ix_(0), + merge_last_count_(0) { + size_t max_num_blocks = num_symbols / min_block_size + 1; + // We have to allocate one more histogram than the maximum number of block + // types for the current histogram when the meta-block is too big. + size_t max_num_types = std::min(max_num_blocks, kMaxBlockTypes + 1); + split_->lengths.resize(max_num_blocks); + split_->types.resize(max_num_blocks); + histograms_->resize(max_num_types); + last_histogram_ix_[0] = last_histogram_ix_[1] = 0; + } + + // Adds the next symbol to the current histogram. When the current histogram + // reaches the target size, decides on merging the block. + void AddSymbol(size_t symbol) { + (*histograms_)[curr_histogram_ix_].Add(symbol); + ++block_size_; + if (block_size_ == target_block_size_) { + FinishBlock(/* is_final = */ false); + } + } + + // Does either of three things: + // (1) emits the current block with a new block type; + // (2) emits the current block with the type of the second last block; + // (3) merges the current block with the last block. + void FinishBlock(bool is_final) { + if (block_size_ < min_block_size_) { + block_size_ = min_block_size_; + } + if (num_blocks_ == 0) { + // Create first block. + split_->lengths[0] = static_cast(block_size_); + split_->types[0] = 0; + last_entropy_[0] = + BitsEntropy(&(*histograms_)[0].data_[0], alphabet_size_); + last_entropy_[1] = last_entropy_[0]; + ++num_blocks_; + ++split_->num_types; + ++curr_histogram_ix_; + block_size_ = 0; + } else if (block_size_ > 0) { + double entropy = BitsEntropy(&(*histograms_)[curr_histogram_ix_].data_[0], + alphabet_size_); + HistogramType combined_histo[2]; + double combined_entropy[2]; + double diff[2]; + for (size_t j = 0; j < 2; ++j) { + size_t last_histogram_ix = last_histogram_ix_[j]; + combined_histo[j] = (*histograms_)[curr_histogram_ix_]; + combined_histo[j].AddHistogram((*histograms_)[last_histogram_ix]); + combined_entropy[j] = BitsEntropy( + &combined_histo[j].data_[0], alphabet_size_); + diff[j] = combined_entropy[j] - entropy - last_entropy_[j]; + } + + if (split_->num_types < kMaxBlockTypes && + diff[0] > split_threshold_ && + diff[1] > split_threshold_) { + // Create new block. + split_->lengths[num_blocks_] = static_cast(block_size_); + split_->types[num_blocks_] = static_cast(split_->num_types); + last_histogram_ix_[1] = last_histogram_ix_[0]; + last_histogram_ix_[0] = static_cast(split_->num_types); + last_entropy_[1] = last_entropy_[0]; + last_entropy_[0] = entropy; + ++num_blocks_; + ++split_->num_types; + ++curr_histogram_ix_; + block_size_ = 0; + merge_last_count_ = 0; + target_block_size_ = min_block_size_; + } else if (diff[1] < diff[0] - 20.0) { + // Combine this block with second last block. + split_->lengths[num_blocks_] = static_cast(block_size_); + split_->types[num_blocks_] = split_->types[num_blocks_ - 2]; + std::swap(last_histogram_ix_[0], last_histogram_ix_[1]); + (*histograms_)[last_histogram_ix_[0]] = combined_histo[1]; + last_entropy_[1] = last_entropy_[0]; + last_entropy_[0] = combined_entropy[1]; + ++num_blocks_; + block_size_ = 0; + (*histograms_)[curr_histogram_ix_].Clear(); + merge_last_count_ = 0; + target_block_size_ = min_block_size_; + } else { + // Combine this block with last block. + split_->lengths[num_blocks_ - 1] += static_cast(block_size_); + (*histograms_)[last_histogram_ix_[0]] = combined_histo[0]; + last_entropy_[0] = combined_entropy[0]; + if (split_->num_types == 1) { + last_entropy_[1] = last_entropy_[0]; + } + block_size_ = 0; + (*histograms_)[curr_histogram_ix_].Clear(); + if (++merge_last_count_ > 1) { + target_block_size_ += min_block_size_; + } + } + } + if (is_final) { + (*histograms_).resize(split_->num_types); + split_->types.resize(num_blocks_); + split_->lengths.resize(num_blocks_); + } + } + + private: + static const uint16_t kMaxBlockTypes = 256; + + // Alphabet size of particular block category. + const size_t alphabet_size_; + // We collect at least this many symbols for each block. + const size_t min_block_size_; + // We merge histograms A and B if + // entropy(A+B) < entropy(A) + entropy(B) + split_threshold_, + // where A is the current histogram and B is the histogram of the last or the + // second last block type. + const double split_threshold_; + + size_t num_blocks_; + BlockSplit* split_; // not owned + std::vector* histograms_; // not owned + + // The number of symbols that we want to collect before deciding on whether + // or not to merge the block with a previous one or emit a new block. + size_t target_block_size_; + // The number of symbols in the current histogram. + size_t block_size_; + // Offset of the current histogram. + size_t curr_histogram_ix_; + // Offset of the histograms of the previous two block types. + size_t last_histogram_ix_[2]; + // Entropy of the previous two block types. + double last_entropy_[2]; + // The number of times we merged the current block with the last one. + size_t merge_last_count_; +}; + +void BuildMetaBlockGreedy(const uint8_t* ringbuffer, + size_t pos, + size_t mask, + const Command *commands, + size_t n_commands, + MetaBlockSplit* mb) { + size_t num_literals = 0; + for (size_t i = 0; i < n_commands; ++i) { + num_literals += commands[i].insert_len_; + } + + BlockSplitter lit_blocks( + 256, 512, 400.0, num_literals, + &mb->literal_split, &mb->literal_histograms); + BlockSplitter cmd_blocks( + kNumCommandPrefixes, 1024, 500.0, n_commands, + &mb->command_split, &mb->command_histograms); + BlockSplitter dist_blocks( + 64, 512, 100.0, n_commands, + &mb->distance_split, &mb->distance_histograms); + + for (size_t i = 0; i < n_commands; ++i) { + const Command cmd = commands[i]; + cmd_blocks.AddSymbol(cmd.cmd_prefix_); + for (size_t j = cmd.insert_len_; j != 0; --j) { + lit_blocks.AddSymbol(ringbuffer[pos & mask]); + ++pos; + } + pos += cmd.copy_len_; + if (cmd.copy_len_ > 0 && cmd.cmd_prefix_ >= 128) { + dist_blocks.AddSymbol(cmd.dist_prefix_); + } + } + + lit_blocks.FinishBlock(/* is_final = */ true); + cmd_blocks.FinishBlock(/* is_final = */ true); + dist_blocks.FinishBlock(/* is_final = */ true); +} + +// Greedy block splitter for one block category (literal, command or distance). +// Gathers histograms for all context buckets. +template +class ContextBlockSplitter { + public: + ContextBlockSplitter(size_t alphabet_size, + size_t num_contexts, + size_t min_block_size, + double split_threshold, + size_t num_symbols, + BlockSplit* split, + std::vector* histograms) + : alphabet_size_(alphabet_size), + num_contexts_(num_contexts), + max_block_types_(kMaxBlockTypes / num_contexts), + min_block_size_(min_block_size), + split_threshold_(split_threshold), + num_blocks_(0), + split_(split), + histograms_(histograms), + target_block_size_(min_block_size), + block_size_(0), + curr_histogram_ix_(0), + last_entropy_(2 * num_contexts), + merge_last_count_(0) { + size_t max_num_blocks = num_symbols / min_block_size + 1; + // We have to allocate one more histogram than the maximum number of block + // types for the current histogram when the meta-block is too big. + size_t max_num_types = std::min(max_num_blocks, max_block_types_ + 1); + split_->lengths.resize(max_num_blocks); + split_->types.resize(max_num_blocks); + histograms_->resize(max_num_types * num_contexts); + last_histogram_ix_[0] = last_histogram_ix_[1] = 0; + } + + // Adds the next symbol to the current block type and context. When the + // current block reaches the target size, decides on merging the block. + void AddSymbol(size_t symbol, size_t context) { + (*histograms_)[curr_histogram_ix_ + context].Add(symbol); + ++block_size_; + if (block_size_ == target_block_size_) { + FinishBlock(/* is_final = */ false); + } + } + + // Does either of three things: + // (1) emits the current block with a new block type; + // (2) emits the current block with the type of the second last block; + // (3) merges the current block with the last block. + void FinishBlock(bool is_final) { + if (block_size_ < min_block_size_) { + block_size_ = min_block_size_; + } + if (num_blocks_ == 0) { + // Create first block. + split_->lengths[0] = static_cast(block_size_); + split_->types[0] = 0; + for (size_t i = 0; i < num_contexts_; ++i) { + last_entropy_[i] = + BitsEntropy(&(*histograms_)[i].data_[0], alphabet_size_); + last_entropy_[num_contexts_ + i] = last_entropy_[i]; + } + ++num_blocks_; + ++split_->num_types; + curr_histogram_ix_ += num_contexts_; + block_size_ = 0; + } else if (block_size_ > 0) { + // Try merging the set of histograms for the current block type with the + // respective set of histograms for the last and second last block types. + // Decide over the split based on the total reduction of entropy across + // all contexts. + std::vector entropy(num_contexts_); + std::vector combined_histo(2 * num_contexts_); + std::vector combined_entropy(2 * num_contexts_); + double diff[2] = { 0.0 }; + for (size_t i = 0; i < num_contexts_; ++i) { + size_t curr_histo_ix = curr_histogram_ix_ + i; + entropy[i] = BitsEntropy(&(*histograms_)[curr_histo_ix].data_[0], + alphabet_size_); + for (size_t j = 0; j < 2; ++j) { + size_t jx = j * num_contexts_ + i; + size_t last_histogram_ix = last_histogram_ix_[j] + i; + combined_histo[jx] = (*histograms_)[curr_histo_ix]; + combined_histo[jx].AddHistogram((*histograms_)[last_histogram_ix]); + combined_entropy[jx] = BitsEntropy( + &combined_histo[jx].data_[0], alphabet_size_); + diff[j] += combined_entropy[jx] - entropy[i] - last_entropy_[jx]; + } + } + + if (split_->num_types < max_block_types_ && + diff[0] > split_threshold_ && + diff[1] > split_threshold_) { + // Create new block. + split_->lengths[num_blocks_] = static_cast(block_size_); + split_->types[num_blocks_] = static_cast(split_->num_types); + last_histogram_ix_[1] = last_histogram_ix_[0]; + last_histogram_ix_[0] = split_->num_types * num_contexts_; + for (size_t i = 0; i < num_contexts_; ++i) { + last_entropy_[num_contexts_ + i] = last_entropy_[i]; + last_entropy_[i] = entropy[i]; + } + ++num_blocks_; + ++split_->num_types; + curr_histogram_ix_ += num_contexts_; + block_size_ = 0; + merge_last_count_ = 0; + target_block_size_ = min_block_size_; + } else if (diff[1] < diff[0] - 20.0) { + // Combine this block with second last block. + split_->lengths[num_blocks_] = static_cast(block_size_); + split_->types[num_blocks_] = split_->types[num_blocks_ - 2]; + std::swap(last_histogram_ix_[0], last_histogram_ix_[1]); + for (size_t i = 0; i < num_contexts_; ++i) { + (*histograms_)[last_histogram_ix_[0] + i] = + combined_histo[num_contexts_ + i]; + last_entropy_[num_contexts_ + i] = last_entropy_[i]; + last_entropy_[i] = combined_entropy[num_contexts_ + i]; + (*histograms_)[curr_histogram_ix_ + i].Clear(); + } + ++num_blocks_; + block_size_ = 0; + merge_last_count_ = 0; + target_block_size_ = min_block_size_; + } else { + // Combine this block with last block. + split_->lengths[num_blocks_ - 1] += static_cast(block_size_); + for (size_t i = 0; i < num_contexts_; ++i) { + (*histograms_)[last_histogram_ix_[0] + i] = combined_histo[i]; + last_entropy_[i] = combined_entropy[i]; + if (split_->num_types == 1) { + last_entropy_[num_contexts_ + i] = last_entropy_[i]; + } + (*histograms_)[curr_histogram_ix_ + i].Clear(); + } + block_size_ = 0; + if (++merge_last_count_ > 1) { + target_block_size_ += min_block_size_; + } + } + } + if (is_final) { + (*histograms_).resize(split_->num_types * num_contexts_); + split_->types.resize(num_blocks_); + split_->lengths.resize(num_blocks_); + } + } + + private: + static const int kMaxBlockTypes = 256; + + // Alphabet size of particular block category. + const size_t alphabet_size_; + const size_t num_contexts_; + const size_t max_block_types_; + // We collect at least this many symbols for each block. + const size_t min_block_size_; + // We merge histograms A and B if + // entropy(A+B) < entropy(A) + entropy(B) + split_threshold_, + // where A is the current histogram and B is the histogram of the last or the + // second last block type. + const double split_threshold_; + + size_t num_blocks_; + BlockSplit* split_; // not owned + std::vector* histograms_; // not owned + + // The number of symbols that we want to collect before deciding on whether + // or not to merge the block with a previous one or emit a new block. + size_t target_block_size_; + // The number of symbols in the current histogram. + size_t block_size_; + // Offset of the current histogram. + size_t curr_histogram_ix_; + // Offset of the histograms of the previous two block types. + size_t last_histogram_ix_[2]; + // Entropy of the previous two block types. + std::vector last_entropy_; + // The number of times we merged the current block with the last one. + size_t merge_last_count_; +}; + +void BuildMetaBlockGreedyWithContexts(const uint8_t* ringbuffer, + size_t pos, + size_t mask, + uint8_t prev_byte, + uint8_t prev_byte2, + ContextType literal_context_mode, + size_t num_contexts, + const uint32_t* static_context_map, + const Command *commands, + size_t n_commands, + MetaBlockSplit* mb) { + size_t num_literals = 0; + for (size_t i = 0; i < n_commands; ++i) { + num_literals += commands[i].insert_len_; + } + + ContextBlockSplitter lit_blocks( + 256, num_contexts, 512, 400.0, num_literals, + &mb->literal_split, &mb->literal_histograms); + BlockSplitter cmd_blocks( + kNumCommandPrefixes, 1024, 500.0, n_commands, + &mb->command_split, &mb->command_histograms); + BlockSplitter dist_blocks( + 64, 512, 100.0, n_commands, + &mb->distance_split, &mb->distance_histograms); + + for (size_t i = 0; i < n_commands; ++i) { + const Command cmd = commands[i]; + cmd_blocks.AddSymbol(cmd.cmd_prefix_); + for (size_t j = cmd.insert_len_; j != 0; --j) { + size_t context = Context(prev_byte, prev_byte2, literal_context_mode); + uint8_t literal = ringbuffer[pos & mask]; + lit_blocks.AddSymbol(literal, static_context_map[context]); + prev_byte2 = prev_byte; + prev_byte = literal; + ++pos; + } + pos += cmd.copy_len_; + if (cmd.copy_len_ > 0) { + prev_byte2 = ringbuffer[(pos - 2) & mask]; + prev_byte = ringbuffer[(pos - 1) & mask]; + if (cmd.cmd_prefix_ >= 128) { + dist_blocks.AddSymbol(cmd.dist_prefix_); + } + } + } + + lit_blocks.FinishBlock(/* is_final = */ true); + cmd_blocks.FinishBlock(/* is_final = */ true); + dist_blocks.FinishBlock(/* is_final = */ true); + + mb->literal_context_map.resize( + mb->literal_split.num_types << kLiteralContextBits); + for (size_t i = 0; i < mb->literal_split.num_types; ++i) { + for (size_t j = 0; j < (1u << kLiteralContextBits); ++j) { + mb->literal_context_map[(i << kLiteralContextBits) + j] = + static_cast(i * num_contexts) + static_context_map[j]; + } + } +} + +void OptimizeHistograms(size_t num_direct_distance_codes, + size_t distance_postfix_bits, + MetaBlockSplit* mb) { + for (size_t i = 0; i < mb->literal_histograms.size(); ++i) { + OptimizeHuffmanCountsForRle(256, &mb->literal_histograms[i].data_[0]); + } + for (size_t i = 0; i < mb->command_histograms.size(); ++i) { + OptimizeHuffmanCountsForRle(kNumCommandPrefixes, + &mb->command_histograms[i].data_[0]); + } + size_t num_distance_codes = + kNumDistanceShortCodes + num_direct_distance_codes + + (48u << distance_postfix_bits); + for (size_t i = 0; i < mb->distance_histograms.size(); ++i) { + OptimizeHuffmanCountsForRle(num_distance_codes, + &mb->distance_histograms[i].data_[0]); + } +} + +} // namespace brotli diff --git a/web/server/h2o/libh2o/deps/brotli/enc/metablock.h b/web/server/h2o/libh2o/deps/brotli/enc/metablock.h new file mode 100644 index 00000000..00c739b0 --- /dev/null +++ b/web/server/h2o/libh2o/deps/brotli/enc/metablock.h @@ -0,0 +1,80 @@ +/* Copyright 2015 Google Inc. All Rights Reserved. + + Distributed under MIT license. + See file LICENSE for detail or copy at https://opensource.org/licenses/MIT +*/ + +// Algorithms for distributing the literals and commands of a metablock between +// block types and contexts. + +#ifndef BROTLI_ENC_METABLOCK_H_ +#define BROTLI_ENC_METABLOCK_H_ + +#include + +#include "./command.h" +#include "./histogram.h" + +namespace brotli { + +struct BlockSplit { + BlockSplit() : num_types(0) {} + + size_t num_types; + std::vector types; + std::vector lengths; +}; + +struct MetaBlockSplit { + BlockSplit literal_split; + BlockSplit command_split; + BlockSplit distance_split; + std::vector literal_context_map; + std::vector distance_context_map; + std::vector literal_histograms; + std::vector command_histograms; + std::vector distance_histograms; +}; + +// Uses the slow shortest-path block splitter and does context clustering. +void BuildMetaBlock(const uint8_t* ringbuffer, + const size_t pos, + const size_t mask, + uint8_t prev_byte, + uint8_t prev_byte2, + const Command* cmds, + size_t num_commands, + ContextType literal_context_mode, + MetaBlockSplit* mb); + +// Uses a fast greedy block splitter that tries to merge current block with the +// last or the second last block and does not do any context modeling. +void BuildMetaBlockGreedy(const uint8_t* ringbuffer, + size_t pos, + size_t mask, + const Command *commands, + size_t n_commands, + MetaBlockSplit* mb); + +// Uses a fast greedy block splitter that tries to merge current block with the +// last or the second last block and uses a static context clustering which +// is the same for all block types. +void BuildMetaBlockGreedyWithContexts(const uint8_t* ringbuffer, + size_t pos, + size_t mask, + uint8_t prev_byte, + uint8_t prev_byte2, + ContextType literal_context_mode, + size_t num_contexts, + const uint32_t* static_context_map, + const Command *commands, + size_t n_commands, + MetaBlockSplit* mb); + +void OptimizeHistograms(size_t num_direct_distance_codes, + size_t distance_postfix_bits, + MetaBlockSplit* mb); + +} // namespace brotli + +#endif // BROTLI_ENC_METABLOCK_H_ diff --git a/web/server/h2o/libh2o/deps/brotli/enc/port.h b/web/server/h2o/libh2o/deps/brotli/enc/port.h new file mode 100644 index 00000000..e73df63a --- /dev/null +++ b/web/server/h2o/libh2o/deps/brotli/enc/port.h @@ -0,0 +1,142 @@ +/* Copyright 2013 Google Inc. All Rights Reserved. + + Distributed under MIT license. + See file LICENSE for detail or copy at https://opensource.org/licenses/MIT +*/ + +// Macros for endianness, branch prediction and unaligned loads and stores. + +#ifndef BROTLI_ENC_PORT_H_ +#define BROTLI_ENC_PORT_H_ + +#include +#include +#include "./types.h" + +#if defined OS_LINUX || defined OS_CYGWIN +#include +#elif defined OS_FREEBSD +#include +#elif defined OS_MACOSX +#include +/* Let's try and follow the Linux convention */ +#define __BYTE_ORDER BYTE_ORDER +#define __LITTLE_ENDIAN LITTLE_ENDIAN +#endif + +// define the macro IS_LITTLE_ENDIAN +// using the above endian definitions from endian.h if +// endian.h was included +#ifdef __BYTE_ORDER +#if __BYTE_ORDER == __LITTLE_ENDIAN +#define IS_LITTLE_ENDIAN +#endif + +#else + +#if defined(__LITTLE_ENDIAN__) +#define IS_LITTLE_ENDIAN +#endif +#endif // __BYTE_ORDER + +#if defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__) +#define IS_LITTLE_ENDIAN +#endif + +// Enable little-endian optimization for x64 architecture on Windows. +#if (defined(_WIN32) || defined(_WIN64)) && defined(_M_X64) +#define IS_LITTLE_ENDIAN +#endif + +/* Compatibility with non-clang compilers. */ +#ifndef __has_builtin +#define __has_builtin(x) 0 +#endif + +#if (__GNUC__ > 2) || (__GNUC__ == 2 && __GNUC_MINOR__ > 95) || \ + (defined(__llvm__) && __has_builtin(__builtin_expect)) +#define PREDICT_FALSE(x) (__builtin_expect(x, 0)) +#define PREDICT_TRUE(x) (__builtin_expect(!!(x), 1)) +#else +#define PREDICT_FALSE(x) (x) +#define PREDICT_TRUE(x) (x) +#endif + +// Portable handling of unaligned loads, stores, and copies. +// On some platforms, like ARM, the copy functions can be more efficient +// then a load and a store. + +#if defined(ARCH_PIII) || \ + defined(ARCH_ATHLON) || defined(ARCH_K8) || defined(_ARCH_PPC) + +// x86 and x86-64 can perform unaligned loads/stores directly; +// modern PowerPC hardware can also do unaligned integer loads and stores; +// but note: the FPU still sends unaligned loads and stores to a trap handler! + +#define BROTLI_UNALIGNED_LOAD32(_p) (*reinterpret_cast(_p)) +#define BROTLI_UNALIGNED_LOAD64(_p) (*reinterpret_cast(_p)) + +#define BROTLI_UNALIGNED_STORE32(_p, _val) \ + (*reinterpret_cast(_p) = (_val)) +#define BROTLI_UNALIGNED_STORE64(_p, _val) \ + (*reinterpret_cast(_p) = (_val)) + +#elif defined(__arm__) && \ + !defined(__ARM_ARCH_5__) && \ + !defined(__ARM_ARCH_5T__) && \ + !defined(__ARM_ARCH_5TE__) && \ + !defined(__ARM_ARCH_5TEJ__) && \ + !defined(__ARM_ARCH_6__) && \ + !defined(__ARM_ARCH_6J__) && \ + !defined(__ARM_ARCH_6K__) && \ + !defined(__ARM_ARCH_6Z__) && \ + !defined(__ARM_ARCH_6ZK__) && \ + !defined(__ARM_ARCH_6T2__) + +// ARMv7 and newer support native unaligned accesses, but only of 16-bit +// and 32-bit values (not 64-bit); older versions either raise a fatal signal, +// do an unaligned read and rotate the words around a bit, or do the reads very +// slowly (trip through kernel mode). + +#define BROTLI_UNALIGNED_LOAD32(_p) (*reinterpret_cast(_p)) +#define BROTLI_UNALIGNED_STORE32(_p, _val) \ + (*reinterpret_cast(_p) = (_val)) + +inline uint64_t BROTLI_UNALIGNED_LOAD64(const void *p) { + uint64_t t; + memcpy(&t, p, sizeof t); + return t; +} + +inline void BROTLI_UNALIGNED_STORE64(void *p, uint64_t v) { + memcpy(p, &v, sizeof v); +} + +#else + +// These functions are provided for architectures that don't support +// unaligned loads and stores. + +inline uint32_t BROTLI_UNALIGNED_LOAD32(const void *p) { + uint32_t t; + memcpy(&t, p, sizeof t); + return t; +} + +inline uint64_t BROTLI_UNALIGNED_LOAD64(const void *p) { + uint64_t t; + memcpy(&t, p, sizeof t); + return t; +} + +inline void BROTLI_UNALIGNED_STORE32(void *p, uint32_t v) { + memcpy(p, &v, sizeof v); +} + +inline void BROTLI_UNALIGNED_STORE64(void *p, uint64_t v) { + memcpy(p, &v, sizeof v); +} + +#endif + +#endif // BROTLI_ENC_PORT_H_ diff --git a/web/server/h2o/libh2o/deps/brotli/enc/prefix.h b/web/server/h2o/libh2o/deps/brotli/enc/prefix.h new file mode 100644 index 00000000..0d11cdac --- /dev/null +++ b/web/server/h2o/libh2o/deps/brotli/enc/prefix.h @@ -0,0 +1,79 @@ +/* Copyright 2013 Google Inc. All Rights Reserved. + + Distributed under MIT license. + See file LICENSE for detail or copy at https://opensource.org/licenses/MIT +*/ + +// Functions for encoding of integers into prefix codes the amount of extra +// bits, and the actual values of the extra bits. + +#ifndef BROTLI_ENC_PREFIX_H_ +#define BROTLI_ENC_PREFIX_H_ + +#include "./fast_log.h" +#include "./types.h" + +namespace brotli { + +static const uint32_t kNumInsertLenPrefixes = 24; +static const uint32_t kNumCopyLenPrefixes = 24; +static const uint32_t kNumCommandPrefixes = 704; +static const uint32_t kNumBlockLenPrefixes = 26; +static const uint32_t kNumDistanceShortCodes = 16; +static const uint32_t kNumDistancePrefixes = 520; + +// Represents the range of values belonging to a prefix code: +// [offset, offset + 2^nbits) +struct PrefixCodeRange { + uint32_t offset; + uint32_t nbits; +}; + +static const PrefixCodeRange kBlockLengthPrefixCode[kNumBlockLenPrefixes] = { + { 1, 2}, { 5, 2}, { 9, 2}, { 13, 2}, + { 17, 3}, { 25, 3}, { 33, 3}, { 41, 3}, + { 49, 4}, { 65, 4}, { 81, 4}, { 97, 4}, + { 113, 5}, { 145, 5}, { 177, 5}, { 209, 5}, + { 241, 6}, { 305, 6}, { 369, 7}, { 497, 8}, + { 753, 9}, { 1265, 10}, {2289, 11}, {4337, 12}, + {8433, 13}, {16625, 24} +}; + +inline void GetBlockLengthPrefixCode(uint32_t len, uint32_t* code, + uint32_t* n_extra, uint32_t* extra) { + *code = 0; + while (*code < 25 && len >= kBlockLengthPrefixCode[*code + 1].offset) { + ++(*code); + } + *n_extra = kBlockLengthPrefixCode[*code].nbits; + *extra = len - kBlockLengthPrefixCode[*code].offset; +} + +inline void PrefixEncodeCopyDistance(size_t distance_code, + size_t num_direct_codes, + size_t postfix_bits, + uint16_t* code, + uint32_t* extra_bits) { + if (distance_code < kNumDistanceShortCodes + num_direct_codes) { + *code = static_cast(distance_code); + *extra_bits = 0; + return; + } + distance_code -= kNumDistanceShortCodes + num_direct_codes; /* >= 0 */ + distance_code += (1 << (postfix_bits + 2)); /* > 0 */ + size_t bucket = Log2FloorNonZero(distance_code) - 1; + size_t postfix_mask = (1 << postfix_bits) - 1; + size_t postfix = distance_code & postfix_mask; + size_t prefix = (distance_code >> bucket) & 1; + size_t offset = (2 + prefix) << bucket; + size_t nbits = bucket - postfix_bits; + *code = static_cast( + (kNumDistanceShortCodes + num_direct_codes + + ((2 * (nbits - 1) + prefix) << postfix_bits) + postfix)); + *extra_bits = static_cast( + (nbits << 24) | ((distance_code - offset) >> postfix_bits)); +} + +} // namespace brotli + +#endif // BROTLI_ENC_PREFIX_H_ diff --git a/web/server/h2o/libh2o/deps/brotli/enc/ringbuffer.h b/web/server/h2o/libh2o/deps/brotli/enc/ringbuffer.h new file mode 100644 index 00000000..d523792a --- /dev/null +++ b/web/server/h2o/libh2o/deps/brotli/enc/ringbuffer.h @@ -0,0 +1,114 @@ +/* Copyright 2013 Google Inc. All Rights Reserved. + + Distributed under MIT license. + See file LICENSE for detail or copy at https://opensource.org/licenses/MIT +*/ + +// Sliding window over the input data. + +#ifndef BROTLI_ENC_RINGBUFFER_H_ +#define BROTLI_ENC_RINGBUFFER_H_ + + +#include "./port.h" +#include "./types.h" + +namespace brotli { + +// A RingBuffer(window_bits, tail_bits) contains `1 << window_bits' bytes of +// data in a circular manner: writing a byte writes it to: +// `position() % (1 << window_bits)'. +// For convenience, the RingBuffer array contains another copy of the +// first `1 << tail_bits' bytes: +// buffer_[i] == buffer_[i + (1 << window_bits)], if i < (1 << tail_bits), +// and another copy of the last two bytes: +// buffer_[-1] == buffer_[(1 << window_bits) - 1] and +// buffer_[-2] == buffer_[(1 << window_bits) - 2]. +class RingBuffer { + public: + RingBuffer(int window_bits, int tail_bits) + : size_(1u << window_bits), + mask_((1u << window_bits) - 1), + tail_size_(1u << tail_bits), + pos_(0) { + static const size_t kSlackForEightByteHashingEverywhere = 7; + const size_t buflen = size_ + tail_size_; + data_ = new uint8_t[2 + buflen + kSlackForEightByteHashingEverywhere]; + buffer_ = data_ + 2; + for (size_t i = 0; i < kSlackForEightByteHashingEverywhere; ++i) { + buffer_[buflen + i] = 0; + } + // Initialize the last two bytes and their copy to zero. + buffer_[-2] = buffer_[size_ - 2] = 0; + buffer_[-1] = buffer_[size_ - 1] = 0; + } + ~RingBuffer() { + delete [] data_; + } + + // Push bytes into the ring buffer. + void Write(const uint8_t *bytes, size_t n) { + const size_t masked_pos = pos_ & mask_; + // The length of the writes is limited so that we do not need to worry + // about a write + WriteTail(bytes, n); + if (PREDICT_TRUE(masked_pos + n <= size_)) { + // A single write fits. + memcpy(&buffer_[masked_pos], bytes, n); + } else { + // Split into two writes. + // Copy into the end of the buffer, including the tail buffer. + memcpy(&buffer_[masked_pos], bytes, + std::min(n, (size_ + tail_size_) - masked_pos)); + // Copy into the beginning of the buffer + memcpy(&buffer_[0], bytes + (size_ - masked_pos), + n - (size_ - masked_pos)); + } + buffer_[-2] = buffer_[size_ - 2]; + buffer_[-1] = buffer_[size_ - 1]; + pos_ += static_cast(n); + if (pos_ > (1u << 30)) { /* Wrap, but preserve not-a-first-lap feature. */ + pos_ = (pos_ & ((1u << 30) - 1)) | (1u << 30); + } + } + + void Reset() { + pos_ = 0; + } + + // Logical cursor position in the ring buffer. + uint32_t position() const { return pos_; } + + // Bit mask for getting the physical position for a logical position. + uint32_t mask() const { return mask_; } + + uint8_t *start() { return &buffer_[0]; } + const uint8_t *start() const { return &buffer_[0]; } + + private: + void WriteTail(const uint8_t *bytes, size_t n) { + const size_t masked_pos = pos_ & mask_; + if (PREDICT_FALSE(masked_pos < tail_size_)) { + // Just fill the tail buffer with the beginning data. + const size_t p = size_ + masked_pos; + memcpy(&buffer_[p], bytes, std::min(n, tail_size_ - masked_pos)); + } + } + + // Size of the ringbuffer is (1 << window_bits) + tail_size_. + const uint32_t size_; + const uint32_t mask_; + const uint32_t tail_size_; + + // Position to write in the ring buffer. + uint32_t pos_; + // The actual ring buffer containing the copy of the last two bytes, the data, + // and the copy of the beginning as a tail. + uint8_t *data_; + // The start of the ringbuffer. + uint8_t *buffer_; +}; + +} // namespace brotli + +#endif // BROTLI_ENC_RINGBUFFER_H_ diff --git a/web/server/h2o/libh2o/deps/brotli/enc/static_dict.cc b/web/server/h2o/libh2o/deps/brotli/enc/static_dict.cc new file mode 100644 index 00000000..27177b1b --- /dev/null +++ b/web/server/h2o/libh2o/deps/brotli/enc/static_dict.cc @@ -0,0 +1,455 @@ +/* Copyright 2013 Google Inc. All Rights Reserved. + + Distributed under MIT license. + See file LICENSE for detail or copy at https://opensource.org/licenses/MIT +*/ + +#include "./static_dict.h" + +#include + +#include "./dictionary.h" +#include "./find_match_length.h" +#include "./static_dict_lut.h" +#include "./transform.h" + +namespace brotli { + +inline uint32_t Hash(const uint8_t *data) { + uint32_t h = BROTLI_UNALIGNED_LOAD32(data) * kDictHashMul32; + // The higher bits contain more mixture from the multiplication, + // so we take our results from there. + return h >> (32 - kDictNumBits); +} + +inline void AddMatch(size_t distance, size_t len, size_t len_code, + uint32_t* matches) { + uint32_t match = static_cast((distance << 5) + len_code); + matches[len] = std::min(matches[len], match); +} + +inline size_t DictMatchLength(const uint8_t* data, + size_t id, + size_t len, + size_t maxlen) { + const size_t offset = kBrotliDictionaryOffsetsByLength[len] + len * id; + return FindMatchLengthWithLimit(&kBrotliDictionary[offset], data, + std::min(len, maxlen)); +} + +inline bool IsMatch(DictWord w, const uint8_t* data, size_t max_length) { + if (w.len > max_length) return false; + const size_t offset = kBrotliDictionaryOffsetsByLength[w.len] + w.len * w.idx; + const uint8_t* dict = &kBrotliDictionary[offset]; + if (w.transform == 0) { + // Match against base dictionary word. + return FindMatchLengthWithLimit(dict, data, w.len) == w.len; + } else if (w.transform == 10) { + // Match against uppercase first transform. + // Note that there are only ASCII uppercase words in the lookup table. + return (dict[0] >= 'a' && dict[0] <= 'z' && + (dict[0] ^ 32) == data[0] && + FindMatchLengthWithLimit(&dict[1], &data[1], w.len - 1u) == + w.len - 1u); + } else { + // Match against uppercase all transform. + // Note that there are only ASCII uppercase words in the lookup table. + for (size_t i = 0; i < w.len; ++i) { + if (dict[i] >= 'a' && dict[i] <= 'z') { + if ((dict[i] ^ 32) != data[i]) return false; + } else { + if (dict[i] != data[i]) return false; + } + } + return true; + } +} + +bool FindAllStaticDictionaryMatches(const uint8_t* data, + size_t min_length, + size_t max_length, + uint32_t* matches) { + bool found_match = false; + size_t key = Hash(data); + size_t bucket = kStaticDictionaryBuckets[key]; + if (bucket != 0) { + size_t num = bucket & 0xff; + size_t offset = bucket >> 8; + for (size_t i = 0; i < num; ++i) { + const DictWord w = kStaticDictionaryWords[offset + i]; + const size_t l = w.len; + const size_t n = 1u << kBrotliDictionarySizeBitsByLength[l]; + const size_t id = w.idx; + if (w.transform == 0) { + const size_t matchlen = DictMatchLength(data, id, l, max_length); + // Transform "" + kIdentity + "" + if (matchlen == l) { + AddMatch(id, l, l, matches); + found_match = true; + } + // Transforms "" + kOmitLast1 + "" and "" + kOmitLast1 + "ing " + if (matchlen >= l - 1) { + AddMatch(id + 12 * n, l - 1, l, matches); + if (l + 2 < max_length && + data[l - 1] == 'i' && data[l] == 'n' && data[l + 1] == 'g' && + data[l + 2] == ' ') { + AddMatch(id + 49 * n, l + 3, l, matches); + } + found_match = true; + } + // Transform "" + kOmitLastN + "" (N = 2 .. 9) + size_t minlen = min_length; + if (l > 9) minlen = std::max(minlen, l - 9); + size_t maxlen = std::min(matchlen, l - 2); + for (size_t len = minlen; len <= maxlen; ++len) { + AddMatch(id + kOmitLastNTransforms[l - len] * n, len, l, matches); + found_match = true; + } + if (matchlen < l || l + 6 >= max_length) { + continue; + } + const uint8_t* s = &data[l]; + // Transforms "" + kIdentity + + if (s[0] == ' ') { + AddMatch(id + n, l + 1, l, matches); + if (s[1] == 'a') { + if (s[2] == ' ') { + AddMatch(id + 28 * n, l + 3, l, matches); + } else if (s[2] == 's') { + if (s[3] == ' ') AddMatch(id + 46 * n, l + 4, l, matches); + } else if (s[2] == 't') { + if (s[3] == ' ') AddMatch(id + 60 * n, l + 4, l, matches); + } else if (s[2] == 'n') { + if (s[3] == 'd' && s[4] == ' ') { + AddMatch(id + 10 * n, l + 5, l, matches); + } + } + } else if (s[1] == 'b') { + if (s[2] == 'y' && s[3] == ' ') { + AddMatch(id + 38 * n, l + 4, l, matches); + } + } else if (s[1] == 'i') { + if (s[2] == 'n') { + if (s[3] == ' ') AddMatch(id + 16 * n, l + 4, l, matches); + } else if (s[2] == 's') { + if (s[3] == ' ') AddMatch(id + 47 * n, l + 4, l, matches); + } + } else if (s[1] == 'f') { + if (s[2] == 'o') { + if (s[3] == 'r' && s[4] == ' ') { + AddMatch(id + 25 * n, l + 5, l, matches); + } + } else if (s[2] == 'r') { + if (s[3] == 'o' && s[4] == 'm' && s[5] == ' ') { + AddMatch(id + 37 * n, l + 6, l, matches); + } + } + } else if (s[1] == 'o') { + if (s[2] == 'f') { + if (s[3] == ' ') AddMatch(id + 8 * n, l + 4, l, matches); + } else if (s[2] == 'n') { + if (s[3] == ' ') AddMatch(id + 45 * n, l + 4, l, matches); + } + } else if (s[1] == 'n') { + if (s[2] == 'o' && s[3] == 't' && s[4] == ' ') { + AddMatch(id + 80 * n, l + 5, l, matches); + } + } else if (s[1] == 't') { + if (s[2] == 'h') { + if (s[3] == 'e') { + if (s[4] == ' ') AddMatch(id + 5 * n, l + 5, l, matches); + } else if (s[3] == 'a') { + if (s[4] == 't' && s[5] == ' ') { + AddMatch(id + 29 * n, l + 6, l, matches); + } + } + } else if (s[2] == 'o') { + if (s[3] == ' ') AddMatch(id + 17 * n, l + 4, l, matches); + } + } else if (s[1] == 'w') { + if (s[2] == 'i' && s[3] == 't' && s[4] == 'h' && s[5] == ' ') { + AddMatch(id + 35 * n, l + 6, l, matches); + } + } + } else if (s[0] == '"') { + AddMatch(id + 19 * n, l + 1, l, matches); + if (s[1] == '>') { + AddMatch(id + 21 * n, l + 2, l, matches); + } + } else if (s[0] == '.') { + AddMatch(id + 20 * n, l + 1, l, matches); + if (s[1] == ' ') { + AddMatch(id + 31 * n, l + 2, l, matches); + if (s[2] == 'T' && s[3] == 'h') { + if (s[4] == 'e') { + if (s[5] == ' ') AddMatch(id + 43 * n, l + 6, l, matches); + } else if (s[4] == 'i') { + if (s[5] == 's' && s[6] == ' ') { + AddMatch(id + 75 * n, l + 7, l, matches); + } + } + } + } + } else if (s[0] == ',') { + AddMatch(id + 76 * n, l + 1, l, matches); + if (s[1] == ' ') { + AddMatch(id + 14 * n, l + 2, l, matches); + } + } else if (s[0] == '\n') { + AddMatch(id + 22 * n, l + 1, l, matches); + if (s[1] == '\t') { + AddMatch(id + 50 * n, l + 2, l, matches); + } + } else if (s[0] == ']') { + AddMatch(id + 24 * n, l + 1, l, matches); + } else if (s[0] == '\'') { + AddMatch(id + 36 * n, l + 1, l, matches); + } else if (s[0] == ':') { + AddMatch(id + 51 * n, l + 1, l, matches); + } else if (s[0] == '(') { + AddMatch(id + 57 * n, l + 1, l, matches); + } else if (s[0] == '=') { + if (s[1] == '"') { + AddMatch(id + 70 * n, l + 2, l, matches); + } else if (s[1] == '\'') { + AddMatch(id + 86 * n, l + 2, l, matches); + } + } else if (s[0] == 'a') { + if (s[1] == 'l' && s[2] == ' ') { + AddMatch(id + 84 * n, l + 3, l, matches); + } + } else if (s[0] == 'e') { + if (s[1] == 'd') { + if (s[2] == ' ') AddMatch(id + 53 * n, l + 3, l, matches); + } else if (s[1] == 'r') { + if (s[2] == ' ') AddMatch(id + 82 * n, l + 3, l, matches); + } else if (s[1] == 's') { + if (s[2] == 't' && s[3] == ' ') { + AddMatch(id + 95 * n, l + 4, l, matches); + } + } + } else if (s[0] == 'f') { + if (s[1] == 'u' && s[2] == 'l' && s[3] == ' ') { + AddMatch(id + 90 * n, l + 4, l, matches); + } + } else if (s[0] == 'i') { + if (s[1] == 'v') { + if (s[2] == 'e' && s[3] == ' ') { + AddMatch(id + 92 * n, l + 4, l, matches); + } + } else if (s[1] == 'z') { + if (s[2] == 'e' && s[3] == ' ') { + AddMatch(id + 100 * n, l + 4, l, matches); + } + } + } else if (s[0] == 'l') { + if (s[1] == 'e') { + if (s[2] == 's' && s[3] == 's' && s[4] == ' ') { + AddMatch(id + 93 * n, l + 5, l, matches); + } + } else if (s[1] == 'y') { + if (s[2] == ' ') AddMatch(id + 61 * n, l + 3, l, matches); + } + } else if (s[0] == 'o') { + if (s[1] == 'u' && s[2] == 's' && s[3] == ' ') { + AddMatch(id + 106 * n, l + 4, l, matches); + } + } + } else { + // Set t=false for kUppercaseFirst and + // t=true otherwise (kUppercaseAll) transform. + const bool t = w.transform != kUppercaseFirst; + if (!IsMatch(w, data, max_length)) { + continue; + } + // Transform "" + kUppercase{First,All} + "" + AddMatch(id + (t ? 44 : 9) * n, l, l, matches); + found_match = true; + if (l + 1 >= max_length) { + continue; + } + // Transforms "" + kUppercase{First,All} + + const uint8_t* s = &data[l]; + if (s[0] == ' ') { + AddMatch(id + (t ? 68 : 4) * n, l + 1, l, matches); + } else if (s[0] == '"') { + AddMatch(id + (t ? 87 : 66) * n, l + 1, l, matches); + if (s[1] == '>') { + AddMatch(id + (t ? 97 : 69) * n, l + 2, l, matches); + } + } else if (s[0] == '.') { + AddMatch(id + (t ? 101 : 79) * n, l + 1, l, matches); + if (s[1] == ' ') { + AddMatch(id + (t ? 114 : 88) * n, l + 2, l, matches); + } + } else if (s[0] == ',') { + AddMatch(id + (t ? 112 : 99) * n, l + 1, l, matches); + if (s[1] == ' ') { + AddMatch(id + (t ? 107 : 58) * n, l + 2, l, matches); + } + } else if (s[0] == '\'') { + AddMatch(id + (t ? 94 : 74) * n, l + 1, l, matches); + } else if (s[0] == '(') { + AddMatch(id + (t ? 113 : 78) * n, l + 1, l, matches); + } else if (s[0] == '=') { + if (s[1] == '"') { + AddMatch(id + (t ? 105 : 104) * n, l + 2, l, matches); + } else if (s[1] == '\'') { + AddMatch(id + (t ? 116 : 108) * n, l + 2, l, matches); + } + } + } + } + } + // Transforms with prefixes " " and "." + if (max_length >= 5 && (data[0] == ' ' || data[0] == '.')) { + bool is_space = (data[0] == ' '); + key = Hash(&data[1]); + bucket = kStaticDictionaryBuckets[key]; + size_t num = bucket & 0xff; + size_t offset = bucket >> 8; + for (size_t i = 0; i < num; ++i) { + const DictWord w = kStaticDictionaryWords[offset + i]; + const size_t l = w.len; + const size_t n = 1u << kBrotliDictionarySizeBitsByLength[l]; + const size_t id = w.idx; + if (w.transform == 0) { + if (!IsMatch(w, &data[1], max_length - 1)) { + continue; + } + // Transforms " " + kIdentity + "" and "." + kIdentity + "" + AddMatch(id + (is_space ? 6 : 32) * n, l + 1, l, matches); + found_match = true; + if (l + 2 >= max_length) { + continue; + } + // Transforms " " + kIdentity + and "." + kIdentity + + const uint8_t* s = &data[l + 1]; + if (s[0] == ' ') { + AddMatch(id + (is_space ? 2 : 77) * n, l + 2, l, matches); + } else if (s[0] == '(') { + AddMatch(id + (is_space ? 89 : 67) * n, l + 2, l, matches); + } else if (is_space) { + if (s[0] == ',') { + AddMatch(id + 103 * n, l + 2, l, matches); + if (s[1] == ' ') { + AddMatch(id + 33 * n, l + 3, l, matches); + } + } else if (s[0] == '.') { + AddMatch(id + 71 * n, l + 2, l, matches); + if (s[1] == ' ') { + AddMatch(id + 52 * n, l + 3, l, matches); + } + } else if (s[0] == '=') { + if (s[1] == '"') { + AddMatch(id + 81 * n, l + 3, l, matches); + } else if (s[1] == '\'') { + AddMatch(id + 98 * n, l + 3, l, matches); + } + } + } + } else if (is_space) { + // Set t=false for kUppercaseFirst and + // t=true otherwise (kUppercaseAll) transform. + const bool t = w.transform != kUppercaseFirst; + if (!IsMatch(w, &data[1], max_length - 1)) { + continue; + } + // Transforms " " + kUppercase{First,All} + "" + AddMatch(id + (t ? 85 : 30) * n, l + 1, l, matches); + found_match = true; + if (l + 2 >= max_length) { + continue; + } + // Transforms " " + kUppercase{First,All} + + const uint8_t* s = &data[l + 1]; + if (s[0] == ' ') { + AddMatch(id + (t ? 83 : 15) * n, l + 2, l, matches); + } else if (s[0] == ',') { + if (!t) { + AddMatch(id + 109 * n, l + 2, l, matches); + } + if (s[1] == ' ') { + AddMatch(id + (t ? 111 : 65) * n, l + 3, l, matches); + } + } else if (s[0] == '.') { + AddMatch(id + (t ? 115 : 96) * n, l + 2, l, matches); + if (s[1] == ' ') { + AddMatch(id + (t ? 117 : 91) * n, l + 3, l, matches); + } + } else if (s[0] == '=') { + if (s[1] == '"') { + AddMatch(id + (t ? 110 : 118) * n, l + 3, l, matches); + } else if (s[1] == '\'') { + AddMatch(id + (t ? 119 : 120) * n, l + 3, l, matches); + } + } + } + } + } + if (max_length >= 6) { + // Transforms with prefixes "e ", "s ", ", " and "\xc2\xa0" + if ((data[1] == ' ' && + (data[0] == 'e' || data[0] == 's' || data[0] == ',')) || + (data[0] == 0xc2 && data[1] == 0xa0)) { + key = Hash(&data[2]); + bucket = kStaticDictionaryBuckets[key]; + size_t num = bucket & 0xff; + size_t offset = bucket >> 8; + for (size_t i = 0; i < num; ++i) { + const DictWord w = kStaticDictionaryWords[offset + i]; + const size_t l = w.len; + const size_t n = 1u << kBrotliDictionarySizeBitsByLength[l]; + const size_t id = w.idx; + if (w.transform == 0 && IsMatch(w, &data[2], max_length - 2)) { + if (data[0] == 0xc2) { + AddMatch(id + 102 * n, l + 2, l, matches); + found_match = true; + } else if (l + 2 < max_length && data[l + 2] == ' ') { + size_t t = data[0] == 'e' ? 18 : (data[0] == 's' ? 7 : 13); + AddMatch(id + t * n, l + 3, l, matches); + found_match = true; + } + } + } + } + } + if (max_length >= 9) { + // Transforms with prefixes " the " and ".com/" + if ((data[0] == ' ' && data[1] == 't' && data[2] == 'h' && + data[3] == 'e' && data[4] == ' ') || + (data[0] == '.' && data[1] == 'c' && data[2] == 'o' && + data[3] == 'm' && data[4] == '/')) { + key = Hash(&data[5]); + bucket = kStaticDictionaryBuckets[key]; + size_t num = bucket & 0xff; + size_t offset = bucket >> 8; + for (size_t i = 0; i < num; ++i) { + const DictWord w = kStaticDictionaryWords[offset + i]; + const size_t l = w.len; + const size_t n = 1u << kBrotliDictionarySizeBitsByLength[l]; + const size_t id = w.idx; + if (w.transform == 0 && IsMatch(w, &data[5], max_length - 5)) { + AddMatch(id + (data[0] == ' ' ? 41 : 72) * n, l + 5, l, matches); + found_match = true; + if (l + 5 < max_length) { + const uint8_t* s = &data[l + 5]; + if (data[0] == ' ') { + if (l + 8 < max_length && + s[0] == ' ' && s[1] == 'o' && s[2] == 'f' && s[3] == ' ') { + AddMatch(id + 62 * n, l + 9, l, matches); + if (l + 12 < max_length && + s[4] == 't' && s[5] == 'h' && s[6] == 'e' && s[7] == ' ') { + AddMatch(id + 73 * n, l + 13, l, matches); + } + } + } + } + } + } + } + } + return found_match; +} + +} // namespace brotli diff --git a/web/server/h2o/libh2o/deps/brotli/enc/static_dict.h b/web/server/h2o/libh2o/deps/brotli/enc/static_dict.h new file mode 100644 index 00000000..d293934d --- /dev/null +++ b/web/server/h2o/libh2o/deps/brotli/enc/static_dict.h @@ -0,0 +1,32 @@ +/* Copyright 2013 Google Inc. All Rights Reserved. + + Distributed under MIT license. + See file LICENSE for detail or copy at https://opensource.org/licenses/MIT +*/ + +// Class to model the static dictionary. + +#ifndef BROTLI_ENC_STATIC_DICT_H_ +#define BROTLI_ENC_STATIC_DICT_H_ + +#include "./types.h" + +namespace brotli { + +static const size_t kMaxDictionaryMatchLen = 37; +static const uint32_t kInvalidMatch = 0xfffffff; + +// Matches data against static dictionary words, and for each length l, +// for which a match is found, updates matches[l] to be the minimum possible +// (distance << 5) + len_code. +// Prerequisites: +// matches array is at least kMaxDictionaryMatchLen + 1 long +// all elements are initialized to kInvalidMatch +bool FindAllStaticDictionaryMatches(const uint8_t* data, + size_t min_length, + size_t max_length, + uint32_t* matches); + +} // namespace brotli + +#endif // BROTLI_ENC_STATIC_DICT_H_ diff --git a/web/server/h2o/libh2o/deps/brotli/enc/static_dict_lut.h b/web/server/h2o/libh2o/deps/brotli/enc/static_dict_lut.h new file mode 100644 index 00000000..489c03a1 --- /dev/null +++ b/web/server/h2o/libh2o/deps/brotli/enc/static_dict_lut.h @@ -0,0 +1,12055 @@ +/* Copyright 2015 Google Inc. All Rights Reserved. + + Distributed under MIT license. + See file LICENSE for detail or copy at https://opensource.org/licenses/MIT +*/ + +// Lookup table for static dictionary and transforms. + +#ifndef BROTLI_ENC_DICTIONARY_LUT_H_ +#define BROTLI_ENC_DICTIONARY_LUT_H_ + +#include "./types.h" + +namespace brotli { + +static const int kDictNumBits = 15 +;static const uint32_t kDictHashMul32 = 0x1e35a7bd; + +struct DictWord { + uint8_t len; + uint8_t transform; + uint16_t idx; +}; + +static const uint32_t kStaticDictionaryBuckets[] = { + 0x000002, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000203, 0x00050e, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x001301, 0x000000, 0x000000, 0x000000, 0x001401, 0x000000, 0x001501, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x001602, + 0x000000, 0x000000, 0x001804, 0x000000, 0x001c18, 0x000000, 0x003402, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x003606, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x003c0f, 0x004b12, 0x000000, 0x000000, + 0x000000, 0x005d02, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x005f01, 0x000000, 0x006001, 0x000000, 0x006101, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x006202, 0x006405, 0x006902, 0x006b02, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x006d01, 0x000000, 0x006e01, + 0x006f01, 0x000000, 0x007005, 0x007506, 0x007b01, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x007c03, 0x007f01, 0x000000, 0x000000, 0x000000, 0x000000, + 0x008002, 0x000000, 0x000000, 0x008201, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x008303, 0x000000, 0x000000, 0x008602, 0x000000, 0x000000, + 0x000000, 0x008801, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x008901, + 0x008a03, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x008d01, 0x008e01, 0x008f01, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x009001, 0x000000, 0x000000, 0x000000, 0x009103, 0x009402, 0x009601, 0x009701, + 0x000000, 0x000000, 0x009801, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x009901, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x009a05, 0x000000, 0x000000, 0x000000, 0x000000, 0x009f16, 0x00b501, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x00b605, 0x000000, + 0x000000, 0x000000, 0x00bb01, 0x00bc03, 0x000000, 0x000000, 0x00bf02, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x00c103, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x00c405, 0x00c907, + 0x00d001, 0x000000, 0x000000, 0x00d10e, 0x000000, 0x00df01, 0x000000, 0x000000, + 0x000000, 0x00e006, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x00e601, 0x000000, 0x000000, 0x000000, + 0x00e708, 0x000000, 0x00ef02, 0x000000, 0x000000, 0x00f102, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x00f302, 0x000000, 0x000000, 0x000000, 0x00f503, 0x000000, 0x000000, + 0x00f802, 0x00fa02, 0x00fc05, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x010103, 0x000000, 0x000000, 0x010402, 0x010604, 0x000000, 0x000000, 0x000000, + 0x010a01, 0x000000, 0x000000, 0x010b01, 0x000000, 0x010c02, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x010e01, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x010f01, 0x000000, + 0x011004, 0x000000, 0x011401, 0x000000, 0x011508, 0x011d01, 0x000000, 0x000000, + 0x000000, 0x000000, 0x011e02, 0x000000, 0x012001, 0x012101, 0x012204, 0x000000, + 0x000000, 0x000000, 0x012601, 0x000000, 0x000000, 0x012701, 0x012801, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x012901, 0x000000, 0x000000, 0x000000, 0x012a06, 0x000000, 0x000000, + 0x013013, 0x000000, 0x014303, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x014601, 0x000000, 0x014701, 0x014807, 0x000000, 0x000000, 0x000000, 0x000000, + 0x014f04, 0x000000, 0x000000, 0x015301, 0x000000, 0x015401, 0x015501, 0x015603, + 0x000000, 0x000000, 0x015902, 0x000000, 0x015b01, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x015c02, 0x015e04, 0x000000, 0x000000, 0x016208, + 0x000000, 0x016a01, 0x000000, 0x016b04, 0x000000, 0x016f01, 0x017001, 0x000000, + 0x017102, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x017301, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x017402, 0x000000, 0x017601, 0x000000, + 0x000000, 0x000000, 0x000000, 0x017701, 0x017811, 0x000000, 0x000000, 0x018901, + 0x018a01, 0x018b02, 0x000000, 0x000000, 0x018d02, 0x000000, 0x000000, 0x000000, + 0x000000, 0x018f08, 0x000000, 0x000000, 0x01970c, 0x000000, 0x000000, 0x000000, + 0x000000, 0x01a301, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x01a401, 0x000000, 0x000000, 0x01a501, 0x01a606, 0x000000, 0x000000, 0x01ac06, + 0x01b201, 0x01b306, 0x01b901, 0x000000, 0x000000, 0x01ba01, 0x000000, 0x01bb01, + 0x01bc08, 0x01c403, 0x01c701, 0x000000, 0x01c801, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x01c901, 0x000000, 0x000000, 0x000000, 0x01ca01, 0x000000, + 0x000000, 0x000000, 0x01cb02, 0x000000, 0x01cd01, 0x01ce02, 0x01d001, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x01d103, 0x01d401, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x01d504, 0x000000, 0x000000, + 0x000000, 0x01d902, 0x000000, 0x01db07, 0x000000, 0x000000, 0x000000, 0x000000, + 0x01e202, 0x000000, 0x01e401, 0x000000, 0x000000, 0x000000, 0x01e502, 0x000000, + 0x000000, 0x01e703, 0x01ea01, 0x01eb05, 0x000000, 0x000000, 0x01f002, 0x01f201, + 0x01f301, 0x000000, 0x01f404, 0x000000, 0x000000, 0x000000, 0x01f801, 0x000000, + 0x000000, 0x01f901, 0x000000, 0x000000, 0x000000, 0x01fa02, 0x000000, 0x000000, + 0x000000, 0x01fc02, 0x000000, 0x000000, 0x000000, 0x000000, 0x01fe01, 0x01ff07, + 0x02060a, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x021001, + 0x021104, 0x000000, 0x000000, 0x000000, 0x021509, 0x000000, 0x000000, 0x000000, + 0x000000, 0x021e0a, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x022804, 0x000000, 0x000000, 0x000000, 0x000000, + 0x022c03, 0x022f01, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x023003, 0x000000, 0x023301, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x023401, 0x023509, 0x000000, 0x023e2c, 0x000000, 0x026a01, 0x000000, + 0x026b03, 0x000000, 0x000000, 0x026e01, 0x026f01, 0x000000, 0x000000, 0x000000, + 0x027001, 0x000000, 0x000000, 0x027101, 0x027201, 0x000000, 0x000000, 0x027302, + 0x000000, 0x000000, 0x000000, 0x000000, 0x027501, 0x000000, 0x02760a, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x028002, 0x000000, 0x000000, 0x000000, 0x000000, 0x02820d, 0x028f0c, 0x029b05, + 0x000000, 0x000000, 0x000000, 0x02a001, 0x000000, 0x000000, 0x000000, 0x02a108, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x02a905, 0x000000, 0x02ae03, 0x000000, 0x02b103, 0x000000, 0x02b406, 0x02ba01, + 0x02bb04, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x02bf01, + 0x02c002, 0x000000, 0x000000, 0x000000, 0x000000, 0x02c203, 0x02c501, 0x000000, + 0x02c60f, 0x000000, 0x000000, 0x000000, 0x000000, 0x02d503, 0x000000, 0x000000, + 0x02d801, 0x000000, 0x000000, 0x000000, 0x02d901, 0x02da15, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x02ef0a, 0x000000, 0x000000, 0x000000, 0x02f901, + 0x000000, 0x02fa04, 0x000000, 0x000000, 0x02fe03, 0x000000, 0x000000, 0x000000, + 0x030104, 0x030501, 0x000000, 0x000000, 0x030601, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x030701, + 0x000000, 0x000000, 0x000000, 0x030806, 0x030e02, 0x000000, 0x000000, 0x000000, + 0x031003, 0x031302, 0x000000, 0x000000, 0x000000, 0x000000, 0x031503, 0x000000, + 0x000000, 0x000000, 0x031801, 0x000000, 0x000000, 0x000000, 0x000000, 0x03190a, + 0x000000, 0x000000, 0x03230f, 0x033202, 0x033406, 0x000000, 0x033a07, 0x000000, + 0x000000, 0x000000, 0x034101, 0x000000, 0x000000, 0x034206, 0x000000, 0x000000, + 0x000000, 0x034803, 0x000000, 0x034b06, 0x000000, 0x035101, 0x035208, 0x035a01, + 0x000000, 0x035b0e, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x036902, 0x000000, 0x036b01, 0x000000, 0x036c0d, 0x037903, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x037c01, + 0x037d04, 0x038101, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x038201, 0x000000, 0x000000, 0x000000, 0x038304, 0x038702, 0x038901, + 0x000000, 0x000000, 0x000000, 0x038a01, 0x000000, 0x038b01, 0x038c01, 0x000000, + 0x038d01, 0x000000, 0x000000, 0x000000, 0x000000, 0x038e05, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x039306, 0x000000, 0x000000, 0x000000, 0x039903, + 0x039c05, 0x000000, 0x03a104, 0x000000, 0x03a509, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x03ae01, 0x000000, 0x000000, 0x03af09, 0x000000, 0x03b801, + 0x03b901, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x03ba07, + 0x000000, 0x03c101, 0x03c20d, 0x000000, 0x000000, 0x03cf01, 0x000000, 0x000000, + 0x03d001, 0x03d101, 0x03d201, 0x03d301, 0x000000, 0x03d403, 0x000000, 0x000000, + 0x000000, 0x000000, 0x03d701, 0x000000, 0x000000, 0x03d802, 0x000000, 0x000000, + 0x03da02, 0x03dc02, 0x03de01, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x03df01, 0x000000, 0x000000, 0x000000, + 0x03e003, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x03e304, + 0x000000, 0x000000, 0x000000, 0x03e702, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x03e903, 0x000000, 0x000000, 0x000000, 0x000000, 0x03ec02, 0x03ee02, + 0x000000, 0x000000, 0x000000, 0x03f001, 0x000000, 0x000000, 0x000000, 0x03f101, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x03f201, 0x000000, + 0x03f302, 0x000000, 0x000000, 0x000000, 0x000000, 0x03f502, 0x03f704, 0x000000, + 0x000000, 0x000000, 0x03fb01, 0x000000, 0x03fc01, 0x000000, 0x000000, 0x000000, + 0x000000, 0x03fd02, 0x000000, 0x000000, 0x000000, 0x03ff01, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x040001, 0x000000, 0x000000, 0x040101, + 0x040204, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x040602, 0x000000, + 0x040801, 0x000000, 0x000000, 0x000000, 0x000000, 0x040903, 0x000000, 0x000000, + 0x000000, 0x040c03, 0x040f02, 0x000000, 0x000000, 0x000000, 0x041101, 0x04120a, + 0x000000, 0x000000, 0x041c01, 0x000000, 0x041d03, 0x000000, 0x000000, 0x042001, + 0x000000, 0x000000, 0x000000, 0x042102, 0x000000, 0x000000, 0x042301, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x042401, 0x000000, + 0x000000, 0x042501, 0x000000, 0x000000, 0x000000, 0x000000, 0x042601, 0x000000, + 0x000000, 0x000000, 0x000000, 0x042701, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x042801, 0x000000, 0x000000, 0x000000, 0x000000, 0x042901, 0x042a02, + 0x000000, 0x000000, 0x000000, 0x042c01, 0x042d02, 0x042f01, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x043002, 0x000000, 0x043205, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x043704, 0x043b04, 0x000000, + 0x000000, 0x000000, 0x000000, 0x043f06, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x044501, 0x000000, 0x04460c, 0x000000, 0x045205, 0x000000, + 0x000000, 0x000000, 0x045702, 0x045905, 0x000000, 0x045e03, 0x000000, 0x046104, + 0x000000, 0x000000, 0x046503, 0x000000, 0x046801, 0x000000, 0x046902, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x046b0c, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x047701, 0x000000, 0x000000, 0x047801, 0x047902, + 0x000000, 0x047b01, 0x047c01, 0x000000, 0x000000, 0x047d01, 0x047e01, 0x000000, + 0x000000, 0x000000, 0x000000, 0x047f01, 0x000000, 0x048001, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x048109, 0x000000, 0x048a01, 0x000000, 0x000000, + 0x000000, 0x048b01, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x048c02, + 0x000000, 0x048e03, 0x000000, 0x049101, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x049201, 0x049301, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x049402, 0x049602, 0x049809, 0x000000, 0x04a109, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x04aa1a, 0x000000, 0x000000, 0x04c403, 0x000000, 0x000000, + 0x04c703, 0x000000, 0x000000, 0x04ca01, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x04cb01, 0x04cc01, 0x000000, 0x000000, 0x04cd01, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x04ce02, + 0x000000, 0x000000, 0x000000, 0x04d00a, 0x000000, 0x000000, 0x04da01, 0x04db02, + 0x04dd02, 0x04df06, 0x000000, 0x000000, 0x000000, 0x000000, 0x04e501, 0x04e603, + 0x04e901, 0x04ea01, 0x000000, 0x000000, 0x000000, 0x04eb01, 0x000000, 0x000000, + 0x04ec01, 0x000000, 0x000000, 0x000000, 0x04ed02, 0x04ef01, 0x000000, 0x000000, + 0x04f001, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x04f101, 0x000000, 0x04f206, + 0x000000, 0x000000, 0x000000, 0x000000, 0x04f801, 0x04f902, 0x04fb0d, 0x050802, + 0x000000, 0x000000, 0x050a01, 0x050b01, 0x050c01, 0x000000, 0x000000, 0x050d01, + 0x050e01, 0x050f06, 0x000000, 0x000000, 0x000000, 0x000000, 0x051502, 0x000000, + 0x051707, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x051e01, 0x051f02, 0x000000, 0x052102, 0x000000, 0x052304, + 0x052701, 0x052801, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x052901, 0x052a01, 0x052b0b, 0x000000, 0x053601, 0x000000, 0x053705, + 0x000000, 0x000000, 0x000000, 0x000000, 0x053c01, 0x053d04, 0x000000, 0x05410b, + 0x000000, 0x054c01, 0x000000, 0x000000, 0x000000, 0x054d02, 0x054f01, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x055001, 0x000000, 0x000000, + 0x000000, 0x055103, 0x055401, 0x000000, 0x05550d, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x056207, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x056902, 0x000000, 0x056b07, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x057208, 0x000000, 0x000000, 0x000000, 0x000000, 0x057a02, + 0x000000, 0x057c02, 0x000000, 0x000000, 0x057e01, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x057f01, 0x058001, 0x000000, 0x058102, 0x000000, 0x000000, + 0x000000, 0x058301, 0x058403, 0x05870d, 0x000000, 0x000000, 0x059416, 0x05aa03, + 0x000000, 0x000000, 0x05ad01, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x05ae01, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x05af03, 0x000000, 0x000000, 0x000000, 0x000000, 0x05b201, + 0x05b301, 0x05b40e, 0x05c202, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x05c403, 0x000000, 0x05c701, 0x000000, 0x05c805, 0x000000, 0x000000, + 0x05cd09, 0x000000, 0x000000, 0x05d601, 0x000000, 0x000000, 0x000000, 0x05d702, + 0x000000, 0x000000, 0x05d901, 0x05da02, 0x05dc13, 0x05ef01, 0x05f005, 0x000000, + 0x000000, 0x000000, 0x05f502, 0x000000, 0x000000, 0x000000, 0x000000, 0x05f701, + 0x05f804, 0x000000, 0x05fc03, 0x05ff01, 0x000000, 0x000000, 0x000000, 0x060001, + 0x06010b, 0x060c01, 0x000000, 0x060d08, 0x061501, 0x06160d, 0x062301, 0x000000, + 0x062402, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x062604, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x062a14, 0x000000, 0x063e04, 0x000000, 0x064201, 0x000000, 0x064301, 0x000000, + 0x064403, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x064702, 0x064901, + 0x000000, 0x000000, 0x000000, 0x000000, 0x064a04, 0x000000, 0x064e01, 0x000000, + 0x064f02, 0x065101, 0x000000, 0x065203, 0x000000, 0x000000, 0x06550c, 0x000000, + 0x000000, 0x000000, 0x000000, 0x066101, 0x000000, 0x000000, 0x000000, 0x066206, + 0x000000, 0x000000, 0x000000, 0x066802, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x066a07, 0x000000, 0x000000, + 0x000000, 0x067102, 0x000000, 0x000000, 0x067301, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x067401, 0x000000, 0x000000, 0x000000, 0x067501, 0x000000, + 0x000000, 0x000000, 0x000000, 0x067607, 0x000000, 0x067d01, 0x000000, 0x000000, + 0x067e01, 0x067f04, 0x000000, 0x000000, 0x068301, 0x000000, 0x000000, 0x068401, + 0x068502, 0x000000, 0x068701, 0x068801, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x068901, 0x000000, 0x000000, 0x000000, 0x068a01, 0x068b04, 0x068f02, + 0x000000, 0x069105, 0x000000, 0x000000, 0x069611, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x06a701, 0x000000, 0x000000, 0x06a810, 0x000000, 0x000000, + 0x06b80d, 0x000000, 0x000000, 0x000000, 0x000000, 0x06c501, 0x06c602, 0x000000, + 0x000000, 0x000000, 0x000000, 0x06c802, 0x000000, 0x000000, 0x000000, 0x000000, + 0x06ca01, 0x000000, 0x000000, 0x06cb01, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x06cc02, 0x06ce02, + 0x000000, 0x000000, 0x000000, 0x000000, 0x06d004, 0x000000, 0x000000, 0x000000, + 0x06d402, 0x000000, 0x000000, 0x000000, 0x06d609, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x06df05, 0x000000, 0x000000, 0x000000, 0x000000, + 0x06e413, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x06f701, 0x000000, + 0x06f802, 0x06fa01, 0x000000, 0x000000, 0x000000, 0x000000, 0x06fb01, 0x06fc01, + 0x000000, 0x000000, 0x000000, 0x000000, 0x06fd01, 0x06fe02, 0x070005, 0x000000, + 0x070501, 0x070602, 0x000000, 0x000000, 0x000000, 0x000000, 0x070802, 0x000000, + 0x070a02, 0x070c01, 0x000000, 0x000000, 0x000000, 0x070d05, 0x071201, 0x000000, + 0x071302, 0x071507, 0x000000, 0x071c01, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x071d0b, 0x07280f, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x073709, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x074002, 0x000000, 0x000000, 0x000000, 0x074202, 0x000000, 0x000000, 0x000000, + 0x000000, 0x074405, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x074937, 0x000000, 0x078004, 0x078404, 0x000000, 0x000000, 0x000000, + 0x078801, 0x078901, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x078a01, 0x000000, 0x000000, 0x000000, 0x000000, + 0x078b02, 0x000000, 0x000000, 0x000000, 0x078d0c, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x079902, 0x000000, 0x000000, + 0x079b02, 0x000000, 0x000000, 0x000000, 0x000000, 0x079d07, 0x000000, 0x07a401, + 0x000000, 0x07a507, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x07ac02, + 0x07ae01, 0x000000, 0x000000, 0x000000, 0x000000, 0x07af01, 0x000000, 0x07b002, + 0x000000, 0x07b201, 0x07b301, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x07b402, 0x000000, 0x000000, 0x000000, 0x000000, 0x07b601, + 0x000000, 0x000000, 0x000000, 0x000000, 0x07b703, 0x07ba03, 0x000000, 0x07bd02, + 0x000000, 0x000000, 0x000000, 0x000000, 0x07bf04, 0x07c302, 0x000000, 0x000000, + 0x000000, 0x000000, 0x07c50e, 0x07d304, 0x07d704, 0x000000, 0x000000, 0x000000, + 0x07db01, 0x07dc02, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x07de01, 0x000000, 0x07df01, 0x07e004, + 0x000000, 0x000000, 0x000000, 0x000000, 0x07e404, 0x000000, 0x000000, 0x07e804, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x07ec07, 0x07f304, 0x07f702, + 0x000000, 0x07f901, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x07fa02, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x07fc01, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x07fd01, 0x07fe01, + 0x000000, 0x07ff01, 0x08000a, 0x000000, 0x080a04, 0x000000, 0x000000, 0x080e01, + 0x000000, 0x080f01, 0x081001, 0x000000, 0x000000, 0x081103, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x081401, 0x000000, 0x000000, 0x000000, + 0x000000, 0x081501, 0x000000, 0x081601, 0x000000, 0x081708, 0x000000, 0x000000, + 0x000000, 0x000000, 0x081f02, 0x082101, 0x082202, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x082401, 0x000000, 0x082502, 0x082701, 0x082810, 0x083802, + 0x000000, 0x000000, 0x000000, 0x000000, 0x083a09, 0x000000, 0x000000, 0x084301, + 0x084403, 0x000000, 0x084702, 0x000000, 0x000000, 0x084901, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x084a02, 0x000000, 0x000000, 0x084c02, 0x084e01, + 0x084f02, 0x000000, 0x000000, 0x000000, 0x085107, 0x000000, 0x000000, 0x000000, + 0x085802, 0x085a01, 0x085b01, 0x085c03, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x085f01, 0x086001, 0x000000, + 0x000000, 0x086103, 0x086401, 0x000000, 0x000000, 0x000000, 0x000000, 0x086501, + 0x000000, 0x000000, 0x086607, 0x086d01, 0x000000, 0x086e01, 0x000000, 0x086f01, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x087001, 0x087120, + 0x000000, 0x000000, 0x089108, 0x089903, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x089c0c, 0x08a803, 0x000000, 0x08ab01, 0x000000, 0x08ac01, + 0x000000, 0x08ad02, 0x08af0d, 0x000000, 0x000000, 0x000000, 0x000000, 0x08bc01, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x08bd01, 0x000000, 0x08be02, + 0x08c001, 0x000000, 0x000000, 0x08c101, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x08c209, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x08cb01, 0x000000, 0x000000, 0x08cc04, 0x000000, 0x000000, 0x000000, 0x08d001, + 0x08d102, 0x000000, 0x000000, 0x000000, 0x08d302, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x08d502, 0x000000, 0x08d705, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x08dc01, 0x08dd01, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x08de02, + 0x000000, 0x08e004, 0x000000, 0x000000, 0x000000, 0x000000, 0x08e401, 0x000000, + 0x000000, 0x000000, 0x000000, 0x08e501, 0x000000, 0x000000, 0x000000, 0x000000, + 0x08e601, 0x000000, 0x08e703, 0x000000, 0x08ea04, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x08ee02, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x08f001, + 0x08f101, 0x000000, 0x000000, 0x000000, 0x000000, 0x08f201, 0x000000, 0x08f301, + 0x000000, 0x000000, 0x000000, 0x08f402, 0x08f601, 0x08f702, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x08f905, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x08fe02, 0x000000, 0x090001, 0x000000, 0x000000, + 0x090101, 0x000000, 0x090206, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x090801, + 0x090901, 0x090a01, 0x090b02, 0x000000, 0x000000, 0x090d01, 0x000000, 0x090e03, + 0x000000, 0x091101, 0x000000, 0x000000, 0x091201, 0x000000, 0x091302, 0x000000, + 0x091509, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x091e01, 0x000000, 0x091f02, 0x092101, 0x092201, 0x000000, 0x09230f, 0x000000, + 0x000000, 0x000000, 0x093214, 0x000000, 0x094607, 0x000000, 0x094d04, 0x095101, + 0x000000, 0x095207, 0x000000, 0x000000, 0x095901, 0x000000, 0x000000, 0x000000, + 0x000000, 0x095a02, 0x000000, 0x095c01, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x095d01, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x095e03, 0x096102, 0x096304, 0x096703, 0x096a02, 0x000000, 0x000000, + 0x000000, 0x096c02, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x096e01, 0x000000, 0x000000, 0x096f01, 0x097002, 0x097201, 0x000000, 0x097305, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x097801, 0x000000, 0x000000, + 0x000000, 0x097901, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x097a01, 0x097b01, + 0x000000, 0x097c01, 0x000000, 0x000000, 0x097d04, 0x098102, 0x000000, 0x098305, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x098801, 0x098903, + 0x000000, 0x098c01, 0x000000, 0x000000, 0x098d0b, 0x099802, 0x000000, 0x099a03, + 0x000000, 0x000000, 0x099d02, 0x000000, 0x099f0d, 0x000000, 0x09ac01, 0x000000, + 0x09ad08, 0x09b505, 0x000000, 0x000000, 0x000000, 0x09ba02, 0x000000, 0x000000, + 0x09bc01, 0x000000, 0x000000, 0x09bd01, 0x000000, 0x09be12, 0x000000, 0x09d00a, + 0x09da01, 0x000000, 0x000000, 0x000000, 0x000000, 0x09db04, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x09df01, 0x09e001, 0x09e101, 0x000000, + 0x000000, 0x09e202, 0x000000, 0x09e401, 0x000000, 0x000000, 0x09e501, 0x09e601, + 0x000000, 0x09e701, 0x09e801, 0x000000, 0x09e901, 0x000000, 0x09ea01, 0x09eb05, + 0x000000, 0x000000, 0x000000, 0x09f001, 0x09f102, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x09f301, 0x000000, 0x000000, 0x09f401, + 0x000000, 0x09f505, 0x09fa02, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x09fc03, 0x000000, 0x09ff01, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x0a000f, 0x000000, + 0x0a0f01, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x0a1001, 0x0a1101, 0x000000, 0x000000, 0x000000, 0x0a1201, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x0a1301, + 0x000000, 0x000000, 0x000000, 0x000000, 0x0a1402, 0x000000, 0x000000, 0x000000, + 0x000000, 0x0a1601, 0x000000, 0x0a1704, 0x000000, 0x0a1b02, 0x0a1d01, 0x000000, + 0x000000, 0x000000, 0x0a1e02, 0x000000, 0x000000, 0x000000, 0x000000, 0x0a2001, + 0x0a2101, 0x000000, 0x0a2206, 0x000000, 0x0a2801, 0x0a2901, 0x000000, 0x000000, + 0x0a2a02, 0x000000, 0x0a2c01, 0x000000, 0x000000, 0x000000, 0x0a2d01, 0x0a2e04, + 0x0a3204, 0x000000, 0x0a3602, 0x000000, 0x000000, 0x000000, 0x0a3802, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x0a3a01, 0x000000, 0x000000, 0x0a3b01, + 0x000000, 0x000000, 0x000000, 0x0a3c02, 0x000000, 0x0a3e02, 0x000000, 0x0a4003, + 0x000000, 0x000000, 0x0a4301, 0x0a4406, 0x000000, 0x000000, 0x0a4a01, 0x0a4b01, + 0x0a4c02, 0x000000, 0x000000, 0x0a4e03, 0x000000, 0x000000, 0x000000, 0x0a5101, + 0x000000, 0x000000, 0x000000, 0x000000, 0x0a5201, 0x000000, 0x0a5305, 0x000000, + 0x0a5806, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x0a5e01, + 0x0a5f01, 0x000000, 0x000000, 0x0a6001, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x0a6101, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x0a6205, + 0x000000, 0x000000, 0x000000, 0x000000, 0x0a6715, 0x0a7c02, 0x000000, 0x0a7e01, + 0x000000, 0x0a7f01, 0x000000, 0x000000, 0x0a8005, 0x000000, 0x000000, 0x0a8501, + 0x000000, 0x0a8603, 0x000000, 0x000000, 0x0a8903, 0x000000, 0x0a8c05, 0x0a9101, + 0x000000, 0x000000, 0x000000, 0x0a9202, 0x000000, 0x0a9401, 0x0a9501, 0x0a9609, + 0x000000, 0x000000, 0x000000, 0x0a9f0a, 0x0aa905, 0x0aae03, 0x000000, 0x000000, + 0x000000, 0x000000, 0x0ab102, 0x0ab307, 0x000000, 0x000000, 0x000000, 0x000000, + 0x0aba01, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x0abb01, + 0x000000, 0x000000, 0x0abc01, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x0abd02, 0x000000, 0x000000, 0x0abf02, 0x0ac104, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x0ac504, 0x000000, 0x000000, 0x000000, 0x000000, 0x0ac901, + 0x000000, 0x000000, 0x000000, 0x000000, 0x0aca01, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x0acb03, 0x0ace01, 0x000000, 0x000000, + 0x000000, 0x000000, 0x0acf02, 0x000000, 0x000000, 0x0ad101, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x0ad201, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x0ad301, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x0ad403, 0x0ad707, 0x000000, + 0x000000, 0x0ade01, 0x000000, 0x000000, 0x0adf05, 0x000000, 0x0ae401, 0x000000, + 0x0ae502, 0x000000, 0x000000, 0x000000, 0x0ae701, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x0ae802, + 0x0aea01, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x0aeb01, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x0aec02, 0x0aee04, + 0x000000, 0x000000, 0x000000, 0x000000, 0x0af203, 0x000000, 0x000000, 0x000000, + 0x000000, 0x0af501, 0x000000, 0x0af601, 0x0af709, 0x0b0002, 0x0b0202, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x0b0401, 0x000000, 0x000000, 0x000000, + 0x000000, 0x0b0501, 0x0b0601, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x0b0704, 0x000000, 0x000000, 0x0b0b06, 0x000000, 0x0b1102, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x0b1302, 0x000000, + 0x0b1501, 0x000000, 0x000000, 0x0b1602, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x0b1801, 0x000000, 0x000000, + 0x000000, 0x0b1901, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x0b1a01, + 0x0b1b02, 0x000000, 0x000000, 0x000000, 0x000000, 0x0b1d01, 0x000000, 0x000000, + 0x0b1e02, 0x000000, 0x0b2004, 0x000000, 0x0b2404, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x0b2801, 0x000000, 0x000000, 0x000000, 0x000000, 0x0b2901, + 0x000000, 0x0b2a01, 0x000000, 0x000000, 0x0b2b02, 0x000000, 0x0b2d06, 0x0b3307, + 0x000000, 0x000000, 0x000000, 0x000000, 0x0b3a01, 0x000000, 0x0b3b01, 0x000000, + 0x000000, 0x0b3c01, 0x0b3d06, 0x0b4305, 0x0b4801, 0x0b4901, 0x000000, 0x000000, + 0x0b4a01, 0x000000, 0x000000, 0x0b4b0e, 0x000000, 0x000000, 0x000000, 0x0b5906, + 0x0b5f01, 0x000000, 0x0b6003, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x0b6312, 0x000000, 0x0b7501, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x0b7604, 0x000000, 0x000000, 0x000000, 0x000000, + 0x0b7a01, 0x000000, 0x0b7b01, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x0b7c05, 0x000000, 0x000000, 0x000000, 0x0b8103, 0x000000, + 0x0b8401, 0x000000, 0x000000, 0x0b8504, 0x0b8901, 0x0b8a04, 0x000000, 0x000000, + 0x000000, 0x0b8e02, 0x0b9001, 0x000000, 0x000000, 0x0b9101, 0x000000, 0x0b9201, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x0b9301, 0x0b9401, + 0x0b9501, 0x0b9602, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x0b9801, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x0b9905, + 0x0b9e07, 0x000000, 0x0ba501, 0x0ba601, 0x0ba705, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x0bac01, 0x000000, 0x000000, 0x0bad01, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x0bae07, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x0bb502, 0x000000, + 0x0bb701, 0x0bb801, 0x000000, 0x000000, 0x0bb901, 0x000000, 0x000000, 0x000000, + 0x0bba09, 0x000000, 0x000000, 0x0bc30a, 0x000000, 0x000000, 0x0bcd02, 0x000000, + 0x000000, 0x0bcf01, 0x000000, 0x000000, 0x0bd002, 0x0bd203, 0x000000, 0x000000, + 0x000000, 0x0bd504, 0x000000, 0x000000, 0x000000, 0x000000, 0x0bd901, 0x0bda01, + 0x000000, 0x000000, 0x0bdb03, 0x000000, 0x0bde0a, 0x000000, 0x0be801, 0x000000, + 0x000000, 0x0be901, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x0bea02, 0x000000, 0x0bec04, 0x000000, 0x000000, 0x000000, 0x000000, 0x0bf001, + 0x000000, 0x0bf105, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x0bf60a, 0x000000, 0x000000, 0x0c0001, 0x0c0104, 0x0c0501, + 0x0c0601, 0x000000, 0x0c0706, 0x0c0d01, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x0c0e05, 0x000000, 0x0c1303, 0x000000, + 0x0c1604, 0x000000, 0x0c1a01, 0x000000, 0x000000, 0x000000, 0x0c1b01, 0x000000, + 0x0c1c01, 0x0c1d14, 0x000000, 0x0c3102, 0x000000, 0x000000, 0x000000, 0x0c3301, + 0x000000, 0x0c3407, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x0c3b02, 0x0c3d02, 0x000000, 0x000000, 0x0c3f0b, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x0c4a02, 0x000000, 0x000000, 0x0c4c01, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x0c4d01, 0x0c4e01, 0x0c4f06, + 0x000000, 0x000000, 0x000000, 0x000000, 0x0c5502, 0x000000, 0x000000, 0x0c5701, + 0x000000, 0x000000, 0x0c5801, 0x000000, 0x000000, 0x0c5901, 0x000000, 0x0c5a03, + 0x0c5d02, 0x0c5f01, 0x000000, 0x000000, 0x0c6001, 0x0c6101, 0x000000, 0x000000, + 0x0c620b, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x0c6d02, 0x000000, 0x0c6f04, 0x000000, 0x000000, 0x0c7306, 0x000000, 0x000000, + 0x0c790a, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x0c8305, + 0x000000, 0x000000, 0x000000, 0x000000, 0x0c8807, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x0c8f01, 0x0c9002, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x0c9201, 0x000000, 0x000000, 0x0c9302, 0x0c9501, 0x000000, 0x0c9601, + 0x000000, 0x000000, 0x000000, 0x000000, 0x0c9701, 0x000000, 0x0c9801, 0x0c9902, + 0x000000, 0x0c9b05, 0x0ca006, 0x000000, 0x0ca602, 0x0ca801, 0x0ca909, 0x000000, + 0x000000, 0x0cb201, 0x0cb301, 0x0cb402, 0x0cb605, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x0cbb01, 0x000000, 0x000000, + 0x0cbc06, 0x000000, 0x000000, 0x000000, 0x0cc204, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x0cc607, 0x000000, 0x000000, + 0x000000, 0x0ccd04, 0x000000, 0x0cd102, 0x000000, 0x000000, 0x000000, 0x0cd301, + 0x000000, 0x000000, 0x000000, 0x0cd401, 0x0cd501, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x0cd605, 0x0cdb02, 0x000000, 0x000000, + 0x000000, 0x000000, 0x0cdd02, 0x0cdf03, 0x000000, 0x000000, 0x0ce201, 0x0ce301, + 0x0ce401, 0x000000, 0x0ce502, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x0ce702, 0x0ce902, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x0ceb03, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x0cee01, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x0cef02, 0x0cf101, 0x0cf203, 0x000000, 0x0cf501, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x0cf602, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x0cf801, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x0cf902, 0x000000, 0x000000, 0x0cfb01, 0x0cfc01, 0x000000, 0x000000, 0x0cfd02, + 0x000000, 0x000000, 0x0cff01, 0x0d0002, 0x0d0204, 0x000000, 0x000000, 0x0d0602, + 0x000000, 0x000000, 0x0d0801, 0x000000, 0x0d0905, 0x000000, 0x000000, 0x000000, + 0x000000, 0x0d0e04, 0x0d1201, 0x000000, 0x000000, 0x000000, 0x0d1303, 0x000000, + 0x000000, 0x0d1603, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x0d1901, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x0d1a0a, 0x000000, 0x000000, 0x0d2401, 0x0d2501, + 0x0d2601, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x0d2701, + 0x0d2801, 0x000000, 0x0d2903, 0x000000, 0x000000, 0x0d2c03, 0x000000, 0x000000, + 0x0d2f01, 0x000000, 0x000000, 0x0d3002, 0x000000, 0x0d3208, 0x0d3a03, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x0d3d0c, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x0d4901, 0x000000, 0x0d4a21, 0x0d6b01, + 0x0d6c02, 0x0d6e02, 0x000000, 0x000000, 0x0d7001, 0x000000, 0x000000, 0x000000, + 0x0d7107, 0x000000, 0x000000, 0x0d7801, 0x000000, 0x000000, 0x000000, 0x0d7901, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x0d7a01, + 0x000000, 0x000000, 0x0d7b01, 0x000000, 0x0d7c03, 0x0d7f01, 0x000000, 0x0d8001, + 0x000000, 0x000000, 0x0d8101, 0x000000, 0x0d8201, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x0d8309, 0x000000, + 0x000000, 0x0d8c01, 0x0d8d05, 0x000000, 0x000000, 0x0d9205, 0x000000, 0x000000, + 0x000000, 0x0d9707, 0x0d9e02, 0x0da001, 0x000000, 0x0da101, 0x000000, 0x000000, + 0x0da208, 0x0daa01, 0x000000, 0x0dab01, 0x000000, 0x000000, 0x0dac01, 0x000000, + 0x000000, 0x000000, 0x0dad0c, 0x000000, 0x0db902, 0x000000, 0x000000, 0x000000, + 0x0dbb01, 0x0dbc01, 0x000000, 0x000000, 0x000000, 0x0dbd02, 0x000000, 0x000000, + 0x000000, 0x000000, 0x0dbf01, 0x0dc001, 0x0dc104, 0x000000, 0x000000, 0x0dc504, + 0x0dc901, 0x000000, 0x000000, 0x000000, 0x000000, 0x0dca05, 0x000000, 0x000000, + 0x000000, 0x000000, 0x0dcf03, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x0dd202, 0x0dd401, 0x000000, 0x000000, 0x0dd502, 0x0dd703, + 0x000000, 0x0dda01, 0x0ddb02, 0x000000, 0x000000, 0x0ddd03, 0x000000, 0x0de001, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x0de101, + 0x000000, 0x0de203, 0x000000, 0x0de501, 0x000000, 0x0de604, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x0dea12, 0x000000, + 0x0dfc12, 0x000000, 0x000000, 0x000000, 0x0e0e01, 0x000000, 0x000000, 0x000000, + 0x0e0f01, 0x000000, 0x0e1001, 0x000000, 0x0e1101, 0x0e1203, 0x000000, 0x000000, + 0x0e1502, 0x0e1702, 0x000000, 0x0e1901, 0x0e1a01, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x0e1b04, 0x0e1f03, + 0x0e2205, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x0e2704, 0x0e2b01, + 0x000000, 0x0e2c05, 0x0e3101, 0x0e3201, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x0e3301, 0x000000, 0x0e3401, 0x000000, 0x000000, 0x0e350d, + 0x0e4201, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x0e4301, + 0x0e4403, 0x000000, 0x000000, 0x000000, 0x000000, 0x0e4701, 0x0e4801, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x0e4901, 0x000000, 0x000000, 0x000000, + 0x000000, 0x0e4a02, 0x000000, 0x0e4c02, 0x0e4e01, 0x0e4f01, 0x000000, 0x0e501b, + 0x000000, 0x0e6b02, 0x000000, 0x000000, 0x000000, 0x0e6d02, 0x0e6f02, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x0e7102, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x0e7301, 0x000000, 0x000000, 0x0e7407, 0x000000, + 0x000000, 0x000000, 0x0e7b01, 0x0e7c02, 0x000000, 0x000000, 0x000000, 0x0e7e01, + 0x0e7f0b, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x0e8a01, 0x000000, + 0x0e8b01, 0x0e8c01, 0x000000, 0x000000, 0x0e8d02, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x0e8f01, 0x0e9005, 0x000000, 0x0e9501, 0x0e9602, + 0x0e9806, 0x000000, 0x000000, 0x000000, 0x0e9e02, 0x000000, 0x0ea001, 0x000000, + 0x000000, 0x0ea101, 0x000000, 0x000000, 0x0ea201, 0x0ea309, 0x000000, 0x0eac02, + 0x000000, 0x0eae07, 0x0eb501, 0x0eb601, 0x000000, 0x0eb701, 0x000000, 0x000000, + 0x000000, 0x000000, 0x0eb802, 0x000000, 0x000000, 0x0eba03, 0x000000, 0x0ebd01, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x0ebe01, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x0ebf01, 0x000000, 0x0ec009, + 0x0ec902, 0x000000, 0x0ecb01, 0x0ecc02, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x0ece14, 0x000000, 0x0ee203, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x0ee501, 0x0ee601, 0x0ee704, + 0x0eeb01, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x0eec04, 0x000000, 0x000000, 0x0ef00a, 0x000000, 0x000000, 0x000000, 0x000000, + 0x0efa0d, 0x000000, 0x000000, 0x0f0701, 0x0f0801, 0x000000, 0x000000, 0x000000, + 0x000000, 0x0f0901, 0x0f0a02, 0x0f0c06, 0x000000, 0x000000, 0x000000, 0x000000, + 0x0f1201, 0x000000, 0x0f1302, 0x0f1501, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x0f160a, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x0f2001, 0x000000, 0x0f2101, 0x000000, 0x0f220b, 0x0f2d01, + 0x000000, 0x0f2e05, 0x000000, 0x000000, 0x000000, 0x000000, 0x0f3315, 0x0f4801, + 0x000000, 0x0f490b, 0x000000, 0x000000, 0x000000, 0x0f5406, 0x0f5a03, 0x000000, + 0x000000, 0x000000, 0x000000, 0x0f5d07, 0x0f6401, 0x0f6501, 0x000000, 0x000000, + 0x000000, 0x000000, 0x0f6601, 0x000000, 0x000000, 0x000000, 0x0f6701, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x0f6802, 0x000000, 0x0f6a09, 0x000000, + 0x000000, 0x000000, 0x0f7301, 0x0f7401, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x0f7501, 0x000000, 0x0f7606, + 0x0f7c01, 0x000000, 0x000000, 0x000000, 0x000000, 0x0f7d01, 0x000000, 0x000000, + 0x000000, 0x0f7e01, 0x000000, 0x000000, 0x000000, 0x0f7f06, 0x0f8501, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x0f8602, 0x0f8801, 0x0f8902, 0x000000, + 0x000000, 0x000000, 0x000000, 0x0f8b05, 0x000000, 0x0f9001, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x0f9119, 0x0faa06, + 0x000000, 0x000000, 0x0fb001, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x0fb101, 0x000000, + 0x000000, 0x000000, 0x000000, 0x0fb204, 0x000000, 0x0fb604, 0x000000, 0x000000, + 0x000000, 0x0fba01, 0x0fbb03, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x0fbe03, 0x0fc101, 0x000000, 0x000000, 0x0fc202, + 0x0fc402, 0x0fc601, 0x0fc713, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x0fda01, 0x000000, 0x0fdb01, 0x0fdc01, 0x000000, 0x0fdd01, 0x0fde03, 0x0fe106, + 0x000000, 0x000000, 0x0fe710, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x0ff703, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x0ffa03, 0x000000, + 0x000000, 0x000000, 0x000000, 0x0ffd01, 0x0ffe01, 0x000000, 0x000000, 0x0fff02, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x100101, 0x100202, 0x000000, + 0x000000, 0x000000, 0x100403, 0x000000, 0x100701, 0x000000, 0x000000, 0x000000, + 0x100803, 0x100b05, 0x000000, 0x101002, 0x000000, 0x000000, 0x101201, 0x10130a, + 0x000000, 0x101d01, 0x000000, 0x000000, 0x101e01, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x101f04, 0x102301, 0x102401, 0x000000, + 0x102503, 0x000000, 0x000000, 0x000000, 0x102804, 0x000000, 0x000000, 0x102c03, + 0x000000, 0x000000, 0x000000, 0x000000, 0x102f02, 0x103101, 0x103201, 0x000000, + 0x000000, 0x000000, 0x000000, 0x1033a3, 0x000000, 0x000000, 0x10d603, 0x000000, + 0x000000, 0x000000, 0x10d90f, 0x10e802, 0x000000, 0x10ea01, 0x10eb01, 0x000000, + 0x10ec01, 0x000000, 0x10ed01, 0x000000, 0x000000, 0x000000, 0x10ee01, 0x000000, + 0x10ef01, 0x000000, 0x000000, 0x000000, 0x10f005, 0x000000, 0x000000, 0x000000, + 0x10f503, 0x10f801, 0x10f904, 0x10fd01, 0x000000, 0x10fe01, 0x10ff02, 0x000000, + 0x110101, 0x110209, 0x000000, 0x000000, 0x110b05, 0x000000, 0x000000, 0x000000, + 0x000000, 0x111004, 0x000000, 0x000000, 0x000000, 0x111401, 0x000000, 0x111503, + 0x000000, 0x000000, 0x000000, 0x000000, 0x111801, 0x000000, 0x000000, 0x000000, + 0x000000, 0x111902, 0x000000, 0x000000, 0x000000, 0x111b01, 0x000000, 0x000000, + 0x000000, 0x111c01, 0x111d02, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x111f01, 0x000000, 0x000000, 0x000000, 0x000000, 0x112001, + 0x000000, 0x000000, 0x000000, 0x112105, 0x000000, 0x000000, 0x000000, 0x112607, + 0x112d09, 0x000000, 0x000000, 0x000000, 0x000000, 0x113602, 0x113801, 0x000000, + 0x000000, 0x000000, 0x000000, 0x113901, 0x000000, 0x000000, 0x113a03, 0x000000, + 0x113d01, 0x113e03, 0x114109, 0x000000, 0x114a01, 0x114b02, 0x114d01, 0x000000, + 0x114e11, 0x000000, 0x115f01, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x116002, 0x000000, 0x000000, 0x000000, 0x116201, 0x116301, 0x000000, 0x116401, + 0x116502, 0x000000, 0x116703, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x116a04, 0x000000, 0x116e03, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x117101, 0x000000, 0x117202, 0x000000, 0x117401, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x117501, 0x117602, 0x000000, 0x117802, + 0x000000, 0x000000, 0x117a02, 0x000000, 0x000000, 0x000000, 0x000000, 0x117c01, + 0x117d01, 0x000000, 0x000000, 0x000000, 0x117e02, 0x118001, 0x000000, 0x118102, + 0x000000, 0x118302, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x118502, 0x000000, 0x000000, 0x118709, 0x000000, 0x000000, 0x11900b, + 0x000000, 0x119b02, 0x000000, 0x000000, 0x119d01, 0x119e09, 0x000000, 0x11a703, + 0x11aa01, 0x000000, 0x11ab01, 0x000000, 0x11ac02, 0x000000, 0x11ae01, 0x000000, + 0x000000, 0x11af02, 0x000000, 0x000000, 0x000000, 0x000000, 0x11b101, 0x000000, + 0x11b201, 0x000000, 0x000000, 0x11b301, 0x000000, 0x000000, 0x000000, 0x11b402, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x11b601, 0x000000, 0x000000, + 0x000000, 0x11b705, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x11bc02, + 0x11be01, 0x11bf01, 0x11c002, 0x11c201, 0x000000, 0x11c302, 0x000000, 0x000000, + 0x000000, 0x000000, 0x11c501, 0x11c602, 0x000000, 0x11c809, 0x000000, 0x000000, + 0x000000, 0x000000, 0x11d109, 0x000000, 0x000000, 0x11da03, 0x000000, 0x000000, + 0x000000, 0x11dd01, 0x000000, 0x000000, 0x000000, 0x11de01, 0x000000, 0x11df01, + 0x000000, 0x11e004, 0x000000, 0x000000, 0x000000, 0x11e401, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x11e504, 0x000000, 0x000000, 0x11e902, 0x000000, + 0x000000, 0x000000, 0x11eb09, 0x000000, 0x000000, 0x11f401, 0x000000, 0x11f512, + 0x000000, 0x000000, 0x000000, 0x000000, 0x120701, 0x120801, 0x000000, 0x120901, + 0x000000, 0x000000, 0x000000, 0x000000, 0x120a01, 0x000000, 0x120b01, 0x000000, + 0x000000, 0x120c03, 0x000000, 0x120f01, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x121020, 0x000000, 0x000000, 0x000000, 0x000000, 0x123002, 0x000000, + 0x123208, 0x000000, 0x123a01, 0x000000, 0x000000, 0x000000, 0x123b02, 0x123d02, + 0x000000, 0x123f01, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x124003, + 0x12430b, 0x000000, 0x000000, 0x000000, 0x000000, 0x124e0a, 0x000000, 0x000000, + 0x000000, 0x000000, 0x125802, 0x000000, 0x000000, 0x000000, 0x000000, 0x125a02, + 0x000000, 0x125c01, 0x000000, 0x000000, 0x000000, 0x000000, 0x125d04, 0x000000, + 0x000000, 0x126107, 0x000000, 0x000000, 0x126801, 0x000000, 0x000000, 0x000000, + 0x126901, 0x126a01, 0x126b01, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x126c03, + 0x000000, 0x000000, 0x126f01, 0x000000, 0x127008, 0x127806, 0x127e02, 0x000000, + 0x000000, 0x000000, 0x128002, 0x000000, 0x000000, 0x000000, 0x128201, 0x000000, + 0x000000, 0x000000, 0x128301, 0x000000, 0x000000, 0x000000, 0x128401, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x128503, 0x000000, 0x128801, 0x128901, + 0x128a01, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x128b01, 0x000000, 0x000000, 0x000000, 0x128c02, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x128e23, 0x12b101, 0x000000, 0x12b201, 0x000000, + 0x12b308, 0x12bb01, 0x000000, 0x000000, 0x12bc01, 0x12bd01, 0x000000, 0x12be07, + 0x12c501, 0x12c602, 0x000000, 0x000000, 0x000000, 0x000000, 0x12c801, 0x12c901, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x12ca01, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x12cb01, 0x000000, 0x12cc02, 0x000000, + 0x000000, 0x12ce06, 0x000000, 0x12d401, 0x12d501, 0x000000, 0x000000, 0x000000, + 0x000000, 0x12d601, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x12d702, 0x000000, 0x000000, 0x000000, + 0x000000, 0x12d902, 0x000000, 0x000000, 0x000000, 0x12db01, 0x000000, 0x12dc0e, + 0x000000, 0x000000, 0x000000, 0x12ea04, 0x000000, 0x000000, 0x12ee06, 0x000000, + 0x12f402, 0x12f603, 0x12f901, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x12fa05, 0x000000, 0x12ff0f, 0x000000, 0x000000, 0x130e01, 0x000000, 0x000000, + 0x000000, 0x000000, 0x130f01, 0x000000, 0x000000, 0x000000, 0x000000, 0x131001, + 0x000000, 0x131101, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x131201, 0x000000, 0x000000, 0x000000, 0x000000, + 0x131302, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x131501, 0x131601, + 0x131706, 0x131d02, 0x131f06, 0x000000, 0x132503, 0x000000, 0x000000, 0x13280a, + 0x000000, 0x000000, 0x133201, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x133301, 0x133402, 0x133602, 0x133805, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x133d01, 0x000000, 0x000000, 0x000000, 0x000000, + 0x133e02, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x134001, 0x000000, 0x134101, 0x134207, 0x000000, 0x13490e, 0x000000, + 0x135701, 0x000000, 0x135804, 0x135c03, 0x135f04, 0x136337, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x139a01, 0x139b02, 0x139d01, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x139e01, 0x000000, 0x000000, + 0x000000, 0x139f01, 0x000000, 0x000000, 0x000000, 0x13a003, 0x000000, 0x000000, + 0x000000, 0x000000, 0x13a301, 0x000000, 0x000000, 0x000000, 0x000000, 0x13a401, + 0x13a501, 0x13a602, 0x000000, 0x13a801, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x13a901, 0x13aa01, 0x000000, + 0x13ab01, 0x000000, 0x000000, 0x13ac01, 0x000000, 0x000000, 0x000000, 0x000000, + 0x13ad01, 0x000000, 0x000000, 0x13ae02, 0x000000, 0x000000, 0x000000, 0x13b001, + 0x13b102, 0x000000, 0x000000, 0x000000, 0x000000, 0x13b305, 0x13b805, 0x13bd01, + 0x000000, 0x13be02, 0x000000, 0x13c003, 0x000000, 0x000000, 0x000000, 0x13c303, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x13c601, 0x000000, 0x13c701, + 0x13c802, 0x000000, 0x13ca01, 0x000000, 0x000000, 0x000000, 0x13cb08, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x13d301, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x13d401, 0x000000, 0x000000, 0x13d502, 0x13d703, + 0x000000, 0x000000, 0x13da02, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x13dc0d, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x13e901, 0x13ea02, 0x13ec04, 0x13f002, 0x13f201, 0x000000, + 0x13f301, 0x000000, 0x13f401, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x13f507, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x13fc01, 0x13fd03, 0x000000, 0x140001, 0x000000, 0x140108, 0x000000, 0x000000, + 0x140907, 0x000000, 0x000000, 0x000000, 0x14100b, 0x000000, 0x000000, 0x000000, + 0x141b03, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x141e03, 0x142101, 0x000000, 0x000000, 0x000000, 0x142201, 0x000000, 0x000000, + 0x142303, 0x142602, 0x142801, 0x000000, 0x000000, 0x000000, 0x000000, 0x142901, + 0x000000, 0x000000, 0x000000, 0x000000, 0x142a01, 0x142b02, 0x000000, 0x142d01, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x142e05, 0x000000, 0x000000, 0x000000, 0x143306, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x143901, 0x143a0b, 0x000000, + 0x000000, 0x144501, 0x000000, 0x000000, 0x144601, 0x144702, 0x144904, 0x000000, + 0x000000, 0x144d03, 0x145002, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x145203, 0x000000, 0x145503, 0x145804, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x145c01, 0x000000, 0x145d02, 0x145f01, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x146001, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x146101, 0x14620c, 0x000000, 0x146e0d, + 0x000000, 0x000000, 0x147b05, 0x148005, 0x000000, 0x148501, 0x000000, 0x148602, + 0x000000, 0x000000, 0x148801, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x148902, 0x000000, 0x148b0a, 0x149507, 0x000000, 0x149c03, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x149f01, 0x14a001, 0x14a101, 0x14a201, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x14a301, 0x000000, 0x14a402, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x14a601, 0x14a701, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x14a802, 0x14aa03, 0x000000, 0x000000, 0x14ad01, 0x000000, 0x000000, + 0x14ae09, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x14b702, 0x000000, 0x000000, 0x14b901, 0x14ba01, 0x14bb01, 0x000000, 0x14bc01, + 0x000000, 0x000000, 0x14bd01, 0x000000, 0x000000, 0x000000, 0x000000, 0x14be01, + 0x14bf01, 0x000000, 0x14c003, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x14c301, 0x000000, 0x000000, 0x000000, 0x14c408, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x14cc01, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x14cd01, 0x000000, 0x14ce02, + 0x14d003, 0x000000, 0x14d306, 0x000000, 0x000000, 0x000000, 0x000000, 0x14d902, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x14db01, 0x000000, 0x000000, 0x14dc01, 0x000000, 0x000000, 0x000000, 0x14dd01, + 0x000000, 0x14de01, 0x14df01, 0x000000, 0x000000, 0x14e002, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x14e201, 0x14e301, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x14e401, + 0x000000, 0x14e504, 0x000000, 0x14e904, 0x000000, 0x000000, 0x000000, 0x000000, + 0x14ed01, 0x000000, 0x000000, 0x14ee02, 0x000000, 0x000000, 0x14f004, 0x000000, + 0x000000, 0x14f402, 0x000000, 0x14f606, 0x000000, 0x14fc06, 0x000000, 0x000000, + 0x000000, 0x150201, 0x000000, 0x000000, 0x000000, 0x150302, 0x000000, 0x000000, + 0x000000, 0x150502, 0x000000, 0x150701, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x150802, 0x000000, 0x000000, 0x000000, 0x000000, 0x150a01, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x150b02, 0x150d03, + 0x151003, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x151301, 0x000000, 0x000000, 0x000000, + 0x000000, 0x151405, 0x151901, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x151a01, 0x000000, 0x000000, 0x000000, 0x151b01, 0x151c01, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x151d04, 0x000000, 0x000000, 0x000000, 0x000000, 0x152101, + 0x000000, 0x000000, 0x152204, 0x000000, 0x152601, 0x000000, 0x000000, 0x000000, + 0x000000, 0x152712, 0x153904, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x153d02, 0x000000, + 0x153f01, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x154001, + 0x154101, 0x000000, 0x000000, 0x000000, 0x154201, 0x154303, 0x154601, 0x000000, + 0x000000, 0x154701, 0x154802, 0x154a05, 0x000000, 0x000000, 0x000000, 0x154f01, + 0x155002, 0x000000, 0x000000, 0x000000, 0x155202, 0x000000, 0x000000, 0x000000, + 0x155403, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x155702, + 0x000000, 0x155901, 0x000000, 0x000000, 0x155a03, 0x000000, 0x155d03, 0x000000, + 0x000000, 0x156001, 0x000000, 0x000000, 0x156102, 0x000000, 0x000000, 0x156301, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x156407, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x156b01, 0x000000, 0x000000, 0x156c01, 0x156d02, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x156f01, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x157012, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x158203, 0x000000, 0x000000, 0x000000, 0x158501, + 0x000000, 0x158601, 0x000000, 0x000000, 0x158701, 0x000000, 0x000000, 0x000000, + 0x158802, 0x000000, 0x158a01, 0x000000, 0x000000, 0x158b01, 0x158c01, 0x000000, + 0x158d04, 0x000000, 0x000000, 0x15910c, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x159d01, 0x159e01, 0x000000, 0x000000, 0x159f02, 0x000000, 0x15a105, + 0x000000, 0x000000, 0x15a601, 0x000000, 0x15a701, 0x000000, 0x000000, 0x15a802, + 0x000000, 0x15aa0a, 0x000000, 0x15b401, 0x000000, 0x000000, 0x15b502, 0x000000, + 0x15b707, 0x15be01, 0x000000, 0x000000, 0x000000, 0x000000, 0x15bf03, 0x000000, + 0x000000, 0x000000, 0x15c202, 0x15c401, 0x000000, 0x15c501, 0x000000, 0x15c602, + 0x000000, 0x000000, 0x000000, 0x000000, 0x15c815, 0x000000, 0x000000, 0x15dd02, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x15df09, 0x15e801, 0x000000, 0x000000, 0x000000, 0x000000, 0x15e902, + 0x000000, 0x000000, 0x15eb0c, 0x000000, 0x15f701, 0x000000, 0x15f804, 0x000000, + 0x000000, 0x000000, 0x15fc0c, 0x000000, 0x160801, 0x000000, 0x160901, 0x160a08, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x161201, 0x000000, + 0x000000, 0x000000, 0x161301, 0x161408, 0x000000, 0x161c01, 0x161d10, 0x162d01, + 0x000000, 0x162e06, 0x000000, 0x000000, 0x000000, 0x000000, 0x163401, 0x163504, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x163902, 0x163b0b, 0x000000, + 0x164603, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x164901, 0x000000, + 0x000000, 0x000000, 0x000000, 0x164a01, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x164b01, 0x000000, 0x000000, 0x164c01, 0x000000, 0x164d02, + 0x000000, 0x000000, 0x000000, 0x164f15, 0x000000, 0x166401, 0x000000, 0x166501, + 0x166609, 0x000000, 0x000000, 0x166f07, 0x167601, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x167702, 0x000000, 0x167903, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x167c01, 0x167d02, 0x000000, 0x167f01, 0x168002, 0x000000, + 0x000000, 0x000000, 0x000000, 0x168201, 0x168301, 0x168401, 0x000000, 0x168501, + 0x000000, 0x168601, 0x168702, 0x000000, 0x168906, 0x000000, 0x000000, 0x000000, + 0x000000, 0x168f04, 0x169302, 0x000000, 0x000000, 0x000000, 0x000000, 0x169502, + 0x000000, 0x000000, 0x000000, 0x000000, 0x169704, 0x000000, 0x000000, 0x169b09, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x16a402, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x16a602, 0x000000, 0x000000, 0x16a80a, 0x000000, + 0x000000, 0x000000, 0x16b205, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x16b70b, 0x000000, 0x000000, 0x16c203, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x16c501, 0x16c601, 0x000000, + 0x000000, 0x16c701, 0x000000, 0x000000, 0x16c802, 0x000000, 0x16ca09, 0x16d301, + 0x16d401, 0x000000, 0x16d504, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x16d902, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x16db03, 0x000000, + 0x16de02, 0x16e002, 0x000000, 0x000000, 0x16e202, 0x000000, 0x16e402, 0x000000, + 0x000000, 0x16e602, 0x000000, 0x16e808, 0x000000, 0x000000, 0x000000, 0x16f002, + 0x16f202, 0x000000, 0x000000, 0x000000, 0x16f402, 0x000000, 0x16f609, 0x000000, + 0x000000, 0x000000, 0x16ff01, 0x000000, 0x000000, 0x170002, 0x170203, 0x000000, + 0x170501, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x170602, + 0x000000, 0x17080a, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x171204, 0x000000, 0x171601, 0x000000, 0x000000, 0x171701, 0x000000, 0x171809, + 0x172102, 0x172303, 0x000000, 0x172601, 0x172701, 0x000000, 0x000000, 0x000000, + 0x000000, 0x172801, 0x172903, 0x000000, 0x172c10, 0x000000, 0x000000, 0x000000, + 0x000000, 0x173c02, 0x000000, 0x000000, 0x173e02, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x174001, 0x000000, 0x000000, + 0x174105, 0x000000, 0x174601, 0x174701, 0x174803, 0x000000, 0x174b0c, 0x000000, + 0x000000, 0x000000, 0x175702, 0x175909, 0x176203, 0x176501, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x176601, 0x000000, 0x176702, 0x000000, 0x000000, + 0x000000, 0x176901, 0x176a01, 0x000000, 0x000000, 0x176b05, 0x000000, 0x000000, + 0x177002, 0x177204, 0x000000, 0x000000, 0x000000, 0x000000, 0x177601, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x177701, 0x000000, 0x000000, 0x177801, + 0x000000, 0x177901, 0x000000, 0x000000, 0x000000, 0x177a04, 0x177e02, 0x000000, + 0x178002, 0x000000, 0x178204, 0x000000, 0x178602, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x178801, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x178904, + 0x000000, 0x178d02, 0x000000, 0x000000, 0x178f01, 0x000000, 0x000000, 0x000000, + 0x179005, 0x179502, 0x179701, 0x000000, 0x000000, 0x000000, 0x179804, 0x179c01, + 0x000000, 0x000000, 0x179d07, 0x000000, 0x000000, 0x17a401, 0x000000, 0x000000, + 0x17a501, 0x000000, 0x17a602, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x17a806, 0x000000, 0x17ae01, 0x000000, 0x000000, 0x000000, 0x17af02, + 0x000000, 0x17b105, 0x17b601, 0x17b703, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x17ba01, 0x17bb01, 0x000000, 0x000000, 0x17bc01, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x17bd01, 0x17be01, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x17bf03, 0x000000, 0x17c201, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x17c304, 0x000000, 0x000000, 0x17c701, 0x000000, 0x17c804, + 0x000000, 0x000000, 0x17cc0c, 0x17d802, 0x000000, 0x000000, 0x17da03, 0x000000, + 0x17dd01, 0x000000, 0x000000, 0x000000, 0x17de0e, 0x17ec01, 0x17ed03, 0x000000, + 0x000000, 0x000000, 0x17f001, 0x000000, 0x000000, 0x000000, 0x000000, 0x17f101, + 0x000000, 0x000000, 0x000000, 0x17f203, 0x17f508, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x17fd02, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x17ff02, 0x000000, 0x000000, 0x180105, 0x180602, 0x180803, 0x000000, + 0x180b07, 0x000000, 0x181211, 0x000000, 0x182301, 0x182401, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x182502, 0x000000, 0x000000, 0x000000, 0x000000, + 0x18270b, 0x18320b, 0x000000, 0x000000, 0x183d02, 0x000000, 0x183f04, 0x000000, + 0x000000, 0x184301, 0x184401, 0x184501, 0x000000, 0x18460d, 0x000000, 0x000000, + 0x000000, 0x185306, 0x000000, 0x000000, 0x000000, 0x185901, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x185a05, 0x185f02, 0x000000, 0x186101, + 0x186201, 0x186306, 0x000000, 0x186905, 0x186e02, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x187001, 0x000000, 0x000000, 0x000000, 0x187114, 0x188506, + 0x000000, 0x188b01, 0x000000, 0x000000, 0x000000, 0x188c01, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x188d22, 0x000000, + 0x000000, 0x000000, 0x18af02, 0x000000, 0x000000, 0x18b10a, 0x18bb02, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x18bd01, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x18be02, + 0x000000, 0x000000, 0x18c001, 0x000000, 0x18c101, 0x000000, 0x18c201, 0x18c310, + 0x000000, 0x000000, 0x18d301, 0x18d40c, 0x18e001, 0x000000, 0x000000, 0x000000, + 0x18e101, 0x18e201, 0x18e301, 0x000000, 0x18e403, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x18e706, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x18ed01, 0x18ee01, 0x18ef02, 0x000000, 0x000000, 0x000000, 0x000000, 0x18f103, + 0x000000, 0x18f408, 0x18fc03, 0x18ff0b, 0x190a03, 0x000000, 0x190d01, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x190e01, 0x190f01, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x191001, 0x000000, + 0x000000, 0x000000, 0x000000, 0x191102, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x191301, 0x000000, 0x191402, 0x191602, 0x191804, + 0x000000, 0x191c01, 0x191d03, 0x000000, 0x192005, 0x192501, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x192601, 0x192701, 0x000000, 0x000000, 0x192803, 0x000000, 0x000000, 0x192b02, + 0x000000, 0x000000, 0x000000, 0x000000, 0x192d01, 0x000000, 0x000000, 0x000000, + 0x000000, 0x192e01, 0x192f02, 0x000000, 0x000000, 0x193104, 0x000000, 0x000000, + 0x000000, 0x193501, 0x000000, 0x000000, 0x193606, 0x000000, 0x193c01, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x193d01, 0x000000, 0x000000, + 0x193e01, 0x000000, 0x193f01, 0x000000, 0x194002, 0x194201, 0x000000, 0x000000, + 0x000000, 0x19430b, 0x000000, 0x194e01, 0x194f01, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x195004, 0x000000, 0x000000, 0x195402, + 0x195606, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x195c01, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x195d01, 0x195e01, 0x195f02, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x196109, 0x000000, 0x000000, 0x000000, 0x196a01, 0x196b03, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x196e01, 0x196f01, 0x000000, 0x000000, 0x000000, 0x000000, 0x197001, 0x000000, + 0x000000, 0x000000, 0x197102, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x197301, 0x000000, 0x000000, 0x197401, 0x197501, 0x000000, 0x000000, 0x000000, + 0x197601, 0x197701, 0x197802, 0x000000, 0x197a01, 0x000000, 0x000000, 0x000000, + 0x000000, 0x197b04, 0x197f02, 0x000000, 0x198102, 0x000000, 0x000000, 0x19832e, + 0x000000, 0x19b105, 0x000000, 0x000000, 0x000000, 0x19b601, 0x000000, 0x19b703, + 0x000000, 0x000000, 0x000000, 0x19ba03, 0x000000, 0x000000, 0x000000, 0x19bd01, + 0x000000, 0x19be01, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x19bf01, + 0x000000, 0x000000, 0x000000, 0x000000, 0x19c001, 0x19c105, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x19c601, 0x19c701, 0x000000, 0x000000, 0x19c801, + 0x19c902, 0x19cb04, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x19cf02, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x19d101, 0x19d204, 0x000000, 0x19d601, 0x000000, 0x19d702, 0x19d902, + 0x19db11, 0x000000, 0x19ec02, 0x000000, 0x000000, 0x000000, 0x000000, 0x19ee02, + 0x000000, 0x000000, 0x000000, 0x000000, 0x19f001, 0x000000, 0x19f105, 0x000000, + 0x000000, 0x000000, 0x19f60d, 0x000000, 0x1a0303, 0x1a0601, 0x000000, 0x1a0702, + 0x000000, 0x1a0903, 0x1a0c06, 0x000000, 0x1a1201, 0x1a1301, 0x1a1401, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x1a1501, 0x000000, 0x000000, 0x000000, 0x1a1601, 0x000000, 0x1a170d, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x1a240b, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x1a2f01, 0x1a3001, 0x1a3105, 0x000000, 0x000000, 0x1a3602, 0x1a3803, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x1a3b01, 0x000000, 0x000000, 0x000000, + 0x1a3c02, 0x000000, 0x1a3e05, 0x1a4301, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x1a4401, 0x1a4502, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x1a4701, 0x1a4806, 0x1a4e02, 0x000000, 0x1a5005, + 0x1a5501, 0x000000, 0x000000, 0x1a5607, 0x1a5d01, 0x000000, 0x1a5e01, 0x000000, + 0x000000, 0x1a5f01, 0x1a6001, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x1a6102, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x1a6307, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x1a6a01, 0x000000, + 0x000000, 0x1a6b01, 0x1a6c05, 0x000000, 0x000000, 0x000000, 0x1a7106, 0x000000, + 0x000000, 0x000000, 0x1a7704, 0x1a7b01, 0x000000, 0x1a7c02, 0x000000, 0x000000, + 0x000000, 0x1a7e01, 0x000000, 0x1a7f01, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x1a8007, + 0x000000, 0x000000, 0x000000, 0x1a8701, 0x000000, 0x000000, 0x000000, 0x1a8809, + 0x000000, 0x000000, 0x1a9101, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x1a9201, 0x000000, 0x000000, 0x000000, 0x1a9308, 0x000000, 0x000000, 0x000000, + 0x1a9b0b, 0x000000, 0x000000, 0x1aa601, 0x000000, 0x1aa70f, 0x1ab60d, 0x000000, + 0x000000, 0x000000, 0x000000, 0x1ac302, 0x000000, 0x000000, 0x1ac502, 0x000000, + 0x1ac701, 0x1ac80a, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x1ad201, 0x000000, 0x1ad302, 0x1ad502, 0x1ad701, + 0x000000, 0x000000, 0x000000, 0x1ad801, 0x1ad901, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x1ada02, 0x000000, 0x000000, 0x1adc01, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x1add01, 0x000000, 0x000000, + 0x000000, 0x1ade01, 0x000000, 0x1adf07, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x1ae601, 0x000000, + 0x1ae703, 0x1aea02, 0x1aec02, 0x000000, 0x1aee04, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x1af202, 0x000000, 0x000000, + 0x000000, 0x000000, 0x1af409, 0x000000, 0x000000, 0x000000, 0x000000, 0x1afd01, + 0x000000, 0x1afe01, 0x000000, 0x000000, 0x1aff01, 0x000000, 0x000000, 0x1b0001, + 0x1b0101, 0x000000, 0x000000, 0x000000, 0x1b0201, 0x000000, 0x000000, 0x000000, + 0x1b0303, 0x1b0605, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x1b0b01, 0x000000, 0x1b0c01, 0x000000, 0x000000, 0x000000, 0x1b0d01, 0x1b0e01, + 0x1b0f01, 0x000000, 0x1b1001, 0x000000, 0x1b1101, 0x000000, 0x000000, 0x1b1204, + 0x1b1601, 0x000000, 0x1b1703, 0x000000, 0x000000, 0x000000, 0x000000, 0x1b1a01, + 0x1b1b01, 0x1b1c01, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x1b1d06, 0x1b2301, 0x1b2403, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x1b2702, 0x1b2909, 0x1b3202, 0x1b3401, 0x1b3501, + 0x000000, 0x000000, 0x1b3601, 0x1b3701, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x1b3801, 0x000000, 0x000000, + 0x1b3909, 0x1b4201, 0x000000, 0x000000, 0x1b4303, 0x000000, 0x000000, 0x1b4601, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x1b4704, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x1b4b02, 0x1b4d02, 0x1b4f03, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x1b5211, + 0x000000, 0x000000, 0x000000, 0x1b6307, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x1b6a02, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x1b6c01, 0x000000, + 0x000000, 0x1b6d01, 0x1b6e05, 0x1b7302, 0x000000, 0x1b7503, 0x1b7805, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x1b7d01, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x1b7e07, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x1b8501, 0x000000, + 0x1b8601, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x1b8704, 0x1b8b02, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x1b8d06, 0x000000, 0x1b9301, 0x000000, 0x000000, + 0x000000, 0x000000, 0x1b9404, 0x000000, 0x1b9802, 0x000000, 0x000000, 0x000000, + 0x000000, 0x1b9a02, 0x1b9c01, 0x000000, 0x1b9d01, 0x1b9e01, 0x1b9f06, 0x000000, + 0x000000, 0x1ba502, 0x000000, 0x1ba701, 0x1ba802, 0x000000, 0x1baa01, 0x000000, + 0x000000, 0x000000, 0x1bab03, 0x1bae01, 0x1baf02, 0x000000, 0x000000, 0x1bb103, + 0x000000, 0x1bb40e, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x1bc201, 0x000000, 0x000000, 0x1bc302, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x1bc504, 0x000000, 0x1bc901, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x1bca01, + 0x000000, 0x1bcb01, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x1bcc01, + 0x000000, 0x000000, 0x1bcd06, 0x000000, 0x000000, 0x1bd301, 0x000000, 0x1bd401, + 0x000000, 0x000000, 0x1bd502, 0x000000, 0x000000, 0x000000, 0x000000, 0x1bd701, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x1bd801, 0x000000, 0x1bd902, + 0x000000, 0x1bdb01, 0x1bdc01, 0x000000, 0x000000, 0x1bdd05, 0x000000, 0x000000, + 0x1be209, 0x000000, 0x1beb02, 0x1bed02, 0x000000, 0x000000, 0x000000, 0x000000, + 0x1bef01, 0x000000, 0x000000, 0x000000, 0x1bf003, 0x1bf301, 0x1bf401, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x1bf505, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x1bfa02, + 0x1bfc04, 0x1c0002, 0x000000, 0x1c0201, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x1c0301, 0x000000, 0x1c0408, + 0x1c0c01, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x1c0d03, 0x1c1002, + 0x000000, 0x000000, 0x000000, 0x000000, 0x1c120e, 0x000000, 0x1c2003, 0x1c2302, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x1c2501, 0x1c2604, 0x000000, + 0x000000, 0x000000, 0x000000, 0x1c2a05, 0x1c2f02, 0x000000, 0x1c3108, 0x000000, + 0x000000, 0x000000, 0x000000, 0x1c3902, 0x1c3b02, 0x1c3d02, 0x1c3f01, 0x1c4002, + 0x1c4202, 0x1c4401, 0x000000, 0x000000, 0x000000, 0x000000, 0x1c4503, 0x1c4801, + 0x000000, 0x1c4905, 0x000000, 0x000000, 0x1c4e13, 0x000000, 0x000000, 0x000000, + 0x1c6117, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x1c7801, 0x000000, 0x000000, 0x1c7901, 0x1c7a01, 0x000000, 0x000000, 0x1c7b05, + 0x000000, 0x1c8003, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x1c8301, 0x000000, 0x1c8401, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x1c8503, 0x000000, 0x000000, 0x000000, 0x000000, + 0x1c8802, 0x000000, 0x000000, 0x000000, 0x000000, 0x1c8a01, 0x000000, 0x1c8b02, + 0x000000, 0x1c8d19, 0x000000, 0x1ca602, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x1ca806, 0x000000, 0x1cae04, 0x1cb201, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x1cb301, 0x000000, 0x1cb401, 0x1cb502, + 0x1cb702, 0x1cb903, 0x000000, 0x000000, 0x000000, 0x000000, 0x1cbc01, 0x000000, + 0x1cbd08, 0x1cc501, 0x000000, 0x1cc601, 0x1cc705, 0x000000, 0x000000, 0x1ccc01, + 0x000000, 0x000000, 0x000000, 0x1ccd02, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x1ccf01, 0x000000, 0x000000, 0x000000, 0x1cd001, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x1cd101, 0x000000, 0x1cd201, + 0x1cd303, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x1cd603, 0x000000, + 0x000000, 0x1cd90c, 0x000000, 0x000000, 0x000000, 0x000000, 0x1ce501, 0x000000, + 0x000000, 0x000000, 0x1ce601, 0x1ce701, 0x000000, 0x1ce801, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x1ce903, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x1cec01, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x1ced0f, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x1cfc06, 0x1d0202, 0x1d0406, 0x000000, 0x000000, 0x000000, + 0x1d0a01, 0x000000, 0x000000, 0x1d0b01, 0x000000, 0x000000, 0x000000, 0x1d0c01, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x1d0d05, 0x1d1203, + 0x000000, 0x1d1502, 0x000000, 0x1d1708, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x1d1f01, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x1d2004, 0x000000, 0x000000, 0x1d2401, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x1d2501, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x1d2603, 0x1d2906, 0x1d2f04, 0x000000, + 0x1d330e, 0x000000, 0x000000, 0x1d4101, 0x000000, 0x1d4202, 0x000000, 0x000000, + 0x1d4405, 0x000000, 0x000000, 0x000000, 0x1d4901, 0x1d4a09, 0x000000, 0x000000, + 0x1d5304, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x1d5701, 0x000000, + 0x000000, 0x000000, 0x1d5801, 0x1d5902, 0x1d5b02, 0x000000, 0x000000, 0x000000, + 0x000000, 0x1d5d01, 0x000000, 0x000000, 0x1d5e02, 0x1d6001, 0x1d6104, 0x000000, + 0x000000, 0x000000, 0x1d6503, 0x000000, 0x000000, 0x1d6802, 0x000000, 0x000000, + 0x1d6a05, 0x000000, 0x1d6f02, 0x000000, 0x1d7101, 0x000000, 0x1d7202, 0x000000, + 0x000000, 0x1d7401, 0x1d7504, 0x1d7901, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x1d7a01, 0x000000, 0x1d7b02, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x1d7d02, 0x000000, 0x000000, 0x1d7f01, 0x1d8001, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x1d8109, 0x1d8a0a, 0x000000, 0x1d9401, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x1d9502, 0x1d9702, 0x000000, 0x1d9903, 0x1d9c02, 0x1d9e01, + 0x000000, 0x000000, 0x000000, 0x1d9f03, 0x000000, 0x1da202, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x1da405, 0x000000, 0x000000, 0x000000, 0x1da901, + 0x000000, 0x000000, 0x1daa05, 0x000000, 0x000000, 0x1daf02, 0x1db108, 0x1db902, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x1dbb01, 0x000000, 0x1dbc01, + 0x1dbd01, 0x000000, 0x000000, 0x1dbe01, 0x000000, 0x000000, 0x1dbf04, 0x000000, + 0x1dc301, 0x000000, 0x1dc401, 0x1dc501, 0x000000, 0x1dc603, 0x000000, 0x000000, + 0x000000, 0x000000, 0x1dc901, 0x000000, 0x000000, 0x000000, 0x000000, 0x1dca02, + 0x1dcc02, 0x1dce02, 0x000000, 0x000000, 0x1dd006, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x1dd601, 0x000000, 0x1dd702, 0x1dd901, 0x000000, 0x000000, + 0x1dda01, 0x000000, 0x000000, 0x000000, 0x000000, 0x1ddb01, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x1ddc10, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x1dec01, 0x1ded01, 0x1dee02, 0x1df001, 0x000000, + 0x1df101, 0x000000, 0x1df211, 0x000000, 0x1e0304, 0x1e0702, 0x1e0901, 0x000000, + 0x1e0a01, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x1e0b08, + 0x000000, 0x000000, 0x1e1307, 0x000000, 0x1e1a01, 0x000000, 0x1e1b01, 0x000000, + 0x1e1c0c, 0x000000, 0x1e2801, 0x000000, 0x000000, 0x000000, 0x1e2902, 0x000000, + 0x1e2b05, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x1e3002, + 0x1e3201, 0x000000, 0x1e3301, 0x000000, 0x1e3402, 0x1e3604, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x1e3a02, 0x000000, 0x000000, + 0x1e3c04, 0x1e4003, 0x000000, 0x1e4303, 0x000000, 0x000000, 0x000000, 0x1e4601, + 0x000000, 0x000000, 0x000000, 0x1e4701, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x1e4803, 0x000000, 0x000000, 0x1e4b01, 0x000000, + 0x1e4c02, 0x000000, 0x1e4e01, 0x000000, 0x1e4f01, 0x000000, 0x000000, 0x000000, + 0x000000, 0x1e5007, 0x1e5701, 0x000000, 0x000000, 0x1e5801, 0x000000, 0x000000, + 0x1e5901, 0x000000, 0x000000, 0x1e5a01, 0x000000, 0x000000, 0x1e5b01, 0x000000, + 0x000000, 0x1e5c05, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x1e6105, + 0x1e6601, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x1e6701, 0x1e6805, + 0x000000, 0x1e6d02, 0x000000, 0x000000, 0x000000, 0x000000, 0x1e6f06, 0x000000, + 0x1e7501, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x1e760b, 0x000000, + 0x1e8103, 0x000000, 0x000000, 0x1e8401, 0x000000, 0x1e8502, 0x000000, 0x1e8702, + 0x000000, 0x1e8906, 0x1e8f01, 0x1e9001, 0x1e9102, 0x000000, 0x1e9302, 0x1e950a, + 0x000000, 0x000000, 0x000000, 0x1e9f02, 0x000000, 0x1ea101, 0x000000, 0x1ea201, + 0x000000, 0x000000, 0x000000, 0x000000, 0x1ea302, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x1ea50a, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x1eaf01, 0x1eb001, 0x1eb104, 0x1eb503, 0x000000, 0x1eb801, + 0x000000, 0x000000, 0x1eb92f, 0x000000, 0x000000, 0x1ee801, 0x000000, 0x000000, + 0x000000, 0x000000, 0x1ee901, 0x000000, 0x000000, 0x1eea02, 0x1eec01, 0x1eed01, + 0x1eee01, 0x000000, 0x1eef01, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x1ef001, 0x1ef102, 0x000000, 0x1ef301, 0x000000, 0x000000, + 0x1ef402, 0x000000, 0x000000, 0x1ef603, 0x000000, 0x1ef905, 0x1efe02, 0x000000, + 0x000000, 0x1f0002, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x1f0201, 0x000000, 0x1f0301, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x1f0404, 0x000000, 0x000000, 0x000000, 0x000000, 0x1f0804, 0x000000, 0x000000, + 0x000000, 0x000000, 0x1f0c01, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x1f0d03, 0x000000, 0x1f100f, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x1f1f01, 0x000000, 0x000000, + 0x000000, 0x000000, 0x1f2003, 0x1f2314, 0x1f3701, 0x000000, 0x1f3801, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x1f390d, 0x000000, 0x000000, 0x000000, 0x000000, 0x1f4601, + 0x1f4702, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x1f4902, 0x000000, 0x000000, + 0x000000, 0x1f4b06, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x1f510a, 0x000000, 0x1f5b01, 0x1f5c01, 0x000000, 0x000000, + 0x1f5d02, 0x000000, 0x000000, 0x1f5f01, 0x1f6001, 0x000000, 0x000000, 0x1f6102, + 0x1f6301, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x1f6406, 0x000000, 0x000000, 0x000000, 0x1f6a09, + 0x1f7307, 0x1f7a01, 0x1f7b01, 0x000000, 0x000000, 0x1f7c01, 0x000000, 0x000000, + 0x000000, 0x1f7d01, 0x000000, 0x1f7e01, 0x000000, 0x1f7f02, 0x000000, 0x1f8102, + 0x1f830c, 0x000000, 0x000000, 0x000000, 0x1f8f01, 0x1f9008, 0x000000, 0x1f9803, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x1f9b01, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x1f9c11, 0x1fad01, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x1fae01, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x1faf03, 0x1fb202, 0x000000, 0x1fb403, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x1fb701, + 0x1fb801, 0x1fb906, 0x1fbf01, 0x1fc001, 0x1fc101, 0x1fc208, 0x000000, 0x000000, + 0x1fca05, 0x000000, 0x000000, 0x1fcf01, 0x000000, 0x000000, 0x000000, 0x000000, + 0x1fd001, 0x1fd107, 0x1fd801, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x1fd903, 0x000000, 0x1fdc03, 0x1fdf02, 0x1fe102, + 0x000000, 0x1fe301, 0x1fe401, 0x000000, 0x000000, 0x000000, 0x000000, 0x1fe501, + 0x1fe60c, 0x000000, 0x000000, 0x1ff206, 0x000000, 0x000000, 0x000000, 0x1ff801, + 0x000000, 0x000000, 0x000000, 0x1ff901, 0x000000, 0x000000, 0x1ffa01, 0x000000, + 0x000000, 0x000000, 0x1ffb10, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x200b06, 0x000000, 0x000000, 0x000000, 0x000000, 0x201103, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x201401, 0x000000, 0x201501, 0x000000, 0x000000, + 0x201603, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x201901, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x201a02, 0x000000, 0x201c01, 0x000000, 0x000000, 0x201d03, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x202008, + 0x000000, 0x000000, 0x000000, 0x202809, 0x000000, 0x000000, 0x203105, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x203601, 0x000000, 0x203704, 0x203b04, 0x000000, 0x203f01, + 0x204004, 0x000000, 0x000000, 0x204403, 0x000000, 0x204701, 0x204802, 0x000000, + 0x000000, 0x000000, 0x000000, 0x204a02, 0x000000, 0x000000, 0x000000, 0x204c01, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x204d08, 0x000000, 0x000000, 0x000000, 0x205501, 0x000000, 0x205604, + 0x205a02, 0x000000, 0x000000, 0x205c01, 0x205d03, 0x206003, 0x206301, 0x000000, + 0x000000, 0x000000, 0x000000, 0x206402, 0x206604, 0x206a01, 0x206b01, 0x206c03, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x206f03, 0x20720e, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x208001, + 0x000000, 0x000000, 0x000000, 0x208101, 0x208202, 0x208401, 0x208501, 0x208605, + 0x000000, 0x000000, 0x208b06, 0x209102, 0x000000, 0x000000, 0x20930a, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x209d01, 0x000000, 0x000000, 0x209e03, + 0x000000, 0x20a101, 0x20a205, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x20a70c, 0x20b305, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x20b803, 0x000000, 0x000000, 0x000000, 0x000000, + 0x20bb03, 0x000000, 0x000000, 0x000000, 0x20be01, 0x000000, 0x20bf02, 0x000000, + 0x000000, 0x000000, 0x000000, 0x20c106, 0x20c702, 0x000000, 0x000000, 0x20c902, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x20cb01, + 0x20cc01, 0x000000, 0x20cd01, 0x000000, 0x20ce01, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x20cf01, 0x000000, 0x20d009, 0x20d901, 0x20da01, 0x000000, + 0x20db01, 0x20dc09, 0x20e501, 0x000000, 0x000000, 0x000000, 0x000000, 0x20e601, + 0x000000, 0x000000, 0x000000, 0x000000, 0x20e701, 0x000000, 0x000000, 0x20e810, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x20f801, + 0x20f901, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x20fa01, + 0x000000, 0x000000, 0x20fb03, 0x000000, 0x20fe04, 0x000000, 0x000000, 0x000000, + 0x000000, 0x210207, 0x000000, 0x210904, 0x000000, 0x210d06, 0x000000, 0x000000, + 0x211301, 0x000000, 0x211401, 0x000000, 0x000000, 0x000000, 0x211503, 0x000000, + 0x211806, 0x211e01, 0x211f01, 0x000000, 0x000000, 0x000000, 0x000000, 0x212002, + 0x212201, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x212306, 0x000000, 0x000000, 0x212901, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x212a02, 0x212c01, 0x212d22, 0x000000, + 0x214f02, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x215104, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x215504, 0x215902, 0x215b01, 0x000000, 0x000000, 0x215c04, 0x000000, + 0x000000, 0x21600c, 0x000000, 0x216c0c, 0x000000, 0x000000, 0x217801, 0x217901, + 0x000000, 0x000000, 0x217a03, 0x217d01, 0x217e04, 0x218204, 0x000000, 0x218608, + 0x000000, 0x000000, 0x000000, 0x000000, 0x218e0f, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x219d01, 0x000000, 0x219e01, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x219f01, 0x000000, 0x000000, 0x21a001, 0x000000, 0x000000, 0x000000, + 0x21a101, 0x000000, 0x000000, 0x000000, 0x21a202, 0x000000, 0x000000, 0x21a404, + 0x21a804, 0x21ac01, 0x000000, 0x000000, 0x21ad01, 0x000000, 0x21ae01, 0x000000, + 0x21af01, 0x21b00c, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x21bc01, 0x21bd01, 0x21be0b, 0x21c902, 0x000000, + 0x000000, 0x000000, 0x000000, 0x21cb02, 0x21cd01, 0x21ce01, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x21cf01, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x21d001, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x21d101, 0x000000, 0x000000, 0x21d201, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x21d301, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x21d402, + 0x21d601, 0x21d701, 0x000000, 0x000000, 0x000000, 0x000000, 0x21d804, 0x000000, + 0x21dc02, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x21de03, 0x21e10a, 0x000000, 0x21eb02, 0x000000, 0x21ed03, 0x000000, 0x000000, + 0x000000, 0x21f001, 0x000000, 0x000000, 0x000000, 0x21f110, 0x000000, 0x220104, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x220501, 0x000000, 0x220602, 0x220801, 0x22090a, + 0x221303, 0x221601, 0x221705, 0x221c03, 0x221f01, 0x000000, 0x222002, 0x222203, + 0x000000, 0x000000, 0x000000, 0x000000, 0x222501, 0x222602, 0x222809, 0x223102, + 0x000000, 0x000000, 0x000000, 0x000000, 0x223301, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x223403, 0x223702, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x223901, 0x223a01, 0x223b02, 0x000000, 0x223d03, 0x224001, + 0x224103, 0x224401, 0x000000, 0x224505, 0x000000, 0x224a01, 0x000000, 0x000000, + 0x000000, 0x000000, 0x224b01, 0x000000, 0x000000, 0x224c02, 0x000000, 0x000000, + 0x224e01, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x224f01, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x225001, 0x000000, 0x000000, 0x000000, 0x000000, 0x225102, 0x000000, 0x000000, + 0x000000, 0x000000, 0x225302, 0x22550d, 0x000000, 0x000000, 0x000000, 0x22620a, + 0x000000, 0x226c01, 0x226d01, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x226e01, 0x226f02, 0x000000, 0x000000, 0x000000, 0x000000, 0x227104, 0x000000, + 0x000000, 0x000000, 0x000000, 0x227506, 0x227b01, 0x227c02, 0x000000, 0x227e02, + 0x000000, 0x000000, 0x000000, 0x000000, 0x228001, 0x000000, 0x000000, 0x000000, + 0x228101, 0x000000, 0x000000, 0x000000, 0x228201, 0x000000, 0x228301, 0x000000, + 0x000000, 0x000000, 0x228401, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x228501, 0x228601, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x228701, 0x000000, + 0x000000, 0x000000, 0x228801, 0x000000, 0x228904, 0x000000, 0x000000, 0x000000, + 0x228d01, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x228e01, 0x000000, 0x228f10, 0x000000, 0x000000, 0x229f02, 0x000000, 0x000000, + 0x22a104, 0x000000, 0x000000, 0x22a502, 0x22a701, 0x000000, 0x000000, 0x22a801, + 0x22a901, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x22aa01, + 0x000000, 0x22ab14, 0x000000, 0x000000, 0x000000, 0x000000, 0x22bf04, 0x22c301, + 0x000000, 0x000000, 0x000000, 0x000000, 0x22c403, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x22c703, 0x000000, 0x22ca04, 0x000000, 0x000000, 0x000000, + 0x000000, 0x22ce01, 0x22cf01, 0x22d001, 0x000000, 0x000000, 0x000000, 0x22d101, + 0x000000, 0x22d201, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x22d30d, 0x000000, + 0x000000, 0x000000, 0x22e001, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x22e102, 0x000000, 0x22e30b, + 0x000000, 0x22ee02, 0x000000, 0x000000, 0x000000, 0x22f002, 0x22f202, 0x000000, + 0x000000, 0x000000, 0x000000, 0x22f401, 0x000000, 0x22f504, 0x000000, 0x22f903, + 0x22fc0d, 0x000000, 0x000000, 0x230901, 0x000000, 0x000000, 0x000000, 0x000000, + 0x230a19, 0x000000, 0x232301, 0x000000, 0x000000, 0x000000, 0x000000, 0x232403, + 0x232701, 0x000000, 0x000000, 0x000000, 0x000000, 0x232801, 0x232902, 0x000000, + 0x232b05, 0x23300f, 0x233f03, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x234237, + 0x237901, 0x000000, 0x000000, 0x237a06, 0x238001, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x238102, 0x000000, 0x000000, 0x000000, 0x238301, + 0x000000, 0x000000, 0x238402, 0x000000, 0x238601, 0x000000, 0x000000, 0x238701, + 0x238804, 0x238c01, 0x238d0a, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x239702, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x239906, 0x000000, 0x000000, 0x239f01, 0x000000, 0x23a001, + 0x23a101, 0x000000, 0x000000, 0x000000, 0x23a201, 0x23a301, 0x000000, 0x000000, + 0x23a401, 0x000000, 0x000000, 0x23a501, 0x000000, 0x23a602, 0x000000, 0x000000, + 0x23a802, 0x23aa01, 0x000000, 0x000000, 0x000000, 0x23ab04, 0x000000, 0x000000, + 0x23af08, 0x000000, 0x23b704, 0x000000, 0x000000, 0x23bb01, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x23bc03, 0x000000, 0x23bf0b, 0x23ca02, + 0x000000, 0x000000, 0x23cc01, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x23cd03, 0x000000, 0x23d001, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x23d102, 0x000000, 0x000000, 0x000000, 0x000000, 0x23d302, + 0x000000, 0x23d501, 0x23d601, 0x23d701, 0x000000, 0x23d809, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x23e101, 0x000000, + 0x23e201, 0x000000, 0x000000, 0x000000, 0x23e301, 0x23e401, 0x000000, 0x000000, + 0x23e501, 0x000000, 0x000000, 0x000000, 0x000000, 0x23e602, 0x000000, 0x000000, + 0x000000, 0x23e804, 0x000000, 0x000000, 0x000000, 0x000000, 0x23ec01, 0x23ed0a, + 0x000000, 0x000000, 0x000000, 0x23f703, 0x23fa05, 0x000000, 0x000000, 0x000000, + 0x000000, 0x23ff01, 0x240003, 0x000000, 0x240301, 0x000000, 0x000000, 0x000000, + 0x000000, 0x240401, 0x240501, 0x240601, 0x000000, 0x240701, 0x240802, 0x000000, + 0x000000, 0x240a01, 0x000000, 0x240b01, 0x240c01, 0x000000, 0x000000, 0x240d02, + 0x000000, 0x240f01, 0x000000, 0x241001, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x241101, 0x241202, 0x000000, 0x000000, 0x241401, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x241502, 0x241701, + 0x000000, 0x000000, 0x241803, 0x000000, 0x000000, 0x000000, 0x000000, 0x241b03, + 0x000000, 0x000000, 0x000000, 0x000000, 0x241e01, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x241f01, + 0x000000, 0x000000, 0x000000, 0x242001, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x242101, 0x000000, 0x000000, 0x000000, 0x000000, 0x242201, 0x000000, + 0x000000, 0x242303, 0x242601, 0x000000, 0x000000, 0x000000, 0x242701, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x242801, 0x000000, + 0x000000, 0x242901, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x242a03, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x242d01, 0x242e02, + 0x000000, 0x000000, 0x243001, 0x243102, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x243303, 0x243602, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x243803, + 0x000000, 0x000000, 0x000000, 0x243b01, 0x243c02, 0x243e01, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x243f0d, 0x000000, 0x000000, + 0x244c04, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x245004, 0x245407, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x245b01, 0x245c04, 0x246008, 0x246801, 0x246904, + 0x000000, 0x246d01, 0x246e96, 0x000000, 0x000000, 0x250402, 0x000000, 0x250603, + 0x000000, 0x000000, 0x000000, 0x000000, 0x250901, 0x000000, 0x000000, 0x000000, + 0x250a01, 0x000000, 0x250b01, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x250c01, 0x000000, 0x000000, 0x250d03, + 0x000000, 0x000000, 0x000000, 0x251001, 0x000000, 0x000000, 0x000000, 0x000000, + 0x251101, 0x251202, 0x000000, 0x000000, 0x000000, 0x000000, 0x251402, 0x000000, + 0x251601, 0x251704, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x251b02, 0x000000, 0x251d02, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x251f03, 0x252202, 0x000000, 0x252402, 0x000000, 0x252602, + 0x000000, 0x000000, 0x252802, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x252a01, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x252b01, 0x252c0f, 0x000000, 0x000000, 0x000000, 0x000000, + 0x253b01, 0x000000, 0x000000, 0x253c05, 0x000000, 0x000000, 0x254101, 0x000000, + 0x254201, 0x254301, 0x000000, 0x000000, 0x000000, 0x000000, 0x254401, 0x000000, + 0x000000, 0x000000, 0x254502, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x254701, 0x254801, 0x000000, 0x254901, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x254a01, 0x254b02, 0x000000, + 0x000000, 0x000000, 0x254d07, 0x000000, 0x255401, 0x000000, 0x255503, 0x000000, + 0x255802, 0x000000, 0x255a07, 0x256102, 0x000000, 0x256302, 0x256501, 0x256602, + 0x000000, 0x000000, 0x000000, 0x25680f, 0x257704, 0x000000, 0x000000, 0x257b02, + 0x000000, 0x000000, 0x000000, 0x257d02, 0x000000, 0x257f01, 0x000000, 0x258007, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x25871e, 0x000000, + 0x25a501, 0x25a602, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x25a802, 0x000000, 0x000000, 0x25aa01, 0x25ab01, 0x25ac01, 0x25ad02, + 0x000000, 0x000000, 0x000000, 0x25af02, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x25b104, 0x25b501, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x25b601, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x25b701, 0x000000, 0x25b801, 0x000000, 0x000000, + 0x000000, 0x000000, 0x25b901, 0x000000, 0x000000, 0x25ba05, 0x000000, 0x000000, + 0x25bf01, 0x000000, 0x000000, 0x25c002, 0x000000, 0x25c202, 0x25c402, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x25c602, 0x000000, 0x25c808, 0x25d001, 0x000000, + 0x000000, 0x000000, 0x000000, 0x25d101, 0x25d201, 0x25d302, 0x000000, 0x000000, + 0x000000, 0x000000, 0x25d50c, 0x25e102, 0x000000, 0x000000, 0x25e301, 0x25e401, + 0x25e501, 0x000000, 0x25e60e, 0x25f401, 0x000000, 0x000000, 0x000000, 0x000000, + 0x25f508, 0x000000, 0x25fd01, 0x000000, 0x000000, 0x000000, 0x000000, 0x25fe01, + 0x000000, 0x000000, 0x000000, 0x25ff0e, 0x000000, 0x260d02, 0x000000, 0x260f06, + 0x000000, 0x000000, 0x000000, 0x261504, 0x000000, 0x261901, 0x261a01, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x261b01, 0x000000, 0x261c0b, 0x262701, + 0x000000, 0x262801, 0x000000, 0x000000, 0x000000, 0x262901, 0x262a02, 0x000000, + 0x262c01, 0x000000, 0x262d01, 0x000000, 0x262e01, 0x000000, 0x000000, 0x000000, + 0x262f01, 0x263007, 0x263702, 0x000000, 0x000000, 0x000000, 0x263903, 0x000000, + 0x263c04, 0x000000, 0x000000, 0x000000, 0x000000, 0x264001, 0x26410e, 0x000000, + 0x000000, 0x000000, 0x264f03, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x265201, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x265308, 0x000000, 0x265b03, + 0x000000, 0x265e05, 0x000000, 0x266302, 0x000000, 0x000000, 0x000000, 0x000000, + 0x266503, 0x000000, 0x000000, 0x266803, 0x266b04, 0x000000, 0x000000, 0x000000, + 0x266f01, 0x000000, 0x000000, 0x000000, 0x267001, 0x000000, 0x000000, 0x267103, + 0x000000, 0x267402, 0x000000, 0x000000, 0x000000, 0x267601, 0x267707, 0x000000, + 0x000000, 0x267e01, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x267f07, 0x268602, 0x268801, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x268901, 0x268a01, 0x268b05, 0x269002, 0x269205, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x269706, 0x000000, + 0x269d01, 0x000000, 0x000000, 0x000000, 0x269e04, 0x000000, 0x000000, 0x26a20f, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x26b101, + 0x26b201, 0x26b301, 0x000000, 0x000000, 0x000000, 0x26b401, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x26b503, 0x000000, 0x000000, 0x000000, + 0x000000, 0x26b801, 0x000000, 0x000000, 0x000000, 0x000000, 0x26b908, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x26c101, 0x000000, 0x000000, 0x000000, + 0x000000, 0x26c202, 0x26c405, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x26c901, 0x000000, 0x000000, 0x000000, 0x26ca01, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x26cb07, 0x000000, 0x26d201, + 0x000000, 0x000000, 0x26d316, 0x26e904, 0x26ed03, 0x000000, 0x26f001, 0x26f104, + 0x000000, 0x000000, 0x26f505, 0x000000, 0x26fa02, 0x26fc01, 0x26fd03, 0x000000, + 0x000000, 0x000000, 0x270002, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x270201, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x270305, 0x270801, 0x000000, 0x000000, 0x270903, 0x000000, 0x000000, + 0x000000, 0x270c07, 0x000000, 0x271303, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x27160c, 0x272201, 0x272302, 0x272509, 0x000000, 0x000000, 0x000000, + 0x272e01, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x272f02, 0x000000, + 0x000000, 0x273102, 0x000000, 0x273302, 0x000000, 0x000000, 0x000000, 0x000000, + 0x273501, 0x000000, 0x273601, 0x273701, 0x273801, 0x273901, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x273a02, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x273c09, 0x274501, 0x000000, 0x000000, 0x000000, 0x000000, 0x274602, + 0x000000, 0x000000, 0x274801, 0x274901, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x274a01, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x274b03, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x274e03, 0x000000, 0x275104, 0x000000, 0x000000, 0x000000, + 0x275502, 0x000000, 0x275704, 0x000000, 0x000000, 0x275b01, 0x275c07, 0x000000, + 0x000000, 0x276303, 0x000000, 0x276603, 0x276901, 0x276a03, 0x000000, 0x000000, + 0x000000, 0x276d03, 0x277001, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x277105, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x277601, 0x000000, 0x277704, 0x000000, 0x277b0c, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x278702, 0x000000, 0x000000, + 0x000000, 0x278903, 0x000000, 0x000000, 0x278c02, 0x000000, 0x000000, 0x000000, + 0x000000, 0x278e01, 0x278f06, 0x000000, 0x000000, 0x279501, 0x000000, 0x279601, + 0x279701, 0x000000, 0x27980a, 0x000000, 0x000000, 0x27a202, 0x000000, 0x27a401, + 0x27a506, 0x000000, 0x000000, 0x27ab02, 0x000000, 0x27ad01, 0x27ae01, 0x27af08, + 0x27b703, 0x000000, 0x000000, 0x27ba02, 0x000000, 0x27bc03, 0x000000, 0x000000, + 0x000000, 0x27bf01, 0x000000, 0x000000, 0x000000, 0x000000, 0x27c001, 0x000000, + 0x000000, 0x000000, 0x000000, 0x27c110, 0x000000, 0x000000, 0x000000, 0x000000, + 0x27d108, 0x000000, 0x27d901, 0x000000, 0x000000, 0x27da01, 0x27db01, 0x000000, + 0x27dc01, 0x27dd01, 0x000000, 0x27de02, 0x000000, 0x000000, 0x000000, 0x000000, + 0x27e004, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x27e404, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x27e80c, + 0x000000, 0x27f401, 0x000000, 0x27f501, 0x27f601, 0x000000, 0x000000, 0x27f705, + 0x000000, 0x000000, 0x27fc01, 0x27fd06, 0x280306, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x280902, 0x000000, 0x280b03, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x280e02, 0x000000, 0x000000, 0x281001, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x281101, 0x000000, 0x281201, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x281318, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x282b04, 0x282f01, 0x283001, 0x000000, 0x000000, 0x000000, 0x283106, 0x000000, + 0x283701, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x283801, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x283901, 0x000000, 0x000000, + 0x000000, 0x000000, 0x283a04, 0x283e03, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x284101, 0x000000, 0x000000, 0x000000, 0x284201, 0x000000, 0x284303, + 0x000000, 0x000000, 0x000000, 0x000000, 0x284604, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x284a02, 0x284c01, 0x000000, 0x000000, + 0x000000, 0x284d01, 0x284e02, 0x000000, 0x285005, 0x000000, 0x285502, 0x000000, + 0x285701, 0x000000, 0x000000, 0x000000, 0x000000, 0x285802, 0x000000, 0x000000, + 0x285a01, 0x000000, 0x285b02, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x285d01, 0x000000, 0x000000, 0x285e03, 0x286101, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x28620a, 0x286c02, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x286e02, 0x000000, 0x287009, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x287906, 0x000000, 0x287f01, 0x000000, + 0x288003, 0x000000, 0x000000, 0x000000, 0x288301, 0x288401, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x288501, 0x000000, 0x000000, 0x000000, 0x288601, + 0x000000, 0x28870a, 0x000000, 0x000000, 0x289102, 0x289302, 0x289501, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x289601, 0x000000, + 0x000000, 0x289702, 0x289902, 0x000000, 0x000000, 0x289b01, 0x000000, 0x289c06, + 0x000000, 0x28a201, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x28a301, 0x000000, 0x28a405, 0x28a901, 0x000000, 0x000000, + 0x28aa01, 0x000000, 0x28ab09, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x28b401, 0x28b501, 0x28b602, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x28b802, 0x000000, + 0x000000, 0x28ba03, 0x000000, 0x000000, 0x28bd02, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x28bf01, 0x000000, 0x28c001, 0x28c102, 0x000000, 0x000000, + 0x000000, 0x000000, 0x28c301, 0x28c401, 0x000000, 0x28c501, 0x000000, 0x28c605, + 0x000000, 0x28cb02, 0x28cd02, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x28cf01, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x28d002, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x28d202, 0x000000, + 0x28d401, 0x000000, 0x000000, 0x000000, 0x28d503, 0x28d802, 0x000000, 0x000000, + 0x28da0a, 0x000000, 0x28e403, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x28e709, 0x28f001, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x28f101, + 0x28f209, 0x000000, 0x28fb07, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x290203, 0x000000, 0x000000, + 0x000000, 0x290508, 0x000000, 0x000000, 0x290d0b, 0x000000, 0x291803, 0x291b01, + 0x000000, 0x000000, 0x291c01, 0x291d02, 0x291f02, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x292103, 0x000000, 0x000000, + 0x000000, 0x000000, 0x292401, 0x000000, 0x292501, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x292601, + 0x292708, 0x000000, 0x000000, 0x292f09, 0x000000, 0x293803, 0x293b01, 0x000000, + 0x293c02, 0x293e03, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x294101, + 0x294201, 0x294301, 0x000000, 0x294401, 0x000000, 0x000000, 0x000000, 0x294501, + 0x000000, 0x294608, 0x000000, 0x000000, 0x000000, 0x000000, 0x294e01, 0x000000, + 0x000000, 0x294f02, 0x000000, 0x295107, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x295801, 0x295901, + 0x295a02, 0x295c01, 0x000000, 0x295d04, 0x000000, 0x000000, 0x296104, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x296503, 0x000000, 0x000000, 0x296801, + 0x000000, 0x000000, 0x000000, 0x296901, 0x000000, 0x296a01, 0x000000, 0x296b01, + 0x000000, 0x296c02, 0x000000, 0x000000, 0x296e13, 0x000000, 0x298101, 0x000000, + 0x298202, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x298401, 0x298501, + 0x29860f, 0x000000, 0x000000, 0x000000, 0x299501, 0x000000, 0x000000, 0x000000, + 0x299603, 0x000000, 0x299901, 0x000000, 0x299a01, 0x000000, 0x000000, 0x000000, + 0x299b01, 0x299c02, 0x299e03, 0x000000, 0x29a101, 0x000000, 0x000000, 0x29a208, + 0x000000, 0x29aa02, 0x000000, 0x000000, 0x000000, 0x000000, 0x29ac01, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x29ad01, 0x000000, 0x000000, 0x000000, 0x29ae01, 0x000000, 0x000000, 0x000000, + 0x000000, 0x29af01, 0x29b001, 0x000000, 0x29b102, 0x000000, 0x000000, 0x000000, + 0x29b302, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x29b504, + 0x000000, 0x29b90a, 0x000000, 0x000000, 0x29c305, 0x000000, 0x29c801, 0x000000, + 0x000000, 0x000000, 0x000000, 0x29c902, 0x000000, 0x000000, 0x000000, 0x29cb03, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x29ce01, 0x000000, 0x29cf01, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x29d00a, + 0x000000, 0x29da03, 0x29dd02, 0x29df02, 0x000000, 0x000000, 0x29e101, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x29e203, + 0x000000, 0x000000, 0x000000, 0x000000, 0x29e501, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x29e603, 0x29e90d, 0x29f601, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x29f701, 0x000000, 0x000000, 0x29f803, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x29fb02, 0x000000, 0x000000, + 0x000000, 0x000000, 0x29fd02, 0x000000, 0x000000, 0x29ff01, 0x2a0003, 0x000000, + 0x000000, 0x000000, 0x2a0302, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x2a0501, 0x000000, 0x000000, 0x000000, 0x2a060a, 0x000000, 0x2a1003, + 0x000000, 0x000000, 0x2a1301, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x2a1404, 0x000000, 0x000000, 0x000000, 0x2a1802, 0x000000, 0x000000, + 0x2a1a01, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x2a1b04, 0x2a1f05, 0x000000, 0x000000, 0x000000, 0x2a2402, 0x000000, + 0x000000, 0x000000, 0x2a2604, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x2a2a01, 0x000000, 0x000000, 0x2a2b0c, + 0x000000, 0x2a3701, 0x000000, 0x2a3801, 0x000000, 0x000000, 0x000000, 0x2a3902, + 0x000000, 0x000000, 0x000000, 0x2a3b02, 0x000000, 0x000000, 0x2a3d01, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x2a3e01, 0x000000, 0x000000, 0x000000, 0x000000, 0x2a3f01, 0x2a4002, 0x000000, + 0x000000, 0x000000, 0x000000, 0x2a4201, 0x000000, 0x2a4301, 0x000000, 0x000000, + 0x000000, 0x000000, 0x2a4401, 0x2a4501, 0x2a4603, 0x000000, 0x2a4917, 0x2a6001, + 0x000000, 0x000000, 0x000000, 0x000000, 0x2a6102, 0x000000, 0x000000, 0x2a6301, + 0x000000, 0x2a6403, 0x000000, 0x000000, 0x2a6701, 0x000000, 0x000000, 0x2a6801, + 0x2a6901, 0x2a6a01, 0x2a6b03, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x2a6e03, 0x000000, 0x2a7101, 0x2a7205, 0x2a7712, 0x2a8901, 0x000000, + 0x000000, 0x2a8a01, 0x2a8b01, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x2a8c03, 0x000000, 0x000000, 0x000000, 0x2a8f03, 0x2a9201, 0x000000, 0x000000, + 0x2a9302, 0x2a9501, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x2a9602, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x2a9801, 0x000000, 0x2a9902, 0x000000, + 0x000000, 0x000000, 0x000000, 0x2a9b03, 0x2a9e01, 0x000000, 0x2a9f04, 0x000000, + 0x000000, 0x2aa301, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x2aa401, + 0x000000, 0x2aa505, 0x000000, 0x000000, 0x000000, 0x2aaa01, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x2aab04, 0x000000, 0x000000, 0x2aaf01, 0x2ab001, + 0x000000, 0x000000, 0x2ab102, 0x000000, 0x000000, 0x000000, 0x2ab307, 0x000000, + 0x000000, 0x000000, 0x000000, 0x2aba06, 0x000000, 0x000000, 0x2ac002, 0x000000, + 0x000000, 0x000000, 0x2ac201, 0x000000, 0x000000, 0x2ac30a, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x2acd02, 0x000000, 0x2acf02, 0x2ad102, 0x000000, 0x000000, + 0x2ad302, 0x000000, 0x000000, 0x000000, 0x2ad501, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x2ad601, + 0x000000, 0x000000, 0x000000, 0x2ad705, 0x000000, 0x000000, 0x000000, 0x2adc02, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x2ade01, 0x000000, 0x000000, + 0x000000, 0x2adf02, 0x2ae104, 0x000000, 0x000000, 0x2ae502, 0x2ae703, 0x2aea01, + 0x000000, 0x000000, 0x2aeb01, 0x000000, 0x2aec02, 0x000000, 0x000000, 0x2aee01, + 0x000000, 0x000000, 0x000000, 0x000000, 0x2aef01, 0x000000, 0x000000, 0x000000, + 0x2af002, 0x000000, 0x2af201, 0x000000, 0x000000, 0x000000, 0x2af301, 0x2af401, + 0x000000, 0x000000, 0x000000, 0x2af501, 0x000000, 0x2af602, 0x000000, 0x2af809, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x2b0102, 0x2b0301, + 0x000000, 0x2b0403, 0x2b0701, 0x2b0802, 0x000000, 0x000000, 0x2b0a01, 0x2b0b01, + 0x2b0c01, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x2b0d01, 0x000000, 0x000000, + 0x2b0e06, 0x2b1402, 0x000000, 0x000000, 0x000000, 0x000000, 0x2b1603, 0x000000, + 0x000000, 0x000000, 0x2b1915, 0x000000, 0x000000, 0x000000, 0x000000, 0x2b2e01, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x2b2f04, 0x2b3301, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x2b3403, 0x000000, 0x000000, + 0x2b3701, 0x2b3801, 0x000000, 0x2b3903, 0x000000, 0x2b3c10, 0x000000, 0x2b4c01, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x2b4d02, 0x000000, 0x000000, + 0x000000, 0x2b4f06, 0x000000, 0x000000, 0x000000, 0x2b5501, 0x000000, 0x000000, + 0x000000, 0x2b5601, 0x2b5701, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x2b5801, 0x2b5901, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x2b5a03, 0x000000, 0x000000, 0x2b5d06, 0x2b6301, 0x000000, 0x000000, + 0x000000, 0x2b6405, 0x000000, 0x2b6905, 0x2b6e0c, 0x000000, 0x2b7a0b, 0x000000, + 0x000000, 0x000000, 0x2b8501, 0x000000, 0x000000, 0x2b8603, 0x000000, 0x2b8901, + 0x000000, 0x2b8a01, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x2b8b01, 0x000000, 0x2b8c03, 0x2b8f01, 0x2b9001, 0x2b9102, 0x000000, + 0x2b9301, 0x000000, 0x2b9401, 0x000000, 0x000000, 0x000000, 0x2b9501, 0x000000, + 0x000000, 0x2b9601, 0x2b9703, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x2b9a01, + 0x000000, 0x000000, 0x2b9b02, 0x2b9d06, 0x000000, 0x000000, 0x000000, 0x2ba302, + 0x2ba502, 0x000000, 0x000000, 0x000000, 0x2ba706, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x2bad01, 0x2bae01, 0x000000, 0x000000, 0x000000, 0x2baf03, + 0x2bb201, 0x000000, 0x000000, 0x2bb301, 0x2bb405, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x2bb906, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x2bbf02, 0x2bc101, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x2bc201, 0x000000, 0x2bc301, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x2bc401, 0x000000, 0x000000, 0x000000, 0x2bc501, + 0x000000, 0x2bc602, 0x000000, 0x000000, 0x2bc802, 0x000000, 0x2bca03, 0x000000, + 0x2bcd11, 0x000000, 0x000000, 0x2bde3e, 0x000000, 0x000000, 0x000000, 0x2c1c02, + 0x2c1e01, 0x000000, 0x000000, 0x2c1f01, 0x2c2005, 0x2c2505, 0x000000, 0x000000, + 0x000000, 0x2c2a02, 0x000000, 0x000000, 0x000000, 0x000000, 0x2c2c01, 0x2c2d01, + 0x000000, 0x2c2e02, 0x000000, 0x000000, 0x000000, 0x2c3001, 0x000000, 0x2c3114, + 0x000000, 0x000000, 0x000000, 0x000000, 0x2c4504, 0x000000, 0x2c4901, 0x000000, + 0x000000, 0x000000, 0x2c4a01, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x2c4b01, 0x000000, 0x2c4c01, 0x2c4d02, 0x000000, 0x2c4f01, 0x000000, 0x2c5003, + 0x000000, 0x000000, 0x000000, 0x2c5301, 0x2c5401, 0x000000, 0x000000, 0x2c5505, + 0x000000, 0x000000, 0x000000, 0x2c5a01, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x2c5b01, 0x000000, 0x2c5c0d, 0x2c6901, 0x000000, 0x000000, + 0x2c6a03, 0x000000, 0x2c6d02, 0x2c6f01, 0x000000, 0x000000, 0x000000, 0x2c7001, + 0x000000, 0x000000, 0x2c7105, 0x2c7603, 0x000000, 0x2c790d, 0x2c8601, 0x000000, + 0x2c8706, 0x2c8d02, 0x000000, 0x000000, 0x000000, 0x2c8f01, 0x000000, 0x000000, + 0x2c9003, 0x2c9305, 0x000000, 0x000000, 0x000000, 0x000000, 0x2c9801, 0x000000, + 0x000000, 0x000000, 0x2c9903, 0x000000, 0x2c9c05, 0x000000, 0x2ca103, 0x2ca401, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x2ca507, 0x000000, 0x2cac01, + 0x000000, 0x2cad02, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x2caf0d, + 0x2cbc01, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x2cbd01, + 0x000000, 0x000000, 0x000000, 0x000000, 0x2cbe01, 0x000000, 0x000000, 0x2cbf04, + 0x2cc301, 0x2cc402, 0x2cc606, 0x000000, 0x2ccc04, 0x000000, 0x2cd001, 0x000000, + 0x000000, 0x000000, 0x000000, 0x2cd101, 0x000000, 0x000000, 0x000000, 0x2cd201, + 0x000000, 0x2cd301, 0x2cd403, 0x2cd701, 0x000000, 0x000000, 0x000000, 0x000000, + 0x2cd803, 0x000000, 0x000000, 0x2cdb03, 0x000000, 0x000000, 0x2cde0a, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x2ce805, 0x000000, 0x000000, 0x2ced07, 0x000000, 0x2cf401, 0x000000, + 0x000000, 0x2cf501, 0x2cf602, 0x2cf802, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x2cfa01, 0x000000, + 0x000000, 0x000000, 0x000000, 0x2cfb04, 0x000000, 0x2cff01, 0x2d0008, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x2d0801, 0x2d0901, 0x2d0a03, 0x2d0d09, 0x000000, 0x000000, + 0x2d1604, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x2d1a01, 0x000000, + 0x2d1b04, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x2d1f04, 0x2d2301, + 0x000000, 0x2d2402, 0x000000, 0x000000, 0x2d2601, 0x000000, 0x2d2701, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x2d2802, 0x000000, 0x000000, + 0x2d2a01, 0x2d2b01, 0x000000, 0x2d2c02, 0x000000, 0x000000, 0x000000, 0x000000, + 0x2d2e02, 0x000000, 0x000000, 0x000000, 0x2d3005, 0x000000, 0x2d3501, 0x000000, + 0x2d3602, 0x000000, 0x000000, 0x000000, 0x2d3801, 0x000000, 0x2d3902, 0x000000, + 0x000000, 0x000000, 0x2d3b01, 0x2d3c01, 0x000000, 0x000000, 0x000000, 0x2d3d02, + 0x2d3f03, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x2d4201, 0x000000, 0x2d4303, 0x2d4604, 0x000000, 0x2d4a01, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x2d4b01, 0x000000, + 0x2d4c01, 0x000000, 0x000000, 0x000000, 0x000000, 0x2d4d03, 0x2d5001, 0x000000, + 0x000000, 0x000000, 0x2d5101, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x2d5201, 0x2d5302, 0x000000, + 0x2d5502, 0x000000, 0x000000, 0x2d5702, 0x000000, 0x000000, 0x000000, 0x000000, + 0x2d5901, 0x000000, 0x000000, 0x2d5a02, 0x000000, 0x000000, 0x000000, 0x000000, + 0x2d5c09, 0x000000, 0x2d6501, 0x000000, 0x000000, 0x000000, 0x2d6602, 0x000000, + 0x000000, 0x000000, 0x000000, 0x2d6801, 0x000000, 0x000000, 0x2d6901, 0x2d6a01, + 0x2d6b02, 0x2d6d09, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x2d7607, 0x000000, 0x000000, 0x2d7d02, 0x000000, 0x2d7f01, 0x2d8001, 0x000000, + 0x2d8101, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x2d8201, 0x000000, 0x000000, 0x2d8301, 0x2d8403, 0x2d8715, + 0x000000, 0x000000, 0x2d9c02, 0x2d9e01, 0x000000, 0x000000, 0x000000, 0x000000, + 0x2d9f01, 0x000000, 0x000000, 0x2da004, 0x000000, 0x2da403, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x2da71c, 0x000000, + 0x000000, 0x000000, 0x2dc303, 0x000000, 0x2dc602, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x2dc803, 0x000000, 0x000000, 0x2dcb13, 0x2dde02, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x2de003, + 0x2de302, 0x2de501, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x2de601, + 0x000000, 0x000000, 0x000000, 0x2de702, 0x2de901, 0x000000, 0x2dea04, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x2dee01, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x2def01, 0x000000, 0x000000, + 0x000000, 0x2df005, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x2df501, 0x2df605, 0x000000, 0x2dfb01, 0x2dfc01, 0x000000, 0x2dfd01, 0x000000, + 0x000000, 0x2dfe02, 0x000000, 0x2e0001, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x2e0102, + 0x2e0303, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x2e0601, 0x000000, 0x2e0701, 0x000000, 0x000000, 0x000000, 0x2e0801, 0x000000, + 0x000000, 0x000000, 0x2e0902, 0x000000, 0x000000, 0x000000, 0x000000, 0x2e0b01, + 0x000000, 0x000000, 0x2e0c02, 0x2e0e01, 0x2e0f03, 0x000000, 0x000000, 0x000000, + 0x000000, 0x2e1227, 0x2e3901, 0x2e3a01, 0x2e3b01, 0x000000, 0x000000, 0x2e3c01, + 0x000000, 0x000000, 0x000000, 0x2e3d08, 0x000000, 0x000000, 0x2e4505, 0x2e4a01, + 0x000000, 0x2e4b11, 0x000000, 0x2e5c02, 0x000000, 0x000000, 0x000000, 0x2e5e01, + 0x000000, 0x000000, 0x000000, 0x2e5f02, 0x2e6101, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x2e6201, 0x000000, 0x2e6301, 0x2e6406, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x2e6a01, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x2e6b01, 0x000000, 0x2e6c01, 0x000000, 0x2e6d01, 0x000000, 0x000000, + 0x2e6e07, 0x000000, 0x2e7501, 0x2e7602, 0x2e780c, 0x2e8401, 0x2e8502, 0x000000, + 0x2e8706, 0x2e8d02, 0x000000, 0x000000, 0x2e8f02, 0x000000, 0x2e9102, 0x2e9303, + 0x2e9601, 0x2e9701, 0x000000, 0x000000, 0x000000, 0x000000, 0x2e9805, 0x000000, + 0x2e9d07, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x2ea402, 0x2ea601, + 0x2ea701, 0x000000, 0x2ea803, 0x000000, 0x000000, 0x000000, 0x000000, 0x2eab01, + 0x2eac04, 0x000000, 0x000000, 0x000000, 0x000000, 0x2eb001, 0x000000, 0x2eb101, + 0x000000, 0x2eb201, 0x000000, 0x2eb301, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x2eb402, 0x000000, 0x000000, 0x2eb602, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x2eb811, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x2ec901, 0x000000, 0x000000, 0x000000, 0x2eca01, + 0x2ecb06, 0x2ed101, 0x2ed205, 0x000000, 0x2ed701, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x2ed801, 0x000000, 0x000000, 0x000000, 0x2ed905, 0x000000, + 0x2ede05, 0x2ee301, 0x2ee401, 0x2ee505, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x2eea01, 0x000000, 0x000000, 0x2eeb02, 0x2eed01, 0x000000, 0x000000, + 0x2eee04, 0x000000, 0x000000, 0x2ef209, 0x2efb01, 0x000000, 0x000000, 0x2efc03, + 0x000000, 0x000000, 0x2eff01, 0x2f0001, 0x000000, 0x000000, 0x000000, 0x000000, + 0x2f0107, 0x000000, 0x2f0802, 0x2f0a01, 0x000000, 0x000000, 0x2f0b02, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x2f0d08, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x2f1501, 0x2f1601, + 0x000000, 0x2f1704, 0x000000, 0x000000, 0x000000, 0x2f1b04, 0x2f1f01, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x2f2002, 0x2f2201, 0x2f2306, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x2f2901, + 0x000000, 0x000000, 0x000000, 0x2f2a01, 0x2f2b03, 0x000000, 0x000000, 0x000000, + 0x2f2e02, 0x000000, 0x2f3005, 0x2f3501, 0x2f3601, 0x000000, 0x000000, 0x2f3701, + 0x000000, 0x000000, 0x000000, 0x000000, 0x2f3803, 0x000000, 0x2f3b05, 0x000000, + 0x000000, 0x000000, 0x000000, 0x2f4001, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x2f4104, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x2f4501, 0x2f4601, 0x2f4707, 0x2f4e03, 0x000000, 0x000000, + 0x2f5102, 0x2f5302, 0x000000, 0x000000, 0x000000, 0x2f5501, 0x000000, 0x000000, + 0x000000, 0x2f5601, 0x2f5708, 0x2f5f02, 0x000000, 0x000000, 0x000000, 0x000000, + 0x2f6101, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x2f6201, + 0x000000, 0x000000, 0x000000, 0x2f6302, 0x2f6503, 0x000000, 0x000000, 0x000000, + 0x000000, 0x2f6802, 0x000000, 0x2f6a02, 0x000000, 0x2f6c01, 0x000000, 0x000000, + 0x2f6d02, 0x000000, 0x000000, 0x000000, 0x2f6f01, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x2f7003, 0x000000, 0x2f7305, 0x000000, 0x2f7801, 0x000000, + 0x000000, 0x000000, 0x000000, 0x2f7911, 0x2f8a02, 0x2f8c02, 0x000000, 0x000000, + 0x000000, 0x2f8e03, 0x000000, 0x000000, 0x000000, 0x000000, 0x2f9105, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x2f9601, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x2f9702, + 0x000000, 0x000000, 0x000000, 0x2f9901, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x2f9a01, 0x2f9b01, 0x000000, 0x000000, 0x2f9c07, 0x000000, 0x2fa301, + 0x000000, 0x2fa401, 0x000000, 0x000000, 0x2fa503, 0x000000, 0x2fa802, 0x000000, + 0x000000, 0x000000, 0x000000, 0x2faa06, 0x000000, 0x2fb001, 0x000000, 0x000000, + 0x000000, 0x000000, 0x2fb101, 0x2fb201, 0x2fb301, 0x2fb404, 0x000000, 0x2fb801, + 0x2fb904, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x2fbd01, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x2fbe06, 0x000000, 0x000000, 0x2fc404, 0x000000, 0x000000, + 0x000000, 0x000000, 0x2fc801, 0x000000, 0x000000, 0x000000, 0x000000, 0x2fc902, + 0x000000, 0x000000, 0x2fcb06, 0x2fd101, 0x000000, 0x000000, 0x000000, 0x2fd201, + 0x000000, 0x000000, 0x000000, 0x2fd309, 0x2fdc01, 0x000000, 0x2fdd02, 0x2fdf01, + 0x000000, 0x2fe012, 0x000000, 0x000000, 0x2ff202, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x2ff401, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x2ff50b, 0x000000, 0x300001, 0x000000, 0x000000, 0x300102, 0x000000, 0x300301, + 0x300401, 0x000000, 0x000000, 0x300501, 0x000000, 0x300601, 0x000000, 0x000000, + 0x300701, 0x000000, 0x300801, 0x000000, 0x300903, 0x000000, 0x000000, 0x000000, + 0x000000, 0x300c08, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x30141d, + 0x000000, 0x303102, 0x303301, 0x000000, 0x000000, 0x000000, 0x000000, 0x303401, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x303501, 0x303601, 0x000000, 0x303701, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x303801, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x303902, 0x000000, + 0x000000, 0x000000, 0x000000, 0x303b02, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x303d01, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x303e04, 0x000000, 0x304201, 0x304301, 0x30440a, 0x000000, 0x000000, 0x304e03, + 0x305101, 0x305201, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x305304, + 0x305703, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x305a03, 0x000000, 0x305d01, 0x000000, 0x305e01, 0x000000, 0x000000, + 0x305f09, 0x000000, 0x000000, 0x000000, 0x000000, 0x306801, 0x000000, 0x000000, + 0x306904, 0x000000, 0x000000, 0x000000, 0x000000, 0x306d05, 0x307201, 0x000000, + 0x000000, 0x307306, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x307901, + 0x000000, 0x000000, 0x000000, 0x307a01, 0x000000, 0x000000, 0x000000, 0x307b08, + 0x000000, 0x000000, 0x000000, 0x000000, 0x308301, 0x000000, 0x308402, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x308602, 0x000000, 0x308804, 0x308c02, + 0x000000, 0x000000, 0x000000, 0x308e01, 0x308f02, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x309101, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x309201, + 0x309301, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x309401, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x309507, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x309c05, 0x000000, 0x000000, 0x000000, 0x30a101, 0x30a201, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x30a317, 0x30ba12, + 0x000000, 0x000000, 0x30cc01, 0x30cd01, 0x000000, 0x000000, 0x000000, 0x30ce01, + 0x000000, 0x000000, 0x000000, 0x000000, 0x30cf06, 0x30d507, 0x30dc01, 0x000000, + 0x000000, 0x000000, 0x000000, 0x30dd02, 0x000000, 0x30df01, 0x30e001, 0x000000, + 0x000000, 0x000000, 0x000000, 0x30e101, 0x000000, 0x000000, 0x000000, 0x30e205, + 0x000000, 0x30e704, 0x000000, 0x000000, 0x000000, 0x30eb03, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x30ee01, 0x000000, + 0x000000, 0x000000, 0x30ef01, 0x000000, 0x000000, 0x000000, 0x30f001, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x30f105, 0x000000, 0x30f601, 0x000000, + 0x000000, 0x30f702, 0x000000, 0x30f902, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x30fb08, 0x000000, 0x310302, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x310501, 0x000000, 0x000000, 0x000000, 0x310601, 0x310702, 0x000000, 0x000000, + 0x000000, 0x310901, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x310a07, 0x000000, 0x000000, 0x311103, 0x000000, 0x311401, + 0x000000, 0x311503, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x311802, 0x000000, + 0x000000, 0x000000, 0x311a03, 0x311d03, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x312001, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x312101, 0x312218, 0x313a05, 0x000000, 0x313f03, + 0x000000, 0x000000, 0x314201, 0x000000, 0x314303, 0x000000, 0x31460a, 0x000000, + 0x315002, 0x000000, 0x000000, 0x000000, 0x000000, 0x315213, 0x316502, 0x000000, + 0x316709, 0x000000, 0x000000, 0x31700d, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x317d01, 0x000000, 0x000000, 0x317e02, 0x000000, 0x318004, + 0x318402, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x318602, 0x000000, 0x318801, 0x000000, + 0x31890b, 0x319401, 0x000000, 0x319503, 0x000000, 0x319804, 0x000000, 0x319c02, + 0x000000, 0x000000, 0x000000, 0x319e01, 0x319f03, 0x000000, 0x000000, 0x000000, + 0x000000, 0x31a21e, 0x31c002, 0x000000, 0x000000, 0x31c201, 0x000000, 0x000000, + 0x31c302, 0x000000, 0x000000, 0x31c501, 0x31c602, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x31c801, 0x000000, + 0x31c901, 0x31ca01, 0x000000, 0x31cb0b, 0x000000, 0x000000, 0x31d608, 0x31de06, + 0x000000, 0x000000, 0x000000, 0x000000, 0x31e401, 0x000000, 0x31e504, 0x31e901, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x31ea01, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x31eb0d, 0x31f81f, 0x000000, + 0x321701, 0x000000, 0x32180b, 0x000000, 0x322303, 0x000000, 0x000000, 0x000000, + 0x000000, 0x322603, 0x000000, 0x322901, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x322a02, 0x322c01, 0x000000, 0x322d01, 0x000000, 0x000000, 0x000000, 0x000000, + 0x322e03, 0x000000, 0x000000, 0x323102, 0x323301, 0x323401, 0x000000, 0x000000, + 0x000000, 0x323501, 0x000000, 0x000000, 0x000000, 0x323601, 0x000000, 0x323702, + 0x000000, 0x323901, 0x000000, 0x000000, 0x323a03, 0x000000, 0x323d01, 0x000000, + 0x323e03, 0x000000, 0x000000, 0x324103, 0x000000, 0x324403, 0x324701, 0x324802, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x324a02, 0x000000, 0x324c01, 0x000000, 0x000000, 0x324d06, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x325301, 0x325403, 0x325701, 0x000000, 0x325804, 0x000000, 0x000000, 0x000000, + 0x000000, 0x325c02, 0x000000, 0x000000, 0x000000, 0x325e01, 0x325f02, 0x326104, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x326507, + 0x000000, 0x326c01, 0x326d10, 0x000000, 0x327d02, 0x000000, 0x327f01, 0x000000, + 0x000000, 0x000000, 0x328001, 0x000000, 0x328101, 0x000000, 0x000000, 0x000000, + 0x000000, 0x328201, 0x000000, 0x328301, 0x328401, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x328508, 0x000000, 0x328d02, + 0x000000, 0x000000, 0x000000, 0x000000, 0x328f02, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x329102, 0x000000, 0x000000, + 0x329301, 0x000000, 0x000000, 0x329401, 0x000000, 0x000000, 0x000000, 0x000000, + 0x329501, 0x000000, 0x000000, 0x000000, 0x000000, 0x329601, 0x000000, 0x329701, + 0x000000, 0x329801, 0x000000, 0x000000, 0x000000, 0x329904, 0x329d01, 0x329e01, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x329f04, 0x32a302, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x32a504, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x32a901, 0x000000, 0x32aa01, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x32ab0a, 0x000000, + 0x000000, 0x32b502, 0x000000, 0x000000, 0x000000, 0x32b701, 0x32b801, 0x000000, + 0x32b90a, 0x32c301, 0x32c404, 0x32c801, 0x32c902, 0x000000, 0x000000, 0x000000, + 0x000000, 0x32cb01, 0x000000, 0x000000, 0x32cc02, 0x000000, 0x000000, 0x32ce02, + 0x32d008, 0x000000, 0x32d803, 0x000000, 0x000000, 0x000000, 0x32db01, 0x000000, + 0x32dc01, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x32dd02, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x32df03, 0x32e201, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x32e301, 0x000000, 0x000000, 0x32e403, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x32e705, 0x000000, + 0x32ec03, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x32ef01, + 0x000000, 0x000000, 0x32f002, 0x000000, 0x000000, 0x000000, 0x32f201, 0x32f302, + 0x32f501, 0x000000, 0x000000, 0x000000, 0x000000, 0x32f602, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x32f805, 0x32fd02, 0x000000, + 0x32ff04, 0x000000, 0x000000, 0x330301, 0x330406, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x330a01, 0x000000, 0x000000, 0x330b03, 0x000000, 0x330e06, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x331401, 0x331501, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x331601, 0x331701, 0x331801, 0x000000, + 0x331903, 0x000000, 0x000000, 0x000000, 0x331c01, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x331d01, 0x000000, 0x331e01, 0x331f06, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x332505, 0x000000, 0x332a01, + 0x000000, 0x332b01, 0x000000, 0x000000, 0x000000, 0x332c18, 0x000000, 0x334401, + 0x334502, 0x334701, 0x334801, 0x000000, 0x000000, 0x334901, 0x000000, 0x334a03, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x334d10, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x335d12, 0x000000, 0x336f01, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x337001, 0x000000, + 0x000000, 0x337104, 0x000000, 0x000000, 0x000000, 0x000000, 0x337502, 0x000000, + 0x000000, 0x000000, 0x337701, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x337801, 0x000000, 0x337905, 0x337e04, 0x338202, 0x000000, 0x000000, 0x000000, + 0x338401, 0x000000, 0x000000, 0x338501, 0x000000, 0x000000, 0x33860f, 0x000000, + 0x000000, 0x339501, 0x000000, 0x000000, 0x000000, 0x339605, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x339b07, 0x000000, 0x000000, 0x33a20d, 0x33af09, 0x000000, 0x000000, 0x000000, + 0x33b808, 0x000000, 0x33c004, 0x33c402, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x33c604, 0x33ca01, 0x000000, 0x33cb01, 0x33cc01, 0x000000, 0x33cd0a, + 0x000000, 0x33d704, 0x000000, 0x000000, 0x000000, 0x000000, 0x33db01, 0x000000, + 0x000000, 0x000000, 0x000000, 0x33dc16, 0x33f202, 0x000000, 0x000000, 0x33f401, + 0x33f501, 0x000000, 0x000000, 0x33f602, 0x000000, 0x000000, 0x33f805, 0x000000, + 0x33fd01, 0x000000, 0x000000, 0x000000, 0x33fe0e, 0x000000, 0x000000, 0x000000, + 0x000000, 0x340c03, 0x000000, 0x340f01, 0x000000, 0x000000, 0x000000, 0x341001, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x341101, 0x000000, + 0x000000, 0x341204, 0x000000, 0x341607, 0x000000, 0x000000, 0x341d01, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x341e0b, 0x000000, 0x342908, 0x000000, + 0x343104, 0x000000, 0x343501, 0x343602, 0x343802, 0x000000, 0x000000, 0x343a01, + 0x343b01, 0x000000, 0x343c01, 0x343d02, 0x000000, 0x343f04, 0x000000, 0x344301, + 0x344405, 0x344901, 0x000000, 0x344a01, 0x344b01, 0x000000, 0x344c02, 0x344e04, + 0x345206, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x345808, 0x346001, + 0x000000, 0x34610a, 0x000000, 0x000000, 0x000000, 0x000000, 0x346b02, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x346d01, 0x000000, 0x000000, 0x000000, + 0x000000, 0x346e02, 0x000000, 0x000000, 0x000000, 0x000000, 0x347002, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x347201, 0x000000, 0x000000, 0x000000, + 0x347302, 0x000000, 0x000000, 0x347508, 0x347d01, 0x000000, 0x347e06, 0x000000, + 0x348403, 0x000000, 0x348701, 0x348802, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x348a06, 0x000000, 0x349001, 0x000000, 0x000000, 0x000000, + 0x000000, 0x349101, 0x349201, 0x000000, 0x349304, 0x000000, 0x000000, 0x000000, + 0x000000, 0x349701, 0x349801, 0x349904, 0x349d01, 0x000000, 0x349e01, 0x349f02, + 0x34a101, 0x34a201, 0x000000, 0x34a302, 0x000000, 0x000000, 0x34a501, 0x34a602, + 0x000000, 0x34a806, 0x000000, 0x000000, 0x000000, 0x000000, 0x34ae03, 0x000000, + 0x34b103, 0x000000, 0x34b401, 0x000000, 0x000000, 0x34b501, 0x000000, 0x000000, + 0x34b601, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x34b701, + 0x34b803, 0x000000, 0x34bb10, 0x000000, 0x000000, 0x34cb06, 0x34d103, 0x000000, + 0x000000, 0x34d403, 0x34d702, 0x000000, 0x000000, 0x000000, 0x34d905, 0x34de02, + 0x000000, 0x34e002, 0x34e201, 0x000000, 0x34e303, 0x000000, 0x34e601, 0x000000, + 0x34e701, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x34e802, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x34ea02, 0x000000, + 0x000000, 0x000000, 0x34ec06, 0x34f201, 0x000000, 0x000000, 0x000000, 0x34f301, + 0x34f401, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x34f505, 0x000000, 0x34fa01, 0x000000, 0x000000, 0x000000, 0x000000, 0x34fb02, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x34fd03, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x350002, + 0x000000, 0x000000, 0x350202, 0x000000, 0x000000, 0x000000, 0x000000, 0x350405, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x350903, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x350c05, 0x000000, 0x351109, 0x000000, 0x351a05, 0x000000, 0x351f01, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x352002, 0x352201, 0x000000, 0x352301, 0x352401, 0x352501, 0x35260a, 0x000000, + 0x000000, 0x353001, 0x353105, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x353602, 0x000000, 0x353802, 0x353a02, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x353c05, 0x000000, + 0x000000, 0x000000, 0x354104, 0x000000, 0x000000, 0x000000, 0x354510, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x355502, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x355703, 0x000000, 0x355a01, 0x000000, 0x000000, 0x355b02, + 0x000000, 0x000000, 0x355d01, 0x000000, 0x000000, 0x000000, 0x355e01, 0x000000, + 0x355f04, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x356301, 0x000000, + 0x356402, 0x356601, 0x000000, 0x000000, 0x356703, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x356a0a, 0x357401, 0x000000, 0x357501, 0x000000, + 0x000000, 0x000000, 0x357605, 0x000000, 0x000000, 0x000000, 0x357b02, 0x357d03, + 0x358005, 0x000000, 0x000000, 0x000000, 0x358503, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x358802, 0x000000, 0x000000, 0x000000, 0x000000, 0x358a07, + 0x000000, 0x000000, 0x000000, 0x359101, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x359201, 0x000000, 0x359301, + 0x359402, 0x000000, 0x000000, 0x359605, 0x359b06, 0x35a101, 0x35a201, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x35a302, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x35a502, + 0x000000, 0x35a701, 0x000000, 0x000000, 0x35a801, 0x35a909, 0x35b204, 0x000000, + 0x35b601, 0x000000, 0x000000, 0x35b701, 0x000000, 0x000000, 0x000000, 0x35b804, + 0x000000, 0x35bc05, 0x000000, 0x000000, 0x35c101, 0x35c201, 0x000000, 0x35c301, + 0x35c401, 0x000000, 0x35c501, 0x000000, 0x000000, 0x35c601, 0x000000, 0x000000, + 0x000000, 0x35c701, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x35c803, 0x000000, 0x000000, 0x35cb03, 0x000000, 0x35ce01, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x35cf02, 0x35d109, 0x35da0a, 0x000000, 0x000000, 0x000000, 0x35e401, + 0x000000, 0x35e503, 0x000000, 0x35e803, 0x000000, 0x35eb02, 0x35ed0a, 0x000000, + 0x000000, 0x000000, 0x000000, 0x35f701, 0x35f811, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x360902, 0x000000, 0x360b02, 0x000000, 0x000000, 0x360d01, + 0x000000, 0x000000, 0x360e01, 0x000000, 0x360f02, 0x000000, 0x000000, 0x000000, + 0x000000, 0x361101, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x361202, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x36140d, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x362102, 0x000000, 0x000000, 0x362301, 0x000000, 0x000000, 0x362401, 0x000000, + 0x000000, 0x362501, 0x362605, 0x000000, 0x362b01, 0x000000, 0x362c01, 0x362d02, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x362f01, 0x000000, 0x000000, 0x000000, 0x000000, 0x363005, + 0x363508, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x363d02, 0x000000, 0x363f01, 0x364001, 0x364101, + 0x000000, 0x000000, 0x364203, 0x364503, 0x000000, 0x364802, 0x364a01, 0x364b04, + 0x364f02, 0x000000, 0x000000, 0x365103, 0x000000, 0x000000, 0x000000, 0x365401, + 0x000000, 0x000000, 0x000000, 0x365501, 0x000000, 0x000000, 0x000000, 0x365601, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x365705, 0x365c01, 0x000000, + 0x000000, 0x000000, 0x000000, 0x365d01, 0x000000, 0x365e01, 0x000000, 0x000000, + 0x365f01, 0x000000, 0x000000, 0x000000, 0x366001, 0x000000, 0x000000, 0x366102, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x366303, + 0x000000, 0x366605, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x366b01, + 0x000000, 0x366c01, 0x000000, 0x366d01, 0x000000, 0x000000, 0x366e09, 0x000000, + 0x36770a, 0x000000, 0x000000, 0x000000, 0x368101, 0x000000, 0x000000, 0x368201, + 0x000000, 0x000000, 0x000000, 0x000000, 0x368301, 0x000000, 0x36840a, 0x000000, + 0x368e02, 0x369001, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x369114, 0x36a501, + 0x000000, 0x36a603, 0x36a901, 0x000000, 0x36aa01, 0x000000, 0x000000, 0x000000, + 0x000000, 0x36ab03, 0x000000, 0x000000, 0x36ae13, 0x000000, 0x000000, 0x000000, + 0x36c101, 0x000000, 0x36c202, 0x000000, 0x36c414, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x36d802, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x36da03, 0x000000, 0x000000, 0x000000, + 0x000000, 0x36dd02, 0x000000, 0x000000, 0x000000, 0x36df01, 0x36e002, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x36e201, 0x000000, 0x000000, 0x36e304, 0x36e707, 0x000000, 0x36ee01, + 0x000000, 0x36ef02, 0x36f101, 0x000000, 0x000000, 0x36f201, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x36f304, + 0x000000, 0x000000, 0x000000, 0x36f702, 0x000000, 0x36f901, 0x36fa01, 0x000000, + 0x36fb03, 0x36fe06, 0x370401, 0x370501, 0x370606, 0x370c02, 0x000000, 0x000000, + 0x000000, 0x000000, 0x370e01, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x370f01, 0x371001, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x371104, 0x000000, 0x371501, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x371601, 0x000000, 0x000000, 0x000000, 0x371701, 0x000000, + 0x000000, 0x371802, 0x000000, 0x000000, 0x000000, 0x371a01, 0x371b01, 0x000000, + 0x000000, 0x371c08, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x372401, 0x000000, 0x000000, 0x000000, 0x000000, 0x372501, + 0x000000, 0x000000, 0x000000, 0x000000, 0x372601, 0x000000, 0x000000, 0x372701, + 0x000000, 0x000000, 0x372801, 0x000000, 0x372905, 0x372e01, 0x000000, 0x372f08, + 0x373702, 0x000000, 0x000000, 0x373902, 0x000000, 0x373b01, 0x000000, 0x000000, + 0x000000, 0x373c01, 0x373d04, 0x000000, 0x000000, 0x000000, 0x000000, 0x374103, + 0x000000, 0x000000, 0x374402, 0x000000, 0x374601, 0x000000, 0x000000, 0x000000, + 0x374701, 0x000000, 0x000000, 0x374801, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x374902, 0x000000, 0x374b01, + 0x374c02, 0x000000, 0x000000, 0x374e02, 0x000000, 0x375001, 0x000000, 0x000000, + 0x000000, 0x000000, 0x375101, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x37520a, 0x000000, 0x000000, 0x375c01, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x375d02, 0x000000, 0x000000, 0x375f02, 0x000000, + 0x000000, 0x376101, 0x000000, 0x000000, 0x376202, 0x376401, 0x000000, 0x000000, + 0x376503, 0x376802, 0x376a03, 0x000000, 0x376d07, 0x000000, 0x000000, 0x377401, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x377501, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x377601, 0x377704, 0x000000, 0x000000, 0x000000, + 0x377b04, 0x000000, 0x000000, 0x377f17, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x379603, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x379901, 0x000000, 0x000000, 0x379a05, 0x000000, 0x000000, 0x000000, + 0x379f01, 0x37a005, 0x000000, 0x000000, 0x000000, 0x37a501, 0x000000, 0x000000, + 0x000000, 0x37a603, 0x000000, 0x37a901, 0x000000, 0x000000, 0x37aa03, 0x000000, + 0x000000, 0x37ad02, 0x000000, 0x000000, 0x37af04, 0x000000, 0x000000, 0x000000, + 0x37b301, 0x000000, 0x37b401, 0x000000, 0x000000, 0x000000, 0x000000, 0x37b505, + 0x37ba02, 0x37bc08, 0x000000, 0x000000, 0x37c401, 0x000000, 0x000000, 0x37c501, + 0x000000, 0x37c603, 0x37c901, 0x000000, 0x000000, 0x000000, 0x37ca01, 0x000000, + 0x000000, 0x000000, 0x37cb01, 0x37cc01, 0x000000, 0x000000, 0x000000, 0x000000, + 0x37cd02, 0x000000, 0x000000, 0x000000, 0x37cf01, 0x000000, 0x000000, 0x000000, + 0x37d001, 0x000000, 0x37d103, 0x000000, 0x37d408, 0x37dc01, 0x37dd02, 0x37df01, + 0x37e002, 0x000000, 0x37e201, 0x000000, 0x37e301, 0x37e402, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x37e601, 0x37e705, 0x000000, 0x000000, 0x37ec01, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x37ed02, 0x000000, 0x000000, + 0x000000, 0x000000, 0x37ef01, 0x000000, 0x000000, 0x000000, 0x000000, 0x37f001, + 0x37f104, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x37f503, 0x37f801, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x37f901, 0x37fa01, + 0x000000, 0x000000, 0x000000, 0x000000, 0x37fb01, 0x000000, 0x000000, 0x000000, + 0x37fc04, 0x000000, 0x000000, 0x380003, 0x380301, 0x000000, 0x380401, 0x000000, + 0x000000, 0x380503, 0x000000, 0x380801, 0x380901, 0x000000, 0x000000, 0x380a0f, + 0x000000, 0x381902, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x381b01, + 0x381c06, 0x382202, 0x000000, 0x382401, 0x000000, 0x000000, 0x382505, 0x000000, + 0x382a15, 0x000000, 0x383f01, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x384004, 0x000000, 0x000000, 0x384401, 0x000000, 0x384502, 0x000000, 0x384701, + 0x384808, 0x000000, 0x000000, 0x000000, 0x385007, 0x000000, 0x000000, 0x385706, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x385d01, 0x000000, 0x000000, 0x000000, 0x385e04, 0x000000, 0x000000, + 0x386205, 0x000000, 0x386702, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x386901, 0x000000, 0x000000, 0x386a03, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x386d08, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x387503, 0x000000, 0x387803, 0x000000, 0x387b06, 0x000000, + 0x000000, 0x388101, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x388202, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x388408, 0x000000, + 0x388c01, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x388d04, + 0x389101, 0x000000, 0x000000, 0x000000, 0x389202, 0x000000, 0x000000, 0x000000, + 0x389401, 0x389501, 0x000000, 0x000000, 0x000000, 0x389601, 0x389701, 0x389803, + 0x389b01, 0x389c01, 0x389d01, 0x389e01, 0x389f01, 0x38a002, 0x000000, 0x38a202, + 0x000000, 0x38a401, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x38a505, 0x000000, 0x38aa05, 0x38af01, + 0x38b001, 0x38b101, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x38b20b, 0x38bd04, 0x38c107, + 0x000000, 0x38c807, 0x000000, 0x38cf03, 0x000000, 0x38d201, 0x000000, 0x000000, + 0x38d302, 0x38d501, 0x38d601, 0x000000, 0x000000, 0x38d701, 0x000000, 0x000000, + 0x000000, 0x38d801, 0x000000, 0x38d902, 0x000000, 0x000000, 0x000000, 0x000000, + 0x38db08, 0x38e301, 0x000000, 0x000000, 0x38e401, 0x38e502, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x38e701, 0x000000, 0x000000, 0x38e802, + 0x000000, 0x000000, 0x000000, 0x38ea05, 0x38ef01, 0x000000, 0x000000, 0x38f001, + 0x38f101, 0x38f201, 0x000000, 0x000000, 0x38f302, 0x000000, 0x000000, 0x000000, + 0x000000, 0x38f501, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x38f604, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x38fa01, 0x000000, 0x38fb0c, 0x000000, + 0x000000, 0x390701, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x390803, 0x000000, + 0x000000, 0x390b01, 0x390c06, 0x391202, 0x000000, 0x391402, 0x000000, 0x000000, + 0x000000, 0x000000, 0x39160c, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x392201, 0x000000, 0x392303, 0x000000, 0x000000, 0x000000, 0x000000, + 0x392602, 0x000000, 0x392801, 0x392901, 0x000000, 0x000000, 0x000000, 0x000000, + 0x392a01, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x392b03, 0x000000, 0x000000, 0x392e03, 0x393102, 0x000000, 0x000000, + 0x000000, 0x000000, 0x393301, 0x000000, 0x000000, 0x000000, 0x000000, 0x393401, + 0x393507, 0x000000, 0x393c01, 0x000000, 0x000000, 0x393d04, 0x000000, 0x394103, + 0x000000, 0x394404, 0x000000, 0x000000, 0x000000, 0x394803, 0x000000, 0x000000, + 0x000000, 0x394b01, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x394c01, 0x000000, 0x000000, 0x394d0a, 0x000000, + 0x000000, 0x000000, 0x395701, 0x000000, 0x000000, 0x395801, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x395901, 0x395a03, 0x000000, 0x000000, 0x000000, + 0x000000, 0x395d01, 0x000000, 0x000000, 0x000000, 0x000000, 0x395e0a, 0x396802, + 0x000000, 0x000000, 0x000000, 0x000000, 0x396a06, 0x397006, 0x397601, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x397701, 0x000000, 0x000000, 0x000000, 0x397806, 0x000000, 0x000000, + 0x000000, 0x000000, 0x397e01, 0x000000, 0x397f01, 0x398005, 0x398502, 0x000000, + 0x000000, 0x000000, 0x398701, 0x398802, 0x000000, 0x000000, 0x000000, 0x000000, + 0x398a02, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x398c03, 0x398f01, 0x399003, 0x000000, 0x000000, 0x399302, 0x399502, 0x000000, + 0x000000, 0x000000, 0x399709, 0x39a002, 0x000000, 0x000000, 0x000000, 0x000000, + 0x39a203, 0x39a502, 0x39a701, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x39a801, 0x39a903, 0x39ac06, 0x39b201, 0x000000, 0x39b301, 0x000000, 0x39b401, + 0x39b501, 0x000000, 0x000000, 0x39b601, 0x000000, 0x000000, 0x39b701, 0x000000, + 0x000000, 0x000000, 0x000000, 0x39b802, 0x000000, 0x39ba03, 0x000000, 0x000000, + 0x39bd03, 0x000000, 0x000000, 0x39c001, 0x39c102, 0x39c307, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x39ca03, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x39cd05, 0x000000, 0x39d201, 0x39d302, 0x39d503, 0x000000, + 0x000000, 0x000000, 0x39d801, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x39d901, 0x000000, 0x000000, 0x000000, 0x000000, 0x39da01, 0x000000, + 0x39db03, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x39de01, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x39df02, + 0x000000, 0x39e101, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x39e201, 0x000000, 0x39e303, 0x000000, 0x39e601, 0x000000, 0x000000, 0x000000, + 0x39e702, 0x000000, 0x000000, 0x39e901, 0x39ea03, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x39ed03, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x39f00c, + 0x000000, 0x39fc01, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x39fd01, + 0x000000, 0x000000, 0x39fe18, 0x3a1602, 0x000000, 0x3a1803, 0x000000, 0x3a1b01, + 0x000000, 0x3a1c01, 0x3a1d02, 0x3a1f01, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x3a2001, 0x000000, 0x3a210c, 0x3a2d01, 0x000000, 0x000000, 0x000000, + 0x000000, 0x3a2e0c, 0x000000, 0x3a3a01, 0x000000, 0x3a3b03, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x3a3e09, 0x000000, 0x000000, + 0x000000, 0x000000, 0x3a470b, 0x000000, 0x000000, 0x3a5201, 0x000000, 0x3a5302, + 0x3a5501, 0x3a5601, 0x000000, 0x000000, 0x3a5709, 0x000000, 0x3a6002, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x3a6201, 0x000000, + 0x000000, 0x3a6301, 0x3a6402, 0x3a6601, 0x000000, 0x000000, 0x3a670c, 0x000000, + 0x000000, 0x000000, 0x3a7309, 0x3a7c11, 0x000000, 0x000000, 0x3a8d05, 0x000000, + 0x000000, 0x000000, 0x000000, 0x3a9203, 0x000000, 0x000000, 0x3a9503, 0x3a9801, + 0x000000, 0x000000, 0x3a9912, 0x3aab01, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x3aac01, 0x000000, 0x3aad01, 0x000000, 0x000000, 0x000000, + 0x000000, 0x3aae02, 0x000000, 0x000000, 0x3ab004, 0x3ab404, 0x3ab801, 0x000000, + 0x000000, 0x000000, 0x3ab901, 0x000000, 0x000000, 0x000000, 0x3aba08, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x3ac201, 0x3ac301, 0x000000, 0x000000, + 0x000000, 0x3ac401, 0x3ac502, 0x3ac702, 0x3ac90f, 0x000000, 0x3ad801, 0x000000, + 0x000000, 0x000000, 0x000000, 0x3ad909, 0x000000, 0x000000, 0x3ae207, 0x3ae902, + 0x3aeb01, 0x000000, 0x000000, 0x3aec01, 0x3aed02, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x3aef01, 0x000000, 0x000000, + 0x000000, 0x3af005, 0x000000, 0x000000, 0x000000, 0x000000, 0x3af502, 0x000000, + 0x3af701, 0x000000, 0x3af803, 0x000000, 0x3afb02, 0x000000, 0x000000, 0x3afd03, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x3b0001, 0x000000, 0x000000, 0x3b0103, 0x000000, 0x3b0404, 0x3b0802, 0x000000, + 0x000000, 0x000000, 0x3b0a03, 0x000000, 0x3b0d01, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x3b0e01, 0x000000, 0x000000, 0x3b0f03, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x3b1206, 0x3b1801, 0x000000, 0x000000, + 0x000000, 0x3b1901, 0x000000, 0x3b1a03, 0x000000, 0x000000, 0x3b1d01, 0x000000, + 0x3b1e02, 0x000000, 0x000000, 0x000000, 0x3b2001, 0x3b2101, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x3b2201, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x3b230e, 0x000000, 0x000000, 0x3b3108, 0x3b3907, 0x000000, + 0x3b4001, 0x3b4105, 0x000000, 0x3b4602, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x3b4801, 0x000000, 0x3b4901, 0x3b4a04, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x3b4e02, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x3b5002, 0x3b5207, 0x000000, 0x3b5901, 0x3b5a01, 0x3b5b08, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x3b6302, 0x000000, + 0x000000, 0x000000, 0x000000, 0x3b6501, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x3b6606, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x3b6c01, 0x000000, 0x3b6d12, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x3b7f02, 0x000000, 0x000000, + 0x000000, 0x000000, 0x3b8104, 0x000000, 0x3b8502, 0x3b8708, 0x000000, 0x3b8f02, + 0x000000, 0x000000, 0x000000, 0x000000, 0x3b9101, 0x3b9201, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x3b9303, 0x000000, 0x000000, + 0x000000, 0x3b9607, 0x3b9d04, 0x3ba101, 0x000000, 0x000000, 0x000000, 0x3ba20a, + 0x000000, 0x000000, 0x000000, 0x3bac02, 0x3bae01, 0x000000, 0x000000, 0x000000, + 0x3baf01, 0x3bb001, 0x3bb103, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x3bb404, 0x000000, 0x000000, 0x000000, 0x000000, 0x3bb802, 0x000000, 0x000000, + 0x3bba05, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x3bbf01, 0x3bc007, 0x000000, 0x000000, 0x3bc702, 0x000000, 0x000000, 0x000000, + 0x000000, 0x3bc901, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x3bca01, 0x3bcb01, 0x000000, 0x3bcc02, 0x000000, 0x000000, 0x3bce01, 0x000000, + 0x000000, 0x3bcf01, 0x3bd001, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x3bd103, + 0x3bd401, 0x000000, 0x000000, 0x000000, 0x3bd501, 0x3bd601, 0x000000, 0x000000, + 0x000000, 0x000000, 0x3bd701, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x3bd803, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x3bdb01, 0x000000, 0x3bdc01, 0x3bdd04, 0x000000, 0x3be104, 0x000000, + 0x000000, 0x000000, 0x000000, 0x3be501, 0x000000, 0x3be606, 0x000000, 0x3bec01, + 0x000000, 0x000000, 0x3bed01, 0x000000, 0x000000, 0x3bee01, 0x3bef01, 0x000000, + 0x000000, 0x000000, 0x000000, 0x3bf002, 0x000000, 0x000000, 0x000000, 0x000000, + 0x3bf201, 0x000000, 0x000000, 0x3bf301, 0x3bf401, 0x3bf506, 0x000000, 0x3bfb01, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x3bfc01, 0x000000, 0x3bfd01, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x3bfe01, 0x3bff04, 0x3c0310, 0x000000, 0x3c130c, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x3c1f01, 0x000000, 0x000000, 0x3c2002, + 0x000000, 0x3c2201, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x3c2301, 0x000000, 0x000000, 0x3c2401, 0x3c2501, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x3c2601, 0x000000, 0x3c2702, 0x000000, 0x000000, 0x000000, 0x3c2903, 0x000000, + 0x3c2c05, 0x3c3101, 0x000000, 0x000000, 0x000000, 0x000000, 0x3c3201, 0x000000, + 0x000000, 0x000000, 0x3c3304, 0x000000, 0x3c370c, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x3c4307, 0x000000, 0x3c4a03, 0x000000, + 0x000000, 0x3c4d01, 0x000000, 0x000000, 0x000000, 0x000000, 0x3c4e01, 0x000000, + 0x000000, 0x000000, 0x3c4f01, 0x000000, 0x000000, 0x000000, 0x3c5008, 0x3c5802, + 0x3c5a01, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x3c5b03, 0x000000, 0x000000, 0x3c5e01, 0x000000, 0x000000, 0x000000, 0x3c5f02, + 0x000000, 0x000000, 0x3c6102, 0x000000, 0x3c6301, 0x3c6401, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x3c6502, 0x3c6701, 0x000000, 0x3c6801, 0x000000, + 0x000000, 0x3c6901, 0x000000, 0x000000, 0x3c6a01, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x3c6b0d, 0x000000, 0x000000, 0x000000, 0x000000, 0x3c7803, + 0x000000, 0x000000, 0x3c7b01, 0x000000, 0x3c7c01, 0x3c7d01, 0x000000, 0x000000, + 0x000000, 0x3c7e01, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x3c7f04, + 0x000000, 0x3c8306, 0x3c8901, 0x000000, 0x000000, 0x000000, 0x3c8a01, 0x000000, + 0x000000, 0x000000, 0x3c8b01, 0x000000, 0x3c8c0b, 0x000000, 0x000000, 0x3c970a, + 0x000000, 0x3ca102, 0x000000, 0x000000, 0x000000, 0x3ca301, 0x000000, 0x3ca401, + 0x3ca501, 0x000000, 0x000000, 0x3ca612, 0x000000, 0x000000, 0x3cb801, 0x3cb902, + 0x000000, 0x3cbb04, 0x3cbf01, 0x000000, 0x3cc001, 0x000000, 0x000000, 0x000000, + 0x3cc101, 0x000000, 0x3cc202, 0x000000, 0x3cc408, 0x3ccc08, 0x3cd404, 0x3cd801, + 0x3cd904, 0x000000, 0x3cdd01, 0x000000, 0x3cde03, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x3ce102, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x3ce301, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x3ce404, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x3ce801, + 0x3ce901, 0x000000, 0x000000, 0x000000, 0x000000, 0x3cea01, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x3ceb01, 0x000000, 0x000000, 0x000000, + 0x3cec03, 0x000000, 0x000000, 0x000000, 0x000000, 0x3cef01, 0x000000, 0x000000, + 0x3cf001, 0x000000, 0x000000, 0x000000, 0x000000, 0x3cf101, 0x3cf201, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x3cf305, 0x000000, 0x3cf803, + 0x000000, 0x000000, 0x3cfb01, 0x000000, 0x000000, 0x3cfc02, 0x000000, 0x000000, + 0x3cfe02, 0x3d0001, 0x3d0102, 0x000000, 0x000000, 0x3d0310, 0x000000, 0x3d1301, + 0x3d140c, 0x000000, 0x000000, 0x3d2001, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x3d2101, 0x000000, 0x000000, 0x3d2205, 0x000000, + 0x000000, 0x000000, 0x3d2702, 0x000000, 0x3d2906, 0x000000, 0x000000, 0x000000, + 0x3d2f01, 0x000000, 0x000000, 0x3d3003, 0x000000, 0x000000, 0x3d3301, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x3d3405, 0x000000, 0x000000, 0x3d3901, + 0x000000, 0x000000, 0x3d3a01, 0x000000, 0x000000, 0x000000, 0x000000, 0x3d3b01, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x3d3c01, 0x000000, 0x000000, 0x000000, 0x000000, + 0x3d3d01, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x3d3e02, 0x000000, + 0x000000, 0x3d4005, 0x000000, 0x3d4501, 0x000000, 0x000000, 0x000000, 0x000000, + 0x3d4601, 0x000000, 0x3d4702, 0x000000, 0x000000, 0x3d4907, 0x000000, 0x000000, + 0x000000, 0x3d5002, 0x000000, 0x3d5201, 0x3d5301, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x3d5401, 0x000000, + 0x3d5501, 0x3d5601, 0x000000, 0x3d5701, 0x000000, 0x3d5802, 0x000000, 0x3d5a02, + 0x000000, 0x3d5c03, 0x000000, 0x3d5f04, 0x3d6301, 0x000000, 0x3d6401, 0x000000, + 0x3d6502, 0x3d6704, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x3d6b01, + 0x000000, 0x000000, 0x000000, 0x3d6c01, 0x000000, 0x3d6d0e, 0x000000, 0x000000, + 0x000000, 0x3d7b05, 0x000000, 0x3d8001, 0x3d8101, 0x000000, 0x000000, 0x3d8201, + 0x000000, 0x3d8301, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x3d8403, + 0x000000, 0x000000, 0x000000, 0x3d8701, 0x000000, 0x3d8806, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x3d8e06, 0x000000, 0x000000, 0x000000, + 0x3d9402, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x3d9604, 0x000000, 0x000000, 0x000000, 0x3d9a0d, 0x000000, + 0x000000, 0x3da701, 0x000000, 0x000000, 0x000000, 0x000000, 0x3da805, 0x3dad01, + 0x3dae01, 0x000000, 0x000000, 0x3daf0f, 0x000000, 0x000000, 0x000000, 0x3dbe04, + 0x000000, 0x3dc207, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x3dc901, 0x000000, + 0x000000, 0x000000, 0x3dca02, 0x000000, 0x000000, 0x000000, 0x000000, 0x3dcc01, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x3dcd02, 0x3dcf03, 0x000000, + 0x000000, 0x3dd202, 0x000000, 0x000000, 0x3dd402, 0x3dd601, 0x000000, 0x3dd701, + 0x000000, 0x000000, 0x3dd802, 0x000000, 0x3dda03, 0x3ddd01, 0x3dde04, 0x3de201, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x3de301, 0x000000, 0x000000, 0x000000, 0x000000, + 0x3de406, 0x3dea05, 0x3def02, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x3df102, 0x3df301, 0x000000, 0x3df403, 0x000000, 0x000000, + 0x000000, 0x3df701, 0x000000, 0x000000, 0x000000, 0x000000, 0x3df801, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x3df906, 0x000000, 0x3dff04, + 0x000000, 0x000000, 0x3e0301, 0x000000, 0x000000, 0x000000, 0x000000, 0x3e0401, + 0x3e0505, 0x3e0a02, 0x3e0c03, 0x000000, 0x000000, 0x3e0f01, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x3e1001, 0x3e1102, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x3e1301, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x3e1401, 0x000000, 0x000000, + 0x3e1501, 0x000000, 0x000000, 0x000000, 0x3e1601, 0x000000, 0x3e1701, 0x3e1801, + 0x000000, 0x3e1903, 0x3e1c01, 0x3e1d09, 0x000000, 0x3e2604, 0x3e2a01, 0x000000, + 0x3e2b08, 0x000000, 0x3e330b, 0x3e3e02, 0x000000, 0x3e400d, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x3e4d08, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x3e5503, 0x000000, 0x000000, 0x000000, 0x3e5805, + 0x000000, 0x000000, 0x3e5d01, 0x000000, 0x3e5e0a, 0x000000, 0x000000, 0x3e6801, + 0x000000, 0x000000, 0x3e6903, 0x000000, 0x000000, 0x3e6c01, 0x3e6d01, 0x3e6e03, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x3e7104, + 0x000000, 0x000000, 0x000000, 0x3e7501, 0x000000, 0x3e7604, 0x3e7a03, 0x3e7d01, + 0x000000, 0x3e7e01, 0x000000, 0x3e7f08, 0x000000, 0x000000, 0x000000, 0x000000, + 0x3e8701, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x3e8802, 0x3e8a02, 0x000000, 0x3e8c01, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x3e8d01, 0x000000, 0x000000, 0x3e8e08, 0x3e9601, 0x3e9701, 0x3e9801, 0x000000, + 0x000000, 0x3e9904, 0x000000, 0x3e9d02, 0x000000, 0x3e9f01, 0x000000, 0x3ea002, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x3ea201, 0x3ea301, + 0x3ea402, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x3ea602, 0x000000, + 0x000000, 0x000000, 0x000000, 0x3ea802, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x3eaa01, 0x3eab03, 0x000000, 0x000000, 0x3eae01, 0x000000, 0x000000, + 0x000000, 0x3eaf01, 0x000000, 0x000000, 0x3eb001, 0x3eb102, 0x3eb303, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x3eb601, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x3eb702, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x3eb902, 0x3ebb01, 0x3ebc02, + 0x000000, 0x000000, 0x3ebe01, 0x000000, 0x000000, 0x3ebf03, 0x000000, 0x000000, + 0x000000, 0x3ec201, 0x3ec301, 0x000000, 0x000000, 0x3ec409, 0x3ecd01, 0x000000, + 0x000000, 0x000000, 0x3ece01, 0x000000, 0x000000, 0x000000, 0x3ecf01, 0x000000, + 0x3ed007, 0x000000, 0x000000, 0x000000, 0x3ed701, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x3ed804, 0x3edc04, 0x000000, 0x3ee006, 0x000000, 0x3ee601, 0x000000, 0x3ee701, + 0x3ee897, 0x000000, 0x000000, 0x3f7f03, 0x000000, 0x000000, 0x3f8201, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x3f8301, 0x3f8401, + 0x000000, 0x000000, 0x3f8501, 0x000000, 0x000000, 0x3f8605, 0x000000, 0x3f8b01, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x3f8c01, + 0x000000, 0x000000, 0x3f8d03, 0x3f9001, 0x000000, 0x3f9101, 0x000000, 0x000000, + 0x000000, 0x000000, 0x3f9201, 0x3f9301, 0x3f9403, 0x3f9701, 0x000000, 0x000000, + 0x000000, 0x3f9803, 0x3f9b02, 0x000000, 0x000000, 0x000000, 0x3f9d03, 0x000000, + 0x3fa001, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x3fa101, 0x000000, 0x000000, 0x000000, 0x000000, 0x3fa201, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x3fa301, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x3fa402, 0x3fa602, 0x3fa805, 0x000000, 0x3fad02, 0x000000, 0x3faf01, 0x000000, + 0x3fb001, 0x000000, 0x3fb101, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x3fb201, + 0x3fb304, 0x3fb701, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x3fb802, 0x3fba03, 0x000000, 0x3fbd03, 0x000000, 0x000000, 0x000000, 0x3fc005, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x3fc507, + 0x3fcc03, 0x3fcf01, 0x000000, 0x000000, 0x000000, 0x000000, 0x3fd003, 0x3fd305, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x3fd801, 0x000000, 0x000000, + 0x3fd901, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x3fda01, 0x000000, 0x000000, 0x3fdb01, 0x000000, 0x000000, + 0x000000, 0x000000, 0x3fdc01, 0x000000, 0x000000, 0x000000, 0x3fdd07, 0x000000, + 0x3fe402, 0x000000, 0x000000, 0x000000, 0x000000, 0x3fe601, 0x3fe702, 0x000000, + 0x000000, 0x000000, 0x000000, 0x3fe901, 0x3fea01, 0x3feb01, 0x3fec01, 0x000000, + 0x000000, 0x3fed01, 0x000000, 0x000000, 0x000000, 0x000000, 0x3fee01, 0x3fef01, + 0x000000, 0x3ff005, 0x3ff502, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x3ff702, 0x000000, 0x000000, 0x000000, 0x000000, 0x3ff901, + 0x3ffa01, 0x000000, 0x3ffb01, 0x000000, 0x000000, 0x000000, 0x3ffc02, 0x3ffe07, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x400509, 0x000000, 0x000000, + 0x000000, 0x400e03, 0x000000, 0x401102, 0x401302, 0x401501, 0x401602, 0x000000, + 0x000000, 0x000000, 0x401802, 0x401a01, 0x000000, 0x000000, 0x000000, 0x000000, + 0x401b01, 0x000000, 0x401c02, 0x401e08, 0x402601, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x402704, 0x000000, 0x000000, 0x000000, 0x402b06, 0x403101, + 0x40320e, 0x404001, 0x000000, 0x404101, 0x404202, 0x000000, 0x000000, 0x000000, + 0x404401, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x404502, 0x000000, 0x000000, 0x404702, 0x404901, 0x000000, 0x000000, 0x404a01, + 0x000000, 0x000000, 0x404b02, 0x000000, 0x000000, 0x000000, 0x000000, 0x404d01, + 0x000000, 0x404e03, 0x000000, 0x000000, 0x40510d, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x405e01, 0x000000, 0x000000, 0x405f01, 0x000000, 0x406003, + 0x406301, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x406404, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x406802, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x406a07, 0x000000, 0x000000, 0x407105, 0x000000, 0x000000, 0x407602, 0x000000, + 0x407801, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x407902, 0x000000, 0x000000, 0x000000, 0x407b01, 0x407c02, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x407e02, + 0x408003, 0x000000, 0x000000, 0x000000, 0x408301, 0x000000, 0x408402, 0x000000, + 0x40860a, 0x000000, 0x409002, 0x000000, 0x000000, 0x409203, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x409507, 0x000000, 0x000000, 0x409c01, + 0x409d01, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x409e04, 0x40a201, 0x40a303, 0x000000, 0x000000, 0x000000, + 0x40a601, 0x000000, 0x40a701, 0x000000, 0x000000, 0x000000, 0x40a805, 0x000000, + 0x000000, 0x40ad04, 0x000000, 0x000000, 0x40b103, 0x40b405, 0x000000, 0x000000, + 0x000000, 0x40b903, 0x000000, 0x000000, 0x000000, 0x40bc0c, 0x40c801, 0x000000, + 0x000000, 0x000000, 0x40c901, 0x40ca08, 0x40d201, 0x000000, 0x40d302, 0x000000, + 0x40d502, 0x000000, 0x000000, 0x000000, 0x40d701, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x40d802, 0x000000, 0x000000, 0x000000, 0x000000, 0x40da01, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x40db08, + 0x40e301, 0x000000, 0x000000, 0x000000, 0x000000, 0x40e405, 0x000000, 0x40e916, + 0x000000, 0x000000, 0x000000, 0x40ff01, 0x000000, 0x000000, 0x410004, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x410401, 0x000000, 0x000000, + 0x000000, 0x000000, 0x410505, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x410a02, 0x000000, 0x000000, 0x000000, 0x000000, 0x410c01, 0x410d01, + 0x000000, 0x000000, 0x000000, 0x410e01, 0x000000, 0x000000, 0x410f0b, 0x411a04, + 0x000000, 0x000000, 0x000000, 0x000000, 0x411e01, 0x000000, 0x411f01, 0x000000, + 0x000000, 0x000000, 0x412003, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x41230a, 0x000000, 0x412d03, 0x000000, 0x000000, 0x000000, 0x000000, 0x413001, + 0x000000, 0x413102, 0x000000, 0x413301, 0x000000, 0x413401, 0x000000, 0x413502, + 0x000000, 0x413709, 0x000000, 0x000000, 0x000000, 0x414002, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x414202, 0x000000, 0x000000, 0x000000, + 0x414402, 0x000000, 0x000000, 0x000000, 0x000000, 0x414601, 0x000000, 0x414701, + 0x414802, 0x000000, 0x000000, 0x000000, 0x414a01, 0x000000, 0x000000, 0x000000, + 0x000000, 0x414b02, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x414d06, 0x415302, 0x000000, 0x000000, 0x415501, + 0x415601, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x415701, 0x000000, 0x415801, 0x000000, 0x000000, 0x415901, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x415a01, 0x000000, 0x000000, 0x000000, 0x415b02, + 0x000000, 0x000000, 0x000000, 0x000000, 0x415d04, 0x416105, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x416602, 0x000000, + 0x000000, 0x416804, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x416c03, + 0x000000, 0x416f04, 0x000000, 0x000000, 0x000000, 0x000000, 0x417302, 0x000000, + 0x000000, 0x417501, 0x000000, 0x417601, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x417702, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x417907, 0x000000, 0x418001, 0x000000, 0x418102, 0x000000, 0x418305, + 0x000000, 0x000000, 0x000000, 0x418803, 0x418b01, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x418c01, 0x000000, 0x000000, 0x418d02, 0x000000, + 0x418f01, 0x000000, 0x000000, 0x419002, 0x419205, 0x419702, 0x000000, 0x000000, + 0x419904, 0x000000, 0x000000, 0x000000, 0x419d0b, 0x000000, 0x000000, 0x41a805, + 0x000000, 0x000000, 0x41ad02, 0x41af01, 0x41b002, 0x000000, 0x41b201, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x41b310, 0x000000, 0x000000, 0x41c303, 0x41c602, 0x000000, 0x000000, + 0x41c80a, 0x41d206, 0x41d801, 0x000000, 0x000000, 0x41d901, 0x41da01, 0x000000, + 0x000000, 0x41db02, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x41dd01, 0x000000, 0x41de01, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x41df0c, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x41eb05, 0x000000, 0x41f001, 0x41f103, + 0x000000, 0x41f401, 0x41f501, 0x000000, 0x41f602, 0x000000, 0x000000, 0x000000, + 0x41f802, 0x41fa03, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x41fd01, + 0x41fe02, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x420001, 0x000000, 0x42010f, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x42100b, 0x000000, 0x000000, 0x421b01, + 0x421c01, 0x421d01, 0x000000, 0x000000, 0x421e0a, 0x000000, 0x000000, 0x000000, + 0x422801, 0x422902, 0x000000, 0x000000, 0x000000, 0x422b01, 0x422c01, 0x000000, + 0x000000, 0x000000, 0x422d03, 0x423001, 0x000000, 0x423103, 0x423401, 0x423502, + 0x000000, 0x000000, 0x000000, 0x423703, 0x423a0a, 0x000000, 0x000000, 0x000000, + 0x424404, 0x000000, 0x424806, 0x000000, 0x000000, 0x424e01, 0x000000, 0x000000, + 0x424f02, 0x000000, 0x000000, 0x000000, 0x000000, 0x425103, 0x000000, 0x000000, + 0x425402, 0x000000, 0x425606, 0x425c01, 0x000000, 0x000000, 0x000000, 0x000000, + 0x425d01, 0x000000, 0x000000, 0x425e02, 0x000000, 0x000000, 0x000000, 0x426001, + 0x000000, 0x426102, 0x426304, 0x426702, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x426902, 0x426b02, 0x000000, 0x426d01, 0x000000, 0x000000, 0x426e01, + 0x000000, 0x000000, 0x000000, 0x000000, 0x426f05, 0x427401, 0x427507, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x427c0a, 0x000000, 0x428602, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x428803, 0x428b02, 0x000000, 0x428d01, 0x000000, 0x000000, 0x428e06, 0x000000, + 0x429401, 0x000000, 0x000000, 0x429501, 0x429601, 0x000000, 0x000000, 0x000000, + 0x000000, 0x429701, 0x000000, 0x429801, 0x429901, 0x000000, 0x429a02, 0x429c01, + 0x000000, 0x429d01, 0x000000, 0x429e08, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x42a601, 0x000000, 0x000000, 0x42a701, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x42a803, 0x000000, 0x000000, 0x42ab04, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x42af01, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x42b001, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x42b106, + 0x000000, 0x42b701, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x42b802, + 0x42ba01, 0x42bb01, 0x000000, 0x000000, 0x000000, 0x42bc07, 0x000000, 0x000000, + 0x000000, 0x000000, 0x42c301, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x42c402, 0x000000, 0x42c607, 0x42cd01, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x42ce02, 0x000000, + 0x000000, 0x42d002, 0x000000, 0x42d207, 0x000000, 0x000000, 0x000000, 0x000000, + 0x42d901, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x42da0a, 0x42e402, + 0x42e601, 0x000000, 0x000000, 0x42e701, 0x000000, 0x000000, 0x000000, 0x42e801, + 0x42e901, 0x000000, 0x42ea01, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x42eb03, 0x42ee0a, 0x42f801, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x42f901, 0x000000, 0x42fa01, 0x000000, 0x42fb01, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x42fc01, 0x42fd01, + 0x000000, 0x42fe02, 0x430002, 0x000000, 0x430208, 0x000000, 0x000000, 0x000000, + 0x000000, 0x430a08, 0x431203, 0x000000, 0x431505, 0x000000, 0x000000, 0x000000, + 0x000000, 0x431a03, 0x000000, 0x000000, 0x431d03, 0x432001, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x432102, 0x000000, 0x000000, 0x432301, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x432402, 0x432603, + 0x000000, 0x432901, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x432a01, 0x432b07, 0x433201, 0x433301, 0x000000, + 0x000000, 0x43340c, 0x434001, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x434101, 0x000000, 0x000000, 0x000000, 0x000000, 0x434201, 0x000000, 0x434301, + 0x000000, 0x434409, 0x000000, 0x000000, 0x434d06, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x435302, 0x000000, 0x435501, 0x435602, 0x000000, 0x000000, + 0x000000, 0x435803, 0x435b01, 0x000000, 0x000000, 0x435c03, 0x000000, 0x435f03, + 0x000000, 0x000000, 0x436201, 0x000000, 0x43630c, 0x000000, 0x000000, 0x436f02, + 0x000000, 0x437102, 0x000000, 0x000000, 0x000000, 0x437303, 0x000000, 0x000000, + 0x000000, 0x000000, 0x437601, 0x437701, 0x000000, 0x437816, 0x000000, 0x438e07, + 0x000000, 0x439503, 0x000000, 0x439801, 0x000000, 0x000000, 0x000000, 0x439902, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x439b01, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x439c01, 0x000000, 0x439d03, 0x43a001, 0x000000, 0x000000, 0x000000, 0x000000, + 0x43a101, 0x43a202, 0x000000, 0x43a401, 0x000000, 0x000000, 0x000000, 0x000000, + 0x43a502, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x43a70e, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x43b50a, + 0x000000, 0x43bf04, 0x43c302, 0x000000, 0x000000, 0x000000, 0x43c501, 0x43c602, + 0x000000, 0x000000, 0x43c801, 0x000000, 0x000000, 0x43c901, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x43ca01, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x43cb01, 0x43cc02, + 0x000000, 0x000000, 0x43ce0c, 0x000000, 0x000000, 0x000000, 0x43da01, 0x000000, + 0x43db15, 0x000000, 0x000000, 0x000000, 0x43f001, 0x000000, 0x000000, 0x000000, + 0x000000, 0x43f101, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x43f204, + 0x000000, 0x000000, 0x43f602, 0x000000, 0x000000, 0x000000, 0x43f810, 0x440801, + 0x000000, 0x440901, 0x000000, 0x440a03, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x440d01, 0x440e01, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x440f04, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x441301, 0x441404, + 0x441804, 0x000000, 0x000000, 0x000000, 0x441c04, 0x000000, 0x000000, 0x442001, + 0x000000, 0x000000, 0x44210b, 0x000000, 0x000000, 0x442c01, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x442d02, 0x442f06, + 0x443504, 0x000000, 0x000000, 0x443902, 0x000000, 0x000000, 0x443b01, 0x000000, + 0x000000, 0x443c01, 0x000000, 0x000000, 0x000000, 0x000000, 0x443d05, 0x000000, + 0x444204, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x444604, 0x000000, + 0x000000, 0x000000, 0x444a01, 0x444b01, 0x000000, 0x444c01, 0x000000, 0x444d05, + 0x000000, 0x445201, 0x445301, 0x000000, 0x000000, 0x445401, 0x000000, 0x445501, + 0x445601, 0x000000, 0x000000, 0x000000, 0x445701, 0x000000, 0x000000, 0x000000, + 0x445805, 0x000000, 0x000000, 0x000000, 0x445d01, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x445e02, 0x000000, 0x446002, 0x000000, 0x446205, 0x000000, + 0x000000, 0x000000, 0x446701, 0x446801, 0x446901, 0x000000, 0x000000, 0x446a04, + 0x000000, 0x000000, 0x000000, 0x446e03, 0x000000, 0x000000, 0x000000, 0x447101, + 0x000000, 0x000000, 0x447204, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x447601, 0x000000, 0x000000, 0x000000, + 0x447706, 0x000000, 0x000000, 0x000000, 0x447d02, 0x000000, 0x000000, 0x000000, + 0x000000, 0x447f03, 0x000000, 0x000000, 0x000000, 0x448201, 0x000000, 0x448303, + 0x448606, 0x448c07, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x449302, 0x000000, 0x000000, 0x449501, 0x000000, 0x449601, + 0x000000, 0x000000, 0x449703, 0x000000, 0x000000, 0x000000, 0x449a01, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x449b01, 0x000000, 0x000000, + 0x449c01, 0x449d01, 0x000000, 0x449e02, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x44a001, 0x44a105, 0x000000, 0x44a606, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x44ac01, 0x000000, 0x000000, 0x000000, 0x44ad01, 0x44ae03, 0x000000, + 0x44b101, 0x000000, 0x000000, 0x44b201, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x44b308, 0x000000, 0x000000, 0x000000, 0x000000, + 0x44bb01, 0x44bc01, 0x000000, 0x000000, 0x44bd02, 0x44bf01, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x44c003, 0x000000, 0x000000, 0x000000, + 0x44c301, 0x000000, 0x000000, 0x44c402, 0x000000, 0x000000, 0x44c605, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x44cb06, 0x000000, 0x000000, 0x44d103, 0x000000, 0x44d401, + 0x44d501, 0x000000, 0x000000, 0x000000, 0x000000, 0x44d601, 0x000000, 0x000000, + 0x44d706, 0x000000, 0x000000, 0x44dd01, 0x000000, 0x000000, 0x44de02, 0x44e001, + 0x44e101, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x44e201, 0x000000, 0x000000, 0x44e301, 0x000000, 0x000000, 0x44e401, 0x000000, + 0x44e502, 0x000000, 0x44e701, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x44e802, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x44ea02, 0x000000, 0x000000, 0x000000, 0x000000, 0x44ec01, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x44ed10, 0x44fd01, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x44fe01, 0x44ff01, 0x000000, 0x450001, 0x450103, 0x000000, 0x000000, + 0x000000, 0x450402, 0x450602, 0x450806, 0x000000, 0x450e05, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x451302, 0x000000, 0x000000, + 0x000000, 0x45151c, 0x000000, 0x453106, 0x000000, 0x000000, 0x453702, 0x453904, + 0x453d02, 0x000000, 0x000000, 0x453f01, 0x000000, 0x000000, 0x454003, 0x000000, + 0x000000, 0x000000, 0x454301, 0x000000, 0x454401, 0x000000, 0x454501, 0x000000, + 0x000000, 0x000000, 0x454602, 0x000000, 0x000000, 0x000000, 0x000000, 0x454802, + 0x000000, 0x000000, 0x000000, 0x000000, 0x454a02, 0x000000, 0x000000, 0x000000, + 0x454c01, 0x454d01, 0x000000, 0x000000, 0x000000, 0x000000, 0x454e01, 0x454f01, + 0x455004, 0x000000, 0x000000, 0x000000, 0x455401, 0x000000, 0x455501, 0x455601, + 0x455702, 0x455907, 0x456001, 0x456101, 0x000000, 0x456203, 0x000000, 0x456506, + 0x000000, 0x456b03, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x456e01, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x456f01, + 0x000000, 0x000000, 0x457001, 0x000000, 0x000000, 0x457101, 0x457203, 0x000000, + 0x457501, 0x457601, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x457725, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x459c01, 0x000000, 0x000000, 0x000000, + 0x459d01, 0x000000, 0x000000, 0x000000, 0x459e02, 0x45a001, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x45a105, 0x45a601, 0x45a701, 0x45a80c, 0x000000, + 0x000000, 0x45b401, 0x000000, 0x000000, 0x000000, 0x45b502, 0x000000, 0x000000, + 0x000000, 0x45b702, 0x45b904, 0x45bd01, 0x000000, 0x45be04, 0x000000, 0x000000, + 0x45c201, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x45c301, + 0x45c409, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x45cd01, 0x45ce01, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x45cf07, 0x000000, 0x000000, 0x000000, + 0x45d602, 0x000000, 0x000000, 0x000000, 0x45d802, 0x45da01, 0x000000, 0x45db01, + 0x000000, 0x45dc01, 0x000000, 0x000000, 0x45dd01, 0x000000, 0x000000, 0x45de04, + 0x45e23e, 0x462001, 0x000000, 0x000000, 0x000000, 0x000000, 0x462101, 0x000000, + 0x000000, 0x46220d, 0x000000, 0x462f04, 0x000000, 0x000000, 0x463302, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x463502, 0x000000, 0x000000, 0x000000, + 0x000000, 0x463702, 0x463905, 0x000000, 0x000000, 0x463e14, 0x000000, 0x000000, + 0x000000, 0x000000, 0x465204, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x465602, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x465801, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x465902, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x465b02, 0x000000, 0x000000, + 0x465d01, 0x000000, 0x000000, 0x000000, 0x465e01, 0x000000, 0x000000, 0x000000, + 0x465f01, 0x000000, 0x46600d, 0x000000, 0x000000, 0x000000, 0x466d01, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x466e05, 0x000000, + 0x000000, 0x467301, 0x467401, 0x46750b, 0x000000, 0x000000, 0x468007, 0x468701, + 0x000000, 0x468801, 0x468901, 0x000000, 0x468a03, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x468d02, 0x000000, 0x000000, + 0x000000, 0x000000, 0x468f03, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x469201, 0x000000, 0x000000, 0x000000, 0x469307, + 0x000000, 0x000000, 0x469a03, 0x000000, 0x000000, 0x469d0f, 0x46ac01, 0x46ad03, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x46b001, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x46b102, 0x46b308, + 0x000000, 0x000000, 0x000000, 0x46bb03, 0x000000, 0x46be01, 0x000000, 0x000000, + 0x46bf01, 0x000000, 0x46c002, 0x000000, 0x000000, 0x46c201, 0x46c302, 0x000000, + 0x46c503, 0x000000, 0x000000, 0x000000, 0x000000, 0x46c802, 0x000000, 0x000000, + 0x000000, 0x000000, 0x46ca01, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x46cb01, 0x000000, 0x000000, 0x000000, + 0x000000, 0x46cc01, 0x46cd01, 0x000000, 0x46ce01, 0x000000, 0x000000, 0x46cf07, + 0x46d60f, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x46e501, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x46e601, 0x46e704, 0x000000, 0x000000, 0x46eb08, 0x46f302, 0x000000, 0x46f505, + 0x46fa01, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x46fb0b, 0x470601, 0x000000, 0x470701, 0x000000, 0x000000, + 0x000000, 0x000000, 0x470802, 0x000000, 0x470a01, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x470b01, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x470c01, 0x000000, 0x000000, 0x470d01, 0x000000, + 0x000000, 0x470e01, 0x470f02, 0x000000, 0x000000, 0x471101, 0x471201, 0x471301, + 0x000000, 0x000000, 0x000000, 0x471406, 0x000000, 0x471a01, 0x000000, 0x471b01, + 0x000000, 0x000000, 0x000000, 0x000000, 0x471c02, 0x000000, 0x000000, 0x000000, + 0x471e01, 0x471f06, 0x000000, 0x000000, 0x472501, 0x000000, 0x000000, 0x000000, + 0x472601, 0x472704, 0x000000, 0x000000, 0x000000, 0x472b02, 0x000000, 0x000000, + 0x472d01, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x472e02, 0x000000, + 0x473006, 0x473603, 0x000000, 0x473901, 0x000000, 0x473a05, 0x000000, 0x000000, + 0x000000, 0x000000, 0x473f01, 0x000000, 0x000000, 0x474001, 0x474101, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x474208, 0x474a02, 0x000000, 0x474c01, + 0x000000, 0x474d0c, 0x000000, 0x000000, 0x000000, 0x475903, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x475c01, 0x475d01, 0x475e02, 0x476008, + 0x476801, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x476901, 0x000000, 0x476a01, + 0x000000, 0x476b01, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x476c02, 0x000000, 0x476e02, 0x477001, 0x000000, 0x000000, 0x477112, 0x000000, + 0x000000, 0x000000, 0x000000, 0x478302, 0x000000, 0x000000, 0x000000, 0x478501, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x478601, 0x000000, 0x478701, 0x478802, + 0x000000, 0x478a01, 0x000000, 0x000000, 0x478b04, 0x478f0b, 0x000000, 0x479a01, + 0x000000, 0x479b04, 0x000000, 0x479f01, 0x000000, 0x000000, 0x000000, 0x000000, + 0x47a003, 0x000000, 0x47a301, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x47a403, 0x000000, 0x47a701, 0x47a801, + 0x000000, 0x47a902, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x47ab03, + 0x000000, 0x47ae05, 0x000000, 0x000000, 0x47b301, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x47b40a, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x47be01, 0x000000, 0x000000, 0x000000, 0x47bf01, 0x000000, 0x47c001, + 0x000000, 0x47c101, 0x47c242, 0x000000, 0x000000, 0x000000, 0x480407, 0x480b01, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x480c05, 0x481101, + 0x000000, 0x000000, 0x000000, 0x000000, 0x481201, 0x000000, 0x481301, 0x000000, + 0x000000, 0x000000, 0x481402, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x481601, 0x000000, 0x000000, 0x000000, 0x481701, 0x000000, 0x481803, 0x000000, + 0x481b01, 0x000000, 0x000000, 0x481c05, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x482101, 0x000000, 0x000000, 0x482206, + 0x000000, 0x000000, 0x000000, 0x000000, 0x482803, 0x000000, 0x000000, 0x000000, + 0x482b01, 0x000000, 0x482c01, 0x000000, 0x000000, 0x000000, 0x482d01, 0x482e01, + 0x482f05, 0x000000, 0x000000, 0x000000, 0x483401, 0x000000, 0x000000, 0x000000, + 0x483502, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x483702, + 0x483901, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x483a04, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x483e01, 0x000000, 0x000000, + 0x483f09, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x484810, + 0x000000, 0x485801, 0x000000, 0x485901, 0x485a02, 0x000000, 0x000000, 0x000000, + 0x485c01, 0x485d01, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x485e05, + 0x000000, 0x000000, 0x000000, 0x000000, 0x486301, 0x486401, 0x000000, 0x486501, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x486602, 0x486801, + 0x000000, 0x486902, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x486b01, 0x486c01, 0x486d01, 0x486e03, 0x000000, 0x487107, 0x000000, 0x000000, + 0x000000, 0x000000, 0x487803, 0x487b02, 0x000000, 0x000000, 0x487d0b, 0x000000, + 0x000000, 0x488802, 0x488a01, 0x000000, 0x000000, 0x000000, 0x488b02, 0x000000, + 0x488d0c, 0x000000, 0x000000, 0x000000, 0x000000, 0x489902, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x489b01, 0x000000, 0x000000, 0x489c01, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x489d02, 0x000000, 0x489f02, + 0x000000, 0x000000, 0x000000, 0x000000, 0x48a102, 0x000000, 0x000000, 0x000000, + 0x48a301, 0x000000, 0x000000, 0x48a401, 0x48a503, 0x000000, 0x000000, 0x48a801, + 0x000000, 0x000000, 0x000000, 0x000000, 0x48a901, 0x000000, 0x000000, 0x000000, + 0x48aa01, 0x48ab01, 0x000000, 0x48ac03, 0x000000, 0x000000, 0x000000, 0x000000, + 0x48af03, 0x000000, 0x000000, 0x48b201, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x48b304, 0x000000, 0x48b701, + 0x000000, 0x000000, 0x48b802, 0x48ba09, 0x000000, 0x000000, 0x000000, 0x48c301, + 0x000000, 0x000000, 0x000000, 0x48c401, 0x000000, 0x000000, 0x48c501, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x48c601, 0x000000, + 0x48c703, 0x000000, 0x000000, 0x48ca02, 0x48cc04, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x48d002, 0x48d205, 0x48d704, 0x000000, 0x48db01, + 0x000000, 0x000000, 0x48dc02, 0x000000, 0x48de01, 0x48df01, 0x000000, 0x000000, + 0x000000, 0x48e009, 0x000000, 0x000000, 0x48e908, 0x48f103, 0x000000, 0x000000, + 0x000000, 0x000000, 0x48f407, 0x48fb01, 0x48fc01, 0x000000, 0x000000, 0x48fd04, + 0x000000, 0x000000, 0x490105, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x490601, 0x490701, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x490803, 0x000000, + 0x000000, 0x490b02, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x490d06, 0x000000, 0x491301, 0x000000, 0x000000, 0x491401, 0x000000, 0x491501, + 0x000000, 0x000000, 0x491603, 0x000000, 0x491904, 0x000000, 0x000000, 0x491d01, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x491e03, 0x000000, + 0x000000, 0x492104, 0x000000, 0x492505, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x492a08, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x493202, + 0x493401, 0x000000, 0x000000, 0x493501, 0x000000, 0x493601, 0x493702, 0x493902, + 0x493b04, 0x000000, 0x493f01, 0x494001, 0x000000, 0x000000, 0x494109, 0x494a02, + 0x000000, 0x494c01, 0x000000, 0x000000, 0x000000, 0x494d03, 0x000000, 0x000000, + 0x000000, 0x495004, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x495405, + 0x495901, 0x495a02, 0x495c03, 0x000000, 0x000000, 0x495f03, 0x496201, 0x000000, + 0x496305, 0x000000, 0x496802, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x496a05, 0x000000, 0x000000, 0x496f01, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x497003, 0x497302, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x497505, 0x000000, 0x000000, 0x000000, 0x497a04, + 0x497e01, 0x497f09, 0x000000, 0x000000, 0x000000, 0x000000, 0x498802, 0x000000, + 0x000000, 0x498a02, 0x498c01, 0x000000, 0x000000, 0x498d01, 0x000000, 0x000000, + 0x000000, 0x000000, 0x498e01, 0x000000, 0x000000, 0x498f01, 0x000000, 0x000000, + 0x000000, 0x000000, 0x499007, 0x000000, 0x499701, 0x000000, 0x499801, 0x000000, + 0x499901, 0x000000, 0x000000, 0x000000, 0x000000, 0x499a01, 0x000000, 0x499b01, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x499c01, 0x499d02, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x499f05, 0x000000, 0x000000, 0x000000, 0x49a407, + 0x49ab02, 0x000000, 0x000000, 0x49ad04, 0x49b101, 0x000000, 0x000000, 0x49b202, + 0x49b405, 0x000000, 0x000000, 0x49b907, 0x49c00a, 0x49ca01, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x49cb03, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x49ce01, 0x000000, 0x49cf04, 0x000000, 0x000000, 0x000000, 0x49d301, + 0x000000, 0x000000, 0x000000, 0x49d401, 0x000000, 0x49d50d, 0x49e201, 0x49e303, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x49e601, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x49e701, 0x000000, + 0x000000, 0x000000, 0x49e808, 0x49f001, 0x000000, 0x000000, 0x000000, 0x000000, + 0x49f102, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x49f302, + 0x000000, 0x000000, 0x000000, 0x000000, 0x49f508, 0x49fd09, 0x000000, 0x000000, + 0x000000, 0x4a0606, 0x4a0c01, 0x000000, 0x000000, 0x000000, 0x000000, 0x4a0d01, + 0x000000, 0x000000, 0x000000, 0x000000, 0x4a0e01, 0x4a0f01, 0x000000, 0x000000, + 0x4a1001, 0x000000, 0x000000, 0x4a1101, 0x000000, 0x000000, 0x000000, 0x000000, + 0x4a1201, 0x4a1301, 0x000000, 0x000000, 0x000000, 0x4a1402, 0x000000, 0x4a1601, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x4a1701, 0x000000, 0x4a1801, 0x000000, 0x4a1903, 0x4a1c03, 0x4a1f01, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x4a2004, 0x000000, + 0x000000, 0x000000, 0x4a2409, 0x000000, 0x000000, 0x000000, 0x4a2d08, 0x000000, + 0x4a3501, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x4a3604, 0x4a3a02, + 0x000000, 0x000000, 0x4a3c01, 0x000000, 0x000000, 0x000000, 0x4a3d02, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x4a3f03, 0x4a4207, 0x000000, + 0x000000, 0x4a4901, 0x000000, 0x000000, 0x4a4a05, 0x000000, 0x4a4f07, 0x000000, + 0x4a5601, 0x4a5707, 0x000000, 0x4a5e02, 0x000000, 0x4a6009, 0x4a6901, 0x000000, + 0x000000, 0x000000, 0x4a6a04, 0x4a6e01, 0x4a6f03, 0x000000, 0x4a7204, 0x4a7601, + 0x4a7718, 0x000000, 0x000000, 0x4a8f05, 0x000000, 0x000000, 0x000000, 0x4a9401, + 0x4a9501, 0x000000, 0x000000, 0x000000, 0x000000, 0x4a9601, 0x000000, 0x4a9701, + 0x000000, 0x000000, 0x000000, 0x4a9801, 0x000000, 0x000000, 0x4a9901, 0x000000, + 0x4a9a01, 0x4a9b03, 0x000000, 0x000000, 0x4a9e08, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x4aa601, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x4aa704, 0x000000, 0x000000, 0x000000, 0x4aab01, + 0x4aac04, 0x000000, 0x4ab001, 0x4ab101, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x4ab201, 0x4ab301, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x4ab401, 0x4ab502, 0x000000, 0x4ab701, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x4ab801, 0x4ab901, 0x4aba01, 0x4abb0e, 0x000000, 0x000000, 0x4ac901, + 0x000000, 0x000000, 0x4aca09, 0x4ad302, 0x4ad518, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x4aed03, 0x4af002, 0x000000, + 0x000000, 0x4af206, 0x000000, 0x000000, 0x000000, 0x4af801, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x4af903, 0x000000, 0x4afc01, 0x000000, 0x000000, + 0x000000, 0x000000, 0x4afd04, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x4b0101, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x4b0202, 0x000000, + 0x4b0405, 0x4b0903, 0x000000, 0x000000, 0x000000, 0x4b0c05, 0x000000, 0x4b1105, + 0x000000, 0x000000, 0x000000, 0x4b1606, 0x4b1c01, 0x000000, 0x000000, 0x4b1d01, + 0x000000, 0x000000, 0x4b1e01, 0x4b1f01, 0x4b2006, 0x4b2601, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x4b2708, 0x000000, 0x4b2f01, 0x4b3005, 0x000000, + 0x000000, 0x000000, 0x000000, 0x4b3502, 0x000000, 0x4b3702, 0x4b3901, 0x4b3a02, + 0x000000, 0x000000, 0x4b3c05, 0x000000, 0x4b4106, 0x000000, 0x000000, 0x000000, + 0x4b4706, 0x000000, 0x4b4d03, 0x4b5001, 0x4b5101, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x4b5201, 0x000000, 0x000000, 0x4b5301, 0x000000, 0x000000, 0x4b5402, + 0x4b5601, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x4b5703, + 0x4b5a01, 0x000000, 0x4b5b05, 0x000000, 0x000000, 0x000000, 0x000000, 0x4b6001, + 0x000000, 0x4b6104, 0x000000, 0x000000, 0x000000, 0x000000, 0x4b6501, 0x4b6601, + 0x000000, 0x000000, 0x000000, 0x000000, 0x4b6701, 0x4b6809, 0x000000, 0x000000, + 0x000000, 0x000000, 0x4b7101, 0x000000, 0x000000, 0x4b7206, 0x000000, 0x000000, + 0x4b7801, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x4b790b, 0x000000, 0x4b8401, 0x000000, 0x4b8501, 0x4b8601, 0x000000, 0x4b8701, + 0x4b8809, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x4b9107, 0x000000, 0x000000, 0x4b9801, + 0x000000, 0x4b9908, 0x4ba104, 0x000000, 0x4ba501, 0x4ba602, 0x000000, 0x000000, + 0x4ba806, 0x000000, 0x4bae02, 0x000000, 0x4bb003, 0x4bb308, 0x4bbb01, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x4bbc01, 0x4bbd02, 0x000000, 0x000000, + 0x000000, 0x000000, 0x4bbf0a, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x4bc90a, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x4bd301, 0x000000, 0x000000, 0x4bd409, 0x4bdd02, 0x000000, 0x4bdf01, + 0x000000, 0x000000, 0x000000, 0x4be003, 0x000000, 0x000000, 0x000000, 0x4be303, + 0x000000, 0x000000, 0x000000, 0x000000, 0x4be601, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x4be710, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x4bf70b, 0x4c0202, 0x000000, 0x000000, 0x4c0401, 0x000000, 0x4c0501, 0x4c0604, + 0x000000, 0x4c0a07, 0x4c1108, 0x4c190c, 0x000000, 0x000000, 0x000000, 0x000000, + 0x4c2507, 0x000000, 0x000000, 0x000000, 0x000000, 0x4c2c01, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x4c2d02, 0x4c2f01, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x4c3001, 0x000000, 0x000000, 0x000000, 0x000000, 0x4c3101, 0x4c3201, + 0x000000, 0x000000, 0x000000, 0x4c3303, 0x000000, 0x000000, 0x4c3603, 0x000000, + 0x000000, 0x4c3901, 0x000000, 0x4c3a01, 0x000000, 0x4c3b02, 0x000000, 0x4c3d0c, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x4c4907, 0x000000, 0x4c5001, 0x4c5105, 0x000000, 0x4c5603, + 0x4c5901, 0x000000, 0x4c5a04, 0x4c5e01, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x4c5f01, 0x4c6002, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x4c6201, 0x000000, 0x000000, 0x4c6304, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x4c6701, 0x4c6801, 0x000000, 0x000000, 0x4c6903, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x4c6c02, 0x4c6e01, 0x000000, 0x4c6f01, 0x000000, + 0x000000, 0x000000, 0x4c7001, 0x4c7108, 0x000000, 0x4c7902, 0x000000, 0x000000, + 0x000000, 0x000000, 0x4c7b01, 0x000000, 0x000000, 0x000000, 0x000000, 0x4c7c03, + 0x4c7f01, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x4c8001, 0x4c8101, 0x000000, 0x000000, 0x000000, 0x4c8201, 0x4c8301, 0x000000, + 0x4c8403, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x4c8701, + 0x4c8806, 0x4c8e01, 0x000000, 0x4c8f04, 0x000000, 0x000000, 0x4c9301, 0x000000, + 0x000000, 0x4c9401, 0x000000, 0x4c9502, 0x4c9702, 0x4c9903, 0x000000, 0x4c9c01, + 0x4c9d02, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x4c9f01, + 0x4ca001, 0x000000, 0x000000, 0x4ca101, 0x000000, 0x000000, 0x4ca201, 0x000000, + 0x000000, 0x000000, 0x4ca301, 0x4ca40a, 0x4cae01, 0x000000, 0x000000, 0x4caf02, + 0x4cb102, 0x4cb307, 0x000000, 0x4cba01, 0x000000, 0x000000, 0x4cbb0e, 0x4cc901, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x4cca10, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x4cda02, 0x4cdc02, 0x000000, 0x000000, 0x000000, 0x000000, 0x4cde04, 0x000000, + 0x4ce201, 0x000000, 0x4ce303, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x4ce601, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x4ce701, 0x4ce803, 0x4ceb03, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x4cee02, 0x4cf001, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x4cf101, 0x4cf201, 0x000000, 0x000000, 0x4cf302, + 0x000000, 0x4cf501, 0x000000, 0x000000, 0x4cf601, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x4cf704, 0x4cfb02, 0x000000, 0x4cfd03, 0x000000, + 0x4d0002, 0x000000, 0x000000, 0x000000, 0x4d0203, 0x000000, 0x000000, 0x000000, + 0x000000, 0x4d0502, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x4d0702, 0x000000, 0x4d0903, 0x000000, 0x000000, 0x4d0c05, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x4d1101, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x4d1203, 0x000000, 0x4d1501, 0x4d1604, 0x4d1a01, 0x000000, + 0x000000, 0x4d1b01, 0x000000, 0x4d1c05, 0x000000, 0x000000, 0x000000, 0x4d2101, + 0x000000, 0x000000, 0x4d2218, 0x000000, 0x4d3a01, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x4d3b03, 0x4d3e03, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x4d4101, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x4d4201, 0x000000, 0x000000, 0x4d430a, 0x4d4d01, + 0x000000, 0x4d4e01, 0x000000, 0x000000, 0x4d4f01, 0x000000, 0x000000, 0x000000, + 0x4d5003, 0x000000, 0x000000, 0x4d5301, 0x4d5402, 0x000000, 0x000000, 0x000000, + 0x4d5602, 0x000000, 0x000000, 0x000000, 0x4d5802, 0x000000, 0x000000, 0x000000, + 0x000000, 0x4d5a01, 0x000000, 0x4d5b01, 0x000000, 0x4d5c02, 0x000000, 0x000000, + 0x4d5e01, 0x000000, 0x000000, 0x000000, 0x4d5f01, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x4d6007, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x4d6705, 0x000000, 0x4d6c01, + 0x000000, 0x4d6d08, 0x4d7501, 0x4d7602, 0x000000, 0x000000, 0x000000, 0x4d7805, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x4d7d01, 0x000000, 0x000000, 0x000000, 0x000000, 0x4d7e04, + 0x000000, 0x000000, 0x4d8202, 0x000000, 0x000000, 0x000000, 0x000000, 0x4d8402, + 0x000000, 0x000000, 0x000000, 0x000000, 0x4d8601, 0x000000, 0x000000, 0x4d8701, + 0x000000, 0x4d8802, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x4d8a03, 0x000000, 0x000000, 0x000000, 0x4d8d0a, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x4d9701, + 0x000000, 0x4d9801, 0x000000, 0x4d9902, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x4d9b02, 0x000000, 0x000000, 0x4d9d01, 0x000000, + 0x000000, 0x4d9e01, 0x000000, 0x000000, 0x4d9f01, 0x4da002, 0x4da205, 0x000000, + 0x4da702, 0x4da902, 0x4dab01, 0x000000, 0x000000, 0x4dac01, 0x4dad02, 0x4daf02, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x4db102, 0x4db301, 0x4db401, 0x000000, + 0x000000, 0x4db501, 0x000000, 0x000000, 0x000000, 0x4db601, 0x000000, 0x4db706, + 0x4dbd01, 0x000000, 0x000000, 0x4dbe02, 0x000000, 0x000000, 0x4dc001, 0x000000, + 0x000000, 0x000000, 0x4dc102, 0x000000, 0x4dc301, 0x000000, 0x4dc402, 0x4dc602, + 0x000000, 0x000000, 0x000000, 0x4dc807, 0x4dcf12, 0x000000, 0x4de101, 0x4de201, + 0x4de302, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x4de501, 0x000000, 0x4de602, 0x000000, 0x4de806, 0x000000, 0x000000, 0x000000, + 0x4dee01, 0x4def02, 0x4df106, 0x4df705, 0x000000, 0x4dfc06, 0x000000, 0x4e0204, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x4e0601, 0x000000, 0x4e070e, + 0x000000, 0x4e1501, 0x000000, 0x000000, 0x4e1602, 0x000000, 0x4e1802, 0x000000, + 0x4e1a03, 0x000000, 0x000000, 0x000000, 0x4e1d01, 0x4e1e02, 0x4e2002, 0x000000, + 0x4e2202, 0x4e2406, 0x000000, 0x4e2a01, 0x4e2b02, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x4e2d06, 0x000000, 0x4e3301, 0x000000, 0x000000, + 0x000000, 0x000000, 0x4e3402, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x4e3601, 0x4e3701, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x4e3802, + 0x000000, 0x000000, 0x4e3a02, 0x000000, 0x000000, 0x4e3c03, 0x000000, 0x000000, + 0x4e3f0c, 0x000000, 0x000000, 0x000000, 0x000000, 0x4e4b01, 0x4e4c03, 0x000000, + 0x4e4f01, 0x4e5001, 0x000000, 0x000000, 0x4e5102, 0x000000, 0x4e5302, 0x000000, + 0x000000, 0x4e5503, 0x4e5802, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x4e5a02, 0x000000, 0x000000, 0x4e5c01, + 0x000000, 0x4e5d02, 0x000000, 0x4e5f02, 0x000000, 0x000000, 0x4e6101, 0x000000, + 0x000000, 0x4e6202, 0x000000, 0x000000, 0x000000, 0x000000, 0x4e6401, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x4e6501, 0x4e6601, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x4e6701, 0x000000, 0x000000, 0x4e6801, 0x4e6901, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x4e6a03, 0x000000, 0x4e6d02, 0x000000, + 0x000000, 0x000000, 0x000000, 0x4e6f01, 0x000000, 0x4e700e, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x4e7e03, 0x000000, 0x4e8109, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x4e8a05, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x4e8f01, + 0x000000, 0x000000, 0x000000, 0x4e9001, 0x4e9101, 0x000000, 0x000000, 0x000000, + 0x4e9208, 0x4e9a01, 0x4e9b07, 0x000000, 0x000000, 0x000000, 0x4ea202, 0x4ea401, + 0x4ea502, 0x000000, 0x000000, 0x000000, 0x000000, 0x4ea701, 0x000000, 0x000000, + 0x4ea801, 0x4ea90c, 0x4eb502, 0x000000, 0x4eb701, 0x000000, 0x000000, 0x000000, + 0x4eb801, 0x000000, 0x000000, 0x4eb904, 0x000000, 0x000000, 0x000000, 0x4ebd05, + 0x000000, 0x4ec201, 0x000000, 0x000000, 0x4ec302, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x4ec502, 0x000000, 0x4ec702, 0x000000, + 0x4ec905, 0x000000, 0x4ece03, 0x000000, 0x000000, 0x4ed12d, 0x000000, 0x000000, + 0x000000, 0x000000, 0x4efe01, 0x000000, 0x000000, 0x000000, 0x000000, 0x4eff02, + 0x000000, 0x4f0104, 0x000000, 0x000000, 0x4f0501, 0x000000, 0x4f0601, 0x000000, + 0x000000, 0x000000, 0x000000, 0x4f0701, 0x000000, 0x000000, 0x4f0801, 0x4f090a, + 0x000000, 0x4f1303, 0x000000, 0x4f1602, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x4f1801, 0x000000, 0x000000, 0x000000, 0x4f1901, 0x000000, + 0x000000, 0x000000, 0x000000, 0x4f1a02, 0x000000, 0x4f1c01, 0x000000, 0x4f1d02, + 0x000000, 0x000000, 0x000000, 0x000000, 0x4f1f08, 0x000000, 0x000000, 0x4f2702, + 0x000000, 0x000000, 0x000000, 0x000000, 0x4f290c, 0x000000, 0x000000, 0x000000, + 0x4f3501, 0x000000, 0x000000, 0x4f3603, 0x4f3901, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x4f3a01, 0x000000, 0x4f3b01, 0x000000, 0x4f3c02, 0x000000, + 0x4f3e03, 0x4f4102, 0x000000, 0x000000, 0x000000, 0x000000, 0x4f4301, 0x000000, + 0x000000, 0x000000, 0x000000, 0x4f4404, 0x4f4802, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x4f4a01, 0x000000, 0x4f4b03, 0x4f4e04, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x4f5201, 0x000000, 0x000000, + 0x4f5301, 0x000000, 0x4f5401, 0x000000, 0x4f5502, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x4f5702, 0x000000, 0x000000, 0x000000, 0x4f5901, + 0x000000, 0x000000, 0x000000, 0x000000, 0x4f5a01, 0x4f5b06, 0x000000, 0x4f6111, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x4f7203, 0x000000, + 0x000000, 0x000000, 0x4f750a, 0x000000, 0x000000, 0x000000, 0x000000, 0x4f7f0a, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x4f8903, 0x000000, 0x000000, 0x4f8c0a, 0x000000, 0x4f9602, + 0x4f9801, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x4f9901, 0x4f9a01, 0x000000, 0x4f9b01, + 0x000000, 0x000000, 0x4f9c01, 0x000000, 0x4f9d01, 0x000000, 0x4f9e05, 0x000000, + 0x4fa302, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x4fa502, + 0x4fa701, 0x4fa802, 0x000000, 0x000000, 0x4faa01, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x4fab02, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x4fad11, 0x4fbe02, 0x000000, 0x000000, 0x000000, + 0x4fc003, 0x000000, 0x000000, 0x4fc306, 0x000000, 0x000000, 0x4fc902, 0x4fcb03, + 0x000000, 0x4fce01, 0x000000, 0x000000, 0x4fcf01, 0x000000, 0x4fd001, 0x4fd101, + 0x4fd205, 0x000000, 0x000000, 0x000000, 0x000000, 0x4fd702, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x4fd901, 0x000000, 0x4fda03, 0x000000, 0x4fdd02, + 0x000000, 0x000000, 0x000000, 0x000000, 0x4fdf03, 0x000000, 0x4fe201, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x4fe301, 0x4fe401, 0x000000, 0x000000, 0x4fe503, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x4fe801, 0x000000, 0x4fe907, 0x000000, 0x000000, + 0x000000, 0x4ff004, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x4ff404, + 0x000000, 0x000000, 0x000000, 0x4ff803, 0x000000, 0x4ffb01, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x4ffc08, 0x000000, + 0x000000, 0x500401, 0x000000, 0x000000, 0x500501, 0x000000, 0x000000, 0x500609, + 0x000000, 0x500f01, 0x000000, 0x501001, 0x000000, 0x000000, 0x501101, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x501201, 0x501301, 0x000000, 0x501413, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x502707, 0x502e02, 0x000000, 0x50300a, 0x000000, 0x000000, + 0x000000, 0x000000, 0x503a01, 0x000000, 0x000000, 0x503b03, 0x000000, 0x000000, + 0x000000, 0x503e03, 0x000000, 0x000000, 0x000000, 0x504102, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x50430f, 0x000000, 0x000000, 0x505201, 0x000000, + 0x000000, 0x505302, 0x000000, 0x505517, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x506c01, 0x000000, 0x000000, 0x000000, 0x000000, 0x506d03, 0x000000, + 0x000000, 0x507001, 0x507101, 0x000000, 0x000000, 0x000000, 0x000000, 0x507202, + 0x000000, 0x507401, 0x507514, 0x000000, 0x000000, 0x000000, 0x508902, 0x508b01, + 0x000000, 0x000000, 0x000000, 0x000000, 0x508c06, 0x000000, 0x000000, 0x000000, + 0x000000, 0x509201, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x509301, + 0x000000, 0x000000, 0x000000, 0x509401, 0x000000, 0x509509, 0x000000, 0x000000, + 0x509e44, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x50e202, 0x000000, + 0x000000, 0x50e404, 0x000000, 0x000000, 0x000000, 0x50e801, 0x50e90a, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x50f301, 0x50f401, 0x000000, 0x000000, + 0x000000, 0x000000, 0x50f502, 0x50f701, 0x50f804, 0x000000, 0x50fc01, 0x000000, + 0x50fd01, 0x000000, 0x50fe01, 0x50ff01, 0x000000, 0x510007, 0x000000, 0x000000, + 0x510701, 0x000000, 0x510803, 0x000000, 0x510b01, 0x000000, 0x000000, 0x510c01, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x510d04, 0x000000, 0x000000, 0x000000, 0x000000, 0x511107, 0x000000, 0x000000, + 0x000000, 0x511802, 0x000000, 0x000000, 0x511a03, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x511d01, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x511e01, 0x000000, 0x000000, 0x000000, 0x000000, + 0x511f01, 0x000000, 0x512008, 0x512808, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x513001, 0x000000, 0x000000, 0x000000, 0x513109, 0x513a06, + 0x514001, 0x000000, 0x514105, 0x000000, 0x514601, 0x000000, 0x000000, 0x514702, + 0x000000, 0x000000, 0x514901, 0x000000, 0x000000, 0x514a01, 0x000000, 0x514b01, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x514c05, 0x000000, 0x000000, + 0x515102, 0x515301, 0x515401, 0x000000, 0x000000, 0x000000, 0x515501, 0x000000, + 0x515603, 0x000000, 0x000000, 0x000000, 0x515903, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x515c01, 0x515d01, 0x515e01, 0x000000, + 0x515f04, 0x516303, 0x000000, 0x000000, 0x516601, 0x000000, 0x000000, 0x516702, + 0x516901, 0x000000, 0x516a01, 0x000000, 0x516b0a, 0x000000, 0x517501, 0x000000, + 0x000000, 0x000000, 0x517601, 0x000000, 0x000000, 0x000000, 0x000000, 0x51770d, + 0x000000, 0x000000, 0x000000, 0x518402, 0x000000, 0x000000, 0x518602, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x518803, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x518b04, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x518f02, 0x000000, 0x000000, 0x519101, 0x000000, 0x000000, + 0x000000, 0x000000, 0x519201, 0x519306, 0x000000, 0x000000, 0x519901, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x519a0e, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x51a801, 0x000000, + 0x51a904, 0x51ad02, 0x000000, 0x000000, 0x51af03, 0x51b201, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x51b301, 0x000000, 0x51b402, 0x000000, 0x51b601, + 0x51b702, 0x51b905, 0x000000, 0x51be01, 0x000000, 0x51bf01, 0x51c001, 0x51c105, + 0x000000, 0x000000, 0x51c604, 0x000000, 0x000000, 0x51ca02, 0x000000, 0x000000, + 0x51cc02, 0x000000, 0x000000, 0x000000, 0x51ce03, 0x000000, 0x000000, 0x000000, + 0x51d101, 0x51d203, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x51d504, + 0x000000, 0x51d901, 0x000000, 0x000000, 0x51da09, 0x51e303, 0x000000, 0x000000, + 0x51e606, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x51ec02, 0x51ee09, + 0x000000, 0x000000, 0x000000, 0x51f703, 0x000000, 0x51fa01, 0x51fb01, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x51fc06, 0x000000, 0x000000, 0x000000, + 0x520203, 0x000000, 0x520501, 0x000000, 0x520601, 0x000000, 0x000000, 0x000000, + 0x000000, 0x520701, 0x520807, 0x000000, 0x000000, 0x000000, 0x000000, 0x520f02, + 0x000000, 0x521106, 0x000000, 0x521701, 0x000000, 0x000000, 0x000000, 0x521801, + 0x521903, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x521c05, 0x522101, + 0x522201, 0x522301, 0x000000, 0x000000, 0x522401, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x522501, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x522601, 0x522705, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x522c01, + 0x000000, 0x000000, 0x522d01, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x522e02, 0x000000, 0x523005, 0x000000, + 0x523501, 0x523602, 0x000000, 0x000000, 0x000000, 0x523804, 0x523c04, 0x000000, + 0x000000, 0x524007, 0x524701, 0x524801, 0x000000, 0x000000, 0x524901, 0x524a02, + 0x000000, 0x000000, 0x000000, 0x524c02, 0x000000, 0x000000, 0x000000, 0x524e01, + 0x524f01, 0x000000, 0x000000, 0x525001, 0x000000, 0x525104, 0x000000, 0x000000, + 0x525501, 0x000000, 0x000000, 0x000000, 0x000000, 0x525601, 0x000000, 0x000000, + 0x525701, 0x525805, 0x000000, 0x000000, 0x525d01, 0x525e02, 0x000000, 0x526002, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x526202, + 0x000000, 0x526401, 0x000000, 0x526501, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x526601, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x526702, 0x000000, 0x526901, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x526a01, 0x000000, 0x000000, 0x526b01, + 0x526c01, 0x526d01, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x526e01, + 0x000000, 0x526f01, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x527003, + 0x527301, 0x527403, 0x000000, 0x000000, 0x527701, 0x527802, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x527a07, 0x528101, 0x528202, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x528404, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x528802, 0x528a03, 0x000000, + 0x000000, 0x528d03, 0x000000, 0x000000, 0x000000, 0x529005, 0x529501, 0x000000, + 0x529601, 0x000000, 0x000000, 0x529701, 0x000000, 0x529801, 0x529906, 0x000000, + 0x529f02, 0x52a101, 0x52a201, 0x52a304, 0x000000, 0x000000, 0x000000, 0x52a701, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x52a803, 0x000000, + 0x52ab02, 0x000000, 0x52ad04, 0x000000, 0x000000, 0x000000, 0x000000, 0x52b101, + 0x000000, 0x000000, 0x000000, 0x000000, 0x52b201, 0x000000, 0x000000, 0x52b302, + 0x000000, 0x52b501, 0x000000, 0x52b601, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x52b703, 0x52ba09, 0x52c301, 0x000000, 0x000000, 0x000000, 0x52c401, + 0x000000, 0x000000, 0x52c502, 0x000000, 0x000000, 0x000000, 0x52c701, 0x000000, + 0x000000, 0x52c805, 0x000000, 0x000000, 0x000000, 0x52cd0e, 0x000000, 0x52db01, + 0x000000, 0x000000, 0x52dc02, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x52de01, 0x52df07, 0x000000, 0x000000, 0x52e602, 0x52e801, 0x000000, + 0x52e901, 0x000000, 0x000000, 0x000000, 0x000000, 0x52ea01, 0x52eb01, 0x000000, + 0x000000, 0x52ec01, 0x000000, 0x000000, 0x000000, 0x000000, 0x52ed06, 0x52f301, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x52f401, 0x000000, 0x000000, + 0x52f501, 0x52f611, 0x000000, 0x000000, 0x000000, 0x000000, 0x530701, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x530802, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x530a04, 0x000000, 0x000000, 0x000000, + 0x530e09, 0x000000, 0x531702, 0x000000, 0x531908, 0x000000, 0x532101, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x53220b, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x532d03, 0x000000, 0x000000, 0x533001, 0x000000, 0x000000, 0x000000, 0x000000, + 0x533101, 0x000000, 0x000000, 0x000000, 0x533201, 0x000000, 0x533302, 0x53350e, + 0x000000, 0x534302, 0x000000, 0x534504, 0x534901, 0x534a01, 0x000000, 0x534b02, + 0x000000, 0x534d01, 0x000000, 0x000000, 0x000000, 0x534e01, 0x534f18, 0x000000, + 0x000000, 0x000000, 0x536702, 0x000000, 0x000000, 0x536907, 0x537001, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x537101, 0x000000, 0x000000, 0x000000, + 0x537203, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x537501, 0x000000, 0x000000, 0x537605, 0x537b02, 0x537d01, + 0x000000, 0x000000, 0x000000, 0x537e02, 0x538001, 0x000000, 0x538102, 0x000000, + 0x000000, 0x000000, 0x538301, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x538401, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x538501, 0x000000, 0x538601, 0x000000, + 0x000000, 0x538701, 0x000000, 0x000000, 0x538804, 0x000000, 0x000000, 0x000000, + 0x000000, 0x538c01, 0x538d07, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x539401, 0x539501, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x539601, 0x000000, 0x539702, 0x000000, + 0x000000, 0x000000, 0x000000, 0x539901, 0x000000, 0x000000, 0x000000, 0x539a01, + 0x539b01, 0x000000, 0x539c01, 0x539d01, 0x000000, 0x000000, 0x000000, 0x539e01, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x539f01, 0x000000, 0x000000, 0x000000, + 0x000000, 0x53a00c, 0x000000, 0x53ac01, 0x000000, 0x53ad03, 0x000000, 0x000000, + 0x000000, 0x53b003, 0x53b301, 0x000000, 0x000000, 0x000000, 0x000000, 0x53b404, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x53b801, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x53b909, 0x000000, 0x53c201, 0x000000, 0x53c305, 0x53c803, 0x000000, 0x53cb01, + 0x000000, 0x53cc01, 0x53cd03, 0x000000, 0x000000, 0x000000, 0x53d001, 0x000000, + 0x000000, 0x53d102, 0x000000, 0x000000, 0x000000, 0x53d301, 0x53d403, 0x000000, + 0x000000, 0x53d709, 0x000000, 0x000000, 0x000000, 0x53e005, 0x53e501, 0x000000, + 0x000000, 0x53e602, 0x000000, 0x000000, 0x53e802, 0x53ea01, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x53eb01, 0x000000, + 0x000000, 0x53ec01, 0x53ed02, 0x000000, 0x000000, 0x53ef23, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x541202, 0x000000, 0x000000, 0x541401, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x541503, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x541801, 0x541901, + 0x000000, 0x000000, 0x541a02, 0x000000, 0x000000, 0x541c06, 0x000000, 0x000000, + 0x542219, 0x543b03, 0x000000, 0x543e08, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x544602, 0x000000, 0x000000, 0x000000, + 0x000000, 0x54480e, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x54560d, + 0x000000, 0x000000, 0x546301, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x546401, 0x000000, 0x54650b, 0x000000, + 0x000000, 0x547001, 0x547101, 0x547201, 0x547303, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x547608, 0x000000, 0x000000, 0x000000, 0x000000, 0x547e04, + 0x000000, 0x548204, 0x000000, 0x000000, 0x000000, 0x000000, 0x548607, 0x548d07, + 0x549409, 0x549d01, 0x000000, 0x000000, 0x549e01, 0x549f02, 0x000000, 0x54a101, + 0x000000, 0x000000, 0x54a203, 0x000000, 0x54a502, 0x54a701, 0x54a801, 0x000000, + 0x54a909, 0x54b201, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x54b30a, + 0x000000, 0x54bd01, 0x000000, 0x000000, 0x000000, 0x000000, 0x54be05, 0x54c303, + 0x000000, 0x54c601, 0x000000, 0x54c705, 0x000000, 0x000000, 0x54cc01, 0x000000, + 0x000000, 0x000000, 0x54cd01, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x54ce01, 0x000000, 0x000000, 0x000000, 0x54cf05, + 0x000000, 0x54d40d, 0x000000, 0x54e101, 0x000000, 0x000000, 0x000000, 0x54e202, + 0x54e404, 0x000000, 0x000000, 0x000000, 0x000000, 0x54e804, 0x54ec01, 0x54ed05, + 0x000000, 0x54f202, 0x000000, 0x000000, 0x000000, 0x54f401, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x54f502, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x54f701, 0x000000, 0x000000, 0x000000, 0x000000, 0x54f802, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x54fa01, 0x54fb01, 0x000000, + 0x54fc03, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x54ff03, + 0x000000, 0x000000, 0x550201, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x550302, 0x000000, 0x000000, 0x550501, + 0x000000, 0x000000, 0x550606, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x550c01, 0x000000, 0x550d01, 0x000000, + 0x000000, 0x550e01, 0x000000, 0x000000, 0x000000, 0x000000, 0x550f01, 0x000000, + 0x000000, 0x551003, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x551307, 0x551a01, 0x551b03, 0x551e06, 0x000000, + 0x000000, 0x000000, 0x552408, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x552c01, 0x000000, 0x000000, 0x000000, 0x000000, 0x552d01, 0x000000, 0x552e02, + 0x553001, 0x000000, 0x553101, 0x553206, 0x000000, 0x553802, 0x553a01, 0x553b03, + 0x000000, 0x553e01, 0x000000, 0x553f01, 0x000000, 0x000000, 0x554001, 0x000000, + 0x000000, 0x554106, 0x554701, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x55480f, 0x555701, 0x555812, 0x000000, 0x000000, 0x556a03, 0x556d01, 0x556e02, + 0x557001, 0x000000, 0x000000, 0x000000, 0x557101, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x557203, 0x000000, + 0x557501, 0x000000, 0x000000, 0x000000, 0x557602, 0x000000, 0x557805, 0x557d01, + 0x000000, 0x000000, 0x000000, 0x000000, 0x557e01, 0x000000, 0x000000, 0x557f06, + 0x558501, 0x558602, 0x558804, 0x000000, 0x558c03, 0x000000, 0x558f02, 0x000000, + 0x000000, 0x559103, 0x000000, 0x000000, 0x000000, 0x559401, 0x559501, 0x559601, + 0x000000, 0x000000, 0x559701, 0x000000, 0x000000, 0x559801, 0x559901, 0x559a04, + 0x000000, 0x559e02, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x55a001, 0x000000, 0x000000, 0x55a10b, 0x55ac06, 0x55b205, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x55b701, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x55b802, 0x000000, 0x55ba02, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x55bc01, 0x000000, 0x000000, + 0x000000, 0x55bd01, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x55be01, + 0x000000, 0x55bf02, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x55c103, 0x55c401, 0x000000, 0x000000, 0x000000, + 0x000000, 0x55c501, 0x000000, 0x55c603, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x55c901, 0x55ca01, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x55cb01, 0x55cc04, 0x000000, 0x000000, + 0x55d001, 0x55d104, 0x000000, 0x000000, 0x000000, 0x55d506, 0x000000, 0x000000, + 0x55db01, 0x55dc01, 0x000000, 0x55dd03, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x55e003, 0x000000, 0x55e304, 0x000000, 0x55e707, 0x000000, 0x55ee02, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x55f001, 0x000000, + 0x55f101, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x55f201, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x55f304, 0x000000, 0x000000, + 0x000000, 0x55f701, 0x000000, 0x55f806, 0x55fe01, 0x000000, 0x000000, 0x55ff01, + 0x000000, 0x000000, 0x000000, 0x560002, 0x560201, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x560301, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x560410, 0x561402, 0x000000, 0x561601, 0x000000, 0x000000, 0x000000, + 0x561708, 0x000000, 0x000000, 0x000000, 0x561f01, 0x562004, 0x000000, 0x000000, + 0x562402, 0x562601, 0x562703, 0x562a01, 0x000000, 0x000000, 0x562b01, 0x562c03, + 0x000000, 0x000000, 0x562f02, 0x000000, 0x000000, 0x000000, 0x000000, 0x563107, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x563801, + 0x000000, 0x000000, 0x000000, 0x563901, 0x563a01, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x563b01, 0x000000, 0x000000, 0x000000, + 0x000000, 0x563c07, 0x56430f, 0x565205, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x565703, 0x000000, 0x000000, 0x565a01, 0x000000, + 0x565b01, 0x000000, 0x565c01, 0x000000, 0x565d01, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x565e08, 0x566601, 0x000000, 0x566702, + 0x566903, 0x000000, 0x000000, 0x000000, 0x000000, 0x566c03, 0x000000, 0x000000, + 0x000000, 0x566f01, 0x56700c, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x567c01, 0x000000, 0x000000, 0x000000, 0x567d02, 0x000000, 0x000000, + 0x567f02, 0x568102, 0x000000, 0x568301, 0x568402, 0x568603, 0x568908, 0x000000, + 0x000000, 0x000000, 0x569102, 0x000000, 0x000000, 0x000000, 0x000000, 0x56930d, + 0x56a002, 0x000000, 0x000000, 0x000000, 0x000000, 0x56a203, 0x000000, 0x56a501, + 0x56a601, 0x000000, 0x000000, 0x56a704, 0x56ab02, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x56ad04, 0x000000, 0x56b107, + 0x56b807, 0x000000, 0x000000, 0x56bf01, 0x000000, 0x56c003, 0x000000, 0x56c303, + 0x000000, 0x000000, 0x56c608, 0x000000, 0x56ce08, 0x56d601, 0x000000, 0x000000, + 0x56d702, 0x000000, 0x56d901, 0x000000, 0x000000, 0x56da01, 0x56db01, 0x000000, + 0x56dc03, 0x000000, 0x56df01, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x56e001, 0x000000, 0x000000, 0x000000, 0x56e104, 0x56e501, 0x56e60c, 0x000000, + 0x000000, 0x000000, 0x56f209, 0x56fb01, 0x000000, 0x56fc01, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x56fd01, 0x000000, 0x000000, + 0x000000, 0x000000, 0x56fe01, 0x000000, 0x56ff05, 0x000000, 0x570401, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x570502, 0x570703, 0x570a03, 0x570d01, + 0x000000, 0x000000, 0x570e02, 0x571001, 0x000000, 0x000000, 0x571103, 0x000000, + 0x571402, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x571606, 0x000000, 0x571c01, 0x571d03, 0x000000, + 0x000000, 0x000000, 0x572003, 0x000000, 0x572307, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x572a02, + 0x000000, 0x000000, 0x000000, 0x572c11, 0x000000, 0x573d01, 0x000000, 0x000000, + 0x000000, 0x573e01, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x573f02, + 0x000000, 0x574106, 0x574703, 0x000000, 0x574a02, 0x574c01, 0x000000, 0x574d07, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x575401, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x575501, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x575601, 0x575701, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x575805, 0x575d03, 0x000000, 0x000000, 0x576001, 0x000000, + 0x576103, 0x576402, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x576602, + 0x000000, 0x576801, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x576903, + 0x000000, 0x000000, 0x000000, 0x000000, 0x576c01, 0x000000, 0x000000, 0x000000, + 0x000000, 0x576d01, 0x000000, 0x576e08, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x577601, 0x000000, 0x000000, + 0x577703, 0x577a01, 0x577b06, 0x578103, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x578401, 0x000000, 0x000000, 0x578502, 0x000000, 0x000000, 0x578701, + 0x000000, 0x000000, 0x578801, 0x57890e, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x579702, 0x000000, 0x000000, 0x000000, 0x000000, 0x579901, + 0x000000, 0x000000, 0x000000, 0x579a01, 0x000000, 0x579b04, 0x000000, 0x579f03, + 0x000000, 0x57a207, 0x57a901, 0x57aa01, 0x000000, 0x000000, 0x000000, 0x000000, + 0x57ab02, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x57ad08, 0x000000, + 0x57b501, 0x000000, 0x57b60a, 0x000000, 0x000000, 0x000000, 0x57c005, 0x000000, + 0x57c501, 0x000000, 0x57c601, 0x000000, 0x000000, 0x000000, 0x000000, 0x57c701, + 0x57c80e, 0x000000, 0x57d601, 0x000000, 0x000000, 0x000000, 0x57d701, 0x000000, + 0x000000, 0x000000, 0x000000, 0x57d80a, 0x000000, 0x000000, 0x57e20f, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x57f101, 0x000000, 0x000000, + 0x57f201, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x57f301, 0x000000, 0x000000, 0x000000, 0x57f403, 0x57f70e, 0x000000, 0x000000, + 0x000000, 0x580501, 0x000000, 0x000000, 0x580601, 0x000000, 0x000000, 0x580704, + 0x000000, 0x580b0d, 0x581802, 0x000000, 0x581a06, 0x000000, 0x000000, 0x000000, + 0x000000, 0x582001, 0x000000, 0x000000, 0x582104, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x582501, 0x000000, 0x000000, 0x000000, 0x000000, 0x582601, 0x582707, 0x000000, + 0x000000, 0x582e04, 0x000000, 0x583203, 0x000000, 0x583501, 0x583602, 0x583801, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x583901, 0x000000, 0x000000, + 0x583a03, 0x000000, 0x000000, 0x583d01, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x583e01, 0x000000, 0x583f01, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x584009, 0x000000, 0x584902, 0x000000, 0x000000, 0x584b05, 0x000000, + 0x000000, 0x585009, 0x000000, 0x000000, 0x585901, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x585a05, 0x000000, 0x585f01, 0x58600d, 0x000000, + 0x000000, 0x586d01, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x586e01, + 0x000000, 0x000000, 0x586f04, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x587301, 0x000000, 0x587402, 0x587605, 0x000000, 0x000000, + 0x000000, 0x000000, 0x587b01, 0x587c01, 0x000000, 0x000000, 0x000000, 0x587d01, + 0x000000, 0x587e01, 0x000000, 0x000000, 0x000000, 0x587f11, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x589002, 0x589201, 0x589302, 0x000000, 0x000000, 0x589501, 0x58960c, 0x000000, + 0x58a202, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x58a403, 0x000000, 0x000000, 0x58a703, 0x000000, 0x58aa08, 0x58b201, 0x58b30a, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x58bd01, 0x000000, 0x58be04, 0x000000, 0x000000, 0x000000, 0x000000, 0x58c201, + 0x000000, 0x000000, 0x000000, 0x58c301, 0x58c401, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x58c502, 0x58c701, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x58c802, 0x000000, 0x000000, + 0x58ca01, 0x000000, 0x000000, 0x000000, 0x000000, 0x58cb03, 0x58ce01, 0x58cf03, + 0x000000, 0x000000, 0x000000, 0x000000, 0x58d20a, 0x000000, 0x58dc02, 0x000000, + 0x000000, 0x58de07, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x58e502, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x58e704, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x58eb01, 0x58ec01, 0x58ed02, 0x000000, 0x58ef01, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x58f001, 0x58f101, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x58f201, 0x000000, 0x000000, 0x58f303, 0x58f601, + 0x000000, 0x58f701, 0x58f803, 0x58fb02, 0x000000, 0x000000, 0x58fd02, 0x58ff03, + 0x000000, 0x590202, 0x000000, 0x590407, 0x590b02, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x590d04, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x591101, 0x000000, 0x591201, 0x591301, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x591405, + 0x000000, 0x000000, 0x591901, 0x591a03, 0x591d02, 0x591f09, 0x000000, 0x592801, + 0x592905, 0x000000, 0x592e02, 0x593001, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x593102, 0x000000, 0x593302, + 0x593501, 0x000000, 0x593601, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x593707, 0x000000, 0x593e09, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x594701, 0x594801, 0x000000, 0x594901, 0x594a03, 0x000000, 0x000000, 0x594d02, + 0x000000, 0x000000, 0x594f01, 0x000000, 0x000000, 0x000000, 0x000000, 0x595001, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x595101, 0x000000, 0x595201, 0x595301, 0x000000, + 0x000000, 0x000000, 0x000000, 0x595402, 0x000000, 0x595601, 0x000000, 0x595701, + 0x000000, 0x595808, 0x596001, 0x596102, 0x596301, 0x596401, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x596501, 0x596607, 0x000000, + 0x596d01, 0x000000, 0x596e05, 0x000000, 0x000000, 0x000000, 0x597301, 0x000000, + 0x597403, 0x000000, 0x000000, 0x000000, 0x000000, 0x597701, 0x000000, 0x000000, + 0x000000, 0x000000, 0x597802, 0x597a08, 0x000000, 0x000000, 0x000000, 0x598202, + 0x598401, 0x000000, 0x000000, 0x598502, 0x000000, 0x000000, 0x000000, 0x598709, + 0x000000, 0x000000, 0x000000, 0x599001, 0x59910b, 0x000000, 0x000000, 0x000000, + 0x599c01, 0x599d01, 0x000000, 0x000000, 0x000000, 0x599e01, 0x000000, 0x000000, + 0x000000, 0x599f02, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x59a101, 0x000000, 0x59a207, 0x000000, 0x000000, 0x59a902, 0x000000, + 0x59ab06, 0x000000, 0x000000, 0x59b101, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x59b201, 0x000000, 0x000000, 0x59b301, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x59b403, 0x000000, + 0x59b701, 0x000000, 0x000000, 0x000000, 0x59b801, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x59b901, 0x000000, 0x59ba07, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x59c101, 0x000000, 0x000000, 0x59c208, 0x000000, 0x59ca02, + 0x000000, 0x000000, 0x59cc01, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x59cd0f, 0x000000, 0x59dc01, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x59dd01, 0x59de01, 0x59df0f, 0x000000, 0x000000, + 0x59ee01, 0x59ef05, 0x59f401, 0x000000, 0x000000, 0x000000, 0x000000, 0x59f502, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x59f703, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x59fa03, 0x000000, 0x000000, 0x000000, 0x000000, + 0x59fd0a, 0x000000, 0x000000, 0x000000, 0x5a0701, 0x000000, 0x5a0803, 0x5a0b01, + 0x5a0c07, 0x5a1301, 0x5a1402, 0x000000, 0x5a1604, 0x000000, 0x000000, 0x000000, + 0x000000, 0x5a1a01, 0x5a1b01, 0x000000, 0x000000, 0x000000, 0x5a1c04, 0x5a2036, + 0x000000, 0x000000, 0x000000, 0x5a5601, 0x000000, 0x5a5701, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x5a5809, 0x000000, 0x5a6103, 0x5a6408, 0x000000, + 0x5a6c01, 0x000000, 0x000000, 0x5a6d02, 0x000000, 0x000000, 0x000000, 0x5a6f02, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x5a7103, 0x000000, 0x000000, 0x000000, 0x000000, 0x5a7402, 0x5a7601, 0x5a7714, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x5a8b01, 0x000000, 0x000000, 0x000000, + 0x000000, 0x5a8c07, 0x000000, 0x000000, 0x5a9301, 0x000000, 0x5a9406, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x5a9a01, 0x000000, 0x000000, 0x5a9b03, 0x5a9e03, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x5aa102, 0x000000, 0x5aa303, 0x000000, 0x5aa602, 0x000000, 0x5aa801, + 0x5aa911, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x5aba02, + 0x5abc01, 0x000000, 0x000000, 0x5abd04, 0x5ac104, 0x5ac507, 0x000000, 0x000000, + 0x000000, 0x5acc01, 0x5acd02, 0x5acf01, 0x000000, 0x000000, 0x000000, 0x000000, + 0x5ad005, 0x5ad50b, 0x000000, 0x000000, 0x000000, 0x5ae003, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x5ae308, 0x000000, 0x5aeb01, + 0x000000, 0x000000, 0x000000, 0x000000, 0x5aec14, 0x000000, 0x5b0001, 0x000000, + 0x5b0101, 0x000000, 0x000000, 0x000000, 0x000000, 0x5b0203, 0x000000, 0x5b0501, + 0x000000, 0x000000, 0x5b0609, 0x5b0f02, 0x000000, 0x000000, 0x5b1106, 0x000000, + 0x5b1704, 0x000000, 0x000000, 0x000000, 0x000000, 0x5b1b01, 0x000000, 0x5b1c03, + 0x000000, 0x5b1f06, 0x000000, 0x5b2503, 0x000000, 0x000000, 0x000000, 0x5b2806, + 0x000000, 0x000000, 0x000000, 0x000000, 0x5b2e01, 0x5b2f02, 0x5b3102, 0x000000, + 0x5b3305, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x5b3802, 0x000000, 0x000000, 0x000000, 0x000000, 0x5b3a01, 0x000000, + 0x5b3b02, 0x5b3d01, 0x000000, 0x000000, 0x000000, 0x5b3e01, 0x5b3f01, 0x000000, + 0x5b4006, 0x000000, 0x5b4602, 0x000000, 0x5b4804, 0x000000, 0x000000, 0x5b4c05, + 0x000000, 0x5b5101, 0x5b5203, 0x000000, 0x5b5501, 0x5b5604, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x5b5a01, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x5b5b02, 0x5b5d03, 0x000000, 0x000000, 0x5b6005, + 0x5b6501, 0x000000, 0x000000, 0x000000, 0x5b6601, 0x000000, 0x000000, 0x000000, + 0x5b6701, 0x000000, 0x000000, 0x000000, 0x000000, 0x5b680e, 0x000000, 0x000000, + 0x000000, 0x5b7601, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x5b7706, 0x000000, 0x5b7d15, 0x000000, 0x5b9201, 0x5b9304, + 0x000000, 0x000000, 0x000000, 0x000000, 0x5b9706, 0x000000, 0x5b9d02, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x5b9f02, 0x000000, 0x000000, + 0x5ba106, 0x5ba701, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x5ba805, 0x000000, 0x000000, 0x000000, 0x5bad01, 0x5bae01, 0x000000, 0x000000, + 0x5baf01, 0x000000, 0x000000, 0x000000, 0x5bb017, 0x5bc701, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x5bc802, 0x000000, + 0x5bca03, 0x000000, 0x000000, 0x5bcd01, 0x000000, 0x000000, 0x5bce0a, 0x000000, + 0x000000, 0x5bd802, 0x000000, 0x000000, 0x5bda02, 0x000000, 0x000000, 0x000000, + 0x5bdc01, 0x000000, 0x000000, 0x000000, 0x000000, 0x5bdd01, 0x5bde02, 0x5be003, + 0x5be301, 0x000000, 0x5be403, 0x5be70b, 0x5bf202, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x5bf403, 0x000000, 0x000000, 0x5bf70c, 0x000000, 0x000000, + 0x5c0301, 0x000000, 0x000000, 0x5c0402, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x5c0601, 0x000000, 0x5c0701, 0x000000, 0x000000, 0x5c0805, 0x000000, + 0x000000, 0x5c0d02, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x5c0f01, + 0x5c1001, 0x5c1101, 0x000000, 0x000000, 0x000000, 0x000000, 0x5c1203, 0x000000, + 0x5c1501, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x5c1604, 0x000000, 0x5c1a02, 0x000000, + 0x000000, 0x5c1c06, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x5c2209, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x5c2b02, 0x5c2d04, 0x000000, 0x000000, 0x000000, 0x000000, 0x5c3104, 0x5c3501, + 0x000000, 0x000000, 0x5c3601, 0x000000, 0x5c3706, 0x000000, 0x000000, 0x000000, + 0x5c3d02, 0x5c3f02, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x5c4101, + 0x000000, 0x000000, 0x5c4202, 0x000000, 0x000000, 0x000000, 0x000000, 0x5c4405, + 0x5c4901, 0x000000, 0x5c4a02, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x5c4c01, 0x000000, 0x5c4d04, 0x000000, 0x000000, 0x000000, + 0x000000, 0x5c5102, 0x000000, 0x5c5302, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x5c5502, 0x000000, 0x000000, 0x000000, 0x000000, 0x5c571b, + 0x5c7202, 0x000000, 0x5c740c, 0x000000, 0x000000, 0x000000, 0x5c8001, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x5c8101, 0x000000, + 0x5c8201, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x5c8301, 0x000000, + 0x000000, 0x000000, 0x5c8404, 0x5c8804, 0x000000, 0x5c8c01, 0x5c8d06, 0x5c9302, + 0x000000, 0x5c9507, 0x000000, 0x5c9c03, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x5c9f02, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x5ca101, 0x000000, 0x000000, 0x5ca203, 0x000000, 0x000000, 0x000000, + 0x000000, 0x5ca502, 0x000000, 0x000000, 0x5ca702, 0x000000, 0x000000, 0x000000, + 0x000000, 0x5ca904, 0x000000, 0x000000, 0x000000, 0x5cad03, 0x5cb00c, 0x000000, + 0x5cbc05, 0x5cc102, 0x000000, 0x5cc301, 0x000000, 0x000000, 0x000000, 0x000000, + 0x5cc401, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x5cc501, 0x000000, + 0x000000, 0x000000, 0x000000, 0x5cc602, 0x000000, 0x5cc804, 0x000000, 0x000000, + 0x000000, 0x000000, 0x5ccc08, 0x5cd405, 0x000000, 0x000000, 0x000000, 0x5cd901, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x5cda01, + 0x000000, 0x5cdb09, 0x5ce40f, 0x000000, 0x000000, 0x5cf302, 0x000000, 0x000000, + 0x000000, 0x000000, 0x5cf501, 0x000000, 0x5cf603, 0x000000, 0x000000, 0x000000, + 0x5cf904, 0x000000, 0x000000, 0x5cfd01, 0x000000, 0x5cfe01, 0x000000, 0x000000, + 0x5cff01, 0x000000, 0x5d000a, 0x000000, 0x5d0a02, 0x000000, 0x000000, 0x000000, + 0x5d0c06, 0x000000, 0x5d1202, 0x000000, 0x000000, 0x000000, 0x5d1401, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x5d1502, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x5d1701, 0x5d1801, 0x5d1901, + 0x5d1a02, 0x000000, 0x000000, 0x000000, 0x000000, 0x5d1c01, 0x5d1d08, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x5d2501, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x5d2620, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x5d4602, 0x5d4801, 0x000000, 0x000000, 0x5d4901, 0x5d4a0c, 0x5d5604, + 0x000000, 0x5d5a02, 0x000000, 0x000000, 0x000000, 0x000000, 0x5d5c01, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x5d5d01, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x5d5e02, 0x5d6001, 0x000000, 0x5d6101, 0x000000, + 0x5d620b, 0x5d6d01, 0x5d6e01, 0x5d6f02, 0x000000, 0x5d7102, 0x000000, 0x5d7303, + 0x000000, 0x5d7607, 0x000000, 0x5d7d03, 0x000000, 0x5d8004, 0x5d8401, 0x000000, + 0x5d8504, 0x5d8909, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x5d9201, + 0x5d9302, 0x5d9501, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x5d9603, 0x000000, 0x5d9903, 0x5d9c01, 0x000000, 0x5d9d01, 0x000000, 0x000000, + 0x000000, 0x000000, 0x5d9e01, 0x5d9f05, 0x000000, 0x000000, 0x5da401, 0x000000, + 0x000000, 0x5da501, 0x000000, 0x000000, 0x000000, 0x000000, 0x5da601, 0x000000, + 0x5da701, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x5da803, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x5dab04, + 0x000000, 0x000000, 0x5daf01, 0x000000, 0x5db002, 0x000000, 0x000000, 0x5db201, + 0x000000, 0x000000, 0x5db302, 0x5db501, 0x5db601, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x5db702, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x5db904, 0x000000, 0x000000, 0x000000, + 0x5dbd01, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x5dbe04, 0x000000, 0x000000, 0x5dc201, 0x000000, 0x5dc302, + 0x000000, 0x5dc501, 0x000000, 0x000000, 0x000000, 0x5dc601, 0x000000, 0x000000, + 0x5dc701, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x5dc801, 0x000000, 0x000000, 0x5dc901, 0x000000, 0x000000, 0x5dca02, 0x000000, + 0x000000, 0x5dcc01, 0x5dcd01, 0x000000, 0x000000, 0x5dce01, 0x5dcf0b, 0x5dda01, + 0x000000, 0x5ddb01, 0x5ddc01, 0x000000, 0x5ddd03, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x5de001, 0x5de101, 0x000000, 0x5de201, 0x000000, 0x000000, + 0x5de308, 0x000000, 0x000000, 0x5deb04, 0x000000, 0x5def01, 0x5df00e, 0x5dfe04, + 0x5e0201, 0x000000, 0x5e0302, 0x5e0501, 0x000000, 0x000000, 0x5e0607, 0x5e0d09, + 0x5e1603, 0x000000, 0x5e1905, 0x000000, 0x000000, 0x000000, 0x5e1e03, 0x000000, + 0x5e2103, 0x5e2403, 0x5e2702, 0x5e2901, 0x000000, 0x5e2a01, 0x000000, 0x000000, + 0x000000, 0x5e2b02, 0x000000, 0x000000, 0x000000, 0x000000, 0x5e2d01, 0x5e2e02, + 0x000000, 0x5e3002, 0x000000, 0x000000, 0x5e3205, 0x5e3704, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x5e3b01, 0x000000, 0x5e3c01, 0x000000, + 0x5e3d01, 0x000000, 0x5e3e08, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x5e4601, 0x000000, 0x000000, 0x5e4701, 0x000000, 0x5e4805, 0x5e4d04, 0x000000, + 0x000000, 0x000000, 0x5e5101, 0x000000, 0x000000, 0x5e5202, 0x5e5405, 0x5e5909, + 0x000000, 0x5e6202, 0x000000, 0x000000, 0x000000, 0x5e6401, 0x5e6501, 0x5e6602, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x5e6801, 0x5e6905, 0x5e6e03, 0x000000, 0x000000, 0x000000, + 0x5e7101, 0x000000, 0x000000, 0x5e7202, 0x000000, 0x000000, 0x5e7403, 0x000000, + 0x5e770d, 0x5e8404, 0x000000, 0x5e8803, 0x5e8b02, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x5e8d06, 0x5e9308, 0x5e9b04, 0x000000, 0x000000, + 0x000000, 0x5e9f02, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x5ea108, 0x000000, 0x5ea901, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x5eaa01, 0x000000, 0x5eab03, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x5eae01, 0x5eaf01, 0x5eb007, + 0x000000, 0x000000, 0x5eb701, 0x000000, 0x000000, 0x5eb802, 0x000000, 0x5eba02, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x5ebc0f, 0x000000, + 0x5ecb01, 0x000000, 0x000000, 0x000000, 0x5ecc02, 0x000000, 0x5ece01, 0x5ecf01, + 0x000000, 0x000000, 0x000000, 0x000000, 0x5ed001, 0x000000, 0x000000, 0x5ed105, + 0x000000, 0x000000, 0x5ed601, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x5ed70d, 0x000000, 0x5ee401, 0x5ee502, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x5ee71b, 0x000000, 0x000000, 0x5f0206, + 0x000000, 0x000000, 0x000000, 0x5f0801, 0x5f0901, 0x5f0a08, 0x5f120c, 0x000000, + 0x5f1e12, 0x000000, 0x000000, 0x5f3001, 0x5f3101, 0x000000, 0x000000, 0x000000, + 0x5f3201, 0x000000, 0x000000, 0x000000, 0x000000, 0x5f3301, 0x5f3401, 0x5f3504, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x5f3901, 0x000000, 0x000000, + 0x000000, 0x000000, 0x5f3a02, 0x000000, 0x5f3c02, 0x000000, 0x5f3e06, 0x5f4401, + 0x000000, 0x5f4504, 0x000000, 0x000000, 0x5f4901, 0x5f4a05, 0x5f4f01, 0x000000, + 0x000000, 0x000000, 0x5f5001, 0x5f5104, 0x000000, 0x5f5505, 0x000000, 0x000000, + 0x000000, 0x5f5a04, 0x000000, 0x000000, 0x000000, 0x5f5e01, 0x000000, 0x5f5f01, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x5f6002, 0x000000, 0x5f6203, + 0x000000, 0x5f6501, 0x000000, 0x5f6605, 0x5f6b07, 0x000000, 0x5f7204, 0x000000, + 0x000000, 0x000000, 0x5f7601, 0x000000, 0x000000, 0x000000, 0x5f7702, 0x5f7904, + 0x5f7d01, 0x000000, 0x000000, 0x000000, 0x5f7e01, 0x5f7f01, 0x5f8003, 0x5f8301, + 0x000000, 0x000000, 0x000000, 0x000000, 0x5f8404, 0x5f8801, 0x000000, 0x000000, + 0x5f8901, 0x5f8a01, 0x5f8b05, 0x000000, 0x5f9005, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x5f9501, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x5f9602, + 0x000000, 0x5f9801, 0x5f9901, 0x5f9a01, 0x5f9b02, 0x000000, 0x5f9d02, 0x000000, + 0x000000, 0x000000, 0x000000, 0x5f9f01, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x5fa001, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x5fa103, 0x5fa401, 0x000000, 0x000000, 0x000000, 0x000000, 0x5fa502, + 0x000000, 0x000000, 0x000000, 0x5fa706, 0x000000, 0x000000, 0x000000, 0x5fad03, + 0x000000, 0x000000, 0x000000, 0x000000, 0x5fb001, 0x000000, 0x000000, 0x5fb101, + 0x000000, 0x000000, 0x000000, 0x5fb207, 0x5fb901, 0x000000, 0x000000, 0x000000, + 0x5fba04, 0x000000, 0x000000, 0x5fbe02, 0x000000, 0x000000, 0x5fc001, 0x5fc103, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x5fc401, 0x000000, 0x5fc502, + 0x000000, 0x5fc701, 0x000000, 0x5fc803, 0x5fcb01, 0x5fcc02, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x5fce01, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x5fcf09, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x5fd802, 0x5fda01, 0x000000, 0x5fdb08, 0x000000, + 0x000000, 0x000000, 0x5fe301, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x5fe401, 0x5fe503, 0x000000, 0x000000, 0x000000, 0x5fe801, 0x5fe901, 0x000000, + 0x5fea01, 0x000000, 0x5feb02, 0x000000, 0x5fed02, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x5fef01, 0x000000, 0x000000, 0x000000, 0x5ff001, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x5ff105, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x5ff602, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x5ff805, 0x000000, 0x000000, 0x000000, 0x5ffd01, 0x000000, 0x5ffe02, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x600004, 0x600403, 0x000000, 0x600701, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x600801, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x600901, 0x000000, 0x000000, 0x600a01, 0x000000, 0x600b02, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x600d01, 0x600e01, 0x000000, 0x000000, 0x000000, 0x000000, 0x600f02, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x601102, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x601301, + 0x601405, 0x000000, 0x000000, 0x000000, 0x000000, 0x601901, 0x601a01, 0x000000, + 0x000000, 0x000000, 0x000000, 0x601b01, 0x000000, 0x000000, 0x601c05, 0x000000, + 0x602101, 0x000000, 0x000000, 0x602201, 0x000000, 0x000000, 0x000000, 0x000000, + 0x602303, 0x602601, 0x602708, 0x602f03, 0x000000, 0x000000, 0x000000, 0x60320b, + 0x000000, 0x603d01, 0x603e01, 0x000000, 0x000000, 0x000000, 0x000000, 0x603f0f, + 0x000000, 0x000000, 0x000000, 0x604e01, 0x604f01, 0x605005, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x605501, 0x000000, + 0x605601, 0x605701, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x605802, + 0x000000, 0x000000, 0x000000, 0x000000, 0x605a01, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x605b01, 0x605c01, 0x000000, 0x605d04, 0x606101, + 0x000000, 0x000000, 0x000000, 0x606203, 0x000000, 0x606501, 0x000000, 0x000000, + 0x606602, 0x000000, 0x000000, 0x000000, 0x606802, 0x000000, 0x606a01, 0x000000, + 0x000000, 0x000000, 0x000000, 0x606b01, 0x000000, 0x606c01, 0x000000, 0x000000, + 0x606d02, 0x000000, 0x000000, 0x606f01, 0x607001, 0x000000, 0x000000, 0x000000, + 0x000000, 0x607101, 0x607206, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x607801, 0x000000, 0x60790b, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x608401, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x608502, 0x000000, 0x608701, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x608801, 0x608901, 0x000000, 0x608a01, + 0x000000, 0x608b02, 0x608d01, 0x000000, 0x608e01, 0x000000, 0x000000, 0x000000, + 0x000000, 0x608f05, 0x000000, 0x000000, 0x60940d, 0x000000, 0x000000, 0x60a10b, + 0x000000, 0x60ac01, 0x60ad02, 0x000000, 0x000000, 0x000000, 0x60af01, 0x000000, + 0x000000, 0x000000, 0x60b005, 0x000000, 0x000000, 0x000000, 0x60b504, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x60b901, 0x000000, 0x60ba01, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x60bb01, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x60bc02, 0x60be01, 0x60bf04, 0x000000, + 0x60c301, 0x000000, 0x000000, 0x000000, 0x000000, 0x60c404, 0x000000, 0x000000, + 0x000000, 0x000000, 0x60c808, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x60d001, 0x000000, 0x60d102, 0x60d301, 0x000000, 0x000000, 0x000000, 0x60d405, + 0x000000, 0x000000, 0x000000, 0x000000, 0x60d904, 0x60dd01, 0x000000, 0x60de01, + 0x60df03, 0x000000, 0x000000, 0x000000, 0x60e201, 0x000000, 0x60e302, 0x60e501, + 0x000000, 0x60e603, 0x000000, 0x000000, 0x000000, 0x60e911, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x60fa01, 0x60fb07, 0x000000, 0x610201, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x610303, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x610604, 0x000000, 0x610a01, 0x610b03, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x610e01, 0x000000, 0x000000, 0x610f01, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x611001, 0x000000, 0x611101, 0x611201, + 0x000000, 0x000000, 0x000000, 0x611301, 0x000000, 0x611401, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x611501, + 0x000000, 0x61160d, 0x000000, 0x000000, 0x61230f, 0x000000, 0x000000, 0x000000, + 0x613201, 0x000000, 0x000000, 0x000000, 0x61330b, 0x000000, 0x613e02, 0x614002, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x614201, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x61430d, 0x000000, 0x615001, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x615103, 0x000000, 0x000000, 0x61540d, + 0x616101, 0x616201, 0x000000, 0x000000, 0x000000, 0x616307, 0x000000, 0x000000, + 0x616a03, 0x000000, 0x000000, 0x616d03, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x617005, 0x617501, 0x000000, + 0x617602, 0x000000, 0x000000, 0x617801, 0x000000, 0x000000, 0x000000, 0x617905, + 0x000000, 0x617e02, 0x000000, 0x000000, 0x000000, 0x618001, 0x000000, 0x000000, + 0x618102, 0x000000, 0x618304, 0x618702, 0x618902, 0x618b04, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x618f01, 0x000000, 0x000000, 0x000000, 0x619005, + 0x000000, 0x619501, 0x000000, 0x000000, 0x619601, 0x000000, 0x000000, 0x619709, + 0x000000, 0x000000, 0x000000, 0x61a001, 0x000000, 0x000000, 0x000000, 0x61a107, + 0x000000, 0x000000, 0x61a802, 0x000000, 0x000000, 0x000000, 0x61aa0f, 0x000000, + 0x000000, 0x61b905, 0x000000, 0x000000, 0x61be0b, 0x000000, 0x000000, 0x000000, + 0x61c901, 0x000000, 0x000000, 0x61ca01, 0x61cb01, 0x000000, 0x61cc02, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x61ce01, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x61cf02, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x61d101, 0x000000, 0x000000, 0x61d202, + 0x61d404, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x61d802, + 0x000000, 0x000000, 0x61da01, 0x000000, 0x61db01, 0x61dc01, 0x000000, 0x000000, + 0x61dd01, 0x000000, 0x000000, 0x000000, 0x61de02, 0x000000, 0x000000, 0x000000, + 0x000000, 0x61e002, 0x61e201, 0x000000, 0x000000, 0x61e304, 0x61e701, 0x000000, + 0x61e804, 0x61ec01, 0x61ed02, 0x000000, 0x000000, 0x000000, 0x000000, 0x61ef01, + 0x000000, 0x61f011, 0x000000, 0x620102, 0x000000, 0x000000, 0x620301, 0x620408, + 0x620c04, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x621003, + 0x621305, 0x000000, 0x000000, 0x621802, 0x000000, 0x000000, 0x621a01, 0x621b01, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x621c03, 0x000000, + 0x000000, 0x000000, 0x621f01, 0x622004, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x622401, 0x000000, 0x000000, 0x000000, 0x622504, + 0x000000, 0x622904, 0x622d05, 0x000000, 0x623204, 0x000000, 0x623608, 0x000000, + 0x000000, 0x000000, 0x623e0a, 0x000000, 0x624802, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x624a0b, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x625501, 0x000000, 0x625620, 0x000000, 0x627602, 0x000000, 0x000000, 0x000000, + 0x627804, 0x000000, 0x000000, 0x000000, 0x000000, 0x627c06, 0x000000, 0x628204, + 0x000000, 0x628602, 0x000000, 0x628802, 0x000000, 0x000000, 0x000000, 0x628a01, + 0x000000, 0x000000, 0x000000, 0x628b01, 0x000000, 0x000000, 0x000000, 0x628c02, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x628e02, + 0x629004, 0x000000, 0x000000, 0x000000, 0x000000, 0x629402, 0x629604, 0x000000, + 0x000000, 0x000000, 0x629a09, 0x000000, 0x000000, 0x000000, 0x62a305, 0x000000, + 0x62a801, 0x62a902, 0x000000, 0x000000, 0x000000, 0x000000, 0x62ab05, 0x62b003, + 0x000000, 0x62b305, 0x000000, 0x000000, 0x62b833, 0x62eb01, 0x000000, 0x62ec01, + 0x000000, 0x62ed01, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x62ee01, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x62ef04, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x62f301, + 0x000000, 0x000000, 0x000000, 0x62f403, 0x000000, 0x000000, 0x000000, 0x62f701, + 0x62f801, 0x62f905, 0x000000, 0x000000, 0x62fe07, 0x000000, 0x630502, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x630702, 0x000000, + 0x630915, 0x000000, 0x631e04, 0x000000, 0x632205, 0x000000, 0x000000, 0x000000, + 0x000000, 0x632702, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x632902, 0x000000, 0x632b02, 0x000000, 0x632d09, + 0x000000, 0x000000, 0x633602, 0x000000, 0x000000, 0x633801, 0x000000, 0x000000, + 0x000000, 0x633905, 0x000000, 0x000000, 0x000000, 0x633e06, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x634402, 0x634602, 0x000000, 0x000000, 0x634802, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x634a02, 0x000000, 0x000000, + 0x000000, 0x634c03, 0x000000, 0x000000, 0x000000, 0x634f09, 0x000000, 0x000000, + 0x000000, 0x000000, 0x635802, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x635a01, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x635b01, 0x000000, 0x000000, 0x000000, 0x635c03, + 0x000000, 0x000000, 0x635f02, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x636101, 0x000000, 0x000000, 0x636203, 0x000000, 0x636503, 0x000000, + 0x000000, 0x636801, 0x000000, 0x000000, 0x000000, 0x636902, 0x000000, 0x000000, + 0x000000, 0x000000, 0x636b01, 0x000000, 0x636c01, 0x636d01, 0x636e01, 0x000000, + 0x000000, 0x000000, 0x636f01, 0x000000, 0x637002, 0x000000, 0x000000, 0x000000, + 0x637202, 0x000000, 0x637407, 0x000000, 0x637b01, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x637c02, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x637e03, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x638101, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x638202, 0x000000, 0x000000, 0x000000, 0x000000, 0x638406, + 0x000000, 0x000000, 0x000000, 0x000000, 0x638a01, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x638b01, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x638c0c, + 0x000000, 0x639801, 0x000000, 0x000000, 0x639906, 0x000000, 0x639f06, 0x000000, + 0x63a502, 0x000000, 0x63a701, 0x000000, 0x000000, 0x63a801, 0x63a903, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x63ac01, 0x63ad01, 0x63ae01, + 0x000000, 0x63af01, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x63b001, 0x000000, 0x63b105, 0x63b607, 0x63bd02, 0x000000, 0x63bf01, + 0x000000, 0x63c00b, 0x000000, 0x000000, 0x63cb02, 0x63cd01, 0x000000, 0x000000, + 0x63ce01, 0x000000, 0x63cf02, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x63d101, 0x000000, 0x63d201, 0x000000, 0x63d301, 0x63d40b, 0x63df02, 0x000000, + 0x000000, 0x000000, 0x63e101, 0x63e203, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x63e505, 0x000000, 0x000000, 0x000000, 0x000000, 0x63ea02, + 0x000000, 0x000000, 0x000000, 0x63ec01, 0x000000, 0x000000, 0x000000, 0x63ed06, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x63f301, 0x000000, 0x000000, 0x000000, 0x000000, 0x63f401, 0x000000, + 0x000000, 0x000000, 0x000000, 0x63f501, 0x000000, 0x63f601, 0x63f701, 0x63f801, + 0x000000, 0x63f902, 0x000000, 0x000000, 0x000000, 0x63fb01, 0x000000, 0x63fc12, + 0x640e03, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x641101, 0x000000, + 0x000000, 0x000000, 0x000000, 0x641204, 0x641606, 0x000000, 0x000000, 0x641c02, + 0x000000, 0x000000, 0x641e04, 0x000000, 0x000000, 0x000000, 0x642201, 0x64230d, + 0x000000, 0x000000, 0x643005, 0x000000, 0x000000, 0x000000, 0x000000, 0x643507, + 0x000000, 0x000000, 0x000000, 0x643c02, 0x643e08, 0x000000, 0x000000, 0x644607, + 0x000000, 0x000000, 0x644d14, 0x646101, 0x000000, 0x646203, 0x646501, 0x646601, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x646702, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x646904, 0x000000, + 0x000000, 0x646d01, 0x000000, 0x646e01, 0x000000, 0x646f03, 0x000000, 0x647201, + 0x647301, 0x647401, 0x000000, 0x000000, 0x64750a, 0x647f04, 0x648302, 0x000000, + 0x000000, 0x000000, 0x648503, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x648802, 0x000000, 0x000000, 0x648a01, + 0x000000, 0x000000, 0x000000, 0x648b01, 0x000000, 0x648c04, 0x649001, 0x000000, + 0x649102, 0x000000, 0x649318, 0x64ab06, 0x64b102, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x64b301, 0x000000, 0x000000, 0x000000, 0x000000, 0x64b401, + 0x000000, 0x64b502, 0x64b701, 0x64b804, 0x000000, 0x000000, 0x000000, 0x64bc08, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x64c404, 0x64c807, + 0x000000, 0x000000, 0x000000, 0x64cf01, 0x64d002, 0x000000, 0x000000, 0x64d203, + 0x64d501, 0x64d602, 0x000000, 0x000000, 0x64d803, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x64db0c, 0x000000, 0x000000, + 0x000000, 0x000000, 0x64e701, 0x64e80d, 0x000000, 0x000000, 0x000000, 0x64f501, + 0x000000, 0x000000, 0x000000, 0x64f601, 0x64f701, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x64f801, 0x64f901, + 0x000000, 0x000000, 0x64fa01, 0x000000, 0x000000, 0x64fb0a, 0x000000, 0x650501, + 0x000000, 0x000000, 0x000000, 0x650602, 0x650802, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x650a01, 0x650b01, 0x000000, 0x650c05, + 0x651101, 0x000000, 0x651201, 0x000000, 0x651301, 0x651401, 0x000000, 0x000000, + 0x000000, 0x000000, 0x651518, 0x652d01, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x652e01, 0x652f01, 0x653003, 0x000000, 0x000000, + 0x000000, 0x653301, 0x653401, 0x000000, 0x000000, 0x000000, 0x000000, 0x653502, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x653701, + 0x000000, 0x653801, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x653902, 0x000000, 0x000000, 0x653b01, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x653c0a, 0x654601, 0x000000, 0x000000, 0x000000, + 0x000000, 0x654702, 0x000000, 0x000000, 0x654903, 0x000000, 0x000000, 0x000000, + 0x654c05, 0x000000, 0x000000, 0x655104, 0x655503, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x655805, 0x000000, 0x655d06, 0x000000, + 0x656305, 0x000000, 0x000000, 0x656801, 0x656901, 0x000000, 0x000000, 0x656a01, + 0x000000, 0x656b01, 0x656c01, 0x656d01, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x656e01, 0x000000, 0x000000, 0x000000, 0x000000, 0x656f01, 0x000000, + 0x000000, 0x000000, 0x657002, 0x657202, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x657402, 0x657603, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x657903, 0x000000, 0x657c01, 0x000000, 0x000000, 0x000000, + 0x657d02, 0x000000, 0x000000, 0x000000, 0x657f09, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x658809, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x659103, 0x000000, 0x000000, 0x000000, 0x659401, 0x000000, + 0x000000, 0x000000, 0x659501, 0x659607, 0x000000, 0x000000, 0x659d01, 0x659e01, + 0x659f01, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x65a001, + 0x65a102, 0x65a302, 0x000000, 0x65a501, 0x65a601, 0x000000, 0x000000, 0x000000, + 0x65a704, 0x65ab01, 0x000000, 0x65ac04, 0x65b001, 0x65b10a, 0x65bb02, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x65bd01, 0x000000, 0x000000, 0x65be02, + 0x000000, 0x000000, 0x65c001, 0x000000, 0x65c101, 0x000000, 0x65c202, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x65c401, 0x000000, 0x000000, 0x000000, + 0x000000, 0x65c505, 0x65ca01, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x65cb06, 0x000000, 0x65d101, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x65d202, 0x000000, 0x65d402, 0x000000, 0x000000, 0x65d602, 0x000000, 0x000000, + 0x000000, 0x65d801, 0x000000, 0x65d903, 0x65dc01, 0x000000, 0x000000, 0x000000, + 0x000000, 0x65dd01, 0x000000, 0x000000, 0x000000, 0x65de0b, 0x000000, 0x65e904, + 0x000000, 0x000000, 0x65ed01, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x65ee01, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x65ef05, + 0x65f406, 0x000000, 0x65fa0f, 0x660902, 0x000000, 0x660b01, 0x000000, 0x000000, + 0x660c0b, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x661705, + 0x661c0e, 0x662a09, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x663302, 0x663501, 0x000000, 0x000000, 0x000000, + 0x663603, 0x000000, 0x663901, 0x663a01, 0x000000, 0x000000, 0x663b02, 0x000000, + 0x000000, 0x663d01, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x663e01, + 0x000000, 0x000000, 0x000000, 0x663f01, 0x664090, 0x000000, 0x66d001, 0x66d101, + 0x000000, 0x66d201, 0x000000, 0x000000, 0x66d301, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x66d406, 0x000000, 0x66da04, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x66de0f, 0x000000, 0x000000, + 0x000000, 0x66ed1d, 0x000000, 0x000000, 0x000000, 0x670a03, 0x000000, 0x000000, + 0x670d01, 0x670e02, 0x671007, 0x000000, 0x000000, 0x67170e, 0x672505, 0x000000, + 0x000000, 0x000000, 0x000000, 0x672a01, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x672b08, 0x000000, 0x000000, 0x673303, 0x000000, 0x000000, 0x673601, + 0x000000, 0x673702, 0x673906, 0x673f03, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x674201, 0x000000, 0x674305, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x674803, 0x000000, 0x674b02, 0x000000, + 0x000000, 0x000000, 0x674d01, 0x000000, 0x000000, 0x000000, 0x000000, 0x674e02, + 0x000000, 0x000000, 0x000000, 0x000000, 0x675001, 0x000000, 0x675102, 0x675301, + 0x000000, 0x675401, 0x675501, 0x000000, 0x000000, 0x000000, 0x675601, 0x000000, + 0x000000, 0x000000, 0x675702, 0x000000, 0x000000, 0x675902, 0x000000, 0x000000, + 0x675b03, 0x000000, 0x675e01, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x675f06, 0x676503, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x676801, 0x000000, + 0x000000, 0x676901, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x676a02, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x676c08, 0x000000, 0x677401, 0x000000, 0x000000, 0x677501, 0x000000, + 0x677601, 0x000000, 0x000000, 0x677705, 0x677c01, 0x677d01, 0x000000, 0x000000, + 0x677e02, 0x000000, 0x678007, 0x678702, 0x678901, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x678a02, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x678c01, 0x000000, 0x000000, 0x678d02, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x678f01, 0x000000, 0x679002, 0x679203, 0x000000, 0x000000, 0x000000, + 0x679501, 0x000000, 0x000000, 0x000000, 0x679605, 0x000000, 0x679b02, 0x679d01, + 0x000000, 0x000000, 0x000000, 0x679e05, 0x000000, 0x67a301, 0x000000, 0x67a404, + 0x67a815, 0x67bd01, 0x000000, 0x000000, 0x000000, 0x67be0c, 0x000000, 0x000000, + 0x000000, 0x67ca02, 0x000000, 0x000000, 0x67cc0f, 0x000000, 0x67db05, 0x000000, + 0x67e00a, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x67ea01, + 0x000000, 0x67eb02, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x67ed01, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x67ee02, 0x67f002, 0x67f203, 0x67f502, + 0x000000, 0x000000, 0x000000, 0x67f704, 0x67fb01, 0x000000, 0x67fc06, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x680202, 0x000000, 0x680401, 0x000000, + 0x000000, 0x680502, 0x000000, 0x000000, 0x68070b, 0x681201, 0x000000, 0x000000, + 0x000000, 0x681302, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x681501, 0x681603, 0x000000, 0x000000, 0x000000, + 0x681906, 0x000000, 0x000000, 0x681f07, 0x000000, 0x000000, 0x000000, 0x000000, + 0x682607, 0x682d01, 0x682e0e, 0x000000, 0x000000, 0x000000, 0x683c01, 0x683d01, + 0x683e02, 0x000000, 0x684037, 0x000000, 0x000000, 0x000000, 0x000000, 0x687701, + 0x000000, 0x687802, 0x000000, 0x687a01, 0x687b01, 0x000000, 0x687c01, 0x687d01, + 0x687e01, 0x000000, 0x000000, 0x000000, 0x000000, 0x687f03, 0x688201, 0x000000, + 0x000000, 0x000000, 0x68830d, 0x689005, 0x000000, 0x000000, 0x000000, 0x689501, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x689602, 0x000000, 0x689801, + 0x689908, 0x000000, 0x68a101, 0x000000, 0x000000, 0x000000, 0x68a201, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x68a301, 0x000000, 0x000000, 0x68a402, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x68a601, 0x000000, 0x68a701, + 0x68a801, 0x000000, 0x000000, 0x000000, 0x68a903, 0x000000, 0x68ac01, 0x68ad02, + 0x000000, 0x000000, 0x000000, 0x68af03, 0x000000, 0x000000, 0x68b201, 0x000000, + 0x68b301, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x68b403, 0x000000, 0x000000, 0x68b701, 0x000000, 0x000000, + 0x68b803, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x68bb0d, 0x000000, 0x68c801, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x68c901, 0x000000, 0x000000, 0x68ca02, 0x68cc05, 0x68d101, + 0x000000, 0x000000, 0x000000, 0x000000, 0x68d20e, 0x000000, 0x000000, 0x68e002, + 0x000000, 0x68e201, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x68e301, 0x000000, 0x68e404, 0x68e801, 0x000000, + 0x68e901, 0x000000, 0x68ea11, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x68fb02, 0x000000, 0x68fd04, 0x690101, 0x690207, 0x000000, + 0x000000, 0x000000, 0x000000, 0x690904, 0x690d01, 0x000000, 0x000000, 0x000000, + 0x000000, 0x690e01, 0x690f04, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x69130b, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x691e02, 0x692001, 0x692101, 0x692201, 0x692303, 0x692602, 0x000000, 0x000000, + 0x000000, 0x692801, 0x692903, 0x000000, 0x000000, 0x692c03, 0x000000, 0x000000, + 0x000000, 0x692f01, 0x000000, 0x000000, 0x693001, 0x693101, 0x000000, 0x000000, + 0x000000, 0x693201, 0x000000, 0x693301, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x693404, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x693806, 0x000000, 0x000000, 0x693e01, 0x000000, 0x000000, 0x693f02, 0x000000, + 0x000000, 0x000000, 0x69410a, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x694b02, 0x000000, 0x694d05, 0x000000, 0x000000, 0x695202, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x695404, + 0x000000, 0x695801, 0x695902, 0x695b01, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x695c01, 0x000000, 0x695d04, 0x000000, 0x696102, 0x000000, 0x696302, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x696504, 0x000000, + 0x696901, 0x696a03, 0x000000, 0x696d0d, 0x000000, 0x000000, 0x000000, 0x000000, + 0x697a03, 0x697d01, 0x000000, 0x000000, 0x697e03, 0x698102, 0x698301, 0x698401, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x698501, 0x698603, 0x698901, 0x000000, 0x698a06, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x699001, 0x000000, 0x000000, 0x000000, 0x699103, 0x000000, + 0x000000, 0x000000, 0x000000, 0x699401, 0x699501, 0x699603, 0x699902, 0x000000, + 0x000000, 0x699b01, 0x699c01, 0x000000, 0x000000, 0x000000, 0x699d04, 0x69a102, + 0x000000, 0x000000, 0x000000, 0x69a301, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x69a401, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x69a501, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x69a602, 0x69a801, 0x000000, 0x69a901, 0x000000, 0x000000, + 0x000000, 0x69aa01, 0x69ab03, 0x000000, 0x69ae01, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x69af02, 0x69b101, 0x69b202, 0x000000, 0x69b403, 0x000000, 0x69b705, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x69bc01, 0x000000, 0x000000, 0x69bd02, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x69bf04, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x69c302, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x69c501, 0x000000, + 0x69c602, 0x000000, 0x000000, 0x000000, 0x69c801, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x69c901, 0x000000, 0x69ca03, 0x69cd01, 0x000000, + 0x000000, 0x000000, 0x000000, 0x69ce01, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x69cf02, 0x69d104, 0x000000, 0x69d501, 0x000000, 0x000000, 0x69d604, + 0x000000, 0x69da03, 0x69dd01, 0x000000, 0x000000, 0x000000, 0x69de02, 0x000000, + 0x000000, 0x000000, 0x000000, 0x69e001, 0x000000, 0x000000, 0x000000, 0x69e101, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x69e201, 0x000000, + 0x000000, 0x000000, 0x000000, 0x69e309, 0x69ec01, 0x000000, 0x000000, 0x000000, + 0x000000, 0x69ed06, 0x000000, 0x000000, 0x69f302, 0x000000, 0x69f504, 0x000000, + 0x000000, 0x69f901, 0x69fa10, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x6a0a01, 0x000000, 0x000000, 0x000000, 0x000000, 0x6a0b01, 0x6a0c01, + 0x000000, 0x000000, 0x000000, 0x000000, 0x6a0d01, 0x6a0e01, 0x000000, 0x6a0f07, + 0x000000, 0x6a1605, 0x000000, 0x000000, 0x000000, 0x6a1b0b, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x6a260e, 0x000000, 0x6a3402, + 0x000000, 0x000000, 0x6a3602, 0x000000, 0x6a3802, 0x000000, 0x6a3a03, 0x000000, + 0x6a3d02, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x6a3f02, 0x000000, + 0x000000, 0x000000, 0x000000, 0x6a4101, 0x000000, 0x000000, 0x000000, 0x000000, + 0x6a4201, 0x000000, 0x000000, 0x6a4302, 0x000000, 0x000000, 0x6a4501, 0x000000, + 0x6a4602, 0x000000, 0x000000, 0x000000, 0x000000, 0x6a4804, 0x000000, 0x000000, + 0x000000, 0x6a4c03, 0x000000, 0x000000, 0x6a4f03, 0x6a5201, 0x6a5302, 0x6a5501, + 0x6a5601, 0x000000, 0x6a5701, 0x000000, 0x6a5801, 0x6a5907, 0x000000, 0x000000, + 0x6a6002, 0x000000, 0x000000, 0x000000, 0x000000, 0x6a6202, 0x000000, 0x6a6401, + 0x000000, 0x6a6501, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x6a6603, 0x000000, 0x6a6901, 0x6a6a07, 0x000000, 0x6a7101, 0x000000, 0x000000, + 0x000000, 0x6a7202, 0x000000, 0x6a7401, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x6a7501, 0x6a7603, 0x6a7901, 0x000000, 0x000000, 0x000000, 0x6a7a08, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x6a8209, 0x000000, + 0x6a8b02, 0x6a8d12, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x6a9f01, 0x6aa004, 0x6aa401, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x6aa50a, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x6aaf01, 0x6ab005, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x6ab502, 0x000000, 0x6ab709, 0x000000, 0x6ac001, 0x000000, + 0x6ac101, 0x6ac201, 0x000000, 0x6ac308, 0x000000, 0x000000, 0x000000, 0x000000, + 0x6acb08, 0x000000, 0x000000, 0x000000, 0x6ad302, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x6ad501, 0x000000, 0x6ad604, 0x000000, 0x000000, + 0x000000, 0x000000, 0x6ada03, 0x000000, 0x000000, 0x6add01, 0x6ade02, 0x6ae004, + 0x000000, 0x000000, 0x000000, 0x6ae402, 0x000000, 0x6ae609, 0x000000, 0x6aef02, + 0x6af101, 0x000000, 0x000000, 0x6af211, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x6b0301, 0x000000, 0x6b0407, 0x6b0b04, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x6b0f2d, 0x000000, 0x000000, 0x000000, 0x000000, + 0x6b3c03, 0x000000, 0x000000, 0x000000, 0x6b3f02, 0x000000, 0x000000, 0x000000, + 0x6b4101, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x6b4201, 0x000000, 0x000000, 0x000000, 0x6b4301, 0x000000, 0x000000, 0x6b4404, + 0x000000, 0x6b4802, 0x6b4a02, 0x000000, 0x000000, 0x6b4c01, 0x000000, 0x6b4d01, + 0x000000, 0x6b4e06, 0x000000, 0x6b5405, 0x6b5902, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x6b5b01, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x6b5c08, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x6b6401, 0x000000, 0x6b6508, 0x6b6d09, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x6b7615, 0x6b8b01, 0x000000, 0x000000, 0x000000, 0x6b8c0c, 0x6b9801, 0x000000, + 0x000000, 0x000000, 0x6b9901, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x6b9a02, 0x000000, 0x000000, + 0x6b9c01, 0x6b9d01, 0x000000, 0x6b9e04, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x6ba210, 0x000000, 0x000000, 0x6bb202, 0x000000, + 0x6bb401, 0x6bb501, 0x6bb602, 0x6bb801, 0x000000, 0x6bb901, 0x000000, 0x000000, + 0x6bba06, 0x6bc001, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x6bc102, + 0x000000, 0x000000, 0x6bc301, 0x6bc407, 0x000000, 0x000000, 0x000000, 0x000000, + 0x6bcb04, 0x000000, 0x000000, 0x6bcf08, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x6bd702, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x6bd908, 0x000000, 0x000000, 0x000000, 0x6be102, + 0x000000, 0x000000, 0x6be30b, 0x000000, 0x000000, 0x000000, 0x6bee01, 0x000000, + 0x000000, 0x6bef02, 0x6bf102, 0x000000, 0x6bf302, 0x6bf505, 0x000000, 0x000000, + 0x000000, 0x6bfa01, 0x000000, 0x6bfb05, 0x6c0002, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x6c0209, 0x6c0b01, 0x000000, 0x6c0c01, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x6c0d02, 0x000000, 0x000000, + 0x6c0f01, 0x000000, 0x6c1004, 0x000000, 0x000000, 0x000000, 0x6c1402, 0x000000, + 0x6c1602, 0x000000, 0x000000, 0x000000, 0x6c1801, 0x6c1908, 0x000000, 0x000000, + 0x000000, 0x6c211d, 0x000000, 0x000000, 0x000000, 0x6c3e01, 0x000000, 0x6c3f01, + 0x6c4006, 0x6c4601, 0x6c4708, 0x000000, 0x000000, 0x6c4f01, 0x000000, 0x6c5002, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x6c5201, 0x000000, 0x000000, 0x6c5301, 0x000000, 0x6c5405, 0x000000, + 0x6c5904, 0x000000, 0x000000, 0x000000, 0x6c5d01, 0x000000, 0x000000, 0x000000, + 0x6c5e01, 0x6c5f01, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x6c6001, 0x6c6101, 0x000000, 0x000000, 0x000000, 0x6c6201, 0x6c6303, 0x6c6601, + 0x6c6710, 0x000000, 0x000000, 0x000000, 0x6c7702, 0x6c7904, 0x000000, 0x000000, + 0x000000, 0x6c7d01, 0x6c7e01, 0x000000, 0x6c7f01, 0x6c8004, 0x000000, 0x000000, + 0x6c8403, 0x000000, 0x6c8702, 0x000000, 0x6c8905, 0x000000, 0x000000, 0x6c8e01, + 0x000000, 0x6c8f01, 0x6c900b, 0x6c9b08, 0x000000, 0x6ca301, 0x6ca401, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x6ca50b, + 0x000000, 0x6cb002, 0x000000, 0x6cb201, 0x000000, 0x000000, 0x000000, 0x000000, + 0x6cb321, 0x6cd401, 0x6cd502, 0x000000, 0x000000, 0x000000, 0x6cd701, 0x000000, + 0x000000, 0x000000, 0x6cd813, 0x6ceb05, 0x000000, 0x6cf001, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x6cf101, 0x000000, 0x6cf201, 0x000000, 0x000000, + 0x000000, 0x6cf305, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x6cf801, + 0x6cf901, 0x000000, 0x000000, 0x6cfa02, 0x000000, 0x000000, 0x000000, 0x6cfc04, + 0x6d000f, 0x000000, 0x000000, 0x6d0f01, 0x000000, 0x000000, 0x6d1001, 0x000000, + 0x6d1109, 0x000000, 0x000000, 0x000000, 0x6d1a03, 0x6d1d07, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x6d2401, 0x000000, 0x6d2503, 0x000000, 0x6d2802, 0x000000, 0x6d2a07, 0x6d3106, + 0x000000, 0x000000, 0x000000, 0x000000, 0x6d3703, 0x6d3a01, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x6d3b01, 0x6d3c02, + 0x000000, 0x000000, 0x000000, 0x6d3e02, 0x000000, 0x6d4006, 0x6d4601, 0x000000, + 0x6d4701, 0x6d4804, 0x000000, 0x6d4c02, 0x000000, 0x6d4e44, 0x6d9201, 0x6d9304, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x6d9702, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x6d9901, 0x6d9a02, 0x000000, 0x000000, + 0x6d9c02, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x6d9e03, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x6da103, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x6da401, 0x6da502, + 0x6da701, 0x000000, 0x6da801, 0x000000, 0x000000, 0x6da901, 0x000000, 0x000000, + 0x000000, 0x000000, 0x6daa03, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x6dad07, 0x000000, 0x000000, 0x000000, 0x000000, 0x6db401, + 0x000000, 0x000000, 0x000000, 0x000000, 0x6db502, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x6db702, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x6db907, 0x000000, 0x6dc011, 0x6dd101, + 0x6dd201, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x6dd302, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x6dd50b, 0x000000, + 0x6de002, 0x000000, 0x6de204, 0x000000, 0x000000, 0x6de605, 0x000000, 0x000000, + 0x000000, 0x6deb01, 0x6dec05, 0x000000, 0x000000, 0x000000, 0x6df106, 0x000000, + 0x000000, 0x000000, 0x000000, 0x6df703, 0x000000, 0x000000, 0x000000, 0x000000, + 0x6dfa02, 0x6dfc04, 0x6e0005, 0x000000, 0x000000, 0x000000, 0x000000, 0x6e0501, + 0x000000, 0x6e0605, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x6e0b01, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x6e0c02, 0x000000, 0x000000, 0x6e0e03, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x6e110a, 0x6e1b02, 0x000000, 0x6e1d01, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x6e1e02, 0x000000, 0x6e200d, 0x6e2d01, 0x000000, 0x000000, + 0x6e2e02, 0x6e3002, 0x000000, 0x6e3202, 0x000000, 0x6e3402, 0x000000, 0x000000, + 0x000000, 0x6e3601, 0x6e3701, 0x6e3805, 0x000000, 0x6e3d01, 0x000000, 0x6e3e02, + 0x6e4001, 0x000000, 0x000000, 0x000000, 0x6e4101, 0x000000, 0x6e4202, 0x6e4403, + 0x6e4703, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x6e4a06, 0x000000, 0x6e5001, 0x000000, 0x000000, 0x6e5101, + 0x000000, 0x000000, 0x000000, 0x000000, 0x6e5202, 0x000000, 0x000000, 0x000000, + 0x6e5403, 0x000000, 0x000000, 0x000000, 0x6e5702, 0x6e5901, 0x000000, 0x6e5a01, + 0x6e5b01, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x6e5c01, + 0x000000, 0x000000, 0x6e5d01, 0x6e5e01, 0x000000, 0x000000, 0x6e5f02, 0x000000, + 0x000000, 0x6e6101, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x6e6201, + 0x000000, 0x000000, 0x6e6301, 0x000000, 0x000000, 0x6e6401, 0x000000, 0x000000, + 0x000000, 0x000000, 0x6e6501, 0x6e6601, 0x000000, 0x000000, 0x6e6702, 0x000000, + 0x000000, 0x000000, 0x6e6902, 0x000000, 0x6e6b01, 0x6e6c01, 0x000000, 0x6e6d02, + 0x6e6f02, 0x6e7103, 0x000000, 0x6e7401, 0x6e7501, 0x000000, 0x000000, 0x000000, + 0x6e7601, 0x000000, 0x6e7701, 0x6e7802, 0x6e7a09, 0x000000, 0x6e8302, 0x000000, + 0x6e8503, 0x000000, 0x6e8802, 0x000000, 0x000000, 0x000000, 0x000000, 0x6e8a01, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x6e8b01, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x6e8c01, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x6e8d01, 0x6e8e01, 0x000000, 0x000000, 0x000000, + 0x000000, 0x6e8f01, 0x000000, 0x000000, 0x6e9007, 0x000000, 0x6e9701, 0x000000, + 0x6e9801, 0x6e9901, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x6e9a05, 0x000000, 0x000000, 0x000000, 0x6e9f01, 0x6ea007, 0x000000, 0x000000, + 0x6ea701, 0x000000, 0x000000, 0x000000, 0x6ea809, 0x6eb101, 0x000000, 0x6eb205, + 0x000000, 0x000000, 0x6eb703, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x6eba01, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x6ebb3f, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x6efa01, 0x000000, 0x6efb01, 0x6efc03, 0x000000, 0x6eff04, + 0x000000, 0x000000, 0x000000, 0x6f0301, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x6f0402, 0x000000, 0x000000, 0x000000, 0x000000, 0x6f0601, 0x000000, + 0x000000, 0x000000, 0x6f0704, 0x000000, 0x000000, 0x6f0b01, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x6f0c02, 0x000000, 0x000000, 0x000000, 0x6f0e03, + 0x6f1118, 0x000000, 0x6f2906, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x6f2f01, 0x000000, + 0x000000, 0x000000, 0x000000, 0x6f3002, 0x000000, 0x6f3204, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x6f3603, 0x000000, 0x000000, 0x000000, + 0x000000, 0x6f3906, 0x000000, 0x6f3f01, 0x000000, 0x6f4004, 0x000000, 0x000000, + 0x6f4401, 0x000000, 0x000000, 0x000000, 0x000000, 0x6f4502, 0x6f4701, 0x000000, + 0x000000, 0x6f4803, 0x000000, 0x000000, 0x000000, 0x000000, 0x6f4b03, 0x000000, + 0x000000, 0x000000, 0x6f4e02, 0x000000, 0x6f5002, 0x000000, 0x6f5201, 0x000000, + 0x000000, 0x000000, 0x000000, 0x6f5302, 0x000000, 0x000000, 0x6f5501, 0x6f5605, + 0x000000, 0x000000, 0x000000, 0x6f5b02, 0x000000, 0x000000, 0x000000, 0x6f5d02, + 0x000000, 0x000000, 0x6f5f01, 0x6f6001, 0x6f6107, 0x6f6805, 0x000000, 0x6f6d01, + 0x000000, 0x6f6e01, 0x6f6f01, 0x000000, 0x000000, 0x000000, 0x000000, 0x6f7003, + 0x000000, 0x000000, 0x6f7305, 0x000000, 0x000000, 0x6f7801, 0x6f7901, 0x000000, + 0x000000, 0x000000, 0x6f7a09, 0x000000, 0x6f8305, 0x000000, 0x6f8801, 0x6f8906, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x6f8f03, 0x6f9201, 0x000000, 0x000000, + 0x6f9301, 0x000000, 0x000000, 0x000000, 0x000000, 0x6f9401, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x6f9502, 0x6f9701, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x6f9801, 0x000000, 0x000000, + 0x000000, 0x6f9902, 0x000000, 0x6f9b01, 0x6f9c02, 0x000000, 0x000000, 0x000000, + 0x000000, 0x6f9e01, 0x000000, 0x000000, 0x000000, 0x000000, 0x6f9f05, 0x6fa407, + 0x6fab01, 0x000000, 0x000000, 0x6fac01, 0x000000, 0x000000, 0x000000, 0x6fad05, + 0x6fb203, 0x000000, 0x6fb503, 0x000000, 0x000000, 0x6fb804, 0x000000, 0x000000, + 0x6fbc09, 0x000000, 0x000000, 0x000000, 0x000000, 0x6fc501, 0x6fc604, 0x6fca01, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x6fcb06, 0x000000, + 0x6fd102, 0x000000, 0x000000, 0x6fd303, 0x000000, 0x6fd601, 0x000000, 0x6fd703, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x6fda02, 0x000000, + 0x000000, 0x000000, 0x6fdc01, 0x6fdd01, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x6fde04, 0x000000, 0x6fe209, 0x000000, 0x000000, 0x6feb0a, 0x000000, + 0x000000, 0x000000, 0x6ff508, 0x000000, 0x6ffd01, 0x6ffe01, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x6fff01, + 0x700002, 0x700201, 0x70030f, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x701204, 0x000000, 0x000000, 0x000000, 0x701601, 0x000000, + 0x000000, 0x000000, 0x701701, 0x000000, 0x701801, 0x701907, 0x000000, 0x702002, + 0x000000, 0x702201, 0x702302, 0x702501, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x702611, 0x703708, 0x000000, 0x000000, 0x000000, + 0x703f01, 0x000000, 0x000000, 0x000000, 0x704001, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x704101, 0x000000, + 0x704202, 0x000000, 0x704401, 0x000000, 0x000000, 0x704503, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x704804, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x704c01, 0x704d02, 0x704f02, 0x705102, 0x705301, 0x000000, 0x705402, 0x000000, + 0x000000, 0x000000, 0x000000, 0x705601, 0x705702, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x705902, 0x000000, 0x000000, 0x000000, 0x705b02, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x705d01, 0x000000, + 0x705e01, 0x705f01, 0x000000, 0x000000, 0x000000, 0x000000, 0x706001, 0x706101, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x706201, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x706301, 0x000000, 0x706409, + 0x000000, 0x706d02, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x706f01, 0x000000, 0x707001, 0x000000, 0x707101, 0x000000, 0x000000, 0x000000, + 0x70720a, 0x000000, 0x000000, 0x000000, 0x707c02, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x707e02, 0x000000, 0x000000, 0x708001, 0x000000, + 0x000000, 0x000000, 0x000000, 0x708103, 0x000000, 0x708401, 0x000000, 0x000000, + 0x708501, 0x000000, 0x000000, 0x708601, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x708702, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x708902, 0x708b04, 0x000000, 0x000000, 0x708f03, 0x709202, 0x000000, + 0x000000, 0x709405, 0x000000, 0x709910, 0x000000, 0x000000, 0x000000, 0x70a90a, + 0x70b301, 0x000000, 0x000000, 0x70b401, 0x000000, 0x70b501, 0x70b602, 0x000000, + 0x000000, 0x000000, 0x70b801, 0x000000, 0x000000, 0x000000, 0x70b909, 0x000000, + 0x70c201, 0x70c301, 0x70c405, 0x000000, 0x000000, 0x000000, 0x70c906, 0x70cf02, + 0x70d108, 0x70d902, 0x70db03, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x70de03, 0x000000, 0x000000, 0x000000, 0x70e101, 0x70e201, + 0x000000, 0x000000, 0x000000, 0x70e304, 0x000000, 0x000000, 0x70e702, 0x000000, + 0x70e901, 0x000000, 0x000000, 0x000000, 0x000000, 0x70ea01, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x70eb02, 0x000000, 0x000000, 0x000000, + 0x70ed04, 0x000000, 0x70f101, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x70f201, 0x70f303, 0x70f601, 0x000000, 0x000000, 0x70f701, + 0x000000, 0x70f803, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x70fb02, 0x000000, 0x000000, 0x000000, 0x000000, 0x70fd03, + 0x710001, 0x000000, 0x000000, 0x000000, 0x710106, 0x000000, 0x710703, 0x000000, + 0x710a03, 0x000000, 0x000000, 0x000000, 0x000000, 0x710d0e, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x711b0a, 0x000000, 0x000000, 0x000000, + 0x712501, 0x000000, 0x000000, 0x000000, 0x000000, 0x712601, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x712703, + 0x000000, 0x712a04, 0x000000, 0x712e01, 0x712f06, 0x000000, 0x713501, 0x713601, + 0x000000, 0x000000, 0x713705, 0x713c07, 0x714301, 0x714401, 0x714501, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x714601, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x714701, 0x000000, 0x714808, 0x000000, 0x000000, + 0x000000, 0x715002, 0x000000, 0x000000, 0x71520a, 0x000000, 0x000000, 0x715c03, + 0x000000, 0x000000, 0x000000, 0x000000, 0x715f01, 0x000000, 0x716001, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x71610a, 0x000000, 0x000000, 0x000000, + 0x716b01, 0x000000, 0x000000, 0x000000, 0x716c01, 0x000000, 0x000000, 0x000000, + 0x000000, 0x716d07, 0x000000, 0x717402, 0x000000, 0x717604, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x717a03, + 0x000000, 0x000000, 0x000000, 0x717d02, 0x717f06, 0x718508, 0x000000, 0x718d0c, + 0x719901, 0x000000, 0x000000, 0x000000, 0x719a01, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x719b01, 0x000000, 0x000000, + 0x000000, 0x000000, 0x719c03, 0x719f02, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x71a107, 0x71a806, 0x000000, 0x000000, 0x000000, + 0x71ae02, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x71b002, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x71b202, + 0x000000, 0x71b406, 0x000000, 0x000000, 0x000000, 0x71ba05, 0x000000, 0x000000, + 0x71bf12, 0x000000, 0x000000, 0x71d102, 0x71d30c, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x71df08, 0x000000, + 0x71e70e, 0x71f502, 0x000000, 0x71f704, 0x000000, 0x000000, 0x71fb01, 0x000000, + 0x71fc2f, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x722b01, 0x000000, 0x000000, 0x722c01, 0x000000, 0x000000, 0x722d04, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x723107, 0x000000, 0x000000, 0x000000, 0x723804, 0x000000, + 0x723c03, 0x000000, 0x723f02, 0x000000, 0x724106, 0x724718, 0x725f02, 0x000000, + 0x726103, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x726401, 0x000000, 0x000000, 0x726505, 0x726a01, 0x726b02, 0x000000, 0x000000, + 0x000000, 0x000000, 0x726d01, 0x000000, 0x726e01, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x726f01, 0x727001, 0x727102, 0x727302, 0x000000, 0x727502, + 0x000000, 0x000000, 0x727703, 0x727a05, 0x000000, 0x727f0a, 0x000000, 0x000000, + 0x000000, 0x728901, 0x000000, 0x000000, 0x728a01, 0x000000, 0x000000, 0x728b02, + 0x728d02, 0x728f07, 0x000000, 0x729603, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x729901, 0x729a02, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x729c02, 0x729e01, 0x000000, 0x000000, 0x000000, 0x000000, + 0x729f01, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x72a001, 0x000000, + 0x000000, 0x000000, 0x000000, 0x72a101, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x72a201, 0x72a301, 0x72a405, 0x000000, + 0x000000, 0x72a901, 0x000000, 0x000000, 0x72aa02, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x72ac07, 0x000000, 0x000000, + 0x000000, 0x000000, 0x72b301, 0x000000, 0x72b401, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x72b502, 0x000000, 0x000000, 0x72b70a, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x72c103, 0x000000, 0x72c405, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x72c903, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x72cc01, 0x000000, 0x000000, 0x000000, 0x72cd01, 0x000000, + 0x000000, 0x72ce06, 0x72d401, 0x000000, 0x72d50e, 0x72e302, 0x72e504, 0x72e901, + 0x72ea01, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x72eb03, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x72ee0c, 0x000000, 0x000000, 0x000000, 0x72fa02, 0x000000, 0x000000, 0x000000, + 0x72fc02, 0x000000, 0x000000, 0x72fe02, 0x000000, 0x730002, 0x000000, 0x000000, + 0x000000, 0x000000, 0x730203, 0x000000, 0x730504, 0x730902, 0x730b04, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x730f05, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x731403, 0x000000, 0x000000, 0x000000, 0x731704, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x731b05, + 0x000000, 0x73200d, 0x000000, 0x000000, 0x000000, 0x732d04, 0x000000, 0x000000, + 0x000000, 0x733101, 0x000000, 0x000000, 0x000000, 0x733201, 0x733305, 0x000000, + 0x000000, 0x733801, 0x000000, 0x000000, 0x000000, 0x733901, 0x000000, 0x733a03, + 0x000000, 0x733d03, 0x734004, 0x000000, 0x734401, 0x000000, 0x000000, 0x000000, + 0x734502, 0x000000, 0x000000, 0x000000, 0x734704, 0x000000, 0x000000, 0x000000, + 0x734b02, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x734d01, 0x000000, 0x734e01, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x734f01, 0x735008, 0x735801, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x735901, 0x000000, 0x000000, 0x735a07, + 0x736102, 0x000000, 0x736302, 0x000000, 0x000000, 0x000000, 0x736501, 0x000000, + 0x736601, 0x736703, 0x736a01, 0x000000, 0x000000, 0x736b01, 0x000000, 0x000000, + 0x000000, 0x736c01, 0x000000, 0x000000, 0x000000, 0x736d02, 0x000000, 0x000000, + 0x736f06, 0x000000, 0x000000, 0x000000, 0x000000, 0x737503, 0x737801, 0x000000, + 0x737902, 0x737b01, 0x000000, 0x000000, 0x737c01, 0x000000, 0x000000, 0x737d0c, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x738906, 0x738f02, 0x739105, 0x739602, 0x000000, 0x000000, + 0x000000, 0x000000, 0x739801, 0x739903, 0x000000, 0x000000, 0x739c10, 0x000000, + 0x000000, 0x73ac01, 0x000000, 0x73ad01, 0x000000, 0x73ae01, 0x000000, 0x000000, + 0x000000, 0x000000, 0x73af01, 0x73b008, 0x000000, 0x000000, 0x73b807, 0x000000, + 0x000000, 0x000000, 0x73bf01, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x73c001, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x73c101, 0x73c202, 0x73c401, 0x000000, 0x73c503, 0x000000, 0x73c802, 0x73ca01, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x73cb01, 0x000000, + 0x73cc04, 0x000000, 0x73d001, 0x000000, 0x000000, 0x000000, 0x73d103, 0x000000, + 0x73d403, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x73d703, + 0x73da01, 0x000000, 0x000000, 0x73db01, 0x000000, 0x000000, 0x000000, 0x73dc03, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x73df07, 0x000000, 0x000000, + 0x000000, 0x73e602, 0x73e802, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x73ea02, 0x000000, 0x73ec02, 0x73ee05, 0x000000, 0x000000, + 0x73f301, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x73f402, 0x000000, + 0x000000, 0x000000, 0x73f601, 0x000000, 0x000000, 0x000000, 0x73f701, 0x000000, + 0x73f801, 0x73f90a, 0x740301, 0x000000, 0x740401, 0x000000, 0x000000, 0x000000, + 0x740504, 0x000000, 0x74090e, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x741701, 0x000000, 0x741806, 0x000000, 0x741e06, 0x000000, + 0x742401, 0x742510, 0x000000, 0x74350b, 0x744002, 0x000000, 0x744201, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x744301, 0x000000, 0x000000, 0x744406, + 0x000000, 0x000000, 0x000000, 0x744a01, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x744b01, 0x000000, 0x000000, 0x000000, 0x744c01, 0x744d01, 0x744e2f, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x747d02, 0x000000, 0x000000, 0x000000, 0x747f01, 0x000000, + 0x748002, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x748202, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x748403, + 0x000000, 0x748702, 0x748901, 0x000000, 0x000000, 0x748a02, 0x000000, 0x000000, + 0x748c01, 0x748d05, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x749201, 0x000000, 0x000000, 0x000000, + 0x000000, 0x749301, 0x749404, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x749814, 0x000000, 0x000000, 0x74ac03, + 0x74af12, 0x74c10f, 0x74d002, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x74d20e, 0x74e001, 0x000000, 0x74e101, 0x000000, 0x000000, 0x74e203, 0x74e512, + 0x74f702, 0x74f901, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x74fa01, 0x74fb03, 0x000000, 0x000000, 0x000000, 0x74fe02, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x750003, 0x000000, 0x000000, 0x750301, + 0x000000, 0x750405, 0x000000, 0x000000, 0x750909, 0x000000, 0x000000, 0x000000, + 0x000000, 0x751201, 0x000000, 0x000000, 0x000000, 0x751306, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x751901, 0x000000, 0x751a0d, 0x75270f, 0x753601, + 0x753702, 0x753903, 0x000000, 0x000000, 0x000000, 0x753c01, 0x000000, 0x000000, + 0x000000, 0x000000, 0x753d02, 0x753f01, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x754006, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x754608, 0x754e02, 0x000000, + 0x000000, 0x755001, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x755104, 0x000000, 0x755501, 0x000000, + 0x755601, 0x000000, 0x75571b, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x757201, 0x757301, 0x000000, 0x000000, 0x000000, 0x757403, 0x000000, + 0x757701, 0x000000, 0x000000, 0x000000, 0x757802, 0x000000, 0x000000, 0x000000, + 0x000000, 0x757a04, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x757e01, 0x000000, 0x000000, 0x757f02, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x758102, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x758306, 0x758901, 0x000000, + 0x000000, 0x758a07, 0x000000, 0x000000, 0x000000, 0x000000, 0x759114, 0x75a501, + 0x000000, 0x75a602, 0x000000, 0x75a809, 0x75b101, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x75b201, 0x75b301, 0x75b402, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x75b601, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x75b701, + 0x000000, 0x000000, 0x75b801, 0x75b901, 0x000000, 0x000000, 0x000000, 0x75ba07, + 0x75c101, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x75c201, 0x000000, + 0x000000, 0x75c303, 0x75c611, 0x000000, 0x000000, 0x000000, 0x75d704, 0x000000, + 0x75db01, 0x75dc07, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x75e301, 0x75e40b, 0x000000, 0x75ef02, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x75f102, 0x75f303, 0x000000, + 0x000000, 0x75f603, 0x000000, 0x000000, 0x75f901, 0x000000, 0x000000, 0x000000, + 0x000000, 0x75fa0a, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x760403, 0x000000, 0x000000, 0x000000, + 0x760701, 0x000000, 0x000000, 0x760801, 0x000000, 0x000000, 0x000000, 0x760901, + 0x000000, 0x000000, 0x000000, 0x000000, 0x760a01, 0x000000, 0x760b02, 0x000000, + 0x760d05, 0x761204, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x761602, + 0x000000, 0x000000, 0x761802, 0x761a03, 0x000000, 0x000000, 0x000000, 0x000000, + 0x761d02, 0x000000, 0x761f03, 0x762202, 0x762405, 0x000000, 0x762902, 0x762b11, + 0x000000, 0x000000, 0x000000, 0x763c02, 0x000000, 0x000000, 0x763e01, 0x763f06, + 0x000000, 0x000000, 0x000000, 0x764502, 0x764702, 0x000000, 0x000000, 0x764902, + 0x000000, 0x764b0a, 0x000000, 0x765501, 0x000000, 0x000000, 0x000000, 0x000000, + 0x765601, 0x765702, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x765901, + 0x765a03, 0x765d02, 0x765f02, 0x76610a, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x766b01, 0x766c01, 0x000000, 0x000000, 0x000000, 0x766d01, + 0x000000, 0x000000, 0x000000, 0x766e01, 0x000000, 0x766f02, 0x767104, 0x767501, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x767605, 0x000000, 0x767b10, + 0x768b01, 0x768c07, 0x000000, 0x000000, 0x769301, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x769401, 0x000000, 0x769501, + 0x000000, 0x769601, 0x769705, 0x000000, 0x000000, 0x769c01, 0x769d0c, 0x76a901, + 0x000000, 0x000000, 0x000000, 0x000000, 0x76aa02, 0x000000, 0x000000, 0x76ac04, + 0x000000, 0x76b003, 0x000000, 0x76b309, 0x76bc04, 0x000000, 0x000000, 0x000000, + 0x76c002, 0x000000, 0x000000, 0x000000, 0x000000, 0x76c201, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x76c301, 0x000000, 0x000000, 0x76c401, 0x000000, + 0x76c502, 0x76c701, 0x000000, 0x76c801, 0x000000, 0x76c907, 0x000000, 0x000000, + 0x000000, 0x76d001, 0x000000, 0x000000, 0x76d101, 0x76d201, 0x000000, 0x76d304, + 0x000000, 0x76d703, 0x000000, 0x000000, 0x000000, 0x76da03, 0x76dd02, 0x76df01, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x76e003, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x76e301, 0x000000, 0x76e401, 0x76e503, 0x000000, + 0x76e801, 0x76e903, 0x000000, 0x000000, 0x000000, 0x76ec07, 0x000000, 0x000000, + 0x000000, 0x000000, 0x76f304, 0x76f701, 0x76f801, 0x000000, 0x000000, 0x000000, + 0x76f906, 0x000000, 0x76ff03, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x770202, 0x000000, 0x770408, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x770c07, 0x000000, 0x000000, 0x771301, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x771401, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x771501, 0x77160a, 0x772001, 0x772107, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x772803, 0x000000, + 0x772b01, 0x000000, 0x000000, 0x000000, 0x772c01, 0x772d04, 0x000000, 0x773102, + 0x773307, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x773a01, 0x000000, 0x773b01, 0x000000, + 0x773c0c, 0x000000, 0x000000, 0x000000, 0x000000, 0x774801, 0x000000, 0x000000, + 0x77490f, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x775802, 0x000000, + 0x000000, 0x775a01, 0x775b02, 0x775d01, 0x775e01, 0x775f01, 0x000000, 0x000000, + 0x776001, 0x000000, 0x776101, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x776207, 0x776901, 0x776a0f, 0x000000, 0x777901, + 0x777a03, 0x000000, 0x000000, 0x777d04, 0x000000, 0x000000, 0x778111, 0x000000, + 0x000000, 0x000000, 0x000000, 0x779201, 0x77930b, 0x779e0b, 0x77a902, 0x000000, + 0x000000, 0x77ab04, 0x77af0f, 0x77be01, 0x77bf01, 0x000000, 0x77c001, 0x000000, + 0x000000, 0x77c10b, 0x77cc01, 0x000000, 0x77cd06, 0x000000, 0x77d302, 0x77d501, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x77d610, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x77e603, 0x000000, 0x000000, 0x77e902, 0x000000, + 0x000000, 0x000000, 0x000000, 0x77eb01, 0x000000, 0x000000, 0x000000, 0x000000, + 0x77ec01, 0x000000, 0x77ed01, 0x77ee04, 0x000000, 0x000000, 0x000000, 0x000000, + 0x77f202, 0x000000, 0x000000, 0x000000, 0x77f401, 0x000000, 0x000000, 0x77f509, + 0x77fe0a, 0x780802, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x780a02, 0x000000, 0x000000, 0x780c01, 0x000000, + 0x000000, 0x000000, 0x780d02, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x780f01, 0x781003, 0x000000, 0x000000, 0x000000, 0x781303, 0x000000, 0x000000, + 0x000000, 0x781603, 0x000000, 0x781901, 0x000000, 0x781a01, 0x781b03, 0x000000, + 0x000000, 0x781e01, 0x781f01, 0x782001, 0x000000, 0x000000, 0x000000, 0x782106, + 0x000000, 0x000000, 0x782703, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x782a01, 0x000000, 0x782b02, 0x000000, 0x000000, 0x782d03, + 0x000000, 0x783001, 0x783101, 0x783203, 0x783503, 0x783802, 0x000000, 0x000000, + 0x783a01, 0x783b01, 0x783c09, 0x000000, 0x000000, 0x000000, 0x000000, 0x784502, + 0x000000, 0x000000, 0x000000, 0x784712, 0x000000, 0x000000, 0x000000, 0x000000, + 0x785902, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x785b07, 0x786204, 0x000000, 0x000000, 0x786601, 0x786701, 0x000000, 0x786802, + 0x000000, 0x786a01, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x786b02, 0x000000, 0x000000, 0x786d04, 0x000000, 0x000000, 0x000000, 0x787101, + 0x000000, 0x787202, 0x000000, 0x787401, 0x787507, 0x000000, 0x787c01, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x787d01, 0x787e02, 0x000000, 0x000000, + 0x788002, 0x000000, 0x788201, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x788306, 0x788901, 0x000000, 0x000000, 0x788a06, 0x000000, 0x789001, 0x000000, + 0x000000, 0x789102, 0x000000, 0x000000, 0x789301, 0x000000, 0x000000, 0x78940c, + 0x000000, 0x000000, 0x000000, 0x78a002, 0x78a206, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x78a802, 0x000000, 0x78aa03, 0x000000, 0x000000, 0x000000, + 0x000000, 0x78ad01, 0x000000, 0x78ae02, 0x000000, 0x78b001, 0x000000, 0x78b106, + 0x000000, 0x000000, 0x000000, 0x78b702, 0x78b903, 0x000000, 0x78bc01, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x78bd05, 0x000000, 0x000000, + 0x000000, 0x78c212, 0x78d409, 0x78dd01, 0x000000, 0x000000, 0x000000, 0x000000, + 0x78de02, 0x000000, 0x000000, 0x78e001, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x78e101, 0x000000, 0x000000, 0x78e208, 0x000000, 0x000000, + 0x78ea01, 0x78eb04, 0x000000, 0x000000, 0x78ef01, 0x000000, 0x000000, 0x78f001, + 0x78f104, 0x78f503, 0x000000, 0x000000, 0x78f805, 0x78fd02, 0x000000, 0x000000, + 0x000000, 0x78ff01, 0x000000, 0x000000, 0x790001, 0x000000, 0x790104, 0x79050c, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x791101, + 0x791203, 0x791502, 0x000000, 0x791701, 0x000000, 0x000000, 0x791802, 0x000000, + 0x000000, 0x791a02, 0x791c01, 0x000000, 0x000000, 0x791d05, 0x792203, 0x000000, + 0x000000, 0x792502, 0x000000, 0x792702, 0x000000, 0x000000, 0x000000, 0x000000, + 0x792902, 0x000000, 0x000000, 0x792b03, 0x792e01, 0x792f01, 0x793002, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x793201, 0x793301, 0x793403, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x793704, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x793b01, 0x793c01, 0x793d03, 0x000000, 0x000000, 0x000000, + 0x794002, 0x794202, 0x794402, 0x000000, 0x794601, 0x000000, 0x000000, 0x000000, + 0x794701, 0x000000, 0x794804, 0x000000, 0x000000, 0x000000, 0x794c01, 0x794d01, + 0x794e08, 0x000000, 0x000000, 0x795603, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x795902, 0x000000, 0x795b03, 0x795e01, 0x000000, 0x000000, 0x000000, + 0x795f01, 0x796002, 0x000000, 0x000000, 0x000000, 0x000000, 0x796201, 0x000000, + 0x000000, 0x796301, 0x000000, 0x000000, 0x000000, 0x796402, 0x796601, 0x000000, + 0x796707, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x796e37, 0x000000, 0x79a502, 0x000000, 0x79a701, + 0x000000, 0x000000, 0x79a801, 0x79a901, 0x79aa02, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x79ac02, 0x000000, 0x79ae01, 0x79af0a, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x79b909, 0x79c203, + 0x79c501, 0x79c601, 0x000000, 0x000000, 0x000000, 0x79c703, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x79ca07, 0x000000, 0x000000, + 0x000000, 0x79d106, 0x000000, 0x000000, 0x000000, 0x79d703, 0x79da01, 0x000000, + 0x000000, 0x79db02, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x79dd01, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x79de06, 0x000000, 0x000000, 0x000000, 0x79e406, 0x000000, 0x000000, 0x000000, + 0x000000, 0x79ea04, 0x79ee10, 0x000000, 0x000000, 0x000000, 0x000000, 0x79fe01, + 0x000000, 0x79ff01, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x7a0003, 0x7a0311, 0x7a1401, 0x000000, + 0x7a1501, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x7a1602, + 0x000000, 0x000000, 0x7a1801, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x7a1901, 0x7a1a01, 0x000000, 0x000000, + 0x7a1b01, 0x000000, 0x7a1c01, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x7a1d01, 0x7a1e01, 0x000000, 0x000000, 0x7a1f02, 0x000000, 0x7a2101, 0x000000, + 0x7a220e, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x7a3001, 0x000000, + 0x7a3102, 0x000000, 0x7a3301, 0x000000, 0x000000, 0x7a3402, 0x7a3601, 0x7a3702, + 0x000000, 0x000000, 0x7a3902, 0x000000, 0x000000, 0x000000, 0x7a3b03, 0x7a3e04, + 0x000000, 0x7a4201, 0x000000, 0x7a4302, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x7a4501, 0x000000, 0x000000, 0x000000, 0x000000, 0x7a4601, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x7a4701, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x7a4803, 0x7a4b01, 0x7a4c06, 0x7a5202, 0x000000, + 0x7a5406, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x7a5a01, 0x000000, + 0x7a5b01, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x7a5c02, 0x7a5e04, + 0x000000, 0x000000, 0x7a6202, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x7a6403, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x7a6701, 0x000000, + 0x000000, 0x7a6801, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x7a6901, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x7a6a03, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x7a6d03, 0x000000, 0x000000, + 0x000000, 0x000000, 0x7a7002, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x7a7201, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x7a7302, 0x000000, 0x000000, 0x7a7501, 0x7a7601, 0x000000, + 0x7a7702, 0x000000, 0x000000, 0x7a7901, 0x000000, 0x000000, 0x000000, 0x000000, + 0x7a7a01, 0x000000, 0x000000, 0x7a7b07, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x7a8209, 0x000000, + 0x7a8b01, 0x000000, 0x000000, 0x7a8c03, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x7a8f0c, 0x000000, 0x7a9b01, + 0x000000, 0x7a9c03, 0x000000, 0x7a9f09, 0x000000, 0x7aa804, 0x000000, 0x7aac02, + 0x7aae01, 0x7aaf01, 0x000000, 0x7ab004, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x7ab402, 0x7ab601, 0x000000, 0x000000, 0x000000, 0x7ab702, + 0x7ab904, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x7abd01, + 0x7abe01, 0x000000, 0x000000, 0x7abf01, 0x000000, 0x7ac007, 0x7ac701, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x7ac801, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x7ac901, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x7aca03, 0x000000, 0x000000, 0x000000, 0x000000, 0x7acd04, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x7ad102, 0x000000, 0x7ad304, 0x000000, 0x7ad703, 0x000000, 0x000000, 0x7ada01, + 0x000000, 0x000000, 0x000000, 0x000000, 0x7adb09, 0x000000, 0x7ae404, 0x7ae801, + 0x000000, 0x000000, 0x7ae901, 0x000000, 0x000000, 0x7aea01, 0x000000, 0x000000, + 0x7aeb01, 0x000000, 0x000000, 0x000000, 0x7aec04, 0x7af003, 0x000000, 0x7af30d, + 0x000000, 0x000000, 0x000000, 0x000000, 0x7b0001, 0x7b0102, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x7b0301, 0x7b0401, 0x7b0507, + 0x000000, 0x000000, 0x000000, 0x000000, 0x7b0c03, 0x7b0f01, 0x7b1004, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x7b1401, 0x000000, 0x000000, 0x000000, 0x000000, 0x7b1501, 0x000000, 0x000000, + 0x7b1602, 0x000000, 0x000000, 0x7b1801, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x7b1908, 0x000000, 0x7b210e, + 0x7b2f03, 0x7b3201, 0x7b3301, 0x000000, 0x7b3405, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x7b3907, 0x7b4006, 0x7b4601, 0x000000, 0x000000, + 0x000000, 0x7b4701, 0x7b4801, 0x7b4902, 0x000000, 0x000000, 0x7b4b03, 0x7b4e02, + 0x000000, 0x7b5001, 0x000000, 0x000000, 0x000000, 0x7b5101, 0x000000, 0x000000, + 0x000000, 0x000000, 0x7b5201, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x7b5302, 0x7b5506, 0x7b5b01, 0x7b5c01, 0x000000, 0x000000, 0x7b5d02, + 0x7b5f01, 0x7b6001, 0x7b6109, 0x7b6a01, 0x000000, 0x7b6b01, 0x000000, 0x000000, + 0x000000, 0x000000, 0x7b6c02, 0x000000, 0x7b6e01, 0x000000, 0x7b6f01, 0x7b7002, + 0x000000, 0x000000, 0x7b7201, 0x7b7304, 0x000000, 0x000000, 0x7b7702, 0x7b7901, + 0x000000, 0x000000, 0x000000, 0x7b7a04, 0x000000, 0x7b7e01, 0x000000, 0x000000, + 0x000000, 0x000000, 0x7b7f01, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x7b8001, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x7b8103, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x7b8401, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x7b8503, 0x7b8802, 0x000000, 0x000000, 0x000000, 0x000000, 0x7b8a0e, 0x000000, + 0x7b9801, 0x000000, 0x000000, 0x7b9901, 0x000000, 0x000000, 0x7b9a01, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x7b9b02, 0x000000, 0x7b9d02, 0x000000, 0x000000, 0x000000, 0x000000, 0x7b9f04, + 0x000000, 0x000000, 0x000000, 0x7ba305, 0x000000, 0x000000, 0x000000, 0x7ba813, + 0x000000, 0x000000, 0x7bbb0d, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x7bc802, 0x7bca01, 0x7bcb02, 0x000000, 0x7bcd02, 0x000000, + 0x000000, 0x000000, 0x7bcf06, 0x000000, 0x7bd501, 0x000000, 0x7bd602, 0x000000, +}; + +static const DictWord kStaticDictionaryWords[] = { + { 8, 0, 1002 }, { 8, 0, 1015 }, { 4, 0, 683 }, { 4, 10, 325 }, + { 10, 10, 125 }, { 7, 11, 572 }, { 9, 11, 592 }, { 11, 11, 680 }, + { 11, 11, 842 }, { 11, 11, 924 }, { 12, 11, 356 }, { 12, 11, 550 }, + { 13, 11, 317 }, { 13, 11, 370 }, { 13, 11, 469 }, { 13, 11, 471 }, + { 14, 11, 397 }, { 18, 11, 69 }, { 18, 11, 145 }, { 6, 0, 1265 }, + { 8, 11, 534 }, { 6, 0, 1431 }, { 11, 0, 138 }, { 12, 0, 40 }, + { 4, 0, 155 }, { 7, 0, 1689 }, { 4, 10, 718 }, { 7, 10, 1216 }, + { 4, 0, 245 }, { 5, 0, 151 }, { 5, 0, 741 }, { 6, 0, 1147 }, + { 7, 0, 498 }, { 7, 0, 870 }, { 7, 0, 1542 }, { 12, 0, 213 }, + { 14, 0, 36 }, { 14, 0, 391 }, { 17, 0, 111 }, { 18, 0, 6 }, + { 18, 0, 46 }, { 18, 0, 151 }, { 19, 0, 36 }, { 20, 0, 32 }, + { 20, 0, 56 }, { 20, 0, 69 }, { 20, 0, 102 }, { 21, 0, 4 }, + { 22, 0, 8 }, { 22, 0, 10 }, { 22, 0, 14 }, { 22, 0, 31 }, + { 4, 0, 624 }, { 7, 0, 1752 }, { 5, 10, 124 }, { 5, 10, 144 }, + { 6, 10, 548 }, { 7, 10, 15 }, { 7, 10, 153 }, { 9, 10, 629 }, + { 6, 0, 503 }, { 9, 0, 586 }, { 13, 0, 468 }, { 14, 0, 66 }, + { 16, 0, 58 }, { 7, 10, 1531 }, { 8, 10, 416 }, { 9, 10, 275 }, + { 10, 10, 100 }, { 11, 10, 658 }, { 11, 10, 979 }, { 12, 10, 86 }, + { 14, 10, 207 }, { 15, 10, 20 }, { 15, 10, 25 }, { 5, 0, 603 }, + { 7, 0, 1212 }, { 9, 0, 565 }, { 14, 0, 301 }, { 5, 10, 915 }, + { 6, 10, 1783 }, { 7, 10, 211 }, { 7, 10, 1353 }, { 9, 10, 83 }, + { 10, 10, 376 }, { 10, 10, 431 }, { 11, 10, 543 }, { 12, 10, 664 }, + { 13, 10, 280 }, { 13, 10, 428 }, { 14, 10, 128 }, { 17, 10, 52 }, + { 17, 10, 81 }, { 4, 0, 492 }, { 5, 0, 451 }, { 7, 0, 835 }, + { 13, 0, 70 }, { 4, 0, 539 }, { 7, 11, 748 }, { 11, 11, 700 }, + { 7, 11, 1517 }, { 11, 11, 597 }, { 14, 11, 76 }, { 14, 11, 335 }, + { 20, 11, 33 }, { 6, 0, 113 }, { 7, 0, 436 }, { 4, 10, 338 }, + { 5, 10, 400 }, { 8, 0, 718 }, { 5, 11, 127 }, { 5, 11, 418 }, + { 6, 0, 1505 }, { 7, 0, 520 }, { 6, 11, 198 }, { 11, 10, 892 }, + { 12, 11, 83 }, { 4, 10, 221 }, { 5, 10, 659 }, { 5, 10, 989 }, + { 7, 10, 697 }, { 7, 10, 1211 }, { 10, 10, 284 }, { 7, 0, 1070 }, + { 5, 11, 276 }, { 6, 11, 55 }, { 7, 11, 1369 }, { 6, 0, 1515 }, + { 6, 11, 1752 }, { 8, 11, 726 }, { 10, 10, 507 }, { 15, 0, 78 }, + { 4, 10, 188 }, { 7, 10, 805 }, { 5, 10, 884 }, { 11, 10, 991 }, + { 5, 11, 764 }, { 6, 10, 1653 }, { 6, 11, 309 }, { 7, 11, 331 }, + { 10, 11, 550 }, { 7, 11, 1861 }, { 4, 11, 348 }, { 7, 11, 986 }, + { 7, 11, 1573 }, { 12, 0, 610 }, { 13, 0, 431 }, { 16, 0, 59 }, + { 9, 11, 799 }, { 12, 10, 166 }, { 6, 0, 1530 }, { 4, 0, 750 }, + { 4, 0, 307 }, { 5, 0, 964 }, { 6, 11, 194 }, { 7, 11, 133 }, + { 10, 11, 493 }, { 10, 11, 570 }, { 11, 11, 664 }, { 5, 11, 24 }, + { 5, 11, 569 }, { 6, 11, 3 }, { 6, 11, 119 }, { 6, 11, 143 }, + { 6, 11, 440 }, { 7, 11, 295 }, { 7, 11, 599 }, { 7, 11, 1686 }, + { 7, 11, 1854 }, { 8, 11, 424 }, { 9, 11, 43 }, { 9, 11, 584 }, + { 9, 11, 760 }, { 10, 11, 148 }, { 10, 11, 328 }, { 11, 11, 159 }, + { 11, 11, 253 }, { 11, 11, 506 }, { 12, 11, 487 }, { 12, 11, 531 }, + { 16, 11, 33 }, { 8, 10, 760 }, { 5, 11, 14 }, { 5, 11, 892 }, + { 6, 11, 283 }, { 7, 11, 234 }, { 8, 11, 537 }, { 7, 11, 1251 }, + { 4, 11, 126 }, { 8, 11, 635 }, { 19, 11, 34 }, { 4, 11, 316 }, + { 7, 11, 1561 }, { 6, 0, 999 }, { 6, 0, 1310 }, { 9, 11, 861 }, + { 4, 11, 64 }, { 5, 11, 352 }, { 5, 11, 720 }, { 6, 11, 368 }, + { 11, 11, 359 }, { 4, 0, 75 }, { 5, 0, 180 }, { 6, 0, 500 }, + { 7, 0, 58 }, { 7, 0, 710 }, { 10, 0, 645 }, { 8, 10, 770 }, + { 5, 0, 649 }, { 6, 0, 276 }, { 7, 0, 282 }, { 7, 0, 879 }, + { 7, 0, 924 }, { 8, 0, 459 }, { 9, 0, 599 }, { 9, 0, 754 }, + { 11, 0, 574 }, { 12, 0, 128 }, { 12, 0, 494 }, { 13, 0, 52 }, + { 13, 0, 301 }, { 15, 0, 30 }, { 15, 0, 132 }, { 4, 0, 200 }, + { 4, 10, 89 }, { 5, 10, 489 }, { 6, 10, 315 }, { 7, 10, 553 }, + { 7, 10, 1745 }, { 10, 10, 243 }, { 7, 11, 1050 }, { 7, 0, 1621 }, + { 6, 10, 1658 }, { 9, 10, 3 }, { 10, 10, 154 }, { 11, 10, 641 }, + { 13, 10, 85 }, { 13, 10, 201 }, { 13, 10, 346 }, { 6, 11, 175 }, + { 9, 11, 289 }, { 5, 11, 432 }, { 5, 11, 913 }, { 6, 0, 225 }, + { 9, 0, 211 }, { 7, 0, 718 }, { 8, 0, 687 }, { 11, 0, 374 }, + { 4, 10, 166 }, { 5, 10, 505 }, { 9, 0, 110 }, { 6, 10, 1670 }, + { 8, 0, 58 }, { 9, 0, 724 }, { 11, 0, 809 }, { 13, 0, 113 }, + { 17, 0, 72 }, { 6, 0, 345 }, { 7, 0, 1247 }, { 16, 11, 82 }, + { 5, 11, 931 }, { 6, 11, 1698 }, { 8, 0, 767 }, { 8, 0, 803 }, + { 9, 0, 301 }, { 9, 0, 903 }, { 11, 0, 203 }, { 6, 0, 1154 }, + { 7, 0, 1949 }, { 8, 0, 674 }, { 6, 0, 259 }, { 7, 0, 1275 }, + { 5, 11, 774 }, { 6, 11, 1637 }, { 6, 11, 1686 }, { 6, 11, 1751 }, + { 6, 0, 1231 }, { 7, 10, 445 }, { 8, 10, 307 }, { 8, 10, 704 }, + { 10, 10, 41 }, { 10, 10, 439 }, { 11, 10, 237 }, { 11, 10, 622 }, + { 12, 10, 201 }, { 8, 0, 254 }, { 6, 11, 260 }, { 7, 11, 1484 }, + { 11, 0, 277 }, { 7, 10, 1977 }, { 4, 10, 189 }, { 5, 10, 713 }, + { 6, 11, 573 }, { 8, 10, 57 }, { 10, 10, 371 }, { 4, 10, 552 }, + { 6, 11, 344 }, { 5, 0, 248 }, { 9, 0, 800 }, { 10, 0, 693 }, + { 11, 0, 482 }, { 11, 0, 734 }, { 11, 0, 789 }, { 6, 11, 240 }, + { 4, 0, 116 }, { 5, 0, 95 }, { 5, 0, 445 }, { 7, 0, 1688 }, + { 8, 0, 29 }, { 9, 0, 272 }, { 11, 0, 509 }, { 11, 0, 915 }, + { 4, 11, 292 }, { 4, 11, 736 }, { 5, 11, 871 }, { 6, 11, 171 }, + { 6, 11, 1689 }, { 7, 11, 1324 }, { 7, 11, 1944 }, { 9, 11, 415 }, + { 9, 11, 580 }, { 14, 11, 230 }, { 18, 11, 68 }, { 7, 0, 490 }, + { 13, 0, 100 }, { 15, 0, 75 }, { 7, 0, 1641 }, { 5, 0, 543 }, + { 7, 11, 209 }, { 8, 11, 661 }, { 10, 11, 42 }, { 11, 11, 58 }, + { 12, 11, 58 }, { 12, 11, 118 }, { 13, 11, 32 }, { 5, 0, 181 }, + { 8, 0, 41 }, { 6, 11, 63 }, { 7, 11, 920 }, { 5, 0, 657 }, + { 5, 11, 793 }, { 10, 0, 709 }, { 7, 0, 25 }, { 8, 0, 202 }, + { 10, 0, 536 }, { 5, 11, 665 }, { 7, 10, 1788 }, { 17, 10, 49 }, + { 9, 0, 423 }, { 12, 0, 89 }, { 5, 11, 67 }, { 6, 11, 62 }, + { 6, 11, 374 }, { 7, 11, 1391 }, { 8, 0, 113 }, { 9, 0, 877 }, + { 10, 0, 554 }, { 11, 0, 83 }, { 12, 0, 136 }, { 19, 0, 109 }, + { 9, 11, 790 }, { 12, 11, 47 }, { 10, 10, 661 }, { 4, 0, 963 }, + { 10, 0, 927 }, { 14, 0, 442 }, { 7, 10, 1945 }, { 5, 0, 976 }, + { 4, 0, 206 }, { 4, 11, 391 }, { 7, 11, 1169 }, { 6, 0, 2002 }, + { 6, 0, 696 }, { 6, 0, 1008 }, { 6, 0, 1170 }, { 4, 11, 271 }, + { 7, 0, 13 }, { 8, 0, 226 }, { 10, 0, 537 }, { 11, 0, 570 }, + { 11, 0, 605 }, { 11, 0, 799 }, { 11, 0, 804 }, { 12, 0, 85 }, + { 12, 0, 516 }, { 12, 0, 623 }, { 13, 0, 112 }, { 13, 0, 361 }, + { 14, 0, 77 }, { 14, 0, 78 }, { 17, 0, 28 }, { 19, 0, 110 }, + { 12, 11, 314 }, { 4, 0, 769 }, { 6, 0, 1544 }, { 4, 0, 551 }, + { 9, 0, 678 }, { 5, 10, 84 }, { 6, 10, 163 }, { 9, 0, 57 }, + { 9, 0, 459 }, { 10, 0, 425 }, { 11, 0, 119 }, { 12, 0, 184 }, + { 12, 0, 371 }, { 13, 0, 358 }, { 17, 0, 51 }, { 5, 0, 188 }, + { 5, 0, 814 }, { 8, 0, 10 }, { 9, 0, 421 }, { 9, 0, 729 }, + { 10, 0, 609 }, { 11, 0, 689 }, { 4, 11, 253 }, { 5, 10, 410 }, + { 5, 11, 544 }, { 7, 11, 300 }, { 9, 11, 340 }, { 6, 0, 624 }, + { 10, 11, 321 }, { 7, 0, 1941 }, { 18, 0, 130 }, { 5, 10, 322 }, + { 8, 10, 186 }, { 9, 10, 262 }, { 10, 10, 187 }, { 14, 10, 208 }, + { 5, 11, 53 }, { 5, 11, 541 }, { 6, 11, 94 }, { 6, 11, 499 }, + { 7, 11, 230 }, { 11, 11, 321 }, { 5, 10, 227 }, { 4, 0, 378 }, + { 4, 11, 920 }, { 5, 11, 25 }, { 5, 11, 790 }, { 6, 11, 457 }, + { 7, 11, 853 }, { 9, 0, 269 }, { 4, 0, 528 }, { 6, 0, 1146 }, + { 7, 10, 1395 }, { 8, 10, 486 }, { 9, 10, 236 }, { 9, 10, 878 }, + { 10, 10, 218 }, { 11, 10, 95 }, { 19, 10, 17 }, { 19, 10, 31 }, + { 7, 10, 2043 }, { 8, 10, 672 }, { 13, 10, 448 }, { 6, 0, 1105 }, + { 6, 0, 1616 }, { 6, 11, 1765 }, { 12, 11, 163 }, { 5, 10, 412 }, + { 5, 11, 822 }, { 4, 11, 634 }, { 6, 0, 656 }, { 6, 11, 1730 }, + { 6, 0, 1940 }, { 5, 0, 104 }, { 6, 0, 173 }, { 7, 0, 1631 }, + { 8, 10, 562 }, { 6, 11, 36 }, { 7, 11, 658 }, { 8, 11, 454 }, + { 19, 11, 86 }, { 5, 0, 457 }, { 6, 10, 1771 }, { 7, 0, 810 }, + { 8, 0, 138 }, { 8, 0, 342 }, { 9, 0, 84 }, { 10, 0, 193 }, + { 11, 0, 883 }, { 12, 0, 359 }, { 9, 0, 620 }, { 7, 10, 1190 }, + { 9, 10, 132 }, { 7, 11, 975 }, { 9, 11, 789 }, { 6, 0, 95 }, + { 6, 0, 1934 }, { 8, 0, 967 }, { 13, 11, 335 }, { 6, 0, 406 }, + { 10, 0, 409 }, { 10, 0, 447 }, { 11, 0, 44 }, { 12, 0, 100 }, + { 4, 10, 317 }, { 7, 10, 1279 }, { 4, 0, 477 }, { 6, 0, 1268 }, + { 6, 0, 1941 }, { 8, 0, 944 }, { 5, 10, 63 }, { 5, 10, 509 }, + { 4, 0, 629 }, { 4, 11, 104 }, { 4, 0, 246 }, { 5, 0, 375 }, + { 6, 0, 1636 }, { 4, 10, 288 }, { 7, 11, 1614 }, { 9, 0, 49 }, + { 10, 0, 774 }, { 8, 10, 89 }, { 8, 10, 620 }, { 11, 10, 628 }, + { 12, 10, 322 }, { 15, 10, 124 }, { 4, 0, 282 }, { 7, 0, 1034 }, + { 11, 0, 398 }, { 11, 0, 634 }, { 12, 0, 1 }, { 12, 0, 79 }, + { 12, 0, 544 }, { 14, 0, 237 }, { 17, 0, 10 }, { 18, 0, 20 }, + { 4, 0, 824 }, { 7, 11, 45 }, { 9, 11, 542 }, { 9, 11, 566 }, + { 10, 11, 728 }, { 5, 0, 118 }, { 5, 0, 499 }, { 6, 0, 476 }, + { 6, 0, 665 }, { 6, 0, 1176 }, { 6, 0, 1196 }, { 7, 0, 600 }, + { 7, 0, 888 }, { 7, 0, 1096 }, { 7, 0, 296 }, { 7, 0, 596 }, + { 8, 0, 560 }, { 8, 0, 586 }, { 9, 0, 612 }, { 11, 0, 304 }, + { 12, 0, 46 }, { 13, 0, 89 }, { 14, 0, 112 }, { 17, 0, 122 }, + { 5, 0, 894 }, { 6, 0, 1772 }, { 9, 0, 1009 }, { 10, 10, 120 }, + { 5, 11, 533 }, { 7, 11, 755 }, { 10, 11, 780 }, { 23, 10, 1 }, + { 6, 0, 1474 }, { 7, 11, 87 }, { 14, 11, 288 }, { 11, 0, 366 }, + { 9, 10, 461 }, { 7, 11, 988 }, { 7, 11, 1939 }, { 9, 11, 64 }, + { 9, 11, 502 }, { 12, 11, 7 }, { 12, 11, 34 }, { 13, 11, 12 }, + { 13, 11, 234 }, { 19, 11, 77 }, { 7, 0, 1599 }, { 7, 0, 1723 }, + { 8, 0, 79 }, { 8, 0, 106 }, { 8, 0, 190 }, { 8, 0, 302 }, + { 8, 0, 383 }, { 8, 0, 713 }, { 9, 0, 119 }, { 9, 0, 233 }, + { 9, 0, 419 }, { 9, 0, 471 }, { 10, 0, 181 }, { 10, 0, 406 }, + { 11, 0, 57 }, { 11, 0, 85 }, { 11, 0, 120 }, { 11, 0, 177 }, + { 11, 0, 296 }, { 11, 0, 382 }, { 11, 0, 454 }, { 11, 0, 758 }, + { 11, 0, 999 }, { 12, 0, 27 }, { 12, 0, 98 }, { 12, 0, 131 }, + { 12, 0, 245 }, { 12, 0, 312 }, { 12, 0, 446 }, { 12, 0, 454 }, + { 13, 0, 25 }, { 13, 0, 98 }, { 13, 0, 426 }, { 13, 0, 508 }, + { 14, 0, 70 }, { 14, 0, 163 }, { 14, 0, 272 }, { 14, 0, 277 }, + { 14, 0, 370 }, { 15, 0, 95 }, { 15, 0, 138 }, { 15, 0, 167 }, + { 17, 0, 38 }, { 20, 0, 96 }, { 7, 10, 1346 }, { 10, 0, 200 }, + { 19, 0, 2 }, { 23, 0, 22 }, { 7, 11, 141 }, { 6, 10, 85 }, + { 6, 0, 1759 }, { 10, 0, 372 }, { 17, 0, 16 }, { 8, 0, 943 }, + { 4, 11, 619 }, { 11, 11, 88 }, { 5, 11, 246 }, { 8, 11, 189 }, + { 9, 11, 355 }, { 9, 11, 512 }, { 10, 11, 124 }, { 10, 11, 453 }, + { 11, 11, 143 }, { 11, 11, 416 }, { 11, 11, 859 }, { 13, 11, 341 }, + { 5, 0, 258 }, { 6, 0, 719 }, { 6, 0, 1798 }, { 6, 0, 1839 }, + { 8, 0, 900 }, { 10, 0, 874 }, { 10, 0, 886 }, { 12, 0, 698 }, + { 12, 0, 732 }, { 12, 0, 770 }, { 16, 0, 106 }, { 18, 0, 163 }, + { 18, 0, 170 }, { 18, 0, 171 }, { 24, 0, 20 }, { 9, 0, 707 }, + { 11, 0, 326 }, { 11, 0, 339 }, { 12, 0, 423 }, { 12, 0, 502 }, + { 20, 0, 62 }, { 9, 11, 707 }, { 11, 11, 326 }, { 11, 11, 339 }, + { 12, 11, 423 }, { 12, 11, 502 }, { 20, 11, 62 }, { 5, 0, 30 }, + { 7, 0, 495 }, { 8, 0, 134 }, { 9, 0, 788 }, { 12, 0, 438 }, + { 5, 11, 678 }, { 5, 10, 279 }, { 6, 10, 235 }, { 7, 10, 468 }, + { 8, 10, 446 }, { 9, 10, 637 }, { 10, 10, 717 }, { 11, 10, 738 }, + { 12, 10, 514 }, { 5, 11, 35 }, { 6, 11, 287 }, { 7, 11, 862 }, + { 7, 11, 1886 }, { 10, 11, 179 }, { 7, 0, 1948 }, { 7, 0, 2004 }, + { 4, 11, 517 }, { 5, 10, 17 }, { 6, 10, 371 }, { 9, 10, 528 }, + { 4, 0, 115 }, { 5, 0, 669 }, { 6, 0, 407 }, { 8, 0, 311 }, + { 11, 0, 10 }, { 13, 0, 5 }, { 9, 0, 381 }, { 5, 0, 50 }, + { 6, 0, 439 }, { 7, 0, 780 }, { 7, 0, 1040 }, { 8, 11, 667 }, + { 11, 11, 403 }, { 18, 11, 83 }, { 5, 0, 1 }, { 6, 0, 81 }, + { 10, 0, 520 }, { 6, 0, 738 }, { 5, 0, 482 }, { 8, 0, 98 }, + { 9, 0, 172 }, { 10, 0, 360 }, { 10, 0, 700 }, { 10, 0, 822 }, + { 11, 0, 302 }, { 11, 0, 778 }, { 12, 0, 50 }, { 12, 0, 127 }, + { 12, 0, 396 }, { 13, 0, 62 }, { 13, 0, 328 }, { 14, 0, 122 }, + { 19, 0, 72 }, { 9, 11, 157 }, { 10, 11, 131 }, { 12, 11, 72 }, + { 7, 11, 714 }, { 7, 11, 539 }, { 5, 0, 2 }, { 6, 0, 512 }, + { 7, 0, 797 }, { 7, 0, 1494 }, { 8, 0, 253 }, { 8, 0, 589 }, + { 9, 0, 77 }, { 10, 0, 1 }, { 10, 0, 129 }, { 10, 0, 225 }, + { 11, 0, 118 }, { 11, 0, 226 }, { 11, 0, 251 }, { 11, 0, 430 }, + { 11, 0, 701 }, { 11, 0, 974 }, { 11, 0, 982 }, { 12, 0, 64 }, + { 12, 0, 260 }, { 12, 0, 488 }, { 12, 0, 690 }, { 5, 11, 394 }, + { 7, 11, 367 }, { 7, 11, 487 }, { 7, 11, 857 }, { 7, 11, 1713 }, + { 8, 11, 246 }, { 9, 11, 537 }, { 10, 11, 165 }, { 12, 11, 219 }, + { 12, 11, 561 }, { 8, 0, 557 }, { 5, 10, 779 }, { 5, 10, 807 }, + { 6, 10, 1655 }, { 6, 10, 1676 }, { 4, 10, 196 }, { 5, 10, 558 }, + { 5, 10, 949 }, { 11, 11, 827 }, { 12, 11, 56 }, { 14, 11, 34 }, + { 15, 11, 148 }, { 9, 0, 347 }, { 5, 0, 572 }, { 6, 0, 832 }, + { 4, 0, 12 }, { 7, 0, 504 }, { 7, 0, 522 }, { 7, 0, 809 }, + { 8, 0, 797 }, { 13, 0, 88 }, { 4, 10, 752 }, { 5, 11, 449 }, + { 7, 11, 86 }, { 8, 11, 103 }, { 17, 11, 69 }, { 7, 11, 2028 }, + { 10, 11, 641 }, { 5, 0, 528 }, { 6, 11, 1 }, { 14, 11, 2 }, + { 6, 0, 861 }, { 10, 0, 294 }, { 4, 10, 227 }, { 5, 10, 159 }, + { 5, 10, 409 }, { 7, 10, 80 }, { 10, 10, 479 }, { 12, 10, 418 }, + { 14, 10, 50 }, { 14, 10, 249 }, { 14, 10, 295 }, { 7, 10, 1470 }, + { 8, 10, 66 }, { 8, 10, 137 }, { 8, 10, 761 }, { 9, 10, 638 }, + { 11, 10, 80 }, { 11, 10, 212 }, { 11, 10, 368 }, { 11, 10, 418 }, + { 12, 10, 8 }, { 13, 10, 15 }, { 16, 10, 61 }, { 17, 10, 59 }, + { 19, 10, 28 }, { 20, 10, 84 }, { 20, 0, 109 }, { 7, 11, 1148 }, + { 6, 11, 277 }, { 7, 11, 1274 }, { 7, 11, 1386 }, { 7, 11, 1392 }, + { 12, 11, 129 }, { 18, 11, 87 }, { 6, 11, 187 }, { 7, 11, 39 }, + { 7, 11, 1203 }, { 8, 11, 380 }, { 8, 11, 542 }, { 14, 11, 117 }, + { 21, 11, 28 }, { 6, 0, 1187 }, { 5, 0, 266 }, { 9, 0, 290 }, + { 9, 0, 364 }, { 10, 0, 293 }, { 11, 0, 606 }, { 14, 0, 45 }, + { 6, 11, 297 }, { 7, 11, 793 }, { 11, 11, 938 }, { 4, 0, 50 }, + { 6, 0, 594 }, { 9, 0, 121 }, { 10, 0, 49 }, { 10, 0, 412 }, + { 11, 0, 834 }, { 8, 0, 748 }, { 7, 11, 464 }, { 8, 11, 438 }, + { 11, 11, 105 }, { 11, 11, 363 }, { 12, 11, 231 }, { 14, 11, 386 }, + { 15, 11, 102 }, { 20, 11, 75 }, { 4, 0, 466 }, { 13, 0, 399 }, + { 14, 0, 337 }, { 6, 10, 38 }, { 7, 10, 1220 }, { 8, 10, 185 }, + { 8, 10, 256 }, { 9, 10, 22 }, { 9, 10, 331 }, { 10, 10, 738 }, + { 11, 10, 205 }, { 11, 10, 540 }, { 11, 10, 746 }, { 13, 10, 465 }, + { 14, 10, 194 }, { 9, 0, 378 }, { 13, 0, 162 }, { 9, 0, 519 }, + { 4, 10, 159 }, { 6, 10, 115 }, { 7, 10, 252 }, { 7, 10, 257 }, + { 7, 10, 1928 }, { 8, 10, 69 }, { 9, 10, 384 }, { 10, 10, 91 }, + { 10, 10, 615 }, { 12, 10, 375 }, { 14, 10, 235 }, { 18, 10, 117 }, + { 19, 10, 123 }, { 5, 11, 604 }, { 5, 10, 911 }, { 8, 10, 278 }, + { 4, 0, 667 }, { 8, 0, 351 }, { 9, 0, 322 }, { 4, 10, 151 }, + { 7, 10, 1567 }, { 6, 0, 902 }, { 5, 10, 990 }, { 12, 0, 180 }, + { 5, 10, 194 }, { 7, 10, 1662 }, { 9, 10, 90 }, { 4, 0, 869 }, + { 6, 0, 1996 }, { 6, 0, 813 }, { 5, 10, 425 }, { 9, 11, 761 }, + { 4, 0, 260 }, { 5, 10, 971 }, { 5, 11, 20 }, { 6, 11, 298 }, + { 7, 11, 659 }, { 7, 11, 1366 }, { 9, 11, 219 }, { 4, 0, 39 }, + { 5, 0, 36 }, { 7, 0, 1843 }, { 8, 0, 407 }, { 11, 0, 144 }, + { 12, 0, 523 }, { 4, 0, 510 }, { 10, 0, 587 }, { 11, 10, 752 }, + { 7, 0, 29 }, { 7, 0, 66 }, { 7, 0, 1980 }, { 10, 0, 487 }, + { 10, 0, 809 }, { 13, 0, 260 }, { 14, 0, 82 }, { 18, 0, 63 }, + { 9, 10, 662 }, { 5, 10, 72 }, { 6, 10, 264 }, { 7, 10, 21 }, + { 7, 10, 46 }, { 7, 10, 2013 }, { 8, 10, 215 }, { 8, 10, 513 }, + { 10, 10, 266 }, { 11, 10, 22 }, { 6, 0, 570 }, { 6, 0, 565 }, + { 7, 0, 1667 }, { 4, 11, 439 }, { 10, 10, 95 }, { 11, 10, 603 }, + { 12, 11, 242 }, { 13, 10, 443 }, { 14, 10, 160 }, { 15, 10, 4 }, + { 6, 0, 1464 }, { 6, 10, 431 }, { 9, 0, 372 }, { 15, 0, 2 }, + { 19, 0, 10 }, { 19, 0, 18 }, { 5, 10, 874 }, { 6, 10, 1677 }, + { 15, 10, 0 }, { 4, 0, 787 }, { 6, 0, 380 }, { 12, 0, 399 }, + { 21, 0, 19 }, { 7, 10, 939 }, { 7, 10, 1172 }, { 7, 10, 1671 }, + { 9, 10, 540 }, { 10, 10, 696 }, { 11, 10, 265 }, { 11, 10, 732 }, + { 11, 10, 928 }, { 11, 10, 937 }, { 13, 10, 438 }, { 9, 0, 200 }, + { 4, 11, 233 }, { 4, 0, 516 }, { 6, 11, 577 }, { 4, 0, 844 }, + { 11, 0, 887 }, { 14, 0, 365 }, { 14, 0, 375 }, { 4, 11, 482 }, + { 8, 0, 821 }, { 12, 0, 44 }, { 7, 0, 1655 }, { 8, 0, 305 }, + { 5, 10, 682 }, { 7, 10, 1887 }, { 7, 11, 346 }, { 4, 10, 696 }, + { 4, 0, 10 }, { 7, 0, 917 }, { 11, 0, 786 }, { 5, 11, 795 }, + { 6, 11, 1741 }, { 8, 11, 417 }, { 9, 11, 782 }, { 4, 0, 1016 }, + { 6, 0, 2031 }, { 5, 0, 684 }, { 4, 10, 726 }, { 5, 10, 630 }, + { 6, 0, 1021 }, { 6, 0, 1480 }, { 8, 10, 802 }, { 8, 10, 838 }, + { 6, 0, 27 }, { 6, 0, 395 }, { 7, 11, 622 }, { 7, 11, 625 }, + { 7, 11, 1750 }, { 4, 11, 203 }, { 7, 11, 1936 }, { 6, 10, 118 }, + { 7, 10, 215 }, { 7, 10, 1521 }, { 12, 10, 11 }, { 4, 0, 813 }, + { 8, 0, 511 }, { 7, 10, 615 }, { 10, 10, 251 }, { 7, 10, 1044 }, + { 17, 0, 56 }, { 5, 10, 225 }, { 6, 0, 342 }, { 6, 0, 496 }, + { 8, 0, 275 }, { 9, 0, 206 }, { 4, 0, 909 }, { 5, 0, 940 }, + { 4, 0, 891 }, { 7, 11, 311 }, { 9, 11, 308 }, { 12, 11, 255 }, + { 4, 10, 370 }, { 5, 10, 756 }, { 7, 10, 1326 }, { 4, 0, 687 }, + { 6, 0, 1596 }, { 6, 0, 1342 }, { 6, 10, 1662 }, { 7, 10, 48 }, + { 8, 10, 771 }, { 10, 10, 116 }, { 13, 10, 104 }, { 14, 10, 105 }, + { 14, 10, 184 }, { 15, 10, 168 }, { 19, 10, 92 }, { 20, 10, 68 }, + { 10, 10, 209 }, { 4, 11, 400 }, { 5, 11, 267 }, { 7, 11, 232 }, + { 23, 11, 12 }, { 6, 0, 41 }, { 13, 0, 160 }, { 13, 11, 314 }, + { 6, 0, 1718 }, { 8, 0, 778 }, { 14, 11, 261 }, { 6, 0, 1610 }, + { 5, 0, 115 }, { 4, 0, 294 }, { 14, 0, 314 }, { 4, 10, 120 }, + { 4, 0, 983 }, { 5, 0, 193 }, { 12, 0, 178 }, { 10, 10, 429 }, + { 5, 10, 820 }, { 7, 10, 931 }, { 6, 0, 994 }, { 6, 0, 1051 }, + { 6, 0, 1439 }, { 7, 0, 174 }, { 5, 11, 732 }, { 4, 11, 100 }, + { 7, 11, 679 }, { 8, 11, 313 }, { 10, 10, 199 }, { 6, 10, 151 }, + { 6, 10, 1675 }, { 7, 10, 383 }, { 23, 10, 10 }, { 6, 0, 1796 }, + { 8, 0, 848 }, { 8, 0, 867 }, { 8, 0, 907 }, { 10, 0, 855 }, + { 12, 0, 703 }, { 12, 0, 221 }, { 4, 0, 122 }, { 5, 0, 796 }, + { 5, 0, 952 }, { 6, 0, 1660 }, { 6, 0, 1671 }, { 8, 0, 567 }, + { 9, 0, 687 }, { 9, 0, 742 }, { 10, 0, 686 }, { 11, 0, 682 }, + { 11, 0, 909 }, { 12, 0, 281 }, { 5, 11, 362 }, { 5, 11, 443 }, + { 6, 11, 318 }, { 7, 11, 1019 }, { 11, 11, 623 }, { 5, 11, 463 }, + { 8, 11, 296 }, { 11, 0, 583 }, { 13, 0, 262 }, { 6, 10, 1624 }, + { 12, 10, 422 }, { 14, 10, 360 }, { 5, 0, 179 }, { 7, 0, 1095 }, + { 7, 0, 1213 }, { 4, 10, 43 }, { 4, 11, 454 }, { 5, 10, 344 }, + { 5, 10, 357 }, { 4, 0, 66 }, { 7, 0, 722 }, { 7, 0, 904 }, + { 6, 0, 773 }, { 7, 0, 352 }, { 5, 10, 888 }, { 5, 11, 48 }, + { 5, 11, 404 }, { 6, 11, 557 }, { 7, 11, 458 }, { 8, 11, 597 }, + { 10, 11, 455 }, { 10, 11, 606 }, { 11, 11, 49 }, { 11, 11, 548 }, + { 12, 11, 476 }, { 13, 11, 18 }, { 13, 11, 450 }, { 6, 11, 418 }, + { 4, 10, 711 }, { 5, 11, 442 }, { 7, 11, 1984 }, { 13, 0, 35 }, + { 9, 0, 152 }, { 6, 0, 1197 }, { 7, 11, 1093 }, { 9, 11, 203 }, + { 9, 10, 440 }, { 10, 0, 592 }, { 10, 0, 753 }, { 12, 0, 317 }, + { 12, 0, 355 }, { 12, 0, 465 }, { 12, 0, 469 }, { 12, 0, 560 }, + { 12, 0, 578 }, { 13, 0, 243 }, { 5, 0, 564 }, { 6, 0, 797 }, + { 5, 10, 958 }, { 5, 10, 987 }, { 5, 11, 55 }, { 7, 11, 376 }, + { 12, 11, 161 }, { 5, 11, 450 }, { 6, 0, 556 }, { 6, 0, 819 }, + { 11, 10, 276 }, { 14, 10, 293 }, { 7, 0, 544 }, { 10, 0, 61 }, + { 8, 0, 719 }, { 4, 10, 65 }, { 5, 10, 479 }, { 5, 10, 1004 }, + { 7, 10, 1913 }, { 8, 10, 317 }, { 9, 10, 302 }, { 10, 10, 612 }, + { 13, 10, 22 }, { 4, 0, 5 }, { 5, 0, 498 }, { 8, 0, 637 }, + { 9, 0, 521 }, { 4, 11, 213 }, { 4, 10, 261 }, { 7, 11, 223 }, + { 7, 10, 510 }, { 8, 11, 80 }, { 5, 0, 927 }, { 7, 0, 101 }, + { 4, 10, 291 }, { 7, 11, 381 }, { 7, 11, 806 }, { 7, 11, 820 }, + { 8, 11, 354 }, { 8, 11, 437 }, { 8, 11, 787 }, { 9, 10, 515 }, + { 9, 11, 657 }, { 10, 11, 58 }, { 10, 11, 339 }, { 10, 11, 749 }, + { 11, 11, 914 }, { 12, 10, 152 }, { 12, 11, 162 }, { 12, 10, 443 }, + { 13, 11, 75 }, { 13, 10, 392 }, { 14, 11, 106 }, { 14, 11, 198 }, + { 14, 11, 320 }, { 14, 10, 357 }, { 14, 11, 413 }, { 18, 11, 43 }, + { 6, 0, 1153 }, { 7, 0, 1441 }, { 8, 11, 747 }, { 4, 0, 893 }, + { 5, 0, 780 }, { 5, 0, 893 }, { 10, 11, 654 }, { 5, 11, 692 }, + { 5, 0, 238 }, { 6, 11, 191 }, { 4, 10, 130 }, { 7, 10, 843 }, + { 6, 0, 1296 }, { 5, 10, 42 }, { 5, 10, 879 }, { 7, 10, 245 }, + { 7, 10, 324 }, { 7, 10, 1532 }, { 11, 10, 463 }, { 11, 10, 472 }, + { 13, 10, 363 }, { 16, 10, 52 }, { 6, 0, 1729 }, { 6, 0, 1999 }, + { 8, 0, 969 }, { 4, 10, 134 }, { 5, 10, 372 }, { 4, 0, 60 }, + { 7, 0, 941 }, { 7, 0, 1800 }, { 8, 0, 314 }, { 9, 0, 700 }, + { 11, 0, 487 }, { 6, 0, 1144 }, { 6, 11, 162 }, { 7, 11, 1960 }, + { 8, 11, 831 }, { 4, 11, 706 }, { 7, 0, 1147 }, { 10, 11, 426 }, + { 10, 11, 89 }, { 7, 0, 1853 }, { 10, 0, 437 }, { 8, 0, 419 }, + { 7, 10, 1634 }, { 5, 0, 828 }, { 5, 0, 806 }, { 7, 0, 176 }, + { 7, 0, 178 }, { 7, 0, 1240 }, { 7, 0, 1976 }, { 4, 10, 644 }, + { 7, 11, 1877 }, { 5, 11, 420 }, { 7, 11, 1449 }, { 4, 0, 51 }, + { 5, 0, 39 }, { 6, 0, 4 }, { 7, 0, 591 }, { 7, 0, 849 }, + { 7, 0, 951 }, { 7, 0, 1613 }, { 7, 0, 1760 }, { 7, 0, 1988 }, + { 9, 0, 434 }, { 10, 0, 754 }, { 11, 0, 25 }, { 11, 0, 37 }, + { 10, 11, 57 }, { 10, 11, 277 }, { 7, 10, 540 }, { 4, 11, 204 }, + { 7, 0, 159 }, { 11, 11, 231 }, { 5, 0, 902 }, { 7, 0, 928 }, + { 7, 11, 366 }, { 9, 11, 287 }, { 12, 11, 199 }, { 12, 11, 556 }, + { 12, 11, 577 }, { 6, 10, 623 }, { 8, 10, 789 }, { 4, 10, 908 }, + { 5, 10, 359 }, { 5, 10, 508 }, { 6, 10, 1723 }, { 7, 10, 343 }, + { 7, 10, 1996 }, { 7, 10, 2026 }, { 6, 0, 270 }, { 4, 10, 341 }, + { 7, 10, 480 }, { 5, 11, 356 }, { 7, 11, 224 }, { 11, 11, 588 }, + { 11, 11, 864 }, { 11, 11, 968 }, { 15, 11, 160 }, { 4, 0, 556 }, + { 9, 0, 801 }, { 4, 0, 416 }, { 14, 0, 372 }, { 5, 0, 152 }, + { 5, 0, 197 }, { 7, 0, 340 }, { 7, 0, 867 }, { 10, 0, 548 }, + { 10, 0, 581 }, { 11, 0, 6 }, { 12, 0, 3 }, { 12, 0, 19 }, + { 14, 0, 110 }, { 14, 0, 289 }, { 11, 0, 369 }, { 7, 11, 630 }, + { 9, 11, 567 }, { 11, 11, 150 }, { 11, 11, 444 }, { 13, 11, 119 }, + { 6, 11, 539 }, { 7, 10, 1995 }, { 8, 10, 299 }, { 11, 10, 890 }, + { 12, 10, 674 }, { 7, 0, 34 }, { 7, 0, 190 }, { 8, 0, 28 }, + { 8, 0, 141 }, { 8, 0, 444 }, { 8, 0, 811 }, { 9, 0, 468 }, + { 11, 0, 334 }, { 12, 0, 24 }, { 12, 0, 386 }, { 12, 0, 576 }, + { 5, 0, 757 }, { 7, 0, 1553 }, { 8, 0, 898 }, { 5, 0, 721 }, + { 8, 0, 1012 }, { 4, 0, 789 }, { 5, 0, 647 }, { 7, 0, 1102 }, + { 4, 0, 898 }, { 10, 0, 183 }, { 4, 10, 238 }, { 5, 10, 503 }, + { 6, 10, 179 }, { 7, 10, 2003 }, { 8, 10, 381 }, { 8, 10, 473 }, + { 9, 10, 149 }, { 10, 10, 788 }, { 15, 10, 45 }, { 15, 10, 86 }, + { 20, 10, 110 }, { 22, 10, 57 }, { 9, 0, 136 }, { 19, 0, 107 }, + { 4, 10, 121 }, { 5, 10, 156 }, { 5, 10, 349 }, { 10, 10, 605 }, + { 14, 10, 342 }, { 4, 11, 235 }, { 7, 11, 255 }, { 4, 11, 194 }, + { 5, 11, 584 }, { 6, 11, 384 }, { 7, 11, 583 }, { 10, 11, 761 }, + { 11, 11, 760 }, { 11, 11, 851 }, { 6, 10, 80 }, { 6, 10, 1694 }, + { 7, 10, 173 }, { 7, 10, 1974 }, { 9, 10, 547 }, { 10, 10, 730 }, + { 14, 10, 18 }, { 22, 10, 39 }, { 4, 10, 923 }, { 6, 10, 1711 }, + { 5, 0, 277 }, { 13, 0, 247 }, { 4, 0, 435 }, { 5, 11, 562 }, + { 6, 0, 1311 }, { 5, 11, 191 }, { 9, 11, 271 }, { 4, 10, 595 }, + { 7, 11, 1537 }, { 14, 11, 96 }, { 15, 11, 73 }, { 5, 0, 437 }, + { 7, 0, 502 }, { 7, 0, 519 }, { 7, 0, 1122 }, { 7, 0, 1751 }, + { 14, 0, 211 }, { 6, 10, 459 }, { 7, 10, 1753 }, { 7, 10, 1805 }, + { 8, 10, 658 }, { 9, 10, 1 }, { 11, 10, 959 }, { 13, 10, 446 }, + { 6, 0, 814 }, { 4, 11, 470 }, { 5, 11, 473 }, { 6, 11, 153 }, + { 7, 11, 1503 }, { 7, 11, 1923 }, { 10, 11, 701 }, { 11, 11, 132 }, + { 11, 11, 168 }, { 11, 11, 227 }, { 11, 11, 320 }, { 11, 11, 436 }, + { 11, 11, 525 }, { 11, 11, 855 }, { 12, 11, 41 }, { 12, 11, 286 }, + { 13, 11, 103 }, { 13, 11, 284 }, { 14, 11, 255 }, { 14, 11, 262 }, + { 15, 11, 117 }, { 15, 11, 127 }, { 5, 0, 265 }, { 6, 0, 212 }, + { 7, 0, 28 }, { 10, 0, 750 }, { 5, 11, 327 }, { 6, 11, 552 }, + { 7, 11, 1754 }, { 9, 11, 604 }, { 6, 0, 2012 }, { 4, 0, 702 }, + { 5, 11, 80 }, { 6, 11, 405 }, { 7, 11, 403 }, { 7, 11, 1502 }, + { 7, 11, 1626 }, { 8, 11, 456 }, { 9, 11, 487 }, { 9, 11, 853 }, + { 9, 11, 889 }, { 10, 11, 309 }, { 11, 11, 721 }, { 11, 11, 994 }, + { 12, 11, 430 }, { 13, 11, 165 }, { 5, 0, 808 }, { 7, 0, 2045 }, + { 5, 0, 166 }, { 8, 0, 739 }, { 12, 0, 511 }, { 6, 10, 490 }, + { 4, 11, 453 }, { 5, 11, 887 }, { 6, 11, 535 }, { 8, 11, 6 }, + { 8, 11, 543 }, { 4, 0, 119 }, { 5, 0, 170 }, { 5, 0, 447 }, + { 7, 0, 1708 }, { 7, 0, 1889 }, { 9, 0, 357 }, { 9, 0, 719 }, + { 12, 0, 486 }, { 12, 0, 596 }, { 9, 0, 500 }, { 7, 10, 250 }, + { 8, 10, 507 }, { 4, 10, 158 }, { 6, 0, 809 }, { 6, 0, 1500 }, + { 9, 0, 327 }, { 11, 0, 350 }, { 11, 0, 831 }, { 13, 0, 352 }, + { 4, 10, 140 }, { 7, 10, 362 }, { 8, 10, 209 }, { 9, 10, 10 }, + { 9, 10, 503 }, { 9, 10, 614 }, { 10, 10, 689 }, { 11, 10, 327 }, + { 11, 10, 725 }, { 12, 10, 252 }, { 12, 10, 583 }, { 13, 10, 192 }, + { 14, 10, 269 }, { 14, 10, 356 }, { 20, 10, 50 }, { 7, 11, 741 }, + { 4, 0, 450 }, { 7, 0, 1158 }, { 19, 10, 1 }, { 19, 10, 26 }, + { 22, 10, 9 }, { 6, 0, 597 }, { 7, 0, 1318 }, { 6, 0, 1602 }, + { 6, 10, 228 }, { 7, 10, 1341 }, { 9, 10, 408 }, { 10, 10, 343 }, + { 7, 0, 1375 }, { 7, 0, 1466 }, { 10, 0, 331 }, { 4, 0, 754 }, + { 4, 10, 557 }, { 5, 11, 101 }, { 6, 11, 88 }, { 6, 11, 543 }, + { 7, 11, 1677 }, { 9, 11, 100 }, { 10, 11, 677 }, { 14, 11, 169 }, + { 14, 11, 302 }, { 14, 11, 313 }, { 15, 11, 48 }, { 15, 11, 84 }, + { 6, 0, 1368 }, { 4, 11, 310 }, { 9, 11, 795 }, { 10, 11, 733 }, + { 11, 11, 451 }, { 12, 11, 249 }, { 14, 11, 115 }, { 14, 11, 286 }, + { 15, 11, 100 }, { 4, 10, 548 }, { 10, 0, 557 }, { 7, 10, 197 }, + { 8, 10, 142 }, { 8, 10, 325 }, { 9, 10, 150 }, { 9, 10, 596 }, + { 10, 10, 353 }, { 11, 10, 74 }, { 11, 10, 315 }, { 12, 10, 662 }, + { 12, 10, 681 }, { 14, 10, 423 }, { 15, 10, 141 }, { 5, 11, 587 }, + { 5, 0, 850 }, { 8, 0, 799 }, { 10, 0, 908 }, { 12, 0, 701 }, + { 12, 0, 757 }, { 14, 0, 466 }, { 4, 0, 62 }, { 5, 0, 275 }, + { 18, 0, 19 }, { 6, 10, 399 }, { 6, 10, 579 }, { 7, 10, 692 }, + { 7, 10, 846 }, { 7, 10, 1015 }, { 7, 10, 1799 }, { 8, 10, 403 }, + { 9, 10, 394 }, { 10, 10, 133 }, { 12, 10, 4 }, { 12, 10, 297 }, + { 12, 10, 452 }, { 16, 10, 81 }, { 18, 10, 25 }, { 21, 10, 14 }, + { 22, 10, 12 }, { 23, 10, 18 }, { 12, 0, 459 }, { 7, 10, 1546 }, + { 11, 10, 299 }, { 14, 10, 407 }, { 4, 10, 177 }, { 4, 11, 498 }, + { 7, 11, 217 }, { 8, 11, 140 }, { 10, 11, 610 }, { 5, 10, 411 }, + { 7, 10, 653 }, { 6, 0, 1802 }, { 7, 10, 439 }, { 10, 10, 727 }, + { 11, 10, 260 }, { 11, 10, 684 }, { 5, 11, 905 }, { 11, 11, 580 }, + { 14, 11, 201 }, { 6, 0, 1397 }, { 5, 10, 208 }, { 7, 10, 753 }, + { 7, 10, 1528 }, { 7, 0, 238 }, { 7, 0, 2033 }, { 8, 0, 120 }, + { 8, 0, 188 }, { 8, 0, 659 }, { 9, 0, 598 }, { 10, 0, 466 }, + { 12, 0, 342 }, { 12, 0, 588 }, { 13, 0, 503 }, { 14, 0, 246 }, + { 15, 0, 92 }, { 7, 11, 1041 }, { 4, 11, 456 }, { 7, 11, 105 }, + { 7, 11, 358 }, { 7, 11, 1637 }, { 8, 11, 643 }, { 11, 11, 483 }, + { 6, 0, 1318 }, { 6, 0, 1324 }, { 4, 0, 201 }, { 7, 0, 1744 }, + { 8, 0, 602 }, { 11, 0, 247 }, { 11, 0, 826 }, { 17, 0, 65 }, + { 5, 10, 242 }, { 8, 0, 164 }, { 18, 0, 62 }, { 5, 10, 953 }, + { 11, 10, 802 }, { 5, 0, 615 }, { 7, 11, 1566 }, { 8, 11, 269 }, + { 9, 11, 212 }, { 9, 11, 718 }, { 14, 11, 15 }, { 14, 11, 132 }, + { 14, 11, 227 }, { 5, 10, 290 }, { 4, 10, 380 }, { 5, 10, 52 }, + { 7, 10, 277 }, { 9, 10, 368 }, { 11, 10, 791 }, { 7, 0, 1243 }, + { 5, 11, 539 }, { 11, 11, 919 }, { 13, 11, 409 }, { 8, 0, 968 }, + { 5, 11, 470 }, { 6, 0, 882 }, { 4, 0, 907 }, { 5, 0, 100 }, + { 10, 0, 329 }, { 12, 0, 416 }, { 21, 0, 29 }, { 10, 10, 138 }, + { 11, 10, 476 }, { 5, 10, 725 }, { 5, 10, 727 }, { 6, 11, 91 }, + { 7, 11, 435 }, { 7, 10, 1811 }, { 4, 11, 16 }, { 5, 11, 316 }, + { 5, 11, 842 }, { 6, 11, 370 }, { 6, 11, 1778 }, { 8, 11, 166 }, + { 11, 11, 812 }, { 12, 11, 206 }, { 12, 11, 351 }, { 14, 11, 418 }, + { 16, 11, 15 }, { 16, 11, 34 }, { 18, 11, 3 }, { 19, 11, 3 }, + { 19, 11, 7 }, { 20, 11, 4 }, { 21, 11, 21 }, { 4, 0, 176 }, + { 5, 0, 636 }, { 5, 0, 998 }, { 7, 0, 9 }, { 7, 0, 1508 }, + { 8, 0, 26 }, { 9, 0, 317 }, { 9, 0, 358 }, { 10, 0, 210 }, + { 10, 0, 292 }, { 10, 0, 533 }, { 11, 0, 555 }, { 12, 0, 526 }, + { 12, 0, 607 }, { 13, 0, 263 }, { 13, 0, 459 }, { 14, 0, 271 }, + { 6, 0, 256 }, { 8, 0, 265 }, { 4, 10, 38 }, { 7, 10, 307 }, + { 7, 10, 999 }, { 7, 10, 1481 }, { 7, 10, 1732 }, { 7, 10, 1738 }, + { 9, 10, 414 }, { 11, 10, 316 }, { 12, 10, 52 }, { 13, 10, 420 }, + { 19, 10, 100 }, { 7, 10, 1296 }, { 4, 11, 611 }, { 5, 11, 606 }, + { 4, 0, 643 }, { 14, 11, 21 }, { 5, 11, 715 }, { 5, 10, 723 }, + { 6, 0, 610 }, { 7, 11, 597 }, { 10, 0, 127 }, { 13, 0, 27 }, + { 6, 0, 1995 }, { 6, 0, 2001 }, { 8, 0, 119 }, { 8, 0, 973 }, + { 4, 11, 149 }, { 10, 11, 368 }, { 12, 0, 522 }, { 4, 11, 154 }, + { 5, 10, 109 }, { 6, 10, 1784 }, { 7, 11, 1134 }, { 7, 10, 1895 }, + { 8, 11, 105 }, { 12, 10, 296 }, { 12, 10, 302 }, { 4, 11, 31 }, + { 6, 11, 429 }, { 7, 11, 962 }, { 9, 11, 458 }, { 11, 11, 691 }, + { 10, 0, 553 }, { 11, 0, 876 }, { 13, 0, 193 }, { 13, 0, 423 }, + { 14, 0, 166 }, { 19, 0, 84 }, { 4, 11, 312 }, { 5, 10, 216 }, + { 7, 10, 1879 }, { 9, 10, 141 }, { 9, 10, 270 }, { 9, 10, 679 }, + { 10, 10, 159 }, { 11, 10, 197 }, { 12, 10, 538 }, { 12, 10, 559 }, + { 14, 10, 144 }, { 14, 10, 167 }, { 15, 10, 67 }, { 6, 0, 1582 }, + { 7, 0, 1578 }, { 7, 11, 1578 }, { 9, 10, 81 }, { 4, 11, 236 }, + { 6, 10, 391 }, { 6, 0, 795 }, { 7, 10, 322 }, { 8, 10, 249 }, + { 5, 11, 836 }, { 5, 11, 857 }, { 6, 11, 1680 }, { 7, 11, 59 }, + { 19, 11, 53 }, { 7, 0, 432 }, { 10, 11, 68 }, { 11, 11, 494 }, + { 4, 11, 81 }, { 11, 11, 867 }, { 7, 0, 126 }, { 8, 0, 84 }, + { 14, 11, 280 }, { 5, 11, 282 }, { 8, 11, 650 }, { 9, 11, 295 }, + { 9, 11, 907 }, { 10, 11, 443 }, { 8, 0, 790 }, { 5, 10, 632 }, + { 10, 10, 526 }, { 6, 0, 64 }, { 12, 0, 377 }, { 13, 0, 309 }, + { 14, 0, 141 }, { 14, 0, 429 }, { 14, 11, 141 }, { 14, 11, 429 }, + { 6, 0, 1529 }, { 6, 0, 321 }, { 7, 0, 1857 }, { 9, 0, 530 }, + { 19, 0, 99 }, { 7, 10, 948 }, { 7, 10, 1042 }, { 8, 10, 235 }, + { 8, 10, 461 }, { 9, 10, 453 }, { 10, 10, 354 }, { 17, 10, 77 }, + { 7, 0, 1104 }, { 11, 0, 269 }, { 11, 0, 539 }, { 11, 0, 627 }, + { 11, 0, 706 }, { 11, 0, 975 }, { 12, 0, 248 }, { 12, 0, 434 }, + { 12, 0, 600 }, { 12, 0, 622 }, { 13, 0, 297 }, { 13, 0, 485 }, + { 14, 0, 69 }, { 14, 0, 409 }, { 15, 0, 108 }, { 4, 10, 362 }, + { 7, 10, 52 }, { 7, 10, 303 }, { 10, 11, 70 }, { 12, 11, 26 }, + { 14, 11, 17 }, { 14, 11, 178 }, { 15, 11, 34 }, { 21, 11, 12 }, + { 11, 0, 977 }, { 13, 0, 507 }, { 9, 0, 34 }, { 11, 0, 484 }, + { 5, 10, 196 }, { 6, 10, 486 }, { 7, 10, 212 }, { 8, 10, 309 }, + { 8, 10, 346 }, { 6, 0, 1700 }, { 7, 0, 26 }, { 7, 0, 293 }, + { 7, 0, 382 }, { 7, 0, 1026 }, { 7, 0, 1087 }, { 7, 0, 2027 }, + { 8, 0, 24 }, { 8, 0, 114 }, { 8, 0, 252 }, { 8, 0, 727 }, + { 8, 0, 729 }, { 9, 0, 30 }, { 9, 0, 199 }, { 9, 0, 231 }, + { 9, 0, 251 }, { 9, 0, 334 }, { 9, 0, 361 }, { 9, 0, 712 }, + { 10, 0, 55 }, { 10, 0, 60 }, { 10, 0, 232 }, { 10, 0, 332 }, + { 10, 0, 384 }, { 10, 0, 396 }, { 10, 0, 504 }, { 10, 0, 542 }, + { 10, 0, 652 }, { 11, 0, 20 }, { 11, 0, 48 }, { 11, 0, 207 }, + { 11, 0, 291 }, { 11, 0, 298 }, { 11, 0, 342 }, { 11, 0, 365 }, + { 11, 0, 394 }, { 11, 0, 620 }, { 11, 0, 705 }, { 11, 0, 1017 }, + { 12, 0, 123 }, { 12, 0, 340 }, { 12, 0, 406 }, { 12, 0, 643 }, + { 13, 0, 61 }, { 13, 0, 269 }, { 13, 0, 311 }, { 13, 0, 319 }, + { 13, 0, 486 }, { 14, 0, 234 }, { 15, 0, 62 }, { 15, 0, 85 }, + { 16, 0, 71 }, { 18, 0, 119 }, { 20, 0, 105 }, { 7, 10, 1912 }, + { 4, 11, 71 }, { 5, 11, 376 }, { 7, 11, 119 }, { 10, 11, 665 }, + { 10, 0, 918 }, { 10, 0, 926 }, { 4, 10, 686 }, { 8, 11, 55 }, + { 10, 10, 625 }, { 8, 10, 706 }, { 4, 11, 479 }, { 4, 10, 30 }, + { 5, 10, 43 }, { 6, 0, 379 }, { 7, 0, 270 }, { 8, 0, 176 }, + { 8, 0, 183 }, { 9, 0, 432 }, { 9, 0, 661 }, { 12, 0, 247 }, + { 12, 0, 617 }, { 18, 0, 125 }, { 7, 11, 607 }, { 8, 11, 99 }, + { 24, 11, 4 }, { 5, 0, 792 }, { 5, 0, 900 }, { 4, 11, 612 }, + { 5, 11, 561 }, { 4, 11, 41 }, { 4, 10, 220 }, { 5, 11, 74 }, + { 7, 10, 1535 }, { 7, 11, 1627 }, { 11, 11, 871 }, { 12, 11, 619 }, + { 7, 0, 1920 }, { 7, 11, 94 }, { 11, 11, 329 }, { 11, 11, 965 }, + { 12, 11, 241 }, { 14, 11, 354 }, { 15, 11, 22 }, { 20, 11, 63 }, + { 9, 11, 209 }, { 9, 11, 300 }, { 6, 0, 771 }, { 7, 0, 1979 }, + { 4, 0, 901 }, { 5, 0, 776 }, { 14, 0, 254 }, { 5, 11, 98 }, + { 9, 11, 16 }, { 13, 11, 386 }, { 5, 11, 984 }, { 4, 11, 182 }, + { 6, 11, 205 }, { 7, 11, 220 }, { 7, 10, 1725 }, { 7, 10, 1774 }, + { 10, 10, 393 }, { 5, 10, 263 }, { 6, 10, 414 }, { 4, 11, 42 }, + { 9, 11, 205 }, { 9, 11, 786 }, { 10, 11, 659 }, { 14, 0, 140 }, + { 20, 0, 41 }, { 8, 0, 440 }, { 10, 0, 359 }, { 6, 10, 178 }, + { 6, 11, 289 }, { 6, 10, 1750 }, { 7, 11, 1670 }, { 9, 10, 690 }, + { 10, 10, 155 }, { 10, 10, 373 }, { 11, 10, 698 }, { 12, 11, 57 }, + { 13, 10, 155 }, { 20, 10, 93 }, { 23, 11, 4 }, { 4, 0, 37 }, + { 5, 0, 334 }, { 7, 0, 1253 }, { 23, 11, 25 }, { 4, 0, 508 }, + { 4, 11, 635 }, { 5, 10, 97 }, { 9, 10, 393 }, { 11, 11, 533 }, + { 4, 0, 640 }, { 5, 0, 513 }, { 6, 10, 1639 }, { 4, 11, 371 }, + { 4, 11, 272 }, { 7, 11, 836 }, { 7, 11, 1651 }, { 17, 11, 89 }, + { 5, 11, 825 }, { 6, 11, 444 }, { 6, 11, 1640 }, { 8, 11, 308 }, + { 4, 10, 191 }, { 7, 10, 934 }, { 8, 10, 647 }, { 17, 10, 97 }, + { 12, 0, 246 }, { 15, 0, 162 }, { 19, 0, 64 }, { 20, 0, 8 }, + { 20, 0, 95 }, { 22, 0, 24 }, { 24, 0, 17 }, { 4, 0, 533 }, + { 5, 10, 165 }, { 9, 10, 346 }, { 10, 10, 655 }, { 5, 11, 737 }, + { 11, 10, 885 }, { 5, 10, 877 }, { 8, 10, 128 }, { 11, 10, 179 }, + { 9, 11, 307 }, { 12, 0, 752 }, { 5, 0, 920 }, { 7, 0, 1048 }, + { 5, 0, 153 }, { 6, 0, 580 }, { 6, 10, 1663 }, { 7, 10, 132 }, + { 7, 10, 1154 }, { 7, 10, 1415 }, { 7, 10, 1507 }, { 12, 10, 493 }, + { 15, 10, 105 }, { 23, 10, 15 }, { 5, 10, 459 }, { 7, 10, 1073 }, + { 8, 10, 241 }, { 8, 10, 334 }, { 10, 0, 391 }, { 7, 0, 1952 }, + { 5, 11, 525 }, { 8, 11, 641 }, { 11, 11, 388 }, { 12, 11, 580 }, + { 14, 0, 126 }, { 6, 0, 640 }, { 4, 0, 483 }, { 7, 0, 1616 }, + { 9, 0, 69 }, { 6, 10, 324 }, { 6, 10, 520 }, { 7, 10, 338 }, + { 7, 10, 1729 }, { 8, 10, 228 }, { 11, 10, 750 }, { 5, 11, 493 }, + { 6, 11, 528 }, { 7, 0, 734 }, { 4, 11, 174 }, { 7, 11, 911 }, + { 10, 0, 480 }, { 9, 0, 495 }, { 18, 0, 104 }, { 7, 10, 705 }, + { 9, 0, 472 }, { 4, 10, 73 }, { 6, 10, 612 }, { 7, 10, 927 }, + { 7, 10, 1330 }, { 7, 10, 1822 }, { 8, 10, 217 }, { 9, 10, 765 }, + { 9, 10, 766 }, { 10, 10, 408 }, { 11, 10, 51 }, { 11, 10, 793 }, + { 12, 10, 266 }, { 15, 10, 158 }, { 20, 10, 89 }, { 22, 10, 32 }, + { 7, 11, 548 }, { 9, 11, 58 }, { 4, 11, 32 }, { 5, 11, 215 }, + { 6, 11, 269 }, { 7, 11, 1782 }, { 7, 11, 1892 }, { 10, 11, 16 }, + { 11, 11, 822 }, { 11, 11, 954 }, { 13, 11, 481 }, { 4, 0, 874 }, + { 9, 0, 229 }, { 5, 10, 389 }, { 8, 10, 636 }, { 7, 11, 1749 }, + { 8, 11, 477 }, { 6, 0, 948 }, { 5, 11, 308 }, { 7, 11, 1088 }, + { 4, 0, 748 }, { 11, 0, 1009 }, { 8, 10, 21 }, { 6, 0, 555 }, + { 7, 0, 485 }, { 5, 11, 126 }, { 8, 11, 297 }, { 9, 11, 366 }, + { 9, 11, 445 }, { 12, 11, 53 }, { 12, 11, 374 }, { 13, 11, 492 }, + { 7, 11, 1551 }, { 11, 11, 361 }, { 8, 0, 193 }, { 8, 0, 472 }, + { 8, 0, 653 }, { 13, 0, 93 }, { 19, 0, 14 }, { 4, 0, 984 }, + { 4, 11, 175 }, { 5, 0, 172 }, { 6, 0, 1971 }, { 4, 11, 685 }, + { 21, 11, 8 }, { 5, 11, 797 }, { 13, 0, 83 }, { 5, 10, 189 }, + { 7, 10, 442 }, { 7, 10, 443 }, { 8, 10, 281 }, { 12, 10, 174 }, + { 13, 10, 261 }, { 6, 0, 1568 }, { 5, 11, 565 }, { 11, 0, 384 }, + { 5, 0, 260 }, { 7, 0, 758 }, { 7, 0, 880 }, { 7, 0, 1359 }, + { 9, 0, 164 }, { 9, 0, 167 }, { 10, 0, 156 }, { 10, 0, 588 }, + { 12, 0, 101 }, { 14, 0, 48 }, { 15, 0, 70 }, { 6, 10, 2 }, + { 7, 10, 1262 }, { 7, 10, 1737 }, { 8, 10, 22 }, { 8, 10, 270 }, + { 8, 10, 612 }, { 9, 10, 312 }, { 9, 10, 436 }, { 10, 10, 311 }, + { 10, 10, 623 }, { 11, 10, 72 }, { 11, 10, 330 }, { 11, 10, 455 }, + { 12, 10, 321 }, { 12, 10, 504 }, { 12, 10, 530 }, { 12, 10, 543 }, + { 13, 10, 17 }, { 13, 10, 156 }, { 13, 10, 334 }, { 17, 10, 60 }, + { 20, 10, 64 }, { 4, 11, 252 }, { 7, 11, 1068 }, { 10, 11, 434 }, + { 11, 11, 228 }, { 11, 11, 426 }, { 13, 11, 231 }, { 18, 11, 106 }, + { 20, 11, 87 }, { 7, 10, 354 }, { 10, 10, 410 }, { 11, 10, 815 }, + { 6, 0, 367 }, { 7, 10, 670 }, { 7, 10, 1327 }, { 8, 10, 411 }, + { 8, 10, 435 }, { 9, 10, 653 }, { 9, 10, 740 }, { 10, 10, 385 }, + { 11, 10, 222 }, { 11, 10, 324 }, { 11, 10, 829 }, { 12, 10, 611 }, + { 7, 0, 1174 }, { 6, 10, 166 }, { 7, 10, 374 }, { 18, 0, 121 }, + { 4, 0, 828 }, { 5, 11, 231 }, { 10, 11, 509 }, { 7, 11, 601 }, + { 9, 11, 277 }, { 9, 11, 674 }, { 10, 11, 178 }, { 10, 11, 257 }, + { 10, 11, 418 }, { 11, 11, 531 }, { 11, 11, 544 }, { 11, 11, 585 }, + { 12, 11, 113 }, { 12, 11, 475 }, { 13, 11, 99 }, { 14, 11, 428 }, + { 6, 0, 1541 }, { 7, 11, 1779 }, { 5, 0, 343 }, { 6, 10, 398 }, + { 7, 10, 50 }, { 7, 11, 1683 }, { 4, 0, 440 }, { 7, 0, 57 }, + { 8, 0, 167 }, { 8, 0, 375 }, { 9, 0, 82 }, { 9, 0, 561 }, + { 9, 0, 744 }, { 10, 0, 620 }, { 9, 11, 744 }, { 6, 0, 926 }, + { 6, 10, 517 }, { 7, 10, 1159 }, { 10, 10, 621 }, { 11, 10, 192 }, + { 9, 0, 827 }, { 8, 0, 194 }, { 8, 0, 756 }, { 10, 10, 223 }, + { 11, 10, 645 }, { 7, 10, 64 }, { 8, 10, 245 }, { 4, 11, 399 }, + { 5, 11, 119 }, { 5, 11, 494 }, { 7, 11, 751 }, { 9, 11, 556 }, + { 4, 0, 808 }, { 7, 0, 22 }, { 7, 10, 1763 }, { 12, 10, 310 }, + { 5, 0, 639 }, { 7, 0, 1249 }, { 11, 0, 896 }, { 6, 11, 584 }, + { 6, 0, 1614 }, { 7, 0, 860 }, { 7, 11, 1121 }, { 5, 10, 129 }, + { 6, 10, 61 }, { 7, 10, 947 }, { 4, 0, 102 }, { 7, 0, 815 }, + { 7, 0, 1699 }, { 11, 0, 964 }, { 13, 10, 505 }, { 13, 10, 506 }, + { 11, 10, 1000 }, { 4, 11, 679 }, { 4, 0, 899 }, { 4, 0, 569 }, + { 5, 11, 694 }, { 9, 11, 714 }, { 8, 0, 795 }, { 6, 0, 2045 }, + { 11, 11, 7 }, { 6, 0, 52 }, { 9, 0, 104 }, { 9, 0, 559 }, + { 12, 0, 308 }, { 19, 0, 87 }, { 4, 0, 301 }, { 4, 0, 604 }, + { 5, 10, 637 }, { 8, 0, 779 }, { 5, 11, 143 }, { 5, 11, 769 }, + { 6, 11, 1760 }, { 7, 11, 682 }, { 7, 11, 1992 }, { 8, 11, 736 }, + { 9, 10, 590 }, { 19, 0, 32 }, { 9, 11, 527 }, { 5, 10, 280 }, + { 7, 10, 1226 }, { 6, 0, 494 }, { 6, 0, 677 }, { 6, 0, 682 }, + { 6, 0, 1044 }, { 5, 10, 281 }, { 7, 10, 1064 }, { 7, 0, 508 }, + { 5, 11, 860 }, { 6, 11, 422 }, { 7, 11, 0 }, { 7, 11, 1544 }, + { 9, 11, 577 }, { 11, 11, 990 }, { 12, 11, 141 }, { 12, 11, 453 }, + { 13, 11, 47 }, { 13, 11, 266 }, { 6, 0, 1014 }, { 5, 11, 515 }, + { 9, 11, 131 }, { 6, 0, 957 }, { 4, 11, 646 }, { 6, 0, 310 }, + { 7, 0, 1849 }, { 8, 0, 72 }, { 8, 0, 272 }, { 8, 0, 431 }, + { 9, 0, 12 }, { 9, 0, 376 }, { 10, 0, 563 }, { 10, 0, 630 }, + { 10, 0, 796 }, { 10, 0, 810 }, { 11, 0, 367 }, { 11, 0, 599 }, + { 11, 0, 686 }, { 12, 0, 672 }, { 7, 0, 570 }, { 4, 11, 396 }, + { 7, 10, 120 }, { 7, 11, 728 }, { 8, 10, 489 }, { 9, 11, 117 }, + { 9, 10, 319 }, { 10, 10, 820 }, { 11, 10, 1004 }, { 12, 10, 379 }, + { 12, 10, 679 }, { 13, 10, 117 }, { 13, 11, 202 }, { 13, 10, 412 }, + { 14, 10, 25 }, { 15, 10, 52 }, { 15, 10, 161 }, { 16, 10, 47 }, + { 20, 11, 51 }, { 21, 10, 2 }, { 6, 11, 121 }, { 6, 11, 124 }, + { 6, 11, 357 }, { 7, 11, 1138 }, { 7, 11, 1295 }, { 8, 11, 162 }, + { 11, 11, 655 }, { 8, 0, 449 }, { 4, 10, 937 }, { 5, 10, 801 }, + { 8, 11, 449 }, { 11, 11, 958 }, { 6, 0, 181 }, { 7, 0, 537 }, + { 8, 0, 64 }, { 9, 0, 127 }, { 10, 0, 496 }, { 12, 0, 510 }, + { 13, 0, 384 }, { 10, 11, 253 }, { 4, 0, 244 }, { 7, 0, 233 }, + { 5, 11, 237 }, { 4, 10, 365 }, { 6, 0, 1650 }, { 10, 0, 702 }, + { 11, 0, 245 }, { 5, 10, 7 }, { 11, 10, 774 }, { 13, 0, 463 }, + { 20, 0, 49 }, { 13, 11, 463 }, { 20, 11, 49 }, { 4, 10, 734 }, + { 5, 10, 662 }, { 6, 10, 430 }, { 4, 10, 746 }, { 7, 10, 1090 }, + { 5, 10, 360 }, { 8, 10, 237 }, { 9, 0, 338 }, { 15, 11, 10 }, + { 7, 11, 571 }, { 10, 11, 366 }, { 6, 0, 1279 }, { 9, 11, 513 }, + { 10, 11, 22 }, { 10, 11, 39 }, { 12, 11, 122 }, { 12, 11, 187 }, + { 5, 0, 896 }, { 18, 0, 178 }, { 6, 0, 695 }, { 9, 0, 808 }, + { 6, 11, 587 }, { 7, 11, 107 }, { 7, 11, 838 }, { 8, 11, 550 }, + { 10, 11, 401 }, { 7, 0, 1117 }, { 8, 0, 539 }, { 4, 10, 277 }, + { 5, 10, 608 }, { 6, 10, 493 }, { 7, 10, 457 }, { 12, 10, 384 }, + { 5, 11, 768 }, { 12, 0, 257 }, { 7, 10, 27 }, { 7, 10, 316 }, + { 12, 0, 1003 }, { 4, 0, 207 }, { 5, 0, 586 }, { 5, 0, 676 }, + { 6, 0, 448 }, { 8, 0, 244 }, { 11, 0, 1 }, { 13, 0, 3 }, + { 16, 0, 54 }, { 17, 0, 4 }, { 18, 0, 13 }, { 5, 10, 552 }, + { 4, 10, 401 }, { 9, 10, 264 }, { 5, 0, 516 }, { 7, 0, 1883 }, + { 7, 11, 1883 }, { 12, 0, 960 }, { 4, 11, 894 }, { 5, 0, 4 }, + { 5, 0, 810 }, { 6, 0, 13 }, { 6, 0, 538 }, { 6, 0, 1690 }, + { 6, 0, 1726 }, { 7, 0, 499 }, { 7, 0, 1819 }, { 8, 0, 148 }, + { 8, 0, 696 }, { 8, 0, 791 }, { 12, 0, 125 }, { 15, 0, 9 }, + { 7, 0, 1268 }, { 11, 0, 30 }, { 14, 0, 315 }, { 9, 10, 543 }, + { 10, 10, 524 }, { 12, 10, 524 }, { 16, 10, 18 }, { 20, 10, 26 }, + { 20, 10, 65 }, { 6, 0, 748 }, { 4, 10, 205 }, { 5, 10, 623 }, + { 7, 10, 104 }, { 8, 10, 519 }, { 11, 0, 542 }, { 11, 0, 852 }, + { 12, 0, 6 }, { 4, 0, 848 }, { 7, 0, 1385 }, { 11, 0, 582 }, + { 11, 0, 650 }, { 11, 0, 901 }, { 11, 0, 949 }, { 12, 0, 232 }, + { 12, 0, 236 }, { 13, 0, 413 }, { 13, 0, 501 }, { 18, 0, 116 }, + { 7, 10, 579 }, { 9, 10, 41 }, { 9, 10, 244 }, { 9, 10, 669 }, + { 10, 10, 5 }, { 11, 10, 861 }, { 11, 10, 951 }, { 11, 10, 980 }, + { 4, 0, 945 }, { 6, 0, 1811 }, { 6, 0, 1845 }, { 6, 0, 1853 }, + { 6, 0, 1858 }, { 8, 0, 862 }, { 12, 0, 782 }, { 12, 0, 788 }, + { 18, 0, 160 }, { 20, 0, 117 }, { 4, 10, 717 }, { 4, 0, 925 }, + { 5, 0, 803 }, { 8, 0, 698 }, { 10, 0, 828 }, { 6, 0, 1416 }, + { 4, 0, 610 }, { 11, 0, 992 }, { 6, 0, 878 }, { 6, 0, 1477 }, + { 7, 0, 1847 }, { 10, 11, 531 }, { 9, 11, 539 }, { 6, 11, 272 }, + { 5, 0, 383 }, { 6, 0, 1404 }, { 4, 10, 489 }, { 4, 11, 9 }, + { 5, 11, 128 }, { 7, 11, 368 }, { 11, 11, 480 }, { 20, 11, 3 }, + { 8, 0, 986 }, { 9, 0, 660 }, { 10, 0, 347 }, { 7, 10, 892 }, + { 8, 11, 682 }, { 7, 0, 572 }, { 9, 0, 592 }, { 11, 0, 680 }, + { 12, 0, 356 }, { 12, 0, 550 }, { 7, 0, 1411 }, { 10, 11, 527 }, + { 4, 11, 2 }, { 7, 11, 545 }, { 7, 11, 894 }, { 9, 10, 473 }, + { 11, 0, 64 }, { 7, 11, 481 }, { 7, 10, 819 }, { 9, 10, 26 }, + { 9, 10, 392 }, { 9, 11, 792 }, { 10, 10, 152 }, { 10, 10, 226 }, + { 12, 10, 276 }, { 12, 10, 426 }, { 12, 10, 589 }, { 13, 10, 460 }, + { 15, 10, 97 }, { 19, 10, 48 }, { 20, 10, 104 }, { 7, 10, 51 }, + { 8, 11, 445 }, { 8, 11, 646 }, { 7, 0, 606 }, { 4, 10, 674 }, + { 6, 0, 1829 }, { 6, 0, 1830 }, { 4, 10, 770 }, { 5, 10, 79 }, + { 7, 10, 1027 }, { 7, 10, 1477 }, { 11, 10, 52 }, { 5, 11, 530 }, + { 14, 11, 113 }, { 6, 10, 1666 }, { 7, 0, 748 }, { 11, 0, 700 }, + { 6, 10, 195 }, { 5, 10, 789 }, { 9, 0, 87 }, { 10, 0, 365 }, + { 4, 10, 251 }, { 4, 10, 688 }, { 7, 10, 513 }, { 7, 10, 1284 }, + { 8, 11, 111 }, { 5, 0, 127 }, { 6, 0, 198 }, { 12, 0, 83 }, + { 5, 11, 556 }, { 5, 10, 889 }, { 4, 10, 160 }, { 5, 10, 330 }, + { 7, 10, 1434 }, { 8, 10, 174 }, { 5, 0, 276 }, { 6, 0, 55 }, + { 7, 0, 1369 }, { 10, 0, 864 }, { 8, 11, 16 }, { 12, 11, 568 }, + { 6, 0, 1752 }, { 8, 0, 726 }, { 7, 0, 1066 }, { 5, 0, 764 }, + { 6, 11, 186 }, { 9, 11, 426 }, { 11, 0, 683 }, { 11, 11, 683 }, + { 6, 0, 309 }, { 7, 0, 331 }, { 10, 0, 550 }, { 5, 10, 374 }, + { 6, 0, 1212 }, { 6, 0, 1852 }, { 7, 0, 1062 }, { 8, 0, 874 }, + { 8, 0, 882 }, { 10, 0, 936 }, { 4, 11, 585 }, { 6, 0, 1364 }, + { 7, 0, 986 }, { 5, 10, 731 }, { 6, 0, 723 }, { 6, 0, 1408 }, + { 10, 0, 381 }, { 7, 0, 1573 }, { 6, 0, 1025 }, { 4, 10, 626 }, + { 5, 10, 642 }, { 6, 10, 425 }, { 10, 10, 202 }, { 11, 10, 141 }, + { 4, 11, 93 }, { 5, 11, 252 }, { 6, 11, 229 }, { 7, 11, 291 }, + { 9, 11, 550 }, { 11, 11, 644 }, { 9, 11, 749 }, { 9, 11, 162 }, + { 4, 11, 381 }, { 7, 0, 1559 }, { 6, 0, 194 }, { 7, 0, 133 }, + { 10, 0, 493 }, { 10, 0, 570 }, { 11, 0, 664 }, { 5, 0, 24 }, + { 5, 0, 569 }, { 6, 0, 3 }, { 6, 0, 119 }, { 6, 0, 143 }, + { 6, 0, 440 }, { 7, 0, 295 }, { 7, 0, 599 }, { 7, 0, 1686 }, + { 7, 0, 1854 }, { 8, 0, 424 }, { 9, 0, 43 }, { 9, 0, 584 }, + { 9, 0, 760 }, { 10, 0, 148 }, { 10, 0, 328 }, { 11, 0, 159 }, + { 11, 0, 253 }, { 11, 0, 506 }, { 12, 0, 487 }, { 12, 0, 531 }, + { 6, 0, 661 }, { 6, 0, 1517 }, { 8, 10, 835 }, { 23, 10, 17 }, + { 5, 0, 14 }, { 5, 0, 892 }, { 6, 0, 283 }, { 7, 0, 234 }, + { 8, 0, 537 }, { 11, 0, 541 }, { 4, 0, 126 }, { 8, 0, 635 }, + { 19, 0, 34 }, { 4, 0, 316 }, { 4, 0, 495 }, { 7, 0, 1561 }, + { 4, 11, 187 }, { 5, 11, 184 }, { 5, 11, 690 }, { 7, 11, 1869 }, + { 10, 11, 756 }, { 11, 11, 783 }, { 4, 0, 998 }, { 9, 0, 861 }, + { 8, 0, 1009 }, { 11, 11, 292 }, { 5, 11, 21 }, { 6, 11, 77 }, + { 6, 11, 157 }, { 7, 11, 974 }, { 7, 11, 1301 }, { 7, 11, 1339 }, + { 7, 11, 1490 }, { 7, 11, 1873 }, { 9, 11, 628 }, { 7, 11, 1283 }, + { 9, 11, 227 }, { 9, 11, 499 }, { 10, 11, 341 }, { 11, 11, 325 }, + { 11, 11, 408 }, { 14, 11, 180 }, { 15, 11, 144 }, { 18, 11, 47 }, + { 19, 11, 49 }, { 4, 0, 64 }, { 5, 0, 352 }, { 5, 0, 720 }, + { 6, 0, 368 }, { 11, 0, 359 }, { 5, 10, 384 }, { 8, 10, 455 }, + { 12, 10, 48 }, { 5, 10, 264 }, { 6, 10, 184 }, { 7, 0, 1577 }, + { 10, 0, 304 }, { 10, 0, 549 }, { 12, 0, 365 }, { 13, 0, 220 }, + { 13, 0, 240 }, { 14, 0, 33 }, { 6, 0, 1107 }, { 6, 0, 929 }, + { 7, 0, 1142 }, { 6, 0, 175 }, { 9, 0, 289 }, { 5, 0, 432 }, + { 5, 0, 913 }, { 6, 0, 279 }, { 7, 0, 219 }, { 5, 10, 633 }, + { 7, 10, 1323 }, { 7, 0, 785 }, { 7, 10, 359 }, { 8, 10, 243 }, + { 12, 10, 175 }, { 11, 0, 595 }, { 4, 10, 105 }, { 8, 11, 398 }, + { 9, 11, 681 }, { 11, 11, 632 }, { 12, 0, 80 }, { 5, 0, 931 }, + { 6, 0, 1698 }, { 14, 11, 241 }, { 6, 11, 20 }, { 6, 0, 1323 }, + { 11, 0, 526 }, { 11, 0, 939 }, { 13, 0, 290 }, { 5, 0, 774 }, + { 6, 0, 780 }, { 6, 0, 1637 }, { 6, 0, 1686 }, { 6, 0, 1751 }, + { 8, 0, 559 }, { 13, 0, 109 }, { 13, 0, 127 }, { 7, 0, 1167 }, + { 11, 0, 934 }, { 13, 0, 391 }, { 17, 0, 76 }, { 7, 11, 709 }, + { 7, 0, 963 }, { 6, 0, 260 }, { 7, 0, 1484 }, { 6, 0, 573 }, + { 4, 10, 758 }, { 11, 11, 941 }, { 7, 10, 1649 }, { 17, 11, 36 }, + { 4, 0, 292 }, { 9, 0, 580 }, { 4, 0, 736 }, { 5, 0, 871 }, + { 6, 0, 1689 }, { 7, 0, 1944 }, { 7, 11, 945 }, { 11, 11, 713 }, + { 11, 11, 744 }, { 6, 0, 1164 }, { 7, 11, 937 }, { 6, 0, 1922 }, + { 9, 0, 982 }, { 15, 0, 173 }, { 15, 0, 178 }, { 15, 0, 200 }, + { 18, 0, 189 }, { 18, 0, 207 }, { 21, 0, 47 }, { 7, 11, 1652 }, + { 7, 0, 1695 }, { 11, 10, 128 }, { 6, 0, 63 }, { 7, 0, 920 }, + { 5, 0, 793 }, { 15, 11, 134 }, { 5, 10, 918 }, { 5, 0, 67 }, + { 6, 0, 62 }, { 6, 0, 374 }, { 7, 0, 1391 }, { 9, 0, 790 }, + { 12, 0, 47 }, { 4, 11, 579 }, { 5, 11, 226 }, { 5, 11, 323 }, + { 7, 11, 960 }, { 10, 11, 784 }, { 13, 11, 191 }, { 4, 0, 391 }, + { 7, 0, 1169 }, { 9, 0, 443 }, { 13, 11, 232 }, { 18, 11, 35 }, + { 4, 10, 340 }, { 4, 0, 271 }, { 9, 11, 313 }, { 5, 11, 973 }, + { 9, 11, 659 }, { 6, 0, 1140 }, { 6, 11, 135 }, { 7, 11, 1176 }, + { 4, 0, 253 }, { 5, 0, 544 }, { 7, 0, 300 }, { 9, 0, 340 }, + { 7, 0, 897 }, { 5, 10, 985 }, { 7, 10, 509 }, { 17, 10, 96 }, + { 10, 11, 735 }, { 7, 10, 1919 }, { 10, 0, 890 }, { 5, 0, 818 }, + { 6, 0, 1122 }, { 5, 0, 53 }, { 5, 0, 541 }, { 6, 0, 94 }, + { 6, 0, 499 }, { 7, 0, 230 }, { 11, 0, 321 }, { 4, 0, 920 }, + { 5, 0, 25 }, { 5, 0, 790 }, { 6, 0, 457 }, { 7, 0, 853 }, + { 8, 0, 788 }, { 14, 11, 31 }, { 4, 10, 247 }, { 7, 11, 314 }, + { 4, 0, 468 }, { 7, 0, 243 }, { 6, 10, 337 }, { 7, 10, 494 }, + { 8, 10, 27 }, { 8, 10, 599 }, { 10, 10, 153 }, { 4, 10, 184 }, + { 5, 10, 390 }, { 7, 10, 618 }, { 7, 10, 1456 }, { 11, 10, 710 }, + { 6, 0, 870 }, { 6, 0, 1238 }, { 6, 0, 1765 }, { 10, 0, 853 }, + { 10, 0, 943 }, { 14, 0, 437 }, { 14, 0, 439 }, { 14, 0, 443 }, + { 14, 0, 446 }, { 14, 0, 452 }, { 14, 0, 469 }, { 14, 0, 471 }, + { 14, 0, 473 }, { 16, 0, 93 }, { 16, 0, 102 }, { 16, 0, 110 }, + { 20, 0, 121 }, { 4, 0, 605 }, { 7, 0, 518 }, { 7, 0, 1282 }, + { 7, 0, 1918 }, { 10, 0, 180 }, { 11, 0, 218 }, { 5, 0, 822 }, + { 4, 0, 634 }, { 11, 0, 916 }, { 14, 0, 419 }, { 6, 11, 281 }, + { 7, 11, 6 }, { 8, 11, 282 }, { 8, 11, 480 }, { 8, 11, 499 }, + { 9, 11, 198 }, { 10, 11, 143 }, { 10, 11, 169 }, { 10, 11, 211 }, + { 10, 11, 417 }, { 10, 11, 574 }, { 11, 11, 147 }, { 11, 11, 395 }, + { 12, 11, 75 }, { 12, 11, 407 }, { 12, 11, 608 }, { 13, 11, 500 }, + { 14, 11, 251 }, { 6, 0, 898 }, { 6, 0, 36 }, { 7, 0, 658 }, + { 8, 0, 454 }, { 22, 11, 48 }, { 5, 11, 674 }, { 7, 11, 1776 }, + { 4, 11, 419 }, { 10, 10, 227 }, { 11, 10, 497 }, { 11, 10, 709 }, + { 12, 10, 415 }, { 6, 10, 360 }, { 7, 10, 1664 }, { 8, 10, 478 }, + { 9, 0, 806 }, { 12, 11, 508 }, { 14, 11, 102 }, { 14, 11, 226 }, + { 16, 11, 57 }, { 7, 11, 1123 }, { 4, 11, 138 }, { 7, 11, 1012 }, + { 7, 11, 1280 }, { 9, 11, 76 }, { 5, 11, 29 }, { 12, 11, 638 }, + { 8, 10, 699 }, { 6, 0, 1326 }, { 4, 0, 104 }, { 7, 11, 735 }, + { 4, 10, 739 }, { 6, 0, 1331 }, { 7, 0, 260 }, { 7, 11, 260 }, + { 7, 11, 1063 }, { 7, 0, 45 }, { 9, 0, 542 }, { 9, 0, 566 }, + { 10, 0, 728 }, { 9, 10, 869 }, { 4, 10, 67 }, { 5, 10, 422 }, + { 7, 10, 1037 }, { 7, 10, 1289 }, { 7, 10, 1555 }, { 9, 10, 741 }, + { 17, 10, 108 }, { 11, 0, 263 }, { 6, 0, 1516 }, { 14, 0, 146 }, + { 15, 0, 42 }, { 16, 0, 23 }, { 17, 0, 86 }, { 18, 0, 17 }, + { 10, 0, 468 }, { 8, 0, 1005 }, { 4, 11, 17 }, { 5, 11, 23 }, + { 7, 11, 995 }, { 11, 11, 383 }, { 11, 11, 437 }, { 12, 11, 460 }, + { 12, 11, 532 }, { 7, 0, 87 }, { 14, 0, 288 }, { 10, 10, 96 }, + { 7, 11, 626 }, { 16, 10, 26 }, { 7, 0, 988 }, { 7, 0, 1939 }, + { 9, 0, 64 }, { 9, 0, 502 }, { 12, 0, 22 }, { 12, 0, 34 }, + { 13, 0, 12 }, { 13, 0, 234 }, { 19, 0, 77 }, { 13, 0, 133 }, + { 8, 10, 203 }, { 11, 10, 823 }, { 11, 10, 846 }, { 12, 10, 482 }, + { 13, 10, 277 }, { 13, 10, 302 }, { 13, 10, 464 }, { 14, 10, 205 }, + { 14, 10, 221 }, { 4, 10, 449 }, { 5, 10, 718 }, { 7, 0, 141 }, + { 6, 0, 1842 }, { 8, 0, 872 }, { 8, 11, 70 }, { 12, 11, 171 }, + { 13, 11, 272 }, { 4, 10, 355 }, { 6, 10, 311 }, { 9, 10, 256 }, + { 10, 10, 404 }, { 4, 0, 619 }, { 9, 0, 261 }, { 10, 11, 233 }, + { 10, 10, 758 }, { 11, 11, 76 }, { 5, 0, 246 }, { 8, 0, 189 }, + { 9, 0, 355 }, { 9, 0, 512 }, { 10, 0, 124 }, { 10, 0, 453 }, + { 11, 0, 143 }, { 11, 0, 416 }, { 11, 0, 859 }, { 13, 0, 341 }, + { 6, 11, 442 }, { 5, 10, 827 }, { 5, 10, 64 }, { 12, 10, 581 }, + { 4, 10, 442 }, { 7, 10, 1047 }, { 7, 10, 1352 }, { 7, 10, 1643 }, + { 6, 11, 1709 }, { 5, 0, 678 }, { 6, 0, 305 }, { 7, 0, 775 }, + { 7, 0, 1065 }, { 5, 10, 977 }, { 11, 11, 69 }, { 12, 11, 105 }, + { 12, 11, 117 }, { 13, 11, 213 }, { 14, 11, 13 }, { 14, 11, 62 }, + { 14, 11, 177 }, { 14, 11, 421 }, { 15, 11, 19 }, { 18, 11, 141 }, + { 9, 11, 309 }, { 5, 0, 35 }, { 7, 0, 862 }, { 7, 0, 1886 }, + { 10, 0, 179 }, { 8, 0, 285 }, { 4, 0, 517 }, { 7, 11, 976 }, + { 9, 11, 146 }, { 10, 11, 206 }, { 10, 11, 596 }, { 13, 11, 218 }, + { 14, 11, 153 }, { 4, 10, 254 }, { 6, 0, 214 }, { 12, 0, 540 }, + { 4, 10, 275 }, { 7, 10, 1219 }, { 12, 10, 376 }, { 8, 0, 667 }, + { 11, 0, 403 }, { 18, 0, 83 }, { 12, 0, 74 }, { 10, 11, 648 }, + { 11, 11, 671 }, { 15, 11, 46 }, { 7, 0, 125 }, { 6, 10, 1753 }, + { 5, 0, 761 }, { 6, 0, 912 }, { 4, 11, 518 }, { 6, 10, 369 }, + { 6, 10, 502 }, { 7, 10, 1036 }, { 7, 11, 1136 }, { 8, 10, 348 }, + { 9, 10, 452 }, { 10, 10, 26 }, { 11, 10, 224 }, { 11, 10, 387 }, + { 11, 10, 772 }, { 12, 10, 95 }, { 12, 10, 629 }, { 13, 10, 195 }, + { 13, 10, 207 }, { 13, 10, 241 }, { 14, 10, 260 }, { 14, 10, 270 }, + { 15, 10, 140 }, { 10, 0, 131 }, { 12, 0, 72 }, { 4, 10, 269 }, + { 5, 10, 480 }, { 7, 10, 532 }, { 7, 10, 1197 }, { 7, 10, 1358 }, + { 8, 10, 291 }, { 11, 10, 349 }, { 14, 10, 396 }, { 8, 11, 689 }, + { 9, 11, 863 }, { 8, 0, 333 }, { 10, 0, 182 }, { 4, 11, 18 }, + { 7, 11, 145 }, { 7, 11, 444 }, { 7, 11, 1278 }, { 8, 11, 49 }, + { 8, 11, 400 }, { 9, 11, 71 }, { 9, 11, 250 }, { 10, 11, 459 }, + { 12, 11, 160 }, { 16, 11, 24 }, { 14, 11, 35 }, { 14, 11, 191 }, + { 7, 11, 1864 }, { 7, 0, 1338 }, { 20, 10, 15 }, { 14, 0, 94 }, + { 15, 0, 65 }, { 16, 0, 4 }, { 16, 0, 77 }, { 16, 0, 80 }, + { 17, 0, 5 }, { 12, 11, 82 }, { 15, 11, 36 }, { 5, 11, 1010 }, + { 5, 0, 449 }, { 5, 0, 646 }, { 7, 0, 86 }, { 8, 0, 103 }, + { 7, 10, 657 }, { 7, 0, 2028 }, { 10, 0, 641 }, { 8, 10, 533 }, + { 6, 0, 1 }, { 11, 11, 970 }, { 5, 11, 87 }, { 7, 11, 313 }, + { 7, 11, 1103 }, { 10, 11, 112 }, { 10, 11, 582 }, { 11, 11, 389 }, + { 11, 11, 813 }, { 12, 11, 385 }, { 13, 11, 286 }, { 14, 11, 124 }, + { 18, 11, 108 }, { 6, 0, 869 }, { 4, 11, 267 }, { 6, 0, 277 }, + { 7, 0, 1274 }, { 7, 0, 1386 }, { 18, 0, 87 }, { 6, 0, 187 }, + { 7, 0, 39 }, { 7, 0, 1203 }, { 8, 0, 380 }, { 14, 0, 117 }, + { 21, 0, 28 }, { 4, 10, 211 }, { 4, 10, 332 }, { 5, 10, 335 }, + { 6, 10, 238 }, { 7, 10, 269 }, { 7, 10, 811 }, { 7, 10, 1797 }, + { 8, 10, 836 }, { 9, 10, 507 }, { 13, 10, 242 }, { 4, 0, 785 }, + { 5, 0, 368 }, { 6, 0, 297 }, { 7, 0, 793 }, { 11, 0, 938 }, + { 7, 0, 464 }, { 8, 0, 558 }, { 11, 0, 105 }, { 12, 0, 231 }, + { 14, 0, 386 }, { 15, 0, 102 }, { 20, 0, 75 }, { 5, 10, 1009 }, + { 8, 0, 877 }, { 12, 0, 731 }, { 11, 11, 289 }, { 10, 11, 249 }, + { 11, 11, 209 }, { 4, 11, 561 }, { 6, 0, 1608 }, { 4, 11, 760 }, + { 6, 0, 1429 }, { 9, 11, 154 }, { 12, 11, 485 }, { 5, 10, 228 }, + { 6, 10, 203 }, { 7, 10, 156 }, { 8, 10, 347 }, { 9, 10, 265 }, + { 7, 0, 1010 }, { 11, 0, 733 }, { 11, 0, 759 }, { 13, 0, 34 }, + { 14, 0, 427 }, { 18, 0, 45 }, { 7, 10, 1131 }, { 7, 10, 1468 }, + { 8, 11, 255 }, { 7, 0, 1656 }, { 9, 0, 369 }, { 10, 0, 338 }, + { 10, 0, 490 }, { 11, 0, 154 }, { 11, 0, 545 }, { 11, 0, 775 }, + { 13, 0, 77 }, { 13, 0, 274 }, { 5, 11, 621 }, { 6, 0, 1038 }, + { 4, 11, 368 }, { 7, 11, 641 }, { 6, 0, 2010 }, { 8, 0, 979 }, + { 8, 0, 985 }, { 10, 0, 951 }, { 10, 0, 1011 }, { 6, 0, 1005 }, + { 19, 0, 121 }, { 5, 10, 291 }, { 5, 10, 318 }, { 7, 10, 765 }, + { 9, 10, 389 }, { 12, 10, 548 }, { 5, 0, 20 }, { 6, 0, 298 }, + { 7, 0, 659 }, { 9, 0, 219 }, { 7, 0, 1440 }, { 11, 0, 854 }, + { 11, 0, 872 }, { 11, 0, 921 }, { 12, 0, 551 }, { 13, 0, 472 }, + { 14, 0, 367 }, { 5, 0, 490 }, { 6, 0, 615 }, { 6, 0, 620 }, + { 7, 0, 683 }, { 6, 0, 1070 }, { 6, 0, 1597 }, { 11, 0, 522 }, + { 4, 0, 439 }, { 8, 0, 669 }, { 6, 0, 766 }, { 6, 0, 1143 }, + { 6, 0, 1245 }, { 10, 10, 525 }, { 11, 10, 82 }, { 9, 11, 92 }, + { 19, 11, 91 }, { 6, 0, 668 }, { 6, 0, 1218 }, { 6, 11, 525 }, + { 9, 11, 876 }, { 12, 11, 284 }, { 4, 0, 233 }, { 8, 0, 547 }, + { 4, 10, 422 }, { 5, 10, 355 }, { 17, 10, 0 }, { 6, 11, 300 }, + { 7, 11, 1515 }, { 4, 0, 482 }, { 9, 10, 905 }, { 4, 0, 886 }, + { 7, 0, 346 }, { 5, 11, 594 }, { 5, 10, 865 }, { 5, 10, 914 }, + { 6, 10, 1625 }, { 7, 0, 334 }, { 5, 0, 795 }, { 6, 0, 1741 }, + { 5, 10, 234 }, { 7, 10, 1383 }, { 6, 11, 1641 }, { 8, 11, 820 }, + { 7, 0, 371 }, { 7, 11, 1313 }, { 10, 11, 660 }, { 7, 10, 1312 }, + { 7, 0, 622 }, { 7, 0, 625 }, { 7, 0, 1750 }, { 7, 0, 339 }, + { 4, 0, 203 }, { 7, 0, 1936 }, { 15, 0, 29 }, { 16, 0, 38 }, + { 15, 11, 29 }, { 16, 11, 38 }, { 5, 0, 338 }, { 7, 0, 1256 }, + { 7, 10, 1493 }, { 10, 0, 130 }, { 6, 10, 421 }, { 7, 10, 61 }, + { 7, 10, 1540 }, { 10, 10, 501 }, { 6, 11, 389 }, { 7, 11, 149 }, + { 9, 11, 142 }, { 10, 11, 94 }, { 9, 10, 341 }, { 11, 0, 678 }, + { 12, 0, 307 }, { 14, 10, 98 }, { 6, 11, 8 }, { 7, 11, 1881 }, + { 8, 11, 91 }, { 7, 0, 2044 }, { 6, 0, 770 }, { 6, 0, 802 }, + { 6, 0, 812 }, { 7, 0, 311 }, { 9, 0, 308 }, { 12, 0, 255 }, + { 6, 10, 102 }, { 7, 10, 72 }, { 15, 10, 142 }, { 19, 10, 67 }, + { 23, 10, 30 }, { 7, 10, 823 }, { 7, 0, 1266 }, { 7, 11, 1746 }, + { 7, 10, 1870 }, { 4, 0, 400 }, { 5, 0, 267 }, { 7, 0, 232 }, + { 7, 11, 24 }, { 11, 11, 542 }, { 11, 11, 852 }, { 7, 11, 1739 }, + { 4, 11, 503 }, { 7, 11, 1661 }, { 5, 11, 130 }, { 7, 11, 1314 }, + { 9, 11, 610 }, { 10, 11, 718 }, { 11, 11, 601 }, { 11, 11, 819 }, + { 11, 11, 946 }, { 12, 11, 536 }, { 10, 11, 149 }, { 11, 11, 280 }, + { 14, 11, 336 }, { 7, 0, 739 }, { 11, 0, 690 }, { 7, 11, 1946 }, + { 8, 10, 48 }, { 8, 10, 88 }, { 8, 10, 582 }, { 8, 10, 681 }, + { 9, 10, 373 }, { 9, 10, 864 }, { 11, 10, 157 }, { 11, 10, 843 }, + { 20, 10, 27 }, { 6, 0, 990 }, { 4, 10, 88 }, { 5, 10, 137 }, + { 5, 10, 174 }, { 5, 10, 777 }, { 6, 10, 1664 }, { 6, 10, 1725 }, + { 7, 10, 77 }, { 7, 10, 426 }, { 7, 10, 1317 }, { 7, 10, 1355 }, + { 8, 10, 126 }, { 8, 10, 563 }, { 9, 10, 523 }, { 9, 10, 750 }, + { 10, 10, 310 }, { 10, 10, 836 }, { 11, 10, 42 }, { 11, 10, 318 }, + { 11, 10, 731 }, { 12, 10, 68 }, { 12, 10, 92 }, { 12, 10, 507 }, + { 12, 10, 692 }, { 13, 10, 81 }, { 13, 10, 238 }, { 13, 10, 374 }, + { 14, 10, 436 }, { 18, 10, 138 }, { 19, 10, 78 }, { 19, 10, 111 }, + { 20, 10, 55 }, { 20, 10, 77 }, { 20, 10, 92 }, { 13, 10, 418 }, + { 7, 0, 1831 }, { 4, 10, 938 }, { 6, 0, 776 }, { 6, 0, 915 }, + { 10, 10, 351 }, { 5, 11, 348 }, { 6, 11, 522 }, { 6, 10, 1668 }, + { 7, 10, 1499 }, { 8, 10, 117 }, { 9, 10, 314 }, { 10, 10, 174 }, + { 7, 10, 707 }, { 4, 0, 613 }, { 5, 10, 403 }, { 4, 11, 392 }, + { 5, 11, 433 }, { 9, 11, 633 }, { 11, 11, 629 }, { 5, 0, 763 }, + { 4, 0, 878 }, { 4, 0, 977 }, { 4, 0, 100 }, { 6, 0, 463 }, + { 4, 10, 44 }, { 5, 10, 311 }, { 7, 10, 639 }, { 7, 10, 762 }, + { 7, 10, 1827 }, { 9, 10, 8 }, { 9, 10, 462 }, { 20, 10, 83 }, + { 6, 11, 234 }, { 4, 10, 346 }, { 7, 10, 115 }, { 9, 10, 180 }, + { 9, 10, 456 }, { 10, 10, 363 }, { 5, 0, 362 }, { 5, 0, 443 }, + { 6, 0, 318 }, { 7, 0, 1019 }, { 11, 0, 623 }, { 5, 0, 463 }, + { 8, 0, 296 }, { 7, 11, 140 }, { 7, 11, 1950 }, { 8, 11, 680 }, + { 11, 11, 817 }, { 19, 11, 88 }, { 7, 11, 1222 }, { 10, 11, 386 }, + { 14, 0, 137 }, { 4, 0, 454 }, { 7, 0, 1914 }, { 6, 11, 5 }, + { 7, 10, 1051 }, { 9, 10, 545 }, { 11, 11, 249 }, { 12, 11, 313 }, + { 16, 11, 66 }, { 17, 11, 26 }, { 7, 0, 1527 }, { 17, 0, 58 }, + { 20, 11, 59 }, { 5, 0, 48 }, { 5, 0, 404 }, { 6, 0, 557 }, + { 7, 0, 458 }, { 8, 0, 597 }, { 10, 0, 455 }, { 10, 0, 606 }, + { 11, 0, 49 }, { 11, 0, 548 }, { 12, 0, 476 }, { 13, 0, 18 }, + { 13, 0, 450 }, { 5, 11, 963 }, { 6, 11, 1773 }, { 5, 0, 729 }, + { 10, 11, 586 }, { 5, 0, 442 }, { 7, 0, 1984 }, { 6, 0, 449 }, + { 16, 0, 40 }, { 4, 0, 853 }, { 7, 11, 180 }, { 8, 11, 509 }, + { 8, 11, 792 }, { 6, 10, 185 }, { 7, 10, 1899 }, { 9, 10, 875 }, + { 11, 10, 673 }, { 6, 11, 524 }, { 12, 0, 227 }, { 4, 10, 327 }, + { 5, 10, 478 }, { 7, 10, 1332 }, { 8, 10, 753 }, { 6, 0, 1491 }, + { 5, 10, 1020 }, { 5, 10, 1022 }, { 4, 10, 103 }, { 5, 10, 401 }, + { 4, 11, 931 }, { 4, 10, 499 }, { 7, 10, 1421 }, { 5, 0, 55 }, + { 7, 0, 376 }, { 12, 0, 161 }, { 5, 0, 450 }, { 6, 0, 1174 }, + { 6, 0, 1562 }, { 10, 0, 62 }, { 13, 0, 400 }, { 7, 11, 1837 }, + { 12, 0, 207 }, { 7, 0, 869 }, { 4, 11, 773 }, { 5, 11, 618 }, + { 9, 11, 756 }, { 4, 10, 96 }, { 4, 0, 213 }, { 7, 0, 223 }, + { 8, 0, 80 }, { 7, 10, 968 }, { 4, 11, 90 }, { 5, 11, 337 }, + { 5, 11, 545 }, { 7, 11, 754 }, { 9, 11, 186 }, { 10, 11, 72 }, + { 10, 11, 782 }, { 11, 11, 513 }, { 11, 11, 577 }, { 11, 11, 610 }, + { 11, 11, 889 }, { 11, 11, 961 }, { 12, 11, 354 }, { 12, 11, 362 }, + { 12, 11, 461 }, { 12, 11, 595 }, { 13, 11, 79 }, { 15, 11, 121 }, + { 7, 0, 381 }, { 7, 0, 806 }, { 7, 0, 820 }, { 8, 0, 354 }, + { 8, 0, 437 }, { 8, 0, 787 }, { 9, 0, 657 }, { 10, 0, 58 }, + { 10, 0, 339 }, { 10, 0, 749 }, { 11, 0, 914 }, { 12, 0, 162 }, + { 13, 0, 75 }, { 14, 0, 106 }, { 14, 0, 198 }, { 14, 0, 320 }, + { 14, 0, 413 }, { 18, 0, 43 }, { 8, 0, 747 }, { 8, 0, 954 }, + { 6, 0, 1073 }, { 7, 0, 556 }, { 7, 11, 151 }, { 9, 11, 329 }, + { 11, 11, 254 }, { 5, 0, 692 }, { 6, 0, 1395 }, { 6, 10, 563 }, + { 9, 10, 224 }, { 6, 0, 191 }, { 4, 0, 804 }, { 9, 11, 187 }, + { 10, 11, 36 }, { 17, 11, 44 }, { 18, 11, 64 }, { 7, 11, 165 }, + { 7, 11, 919 }, { 8, 11, 517 }, { 4, 11, 506 }, { 5, 11, 295 }, + { 7, 11, 1680 }, { 15, 11, 14 }, { 16, 11, 5 }, { 4, 0, 706 }, + { 6, 0, 162 }, { 7, 0, 1960 }, { 8, 0, 831 }, { 7, 11, 1376 }, + { 7, 11, 987 }, { 9, 11, 688 }, { 10, 11, 522 }, { 11, 11, 788 }, + { 12, 11, 566 }, { 22, 0, 35 }, { 10, 0, 426 }, { 7, 0, 1235 }, + { 7, 11, 1741 }, { 7, 11, 389 }, { 7, 11, 700 }, { 7, 11, 940 }, + { 8, 11, 514 }, { 9, 11, 116 }, { 9, 11, 535 }, { 10, 11, 118 }, + { 11, 11, 107 }, { 11, 11, 148 }, { 11, 11, 922 }, { 12, 11, 254 }, + { 12, 11, 421 }, { 14, 11, 238 }, { 6, 0, 1234 }, { 4, 11, 743 }, + { 4, 10, 910 }, { 5, 10, 832 }, { 7, 11, 1335 }, { 13, 0, 96 }, + { 7, 11, 185 }, { 18, 0, 149 }, { 4, 0, 204 }, { 9, 0, 902 }, + { 4, 11, 784 }, { 5, 11, 745 }, { 8, 0, 833 }, { 8, 0, 949 }, + { 7, 0, 366 }, { 9, 0, 287 }, { 12, 0, 199 }, { 12, 0, 556 }, + { 12, 0, 577 }, { 5, 11, 81 }, { 7, 11, 146 }, { 7, 11, 1342 }, + { 7, 11, 1446 }, { 8, 11, 53 }, { 8, 11, 561 }, { 8, 11, 694 }, + { 8, 11, 754 }, { 9, 11, 97 }, { 9, 11, 115 }, { 9, 11, 894 }, + { 10, 11, 462 }, { 10, 11, 813 }, { 11, 11, 230 }, { 11, 11, 657 }, + { 11, 11, 699 }, { 11, 11, 748 }, { 12, 11, 119 }, { 12, 11, 200 }, + { 12, 11, 283 }, { 14, 11, 273 }, { 17, 11, 15 }, { 5, 11, 408 }, + { 9, 11, 747 }, { 9, 11, 498 }, { 12, 11, 181 }, { 6, 0, 2020 }, + { 8, 0, 992 }, { 5, 0, 356 }, { 7, 0, 224 }, { 6, 0, 784 }, + { 7, 0, 630 }, { 9, 0, 567 }, { 11, 0, 150 }, { 11, 0, 444 }, + { 13, 0, 119 }, { 8, 10, 528 }, { 9, 10, 348 }, { 6, 0, 539 }, + { 4, 10, 20 }, { 5, 10, 616 }, { 14, 0, 27 }, { 7, 11, 30 }, + { 8, 11, 86 }, { 8, 11, 315 }, { 8, 11, 700 }, { 9, 11, 576 }, + { 9, 11, 858 }, { 11, 11, 310 }, { 11, 11, 888 }, { 11, 11, 904 }, + { 12, 11, 361 }, { 13, 11, 248 }, { 10, 11, 839 }, { 6, 0, 755 }, + { 6, 0, 1063 }, { 7, 10, 1091 }, { 7, 10, 1765 }, { 6, 11, 428 }, + { 7, 11, 524 }, { 8, 11, 169 }, { 8, 11, 234 }, { 9, 11, 480 }, + { 10, 11, 646 }, { 11, 0, 814 }, { 7, 11, 1462 }, { 11, 11, 659 }, + { 4, 10, 26 }, { 5, 10, 429 }, { 6, 10, 245 }, { 7, 10, 704 }, + { 7, 10, 1379 }, { 7, 10, 1474 }, { 7, 11, 1205 }, { 10, 11, 637 }, + { 11, 11, 803 }, { 4, 10, 621 }, { 8, 0, 987 }, { 4, 11, 266 }, + { 8, 11, 4 }, { 9, 11, 39 }, { 10, 11, 166 }, { 11, 11, 918 }, + { 12, 11, 635 }, { 20, 11, 10 }, { 22, 11, 27 }, { 22, 11, 43 }, + { 4, 0, 235 }, { 7, 0, 255 }, { 4, 0, 194 }, { 5, 0, 584 }, + { 6, 0, 384 }, { 7, 0, 583 }, { 10, 0, 761 }, { 11, 0, 760 }, + { 11, 0, 851 }, { 5, 10, 542 }, { 6, 0, 1086 }, { 5, 10, 868 }, + { 8, 0, 1016 }, { 8, 0, 1018 }, { 7, 0, 1396 }, { 7, 11, 1396 }, + { 8, 10, 433 }, { 7, 10, 1495 }, { 10, 10, 215 }, { 13, 10, 124 }, + { 7, 11, 157 }, { 8, 11, 279 }, { 9, 11, 759 }, { 16, 11, 31 }, + { 16, 11, 39 }, { 16, 11, 75 }, { 18, 11, 24 }, { 20, 11, 42 }, + { 24, 11, 1 }, { 5, 0, 562 }, { 6, 11, 604 }, { 6, 0, 913 }, + { 5, 0, 191 }, { 9, 0, 271 }, { 4, 0, 470 }, { 6, 0, 153 }, + { 7, 0, 1503 }, { 7, 0, 1923 }, { 10, 0, 701 }, { 11, 0, 132 }, + { 11, 0, 227 }, { 11, 0, 320 }, { 11, 0, 436 }, { 11, 0, 525 }, + { 11, 0, 855 }, { 11, 0, 873 }, { 12, 0, 41 }, { 12, 0, 286 }, + { 13, 0, 103 }, { 13, 0, 284 }, { 14, 0, 255 }, { 14, 0, 262 }, + { 15, 0, 117 }, { 15, 0, 127 }, { 7, 0, 475 }, { 12, 0, 45 }, + { 19, 10, 112 }, { 4, 11, 567 }, { 9, 11, 859 }, { 6, 0, 713 }, + { 6, 0, 969 }, { 6, 0, 1290 }, { 6, 0, 1551 }, { 5, 0, 327 }, + { 6, 0, 552 }, { 6, 0, 1292 }, { 7, 0, 1754 }, { 9, 0, 604 }, + { 4, 0, 223 }, { 6, 0, 359 }, { 11, 0, 3 }, { 13, 0, 108 }, + { 14, 0, 89 }, { 16, 0, 22 }, { 5, 11, 762 }, { 7, 11, 1880 }, + { 9, 11, 680 }, { 11, 11, 798 }, { 5, 0, 80 }, { 6, 0, 405 }, + { 7, 0, 403 }, { 7, 0, 1502 }, { 8, 0, 456 }, { 9, 0, 487 }, + { 9, 0, 853 }, { 9, 0, 889 }, { 10, 0, 309 }, { 11, 0, 721 }, + { 11, 0, 994 }, { 12, 0, 430 }, { 13, 0, 165 }, { 5, 11, 298 }, + { 4, 10, 647 }, { 6, 0, 2016 }, { 18, 10, 10 }, { 18, 11, 10 }, + { 4, 0, 453 }, { 5, 0, 887 }, { 6, 0, 535 }, { 8, 0, 6 }, + { 8, 0, 543 }, { 8, 0, 826 }, { 8, 0, 975 }, { 10, 0, 961 }, + { 10, 0, 962 }, { 10, 10, 220 }, { 6, 0, 1891 }, { 6, 0, 1893 }, + { 9, 0, 916 }, { 9, 0, 965 }, { 9, 0, 972 }, { 12, 0, 801 }, + { 12, 0, 859 }, { 12, 0, 883 }, { 15, 0, 226 }, { 21, 0, 51 }, + { 4, 10, 109 }, { 7, 11, 267 }, { 7, 11, 92 }, { 7, 11, 182 }, + { 8, 11, 453 }, { 9, 11, 204 }, { 11, 11, 950 }, { 12, 11, 94 }, + { 12, 11, 644 }, { 16, 11, 20 }, { 16, 11, 70 }, { 16, 11, 90 }, + { 19, 11, 55 }, { 6, 10, 1746 }, { 6, 11, 71 }, { 7, 11, 845 }, + { 7, 11, 1308 }, { 8, 11, 160 }, { 9, 11, 318 }, { 5, 0, 101 }, + { 6, 0, 88 }, { 7, 0, 263 }, { 7, 0, 628 }, { 7, 0, 1677 }, + { 8, 0, 349 }, { 9, 0, 100 }, { 10, 0, 677 }, { 14, 0, 169 }, + { 14, 0, 302 }, { 14, 0, 313 }, { 15, 0, 48 }, { 15, 0, 84 }, + { 7, 11, 237 }, { 8, 11, 664 }, { 9, 11, 42 }, { 9, 11, 266 }, + { 9, 11, 380 }, { 9, 11, 645 }, { 10, 11, 177 }, { 10, 11, 276 }, + { 10, 11, 69 }, { 4, 0, 310 }, { 7, 0, 708 }, { 7, 0, 996 }, + { 9, 0, 795 }, { 10, 0, 390 }, { 10, 0, 733 }, { 11, 0, 451 }, + { 12, 0, 249 }, { 14, 0, 115 }, { 14, 0, 286 }, { 15, 0, 100 }, + { 5, 0, 587 }, { 4, 10, 40 }, { 10, 10, 67 }, { 11, 10, 117 }, + { 11, 10, 768 }, { 11, 10, 935 }, { 6, 0, 1942 }, { 7, 0, 512 }, + { 8, 0, 983 }, { 7, 10, 992 }, { 8, 10, 301 }, { 9, 10, 722 }, + { 12, 10, 63 }, { 13, 10, 29 }, { 14, 10, 161 }, { 15, 10, 18 }, + { 8, 11, 76 }, { 11, 10, 923 }, { 6, 0, 645 }, { 6, 0, 851 }, + { 4, 0, 498 }, { 4, 11, 293 }, { 7, 0, 217 }, { 8, 0, 140 }, + { 10, 0, 610 }, { 14, 11, 352 }, { 17, 11, 53 }, { 18, 11, 146 }, + { 18, 11, 152 }, { 19, 11, 11 }, { 22, 11, 54 }, { 6, 0, 1448 }, + { 10, 11, 841 }, { 5, 0, 905 }, { 4, 11, 605 }, { 7, 11, 518 }, + { 7, 11, 1282 }, { 7, 11, 1918 }, { 10, 11, 180 }, { 11, 11, 218 }, + { 11, 11, 917 }, { 7, 10, 825 }, { 12, 10, 328 }, { 4, 0, 456 }, + { 7, 0, 105 }, { 7, 0, 358 }, { 7, 0, 1637 }, { 8, 0, 643 }, + { 11, 0, 483 }, { 6, 0, 792 }, { 6, 11, 96 }, { 7, 11, 1426 }, + { 9, 11, 691 }, { 4, 11, 651 }, { 5, 11, 289 }, { 7, 11, 688 }, + { 8, 11, 35 }, { 9, 11, 511 }, { 10, 11, 767 }, { 19, 11, 118 }, + { 22, 0, 56 }, { 5, 0, 243 }, { 5, 0, 535 }, { 6, 10, 204 }, + { 10, 10, 320 }, { 10, 10, 583 }, { 13, 10, 502 }, { 14, 10, 72 }, + { 14, 10, 274 }, { 14, 10, 312 }, { 14, 10, 344 }, { 15, 10, 159 }, + { 16, 10, 62 }, { 16, 10, 69 }, { 17, 10, 30 }, { 18, 10, 42 }, + { 18, 10, 53 }, { 18, 10, 84 }, { 18, 10, 140 }, { 19, 10, 68 }, + { 19, 10, 85 }, { 20, 10, 5 }, { 20, 10, 45 }, { 20, 10, 101 }, + { 22, 10, 7 }, { 22, 10, 20 }, { 4, 10, 558 }, { 6, 10, 390 }, + { 7, 10, 162 }, { 7, 10, 689 }, { 9, 10, 360 }, { 10, 10, 653 }, + { 18, 11, 23 }, { 7, 0, 1748 }, { 5, 10, 856 }, { 6, 10, 1672 }, + { 6, 10, 1757 }, { 6, 10, 1781 }, { 5, 0, 539 }, { 5, 0, 754 }, + { 6, 0, 876 }, { 4, 11, 704 }, { 7, 11, 1078 }, { 5, 10, 92 }, + { 10, 10, 736 }, { 12, 10, 102 }, { 17, 0, 91 }, { 5, 10, 590 }, + { 9, 10, 213 }, { 6, 0, 1565 }, { 6, 0, 91 }, { 7, 0, 435 }, + { 4, 0, 939 }, { 12, 0, 792 }, { 6, 0, 1399 }, { 4, 0, 16 }, + { 5, 0, 316 }, { 5, 0, 842 }, { 6, 0, 370 }, { 6, 0, 1778 }, + { 8, 0, 166 }, { 11, 0, 812 }, { 12, 0, 206 }, { 12, 0, 351 }, + { 14, 0, 418 }, { 16, 0, 15 }, { 16, 0, 34 }, { 18, 0, 3 }, + { 19, 0, 3 }, { 19, 0, 7 }, { 20, 0, 4 }, { 21, 0, 21 }, + { 4, 11, 720 }, { 5, 11, 306 }, { 16, 0, 95 }, { 5, 11, 431 }, + { 4, 11, 234 }, { 7, 0, 551 }, { 4, 0, 999 }, { 6, 0, 1966 }, + { 6, 0, 2042 }, { 7, 0, 619 }, { 10, 0, 547 }, { 11, 0, 122 }, + { 12, 0, 601 }, { 15, 0, 7 }, { 20, 0, 20 }, { 5, 11, 464 }, + { 6, 11, 236 }, { 7, 11, 276 }, { 7, 11, 696 }, { 7, 11, 914 }, + { 7, 11, 1108 }, { 7, 11, 1448 }, { 9, 11, 15 }, { 9, 11, 564 }, + { 10, 11, 14 }, { 12, 11, 565 }, { 13, 11, 449 }, { 14, 11, 53 }, + { 15, 11, 13 }, { 16, 11, 64 }, { 17, 11, 41 }, { 6, 0, 884 }, + { 6, 0, 1019 }, { 6, 0, 1150 }, { 6, 11, 1767 }, { 12, 11, 194 }, + { 17, 11, 107 }, { 8, 10, 503 }, { 5, 11, 840 }, { 7, 0, 671 }, + { 6, 10, 466 }, { 4, 0, 888 }, { 4, 0, 149 }, { 10, 0, 368 }, + { 4, 0, 154 }, { 7, 0, 1134 }, { 8, 0, 105 }, { 7, 0, 983 }, + { 9, 11, 642 }, { 11, 11, 236 }, { 14, 11, 193 }, { 4, 0, 31 }, + { 6, 0, 429 }, { 7, 0, 962 }, { 9, 0, 458 }, { 11, 0, 691 }, + { 6, 0, 643 }, { 6, 0, 1102 }, { 4, 0, 312 }, { 4, 11, 68 }, + { 5, 11, 634 }, { 6, 11, 386 }, { 7, 11, 794 }, { 8, 11, 273 }, + { 9, 11, 563 }, { 10, 11, 105 }, { 10, 11, 171 }, { 11, 11, 94 }, + { 11, 11, 354 }, { 5, 0, 740 }, { 7, 0, 1642 }, { 4, 11, 95 }, + { 7, 11, 416 }, { 8, 11, 211 }, { 11, 11, 830 }, { 4, 0, 236 }, + { 10, 10, 241 }, { 7, 11, 731 }, { 13, 11, 20 }, { 15, 11, 11 }, + { 5, 0, 836 }, { 5, 0, 857 }, { 6, 0, 1680 }, { 7, 0, 59 }, + { 10, 0, 68 }, { 11, 0, 494 }, { 24, 11, 6 }, { 4, 0, 81 }, + { 11, 0, 867 }, { 7, 0, 795 }, { 5, 11, 689 }, { 4, 0, 1001 }, + { 5, 0, 282 }, { 6, 0, 1932 }, { 6, 0, 1977 }, { 6, 0, 1987 }, + { 6, 0, 1992 }, { 8, 0, 650 }, { 8, 0, 919 }, { 8, 0, 920 }, + { 8, 0, 923 }, { 8, 0, 926 }, { 8, 0, 927 }, { 8, 0, 931 }, + { 8, 0, 939 }, { 8, 0, 947 }, { 8, 0, 956 }, { 8, 0, 997 }, + { 9, 0, 907 }, { 10, 0, 950 }, { 10, 0, 953 }, { 10, 0, 954 }, + { 10, 0, 956 }, { 10, 0, 958 }, { 10, 0, 959 }, { 10, 0, 964 }, + { 10, 0, 970 }, { 10, 0, 972 }, { 10, 0, 973 }, { 10, 0, 975 }, + { 10, 0, 976 }, { 10, 0, 980 }, { 10, 0, 981 }, { 10, 0, 984 }, + { 10, 0, 988 }, { 10, 0, 990 }, { 10, 0, 995 }, { 10, 0, 999 }, + { 10, 0, 1002 }, { 10, 0, 1003 }, { 10, 0, 1005 }, { 10, 0, 1006 }, + { 10, 0, 1008 }, { 10, 0, 1009 }, { 10, 0, 1012 }, { 10, 0, 1014 }, + { 10, 0, 1015 }, { 10, 0, 1019 }, { 10, 0, 1020 }, { 10, 0, 1022 }, + { 12, 0, 959 }, { 12, 0, 961 }, { 12, 0, 962 }, { 12, 0, 963 }, + { 12, 0, 964 }, { 12, 0, 965 }, { 12, 0, 967 }, { 12, 0, 968 }, + { 12, 0, 969 }, { 12, 0, 970 }, { 12, 0, 971 }, { 12, 0, 972 }, + { 12, 0, 973 }, { 12, 0, 974 }, { 12, 0, 975 }, { 12, 0, 976 }, + { 12, 0, 977 }, { 12, 0, 979 }, { 12, 0, 981 }, { 12, 0, 982 }, + { 12, 0, 983 }, { 12, 0, 984 }, { 12, 0, 985 }, { 12, 0, 986 }, + { 12, 0, 987 }, { 12, 0, 989 }, { 12, 0, 990 }, { 12, 0, 992 }, + { 12, 0, 993 }, { 12, 0, 995 }, { 12, 0, 998 }, { 12, 0, 999 }, + { 12, 0, 1000 }, { 12, 0, 1001 }, { 12, 0, 1002 }, { 12, 0, 1004 }, + { 12, 0, 1005 }, { 12, 0, 1006 }, { 12, 0, 1007 }, { 12, 0, 1008 }, + { 12, 0, 1009 }, { 12, 0, 1010 }, { 12, 0, 1011 }, { 12, 0, 1012 }, + { 12, 0, 1014 }, { 12, 0, 1015 }, { 12, 0, 1016 }, { 12, 0, 1017 }, + { 12, 0, 1018 }, { 12, 0, 1019 }, { 12, 0, 1022 }, { 12, 0, 1023 }, + { 14, 0, 475 }, { 14, 0, 477 }, { 14, 0, 478 }, { 14, 0, 479 }, + { 14, 0, 480 }, { 14, 0, 482 }, { 14, 0, 483 }, { 14, 0, 484 }, + { 14, 0, 485 }, { 14, 0, 486 }, { 14, 0, 487 }, { 14, 0, 488 }, + { 14, 0, 489 }, { 14, 0, 490 }, { 14, 0, 491 }, { 14, 0, 492 }, + { 14, 0, 493 }, { 14, 0, 494 }, { 14, 0, 495 }, { 14, 0, 496 }, + { 14, 0, 497 }, { 14, 0, 498 }, { 14, 0, 499 }, { 14, 0, 500 }, + { 14, 0, 501 }, { 14, 0, 502 }, { 14, 0, 503 }, { 14, 0, 504 }, + { 14, 0, 506 }, { 14, 0, 507 }, { 14, 0, 508 }, { 14, 0, 509 }, + { 14, 0, 510 }, { 14, 0, 511 }, { 16, 0, 113 }, { 16, 0, 114 }, + { 16, 0, 115 }, { 16, 0, 117 }, { 16, 0, 118 }, { 16, 0, 119 }, + { 16, 0, 121 }, { 16, 0, 122 }, { 16, 0, 123 }, { 16, 0, 124 }, + { 16, 0, 125 }, { 16, 0, 126 }, { 16, 0, 127 }, { 18, 0, 242 }, + { 18, 0, 243 }, { 18, 0, 244 }, { 18, 0, 245 }, { 18, 0, 248 }, + { 18, 0, 249 }, { 18, 0, 250 }, { 18, 0, 251 }, { 18, 0, 252 }, + { 18, 0, 253 }, { 18, 0, 254 }, { 18, 0, 255 }, { 20, 0, 125 }, + { 20, 0, 126 }, { 20, 0, 127 }, { 7, 11, 1717 }, { 7, 11, 1769 }, + { 10, 11, 546 }, { 7, 11, 1127 }, { 7, 11, 1572 }, { 10, 11, 297 }, + { 10, 11, 422 }, { 11, 11, 764 }, { 11, 11, 810 }, { 12, 11, 264 }, + { 13, 11, 102 }, { 13, 11, 300 }, { 13, 11, 484 }, { 14, 11, 147 }, + { 14, 11, 229 }, { 17, 11, 71 }, { 18, 11, 118 }, { 19, 11, 120 }, + { 6, 0, 1148 }, { 6, 0, 1586 }, { 4, 0, 775 }, { 7, 10, 954 }, + { 5, 11, 864 }, { 5, 11, 928 }, { 10, 11, 189 }, { 7, 10, 1958 }, + { 6, 10, 549 }, { 8, 10, 34 }, { 8, 10, 283 }, { 9, 10, 165 }, + { 10, 10, 475 }, { 5, 10, 652 }, { 5, 10, 701 }, { 7, 10, 449 }, + { 7, 11, 695 }, { 4, 10, 655 }, { 7, 10, 850 }, { 17, 10, 75 }, + { 18, 10, 137 }, { 12, 11, 682 }, { 5, 11, 523 }, { 8, 0, 970 }, + { 8, 10, 670 }, { 8, 11, 555 }, { 7, 11, 76 }, { 8, 11, 44 }, + { 9, 11, 884 }, { 10, 11, 580 }, { 11, 11, 399 }, { 11, 11, 894 }, + { 15, 11, 122 }, { 18, 11, 144 }, { 19, 11, 61 }, { 6, 10, 159 }, + { 6, 10, 364 }, { 7, 10, 516 }, { 7, 10, 1439 }, { 9, 10, 518 }, + { 4, 0, 71 }, { 5, 0, 376 }, { 7, 0, 119 }, { 10, 0, 665 }, + { 13, 10, 151 }, { 11, 0, 827 }, { 14, 0, 34 }, { 15, 0, 148 }, + { 5, 11, 518 }, { 4, 0, 479 }, { 7, 11, 1787 }, { 7, 11, 1852 }, + { 7, 10, 993 }, { 7, 0, 607 }, { 8, 0, 99 }, { 6, 0, 1960 }, + { 4, 0, 793 }, { 4, 0, 41 }, { 5, 0, 74 }, { 7, 0, 1627 }, + { 11, 0, 871 }, { 12, 0, 619 }, { 7, 0, 94 }, { 11, 0, 329 }, + { 11, 0, 965 }, { 12, 0, 241 }, { 14, 0, 354 }, { 15, 0, 22 }, + { 20, 0, 63 }, { 7, 10, 501 }, { 9, 10, 111 }, { 10, 10, 141 }, + { 11, 10, 332 }, { 13, 10, 43 }, { 13, 10, 429 }, { 14, 10, 130 }, + { 14, 10, 415 }, { 17, 10, 102 }, { 9, 0, 209 }, { 9, 0, 300 }, + { 6, 0, 1497 }, { 10, 11, 255 }, { 4, 11, 934 }, { 5, 11, 138 }, + { 8, 11, 610 }, { 5, 0, 98 }, { 6, 0, 1316 }, { 10, 11, 804 }, + { 10, 11, 832 }, { 8, 11, 96 }, { 9, 11, 36 }, { 10, 11, 607 }, + { 11, 11, 423 }, { 11, 11, 442 }, { 12, 11, 309 }, { 14, 11, 199 }, + { 15, 11, 90 }, { 17, 11, 110 }, { 4, 0, 463 }, { 5, 10, 149 }, + { 8, 10, 233 }, { 5, 10, 935 }, { 4, 11, 652 }, { 8, 11, 320 }, + { 9, 11, 13 }, { 9, 11, 398 }, { 9, 11, 727 }, { 10, 11, 75 }, + { 10, 11, 184 }, { 10, 11, 230 }, { 10, 11, 564 }, { 10, 11, 569 }, + { 11, 11, 973 }, { 12, 11, 70 }, { 12, 11, 189 }, { 13, 11, 57 }, + { 13, 11, 257 }, { 22, 11, 6 }, { 22, 11, 16 }, { 14, 0, 291 }, + { 12, 10, 582 }, { 18, 10, 131 }, { 8, 10, 801 }, { 5, 0, 984 }, + { 17, 11, 116 }, { 4, 11, 692 }, { 5, 11, 321 }, { 4, 0, 182 }, + { 6, 0, 205 }, { 7, 0, 220 }, { 4, 0, 42 }, { 9, 0, 205 }, + { 9, 0, 786 }, { 10, 0, 659 }, { 6, 0, 801 }, { 11, 11, 130 }, + { 12, 11, 609 }, { 4, 0, 635 }, { 5, 11, 345 }, { 7, 11, 1016 }, + { 11, 0, 533 }, { 4, 0, 371 }, { 4, 0, 272 }, { 7, 0, 836 }, + { 6, 0, 1282 }, { 7, 11, 1100 }, { 5, 0, 825 }, { 6, 0, 1640 }, + { 7, 11, 1325 }, { 5, 11, 673 }, { 4, 11, 287 }, { 5, 11, 1018 }, + { 7, 0, 357 }, { 6, 0, 467 }, { 9, 0, 879 }, { 7, 0, 317 }, + { 7, 0, 569 }, { 6, 0, 924 }, { 6, 0, 1588 }, { 5, 11, 34 }, + { 5, 10, 406 }, { 10, 11, 724 }, { 12, 11, 444 }, { 13, 11, 354 }, + { 18, 11, 32 }, { 23, 11, 24 }, { 23, 11, 31 }, { 24, 11, 5 }, + { 6, 0, 1795 }, { 6, 0, 1835 }, { 6, 0, 1836 }, { 6, 0, 1856 }, + { 8, 0, 844 }, { 8, 0, 849 }, { 8, 0, 854 }, { 8, 0, 870 }, + { 8, 0, 887 }, { 10, 0, 852 }, { 10, 0, 942 }, { 6, 10, 69 }, + { 7, 10, 117 }, { 9, 0, 307 }, { 4, 0, 944 }, { 6, 0, 1799 }, + { 6, 0, 1825 }, { 10, 0, 848 }, { 10, 0, 875 }, { 10, 0, 895 }, + { 10, 0, 899 }, { 10, 0, 902 }, { 12, 0, 773 }, { 11, 0, 43 }, + { 13, 0, 72 }, { 13, 0, 142 }, { 7, 10, 1830 }, { 6, 11, 382 }, + { 4, 10, 432 }, { 7, 10, 824 }, { 4, 11, 329 }, { 7, 0, 1820 }, + { 11, 11, 124 }, { 5, 10, 826 }, { 5, 0, 525 }, { 4, 11, 906 }, + { 7, 11, 1940 }, { 8, 11, 366 }, { 10, 11, 10 }, { 4, 11, 123 }, + { 4, 11, 649 }, { 5, 11, 605 }, { 7, 11, 1509 }, { 8, 11, 36 }, + { 6, 0, 110 }, { 7, 0, 1681 }, { 5, 0, 493 }, { 5, 11, 767 }, + { 4, 0, 174 }, { 7, 0, 911 }, { 10, 11, 786 }, { 8, 0, 417 }, + { 9, 0, 782 }, { 5, 10, 1000 }, { 7, 0, 733 }, { 9, 0, 583 }, + { 4, 10, 297 }, { 6, 10, 529 }, { 7, 10, 152 }, { 7, 10, 713 }, + { 7, 10, 1845 }, { 8, 10, 710 }, { 8, 10, 717 }, { 12, 10, 639 }, + { 12, 10, 685 }, { 4, 0, 32 }, { 5, 0, 215 }, { 6, 0, 269 }, + { 7, 0, 1782 }, { 7, 0, 1892 }, { 10, 0, 16 }, { 11, 0, 822 }, + { 11, 0, 954 }, { 13, 0, 481 }, { 4, 11, 273 }, { 5, 11, 658 }, + { 5, 11, 995 }, { 8, 0, 477 }, { 6, 11, 72 }, { 7, 11, 1345 }, + { 5, 0, 308 }, { 7, 0, 1088 }, { 4, 10, 520 }, { 7, 10, 575 }, + { 5, 11, 589 }, { 5, 0, 126 }, { 8, 0, 297 }, { 9, 0, 366 }, + { 12, 0, 374 }, { 7, 0, 1551 }, { 11, 0, 361 }, { 5, 11, 117 }, + { 6, 11, 514 }, { 6, 11, 541 }, { 7, 11, 1164 }, { 7, 11, 1436 }, + { 8, 11, 220 }, { 8, 11, 648 }, { 10, 11, 688 }, { 11, 11, 560 }, + { 5, 11, 686 }, { 4, 0, 946 }, { 6, 0, 1807 }, { 8, 0, 871 }, + { 10, 0, 854 }, { 10, 0, 870 }, { 10, 0, 888 }, { 10, 0, 897 }, + { 10, 0, 920 }, { 12, 0, 722 }, { 12, 0, 761 }, { 12, 0, 763 }, + { 12, 0, 764 }, { 14, 0, 454 }, { 14, 0, 465 }, { 16, 0, 107 }, + { 18, 0, 167 }, { 18, 0, 168 }, { 18, 0, 172 }, { 4, 0, 175 }, + { 7, 0, 1307 }, { 4, 0, 685 }, { 7, 11, 1834 }, { 5, 0, 797 }, + { 6, 0, 745 }, { 6, 0, 858 }, { 6, 0, 963 }, { 5, 0, 565 }, + { 5, 10, 397 }, { 6, 10, 154 }, { 7, 11, 196 }, { 7, 10, 676 }, + { 8, 10, 443 }, { 8, 10, 609 }, { 9, 10, 24 }, { 9, 10, 325 }, + { 10, 10, 35 }, { 10, 11, 765 }, { 11, 11, 347 }, { 11, 10, 535 }, + { 11, 11, 552 }, { 11, 11, 576 }, { 11, 10, 672 }, { 11, 11, 790 }, + { 11, 10, 1018 }, { 12, 11, 263 }, { 12, 10, 637 }, { 13, 11, 246 }, + { 13, 11, 270 }, { 13, 11, 395 }, { 14, 11, 74 }, { 14, 11, 176 }, + { 14, 11, 190 }, { 14, 11, 398 }, { 14, 11, 412 }, { 15, 11, 32 }, + { 15, 11, 63 }, { 16, 10, 30 }, { 16, 11, 88 }, { 19, 11, 105 }, + { 13, 11, 84 }, { 13, 11, 122 }, { 4, 0, 252 }, { 7, 0, 1068 }, + { 10, 0, 434 }, { 11, 0, 228 }, { 11, 0, 426 }, { 13, 0, 231 }, + { 18, 0, 106 }, { 20, 0, 87 }, { 9, 0, 826 }, { 4, 11, 589 }, + { 11, 11, 282 }, { 5, 11, 381 }, { 7, 11, 1792 }, { 4, 0, 791 }, + { 5, 0, 231 }, { 10, 0, 509 }, { 5, 10, 981 }, { 7, 0, 601 }, + { 9, 0, 277 }, { 9, 0, 674 }, { 10, 0, 178 }, { 10, 0, 418 }, + { 10, 0, 571 }, { 11, 0, 531 }, { 12, 0, 113 }, { 12, 0, 475 }, + { 13, 0, 99 }, { 14, 0, 428 }, { 4, 10, 56 }, { 7, 11, 616 }, + { 7, 10, 1791 }, { 8, 10, 607 }, { 8, 10, 651 }, { 10, 11, 413 }, + { 11, 10, 465 }, { 11, 10, 835 }, { 12, 10, 337 }, { 13, 10, 480 }, + { 7, 0, 1591 }, { 16, 0, 43 }, { 9, 10, 158 }, { 10, 10, 411 }, + { 7, 0, 1683 }, { 8, 0, 289 }, { 11, 0, 45 }, { 12, 0, 278 }, + { 12, 0, 537 }, { 6, 11, 120 }, { 7, 11, 1188 }, { 7, 11, 1710 }, + { 8, 11, 286 }, { 9, 11, 667 }, { 11, 11, 592 }, { 11, 11, 730 }, + { 8, 10, 617 }, { 7, 0, 1120 }, { 7, 11, 1146 }, { 11, 10, 563 }, + { 4, 11, 352 }, { 4, 10, 369 }, { 7, 11, 687 }, { 15, 11, 38 }, + { 4, 0, 399 }, { 5, 0, 119 }, { 5, 0, 494 }, { 7, 0, 751 }, + { 9, 0, 556 }, { 14, 11, 179 }, { 15, 11, 151 }, { 22, 11, 11 }, + { 4, 11, 192 }, { 5, 11, 49 }, { 6, 11, 200 }, { 6, 11, 293 }, + { 6, 11, 1696 }, { 7, 11, 488 }, { 4, 0, 398 }, { 5, 0, 660 }, + { 7, 0, 1030 }, { 6, 10, 622 }, { 7, 11, 595 }, { 13, 0, 168 }, + { 4, 11, 147 }, { 7, 0, 973 }, { 10, 10, 624 }, { 14, 10, 279 }, + { 4, 10, 363 }, { 4, 0, 642 }, { 5, 11, 934 }, { 6, 0, 1615 }, + { 7, 11, 505 }, { 7, 11, 523 }, { 7, 0, 594 }, { 7, 0, 851 }, + { 7, 0, 1858 }, { 9, 0, 411 }, { 9, 0, 574 }, { 9, 0, 666 }, + { 9, 0, 737 }, { 10, 0, 346 }, { 10, 0, 712 }, { 11, 0, 246 }, + { 11, 0, 432 }, { 11, 0, 517 }, { 11, 0, 647 }, { 11, 0, 679 }, + { 11, 0, 727 }, { 12, 0, 304 }, { 12, 0, 305 }, { 12, 0, 323 }, + { 12, 0, 483 }, { 12, 0, 572 }, { 12, 0, 593 }, { 12, 0, 602 }, + { 13, 0, 95 }, { 13, 0, 101 }, { 13, 0, 171 }, { 13, 0, 315 }, + { 13, 0, 378 }, { 13, 0, 425 }, { 13, 0, 475 }, { 14, 0, 63 }, + { 14, 0, 380 }, { 14, 0, 384 }, { 15, 0, 133 }, { 18, 0, 112 }, + { 20, 0, 72 }, { 7, 0, 1093 }, { 4, 0, 679 }, { 8, 0, 913 }, + { 10, 0, 903 }, { 10, 0, 915 }, { 12, 0, 648 }, { 12, 0, 649 }, + { 14, 0, 455 }, { 16, 0, 112 }, { 10, 11, 438 }, { 9, 0, 203 }, + { 6, 10, 292 }, { 6, 0, 1492 }, { 7, 0, 1374 }, { 8, 0, 540 }, + { 5, 10, 177 }, { 6, 10, 616 }, { 7, 10, 827 }, { 9, 10, 525 }, + { 10, 10, 656 }, { 7, 0, 1486 }, { 9, 0, 714 }, { 10, 10, 31 }, + { 8, 0, 825 }, { 6, 0, 1511 }, { 4, 11, 637 }, { 6, 0, 952 }, + { 4, 10, 161 }, { 5, 10, 631 }, { 5, 0, 143 }, { 5, 0, 769 }, + { 6, 0, 1760 }, { 7, 0, 682 }, { 7, 0, 1992 }, { 8, 0, 736 }, + { 4, 0, 700 }, { 6, 0, 1540 }, { 4, 11, 777 }, { 9, 11, 867 }, + { 10, 11, 837 }, { 7, 0, 1557 }, { 7, 10, 1684 }, { 5, 0, 860 }, + { 6, 0, 422 }, { 7, 0, 0 }, { 7, 0, 1544 }, { 9, 0, 605 }, + { 11, 0, 990 }, { 12, 0, 235 }, { 12, 0, 453 }, { 13, 0, 47 }, + { 13, 0, 266 }, { 9, 10, 469 }, { 9, 10, 709 }, { 12, 10, 512 }, + { 14, 10, 65 }, { 17, 10, 12 }, { 11, 0, 807 }, { 10, 10, 229 }, + { 11, 10, 73 }, { 11, 10, 376 }, { 6, 11, 170 }, { 7, 11, 1080 }, + { 8, 11, 395 }, { 8, 11, 487 }, { 11, 11, 125 }, { 13, 11, 147 }, + { 5, 0, 515 }, { 9, 0, 131 }, { 7, 0, 1605 }, { 11, 0, 962 }, + { 18, 0, 139 }, { 4, 0, 646 }, { 4, 0, 396 }, { 7, 0, 728 }, + { 9, 0, 117 }, { 13, 0, 202 }, { 20, 0, 51 }, { 6, 0, 121 }, + { 6, 0, 124 }, { 6, 0, 357 }, { 7, 0, 1138 }, { 7, 0, 1295 }, + { 8, 0, 162 }, { 8, 0, 508 }, { 11, 0, 655 }, { 4, 11, 535 }, + { 6, 10, 558 }, { 7, 10, 651 }, { 8, 11, 618 }, { 9, 10, 0 }, + { 10, 10, 34 }, { 11, 10, 1008 }, { 7, 11, 1245 }, { 10, 0, 357 }, + { 22, 11, 23 }, { 5, 0, 237 }, { 7, 0, 1784 }, { 7, 10, 1832 }, + { 10, 10, 374 }, { 4, 0, 713 }, { 4, 11, 46 }, { 6, 0, 1536 }, + { 10, 0, 348 }, { 5, 11, 811 }, { 6, 11, 1679 }, { 6, 11, 1714 }, + { 7, 11, 2032 }, { 11, 11, 182 }, { 14, 11, 195 }, { 6, 0, 523 }, + { 7, 0, 738 }, { 7, 10, 771 }, { 7, 10, 1731 }, { 9, 10, 405 }, + { 10, 10, 421 }, { 7, 11, 1458 }, { 9, 11, 407 }, { 11, 11, 15 }, + { 6, 11, 34 }, { 7, 11, 69 }, { 7, 11, 640 }, { 7, 11, 1089 }, + { 8, 11, 708 }, { 8, 11, 721 }, { 9, 11, 363 }, { 9, 11, 643 }, + { 10, 11, 628 }, { 20, 11, 98 }, { 5, 0, 434 }, { 7, 0, 1877 }, + { 7, 0, 571 }, { 10, 0, 366 }, { 5, 10, 881 }, { 5, 10, 885 }, + { 9, 0, 513 }, { 10, 0, 25 }, { 10, 0, 39 }, { 12, 0, 122 }, + { 12, 0, 187 }, { 4, 0, 580 }, { 5, 10, 142 }, { 6, 10, 546 }, + { 4, 11, 462 }, { 9, 0, 873 }, { 5, 10, 466 }, { 11, 10, 571 }, + { 12, 10, 198 }, { 13, 10, 283 }, { 14, 10, 186 }, { 15, 10, 21 }, + { 15, 10, 103 }, { 7, 0, 171 }, { 4, 10, 185 }, { 5, 10, 257 }, + { 5, 10, 839 }, { 5, 10, 936 }, { 9, 10, 399 }, { 10, 10, 258 }, + { 10, 10, 395 }, { 10, 10, 734 }, { 11, 10, 1014 }, { 12, 10, 23 }, + { 13, 10, 350 }, { 14, 10, 150 }, { 19, 10, 6 }, { 6, 0, 625 }, + { 7, 0, 107 }, { 7, 0, 838 }, { 8, 0, 550 }, { 10, 0, 401 }, + { 5, 11, 73 }, { 6, 11, 23 }, { 6, 11, 338 }, { 4, 0, 943 }, + { 6, 0, 1850 }, { 12, 0, 713 }, { 14, 0, 434 }, { 11, 0, 588 }, + { 11, 0, 864 }, { 11, 0, 936 }, { 11, 0, 968 }, { 12, 0, 73 }, + { 12, 0, 343 }, { 12, 0, 394 }, { 13, 0, 275 }, { 14, 0, 257 }, + { 15, 0, 160 }, { 7, 10, 404 }, { 7, 10, 1377 }, { 7, 10, 1430 }, + { 7, 10, 2017 }, { 8, 10, 149 }, { 8, 10, 239 }, { 8, 10, 512 }, + { 8, 10, 793 }, { 8, 10, 818 }, { 9, 10, 474 }, { 9, 10, 595 }, + { 10, 10, 122 }, { 10, 10, 565 }, { 10, 10, 649 }, { 10, 10, 783 }, + { 11, 10, 239 }, { 11, 10, 295 }, { 11, 10, 447 }, { 11, 10, 528 }, + { 11, 10, 639 }, { 11, 10, 800 }, { 12, 10, 25 }, { 12, 10, 157 }, + { 12, 10, 316 }, { 12, 10, 390 }, { 12, 10, 391 }, { 12, 10, 395 }, + { 12, 10, 478 }, { 12, 10, 503 }, { 12, 10, 592 }, { 12, 10, 680 }, + { 13, 10, 50 }, { 13, 10, 53 }, { 13, 10, 132 }, { 13, 10, 198 }, + { 13, 10, 322 }, { 13, 10, 415 }, { 13, 10, 511 }, { 14, 10, 71 }, + { 14, 10, 395 }, { 15, 10, 71 }, { 15, 10, 136 }, { 17, 10, 123 }, + { 18, 10, 93 }, { 19, 10, 58 }, { 5, 0, 768 }, { 11, 0, 103 }, + { 14, 0, 0 }, { 8, 10, 712 }, { 4, 0, 799 }, { 4, 0, 894 }, + { 7, 11, 725 }, { 8, 11, 498 }, { 11, 11, 268 }, { 7, 11, 1798 }, + { 7, 11, 773 }, { 13, 11, 360 }, { 4, 10, 377 }, { 24, 10, 13 }, + { 7, 0, 1673 }, { 4, 11, 583 }, { 6, 0, 1052 }, { 5, 11, 220 }, + { 12, 11, 69 }, { 4, 11, 544 }, { 4, 10, 180 }, { 7, 10, 1906 }, + { 6, 0, 272 }, { 4, 0, 441 }, { 6, 0, 1421 }, { 4, 0, 9 }, + { 5, 0, 128 }, { 7, 0, 368 }, { 11, 0, 480 }, { 20, 0, 3 }, + { 5, 11, 176 }, { 6, 11, 437 }, { 6, 11, 564 }, { 11, 11, 181 }, + { 13, 11, 183 }, { 4, 10, 491 }, { 7, 0, 1182 }, { 13, 11, 67 }, + { 6, 0, 1346 }, { 4, 10, 171 }, { 10, 10, 234 }, { 4, 10, 586 }, + { 7, 10, 1186 }, { 10, 10, 631 }, { 8, 0, 682 }, { 6, 0, 1004 }, + { 15, 0, 24 }, { 15, 11, 24 }, { 6, 0, 968 }, { 4, 0, 2 }, + { 6, 0, 742 }, { 6, 0, 793 }, { 7, 0, 545 }, { 7, 0, 894 }, + { 9, 10, 931 }, { 10, 10, 334 }, { 20, 10, 71 }, { 8, 11, 600 }, + { 5, 10, 765 }, { 9, 0, 769 }, { 12, 0, 185 }, { 4, 11, 790 }, + { 5, 11, 273 }, { 6, 11, 394 }, { 7, 0, 474 }, { 9, 0, 578 }, + { 4, 11, 135 }, { 6, 11, 127 }, { 7, 11, 1185 }, { 7, 11, 1511 }, + { 8, 11, 613 }, { 11, 11, 5 }, { 12, 11, 133 }, { 12, 11, 495 }, + { 12, 11, 586 }, { 14, 11, 385 }, { 15, 11, 118 }, { 17, 11, 20 }, + { 18, 11, 98 }, { 5, 10, 424 }, { 5, 0, 530 }, { 14, 0, 113 }, + { 6, 11, 230 }, { 7, 11, 961 }, { 7, 11, 1085 }, { 8, 11, 462 }, + { 7, 11, 1954 }, { 9, 11, 636 }, { 8, 10, 714 }, { 21, 11, 6 }, + { 7, 10, 685 }, { 9, 10, 420 }, { 10, 10, 269 }, { 10, 10, 285 }, + { 10, 10, 576 }, { 11, 10, 397 }, { 13, 10, 175 }, { 17, 10, 90 }, + { 4, 10, 429 }, { 5, 0, 556 }, { 5, 11, 162 }, { 8, 11, 68 }, + { 4, 11, 654 }, { 4, 11, 156 }, { 7, 11, 998 }, { 7, 11, 1045 }, + { 7, 11, 1860 }, { 9, 11, 48 }, { 9, 11, 692 }, { 11, 11, 419 }, + { 11, 11, 602 }, { 6, 0, 1317 }, { 8, 0, 16 }, { 9, 0, 825 }, + { 12, 0, 568 }, { 7, 11, 1276 }, { 8, 11, 474 }, { 9, 11, 652 }, + { 18, 0, 97 }, { 7, 10, 18 }, { 7, 10, 699 }, { 7, 10, 1966 }, + { 8, 10, 752 }, { 9, 10, 273 }, { 9, 10, 412 }, { 9, 10, 703 }, + { 10, 10, 71 }, { 10, 10, 427 }, { 10, 10, 508 }, { 10, 0, 703 }, + { 7, 11, 1454 }, { 10, 11, 703 }, { 4, 10, 53 }, { 5, 10, 186 }, + { 7, 10, 752 }, { 6, 0, 892 }, { 6, 0, 1571 }, { 8, 10, 575 }, + { 10, 10, 289 }, { 11, 10, 319 }, { 6, 0, 186 }, { 9, 0, 426 }, + { 6, 0, 1101 }, { 4, 10, 675 }, { 4, 0, 585 }, { 6, 0, 1870 }, + { 9, 0, 937 }, { 24, 11, 10 }, { 9, 11, 197 }, { 10, 11, 300 }, + { 12, 11, 473 }, { 13, 11, 90 }, { 13, 11, 405 }, { 4, 0, 93 }, + { 5, 0, 252 }, { 6, 0, 229 }, { 7, 0, 291 }, { 9, 0, 550 }, + { 11, 0, 644 }, { 9, 0, 749 }, { 9, 0, 162 }, { 6, 10, 209 }, + { 8, 10, 468 }, { 9, 10, 210 }, { 11, 10, 36 }, { 12, 10, 28 }, + { 12, 10, 630 }, { 13, 10, 21 }, { 13, 10, 349 }, { 14, 10, 7 }, + { 17, 10, 13 }, { 4, 0, 381 }, { 4, 11, 606 }, { 4, 10, 342 }, + { 7, 10, 1179 }, { 7, 11, 1587 }, { 7, 11, 1707 }, { 10, 11, 528 }, + { 11, 11, 504 }, { 12, 11, 39 }, { 13, 11, 265 }, { 13, 11, 439 }, + { 4, 10, 928 }, { 5, 10, 910 }, { 7, 10, 1838 }, { 7, 11, 1978 }, + { 8, 11, 676 }, { 6, 0, 762 }, { 6, 0, 796 }, { 6, 0, 956 }, + { 4, 10, 318 }, { 4, 10, 496 }, { 7, 10, 856 }, { 11, 10, 654 }, + { 9, 11, 242 }, { 4, 11, 361 }, { 5, 11, 315 }, { 4, 11, 461 }, + { 4, 11, 472 }, { 4, 0, 857 }, { 5, 0, 21 }, { 6, 0, 77 }, + { 6, 0, 157 }, { 7, 0, 974 }, { 7, 0, 1301 }, { 7, 0, 1339 }, + { 7, 0, 1490 }, { 7, 0, 1873 }, { 9, 0, 628 }, { 7, 10, 915 }, + { 8, 10, 247 }, { 19, 10, 0 }, { 4, 10, 202 }, { 5, 10, 382 }, + { 6, 10, 454 }, { 7, 10, 936 }, { 7, 10, 1803 }, { 8, 10, 758 }, + { 9, 10, 375 }, { 9, 10, 895 }, { 10, 10, 743 }, { 10, 10, 792 }, + { 11, 10, 978 }, { 11, 10, 1012 }, { 14, 10, 109 }, { 7, 11, 617 }, + { 10, 11, 498 }, { 11, 11, 501 }, { 12, 11, 16 }, { 12, 11, 150 }, + { 7, 10, 1150 }, { 7, 10, 1425 }, { 7, 10, 1453 }, { 10, 11, 747 }, + { 12, 10, 513 }, { 5, 11, 155 }, { 11, 0, 919 }, { 13, 0, 409 }, + { 10, 10, 791 }, { 10, 0, 633 }, { 11, 11, 729 }, { 7, 11, 163 }, + { 8, 11, 319 }, { 9, 11, 402 }, { 10, 11, 24 }, { 10, 11, 681 }, + { 11, 11, 200 }, { 11, 11, 567 }, { 12, 11, 253 }, { 12, 11, 410 }, + { 14, 11, 219 }, { 5, 11, 475 }, { 7, 11, 1780 }, { 9, 11, 230 }, + { 11, 11, 297 }, { 11, 11, 558 }, { 14, 11, 322 }, { 19, 11, 76 }, + { 7, 0, 332 }, { 6, 10, 445 }, { 9, 10, 909 }, { 7, 11, 1956 }, + { 8, 11, 274 }, { 6, 10, 578 }, { 7, 0, 1489 }, { 7, 11, 1848 }, + { 5, 11, 944 }, { 6, 11, 1769 }, { 4, 11, 144 }, { 8, 10, 766 }, + { 4, 0, 832 }, { 7, 10, 541 }, { 8, 0, 398 }, { 9, 0, 681 }, + { 11, 0, 632 }, { 8, 0, 645 }, { 9, 0, 791 }, { 10, 0, 93 }, + { 16, 0, 13 }, { 17, 0, 23 }, { 18, 0, 135 }, { 19, 0, 12 }, + { 20, 0, 1 }, { 20, 0, 12 }, { 20, 0, 14 }, { 6, 11, 247 }, + { 9, 11, 555 }, { 6, 0, 20 }, { 4, 0, 800 }, { 7, 0, 1841 }, + { 11, 10, 983 }, { 9, 10, 768 }, { 4, 10, 584 }, { 13, 11, 51 }, + { 6, 0, 1993 }, { 4, 11, 620 }, { 10, 11, 280 }, { 8, 0, 769 }, + { 11, 0, 290 }, { 11, 0, 665 }, { 7, 11, 1810 }, { 11, 11, 866 }, + { 12, 11, 103 }, { 13, 11, 495 }, { 17, 11, 67 }, { 19, 11, 74 }, + { 6, 0, 1426 }, { 11, 0, 60 }, { 4, 10, 326 }, { 7, 10, 1770 }, + { 7, 0, 1874 }, { 9, 0, 641 }, { 4, 10, 226 }, { 6, 0, 644 }, + { 5, 10, 426 }, { 8, 10, 30 }, { 9, 10, 2 }, { 11, 10, 549 }, + { 19, 10, 122 }, { 5, 11, 428 }, { 10, 11, 442 }, { 7, 11, 1871 }, + { 7, 0, 1757 }, { 19, 10, 117 }, { 7, 0, 937 }, { 7, 0, 1652 }, + { 6, 0, 654 }, { 6, 0, 1476 }, { 5, 11, 99 }, { 7, 0, 527 }, + { 4, 10, 345 }, { 4, 10, 385 }, { 4, 11, 397 }, { 7, 10, 265 }, + { 7, 10, 587 }, { 4, 0, 579 }, { 5, 0, 226 }, { 5, 0, 323 }, + { 7, 0, 960 }, { 6, 0, 1486 }, { 8, 11, 502 }, { 16, 11, 9 }, + { 4, 10, 347 }, { 5, 10, 423 }, { 5, 10, 996 }, { 7, 10, 1329 }, + { 7, 11, 727 }, { 18, 11, 73 }, { 4, 11, 485 }, { 7, 11, 353 }, + { 7, 10, 1259 }, { 7, 11, 1523 }, { 9, 10, 125 }, { 11, 10, 65 }, + { 6, 0, 325 }, { 5, 10, 136 }, { 6, 11, 366 }, { 7, 11, 1384 }, + { 7, 11, 1601 }, { 8, 10, 644 }, { 10, 11, 160 }, { 6, 0, 1345 }, + { 9, 11, 282 }, { 18, 0, 91 }, { 19, 0, 70 }, { 8, 0, 404 }, + { 4, 11, 157 }, { 5, 11, 471 }, { 5, 0, 973 }, { 6, 0, 135 }, + { 7, 0, 1176 }, { 8, 11, 116 }, { 11, 11, 551 }, { 14, 11, 159 }, + { 4, 0, 549 }, { 4, 10, 433 }, { 5, 10, 719 }, { 8, 0, 976 }, + { 5, 11, 160 }, { 7, 11, 363 }, { 7, 11, 589 }, { 10, 11, 170 }, + { 13, 11, 55 }, { 16, 0, 21 }, { 16, 0, 51 }, { 7, 0, 314 }, + { 7, 10, 1363 }, { 4, 11, 108 }, { 7, 11, 405 }, { 10, 11, 491 }, + { 11, 11, 498 }, { 18, 0, 4 }, { 4, 10, 555 }, { 8, 10, 536 }, + { 10, 10, 288 }, { 11, 10, 1005 }, { 7, 11, 1005 }, { 6, 0, 281 }, + { 7, 0, 6 }, { 8, 0, 282 }, { 8, 0, 480 }, { 8, 0, 499 }, + { 9, 0, 198 }, { 10, 0, 143 }, { 10, 0, 169 }, { 10, 0, 211 }, + { 10, 0, 417 }, { 10, 0, 574 }, { 11, 0, 147 }, { 11, 0, 395 }, + { 12, 0, 75 }, { 12, 0, 407 }, { 12, 0, 608 }, { 13, 0, 500 }, + { 14, 0, 251 }, { 6, 0, 1093 }, { 6, 0, 1405 }, { 9, 10, 370 }, + { 10, 10, 90 }, { 4, 11, 926 }, { 5, 11, 983 }, { 7, 0, 1776 }, + { 6, 0, 1528 }, { 4, 0, 419 }, { 4, 11, 538 }, { 6, 11, 294 }, + { 7, 11, 1267 }, { 8, 11, 624 }, { 7, 11, 1772 }, { 10, 11, 301 }, + { 4, 10, 257 }, { 7, 10, 2031 }, { 4, 0, 138 }, { 7, 0, 1012 }, + { 7, 0, 1280 }, { 9, 0, 76 }, { 7, 10, 1768 }, { 4, 11, 757 }, + { 5, 0, 29 }, { 12, 0, 638 }, { 7, 11, 655 }, { 7, 11, 1844 }, + { 7, 0, 1418 }, { 6, 11, 257 }, { 7, 11, 1522 }, { 8, 11, 469 }, + { 10, 11, 47 }, { 14, 11, 278 }, { 6, 10, 83 }, { 6, 10, 1733 }, + { 7, 10, 1389 }, { 11, 11, 204 }, { 11, 11, 243 }, { 12, 11, 293 }, + { 7, 11, 1875 }, { 6, 0, 1710 }, { 7, 0, 2038 }, { 9, 11, 299 }, + { 4, 0, 17 }, { 5, 0, 23 }, { 7, 0, 995 }, { 11, 0, 383 }, + { 11, 0, 437 }, { 12, 0, 460 }, { 12, 0, 532 }, { 5, 0, 862 }, + { 9, 10, 696 }, { 6, 0, 592 }, { 10, 0, 946 }, { 10, 11, 599 }, + { 7, 10, 1718 }, { 9, 10, 95 }, { 9, 10, 274 }, { 10, 10, 279 }, + { 10, 10, 317 }, { 10, 10, 420 }, { 11, 10, 303 }, { 11, 10, 808 }, + { 12, 10, 134 }, { 12, 10, 367 }, { 13, 10, 149 }, { 13, 10, 347 }, + { 14, 10, 349 }, { 14, 10, 406 }, { 18, 10, 22 }, { 18, 10, 89 }, + { 18, 10, 122 }, { 19, 10, 47 }, { 8, 0, 70 }, { 12, 0, 171 }, + { 13, 0, 272 }, { 5, 10, 26 }, { 4, 10, 550 }, { 9, 0, 812 }, + { 10, 0, 233 }, { 11, 0, 76 }, { 6, 0, 988 }, { 6, 0, 442 }, + { 8, 10, 822 }, { 7, 0, 896 }, { 4, 10, 902 }, { 5, 10, 809 }, + { 6, 10, 122 }, { 5, 11, 150 }, { 7, 11, 106 }, { 8, 11, 603 }, + { 9, 11, 593 }, { 9, 11, 634 }, { 10, 11, 44 }, { 10, 11, 173 }, + { 11, 11, 462 }, { 11, 11, 515 }, { 13, 11, 216 }, { 13, 11, 288 }, + { 14, 11, 400 }, { 8, 0, 483 }, { 7, 10, 262 }, { 6, 0, 1709 }, + { 5, 10, 620 }, { 4, 10, 34 }, { 5, 10, 574 }, { 7, 10, 279 }, + { 7, 10, 1624 }, { 8, 10, 601 }, { 9, 10, 170 }, { 19, 0, 119 }, + { 12, 11, 108 }, { 13, 11, 291 }, { 11, 0, 69 }, { 12, 0, 105 }, + { 12, 0, 117 }, { 13, 0, 213 }, { 14, 0, 13 }, { 14, 0, 62 }, + { 14, 0, 177 }, { 14, 0, 421 }, { 15, 0, 19 }, { 18, 0, 141 }, + { 9, 0, 309 }, { 11, 11, 278 }, { 14, 11, 73 }, { 7, 0, 608 }, + { 7, 0, 976 }, { 9, 0, 146 }, { 10, 0, 206 }, { 10, 0, 596 }, + { 13, 0, 218 }, { 14, 0, 153 }, { 5, 10, 332 }, { 6, 10, 261 }, + { 8, 10, 182 }, { 11, 10, 943 }, { 4, 11, 493 }, { 16, 11, 55 }, + { 6, 10, 1721 }, { 4, 0, 768 }, { 4, 10, 933 }, { 5, 10, 880 }, + { 7, 11, 555 }, { 7, 11, 1316 }, { 7, 11, 1412 }, { 7, 11, 1839 }, + { 9, 11, 192 }, { 9, 11, 589 }, { 11, 11, 241 }, { 11, 11, 676 }, + { 11, 11, 811 }, { 11, 11, 891 }, { 12, 11, 140 }, { 12, 11, 346 }, + { 12, 11, 479 }, { 13, 11, 30 }, { 13, 11, 49 }, { 13, 11, 381 }, + { 14, 11, 188 }, { 15, 11, 150 }, { 16, 11, 76 }, { 18, 11, 30 }, + { 20, 11, 52 }, { 4, 0, 518 }, { 7, 0, 1136 }, { 6, 11, 568 }, + { 7, 11, 112 }, { 7, 11, 1804 }, { 8, 11, 362 }, { 8, 11, 410 }, + { 8, 11, 830 }, { 9, 11, 514 }, { 11, 11, 649 }, { 14, 11, 157 }, + { 7, 11, 673 }, { 8, 0, 689 }, { 9, 0, 863 }, { 4, 0, 18 }, + { 7, 0, 145 }, { 7, 0, 444 }, { 7, 0, 1278 }, { 8, 0, 49 }, + { 8, 0, 400 }, { 9, 0, 71 }, { 9, 0, 250 }, { 10, 0, 459 }, + { 12, 0, 160 }, { 16, 0, 24 }, { 4, 11, 625 }, { 12, 0, 1020 }, + { 4, 0, 997 }, { 6, 0, 1946 }, { 6, 0, 1984 }, { 6, 0, 1998 }, + { 6, 11, 16 }, { 6, 11, 158 }, { 7, 11, 43 }, { 7, 11, 129 }, + { 7, 11, 181 }, { 8, 11, 276 }, { 8, 11, 377 }, { 10, 11, 523 }, + { 11, 11, 816 }, { 12, 11, 455 }, { 13, 11, 303 }, { 14, 11, 135 }, + { 5, 10, 812 }, { 6, 0, 658 }, { 4, 11, 1 }, { 7, 11, 1143 }, + { 7, 11, 1463 }, { 8, 11, 61 }, { 9, 11, 207 }, { 9, 11, 390 }, + { 9, 11, 467 }, { 11, 11, 836 }, { 22, 11, 26 }, { 12, 0, 106 }, + { 6, 0, 1827 }, { 10, 0, 931 }, { 18, 0, 166 }, { 20, 0, 114 }, + { 4, 10, 137 }, { 7, 10, 1178 }, { 7, 11, 1319 }, { 7, 10, 1520 }, + { 5, 0, 1010 }, { 4, 11, 723 }, { 5, 11, 895 }, { 7, 11, 1031 }, + { 8, 11, 199 }, { 8, 11, 340 }, { 9, 11, 153 }, { 9, 11, 215 }, + { 10, 11, 21 }, { 10, 11, 59 }, { 10, 11, 80 }, { 10, 11, 224 }, + { 11, 11, 229 }, { 11, 11, 652 }, { 12, 11, 192 }, { 13, 11, 146 }, + { 14, 11, 91 }, { 4, 11, 295 }, { 6, 11, 619 }, { 7, 11, 898 }, + { 7, 11, 1092 }, { 8, 11, 485 }, { 18, 11, 28 }, { 19, 11, 116 }, + { 9, 11, 51 }, { 6, 10, 1661 }, { 7, 10, 1975 }, { 7, 10, 2009 }, + { 7, 10, 2011 }, { 5, 11, 309 }, { 12, 11, 211 }, { 5, 0, 87 }, + { 7, 0, 313 }, { 7, 0, 1103 }, { 10, 0, 208 }, { 10, 0, 582 }, + { 11, 0, 389 }, { 11, 0, 813 }, { 12, 0, 385 }, { 13, 0, 286 }, + { 14, 0, 124 }, { 18, 0, 108 }, { 5, 11, 125 }, { 8, 11, 77 }, + { 10, 11, 15 }, { 4, 0, 267 }, { 5, 0, 703 }, { 9, 11, 155 }, + { 5, 11, 439 }, { 11, 11, 164 }, { 12, 11, 76 }, { 9, 0, 496 }, + { 5, 10, 89 }, { 7, 10, 1915 }, { 9, 10, 185 }, { 9, 10, 235 }, + { 10, 10, 64 }, { 10, 10, 270 }, { 10, 10, 403 }, { 10, 10, 469 }, + { 10, 10, 529 }, { 10, 10, 590 }, { 11, 10, 140 }, { 11, 10, 860 }, + { 13, 10, 1 }, { 13, 10, 422 }, { 14, 10, 341 }, { 14, 10, 364 }, + { 17, 10, 93 }, { 18, 10, 113 }, { 19, 10, 97 }, { 19, 10, 113 }, + { 5, 10, 695 }, { 7, 0, 1121 }, { 5, 10, 6 }, { 6, 10, 183 }, + { 7, 10, 680 }, { 7, 10, 978 }, { 7, 10, 1013 }, { 7, 10, 1055 }, + { 12, 10, 230 }, { 13, 10, 172 }, { 18, 10, 29 }, { 4, 11, 8 }, + { 7, 11, 1152 }, { 7, 11, 1153 }, { 7, 11, 1715 }, { 9, 11, 374 }, + { 10, 11, 478 }, { 11, 11, 648 }, { 7, 11, 1099 }, { 6, 10, 29 }, + { 11, 10, 63 }, { 4, 0, 561 }, { 10, 0, 249 }, { 11, 0, 209 }, + { 4, 0, 760 }, { 7, 11, 799 }, { 10, 11, 511 }, { 8, 11, 87 }, + { 9, 0, 154 }, { 12, 0, 485 }, { 8, 0, 255 }, { 4, 0, 323 }, + { 12, 0, 419 }, { 4, 10, 311 }, { 6, 10, 1740 }, { 4, 0, 368 }, + { 7, 0, 641 }, { 7, 10, 170 }, { 8, 10, 90 }, { 8, 10, 177 }, + { 8, 10, 415 }, { 11, 10, 714 }, { 14, 10, 281 }, { 4, 11, 69 }, + { 5, 11, 122 }, { 9, 11, 656 }, { 10, 11, 464 }, { 5, 11, 849 }, + { 6, 11, 1633 }, { 8, 0, 522 }, { 14, 0, 328 }, { 11, 10, 91 }, + { 13, 10, 129 }, { 15, 10, 101 }, { 17, 10, 125 }, { 7, 0, 562 }, + { 8, 0, 551 }, { 4, 10, 494 }, { 6, 10, 74 }, { 7, 10, 44 }, + { 11, 11, 499 }, { 12, 10, 17 }, { 15, 10, 5 }, { 20, 10, 11 }, + { 4, 10, 276 }, { 5, 10, 296 }, { 9, 0, 92 }, { 19, 0, 91 }, + { 4, 10, 7 }, { 5, 10, 90 }, { 5, 10, 158 }, { 6, 10, 542 }, + { 7, 10, 221 }, { 7, 10, 1574 }, { 9, 10, 490 }, { 10, 10, 540 }, + { 11, 10, 443 }, { 11, 10, 757 }, { 6, 0, 525 }, { 6, 0, 1976 }, + { 8, 0, 806 }, { 9, 0, 876 }, { 12, 0, 284 }, { 5, 11, 859 }, + { 7, 10, 588 }, { 7, 11, 1160 }, { 8, 11, 107 }, { 9, 10, 175 }, + { 9, 11, 291 }, { 9, 11, 439 }, { 10, 10, 530 }, { 10, 11, 663 }, + { 11, 11, 609 }, { 12, 11, 197 }, { 7, 11, 168 }, { 13, 11, 196 }, + { 13, 11, 237 }, { 11, 0, 958 }, { 5, 0, 594 }, { 7, 10, 580 }, + { 7, 10, 88 }, { 8, 10, 627 }, { 6, 0, 479 }, { 6, 0, 562 }, + { 7, 0, 1060 }, { 13, 0, 6 }, { 5, 10, 872 }, { 6, 10, 57 }, + { 7, 10, 471 }, { 9, 10, 447 }, { 9, 10, 454 }, { 8, 11, 413 }, + { 17, 11, 19 }, { 4, 11, 117 }, { 6, 11, 372 }, { 7, 11, 1905 }, + { 14, 11, 323 }, { 4, 11, 722 }, { 11, 11, 471 }, { 17, 0, 61 }, + { 5, 10, 31 }, { 6, 10, 614 }, { 8, 10, 330 }, { 12, 10, 477 }, + { 7, 10, 1200 }, { 10, 10, 460 }, { 6, 10, 424 }, { 7, 10, 1866 }, + { 6, 0, 1641 }, { 8, 0, 820 }, { 6, 0, 1556 }, { 6, 0, 1618 }, + { 9, 11, 5 }, { 12, 11, 216 }, { 12, 11, 294 }, { 12, 11, 298 }, + { 12, 11, 400 }, { 12, 11, 518 }, { 13, 11, 229 }, { 15, 11, 139 }, + { 15, 11, 155 }, { 16, 11, 79 }, { 4, 0, 302 }, { 7, 0, 1766 }, + { 5, 10, 13 }, { 6, 10, 142 }, { 6, 0, 148 }, { 7, 0, 1313 }, + { 7, 10, 116 }, { 8, 10, 322 }, { 8, 10, 755 }, { 9, 10, 548 }, + { 10, 10, 714 }, { 11, 10, 884 }, { 13, 10, 324 }, { 9, 0, 676 }, + { 9, 11, 88 }, { 11, 11, 270 }, { 5, 11, 12 }, { 7, 11, 375 }, + { 9, 11, 438 }, { 6, 0, 1674 }, { 7, 10, 1472 }, { 7, 10, 1554 }, + { 11, 0, 178 }, { 7, 10, 1071 }, { 7, 10, 1541 }, { 7, 10, 1767 }, + { 7, 10, 1806 }, { 11, 10, 162 }, { 11, 10, 242 }, { 12, 10, 605 }, + { 15, 10, 26 }, { 16, 10, 44 }, { 6, 0, 389 }, { 7, 0, 149 }, + { 9, 0, 142 }, { 10, 0, 94 }, { 12, 11, 71 }, { 17, 10, 115 }, + { 6, 0, 8 }, { 7, 0, 1881 }, { 8, 0, 91 }, { 11, 11, 966 }, + { 12, 11, 287 }, { 13, 11, 342 }, { 13, 11, 402 }, { 15, 11, 110 }, + { 15, 11, 163 }, { 4, 11, 258 }, { 8, 11, 639 }, { 6, 11, 22 }, + { 7, 11, 903 }, { 10, 11, 577 }, { 5, 11, 681 }, { 7, 10, 1111 }, + { 7, 11, 1286 }, { 9, 0, 112 }, { 8, 10, 1 }, { 10, 10, 326 }, + { 5, 10, 488 }, { 6, 10, 527 }, { 7, 10, 489 }, { 7, 10, 1636 }, + { 8, 10, 121 }, { 8, 10, 144 }, { 8, 10, 359 }, { 9, 10, 193 }, + { 9, 10, 241 }, { 9, 10, 336 }, { 9, 10, 882 }, { 11, 10, 266 }, + { 11, 10, 372 }, { 11, 10, 944 }, { 12, 10, 401 }, { 12, 10, 641 }, + { 4, 11, 664 }, { 5, 11, 804 }, { 6, 0, 747 }, { 6, 0, 1015 }, + { 7, 0, 1746 }, { 9, 10, 31 }, { 10, 10, 244 }, { 10, 10, 699 }, + { 12, 10, 149 }, { 13, 10, 497 }, { 5, 10, 377 }, { 7, 0, 24 }, + { 6, 0, 1352 }, { 5, 11, 32 }, { 17, 10, 101 }, { 7, 0, 1530 }, + { 10, 0, 158 }, { 13, 0, 13 }, { 13, 0, 137 }, { 13, 0, 258 }, + { 14, 0, 111 }, { 14, 0, 225 }, { 14, 0, 253 }, { 14, 0, 304 }, + { 14, 0, 339 }, { 14, 0, 417 }, { 18, 0, 33 }, { 4, 0, 503 }, + { 7, 0, 1661 }, { 5, 0, 130 }, { 6, 0, 845 }, { 7, 0, 1314 }, + { 9, 0, 610 }, { 10, 0, 718 }, { 11, 0, 601 }, { 11, 0, 819 }, + { 11, 0, 946 }, { 12, 0, 536 }, { 10, 0, 149 }, { 11, 0, 280 }, + { 14, 0, 336 }, { 6, 0, 1401 }, { 7, 0, 1946 }, { 8, 0, 663 }, + { 16, 0, 8 }, { 6, 0, 1607 }, { 7, 10, 2023 }, { 4, 11, 289 }, + { 7, 11, 629 }, { 7, 11, 1698 }, { 7, 11, 1711 }, { 12, 11, 215 }, + { 6, 11, 450 }, { 8, 11, 109 }, { 10, 0, 882 }, { 10, 0, 883 }, + { 10, 0, 914 }, { 10, 0, 928 }, { 5, 10, 843 }, { 8, 11, 705 }, + { 4, 10, 554 }, { 5, 10, 536 }, { 5, 0, 417 }, { 9, 10, 79 }, + { 11, 10, 625 }, { 17, 10, 7 }, { 7, 11, 1238 }, { 14, 11, 37 }, + { 4, 0, 392 }, { 7, 0, 1597 }, { 5, 0, 433 }, { 9, 0, 633 }, + { 11, 0, 629 }, { 4, 10, 424 }, { 7, 10, 336 }, { 8, 10, 785 }, + { 6, 11, 355 }, { 6, 0, 234 }, { 7, 0, 769 }, { 9, 0, 18 }, + { 10, 0, 358 }, { 4, 10, 896 }, { 6, 10, 1777 }, { 10, 11, 323 }, + { 7, 0, 140 }, { 7, 0, 1950 }, { 8, 0, 680 }, { 11, 0, 817 }, + { 19, 0, 88 }, { 7, 0, 1222 }, { 10, 0, 386 }, { 11, 11, 908 }, + { 11, 0, 249 }, { 12, 0, 313 }, { 16, 0, 66 }, { 17, 0, 26 }, + { 6, 0, 5 }, { 7, 10, 750 }, { 9, 10, 223 }, { 11, 10, 27 }, + { 11, 10, 466 }, { 12, 10, 624 }, { 14, 10, 265 }, { 18, 10, 61 }, + { 6, 11, 26 }, { 6, 0, 1216 }, { 5, 0, 963 }, { 6, 0, 1773 }, + { 4, 11, 414 }, { 5, 11, 467 }, { 9, 11, 654 }, { 10, 11, 451 }, + { 12, 11, 59 }, { 13, 11, 375 }, { 7, 11, 17 }, { 4, 10, 603 }, + { 5, 10, 661 }, { 4, 10, 11 }, { 6, 10, 128 }, { 7, 10, 231 }, + { 7, 10, 1533 }, { 10, 10, 725 }, { 7, 11, 955 }, { 7, 0, 180 }, + { 8, 0, 509 }, { 8, 0, 792 }, { 4, 10, 476 }, { 4, 0, 1002 }, + { 5, 11, 538 }, { 7, 10, 1807 }, { 4, 0, 931 }, { 7, 0, 943 }, + { 11, 0, 614 }, { 12, 0, 747 }, { 7, 0, 1837 }, { 9, 10, 20 }, + { 10, 10, 324 }, { 10, 10, 807 }, { 11, 10, 488 }, { 6, 0, 641 }, + { 6, 11, 280 }, { 10, 11, 502 }, { 11, 11, 344 }, { 12, 11, 38 }, + { 5, 11, 45 }, { 7, 11, 1161 }, { 11, 11, 448 }, { 11, 11, 880 }, + { 13, 11, 139 }, { 13, 11, 407 }, { 15, 11, 16 }, { 17, 11, 95 }, + { 18, 11, 66 }, { 18, 11, 88 }, { 18, 11, 123 }, { 21, 11, 7 }, + { 9, 0, 280 }, { 10, 0, 134 }, { 22, 0, 22 }, { 23, 0, 5 }, + { 23, 0, 29 }, { 8, 11, 777 }, { 4, 0, 90 }, { 5, 0, 545 }, + { 7, 0, 754 }, { 9, 0, 186 }, { 10, 0, 72 }, { 10, 0, 782 }, + { 11, 0, 577 }, { 11, 0, 610 }, { 11, 0, 960 }, { 12, 0, 354 }, + { 12, 0, 362 }, { 12, 0, 595 }, { 4, 11, 410 }, { 7, 11, 521 }, + { 7, 11, 1778 }, { 5, 10, 112 }, { 6, 10, 103 }, { 6, 10, 150 }, + { 10, 10, 356 }, { 4, 0, 742 }, { 7, 0, 151 }, { 9, 0, 329 }, + { 11, 0, 254 }, { 8, 0, 853 }, { 8, 0, 881 }, { 8, 0, 911 }, + { 8, 0, 912 }, { 10, 0, 872 }, { 12, 0, 741 }, { 12, 0, 742 }, + { 24, 0, 18 }, { 4, 11, 573 }, { 8, 11, 655 }, { 6, 0, 921 }, + { 6, 0, 934 }, { 9, 0, 187 }, { 10, 0, 36 }, { 11, 0, 1016 }, + { 17, 0, 44 }, { 18, 0, 64 }, { 7, 0, 833 }, { 8, 0, 517 }, + { 4, 0, 506 }, { 5, 0, 295 }, { 7, 0, 1680 }, { 4, 10, 708 }, + { 8, 10, 15 }, { 9, 10, 50 }, { 9, 10, 386 }, { 11, 10, 18 }, + { 11, 10, 529 }, { 12, 10, 228 }, { 7, 0, 251 }, { 7, 0, 1701 }, + { 8, 0, 436 }, { 4, 10, 563 }, { 7, 10, 592 }, { 7, 10, 637 }, + { 7, 10, 770 }, { 8, 10, 463 }, { 9, 10, 60 }, { 9, 10, 335 }, + { 9, 10, 904 }, { 10, 10, 73 }, { 11, 10, 434 }, { 12, 10, 585 }, + { 13, 10, 331 }, { 18, 10, 110 }, { 20, 10, 60 }, { 4, 10, 502 }, + { 8, 0, 584 }, { 6, 10, 347 }, { 10, 10, 161 }, { 7, 0, 987 }, + { 9, 0, 688 }, { 10, 0, 522 }, { 11, 0, 788 }, { 12, 0, 137 }, + { 12, 0, 566 }, { 14, 0, 9 }, { 14, 0, 24 }, { 14, 0, 64 }, + { 7, 11, 899 }, { 14, 11, 325 }, { 4, 0, 214 }, { 5, 0, 500 }, + { 5, 10, 102 }, { 6, 10, 284 }, { 7, 10, 1079 }, { 7, 10, 1423 }, + { 7, 10, 1702 }, { 8, 10, 470 }, { 9, 10, 554 }, { 9, 10, 723 }, + { 11, 10, 333 }, { 7, 10, 246 }, { 7, 10, 840 }, { 6, 10, 10 }, + { 8, 10, 571 }, { 9, 10, 739 }, { 15, 10, 91 }, { 5, 10, 626 }, + { 18, 0, 195 }, { 6, 0, 1775 }, { 7, 0, 389 }, { 7, 0, 700 }, + { 7, 0, 940 }, { 8, 0, 514 }, { 9, 0, 116 }, { 9, 0, 535 }, + { 10, 0, 118 }, { 11, 0, 107 }, { 11, 0, 148 }, { 11, 0, 922 }, + { 12, 0, 254 }, { 12, 0, 421 }, { 14, 0, 238 }, { 5, 10, 18 }, + { 6, 10, 526 }, { 13, 10, 24 }, { 13, 10, 110 }, { 19, 10, 5 }, + { 19, 10, 44 }, { 4, 0, 743 }, { 11, 0, 292 }, { 4, 10, 309 }, + { 5, 10, 462 }, { 7, 10, 970 }, { 7, 10, 1097 }, { 22, 10, 30 }, + { 22, 10, 33 }, { 11, 11, 338 }, { 7, 11, 1598 }, { 7, 0, 1283 }, + { 9, 0, 227 }, { 11, 0, 325 }, { 11, 0, 408 }, { 14, 0, 180 }, + { 18, 0, 47 }, { 4, 0, 953 }, { 6, 0, 1805 }, { 6, 0, 1814 }, + { 6, 0, 1862 }, { 12, 0, 774 }, { 6, 11, 611 }, { 7, 11, 1733 }, + { 7, 11, 1464 }, { 5, 0, 81 }, { 7, 0, 146 }, { 7, 0, 1342 }, + { 8, 0, 53 }, { 8, 0, 561 }, { 8, 0, 694 }, { 8, 0, 754 }, + { 9, 0, 115 }, { 9, 0, 179 }, { 9, 0, 894 }, { 10, 0, 462 }, + { 10, 0, 813 }, { 11, 0, 230 }, { 11, 0, 657 }, { 11, 0, 699 }, + { 11, 0, 748 }, { 12, 0, 119 }, { 12, 0, 200 }, { 12, 0, 283 }, + { 14, 0, 273 }, { 5, 0, 408 }, { 6, 0, 789 }, { 6, 0, 877 }, + { 6, 0, 1253 }, { 6, 0, 1413 }, { 9, 0, 747 }, { 6, 10, 1704 }, + { 7, 11, 663 }, { 6, 0, 1910 }, { 6, 0, 1915 }, { 6, 0, 1923 }, + { 9, 0, 913 }, { 9, 0, 928 }, { 9, 0, 950 }, { 9, 0, 954 }, + { 9, 0, 978 }, { 9, 0, 993 }, { 12, 0, 812 }, { 12, 0, 819 }, + { 12, 0, 831 }, { 12, 0, 833 }, { 12, 0, 838 }, { 12, 0, 909 }, + { 12, 0, 928 }, { 12, 0, 931 }, { 12, 0, 950 }, { 15, 0, 186 }, + { 15, 0, 187 }, { 15, 0, 195 }, { 15, 0, 196 }, { 15, 0, 209 }, + { 15, 0, 215 }, { 15, 0, 236 }, { 15, 0, 241 }, { 15, 0, 249 }, + { 15, 0, 253 }, { 18, 0, 180 }, { 18, 0, 221 }, { 18, 0, 224 }, + { 18, 0, 227 }, { 18, 0, 229 }, { 21, 0, 60 }, { 7, 0, 1826 }, + { 7, 0, 1938 }, { 11, 0, 490 }, { 18, 0, 143 }, { 5, 10, 86 }, + { 7, 10, 743 }, { 9, 10, 85 }, { 10, 10, 281 }, { 10, 10, 432 }, + { 12, 10, 251 }, { 13, 10, 118 }, { 14, 10, 378 }, { 5, 10, 524 }, + { 5, 10, 744 }, { 13, 11, 442 }, { 10, 10, 107 }, { 12, 10, 436 }, + { 7, 11, 503 }, { 6, 0, 1162 }, { 4, 10, 927 }, { 7, 0, 30 }, + { 8, 0, 86 }, { 8, 0, 315 }, { 8, 0, 700 }, { 9, 0, 576 }, + { 9, 0, 858 }, { 10, 0, 414 }, { 11, 0, 310 }, { 11, 0, 888 }, + { 11, 0, 904 }, { 12, 0, 361 }, { 13, 0, 248 }, { 13, 0, 371 }, + { 14, 0, 142 }, { 12, 10, 670 }, { 18, 10, 94 }, { 6, 0, 721 }, + { 4, 11, 113 }, { 5, 11, 163 }, { 5, 11, 735 }, { 7, 11, 1009 }, + { 7, 10, 1149 }, { 9, 11, 9 }, { 9, 10, 156 }, { 9, 11, 771 }, + { 12, 11, 90 }, { 13, 11, 138 }, { 13, 11, 410 }, { 15, 11, 128 }, + { 10, 0, 839 }, { 5, 10, 778 }, { 9, 0, 617 }, { 5, 10, 502 }, + { 8, 10, 196 }, { 10, 10, 283 }, { 11, 10, 406 }, { 6, 0, 428 }, + { 7, 0, 524 }, { 8, 0, 169 }, { 8, 0, 234 }, { 9, 0, 480 }, + { 10, 0, 646 }, { 5, 10, 855 }, { 6, 0, 1648 }, { 7, 0, 1205 }, + { 10, 0, 637 }, { 7, 0, 1596 }, { 4, 11, 935 }, { 5, 11, 823 }, + { 5, 11, 269 }, { 7, 11, 434 }, { 7, 11, 891 }, { 8, 11, 339 }, + { 9, 11, 702 }, { 11, 11, 594 }, { 11, 11, 718 }, { 17, 11, 100 }, + { 7, 11, 878 }, { 9, 11, 485 }, { 13, 11, 264 }, { 4, 0, 266 }, + { 8, 0, 4 }, { 9, 0, 39 }, { 10, 0, 166 }, { 11, 0, 918 }, + { 12, 0, 635 }, { 20, 0, 10 }, { 22, 0, 27 }, { 22, 0, 43 }, + { 22, 0, 52 }, { 6, 11, 1713 }, { 7, 10, 1400 }, { 9, 10, 446 }, + { 10, 10, 45 }, { 7, 11, 900 }, { 4, 0, 862 }, { 6, 0, 1554 }, + { 7, 11, 1033 }, { 19, 0, 16 }, { 19, 11, 16 }, { 7, 11, 1208 }, + { 7, 0, 157 }, { 8, 0, 279 }, { 6, 0, 604 }, { 8, 0, 391 }, + { 13, 10, 455 }, { 15, 10, 99 }, { 15, 10, 129 }, { 16, 10, 68 }, + { 7, 10, 172 }, { 7, 0, 945 }, { 11, 0, 713 }, { 11, 0, 744 }, + { 4, 0, 973 }, { 10, 0, 877 }, { 10, 0, 937 }, { 10, 0, 938 }, + { 12, 0, 711 }, { 11, 0, 1022 }, { 4, 10, 568 }, { 14, 11, 143 }, + { 4, 0, 567 }, { 9, 0, 859 }, { 4, 10, 732 }, { 7, 0, 1846 }, + { 8, 0, 628 }, { 8, 10, 733 }, { 5, 0, 762 }, { 4, 10, 428 }, + { 7, 10, 1789 }, { 10, 0, 784 }, { 13, 0, 191 }, { 7, 10, 2015 }, + { 12, 10, 665 }, { 5, 0, 298 }, { 7, 0, 633 }, { 7, 0, 905 }, + { 7, 0, 909 }, { 7, 0, 1538 }, { 9, 0, 767 }, { 12, 0, 636 }, + { 10, 10, 806 }, { 4, 0, 795 }, { 11, 0, 301 }, { 7, 0, 1970 }, + { 5, 11, 625 }, { 7, 11, 1617 }, { 7, 11, 275 }, { 7, 11, 37 }, + { 8, 11, 425 }, { 8, 11, 693 }, { 9, 11, 720 }, { 10, 11, 380 }, + { 10, 11, 638 }, { 11, 11, 273 }, { 11, 11, 307 }, { 11, 11, 473 }, + { 12, 11, 61 }, { 15, 11, 43 }, { 7, 11, 198 }, { 6, 0, 1236 }, + { 7, 0, 369 }, { 12, 0, 644 }, { 12, 0, 645 }, { 16, 0, 90 }, + { 19, 0, 15 }, { 21, 0, 27 }, { 6, 0, 71 }, { 7, 0, 845 }, + { 8, 0, 160 }, { 9, 0, 318 }, { 6, 10, 1623 }, { 6, 10, 1681 }, + { 6, 0, 1447 }, { 6, 0, 1255 }, { 10, 0, 735 }, { 8, 0, 76 }, + { 4, 11, 168 }, { 6, 10, 1748 }, { 8, 10, 715 }, { 9, 10, 802 }, + { 10, 10, 46 }, { 10, 10, 819 }, { 13, 10, 308 }, { 14, 10, 351 }, + { 14, 10, 363 }, { 18, 10, 67 }, { 7, 11, 91 }, { 6, 0, 474 }, + { 4, 10, 63 }, { 5, 10, 347 }, { 5, 10, 749 }, { 10, 0, 841 }, + { 5, 10, 366 }, { 6, 0, 836 }, { 4, 11, 225 }, { 7, 0, 1622 }, + { 7, 10, 89 }, { 12, 0, 735 }, { 6, 0, 1601 }, { 10, 11, 145 }, + { 6, 0, 1390 }, { 9, 0, 804 }, { 14, 0, 394 }, { 6, 11, 15 }, + { 7, 11, 70 }, { 10, 11, 240 }, { 19, 11, 93 }, { 6, 0, 96 }, + { 7, 0, 1426 }, { 4, 0, 651 }, { 5, 0, 289 }, { 7, 11, 956 }, + { 7, 10, 977 }, { 7, 11, 1157 }, { 7, 11, 1506 }, { 7, 11, 1606 }, + { 7, 11, 1615 }, { 7, 11, 1619 }, { 7, 11, 1736 }, { 7, 11, 1775 }, + { 8, 11, 590 }, { 9, 11, 324 }, { 9, 11, 736 }, { 9, 11, 774 }, + { 9, 11, 776 }, { 9, 11, 784 }, { 10, 11, 567 }, { 10, 11, 708 }, + { 11, 11, 518 }, { 11, 11, 613 }, { 11, 11, 695 }, { 11, 11, 716 }, + { 11, 11, 739 }, { 11, 11, 770 }, { 11, 11, 771 }, { 11, 11, 848 }, + { 11, 11, 857 }, { 11, 11, 931 }, { 11, 11, 947 }, { 12, 11, 326 }, + { 12, 11, 387 }, { 12, 11, 484 }, { 12, 11, 528 }, { 12, 11, 552 }, + { 12, 11, 613 }, { 13, 11, 189 }, { 13, 11, 256 }, { 13, 11, 340 }, + { 13, 11, 432 }, { 13, 11, 436 }, { 13, 11, 440 }, { 13, 11, 454 }, + { 14, 11, 174 }, { 14, 11, 220 }, { 14, 11, 284 }, { 14, 11, 390 }, + { 17, 11, 121 }, { 7, 0, 688 }, { 8, 0, 35 }, { 9, 0, 511 }, + { 10, 0, 767 }, { 19, 0, 118 }, { 6, 0, 667 }, { 4, 0, 513 }, + { 5, 10, 824 }, { 5, 10, 941 }, { 7, 10, 440 }, { 8, 10, 230 }, + { 11, 10, 106 }, { 6, 0, 2034 }, { 7, 11, 1399 }, { 15, 11, 66 }, + { 7, 11, 1529 }, { 4, 11, 145 }, { 6, 11, 176 }, { 7, 11, 395 }, + { 9, 11, 562 }, { 16, 11, 28 }, { 4, 11, 501 }, { 4, 0, 704 }, + { 6, 0, 1524 }, { 7, 0, 1078 }, { 6, 11, 464 }, { 6, 11, 509 }, + { 10, 11, 82 }, { 20, 11, 91 }, { 23, 11, 13 }, { 4, 0, 720 }, + { 5, 0, 306 }, { 5, 0, 431 }, { 7, 0, 1196 }, { 4, 10, 914 }, + { 5, 10, 800 }, { 5, 10, 852 }, { 7, 11, 1189 }, { 10, 0, 54 }, + { 13, 10, 115 }, { 7, 10, 564 }, { 14, 10, 168 }, { 5, 0, 464 }, + { 6, 0, 236 }, { 7, 0, 696 }, { 7, 0, 914 }, { 7, 0, 1108 }, + { 7, 0, 1448 }, { 9, 0, 15 }, { 9, 0, 564 }, { 10, 0, 14 }, + { 12, 0, 565 }, { 13, 0, 449 }, { 14, 0, 53 }, { 15, 0, 13 }, + { 16, 0, 64 }, { 17, 0, 41 }, { 4, 10, 918 }, { 5, 10, 876 }, + { 6, 0, 1418 }, { 6, 10, 1764 }, { 4, 10, 92 }, { 5, 10, 274 }, + { 6, 0, 907 }, { 4, 11, 114 }, { 8, 10, 501 }, { 9, 11, 492 }, + { 13, 11, 462 }, { 14, 11, 215 }, { 4, 11, 77 }, { 5, 11, 361 }, + { 6, 11, 139 }, { 6, 11, 401 }, { 6, 11, 404 }, { 7, 11, 413 }, + { 7, 11, 715 }, { 7, 11, 1716 }, { 11, 11, 279 }, { 12, 11, 179 }, + { 12, 11, 258 }, { 13, 11, 244 }, { 14, 11, 358 }, { 6, 0, 1767 }, + { 12, 0, 194 }, { 17, 0, 107 }, { 6, 11, 1717 }, { 5, 10, 743 }, + { 14, 11, 329 }, { 4, 10, 49 }, { 7, 10, 280 }, { 7, 10, 1633 }, + { 5, 0, 840 }, { 7, 11, 1061 }, { 8, 11, 82 }, { 11, 11, 250 }, + { 12, 11, 420 }, { 13, 11, 184 }, { 7, 11, 724 }, { 6, 0, 900 }, + { 8, 10, 47 }, { 6, 0, 1436 }, { 16, 11, 0 }, { 6, 0, 675 }, + { 7, 0, 1008 }, { 7, 0, 1560 }, { 9, 0, 642 }, { 11, 0, 236 }, + { 14, 0, 193 }, { 5, 10, 272 }, { 5, 10, 908 }, { 5, 10, 942 }, + { 8, 10, 197 }, { 9, 10, 47 }, { 11, 10, 538 }, { 11, 10, 742 }, + { 4, 0, 68 }, { 5, 0, 628 }, { 5, 0, 634 }, { 6, 0, 386 }, + { 7, 0, 794 }, { 8, 0, 273 }, { 9, 0, 563 }, { 10, 0, 105 }, + { 10, 0, 171 }, { 11, 0, 94 }, { 11, 0, 354 }, { 7, 10, 1911 }, + { 9, 10, 891 }, { 4, 0, 95 }, { 6, 0, 1297 }, { 6, 0, 1604 }, + { 7, 0, 416 }, { 11, 0, 830 }, { 6, 11, 513 }, { 7, 11, 1052 }, + { 7, 0, 731 }, { 13, 0, 20 }, { 15, 0, 11 }, { 9, 11, 899 }, + { 10, 0, 850 }, { 12, 0, 697 }, { 4, 0, 662 }, { 7, 11, 1417 }, + { 12, 11, 382 }, { 17, 11, 48 }, { 24, 11, 12 }, { 5, 0, 736 }, + { 4, 0, 861 }, { 4, 10, 407 }, { 4, 10, 560 }, { 13, 10, 490 }, + { 6, 11, 545 }, { 7, 11, 565 }, { 7, 11, 1669 }, { 10, 11, 114 }, + { 11, 11, 642 }, { 12, 11, 618 }, { 6, 0, 871 }, { 6, 0, 1000 }, + { 5, 0, 864 }, { 10, 0, 648 }, { 11, 0, 671 }, { 15, 0, 46 }, + { 5, 11, 5 }, { 5, 0, 928 }, { 11, 0, 90 }, { 13, 0, 7 }, + { 4, 10, 475 }, { 11, 10, 35 }, { 13, 10, 71 }, { 13, 10, 177 }, + { 14, 10, 422 }, { 8, 0, 332 }, { 7, 11, 192 }, { 6, 0, 1055 }, + { 8, 11, 763 }, { 11, 0, 986 }, { 12, 0, 682 }, { 7, 0, 76 }, + { 8, 0, 44 }, { 9, 0, 884 }, { 10, 0, 580 }, { 11, 0, 399 }, + { 11, 0, 894 }, { 15, 0, 122 }, { 7, 11, 1237 }, { 7, 10, 636 }, + { 11, 0, 300 }, { 6, 10, 222 }, { 7, 10, 1620 }, { 8, 10, 409 }, + { 9, 10, 693 }, { 4, 11, 87 }, { 5, 11, 250 }, { 10, 11, 601 }, + { 13, 11, 298 }, { 13, 11, 353 }, { 13, 11, 376 }, { 5, 0, 518 }, + { 10, 0, 340 }, { 11, 0, 175 }, { 21, 0, 16 }, { 12, 0, 771 }, + { 6, 0, 1108 }, { 9, 0, 831 }, { 4, 0, 836 }, { 7, 0, 1852 }, + { 4, 0, 957 }, { 6, 0, 1804 }, { 8, 0, 842 }, { 8, 0, 843 }, + { 8, 0, 851 }, { 8, 0, 855 }, { 12, 0, 767 }, { 7, 11, 814 }, + { 4, 11, 57 }, { 7, 11, 1195 }, { 7, 11, 1438 }, { 7, 11, 1548 }, + { 7, 11, 1835 }, { 7, 11, 1904 }, { 9, 11, 757 }, { 10, 11, 604 }, + { 11, 11, 519 }, { 5, 10, 882 }, { 10, 0, 246 }, { 4, 0, 934 }, + { 5, 0, 202 }, { 8, 0, 610 }, { 7, 11, 1897 }, { 12, 11, 290 }, + { 13, 11, 80 }, { 13, 11, 437 }, { 17, 11, 74 }, { 8, 0, 96 }, + { 9, 0, 36 }, { 10, 0, 607 }, { 10, 0, 804 }, { 10, 0, 832 }, + { 11, 0, 423 }, { 11, 0, 442 }, { 12, 0, 309 }, { 14, 0, 199 }, + { 15, 0, 90 }, { 17, 0, 110 }, { 4, 10, 426 }, { 7, 0, 654 }, + { 8, 0, 240 }, { 6, 10, 58 }, { 7, 10, 745 }, { 7, 10, 1969 }, + { 8, 10, 675 }, { 9, 10, 479 }, { 9, 10, 731 }, { 10, 10, 330 }, + { 10, 10, 593 }, { 10, 10, 817 }, { 11, 10, 32 }, { 11, 10, 133 }, + { 11, 10, 221 }, { 17, 10, 68 }, { 9, 0, 13 }, { 9, 0, 398 }, + { 9, 0, 727 }, { 10, 0, 75 }, { 10, 0, 184 }, { 10, 0, 230 }, + { 10, 0, 564 }, { 10, 0, 569 }, { 11, 0, 973 }, { 12, 0, 70 }, + { 12, 0, 189 }, { 13, 0, 57 }, { 13, 0, 257 }, { 4, 11, 209 }, + { 7, 11, 902 }, { 7, 0, 391 }, { 9, 10, 538 }, { 6, 0, 403 }, + { 6, 11, 303 }, { 7, 11, 335 }, { 7, 11, 1437 }, { 7, 11, 1668 }, + { 8, 11, 553 }, { 8, 11, 652 }, { 8, 11, 656 }, { 9, 11, 558 }, + { 11, 11, 743 }, { 21, 11, 18 }, { 4, 11, 559 }, { 11, 0, 75 }, + { 14, 0, 267 }, { 6, 0, 815 }, { 13, 11, 2 }, { 13, 0, 366 }, + { 9, 0, 631 }, { 5, 11, 1017 }, { 5, 0, 345 }, { 7, 0, 1016 }, + { 5, 11, 709 }, { 6, 11, 1745 }, { 5, 10, 566 }, { 7, 0, 952 }, + { 6, 10, 48 }, { 9, 10, 139 }, { 10, 10, 399 }, { 11, 10, 469 }, + { 12, 10, 634 }, { 13, 10, 223 }, { 5, 0, 673 }, { 9, 0, 850 }, + { 7, 11, 8 }, { 8, 11, 206 }, { 6, 0, 662 }, { 21, 0, 35 }, + { 4, 0, 287 }, { 5, 0, 1018 }, { 6, 10, 114 }, { 7, 10, 1224 }, + { 7, 10, 1556 }, { 8, 10, 3 }, { 8, 10, 576 }, { 9, 10, 267 }, + { 4, 0, 884 }, { 5, 0, 34 }, { 10, 0, 724 }, { 12, 0, 444 }, + { 13, 0, 354 }, { 18, 0, 32 }, { 23, 0, 24 }, { 23, 0, 31 }, + { 24, 0, 5 }, { 5, 10, 933 }, { 4, 11, 776 }, { 10, 0, 151 }, + { 8, 0, 427 }, { 6, 0, 382 }, { 4, 0, 329 }, { 9, 0, 846 }, + { 10, 0, 827 }, { 10, 11, 33 }, { 9, 0, 279 }, { 10, 0, 407 }, + { 14, 0, 84 }, { 22, 0, 18 }, { 7, 11, 1297 }, { 8, 11, 406 }, + { 4, 0, 906 }, { 8, 0, 366 }, { 6, 0, 843 }, { 6, 0, 1443 }, + { 7, 0, 1372 }, { 10, 0, 992 }, { 4, 0, 123 }, { 5, 0, 605 }, + { 7, 0, 1509 }, { 8, 0, 36 }, { 4, 0, 649 }, { 8, 11, 175 }, + { 10, 11, 168 }, { 10, 11, 573 }, { 5, 0, 767 }, { 6, 0, 1018 }, + { 7, 11, 1305 }, { 12, 10, 30 }, { 13, 10, 148 }, { 14, 10, 87 }, + { 14, 10, 182 }, { 16, 10, 42 }, { 20, 10, 70 }, { 6, 11, 607 }, + { 4, 0, 273 }, { 5, 0, 658 }, { 5, 0, 995 }, { 6, 0, 72 }, + { 11, 11, 174 }, { 10, 0, 483 }, { 12, 0, 368 }, { 7, 10, 56 }, + { 7, 10, 1989 }, { 8, 10, 337 }, { 8, 10, 738 }, { 9, 10, 600 }, + { 13, 10, 447 }, { 14, 10, 92 }, { 5, 11, 784 }, { 10, 10, 666 }, + { 7, 0, 1345 }, { 11, 11, 882 }, { 6, 0, 1293 }, { 5, 0, 589 }, + { 6, 0, 1988 }, { 5, 0, 117 }, { 6, 0, 514 }, { 6, 0, 541 }, + { 7, 0, 1164 }, { 7, 0, 1436 }, { 8, 0, 220 }, { 8, 0, 648 }, + { 10, 0, 688 }, { 11, 0, 560 }, { 8, 0, 379 }, { 5, 0, 686 }, + { 7, 10, 866 }, { 7, 10, 1163 }, { 4, 10, 328 }, { 9, 11, 14 }, + { 9, 11, 441 }, { 10, 11, 306 }, { 11, 11, 9 }, { 4, 10, 101 }, + { 7, 10, 1171 }, { 5, 10, 833 }, { 8, 10, 744 }, { 5, 11, 161 }, + { 7, 11, 839 }, { 7, 11, 887 }, { 7, 0, 196 }, { 10, 0, 765 }, + { 11, 0, 347 }, { 11, 0, 552 }, { 11, 0, 790 }, { 12, 0, 263 }, + { 13, 0, 246 }, { 13, 0, 270 }, { 13, 0, 395 }, { 14, 0, 176 }, + { 14, 0, 190 }, { 14, 0, 398 }, { 14, 0, 412 }, { 15, 0, 32 }, + { 15, 0, 63 }, { 16, 0, 88 }, { 19, 0, 105 }, { 6, 10, 9 }, + { 6, 10, 397 }, { 7, 10, 53 }, { 7, 10, 1742 }, { 10, 10, 632 }, + { 11, 10, 828 }, { 12, 10, 146 }, { 5, 0, 381 }, { 7, 0, 1792 }, + { 6, 0, 1452 }, { 7, 11, 429 }, { 8, 0, 367 }, { 10, 0, 760 }, + { 14, 0, 79 }, { 20, 0, 17 }, { 24, 0, 0 }, { 7, 0, 616 }, + { 10, 0, 413 }, { 11, 10, 417 }, { 12, 10, 223 }, { 12, 10, 265 }, + { 7, 11, 1611 }, { 13, 11, 14 }, { 15, 11, 44 }, { 19, 11, 13 }, + { 20, 11, 76 }, { 7, 0, 1229 }, { 6, 0, 120 }, { 7, 0, 1188 }, + { 7, 0, 1710 }, { 8, 0, 286 }, { 9, 0, 667 }, { 11, 0, 592 }, + { 11, 0, 730 }, { 7, 11, 1814 }, { 7, 0, 1146 }, { 4, 10, 186 }, + { 5, 10, 157 }, { 8, 10, 168 }, { 10, 10, 6 }, { 4, 0, 352 }, + { 7, 0, 687 }, { 4, 0, 192 }, { 5, 0, 49 }, { 6, 0, 200 }, + { 6, 0, 293 }, { 6, 0, 1696 }, { 7, 0, 1151 }, { 5, 10, 875 }, + { 5, 10, 773 }, { 5, 10, 991 }, { 6, 10, 1635 }, { 6, 10, 1788 }, + { 7, 10, 111 }, { 8, 10, 581 }, { 6, 0, 935 }, { 6, 0, 1151 }, + { 6, 0, 1050 }, { 4, 0, 650 }, { 4, 0, 147 }, { 11, 0, 194 }, + { 12, 0, 62 }, { 12, 0, 88 }, { 11, 11, 194 }, { 12, 11, 62 }, + { 12, 11, 88 }, { 6, 0, 339 }, { 7, 0, 923 }, { 6, 10, 1747 }, + { 7, 11, 643 }, { 8, 11, 236 }, { 5, 0, 934 }, { 7, 10, 1364 }, + { 7, 10, 1907 }, { 13, 10, 158 }, { 4, 10, 659 }, { 4, 10, 404 }, + { 7, 10, 675 }, { 7, 11, 581 }, { 9, 11, 644 }, { 9, 11, 699 }, + { 13, 0, 211 }, { 14, 0, 133 }, { 14, 0, 204 }, { 15, 0, 64 }, + { 15, 0, 69 }, { 15, 0, 114 }, { 16, 0, 10 }, { 19, 0, 23 }, + { 19, 0, 35 }, { 19, 0, 39 }, { 19, 0, 51 }, { 19, 0, 71 }, + { 19, 0, 75 }, { 24, 0, 15 }, { 5, 10, 391 }, { 5, 11, 54 }, + { 7, 11, 1513 }, { 7, 0, 222 }, { 8, 0, 341 }, { 5, 10, 540 }, + { 6, 10, 1697 }, { 6, 10, 78 }, { 4, 11, 744 }, { 8, 0, 293 }, + { 9, 11, 701 }, { 7, 11, 930 }, { 10, 11, 402 }, { 10, 11, 476 }, + { 13, 11, 452 }, { 18, 11, 55 }, { 19, 11, 104 }, { 4, 0, 637 }, + { 5, 10, 460 }, { 8, 11, 50 }, { 9, 11, 624 }, { 4, 11, 572 }, + { 6, 0, 1159 }, { 4, 10, 199 }, { 11, 10, 34 }, { 6, 0, 847 }, + { 6, 10, 388 }, { 6, 11, 43 }, { 7, 11, 38 }, { 8, 11, 248 }, + { 9, 11, 504 }, { 10, 11, 513 }, { 9, 0, 683 }, { 4, 10, 511 }, + { 6, 10, 608 }, { 9, 10, 333 }, { 10, 10, 602 }, { 11, 10, 441 }, + { 11, 10, 723 }, { 11, 10, 976 }, { 12, 10, 357 }, { 9, 0, 867 }, + { 10, 0, 837 }, { 6, 0, 944 }, { 7, 11, 326 }, { 7, 0, 1809 }, + { 5, 10, 938 }, { 7, 11, 783 }, { 8, 10, 707 }, { 5, 11, 766 }, + { 5, 11, 363 }, { 6, 0, 170 }, { 7, 0, 1080 }, { 8, 0, 395 }, + { 8, 0, 487 }, { 13, 0, 147 }, { 6, 11, 258 }, { 12, 11, 409 }, + { 4, 0, 535 }, { 8, 0, 618 }, { 5, 11, 249 }, { 20, 11, 82 }, + { 6, 0, 1379 }, { 21, 11, 15 }, { 7, 0, 1625 }, { 22, 0, 23 }, + { 5, 11, 393 }, { 6, 11, 378 }, { 7, 11, 1981 }, { 9, 11, 32 }, + { 9, 11, 591 }, { 10, 11, 685 }, { 10, 11, 741 }, { 14, 11, 382 }, + { 5, 11, 788 }, { 7, 11, 1968 }, { 10, 11, 19 }, { 11, 11, 911 }, + { 7, 11, 1401 }, { 7, 11, 1476 }, { 4, 11, 61 }, { 5, 11, 58 }, + { 5, 11, 171 }, { 5, 11, 635 }, { 5, 11, 683 }, { 5, 11, 700 }, + { 6, 11, 291 }, { 6, 11, 566 }, { 7, 11, 1650 }, { 11, 11, 523 }, + { 12, 11, 273 }, { 12, 11, 303 }, { 15, 11, 39 }, { 15, 11, 111 }, + { 6, 10, 469 }, { 7, 10, 1709 }, { 10, 10, 515 }, { 4, 0, 778 }, + { 6, 11, 589 }, { 4, 0, 46 }, { 5, 0, 811 }, { 6, 0, 1679 }, + { 6, 0, 1714 }, { 7, 0, 2032 }, { 7, 0, 1458 }, { 9, 0, 407 }, + { 11, 0, 15 }, { 12, 0, 651 }, { 21, 0, 37 }, { 7, 0, 938 }, + { 4, 10, 500 }, { 6, 0, 34 }, { 7, 0, 69 }, { 7, 0, 1089 }, + { 7, 0, 1281 }, { 8, 0, 708 }, { 8, 0, 721 }, { 9, 0, 363 }, + { 20, 0, 98 }, { 10, 11, 231 }, { 19, 11, 124 }, { 7, 11, 726 }, + { 24, 11, 9 }, { 5, 10, 68 }, { 6, 10, 383 }, { 8, 11, 583 }, + { 4, 11, 917 }, { 5, 11, 1005 }, { 11, 10, 216 }, { 11, 10, 340 }, + { 7, 11, 1675 }, { 8, 0, 441 }, { 10, 0, 314 }, { 15, 0, 3 }, + { 4, 11, 919 }, { 4, 10, 337 }, { 6, 10, 353 }, { 7, 10, 1934 }, + { 8, 10, 488 }, { 9, 10, 429 }, { 7, 0, 889 }, { 7, 10, 1795 }, + { 8, 10, 259 }, { 9, 10, 135 }, { 9, 10, 177 }, { 9, 10, 860 }, + { 10, 10, 825 }, { 11, 10, 115 }, { 11, 10, 370 }, { 11, 10, 405 }, + { 11, 10, 604 }, { 12, 10, 10 }, { 12, 10, 667 }, { 12, 10, 669 }, + { 13, 10, 76 }, { 14, 10, 310 }, { 15, 10, 76 }, { 15, 10, 147 }, + { 20, 10, 23 }, { 4, 10, 15 }, { 4, 11, 255 }, { 5, 10, 22 }, + { 5, 11, 302 }, { 6, 11, 132 }, { 6, 10, 244 }, { 7, 10, 40 }, + { 7, 11, 128 }, { 7, 10, 200 }, { 7, 11, 283 }, { 7, 10, 906 }, + { 7, 10, 1199 }, { 7, 11, 1299 }, { 9, 10, 616 }, { 10, 11, 52 }, + { 10, 11, 514 }, { 10, 10, 716 }, { 11, 10, 635 }, { 11, 10, 801 }, + { 11, 11, 925 }, { 12, 10, 458 }, { 13, 11, 92 }, { 14, 11, 309 }, + { 4, 0, 462 }, { 9, 11, 173 }, { 7, 10, 1735 }, { 8, 0, 525 }, + { 5, 10, 598 }, { 7, 10, 791 }, { 8, 10, 108 }, { 9, 10, 123 }, + { 5, 0, 73 }, { 6, 0, 23 }, { 6, 0, 338 }, { 4, 0, 676 }, + { 4, 10, 683 }, { 7, 0, 725 }, { 8, 0, 498 }, { 11, 0, 268 }, + { 12, 0, 21 }, { 23, 0, 7 }, { 7, 0, 773 }, { 4, 10, 155 }, + { 7, 10, 1689 }, { 4, 0, 164 }, { 5, 0, 730 }, { 5, 10, 151 }, + { 5, 10, 741 }, { 6, 11, 210 }, { 7, 10, 498 }, { 7, 10, 870 }, + { 7, 10, 1542 }, { 12, 10, 213 }, { 14, 10, 36 }, { 14, 10, 391 }, + { 17, 10, 111 }, { 18, 10, 6 }, { 18, 10, 46 }, { 18, 10, 151 }, + { 19, 10, 36 }, { 20, 10, 32 }, { 20, 10, 56 }, { 20, 10, 69 }, + { 20, 10, 102 }, { 21, 10, 4 }, { 22, 10, 8 }, { 22, 10, 10 }, + { 22, 10, 14 }, { 22, 10, 31 }, { 4, 10, 624 }, { 7, 10, 1752 }, + { 4, 0, 583 }, { 9, 0, 936 }, { 15, 0, 214 }, { 18, 0, 199 }, + { 24, 0, 26 }, { 6, 11, 588 }, { 7, 0, 1462 }, { 11, 0, 659 }, + { 4, 11, 284 }, { 6, 11, 223 }, { 5, 0, 220 }, { 11, 0, 803 }, + { 4, 0, 544 }, { 4, 10, 492 }, { 5, 10, 451 }, { 16, 0, 98 }, + { 20, 0, 119 }, { 4, 11, 218 }, { 7, 11, 526 }, { 15, 11, 137 }, + { 7, 10, 835 }, { 4, 11, 270 }, { 5, 11, 192 }, { 6, 11, 332 }, + { 7, 11, 1322 }, { 13, 11, 9 }, { 13, 10, 70 }, { 14, 11, 104 }, + { 14, 11, 311 }, { 4, 10, 539 }, { 12, 11, 661 }, { 5, 0, 176 }, + { 6, 0, 437 }, { 6, 0, 564 }, { 11, 0, 181 }, { 13, 0, 183 }, + { 7, 0, 1192 }, { 6, 10, 113 }, { 7, 10, 436 }, { 8, 10, 718 }, + { 7, 10, 520 }, { 7, 0, 1878 }, { 12, 11, 196 }, { 7, 11, 379 }, + { 8, 11, 481 }, { 9, 11, 377 }, { 5, 11, 1003 }, { 6, 11, 149 }, + { 9, 11, 746 }, { 8, 11, 262 }, { 9, 11, 627 }, { 10, 11, 18 }, + { 11, 11, 214 }, { 11, 11, 404 }, { 11, 11, 457 }, { 11, 11, 780 }, + { 11, 11, 849 }, { 11, 11, 913 }, { 13, 11, 330 }, { 13, 11, 401 }, + { 14, 11, 200 }, { 21, 0, 26 }, { 8, 11, 304 }, { 4, 11, 142 }, + { 7, 0, 944 }, { 4, 0, 790 }, { 5, 0, 273 }, { 6, 0, 394 }, + { 6, 0, 855 }, { 4, 0, 135 }, { 6, 0, 127 }, { 7, 0, 1185 }, + { 7, 0, 1511 }, { 8, 0, 613 }, { 11, 0, 5 }, { 12, 0, 336 }, + { 12, 0, 495 }, { 12, 0, 586 }, { 12, 0, 660 }, { 12, 0, 668 }, + { 14, 0, 385 }, { 15, 0, 118 }, { 17, 0, 20 }, { 18, 0, 98 }, + { 6, 0, 230 }, { 9, 0, 752 }, { 18, 0, 109 }, { 12, 10, 610 }, + { 13, 10, 431 }, { 16, 10, 59 }, { 7, 0, 1954 }, { 7, 11, 925 }, + { 4, 11, 471 }, { 5, 11, 51 }, { 6, 11, 602 }, { 8, 11, 484 }, + { 10, 11, 195 }, { 12, 11, 159 }, { 4, 10, 307 }, { 8, 11, 688 }, + { 4, 11, 697 }, { 7, 11, 812 }, { 7, 11, 1261 }, { 7, 11, 1360 }, + { 9, 11, 632 }, { 12, 11, 352 }, { 5, 0, 162 }, { 8, 0, 68 }, + { 5, 10, 964 }, { 4, 0, 654 }, { 8, 11, 212 }, { 4, 0, 156 }, + { 7, 0, 998 }, { 7, 0, 1045 }, { 7, 0, 1860 }, { 9, 0, 48 }, + { 9, 0, 692 }, { 11, 0, 419 }, { 11, 0, 602 }, { 5, 11, 221 }, + { 4, 11, 373 }, { 5, 11, 283 }, { 6, 11, 480 }, { 7, 11, 609 }, + { 14, 11, 216 }, { 4, 0, 240 }, { 6, 11, 192 }, { 9, 11, 793 }, + { 17, 11, 55 }, { 4, 10, 75 }, { 5, 10, 180 }, { 6, 10, 500 }, + { 7, 10, 58 }, { 7, 10, 710 }, { 10, 10, 645 }, { 4, 11, 132 }, + { 5, 11, 69 }, { 5, 10, 649 }, { 7, 11, 1242 }, { 6, 10, 276 }, + { 7, 10, 282 }, { 7, 10, 879 }, { 7, 10, 924 }, { 8, 10, 459 }, + { 9, 10, 599 }, { 9, 10, 754 }, { 11, 10, 574 }, { 12, 10, 128 }, + { 12, 10, 494 }, { 13, 10, 52 }, { 13, 10, 301 }, { 15, 10, 30 }, + { 15, 10, 132 }, { 4, 10, 200 }, { 4, 11, 111 }, { 7, 11, 302 }, + { 9, 0, 197 }, { 10, 0, 300 }, { 12, 0, 473 }, { 13, 0, 90 }, + { 13, 0, 405 }, { 4, 11, 767 }, { 6, 11, 42 }, { 7, 11, 1416 }, + { 7, 11, 1590 }, { 7, 11, 2005 }, { 8, 11, 131 }, { 8, 11, 466 }, + { 9, 11, 672 }, { 13, 11, 252 }, { 20, 11, 103 }, { 8, 0, 958 }, + { 8, 0, 999 }, { 10, 0, 963 }, { 10, 0, 1001 }, { 7, 10, 1621 }, + { 7, 0, 858 }, { 4, 0, 606 }, { 9, 11, 444 }, { 6, 11, 44 }, + { 8, 11, 368 }, { 11, 11, 172 }, { 4, 11, 570 }, { 5, 11, 120 }, + { 11, 11, 624 }, { 7, 0, 1978 }, { 8, 0, 676 }, { 6, 10, 225 }, + { 9, 10, 211 }, { 7, 0, 972 }, { 11, 0, 102 }, { 8, 10, 687 }, + { 6, 11, 227 }, { 7, 11, 1589 }, { 8, 10, 58 }, { 9, 10, 724 }, + { 11, 10, 809 }, { 13, 10, 113 }, { 17, 10, 72 }, { 4, 0, 361 }, + { 5, 0, 315 }, { 4, 0, 461 }, { 6, 10, 345 }, { 7, 10, 1247 }, + { 4, 0, 472 }, { 8, 10, 767 }, { 8, 10, 803 }, { 9, 10, 301 }, + { 9, 10, 903 }, { 7, 11, 1333 }, { 7, 11, 477 }, { 7, 10, 1949 }, + { 8, 10, 674 }, { 6, 0, 905 }, { 10, 0, 747 }, { 5, 0, 155 }, + { 6, 10, 259 }, { 7, 0, 163 }, { 8, 0, 319 }, { 9, 0, 402 }, + { 10, 0, 24 }, { 10, 0, 681 }, { 11, 0, 200 }, { 12, 0, 253 }, + { 12, 0, 410 }, { 14, 0, 219 }, { 5, 0, 475 }, { 7, 0, 1780 }, + { 9, 0, 230 }, { 11, 0, 297 }, { 11, 0, 558 }, { 14, 0, 322 }, + { 19, 0, 76 }, { 6, 11, 1667 }, { 7, 11, 2036 }, { 10, 11, 600 }, + { 8, 10, 254 }, { 6, 0, 848 }, { 7, 0, 1956 }, { 6, 11, 511 }, + { 12, 11, 132 }, { 5, 11, 568 }, { 6, 11, 138 }, { 7, 11, 1293 }, + { 6, 0, 631 }, { 9, 0, 838 }, { 21, 0, 36 }, { 4, 11, 565 }, + { 8, 11, 23 }, { 8, 11, 827 }, { 5, 0, 944 }, { 6, 0, 1769 }, + { 4, 0, 144 }, { 6, 0, 842 }, { 6, 0, 1400 }, { 4, 11, 922 }, + { 5, 11, 1023 }, { 5, 10, 248 }, { 9, 10, 800 }, { 10, 10, 693 }, + { 11, 10, 482 }, { 11, 10, 734 }, { 11, 10, 789 }, { 7, 11, 1002 }, + { 11, 11, 145 }, { 4, 10, 116 }, { 5, 10, 95 }, { 5, 10, 445 }, + { 7, 10, 1688 }, { 8, 10, 29 }, { 9, 10, 272 }, { 11, 10, 509 }, + { 11, 10, 915 }, { 14, 0, 369 }, { 18, 0, 72 }, { 7, 10, 1641 }, + { 4, 11, 740 }, { 5, 10, 543 }, { 12, 11, 116 }, { 6, 0, 247 }, + { 9, 0, 555 }, { 5, 10, 181 }, { 8, 10, 41 }, { 5, 10, 657 }, + { 8, 0, 996 }, { 10, 10, 709 }, { 7, 0, 189 }, { 8, 10, 202 }, + { 10, 10, 536 }, { 8, 11, 402 }, { 4, 11, 716 }, { 13, 11, 31 }, + { 10, 0, 280 }, { 10, 0, 797 }, { 9, 10, 423 }, { 12, 10, 89 }, + { 8, 10, 113 }, { 9, 10, 877 }, { 10, 10, 554 }, { 11, 10, 83 }, + { 12, 10, 136 }, { 19, 10, 109 }, { 5, 10, 976 }, { 7, 0, 746 }, + { 4, 10, 206 }, { 8, 0, 526 }, { 11, 0, 345 }, { 8, 0, 1017 }, + { 8, 11, 152 }, { 9, 11, 53 }, { 9, 11, 268 }, { 9, 11, 901 }, + { 10, 11, 518 }, { 10, 11, 829 }, { 11, 11, 188 }, { 13, 11, 74 }, + { 14, 11, 46 }, { 15, 11, 17 }, { 15, 11, 33 }, { 17, 11, 40 }, + { 18, 11, 36 }, { 19, 11, 20 }, { 22, 11, 1 }, { 24, 11, 2 }, + { 5, 11, 736 }, { 8, 11, 532 }, { 5, 0, 428 }, { 10, 0, 651 }, + { 7, 11, 681 }, { 7, 0, 1162 }, { 7, 0, 327 }, { 13, 0, 230 }, + { 17, 0, 113 }, { 8, 10, 226 }, { 10, 10, 537 }, { 11, 10, 570 }, + { 11, 10, 605 }, { 11, 10, 799 }, { 11, 10, 804 }, { 12, 10, 85 }, + { 12, 10, 516 }, { 12, 10, 623 }, { 12, 11, 677 }, { 13, 10, 361 }, + { 14, 10, 77 }, { 14, 10, 78 }, { 19, 10, 110 }, { 4, 0, 792 }, + { 7, 0, 1717 }, { 10, 0, 546 }, { 4, 10, 769 }, { 4, 11, 684 }, + { 8, 11, 384 }, { 4, 10, 551 }, { 6, 0, 1203 }, { 9, 10, 57 }, + { 9, 10, 459 }, { 10, 10, 425 }, { 11, 10, 119 }, { 12, 10, 184 }, + { 12, 10, 371 }, { 13, 10, 358 }, { 17, 10, 51 }, { 5, 0, 672 }, + { 5, 10, 814 }, { 8, 10, 10 }, { 9, 10, 421 }, { 9, 10, 729 }, + { 10, 10, 609 }, { 11, 10, 689 }, { 10, 0, 189 }, { 6, 10, 624 }, + { 7, 11, 110 }, { 7, 11, 188 }, { 8, 11, 290 }, { 8, 11, 591 }, + { 9, 11, 382 }, { 9, 11, 649 }, { 11, 11, 71 }, { 11, 11, 155 }, + { 11, 11, 313 }, { 12, 11, 5 }, { 13, 11, 325 }, { 14, 11, 287 }, + { 5, 0, 99 }, { 6, 0, 1053 }, { 7, 0, 298 }, { 7, 11, 360 }, + { 7, 11, 425 }, { 9, 11, 66 }, { 9, 11, 278 }, { 10, 11, 644 }, + { 4, 0, 397 }, { 8, 0, 555 }, { 9, 10, 269 }, { 4, 10, 528 }, + { 4, 11, 900 }, { 5, 11, 861 }, { 6, 0, 1157 }, { 5, 11, 254 }, + { 7, 11, 985 }, { 8, 11, 73 }, { 7, 11, 1959 }, { 8, 11, 683 }, + { 12, 0, 398 }, { 20, 0, 39 }, { 21, 0, 11 }, { 22, 0, 41 }, + { 4, 0, 485 }, { 7, 0, 353 }, { 7, 0, 1523 }, { 6, 0, 366 }, + { 7, 0, 1384 }, { 7, 0, 1601 }, { 10, 0, 787 }, { 9, 0, 282 }, + { 5, 10, 104 }, { 6, 10, 173 }, { 7, 10, 1631 }, { 11, 11, 146 }, + { 4, 0, 157 }, { 5, 0, 471 }, { 6, 0, 941 }, { 4, 11, 725 }, + { 7, 0, 1336 }, { 8, 10, 138 }, { 8, 10, 342 }, { 9, 10, 84 }, + { 10, 10, 193 }, { 11, 10, 883 }, { 12, 10, 359 }, { 6, 11, 196 }, + { 8, 0, 116 }, { 5, 11, 831 }, { 6, 0, 787 }, { 6, 10, 95 }, + { 6, 10, 406 }, { 10, 10, 409 }, { 10, 10, 447 }, { 11, 10, 44 }, + { 12, 10, 100 }, { 5, 0, 160 }, { 7, 0, 363 }, { 7, 0, 589 }, + { 10, 0, 170 }, { 13, 0, 55 }, { 6, 0, 1815 }, { 4, 0, 866 }, + { 6, 0, 889 }, { 6, 0, 1067 }, { 6, 0, 1183 }, { 4, 11, 321 }, + { 6, 11, 569 }, { 5, 11, 848 }, { 6, 11, 66 }, { 4, 11, 36 }, + { 6, 10, 1636 }, { 7, 11, 1387 }, { 10, 11, 205 }, { 11, 11, 755 }, + { 13, 11, 271 }, { 4, 0, 689 }, { 9, 0, 820 }, { 4, 10, 282 }, + { 7, 10, 1034 }, { 11, 10, 398 }, { 11, 10, 634 }, { 12, 10, 1 }, + { 12, 10, 79 }, { 12, 10, 544 }, { 14, 10, 237 }, { 17, 10, 10 }, + { 18, 10, 20 }, { 4, 0, 108 }, { 7, 0, 804 }, { 11, 0, 498 }, + { 4, 11, 887 }, { 6, 0, 1119 }, { 7, 11, 620 }, { 6, 11, 165 }, + { 10, 11, 388 }, { 5, 0, 244 }, { 5, 10, 499 }, { 6, 10, 476 }, + { 7, 10, 600 }, { 7, 10, 888 }, { 7, 10, 1096 }, { 12, 0, 609 }, + { 7, 0, 1005 }, { 4, 0, 412 }, { 5, 0, 581 }, { 4, 11, 719 }, + { 7, 11, 155 }, { 7, 10, 296 }, { 7, 10, 596 }, { 8, 10, 560 }, + { 8, 10, 586 }, { 9, 10, 612 }, { 11, 10, 304 }, { 12, 10, 46 }, + { 13, 10, 89 }, { 14, 10, 112 }, { 17, 10, 122 }, { 4, 0, 895 }, + { 5, 0, 772 }, { 14, 11, 307 }, { 7, 0, 1898 }, { 4, 0, 926 }, + { 5, 0, 983 }, { 4, 11, 353 }, { 6, 11, 146 }, { 6, 11, 1789 }, + { 7, 11, 288 }, { 7, 11, 990 }, { 7, 11, 1348 }, { 9, 11, 665 }, + { 9, 11, 898 }, { 11, 11, 893 }, { 14, 11, 212 }, { 4, 0, 538 }, + { 5, 11, 532 }, { 6, 0, 294 }, { 7, 0, 1267 }, { 8, 0, 624 }, + { 13, 0, 496 }, { 7, 0, 1325 }, { 4, 11, 45 }, { 7, 11, 1257 }, + { 10, 0, 301 }, { 9, 0, 298 }, { 12, 0, 291 }, { 13, 0, 276 }, + { 14, 0, 6 }, { 17, 0, 18 }, { 21, 0, 32 }, { 7, 10, 1599 }, + { 7, 10, 1723 }, { 8, 10, 79 }, { 8, 10, 106 }, { 8, 10, 190 }, + { 8, 10, 302 }, { 8, 10, 383 }, { 8, 10, 713 }, { 9, 10, 119 }, + { 9, 10, 233 }, { 9, 10, 419 }, { 9, 10, 471 }, { 10, 10, 181 }, + { 10, 10, 406 }, { 11, 10, 57 }, { 11, 10, 85 }, { 11, 10, 120 }, + { 11, 10, 177 }, { 11, 10, 296 }, { 11, 10, 382 }, { 11, 10, 454 }, + { 11, 10, 758 }, { 11, 10, 999 }, { 12, 10, 27 }, { 12, 10, 131 }, + { 12, 10, 245 }, { 12, 10, 312 }, { 12, 10, 446 }, { 12, 10, 454 }, + { 13, 10, 98 }, { 13, 10, 426 }, { 13, 10, 508 }, { 14, 10, 163 }, + { 14, 10, 272 }, { 14, 10, 277 }, { 14, 10, 370 }, { 15, 10, 95 }, + { 15, 10, 138 }, { 15, 10, 167 }, { 17, 10, 38 }, { 20, 10, 96 }, + { 4, 0, 757 }, { 6, 0, 1263 }, { 4, 0, 820 }, { 6, 10, 1759 }, + { 5, 0, 722 }, { 8, 11, 816 }, { 10, 10, 372 }, { 17, 10, 16 }, + { 6, 0, 1039 }, { 4, 0, 991 }, { 6, 0, 2028 }, { 5, 10, 258 }, + { 7, 0, 1875 }, { 11, 0, 124 }, { 6, 11, 559 }, { 6, 11, 1691 }, + { 7, 11, 586 }, { 5, 0, 324 }, { 7, 0, 881 }, { 8, 10, 134 }, + { 9, 10, 788 }, { 12, 10, 438 }, { 7, 11, 1823 }, { 11, 11, 693 }, + { 6, 0, 1348 }, { 6, 0, 1545 }, { 6, 0, 911 }, { 4, 0, 954 }, + { 8, 0, 329 }, { 8, 0, 414 }, { 7, 10, 1948 }, { 7, 10, 2004 }, + { 5, 0, 517 }, { 6, 10, 439 }, { 7, 10, 780 }, { 7, 10, 1040 }, + { 4, 0, 816 }, { 5, 10, 1 }, { 6, 10, 81 }, { 10, 10, 520 }, + { 9, 0, 713 }, { 10, 0, 222 }, { 5, 10, 482 }, { 8, 10, 98 }, + { 10, 10, 700 }, { 10, 10, 822 }, { 11, 10, 302 }, { 11, 10, 778 }, + { 12, 10, 50 }, { 12, 10, 127 }, { 12, 10, 396 }, { 13, 10, 62 }, + { 13, 10, 328 }, { 14, 10, 122 }, { 19, 10, 72 }, { 9, 0, 33 }, + { 5, 10, 2 }, { 7, 10, 1494 }, { 8, 10, 589 }, { 6, 10, 512 }, + { 7, 10, 797 }, { 8, 10, 253 }, { 9, 10, 77 }, { 10, 10, 1 }, + { 10, 11, 108 }, { 10, 10, 129 }, { 10, 10, 225 }, { 11, 11, 116 }, + { 11, 10, 118 }, { 11, 10, 226 }, { 11, 10, 251 }, { 11, 10, 430 }, + { 11, 10, 701 }, { 11, 10, 974 }, { 11, 10, 982 }, { 12, 10, 64 }, + { 12, 10, 260 }, { 12, 10, 488 }, { 12, 10, 690 }, { 6, 11, 456 }, + { 5, 11, 925 }, { 5, 0, 150 }, { 7, 0, 106 }, { 7, 0, 774 }, + { 8, 0, 603 }, { 9, 0, 593 }, { 9, 0, 634 }, { 10, 0, 44 }, + { 10, 0, 173 }, { 11, 0, 462 }, { 11, 0, 515 }, { 13, 0, 216 }, + { 13, 0, 288 }, { 14, 0, 400 }, { 9, 10, 347 }, { 5, 0, 748 }, + { 6, 0, 553 }, { 12, 0, 108 }, { 13, 0, 291 }, { 7, 0, 420 }, + { 4, 10, 12 }, { 7, 10, 522 }, { 7, 10, 809 }, { 8, 10, 797 }, + { 13, 10, 88 }, { 6, 11, 193 }, { 7, 11, 240 }, { 7, 11, 1682 }, + { 10, 11, 51 }, { 10, 11, 640 }, { 11, 11, 410 }, { 13, 11, 82 }, + { 14, 11, 247 }, { 14, 11, 331 }, { 14, 11, 377 }, { 5, 10, 528 }, + { 7, 0, 1777 }, { 4, 0, 493 }, { 16, 0, 55 }, { 8, 11, 633 }, + { 11, 0, 81 }, { 6, 0, 980 }, { 8, 0, 321 }, { 20, 10, 109 }, + { 5, 10, 266 }, { 9, 10, 290 }, { 9, 10, 364 }, { 10, 10, 293 }, + { 11, 10, 606 }, { 14, 10, 45 }, { 6, 0, 568 }, { 7, 0, 112 }, + { 7, 0, 1804 }, { 8, 0, 362 }, { 8, 0, 410 }, { 8, 0, 830 }, + { 9, 0, 514 }, { 11, 0, 649 }, { 14, 0, 157 }, { 4, 0, 74 }, + { 6, 0, 510 }, { 6, 10, 594 }, { 9, 10, 121 }, { 10, 10, 49 }, + { 10, 10, 412 }, { 11, 10, 834 }, { 6, 0, 838 }, { 8, 10, 748 }, + { 4, 10, 466 }, { 4, 0, 625 }, { 7, 11, 1443 }, { 4, 11, 237 }, + { 7, 11, 514 }, { 9, 10, 378 }, { 13, 10, 162 }, { 6, 0, 16 }, + { 6, 0, 158 }, { 7, 0, 43 }, { 7, 0, 129 }, { 7, 0, 181 }, + { 8, 0, 276 }, { 8, 0, 377 }, { 10, 0, 523 }, { 11, 0, 816 }, + { 12, 0, 455 }, { 13, 0, 303 }, { 14, 0, 135 }, { 7, 0, 281 }, + { 4, 0, 1 }, { 7, 0, 1143 }, { 7, 0, 1463 }, { 8, 0, 61 }, + { 9, 0, 207 }, { 9, 0, 390 }, { 9, 0, 467 }, { 11, 0, 836 }, + { 6, 11, 392 }, { 7, 11, 65 }, { 7, 11, 2019 }, { 4, 10, 667 }, + { 4, 0, 723 }, { 5, 0, 895 }, { 7, 0, 1031 }, { 8, 0, 199 }, + { 8, 0, 340 }, { 9, 0, 153 }, { 9, 0, 215 }, { 10, 0, 21 }, + { 10, 0, 59 }, { 10, 0, 80 }, { 10, 0, 224 }, { 10, 0, 838 }, + { 11, 0, 229 }, { 11, 0, 652 }, { 12, 0, 192 }, { 13, 0, 146 }, + { 14, 0, 91 }, { 4, 0, 295 }, { 9, 0, 51 }, { 9, 11, 222 }, + { 10, 11, 43 }, { 11, 11, 900 }, { 5, 0, 309 }, { 12, 0, 211 }, + { 5, 0, 125 }, { 8, 0, 77 }, { 10, 0, 15 }, { 8, 11, 604 }, + { 10, 0, 789 }, { 5, 0, 173 }, { 4, 10, 39 }, { 7, 10, 1843 }, + { 8, 10, 407 }, { 11, 10, 144 }, { 12, 10, 523 }, { 10, 11, 265 }, + { 5, 0, 439 }, { 4, 10, 510 }, { 7, 0, 648 }, { 7, 0, 874 }, + { 11, 0, 164 }, { 12, 0, 76 }, { 18, 0, 9 }, { 7, 10, 1980 }, + { 10, 10, 487 }, { 10, 10, 809 }, { 12, 0, 111 }, { 14, 0, 294 }, + { 19, 0, 45 }, { 13, 10, 260 }, { 18, 10, 63 }, { 5, 11, 549 }, + { 6, 10, 570 }, { 4, 0, 8 }, { 7, 0, 1152 }, { 7, 0, 1153 }, + { 7, 0, 1715 }, { 9, 0, 374 }, { 10, 0, 478 }, { 11, 0, 648 }, + { 7, 0, 1099 }, { 5, 0, 575 }, { 6, 0, 354 }, { 7, 0, 701 }, + { 7, 11, 36 }, { 8, 11, 201 }, { 8, 11, 605 }, { 4, 10, 787 }, + { 8, 11, 156 }, { 6, 0, 518 }, { 21, 11, 13 }, { 12, 11, 224 }, + { 6, 0, 702 }, { 4, 10, 516 }, { 5, 11, 724 }, { 10, 11, 305 }, + { 11, 11, 151 }, { 12, 11, 33 }, { 12, 11, 121 }, { 12, 11, 381 }, + { 17, 11, 3 }, { 17, 11, 27 }, { 17, 11, 78 }, { 18, 11, 18 }, + { 19, 11, 54 }, { 21, 11, 5 }, { 8, 0, 87 }, { 4, 11, 523 }, + { 5, 11, 638 }, { 11, 10, 887 }, { 14, 10, 365 }, { 14, 10, 375 }, + { 10, 0, 438 }, { 8, 10, 821 }, { 7, 11, 1908 }, { 6, 11, 242 }, + { 7, 11, 227 }, { 7, 11, 1581 }, { 8, 11, 104 }, { 9, 11, 113 }, + { 9, 11, 220 }, { 9, 11, 427 }, { 10, 11, 74 }, { 10, 11, 239 }, + { 11, 11, 579 }, { 11, 11, 1023 }, { 13, 11, 4 }, { 13, 11, 204 }, + { 13, 11, 316 }, { 18, 11, 95 }, { 20, 11, 86 }, { 4, 0, 69 }, + { 5, 0, 122 }, { 5, 0, 849 }, { 6, 0, 1633 }, { 9, 0, 656 }, + { 10, 0, 464 }, { 7, 0, 1802 }, { 4, 10, 10 }, { 11, 10, 786 }, + { 7, 11, 861 }, { 11, 0, 499 }, { 7, 0, 476 }, { 7, 0, 1592 }, + { 10, 0, 87 }, { 5, 10, 684 }, { 4, 0, 840 }, { 6, 10, 27 }, + { 14, 0, 283 }, { 6, 0, 1620 }, { 7, 11, 1328 }, { 8, 11, 494 }, + { 5, 0, 859 }, { 7, 0, 1160 }, { 8, 0, 107 }, { 9, 0, 291 }, + { 9, 0, 439 }, { 10, 0, 663 }, { 11, 0, 609 }, { 12, 0, 197 }, + { 7, 11, 1306 }, { 8, 11, 505 }, { 9, 11, 482 }, { 10, 11, 126 }, + { 11, 11, 225 }, { 12, 11, 347 }, { 12, 11, 449 }, { 13, 11, 19 }, + { 14, 11, 218 }, { 5, 11, 268 }, { 10, 11, 764 }, { 12, 11, 120 }, + { 13, 11, 39 }, { 17, 11, 127 }, { 17, 10, 56 }, { 7, 11, 1672 }, + { 10, 11, 472 }, { 11, 11, 189 }, { 15, 11, 51 }, { 6, 10, 342 }, + { 6, 10, 496 }, { 8, 10, 275 }, { 9, 10, 206 }, { 5, 0, 600 }, + { 4, 0, 117 }, { 6, 0, 372 }, { 7, 0, 1905 }, { 14, 0, 323 }, + { 4, 10, 909 }, { 5, 10, 940 }, { 7, 11, 1471 }, { 4, 10, 891 }, + { 4, 0, 722 }, { 11, 0, 471 }, { 4, 11, 384 }, { 7, 11, 1022 }, + { 4, 10, 687 }, { 9, 0, 5 }, { 12, 0, 216 }, { 12, 0, 294 }, + { 12, 0, 298 }, { 12, 0, 400 }, { 12, 0, 518 }, { 13, 0, 229 }, + { 15, 0, 139 }, { 7, 11, 1703 }, { 7, 11, 1602 }, { 10, 11, 698 }, + { 12, 11, 212 }, { 13, 11, 307 }, { 6, 10, 41 }, { 13, 10, 160 }, + { 7, 11, 1077 }, { 9, 11, 159 }, { 11, 11, 28 }, { 12, 11, 603 }, + { 4, 0, 514 }, { 7, 0, 1304 }, { 10, 0, 477 }, { 6, 0, 1774 }, + { 9, 0, 88 }, { 11, 0, 270 }, { 5, 0, 12 }, { 7, 0, 375 }, + { 9, 0, 438 }, { 6, 10, 1718 }, { 4, 11, 515 }, { 8, 10, 778 }, + { 8, 11, 632 }, { 8, 11, 697 }, { 9, 11, 854 }, { 6, 0, 362 }, + { 6, 0, 997 }, { 18, 0, 51 }, { 7, 0, 816 }, { 7, 0, 1241 }, + { 9, 0, 283 }, { 9, 0, 520 }, { 10, 0, 213 }, { 10, 0, 307 }, + { 10, 0, 463 }, { 10, 0, 671 }, { 10, 0, 746 }, { 11, 0, 401 }, + { 11, 0, 794 }, { 12, 0, 517 }, { 18, 0, 107 }, { 19, 0, 115 }, + { 5, 10, 115 }, { 22, 11, 28 }, { 4, 11, 136 }, { 5, 11, 551 }, + { 14, 10, 314 }, { 4, 0, 258 }, { 6, 0, 22 }, { 7, 0, 903 }, + { 7, 0, 1963 }, { 8, 0, 639 }, { 10, 0, 577 }, { 5, 0, 681 }, + { 8, 0, 782 }, { 13, 0, 130 }, { 17, 0, 84 }, { 5, 10, 193 }, + { 12, 10, 178 }, { 9, 11, 17 }, { 10, 11, 291 }, { 7, 11, 1287 }, + { 9, 11, 44 }, { 10, 11, 552 }, { 10, 11, 642 }, { 11, 11, 839 }, + { 12, 11, 274 }, { 12, 11, 275 }, { 12, 11, 372 }, { 13, 11, 91 }, + { 14, 11, 125 }, { 7, 10, 174 }, { 4, 0, 664 }, { 5, 0, 804 }, + { 11, 0, 1013 }, { 6, 0, 942 }, { 6, 0, 1349 }, { 6, 0, 1353 }, + { 6, 0, 1450 }, { 7, 11, 1518 }, { 11, 11, 694 }, { 11, 0, 356 }, + { 4, 10, 122 }, { 5, 10, 796 }, { 5, 10, 952 }, { 6, 10, 1660 }, + { 6, 10, 1671 }, { 8, 10, 567 }, { 9, 10, 687 }, { 9, 10, 742 }, + { 10, 10, 686 }, { 11, 10, 682 }, { 12, 10, 281 }, { 5, 0, 32 }, + { 6, 11, 147 }, { 7, 11, 886 }, { 9, 11, 753 }, { 10, 11, 268 }, + { 5, 10, 179 }, { 7, 10, 1095 }, { 7, 10, 1213 }, { 4, 10, 66 }, + { 7, 10, 722 }, { 7, 10, 904 }, { 7, 10, 352 }, { 9, 11, 245 }, + { 10, 11, 137 }, { 4, 0, 289 }, { 7, 0, 629 }, { 7, 0, 1698 }, + { 7, 0, 1711 }, { 12, 0, 215 }, { 5, 11, 414 }, { 6, 0, 1975 }, + { 7, 11, 1762 }, { 6, 0, 450 }, { 8, 0, 109 }, { 13, 10, 35 }, + { 6, 11, 599 }, { 8, 0, 705 }, { 5, 0, 664 }, { 6, 11, 1749 }, + { 11, 11, 402 }, { 12, 11, 109 }, { 12, 11, 431 }, { 13, 11, 179 }, + { 13, 11, 206 }, { 14, 11, 175 }, { 14, 11, 217 }, { 16, 11, 3 }, + { 20, 11, 53 }, { 7, 0, 1238 }, { 6, 11, 1627 }, { 4, 11, 488 }, + { 13, 0, 318 }, { 10, 10, 592 }, { 10, 10, 753 }, { 12, 10, 317 }, + { 12, 10, 355 }, { 12, 10, 465 }, { 12, 10, 469 }, { 12, 10, 560 }, + { 12, 10, 578 }, { 5, 10, 564 }, { 4, 11, 83 }, { 12, 11, 676 }, + { 6, 0, 1872 }, { 6, 0, 1906 }, { 6, 0, 1907 }, { 9, 0, 934 }, + { 9, 0, 956 }, { 9, 0, 960 }, { 9, 0, 996 }, { 12, 0, 794 }, + { 12, 0, 876 }, { 12, 0, 880 }, { 12, 0, 918 }, { 15, 0, 230 }, + { 18, 0, 234 }, { 18, 0, 238 }, { 21, 0, 38 }, { 21, 0, 62 }, + { 6, 10, 556 }, { 6, 11, 278 }, { 9, 0, 103 }, { 7, 10, 544 }, + { 8, 10, 719 }, { 10, 10, 61 }, { 4, 10, 5 }, { 5, 10, 498 }, + { 8, 10, 637 }, { 9, 10, 521 }, { 7, 0, 777 }, { 12, 0, 229 }, + { 12, 0, 239 }, { 15, 0, 12 }, { 12, 11, 229 }, { 12, 11, 239 }, + { 15, 11, 12 }, { 6, 0, 26 }, { 7, 11, 388 }, { 7, 11, 644 }, + { 11, 11, 781 }, { 7, 11, 229 }, { 8, 11, 59 }, { 9, 11, 190 }, + { 9, 11, 257 }, { 10, 11, 378 }, { 12, 11, 191 }, { 5, 10, 927 }, + { 7, 10, 1441 }, { 4, 10, 893 }, { 5, 10, 780 }, { 5, 10, 893 }, + { 4, 0, 414 }, { 5, 0, 467 }, { 9, 0, 654 }, { 10, 0, 451 }, + { 12, 0, 59 }, { 13, 0, 375 }, { 14, 0, 173 }, { 7, 0, 17 }, + { 7, 0, 1350 }, { 5, 10, 238 }, { 7, 0, 955 }, { 4, 0, 960 }, + { 10, 0, 887 }, { 12, 0, 753 }, { 18, 0, 161 }, { 18, 0, 162 }, + { 24, 0, 19 }, { 8, 11, 344 }, { 6, 10, 1729 }, { 9, 11, 288 }, + { 4, 11, 660 }, { 4, 0, 217 }, { 5, 0, 710 }, { 7, 0, 760 }, + { 7, 0, 1926 }, { 9, 0, 428 }, { 9, 0, 708 }, { 10, 0, 254 }, + { 10, 0, 296 }, { 10, 0, 720 }, { 11, 0, 109 }, { 11, 0, 255 }, + { 12, 0, 165 }, { 12, 0, 315 }, { 13, 0, 107 }, { 13, 0, 203 }, + { 14, 0, 54 }, { 14, 0, 99 }, { 14, 0, 114 }, { 14, 0, 388 }, + { 16, 0, 85 }, { 17, 0, 9 }, { 17, 0, 33 }, { 20, 0, 25 }, + { 20, 0, 28 }, { 20, 0, 29 }, { 21, 0, 9 }, { 21, 0, 10 }, + { 21, 0, 34 }, { 22, 0, 17 }, { 4, 10, 60 }, { 7, 10, 1800 }, + { 8, 10, 314 }, { 9, 10, 700 }, { 11, 10, 487 }, { 7, 11, 1035 }, + { 10, 11, 737 }, { 7, 11, 690 }, { 9, 11, 217 }, { 9, 11, 587 }, + { 12, 11, 521 }, { 6, 0, 919 }, { 7, 11, 706 }, { 7, 11, 1058 }, + { 10, 11, 538 }, { 7, 10, 1853 }, { 10, 10, 437 }, { 8, 10, 419 }, + { 6, 0, 280 }, { 10, 0, 502 }, { 11, 0, 344 }, { 12, 0, 38 }, + { 5, 0, 45 }, { 7, 0, 1161 }, { 11, 0, 448 }, { 11, 0, 880 }, + { 13, 0, 139 }, { 13, 0, 407 }, { 15, 0, 16 }, { 17, 0, 95 }, + { 18, 0, 66 }, { 18, 0, 88 }, { 18, 0, 123 }, { 21, 0, 7 }, + { 11, 11, 92 }, { 11, 11, 196 }, { 11, 11, 409 }, { 11, 11, 450 }, + { 11, 11, 666 }, { 11, 11, 777 }, { 12, 11, 262 }, { 13, 11, 385 }, + { 13, 11, 393 }, { 15, 11, 115 }, { 16, 11, 45 }, { 17, 11, 82 }, + { 8, 0, 777 }, { 6, 11, 1744 }, { 4, 0, 410 }, { 7, 0, 521 }, + { 5, 10, 828 }, { 6, 0, 673 }, { 7, 0, 1110 }, { 7, 0, 1778 }, + { 7, 10, 176 }, { 7, 10, 178 }, { 5, 10, 806 }, { 7, 11, 268 }, + { 7, 10, 1976 }, { 8, 11, 569 }, { 4, 11, 733 }, { 9, 11, 194 }, + { 10, 11, 92 }, { 11, 11, 198 }, { 12, 11, 84 }, { 12, 11, 87 }, + { 13, 11, 128 }, { 16, 11, 74 }, { 5, 0, 341 }, { 7, 0, 1129 }, + { 11, 0, 414 }, { 4, 10, 51 }, { 6, 10, 4 }, { 7, 10, 591 }, + { 7, 10, 849 }, { 7, 10, 951 }, { 7, 10, 1613 }, { 7, 10, 1760 }, + { 7, 10, 1988 }, { 9, 10, 434 }, { 10, 10, 754 }, { 11, 10, 25 }, + { 11, 10, 37 }, { 5, 10, 902 }, { 7, 10, 928 }, { 7, 0, 787 }, + { 4, 0, 436 }, { 6, 10, 270 }, { 7, 0, 1587 }, { 7, 0, 1707 }, + { 6, 0, 377 }, { 7, 0, 1025 }, { 9, 0, 613 }, { 17, 0, 104 }, + { 7, 11, 982 }, { 7, 11, 1361 }, { 10, 11, 32 }, { 15, 11, 56 }, + { 11, 0, 96 }, { 4, 0, 451 }, { 4, 10, 416 }, { 14, 10, 372 }, + { 5, 10, 152 }, { 5, 10, 197 }, { 7, 11, 306 }, { 7, 10, 340 }, + { 7, 10, 867 }, { 10, 10, 548 }, { 10, 10, 581 }, { 11, 10, 6 }, + { 12, 10, 3 }, { 12, 10, 19 }, { 14, 10, 110 }, { 14, 10, 289 }, + { 6, 0, 680 }, { 6, 11, 609 }, { 7, 0, 483 }, { 7, 10, 190 }, + { 8, 10, 28 }, { 8, 10, 141 }, { 8, 10, 444 }, { 8, 10, 811 }, + { 9, 10, 468 }, { 11, 10, 334 }, { 12, 10, 24 }, { 12, 10, 386 }, + { 12, 10, 576 }, { 10, 0, 916 }, { 5, 10, 757 }, { 5, 10, 721 }, + { 7, 10, 1553 }, { 5, 11, 178 }, { 6, 0, 937 }, { 4, 10, 898 }, + { 5, 0, 739 }, { 19, 0, 82 }, { 7, 0, 663 }, { 18, 0, 128 }, + { 5, 10, 277 }, { 13, 10, 247 }, { 6, 0, 1087 }, { 4, 10, 435 }, + { 6, 11, 381 }, { 7, 11, 645 }, { 7, 11, 694 }, { 8, 11, 546 }, + { 7, 0, 503 }, { 7, 0, 1885 }, { 6, 0, 1965 }, { 8, 0, 925 }, + { 10, 0, 955 }, { 4, 0, 113 }, { 5, 0, 163 }, { 5, 0, 735 }, + { 7, 0, 1009 }, { 9, 0, 9 }, { 9, 0, 771 }, { 12, 0, 90 }, + { 13, 0, 138 }, { 13, 0, 410 }, { 15, 0, 128 }, { 4, 0, 324 }, + { 10, 0, 104 }, { 7, 0, 460 }, { 5, 10, 265 }, { 6, 10, 212 }, + { 5, 11, 105 }, { 7, 11, 261 }, { 7, 11, 1107 }, { 7, 11, 1115 }, + { 7, 11, 1354 }, { 7, 11, 1588 }, { 7, 11, 1705 }, { 7, 11, 1902 }, + { 9, 11, 465 }, { 10, 11, 248 }, { 10, 11, 349 }, { 10, 11, 647 }, + { 11, 11, 527 }, { 11, 11, 660 }, { 11, 11, 669 }, { 12, 11, 529 }, + { 13, 11, 305 }, { 5, 11, 438 }, { 9, 11, 694 }, { 12, 11, 627 }, + { 13, 11, 210 }, { 24, 11, 11 }, { 4, 0, 935 }, { 5, 0, 823 }, + { 4, 10, 702 }, { 5, 0, 269 }, { 7, 0, 434 }, { 7, 0, 891 }, + { 8, 0, 339 }, { 9, 0, 702 }, { 11, 0, 594 }, { 11, 0, 718 }, + { 17, 0, 100 }, { 5, 10, 808 }, { 7, 10, 2045 }, { 7, 0, 1014 }, + { 9, 0, 485 }, { 13, 0, 264 }, { 6, 0, 1713 }, { 7, 0, 1810 }, + { 11, 0, 866 }, { 12, 0, 103 }, { 13, 0, 495 }, { 12, 11, 233 }, + { 4, 0, 423 }, { 10, 0, 949 }, { 10, 0, 1013 }, { 7, 0, 900 }, + { 8, 11, 25 }, { 10, 11, 826 }, { 5, 10, 166 }, { 8, 10, 739 }, + { 12, 10, 511 }, { 6, 0, 2018 }, { 7, 11, 1270 }, { 11, 11, 612 }, + { 4, 10, 119 }, { 5, 10, 170 }, { 5, 10, 447 }, { 7, 10, 1708 }, + { 7, 10, 1889 }, { 9, 10, 357 }, { 9, 10, 719 }, { 12, 10, 486 }, + { 12, 10, 596 }, { 12, 0, 574 }, { 12, 11, 574 }, { 4, 11, 308 }, + { 6, 0, 964 }, { 6, 0, 1206 }, { 6, 0, 1302 }, { 4, 10, 450 }, + { 7, 10, 1158 }, { 7, 11, 150 }, { 8, 11, 649 }, { 14, 0, 213 }, + { 20, 0, 38 }, { 9, 11, 45 }, { 9, 11, 311 }, { 13, 11, 42 }, + { 6, 11, 521 }, { 7, 10, 1375 }, { 7, 10, 1466 }, { 10, 10, 331 }, + { 4, 10, 754 }, { 5, 11, 339 }, { 7, 11, 1442 }, { 14, 11, 3 }, + { 15, 11, 41 }, { 19, 11, 66 }, { 8, 11, 378 }, { 6, 0, 1022 }, + { 5, 10, 850 }, { 8, 10, 799 }, { 14, 0, 143 }, { 7, 0, 2029 }, + { 6, 11, 1628 }, { 8, 0, 523 }, { 22, 0, 34 }, { 5, 0, 625 }, + { 7, 0, 1617 }, { 7, 0, 275 }, { 7, 10, 238 }, { 7, 10, 2033 }, + { 8, 10, 120 }, { 8, 10, 188 }, { 8, 10, 659 }, { 9, 10, 598 }, + { 10, 10, 466 }, { 12, 10, 342 }, { 12, 10, 588 }, { 13, 10, 503 }, + { 14, 10, 246 }, { 15, 10, 92 }, { 7, 0, 37 }, { 8, 0, 425 }, + { 8, 0, 693 }, { 9, 0, 720 }, { 10, 0, 380 }, { 10, 0, 638 }, + { 11, 0, 273 }, { 11, 0, 473 }, { 12, 0, 61 }, { 15, 0, 43 }, + { 7, 11, 829 }, { 7, 0, 1943 }, { 4, 0, 765 }, { 5, 11, 486 }, + { 7, 11, 1349 }, { 7, 11, 1635 }, { 8, 11, 17 }, { 10, 11, 217 }, + { 10, 11, 295 }, { 4, 10, 201 }, { 7, 10, 1744 }, { 8, 10, 602 }, + { 11, 10, 247 }, { 11, 10, 826 }, { 17, 10, 65 }, { 10, 11, 558 }, + { 11, 0, 551 }, { 14, 0, 159 }, { 8, 10, 164 }, { 18, 10, 62 }, + { 11, 11, 176 }, { 4, 0, 168 }, { 8, 0, 1010 }, { 6, 0, 1994 }, + { 7, 0, 91 }, { 10, 0, 532 }, { 7, 10, 1243 }, { 7, 0, 1884 }, + { 4, 10, 907 }, { 5, 10, 100 }, { 10, 10, 329 }, { 12, 10, 416 }, + { 21, 10, 29 }, { 6, 11, 447 }, { 4, 10, 176 }, { 5, 10, 636 }, + { 5, 10, 998 }, { 7, 10, 9 }, { 7, 10, 1508 }, { 8, 10, 26 }, + { 9, 10, 317 }, { 9, 10, 358 }, { 10, 10, 210 }, { 10, 10, 292 }, + { 10, 10, 533 }, { 11, 10, 555 }, { 12, 10, 526 }, { 12, 10, 607 }, + { 13, 10, 263 }, { 13, 10, 459 }, { 14, 10, 271 }, { 4, 11, 609 }, + { 7, 11, 756 }, { 6, 0, 15 }, { 7, 0, 70 }, { 10, 0, 240 }, + { 19, 0, 93 }, { 4, 11, 930 }, { 5, 11, 947 }, { 6, 0, 1227 }, + { 6, 0, 1534 }, { 5, 11, 939 }, { 5, 11, 962 }, { 5, 11, 651 }, + { 8, 11, 170 }, { 9, 11, 61 }, { 9, 11, 63 }, { 10, 11, 23 }, + { 10, 11, 37 }, { 10, 11, 834 }, { 11, 11, 4 }, { 11, 11, 187 }, + { 11, 11, 281 }, { 11, 11, 503 }, { 11, 11, 677 }, { 12, 11, 96 }, + { 12, 11, 130 }, { 12, 11, 244 }, { 14, 11, 5 }, { 14, 11, 40 }, + { 14, 11, 162 }, { 14, 11, 202 }, { 18, 11, 133 }, { 4, 11, 406 }, + { 5, 11, 579 }, { 12, 11, 492 }, { 22, 11, 15 }, { 11, 0, 392 }, + { 6, 10, 610 }, { 10, 10, 127 }, { 13, 10, 27 }, { 7, 0, 655 }, + { 7, 0, 1844 }, { 8, 10, 119 }, { 4, 0, 145 }, { 6, 0, 176 }, + { 7, 0, 395 }, { 9, 0, 562 }, { 4, 0, 501 }, { 12, 11, 145 }, + { 8, 0, 1019 }, { 6, 0, 509 }, { 11, 0, 267 }, { 6, 11, 17 }, + { 7, 11, 16 }, { 7, 11, 1001 }, { 7, 11, 1982 }, { 9, 11, 886 }, + { 10, 11, 489 }, { 10, 11, 800 }, { 11, 11, 782 }, { 12, 11, 320 }, + { 13, 11, 467 }, { 14, 11, 145 }, { 14, 11, 387 }, { 15, 11, 119 }, + { 17, 11, 17 }, { 6, 0, 1099 }, { 5, 11, 458 }, { 7, 11, 1983 }, + { 8, 11, 0 }, { 8, 11, 171 }, { 9, 11, 120 }, { 9, 11, 732 }, + { 10, 11, 473 }, { 11, 11, 656 }, { 11, 11, 998 }, { 18, 11, 0 }, + { 18, 11, 2 }, { 19, 11, 21 }, { 12, 11, 427 }, { 18, 11, 38 }, + { 10, 0, 948 }, { 10, 0, 968 }, { 7, 10, 126 }, { 8, 10, 84 }, + { 8, 10, 790 }, { 4, 0, 114 }, { 9, 0, 492 }, { 13, 0, 462 }, + { 14, 0, 215 }, { 6, 10, 64 }, { 12, 10, 377 }, { 13, 10, 309 }, + { 4, 0, 77 }, { 5, 0, 361 }, { 6, 0, 139 }, { 6, 0, 401 }, + { 6, 0, 404 }, { 7, 0, 413 }, { 7, 0, 715 }, { 7, 0, 1716 }, + { 11, 0, 279 }, { 12, 0, 179 }, { 12, 0, 258 }, { 13, 0, 244 }, + { 14, 0, 358 }, { 6, 0, 1717 }, { 7, 0, 772 }, { 7, 0, 1061 }, + { 7, 0, 1647 }, { 8, 0, 82 }, { 11, 0, 250 }, { 11, 0, 607 }, + { 12, 0, 311 }, { 12, 0, 420 }, { 13, 0, 184 }, { 13, 0, 367 }, + { 7, 10, 1104 }, { 11, 10, 269 }, { 11, 10, 539 }, { 11, 10, 627 }, + { 11, 10, 706 }, { 11, 10, 975 }, { 12, 10, 248 }, { 12, 10, 434 }, + { 12, 10, 600 }, { 12, 10, 622 }, { 13, 10, 297 }, { 13, 10, 485 }, + { 14, 10, 69 }, { 14, 10, 409 }, { 15, 10, 108 }, { 7, 0, 724 }, + { 4, 11, 512 }, { 4, 11, 519 }, { 5, 11, 342 }, { 6, 0, 1133 }, + { 17, 11, 29 }, { 11, 10, 977 }, { 13, 10, 507 }, { 6, 0, 841 }, + { 6, 0, 1042 }, { 6, 0, 1194 }, { 10, 0, 993 }, { 12, 0, 1021 }, + { 6, 11, 31 }, { 7, 11, 491 }, { 7, 11, 530 }, { 8, 11, 592 }, + { 9, 10, 34 }, { 11, 11, 53 }, { 11, 10, 484 }, { 11, 11, 779 }, + { 12, 11, 167 }, { 12, 11, 411 }, { 14, 11, 14 }, { 14, 11, 136 }, + { 15, 11, 72 }, { 16, 11, 17 }, { 16, 11, 72 }, { 4, 0, 1021 }, + { 6, 0, 2037 }, { 5, 11, 907 }, { 7, 0, 373 }, { 8, 0, 335 }, + { 8, 0, 596 }, { 9, 0, 488 }, { 6, 10, 1700 }, { 7, 10, 293 }, + { 7, 10, 382 }, { 7, 10, 1026 }, { 7, 10, 1087 }, { 7, 10, 2027 }, + { 8, 10, 252 }, { 8, 10, 727 }, { 8, 10, 729 }, { 9, 10, 30 }, + { 9, 10, 199 }, { 9, 10, 231 }, { 9, 10, 251 }, { 9, 10, 334 }, + { 9, 10, 361 }, { 9, 10, 712 }, { 10, 10, 55 }, { 10, 10, 60 }, + { 10, 10, 232 }, { 10, 10, 332 }, { 10, 10, 384 }, { 10, 10, 396 }, + { 10, 10, 504 }, { 10, 10, 542 }, { 10, 10, 652 }, { 11, 10, 20 }, + { 11, 10, 48 }, { 11, 10, 207 }, { 11, 10, 291 }, { 11, 10, 298 }, + { 11, 10, 342 }, { 11, 10, 365 }, { 11, 10, 394 }, { 11, 10, 620 }, + { 11, 10, 705 }, { 11, 10, 1017 }, { 12, 10, 123 }, { 12, 10, 340 }, + { 12, 10, 406 }, { 12, 10, 643 }, { 13, 10, 61 }, { 13, 10, 269 }, + { 13, 10, 311 }, { 13, 10, 319 }, { 13, 10, 486 }, { 14, 10, 234 }, + { 15, 10, 62 }, { 15, 10, 85 }, { 16, 10, 71 }, { 18, 10, 119 }, + { 20, 10, 105 }, { 22, 0, 37 }, { 4, 11, 208 }, { 5, 11, 106 }, + { 6, 11, 531 }, { 8, 11, 408 }, { 9, 11, 188 }, { 10, 11, 572 }, + { 4, 0, 564 }, { 6, 0, 513 }, { 7, 0, 1052 }, { 4, 0, 825 }, + { 9, 0, 899 }, { 12, 11, 441 }, { 6, 0, 778 }, { 5, 11, 379 }, + { 7, 0, 1417 }, { 12, 0, 382 }, { 17, 0, 48 }, { 24, 0, 12 }, + { 4, 11, 241 }, { 7, 0, 1116 }, { 6, 10, 379 }, { 7, 10, 270 }, + { 8, 10, 176 }, { 8, 10, 183 }, { 9, 10, 432 }, { 9, 10, 661 }, + { 12, 10, 247 }, { 12, 10, 617 }, { 18, 10, 125 }, { 5, 10, 792 }, + { 5, 10, 900 }, { 6, 0, 545 }, { 7, 0, 565 }, { 7, 0, 1669 }, + { 10, 0, 114 }, { 11, 0, 642 }, { 12, 0, 618 }, { 5, 0, 5 }, + { 10, 11, 7 }, { 4, 11, 259 }, { 7, 0, 192 }, { 6, 0, 701 }, + { 8, 0, 763 }, { 7, 10, 1979 }, { 4, 10, 901 }, { 5, 10, 776 }, + { 10, 0, 755 }, { 19, 0, 29 }, { 5, 0, 759 }, { 4, 11, 173 }, + { 5, 11, 312 }, { 5, 11, 512 }, { 7, 11, 1285 }, { 7, 11, 1603 }, + { 7, 11, 1691 }, { 9, 11, 464 }, { 11, 11, 195 }, { 12, 11, 279 }, + { 12, 11, 448 }, { 14, 11, 11 }, { 19, 11, 102 }, { 7, 0, 370 }, + { 7, 0, 1007 }, { 7, 0, 1177 }, { 7, 0, 1565 }, { 7, 0, 1237 }, + { 4, 0, 87 }, { 5, 0, 250 }, { 13, 0, 298 }, { 4, 11, 452 }, + { 5, 11, 583 }, { 5, 11, 817 }, { 6, 11, 433 }, { 7, 11, 593 }, + { 7, 11, 720 }, { 7, 11, 1378 }, { 8, 11, 161 }, { 9, 11, 284 }, + { 10, 11, 313 }, { 11, 11, 886 }, { 4, 11, 547 }, { 7, 11, 1409 }, + { 8, 11, 722 }, { 4, 10, 37 }, { 5, 10, 334 }, { 7, 10, 1253 }, + { 4, 10, 508 }, { 12, 0, 107 }, { 18, 0, 31 }, { 8, 11, 420 }, + { 11, 11, 193 }, { 7, 0, 814 }, { 7, 11, 409 }, { 12, 0, 991 }, + { 4, 0, 57 }, { 7, 0, 1195 }, { 7, 0, 1438 }, { 7, 0, 1548 }, + { 7, 0, 1835 }, { 7, 0, 1904 }, { 9, 0, 757 }, { 10, 0, 604 }, + { 11, 0, 519 }, { 4, 0, 540 }, { 10, 11, 308 }, { 4, 10, 533 }, + { 8, 0, 608 }, { 16, 11, 65 }, { 4, 0, 1014 }, { 6, 0, 2029 }, + { 4, 0, 209 }, { 7, 0, 902 }, { 5, 11, 1002 }, { 8, 11, 745 }, + { 6, 0, 2030 }, { 6, 0, 303 }, { 7, 0, 335 }, { 7, 0, 1437 }, + { 7, 0, 1668 }, { 8, 0, 553 }, { 8, 0, 652 }, { 8, 0, 656 }, + { 9, 0, 558 }, { 11, 0, 743 }, { 21, 0, 18 }, { 5, 11, 575 }, + { 6, 11, 354 }, { 7, 11, 701 }, { 4, 11, 239 }, { 6, 11, 477 }, + { 7, 11, 1607 }, { 11, 11, 68 }, { 11, 11, 617 }, { 4, 0, 559 }, + { 8, 0, 527 }, { 18, 0, 60 }, { 19, 0, 24 }, { 5, 10, 920 }, + { 10, 0, 511 }, { 5, 0, 1017 }, { 5, 0, 675 }, { 10, 10, 391 }, + { 11, 0, 156 }, { 7, 10, 1952 }, { 10, 11, 369 }, { 4, 11, 367 }, + { 5, 0, 709 }, { 6, 0, 698 }, { 6, 0, 887 }, { 14, 10, 126 }, + { 6, 0, 1745 }, { 4, 10, 483 }, { 13, 11, 299 }, { 14, 11, 75 }, + { 5, 0, 714 }, { 7, 0, 8 }, { 8, 0, 206 }, { 10, 10, 480 }, + { 4, 11, 694 }, { 9, 10, 495 }, { 18, 10, 104 }, { 7, 11, 1248 }, + { 11, 11, 621 }, { 11, 11, 702 }, { 12, 11, 687 }, { 4, 0, 776 }, + { 11, 10, 1009 }, { 7, 0, 1272 }, { 6, 0, 1059 }, { 8, 10, 653 }, + { 13, 10, 93 }, { 19, 10, 14 }, { 7, 11, 213 }, { 8, 0, 406 }, + { 5, 10, 172 }, { 4, 0, 947 }, { 8, 0, 175 }, { 10, 0, 168 }, + { 10, 0, 573 }, { 4, 0, 870 }, { 6, 0, 1567 }, { 23, 11, 28 }, + { 6, 11, 472 }, { 5, 10, 260 }, { 8, 11, 132 }, { 4, 11, 751 }, + { 11, 11, 390 }, { 12, 11, 32 }, { 4, 11, 409 }, { 5, 11, 78 }, + { 12, 0, 554 }, { 6, 11, 473 }, { 17, 11, 105 }, { 5, 0, 784 }, + { 8, 0, 908 }, { 8, 11, 306 }, { 11, 0, 882 }, { 6, 0, 358 }, + { 7, 0, 1393 }, { 8, 0, 396 }, { 10, 0, 263 }, { 14, 0, 154 }, + { 16, 0, 48 }, { 17, 0, 8 }, { 7, 11, 1759 }, { 8, 11, 396 }, + { 10, 11, 263 }, { 14, 11, 154 }, { 16, 11, 48 }, { 17, 11, 8 }, + { 13, 11, 163 }, { 13, 11, 180 }, { 18, 11, 78 }, { 20, 11, 35 }, + { 14, 0, 32 }, { 18, 0, 85 }, { 20, 0, 2 }, { 24, 0, 16 }, + { 7, 0, 228 }, { 10, 0, 770 }, { 8, 10, 167 }, { 8, 10, 375 }, + { 9, 10, 82 }, { 9, 10, 561 }, { 10, 10, 620 }, { 4, 0, 845 }, + { 9, 0, 14 }, { 9, 0, 441 }, { 10, 0, 306 }, { 11, 0, 9 }, + { 11, 0, 966 }, { 12, 0, 287 }, { 13, 0, 342 }, { 13, 0, 402 }, + { 15, 0, 110 }, { 15, 0, 163 }, { 8, 10, 194 }, { 8, 10, 756 }, + { 6, 0, 1578 }, { 4, 0, 967 }, { 6, 0, 1820 }, { 6, 0, 1847 }, + { 12, 0, 716 }, { 8, 0, 594 }, { 7, 0, 1428 }, { 7, 0, 1640 }, + { 7, 0, 1867 }, { 9, 0, 169 }, { 9, 0, 182 }, { 9, 0, 367 }, + { 9, 0, 478 }, { 9, 0, 506 }, { 9, 0, 551 }, { 9, 0, 557 }, + { 9, 0, 648 }, { 9, 0, 697 }, { 9, 0, 705 }, { 9, 0, 725 }, + { 9, 0, 787 }, { 9, 0, 794 }, { 10, 0, 198 }, { 10, 0, 214 }, + { 10, 0, 267 }, { 10, 0, 275 }, { 10, 0, 456 }, { 10, 0, 551 }, + { 10, 0, 561 }, { 10, 0, 613 }, { 10, 0, 627 }, { 10, 0, 668 }, + { 10, 0, 675 }, { 10, 0, 691 }, { 10, 0, 695 }, { 10, 0, 707 }, + { 10, 0, 715 }, { 11, 0, 183 }, { 11, 0, 201 }, { 11, 0, 244 }, + { 11, 0, 262 }, { 11, 0, 352 }, { 11, 0, 439 }, { 11, 0, 493 }, + { 11, 0, 572 }, { 11, 0, 591 }, { 11, 0, 608 }, { 11, 0, 611 }, + { 11, 0, 646 }, { 11, 0, 674 }, { 11, 0, 711 }, { 11, 0, 751 }, + { 11, 0, 761 }, { 11, 0, 776 }, { 11, 0, 785 }, { 11, 0, 850 }, + { 11, 0, 853 }, { 11, 0, 862 }, { 11, 0, 865 }, { 11, 0, 868 }, + { 11, 0, 875 }, { 11, 0, 898 }, { 11, 0, 902 }, { 11, 0, 903 }, + { 11, 0, 910 }, { 11, 0, 932 }, { 11, 0, 942 }, { 11, 0, 957 }, + { 11, 0, 967 }, { 11, 0, 972 }, { 12, 0, 148 }, { 12, 0, 195 }, + { 12, 0, 220 }, { 12, 0, 237 }, { 12, 0, 318 }, { 12, 0, 339 }, + { 12, 0, 393 }, { 12, 0, 445 }, { 12, 0, 450 }, { 12, 0, 474 }, + { 12, 0, 505 }, { 12, 0, 509 }, { 12, 0, 533 }, { 12, 0, 591 }, + { 12, 0, 594 }, { 12, 0, 597 }, { 12, 0, 621 }, { 12, 0, 633 }, + { 12, 0, 642 }, { 13, 0, 59 }, { 13, 0, 60 }, { 13, 0, 145 }, + { 13, 0, 239 }, { 13, 0, 250 }, { 13, 0, 329 }, { 13, 0, 344 }, + { 13, 0, 365 }, { 13, 0, 372 }, { 13, 0, 387 }, { 13, 0, 403 }, + { 13, 0, 414 }, { 13, 0, 456 }, { 13, 0, 470 }, { 13, 0, 478 }, + { 13, 0, 483 }, { 13, 0, 489 }, { 14, 0, 55 }, { 14, 0, 57 }, + { 14, 0, 81 }, { 14, 0, 90 }, { 14, 0, 148 }, { 14, 0, 239 }, + { 14, 0, 266 }, { 14, 0, 321 }, { 14, 0, 326 }, { 14, 0, 327 }, + { 14, 0, 330 }, { 14, 0, 347 }, { 14, 0, 355 }, { 14, 0, 401 }, + { 14, 0, 404 }, { 14, 0, 411 }, { 14, 0, 414 }, { 14, 0, 416 }, + { 14, 0, 420 }, { 15, 0, 61 }, { 15, 0, 74 }, { 15, 0, 87 }, + { 15, 0, 88 }, { 15, 0, 94 }, { 15, 0, 96 }, { 15, 0, 116 }, + { 15, 0, 149 }, { 15, 0, 154 }, { 16, 0, 50 }, { 16, 0, 63 }, + { 16, 0, 73 }, { 17, 0, 2 }, { 17, 0, 66 }, { 17, 0, 92 }, + { 17, 0, 103 }, { 17, 0, 112 }, { 17, 0, 120 }, { 18, 0, 50 }, + { 18, 0, 54 }, { 18, 0, 82 }, { 18, 0, 86 }, { 18, 0, 90 }, + { 18, 0, 111 }, { 18, 0, 115 }, { 18, 0, 156 }, { 19, 0, 40 }, + { 19, 0, 79 }, { 20, 0, 78 }, { 21, 0, 22 }, { 7, 11, 883 }, + { 5, 0, 161 }, { 7, 0, 839 }, { 4, 0, 782 }, { 13, 11, 293 }, + { 14, 11, 56 }, { 5, 11, 617 }, { 11, 11, 50 }, { 7, 10, 22 }, + { 17, 0, 64 }, { 5, 10, 639 }, { 7, 10, 1249 }, { 11, 10, 896 }, + { 10, 0, 998 }, { 7, 11, 2042 }, { 4, 11, 546 }, { 14, 11, 233 }, + { 6, 0, 1043 }, { 6, 0, 1574 }, { 6, 0, 1496 }, { 4, 10, 102 }, + { 7, 10, 815 }, { 7, 10, 1699 }, { 11, 10, 964 }, { 12, 0, 781 }, + { 14, 0, 461 }, { 4, 11, 313 }, { 5, 11, 577 }, { 6, 0, 639 }, + { 6, 0, 1114 }, { 9, 0, 817 }, { 8, 11, 184 }, { 13, 11, 433 }, + { 7, 0, 1814 }, { 7, 11, 935 }, { 10, 0, 997 }, { 12, 0, 958 }, + { 4, 0, 812 }, { 9, 11, 625 }, { 4, 10, 899 }, { 8, 10, 795 }, + { 5, 11, 886 }, { 6, 11, 46 }, { 6, 11, 1790 }, { 7, 11, 14 }, + { 7, 11, 732 }, { 7, 11, 1654 }, { 8, 11, 95 }, { 8, 11, 327 }, + { 8, 11, 616 }, { 10, 11, 598 }, { 10, 11, 769 }, { 11, 11, 134 }, + { 11, 11, 747 }, { 12, 11, 378 }, { 14, 11, 97 }, { 8, 0, 139 }, + { 6, 10, 52 }, { 9, 10, 104 }, { 9, 10, 559 }, { 12, 10, 308 }, + { 19, 10, 87 }, { 5, 11, 1021 }, { 4, 10, 604 }, { 4, 10, 301 }, + { 8, 10, 779 }, { 7, 0, 643 }, { 8, 0, 236 }, { 4, 11, 153 }, + { 6, 0, 1172 }, { 19, 10, 32 }, { 5, 11, 798 }, { 6, 0, 1338 }, + { 4, 11, 587 }, { 6, 11, 598 }, { 7, 11, 42 }, { 8, 11, 695 }, + { 10, 11, 212 }, { 11, 11, 158 }, { 14, 11, 196 }, { 17, 11, 85 }, + { 7, 10, 508 }, { 5, 11, 957 }, { 5, 11, 1008 }, { 7, 11, 249 }, + { 4, 11, 129 }, { 7, 11, 465 }, { 5, 0, 54 }, { 7, 11, 470 }, + { 7, 11, 1057 }, { 7, 11, 1201 }, { 9, 11, 755 }, { 11, 11, 906 }, + { 12, 11, 527 }, { 7, 11, 908 }, { 18, 11, 7 }, { 5, 11, 148 }, + { 8, 11, 450 }, { 16, 11, 1 }, { 4, 0, 256 }, { 7, 0, 1488 }, + { 9, 0, 351 }, { 6, 10, 310 }, { 7, 10, 1849 }, { 8, 10, 72 }, + { 8, 10, 272 }, { 8, 10, 431 }, { 9, 10, 12 }, { 10, 10, 563 }, + { 10, 10, 630 }, { 10, 10, 796 }, { 10, 10, 810 }, { 11, 10, 367 }, + { 11, 10, 599 }, { 11, 10, 686 }, { 12, 10, 672 }, { 6, 0, 1885 }, + { 6, 0, 1898 }, { 6, 0, 1899 }, { 12, 0, 955 }, { 4, 0, 714 }, + { 5, 0, 469 }, { 6, 0, 1270 }, { 6, 0, 1456 }, { 4, 0, 744 }, + { 6, 0, 313 }, { 7, 10, 537 }, { 8, 10, 64 }, { 9, 10, 127 }, + { 10, 10, 496 }, { 12, 10, 510 }, { 13, 10, 384 }, { 4, 11, 217 }, + { 4, 10, 244 }, { 5, 11, 710 }, { 7, 10, 233 }, { 7, 11, 1926 }, + { 9, 11, 428 }, { 9, 11, 708 }, { 10, 11, 254 }, { 10, 11, 296 }, + { 10, 11, 720 }, { 11, 11, 109 }, { 11, 11, 255 }, { 12, 11, 165 }, + { 12, 11, 315 }, { 13, 11, 107 }, { 13, 11, 203 }, { 14, 11, 54 }, + { 14, 11, 99 }, { 14, 11, 114 }, { 14, 11, 388 }, { 16, 11, 85 }, + { 17, 11, 9 }, { 17, 11, 33 }, { 20, 11, 25 }, { 20, 11, 28 }, + { 20, 11, 29 }, { 21, 11, 9 }, { 21, 11, 10 }, { 21, 11, 34 }, + { 22, 11, 17 }, { 10, 0, 402 }, { 7, 0, 969 }, { 18, 0, 55 }, + { 8, 0, 50 }, { 9, 0, 624 }, { 6, 0, 1355 }, { 4, 0, 572 }, + { 6, 10, 1650 }, { 10, 10, 702 }, { 11, 10, 245 }, { 10, 0, 847 }, + { 14, 0, 445 }, { 6, 0, 43 }, { 7, 0, 38 }, { 8, 0, 248 }, + { 10, 0, 513 }, { 5, 0, 369 }, { 9, 10, 338 }, { 5, 0, 766 }, + { 5, 0, 363 }, { 5, 10, 896 }, { 8, 11, 392 }, { 11, 11, 54 }, + { 13, 11, 173 }, { 13, 11, 294 }, { 20, 11, 7 }, { 6, 0, 678 }, + { 7, 11, 1230 }, { 8, 11, 531 }, { 6, 0, 258 }, { 12, 0, 409 }, + { 5, 0, 249 }, { 20, 0, 82 }, { 7, 10, 1117 }, { 8, 10, 539 }, + { 5, 0, 393 }, { 6, 0, 378 }, { 7, 0, 1981 }, { 9, 0, 32 }, + { 9, 0, 591 }, { 10, 0, 685 }, { 10, 0, 741 }, { 14, 0, 382 }, + { 5, 0, 788 }, { 6, 0, 1281 }, { 6, 0, 1295 }, { 7, 0, 1968 }, + { 13, 0, 509 }, { 4, 0, 61 }, { 5, 0, 58 }, { 5, 0, 171 }, + { 5, 0, 683 }, { 6, 0, 291 }, { 6, 0, 566 }, { 7, 0, 1650 }, + { 11, 0, 523 }, { 12, 0, 273 }, { 12, 0, 303 }, { 15, 0, 39 }, + { 15, 0, 111 }, { 6, 0, 706 }, { 6, 0, 1283 }, { 6, 0, 589 }, + { 7, 11, 1433 }, { 5, 11, 435 }, { 7, 0, 1059 }, { 13, 0, 54 }, + { 5, 10, 4 }, { 5, 10, 810 }, { 6, 10, 13 }, { 6, 10, 538 }, + { 6, 10, 1690 }, { 6, 10, 1726 }, { 7, 10, 1819 }, { 8, 10, 148 }, + { 8, 10, 696 }, { 8, 10, 791 }, { 12, 10, 125 }, { 15, 10, 9 }, + { 7, 10, 1268 }, { 5, 11, 85 }, { 6, 11, 419 }, { 7, 11, 134 }, + { 7, 11, 305 }, { 7, 11, 361 }, { 7, 11, 1337 }, { 8, 11, 71 }, + { 12, 11, 519 }, { 9, 0, 824 }, { 12, 11, 688 }, { 5, 11, 691 }, + { 7, 11, 345 }, { 7, 10, 1385 }, { 9, 11, 94 }, { 11, 10, 582 }, + { 11, 10, 650 }, { 11, 10, 901 }, { 11, 10, 949 }, { 12, 11, 169 }, + { 12, 10, 232 }, { 12, 10, 236 }, { 13, 10, 413 }, { 13, 10, 501 }, + { 18, 10, 116 }, { 4, 0, 917 }, { 5, 0, 1005 }, { 7, 0, 1598 }, + { 5, 11, 183 }, { 6, 11, 582 }, { 9, 11, 344 }, { 10, 11, 679 }, + { 12, 11, 435 }, { 4, 10, 925 }, { 5, 10, 803 }, { 8, 10, 698 }, + { 10, 10, 828 }, { 4, 0, 919 }, { 7, 11, 511 }, { 11, 10, 992 }, + { 4, 0, 255 }, { 5, 0, 302 }, { 6, 0, 132 }, { 7, 0, 128 }, + { 7, 0, 283 }, { 7, 0, 1299 }, { 10, 0, 52 }, { 10, 0, 514 }, + { 11, 0, 925 }, { 13, 0, 92 }, { 14, 0, 309 }, { 6, 0, 1369 }, + { 7, 10, 1847 }, { 6, 0, 328 }, { 7, 11, 1993 }, { 8, 11, 684 }, + { 5, 10, 383 }, { 9, 0, 173 }, { 6, 11, 583 }, { 6, 0, 1411 }, + { 19, 0, 65 }, { 5, 11, 704 }, { 8, 11, 357 }, { 10, 11, 745 }, + { 14, 11, 426 }, { 17, 11, 94 }, { 19, 11, 57 }, { 9, 10, 660 }, + { 10, 10, 347 }, { 4, 11, 179 }, { 5, 11, 198 }, { 5, 11, 697 }, + { 7, 11, 347 }, { 7, 11, 971 }, { 8, 11, 181 }, { 10, 11, 711 }, + { 13, 0, 442 }, { 11, 0, 842 }, { 11, 0, 924 }, { 13, 0, 317 }, + { 13, 0, 370 }, { 13, 0, 469 }, { 13, 0, 471 }, { 14, 0, 397 }, + { 18, 0, 69 }, { 18, 0, 145 }, { 7, 10, 572 }, { 9, 10, 592 }, + { 11, 10, 680 }, { 12, 10, 356 }, { 12, 10, 550 }, { 14, 11, 19 }, + { 14, 11, 28 }, { 16, 11, 29 }, { 8, 0, 534 }, { 4, 11, 243 }, + { 5, 11, 203 }, { 7, 11, 19 }, { 7, 11, 71 }, { 7, 11, 113 }, + { 10, 11, 405 }, { 11, 11, 357 }, { 14, 11, 240 }, { 6, 0, 210 }, + { 10, 0, 845 }, { 10, 0, 862 }, { 7, 11, 1351 }, { 9, 11, 581 }, + { 10, 11, 639 }, { 11, 11, 453 }, { 12, 11, 584 }, { 7, 11, 1450 }, + { 11, 11, 99 }, { 10, 0, 892 }, { 12, 0, 719 }, { 16, 0, 105 }, + { 4, 0, 284 }, { 6, 0, 223 }, { 6, 11, 492 }, { 5, 11, 134 }, + { 6, 11, 408 }, { 6, 11, 495 }, { 7, 11, 1593 }, { 8, 0, 529 }, + { 9, 0, 807 }, { 4, 0, 218 }, { 7, 0, 526 }, { 15, 0, 137 }, + { 6, 0, 1444 }, { 14, 11, 4 }, { 4, 11, 665 }, { 4, 0, 270 }, + { 5, 0, 192 }, { 6, 0, 332 }, { 7, 0, 1322 }, { 4, 11, 248 }, + { 7, 11, 137 }, { 9, 11, 349 }, { 12, 0, 661 }, { 7, 0, 1517 }, + { 11, 0, 597 }, { 14, 0, 76 }, { 14, 0, 335 }, { 20, 0, 33 }, + { 7, 10, 748 }, { 11, 10, 700 }, { 5, 11, 371 }, { 7, 11, 563 }, + { 18, 11, 57 }, { 5, 10, 127 }, { 5, 0, 418 }, { 4, 11, 374 }, + { 7, 11, 547 }, { 7, 11, 1700 }, { 7, 11, 1833 }, { 11, 11, 858 }, + { 6, 10, 198 }, { 12, 10, 83 }, { 7, 11, 1812 }, { 13, 11, 259 }, + { 13, 11, 356 }, { 14, 11, 242 }, { 19, 11, 114 }, { 7, 0, 379 }, + { 8, 0, 481 }, { 9, 0, 377 }, { 5, 10, 276 }, { 6, 10, 55 }, + { 7, 10, 1369 }, { 10, 11, 286 }, { 5, 0, 1003 }, { 6, 0, 149 }, + { 6, 10, 1752 }, { 8, 10, 726 }, { 8, 0, 262 }, { 9, 0, 627 }, + { 10, 0, 18 }, { 11, 0, 214 }, { 11, 0, 404 }, { 11, 0, 457 }, + { 11, 0, 780 }, { 11, 0, 913 }, { 13, 0, 401 }, { 14, 0, 200 }, + { 6, 11, 1647 }, { 7, 11, 1552 }, { 7, 11, 2010 }, { 9, 11, 494 }, + { 9, 11, 509 }, { 7, 0, 742 }, { 8, 0, 304 }, { 4, 0, 142 }, + { 5, 10, 764 }, { 6, 10, 309 }, { 7, 10, 331 }, { 10, 10, 550 }, + { 7, 10, 1062 }, { 6, 11, 123 }, { 7, 11, 214 }, { 7, 10, 986 }, + { 9, 11, 728 }, { 10, 11, 157 }, { 11, 11, 346 }, { 11, 11, 662 }, + { 15, 11, 106 }, { 7, 10, 1573 }, { 7, 0, 925 }, { 9, 0, 799 }, + { 4, 0, 471 }, { 5, 0, 51 }, { 6, 0, 602 }, { 8, 0, 484 }, + { 10, 0, 195 }, { 8, 0, 688 }, { 4, 0, 697 }, { 6, 0, 1169 }, + { 6, 0, 1241 }, { 6, 10, 194 }, { 7, 10, 133 }, { 10, 10, 493 }, + { 10, 10, 570 }, { 11, 10, 664 }, { 12, 0, 751 }, { 7, 0, 929 }, + { 10, 0, 452 }, { 11, 0, 878 }, { 16, 0, 33 }, { 5, 10, 24 }, + { 5, 10, 569 }, { 6, 10, 3 }, { 6, 10, 119 }, { 6, 10, 143 }, + { 6, 10, 440 }, { 7, 10, 599 }, { 7, 10, 1686 }, { 7, 10, 1854 }, + { 8, 10, 424 }, { 9, 10, 43 }, { 9, 10, 584 }, { 9, 10, 760 }, + { 10, 10, 328 }, { 11, 10, 159 }, { 11, 10, 253 }, { 12, 10, 487 }, + { 12, 10, 531 }, { 4, 11, 707 }, { 13, 11, 106 }, { 18, 11, 49 }, + { 19, 11, 41 }, { 5, 0, 221 }, { 5, 11, 588 }, { 6, 11, 393 }, + { 6, 0, 1437 }, { 6, 11, 211 }, { 7, 11, 1690 }, { 11, 11, 486 }, + { 12, 11, 369 }, { 5, 10, 14 }, { 5, 10, 892 }, { 6, 10, 283 }, + { 7, 10, 234 }, { 8, 10, 537 }, { 4, 0, 988 }, { 8, 0, 955 }, + { 7, 0, 1251 }, { 4, 10, 126 }, { 8, 10, 635 }, { 19, 10, 34 }, + { 4, 10, 316 }, { 7, 10, 1561 }, { 9, 10, 861 }, { 4, 10, 64 }, + { 5, 10, 352 }, { 5, 10, 720 }, { 6, 10, 368 }, { 11, 10, 359 }, + { 6, 0, 192 }, { 4, 0, 132 }, { 5, 0, 69 }, { 7, 0, 1242 }, + { 7, 10, 1577 }, { 10, 10, 304 }, { 10, 10, 549 }, { 12, 10, 365 }, + { 13, 10, 220 }, { 13, 10, 240 }, { 14, 10, 33 }, { 4, 0, 111 }, + { 7, 0, 865 }, { 6, 11, 219 }, { 5, 11, 582 }, { 6, 11, 1646 }, + { 7, 11, 99 }, { 7, 11, 1962 }, { 7, 11, 1986 }, { 8, 11, 515 }, + { 8, 11, 773 }, { 9, 11, 23 }, { 9, 11, 491 }, { 12, 11, 620 }, + { 14, 11, 52 }, { 17, 11, 50 }, { 4, 0, 767 }, { 7, 11, 568 }, + { 20, 11, 21 }, { 6, 0, 42 }, { 7, 0, 1416 }, { 7, 0, 2005 }, + { 8, 0, 131 }, { 8, 0, 466 }, { 9, 0, 672 }, { 13, 0, 252 }, + { 20, 0, 103 }, { 5, 11, 851 }, { 7, 0, 1050 }, { 6, 10, 175 }, + { 9, 10, 289 }, { 5, 10, 432 }, { 5, 10, 913 }, { 6, 0, 44 }, + { 8, 0, 368 }, { 7, 11, 784 }, { 4, 0, 570 }, { 5, 0, 120 }, + { 11, 10, 595 }, { 12, 0, 29 }, { 6, 0, 227 }, { 7, 0, 1589 }, + { 4, 11, 98 }, { 7, 11, 1365 }, { 9, 11, 422 }, { 9, 11, 670 }, + { 10, 11, 775 }, { 11, 11, 210 }, { 13, 11, 26 }, { 13, 11, 457 }, + { 13, 11, 476 }, { 12, 10, 80 }, { 5, 10, 931 }, { 6, 10, 1698 }, + { 5, 0, 522 }, { 6, 0, 1120 }, { 7, 0, 1529 }, { 12, 0, 739 }, + { 14, 0, 448 }, { 14, 0, 467 }, { 11, 10, 526 }, { 11, 10, 939 }, + { 13, 10, 290 }, { 5, 10, 774 }, { 6, 10, 1637 }, { 6, 10, 1686 }, + { 6, 10, 1751 }, { 6, 0, 1667 }, { 7, 0, 2036 }, { 7, 10, 1167 }, + { 11, 10, 934 }, { 13, 10, 391 }, { 17, 10, 76 }, { 9, 11, 147 }, + { 6, 10, 260 }, { 7, 10, 1484 }, { 11, 11, 821 }, { 12, 11, 110 }, + { 12, 11, 153 }, { 18, 11, 41 }, { 22, 11, 19 }, { 6, 0, 511 }, + { 12, 0, 132 }, { 6, 10, 573 }, { 5, 0, 568 }, { 6, 0, 138 }, + { 7, 0, 1293 }, { 4, 0, 1020 }, { 8, 0, 258 }, { 9, 0, 208 }, + { 9, 0, 359 }, { 4, 0, 565 }, { 8, 0, 23 }, { 8, 0, 827 }, + { 6, 0, 344 }, { 4, 0, 922 }, { 5, 0, 1023 }, { 13, 11, 477 }, + { 14, 11, 120 }, { 20, 11, 61 }, { 6, 0, 240 }, { 5, 11, 209 }, + { 6, 11, 30 }, { 11, 11, 56 }, { 11, 11, 305 }, { 6, 0, 171 }, + { 7, 0, 1002 }, { 7, 0, 1324 }, { 9, 0, 415 }, { 14, 0, 230 }, + { 18, 0, 68 }, { 4, 10, 292 }, { 4, 10, 736 }, { 5, 10, 871 }, + { 6, 10, 1689 }, { 7, 10, 1944 }, { 9, 10, 580 }, { 9, 11, 635 }, + { 11, 11, 559 }, { 4, 11, 150 }, { 5, 11, 303 }, { 6, 11, 327 }, + { 6, 10, 63 }, { 7, 10, 920 }, { 5, 10, 793 }, { 8, 11, 192 }, + { 10, 11, 78 }, { 10, 11, 555 }, { 11, 11, 308 }, { 13, 11, 359 }, + { 19, 11, 95 }, { 7, 11, 786 }, { 7, 11, 1712 }, { 8, 0, 402 }, + { 6, 0, 754 }, { 6, 11, 1638 }, { 7, 11, 79 }, { 7, 11, 496 }, + { 9, 11, 138 }, { 10, 11, 336 }, { 11, 11, 12 }, { 12, 11, 412 }, + { 12, 11, 440 }, { 14, 11, 305 }, { 4, 0, 716 }, { 13, 0, 31 }, + { 5, 0, 982 }, { 8, 0, 691 }, { 8, 0, 731 }, { 5, 10, 67 }, + { 6, 10, 62 }, { 6, 10, 374 }, { 7, 10, 1391 }, { 9, 10, 790 }, + { 12, 10, 47 }, { 11, 11, 556 }, { 23, 11, 1 }, { 7, 11, 204 }, + { 7, 11, 415 }, { 8, 11, 42 }, { 10, 11, 85 }, { 11, 11, 33 }, + { 11, 11, 564 }, { 12, 11, 571 }, { 21, 11, 1 }, { 8, 0, 888 }, + { 7, 11, 610 }, { 7, 11, 1501 }, { 4, 10, 391 }, { 7, 10, 1169 }, + { 5, 0, 847 }, { 9, 0, 840 }, { 10, 0, 803 }, { 9, 0, 823 }, + { 6, 0, 785 }, { 8, 0, 152 }, { 9, 0, 53 }, { 9, 0, 268 }, + { 9, 0, 901 }, { 10, 0, 518 }, { 10, 0, 829 }, { 11, 0, 188 }, + { 13, 0, 74 }, { 14, 0, 46 }, { 15, 0, 17 }, { 15, 0, 33 }, + { 17, 0, 40 }, { 18, 0, 36 }, { 19, 0, 20 }, { 22, 0, 1 }, + { 24, 0, 2 }, { 4, 11, 3 }, { 5, 11, 247 }, { 5, 11, 644 }, + { 7, 11, 744 }, { 7, 11, 1207 }, { 7, 11, 1225 }, { 7, 11, 1909 }, + { 18, 11, 147 }, { 8, 0, 532 }, { 7, 0, 681 }, { 4, 10, 271 }, + { 12, 0, 314 }, { 12, 0, 677 }, { 4, 0, 684 }, { 8, 0, 384 }, + { 5, 11, 285 }, { 9, 11, 67 }, { 13, 11, 473 }, { 15, 11, 82 }, + { 4, 10, 253 }, { 5, 10, 544 }, { 7, 10, 300 }, { 9, 10, 340 }, + { 7, 0, 110 }, { 7, 0, 447 }, { 8, 0, 290 }, { 8, 0, 591 }, + { 9, 0, 382 }, { 9, 0, 649 }, { 11, 0, 71 }, { 11, 0, 155 }, + { 11, 0, 313 }, { 12, 0, 5 }, { 13, 0, 325 }, { 14, 0, 287 }, + { 6, 0, 1818 }, { 8, 0, 1007 }, { 10, 0, 321 }, { 7, 0, 360 }, + { 7, 0, 425 }, { 9, 0, 66 }, { 9, 0, 278 }, { 10, 0, 644 }, + { 5, 10, 818 }, { 5, 0, 385 }, { 5, 10, 541 }, { 6, 10, 94 }, + { 6, 10, 499 }, { 7, 10, 230 }, { 11, 10, 321 }, { 4, 10, 920 }, + { 5, 10, 25 }, { 5, 10, 790 }, { 6, 10, 457 }, { 7, 10, 853 }, + { 8, 10, 788 }, { 4, 0, 900 }, { 5, 0, 861 }, { 5, 0, 254 }, + { 7, 0, 985 }, { 8, 0, 73 }, { 7, 0, 1959 }, { 8, 0, 683 }, + { 6, 10, 1765 }, { 5, 10, 822 }, { 4, 10, 634 }, { 4, 11, 29 }, + { 6, 11, 532 }, { 7, 11, 1628 }, { 7, 11, 1648 }, { 9, 11, 303 }, + { 9, 11, 350 }, { 10, 11, 433 }, { 11, 11, 97 }, { 11, 11, 557 }, + { 11, 11, 745 }, { 12, 11, 289 }, { 12, 11, 335 }, { 12, 11, 348 }, + { 12, 11, 606 }, { 13, 11, 116 }, { 13, 11, 233 }, { 13, 11, 466 }, + { 14, 11, 181 }, { 14, 11, 209 }, { 14, 11, 232 }, { 14, 11, 236 }, + { 14, 11, 300 }, { 16, 11, 41 }, { 20, 11, 97 }, { 19, 0, 86 }, + { 6, 10, 36 }, { 7, 10, 658 }, { 8, 10, 454 }, { 7, 11, 1692 }, + { 4, 0, 725 }, { 5, 11, 501 }, { 7, 11, 1704 }, { 9, 11, 553 }, + { 11, 11, 520 }, { 12, 11, 557 }, { 13, 11, 249 }, { 6, 0, 196 }, + { 5, 0, 831 }, { 8, 0, 723 }, { 7, 0, 1897 }, { 13, 0, 80 }, + { 13, 0, 437 }, { 17, 0, 74 }, { 4, 0, 992 }, { 6, 0, 627 }, + { 8, 0, 994 }, { 7, 11, 1294 }, { 4, 10, 104 }, { 5, 0, 848 }, + { 6, 0, 66 }, { 8, 0, 764 }, { 4, 0, 36 }, { 7, 0, 1387 }, + { 10, 0, 205 }, { 11, 0, 755 }, { 6, 0, 1046 }, { 6, 0, 1485 }, + { 6, 0, 950 }, { 4, 0, 887 }, { 14, 0, 450 }, { 20, 0, 111 }, + { 7, 0, 620 }, { 7, 0, 831 }, { 9, 10, 542 }, { 9, 10, 566 }, + { 10, 10, 728 }, { 6, 0, 165 }, { 10, 0, 388 }, { 11, 10, 263 }, + { 4, 0, 719 }, { 7, 0, 155 }, { 10, 10, 468 }, { 6, 11, 453 }, + { 16, 11, 36 }, { 6, 11, 129 }, { 5, 0, 533 }, { 7, 0, 755 }, + { 10, 0, 780 }, { 6, 0, 1465 }, { 4, 0, 353 }, { 6, 0, 146 }, + { 6, 0, 1789 }, { 7, 0, 427 }, { 7, 0, 990 }, { 7, 0, 1348 }, + { 9, 0, 665 }, { 9, 0, 898 }, { 11, 0, 893 }, { 14, 0, 212 }, + { 7, 10, 87 }, { 14, 10, 288 }, { 4, 0, 45 }, { 7, 0, 1257 }, + { 12, 0, 7 }, { 7, 10, 988 }, { 7, 10, 1939 }, { 9, 10, 64 }, + { 9, 10, 502 }, { 12, 10, 34 }, { 13, 10, 12 }, { 13, 10, 234 }, + { 19, 10, 77 }, { 4, 0, 607 }, { 5, 11, 60 }, { 6, 11, 504 }, + { 7, 11, 614 }, { 7, 11, 1155 }, { 12, 11, 0 }, { 7, 10, 141 }, + { 8, 11, 198 }, { 11, 11, 29 }, { 12, 11, 534 }, { 12, 0, 65 }, + { 8, 0, 816 }, { 4, 10, 619 }, { 11, 0, 88 }, { 5, 10, 246 }, + { 8, 10, 189 }, { 9, 10, 355 }, { 9, 10, 512 }, { 10, 10, 124 }, + { 10, 10, 453 }, { 11, 10, 143 }, { 11, 10, 416 }, { 11, 10, 859 }, + { 13, 10, 341 }, { 4, 11, 379 }, { 7, 11, 1397 }, { 4, 0, 600 }, + { 9, 0, 621 }, { 5, 0, 367 }, { 6, 0, 561 }, { 6, 0, 559 }, + { 6, 0, 1691 }, { 6, 0, 585 }, { 6, 11, 585 }, { 7, 11, 1228 }, + { 4, 11, 118 }, { 5, 10, 678 }, { 6, 11, 274 }, { 6, 11, 361 }, + { 7, 11, 75 }, { 13, 11, 441 }, { 7, 11, 1818 }, { 9, 11, 841 }, + { 5, 0, 573 }, { 6, 0, 287 }, { 7, 10, 862 }, { 7, 10, 1886 }, + { 10, 10, 179 }, { 4, 10, 517 }, { 12, 11, 693 }, { 5, 11, 314 }, + { 6, 11, 221 }, { 7, 11, 419 }, { 10, 11, 650 }, { 11, 11, 396 }, + { 12, 11, 156 }, { 13, 11, 369 }, { 14, 11, 333 }, { 17, 11, 47 }, + { 12, 10, 540 }, { 8, 10, 667 }, { 11, 10, 403 }, { 18, 10, 83 }, + { 6, 0, 672 }, { 5, 10, 761 }, { 9, 0, 157 }, { 10, 10, 131 }, + { 12, 10, 72 }, { 7, 0, 714 }, { 6, 11, 460 }, { 6, 0, 456 }, + { 5, 0, 925 }, { 5, 11, 682 }, { 7, 11, 1887 }, { 8, 11, 510 }, + { 8, 11, 475 }, { 5, 11, 1016 }, { 9, 0, 19 }, { 7, 11, 602 }, + { 8, 11, 179 }, { 10, 11, 781 }, { 12, 11, 126 }, { 6, 11, 329 }, + { 10, 11, 111 }, { 6, 0, 822 }, { 6, 0, 1473 }, { 16, 11, 86 }, + { 11, 0, 113 }, { 11, 11, 113 }, { 5, 11, 821 }, { 6, 11, 1687 }, + { 5, 10, 449 }, { 7, 0, 463 }, { 17, 0, 69 }, { 8, 10, 103 }, + { 7, 10, 2028 }, { 10, 10, 641 }, { 6, 0, 193 }, { 7, 0, 240 }, + { 7, 0, 1682 }, { 10, 0, 51 }, { 10, 0, 640 }, { 11, 0, 410 }, + { 13, 0, 82 }, { 14, 0, 247 }, { 14, 0, 331 }, { 14, 0, 377 }, + { 6, 0, 471 }, { 11, 0, 411 }, { 14, 0, 2 }, { 5, 11, 71 }, + { 7, 11, 1407 }, { 9, 11, 388 }, { 9, 11, 704 }, { 10, 11, 261 }, + { 10, 11, 619 }, { 11, 11, 547 }, { 11, 11, 619 }, { 15, 11, 157 }, + { 8, 0, 633 }, { 7, 0, 1148 }, { 6, 0, 554 }, { 7, 0, 1392 }, + { 12, 0, 129 }, { 7, 10, 1274 }, { 7, 10, 1386 }, { 7, 11, 2008 }, + { 9, 11, 337 }, { 10, 11, 517 }, { 18, 10, 87 }, { 7, 0, 803 }, + { 8, 0, 542 }, { 6, 10, 187 }, { 7, 10, 1203 }, { 8, 10, 380 }, + { 14, 10, 117 }, { 21, 10, 28 }, { 6, 10, 297 }, { 7, 10, 793 }, + { 11, 10, 938 }, { 8, 0, 438 }, { 11, 0, 363 }, { 7, 10, 464 }, + { 11, 10, 105 }, { 12, 10, 231 }, { 14, 10, 386 }, { 15, 10, 102 }, + { 20, 10, 75 }, { 5, 11, 16 }, { 6, 11, 86 }, { 6, 11, 603 }, + { 7, 11, 292 }, { 7, 11, 561 }, { 8, 11, 257 }, { 8, 11, 382 }, + { 9, 11, 721 }, { 9, 11, 778 }, { 11, 11, 581 }, { 12, 11, 466 }, + { 6, 0, 717 }, { 4, 11, 486 }, { 5, 11, 491 }, { 4, 0, 875 }, + { 4, 11, 72 }, { 6, 11, 265 }, { 7, 11, 847 }, { 4, 0, 237 }, + { 7, 0, 514 }, { 6, 0, 392 }, { 7, 0, 65 }, { 7, 0, 2019 }, + { 12, 11, 261 }, { 7, 11, 922 }, { 9, 11, 404 }, { 12, 0, 563 }, + { 14, 0, 101 }, { 18, 0, 129 }, { 7, 10, 1010 }, { 11, 10, 733 }, + { 11, 10, 759 }, { 13, 10, 34 }, { 18, 10, 45 }, { 7, 10, 1656 }, + { 9, 10, 369 }, { 10, 10, 338 }, { 10, 10, 490 }, { 11, 10, 154 }, + { 11, 10, 545 }, { 11, 10, 775 }, { 13, 10, 77 }, { 13, 10, 274 }, + { 4, 0, 444 }, { 10, 0, 146 }, { 12, 0, 9 }, { 11, 11, 163 }, + { 7, 0, 1260 }, { 7, 0, 1790 }, { 9, 0, 222 }, { 10, 0, 43 }, + { 11, 0, 900 }, { 9, 11, 234 }, { 10, 0, 971 }, { 9, 0, 761 }, + { 6, 0, 699 }, { 8, 11, 434 }, { 6, 0, 1116 }, { 7, 0, 1366 }, + { 5, 10, 20 }, { 6, 11, 197 }, { 6, 10, 298 }, { 7, 10, 659 }, + { 8, 11, 205 }, { 9, 10, 219 }, { 4, 11, 490 }, { 11, 11, 820 }, + { 22, 11, 51 }, { 7, 10, 1440 }, { 11, 10, 854 }, { 11, 10, 872 }, + { 11, 10, 921 }, { 12, 10, 551 }, { 13, 10, 472 }, { 14, 10, 367 }, + { 12, 11, 13 }, { 4, 0, 829 }, { 12, 0, 242 }, { 4, 10, 439 }, + { 8, 10, 669 }, { 6, 0, 593 }, { 6, 11, 452 }, { 7, 11, 312 }, + { 10, 11, 219 }, { 4, 11, 333 }, { 9, 11, 176 }, { 12, 11, 353 }, + { 13, 11, 187 }, { 7, 0, 36 }, { 8, 0, 201 }, { 8, 0, 605 }, + { 12, 0, 224 }, { 4, 10, 233 }, { 6, 0, 1430 }, { 6, 0, 1806 }, + { 4, 0, 523 }, { 5, 0, 638 }, { 6, 0, 1889 }, { 9, 0, 958 }, + { 9, 0, 971 }, { 9, 0, 976 }, { 12, 0, 796 }, { 12, 0, 799 }, + { 12, 0, 808 }, { 12, 0, 835 }, { 12, 0, 836 }, { 12, 0, 914 }, + { 12, 0, 946 }, { 15, 0, 216 }, { 15, 0, 232 }, { 18, 0, 183 }, + { 18, 0, 187 }, { 18, 0, 194 }, { 18, 0, 212 }, { 18, 0, 232 }, + { 21, 0, 49 }, { 4, 10, 482 }, { 6, 0, 827 }, { 6, 0, 1434 }, + { 7, 10, 346 }, { 6, 0, 2043 }, { 6, 0, 242 }, { 7, 0, 227 }, + { 7, 0, 1581 }, { 8, 0, 104 }, { 9, 0, 113 }, { 9, 0, 220 }, + { 9, 0, 427 }, { 10, 0, 136 }, { 10, 0, 239 }, { 11, 0, 579 }, + { 11, 0, 1023 }, { 13, 0, 4 }, { 13, 0, 204 }, { 13, 0, 316 }, + { 20, 0, 86 }, { 6, 11, 1685 }, { 7, 0, 148 }, { 8, 0, 284 }, + { 13, 0, 63 }, { 14, 0, 10 }, { 7, 11, 584 }, { 6, 0, 1249 }, + { 7, 0, 861 }, { 7, 10, 334 }, { 5, 10, 795 }, { 6, 10, 1741 }, + { 9, 11, 70 }, { 4, 0, 807 }, { 7, 11, 135 }, { 8, 11, 7 }, + { 8, 11, 62 }, { 9, 11, 243 }, { 10, 11, 658 }, { 10, 11, 697 }, + { 11, 11, 456 }, { 11, 11, 756 }, { 9, 11, 395 }, { 10, 11, 79 }, + { 9, 11, 108 }, { 19, 0, 94 }, { 8, 0, 494 }, { 7, 11, 631 }, + { 7, 10, 622 }, { 7, 0, 1510 }, { 7, 10, 1750 }, { 4, 10, 203 }, + { 7, 10, 1936 }, { 7, 11, 406 }, { 7, 11, 459 }, { 8, 11, 606 }, + { 11, 11, 726 }, { 7, 0, 1306 }, { 8, 0, 505 }, { 9, 0, 482 }, + { 10, 0, 126 }, { 11, 0, 225 }, { 12, 0, 347 }, { 12, 0, 449 }, + { 13, 0, 19 }, { 14, 0, 218 }, { 14, 0, 435 }, { 5, 0, 268 }, + { 10, 0, 764 }, { 12, 0, 120 }, { 13, 0, 39 }, { 17, 0, 127 }, + { 14, 11, 68 }, { 11, 10, 678 }, { 12, 10, 307 }, { 12, 11, 268 }, + { 12, 11, 640 }, { 14, 11, 119 }, { 7, 10, 2044 }, { 5, 11, 612 }, + { 4, 11, 372 }, { 7, 11, 482 }, { 8, 11, 158 }, { 9, 11, 602 }, + { 9, 11, 615 }, { 10, 11, 245 }, { 10, 11, 678 }, { 10, 11, 744 }, + { 11, 11, 248 }, { 11, 11, 806 }, { 7, 10, 311 }, { 9, 10, 308 }, + { 12, 10, 255 }, { 4, 0, 384 }, { 7, 0, 1022 }, { 5, 11, 854 }, + { 7, 11, 1991 }, { 7, 10, 1266 }, { 4, 10, 400 }, { 5, 10, 267 }, + { 7, 10, 232 }, { 7, 0, 1703 }, { 9, 0, 159 }, { 11, 0, 661 }, + { 12, 0, 603 }, { 4, 0, 964 }, { 14, 0, 438 }, { 14, 0, 444 }, + { 14, 0, 456 }, { 22, 0, 60 }, { 22, 0, 63 }, { 9, 11, 106 }, + { 9, 11, 163 }, { 9, 11, 296 }, { 10, 11, 167 }, { 10, 11, 172 }, + { 10, 11, 777 }, { 11, 11, 16 }, { 8, 0, 583 }, { 4, 0, 515 }, + { 8, 0, 632 }, { 8, 0, 697 }, { 9, 0, 854 }, { 5, 11, 195 }, + { 7, 11, 1685 }, { 6, 0, 1123 }, { 6, 0, 1365 }, { 6, 11, 328 }, + { 7, 11, 1997 }, { 8, 11, 730 }, { 11, 11, 1006 }, { 4, 0, 136 }, + { 5, 0, 551 }, { 6, 0, 1782 }, { 7, 0, 1287 }, { 9, 0, 44 }, + { 10, 0, 552 }, { 10, 0, 642 }, { 11, 0, 839 }, { 12, 0, 274 }, + { 12, 0, 275 }, { 12, 0, 372 }, { 13, 0, 91 }, { 14, 0, 125 }, + { 5, 11, 751 }, { 11, 11, 797 }, { 12, 11, 203 }, { 5, 0, 732 }, + { 7, 0, 679 }, { 8, 0, 313 }, { 4, 10, 100 }, { 7, 11, 821 }, + { 10, 0, 361 }, { 14, 0, 316 }, { 6, 0, 595 }, { 6, 0, 147 }, + { 7, 0, 886 }, { 9, 0, 753 }, { 10, 0, 268 }, { 5, 10, 362 }, + { 5, 10, 443 }, { 6, 10, 318 }, { 7, 10, 1019 }, { 11, 10, 623 }, + { 5, 10, 463 }, { 8, 10, 296 }, { 4, 10, 454 }, { 5, 11, 950 }, + { 5, 11, 994 }, { 6, 11, 351 }, { 10, 0, 137 }, { 5, 10, 48 }, + { 5, 10, 404 }, { 6, 10, 557 }, { 7, 10, 458 }, { 8, 10, 597 }, + { 10, 10, 455 }, { 10, 10, 606 }, { 11, 10, 49 }, { 11, 10, 548 }, + { 12, 10, 476 }, { 13, 10, 18 }, { 13, 10, 450 }, { 5, 0, 414 }, + { 7, 0, 1762 }, { 5, 11, 421 }, { 7, 11, 47 }, { 5, 10, 442 }, + { 7, 10, 1984 }, { 6, 0, 599 }, { 6, 0, 1749 }, { 6, 0, 1627 }, + { 4, 0, 488 }, { 4, 11, 350 }, { 9, 11, 751 }, { 4, 0, 83 }, + { 12, 0, 676 }, { 5, 11, 967 }, { 7, 0, 1639 }, { 5, 10, 55 }, + { 12, 10, 161 }, { 4, 11, 473 }, { 7, 11, 623 }, { 8, 11, 808 }, + { 9, 11, 871 }, { 9, 11, 893 }, { 11, 11, 38 }, { 11, 11, 431 }, + { 12, 11, 112 }, { 12, 11, 217 }, { 12, 11, 243 }, { 12, 11, 562 }, + { 12, 11, 683 }, { 13, 11, 141 }, { 13, 11, 197 }, { 13, 11, 227 }, + { 13, 11, 406 }, { 13, 11, 487 }, { 14, 11, 156 }, { 14, 11, 203 }, + { 14, 11, 224 }, { 14, 11, 256 }, { 18, 11, 58 }, { 22, 11, 0 }, + { 5, 10, 450 }, { 7, 11, 736 }, { 11, 11, 264 }, { 6, 0, 278 }, + { 4, 11, 222 }, { 7, 11, 286 }, { 8, 11, 629 }, { 7, 10, 869 }, + { 12, 0, 97 }, { 16, 0, 14 }, { 6, 0, 1085 }, { 4, 10, 213 }, + { 7, 10, 223 }, { 8, 10, 80 }, { 7, 0, 388 }, { 7, 0, 644 }, + { 11, 0, 781 }, { 4, 0, 849 }, { 7, 0, 229 }, { 8, 0, 59 }, + { 9, 0, 190 }, { 10, 0, 378 }, { 12, 0, 191 }, { 7, 10, 381 }, + { 7, 10, 806 }, { 7, 10, 820 }, { 8, 10, 354 }, { 8, 10, 437 }, + { 8, 10, 787 }, { 9, 10, 657 }, { 10, 10, 58 }, { 10, 10, 339 }, + { 10, 10, 749 }, { 11, 10, 914 }, { 12, 10, 162 }, { 13, 10, 75 }, + { 14, 10, 106 }, { 14, 10, 198 }, { 14, 10, 320 }, { 14, 10, 413 }, + { 18, 10, 43 }, { 13, 11, 306 }, { 8, 10, 747 }, { 6, 0, 1115 }, + { 16, 0, 94 }, { 16, 0, 108 }, { 8, 11, 146 }, { 6, 0, 700 }, + { 6, 0, 817 }, { 6, 0, 1002 }, { 5, 10, 692 }, { 4, 11, 465 }, + { 7, 11, 1663 }, { 6, 10, 191 }, { 6, 0, 1414 }, { 7, 11, 913 }, + { 4, 0, 660 }, { 7, 0, 1035 }, { 10, 0, 737 }, { 6, 10, 162 }, + { 7, 10, 1960 }, { 8, 10, 831 }, { 4, 10, 706 }, { 7, 0, 690 }, + { 9, 0, 217 }, { 9, 0, 587 }, { 12, 0, 521 }, { 10, 10, 426 }, + { 7, 10, 1235 }, { 6, 11, 82 }, { 7, 11, 138 }, { 7, 11, 517 }, + { 9, 11, 673 }, { 11, 11, 238 }, { 10, 0, 272 }, { 5, 11, 495 }, + { 7, 11, 834 }, { 9, 11, 733 }, { 11, 11, 378 }, { 6, 0, 1744 }, + { 4, 0, 1011 }, { 7, 11, 828 }, { 14, 11, 116 }, { 4, 0, 733 }, + { 9, 0, 194 }, { 10, 0, 92 }, { 11, 0, 198 }, { 12, 0, 84 }, + { 13, 0, 128 }, { 5, 11, 559 }, { 10, 0, 57 }, { 10, 0, 277 }, + { 6, 11, 21 }, { 6, 11, 1737 }, { 7, 11, 1444 }, { 8, 11, 224 }, + { 4, 10, 204 }, { 9, 10, 902 }, { 8, 10, 833 }, { 11, 0, 348 }, + { 12, 0, 99 }, { 18, 0, 1 }, { 18, 0, 11 }, { 19, 0, 4 }, + { 7, 10, 366 }, { 9, 10, 287 }, { 12, 10, 199 }, { 12, 10, 556 }, + { 12, 10, 577 }, { 6, 0, 1981 }, { 8, 0, 936 }, { 21, 0, 33 }, + { 22, 0, 40 }, { 5, 11, 519 }, { 10, 11, 204 }, { 5, 10, 356 }, + { 7, 10, 224 }, { 6, 0, 775 }, { 7, 0, 306 }, { 7, 10, 630 }, + { 9, 10, 567 }, { 11, 10, 150 }, { 11, 10, 444 }, { 13, 10, 119 }, + { 5, 0, 979 }, { 6, 10, 539 }, { 5, 0, 611 }, { 4, 11, 402 }, + { 7, 11, 1679 }, { 5, 0, 178 }, { 7, 11, 2 }, { 8, 11, 323 }, + { 8, 11, 479 }, { 5, 11, 59 }, { 7, 11, 672 }, { 4, 0, 1010 }, + { 6, 0, 1969 }, { 10, 11, 237 }, { 5, 11, 412 }, { 18, 11, 34 }, + { 7, 11, 1740 }, { 18, 11, 48 }, { 6, 0, 664 }, { 11, 10, 814 }, + { 4, 11, 85 }, { 7, 11, 549 }, { 5, 11, 94 }, { 5, 11, 457 }, + { 4, 0, 390 }, { 6, 0, 1510 }, { 4, 10, 235 }, { 7, 10, 255 }, + { 4, 10, 194 }, { 5, 10, 584 }, { 6, 11, 11 }, { 6, 10, 384 }, + { 7, 11, 187 }, { 7, 10, 583 }, { 10, 10, 761 }, { 11, 10, 760 }, + { 11, 10, 851 }, { 4, 11, 522 }, { 11, 11, 802 }, { 7, 0, 493 }, + { 10, 11, 776 }, { 13, 11, 345 }, { 14, 11, 425 }, { 18, 0, 37 }, + { 4, 11, 52 }, { 7, 11, 661 }, { 6, 0, 724 }, { 6, 0, 829 }, + { 5, 11, 520 }, { 5, 10, 562 }, { 4, 11, 281 }, { 5, 11, 38 }, + { 7, 11, 194 }, { 7, 11, 668 }, { 7, 11, 1893 }, { 9, 11, 397 }, + { 5, 10, 191 }, { 9, 10, 271 }, { 7, 0, 1537 }, { 14, 0, 96 }, + { 15, 0, 73 }, { 5, 0, 473 }, { 11, 0, 168 }, { 4, 10, 470 }, + { 6, 10, 153 }, { 7, 10, 1503 }, { 7, 10, 1923 }, { 10, 10, 701 }, + { 11, 10, 132 }, { 11, 10, 227 }, { 11, 10, 320 }, { 11, 10, 436 }, + { 11, 10, 525 }, { 11, 10, 855 }, { 12, 10, 41 }, { 12, 10, 286 }, + { 13, 10, 103 }, { 13, 10, 284 }, { 14, 10, 255 }, { 14, 10, 262 }, + { 15, 10, 117 }, { 15, 10, 127 }, { 5, 0, 105 }, { 5, 0, 438 }, + { 9, 0, 694 }, { 12, 0, 627 }, { 13, 0, 210 }, { 5, 10, 327 }, + { 6, 10, 552 }, { 7, 10, 1754 }, { 9, 10, 604 }, { 6, 0, 1256 }, + { 24, 0, 11 }, { 5, 11, 448 }, { 11, 11, 98 }, { 11, 11, 524 }, + { 7, 0, 1626 }, { 5, 10, 80 }, { 6, 10, 405 }, { 7, 10, 403 }, + { 7, 10, 1502 }, { 8, 10, 456 }, { 9, 10, 487 }, { 9, 10, 853 }, + { 9, 10, 889 }, { 10, 10, 309 }, { 11, 10, 721 }, { 11, 10, 994 }, + { 12, 10, 430 }, { 13, 10, 165 }, { 14, 11, 16 }, { 18, 11, 44 }, + { 4, 0, 779 }, { 8, 0, 25 }, { 10, 0, 826 }, { 4, 10, 453 }, + { 5, 10, 887 }, { 6, 10, 535 }, { 8, 10, 6 }, { 8, 10, 543 }, + { 8, 10, 826 }, { 9, 11, 461 }, { 12, 11, 632 }, { 4, 0, 308 }, + { 7, 0, 741 }, { 4, 0, 671 }, { 7, 0, 150 }, { 8, 0, 649 }, + { 8, 0, 1020 }, { 9, 0, 99 }, { 6, 11, 336 }, { 8, 11, 552 }, + { 9, 11, 285 }, { 10, 11, 99 }, { 11, 11, 568 }, { 6, 0, 521 }, + { 5, 0, 339 }, { 14, 0, 3 }, { 15, 0, 41 }, { 15, 0, 166 }, + { 19, 0, 66 }, { 6, 11, 423 }, { 7, 11, 665 }, { 7, 11, 1210 }, + { 9, 11, 218 }, { 13, 11, 222 }, { 6, 0, 543 }, { 5, 10, 101 }, + { 5, 11, 256 }, { 6, 10, 88 }, { 7, 10, 1677 }, { 9, 10, 100 }, + { 10, 10, 677 }, { 14, 10, 169 }, { 14, 10, 302 }, { 14, 10, 313 }, + { 15, 10, 48 }, { 15, 10, 84 }, { 4, 10, 310 }, { 7, 10, 708 }, + { 7, 10, 996 }, { 9, 10, 795 }, { 10, 10, 390 }, { 10, 10, 733 }, + { 11, 10, 451 }, { 12, 10, 249 }, { 14, 10, 115 }, { 14, 10, 286 }, + { 15, 10, 100 }, { 5, 10, 587 }, { 13, 11, 417 }, { 14, 11, 129 }, + { 15, 11, 15 }, { 6, 0, 1358 }, { 8, 11, 554 }, { 4, 10, 498 }, + { 7, 10, 217 }, { 8, 10, 140 }, { 10, 10, 610 }, { 7, 11, 989 }, + { 7, 11, 634 }, { 6, 0, 155 }, { 12, 0, 234 }, { 7, 11, 462 }, + { 4, 11, 618 }, { 6, 0, 1628 }, { 4, 0, 766 }, { 4, 11, 339 }, + { 5, 10, 905 }, { 7, 11, 259 }, { 7, 0, 829 }, { 4, 11, 759 }, + { 13, 11, 169 }, { 7, 0, 1445 }, { 4, 10, 456 }, { 7, 10, 358 }, + { 7, 10, 1637 }, { 8, 10, 643 }, { 11, 10, 483 }, { 5, 0, 486 }, + { 7, 0, 1349 }, { 5, 11, 688 }, { 7, 11, 712 }, { 7, 0, 1635 }, + { 8, 0, 17 }, { 10, 0, 217 }, { 10, 0, 295 }, { 12, 0, 2 }, + { 12, 11, 2 }, { 10, 0, 558 }, { 22, 10, 56 }, { 4, 11, 278 }, + { 5, 11, 465 }, { 7, 11, 1367 }, { 8, 11, 482 }, { 5, 10, 535 }, + { 6, 0, 1362 }, { 6, 0, 1461 }, { 10, 11, 274 }, { 10, 11, 625 }, + { 11, 11, 530 }, { 5, 0, 599 }, { 5, 11, 336 }, { 6, 11, 341 }, + { 6, 11, 478 }, { 6, 11, 1763 }, { 8, 11, 386 }, { 7, 10, 1748 }, + { 9, 11, 151 }, { 6, 0, 1376 }, { 5, 10, 539 }, { 7, 11, 73 }, + { 7, 11, 1971 }, { 11, 11, 283 }, { 9, 0, 93 }, { 11, 0, 474 }, + { 6, 10, 91 }, { 7, 10, 435 }, { 6, 0, 447 }, { 5, 11, 396 }, + { 6, 11, 501 }, { 4, 10, 16 }, { 5, 10, 316 }, { 5, 10, 842 }, + { 6, 10, 370 }, { 6, 10, 1778 }, { 8, 10, 166 }, { 11, 10, 812 }, + { 12, 10, 206 }, { 12, 10, 351 }, { 14, 10, 418 }, { 16, 10, 15 }, + { 16, 10, 34 }, { 18, 10, 3 }, { 19, 10, 3 }, { 19, 10, 7 }, + { 20, 10, 4 }, { 21, 10, 21 }, { 7, 0, 577 }, { 7, 0, 1432 }, + { 9, 0, 475 }, { 9, 0, 505 }, { 9, 0, 526 }, { 9, 0, 609 }, + { 9, 0, 689 }, { 9, 0, 726 }, { 9, 0, 735 }, { 9, 0, 738 }, + { 10, 0, 556 }, { 10, 0, 674 }, { 10, 0, 684 }, { 11, 0, 89 }, + { 11, 0, 202 }, { 11, 0, 272 }, { 11, 0, 380 }, { 11, 0, 415 }, + { 11, 0, 505 }, { 11, 0, 537 }, { 11, 0, 550 }, { 11, 0, 562 }, + { 11, 0, 640 }, { 11, 0, 667 }, { 11, 0, 688 }, { 11, 0, 847 }, + { 11, 0, 927 }, { 11, 0, 930 }, { 11, 0, 940 }, { 12, 0, 144 }, + { 12, 0, 325 }, { 12, 0, 329 }, { 12, 0, 389 }, { 12, 0, 403 }, + { 12, 0, 451 }, { 12, 0, 515 }, { 12, 0, 604 }, { 12, 0, 616 }, + { 12, 0, 626 }, { 13, 0, 66 }, { 13, 0, 131 }, { 13, 0, 167 }, + { 13, 0, 236 }, { 13, 0, 368 }, { 13, 0, 411 }, { 13, 0, 434 }, + { 13, 0, 453 }, { 13, 0, 461 }, { 13, 0, 474 }, { 14, 0, 59 }, + { 14, 0, 60 }, { 14, 0, 139 }, { 14, 0, 152 }, { 14, 0, 276 }, + { 14, 0, 353 }, { 14, 0, 402 }, { 15, 0, 28 }, { 15, 0, 81 }, + { 15, 0, 123 }, { 15, 0, 152 }, { 18, 0, 136 }, { 20, 0, 88 }, + { 4, 11, 929 }, { 5, 11, 799 }, { 8, 11, 46 }, { 14, 0, 307 }, + { 4, 0, 609 }, { 7, 0, 756 }, { 9, 0, 544 }, { 11, 0, 413 }, + { 16, 0, 25 }, { 10, 0, 687 }, { 7, 10, 619 }, { 10, 10, 547 }, + { 11, 10, 122 }, { 12, 10, 601 }, { 4, 0, 930 }, { 5, 0, 947 }, + { 5, 0, 939 }, { 14, 0, 21 }, { 4, 11, 892 }, { 5, 11, 770 }, + { 5, 0, 962 }, { 5, 0, 651 }, { 8, 0, 170 }, { 9, 0, 61 }, + { 9, 0, 63 }, { 10, 0, 23 }, { 10, 0, 37 }, { 10, 0, 834 }, + { 11, 0, 4 }, { 11, 0, 187 }, { 11, 0, 281 }, { 11, 0, 503 }, + { 11, 0, 677 }, { 12, 0, 96 }, { 12, 0, 130 }, { 12, 0, 244 }, + { 14, 0, 5 }, { 14, 0, 40 }, { 14, 0, 162 }, { 14, 0, 202 }, + { 18, 0, 133 }, { 4, 0, 406 }, { 5, 0, 579 }, { 12, 0, 492 }, + { 22, 0, 15 }, { 7, 11, 158 }, { 7, 0, 597 }, { 4, 0, 981 }, + { 4, 10, 888 }, { 4, 10, 149 }, { 10, 10, 368 }, { 4, 0, 545 }, + { 4, 10, 154 }, { 7, 10, 1134 }, { 8, 10, 105 }, { 7, 11, 2001 }, + { 6, 0, 1558 }, { 4, 10, 31 }, { 6, 10, 429 }, { 7, 10, 962 }, + { 9, 10, 458 }, { 11, 10, 691 }, { 4, 10, 312 }, { 7, 10, 1642 }, + { 6, 0, 17 }, { 6, 0, 1304 }, { 7, 0, 16 }, { 7, 0, 1001 }, + { 9, 0, 886 }, { 10, 0, 489 }, { 10, 0, 800 }, { 11, 0, 782 }, + { 12, 0, 320 }, { 13, 0, 467 }, { 14, 0, 145 }, { 14, 0, 387 }, + { 15, 0, 119 }, { 7, 0, 1982 }, { 17, 0, 17 }, { 7, 11, 1461 }, + { 12, 11, 91 }, { 4, 10, 236 }, { 4, 11, 602 }, { 10, 0, 907 }, + { 8, 0, 110 }, { 7, 0, 272 }, { 19, 0, 53 }, { 5, 10, 836 }, + { 5, 10, 857 }, { 6, 10, 1680 }, { 5, 0, 458 }, { 7, 11, 1218 }, + { 8, 11, 303 }, { 7, 0, 1983 }, { 8, 0, 0 }, { 8, 0, 171 }, + { 9, 0, 120 }, { 9, 0, 732 }, { 10, 0, 473 }, { 11, 0, 656 }, + { 11, 0, 998 }, { 18, 0, 0 }, { 18, 0, 2 }, { 19, 0, 21 }, + { 10, 10, 68 }, { 11, 10, 494 }, { 9, 11, 662 }, { 4, 11, 13 }, + { 5, 11, 567 }, { 7, 11, 1498 }, { 9, 11, 124 }, { 11, 11, 521 }, + { 12, 11, 405 }, { 4, 10, 81 }, { 11, 10, 867 }, { 7, 11, 1006 }, + { 7, 11, 800 }, { 7, 11, 1783 }, { 10, 11, 12 }, { 9, 0, 295 }, + { 10, 0, 443 }, { 5, 10, 282 }, { 8, 10, 650 }, { 9, 10, 907 }, + { 4, 11, 735 }, { 4, 11, 170 }, { 4, 10, 775 }, { 7, 11, 323 }, + { 6, 0, 1844 }, { 10, 0, 924 }, { 11, 11, 844 }, { 12, 11, 104 }, + { 12, 11, 625 }, { 5, 11, 304 }, { 7, 11, 1403 }, { 12, 11, 498 }, + { 6, 0, 1232 }, { 4, 0, 519 }, { 10, 0, 70 }, { 12, 0, 26 }, + { 14, 0, 17 }, { 14, 0, 178 }, { 15, 0, 34 }, { 21, 0, 12 }, + { 4, 0, 993 }, { 4, 11, 148 }, { 5, 11, 742 }, { 6, 0, 31 }, + { 7, 0, 491 }, { 7, 0, 530 }, { 8, 0, 592 }, { 11, 0, 53 }, + { 11, 0, 779 }, { 12, 0, 167 }, { 12, 0, 411 }, { 14, 0, 14 }, + { 14, 0, 136 }, { 15, 0, 72 }, { 16, 0, 17 }, { 16, 0, 72 }, + { 5, 0, 907 }, { 6, 0, 733 }, { 5, 11, 111 }, { 4, 10, 71 }, + { 5, 10, 376 }, { 7, 10, 119 }, { 10, 10, 665 }, { 8, 0, 55 }, + { 8, 0, 430 }, { 8, 11, 430 }, { 4, 0, 208 }, { 5, 0, 106 }, + { 6, 0, 531 }, { 8, 0, 408 }, { 9, 0, 188 }, { 10, 0, 572 }, + { 12, 0, 56 }, { 11, 10, 827 }, { 14, 10, 34 }, { 15, 10, 148 }, + { 6, 0, 1693 }, { 5, 11, 444 }, { 4, 10, 479 }, { 12, 0, 441 }, + { 9, 0, 449 }, { 10, 0, 192 }, { 10, 0, 740 }, { 6, 0, 928 }, + { 4, 0, 241 }, { 7, 10, 607 }, { 8, 10, 99 }, { 8, 11, 123 }, + { 15, 11, 6 }, { 16, 11, 7 }, { 6, 11, 285 }, { 8, 11, 654 }, + { 11, 11, 749 }, { 12, 11, 190 }, { 12, 11, 327 }, { 13, 11, 120 }, + { 13, 11, 121 }, { 13, 11, 327 }, { 15, 11, 47 }, { 18, 11, 40 }, + { 4, 10, 41 }, { 5, 10, 74 }, { 7, 10, 1627 }, { 11, 10, 871 }, + { 12, 10, 619 }, { 7, 0, 1525 }, { 11, 10, 329 }, { 11, 10, 965 }, + { 12, 10, 241 }, { 14, 10, 354 }, { 15, 10, 22 }, { 20, 10, 63 }, + { 4, 0, 259 }, { 7, 11, 183 }, { 9, 10, 209 }, { 9, 10, 300 }, + { 5, 11, 937 }, { 7, 11, 100 }, { 5, 10, 98 }, { 4, 0, 173 }, + { 5, 0, 312 }, { 5, 0, 512 }, { 7, 0, 1285 }, { 13, 0, 185 }, + { 7, 0, 1603 }, { 7, 0, 1691 }, { 9, 0, 464 }, { 11, 0, 195 }, + { 12, 0, 279 }, { 12, 0, 448 }, { 14, 0, 11 }, { 19, 0, 102 }, + { 7, 0, 1113 }, { 5, 10, 984 }, { 4, 0, 452 }, { 5, 0, 583 }, + { 7, 0, 720 }, { 4, 0, 547 }, { 5, 0, 817 }, { 6, 0, 433 }, + { 7, 0, 593 }, { 7, 0, 1378 }, { 8, 0, 161 }, { 9, 0, 284 }, + { 10, 0, 313 }, { 11, 0, 886 }, { 8, 0, 722 }, { 4, 10, 182 }, + { 6, 10, 205 }, { 7, 10, 220 }, { 22, 0, 13 }, { 4, 10, 42 }, + { 9, 10, 205 }, { 9, 10, 786 }, { 10, 10, 659 }, { 6, 0, 289 }, + { 7, 0, 1670 }, { 12, 0, 57 }, { 23, 0, 4 }, { 4, 10, 635 }, + { 14, 0, 43 }, { 18, 0, 21 }, { 11, 10, 533 }, { 7, 0, 1694 }, + { 8, 0, 420 }, { 11, 0, 193 }, { 7, 0, 409 }, { 4, 10, 371 }, + { 4, 10, 272 }, { 7, 10, 836 }, { 5, 10, 825 }, { 6, 10, 1640 }, + { 5, 11, 251 }, { 5, 11, 956 }, { 8, 11, 268 }, { 9, 11, 214 }, + { 18, 11, 142 }, { 10, 0, 308 }, { 6, 0, 1863 }, { 13, 11, 37 }, + { 9, 10, 879 }, { 7, 10, 317 }, { 7, 10, 569 }, { 4, 11, 294 }, + { 6, 0, 790 }, { 5, 0, 1002 }, { 8, 0, 745 }, { 5, 11, 346 }, + { 5, 11, 711 }, { 8, 11, 390 }, { 7, 0, 289 }, { 5, 0, 504 }, + { 11, 0, 68 }, { 9, 10, 307 }, { 4, 0, 239 }, { 6, 0, 477 }, + { 7, 0, 1607 }, { 11, 0, 617 }, { 21, 0, 13 }, { 5, 0, 609 }, + { 5, 11, 624 }, { 5, 11, 783 }, { 7, 11, 1998 }, { 7, 11, 2047 }, + { 5, 10, 525 }, { 4, 0, 367 }, { 4, 11, 594 }, { 6, 0, 528 }, + { 5, 10, 493 }, { 4, 10, 174 }, { 7, 10, 911 }, { 8, 10, 417 }, + { 9, 10, 782 }, { 4, 0, 694 }, { 7, 0, 548 }, { 9, 0, 58 }, + { 4, 10, 32 }, { 5, 10, 215 }, { 6, 10, 269 }, { 7, 10, 1782 }, + { 7, 10, 1892 }, { 10, 10, 16 }, { 11, 10, 822 }, { 11, 10, 954 }, + { 13, 10, 481 }, { 12, 0, 687 }, { 7, 0, 1749 }, { 8, 10, 477 }, + { 4, 11, 569 }, { 5, 10, 308 }, { 7, 10, 1088 }, { 4, 0, 661 }, + { 10, 0, 1004 }, { 5, 11, 37 }, { 6, 11, 39 }, { 6, 11, 451 }, + { 7, 11, 218 }, { 7, 11, 667 }, { 7, 11, 1166 }, { 7, 11, 1687 }, + { 8, 11, 662 }, { 16, 11, 2 }, { 9, 0, 445 }, { 12, 0, 53 }, + { 13, 0, 492 }, { 5, 10, 126 }, { 8, 10, 297 }, { 9, 10, 366 }, + { 12, 10, 374 }, { 7, 10, 1551 }, { 11, 10, 361 }, { 20, 0, 74 }, + { 6, 11, 508 }, { 7, 0, 213 }, { 4, 10, 175 }, { 4, 10, 685 }, + { 6, 0, 760 }, { 6, 0, 834 }, { 6, 0, 1248 }, { 7, 11, 453 }, + { 7, 11, 635 }, { 7, 11, 796 }, { 8, 11, 331 }, { 9, 11, 328 }, + { 9, 11, 330 }, { 9, 11, 865 }, { 10, 11, 119 }, { 10, 11, 235 }, + { 11, 11, 111 }, { 11, 11, 129 }, { 11, 11, 240 }, { 12, 11, 31 }, + { 12, 11, 66 }, { 12, 11, 222 }, { 12, 11, 269 }, { 12, 11, 599 }, + { 12, 11, 689 }, { 13, 11, 186 }, { 13, 11, 364 }, { 14, 11, 345 }, + { 7, 0, 1672 }, { 11, 0, 189 }, { 5, 10, 797 }, { 5, 10, 565 }, + { 6, 0, 1548 }, { 6, 11, 98 }, { 7, 11, 585 }, { 7, 11, 702 }, + { 9, 0, 968 }, { 15, 0, 192 }, { 21, 0, 56 }, { 4, 10, 252 }, + { 6, 11, 37 }, { 7, 11, 299 }, { 7, 10, 1068 }, { 7, 11, 1666 }, + { 8, 11, 195 }, { 8, 11, 316 }, { 9, 11, 178 }, { 9, 11, 276 }, + { 9, 11, 339 }, { 9, 11, 536 }, { 10, 11, 102 }, { 10, 11, 362 }, + { 10, 10, 434 }, { 10, 11, 785 }, { 11, 11, 55 }, { 11, 11, 149 }, + { 11, 10, 228 }, { 11, 10, 426 }, { 11, 11, 773 }, { 13, 10, 231 }, + { 13, 11, 416 }, { 13, 11, 419 }, { 14, 11, 38 }, { 14, 11, 41 }, + { 14, 11, 210 }, { 18, 10, 106 }, { 20, 10, 87 }, { 4, 0, 751 }, + { 11, 0, 390 }, { 12, 0, 32 }, { 4, 0, 409 }, { 5, 0, 78 }, + { 11, 11, 458 }, { 12, 11, 15 }, { 12, 11, 432 }, { 7, 0, 1602 }, + { 10, 0, 257 }, { 10, 0, 698 }, { 11, 0, 544 }, { 11, 0, 585 }, + { 12, 0, 212 }, { 13, 0, 307 }, { 5, 10, 231 }, { 7, 10, 601 }, + { 9, 10, 277 }, { 9, 10, 674 }, { 10, 10, 178 }, { 10, 10, 418 }, + { 10, 10, 509 }, { 11, 10, 531 }, { 12, 10, 113 }, { 12, 10, 475 }, + { 13, 10, 99 }, { 14, 10, 428 }, { 6, 0, 473 }, { 17, 0, 105 }, + { 6, 0, 1949 }, { 15, 0, 156 }, { 5, 11, 645 }, { 7, 10, 1591 }, + { 16, 10, 43 }, { 7, 0, 1779 }, { 7, 10, 1683 }, { 4, 11, 290 }, + { 7, 11, 1356 }, { 6, 0, 763 }, { 6, 11, 70 }, { 7, 11, 1292 }, + { 10, 11, 762 }, { 11, 11, 288 }, { 14, 0, 29 }, { 12, 11, 428 }, + { 7, 0, 883 }, { 7, 11, 131 }, { 7, 11, 422 }, { 8, 11, 210 }, + { 12, 11, 573 }, { 6, 0, 488 }, { 4, 10, 399 }, { 5, 10, 119 }, + { 5, 10, 494 }, { 7, 10, 751 }, { 9, 10, 556 }, { 5, 0, 617 }, + { 4, 11, 936 }, { 11, 0, 50 }, { 7, 0, 1518 }, { 11, 0, 694 }, + { 9, 0, 785 }, { 4, 0, 546 }, { 7, 0, 2042 }, { 7, 11, 716 }, + { 13, 11, 97 }, { 13, 11, 251 }, { 4, 11, 653 }, { 17, 0, 22 }, + { 6, 0, 1016 }, { 4, 0, 313 }, { 5, 0, 577 }, { 8, 11, 657 }, + { 8, 0, 184 }, { 13, 0, 433 }, { 7, 0, 935 }, { 6, 0, 720 }, + { 9, 0, 114 }, { 18, 11, 80 }, { 12, 0, 186 }, { 12, 0, 292 }, + { 14, 0, 100 }, { 18, 0, 70 }, { 7, 10, 594 }, { 7, 10, 851 }, + { 7, 10, 1858 }, { 9, 10, 411 }, { 9, 10, 574 }, { 9, 10, 666 }, + { 9, 10, 737 }, { 10, 10, 346 }, { 10, 10, 712 }, { 11, 10, 246 }, + { 11, 10, 432 }, { 11, 10, 517 }, { 11, 10, 647 }, { 11, 10, 679 }, + { 11, 10, 727 }, { 12, 10, 304 }, { 12, 10, 305 }, { 12, 10, 323 }, + { 12, 10, 483 }, { 12, 10, 572 }, { 12, 10, 593 }, { 12, 10, 602 }, + { 13, 10, 95 }, { 13, 10, 101 }, { 13, 10, 171 }, { 13, 10, 315 }, + { 13, 10, 378 }, { 13, 10, 425 }, { 13, 10, 475 }, { 14, 10, 63 }, + { 14, 10, 380 }, { 14, 10, 384 }, { 15, 10, 133 }, { 18, 10, 112 }, + { 20, 10, 72 }, { 7, 10, 1093 }, { 7, 11, 1836 }, { 4, 10, 679 }, + { 9, 10, 203 }, { 11, 0, 402 }, { 12, 0, 109 }, { 12, 0, 431 }, + { 13, 0, 179 }, { 13, 0, 206 }, { 14, 0, 217 }, { 16, 0, 3 }, + { 20, 0, 53 }, { 7, 11, 1368 }, { 8, 11, 232 }, { 8, 11, 361 }, + { 10, 11, 682 }, { 10, 11, 742 }, { 9, 10, 714 }, { 5, 0, 886 }, + { 6, 0, 46 }, { 6, 0, 1790 }, { 7, 0, 14 }, { 7, 0, 732 }, + { 7, 0, 1654 }, { 8, 0, 95 }, { 8, 0, 327 }, { 8, 0, 616 }, + { 9, 0, 892 }, { 10, 0, 598 }, { 10, 0, 769 }, { 11, 0, 134 }, + { 11, 0, 747 }, { 12, 0, 378 }, { 14, 0, 97 }, { 9, 11, 534 }, + { 4, 0, 969 }, { 8, 10, 825 }, { 9, 11, 27 }, { 6, 0, 727 }, + { 14, 11, 12 }, { 5, 0, 1021 }, { 6, 0, 1190 }, { 6, 11, 1657 }, + { 5, 10, 143 }, { 5, 10, 769 }, { 6, 10, 1760 }, { 7, 10, 682 }, + { 7, 10, 1992 }, { 8, 10, 736 }, { 4, 0, 153 }, { 7, 11, 127 }, + { 5, 0, 798 }, { 4, 0, 587 }, { 6, 0, 598 }, { 7, 0, 42 }, + { 8, 0, 695 }, { 10, 0, 212 }, { 11, 0, 158 }, { 14, 0, 196 }, + { 17, 0, 85 }, { 5, 10, 860 }, { 6, 0, 1929 }, { 6, 0, 1933 }, + { 5, 0, 957 }, { 5, 0, 1008 }, { 9, 0, 577 }, { 12, 0, 141 }, + { 6, 10, 422 }, { 7, 10, 0 }, { 7, 10, 1544 }, { 8, 11, 364 }, + { 11, 10, 990 }, { 12, 10, 453 }, { 13, 10, 47 }, { 13, 10, 266 }, + { 6, 0, 1319 }, { 4, 0, 129 }, { 7, 0, 465 }, { 7, 0, 470 }, + { 7, 0, 1057 }, { 7, 0, 1201 }, { 9, 0, 755 }, { 11, 0, 906 }, + { 12, 0, 527 }, { 7, 0, 908 }, { 18, 0, 7 }, { 5, 0, 148 }, + { 8, 0, 450 }, { 5, 10, 515 }, { 9, 10, 131 }, { 7, 10, 1605 }, + { 11, 10, 962 }, { 18, 10, 139 }, { 4, 10, 646 }, { 6, 0, 1166 }, + { 4, 10, 396 }, { 7, 10, 728 }, { 9, 10, 117 }, { 13, 10, 202 }, + { 20, 10, 51 }, { 6, 10, 121 }, { 6, 10, 124 }, { 6, 10, 357 }, + { 7, 10, 1138 }, { 7, 10, 1295 }, { 8, 10, 162 }, { 11, 10, 655 }, + { 14, 0, 374 }, { 14, 11, 374 }, { 10, 0, 253 }, { 11, 0, 1003 }, + { 5, 11, 909 }, { 9, 11, 849 }, { 10, 11, 805 }, { 5, 10, 237 }, + { 7, 11, 525 }, { 7, 11, 1579 }, { 8, 11, 497 }, { 8, 11, 573 }, + { 9, 0, 46 }, { 4, 0, 879 }, { 6, 0, 806 }, { 7, 0, 1868 }, + { 6, 0, 1837 }, { 6, 0, 1846 }, { 6, 0, 730 }, { 6, 0, 881 }, + { 7, 0, 965 }, { 7, 0, 1460 }, { 7, 0, 1604 }, { 7, 11, 193 }, + { 7, 11, 397 }, { 7, 11, 1105 }, { 8, 11, 124 }, { 8, 11, 619 }, + { 9, 11, 305 }, { 10, 11, 264 }, { 11, 11, 40 }, { 12, 11, 349 }, + { 13, 11, 134 }, { 13, 11, 295 }, { 14, 11, 155 }, { 15, 11, 120 }, + { 18, 11, 105 }, { 8, 0, 506 }, { 15, 0, 10 }, { 4, 11, 262 }, + { 7, 11, 342 }, { 7, 10, 571 }, { 7, 10, 1877 }, { 10, 10, 366 }, + { 13, 11, 23 }, { 5, 11, 641 }, { 10, 0, 22 }, { 9, 10, 513 }, + { 10, 10, 39 }, { 12, 10, 122 }, { 12, 10, 187 }, { 7, 11, 1431 }, + { 22, 11, 49 }, { 4, 11, 99 }, { 6, 11, 250 }, { 6, 11, 346 }, + { 8, 11, 127 }, { 10, 11, 81 }, { 6, 0, 2014 }, { 8, 0, 928 }, + { 10, 0, 960 }, { 10, 0, 979 }, { 12, 0, 996 }, { 6, 0, 296 }, + { 4, 11, 915 }, { 5, 11, 75 }, { 9, 11, 517 }, { 10, 11, 470 }, + { 12, 11, 155 }, { 13, 11, 224 }, { 9, 10, 873 }, { 4, 0, 854 }, + { 12, 11, 18 }, { 6, 0, 587 }, { 7, 10, 107 }, { 7, 10, 838 }, + { 8, 10, 550 }, { 10, 10, 401 }, { 11, 0, 636 }, { 15, 0, 145 }, + { 17, 0, 34 }, { 19, 0, 50 }, { 23, 0, 20 }, { 11, 10, 588 }, + { 11, 10, 864 }, { 11, 10, 968 }, { 15, 10, 160 }, { 7, 11, 216 }, + { 7, 0, 982 }, { 10, 0, 32 }, { 15, 0, 56 }, { 5, 10, 768 }, + { 5, 11, 954 }, { 6, 11, 304 }, { 7, 11, 1114 }, { 8, 11, 418 }, + { 10, 11, 345 }, { 11, 11, 341 }, { 11, 11, 675 }, { 13, 11, 40 }, + { 9, 11, 410 }, { 11, 11, 425 }, { 8, 0, 941 }, { 5, 0, 435 }, + { 4, 10, 894 }, { 5, 0, 85 }, { 6, 0, 419 }, { 7, 0, 134 }, + { 7, 0, 305 }, { 7, 0, 361 }, { 7, 0, 1337 }, { 8, 0, 71 }, + { 12, 0, 519 }, { 12, 0, 688 }, { 7, 0, 740 }, { 5, 0, 691 }, + { 7, 0, 345 }, { 9, 0, 94 }, { 12, 0, 169 }, { 5, 0, 183 }, + { 6, 0, 582 }, { 10, 0, 679 }, { 12, 0, 435 }, { 6, 11, 14 }, + { 6, 0, 945 }, { 7, 0, 511 }, { 6, 11, 1708 }, { 5, 11, 113 }, + { 6, 11, 243 }, { 7, 11, 1865 }, { 11, 11, 161 }, { 16, 11, 37 }, + { 17, 11, 99 }, { 4, 11, 274 }, { 9, 0, 539 }, { 7, 0, 1993 }, + { 8, 0, 684 }, { 6, 10, 272 }, { 6, 0, 659 }, { 6, 0, 982 }, + { 4, 10, 9 }, { 5, 10, 128 }, { 7, 10, 368 }, { 11, 10, 480 }, + { 20, 10, 3 }, { 6, 0, 583 }, { 4, 0, 803 }, { 5, 0, 704 }, + { 4, 0, 179 }, { 5, 0, 198 }, { 5, 0, 697 }, { 7, 0, 347 }, + { 7, 0, 971 }, { 8, 0, 181 }, { 10, 0, 711 }, { 7, 11, 166 }, + { 8, 10, 682 }, { 4, 10, 2 }, { 7, 10, 545 }, { 7, 10, 894 }, + { 8, 11, 521 }, { 7, 0, 481 }, { 4, 0, 243 }, { 5, 0, 203 }, + { 7, 0, 19 }, { 7, 0, 71 }, { 7, 0, 113 }, { 10, 0, 405 }, + { 11, 0, 357 }, { 14, 0, 240 }, { 5, 11, 725 }, { 5, 11, 727 }, + { 7, 11, 1811 }, { 6, 0, 826 }, { 9, 11, 304 }, { 7, 0, 1450 }, + { 11, 0, 99 }, { 5, 11, 654 }, { 6, 0, 492 }, { 5, 0, 134 }, + { 6, 0, 408 }, { 6, 0, 495 }, { 7, 0, 1593 }, { 6, 11, 273 }, + { 10, 11, 188 }, { 13, 11, 377 }, { 18, 11, 77 }, { 9, 10, 769 }, + { 12, 10, 185 }, { 7, 11, 410 }, { 14, 0, 4 }, { 4, 0, 665 }, + { 6, 11, 1785 }, { 4, 0, 248 }, { 7, 0, 137 }, { 9, 0, 349 }, + { 5, 10, 530 }, { 14, 10, 113 }, { 7, 0, 1270 }, { 11, 0, 612 }, + { 4, 11, 780 }, { 5, 0, 371 }, { 7, 0, 563 }, { 7, 0, 826 }, + { 6, 0, 1535 }, { 23, 0, 21 }, { 23, 0, 23 }, { 4, 0, 374 }, + { 7, 0, 547 }, { 7, 0, 1700 }, { 7, 0, 1833 }, { 11, 0, 858 }, + { 5, 10, 556 }, { 7, 11, 612 }, { 8, 11, 545 }, { 8, 11, 568 }, + { 8, 11, 642 }, { 9, 11, 717 }, { 10, 11, 541 }, { 10, 11, 763 }, + { 11, 11, 449 }, { 12, 11, 489 }, { 13, 11, 153 }, { 13, 11, 296 }, + { 14, 11, 138 }, { 14, 11, 392 }, { 15, 11, 50 }, { 16, 11, 6 }, + { 16, 11, 12 }, { 20, 11, 9 }, { 9, 0, 311 }, { 13, 0, 42 }, + { 8, 10, 16 }, { 12, 10, 568 }, { 6, 0, 1968 }, { 6, 0, 2027 }, + { 10, 0, 991 }, { 6, 0, 1647 }, { 7, 0, 1552 }, { 7, 0, 2010 }, + { 9, 0, 494 }, { 9, 0, 509 }, { 5, 11, 948 }, { 6, 10, 186 }, + { 9, 10, 426 }, { 6, 0, 769 }, { 6, 0, 642 }, { 4, 10, 585 }, + { 6, 0, 123 }, { 7, 0, 214 }, { 9, 0, 728 }, { 10, 0, 157 }, + { 11, 0, 346 }, { 11, 0, 662 }, { 15, 0, 106 }, { 14, 11, 381 }, + { 7, 0, 1435 }, { 4, 11, 532 }, { 5, 11, 706 }, { 7, 11, 662 }, + { 5, 11, 837 }, { 6, 11, 1651 }, { 4, 10, 93 }, { 5, 10, 252 }, + { 6, 10, 229 }, { 7, 10, 291 }, { 9, 10, 550 }, { 11, 10, 644 }, + { 20, 0, 79 }, { 9, 10, 749 }, { 6, 0, 1425 }, { 9, 10, 162 }, + { 4, 11, 362 }, { 7, 11, 52 }, { 7, 11, 303 }, { 12, 11, 166 }, + { 4, 10, 381 }, { 4, 11, 330 }, { 7, 11, 933 }, { 7, 11, 2012 }, + { 8, 11, 292 }, { 7, 11, 767 }, { 4, 0, 707 }, { 5, 0, 588 }, + { 6, 0, 393 }, { 13, 0, 106 }, { 18, 0, 49 }, { 19, 0, 41 }, + { 6, 0, 211 }, { 7, 0, 1690 }, { 11, 0, 486 }, { 12, 0, 369 }, + { 9, 11, 883 }, { 4, 11, 703 }, { 7, 11, 207 }, { 4, 0, 187 }, + { 5, 0, 184 }, { 5, 0, 690 }, { 7, 0, 1869 }, { 10, 0, 756 }, + { 11, 0, 783 }, { 4, 11, 571 }, { 6, 0, 1382 }, { 5, 0, 175 }, + { 6, 10, 77 }, { 6, 10, 157 }, { 7, 10, 974 }, { 7, 10, 1301 }, + { 7, 10, 1339 }, { 7, 10, 1490 }, { 7, 10, 1873 }, { 9, 10, 628 }, + { 6, 0, 1493 }, { 5, 11, 873 }, { 5, 11, 960 }, { 6, 0, 1007 }, + { 12, 11, 93 }, { 12, 11, 501 }, { 13, 11, 362 }, { 14, 11, 151 }, + { 15, 11, 40 }, { 15, 11, 59 }, { 16, 11, 46 }, { 17, 11, 25 }, + { 18, 11, 14 }, { 18, 11, 134 }, { 19, 11, 25 }, { 19, 11, 69 }, + { 20, 11, 16 }, { 20, 11, 19 }, { 20, 11, 66 }, { 21, 11, 23 }, + { 21, 11, 25 }, { 22, 11, 42 }, { 11, 10, 919 }, { 13, 10, 409 }, + { 6, 0, 219 }, { 5, 0, 582 }, { 6, 0, 1646 }, { 7, 0, 99 }, + { 7, 0, 1962 }, { 7, 0, 1986 }, { 8, 0, 515 }, { 8, 0, 773 }, + { 9, 0, 23 }, { 9, 0, 491 }, { 12, 0, 620 }, { 14, 0, 93 }, + { 5, 0, 851 }, { 5, 11, 33 }, { 6, 11, 470 }, { 7, 11, 1291 }, + { 6, 0, 1278 }, { 7, 11, 1882 }, { 7, 10, 1489 }, { 4, 0, 1000 }, + { 10, 0, 982 }, { 8, 0, 762 }, { 8, 0, 812 }, { 9, 0, 910 }, + { 6, 11, 47 }, { 7, 11, 90 }, { 7, 11, 664 }, { 7, 11, 830 }, + { 7, 11, 1380 }, { 7, 11, 2025 }, { 8, 11, 448 }, { 8, 11, 828 }, + { 4, 0, 98 }, { 4, 0, 940 }, { 6, 0, 1819 }, { 6, 0, 1834 }, + { 6, 0, 1841 }, { 7, 0, 1365 }, { 8, 0, 859 }, { 8, 0, 897 }, + { 8, 0, 918 }, { 9, 0, 422 }, { 9, 0, 670 }, { 10, 0, 775 }, + { 10, 0, 894 }, { 10, 0, 909 }, { 10, 0, 910 }, { 10, 0, 935 }, + { 11, 0, 210 }, { 12, 0, 750 }, { 12, 0, 755 }, { 13, 0, 26 }, + { 13, 0, 457 }, { 13, 0, 476 }, { 16, 0, 100 }, { 16, 0, 109 }, + { 18, 0, 173 }, { 18, 0, 175 }, { 8, 10, 398 }, { 9, 10, 681 }, + { 11, 10, 632 }, { 9, 11, 417 }, { 9, 11, 493 }, { 8, 10, 645 }, + { 10, 0, 906 }, { 6, 0, 1730 }, { 6, 10, 20 }, { 5, 11, 1019 }, + { 6, 0, 1185 }, { 10, 0, 40 }, { 8, 10, 769 }, { 9, 0, 147 }, + { 6, 11, 208 }, { 12, 0, 650 }, { 5, 0, 209 }, { 6, 0, 30 }, + { 11, 0, 56 }, { 11, 0, 305 }, { 4, 0, 553 }, { 10, 11, 344 }, + { 6, 11, 68 }, { 7, 11, 398 }, { 7, 11, 448 }, { 7, 11, 1629 }, + { 7, 11, 1813 }, { 8, 11, 387 }, { 8, 11, 442 }, { 9, 11, 710 }, + { 10, 11, 282 }, { 10, 11, 722 }, { 5, 0, 597 }, { 14, 0, 20 }, + { 14, 11, 20 }, { 7, 0, 1614 }, { 7, 10, 1757 }, { 4, 0, 150 }, + { 5, 0, 303 }, { 6, 0, 327 }, { 7, 10, 937 }, { 16, 0, 49 }, + { 7, 10, 1652 }, { 16, 11, 49 }, { 8, 0, 192 }, { 10, 0, 78 }, + { 13, 0, 359 }, { 7, 0, 786 }, { 15, 0, 134 }, { 6, 0, 1638 }, + { 7, 0, 79 }, { 7, 0, 496 }, { 9, 0, 138 }, { 10, 0, 336 }, + { 11, 0, 12 }, { 12, 0, 412 }, { 12, 0, 440 }, { 14, 0, 305 }, + { 8, 11, 491 }, { 4, 10, 579 }, { 5, 10, 226 }, { 5, 10, 323 }, + { 7, 10, 960 }, { 7, 0, 204 }, { 7, 0, 415 }, { 8, 0, 42 }, + { 10, 0, 85 }, { 11, 0, 564 }, { 4, 0, 614 }, { 4, 11, 403 }, + { 5, 11, 441 }, { 7, 11, 450 }, { 11, 11, 101 }, { 12, 11, 193 }, + { 13, 11, 430 }, { 7, 11, 1927 }, { 7, 11, 1330 }, { 4, 0, 3 }, + { 5, 0, 247 }, { 5, 0, 644 }, { 7, 0, 744 }, { 7, 0, 1207 }, + { 7, 0, 1225 }, { 7, 0, 1909 }, { 18, 0, 147 }, { 8, 0, 942 }, + { 4, 0, 1019 }, { 6, 0, 2023 }, { 5, 11, 679 }, { 5, 10, 973 }, + { 5, 0, 285 }, { 9, 0, 67 }, { 13, 0, 473 }, { 15, 0, 82 }, + { 7, 11, 328 }, { 9, 11, 326 }, { 23, 0, 8 }, { 6, 10, 135 }, + { 7, 10, 1176 }, { 7, 11, 1128 }, { 6, 0, 1309 }, { 7, 11, 1796 }, + { 7, 10, 314 }, { 4, 11, 574 }, { 7, 11, 350 }, { 7, 11, 1024 }, + { 8, 11, 338 }, { 9, 11, 677 }, { 10, 11, 808 }, { 11, 11, 508 }, + { 7, 11, 818 }, { 17, 11, 14 }, { 17, 11, 45 }, { 18, 11, 75 }, + { 20, 11, 18 }, { 18, 10, 4 }, { 7, 11, 1081 }, { 4, 0, 29 }, + { 6, 0, 532 }, { 7, 0, 1628 }, { 7, 0, 1648 }, { 9, 0, 350 }, + { 10, 0, 433 }, { 11, 0, 97 }, { 11, 0, 557 }, { 11, 0, 745 }, + { 12, 0, 289 }, { 12, 0, 335 }, { 12, 0, 348 }, { 12, 0, 606 }, + { 13, 0, 116 }, { 13, 0, 233 }, { 13, 0, 466 }, { 14, 0, 181 }, + { 14, 0, 209 }, { 14, 0, 232 }, { 14, 0, 236 }, { 14, 0, 300 }, + { 16, 0, 41 }, { 20, 0, 97 }, { 7, 0, 318 }, { 6, 10, 281 }, + { 8, 10, 282 }, { 8, 10, 480 }, { 8, 10, 499 }, { 9, 10, 198 }, + { 10, 10, 143 }, { 10, 10, 169 }, { 10, 10, 211 }, { 10, 10, 417 }, + { 10, 10, 574 }, { 11, 10, 147 }, { 11, 10, 395 }, { 12, 10, 75 }, + { 12, 10, 407 }, { 12, 10, 608 }, { 13, 10, 500 }, { 14, 10, 251 }, + { 7, 11, 1676 }, { 7, 11, 2037 }, { 7, 0, 1692 }, { 5, 0, 501 }, + { 7, 0, 1704 }, { 9, 0, 553 }, { 11, 0, 520 }, { 12, 0, 557 }, + { 13, 0, 249 }, { 6, 0, 1527 }, { 14, 0, 324 }, { 15, 0, 55 }, + { 15, 0, 80 }, { 14, 11, 324 }, { 15, 11, 55 }, { 15, 11, 80 }, + { 7, 10, 1776 }, { 8, 0, 988 }, { 9, 11, 297 }, { 4, 10, 419 }, + { 14, 0, 223 }, { 11, 11, 234 }, { 7, 0, 1123 }, { 12, 0, 508 }, + { 14, 0, 102 }, { 14, 0, 226 }, { 16, 0, 57 }, { 4, 10, 138 }, + { 7, 10, 1012 }, { 7, 10, 1280 }, { 9, 10, 76 }, { 7, 0, 1764 }, + { 5, 10, 29 }, { 12, 10, 638 }, { 6, 0, 2015 }, { 6, 0, 1599 }, + { 10, 11, 56 }, { 6, 11, 306 }, { 7, 11, 1140 }, { 7, 11, 1340 }, + { 8, 11, 133 }, { 10, 11, 449 }, { 11, 11, 1011 }, { 6, 10, 1710 }, + { 7, 10, 2038 }, { 7, 11, 1763 }, { 12, 11, 310 }, { 6, 0, 129 }, + { 4, 10, 17 }, { 5, 10, 23 }, { 7, 10, 995 }, { 11, 10, 383 }, + { 11, 10, 437 }, { 12, 10, 460 }, { 12, 10, 532 }, { 5, 11, 329 }, + { 8, 11, 260 }, { 5, 10, 862 }, { 4, 0, 534 }, { 6, 0, 811 }, + { 7, 0, 626 }, { 4, 11, 657 }, { 4, 0, 25 }, { 5, 0, 60 }, + { 6, 0, 504 }, { 7, 0, 614 }, { 7, 0, 1155 }, { 12, 0, 0 }, + { 24, 11, 7 }, { 7, 0, 1248 }, { 11, 0, 621 }, { 11, 0, 702 }, + { 9, 0, 321 }, { 8, 10, 70 }, { 12, 10, 171 }, { 13, 10, 272 }, + { 10, 10, 233 }, { 11, 10, 76 }, { 4, 0, 379 }, { 7, 0, 1397 }, + { 6, 10, 442 }, { 5, 11, 66 }, { 7, 11, 1896 }, { 8, 11, 288 }, + { 6, 11, 1643 }, { 6, 10, 1709 }, { 4, 11, 21 }, { 5, 11, 91 }, + { 5, 11, 570 }, { 5, 11, 648 }, { 5, 11, 750 }, { 5, 11, 781 }, + { 6, 11, 54 }, { 6, 11, 112 }, { 6, 11, 402 }, { 6, 11, 1732 }, + { 7, 11, 315 }, { 7, 11, 749 }, { 7, 11, 1347 }, { 7, 11, 1900 }, + { 9, 11, 78 }, { 9, 11, 508 }, { 10, 11, 611 }, { 11, 11, 510 }, + { 11, 11, 728 }, { 13, 11, 36 }, { 14, 11, 39 }, { 16, 11, 83 }, + { 17, 11, 124 }, { 20, 11, 30 }, { 4, 0, 118 }, { 6, 0, 274 }, + { 6, 0, 361 }, { 7, 0, 75 }, { 13, 0, 441 }, { 10, 11, 322 }, + { 10, 11, 719 }, { 11, 11, 407 }, { 19, 10, 119 }, { 12, 11, 549 }, + { 14, 11, 67 }, { 19, 11, 60 }, { 11, 10, 69 }, { 12, 10, 105 }, + { 12, 10, 117 }, { 13, 10, 213 }, { 14, 10, 13 }, { 14, 10, 62 }, + { 14, 10, 177 }, { 14, 10, 421 }, { 15, 10, 19 }, { 18, 10, 141 }, + { 9, 0, 841 }, { 9, 10, 309 }, { 7, 10, 608 }, { 7, 10, 976 }, + { 8, 11, 125 }, { 8, 11, 369 }, { 8, 11, 524 }, { 9, 10, 146 }, + { 10, 10, 206 }, { 10, 11, 486 }, { 10, 10, 596 }, { 11, 11, 13 }, + { 11, 11, 381 }, { 11, 11, 736 }, { 11, 11, 766 }, { 11, 11, 845 }, + { 13, 11, 114 }, { 13, 10, 218 }, { 13, 11, 292 }, { 14, 11, 47 }, + { 14, 10, 153 }, { 12, 0, 693 }, { 7, 11, 759 }, { 5, 0, 314 }, + { 6, 0, 221 }, { 7, 0, 419 }, { 10, 0, 650 }, { 11, 0, 396 }, + { 12, 0, 156 }, { 13, 0, 369 }, { 14, 0, 333 }, { 17, 0, 47 }, + { 6, 11, 1684 }, { 6, 11, 1731 }, { 7, 11, 356 }, { 7, 11, 1932 }, + { 8, 11, 54 }, { 8, 11, 221 }, { 9, 11, 225 }, { 9, 11, 356 }, + { 10, 11, 77 }, { 10, 11, 446 }, { 10, 11, 731 }, { 12, 11, 404 }, + { 13, 11, 491 }, { 4, 11, 375 }, { 4, 10, 518 }, { 7, 10, 1136 }, + { 4, 0, 913 }, { 4, 11, 411 }, { 11, 11, 643 }, { 12, 11, 115 }, + { 4, 11, 80 }, { 5, 11, 44 }, { 8, 10, 689 }, { 9, 10, 863 }, + { 10, 0, 880 }, { 4, 10, 18 }, { 7, 10, 145 }, { 7, 10, 444 }, + { 7, 10, 1278 }, { 8, 10, 49 }, { 8, 10, 400 }, { 9, 10, 71 }, + { 9, 10, 250 }, { 10, 10, 459 }, { 12, 10, 160 }, { 16, 10, 24 }, + { 8, 0, 475 }, { 5, 0, 1016 }, { 5, 11, 299 }, { 7, 11, 1083 }, + { 7, 0, 602 }, { 8, 0, 179 }, { 10, 0, 781 }, { 12, 0, 126 }, + { 6, 0, 329 }, { 10, 0, 111 }, { 7, 0, 1864 }, { 4, 11, 219 }, + { 7, 11, 1761 }, { 9, 11, 86 }, { 6, 0, 1888 }, { 6, 0, 1892 }, + { 6, 0, 1901 }, { 6, 0, 1904 }, { 9, 0, 953 }, { 9, 0, 985 }, + { 9, 0, 991 }, { 9, 0, 1001 }, { 12, 0, 818 }, { 12, 0, 846 }, + { 12, 0, 847 }, { 12, 0, 861 }, { 12, 0, 862 }, { 12, 0, 873 }, + { 12, 0, 875 }, { 12, 0, 877 }, { 12, 0, 879 }, { 12, 0, 881 }, + { 12, 0, 884 }, { 12, 0, 903 }, { 12, 0, 915 }, { 12, 0, 926 }, + { 12, 0, 939 }, { 15, 0, 182 }, { 15, 0, 219 }, { 15, 0, 255 }, + { 18, 0, 191 }, { 18, 0, 209 }, { 18, 0, 211 }, { 21, 0, 41 }, + { 5, 11, 328 }, { 7, 11, 918 }, { 9, 0, 780 }, { 12, 0, 82 }, + { 15, 0, 36 }, { 5, 10, 1010 }, { 5, 0, 821 }, { 6, 0, 1687 }, + { 5, 11, 514 }, { 4, 0, 956 }, { 6, 0, 1180 }, { 10, 0, 112 }, + { 5, 10, 87 }, { 7, 10, 313 }, { 7, 10, 1103 }, { 10, 10, 582 }, + { 11, 10, 389 }, { 11, 10, 813 }, { 12, 10, 385 }, { 13, 10, 286 }, + { 14, 10, 124 }, { 18, 10, 108 }, { 5, 0, 71 }, { 7, 0, 1407 }, + { 9, 0, 704 }, { 10, 0, 261 }, { 10, 0, 619 }, { 11, 0, 547 }, + { 11, 0, 619 }, { 15, 0, 157 }, { 4, 0, 531 }, { 5, 0, 455 }, + { 5, 11, 301 }, { 6, 11, 571 }, { 14, 11, 49 }, { 18, 11, 102 }, + { 4, 10, 267 }, { 6, 0, 385 }, { 7, 0, 2008 }, { 9, 0, 337 }, + { 10, 0, 517 }, { 5, 11, 726 }, { 5, 11, 364 }, { 4, 11, 76 }, + { 7, 11, 1550 }, { 9, 11, 306 }, { 9, 11, 430 }, { 9, 11, 663 }, + { 10, 11, 683 }, { 11, 11, 427 }, { 11, 11, 753 }, { 12, 11, 334 }, + { 12, 11, 442 }, { 14, 11, 258 }, { 14, 11, 366 }, { 15, 11, 131 }, + { 6, 0, 1865 }, { 6, 0, 1879 }, { 6, 0, 1881 }, { 6, 0, 1894 }, + { 6, 0, 1908 }, { 9, 0, 915 }, { 9, 0, 926 }, { 9, 0, 940 }, + { 9, 0, 943 }, { 9, 0, 966 }, { 9, 0, 980 }, { 9, 0, 989 }, + { 9, 0, 1005 }, { 9, 0, 1010 }, { 12, 0, 813 }, { 12, 0, 817 }, + { 12, 0, 840 }, { 12, 0, 843 }, { 12, 0, 855 }, { 12, 0, 864 }, + { 12, 0, 871 }, { 12, 0, 872 }, { 12, 0, 899 }, { 12, 0, 905 }, + { 12, 0, 924 }, { 15, 0, 171 }, { 15, 0, 181 }, { 15, 0, 224 }, + { 15, 0, 235 }, { 15, 0, 251 }, { 18, 0, 184 }, { 9, 11, 52 }, + { 5, 0, 16 }, { 6, 0, 86 }, { 6, 0, 603 }, { 7, 0, 292 }, + { 7, 0, 561 }, { 8, 0, 257 }, { 8, 0, 382 }, { 9, 0, 721 }, + { 9, 0, 778 }, { 11, 0, 581 }, { 12, 0, 466 }, { 4, 0, 486 }, + { 5, 0, 491 }, { 7, 10, 1121 }, { 4, 0, 72 }, { 6, 0, 265 }, + { 7, 0, 1300 }, { 7, 11, 1183 }, { 10, 10, 249 }, { 11, 10, 209 }, + { 4, 10, 561 }, { 9, 11, 519 }, { 4, 11, 656 }, { 4, 10, 760 }, + { 7, 11, 779 }, { 9, 10, 154 }, { 12, 10, 485 }, { 7, 11, 1793 }, + { 7, 11, 144 }, { 8, 10, 255 }, { 5, 0, 621 }, { 4, 10, 368 }, + { 7, 10, 641 }, { 7, 11, 1373 }, { 7, 11, 554 }, { 7, 11, 605 }, + { 13, 11, 10 }, { 9, 0, 234 }, { 5, 0, 815 }, { 6, 0, 1688 }, + { 6, 0, 1755 }, { 5, 11, 838 }, { 5, 11, 841 }, { 6, 11, 1649 }, + { 7, 0, 1987 }, { 7, 0, 2040 }, { 8, 0, 743 }, { 5, 11, 1012 }, + { 6, 0, 197 }, { 8, 0, 205 }, { 6, 0, 314 }, { 6, 11, 314 }, + { 16, 11, 53 }, { 6, 11, 251 }, { 7, 11, 365 }, { 7, 11, 1357 }, + { 7, 11, 1497 }, { 8, 11, 154 }, { 13, 11, 281 }, { 5, 11, 340 }, + { 6, 0, 452 }, { 7, 0, 312 }, { 10, 0, 219 }, { 10, 0, 589 }, + { 4, 0, 333 }, { 9, 0, 176 }, { 12, 0, 353 }, { 13, 0, 187 }, + { 9, 10, 92 }, { 19, 10, 91 }, { 6, 0, 1110 }, { 11, 0, 47 }, + { 11, 11, 495 }, { 6, 10, 525 }, { 8, 10, 806 }, { 9, 10, 876 }, + { 12, 10, 284 }, { 8, 11, 261 }, { 9, 11, 144 }, { 9, 11, 466 }, + { 10, 11, 370 }, { 12, 11, 470 }, { 13, 11, 144 }, { 14, 11, 348 }, + { 9, 11, 897 }, { 8, 0, 863 }, { 8, 0, 864 }, { 8, 0, 868 }, + { 8, 0, 884 }, { 10, 0, 866 }, { 10, 0, 868 }, { 10, 0, 873 }, + { 10, 0, 911 }, { 10, 0, 912 }, { 10, 0, 944 }, { 12, 0, 727 }, + { 6, 11, 248 }, { 9, 11, 546 }, { 10, 11, 535 }, { 11, 11, 681 }, + { 13, 11, 135 }, { 6, 0, 300 }, { 7, 0, 1515 }, { 6, 0, 1237 }, + { 11, 10, 958 }, { 5, 10, 594 }, { 12, 11, 250 }, { 6, 0, 1685 }, + { 6, 11, 567 }, { 7, 0, 135 }, { 8, 0, 7 }, { 8, 0, 62 }, + { 9, 0, 243 }, { 10, 0, 658 }, { 10, 0, 697 }, { 11, 0, 456 }, + { 11, 0, 756 }, { 9, 0, 395 }, { 10, 0, 79 }, { 6, 10, 1641 }, + { 8, 10, 820 }, { 4, 10, 302 }, { 7, 10, 1766 }, { 6, 11, 174 }, + { 7, 10, 1313 }, { 7, 0, 631 }, { 6, 10, 1674 }, { 6, 11, 395 }, + { 10, 0, 835 }, { 7, 0, 406 }, { 7, 0, 459 }, { 8, 0, 606 }, + { 11, 0, 726 }, { 6, 11, 617 }, { 6, 0, 979 }, { 6, 10, 389 }, + { 7, 10, 149 }, { 9, 10, 142 }, { 10, 10, 94 }, { 5, 11, 878 }, + { 5, 11, 972 }, { 6, 10, 8 }, { 7, 10, 1881 }, { 8, 10, 91 }, + { 8, 11, 511 }, { 5, 0, 612 }, { 4, 11, 351 }, { 4, 0, 372 }, + { 7, 0, 482 }, { 8, 0, 158 }, { 9, 0, 602 }, { 9, 0, 615 }, + { 10, 0, 245 }, { 10, 0, 678 }, { 10, 0, 744 }, { 11, 0, 248 }, + { 11, 0, 806 }, { 5, 0, 854 }, { 7, 0, 1991 }, { 4, 11, 286 }, + { 7, 11, 344 }, { 7, 11, 438 }, { 7, 11, 627 }, { 7, 11, 1516 }, + { 8, 11, 40 }, { 9, 11, 56 }, { 9, 11, 294 }, { 10, 11, 30 }, + { 10, 11, 259 }, { 11, 11, 969 }, { 18, 11, 148 }, { 7, 0, 1492 }, + { 5, 11, 259 }, { 7, 11, 414 }, { 7, 11, 854 }, { 14, 11, 107 }, + { 7, 10, 1746 }, { 6, 0, 833 }, { 6, 0, 998 }, { 7, 10, 24 }, + { 6, 0, 750 }, { 7, 0, 1739 }, { 4, 10, 503 }, { 7, 10, 1661 }, + { 5, 10, 130 }, { 7, 10, 1314 }, { 9, 10, 610 }, { 10, 10, 718 }, + { 11, 10, 601 }, { 11, 10, 819 }, { 11, 10, 946 }, { 12, 10, 536 }, + { 10, 10, 149 }, { 11, 10, 280 }, { 14, 10, 336 }, { 4, 11, 738 }, + { 7, 10, 1946 }, { 5, 0, 195 }, { 7, 0, 1685 }, { 7, 0, 1997 }, + { 8, 0, 730 }, { 11, 0, 1006 }, { 23, 11, 17 }, { 5, 11, 866 }, + { 14, 0, 463 }, { 14, 0, 470 }, { 22, 0, 61 }, { 5, 0, 751 }, + { 8, 0, 266 }, { 11, 0, 578 }, { 4, 10, 392 }, { 7, 10, 1597 }, + { 5, 10, 433 }, { 9, 10, 633 }, { 11, 10, 629 }, { 7, 0, 821 }, + { 6, 0, 715 }, { 6, 0, 1325 }, { 5, 11, 116 }, { 6, 0, 868 }, + { 4, 11, 457 }, { 6, 0, 959 }, { 6, 10, 234 }, { 10, 11, 199 }, + { 7, 0, 1053 }, { 7, 10, 1950 }, { 8, 10, 680 }, { 11, 10, 817 }, + { 19, 10, 88 }, { 7, 10, 1222 }, { 10, 10, 386 }, { 5, 0, 950 }, + { 5, 0, 994 }, { 6, 0, 351 }, { 6, 0, 1124 }, { 6, 0, 1081 }, + { 7, 0, 1595 }, { 6, 10, 5 }, { 11, 10, 249 }, { 12, 10, 313 }, + { 16, 10, 66 }, { 17, 10, 26 }, { 20, 0, 59 }, { 5, 11, 527 }, + { 6, 11, 189 }, { 7, 11, 859 }, { 5, 10, 963 }, { 6, 10, 1773 }, + { 11, 11, 104 }, { 11, 11, 554 }, { 15, 11, 60 }, { 15, 11, 125 }, + { 7, 0, 47 }, { 9, 0, 684 }, { 6, 11, 116 }, { 6, 0, 1606 }, + { 6, 0, 777 }, { 7, 0, 1020 }, { 8, 10, 509 }, { 8, 10, 792 }, + { 7, 0, 1094 }, { 4, 0, 350 }, { 5, 11, 487 }, { 4, 11, 86 }, + { 5, 11, 667 }, { 5, 11, 753 }, { 6, 11, 316 }, { 6, 11, 455 }, + { 7, 11, 946 }, { 7, 0, 1812 }, { 13, 0, 259 }, { 13, 0, 356 }, + { 14, 0, 242 }, { 19, 0, 114 }, { 4, 10, 931 }, { 5, 0, 967 }, + { 4, 0, 473 }, { 7, 0, 623 }, { 8, 0, 808 }, { 9, 0, 871 }, + { 9, 0, 893 }, { 11, 0, 38 }, { 11, 0, 431 }, { 12, 0, 112 }, + { 12, 0, 217 }, { 12, 0, 243 }, { 12, 0, 562 }, { 12, 0, 663 }, + { 12, 0, 683 }, { 13, 0, 141 }, { 13, 0, 197 }, { 13, 0, 227 }, + { 13, 0, 406 }, { 13, 0, 487 }, { 14, 0, 156 }, { 14, 0, 203 }, + { 14, 0, 224 }, { 14, 0, 256 }, { 18, 0, 58 }, { 22, 0, 0 }, + { 10, 0, 286 }, { 7, 10, 943 }, { 11, 10, 614 }, { 7, 10, 1837 }, + { 22, 11, 45 }, { 4, 0, 798 }, { 4, 0, 222 }, { 7, 0, 286 }, + { 8, 0, 629 }, { 4, 11, 79 }, { 7, 11, 1773 }, { 10, 11, 450 }, + { 11, 11, 589 }, { 13, 11, 332 }, { 13, 11, 493 }, { 14, 11, 183 }, + { 14, 11, 334 }, { 14, 11, 362 }, { 14, 11, 368 }, { 14, 11, 376 }, + { 14, 11, 379 }, { 19, 11, 90 }, { 19, 11, 103 }, { 19, 11, 127 }, + { 20, 11, 90 }, { 5, 0, 337 }, { 11, 0, 513 }, { 11, 0, 889 }, + { 11, 0, 961 }, { 12, 0, 461 }, { 13, 0, 79 }, { 15, 0, 121 }, + { 4, 10, 90 }, { 5, 10, 545 }, { 7, 10, 754 }, { 9, 10, 186 }, + { 10, 10, 72 }, { 10, 10, 782 }, { 11, 10, 577 }, { 11, 10, 610 }, + { 12, 10, 354 }, { 12, 10, 362 }, { 12, 10, 595 }, { 13, 0, 306 }, + { 8, 0, 146 }, { 7, 0, 1646 }, { 9, 10, 329 }, { 11, 10, 254 }, + { 13, 11, 124 }, { 4, 0, 465 }, { 7, 0, 1663 }, { 4, 0, 525 }, + { 5, 11, 663 }, { 10, 0, 299 }, { 18, 0, 74 }, { 9, 10, 187 }, + { 11, 10, 1016 }, { 17, 10, 44 }, { 7, 0, 165 }, { 7, 0, 919 }, + { 4, 10, 506 }, { 8, 10, 517 }, { 5, 10, 295 }, { 7, 10, 1680 }, + { 5, 11, 846 }, { 6, 0, 1064 }, { 5, 11, 378 }, { 7, 11, 1402 }, + { 7, 11, 1414 }, { 8, 11, 465 }, { 9, 11, 286 }, { 10, 11, 185 }, + { 10, 11, 562 }, { 10, 11, 635 }, { 11, 11, 31 }, { 11, 11, 393 }, + { 12, 11, 456 }, { 13, 11, 312 }, { 18, 11, 65 }, { 18, 11, 96 }, + { 19, 11, 89 }, { 4, 0, 596 }, { 7, 10, 987 }, { 9, 10, 688 }, + { 10, 10, 522 }, { 11, 10, 788 }, { 12, 10, 566 }, { 6, 0, 82 }, + { 7, 0, 138 }, { 7, 0, 517 }, { 7, 0, 1741 }, { 11, 0, 238 }, + { 4, 11, 648 }, { 6, 10, 1775 }, { 7, 0, 1233 }, { 7, 10, 700 }, + { 7, 10, 940 }, { 8, 10, 514 }, { 9, 10, 116 }, { 9, 10, 535 }, + { 10, 10, 118 }, { 11, 10, 107 }, { 11, 10, 148 }, { 11, 10, 922 }, + { 12, 10, 254 }, { 12, 10, 421 }, { 14, 10, 238 }, { 4, 0, 962 }, + { 6, 0, 1824 }, { 8, 0, 894 }, { 12, 0, 708 }, { 12, 0, 725 }, + { 14, 0, 451 }, { 20, 0, 94 }, { 22, 0, 59 }, { 22, 0, 62 }, + { 5, 11, 945 }, { 6, 11, 1656 }, { 6, 11, 1787 }, { 7, 11, 167 }, + { 8, 11, 824 }, { 9, 11, 391 }, { 10, 11, 375 }, { 11, 11, 185 }, + { 5, 0, 495 }, { 7, 0, 834 }, { 9, 0, 733 }, { 11, 0, 378 }, + { 4, 10, 743 }, { 7, 11, 1273 }, { 6, 0, 1204 }, { 7, 11, 1645 }, + { 8, 11, 352 }, { 9, 11, 249 }, { 11, 10, 292 }, { 5, 0, 559 }, + { 4, 11, 152 }, { 9, 0, 499 }, { 10, 0, 341 }, { 15, 0, 144 }, + { 19, 0, 49 }, { 7, 10, 1283 }, { 9, 10, 227 }, { 11, 10, 325 }, + { 11, 10, 408 }, { 14, 10, 180 }, { 18, 10, 47 }, { 6, 0, 21 }, + { 6, 0, 1737 }, { 7, 0, 1444 }, { 8, 0, 224 }, { 5, 11, 1006 }, + { 7, 0, 1446 }, { 9, 0, 97 }, { 17, 0, 15 }, { 5, 10, 81 }, + { 7, 10, 146 }, { 7, 10, 1342 }, { 8, 10, 53 }, { 8, 10, 561 }, + { 8, 10, 694 }, { 8, 10, 754 }, { 9, 10, 115 }, { 9, 10, 894 }, + { 10, 10, 462 }, { 10, 10, 813 }, { 11, 10, 230 }, { 11, 10, 657 }, + { 11, 10, 699 }, { 11, 10, 748 }, { 12, 10, 119 }, { 12, 10, 200 }, + { 12, 10, 283 }, { 14, 10, 273 }, { 5, 10, 408 }, { 9, 10, 747 }, + { 7, 11, 431 }, { 7, 11, 832 }, { 6, 0, 729 }, { 6, 0, 953 }, + { 4, 0, 727 }, { 8, 0, 565 }, { 5, 11, 351 }, { 7, 11, 264 }, + { 8, 11, 565 }, { 6, 0, 1948 }, { 5, 0, 519 }, { 5, 11, 40 }, + { 7, 11, 598 }, { 7, 11, 1638 }, { 8, 11, 78 }, { 9, 11, 166 }, + { 9, 11, 640 }, { 9, 11, 685 }, { 9, 11, 773 }, { 11, 11, 215 }, + { 13, 11, 65 }, { 14, 11, 172 }, { 14, 11, 317 }, { 17, 11, 6 }, + { 8, 11, 60 }, { 9, 11, 343 }, { 11, 11, 769 }, { 9, 11, 455 }, + { 6, 0, 1193 }, { 12, 0, 790 }, { 7, 11, 1951 }, { 8, 11, 765 }, + { 8, 11, 772 }, { 12, 11, 671 }, { 7, 11, 108 }, { 8, 11, 219 }, + { 8, 11, 388 }, { 9, 11, 639 }, { 9, 11, 775 }, { 11, 11, 275 }, + { 12, 11, 464 }, { 4, 11, 468 }, { 7, 10, 30 }, { 8, 10, 86 }, + { 8, 10, 315 }, { 8, 10, 700 }, { 9, 10, 576 }, { 9, 10, 858 }, + { 11, 10, 310 }, { 11, 10, 888 }, { 11, 10, 904 }, { 12, 10, 361 }, + { 13, 10, 248 }, { 5, 11, 15 }, { 6, 11, 56 }, { 7, 11, 1758 }, + { 8, 11, 500 }, { 9, 11, 730 }, { 11, 11, 331 }, { 13, 11, 150 }, + { 14, 11, 282 }, { 4, 0, 402 }, { 7, 0, 2 }, { 8, 0, 323 }, + { 8, 0, 479 }, { 10, 10, 839 }, { 11, 0, 580 }, { 14, 0, 201 }, + { 5, 0, 59 }, { 7, 0, 672 }, { 9, 10, 617 }, { 18, 0, 34 }, + { 6, 11, 1886 }, { 4, 0, 961 }, { 8, 0, 896 }, { 6, 0, 1285 }, + { 5, 11, 205 }, { 6, 11, 438 }, { 9, 11, 711 }, { 6, 10, 428 }, + { 7, 10, 524 }, { 8, 10, 169 }, { 8, 10, 234 }, { 9, 10, 480 }, + { 10, 10, 646 }, { 20, 0, 46 }, { 13, 0, 479 }, { 5, 11, 534 }, + { 6, 0, 2019 }, { 6, 10, 1648 }, { 4, 0, 85 }, { 7, 0, 549 }, + { 7, 10, 1205 }, { 10, 10, 637 }, { 4, 0, 663 }, { 5, 0, 94 }, + { 7, 11, 235 }, { 7, 11, 1475 }, { 15, 11, 68 }, { 18, 11, 120 }, + { 6, 11, 443 }, { 9, 11, 237 }, { 9, 11, 571 }, { 9, 11, 695 }, + { 10, 11, 139 }, { 11, 11, 715 }, { 12, 11, 417 }, { 13, 11, 421 }, + { 4, 0, 783 }, { 4, 0, 682 }, { 8, 0, 65 }, { 9, 10, 39 }, + { 10, 10, 166 }, { 11, 10, 918 }, { 12, 10, 635 }, { 20, 10, 10 }, + { 22, 10, 27 }, { 22, 10, 43 }, { 22, 10, 52 }, { 6, 0, 11 }, + { 7, 0, 187 }, { 4, 0, 522 }, { 4, 0, 52 }, { 7, 0, 661 }, + { 4, 0, 383 }, { 5, 0, 520 }, { 7, 11, 546 }, { 11, 0, 343 }, + { 14, 0, 127 }, { 4, 11, 578 }, { 7, 10, 157 }, { 7, 11, 624 }, + { 7, 11, 916 }, { 8, 10, 279 }, { 10, 11, 256 }, { 11, 11, 87 }, + { 11, 11, 703 }, { 6, 10, 604 }, { 4, 0, 281 }, { 5, 0, 38 }, + { 7, 0, 194 }, { 7, 0, 668 }, { 7, 0, 1893 }, { 9, 0, 397 }, + { 7, 10, 945 }, { 11, 10, 713 }, { 11, 10, 744 }, { 11, 10, 1022 }, + { 9, 0, 635 }, { 11, 0, 559 }, { 5, 11, 923 }, { 7, 11, 490 }, + { 12, 11, 553 }, { 13, 11, 100 }, { 14, 11, 118 }, { 15, 11, 75 }, + { 4, 0, 975 }, { 4, 10, 567 }, { 9, 10, 859 }, { 7, 10, 1846 }, + { 7, 11, 1846 }, { 8, 10, 628 }, { 8, 11, 628 }, { 20, 0, 116 }, + { 10, 11, 750 }, { 14, 0, 51 }, { 14, 11, 51 }, { 15, 11, 7 }, + { 20, 11, 20 }, { 4, 0, 858 }, { 6, 0, 1075 }, { 4, 11, 924 }, + { 5, 10, 762 }, { 8, 0, 535 }, { 5, 0, 448 }, { 10, 10, 784 }, + { 13, 10, 191 }, { 5, 10, 298 }, { 7, 0, 610 }, { 7, 0, 1501 }, + { 7, 10, 633 }, { 7, 10, 905 }, { 7, 10, 909 }, { 7, 10, 1538 }, + { 9, 10, 767 }, { 12, 10, 636 }, { 4, 11, 265 }, { 7, 11, 807 }, + { 7, 11, 950 }, { 5, 11, 93 }, { 12, 11, 267 }, { 16, 11, 26 }, + { 8, 0, 191 }, { 11, 10, 301 }, { 7, 10, 1970 }, { 7, 0, 267 }, + { 4, 0, 319 }, { 5, 0, 699 }, { 10, 0, 673 }, { 6, 0, 336 }, + { 7, 0, 92 }, { 7, 0, 182 }, { 8, 0, 453 }, { 8, 0, 552 }, + { 9, 0, 204 }, { 9, 0, 285 }, { 10, 0, 99 }, { 11, 0, 568 }, + { 11, 0, 950 }, { 12, 0, 94 }, { 16, 0, 20 }, { 16, 0, 70 }, + { 19, 0, 55 }, { 12, 10, 644 }, { 16, 10, 90 }, { 6, 0, 551 }, + { 7, 0, 1308 }, { 7, 10, 845 }, { 7, 11, 994 }, { 8, 10, 160 }, + { 9, 10, 318 }, { 19, 11, 1 }, { 19, 11, 26 }, { 22, 11, 9 }, + { 7, 0, 1406 }, { 9, 0, 218 }, { 13, 0, 222 }, { 5, 0, 256 }, + { 10, 0, 69 }, { 5, 11, 233 }, { 5, 11, 320 }, { 6, 11, 140 }, + { 7, 11, 330 }, { 8, 11, 295 }, { 6, 0, 1980 }, { 8, 0, 952 }, + { 4, 0, 833 }, { 9, 11, 678 }, { 5, 11, 978 }, { 4, 11, 905 }, + { 6, 11, 1701 }, { 9, 11, 843 }, { 10, 10, 735 }, { 8, 10, 76 }, + { 17, 0, 39 }, { 20, 0, 36 }, { 18, 0, 81 }, { 18, 11, 81 }, + { 14, 0, 352 }, { 17, 0, 53 }, { 18, 0, 146 }, { 18, 0, 152 }, + { 19, 0, 11 }, { 22, 0, 54 }, { 7, 0, 634 }, { 10, 10, 841 }, + { 4, 0, 618 }, { 4, 0, 339 }, { 7, 0, 259 }, { 17, 0, 73 }, + { 4, 11, 275 }, { 12, 11, 376 }, { 4, 11, 509 }, { 7, 11, 273 }, + { 11, 11, 377 }, { 4, 0, 759 }, { 13, 0, 169 }, { 9, 10, 804 }, + { 6, 10, 96 }, { 7, 10, 1426 }, { 4, 10, 651 }, { 5, 10, 289 }, + { 7, 0, 1075 }, { 8, 10, 35 }, { 9, 10, 511 }, { 10, 10, 767 }, + { 19, 10, 118 }, { 6, 0, 649 }, { 6, 0, 670 }, { 8, 0, 482 }, + { 5, 0, 336 }, { 6, 0, 341 }, { 6, 0, 478 }, { 6, 0, 1763 }, + { 8, 0, 386 }, { 5, 11, 802 }, { 7, 11, 2021 }, { 8, 11, 805 }, + { 14, 11, 94 }, { 15, 11, 65 }, { 16, 11, 4 }, { 16, 11, 77 }, + { 16, 11, 80 }, { 17, 11, 5 }, { 6, 0, 1035 }, { 5, 11, 167 }, + { 5, 11, 899 }, { 6, 11, 410 }, { 9, 11, 777 }, { 6, 11, 1705 }, + { 5, 0, 924 }, { 5, 0, 969 }, { 4, 10, 704 }, { 7, 0, 73 }, + { 7, 11, 10 }, { 7, 10, 1078 }, { 5, 11, 11 }, { 6, 11, 117 }, + { 6, 11, 485 }, { 7, 11, 1133 }, { 9, 11, 582 }, { 9, 11, 594 }, + { 11, 11, 21 }, { 11, 11, 818 }, { 12, 11, 535 }, { 13, 11, 86 }, + { 7, 0, 1971 }, { 4, 11, 264 }, { 7, 11, 1067 }, { 8, 11, 204 }, + { 8, 11, 385 }, { 11, 11, 953 }, { 6, 0, 1458 }, { 7, 0, 1344 }, + { 5, 0, 396 }, { 6, 0, 501 }, { 4, 10, 720 }, { 5, 10, 306 }, + { 4, 0, 929 }, { 5, 0, 799 }, { 8, 0, 46 }, { 8, 0, 740 }, + { 5, 10, 431 }, { 7, 11, 646 }, { 7, 11, 1730 }, { 11, 11, 446 }, + { 13, 11, 178 }, { 7, 0, 276 }, { 5, 10, 464 }, { 6, 10, 236 }, + { 7, 10, 696 }, { 7, 10, 914 }, { 7, 10, 1108 }, { 7, 10, 1448 }, + { 9, 10, 15 }, { 9, 10, 564 }, { 10, 10, 14 }, { 12, 10, 565 }, + { 13, 10, 449 }, { 14, 10, 53 }, { 15, 10, 13 }, { 16, 10, 64 }, + { 17, 10, 41 }, { 4, 0, 892 }, { 5, 0, 770 }, { 6, 10, 1767 }, + { 12, 10, 194 }, { 17, 10, 107 }, { 7, 0, 158 }, { 5, 10, 840 }, + { 10, 11, 608 }, { 6, 0, 1432 }, { 10, 11, 250 }, { 8, 11, 794 }, + { 9, 11, 400 }, { 10, 11, 298 }, { 14, 11, 228 }, { 23, 0, 25 }, + { 7, 11, 1131 }, { 7, 11, 1468 }, { 7, 0, 2001 }, { 9, 10, 642 }, + { 11, 10, 236 }, { 14, 10, 193 }, { 4, 10, 68 }, { 5, 10, 634 }, + { 6, 10, 386 }, { 7, 10, 794 }, { 8, 10, 273 }, { 9, 10, 563 }, + { 10, 10, 105 }, { 10, 10, 171 }, { 11, 10, 94 }, { 11, 10, 354 }, + { 8, 11, 724 }, { 4, 0, 478 }, { 11, 11, 512 }, { 13, 11, 205 }, + { 19, 11, 30 }, { 22, 11, 36 }, { 23, 11, 19 }, { 7, 0, 1461 }, + { 12, 0, 91 }, { 6, 11, 190 }, { 7, 11, 768 }, { 7, 11, 1170 }, + { 4, 0, 602 }, { 8, 0, 211 }, { 4, 10, 95 }, { 7, 10, 416 }, + { 11, 10, 830 }, { 7, 10, 731 }, { 13, 10, 20 }, { 15, 10, 11 }, + { 6, 0, 1068 }, { 7, 0, 1872 }, { 4, 0, 13 }, { 5, 0, 567 }, + { 7, 0, 1498 }, { 9, 0, 124 }, { 11, 0, 521 }, { 12, 0, 405 }, + { 7, 11, 1023 }, { 7, 0, 1006 }, { 4, 0, 735 }, { 10, 0, 812 }, + { 4, 0, 170 }, { 7, 0, 323 }, { 6, 11, 137 }, { 9, 11, 75 }, + { 9, 11, 253 }, { 10, 11, 194 }, { 10, 11, 444 }, { 5, 0, 304 }, + { 7, 0, 1403 }, { 5, 10, 864 }, { 10, 10, 648 }, { 11, 10, 671 }, + { 15, 10, 46 }, { 7, 11, 1180 }, { 5, 10, 928 }, { 4, 0, 148 }, + { 5, 0, 742 }, { 11, 10, 986 }, { 12, 10, 682 }, { 5, 0, 523 }, + { 7, 11, 1743 }, { 7, 0, 730 }, { 18, 0, 144 }, { 19, 0, 61 }, + { 8, 10, 44 }, { 9, 10, 884 }, { 10, 10, 580 }, { 11, 10, 399 }, + { 11, 10, 894 }, { 15, 10, 122 }, { 5, 11, 760 }, { 7, 11, 542 }, + { 8, 11, 135 }, { 8, 11, 496 }, { 8, 0, 981 }, { 5, 0, 111 }, + { 10, 0, 132 }, { 11, 0, 191 }, { 11, 0, 358 }, { 11, 0, 460 }, + { 7, 11, 319 }, { 7, 11, 355 }, { 7, 11, 763 }, { 10, 11, 389 }, + { 17, 11, 43 }, { 6, 0, 890 }, { 6, 0, 1420 }, { 8, 11, 557 }, + { 5, 10, 518 }, { 5, 0, 444 }, { 7, 0, 1787 }, { 7, 10, 1852 }, + { 8, 0, 123 }, { 15, 0, 6 }, { 16, 0, 7 }, { 6, 0, 2041 }, + { 10, 11, 38 }, { 11, 11, 784 }, { 8, 0, 932 }, { 5, 0, 937 }, + { 7, 0, 100 }, { 6, 0, 995 }, { 4, 11, 58 }, { 5, 11, 286 }, + { 6, 11, 319 }, { 7, 11, 402 }, { 7, 11, 1254 }, { 7, 11, 1903 }, + { 8, 11, 356 }, { 12, 11, 408 }, { 4, 11, 389 }, { 9, 11, 181 }, + { 9, 11, 255 }, { 10, 11, 8 }, { 10, 11, 29 }, { 10, 11, 816 }, + { 11, 11, 311 }, { 11, 11, 561 }, { 12, 11, 67 }, { 13, 11, 181 }, + { 10, 0, 255 }, { 5, 0, 138 }, { 4, 10, 934 }, { 8, 10, 610 }, + { 4, 0, 965 }, { 10, 0, 863 }, { 10, 0, 898 }, { 10, 10, 804 }, + { 10, 10, 832 }, { 12, 0, 631 }, { 8, 10, 96 }, { 9, 10, 36 }, + { 10, 10, 607 }, { 11, 10, 423 }, { 11, 10, 442 }, { 12, 10, 309 }, + { 14, 10, 199 }, { 15, 10, 90 }, { 17, 10, 110 }, { 6, 0, 1394 }, + { 4, 0, 652 }, { 8, 0, 320 }, { 22, 0, 6 }, { 22, 0, 16 }, + { 9, 10, 13 }, { 9, 10, 398 }, { 9, 10, 727 }, { 10, 10, 75 }, + { 10, 10, 184 }, { 10, 10, 230 }, { 10, 10, 564 }, { 10, 10, 569 }, + { 11, 10, 973 }, { 12, 10, 70 }, { 12, 10, 189 }, { 13, 10, 57 }, + { 13, 10, 257 }, { 6, 0, 897 }, { 6, 0, 1333 }, { 4, 0, 692 }, + { 5, 0, 321 }, { 5, 11, 373 }, { 7, 0, 922 }, { 5, 0, 619 }, + { 5, 0, 698 }, { 9, 10, 631 }, { 5, 10, 345 }, { 7, 10, 1016 }, + { 9, 0, 957 }, { 9, 0, 1018 }, { 12, 0, 828 }, { 12, 0, 844 }, + { 12, 0, 897 }, { 12, 0, 901 }, { 12, 0, 943 }, { 15, 0, 180 }, + { 18, 0, 197 }, { 18, 0, 200 }, { 18, 0, 213 }, { 18, 0, 214 }, + { 18, 0, 226 }, { 5, 0, 917 }, { 6, 0, 1659 }, { 7, 0, 1100 }, + { 6, 0, 1173 }, { 6, 0, 1930 }, { 5, 0, 251 }, { 5, 0, 956 }, + { 8, 0, 268 }, { 9, 0, 214 }, { 18, 0, 142 }, { 5, 10, 673 }, + { 9, 10, 850 }, { 4, 10, 287 }, { 5, 10, 1018 }, { 4, 11, 672 }, + { 5, 0, 346 }, { 5, 0, 711 }, { 8, 0, 390 }, { 11, 11, 752 }, + { 11, 11, 885 }, { 5, 10, 34 }, { 10, 10, 724 }, { 12, 10, 444 }, + { 13, 10, 354 }, { 18, 10, 32 }, { 23, 10, 24 }, { 23, 10, 31 }, + { 24, 10, 5 }, { 4, 11, 710 }, { 6, 11, 606 }, { 6, 0, 744 }, + { 6, 10, 382 }, { 5, 11, 145 }, { 4, 10, 329 }, { 7, 11, 884 }, + { 12, 11, 124 }, { 4, 11, 467 }, { 5, 11, 405 }, { 6, 11, 544 }, + { 9, 10, 846 }, { 10, 10, 827 }, { 5, 0, 624 }, { 9, 11, 372 }, + { 15, 11, 2 }, { 19, 11, 10 }, { 19, 11, 18 }, { 4, 11, 387 }, + { 7, 11, 1288 }, { 5, 0, 783 }, { 7, 0, 1998 }, { 7, 0, 2047 }, + { 4, 10, 906 }, { 8, 10, 366 }, { 7, 11, 550 }, { 4, 10, 123 }, + { 4, 10, 649 }, { 5, 10, 605 }, { 7, 10, 1509 }, { 8, 10, 36 }, + { 6, 0, 1125 }, { 4, 0, 594 }, { 5, 10, 767 }, { 7, 11, 1227 }, + { 8, 11, 467 }, { 4, 11, 576 }, { 7, 11, 1263 }, { 4, 0, 268 }, + { 7, 0, 1534 }, { 7, 11, 1534 }, { 4, 10, 273 }, { 5, 10, 658 }, + { 5, 11, 919 }, { 5, 10, 995 }, { 6, 11, 1673 }, { 5, 0, 563 }, + { 6, 10, 72 }, { 7, 10, 1345 }, { 4, 11, 82 }, { 5, 11, 333 }, + { 5, 11, 904 }, { 6, 11, 207 }, { 7, 11, 325 }, { 7, 11, 1726 }, + { 8, 11, 101 }, { 10, 11, 778 }, { 11, 11, 220 }, { 5, 0, 37 }, + { 6, 0, 39 }, { 6, 0, 451 }, { 7, 0, 218 }, { 7, 0, 667 }, + { 7, 0, 1166 }, { 7, 0, 1687 }, { 8, 0, 662 }, { 16, 0, 2 }, + { 5, 10, 589 }, { 6, 0, 1332 }, { 5, 11, 903 }, { 6, 0, 508 }, + { 5, 10, 117 }, { 6, 10, 514 }, { 6, 10, 541 }, { 7, 10, 1164 }, + { 7, 10, 1436 }, { 8, 10, 220 }, { 8, 10, 648 }, { 10, 10, 688 }, + { 11, 10, 560 }, { 12, 11, 147 }, { 6, 11, 555 }, { 7, 11, 485 }, + { 5, 10, 686 }, { 7, 0, 453 }, { 7, 0, 635 }, { 7, 0, 796 }, + { 8, 0, 331 }, { 9, 0, 330 }, { 9, 0, 865 }, { 10, 0, 119 }, + { 10, 0, 235 }, { 11, 0, 111 }, { 11, 0, 129 }, { 11, 0, 240 }, + { 12, 0, 31 }, { 12, 0, 66 }, { 12, 0, 222 }, { 12, 0, 269 }, + { 12, 0, 599 }, { 12, 0, 684 }, { 12, 0, 689 }, { 12, 0, 691 }, + { 14, 0, 345 }, { 7, 0, 1834 }, { 4, 11, 705 }, { 7, 11, 615 }, + { 10, 11, 251 }, { 8, 11, 345 }, { 9, 0, 527 }, { 6, 0, 98 }, + { 7, 0, 702 }, { 7, 0, 991 }, { 11, 0, 576 }, { 14, 0, 74 }, + { 7, 10, 196 }, { 10, 10, 765 }, { 11, 10, 347 }, { 11, 10, 552 }, + { 11, 10, 790 }, { 12, 10, 263 }, { 13, 10, 246 }, { 13, 10, 270 }, + { 13, 10, 395 }, { 14, 10, 176 }, { 14, 10, 190 }, { 14, 10, 398 }, + { 14, 10, 412 }, { 15, 10, 32 }, { 15, 10, 63 }, { 16, 10, 88 }, + { 19, 10, 105 }, { 6, 11, 90 }, { 13, 0, 84 }, { 13, 0, 122 }, + { 6, 0, 37 }, { 7, 0, 299 }, { 7, 0, 1666 }, { 8, 0, 195 }, + { 8, 0, 316 }, { 9, 0, 178 }, { 9, 0, 276 }, { 9, 0, 339 }, + { 9, 0, 536 }, { 10, 0, 102 }, { 10, 0, 362 }, { 10, 0, 785 }, + { 11, 0, 55 }, { 11, 0, 149 }, { 11, 0, 773 }, { 13, 0, 416 }, + { 13, 0, 419 }, { 14, 0, 38 }, { 14, 0, 41 }, { 14, 0, 210 }, + { 5, 10, 381 }, { 7, 10, 1792 }, { 7, 11, 813 }, { 12, 11, 497 }, + { 13, 11, 56 }, { 7, 10, 616 }, { 10, 10, 413 }, { 5, 0, 645 }, + { 6, 11, 125 }, { 7, 11, 1277 }, { 4, 0, 290 }, { 6, 0, 70 }, + { 7, 0, 1292 }, { 10, 0, 762 }, { 11, 0, 288 }, { 6, 10, 120 }, + { 7, 10, 1188 }, { 7, 10, 1710 }, { 8, 10, 286 }, { 9, 10, 667 }, + { 11, 10, 592 }, { 11, 10, 730 }, { 7, 11, 1784 }, { 7, 0, 1315 }, + { 7, 11, 1315 }, { 6, 0, 1955 }, { 7, 10, 1146 }, { 7, 0, 131 }, + { 7, 0, 422 }, { 8, 0, 210 }, { 12, 0, 573 }, { 4, 10, 352 }, + { 7, 10, 687 }, { 11, 0, 797 }, { 15, 0, 38 }, { 14, 0, 179 }, + { 15, 0, 151 }, { 22, 0, 11 }, { 7, 0, 488 }, { 4, 10, 192 }, + { 5, 10, 49 }, { 6, 10, 200 }, { 6, 10, 293 }, { 6, 10, 1696 }, + { 4, 0, 936 }, { 7, 11, 703 }, { 6, 11, 160 }, { 7, 11, 1106 }, + { 9, 11, 770 }, { 10, 11, 618 }, { 11, 11, 112 }, { 12, 11, 413 }, + { 5, 0, 453 }, { 6, 0, 441 }, { 7, 0, 595 }, { 4, 10, 650 }, + { 4, 10, 147 }, { 6, 0, 991 }, { 6, 0, 1182 }, { 12, 11, 271 }, + { 17, 11, 109 }, { 5, 10, 934 }, { 12, 11, 221 }, { 4, 0, 653 }, + { 7, 0, 505 }, { 7, 0, 523 }, { 6, 0, 903 }, { 7, 11, 479 }, + { 7, 11, 304 }, { 9, 11, 646 }, { 9, 11, 862 }, { 10, 11, 262 }, + { 11, 11, 696 }, { 12, 11, 208 }, { 15, 11, 79 }, { 19, 11, 108 }, + { 18, 0, 80 }, { 7, 11, 981 }, { 14, 0, 432 }, { 4, 0, 314 }, + { 9, 11, 152 }, { 7, 0, 1368 }, { 8, 0, 232 }, { 8, 0, 361 }, + { 10, 0, 682 }, { 10, 0, 742 }, { 7, 11, 1586 }, { 9, 0, 534 }, + { 4, 11, 434 }, { 11, 11, 663 }, { 12, 11, 210 }, { 13, 11, 166 }, + { 13, 11, 310 }, { 14, 11, 373 }, { 19, 11, 43 }, { 7, 11, 1091 }, + { 7, 11, 1765 }, { 6, 11, 550 }, { 7, 11, 652 }, { 9, 0, 27 }, + { 14, 0, 12 }, { 4, 10, 637 }, { 5, 11, 553 }, { 7, 11, 766 }, + { 10, 11, 824 }, { 7, 11, 737 }, { 8, 11, 298 }, { 8, 11, 452 }, + { 7, 0, 736 }, { 11, 0, 264 }, { 6, 0, 1657 }, { 5, 11, 292 }, + { 10, 11, 135 }, { 6, 0, 844 }, { 6, 0, 1117 }, { 7, 0, 127 }, + { 9, 10, 867 }, { 10, 10, 837 }, { 6, 0, 1184 }, { 6, 0, 1208 }, + { 6, 0, 1294 }, { 8, 0, 364 }, { 6, 0, 1415 }, { 7, 0, 1334 }, + { 11, 0, 125 }, { 6, 10, 170 }, { 7, 11, 393 }, { 8, 10, 395 }, + { 8, 10, 487 }, { 10, 11, 603 }, { 11, 11, 206 }, { 13, 10, 147 }, + { 9, 11, 748 }, { 4, 11, 912 }, { 9, 11, 232 }, { 4, 10, 535 }, + { 8, 10, 618 }, { 9, 0, 792 }, { 7, 11, 1973 }, { 8, 11, 716 }, + { 7, 11, 98 }, { 5, 0, 909 }, { 9, 0, 849 }, { 10, 0, 805 }, + { 4, 0, 630 }, { 4, 0, 699 }, { 5, 11, 733 }, { 14, 11, 103 }, + { 22, 10, 23 }, { 12, 11, 158 }, { 18, 11, 8 }, { 19, 11, 62 }, + { 20, 11, 6 }, { 22, 11, 4 }, { 23, 11, 2 }, { 23, 11, 9 }, + { 4, 0, 968 }, { 4, 10, 778 }, { 4, 10, 46 }, { 5, 10, 811 }, + { 6, 10, 1679 }, { 6, 10, 1714 }, { 7, 10, 2032 }, { 6, 0, 1446 }, + { 7, 10, 1458 }, { 9, 10, 407 }, { 11, 10, 15 }, { 7, 0, 206 }, + { 7, 0, 397 }, { 7, 0, 621 }, { 7, 0, 640 }, { 8, 0, 124 }, + { 8, 0, 619 }, { 9, 0, 305 }, { 9, 0, 643 }, { 10, 0, 264 }, + { 10, 0, 628 }, { 11, 0, 40 }, { 12, 0, 349 }, { 13, 0, 134 }, + { 13, 0, 295 }, { 14, 0, 155 }, { 15, 0, 120 }, { 18, 0, 105 }, + { 6, 10, 34 }, { 7, 10, 1089 }, { 8, 10, 708 }, { 8, 10, 721 }, + { 9, 10, 363 }, { 20, 10, 98 }, { 4, 0, 262 }, { 5, 0, 641 }, + { 7, 0, 342 }, { 9, 11, 72 }, { 4, 0, 99 }, { 6, 0, 250 }, + { 6, 0, 346 }, { 8, 0, 127 }, { 10, 0, 81 }, { 4, 0, 915 }, + { 5, 0, 75 }, { 9, 0, 517 }, { 10, 0, 470 }, { 12, 0, 155 }, + { 13, 0, 224 }, { 4, 10, 462 }, { 11, 11, 600 }, { 11, 11, 670 }, + { 13, 11, 245 }, { 14, 0, 83 }, { 5, 10, 73 }, { 6, 10, 23 }, + { 6, 10, 338 }, { 6, 0, 1031 }, { 11, 11, 923 }, { 7, 11, 164 }, + { 7, 11, 1571 }, { 9, 11, 107 }, { 12, 11, 225 }, { 6, 0, 1470 }, + { 5, 0, 954 }, { 6, 0, 304 }, { 8, 0, 418 }, { 10, 0, 345 }, + { 11, 0, 341 }, { 11, 0, 675 }, { 9, 0, 410 }, { 11, 0, 425 }, + { 4, 11, 27 }, { 5, 11, 484 }, { 5, 11, 510 }, { 6, 11, 434 }, + { 7, 11, 1000 }, { 7, 11, 1098 }, { 8, 11, 2 }, { 8, 11, 200 }, + { 6, 0, 734 }, { 12, 11, 257 }, { 7, 10, 725 }, { 8, 10, 498 }, + { 11, 10, 268 }, { 6, 0, 1822 }, { 7, 0, 1798 }, { 7, 10, 773 }, + { 4, 11, 460 }, { 4, 11, 932 }, { 5, 11, 891 }, { 6, 0, 14 }, + { 4, 10, 583 }, { 7, 10, 1462 }, { 8, 11, 625 }, { 11, 10, 659 }, + { 5, 0, 113 }, { 6, 0, 243 }, { 6, 0, 1708 }, { 7, 0, 1865 }, + { 11, 0, 161 }, { 16, 0, 37 }, { 17, 0, 99 }, { 5, 10, 220 }, + { 6, 11, 76 }, { 5, 11, 461 }, { 7, 11, 1925 }, { 12, 0, 69 }, + { 8, 11, 92 }, { 9, 11, 221 }, { 11, 10, 803 }, { 4, 10, 544 }, + { 4, 0, 274 }, { 6, 0, 922 }, { 4, 0, 541 }, { 5, 0, 627 }, + { 6, 10, 437 }, { 6, 10, 564 }, { 11, 10, 181 }, { 13, 10, 183 }, + { 7, 10, 1192 }, { 7, 0, 166 }, { 4, 11, 763 }, { 5, 11, 253 }, + { 6, 0, 849 }, { 9, 11, 73 }, { 10, 11, 110 }, { 14, 11, 185 }, + { 17, 11, 119 }, { 5, 11, 212 }, { 12, 11, 35 }, { 13, 11, 382 }, + { 5, 0, 717 }, { 9, 0, 304 }, { 8, 0, 600 }, { 5, 0, 654 }, + { 6, 0, 273 }, { 10, 0, 188 }, { 13, 0, 377 }, { 18, 0, 77 }, + { 4, 10, 790 }, { 5, 10, 273 }, { 6, 10, 394 }, { 4, 0, 543 }, + { 7, 0, 410 }, { 11, 0, 98 }, { 11, 0, 524 }, { 13, 0, 87 }, + { 4, 0, 941 }, { 7, 11, 1175 }, { 4, 0, 250 }, { 7, 0, 1612 }, + { 11, 0, 186 }, { 12, 0, 133 }, { 6, 10, 127 }, { 7, 10, 1511 }, + { 8, 10, 613 }, { 12, 10, 495 }, { 12, 10, 586 }, { 12, 10, 660 }, + { 12, 10, 668 }, { 14, 10, 385 }, { 15, 10, 118 }, { 17, 10, 20 }, + { 18, 10, 98 }, { 6, 0, 1785 }, { 5, 11, 816 }, { 6, 0, 1339 }, + { 7, 0, 961 }, { 7, 0, 1085 }, { 7, 0, 1727 }, { 8, 0, 462 }, + { 6, 10, 230 }, { 7, 11, 1727 }, { 9, 0, 636 }, { 7, 10, 1954 }, + { 4, 0, 780 }, { 5, 11, 869 }, { 5, 11, 968 }, { 6, 11, 1626 }, + { 8, 11, 734 }, { 8, 11, 784 }, { 4, 11, 542 }, { 6, 11, 1716 }, + { 6, 11, 1727 }, { 7, 11, 1082 }, { 7, 11, 1545 }, { 8, 11, 56 }, + { 8, 11, 118 }, { 8, 11, 412 }, { 8, 11, 564 }, { 9, 11, 888 }, + { 9, 11, 908 }, { 10, 11, 50 }, { 10, 11, 423 }, { 11, 11, 685 }, + { 11, 11, 697 }, { 11, 11, 933 }, { 12, 11, 299 }, { 13, 11, 126 }, + { 13, 11, 136 }, { 13, 11, 170 }, { 13, 11, 190 }, { 6, 11, 226 }, + { 4, 11, 232 }, { 9, 11, 202 }, { 10, 11, 474 }, { 12, 11, 433 }, + { 9, 11, 500 }, { 5, 0, 529 }, { 8, 10, 68 }, { 4, 10, 654 }, + { 4, 10, 156 }, { 7, 10, 998 }, { 7, 10, 1045 }, { 7, 10, 1860 }, + { 9, 10, 48 }, { 9, 10, 692 }, { 11, 10, 419 }, { 11, 10, 602 }, + { 7, 0, 1276 }, { 8, 0, 474 }, { 9, 0, 652 }, { 6, 11, 108 }, + { 7, 11, 1003 }, { 7, 11, 1181 }, { 8, 11, 343 }, { 7, 11, 1264 }, + { 7, 11, 1678 }, { 11, 11, 945 }, { 12, 11, 341 }, { 12, 11, 471 }, + { 12, 11, 569 }, { 6, 11, 1712 }, { 5, 0, 948 }, { 12, 0, 468 }, + { 19, 0, 96 }, { 20, 0, 24 }, { 4, 11, 133 }, { 7, 11, 711 }, + { 7, 11, 1298 }, { 7, 11, 1585 }, { 7, 11, 1929 }, { 6, 0, 753 }, + { 12, 0, 657 }, { 11, 0, 941 }, { 6, 11, 99 }, { 7, 11, 1808 }, + { 17, 11, 57 }, { 6, 11, 574 }, { 7, 11, 428 }, { 7, 11, 1250 }, + { 10, 11, 669 }, { 11, 11, 485 }, { 11, 11, 840 }, { 12, 11, 300 }, + { 14, 11, 250 }, { 4, 0, 532 }, { 5, 0, 706 }, { 7, 0, 662 }, + { 5, 0, 837 }, { 6, 0, 1651 }, { 11, 0, 985 }, { 7, 0, 1861 }, + { 9, 10, 197 }, { 10, 10, 300 }, { 12, 10, 473 }, { 13, 10, 90 }, + { 13, 10, 405 }, { 9, 11, 252 }, { 6, 11, 323 }, { 7, 11, 1564 }, + { 4, 0, 330 }, { 4, 0, 863 }, { 7, 0, 933 }, { 7, 0, 2012 }, + { 8, 0, 292 }, { 7, 11, 461 }, { 8, 11, 775 }, { 10, 11, 435 }, + { 4, 10, 606 }, { 4, 11, 655 }, { 7, 11, 850 }, { 17, 11, 75 }, + { 18, 11, 137 }, { 7, 0, 767 }, { 7, 10, 1978 }, { 8, 10, 676 }, + { 4, 0, 641 }, { 7, 11, 1559 }, { 6, 0, 1233 }, { 9, 0, 242 }, + { 17, 0, 114 }, { 4, 10, 361 }, { 5, 10, 315 }, { 9, 0, 883 }, + { 4, 10, 461 }, { 10, 0, 274 }, { 6, 0, 2008 }, { 6, 0, 1794 }, + { 4, 0, 703 }, { 7, 0, 207 }, { 12, 0, 285 }, { 4, 10, 472 }, + { 4, 0, 571 }, { 5, 0, 873 }, { 5, 0, 960 }, { 8, 0, 823 }, + { 9, 0, 881 }, { 8, 11, 577 }, { 7, 0, 617 }, { 10, 0, 498 }, + { 11, 0, 501 }, { 12, 0, 16 }, { 12, 0, 150 }, { 10, 10, 747 }, + { 4, 0, 431 }, { 5, 10, 155 }, { 11, 0, 283 }, { 11, 0, 567 }, + { 7, 10, 163 }, { 8, 10, 319 }, { 9, 10, 402 }, { 10, 10, 24 }, + { 10, 10, 681 }, { 11, 10, 200 }, { 12, 10, 253 }, { 12, 10, 410 }, + { 14, 10, 219 }, { 4, 11, 413 }, { 5, 11, 677 }, { 8, 11, 432 }, + { 12, 11, 280 }, { 9, 0, 401 }, { 5, 10, 475 }, { 7, 10, 1780 }, + { 11, 10, 297 }, { 11, 10, 558 }, { 14, 10, 322 }, { 19, 10, 76 }, + { 6, 0, 781 }, { 9, 0, 134 }, { 10, 0, 2 }, { 10, 0, 27 }, + { 10, 0, 333 }, { 11, 0, 722 }, { 15, 0, 1 }, { 5, 0, 33 }, + { 6, 0, 470 }, { 11, 0, 424 }, { 7, 0, 2006 }, { 12, 0, 783 }, + { 7, 10, 1956 }, { 8, 0, 274 }, { 7, 0, 1882 }, { 4, 0, 794 }, + { 7, 0, 1848 }, { 5, 10, 944 }, { 6, 10, 1769 }, { 6, 0, 47 }, + { 7, 0, 90 }, { 7, 0, 664 }, { 7, 0, 830 }, { 7, 0, 1380 }, + { 7, 0, 2025 }, { 8, 0, 448 }, { 8, 0, 828 }, { 4, 10, 144 }, + { 6, 0, 1199 }, { 4, 11, 395 }, { 11, 11, 762 }, { 7, 11, 1504 }, + { 9, 0, 417 }, { 9, 0, 493 }, { 9, 11, 174 }, { 10, 11, 164 }, + { 11, 11, 440 }, { 11, 11, 841 }, { 15, 11, 98 }, { 6, 11, 426 }, + { 11, 11, 1002 }, { 6, 0, 295 }, { 6, 0, 816 }, { 6, 10, 247 }, + { 9, 10, 555 }, { 5, 0, 1019 }, { 4, 0, 620 }, { 5, 11, 476 }, + { 10, 10, 280 }, { 10, 10, 797 }, { 11, 0, 464 }, { 5, 11, 76 }, + { 6, 11, 458 }, { 6, 11, 497 }, { 7, 11, 764 }, { 7, 11, 868 }, + { 9, 11, 658 }, { 10, 11, 594 }, { 11, 11, 173 }, { 11, 11, 566 }, + { 12, 11, 20 }, { 12, 11, 338 }, { 13, 11, 200 }, { 6, 0, 208 }, + { 4, 11, 526 }, { 7, 11, 1029 }, { 7, 11, 1054 }, { 4, 11, 636 }, + { 6, 11, 233 }, { 7, 11, 660 }, { 7, 11, 1124 }, { 17, 11, 31 }, + { 19, 11, 22 }, { 23, 11, 14 }, { 10, 0, 442 }, { 5, 10, 428 }, + { 10, 0, 930 }, { 12, 0, 778 }, { 6, 0, 68 }, { 7, 0, 448 }, + { 7, 0, 1629 }, { 7, 0, 1769 }, { 7, 0, 1813 }, { 8, 0, 442 }, + { 8, 0, 516 }, { 9, 0, 710 }, { 10, 0, 282 }, { 10, 0, 722 }, + { 7, 10, 1717 }, { 10, 10, 546 }, { 6, 0, 1128 }, { 11, 0, 844 }, + { 12, 0, 104 }, { 12, 0, 625 }, { 4, 11, 432 }, { 7, 11, 824 }, + { 10, 10, 189 }, { 5, 0, 787 }, { 5, 10, 99 }, { 4, 11, 279 }, + { 7, 11, 301 }, { 9, 11, 362 }, { 8, 0, 491 }, { 4, 10, 397 }, + { 8, 10, 555 }, { 4, 11, 178 }, { 5, 11, 399 }, { 6, 0, 711 }, + { 16, 0, 9 }, { 4, 0, 403 }, { 5, 0, 441 }, { 7, 0, 450 }, + { 10, 0, 840 }, { 11, 0, 101 }, { 12, 0, 193 }, { 13, 0, 430 }, + { 7, 11, 1246 }, { 12, 10, 398 }, { 20, 10, 39 }, { 21, 10, 11 }, + { 22, 10, 41 }, { 4, 10, 485 }, { 7, 10, 353 }, { 7, 10, 1523 }, + { 6, 10, 366 }, { 7, 10, 1384 }, { 7, 10, 1601 }, { 7, 11, 1912 }, + { 7, 0, 396 }, { 10, 0, 160 }, { 7, 11, 396 }, { 9, 10, 282 }, + { 6, 11, 1692 }, { 4, 10, 157 }, { 5, 10, 471 }, { 6, 11, 202 }, + { 10, 11, 448 }, { 11, 11, 208 }, { 12, 11, 360 }, { 17, 11, 117 }, + { 17, 11, 118 }, { 18, 11, 27 }, { 20, 11, 67 }, { 5, 0, 679 }, + { 9, 0, 326 }, { 8, 10, 116 }, { 7, 11, 872 }, { 10, 11, 516 }, + { 11, 11, 167 }, { 4, 11, 224 }, { 5, 11, 546 }, { 7, 11, 35 }, + { 8, 11, 11 }, { 8, 11, 12 }, { 9, 11, 315 }, { 9, 11, 533 }, + { 10, 11, 802 }, { 11, 11, 166 }, { 12, 11, 525 }, { 14, 11, 243 }, + { 7, 0, 1128 }, { 7, 11, 1920 }, { 5, 11, 241 }, { 8, 11, 242 }, + { 9, 11, 451 }, { 10, 11, 667 }, { 11, 11, 598 }, { 12, 11, 429 }, + { 6, 0, 737 }, { 5, 10, 160 }, { 7, 10, 363 }, { 7, 10, 589 }, + { 10, 10, 170 }, { 13, 10, 55 }, { 7, 0, 1796 }, { 14, 11, 254 }, + { 4, 0, 574 }, { 7, 0, 350 }, { 7, 0, 1024 }, { 8, 0, 338 }, + { 9, 0, 677 }, { 10, 0, 808 }, { 6, 0, 1096 }, { 9, 11, 516 }, + { 7, 0, 405 }, { 10, 0, 491 }, { 4, 10, 108 }, { 4, 11, 366 }, + { 11, 10, 498 }, { 11, 11, 337 }, { 14, 11, 303 }, { 6, 11, 1736 }, + { 7, 0, 1081 }, { 12, 11, 364 }, { 7, 10, 1005 }, { 12, 10, 609 }, + { 7, 0, 1676 }, { 4, 10, 895 }, { 5, 10, 772 }, { 7, 0, 2037 }, + { 6, 0, 1207 }, { 11, 11, 916 }, { 14, 11, 419 }, { 14, 11, 140 }, + { 20, 11, 41 }, { 6, 11, 331 }, { 8, 11, 623 }, { 9, 0, 944 }, + { 9, 0, 969 }, { 9, 0, 1022 }, { 12, 0, 913 }, { 12, 0, 936 }, + { 15, 0, 177 }, { 15, 0, 193 }, { 4, 10, 926 }, { 5, 10, 983 }, + { 5, 0, 354 }, { 7, 11, 506 }, { 8, 0, 598 }, { 9, 0, 664 }, + { 10, 0, 441 }, { 4, 11, 640 }, { 5, 11, 513 }, { 9, 0, 297 }, + { 4, 10, 538 }, { 6, 10, 294 }, { 7, 10, 1267 }, { 8, 10, 624 }, + { 7, 0, 1772 }, { 7, 11, 1888 }, { 8, 11, 289 }, { 11, 11, 45 }, + { 12, 11, 278 }, { 12, 11, 537 }, { 7, 10, 1325 }, { 10, 0, 751 }, + { 13, 0, 37 }, { 6, 0, 1828 }, { 4, 10, 757 }, { 4, 11, 394 }, + { 6, 0, 257 }, { 7, 0, 1522 }, { 4, 0, 582 }, { 9, 0, 191 }, + { 7, 11, 1931 }, { 7, 11, 574 }, { 7, 11, 1719 }, { 9, 11, 145 }, + { 4, 11, 658 }, { 10, 0, 790 }, { 4, 11, 369 }, { 9, 11, 781 }, + { 10, 11, 144 }, { 11, 11, 385 }, { 13, 11, 161 }, { 13, 11, 228 }, + { 13, 11, 268 }, { 20, 11, 107 }, { 8, 0, 469 }, { 10, 0, 47 }, + { 8, 11, 374 }, { 6, 0, 306 }, { 7, 0, 1140 }, { 7, 0, 1340 }, + { 8, 0, 133 }, { 10, 0, 449 }, { 11, 0, 1011 }, { 7, 10, 1875 }, + { 11, 10, 124 }, { 4, 11, 344 }, { 6, 11, 498 }, { 11, 11, 323 }, + { 9, 0, 299 }, { 4, 0, 837 }, { 5, 11, 906 }, { 5, 0, 329 }, + { 8, 0, 260 }, { 10, 0, 10 }, { 6, 0, 1320 }, { 4, 0, 657 }, + { 18, 0, 158 }, { 7, 0, 1191 }, { 24, 0, 7 }, { 6, 0, 1939 }, + { 8, 0, 974 }, { 10, 0, 996 }, { 7, 0, 1665 }, { 11, 11, 126 }, + { 11, 11, 287 }, { 15, 0, 8 }, { 14, 11, 149 }, { 14, 11, 399 }, + { 15, 11, 57 }, { 5, 0, 66 }, { 7, 0, 1896 }, { 8, 0, 288 }, + { 7, 0, 175 }, { 10, 0, 494 }, { 5, 10, 150 }, { 8, 10, 603 }, + { 9, 10, 593 }, { 9, 10, 634 }, { 10, 10, 173 }, { 11, 10, 462 }, + { 11, 10, 515 }, { 13, 10, 216 }, { 13, 10, 288 }, { 14, 10, 400 }, + { 6, 0, 1643 }, { 8, 11, 21 }, { 4, 0, 21 }, { 5, 0, 91 }, + { 5, 0, 648 }, { 5, 0, 750 }, { 5, 0, 781 }, { 6, 0, 54 }, + { 6, 0, 112 }, { 6, 0, 402 }, { 6, 0, 1732 }, { 7, 0, 315 }, + { 7, 0, 749 }, { 7, 0, 1427 }, { 7, 0, 1900 }, { 9, 0, 78 }, + { 9, 0, 508 }, { 10, 0, 611 }, { 10, 0, 811 }, { 11, 0, 510 }, + { 11, 0, 728 }, { 13, 0, 36 }, { 14, 0, 39 }, { 16, 0, 83 }, + { 17, 0, 124 }, { 20, 0, 30 }, { 4, 0, 668 }, { 8, 0, 570 }, + { 10, 0, 322 }, { 10, 0, 719 }, { 11, 0, 407 }, { 7, 11, 1381 }, + { 8, 11, 193 }, { 12, 10, 108 }, { 13, 10, 291 }, { 4, 11, 616 }, + { 8, 11, 692 }, { 8, 0, 125 }, { 8, 0, 369 }, { 8, 0, 524 }, + { 10, 0, 486 }, { 11, 0, 13 }, { 11, 0, 381 }, { 11, 0, 736 }, + { 11, 0, 766 }, { 11, 0, 845 }, { 13, 0, 114 }, { 13, 0, 292 }, + { 14, 0, 47 }, { 6, 0, 1247 }, { 6, 0, 1684 }, { 6, 0, 1731 }, + { 7, 0, 356 }, { 8, 0, 54 }, { 8, 0, 221 }, { 9, 0, 225 }, + { 9, 0, 356 }, { 10, 0, 77 }, { 10, 0, 446 }, { 10, 0, 731 }, + { 12, 0, 404 }, { 13, 0, 491 }, { 7, 10, 1777 }, { 4, 11, 305 }, + { 4, 10, 493 }, { 16, 10, 55 }, { 4, 0, 951 }, { 6, 0, 1809 }, + { 6, 0, 1849 }, { 8, 0, 846 }, { 8, 0, 866 }, { 8, 0, 899 }, + { 10, 0, 896 }, { 12, 0, 694 }, { 14, 0, 468 }, { 5, 11, 214 }, + { 7, 11, 603 }, { 8, 11, 611 }, { 9, 11, 686 }, { 10, 11, 88 }, + { 11, 11, 459 }, { 11, 11, 496 }, { 12, 11, 463 }, { 12, 11, 590 }, + { 13, 11, 0 }, { 14, 11, 214 }, { 4, 0, 411 }, { 4, 0, 80 }, + { 5, 0, 44 }, { 12, 11, 74 }, { 15, 0, 31 }, { 7, 0, 669 }, + { 6, 10, 568 }, { 7, 10, 1804 }, { 8, 10, 362 }, { 8, 10, 410 }, + { 8, 10, 830 }, { 9, 10, 514 }, { 11, 10, 649 }, { 14, 10, 157 }, + { 7, 0, 673 }, { 6, 11, 1703 }, { 4, 10, 625 }, { 6, 0, 1303 }, + { 5, 0, 299 }, { 7, 0, 1083 }, { 10, 0, 704 }, { 6, 0, 275 }, + { 7, 0, 408 }, { 6, 10, 158 }, { 7, 10, 129 }, { 7, 10, 181 }, + { 8, 10, 276 }, { 8, 10, 377 }, { 10, 10, 523 }, { 11, 10, 816 }, + { 12, 10, 455 }, { 13, 10, 303 }, { 14, 10, 135 }, { 4, 0, 219 }, + { 7, 0, 367 }, { 7, 0, 1713 }, { 7, 0, 1761 }, { 9, 0, 86 }, + { 9, 0, 537 }, { 10, 0, 165 }, { 12, 0, 219 }, { 12, 0, 561 }, + { 8, 0, 216 }, { 4, 10, 1 }, { 4, 11, 737 }, { 6, 11, 317 }, + { 7, 10, 1143 }, { 7, 10, 1463 }, { 9, 10, 207 }, { 9, 10, 390 }, + { 9, 10, 467 }, { 10, 11, 98 }, { 11, 11, 294 }, { 11, 10, 836 }, + { 12, 11, 60 }, { 12, 11, 437 }, { 13, 11, 64 }, { 13, 11, 380 }, + { 14, 11, 430 }, { 6, 11, 1758 }, { 8, 11, 520 }, { 9, 11, 345 }, + { 9, 11, 403 }, { 14, 11, 350 }, { 5, 11, 47 }, { 10, 11, 242 }, + { 10, 11, 579 }, { 5, 11, 139 }, { 7, 11, 1168 }, { 10, 11, 539 }, + { 7, 0, 1319 }, { 4, 10, 295 }, { 4, 10, 723 }, { 5, 10, 895 }, + { 7, 10, 1031 }, { 8, 10, 199 }, { 8, 10, 340 }, { 9, 10, 153 }, + { 9, 10, 215 }, { 10, 10, 21 }, { 10, 10, 59 }, { 10, 10, 80 }, + { 10, 10, 224 }, { 10, 10, 838 }, { 11, 10, 229 }, { 11, 10, 652 }, + { 12, 10, 192 }, { 13, 10, 146 }, { 14, 10, 91 }, { 12, 0, 428 }, + { 9, 10, 51 }, { 5, 0, 514 }, { 5, 10, 309 }, { 12, 10, 211 }, + { 6, 0, 1010 }, { 5, 10, 125 }, { 8, 10, 77 }, { 10, 10, 15 }, + { 4, 0, 55 }, { 5, 0, 301 }, { 6, 0, 571 }, { 14, 0, 49 }, + { 18, 0, 102 }, { 8, 11, 370 }, { 4, 11, 107 }, { 7, 11, 613 }, + { 8, 11, 358 }, { 8, 11, 439 }, { 8, 11, 504 }, { 9, 11, 501 }, + { 10, 11, 383 }, { 11, 11, 477 }, { 4, 11, 229 }, { 5, 0, 364 }, + { 5, 10, 439 }, { 4, 11, 903 }, { 7, 11, 1816 }, { 11, 0, 379 }, + { 12, 10, 76 }, { 4, 0, 76 }, { 4, 0, 971 }, { 7, 0, 1550 }, + { 9, 0, 306 }, { 9, 0, 430 }, { 9, 0, 663 }, { 10, 0, 683 }, + { 10, 0, 921 }, { 11, 0, 427 }, { 11, 0, 753 }, { 12, 0, 334 }, + { 12, 0, 442 }, { 14, 0, 258 }, { 14, 0, 366 }, { 15, 0, 131 }, + { 9, 0, 52 }, { 4, 11, 47 }, { 6, 11, 373 }, { 7, 11, 452 }, + { 7, 11, 543 }, { 7, 11, 1714 }, { 7, 11, 1856 }, { 9, 11, 6 }, + { 11, 11, 257 }, { 11, 11, 391 }, { 4, 10, 8 }, { 7, 10, 1152 }, + { 7, 10, 1153 }, { 7, 10, 1715 }, { 9, 10, 374 }, { 10, 10, 478 }, + { 11, 10, 648 }, { 4, 11, 785 }, { 5, 11, 368 }, { 7, 10, 1099 }, + { 7, 11, 860 }, { 5, 11, 980 }, { 6, 11, 1754 }, { 6, 0, 1258 }, + { 6, 0, 1058 }, { 6, 0, 1359 }, { 7, 11, 536 }, { 7, 11, 1331 }, + { 8, 11, 143 }, { 4, 0, 656 }, { 7, 0, 779 }, { 8, 10, 87 }, + { 5, 11, 19 }, { 6, 11, 533 }, { 18, 11, 126 }, { 7, 0, 144 }, + { 10, 10, 438 }, { 5, 11, 395 }, { 5, 11, 951 }, { 6, 11, 1776 }, + { 7, 0, 1373 }, { 7, 0, 554 }, { 7, 0, 605 }, { 13, 0, 10 }, + { 4, 10, 69 }, { 5, 10, 122 }, { 9, 10, 656 }, { 10, 10, 464 }, + { 5, 10, 849 }, { 6, 10, 1633 }, { 5, 0, 838 }, { 5, 0, 841 }, + { 6, 0, 1649 }, { 5, 0, 1012 }, { 11, 10, 499 }, { 7, 10, 476 }, + { 7, 10, 1592 }, { 10, 10, 87 }, { 6, 0, 251 }, { 7, 0, 365 }, + { 7, 0, 1357 }, { 7, 0, 1497 }, { 8, 0, 154 }, { 13, 0, 281 }, + { 4, 11, 441 }, { 4, 11, 695 }, { 7, 11, 497 }, { 9, 11, 387 }, + { 19, 11, 81 }, { 5, 0, 340 }, { 14, 10, 283 }, { 14, 11, 283 }, + { 6, 0, 810 }, { 7, 11, 1894 }, { 11, 0, 495 }, { 5, 11, 284 }, + { 6, 11, 49 }, { 6, 11, 350 }, { 7, 11, 1 }, { 7, 11, 377 }, + { 7, 11, 1693 }, { 8, 11, 18 }, { 8, 11, 678 }, { 9, 11, 161 }, + { 9, 11, 585 }, { 9, 11, 671 }, { 9, 11, 839 }, { 11, 11, 912 }, + { 13, 11, 427 }, { 5, 10, 859 }, { 7, 10, 1160 }, { 8, 10, 107 }, + { 9, 10, 291 }, { 9, 10, 439 }, { 10, 10, 663 }, { 11, 10, 609 }, + { 12, 10, 197 }, { 8, 0, 261 }, { 9, 0, 144 }, { 9, 0, 466 }, + { 10, 0, 370 }, { 12, 0, 470 }, { 13, 0, 144 }, { 14, 0, 348 }, + { 9, 0, 897 }, { 6, 0, 248 }, { 9, 0, 546 }, { 10, 0, 535 }, + { 11, 0, 681 }, { 13, 0, 135 }, { 4, 0, 358 }, { 7, 0, 1496 }, + { 6, 0, 567 }, { 8, 0, 445 }, { 4, 10, 117 }, { 6, 10, 372 }, + { 7, 10, 1905 }, { 14, 10, 323 }, { 4, 10, 722 }, { 11, 10, 471 }, + { 6, 0, 697 }, { 6, 0, 996 }, { 7, 11, 2007 }, { 9, 11, 101 }, + { 9, 11, 450 }, { 10, 11, 66 }, { 10, 11, 842 }, { 11, 11, 536 }, + { 12, 11, 587 }, { 4, 0, 577 }, { 6, 0, 1336 }, { 9, 10, 5 }, + { 12, 10, 216 }, { 12, 10, 294 }, { 12, 10, 298 }, { 12, 10, 400 }, + { 12, 10, 518 }, { 13, 10, 229 }, { 15, 10, 139 }, { 6, 0, 174 }, + { 10, 0, 917 }, { 6, 10, 1774 }, { 5, 10, 12 }, { 7, 10, 375 }, + { 9, 10, 88 }, { 9, 10, 438 }, { 11, 11, 62 }, { 11, 10, 270 }, + { 6, 11, 1766 }, { 6, 11, 0 }, { 7, 11, 84 }, { 7, 10, 816 }, + { 7, 10, 1241 }, { 9, 10, 283 }, { 9, 10, 520 }, { 10, 10, 213 }, + { 10, 10, 307 }, { 10, 10, 463 }, { 10, 10, 671 }, { 10, 10, 746 }, + { 11, 10, 401 }, { 11, 10, 794 }, { 11, 11, 895 }, { 12, 10, 517 }, + { 17, 11, 11 }, { 18, 10, 107 }, { 19, 10, 115 }, { 5, 0, 878 }, + { 5, 0, 972 }, { 6, 11, 1665 }, { 7, 11, 256 }, { 7, 11, 1388 }, + { 10, 11, 499 }, { 4, 10, 258 }, { 8, 10, 639 }, { 4, 11, 22 }, + { 5, 11, 10 }, { 6, 10, 22 }, { 7, 11, 848 }, { 7, 10, 903 }, + { 7, 10, 1963 }, { 8, 11, 97 }, { 10, 10, 577 }, { 5, 10, 681 }, + { 8, 10, 782 }, { 5, 11, 481 }, { 4, 0, 351 }, { 4, 10, 664 }, + { 5, 10, 804 }, { 11, 10, 1013 }, { 6, 11, 134 }, { 7, 11, 437 }, + { 7, 11, 959 }, { 9, 11, 37 }, { 14, 11, 285 }, { 14, 11, 371 }, + { 16, 11, 60 }, { 7, 11, 486 }, { 8, 11, 155 }, { 11, 11, 93 }, + { 12, 11, 164 }, { 4, 0, 286 }, { 7, 0, 438 }, { 7, 0, 627 }, + { 7, 0, 1516 }, { 8, 0, 40 }, { 9, 0, 56 }, { 9, 0, 294 }, + { 10, 0, 30 }, { 11, 0, 969 }, { 11, 0, 995 }, { 18, 0, 148 }, + { 5, 11, 591 }, { 7, 11, 337 }, { 6, 0, 1950 }, { 5, 10, 32 }, + { 10, 11, 500 }, { 5, 11, 380 }, { 5, 11, 650 }, { 8, 11, 310 }, + { 4, 11, 364 }, { 7, 11, 1156 }, { 7, 11, 1187 }, { 9, 11, 409 }, + { 4, 0, 738 }, { 6, 11, 482 }, { 4, 11, 781 }, { 6, 11, 487 }, + { 7, 11, 926 }, { 8, 11, 263 }, { 11, 11, 500 }, { 7, 11, 418 }, + { 6, 0, 2047 }, { 10, 0, 969 }, { 4, 10, 289 }, { 7, 10, 629 }, + { 7, 10, 1698 }, { 7, 10, 1711 }, { 12, 10, 215 }, { 6, 10, 450 }, + { 8, 10, 109 }, { 6, 0, 818 }, { 8, 10, 705 }, { 5, 0, 866 }, + { 4, 11, 94 }, { 7, 11, 1265 }, { 4, 11, 417 }, { 6, 0, 1467 }, + { 7, 10, 1238 }, { 4, 0, 972 }, { 6, 0, 1851 }, { 6, 0, 1857 }, + { 6, 0, 355 }, { 5, 0, 116 }, { 4, 0, 457 }, { 7, 11, 1411 }, + { 4, 11, 408 }, { 4, 11, 741 }, { 7, 11, 500 }, { 6, 10, 26 }, + { 14, 11, 137 }, { 5, 0, 527 }, { 6, 0, 189 }, { 7, 0, 859 }, + { 8, 0, 267 }, { 11, 0, 104 }, { 11, 0, 554 }, { 15, 0, 60 }, + { 15, 0, 125 }, { 6, 0, 1613 }, { 4, 10, 414 }, { 5, 10, 467 }, + { 9, 10, 654 }, { 10, 10, 451 }, { 12, 10, 59 }, { 13, 10, 375 }, + { 7, 10, 17 }, { 6, 0, 116 }, { 7, 11, 541 }, { 7, 10, 955 }, + { 6, 11, 73 }, { 7, 11, 177 }, { 5, 11, 576 }, { 6, 0, 886 }, + { 5, 0, 487 }, { 4, 0, 86 }, { 5, 0, 667 }, { 5, 0, 753 }, + { 6, 0, 316 }, { 6, 0, 455 }, { 7, 0, 946 }, { 14, 11, 231 }, + { 22, 0, 45 }, { 6, 0, 863 }, { 6, 0, 1953 }, { 6, 10, 280 }, + { 10, 10, 502 }, { 11, 10, 344 }, { 12, 10, 38 }, { 4, 0, 79 }, + { 7, 0, 1773 }, { 10, 0, 450 }, { 11, 0, 589 }, { 13, 0, 332 }, + { 13, 0, 493 }, { 14, 0, 183 }, { 14, 0, 334 }, { 14, 0, 362 }, + { 14, 0, 368 }, { 14, 0, 376 }, { 14, 0, 379 }, { 19, 0, 90 }, + { 19, 0, 103 }, { 19, 0, 127 }, { 20, 0, 90 }, { 5, 10, 45 }, + { 7, 10, 1161 }, { 11, 10, 448 }, { 11, 10, 880 }, { 13, 10, 139 }, + { 13, 10, 407 }, { 15, 10, 16 }, { 17, 10, 95 }, { 18, 10, 66 }, + { 18, 10, 88 }, { 18, 10, 123 }, { 21, 10, 7 }, { 8, 10, 777 }, + { 4, 10, 410 }, { 7, 10, 521 }, { 7, 10, 1778 }, { 7, 11, 538 }, + { 14, 0, 381 }, { 5, 11, 413 }, { 6, 0, 1142 }, { 6, 0, 1189 }, + { 8, 11, 495 }, { 5, 0, 663 }, { 6, 0, 1962 }, { 6, 0, 2003 }, + { 7, 11, 54 }, { 8, 11, 312 }, { 10, 11, 191 }, { 10, 11, 614 }, + { 12, 11, 567 }, { 4, 10, 436 }, { 5, 0, 846 }, { 10, 0, 528 }, + { 11, 0, 504 }, { 7, 10, 1587 }, { 7, 10, 1707 }, { 5, 0, 378 }, + { 8, 0, 465 }, { 9, 0, 286 }, { 10, 0, 185 }, { 10, 0, 562 }, + { 10, 0, 635 }, { 11, 0, 31 }, { 11, 0, 393 }, { 13, 0, 312 }, + { 18, 0, 65 }, { 18, 0, 96 }, { 19, 0, 89 }, { 7, 0, 899 }, + { 14, 0, 325 }, { 6, 11, 468 }, { 7, 11, 567 }, { 7, 11, 1478 }, + { 8, 11, 530 }, { 14, 11, 290 }, { 7, 0, 1880 }, { 9, 0, 680 }, + { 11, 0, 798 }, { 6, 0, 1770 }, { 4, 0, 648 }, { 22, 11, 35 }, + { 5, 0, 945 }, { 6, 0, 1656 }, { 6, 0, 1787 }, { 7, 0, 167 }, + { 8, 0, 824 }, { 9, 0, 391 }, { 10, 0, 375 }, { 11, 0, 185 }, + { 6, 11, 484 }, { 7, 11, 822 }, { 6, 0, 2046 }, { 7, 0, 1645 }, + { 8, 0, 352 }, { 9, 0, 249 }, { 4, 0, 152 }, { 6, 0, 611 }, + { 7, 0, 1733 }, { 6, 11, 1724 }, { 7, 11, 2022 }, { 5, 0, 1006 }, + { 13, 11, 96 }, { 5, 0, 420 }, { 7, 0, 1449 }, { 18, 11, 149 }, + { 7, 0, 832 }, { 7, 10, 663 }, { 5, 0, 351 }, { 5, 0, 40 }, + { 7, 0, 598 }, { 7, 0, 1638 }, { 8, 0, 78 }, { 9, 0, 166 }, + { 9, 0, 640 }, { 9, 0, 685 }, { 9, 0, 773 }, { 11, 0, 215 }, + { 13, 0, 65 }, { 14, 0, 172 }, { 14, 0, 317 }, { 17, 0, 6 }, + { 8, 0, 60 }, { 9, 0, 343 }, { 11, 0, 769 }, { 6, 0, 1354 }, + { 4, 0, 724 }, { 9, 0, 745 }, { 4, 11, 474 }, { 7, 0, 1951 }, + { 8, 0, 765 }, { 8, 0, 772 }, { 12, 0, 671 }, { 7, 0, 108 }, + { 8, 0, 219 }, { 8, 0, 388 }, { 9, 0, 775 }, { 11, 0, 275 }, + { 12, 0, 464 }, { 9, 0, 639 }, { 7, 10, 503 }, { 5, 11, 366 }, + { 5, 0, 15 }, { 6, 0, 56 }, { 7, 0, 1758 }, { 8, 0, 500 }, + { 9, 0, 730 }, { 11, 0, 331 }, { 13, 0, 150 }, { 14, 0, 282 }, + { 5, 11, 305 }, { 9, 11, 560 }, { 13, 11, 208 }, { 4, 10, 113 }, + { 5, 10, 163 }, { 5, 10, 735 }, { 7, 10, 1009 }, { 9, 10, 9 }, + { 9, 10, 771 }, { 12, 10, 90 }, { 13, 10, 138 }, { 13, 10, 410 }, + { 15, 10, 128 }, { 4, 10, 324 }, { 10, 10, 104 }, { 7, 11, 466 }, + { 14, 11, 27 }, { 6, 0, 1886 }, { 5, 0, 205 }, { 6, 0, 438 }, + { 9, 0, 711 }, { 4, 11, 480 }, { 6, 11, 167 }, { 6, 11, 302 }, + { 6, 11, 1642 }, { 7, 11, 130 }, { 7, 11, 656 }, { 7, 11, 837 }, + { 7, 11, 1547 }, { 7, 11, 1657 }, { 8, 11, 429 }, { 9, 11, 228 }, + { 10, 11, 643 }, { 13, 11, 289 }, { 13, 11, 343 }, { 19, 11, 101 }, + { 6, 0, 865 }, { 6, 0, 2025 }, { 8, 0, 965 }, { 7, 11, 278 }, + { 10, 11, 739 }, { 11, 11, 708 }, { 13, 11, 348 }, { 5, 0, 534 }, + { 7, 11, 1922 }, { 9, 0, 691 }, { 4, 10, 935 }, { 5, 10, 823 }, + { 6, 0, 443 }, { 9, 0, 237 }, { 9, 0, 571 }, { 9, 0, 695 }, + { 10, 0, 139 }, { 11, 0, 715 }, { 12, 0, 417 }, { 13, 0, 421 }, + { 5, 10, 269 }, { 7, 10, 434 }, { 7, 10, 891 }, { 8, 10, 339 }, + { 9, 10, 702 }, { 11, 10, 594 }, { 11, 10, 718 }, { 17, 10, 100 }, + { 6, 0, 1555 }, { 7, 0, 878 }, { 9, 10, 485 }, { 13, 10, 264 }, + { 6, 10, 1713 }, { 7, 10, 1810 }, { 11, 10, 866 }, { 12, 10, 103 }, + { 13, 10, 495 }, { 7, 10, 900 }, { 6, 0, 1410 }, { 9, 11, 316 }, + { 11, 11, 256 }, { 4, 0, 995 }, { 7, 0, 1033 }, { 4, 0, 578 }, + { 10, 0, 881 }, { 12, 0, 740 }, { 12, 0, 743 }, { 12, 0, 759 }, + { 4, 0, 822 }, { 5, 0, 923 }, { 14, 10, 143 }, { 7, 11, 1696 }, + { 6, 11, 363 }, { 7, 11, 1955 }, { 8, 11, 725 }, { 4, 0, 924 }, + { 5, 0, 665 }, { 7, 10, 2029 }, { 7, 0, 1901 }, { 4, 0, 265 }, + { 6, 0, 1092 }, { 6, 0, 1417 }, { 7, 0, 807 }, { 7, 0, 950 }, + { 5, 0, 93 }, { 12, 0, 267 }, { 13, 0, 498 }, { 7, 0, 1451 }, + { 5, 11, 813 }, { 7, 11, 2046 }, { 5, 10, 625 }, { 7, 10, 1617 }, + { 7, 0, 747 }, { 6, 0, 788 }, { 9, 0, 828 }, { 7, 0, 184 }, + { 11, 0, 307 }, { 11, 0, 400 }, { 15, 0, 130 }, { 5, 11, 712 }, + { 7, 11, 1855 }, { 8, 10, 425 }, { 8, 10, 693 }, { 9, 10, 720 }, + { 10, 10, 380 }, { 10, 10, 638 }, { 11, 11, 17 }, { 11, 10, 473 }, + { 12, 10, 61 }, { 13, 11, 321 }, { 16, 11, 67 }, { 7, 0, 198 }, + { 6, 11, 320 }, { 7, 11, 781 }, { 7, 11, 1921 }, { 9, 11, 55 }, + { 10, 11, 186 }, { 10, 11, 273 }, { 10, 11, 664 }, { 10, 11, 801 }, + { 11, 11, 996 }, { 11, 11, 997 }, { 13, 11, 157 }, { 14, 11, 170 }, + { 8, 11, 271 }, { 7, 0, 994 }, { 7, 11, 103 }, { 7, 11, 863 }, + { 11, 11, 184 }, { 14, 11, 299 }, { 17, 11, 62 }, { 11, 10, 551 }, + { 14, 10, 159 }, { 5, 0, 233 }, { 5, 0, 320 }, { 6, 0, 140 }, + { 8, 0, 295 }, { 8, 0, 615 }, { 8, 11, 615 }, { 5, 0, 978 }, + { 4, 0, 905 }, { 6, 0, 1701 }, { 9, 0, 843 }, { 4, 10, 168 }, + { 4, 0, 974 }, { 8, 0, 850 }, { 12, 0, 709 }, { 12, 0, 768 }, + { 12, 0, 786 }, { 7, 10, 91 }, { 24, 0, 6 }, { 10, 10, 532 }, + { 7, 10, 1884 }, { 4, 0, 509 }, { 6, 0, 1307 }, { 7, 0, 273 }, + { 5, 11, 77 }, { 7, 11, 1455 }, { 10, 11, 843 }, { 19, 11, 73 }, + { 22, 11, 5 }, { 4, 11, 458 }, { 7, 11, 1420 }, { 6, 11, 109 }, + { 10, 11, 382 }, { 6, 0, 201 }, { 6, 11, 330 }, { 7, 10, 70 }, + { 7, 11, 1084 }, { 10, 10, 240 }, { 11, 11, 142 }, { 19, 10, 93 }, + { 7, 0, 1041 }, { 12, 11, 328 }, { 5, 11, 354 }, { 6, 0, 1040 }, + { 5, 0, 693 }, { 6, 0, 774 }, { 11, 0, 234 }, { 4, 0, 336 }, + { 7, 0, 1399 }, { 11, 10, 392 }, { 20, 0, 22 }, { 20, 11, 22 }, + { 5, 0, 802 }, { 7, 0, 2021 }, { 8, 0, 805 }, { 5, 0, 167 }, + { 5, 0, 899 }, { 6, 0, 410 }, { 9, 0, 777 }, { 9, 0, 789 }, + { 6, 0, 1705 }, { 7, 10, 655 }, { 7, 10, 1844 }, { 4, 10, 145 }, + { 6, 10, 176 }, { 7, 10, 395 }, { 9, 10, 562 }, { 4, 10, 501 }, + { 7, 0, 10 }, { 5, 0, 11 }, { 6, 0, 117 }, { 6, 0, 485 }, + { 7, 0, 1133 }, { 9, 0, 582 }, { 9, 0, 594 }, { 10, 0, 82 }, + { 11, 0, 21 }, { 11, 0, 818 }, { 12, 0, 535 }, { 13, 0, 86 }, + { 20, 0, 91 }, { 23, 0, 13 }, { 6, 10, 509 }, { 4, 0, 264 }, + { 7, 0, 1067 }, { 8, 0, 204 }, { 8, 0, 385 }, { 11, 0, 953 }, + { 11, 11, 737 }, { 10, 0, 56 }, { 6, 0, 1917 }, { 5, 0, 470 }, + { 10, 11, 657 }, { 14, 11, 297 }, { 14, 11, 361 }, { 7, 11, 412 }, + { 7, 0, 1198 }, { 7, 11, 1198 }, { 8, 11, 556 }, { 14, 11, 123 }, + { 14, 11, 192 }, { 15, 11, 27 }, { 7, 11, 1985 }, { 14, 11, 146 }, + { 15, 11, 42 }, { 16, 11, 23 }, { 17, 11, 86 }, { 18, 11, 17 }, + { 11, 0, 1015 }, { 8, 11, 122 }, { 4, 10, 114 }, { 9, 10, 492 }, + { 13, 10, 462 }, { 14, 10, 215 }, { 4, 10, 77 }, { 5, 10, 361 }, + { 6, 10, 139 }, { 6, 10, 401 }, { 6, 10, 404 }, { 7, 10, 413 }, + { 7, 10, 715 }, { 7, 10, 1716 }, { 11, 10, 279 }, { 12, 10, 179 }, + { 12, 10, 258 }, { 13, 10, 244 }, { 14, 10, 358 }, { 6, 10, 1717 }, + { 7, 10, 1061 }, { 8, 10, 82 }, { 11, 10, 250 }, { 12, 10, 420 }, + { 13, 10, 184 }, { 5, 0, 715 }, { 7, 10, 724 }, { 9, 0, 919 }, + { 9, 0, 922 }, { 9, 0, 927 }, { 9, 0, 933 }, { 9, 0, 962 }, + { 9, 0, 1000 }, { 9, 0, 1002 }, { 9, 0, 1021 }, { 12, 0, 890 }, + { 12, 0, 907 }, { 12, 0, 930 }, { 15, 0, 207 }, { 15, 0, 228 }, + { 15, 0, 238 }, { 21, 0, 61 }, { 8, 0, 794 }, { 9, 0, 400 }, + { 10, 0, 298 }, { 14, 0, 228 }, { 5, 11, 430 }, { 5, 11, 932 }, + { 6, 11, 131 }, { 7, 11, 417 }, { 9, 11, 522 }, { 11, 11, 314 }, + { 13, 11, 390 }, { 4, 0, 867 }, { 8, 0, 724 }, { 4, 11, 507 }, + { 9, 11, 261 }, { 4, 11, 343 }, { 5, 11, 511 }, { 6, 0, 190 }, + { 7, 0, 768 }, { 7, 0, 1170 }, { 6, 10, 513 }, { 7, 10, 1052 }, + { 7, 11, 455 }, { 10, 11, 591 }, { 6, 0, 1066 }, { 9, 10, 899 }, + { 14, 0, 67 }, { 19, 0, 60 }, { 4, 0, 948 }, { 18, 0, 174 }, + { 18, 0, 176 }, { 7, 0, 1023 }, { 7, 10, 1417 }, { 12, 10, 382 }, + { 17, 10, 48 }, { 24, 10, 12 }, { 6, 11, 575 }, { 4, 0, 764 }, + { 6, 10, 545 }, { 7, 10, 565 }, { 7, 10, 1669 }, { 10, 10, 114 }, + { 11, 10, 642 }, { 12, 10, 618 }, { 6, 0, 137 }, { 9, 0, 75 }, + { 9, 0, 253 }, { 10, 0, 194 }, { 10, 0, 444 }, { 4, 0, 756 }, + { 5, 10, 5 }, { 8, 0, 1008 }, { 7, 10, 192 }, { 4, 0, 842 }, + { 11, 0, 643 }, { 12, 0, 115 }, { 8, 10, 763 }, { 11, 0, 67 }, + { 5, 10, 759 }, { 4, 0, 821 }, { 5, 0, 760 }, { 7, 0, 542 }, + { 8, 0, 135 }, { 8, 0, 496 }, { 7, 11, 580 }, { 7, 10, 370 }, + { 7, 10, 1007 }, { 7, 10, 1177 }, { 7, 10, 1565 }, { 7, 10, 1237 }, + { 12, 0, 736 }, { 7, 0, 319 }, { 7, 0, 355 }, { 7, 0, 763 }, + { 10, 0, 389 }, { 17, 0, 43 }, { 8, 11, 333 }, { 10, 11, 182 }, + { 4, 10, 87 }, { 5, 10, 250 }, { 13, 10, 298 }, { 10, 0, 786 }, + { 6, 0, 2044 }, { 8, 11, 330 }, { 12, 11, 477 }, { 7, 11, 1338 }, + { 4, 11, 125 }, { 6, 0, 1030 }, { 6, 0, 1083 }, { 4, 11, 721 }, + { 7, 10, 814 }, { 7, 11, 776 }, { 8, 11, 145 }, { 19, 11, 56 }, + { 6, 0, 1226 }, { 4, 10, 57 }, { 7, 10, 1195 }, { 7, 10, 1438 }, + { 7, 10, 1548 }, { 7, 10, 1835 }, { 7, 10, 1904 }, { 9, 10, 757 }, + { 10, 10, 604 }, { 11, 10, 519 }, { 7, 11, 792 }, { 8, 11, 147 }, + { 10, 11, 821 }, { 11, 11, 1021 }, { 9, 11, 797 }, { 4, 0, 58 }, + { 5, 0, 286 }, { 6, 0, 319 }, { 7, 0, 402 }, { 7, 0, 1254 }, + { 7, 0, 1903 }, { 8, 0, 356 }, { 12, 0, 408 }, { 4, 0, 389 }, + { 4, 0, 815 }, { 9, 0, 181 }, { 9, 0, 255 }, { 10, 0, 8 }, + { 10, 0, 29 }, { 10, 0, 816 }, { 11, 0, 311 }, { 11, 0, 561 }, + { 12, 0, 67 }, { 13, 0, 181 }, { 7, 11, 1472 }, { 7, 11, 1554 }, + { 7, 11, 1071 }, { 7, 11, 1541 }, { 7, 11, 1767 }, { 7, 11, 1806 }, + { 7, 11, 1999 }, { 9, 11, 248 }, { 10, 11, 400 }, { 11, 11, 162 }, + { 11, 11, 178 }, { 11, 11, 242 }, { 12, 11, 605 }, { 15, 11, 26 }, + { 16, 11, 44 }, { 5, 11, 168 }, { 5, 11, 930 }, { 8, 11, 74 }, + { 9, 11, 623 }, { 12, 11, 500 }, { 12, 11, 579 }, { 13, 11, 41 }, + { 15, 11, 93 }, { 6, 11, 220 }, { 7, 11, 1101 }, { 13, 11, 105 }, + { 5, 0, 474 }, { 7, 0, 507 }, { 4, 10, 209 }, { 7, 11, 507 }, + { 7, 10, 902 }, { 4, 0, 427 }, { 6, 0, 413 }, { 7, 10, 335 }, + { 7, 10, 1437 }, { 7, 10, 1668 }, { 8, 10, 553 }, { 8, 10, 652 }, + { 8, 10, 656 }, { 9, 10, 558 }, { 11, 10, 743 }, { 21, 10, 18 }, + { 4, 0, 730 }, { 6, 11, 19 }, { 7, 11, 1413 }, { 11, 11, 428 }, + { 5, 0, 373 }, { 4, 10, 559 }, { 7, 11, 96 }, { 8, 11, 401 }, + { 9, 11, 896 }, { 7, 0, 799 }, { 7, 0, 1972 }, { 5, 10, 1017 }, + { 10, 10, 511 }, { 7, 0, 1793 }, { 7, 11, 1961 }, { 7, 11, 1965 }, + { 8, 11, 702 }, { 8, 11, 750 }, { 8, 11, 150 }, { 8, 11, 737 }, + { 12, 11, 366 }, { 4, 0, 322 }, { 5, 10, 709 }, { 8, 11, 800 }, + { 9, 11, 148 }, { 9, 11, 872 }, { 9, 11, 890 }, { 11, 11, 309 }, + { 11, 11, 1001 }, { 13, 11, 267 }, { 13, 11, 323 }, { 6, 10, 1745 }, + { 7, 0, 290 }, { 8, 10, 206 }, { 7, 0, 1651 }, { 17, 0, 89 }, + { 11, 0, 2 }, { 4, 0, 672 }, { 6, 0, 1860 }, { 8, 0, 905 }, + { 10, 0, 844 }, { 10, 0, 846 }, { 10, 0, 858 }, { 12, 0, 699 }, + { 12, 0, 746 }, { 12, 0, 772 }, { 7, 11, 424 }, { 5, 11, 547 }, + { 5, 0, 737 }, { 5, 11, 490 }, { 6, 11, 615 }, { 6, 11, 620 }, + { 7, 11, 683 }, { 6, 0, 746 }, { 6, 0, 1612 }, { 4, 10, 776 }, + { 9, 11, 385 }, { 21, 11, 17 }, { 5, 0, 145 }, { 7, 10, 1272 }, + { 7, 0, 884 }, { 12, 0, 124 }, { 4, 0, 387 }, { 7, 0, 1288 }, + { 5, 11, 133 }, { 8, 10, 406 }, { 8, 11, 187 }, { 6, 0, 679 }, + { 8, 11, 8 }, { 10, 11, 0 }, { 7, 0, 550 }, { 7, 11, 798 }, + { 8, 11, 685 }, { 7, 11, 1086 }, { 17, 11, 46 }, { 8, 10, 175 }, + { 10, 10, 168 }, { 10, 10, 573 }, { 7, 0, 1305 }, { 4, 0, 576 }, + { 7, 0, 1263 }, { 6, 0, 686 }, { 6, 0, 1563 }, { 6, 0, 607 }, + { 5, 0, 919 }, { 6, 0, 1673 }, { 20, 0, 37 }, { 8, 11, 774 }, + { 10, 11, 670 }, { 12, 11, 51 }, { 5, 10, 784 }, { 11, 10, 882 }, + { 4, 0, 82 }, { 5, 0, 333 }, { 5, 0, 904 }, { 6, 0, 207 }, + { 7, 0, 325 }, { 7, 0, 1726 }, { 8, 0, 101 }, { 10, 0, 778 }, + { 11, 0, 220 }, { 7, 11, 371 }, { 4, 0, 958 }, { 5, 0, 903 }, + { 4, 11, 127 }, { 5, 11, 350 }, { 6, 11, 356 }, { 8, 11, 426 }, + { 9, 11, 572 }, { 10, 11, 247 }, { 11, 11, 312 }, { 12, 0, 147 }, + { 6, 11, 59 }, { 7, 11, 885 }, { 9, 11, 603 }, { 13, 11, 397 }, + { 10, 0, 367 }, { 9, 10, 14 }, { 9, 10, 441 }, { 11, 10, 9 }, + { 11, 10, 966 }, { 12, 10, 287 }, { 13, 10, 342 }, { 13, 10, 402 }, + { 15, 10, 110 }, { 15, 10, 163 }, { 6, 0, 690 }, { 4, 0, 705 }, + { 9, 0, 651 }, { 11, 0, 971 }, { 13, 0, 273 }, { 7, 10, 1428 }, + { 7, 10, 1640 }, { 7, 10, 1867 }, { 9, 10, 169 }, { 9, 10, 182 }, + { 9, 10, 367 }, { 9, 10, 478 }, { 9, 10, 506 }, { 9, 10, 551 }, + { 9, 10, 557 }, { 9, 10, 648 }, { 9, 10, 697 }, { 9, 10, 705 }, + { 9, 10, 725 }, { 9, 10, 787 }, { 9, 10, 794 }, { 10, 10, 198 }, + { 10, 10, 214 }, { 10, 10, 267 }, { 10, 10, 275 }, { 10, 10, 456 }, + { 10, 10, 551 }, { 10, 10, 561 }, { 10, 10, 613 }, { 10, 10, 627 }, + { 10, 10, 668 }, { 10, 10, 675 }, { 10, 10, 691 }, { 10, 10, 695 }, + { 10, 10, 707 }, { 10, 10, 715 }, { 11, 10, 183 }, { 11, 10, 201 }, + { 11, 10, 262 }, { 11, 10, 352 }, { 11, 10, 439 }, { 11, 10, 493 }, + { 11, 10, 572 }, { 11, 10, 591 }, { 11, 10, 608 }, { 11, 10, 611 }, + { 11, 10, 646 }, { 11, 10, 674 }, { 11, 10, 711 }, { 11, 10, 751 }, + { 11, 10, 761 }, { 11, 10, 776 }, { 11, 10, 785 }, { 11, 10, 850 }, + { 11, 10, 853 }, { 11, 10, 862 }, { 11, 10, 865 }, { 11, 10, 868 }, + { 11, 10, 875 }, { 11, 10, 898 }, { 11, 10, 902 }, { 11, 10, 903 }, + { 11, 10, 910 }, { 11, 10, 932 }, { 11, 10, 942 }, { 11, 10, 957 }, + { 11, 10, 967 }, { 11, 10, 972 }, { 12, 10, 148 }, { 12, 10, 195 }, + { 12, 10, 220 }, { 12, 10, 237 }, { 12, 10, 318 }, { 12, 10, 339 }, + { 12, 10, 393 }, { 12, 10, 445 }, { 12, 10, 450 }, { 12, 10, 474 }, + { 12, 10, 505 }, { 12, 10, 509 }, { 12, 10, 533 }, { 12, 10, 591 }, + { 12, 10, 594 }, { 12, 10, 597 }, { 12, 10, 621 }, { 12, 10, 633 }, + { 12, 10, 642 }, { 13, 10, 59 }, { 13, 10, 60 }, { 13, 10, 145 }, + { 13, 10, 239 }, { 13, 10, 250 }, { 13, 10, 329 }, { 13, 10, 344 }, + { 13, 10, 365 }, { 13, 10, 372 }, { 13, 10, 387 }, { 13, 10, 403 }, + { 13, 10, 414 }, { 13, 10, 456 }, { 13, 10, 470 }, { 13, 10, 478 }, + { 13, 10, 483 }, { 13, 10, 489 }, { 14, 10, 55 }, { 14, 10, 57 }, + { 14, 10, 81 }, { 14, 10, 90 }, { 14, 10, 148 }, { 14, 10, 239 }, + { 14, 10, 266 }, { 14, 10, 321 }, { 14, 10, 326 }, { 14, 10, 327 }, + { 14, 10, 330 }, { 14, 10, 347 }, { 14, 10, 355 }, { 14, 10, 401 }, + { 14, 10, 404 }, { 14, 10, 411 }, { 14, 10, 414 }, { 14, 10, 416 }, + { 14, 10, 420 }, { 15, 10, 61 }, { 15, 10, 74 }, { 15, 10, 87 }, + { 15, 10, 88 }, { 15, 10, 94 }, { 15, 10, 96 }, { 15, 10, 116 }, + { 15, 10, 149 }, { 15, 10, 154 }, { 16, 10, 50 }, { 16, 10, 63 }, + { 16, 10, 73 }, { 17, 10, 2 }, { 17, 10, 66 }, { 17, 10, 92 }, + { 17, 10, 103 }, { 17, 10, 112 }, { 17, 10, 120 }, { 18, 10, 50 }, + { 18, 10, 54 }, { 18, 10, 82 }, { 18, 10, 86 }, { 18, 10, 90 }, + { 18, 10, 111 }, { 18, 10, 115 }, { 18, 10, 156 }, { 19, 10, 40 }, + { 19, 10, 79 }, { 20, 10, 78 }, { 21, 10, 22 }, { 7, 0, 887 }, + { 5, 10, 161 }, { 7, 10, 839 }, { 14, 11, 98 }, { 6, 0, 90 }, + { 10, 11, 356 }, { 7, 11, 441 }, { 6, 11, 111 }, { 7, 11, 4 }, + { 8, 11, 163 }, { 8, 11, 776 }, { 10, 11, 566 }, { 6, 0, 908 }, + { 6, 0, 1261 }, { 7, 0, 813 }, { 12, 0, 497 }, { 13, 0, 56 }, + { 6, 0, 1235 }, { 7, 0, 429 }, { 7, 11, 1994 }, { 10, 0, 904 }, + { 6, 0, 125 }, { 7, 0, 1277 }, { 9, 0, 772 }, { 23, 0, 12 }, + { 4, 0, 841 }, { 5, 0, 386 }, { 5, 11, 386 }, { 5, 11, 297 }, + { 7, 11, 1038 }, { 6, 0, 860 }, { 6, 0, 1069 }, { 7, 11, 309 }, + { 8, 0, 946 }, { 7, 10, 1814 }, { 13, 11, 418 }, { 8, 11, 363 }, + { 10, 0, 768 }, { 11, 0, 787 }, { 22, 11, 30 }, { 22, 11, 33 }, + { 6, 0, 160 }, { 7, 0, 1106 }, { 9, 0, 770 }, { 11, 0, 112 }, + { 12, 0, 413 }, { 11, 11, 216 }, { 11, 11, 340 }, { 8, 10, 139 }, + { 7, 11, 1390 }, { 7, 11, 808 }, { 4, 11, 280 }, { 12, 0, 271 }, + { 17, 0, 109 }, { 7, 10, 643 }, { 8, 10, 236 }, { 12, 11, 54 }, + { 4, 11, 421 }, { 5, 11, 548 }, { 11, 0, 719 }, { 12, 0, 36 }, + { 13, 0, 337 }, { 7, 0, 581 }, { 9, 0, 644 }, { 9, 0, 699 }, + { 11, 11, 511 }, { 13, 11, 394 }, { 14, 11, 298 }, { 14, 11, 318 }, + { 18, 11, 103 }, { 7, 0, 304 }, { 9, 0, 646 }, { 9, 0, 862 }, + { 11, 0, 696 }, { 12, 0, 208 }, { 15, 0, 79 }, { 19, 0, 108 }, + { 4, 0, 631 }, { 7, 0, 1126 }, { 7, 0, 1536 }, { 7, 11, 1527 }, + { 8, 0, 880 }, { 10, 0, 869 }, { 10, 0, 913 }, { 7, 0, 1513 }, + { 5, 10, 54 }, { 6, 11, 254 }, { 9, 11, 109 }, { 10, 11, 103 }, + { 7, 0, 981 }, { 5, 11, 729 }, { 4, 10, 744 }, { 4, 0, 434 }, + { 6, 0, 550 }, { 7, 0, 930 }, { 10, 0, 476 }, { 13, 0, 452 }, + { 19, 0, 104 }, { 6, 11, 1630 }, { 10, 10, 402 }, { 18, 10, 55 }, + { 5, 0, 553 }, { 10, 0, 824 }, { 8, 0, 452 }, { 8, 0, 151 }, + { 9, 10, 624 }, { 4, 10, 572 }, { 4, 0, 772 }, { 5, 11, 671 }, + { 5, 0, 292 }, { 10, 0, 135 }, { 4, 11, 889 }, { 12, 11, 207 }, + { 9, 0, 504 }, { 6, 10, 43 }, { 7, 10, 38 }, { 8, 10, 248 }, + { 10, 10, 513 }, { 6, 0, 1089 }, { 7, 11, 1910 }, { 4, 11, 627 }, + { 5, 11, 775 }, { 7, 0, 783 }, { 5, 10, 766 }, { 5, 10, 363 }, + { 7, 0, 387 }, { 7, 11, 387 }, { 7, 0, 393 }, { 10, 0, 603 }, + { 11, 0, 206 }, { 7, 11, 202 }, { 11, 11, 362 }, { 11, 11, 948 }, + { 12, 11, 388 }, { 6, 11, 507 }, { 7, 11, 451 }, { 8, 11, 389 }, + { 12, 11, 490 }, { 13, 11, 16 }, { 13, 11, 215 }, { 13, 11, 351 }, + { 18, 11, 132 }, { 19, 11, 125 }, { 4, 0, 912 }, { 9, 0, 232 }, + { 7, 11, 841 }, { 6, 10, 258 }, { 12, 10, 409 }, { 5, 10, 249 }, + { 20, 10, 82 }, { 8, 11, 566 }, { 6, 0, 977 }, { 7, 11, 1214 }, + { 7, 0, 1973 }, { 8, 0, 716 }, { 7, 0, 98 }, { 5, 0, 733 }, + { 5, 11, 912 }, { 6, 11, 1695 }, { 5, 10, 393 }, { 6, 10, 378 }, + { 7, 10, 1981 }, { 9, 10, 32 }, { 9, 10, 591 }, { 10, 10, 685 }, + { 10, 10, 741 }, { 14, 10, 382 }, { 5, 10, 788 }, { 10, 0, 19 }, + { 11, 0, 911 }, { 7, 10, 1968 }, { 13, 10, 509 }, { 5, 0, 668 }, + { 5, 11, 236 }, { 6, 11, 572 }, { 8, 11, 492 }, { 11, 11, 618 }, + { 16, 11, 56 }, { 7, 11, 1789 }, { 4, 0, 360 }, { 5, 0, 635 }, + { 5, 0, 700 }, { 5, 10, 58 }, { 5, 10, 171 }, { 5, 10, 683 }, + { 6, 10, 291 }, { 6, 10, 566 }, { 7, 10, 1650 }, { 11, 10, 523 }, + { 12, 10, 273 }, { 12, 10, 303 }, { 15, 10, 39 }, { 15, 10, 111 }, + { 5, 0, 901 }, { 6, 10, 589 }, { 5, 11, 190 }, { 8, 11, 318 }, + { 12, 0, 656 }, { 7, 0, 726 }, { 24, 0, 9 }, { 4, 10, 917 }, + { 5, 10, 1005 }, { 7, 10, 1598 }, { 6, 11, 491 }, { 4, 10, 919 }, + { 5, 11, 434 }, { 9, 0, 72 }, { 6, 0, 1269 }, { 6, 0, 1566 }, + { 6, 0, 1621 }, { 9, 0, 463 }, { 10, 0, 595 }, { 4, 10, 255 }, + { 5, 10, 302 }, { 6, 10, 132 }, { 7, 10, 128 }, { 7, 10, 283 }, + { 7, 10, 1299 }, { 10, 10, 52 }, { 10, 10, 514 }, { 11, 10, 925 }, + { 13, 10, 92 }, { 14, 10, 309 }, { 7, 0, 1454 }, { 6, 0, 1287 }, + { 11, 0, 600 }, { 13, 0, 245 }, { 9, 10, 173 }, { 8, 0, 989 }, + { 7, 0, 164 }, { 7, 0, 1571 }, { 9, 0, 107 }, { 12, 0, 225 }, + { 6, 0, 1061 }, { 13, 10, 442 }, { 4, 0, 27 }, { 5, 0, 484 }, + { 5, 0, 510 }, { 6, 0, 434 }, { 7, 0, 1000 }, { 7, 0, 1098 }, + { 8, 0, 2 }, { 7, 11, 85 }, { 7, 11, 247 }, { 8, 11, 585 }, + { 10, 11, 163 }, { 10, 11, 316 }, { 11, 11, 103 }, { 14, 11, 0 }, + { 6, 0, 1127 }, { 4, 0, 460 }, { 6, 0, 852 }, { 6, 10, 210 }, + { 4, 0, 932 }, { 5, 0, 891 }, { 6, 0, 588 }, { 19, 11, 83 }, + { 8, 0, 625 }, { 4, 10, 284 }, { 6, 10, 223 }, { 6, 0, 76 }, + { 8, 0, 92 }, { 9, 0, 221 }, { 4, 11, 124 }, { 10, 11, 457 }, + { 11, 11, 121 }, { 11, 11, 169 }, { 11, 11, 422 }, { 11, 11, 870 }, + { 12, 11, 214 }, { 13, 11, 389 }, { 14, 11, 187 }, { 15, 11, 77 }, + { 9, 11, 618 }, { 10, 11, 482 }, { 4, 10, 218 }, { 7, 10, 526 }, + { 15, 10, 137 }, { 13, 0, 9 }, { 14, 0, 104 }, { 14, 0, 311 }, + { 4, 10, 270 }, { 5, 10, 192 }, { 6, 10, 332 }, { 7, 10, 1322 }, + { 12, 10, 661 }, { 7, 11, 1193 }, { 6, 11, 107 }, { 7, 11, 638 }, + { 7, 11, 1632 }, { 9, 11, 396 }, { 4, 0, 763 }, { 4, 0, 622 }, + { 5, 11, 370 }, { 6, 11, 1756 }, { 5, 0, 253 }, { 7, 0, 546 }, + { 9, 0, 73 }, { 10, 0, 110 }, { 14, 0, 185 }, { 17, 0, 119 }, + { 5, 11, 204 }, { 7, 0, 624 }, { 7, 0, 916 }, { 10, 0, 256 }, + { 11, 0, 87 }, { 7, 10, 379 }, { 8, 10, 481 }, { 9, 10, 377 }, + { 5, 0, 212 }, { 12, 0, 35 }, { 13, 0, 382 }, { 5, 11, 970 }, + { 6, 11, 1706 }, { 9, 0, 746 }, { 5, 10, 1003 }, { 6, 10, 149 }, + { 10, 0, 150 }, { 11, 0, 849 }, { 13, 0, 330 }, { 8, 10, 262 }, + { 9, 10, 627 }, { 11, 10, 214 }, { 11, 10, 404 }, { 11, 10, 457 }, + { 11, 10, 780 }, { 11, 10, 913 }, { 13, 10, 401 }, { 14, 10, 200 }, + { 6, 0, 1466 }, { 7, 11, 3 }, { 6, 0, 1299 }, { 4, 11, 35 }, + { 5, 11, 121 }, { 5, 11, 483 }, { 5, 11, 685 }, { 6, 11, 489 }, + { 7, 11, 1204 }, { 8, 11, 394 }, { 7, 10, 742 }, { 4, 10, 142 }, + { 8, 10, 304 }, { 4, 11, 921 }, { 5, 11, 1007 }, { 6, 0, 1518 }, + { 6, 0, 1229 }, { 7, 0, 1175 }, { 5, 0, 816 }, { 12, 0, 159 }, + { 4, 10, 471 }, { 4, 11, 712 }, { 5, 10, 51 }, { 6, 10, 602 }, + { 7, 10, 925 }, { 8, 10, 484 }, { 10, 10, 195 }, { 6, 11, 1629 }, + { 5, 0, 869 }, { 5, 0, 968 }, { 6, 0, 1626 }, { 8, 0, 734 }, + { 8, 0, 784 }, { 4, 0, 542 }, { 6, 0, 1716 }, { 6, 0, 1727 }, + { 7, 0, 1082 }, { 7, 0, 1545 }, { 8, 0, 56 }, { 8, 0, 118 }, + { 8, 0, 412 }, { 8, 0, 564 }, { 9, 0, 888 }, { 9, 0, 908 }, + { 10, 0, 50 }, { 10, 0, 423 }, { 11, 0, 685 }, { 11, 0, 697 }, + { 11, 0, 933 }, { 12, 0, 299 }, { 13, 0, 126 }, { 13, 0, 136 }, + { 13, 0, 170 }, { 13, 0, 190 }, { 8, 10, 688 }, { 4, 10, 697 }, + { 4, 0, 232 }, { 9, 0, 202 }, { 10, 0, 474 }, { 12, 0, 433 }, + { 8, 0, 212 }, { 6, 0, 108 }, { 7, 0, 1003 }, { 7, 0, 1181 }, + { 8, 0, 111 }, { 8, 0, 343 }, { 5, 10, 221 }, { 7, 11, 1255 }, + { 5, 11, 485 }, { 6, 0, 1712 }, { 14, 0, 216 }, { 5, 0, 643 }, + { 6, 0, 516 }, { 4, 11, 285 }, { 5, 11, 317 }, { 6, 11, 301 }, + { 7, 11, 7 }, { 8, 11, 153 }, { 10, 11, 766 }, { 11, 11, 468 }, + { 12, 11, 467 }, { 13, 11, 143 }, { 4, 0, 133 }, { 7, 0, 711 }, + { 7, 0, 1298 }, { 7, 0, 1585 }, { 6, 0, 650 }, { 7, 11, 512 }, + { 6, 0, 99 }, { 7, 0, 1808 }, { 17, 0, 57 }, { 6, 0, 246 }, + { 6, 0, 574 }, { 7, 0, 428 }, { 9, 0, 793 }, { 10, 0, 669 }, + { 11, 0, 485 }, { 11, 0, 840 }, { 12, 0, 300 }, { 14, 0, 250 }, + { 17, 0, 55 }, { 4, 10, 132 }, { 5, 10, 69 }, { 7, 10, 1242 }, + { 8, 0, 1023 }, { 7, 0, 302 }, { 4, 10, 111 }, { 7, 0, 1871 }, + { 4, 0, 728 }, { 9, 0, 252 }, { 4, 10, 767 }, { 6, 0, 461 }, + { 7, 0, 1590 }, { 7, 10, 1416 }, { 7, 10, 2005 }, { 8, 10, 131 }, + { 8, 10, 466 }, { 9, 10, 672 }, { 13, 10, 252 }, { 20, 10, 103 }, + { 6, 0, 323 }, { 7, 0, 1564 }, { 7, 0, 461 }, { 8, 0, 775 }, + { 6, 10, 44 }, { 8, 10, 368 }, { 11, 0, 172 }, { 4, 0, 464 }, + { 4, 10, 570 }, { 5, 10, 120 }, { 9, 11, 269 }, { 6, 10, 227 }, + { 7, 10, 1589 }, { 6, 11, 1719 }, { 6, 11, 1735 }, { 7, 11, 2016 }, + { 7, 11, 2020 }, { 8, 11, 837 }, { 9, 11, 852 }, { 7, 0, 727 }, + { 18, 0, 73 }, { 4, 0, 1023 }, { 7, 11, 852 }, { 7, 10, 1529 }, + { 8, 0, 577 }, { 10, 11, 568 }, { 6, 0, 1037 }, { 8, 11, 67 }, + { 10, 11, 419 }, { 4, 0, 413 }, { 5, 0, 677 }, { 8, 0, 432 }, + { 12, 0, 280 }, { 10, 0, 600 }, { 6, 10, 1667 }, { 7, 11, 967 }, + { 7, 10, 2036 }, { 13, 11, 11 }, { 6, 10, 511 }, { 12, 10, 132 }, + { 6, 0, 799 }, { 5, 10, 568 }, { 6, 10, 138 }, { 7, 10, 1293 }, + { 8, 0, 159 }, { 4, 10, 565 }, { 8, 10, 827 }, { 7, 0, 646 }, + { 7, 0, 1730 }, { 11, 0, 446 }, { 13, 0, 178 }, { 4, 10, 922 }, + { 5, 10, 1023 }, { 7, 11, 11 }, { 4, 0, 395 }, { 11, 0, 145 }, + { 7, 10, 1002 }, { 9, 0, 174 }, { 10, 0, 164 }, { 11, 0, 440 }, + { 11, 0, 514 }, { 11, 0, 841 }, { 15, 0, 98 }, { 21, 0, 20 }, + { 6, 0, 426 }, { 10, 0, 608 }, { 11, 0, 1002 }, { 7, 11, 320 }, + { 8, 11, 51 }, { 12, 11, 481 }, { 12, 11, 570 }, { 20, 11, 106 }, + { 9, 0, 977 }, { 9, 0, 983 }, { 4, 11, 445 }, { 10, 0, 250 }, + { 11, 0, 100 }, { 6, 0, 1982 }, { 8, 10, 402 }, { 5, 11, 239 }, + { 4, 10, 716 }, { 13, 10, 31 }, { 5, 0, 476 }, { 7, 11, 83 }, + { 7, 11, 1990 }, { 8, 11, 130 }, { 11, 11, 720 }, { 8, 10, 691 }, + { 8, 10, 731 }, { 5, 11, 123 }, { 6, 11, 530 }, { 7, 11, 348 }, + { 7, 11, 1419 }, { 5, 0, 76 }, { 6, 0, 458 }, { 6, 0, 497 }, + { 7, 0, 868 }, { 9, 0, 658 }, { 10, 0, 594 }, { 11, 0, 173 }, + { 11, 0, 566 }, { 12, 0, 20 }, { 12, 0, 338 }, { 13, 0, 200 }, + { 9, 11, 139 }, { 10, 11, 399 }, { 11, 11, 469 }, { 12, 11, 634 }, + { 13, 11, 223 }, { 9, 10, 840 }, { 10, 10, 803 }, { 5, 10, 847 }, + { 11, 11, 223 }, { 12, 11, 168 }, { 4, 11, 210 }, { 8, 0, 447 }, + { 9, 10, 53 }, { 9, 10, 268 }, { 9, 10, 901 }, { 10, 10, 518 }, + { 10, 10, 829 }, { 11, 10, 188 }, { 13, 10, 74 }, { 14, 10, 46 }, + { 15, 10, 17 }, { 15, 10, 33 }, { 17, 10, 40 }, { 18, 10, 36 }, + { 19, 10, 20 }, { 22, 10, 1 }, { 24, 10, 2 }, { 4, 0, 526 }, + { 7, 0, 1029 }, { 7, 0, 1054 }, { 19, 11, 59 }, { 22, 11, 2 }, + { 4, 0, 636 }, { 6, 0, 1875 }, { 6, 0, 1920 }, { 9, 0, 999 }, + { 12, 0, 807 }, { 12, 0, 825 }, { 15, 0, 179 }, { 15, 0, 190 }, + { 18, 0, 182 }, { 8, 10, 532 }, { 6, 0, 1699 }, { 7, 0, 660 }, + { 7, 0, 1124 }, { 17, 0, 31 }, { 19, 0, 22 }, { 23, 0, 14 }, + { 7, 10, 681 }, { 4, 11, 430 }, { 12, 10, 677 }, { 4, 10, 684 }, + { 8, 10, 384 }, { 4, 11, 756 }, { 5, 11, 213 }, { 7, 0, 188 }, + { 7, 10, 110 }, { 8, 10, 290 }, { 8, 10, 591 }, { 9, 10, 382 }, + { 9, 10, 649 }, { 11, 10, 71 }, { 11, 10, 155 }, { 11, 10, 313 }, + { 12, 10, 5 }, { 13, 10, 325 }, { 14, 10, 287 }, { 7, 10, 360 }, + { 7, 10, 425 }, { 9, 10, 66 }, { 9, 10, 278 }, { 10, 10, 644 }, + { 14, 11, 164 }, { 4, 0, 279 }, { 7, 0, 301 }, { 9, 0, 362 }, + { 6, 11, 586 }, { 7, 0, 1743 }, { 4, 0, 178 }, { 5, 0, 399 }, + { 4, 10, 900 }, { 5, 10, 861 }, { 5, 10, 254 }, { 7, 10, 985 }, + { 8, 10, 73 }, { 5, 11, 108 }, { 7, 10, 1959 }, { 8, 10, 683 }, + { 5, 11, 219 }, { 4, 11, 193 }, { 5, 11, 916 }, { 7, 11, 364 }, + { 10, 11, 398 }, { 10, 11, 726 }, { 11, 11, 317 }, { 11, 11, 626 }, + { 12, 11, 142 }, { 12, 11, 288 }, { 12, 11, 678 }, { 13, 11, 313 }, + { 15, 11, 113 }, { 18, 11, 114 }, { 21, 11, 30 }, { 22, 11, 53 }, + { 6, 11, 241 }, { 7, 11, 907 }, { 8, 11, 832 }, { 9, 11, 342 }, + { 10, 11, 729 }, { 11, 11, 284 }, { 11, 11, 445 }, { 11, 11, 651 }, + { 11, 11, 863 }, { 13, 11, 398 }, { 18, 11, 99 }, { 4, 0, 872 }, + { 6, 0, 831 }, { 6, 0, 1692 }, { 6, 0, 202 }, { 6, 0, 1006 }, + { 9, 0, 832 }, { 10, 0, 636 }, { 11, 0, 208 }, { 12, 0, 360 }, + { 17, 0, 118 }, { 18, 0, 27 }, { 20, 0, 67 }, { 9, 11, 734 }, + { 4, 10, 725 }, { 7, 11, 993 }, { 10, 11, 666 }, { 6, 0, 1954 }, + { 6, 10, 196 }, { 7, 0, 872 }, { 10, 0, 516 }, { 11, 0, 167 }, + { 5, 10, 831 }, { 4, 11, 562 }, { 9, 11, 254 }, { 11, 11, 879 }, + { 9, 0, 313 }, { 4, 0, 224 }, { 4, 11, 786 }, { 11, 0, 24 }, + { 12, 0, 170 }, { 8, 10, 723 }, { 5, 0, 546 }, { 7, 0, 35 }, + { 8, 0, 11 }, { 8, 0, 12 }, { 9, 0, 315 }, { 9, 0, 533 }, + { 10, 0, 802 }, { 11, 0, 166 }, { 12, 0, 525 }, { 14, 0, 243 }, + { 7, 0, 1937 }, { 13, 10, 80 }, { 13, 10, 437 }, { 17, 10, 74 }, + { 5, 0, 241 }, { 8, 0, 242 }, { 9, 0, 451 }, { 10, 0, 667 }, + { 11, 0, 598 }, { 12, 0, 429 }, { 22, 0, 46 }, { 6, 0, 1273 }, + { 9, 0, 830 }, { 5, 10, 848 }, { 6, 10, 66 }, { 8, 10, 764 }, + { 6, 0, 825 }, { 6, 0, 993 }, { 4, 0, 1006 }, { 10, 0, 327 }, + { 13, 0, 271 }, { 4, 10, 36 }, { 7, 10, 1387 }, { 11, 10, 755 }, + { 6, 0, 1023 }, { 7, 0, 1580 }, { 4, 0, 366 }, { 9, 0, 516 }, + { 4, 10, 887 }, { 6, 0, 1736 }, { 7, 0, 1891 }, { 6, 11, 216 }, + { 7, 11, 901 }, { 7, 11, 1343 }, { 8, 11, 493 }, { 6, 10, 165 }, + { 10, 10, 388 }, { 7, 11, 341 }, { 11, 11, 219 }, { 4, 10, 719 }, + { 7, 10, 155 }, { 6, 0, 1935 }, { 4, 0, 826 }, { 6, 0, 331 }, + { 6, 0, 1605 }, { 8, 0, 623 }, { 11, 0, 139 }, { 11, 0, 171 }, + { 7, 11, 1734 }, { 10, 11, 115 }, { 11, 11, 420 }, { 12, 11, 154 }, + { 13, 11, 404 }, { 14, 11, 346 }, { 15, 11, 54 }, { 15, 11, 112 }, + { 7, 0, 288 }, { 4, 10, 353 }, { 6, 10, 146 }, { 6, 10, 1789 }, + { 7, 10, 990 }, { 7, 10, 1348 }, { 9, 10, 665 }, { 9, 10, 898 }, + { 11, 10, 893 }, { 14, 10, 212 }, { 6, 0, 916 }, { 6, 0, 1592 }, + { 7, 0, 1888 }, { 4, 10, 45 }, { 7, 10, 1257 }, { 5, 11, 1011 }, + { 8, 11, 701 }, { 11, 11, 596 }, { 4, 11, 54 }, { 5, 11, 666 }, + { 7, 11, 1039 }, { 7, 11, 1130 }, { 9, 11, 195 }, { 10, 11, 302 }, + { 6, 0, 1471 }, { 6, 0, 1570 }, { 4, 0, 394 }, { 12, 10, 65 }, + { 8, 10, 816 }, { 7, 0, 1931 }, { 7, 0, 574 }, { 7, 0, 1719 }, + { 6, 11, 467 }, { 4, 0, 658 }, { 9, 0, 781 }, { 10, 0, 144 }, + { 11, 0, 385 }, { 13, 0, 161 }, { 13, 0, 228 }, { 13, 0, 268 }, + { 20, 0, 107 }, { 6, 11, 1669 }, { 8, 0, 374 }, { 7, 0, 735 }, + { 4, 0, 344 }, { 6, 0, 498 }, { 11, 0, 323 }, { 7, 0, 586 }, + { 7, 0, 1063 }, { 6, 10, 559 }, { 6, 10, 1691 }, { 9, 0, 155 }, + { 5, 0, 906 }, { 7, 11, 122 }, { 9, 11, 259 }, { 10, 11, 84 }, + { 11, 11, 470 }, { 12, 11, 541 }, { 13, 11, 379 }, { 6, 0, 1139 }, + { 10, 0, 108 }, { 11, 0, 116 }, { 6, 10, 456 }, { 5, 10, 925 }, + { 5, 11, 82 }, { 5, 11, 131 }, { 7, 11, 1755 }, { 8, 11, 31 }, + { 9, 11, 168 }, { 9, 11, 764 }, { 11, 11, 869 }, { 6, 11, 605 }, + { 5, 11, 278 }, { 9, 11, 68 }, { 4, 11, 163 }, { 5, 11, 201 }, + { 5, 11, 307 }, { 5, 11, 310 }, { 6, 11, 335 }, { 7, 11, 284 }, + { 8, 11, 165 }, { 7, 11, 1660 }, { 6, 11, 33 }, { 7, 11, 1244 }, + { 4, 0, 616 }, { 8, 11, 483 }, { 8, 0, 857 }, { 8, 0, 902 }, + { 8, 0, 910 }, { 10, 0, 879 }, { 12, 0, 726 }, { 4, 11, 199 }, + { 11, 11, 34 }, { 8, 0, 692 }, { 6, 10, 193 }, { 7, 10, 240 }, + { 7, 10, 1682 }, { 10, 10, 51 }, { 10, 10, 640 }, { 11, 10, 410 }, + { 13, 10, 82 }, { 14, 10, 247 }, { 14, 10, 331 }, { 14, 10, 377 }, + { 6, 0, 823 }, { 6, 0, 983 }, { 11, 10, 411 }, { 4, 0, 305 }, + { 8, 10, 633 }, { 10, 11, 203 }, { 6, 0, 681 }, { 6, 11, 326 }, + { 7, 11, 677 }, { 9, 11, 425 }, { 5, 0, 214 }, { 7, 0, 603 }, + { 8, 0, 611 }, { 9, 0, 686 }, { 10, 0, 88 }, { 11, 0, 459 }, + { 11, 0, 496 }, { 12, 0, 463 }, { 12, 0, 590 }, { 13, 0, 0 }, + { 8, 0, 1004 }, { 14, 0, 23 }, { 6, 0, 1703 }, { 19, 11, 8 }, + { 17, 11, 56 }, { 7, 0, 1443 }, { 4, 10, 237 }, { 7, 10, 514 }, + { 6, 0, 714 }, { 17, 0, 19 }, { 5, 11, 358 }, { 7, 11, 473 }, + { 7, 11, 1184 }, { 10, 11, 662 }, { 13, 11, 212 }, { 13, 11, 304 }, + { 13, 11, 333 }, { 17, 11, 98 }, { 4, 0, 737 }, { 10, 0, 98 }, + { 11, 0, 294 }, { 12, 0, 60 }, { 12, 0, 437 }, { 13, 0, 64 }, + { 13, 0, 380 }, { 14, 0, 430 }, { 6, 10, 392 }, { 7, 10, 65 }, + { 7, 10, 2019 }, { 6, 0, 1758 }, { 8, 0, 520 }, { 9, 0, 345 }, + { 9, 0, 403 }, { 14, 0, 350 }, { 5, 0, 47 }, { 10, 0, 242 }, + { 10, 0, 579 }, { 5, 0, 139 }, { 7, 0, 1168 }, { 10, 0, 539 }, + { 6, 0, 1459 }, { 13, 0, 388 }, { 13, 11, 388 }, { 6, 0, 253 }, + { 7, 10, 1260 }, { 7, 10, 1790 }, { 10, 0, 252 }, { 9, 10, 222 }, + { 11, 10, 900 }, { 12, 0, 745 }, { 5, 11, 946 }, { 4, 0, 107 }, + { 7, 0, 613 }, { 8, 0, 439 }, { 8, 0, 504 }, { 9, 0, 501 }, + { 10, 0, 383 }, { 11, 0, 477 }, { 7, 11, 1485 }, { 4, 0, 871 }, + { 7, 11, 411 }, { 7, 11, 590 }, { 8, 11, 631 }, { 9, 11, 323 }, + { 10, 11, 355 }, { 11, 11, 491 }, { 12, 11, 143 }, { 12, 11, 402 }, + { 13, 11, 73 }, { 14, 11, 408 }, { 15, 11, 107 }, { 18, 11, 71 }, + { 4, 0, 229 }, { 4, 0, 903 }, { 12, 0, 71 }, { 5, 0, 549 }, + { 4, 0, 47 }, { 6, 0, 373 }, { 7, 0, 452 }, { 7, 0, 543 }, + { 7, 0, 1828 }, { 7, 0, 1856 }, { 9, 0, 6 }, { 11, 0, 257 }, + { 11, 0, 391 }, { 7, 11, 1467 }, { 8, 11, 328 }, { 10, 11, 544 }, + { 11, 11, 955 }, { 13, 11, 320 }, { 17, 11, 83 }, { 5, 0, 980 }, + { 6, 0, 1754 }, { 8, 0, 865 }, { 5, 0, 705 }, { 9, 0, 606 }, + { 7, 0, 161 }, { 8, 10, 201 }, { 8, 10, 605 }, { 15, 11, 35 }, + { 5, 11, 835 }, { 6, 11, 483 }, { 12, 10, 224 }, { 7, 0, 536 }, + { 7, 0, 1331 }, { 8, 0, 143 }, { 6, 0, 1388 }, { 5, 0, 724 }, + { 10, 0, 305 }, { 11, 0, 151 }, { 12, 0, 33 }, { 12, 0, 121 }, + { 12, 0, 381 }, { 17, 0, 3 }, { 17, 0, 27 }, { 17, 0, 78 }, + { 18, 0, 18 }, { 19, 0, 54 }, { 21, 0, 5 }, { 4, 10, 523 }, + { 5, 10, 638 }, { 5, 0, 19 }, { 6, 0, 533 }, { 5, 0, 395 }, + { 5, 0, 951 }, { 6, 0, 1776 }, { 7, 0, 1908 }, { 4, 0, 846 }, + { 10, 0, 74 }, { 11, 0, 663 }, { 12, 0, 210 }, { 13, 0, 166 }, + { 13, 0, 310 }, { 14, 0, 373 }, { 18, 0, 95 }, { 19, 0, 43 }, + { 6, 10, 242 }, { 7, 10, 227 }, { 7, 10, 1581 }, { 8, 10, 104 }, + { 9, 10, 113 }, { 9, 10, 220 }, { 9, 10, 427 }, { 10, 10, 239 }, + { 11, 10, 579 }, { 11, 10, 1023 }, { 13, 10, 4 }, { 13, 10, 204 }, + { 13, 10, 316 }, { 20, 10, 86 }, { 9, 11, 716 }, { 11, 11, 108 }, + { 13, 11, 123 }, { 14, 11, 252 }, { 19, 11, 38 }, { 21, 11, 3 }, + { 23, 11, 11 }, { 8, 0, 372 }, { 9, 0, 122 }, { 10, 0, 175 }, + { 4, 11, 677 }, { 7, 11, 1374 }, { 8, 11, 540 }, { 7, 10, 861 }, + { 4, 0, 695 }, { 7, 0, 497 }, { 9, 0, 387 }, { 19, 0, 81 }, + { 8, 0, 937 }, { 6, 0, 718 }, { 7, 0, 1328 }, { 8, 10, 494 }, + { 4, 11, 331 }, { 6, 0, 1581 }, { 5, 11, 747 }, { 5, 0, 284 }, + { 6, 0, 49 }, { 6, 0, 350 }, { 7, 0, 1 }, { 7, 0, 377 }, + { 7, 0, 1693 }, { 8, 0, 18 }, { 8, 0, 678 }, { 9, 0, 161 }, + { 9, 0, 585 }, { 9, 0, 671 }, { 9, 0, 839 }, { 11, 0, 912 }, + { 13, 0, 427 }, { 7, 10, 1306 }, { 8, 10, 505 }, { 9, 10, 482 }, + { 10, 10, 126 }, { 11, 10, 225 }, { 12, 10, 347 }, { 12, 10, 449 }, + { 13, 10, 19 }, { 14, 10, 218 }, { 14, 10, 435 }, { 10, 10, 764 }, + { 12, 10, 120 }, { 13, 10, 39 }, { 17, 10, 127 }, { 4, 0, 597 }, + { 5, 10, 268 }, { 6, 0, 1094 }, { 4, 0, 1008 }, { 6, 0, 1973 }, + { 4, 0, 811 }, { 11, 0, 908 }, { 7, 0, 1471 }, { 5, 11, 326 }, + { 4, 10, 384 }, { 7, 10, 1022 }, { 7, 0, 1935 }, { 8, 0, 324 }, + { 12, 0, 42 }, { 4, 11, 691 }, { 7, 11, 1935 }, { 8, 11, 324 }, + { 9, 11, 35 }, { 10, 11, 680 }, { 11, 11, 364 }, { 12, 11, 42 }, + { 13, 11, 357 }, { 18, 11, 16 }, { 7, 0, 2014 }, { 7, 0, 2007 }, + { 9, 0, 101 }, { 9, 0, 450 }, { 10, 0, 66 }, { 10, 0, 842 }, + { 11, 0, 536 }, { 12, 0, 587 }, { 6, 11, 32 }, { 7, 11, 385 }, + { 7, 11, 757 }, { 7, 11, 1916 }, { 8, 11, 37 }, { 8, 11, 94 }, + { 8, 11, 711 }, { 9, 11, 541 }, { 10, 11, 162 }, { 10, 11, 795 }, + { 11, 11, 989 }, { 11, 11, 1010 }, { 12, 11, 14 }, { 14, 11, 308 }, + { 11, 0, 586 }, { 7, 10, 1703 }, { 7, 0, 1077 }, { 11, 0, 28 }, + { 9, 10, 159 }, { 12, 10, 603 }, { 6, 0, 1221 }, { 8, 10, 583 }, + { 6, 11, 152 }, { 6, 11, 349 }, { 6, 11, 1682 }, { 7, 11, 1252 }, + { 8, 11, 112 }, { 9, 11, 435 }, { 9, 11, 668 }, { 10, 11, 290 }, + { 10, 11, 319 }, { 10, 11, 815 }, { 11, 11, 180 }, { 11, 11, 837 }, + { 12, 11, 240 }, { 13, 11, 152 }, { 13, 11, 219 }, { 14, 11, 158 }, + { 11, 0, 62 }, { 4, 10, 515 }, { 8, 10, 632 }, { 8, 10, 697 }, + { 9, 10, 854 }, { 6, 0, 1766 }, { 4, 11, 581 }, { 6, 11, 126 }, + { 7, 11, 573 }, { 8, 11, 397 }, { 14, 11, 44 }, { 22, 0, 28 }, + { 11, 0, 670 }, { 22, 0, 25 }, { 4, 10, 136 }, { 5, 10, 551 }, + { 6, 0, 1665 }, { 7, 0, 256 }, { 7, 0, 1388 }, { 10, 0, 499 }, + { 4, 0, 22 }, { 5, 0, 10 }, { 7, 0, 1576 }, { 8, 0, 97 }, + { 6, 10, 1782 }, { 5, 0, 481 }, { 7, 10, 1287 }, { 9, 10, 44 }, + { 10, 10, 552 }, { 10, 10, 642 }, { 11, 10, 839 }, { 12, 10, 274 }, + { 12, 10, 275 }, { 12, 10, 372 }, { 13, 10, 91 }, { 14, 10, 125 }, + { 5, 11, 926 }, { 7, 11, 1232 }, { 9, 11, 531 }, { 6, 0, 134 }, + { 7, 0, 437 }, { 7, 0, 1824 }, { 9, 0, 37 }, { 14, 0, 285 }, + { 14, 0, 371 }, { 7, 0, 486 }, { 8, 0, 155 }, { 11, 0, 93 }, + { 12, 0, 164 }, { 6, 0, 1391 }, { 6, 0, 1442 }, { 5, 11, 670 }, + { 5, 0, 591 }, { 6, 10, 147 }, { 7, 10, 886 }, { 7, 11, 1957 }, + { 9, 10, 753 }, { 10, 10, 268 }, { 5, 0, 380 }, { 5, 0, 650 }, + { 7, 0, 1173 }, { 8, 0, 310 }, { 4, 0, 364 }, { 7, 0, 1156 }, + { 7, 0, 1187 }, { 9, 0, 409 }, { 7, 11, 1621 }, { 6, 0, 482 }, + { 5, 11, 506 }, { 4, 0, 781 }, { 6, 0, 487 }, { 7, 0, 926 }, + { 8, 0, 263 }, { 11, 0, 500 }, { 10, 10, 137 }, { 7, 11, 242 }, + { 11, 11, 96 }, { 5, 10, 414 }, { 7, 10, 1762 }, { 6, 0, 804 }, + { 5, 11, 834 }, { 7, 11, 1202 }, { 8, 11, 14 }, { 9, 11, 481 }, + { 9, 11, 880 }, { 6, 10, 599 }, { 4, 0, 94 }, { 7, 0, 1265 }, + { 4, 0, 415 }, { 4, 0, 417 }, { 5, 0, 348 }, { 6, 0, 522 }, + { 6, 10, 1749 }, { 7, 11, 1526 }, { 10, 11, 465 }, { 6, 10, 1627 }, + { 4, 0, 1012 }, { 4, 10, 488 }, { 4, 11, 357 }, { 6, 11, 172 }, + { 7, 11, 143 }, { 9, 11, 413 }, { 4, 10, 83 }, { 4, 11, 590 }, + { 18, 11, 76 }, { 12, 10, 676 }, { 7, 11, 287 }, { 8, 11, 355 }, + { 9, 11, 293 }, { 9, 11, 743 }, { 6, 10, 278 }, { 6, 0, 1803 }, + { 18, 0, 165 }, { 24, 0, 21 }, { 5, 11, 169 }, { 7, 11, 333 }, + { 8, 11, 45 }, { 12, 10, 97 }, { 12, 11, 97 }, { 4, 0, 408 }, + { 4, 0, 741 }, { 7, 0, 500 }, { 4, 11, 198 }, { 7, 10, 388 }, + { 7, 10, 644 }, { 11, 10, 781 }, { 4, 11, 24 }, { 5, 11, 140 }, + { 5, 11, 185 }, { 7, 11, 1500 }, { 11, 11, 565 }, { 11, 11, 838 }, + { 6, 0, 1321 }, { 9, 0, 257 }, { 7, 10, 229 }, { 8, 10, 59 }, + { 9, 10, 190 }, { 10, 10, 378 }, { 12, 10, 191 }, { 4, 11, 334 }, + { 5, 11, 593 }, { 7, 11, 1885 }, { 6, 0, 1138 }, { 4, 0, 249 }, + { 6, 0, 73 }, { 7, 0, 177 }, { 5, 0, 576 }, { 14, 0, 231 }, + { 9, 0, 288 }, { 4, 10, 660 }, { 7, 10, 1035 }, { 10, 10, 737 }, + { 7, 0, 1487 }, { 6, 0, 989 }, { 9, 0, 433 }, { 7, 10, 690 }, + { 9, 10, 587 }, { 12, 10, 521 }, { 7, 0, 1264 }, { 7, 0, 1678 }, + { 11, 0, 945 }, { 12, 0, 341 }, { 12, 0, 471 }, { 12, 0, 569 }, + { 4, 11, 709 }, { 5, 11, 897 }, { 5, 11, 224 }, { 13, 11, 174 }, + { 18, 11, 52 }, { 7, 11, 1840 }, { 6, 10, 1744 }, { 12, 0, 87 }, + { 16, 0, 74 }, { 4, 10, 733 }, { 9, 10, 194 }, { 10, 10, 92 }, + { 11, 10, 198 }, { 12, 10, 84 }, { 13, 10, 128 }, { 12, 0, 779 }, + { 7, 0, 538 }, { 4, 11, 608 }, { 5, 11, 497 }, { 5, 0, 413 }, + { 7, 11, 1375 }, { 7, 11, 1466 }, { 10, 11, 331 }, { 8, 0, 495 }, + { 6, 11, 540 }, { 8, 11, 136 }, { 7, 0, 54 }, { 8, 0, 312 }, + { 10, 0, 191 }, { 10, 0, 614 }, { 12, 0, 567 }, { 6, 0, 468 }, + { 7, 0, 567 }, { 7, 0, 1478 }, { 8, 0, 530 }, { 14, 0, 290 }, + { 5, 11, 999 }, { 4, 11, 299 }, { 7, 10, 306 }, { 7, 11, 1004 }, + { 14, 11, 296 }, { 6, 0, 1484 }, { 5, 10, 979 }, { 6, 0, 609 }, + { 9, 0, 815 }, { 12, 11, 137 }, { 14, 11, 9 }, { 14, 11, 24 }, + { 14, 11, 64 }, { 5, 11, 456 }, { 6, 0, 484 }, { 7, 0, 822 }, + { 5, 10, 178 }, { 8, 11, 180 }, { 4, 11, 755 }, { 9, 0, 900 }, + { 7, 0, 1335 }, { 6, 0, 1724 }, { 7, 0, 2022 }, { 7, 11, 1139 }, + { 5, 0, 640 }, { 4, 10, 390 }, { 6, 0, 1831 }, { 10, 11, 633 }, + { 7, 11, 566 }, { 4, 11, 890 }, { 5, 11, 805 }, { 5, 11, 819 }, + { 5, 11, 961 }, { 6, 11, 396 }, { 6, 11, 1631 }, { 6, 11, 1678 }, + { 7, 11, 1967 }, { 7, 11, 2041 }, { 9, 11, 630 }, { 11, 11, 8 }, + { 11, 11, 1019 }, { 12, 11, 176 }, { 13, 11, 225 }, { 14, 11, 292 }, + { 21, 11, 24 }, { 4, 0, 474 }, { 6, 0, 1103 }, { 7, 0, 1504 }, + { 6, 0, 1576 }, { 6, 0, 961 }, { 6, 0, 1034 }, { 12, 0, 655 }, + { 11, 11, 514 }, { 21, 11, 20 }, { 5, 0, 305 }, { 7, 11, 1815 }, + { 7, 11, 1505 }, { 10, 11, 190 }, { 10, 11, 634 }, { 11, 11, 792 }, + { 12, 11, 358 }, { 12, 11, 447 }, { 5, 11, 0 }, { 6, 11, 536 }, + { 7, 11, 604 }, { 13, 11, 445 }, { 17, 11, 126 }, { 7, 0, 1236 }, + { 5, 10, 105 }, { 4, 0, 480 }, { 6, 0, 217 }, { 6, 0, 302 }, + { 6, 0, 1642 }, { 7, 0, 130 }, { 7, 0, 837 }, { 7, 0, 1321 }, + { 7, 0, 1547 }, { 7, 0, 1657 }, { 8, 0, 429 }, { 9, 0, 228 }, + { 13, 0, 289 }, { 13, 0, 343 }, { 19, 0, 101 }, { 6, 11, 232 }, + { 6, 11, 412 }, { 7, 11, 1074 }, { 8, 11, 9 }, { 8, 11, 157 }, + { 8, 11, 786 }, { 9, 11, 196 }, { 9, 11, 352 }, { 9, 11, 457 }, + { 10, 11, 337 }, { 11, 11, 232 }, { 11, 11, 877 }, { 12, 11, 480 }, + { 12, 11, 546 }, { 5, 10, 438 }, { 7, 11, 958 }, { 9, 10, 694 }, + { 12, 10, 627 }, { 13, 11, 38 }, { 13, 10, 210 }, { 4, 11, 382 }, + { 8, 11, 579 }, { 7, 0, 278 }, { 10, 0, 739 }, { 11, 0, 708 }, + { 13, 0, 348 }, { 4, 11, 212 }, { 7, 11, 1206 }, { 7, 11, 1898 }, + { 6, 0, 708 }, { 6, 0, 1344 }, { 24, 10, 11 }, { 9, 11, 768 }, + { 6, 0, 1840 }, { 12, 0, 233 }, { 8, 10, 25 }, { 10, 10, 826 }, + { 6, 0, 2017 }, { 5, 11, 655 }, { 6, 0, 1488 }, { 11, 11, 290 }, + { 4, 10, 308 }, { 6, 0, 1590 }, { 6, 0, 1800 }, { 6, 0, 1259 }, + { 16, 0, 28 }, { 6, 11, 231 }, { 7, 11, 95 }, { 8, 11, 423 }, + { 5, 11, 300 }, { 7, 10, 150 }, { 8, 10, 649 }, { 7, 11, 1874 }, + { 9, 11, 641 }, { 6, 11, 237 }, { 7, 11, 611 }, { 8, 11, 100 }, + { 9, 11, 416 }, { 11, 11, 335 }, { 12, 11, 173 }, { 18, 11, 101 }, + { 9, 0, 45 }, { 6, 10, 521 }, { 17, 0, 36 }, { 14, 11, 26 }, + { 18, 11, 150 }, { 7, 0, 1442 }, { 14, 0, 22 }, { 5, 10, 339 }, + { 15, 10, 41 }, { 15, 10, 166 }, { 19, 10, 66 }, { 8, 0, 378 }, + { 6, 11, 581 }, { 7, 11, 1119 }, { 6, 0, 1507 }, { 19, 11, 117 }, + { 11, 0, 39 }, { 6, 0, 1054 }, { 6, 0, 363 }, { 7, 0, 1955 }, + { 8, 0, 725 }, { 6, 0, 2036 }, { 5, 11, 199 }, { 6, 0, 1871 }, + { 9, 0, 935 }, { 9, 0, 961 }, { 9, 0, 1004 }, { 9, 0, 1016 }, + { 12, 0, 805 }, { 12, 0, 852 }, { 12, 0, 853 }, { 12, 0, 869 }, + { 12, 0, 882 }, { 12, 0, 896 }, { 12, 0, 906 }, { 12, 0, 917 }, + { 12, 0, 940 }, { 15, 0, 170 }, { 15, 0, 176 }, { 15, 0, 188 }, + { 15, 0, 201 }, { 15, 0, 205 }, { 15, 0, 212 }, { 15, 0, 234 }, + { 15, 0, 244 }, { 18, 0, 181 }, { 18, 0, 193 }, { 18, 0, 196 }, + { 18, 0, 201 }, { 18, 0, 202 }, { 18, 0, 210 }, { 18, 0, 217 }, + { 18, 0, 235 }, { 18, 0, 236 }, { 18, 0, 237 }, { 21, 0, 54 }, + { 21, 0, 55 }, { 21, 0, 58 }, { 21, 0, 59 }, { 24, 0, 22 }, + { 6, 10, 1628 }, { 9, 0, 805 }, { 5, 0, 813 }, { 7, 0, 2046 }, + { 14, 11, 42 }, { 5, 0, 712 }, { 6, 0, 1240 }, { 11, 0, 17 }, + { 13, 0, 321 }, { 16, 0, 67 }, { 4, 0, 617 }, { 7, 10, 829 }, + { 6, 0, 320 }, { 7, 0, 781 }, { 7, 0, 1921 }, { 9, 0, 55 }, + { 10, 0, 186 }, { 10, 0, 273 }, { 10, 0, 664 }, { 10, 0, 801 }, + { 11, 0, 996 }, { 11, 0, 997 }, { 13, 0, 157 }, { 14, 0, 170 }, + { 8, 0, 271 }, { 5, 10, 486 }, { 7, 10, 1349 }, { 18, 11, 91 }, + { 19, 11, 70 }, { 10, 0, 445 }, { 7, 10, 1635 }, { 8, 10, 17 }, + { 10, 10, 295 }, { 8, 11, 404 }, { 7, 0, 103 }, { 7, 0, 863 }, + { 11, 0, 184 }, { 17, 0, 62 }, { 10, 10, 558 }, { 9, 0, 659 }, + { 6, 11, 312 }, { 6, 11, 1715 }, { 10, 11, 584 }, { 11, 11, 546 }, + { 11, 11, 692 }, { 12, 11, 259 }, { 12, 11, 295 }, { 13, 11, 46 }, + { 13, 11, 154 }, { 6, 0, 676 }, { 4, 11, 588 }, { 4, 11, 231 }, + { 5, 11, 61 }, { 6, 11, 104 }, { 7, 11, 729 }, { 7, 11, 964 }, + { 7, 11, 1658 }, { 12, 11, 414 }, { 6, 11, 263 }, { 10, 11, 757 }, + { 11, 0, 337 }, { 14, 0, 303 }, { 7, 11, 1363 }, { 4, 11, 320 }, + { 12, 0, 506 }, { 6, 10, 447 }, { 5, 0, 77 }, { 7, 0, 1455 }, + { 10, 0, 843 }, { 19, 0, 73 }, { 7, 10, 577 }, { 7, 10, 1432 }, + { 9, 10, 475 }, { 9, 10, 505 }, { 9, 10, 526 }, { 9, 10, 609 }, + { 9, 10, 689 }, { 9, 10, 726 }, { 9, 10, 735 }, { 9, 10, 738 }, + { 10, 10, 556 }, { 10, 10, 674 }, { 10, 10, 684 }, { 11, 10, 89 }, + { 11, 10, 202 }, { 11, 10, 272 }, { 11, 10, 380 }, { 11, 10, 415 }, + { 11, 10, 505 }, { 11, 10, 537 }, { 11, 10, 550 }, { 11, 10, 562 }, + { 11, 10, 640 }, { 11, 10, 667 }, { 11, 10, 688 }, { 11, 10, 847 }, + { 11, 10, 927 }, { 11, 10, 930 }, { 11, 10, 940 }, { 12, 10, 144 }, + { 12, 10, 325 }, { 12, 10, 329 }, { 12, 10, 389 }, { 12, 10, 403 }, + { 12, 10, 451 }, { 12, 10, 515 }, { 12, 10, 604 }, { 12, 10, 616 }, + { 12, 10, 626 }, { 13, 10, 66 }, { 13, 10, 131 }, { 13, 10, 167 }, + { 13, 10, 236 }, { 13, 10, 368 }, { 13, 10, 411 }, { 13, 10, 434 }, + { 13, 10, 453 }, { 13, 10, 461 }, { 13, 10, 474 }, { 14, 10, 59 }, + { 14, 10, 60 }, { 14, 10, 139 }, { 14, 10, 152 }, { 14, 10, 276 }, + { 14, 10, 353 }, { 14, 10, 402 }, { 15, 10, 28 }, { 15, 10, 81 }, + { 15, 10, 123 }, { 15, 10, 152 }, { 18, 10, 136 }, { 20, 10, 88 }, + { 4, 0, 458 }, { 7, 0, 1420 }, { 6, 0, 109 }, { 10, 0, 382 }, + { 4, 11, 405 }, { 4, 10, 609 }, { 7, 10, 756 }, { 7, 11, 817 }, + { 9, 10, 544 }, { 11, 10, 413 }, { 14, 11, 58 }, { 14, 10, 307 }, + { 16, 10, 25 }, { 17, 11, 37 }, { 18, 11, 124 }, { 6, 0, 330 }, + { 7, 0, 1084 }, { 11, 0, 142 }, { 5, 11, 974 }, { 4, 10, 930 }, + { 5, 10, 947 }, { 5, 10, 939 }, { 14, 11, 394 }, { 16, 0, 91 }, + { 17, 0, 87 }, { 5, 11, 235 }, { 5, 10, 962 }, { 7, 11, 1239 }, + { 11, 11, 131 }, { 12, 11, 370 }, { 11, 0, 492 }, { 5, 10, 651 }, + { 8, 10, 170 }, { 9, 10, 61 }, { 9, 10, 63 }, { 10, 10, 23 }, + { 10, 10, 37 }, { 10, 10, 834 }, { 11, 10, 4 }, { 11, 10, 281 }, + { 11, 10, 503 }, { 11, 10, 677 }, { 12, 10, 96 }, { 12, 10, 130 }, + { 12, 10, 244 }, { 14, 10, 5 }, { 14, 10, 40 }, { 14, 10, 162 }, + { 14, 10, 202 }, { 18, 10, 133 }, { 4, 10, 406 }, { 5, 10, 579 }, + { 12, 10, 492 }, { 22, 10, 15 }, { 9, 11, 137 }, { 10, 11, 221 }, + { 6, 0, 1239 }, { 11, 0, 211 }, { 12, 0, 145 }, { 7, 11, 390 }, + { 10, 11, 140 }, { 7, 11, 1418 }, { 7, 11, 1144 }, { 6, 0, 1049 }, + { 7, 0, 321 }, { 6, 10, 17 }, { 7, 10, 1001 }, { 7, 10, 1982 }, + { 9, 10, 886 }, { 10, 10, 489 }, { 10, 10, 800 }, { 11, 10, 782 }, + { 12, 10, 320 }, { 13, 10, 467 }, { 14, 10, 145 }, { 14, 10, 387 }, + { 15, 10, 119 }, { 17, 10, 17 }, { 5, 11, 407 }, { 11, 11, 489 }, + { 19, 11, 37 }, { 20, 11, 73 }, { 22, 11, 38 }, { 5, 10, 458 }, + { 7, 0, 1985 }, { 7, 10, 1983 }, { 8, 10, 0 }, { 8, 10, 171 }, + { 9, 10, 120 }, { 9, 10, 732 }, { 10, 10, 473 }, { 11, 10, 656 }, + { 11, 10, 998 }, { 18, 10, 0 }, { 18, 10, 2 }, { 19, 10, 21 }, + { 5, 11, 325 }, { 7, 11, 1483 }, { 8, 11, 5 }, { 8, 11, 227 }, + { 9, 11, 105 }, { 10, 11, 585 }, { 12, 11, 614 }, { 8, 0, 122 }, + { 4, 0, 234 }, { 7, 11, 1196 }, { 6, 0, 976 }, { 6, 0, 1098 }, + { 6, 0, 1441 }, { 7, 0, 253 }, { 8, 0, 549 }, { 6, 11, 621 }, + { 13, 11, 504 }, { 16, 11, 19 }, { 4, 10, 519 }, { 5, 0, 430 }, + { 5, 0, 932 }, { 6, 0, 131 }, { 7, 0, 417 }, { 9, 0, 522 }, + { 11, 0, 314 }, { 13, 0, 390 }, { 14, 0, 149 }, { 14, 0, 399 }, + { 15, 0, 57 }, { 5, 10, 907 }, { 6, 10, 31 }, { 6, 11, 218 }, + { 7, 10, 491 }, { 7, 10, 530 }, { 8, 10, 592 }, { 11, 10, 53 }, + { 11, 10, 779 }, { 12, 10, 167 }, { 12, 10, 411 }, { 14, 10, 14 }, + { 14, 10, 136 }, { 15, 10, 72 }, { 16, 10, 17 }, { 16, 10, 72 }, + { 12, 11, 330 }, { 7, 11, 454 }, { 7, 11, 782 }, { 8, 11, 768 }, + { 4, 0, 507 }, { 10, 11, 676 }, { 12, 11, 462 }, { 6, 0, 630 }, + { 9, 0, 811 }, { 4, 10, 208 }, { 5, 10, 106 }, { 6, 10, 531 }, + { 8, 10, 408 }, { 9, 10, 188 }, { 10, 10, 572 }, { 4, 0, 343 }, + { 5, 0, 511 }, { 6, 10, 1693 }, { 6, 11, 164 }, { 4, 0, 448 }, + { 7, 0, 455 }, { 10, 0, 591 }, { 7, 0, 1381 }, { 12, 10, 441 }, + { 22, 11, 50 }, { 9, 10, 449 }, { 10, 10, 192 }, { 10, 10, 740 }, + { 6, 0, 575 }, { 4, 10, 241 }, { 6, 0, 1175 }, { 6, 0, 653 }, + { 6, 0, 1761 }, { 6, 0, 1198 }, { 4, 10, 259 }, { 6, 11, 343 }, + { 7, 11, 195 }, { 9, 11, 226 }, { 10, 11, 197 }, { 10, 11, 575 }, + { 11, 11, 502 }, { 11, 11, 899 }, { 7, 0, 1127 }, { 7, 0, 1572 }, + { 10, 0, 297 }, { 10, 0, 422 }, { 11, 0, 764 }, { 11, 0, 810 }, + { 12, 0, 264 }, { 13, 0, 102 }, { 13, 0, 300 }, { 13, 0, 484 }, + { 14, 0, 147 }, { 14, 0, 229 }, { 17, 0, 71 }, { 18, 0, 118 }, + { 19, 0, 120 }, { 7, 11, 666 }, { 4, 0, 678 }, { 4, 10, 173 }, + { 5, 10, 312 }, { 5, 10, 512 }, { 7, 10, 1285 }, { 7, 10, 1603 }, + { 7, 10, 1691 }, { 9, 10, 464 }, { 11, 10, 195 }, { 12, 10, 279 }, + { 12, 10, 448 }, { 14, 10, 11 }, { 19, 10, 102 }, { 16, 0, 99 }, + { 18, 0, 164 }, { 7, 11, 1125 }, { 9, 11, 143 }, { 11, 11, 61 }, + { 14, 11, 405 }, { 22, 11, 21 }, { 9, 11, 260 }, { 4, 10, 452 }, + { 5, 10, 583 }, { 5, 10, 817 }, { 6, 10, 433 }, { 7, 10, 593 }, + { 7, 10, 720 }, { 7, 10, 1378 }, { 8, 10, 161 }, { 9, 10, 284 }, + { 10, 10, 313 }, { 11, 10, 886 }, { 4, 10, 547 }, { 8, 10, 722 }, + { 14, 0, 35 }, { 14, 0, 191 }, { 13, 0, 45 }, { 10, 0, 121 }, + { 4, 0, 125 }, { 6, 0, 1622 }, { 5, 11, 959 }, { 8, 10, 420 }, + { 11, 10, 193 }, { 4, 0, 721 }, { 7, 10, 409 }, { 8, 0, 145 }, + { 7, 0, 792 }, { 8, 0, 147 }, { 10, 0, 821 }, { 11, 0, 970 }, + { 11, 0, 1021 }, { 8, 11, 173 }, { 6, 11, 266 }, { 4, 0, 715 }, + { 7, 0, 1999 }, { 10, 10, 308 }, { 5, 0, 531 }, { 5, 0, 168 }, + { 5, 0, 930 }, { 8, 0, 74 }, { 9, 0, 623 }, { 12, 0, 500 }, + { 12, 0, 579 }, { 16, 0, 65 }, { 10, 11, 246 }, { 6, 0, 220 }, + { 7, 0, 1101 }, { 13, 0, 105 }, { 14, 11, 314 }, { 5, 10, 1002 }, + { 8, 10, 745 }, { 6, 0, 960 }, { 20, 0, 0 }, { 20, 11, 0 }, + { 4, 0, 1005 }, { 4, 10, 239 }, { 6, 10, 477 }, { 7, 10, 1607 }, + { 11, 10, 68 }, { 11, 10, 617 }, { 6, 0, 19 }, { 7, 0, 1413 }, + { 11, 0, 428 }, { 21, 10, 13 }, { 7, 0, 96 }, { 8, 0, 401 }, + { 8, 0, 703 }, { 9, 0, 896 }, { 8, 11, 300 }, { 6, 0, 1595 }, + { 17, 0, 116 }, { 8, 0, 1021 }, { 7, 0, 1961 }, { 7, 0, 1965 }, + { 7, 0, 2030 }, { 8, 0, 150 }, { 8, 0, 702 }, { 8, 0, 737 }, + { 8, 0, 750 }, { 12, 0, 366 }, { 11, 11, 75 }, { 14, 11, 267 }, + { 4, 10, 367 }, { 8, 0, 800 }, { 9, 0, 148 }, { 9, 0, 872 }, + { 9, 0, 890 }, { 11, 0, 309 }, { 11, 0, 1001 }, { 13, 0, 267 }, + { 13, 0, 323 }, { 5, 11, 427 }, { 5, 11, 734 }, { 7, 11, 478 }, + { 8, 11, 52 }, { 7, 11, 239 }, { 11, 11, 217 }, { 14, 11, 165 }, + { 4, 11, 323 }, { 12, 11, 419 }, { 13, 0, 299 }, { 14, 0, 75 }, + { 6, 11, 87 }, { 6, 11, 1734 }, { 7, 11, 20 }, { 7, 11, 1056 }, + { 8, 11, 732 }, { 9, 11, 406 }, { 9, 11, 911 }, { 10, 11, 694 }, + { 6, 0, 1383 }, { 4, 10, 694 }, { 5, 11, 613 }, { 9, 0, 779 }, + { 4, 0, 598 }, { 12, 10, 687 }, { 6, 0, 970 }, { 7, 0, 424 }, + { 5, 0, 547 }, { 7, 11, 32 }, { 7, 11, 984 }, { 8, 11, 85 }, + { 8, 11, 709 }, { 9, 11, 579 }, { 9, 11, 847 }, { 9, 11, 856 }, + { 10, 11, 799 }, { 11, 11, 258 }, { 11, 11, 1007 }, { 12, 11, 331 }, + { 12, 11, 615 }, { 13, 11, 188 }, { 13, 11, 435 }, { 14, 11, 8 }, + { 15, 11, 165 }, { 16, 11, 27 }, { 20, 11, 40 }, { 6, 0, 1222 }, + { 6, 0, 1385 }, { 4, 0, 876 }, { 10, 11, 151 }, { 7, 10, 213 }, + { 4, 11, 167 }, { 7, 11, 82 }, { 5, 0, 133 }, { 6, 11, 24 }, + { 7, 11, 74 }, { 7, 11, 678 }, { 9, 11, 258 }, { 5, 11, 62 }, + { 6, 11, 534 }, { 7, 11, 684 }, { 7, 11, 1043 }, { 7, 11, 1072 }, + { 8, 11, 280 }, { 8, 11, 541 }, { 8, 11, 686 }, { 10, 11, 519 }, + { 11, 11, 252 }, { 12, 11, 282 }, { 8, 0, 187 }, { 8, 0, 8 }, + { 10, 0, 0 }, { 10, 0, 818 }, { 11, 0, 988 }, { 4, 11, 359 }, + { 11, 0, 429 }, { 15, 0, 51 }, { 7, 10, 1672 }, { 8, 0, 685 }, + { 5, 11, 211 }, { 7, 11, 88 }, { 8, 11, 627 }, { 6, 0, 472 }, + { 8, 0, 132 }, { 6, 11, 145 }, { 13, 11, 336 }, { 4, 10, 751 }, + { 11, 10, 390 }, { 12, 10, 32 }, { 6, 0, 938 }, { 6, 0, 1060 }, + { 4, 11, 263 }, { 4, 10, 409 }, { 5, 10, 78 }, { 9, 0, 874 }, + { 8, 0, 774 }, { 10, 0, 670 }, { 12, 0, 51 }, { 4, 11, 916 }, + { 6, 10, 473 }, { 7, 10, 1602 }, { 10, 10, 698 }, { 12, 10, 212 }, + { 13, 10, 307 }, { 17, 10, 105 }, { 18, 0, 92 }, { 15, 10, 156 }, + { 4, 0, 830 }, { 9, 0, 701 }, { 4, 11, 599 }, { 6, 11, 1634 }, + { 7, 11, 5 }, { 7, 11, 55 }, { 7, 11, 67 }, { 7, 11, 97 }, + { 7, 11, 691 }, { 7, 11, 979 }, { 7, 11, 1697 }, { 8, 11, 207 }, + { 8, 11, 214 }, { 8, 11, 231 }, { 8, 11, 294 }, { 8, 11, 336 }, + { 8, 11, 428 }, { 8, 11, 451 }, { 8, 11, 460 }, { 8, 11, 471 }, + { 8, 11, 622 }, { 8, 11, 626 }, { 8, 11, 679 }, { 8, 11, 759 }, + { 8, 11, 829 }, { 9, 11, 11 }, { 9, 11, 246 }, { 9, 11, 484 }, + { 9, 11, 573 }, { 9, 11, 706 }, { 9, 11, 762 }, { 9, 11, 798 }, + { 9, 11, 855 }, { 9, 11, 870 }, { 9, 11, 912 }, { 10, 11, 303 }, + { 10, 11, 335 }, { 10, 11, 424 }, { 10, 11, 461 }, { 10, 11, 543 }, + { 10, 11, 759 }, { 10, 11, 814 }, { 11, 11, 59 }, { 11, 11, 199 }, + { 11, 11, 235 }, { 11, 11, 475 }, { 11, 11, 590 }, { 11, 11, 929 }, + { 11, 11, 963 }, { 12, 11, 114 }, { 12, 11, 182 }, { 12, 11, 226 }, + { 12, 11, 332 }, { 12, 11, 439 }, { 12, 11, 575 }, { 12, 11, 598 }, + { 13, 11, 8 }, { 13, 11, 125 }, { 13, 11, 194 }, { 13, 11, 287 }, + { 14, 11, 197 }, { 14, 11, 383 }, { 15, 11, 53 }, { 17, 11, 63 }, + { 19, 11, 46 }, { 19, 11, 98 }, { 19, 11, 106 }, { 20, 11, 85 }, + { 4, 0, 127 }, { 5, 0, 350 }, { 6, 0, 356 }, { 8, 0, 426 }, + { 9, 0, 572 }, { 10, 0, 247 }, { 11, 0, 312 }, { 6, 0, 1215 }, + { 6, 0, 59 }, { 9, 0, 603 }, { 13, 0, 397 }, { 7, 11, 1853 }, + { 10, 11, 437 }, { 6, 0, 1762 }, { 19, 11, 126 }, { 7, 10, 883 }, + { 13, 0, 293 }, { 14, 0, 56 }, { 5, 10, 617 }, { 11, 10, 50 }, + { 5, 11, 187 }, { 7, 10, 1518 }, { 11, 10, 694 }, { 7, 0, 441 }, + { 6, 0, 111 }, { 7, 0, 4 }, { 8, 0, 163 }, { 8, 0, 776 }, + { 10, 0, 566 }, { 4, 0, 806 }, { 4, 11, 215 }, { 9, 11, 38 }, + { 10, 11, 3 }, { 11, 11, 23 }, { 11, 11, 127 }, { 11, 11, 796 }, + { 14, 0, 233 }, { 4, 10, 546 }, { 7, 10, 2042 }, { 7, 0, 1994 }, + { 6, 0, 1739 }, { 7, 11, 1530 }, { 8, 0, 393 }, { 5, 0, 297 }, + { 7, 0, 1038 }, { 14, 0, 359 }, { 19, 0, 52 }, { 20, 0, 47 }, + { 7, 0, 309 }, { 4, 10, 313 }, { 5, 10, 577 }, { 8, 10, 184 }, + { 13, 10, 433 }, { 7, 10, 935 }, { 12, 10, 186 }, { 12, 10, 292 }, + { 14, 10, 100 }, { 18, 10, 70 }, { 8, 0, 363 }, { 14, 0, 175 }, + { 11, 10, 402 }, { 12, 10, 109 }, { 12, 10, 431 }, { 13, 10, 179 }, + { 13, 10, 206 }, { 14, 10, 217 }, { 16, 10, 3 }, { 20, 10, 53 }, + { 5, 10, 886 }, { 6, 10, 46 }, { 6, 10, 1790 }, { 7, 10, 14 }, + { 7, 10, 732 }, { 7, 10, 1654 }, { 8, 10, 95 }, { 8, 10, 327 }, + { 8, 10, 616 }, { 9, 10, 892 }, { 10, 10, 598 }, { 10, 10, 769 }, + { 11, 10, 134 }, { 11, 10, 747 }, { 12, 10, 378 }, { 14, 10, 97 }, + { 8, 0, 666 }, { 7, 0, 1675 }, { 6, 0, 655 }, { 6, 0, 1600 }, + { 7, 0, 808 }, { 5, 10, 1021 }, { 4, 11, 28 }, { 5, 11, 440 }, + { 7, 11, 248 }, { 11, 11, 833 }, { 12, 11, 344 }, { 6, 11, 1654 }, + { 4, 0, 280 }, { 12, 0, 54 }, { 4, 0, 421 }, { 5, 0, 548 }, + { 4, 10, 153 }, { 6, 11, 339 }, { 7, 11, 923 }, { 5, 11, 853 }, + { 5, 10, 798 }, { 4, 10, 587 }, { 6, 11, 249 }, { 7, 11, 1234 }, + { 11, 11, 573 }, { 6, 10, 598 }, { 7, 10, 42 }, { 8, 10, 695 }, + { 10, 10, 212 }, { 11, 10, 158 }, { 14, 10, 196 }, { 17, 10, 85 }, + { 7, 0, 249 }, { 5, 10, 957 }, { 5, 10, 1008 }, { 4, 10, 129 }, + { 7, 10, 465 }, { 6, 0, 254 }, { 7, 0, 842 }, { 7, 0, 1659 }, + { 9, 0, 109 }, { 10, 0, 103 }, { 7, 10, 908 }, { 7, 10, 1201 }, + { 9, 10, 755 }, { 11, 10, 906 }, { 12, 10, 527 }, { 18, 10, 7 }, + { 5, 0, 262 }, { 8, 10, 450 }, { 16, 0, 1 }, { 10, 11, 201 }, + { 14, 11, 319 }, { 7, 11, 49 }, { 7, 11, 392 }, { 8, 11, 20 }, + { 8, 11, 172 }, { 8, 11, 690 }, { 9, 11, 383 }, { 9, 11, 845 }, + { 10, 11, 48 }, { 11, 11, 293 }, { 11, 11, 832 }, { 11, 11, 920 }, + { 13, 11, 221 }, { 5, 11, 858 }, { 5, 11, 992 }, { 6, 0, 805 }, + { 11, 10, 1003 }, { 6, 0, 1630 }, { 6, 11, 307 }, { 7, 11, 1512 }, + { 7, 11, 1794 }, { 6, 11, 268 }, { 9, 11, 62 }, { 7, 10, 1868 }, + { 5, 0, 671 }, { 4, 0, 989 }, { 8, 0, 972 }, { 8, 0, 998 }, + { 4, 11, 423 }, { 4, 0, 889 }, { 7, 0, 1382 }, { 7, 0, 1910 }, + { 7, 10, 965 }, { 7, 10, 1460 }, { 7, 10, 1604 }, { 4, 0, 627 }, + { 5, 0, 775 }, { 10, 11, 106 }, { 6, 11, 348 }, { 7, 0, 202 }, + { 11, 0, 362 }, { 11, 0, 948 }, { 12, 0, 388 }, { 10, 11, 771 }, + { 6, 11, 613 }, { 8, 11, 223 }, { 6, 0, 560 }, { 7, 0, 451 }, + { 8, 0, 389 }, { 12, 0, 490 }, { 13, 0, 16 }, { 13, 0, 215 }, + { 13, 0, 351 }, { 18, 0, 132 }, { 19, 0, 125 }, { 7, 0, 841 }, + { 8, 0, 566 }, { 8, 0, 938 }, { 4, 11, 670 }, { 5, 0, 912 }, + { 6, 0, 1695 }, { 12, 11, 55 }, { 9, 11, 40 }, { 11, 11, 136 }, + { 7, 0, 1361 }, { 7, 10, 982 }, { 10, 10, 32 }, { 15, 10, 56 }, + { 11, 11, 259 }, { 12, 11, 270 }, { 5, 0, 236 }, { 6, 0, 572 }, + { 8, 0, 492 }, { 11, 0, 618 }, { 16, 0, 56 }, { 8, 11, 572 }, + { 9, 11, 310 }, { 9, 11, 682 }, { 9, 11, 698 }, { 6, 0, 1854 }, + { 5, 0, 190 }, { 8, 0, 318 }, { 5, 10, 435 }, { 7, 0, 1376 }, + { 4, 11, 296 }, { 6, 11, 352 }, { 7, 11, 401 }, { 7, 11, 1410 }, + { 7, 11, 1594 }, { 7, 11, 1674 }, { 8, 11, 63 }, { 8, 11, 660 }, + { 9, 11, 74 }, { 7, 0, 349 }, { 5, 10, 85 }, { 6, 10, 419 }, + { 7, 10, 305 }, { 7, 10, 361 }, { 7, 10, 1337 }, { 8, 10, 71 }, + { 12, 10, 519 }, { 4, 11, 139 }, { 4, 11, 388 }, { 12, 11, 188 }, + { 6, 0, 1972 }, { 6, 0, 2013 }, { 8, 0, 951 }, { 10, 0, 947 }, + { 10, 0, 974 }, { 10, 0, 1018 }, { 14, 0, 476 }, { 12, 10, 688 }, + { 7, 10, 740 }, { 5, 10, 691 }, { 7, 10, 345 }, { 9, 10, 94 }, + { 12, 10, 169 }, { 9, 0, 344 }, { 5, 10, 183 }, { 6, 10, 582 }, + { 10, 10, 679 }, { 12, 10, 435 }, { 7, 10, 511 }, { 4, 0, 850 }, + { 8, 11, 441 }, { 10, 11, 314 }, { 15, 11, 3 }, { 7, 10, 1993 }, + { 8, 10, 684 }, { 4, 11, 747 }, { 6, 11, 290 }, { 6, 10, 583 }, + { 7, 11, 649 }, { 7, 11, 1479 }, { 7, 11, 1583 }, { 5, 11, 232 }, + { 5, 10, 704 }, { 6, 0, 910 }, { 4, 10, 179 }, { 5, 10, 198 }, + { 5, 10, 697 }, { 7, 10, 347 }, { 7, 10, 971 }, { 8, 10, 181 }, + { 10, 10, 711 }, { 8, 11, 525 }, { 14, 0, 19 }, { 14, 0, 28 }, + { 16, 0, 29 }, { 7, 0, 85 }, { 7, 0, 247 }, { 8, 0, 585 }, + { 10, 0, 163 }, { 4, 0, 487 }, { 7, 11, 472 }, { 7, 11, 1801 }, + { 10, 11, 748 }, { 13, 11, 458 }, { 4, 10, 243 }, { 5, 10, 203 }, + { 7, 10, 19 }, { 7, 10, 71 }, { 7, 10, 113 }, { 10, 10, 405 }, + { 11, 10, 357 }, { 14, 10, 240 }, { 7, 10, 1450 }, { 11, 10, 99 }, + { 4, 11, 425 }, { 10, 0, 145 }, { 19, 0, 83 }, { 6, 10, 492 }, + { 9, 11, 247 }, { 4, 0, 1013 }, { 6, 0, 2033 }, { 5, 10, 134 }, + { 6, 10, 408 }, { 6, 10, 495 }, { 7, 10, 1593 }, { 7, 0, 1922 }, + { 6, 11, 1768 }, { 4, 0, 124 }, { 10, 0, 457 }, { 11, 0, 121 }, + { 11, 0, 169 }, { 11, 0, 870 }, { 11, 0, 874 }, { 12, 0, 214 }, + { 14, 0, 187 }, { 15, 0, 77 }, { 5, 0, 557 }, { 7, 0, 1457 }, + { 11, 0, 66 }, { 5, 11, 943 }, { 6, 11, 1779 }, { 14, 10, 4 }, + { 4, 10, 248 }, { 4, 10, 665 }, { 7, 10, 137 }, { 9, 10, 349 }, + { 7, 0, 1193 }, { 5, 11, 245 }, { 6, 11, 576 }, { 7, 11, 582 }, + { 8, 11, 225 }, { 16, 0, 82 }, { 7, 10, 1270 }, { 11, 10, 612 }, + { 5, 0, 454 }, { 10, 0, 352 }, { 10, 11, 352 }, { 18, 0, 57 }, + { 5, 10, 371 }, { 7, 10, 563 }, { 7, 0, 1333 }, { 6, 0, 107 }, + { 7, 0, 638 }, { 7, 0, 1632 }, { 9, 0, 396 }, { 6, 11, 610 }, + { 5, 0, 370 }, { 6, 0, 1756 }, { 4, 10, 374 }, { 7, 10, 547 }, + { 7, 10, 1700 }, { 7, 10, 1833 }, { 11, 10, 858 }, { 5, 0, 204 }, + { 6, 0, 1305 }, { 9, 10, 311 }, { 13, 10, 42 }, { 5, 0, 970 }, + { 6, 0, 1706 }, { 6, 10, 1647 }, { 7, 10, 1552 }, { 7, 10, 2010 }, + { 9, 10, 494 }, { 9, 10, 509 }, { 13, 11, 455 }, { 15, 11, 99 }, + { 15, 11, 129 }, { 16, 11, 68 }, { 7, 0, 3 }, { 4, 0, 35 }, + { 5, 0, 121 }, { 5, 0, 483 }, { 5, 0, 685 }, { 6, 0, 489 }, + { 6, 0, 782 }, { 6, 0, 1032 }, { 7, 0, 1204 }, { 8, 0, 394 }, + { 4, 0, 921 }, { 5, 0, 1007 }, { 8, 11, 360 }, { 10, 11, 63 }, + { 7, 0, 1696 }, { 6, 0, 1519 }, { 4, 11, 443 }, { 7, 11, 944 }, + { 6, 10, 123 }, { 7, 10, 214 }, { 9, 10, 728 }, { 10, 10, 157 }, + { 11, 10, 346 }, { 11, 10, 662 }, { 15, 10, 106 }, { 9, 0, 981 }, + { 7, 10, 1435 }, { 6, 0, 1072 }, { 4, 0, 712 }, { 6, 0, 1629 }, + { 6, 0, 728 }, { 4, 11, 298 }, { 9, 11, 483 }, { 6, 0, 1177 }, + { 6, 0, 1271 }, { 5, 11, 164 }, { 7, 11, 121 }, { 14, 11, 189 }, + { 7, 0, 1608 }, { 4, 10, 707 }, { 5, 10, 588 }, { 6, 10, 393 }, + { 13, 10, 106 }, { 18, 10, 49 }, { 19, 10, 41 }, { 23, 0, 16 }, + { 23, 11, 16 }, { 6, 10, 211 }, { 7, 10, 1690 }, { 11, 10, 486 }, + { 12, 10, 369 }, { 5, 0, 485 }, { 19, 11, 15 }, { 21, 11, 27 }, + { 4, 11, 172 }, { 9, 11, 611 }, { 10, 11, 436 }, { 12, 11, 673 }, + { 13, 11, 255 }, { 5, 11, 844 }, { 10, 11, 484 }, { 11, 11, 754 }, + { 12, 11, 457 }, { 14, 11, 171 }, { 14, 11, 389 }, { 18, 11, 153 }, + { 4, 0, 285 }, { 5, 0, 27 }, { 5, 0, 317 }, { 6, 0, 301 }, + { 7, 0, 7 }, { 8, 0, 153 }, { 10, 0, 766 }, { 11, 0, 468 }, + { 12, 0, 467 }, { 13, 0, 143 }, { 6, 0, 1462 }, { 9, 11, 263 }, + { 10, 11, 147 }, { 10, 11, 492 }, { 5, 11, 537 }, { 6, 0, 1945 }, + { 6, 0, 1986 }, { 6, 0, 1991 }, { 6, 0, 2038 }, { 6, 10, 219 }, + { 9, 11, 842 }, { 14, 0, 52 }, { 17, 0, 50 }, { 5, 10, 582 }, + { 6, 10, 1646 }, { 7, 10, 99 }, { 7, 10, 1962 }, { 7, 10, 1986 }, + { 8, 10, 515 }, { 8, 10, 773 }, { 9, 10, 23 }, { 9, 10, 491 }, + { 12, 10, 620 }, { 14, 10, 93 }, { 10, 11, 97 }, { 20, 0, 21 }, + { 20, 0, 44 }, { 5, 10, 851 }, { 8, 0, 819 }, { 11, 0, 917 }, + { 5, 11, 230 }, { 5, 11, 392 }, { 6, 11, 420 }, { 8, 10, 762 }, + { 8, 10, 812 }, { 9, 11, 568 }, { 9, 10, 910 }, { 12, 11, 612 }, + { 7, 0, 784 }, { 15, 0, 135 }, { 15, 11, 135 }, { 10, 0, 454 }, + { 12, 0, 324 }, { 4, 11, 0 }, { 5, 11, 41 }, { 7, 11, 1459 }, + { 7, 11, 1469 }, { 7, 11, 1618 }, { 7, 11, 1859 }, { 9, 11, 549 }, + { 11, 11, 905 }, { 4, 10, 98 }, { 7, 10, 1365 }, { 9, 10, 422 }, + { 9, 10, 670 }, { 10, 10, 775 }, { 11, 10, 210 }, { 13, 10, 26 }, + { 13, 10, 457 }, { 13, 10, 476 }, { 6, 0, 1719 }, { 6, 0, 1735 }, + { 7, 0, 2016 }, { 7, 0, 2020 }, { 8, 0, 837 }, { 9, 0, 852 }, + { 5, 11, 696 }, { 7, 0, 852 }, { 4, 0, 952 }, { 6, 10, 1730 }, + { 4, 11, 771 }, { 10, 0, 568 }, { 9, 0, 448 }, { 11, 0, 146 }, + { 8, 0, 67 }, { 10, 0, 419 }, { 5, 11, 921 }, { 9, 10, 147 }, + { 6, 0, 1826 }, { 10, 0, 657 }, { 14, 0, 297 }, { 14, 0, 361 }, + { 6, 0, 666 }, { 6, 0, 767 }, { 6, 0, 1542 }, { 11, 0, 729 }, + { 6, 11, 180 }, { 7, 11, 1137 }, { 8, 11, 751 }, { 11, 11, 805 }, + { 4, 11, 183 }, { 7, 11, 271 }, { 11, 11, 824 }, { 11, 11, 952 }, + { 13, 11, 278 }, { 13, 11, 339 }, { 13, 11, 482 }, { 14, 11, 424 }, + { 20, 11, 99 }, { 4, 0, 669 }, { 5, 11, 477 }, { 5, 11, 596 }, + { 6, 11, 505 }, { 7, 11, 1221 }, { 11, 11, 907 }, { 12, 11, 209 }, + { 13, 11, 214 }, { 7, 11, 1215 }, { 5, 0, 402 }, { 6, 10, 30 }, + { 11, 10, 56 }, { 11, 10, 305 }, { 7, 11, 564 }, { 14, 11, 168 }, + { 11, 0, 152 }, { 7, 0, 912 }, { 7, 10, 1614 }, { 4, 10, 150 }, + { 5, 10, 303 }, { 6, 10, 327 }, { 7, 0, 320 }, { 8, 0, 51 }, + { 9, 0, 868 }, { 10, 0, 833 }, { 12, 0, 481 }, { 12, 0, 570 }, + { 20, 0, 106 }, { 4, 0, 445 }, { 7, 11, 274 }, { 11, 11, 263 }, + { 11, 11, 479 }, { 11, 11, 507 }, { 12, 11, 277 }, { 10, 0, 555 }, + { 11, 0, 308 }, { 19, 0, 95 }, { 6, 11, 1645 }, { 8, 10, 192 }, + { 10, 10, 78 }, { 13, 10, 359 }, { 7, 10, 786 }, { 6, 11, 92 }, + { 6, 11, 188 }, { 7, 11, 1269 }, { 7, 11, 1524 }, { 7, 11, 1876 }, + { 10, 11, 228 }, { 11, 11, 1020 }, { 4, 11, 459 }, { 5, 11, 966 }, + { 11, 0, 386 }, { 6, 10, 1638 }, { 7, 10, 79 }, { 7, 10, 496 }, + { 9, 10, 138 }, { 10, 10, 336 }, { 12, 10, 412 }, { 12, 10, 440 }, + { 14, 10, 305 }, { 5, 0, 239 }, { 7, 0, 83 }, { 7, 0, 1990 }, + { 8, 0, 130 }, { 11, 0, 720 }, { 10, 11, 709 }, { 4, 0, 143 }, + { 5, 0, 550 }, { 5, 0, 752 }, { 5, 0, 123 }, { 6, 0, 530 }, + { 7, 0, 348 }, { 7, 0, 1419 }, { 7, 0, 2024 }, { 6, 11, 18 }, + { 7, 11, 179 }, { 7, 11, 721 }, { 7, 11, 932 }, { 8, 11, 548 }, + { 8, 11, 757 }, { 9, 11, 54 }, { 9, 11, 65 }, { 9, 11, 532 }, + { 9, 11, 844 }, { 10, 11, 113 }, { 10, 11, 117 }, { 10, 11, 236 }, + { 10, 11, 315 }, { 10, 11, 430 }, { 10, 11, 798 }, { 11, 11, 153 }, + { 11, 11, 351 }, { 11, 11, 375 }, { 12, 11, 78 }, { 12, 11, 151 }, + { 12, 11, 392 }, { 14, 11, 248 }, { 15, 11, 23 }, { 7, 10, 204 }, + { 7, 10, 415 }, { 8, 10, 42 }, { 10, 10, 85 }, { 11, 10, 564 }, + { 6, 0, 958 }, { 5, 11, 965 }, { 4, 0, 210 }, { 7, 11, 1429 }, + { 10, 11, 480 }, { 6, 11, 182 }, { 11, 11, 345 }, { 10, 11, 65 }, + { 10, 11, 488 }, { 10, 11, 497 }, { 4, 10, 3 }, { 5, 10, 247 }, + { 5, 10, 644 }, { 7, 10, 744 }, { 7, 10, 1207 }, { 7, 10, 1225 }, + { 7, 10, 1909 }, { 18, 10, 147 }, { 4, 0, 430 }, { 5, 10, 285 }, + { 9, 10, 67 }, { 13, 10, 473 }, { 15, 10, 82 }, { 16, 11, 16 }, + { 7, 11, 1162 }, { 9, 11, 588 }, { 10, 11, 260 }, { 23, 10, 8 }, + { 5, 0, 213 }, { 10, 0, 7 }, { 7, 0, 801 }, { 6, 11, 1786 }, + { 7, 11, 308 }, { 6, 0, 936 }, { 6, 0, 1289 }, { 5, 0, 108 }, + { 4, 0, 885 }, { 5, 0, 219 }, { 11, 0, 587 }, { 4, 0, 193 }, + { 5, 0, 916 }, { 6, 0, 1041 }, { 7, 0, 364 }, { 10, 0, 398 }, + { 10, 0, 726 }, { 11, 0, 317 }, { 11, 0, 626 }, { 12, 0, 142 }, + { 12, 0, 288 }, { 12, 0, 678 }, { 13, 0, 313 }, { 15, 0, 113 }, + { 18, 0, 114 }, { 7, 0, 1165 }, { 6, 0, 241 }, { 9, 0, 342 }, + { 10, 0, 729 }, { 11, 0, 284 }, { 11, 0, 445 }, { 11, 0, 651 }, + { 11, 0, 863 }, { 13, 0, 398 }, { 18, 0, 99 }, { 7, 0, 907 }, + { 8, 0, 832 }, { 9, 0, 303 }, { 4, 10, 29 }, { 6, 10, 532 }, + { 7, 10, 1628 }, { 7, 10, 1648 }, { 9, 10, 350 }, { 10, 10, 433 }, + { 11, 10, 97 }, { 11, 10, 557 }, { 11, 10, 745 }, { 12, 10, 289 }, + { 12, 10, 335 }, { 12, 10, 348 }, { 12, 10, 606 }, { 13, 10, 116 }, + { 13, 10, 233 }, { 13, 10, 466 }, { 14, 10, 181 }, { 14, 10, 209 }, + { 14, 10, 232 }, { 14, 10, 236 }, { 14, 10, 300 }, { 16, 10, 41 }, + { 20, 10, 97 }, { 7, 11, 423 }, { 7, 10, 1692 }, { 8, 11, 588 }, + { 6, 0, 931 }, { 6, 0, 1454 }, { 5, 10, 501 }, { 7, 10, 1704 }, + { 9, 10, 553 }, { 11, 10, 520 }, { 12, 10, 557 }, { 13, 10, 249 }, + { 8, 11, 287 }, { 4, 0, 562 }, { 9, 0, 254 }, { 11, 0, 879 }, + { 4, 0, 786 }, { 14, 11, 32 }, { 18, 11, 85 }, { 20, 11, 2 }, + { 24, 11, 16 }, { 7, 0, 1294 }, { 7, 11, 723 }, { 7, 11, 1135 }, + { 6, 0, 216 }, { 7, 0, 901 }, { 7, 0, 1343 }, { 8, 0, 493 }, + { 6, 11, 403 }, { 7, 11, 719 }, { 8, 11, 809 }, { 8, 11, 834 }, + { 5, 11, 210 }, { 6, 11, 213 }, { 7, 11, 60 }, { 10, 11, 364 }, + { 11, 11, 135 }, { 7, 0, 341 }, { 11, 0, 219 }, { 5, 11, 607 }, + { 8, 11, 326 }, { 8, 11, 490 }, { 4, 11, 701 }, { 5, 11, 472 }, + { 5, 11, 639 }, { 7, 11, 1249 }, { 9, 11, 758 }, { 11, 11, 896 }, + { 7, 11, 380 }, { 7, 11, 1947 }, { 11, 0, 130 }, { 7, 0, 1734 }, + { 10, 0, 115 }, { 11, 0, 420 }, { 12, 0, 154 }, { 13, 0, 404 }, + { 14, 0, 346 }, { 15, 0, 54 }, { 6, 10, 129 }, { 4, 11, 386 }, + { 7, 11, 41 }, { 8, 11, 405 }, { 9, 11, 497 }, { 11, 11, 110 }, + { 11, 11, 360 }, { 15, 11, 37 }, { 16, 11, 84 }, { 13, 11, 282 }, + { 5, 11, 46 }, { 7, 11, 1452 }, { 7, 11, 1480 }, { 8, 11, 634 }, + { 12, 11, 472 }, { 4, 11, 524 }, { 8, 11, 810 }, { 10, 11, 238 }, + { 13, 11, 33 }, { 5, 0, 604 }, { 5, 0, 1011 }, { 8, 0, 701 }, + { 8, 0, 856 }, { 8, 0, 858 }, { 8, 0, 879 }, { 12, 0, 702 }, + { 14, 0, 447 }, { 4, 0, 54 }, { 5, 0, 666 }, { 7, 0, 1039 }, + { 7, 0, 1130 }, { 9, 0, 195 }, { 10, 0, 302 }, { 4, 10, 25 }, + { 5, 10, 60 }, { 6, 10, 504 }, { 7, 10, 614 }, { 7, 10, 1155 }, + { 12, 10, 0 }, { 7, 10, 1248 }, { 11, 10, 621 }, { 11, 10, 702 }, + { 5, 11, 997 }, { 9, 10, 321 }, { 6, 0, 1669 }, { 6, 0, 1791 }, + { 4, 10, 379 }, { 7, 10, 1397 }, { 10, 11, 372 }, { 5, 11, 782 }, + { 5, 11, 829 }, { 6, 11, 1738 }, { 7, 0, 1228 }, { 4, 10, 118 }, + { 6, 10, 274 }, { 6, 10, 361 }, { 7, 10, 75 }, { 13, 10, 441 }, + { 4, 0, 623 }, { 9, 11, 279 }, { 10, 11, 407 }, { 14, 11, 84 }, + { 22, 11, 18 }, { 9, 10, 841 }, { 7, 0, 798 }, { 12, 10, 693 }, + { 5, 10, 314 }, { 6, 10, 221 }, { 7, 10, 419 }, { 10, 10, 650 }, + { 11, 10, 396 }, { 12, 10, 156 }, { 13, 10, 369 }, { 14, 10, 333 }, + { 17, 10, 47 }, { 7, 11, 1372 }, { 7, 0, 122 }, { 9, 0, 259 }, + { 10, 0, 84 }, { 11, 0, 470 }, { 12, 0, 541 }, { 13, 0, 379 }, + { 6, 0, 837 }, { 8, 0, 1013 }, { 4, 11, 78 }, { 5, 11, 96 }, + { 5, 11, 182 }, { 7, 11, 1724 }, { 7, 11, 1825 }, { 10, 11, 394 }, + { 10, 11, 471 }, { 11, 11, 532 }, { 14, 11, 340 }, { 17, 11, 88 }, + { 6, 0, 577 }, { 7, 11, 1964 }, { 4, 10, 913 }, { 6, 0, 460 }, + { 8, 0, 891 }, { 10, 0, 901 }, { 10, 0, 919 }, { 10, 0, 932 }, + { 12, 0, 715 }, { 12, 0, 728 }, { 12, 0, 777 }, { 14, 0, 457 }, + { 16, 0, 103 }, { 5, 0, 82 }, { 5, 0, 131 }, { 7, 0, 1755 }, + { 8, 0, 31 }, { 9, 0, 168 }, { 9, 0, 764 }, { 11, 0, 869 }, + { 8, 10, 475 }, { 6, 0, 605 }, { 5, 10, 1016 }, { 9, 11, 601 }, + { 9, 11, 619 }, { 10, 11, 505 }, { 10, 11, 732 }, { 11, 11, 355 }, + { 12, 11, 139 }, { 7, 10, 602 }, { 8, 10, 179 }, { 10, 10, 781 }, + { 12, 10, 126 }, { 6, 0, 1246 }, { 6, 10, 329 }, { 10, 10, 111 }, + { 6, 11, 215 }, { 7, 11, 1028 }, { 7, 11, 1473 }, { 7, 11, 1721 }, + { 9, 11, 424 }, { 10, 11, 779 }, { 5, 0, 278 }, { 9, 0, 68 }, + { 6, 0, 932 }, { 6, 0, 1084 }, { 16, 0, 86 }, { 4, 0, 163 }, + { 5, 0, 201 }, { 5, 0, 307 }, { 5, 0, 310 }, { 6, 0, 335 }, + { 7, 0, 284 }, { 7, 0, 1660 }, { 8, 0, 165 }, { 8, 0, 781 }, + { 6, 0, 707 }, { 6, 0, 33 }, { 7, 0, 1244 }, { 5, 10, 821 }, + { 6, 11, 67 }, { 6, 10, 1687 }, { 7, 11, 258 }, { 7, 11, 1630 }, + { 9, 11, 354 }, { 9, 11, 675 }, { 10, 11, 830 }, { 14, 11, 80 }, + { 17, 11, 80 }, { 6, 11, 141 }, { 7, 11, 225 }, { 9, 11, 59 }, + { 9, 11, 607 }, { 10, 11, 312 }, { 11, 11, 687 }, { 12, 11, 555 }, + { 13, 11, 373 }, { 13, 11, 494 }, { 20, 11, 58 }, { 6, 0, 1113 }, + { 9, 0, 388 }, { 5, 10, 71 }, { 7, 10, 1407 }, { 9, 10, 704 }, + { 10, 10, 261 }, { 10, 10, 619 }, { 11, 10, 547 }, { 11, 10, 619 }, + { 15, 10, 157 }, { 7, 0, 1953 }, { 8, 0, 720 }, { 10, 0, 203 }, + { 7, 10, 2008 }, { 9, 10, 337 }, { 10, 10, 517 }, { 6, 0, 326 }, + { 7, 0, 677 }, { 9, 0, 425 }, { 11, 11, 81 }, { 7, 0, 1316 }, + { 7, 0, 1412 }, { 7, 0, 1839 }, { 9, 0, 589 }, { 11, 0, 241 }, + { 11, 0, 676 }, { 11, 0, 811 }, { 11, 0, 891 }, { 12, 0, 140 }, + { 12, 0, 346 }, { 12, 0, 479 }, { 13, 0, 140 }, { 13, 0, 381 }, + { 14, 0, 188 }, { 18, 0, 30 }, { 20, 0, 108 }, { 5, 0, 416 }, + { 6, 10, 86 }, { 6, 10, 603 }, { 7, 10, 292 }, { 7, 10, 561 }, + { 8, 10, 257 }, { 8, 10, 382 }, { 9, 10, 721 }, { 9, 10, 778 }, + { 11, 10, 581 }, { 12, 10, 466 }, { 4, 10, 486 }, { 5, 10, 491 }, + { 6, 0, 1300 }, { 4, 10, 72 }, { 7, 0, 847 }, { 6, 10, 265 }, + { 7, 11, 430 }, { 11, 11, 46 }, { 5, 11, 602 }, { 6, 11, 106 }, + { 7, 11, 1786 }, { 7, 11, 1821 }, { 7, 11, 2018 }, { 9, 11, 418 }, + { 9, 11, 763 }, { 5, 0, 358 }, { 7, 0, 535 }, { 7, 0, 1184 }, + { 10, 0, 662 }, { 13, 0, 212 }, { 13, 0, 304 }, { 13, 0, 333 }, + { 17, 0, 98 }, { 5, 11, 65 }, { 6, 11, 416 }, { 7, 11, 1720 }, + { 7, 11, 1924 }, { 8, 11, 677 }, { 10, 11, 109 }, { 11, 11, 14 }, + { 11, 11, 70 }, { 11, 11, 569 }, { 11, 11, 735 }, { 15, 11, 153 }, + { 20, 11, 80 }, { 6, 0, 1823 }, { 8, 0, 839 }, { 8, 0, 852 }, + { 8, 0, 903 }, { 10, 0, 940 }, { 12, 0, 707 }, { 12, 0, 775 }, + { 7, 11, 1229 }, { 6, 0, 1522 }, { 12, 0, 654 }, { 8, 11, 595 }, + { 11, 0, 163 }, { 13, 0, 314 }, { 4, 0, 978 }, { 4, 0, 601 }, + { 6, 0, 2035 }, { 9, 10, 234 }, { 5, 10, 815 }, { 6, 10, 1688 }, + { 6, 10, 1755 }, { 5, 0, 946 }, { 8, 0, 434 }, { 6, 10, 197 }, + { 8, 10, 205 }, { 7, 0, 411 }, { 7, 0, 590 }, { 8, 0, 631 }, + { 9, 0, 323 }, { 10, 0, 355 }, { 11, 0, 491 }, { 12, 0, 143 }, + { 12, 0, 402 }, { 13, 0, 73 }, { 14, 0, 408 }, { 15, 0, 107 }, + { 18, 0, 71 }, { 7, 0, 1467 }, { 8, 0, 328 }, { 10, 0, 544 }, + { 11, 0, 955 }, { 12, 0, 13 }, { 13, 0, 320 }, { 17, 0, 83 }, + { 14, 0, 410 }, { 11, 0, 511 }, { 13, 0, 394 }, { 14, 0, 298 }, + { 14, 0, 318 }, { 18, 0, 103 }, { 6, 10, 452 }, { 7, 10, 312 }, + { 10, 10, 219 }, { 10, 10, 589 }, { 4, 10, 333 }, { 9, 10, 176 }, + { 12, 10, 353 }, { 13, 10, 187 }, { 7, 11, 329 }, { 4, 11, 469 }, + { 5, 0, 835 }, { 6, 0, 483 }, { 6, 11, 1743 }, { 5, 11, 929 }, + { 6, 11, 340 }, { 8, 11, 376 }, { 8, 11, 807 }, { 6, 10, 1685 }, + { 4, 0, 677 }, { 5, 11, 218 }, { 7, 11, 1610 }, { 10, 11, 83 }, + { 5, 11, 571 }, { 7, 11, 1842 }, { 4, 11, 455 }, { 9, 0, 70 }, + { 7, 0, 1405 }, { 7, 10, 135 }, { 8, 10, 7 }, { 8, 10, 62 }, + { 9, 10, 243 }, { 10, 10, 658 }, { 10, 10, 697 }, { 11, 10, 456 }, + { 11, 10, 756 }, { 9, 10, 395 }, { 10, 10, 79 }, { 9, 0, 108 }, + { 6, 11, 161 }, { 7, 11, 372 }, { 9, 11, 597 }, { 4, 11, 349 }, + { 4, 0, 777 }, { 4, 0, 331 }, { 7, 10, 631 }, { 5, 0, 747 }, + { 6, 11, 432 }, { 6, 11, 608 }, { 11, 11, 322 }, { 10, 10, 835 }, + { 5, 11, 468 }, { 7, 11, 1809 }, { 10, 11, 325 }, { 11, 11, 856 }, + { 12, 11, 345 }, { 15, 11, 104 }, { 5, 11, 223 }, { 7, 10, 406 }, + { 7, 10, 459 }, { 8, 10, 606 }, { 11, 10, 726 }, { 4, 11, 566 }, + { 14, 0, 68 }, { 4, 11, 59 }, { 7, 11, 1394 }, { 6, 11, 436 }, + { 11, 11, 481 }, { 4, 11, 48 }, { 5, 11, 271 }, { 7, 11, 953 }, + { 11, 11, 170 }, { 5, 11, 610 }, { 8, 11, 457 }, { 5, 11, 755 }, + { 7, 11, 1217 }, { 5, 10, 612 }, { 4, 11, 197 }, { 4, 0, 505 }, + { 4, 10, 372 }, { 7, 10, 482 }, { 8, 10, 158 }, { 9, 10, 602 }, + { 9, 10, 615 }, { 10, 10, 245 }, { 10, 10, 678 }, { 10, 10, 744 }, + { 11, 10, 248 }, { 11, 10, 806 }, { 5, 0, 326 }, { 5, 10, 854 }, + { 7, 10, 1991 }, { 4, 0, 691 }, { 18, 0, 16 }, { 6, 0, 628 }, + { 9, 0, 35 }, { 10, 0, 680 }, { 10, 0, 793 }, { 11, 0, 364 }, + { 13, 0, 357 }, { 15, 0, 164 }, { 10, 0, 654 }, { 6, 0, 32 }, + { 7, 0, 385 }, { 7, 0, 757 }, { 7, 0, 1916 }, { 8, 0, 37 }, + { 8, 0, 94 }, { 8, 0, 711 }, { 9, 0, 541 }, { 10, 0, 162 }, + { 10, 0, 795 }, { 11, 0, 989 }, { 11, 0, 1010 }, { 12, 0, 14 }, + { 14, 0, 308 }, { 5, 11, 217 }, { 6, 0, 152 }, { 6, 0, 349 }, + { 6, 0, 1682 }, { 7, 0, 1252 }, { 8, 0, 112 }, { 9, 0, 435 }, + { 9, 0, 668 }, { 10, 0, 290 }, { 10, 0, 319 }, { 10, 0, 815 }, + { 11, 0, 180 }, { 11, 0, 837 }, { 12, 0, 240 }, { 13, 0, 152 }, + { 13, 0, 219 }, { 14, 0, 158 }, { 4, 0, 581 }, { 6, 0, 726 }, + { 5, 10, 195 }, { 7, 10, 1685 }, { 6, 0, 126 }, { 7, 0, 573 }, + { 8, 0, 397 }, { 14, 0, 44 }, { 10, 0, 89 }, { 7, 10, 1997 }, + { 8, 10, 730 }, { 11, 10, 1006 }, { 6, 0, 1531 }, { 6, 0, 1167 }, + { 5, 0, 926 }, { 12, 0, 203 }, { 5, 10, 751 }, { 4, 11, 165 }, + { 7, 11, 1398 }, { 7, 11, 1829 }, { 7, 0, 1232 }, { 9, 0, 531 }, + { 7, 10, 821 }, { 6, 0, 943 }, { 5, 0, 670 }, { 4, 0, 880 }, + { 11, 0, 231 }, { 6, 0, 1617 }, { 7, 0, 1957 }, { 5, 11, 9 }, + { 7, 11, 297 }, { 7, 11, 966 }, { 12, 11, 306 }, { 6, 0, 975 }, + { 6, 0, 985 }, { 5, 10, 950 }, { 5, 10, 994 }, { 6, 10, 351 }, + { 12, 11, 21 }, { 23, 11, 7 }, { 5, 11, 146 }, { 6, 11, 411 }, + { 10, 11, 721 }, { 7, 0, 242 }, { 7, 0, 1942 }, { 6, 11, 177 }, + { 7, 11, 467 }, { 5, 0, 421 }, { 7, 10, 47 }, { 9, 10, 684 }, + { 5, 0, 834 }, { 7, 0, 1202 }, { 8, 0, 14 }, { 9, 0, 481 }, + { 9, 0, 880 }, { 10, 0, 465 }, { 6, 0, 688 }, { 9, 0, 834 }, + { 4, 10, 350 }, { 4, 0, 855 }, { 4, 0, 357 }, { 6, 0, 172 }, + { 7, 0, 143 }, { 9, 0, 413 }, { 5, 11, 200 }, { 4, 0, 590 }, + { 7, 10, 1812 }, { 13, 10, 259 }, { 13, 10, 356 }, { 14, 10, 242 }, + { 19, 10, 114 }, { 5, 10, 967 }, { 11, 0, 114 }, { 4, 10, 473 }, + { 7, 10, 623 }, { 8, 10, 808 }, { 9, 10, 871 }, { 9, 10, 893 }, + { 11, 10, 431 }, { 12, 10, 112 }, { 12, 10, 217 }, { 12, 10, 243 }, + { 12, 10, 562 }, { 12, 10, 663 }, { 12, 10, 683 }, { 13, 10, 141 }, + { 13, 10, 197 }, { 13, 10, 227 }, { 13, 10, 406 }, { 13, 10, 487 }, + { 14, 10, 156 }, { 14, 10, 203 }, { 14, 10, 224 }, { 14, 10, 256 }, + { 18, 10, 58 }, { 22, 10, 0 }, { 10, 10, 286 }, { 4, 10, 222 }, + { 7, 10, 286 }, { 8, 10, 629 }, { 5, 0, 169 }, { 7, 0, 333 }, + { 8, 0, 45 }, { 6, 11, 481 }, { 4, 0, 198 }, { 4, 0, 24 }, + { 5, 0, 140 }, { 5, 0, 185 }, { 7, 0, 1500 }, { 11, 0, 565 }, + { 11, 0, 838 }, { 4, 11, 84 }, { 7, 11, 1482 }, { 10, 11, 76 }, + { 10, 11, 142 }, { 5, 0, 585 }, { 13, 10, 306 }, { 5, 11, 1015 }, + { 4, 11, 315 }, { 5, 11, 507 }, { 7, 11, 1370 }, { 8, 10, 146 }, + { 6, 0, 691 }, { 6, 0, 1503 }, { 4, 0, 334 }, { 5, 0, 593 }, + { 4, 10, 465 }, { 7, 10, 1663 }, { 14, 11, 173 }, { 7, 0, 913 }, + { 12, 0, 116 }, { 6, 11, 1722 }, { 6, 0, 1360 }, { 4, 0, 802 }, + { 8, 11, 222 }, { 8, 11, 476 }, { 9, 11, 238 }, { 11, 11, 516 }, + { 11, 11, 575 }, { 15, 11, 109 }, { 18, 11, 100 }, { 6, 0, 308 }, + { 9, 0, 673 }, { 7, 10, 138 }, { 7, 10, 517 }, { 11, 10, 238 }, + { 4, 0, 709 }, { 6, 0, 1876 }, { 6, 0, 1895 }, { 9, 0, 994 }, + { 9, 0, 1006 }, { 12, 0, 829 }, { 12, 0, 888 }, { 12, 0, 891 }, + { 18, 0, 185 }, { 20, 10, 94 }, { 4, 0, 228 }, { 5, 0, 897 }, + { 7, 0, 1840 }, { 5, 10, 495 }, { 7, 10, 834 }, { 9, 10, 733 }, + { 11, 10, 378 }, { 5, 10, 559 }, { 6, 10, 21 }, { 6, 10, 1737 }, + { 7, 10, 1444 }, { 8, 10, 224 }, { 4, 0, 608 }, { 5, 0, 497 }, + { 6, 11, 40 }, { 7, 11, 1781 }, { 6, 0, 1573 }, { 7, 0, 2039 }, + { 6, 0, 540 }, { 8, 0, 136 }, { 4, 0, 897 }, { 5, 0, 786 }, + { 5, 10, 519 }, { 6, 0, 1878 }, { 6, 0, 1884 }, { 9, 0, 938 }, + { 9, 0, 948 }, { 9, 0, 955 }, { 9, 0, 973 }, { 9, 0, 1012 }, + { 12, 0, 895 }, { 12, 0, 927 }, { 15, 0, 254 }, { 6, 0, 1469 }, + { 5, 0, 999 }, { 4, 0, 299 }, { 7, 0, 1004 }, { 4, 0, 745 }, + { 5, 0, 578 }, { 8, 11, 574 }, { 5, 0, 456 }, { 6, 0, 1457 }, + { 7, 0, 1679 }, { 4, 10, 402 }, { 7, 0, 693 }, { 8, 0, 180 }, + { 12, 0, 163 }, { 8, 10, 323 }, { 8, 10, 479 }, { 11, 10, 580 }, + { 14, 10, 201 }, { 5, 10, 59 }, { 7, 10, 672 }, { 4, 11, 354 }, + { 18, 10, 34 }, { 4, 0, 755 }, { 7, 11, 1558 }, { 7, 0, 1740 }, + { 18, 0, 48 }, { 4, 10, 85 }, { 7, 10, 549 }, { 11, 0, 338 }, + { 5, 10, 94 }, { 6, 0, 1091 }, { 7, 11, 469 }, { 12, 0, 695 }, + { 12, 0, 704 }, { 20, 0, 113 }, { 5, 11, 830 }, { 14, 11, 338 }, + { 20, 11, 81 }, { 7, 0, 1464 }, { 6, 10, 11 }, { 7, 10, 187 }, + { 7, 0, 975 }, { 13, 0, 335 }, { 4, 10, 522 }, { 6, 0, 1979 }, + { 5, 11, 496 }, { 7, 11, 203 }, { 4, 10, 52 }, { 7, 10, 661 }, + { 7, 0, 1566 }, { 8, 0, 269 }, { 9, 0, 212 }, { 9, 0, 718 }, + { 14, 0, 15 }, { 14, 0, 132 }, { 14, 0, 227 }, { 4, 0, 890 }, + { 5, 0, 805 }, { 5, 0, 819 }, { 5, 0, 961 }, { 6, 0, 396 }, + { 6, 0, 1631 }, { 6, 0, 1678 }, { 7, 0, 1967 }, { 7, 0, 2041 }, + { 9, 0, 630 }, { 11, 0, 8 }, { 11, 0, 1019 }, { 12, 0, 176 }, + { 13, 0, 225 }, { 14, 0, 292 }, { 21, 0, 24 }, { 4, 10, 383 }, + { 5, 10, 520 }, { 6, 11, 547 }, { 7, 11, 1748 }, { 5, 11, 88 }, + { 9, 11, 239 }, { 18, 11, 128 }, { 7, 11, 650 }, { 7, 11, 1310 }, + { 4, 10, 281 }, { 5, 10, 38 }, { 7, 10, 194 }, { 7, 10, 668 }, + { 7, 10, 1893 }, { 9, 10, 397 }, { 7, 0, 1815 }, { 9, 10, 635 }, + { 11, 10, 559 }, { 7, 0, 1505 }, { 10, 0, 190 }, { 10, 0, 634 }, + { 11, 0, 792 }, { 12, 0, 358 }, { 12, 0, 447 }, { 5, 0, 0 }, + { 6, 0, 536 }, { 7, 0, 604 }, { 13, 0, 445 }, { 17, 0, 126 }, + { 7, 11, 1076 }, { 9, 11, 80 }, { 11, 11, 78 }, { 11, 11, 421 }, + { 11, 11, 534 }, { 12, 11, 545 }, { 8, 0, 966 }, { 10, 0, 1023 }, + { 14, 11, 369 }, { 18, 11, 72 }, { 7, 11, 1641 }, { 6, 0, 232 }, + { 6, 0, 412 }, { 7, 0, 1074 }, { 8, 0, 9 }, { 8, 0, 157 }, + { 8, 0, 786 }, { 9, 0, 196 }, { 9, 0, 352 }, { 9, 0, 457 }, + { 10, 0, 337 }, { 11, 0, 232 }, { 11, 0, 877 }, { 12, 0, 480 }, + { 12, 0, 546 }, { 7, 0, 958 }, { 4, 0, 382 }, { 8, 0, 579 }, + { 4, 0, 212 }, { 7, 0, 1206 }, { 4, 11, 497 }, { 5, 11, 657 }, + { 7, 11, 1584 }, { 4, 0, 681 }, { 8, 0, 971 }, { 10, 0, 965 }, + { 5, 10, 448 }, { 8, 10, 535 }, { 14, 0, 16 }, { 18, 0, 44 }, + { 11, 0, 584 }, { 11, 0, 616 }, { 14, 0, 275 }, { 11, 11, 584 }, + { 11, 11, 616 }, { 14, 11, 275 }, { 8, 11, 13 }, { 7, 10, 610 }, + { 7, 10, 1501 }, { 7, 11, 642 }, { 8, 11, 250 }, { 11, 11, 123 }, + { 11, 11, 137 }, { 13, 11, 48 }, { 14, 11, 95 }, { 5, 0, 655 }, + { 17, 0, 67 }, { 19, 0, 74 }, { 6, 0, 751 }, { 6, 0, 1967 }, + { 6, 0, 231 }, { 8, 0, 423 }, { 5, 0, 300 }, { 10, 0, 1016 }, + { 4, 10, 319 }, { 5, 10, 699 }, { 10, 10, 673 }, { 6, 0, 237 }, + { 7, 0, 611 }, { 8, 0, 100 }, { 9, 0, 416 }, { 11, 0, 335 }, + { 12, 0, 173 }, { 18, 0, 101 }, { 6, 10, 336 }, { 8, 10, 552 }, + { 9, 10, 285 }, { 10, 10, 99 }, { 11, 10, 568 }, { 6, 0, 1370 }, + { 7, 10, 1406 }, { 9, 10, 218 }, { 13, 10, 222 }, { 5, 10, 256 }, + { 7, 0, 1208 }, { 14, 11, 213 }, { 20, 11, 38 }, { 6, 0, 1219 }, + { 7, 11, 1642 }, { 13, 0, 417 }, { 14, 0, 129 }, { 15, 0, 15 }, + { 10, 11, 545 }, { 12, 11, 301 }, { 17, 10, 39 }, { 20, 10, 36 }, + { 5, 0, 199 }, { 4, 11, 904 }, { 5, 11, 794 }, { 12, 0, 427 }, + { 18, 0, 38 }, { 6, 0, 949 }, { 8, 0, 665 }, { 7, 10, 634 }, + { 4, 10, 618 }, { 7, 10, 259 }, { 4, 10, 339 }, { 5, 11, 761 }, + { 13, 10, 169 }, { 4, 10, 759 }, { 5, 0, 688 }, { 7, 0, 539 }, + { 7, 0, 712 }, { 7, 11, 386 }, { 10, 11, 713 }, { 6, 0, 1186 }, + { 6, 11, 7 }, { 6, 11, 35 }, { 7, 11, 147 }, { 7, 11, 1069 }, + { 7, 11, 1568 }, { 7, 11, 1575 }, { 7, 11, 1917 }, { 8, 11, 43 }, + { 8, 11, 208 }, { 9, 11, 128 }, { 9, 11, 866 }, { 10, 11, 20 }, + { 11, 11, 981 }, { 19, 11, 33 }, { 7, 11, 893 }, { 8, 10, 482 }, + { 13, 11, 424 }, { 6, 0, 312 }, { 6, 0, 1715 }, { 10, 0, 584 }, + { 11, 0, 546 }, { 11, 0, 692 }, { 12, 0, 259 }, { 12, 0, 295 }, + { 13, 0, 46 }, { 13, 0, 154 }, { 5, 10, 336 }, { 6, 10, 341 }, + { 6, 10, 478 }, { 6, 10, 1763 }, { 8, 10, 386 }, { 9, 0, 151 }, + { 4, 0, 588 }, { 24, 0, 4 }, { 6, 11, 322 }, { 9, 11, 552 }, + { 11, 11, 274 }, { 13, 11, 209 }, { 13, 11, 499 }, { 14, 11, 85 }, + { 15, 11, 126 }, { 17, 11, 70 }, { 7, 10, 73 }, { 4, 0, 231 }, + { 5, 0, 61 }, { 6, 0, 104 }, { 7, 0, 729 }, { 7, 0, 964 }, + { 7, 0, 1658 }, { 12, 0, 414 }, { 6, 0, 263 }, { 10, 0, 757 }, + { 7, 10, 1971 }, { 4, 0, 612 }, { 5, 0, 561 }, { 4, 0, 320 }, + { 7, 10, 1344 }, { 8, 11, 83 }, { 8, 11, 817 }, { 9, 11, 28 }, + { 9, 11, 29 }, { 9, 11, 885 }, { 10, 11, 387 }, { 11, 11, 633 }, + { 11, 11, 740 }, { 13, 11, 235 }, { 13, 11, 254 }, { 15, 11, 143 }, + { 15, 11, 146 }, { 5, 10, 396 }, { 6, 10, 501 }, { 12, 11, 49 }, + { 4, 0, 225 }, { 4, 10, 929 }, { 5, 10, 799 }, { 8, 10, 46 }, + { 8, 10, 740 }, { 4, 0, 405 }, { 7, 0, 817 }, { 14, 0, 58 }, + { 17, 0, 37 }, { 18, 0, 124 }, { 5, 0, 974 }, { 4, 11, 412 }, + { 5, 11, 581 }, { 4, 10, 892 }, { 5, 10, 770 }, { 4, 0, 996 }, + { 6, 0, 2026 }, { 4, 0, 527 }, { 5, 0, 235 }, { 7, 0, 1239 }, + { 11, 0, 131 }, { 12, 0, 370 }, { 9, 0, 16 }, { 13, 0, 386 }, + { 7, 11, 421 }, { 7, 0, 956 }, { 7, 0, 1157 }, { 7, 0, 1506 }, + { 7, 0, 1606 }, { 7, 0, 1615 }, { 7, 0, 1619 }, { 7, 0, 1736 }, + { 7, 0, 1775 }, { 8, 0, 590 }, { 9, 0, 324 }, { 9, 0, 736 }, + { 9, 0, 774 }, { 9, 0, 776 }, { 9, 0, 784 }, { 10, 0, 567 }, + { 10, 0, 708 }, { 11, 0, 518 }, { 11, 0, 613 }, { 11, 0, 695 }, + { 11, 0, 716 }, { 11, 0, 739 }, { 11, 0, 770 }, { 11, 0, 771 }, + { 11, 0, 848 }, { 11, 0, 857 }, { 11, 0, 931 }, { 11, 0, 947 }, + { 12, 0, 326 }, { 12, 0, 387 }, { 12, 0, 484 }, { 12, 0, 528 }, + { 12, 0, 552 }, { 12, 0, 613 }, { 13, 0, 189 }, { 13, 0, 256 }, + { 13, 0, 340 }, { 13, 0, 432 }, { 13, 0, 436 }, { 13, 0, 440 }, + { 13, 0, 454 }, { 14, 0, 174 }, { 14, 0, 220 }, { 14, 0, 284 }, + { 14, 0, 390 }, { 17, 0, 121 }, { 7, 10, 158 }, { 9, 0, 137 }, + { 10, 0, 221 }, { 4, 11, 110 }, { 10, 11, 415 }, { 10, 11, 597 }, + { 14, 11, 206 }, { 13, 11, 496 }, { 7, 11, 205 }, { 23, 10, 25 }, + { 7, 11, 778 }, { 7, 11, 1656 }, { 7, 10, 2001 }, { 9, 11, 369 }, + { 10, 11, 338 }, { 10, 11, 490 }, { 11, 11, 154 }, { 11, 11, 545 }, + { 11, 11, 775 }, { 13, 11, 77 }, { 13, 11, 274 }, { 4, 11, 444 }, + { 10, 11, 146 }, { 12, 11, 9 }, { 7, 0, 390 }, { 10, 0, 140 }, + { 7, 0, 1144 }, { 6, 0, 464 }, { 7, 10, 1461 }, { 12, 10, 91 }, + { 4, 10, 602 }, { 4, 11, 283 }, { 7, 11, 1194 }, { 5, 0, 407 }, + { 11, 0, 204 }, { 11, 0, 243 }, { 11, 0, 489 }, { 12, 0, 293 }, + { 19, 0, 37 }, { 20, 0, 73 }, { 22, 0, 38 }, { 7, 0, 1218 }, + { 8, 0, 303 }, { 5, 0, 325 }, { 8, 0, 5 }, { 8, 0, 227 }, + { 9, 0, 105 }, { 10, 0, 585 }, { 12, 0, 614 }, { 4, 10, 13 }, + { 5, 10, 567 }, { 7, 10, 1498 }, { 9, 10, 124 }, { 11, 10, 521 }, + { 12, 10, 405 }, { 7, 10, 1006 }, { 7, 0, 800 }, { 10, 0, 12 }, + { 6, 11, 1720 }, { 7, 0, 1783 }, { 4, 10, 735 }, { 10, 10, 812 }, + { 4, 10, 170 }, { 7, 10, 323 }, { 6, 0, 621 }, { 13, 0, 504 }, + { 16, 0, 89 }, { 5, 10, 304 }, { 7, 10, 1403 }, { 9, 11, 216 }, + { 6, 0, 920 }, { 6, 0, 1104 }, { 9, 11, 183 }, { 11, 11, 286 }, + { 4, 0, 376 }, { 5, 10, 742 }, { 6, 0, 218 }, { 8, 0, 641 }, + { 11, 0, 388 }, { 12, 0, 580 }, { 7, 0, 454 }, { 7, 0, 782 }, + { 8, 0, 768 }, { 12, 0, 686 }, { 9, 11, 33 }, { 5, 10, 111 }, + { 16, 0, 0 }, { 10, 0, 676 }, { 12, 0, 462 }, { 6, 0, 164 }, + { 8, 11, 735 }, { 5, 10, 444 }, { 22, 0, 50 }, { 7, 11, 1862 }, + { 12, 11, 491 }, { 12, 11, 520 }, { 13, 11, 383 }, { 14, 11, 244 }, + { 18, 11, 12 }, { 5, 11, 132 }, { 9, 11, 486 }, { 9, 11, 715 }, + { 10, 11, 458 }, { 11, 11, 373 }, { 11, 11, 668 }, { 11, 11, 795 }, + { 11, 11, 897 }, { 12, 11, 272 }, { 12, 11, 424 }, { 12, 11, 539 }, + { 12, 11, 558 }, { 14, 11, 245 }, { 14, 11, 263 }, { 14, 11, 264 }, + { 14, 11, 393 }, { 14, 11, 403 }, { 8, 10, 123 }, { 15, 10, 6 }, + { 16, 10, 7 }, { 6, 0, 285 }, { 8, 0, 654 }, { 11, 0, 749 }, + { 12, 0, 190 }, { 12, 0, 327 }, { 13, 0, 120 }, { 13, 0, 121 }, + { 13, 0, 327 }, { 15, 0, 47 }, { 18, 0, 40 }, { 5, 11, 8 }, + { 6, 11, 89 }, { 6, 11, 400 }, { 7, 11, 1569 }, { 7, 11, 1623 }, + { 7, 11, 1850 }, { 8, 11, 218 }, { 8, 11, 422 }, { 9, 11, 570 }, + { 10, 11, 626 }, { 6, 11, 387 }, { 7, 11, 882 }, { 13, 11, 111 }, + { 6, 0, 343 }, { 7, 0, 195 }, { 9, 0, 226 }, { 10, 0, 197 }, + { 10, 0, 575 }, { 11, 0, 502 }, { 11, 0, 899 }, { 6, 11, 224 }, + { 7, 11, 877 }, { 9, 11, 647 }, { 5, 10, 937 }, { 7, 10, 100 }, + { 7, 11, 790 }, { 22, 0, 29 }, { 19, 0, 8 }, { 6, 0, 1812 }, + { 21, 0, 8 }, { 7, 11, 394 }, { 7, 0, 1125 }, { 9, 0, 143 }, + { 11, 0, 61 }, { 14, 0, 405 }, { 22, 0, 21 }, { 10, 11, 755 }, + { 19, 11, 29 }, { 9, 11, 378 }, { 13, 11, 162 }, { 7, 10, 922 }, + { 5, 10, 619 }, { 5, 10, 698 }, { 6, 0, 1327 }, { 6, 0, 1598 }, + { 9, 0, 575 }, { 9, 11, 569 }, { 12, 11, 12 }, { 12, 11, 81 }, + { 12, 11, 319 }, { 13, 11, 69 }, { 14, 11, 259 }, { 16, 11, 87 }, + { 17, 11, 1 }, { 17, 11, 21 }, { 17, 11, 24 }, { 18, 11, 15 }, + { 18, 11, 56 }, { 18, 11, 59 }, { 18, 11, 127 }, { 18, 11, 154 }, + { 19, 11, 19 }, { 20, 11, 31 }, { 6, 0, 895 }, { 7, 11, 1231 }, + { 5, 0, 959 }, { 7, 11, 124 }, { 8, 11, 38 }, { 5, 11, 261 }, + { 7, 11, 78 }, { 7, 11, 199 }, { 8, 11, 815 }, { 9, 11, 126 }, + { 10, 11, 342 }, { 5, 10, 917 }, { 6, 10, 1659 }, { 7, 0, 1759 }, + { 5, 11, 595 }, { 7, 11, 1863 }, { 8, 0, 173 }, { 6, 0, 266 }, + { 14, 0, 261 }, { 4, 11, 628 }, { 5, 10, 251 }, { 5, 10, 956 }, + { 8, 10, 268 }, { 9, 10, 214 }, { 18, 10, 142 }, { 7, 11, 266 }, + { 8, 11, 804 }, { 7, 11, 208 }, { 6, 11, 79 }, { 7, 11, 1021 }, + { 7, 11, 1519 }, { 11, 11, 704 }, { 13, 11, 396 }, { 5, 10, 346 }, + { 5, 10, 711 }, { 8, 10, 390 }, { 8, 11, 741 }, { 6, 11, 376 }, + { 6, 0, 1427 }, { 6, 0, 1033 }, { 6, 0, 1217 }, { 8, 0, 300 }, + { 5, 10, 624 }, { 6, 11, 100 }, { 7, 11, 244 }, { 7, 11, 632 }, + { 7, 11, 1609 }, { 8, 11, 178 }, { 8, 11, 638 }, { 13, 11, 58 }, + { 6, 0, 584 }, { 5, 10, 783 }, { 7, 10, 1998 }, { 7, 10, 2047 }, + { 5, 0, 427 }, { 5, 0, 734 }, { 7, 0, 478 }, { 8, 0, 52 }, + { 7, 0, 239 }, { 11, 0, 217 }, { 14, 0, 165 }, { 6, 0, 1129 }, + { 6, 0, 168 }, { 6, 0, 1734 }, { 7, 0, 20 }, { 7, 0, 1056 }, + { 8, 0, 732 }, { 9, 0, 406 }, { 9, 0, 911 }, { 10, 0, 694 }, + { 4, 10, 594 }, { 5, 11, 791 }, { 7, 11, 686 }, { 8, 11, 33 }, + { 8, 11, 238 }, { 10, 11, 616 }, { 11, 11, 467 }, { 11, 11, 881 }, + { 13, 11, 217 }, { 13, 11, 253 }, { 14, 11, 268 }, { 9, 11, 476 }, + { 6, 0, 418 }, { 5, 0, 613 }, { 4, 0, 632 }, { 4, 11, 447 }, + { 7, 0, 32 }, { 7, 0, 984 }, { 8, 0, 85 }, { 8, 0, 709 }, + { 9, 0, 579 }, { 9, 0, 847 }, { 9, 0, 856 }, { 10, 0, 799 }, + { 11, 0, 258 }, { 11, 0, 1007 }, { 12, 0, 331 }, { 12, 0, 615 }, + { 13, 0, 188 }, { 13, 0, 435 }, { 14, 0, 8 }, { 15, 0, 165 }, + { 16, 0, 27 }, { 20, 0, 40 }, { 16, 11, 35 }, { 4, 11, 128 }, + { 5, 11, 415 }, { 6, 11, 462 }, { 7, 11, 294 }, { 7, 11, 578 }, + { 10, 11, 710 }, { 11, 11, 86 }, { 5, 0, 694 }, { 8, 0, 909 }, + { 7, 0, 1109 }, { 11, 0, 7 }, { 5, 10, 37 }, { 6, 10, 39 }, + { 6, 10, 451 }, { 7, 10, 218 }, { 7, 10, 1166 }, { 7, 10, 1687 }, + { 8, 10, 662 }, { 16, 10, 2 }, { 8, 11, 587 }, { 6, 11, 427 }, + { 7, 11, 1018 }, { 10, 11, 692 }, { 4, 11, 195 }, { 6, 10, 508 }, + { 7, 11, 802 }, { 4, 0, 167 }, { 7, 0, 82 }, { 5, 0, 62 }, + { 6, 0, 24 }, { 6, 0, 534 }, { 7, 0, 74 }, { 7, 0, 678 }, + { 7, 0, 684 }, { 7, 0, 1043 }, { 7, 0, 1072 }, { 8, 0, 280 }, + { 8, 0, 541 }, { 8, 0, 686 }, { 9, 0, 258 }, { 10, 0, 519 }, + { 11, 0, 252 }, { 12, 0, 282 }, { 10, 0, 33 }, { 4, 0, 359 }, + { 5, 11, 738 }, { 7, 0, 980 }, { 9, 0, 328 }, { 13, 0, 186 }, + { 13, 0, 364 }, { 7, 10, 635 }, { 7, 10, 796 }, { 8, 10, 331 }, + { 9, 10, 330 }, { 9, 10, 865 }, { 10, 10, 119 }, { 10, 10, 235 }, + { 11, 10, 111 }, { 11, 10, 129 }, { 11, 10, 240 }, { 12, 10, 31 }, + { 12, 10, 66 }, { 12, 10, 222 }, { 12, 10, 269 }, { 12, 10, 599 }, + { 12, 10, 684 }, { 12, 10, 689 }, { 12, 10, 691 }, { 14, 10, 345 }, + { 9, 10, 527 }, { 6, 0, 596 }, { 7, 0, 585 }, { 7, 10, 702 }, + { 6, 11, 1683 }, { 5, 0, 211 }, { 6, 0, 145 }, { 13, 0, 336 }, + { 6, 0, 1130 }, { 7, 0, 873 }, { 6, 10, 37 }, { 7, 10, 1666 }, + { 8, 10, 195 }, { 8, 10, 316 }, { 9, 10, 178 }, { 9, 10, 276 }, + { 9, 10, 339 }, { 9, 10, 536 }, { 10, 10, 102 }, { 10, 10, 362 }, + { 10, 10, 785 }, { 11, 10, 55 }, { 11, 10, 149 }, { 11, 10, 773 }, + { 13, 10, 416 }, { 13, 10, 419 }, { 14, 10, 38 }, { 14, 10, 41 }, + { 14, 10, 210 }, { 8, 0, 840 }, { 8, 0, 841 }, { 4, 0, 263 }, + { 5, 11, 3 }, { 8, 11, 578 }, { 9, 11, 118 }, { 10, 11, 705 }, + { 12, 11, 383 }, { 13, 11, 279 }, { 4, 0, 916 }, { 5, 11, 229 }, + { 5, 10, 645 }, { 15, 0, 155 }, { 16, 0, 79 }, { 8, 11, 102 }, + { 10, 11, 578 }, { 10, 11, 672 }, { 12, 11, 496 }, { 13, 11, 408 }, + { 14, 11, 121 }, { 17, 11, 106 }, { 4, 0, 599 }, { 5, 0, 592 }, + { 6, 0, 1634 }, { 7, 0, 5 }, { 7, 0, 55 }, { 7, 0, 67 }, + { 7, 0, 97 }, { 7, 0, 691 }, { 7, 0, 979 }, { 7, 0, 1600 }, + { 7, 0, 1697 }, { 8, 0, 207 }, { 8, 0, 214 }, { 8, 0, 231 }, + { 8, 0, 294 }, { 8, 0, 336 }, { 8, 0, 428 }, { 8, 0, 471 }, + { 8, 0, 622 }, { 8, 0, 626 }, { 8, 0, 679 }, { 8, 0, 759 }, + { 8, 0, 829 }, { 9, 0, 11 }, { 9, 0, 246 }, { 9, 0, 484 }, + { 9, 0, 573 }, { 9, 0, 706 }, { 9, 0, 762 }, { 9, 0, 798 }, + { 9, 0, 855 }, { 9, 0, 870 }, { 9, 0, 912 }, { 10, 0, 303 }, + { 10, 0, 335 }, { 10, 0, 424 }, { 10, 0, 461 }, { 10, 0, 543 }, + { 10, 0, 759 }, { 10, 0, 814 }, { 11, 0, 59 }, { 11, 0, 199 }, + { 11, 0, 235 }, { 11, 0, 590 }, { 11, 0, 631 }, { 11, 0, 929 }, + { 11, 0, 963 }, { 11, 0, 987 }, { 12, 0, 114 }, { 12, 0, 182 }, + { 12, 0, 226 }, { 12, 0, 332 }, { 12, 0, 439 }, { 12, 0, 575 }, + { 12, 0, 598 }, { 12, 0, 675 }, { 13, 0, 8 }, { 13, 0, 125 }, + { 13, 0, 194 }, { 13, 0, 287 }, { 14, 0, 197 }, { 14, 0, 383 }, + { 15, 0, 53 }, { 17, 0, 63 }, { 19, 0, 46 }, { 19, 0, 98 }, + { 19, 0, 106 }, { 20, 0, 85 }, { 7, 0, 1356 }, { 4, 10, 290 }, + { 6, 10, 70 }, { 7, 10, 1292 }, { 10, 10, 762 }, { 11, 10, 288 }, + { 22, 11, 55 }, { 4, 0, 593 }, { 8, 11, 115 }, { 8, 11, 350 }, + { 9, 11, 489 }, { 10, 11, 128 }, { 11, 11, 306 }, { 12, 11, 373 }, + { 14, 11, 30 }, { 17, 11, 79 }, { 19, 11, 80 }, { 7, 11, 1235 }, + { 6, 0, 1392 }, { 4, 11, 230 }, { 5, 11, 702 }, { 19, 0, 126 }, + { 7, 10, 131 }, { 7, 10, 422 }, { 8, 10, 210 }, { 12, 10, 573 }, + { 6, 0, 1179 }, { 11, 11, 435 }, { 11, 10, 797 }, { 6, 11, 1728 }, + { 4, 0, 162 }, { 18, 11, 26 }, { 19, 11, 42 }, { 20, 11, 43 }, + { 21, 11, 0 }, { 23, 11, 27 }, { 24, 11, 14 }, { 4, 10, 936 }, + { 6, 0, 765 }, { 5, 10, 453 }, { 6, 10, 441 }, { 5, 0, 187 }, + { 7, 0, 1286 }, { 6, 0, 635 }, { 6, 0, 904 }, { 6, 0, 1210 }, + { 6, 0, 1489 }, { 4, 0, 215 }, { 8, 0, 890 }, { 9, 0, 38 }, + { 10, 0, 923 }, { 11, 0, 23 }, { 11, 0, 127 }, { 11, 0, 796 }, + { 6, 0, 1165 }, { 6, 0, 1306 }, { 7, 0, 716 }, { 13, 0, 97 }, + { 13, 0, 251 }, { 4, 10, 653 }, { 8, 0, 657 }, { 18, 10, 80 }, + { 5, 11, 622 }, { 7, 11, 1032 }, { 11, 11, 26 }, { 11, 11, 213 }, + { 11, 11, 707 }, { 12, 11, 380 }, { 13, 11, 226 }, { 13, 11, 355 }, + { 6, 0, 299 }, { 5, 11, 70 }, { 6, 11, 334 }, { 9, 11, 171 }, + { 11, 11, 637 }, { 12, 11, 202 }, { 14, 11, 222 }, { 17, 11, 42 }, + { 14, 0, 134 }, { 4, 11, 23 }, { 5, 11, 313 }, { 5, 11, 1014 }, + { 6, 11, 50 }, { 6, 11, 51 }, { 7, 11, 142 }, { 7, 11, 384 }, + { 9, 11, 783 }, { 11, 11, 741 }, { 4, 11, 141 }, { 7, 11, 559 }, + { 8, 11, 640 }, { 9, 11, 460 }, { 12, 11, 183 }, { 13, 11, 488 }, + { 8, 11, 614 }, { 7, 10, 1368 }, { 8, 10, 232 }, { 8, 10, 361 }, + { 10, 10, 682 }, { 10, 10, 742 }, { 9, 10, 534 }, { 6, 0, 1082 }, + { 12, 0, 658 }, { 9, 10, 27 }, { 7, 0, 2002 }, { 14, 10, 12 }, + { 4, 0, 28 }, { 5, 0, 440 }, { 7, 0, 248 }, { 11, 0, 833 }, + { 12, 0, 344 }, { 7, 10, 736 }, { 11, 10, 264 }, { 6, 10, 1657 }, + { 6, 0, 1654 }, { 10, 0, 531 }, { 5, 11, 222 }, { 9, 11, 140 }, + { 10, 11, 534 }, { 6, 0, 634 }, { 6, 0, 798 }, { 6, 0, 840 }, + { 10, 11, 503 }, { 7, 10, 127 }, { 5, 0, 853 }, { 5, 11, 154 }, + { 7, 11, 1491 }, { 10, 11, 379 }, { 10, 11, 485 }, { 6, 0, 249 }, + { 7, 0, 1234 }, { 11, 0, 573 }, { 5, 11, 716 }, { 7, 11, 1570 }, + { 12, 11, 542 }, { 8, 10, 364 }, { 10, 0, 527 }, { 4, 11, 91 }, + { 5, 11, 388 }, { 5, 11, 845 }, { 6, 11, 206 }, { 6, 11, 252 }, + { 6, 11, 365 }, { 7, 11, 136 }, { 7, 11, 531 }, { 8, 11, 264 }, + { 8, 11, 621 }, { 6, 0, 1419 }, { 7, 11, 1441 }, { 7, 0, 49 }, + { 7, 0, 392 }, { 8, 0, 20 }, { 8, 0, 172 }, { 8, 0, 690 }, + { 9, 0, 383 }, { 9, 0, 845 }, { 10, 0, 48 }, { 11, 0, 293 }, + { 11, 0, 832 }, { 11, 0, 920 }, { 11, 0, 984 }, { 13, 0, 221 }, + { 5, 0, 858 }, { 5, 0, 992 }, { 5, 0, 728 }, { 9, 10, 792 }, + { 5, 10, 909 }, { 9, 10, 849 }, { 10, 10, 805 }, { 7, 0, 525 }, + { 7, 0, 1579 }, { 8, 0, 497 }, { 8, 0, 573 }, { 6, 0, 268 }, + { 9, 0, 62 }, { 7, 11, 576 }, { 6, 0, 1201 }, { 5, 11, 771 }, + { 5, 11, 863 }, { 5, 11, 898 }, { 6, 11, 1632 }, { 6, 11, 1644 }, + { 6, 11, 1780 }, { 5, 11, 331 }, { 7, 0, 193 }, { 7, 0, 1105 }, + { 10, 0, 495 }, { 7, 10, 397 }, { 8, 10, 124 }, { 8, 10, 619 }, + { 9, 10, 305 }, { 11, 10, 40 }, { 12, 10, 349 }, { 13, 10, 134 }, + { 13, 10, 295 }, { 14, 10, 155 }, { 15, 10, 120 }, { 18, 10, 105 }, + { 10, 0, 106 }, { 6, 0, 859 }, { 5, 11, 107 }, { 7, 11, 201 }, + { 8, 11, 518 }, { 6, 11, 446 }, { 7, 11, 1817 }, { 13, 0, 23 }, + { 4, 10, 262 }, { 7, 10, 342 }, { 5, 10, 641 }, { 9, 11, 851 }, + { 6, 0, 925 }, { 9, 0, 813 }, { 4, 11, 504 }, { 6, 0, 613 }, + { 8, 0, 223 }, { 4, 10, 99 }, { 6, 10, 250 }, { 6, 10, 346 }, + { 8, 10, 127 }, { 10, 10, 81 }, { 8, 0, 953 }, { 4, 10, 915 }, + { 11, 11, 892 }, { 5, 10, 75 }, { 9, 10, 517 }, { 10, 10, 470 }, + { 12, 10, 155 }, { 13, 10, 224 }, { 4, 0, 666 }, { 7, 0, 1017 }, + { 7, 11, 996 }, { 10, 11, 390 }, { 5, 11, 883 }, { 5, 11, 975 }, + { 14, 10, 83 }, { 14, 11, 83 }, { 4, 0, 670 }, { 5, 11, 922 }, + { 6, 11, 1707 }, { 7, 0, 216 }, { 9, 0, 40 }, { 11, 0, 136 }, + { 7, 11, 787 }, { 5, 10, 954 }, { 5, 11, 993 }, { 7, 11, 515 }, + { 9, 11, 91 }, { 11, 0, 259 }, { 7, 0, 1114 }, { 9, 0, 310 }, + { 9, 0, 682 }, { 10, 0, 440 }, { 13, 0, 40 }, { 6, 10, 304 }, + { 8, 10, 418 }, { 11, 10, 341 }, { 11, 10, 675 }, { 14, 0, 296 }, + { 9, 10, 410 }, { 11, 10, 425 }, { 10, 11, 377 }, { 12, 11, 363 }, + { 13, 11, 68 }, { 13, 11, 94 }, { 14, 11, 108 }, { 14, 11, 306 }, + { 7, 0, 1401 }, { 7, 0, 1476 }, { 4, 0, 296 }, { 6, 0, 475 }, + { 7, 0, 401 }, { 7, 0, 1410 }, { 7, 0, 1594 }, { 7, 0, 1674 }, + { 8, 0, 63 }, { 8, 0, 660 }, { 9, 0, 74 }, { 4, 0, 139 }, + { 4, 0, 388 }, { 12, 0, 188 }, { 4, 0, 797 }, { 4, 11, 766 }, + { 5, 11, 103 }, { 7, 11, 921 }, { 8, 11, 580 }, { 8, 11, 593 }, + { 8, 11, 630 }, { 10, 11, 28 }, { 4, 11, 911 }, { 5, 11, 867 }, + { 5, 11, 1013 }, { 6, 10, 14 }, { 6, 0, 1572 }, { 6, 10, 1708 }, + { 21, 0, 39 }, { 5, 10, 113 }, { 6, 10, 243 }, { 7, 10, 1865 }, + { 11, 10, 161 }, { 16, 10, 37 }, { 17, 10, 99 }, { 7, 11, 1563 }, + { 13, 11, 182 }, { 5, 11, 135 }, { 6, 11, 519 }, { 7, 11, 1722 }, + { 10, 11, 271 }, { 11, 11, 261 }, { 17, 11, 54 }, { 4, 10, 274 }, + { 6, 0, 1594 }, { 4, 11, 300 }, { 5, 11, 436 }, { 7, 11, 484 }, + { 4, 0, 747 }, { 6, 0, 290 }, { 7, 0, 649 }, { 7, 0, 1479 }, + { 7, 0, 1583 }, { 5, 11, 535 }, { 19, 11, 82 }, { 5, 0, 232 }, + { 9, 0, 887 }, { 7, 10, 166 }, { 8, 0, 521 }, { 4, 0, 14 }, + { 7, 0, 472 }, { 7, 0, 1801 }, { 10, 0, 748 }, { 13, 0, 458 }, + { 6, 0, 741 }, { 6, 0, 992 }, { 16, 0, 111 }, { 9, 10, 304 }, + { 4, 0, 425 }, { 5, 11, 387 }, { 7, 11, 557 }, { 12, 11, 547 }, + { 14, 11, 86 }, { 7, 11, 1747 }, { 5, 10, 654 }, { 7, 11, 1489 }, + { 7, 0, 789 }, { 4, 11, 6 }, { 5, 11, 708 }, { 8, 11, 75 }, + { 6, 10, 273 }, { 10, 10, 188 }, { 13, 10, 377 }, { 18, 10, 77 }, + { 6, 0, 1593 }, { 4, 11, 303 }, { 7, 11, 619 }, { 10, 11, 547 }, + { 10, 11, 687 }, { 11, 11, 122 }, { 12, 11, 601 }, { 6, 0, 1768 }, + { 7, 10, 410 }, { 10, 11, 772 }, { 11, 0, 233 }, { 11, 10, 524 }, + { 5, 0, 943 }, { 6, 0, 1779 }, { 6, 10, 1785 }, { 8, 11, 529 }, + { 4, 0, 955 }, { 5, 0, 245 }, { 6, 0, 576 }, { 7, 0, 582 }, + { 8, 0, 225 }, { 4, 10, 780 }, { 14, 0, 241 }, { 6, 0, 1943 }, + { 4, 11, 106 }, { 7, 11, 310 }, { 7, 11, 1785 }, { 10, 11, 690 }, + { 11, 11, 717 }, { 6, 0, 1284 }, { 5, 11, 890 }, { 5, 11, 988 }, + { 6, 11, 626 }, { 14, 11, 431 }, { 10, 11, 706 }, { 17, 11, 32 }, + { 9, 11, 332 }, { 4, 11, 698 }, { 7, 0, 709 }, { 5, 10, 948 }, + { 10, 11, 17 }, { 8, 0, 554 }, { 6, 0, 1564 }, { 11, 10, 941 }, + { 4, 0, 443 }, { 6, 0, 909 }, { 6, 11, 84 }, { 14, 0, 280 }, + { 4, 10, 532 }, { 5, 10, 706 }, { 7, 10, 662 }, { 4, 0, 729 }, + { 5, 10, 837 }, { 6, 10, 1651 }, { 11, 10, 985 }, { 7, 10, 1861 }, + { 4, 0, 348 }, { 24, 11, 3 }, { 5, 11, 986 }, { 6, 11, 130 }, + { 7, 11, 1582 }, { 8, 11, 458 }, { 10, 11, 101 }, { 10, 11, 318 }, + { 10, 11, 823 }, { 6, 0, 758 }, { 4, 0, 298 }, { 9, 0, 848 }, + { 4, 10, 330 }, { 7, 10, 933 }, { 7, 10, 2012 }, { 8, 10, 292 }, + { 7, 11, 1644 }, { 9, 11, 129 }, { 6, 0, 1422 }, { 9, 0, 829 }, + { 7, 10, 767 }, { 5, 0, 164 }, { 7, 0, 121 }, { 14, 0, 189 }, + { 7, 0, 812 }, { 7, 0, 1261 }, { 7, 0, 1360 }, { 9, 0, 632 }, + { 12, 0, 352 }, { 7, 11, 1788 }, { 11, 0, 556 }, { 7, 11, 997 }, + { 17, 10, 114 }, { 4, 0, 172 }, { 9, 0, 611 }, { 10, 0, 436 }, + { 12, 0, 673 }, { 13, 0, 255 }, { 9, 10, 883 }, { 11, 0, 530 }, + { 10, 10, 274 }, { 5, 0, 844 }, { 6, 0, 984 }, { 13, 0, 232 }, + { 18, 0, 35 }, { 4, 10, 703 }, { 7, 10, 207 }, { 4, 10, 571 }, + { 9, 0, 263 }, { 10, 0, 147 }, { 10, 0, 492 }, { 7, 11, 1756 }, + { 9, 11, 98 }, { 5, 10, 873 }, { 5, 10, 960 }, { 8, 10, 823 }, + { 9, 10, 881 }, { 5, 0, 537 }, { 4, 0, 859 }, { 7, 11, 1046 }, + { 11, 11, 160 }, { 9, 0, 842 }, { 11, 10, 283 }, { 5, 10, 33 }, + { 6, 10, 470 }, { 11, 10, 424 }, { 6, 11, 45 }, { 7, 11, 433 }, + { 8, 11, 129 }, { 9, 11, 21 }, { 10, 11, 392 }, { 11, 11, 79 }, + { 12, 11, 499 }, { 13, 11, 199 }, { 13, 11, 451 }, { 7, 0, 1291 }, + { 7, 10, 1882 }, { 7, 11, 558 }, { 8, 11, 353 }, { 6, 0, 1482 }, + { 5, 0, 230 }, { 5, 0, 392 }, { 6, 0, 420 }, { 9, 0, 568 }, + { 12, 0, 612 }, { 6, 0, 262 }, { 7, 10, 90 }, { 7, 10, 664 }, + { 7, 10, 830 }, { 7, 10, 1380 }, { 7, 10, 2025 }, { 8, 11, 81 }, + { 8, 10, 448 }, { 8, 10, 828 }, { 9, 11, 189 }, { 9, 11, 201 }, + { 11, 11, 478 }, { 11, 11, 712 }, { 13, 11, 338 }, { 14, 0, 31 }, + { 5, 11, 353 }, { 23, 11, 26 }, { 4, 0, 753 }, { 4, 0, 0 }, + { 5, 0, 41 }, { 7, 0, 1459 }, { 7, 0, 1469 }, { 7, 0, 1859 }, + { 9, 0, 549 }, { 11, 0, 905 }, { 9, 10, 417 }, { 9, 10, 493 }, + { 7, 11, 1113 }, { 5, 0, 696 }, { 13, 11, 448 }, { 6, 10, 295 }, + { 4, 0, 834 }, { 4, 0, 771 }, { 5, 10, 1019 }, { 6, 11, 25 }, + { 7, 11, 855 }, { 7, 11, 1258 }, { 16, 11, 32 }, { 6, 0, 1076 }, + { 5, 0, 921 }, { 5, 0, 674 }, { 4, 11, 4 }, { 7, 11, 1118 }, + { 7, 11, 1320 }, { 7, 11, 1706 }, { 8, 11, 277 }, { 9, 11, 622 }, + { 10, 11, 9 }, { 11, 11, 724 }, { 12, 11, 350 }, { 12, 11, 397 }, + { 13, 11, 28 }, { 13, 11, 159 }, { 15, 11, 89 }, { 18, 11, 5 }, + { 19, 11, 9 }, { 20, 11, 34 }, { 22, 11, 47 }, { 6, 10, 208 }, + { 6, 0, 444 }, { 8, 0, 308 }, { 6, 0, 180 }, { 7, 0, 1137 }, + { 8, 0, 751 }, { 11, 0, 805 }, { 4, 0, 183 }, { 7, 0, 271 }, + { 11, 0, 824 }, { 11, 0, 952 }, { 13, 0, 278 }, { 13, 0, 339 }, + { 13, 0, 482 }, { 14, 0, 424 }, { 20, 0, 99 }, { 7, 11, 317 }, + { 7, 11, 569 }, { 4, 0, 19 }, { 5, 0, 477 }, { 5, 0, 596 }, + { 6, 0, 505 }, { 7, 0, 1221 }, { 11, 0, 907 }, { 12, 0, 209 }, + { 13, 0, 214 }, { 7, 0, 1215 }, { 6, 0, 271 }, { 7, 0, 398 }, + { 8, 0, 387 }, { 10, 0, 344 }, { 7, 10, 448 }, { 7, 10, 1629 }, + { 7, 10, 1813 }, { 8, 10, 442 }, { 9, 10, 710 }, { 10, 10, 282 }, + { 10, 10, 722 }, { 11, 10, 844 }, { 12, 10, 104 }, { 12, 10, 625 }, + { 6, 11, 255 }, { 5, 10, 787 }, { 6, 0, 1645 }, { 11, 11, 956 }, + { 23, 11, 3 }, { 6, 0, 92 }, { 6, 0, 188 }, { 7, 0, 209 }, + { 7, 0, 1269 }, { 7, 0, 1524 }, { 7, 0, 1876 }, { 8, 0, 661 }, + { 10, 0, 42 }, { 10, 0, 228 }, { 11, 0, 58 }, { 11, 0, 1020 }, + { 12, 0, 58 }, { 12, 0, 118 }, { 13, 0, 32 }, { 4, 0, 459 }, + { 5, 0, 966 }, { 4, 11, 536 }, { 7, 11, 1141 }, { 10, 11, 723 }, + { 11, 11, 371 }, { 12, 0, 330 }, { 6, 0, 1557 }, { 7, 11, 285 }, + { 7, 11, 876 }, { 8, 10, 491 }, { 7, 11, 560 }, { 6, 0, 18 }, + { 7, 0, 179 }, { 7, 0, 932 }, { 8, 0, 548 }, { 8, 0, 757 }, + { 9, 0, 54 }, { 9, 0, 65 }, { 9, 0, 532 }, { 9, 0, 844 }, + { 10, 0, 113 }, { 10, 0, 117 }, { 10, 0, 315 }, { 10, 0, 560 }, + { 10, 0, 622 }, { 10, 0, 798 }, { 11, 0, 153 }, { 11, 0, 351 }, + { 11, 0, 375 }, { 12, 0, 78 }, { 12, 0, 151 }, { 12, 0, 392 }, + { 12, 0, 666 }, { 14, 0, 248 }, { 15, 0, 23 }, { 6, 0, 1742 }, + { 4, 11, 690 }, { 4, 10, 403 }, { 5, 10, 441 }, { 7, 10, 450 }, + { 10, 10, 840 }, { 11, 10, 101 }, { 12, 10, 193 }, { 13, 10, 430 }, + { 5, 0, 965 }, { 6, 0, 182 }, { 10, 0, 65 }, { 10, 0, 488 }, + { 10, 0, 497 }, { 7, 11, 1346 }, { 6, 0, 973 }, { 6, 0, 1158 }, + { 10, 11, 200 }, { 19, 11, 2 }, { 23, 11, 22 }, { 4, 11, 190 }, + { 5, 11, 554 }, { 5, 10, 679 }, { 7, 0, 328 }, { 9, 10, 326 }, + { 5, 11, 1001 }, { 9, 0, 588 }, { 10, 0, 260 }, { 5, 11, 446 }, + { 7, 10, 1128 }, { 7, 10, 1796 }, { 19, 11, 119 }, { 6, 0, 1786 }, + { 6, 0, 1328 }, { 6, 0, 1985 }, { 8, 0, 962 }, { 10, 0, 1017 }, + { 7, 0, 308 }, { 11, 0, 508 }, { 4, 10, 574 }, { 7, 10, 350 }, + { 7, 10, 1024 }, { 8, 10, 338 }, { 9, 10, 677 }, { 10, 10, 808 }, + { 10, 11, 752 }, { 7, 10, 1081 }, { 9, 11, 96 }, { 7, 10, 1676 }, + { 7, 10, 2037 }, { 8, 0, 588 }, { 4, 11, 304 }, { 5, 0, 614 }, + { 12, 0, 793 }, { 8, 0, 287 }, { 9, 10, 297 }, { 13, 10, 37 }, + { 6, 11, 53 }, { 6, 11, 199 }, { 7, 11, 1408 }, { 8, 11, 32 }, + { 8, 11, 93 }, { 9, 11, 437 }, { 10, 11, 397 }, { 10, 11, 629 }, + { 11, 11, 593 }, { 11, 11, 763 }, { 13, 11, 326 }, { 17, 11, 35 }, + { 6, 11, 105 }, { 9, 11, 320 }, { 10, 11, 506 }, { 10, 11, 794 }, + { 5, 11, 114 }, { 5, 11, 255 }, { 13, 11, 285 }, { 12, 0, 290 }, + { 7, 11, 2035 }, { 8, 11, 19 }, { 9, 11, 89 }, { 10, 11, 831 }, + { 6, 0, 1136 }, { 7, 0, 719 }, { 8, 0, 796 }, { 8, 0, 809 }, + { 8, 0, 834 }, { 6, 10, 306 }, { 7, 10, 1140 }, { 7, 10, 1340 }, + { 8, 10, 133 }, { 10, 10, 449 }, { 11, 10, 1011 }, { 5, 0, 210 }, + { 6, 0, 213 }, { 7, 0, 60 }, { 10, 0, 364 }, { 11, 0, 135 }, + { 5, 0, 607 }, { 8, 0, 326 }, { 8, 0, 490 }, { 10, 11, 176 }, + { 4, 0, 701 }, { 5, 0, 472 }, { 7, 0, 380 }, { 9, 0, 758 }, + { 7, 0, 1947 }, { 6, 0, 1079 }, { 10, 0, 278 }, { 10, 11, 391 }, + { 5, 10, 329 }, { 8, 10, 260 }, { 11, 11, 156 }, { 4, 0, 386 }, + { 7, 0, 41 }, { 8, 0, 405 }, { 8, 0, 728 }, { 9, 0, 497 }, + { 11, 0, 110 }, { 11, 0, 360 }, { 15, 0, 37 }, { 16, 0, 84 }, + { 5, 0, 46 }, { 7, 0, 1452 }, { 7, 0, 1480 }, { 8, 0, 634 }, + { 12, 0, 472 }, { 8, 0, 961 }, { 4, 0, 524 }, { 8, 0, 810 }, + { 10, 0, 238 }, { 13, 0, 33 }, { 4, 10, 657 }, { 24, 10, 7 }, + { 5, 0, 532 }, { 5, 0, 997 }, { 7, 10, 1665 }, { 7, 11, 594 }, + { 7, 11, 851 }, { 7, 11, 1858 }, { 9, 11, 411 }, { 9, 11, 574 }, + { 9, 11, 666 }, { 9, 11, 737 }, { 10, 11, 346 }, { 10, 11, 712 }, + { 11, 11, 246 }, { 11, 11, 432 }, { 11, 11, 517 }, { 11, 11, 647 }, + { 11, 11, 679 }, { 11, 11, 727 }, { 12, 11, 304 }, { 12, 11, 305 }, + { 12, 11, 323 }, { 12, 11, 483 }, { 12, 11, 572 }, { 12, 11, 593 }, + { 12, 11, 602 }, { 13, 11, 95 }, { 13, 11, 101 }, { 13, 11, 171 }, + { 13, 11, 315 }, { 13, 11, 378 }, { 13, 11, 425 }, { 13, 11, 475 }, + { 14, 11, 63 }, { 14, 11, 380 }, { 14, 11, 384 }, { 15, 11, 133 }, + { 18, 11, 112 }, { 20, 11, 72 }, { 5, 11, 955 }, { 8, 11, 814 }, + { 6, 0, 1301 }, { 5, 10, 66 }, { 7, 10, 1896 }, { 8, 10, 288 }, + { 5, 11, 56 }, { 6, 10, 1643 }, { 6, 0, 1298 }, { 20, 11, 100 }, + { 5, 0, 782 }, { 5, 0, 829 }, { 6, 0, 671 }, { 6, 0, 1156 }, + { 6, 0, 1738 }, { 9, 11, 621 }, { 4, 0, 306 }, { 5, 0, 570 }, + { 7, 0, 1347 }, { 5, 10, 91 }, { 5, 10, 648 }, { 5, 10, 750 }, + { 5, 10, 781 }, { 6, 10, 54 }, { 6, 10, 112 }, { 6, 10, 402 }, + { 6, 10, 1732 }, { 7, 10, 315 }, { 7, 10, 749 }, { 7, 10, 1900 }, + { 9, 10, 78 }, { 9, 10, 508 }, { 10, 10, 611 }, { 10, 10, 811 }, + { 11, 10, 510 }, { 11, 10, 728 }, { 13, 10, 36 }, { 14, 10, 39 }, + { 16, 10, 83 }, { 17, 10, 124 }, { 20, 10, 30 }, { 8, 10, 570 }, + { 9, 11, 477 }, { 13, 11, 78 }, { 4, 11, 639 }, { 10, 11, 4 }, + { 10, 10, 322 }, { 10, 10, 719 }, { 11, 10, 407 }, { 11, 11, 638 }, + { 12, 11, 177 }, { 20, 11, 57 }, { 7, 0, 1823 }, { 11, 0, 693 }, + { 7, 0, 759 }, { 5, 11, 758 }, { 8, 10, 125 }, { 8, 10, 369 }, + { 8, 10, 524 }, { 10, 10, 486 }, { 11, 10, 13 }, { 11, 10, 381 }, + { 11, 10, 736 }, { 11, 10, 766 }, { 11, 10, 845 }, { 13, 10, 114 }, + { 13, 10, 292 }, { 14, 10, 47 }, { 7, 0, 1932 }, { 6, 10, 1684 }, + { 6, 10, 1731 }, { 7, 10, 356 }, { 8, 10, 54 }, { 8, 10, 221 }, + { 9, 10, 225 }, { 9, 10, 356 }, { 10, 10, 77 }, { 10, 10, 446 }, + { 10, 10, 731 }, { 12, 10, 404 }, { 13, 10, 491 }, { 7, 11, 552 }, + { 7, 11, 1112 }, { 4, 0, 78 }, { 5, 0, 96 }, { 5, 0, 182 }, + { 6, 0, 1257 }, { 7, 0, 1724 }, { 7, 0, 1825 }, { 10, 0, 394 }, + { 10, 0, 471 }, { 11, 0, 532 }, { 14, 0, 340 }, { 17, 0, 88 }, + { 11, 11, 328 }, { 7, 0, 1964 }, { 4, 10, 411 }, { 4, 10, 80 }, + { 5, 10, 44 }, { 9, 11, 133 }, { 5, 11, 110 }, { 6, 11, 169 }, + { 6, 11, 1702 }, { 7, 11, 400 }, { 8, 11, 538 }, { 9, 11, 184 }, + { 9, 11, 524 }, { 12, 11, 218 }, { 4, 0, 521 }, { 5, 10, 299 }, + { 7, 10, 1083 }, { 12, 11, 554 }, { 6, 11, 133 }, { 9, 11, 353 }, + { 12, 11, 628 }, { 18, 11, 79 }, { 6, 0, 215 }, { 7, 0, 584 }, + { 7, 0, 1028 }, { 7, 0, 1473 }, { 7, 0, 1721 }, { 9, 0, 424 }, + { 10, 0, 779 }, { 7, 0, 857 }, { 7, 0, 1209 }, { 7, 10, 1713 }, + { 9, 10, 537 }, { 10, 10, 165 }, { 12, 10, 219 }, { 12, 10, 561 }, + { 4, 10, 219 }, { 6, 11, 93 }, { 7, 11, 1422 }, { 7, 10, 1761 }, + { 7, 11, 1851 }, { 8, 11, 673 }, { 9, 10, 86 }, { 9, 11, 529 }, + { 12, 11, 43 }, { 9, 11, 371 }, { 8, 0, 671 }, { 5, 0, 328 }, + { 7, 0, 918 }, { 4, 0, 529 }, { 9, 11, 25 }, { 10, 11, 467 }, + { 10, 11, 559 }, { 4, 11, 335 }, { 7, 11, 942 }, { 6, 0, 716 }, + { 6, 0, 1509 }, { 6, 0, 67 }, { 7, 0, 258 }, { 7, 0, 1630 }, + { 9, 0, 354 }, { 9, 0, 675 }, { 10, 0, 830 }, { 14, 0, 80 }, + { 17, 0, 80 }, { 12, 10, 428 }, { 6, 0, 1112 }, { 6, 0, 141 }, + { 7, 0, 225 }, { 9, 0, 59 }, { 9, 0, 607 }, { 10, 0, 312 }, + { 11, 0, 687 }, { 12, 0, 555 }, { 13, 0, 373 }, { 13, 0, 494 }, + { 20, 0, 58 }, { 5, 10, 514 }, { 8, 11, 39 }, { 10, 11, 773 }, + { 11, 11, 84 }, { 12, 11, 205 }, { 14, 11, 1 }, { 8, 0, 783 }, + { 5, 11, 601 }, { 5, 11, 870 }, { 8, 11, 594 }, { 4, 10, 55 }, + { 5, 10, 301 }, { 6, 10, 571 }, { 14, 10, 49 }, { 18, 10, 102 }, + { 4, 11, 181 }, { 6, 11, 1652 }, { 5, 10, 364 }, { 4, 11, 97 }, + { 5, 11, 147 }, { 6, 11, 286 }, { 7, 11, 1362 }, { 13, 11, 176 }, + { 4, 10, 76 }, { 7, 10, 1550 }, { 9, 10, 306 }, { 9, 10, 430 }, + { 9, 10, 663 }, { 10, 10, 683 }, { 11, 10, 427 }, { 11, 10, 753 }, + { 12, 10, 334 }, { 12, 10, 442 }, { 14, 10, 258 }, { 14, 10, 366 }, + { 15, 10, 131 }, { 9, 10, 52 }, { 6, 0, 955 }, { 6, 0, 1498 }, + { 6, 11, 375 }, { 7, 11, 169 }, { 7, 11, 254 }, { 8, 11, 780 }, + { 7, 0, 430 }, { 11, 0, 46 }, { 14, 0, 343 }, { 14, 11, 343 }, + { 7, 0, 1183 }, { 5, 0, 602 }, { 7, 0, 2018 }, { 9, 0, 418 }, + { 9, 0, 803 }, { 7, 11, 1447 }, { 8, 0, 677 }, { 7, 11, 1044 }, + { 11, 11, 285 }, { 4, 10, 656 }, { 7, 10, 779 }, { 7, 10, 144 }, + { 5, 11, 629 }, { 7, 11, 1549 }, { 7, 10, 1373 }, { 10, 11, 209 }, + { 7, 10, 554 }, { 7, 10, 605 }, { 13, 10, 10 }, { 5, 10, 838 }, + { 5, 10, 841 }, { 6, 10, 1649 }, { 5, 10, 1012 }, { 6, 0, 1357 }, + { 6, 0, 1380 }, { 16, 0, 53 }, { 6, 0, 590 }, { 7, 10, 365 }, + { 7, 10, 1357 }, { 7, 10, 1497 }, { 8, 10, 154 }, { 13, 10, 281 }, + { 5, 10, 340 }, { 4, 11, 420 }, { 7, 0, 329 }, { 19, 11, 32 }, + { 4, 0, 469 }, { 10, 11, 429 }, { 11, 10, 495 }, { 8, 10, 261 }, + { 9, 10, 144 }, { 9, 10, 466 }, { 10, 10, 370 }, { 12, 10, 470 }, + { 13, 10, 144 }, { 14, 10, 348 }, { 14, 0, 460 }, { 4, 11, 325 }, + { 9, 10, 897 }, { 10, 11, 125 }, { 6, 0, 1743 }, { 6, 10, 248 }, + { 9, 10, 546 }, { 10, 10, 535 }, { 11, 10, 681 }, { 13, 10, 135 }, + { 4, 0, 990 }, { 5, 0, 929 }, { 6, 0, 340 }, { 8, 0, 376 }, + { 8, 0, 807 }, { 8, 0, 963 }, { 8, 0, 980 }, { 10, 0, 1007 }, + { 6, 0, 1603 }, { 12, 0, 250 }, { 4, 11, 714 }, { 5, 11, 469 }, + { 6, 10, 567 }, { 8, 10, 445 }, { 5, 0, 218 }, { 7, 0, 1610 }, + { 8, 0, 646 }, { 10, 0, 83 }, { 11, 11, 138 }, { 12, 11, 40 }, + { 7, 0, 1512 }, { 7, 0, 1794 }, { 7, 11, 1216 }, { 11, 0, 0 }, + { 16, 0, 78 }, { 4, 11, 718 }, { 5, 0, 571 }, { 4, 0, 455 }, + { 6, 0, 1012 }, { 5, 11, 124 }, { 5, 11, 144 }, { 6, 11, 548 }, + { 7, 11, 15 }, { 7, 11, 153 }, { 9, 11, 629 }, { 14, 11, 10 }, + { 6, 11, 75 }, { 7, 11, 1531 }, { 8, 11, 416 }, { 9, 11, 240 }, + { 9, 11, 275 }, { 10, 11, 100 }, { 11, 11, 658 }, { 11, 11, 979 }, + { 12, 11, 86 }, { 13, 11, 468 }, { 14, 11, 66 }, { 14, 11, 207 }, + { 15, 11, 20 }, { 15, 11, 25 }, { 16, 11, 58 }, { 4, 10, 577 }, + { 5, 11, 141 }, { 5, 11, 915 }, { 6, 11, 1783 }, { 7, 11, 211 }, + { 7, 11, 698 }, { 7, 11, 1353 }, { 9, 11, 83 }, { 9, 11, 281 }, + { 10, 11, 376 }, { 10, 11, 431 }, { 11, 11, 543 }, { 12, 11, 664 }, + { 13, 11, 280 }, { 13, 11, 428 }, { 14, 11, 61 }, { 14, 11, 128 }, + { 17, 11, 52 }, { 17, 11, 81 }, { 6, 0, 161 }, { 7, 0, 372 }, + { 9, 0, 597 }, { 4, 0, 349 }, { 10, 11, 702 }, { 11, 11, 245 }, + { 6, 0, 524 }, { 6, 10, 174 }, { 6, 0, 432 }, { 9, 0, 751 }, + { 11, 0, 322 }, { 19, 11, 94 }, { 4, 11, 338 }, { 5, 11, 400 }, + { 5, 0, 468 }, { 10, 0, 325 }, { 11, 0, 856 }, { 12, 0, 345 }, + { 15, 0, 104 }, { 5, 0, 223 }, { 4, 0, 566 }, { 4, 11, 221 }, + { 5, 11, 659 }, { 5, 11, 989 }, { 7, 11, 697 }, { 7, 11, 1211 }, + { 10, 11, 284 }, { 7, 11, 1070 }, { 4, 0, 59 }, { 7, 0, 1394 }, + { 6, 0, 436 }, { 11, 0, 481 }, { 5, 10, 878 }, { 5, 10, 972 }, + { 4, 0, 48 }, { 5, 0, 271 }, { 7, 0, 953 }, { 5, 0, 610 }, + { 8, 0, 457 }, { 4, 0, 773 }, { 5, 0, 618 }, { 9, 0, 756 }, + { 5, 0, 755 }, { 7, 0, 1217 }, { 10, 11, 507 }, { 4, 10, 351 }, + { 4, 0, 197 }, { 15, 11, 78 }, { 4, 11, 188 }, { 7, 11, 805 }, + { 11, 11, 276 }, { 14, 11, 293 }, { 5, 11, 884 }, { 11, 11, 991 }, + { 4, 10, 286 }, { 10, 0, 259 }, { 10, 0, 428 }, { 7, 10, 438 }, + { 7, 10, 627 }, { 7, 10, 1516 }, { 8, 10, 40 }, { 9, 10, 56 }, + { 9, 10, 294 }, { 11, 10, 969 }, { 11, 10, 995 }, { 18, 10, 148 }, + { 4, 0, 356 }, { 5, 0, 217 }, { 5, 0, 492 }, { 5, 0, 656 }, + { 8, 0, 544 }, { 8, 11, 544 }, { 5, 0, 259 }, { 6, 0, 1230 }, + { 7, 0, 414 }, { 7, 0, 854 }, { 14, 0, 107 }, { 4, 0, 1007 }, + { 15, 0, 14 }, { 16, 0, 5 }, { 6, 0, 1580 }, { 4, 10, 738 }, + { 4, 11, 596 }, { 4, 0, 673 }, { 5, 10, 866 }, { 6, 0, 1843 }, + { 7, 11, 1847 }, { 4, 0, 165 }, { 7, 0, 1398 }, { 7, 0, 1829 }, + { 7, 11, 1634 }, { 19, 11, 65 }, { 6, 0, 885 }, { 6, 0, 1009 }, + { 9, 0, 809 }, { 5, 10, 116 }, { 4, 10, 457 }, { 8, 11, 770 }, + { 9, 0, 498 }, { 12, 0, 181 }, { 10, 11, 361 }, { 14, 11, 316 }, + { 6, 11, 595 }, { 5, 0, 9 }, { 7, 0, 297 }, { 7, 0, 966 }, + { 12, 0, 306 }, { 4, 11, 89 }, { 5, 11, 489 }, { 6, 11, 315 }, + { 7, 11, 553 }, { 7, 11, 1745 }, { 10, 11, 243 }, { 6, 0, 1487 }, + { 4, 0, 437 }, { 5, 0, 146 }, { 6, 0, 411 }, { 10, 0, 721 }, + { 5, 10, 527 }, { 6, 10, 189 }, { 7, 10, 859 }, { 11, 10, 104 }, + { 11, 10, 554 }, { 15, 10, 60 }, { 15, 10, 125 }, { 6, 11, 1658 }, + { 9, 11, 3 }, { 10, 11, 154 }, { 11, 11, 641 }, { 13, 11, 85 }, + { 13, 11, 201 }, { 13, 11, 346 }, { 6, 0, 177 }, { 7, 0, 467 }, + { 6, 0, 1377 }, { 6, 10, 116 }, { 8, 11, 645 }, { 4, 11, 166 }, + { 5, 11, 505 }, { 6, 11, 1670 }, { 9, 11, 110 }, { 5, 10, 487 }, + { 4, 10, 86 }, { 5, 10, 667 }, { 5, 10, 753 }, { 6, 10, 316 }, + { 6, 10, 455 }, { 7, 10, 946 }, { 5, 0, 200 }, { 4, 0, 959 }, + { 6, 0, 1928 }, { 6, 0, 1957 }, { 11, 11, 203 }, { 22, 10, 45 }, + { 4, 10, 79 }, { 7, 10, 1773 }, { 10, 10, 450 }, { 11, 10, 589 }, + { 13, 10, 332 }, { 13, 10, 493 }, { 14, 10, 183 }, { 14, 10, 334 }, + { 14, 10, 362 }, { 14, 10, 368 }, { 14, 10, 376 }, { 14, 10, 379 }, + { 19, 10, 90 }, { 19, 10, 103 }, { 19, 10, 127 }, { 20, 10, 90 }, + { 6, 0, 1435 }, { 7, 11, 1275 }, { 6, 0, 481 }, { 7, 11, 445 }, + { 8, 11, 307 }, { 8, 11, 704 }, { 10, 11, 41 }, { 10, 11, 439 }, + { 11, 11, 237 }, { 11, 11, 622 }, { 12, 11, 201 }, { 7, 11, 869 }, + { 4, 0, 84 }, { 7, 0, 1482 }, { 10, 0, 76 }, { 10, 0, 142 }, + { 11, 11, 277 }, { 16, 11, 14 }, { 7, 11, 1977 }, { 4, 11, 189 }, + { 5, 11, 713 }, { 8, 11, 57 }, { 5, 0, 1015 }, { 10, 11, 371 }, + { 4, 0, 315 }, { 5, 0, 507 }, { 7, 0, 1370 }, { 4, 11, 552 }, + { 14, 10, 381 }, { 9, 0, 759 }, { 16, 0, 31 }, { 16, 0, 39 }, + { 16, 0, 75 }, { 18, 0, 24 }, { 20, 0, 42 }, { 24, 0, 1 }, + { 6, 0, 712 }, { 6, 0, 1722 }, { 5, 10, 663 }, { 5, 10, 846 }, + { 8, 0, 222 }, { 8, 0, 476 }, { 9, 0, 238 }, { 11, 0, 516 }, + { 11, 0, 575 }, { 15, 0, 109 }, { 18, 0, 100 }, { 7, 0, 1402 }, + { 7, 0, 1414 }, { 12, 0, 456 }, { 5, 10, 378 }, { 8, 10, 465 }, + { 9, 10, 286 }, { 10, 10, 185 }, { 10, 10, 562 }, { 10, 10, 635 }, + { 11, 10, 31 }, { 11, 10, 393 }, { 13, 10, 312 }, { 18, 10, 65 }, + { 18, 10, 96 }, { 19, 10, 89 }, { 4, 0, 986 }, { 6, 0, 1958 }, + { 6, 0, 2032 }, { 8, 0, 934 }, { 10, 0, 985 }, { 7, 10, 1880 }, + { 9, 10, 680 }, { 11, 10, 798 }, { 6, 10, 1770 }, { 17, 11, 49 }, + { 4, 11, 614 }, { 4, 10, 648 }, { 5, 10, 945 }, { 6, 10, 1656 }, + { 6, 10, 1787 }, { 7, 10, 167 }, { 8, 10, 824 }, { 9, 10, 391 }, + { 10, 10, 375 }, { 11, 10, 185 }, { 10, 11, 661 }, { 7, 0, 1273 }, + { 7, 11, 1945 }, { 7, 0, 706 }, { 7, 0, 1058 }, { 10, 0, 538 }, + { 7, 10, 1645 }, { 8, 10, 352 }, { 9, 10, 249 }, { 4, 10, 152 }, + { 11, 0, 92 }, { 11, 0, 196 }, { 11, 0, 409 }, { 11, 0, 450 }, + { 11, 0, 666 }, { 11, 0, 777 }, { 12, 0, 262 }, { 13, 0, 385 }, + { 13, 0, 393 }, { 15, 0, 115 }, { 16, 0, 45 }, { 17, 0, 82 }, + { 5, 10, 1006 }, { 6, 0, 40 }, { 7, 0, 1781 }, { 9, 11, 614 }, + { 11, 11, 327 }, { 5, 10, 420 }, { 7, 10, 1449 }, { 7, 0, 431 }, + { 10, 0, 97 }, { 7, 10, 832 }, { 6, 0, 423 }, { 7, 0, 665 }, + { 7, 0, 1210 }, { 7, 0, 237 }, { 8, 0, 664 }, { 9, 0, 42 }, + { 9, 0, 266 }, { 9, 0, 380 }, { 9, 0, 645 }, { 10, 0, 177 }, + { 10, 0, 276 }, { 7, 0, 264 }, { 5, 10, 351 }, { 8, 0, 213 }, + { 5, 10, 40 }, { 7, 10, 598 }, { 7, 10, 1638 }, { 9, 10, 166 }, + { 9, 10, 640 }, { 9, 10, 685 }, { 9, 10, 773 }, { 11, 10, 215 }, + { 13, 10, 65 }, { 14, 10, 172 }, { 14, 10, 317 }, { 17, 10, 6 }, + { 5, 11, 84 }, { 6, 11, 163 }, { 8, 10, 60 }, { 9, 10, 343 }, + { 11, 10, 769 }, { 9, 0, 455 }, { 5, 11, 410 }, { 8, 0, 906 }, + { 12, 0, 700 }, { 12, 0, 706 }, { 12, 0, 729 }, { 21, 11, 33 }, + { 22, 11, 40 }, { 7, 10, 1951 }, { 8, 10, 765 }, { 8, 10, 772 }, + { 12, 10, 671 }, { 7, 10, 108 }, { 8, 10, 219 }, { 8, 10, 388 }, + { 9, 10, 639 }, { 9, 10, 775 }, { 11, 10, 275 }, { 12, 10, 464 }, + { 5, 11, 322 }, { 7, 11, 1941 }, { 8, 11, 186 }, { 9, 11, 262 }, + { 10, 11, 187 }, { 14, 11, 208 }, { 18, 11, 130 }, { 11, 0, 624 }, + { 8, 0, 574 }, { 5, 11, 227 }, { 12, 11, 29 }, { 7, 11, 1546 }, + { 11, 11, 299 }, { 14, 11, 407 }, { 5, 10, 15 }, { 6, 10, 56 }, + { 7, 10, 1758 }, { 8, 10, 500 }, { 9, 10, 730 }, { 11, 10, 331 }, + { 13, 10, 150 }, { 14, 10, 282 }, { 7, 11, 1395 }, { 8, 11, 486 }, + { 9, 11, 236 }, { 9, 11, 878 }, { 10, 11, 218 }, { 11, 11, 95 }, + { 19, 11, 17 }, { 19, 11, 31 }, { 7, 11, 2043 }, { 4, 0, 354 }, + { 18, 11, 4 }, { 12, 11, 80 }, { 7, 0, 1558 }, { 6, 10, 1886 }, + { 5, 10, 205 }, { 6, 10, 438 }, { 9, 10, 711 }, { 5, 11, 522 }, + { 5, 10, 534 }, { 7, 0, 235 }, { 7, 0, 1475 }, { 15, 0, 68 }, + { 18, 0, 120 }, { 9, 10, 691 }, { 4, 0, 942 }, { 6, 0, 1813 }, + { 8, 0, 917 }, { 10, 0, 884 }, { 12, 0, 696 }, { 12, 0, 717 }, + { 12, 0, 723 }, { 12, 0, 738 }, { 12, 0, 749 }, { 12, 0, 780 }, + { 16, 0, 97 }, { 18, 0, 169 }, { 6, 10, 443 }, { 8, 11, 562 }, + { 9, 10, 237 }, { 9, 10, 571 }, { 9, 10, 695 }, { 10, 10, 139 }, + { 11, 10, 715 }, { 12, 10, 417 }, { 13, 10, 421 }, { 7, 0, 957 }, + { 5, 0, 830 }, { 6, 11, 1771 }, { 18, 0, 23 }, { 5, 0, 496 }, + { 6, 0, 694 }, { 7, 0, 203 }, { 7, 11, 1190 }, { 9, 11, 620 }, + { 9, 11, 132 }, { 6, 0, 547 }, { 6, 0, 1549 }, { 8, 11, 258 }, + { 9, 11, 208 }, { 9, 11, 359 }, { 4, 0, 864 }, { 5, 0, 88 }, + { 9, 0, 239 }, { 7, 11, 493 }, { 4, 11, 317 }, { 7, 11, 1279 }, + { 4, 11, 477 }, { 4, 10, 578 }, { 5, 11, 63 }, { 5, 11, 509 }, + { 7, 0, 650 }, { 7, 0, 1310 }, { 7, 0, 1076 }, { 9, 0, 80 }, + { 11, 0, 78 }, { 11, 0, 421 }, { 11, 0, 534 }, { 12, 0, 545 }, + { 4, 11, 288 }, { 12, 0, 553 }, { 14, 0, 118 }, { 5, 10, 923 }, + { 7, 0, 274 }, { 11, 0, 479 }, { 11, 0, 507 }, { 8, 11, 89 }, + { 8, 11, 620 }, { 9, 11, 49 }, { 10, 11, 774 }, { 11, 11, 628 }, + { 12, 11, 322 }, { 15, 11, 124 }, { 4, 0, 497 }, { 7, 0, 1584 }, + { 7, 0, 261 }, { 7, 0, 1115 }, { 7, 0, 1354 }, { 7, 0, 1404 }, + { 7, 0, 1588 }, { 7, 0, 1705 }, { 7, 0, 1902 }, { 9, 0, 465 }, + { 10, 0, 248 }, { 10, 0, 349 }, { 10, 0, 647 }, { 11, 0, 527 }, + { 11, 0, 660 }, { 11, 0, 669 }, { 12, 0, 529 }, { 13, 0, 305 }, + { 4, 10, 924 }, { 5, 10, 665 }, { 8, 0, 13 }, { 6, 0, 791 }, + { 10, 11, 120 }, { 7, 0, 642 }, { 8, 0, 250 }, { 11, 0, 123 }, + { 11, 0, 137 }, { 13, 0, 48 }, { 14, 0, 95 }, { 4, 10, 265 }, + { 7, 10, 807 }, { 7, 10, 950 }, { 5, 10, 93 }, { 12, 10, 267 }, + { 7, 0, 1429 }, { 4, 0, 949 }, { 10, 0, 885 }, { 10, 0, 891 }, + { 10, 0, 900 }, { 10, 0, 939 }, { 12, 0, 760 }, { 14, 0, 449 }, + { 11, 11, 366 }, { 4, 0, 818 }, { 6, 11, 85 }, { 7, 10, 994 }, + { 7, 0, 330 }, { 5, 10, 233 }, { 5, 10, 320 }, { 6, 10, 140 }, + { 8, 10, 295 }, { 4, 0, 1004 }, { 8, 0, 982 }, { 8, 0, 993 }, + { 5, 10, 978 }, { 4, 10, 905 }, { 6, 10, 1701 }, { 9, 10, 843 }, + { 10, 0, 545 }, { 12, 0, 301 }, { 6, 0, 947 }, { 6, 0, 1062 }, + { 6, 0, 1188 }, { 4, 0, 904 }, { 5, 0, 794 }, { 24, 10, 6 }, + { 6, 0, 1372 }, { 7, 11, 608 }, { 5, 11, 279 }, { 6, 11, 235 }, + { 7, 11, 468 }, { 8, 11, 446 }, { 9, 11, 637 }, { 10, 11, 717 }, + { 11, 11, 738 }, { 12, 11, 514 }, { 4, 10, 509 }, { 5, 11, 17 }, + { 6, 11, 371 }, { 9, 11, 528 }, { 4, 0, 693 }, { 4, 11, 115 }, + { 5, 11, 669 }, { 6, 11, 407 }, { 8, 11, 311 }, { 11, 11, 10 }, + { 13, 11, 5 }, { 11, 0, 377 }, { 7, 10, 273 }, { 9, 11, 381 }, + { 7, 0, 695 }, { 7, 0, 386 }, { 10, 0, 713 }, { 7, 10, 1041 }, + { 6, 0, 1291 }, { 6, 0, 7 }, { 6, 0, 35 }, { 7, 0, 147 }, + { 7, 0, 1069 }, { 7, 0, 1568 }, { 7, 0, 1575 }, { 7, 0, 1917 }, + { 8, 0, 43 }, { 8, 0, 208 }, { 9, 0, 128 }, { 9, 0, 866 }, + { 10, 0, 20 }, { 11, 0, 981 }, { 19, 0, 33 }, { 7, 0, 893 }, + { 13, 0, 424 }, { 11, 10, 234 }, { 22, 11, 56 }, { 5, 11, 779 }, + { 5, 11, 807 }, { 6, 11, 1655 }, { 6, 11, 1676 }, { 5, 10, 802 }, + { 7, 10, 2021 }, { 8, 10, 805 }, { 4, 11, 196 }, { 5, 10, 167 }, + { 5, 11, 558 }, { 5, 10, 899 }, { 5, 11, 949 }, { 6, 10, 410 }, + { 9, 10, 777 }, { 9, 10, 789 }, { 6, 10, 1705 }, { 8, 0, 904 }, + { 12, 0, 787 }, { 6, 0, 322 }, { 9, 0, 552 }, { 11, 0, 274 }, + { 13, 0, 209 }, { 13, 0, 499 }, { 14, 0, 85 }, { 15, 0, 126 }, + { 17, 0, 70 }, { 7, 10, 10 }, { 5, 10, 11 }, { 6, 10, 117 }, + { 6, 10, 485 }, { 7, 10, 1133 }, { 9, 10, 582 }, { 9, 10, 594 }, + { 11, 10, 21 }, { 11, 10, 818 }, { 12, 10, 535 }, { 13, 10, 86 }, + { 4, 10, 264 }, { 7, 10, 1067 }, { 8, 10, 204 }, { 8, 10, 385 }, + { 11, 10, 953 }, { 4, 11, 752 }, { 10, 10, 56 }, { 5, 10, 470 }, + { 6, 0, 1808 }, { 8, 0, 83 }, { 8, 0, 742 }, { 8, 0, 817 }, + { 9, 0, 28 }, { 9, 0, 29 }, { 9, 0, 885 }, { 10, 0, 387 }, + { 11, 0, 633 }, { 11, 0, 740 }, { 13, 0, 235 }, { 13, 0, 254 }, + { 15, 0, 143 }, { 15, 0, 146 }, { 12, 0, 49 }, { 6, 0, 1832 }, + { 4, 11, 227 }, { 5, 11, 159 }, { 5, 11, 409 }, { 7, 11, 80 }, + { 10, 11, 294 }, { 10, 11, 479 }, { 12, 11, 418 }, { 14, 11, 50 }, + { 14, 11, 249 }, { 14, 11, 295 }, { 7, 11, 1470 }, { 8, 11, 66 }, + { 8, 11, 137 }, { 8, 11, 761 }, { 9, 11, 638 }, { 11, 11, 80 }, + { 11, 11, 212 }, { 11, 11, 368 }, { 11, 11, 418 }, { 12, 11, 8 }, + { 13, 11, 15 }, { 16, 11, 61 }, { 17, 11, 59 }, { 19, 11, 28 }, + { 20, 11, 84 }, { 11, 10, 1015 }, { 10, 11, 468 }, { 7, 0, 421 }, + { 6, 0, 415 }, { 7, 0, 1049 }, { 9, 0, 442 }, { 6, 11, 38 }, + { 7, 11, 1220 }, { 8, 11, 185 }, { 8, 11, 256 }, { 9, 11, 22 }, + { 9, 11, 331 }, { 10, 11, 738 }, { 11, 11, 205 }, { 11, 11, 540 }, + { 11, 11, 746 }, { 13, 11, 399 }, { 13, 11, 465 }, { 14, 11, 88 }, + { 14, 11, 194 }, { 11, 0, 289 }, { 5, 10, 715 }, { 4, 0, 110 }, + { 10, 0, 415 }, { 10, 0, 597 }, { 14, 0, 206 }, { 4, 11, 159 }, + { 6, 11, 115 }, { 7, 11, 252 }, { 7, 11, 257 }, { 7, 11, 1928 }, + { 8, 11, 69 }, { 9, 11, 384 }, { 10, 11, 91 }, { 10, 11, 615 }, + { 12, 11, 375 }, { 14, 11, 235 }, { 18, 11, 117 }, { 19, 11, 123 }, + { 5, 11, 911 }, { 8, 11, 278 }, { 7, 0, 205 }, { 7, 0, 2000 }, + { 8, 10, 794 }, { 9, 10, 400 }, { 10, 10, 298 }, { 14, 10, 228 }, + { 7, 11, 1774 }, { 4, 11, 151 }, { 7, 11, 1567 }, { 8, 11, 351 }, + { 9, 11, 322 }, { 8, 10, 724 }, { 5, 11, 990 }, { 7, 0, 1539 }, + { 11, 0, 512 }, { 13, 0, 205 }, { 19, 0, 30 }, { 22, 0, 36 }, + { 23, 0, 19 }, { 7, 11, 1539 }, { 5, 11, 194 }, { 7, 11, 1662 }, + { 9, 11, 90 }, { 12, 11, 180 }, { 6, 10, 190 }, { 7, 10, 768 }, + { 7, 10, 1170 }, { 6, 0, 1340 }, { 4, 0, 283 }, { 7, 0, 1194 }, + { 5, 11, 425 }, { 5, 11, 971 }, { 12, 0, 549 }, { 14, 10, 67 }, + { 19, 10, 60 }, { 7, 10, 1023 }, { 6, 0, 1720 }, { 10, 11, 587 }, + { 5, 11, 72 }, { 6, 11, 264 }, { 7, 11, 21 }, { 7, 11, 46 }, + { 7, 11, 2013 }, { 8, 11, 215 }, { 8, 11, 513 }, { 10, 11, 266 }, + { 11, 11, 22 }, { 5, 0, 319 }, { 7, 0, 534 }, { 6, 10, 137 }, + { 9, 10, 75 }, { 9, 10, 253 }, { 10, 10, 194 }, { 10, 10, 444 }, + { 7, 0, 1180 }, { 20, 0, 112 }, { 6, 11, 239 }, { 7, 11, 118 }, + { 10, 11, 95 }, { 11, 11, 603 }, { 13, 11, 443 }, { 14, 11, 160 }, + { 15, 11, 4 }, { 6, 11, 431 }, { 5, 11, 874 }, { 6, 11, 1677 }, + { 11, 10, 643 }, { 12, 10, 115 }, { 15, 11, 0 }, { 6, 0, 967 }, + { 6, 11, 65 }, { 7, 11, 939 }, { 7, 11, 1172 }, { 7, 11, 1671 }, + { 9, 11, 540 }, { 10, 11, 696 }, { 11, 11, 265 }, { 11, 11, 732 }, + { 11, 11, 928 }, { 11, 11, 937 }, { 12, 11, 399 }, { 13, 11, 438 }, + { 21, 11, 19 }, { 9, 11, 200 }, { 7, 0, 1940 }, { 5, 10, 760 }, + { 7, 10, 542 }, { 8, 10, 135 }, { 8, 10, 496 }, { 12, 11, 44 }, + { 7, 11, 1655 }, { 8, 11, 305 }, { 7, 10, 319 }, { 7, 10, 355 }, + { 7, 10, 763 }, { 10, 10, 389 }, { 17, 10, 43 }, { 8, 0, 735 }, + { 10, 10, 786 }, { 9, 11, 19 }, { 4, 11, 696 }, { 5, 0, 132 }, + { 9, 0, 486 }, { 9, 0, 715 }, { 10, 0, 458 }, { 11, 0, 373 }, + { 11, 0, 668 }, { 11, 0, 795 }, { 11, 0, 897 }, { 12, 0, 272 }, + { 12, 0, 424 }, { 12, 0, 539 }, { 12, 0, 558 }, { 14, 0, 245 }, + { 14, 0, 263 }, { 14, 0, 264 }, { 14, 0, 393 }, { 14, 0, 403 }, + { 10, 0, 38 }, { 11, 0, 784 }, { 4, 0, 838 }, { 4, 11, 302 }, + { 7, 11, 1766 }, { 5, 0, 379 }, { 5, 0, 8 }, { 6, 0, 89 }, + { 6, 0, 400 }, { 7, 0, 1569 }, { 7, 0, 1623 }, { 7, 0, 1850 }, + { 8, 0, 218 }, { 8, 0, 422 }, { 9, 0, 570 }, { 10, 0, 626 }, + { 4, 11, 726 }, { 5, 11, 630 }, { 4, 0, 1017 }, { 10, 0, 660 }, + { 6, 0, 387 }, { 7, 0, 882 }, { 13, 0, 111 }, { 6, 0, 224 }, + { 7, 0, 877 }, { 9, 0, 647 }, { 4, 10, 58 }, { 5, 10, 286 }, + { 6, 10, 319 }, { 7, 10, 402 }, { 7, 10, 1254 }, { 7, 10, 1903 }, + { 8, 10, 356 }, { 12, 10, 408 }, { 7, 0, 790 }, { 9, 0, 510 }, + { 10, 0, 53 }, { 4, 10, 389 }, { 9, 10, 181 }, { 10, 10, 29 }, + { 10, 10, 816 }, { 11, 10, 311 }, { 11, 10, 561 }, { 12, 10, 67 }, + { 13, 10, 181 }, { 14, 0, 458 }, { 6, 11, 118 }, { 7, 11, 215 }, + { 7, 11, 1521 }, { 12, 11, 11 }, { 6, 0, 954 }, { 7, 0, 394 }, + { 6, 0, 1367 }, { 5, 11, 225 }, { 5, 10, 373 }, { 4, 0, 882 }, + { 7, 0, 1409 }, { 7, 10, 1972 }, { 7, 10, 1793 }, { 4, 11, 370 }, + { 5, 11, 756 }, { 7, 11, 1326 }, { 22, 11, 13 }, { 7, 11, 354 }, + { 10, 11, 410 }, { 11, 11, 815 }, { 6, 11, 1662 }, { 7, 11, 48 }, + { 8, 11, 771 }, { 10, 11, 116 }, { 13, 11, 104 }, { 14, 11, 105 }, + { 14, 11, 184 }, { 15, 11, 168 }, { 19, 11, 92 }, { 20, 11, 68 }, + { 7, 0, 124 }, { 8, 0, 38 }, { 5, 0, 261 }, { 7, 0, 78 }, + { 7, 0, 199 }, { 8, 0, 815 }, { 9, 0, 126 }, { 10, 0, 342 }, + { 12, 0, 647 }, { 4, 0, 628 }, { 12, 0, 724 }, { 7, 0, 266 }, + { 8, 0, 804 }, { 7, 10, 1651 }, { 17, 10, 89 }, { 7, 0, 208 }, + { 6, 0, 1178 }, { 6, 0, 79 }, { 7, 0, 1519 }, { 4, 10, 672 }, + { 5, 10, 737 }, { 8, 0, 741 }, { 4, 11, 120 }, { 4, 0, 710 }, + { 6, 0, 376 }, { 6, 0, 606 }, { 6, 0, 1347 }, { 6, 0, 1494 }, + { 6, 0, 850 }, { 6, 0, 1553 }, { 9, 0, 821 }, { 5, 10, 145 }, + { 6, 11, 593 }, { 7, 0, 1311 }, { 12, 0, 135 }, { 4, 0, 467 }, + { 5, 0, 405 }, { 6, 0, 544 }, { 5, 11, 820 }, { 7, 11, 931 }, + { 6, 0, 100 }, { 7, 0, 244 }, { 7, 0, 632 }, { 7, 0, 1609 }, + { 8, 0, 178 }, { 8, 0, 638 }, { 13, 0, 58 }, { 4, 10, 387 }, + { 7, 10, 1288 }, { 6, 11, 151 }, { 6, 11, 1675 }, { 7, 11, 383 }, + { 23, 11, 10 }, { 4, 0, 481 }, { 7, 10, 550 }, { 6, 0, 1378 }, + { 6, 11, 1624 }, { 11, 11, 11 }, { 12, 11, 422 }, { 13, 11, 262 }, + { 14, 11, 360 }, { 5, 0, 791 }, { 4, 11, 43 }, { 5, 11, 344 }, + { 5, 11, 357 }, { 7, 0, 1227 }, { 12, 0, 978 }, { 7, 0, 686 }, + { 8, 0, 33 }, { 8, 0, 238 }, { 10, 0, 616 }, { 11, 0, 467 }, + { 11, 0, 881 }, { 13, 0, 217 }, { 13, 0, 253 }, { 14, 0, 268 }, + { 9, 0, 857 }, { 8, 0, 467 }, { 8, 0, 1006 }, { 7, 11, 148 }, + { 8, 11, 284 }, { 13, 11, 63 }, { 4, 10, 576 }, { 7, 10, 1263 }, + { 5, 11, 888 }, { 5, 10, 919 }, { 6, 10, 1673 }, { 20, 10, 37 }, + { 20, 11, 37 }, { 4, 0, 447 }, { 4, 11, 711 }, { 4, 0, 128 }, + { 5, 0, 415 }, { 6, 0, 462 }, { 7, 0, 294 }, { 7, 0, 578 }, + { 10, 0, 710 }, { 11, 0, 86 }, { 4, 10, 82 }, { 5, 10, 333 }, + { 5, 10, 904 }, { 6, 10, 207 }, { 7, 10, 325 }, { 7, 10, 1726 }, + { 8, 10, 101 }, { 10, 10, 778 }, { 11, 10, 220 }, { 8, 0, 587 }, + { 9, 11, 440 }, { 5, 10, 903 }, { 6, 0, 427 }, { 7, 0, 1018 }, + { 10, 0, 692 }, { 4, 0, 195 }, { 7, 0, 802 }, { 12, 10, 147 }, + { 6, 0, 1546 }, { 6, 0, 684 }, { 4, 10, 705 }, { 8, 0, 345 }, + { 11, 11, 678 }, { 12, 11, 307 }, { 5, 0, 365 }, { 6, 0, 1683 }, + { 4, 11, 65 }, { 5, 11, 479 }, { 5, 11, 1004 }, { 7, 11, 1913 }, + { 8, 11, 317 }, { 9, 11, 302 }, { 10, 11, 612 }, { 13, 11, 22 }, + { 10, 0, 472 }, { 4, 11, 261 }, { 7, 11, 510 }, { 6, 10, 90 }, + { 14, 0, 433 }, { 23, 0, 28 }, { 4, 11, 291 }, { 7, 11, 101 }, + { 9, 11, 515 }, { 12, 11, 152 }, { 12, 11, 443 }, { 13, 11, 392 }, + { 14, 11, 357 }, { 12, 0, 997 }, { 5, 0, 3 }, { 8, 0, 578 }, + { 9, 0, 118 }, { 10, 0, 705 }, { 13, 0, 279 }, { 7, 11, 1266 }, + { 7, 10, 813 }, { 12, 10, 497 }, { 13, 10, 56 }, { 5, 0, 229 }, + { 6, 10, 125 }, { 7, 10, 1277 }, { 8, 0, 102 }, { 10, 0, 578 }, + { 10, 0, 672 }, { 12, 0, 496 }, { 13, 0, 408 }, { 14, 0, 121 }, + { 17, 0, 106 }, { 23, 10, 12 }, { 6, 0, 866 }, { 6, 0, 1080 }, + { 8, 0, 1022 }, { 4, 11, 130 }, { 7, 11, 843 }, { 5, 11, 42 }, + { 5, 11, 879 }, { 7, 11, 245 }, { 7, 11, 324 }, { 7, 11, 1532 }, + { 11, 11, 463 }, { 11, 11, 472 }, { 13, 11, 363 }, { 16, 11, 52 }, + { 22, 0, 55 }, { 8, 0, 115 }, { 8, 0, 350 }, { 9, 0, 489 }, + { 10, 0, 128 }, { 11, 0, 306 }, { 12, 0, 373 }, { 14, 0, 30 }, + { 17, 0, 79 }, { 19, 0, 80 }, { 4, 11, 134 }, { 5, 11, 372 }, + { 6, 0, 657 }, { 6, 0, 933 }, { 7, 11, 1147 }, { 4, 0, 230 }, + { 5, 0, 702 }, { 6, 0, 1728 }, { 4, 0, 484 }, { 18, 0, 26 }, + { 19, 0, 42 }, { 20, 0, 43 }, { 21, 0, 0 }, { 23, 0, 27 }, + { 24, 0, 14 }, { 7, 0, 185 }, { 7, 0, 703 }, { 6, 0, 417 }, + { 10, 0, 618 }, { 7, 10, 1106 }, { 9, 10, 770 }, { 11, 10, 112 }, + { 12, 10, 413 }, { 6, 0, 803 }, { 4, 11, 644 }, { 6, 0, 1262 }, + { 7, 11, 540 }, { 12, 10, 271 }, { 17, 10, 109 }, { 7, 11, 123 }, + { 4, 0, 633 }, { 6, 11, 623 }, { 4, 11, 908 }, { 5, 11, 359 }, + { 5, 11, 508 }, { 6, 11, 1723 }, { 7, 11, 343 }, { 7, 11, 1996 }, + { 7, 11, 2026 }, { 7, 0, 479 }, { 10, 0, 262 }, { 7, 10, 304 }, + { 9, 10, 646 }, { 9, 10, 862 }, { 11, 10, 696 }, { 12, 10, 208 }, + { 15, 10, 79 }, { 19, 10, 108 }, { 4, 11, 341 }, { 7, 11, 480 }, + { 6, 0, 830 }, { 5, 0, 70 }, { 5, 0, 622 }, { 6, 0, 334 }, + { 7, 0, 1032 }, { 9, 0, 171 }, { 11, 0, 26 }, { 11, 0, 213 }, + { 11, 0, 637 }, { 11, 0, 707 }, { 12, 0, 202 }, { 12, 0, 380 }, + { 13, 0, 226 }, { 13, 0, 355 }, { 14, 0, 222 }, { 17, 0, 42 }, + { 7, 10, 981 }, { 15, 0, 217 }, { 9, 11, 114 }, { 4, 0, 23 }, + { 4, 0, 141 }, { 5, 0, 313 }, { 5, 0, 1014 }, { 6, 0, 50 }, + { 6, 0, 51 }, { 7, 0, 142 }, { 7, 0, 384 }, { 7, 0, 559 }, + { 8, 0, 640 }, { 9, 0, 460 }, { 9, 0, 783 }, { 11, 0, 741 }, + { 12, 0, 183 }, { 13, 0, 488 }, { 13, 0, 360 }, { 7, 0, 1586 }, + { 7, 11, 1995 }, { 8, 11, 299 }, { 11, 11, 890 }, { 12, 11, 674 }, + { 4, 10, 434 }, { 7, 0, 652 }, { 6, 10, 550 }, { 7, 0, 766 }, + { 5, 10, 553 }, { 10, 10, 824 }, { 7, 0, 737 }, { 8, 0, 298 }, + { 8, 10, 452 }, { 4, 11, 238 }, { 5, 11, 503 }, { 6, 11, 179 }, + { 7, 11, 2003 }, { 8, 11, 381 }, { 8, 11, 473 }, { 9, 11, 149 }, + { 10, 11, 183 }, { 15, 11, 45 }, { 15, 11, 86 }, { 5, 10, 292 }, + { 5, 0, 222 }, { 9, 0, 655 }, { 10, 0, 534 }, { 10, 10, 135 }, + { 4, 11, 121 }, { 5, 11, 156 }, { 5, 11, 349 }, { 9, 11, 136 }, + { 10, 11, 605 }, { 14, 11, 342 }, { 19, 11, 107 }, { 9, 0, 906 }, + { 6, 0, 1013 }, { 6, 0, 1250 }, { 6, 0, 1956 }, { 6, 0, 2009 }, + { 8, 0, 991 }, { 16, 0, 120 }, { 7, 11, 1192 }, { 10, 0, 503 }, + { 5, 0, 154 }, { 7, 0, 1491 }, { 10, 0, 379 }, { 10, 0, 485 }, + { 6, 0, 1867 }, { 6, 0, 1914 }, { 6, 0, 1925 }, { 9, 0, 917 }, + { 9, 0, 925 }, { 9, 0, 932 }, { 9, 0, 951 }, { 9, 0, 1007 }, + { 9, 0, 1013 }, { 12, 0, 806 }, { 12, 0, 810 }, { 12, 0, 814 }, + { 12, 0, 816 }, { 12, 0, 824 }, { 12, 0, 832 }, { 12, 0, 837 }, + { 12, 0, 863 }, { 12, 0, 868 }, { 12, 0, 870 }, { 12, 0, 889 }, + { 12, 0, 892 }, { 12, 0, 900 }, { 12, 0, 902 }, { 12, 0, 908 }, + { 12, 0, 933 }, { 12, 0, 942 }, { 12, 0, 949 }, { 12, 0, 954 }, + { 15, 0, 175 }, { 15, 0, 203 }, { 15, 0, 213 }, { 15, 0, 218 }, + { 15, 0, 225 }, { 15, 0, 231 }, { 15, 0, 239 }, { 15, 0, 248 }, + { 15, 0, 252 }, { 18, 0, 190 }, { 18, 0, 204 }, { 18, 0, 215 }, + { 18, 0, 216 }, { 18, 0, 222 }, { 18, 0, 225 }, { 18, 0, 230 }, + { 18, 0, 239 }, { 18, 0, 241 }, { 21, 0, 42 }, { 21, 0, 43 }, + { 21, 0, 44 }, { 21, 0, 45 }, { 21, 0, 46 }, { 21, 0, 53 }, + { 24, 0, 27 }, { 24, 0, 31 }, { 5, 0, 716 }, { 7, 0, 844 }, + { 4, 0, 91 }, { 5, 0, 388 }, { 5, 0, 845 }, { 6, 0, 206 }, + { 6, 0, 252 }, { 6, 0, 365 }, { 7, 0, 136 }, { 7, 0, 531 }, + { 8, 0, 621 }, { 7, 10, 393 }, { 10, 10, 603 }, { 11, 10, 206 }, + { 6, 11, 80 }, { 6, 11, 1694 }, { 7, 11, 173 }, { 7, 11, 1974 }, + { 9, 11, 547 }, { 10, 11, 730 }, { 14, 11, 18 }, { 22, 11, 39 }, + { 9, 0, 748 }, { 4, 11, 923 }, { 6, 11, 1711 }, { 4, 10, 912 }, + { 9, 10, 232 }, { 7, 10, 98 }, { 7, 10, 1973 }, { 8, 10, 716 }, + { 14, 0, 103 }, { 5, 10, 733 }, { 4, 11, 595 }, { 12, 0, 158 }, + { 18, 0, 8 }, { 19, 0, 62 }, { 20, 0, 6 }, { 22, 0, 4 }, + { 23, 0, 2 }, { 23, 0, 9 }, { 5, 11, 240 }, { 6, 11, 459 }, + { 7, 11, 12 }, { 7, 11, 114 }, { 7, 11, 502 }, { 7, 11, 1751 }, + { 7, 11, 1753 }, { 7, 11, 1805 }, { 8, 11, 658 }, { 9, 11, 1 }, + { 11, 11, 959 }, { 13, 11, 446 }, { 14, 11, 211 }, { 7, 0, 576 }, + { 5, 0, 771 }, { 5, 0, 863 }, { 5, 0, 898 }, { 6, 0, 648 }, + { 6, 0, 1632 }, { 6, 0, 1644 }, { 6, 0, 1780 }, { 5, 0, 331 }, + { 7, 11, 633 }, { 7, 11, 905 }, { 7, 11, 909 }, { 7, 11, 1538 }, + { 9, 11, 767 }, { 12, 11, 636 }, { 12, 0, 632 }, { 5, 0, 107 }, + { 7, 0, 201 }, { 8, 0, 518 }, { 6, 0, 446 }, { 7, 0, 1817 }, + { 6, 11, 490 }, { 9, 0, 851 }, { 13, 0, 510 }, { 7, 11, 250 }, + { 8, 11, 506 }, { 8, 11, 507 }, { 4, 0, 504 }, { 9, 10, 72 }, + { 4, 11, 158 }, { 4, 11, 140 }, { 7, 11, 362 }, { 8, 11, 209 }, + { 9, 11, 10 }, { 9, 11, 160 }, { 9, 11, 503 }, { 10, 11, 689 }, + { 11, 11, 350 }, { 11, 11, 553 }, { 11, 11, 725 }, { 12, 11, 252 }, + { 12, 11, 583 }, { 13, 11, 192 }, { 13, 11, 352 }, { 14, 11, 269 }, + { 14, 11, 356 }, { 20, 11, 50 }, { 6, 11, 597 }, { 7, 11, 1318 }, + { 7, 10, 1454 }, { 5, 0, 883 }, { 5, 0, 975 }, { 8, 0, 392 }, + { 20, 0, 7 }, { 6, 11, 228 }, { 7, 11, 1341 }, { 9, 11, 408 }, + { 10, 11, 343 }, { 11, 11, 348 }, { 11, 10, 600 }, { 12, 11, 99 }, + { 13, 10, 245 }, { 18, 11, 1 }, { 18, 11, 11 }, { 19, 11, 4 }, + { 6, 11, 296 }, { 5, 0, 922 }, { 6, 0, 1707 }, { 4, 11, 557 }, + { 4, 11, 548 }, { 7, 10, 164 }, { 7, 10, 1571 }, { 9, 10, 107 }, + { 12, 10, 225 }, { 7, 11, 197 }, { 8, 11, 142 }, { 8, 11, 325 }, + { 9, 11, 150 }, { 9, 11, 596 }, { 10, 11, 350 }, { 10, 11, 353 }, + { 11, 11, 74 }, { 11, 11, 315 }, { 14, 11, 423 }, { 15, 11, 141 }, + { 5, 0, 993 }, { 7, 0, 515 }, { 9, 0, 91 }, { 4, 0, 131 }, + { 8, 0, 200 }, { 5, 10, 484 }, { 5, 10, 510 }, { 6, 10, 434 }, + { 7, 10, 1000 }, { 7, 10, 1098 }, { 8, 10, 2 }, { 24, 0, 10 }, + { 4, 11, 62 }, { 5, 11, 83 }, { 6, 11, 399 }, { 6, 11, 579 }, + { 7, 11, 692 }, { 7, 11, 846 }, { 7, 11, 1015 }, { 7, 11, 1799 }, + { 8, 11, 403 }, { 9, 11, 394 }, { 10, 11, 133 }, { 12, 11, 4 }, + { 12, 11, 297 }, { 12, 11, 452 }, { 16, 11, 81 }, { 18, 11, 19 }, + { 18, 11, 25 }, { 21, 11, 14 }, { 22, 11, 12 }, { 23, 11, 18 }, + { 12, 11, 459 }, { 4, 11, 177 }, { 7, 0, 1433 }, { 9, 0, 365 }, + { 9, 11, 365 }, { 4, 10, 460 }, { 5, 0, 103 }, { 6, 0, 2004 }, + { 7, 0, 921 }, { 8, 0, 580 }, { 8, 0, 593 }, { 8, 0, 630 }, + { 10, 0, 28 }, { 5, 11, 411 }, { 7, 11, 653 }, { 4, 10, 932 }, + { 5, 10, 891 }, { 4, 0, 911 }, { 5, 0, 867 }, { 5, 0, 1013 }, + { 7, 0, 2034 }, { 8, 0, 798 }, { 8, 0, 813 }, { 7, 11, 439 }, + { 10, 11, 727 }, { 11, 11, 260 }, { 11, 11, 684 }, { 8, 10, 625 }, + { 5, 11, 208 }, { 7, 11, 753 }, { 7, 11, 1528 }, { 5, 0, 461 }, + { 7, 0, 1925 }, { 12, 0, 39 }, { 13, 0, 265 }, { 13, 0, 439 }, + { 6, 10, 76 }, { 6, 0, 853 }, { 8, 10, 92 }, { 9, 10, 221 }, + { 5, 0, 135 }, { 6, 0, 519 }, { 7, 0, 1722 }, { 10, 0, 271 }, + { 11, 0, 261 }, { 17, 0, 54 }, { 11, 11, 814 }, { 14, 0, 338 }, + { 20, 0, 81 }, { 4, 0, 300 }, { 5, 0, 436 }, { 5, 0, 419 }, + { 5, 0, 687 }, { 7, 0, 864 }, { 9, 0, 470 }, { 7, 11, 864 }, + { 9, 0, 836 }, { 5, 11, 242 }, { 6, 0, 1937 }, { 4, 10, 763 }, + { 5, 11, 953 }, { 4, 10, 622 }, { 4, 0, 393 }, { 5, 10, 253 }, + { 8, 0, 357 }, { 10, 0, 745 }, { 14, 0, 426 }, { 17, 0, 94 }, + { 19, 0, 57 }, { 7, 10, 546 }, { 5, 11, 615 }, { 18, 11, 37 }, + { 9, 10, 73 }, { 10, 10, 110 }, { 14, 10, 185 }, { 17, 10, 119 }, + { 11, 0, 703 }, { 7, 10, 624 }, { 7, 10, 916 }, { 10, 10, 256 }, + { 11, 10, 87 }, { 5, 11, 290 }, { 5, 10, 212 }, { 12, 10, 35 }, + { 13, 10, 382 }, { 4, 11, 380 }, { 5, 11, 52 }, { 7, 11, 277 }, + { 9, 11, 368 }, { 11, 11, 791 }, { 5, 0, 387 }, { 10, 11, 138 }, + { 11, 11, 476 }, { 4, 0, 6 }, { 5, 0, 708 }, { 8, 0, 75 }, + { 7, 0, 1351 }, { 9, 0, 581 }, { 10, 0, 639 }, { 11, 0, 453 }, + { 12, 0, 584 }, { 4, 0, 303 }, { 10, 0, 772 }, { 7, 10, 1175 }, + { 4, 0, 749 }, { 5, 10, 816 }, { 6, 11, 256 }, { 7, 11, 307 }, + { 7, 11, 999 }, { 7, 11, 1481 }, { 7, 11, 1732 }, { 7, 11, 1738 }, + { 8, 11, 265 }, { 9, 11, 414 }, { 11, 11, 316 }, { 12, 11, 52 }, + { 13, 11, 420 }, { 19, 11, 100 }, { 7, 11, 1296 }, { 6, 0, 1065 }, + { 5, 10, 869 }, { 5, 10, 968 }, { 6, 10, 1626 }, { 8, 10, 734 }, + { 8, 10, 784 }, { 4, 10, 542 }, { 6, 10, 1716 }, { 6, 10, 1727 }, + { 7, 10, 1082 }, { 7, 10, 1545 }, { 8, 10, 56 }, { 8, 10, 118 }, + { 8, 10, 412 }, { 8, 10, 564 }, { 9, 10, 888 }, { 9, 10, 908 }, + { 10, 10, 50 }, { 10, 10, 423 }, { 11, 10, 685 }, { 11, 10, 697 }, + { 11, 10, 933 }, { 12, 10, 299 }, { 13, 10, 126 }, { 13, 10, 136 }, + { 13, 10, 170 }, { 13, 10, 190 }, { 6, 0, 226 }, { 4, 0, 106 }, + { 7, 0, 310 }, { 11, 0, 717 }, { 5, 11, 723 }, { 5, 0, 890 }, + { 5, 0, 988 }, { 4, 10, 232 }, { 9, 10, 202 }, { 10, 10, 474 }, + { 12, 10, 433 }, { 6, 0, 626 }, { 14, 0, 431 }, { 10, 0, 706 }, + { 22, 0, 44 }, { 13, 0, 51 }, { 6, 10, 108 }, { 7, 10, 1003 }, + { 7, 10, 1181 }, { 8, 10, 111 }, { 8, 10, 343 }, { 4, 0, 698 }, + { 5, 11, 109 }, { 6, 11, 1784 }, { 7, 11, 1895 }, { 12, 11, 296 }, + { 12, 11, 302 }, { 6, 0, 828 }, { 6, 10, 1712 }, { 10, 0, 17 }, + { 7, 0, 1929 }, { 4, 10, 133 }, { 5, 11, 216 }, { 7, 10, 711 }, + { 7, 10, 1298 }, { 7, 10, 1585 }, { 7, 11, 1879 }, { 9, 11, 141 }, + { 9, 11, 270 }, { 9, 11, 679 }, { 10, 11, 159 }, { 10, 11, 553 }, + { 11, 11, 197 }, { 11, 11, 438 }, { 12, 11, 538 }, { 12, 11, 559 }, + { 13, 11, 193 }, { 13, 11, 423 }, { 14, 11, 144 }, { 14, 11, 166 }, + { 14, 11, 167 }, { 15, 11, 67 }, { 19, 11, 84 }, { 13, 11, 127 }, + { 7, 11, 1872 }, { 9, 11, 81 }, { 6, 10, 99 }, { 7, 10, 1808 }, + { 17, 10, 57 }, { 6, 11, 391 }, { 5, 0, 689 }, { 6, 0, 84 }, + { 7, 0, 1250 }, { 6, 10, 574 }, { 7, 10, 428 }, { 10, 10, 669 }, + { 11, 10, 485 }, { 11, 10, 840 }, { 12, 10, 300 }, { 14, 10, 250 }, + { 7, 11, 322 }, { 8, 11, 249 }, { 7, 11, 432 }, { 7, 11, 1649 }, + { 7, 10, 1871 }, { 9, 10, 252 }, { 6, 11, 155 }, { 12, 11, 234 }, + { 7, 0, 871 }, { 19, 0, 27 }, { 19, 11, 27 }, { 12, 0, 498 }, + { 5, 0, 986 }, { 6, 0, 130 }, { 10, 0, 823 }, { 6, 0, 1793 }, + { 7, 0, 1582 }, { 8, 0, 458 }, { 10, 0, 101 }, { 10, 0, 318 }, + { 10, 0, 945 }, { 12, 0, 734 }, { 16, 0, 104 }, { 18, 0, 177 }, + { 6, 10, 323 }, { 7, 10, 1564 }, { 5, 11, 632 }, { 10, 11, 526 }, + { 10, 0, 435 }, { 7, 10, 461 }, { 8, 10, 775 }, { 6, 11, 144 }, + { 7, 11, 948 }, { 7, 11, 1042 }, { 7, 11, 1857 }, { 8, 11, 235 }, + { 8, 11, 461 }, { 9, 11, 453 }, { 9, 11, 530 }, { 10, 11, 354 }, + { 17, 11, 77 }, { 19, 11, 99 }, { 20, 11, 79 }, { 10, 0, 966 }, + { 7, 0, 1644 }, { 9, 0, 129 }, { 7, 0, 997 }, { 8, 0, 502 }, + { 5, 11, 196 }, { 6, 11, 486 }, { 7, 11, 212 }, { 8, 11, 309 }, + { 8, 11, 346 }, { 7, 10, 727 }, { 18, 10, 73 }, { 4, 0, 823 }, + { 4, 11, 686 }, { 7, 0, 1927 }, { 4, 0, 762 }, { 7, 0, 1756 }, + { 9, 0, 98 }, { 8, 10, 577 }, { 24, 0, 8 }, { 4, 11, 30 }, + { 5, 11, 43 }, { 24, 11, 8 }, { 7, 0, 1046 }, { 11, 0, 160 }, + { 7, 0, 492 }, { 4, 10, 413 }, { 5, 10, 677 }, { 7, 11, 492 }, + { 8, 10, 432 }, { 12, 10, 280 }, { 6, 0, 45 }, { 7, 0, 433 }, + { 8, 0, 129 }, { 9, 0, 21 }, { 10, 0, 392 }, { 11, 0, 79 }, + { 12, 0, 499 }, { 13, 0, 199 }, { 13, 0, 451 }, { 7, 0, 558 }, + { 8, 0, 353 }, { 4, 11, 220 }, { 7, 11, 1535 }, { 9, 11, 93 }, + { 11, 11, 474 }, { 7, 10, 646 }, { 7, 10, 1730 }, { 11, 10, 446 }, + { 13, 10, 178 }, { 5, 0, 785 }, { 6, 0, 1145 }, { 8, 0, 81 }, + { 9, 0, 189 }, { 9, 0, 201 }, { 11, 0, 478 }, { 11, 0, 712 }, + { 13, 0, 338 }, { 5, 0, 353 }, { 23, 0, 26 }, { 11, 0, 762 }, + { 4, 10, 395 }, { 6, 0, 2024 }, { 4, 0, 611 }, { 5, 0, 606 }, + { 9, 10, 174 }, { 10, 10, 164 }, { 11, 10, 440 }, { 11, 10, 841 }, + { 15, 10, 98 }, { 6, 10, 426 }, { 10, 10, 608 }, { 11, 10, 1002 }, + { 10, 10, 250 }, { 6, 0, 25 }, { 7, 0, 855 }, { 7, 0, 1258 }, + { 16, 0, 32 }, { 7, 11, 1725 }, { 10, 11, 393 }, { 5, 11, 263 }, + { 6, 11, 414 }, { 6, 0, 2011 }, { 5, 10, 476 }, { 4, 0, 4 }, + { 7, 0, 1118 }, { 7, 0, 1320 }, { 7, 0, 1706 }, { 8, 0, 277 }, + { 9, 0, 622 }, { 10, 0, 9 }, { 11, 0, 724 }, { 12, 0, 350 }, + { 12, 0, 397 }, { 13, 0, 28 }, { 13, 0, 159 }, { 15, 0, 89 }, + { 18, 0, 5 }, { 19, 0, 9 }, { 20, 0, 34 }, { 22, 0, 47 }, + { 6, 11, 178 }, { 6, 11, 1750 }, { 8, 11, 251 }, { 9, 11, 690 }, + { 10, 11, 155 }, { 10, 11, 196 }, { 10, 11, 373 }, { 11, 11, 698 }, + { 13, 11, 155 }, { 20, 11, 93 }, { 5, 11, 97 }, { 9, 11, 393 }, + { 7, 0, 764 }, { 11, 0, 461 }, { 12, 0, 172 }, { 5, 10, 76 }, + { 6, 10, 458 }, { 6, 10, 497 }, { 7, 10, 868 }, { 9, 10, 658 }, + { 10, 10, 594 }, { 11, 10, 566 }, { 12, 10, 338 }, { 13, 10, 200 }, + { 6, 0, 1449 }, { 10, 11, 40 }, { 6, 11, 1639 }, { 6, 0, 1445 }, + { 6, 0, 1168 }, { 4, 10, 526 }, { 7, 10, 1029 }, { 7, 10, 1054 }, + { 4, 11, 191 }, { 7, 11, 934 }, { 8, 11, 647 }, { 17, 11, 97 }, + { 4, 10, 636 }, { 6, 0, 233 }, { 7, 10, 660 }, { 7, 10, 1124 }, + { 17, 10, 31 }, { 19, 10, 22 }, { 23, 10, 14 }, { 6, 10, 1699 }, + { 8, 11, 110 }, { 12, 11, 246 }, { 15, 11, 162 }, { 19, 11, 64 }, + { 20, 11, 8 }, { 20, 11, 95 }, { 22, 11, 24 }, { 24, 11, 17 }, + { 5, 11, 165 }, { 9, 11, 346 }, { 10, 11, 655 }, { 5, 11, 319 }, + { 7, 11, 534 }, { 6, 0, 255 }, { 9, 0, 216 }, { 8, 11, 128 }, + { 11, 11, 179 }, { 9, 0, 183 }, { 11, 0, 286 }, { 11, 0, 956 }, + { 23, 0, 3 }, { 4, 0, 536 }, { 7, 0, 1141 }, { 10, 0, 723 }, + { 11, 0, 371 }, { 4, 10, 279 }, { 7, 10, 301 }, { 9, 10, 362 }, + { 7, 0, 285 }, { 5, 11, 57 }, { 6, 11, 101 }, { 6, 11, 1663 }, + { 7, 11, 132 }, { 7, 11, 1048 }, { 7, 11, 1154 }, { 7, 11, 1415 }, + { 7, 11, 1507 }, { 12, 11, 493 }, { 15, 11, 105 }, { 23, 11, 15 }, + { 5, 11, 459 }, { 7, 11, 1073 }, { 7, 10, 1743 }, { 8, 11, 241 }, + { 8, 11, 334 }, { 4, 10, 178 }, { 5, 10, 399 }, { 7, 0, 560 }, + { 4, 0, 690 }, { 7, 0, 1246 }, { 18, 0, 157 }, { 19, 0, 63 }, + { 10, 0, 599 }, { 11, 0, 33 }, { 12, 0, 571 }, { 21, 0, 1 }, + { 6, 11, 324 }, { 6, 11, 520 }, { 7, 11, 338 }, { 7, 11, 1616 }, + { 7, 11, 1729 }, { 8, 11, 228 }, { 9, 11, 69 }, { 11, 11, 750 }, + { 7, 0, 1862 }, { 12, 0, 491 }, { 12, 0, 520 }, { 13, 0, 383 }, + { 14, 0, 244 }, { 7, 11, 734 }, { 6, 10, 1692 }, { 10, 0, 448 }, + { 11, 0, 630 }, { 17, 0, 117 }, { 6, 10, 202 }, { 7, 11, 705 }, + { 12, 10, 360 }, { 17, 10, 118 }, { 18, 10, 27 }, { 20, 10, 67 }, + { 4, 11, 73 }, { 6, 11, 612 }, { 7, 11, 927 }, { 7, 11, 1822 }, + { 8, 11, 217 }, { 9, 11, 472 }, { 9, 11, 765 }, { 9, 11, 766 }, + { 10, 11, 408 }, { 11, 11, 51 }, { 11, 11, 793 }, { 12, 11, 266 }, + { 15, 11, 158 }, { 20, 11, 89 }, { 22, 11, 32 }, { 4, 0, 190 }, + { 5, 0, 554 }, { 5, 0, 1001 }, { 5, 11, 389 }, { 8, 11, 636 }, + { 9, 11, 229 }, { 5, 0, 446 }, { 7, 10, 872 }, { 10, 10, 516 }, + { 11, 10, 167 }, { 9, 10, 313 }, { 4, 10, 224 }, { 6, 0, 1313 }, + { 5, 10, 546 }, { 7, 10, 35 }, { 8, 10, 11 }, { 8, 10, 12 }, + { 9, 10, 315 }, { 9, 10, 533 }, { 10, 10, 802 }, { 11, 10, 166 }, + { 12, 10, 525 }, { 14, 10, 243 }, { 6, 0, 636 }, { 9, 0, 837 }, + { 5, 10, 241 }, { 8, 10, 242 }, { 9, 10, 451 }, { 10, 10, 667 }, + { 11, 10, 598 }, { 12, 10, 429 }, { 22, 10, 46 }, { 22, 11, 46 }, + { 8, 11, 472 }, { 11, 0, 278 }, { 14, 0, 73 }, { 13, 11, 185 }, + { 4, 0, 868 }, { 6, 0, 972 }, { 4, 10, 366 }, { 9, 10, 516 }, + { 10, 0, 1010 }, { 5, 11, 189 }, { 6, 10, 1736 }, { 7, 11, 442 }, + { 7, 11, 443 }, { 8, 11, 281 }, { 12, 11, 174 }, { 13, 11, 83 }, + { 13, 11, 261 }, { 11, 11, 384 }, { 6, 11, 2 }, { 7, 11, 191 }, + { 7, 11, 446 }, { 7, 11, 758 }, { 7, 11, 1262 }, { 7, 11, 1737 }, + { 8, 11, 22 }, { 8, 11, 270 }, { 8, 11, 612 }, { 9, 11, 4 }, + { 9, 11, 167 }, { 9, 11, 312 }, { 9, 11, 436 }, { 10, 11, 156 }, + { 10, 11, 216 }, { 10, 11, 311 }, { 10, 11, 623 }, { 11, 11, 72 }, + { 11, 11, 330 }, { 11, 11, 455 }, { 12, 11, 101 }, { 12, 11, 321 }, + { 12, 11, 504 }, { 12, 11, 530 }, { 12, 11, 543 }, { 13, 11, 17 }, + { 13, 11, 156 }, { 13, 11, 334 }, { 14, 11, 48 }, { 15, 11, 70 }, + { 17, 11, 60 }, { 20, 11, 64 }, { 6, 10, 331 }, { 8, 10, 623 }, + { 7, 0, 1231 }, { 4, 0, 304 }, { 6, 11, 60 }, { 7, 11, 670 }, + { 7, 11, 1327 }, { 8, 11, 411 }, { 8, 11, 435 }, { 9, 11, 653 }, + { 9, 11, 740 }, { 10, 11, 385 }, { 11, 11, 222 }, { 11, 11, 324 }, + { 11, 11, 829 }, { 12, 11, 611 }, { 7, 0, 506 }, { 6, 11, 166 }, + { 7, 11, 374 }, { 7, 11, 1174 }, { 14, 11, 43 }, { 18, 11, 21 }, + { 7, 11, 1694 }, { 7, 10, 1888 }, { 5, 11, 206 }, { 6, 11, 398 }, + { 7, 11, 50 }, { 22, 0, 26 }, { 6, 0, 53 }, { 6, 0, 199 }, + { 7, 0, 1408 }, { 8, 0, 32 }, { 8, 0, 93 }, { 10, 0, 397 }, + { 10, 0, 629 }, { 11, 0, 593 }, { 11, 0, 763 }, { 13, 0, 326 }, + { 17, 0, 35 }, { 6, 0, 105 }, { 4, 10, 394 }, { 4, 0, 843 }, + { 10, 0, 794 }, { 11, 0, 704 }, { 13, 0, 396 }, { 5, 0, 114 }, + { 5, 0, 255 }, { 13, 0, 285 }, { 6, 0, 619 }, { 7, 0, 898 }, + { 7, 0, 1092 }, { 8, 0, 485 }, { 18, 0, 28 }, { 19, 0, 116 }, + { 7, 10, 1931 }, { 9, 0, 145 }, { 7, 10, 574 }, { 7, 10, 1719 }, + { 7, 0, 2035 }, { 8, 0, 19 }, { 9, 0, 89 }, { 10, 0, 831 }, + { 4, 10, 658 }, { 6, 11, 517 }, { 7, 11, 1159 }, { 10, 11, 621 }, + { 11, 11, 192 }, { 7, 0, 1933 }, { 7, 11, 1933 }, { 9, 10, 781 }, + { 10, 10, 144 }, { 11, 10, 385 }, { 13, 10, 161 }, { 13, 10, 228 }, + { 13, 10, 268 }, { 20, 10, 107 }, { 8, 10, 374 }, { 10, 11, 223 }, + { 11, 11, 645 }, { 7, 0, 1728 }, { 7, 11, 64 }, { 7, 11, 289 }, + { 8, 11, 245 }, { 4, 10, 344 }, { 6, 10, 498 }, { 11, 10, 323 }, + { 8, 0, 746 }, { 7, 10, 1063 }, { 9, 10, 155 }, { 4, 0, 987 }, + { 6, 0, 1964 }, { 6, 0, 1974 }, { 6, 0, 1990 }, { 8, 0, 995 }, + { 5, 11, 609 }, { 5, 10, 906 }, { 6, 0, 1550 }, { 6, 0, 874 }, + { 5, 11, 129 }, { 6, 11, 61 }, { 7, 11, 947 }, { 4, 0, 1018 }, + { 6, 0, 1938 }, { 6, 0, 2021 }, { 6, 0, 2039 }, { 4, 0, 814 }, + { 11, 0, 126 }, { 11, 0, 287 }, { 6, 0, 1264 }, { 5, 0, 955 }, + { 8, 0, 814 }, { 13, 11, 506 }, { 4, 11, 314 }, { 6, 0, 981 }, + { 11, 11, 1000 }, { 5, 0, 56 }, { 8, 0, 892 }, { 8, 0, 915 }, + { 12, 0, 776 }, { 20, 0, 100 }, { 10, 0, 4 }, { 10, 0, 13 }, + { 11, 0, 638 }, { 20, 0, 57 }, { 20, 11, 74 }, { 5, 0, 738 }, + { 4, 10, 616 }, { 5, 11, 637 }, { 8, 10, 692 }, { 5, 0, 758 }, + { 4, 10, 305 }, { 9, 11, 590 }, { 5, 11, 280 }, { 7, 11, 1226 }, + { 6, 11, 494 }, { 7, 0, 1112 }, { 5, 11, 281 }, { 13, 0, 44 }, + { 14, 0, 214 }, { 5, 10, 214 }, { 7, 10, 603 }, { 8, 10, 611 }, + { 9, 10, 686 }, { 10, 10, 88 }, { 11, 10, 459 }, { 11, 10, 496 }, + { 12, 10, 463 }, { 12, 10, 590 }, { 11, 0, 328 }, { 7, 11, 1064 }, + { 9, 0, 133 }, { 7, 0, 168 }, { 13, 0, 196 }, { 13, 0, 237 }, + { 6, 10, 1703 }, { 6, 0, 1152 }, { 7, 0, 1245 }, { 5, 0, 110 }, + { 6, 0, 169 }, { 6, 0, 1702 }, { 7, 0, 400 }, { 8, 0, 538 }, + { 9, 0, 184 }, { 9, 0, 524 }, { 12, 0, 218 }, { 6, 0, 1816 }, + { 10, 0, 871 }, { 12, 0, 769 }, { 12, 0, 785 }, { 4, 11, 630 }, + { 7, 11, 33 }, { 7, 11, 120 }, { 8, 11, 489 }, { 9, 11, 319 }, + { 10, 11, 820 }, { 11, 11, 1004 }, { 12, 11, 379 }, { 13, 11, 117 }, + { 13, 11, 412 }, { 14, 11, 25 }, { 15, 11, 52 }, { 15, 11, 161 }, + { 16, 11, 47 }, { 21, 11, 2 }, { 6, 0, 133 }, { 8, 0, 413 }, + { 9, 0, 353 }, { 11, 0, 993 }, { 17, 10, 19 }, { 4, 11, 937 }, + { 5, 11, 801 }, { 6, 0, 978 }, { 6, 0, 93 }, { 6, 0, 1508 }, + { 7, 0, 1422 }, { 7, 0, 1851 }, { 8, 0, 673 }, { 9, 0, 529 }, + { 12, 0, 43 }, { 6, 0, 317 }, { 10, 0, 512 }, { 4, 10, 737 }, + { 11, 10, 294 }, { 12, 10, 60 }, { 12, 10, 437 }, { 13, 10, 64 }, + { 13, 10, 380 }, { 14, 10, 430 }, { 9, 0, 371 }, { 7, 11, 1591 }, + { 16, 11, 43 }, { 6, 10, 1758 }, { 8, 10, 520 }, { 9, 10, 345 }, + { 9, 10, 403 }, { 14, 10, 350 }, { 5, 0, 526 }, { 10, 10, 242 }, + { 10, 10, 579 }, { 9, 0, 25 }, { 10, 0, 467 }, { 10, 0, 559 }, + { 5, 10, 139 }, { 7, 10, 1168 }, { 10, 10, 539 }, { 4, 0, 335 }, + { 7, 0, 942 }, { 12, 0, 754 }, { 4, 11, 365 }, { 11, 0, 182 }, + { 14, 0, 195 }, { 14, 11, 29 }, { 5, 11, 7 }, { 11, 11, 774 }, + { 4, 11, 746 }, { 7, 11, 1090 }, { 8, 0, 39 }, { 10, 0, 773 }, + { 11, 0, 84 }, { 12, 0, 205 }, { 14, 0, 1 }, { 5, 0, 601 }, + { 5, 0, 870 }, { 5, 11, 360 }, { 8, 11, 237 }, { 4, 0, 181 }, + { 8, 0, 370 }, { 6, 0, 1652 }, { 8, 0, 358 }, { 4, 10, 107 }, + { 7, 10, 613 }, { 8, 10, 439 }, { 8, 10, 504 }, { 9, 10, 501 }, + { 10, 10, 383 }, { 11, 10, 477 }, { 4, 10, 229 }, { 9, 11, 785 }, + { 4, 0, 97 }, { 5, 0, 147 }, { 6, 0, 286 }, { 7, 0, 1362 }, + { 13, 0, 176 }, { 6, 0, 537 }, { 7, 0, 788 }, { 7, 0, 1816 }, + { 4, 10, 903 }, { 12, 10, 71 }, { 6, 0, 743 }, { 6, 0, 1223 }, + { 6, 0, 375 }, { 7, 0, 169 }, { 7, 0, 254 }, { 8, 0, 780 }, + { 7, 11, 1493 }, { 7, 0, 1714 }, { 4, 10, 47 }, { 6, 10, 373 }, + { 7, 10, 452 }, { 7, 10, 543 }, { 7, 10, 1856 }, { 9, 10, 6 }, + { 11, 10, 257 }, { 11, 10, 391 }, { 6, 0, 896 }, { 8, 0, 1003 }, + { 7, 0, 1447 }, { 9, 11, 341 }, { 5, 10, 980 }, { 6, 10, 1754 }, + { 17, 11, 22 }, { 4, 11, 277 }, { 5, 11, 608 }, { 6, 11, 493 }, + { 7, 11, 457 }, { 12, 11, 384 }, { 7, 10, 536 }, { 7, 10, 1331 }, + { 8, 10, 143 }, { 12, 0, 744 }, { 7, 11, 27 }, { 7, 11, 316 }, + { 18, 0, 126 }, { 5, 10, 19 }, { 6, 10, 533 }, { 4, 0, 788 }, + { 11, 0, 41 }, { 5, 11, 552 }, { 5, 11, 586 }, { 5, 11, 676 }, + { 6, 11, 448 }, { 8, 11, 244 }, { 11, 11, 1 }, { 11, 11, 41 }, + { 13, 11, 3 }, { 16, 11, 54 }, { 17, 11, 4 }, { 18, 11, 13 }, + { 4, 0, 985 }, { 6, 0, 1801 }, { 4, 11, 401 }, { 9, 11, 264 }, + { 5, 10, 395 }, { 5, 10, 951 }, { 6, 10, 1776 }, { 5, 0, 629 }, + { 7, 0, 1549 }, { 11, 10, 663 }, { 12, 10, 210 }, { 13, 10, 166 }, + { 13, 10, 310 }, { 14, 10, 373 }, { 19, 10, 43 }, { 9, 11, 543 }, + { 10, 11, 524 }, { 11, 11, 30 }, { 12, 11, 524 }, { 14, 11, 315 }, + { 16, 11, 18 }, { 20, 11, 26 }, { 20, 11, 65 }, { 4, 11, 205 }, + { 5, 11, 623 }, { 7, 11, 104 }, { 8, 11, 519 }, { 5, 0, 293 }, + { 6, 0, 601 }, { 7, 11, 579 }, { 9, 11, 41 }, { 9, 11, 244 }, + { 9, 11, 669 }, { 10, 11, 5 }, { 11, 11, 861 }, { 11, 11, 951 }, + { 11, 11, 980 }, { 4, 11, 717 }, { 4, 10, 695 }, { 7, 10, 497 }, + { 9, 10, 387 }, { 19, 10, 81 }, { 4, 0, 420 }, { 14, 0, 37 }, + { 6, 0, 1134 }, { 6, 0, 1900 }, { 12, 0, 830 }, { 12, 0, 878 }, + { 12, 0, 894 }, { 15, 0, 221 }, { 15, 0, 245 }, { 4, 11, 489 }, + { 7, 0, 1570 }, { 12, 0, 542 }, { 8, 0, 933 }, { 8, 0, 957 }, + { 6, 0, 1371 }, { 7, 0, 31 }, { 8, 0, 373 }, { 5, 10, 284 }, + { 6, 10, 49 }, { 6, 10, 350 }, { 7, 10, 377 }, { 7, 10, 1693 }, + { 8, 10, 678 }, { 9, 10, 161 }, { 9, 10, 585 }, { 9, 10, 671 }, + { 9, 10, 839 }, { 11, 10, 912 }, { 13, 10, 427 }, { 7, 11, 892 }, + { 4, 0, 325 }, { 10, 0, 125 }, { 11, 11, 47 }, { 4, 10, 597 }, + { 10, 0, 323 }, { 6, 0, 1547 }, { 7, 11, 1605 }, { 9, 11, 473 }, + { 11, 11, 962 }, { 18, 11, 139 }, { 11, 10, 908 }, { 7, 11, 819 }, + { 9, 11, 26 }, { 9, 11, 392 }, { 10, 11, 152 }, { 10, 11, 226 }, + { 11, 11, 19 }, { 12, 11, 276 }, { 12, 11, 426 }, { 12, 11, 589 }, + { 13, 11, 460 }, { 15, 11, 97 }, { 19, 11, 48 }, { 20, 11, 104 }, + { 7, 11, 51 }, { 4, 0, 718 }, { 7, 0, 1216 }, { 6, 0, 1896 }, + { 6, 0, 1905 }, { 6, 0, 1912 }, { 9, 0, 947 }, { 9, 0, 974 }, + { 12, 0, 809 }, { 12, 0, 850 }, { 12, 0, 858 }, { 12, 0, 874 }, + { 12, 0, 887 }, { 12, 0, 904 }, { 12, 0, 929 }, { 12, 0, 948 }, + { 12, 0, 952 }, { 15, 0, 198 }, { 15, 0, 206 }, { 15, 0, 220 }, + { 15, 0, 227 }, { 15, 0, 247 }, { 18, 0, 188 }, { 21, 0, 48 }, + { 21, 0, 50 }, { 24, 0, 25 }, { 24, 0, 29 }, { 7, 11, 761 }, + { 7, 11, 1051 }, { 9, 11, 545 }, { 5, 0, 124 }, { 5, 0, 144 }, + { 6, 0, 548 }, { 7, 0, 15 }, { 7, 0, 153 }, { 9, 0, 629 }, + { 7, 11, 606 }, { 7, 10, 2014 }, { 7, 10, 2007 }, { 9, 11, 46 }, + { 9, 10, 101 }, { 9, 10, 450 }, { 10, 10, 66 }, { 10, 10, 842 }, + { 11, 10, 536 }, { 12, 10, 587 }, { 6, 0, 75 }, { 7, 0, 1531 }, + { 8, 0, 416 }, { 9, 0, 240 }, { 9, 0, 275 }, { 10, 0, 100 }, + { 11, 0, 658 }, { 11, 0, 979 }, { 12, 0, 86 }, { 14, 0, 207 }, + { 15, 0, 20 }, { 15, 0, 25 }, { 5, 0, 141 }, { 5, 0, 915 }, + { 6, 0, 1783 }, { 7, 0, 211 }, { 7, 0, 698 }, { 7, 0, 1353 }, + { 9, 0, 83 }, { 9, 0, 281 }, { 10, 0, 376 }, { 10, 0, 431 }, + { 11, 0, 543 }, { 12, 0, 664 }, { 13, 0, 280 }, { 13, 0, 428 }, + { 14, 0, 61 }, { 14, 0, 128 }, { 17, 0, 52 }, { 17, 0, 81 }, + { 4, 11, 674 }, { 7, 0, 533 }, { 21, 0, 6 }, { 4, 11, 770 }, + { 5, 0, 538 }, { 5, 11, 79 }, { 7, 11, 1027 }, { 7, 11, 1477 }, + { 11, 11, 52 }, { 11, 10, 62 }, { 4, 0, 338 }, { 5, 0, 400 }, + { 5, 11, 789 }, { 6, 11, 195 }, { 4, 11, 251 }, { 4, 11, 688 }, + { 7, 11, 513 }, { 7, 11, 1284 }, { 9, 11, 87 }, { 10, 11, 365 }, + { 6, 10, 1766 }, { 6, 0, 0 }, { 7, 0, 84 }, { 11, 0, 895 }, + { 17, 0, 11 }, { 11, 0, 892 }, { 4, 0, 221 }, { 5, 0, 659 }, + { 7, 0, 697 }, { 7, 0, 1211 }, { 10, 0, 284 }, { 5, 0, 989 }, + { 5, 11, 889 }, { 4, 11, 160 }, { 5, 11, 330 }, { 7, 11, 1434 }, + { 8, 11, 174 }, { 6, 10, 1665 }, { 7, 10, 256 }, { 7, 10, 1388 }, + { 10, 10, 499 }, { 11, 10, 670 }, { 7, 0, 848 }, { 4, 10, 22 }, + { 5, 10, 10 }, { 8, 10, 97 }, { 10, 0, 507 }, { 5, 10, 481 }, + { 4, 0, 188 }, { 7, 0, 805 }, { 5, 0, 884 }, { 6, 0, 732 }, + { 11, 0, 991 }, { 7, 11, 968 }, { 11, 11, 636 }, { 15, 11, 145 }, + { 17, 11, 34 }, { 19, 11, 50 }, { 23, 11, 20 }, { 7, 0, 959 }, + { 16, 0, 60 }, { 6, 10, 134 }, { 7, 10, 437 }, { 9, 10, 37 }, + { 14, 10, 285 }, { 14, 10, 371 }, { 7, 10, 486 }, { 8, 10, 155 }, + { 11, 10, 93 }, { 12, 10, 164 }, { 6, 0, 1653 }, { 7, 0, 337 }, + { 5, 10, 591 }, { 6, 0, 1989 }, { 8, 0, 922 }, { 8, 0, 978 }, + { 5, 11, 374 }, { 4, 0, 638 }, { 10, 0, 500 }, { 5, 11, 731 }, + { 5, 10, 380 }, { 5, 10, 650 }, { 8, 10, 310 }, { 10, 11, 381 }, + { 4, 10, 364 }, { 7, 10, 1156 }, { 7, 10, 1187 }, { 9, 10, 409 }, + { 9, 11, 224 }, { 12, 0, 166 }, { 6, 10, 482 }, { 4, 11, 626 }, + { 5, 11, 642 }, { 6, 11, 425 }, { 10, 11, 202 }, { 11, 11, 141 }, + { 4, 10, 781 }, { 6, 10, 487 }, { 7, 10, 926 }, { 8, 10, 263 }, + { 11, 10, 500 }, { 7, 0, 418 }, { 4, 10, 94 }, { 7, 10, 1265 }, + { 8, 0, 760 }, { 4, 10, 417 }, { 8, 11, 835 }, { 5, 10, 348 }, + { 6, 10, 522 }, { 6, 0, 1277 }, { 6, 0, 1538 }, { 11, 11, 541 }, + { 7, 11, 1597 }, { 5, 11, 384 }, { 8, 11, 455 }, { 12, 11, 48 }, + { 8, 0, 770 }, { 5, 11, 264 }, { 6, 11, 184 }, { 4, 0, 89 }, + { 5, 0, 489 }, { 6, 0, 315 }, { 7, 0, 553 }, { 7, 0, 1745 }, + { 10, 0, 243 }, { 4, 10, 408 }, { 4, 10, 741 }, { 7, 10, 500 }, + { 6, 0, 1396 }, { 5, 0, 560 }, { 6, 0, 1658 }, { 9, 0, 3 }, + { 10, 0, 154 }, { 11, 0, 641 }, { 13, 0, 85 }, { 13, 0, 201 }, + { 13, 0, 346 }, { 7, 11, 1595 }, { 5, 11, 633 }, { 6, 11, 28 }, + { 7, 11, 219 }, { 7, 11, 1323 }, { 9, 11, 769 }, { 12, 11, 185 }, + { 7, 11, 785 }, { 7, 11, 359 }, { 8, 11, 243 }, { 12, 11, 175 }, + { 10, 0, 586 }, { 7, 0, 1271 }, { 6, 10, 73 }, { 4, 11, 105 }, + { 4, 0, 166 }, { 5, 0, 505 }, { 6, 0, 1670 }, { 5, 10, 576 }, + { 4, 11, 324 }, { 10, 11, 104 }, { 14, 10, 231 }, { 6, 0, 637 }, + { 7, 10, 1264 }, { 7, 10, 1678 }, { 11, 10, 945 }, { 12, 10, 341 }, + { 12, 10, 471 }, { 12, 10, 569 }, { 23, 11, 21 }, { 23, 11, 23 }, + { 8, 11, 559 }, { 13, 11, 109 }, { 6, 0, 1947 }, { 7, 0, 445 }, + { 8, 0, 307 }, { 8, 0, 704 }, { 10, 0, 41 }, { 10, 0, 439 }, + { 11, 0, 237 }, { 11, 0, 622 }, { 12, 0, 201 }, { 7, 11, 963 }, + { 7, 0, 1977 }, { 4, 0, 189 }, { 5, 0, 713 }, { 8, 0, 57 }, + { 10, 0, 371 }, { 7, 10, 538 }, { 4, 0, 552 }, { 6, 0, 883 }, + { 5, 10, 413 }, { 6, 0, 923 }, { 4, 11, 758 }, { 10, 11, 215 }, + { 8, 10, 495 }, { 7, 10, 54 }, { 8, 10, 312 }, { 10, 10, 191 }, + { 10, 10, 614 }, { 12, 10, 567 }, { 7, 11, 351 }, { 11, 11, 128 }, + { 7, 0, 875 }, { 6, 10, 468 }, { 7, 10, 1478 }, { 8, 10, 530 }, + { 14, 10, 290 }, { 7, 0, 1788 }, { 17, 0, 49 }, { 5, 11, 918 }, + { 12, 11, 398 }, { 20, 11, 39 }, { 21, 11, 11 }, { 22, 11, 41 }, + { 10, 0, 661 }, { 6, 10, 484 }, { 7, 10, 822 }, { 7, 0, 1945 }, + { 6, 0, 794 }, { 9, 10, 900 }, { 7, 10, 1335 }, { 6, 10, 1724 }, + { 7, 10, 2022 }, { 4, 11, 340 }, { 6, 0, 1135 }, { 4, 0, 784 }, + { 5, 0, 745 }, { 5, 0, 84 }, { 6, 0, 163 }, { 5, 0, 410 }, + { 4, 0, 976 }, { 5, 11, 985 }, { 7, 11, 509 }, { 7, 11, 529 }, + { 17, 11, 96 }, { 4, 10, 474 }, { 6, 0, 703 }, { 7, 11, 1919 }, + { 5, 0, 322 }, { 8, 0, 186 }, { 9, 0, 262 }, { 10, 0, 187 }, + { 14, 0, 208 }, { 7, 10, 1504 }, { 5, 0, 227 }, { 9, 0, 560 }, + { 13, 0, 208 }, { 5, 10, 305 }, { 4, 11, 247 }, { 7, 0, 1395 }, + { 8, 0, 486 }, { 9, 0, 236 }, { 9, 0, 878 }, { 10, 0, 218 }, + { 11, 0, 95 }, { 19, 0, 17 }, { 19, 0, 31 }, { 7, 0, 2043 }, + { 8, 0, 672 }, { 13, 0, 448 }, { 4, 11, 184 }, { 5, 11, 390 }, + { 6, 11, 337 }, { 7, 11, 23 }, { 7, 11, 494 }, { 7, 11, 618 }, + { 7, 11, 1456 }, { 8, 11, 27 }, { 8, 11, 599 }, { 10, 11, 153 }, + { 11, 11, 710 }, { 7, 0, 466 }, { 7, 10, 1236 }, { 6, 0, 167 }, + { 7, 0, 186 }, { 7, 0, 656 }, { 10, 0, 643 }, { 4, 10, 480 }, + { 6, 10, 302 }, { 6, 10, 1642 }, { 7, 10, 837 }, { 7, 10, 1547 }, + { 7, 10, 1657 }, { 8, 10, 429 }, { 9, 10, 228 }, { 13, 10, 289 }, + { 13, 10, 343 }, { 19, 10, 101 }, { 6, 0, 1428 }, { 6, 0, 1440 }, + { 5, 0, 412 }, { 7, 10, 278 }, { 10, 10, 739 }, { 11, 10, 708 }, + { 13, 10, 348 }, { 6, 0, 1118 }, { 8, 0, 562 }, { 20, 11, 46 }, + { 9, 0, 316 }, { 11, 0, 256 }, { 6, 0, 1771 }, { 7, 0, 1190 }, + { 9, 0, 132 }, { 10, 11, 227 }, { 11, 11, 497 }, { 11, 11, 709 }, + { 12, 11, 415 }, { 15, 0, 66 }, { 6, 11, 360 }, { 7, 11, 1664 }, + { 8, 11, 478 }, { 16, 10, 28 }, { 4, 0, 317 }, { 7, 0, 1279 }, + { 5, 0, 63 }, { 5, 0, 509 }, { 8, 11, 699 }, { 17, 10, 36 }, + { 6, 0, 1475 }, { 11, 11, 343 }, { 14, 11, 127 }, { 4, 11, 739 }, + { 4, 0, 288 }, { 7, 11, 1757 }, { 8, 0, 89 }, { 8, 0, 620 }, + { 9, 0, 608 }, { 11, 0, 628 }, { 12, 0, 322 }, { 15, 0, 124 }, + { 6, 0, 1225 }, { 7, 0, 1189 }, { 4, 11, 67 }, { 5, 11, 422 }, + { 6, 10, 363 }, { 7, 11, 1037 }, { 7, 11, 1289 }, { 7, 11, 1555 }, + { 7, 10, 1955 }, { 8, 10, 725 }, { 9, 11, 741 }, { 17, 11, 108 }, + { 6, 0, 1468 }, { 6, 0, 689 }, { 6, 0, 1451 }, { 10, 0, 120 }, + { 23, 0, 1 }, { 9, 10, 805 }, { 14, 0, 329 }, { 5, 10, 813 }, + { 7, 10, 2046 }, { 7, 0, 226 }, { 10, 11, 96 }, { 7, 0, 1855 }, + { 5, 10, 712 }, { 11, 10, 17 }, { 13, 10, 321 }, { 16, 10, 67 }, + { 9, 0, 461 }, { 6, 10, 320 }, { 7, 10, 781 }, { 7, 10, 1921 }, + { 9, 10, 55 }, { 10, 10, 186 }, { 10, 10, 273 }, { 10, 10, 664 }, + { 10, 10, 801 }, { 11, 10, 996 }, { 11, 10, 997 }, { 13, 10, 157 }, + { 14, 10, 170 }, { 8, 11, 203 }, { 8, 10, 271 }, { 11, 11, 823 }, + { 11, 11, 846 }, { 12, 11, 482 }, { 13, 11, 133 }, { 13, 11, 277 }, + { 13, 11, 302 }, { 13, 11, 464 }, { 14, 11, 205 }, { 14, 11, 221 }, + { 7, 0, 1346 }, { 4, 11, 449 }, { 5, 11, 718 }, { 6, 0, 85 }, + { 14, 0, 299 }, { 7, 10, 103 }, { 7, 10, 863 }, { 11, 10, 184 }, + { 17, 10, 62 }, { 4, 11, 355 }, { 6, 11, 311 }, { 9, 11, 256 }, + { 10, 11, 404 }, { 9, 10, 659 }, { 10, 11, 758 }, { 5, 11, 827 }, + { 5, 11, 64 }, { 12, 11, 581 }, { 6, 0, 1171 }, { 4, 11, 442 }, + { 7, 11, 1047 }, { 7, 11, 1352 }, { 7, 11, 1643 }, { 4, 0, 980 }, + { 5, 11, 977 }, { 6, 11, 288 }, { 7, 11, 528 }, { 7, 11, 1065 }, + { 5, 0, 279 }, { 6, 0, 235 }, { 7, 0, 468 }, { 8, 0, 446 }, + { 9, 0, 637 }, { 10, 0, 717 }, { 11, 0, 738 }, { 12, 0, 514 }, + { 4, 0, 293 }, { 11, 10, 337 }, { 14, 10, 303 }, { 8, 11, 285 }, + { 5, 0, 17 }, { 6, 0, 371 }, { 9, 0, 528 }, { 12, 0, 364 }, + { 4, 11, 254 }, { 5, 10, 77 }, { 7, 10, 1455 }, { 10, 10, 843 }, + { 19, 10, 73 }, { 22, 0, 5 }, { 4, 10, 458 }, { 6, 11, 12 }, + { 7, 11, 1219 }, { 17, 11, 73 }, { 7, 10, 1420 }, { 6, 10, 109 }, + { 10, 10, 382 }, { 7, 11, 125 }, { 6, 10, 330 }, { 7, 10, 1084 }, + { 11, 10, 142 }, { 6, 11, 369 }, { 6, 11, 502 }, { 7, 11, 1036 }, + { 8, 11, 348 }, { 9, 11, 452 }, { 10, 11, 26 }, { 11, 11, 224 }, + { 11, 11, 387 }, { 11, 11, 772 }, { 12, 11, 95 }, { 12, 11, 629 }, + { 13, 11, 195 }, { 13, 11, 207 }, { 13, 11, 241 }, { 14, 11, 260 }, + { 14, 11, 270 }, { 15, 11, 140 }, { 4, 11, 269 }, { 5, 11, 480 }, + { 7, 11, 532 }, { 7, 11, 1197 }, { 7, 11, 1358 }, { 8, 11, 291 }, + { 11, 11, 349 }, { 14, 11, 396 }, { 22, 0, 48 }, { 10, 0, 601 }, + { 13, 0, 353 }, { 13, 0, 376 }, { 5, 0, 779 }, { 5, 0, 807 }, + { 6, 0, 1655 }, { 6, 0, 1676 }, { 14, 11, 223 }, { 4, 0, 196 }, + { 5, 0, 558 }, { 5, 0, 949 }, { 20, 11, 15 }, { 7, 11, 1764 }, + { 6, 0, 1322 }, { 4, 0, 752 }, { 11, 0, 737 }, { 7, 11, 657 }, + { 8, 11, 533 }, { 7, 0, 412 }, { 4, 0, 227 }, { 5, 0, 159 }, + { 5, 0, 409 }, { 7, 0, 80 }, { 8, 0, 556 }, { 10, 0, 479 }, + { 12, 0, 418 }, { 14, 0, 50 }, { 14, 0, 123 }, { 14, 0, 192 }, + { 14, 0, 249 }, { 14, 0, 295 }, { 15, 0, 27 }, { 7, 0, 1470 }, + { 8, 0, 66 }, { 8, 0, 137 }, { 8, 0, 761 }, { 9, 0, 638 }, + { 11, 0, 80 }, { 11, 0, 212 }, { 11, 0, 368 }, { 11, 0, 418 }, + { 12, 0, 8 }, { 13, 0, 15 }, { 16, 0, 61 }, { 17, 0, 59 }, + { 19, 0, 28 }, { 20, 0, 84 }, { 7, 10, 1985 }, { 4, 11, 211 }, + { 4, 11, 332 }, { 5, 11, 335 }, { 6, 11, 238 }, { 7, 11, 269 }, + { 7, 11, 811 }, { 7, 11, 1797 }, { 8, 10, 122 }, { 8, 11, 836 }, + { 9, 11, 507 }, { 13, 11, 242 }, { 6, 0, 683 }, { 6, 0, 1252 }, + { 4, 0, 873 }, { 4, 10, 234 }, { 6, 0, 835 }, { 6, 0, 38 }, + { 7, 0, 1220 }, { 8, 0, 185 }, { 8, 0, 256 }, { 9, 0, 22 }, + { 9, 0, 331 }, { 10, 0, 738 }, { 11, 0, 205 }, { 11, 0, 540 }, + { 11, 0, 746 }, { 13, 0, 465 }, { 14, 0, 88 }, { 14, 0, 194 }, + { 10, 0, 986 }, { 5, 11, 1009 }, { 12, 11, 582 }, { 18, 11, 131 }, + { 4, 0, 159 }, { 6, 0, 115 }, { 7, 0, 252 }, { 7, 0, 257 }, + { 7, 0, 1928 }, { 8, 0, 69 }, { 9, 0, 384 }, { 10, 0, 91 }, + { 10, 0, 615 }, { 12, 0, 375 }, { 14, 0, 235 }, { 18, 0, 117 }, + { 19, 0, 123 }, { 5, 0, 911 }, { 8, 0, 278 }, { 5, 10, 430 }, + { 5, 10, 932 }, { 6, 10, 131 }, { 7, 10, 417 }, { 9, 10, 522 }, + { 11, 10, 314 }, { 13, 10, 390 }, { 14, 10, 149 }, { 14, 10, 399 }, + { 15, 10, 57 }, { 4, 0, 151 }, { 7, 0, 1567 }, { 8, 0, 749 }, + { 5, 11, 228 }, { 6, 11, 203 }, { 7, 11, 156 }, { 8, 11, 347 }, + { 9, 11, 265 }, { 4, 10, 507 }, { 10, 0, 989 }, { 12, 0, 956 }, + { 5, 0, 990 }, { 5, 0, 194 }, { 6, 0, 927 }, { 7, 0, 1662 }, + { 9, 0, 90 }, { 12, 0, 564 }, { 4, 10, 343 }, { 5, 10, 511 }, + { 5, 0, 425 }, { 7, 10, 455 }, { 10, 10, 591 }, { 4, 0, 774 }, + { 7, 11, 476 }, { 7, 11, 1592 }, { 10, 11, 87 }, { 5, 0, 971 }, + { 7, 10, 1381 }, { 5, 11, 318 }, { 19, 11, 121 }, { 5, 11, 291 }, + { 7, 11, 765 }, { 9, 11, 389 }, { 12, 11, 548 }, { 6, 10, 575 }, + { 4, 0, 827 }, { 12, 0, 646 }, { 12, 0, 705 }, { 12, 0, 712 }, + { 12, 0, 714 }, { 11, 0, 752 }, { 9, 0, 662 }, { 5, 0, 72 }, + { 6, 0, 264 }, { 7, 0, 21 }, { 7, 0, 46 }, { 7, 0, 2013 }, + { 8, 0, 215 }, { 8, 0, 513 }, { 10, 0, 266 }, { 11, 0, 22 }, + { 11, 11, 522 }, { 6, 0, 239 }, { 7, 0, 118 }, { 10, 0, 95 }, + { 11, 0, 603 }, { 13, 0, 443 }, { 14, 0, 160 }, { 15, 0, 4 }, + { 6, 0, 431 }, { 6, 0, 669 }, { 7, 10, 1127 }, { 7, 10, 1572 }, + { 10, 10, 297 }, { 10, 10, 422 }, { 11, 10, 764 }, { 11, 10, 810 }, + { 12, 10, 264 }, { 13, 10, 102 }, { 13, 10, 300 }, { 13, 10, 484 }, + { 14, 10, 147 }, { 14, 10, 229 }, { 17, 10, 71 }, { 18, 10, 118 }, + { 19, 10, 120 }, { 5, 0, 874 }, { 6, 0, 1677 }, { 15, 0, 0 }, + { 10, 11, 525 }, { 11, 11, 82 }, { 6, 0, 65 }, { 7, 0, 939 }, + { 7, 0, 1172 }, { 7, 0, 1671 }, { 9, 0, 540 }, { 10, 0, 696 }, + { 11, 0, 265 }, { 11, 0, 732 }, { 11, 0, 928 }, { 11, 0, 937 }, + { 13, 0, 438 }, { 6, 0, 1350 }, { 8, 11, 547 }, { 4, 11, 422 }, + { 5, 11, 355 }, { 17, 11, 0 }, { 9, 11, 905 }, { 5, 0, 682 }, + { 7, 0, 1887 }, { 4, 0, 809 }, { 4, 0, 696 }, { 5, 11, 865 }, + { 6, 0, 1074 }, { 6, 0, 1472 }, { 14, 10, 35 }, { 14, 10, 191 }, + { 5, 11, 914 }, { 6, 11, 1625 }, { 5, 11, 234 }, { 7, 11, 1383 }, + { 9, 11, 780 }, { 4, 10, 125 }, { 4, 0, 726 }, { 5, 0, 630 }, + { 8, 0, 802 }, { 8, 0, 838 }, { 4, 10, 721 }, { 6, 0, 1337 }, + { 7, 0, 776 }, { 19, 0, 56 }, { 8, 10, 145 }, { 4, 0, 970 }, + { 7, 10, 792 }, { 8, 10, 147 }, { 10, 10, 821 }, { 11, 10, 1021 }, + { 11, 10, 970 }, { 8, 0, 940 }, { 9, 0, 797 }, { 7, 11, 1312 }, + { 9, 0, 248 }, { 10, 0, 400 }, { 7, 11, 816 }, { 7, 11, 1241 }, + { 7, 10, 1999 }, { 9, 11, 283 }, { 9, 11, 520 }, { 10, 11, 213 }, + { 10, 11, 307 }, { 10, 11, 463 }, { 10, 11, 671 }, { 10, 11, 746 }, + { 11, 11, 401 }, { 11, 11, 794 }, { 12, 11, 517 }, { 18, 11, 107 }, + { 19, 11, 115 }, { 6, 0, 1951 }, { 6, 0, 2040 }, { 7, 11, 339 }, + { 13, 0, 41 }, { 15, 0, 93 }, { 5, 10, 168 }, { 5, 10, 930 }, + { 8, 10, 74 }, { 9, 10, 623 }, { 12, 10, 500 }, { 12, 10, 579 }, + { 6, 0, 118 }, { 7, 0, 215 }, { 7, 0, 1521 }, { 12, 0, 11 }, + { 6, 10, 220 }, { 7, 10, 1101 }, { 13, 10, 105 }, { 6, 11, 421 }, + { 7, 11, 61 }, { 7, 11, 1540 }, { 10, 11, 11 }, { 10, 11, 501 }, + { 7, 0, 615 }, { 10, 0, 251 }, { 12, 11, 631 }, { 7, 0, 1044 }, + { 6, 10, 19 }, { 7, 10, 1413 }, { 11, 10, 428 }, { 5, 0, 225 }, + { 7, 10, 96 }, { 8, 10, 401 }, { 8, 10, 703 }, { 9, 10, 896 }, + { 17, 10, 116 }, { 6, 11, 102 }, { 7, 11, 72 }, { 15, 11, 142 }, + { 19, 11, 67 }, { 7, 10, 1961 }, { 7, 10, 1965 }, { 8, 10, 702 }, + { 8, 10, 750 }, { 7, 10, 2030 }, { 8, 10, 150 }, { 8, 10, 737 }, + { 12, 10, 366 }, { 23, 11, 30 }, { 4, 0, 370 }, { 5, 0, 756 }, + { 7, 0, 1326 }, { 7, 11, 823 }, { 8, 10, 800 }, { 9, 10, 148 }, + { 9, 10, 872 }, { 9, 10, 890 }, { 11, 10, 309 }, { 11, 10, 1001 }, + { 13, 10, 267 }, { 13, 10, 323 }, { 6, 0, 1662 }, { 7, 0, 48 }, + { 8, 0, 771 }, { 10, 0, 116 }, { 13, 0, 104 }, { 14, 0, 105 }, + { 14, 0, 184 }, { 15, 0, 168 }, { 19, 0, 92 }, { 20, 0, 68 }, + { 10, 0, 209 }, { 7, 11, 1870 }, { 7, 11, 68 }, { 8, 11, 48 }, + { 8, 11, 88 }, { 8, 11, 582 }, { 8, 11, 681 }, { 9, 11, 373 }, + { 9, 11, 864 }, { 11, 11, 157 }, { 11, 11, 336 }, { 11, 11, 843 }, + { 20, 11, 27 }, { 6, 0, 930 }, { 4, 11, 88 }, { 5, 11, 137 }, + { 5, 11, 174 }, { 5, 11, 777 }, { 6, 11, 1664 }, { 6, 11, 1725 }, + { 7, 11, 77 }, { 7, 11, 426 }, { 7, 11, 1317 }, { 7, 11, 1355 }, + { 8, 11, 126 }, { 8, 11, 563 }, { 9, 11, 523 }, { 9, 11, 750 }, + { 10, 11, 310 }, { 10, 11, 836 }, { 11, 11, 42 }, { 11, 11, 318 }, + { 11, 11, 731 }, { 12, 11, 68 }, { 12, 11, 92 }, { 12, 11, 507 }, + { 12, 11, 692 }, { 13, 11, 81 }, { 13, 11, 238 }, { 13, 11, 374 }, + { 18, 11, 138 }, { 19, 11, 78 }, { 19, 11, 111 }, { 20, 11, 55 }, + { 20, 11, 77 }, { 20, 11, 92 }, { 4, 11, 938 }, { 7, 11, 1831 }, + { 5, 10, 547 }, { 7, 10, 424 }, { 8, 11, 617 }, { 10, 11, 351 }, + { 6, 0, 1286 }, { 6, 11, 1668 }, { 7, 11, 1499 }, { 8, 11, 117 }, + { 9, 11, 314 }, { 10, 11, 174 }, { 6, 0, 759 }, { 6, 0, 894 }, + { 7, 11, 707 }, { 11, 11, 563 }, { 4, 0, 120 }, { 7, 0, 1894 }, + { 9, 0, 385 }, { 21, 0, 17 }, { 10, 0, 429 }, { 5, 11, 403 }, + { 5, 0, 820 }, { 7, 0, 931 }, { 10, 0, 199 }, { 5, 10, 133 }, + { 6, 0, 151 }, { 6, 0, 1675 }, { 7, 0, 383 }, { 23, 0, 10 }, + { 6, 0, 761 }, { 8, 10, 187 }, { 8, 0, 365 }, { 10, 10, 0 }, + { 10, 10, 818 }, { 11, 10, 988 }, { 4, 11, 44 }, { 5, 11, 311 }, + { 6, 11, 156 }, { 7, 11, 639 }, { 7, 11, 762 }, { 7, 11, 1827 }, + { 9, 11, 8 }, { 9, 11, 462 }, { 20, 11, 83 }, { 4, 11, 346 }, + { 7, 11, 115 }, { 9, 11, 180 }, { 9, 11, 456 }, { 10, 11, 363 }, + { 8, 10, 685 }, { 7, 0, 1086 }, { 17, 0, 46 }, { 6, 0, 1624 }, + { 11, 0, 11 }, { 12, 0, 422 }, { 13, 0, 444 }, { 14, 0, 360 }, + { 6, 0, 1020 }, { 6, 0, 1260 }, { 6, 0, 1589 }, { 4, 0, 43 }, + { 5, 0, 344 }, { 5, 0, 357 }, { 14, 0, 472 }, { 22, 0, 58 }, + { 6, 0, 1864 }, { 6, 0, 1866 }, { 6, 0, 1868 }, { 6, 0, 1869 }, + { 6, 0, 1874 }, { 6, 0, 1877 }, { 6, 0, 1903 }, { 6, 0, 1911 }, + { 9, 0, 920 }, { 9, 0, 921 }, { 9, 0, 924 }, { 9, 0, 946 }, + { 9, 0, 959 }, { 9, 0, 963 }, { 9, 0, 970 }, { 9, 0, 997 }, + { 9, 0, 1008 }, { 9, 0, 1017 }, { 12, 0, 795 }, { 12, 0, 797 }, + { 12, 0, 798 }, { 12, 0, 800 }, { 12, 0, 803 }, { 12, 0, 811 }, + { 12, 0, 820 }, { 12, 0, 821 }, { 12, 0, 839 }, { 12, 0, 841 }, + { 12, 0, 848 }, { 12, 0, 911 }, { 12, 0, 921 }, { 12, 0, 922 }, + { 12, 0, 925 }, { 12, 0, 937 }, { 12, 0, 944 }, { 12, 0, 945 }, + { 12, 0, 953 }, { 15, 0, 184 }, { 15, 0, 191 }, { 15, 0, 199 }, + { 15, 0, 237 }, { 15, 0, 240 }, { 15, 0, 243 }, { 15, 0, 246 }, + { 18, 0, 203 }, { 21, 0, 40 }, { 21, 0, 52 }, { 21, 0, 57 }, + { 24, 0, 23 }, { 24, 0, 28 }, { 24, 0, 30 }, { 6, 0, 725 }, + { 17, 11, 58 }, { 5, 0, 888 }, { 9, 10, 874 }, { 4, 0, 711 }, + { 8, 10, 774 }, { 10, 10, 670 }, { 12, 10, 51 }, { 16, 11, 40 }, + { 6, 11, 185 }, { 7, 11, 1899 }, { 11, 11, 673 }, { 9, 10, 701 }, + { 9, 0, 440 }, { 4, 11, 327 }, { 5, 11, 478 }, { 7, 11, 1332 }, + { 8, 11, 753 }, { 12, 11, 227 }, { 4, 10, 127 }, { 5, 10, 350 }, + { 6, 10, 356 }, { 8, 10, 426 }, { 9, 10, 572 }, { 10, 10, 247 }, + { 11, 10, 312 }, { 5, 11, 1020 }, { 5, 11, 1022 }, { 4, 11, 103 }, + { 5, 11, 401 }, { 6, 0, 1913 }, { 6, 0, 1926 }, { 6, 0, 1959 }, + { 9, 0, 914 }, { 9, 0, 939 }, { 9, 0, 952 }, { 9, 0, 979 }, + { 9, 0, 990 }, { 9, 0, 998 }, { 9, 0, 1003 }, { 9, 0, 1023 }, + { 12, 0, 827 }, { 12, 0, 834 }, { 12, 0, 845 }, { 12, 0, 912 }, + { 12, 0, 935 }, { 12, 0, 951 }, { 15, 0, 172 }, { 15, 0, 174 }, + { 18, 0, 198 }, { 21, 0, 63 }, { 5, 0, 958 }, { 5, 0, 987 }, + { 4, 11, 499 }, { 7, 11, 1421 }, { 7, 0, 885 }, { 6, 10, 59 }, + { 6, 10, 1762 }, { 9, 10, 603 }, { 13, 10, 397 }, { 10, 11, 62 }, + { 13, 11, 164 }, { 4, 0, 847 }, { 7, 0, 326 }, { 11, 0, 276 }, + { 14, 0, 293 }, { 4, 0, 65 }, { 5, 0, 479 }, { 5, 0, 1004 }, + { 7, 0, 1913 }, { 8, 0, 317 }, { 9, 0, 302 }, { 10, 0, 612 }, + { 13, 0, 22 }, { 4, 11, 96 }, { 4, 0, 261 }, { 7, 0, 510 }, + { 7, 0, 1514 }, { 6, 10, 111 }, { 7, 10, 4 }, { 8, 10, 163 }, + { 8, 10, 776 }, { 10, 10, 566 }, { 4, 0, 291 }, { 9, 0, 515 }, + { 12, 0, 152 }, { 12, 0, 443 }, { 13, 0, 392 }, { 14, 0, 357 }, + { 7, 11, 399 }, { 7, 11, 1492 }, { 4, 0, 589 }, { 11, 0, 282 }, + { 6, 11, 563 }, { 7, 10, 1994 }, { 5, 10, 297 }, { 7, 10, 1038 }, + { 4, 0, 130 }, { 7, 0, 843 }, { 7, 0, 1562 }, { 5, 0, 42 }, + { 5, 0, 879 }, { 7, 0, 245 }, { 7, 0, 324 }, { 7, 0, 1532 }, + { 11, 0, 463 }, { 11, 0, 472 }, { 13, 0, 363 }, { 16, 0, 52 }, + { 4, 0, 134 }, { 5, 0, 372 }, { 5, 0, 680 }, { 8, 10, 363 }, + { 6, 0, 1997 }, { 8, 0, 935 }, { 8, 0, 977 }, { 4, 0, 810 }, + { 7, 0, 1634 }, { 7, 10, 1675 }, { 7, 0, 1390 }, { 4, 11, 910 }, + { 5, 11, 832 }, { 7, 10, 808 }, { 8, 11, 266 }, { 11, 11, 578 }, + { 4, 0, 644 }, { 4, 0, 982 }, { 10, 0, 867 }, { 4, 10, 280 }, + { 7, 0, 540 }, { 12, 10, 54 }, { 7, 0, 123 }, { 6, 0, 1978 }, + { 4, 10, 421 }, { 5, 10, 548 }, { 6, 0, 623 }, { 8, 0, 789 }, + { 4, 0, 908 }, { 5, 0, 359 }, { 5, 0, 508 }, { 6, 0, 1723 }, + { 7, 0, 343 }, { 7, 0, 1996 }, { 7, 0, 2026 }, { 6, 0, 1220 }, + { 4, 0, 341 }, { 7, 0, 480 }, { 6, 10, 254 }, { 9, 10, 109 }, + { 10, 10, 103 }, { 6, 0, 888 }, { 8, 11, 528 }, { 9, 11, 348 }, + { 7, 0, 1995 }, { 8, 0, 299 }, { 11, 0, 890 }, { 12, 0, 674 }, + { 4, 11, 20 }, { 5, 11, 616 }, { 7, 11, 1094 }, { 6, 10, 1630 }, + { 4, 0, 238 }, { 5, 0, 503 }, { 6, 0, 179 }, { 7, 0, 2003 }, + { 8, 0, 381 }, { 8, 0, 473 }, { 9, 0, 149 }, { 10, 0, 788 }, + { 15, 0, 45 }, { 15, 0, 86 }, { 20, 0, 110 }, { 22, 0, 57 }, + { 5, 10, 671 }, { 4, 11, 26 }, { 5, 11, 429 }, { 6, 11, 245 }, + { 7, 11, 704 }, { 7, 11, 1379 }, { 7, 11, 1474 }, { 4, 0, 121 }, + { 5, 0, 156 }, { 5, 0, 349 }, { 9, 0, 431 }, { 10, 0, 605 }, + { 14, 0, 342 }, { 7, 11, 943 }, { 11, 11, 614 }, { 4, 10, 889 }, + { 4, 11, 621 }, { 7, 10, 1382 }, { 7, 11, 1382 }, { 7, 10, 1910 }, + { 4, 10, 627 }, { 5, 10, 775 }, { 5, 11, 542 }, { 5, 11, 868 }, + { 8, 11, 433 }, { 6, 0, 1373 }, { 7, 0, 1011 }, { 11, 10, 362 }, + { 11, 10, 948 }, { 12, 10, 388 }, { 6, 0, 80 }, { 7, 0, 173 }, + { 9, 0, 547 }, { 10, 0, 730 }, { 14, 0, 18 }, { 22, 0, 39 }, + { 7, 11, 1495 }, { 6, 0, 1694 }, { 7, 0, 1974 }, { 12, 0, 196 }, + { 4, 0, 923 }, { 6, 0, 507 }, { 6, 0, 1711 }, { 7, 10, 451 }, + { 8, 10, 389 }, { 12, 10, 490 }, { 13, 10, 16 }, { 13, 10, 215 }, + { 13, 10, 351 }, { 18, 10, 132 }, { 19, 10, 125 }, { 6, 0, 646 }, + { 6, 0, 1047 }, { 7, 10, 841 }, { 8, 10, 566 }, { 6, 0, 1611 }, + { 7, 0, 1214 }, { 11, 0, 926 }, { 4, 11, 525 }, { 4, 0, 595 }, + { 5, 0, 240 }, { 6, 0, 459 }, { 7, 0, 12 }, { 7, 0, 114 }, + { 7, 0, 949 }, { 7, 0, 1753 }, { 7, 0, 1805 }, { 8, 0, 658 }, + { 9, 0, 1 }, { 11, 0, 959 }, { 13, 0, 446 }, { 5, 10, 912 }, + { 6, 10, 1695 }, { 4, 0, 446 }, { 7, 11, 62 }, { 12, 11, 45 }, + { 19, 11, 112 }, { 5, 10, 236 }, { 6, 10, 572 }, { 8, 10, 492 }, + { 11, 10, 618 }, { 16, 10, 56 }, { 5, 10, 190 }, { 8, 10, 318 }, + { 7, 10, 1376 }, { 4, 11, 223 }, { 6, 11, 359 }, { 11, 11, 3 }, + { 13, 11, 108 }, { 14, 11, 89 }, { 16, 11, 22 }, { 4, 11, 647 }, + { 6, 0, 490 }, { 6, 0, 491 }, { 6, 0, 1584 }, { 7, 11, 685 }, + { 10, 11, 220 }, { 7, 0, 250 }, { 8, 0, 507 }, { 4, 0, 158 }, + { 4, 0, 140 }, { 7, 0, 362 }, { 8, 0, 209 }, { 9, 0, 10 }, + { 9, 0, 160 }, { 9, 0, 503 }, { 9, 0, 614 }, { 10, 0, 689 }, + { 11, 0, 327 }, { 11, 0, 553 }, { 11, 0, 725 }, { 11, 0, 767 }, + { 12, 0, 252 }, { 12, 0, 583 }, { 13, 0, 192 }, { 14, 0, 269 }, + { 14, 0, 356 }, { 20, 0, 50 }, { 19, 0, 1 }, { 19, 0, 26 }, + { 22, 0, 9 }, { 4, 11, 109 }, { 6, 0, 228 }, { 7, 0, 1341 }, + { 9, 0, 408 }, { 10, 0, 343 }, { 4, 0, 373 }, { 5, 0, 283 }, + { 6, 0, 480 }, { 7, 0, 609 }, { 10, 0, 860 }, { 10, 0, 878 }, + { 6, 0, 779 }, { 6, 0, 1209 }, { 4, 0, 557 }, { 7, 11, 263 }, + { 7, 11, 628 }, { 8, 11, 349 }, { 4, 0, 548 }, { 7, 0, 197 }, + { 8, 0, 142 }, { 8, 0, 325 }, { 9, 0, 150 }, { 9, 0, 596 }, + { 10, 0, 350 }, { 10, 0, 353 }, { 11, 0, 74 }, { 11, 0, 315 }, + { 12, 0, 662 }, { 12, 0, 681 }, { 14, 0, 423 }, { 15, 0, 141 }, + { 4, 11, 40 }, { 10, 11, 67 }, { 11, 11, 117 }, { 11, 11, 768 }, + { 11, 11, 935 }, { 7, 11, 992 }, { 8, 11, 301 }, { 9, 11, 722 }, + { 12, 11, 63 }, { 13, 11, 29 }, { 14, 11, 161 }, { 15, 11, 18 }, + { 6, 0, 1490 }, { 10, 11, 532 }, { 5, 0, 580 }, { 7, 0, 378 }, + { 7, 0, 674 }, { 7, 0, 1424 }, { 15, 0, 83 }, { 16, 0, 11 }, + { 15, 11, 83 }, { 16, 11, 11 }, { 6, 0, 1057 }, { 6, 0, 1335 }, + { 10, 0, 316 }, { 7, 10, 85 }, { 7, 10, 247 }, { 8, 10, 585 }, + { 10, 10, 163 }, { 4, 0, 169 }, { 5, 0, 83 }, { 6, 0, 399 }, + { 6, 0, 579 }, { 6, 0, 1513 }, { 7, 0, 692 }, { 7, 0, 846 }, + { 7, 0, 1015 }, { 7, 0, 1799 }, { 8, 0, 403 }, { 9, 0, 394 }, + { 10, 0, 133 }, { 12, 0, 4 }, { 12, 0, 297 }, { 12, 0, 452 }, + { 16, 0, 81 }, { 18, 0, 25 }, { 21, 0, 14 }, { 22, 0, 12 }, + { 23, 0, 18 }, { 6, 0, 1106 }, { 7, 0, 1546 }, { 11, 0, 299 }, + { 14, 0, 407 }, { 6, 0, 1192 }, { 4, 0, 177 }, { 5, 0, 411 }, + { 7, 0, 653 }, { 7, 0, 439 }, { 10, 0, 727 }, { 11, 0, 260 }, + { 11, 0, 684 }, { 10, 10, 145 }, { 19, 10, 83 }, { 5, 0, 208 }, + { 7, 0, 753 }, { 7, 0, 1528 }, { 9, 11, 617 }, { 7, 10, 1922 }, + { 7, 11, 825 }, { 11, 0, 422 }, { 13, 0, 389 }, { 4, 10, 124 }, + { 10, 10, 457 }, { 11, 10, 121 }, { 11, 10, 169 }, { 11, 10, 870 }, + { 12, 10, 214 }, { 14, 10, 187 }, { 15, 10, 77 }, { 11, 0, 615 }, + { 15, 0, 58 }, { 11, 11, 615 }, { 15, 11, 58 }, { 9, 0, 618 }, + { 10, 0, 482 }, { 6, 0, 1952 }, { 6, 0, 1970 }, { 14, 0, 505 }, + { 7, 10, 1193 }, { 7, 11, 1838 }, { 5, 0, 242 }, { 7, 10, 1333 }, + { 6, 10, 107 }, { 7, 10, 638 }, { 7, 10, 1632 }, { 9, 10, 396 }, + { 5, 0, 953 }, { 5, 10, 370 }, { 6, 10, 1756 }, { 5, 11, 28 }, + { 6, 11, 204 }, { 10, 11, 320 }, { 10, 11, 583 }, { 13, 11, 502 }, + { 14, 11, 72 }, { 14, 11, 274 }, { 14, 11, 312 }, { 14, 11, 344 }, + { 15, 11, 159 }, { 16, 11, 62 }, { 16, 11, 69 }, { 17, 11, 30 }, + { 18, 11, 42 }, { 18, 11, 53 }, { 18, 11, 84 }, { 18, 11, 140 }, + { 19, 11, 68 }, { 19, 11, 85 }, { 20, 11, 5 }, { 20, 11, 45 }, + { 20, 11, 101 }, { 22, 11, 7 }, { 22, 11, 20 }, { 4, 11, 558 }, + { 6, 11, 390 }, { 7, 11, 162 }, { 7, 11, 689 }, { 9, 11, 360 }, + { 10, 11, 653 }, { 11, 0, 802 }, { 13, 0, 67 }, { 5, 10, 204 }, + { 5, 0, 290 }, { 5, 10, 970 }, { 6, 10, 1706 }, { 4, 0, 380 }, + { 5, 0, 52 }, { 7, 0, 277 }, { 9, 0, 368 }, { 11, 0, 791 }, + { 5, 11, 856 }, { 6, 11, 1672 }, { 6, 11, 1757 }, { 6, 11, 1781 }, + { 7, 11, 1150 }, { 7, 11, 1425 }, { 7, 11, 1453 }, { 12, 11, 513 }, + { 5, 11, 92 }, { 7, 10, 3 }, { 10, 11, 736 }, { 12, 11, 102 }, + { 4, 0, 112 }, { 5, 0, 653 }, { 5, 10, 483 }, { 5, 10, 685 }, + { 6, 10, 489 }, { 7, 10, 1204 }, { 8, 10, 394 }, { 4, 10, 921 }, + { 6, 0, 1028 }, { 5, 10, 1007 }, { 5, 11, 590 }, { 9, 11, 213 }, + { 17, 11, 91 }, { 7, 10, 1696 }, { 10, 0, 138 }, { 11, 0, 476 }, + { 5, 0, 725 }, { 5, 0, 727 }, { 7, 0, 1811 }, { 4, 0, 979 }, + { 6, 0, 1821 }, { 6, 0, 1838 }, { 8, 0, 876 }, { 8, 0, 883 }, + { 8, 0, 889 }, { 8, 0, 893 }, { 8, 0, 895 }, { 10, 0, 934 }, + { 12, 0, 720 }, { 14, 0, 459 }, { 20, 0, 123 }, { 7, 11, 551 }, + { 4, 0, 38 }, { 6, 0, 435 }, { 7, 0, 307 }, { 7, 0, 999 }, + { 7, 0, 1481 }, { 7, 0, 1732 }, { 7, 0, 1738 }, { 8, 0, 371 }, + { 9, 0, 414 }, { 11, 0, 316 }, { 12, 0, 52 }, { 13, 0, 420 }, + { 19, 0, 100 }, { 7, 0, 1296 }, { 4, 10, 712 }, { 6, 10, 1629 }, + { 5, 0, 723 }, { 6, 0, 651 }, { 8, 11, 191 }, { 9, 11, 791 }, + { 10, 11, 93 }, { 11, 11, 301 }, { 16, 11, 13 }, { 17, 11, 23 }, + { 18, 11, 135 }, { 19, 11, 12 }, { 20, 11, 1 }, { 20, 11, 12 }, + { 20, 11, 14 }, { 8, 11, 503 }, { 6, 11, 466 }, { 7, 11, 671 }, + { 6, 0, 1200 }, { 6, 0, 1330 }, { 7, 0, 1255 }, { 6, 0, 986 }, + { 5, 0, 109 }, { 6, 0, 1784 }, { 7, 0, 1895 }, { 12, 0, 296 }, + { 12, 0, 302 }, { 7, 11, 983 }, { 5, 10, 485 }, { 6, 0, 660 }, + { 6, 0, 800 }, { 5, 0, 216 }, { 5, 0, 294 }, { 6, 0, 591 }, + { 7, 0, 1879 }, { 9, 0, 141 }, { 9, 0, 270 }, { 9, 0, 679 }, + { 10, 0, 159 }, { 11, 0, 197 }, { 11, 0, 438 }, { 12, 0, 538 }, + { 12, 0, 559 }, { 14, 0, 144 }, { 14, 0, 167 }, { 15, 0, 67 }, + { 4, 10, 285 }, { 5, 10, 317 }, { 6, 10, 301 }, { 7, 10, 7 }, + { 8, 10, 153 }, { 10, 10, 766 }, { 11, 10, 468 }, { 12, 10, 467 }, + { 13, 10, 143 }, { 8, 0, 945 }, { 6, 0, 1090 }, { 9, 0, 81 }, + { 12, 11, 468 }, { 19, 11, 96 }, { 20, 11, 24 }, { 6, 0, 391 }, + { 10, 11, 241 }, { 7, 0, 322 }, { 8, 0, 249 }, { 6, 0, 1412 }, + { 7, 11, 795 }, { 5, 0, 632 }, { 10, 0, 526 }, { 8, 10, 819 }, + { 6, 0, 144 }, { 7, 0, 948 }, { 7, 0, 1042 }, { 8, 0, 235 }, + { 8, 0, 461 }, { 9, 0, 453 }, { 9, 0, 796 }, { 10, 0, 354 }, + { 17, 0, 77 }, { 7, 11, 954 }, { 11, 10, 917 }, { 6, 0, 940 }, + { 6, 0, 1228 }, { 4, 0, 362 }, { 7, 0, 52 }, { 7, 0, 303 }, + { 6, 11, 549 }, { 8, 11, 34 }, { 8, 11, 283 }, { 9, 11, 165 }, + { 10, 11, 475 }, { 7, 11, 370 }, { 7, 11, 1007 }, { 7, 11, 1177 }, + { 7, 11, 1565 }, { 5, 11, 652 }, { 5, 11, 701 }, { 7, 11, 449 }, + { 5, 0, 196 }, { 6, 0, 486 }, { 7, 0, 212 }, { 8, 0, 309 }, + { 8, 0, 346 }, { 6, 10, 1719 }, { 6, 10, 1735 }, { 7, 10, 2016 }, + { 7, 10, 2020 }, { 8, 10, 837 }, { 9, 10, 852 }, { 6, 11, 159 }, + { 6, 11, 364 }, { 7, 11, 516 }, { 7, 11, 1439 }, { 9, 11, 518 }, + { 7, 0, 1912 }, { 7, 0, 1290 }, { 4, 0, 686 }, { 13, 11, 151 }, + { 10, 0, 625 }, { 8, 0, 706 }, { 10, 10, 568 }, { 11, 0, 412 }, + { 4, 0, 30 }, { 5, 0, 43 }, { 8, 10, 67 }, { 10, 10, 419 }, + { 7, 0, 967 }, { 13, 0, 11 }, { 12, 0, 758 }, { 14, 0, 441 }, + { 14, 0, 462 }, { 10, 10, 657 }, { 14, 10, 297 }, { 14, 10, 361 }, + { 11, 10, 729 }, { 4, 0, 220 }, { 7, 0, 1535 }, { 7, 11, 501 }, + { 9, 11, 111 }, { 10, 11, 141 }, { 11, 11, 332 }, { 13, 11, 43 }, + { 13, 11, 429 }, { 14, 11, 130 }, { 14, 11, 415 }, { 17, 11, 102 }, + { 4, 0, 950 }, { 6, 0, 1859 }, { 7, 0, 11 }, { 8, 0, 873 }, + { 12, 0, 710 }, { 12, 0, 718 }, { 12, 0, 748 }, { 12, 0, 765 }, + { 20, 0, 124 }, { 5, 11, 149 }, { 5, 11, 935 }, { 8, 11, 233 }, + { 14, 11, 291 }, { 6, 0, 1579 }, { 7, 0, 890 }, { 8, 10, 51 }, + { 9, 10, 868 }, { 10, 10, 833 }, { 12, 10, 481 }, { 12, 10, 570 }, + { 20, 10, 106 }, { 13, 0, 2 }, { 4, 10, 445 }, { 8, 11, 801 }, + { 7, 0, 1774 }, { 7, 0, 1725 }, { 10, 0, 393 }, { 5, 0, 263 }, + { 6, 0, 414 }, { 4, 11, 322 }, { 5, 10, 239 }, { 7, 0, 456 }, + { 7, 10, 1990 }, { 8, 10, 130 }, { 11, 10, 720 }, { 9, 0, 818 }, + { 5, 10, 123 }, { 6, 10, 530 }, { 7, 10, 348 }, { 7, 10, 1419 }, + { 7, 10, 2024 }, { 6, 0, 178 }, { 6, 0, 1750 }, { 8, 0, 251 }, + { 9, 0, 690 }, { 10, 0, 155 }, { 10, 0, 196 }, { 10, 0, 373 }, + { 11, 0, 698 }, { 13, 0, 155 }, { 20, 0, 93 }, { 5, 0, 97 }, + { 9, 0, 393 }, { 6, 0, 674 }, { 11, 0, 223 }, { 12, 0, 168 }, + { 4, 10, 210 }, { 11, 11, 464 }, { 6, 0, 1639 }, { 18, 0, 159 }, + { 11, 11, 2 }, { 7, 0, 934 }, { 8, 0, 647 }, { 17, 0, 97 }, + { 19, 0, 59 }, { 22, 0, 2 }, { 4, 0, 191 }, { 5, 0, 165 }, + { 9, 0, 346 }, { 10, 0, 655 }, { 11, 0, 885 }, { 4, 10, 430 }, + { 7, 11, 357 }, { 5, 0, 877 }, { 5, 10, 213 }, { 5, 11, 406 }, + { 8, 0, 128 }, { 11, 0, 179 }, { 6, 11, 69 }, { 7, 11, 117 }, + { 7, 0, 1297 }, { 11, 11, 43 }, { 13, 11, 72 }, { 13, 11, 142 }, + { 7, 11, 1830 }, { 14, 0, 164 }, { 5, 0, 57 }, { 6, 0, 101 }, + { 6, 0, 586 }, { 6, 0, 1663 }, { 7, 0, 132 }, { 7, 0, 1154 }, + { 7, 0, 1415 }, { 7, 0, 1507 }, { 12, 0, 493 }, { 15, 0, 105 }, + { 23, 0, 15 }, { 5, 0, 459 }, { 7, 0, 1073 }, { 8, 0, 241 }, + { 8, 0, 334 }, { 5, 11, 826 }, { 5, 10, 108 }, { 5, 10, 219 }, + { 10, 11, 132 }, { 11, 11, 191 }, { 11, 11, 358 }, { 11, 11, 460 }, + { 6, 0, 324 }, { 6, 0, 520 }, { 7, 0, 338 }, { 7, 0, 1729 }, + { 8, 0, 228 }, { 11, 0, 750 }, { 21, 0, 30 }, { 22, 0, 53 }, + { 4, 10, 193 }, { 5, 10, 916 }, { 7, 10, 364 }, { 10, 10, 398 }, + { 10, 10, 726 }, { 11, 10, 317 }, { 11, 10, 626 }, { 12, 10, 142 }, + { 12, 10, 288 }, { 12, 10, 678 }, { 13, 10, 313 }, { 15, 10, 113 }, + { 18, 10, 114 }, { 6, 11, 110 }, { 7, 11, 1681 }, { 7, 0, 910 }, + { 6, 10, 241 }, { 7, 10, 907 }, { 8, 10, 832 }, { 9, 10, 342 }, + { 10, 10, 729 }, { 11, 10, 284 }, { 11, 10, 445 }, { 11, 10, 651 }, + { 11, 10, 863 }, { 13, 10, 398 }, { 18, 10, 99 }, { 7, 0, 705 }, + { 9, 0, 734 }, { 5, 11, 1000 }, { 7, 11, 733 }, { 9, 11, 583 }, + { 4, 0, 73 }, { 6, 0, 612 }, { 7, 0, 927 }, { 7, 0, 1822 }, + { 8, 0, 217 }, { 9, 0, 765 }, { 9, 0, 766 }, { 10, 0, 408 }, + { 11, 0, 51 }, { 11, 0, 793 }, { 12, 0, 266 }, { 15, 0, 158 }, + { 20, 0, 89 }, { 22, 0, 32 }, { 7, 0, 1330 }, { 4, 11, 297 }, + { 6, 11, 529 }, { 7, 11, 152 }, { 7, 11, 713 }, { 7, 11, 1845 }, + { 8, 11, 710 }, { 8, 11, 717 }, { 12, 11, 639 }, { 5, 0, 389 }, + { 8, 0, 636 }, { 6, 0, 1409 }, { 4, 10, 562 }, { 9, 10, 254 }, + { 11, 10, 879 }, { 6, 0, 893 }, { 4, 10, 786 }, { 4, 11, 520 }, + { 7, 11, 575 }, { 8, 0, 21 }, { 12, 0, 721 }, { 8, 0, 959 }, + { 7, 11, 1428 }, { 7, 11, 1640 }, { 9, 11, 169 }, { 9, 11, 182 }, + { 9, 11, 367 }, { 9, 11, 478 }, { 9, 11, 506 }, { 9, 11, 551 }, + { 9, 11, 648 }, { 9, 11, 651 }, { 9, 11, 697 }, { 9, 11, 705 }, + { 9, 11, 725 }, { 9, 11, 787 }, { 9, 11, 794 }, { 10, 11, 198 }, + { 10, 11, 214 }, { 10, 11, 267 }, { 10, 11, 275 }, { 10, 11, 456 }, + { 10, 11, 551 }, { 10, 11, 561 }, { 10, 11, 613 }, { 10, 11, 627 }, + { 10, 11, 668 }, { 10, 11, 675 }, { 10, 11, 691 }, { 10, 11, 695 }, + { 10, 11, 707 }, { 10, 11, 715 }, { 11, 11, 183 }, { 11, 11, 201 }, + { 11, 11, 244 }, { 11, 11, 262 }, { 11, 11, 352 }, { 11, 11, 439 }, + { 11, 11, 493 }, { 11, 11, 572 }, { 11, 11, 591 }, { 11, 11, 608 }, + { 11, 11, 611 }, { 11, 11, 646 }, { 11, 11, 674 }, { 11, 11, 711 }, + { 11, 11, 751 }, { 11, 11, 761 }, { 11, 11, 776 }, { 11, 11, 785 }, + { 11, 11, 850 }, { 11, 11, 853 }, { 11, 11, 862 }, { 11, 11, 865 }, + { 11, 11, 868 }, { 11, 11, 898 }, { 11, 11, 902 }, { 11, 11, 903 }, + { 11, 11, 910 }, { 11, 11, 932 }, { 11, 11, 942 }, { 11, 11, 957 }, + { 11, 11, 967 }, { 11, 11, 972 }, { 12, 11, 148 }, { 12, 11, 195 }, + { 12, 11, 220 }, { 12, 11, 237 }, { 12, 11, 318 }, { 12, 11, 339 }, + { 12, 11, 393 }, { 12, 11, 445 }, { 12, 11, 450 }, { 12, 11, 474 }, + { 12, 11, 509 }, { 12, 11, 533 }, { 12, 11, 591 }, { 12, 11, 594 }, + { 12, 11, 597 }, { 12, 11, 621 }, { 12, 11, 633 }, { 12, 11, 642 }, + { 13, 11, 59 }, { 13, 11, 60 }, { 13, 11, 145 }, { 13, 11, 239 }, + { 13, 11, 250 }, { 13, 11, 273 }, { 13, 11, 329 }, { 13, 11, 344 }, + { 13, 11, 365 }, { 13, 11, 372 }, { 13, 11, 387 }, { 13, 11, 403 }, + { 13, 11, 414 }, { 13, 11, 456 }, { 13, 11, 478 }, { 13, 11, 483 }, + { 13, 11, 489 }, { 14, 11, 55 }, { 14, 11, 57 }, { 14, 11, 81 }, + { 14, 11, 90 }, { 14, 11, 148 }, { 14, 11, 239 }, { 14, 11, 266 }, + { 14, 11, 321 }, { 14, 11, 326 }, { 14, 11, 327 }, { 14, 11, 330 }, + { 14, 11, 347 }, { 14, 11, 355 }, { 14, 11, 401 }, { 14, 11, 411 }, + { 14, 11, 414 }, { 14, 11, 416 }, { 14, 11, 420 }, { 15, 11, 61 }, + { 15, 11, 74 }, { 15, 11, 87 }, { 15, 11, 88 }, { 15, 11, 94 }, + { 15, 11, 96 }, { 15, 11, 116 }, { 15, 11, 149 }, { 15, 11, 154 }, + { 16, 11, 50 }, { 16, 11, 63 }, { 16, 11, 73 }, { 17, 11, 2 }, + { 17, 11, 66 }, { 17, 11, 92 }, { 17, 11, 103 }, { 17, 11, 112 }, + { 18, 11, 50 }, { 18, 11, 54 }, { 18, 11, 82 }, { 18, 11, 86 }, + { 18, 11, 90 }, { 18, 11, 111 }, { 18, 11, 115 }, { 18, 11, 156 }, + { 19, 11, 40 }, { 19, 11, 79 }, { 20, 11, 78 }, { 21, 11, 22 }, + { 9, 11, 170 }, { 6, 0, 1433 }, { 7, 11, 1307 }, { 11, 11, 411 }, + { 5, 0, 189 }, { 7, 0, 442 }, { 7, 0, 443 }, { 8, 0, 281 }, + { 12, 0, 174 }, { 13, 0, 261 }, { 6, 10, 216 }, { 7, 10, 901 }, + { 7, 10, 1343 }, { 8, 10, 493 }, { 5, 11, 397 }, { 6, 11, 154 }, + { 7, 10, 341 }, { 7, 11, 676 }, { 8, 11, 443 }, { 8, 11, 609 }, + { 9, 11, 24 }, { 9, 11, 325 }, { 10, 11, 35 }, { 11, 10, 219 }, + { 11, 11, 535 }, { 11, 11, 672 }, { 11, 11, 1018 }, { 12, 11, 637 }, + { 16, 11, 30 }, { 6, 0, 2 }, { 7, 0, 191 }, { 7, 0, 446 }, + { 7, 0, 1262 }, { 7, 0, 1737 }, { 8, 0, 22 }, { 8, 0, 270 }, + { 8, 0, 612 }, { 9, 0, 4 }, { 9, 0, 312 }, { 9, 0, 436 }, + { 9, 0, 626 }, { 10, 0, 216 }, { 10, 0, 311 }, { 10, 0, 521 }, + { 10, 0, 623 }, { 11, 0, 72 }, { 11, 0, 330 }, { 11, 0, 455 }, + { 12, 0, 321 }, { 12, 0, 504 }, { 12, 0, 530 }, { 12, 0, 543 }, + { 13, 0, 17 }, { 13, 0, 156 }, { 13, 0, 334 }, { 14, 0, 131 }, + { 17, 0, 60 }, { 20, 0, 64 }, { 7, 0, 354 }, { 10, 0, 410 }, + { 11, 0, 815 }, { 11, 10, 130 }, { 7, 10, 1734 }, { 9, 11, 631 }, + { 12, 0, 425 }, { 15, 0, 112 }, { 10, 10, 115 }, { 11, 10, 420 }, + { 13, 10, 404 }, { 14, 10, 346 }, { 15, 10, 54 }, { 6, 0, 60 }, + { 6, 0, 166 }, { 7, 0, 374 }, { 7, 0, 670 }, { 7, 0, 1327 }, + { 8, 0, 411 }, { 8, 0, 435 }, { 9, 0, 653 }, { 9, 0, 740 }, + { 10, 0, 385 }, { 11, 0, 222 }, { 11, 0, 324 }, { 11, 0, 829 }, + { 12, 0, 611 }, { 7, 0, 1611 }, { 13, 0, 14 }, { 15, 0, 44 }, + { 19, 0, 13 }, { 20, 0, 76 }, { 5, 11, 981 }, { 4, 11, 56 }, + { 7, 11, 1791 }, { 8, 11, 607 }, { 8, 11, 651 }, { 11, 11, 465 }, + { 11, 11, 835 }, { 12, 11, 337 }, { 13, 11, 480 }, { 6, 0, 1478 }, + { 5, 10, 1011 }, { 8, 10, 701 }, { 11, 0, 596 }, { 5, 0, 206 }, + { 6, 0, 398 }, { 4, 10, 54 }, { 5, 10, 666 }, { 7, 10, 1039 }, + { 7, 10, 1130 }, { 9, 10, 195 }, { 10, 10, 302 }, { 7, 0, 50 }, + { 9, 11, 158 }, { 10, 11, 411 }, { 7, 11, 1120 }, { 6, 0, 517 }, + { 7, 0, 1159 }, { 10, 0, 621 }, { 11, 0, 192 }, { 6, 10, 1669 }, + { 4, 0, 592 }, { 6, 0, 600 }, { 7, 0, 1653 }, { 10, 0, 223 }, + { 11, 0, 645 }, { 8, 11, 139 }, { 7, 0, 64 }, { 8, 0, 245 }, + { 14, 0, 278 }, { 6, 11, 622 }, { 7, 11, 1030 }, { 8, 0, 604 }, + { 6, 0, 1502 }, { 10, 0, 265 }, { 13, 11, 168 }, { 7, 0, 1763 }, + { 12, 0, 310 }, { 7, 10, 798 }, { 11, 11, 719 }, { 7, 11, 160 }, + { 10, 11, 624 }, { 14, 11, 279 }, { 4, 11, 363 }, { 7, 10, 122 }, + { 9, 10, 259 }, { 10, 10, 84 }, { 11, 10, 470 }, { 12, 10, 541 }, + { 13, 10, 379 }, { 5, 0, 129 }, { 6, 0, 61 }, { 7, 0, 947 }, + { 6, 0, 1356 }, { 7, 11, 1191 }, { 13, 0, 505 }, { 13, 0, 506 }, + { 11, 0, 1000 }, { 5, 10, 82 }, { 5, 10, 131 }, { 7, 10, 1755 }, + { 8, 10, 31 }, { 9, 10, 168 }, { 9, 10, 764 }, { 11, 10, 869 }, + { 6, 0, 966 }, { 6, 10, 605 }, { 6, 11, 292 }, { 5, 11, 177 }, + { 6, 11, 616 }, { 7, 11, 827 }, { 9, 11, 525 }, { 10, 11, 656 }, + { 7, 11, 1486 }, { 10, 11, 31 }, { 5, 10, 278 }, { 9, 10, 68 }, + { 4, 10, 163 }, { 5, 10, 201 }, { 5, 10, 307 }, { 5, 10, 310 }, + { 6, 10, 335 }, { 7, 10, 284 }, { 8, 10, 165 }, { 6, 0, 839 }, + { 7, 10, 1660 }, { 8, 10, 781 }, { 6, 10, 33 }, { 7, 10, 1244 }, + { 5, 0, 637 }, { 4, 11, 161 }, { 5, 11, 631 }, { 9, 0, 590 }, + { 7, 10, 1953 }, { 8, 10, 720 }, { 5, 0, 280 }, { 7, 0, 1226 }, + { 10, 10, 203 }, { 6, 0, 1386 }, { 5, 0, 281 }, { 6, 0, 1026 }, + { 6, 10, 326 }, { 7, 10, 677 }, { 9, 10, 425 }, { 7, 11, 1557 }, + { 7, 11, 1684 }, { 7, 0, 1064 }, { 9, 11, 469 }, { 9, 11, 709 }, + { 12, 11, 512 }, { 14, 11, 65 }, { 17, 11, 12 }, { 6, 0, 917 }, + { 10, 11, 229 }, { 11, 11, 73 }, { 11, 11, 376 }, { 11, 11, 433 }, + { 7, 0, 555 }, { 9, 0, 192 }, { 13, 0, 30 }, { 13, 0, 49 }, + { 15, 0, 150 }, { 16, 0, 76 }, { 20, 0, 52 }, { 7, 10, 1316 }, + { 7, 10, 1412 }, { 7, 10, 1839 }, { 9, 10, 589 }, { 11, 10, 241 }, + { 11, 10, 676 }, { 11, 10, 811 }, { 11, 10, 891 }, { 12, 10, 140 }, + { 12, 10, 346 }, { 12, 10, 479 }, { 13, 10, 381 }, { 14, 10, 188 }, + { 18, 10, 30 }, { 21, 0, 15 }, { 6, 0, 1882 }, { 6, 0, 1883 }, + { 6, 0, 1897 }, { 9, 0, 945 }, { 9, 0, 1014 }, { 9, 0, 1020 }, + { 12, 0, 823 }, { 12, 0, 842 }, { 12, 0, 866 }, { 12, 0, 934 }, + { 15, 0, 242 }, { 18, 0, 208 }, { 6, 0, 965 }, { 6, 0, 1499 }, + { 7, 0, 33 }, { 7, 0, 120 }, { 8, 0, 489 }, { 9, 0, 319 }, + { 10, 0, 820 }, { 11, 0, 1004 }, { 12, 0, 379 }, { 12, 0, 679 }, + { 13, 0, 117 }, { 13, 0, 412 }, { 14, 0, 25 }, { 15, 0, 52 }, + { 15, 0, 161 }, { 16, 0, 47 }, { 21, 0, 2 }, { 6, 11, 558 }, + { 7, 11, 651 }, { 8, 11, 421 }, { 9, 11, 0 }, { 10, 11, 34 }, + { 4, 0, 937 }, { 5, 0, 801 }, { 7, 0, 473 }, { 5, 10, 358 }, + { 7, 10, 1184 }, { 10, 10, 662 }, { 13, 10, 212 }, { 13, 10, 304 }, + { 13, 10, 333 }, { 17, 10, 98 }, { 4, 0, 877 }, { 6, 0, 693 }, + { 6, 0, 824 }, { 4, 0, 365 }, { 7, 11, 1832 }, { 10, 11, 374 }, + { 5, 0, 7 }, { 11, 0, 774 }, { 4, 0, 734 }, { 5, 0, 662 }, + { 6, 0, 430 }, { 4, 0, 746 }, { 7, 0, 1090 }, { 5, 0, 360 }, + { 8, 0, 237 }, { 10, 0, 231 }, { 19, 0, 124 }, { 10, 11, 348 }, + { 6, 11, 6 }, { 7, 11, 81 }, { 7, 11, 771 }, { 7, 11, 1731 }, + { 9, 11, 405 }, { 10, 11, 421 }, { 6, 0, 740 }, { 9, 0, 822 }, + { 5, 10, 946 }, { 7, 0, 1485 }, { 8, 0, 929 }, { 7, 10, 411 }, + { 8, 10, 631 }, { 9, 10, 323 }, { 10, 10, 355 }, { 11, 10, 491 }, + { 12, 10, 143 }, { 12, 10, 402 }, { 13, 10, 73 }, { 14, 10, 408 }, + { 15, 10, 107 }, { 18, 10, 71 }, { 7, 10, 590 }, { 5, 11, 881 }, + { 5, 11, 885 }, { 22, 11, 25 }, { 4, 0, 852 }, { 5, 11, 142 }, + { 6, 11, 546 }, { 7, 10, 1467 }, { 8, 10, 328 }, { 10, 10, 544 }, + { 11, 10, 955 }, { 13, 10, 320 }, { 17, 10, 83 }, { 9, 0, 17 }, + { 10, 0, 291 }, { 11, 10, 511 }, { 13, 10, 394 }, { 14, 10, 298 }, + { 14, 10, 318 }, { 18, 10, 103 }, { 5, 11, 466 }, { 11, 11, 571 }, + { 12, 11, 198 }, { 13, 11, 283 }, { 14, 11, 186 }, { 15, 11, 21 }, + { 15, 11, 103 }, { 6, 0, 1001 }, { 4, 11, 185 }, { 5, 11, 257 }, + { 5, 11, 839 }, { 5, 11, 936 }, { 7, 11, 171 }, { 9, 11, 399 }, + { 10, 11, 258 }, { 10, 11, 395 }, { 10, 11, 734 }, { 11, 11, 1014 }, + { 12, 11, 23 }, { 13, 11, 350 }, { 14, 11, 150 }, { 19, 11, 6 }, + { 15, 0, 35 }, { 4, 0, 831 }, { 5, 10, 835 }, { 6, 10, 483 }, + { 4, 0, 277 }, { 5, 0, 608 }, { 6, 0, 493 }, { 7, 0, 457 }, + { 12, 0, 384 }, { 7, 11, 404 }, { 7, 11, 1377 }, { 7, 11, 1430 }, + { 7, 11, 2017 }, { 8, 11, 149 }, { 8, 11, 239 }, { 8, 11, 512 }, + { 8, 11, 793 }, { 8, 11, 818 }, { 9, 11, 474 }, { 9, 11, 595 }, + { 10, 11, 122 }, { 10, 11, 565 }, { 10, 11, 649 }, { 10, 11, 783 }, + { 11, 11, 239 }, { 11, 11, 295 }, { 11, 11, 447 }, { 11, 11, 528 }, + { 11, 11, 639 }, { 11, 11, 800 }, { 11, 11, 936 }, { 12, 11, 25 }, + { 12, 11, 73 }, { 12, 11, 77 }, { 12, 11, 157 }, { 12, 11, 316 }, + { 12, 11, 390 }, { 12, 11, 391 }, { 12, 11, 394 }, { 12, 11, 395 }, + { 12, 11, 478 }, { 12, 11, 503 }, { 12, 11, 592 }, { 12, 11, 680 }, + { 13, 11, 50 }, { 13, 11, 53 }, { 13, 11, 132 }, { 13, 11, 198 }, + { 13, 11, 275 }, { 13, 11, 322 }, { 13, 11, 415 }, { 14, 11, 71 }, + { 14, 11, 257 }, { 14, 11, 395 }, { 15, 11, 71 }, { 15, 11, 136 }, + { 17, 11, 123 }, { 18, 11, 93 }, { 19, 11, 58 }, { 6, 0, 1351 }, + { 7, 0, 27 }, { 7, 0, 316 }, { 8, 11, 712 }, { 8, 0, 984 }, + { 5, 0, 552 }, { 9, 0, 264 }, { 4, 0, 401 }, { 6, 0, 710 }, + { 6, 0, 1111 }, { 6, 0, 1343 }, { 6, 0, 1211 }, { 9, 0, 543 }, + { 10, 0, 524 }, { 11, 0, 108 }, { 11, 0, 653 }, { 12, 0, 524 }, + { 13, 0, 123 }, { 14, 0, 252 }, { 16, 0, 18 }, { 19, 0, 38 }, + { 20, 0, 26 }, { 20, 0, 65 }, { 21, 0, 3 }, { 23, 0, 11 }, + { 4, 0, 205 }, { 5, 0, 623 }, { 7, 0, 104 }, { 8, 0, 519 }, + { 9, 0, 716 }, { 4, 10, 677 }, { 4, 11, 377 }, { 24, 11, 13 }, + { 7, 11, 1673 }, { 7, 0, 579 }, { 9, 0, 41 }, { 9, 0, 244 }, + { 9, 0, 669 }, { 10, 0, 5 }, { 11, 0, 861 }, { 11, 0, 951 }, + { 11, 0, 980 }, { 4, 0, 717 }, { 8, 0, 1011 }, { 4, 0, 805 }, + { 4, 11, 180 }, { 7, 11, 1906 }, { 4, 10, 777 }, { 4, 10, 331 }, + { 4, 0, 489 }, { 6, 0, 1024 }, { 4, 11, 491 }, { 5, 10, 747 }, + { 7, 11, 1182 }, { 4, 11, 171 }, { 10, 11, 234 }, { 4, 11, 586 }, + { 7, 11, 1186 }, { 10, 11, 631 }, { 7, 0, 892 }, { 7, 11, 336 }, + { 9, 11, 931 }, { 10, 11, 334 }, { 20, 11, 71 }, { 9, 0, 473 }, + { 6, 0, 864 }, { 12, 0, 659 }, { 11, 11, 926 }, { 7, 0, 819 }, + { 9, 0, 26 }, { 9, 0, 392 }, { 10, 0, 152 }, { 10, 0, 226 }, + { 11, 0, 19 }, { 12, 0, 276 }, { 12, 0, 426 }, { 12, 0, 589 }, + { 13, 0, 460 }, { 15, 0, 97 }, { 19, 0, 48 }, { 20, 0, 104 }, + { 7, 0, 51 }, { 5, 10, 326 }, { 4, 10, 691 }, { 18, 10, 16 }, + { 9, 0, 130 }, { 11, 0, 765 }, { 10, 10, 680 }, { 10, 10, 793 }, + { 13, 10, 357 }, { 5, 11, 765 }, { 8, 0, 229 }, { 6, 10, 32 }, + { 7, 10, 385 }, { 7, 10, 757 }, { 7, 10, 1916 }, { 8, 10, 94 }, + { 8, 10, 711 }, { 9, 10, 541 }, { 10, 10, 162 }, { 10, 10, 795 }, + { 11, 10, 989 }, { 11, 10, 1010 }, { 12, 10, 14 }, { 14, 10, 308 }, + { 7, 11, 474 }, { 9, 11, 578 }, { 4, 0, 674 }, { 4, 0, 770 }, + { 5, 0, 79 }, { 7, 0, 1027 }, { 7, 0, 1477 }, { 11, 0, 52 }, + { 5, 11, 424 }, { 6, 0, 1666 }, { 6, 0, 409 }, { 6, 10, 349 }, + { 6, 10, 1682 }, { 7, 10, 1252 }, { 8, 10, 112 }, { 8, 11, 714 }, + { 9, 10, 435 }, { 9, 10, 668 }, { 10, 10, 290 }, { 10, 10, 319 }, + { 10, 10, 815 }, { 11, 10, 180 }, { 11, 10, 837 }, { 12, 10, 240 }, + { 13, 10, 152 }, { 13, 10, 219 }, { 14, 10, 158 }, { 5, 0, 789 }, + { 6, 0, 195 }, { 4, 0, 251 }, { 4, 0, 688 }, { 7, 0, 513 }, + { 7, 0, 1284 }, { 4, 10, 581 }, { 9, 11, 420 }, { 10, 11, 269 }, + { 10, 11, 285 }, { 10, 11, 576 }, { 11, 11, 397 }, { 13, 11, 175 }, + { 17, 11, 90 }, { 6, 10, 126 }, { 7, 10, 573 }, { 8, 10, 397 }, + { 14, 10, 44 }, { 4, 11, 429 }, { 5, 0, 889 }, { 4, 0, 160 }, + { 5, 0, 330 }, { 7, 0, 1434 }, { 8, 0, 174 }, { 7, 11, 18 }, + { 7, 11, 699 }, { 7, 11, 1966 }, { 8, 11, 752 }, { 9, 11, 273 }, + { 9, 11, 412 }, { 9, 11, 703 }, { 10, 11, 71 }, { 10, 11, 427 }, + { 10, 11, 508 }, { 18, 11, 97 }, { 6, 0, 872 }, { 6, 0, 899 }, + { 5, 10, 926 }, { 6, 0, 1126 }, { 6, 0, 918 }, { 4, 11, 53 }, + { 5, 11, 186 }, { 7, 11, 752 }, { 7, 0, 268 }, { 8, 0, 569 }, + { 6, 0, 1224 }, { 6, 0, 1361 }, { 7, 10, 1232 }, { 9, 10, 531 }, + { 8, 11, 575 }, { 10, 11, 289 }, { 11, 11, 319 }, { 5, 10, 670 }, + { 4, 11, 675 }, { 5, 0, 374 }, { 7, 10, 1957 }, { 5, 0, 731 }, + { 11, 0, 190 }, { 15, 0, 49 }, { 11, 11, 190 }, { 15, 11, 49 }, + { 4, 0, 626 }, { 5, 0, 506 }, { 5, 0, 642 }, { 6, 0, 425 }, + { 10, 0, 202 }, { 11, 0, 141 }, { 9, 0, 444 }, { 7, 10, 242 }, + { 7, 10, 1942 }, { 6, 11, 209 }, { 8, 11, 468 }, { 9, 11, 210 }, + { 11, 11, 36 }, { 12, 11, 28 }, { 12, 11, 630 }, { 13, 11, 21 }, + { 13, 11, 349 }, { 14, 11, 7 }, { 17, 11, 13 }, { 4, 11, 342 }, + { 7, 11, 1179 }, { 5, 10, 834 }, { 7, 10, 1202 }, { 8, 10, 14 }, + { 9, 10, 481 }, { 9, 10, 880 }, { 4, 11, 928 }, { 5, 11, 910 }, + { 4, 11, 318 }, { 4, 11, 496 }, { 7, 11, 856 }, { 11, 11, 654 }, + { 8, 0, 835 }, { 7, 0, 1526 }, { 10, 10, 465 }, { 23, 0, 17 }, + { 7, 0, 477 }, { 4, 10, 357 }, { 6, 10, 172 }, { 7, 10, 143 }, + { 9, 10, 413 }, { 6, 0, 1374 }, { 10, 0, 994 }, { 18, 0, 76 }, + { 4, 10, 590 }, { 7, 0, 287 }, { 8, 0, 355 }, { 9, 0, 293 }, + { 9, 0, 743 }, { 6, 0, 1389 }, { 7, 11, 915 }, { 8, 11, 247 }, + { 19, 11, 0 }, { 4, 11, 202 }, { 5, 11, 382 }, { 6, 11, 454 }, + { 7, 11, 936 }, { 7, 11, 1803 }, { 8, 11, 758 }, { 9, 11, 375 }, + { 9, 11, 895 }, { 10, 11, 743 }, { 10, 11, 792 }, { 11, 11, 978 }, + { 11, 11, 1012 }, { 14, 11, 109 }, { 5, 0, 384 }, { 8, 0, 455 }, + { 12, 0, 48 }, { 4, 11, 390 }, { 5, 10, 169 }, { 7, 10, 333 }, + { 8, 10, 45 }, { 5, 0, 264 }, { 6, 0, 184 }, { 10, 11, 791 }, + { 5, 11, 717 }, { 4, 10, 198 }, { 6, 11, 445 }, { 7, 11, 332 }, + { 9, 11, 909 }, { 8, 0, 1001 }, { 4, 10, 24 }, { 5, 10, 140 }, + { 5, 10, 185 }, { 7, 10, 1500 }, { 11, 10, 565 }, { 11, 10, 838 }, + { 6, 11, 578 }, { 5, 0, 633 }, { 6, 0, 28 }, { 7, 0, 1323 }, + { 4, 0, 851 }, { 8, 11, 267 }, { 7, 0, 359 }, { 8, 0, 243 }, + { 12, 0, 175 }, { 4, 10, 334 }, { 5, 10, 593 }, { 13, 11, 87 }, + { 8, 11, 766 }, { 10, 0, 287 }, { 12, 0, 138 }, { 10, 11, 287 }, + { 12, 11, 138 }, { 4, 0, 105 }, { 4, 0, 740 }, { 12, 10, 116 }, + { 6, 0, 857 }, { 7, 11, 1841 }, { 6, 0, 1402 }, { 9, 0, 819 }, + { 4, 11, 584 }, { 4, 10, 709 }, { 5, 10, 897 }, { 5, 0, 224 }, + { 13, 0, 174 }, { 18, 0, 52 }, { 7, 10, 1840 }, { 4, 10, 608 }, + { 5, 10, 497 }, { 11, 11, 60 }, { 4, 0, 758 }, { 7, 0, 1649 }, + { 4, 11, 226 }, { 4, 11, 326 }, { 7, 11, 1770 }, { 5, 11, 426 }, + { 8, 11, 30 }, { 9, 11, 2 }, { 11, 11, 549 }, { 19, 11, 122 }, + { 7, 10, 2039 }, { 6, 10, 540 }, { 8, 10, 136 }, { 4, 0, 573 }, + { 8, 0, 655 }, { 4, 10, 897 }, { 5, 10, 786 }, { 7, 0, 351 }, + { 11, 0, 128 }, { 5, 10, 999 }, { 4, 10, 299 }, { 7, 10, 1004 }, + { 5, 0, 918 }, { 4, 11, 345 }, { 4, 11, 385 }, { 7, 11, 265 }, + { 7, 11, 587 }, { 5, 10, 456 }, { 8, 10, 180 }, { 6, 0, 687 }, + { 6, 0, 1537 }, { 4, 11, 347 }, { 5, 11, 423 }, { 5, 11, 996 }, + { 7, 11, 1329 }, { 4, 10, 755 }, { 7, 11, 1259 }, { 9, 11, 125 }, + { 11, 11, 65 }, { 12, 11, 285 }, { 5, 11, 136 }, { 6, 11, 136 }, + { 8, 11, 644 }, { 6, 0, 1525 }, { 4, 0, 1009 }, { 7, 0, 1139 }, + { 11, 10, 338 }, { 4, 0, 340 }, { 7, 10, 1464 }, { 8, 0, 847 }, + { 10, 0, 861 }, { 10, 0, 876 }, { 10, 0, 889 }, { 10, 0, 922 }, + { 10, 0, 929 }, { 10, 0, 933 }, { 12, 0, 784 }, { 12, 0, 791 }, + { 11, 0, 176 }, { 9, 11, 134 }, { 10, 11, 2 }, { 10, 11, 27 }, + { 10, 11, 333 }, { 11, 11, 722 }, { 15, 11, 1 }, { 4, 11, 433 }, + { 5, 11, 719 }, { 5, 0, 985 }, { 7, 0, 509 }, { 7, 0, 529 }, + { 17, 0, 96 }, { 4, 0, 615 }, { 4, 10, 890 }, { 5, 10, 805 }, + { 5, 10, 819 }, { 5, 10, 961 }, { 6, 10, 396 }, { 6, 10, 1631 }, + { 6, 10, 1678 }, { 7, 10, 1967 }, { 7, 10, 2041 }, { 9, 10, 630 }, + { 11, 10, 8 }, { 11, 10, 1019 }, { 12, 10, 176 }, { 13, 10, 225 }, + { 14, 10, 292 }, { 21, 10, 24 }, { 7, 0, 1919 }, { 6, 0, 1131 }, + { 16, 11, 21 }, { 16, 11, 51 }, { 7, 10, 1815 }, { 4, 0, 247 }, + { 7, 10, 1505 }, { 10, 10, 190 }, { 10, 10, 634 }, { 11, 10, 792 }, + { 12, 10, 358 }, { 12, 10, 447 }, { 5, 10, 0 }, { 6, 10, 536 }, + { 7, 10, 604 }, { 13, 10, 445 }, { 17, 10, 126 }, { 4, 0, 184 }, + { 5, 0, 390 }, { 6, 0, 337 }, { 7, 0, 23 }, { 7, 0, 494 }, + { 7, 0, 618 }, { 7, 0, 1456 }, { 8, 0, 27 }, { 8, 0, 599 }, + { 10, 0, 153 }, { 11, 0, 710 }, { 6, 10, 232 }, { 6, 10, 412 }, + { 7, 10, 1074 }, { 8, 10, 9 }, { 8, 10, 157 }, { 8, 10, 786 }, + { 9, 10, 196 }, { 9, 10, 352 }, { 9, 10, 457 }, { 10, 10, 337 }, + { 11, 10, 232 }, { 11, 10, 877 }, { 12, 10, 480 }, { 12, 10, 546 }, + { 13, 0, 38 }, { 7, 10, 958 }, { 4, 10, 382 }, { 8, 10, 579 }, + { 4, 10, 212 }, { 7, 10, 1206 }, { 4, 11, 555 }, { 8, 11, 536 }, + { 10, 11, 288 }, { 11, 11, 139 }, { 11, 11, 171 }, { 9, 11, 370 }, + { 10, 11, 90 }, { 4, 0, 1015 }, { 6, 0, 1088 }, { 5, 10, 655 }, + { 7, 11, 977 }, { 6, 0, 1585 }, { 17, 10, 67 }, { 19, 10, 74 }, + { 10, 0, 227 }, { 11, 0, 497 }, { 11, 0, 709 }, { 12, 0, 415 }, + { 6, 0, 360 }, { 7, 0, 1664 }, { 8, 0, 478 }, { 7, 0, 95 }, + { 6, 10, 231 }, { 8, 10, 423 }, { 12, 11, 65 }, { 4, 11, 257 }, + { 7, 11, 2031 }, { 7, 11, 1768 }, { 5, 10, 300 }, { 11, 11, 211 }, + { 8, 0, 699 }, { 6, 10, 237 }, { 7, 10, 611 }, { 8, 10, 100 }, + { 9, 10, 416 }, { 11, 10, 335 }, { 12, 10, 173 }, { 18, 10, 101 }, + { 14, 0, 26 }, { 18, 0, 150 }, { 6, 0, 581 }, { 7, 0, 1119 }, + { 7, 10, 1208 }, { 4, 0, 739 }, { 6, 11, 83 }, { 6, 11, 1733 }, + { 7, 11, 1389 }, { 9, 0, 869 }, { 4, 0, 67 }, { 5, 0, 422 }, + { 7, 0, 1037 }, { 7, 0, 1289 }, { 7, 0, 1555 }, { 9, 0, 741 }, + { 17, 0, 108 }, { 5, 10, 199 }, { 12, 10, 427 }, { 18, 10, 38 }, + { 8, 0, 464 }, { 14, 0, 42 }, { 10, 0, 96 }, { 8, 11, 501 }, + { 9, 11, 696 }, { 6, 11, 592 }, { 4, 0, 512 }, { 4, 0, 966 }, + { 5, 0, 342 }, { 6, 0, 1855 }, { 8, 0, 869 }, { 8, 0, 875 }, + { 8, 0, 901 }, { 16, 0, 26 }, { 8, 0, 203 }, { 11, 0, 823 }, + { 11, 0, 846 }, { 12, 0, 482 }, { 13, 0, 277 }, { 13, 0, 302 }, + { 13, 0, 464 }, { 14, 0, 205 }, { 14, 0, 221 }, { 4, 0, 449 }, + { 5, 0, 718 }, { 7, 11, 1718 }, { 9, 11, 95 }, { 9, 11, 274 }, + { 10, 11, 279 }, { 10, 11, 317 }, { 10, 11, 420 }, { 11, 11, 303 }, + { 11, 11, 808 }, { 12, 11, 134 }, { 12, 11, 367 }, { 13, 11, 149 }, + { 13, 11, 347 }, { 14, 11, 349 }, { 14, 11, 406 }, { 18, 11, 22 }, + { 18, 11, 89 }, { 18, 11, 122 }, { 19, 11, 47 }, { 5, 11, 26 }, + { 4, 0, 355 }, { 6, 0, 311 }, { 9, 0, 256 }, { 10, 0, 404 }, + { 4, 11, 550 }, { 10, 0, 758 }, { 6, 10, 312 }, { 6, 10, 1715 }, + { 10, 10, 584 }, { 11, 10, 546 }, { 11, 10, 692 }, { 12, 10, 259 }, + { 12, 10, 295 }, { 13, 10, 46 }, { 13, 10, 154 }, { 8, 11, 822 }, + { 5, 0, 827 }, { 4, 11, 902 }, { 5, 11, 809 }, { 6, 11, 122 }, + { 7, 11, 896 }, { 5, 0, 64 }, { 12, 0, 581 }, { 4, 0, 442 }, + { 6, 0, 739 }, { 7, 0, 1047 }, { 7, 0, 1352 }, { 7, 0, 1643 }, + { 7, 11, 1911 }, { 9, 11, 449 }, { 10, 11, 192 }, { 10, 11, 740 }, + { 7, 11, 262 }, { 4, 10, 588 }, { 5, 11, 620 }, { 5, 0, 977 }, + { 6, 0, 288 }, { 7, 0, 528 }, { 4, 11, 34 }, { 5, 11, 574 }, + { 7, 11, 279 }, { 7, 11, 1624 }, { 8, 11, 601 }, { 6, 0, 1375 }, + { 4, 10, 231 }, { 5, 10, 61 }, { 6, 10, 104 }, { 7, 10, 729 }, + { 7, 10, 964 }, { 7, 10, 1658 }, { 12, 10, 414 }, { 6, 10, 263 }, + { 10, 10, 757 }, { 4, 10, 320 }, { 4, 0, 254 }, { 7, 0, 1309 }, + { 5, 11, 332 }, { 7, 11, 1309 }, { 6, 11, 261 }, { 8, 11, 182 }, + { 11, 11, 943 }, { 4, 10, 225 }, { 6, 0, 12 }, { 7, 0, 1219 }, + { 4, 0, 275 }, { 12, 0, 376 }, { 6, 11, 1721 }, { 13, 11, 490 }, + { 4, 11, 933 }, { 5, 11, 880 }, { 6, 0, 951 }, { 6, 0, 1109 }, + { 6, 0, 1181 }, { 7, 0, 154 }, { 4, 10, 405 }, { 7, 10, 817 }, + { 14, 10, 58 }, { 17, 10, 37 }, { 18, 10, 124 }, { 6, 0, 1520 }, + { 5, 10, 974 }, { 6, 0, 1753 }, { 6, 0, 369 }, { 6, 0, 502 }, + { 7, 0, 1036 }, { 8, 0, 348 }, { 9, 0, 452 }, { 10, 0, 26 }, + { 11, 0, 224 }, { 11, 0, 387 }, { 11, 0, 772 }, { 12, 0, 95 }, + { 12, 0, 629 }, { 13, 0, 195 }, { 13, 0, 207 }, { 13, 0, 241 }, + { 14, 0, 260 }, { 14, 0, 270 }, { 15, 0, 140 }, { 4, 0, 269 }, + { 5, 0, 480 }, { 7, 0, 532 }, { 7, 0, 1197 }, { 7, 0, 1358 }, + { 8, 0, 291 }, { 11, 0, 349 }, { 14, 0, 396 }, { 5, 10, 235 }, + { 7, 10, 1239 }, { 11, 10, 131 }, { 12, 10, 370 }, { 7, 10, 956 }, + { 7, 10, 1157 }, { 7, 10, 1506 }, { 7, 10, 1606 }, { 7, 10, 1615 }, + { 7, 10, 1619 }, { 7, 10, 1736 }, { 7, 10, 1775 }, { 8, 10, 590 }, + { 9, 10, 324 }, { 9, 10, 736 }, { 9, 10, 774 }, { 9, 10, 776 }, + { 9, 10, 784 }, { 10, 10, 567 }, { 10, 10, 708 }, { 11, 10, 518 }, + { 11, 10, 613 }, { 11, 10, 695 }, { 11, 10, 716 }, { 11, 10, 739 }, + { 11, 10, 770 }, { 11, 10, 771 }, { 11, 10, 848 }, { 11, 10, 857 }, + { 11, 10, 931 }, { 11, 10, 947 }, { 12, 10, 326 }, { 12, 10, 387 }, + { 12, 10, 484 }, { 12, 10, 528 }, { 12, 10, 552 }, { 12, 10, 613 }, + { 13, 10, 189 }, { 13, 10, 256 }, { 13, 10, 340 }, { 13, 10, 432 }, + { 13, 10, 436 }, { 13, 10, 440 }, { 13, 10, 454 }, { 14, 10, 174 }, + { 14, 10, 220 }, { 14, 10, 284 }, { 14, 10, 390 }, { 17, 10, 121 }, + { 8, 11, 598 }, { 9, 11, 664 }, { 10, 11, 441 }, { 9, 10, 137 }, + { 10, 10, 221 }, { 5, 11, 812 }, { 20, 0, 15 }, { 6, 0, 1341 }, + { 6, 0, 1017 }, { 4, 11, 137 }, { 7, 11, 1178 }, { 7, 11, 1520 }, + { 7, 10, 390 }, { 10, 10, 140 }, { 7, 11, 1260 }, { 7, 11, 1790 }, + { 9, 11, 191 }, { 7, 10, 1144 }, { 6, 0, 1810 }, { 7, 0, 657 }, + { 8, 0, 886 }, { 10, 0, 857 }, { 14, 0, 440 }, { 16, 0, 96 }, + { 8, 0, 533 }, { 6, 11, 1661 }, { 7, 11, 1975 }, { 7, 11, 2009 }, + { 7, 11, 2011 }, { 6, 0, 1453 }, { 6, 10, 464 }, { 4, 11, 715 }, + { 5, 10, 407 }, { 11, 10, 204 }, { 11, 10, 243 }, { 11, 10, 489 }, + { 12, 10, 293 }, { 19, 10, 37 }, { 20, 10, 73 }, { 22, 10, 38 }, + { 5, 11, 703 }, { 4, 0, 211 }, { 7, 0, 1483 }, { 5, 10, 325 }, + { 8, 10, 5 }, { 8, 10, 227 }, { 9, 10, 105 }, { 10, 10, 585 }, + { 12, 10, 614 }, { 4, 0, 332 }, { 5, 0, 335 }, { 6, 0, 238 }, + { 7, 0, 269 }, { 7, 0, 811 }, { 7, 0, 1797 }, { 8, 0, 836 }, + { 9, 0, 507 }, { 13, 0, 242 }, { 5, 11, 89 }, { 7, 11, 1915 }, + { 9, 11, 185 }, { 9, 11, 235 }, { 9, 11, 496 }, { 10, 11, 64 }, + { 10, 11, 270 }, { 10, 11, 403 }, { 10, 11, 469 }, { 10, 11, 529 }, + { 10, 11, 590 }, { 11, 11, 140 }, { 11, 11, 860 }, { 13, 11, 1 }, + { 13, 11, 422 }, { 14, 11, 341 }, { 14, 11, 364 }, { 17, 11, 93 }, + { 18, 11, 113 }, { 19, 11, 97 }, { 19, 11, 113 }, { 5, 11, 695 }, + { 16, 0, 19 }, { 5, 11, 6 }, { 6, 11, 183 }, { 6, 10, 621 }, + { 7, 11, 680 }, { 7, 11, 978 }, { 7, 11, 1013 }, { 7, 11, 1055 }, + { 12, 11, 230 }, { 13, 11, 172 }, { 13, 10, 504 }, { 18, 11, 29 }, + { 8, 0, 156 }, { 5, 0, 1009 }, { 6, 11, 29 }, { 11, 11, 63 }, + { 6, 0, 820 }, { 6, 10, 218 }, { 7, 10, 454 }, { 7, 10, 782 }, + { 8, 10, 768 }, { 12, 10, 686 }, { 5, 0, 228 }, { 6, 0, 203 }, + { 7, 0, 156 }, { 8, 0, 347 }, { 9, 0, 265 }, { 18, 0, 39 }, + { 20, 0, 54 }, { 21, 0, 31 }, { 22, 0, 3 }, { 23, 0, 0 }, + { 15, 11, 8 }, { 18, 11, 39 }, { 20, 11, 54 }, { 21, 11, 31 }, + { 22, 11, 3 }, { 23, 11, 0 }, { 7, 0, 1131 }, { 7, 0, 1468 }, + { 16, 10, 0 }, { 6, 0, 1276 }, { 10, 10, 676 }, { 12, 10, 462 }, + { 4, 11, 311 }, { 6, 11, 1740 }, { 7, 11, 170 }, { 8, 11, 90 }, + { 8, 11, 177 }, { 8, 11, 415 }, { 11, 11, 714 }, { 14, 11, 281 }, + { 6, 10, 164 }, { 6, 0, 1792 }, { 10, 0, 849 }, { 22, 10, 50 }, + { 5, 0, 291 }, { 5, 0, 318 }, { 7, 0, 765 }, { 9, 0, 389 }, + { 12, 0, 548 }, { 8, 11, 522 }, { 14, 11, 328 }, { 11, 11, 91 }, + { 13, 11, 129 }, { 15, 11, 101 }, { 17, 11, 125 }, { 4, 11, 494 }, + { 6, 11, 74 }, { 7, 11, 44 }, { 7, 11, 407 }, { 8, 11, 551 }, + { 12, 11, 17 }, { 15, 11, 5 }, { 20, 11, 11 }, { 4, 11, 276 }, + { 5, 11, 296 }, { 6, 10, 343 }, { 7, 10, 195 }, { 7, 11, 1777 }, + { 9, 10, 226 }, { 10, 10, 197 }, { 10, 10, 575 }, { 11, 10, 502 }, + { 11, 10, 899 }, { 10, 0, 525 }, { 11, 0, 82 }, { 14, 0, 453 }, + { 4, 11, 7 }, { 5, 11, 90 }, { 5, 11, 158 }, { 6, 11, 542 }, + { 7, 11, 221 }, { 7, 11, 1574 }, { 9, 11, 490 }, { 10, 11, 540 }, + { 11, 11, 443 }, { 11, 11, 757 }, { 7, 0, 666 }, { 22, 10, 29 }, + { 22, 11, 29 }, { 4, 0, 422 }, { 19, 10, 8 }, { 5, 0, 355 }, + { 17, 0, 0 }, { 6, 0, 1873 }, { 9, 0, 918 }, { 7, 11, 588 }, + { 9, 11, 175 }, { 10, 11, 530 }, { 15, 11, 31 }, { 11, 0, 165 }, + { 7, 10, 1125 }, { 9, 10, 143 }, { 14, 10, 405 }, { 22, 10, 21 }, + { 9, 0, 260 }, { 9, 0, 905 }, { 5, 11, 872 }, { 6, 11, 57 }, + { 6, 11, 479 }, { 6, 11, 562 }, { 7, 11, 471 }, { 7, 11, 1060 }, + { 9, 11, 447 }, { 9, 11, 454 }, { 13, 11, 6 }, { 10, 11, 704 }, + { 5, 0, 865 }, { 5, 0, 914 }, { 6, 0, 1625 }, { 5, 0, 234 }, + { 7, 0, 1383 }, { 5, 11, 31 }, { 6, 11, 614 }, { 17, 11, 61 }, + { 7, 11, 1200 }, { 10, 11, 460 }, { 6, 11, 424 }, { 7, 11, 1866 }, + { 8, 0, 306 }, { 5, 10, 959 }, { 12, 11, 30 }, { 13, 11, 148 }, + { 14, 11, 87 }, { 14, 11, 182 }, { 16, 11, 42 }, { 18, 11, 92 }, + { 20, 11, 70 }, { 6, 0, 1919 }, { 6, 0, 1921 }, { 9, 0, 923 }, + { 9, 0, 930 }, { 9, 0, 941 }, { 9, 0, 949 }, { 9, 0, 987 }, + { 9, 0, 988 }, { 9, 0, 992 }, { 12, 0, 802 }, { 12, 0, 815 }, + { 12, 0, 856 }, { 12, 0, 885 }, { 12, 0, 893 }, { 12, 0, 898 }, + { 12, 0, 919 }, { 12, 0, 920 }, { 12, 0, 941 }, { 12, 0, 947 }, + { 15, 0, 183 }, { 15, 0, 185 }, { 15, 0, 189 }, { 15, 0, 197 }, + { 15, 0, 202 }, { 15, 0, 233 }, { 18, 0, 218 }, { 18, 0, 219 }, + { 18, 0, 233 }, { 15, 11, 156 }, { 7, 10, 1759 }, { 8, 10, 173 }, + { 13, 0, 163 }, { 13, 0, 180 }, { 18, 0, 78 }, { 20, 0, 35 }, + { 5, 11, 13 }, { 6, 11, 142 }, { 6, 10, 266 }, { 6, 11, 97 }, + { 7, 11, 116 }, { 8, 11, 322 }, { 8, 11, 755 }, { 9, 11, 548 }, + { 10, 11, 714 }, { 11, 11, 884 }, { 13, 11, 324 }, { 7, 0, 1312 }, + { 9, 0, 814 }, { 9, 11, 676 }, { 5, 0, 707 }, { 7, 0, 1493 }, + { 6, 0, 421 }, { 7, 0, 61 }, { 7, 0, 1540 }, { 10, 0, 11 }, + { 10, 0, 501 }, { 12, 0, 733 }, { 12, 0, 766 }, { 7, 11, 866 }, + { 7, 11, 1163 }, { 9, 0, 341 }, { 14, 0, 98 }, { 17, 11, 115 }, + { 7, 11, 1111 }, { 8, 10, 300 }, { 8, 0, 1014 }, { 8, 11, 1 }, + { 9, 11, 112 }, { 10, 11, 326 }, { 4, 11, 730 }, { 5, 11, 488 }, + { 6, 11, 527 }, { 7, 11, 489 }, { 7, 11, 1636 }, { 8, 11, 121 }, + { 8, 11, 144 }, { 8, 11, 359 }, { 9, 11, 193 }, { 9, 11, 241 }, + { 9, 11, 336 }, { 9, 11, 882 }, { 11, 11, 266 }, { 11, 11, 372 }, + { 11, 11, 944 }, { 12, 11, 401 }, { 12, 11, 641 }, { 6, 0, 971 }, + { 6, 0, 1121 }, { 6, 0, 102 }, { 7, 0, 72 }, { 15, 0, 142 }, + { 19, 0, 67 }, { 23, 0, 30 }, { 7, 0, 823 }, { 6, 0, 1045 }, + { 5, 10, 427 }, { 5, 10, 734 }, { 7, 10, 478 }, { 8, 10, 52 }, + { 7, 0, 1930 }, { 11, 10, 217 }, { 14, 10, 165 }, { 6, 0, 1512 }, + { 7, 0, 1870 }, { 9, 11, 31 }, { 10, 11, 244 }, { 10, 11, 699 }, + { 12, 11, 149 }, { 13, 11, 497 }, { 5, 11, 377 }, { 17, 11, 101 }, + { 10, 11, 158 }, { 13, 11, 13 }, { 13, 11, 137 }, { 13, 11, 258 }, + { 14, 11, 111 }, { 14, 11, 225 }, { 14, 11, 253 }, { 14, 11, 304 }, + { 14, 11, 339 }, { 14, 11, 417 }, { 18, 11, 33 }, { 6, 0, 87 }, + { 6, 10, 1734 }, { 7, 10, 20 }, { 7, 10, 1056 }, { 8, 10, 732 }, + { 9, 10, 406 }, { 9, 10, 911 }, { 10, 10, 694 }, { 6, 0, 1243 }, + { 9, 0, 245 }, { 7, 0, 68 }, { 8, 0, 48 }, { 8, 0, 88 }, + { 8, 0, 582 }, { 8, 0, 681 }, { 9, 0, 373 }, { 9, 0, 864 }, + { 11, 0, 157 }, { 11, 0, 336 }, { 11, 0, 843 }, { 20, 0, 27 }, + { 8, 11, 663 }, { 16, 11, 8 }, { 5, 10, 613 }, { 4, 0, 88 }, + { 5, 0, 137 }, { 5, 0, 174 }, { 5, 0, 777 }, { 6, 0, 1664 }, + { 6, 0, 1725 }, { 7, 0, 77 }, { 7, 0, 426 }, { 7, 0, 1317 }, + { 7, 0, 1355 }, { 8, 0, 126 }, { 8, 0, 563 }, { 9, 0, 523 }, + { 9, 0, 750 }, { 10, 0, 310 }, { 10, 0, 836 }, { 11, 0, 42 }, + { 11, 0, 318 }, { 11, 0, 731 }, { 12, 0, 68 }, { 12, 0, 92 }, + { 12, 0, 507 }, { 12, 0, 692 }, { 13, 0, 81 }, { 13, 0, 238 }, + { 13, 0, 374 }, { 14, 0, 436 }, { 18, 0, 138 }, { 19, 0, 78 }, + { 19, 0, 111 }, { 20, 0, 55 }, { 20, 0, 77 }, { 20, 0, 92 }, + { 13, 0, 418 }, { 4, 0, 938 }, { 9, 0, 625 }, { 10, 0, 351 }, + { 5, 11, 843 }, { 7, 10, 32 }, { 7, 10, 984 }, { 8, 10, 85 }, + { 8, 10, 709 }, { 9, 10, 579 }, { 9, 10, 847 }, { 9, 10, 856 }, + { 10, 10, 799 }, { 11, 10, 258 }, { 11, 10, 1007 }, { 12, 10, 331 }, + { 12, 10, 615 }, { 13, 10, 188 }, { 13, 10, 435 }, { 14, 10, 8 }, + { 15, 10, 165 }, { 16, 10, 27 }, { 20, 10, 40 }, { 6, 0, 1668 }, + { 7, 0, 1499 }, { 8, 0, 117 }, { 9, 0, 314 }, { 10, 0, 174 }, + { 7, 0, 707 }, { 4, 11, 554 }, { 5, 11, 536 }, { 5, 0, 403 }, + { 5, 11, 207 }, { 9, 11, 79 }, { 11, 11, 625 }, { 17, 11, 7 }, + { 4, 11, 424 }, { 8, 11, 785 }, { 4, 10, 167 }, { 7, 10, 82 }, + { 9, 0, 7 }, { 23, 0, 6 }, { 9, 11, 7 }, { 23, 11, 6 }, + { 6, 0, 282 }, { 5, 10, 62 }, { 6, 10, 534 }, { 7, 10, 74 }, + { 7, 10, 678 }, { 7, 10, 684 }, { 7, 10, 1043 }, { 7, 10, 1072 }, + { 8, 10, 280 }, { 8, 10, 541 }, { 8, 10, 686 }, { 9, 10, 258 }, + { 10, 10, 519 }, { 11, 10, 252 }, { 12, 10, 282 }, { 10, 10, 33 }, + { 4, 10, 359 }, { 4, 0, 44 }, { 5, 0, 311 }, { 6, 0, 156 }, + { 7, 0, 639 }, { 7, 0, 762 }, { 7, 0, 1827 }, { 9, 0, 8 }, + { 9, 0, 462 }, { 20, 0, 83 }, { 7, 11, 769 }, { 9, 11, 18 }, + { 10, 11, 358 }, { 4, 0, 346 }, { 7, 0, 115 }, { 9, 0, 180 }, + { 9, 0, 456 }, { 10, 0, 363 }, { 4, 11, 896 }, { 6, 11, 1777 }, + { 5, 10, 211 }, { 7, 0, 761 }, { 7, 0, 1051 }, { 9, 0, 545 }, + { 6, 10, 145 }, { 13, 10, 336 }, { 7, 11, 750 }, { 9, 11, 223 }, + { 11, 11, 27 }, { 11, 11, 466 }, { 12, 11, 624 }, { 14, 11, 265 }, + { 18, 11, 61 }, { 6, 0, 752 }, { 6, 0, 768 }, { 6, 0, 1195 }, + { 6, 0, 1254 }, { 6, 0, 1619 }, { 9, 0, 835 }, { 6, 0, 1936 }, + { 8, 0, 930 }, { 8, 0, 960 }, { 4, 10, 263 }, { 4, 11, 249 }, + { 12, 0, 653 }, { 4, 10, 916 }, { 4, 11, 603 }, { 5, 11, 661 }, + { 8, 0, 344 }, { 4, 11, 11 }, { 6, 11, 128 }, { 7, 11, 231 }, + { 7, 11, 1533 }, { 10, 11, 725 }, { 6, 0, 1483 }, { 6, 0, 875 }, + { 6, 0, 185 }, { 7, 0, 1899 }, { 9, 0, 875 }, { 11, 0, 673 }, + { 15, 10, 155 }, { 16, 10, 79 }, { 7, 0, 93 }, { 7, 0, 210 }, + { 7, 0, 1223 }, { 8, 0, 451 }, { 8, 0, 460 }, { 11, 0, 353 }, + { 11, 0, 475 }, { 4, 10, 599 }, { 6, 10, 1634 }, { 7, 10, 67 }, + { 7, 10, 691 }, { 7, 10, 979 }, { 7, 10, 1697 }, { 8, 10, 207 }, + { 8, 10, 214 }, { 8, 10, 231 }, { 8, 10, 294 }, { 8, 10, 336 }, + { 8, 10, 428 }, { 8, 10, 471 }, { 8, 10, 622 }, { 8, 10, 626 }, + { 8, 10, 679 }, { 8, 10, 759 }, { 8, 10, 829 }, { 9, 10, 11 }, + { 9, 10, 246 }, { 9, 10, 484 }, { 9, 10, 573 }, { 9, 10, 706 }, + { 9, 10, 762 }, { 9, 10, 798 }, { 9, 10, 855 }, { 9, 10, 870 }, + { 9, 10, 912 }, { 10, 10, 303 }, { 10, 10, 335 }, { 10, 10, 424 }, + { 10, 10, 461 }, { 10, 10, 543 }, { 10, 10, 759 }, { 10, 10, 814 }, + { 11, 10, 59 }, { 11, 10, 235 }, { 11, 10, 590 }, { 11, 10, 929 }, + { 11, 10, 963 }, { 11, 10, 987 }, { 12, 10, 114 }, { 12, 10, 182 }, + { 12, 10, 226 }, { 12, 10, 332 }, { 12, 10, 439 }, { 12, 10, 575 }, + { 12, 10, 598 }, { 12, 10, 675 }, { 13, 10, 8 }, { 13, 10, 125 }, + { 13, 10, 194 }, { 13, 10, 287 }, { 14, 10, 197 }, { 14, 10, 383 }, + { 15, 10, 53 }, { 17, 10, 63 }, { 19, 10, 46 }, { 19, 10, 98 }, + { 19, 10, 106 }, { 20, 10, 85 }, { 4, 11, 476 }, { 4, 0, 327 }, + { 5, 0, 478 }, { 7, 0, 1332 }, { 8, 0, 753 }, { 5, 0, 1020 }, + { 5, 0, 1022 }, { 7, 11, 1807 }, { 4, 0, 103 }, { 5, 0, 401 }, + { 4, 0, 499 }, { 7, 0, 1421 }, { 10, 0, 207 }, { 13, 0, 164 }, + { 19, 10, 126 }, { 9, 11, 20 }, { 10, 11, 324 }, { 11, 11, 488 }, + { 4, 0, 96 }, { 9, 11, 280 }, { 10, 11, 134 }, { 7, 0, 968 }, + { 5, 10, 187 }, { 7, 10, 1286 }, { 5, 11, 112 }, { 6, 11, 103 }, + { 6, 11, 150 }, { 8, 0, 914 }, { 10, 0, 3 }, { 4, 10, 215 }, + { 9, 10, 38 }, { 11, 10, 23 }, { 11, 10, 127 }, { 11, 10, 796 }, + { 7, 0, 399 }, { 6, 0, 563 }, { 9, 0, 224 }, { 6, 0, 704 }, + { 6, 0, 1214 }, { 4, 11, 708 }, { 8, 11, 15 }, { 9, 11, 50 }, + { 9, 11, 386 }, { 11, 11, 18 }, { 11, 11, 529 }, { 12, 11, 228 }, + { 4, 11, 563 }, { 7, 11, 109 }, { 7, 11, 592 }, { 7, 11, 637 }, + { 7, 11, 770 }, { 7, 11, 1701 }, { 8, 11, 436 }, { 8, 11, 463 }, + { 9, 11, 60 }, { 9, 11, 335 }, { 9, 11, 904 }, { 10, 11, 73 }, + { 11, 11, 434 }, { 12, 11, 585 }, { 13, 11, 331 }, { 18, 11, 110 }, + { 20, 11, 60 }, { 6, 0, 1559 }, { 4, 11, 502 }, { 6, 11, 347 }, + { 10, 11, 161 }, { 4, 11, 33 }, { 5, 11, 102 }, { 5, 11, 500 }, + { 6, 11, 284 }, { 7, 11, 1079 }, { 7, 11, 1423 }, { 7, 11, 1702 }, + { 8, 11, 470 }, { 9, 11, 554 }, { 9, 11, 723 }, { 11, 11, 333 }, + { 7, 11, 246 }, { 7, 11, 840 }, { 6, 11, 10 }, { 8, 11, 571 }, + { 9, 11, 739 }, { 15, 11, 91 }, { 8, 0, 861 }, { 10, 0, 905 }, + { 12, 0, 730 }, { 12, 0, 789 }, { 5, 11, 626 }, { 6, 0, 946 }, + { 5, 0, 746 }, { 12, 0, 333 }, { 14, 0, 332 }, { 12, 11, 333 }, + { 14, 11, 332 }, { 5, 11, 18 }, { 6, 11, 526 }, { 13, 11, 24 }, + { 13, 11, 110 }, { 19, 11, 5 }, { 19, 11, 44 }, { 4, 0, 910 }, + { 5, 0, 832 }, { 7, 10, 2002 }, { 10, 11, 768 }, { 11, 11, 787 }, + { 4, 11, 309 }, { 5, 11, 462 }, { 7, 11, 970 }, { 7, 11, 1097 }, + { 4, 10, 28 }, { 5, 10, 440 }, { 7, 10, 248 }, { 11, 10, 833 }, + { 12, 10, 344 }, { 6, 10, 1654 }, { 6, 0, 632 }, { 6, 0, 652 }, + { 6, 0, 1272 }, { 6, 0, 1384 }, { 6, 0, 1560 }, { 6, 11, 1704 }, + { 6, 0, 1393 }, { 5, 10, 853 }, { 6, 10, 249 }, { 7, 10, 1234 }, + { 11, 10, 573 }, { 5, 11, 86 }, { 7, 11, 743 }, { 9, 11, 85 }, + { 10, 11, 281 }, { 10, 11, 432 }, { 11, 11, 490 }, { 12, 11, 251 }, + { 13, 11, 118 }, { 14, 11, 378 }, { 18, 11, 143 }, { 5, 11, 524 }, + { 5, 11, 744 }, { 6, 0, 1514 }, { 10, 0, 201 }, { 14, 0, 319 }, + { 7, 0, 717 }, { 10, 0, 510 }, { 7, 10, 392 }, { 8, 10, 20 }, + { 8, 10, 172 }, { 8, 10, 690 }, { 9, 10, 383 }, { 9, 10, 845 }, + { 11, 10, 293 }, { 11, 10, 832 }, { 11, 10, 920 }, { 11, 10, 984 }, + { 13, 10, 221 }, { 6, 0, 1381 }, { 5, 10, 858 }, { 5, 10, 992 }, + { 8, 0, 528 }, { 9, 0, 348 }, { 10, 11, 107 }, { 12, 11, 436 }, + { 4, 0, 20 }, { 5, 0, 616 }, { 6, 0, 1251 }, { 4, 11, 927 }, + { 10, 11, 123 }, { 12, 11, 670 }, { 13, 11, 371 }, { 14, 11, 142 }, + { 18, 11, 94 }, { 6, 0, 1163 }, { 7, 11, 1149 }, { 9, 11, 156 }, + { 6, 0, 307 }, { 5, 11, 778 }, { 7, 0, 1091 }, { 7, 0, 1765 }, + { 5, 11, 502 }, { 6, 10, 268 }, { 9, 10, 62 }, { 8, 11, 196 }, + { 10, 11, 283 }, { 11, 11, 406 }, { 4, 0, 26 }, { 5, 0, 429 }, + { 6, 0, 245 }, { 7, 0, 704 }, { 7, 0, 1379 }, { 7, 0, 1474 }, + { 5, 11, 855 }, { 4, 0, 881 }, { 4, 0, 621 }, { 7, 11, 1596 }, + { 7, 11, 1400 }, { 9, 11, 446 }, { 10, 11, 45 }, { 6, 0, 736 }, + { 10, 10, 106 }, { 5, 0, 542 }, { 6, 0, 348 }, { 5, 0, 868 }, + { 8, 0, 433 }, { 7, 0, 1495 }, { 10, 0, 771 }, { 6, 10, 613 }, + { 8, 10, 223 }, { 10, 0, 215 }, { 13, 0, 124 }, { 8, 11, 391 }, + { 7, 11, 172 }, { 4, 10, 670 }, { 12, 0, 55 }, { 9, 10, 40 }, + { 11, 10, 136 }, { 7, 0, 62 }, { 19, 0, 112 }, { 4, 0, 856 }, + { 4, 11, 568 }, { 12, 0, 270 }, { 11, 10, 259 }, { 8, 0, 572 }, + { 9, 0, 698 }, { 4, 11, 732 }, { 9, 10, 310 }, { 9, 10, 682 }, + { 14, 10, 296 }, { 6, 0, 939 }, { 8, 11, 733 }, { 7, 11, 1435 }, + { 7, 10, 1401 }, { 7, 10, 1476 }, { 6, 0, 352 }, { 4, 10, 296 }, + { 7, 10, 401 }, { 7, 10, 1410 }, { 7, 10, 1594 }, { 7, 10, 1674 }, + { 8, 10, 63 }, { 8, 10, 660 }, { 9, 10, 74 }, { 4, 11, 428 }, + { 5, 11, 668 }, { 4, 10, 139 }, { 4, 10, 388 }, { 12, 10, 188 }, + { 7, 11, 2015 }, { 12, 11, 665 }, { 4, 0, 647 }, { 18, 0, 10 }, + { 10, 0, 220 }, { 14, 0, 464 }, { 4, 0, 109 }, { 6, 0, 1746 }, + { 6, 0, 515 }, { 4, 10, 747 }, { 6, 11, 1623 }, { 6, 11, 1681 }, + { 7, 10, 649 }, { 7, 10, 1479 }, { 7, 10, 1583 }, { 5, 10, 232 }, + { 7, 0, 566 }, { 9, 10, 887 }, { 4, 0, 40 }, { 10, 0, 67 }, + { 11, 0, 117 }, { 11, 0, 768 }, { 11, 0, 935 }, { 4, 0, 801 }, + { 7, 0, 992 }, { 8, 0, 301 }, { 9, 0, 722 }, { 12, 0, 63 }, + { 13, 0, 29 }, { 14, 0, 161 }, { 15, 0, 18 }, { 11, 0, 923 }, + { 6, 11, 1748 }, { 8, 11, 715 }, { 9, 11, 802 }, { 10, 11, 46 }, + { 10, 11, 819 }, { 13, 11, 308 }, { 14, 11, 351 }, { 14, 11, 363 }, + { 18, 11, 67 }, { 9, 11, 745 }, { 7, 0, 1145 }, { 4, 10, 14 }, + { 7, 10, 1801 }, { 10, 10, 748 }, { 13, 10, 458 }, { 4, 11, 63 }, + { 5, 11, 347 }, { 6, 11, 474 }, { 7, 0, 568 }, { 4, 10, 425 }, + { 7, 11, 577 }, { 7, 11, 1432 }, { 9, 11, 475 }, { 9, 11, 505 }, + { 9, 11, 526 }, { 9, 11, 609 }, { 9, 11, 689 }, { 9, 11, 726 }, + { 9, 11, 735 }, { 9, 11, 738 }, { 10, 11, 556 }, { 10, 11, 674 }, + { 10, 11, 684 }, { 11, 11, 89 }, { 11, 11, 202 }, { 11, 11, 272 }, + { 11, 11, 380 }, { 11, 11, 415 }, { 11, 11, 505 }, { 11, 11, 537 }, + { 11, 11, 550 }, { 11, 11, 562 }, { 11, 11, 640 }, { 11, 11, 667 }, + { 11, 11, 688 }, { 11, 11, 847 }, { 11, 11, 927 }, { 11, 11, 930 }, + { 11, 11, 940 }, { 12, 11, 144 }, { 12, 11, 325 }, { 12, 11, 329 }, + { 12, 11, 389 }, { 12, 11, 403 }, { 12, 11, 451 }, { 12, 11, 515 }, + { 12, 11, 604 }, { 12, 11, 616 }, { 12, 11, 626 }, { 13, 11, 66 }, + { 13, 11, 131 }, { 13, 11, 167 }, { 13, 11, 236 }, { 13, 11, 368 }, + { 13, 11, 411 }, { 13, 11, 434 }, { 13, 11, 453 }, { 13, 11, 461 }, + { 13, 11, 474 }, { 14, 11, 59 }, { 14, 11, 60 }, { 14, 11, 139 }, + { 14, 11, 152 }, { 14, 11, 276 }, { 14, 11, 353 }, { 14, 11, 402 }, + { 15, 11, 28 }, { 15, 11, 81 }, { 15, 11, 123 }, { 15, 11, 152 }, + { 18, 11, 136 }, { 20, 11, 88 }, { 9, 0, 247 }, { 7, 11, 1622 }, + { 9, 11, 544 }, { 11, 11, 413 }, { 16, 11, 25 }, { 4, 0, 645 }, + { 7, 0, 825 }, { 6, 10, 1768 }, { 7, 11, 89 }, { 12, 0, 328 }, + { 5, 10, 943 }, { 6, 10, 1779 }, { 6, 0, 1363 }, { 5, 10, 245 }, + { 6, 10, 576 }, { 7, 10, 582 }, { 8, 10, 225 }, { 6, 0, 1280 }, + { 5, 11, 824 }, { 5, 11, 941 }, { 7, 11, 440 }, { 8, 11, 230 }, + { 11, 11, 106 }, { 5, 0, 28 }, { 6, 0, 204 }, { 10, 0, 320 }, + { 10, 0, 583 }, { 13, 0, 502 }, { 14, 0, 72 }, { 14, 0, 274 }, + { 14, 0, 312 }, { 14, 0, 344 }, { 15, 0, 159 }, { 16, 0, 62 }, + { 16, 0, 69 }, { 17, 0, 30 }, { 18, 0, 42 }, { 18, 0, 53 }, + { 18, 0, 84 }, { 18, 0, 140 }, { 19, 0, 68 }, { 19, 0, 85 }, + { 20, 0, 5 }, { 20, 0, 45 }, { 20, 0, 101 }, { 22, 0, 7 }, + { 22, 0, 20 }, { 4, 0, 558 }, { 6, 0, 390 }, { 7, 0, 162 }, + { 7, 0, 689 }, { 9, 0, 360 }, { 10, 0, 653 }, { 6, 0, 764 }, + { 6, 0, 862 }, { 9, 0, 833 }, { 5, 0, 856 }, { 6, 0, 1672 }, + { 6, 0, 1757 }, { 6, 0, 1781 }, { 5, 0, 92 }, { 10, 0, 736 }, + { 12, 0, 102 }, { 6, 0, 1927 }, { 6, 0, 1944 }, { 8, 0, 924 }, + { 8, 0, 948 }, { 10, 0, 967 }, { 10, 0, 978 }, { 6, 0, 1479 }, + { 5, 0, 590 }, { 8, 0, 360 }, { 9, 0, 213 }, { 10, 0, 63 }, + { 6, 0, 1521 }, { 6, 0, 709 }, { 6, 0, 891 }, { 4, 10, 443 }, + { 13, 0, 477 }, { 14, 0, 120 }, { 20, 0, 61 }, { 4, 11, 914 }, + { 5, 11, 800 }, { 5, 11, 852 }, { 10, 11, 54 }, { 13, 11, 115 }, + { 4, 11, 918 }, { 5, 11, 876 }, { 11, 11, 152 }, { 4, 11, 92 }, + { 5, 11, 274 }, { 7, 11, 1901 }, { 9, 11, 800 }, { 10, 11, 693 }, + { 11, 11, 482 }, { 11, 11, 734 }, { 11, 11, 789 }, { 9, 0, 483 }, + { 4, 10, 298 }, { 6, 0, 1213 }, { 13, 11, 498 }, { 7, 11, 1451 }, + { 5, 11, 743 }, { 4, 0, 1022 }, { 10, 0, 1000 }, { 12, 0, 957 }, + { 12, 0, 980 }, { 12, 0, 1013 }, { 14, 0, 481 }, { 16, 0, 116 }, + { 8, 0, 503 }, { 17, 0, 29 }, { 4, 11, 49 }, { 7, 11, 280 }, + { 7, 11, 1633 }, { 7, 0, 1712 }, { 6, 0, 466 }, { 8, 11, 47 }, + { 5, 10, 164 }, { 7, 10, 121 }, { 14, 10, 189 }, { 7, 10, 812 }, + { 7, 10, 1261 }, { 7, 10, 1360 }, { 9, 10, 632 }, { 12, 10, 352 }, + { 11, 10, 556 }, { 4, 0, 731 }, { 5, 11, 272 }, { 5, 11, 908 }, + { 5, 11, 942 }, { 7, 11, 1008 }, { 7, 11, 1560 }, { 8, 11, 197 }, + { 9, 11, 47 }, { 11, 11, 538 }, { 11, 11, 742 }, { 4, 10, 172 }, + { 9, 10, 611 }, { 10, 10, 436 }, { 12, 10, 673 }, { 13, 10, 255 }, + { 5, 10, 844 }, { 10, 0, 484 }, { 11, 0, 754 }, { 12, 0, 457 }, + { 14, 0, 171 }, { 14, 0, 389 }, { 18, 0, 153 }, { 9, 10, 263 }, + { 10, 10, 147 }, { 10, 10, 492 }, { 9, 11, 891 }, { 10, 0, 241 }, + { 5, 10, 537 }, { 6, 0, 2005 }, { 8, 0, 964 }, { 9, 10, 842 }, + { 23, 11, 8 }, { 4, 11, 407 }, { 4, 11, 560 }, { 7, 11, 1884 }, + { 6, 0, 1100 }, { 6, 0, 1242 }, { 7, 0, 954 }, { 5, 10, 230 }, + { 5, 10, 392 }, { 6, 10, 420 }, { 9, 10, 568 }, { 12, 10, 612 }, + { 4, 11, 475 }, { 11, 11, 35 }, { 11, 11, 90 }, { 13, 11, 7 }, + { 13, 11, 71 }, { 13, 11, 177 }, { 14, 11, 422 }, { 8, 11, 332 }, + { 7, 0, 1958 }, { 6, 0, 549 }, { 8, 0, 34 }, { 8, 0, 283 }, + { 9, 0, 165 }, { 10, 0, 475 }, { 10, 0, 952 }, { 12, 0, 966 }, + { 12, 0, 994 }, { 5, 0, 652 }, { 5, 0, 701 }, { 7, 0, 449 }, + { 4, 0, 655 }, { 7, 0, 850 }, { 17, 0, 75 }, { 18, 0, 137 }, + { 4, 0, 146 }, { 7, 0, 1618 }, { 8, 0, 670 }, { 5, 10, 41 }, + { 7, 10, 1459 }, { 7, 10, 1469 }, { 7, 10, 1859 }, { 9, 10, 549 }, + { 11, 10, 905 }, { 5, 10, 696 }, { 6, 0, 159 }, { 6, 0, 364 }, + { 7, 0, 516 }, { 9, 0, 518 }, { 7, 0, 1439 }, { 6, 11, 222 }, + { 7, 11, 636 }, { 7, 11, 1620 }, { 8, 11, 409 }, { 9, 11, 693 }, + { 11, 11, 77 }, { 13, 0, 151 }, { 13, 11, 45 }, { 6, 0, 1027 }, + { 4, 11, 336 }, { 4, 10, 771 }, { 11, 11, 392 }, { 10, 11, 121 }, + { 11, 11, 175 }, { 21, 11, 16 }, { 8, 0, 950 }, { 10, 0, 983 }, + { 5, 10, 921 }, { 7, 0, 993 }, { 6, 10, 180 }, { 7, 10, 1137 }, + { 8, 10, 751 }, { 11, 10, 805 }, { 7, 0, 501 }, { 9, 0, 111 }, + { 10, 0, 141 }, { 11, 0, 332 }, { 13, 0, 43 }, { 13, 0, 429 }, + { 14, 0, 130 }, { 14, 0, 415 }, { 17, 0, 102 }, { 4, 10, 183 }, + { 5, 11, 882 }, { 7, 10, 271 }, { 11, 10, 824 }, { 11, 10, 952 }, + { 13, 10, 278 }, { 13, 10, 339 }, { 13, 10, 482 }, { 14, 10, 424 }, + { 20, 10, 99 }, { 4, 10, 19 }, { 5, 10, 477 }, { 5, 10, 596 }, + { 6, 10, 505 }, { 7, 10, 1221 }, { 11, 10, 907 }, { 12, 10, 209 }, + { 13, 10, 214 }, { 7, 10, 1215 }, { 5, 0, 452 }, { 4, 11, 426 }, + { 5, 0, 149 }, { 8, 0, 233 }, { 5, 0, 935 }, { 6, 11, 58 }, + { 7, 11, 654 }, { 7, 11, 745 }, { 7, 11, 1969 }, { 8, 11, 240 }, + { 8, 11, 675 }, { 9, 11, 479 }, { 9, 11, 731 }, { 10, 11, 330 }, + { 10, 11, 593 }, { 10, 11, 817 }, { 11, 11, 32 }, { 11, 11, 133 }, + { 11, 11, 221 }, { 17, 11, 68 }, { 12, 0, 582 }, { 18, 0, 131 }, + { 7, 11, 102 }, { 9, 11, 538 }, { 8, 0, 801 }, { 6, 10, 1645 }, + { 4, 0, 70 }, { 6, 10, 92 }, { 6, 10, 188 }, { 7, 10, 1269 }, + { 7, 10, 1524 }, { 7, 10, 1876 }, { 10, 10, 228 }, { 11, 10, 1020 }, + { 4, 10, 459 }, { 5, 10, 966 }, { 10, 0, 369 }, { 16, 0, 36 }, + { 12, 10, 330 }, { 13, 11, 366 }, { 7, 0, 721 }, { 10, 0, 236 }, + { 12, 0, 204 }, { 6, 10, 18 }, { 7, 10, 932 }, { 8, 10, 757 }, + { 9, 10, 54 }, { 9, 10, 65 }, { 9, 10, 844 }, { 10, 10, 113 }, + { 10, 10, 315 }, { 10, 10, 798 }, { 11, 10, 153 }, { 12, 10, 151 }, + { 12, 10, 392 }, { 12, 10, 666 }, { 14, 10, 248 }, { 7, 0, 241 }, + { 10, 0, 430 }, { 8, 10, 548 }, { 9, 10, 532 }, { 10, 10, 117 }, + { 11, 10, 351 }, { 11, 10, 375 }, { 15, 10, 23 }, { 6, 10, 1742 }, + { 5, 10, 965 }, { 5, 11, 566 }, { 6, 11, 48 }, { 7, 11, 63 }, + { 6, 10, 182 }, { 10, 10, 65 }, { 10, 10, 488 }, { 10, 10, 497 }, + { 6, 11, 114 }, { 7, 11, 1224 }, { 7, 11, 1556 }, { 8, 11, 3 }, + { 6, 0, 1817 }, { 8, 11, 576 }, { 9, 11, 267 }, { 6, 0, 1078 }, + { 16, 0, 16 }, { 9, 10, 588 }, { 10, 10, 260 }, { 10, 0, 1021 }, + { 5, 0, 406 }, { 6, 0, 2022 }, { 5, 11, 933 }, { 6, 0, 69 }, + { 7, 0, 117 }, { 7, 0, 1830 }, { 8, 11, 427 }, { 4, 0, 432 }, + { 7, 0, 824 }, { 6, 10, 1786 }, { 5, 0, 826 }, { 11, 11, 67 }, + { 5, 11, 759 }, { 7, 10, 308 }, { 9, 0, 816 }, { 5, 0, 1000 }, + { 4, 0, 297 }, { 6, 0, 529 }, { 7, 0, 152 }, { 7, 0, 713 }, + { 7, 0, 1845 }, { 8, 0, 710 }, { 8, 0, 717 }, { 12, 0, 639 }, + { 12, 0, 685 }, { 7, 0, 423 }, { 8, 10, 588 }, { 8, 10, 287 }, + { 8, 0, 510 }, { 6, 0, 1048 }, { 6, 0, 618 }, { 7, 11, 56 }, + { 7, 11, 1989 }, { 8, 11, 337 }, { 8, 11, 738 }, { 9, 11, 600 }, + { 10, 11, 483 }, { 12, 11, 37 }, { 13, 11, 447 }, { 14, 11, 92 }, + { 4, 0, 520 }, { 7, 0, 575 }, { 8, 0, 990 }, { 10, 0, 977 }, + { 7, 11, 774 }, { 9, 11, 347 }, { 11, 11, 24 }, { 12, 11, 170 }, + { 8, 11, 379 }, { 12, 10, 290 }, { 4, 11, 328 }, { 4, 0, 321 }, + { 6, 0, 569 }, { 4, 11, 101 }, { 7, 11, 1171 }, { 7, 0, 723 }, + { 7, 0, 1135 }, { 5, 11, 833 }, { 8, 11, 744 }, { 7, 10, 719 }, + { 8, 10, 809 }, { 8, 10, 834 }, { 8, 0, 921 }, { 8, 10, 796 }, + { 5, 10, 210 }, { 6, 10, 213 }, { 7, 10, 60 }, { 10, 10, 364 }, + { 11, 10, 135 }, { 5, 0, 397 }, { 6, 0, 154 }, { 7, 0, 676 }, + { 8, 0, 443 }, { 8, 0, 609 }, { 9, 0, 24 }, { 9, 0, 325 }, + { 10, 0, 35 }, { 11, 0, 535 }, { 11, 0, 672 }, { 11, 0, 1018 }, + { 12, 0, 637 }, { 16, 0, 30 }, { 5, 10, 607 }, { 8, 10, 326 }, + { 8, 10, 490 }, { 4, 10, 701 }, { 5, 10, 472 }, { 6, 11, 9 }, + { 6, 11, 397 }, { 7, 11, 53 }, { 7, 11, 1742 }, { 9, 10, 758 }, + { 10, 11, 632 }, { 11, 11, 828 }, { 12, 11, 146 }, { 7, 10, 380 }, + { 7, 10, 1947 }, { 20, 11, 109 }, { 10, 10, 278 }, { 10, 11, 278 }, + { 6, 0, 856 }, { 7, 0, 139 }, { 4, 10, 386 }, { 8, 10, 405 }, + { 8, 10, 728 }, { 9, 10, 497 }, { 11, 10, 110 }, { 11, 10, 360 }, + { 15, 10, 37 }, { 16, 10, 84 }, { 13, 0, 282 }, { 5, 0, 981 }, + { 5, 0, 288 }, { 7, 10, 1452 }, { 7, 10, 1480 }, { 8, 10, 634 }, + { 12, 10, 472 }, { 7, 0, 1890 }, { 8, 11, 367 }, { 10, 11, 760 }, + { 14, 11, 79 }, { 20, 11, 17 }, { 24, 11, 0 }, { 4, 10, 524 }, + { 8, 10, 810 }, { 4, 0, 56 }, { 7, 0, 1791 }, { 8, 0, 607 }, + { 8, 0, 651 }, { 11, 0, 465 }, { 11, 0, 835 }, { 12, 0, 337 }, + { 13, 0, 480 }, { 10, 10, 238 }, { 13, 10, 33 }, { 11, 11, 417 }, + { 12, 11, 223 }, { 12, 11, 265 }, { 9, 0, 158 }, { 10, 0, 411 }, + { 12, 0, 261 }, { 5, 10, 532 }, { 5, 10, 997 }, { 12, 11, 186 }, + { 12, 11, 292 }, { 14, 11, 100 }, { 18, 11, 70 }, { 6, 0, 1403 }, + { 8, 0, 617 }, { 6, 0, 1205 }, { 11, 0, 563 }, { 4, 0, 242 }, + { 6, 0, 333 }, { 4, 11, 186 }, { 5, 11, 157 }, { 8, 11, 168 }, + { 10, 11, 6 }, { 4, 0, 369 }, { 5, 11, 875 }, { 5, 10, 782 }, + { 5, 10, 829 }, { 6, 10, 1738 }, { 6, 0, 622 }, { 7, 11, 1272 }, + { 6, 0, 1407 }, { 7, 11, 111 }, { 8, 11, 581 }, { 7, 10, 1823 }, + { 11, 10, 693 }, { 7, 0, 160 }, { 10, 0, 624 }, { 14, 0, 279 }, + { 4, 0, 363 }, { 10, 11, 589 }, { 12, 11, 111 }, { 13, 11, 260 }, + { 14, 11, 82 }, { 18, 11, 63 }, { 19, 11, 45 }, { 7, 11, 1364 }, + { 7, 11, 1907 }, { 13, 11, 158 }, { 4, 11, 404 }, { 4, 11, 659 }, + { 7, 11, 675 }, { 13, 11, 211 }, { 14, 11, 133 }, { 14, 11, 204 }, + { 15, 11, 64 }, { 15, 11, 69 }, { 15, 11, 114 }, { 16, 11, 10 }, + { 19, 11, 23 }, { 19, 11, 35 }, { 19, 11, 39 }, { 19, 11, 51 }, + { 19, 11, 71 }, { 19, 11, 75 }, { 24, 11, 15 }, { 4, 10, 78 }, + { 5, 10, 96 }, { 5, 10, 182 }, { 7, 10, 1724 }, { 7, 10, 1825 }, + { 10, 10, 394 }, { 10, 10, 471 }, { 11, 10, 532 }, { 14, 10, 340 }, + { 17, 10, 88 }, { 7, 10, 1964 }, { 5, 11, 391 }, { 11, 11, 887 }, + { 14, 11, 365 }, { 14, 11, 375 }, { 5, 11, 540 }, { 6, 11, 1697 }, + { 7, 11, 222 }, { 8, 11, 341 }, { 6, 11, 78 }, { 9, 0, 601 }, + { 9, 0, 619 }, { 10, 0, 505 }, { 10, 0, 732 }, { 11, 0, 355 }, + { 12, 0, 139 }, { 6, 0, 292 }, { 11, 0, 174 }, { 5, 0, 177 }, + { 6, 0, 616 }, { 7, 0, 827 }, { 9, 0, 525 }, { 10, 0, 656 }, + { 10, 0, 31 }, { 6, 10, 215 }, { 7, 10, 1028 }, { 7, 10, 1473 }, + { 7, 10, 1721 }, { 9, 10, 424 }, { 10, 10, 779 }, { 7, 10, 584 }, + { 8, 11, 293 }, { 6, 0, 685 }, { 7, 11, 1868 }, { 5, 11, 460 }, + { 7, 0, 647 }, { 6, 10, 67 }, { 7, 10, 1630 }, { 9, 10, 354 }, + { 9, 10, 675 }, { 10, 10, 830 }, { 14, 10, 80 }, { 17, 10, 80 }, + { 4, 0, 161 }, { 5, 0, 631 }, { 6, 10, 141 }, { 7, 10, 225 }, + { 9, 10, 59 }, { 9, 10, 607 }, { 10, 10, 312 }, { 11, 10, 687 }, + { 12, 10, 555 }, { 13, 10, 373 }, { 13, 10, 494 }, { 20, 10, 58 }, + { 7, 11, 965 }, { 7, 11, 1460 }, { 7, 11, 1604 }, { 8, 10, 783 }, + { 6, 11, 388 }, { 6, 0, 722 }, { 6, 0, 1267 }, { 4, 11, 511 }, + { 9, 11, 333 }, { 9, 11, 379 }, { 10, 11, 602 }, { 11, 11, 441 }, + { 11, 11, 723 }, { 11, 11, 976 }, { 12, 11, 357 }, { 6, 0, 1797 }, + { 7, 0, 1684 }, { 9, 0, 469 }, { 9, 0, 709 }, { 12, 0, 512 }, + { 14, 0, 65 }, { 17, 0, 12 }, { 5, 11, 938 }, { 8, 11, 707 }, + { 7, 0, 1230 }, { 8, 0, 531 }, { 10, 0, 229 }, { 11, 0, 73 }, + { 11, 0, 376 }, { 11, 0, 433 }, { 12, 0, 268 }, { 12, 0, 640 }, + { 14, 0, 119 }, { 7, 10, 430 }, { 11, 10, 46 }, { 6, 0, 558 }, + { 7, 0, 651 }, { 8, 0, 421 }, { 9, 0, 0 }, { 10, 0, 34 }, + { 11, 0, 1008 }, { 6, 0, 106 }, { 7, 0, 1786 }, { 7, 0, 1821 }, + { 9, 0, 102 }, { 9, 0, 763 }, { 5, 10, 602 }, { 7, 10, 2018 }, + { 9, 10, 418 }, { 5, 0, 65 }, { 6, 0, 416 }, { 7, 0, 1720 }, + { 7, 0, 1924 }, { 10, 0, 109 }, { 11, 0, 14 }, { 11, 0, 70 }, + { 11, 0, 569 }, { 11, 0, 735 }, { 15, 0, 153 }, { 20, 0, 80 }, + { 8, 10, 677 }, { 7, 11, 1625 }, { 9, 11, 772 }, { 8, 0, 595 }, + { 6, 11, 469 }, { 7, 11, 1709 }, { 10, 11, 515 }, { 7, 0, 1832 }, + { 10, 0, 374 }, { 9, 0, 106 }, { 9, 0, 163 }, { 9, 0, 296 }, + { 10, 0, 167 }, { 10, 0, 172 }, { 10, 0, 777 }, { 11, 0, 16 }, + { 6, 0, 6 }, { 7, 0, 81 }, { 7, 0, 771 }, { 7, 0, 1731 }, + { 9, 0, 405 }, { 10, 0, 421 }, { 4, 11, 500 }, { 7, 11, 938 }, + { 5, 11, 68 }, { 6, 11, 383 }, { 5, 0, 881 }, { 5, 0, 885 }, + { 6, 0, 854 }, { 6, 0, 1132 }, { 6, 0, 1495 }, { 6, 0, 1526 }, + { 6, 0, 1533 }, { 6, 0, 1577 }, { 4, 11, 337 }, { 6, 11, 353 }, + { 7, 11, 1934 }, { 8, 11, 488 }, { 9, 11, 429 }, { 7, 11, 236 }, + { 7, 11, 1795 }, { 8, 11, 259 }, { 9, 11, 135 }, { 9, 11, 177 }, + { 10, 11, 825 }, { 11, 11, 115 }, { 11, 11, 370 }, { 11, 11, 405 }, + { 11, 11, 604 }, { 12, 11, 10 }, { 12, 11, 667 }, { 12, 11, 669 }, + { 13, 11, 76 }, { 14, 11, 310 }, { 15, 11, 76 }, { 15, 11, 147 }, + { 20, 11, 23 }, { 5, 0, 142 }, { 6, 0, 546 }, { 4, 11, 15 }, + { 5, 11, 22 }, { 6, 11, 244 }, { 7, 11, 40 }, { 7, 11, 200 }, + { 7, 11, 906 }, { 7, 11, 1199 }, { 9, 11, 616 }, { 10, 11, 716 }, + { 11, 11, 635 }, { 11, 11, 801 }, { 12, 11, 458 }, { 5, 0, 466 }, + { 11, 0, 571 }, { 12, 0, 198 }, { 13, 0, 283 }, { 14, 0, 186 }, + { 15, 0, 21 }, { 15, 0, 103 }, { 7, 10, 329 }, { 4, 0, 185 }, + { 5, 0, 257 }, { 5, 0, 839 }, { 5, 0, 936 }, { 9, 0, 399 }, + { 10, 0, 258 }, { 10, 0, 395 }, { 10, 0, 734 }, { 11, 0, 1014 }, + { 12, 0, 23 }, { 13, 0, 350 }, { 14, 0, 150 }, { 19, 0, 6 }, + { 7, 11, 1735 }, { 12, 11, 36 }, { 13, 11, 337 }, { 5, 11, 598 }, + { 7, 11, 791 }, { 8, 11, 108 }, { 9, 11, 123 }, { 4, 10, 469 }, + { 7, 0, 404 }, { 7, 0, 1377 }, { 7, 0, 1430 }, { 7, 0, 2017 }, + { 8, 0, 149 }, { 8, 0, 239 }, { 8, 0, 512 }, { 8, 0, 793 }, + { 8, 0, 818 }, { 9, 0, 474 }, { 9, 0, 595 }, { 10, 0, 122 }, + { 10, 0, 565 }, { 10, 0, 649 }, { 10, 0, 783 }, { 11, 0, 239 }, + { 11, 0, 295 }, { 11, 0, 447 }, { 11, 0, 528 }, { 11, 0, 639 }, + { 11, 0, 800 }, { 12, 0, 25 }, { 12, 0, 77 }, { 12, 0, 157 }, + { 12, 0, 256 }, { 12, 0, 316 }, { 12, 0, 390 }, { 12, 0, 391 }, + { 12, 0, 395 }, { 12, 0, 478 }, { 12, 0, 503 }, { 12, 0, 592 }, + { 12, 0, 680 }, { 13, 0, 50 }, { 13, 0, 53 }, { 13, 0, 132 }, + { 13, 0, 198 }, { 13, 0, 322 }, { 13, 0, 415 }, { 13, 0, 511 }, + { 14, 0, 71 }, { 14, 0, 395 }, { 15, 0, 71 }, { 15, 0, 136 }, + { 17, 0, 123 }, { 18, 0, 93 }, { 19, 0, 58 }, { 8, 0, 712 }, + { 6, 10, 1743 }, { 5, 10, 929 }, { 6, 10, 340 }, { 8, 10, 376 }, + { 8, 10, 807 }, { 6, 0, 1848 }, { 8, 0, 860 }, { 10, 0, 856 }, + { 10, 0, 859 }, { 10, 0, 925 }, { 10, 0, 941 }, { 12, 0, 762 }, + { 6, 0, 629 }, { 6, 0, 906 }, { 9, 0, 810 }, { 12, 0, 652 }, + { 5, 10, 218 }, { 7, 10, 1610 }, { 10, 10, 83 }, { 7, 10, 1512 }, + { 7, 10, 1794 }, { 4, 0, 377 }, { 24, 0, 13 }, { 4, 11, 155 }, + { 7, 11, 1689 }, { 11, 10, 0 }, { 16, 10, 78 }, { 4, 11, 164 }, + { 5, 11, 151 }, { 5, 11, 730 }, { 5, 11, 741 }, { 7, 11, 498 }, + { 7, 11, 870 }, { 7, 11, 1542 }, { 12, 11, 213 }, { 14, 11, 36 }, + { 14, 11, 391 }, { 17, 11, 111 }, { 18, 11, 6 }, { 18, 11, 46 }, + { 18, 11, 151 }, { 19, 11, 36 }, { 20, 11, 32 }, { 20, 11, 56 }, + { 20, 11, 69 }, { 20, 11, 102 }, { 21, 11, 4 }, { 22, 11, 8 }, + { 22, 11, 10 }, { 22, 11, 14 }, { 22, 11, 31 }, { 7, 0, 1842 }, + { 5, 10, 571 }, { 4, 10, 455 }, { 4, 11, 624 }, { 7, 11, 1752 }, + { 6, 0, 1501 }, { 4, 11, 492 }, { 5, 11, 451 }, { 6, 10, 161 }, + { 7, 10, 372 }, { 9, 10, 597 }, { 4, 10, 349 }, { 4, 0, 180 }, + { 7, 0, 1906 }, { 7, 11, 835 }, { 13, 11, 70 }, { 4, 0, 491 }, + { 9, 10, 751 }, { 6, 10, 432 }, { 11, 10, 322 }, { 4, 0, 171 }, + { 10, 0, 234 }, { 6, 11, 113 }, { 7, 11, 436 }, { 4, 0, 586 }, + { 7, 0, 1186 }, { 10, 0, 631 }, { 5, 10, 468 }, { 10, 10, 325 }, + { 11, 10, 856 }, { 12, 10, 345 }, { 15, 10, 104 }, { 5, 10, 223 }, + { 10, 11, 592 }, { 10, 11, 753 }, { 12, 11, 317 }, { 12, 11, 355 }, + { 12, 11, 465 }, { 12, 11, 469 }, { 12, 11, 560 }, { 12, 11, 578 }, + { 13, 11, 243 }, { 4, 10, 566 }, { 7, 11, 520 }, { 4, 10, 59 }, + { 7, 10, 1394 }, { 6, 10, 436 }, { 11, 10, 481 }, { 9, 0, 931 }, + { 10, 0, 334 }, { 20, 0, 71 }, { 4, 10, 48 }, { 5, 10, 271 }, + { 7, 10, 953 }, { 7, 11, 1878 }, { 11, 0, 170 }, { 5, 10, 610 }, + { 8, 10, 457 }, { 5, 10, 755 }, { 6, 0, 1587 }, { 7, 10, 1217 }, + { 4, 10, 197 }, { 21, 11, 26 }, { 5, 11, 585 }, { 9, 11, 521 }, + { 5, 0, 765 }, { 5, 10, 217 }, { 11, 11, 586 }, { 5, 0, 424 }, + { 9, 11, 752 }, { 12, 11, 610 }, { 13, 11, 431 }, { 16, 11, 59 }, + { 18, 11, 109 }, { 8, 0, 714 }, { 7, 0, 685 }, { 4, 11, 307 }, + { 9, 0, 420 }, { 10, 0, 269 }, { 10, 0, 285 }, { 10, 0, 576 }, + { 11, 0, 397 }, { 13, 0, 175 }, { 17, 0, 90 }, { 4, 0, 429 }, + { 5, 11, 964 }, { 9, 11, 463 }, { 10, 11, 595 }, { 7, 0, 18 }, + { 7, 0, 699 }, { 7, 0, 1966 }, { 8, 0, 752 }, { 9, 0, 273 }, + { 9, 0, 412 }, { 9, 0, 703 }, { 10, 0, 71 }, { 10, 0, 427 }, + { 10, 0, 508 }, { 4, 10, 165 }, { 7, 10, 1398 }, { 7, 10, 1829 }, + { 4, 0, 53 }, { 5, 0, 186 }, { 7, 0, 752 }, { 7, 0, 828 }, + { 14, 0, 116 }, { 8, 0, 575 }, { 10, 0, 289 }, { 11, 0, 319 }, + { 4, 0, 675 }, { 6, 0, 1424 }, { 4, 11, 75 }, { 5, 11, 180 }, + { 6, 11, 500 }, { 7, 11, 58 }, { 7, 11, 710 }, { 10, 11, 645 }, + { 5, 11, 649 }, { 6, 11, 276 }, { 7, 11, 282 }, { 7, 11, 879 }, + { 7, 11, 924 }, { 8, 11, 459 }, { 9, 11, 599 }, { 9, 11, 754 }, + { 11, 11, 574 }, { 12, 11, 128 }, { 12, 11, 494 }, { 13, 11, 52 }, + { 13, 11, 301 }, { 15, 11, 30 }, { 15, 11, 132 }, { 6, 0, 647 }, + { 6, 0, 1095 }, { 5, 10, 9 }, { 7, 10, 297 }, { 7, 10, 966 }, + { 12, 10, 306 }, { 4, 11, 200 }, { 6, 0, 1334 }, { 5, 10, 146 }, + { 6, 10, 411 }, { 10, 10, 721 }, { 6, 0, 209 }, { 6, 0, 1141 }, + { 6, 0, 1288 }, { 8, 0, 468 }, { 9, 0, 210 }, { 11, 0, 36 }, + { 12, 0, 28 }, { 12, 0, 630 }, { 13, 0, 21 }, { 13, 0, 349 }, + { 14, 0, 7 }, { 17, 0, 13 }, { 6, 10, 177 }, { 7, 10, 467 }, + { 4, 0, 342 }, { 7, 0, 1179 }, { 10, 11, 454 }, { 12, 11, 324 }, + { 4, 0, 928 }, { 5, 0, 910 }, { 7, 0, 1838 }, { 6, 11, 225 }, + { 9, 11, 211 }, { 16, 0, 101 }, { 20, 0, 115 }, { 20, 0, 118 }, + { 20, 0, 122 }, { 4, 0, 496 }, { 7, 0, 856 }, { 4, 0, 318 }, + { 11, 0, 654 }, { 7, 11, 718 }, { 11, 11, 102 }, { 8, 11, 58 }, + { 9, 11, 724 }, { 11, 11, 809 }, { 13, 11, 113 }, { 17, 11, 72 }, + { 5, 10, 200 }, { 6, 11, 345 }, { 7, 11, 1247 }, { 8, 11, 767 }, + { 8, 11, 803 }, { 9, 11, 301 }, { 9, 11, 903 }, { 7, 0, 915 }, + { 8, 0, 247 }, { 19, 0, 0 }, { 7, 11, 1949 }, { 8, 11, 674 }, + { 4, 0, 202 }, { 5, 0, 382 }, { 6, 0, 454 }, { 7, 0, 936 }, + { 7, 0, 1803 }, { 8, 0, 758 }, { 9, 0, 375 }, { 9, 0, 895 }, + { 10, 0, 743 }, { 10, 0, 792 }, { 11, 0, 978 }, { 11, 0, 1012 }, + { 14, 0, 109 }, { 7, 0, 1150 }, { 7, 0, 1425 }, { 7, 0, 1453 }, + { 12, 0, 513 }, { 6, 11, 259 }, { 10, 0, 791 }, { 11, 0, 821 }, + { 12, 0, 110 }, { 12, 0, 153 }, { 18, 0, 41 }, { 22, 0, 19 }, + { 6, 10, 481 }, { 4, 0, 796 }, { 6, 0, 445 }, { 9, 0, 909 }, + { 8, 11, 254 }, { 10, 0, 776 }, { 13, 0, 345 }, { 14, 0, 425 }, + { 4, 10, 84 }, { 7, 10, 1482 }, { 10, 10, 76 }, { 10, 10, 142 }, + { 7, 11, 742 }, { 6, 0, 578 }, { 5, 10, 1015 }, { 6, 0, 1387 }, + { 4, 10, 315 }, { 5, 10, 507 }, { 7, 10, 1370 }, { 4, 0, 438 }, + { 5, 0, 555 }, { 8, 0, 766 }, { 5, 11, 248 }, { 6, 10, 1722 }, + { 4, 11, 116 }, { 5, 11, 95 }, { 5, 11, 445 }, { 7, 11, 1688 }, + { 8, 11, 29 }, { 9, 11, 272 }, { 11, 11, 509 }, { 11, 11, 915 }, + { 7, 0, 541 }, { 5, 11, 543 }, { 8, 10, 222 }, { 8, 10, 476 }, + { 9, 10, 238 }, { 11, 10, 516 }, { 11, 10, 575 }, { 15, 10, 109 }, + { 18, 10, 100 }, { 6, 0, 880 }, { 6, 0, 1191 }, { 5, 11, 181 }, + { 8, 11, 41 }, { 6, 0, 1506 }, { 4, 11, 681 }, { 7, 11, 25 }, + { 8, 11, 202 }, { 10, 11, 536 }, { 11, 0, 983 }, { 9, 0, 768 }, + { 4, 0, 584 }, { 9, 11, 423 }, { 12, 11, 89 }, { 8, 11, 113 }, + { 9, 11, 877 }, { 10, 11, 554 }, { 11, 11, 83 }, { 12, 11, 136 }, + { 19, 11, 109 }, { 7, 10, 706 }, { 7, 10, 1058 }, { 10, 10, 538 }, + { 5, 11, 976 }, { 4, 11, 206 }, { 7, 11, 746 }, { 8, 11, 526 }, + { 12, 0, 737 }, { 11, 10, 92 }, { 11, 10, 196 }, { 11, 10, 409 }, + { 11, 10, 450 }, { 11, 10, 666 }, { 11, 10, 777 }, { 12, 10, 262 }, + { 13, 10, 385 }, { 13, 10, 393 }, { 15, 10, 115 }, { 16, 10, 45 }, + { 17, 10, 82 }, { 4, 0, 226 }, { 4, 0, 326 }, { 7, 0, 1770 }, + { 4, 11, 319 }, { 5, 11, 699 }, { 10, 11, 673 }, { 6, 10, 40 }, + { 7, 10, 1781 }, { 5, 0, 426 }, { 8, 0, 30 }, { 9, 0, 2 }, + { 11, 0, 549 }, { 19, 0, 122 }, { 6, 0, 1161 }, { 6, 0, 1329 }, + { 10, 10, 97 }, { 6, 10, 423 }, { 7, 10, 665 }, { 7, 10, 1210 }, + { 7, 11, 13 }, { 8, 11, 226 }, { 10, 11, 537 }, { 11, 11, 570 }, + { 11, 11, 605 }, { 11, 11, 799 }, { 11, 11, 804 }, { 12, 11, 85 }, + { 12, 11, 516 }, { 12, 11, 623 }, { 13, 11, 112 }, { 13, 11, 361 }, + { 14, 11, 77 }, { 14, 11, 78 }, { 17, 11, 28 }, { 19, 11, 110 }, + { 4, 11, 769 }, { 4, 11, 551 }, { 4, 11, 728 }, { 19, 0, 117 }, + { 9, 11, 57 }, { 9, 11, 459 }, { 10, 11, 425 }, { 11, 11, 119 }, + { 12, 11, 184 }, { 12, 11, 371 }, { 13, 11, 358 }, { 17, 11, 51 }, + { 5, 11, 188 }, { 5, 11, 814 }, { 8, 11, 10 }, { 9, 11, 421 }, + { 9, 11, 729 }, { 10, 11, 609 }, { 11, 11, 689 }, { 6, 11, 624 }, + { 7, 11, 298 }, { 7, 0, 462 }, { 4, 0, 345 }, { 11, 10, 624 }, + { 8, 10, 574 }, { 4, 0, 385 }, { 7, 0, 265 }, { 7, 0, 587 }, + { 6, 0, 808 }, { 4, 11, 528 }, { 5, 0, 398 }, { 4, 10, 354 }, + { 4, 0, 347 }, { 5, 0, 423 }, { 5, 0, 996 }, { 7, 0, 1329 }, + { 7, 10, 1558 }, { 7, 0, 1259 }, { 9, 0, 125 }, { 11, 0, 65 }, + { 5, 0, 136 }, { 6, 0, 136 }, { 8, 0, 644 }, { 5, 11, 104 }, + { 6, 11, 173 }, { 7, 11, 1631 }, { 7, 0, 469 }, { 5, 10, 830 }, + { 4, 0, 278 }, { 5, 0, 465 }, { 7, 0, 1367 }, { 7, 11, 810 }, + { 8, 11, 138 }, { 8, 11, 342 }, { 9, 11, 84 }, { 10, 11, 193 }, + { 11, 11, 883 }, { 12, 11, 359 }, { 5, 10, 496 }, { 7, 10, 203 }, + { 4, 0, 433 }, { 5, 0, 719 }, { 6, 11, 95 }, { 6, 10, 547 }, + { 5, 10, 88 }, { 9, 10, 239 }, { 6, 11, 406 }, { 10, 11, 409 }, + { 10, 11, 447 }, { 11, 11, 44 }, { 12, 11, 100 }, { 6, 0, 1423 }, + { 7, 10, 650 }, { 7, 10, 1310 }, { 6, 0, 749 }, { 7, 11, 1243 }, + { 7, 0, 1363 }, { 6, 0, 381 }, { 7, 0, 645 }, { 7, 0, 694 }, + { 8, 0, 546 }, { 7, 10, 1076 }, { 9, 10, 80 }, { 11, 10, 78 }, + { 11, 10, 421 }, { 11, 10, 534 }, { 12, 10, 545 }, { 6, 11, 1636 }, + { 7, 11, 1344 }, { 12, 0, 277 }, { 7, 10, 274 }, { 11, 10, 479 }, + { 11, 10, 507 }, { 6, 0, 705 }, { 6, 0, 783 }, { 6, 0, 1275 }, + { 6, 0, 1481 }, { 4, 11, 282 }, { 7, 11, 1034 }, { 11, 11, 398 }, + { 11, 11, 634 }, { 12, 11, 1 }, { 12, 11, 79 }, { 12, 11, 544 }, + { 14, 11, 237 }, { 17, 11, 10 }, { 18, 11, 20 }, { 6, 0, 453 }, + { 4, 0, 555 }, { 8, 0, 536 }, { 10, 0, 288 }, { 11, 0, 1005 }, + { 4, 10, 497 }, { 7, 10, 1584 }, { 5, 11, 118 }, { 5, 11, 499 }, + { 6, 11, 476 }, { 7, 11, 600 }, { 7, 11, 888 }, { 7, 11, 1096 }, + { 10, 0, 987 }, { 7, 0, 1107 }, { 7, 10, 261 }, { 7, 10, 1115 }, + { 7, 10, 1354 }, { 7, 10, 1588 }, { 7, 10, 1705 }, { 7, 10, 1902 }, + { 9, 10, 465 }, { 10, 10, 248 }, { 10, 10, 349 }, { 10, 10, 647 }, + { 11, 10, 527 }, { 11, 10, 660 }, { 11, 10, 669 }, { 12, 10, 529 }, + { 13, 10, 305 }, { 7, 11, 296 }, { 7, 11, 596 }, { 8, 11, 560 }, + { 8, 11, 586 }, { 9, 11, 612 }, { 11, 11, 100 }, { 11, 11, 304 }, + { 12, 11, 46 }, { 13, 11, 89 }, { 14, 11, 112 }, { 17, 11, 122 }, + { 9, 0, 370 }, { 10, 0, 90 }, { 8, 10, 13 }, { 4, 0, 860 }, + { 7, 10, 642 }, { 8, 10, 250 }, { 11, 10, 123 }, { 11, 10, 137 }, + { 13, 10, 48 }, { 14, 10, 95 }, { 7, 10, 1429 }, { 9, 11, 321 }, + { 4, 0, 257 }, { 7, 0, 2031 }, { 7, 0, 1768 }, { 7, 11, 1599 }, + { 7, 11, 1723 }, { 8, 11, 79 }, { 8, 11, 106 }, { 8, 11, 190 }, + { 8, 11, 302 }, { 8, 11, 383 }, { 9, 11, 119 }, { 9, 11, 233 }, + { 9, 11, 298 }, { 9, 11, 419 }, { 9, 11, 471 }, { 10, 11, 181 }, + { 10, 11, 406 }, { 11, 11, 57 }, { 11, 11, 85 }, { 11, 11, 120 }, + { 11, 11, 177 }, { 11, 11, 296 }, { 11, 11, 382 }, { 11, 11, 454 }, + { 11, 11, 758 }, { 11, 11, 999 }, { 12, 11, 27 }, { 12, 11, 98 }, + { 12, 11, 131 }, { 12, 11, 245 }, { 12, 11, 312 }, { 12, 11, 446 }, + { 12, 11, 454 }, { 13, 11, 25 }, { 13, 11, 98 }, { 13, 11, 426 }, + { 13, 11, 508 }, { 14, 11, 6 }, { 14, 11, 163 }, { 14, 11, 272 }, + { 14, 11, 277 }, { 14, 11, 370 }, { 15, 11, 95 }, { 15, 11, 138 }, + { 15, 11, 167 }, { 17, 11, 18 }, { 17, 11, 38 }, { 20, 11, 96 }, + { 21, 11, 32 }, { 5, 11, 722 }, { 6, 11, 1759 }, { 17, 11, 16 }, + { 6, 0, 1071 }, { 6, 0, 1561 }, { 10, 10, 545 }, { 12, 10, 301 }, + { 6, 0, 83 }, { 6, 0, 1733 }, { 7, 0, 1389 }, { 4, 0, 835 }, + { 7, 0, 1818 }, { 5, 11, 258 }, { 4, 10, 904 }, { 5, 10, 794 }, + { 6, 0, 2006 }, { 5, 11, 30 }, { 7, 11, 495 }, { 8, 11, 134 }, + { 9, 11, 788 }, { 12, 11, 438 }, { 7, 11, 2004 }, { 9, 0, 696 }, + { 5, 11, 50 }, { 6, 11, 439 }, { 7, 11, 780 }, { 7, 11, 1040 }, + { 7, 11, 772 }, { 7, 11, 1104 }, { 7, 11, 1647 }, { 11, 11, 269 }, + { 11, 11, 539 }, { 11, 11, 607 }, { 11, 11, 627 }, { 11, 11, 706 }, + { 11, 11, 975 }, { 12, 11, 248 }, { 12, 11, 311 }, { 12, 11, 434 }, + { 12, 11, 600 }, { 12, 11, 622 }, { 13, 11, 297 }, { 13, 11, 367 }, + { 13, 11, 485 }, { 14, 11, 69 }, { 14, 11, 409 }, { 15, 11, 108 }, + { 5, 11, 1 }, { 6, 11, 81 }, { 10, 11, 520 }, { 7, 0, 1718 }, + { 9, 0, 95 }, { 9, 0, 274 }, { 10, 0, 279 }, { 10, 0, 317 }, + { 10, 0, 420 }, { 11, 0, 303 }, { 11, 0, 808 }, { 12, 0, 134 }, + { 12, 0, 367 }, { 13, 0, 149 }, { 13, 0, 347 }, { 14, 0, 349 }, + { 14, 0, 406 }, { 18, 0, 22 }, { 18, 0, 89 }, { 18, 0, 122 }, + { 19, 0, 47 }, { 5, 11, 482 }, { 8, 11, 98 }, { 9, 11, 172 }, + { 10, 11, 222 }, { 10, 11, 700 }, { 10, 11, 822 }, { 11, 11, 302 }, + { 11, 11, 778 }, { 12, 11, 50 }, { 12, 11, 127 }, { 12, 11, 396 }, + { 13, 11, 62 }, { 13, 11, 328 }, { 14, 11, 122 }, { 19, 11, 72 }, + { 7, 10, 386 }, { 10, 10, 713 }, { 6, 10, 7 }, { 6, 10, 35 }, + { 7, 10, 147 }, { 7, 10, 1069 }, { 7, 10, 1568 }, { 7, 10, 1575 }, + { 7, 10, 1917 }, { 8, 10, 43 }, { 8, 10, 208 }, { 9, 10, 128 }, + { 9, 10, 866 }, { 10, 10, 20 }, { 11, 10, 981 }, { 19, 10, 33 }, + { 5, 0, 26 }, { 4, 0, 550 }, { 5, 11, 2 }, { 7, 11, 1494 }, + { 8, 11, 589 }, { 6, 11, 512 }, { 7, 11, 797 }, { 8, 11, 253 }, + { 9, 11, 77 }, { 10, 11, 1 }, { 10, 11, 129 }, { 10, 11, 225 }, + { 11, 11, 118 }, { 11, 11, 226 }, { 11, 11, 251 }, { 11, 11, 430 }, + { 11, 11, 701 }, { 11, 11, 974 }, { 11, 11, 982 }, { 12, 11, 64 }, + { 12, 11, 260 }, { 12, 11, 488 }, { 12, 11, 690 }, { 7, 10, 893 }, + { 13, 10, 424 }, { 6, 0, 901 }, { 8, 0, 822 }, { 4, 0, 902 }, + { 5, 0, 809 }, { 6, 0, 122 }, { 6, 0, 807 }, { 6, 0, 1366 }, + { 7, 0, 262 }, { 5, 11, 748 }, { 6, 11, 553 }, { 5, 0, 620 }, + { 4, 0, 34 }, { 5, 0, 574 }, { 7, 0, 279 }, { 7, 0, 1624 }, + { 8, 0, 601 }, { 9, 0, 170 }, { 6, 10, 322 }, { 9, 10, 552 }, + { 11, 10, 274 }, { 13, 10, 209 }, { 13, 10, 499 }, { 14, 10, 85 }, + { 15, 10, 126 }, { 17, 10, 70 }, { 4, 0, 537 }, { 4, 11, 12 }, + { 7, 11, 420 }, { 7, 11, 522 }, { 7, 11, 809 }, { 8, 11, 797 }, + { 13, 11, 88 }, { 5, 0, 332 }, { 8, 10, 83 }, { 8, 10, 742 }, + { 8, 10, 817 }, { 9, 10, 28 }, { 9, 10, 29 }, { 9, 10, 885 }, + { 10, 10, 387 }, { 11, 10, 633 }, { 11, 10, 740 }, { 13, 10, 235 }, + { 13, 10, 254 }, { 15, 10, 143 }, { 15, 10, 146 }, { 6, 0, 1909 }, + { 9, 0, 964 }, { 12, 0, 822 }, { 12, 0, 854 }, { 12, 0, 865 }, + { 12, 0, 910 }, { 12, 0, 938 }, { 15, 0, 169 }, { 15, 0, 208 }, + { 15, 0, 211 }, { 18, 0, 205 }, { 18, 0, 206 }, { 18, 0, 220 }, + { 18, 0, 223 }, { 24, 0, 24 }, { 12, 10, 49 }, { 5, 11, 528 }, + { 7, 11, 1580 }, { 6, 0, 261 }, { 8, 0, 182 }, { 11, 0, 943 }, + { 6, 0, 1721 }, { 4, 0, 933 }, { 5, 0, 880 }, { 8, 11, 321 }, + { 5, 11, 266 }, { 9, 11, 290 }, { 9, 11, 364 }, { 10, 11, 293 }, + { 11, 11, 606 }, { 14, 11, 45 }, { 6, 0, 1609 }, { 4, 11, 50 }, + { 6, 11, 510 }, { 6, 11, 594 }, { 9, 11, 121 }, { 10, 11, 49 }, + { 10, 11, 412 }, { 11, 11, 834 }, { 7, 0, 895 }, { 8, 11, 748 }, + { 4, 11, 466 }, { 4, 10, 110 }, { 10, 10, 415 }, { 10, 10, 597 }, + { 14, 10, 206 }, { 5, 0, 812 }, { 7, 11, 281 }, { 6, 0, 1890 }, + { 6, 0, 1902 }, { 6, 0, 1916 }, { 9, 0, 929 }, { 9, 0, 942 }, + { 9, 0, 975 }, { 9, 0, 984 }, { 9, 0, 986 }, { 9, 0, 1011 }, + { 9, 0, 1019 }, { 12, 0, 804 }, { 12, 0, 851 }, { 12, 0, 867 }, + { 12, 0, 916 }, { 12, 0, 923 }, { 15, 0, 194 }, { 15, 0, 204 }, + { 15, 0, 210 }, { 15, 0, 222 }, { 15, 0, 223 }, { 15, 0, 229 }, + { 15, 0, 250 }, { 18, 0, 179 }, { 18, 0, 186 }, { 18, 0, 192 }, + { 7, 10, 205 }, { 7, 10, 2000 }, { 4, 11, 667 }, { 7, 0, 778 }, + { 4, 0, 137 }, { 7, 0, 1178 }, { 7, 0, 1520 }, { 6, 0, 1314 }, + { 4, 11, 242 }, { 6, 11, 333 }, { 6, 0, 1661 }, { 7, 0, 1975 }, + { 7, 0, 2009 }, { 7, 0, 2011 }, { 6, 0, 1591 }, { 4, 10, 283 }, + { 7, 10, 1194 }, { 11, 0, 820 }, { 22, 0, 51 }, { 4, 11, 39 }, + { 5, 11, 36 }, { 7, 11, 1843 }, { 8, 11, 407 }, { 11, 11, 144 }, + { 12, 11, 523 }, { 6, 10, 1720 }, { 4, 11, 510 }, { 7, 11, 29 }, + { 7, 11, 66 }, { 7, 11, 1980 }, { 10, 11, 487 }, { 10, 11, 809 }, + { 18, 11, 9 }, { 5, 0, 89 }, { 7, 0, 1915 }, { 9, 0, 185 }, + { 9, 0, 235 }, { 10, 0, 64 }, { 10, 0, 270 }, { 10, 0, 403 }, + { 10, 0, 469 }, { 10, 0, 529 }, { 10, 0, 590 }, { 11, 0, 140 }, + { 11, 0, 860 }, { 13, 0, 1 }, { 13, 0, 422 }, { 14, 0, 341 }, + { 14, 0, 364 }, { 17, 0, 93 }, { 18, 0, 113 }, { 19, 0, 97 }, + { 19, 0, 113 }, { 5, 0, 695 }, { 6, 0, 987 }, { 6, 0, 1160 }, + { 5, 0, 6 }, { 6, 0, 183 }, { 7, 0, 680 }, { 7, 0, 978 }, + { 7, 0, 1013 }, { 7, 0, 1055 }, { 12, 0, 230 }, { 13, 0, 172 }, + { 18, 0, 29 }, { 6, 11, 570 }, { 4, 11, 787 }, { 6, 11, 518 }, + { 6, 0, 29 }, { 11, 0, 63 }, { 4, 11, 516 }, { 8, 11, 821 }, + { 4, 0, 311 }, { 6, 0, 1740 }, { 7, 0, 170 }, { 8, 0, 90 }, + { 8, 0, 177 }, { 8, 0, 415 }, { 11, 0, 714 }, { 14, 0, 281 }, + { 8, 10, 735 }, { 6, 0, 1961 }, { 7, 11, 1405 }, { 4, 11, 10 }, + { 7, 11, 917 }, { 11, 11, 786 }, { 5, 10, 132 }, { 9, 10, 486 }, + { 9, 10, 715 }, { 10, 10, 458 }, { 11, 10, 373 }, { 11, 10, 668 }, + { 11, 10, 795 }, { 11, 10, 897 }, { 12, 10, 272 }, { 12, 10, 424 }, + { 12, 10, 539 }, { 12, 10, 558 }, { 14, 10, 245 }, { 14, 10, 263 }, + { 14, 10, 264 }, { 14, 10, 393 }, { 14, 10, 403 }, { 11, 0, 91 }, + { 13, 0, 129 }, { 15, 0, 101 }, { 17, 0, 125 }, { 7, 0, 1132 }, + { 4, 0, 494 }, { 6, 0, 74 }, { 7, 0, 44 }, { 7, 0, 407 }, + { 12, 0, 17 }, { 15, 0, 5 }, { 20, 0, 11 }, { 5, 10, 379 }, + { 5, 0, 270 }, { 5, 11, 684 }, { 6, 10, 89 }, { 6, 10, 400 }, + { 7, 10, 1569 }, { 7, 10, 1623 }, { 7, 10, 1850 }, { 8, 10, 218 }, + { 8, 10, 422 }, { 9, 10, 570 }, { 10, 10, 626 }, { 4, 0, 276 }, + { 5, 0, 296 }, { 6, 0, 1523 }, { 6, 11, 27 }, { 6, 10, 387 }, + { 7, 10, 882 }, { 13, 10, 111 }, { 6, 10, 224 }, { 7, 10, 877 }, + { 9, 10, 647 }, { 7, 10, 790 }, { 4, 0, 7 }, { 5, 0, 90 }, + { 5, 0, 158 }, { 6, 0, 542 }, { 7, 0, 221 }, { 7, 0, 1574 }, + { 9, 0, 490 }, { 10, 0, 540 }, { 11, 0, 443 }, { 11, 0, 757 }, + { 7, 0, 588 }, { 9, 0, 175 }, { 10, 0, 530 }, { 7, 10, 394 }, + { 14, 11, 23 }, { 6, 0, 786 }, { 7, 0, 580 }, { 7, 0, 88 }, + { 8, 0, 627 }, { 5, 0, 872 }, { 6, 0, 57 }, { 7, 0, 471 }, + { 9, 0, 447 }, { 9, 0, 454 }, { 6, 11, 342 }, { 6, 11, 496 }, + { 8, 11, 275 }, { 9, 11, 206 }, { 4, 11, 909 }, { 5, 11, 940 }, + { 6, 0, 735 }, { 4, 11, 891 }, { 8, 0, 845 }, { 8, 0, 916 }, + { 7, 10, 1409 }, { 5, 0, 31 }, { 6, 0, 614 }, { 11, 0, 458 }, + { 12, 0, 15 }, { 12, 0, 432 }, { 8, 0, 330 }, { 12, 0, 477 }, + { 4, 0, 530 }, { 5, 0, 521 }, { 7, 0, 1200 }, { 10, 0, 460 }, + { 4, 11, 687 }, { 6, 0, 424 }, { 7, 0, 1866 }, { 9, 0, 569 }, + { 12, 0, 12 }, { 12, 0, 81 }, { 12, 0, 319 }, { 13, 0, 69 }, + { 14, 0, 259 }, { 16, 0, 87 }, { 17, 0, 1 }, { 17, 0, 21 }, + { 17, 0, 24 }, { 18, 0, 15 }, { 18, 0, 56 }, { 18, 0, 59 }, + { 18, 0, 127 }, { 18, 0, 154 }, { 19, 0, 19 }, { 20, 0, 31 }, + { 7, 0, 1302 }, { 8, 10, 38 }, { 6, 11, 253 }, { 5, 10, 261 }, + { 7, 10, 78 }, { 7, 10, 199 }, { 8, 10, 815 }, { 9, 10, 126 }, + { 10, 10, 342 }, { 5, 0, 595 }, { 7, 0, 1863 }, { 6, 11, 41 }, + { 13, 11, 160 }, { 5, 0, 13 }, { 6, 0, 142 }, { 6, 0, 97 }, + { 7, 0, 116 }, { 8, 0, 322 }, { 8, 0, 755 }, { 9, 0, 548 }, + { 10, 0, 714 }, { 11, 0, 884 }, { 13, 0, 324 }, { 7, 11, 1304 }, + { 10, 11, 477 }, { 4, 10, 628 }, { 6, 11, 1718 }, { 7, 10, 266 }, + { 8, 10, 804 }, { 7, 10, 208 }, { 7, 0, 1021 }, { 6, 10, 79 }, + { 7, 10, 1519 }, { 7, 0, 1472 }, { 7, 0, 1554 }, { 6, 11, 362 }, + { 18, 11, 51 }, { 7, 0, 1071 }, { 7, 0, 1541 }, { 7, 0, 1767 }, + { 7, 0, 1806 }, { 11, 0, 162 }, { 11, 0, 242 }, { 11, 0, 452 }, + { 12, 0, 605 }, { 15, 0, 26 }, { 16, 0, 44 }, { 8, 10, 741 }, + { 5, 11, 115 }, { 17, 0, 115 }, { 6, 10, 376 }, { 6, 0, 1406 }, + { 6, 0, 1543 }, { 5, 11, 193 }, { 12, 11, 178 }, { 13, 11, 130 }, + { 17, 11, 84 }, { 7, 0, 1111 }, { 8, 0, 1 }, { 9, 0, 650 }, + { 10, 0, 326 }, { 5, 11, 705 }, { 9, 11, 606 }, { 5, 0, 488 }, + { 6, 0, 527 }, { 7, 0, 489 }, { 7, 0, 1636 }, { 8, 0, 121 }, + { 8, 0, 144 }, { 8, 0, 359 }, { 9, 0, 193 }, { 9, 0, 241 }, + { 9, 0, 336 }, { 9, 0, 882 }, { 11, 0, 266 }, { 11, 0, 372 }, + { 11, 0, 944 }, { 12, 0, 401 }, { 12, 0, 641 }, { 7, 11, 174 }, + { 6, 0, 267 }, { 7, 10, 244 }, { 7, 10, 632 }, { 7, 10, 1609 }, + { 8, 10, 178 }, { 8, 10, 638 }, { 13, 10, 58 }, { 6, 0, 1983 }, + { 6, 0, 1155 }, { 6, 0, 1575 }, { 6, 0, 1438 }, { 9, 0, 31 }, + { 10, 0, 244 }, { 10, 0, 699 }, { 12, 0, 149 }, { 13, 0, 497 }, + { 5, 0, 377 }, { 4, 11, 122 }, { 5, 11, 796 }, { 5, 11, 952 }, + { 6, 11, 1660 }, { 6, 11, 1671 }, { 8, 11, 567 }, { 9, 11, 687 }, + { 9, 11, 742 }, { 10, 11, 686 }, { 11, 11, 356 }, { 11, 11, 682 }, + { 12, 11, 281 }, { 17, 0, 101 }, { 11, 11, 0 }, { 16, 11, 78 }, + { 5, 11, 179 }, { 5, 10, 791 }, { 7, 11, 1095 }, { 7, 11, 1213 }, + { 8, 11, 372 }, { 9, 11, 122 }, { 10, 11, 175 }, { 7, 10, 686 }, + { 8, 10, 33 }, { 8, 10, 238 }, { 10, 10, 616 }, { 11, 10, 467 }, + { 11, 10, 881 }, { 13, 10, 217 }, { 13, 10, 253 }, { 14, 10, 268 }, + { 9, 0, 476 }, { 4, 11, 66 }, { 7, 11, 722 }, { 7, 11, 904 }, + { 7, 11, 352 }, { 9, 11, 684 }, { 7, 0, 2023 }, { 7, 0, 1836 }, + { 4, 10, 447 }, { 5, 0, 843 }, { 16, 0, 35 }, { 9, 11, 779 }, + { 13, 11, 35 }, { 4, 10, 128 }, { 5, 10, 415 }, { 6, 10, 462 }, + { 7, 10, 294 }, { 7, 10, 578 }, { 10, 10, 710 }, { 11, 10, 86 }, + { 4, 0, 554 }, { 5, 0, 536 }, { 8, 10, 587 }, { 5, 0, 207 }, + { 9, 0, 79 }, { 11, 0, 625 }, { 17, 0, 7 }, { 7, 0, 1371 }, + { 6, 10, 427 }, { 10, 10, 692 }, { 4, 0, 424 }, { 4, 10, 195 }, + { 7, 10, 802 }, { 8, 0, 785 }, { 5, 11, 564 }, { 7, 0, 336 }, + { 4, 0, 896 }, { 6, 0, 1777 }, { 6, 11, 556 }, { 9, 11, 103 }, + { 6, 10, 1683 }, { 7, 11, 544 }, { 8, 11, 719 }, { 10, 11, 61 }, + { 10, 10, 472 }, { 4, 11, 5 }, { 5, 11, 498 }, { 8, 11, 637 }, + { 7, 0, 750 }, { 9, 0, 223 }, { 11, 0, 27 }, { 11, 0, 466 }, + { 12, 0, 624 }, { 14, 0, 265 }, { 18, 0, 61 }, { 12, 0, 238 }, + { 18, 0, 155 }, { 12, 11, 238 }, { 18, 11, 155 }, { 23, 10, 28 }, + { 5, 11, 927 }, { 12, 0, 383 }, { 5, 10, 3 }, { 8, 10, 578 }, + { 9, 10, 118 }, { 10, 10, 705 }, { 13, 10, 279 }, { 4, 11, 893 }, + { 5, 11, 780 }, { 5, 11, 893 }, { 4, 0, 603 }, { 5, 0, 661 }, + { 4, 0, 11 }, { 6, 0, 128 }, { 7, 0, 231 }, { 7, 0, 1533 }, + { 10, 0, 725 }, { 5, 10, 229 }, { 5, 11, 238 }, { 7, 11, 1350 }, + { 8, 10, 102 }, { 10, 10, 578 }, { 10, 10, 672 }, { 12, 10, 496 }, + { 13, 10, 408 }, { 14, 10, 121 }, { 17, 10, 106 }, { 4, 0, 476 }, + { 6, 0, 1552 }, { 6, 11, 1729 }, { 8, 10, 115 }, { 8, 10, 350 }, + { 9, 10, 489 }, { 10, 10, 128 }, { 11, 10, 306 }, { 12, 10, 373 }, + { 14, 10, 30 }, { 17, 10, 79 }, { 19, 10, 80 }, { 22, 10, 55 }, + { 7, 0, 1807 }, { 4, 0, 680 }, { 4, 11, 60 }, { 7, 11, 760 }, + { 7, 11, 1800 }, { 8, 11, 314 }, { 9, 11, 700 }, { 11, 11, 487 }, + { 4, 10, 230 }, { 5, 10, 702 }, { 20, 11, 94 }, { 4, 11, 228 }, + { 11, 0, 435 }, { 9, 0, 20 }, { 10, 0, 324 }, { 10, 0, 807 }, + { 11, 0, 488 }, { 6, 10, 1728 }, { 8, 11, 419 }, { 4, 10, 484 }, + { 18, 10, 26 }, { 19, 10, 42 }, { 20, 10, 43 }, { 21, 10, 0 }, + { 23, 10, 27 }, { 24, 10, 14 }, { 7, 0, 1431 }, { 5, 11, 828 }, + { 5, 0, 112 }, { 6, 0, 103 }, { 6, 0, 150 }, { 7, 0, 1303 }, + { 9, 0, 292 }, { 10, 0, 481 }, { 20, 0, 13 }, { 7, 11, 176 }, + { 7, 11, 178 }, { 7, 11, 1110 }, { 10, 11, 481 }, { 20, 11, 13 }, + { 10, 0, 356 }, { 4, 11, 51 }, { 5, 11, 39 }, { 6, 11, 4 }, + { 7, 11, 591 }, { 7, 11, 849 }, { 7, 11, 951 }, { 7, 11, 1129 }, + { 7, 11, 1613 }, { 7, 11, 1760 }, { 7, 11, 1988 }, { 9, 11, 434 }, + { 10, 11, 754 }, { 11, 11, 25 }, { 11, 11, 37 }, { 11, 11, 414 }, + { 6, 0, 1963 }, { 6, 0, 2000 }, { 4, 10, 633 }, { 6, 0, 1244 }, + { 5, 11, 902 }, { 7, 11, 928 }, { 12, 0, 18 }, { 10, 0, 204 }, + { 7, 11, 1173 }, { 6, 0, 867 }, { 4, 0, 708 }, { 8, 0, 15 }, + { 9, 0, 50 }, { 9, 0, 386 }, { 11, 0, 18 }, { 11, 0, 529 }, + { 12, 0, 228 }, { 6, 11, 270 }, { 4, 0, 563 }, { 7, 0, 109 }, + { 7, 0, 592 }, { 7, 0, 637 }, { 7, 0, 770 }, { 8, 0, 463 }, + { 9, 0, 60 }, { 9, 0, 335 }, { 9, 0, 904 }, { 10, 0, 73 }, + { 11, 0, 434 }, { 12, 0, 585 }, { 13, 0, 331 }, { 18, 0, 110 }, + { 20, 0, 60 }, { 4, 0, 502 }, { 14, 11, 359 }, { 19, 11, 52 }, + { 20, 11, 47 }, { 6, 11, 377 }, { 7, 11, 1025 }, { 9, 11, 613 }, + { 17, 11, 104 }, { 6, 0, 347 }, { 10, 0, 161 }, { 5, 10, 70 }, + { 5, 10, 622 }, { 6, 10, 334 }, { 7, 10, 1032 }, { 9, 10, 171 }, + { 11, 10, 26 }, { 11, 10, 213 }, { 11, 10, 637 }, { 11, 10, 707 }, + { 12, 10, 202 }, { 12, 10, 380 }, { 13, 10, 226 }, { 13, 10, 355 }, + { 14, 10, 222 }, { 17, 10, 42 }, { 4, 11, 416 }, { 4, 0, 33 }, + { 5, 0, 102 }, { 6, 0, 284 }, { 7, 0, 1079 }, { 7, 0, 1423 }, + { 7, 0, 1702 }, { 8, 0, 470 }, { 9, 0, 554 }, { 9, 0, 723 }, + { 11, 0, 333 }, { 14, 11, 372 }, { 5, 11, 152 }, { 5, 11, 197 }, + { 7, 11, 340 }, { 7, 11, 867 }, { 10, 11, 548 }, { 10, 11, 581 }, + { 11, 11, 6 }, { 12, 11, 3 }, { 12, 11, 19 }, { 14, 11, 110 }, + { 14, 11, 289 }, { 7, 0, 246 }, { 7, 0, 840 }, { 6, 0, 10 }, + { 8, 0, 571 }, { 9, 0, 739 }, { 15, 0, 91 }, { 6, 0, 465 }, + { 7, 0, 1465 }, { 4, 10, 23 }, { 4, 10, 141 }, { 5, 10, 313 }, + { 5, 10, 1014 }, { 6, 10, 50 }, { 7, 10, 142 }, { 7, 10, 559 }, + { 8, 10, 640 }, { 9, 10, 460 }, { 9, 10, 783 }, { 11, 10, 741 }, + { 12, 10, 183 }, { 13, 10, 488 }, { 5, 0, 626 }, { 8, 0, 614 }, + { 10, 0, 237 }, { 7, 11, 34 }, { 7, 11, 190 }, { 8, 11, 28 }, + { 8, 11, 141 }, { 8, 11, 444 }, { 8, 11, 811 }, { 9, 11, 468 }, + { 11, 11, 334 }, { 12, 11, 24 }, { 12, 11, 386 }, { 12, 11, 576 }, + { 5, 11, 757 }, { 5, 0, 18 }, { 6, 0, 526 }, { 13, 0, 24 }, + { 13, 0, 110 }, { 19, 0, 5 }, { 19, 0, 44 }, { 6, 0, 506 }, + { 6, 11, 506 }, { 7, 11, 1553 }, { 4, 0, 309 }, { 5, 0, 462 }, + { 7, 0, 970 }, { 7, 0, 1097 }, { 22, 0, 30 }, { 22, 0, 33 }, + { 7, 11, 1385 }, { 11, 11, 582 }, { 11, 11, 650 }, { 11, 11, 901 }, + { 11, 11, 949 }, { 12, 11, 232 }, { 12, 11, 236 }, { 13, 11, 413 }, + { 13, 11, 501 }, { 18, 11, 116 }, { 9, 0, 140 }, { 5, 10, 222 }, + { 10, 10, 534 }, { 6, 0, 1056 }, { 9, 10, 906 }, { 6, 0, 1704 }, + { 10, 10, 503 }, { 6, 0, 1036 }, { 5, 10, 154 }, { 7, 10, 1491 }, + { 10, 10, 379 }, { 10, 10, 485 }, { 4, 11, 383 }, { 5, 10, 716 }, + { 6, 0, 1315 }, { 5, 0, 86 }, { 7, 0, 743 }, { 9, 0, 85 }, + { 10, 0, 281 }, { 10, 0, 432 }, { 11, 0, 825 }, { 12, 0, 251 }, + { 13, 0, 118 }, { 14, 0, 378 }, { 8, 0, 264 }, { 4, 10, 91 }, + { 5, 10, 388 }, { 5, 10, 845 }, { 6, 10, 206 }, { 6, 10, 252 }, + { 6, 10, 365 }, { 7, 10, 136 }, { 7, 10, 531 }, { 8, 10, 621 }, + { 5, 0, 524 }, { 5, 0, 744 }, { 5, 11, 277 }, { 13, 11, 247 }, + { 4, 11, 435 }, { 10, 0, 107 }, { 12, 0, 436 }, { 4, 0, 927 }, + { 10, 0, 123 }, { 12, 0, 670 }, { 18, 0, 94 }, { 7, 0, 1149 }, + { 9, 0, 156 }, { 10, 0, 957 }, { 5, 11, 265 }, { 6, 11, 212 }, + { 7, 11, 28 }, { 5, 0, 778 }, { 5, 0, 502 }, { 8, 0, 196 }, + { 10, 0, 283 }, { 11, 0, 406 }, { 7, 10, 576 }, { 8, 11, 535 }, + { 6, 0, 1312 }, { 5, 10, 771 }, { 5, 10, 863 }, { 5, 10, 898 }, + { 6, 10, 1632 }, { 6, 10, 1644 }, { 6, 10, 1780 }, { 5, 0, 855 }, + { 5, 10, 331 }, { 7, 11, 1487 }, { 4, 11, 702 }, { 5, 11, 808 }, + { 7, 11, 2045 }, { 7, 0, 1400 }, { 9, 0, 446 }, { 10, 0, 45 }, + { 12, 10, 632 }, { 4, 0, 1003 }, { 5, 11, 166 }, { 8, 11, 739 }, + { 12, 11, 511 }, { 5, 10, 107 }, { 7, 10, 201 }, { 8, 10, 518 }, + { 6, 10, 446 }, { 7, 10, 1817 }, { 6, 0, 1532 }, { 6, 0, 1097 }, + { 4, 11, 119 }, { 5, 11, 170 }, { 5, 11, 447 }, { 7, 11, 1708 }, + { 7, 11, 1889 }, { 9, 11, 357 }, { 9, 11, 719 }, { 12, 11, 486 }, + { 12, 11, 596 }, { 9, 10, 851 }, { 13, 10, 510 }, { 7, 0, 612 }, + { 8, 0, 545 }, { 8, 0, 568 }, { 8, 0, 642 }, { 9, 0, 717 }, + { 10, 0, 541 }, { 10, 0, 763 }, { 11, 0, 449 }, { 12, 0, 489 }, + { 13, 0, 153 }, { 13, 0, 296 }, { 14, 0, 138 }, { 14, 0, 392 }, + { 15, 0, 50 }, { 16, 0, 6 }, { 16, 0, 12 }, { 20, 0, 9 }, + { 4, 10, 504 }, { 4, 11, 450 }, { 7, 11, 1158 }, { 11, 0, 54 }, + { 13, 0, 173 }, { 13, 0, 294 }, { 5, 10, 883 }, { 5, 10, 975 }, + { 8, 10, 392 }, { 20, 10, 7 }, { 13, 0, 455 }, { 15, 0, 99 }, + { 15, 0, 129 }, { 16, 0, 68 }, { 7, 0, 172 }, { 4, 11, 754 }, + { 5, 10, 922 }, { 6, 10, 1707 }, { 6, 0, 1029 }, { 17, 11, 39 }, + { 20, 11, 36 }, { 4, 0, 568 }, { 5, 10, 993 }, { 7, 10, 515 }, + { 9, 10, 91 }, { 4, 0, 732 }, { 10, 0, 617 }, { 10, 11, 617 }, + { 6, 0, 974 }, { 7, 0, 989 }, { 10, 0, 377 }, { 12, 0, 363 }, + { 13, 0, 68 }, { 13, 0, 94 }, { 14, 0, 108 }, { 14, 0, 306 }, + { 8, 0, 733 }, { 4, 0, 428 }, { 7, 0, 1789 }, { 7, 11, 1062 }, + { 7, 0, 2015 }, { 12, 0, 665 }, { 7, 10, 1433 }, { 5, 0, 287 }, + { 7, 10, 921 }, { 8, 10, 580 }, { 8, 10, 593 }, { 8, 10, 630 }, + { 10, 10, 28 }, { 10, 0, 806 }, { 4, 10, 911 }, { 5, 10, 867 }, + { 5, 10, 1013 }, { 7, 10, 2034 }, { 8, 10, 798 }, { 8, 10, 813 }, + { 6, 0, 1539 }, { 8, 11, 523 }, { 22, 11, 34 }, { 7, 11, 740 }, + { 7, 11, 238 }, { 7, 11, 2033 }, { 8, 11, 120 }, { 8, 11, 188 }, + { 8, 11, 659 }, { 9, 11, 598 }, { 10, 11, 466 }, { 12, 11, 342 }, + { 12, 11, 588 }, { 13, 11, 503 }, { 14, 11, 246 }, { 15, 11, 92 }, + { 7, 0, 1563 }, { 13, 0, 182 }, { 5, 10, 135 }, { 6, 10, 519 }, + { 7, 10, 1722 }, { 10, 10, 271 }, { 11, 10, 261 }, { 17, 10, 54 }, + { 14, 10, 338 }, { 20, 10, 81 }, { 7, 0, 484 }, { 4, 10, 300 }, + { 5, 10, 436 }, { 17, 11, 114 }, { 6, 0, 1623 }, { 6, 0, 1681 }, + { 5, 11, 640 }, { 4, 11, 201 }, { 7, 11, 1744 }, { 8, 11, 602 }, + { 11, 11, 247 }, { 11, 11, 826 }, { 17, 11, 65 }, { 8, 11, 164 }, + { 18, 11, 62 }, { 6, 0, 1833 }, { 6, 0, 1861 }, { 8, 0, 878 }, + { 6, 0, 1569 }, { 8, 10, 357 }, { 10, 10, 745 }, { 14, 10, 426 }, + { 17, 10, 94 }, { 19, 10, 57 }, { 12, 0, 93 }, { 12, 0, 501 }, + { 13, 0, 362 }, { 14, 0, 151 }, { 15, 0, 40 }, { 15, 0, 59 }, + { 16, 0, 46 }, { 17, 0, 25 }, { 18, 0, 14 }, { 18, 0, 134 }, + { 19, 0, 25 }, { 19, 0, 69 }, { 20, 0, 16 }, { 20, 0, 19 }, + { 20, 0, 66 }, { 21, 0, 23 }, { 21, 0, 25 }, { 22, 0, 42 }, + { 6, 0, 1748 }, { 8, 0, 715 }, { 9, 0, 802 }, { 10, 0, 46 }, + { 10, 0, 819 }, { 13, 0, 308 }, { 14, 0, 351 }, { 14, 0, 363 }, + { 18, 0, 67 }, { 4, 0, 994 }, { 4, 0, 63 }, { 5, 0, 347 }, + { 4, 0, 591 }, { 5, 0, 749 }, { 7, 11, 1577 }, { 10, 11, 304 }, + { 10, 11, 549 }, { 11, 11, 424 }, { 12, 11, 365 }, { 13, 11, 220 }, + { 13, 11, 240 }, { 14, 11, 33 }, { 5, 0, 366 }, { 7, 0, 557 }, + { 12, 0, 547 }, { 14, 0, 86 }, { 5, 10, 387 }, { 7, 0, 1747 }, + { 4, 11, 907 }, { 5, 11, 100 }, { 10, 11, 329 }, { 12, 11, 416 }, + { 21, 11, 29 }, { 4, 10, 6 }, { 5, 10, 708 }, { 8, 10, 75 }, + { 7, 10, 1351 }, { 9, 10, 581 }, { 10, 10, 639 }, { 11, 10, 453 }, + { 12, 10, 584 }, { 7, 0, 89 }, { 4, 10, 303 }, { 10, 10, 772 }, + { 4, 11, 176 }, { 5, 11, 636 }, { 5, 11, 998 }, { 8, 11, 26 }, + { 9, 11, 358 }, { 7, 11, 9 }, { 7, 11, 1508 }, { 9, 11, 317 }, + { 10, 11, 210 }, { 10, 11, 292 }, { 10, 11, 533 }, { 11, 11, 555 }, + { 12, 11, 526 }, { 12, 11, 607 }, { 13, 11, 263 }, { 13, 11, 459 }, + { 14, 11, 271 }, { 6, 0, 1463 }, { 6, 0, 772 }, { 6, 0, 1137 }, + { 11, 11, 595 }, { 7, 0, 977 }, { 11, 11, 66 }, { 10, 0, 893 }, + { 20, 0, 48 }, { 20, 11, 48 }, { 5, 0, 824 }, { 5, 0, 941 }, + { 6, 11, 295 }, { 7, 0, 1543 }, { 7, 0, 1785 }, { 10, 0, 690 }, + { 4, 10, 106 }, { 11, 10, 717 }, { 7, 0, 440 }, { 8, 0, 230 }, + { 11, 0, 106 }, { 5, 10, 890 }, { 5, 10, 988 }, { 6, 10, 626 }, + { 14, 10, 431 }, { 10, 11, 127 }, { 13, 11, 27 }, { 17, 0, 32 }, + { 10, 10, 706 }, { 22, 10, 44 }, { 4, 0, 216 }, { 9, 0, 332 }, + { 4, 10, 698 }, { 8, 11, 119 }, { 11, 11, 267 }, { 10, 10, 17 }, + { 11, 11, 526 }, { 11, 11, 939 }, { 13, 11, 290 }, { 7, 11, 1167 }, + { 11, 11, 934 }, { 13, 11, 391 }, { 17, 11, 76 }, { 11, 11, 39 }, + { 6, 10, 84 }, { 4, 0, 914 }, { 5, 0, 800 }, { 5, 0, 852 }, + { 10, 0, 416 }, { 13, 0, 115 }, { 7, 0, 564 }, { 14, 0, 168 }, + { 4, 0, 918 }, { 5, 0, 876 }, { 6, 0, 1764 }, { 24, 0, 3 }, + { 4, 0, 92 }, { 5, 0, 274 }, { 7, 11, 126 }, { 8, 11, 84 }, + { 12, 10, 498 }, { 8, 11, 790 }, { 8, 0, 501 }, { 5, 10, 986 }, + { 6, 10, 130 }, { 7, 10, 1582 }, { 8, 10, 458 }, { 10, 10, 101 }, + { 10, 10, 318 }, { 10, 10, 823 }, { 6, 11, 64 }, { 12, 11, 377 }, + { 13, 11, 309 }, { 5, 0, 743 }, { 10, 0, 851 }, { 4, 0, 49 }, + { 7, 0, 280 }, { 7, 0, 1633 }, { 6, 0, 879 }, { 8, 0, 47 }, + { 7, 10, 1644 }, { 9, 10, 129 }, { 4, 0, 865 }, { 6, 0, 1202 }, + { 9, 11, 34 }, { 11, 11, 484 }, { 7, 10, 997 }, { 5, 0, 272 }, + { 5, 0, 908 }, { 5, 0, 942 }, { 8, 0, 197 }, { 9, 0, 47 }, + { 11, 0, 538 }, { 11, 0, 742 }, { 6, 11, 1700 }, { 7, 11, 26 }, + { 7, 11, 293 }, { 7, 11, 382 }, { 7, 11, 1026 }, { 7, 11, 1087 }, + { 7, 11, 2027 }, { 8, 11, 24 }, { 8, 11, 114 }, { 8, 11, 252 }, + { 8, 11, 727 }, { 8, 11, 729 }, { 9, 11, 30 }, { 9, 11, 199 }, + { 9, 11, 231 }, { 9, 11, 251 }, { 9, 11, 334 }, { 9, 11, 361 }, + { 9, 11, 488 }, { 9, 11, 712 }, { 10, 11, 55 }, { 10, 11, 60 }, + { 10, 11, 232 }, { 10, 11, 332 }, { 10, 11, 384 }, { 10, 11, 396 }, + { 10, 11, 504 }, { 10, 11, 542 }, { 10, 11, 652 }, { 11, 11, 20 }, + { 11, 11, 48 }, { 11, 11, 207 }, { 11, 11, 291 }, { 11, 11, 298 }, + { 11, 11, 342 }, { 11, 11, 365 }, { 11, 11, 394 }, { 11, 11, 620 }, + { 11, 11, 705 }, { 11, 11, 1017 }, { 12, 11, 123 }, { 12, 11, 340 }, + { 12, 11, 406 }, { 12, 11, 643 }, { 13, 11, 61 }, { 13, 11, 269 }, + { 13, 11, 311 }, { 13, 11, 319 }, { 13, 11, 486 }, { 14, 11, 234 }, + { 15, 11, 62 }, { 15, 11, 85 }, { 16, 11, 71 }, { 18, 11, 119 }, + { 20, 11, 105 }, { 6, 0, 1455 }, { 22, 11, 37 }, { 7, 10, 1927 }, + { 7, 0, 1911 }, { 9, 0, 891 }, { 7, 10, 1756 }, { 9, 10, 98 }, + { 7, 10, 1046 }, { 11, 10, 160 }, { 4, 0, 761 }, { 6, 11, 379 }, + { 7, 11, 270 }, { 7, 11, 1116 }, { 8, 11, 176 }, { 8, 11, 183 }, + { 9, 11, 432 }, { 9, 11, 661 }, { 12, 11, 247 }, { 12, 11, 617 }, + { 18, 11, 125 }, { 6, 10, 45 }, { 7, 10, 433 }, { 8, 10, 129 }, + { 9, 10, 21 }, { 10, 10, 392 }, { 11, 10, 79 }, { 12, 10, 499 }, + { 13, 10, 199 }, { 13, 10, 451 }, { 4, 0, 407 }, { 5, 11, 792 }, + { 5, 11, 900 }, { 4, 0, 560 }, { 7, 0, 183 }, { 13, 0, 490 }, + { 7, 10, 558 }, { 8, 10, 353 }, { 4, 0, 475 }, { 6, 0, 731 }, + { 11, 0, 35 }, { 13, 0, 71 }, { 13, 0, 177 }, { 14, 0, 422 }, + { 5, 10, 785 }, { 8, 10, 81 }, { 9, 10, 189 }, { 9, 10, 201 }, + { 11, 10, 478 }, { 11, 10, 712 }, { 13, 10, 338 }, { 4, 0, 418 }, + { 4, 0, 819 }, { 5, 10, 353 }, { 23, 10, 26 }, { 4, 11, 901 }, + { 5, 11, 776 }, { 4, 0, 575 }, { 7, 0, 818 }, { 16, 0, 92 }, + { 17, 0, 14 }, { 17, 0, 45 }, { 18, 0, 75 }, { 20, 0, 18 }, + { 6, 0, 222 }, { 7, 0, 636 }, { 7, 0, 1620 }, { 8, 0, 409 }, + { 9, 0, 693 }, { 11, 0, 77 }, { 6, 10, 25 }, { 7, 10, 855 }, + { 7, 10, 1258 }, { 16, 10, 32 }, { 6, 0, 1880 }, { 6, 0, 1887 }, + { 6, 0, 1918 }, { 6, 0, 1924 }, { 9, 0, 967 }, { 9, 0, 995 }, + { 9, 0, 1015 }, { 12, 0, 826 }, { 12, 0, 849 }, { 12, 0, 857 }, + { 12, 0, 860 }, { 12, 0, 886 }, { 12, 0, 932 }, { 18, 0, 228 }, + { 18, 0, 231 }, { 18, 0, 240 }, { 6, 0, 633 }, { 6, 0, 1308 }, + { 4, 11, 37 }, { 5, 11, 334 }, { 7, 11, 1253 }, { 10, 0, 86 }, + { 4, 10, 4 }, { 7, 10, 1118 }, { 7, 10, 1320 }, { 7, 10, 1706 }, + { 8, 10, 277 }, { 9, 10, 622 }, { 11, 10, 724 }, { 12, 10, 350 }, + { 12, 10, 397 }, { 13, 10, 28 }, { 13, 10, 159 }, { 15, 10, 89 }, + { 18, 10, 5 }, { 19, 10, 9 }, { 20, 10, 34 }, { 22, 10, 47 }, + { 4, 11, 508 }, { 9, 11, 448 }, { 12, 11, 107 }, { 18, 11, 31 }, + { 4, 0, 817 }, { 6, 0, 663 }, { 5, 0, 882 }, { 6, 0, 914 }, + { 4, 11, 540 }, { 4, 11, 533 }, { 8, 11, 608 }, { 8, 0, 885 }, + { 10, 0, 865 }, { 4, 0, 426 }, { 6, 0, 58 }, { 7, 0, 745 }, + { 7, 0, 1969 }, { 8, 0, 399 }, { 8, 0, 675 }, { 9, 0, 479 }, + { 9, 0, 731 }, { 10, 0, 330 }, { 10, 0, 593 }, { 10, 0, 817 }, + { 11, 0, 32 }, { 11, 0, 133 }, { 11, 0, 221 }, { 17, 0, 68 }, + { 6, 10, 255 }, { 7, 0, 102 }, { 9, 0, 538 }, { 9, 10, 216 }, + { 7, 11, 253 }, { 8, 11, 549 }, { 7, 11, 912 }, { 9, 10, 183 }, + { 11, 10, 286 }, { 11, 10, 956 }, { 23, 10, 3 }, { 8, 11, 527 }, + { 18, 11, 60 }, { 19, 11, 24 }, { 4, 10, 536 }, { 7, 10, 1141 }, + { 10, 10, 723 }, { 11, 10, 371 }, { 5, 11, 920 }, { 7, 0, 876 }, + { 7, 10, 285 }, { 7, 10, 560 }, { 4, 10, 690 }, { 14, 11, 126 }, + { 11, 10, 33 }, { 12, 10, 571 }, { 21, 10, 1 }, { 5, 0, 566 }, + { 9, 0, 139 }, { 10, 0, 399 }, { 11, 0, 469 }, { 12, 0, 634 }, + { 13, 0, 223 }, { 4, 11, 483 }, { 6, 0, 48 }, { 7, 0, 63 }, + { 18, 0, 12 }, { 7, 10, 1862 }, { 12, 10, 491 }, { 12, 10, 520 }, + { 13, 10, 383 }, { 14, 10, 244 }, { 7, 11, 1665 }, { 4, 11, 448 }, + { 9, 11, 495 }, { 18, 11, 104 }, { 6, 0, 114 }, { 7, 0, 1224 }, + { 7, 0, 1556 }, { 8, 0, 3 }, { 4, 10, 190 }, { 5, 10, 554 }, + { 8, 0, 576 }, { 9, 0, 267 }, { 5, 10, 1001 }, { 5, 10, 446 }, + { 5, 0, 933 }, { 11, 11, 1009 }, { 8, 11, 653 }, { 13, 11, 93 }, + { 19, 11, 14 }, { 6, 0, 692 }, { 6, 0, 821 }, { 6, 0, 1077 }, + { 5, 11, 172 }, { 7, 11, 801 }, { 10, 0, 752 }, { 4, 0, 375 }, + { 6, 0, 638 }, { 6, 0, 1011 }, { 12, 11, 540 }, { 9, 0, 96 }, + { 5, 11, 260 }, { 11, 11, 587 }, { 7, 10, 1231 }, { 12, 0, 30 }, + { 13, 0, 148 }, { 14, 0, 87 }, { 14, 0, 182 }, { 16, 0, 42 }, + { 20, 0, 70 }, { 4, 10, 304 }, { 6, 0, 1398 }, { 7, 0, 56 }, + { 7, 0, 1989 }, { 8, 0, 337 }, { 8, 0, 738 }, { 9, 0, 600 }, + { 12, 0, 37 }, { 13, 0, 447 }, { 14, 0, 92 }, { 10, 0, 666 }, + { 5, 0, 394 }, { 7, 0, 487 }, { 8, 0, 246 }, { 9, 0, 437 }, + { 6, 10, 53 }, { 6, 10, 199 }, { 7, 10, 1408 }, { 8, 10, 32 }, + { 8, 10, 93 }, { 10, 10, 397 }, { 10, 10, 629 }, { 11, 10, 593 }, + { 11, 10, 763 }, { 13, 10, 326 }, { 17, 10, 35 }, { 6, 10, 105 }, + { 9, 0, 320 }, { 10, 0, 506 }, { 10, 10, 794 }, { 7, 11, 57 }, + { 8, 11, 167 }, { 8, 11, 375 }, { 9, 11, 82 }, { 9, 11, 561 }, + { 10, 11, 620 }, { 10, 11, 770 }, { 11, 10, 704 }, { 13, 10, 396 }, + { 6, 0, 1003 }, { 5, 10, 114 }, { 5, 10, 255 }, { 13, 10, 285 }, + { 7, 0, 866 }, { 7, 0, 1163 }, { 5, 11, 531 }, { 4, 0, 328 }, + { 7, 10, 2035 }, { 8, 10, 19 }, { 9, 10, 89 }, { 10, 10, 831 }, + { 8, 11, 194 }, { 8, 11, 756 }, { 8, 0, 1000 }, { 5, 11, 453 }, + { 6, 11, 441 }, { 4, 0, 101 }, { 5, 0, 833 }, { 7, 0, 1171 }, + { 8, 0, 744 }, { 5, 0, 726 }, { 8, 10, 746 }, { 10, 0, 176 }, + { 6, 0, 9 }, { 6, 0, 397 }, { 7, 0, 53 }, { 7, 0, 1742 }, + { 10, 0, 632 }, { 11, 0, 828 }, { 12, 0, 146 }, { 7, 11, 22 }, + { 17, 11, 64 }, { 4, 0, 839 }, { 11, 0, 417 }, { 12, 0, 223 }, + { 12, 0, 265 }, { 4, 11, 102 }, { 7, 11, 815 }, { 7, 11, 1699 }, + { 11, 11, 964 }, { 5, 10, 955 }, { 8, 10, 814 }, { 6, 0, 1931 }, + { 6, 0, 2007 }, { 18, 0, 246 }, { 18, 0, 247 }, { 8, 0, 198 }, + { 11, 0, 29 }, { 12, 0, 534 }, { 7, 0, 1771 }, { 6, 0, 846 }, + { 7, 11, 1010 }, { 11, 11, 733 }, { 11, 11, 759 }, { 12, 11, 563 }, + { 13, 11, 34 }, { 14, 11, 101 }, { 18, 11, 45 }, { 18, 11, 129 }, + { 4, 0, 186 }, { 5, 0, 157 }, { 8, 0, 168 }, { 10, 0, 6 }, + { 4, 11, 899 }, { 5, 10, 56 }, { 20, 10, 100 }, { 5, 0, 875 }, + { 5, 0, 773 }, { 5, 0, 991 }, { 6, 0, 1635 }, { 6, 0, 1788 }, + { 6, 0, 1274 }, { 9, 0, 477 }, { 13, 0, 78 }, { 4, 0, 639 }, + { 7, 0, 111 }, { 8, 0, 581 }, { 12, 0, 177 }, { 6, 11, 52 }, + { 9, 11, 104 }, { 9, 11, 559 }, { 10, 10, 4 }, { 10, 10, 13 }, + { 11, 10, 638 }, { 12, 11, 308 }, { 19, 11, 87 }, { 20, 10, 57 }, + { 4, 11, 604 }, { 4, 11, 301 }, { 5, 10, 738 }, { 5, 10, 758 }, + { 6, 0, 1747 }, { 7, 11, 1440 }, { 11, 11, 854 }, { 11, 11, 872 }, + { 11, 11, 921 }, { 12, 11, 551 }, { 13, 11, 472 }, { 14, 11, 367 }, + { 7, 0, 1364 }, { 7, 0, 1907 }, { 13, 0, 158 }, { 6, 0, 873 }, + { 4, 0, 404 }, { 4, 0, 659 }, { 7, 0, 552 }, { 7, 0, 675 }, + { 7, 10, 1112 }, { 11, 10, 328 }, { 7, 11, 508 }, { 9, 10, 133 }, + { 5, 0, 391 }, { 5, 10, 110 }, { 6, 10, 169 }, { 6, 10, 1702 }, + { 7, 10, 400 }, { 8, 10, 538 }, { 9, 10, 184 }, { 9, 10, 524 }, + { 12, 10, 218 }, { 6, 11, 310 }, { 7, 11, 1849 }, { 8, 11, 72 }, + { 8, 11, 272 }, { 8, 11, 431 }, { 9, 11, 12 }, { 9, 11, 351 }, + { 10, 11, 563 }, { 10, 11, 630 }, { 10, 11, 810 }, { 11, 11, 367 }, + { 11, 11, 599 }, { 11, 11, 686 }, { 12, 11, 672 }, { 5, 0, 540 }, + { 6, 0, 1697 }, { 8, 0, 668 }, { 4, 0, 883 }, { 6, 0, 78 }, + { 12, 0, 628 }, { 18, 0, 79 }, { 6, 10, 133 }, { 9, 10, 353 }, + { 11, 10, 993 }, { 6, 11, 181 }, { 7, 11, 537 }, { 8, 11, 64 }, + { 9, 11, 127 }, { 10, 11, 496 }, { 12, 11, 510 }, { 13, 11, 384 }, + { 6, 10, 93 }, { 7, 10, 1422 }, { 7, 10, 1851 }, { 8, 10, 673 }, + { 9, 10, 529 }, { 12, 10, 43 }, { 9, 10, 371 }, { 6, 0, 1460 }, + { 6, 0, 962 }, { 4, 11, 244 }, { 7, 11, 233 }, { 9, 10, 25 }, + { 10, 10, 467 }, { 10, 10, 559 }, { 4, 10, 335 }, { 7, 10, 942 }, + { 5, 0, 460 }, { 7, 11, 334 }, { 6, 11, 1650 }, { 4, 0, 199 }, + { 11, 0, 34 }, { 5, 10, 601 }, { 8, 10, 39 }, { 10, 10, 773 }, + { 11, 10, 84 }, { 12, 10, 205 }, { 14, 10, 1 }, { 5, 10, 870 }, + { 6, 0, 388 }, { 14, 0, 474 }, { 20, 0, 120 }, { 5, 11, 369 }, + { 11, 0, 271 }, { 4, 0, 511 }, { 9, 0, 333 }, { 9, 0, 379 }, + { 10, 0, 602 }, { 11, 0, 441 }, { 11, 0, 723 }, { 11, 0, 976 }, + { 12, 0, 357 }, { 4, 10, 181 }, { 6, 0, 608 }, { 6, 10, 1652 }, + { 22, 0, 49 }, { 9, 11, 338 }, { 12, 0, 988 }, { 6, 0, 617 }, + { 5, 0, 938 }, { 8, 0, 707 }, { 4, 10, 97 }, { 5, 10, 147 }, + { 6, 10, 286 }, { 7, 10, 1362 }, { 13, 10, 176 }, { 6, 0, 756 }, + { 6, 0, 1149 }, { 5, 11, 896 }, { 6, 10, 375 }, { 7, 10, 169 }, + { 7, 10, 254 }, { 8, 10, 780 }, { 6, 0, 1583 }, { 7, 10, 1447 }, + { 11, 0, 285 }, { 7, 11, 1117 }, { 8, 11, 393 }, { 8, 11, 539 }, + { 7, 0, 344 }, { 6, 0, 469 }, { 7, 0, 1709 }, { 10, 0, 515 }, + { 5, 10, 629 }, { 7, 10, 1549 }, { 5, 11, 4 }, { 5, 11, 810 }, + { 6, 11, 13 }, { 6, 11, 538 }, { 6, 11, 1690 }, { 6, 11, 1726 }, + { 7, 11, 499 }, { 7, 11, 1819 }, { 8, 11, 148 }, { 8, 11, 696 }, + { 8, 11, 791 }, { 12, 11, 125 }, { 13, 11, 54 }, { 15, 11, 9 }, + { 7, 11, 1268 }, { 9, 0, 404 }, { 4, 0, 500 }, { 5, 0, 68 }, + { 6, 0, 383 }, { 11, 0, 216 }, { 11, 0, 340 }, { 4, 11, 925 }, + { 5, 11, 803 }, { 8, 11, 698 }, { 10, 11, 828 }, { 4, 0, 337 }, + { 6, 0, 353 }, { 7, 0, 1934 }, { 8, 0, 488 }, { 9, 0, 429 }, + { 7, 0, 236 }, { 7, 0, 1795 }, { 8, 0, 259 }, { 9, 0, 135 }, + { 9, 0, 177 }, { 9, 0, 860 }, { 10, 0, 825 }, { 11, 0, 115 }, + { 11, 0, 370 }, { 11, 0, 405 }, { 11, 0, 604 }, { 12, 0, 10 }, + { 12, 0, 667 }, { 12, 0, 669 }, { 13, 0, 76 }, { 14, 0, 310 }, + { 15, 0, 76 }, { 15, 0, 147 }, { 20, 0, 23 }, { 4, 0, 15 }, + { 4, 0, 490 }, { 5, 0, 22 }, { 6, 0, 244 }, { 7, 0, 40 }, + { 7, 0, 200 }, { 7, 0, 906 }, { 7, 0, 1199 }, { 9, 0, 616 }, + { 10, 0, 716 }, { 11, 0, 635 }, { 11, 0, 801 }, { 12, 0, 458 }, + { 12, 0, 756 }, { 4, 10, 420 }, { 6, 0, 1504 }, { 6, 0, 757 }, + { 5, 11, 383 }, { 6, 0, 1266 }, { 7, 0, 1735 }, { 5, 0, 598 }, + { 7, 0, 791 }, { 8, 0, 108 }, { 9, 0, 123 }, { 7, 10, 1570 }, + { 12, 10, 542 }, { 14, 11, 410 }, { 9, 11, 660 }, { 10, 11, 347 }, +}; + +} // namespace brotli + +#endif // BROTLI_ENC_DICTIONARY_LUT_H_ diff --git a/web/server/h2o/libh2o/deps/brotli/enc/streams.cc b/web/server/h2o/libh2o/deps/brotli/enc/streams.cc new file mode 100644 index 00000000..2ea766f2 --- /dev/null +++ b/web/server/h2o/libh2o/deps/brotli/enc/streams.cc @@ -0,0 +1,114 @@ +/* Copyright 2009 Google Inc. All Rights Reserved. + + Distributed under MIT license. + See file LICENSE for detail or copy at https://opensource.org/licenses/MIT +*/ + +// Convience routines to make Brotli I/O classes from some memory containers and +// files. + +#include "./streams.h" + +#include +#include +#include + +namespace brotli { + +BrotliMemOut::BrotliMemOut(void* buf, size_t len) + : buf_(buf), + len_(len), + pos_(0) {} + +void BrotliMemOut::Reset(void* buf, size_t len) { + buf_ = buf; + len_ = len; + pos_ = 0; +} + +// Brotli output routine: copy n bytes to the output buffer. +bool BrotliMemOut::Write(const void *buf, size_t n) { + if (n + pos_ > len_) + return false; + char* p = reinterpret_cast(buf_) + pos_; + memcpy(p, buf, n); + pos_ += n; + return true; +} + +BrotliStringOut::BrotliStringOut(std::string* buf, size_t max_size) + : buf_(buf), + max_size_(max_size) { + assert(buf->empty()); +} + +void BrotliStringOut::Reset(std::string* buf, size_t max_size) { + buf_ = buf; + max_size_ = max_size; +} + +// Brotli output routine: add n bytes to a string. +bool BrotliStringOut::Write(const void *buf, size_t n) { + if (buf_->size() + n > max_size_) + return false; + buf_->append(static_cast(buf), n); + return true; +} + +BrotliMemIn::BrotliMemIn(const void* buf, size_t len) + : buf_(buf), + len_(len), + pos_(0) {} + +void BrotliMemIn::Reset(const void* buf, size_t len) { + buf_ = buf; + len_ = len; + pos_ = 0; +} + +// Brotli input routine: read the next chunk of memory. +const void* BrotliMemIn::Read(size_t n, size_t* output) { + if (pos_ == len_) { + return NULL; + } + if (n > len_ - pos_) + n = len_ - pos_; + const char* p = reinterpret_cast(buf_) + pos_; + pos_ += n; + *output = n; + return p; +} + +BrotliFileIn::BrotliFileIn(FILE* f, size_t max_read_size) + : f_(f), + buf_(new char[max_read_size]), + buf_size_(max_read_size) { } + +BrotliFileIn::~BrotliFileIn() { + delete[] buf_; +} + +const void* BrotliFileIn::Read(size_t n, size_t* bytes_read) { + if (n > buf_size_) { + n = buf_size_; + } else if (n == 0) { + return feof(f_) ? NULL : buf_; + } + *bytes_read = fread(buf_, 1, n, f_); + if (*bytes_read == 0) { + return NULL; + } else { + return buf_; + } +} + +BrotliFileOut::BrotliFileOut(FILE* f) : f_(f) {} + +bool BrotliFileOut::Write(const void* buf, size_t n) { + if (fwrite(buf, n, 1, f_) != 1) { + return false; + } + return true; +} + +} // namespace brotli diff --git a/web/server/h2o/libh2o/deps/brotli/enc/streams.h b/web/server/h2o/libh2o/deps/brotli/enc/streams.h new file mode 100644 index 00000000..68fc23cc --- /dev/null +++ b/web/server/h2o/libh2o/deps/brotli/enc/streams.h @@ -0,0 +1,121 @@ +/* Copyright 2009 Google Inc. All Rights Reserved. + + Distributed under MIT license. + See file LICENSE for detail or copy at https://opensource.org/licenses/MIT +*/ + +// Input and output classes for streaming brotli compression. + +#ifndef BROTLI_ENC_STREAMS_H_ +#define BROTLI_ENC_STREAMS_H_ + +#include +#include +#include "./port.h" +#include "./types.h" + +namespace brotli { + +// Input interface for the compression routines. +class BrotliIn { + public: + virtual ~BrotliIn() {} + + // Return a pointer to the next block of input of at most n bytes. + // Return the actual length in *nread. + // At end of data, return NULL. Don't return NULL if there is more data + // to read, even if called with n == 0. + // Read will only be called if some of its bytes are needed. + virtual const void* Read(size_t n, size_t* nread) = 0; +}; + +// Output interface for the compression routines. +class BrotliOut { + public: + virtual ~BrotliOut() {} + + // Write n bytes of data from buf. + // Return true if all written, false otherwise. + virtual bool Write(const void *buf, size_t n) = 0; +}; + +// Adapter class to make BrotliIn objects from raw memory. +class BrotliMemIn : public BrotliIn { + public: + BrotliMemIn(const void* buf, size_t len); + + void Reset(const void* buf, size_t len); + + // returns the amount of data consumed + size_t position() const { return pos_; } + + const void* Read(size_t n, size_t* OUTPUT); + + private: + const void* buf_; // start of input buffer + size_t len_; // length of input + size_t pos_; // current read position within input +}; + +// Adapter class to make BrotliOut objects from raw memory. +class BrotliMemOut : public BrotliOut { + public: + BrotliMemOut(void* buf, size_t len); + + void Reset(void* buf, size_t len); + + // returns the amount of data written + size_t position() const { return pos_; } + + bool Write(const void* buf, size_t n); + + private: + void* buf_; // start of output buffer + size_t len_; // length of output + size_t pos_; // current write position within output +}; + +// Adapter class to make BrotliOut objects from a string. +class BrotliStringOut : public BrotliOut { + public: + // Create a writer that appends its data to buf. + // buf->size() will grow to at most max_size + // buf is expected to be empty when constructing BrotliStringOut. + BrotliStringOut(std::string* buf, size_t max_size); + + void Reset(std::string* buf, size_t max_len); + + bool Write(const void* buf, size_t n); + + private: + std::string* buf_; // start of output buffer + size_t max_size_; // max length of output +}; + +// Adapter class to make BrotliIn object from a file. +class BrotliFileIn : public BrotliIn { + public: + BrotliFileIn(FILE* f, size_t max_read_size); + ~BrotliFileIn(); + + const void* Read(size_t n, size_t* bytes_read); + + private: + FILE* f_; + char* buf_; + size_t buf_size_; +}; + +// Adapter class to make BrotliOut object from a file. +class BrotliFileOut : public BrotliOut { + public: + explicit BrotliFileOut(FILE* f); + + bool Write(const void* buf, size_t n); + private: + FILE* f_; +}; + +} // namespace brotli + +#endif // BROTLI_ENC_STREAMS_H_ diff --git a/web/server/h2o/libh2o/deps/brotli/enc/transform.h b/web/server/h2o/libh2o/deps/brotli/enc/transform.h new file mode 100644 index 00000000..ffd7f4c0 --- /dev/null +++ b/web/server/h2o/libh2o/deps/brotli/enc/transform.h @@ -0,0 +1,248 @@ +/* Copyright 2010 Google Inc. All Rights Reserved. + + Distributed under MIT license. + See file LICENSE for detail or copy at https://opensource.org/licenses/MIT +*/ + +// Transformations on dictionary words. + +#ifndef BROTLI_ENC_TRANSFORM_H_ +#define BROTLI_ENC_TRANSFORM_H_ + +#include + +#include "./dictionary.h" + +namespace brotli { + +enum WordTransformType { + kIdentity = 0, + kOmitLast1 = 1, + kOmitLast2 = 2, + kOmitLast3 = 3, + kOmitLast4 = 4, + kOmitLast5 = 5, + kOmitLast6 = 6, + kOmitLast7 = 7, + kOmitLast8 = 8, + kOmitLast9 = 9, + kUppercaseFirst = 10, + kUppercaseAll = 11, + kOmitFirst1 = 12, + kOmitFirst2 = 13, + kOmitFirst3 = 14, + kOmitFirst4 = 15, + kOmitFirst5 = 16, + kOmitFirst6 = 17, + kOmitFirst7 = 18, + kOmitFirst8 = 19, + kOmitFirst9 = 20 +}; + +struct Transform { + const char* prefix; + WordTransformType word_transform; + const char* suffix; +}; + +static const Transform kTransforms[] = { + { "", kIdentity, "" }, + { "", kIdentity, " " }, + { " ", kIdentity, " " }, + { "", kOmitFirst1, "" }, + { "", kUppercaseFirst, " " }, + { "", kIdentity, " the " }, + { " ", kIdentity, "" }, + { "s ", kIdentity, " " }, + { "", kIdentity, " of " }, + { "", kUppercaseFirst, "" }, + { "", kIdentity, " and " }, + { "", kOmitFirst2, "" }, + { "", kOmitLast1, "" }, + { ", ", kIdentity, " " }, + { "", kIdentity, ", " }, + { " ", kUppercaseFirst, " " }, + { "", kIdentity, " in " }, + { "", kIdentity, " to " }, + { "e ", kIdentity, " " }, + { "", kIdentity, "\"" }, + { "", kIdentity, "." }, + { "", kIdentity, "\">" }, + { "", kIdentity, "\n" }, + { "", kOmitLast3, "" }, + { "", kIdentity, "]" }, + { "", kIdentity, " for " }, + { "", kOmitFirst3, "" }, + { "", kOmitLast2, "" }, + { "", kIdentity, " a " }, + { "", kIdentity, " that " }, + { " ", kUppercaseFirst, "" }, + { "", kIdentity, ". " }, + { ".", kIdentity, "" }, + { " ", kIdentity, ", " }, + { "", kOmitFirst4, "" }, + { "", kIdentity, " with " }, + { "", kIdentity, "'" }, + { "", kIdentity, " from " }, + { "", kIdentity, " by " }, + { "", kOmitFirst5, "" }, + { "", kOmitFirst6, "" }, + { " the ", kIdentity, "" }, + { "", kOmitLast4, "" }, + { "", kIdentity, ". The " }, + { "", kUppercaseAll, "" }, + { "", kIdentity, " on " }, + { "", kIdentity, " as " }, + { "", kIdentity, " is " }, + { "", kOmitLast7, "" }, + { "", kOmitLast1, "ing " }, + { "", kIdentity, "\n\t" }, + { "", kIdentity, ":" }, + { " ", kIdentity, ". " }, + { "", kIdentity, "ed " }, + { "", kOmitFirst9, "" }, + { "", kOmitFirst7, "" }, + { "", kOmitLast6, "" }, + { "", kIdentity, "(" }, + { "", kUppercaseFirst, ", " }, + { "", kOmitLast8, "" }, + { "", kIdentity, " at " }, + { "", kIdentity, "ly " }, + { " the ", kIdentity, " of " }, + { "", kOmitLast5, "" }, + { "", kOmitLast9, "" }, + { " ", kUppercaseFirst, ", " }, + { "", kUppercaseFirst, "\"" }, + { ".", kIdentity, "(" }, + { "", kUppercaseAll, " " }, + { "", kUppercaseFirst, "\">" }, + { "", kIdentity, "=\"" }, + { " ", kIdentity, "." }, + { ".com/", kIdentity, "" }, + { " the ", kIdentity, " of the " }, + { "", kUppercaseFirst, "'" }, + { "", kIdentity, ". This " }, + { "", kIdentity, "," }, + { ".", kIdentity, " " }, + { "", kUppercaseFirst, "(" }, + { "", kUppercaseFirst, "." }, + { "", kIdentity, " not " }, + { " ", kIdentity, "=\"" }, + { "", kIdentity, "er " }, + { " ", kUppercaseAll, " " }, + { "", kIdentity, "al " }, + { " ", kUppercaseAll, "" }, + { "", kIdentity, "='" }, + { "", kUppercaseAll, "\"" }, + { "", kUppercaseFirst, ". " }, + { " ", kIdentity, "(" }, + { "", kIdentity, "ful " }, + { " ", kUppercaseFirst, ". " }, + { "", kIdentity, "ive " }, + { "", kIdentity, "less " }, + { "", kUppercaseAll, "'" }, + { "", kIdentity, "est " }, + { " ", kUppercaseFirst, "." }, + { "", kUppercaseAll, "\">" }, + { " ", kIdentity, "='" }, + { "", kUppercaseFirst, "," }, + { "", kIdentity, "ize " }, + { "", kUppercaseAll, "." }, + { "\xc2\xa0", kIdentity, "" }, + { " ", kIdentity, "," }, + { "", kUppercaseFirst, "=\"" }, + { "", kUppercaseAll, "=\"" }, + { "", kIdentity, "ous " }, + { "", kUppercaseAll, ", " }, + { "", kUppercaseFirst, "='" }, + { " ", kUppercaseFirst, "," }, + { " ", kUppercaseAll, "=\"" }, + { " ", kUppercaseAll, ", " }, + { "", kUppercaseAll, "," }, + { "", kUppercaseAll, "(" }, + { "", kUppercaseAll, ". " }, + { " ", kUppercaseAll, "." }, + { "", kUppercaseAll, "='" }, + { " ", kUppercaseAll, ". " }, + { " ", kUppercaseFirst, "=\"" }, + { " ", kUppercaseAll, "='" }, + { " ", kUppercaseFirst, "='" }, +}; + +static const size_t kNumTransforms = + sizeof(kTransforms) / sizeof(kTransforms[0]); + +static const size_t kOmitLastNTransforms[10] = { + 0, 12, 27, 23, 42, 63, 56, 48, 59, 64, +}; + +static size_t ToUpperCase(uint8_t *p, size_t len) { + if (len == 1 || p[0] < 0xc0) { + if (p[0] >= 'a' && p[0] <= 'z') { + p[0] ^= 32; + } + return 1; + } + if (p[0] < 0xe0) { + p[1] ^= 32; + return 2; + } + if (len == 2) { + return 2; + } + p[2] ^= 5; + return 3; +} + +inline std::string TransformWord( + WordTransformType transform_type, const uint8_t* word, size_t len) { + if (transform_type <= kOmitLast9) { + if (len <= transform_type) { + return std::string(); + } + return std::string(word, word + len - transform_type); + } + + if (transform_type >= kOmitFirst1) { + const size_t skip = transform_type - (kOmitFirst1 - 1); + if (len <= skip) { + return std::string(); + } + return std::string(word + skip, word + len); + } + + std::string ret = std::string(word, word + len); + uint8_t *uppercase = reinterpret_cast(&ret[0]); + if (transform_type == kUppercaseFirst) { + ToUpperCase(uppercase, len); + } else if (transform_type == kUppercaseAll) { + size_t position = 0; + while (position < len) { + size_t step = ToUpperCase(uppercase, len - position); + uppercase += step; + position += step; + } + } + return ret; +} + +inline std::string ApplyTransform( + const Transform& t, const uint8_t* word, size_t len) { + return std::string(t.prefix) + + TransformWord(t.word_transform, word, len) + std::string(t.suffix); +} + +inline std::string GetTransformedDictionaryWord(size_t len_code, + size_t word_id) { + size_t num_words = 1u << kBrotliDictionarySizeBitsByLength[len_code]; + size_t offset = kBrotliDictionaryOffsetsByLength[len_code]; + size_t t = word_id / num_words; + size_t word_idx = word_id % num_words; + offset += len_code * word_idx; + const uint8_t* word = &kBrotliDictionary[offset]; + return ApplyTransform(kTransforms[t], word, len_code); +} + +} // namespace brotli + +#endif // BROTLI_ENC_TRANSFORM_H_ diff --git a/web/server/h2o/libh2o/deps/brotli/enc/types.h b/web/server/h2o/libh2o/deps/brotli/enc/types.h new file mode 100644 index 00000000..851749cb --- /dev/null +++ b/web/server/h2o/libh2o/deps/brotli/enc/types.h @@ -0,0 +1,27 @@ +/* Copyright 2013 Google Inc. All Rights Reserved. + + Distributed under MIT license. + See file LICENSE for detail or copy at https://opensource.org/licenses/MIT +*/ + +/* Common types */ + +#ifndef BROTLI_ENC_TYPES_H_ +#define BROTLI_ENC_TYPES_H_ + +#include /* for size_t */ + +#if defined(_MSC_VER) && (_MSC_VER < 1600) +typedef __int8 int8_t; +typedef unsigned __int8 uint8_t; +typedef __int16 int16_t; +typedef unsigned __int16 uint16_t; +typedef __int32 int32_t; +typedef unsigned __int32 uint32_t; +typedef unsigned __int64 uint64_t; +typedef __int64 int64_t; +#else +#include +#endif /* defined(_MSC_VER) && (_MSC_VER < 1600) */ + +#endif /* BROTLI_ENC_TYPES_H_ */ diff --git a/web/server/h2o/libh2o/deps/brotli/enc/utf8_util.cc b/web/server/h2o/libh2o/deps/brotli/enc/utf8_util.cc new file mode 100644 index 00000000..a2b5c3a6 --- /dev/null +++ b/web/server/h2o/libh2o/deps/brotli/enc/utf8_util.cc @@ -0,0 +1,83 @@ +/* Copyright 2013 Google Inc. All Rights Reserved. + + Distributed under MIT license. + See file LICENSE for detail or copy at https://opensource.org/licenses/MIT +*/ + +// Heuristics for deciding about the UTF8-ness of strings. + +#include "./utf8_util.h" + +#include "./types.h" + +namespace brotli { + +namespace { + +size_t ParseAsUTF8(int* symbol, const uint8_t* input, size_t size) { + // ASCII + if ((input[0] & 0x80) == 0) { + *symbol = input[0]; + if (*symbol > 0) { + return 1; + } + } + // 2-byte UTF8 + if (size > 1u && + (input[0] & 0xe0) == 0xc0 && + (input[1] & 0xc0) == 0x80) { + *symbol = (((input[0] & 0x1f) << 6) | + (input[1] & 0x3f)); + if (*symbol > 0x7f) { + return 2; + } + } + // 3-byte UFT8 + if (size > 2u && + (input[0] & 0xf0) == 0xe0 && + (input[1] & 0xc0) == 0x80 && + (input[2] & 0xc0) == 0x80) { + *symbol = (((input[0] & 0x0f) << 12) | + ((input[1] & 0x3f) << 6) | + (input[2] & 0x3f)); + if (*symbol > 0x7ff) { + return 3; + } + } + // 4-byte UFT8 + if (size > 3u && + (input[0] & 0xf8) == 0xf0 && + (input[1] & 0xc0) == 0x80 && + (input[2] & 0xc0) == 0x80 && + (input[3] & 0xc0) == 0x80) { + *symbol = (((input[0] & 0x07) << 18) | + ((input[1] & 0x3f) << 12) | + ((input[2] & 0x3f) << 6) | + (input[3] & 0x3f)); + if (*symbol > 0xffff && *symbol <= 0x10ffff) { + return 4; + } + } + // Not UTF8, emit a special symbol above the UTF8-code space + *symbol = 0x110000 | input[0]; + return 1; +} + +} // namespace + +// Returns true if at least min_fraction of the data is UTF8-encoded. +bool IsMostlyUTF8(const uint8_t* data, const size_t pos, const size_t mask, + const size_t length, const double min_fraction) { + size_t size_utf8 = 0; + size_t i = 0; + while (i < length) { + int symbol; + size_t bytes_read = ParseAsUTF8( + &symbol, &data[(pos + i) & mask], length - i); + i += bytes_read; + if (symbol < 0x110000) size_utf8 += bytes_read; + } + return size_utf8 > min_fraction * static_cast(length); +} + +} // namespace brotli diff --git a/web/server/h2o/libh2o/deps/brotli/enc/utf8_util.h b/web/server/h2o/libh2o/deps/brotli/enc/utf8_util.h new file mode 100644 index 00000000..74f22b6a --- /dev/null +++ b/web/server/h2o/libh2o/deps/brotli/enc/utf8_util.h @@ -0,0 +1,25 @@ +/* Copyright 2013 Google Inc. All Rights Reserved. + + Distributed under MIT license. + See file LICENSE for detail or copy at https://opensource.org/licenses/MIT +*/ + +// Heuristics for deciding about the UTF8-ness of strings. + +#ifndef BROTLI_ENC_UTF8_UTIL_H_ +#define BROTLI_ENC_UTF8_UTIL_H_ + +#include "./types.h" + +namespace brotli { + +static const double kMinUTF8Ratio = 0.75; + +// Returns true if at least min_fraction of the bytes between pos and +// pos + length in the (data, mask) ringbuffer is UTF8-encoded. +bool IsMostlyUTF8(const uint8_t* data, const size_t pos, const size_t mask, + const size_t length, const double min_fraction); + +} // namespace brotli + +#endif // BROTLI_ENC_UTF8_UTIL_H_ diff --git a/web/server/h2o/libh2o/deps/brotli/enc/write_bits.h b/web/server/h2o/libh2o/deps/brotli/enc/write_bits.h new file mode 100644 index 00000000..b605203a --- /dev/null +++ b/web/server/h2o/libh2o/deps/brotli/enc/write_bits.h @@ -0,0 +1,84 @@ +/* Copyright 2010 Google Inc. All Rights Reserved. + + Distributed under MIT license. + See file LICENSE for detail or copy at https://opensource.org/licenses/MIT +*/ + +// Write bits into a byte array. + +#ifndef BROTLI_ENC_WRITE_BITS_H_ +#define BROTLI_ENC_WRITE_BITS_H_ + +#include +#include + +#include "./port.h" +#include "./types.h" + +namespace brotli { + +//#define BIT_WRITER_DEBUG + +// This function writes bits into bytes in increasing addresses, and within +// a byte least-significant-bit first. +// +// The function can write up to 56 bits in one go with WriteBits +// Example: let's assume that 3 bits (Rs below) have been written already: +// +// BYTE-0 BYTE+1 BYTE+2 +// +// 0000 0RRR 0000 0000 0000 0000 +// +// Now, we could write 5 or less bits in MSB by just sifting by 3 +// and OR'ing to BYTE-0. +// +// For n bits, we take the last 5 bits, OR that with high bits in BYTE-0, +// and locate the rest in BYTE+1, BYTE+2, etc. +inline void WriteBits(size_t n_bits, + uint64_t bits, + size_t * __restrict pos, + uint8_t * __restrict array) { +#ifdef BIT_WRITER_DEBUG + printf("WriteBits %2d 0x%016llx %10d\n", n_bits, bits, *pos); +#endif + assert((bits >> n_bits) == 0); + assert(n_bits <= 56); +#ifdef IS_LITTLE_ENDIAN + // This branch of the code can write up to 56 bits at a time, + // 7 bits are lost by being perhaps already in *p and at least + // 1 bit is needed to initialize the bit-stream ahead (i.e. if 7 + // bits are in *p and we write 57 bits, then the next write will + // access a byte that was never initialized). + uint8_t *p = &array[*pos >> 3]; + uint64_t v = *p; + v |= bits << (*pos & 7); + BROTLI_UNALIGNED_STORE64(p, v); // Set some bits. + *pos += n_bits; +#else + // implicit & 0xff is assumed for uint8_t arithmetics + uint8_t *array_pos = &array[*pos >> 3]; + const size_t bits_reserved_in_first_byte = (*pos & 7); + bits <<= bits_reserved_in_first_byte; + *array_pos++ |= static_cast(bits); + for (size_t bits_left_to_write = n_bits + bits_reserved_in_first_byte; + bits_left_to_write >= 9; + bits_left_to_write -= 8) { + bits >>= 8; + *array_pos++ = static_cast(bits); + } + *array_pos = 0; + *pos += n_bits; +#endif +} + +inline void WriteBitsPrepareStorage(size_t pos, uint8_t *array) { +#ifdef BIT_WRITER_DEBUG + printf("WriteBitsPrepareStorage %10d\n", pos); +#endif + assert((pos & 7) == 0); + array[pos >> 3] = 0; +} + +} // namespace brotli + +#endif // BROTLI_ENC_WRITE_BITS_H_ diff --git a/web/server/h2o/libh2o/deps/brotli/python/README.md b/web/server/h2o/libh2o/deps/brotli/python/README.md new file mode 100644 index 00000000..e7872286 --- /dev/null +++ b/web/server/h2o/libh2o/deps/brotli/python/README.md @@ -0,0 +1,5 @@ +This directory contains Python brotli wrapper module and roundtrip tests. + +To build module execute `python setup.py build_ext` from root project directory. + +To test module run `python setup.py test`. diff --git a/web/server/h2o/libh2o/deps/brotli/python/bro.py b/web/server/h2o/libh2o/deps/brotli/python/bro.py new file mode 100755 index 00000000..c6f74ce9 --- /dev/null +++ b/web/server/h2o/libh2o/deps/brotli/python/bro.py @@ -0,0 +1,132 @@ +#! /usr/bin/env python +"""bro %s -- compression/decompression utility using the Brotli algorithm.""" + +from __future__ import print_function +import argparse +import sys +import os +import brotli +import platform + + +# default values of encoder parameters +DEFAULT_PARAMS = { + 'mode': brotli.MODE_GENERIC, + 'quality': 11, + 'lgwin': 22, + 'lgblock': 0, +} + + +def get_binary_stdio(stream): + """ Return the specified standard input, output or errors stream as a + 'raw' buffer object suitable for reading/writing binary data from/to it. + """ + assert stream in ['stdin', 'stdout', 'stderr'], "invalid stream name" + stdio = getattr(sys, stream) + if sys.version_info[0] < 3: + if sys.platform == 'win32': + # set I/O stream binary flag on python2.x (Windows) + runtime = platform.python_implementation() + if runtime == "PyPy": + # the msvcrt trick doesn't work in pypy, so I use fdopen + mode = "rb" if stream == "stdin" else "wb" + stdio = os.fdopen(stdio.fileno(), mode, 0) + else: + # this works with CPython -- untested on other implementations + import msvcrt + msvcrt.setmode(stdio.fileno(), os.O_BINARY) + return stdio + else: + # get 'buffer' attribute to read/write binary data on python3.x + if hasattr(stdio, 'buffer'): + return stdio.buffer + else: + orig_stdio = getattr(sys, "__%s__" % stream) + return orig_stdio.buffer + + +def main(args=None): + + parser = argparse.ArgumentParser( + prog='bro.py', + description="Compression/decompression utility using the Brotli algorithm.") + parser.add_argument('--version', action='version', version=brotli.__version__) + parser.add_argument('-i', '--input', metavar='FILE', type=str, dest='infile', + help='Input file', default=None) + parser.add_argument('-o', '--output', metavar='FILE', type=str, dest='outfile', + help='Output file', default=None) + parser.add_argument('-f', '--force', action='store_true', + help='Overwrite existing output file', default=False) + parser.add_argument('-d', '--decompress', action='store_true', + help='Decompress input file', default=False) + params = parser.add_argument_group('optional encoder parameters') + params.add_argument('-m', '--mode', metavar="MODE", type=int, choices=[0, 1, 2], + help='The compression mode can be 0 for generic input, ' + '1 for UTF-8 encoded text, or 2 for WOFF 2.0 font data. ' + 'Defaults to 0.') + params.add_argument('-q', '--quality', metavar="QUALITY", type=int, + choices=list(range(0, 12)), + help='Controls the compression-speed vs compression-density ' + 'tradeoff. The higher the quality, the slower the ' + 'compression. Range is 0 to 11. Defaults to 11.') + params.add_argument('--lgwin', metavar="LGWIN", type=int, + choices=list(range(10, 25)), + help='Base 2 logarithm of the sliding window size. Range is ' + '10 to 24. Defaults to 22.') + params.add_argument('--lgblock', metavar="LGBLOCK", type=int, + choices=[0] + list(range(16, 25)), + help='Base 2 logarithm of the maximum input block size. ' + 'Range is 16 to 24. If set to 0, the value will be set based ' + 'on the quality. Defaults to 0.') + params.add_argument('--custom-dictionary', metavar="FILE", type=str, dest='dictfile', + help='Custom dictionary file.', default = None) + # set default values using global DEFAULT_PARAMS dictionary + parser.set_defaults(**DEFAULT_PARAMS) + + options = parser.parse_args(args=args) + + if options.infile: + if not os.path.isfile(options.infile): + parser.error('file "%s" not found' % options.infile) + with open(options.infile, "rb") as infile: + data = infile.read() + else: + if sys.stdin.isatty(): + # interactive console, just quit + parser.error('no input') + infile = get_binary_stdio('stdin') + data = infile.read() + + if options.outfile: + if os.path.isfile(options.outfile) and not options.force: + parser.error('output file exists') + outfile = open(options.outfile, "wb") + else: + outfile = get_binary_stdio('stdout') + + if options.dictfile: + if not os.path.isfile(options.dictfile): + parser.error('file "%s" not found' % options.dictfile) + with open(options.dictfile, "rb") as dictfile: + custom_dictionary = dictfile.read() + else: + custom_dictionary = '' + + + try: + if options.decompress: + data = brotli.decompress(data, dictionary=custom_dictionary) + else: + data = brotli.compress( + data, mode=options.mode, quality=options.quality, + lgwin=options.lgwin, lgblock=options.lgblock, dictionary=custom_dictionary) + except brotli.error as e: + parser.exit(1,'bro: error: %s: %s' % (e, options.infile or 'sys.stdin')) + + outfile.write(data) + outfile.close() + + +if __name__ == '__main__': + main() diff --git a/web/server/h2o/libh2o/deps/brotli/python/brotlimodule.cc b/web/server/h2o/libh2o/deps/brotli/python/brotlimodule.cc new file mode 100644 index 00000000..936d1a48 --- /dev/null +++ b/web/server/h2o/libh2o/deps/brotli/python/brotlimodule.cc @@ -0,0 +1,302 @@ +#define PY_SSIZE_T_CLEAN 1 +#include +#include +#include "../enc/encode.h" +#include "../dec/decode.h" +#include "../tools/version.h" + +#if PY_MAJOR_VERSION >= 3 +#define PyInt_Check PyLong_Check +#define PyInt_AsLong PyLong_AsLong +#endif + +using namespace brotli; + +static PyObject *BrotliError; + +static int as_bounded_int(PyObject *o, int* result, int lower_bound, int upper_bound) { + long value = PyInt_AsLong(o); + if ((value < (long) lower_bound) || (value > (long) upper_bound)) { + return 0; + } + *result = (int) value; + return 1; +} + +static int mode_convertor(PyObject *o, BrotliParams::Mode *mode) { + if (!PyInt_Check(o)) { + PyErr_SetString(BrotliError, "Invalid mode"); + return 0; + } + + int mode_value = -1; + if (!as_bounded_int(o, &mode_value, 0, 255)) { + PyErr_SetString(BrotliError, "Invalid mode"); + return 0; + } + *mode = (BrotliParams::Mode) mode_value; + if (*mode != BrotliParams::MODE_GENERIC && + *mode != BrotliParams::MODE_TEXT && + *mode != BrotliParams::MODE_FONT) { + PyErr_SetString(BrotliError, "Invalid mode"); + return 0; + } + + return 1; +} + +static int quality_convertor(PyObject *o, int *quality) { + if (!PyInt_Check(o)) { + PyErr_SetString(BrotliError, "Invalid quality"); + return 0; + } + + if (!as_bounded_int(o, quality, 0, 11)) { + PyErr_SetString(BrotliError, "Invalid quality. Range is 0 to 11."); + return 0; + } + + return 1; +} + +static int lgwin_convertor(PyObject *o, int *lgwin) { + if (!PyInt_Check(o)) { + PyErr_SetString(BrotliError, "Invalid lgwin"); + return 0; + } + + if (!as_bounded_int(o, lgwin, 10, 24)) { + PyErr_SetString(BrotliError, "Invalid lgwin. Range is 10 to 24."); + return 0; + } + + return 1; +} + +static int lgblock_convertor(PyObject *o, int *lgblock) { + if (!PyInt_Check(o)) { + PyErr_SetString(BrotliError, "Invalid lgblock"); + return 0; + } + + if (!as_bounded_int(o, lgblock, 0, 24) || (*lgblock != 0 && *lgblock < 16)) { + PyErr_SetString(BrotliError, "Invalid lgblock. Can be 0 or in range 16 to 24."); + return 0; + } + + return 1; +} + +PyDoc_STRVAR(compress__doc__, +"Compress a byte string.\n" +"\n" +"Signature:\n" +" compress(string, mode=MODE_GENERIC, quality=11, lgwin=22, lgblock=0, dictionary='')\n" +"\n" +"Args:\n" +" string (bytes): The input data.\n" +" mode (int, optional): The compression mode can be MODE_GENERIC (default),\n" +" MODE_TEXT (for UTF-8 format text input) or MODE_FONT (for WOFF 2.0). \n" +" quality (int, optional): Controls the compression-speed vs compression-\n" +" density tradeoff. The higher the quality, the slower the compression.\n" +" Range is 0 to 11. Defaults to 11.\n" +" lgwin (int, optional): Base 2 logarithm of the sliding window size. Range\n" +" is 10 to 24. Defaults to 22.\n" +" lgblock (int, optional): Base 2 logarithm of the maximum input block size.\n" +" Range is 16 to 24. If set to 0, the value will be set based on the\n" +" quality. Defaults to 0.\n" +" dictionary (bytes, optional): Custom dictionary. Only last sliding window\n" +" size bytes will be used.\n" +"\n" +"Returns:\n" +" The compressed byte string.\n" +"\n" +"Raises:\n" +" brotli.error: If arguments are invalid, or compressor fails.\n"); + +static PyObject* brotli_compress(PyObject *self, PyObject *args, PyObject *keywds) { + PyObject *ret = NULL; + uint8_t *input, *output, *custom_dictionary; + size_t length, output_length, custom_dictionary_length; + BrotliParams::Mode mode = (BrotliParams::Mode) -1; + int quality = -1; + int lgwin = -1; + int lgblock = -1; + int ok; + + static const char *kwlist[] = { + "string", "mode", "quality", "lgwin", "lgblock", "dictionary", NULL}; + + custom_dictionary = NULL; + custom_dictionary_length = 0; + + ok = PyArg_ParseTupleAndKeywords(args, keywds, "s#|O&O&O&O&s#:compress", + const_cast(kwlist), + &input, &length, + &mode_convertor, &mode, + &quality_convertor, &quality, + &lgwin_convertor, &lgwin, + &lgblock_convertor, &lgblock, + &custom_dictionary, &custom_dictionary_length); + if (!ok) + return NULL; + + output_length = length + (length >> 2) + 10240; + output = new uint8_t[output_length]; + + BrotliParams params; + if ((int) mode != -1) + params.mode = mode; + if (quality != -1) + params.quality = quality; + if (lgwin != -1) + params.lgwin = lgwin; + if (lgblock != -1) + params.lgblock = lgblock; + + if (custom_dictionary_length == 0) { + ok = BrotliCompressBuffer(params, length, input, + &output_length, output); + } else { + uint8_t *custom_dictionary_start = custom_dictionary; + BrotliMemIn in(input, length); + BrotliMemOut out(output, output_length); + size_t sliding_window_size = ((size_t)1) << params.lgwin; + if (custom_dictionary_length > sliding_window_size) { + custom_dictionary_start += custom_dictionary_length - sliding_window_size; + custom_dictionary_length = sliding_window_size; + } + ok = BrotliCompressWithCustomDictionary(custom_dictionary_length, + custom_dictionary_start, params, &in, &out); + output_length = out.position(); + } + + if (ok) { + ret = PyBytes_FromStringAndSize((char*)output, output_length); + } else { + PyErr_SetString(BrotliError, "BrotliCompressBuffer failed"); + } + + delete[] output; + + return ret; +} + +PyDoc_STRVAR(decompress__doc__, +"Decompress a compressed byte string.\n" +"\n" +"Signature:\n" +" decompress(string)\n" +"\n" +"Args:\n" +" string (bytes): The compressed input data.\n" +" dictionary (bytes, optional): Custom dictionary. MUST be the same data\n" +" as passed to compress method.\n" +"\n" +"Returns:\n" +" The decompressed byte string.\n" +"\n" +"Raises:\n" +" brotli.error: If decompressor fails.\n"); + +static PyObject* brotli_decompress(PyObject *self, PyObject *args, PyObject *keywds) { + PyObject *ret = NULL; + const uint8_t *input, *custom_dictionary; + size_t length, custom_dictionary_length; + int ok; + + static const char *kwlist[] = {"string", "dictionary", NULL}; + + custom_dictionary = NULL; + custom_dictionary_length = 0; + + ok = PyArg_ParseTupleAndKeywords(args, keywds, "s#|s#:decompress", + const_cast(kwlist), + &input, &length, + &custom_dictionary, &custom_dictionary_length); + if (!ok) + return NULL; + + std::vector output; + const size_t kBufferSize = 65536; + uint8_t* buffer = new uint8_t[kBufferSize]; + BrotliState state; + BrotliStateInit(&state); + if (custom_dictionary_length != 0) { + BrotliSetCustomDictionary(custom_dictionary_length, custom_dictionary, &state); + } + + BrotliResult result = BROTLI_RESULT_NEEDS_MORE_OUTPUT; + while (result == BROTLI_RESULT_NEEDS_MORE_OUTPUT) { + size_t available_out = kBufferSize; + uint8_t* next_out = buffer; + size_t total_out = 0; + result = BrotliDecompressStream(&length, &input, + &available_out, &next_out, + &total_out, &state); + size_t used_out = kBufferSize - available_out; + if (used_out != 0) + output.insert(output.end(), buffer, buffer + used_out); + } + ok = result == BROTLI_RESULT_SUCCESS; + if (ok) { + ret = PyBytes_FromStringAndSize((char*)(output.size() ? &output[0] : NULL), output.size()); + } else { + PyErr_SetString(BrotliError, "BrotliDecompress failed"); + } + + BrotliStateCleanup(&state); + delete[] buffer; + + return ret; +} + +static PyMethodDef brotli_methods[] = { + {"compress", (PyCFunction)brotli_compress, METH_VARARGS | METH_KEYWORDS, compress__doc__}, + {"decompress", (PyCFunction)brotli_decompress, METH_VARARGS | METH_KEYWORDS, decompress__doc__}, + {NULL, NULL, 0, NULL} +}; + +PyDoc_STRVAR(brotli__doc__, +"The functions in this module allow compression and decompression using the\n" +"Brotli library.\n\n"); + +#if PY_MAJOR_VERSION >= 3 +#define INIT_BROTLI PyInit_brotli +#define CREATE_BROTLI PyModule_Create(&brotli_module) +#define RETURN_BROTLI return m + +static struct PyModuleDef brotli_module = { + PyModuleDef_HEAD_INIT, + "brotli", + brotli__doc__, + 0, + brotli_methods, + NULL, + NULL, + NULL +}; +#else +#define INIT_BROTLI initbrotli +#define CREATE_BROTLI Py_InitModule3("brotli", brotli_methods, brotli__doc__) +#define RETURN_BROTLI return +#endif + +PyMODINIT_FUNC INIT_BROTLI(void) { + PyObject *m = CREATE_BROTLI; + + BrotliError = PyErr_NewException((char*) "brotli.error", NULL, NULL); + + if (BrotliError != NULL) { + Py_INCREF(BrotliError); + PyModule_AddObject(m, "error", BrotliError); + } + + PyModule_AddIntConstant(m, "MODE_GENERIC", (int) BrotliParams::MODE_GENERIC); + PyModule_AddIntConstant(m, "MODE_TEXT", (int) BrotliParams::MODE_TEXT); + PyModule_AddIntConstant(m, "MODE_FONT", (int) BrotliParams::MODE_FONT); + + PyModule_AddStringConstant(m, "__version__", BROTLI_VERSION); + + RETURN_BROTLI; +} diff --git a/web/server/h2o/libh2o/deps/brotli/python/tests/compatibility_test.py b/web/server/h2o/libh2o/deps/brotli/python/tests/compatibility_test.py new file mode 100755 index 00000000..668c9ece --- /dev/null +++ b/web/server/h2o/libh2o/deps/brotli/python/tests/compatibility_test.py @@ -0,0 +1,27 @@ +#!/usr/bin/env python +from __future__ import print_function +import glob +import sys +import os +from subprocess import check_call + +from test_utils import PYTHON, BRO, TEST_ENV, diff_q + + +os.chdir(os.path.abspath("../../tests")) +for filename in glob.glob("testdata/*.compressed*"): + filename = os.path.abspath(filename) + print('Testing decompression of file "%s"' % os.path.basename(filename)) + expected = filename.split(".compressed")[0] + uncompressed = expected + ".uncompressed" + check_call([PYTHON, BRO, "-f", "-d", "-i", filename, "-o", uncompressed], + env=TEST_ENV) + if diff_q(uncompressed, expected) != 0: + sys.exit(1) + # Test the streaming version + with open(filename, "rb") as infile, open(uncompressed, "wb") as outfile: + check_call([PYTHON, BRO, '-d'], stdin=infile, stdout=outfile, + env=TEST_ENV) + if diff_q(uncompressed, expected) != 0: + sys.exit(1) + os.unlink(uncompressed) diff --git a/web/server/h2o/libh2o/deps/brotli/python/tests/custom_dictionary_test.py b/web/server/h2o/libh2o/deps/brotli/python/tests/custom_dictionary_test.py new file mode 100644 index 00000000..afbf07a8 --- /dev/null +++ b/web/server/h2o/libh2o/deps/brotli/python/tests/custom_dictionary_test.py @@ -0,0 +1,36 @@ +#!/usr/bin/env python +from __future__ import print_function +import sys +import os +from subprocess import check_call, Popen, PIPE + +from test_utils import PYTHON, BRO, TEST_ENV, diff_q + + +INPUTS = """\ +testdata/alice29.txt +testdata/asyoulik.txt +testdata/lcet10.txt +testdata/plrabn12.txt +../enc/encode.cc +../enc/dictionary.h +../dec/decode.c +%s +""" % BRO + +os.chdir(os.path.abspath("../../tests")) +for filename in INPUTS.splitlines(): + for quality in (1, 6, 9, 11): + for lgwin in (10, 15, 20, 24): + filename = os.path.abspath(filename) + print('Roundtrip testing file "%s" at quality %d with lg(win)=%d and auto-custom-dictionary' % + (os.path.basename(filename), quality, lgwin)) + compressed = os.path.splitext(filename)[0] + ".custom_bro" + uncompressed = os.path.splitext(filename)[0] + ".custom_unbro" + check_call([PYTHON, BRO, "-f", "-q", str(quality), "-i", filename, + "-o", compressed, "--lgwin", str(lgwin), + "--custom-dictionary", filename], env=TEST_ENV) + check_call([PYTHON, BRO, "-f", "-d", "-i", compressed, "-o", + uncompressed, "--custom-dictionary", filename], env=TEST_ENV) + if diff_q(filename, uncompressed) != 0: + sys.exit(1) diff --git a/web/server/h2o/libh2o/deps/brotli/python/tests/roundtrip_test.py b/web/server/h2o/libh2o/deps/brotli/python/tests/roundtrip_test.py new file mode 100755 index 00000000..719a7b77 --- /dev/null +++ b/web/server/h2o/libh2o/deps/brotli/python/tests/roundtrip_test.py @@ -0,0 +1,43 @@ +#!/usr/bin/env python +from __future__ import print_function +import sys +import os +from subprocess import check_call, Popen, PIPE + +from test_utils import PYTHON, BRO, TEST_ENV, diff_q + + +INPUTS = """\ +testdata/alice29.txt +testdata/asyoulik.txt +testdata/lcet10.txt +testdata/plrabn12.txt +../enc/encode.cc +../enc/dictionary.h +../dec/decode.c +%s +""" % BRO + +os.chdir(os.path.abspath("../../tests")) +for filename in INPUTS.splitlines(): + for quality in (1, 6, 9, 11): + filename = os.path.abspath(filename) + print('Roundtrip testing file "%s" at quality %d' % + (os.path.basename(filename), quality)) + compressed = os.path.splitext(filename)[0] + ".bro" + uncompressed = os.path.splitext(filename)[0] + ".unbro" + check_call([PYTHON, BRO, "-f", "-q", str(quality), "-i", filename, + "-o", compressed], env=TEST_ENV) + check_call([PYTHON, BRO, "-f", "-d", "-i", compressed, "-o", + uncompressed], env=TEST_ENV) + if diff_q(filename, uncompressed) != 0: + sys.exit(1) + # Test the streaming version + with open(filename, "rb") as infile, \ + open(uncompressed, "wb") as outfile: + p = Popen([PYTHON, BRO, "-q", str(quality)], stdin=infile, + stdout=PIPE, env=TEST_ENV) + check_call([PYTHON, BRO, "-d"], stdin=p.stdout, stdout=outfile, + env=TEST_ENV) + if diff_q(filename, uncompressed) != 0: + sys.exit(1) diff --git a/web/server/h2o/libh2o/deps/brotli/python/tests/test_utils.py b/web/server/h2o/libh2o/deps/brotli/python/tests/test_utils.py new file mode 100644 index 00000000..381b64e9 --- /dev/null +++ b/web/server/h2o/libh2o/deps/brotli/python/tests/test_utils.py @@ -0,0 +1,36 @@ +from __future__ import print_function +import sys +import os +import sysconfig +import filecmp + + +def diff_q(first_file, second_file): + """Simulate call to POSIX diff with -q argument""" + if not filecmp.cmp(first_file, second_file, shallow=False): + print("Files %s and %s differ" % (first_file, second_file), + file=sys.stderr) + return 1 + return 0 + + +PYTHON = sys.executable or "python" + +# 'bro.py' script should be in parent directory +BRO = os.path.abspath("../bro.py") + +# get platform- and version-specific build/lib folder +platform_lib_name = "lib.{platform}-{version[0]}.{version[1]}".format( + platform=sysconfig.get_platform(), + version=sys.version_info) + +# by default, distutils' build base is in the same location as setup.py +build_base = os.path.abspath(os.path.join("..", "..", "build")) +build_lib = os.path.join(build_base, platform_lib_name) + +# prepend build/lib to PYTHONPATH environment variable +TEST_ENV = os.environ.copy() +if 'PYTHONPATH' not in TEST_ENV: + TEST_ENV['PYTHONPATH'] = build_lib +else: + TEST_ENV['PYTHONPATH'] = build_lib + os.pathsep + TEST_ENV['PYTHONPATH'] diff --git a/web/server/h2o/libh2o/deps/brotli/setup.py b/web/server/h2o/libh2o/deps/brotli/setup.py new file mode 100644 index 00000000..45403487 --- /dev/null +++ b/web/server/h2o/libh2o/deps/brotli/setup.py @@ -0,0 +1,227 @@ +try: + import setuptools +except: + pass +import distutils +from distutils.core import setup, Extension +from distutils.command.build_ext import build_ext +from distutils.cmd import Command +import platform +import os +import re + + +CURR_DIR = os.path.abspath(os.path.dirname(os.path.realpath(__file__))) + + +def get_version(): + """ Return BROTLI_VERSION string as defined in 'tools/version.h' file. """ + brotlimodule = os.path.join(CURR_DIR, 'tools', 'version.h') + with open(brotlimodule, 'r') as f: + for line in f: + m = re.match(r'#define\sBROTLI_VERSION\s"(.*)"', line) + if m: + return m.group(1) + return "" + + +class TestCommand(Command): + """ Run all *_test.py scripts in 'tests' folder with the same Python + interpreter used to run setup.py. + """ + + user_options = [] + + def initialize_options(self): + pass + + def finalize_options(self): + pass + + def run(self): + import sys, subprocess, glob + + test_dir = os.path.join(CURR_DIR, 'python', 'tests') + os.chdir(test_dir) + + for test in glob.glob("*_test.py"): + try: + subprocess.check_call([sys.executable, test]) + except subprocess.CalledProcessError: + raise SystemExit(1) + + +class BuildExt(build_ext): + def get_source_files(self): + filenames = build_ext.get_source_files(self) + for ext in self.extensions: + filenames.extend(ext.depends) + return filenames + + def build_extension(self, ext): + c_sources = [] + cxx_sources = [] + for source in ext.sources: + if source.endswith(".c"): + c_sources.append(source) + else: + cxx_sources.append(source) + extra_args = ext.extra_compile_args or [] + + objects = [] + for lang, sources in (("c", c_sources), ("c++", cxx_sources)): + if lang == "c++": + if self.compiler.compiler_type == "msvc": + extra_args.append("/EHsc") + + macros = ext.define_macros[:] + if platform.system() == "Darwin": + macros.append(("OS_MACOSX", "1")) + elif self.compiler.compiler_type == "mingw32": + # On Windows Python 2.7, pyconfig.h defines "hypot" as "_hypot", + # This clashes with GCC's cmath, and causes compilation errors when + # building under MinGW: http://bugs.python.org/issue11566 + macros.append(("_hypot", "hypot")) + for undef in ext.undef_macros: + macros.append((undef,)) + + objs = self.compiler.compile(sources, + output_dir=self.build_temp, + macros=macros, + include_dirs=ext.include_dirs, + debug=self.debug, + extra_postargs=extra_args, + depends=ext.depends) + objects.extend(objs) + + self._built_objects = objects[:] + if ext.extra_objects: + objects.extend(ext.extra_objects) + extra_args = ext.extra_link_args or [] + # when using GCC on Windows, we statically link libgcc and libstdc++, + # so that we don't need to package extra DLLs + if self.compiler.compiler_type == "mingw32": + extra_args.extend(['-static-libgcc', '-static-libstdc++']) + + ext_path = self.get_ext_fullpath(ext.name) + # Detect target language, if not provided + language = ext.language or self.compiler.detect_language(sources) + + self.compiler.link_shared_object( + objects, ext_path, + libraries=self.get_libraries(ext), + library_dirs=ext.library_dirs, + runtime_library_dirs=ext.runtime_library_dirs, + extra_postargs=extra_args, + export_symbols=self.get_export_symbols(ext), + debug=self.debug, + build_temp=self.build_temp, + target_lang=language) + +brotli = Extension("brotli", + sources=[ + "python/brotlimodule.cc", + "enc/backward_references.cc", + "enc/block_splitter.cc", + "enc/brotli_bit_stream.cc", + "enc/compress_fragment.cc", + "enc/compress_fragment_two_pass.cc", + "enc/encode.cc", + "enc/entropy_encode.cc", + "enc/histogram.cc", + "enc/literal_cost.cc", + "enc/metablock.cc", + "enc/static_dict.cc", + "enc/streams.cc", + "enc/utf8_util.cc", + "dec/bit_reader.c", + "dec/decode.c", + "dec/dictionary.c", + "dec/huffman.c", + "dec/state.c", + ], + depends=[ + "enc/backward_references.h", + "enc/bit_cost.h", + "enc/block_splitter.h", + "enc/brotli_bit_stream.h", + "enc/cluster.h", + "enc/command.h", + "enc/compress_fragment.h", + "enc/compress_fragment_tw_pass.h" + "enc/context.h", + "enc/dictionary.h", + "enc/dictionary_hash.h", + "enc/encode.h", + "enc/entropy_encode.h", + "enc/entropy_encode_static.h", + "enc/fast_log.h", + "enc/find_match_length.h", + "enc/hash.h", + "enc/histogram.h", + "enc/literal_cost.h", + "enc/metablock.h", + "enc/port.h", + "enc/prefix.h", + "enc/ringbuffer.h", + "enc/static_dict.h", + "enc/static_dict_lut.h", + "enc/streams.h", + "enc/transform.h", + "enc/types.h", + "enc/utf8_util.h", + "enc/write_bits.h", + "dec/bit_reader.h", + "dec/context.h", + "dec/decode.h", + "dec/dictionary.h", + "dec/huffman.h", + "dec/prefix.h", + "dec/port.h", + "dec/streams.h", + "dec/transform.h", + "dec/types.h", + "dec/state.h", + ], + language="c++", + ) + +setup( + name="Brotli", + version=get_version(), + url="https://github.com/google/brotli", + description="Python binding of the Brotli compression library", + author="Khaled Hosny", + author_email="khaledhosny@eglug.org", + license="Apache 2.0", + classifiers=[ + 'Development Status :: 4 - Beta', + 'Environment :: Console', + 'Intended Audience :: Developers', + 'License :: OSI Approved :: Apache Software License', + 'Operating System :: MacOS :: MacOS X', + 'Operating System :: Microsoft :: Windows', + 'Operating System :: POSIX :: Linux', + 'Programming Language :: C', + 'Programming Language :: C++', + 'Programming Language :: Python', + 'Programming Language :: Python :: 2', + 'Programming Language :: Python :: 2.7', + 'Programming Language :: Python :: 3', + 'Programming Language :: Python :: 3.3', + 'Programming Language :: Python :: 3.4', + 'Programming Language :: Python :: 3.5', + 'Programming Language :: Unix Shell', + 'Topic :: Software Development :: Libraries', + 'Topic :: Software Development :: Libraries :: Python Modules', + 'Topic :: System :: Archiving', + 'Topic :: System :: Archiving :: Compression', + 'Topic :: Text Processing :: Fonts', + 'Topic :: Utilities', + ], + ext_modules=[brotli], + cmdclass={ + 'build_ext': BuildExt, + 'test': TestCommand + }, +) diff --git a/web/server/h2o/libh2o/deps/brotli/shared.mk b/web/server/h2o/libh2o/deps/brotli/shared.mk new file mode 100644 index 00000000..2a0e7d1f --- /dev/null +++ b/web/server/h2o/libh2o/deps/brotli/shared.mk @@ -0,0 +1,13 @@ +OS := $(shell uname) + +CC ?= gcc +CXX ?= g++ + +COMMON_FLAGS = -fno-omit-frame-pointer -no-canonical-prefixes -O2 + +ifeq ($(OS), Darwin) + CPPFLAGS += -DOS_MACOSX +endif + +CFLAGS += $(COMMON_FLAGS) +CXXFLAGS += $(COMMON_FLAGS) diff --git a/web/server/h2o/libh2o/deps/brotli/tests/Makefile b/web/server/h2o/libh2o/deps/brotli/tests/Makefile new file mode 100644 index 00000000..8b2eedbf --- /dev/null +++ b/web/server/h2o/libh2o/deps/brotli/tests/Makefile @@ -0,0 +1,19 @@ +#brotli/tests + +include ../shared.mk + +BROTLI = .. + +all: test + +test: deps + ./compatibility_test.sh + ./roundtrip_test.sh + +deps : + $(MAKE) -C $(BROTLI)/tools + +clean : + rm -f testdata/*.{bro,unbro,uncompressed} + rm -f $(BROTLI)/{enc,dec,tools}/*.{un,}bro + $(MAKE) -C $(BROTLI)/tools clean diff --git a/web/server/h2o/libh2o/deps/brotli/tests/compatibility_test.sh b/web/server/h2o/libh2o/deps/brotli/tests/compatibility_test.sh new file mode 100755 index 00000000..e907485e --- /dev/null +++ b/web/server/h2o/libh2o/deps/brotli/tests/compatibility_test.sh @@ -0,0 +1,21 @@ +#!/bin/bash +# +# Test that the brotli command-line tool can decompress old brotli-compressed +# files. + +set -o errexit + +BRO=../tools/bro + +for file in testdata/*.compressed*; do + echo "Testing decompression of file $file" + expected=${file%.compressed*} + uncompressed=${expected}.uncompressed + $BRO -f -d -i $file -o $uncompressed + diff -q $uncompressed $expected + # Test the streaming version + cat $file | $BRO -d > $uncompressed + diff -q $uncompressed $expected + rm -f $uncompressed +done + diff --git a/web/server/h2o/libh2o/deps/brotli/tests/roundtrip_test.sh b/web/server/h2o/libh2o/deps/brotli/tests/roundtrip_test.sh new file mode 100755 index 00000000..9b05fce4 --- /dev/null +++ b/web/server/h2o/libh2o/deps/brotli/tests/roundtrip_test.sh @@ -0,0 +1,31 @@ +#!/bin/bash +# +# Roundtrip test for the brotli command-line tool. + +set -o errexit + +BRO=../tools/bro +INPUTS=""" +testdata/alice29.txt +testdata/asyoulik.txt +testdata/lcet10.txt +testdata/plrabn12.txt +../enc/encode.cc +../enc/dictionary.h +../dec/decode.c +$BRO +""" + +for file in $INPUTS; do + for quality in 1 6 9 11; do + echo "Roundtrip testing $file at quality $quality" + compressed=${file}.bro + uncompressed=${file}.unbro + $BRO -f -q $quality -i $file -o $compressed + $BRO -f -d -i $compressed -o $uncompressed + diff -q $file $uncompressed + # Test the streaming version + cat $file | $BRO -q $quality | $BRO -d >$uncompressed + diff -q $file $uncompressed + done +done diff --git a/web/server/h2o/libh2o/deps/brotli/tests/testdata/10x10y b/web/server/h2o/libh2o/deps/brotli/tests/testdata/10x10y new file mode 100644 index 00000000..3f9cf865 --- /dev/null +++ b/web/server/h2o/libh2o/deps/brotli/tests/testdata/10x10y @@ -0,0 +1 @@ +XXXXXXXXXXYYYYYYYYYY \ No newline at end of file diff --git a/web/server/h2o/libh2o/deps/brotli/tests/testdata/10x10y.compressed b/web/server/h2o/libh2o/deps/brotli/tests/testdata/10x10y.compressed new file mode 100644 index 00000000..3769516d Binary files /dev/null and b/web/server/h2o/libh2o/deps/brotli/tests/testdata/10x10y.compressed differ diff --git a/web/server/h2o/libh2o/deps/brotli/tests/testdata/64x b/web/server/h2o/libh2o/deps/brotli/tests/testdata/64x new file mode 100644 index 00000000..caa41718 --- /dev/null +++ b/web/server/h2o/libh2o/deps/brotli/tests/testdata/64x @@ -0,0 +1 @@ +XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX \ No newline at end of file diff --git a/web/server/h2o/libh2o/deps/brotli/tests/testdata/64x.compressed b/web/server/h2o/libh2o/deps/brotli/tests/testdata/64x.compressed new file mode 100644 index 00000000..74d0be10 Binary files /dev/null and b/web/server/h2o/libh2o/deps/brotli/tests/testdata/64x.compressed differ diff --git a/web/server/h2o/libh2o/deps/brotli/tests/testdata/alice29.txt b/web/server/h2o/libh2o/deps/brotli/tests/testdata/alice29.txt new file mode 100644 index 00000000..70336552 --- /dev/null +++ b/web/server/h2o/libh2o/deps/brotli/tests/testdata/alice29.txt @@ -0,0 +1,3609 @@ + + + + + ALICE'S ADVENTURES IN WONDERLAND + + Lewis Carroll + + THE MILLENNIUM FULCRUM EDITION 2.9 + + + + + CHAPTER I + + Down the Rabbit-Hole + + + Alice was beginning to get very tired of sitting by her sister +on the bank, and of having nothing to do: once or twice she had +peeped into the book her sister was reading, but it had no +pictures or conversations in it, `and what is the use of a book,' +thought Alice `without pictures or conversation?' + + So she was considering in her own mind (as well as she could, +for the hot day made her feel very sleepy and stupid), whether +the pleasure of making a daisy-chain would be worth the trouble +of getting up and picking the daisies, when suddenly a White +Rabbit with pink eyes ran close by her. + + There was nothing so VERY remarkable in that; nor did Alice +think it so VERY much out of the way to hear the Rabbit say to +itself, `Oh dear! Oh dear! I shall be late!' (when she thought +it over afterwards, it occurred to her that she ought to have +wondered at this, but at the time it all seemed quite natural); +but when the Rabbit actually TOOK A WATCH OUT OF ITS WAISTCOAT- +POCKET, and looked at it, and then hurried on, Alice started to +her feet, for it flashed across her mind that she had never +before seen a rabbit with either a waistcoat-pocket, or a watch to +take out of it, and burning with curiosity, she ran across the +field after it, and fortunately was just in time to see it pop +down a large rabbit-hole under the hedge. + + In another moment down went Alice after it, never once +considering how in the world she was to get out again. + + The rabbit-hole went straight on like a tunnel for some way, +and then dipped suddenly down, so suddenly that Alice had not a +moment to think about stopping herself before she found herself +falling down a very deep well. + + Either the well was very deep, or she fell very slowly, for she +had plenty of time as she went down to look about her and to +wonder what was going to happen next. First, she tried to look +down and make out what she was coming to, but it was too dark to +see anything; then she looked at the sides of the well, and +noticed that they were filled with cupboards and book-shelves; +here and there she saw maps and pictures hung upon pegs. She +took down a jar from one of the shelves as she passed; it was +labelled `ORANGE MARMALADE', but to her great disappointment it +was empty: she did not like to drop the jar for fear of killing +somebody, so managed to put it into one of the cupboards as she +fell past it. + + `Well!' thought Alice to herself, `after such a fall as this, I +shall think nothing of tumbling down stairs! How brave they'll +all think me at home! Why, I wouldn't say anything about it, +even if I fell off the top of the house!' (Which was very likely +true.) + + Down, down, down. Would the fall NEVER come to an end! `I +wonder how many miles I've fallen by this time?' she said aloud. +`I must be getting somewhere near the centre of the earth. Let +me see: that would be four thousand miles down, I think--' (for, +you see, Alice had learnt several things of this sort in her +lessons in the schoolroom, and though this was not a VERY good +opportunity for showing off her knowledge, as there was no one to +listen to her, still it was good practice to say it over) `--yes, +that's about the right distance--but then I wonder what Latitude +or Longitude I've got to?' (Alice had no idea what Latitude was, +or Longitude either, but thought they were nice grand words to +say.) + + Presently she began again. `I wonder if I shall fall right +THROUGH the earth! How funny it'll seem to come out among the +people that walk with their heads downward! The Antipathies, I +think--' (she was rather glad there WAS no one listening, this +time, as it didn't sound at all the right word) `--but I shall +have to ask them what the name of the country is, you know. +Please, Ma'am, is this New Zealand or Australia?' (and she tried +to curtsey as she spoke--fancy CURTSEYING as you're falling +through the air! Do you think you could manage it?) `And what +an ignorant little girl she'll think me for asking! No, it'll +never do to ask: perhaps I shall see it written up somewhere.' + + Down, down, down. There was nothing else to do, so Alice soon +began talking again. `Dinah'll miss me very much to-night, I +should think!' (Dinah was the cat.) `I hope they'll remember +her saucer of milk at tea-time. Dinah my dear! I wish you were +down here with me! There are no mice in the air, I'm afraid, but +you might catch a bat, and that's very like a mouse, you know. +But do cats eat bats, I wonder?' And here Alice began to get +rather sleepy, and went on saying to herself, in a dreamy sort of +way, `Do cats eat bats? Do cats eat bats?' and sometimes, `Do +bats eat cats?' for, you see, as she couldn't answer either +question, it didn't much matter which way she put it. She felt +that she was dozing off, and had just begun to dream that she +was walking hand in hand with Dinah, and saying to her very +earnestly, `Now, Dinah, tell me the truth: did you ever eat a +bat?' when suddenly, thump! thump! down she came upon a heap of +sticks and dry leaves, and the fall was over. + + Alice was not a bit hurt, and she jumped up on to her feet in a +moment: she looked up, but it was all dark overhead; before her +was another long passage, and the White Rabbit was still in +sight, hurrying down it. There was not a moment to be lost: +away went Alice like the wind, and was just in time to hear it +say, as it turned a corner, `Oh my ears and whiskers, how late +it's getting!' She was close behind it when she turned the +corner, but the Rabbit was no longer to be seen: she found +herself in a long, low hall, which was lit up by a row of lamps +hanging from the roof. + + There were doors all round the hall, but they were all locked; +and when Alice had been all the way down one side and up the +other, trying every door, she walked sadly down the middle, +wondering how she was ever to get out again. + + Suddenly she came upon a little three-legged table, all made of +solid glass; there was nothing on it except a tiny golden key, +and Alice's first thought was that it might belong to one of the +doors of the hall; but, alas! either the locks were too large, or +the key was too small, but at any rate it would not open any of +them. However, on the second time round, she came upon a low +curtain she had not noticed before, and behind it was a little +door about fifteen inches high: she tried the little golden key +in the lock, and to her great delight it fitted! + + Alice opened the door and found that it led into a small +passage, not much larger than a rat-hole: she knelt down and +looked along the passage into the loveliest garden you ever saw. +How she longed to get out of that dark hall, and wander about +among those beds of bright flowers and those cool fountains, but +she could not even get her head though the doorway; `and even if +my head would go through,' thought poor Alice, `it would be of +very little use without my shoulders. Oh, how I wish +I could shut up like a telescope! I think I could, if I only +know how to begin.' For, you see, so many out-of-the-way things +had happened lately, that Alice had begun to think that very few +things indeed were really impossible. + + There seemed to be no use in waiting by the little door, so she +went back to the table, half hoping she might find another key on +it, or at any rate a book of rules for shutting people up like +telescopes: this time she found a little bottle on it, (`which +certainly was not here before,' said Alice,) and round the neck +of the bottle was a paper label, with the words `DRINK ME' +beautifully printed on it in large letters. + + It was all very well to say `Drink me,' but the wise little +Alice was not going to do THAT in a hurry. `No, I'll look +first,' she said, `and see whether it's marked "poison" or not'; +for she had read several nice little histories about children who +had got burnt, and eaten up by wild beasts and other unpleasant +things, all because they WOULD not remember the simple rules +their friends had taught them: such as, that a red-hot poker +will burn you if you hold it too long; and that if you cut your +finger VERY deeply with a knife, it usually bleeds; and she had +never forgotten that, if you drink much from a bottle marked +`poison,' it is almost certain to disagree with you, sooner or +later. + + However, this bottle was NOT marked `poison,' so Alice ventured +to taste it, and finding it very nice, (it had, in fact, a sort +of mixed flavour of cherry-tart, custard, pine-apple, roast +turkey, toffee, and hot buttered toast,) she very soon finished +it off. + + * * * * * * * + + * * * * * * + + * * * * * * * + + `What a curious feeling!' said Alice; `I must be shutting up +like a telescope.' + + And so it was indeed: she was now only ten inches high, and +her face brightened up at the thought that she was now the right +size for going though the little door into that lovely garden. +First, however, she waited for a few minutes to see if she was +going to shrink any further: she felt a little nervous about +this; `for it might end, you know,' said Alice to herself, `in my +going out altogether, like a candle. I wonder what I should be +like then?' And she tried to fancy what the flame of a candle is +like after the candle is blown out, for she could not remember +ever having seen such a thing. + + After a while, finding that nothing more happened, she decided +on going into the garden at once; but, alas for poor Alice! when +she got to the door, she found he had forgotten the little golden +key, and when she went back to the table for it, she found she +could not possibly reach it: she could see it quite plainly +through the glass, and she tried her best to climb up one of the +legs of the table, but it was too slippery; and when she had +tired herself out with trying, the poor little thing sat down and +cried. + + `Come, there's no use in crying like that!' said Alice to +herself, rather sharply; `I advise you to leave off this minute!' +She generally gave herself very good advice, (though she very +seldom followed it), and sometimes she scolded herself so +severely as to bring tears into her eyes; and once she remembered +trying to box her own ears for having cheated herself in a game +of croquet she was playing against herself, for this curious +child was very fond of pretending to be two people. `But it's no +use now,' thought poor Alice, `to pretend to be two people! Why, +there's hardly enough of me left to make ONE respectable +person!' + + Soon her eye fell on a little glass box that was lying under +the table: she opened it, and found in it a very small cake, on +which the words `EAT ME' were beautifully marked in currants. +`Well, I'll eat it,' said Alice, `and if it makes me grow larger, +I can reach the key; and if it makes me grow smaller, I can creep +under the door; so either way I'll get into the garden, and I +don't care which happens!' + + She ate a little bit, and said anxiously to herself, `Which +way? Which way?', holding her hand on the top of her head to +feel which way it was growing, and she was quite surprised to +find that she remained the same size: to be sure, this generally +happens when one eats cake, but Alice had got so much into the +way of expecting nothing but out-of-the-way things to happen, +that it seemed quite dull and stupid for life to go on in the +common way. + + So she set to work, and very soon finished off the cake. + + * * * * * * * + + * * * * * * + + * * * * * * * + + + + + CHAPTER II + + The Pool of Tears + + + `Curiouser and curiouser!' cried Alice (she was so much +surprised, that for the moment she quite forgot how to speak good +English); `now I'm opening out like the largest telescope that +ever was! Good-bye, feet!' (for when she looked down at her +feet, they seemed to be almost out of sight, they were getting so +far off). `Oh, my poor little feet, I wonder who will put on +your shoes and stockings for you now, dears? I'm sure _I_ shan't +be able! I shall be a great deal too far off to trouble myself +about you: you must manage the best way you can; --but I must be +kind to them,' thought Alice, `or perhaps they won't walk the +way I want to go! Let me see: I'll give them a new pair of +boots every Christmas.' + + And she went on planning to herself how she would manage it. +`They must go by the carrier,' she thought; `and how funny it'll +seem, sending presents to one's own feet! And how odd the +directions will look! + + ALICE'S RIGHT FOOT, ESQ. + HEARTHRUG, + NEAR THE FENDER, + (WITH ALICE'S LOVE). + +Oh dear, what nonsense I'm talking!' + + Just then her head struck against the roof of the hall: in +fact she was now more than nine feet high, and she at once took +up the little golden key and hurried off to the garden door. + + Poor Alice! It was as much as she could do, lying down on one +side, to look through into the garden with one eye; but to get +through was more hopeless than ever: she sat down and began to +cry again. + + `You ought to be ashamed of yourself,' said Alice, `a great +girl like you,' (she might well say this), `to go on crying in +this way! Stop this moment, I tell you!' But she went on all +the same, shedding gallons of tears, until there was a large pool +all round her, about four inches deep and reaching half down the +hall. + + After a time she heard a little pattering of feet in the +distance, and she hastily dried her eyes to see what was coming. +It was the White Rabbit returning, splendidly dressed, with a +pair of white kid gloves in one hand and a large fan in the +other: he came trotting along in a great hurry, muttering to +himself as he came, `Oh! the Duchess, the Duchess! Oh! won't she +be savage if I've kept her waiting!' Alice felt so desperate +that she was ready to ask help of any one; so, when the Rabbit +came near her, she began, in a low, timid voice, `If you please, +sir--' The Rabbit started violently, dropped the white kid +gloves and the fan, and skurried away into the darkness as hard +as he could go. + + Alice took up the fan and gloves, and, as the hall was very +hot, she kept fanning herself all the time she went on talking: +`Dear, dear! How queer everything is to-day! And yesterday +things went on just as usual. I wonder if I've been changed in +the night? Let me think: was I the same when I got up this +morning? I almost think I can remember feeling a little +different. But if I'm not the same, the next question is, Who in +the world am I? Ah, THAT'S the great puzzle!' And she began +thinking over all the children she knew that were of the same age +as herself, to see if she could have been changed for any of +them. + + `I'm sure I'm not Ada,' she said, `for her hair goes in such +long ringlets, and mine doesn't go in ringlets at all; and I'm +sure I can't be Mabel, for I know all sorts of things, and she, +oh! she knows such a very little! Besides, SHE'S she, and I'm I, +and--oh dear, how puzzling it all is! I'll try if I know all the +things I used to know. Let me see: four times five is twelve, +and four times six is thirteen, and four times seven is--oh dear! +I shall never get to twenty at that rate! However, the +Multiplication Table doesn't signify: let's try Geography. +London is the capital of Paris, and Paris is the capital of Rome, +and Rome--no, THAT'S all wrong, I'm certain! I must have been +changed for Mabel! I'll try and say "How doth the little--"' +and she crossed her hands on her lap as if she were saying lessons, +and began to repeat it, but her voice sounded hoarse and +strange, and the words did not come the same as they used to do:-- + + `How doth the little crocodile + Improve his shining tail, + And pour the waters of the Nile + On every golden scale! + + `How cheerfully he seems to grin, + How neatly spread his claws, + And welcome little fishes in + With gently smiling jaws!' + + `I'm sure those are not the right words,' said poor Alice, and +her eyes filled with tears again as she went on, `I must be Mabel +after all, and I shall have to go and live in that poky little +house, and have next to no toys to play with, and oh! ever so +many lessons to learn! No, I've made up my mind about it; if I'm +Mabel, I'll stay down here! It'll be no use their putting their +heads down and saying "Come up again, dear!" I shall only look +up and say "Who am I then? Tell me that first, and then, if I +like being that person, I'll come up: if not, I'll stay down +here till I'm somebody else"--but, oh dear!' cried Alice, with a +sudden burst of tears, `I do wish they WOULD put their heads +down! I am so VERY tired of being all alone here!' + + As she said this she looked down at her hands, and was +surprised to see that she had put on one of the Rabbit's little +white kid gloves while she was talking. `How CAN I have done +that?' she thought. `I must be growing small again.' She got up +and went to the table to measure herself by it, and found that, +as nearly as she could guess, she was now about two feet high, +and was going on shrinking rapidly: she soon found out that the +cause of this was the fan she was holding, and she dropped it +hastily, just in time to avoid shrinking away altogether. + +`That WAS a narrow escape!' said Alice, a good deal frightened at +the sudden change, but very glad to find herself still in +existence; `and now for the garden!' and she ran with all speed +back to the little door: but, alas! the little door was shut +again, and the little golden key was lying on the glass table as +before, `and things are worse than ever,' thought the poor child, +`for I never was so small as this before, never! And I declare +it's too bad, that it is!' + + As she said these words her foot slipped, and in another +moment, splash! she was up to her chin in salt water. He first +idea was that she had somehow fallen into the sea, `and in that +case I can go back by railway,' she said to herself. (Alice had +been to the seaside once in her life, and had come to the general +conclusion, that wherever you go to on the English coast you find +a number of bathing machines in the sea, some children digging in +the sand with wooden spades, then a row of lodging houses, and +behind them a railway station.) However, she soon made out that +she was in the pool of tears which she had wept when she was nine +feet high. + + `I wish I hadn't cried so much!' said Alice, as she swam about, +trying to find her way out. `I shall be punished for it now, I +suppose, by being drowned in my own tears! That WILL be a queer +thing, to be sure! However, everything is queer to-day.' + + Just then she heard something splashing about in the pool a +little way off, and she swam nearer to make out what it was: at +first she thought it must be a walrus or hippopotamus, but then +she remembered how small she was now, and she soon made out that +it was only a mouse that had slipped in like herself. + + `Would it be of any use, now,' thought Alice, `to speak to this +mouse? Everything is so out-of-the-way down here, that I should +think very likely it can talk: at any rate, there's no harm in +trying.' So she began: `O Mouse, do you know the way out of +this pool? I am very tired of swimming about here, O Mouse!' +(Alice thought this must be the right way of speaking to a mouse: +she had never done such a thing before, but she remembered having +seen in her brother's Latin Grammar, `A mouse--of a mouse--to a +mouse--a mouse--O mouse!' The Mouse looked at her rather +inquisitively, and seemed to her to wink with one of its little +eyes, but it said nothing. + + `Perhaps it doesn't understand English,' thought Alice; `I +daresay it's a French mouse, come over with William the +Conqueror.' (For, with all her knowledge of history, Alice had +no very clear notion how long ago anything had happened.) So she +began again: `Ou est ma chatte?' which was the first sentence in +her French lesson-book. The Mouse gave a sudden leap out of the +water, and seemed to quiver all over with fright. `Oh, I beg +your pardon!' cried Alice hastily, afraid that she had hurt the +poor animal's feelings. `I quite forgot you didn't like cats.' + + `Not like cats!' cried the Mouse, in a shrill, passionate +voice. `Would YOU like cats if you were me?' + + `Well, perhaps not,' said Alice in a soothing tone: `don't be +angry about it. And yet I wish I could show you our cat Dinah: +I think you'd take a fancy to cats if you could only see her. +She is such a dear quiet thing,' Alice went on, half to herself, +as she swam lazily about in the pool, `and she sits purring so +nicely by the fire, licking her paws and washing her face--and +she is such a nice soft thing to nurse--and she's such a capital +one for catching mice--oh, I beg your pardon!' cried Alice again, +for this time the Mouse was bristling all over, and she felt +certain it must be really offended. `We won't talk about her any +more if you'd rather not.' + + `We indeed!' cried the Mouse, who was trembling down to the end +of his tail. `As if I would talk on such a subject! Our family +always HATED cats: nasty, low, vulgar things! Don't let me hear +the name again!' + + `I won't indeed!' said Alice, in a great hurry to change the +subject of conversation. `Are you--are you fond--of--of dogs?' +The Mouse did not answer, so Alice went on eagerly: `There is +such a nice little dog near our house I should like to show you! +A little bright-eyed terrier, you know, with oh, such long curly +brown hair! And it'll fetch things when you throw them, and +it'll sit up and beg for its dinner, and all sorts of things--I +can't remember half of them--and it belongs to a farmer, you +know, and he says it's so useful, it's worth a hundred pounds! +He says it kills all the rats and--oh dear!' cried Alice in a +sorrowful tone, `I'm afraid I've offended it again!' For the +Mouse was swimming away from her as hard as it could go, and +making quite a commotion in the pool as it went. + + So she called softly after it, `Mouse dear! Do come back +again, and we won't talk about cats or dogs either, if you don't +like them!' When the Mouse heard this, it turned round and swam +slowly back to her: its face was quite pale (with passion, Alice +thought), and it said in a low trembling voice, `Let us get to +the shore, and then I'll tell you my history, and you'll +understand why it is I hate cats and dogs.' + + It was high time to go, for the pool was getting quite crowded +with the birds and animals that had fallen into it: there were a +Duck and a Dodo, a Lory and an Eaglet, and several other curious +creatures. Alice led the way, and the whole party swam to the +shore. + + + + CHAPTER III + + A Caucus-Race and a Long Tale + + + They were indeed a queer-looking party that assembled on the +bank--the birds with draggled feathers, the animals with their +fur clinging close to them, and all dripping wet, cross, and +uncomfortable. + + The first question of course was, how to get dry again: they +had a consultation about this, and after a few minutes it seemed +quite natural to Alice to find herself talking familiarly with +them, as if she had known them all her life. Indeed, she had +quite a long argument with the Lory, who at last turned sulky, +and would only say, `I am older than you, and must know better'; +and this Alice would not allow without knowing how old it was, +and, as the Lory positively refused to tell its age, there was no +more to be said. + + At last the Mouse, who seemed to be a person of authority among +them, called out, `Sit down, all of you, and listen to me! I'LL +soon make you dry enough!' They all sat down at once, in a large +ring, with the Mouse in the middle. Alice kept her eyes +anxiously fixed on it, for she felt sure she would catch a bad +cold if she did not get dry very soon. + + `Ahem!' said the Mouse with an important air, `are you all ready? +This is the driest thing I know. Silence all round, if you please! +"William the Conqueror, whose cause was favoured by the pope, was +soon submitted to by the English, who wanted leaders, and had been +of late much accustomed to usurpation and conquest. Edwin and +Morcar, the earls of Mercia and Northumbria--"' + + `Ugh!' said the Lory, with a shiver. + + `I beg your pardon!' said the Mouse, frowning, but very +politely: `Did you speak?' + + `Not I!' said the Lory hastily. + + `I thought you did,' said the Mouse. `--I proceed. "Edwin and +Morcar, the earls of Mercia and Northumbria, declared for him: +and even Stigand, the patriotic archbishop of Canterbury, found +it advisable--"' + + `Found WHAT?' said the Duck. + + `Found IT,' the Mouse replied rather crossly: `of course you +know what "it" means.' + + `I know what "it" means well enough, when I find a thing,' said +the Duck: `it's generally a frog or a worm. The question is, +what did the archbishop find?' + + The Mouse did not notice this question, but hurriedly went on, +`"--found it advisable to go with Edgar Atheling to meet William +and offer him the crown. William's conduct at first was +moderate. But the insolence of his Normans--" How are you +getting on now, my dear?' it continued, turning to Alice as it +spoke. + + `As wet as ever,' said Alice in a melancholy tone: `it doesn't +seem to dry me at all.' + + `In that case,' said the Dodo solemnly, rising to its feet, `I +move that the meeting adjourn, for the immediate adoption of more +energetic remedies--' + + `Speak English!' said the Eaglet. `I don't know the meaning of +half those long words, and, what's more, I don't believe you do +either!' And the Eaglet bent down its head to hide a smile: +some of the other birds tittered audibly. + + `What I was going to say,' said the Dodo in an offended tone, +`was, that the best thing to get us dry would be a Caucus-race.' + + `What IS a Caucus-race?' said Alice; not that she wanted much +to know, but the Dodo had paused as if it thought that SOMEBODY +ought to speak, and no one else seemed inclined to say anything. + + `Why,' said the Dodo, `the best way to explain it is to do it.' +(And, as you might like to try the thing yourself, some winter +day, I will tell you how the Dodo managed it.) + + First it marked out a race-course, in a sort of circle, (`the +exact shape doesn't matter,' it said,) and then all the party +were placed along the course, here and there. There was no `One, +two, three, and away,' but they began running when they liked, +and left off when they liked, so that it was not easy to know +when the race was over. However, when they had been running half +an hour or so, and were quite dry again, the Dodo suddenly called +out `The race is over!' and they all crowded round it, panting, +and asking, `But who has won?' + + This question the Dodo could not answer without a great deal of +thought, and it sat for a long time with one finger pressed upon +its forehead (the position in which you usually see Shakespeare, +in the pictures of him), while the rest waited in silence. At +last the Dodo said, `EVERYBODY has won, and all must have +prizes.' + + `But who is to give the prizes?' quite a chorus of voices +asked. + + `Why, SHE, of course,' said the Dodo, pointing to Alice with +one finger; and the whole party at once crowded round her, +calling out in a confused way, `Prizes! Prizes!' + + Alice had no idea what to do, and in despair she put her hand +in her pocket, and pulled out a box of comfits, (luckily the salt +water had not got into it), and handed them round as prizes. +There was exactly one a-piece all round. + + `But she must have a prize herself, you know,' said the Mouse. + + `Of course,' the Dodo replied very gravely. `What else have +you got in your pocket?' he went on, turning to Alice. + + `Only a thimble,' said Alice sadly. + + `Hand it over here,' said the Dodo. + + Then they all crowded round her once more, while the Dodo +solemnly presented the thimble, saying `We beg your acceptance of +this elegant thimble'; and, when it had finished this short +speech, they all cheered. + + Alice thought the whole thing very absurd, but they all looked +so grave that she did not dare to laugh; and, as she could not +think of anything to say, she simply bowed, and took the thimble, +looking as solemn as she could. + + The next thing was to eat the comfits: this caused some noise +and confusion, as the large birds complained that they could not +taste theirs, and the small ones choked and had to be patted on +the back. However, it was over at last, and they sat down again +in a ring, and begged the Mouse to tell them something more. + + `You promised to tell me your history, you know,' said Alice, +`and why it is you hate--C and D,' she added in a whisper, half +afraid that it would be offended again. + + `Mine is a long and a sad tale!' said the Mouse, turning to +Alice, and sighing. + + `It IS a long tail, certainly,' said Alice, looking down with +wonder at the Mouse's tail; `but why do you call it sad?' And +she kept on puzzling about it while the Mouse was speaking, so +that her idea of the tale was something like this:-- + + `Fury said to a + mouse, That he + met in the + house, + "Let us + both go to + law: I will + prosecute + YOU. --Come, + I'll take no + denial; We + must have a + trial: For + really this + morning I've + nothing + to do." + Said the + mouse to the + cur, "Such + a trial, + dear Sir, + With + no jury + or judge, + would be + wasting + our + breath." + "I'll be + judge, I'll + be jury," + Said + cunning + old Fury: + "I'll + try the + whole + cause, + and + condemn + you + to + death."' + + + `You are not attending!' said the Mouse to Alice severely. +`What are you thinking of?' + + `I beg your pardon,' said Alice very humbly: `you had got to +the fifth bend, I think?' + + `I had NOT!' cried the Mouse, sharply and very angrily. + + `A knot!' said Alice, always ready to make herself useful, and +looking anxiously about her. `Oh, do let me help to undo it!' + + `I shall do nothing of the sort,' said the Mouse, getting up +and walking away. `You insult me by talking such nonsense!' + + `I didn't mean it!' pleaded poor Alice. `But you're so easily +offended, you know!' + + The Mouse only growled in reply. + + `Please come back and finish your story!' Alice called after +it; and the others all joined in chorus, `Yes, please do!' but +the Mouse only shook its head impatiently, and walked a little +quicker. + + `What a pity it wouldn't stay!' sighed the Lory, as soon as it +was quite out of sight; and an old Crab took the opportunity of +saying to her daughter `Ah, my dear! Let this be a lesson to you +never to lose YOUR temper!' `Hold your tongue, Ma!' said the +young Crab, a little snappishly. `You're enough to try the +patience of an oyster!' + + `I wish I had our Dinah here, I know I do!' said Alice aloud, +addressing nobody in particular. `She'd soon fetch it back!' + + `And who is Dinah, if I might venture to ask the question?' +said the Lory. + + Alice replied eagerly, for she was always ready to talk about +her pet: `Dinah's our cat. And she's such a capital one for +catching mice you can't think! And oh, I wish you could see her +after the birds! Why, she'll eat a little bird as soon as look +at it!' + + This speech caused a remarkable sensation among the party. +Some of the birds hurried off at once: one the old Magpie began +wrapping itself up very carefully, remarking, `I really must be +getting home; the night-air doesn't suit my throat!' and a Canary +called out in a trembling voice to its children, `Come away, my +dears! It's high time you were all in bed!' On various pretexts +they all moved off, and Alice was soon left alone. + + `I wish I hadn't mentioned Dinah!' she said to herself in a +melancholy tone. `Nobody seems to like her, down here, and I'm +sure she's the best cat in the world! Oh, my dear Dinah! I +wonder if I shall ever see you any more!' And here poor Alice +began to cry again, for she felt very lonely and low-spirited. +In a little while, however, she again heard a little pattering of +footsteps in the distance, and she looked up eagerly, half hoping +that the Mouse had changed his mind, and was coming back to +finish his story. + + + + CHAPTER IV + + The Rabbit Sends in a Little Bill + + + It was the White Rabbit, trotting slowly back again, and +looking anxiously about as it went, as if it had lost something; +and she heard it muttering to itself `The Duchess! The Duchess! +Oh my dear paws! Oh my fur and whiskers! She'll get me +executed, as sure as ferrets are ferrets! Where CAN I have +dropped them, I wonder?' Alice guessed in a moment that it was +looking for the fan and the pair of white kid gloves, and she +very good-naturedly began hunting about for them, but they were +nowhere to be seen--everything seemed to have changed since her +swim in the pool, and the great hall, with the glass table and +the little door, had vanished completely. + + Very soon the Rabbit noticed Alice, as she went hunting about, +and called out to her in an angry tone, `Why, Mary Ann, what ARE +you doing out here? Run home this moment, and fetch me a pair of +gloves and a fan! Quick, now!' And Alice was so much frightened +that she ran off at once in the direction it pointed to, without +trying to explain the mistake it had made. + + `He took me for his housemaid,' she said to herself as she ran. +`How surprised he'll be when he finds out who I am! But I'd +better take him his fan and gloves--that is, if I can find them.' +As she said this, she came upon a neat little house, on the door +of which was a bright brass plate with the name `W. RABBIT' +engraved upon it. She went in without knocking, and hurried +upstairs, in great fear lest she should meet the real Mary Ann, +and be turned out of the house before she had found the fan and +gloves. + + `How queer it seems,' Alice said to herself, `to be going +messages for a rabbit! I suppose Dinah'll be sending me on +messages next!' And she began fancying the sort of thing that +would happen: `"Miss Alice! Come here directly, and get ready +for your walk!" "Coming in a minute, nurse! But I've got to see +that the mouse doesn't get out." Only I don't think,' Alice went +on, `that they'd let Dinah stop in the house if it began ordering +people about like that!' + + By this time she had found her way into a tidy little room with +a table in the window, and on it (as she had hoped) a fan and two +or three pairs of tiny white kid gloves: she took up the fan and +a pair of the gloves, and was just going to leave the room, when +her eye fell upon a little bottle that stood near the looking- +glass. There was no label this time with the words `DRINK ME,' +but nevertheless she uncorked it and put it to her lips. `I know +SOMETHING interesting is sure to happen,' she said to herself, +`whenever I eat or drink anything; so I'll just see what this +bottle does. I do hope it'll make me grow large again, for +really I'm quite tired of being such a tiny little thing!' + + It did so indeed, and much sooner than she had expected: +before she had drunk half the bottle, she found her head pressing +against the ceiling, and had to stoop to save her neck from being +broken. She hastily put down the bottle, saying to herself +`That's quite enough--I hope I shan't grow any more--As it is, I +can't get out at the door--I do wish I hadn't drunk quite so +much!' + + Alas! it was too late to wish that! She went on growing, and +growing, and very soon had to kneel down on the floor: in +another minute there was not even room for this, and she tried +the effect of lying down with one elbow against the door, and the +other arm curled round her head. Still she went on growing, and, +as a last resource, she put one arm out of the window, and one +foot up the chimney, and said to herself `Now I can do no more, +whatever happens. What WILL become of me?' + + Luckily for Alice, the little magic bottle had now had its full +effect, and she grew no larger: still it was very uncomfortable, +and, as there seemed to be no sort of chance of her ever getting +out of the room again, no wonder she felt unhappy. + + `It was much pleasanter at home,' thought poor Alice, `when one +wasn't always growing larger and smaller, and being ordered about +by mice and rabbits. I almost wish I hadn't gone down that +rabbit-hole--and yet--and yet--it's rather curious, you know, +this sort of life! I do wonder what CAN have happened to me! +When I used to read fairy-tales, I fancied that kind of thing +never happened, and now here I am in the middle of one! There +ought to be a book written about me, that there ought! And when +I grow up, I'll write one--but I'm grown up now,' she added in a +sorrowful tone; `at least there's no room to grow up any more +HERE.' + + `But then,' thought Alice, `shall I NEVER get any older than I +am now? That'll be a comfort, one way--never to be an old woman- +-but then--always to have lessons to learn! Oh, I shouldn't like +THAT!' + + `Oh, you foolish Alice!' she answered herself. `How can you +learn lessons in here? Why, there's hardly room for YOU, and no +room at all for any lesson-books!' + + And so she went on, taking first one side and then the other, +and making quite a conversation of it altogether; but after a few +minutes she heard a voice outside, and stopped to listen. + + `Mary Ann! Mary Ann!' said the voice. `Fetch me my gloves +this moment!' Then came a little pattering of feet on the +stairs. Alice knew it was the Rabbit coming to look for her, and +she trembled till she shook the house, quite forgetting that she +was now about a thousand times as large as the Rabbit, and had no +reason to be afraid of it. + + Presently the Rabbit came up to the door, and tried to open it; +but, as the door opened inwards, and Alice's elbow was pressed +hard against it, that attempt proved a failure. Alice heard it +say to itself `Then I'll go round and get in at the window.' + + `THAT you won't' thought Alice, and, after waiting till she +fancied she heard the Rabbit just under the window, she suddenly +spread out her hand, and made a snatch in the air. She did not +get hold of anything, but she heard a little shriek and a fall, +and a crash of broken glass, from which she concluded that it was +just possible it had fallen into a cucumber-frame, or something +of the sort. + + Next came an angry voice--the Rabbit's--`Pat! Pat! Where are +you?' And then a voice she had never heard before, `Sure then +I'm here! Digging for apples, yer honour!' + + `Digging for apples, indeed!' said the Rabbit angrily. `Here! +Come and help me out of THIS!' (Sounds of more broken glass.) + + `Now tell me, Pat, what's that in the window?' + + `Sure, it's an arm, yer honour!' (He pronounced it `arrum.') + + `An arm, you goose! Who ever saw one that size? Why, it +fills the whole window!' + + `Sure, it does, yer honour: but it's an arm for all that.' + + `Well, it's got no business there, at any rate: go and take it +away!' + + There was a long silence after this, and Alice could only hear +whispers now and then; such as, `Sure, I don't like it, yer +honour, at all, at all!' `Do as I tell you, you coward!' and at +last she spread out her hand again, and made another snatch in +the air. This time there were TWO little shrieks, and more +sounds of broken glass. `What a number of cucumber-frames there +must be!' thought Alice. `I wonder what they'll do next! As for +pulling me out of the window, I only wish they COULD! I'm sure I +don't want to stay in here any longer!' + + She waited for some time without hearing anything more: at +last came a rumbling of little cartwheels, and the sound of a +good many voice all talking together: she made out the words: +`Where's the other ladder?--Why, I hadn't to bring but one; +Bill's got the other--Bill! fetch it here, lad!--Here, put 'em up +at this corner--No, tie 'em together first--they don't reach half +high enough yet--Oh! they'll do well enough; don't be particular- +-Here, Bill! catch hold of this rope--Will the roof bear?--Mind +that loose slate--Oh, it's coming down! Heads below!' (a loud +crash)--`Now, who did that?--It was Bill, I fancy--Who's to go +down the chimney?--Nay, I shan't! YOU do it!--That I won't, +then!--Bill's to go down--Here, Bill! the master says you're to +go down the chimney!' + + `Oh! So Bill's got to come down the chimney, has he?' said +Alice to herself. `Shy, they seem to put everything upon Bill! +I wouldn't be in Bill's place for a good deal: this fireplace is +narrow, to be sure; but I THINK I can kick a little!' + + She drew her foot as far down the chimney as she could, and +waited till she heard a little animal (she couldn't guess of what +sort it was) scratching and scrambling about in the chimney close +above her: then, saying to herself `This is Bill,' she gave one +sharp kick, and waited to see what would happen next. + + The first thing she heard was a general chorus of `There goes +Bill!' then the Rabbit's voice along--`Catch him, you by the +hedge!' then silence, and then another confusion of voices--`Hold +up his head--Brandy now--Don't choke him--How was it, old fellow? +What happened to you? Tell us all about it!' + + Last came a little feeble, squeaking voice, (`That's Bill,' +thought Alice,) `Well, I hardly know--No more, thank ye; I'm +better now--but I'm a deal too flustered to tell you--all I know +is, something comes at me like a Jack-in-the-box, and up I goes +like a sky-rocket!' + + `So you did, old fellow!' said the others. + + `We must burn the house down!' said the Rabbit's voice; and +Alice called out as loud as she could, `If you do. I'll set +Dinah at you!' + + There was a dead silence instantly, and Alice thought to +herself, `I wonder what they WILL do next! If they had any +sense, they'd take the roof off.' After a minute or two, they +began moving about again, and Alice heard the Rabbit say, `A +barrowful will do, to begin with.' + + `A barrowful of WHAT?' thought Alice; but she had not long to +doubt, for the next moment a shower of little pebbles came +rattling in at the window, and some of them hit her in the face. +`I'll put a stop to this,' she said to herself, and shouted out, +`You'd better not do that again!' which produced another dead +silence. + + Alice noticed with some surprise that the pebbles were all +turning into little cakes as they lay on the floor, and a bright +idea came into her head. `If I eat one of these cakes,' she +thought, `it's sure to make SOME change in my size; and as it +can't possibly make me larger, it must make me smaller, I +suppose.' + + So she swallowed one of the cakes, and was delighted to find +that she began shrinking directly. As soon as she was small +enough to get through the door, she ran out of the house, and +found quite a crowd of little animals and birds waiting outside. +The poor little Lizard, Bill, was in the middle, being held up by +two guinea-pigs, who were giving it something out of a bottle. +They all made a rush at Alice the moment she appeared; but she +ran off as hard as she could, and soon found herself safe in a +thick wood. + + `The first thing I've got to do,' said Alice to herself, as she +wandered about in the wood, `is to grow to my right size again; +and the second thing is to find my way into that lovely garden. +I think that will be the best plan.' + + It sounded an excellent plan, no doubt, and very neatly and +simply arranged; the only difficulty was, that she had not the +smallest idea how to set about it; and while she was peering +about anxiously among the trees, a little sharp bark just over +her head made her look up in a great hurry. + + An enormous puppy was looking down at her with large round +eyes, and feebly stretching out one paw, trying to touch her. +`Poor little thing!' said Alice, in a coaxing tone, and she tried +hard to whistle to it; but she was terribly frightened all the +time at the thought that it might be hungry, in which case it +would be very likely to eat her up in spite of all her coaxing. + + Hardly knowing what she did, she picked up a little bit of +stick, and held it out to the puppy; whereupon the puppy jumped +into the air off all its feet at once, with a yelp of delight, +and rushed at the stick, and made believe to worry it; then Alice +dodged behind a great thistle, to keep herself from being run +over; and the moment she appeared on the other side, the puppy +made another rush at the stick, and tumbled head over heels in +its hurry to get hold of it; then Alice, thinking it was very +like having a game of play with a cart-horse, and expecting every +moment to be trampled under its feet, ran round the thistle +again; then the puppy began a series of short charges at the +stick, running a very little way forwards each time and a long +way back, and barking hoarsely all the while, till at last it sat +down a good way off, panting, with its tongue hanging out of its +mouth, and its great eyes half shut. + + This seemed to Alice a good opportunity for making her escape; +so she set off at once, and ran till she was quite tired and out +of breath, and till the puppy's bark sounded quite faint in the +distance. + + `And yet what a dear little puppy it was!' said Alice, as she +leant against a buttercup to rest herself, and fanned herself +with one of the leaves: `I should have liked teaching it tricks +very much, if--if I'd only been the right size to do it! Oh +dear! I'd nearly forgotten that I've got to grow up again! Let +me see--how IS it to be managed? I suppose I ought to eat or +drink something or other; but the great question is, what?' + + The great question certainly was, what? Alice looked all round +her at the flowers and the blades of grass, but she did not see +anything that looked like the right thing to eat or drink under +the circumstances. There was a large mushroom growing near her, +about the same height as herself; and when she had looked under +it, and on both sides of it, and behind it, it occurred to her +that she might as well look and see what was on the top of it. + + She stretched herself up on tiptoe, and peeped over the edge of +the mushroom, and her eyes immediately met those of a large +caterpillar, that was sitting on the top with its arms folded, +quietly smoking a long hookah, and taking not the smallest notice +of her or of anything else. + + + + CHAPTER V + + Advice from a Caterpillar + + + The Caterpillar and Alice looked at each other for some time in +silence: at last the Caterpillar took the hookah out of its +mouth, and addressed her in a languid, sleepy voice. + + `Who are YOU?' said the Caterpillar. + + This was not an encouraging opening for a conversation. Alice +replied, rather shyly, `I--I hardly know, sir, just at present-- +at least I know who I WAS when I got up this morning, but I think +I must have been changed several times since then.' + + `What do you mean by that?' said the Caterpillar sternly. +`Explain yourself!' + + `I can't explain MYSELF, I'm afraid, sir' said Alice, `because +I'm not myself, you see.' + + `I don't see,' said the Caterpillar. + + `I'm afraid I can't put it more clearly,' Alice replied very +politely, `for I can't understand it myself to begin with; and +being so many different sizes in a day is very confusing.' + + `It isn't,' said the Caterpillar. + + `Well, perhaps you haven't found it so yet,' said Alice; `but +when you have to turn into a chrysalis--you will some day, you +know--and then after that into a butterfly, I should think you'll +feel it a little queer, won't you?' + + `Not a bit,' said the Caterpillar. + + `Well, perhaps your feelings may be different,' said Alice; +`all I know is, it would feel very queer to ME.' + + `You!' said the Caterpillar contemptuously. `Who are YOU?' + + Which brought them back again to the beginning of the +conversation. Alice felt a little irritated at the Caterpillar's +making such VERY short remarks, and she drew herself up and said, +very gravely, `I think, you ought to tell me who YOU are, first.' + + `Why?' said the Caterpillar. + + Here was another puzzling question; and as Alice could not +think of any good reason, and as the Caterpillar seemed to be in +a VERY unpleasant state of mind, she turned away. + + `Come back!' the Caterpillar called after her. `I've something +important to say!' + + This sounded promising, certainly: Alice turned and came back +again. + + `Keep your temper,' said the Caterpillar. + + `Is that all?' said Alice, swallowing down her anger as well as +she could. + + `No,' said the Caterpillar. + + Alice thought she might as well wait, as she had nothing else +to do, and perhaps after all it might tell her something worth +hearing. For some minutes it puffed away without speaking, but +at last it unfolded its arms, took the hookah out of its mouth +again, and said, `So you think you're changed, do you?' + + `I'm afraid I am, sir,' said Alice; `I can't remember things as +I used--and I don't keep the same size for ten minutes together!' + + `Can't remember WHAT things?' said the Caterpillar. + + `Well, I've tried to say "HOW DOTH THE LITTLE BUSY BEE," but it +all came different!' Alice replied in a very melancholy voice. + + `Repeat, "YOU ARE OLD, FATHER WILLIAM,"' said the Caterpillar. + + Alice folded her hands, and began:-- + + `You are old, Father William,' the young man said, + `And your hair has become very white; + And yet you incessantly stand on your head-- + Do you think, at your age, it is right?' + + `In my youth,' Father William replied to his son, + `I feared it might injure the brain; + But, now that I'm perfectly sure I have none, + Why, I do it again and again.' + + `You are old,' said the youth, `as I mentioned before, + And have grown most uncommonly fat; + Yet you turned a back-somersault in at the door-- + Pray, what is the reason of that?' + + `In my youth,' said the sage, as he shook his grey locks, + `I kept all my limbs very supple + By the use of this ointment--one shilling the box-- + Allow me to sell you a couple?' + + `You are old,' said the youth, `and your jaws are too weak + For anything tougher than suet; + Yet you finished the goose, with the bones and the beak-- + Pray how did you manage to do it?' + + `In my youth,' said his father, `I took to the law, + And argued each case with my wife; + And the muscular strength, which it gave to my jaw, + Has lasted the rest of my life.' + + `You are old,' said the youth, `one would hardly suppose + That your eye was as steady as ever; + Yet you balanced an eel on the end of your nose-- + What made you so awfully clever?' + + `I have answered three questions, and that is enough,' + Said his father; `don't give yourself airs! + Do you think I can listen all day to such stuff? + Be off, or I'll kick you down stairs!' + + + `That is not said right,' said the Caterpillar. + + `Not QUITE right, I'm afraid,' said Alice, timidly; `some of the +words have got altered.' + + `It is wrong from beginning to end,' said the Caterpillar +decidedly, and there was silence for some minutes. + + The Caterpillar was the first to speak. + + `What size do you want to be?' it asked. + + `Oh, I'm not particular as to size,' Alice hastily replied; +`only one doesn't like changing so often, you know.' + + `I DON'T know,' said the Caterpillar. + + Alice said nothing: she had never been so much contradicted in +her life before, and she felt that she was losing her temper. + + `Are you content now?' said the Caterpillar. + + `Well, I should like to be a LITTLE larger, sir, if you +wouldn't mind,' said Alice: `three inches is such a wretched +height to be.' + + `It is a very good height indeed!' said the Caterpillar +angrily, rearing itself upright as it spoke (it was exactly three +inches high). + + `But I'm not used to it!' pleaded poor Alice in a piteous tone. +And she thought of herself, `I wish the creatures wouldn't be so +easily offended!' + + `You'll get used to it in time,' said the Caterpillar; and it +put the hookah into its mouth and began smoking again. + + This time Alice waited patiently until it chose to speak again. +In a minute or two the Caterpillar took the hookah out of its +mouth and yawned once or twice, and shook itself. Then it got +down off the mushroom, and crawled away in the grass, merely +remarking as it went, `One side will make you grow taller, and +the other side will make you grow shorter.' + + `One side of WHAT? The other side of WHAT?' thought Alice to +herself. + + `Of the mushroom,' said the Caterpillar, just as if she had +asked it aloud; and in another moment it was out of sight. + + Alice remained looking thoughtfully at the mushroom for a +minute, trying to make out which were the two sides of it; and as +it was perfectly round, she found this a very difficult question. +However, at last she stretched her arms round it as far as they +would go, and broke off a bit of the edge with each hand. + + `And now which is which?' she said to herself, and nibbled a +little of the right-hand bit to try the effect: the next moment +she felt a violent blow underneath her chin: it had struck her +foot! + + She was a good deal frightened by this very sudden change, but +she felt that there was no time to be lost, as she was shrinking +rapidly; so she set to work at once to eat some of the other bit. +Her chin was pressed so closely against her foot, that there was +hardly room to open her mouth; but she did it at last, and +managed to swallow a morsel of the lefthand bit. + + + * * * * * * * + + * * * * * * + + * * * * * * * + + `Come, my head's free at last!' said Alice in a tone of +delight, which changed into alarm in another moment, when she +found that her shoulders were nowhere to be found: all she could +see, when she looked down, was an immense length of neck, which +seemed to rise like a stalk out of a sea of green leaves that lay +far below her. + + `What CAN all that green stuff be?' said Alice. `And where +HAVE my shoulders got to? And oh, my poor hands, how is it I +can't see you?' She was moving them about as she spoke, but no +result seemed to follow, except a little shaking among the +distant green leaves. + + As there seemed to be no chance of getting her hands up to her +head, she tried to get her head down to them, and was delighted +to find that her neck would bend about easily in any direction, +like a serpent. She had just succeeded in curving it down into a +graceful zigzag, and was going to dive in among the leaves, which +she found to be nothing but the tops of the trees under which she +had been wandering, when a sharp hiss made her draw back in a +hurry: a large pigeon had flown into her face, and was beating +her violently with its wings. + + `Serpent!' screamed the Pigeon. + + `I'm NOT a serpent!' said Alice indignantly. `Let me alone!' + + `Serpent, I say again!' repeated the Pigeon, but in a more +subdued tone, and added with a kind of sob, `I've tried every +way, and nothing seems to suit them!' + + `I haven't the least idea what you're talking about,' said +Alice. + + `I've tried the roots of trees, and I've tried banks, and I've +tried hedges,' the Pigeon went on, without attending to her; `but +those serpents! There's no pleasing them!' + + Alice was more and more puzzled, but she thought there was no +use in saying anything more till the Pigeon had finished. + + `As if it wasn't trouble enough hatching the eggs,' said the +Pigeon; `but I must be on the look-out for serpents night and +day! Why, I haven't had a wink of sleep these three weeks!' + + `I'm very sorry you've been annoyed,' said Alice, who was +beginning to see its meaning. + + `And just as I'd taken the highest tree in the wood,' continued +the Pigeon, raising its voice to a shriek, `and just as I was +thinking I should be free of them at last, they must needs come +wriggling down from the sky! Ugh, Serpent!' + + `But I'm NOT a serpent, I tell you!' said Alice. `I'm a--I'm +a--' + + `Well! WHAT are you?' said the Pigeon. `I can see you're +trying to invent something!' + + `I--I'm a little girl,' said Alice, rather doubtfully, as she +remembered the number of changes she had gone through that day. + + `A likely story indeed!' said the Pigeon in a tone of the +deepest contempt. `I've seen a good many little girls in my +time, but never ONE with such a neck as that! No, no! You're a +serpent; and there's no use denying it. I suppose you'll be +telling me next that you never tasted an egg!' + + `I HAVE tasted eggs, certainly,' said Alice, who was a very +truthful child; `but little girls eat eggs quite as much as +serpents do, you know.' + + `I don't believe it,' said the Pigeon; `but if they do, why +then they're a kind of serpent, that's all I can say.' + + This was such a new idea to Alice, that she was quite silent +for a minute or two, which gave the Pigeon the opportunity of +adding, `You're looking for eggs, I know THAT well enough; and +what does it matter to me whether you're a little girl or a +serpent?' + + `It matters a good deal to ME,' said Alice hastily; `but I'm +not looking for eggs, as it happens; and if I was, I shouldn't +want YOURS: I don't like them raw.' + + `Well, be off, then!' said the Pigeon in a sulky tone, as it +settled down again into its nest. Alice crouched down among the +trees as well as she could, for her neck kept getting entangled +among the branches, and every now and then she had to stop and +untwist it. After a while she remembered that she still held the +pieces of mushroom in her hands, and she set to work very +carefully, nibbling first at one and then at the other, and +growing sometimes taller and sometimes shorter, until she had +succeeded in bringing herself down to her usual height. + + It was so long since she had been anything near the right size, +that it felt quite strange at first; but she got used to it in a +few minutes, and began talking to herself, as usual. `Come, +there's half my plan done now! How puzzling all these changes +are! I'm never sure what I'm going to be, from one minute to +another! However, I've got back to my right size: the next +thing is, to get into that beautiful garden--how IS that to be +done, I wonder?' As she said this, she came suddenly upon an +open place, with a little house in it about four feet high. +`Whoever lives there,' thought Alice, `it'll never do to come +upon them THIS size: why, I should frighten them out of their +wits!' So she began nibbling at the righthand bit again, and did +not venture to go near the house till she had brought herself +down to nine inches high. + + + + CHAPTER VI + + Pig and Pepper + + + For a minute or two she stood looking at the house, and +wondering what to do next, when suddenly a footman in livery came +running out of the wood--(she considered him to be a footman +because he was in livery: otherwise, judging by his face only, +she would have called him a fish)--and rapped loudly at the door +with his knuckles. It was opened by another footman in livery, +with a round face, and large eyes like a frog; and both footmen, +Alice noticed, had powdered hair that curled all over their +heads. She felt very curious to know what it was all about, and +crept a little way out of the wood to listen. + + The Fish-Footman began by producing from under his arm a great +letter, nearly as large as himself, and this he handed over to +the other, saying, in a solemn tone, `For the Duchess. An +invitation from the Queen to play croquet.' The Frog-Footman +repeated, in the same solemn tone, only changing the order of the +words a little, `From the Queen. An invitation for the Duchess +to play croquet.' + + Then they both bowed low, and their curls got entangled +together. + + Alice laughed so much at this, that she had to run back into +the wood for fear of their hearing her; and when she next peeped +out the Fish-Footman was gone, and the other was sitting on the +ground near the door, staring stupidly up into the sky. + + Alice went timidly up to the door, and knocked. + + `There's no sort of use in knocking,' said the Footman, `and +that for two reasons. First, because I'm on the same side of the +door as you are; secondly, because they're making such a noise +inside, no one could possibly hear you.' And certainly there was +a most extraordinary noise going on within--a constant howling +and sneezing, and every now and then a great crash, as if a dish +or kettle had been broken to pieces. + + `Please, then,' said Alice, `how am I to get in?' + + `There might be some sense in your knocking,' the Footman went +on without attending to her, `if we had the door between us. For +instance, if you were INSIDE, you might knock, and I could let +you out, you know.' He was looking up into the sky all the time +he was speaking, and this Alice thought decidedly uncivil. `But +perhaps he can't help it,' she said to herself; `his eyes are so +VERY nearly at the top of his head. But at any rate he might +answer questions.--How am I to get in?' she repeated, aloud. + + `I shall sit here,' the Footman remarked, `till tomorrow--' + + At this moment the door of the house opened, and a large plate +came skimming out, straight at the Footman's head: it just +grazed his nose, and broke to pieces against one of the trees +behind him. + + `--or next day, maybe,' the Footman continued in the same tone, +exactly as if nothing had happened. + + `How am I to get in?' asked Alice again, in a louder tone. + + `ARE you to get in at all?' said the Footman. `That's the +first question, you know.' + + It was, no doubt: only Alice did not like to be told so. +`It's really dreadful,' she muttered to herself, `the way all the +creatures argue. It's enough to drive one crazy!' + + The Footman seemed to think this a good opportunity for +repeating his remark, with variations. `I shall sit here,' he +said, `on and off, for days and days.' + + `But what am I to do?' said Alice. + + `Anything you like,' said the Footman, and began whistling. + + `Oh, there's no use in talking to him,' said Alice desperately: +`he's perfectly idiotic!' And she opened the door and went in. + + The door led right into a large kitchen, which was full of +smoke from one end to the other: the Duchess was sitting on a +three-legged stool in the middle, nursing a baby; the cook was +leaning over the fire, stirring a large cauldron which seemed to +be full of soup. + + `There's certainly too much pepper in that soup!' Alice said to +herself, as well as she could for sneezing. + + There was certainly too much of it in the air. Even the +Duchess sneezed occasionally; and as for the baby, it was +sneezing and howling alternately without a moment's pause. The +only things in the kitchen that did not sneeze, were the cook, +and a large cat which was sitting on the hearth and grinning from +ear to ear. + + `Please would you tell me,' said Alice, a little timidly, for +she was not quite sure whether it was good manners for her to +speak first, `why your cat grins like that?' + + `It's a Cheshire cat,' said the Duchess, `and that's why. +Pig!' + + She said the last word with such sudden violence that Alice +quite jumped; but she saw in another moment that it was addressed +to the baby, and not to her, so she took courage, and went on +again:-- + + `I didn't know that Cheshire cats always grinned; in fact, I +didn't know that cats COULD grin.' + + `They all can,' said the Duchess; `and most of 'em do.' + + `I don't know of any that do,' Alice said very politely, +feeling quite pleased to have got into a conversation. + + `You don't know much,' said the Duchess; `and that's a fact.' + + Alice did not at all like the tone of this remark, and thought +it would be as well to introduce some other subject of +conversation. While she was trying to fix on one, the cook took +the cauldron of soup off the fire, and at once set to work +throwing everything within her reach at the Duchess and the baby +--the fire-irons came first; then followed a shower of saucepans, +plates, and dishes. The Duchess took no notice of them even when +they hit her; and the baby was howling so much already, that it +was quite impossible to say whether the blows hurt it or not. + + `Oh, PLEASE mind what you're doing!' cried Alice, jumping up +and down in an agony of terror. `Oh, there goes his PRECIOUS +nose'; as an unusually large saucepan flew close by it, and very +nearly carried it off. + + `If everybody minded their own business,' the Duchess said in a +hoarse growl, `the world would go round a deal faster than it +does.' + + `Which would NOT be an advantage,' said Alice, who felt very +glad to get an opportunity of showing off a little of her +knowledge. `Just think of what work it would make with the day +and night! You see the earth takes twenty-four hours to turn +round on its axis--' + + `Talking of axes,' said the Duchess, `chop off her head!' + + Alice glanced rather anxiously at the cook, to see if she meant +to take the hint; but the cook was busily stirring the soup, and +seemed not to be listening, so she went on again: `Twenty-four +hours, I THINK; or is it twelve? I--' + + `Oh, don't bother ME,' said the Duchess; `I never could abide +figures!' And with that she began nursing her child again, +singing a sort of lullaby to it as she did so, and giving it a +violent shake at the end of every line: + + `Speak roughly to your little boy, + And beat him when he sneezes: + He only does it to annoy, + Because he knows it teases.' + + CHORUS. + + (In which the cook and the baby joined):-- + + `Wow! wow! wow!' + + While the Duchess sang the second verse of the song, she kept +tossing the baby violently up and down, and the poor little thing +howled so, that Alice could hardly hear the words:-- + + `I speak severely to my boy, + I beat him when he sneezes; + For he can thoroughly enjoy + The pepper when he pleases!' + + CHORUS. + + `Wow! wow! wow!' + + `Here! you may nurse it a bit, if you like!' the Duchess said +to Alice, flinging the baby at her as she spoke. `I must go and +get ready to play croquet with the Queen,' and she hurried out of +the room. The cook threw a frying-pan after her as she went out, +but it just missed her. + + Alice caught the baby with some difficulty, as it was a queer- +shaped little creature, and held out its arms and legs in all +directions, `just like a star-fish,' thought Alice. The poor +little thing was snorting like a steam-engine when she caught it, +and kept doubling itself up and straightening itself out again, +so that altogether, for the first minute or two, it was as much +as she could do to hold it. + + As soon as she had made out the proper way of nursing it, +(which was to twist it up into a sort of knot, and then keep +tight hold of its right ear and left foot, so as to prevent its +undoing itself,) she carried it out into the open air. `IF I +don't take this child away with me,' thought Alice, `they're sure +to kill it in a day or two: wouldn't it be murder to leave it +behind?' She said the last words out loud, and the little thing +grunted in reply (it had left off sneezing by this time). `Don't +grunt,' said Alice; `that's not at all a proper way of expressing +yourself.' + + The baby grunted again, and Alice looked very anxiously into +its face to see what was the matter with it. There could be no +doubt that it had a VERY turn-up nose, much more like a snout +than a real nose; also its eyes were getting extremely small for +a baby: altogether Alice did not like the look of the thing at +all. `But perhaps it was only sobbing,' she thought, and looked +into its eyes again, to see if there were any tears. + + No, there were no tears. `If you're going to turn into a pig, +my dear,' said Alice, seriously, `I'll have nothing more to do +with you. Mind now!' The poor little thing sobbed again (or +grunted, it was impossible to say which), and they went on for +some while in silence. + + Alice was just beginning to think to herself, `Now, what am I +to do with this creature when I get it home?' when it grunted +again, so violently, that she looked down into its face in some +alarm. This time there could be NO mistake about it: it was +neither more nor less than a pig, and she felt that it would be +quite absurd for her to carry it further. + + So she set the little creature down, and felt quite relieved to +see it trot away quietly into the wood. `If it had grown up,' +she said to herself, `it would have made a dreadfully ugly child: +but it makes rather a handsome pig, I think.' And she began +thinking over other children she knew, who might do very well as +pigs, and was just saying to herself, `if one only knew the right +way to change them--' when she was a little startled by seeing +the Cheshire Cat sitting on a bough of a tree a few yards off. + + The Cat only grinned when it saw Alice. It looked good- +natured, she thought: still it had VERY long claws and a great +many teeth, so she felt that it ought to be treated with respect. + + `Cheshire Puss,' she began, rather timidly, as she did not at +all know whether it would like the name: however, it only +grinned a little wider. `Come, it's pleased so far,' thought +Alice, and she went on. `Would you tell me, please, which way I +ought to go from here?' + + `That depends a good deal on where you want to get to,' said +the Cat. + + `I don't much care where--' said Alice. + + `Then it doesn't matter which way you go,' said the Cat. + + `--so long as I get SOMEWHERE,' Alice added as an explanation. + + `Oh, you're sure to do that,' said the Cat, `if you only walk +long enough.' + + Alice felt that this could not be denied, so she tried another +question. `What sort of people live about here?' + + `In THAT direction,' the Cat said, waving its right paw round, +`lives a Hatter: and in THAT direction,' waving the other paw, +`lives a March Hare. Visit either you like: they're both mad.' + + `But I don't want to go among mad people,' Alice remarked. + + `Oh, you can't help that,' said the Cat: `we're all mad here. +I'm mad. You're mad.' + + `How do you know I'm mad?' said Alice. + + `You must be,' said the Cat, `or you wouldn't have come here.' + + Alice didn't think that proved it at all; however, she went on +`And how do you know that you're mad?' + + `To begin with,' said the Cat, `a dog's not mad. You grant +that?' + + `I suppose so,' said Alice. + + `Well, then,' the Cat went on, `you see, a dog growls when it's +angry, and wags its tail when it's pleased. Now I growl when I'm +pleased, and wag my tail when I'm angry. Therefore I'm mad.' + + `I call it purring, not growling,' said Alice. + + `Call it what you like,' said the Cat. `Do you play croquet +with the Queen to-day?' + + `I should like it very much,' said Alice, `but I haven't been +invited yet.' + + `You'll see me there,' said the Cat, and vanished. + + Alice was not much surprised at this, she was getting so used +to queer things happening. While she was looking at the place +where it had been, it suddenly appeared again. + + `By-the-bye, what became of the baby?' said the Cat. `I'd +nearly forgotten to ask.' + + `It turned into a pig,' Alice quietly said, just as if it had +come back in a natural way. + + `I thought it would,' said the Cat, and vanished again. + + Alice waited a little, half expecting to see it again, but it +did not appear, and after a minute or two she walked on in the +direction in which the March Hare was said to live. `I've seen +hatters before,' she said to herself; `the March Hare will be +much the most interesting, and perhaps as this is May it won't be +raving mad--at least not so mad as it was in March.' As she said +this, she looked up, and there was the Cat again, sitting on a +branch of a tree. + + `Did you say pig, or fig?' said the Cat. + + `I said pig,' replied Alice; `and I wish you wouldn't keep +appearing and vanishing so suddenly: you make one quite giddy.' + + `All right,' said the Cat; and this time it vanished quite +slowly, beginning with the end of the tail, and ending with the +grin, which remained some time after the rest of it had gone. + + `Well! I've often seen a cat without a grin,' thought Alice; +`but a grin without a cat! It's the most curious thing I ever +say in my life!' + + She had not gone much farther before she came in sight of the +house of the March Hare: she thought it must be the right house, +because the chimneys were shaped like ears and the roof was +thatched with fur. It was so large a house, that she did not +like to go nearer till she had nibbled some more of the lefthand +bit of mushroom, and raised herself to about two feet high: even +then she walked up towards it rather timidly, saying to herself +`Suppose it should be raving mad after all! I almost wish I'd +gone to see the Hatter instead!' + + + + CHAPTER VII + + A Mad Tea-Party + + + There was a table set out under a tree in front of the house, +and the March Hare and the Hatter were having tea at it: a +Dormouse was sitting between them, fast asleep, and the other two +were using it as a cushion, resting their elbows on it, and the +talking over its head. `Very uncomfortable for the Dormouse,' +thought Alice; `only, as it's asleep, I suppose it doesn't mind.' + + The table was a large one, but the three were all crowded +together at one corner of it: `No room! No room!' they cried +out when they saw Alice coming. `There's PLENTY of room!' said +Alice indignantly, and she sat down in a large arm-chair at one +end of the table. + + `Have some wine,' the March Hare said in an encouraging tone. + + Alice looked all round the table, but there was nothing on it +but tea. `I don't see any wine,' she remarked. + + `There isn't any,' said the March Hare. + + `Then it wasn't very civil of you to offer it,' said Alice +angrily. + + `It wasn't very civil of you to sit down without being +invited,' said the March Hare. + + `I didn't know it was YOUR table,' said Alice; `it's laid for a +great many more than three.' + + `Your hair wants cutting,' said the Hatter. He had been +looking at Alice for some time with great curiosity, and this was +his first speech. + + `You should learn not to make personal remarks,' Alice said +with some severity; `it's very rude.' + + The Hatter opened his eyes very wide on hearing this; but all +he SAID was, `Why is a raven like a writing-desk?' + + `Come, we shall have some fun now!' thought Alice. `I'm glad +they've begun asking riddles.--I believe I can guess that,' she +added aloud. + + `Do you mean that you think you can find out the answer to it?' +said the March Hare. + + `Exactly so,' said Alice. + + `Then you should say what you mean,' the March Hare went on. + + `I do,' Alice hastily replied; `at least--at least I mean what +I say--that's the same thing, you know.' + + `Not the same thing a bit!' said the Hatter. `You might just +as well say that "I see what I eat" is the same thing as "I eat +what I see"!' + + `You might just as well say,' added the March Hare, `that "I +like what I get" is the same thing as "I get what I like"!' + + `You might just as well say,' added the Dormouse, who seemed to +be talking in his sleep, `that "I breathe when I sleep" is the +same thing as "I sleep when I breathe"!' + + `It IS the same thing with you,' said the Hatter, and here the +conversation dropped, and the party sat silent for a minute, +while Alice thought over all she could remember about ravens and +writing-desks, which wasn't much. + + The Hatter was the first to break the silence. `What day of +the month is it?' he said, turning to Alice: he had taken his +watch out of his pocket, and was looking at it uneasily, shaking +it every now and then, and holding it to his ear. + + Alice considered a little, and then said `The fourth.' + + `Two days wrong!' sighed the Hatter. `I told you butter +wouldn't suit the works!' he added looking angrily at the March +Hare. + + `It was the BEST butter,' the March Hare meekly replied. + + `Yes, but some crumbs must have got in as well,' the Hatter +grumbled: `you shouldn't have put it in with the bread-knife.' + + The March Hare took the watch and looked at it gloomily: then +he dipped it into his cup of tea, and looked at it again: but he +could think of nothing better to say than his first remark, `It +was the BEST butter, you know.' + + Alice had been looking over his shoulder with some curiosity. +`What a funny watch!' she remarked. `It tells the day of the +month, and doesn't tell what o'clock it is!' + + `Why should it?' muttered the Hatter. `Does YOUR watch tell +you what year it is?' + + `Of course not,' Alice replied very readily: `but that's +because it stays the same year for such a long time together.' + + `Which is just the case with MINE,' said the Hatter. + + Alice felt dreadfully puzzled. The Hatter's remark seemed to +have no sort of meaning in it, and yet it was certainly English. +`I don't quite understand you,' she said, as politely as she +could. + + `The Dormouse is asleep again,' said the Hatter, and he poured +a little hot tea upon its nose. + + The Dormouse shook its head impatiently, and said, without +opening its eyes, `Of course, of course; just what I was going to +remark myself.' + + `Have you guessed the riddle yet?' the Hatter said, turning to +Alice again. + + `No, I give it up,' Alice replied: `what's the answer?' + + `I haven't the slightest idea,' said the Hatter. + + `Nor I,' said the March Hare. + + Alice sighed wearily. `I think you might do something better +with the time,' she said, `than waste it in asking riddles that +have no answers.' + + `If you knew Time as well as I do,' said the Hatter, `you +wouldn't talk about wasting IT. It's HIM.' + + `I don't know what you mean,' said Alice. + + `Of course you don't!' the Hatter said, tossing his head +contemptuously. `I dare say you never even spoke to Time!' + + `Perhaps not,' Alice cautiously replied: `but I know I have to +beat time when I learn music.' + + `Ah! that accounts for it,' said the Hatter. `He won't stand +beating. Now, if you only kept on good terms with him, he'd do +almost anything you liked with the clock. For instance, suppose +it were nine o'clock in the morning, just time to begin lessons: +you'd only have to whisper a hint to Time, and round goes the +clock in a twinkling! Half-past one, time for dinner!' + + (`I only wish it was,' the March Hare said to itself in a +whisper.) + + `That would be grand, certainly,' said Alice thoughtfully: +`but then--I shouldn't be hungry for it, you know.' + + `Not at first, perhaps,' said the Hatter: `but you could keep +it to half-past one as long as you liked.' + + `Is that the way YOU manage?' Alice asked. + + The Hatter shook his head mournfully. `Not I!' he replied. +`We quarrelled last March--just before HE went mad, you know--' +(pointing with his tea spoon at the March Hare,) `--it was at the +great concert given by the Queen of Hearts, and I had to sing + + "Twinkle, twinkle, little bat! + How I wonder what you're at!" + +You know the song, perhaps?' + + `I've heard something like it,' said Alice. + + `It goes on, you know,' the Hatter continued, `in this way:-- + + "Up above the world you fly, + Like a tea-tray in the sky. + Twinkle, twinkle--"' + +Here the Dormouse shook itself, and began singing in its sleep +`Twinkle, twinkle, twinkle, twinkle--' and went on so long that +they had to pinch it to make it stop. + + `Well, I'd hardly finished the first verse,' said the Hatter, +`when the Queen jumped up and bawled out, "He's murdering the +time! Off with his head!"' + + `How dreadfully savage!' exclaimed Alice. + + `And ever since that,' the Hatter went on in a mournful tone, +`he won't do a thing I ask! It's always six o'clock now.' + + A bright idea came into Alice's head. `Is that the reason so +many tea-things are put out here?' she asked. + + `Yes, that's it,' said the Hatter with a sigh: `it's always +tea-time, and we've no time to wash the things between whiles.' + + `Then you keep moving round, I suppose?' said Alice. + + `Exactly so,' said the Hatter: `as the things get used up.' + + `But what happens when you come to the beginning again?' Alice +ventured to ask. + + `Suppose we change the subject,' the March Hare interrupted, +yawning. `I'm getting tired of this. I vote the young lady +tells us a story.' + + `I'm afraid I don't know one,' said Alice, rather alarmed at +the proposal. + + `Then the Dormouse shall!' they both cried. `Wake up, +Dormouse!' And they pinched it on both sides at once. + + The Dormouse slowly opened his eyes. `I wasn't asleep,' he +said in a hoarse, feeble voice: `I heard every word you fellows +were saying.' + + `Tell us a story!' said the March Hare. + + `Yes, please do!' pleaded Alice. + + `And be quick about it,' added the Hatter, `or you'll be asleep +again before it's done.' + + `Once upon a time there were three little sisters,' the +Dormouse began in a great hurry; `and their names were Elsie, +Lacie, and Tillie; and they lived at the bottom of a well--' + + `What did they live on?' said Alice, who always took a great +interest in questions of eating and drinking. + + `They lived on treacle,' said the Dormouse, after thinking a +minute or two. + + `They couldn't have done that, you know,' Alice gently +remarked; `they'd have been ill.' + + `So they were,' said the Dormouse; `VERY ill.' + + Alice tried to fancy to herself what such an extraordinary ways +of living would be like, but it puzzled her too much, so she went +on: `But why did they live at the bottom of a well?' + + `Take some more tea,' the March Hare said to Alice, very +earnestly. + + `I've had nothing yet,' Alice replied in an offended tone, `so +I can't take more.' + + `You mean you can't take LESS,' said the Hatter: `it's very +easy to take MORE than nothing.' + + `Nobody asked YOUR opinion,' said Alice. + + `Who's making personal remarks now?' the Hatter asked +triumphantly. + + Alice did not quite know what to say to this: so she helped +herself to some tea and bread-and-butter, and then turned to the +Dormouse, and repeated her question. `Why did they live at the +bottom of a well?' + + The Dormouse again took a minute or two to think about it, and +then said, `It was a treacle-well.' + + `There's no such thing!' Alice was beginning very angrily, but +the Hatter and the March Hare went `Sh! sh!' and the Dormouse +sulkily remarked, `If you can't be civil, you'd better finish the +story for yourself.' + + `No, please go on!' Alice said very humbly; `I won't interrupt +again. I dare say there may be ONE.' + + `One, indeed!' said the Dormouse indignantly. However, he +consented to go on. `And so these three little sisters--they +were learning to draw, you know--' + + `What did they draw?' said Alice, quite forgetting her promise. + + `Treacle,' said the Dormouse, without considering at all this +time. + + `I want a clean cup,' interrupted the Hatter: `let's all move +one place on.' + + He moved on as he spoke, and the Dormouse followed him: the +March Hare moved into the Dormouse's place, and Alice rather +unwillingly took the place of the March Hare. The Hatter was the +only one who got any advantage from the change: and Alice was a +good deal worse off than before, as the March Hare had just upset +the milk-jug into his plate. + + Alice did not wish to offend the Dormouse again, so she began +very cautiously: `But I don't understand. Where did they draw +the treacle from?' + + `You can draw water out of a water-well,' said the Hatter; `so +I should think you could draw treacle out of a treacle-well--eh, +stupid?' + + `But they were IN the well,' Alice said to the Dormouse, not +choosing to notice this last remark. + + `Of course they were', said the Dormouse; `--well in.' + + This answer so confused poor Alice, that she let the Dormouse +go on for some time without interrupting it. + + `They were learning to draw,' the Dormouse went on, yawning and +rubbing its eyes, for it was getting very sleepy; `and they drew +all manner of things--everything that begins with an M--' + + `Why with an M?' said Alice. + + `Why not?' said the March Hare. + + Alice was silent. + + The Dormouse had closed its eyes by this time, and was going +off into a doze; but, on being pinched by the Hatter, it woke up +again with a little shriek, and went on: `--that begins with an +M, such as mouse-traps, and the moon, and memory, and muchness-- +you know you say things are "much of a muchness"--did you ever +see such a thing as a drawing of a muchness?' + + `Really, now you ask me,' said Alice, very much confused, `I +don't think--' + + `Then you shouldn't talk,' said the Hatter. + + This piece of rudeness was more than Alice could bear: she got +up in great disgust, and walked off; the Dormouse fell asleep +instantly, and neither of the others took the least notice of her +going, though she looked back once or twice, half hoping that +they would call after her: the last time she saw them, they were +trying to put the Dormouse into the teapot. + + `At any rate I'll never go THERE again!' said Alice as she +picked her way through the wood. `It's the stupidest tea-party I +ever was at in all my life!' + + Just as she said this, she noticed that one of the trees had a +door leading right into it. `That's very curious!' she thought. +`But everything's curious today. I think I may as well go in at +once.' And in she went. + + Once more she found herself in the long hall, and close to the +little glass table. `Now, I'll manage better this time,' she +said to herself, and began by taking the little golden key, and +unlocking the door that led into the garden. Then she went to +work nibbling at the mushroom (she had kept a piece of it in her +pocked) till she was about a foot high: then she walked down the +little passage: and THEN--she found herself at last in the +beautiful garden, among the bright flower-beds and the cool +fountains. + + + + CHAPTER VIII + + The Queen's Croquet-Ground + + + A large rose-tree stood near the entrance of the garden: the +roses growing on it were white, but there were three gardeners at +it, busily painting them red. Alice thought this a very curious +thing, and she went nearer to watch them, and just as she came up +to them she heard one of them say, `Look out now, Five! Don't go +splashing paint over me like that!' + + `I couldn't help it,' said Five, in a sulky tone; `Seven jogged +my elbow.' + + On which Seven looked up and said, `That's right, Five! Always +lay the blame on others!' + + `YOU'D better not talk!' said Five. `I heard the Queen say only +yesterday you deserved to be beheaded!' + + `What for?' said the one who had spoken first. + + `That's none of YOUR business, Two!' said Seven. + + `Yes, it IS his business!' said Five, `and I'll tell him--it +was for bringing the cook tulip-roots instead of onions.' + + Seven flung down his brush, and had just begun `Well, of all +the unjust things--' when his eye chanced to fall upon Alice, as +she stood watching them, and he checked himself suddenly: the +others looked round also, and all of them bowed low. + + `Would you tell me,' said Alice, a little timidly, `why you are +painting those roses?' + + Five and Seven said nothing, but looked at Two. Two began in a +low voice, `Why the fact is, you see, Miss, this here ought to +have been a RED rose-tree, and we put a white one in by mistake; +and if the Queen was to find it out, we should all have our heads +cut off, you know. So you see, Miss, we're doing our best, afore +she comes, to--' At this moment Five, who had been anxiously +looking across the garden, called out `The Queen! The Queen!' +and the three gardeners instantly threw themselves flat upon +their faces. There was a sound of many footsteps, and Alice +looked round, eager to see the Queen. + + First came ten soldiers carrying clubs; these were all shaped +like the three gardeners, oblong and flat, with their hands and +feet at the corners: next the ten courtiers; these were +ornamented all over with diamonds, and walked two and two, as the +soldiers did. After these came the royal children; there were +ten of them, and the little dears came jumping merrily along hand +in hand, in couples: they were all ornamented with hearts. Next +came the guests, mostly Kings and Queens, and among them Alice +recognised the White Rabbit: it was talking in a hurried nervous +manner, smiling at everything that was said, and went by without +noticing her. Then followed the Knave of Hearts, carrying the +King's crown on a crimson velvet cushion; and, last of all this +grand procession, came THE KING AND QUEEN OF HEARTS. + + Alice was rather doubtful whether she ought not to lie down on +her face like the three gardeners, but she could not remember +every having heard of such a rule at processions; `and besides, +what would be the use of a procession,' thought she, `if people +had all to lie down upon their faces, so that they couldn't see +it?' So she stood still where she was, and waited. + + When the procession came opposite to Alice, they all stopped +and looked at her, and the Queen said severely `Who is this?' +She said it to the Knave of Hearts, who only bowed and smiled in +reply. + + `Idiot!' said the Queen, tossing her head impatiently; and, +turning to Alice, she went on, `What's your name, child?' + + `My name is Alice, so please your Majesty,' said Alice very +politely; but she added, to herself, `Why, they're only a pack of +cards, after all. I needn't be afraid of them!' + + `And who are THESE?' said the Queen, pointing to the three +gardeners who were lying round the rosetree; for, you see, as +they were lying on their faces, and the pattern on their backs +was the same as the rest of the pack, she could not tell whether +they were gardeners, or soldiers, or courtiers, or three of her +own children. + + `How should I know?' said Alice, surprised at her own courage. +`It's no business of MINE.' + + The Queen turned crimson with fury, and, after glaring at her +for a moment like a wild beast, screamed `Off with her head! +Off--' + + `Nonsense!' said Alice, very loudly and decidedly, and the +Queen was silent. + + The King laid his hand upon her arm, and timidly said +`Consider, my dear: she is only a child!' + + The Queen turned angrily away from him, and said to the Knave +`Turn them over!' + + The Knave did so, very carefully, with one foot. + + `Get up!' said the Queen, in a shrill, loud voice, and the +three gardeners instantly jumped up, and began bowing to the +King, the Queen, the royal children, and everybody else. + + `Leave off that!' screamed the Queen. `You make me giddy.' +And then, turning to the rose-tree, she went on, `What HAVE you +been doing here?' + + `May it please your Majesty,' said Two, in a very humble tone, +going down on one knee as he spoke, `we were trying--' + + `I see!' said the Queen, who had meanwhile been examining the +roses. `Off with their heads!' and the procession moved on, +three of the soldiers remaining behind to execute the unfortunate +gardeners, who ran to Alice for protection. + + `You shan't be beheaded!' said Alice, and she put them into a +large flower-pot that stood near. The three soldiers wandered +about for a minute or two, looking for them, and then quietly +marched off after the others. + + `Are their heads off?' shouted the Queen. + + `Their heads are gone, if it please your Majesty!' the soldiers +shouted in reply. + + `That's right!' shouted the Queen. `Can you play croquet?' + + The soldiers were silent, and looked at Alice, as the question +was evidently meant for her. + + `Yes!' shouted Alice. + + `Come on, then!' roared the Queen, and Alice joined the +procession, wondering very much what would happen next. + + `It's--it's a very fine day!' said a timid voice at her side. +She was walking by the White Rabbit, who was peeping anxiously +into her face. + + `Very,' said Alice: `--where's the Duchess?' + + `Hush! Hush!' said the Rabbit in a low, hurried tone. He +looked anxiously over his shoulder as he spoke, and then raised +himself upon tiptoe, put his mouth close to her ear, and +whispered `She's under sentence of execution.' + + `What for?' said Alice. + + `Did you say "What a pity!"?' the Rabbit asked. + + `No, I didn't,' said Alice: `I don't think it's at all a pity. +I said "What for?"' + + `She boxed the Queen's ears--' the Rabbit began. Alice gave a +little scream of laughter. `Oh, hush!' the Rabbit whispered in a +frightened tone. `The Queen will hear you! You see, she came +rather late, and the Queen said--' + + `Get to your places!' shouted the Queen in a voice of thunder, +and people began running about in all directions, tumbling up +against each other; however, they got settled down in a minute or +two, and the game began. Alice thought she had never seen such a +curious croquet-ground in her life; it was all ridges and +furrows; the balls were live hedgehogs, the mallets live +flamingoes, and the soldiers had to double themselves up and to +stand on their hands and feet, to make the arches. + + The chief difficulty Alice found at first was in managing her +flamingo: she succeeded in getting its body tucked away, +comfortably enough, under her arm, with its legs hanging down, +but generally, just as she had got its neck nicely straightened +out, and was going to give the hedgehog a blow with its head, it +WOULD twist itself round and look up in her face, with such a +puzzled expression that she could not help bursting out laughing: +and when she had got its head down, and was going to begin again, +it was very provoking to find that the hedgehog had unrolled +itself, and was in the act of crawling away: besides all this, +there was generally a ridge or furrow in the way wherever she +wanted to send the hedgehog to, and, as the doubled-up soldiers +were always getting up and walking off to other parts of the +ground, Alice soon came to the conclusion that it was a very +difficult game indeed. + + The players all played at once without waiting for turns, +quarrelling all the while, and fighting for the hedgehogs; and in +a very short time the Queen was in a furious passion, and went +stamping about, and shouting `Off with his head!' or `Off with +her head!' about once in a minute. + + Alice began to feel very uneasy: to be sure, she had not as +yet had any dispute with the Queen, but she knew that it might +happen any minute, `and then,' thought she, `what would become of +me? They're dreadfully fond of beheading people here; the great +wonder is, that there's any one left alive!' + + She was looking about for some way of escape, and wondering +whether she could get away without being seen, when she noticed a +curious appearance in the air: it puzzled her very much at +first, but, after watching it a minute or two, she made it out to +be a grin, and she said to herself `It's the Cheshire Cat: now I +shall have somebody to talk to.' + + `How are you getting on?' said the Cat, as soon as there was +mouth enough for it to speak with. + + Alice waited till the eyes appeared, and then nodded. `It's no +use speaking to it,' she thought, `till its ears have come, or at +least one of them.' In another minute the whole head appeared, +and then Alice put down her flamingo, and began an account of the +game, feeling very glad she had someone to listen to her. The +Cat seemed to think that there was enough of it now in sight, and +no more of it appeared. + + `I don't think they play at all fairly,' Alice began, in rather +a complaining tone, `and they all quarrel so dreadfully one can't +hear oneself speak--and they don't seem to have any rules in +particular; at least, if there are, nobody attends to them--and +you've no idea how confusing it is all the things being alive; +for instance, there's the arch I've got to go through next +walking about at the other end of the ground--and I should have +croqueted the Queen's hedgehog just now, only it ran away when it +saw mine coming!' + + `How do you like the Queen?' said the Cat in a low voice. + + `Not at all,' said Alice: `she's so extremely--' Just then +she noticed that the Queen was close behind her, listening: so +she went on, `--likely to win, that it's hardly worth while +finishing the game.' + + The Queen smiled and passed on. + + `Who ARE you talking to?' said the King, going up to Alice, and +looking at the Cat's head with great curiosity. + + `It's a friend of mine--a Cheshire Cat,' said Alice: `allow me +to introduce it.' + + `I don't like the look of it at all,' said the King: `however, +it may kiss my hand if it likes.' + + `I'd rather not,' the Cat remarked. + + `Don't be impertinent,' said the King, `and don't look at me +like that!' He got behind Alice as he spoke. + + `A cat may look at a king,' said Alice. `I've read that in +some book, but I don't remember where.' + + `Well, it must be removed,' said the King very decidedly, and +he called the Queen, who was passing at the moment, `My dear! I +wish you would have this cat removed!' + + The Queen had only one way of settling all difficulties, great +or small. `Off with his head!' she said, without even looking +round. + + `I'll fetch the executioner myself,' said the King eagerly, and +he hurried off. + + Alice thought she might as well go back, and see how the game +was going on, as she heard the Queen's voice in the distance, +screaming with passion. She had already heard her sentence three +of the players to be executed for having missed their turns, and +she did not like the look of things at all, as the game was in +such confusion that she never knew whether it was her turn or +not. So she went in search of her hedgehog. + + The hedgehog was engaged in a fight with another hedgehog, +which seemed to Alice an excellent opportunity for croqueting one +of them with the other: the only difficulty was, that her +flamingo was gone across to the other side of the garden, where +Alice could see it trying in a helpless sort of way to fly up +into a tree. + + By the time she had caught the flamingo and brought it back, +the fight was over, and both the hedgehogs were out of sight: +`but it doesn't matter much,' thought Alice, `as all the arches +are gone from this side of the ground.' So she tucked it away +under her arm, that it might not escape again, and went back for +a little more conversation with her friend. + + When she got back to the Cheshire Cat, she was surprised to +find quite a large crowd collected round it: there was a dispute +going on between the executioner, the King, and the Queen, who +were all talking at once, while all the rest were quite silent, +and looked very uncomfortable. + + The moment Alice appeared, she was appealed to by all three to +settle the question, and they repeated their arguments to her, +though, as they all spoke at once, she found it very hard indeed +to make out exactly what they said. + + The executioner's argument was, that you couldn't cut off a +head unless there was a body to cut it off from: that he had +never had to do such a thing before, and he wasn't going to begin +at HIS time of life. + + The King's argument was, that anything that had a head could be +beheaded, and that you weren't to talk nonsense. + + The Queen's argument was, that if something wasn't done about +it in less than no time she'd have everybody executed, all round. +(It was this last remark that had made the whole party look so +grave and anxious.) + + Alice could think of nothing else to say but `It belongs to the +Duchess: you'd better ask HER about it.' + + `She's in prison,' the Queen said to the executioner: `fetch +her here.' And the executioner went off like an arrow. + + The Cat's head began fading away the moment he was gone, and, +by the time he had come back with the Dutchess, it had entirely +disappeared; so the King and the executioner ran wildly up and +down looking for it, while the rest of the party went back to the game. + + + + CHAPTER IX + + The Mock Turtle's Story + + + `You can't think how glad I am to see you again, you dear old +thing!' said the Duchess, as she tucked her arm affectionately +into Alice's, and they walked off together. + + Alice was very glad to find her in such a pleasant temper, and +thought to herself that perhaps it was only the pepper that had +made her so savage when they met in the kitchen. + + `When I'M a Duchess,' she said to herself, (not in a very +hopeful tone though), `I won't have any pepper in my kitchen AT +ALL. Soup does very well without--Maybe it's always pepper that +makes people hot-tempered,' she went on, very much pleased at +having found out a new kind of rule, `and vinegar that makes them +sour--and camomile that makes them bitter--and--and barley-sugar +and such things that make children sweet-tempered. I only wish +people knew that: then they wouldn't be so stingy about it, you +know--' + + She had quite forgotten the Duchess by this time, and was a +little startled when she heard her voice close to her ear. +`You're thinking about something, my dear, and that makes you +forget to talk. I can't tell you just now what the moral of that +is, but I shall remember it in a bit.' + + `Perhaps it hasn't one,' Alice ventured to remark. + + `Tut, tut, child!' said the Duchess. `Everything's got a +moral, if only you can find it.' And she squeezed herself up +closer to Alice's side as she spoke. + + Alice did not much like keeping so close to her: first, +because the Duchess was VERY ugly; and secondly, because she was +exactly the right height to rest her chin upon Alice's shoulder, +and it was an uncomfortably sharp chin. However, she did not +like to be rude, so she bore it as well as she could. + + `The game's going on rather better now,' she said, by way of +keeping up the conversation a little. + + `'Tis so,' said the Duchess: `and the moral of that is--"Oh, +'tis love, 'tis love, that makes the world go round!"' + + `Somebody said,' Alice whispered, `that it's done by everybody +minding their own business!' + + `Ah, well! It means much the same thing,' said the Duchess, +digging her sharp little chin into Alice's shoulder as she added, +`and the moral of THAT is--"Take care of the sense, and the +sounds will take care of themselves."' + + `How fond she is of finding morals in things!' Alice thought to +herself. + + `I dare say you're wondering why I don't put my arm round your +waist,' the Duchess said after a pause: `the reason is, that I'm +doubtful about the temper of your flamingo. Shall I try the +experiment?' + + `HE might bite,' Alice cautiously replied, not feeling at all +anxious to have the experiment tried. + + `Very true,' said the Duchess: `flamingoes and mustard both +bite. And the moral of that is--"Birds of a feather flock +together."' + + `Only mustard isn't a bird,' Alice remarked. + + `Right, as usual,' said the Duchess: `what a clear way you +have of putting things!' + + `It's a mineral, I THINK,' said Alice. + + `Of course it is,' said the Duchess, who seemed ready to agree +to everything that Alice said; `there's a large mustard-mine near +here. And the moral of that is--"The more there is of mine, the +less there is of yours."' + + `Oh, I know!' exclaimed Alice, who had not attended to this +last remark, `it's a vegetable. It doesn't look like one, but it +is.' + + `I quite agree with you,' said the Duchess; `and the moral of +that is--"Be what you would seem to be"--or if you'd like it put +more simply--"Never imagine yourself not to be otherwise than +what it might appear to others that what you were or might have +been was not otherwise than what you had been would have appeared +to them to be otherwise."' + + `I think I should understand that better,' Alice said very +politely, `if I had it written down: but I can't quite follow it +as you say it.' + + `That's nothing to what I could say if I chose,' the Duchess +replied, in a pleased tone. + + `Pray don't trouble yourself to say it any longer than that,' +said Alice. + + `Oh, don't talk about trouble!' said the Duchess. `I make you +a present of everything I've said as yet.' + + `A cheap sort of present!' thought Alice. `I'm glad they don't +give birthday presents like that!' But she did not venture to +say it out loud. + + `Thinking again?' the Duchess asked, with another dig of her +sharp little chin. + + `I've a right to think,' said Alice sharply, for she was +beginning to feel a little worried. + + `Just about as much right,' said the Duchess, `as pigs have to +fly; and the m--' + + But here, to Alice's great surprise, the Duchess's voice died +away, even in the middle of her favourite word `moral,' and the +arm that was linked into hers began to tremble. Alice looked up, +and there stood the Queen in front of them, with her arms folded, +frowning like a thunderstorm. + + `A fine day, your Majesty!' the Duchess began in a low, weak +voice. + + `Now, I give you fair warning,' shouted the Queen, stamping on +the ground as she spoke; `either you or your head must be off, +and that in about half no time! Take your choice!' + + The Duchess took her choice, and was gone in a moment. + + `Let's go on with the game,' the Queen said to Alice; and Alice +was too much frightened to say a word, but slowly followed her +back to the croquet-ground. + + The other guests had taken advantage of the Queen's absence, +and were resting in the shade: however, the moment they saw her, +they hurried back to the game, the Queen merely remarking that a +moment's delay would cost them their lives. + + All the time they were playing the Queen never left off +quarrelling with the other players, and shouting `Off with his +head!' or `Off with her head!' Those whom she sentenced were +taken into custody by the soldiers, who of course had to leave +off being arches to do this, so that by the end of half an hour +or so there were no arches left, and all the players, except the +King, the Queen, and Alice, were in custody and under sentence of +execution. + + Then the Queen left off, quite out of breath, and said to +Alice, `Have you seen the Mock Turtle yet?' + + `No,' said Alice. `I don't even know what a Mock Turtle is.' + + `It's the thing Mock Turtle Soup is made from,' said the Queen. + + `I never saw one, or heard of one,' said Alice. + + `Come on, then,' said the Queen, `and he shall tell you his +history,' + + As they walked off together, Alice heard the King say in a low +voice, to the company generally, `You are all pardoned.' `Come, +THAT'S a good thing!' she said to herself, for she had felt quite +unhappy at the number of executions the Queen had ordered. + + They very soon came upon a Gryphon, lying fast asleep in the +sun. (IF you don't know what a Gryphon is, look at the picture.) +`Up, lazy thing!' said the Queen, `and take this young lady to +see the Mock Turtle, and to hear his history. I must go back and +see after some executions I have ordered'; and she walked off, +leaving Alice alone with the Gryphon. Alice did not quite like +the look of the creature, but on the whole she thought it would +be quite as safe to stay with it as to go after that savage +Queen: so she waited. + + The Gryphon sat up and rubbed its eyes: then it watched the +Queen till she was out of sight: then it chuckled. `What fun!' +said the Gryphon, half to itself, half to Alice. + + `What IS the fun?' said Alice. + + `Why, SHE,' said the Gryphon. `It's all her fancy, that: they +never executes nobody, you know. Come on!' + + `Everybody says "come on!" here,' thought Alice, as she went +slowly after it: `I never was so ordered about in all my life, +never!' + + They had not gone far before they saw the Mock Turtle in the +distance, sitting sad and lonely on a little ledge of rock, and, +as they came nearer, Alice could hear him sighing as if his heart +would break. She pitied him deeply. `What is his sorrow?' she +asked the Gryphon, and the Gryphon answered, very nearly in the +same words as before, `It's all his fancy, that: he hasn't got +no sorrow, you know. Come on!' + + So they went up to the Mock Turtle, who looked at them with +large eyes full of tears, but said nothing. + + `This here young lady,' said the Gryphon, `she wants for to +know your history, she do.' + + `I'll tell it her,' said the Mock Turtle in a deep, hollow +tone: `sit down, both of you, and don't speak a word till I've +finished.' + + So they sat down, and nobody spoke for some minutes. Alice +thought to herself, `I don't see how he can EVEN finish, if he +doesn't begin.' But she waited patiently. + + `Once,' said the Mock Turtle at last, with a deep sigh, `I was +a real Turtle.' + + These words were followed by a very long silence, broken only +by an occasional exclamation of `Hjckrrh!' from the Gryphon, and +the constant heavy sobbing of the Mock Turtle. Alice was very +nearly getting up and saying, `Thank you, sir, for your +interesting story,' but she could not help thinking there MUST be +more to come, so she sat still and said nothing. + + `When we were little,' the Mock Turtle went on at last, more +calmly, though still sobbing a little now and then, `we went to +school in the sea. The master was an old Turtle--we used to call +him Tortoise--' + + `Why did you call him Tortoise, if he wasn't one?' Alice asked. + + `We called him Tortoise because he taught us,' said the Mock +Turtle angrily: `really you are very dull!' + + `You ought to be ashamed of yourself for asking such a simple +question,' added the Gryphon; and then they both sat silent and +looked at poor Alice, who felt ready to sink into the earth. At +last the Gryphon said to the Mock Turtle, `Drive on, old fellow! +Don't be all day about it!' and he went on in these words: + + `Yes, we went to school in the sea, though you mayn't believe +it--' + + `I never said I didn't!' interrupted Alice. + + `You did,' said the Mock Turtle. + + `Hold your tongue!' added the Gryphon, before Alice could speak +again. The Mock Turtle went on. + + `We had the best of educations--in fact, we went to school +every day--' + + `I'VE been to a day-school, too,' said Alice; `you needn't be +so proud as all that.' + + `With extras?' asked the Mock Turtle a little anxiously. + + `Yes,' said Alice, `we learned French and music.' + + `And washing?' said the Mock Turtle. + + `Certainly not!' said Alice indignantly. + + `Ah! then yours wasn't a really good school,' said the Mock +Turtle in a tone of great relief. `Now at OURS they had at the +end of the bill, "French, music, AND WASHING--extra."' + + `You couldn't have wanted it much,' said Alice; `living at the +bottom of the sea.' + + `I couldn't afford to learn it.' said the Mock Turtle with a +sigh. `I only took the regular course.' + + `What was that?' inquired Alice. + + `Reeling and Writhing, of course, to begin with,' the Mock +Turtle replied; `and then the different branches of Arithmetic-- +Ambition, Distraction, Uglification, and Derision.' + + `I never heard of "Uglification,"' Alice ventured to say. `What +is it?' + + The Gryphon lifted up both its paws in surprise. `What! Never +heard of uglifying!' it exclaimed. `You know what to beautify +is, I suppose?' + + `Yes,' said Alice doubtfully: `it means--to--make--anything-- +prettier.' + + `Well, then,' the Gryphon went on, `if you don't know what to +uglify is, you ARE a simpleton.' + + Alice did not feel encouraged to ask any more questions about +it, so she turned to the Mock Turtle, and said `What else had you +to learn?' + + `Well, there was Mystery,' the Mock Turtle replied, counting +off the subjects on his flappers, `--Mystery, ancient and modern, +with Seaography: then Drawling--the Drawling-master was an old +conger-eel, that used to come once a week: HE taught us +Drawling, Stretching, and Fainting in Coils.' + + `What was THAT like?' said Alice. + + `Well, I can't show it you myself,' the Mock Turtle said: `I'm +too stiff. And the Gryphon never learnt it.' + + `Hadn't time,' said the Gryphon: `I went to the Classics +master, though. He was an old crab, HE was.' + + `I never went to him,' the Mock Turtle said with a sigh: `he +taught Laughing and Grief, they used to say.' + + `So he did, so he did,' said the Gryphon, sighing in his turn; +and both creatures hid their faces in their paws. + + `And how many hours a day did you do lessons?' said Alice, in a +hurry to change the subject. + + `Ten hours the first day,' said the Mock Turtle: `nine the +next, and so on.' + + `What a curious plan!' exclaimed Alice. + + `That's the reason they're called lessons,' the Gryphon +remarked: `because they lessen from day to day.' + + This was quite a new idea to Alice, and she thought it over a +little before she made her next remark. `Then the eleventh day +must have been a holiday?' + + `Of course it was,' said the Mock Turtle. + + `And how did you manage on the twelfth?' Alice went on eagerly. + + `That's enough about lessons,' the Gryphon interrupted in a +very decided tone: `tell her something about the games now.' + + + + CHAPTER X + + The Lobster Quadrille + + + The Mock Turtle sighed deeply, and drew the back of one flapper +across his eyes. He looked at Alice, and tried to speak, but for +a minute or two sobs choked his voice. `Same as if he had a bone +in his throat,' said the Gryphon: and it set to work shaking him +and punching him in the back. At last the Mock Turtle recovered +his voice, and, with tears running down his cheeks, he went on +again:-- + + `You may not have lived much under the sea--' (`I haven't,' +said Alice)--`and perhaps you were never even introduced to a lobster--' +(Alice began to say `I once tasted--' but checked herself hastily, +and said `No, never') `--so you can have no idea what a delightful +thing a Lobster Quadrille is!' + + `No, indeed,' said Alice. `What sort of a dance is it?' + + `Why,' said the Gryphon, `you first form into a line along the +sea-shore--' + + `Two lines!' cried the Mock Turtle. `Seals, turtles, salmon, +and so on; then, when you've cleared all the jelly-fish out of +the way--' + + `THAT generally takes some time,' interrupted the Gryphon. + + `--you advance twice--' + + `Each with a lobster as a partner!' cried the Gryphon. + + `Of course,' the Mock Turtle said: `advance twice, set to +partners--' + + `--change lobsters, and retire in same order,' continued the +Gryphon. + + `Then, you know,' the Mock Turtle went on, `you throw the--' + + `The lobsters!' shouted the Gryphon, with a bound into the air. + + `--as far out to sea as you can--' + + `Swim after them!' screamed the Gryphon. + + `Turn a somersault in the sea!' cried the Mock Turtle, +capering wildly about. + + `Back to land again, and that's all the first figure,' said the +Mock Turtle, suddenly dropping his voice; and the two creatures, +who had been jumping about like mad things all this time, sat +down again very sadly and quietly, and looked at Alice. + + `It must be a very pretty dance,' said Alice timidly. + + `Would you like to see a little of it?' said the Mock Turtle. + + `Very much indeed,' said Alice. + + `Come, let's try the first figure!' said the Mock Turtle to the +Gryphon. `We can do without lobsters, you know. Which shall +sing?' + + `Oh, YOU sing,' said the Gryphon. `I've forgotten the words.' + + So they began solemnly dancing round and round Alice, every now +and then treading on her toes when they passed too close, and +waving their forepaws to mark the time, while the Mock Turtle +sang this, very slowly and sadly:-- + + +`"Will you walk a little faster?" said a whiting to a snail. +"There's a porpoise close behind us, and he's treading on my + tail. +See how eagerly the lobsters and the turtles all advance! +They are waiting on the shingle--will you come and join the +dance? + +Will you, won't you, will you, won't you, will you join the +dance? +Will you, won't you, will you, won't you, won't you join the +dance? + + +"You can really have no notion how delightful it will be +When they take us up and throw us, with the lobsters, out to + sea!" +But the snail replied "Too far, too far!" and gave a look + askance-- +Said he thanked the whiting kindly, but he would not join the + dance. + Would not, could not, would not, could not, would not join + the dance. + Would not, could not, would not, could not, could not join + the dance. + +`"What matters it how far we go?" his scaly friend replied. +"There is another shore, you know, upon the other side. +The further off from England the nearer is to France-- +Then turn not pale, beloved snail, but come and join the dance. + + Will you, won't you, will you, won't you, will you join the + dance? + Will you, won't you, will you, won't you, won't you join the + dance?"' + + + + `Thank you, it's a very interesting dance to watch,' said +Alice, feeling very glad that it was over at last: `and I do so +like that curious song about the whiting!' + + `Oh, as to the whiting,' said the Mock Turtle, `they--you've +seen them, of course?' + + `Yes,' said Alice, `I've often seen them at dinn--' she +checked herself hastily. + + `I don't know where Dinn may be,' said the Mock Turtle, `but +if you've seen them so often, of course you know what they're +like.' + + `I believe so,' Alice replied thoughtfully. `They have their +tails in their mouths--and they're all over crumbs.' + + `You're wrong about the crumbs,' said the Mock Turtle: +`crumbs would all wash off in the sea. But they HAVE their tails +in their mouths; and the reason is--' here the Mock Turtle +yawned and shut his eyes.--`Tell her about the reason and all +that,' he said to the Gryphon. + + `The reason is,' said the Gryphon, `that they WOULD go with +the lobsters to the dance. So they got thrown out to sea. So +they had to fall a long way. So they got their tails fast in +their mouths. So they couldn't get them out again. That's all.' + + `Thank you,' said Alice, `it's very interesting. I never knew +so much about a whiting before.' + + `I can tell you more than that, if you like,' said the +Gryphon. `Do you know why it's called a whiting?' + + `I never thought about it,' said Alice. `Why?' + + `IT DOES THE BOOTS AND SHOES.' the Gryphon replied very +solemnly. + + Alice was thoroughly puzzled. `Does the boots and shoes!' she +repeated in a wondering tone. + + `Why, what are YOUR shoes done with?' said the Gryphon. `I +mean, what makes them so shiny?' + + Alice looked down at them, and considered a little before she +gave her answer. `They're done with blacking, I believe.' + + `Boots and shoes under the sea,' the Gryphon went on in a deep +voice, `are done with a whiting. Now you know.' + + `And what are they made of?' Alice asked in a tone of great +curiosity. + + `Soles and eels, of course,' the Gryphon replied rather +impatiently: `any shrimp could have told you that.' + + `If I'd been the whiting,' said Alice, whose thoughts were +still running on the song, `I'd have said to the porpoise, "Keep +back, please: we don't want YOU with us!"' + + `They were obliged to have him with them,' the Mock Turtle +said: `no wise fish would go anywhere without a porpoise.' + + `Wouldn't it really?' said Alice in a tone of great surprise. + + `Of course not,' said the Mock Turtle: `why, if a fish came +to ME, and told me he was going a journey, I should say "With +what porpoise?"' + + `Don't you mean "purpose"?' said Alice. + + `I mean what I say,' the Mock Turtle replied in an offended +tone. And the Gryphon added `Come, let's hear some of YOUR +adventures.' + + `I could tell you my adventures--beginning from this morning,' +said Alice a little timidly: `but it's no use going back to +yesterday, because I was a different person then.' + + `Explain all that,' said the Mock Turtle. + + `No, no! The adventures first,' said the Gryphon in an +impatient tone: `explanations take such a dreadful time.' + + So Alice began telling them her adventures from the time when +she first saw the White Rabbit. She was a little nervous about +it just at first, the two creatures got so close to her, one on +each side, and opened their eyes and mouths so VERY wide, but she +gained courage as she went on. Her listeners were perfectly +quiet till she got to the part about her repeating `YOU ARE OLD, +FATHER WILLIAM,' to the Caterpillar, and the words all coming +different, and then the Mock Turtle drew a long breath, and said +`That's very curious.' + + `It's all about as curious as it can be,' said the Gryphon. + + `It all came different!' the Mock Turtle repeated +thoughtfully. `I should like to hear her try and repeat +something now. Tell her to begin.' He looked at the Gryphon as +if he thought it had some kind of authority over Alice. + + `Stand up and repeat "'TIS THE VOICE OF THE SLUGGARD,"' said +the Gryphon. + + `How the creatures order one about, and make one repeat +lessons!' thought Alice; `I might as well be at school at once.' +However, she got up, and began to repeat it, but her head was so +full of the Lobster Quadrille, that she hardly knew what she was +saying, and the words came very queer indeed:-- + + `'Tis the voice of the Lobster; I heard him declare, + "You have baked me too brown, I must sugar my hair." + As a duck with its eyelids, so he with his nose + Trims his belt and his buttons, and turns out his toes.' + + [later editions continued as follows + When the sands are all dry, he is gay as a lark, + And will talk in contemptuous tones of the Shark, + But, when the tide rises and sharks are around, + His voice has a timid and tremulous sound.] + + `That's different from what I used to say when I was a child,' +said the Gryphon. + + `Well, I never heard it before,' said the Mock Turtle; `but it +sounds uncommon nonsense.' + + Alice said nothing; she had sat down with her face in her +hands, wondering if anything would EVER happen in a natural way +again. + + `I should like to have it explained,' said the Mock Turtle. + + `She can't explain it,' said the Gryphon hastily. `Go on with +the next verse.' + + `But about his toes?' the Mock Turtle persisted. `How COULD +he turn them out with his nose, you know?' + + `It's the first position in dancing.' Alice said; but was +dreadfully puzzled by the whole thing, and longed to change the +subject. + + `Go on with the next verse,' the Gryphon repeated impatiently: +`it begins "I passed by his garden."' + + Alice did not dare to disobey, though she felt sure it would +all come wrong, and she went on in a trembling voice:-- + + `I passed by his garden, and marked, with one eye, + How the Owl and the Panther were sharing a pie--' + + [later editions continued as follows + The Panther took pie-crust, and gravy, and meat, + While the Owl had the dish as its share of the treat. + When the pie was all finished, the Owl, as a boon, + Was kindly permitted to pocket the spoon: + While the Panther received knife and fork with a growl, + And concluded the banquet--] + + `What IS the use of repeating all that stuff,' the Mock Turtle +interrupted, `if you don't explain it as you go on? It's by far +the most confusing thing I ever heard!' + + `Yes, I think you'd better leave off,' said the Gryphon: and +Alice was only too glad to do so. + + `Shall we try another figure of the Lobster Quadrille?' the +Gryphon went on. `Or would you like the Mock Turtle to sing you +a song?' + + `Oh, a song, please, if the Mock Turtle would be so kind,' +Alice replied, so eagerly that the Gryphon said, in a rather +offended tone, `Hm! No accounting for tastes! Sing her "Turtle +Soup," will you, old fellow?' + + The Mock Turtle sighed deeply, and began, in a voice sometimes +choked with sobs, to sing this:-- + + + `Beautiful Soup, so rich and green, + Waiting in a hot tureen! + Who for such dainties would not stoop? + Soup of the evening, beautiful Soup! + Soup of the evening, beautiful Soup! + Beau--ootiful Soo--oop! + Beau--ootiful Soo--oop! + Soo--oop of the e--e--evening, + Beautiful, beautiful Soup! + + `Beautiful Soup! Who cares for fish, + Game, or any other dish? + Who would not give all else for two p + ennyworth only of beautiful Soup? + Pennyworth only of beautiful Soup? + Beau--ootiful Soo--oop! + Beau--ootiful Soo--oop! + Soo--oop of the e--e--evening, + Beautiful, beauti--FUL SOUP!' + + `Chorus again!' cried the Gryphon, and the Mock Turtle had +just begun to repeat it, when a cry of `The trial's beginning!' +was heard in the distance. + + `Come on!' cried the Gryphon, and, taking Alice by the hand, +it hurried off, without waiting for the end of the song. + + `What trial is it?' Alice panted as she ran; but the Gryphon +only answered `Come on!' and ran the faster, while more and more +faintly came, carried on the breeze that followed them, the +melancholy words:-- + + `Soo--oop of the e--e--evening, + Beautiful, beautiful Soup!' + + + + CHAPTER XI + + Who Stole the Tarts? + + + The King and Queen of Hearts were seated on their throne when +they arrived, with a great crowd assembled about them--all sorts +of little birds and beasts, as well as the whole pack of cards: +the Knave was standing before them, in chains, with a soldier on +each side to guard him; and near the King was the White Rabbit, +with a trumpet in one hand, and a scroll of parchment in the +other. In the very middle of the court was a table, with a large +dish of tarts upon it: they looked so good, that it made Alice +quite hungry to look at them--`I wish they'd get the trial done,' +she thought, `and hand round the refreshments!' But there seemed +to be no chance of this, so she began looking at everything about +her, to pass away the time. + + Alice had never been in a court of justice before, but she had +read about them in books, and she was quite pleased to find that +she knew the name of nearly everything there. `That's the +judge,' she said to herself, `because of his great wig.' + + The judge, by the way, was the King; and as he wore his crown +over the wig, (look at the frontispiece if you want to see how he +did it,) he did not look at all comfortable, and it was certainly +not becoming. + + `And that's the jury-box,' thought Alice, `and those twelve +creatures,' (she was obliged to say `creatures,' you see, because +some of them were animals, and some were birds,) `I suppose they +are the jurors.' She said this last word two or three times over +to herself, being rather proud of it: for she thought, and +rightly too, that very few little girls of her age knew the +meaning of it at all. However, `jury-men' would have done just +as well. + + The twelve jurors were all writing very busily on slates. +`What are they doing?' Alice whispered to the Gryphon. `They +can't have anything to put down yet, before the trial's begun.' + + `They're putting down their names,' the Gryphon whispered in +reply, `for fear they should forget them before the end of the +trial.' + + `Stupid things!' Alice began in a loud, indignant voice, but +she stopped hastily, for the White Rabbit cried out, `Silence in +the court!' and the King put on his spectacles and looked +anxiously round, to make out who was talking. + + Alice could see, as well as if she were looking over their +shoulders, that all the jurors were writing down `stupid things!' +on their slates, and she could even make out that one of them +didn't know how to spell `stupid,' and that he had to ask his +neighbour to tell him. `A nice muddle their slates'll be in +before the trial's over!' thought Alice. + + One of the jurors had a pencil that squeaked. This of course, +Alice could not stand, and she went round the court and got +behind him, and very soon found an opportunity of taking it +away. She did it so quickly that the poor little juror (it was +Bill, the Lizard) could not make out at all what had become of +it; so, after hunting all about for it, he was obliged to write +with one finger for the rest of the day; and this was of very +little use, as it left no mark on the slate. + + `Herald, read the accusation!' said the King. + + On this the White Rabbit blew three blasts on the trumpet, and +then unrolled the parchment scroll, and read as follows:-- + + `The Queen of Hearts, she made some tarts, + All on a summer day: + The Knave of Hearts, he stole those tarts, + And took them quite away!' + + `Consider your verdict,' the King said to the jury. + + `Not yet, not yet!' the Rabbit hastily interrupted. `There's +a great deal to come before that!' + + `Call the first witness,' said the King; and the White Rabbit +blew three blasts on the trumpet, and called out, `First +witness!' + + The first witness was the Hatter. He came in with a teacup in +one hand and a piece of bread-and-butter in the other. `I beg +pardon, your Majesty,' he began, `for bringing these in: but I +hadn't quite finished my tea when I was sent for.' + + `You ought to have finished,' said the King. `When did you +begin?' + + The Hatter looked at the March Hare, who had followed him into +the court, arm-in-arm with the Dormouse. `Fourteenth of March, I +think it was,' he said. + + `Fifteenth,' said the March Hare. + + `Sixteenth,' added the Dormouse. + + `Write that down,' the King said to the jury, and the jury +eagerly wrote down all three dates on their slates, and then +added them up, and reduced the answer to shillings and pence. + + `Take off your hat,' the King said to the Hatter. + + `It isn't mine,' said the Hatter. + + `Stolen!' the King exclaimed, turning to the jury, who +instantly made a memorandum of the fact. + + `I keep them to sell,' the Hatter added as an explanation; +`I've none of my own. I'm a hatter.' + + Here the Queen put on her spectacles, and began staring at the +Hatter, who turned pale and fidgeted. + + `Give your evidence,' said the King; `and don't be nervous, or +I'll have you executed on the spot.' + + This did not seem to encourage the witness at all: he kept +shifting from one foot to the other, looking uneasily at the +Queen, and in his confusion he bit a large piece out of his +teacup instead of the bread-and-butter. + + Just at this moment Alice felt a very curious sensation, which +puzzled her a good deal until she made out what it was: she was +beginning to grow larger again, and she thought at first she +would get up and leave the court; but on second thoughts she +decided to remain where she was as long as there was room for +her. + + `I wish you wouldn't squeeze so.' said the Dormouse, who was +sitting next to her. `I can hardly breathe.' + + `I can't help it,' said Alice very meekly: `I'm growing.' + + `You've no right to grow here,' said the Dormouse. + + `Don't talk nonsense,' said Alice more boldly: `you know +you're growing too.' + + `Yes, but I grow at a reasonable pace,' said the Dormouse: +`not in that ridiculous fashion.' And he got up very sulkily +and crossed over to the other side of the court. + + All this time the Queen had never left off staring at the +Hatter, and, just as the Dormouse crossed the court, she said to +one of the officers of the court, `Bring me the list of the +singers in the last concert!' on which the wretched Hatter +trembled so, that he shook both his shoes off. + + `Give your evidence,' the King repeated angrily, `or I'll have +you executed, whether you're nervous or not.' + + `I'm a poor man, your Majesty,' the Hatter began, in a +trembling voice, `--and I hadn't begun my tea--not above a week +or so--and what with the bread-and-butter getting so thin--and +the twinkling of the tea--' + + `The twinkling of the what?' said the King. + + `It began with the tea,' the Hatter replied. + + `Of course twinkling begins with a T!' said the King sharply. +`Do you take me for a dunce? Go on!' + + `I'm a poor man,' the Hatter went on, `and most things +twinkled after that--only the March Hare said--' + + `I didn't!' the March Hare interrupted in a great hurry. + + `You did!' said the Hatter. + + `I deny it!' said the March Hare. + + `He denies it,' said the King: `leave out that part.' + + `Well, at any rate, the Dormouse said--' the Hatter went on, +looking anxiously round to see if he would deny it too: but the +Dormouse denied nothing, being fast asleep. + + `After that,' continued the Hatter, `I cut some more bread- +and-butter--' + + `But what did the Dormouse say?' one of the jury asked. + + `That I can't remember,' said the Hatter. + + `You MUST remember,' remarked the King, `or I'll have you +executed.' + + The miserable Hatter dropped his teacup and bread-and-butter, +and went down on one knee. `I'm a poor man, your Majesty,' he +began. + + `You're a very poor speaker,' said the King. + + Here one of the guinea-pigs cheered, and was immediately +suppressed by the officers of the court. (As that is rather a +hard word, I will just explain to you how it was done. They had +a large canvas bag, which tied up at the mouth with strings: +into this they slipped the guinea-pig, head first, and then sat +upon it.) + + `I'm glad I've seen that done,' thought Alice. `I've so often +read in the newspapers, at the end of trials, "There was some +attempts at applause, which was immediately suppressed by the +officers of the court," and I never understood what it meant +till now.' + + `If that's all you know about it, you may stand down,' +continued the King. + + `I can't go no lower,' said the Hatter: `I'm on the floor, as +it is.' + + `Then you may SIT down,' the King replied. + + Here the other guinea-pig cheered, and was suppressed. + + `Come, that finished the guinea-pigs!' thought Alice. `Now we +shall get on better.' + + `I'd rather finish my tea,' said the Hatter, with an anxious +look at the Queen, who was reading the list of singers. + + `You may go,' said the King, and the Hatter hurriedly left the +court, without even waiting to put his shoes on. + + `--and just take his head off outside,' the Queen added to one +of the officers: but the Hatter was out of sight before the +officer could get to the door. + + `Call the next witness!' said the King. + + The next witness was the Duchess's cook. She carried the +pepper-box in her hand, and Alice guessed who it was, even before +she got into the court, by the way the people near the door began +sneezing all at once. + + `Give your evidence,' said the King. + + `Shan't,' said the cook. + + The King looked anxiously at the White Rabbit, who said in a +low voice, `Your Majesty must cross-examine THIS witness.' + + `Well, if I must, I must,' the King said, with a melancholy +air, and, after folding his arms and frowning at the cook till +his eyes were nearly out of sight, he said in a deep voice, `What +are tarts made of?' + + `Pepper, mostly,' said the cook. + + `Treacle,' said a sleepy voice behind her. + + `Collar that Dormouse,' the Queen shrieked out. `Behead that +Dormouse! Turn that Dormouse out of court! Suppress him! Pinch +him! Off with his whiskers!' + + For some minutes the whole court was in confusion, getting the +Dormouse turned out, and, by the time they had settled down +again, the cook had disappeared. + + `Never mind!' said the King, with an air of great relief. +`Call the next witness.' And he added in an undertone to the +Queen, `Really, my dear, YOU must cross-examine the next witness. +It quite makes my forehead ache!' + + Alice watched the White Rabbit as he fumbled over the list, +feeling very curious to see what the next witness would be like, +`--for they haven't got much evidence YET,' she said to herself. +Imagine her surprise, when the White Rabbit read out, at the top +of his shrill little voice, the name `Alice!' + + + + CHAPTER XII + + Alice's Evidence + + + `Here!' cried Alice, quite forgetting in the flurry of the +moment how large she had grown in the last few minutes, and she +jumped up in such a hurry that she tipped over the jury-box with +the edge of her skirt, upsetting all the jurymen on to the heads +of the crowd below, and there they lay sprawling about, reminding +her very much of a globe of goldfish she had accidentally upset +the week before. + + `Oh, I BEG your pardon!' she exclaimed in a tone of great +dismay, and began picking them up again as quickly as she could, +for the accident of the goldfish kept running in her head, and +she had a vague sort of idea that they must be collected at once +and put back into the jury-box, or they would die. + + `The trial cannot proceed,' said the King in a very grave +voice, `until all the jurymen are back in their proper places-- +ALL,' he repeated with great emphasis, looking hard at Alice as +he said do. + + Alice looked at the jury-box, and saw that, in her haste, she +had put the Lizard in head downwards, and the poor little thing +was waving its tail about in a melancholy way, being quite unable +to move. She soon got it out again, and put it right; `not that +it signifies much,' she said to herself; `I should think it +would be QUITE as much use in the trial one way up as the other.' + + As soon as the jury had a little recovered from the shock of +being upset, and their slates and pencils had been found and +handed back to them, they set to work very diligently to write +out a history of the accident, all except the Lizard, who seemed +too much overcome to do anything but sit with its mouth open, +gazing up into the roof of the court. + + `What do you know about this business?' the King said to +Alice. + + `Nothing,' said Alice. + + `Nothing WHATEVER?' persisted the King. + + `Nothing whatever,' said Alice. + + `That's very important,' the King said, turning to the jury. +They were just beginning to write this down on their slates, when +the White Rabbit interrupted: `UNimportant, your Majesty means, +of course,' he said in a very respectful tone, but frowning and +making faces at him as he spoke. + + `UNimportant, of course, I meant,' the King hastily said, and +went on to himself in an undertone, `important--unimportant-- +unimportant--important--' as if he were trying which word +sounded best. + + Some of the jury wrote it down `important,' and some +`unimportant.' Alice could see this, as she was near enough to +look over their slates; `but it doesn't matter a bit,' she +thought to herself. + + At this moment the King, who had been for some time busily +writing in his note-book, cackled out `Silence!' and read out +from his book, `Rule Forty-two. ALL PERSONS MORE THAN A MILE +HIGH TO LEAVE THE COURT.' + + Everybody looked at Alice. + + `I'M not a mile high,' said Alice. + + `You are,' said the King. + + `Nearly two miles high,' added the Queen. + + `Well, I shan't go, at any rate,' said Alice: `besides, +that's not a regular rule: you invented it just now.' + + `It's the oldest rule in the book,' said the King. + + `Then it ought to be Number One,' said Alice. + + The King turned pale, and shut his note-book hastily. +`Consider your verdict,' he said to the jury, in a low, trembling +voice. + + `There's more evidence to come yet, please your Majesty,' said +the White Rabbit, jumping up in a great hurry; `this paper has +just been picked up.' + + `What's in it?' said the Queen. + + `I haven't opened it yet,' said the White Rabbit, `but it seems +to be a letter, written by the prisoner to--to somebody.' + + `It must have been that,' said the King, `unless it was +written to nobody, which isn't usual, you know.' + + `Who is it directed to?' said one of the jurymen. + + `It isn't directed at all,' said the White Rabbit; `in fact, +there's nothing written on the OUTSIDE.' He unfolded the paper +as he spoke, and added `It isn't a letter, after all: it's a set +of verses.' + + `Are they in the prisoner's handwriting?' asked another of +they jurymen. + + `No, they're not,' said the White Rabbit, `and that's the +queerest thing about it.' (The jury all looked puzzled.) + + `He must have imitated somebody else's hand,' said the King. +(The jury all brightened up again.) + + `Please your Majesty,' said the Knave, `I didn't write it, and +they can't prove I did: there's no name signed at the end.' + + `If you didn't sign it,' said the King, `that only makes the +matter worse. You MUST have meant some mischief, or else you'd +have signed your name like an honest man.' + + There was a general clapping of hands at this: it was the +first really clever thing the King had said that day. + + `That PROVES his guilt,' said the Queen. + + `It proves nothing of the sort!' said Alice. `Why, you don't +even know what they're about!' + + `Read them,' said the King. + + The White Rabbit put on his spectacles. `Where shall I begin, +please your Majesty?' he asked. + + `Begin at the beginning,' the King said gravely, `and go on +till you come to the end: then stop.' + + These were the verses the White Rabbit read:-- + + `They told me you had been to her, + And mentioned me to him: + She gave me a good character, + But said I could not swim. + + He sent them word I had not gone + (We know it to be true): + If she should push the matter on, + What would become of you? + + I gave her one, they gave him two, + You gave us three or more; + They all returned from him to you, + Though they were mine before. + + If I or she should chance to be + Involved in this affair, + He trusts to you to set them free, + Exactly as we were. + + My notion was that you had been + (Before she had this fit) + An obstacle that came between + Him, and ourselves, and it. + + Don't let him know she liked them best, + For this must ever be + A secret, kept from all the rest, + Between yourself and me.' + + `That's the most important piece of evidence we've heard yet,' +said the King, rubbing his hands; `so now let the jury--' + + `If any one of them can explain it,' said Alice, (she had +grown so large in the last few minutes that she wasn't a bit +afraid of interrupting him,) `I'll give him sixpence. _I_ don't +believe there's an atom of meaning in it.' + + The jury all wrote down on their slates, `SHE doesn't believe +there's an atom of meaning in it,' but none of them attempted to +explain the paper. + + `If there's no meaning in it,' said the King, `that saves a +world of trouble, you know, as we needn't try to find any. And +yet I don't know,' he went on, spreading out the verses on his +knee, and looking at them with one eye; `I seem to see some +meaning in them, after all. "--SAID I COULD NOT SWIM--" you +can't swim, can you?' he added, turning to the Knave. + + The Knave shook his head sadly. `Do I look like it?' he said. +(Which he certainly did NOT, being made entirely of cardboard.) + + `All right, so far,' said the King, and he went on muttering +over the verses to himself: `"WE KNOW IT TO BE TRUE--" that's +the jury, of course-- "I GAVE HER ONE, THEY GAVE HIM TWO--" why, +that must be what he did with the tarts, you know--' + + `But, it goes on "THEY ALL RETURNED FROM HIM TO YOU,"' said +Alice. + + `Why, there they are!' said the King triumphantly, pointing to +the tarts on the table. `Nothing can be clearer than THAT. +Then again--"BEFORE SHE HAD THIS FIT--" you never had fits, my +dear, I think?' he said to the Queen. + + `Never!' said the Queen furiously, throwing an inkstand at the +Lizard as she spoke. (The unfortunate little Bill had left off +writing on his slate with one finger, as he found it made no +mark; but he now hastily began again, using the ink, that was +trickling down his face, as long as it lasted.) + + `Then the words don't FIT you,' said the King, looking round +the court with a smile. There was a dead silence. + + `It's a pun!' the King added in an offended tone, and +everybody laughed, `Let the jury consider their verdict,' the +King said, for about the twentieth time that day. + + `No, no!' said the Queen. `Sentence first--verdict afterwards.' + + `Stuff and nonsense!' said Alice loudly. `The idea of having +the sentence first!' + + `Hold your tongue!' said the Queen, turning purple. + + `I won't!' said Alice. + + `Off with her head!' the Queen shouted at the top of her voice. +Nobody moved. + + `Who cares for you?' said Alice, (she had grown to her full +size by this time.) `You're nothing but a pack of cards!' + + At this the whole pack rose up into the air, and came flying +down upon her: she gave a little scream, half of fright and half +of anger, and tried to beat them off, and found herself lying on +the bank, with her head in the lap of her sister, who was gently +brushing away some dead leaves that had fluttered down from the +trees upon her face. + + `Wake up, Alice dear!' said her sister; `Why, what a long +sleep you've had!' + + `Oh, I've had such a curious dream!' said Alice, and she told +her sister, as well as she could remember them, all these strange +Adventures of hers that you have just been reading about; and +when she had finished, her sister kissed her, and said, `It WAS a +curious dream, dear, certainly: but now run in to your tea; it's +getting late.' So Alice got up and ran off, thinking while she +ran, as well she might, what a wonderful dream it had been. + + But her sister sat still just as she left her, leaning her +head on her hand, watching the setting sun, and thinking of +little Alice and all her wonderful Adventures, till she too began +dreaming after a fashion, and this was her dream:-- + + First, she dreamed of little Alice herself, and once again the +tiny hands were clasped upon her knee, and the bright eager eyes +were looking up into hers--she could hear the very tones of her +voice, and see that queer little toss of her head to keep back +the wandering hair that WOULD always get into her eyes--and +still as she listened, or seemed to listen, the whole place +around her became alive the strange creatures of her little +sister's dream. + + The long grass rustled at her feet as the White Rabbit hurried +by--the frightened Mouse splashed his way through the +neighbouring pool--she could hear the rattle of the teacups as +the March Hare and his friends shared their never-ending meal, +and the shrill voice of the Queen ordering off her unfortunate +guests to execution--once more the pig-baby was sneezing on the +Duchess's knee, while plates and dishes crashed around it--once +more the shriek of the Gryphon, the squeaking of the Lizard's +slate-pencil, and the choking of the suppressed guinea-pigs, +filled the air, mixed up with the distant sobs of the miserable +Mock Turtle. + + So she sat on, with closed eyes, and half believed herself in +Wonderland, though she knew she had but to open them again, and +all would change to dull reality--the grass would be only +rustling in the wind, and the pool rippling to the waving of the +reeds--the rattling teacups would change to tinkling sheep- +bells, and the Queen's shrill cries to the voice of the shepherd +boy--and the sneeze of the baby, the shriek of the Gryphon, and +all thy other queer noises, would change (she knew) to the +confused clamour of the busy farm-yard--while the lowing of the +cattle in the distance would take the place of the Mock Turtle's +heavy sobs. + + Lastly, she pictured to herself how this same little sister of +hers would, in the after-time, be herself a grown woman; and how +she would keep, through all her riper years, the simple and +loving heart of her childhood: and how she would gather about +her other little children, and make THEIR eyes bright and eager +with many a strange tale, perhaps even with the dream of +Wonderland of long ago: and how she would feel with all their +simple sorrows, and find a pleasure in all their simple joys, +remembering her own child-life, and the happy summer days. + + THE END + \ No newline at end of file diff --git a/web/server/h2o/libh2o/deps/brotli/tests/testdata/alice29.txt.compressed b/web/server/h2o/libh2o/deps/brotli/tests/testdata/alice29.txt.compressed new file mode 100644 index 00000000..37d86e25 Binary files /dev/null and b/web/server/h2o/libh2o/deps/brotli/tests/testdata/alice29.txt.compressed differ diff --git a/web/server/h2o/libh2o/deps/brotli/tests/testdata/asyoulik.txt b/web/server/h2o/libh2o/deps/brotli/tests/testdata/asyoulik.txt new file mode 100644 index 00000000..88dc7b60 --- /dev/null +++ b/web/server/h2o/libh2o/deps/brotli/tests/testdata/asyoulik.txt @@ -0,0 +1,4122 @@ + AS YOU LIKE IT + + + DRAMATIS PERSONAE + + +DUKE SENIOR living in banishment. + +DUKE FREDERICK his brother, an usurper of his dominions. + + +AMIENS | + | lords attending on the banished duke. +JAQUES | + + +LE BEAU a courtier attending upon Frederick. + +CHARLES wrestler to Frederick. + + +OLIVER | + | +JAQUES (JAQUES DE BOYS:) | sons of Sir Rowland de Boys. + | +ORLANDO | + + +ADAM | + | servants to Oliver. +DENNIS | + + +TOUCHSTONE a clown. + +SIR OLIVER MARTEXT a vicar. + + +CORIN | + | shepherds. +SILVIUS | + + +WILLIAM a country fellow in love with Audrey. + + A person representing HYMEN. (HYMEN:) + +ROSALIND daughter to the banished duke. + +CELIA daughter to Frederick. + +PHEBE a shepherdess. + +AUDREY a country wench. + + Lords, pages, and attendants, &c. + (Forester:) + (A Lord:) + (First Lord:) + (Second Lord:) + (First Page:) + (Second Page:) + + +SCENE Oliver's house; Duke Frederick's court; and the + Forest of Arden. + + + + + AS YOU LIKE IT + + +ACT I + + + +SCENE I Orchard of Oliver's house. + + + [Enter ORLANDO and ADAM] + +ORLANDO As I remember, Adam, it was upon this fashion + bequeathed me by will but poor a thousand crowns, + and, as thou sayest, charged my brother, on his + blessing, to breed me well: and there begins my + sadness. My brother Jaques he keeps at school, and + report speaks goldenly of his profit: for my part, + he keeps me rustically at home, or, to speak more + properly, stays me here at home unkept; for call you + that keeping for a gentleman of my birth, that + differs not from the stalling of an ox? His horses + are bred better; for, besides that they are fair + with their feeding, they are taught their manage, + and to that end riders dearly hired: but I, his + brother, gain nothing under him but growth; for the + which his animals on his dunghills are as much + bound to him as I. Besides this nothing that he so + plentifully gives me, the something that nature gave + me his countenance seems to take from me: he lets + me feed with his hinds, bars me the place of a + brother, and, as much as in him lies, mines my + gentility with my education. This is it, Adam, that + grieves me; and the spirit of my father, which I + think is within me, begins to mutiny against this + servitude: I will no longer endure it, though yet I + know no wise remedy how to avoid it. + +ADAM Yonder comes my master, your brother. + +ORLANDO Go apart, Adam, and thou shalt hear how he will + shake me up. + + [Enter OLIVER] + +OLIVER Now, sir! what make you here? + +ORLANDO Nothing: I am not taught to make any thing. + +OLIVER What mar you then, sir? + +ORLANDO Marry, sir, I am helping you to mar that which God + made, a poor unworthy brother of yours, with idleness. + +OLIVER Marry, sir, be better employed, and be naught awhile. + +ORLANDO Shall I keep your hogs and eat husks with them? + What prodigal portion have I spent, that I should + come to such penury? + +OLIVER Know you where your are, sir? + +ORLANDO O, sir, very well; here in your orchard. + +OLIVER Know you before whom, sir? + +ORLANDO Ay, better than him I am before knows me. I know + you are my eldest brother; and, in the gentle + condition of blood, you should so know me. The + courtesy of nations allows you my better, in that + you are the first-born; but the same tradition + takes not away my blood, were there twenty brothers + betwixt us: I have as much of my father in me as + you; albeit, I confess, your coming before me is + nearer to his reverence. + +OLIVER What, boy! + +ORLANDO Come, come, elder brother, you are too young in this. + +OLIVER Wilt thou lay hands on me, villain? + +ORLANDO I am no villain; I am the youngest son of Sir + Rowland de Boys; he was my father, and he is thrice + a villain that says such a father begot villains. + Wert thou not my brother, I would not take this hand + from thy throat till this other had pulled out thy + tongue for saying so: thou hast railed on thyself. + +ADAM Sweet masters, be patient: for your father's + remembrance, be at accord. + +OLIVER Let me go, I say. + +ORLANDO I will not, till I please: you shall hear me. My + father charged you in his will to give me good + education: you have trained me like a peasant, + obscuring and hiding from me all gentleman-like + qualities. The spirit of my father grows strong in + me, and I will no longer endure it: therefore allow + me such exercises as may become a gentleman, or + give me the poor allottery my father left me by + testament; with that I will go buy my fortunes. + +OLIVER And what wilt thou do? beg, when that is spent? + Well, sir, get you in: I will not long be troubled + with you; you shall have some part of your will: I + pray you, leave me. + +ORLANDO I will no further offend you than becomes me for my good. + +OLIVER Get you with him, you old dog. + +ADAM Is 'old dog' my reward? Most true, I have lost my + teeth in your service. God be with my old master! + he would not have spoke such a word. + + [Exeunt ORLANDO and ADAM] + +OLIVER Is it even so? begin you to grow upon me? I will + physic your rankness, and yet give no thousand + crowns neither. Holla, Dennis! + + [Enter DENNIS] + +DENNIS Calls your worship? + +OLIVER Was not Charles, the duke's wrestler, here to speak with me? + +DENNIS So please you, he is here at the door and importunes + access to you. + +OLIVER Call him in. + + [Exit DENNIS] + + 'Twill be a good way; and to-morrow the wrestling is. + + [Enter CHARLES] + +CHARLES Good morrow to your worship. + +OLIVER Good Monsieur Charles, what's the new news at the + new court? + +CHARLES There's no news at the court, sir, but the old news: + that is, the old duke is banished by his younger + brother the new duke; and three or four loving lords + have put themselves into voluntary exile with him, + whose lands and revenues enrich the new duke; + therefore he gives them good leave to wander. + +OLIVER Can you tell if Rosalind, the duke's daughter, be + banished with her father? + +CHARLES O, no; for the duke's daughter, her cousin, so loves + her, being ever from their cradles bred together, + that she would have followed her exile, or have died + to stay behind her. She is at the court, and no + less beloved of her uncle than his own daughter; and + never two ladies loved as they do. + +OLIVER Where will the old duke live? + +CHARLES They say he is already in the forest of Arden, and + a many merry men with him; and there they live like + the old Robin Hood of England: they say many young + gentlemen flock to him every day, and fleet the time + carelessly, as they did in the golden world. + +OLIVER What, you wrestle to-morrow before the new duke? + +CHARLES Marry, do I, sir; and I came to acquaint you with a + matter. I am given, sir, secretly to understand + that your younger brother Orlando hath a disposition + to come in disguised against me to try a fall. + To-morrow, sir, I wrestle for my credit; and he that + escapes me without some broken limb shall acquit him + well. Your brother is but young and tender; and, + for your love, I would be loath to foil him, as I + must, for my own honour, if he come in: therefore, + out of my love to you, I came hither to acquaint you + withal, that either you might stay him from his + intendment or brook such disgrace well as he shall + run into, in that it is a thing of his own search + and altogether against my will. + +OLIVER Charles, I thank thee for thy love to me, which + thou shalt find I will most kindly requite. I had + myself notice of my brother's purpose herein and + have by underhand means laboured to dissuade him from + it, but he is resolute. I'll tell thee, Charles: + it is the stubbornest young fellow of France, full + of ambition, an envious emulator of every man's + good parts, a secret and villanous contriver against + me his natural brother: therefore use thy + discretion; I had as lief thou didst break his neck + as his finger. And thou wert best look to't; for if + thou dost him any slight disgrace or if he do not + mightily grace himself on thee, he will practise + against thee by poison, entrap thee by some + treacherous device and never leave thee till he + hath ta'en thy life by some indirect means or other; + for, I assure thee, and almost with tears I speak + it, there is not one so young and so villanous this + day living. I speak but brotherly of him; but + should I anatomize him to thee as he is, I must + blush and weep and thou must look pale and wonder. + +CHARLES I am heartily glad I came hither to you. If he come + to-morrow, I'll give him his payment: if ever he go + alone again, I'll never wrestle for prize more: and + so God keep your worship! + +OLIVER Farewell, good Charles. + + [Exit CHARLES] + + Now will I stir this gamester: I hope I shall see + an end of him; for my soul, yet I know not why, + hates nothing more than he. Yet he's gentle, never + schooled and yet learned, full of noble device, of + all sorts enchantingly beloved, and indeed so much + in the heart of the world, and especially of my own + people, who best know him, that I am altogether + misprised: but it shall not be so long; this + wrestler shall clear all: nothing remains but that + I kindle the boy thither; which now I'll go about. + + [Exit] + + + + + AS YOU LIKE IT + + +ACT I + + + +SCENE II Lawn before the Duke's palace. + + + [Enter CELIA and ROSALIND] + +CELIA I pray thee, Rosalind, sweet my coz, be merry. + +ROSALIND Dear Celia, I show more mirth than I am mistress of; + and would you yet I were merrier? Unless you could + teach me to forget a banished father, you must not + learn me how to remember any extraordinary pleasure. + +CELIA Herein I see thou lovest me not with the full weight + that I love thee. If my uncle, thy banished father, + had banished thy uncle, the duke my father, so thou + hadst been still with me, I could have taught my + love to take thy father for mine: so wouldst thou, + if the truth of thy love to me were so righteously + tempered as mine is to thee. + +ROSALIND Well, I will forget the condition of my estate, to + rejoice in yours. + +CELIA You know my father hath no child but I, nor none is + like to have: and, truly, when he dies, thou shalt + be his heir, for what he hath taken away from thy + father perforce, I will render thee again in + affection; by mine honour, I will; and when I break + that oath, let me turn monster: therefore, my + sweet Rose, my dear Rose, be merry. + +ROSALIND From henceforth I will, coz, and devise sports. Let + me see; what think you of falling in love? + +CELIA Marry, I prithee, do, to make sport withal: but + love no man in good earnest; nor no further in sport + neither than with safety of a pure blush thou mayst + in honour come off again. + +ROSALIND What shall be our sport, then? + +CELIA Let us sit and mock the good housewife Fortune from + her wheel, that her gifts may henceforth be bestowed equally. + +ROSALIND I would we could do so, for her benefits are + mightily misplaced, and the bountiful blind woman + doth most mistake in her gifts to women. + +CELIA 'Tis true; for those that she makes fair she scarce + makes honest, and those that she makes honest she + makes very ill-favouredly. + +ROSALIND Nay, now thou goest from Fortune's office to + Nature's: Fortune reigns in gifts of the world, + not in the lineaments of Nature. + + [Enter TOUCHSTONE] + +CELIA No? when Nature hath made a fair creature, may she + not by Fortune fall into the fire? Though Nature + hath given us wit to flout at Fortune, hath not + Fortune sent in this fool to cut off the argument? + +ROSALIND Indeed, there is Fortune too hard for Nature, when + Fortune makes Nature's natural the cutter-off of + Nature's wit. + +CELIA Peradventure this is not Fortune's work neither, but + Nature's; who perceiveth our natural wits too dull + to reason of such goddesses and hath sent this + natural for our whetstone; for always the dulness of + the fool is the whetstone of the wits. How now, + wit! whither wander you? + +TOUCHSTONE Mistress, you must come away to your father. + +CELIA Were you made the messenger? + +TOUCHSTONE No, by mine honour, but I was bid to come for you. + +ROSALIND Where learned you that oath, fool? + +TOUCHSTONE Of a certain knight that swore by his honour they + were good pancakes and swore by his honour the + mustard was naught: now I'll stand to it, the + pancakes were naught and the mustard was good, and + yet was not the knight forsworn. + +CELIA How prove you that, in the great heap of your + knowledge? + +ROSALIND Ay, marry, now unmuzzle your wisdom. + +TOUCHSTONE Stand you both forth now: stroke your chins, and + swear by your beards that I am a knave. + +CELIA By our beards, if we had them, thou art. + +TOUCHSTONE By my knavery, if I had it, then I were; but if you + swear by that that is not, you are not forsworn: no + more was this knight swearing by his honour, for he + never had any; or if he had, he had sworn it away + before ever he saw those pancakes or that mustard. + +CELIA Prithee, who is't that thou meanest? + +TOUCHSTONE One that old Frederick, your father, loves. + +CELIA My father's love is enough to honour him: enough! + speak no more of him; you'll be whipped for taxation + one of these days. + +TOUCHSTONE The more pity, that fools may not speak wisely what + wise men do foolishly. + +CELIA By my troth, thou sayest true; for since the little + wit that fools have was silenced, the little foolery + that wise men have makes a great show. Here comes + Monsieur Le Beau. + +ROSALIND With his mouth full of news. + +CELIA Which he will put on us, as pigeons feed their young. + +ROSALIND Then shall we be news-crammed. + +CELIA All the better; we shall be the more marketable. + + [Enter LE BEAU] + + Bon jour, Monsieur Le Beau: what's the news? + +LE BEAU Fair princess, you have lost much good sport. + +CELIA Sport! of what colour? + +LE BEAU What colour, madam! how shall I answer you? + +ROSALIND As wit and fortune will. + +TOUCHSTONE Or as the Destinies decree. + +CELIA Well said: that was laid on with a trowel. + +TOUCHSTONE Nay, if I keep not my rank,-- + +ROSALIND Thou losest thy old smell. + +LE BEAU You amaze me, ladies: I would have told you of good + wrestling, which you have lost the sight of. + +ROSALIND You tell us the manner of the wrestling. + +LE BEAU I will tell you the beginning; and, if it please + your ladyships, you may see the end; for the best is + yet to do; and here, where you are, they are coming + to perform it. + +CELIA Well, the beginning, that is dead and buried. + +LE BEAU There comes an old man and his three sons,-- + +CELIA I could match this beginning with an old tale. + +LE BEAU Three proper young men, of excellent growth and presence. + +ROSALIND With bills on their necks, 'Be it known unto all men + by these presents.' + +LE BEAU The eldest of the three wrestled with Charles, the + duke's wrestler; which Charles in a moment threw him + and broke three of his ribs, that there is little + hope of life in him: so he served the second, and + so the third. Yonder they lie; the poor old man, + their father, making such pitiful dole over them + that all the beholders take his part with weeping. + +ROSALIND Alas! + +TOUCHSTONE But what is the sport, monsieur, that the ladies + have lost? + +LE BEAU Why, this that I speak of. + +TOUCHSTONE Thus men may grow wiser every day: it is the first + time that ever I heard breaking of ribs was sport + for ladies. + +CELIA Or I, I promise thee. + +ROSALIND But is there any else longs to see this broken music + in his sides? is there yet another dotes upon + rib-breaking? Shall we see this wrestling, cousin? + +LE BEAU You must, if you stay here; for here is the place + appointed for the wrestling, and they are ready to + perform it. + +CELIA Yonder, sure, they are coming: let us now stay and see it. + + [Flourish. Enter DUKE FREDERICK, Lords, ORLANDO, + CHARLES, and Attendants] + +DUKE FREDERICK Come on: since the youth will not be entreated, his + own peril on his forwardness. + +ROSALIND Is yonder the man? + +LE BEAU Even he, madam. + +CELIA Alas, he is too young! yet he looks successfully. + +DUKE FREDERICK How now, daughter and cousin! are you crept hither + to see the wrestling? + +ROSALIND Ay, my liege, so please you give us leave. + +DUKE FREDERICK You will take little delight in it, I can tell you; + there is such odds in the man. In pity of the + challenger's youth I would fain dissuade him, but he + will not be entreated. Speak to him, ladies; see if + you can move him. + +CELIA Call him hither, good Monsieur Le Beau. + +DUKE FREDERICK Do so: I'll not be by. + +LE BEAU Monsieur the challenger, the princesses call for you. + +ORLANDO I attend them with all respect and duty. + +ROSALIND Young man, have you challenged Charles the wrestler? + +ORLANDO No, fair princess; he is the general challenger: I + come but in, as others do, to try with him the + strength of my youth. + +CELIA Young gentleman, your spirits are too bold for your + years. You have seen cruel proof of this man's + strength: if you saw yourself with your eyes or + knew yourself with your judgment, the fear of your + adventure would counsel you to a more equal + enterprise. We pray you, for your own sake, to + embrace your own safety and give over this attempt. + +ROSALIND Do, young sir; your reputation shall not therefore + be misprised: we will make it our suit to the duke + that the wrestling might not go forward. + +ORLANDO I beseech you, punish me not with your hard + thoughts; wherein I confess me much guilty, to deny + so fair and excellent ladies any thing. But let + your fair eyes and gentle wishes go with me to my + trial: wherein if I be foiled, there is but one + shamed that was never gracious; if killed, but one + dead that was willing to be so: I shall do my + friends no wrong, for I have none to lament me, the + world no injury, for in it I have nothing; only in + the world I fill up a place, which may be better + supplied when I have made it empty. + +ROSALIND The little strength that I have, I would it were with you. + +CELIA And mine, to eke out hers. + +ROSALIND Fare you well: pray heaven I be deceived in you! + +CELIA Your heart's desires be with you! + +CHARLES Come, where is this young gallant that is so + desirous to lie with his mother earth? + +ORLANDO Ready, sir; but his will hath in it a more modest working. + +DUKE FREDERICK You shall try but one fall. + +CHARLES No, I warrant your grace, you shall not entreat him + to a second, that have so mightily persuaded him + from a first. + +ORLANDO An you mean to mock me after, you should not have + mocked me before: but come your ways. + +ROSALIND Now Hercules be thy speed, young man! + +CELIA I would I were invisible, to catch the strong + fellow by the leg. + + [They wrestle] + +ROSALIND O excellent young man! + +CELIA If I had a thunderbolt in mine eye, I can tell who + should down. + + [Shout. CHARLES is thrown] + +DUKE FREDERICK No more, no more. + +ORLANDO Yes, I beseech your grace: I am not yet well breathed. + +DUKE FREDERICK How dost thou, Charles? + +LE BEAU He cannot speak, my lord. + +DUKE FREDERICK Bear him away. What is thy name, young man? + +ORLANDO Orlando, my liege; the youngest son of Sir Rowland de Boys. + +DUKE FREDERICK I would thou hadst been son to some man else: + The world esteem'd thy father honourable, + But I did find him still mine enemy: + Thou shouldst have better pleased me with this deed, + Hadst thou descended from another house. + But fare thee well; thou art a gallant youth: + I would thou hadst told me of another father. + + [Exeunt DUKE FREDERICK, train, and LE BEAU] + +CELIA Were I my father, coz, would I do this? + +ORLANDO I am more proud to be Sir Rowland's son, + His youngest son; and would not change that calling, + To be adopted heir to Frederick. + +ROSALIND My father loved Sir Rowland as his soul, + And all the world was of my father's mind: + Had I before known this young man his son, + I should have given him tears unto entreaties, + Ere he should thus have ventured. + +CELIA Gentle cousin, + Let us go thank him and encourage him: + My father's rough and envious disposition + Sticks me at heart. Sir, you have well deserved: + If you do keep your promises in love + But justly, as you have exceeded all promise, + Your mistress shall be happy. + +ROSALIND Gentleman, + + [Giving him a chain from her neck] + + Wear this for me, one out of suits with fortune, + That could give more, but that her hand lacks means. + Shall we go, coz? + +CELIA Ay. Fare you well, fair gentleman. + +ORLANDO Can I not say, I thank you? My better parts + Are all thrown down, and that which here stands up + Is but a quintain, a mere lifeless block. + +ROSALIND He calls us back: my pride fell with my fortunes; + I'll ask him what he would. Did you call, sir? + Sir, you have wrestled well and overthrown + More than your enemies. + +CELIA Will you go, coz? + +ROSALIND Have with you. Fare you well. + + [Exeunt ROSALIND and CELIA] + +ORLANDO What passion hangs these weights upon my tongue? + I cannot speak to her, yet she urged conference. + O poor Orlando, thou art overthrown! + Or Charles or something weaker masters thee. + + [Re-enter LE BEAU] + +LE BEAU Good sir, I do in friendship counsel you + To leave this place. Albeit you have deserved + High commendation, true applause and love, + Yet such is now the duke's condition + That he misconstrues all that you have done. + The duke is humorous; what he is indeed, + More suits you to conceive than I to speak of. + +ORLANDO I thank you, sir: and, pray you, tell me this: + Which of the two was daughter of the duke + That here was at the wrestling? + +LE BEAU Neither his daughter, if we judge by manners; + But yet indeed the lesser is his daughter + The other is daughter to the banish'd duke, + And here detain'd by her usurping uncle, + To keep his daughter company; whose loves + Are dearer than the natural bond of sisters. + But I can tell you that of late this duke + Hath ta'en displeasure 'gainst his gentle niece, + Grounded upon no other argument + But that the people praise her for her virtues + And pity her for her good father's sake; + And, on my life, his malice 'gainst the lady + Will suddenly break forth. Sir, fare you well: + Hereafter, in a better world than this, + I shall desire more love and knowledge of you. + +ORLANDO I rest much bounden to you: fare you well. + + [Exit LE BEAU] + + Thus must I from the smoke into the smother; + From tyrant duke unto a tyrant brother: + But heavenly Rosalind! + + [Exit] + + + + + AS YOU LIKE IT + + +ACT I + + + +SCENE III A room in the palace. + + + [Enter CELIA and ROSALIND] + +CELIA Why, cousin! why, Rosalind! Cupid have mercy! not a word? + +ROSALIND Not one to throw at a dog. + +CELIA No, thy words are too precious to be cast away upon + curs; throw some of them at me; come, lame me with reasons. + +ROSALIND Then there were two cousins laid up; when the one + should be lamed with reasons and the other mad + without any. + +CELIA But is all this for your father? + +ROSALIND No, some of it is for my child's father. O, how + full of briers is this working-day world! + +CELIA They are but burs, cousin, thrown upon thee in + holiday foolery: if we walk not in the trodden + paths our very petticoats will catch them. + +ROSALIND I could shake them off my coat: these burs are in my heart. + +CELIA Hem them away. + +ROSALIND I would try, if I could cry 'hem' and have him. + +CELIA Come, come, wrestle with thy affections. + +ROSALIND O, they take the part of a better wrestler than myself! + +CELIA O, a good wish upon you! you will try in time, in + despite of a fall. But, turning these jests out of + service, let us talk in good earnest: is it + possible, on such a sudden, you should fall into so + strong a liking with old Sir Rowland's youngest son? + +ROSALIND The duke my father loved his father dearly. + +CELIA Doth it therefore ensue that you should love his son + dearly? By this kind of chase, I should hate him, + for my father hated his father dearly; yet I hate + not Orlando. + +ROSALIND No, faith, hate him not, for my sake. + +CELIA Why should I not? doth he not deserve well? + +ROSALIND Let me love him for that, and do you love him + because I do. Look, here comes the duke. + +CELIA With his eyes full of anger. + + [Enter DUKE FREDERICK, with Lords] + +DUKE FREDERICK Mistress, dispatch you with your safest haste + And get you from our court. + +ROSALIND Me, uncle? + +DUKE FREDERICK You, cousin + Within these ten days if that thou be'st found + So near our public court as twenty miles, + Thou diest for it. + +ROSALIND I do beseech your grace, + Let me the knowledge of my fault bear with me: + If with myself I hold intelligence + Or have acquaintance with mine own desires, + If that I do not dream or be not frantic,-- + As I do trust I am not--then, dear uncle, + Never so much as in a thought unborn + Did I offend your highness. + +DUKE FREDERICK Thus do all traitors: + If their purgation did consist in words, + They are as innocent as grace itself: + Let it suffice thee that I trust thee not. + +ROSALIND Yet your mistrust cannot make me a traitor: + Tell me whereon the likelihood depends. + +DUKE FREDERICK Thou art thy father's daughter; there's enough. + +ROSALIND So was I when your highness took his dukedom; + So was I when your highness banish'd him: + Treason is not inherited, my lord; + Or, if we did derive it from our friends, + What's that to me? my father was no traitor: + Then, good my liege, mistake me not so much + To think my poverty is treacherous. + +CELIA Dear sovereign, hear me speak. + +DUKE FREDERICK Ay, Celia; we stay'd her for your sake, + Else had she with her father ranged along. + +CELIA I did not then entreat to have her stay; + It was your pleasure and your own remorse: + I was too young that time to value her; + But now I know her: if she be a traitor, + Why so am I; we still have slept together, + Rose at an instant, learn'd, play'd, eat together, + And wheresoever we went, like Juno's swans, + Still we went coupled and inseparable. + +DUKE FREDERICK She is too subtle for thee; and her smoothness, + Her very silence and her patience + Speak to the people, and they pity her. + Thou art a fool: she robs thee of thy name; + And thou wilt show more bright and seem more virtuous + When she is gone. Then open not thy lips: + Firm and irrevocable is my doom + Which I have pass'd upon her; she is banish'd. + +CELIA Pronounce that sentence then on me, my liege: + I cannot live out of her company. + +DUKE FREDERICK You are a fool. You, niece, provide yourself: + If you outstay the time, upon mine honour, + And in the greatness of my word, you die. + + [Exeunt DUKE FREDERICK and Lords] + +CELIA O my poor Rosalind, whither wilt thou go? + Wilt thou change fathers? I will give thee mine. + I charge thee, be not thou more grieved than I am. + +ROSALIND I have more cause. + +CELIA Thou hast not, cousin; + Prithee be cheerful: know'st thou not, the duke + Hath banish'd me, his daughter? + +ROSALIND That he hath not. + +CELIA No, hath not? Rosalind lacks then the love + Which teacheth thee that thou and I am one: + Shall we be sunder'd? shall we part, sweet girl? + No: let my father seek another heir. + Therefore devise with me how we may fly, + Whither to go and what to bear with us; + And do not seek to take your change upon you, + To bear your griefs yourself and leave me out; + For, by this heaven, now at our sorrows pale, + Say what thou canst, I'll go along with thee. + +ROSALIND Why, whither shall we go? + +CELIA To seek my uncle in the forest of Arden. + +ROSALIND Alas, what danger will it be to us, + Maids as we are, to travel forth so far! + Beauty provoketh thieves sooner than gold. + +CELIA I'll put myself in poor and mean attire + And with a kind of umber smirch my face; + The like do you: so shall we pass along + And never stir assailants. + +ROSALIND Were it not better, + Because that I am more than common tall, + That I did suit me all points like a man? + A gallant curtle-axe upon my thigh, + A boar-spear in my hand; and--in my heart + Lie there what hidden woman's fear there will-- + We'll have a swashing and a martial outside, + As many other mannish cowards have + That do outface it with their semblances. + +CELIA What shall I call thee when thou art a man? + +ROSALIND I'll have no worse a name than Jove's own page; + And therefore look you call me Ganymede. + But what will you be call'd? + +CELIA Something that hath a reference to my state + No longer Celia, but Aliena. + +ROSALIND But, cousin, what if we assay'd to steal + The clownish fool out of your father's court? + Would he not be a comfort to our travel? + +CELIA He'll go along o'er the wide world with me; + Leave me alone to woo him. Let's away, + And get our jewels and our wealth together, + Devise the fittest time and safest way + To hide us from pursuit that will be made + After my flight. Now go we in content + To liberty and not to banishment. + + [Exeunt] + + + + + AS YOU LIKE IT + + +ACT II + + + +SCENE I The Forest of Arden. + + + [Enter DUKE SENIOR, AMIENS, and two or three Lords, + like foresters] + +DUKE SENIOR Now, my co-mates and brothers in exile, + Hath not old custom made this life more sweet + Than that of painted pomp? Are not these woods + More free from peril than the envious court? + Here feel we but the penalty of Adam, + The seasons' difference, as the icy fang + And churlish chiding of the winter's wind, + Which, when it bites and blows upon my body, + Even till I shrink with cold, I smile and say + 'This is no flattery: these are counsellors + That feelingly persuade me what I am.' + Sweet are the uses of adversity, + Which, like the toad, ugly and venomous, + Wears yet a precious jewel in his head; + And this our life exempt from public haunt + Finds tongues in trees, books in the running brooks, + Sermons in stones and good in every thing. + I would not change it. + +AMIENS Happy is your grace, + That can translate the stubbornness of fortune + Into so quiet and so sweet a style. + +DUKE SENIOR Come, shall we go and kill us venison? + And yet it irks me the poor dappled fools, + Being native burghers of this desert city, + Should in their own confines with forked heads + Have their round haunches gored. + +First Lord Indeed, my lord, + The melancholy Jaques grieves at that, + And, in that kind, swears you do more usurp + Than doth your brother that hath banish'd you. + To-day my Lord of Amiens and myself + Did steal behind him as he lay along + Under an oak whose antique root peeps out + Upon the brook that brawls along this wood: + To the which place a poor sequester'd stag, + That from the hunter's aim had ta'en a hurt, + Did come to languish, and indeed, my lord, + The wretched animal heaved forth such groans + That their discharge did stretch his leathern coat + Almost to bursting, and the big round tears + Coursed one another down his innocent nose + In piteous chase; and thus the hairy fool + Much marked of the melancholy Jaques, + Stood on the extremest verge of the swift brook, + Augmenting it with tears. + +DUKE SENIOR But what said Jaques? + Did he not moralize this spectacle? + +First Lord O, yes, into a thousand similes. + First, for his weeping into the needless stream; + 'Poor deer,' quoth he, 'thou makest a testament + As worldlings do, giving thy sum of more + To that which had too much:' then, being there alone, + Left and abandon'd of his velvet friends, + ''Tis right:' quoth he; 'thus misery doth part + The flux of company:' anon a careless herd, + Full of the pasture, jumps along by him + And never stays to greet him; 'Ay' quoth Jaques, + 'Sweep on, you fat and greasy citizens; + 'Tis just the fashion: wherefore do you look + Upon that poor and broken bankrupt there?' + Thus most invectively he pierceth through + The body of the country, city, court, + Yea, and of this our life, swearing that we + Are mere usurpers, tyrants and what's worse, + To fright the animals and to kill them up + In their assign'd and native dwelling-place. + +DUKE SENIOR And did you leave him in this contemplation? + +Second Lord We did, my lord, weeping and commenting + Upon the sobbing deer. + +DUKE SENIOR Show me the place: + I love to cope him in these sullen fits, + For then he's full of matter. + +First Lord I'll bring you to him straight. + + [Exeunt] + + + + + AS YOU LIKE IT + + +ACT II + + + +SCENE II A room in the palace. + + + [Enter DUKE FREDERICK, with Lords] + +DUKE FREDERICK Can it be possible that no man saw them? + It cannot be: some villains of my court + Are of consent and sufferance in this. + +First Lord I cannot hear of any that did see her. + The ladies, her attendants of her chamber, + Saw her abed, and in the morning early + They found the bed untreasured of their mistress. + +Second Lord My lord, the roynish clown, at whom so oft + Your grace was wont to laugh, is also missing. + Hisperia, the princess' gentlewoman, + Confesses that she secretly o'erheard + Your daughter and her cousin much commend + The parts and graces of the wrestler + That did but lately foil the sinewy Charles; + And she believes, wherever they are gone, + That youth is surely in their company. + +DUKE FREDERICK Send to his brother; fetch that gallant hither; + If he be absent, bring his brother to me; + I'll make him find him: do this suddenly, + And let not search and inquisition quail + To bring again these foolish runaways. + + [Exeunt] + + + + + AS YOU LIKE IT + + +ACT II + + + +SCENE III Before OLIVER'S house. + + + [Enter ORLANDO and ADAM, meeting] + +ORLANDO Who's there? + +ADAM What, my young master? O, my gentle master! + O my sweet master! O you memory + Of old Sir Rowland! why, what make you here? + Why are you virtuous? why do people love you? + And wherefore are you gentle, strong and valiant? + Why would you be so fond to overcome + The bonny priser of the humorous duke? + Your praise is come too swiftly home before you. + Know you not, master, to some kind of men + Their graces serve them but as enemies? + No more do yours: your virtues, gentle master, + Are sanctified and holy traitors to you. + O, what a world is this, when what is comely + Envenoms him that bears it! + +ORLANDO Why, what's the matter? + +ADAM O unhappy youth! + Come not within these doors; within this roof + The enemy of all your graces lives: + Your brother--no, no brother; yet the son-- + Yet not the son, I will not call him son + Of him I was about to call his father-- + Hath heard your praises, and this night he means + To burn the lodging where you use to lie + And you within it: if he fail of that, + He will have other means to cut you off. + I overheard him and his practises. + This is no place; this house is but a butchery: + Abhor it, fear it, do not enter it. + +ORLANDO Why, whither, Adam, wouldst thou have me go? + +ADAM No matter whither, so you come not here. + +ORLANDO What, wouldst thou have me go and beg my food? + Or with a base and boisterous sword enforce + A thievish living on the common road? + This I must do, or know not what to do: + Yet this I will not do, do how I can; + I rather will subject me to the malice + Of a diverted blood and bloody brother. + +ADAM But do not so. I have five hundred crowns, + The thrifty hire I saved under your father, + Which I did store to be my foster-nurse + When service should in my old limbs lie lame + And unregarded age in corners thrown: + Take that, and He that doth the ravens feed, + Yea, providently caters for the sparrow, + Be comfort to my age! Here is the gold; + And all this I give you. Let me be your servant: + Though I look old, yet I am strong and lusty; + For in my youth I never did apply + Hot and rebellious liquors in my blood, + Nor did not with unbashful forehead woo + The means of weakness and debility; + Therefore my age is as a lusty winter, + Frosty, but kindly: let me go with you; + I'll do the service of a younger man + In all your business and necessities. + +ORLANDO O good old man, how well in thee appears + The constant service of the antique world, + When service sweat for duty, not for meed! + Thou art not for the fashion of these times, + Where none will sweat but for promotion, + And having that, do choke their service up + Even with the having: it is not so with thee. + But, poor old man, thou prunest a rotten tree, + That cannot so much as a blossom yield + In lieu of all thy pains and husbandry + But come thy ways; well go along together, + And ere we have thy youthful wages spent, + We'll light upon some settled low content. + +ADAM Master, go on, and I will follow thee, + To the last gasp, with truth and loyalty. + From seventeen years till now almost fourscore + Here lived I, but now live here no more. + At seventeen years many their fortunes seek; + But at fourscore it is too late a week: + Yet fortune cannot recompense me better + Than to die well and not my master's debtor. + + [Exeunt] + + + + + AS YOU LIKE IT + + +ACT II + + + +SCENE IV The Forest of Arden. + + + [Enter ROSALIND for Ganymede, CELIA for Aliena, + and TOUCHSTONE] + +ROSALIND O Jupiter, how weary are my spirits! + +TOUCHSTONE I care not for my spirits, if my legs were not weary. + +ROSALIND I could find in my heart to disgrace my man's + apparel and to cry like a woman; but I must comfort + the weaker vessel, as doublet and hose ought to show + itself courageous to petticoat: therefore courage, + good Aliena! + +CELIA I pray you, bear with me; I cannot go no further. + +TOUCHSTONE For my part, I had rather bear with you than bear + you; yet I should bear no cross if I did bear you, + for I think you have no money in your purse. + +ROSALIND Well, this is the forest of Arden. + +TOUCHSTONE Ay, now am I in Arden; the more fool I; when I was + at home, I was in a better place: but travellers + must be content. + +ROSALIND Ay, be so, good Touchstone. + + [Enter CORIN and SILVIUS] + + Look you, who comes here; a young man and an old in + solemn talk. + +CORIN That is the way to make her scorn you still. + +SILVIUS O Corin, that thou knew'st how I do love her! + +CORIN I partly guess; for I have loved ere now. + +SILVIUS No, Corin, being old, thou canst not guess, + Though in thy youth thou wast as true a lover + As ever sigh'd upon a midnight pillow: + But if thy love were ever like to mine-- + As sure I think did never man love so-- + How many actions most ridiculous + Hast thou been drawn to by thy fantasy? + +CORIN Into a thousand that I have forgotten. + +SILVIUS O, thou didst then ne'er love so heartily! + If thou remember'st not the slightest folly + That ever love did make thee run into, + Thou hast not loved: + Or if thou hast not sat as I do now, + Wearying thy hearer in thy mistress' praise, + Thou hast not loved: + Or if thou hast not broke from company + Abruptly, as my passion now makes me, + Thou hast not loved. + O Phebe, Phebe, Phebe! + + [Exit] + +ROSALIND Alas, poor shepherd! searching of thy wound, + I have by hard adventure found mine own. + +TOUCHSTONE And I mine. I remember, when I was in love I broke + my sword upon a stone and bid him take that for + coming a-night to Jane Smile; and I remember the + kissing of her batlet and the cow's dugs that her + pretty chopt hands had milked; and I remember the + wooing of a peascod instead of her, from whom I took + two cods and, giving her them again, said with + weeping tears 'Wear these for my sake.' We that are + true lovers run into strange capers; but as all is + mortal in nature, so is all nature in love mortal in folly. + +ROSALIND Thou speakest wiser than thou art ware of. + +TOUCHSTONE Nay, I shall ne'er be ware of mine own wit till I + break my shins against it. + +ROSALIND Jove, Jove! this shepherd's passion + Is much upon my fashion. + +TOUCHSTONE And mine; but it grows something stale with me. + +CELIA I pray you, one of you question yond man + If he for gold will give us any food: + I faint almost to death. + +TOUCHSTONE Holla, you clown! + +ROSALIND Peace, fool: he's not thy kinsman. + +CORIN Who calls? + +TOUCHSTONE Your betters, sir. + +CORIN Else are they very wretched. + +ROSALIND Peace, I say. Good even to you, friend. + +CORIN And to you, gentle sir, and to you all. + +ROSALIND I prithee, shepherd, if that love or gold + Can in this desert place buy entertainment, + Bring us where we may rest ourselves and feed: + Here's a young maid with travel much oppress'd + And faints for succor. + +CORIN Fair sir, I pity her + And wish, for her sake more than for mine own, + My fortunes were more able to relieve her; + But I am shepherd to another man + And do not shear the fleeces that I graze: + My master is of churlish disposition + And little recks to find the way to heaven + By doing deeds of hospitality: + Besides, his cote, his flocks and bounds of feed + Are now on sale, and at our sheepcote now, + By reason of his absence, there is nothing + That you will feed on; but what is, come see. + And in my voice most welcome shall you be. + +ROSALIND What is he that shall buy his flock and pasture? + +CORIN That young swain that you saw here but erewhile, + That little cares for buying any thing. + +ROSALIND I pray thee, if it stand with honesty, + Buy thou the cottage, pasture and the flock, + And thou shalt have to pay for it of us. + +CELIA And we will mend thy wages. I like this place. + And willingly could waste my time in it. + +CORIN Assuredly the thing is to be sold: + Go with me: if you like upon report + The soil, the profit and this kind of life, + I will your very faithful feeder be + And buy it with your gold right suddenly. + + [Exeunt] + + + + + AS YOU LIKE IT + + +ACT II + + + +SCENE V The Forest. + + + [Enter AMIENS, JAQUES, and others] + + SONG. +AMIENS Under the greenwood tree + Who loves to lie with me, + And turn his merry note + Unto the sweet bird's throat, + Come hither, come hither, come hither: + Here shall he see No enemy + But winter and rough weather. + +JAQUES More, more, I prithee, more. + +AMIENS It will make you melancholy, Monsieur Jaques. + +JAQUES I thank it. More, I prithee, more. I can suck + melancholy out of a song, as a weasel sucks eggs. + More, I prithee, more. + +AMIENS My voice is ragged: I know I cannot please you. + +JAQUES I do not desire you to please me; I do desire you to + sing. Come, more; another stanzo: call you 'em stanzos? + +AMIENS What you will, Monsieur Jaques. + +JAQUES Nay, I care not for their names; they owe me + nothing. Will you sing? + +AMIENS More at your request than to please myself. + +JAQUES Well then, if ever I thank any man, I'll thank you; + but that they call compliment is like the encounter + of two dog-apes, and when a man thanks me heartily, + methinks I have given him a penny and he renders me + the beggarly thanks. Come, sing; and you that will + not, hold your tongues. + +AMIENS Well, I'll end the song. Sirs, cover the while; the + duke will drink under this tree. He hath been all + this day to look you. + +JAQUES And I have been all this day to avoid him. He is + too disputable for my company: I think of as many + matters as he, but I give heaven thanks and make no + boast of them. Come, warble, come. + + SONG. + Who doth ambition shun + + [All together here] + + And loves to live i' the sun, + Seeking the food he eats + And pleased with what he gets, + Come hither, come hither, come hither: + Here shall he see No enemy + But winter and rough weather. + +JAQUES I'll give you a verse to this note that I made + yesterday in despite of my invention. + +AMIENS And I'll sing it. + +JAQUES Thus it goes:-- + + If it do come to pass + That any man turn ass, + Leaving his wealth and ease, + A stubborn will to please, + Ducdame, ducdame, ducdame: + Here shall he see + Gross fools as he, + An if he will come to me. + +AMIENS What's that 'ducdame'? + +JAQUES 'Tis a Greek invocation, to call fools into a + circle. I'll go sleep, if I can; if I cannot, I'll + rail against all the first-born of Egypt. + +AMIENS And I'll go seek the duke: his banquet is prepared. + + [Exeunt severally] + + + + + AS YOU LIKE IT + + +ACT II + + + +SCENE VI The forest. + + + [Enter ORLANDO and ADAM] + +ADAM Dear master, I can go no further. O, I die for food! + Here lie I down, and measure out my grave. Farewell, + kind master. + +ORLANDO Why, how now, Adam! no greater heart in thee? Live + a little; comfort a little; cheer thyself a little. + If this uncouth forest yield any thing savage, I + will either be food for it or bring it for food to + thee. Thy conceit is nearer death than thy powers. + For my sake be comfortable; hold death awhile at + the arm's end: I will here be with thee presently; + and if I bring thee not something to eat, I will + give thee leave to die: but if thou diest before I + come, thou art a mocker of my labour. Well said! + thou lookest cheerly, and I'll be with thee quickly. + Yet thou liest in the bleak air: come, I will bear + thee to some shelter; and thou shalt not die for + lack of a dinner, if there live any thing in this + desert. Cheerly, good Adam! + + [Exeunt] + + + + + AS YOU LIKE IT + + +ACT II + + + +SCENE VII The forest. + + + [A table set out. Enter DUKE SENIOR, AMIENS, and + Lords like outlaws] + +DUKE SENIOR I think he be transform'd into a beast; + For I can no where find him like a man. + +First Lord My lord, he is but even now gone hence: + Here was he merry, hearing of a song. + +DUKE SENIOR If he, compact of jars, grow musical, + We shall have shortly discord in the spheres. + Go, seek him: tell him I would speak with him. + + [Enter JAQUES] + +First Lord He saves my labour by his own approach. + +DUKE SENIOR Why, how now, monsieur! what a life is this, + That your poor friends must woo your company? + What, you look merrily! + +JAQUES A fool, a fool! I met a fool i' the forest, + A motley fool; a miserable world! + As I do live by food, I met a fool + Who laid him down and bask'd him in the sun, + And rail'd on Lady Fortune in good terms, + In good set terms and yet a motley fool. + 'Good morrow, fool,' quoth I. 'No, sir,' quoth he, + 'Call me not fool till heaven hath sent me fortune:' + And then he drew a dial from his poke, + And, looking on it with lack-lustre eye, + Says very wisely, 'It is ten o'clock: + Thus we may see,' quoth he, 'how the world wags: + 'Tis but an hour ago since it was nine, + And after one hour more 'twill be eleven; + And so, from hour to hour, we ripe and ripe, + And then, from hour to hour, we rot and rot; + And thereby hangs a tale.' When I did hear + The motley fool thus moral on the time, + My lungs began to crow like chanticleer, + That fools should be so deep-contemplative, + And I did laugh sans intermission + An hour by his dial. O noble fool! + A worthy fool! Motley's the only wear. + +DUKE SENIOR What fool is this? + +JAQUES O worthy fool! One that hath been a courtier, + And says, if ladies be but young and fair, + They have the gift to know it: and in his brain, + Which is as dry as the remainder biscuit + After a voyage, he hath strange places cramm'd + With observation, the which he vents + In mangled forms. O that I were a fool! + I am ambitious for a motley coat. + +DUKE SENIOR Thou shalt have one. + +JAQUES It is my only suit; + Provided that you weed your better judgments + Of all opinion that grows rank in them + That I am wise. I must have liberty + Withal, as large a charter as the wind, + To blow on whom I please; for so fools have; + And they that are most galled with my folly, + They most must laugh. And why, sir, must they so? + The 'why' is plain as way to parish church: + He that a fool doth very wisely hit + Doth very foolishly, although he smart, + Not to seem senseless of the bob: if not, + The wise man's folly is anatomized + Even by the squandering glances of the fool. + Invest me in my motley; give me leave + To speak my mind, and I will through and through + Cleanse the foul body of the infected world, + If they will patiently receive my medicine. + +DUKE SENIOR Fie on thee! I can tell what thou wouldst do. + +JAQUES What, for a counter, would I do but good? + +DUKE SENIOR Most mischievous foul sin, in chiding sin: + For thou thyself hast been a libertine, + As sensual as the brutish sting itself; + And all the embossed sores and headed evils, + That thou with licence of free foot hast caught, + Wouldst thou disgorge into the general world. + +JAQUES Why, who cries out on pride, + That can therein tax any private party? + Doth it not flow as hugely as the sea, + Till that the weary very means do ebb? + What woman in the city do I name, + When that I say the city-woman bears + The cost of princes on unworthy shoulders? + Who can come in and say that I mean her, + When such a one as she such is her neighbour? + Or what is he of basest function + That says his bravery is not of my cost, + Thinking that I mean him, but therein suits + His folly to the mettle of my speech? + There then; how then? what then? Let me see wherein + My tongue hath wrong'd him: if it do him right, + Then he hath wrong'd himself; if he be free, + Why then my taxing like a wild-goose flies, + Unclaim'd of any man. But who comes here? + + [Enter ORLANDO, with his sword drawn] + +ORLANDO Forbear, and eat no more. + +JAQUES Why, I have eat none yet. + +ORLANDO Nor shalt not, till necessity be served. + +JAQUES Of what kind should this cock come of? + +DUKE SENIOR Art thou thus bolden'd, man, by thy distress, + Or else a rude despiser of good manners, + That in civility thou seem'st so empty? + +ORLANDO You touch'd my vein at first: the thorny point + Of bare distress hath ta'en from me the show + Of smooth civility: yet am I inland bred + And know some nurture. But forbear, I say: + He dies that touches any of this fruit + Till I and my affairs are answered. + +JAQUES An you will not be answered with reason, I must die. + +DUKE SENIOR What would you have? Your gentleness shall force + More than your force move us to gentleness. + +ORLANDO I almost die for food; and let me have it. + +DUKE SENIOR Sit down and feed, and welcome to our table. + +ORLANDO Speak you so gently? Pardon me, I pray you: + I thought that all things had been savage here; + And therefore put I on the countenance + Of stern commandment. But whate'er you are + That in this desert inaccessible, + Under the shade of melancholy boughs, + Lose and neglect the creeping hours of time + If ever you have look'd on better days, + If ever been where bells have knoll'd to church, + If ever sat at any good man's feast, + If ever from your eyelids wiped a tear + And know what 'tis to pity and be pitied, + Let gentleness my strong enforcement be: + In the which hope I blush, and hide my sword. + +DUKE SENIOR True is it that we have seen better days, + And have with holy bell been knoll'd to church + And sat at good men's feasts and wiped our eyes + Of drops that sacred pity hath engender'd: + And therefore sit you down in gentleness + And take upon command what help we have + That to your wanting may be minister'd. + +ORLANDO Then but forbear your food a little while, + Whiles, like a doe, I go to find my fawn + And give it food. There is an old poor man, + Who after me hath many a weary step + Limp'd in pure love: till he be first sufficed, + Oppress'd with two weak evils, age and hunger, + I will not touch a bit. + +DUKE SENIOR Go find him out, + And we will nothing waste till you return. + +ORLANDO I thank ye; and be blest for your good comfort! + + [Exit] + +DUKE SENIOR Thou seest we are not all alone unhappy: + This wide and universal theatre + Presents more woeful pageants than the scene + Wherein we play in. + +JAQUES All the world's a stage, + And all the men and women merely players: + They have their exits and their entrances; + And one man in his time plays many parts, + His acts being seven ages. At first the infant, + Mewling and puking in the nurse's arms. + And then the whining school-boy, with his satchel + And shining morning face, creeping like snail + Unwillingly to school. And then the lover, + Sighing like furnace, with a woeful ballad + Made to his mistress' eyebrow. Then a soldier, + Full of strange oaths and bearded like the pard, + Jealous in honour, sudden and quick in quarrel, + Seeking the bubble reputation + Even in the cannon's mouth. And then the justice, + In fair round belly with good capon lined, + With eyes severe and beard of formal cut, + Full of wise saws and modern instances; + And so he plays his part. The sixth age shifts + Into the lean and slipper'd pantaloon, + With spectacles on nose and pouch on side, + His youthful hose, well saved, a world too wide + For his shrunk shank; and his big manly voice, + Turning again toward childish treble, pipes + And whistles in his sound. Last scene of all, + That ends this strange eventful history, + Is second childishness and mere oblivion, + Sans teeth, sans eyes, sans taste, sans everything. + + [Re-enter ORLANDO, with ADAM] + +DUKE SENIOR Welcome. Set down your venerable burthen, + And let him feed. + +ORLANDO I thank you most for him. + +ADAM So had you need: + I scarce can speak to thank you for myself. + +DUKE SENIOR Welcome; fall to: I will not trouble you + As yet, to question you about your fortunes. + Give us some music; and, good cousin, sing. + + SONG. +AMIENS Blow, blow, thou winter wind. + Thou art not so unkind + As man's ingratitude; + Thy tooth is not so keen, + Because thou art not seen, + Although thy breath be rude. + Heigh-ho! sing, heigh-ho! unto the green holly: + Most friendship is feigning, most loving mere folly: + Then, heigh-ho, the holly! + This life is most jolly. + Freeze, freeze, thou bitter sky, + That dost not bite so nigh + As benefits forgot: + Though thou the waters warp, + Thy sting is not so sharp + As friend remember'd not. + Heigh-ho! sing, &c. + +DUKE SENIOR If that you were the good Sir Rowland's son, + As you have whisper'd faithfully you were, + And as mine eye doth his effigies witness + Most truly limn'd and living in your face, + Be truly welcome hither: I am the duke + That loved your father: the residue of your fortune, + Go to my cave and tell me. Good old man, + Thou art right welcome as thy master is. + Support him by the arm. Give me your hand, + And let me all your fortunes understand. + + [Exeunt] + + + + + AS YOU LIKE IT + + +ACT III + + + +SCENE I A room in the palace. + + + [Enter DUKE FREDERICK, Lords, and OLIVER] + +DUKE FREDERICK Not see him since? Sir, sir, that cannot be: + But were I not the better part made mercy, + I should not seek an absent argument + Of my revenge, thou present. But look to it: + Find out thy brother, wheresoe'er he is; + Seek him with candle; bring him dead or living + Within this twelvemonth, or turn thou no more + To seek a living in our territory. + Thy lands and all things that thou dost call thine + Worth seizure do we seize into our hands, + Till thou canst quit thee by thy brothers mouth + Of what we think against thee. + +OLIVER O that your highness knew my heart in this! + I never loved my brother in my life. + +DUKE FREDERICK More villain thou. Well, push him out of doors; + And let my officers of such a nature + Make an extent upon his house and lands: + Do this expediently and turn him going. + + [Exeunt] + + + + + AS YOU LIKE IT + + +ACT III + + + +SCENE II The forest. + + + [Enter ORLANDO, with a paper] + +ORLANDO Hang there, my verse, in witness of my love: + And thou, thrice-crowned queen of night, survey + With thy chaste eye, from thy pale sphere above, + Thy huntress' name that my full life doth sway. + O Rosalind! these trees shall be my books + And in their barks my thoughts I'll character; + That every eye which in this forest looks + Shall see thy virtue witness'd every where. + Run, run, Orlando; carve on every tree + The fair, the chaste and unexpressive she. + + [Exit] + + [Enter CORIN and TOUCHSTONE] + +CORIN And how like you this shepherd's life, Master Touchstone? + +TOUCHSTONE Truly, shepherd, in respect of itself, it is a good + life, but in respect that it is a shepherd's life, + it is naught. In respect that it is solitary, I + like it very well; but in respect that it is + private, it is a very vile life. Now, in respect it + is in the fields, it pleaseth me well; but in + respect it is not in the court, it is tedious. As + is it a spare life, look you, it fits my humour well; + but as there is no more plenty in it, it goes much + against my stomach. Hast any philosophy in thee, shepherd? + +CORIN No more but that I know the more one sickens the + worse at ease he is; and that he that wants money, + means and content is without three good friends; + that the property of rain is to wet and fire to + burn; that good pasture makes fat sheep, and that a + great cause of the night is lack of the sun; that + he that hath learned no wit by nature nor art may + complain of good breeding or comes of a very dull kindred. + +TOUCHSTONE Such a one is a natural philosopher. Wast ever in + court, shepherd? + +CORIN No, truly. + +TOUCHSTONE Then thou art damned. + +CORIN Nay, I hope. + +TOUCHSTONE Truly, thou art damned like an ill-roasted egg, all + on one side. + +CORIN For not being at court? Your reason. + +TOUCHSTONE Why, if thou never wast at court, thou never sawest + good manners; if thou never sawest good manners, + then thy manners must be wicked; and wickedness is + sin, and sin is damnation. Thou art in a parlous + state, shepherd. + +CORIN Not a whit, Touchstone: those that are good manners + at the court are as ridiculous in the country as the + behavior of the country is most mockable at the + court. You told me you salute not at the court, but + you kiss your hands: that courtesy would be + uncleanly, if courtiers were shepherds. + +TOUCHSTONE Instance, briefly; come, instance. + +CORIN Why, we are still handling our ewes, and their + fells, you know, are greasy. + +TOUCHSTONE Why, do not your courtier's hands sweat? and is not + the grease of a mutton as wholesome as the sweat of + a man? Shallow, shallow. A better instance, I say; come. + +CORIN Besides, our hands are hard. + +TOUCHSTONE Your lips will feel them the sooner. Shallow again. + A more sounder instance, come. + +CORIN And they are often tarred over with the surgery of + our sheep: and would you have us kiss tar? The + courtier's hands are perfumed with civet. + +TOUCHSTONE Most shallow man! thou worms-meat, in respect of a + good piece of flesh indeed! Learn of the wise, and + perpend: civet is of a baser birth than tar, the + very uncleanly flux of a cat. Mend the instance, shepherd. + +CORIN You have too courtly a wit for me: I'll rest. + +TOUCHSTONE Wilt thou rest damned? God help thee, shallow man! + God make incision in thee! thou art raw. + +CORIN Sir, I am a true labourer: I earn that I eat, get + that I wear, owe no man hate, envy no man's + happiness, glad of other men's good, content with my + harm, and the greatest of my pride is to see my ewes + graze and my lambs suck. + +TOUCHSTONE That is another simple sin in you, to bring the ewes + and the rams together and to offer to get your + living by the copulation of cattle; to be bawd to a + bell-wether, and to betray a she-lamb of a + twelvemonth to a crooked-pated, old, cuckoldly ram, + out of all reasonable match. If thou beest not + damned for this, the devil himself will have no + shepherds; I cannot see else how thou shouldst + 'scape. + +CORIN Here comes young Master Ganymede, my new mistress's brother. + + [Enter ROSALIND, with a paper, reading] + +ROSALIND From the east to western Ind, + No jewel is like Rosalind. + Her worth, being mounted on the wind, + Through all the world bears Rosalind. + All the pictures fairest lined + Are but black to Rosalind. + Let no fair be kept in mind + But the fair of Rosalind. + +TOUCHSTONE I'll rhyme you so eight years together, dinners and + suppers and sleeping-hours excepted: it is the + right butter-women's rank to market. + +ROSALIND Out, fool! + +TOUCHSTONE For a taste: + If a hart do lack a hind, + Let him seek out Rosalind. + If the cat will after kind, + So be sure will Rosalind. + Winter garments must be lined, + So must slender Rosalind. + They that reap must sheaf and bind; + Then to cart with Rosalind. + Sweetest nut hath sourest rind, + Such a nut is Rosalind. + He that sweetest rose will find + Must find love's prick and Rosalind. + This is the very false gallop of verses: why do you + infect yourself with them? + +ROSALIND Peace, you dull fool! I found them on a tree. + +TOUCHSTONE Truly, the tree yields bad fruit. + +ROSALIND I'll graff it with you, and then I shall graff it + with a medlar: then it will be the earliest fruit + i' the country; for you'll be rotten ere you be half + ripe, and that's the right virtue of the medlar. + +TOUCHSTONE You have said; but whether wisely or no, let the + forest judge. + + [Enter CELIA, with a writing] + +ROSALIND Peace! Here comes my sister, reading: stand aside. + +CELIA [Reads] + + Why should this a desert be? + For it is unpeopled? No: + Tongues I'll hang on every tree, + That shall civil sayings show: + Some, how brief the life of man + Runs his erring pilgrimage, + That the stretching of a span + Buckles in his sum of age; + Some, of violated vows + 'Twixt the souls of friend and friend: + But upon the fairest boughs, + Or at every sentence end, + Will I Rosalinda write, + Teaching all that read to know + The quintessence of every sprite + Heaven would in little show. + Therefore Heaven Nature charged + That one body should be fill'd + With all graces wide-enlarged: + Nature presently distill'd + Helen's cheek, but not her heart, + Cleopatra's majesty, + Atalanta's better part, + Sad Lucretia's modesty. + Thus Rosalind of many parts + By heavenly synod was devised, + Of many faces, eyes and hearts, + To have the touches dearest prized. + Heaven would that she these gifts should have, + And I to live and die her slave. + +ROSALIND O most gentle pulpiter! what tedious homily of love + have you wearied your parishioners withal, and never + cried 'Have patience, good people!' + +CELIA How now! back, friends! Shepherd, go off a little. + Go with him, sirrah. + +TOUCHSTONE Come, shepherd, let us make an honourable retreat; + though not with bag and baggage, yet with scrip and scrippage. + + [Exeunt CORIN and TOUCHSTONE] + +CELIA Didst thou hear these verses? + +ROSALIND O, yes, I heard them all, and more too; for some of + them had in them more feet than the verses would bear. + +CELIA That's no matter: the feet might bear the verses. + +ROSALIND Ay, but the feet were lame and could not bear + themselves without the verse and therefore stood + lamely in the verse. + +CELIA But didst thou hear without wondering how thy name + should be hanged and carved upon these trees? + +ROSALIND I was seven of the nine days out of the wonder + before you came; for look here what I found on a + palm-tree. I was never so be-rhymed since + Pythagoras' time, that I was an Irish rat, which I + can hardly remember. + +CELIA Trow you who hath done this? + +ROSALIND Is it a man? + +CELIA And a chain, that you once wore, about his neck. + Change you colour? + +ROSALIND I prithee, who? + +CELIA O Lord, Lord! it is a hard matter for friends to + meet; but mountains may be removed with earthquakes + and so encounter. + +ROSALIND Nay, but who is it? + +CELIA Is it possible? + +ROSALIND Nay, I prithee now with most petitionary vehemence, + tell me who it is. + +CELIA O wonderful, wonderful, and most wonderful + wonderful! and yet again wonderful, and after that, + out of all hooping! + +ROSALIND Good my complexion! dost thou think, though I am + caparisoned like a man, I have a doublet and hose in + my disposition? One inch of delay more is a + South-sea of discovery; I prithee, tell me who is it + quickly, and speak apace. I would thou couldst + stammer, that thou mightst pour this concealed man + out of thy mouth, as wine comes out of a narrow- + mouthed bottle, either too much at once, or none at + all. I prithee, take the cork out of thy mouth that + may drink thy tidings. + +CELIA So you may put a man in your belly. + +ROSALIND Is he of God's making? What manner of man? Is his + head worth a hat, or his chin worth a beard? + +CELIA Nay, he hath but a little beard. + +ROSALIND Why, God will send more, if the man will be + thankful: let me stay the growth of his beard, if + thou delay me not the knowledge of his chin. + +CELIA It is young Orlando, that tripped up the wrestler's + heels and your heart both in an instant. + +ROSALIND Nay, but the devil take mocking: speak, sad brow and + true maid. + +CELIA I' faith, coz, 'tis he. + +ROSALIND Orlando? + +CELIA Orlando. + +ROSALIND Alas the day! what shall I do with my doublet and + hose? What did he when thou sawest him? What said + he? How looked he? Wherein went he? What makes + him here? Did he ask for me? Where remains he? + How parted he with thee? and when shalt thou see + him again? Answer me in one word. + +CELIA You must borrow me Gargantua's mouth first: 'tis a + word too great for any mouth of this age's size. To + say ay and no to these particulars is more than to + answer in a catechism. + +ROSALIND But doth he know that I am in this forest and in + man's apparel? Looks he as freshly as he did the + day he wrestled? + +CELIA It is as easy to count atomies as to resolve the + propositions of a lover; but take a taste of my + finding him, and relish it with good observance. + I found him under a tree, like a dropped acorn. + +ROSALIND It may well be called Jove's tree, when it drops + forth such fruit. + +CELIA Give me audience, good madam. + +ROSALIND Proceed. + +CELIA There lay he, stretched along, like a wounded knight. + +ROSALIND Though it be pity to see such a sight, it well + becomes the ground. + +CELIA Cry 'holla' to thy tongue, I prithee; it curvets + unseasonably. He was furnished like a hunter. + +ROSALIND O, ominous! he comes to kill my heart. + +CELIA I would sing my song without a burden: thou bringest + me out of tune. + +ROSALIND Do you not know I am a woman? when I think, I must + speak. Sweet, say on. + +CELIA You bring me out. Soft! comes he not here? + + [Enter ORLANDO and JAQUES] + +ROSALIND 'Tis he: slink by, and note him. + +JAQUES I thank you for your company; but, good faith, I had + as lief have been myself alone. + +ORLANDO And so had I; but yet, for fashion sake, I thank you + too for your society. + +JAQUES God be wi' you: let's meet as little as we can. + +ORLANDO I do desire we may be better strangers. + +JAQUES I pray you, mar no more trees with writing + love-songs in their barks. + +ORLANDO I pray you, mar no more of my verses with reading + them ill-favouredly. + +JAQUES Rosalind is your love's name? + +ORLANDO Yes, just. + +JAQUES I do not like her name. + +ORLANDO There was no thought of pleasing you when she was + christened. + +JAQUES What stature is she of? + +ORLANDO Just as high as my heart. + +JAQUES You are full of pretty answers. Have you not been + acquainted with goldsmiths' wives, and conned them + out of rings? + +ORLANDO Not so; but I answer you right painted cloth, from + whence you have studied your questions. + +JAQUES You have a nimble wit: I think 'twas made of + Atalanta's heels. Will you sit down with me? and + we two will rail against our mistress the world and + all our misery. + +ORLANDO I will chide no breather in the world but myself, + against whom I know most faults. + +JAQUES The worst fault you have is to be in love. + +ORLANDO 'Tis a fault I will not change for your best virtue. + I am weary of you. + +JAQUES By my troth, I was seeking for a fool when I found + you. + +ORLANDO He is drowned in the brook: look but in, and you + shall see him. + +JAQUES There I shall see mine own figure. + +ORLANDO Which I take to be either a fool or a cipher. + +JAQUES I'll tarry no longer with you: farewell, good + Signior Love. + +ORLANDO I am glad of your departure: adieu, good Monsieur + Melancholy. + + [Exit JAQUES] + +ROSALIND [Aside to CELIA] I will speak to him, like a saucy + lackey and under that habit play the knave with him. + Do you hear, forester? + +ORLANDO Very well: what would you? + +ROSALIND I pray you, what is't o'clock? + +ORLANDO You should ask me what time o' day: there's no clock + in the forest. + +ROSALIND Then there is no true lover in the forest; else + sighing every minute and groaning every hour would + detect the lazy foot of Time as well as a clock. + +ORLANDO And why not the swift foot of Time? had not that + been as proper? + +ROSALIND By no means, sir: Time travels in divers paces with + divers persons. I'll tell you who Time ambles + withal, who Time trots withal, who Time gallops + withal and who he stands still withal. + +ORLANDO I prithee, who doth he trot withal? + +ROSALIND Marry, he trots hard with a young maid between the + contract of her marriage and the day it is + solemnized: if the interim be but a se'nnight, + Time's pace is so hard that it seems the length of + seven year. + +ORLANDO Who ambles Time withal? + +ROSALIND With a priest that lacks Latin and a rich man that + hath not the gout, for the one sleeps easily because + he cannot study, and the other lives merrily because + he feels no pain, the one lacking the burden of lean + and wasteful learning, the other knowing no burden + of heavy tedious penury; these Time ambles withal. + +ORLANDO Who doth he gallop withal? + +ROSALIND With a thief to the gallows, for though he go as + softly as foot can fall, he thinks himself too soon there. + +ORLANDO Who stays it still withal? + +ROSALIND With lawyers in the vacation, for they sleep between + term and term and then they perceive not how Time moves. + +ORLANDO Where dwell you, pretty youth? + +ROSALIND With this shepherdess, my sister; here in the + skirts of the forest, like fringe upon a petticoat. + +ORLANDO Are you native of this place? + +ROSALIND As the cony that you see dwell where she is kindled. + +ORLANDO Your accent is something finer than you could + purchase in so removed a dwelling. + +ROSALIND I have been told so of many: but indeed an old + religious uncle of mine taught me to speak, who was + in his youth an inland man; one that knew courtship + too well, for there he fell in love. I have heard + him read many lectures against it, and I thank God + I am not a woman, to be touched with so many + giddy offences as he hath generally taxed their + whole sex withal. + +ORLANDO Can you remember any of the principal evils that he + laid to the charge of women? + +ROSALIND There were none principal; they were all like one + another as half-pence are, every one fault seeming + monstrous till his fellow fault came to match it. + +ORLANDO I prithee, recount some of them. + +ROSALIND No, I will not cast away my physic but on those that + are sick. There is a man haunts the forest, that + abuses our young plants with carving 'Rosalind' on + their barks; hangs odes upon hawthorns and elegies + on brambles, all, forsooth, deifying the name of + Rosalind: if I could meet that fancy-monger I would + give him some good counsel, for he seems to have the + quotidian of love upon him. + +ORLANDO I am he that is so love-shaked: I pray you tell me + your remedy. + +ROSALIND There is none of my uncle's marks upon you: he + taught me how to know a man in love; in which cage + of rushes I am sure you are not prisoner. + +ORLANDO What were his marks? + +ROSALIND A lean cheek, which you have not, a blue eye and + sunken, which you have not, an unquestionable + spirit, which you have not, a beard neglected, + which you have not; but I pardon you for that, for + simply your having in beard is a younger brother's + revenue: then your hose should be ungartered, your + bonnet unbanded, your sleeve unbuttoned, your shoe + untied and every thing about you demonstrating a + careless desolation; but you are no such man; you + are rather point-device in your accoutrements as + loving yourself than seeming the lover of any other. + +ORLANDO Fair youth, I would I could make thee believe I love. + +ROSALIND Me believe it! you may as soon make her that you + love believe it; which, I warrant, she is apter to + do than to confess she does: that is one of the + points in the which women still give the lie to + their consciences. But, in good sooth, are you he + that hangs the verses on the trees, wherein Rosalind + is so admired? + +ORLANDO I swear to thee, youth, by the white hand of + Rosalind, I am that he, that unfortunate he. + +ROSALIND But are you so much in love as your rhymes speak? + +ORLANDO Neither rhyme nor reason can express how much. + +ROSALIND Love is merely a madness, and, I tell you, deserves + as well a dark house and a whip as madmen do: and + the reason why they are not so punished and cured + is, that the lunacy is so ordinary that the whippers + are in love too. Yet I profess curing it by counsel. + +ORLANDO Did you ever cure any so? + +ROSALIND Yes, one, and in this manner. He was to imagine me + his love, his mistress; and I set him every day to + woo me: at which time would I, being but a moonish + youth, grieve, be effeminate, changeable, longing + and liking, proud, fantastical, apish, shallow, + inconstant, full of tears, full of smiles, for every + passion something and for no passion truly any + thing, as boys and women are for the most part + cattle of this colour; would now like him, now loathe + him; then entertain him, then forswear him; now weep + for him, then spit at him; that I drave my suitor + from his mad humour of love to a living humour of + madness; which was, to forswear the full stream of + the world, and to live in a nook merely monastic. + And thus I cured him; and this way will I take upon + me to wash your liver as clean as a sound sheep's + heart, that there shall not be one spot of love in't. + +ORLANDO I would not be cured, youth. + +ROSALIND I would cure you, if you would but call me Rosalind + and come every day to my cote and woo me. + +ORLANDO Now, by the faith of my love, I will: tell me + where it is. + +ROSALIND Go with me to it and I'll show it you and by the way + you shall tell me where in the forest you live. + Will you go? + +ORLANDO With all my heart, good youth. + +ROSALIND Nay you must call me Rosalind. Come, sister, will you go? + + [Exeunt] + + + + + AS YOU LIKE IT + + +ACT III + + + +SCENE III The forest. + + + [Enter TOUCHSTONE and AUDREY; JAQUES behind] + +TOUCHSTONE Come apace, good Audrey: I will fetch up your + goats, Audrey. And how, Audrey? am I the man yet? + doth my simple feature content you? + +AUDREY Your features! Lord warrant us! what features! + +TOUCHSTONE I am here with thee and thy goats, as the most + capricious poet, honest Ovid, was among the Goths. + +JAQUES [Aside] O knowledge ill-inhabited, worse than Jove + in a thatched house! + +TOUCHSTONE When a man's verses cannot be understood, nor a + man's good wit seconded with the forward child + Understanding, it strikes a man more dead than a + great reckoning in a little room. Truly, I would + the gods had made thee poetical. + +AUDREY I do not know what 'poetical' is: is it honest in + deed and word? is it a true thing? + +TOUCHSTONE No, truly; for the truest poetry is the most + feigning; and lovers are given to poetry, and what + they swear in poetry may be said as lovers they do feign. + +AUDREY Do you wish then that the gods had made me poetical? + +TOUCHSTONE I do, truly; for thou swearest to me thou art + honest: now, if thou wert a poet, I might have some + hope thou didst feign. + +AUDREY Would you not have me honest? + +TOUCHSTONE No, truly, unless thou wert hard-favoured; for + honesty coupled to beauty is to have honey a sauce to sugar. + +JAQUES [Aside] A material fool! + +AUDREY Well, I am not fair; and therefore I pray the gods + make me honest. + +TOUCHSTONE Truly, and to cast away honesty upon a foul slut + were to put good meat into an unclean dish. + +AUDREY I am not a slut, though I thank the gods I am foul. + +TOUCHSTONE Well, praised be the gods for thy foulness! + sluttishness may come hereafter. But be it as it may + be, I will marry thee, and to that end I have been + with Sir Oliver Martext, the vicar of the next + village, who hath promised to meet me in this place + of the forest and to couple us. + +JAQUES [Aside] I would fain see this meeting. + +AUDREY Well, the gods give us joy! + +TOUCHSTONE Amen. A man may, if he were of a fearful heart, + stagger in this attempt; for here we have no temple + but the wood, no assembly but horn-beasts. But what + though? Courage! As horns are odious, they are + necessary. It is said, 'many a man knows no end of + his goods:' right; many a man has good horns, and + knows no end of them. Well, that is the dowry of + his wife; 'tis none of his own getting. Horns? + Even so. Poor men alone? No, no; the noblest deer + hath them as huge as the rascal. Is the single man + therefore blessed? No: as a walled town is more + worthier than a village, so is the forehead of a + married man more honourable than the bare brow of a + bachelor; and by how much defence is better than no + skill, by so much is a horn more precious than to + want. Here comes Sir Oliver. + + [Enter SIR OLIVER MARTEXT] + + Sir Oliver Martext, you are well met: will you + dispatch us here under this tree, or shall we go + with you to your chapel? + +SIR OLIVER MARTEXT Is there none here to give the woman? + +TOUCHSTONE I will not take her on gift of any man. + +SIR OLIVER MARTEXT Truly, she must be given, or the marriage is not lawful. + +JAQUES [Advancing] + + Proceed, proceed I'll give her. + +TOUCHSTONE Good even, good Master What-ye-call't: how do you, + sir? You are very well met: God 'ild you for your + last company: I am very glad to see you: even a + toy in hand here, sir: nay, pray be covered. + +JAQUES Will you be married, motley? + +TOUCHSTONE As the ox hath his bow, sir, the horse his curb and + the falcon her bells, so man hath his desires; and + as pigeons bill, so wedlock would be nibbling. + +JAQUES And will you, being a man of your breeding, be + married under a bush like a beggar? Get you to + church, and have a good priest that can tell you + what marriage is: this fellow will but join you + together as they join wainscot; then one of you will + prove a shrunk panel and, like green timber, warp, warp. + +TOUCHSTONE [Aside] I am not in the mind but I were better to be + married of him than of another: for he is not like + to marry me well; and not being well married, it + will be a good excuse for me hereafter to leave my wife. + +JAQUES Go thou with me, and let me counsel thee. + +TOUCHSTONE 'Come, sweet Audrey: + We must be married, or we must live in bawdry. + Farewell, good Master Oliver: not,-- + O sweet Oliver, + O brave Oliver, + Leave me not behind thee: but,-- + Wind away, + Begone, I say, + I will not to wedding with thee. + + [Exeunt JAQUES, TOUCHSTONE and AUDREY] + +SIR OLIVER MARTEXT 'Tis no matter: ne'er a fantastical knave of them + all shall flout me out of my calling. + + [Exit] + + + + + AS YOU LIKE IT + + +ACT III + + + +SCENE IV The forest. + + + [Enter ROSALIND and CELIA] + +ROSALIND Never talk to me; I will weep. + +CELIA Do, I prithee; but yet have the grace to consider + that tears do not become a man. + +ROSALIND But have I not cause to weep? + +CELIA As good cause as one would desire; therefore weep. + +ROSALIND His very hair is of the dissembling colour. + +CELIA Something browner than Judas's marry, his kisses are + Judas's own children. + +ROSALIND I' faith, his hair is of a good colour. + +CELIA An excellent colour: your chestnut was ever the only colour. + +ROSALIND And his kissing is as full of sanctity as the touch + of holy bread. + +CELIA He hath bought a pair of cast lips of Diana: a nun + of winter's sisterhood kisses not more religiously; + the very ice of chastity is in them. + +ROSALIND But why did he swear he would come this morning, and + comes not? + +CELIA Nay, certainly, there is no truth in him. + +ROSALIND Do you think so? + +CELIA Yes; I think he is not a pick-purse nor a + horse-stealer, but for his verity in love, I do + think him as concave as a covered goblet or a + worm-eaten nut. + +ROSALIND Not true in love? + +CELIA Yes, when he is in; but I think he is not in. + +ROSALIND You have heard him swear downright he was. + +CELIA 'Was' is not 'is:' besides, the oath of a lover is + no stronger than the word of a tapster; they are + both the confirmer of false reckonings. He attends + here in the forest on the duke your father. + +ROSALIND I met the duke yesterday and had much question with + him: he asked me of what parentage I was; I told + him, of as good as he; so he laughed and let me go. + But what talk we of fathers, when there is such a + man as Orlando? + +CELIA O, that's a brave man! he writes brave verses, + speaks brave words, swears brave oaths and breaks + them bravely, quite traverse, athwart the heart of + his lover; as a puisny tilter, that spurs his horse + but on one side, breaks his staff like a noble + goose: but all's brave that youth mounts and folly + guides. Who comes here? + + [Enter CORIN] + +CORIN Mistress and master, you have oft inquired + After the shepherd that complain'd of love, + Who you saw sitting by me on the turf, + Praising the proud disdainful shepherdess + That was his mistress. + +CELIA Well, and what of him? + +CORIN If you will see a pageant truly play'd, + Between the pale complexion of true love + And the red glow of scorn and proud disdain, + Go hence a little and I shall conduct you, + If you will mark it. + +ROSALIND O, come, let us remove: + The sight of lovers feedeth those in love. + Bring us to this sight, and you shall say + I'll prove a busy actor in their play. + + [Exeunt] + + + + + AS YOU LIKE IT + + +ACT III + + + +SCENE V Another part of the forest. + + + [Enter SILVIUS and PHEBE] + +SILVIUS Sweet Phebe, do not scorn me; do not, Phebe; + Say that you love me not, but say not so + In bitterness. The common executioner, + Whose heart the accustom'd sight of death makes hard, + Falls not the axe upon the humbled neck + But first begs pardon: will you sterner be + Than he that dies and lives by bloody drops? + + [Enter ROSALIND, CELIA, and CORIN, behind] + +PHEBE I would not be thy executioner: + I fly thee, for I would not injure thee. + Thou tell'st me there is murder in mine eye: + 'Tis pretty, sure, and very probable, + That eyes, that are the frail'st and softest things, + Who shut their coward gates on atomies, + Should be call'd tyrants, butchers, murderers! + Now I do frown on thee with all my heart; + And if mine eyes can wound, now let them kill thee: + Now counterfeit to swoon; why now fall down; + Or if thou canst not, O, for shame, for shame, + Lie not, to say mine eyes are murderers! + Now show the wound mine eye hath made in thee: + Scratch thee but with a pin, and there remains + Some scar of it; lean but upon a rush, + The cicatrice and capable impressure + Thy palm some moment keeps; but now mine eyes, + Which I have darted at thee, hurt thee not, + Nor, I am sure, there is no force in eyes + That can do hurt. + +SILVIUS O dear Phebe, + If ever,--as that ever may be near,-- + You meet in some fresh cheek the power of fancy, + Then shall you know the wounds invisible + That love's keen arrows make. + +PHEBE But till that time + Come not thou near me: and when that time comes, + Afflict me with thy mocks, pity me not; + As till that time I shall not pity thee. + +ROSALIND And why, I pray you? Who might be your mother, + That you insult, exult, and all at once, + Over the wretched? What though you have no beauty,-- + As, by my faith, I see no more in you + Than without candle may go dark to bed-- + Must you be therefore proud and pitiless? + Why, what means this? Why do you look on me? + I see no more in you than in the ordinary + Of nature's sale-work. 'Od's my little life, + I think she means to tangle my eyes too! + No, faith, proud mistress, hope not after it: + 'Tis not your inky brows, your black silk hair, + Your bugle eyeballs, nor your cheek of cream, + That can entame my spirits to your worship. + You foolish shepherd, wherefore do you follow her, + Like foggy south puffing with wind and rain? + You are a thousand times a properer man + Than she a woman: 'tis such fools as you + That makes the world full of ill-favour'd children: + 'Tis not her glass, but you, that flatters her; + And out of you she sees herself more proper + Than any of her lineaments can show her. + But, mistress, know yourself: down on your knees, + And thank heaven, fasting, for a good man's love: + For I must tell you friendly in your ear, + Sell when you can: you are not for all markets: + Cry the man mercy; love him; take his offer: + Foul is most foul, being foul to be a scoffer. + So take her to thee, shepherd: fare you well. + +PHEBE Sweet youth, I pray you, chide a year together: + I had rather hear you chide than this man woo. + +ROSALIND He's fallen in love with your foulness and she'll + fall in love with my anger. If it be so, as fast as + she answers thee with frowning looks, I'll sauce her + with bitter words. Why look you so upon me? + +PHEBE For no ill will I bear you. + +ROSALIND I pray you, do not fall in love with me, + For I am falser than vows made in wine: + Besides, I like you not. If you will know my house, + 'Tis at the tuft of olives here hard by. + Will you go, sister? Shepherd, ply her hard. + Come, sister. Shepherdess, look on him better, + And be not proud: though all the world could see, + None could be so abused in sight as he. + Come, to our flock. + + [Exeunt ROSALIND, CELIA and CORIN] + +PHEBE Dead Shepherd, now I find thy saw of might, + 'Who ever loved that loved not at first sight?' + +SILVIUS Sweet Phebe,-- + +PHEBE Ha, what say'st thou, Silvius? + +SILVIUS Sweet Phebe, pity me. + +PHEBE Why, I am sorry for thee, gentle Silvius. + +SILVIUS Wherever sorrow is, relief would be: + If you do sorrow at my grief in love, + By giving love your sorrow and my grief + Were both extermined. + +PHEBE Thou hast my love: is not that neighbourly? + +SILVIUS I would have you. + +PHEBE Why, that were covetousness. + Silvius, the time was that I hated thee, + And yet it is not that I bear thee love; + But since that thou canst talk of love so well, + Thy company, which erst was irksome to me, + I will endure, and I'll employ thee too: + But do not look for further recompense + Than thine own gladness that thou art employ'd. + +SILVIUS So holy and so perfect is my love, + And I in such a poverty of grace, + That I shall think it a most plenteous crop + To glean the broken ears after the man + That the main harvest reaps: loose now and then + A scatter'd smile, and that I'll live upon. + +PHEBE Know'st now the youth that spoke to me erewhile? + +SILVIUS Not very well, but I have met him oft; + And he hath bought the cottage and the bounds + That the old carlot once was master of. + +PHEBE Think not I love him, though I ask for him: + 'Tis but a peevish boy; yet he talks well; + But what care I for words? yet words do well + When he that speaks them pleases those that hear. + It is a pretty youth: not very pretty: + But, sure, he's proud, and yet his pride becomes him: + He'll make a proper man: the best thing in him + Is his complexion; and faster than his tongue + Did make offence his eye did heal it up. + He is not very tall; yet for his years he's tall: + His leg is but so so; and yet 'tis well: + There was a pretty redness in his lip, + A little riper and more lusty red + Than that mix'd in his cheek; 'twas just the difference + Between the constant red and mingled damask. + There be some women, Silvius, had they mark'd him + In parcels as I did, would have gone near + To fall in love with him; but, for my part, + I love him not nor hate him not; and yet + I have more cause to hate him than to love him: + For what had he to do to chide at me? + He said mine eyes were black and my hair black: + And, now I am remember'd, scorn'd at me: + I marvel why I answer'd not again: + But that's all one; omittance is no quittance. + I'll write to him a very taunting letter, + And thou shalt bear it: wilt thou, Silvius? + +SILVIUS Phebe, with all my heart. + +PHEBE I'll write it straight; + The matter's in my head and in my heart: + I will be bitter with him and passing short. + Go with me, Silvius. + + [Exeunt] + + + + + AS YOU LIKE IT + + +ACT IV + + + +SCENE I The forest. + + + [Enter ROSALIND, CELIA, and JAQUES] + +JAQUES I prithee, pretty youth, let me be better acquainted + with thee. + +ROSALIND They say you are a melancholy fellow. + +JAQUES I am so; I do love it better than laughing. + +ROSALIND Those that are in extremity of either are abominable + fellows and betray themselves to every modern + censure worse than drunkards. + +JAQUES Why, 'tis good to be sad and say nothing. + +ROSALIND Why then, 'tis good to be a post. + +JAQUES I have neither the scholar's melancholy, which is + emulation, nor the musician's, which is fantastical, + nor the courtier's, which is proud, nor the + soldier's, which is ambitious, nor the lawyer's, + which is politic, nor the lady's, which is nice, nor + the lover's, which is all these: but it is a + melancholy of mine own, compounded of many simples, + extracted from many objects, and indeed the sundry's + contemplation of my travels, in which my often + rumination wraps me m a most humorous sadness. + +ROSALIND A traveller! By my faith, you have great reason to + be sad: I fear you have sold your own lands to see + other men's; then, to have seen much and to have + nothing, is to have rich eyes and poor hands. + +JAQUES Yes, I have gained my experience. + +ROSALIND And your experience makes you sad: I had rather have + a fool to make me merry than experience to make me + sad; and to travel for it too! + + [Enter ORLANDO] + +ORLANDO Good day and happiness, dear Rosalind! + +JAQUES Nay, then, God be wi' you, an you talk in blank verse. + + [Exit] + +ROSALIND Farewell, Monsieur Traveller: look you lisp and + wear strange suits, disable all the benefits of your + own country, be out of love with your nativity and + almost chide God for making you that countenance you + are, or I will scarce think you have swam in a + gondola. Why, how now, Orlando! where have you been + all this while? You a lover! An you serve me such + another trick, never come in my sight more. + +ORLANDO My fair Rosalind, I come within an hour of my promise. + +ROSALIND Break an hour's promise in love! He that will + divide a minute into a thousand parts and break but + a part of the thousandth part of a minute in the + affairs of love, it may be said of him that Cupid + hath clapped him o' the shoulder, but I'll warrant + him heart-whole. + +ORLANDO Pardon me, dear Rosalind. + +ROSALIND Nay, an you be so tardy, come no more in my sight: I + had as lief be wooed of a snail. + +ORLANDO Of a snail? + +ROSALIND Ay, of a snail; for though he comes slowly, he + carries his house on his head; a better jointure, + I think, than you make a woman: besides he brings + his destiny with him. + +ORLANDO What's that? + +ROSALIND Why, horns, which such as you are fain to be + beholding to your wives for: but he comes armed in + his fortune and prevents the slander of his wife. + +ORLANDO Virtue is no horn-maker; and my Rosalind is virtuous. + +ROSALIND And I am your Rosalind. + +CELIA It pleases him to call you so; but he hath a + Rosalind of a better leer than you. + +ROSALIND Come, woo me, woo me, for now I am in a holiday + humour and like enough to consent. What would you + say to me now, an I were your very very Rosalind? + +ORLANDO I would kiss before I spoke. + +ROSALIND Nay, you were better speak first, and when you were + gravelled for lack of matter, you might take + occasion to kiss. Very good orators, when they are + out, they will spit; and for lovers lacking--God + warn us!--matter, the cleanliest shift is to kiss. + +ORLANDO How if the kiss be denied? + +ROSALIND Then she puts you to entreaty, and there begins new matter. + +ORLANDO Who could be out, being before his beloved mistress? + +ROSALIND Marry, that should you, if I were your mistress, or + I should think my honesty ranker than my wit. + +ORLANDO What, of my suit? + +ROSALIND Not out of your apparel, and yet out of your suit. + Am not I your Rosalind? + +ORLANDO I take some joy to say you are, because I would be + talking of her. + +ROSALIND Well in her person I say I will not have you. + +ORLANDO Then in mine own person I die. + +ROSALIND No, faith, die by attorney. The poor world is + almost six thousand years old, and in all this time + there was not any man died in his own person, + videlicit, in a love-cause. Troilus had his brains + dashed out with a Grecian club; yet he did what he + could to die before, and he is one of the patterns + of love. Leander, he would have lived many a fair + year, though Hero had turned nun, if it had not been + for a hot midsummer night; for, good youth, he went + but forth to wash him in the Hellespont and being + taken with the cramp was drowned and the foolish + coroners of that age found it was 'Hero of Sestos.' + But these are all lies: men have died from time to + time and worms have eaten them, but not for love. + +ORLANDO I would not have my right Rosalind of this mind, + for, I protest, her frown might kill me. + +ROSALIND By this hand, it will not kill a fly. But come, now + I will be your Rosalind in a more coming-on + disposition, and ask me what you will. I will grant + it. + +ORLANDO Then love me, Rosalind. + +ROSALIND Yes, faith, will I, Fridays and Saturdays and all. + +ORLANDO And wilt thou have me? + +ROSALIND Ay, and twenty such. + +ORLANDO What sayest thou? + +ROSALIND Are you not good? + +ORLANDO I hope so. + +ROSALIND Why then, can one desire too much of a good thing? + Come, sister, you shall be the priest and marry us. + Give me your hand, Orlando. What do you say, sister? + +ORLANDO Pray thee, marry us. + +CELIA I cannot say the words. + +ROSALIND You must begin, 'Will you, Orlando--' + +CELIA Go to. Will you, Orlando, have to wife this Rosalind? + +ORLANDO I will. + +ROSALIND Ay, but when? + +ORLANDO Why now; as fast as she can marry us. + +ROSALIND Then you must say 'I take thee, Rosalind, for wife.' + +ORLANDO I take thee, Rosalind, for wife. + +ROSALIND I might ask you for your commission; but I do take + thee, Orlando, for my husband: there's a girl goes + before the priest; and certainly a woman's thought + runs before her actions. + +ORLANDO So do all thoughts; they are winged. + +ROSALIND Now tell me how long you would have her after you + have possessed her. + +ORLANDO For ever and a day. + +ROSALIND Say 'a day,' without the 'ever.' No, no, Orlando; + men are April when they woo, December when they wed: + maids are May when they are maids, but the sky + changes when they are wives. I will be more jealous + of thee than a Barbary cock-pigeon over his hen, + more clamorous than a parrot against rain, more + new-fangled than an ape, more giddy in my desires + than a monkey: I will weep for nothing, like Diana + in the fountain, and I will do that when you are + disposed to be merry; I will laugh like a hyen, and + that when thou art inclined to sleep. + +ORLANDO But will my Rosalind do so? + +ROSALIND By my life, she will do as I do. + +ORLANDO O, but she is wise. + +ROSALIND Or else she could not have the wit to do this: the + wiser, the waywarder: make the doors upon a woman's + wit and it will out at the casement; shut that and + 'twill out at the key-hole; stop that, 'twill fly + with the smoke out at the chimney. + +ORLANDO A man that had a wife with such a wit, he might say + 'Wit, whither wilt?' + +ROSALIND Nay, you might keep that cheque for it till you met + your wife's wit going to your neighbour's bed. + +ORLANDO And what wit could wit have to excuse that? + +ROSALIND Marry, to say she came to seek you there. You shall + never take her without her answer, unless you take + her without her tongue. O, that woman that cannot + make her fault her husband's occasion, let her + never nurse her child herself, for she will breed + it like a fool! + +ORLANDO For these two hours, Rosalind, I will leave thee. + +ROSALIND Alas! dear love, I cannot lack thee two hours. + +ORLANDO I must attend the duke at dinner: by two o'clock I + will be with thee again. + +ROSALIND Ay, go your ways, go your ways; I knew what you + would prove: my friends told me as much, and I + thought no less: that flattering tongue of yours + won me: 'tis but one cast away, and so, come, + death! Two o'clock is your hour? + +ORLANDO Ay, sweet Rosalind. + +ROSALIND By my troth, and in good earnest, and so God mend + me, and by all pretty oaths that are not dangerous, + if you break one jot of your promise or come one + minute behind your hour, I will think you the most + pathetical break-promise and the most hollow lover + and the most unworthy of her you call Rosalind that + may be chosen out of the gross band of the + unfaithful: therefore beware my censure and keep + your promise. + +ORLANDO With no less religion than if thou wert indeed my + Rosalind: so adieu. + +ROSALIND Well, Time is the old justice that examines all such + offenders, and let Time try: adieu. + + [Exit ORLANDO] + +CELIA You have simply misused our sex in your love-prate: + we must have your doublet and hose plucked over your + head, and show the world what the bird hath done to + her own nest. + +ROSALIND O coz, coz, coz, my pretty little coz, that thou + didst know how many fathom deep I am in love! But + it cannot be sounded: my affection hath an unknown + bottom, like the bay of Portugal. + +CELIA Or rather, bottomless, that as fast as you pour + affection in, it runs out. + +ROSALIND No, that same wicked bastard of Venus that was begot + of thought, conceived of spleen and born of madness, + that blind rascally boy that abuses every one's eyes + because his own are out, let him be judge how deep I + am in love. I'll tell thee, Aliena, I cannot be out + of the sight of Orlando: I'll go find a shadow and + sigh till he come. + +CELIA And I'll sleep. + + [Exeunt] + + + + + AS YOU LIKE IT + + +ACT IV + + + +SCENE II The forest. + + + [Enter JAQUES, Lords, and Foresters] + +JAQUES Which is he that killed the deer? + +A Lord Sir, it was I. + +JAQUES Let's present him to the duke, like a Roman + conqueror; and it would do well to set the deer's + horns upon his head, for a branch of victory. Have + you no song, forester, for this purpose? + +Forester Yes, sir. + +JAQUES Sing it: 'tis no matter how it be in tune, so it + make noise enough. + + SONG. +Forester What shall he have that kill'd the deer? + His leather skin and horns to wear. + Then sing him home; + + [The rest shall bear this burden] + + Take thou no scorn to wear the horn; + It was a crest ere thou wast born: + Thy father's father wore it, + And thy father bore it: + The horn, the horn, the lusty horn + Is not a thing to laugh to scorn. + + [Exeunt] + + + + + AS YOU LIKE IT + + +ACT IV + + + +SCENE III The forest. + + + [Enter ROSALIND and CELIA] + +ROSALIND How say you now? Is it not past two o'clock? and + here much Orlando! + +CELIA I warrant you, with pure love and troubled brain, he + hath ta'en his bow and arrows and is gone forth to + sleep. Look, who comes here. + + [Enter SILVIUS] + +SILVIUS My errand is to you, fair youth; + My gentle Phebe bid me give you this: + I know not the contents; but, as I guess + By the stern brow and waspish action + Which she did use as she was writing of it, + It bears an angry tenor: pardon me: + I am but as a guiltless messenger. + +ROSALIND Patience herself would startle at this letter + And play the swaggerer; bear this, bear all: + She says I am not fair, that I lack manners; + She calls me proud, and that she could not love me, + Were man as rare as phoenix. 'Od's my will! + Her love is not the hare that I do hunt: + Why writes she so to me? Well, shepherd, well, + This is a letter of your own device. + +SILVIUS No, I protest, I know not the contents: + Phebe did write it. + +ROSALIND Come, come, you are a fool + And turn'd into the extremity of love. + I saw her hand: she has a leathern hand. + A freestone-colour'd hand; I verily did think + That her old gloves were on, but 'twas her hands: + She has a huswife's hand; but that's no matter: + I say she never did invent this letter; + This is a man's invention and his hand. + +SILVIUS Sure, it is hers. + +ROSALIND Why, 'tis a boisterous and a cruel style. + A style for-challengers; why, she defies me, + Like Turk to Christian: women's gentle brain + Could not drop forth such giant-rude invention + Such Ethiope words, blacker in their effect + Than in their countenance. Will you hear the letter? + +SILVIUS So please you, for I never heard it yet; + Yet heard too much of Phebe's cruelty. + +ROSALIND She Phebes me: mark how the tyrant writes. + + [Reads] + + Art thou god to shepherd turn'd, + That a maiden's heart hath burn'd? + Can a woman rail thus? + +SILVIUS Call you this railing? + +ROSALIND [Reads] + + Why, thy godhead laid apart, + Warr'st thou with a woman's heart? + Did you ever hear such railing? + Whiles the eye of man did woo me, + That could do no vengeance to me. + Meaning me a beast. + If the scorn of your bright eyne + Have power to raise such love in mine, + Alack, in me what strange effect + Would they work in mild aspect! + Whiles you chid me, I did love; + How then might your prayers move! + He that brings this love to thee + Little knows this love in me: + And by him seal up thy mind; + Whether that thy youth and kind + Will the faithful offer take + Of me and all that I can make; + Or else by him my love deny, + And then I'll study how to die. + +SILVIUS Call you this chiding? + +CELIA Alas, poor shepherd! + +ROSALIND Do you pity him? no, he deserves no pity. Wilt + thou love such a woman? What, to make thee an + instrument and play false strains upon thee! not to + be endured! Well, go your way to her, for I see + love hath made thee a tame snake, and say this to + her: that if she love me, I charge her to love + thee; if she will not, I will never have her unless + thou entreat for her. If you be a true lover, + hence, and not a word; for here comes more company. + + [Exit SILVIUS] + + [Enter OLIVER] + +OLIVER Good morrow, fair ones: pray you, if you know, + Where in the purlieus of this forest stands + A sheep-cote fenced about with olive trees? + +CELIA West of this place, down in the neighbour bottom: + The rank of osiers by the murmuring stream + Left on your right hand brings you to the place. + But at this hour the house doth keep itself; + There's none within. + +OLIVER If that an eye may profit by a tongue, + Then should I know you by description; + Such garments and such years: 'The boy is fair, + Of female favour, and bestows himself + Like a ripe sister: the woman low + And browner than her brother.' Are not you + The owner of the house I did inquire for? + +CELIA It is no boast, being ask'd, to say we are. + +OLIVER Orlando doth commend him to you both, + And to that youth he calls his Rosalind + He sends this bloody napkin. Are you he? + +ROSALIND I am: what must we understand by this? + +OLIVER Some of my shame; if you will know of me + What man I am, and how, and why, and where + This handkercher was stain'd. + +CELIA I pray you, tell it. + +OLIVER When last the young Orlando parted from you + He left a promise to return again + Within an hour, and pacing through the forest, + Chewing the food of sweet and bitter fancy, + Lo, what befell! he threw his eye aside, + And mark what object did present itself: + Under an oak, whose boughs were moss'd with age + And high top bald with dry antiquity, + A wretched ragged man, o'ergrown with hair, + Lay sleeping on his back: about his neck + A green and gilded snake had wreathed itself, + Who with her head nimble in threats approach'd + The opening of his mouth; but suddenly, + Seeing Orlando, it unlink'd itself, + And with indented glides did slip away + Into a bush: under which bush's shade + A lioness, with udders all drawn dry, + Lay couching, head on ground, with catlike watch, + When that the sleeping man should stir; for 'tis + The royal disposition of that beast + To prey on nothing that doth seem as dead: + This seen, Orlando did approach the man + And found it was his brother, his elder brother. + +CELIA O, I have heard him speak of that same brother; + And he did render him the most unnatural + That lived amongst men. + +OLIVER And well he might so do, + For well I know he was unnatural. + +ROSALIND But, to Orlando: did he leave him there, + Food to the suck'd and hungry lioness? + +OLIVER Twice did he turn his back and purposed so; + But kindness, nobler ever than revenge, + And nature, stronger than his just occasion, + Made him give battle to the lioness, + Who quickly fell before him: in which hurtling + From miserable slumber I awaked. + +CELIA Are you his brother? + +ROSALIND Wast you he rescued? + +CELIA Was't you that did so oft contrive to kill him? + +OLIVER 'Twas I; but 'tis not I I do not shame + To tell you what I was, since my conversion + So sweetly tastes, being the thing I am. + +ROSALIND But, for the bloody napkin? + +OLIVER By and by. + When from the first to last betwixt us two + Tears our recountments had most kindly bathed, + As how I came into that desert place:-- + In brief, he led me to the gentle duke, + Who gave me fresh array and entertainment, + Committing me unto my brother's love; + Who led me instantly unto his cave, + There stripp'd himself, and here upon his arm + The lioness had torn some flesh away, + Which all this while had bled; and now he fainted + And cried, in fainting, upon Rosalind. + Brief, I recover'd him, bound up his wound; + And, after some small space, being strong at heart, + He sent me hither, stranger as I am, + To tell this story, that you might excuse + His broken promise, and to give this napkin + Dyed in his blood unto the shepherd youth + That he in sport doth call his Rosalind. + + [ROSALIND swoons] + +CELIA Why, how now, Ganymede! sweet Ganymede! + +OLIVER Many will swoon when they do look on blood. + +CELIA There is more in it. Cousin Ganymede! + +OLIVER Look, he recovers. + +ROSALIND I would I were at home. + +CELIA We'll lead you thither. + I pray you, will you take him by the arm? + +OLIVER Be of good cheer, youth: you a man! you lack a + man's heart. + +ROSALIND I do so, I confess it. Ah, sirrah, a body would + think this was well counterfeited! I pray you, tell + your brother how well I counterfeited. Heigh-ho! + +OLIVER This was not counterfeit: there is too great + testimony in your complexion that it was a passion + of earnest. + +ROSALIND Counterfeit, I assure you. + +OLIVER Well then, take a good heart and counterfeit to be a man. + +ROSALIND So I do: but, i' faith, I should have been a woman by right. + +CELIA Come, you look paler and paler: pray you, draw + homewards. Good sir, go with us. + +OLIVER That will I, for I must bear answer back + How you excuse my brother, Rosalind. + +ROSALIND I shall devise something: but, I pray you, commend + my counterfeiting to him. Will you go? + + [Exeunt] + + + + + AS YOU LIKE IT + + +ACT V + + + +SCENE I The forest. + + + [Enter TOUCHSTONE and AUDREY] + +TOUCHSTONE We shall find a time, Audrey; patience, gentle Audrey. + +AUDREY Faith, the priest was good enough, for all the old + gentleman's saying. + +TOUCHSTONE A most wicked Sir Oliver, Audrey, a most vile + Martext. But, Audrey, there is a youth here in the + forest lays claim to you. + +AUDREY Ay, I know who 'tis; he hath no interest in me in + the world: here comes the man you mean. + +TOUCHSTONE It is meat and drink to me to see a clown: by my + troth, we that have good wits have much to answer + for; we shall be flouting; we cannot hold. + + [Enter WILLIAM] + +WILLIAM Good even, Audrey. + +AUDREY God ye good even, William. + +WILLIAM And good even to you, sir. + +TOUCHSTONE Good even, gentle friend. Cover thy head, cover thy + head; nay, prithee, be covered. How old are you, friend? + +WILLIAM Five and twenty, sir. + +TOUCHSTONE A ripe age. Is thy name William? + +WILLIAM William, sir. + +TOUCHSTONE A fair name. Wast born i' the forest here? + +WILLIAM Ay, sir, I thank God. + +TOUCHSTONE 'Thank God;' a good answer. Art rich? + +WILLIAM Faith, sir, so so. + +TOUCHSTONE 'So so' is good, very good, very excellent good; and + yet it is not; it is but so so. Art thou wise? + +WILLIAM Ay, sir, I have a pretty wit. + +TOUCHSTONE Why, thou sayest well. I do now remember a saying, + 'The fool doth think he is wise, but the wise man + knows himself to be a fool.' The heathen + philosopher, when he had a desire to eat a grape, + would open his lips when he put it into his mouth; + meaning thereby that grapes were made to eat and + lips to open. You do love this maid? + +WILLIAM I do, sir. + +TOUCHSTONE Give me your hand. Art thou learned? + +WILLIAM No, sir. + +TOUCHSTONE Then learn this of me: to have, is to have; for it + is a figure in rhetoric that drink, being poured out + of a cup into a glass, by filling the one doth empty + the other; for all your writers do consent that ipse + is he: now, you are not ipse, for I am he. + +WILLIAM Which he, sir? + +TOUCHSTONE He, sir, that must marry this woman. Therefore, you + clown, abandon,--which is in the vulgar leave,--the + society,--which in the boorish is company,--of this + female,--which in the common is woman; which + together is, abandon the society of this female, or, + clown, thou perishest; or, to thy better + understanding, diest; or, to wit I kill thee, make + thee away, translate thy life into death, thy + liberty into bondage: I will deal in poison with + thee, or in bastinado, or in steel; I will bandy + with thee in faction; I will o'errun thee with + policy; I will kill thee a hundred and fifty ways: + therefore tremble and depart. + +AUDREY Do, good William. + +WILLIAM God rest you merry, sir. + + [Exit] + + [Enter CORIN] + +CORIN Our master and mistress seeks you; come, away, away! + +TOUCHSTONE Trip, Audrey! trip, Audrey! I attend, I attend. + + [Exeunt] + + + + + AS YOU LIKE IT + + +ACT V + + + +SCENE II The forest. + + + [Enter ORLANDO and OLIVER] + +ORLANDO Is't possible that on so little acquaintance you + should like her? that but seeing you should love + her? and loving woo? and, wooing, she should + grant? and will you persever to enjoy her? + +OLIVER Neither call the giddiness of it in question, the + poverty of her, the small acquaintance, my sudden + wooing, nor her sudden consenting; but say with me, + I love Aliena; say with her that she loves me; + consent with both that we may enjoy each other: it + shall be to your good; for my father's house and all + the revenue that was old Sir Rowland's will I + estate upon you, and here live and die a shepherd. + +ORLANDO You have my consent. Let your wedding be to-morrow: + thither will I invite the duke and all's contented + followers. Go you and prepare Aliena; for look + you, here comes my Rosalind. + + [Enter ROSALIND] + +ROSALIND God save you, brother. + +OLIVER And you, fair sister. + + [Exit] + +ROSALIND O, my dear Orlando, how it grieves me to see thee + wear thy heart in a scarf! + +ORLANDO It is my arm. + +ROSALIND I thought thy heart had been wounded with the claws + of a lion. + +ORLANDO Wounded it is, but with the eyes of a lady. + +ROSALIND Did your brother tell you how I counterfeited to + swoon when he showed me your handkerchief? + +ORLANDO Ay, and greater wonders than that. + +ROSALIND O, I know where you are: nay, 'tis true: there was + never any thing so sudden but the fight of two rams + and Caesar's thrasonical brag of 'I came, saw, and + overcame:' for your brother and my sister no sooner + met but they looked, no sooner looked but they + loved, no sooner loved but they sighed, no sooner + sighed but they asked one another the reason, no + sooner knew the reason but they sought the remedy; + and in these degrees have they made a pair of stairs + to marriage which they will climb incontinent, or + else be incontinent before marriage: they are in + the very wrath of love and they will together; clubs + cannot part them. + +ORLANDO They shall be married to-morrow, and I will bid the + duke to the nuptial. But, O, how bitter a thing it + is to look into happiness through another man's + eyes! By so much the more shall I to-morrow be at + the height of heart-heaviness, by how much I shall + think my brother happy in having what he wishes for. + +ROSALIND Why then, to-morrow I cannot serve your turn for Rosalind? + +ORLANDO I can live no longer by thinking. + +ROSALIND I will weary you then no longer with idle talking. + Know of me then, for now I speak to some purpose, + that I know you are a gentleman of good conceit: I + speak not this that you should bear a good opinion + of my knowledge, insomuch I say I know you are; + neither do I labour for a greater esteem than may in + some little measure draw a belief from you, to do + yourself good and not to grace me. Believe then, if + you please, that I can do strange things: I have, + since I was three year old, conversed with a + magician, most profound in his art and yet not + damnable. If you do love Rosalind so near the heart + as your gesture cries it out, when your brother + marries Aliena, shall you marry her: I know into + what straits of fortune she is driven; and it is + not impossible to me, if it appear not inconvenient + to you, to set her before your eyes tomorrow human + as she is and without any danger. + +ORLANDO Speakest thou in sober meanings? + +ROSALIND By my life, I do; which I tender dearly, though I + say I am a magician. Therefore, put you in your + best array: bid your friends; for if you will be + married to-morrow, you shall, and to Rosalind, if you will. + + [Enter SILVIUS and PHEBE] + + Look, here comes a lover of mine and a lover of hers. + +PHEBE Youth, you have done me much ungentleness, + To show the letter that I writ to you. + +ROSALIND I care not if I have: it is my study + To seem despiteful and ungentle to you: + You are there followed by a faithful shepherd; + Look upon him, love him; he worships you. + +PHEBE Good shepherd, tell this youth what 'tis to love. + +SILVIUS It is to be all made of sighs and tears; + And so am I for Phebe. + +PHEBE And I for Ganymede. + +ORLANDO And I for Rosalind. + +ROSALIND And I for no woman. + +SILVIUS It is to be all made of faith and service; + And so am I for Phebe. + +PHEBE And I for Ganymede. + +ORLANDO And I for Rosalind. + +ROSALIND And I for no woman. + +SILVIUS It is to be all made of fantasy, + All made of passion and all made of wishes, + All adoration, duty, and observance, + All humbleness, all patience and impatience, + All purity, all trial, all observance; + And so am I for Phebe. + +PHEBE And so am I for Ganymede. + +ORLANDO And so am I for Rosalind. + +ROSALIND And so am I for no woman. + +PHEBE If this be so, why blame you me to love you? + +SILVIUS If this be so, why blame you me to love you? + +ORLANDO If this be so, why blame you me to love you? + +ROSALIND Who do you speak to, 'Why blame you me to love you?' + +ORLANDO To her that is not here, nor doth not hear. + +ROSALIND Pray you, no more of this; 'tis like the howling + of Irish wolves against the moon. + + [To SILVIUS] + + I will help you, if I can: + + [To PHEBE] + + I would love you, if I could. To-morrow meet me all together. + + [To PHEBE] + + I will marry you, if ever I marry woman, and I'll be + married to-morrow: + + [To ORLANDO] + + I will satisfy you, if ever I satisfied man, and you + shall be married to-morrow: + + [To SILVIUS] + + I will content you, if what pleases you contents + you, and you shall be married to-morrow. + + [To ORLANDO] + + As you love Rosalind, meet: + + [To SILVIUS] + + as you love Phebe, meet: and as I love no woman, + I'll meet. So fare you well: I have left you commands. + +SILVIUS I'll not fail, if I live. + +PHEBE Nor I. + +ORLANDO Nor I. + + [Exeunt] + + + + + AS YOU LIKE IT + + +ACT V + + + +SCENE III The forest. + + + [Enter TOUCHSTONE and AUDREY] + +TOUCHSTONE To-morrow is the joyful day, Audrey; to-morrow will + we be married. + +AUDREY I do desire it with all my heart; and I hope it is + no dishonest desire to desire to be a woman of the + world. Here comes two of the banished duke's pages. + + [Enter two Pages] + +First Page Well met, honest gentleman. + +TOUCHSTONE By my troth, well met. Come, sit, sit, and a song. + +Second Page We are for you: sit i' the middle. + +First Page Shall we clap into't roundly, without hawking or + spitting or saying we are hoarse, which are the only + prologues to a bad voice? + +Second Page I'faith, i'faith; and both in a tune, like two + gipsies on a horse. + + SONG. + It was a lover and his lass, + With a hey, and a ho, and a hey nonino, + That o'er the green corn-field did pass + In the spring time, the only pretty ring time, + When birds do sing, hey ding a ding, ding: + Sweet lovers love the spring. + + Between the acres of the rye, + With a hey, and a ho, and a hey nonino + These pretty country folks would lie, + In spring time, &c. + + This carol they began that hour, + With a hey, and a ho, and a hey nonino, + How that a life was but a flower + In spring time, &c. + + And therefore take the present time, + With a hey, and a ho, and a hey nonino; + For love is crowned with the prime + In spring time, &c. + +TOUCHSTONE Truly, young gentlemen, though there was no great + matter in the ditty, yet the note was very + untuneable. + +First Page You are deceived, sir: we kept time, we lost not our time. + +TOUCHSTONE By my troth, yes; I count it but time lost to hear + such a foolish song. God be wi' you; and God mend + your voices! Come, Audrey. + + [Exeunt] + + + + + AS YOU LIKE IT + + +ACT V + + + +SCENE IV The forest. + + + [Enter DUKE SENIOR, AMIENS, JAQUES, ORLANDO, OLIVER, + and CELIA] + +DUKE SENIOR Dost thou believe, Orlando, that the boy + Can do all this that he hath promised? + +ORLANDO I sometimes do believe, and sometimes do not; + As those that fear they hope, and know they fear. + + [Enter ROSALIND, SILVIUS, and PHEBE] + +ROSALIND Patience once more, whiles our compact is urged: + You say, if I bring in your Rosalind, + You will bestow her on Orlando here? + +DUKE SENIOR That would I, had I kingdoms to give with her. + +ROSALIND And you say, you will have her, when I bring her? + +ORLANDO That would I, were I of all kingdoms king. + +ROSALIND You say, you'll marry me, if I be willing? + +PHEBE That will I, should I die the hour after. + +ROSALIND But if you do refuse to marry me, + You'll give yourself to this most faithful shepherd? + +PHEBE So is the bargain. + +ROSALIND You say, that you'll have Phebe, if she will? + +SILVIUS Though to have her and death were both one thing. + +ROSALIND I have promised to make all this matter even. + Keep you your word, O duke, to give your daughter; + You yours, Orlando, to receive his daughter: + Keep your word, Phebe, that you'll marry me, + Or else refusing me, to wed this shepherd: + Keep your word, Silvius, that you'll marry her. + If she refuse me: and from hence I go, + To make these doubts all even. + + [Exeunt ROSALIND and CELIA] + +DUKE SENIOR I do remember in this shepherd boy + Some lively touches of my daughter's favour. + +ORLANDO My lord, the first time that I ever saw him + Methought he was a brother to your daughter: + But, my good lord, this boy is forest-born, + And hath been tutor'd in the rudiments + Of many desperate studies by his uncle, + Whom he reports to be a great magician, + Obscured in the circle of this forest. + + [Enter TOUCHSTONE and AUDREY] + +JAQUES There is, sure, another flood toward, and these + couples are coming to the ark. Here comes a pair of + very strange beasts, which in all tongues are called fools. + +TOUCHSTONE Salutation and greeting to you all! + +JAQUES Good my lord, bid him welcome: this is the + motley-minded gentleman that I have so often met in + the forest: he hath been a courtier, he swears. + +TOUCHSTONE If any man doubt that, let him put me to my + purgation. I have trod a measure; I have flattered + a lady; I have been politic with my friend, smooth + with mine enemy; I have undone three tailors; I have + had four quarrels, and like to have fought one. + +JAQUES And how was that ta'en up? + +TOUCHSTONE Faith, we met, and found the quarrel was upon the + seventh cause. + +JAQUES How seventh cause? Good my lord, like this fellow. + +DUKE SENIOR I like him very well. + +TOUCHSTONE God 'ild you, sir; I desire you of the like. I + press in here, sir, amongst the rest of the country + copulatives, to swear and to forswear: according as + marriage binds and blood breaks: a poor virgin, + sir, an ill-favoured thing, sir, but mine own; a poor + humour of mine, sir, to take that that no man else + will: rich honesty dwells like a miser, sir, in a + poor house; as your pearl in your foul oyster. + +DUKE SENIOR By my faith, he is very swift and sententious. + +TOUCHSTONE According to the fool's bolt, sir, and such dulcet diseases. + +JAQUES But, for the seventh cause; how did you find the + quarrel on the seventh cause? + +TOUCHSTONE Upon a lie seven times removed:--bear your body more + seeming, Audrey:--as thus, sir. I did dislike the + cut of a certain courtier's beard: he sent me word, + if I said his beard was not cut well, he was in the + mind it was: this is called the Retort Courteous. + If I sent him word again 'it was not well cut,' he + would send me word, he cut it to please himself: + this is called the Quip Modest. If again 'it was + not well cut,' he disabled my judgment: this is + called the Reply Churlish. If again 'it was not + well cut,' he would answer, I spake not true: this + is called the Reproof Valiant. If again 'it was not + well cut,' he would say I lied: this is called the + Counter-cheque Quarrelsome: and so to the Lie + Circumstantial and the Lie Direct. + +JAQUES And how oft did you say his beard was not well cut? + +TOUCHSTONE I durst go no further than the Lie Circumstantial, + nor he durst not give me the Lie Direct; and so we + measured swords and parted. + +JAQUES Can you nominate in order now the degrees of the lie? + +TOUCHSTONE O sir, we quarrel in print, by the book; as you have + books for good manners: I will name you the degrees. + The first, the Retort Courteous; the second, the + Quip Modest; the third, the Reply Churlish; the + fourth, the Reproof Valiant; the fifth, the + Countercheque Quarrelsome; the sixth, the Lie with + Circumstance; the seventh, the Lie Direct. All + these you may avoid but the Lie Direct; and you may + avoid that too, with an If. I knew when seven + justices could not take up a quarrel, but when the + parties were met themselves, one of them thought but + of an If, as, 'If you said so, then I said so;' and + they shook hands and swore brothers. Your If is the + only peacemaker; much virtue in If. + +JAQUES Is not this a rare fellow, my lord? he's as good at + any thing and yet a fool. + +DUKE SENIOR He uses his folly like a stalking-horse and under + the presentation of that he shoots his wit. + + [Enter HYMEN, ROSALIND, and CELIA] + + [Still Music] + +HYMEN Then is there mirth in heaven, + When earthly things made even + Atone together. + Good duke, receive thy daughter + Hymen from heaven brought her, + Yea, brought her hither, + That thou mightst join her hand with his + Whose heart within his bosom is. + +ROSALIND [To DUKE SENIOR] To you I give myself, for I am yours. + + [To ORLANDO] + + To you I give myself, for I am yours. + +DUKE SENIOR If there be truth in sight, you are my daughter. + +ORLANDO If there be truth in sight, you are my Rosalind. + +PHEBE If sight and shape be true, + Why then, my love adieu! + +ROSALIND I'll have no father, if you be not he: + I'll have no husband, if you be not he: + Nor ne'er wed woman, if you be not she. + +HYMEN Peace, ho! I bar confusion: + 'Tis I must make conclusion + Of these most strange events: + Here's eight that must take hands + To join in Hymen's bands, + If truth holds true contents. + You and you no cross shall part: + You and you are heart in heart + You to his love must accord, + Or have a woman to your lord: + You and you are sure together, + As the winter to foul weather. + Whiles a wedlock-hymn we sing, + Feed yourselves with questioning; + That reason wonder may diminish, + How thus we met, and these things finish. + + SONG. + Wedding is great Juno's crown: + O blessed bond of board and bed! + 'Tis Hymen peoples every town; + High wedlock then be honoured: + Honour, high honour and renown, + To Hymen, god of every town! + +DUKE SENIOR O my dear niece, welcome thou art to me! + Even daughter, welcome, in no less degree. + +PHEBE I will not eat my word, now thou art mine; + Thy faith my fancy to thee doth combine. + + [Enter JAQUES DE BOYS] + +JAQUES DE BOYS Let me have audience for a word or two: + I am the second son of old Sir Rowland, + That bring these tidings to this fair assembly. + Duke Frederick, hearing how that every day + Men of great worth resorted to this forest, + Address'd a mighty power; which were on foot, + In his own conduct, purposely to take + His brother here and put him to the sword: + And to the skirts of this wild wood he came; + Where meeting with an old religious man, + After some question with him, was converted + Both from his enterprise and from the world, + His crown bequeathing to his banish'd brother, + And all their lands restored to them again + That were with him exiled. This to be true, + I do engage my life. + +DUKE SENIOR Welcome, young man; + Thou offer'st fairly to thy brothers' wedding: + To one his lands withheld, and to the other + A land itself at large, a potent dukedom. + First, in this forest, let us do those ends + That here were well begun and well begot: + And after, every of this happy number + That have endured shrewd days and nights with us + Shall share the good of our returned fortune, + According to the measure of their states. + Meantime, forget this new-fall'n dignity + And fall into our rustic revelry. + Play, music! And you, brides and bridegrooms all, + With measure heap'd in joy, to the measures fall. + +JAQUES Sir, by your patience. If I heard you rightly, + The duke hath put on a religious life + And thrown into neglect the pompous court? + +JAQUES DE BOYS He hath. + +JAQUES To him will I : out of these convertites + There is much matter to be heard and learn'd. + + [To DUKE SENIOR] + + You to your former honour I bequeath; + Your patience and your virtue well deserves it: + + [To ORLANDO] + + You to a love that your true faith doth merit: + + [To OLIVER] + + You to your land and love and great allies: + + [To SILVIUS] + + You to a long and well-deserved bed: + + [To TOUCHSTONE] + + And you to wrangling; for thy loving voyage + Is but for two months victuall'd. So, to your pleasures: + I am for other than for dancing measures. + +DUKE SENIOR Stay, Jaques, stay. + +JAQUES To see no pastime I what you would have + I'll stay to know at your abandon'd cave. + + [Exit] + +DUKE SENIOR Proceed, proceed: we will begin these rites, + As we do trust they'll end, in true delights. + + [A dance] + + + + + AS YOU LIKE IT + + EPILOGUE + + +ROSALIND It is not the fashion to see the lady the epilogue; + but it is no more unhandsome than to see the lord + the prologue. If it be true that good wine needs + no bush, 'tis true that a good play needs no + epilogue; yet to good wine they do use good bushes, + and good plays prove the better by the help of good + epilogues. What a case am I in then, that am + neither a good epilogue nor cannot insinuate with + you in the behalf of a good play! I am not + furnished like a beggar, therefore to beg will not + become me: my way is to conjure you; and I'll begin + with the women. I charge you, O women, for the love + you bear to men, to like as much of this play as + please you: and I charge you, O men, for the love + you bear to women--as I perceive by your simpering, + none of you hates them--that between you and the + women the play may please. If I were a woman I + would kiss as many of you as had beards that pleased + me, complexions that liked me and breaths that I + defied not: and, I am sure, as many as have good + beards or good faces or sweet breaths will, for my + kind offer, when I make curtsy, bid me farewell. + + [Exeunt] diff --git a/web/server/h2o/libh2o/deps/brotli/tests/testdata/asyoulik.txt.compressed b/web/server/h2o/libh2o/deps/brotli/tests/testdata/asyoulik.txt.compressed new file mode 100644 index 00000000..3a762110 Binary files /dev/null and b/web/server/h2o/libh2o/deps/brotli/tests/testdata/asyoulik.txt.compressed differ diff --git a/web/server/h2o/libh2o/deps/brotli/tests/testdata/backward65536 b/web/server/h2o/libh2o/deps/brotli/tests/testdata/backward65536 new file mode 100644 index 00000000..40efb3c1 Binary files /dev/null and b/web/server/h2o/libh2o/deps/brotli/tests/testdata/backward65536 differ diff --git a/web/server/h2o/libh2o/deps/brotli/tests/testdata/backward65536.compressed b/web/server/h2o/libh2o/deps/brotli/tests/testdata/backward65536.compressed new file mode 100644 index 00000000..07152197 Binary files /dev/null and b/web/server/h2o/libh2o/deps/brotli/tests/testdata/backward65536.compressed differ diff --git a/web/server/h2o/libh2o/deps/brotli/tests/testdata/bb.binast b/web/server/h2o/libh2o/deps/brotli/tests/testdata/bb.binast new file mode 100644 index 00000000..9b7f0739 Binary files /dev/null and b/web/server/h2o/libh2o/deps/brotli/tests/testdata/bb.binast differ diff --git a/web/server/h2o/libh2o/deps/brotli/tests/testdata/compressed_file b/web/server/h2o/libh2o/deps/brotli/tests/testdata/compressed_file new file mode 100644 index 00000000..37d86e25 Binary files /dev/null and b/web/server/h2o/libh2o/deps/brotli/tests/testdata/compressed_file differ diff --git a/web/server/h2o/libh2o/deps/brotli/tests/testdata/compressed_file.compressed b/web/server/h2o/libh2o/deps/brotli/tests/testdata/compressed_file.compressed new file mode 100644 index 00000000..8834f327 Binary files /dev/null and b/web/server/h2o/libh2o/deps/brotli/tests/testdata/compressed_file.compressed differ diff --git a/web/server/h2o/libh2o/deps/brotli/tests/testdata/compressed_repeated b/web/server/h2o/libh2o/deps/brotli/tests/testdata/compressed_repeated new file mode 100644 index 00000000..9870b5fd Binary files /dev/null and b/web/server/h2o/libh2o/deps/brotli/tests/testdata/compressed_repeated differ diff --git a/web/server/h2o/libh2o/deps/brotli/tests/testdata/compressed_repeated.compressed b/web/server/h2o/libh2o/deps/brotli/tests/testdata/compressed_repeated.compressed new file mode 100644 index 00000000..09275458 Binary files /dev/null and b/web/server/h2o/libh2o/deps/brotli/tests/testdata/compressed_repeated.compressed differ diff --git a/web/server/h2o/libh2o/deps/brotli/tests/testdata/empty b/web/server/h2o/libh2o/deps/brotli/tests/testdata/empty new file mode 100644 index 00000000..e69de29b diff --git a/web/server/h2o/libh2o/deps/brotli/tests/testdata/empty.compressed b/web/server/h2o/libh2o/deps/brotli/tests/testdata/empty.compressed new file mode 100644 index 00000000..f8fa5a23 --- /dev/null +++ b/web/server/h2o/libh2o/deps/brotli/tests/testdata/empty.compressed @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/web/server/h2o/libh2o/deps/brotli/tests/testdata/empty.compressed.00 b/web/server/h2o/libh2o/deps/brotli/tests/testdata/empty.compressed.00 new file mode 100644 index 00000000..f8fa5a23 --- /dev/null +++ b/web/server/h2o/libh2o/deps/brotli/tests/testdata/empty.compressed.00 @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/web/server/h2o/libh2o/deps/brotli/tests/testdata/empty.compressed.01 b/web/server/h2o/libh2o/deps/brotli/tests/testdata/empty.compressed.01 new file mode 100644 index 00000000..17bb3472 --- /dev/null +++ b/web/server/h2o/libh2o/deps/brotli/tests/testdata/empty.compressed.01 @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/web/server/h2o/libh2o/deps/brotli/tests/testdata/empty.compressed.02 b/web/server/h2o/libh2o/deps/brotli/tests/testdata/empty.compressed.02 new file mode 100644 index 00000000..c183df6a --- /dev/null +++ b/web/server/h2o/libh2o/deps/brotli/tests/testdata/empty.compressed.02 @@ -0,0 +1 @@ +¡ \ No newline at end of file diff --git a/web/server/h2o/libh2o/deps/brotli/tests/testdata/empty.compressed.03 b/web/server/h2o/libh2o/deps/brotli/tests/testdata/empty.compressed.03 new file mode 100644 index 00000000..ae60db8f --- /dev/null +++ b/web/server/h2o/libh2o/deps/brotli/tests/testdata/empty.compressed.03 @@ -0,0 +1 @@ +± \ No newline at end of file diff --git a/web/server/h2o/libh2o/deps/brotli/tests/testdata/empty.compressed.04 b/web/server/h2o/libh2o/deps/brotli/tests/testdata/empty.compressed.04 new file mode 100644 index 00000000..8fac0345 --- /dev/null +++ b/web/server/h2o/libh2o/deps/brotli/tests/testdata/empty.compressed.04 @@ -0,0 +1 @@ +Á \ No newline at end of file diff --git a/web/server/h2o/libh2o/deps/brotli/tests/testdata/empty.compressed.05 b/web/server/h2o/libh2o/deps/brotli/tests/testdata/empty.compressed.05 new file mode 100644 index 00000000..98c9dcca --- /dev/null +++ b/web/server/h2o/libh2o/deps/brotli/tests/testdata/empty.compressed.05 @@ -0,0 +1 @@ +Ñ \ No newline at end of file diff --git a/web/server/h2o/libh2o/deps/brotli/tests/testdata/empty.compressed.06 b/web/server/h2o/libh2o/deps/brotli/tests/testdata/empty.compressed.06 new file mode 100644 index 00000000..84f606f0 --- /dev/null +++ b/web/server/h2o/libh2o/deps/brotli/tests/testdata/empty.compressed.06 @@ -0,0 +1 @@ +á \ No newline at end of file diff --git a/web/server/h2o/libh2o/deps/brotli/tests/testdata/empty.compressed.07 b/web/server/h2o/libh2o/deps/brotli/tests/testdata/empty.compressed.07 new file mode 100644 index 00000000..0941d536 --- /dev/null +++ b/web/server/h2o/libh2o/deps/brotli/tests/testdata/empty.compressed.07 @@ -0,0 +1 @@ +ñ \ No newline at end of file diff --git a/web/server/h2o/libh2o/deps/brotli/tests/testdata/empty.compressed.08 b/web/server/h2o/libh2o/deps/brotli/tests/testdata/empty.compressed.08 new file mode 100644 index 00000000..e440e5c8 --- /dev/null +++ b/web/server/h2o/libh2o/deps/brotli/tests/testdata/empty.compressed.08 @@ -0,0 +1 @@ +3 \ No newline at end of file diff --git a/web/server/h2o/libh2o/deps/brotli/tests/testdata/empty.compressed.09 b/web/server/h2o/libh2o/deps/brotli/tests/testdata/empty.compressed.09 new file mode 100644 index 00000000..7813681f --- /dev/null +++ b/web/server/h2o/libh2o/deps/brotli/tests/testdata/empty.compressed.09 @@ -0,0 +1 @@ +5 \ No newline at end of file diff --git a/web/server/h2o/libh2o/deps/brotli/tests/testdata/empty.compressed.10 b/web/server/h2o/libh2o/deps/brotli/tests/testdata/empty.compressed.10 new file mode 100644 index 00000000..c7930257 --- /dev/null +++ b/web/server/h2o/libh2o/deps/brotli/tests/testdata/empty.compressed.10 @@ -0,0 +1 @@ +7 \ No newline at end of file diff --git a/web/server/h2o/libh2o/deps/brotli/tests/testdata/empty.compressed.11 b/web/server/h2o/libh2o/deps/brotli/tests/testdata/empty.compressed.11 new file mode 100644 index 00000000..f11c82a4 --- /dev/null +++ b/web/server/h2o/libh2o/deps/brotli/tests/testdata/empty.compressed.11 @@ -0,0 +1 @@ +9 \ No newline at end of file diff --git a/web/server/h2o/libh2o/deps/brotli/tests/testdata/empty.compressed.12 b/web/server/h2o/libh2o/deps/brotli/tests/testdata/empty.compressed.12 new file mode 100644 index 00000000..1c8a0e79 --- /dev/null +++ b/web/server/h2o/libh2o/deps/brotli/tests/testdata/empty.compressed.12 @@ -0,0 +1 @@ +; \ No newline at end of file diff --git a/web/server/h2o/libh2o/deps/brotli/tests/testdata/empty.compressed.13 b/web/server/h2o/libh2o/deps/brotli/tests/testdata/empty.compressed.13 new file mode 100644 index 00000000..851c75cc --- /dev/null +++ b/web/server/h2o/libh2o/deps/brotli/tests/testdata/empty.compressed.13 @@ -0,0 +1 @@ += \ No newline at end of file diff --git a/web/server/h2o/libh2o/deps/brotli/tests/testdata/empty.compressed.14 b/web/server/h2o/libh2o/deps/brotli/tests/testdata/empty.compressed.14 new file mode 100644 index 00000000..0d758c9c --- /dev/null +++ b/web/server/h2o/libh2o/deps/brotli/tests/testdata/empty.compressed.14 @@ -0,0 +1 @@ +? \ No newline at end of file diff --git a/web/server/h2o/libh2o/deps/brotli/tests/testdata/empty.compressed.15 b/web/server/h2o/libh2o/deps/brotli/tests/testdata/empty.compressed.15 new file mode 100644 index 00000000..152f9ed5 --- /dev/null +++ b/web/server/h2o/libh2o/deps/brotli/tests/testdata/empty.compressed.15 @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/web/server/h2o/libh2o/deps/brotli/tests/testdata/empty.compressed.16 b/web/server/h2o/libh2o/deps/brotli/tests/testdata/empty.compressed.16 new file mode 100644 index 00000000..e136a792 Binary files /dev/null and b/web/server/h2o/libh2o/deps/brotli/tests/testdata/empty.compressed.16 differ diff --git a/web/server/h2o/libh2o/deps/brotli/tests/testdata/empty.compressed.17 b/web/server/h2o/libh2o/deps/brotli/tests/testdata/empty.compressed.17 new file mode 100644 index 00000000..81f0388b --- /dev/null +++ b/web/server/h2o/libh2o/deps/brotli/tests/testdata/empty.compressed.17 @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/web/server/h2o/libh2o/deps/brotli/tests/testdata/empty.compressed.18 b/web/server/h2o/libh2o/deps/brotli/tests/testdata/empty.compressed.18 new file mode 100644 index 00000000..524e3419 Binary files /dev/null and b/web/server/h2o/libh2o/deps/brotli/tests/testdata/empty.compressed.18 differ diff --git a/web/server/h2o/libh2o/deps/brotli/tests/testdata/lcet10.txt b/web/server/h2o/libh2o/deps/brotli/tests/testdata/lcet10.txt new file mode 100644 index 00000000..25dda6b3 --- /dev/null +++ b/web/server/h2o/libh2o/deps/brotli/tests/testdata/lcet10.txt @@ -0,0 +1,7519 @@ + + +The Project Gutenberg Etext of LOC WORKSHOP ON ELECTRONIC TEXTS + + + + + WORKSHOP ON ELECTRONIC TEXTS + + PROCEEDINGS + + + + Edited by James Daly + + + + + + + + 9-10 June 1992 + + + Library of Congress + Washington, D.C. + + + + Supported by a Grant from the David and Lucile Packard Foundation + + + *** *** *** ****** *** *** *** + + + TABLE OF CONTENTS + + +Acknowledgements + +Introduction + +Proceedings + Welcome + Prosser Gifford and Carl Fleischhauer + + Session I. Content in a New Form: Who Will Use It and What Will They Do? + James Daly (Moderator) + Avra Michelson, Overview + Susan H. Veccia, User Evaluation + Joanne Freeman, Beyond the Scholar + Discussion + + Session II. Show and Tell + Jacqueline Hess (Moderator) + Elli Mylonas, Perseus Project + Discussion + Eric M. Calaluca, Patrologia Latina Database + Carl Fleischhauer and Ricky Erway, American Memory + Discussion + Dorothy Twohig, The Papers of George Washington + Discussion + Maria L. Lebron, The Online Journal of Current Clinical Trials + Discussion + Lynne K. Personius, Cornell mathematics books + Discussion + + Session III. Distribution, Networks, and Networking: + Options for Dissemination + Robert G. Zich (Moderator) + Clifford A. Lynch + Discussion + Howard Besser + Discussion + Ronald L. Larsen + Edwin B. Brownrigg + Discussion + + Session IV. Image Capture, Text Capture, Overview of Text and + Image Storage Formats + William L. Hooton (Moderator) + A) Principal Methods for Image Capture of Text: + direct scanning, use of microform + Anne R. Kenney + Pamela Q.J. Andre + Judith A. Zidar + Donald J. Waters + Discussion + B) Special Problems: bound volumes, conservation, + reproducing printed halftones + George Thoma + Carl Fleischhauer + Discussion + C) Image Standards and Implications for Preservation + Jean Baronas + Patricia Battin + Discussion + D) Text Conversion: OCR vs. rekeying, standards of accuracy + and use of imperfect texts, service bureaus + Michael Lesk + Ricky Erway + Judith A. Zidar + Discussion + + Session V. Approaches to Preparing Electronic Texts + Susan Hockey (Moderator) + Stuart Weibel + Discussion + C.M. Sperberg-McQueen + Discussion + Eric M. Calaluca + Discussion + + Session VI. Copyright Issues + Marybeth Peters + + Session VII. Conclusion + Prosser Gifford (Moderator) + General discussion + +Appendix I: Program + +Appendix II: Abstracts + +Appendix III: Directory of Participants + + + *** *** *** ****** *** *** *** + + + Acknowledgements + +I would like to thank Carl Fleischhauer and Prosser Gifford for the +opportunity to learn about areas of human activity unknown to me a scant +ten months ago, and the David and Lucile Packard Foundation for +supporting that opportunity. The help given by others is acknowledged on +a separate page. + + 19 October 1992 + + + *** *** *** ****** *** *** *** + + + INTRODUCTION + +The Workshop on Electronic Texts (1) drew together representatives of +various projects and interest groups to compare ideas, beliefs, +experiences, and, in particular, methods of placing and presenting +historical textual materials in computerized form. Most attendees gained +much in insight and outlook from the event. But the assembly did not +form a new nation, or, to put it another way, the diversity of projects +and interests was too great to draw the representatives into a cohesive, +action-oriented body.(2) + +Everyone attending the Workshop shared an interest in preserving and +providing access to historical texts. But within this broad field the +attendees represented a variety of formal, informal, figurative, and +literal groups, with many individuals belonging to more than one. These +groups may be defined roughly according to the following topics or +activities: + +* Imaging +* Searchable coded texts +* National and international computer networks +* CD-ROM production and dissemination +* Methods and technology for converting older paper materials into +electronic form +* Study of the use of digital materials by scholars and others + +This summary is arranged thematically and does not follow the actual +sequence of presentations. + +NOTES: + (1) In this document, the phrase electronic text is used to mean + any computerized reproduction or version of a document, book, + article, or manuscript (including images), and not merely a machine- + readable or machine-searchable text. + + (2) The Workshop was held at the Library of Congress on 9-10 June + 1992, with funding from the David and Lucile Packard Foundation. + The document that follows represents a summary of the presentations + made at the Workshop and was compiled by James DALY. This + introduction was written by DALY and Carl FLEISCHHAUER. + + +PRESERVATION AND IMAGING + +Preservation, as that term is used by archivists,(3) was most explicitly +discussed in the context of imaging. Anne KENNEY and Lynne PERSONIUS +explained how the concept of a faithful copy and the user-friendliness of +the traditional book have guided their project at Cornell University.(4) +Although interested in computerized dissemination, participants in the +Cornell project are creating digital image sets of older books in the +public domain as a source for a fresh paper facsimile or, in a future +phase, microfilm. The books returned to the library shelves are +high-quality and useful replacements on acid-free paper that should last +a long time. To date, the Cornell project has placed little or no +emphasis on creating searchable texts; one would not be surprised to find +that the project participants view such texts as new editions, and thus +not as faithful reproductions. + +In her talk on preservation, Patricia BATTIN struck an ecumenical and +flexible note as she endorsed the creation and dissemination of a variety +of types of digital copies. Do not be too narrow in defining what counts +as a preservation element, BATTIN counseled; for the present, at least, +digital copies made with preservation in mind cannot be as narrowly +standardized as, say, microfilm copies with the same objective. Setting +standards precipitously can inhibit creativity, but delay can result in +chaos, she advised. + +In part, BATTIN's position reflected the unsettled nature of image-format +standards, and attendees could hear echoes of this unsettledness in the +comments of various speakers. For example, Jean BARONAS reviewed the +status of several formal standards moving through committees of experts; +and Clifford LYNCH encouraged the use of a new guideline for transmitting +document images on Internet. Testimony from participants in the National +Agricultural Library's (NAL) Text Digitization Program and LC's American +Memory project highlighted some of the challenges to the actual creation +or interchange of images, including difficulties in converting +preservation microfilm to digital form. Donald WATERS reported on the +progress of a master plan for a project at Yale University to convert +books on microfilm to digital image sets, Project Open Book (POB). + +The Workshop offered rather less of an imaging practicum than planned, +but "how-to" hints emerge at various points, for example, throughout +KENNEY's presentation and in the discussion of arcana such as +thresholding and dithering offered by George THOMA and FLEISCHHAUER. + +NOTES: + (3) Although there is a sense in which any reproductions of + historical materials preserve the human record, specialists in the + field have developed particular guidelines for the creation of + acceptable preservation copies. + + (4) Titles and affiliations of presenters are given at the + beginning of their respective talks and in the Directory of + Participants (Appendix III). + + +THE MACHINE-READABLE TEXT: MARKUP AND USE + +The sections of the Workshop that dealt with machine-readable text tended +to be more concerned with access and use than with preservation, at least +in the narrow technical sense. Michael SPERBERG-McQUEEN made a forceful +presentation on the Text Encoding Initiative's (TEI) implementation of +the Standard Generalized Markup Language (SGML). His ideas were echoed +by Susan HOCKEY, Elli MYLONAS, and Stuart WEIBEL. While the +presentations made by the TEI advocates contained no practicum, their +discussion focused on the value of the finished product, what the +European Community calls reusability, but what may also be termed +durability. They argued that marking up--that is, coding--a text in a +well-conceived way will permit it to be moved from one computer +environment to another, as well as to be used by various users. Two +kinds of markup were distinguished: 1) procedural markup, which +describes the features of a text (e.g., dots on a page), and 2) +descriptive markup, which describes the structure or elements of a +document (e.g., chapters, paragraphs, and front matter). + +The TEI proponents emphasized the importance of texts to scholarship. +They explained how heavily coded (and thus analyzed and annotated) texts +can underlie research, play a role in scholarly communication, and +facilitate classroom teaching. SPERBERG-McQUEEN reminded listeners that +a written or printed item (e.g., a particular edition of a book) is +merely a representation of the abstraction we call a text. To concern +ourselves with faithfully reproducing a printed instance of the text, +SPERBERG-McQUEEN argued, is to concern ourselves with the representation +of a representation ("images as simulacra for the text"). The TEI proponents' +interest in images tends to focus on corollary materials for use in teaching, +for example, photographs of the Acropolis to accompany a Greek text. + +By the end of the Workshop, SPERBERG-McQUEEN confessed to having been +converted to a limited extent to the view that electronic images +constitute a promising alternative to microfilming; indeed, an +alternative probably superior to microfilming. But he was not convinced +that electronic images constitute a serious attempt to represent text in +electronic form. HOCKEY and MYLONAS also conceded that their experience +at the Pierce Symposium the previous week at Georgetown University and +the present conference at the Library of Congress had compelled them to +reevaluate their perspective on the usefulness of text as images. +Attendees could see that the text and image advocates were in +constructive tension, so to say. + +Three nonTEI presentations described approaches to preparing +machine-readable text that are less rigorous and thus less expensive. In +the case of the Papers of George Washington, Dorothy TWOHIG explained +that the digital version will provide a not-quite-perfect rendering of +the transcribed text--some 135,000 documents, available for research +during the decades while the perfect or print version is completed. +Members of the American Memory team and the staff of NAL's Text +Digitization Program (see below) also outlined a middle ground concerning +searchable texts. In the case of American Memory, contractors produce +texts with about 99-percent accuracy that serve as "browse" or +"reference" versions of written or printed originals. End users who need +faithful copies or perfect renditions must refer to accompanying sets of +digital facsimile images or consult copies of the originals in a nearby +library or archive. American Memory staff argued that the high cost of +producing 100-percent accurate copies would prevent LC from offering +access to large parts of its collections. + + +THE MACHINE-READABLE TEXT: METHODS OF CONVERSION + +Although the Workshop did not include a systematic examination of the +methods for converting texts from paper (or from facsimile images) into +machine-readable form, nevertheless, various speakers touched upon this +matter. For example, WEIBEL reported that OCLC has experimented with a +merging of multiple optical character recognition systems that will +reduce errors from an unacceptable rate of 5 characters out of every +l,000 to an unacceptable rate of 2 characters out of every l,000. + +Pamela ANDRE presented an overview of NAL's Text Digitization Program and +Judith ZIDAR discussed the technical details. ZIDAR explained how NAL +purchased hardware and software capable of performing optical character +recognition (OCR) and text conversion and used its own staff to convert +texts. The process, ZIDAR said, required extensive editing and project +staff found themselves considering alternatives, including rekeying +and/or creating abstracts or summaries of texts. NAL reckoned costs at +$7 per page. By way of contrast, Ricky ERWAY explained that American +Memory had decided from the start to contract out conversion to external +service bureaus. The criteria used to select these contractors were cost +and quality of results, as opposed to methods of conversion. ERWAY noted +that historical documents or books often do not lend themselves to OCR. +Bound materials represent a special problem. In her experience, quality +control--inspecting incoming materials, counting errors in samples--posed +the most time-consuming aspect of contracting out conversion. ERWAY +reckoned American Memory's costs at $4 per page, but cautioned that fewer +cost-elements had been included than in NAL's figure. + + +OPTIONS FOR DISSEMINATION + +The topic of dissemination proper emerged at various points during the +Workshop. At the session devoted to national and international computer +networks, LYNCH, Howard BESSER, Ronald LARSEN, and Edwin BROWNRIGG +highlighted the virtues of Internet today and of the network that will +evolve from Internet. Listeners could discern in these narratives a +vision of an information democracy in which millions of citizens freely +find and use what they need. LYNCH noted that a lack of standards +inhibits disseminating multimedia on the network, a topic also discussed +by BESSER. LARSEN addressed the issues of network scalability and +modularity and commented upon the difficulty of anticipating the effects +of growth in orders of magnitude. BROWNRIGG talked about the ability of +packet radio to provide certain links in a network without the need for +wiring. However, the presenters also called attention to the +shortcomings and incongruities of present-day computer networks. For +example: 1) Network use is growing dramatically, but much network +traffic consists of personal communication (E-mail). 2) Large bodies of +information are available, but a user's ability to search across their +entirety is limited. 3) There are significant resources for science and +technology, but few network sources provide content in the humanities. +4) Machine-readable texts are commonplace, but the capability of the +system to deal with images (let alone other media formats) lags behind. +A glimpse of a multimedia future for networks, however, was provided by +Maria LEBRON in her overview of the Online Journal of Current Clinical +Trials (OJCCT), and the process of scholarly publishing on-line. + +The contrasting form of the CD-ROM disk was never systematically +analyzed, but attendees could glean an impression from several of the +show-and-tell presentations. The Perseus and American Memory examples +demonstrated recently published disks, while the descriptions of the +IBYCUS version of the Papers of George Washington and Chadwyck-Healey's +Patrologia Latina Database (PLD) told of disks to come. According to +Eric CALALUCA, PLD's principal focus has been on converting Jacques-Paul +Migne's definitive collection of Latin texts to machine-readable form. +Although everyone could share the network advocates' enthusiasm for an +on-line future, the possibility of rolling up one's sleeves for a session +with a CD-ROM containing both textual materials and a powerful retrieval +engine made the disk seem an appealing vessel indeed. The overall +discussion suggested that the transition from CD-ROM to on-line networked +access may prove far slower and more difficult than has been anticipated. + + +WHO ARE THE USERS AND WHAT DO THEY DO? + +Although concerned with the technicalities of production, the Workshop +never lost sight of the purposes and uses of electronic versions of +textual materials. As noted above, those interested in imaging discussed +the problematical matter of digital preservation, while the TEI proponents +described how machine-readable texts can be used in research. This latter +topic received thorough treatment in the paper read by Avra MICHELSON. +She placed the phenomenon of electronic texts within the context of +broader trends in information technology and scholarly communication. + +Among other things, MICHELSON described on-line conferences that +represent a vigorous and important intellectual forum for certain +disciplines. Internet now carries more than 700 conferences, with about +80 percent of these devoted to topics in the social sciences and the +humanities. Other scholars use on-line networks for "distance learning." +Meanwhile, there has been a tremendous growth in end-user computing; +professors today are less likely than their predecessors to ask the +campus computer center to process their data. Electronic texts are one +key to these sophisticated applications, MICHELSON reported, and more and +more scholars in the humanities now work in an on-line environment. +Toward the end of the Workshop, Michael LESK presented a corollary to +MICHELSON's talk, reporting the results of an experiment that compared +the work of one group of chemistry students using traditional printed +texts and two groups using electronic sources. The experiment +demonstrated that in the event one does not know what to read, one needs +the electronic systems; the electronic systems hold no advantage at the +moment if one knows what to read, but neither do they impose a penalty. + +DALY provided an anecdotal account of the revolutionizing impact of the +new technology on his previous methods of research in the field of classics. +His account, by extrapolation, served to illustrate in part the arguments +made by MICHELSON concerning the positive effects of the sudden and radical +transformation being wrought in the ways scholars work. + +Susan VECCIA and Joanne FREEMAN delineated the use of electronic +materials outside the university. The most interesting aspect of their +use, FREEMAN said, could be seen as a paradox: teachers in elementary +and secondary schools requested access to primary source materials but, +at the same time, found that "primariness" itself made these materials +difficult for their students to use. + + +OTHER TOPICS + +Marybeth PETERS reviewed copyright law in the United States and offered +advice during a lively discussion of this subject. But uncertainty +remains concerning the price of copyright in a digital medium, because a +solution remains to be worked out concerning management and synthesis of +copyrighted and out-of-copyright pieces of a database. + +As moderator of the final session of the Workshop, Prosser GIFFORD directed +discussion to future courses of action and the potential role of LC in +advancing them. Among the recommendations that emerged were the following: + + * Workshop participants should 1) begin to think about working + with image material, but structure and digitize it in such a + way that at a later stage it can be interpreted into text, and + 2) find a common way to build text and images together so that + they can be used jointly at some stage in the future, with + appropriate network support, because that is how users will want + to access these materials. The Library might encourage attempts + to bring together people who are working on texts and images. + + * A network version of American Memory should be developed or + consideration should be given to making the data in it + available to people interested in doing network multimedia. + Given the current dearth of digital data that is appealing and + unencumbered by extremely complex rights problems, developing a + network version of American Memory could do much to help make + network multimedia a reality. + + * Concerning the thorny issue of electronic deposit, LC should + initiate a catalytic process in terms of distributed + responsibility, that is, bring together the distributed + organizations and set up a study group to look at all the + issues related to electronic deposit and see where we as a + nation should move. For example, LC might attempt to persuade + one major library in each state to deal with its state + equivalent publisher, which might produce a cooperative project + that would be equitably distributed around the country, and one + in which LC would be dealing with a minimal number of publishers + and minimal copyright problems. LC must also deal with the + concept of on-line publishing, determining, among other things, + how serials such as OJCCT might be deposited for copyright. + + * Since a number of projects are planning to carry out + preservation by creating digital images that will end up in + on-line or near-line storage at some institution, LC might play + a helpful role, at least in the near term, by accelerating how + to catalog that information into the Research Library Information + Network (RLIN) and then into OCLC, so that it would be accessible. + This would reduce the possibility of multiple institutions digitizing + the same work. + + +CONCLUSION + +The Workshop was valuable because it brought together partisans from +various groups and provided an occasion to compare goals and methods. +The more committed partisans frequently communicate with others in their +groups, but less often across group boundaries. The Workshop was also +valuable to attendees--including those involved with American Memory--who +came less committed to particular approaches or concepts. These +attendees learned a great deal, and plan to select and employ elements of +imaging, text-coding, and networked distribution that suit their +respective projects and purposes. + +Still, reality rears its ugly head: no breakthrough has been achieved. +On the imaging side, one confronts a proliferation of competing +data-interchange standards and a lack of consensus on the role of digital +facsimiles in preservation. In the realm of machine-readable texts, one +encounters a reasonably mature standard but methodological difficulties +and high costs. These latter problems, of course, represent a special +impediment to the desire, as it is sometimes expressed in the popular +press, "to put the [contents of the] Library of Congress on line." In +the words of one participant, there was "no solution to the economic +problems--the projects that are out there are surviving, but it is going +to be a lot of work to transform the information industry, and so far the +investment to do that is not forthcoming" (LESK, per litteras). + + + *** *** *** ****** *** *** *** + + + PROCEEDINGS + + +WELCOME + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +GIFFORD * Origin of Workshop in current Librarian's desire to make LC's +collections more widely available * Desiderata arising from the prospect +of greater interconnectedness * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +After welcoming participants on behalf of the Library of Congress, +American Memory (AM), and the National Demonstration Lab, Prosser +GIFFORD, director for scholarly programs, Library of Congress, located +the origin of the Workshop on Electronic Texts in a conversation he had +had considerably more than a year ago with Carl FLEISCHHAUER concerning +some of the issues faced by AM. On the assumption that numerous other +people were asking the same questions, the decision was made to bring +together as many of these people as possible to ask the same questions +together. In a deeper sense, GIFFORD said, the origin of the Workshop +lay in the desire of the current Librarian of Congress, James H. +Billington, to make the collections of the Library, especially those +offering unique or unusual testimony on aspects of the American +experience, available to a much wider circle of users than those few +people who can come to Washington to use them. This meant that the +emphasis of AM, from the outset, has been on archival collections of the +basic material, and on making these collections themselves available, +rather than selected or heavily edited products. + +From AM's emphasis followed the questions with which the Workshop began: +who will use these materials, and in what form will they wish to use +them. But an even larger issue deserving mention, in GIFFORD's view, was +the phenomenal growth in Internet connectivity. He expressed the hope +that the prospect of greater interconnectedness than ever before would +lead to: 1) much more cooperative and mutually supportive endeavors; 2) +development of systems of shared and distributed responsibilities to +avoid duplication and to ensure accuracy and preservation of unique +materials; and 3) agreement on the necessary standards and development of +the appropriate directories and indices to make navigation +straightforward among the varied resources that are, and increasingly +will be, available. In this connection, GIFFORD requested that +participants reflect from the outset upon the sorts of outcomes they +thought the Workshop might have. Did those present constitute a group +with sufficient common interests to propose a next step or next steps, +and if so, what might those be? They would return to these questions the +following afternoon. + + ****** + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +FLEISCHHAUER * Core of Workshop concerns preparation and production of +materials * Special challenge in conversion of textual materials * +Quality versus quantity * Do the several groups represented share common +interests? * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Carl FLEISCHHAUER, coordinator, American Memory, Library of Congress, +emphasized that he would attempt to represent the people who perform some +of the work of converting or preparing materials and that the core of +the Workshop had to do with preparation and production. FLEISCHHAUER +then drew a distinction between the long term, when many things would be +available and connected in the ways that GIFFORD described, and the short +term, in which AM not only has wrestled with the issue of what is the +best course to pursue but also has faced a variety of technical +challenges. + +FLEISCHHAUER remarked AM's endeavors to deal with a wide range of library +formats, such as motion picture collections, sound-recording collections, +and pictorial collections of various sorts, especially collections of +photographs. In the course of these efforts, AM kept coming back to +textual materials--manuscripts or rare printed matter, bound materials, +etc. Text posed the greatest conversion challenge of all. Thus, the +genesis of the Workshop, which reflects the problems faced by AM. These +problems include physical problems. For example, those in the library +and archive business deal with collections made up of fragile and rare +manuscript items, bound materials, especially the notoriously brittle +bound materials of the late nineteenth century. These are precious +cultural artifacts, however, as well as interesting sources of +information, and LC desires to retain and conserve them. AM needs to +handle things without damaging them. Guillotining a book to run it +through a sheet feeder must be avoided at all costs. + +Beyond physical problems, issues pertaining to quality arose. For +example, the desire to provide users with a searchable text is affected +by the question of acceptable level of accuracy. One hundred percent +accuracy is tremendously expensive. On the other hand, the output of +optical character recognition (OCR) can be tremendously inaccurate. +Although AM has attempted to find a middle ground, uncertainty persists +as to whether or not it has discovered the right solution. + +Questions of quality arose concerning images as well. FLEISCHHAUER +contrasted the extremely high level of quality of the digital images in +the Cornell Xerox Project with AM's efforts to provide a browse-quality +or access-quality image, as opposed to an archival or preservation image. +FLEISCHHAUER therefore welcomed the opportunity to compare notes. + +FLEISCHHAUER observed in passing that conversations he had had about +networks have begun to signal that for various forms of media a +determination may be made that there is a browse-quality item, or a +distribution-and-access-quality item that may coexist in some systems +with a higher quality archival item that would be inconvenient to send +through the network because of its size. FLEISCHHAUER referred, of +course, to images more than to searchable text. + +As AM considered those questions, several conceptual issues arose: ought +AM occasionally to reproduce materials entirely through an image set, at +other times, entirely through a text set, and in some cases, a mix? +There probably would be times when the historical authenticity of an +artifact would require that its image be used. An image might be +desirable as a recourse for users if one could not provide 100-percent +accurate text. Again, AM wondered, as a practical matter, if a +distinction could be drawn between rare printed matter that might exist +in multiple collections--that is, in ten or fifteen libraries. In such +cases, the need for perfect reproduction would be less than for unique +items. Implicit in his remarks, FLEISCHHAUER conceded, was the admission +that AM has been tilting strongly towards quantity and drawing back a +little from perfect quality. That is, it seemed to AM that society would +be better served if more things were distributed by LC--even if they were +not quite perfect--than if fewer things, perfectly represented, were +distributed. This was stated as a proposition to be tested, with +responses to be gathered from users. + +In thinking about issues related to reproduction of materials and seeing +other people engaged in parallel activities, AM deemed it useful to +convene a conference. Hence, the Workshop. FLEISCHHAUER thereupon +surveyed the several groups represented: 1) the world of images (image +users and image makers); 2) the world of text and scholarship and, within +this group, those concerned with language--FLEISCHHAUER confessed to finding +delightful irony in the fact that some of the most advanced thinkers on +computerized texts are those dealing with ancient Greek and Roman materials; +3) the network world; and 4) the general world of library science, which +includes people interested in preservation and cataloging. + +FLEISCHHAUER concluded his remarks with special thanks to the David and +Lucile Packard Foundation for its support of the meeting, the American +Memory group, the Office for Scholarly Programs, the National +Demonstration Lab, and the Office of Special Events. He expressed the +hope that David Woodley Packard might be able to attend, noting that +Packard's work and the work of the foundation had sponsored a number of +projects in the text area. + + ****** + +SESSION I. CONTENT IN A NEW FORM: WHO WILL USE IT AND WHAT WILL THEY DO? + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +DALY * Acknowledgements * A new Latin authors disk * Effects of the new +technology on previous methods of research * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Serving as moderator, James DALY acknowledged the generosity of all the +presenters for giving of their time, counsel, and patience in planning +the Workshop, as well as of members of the American Memory project and +other Library of Congress staff, and the David and Lucile Packard +Foundation and its executive director, Colburn S. Wilbur. + +DALY then recounted his visit in March to the Center for Electronic Texts +in the Humanities (CETH) and the Department of Classics at Rutgers +University, where an old friend, Lowell Edmunds, introduced him to the +department's IBYCUS scholarly personal computer, and, in particular, the +new Latin CD-ROM, containing, among other things, almost all classical +Latin literary texts through A.D. 200. Packard Humanities Institute +(PHI), Los Altos, California, released this disk late in 1991, with a +nominal triennial licensing fee. + +Playing with the disk for an hour or so at Rutgers brought home to DALY +at once the revolutionizing impact of the new technology on his previous +methods of research. Had this disk been available two or three years +earlier, DALY contended, when he was engaged in preparing a commentary on +Book 10 of Virgil's Aeneid for Cambridge University Press, he would not +have required a forty-eight-square-foot table on which to spread the +numerous, most frequently consulted items, including some ten or twelve +concordances to key Latin authors, an almost equal number of lexica to +authors who lacked concordances, and where either lexica or concordances +were lacking, numerous editions of authors antedating and postdating Virgil. + +Nor, when checking each of the average six to seven words contained in +the Virgilian hexameter for its usage elsewhere in Virgil's works or +other Latin authors, would DALY have had to maintain the laborious +mechanical process of flipping through these concordances, lexica, and +editions each time. Nor would he have had to frequent as often the +Milton S. Eisenhower Library at the Johns Hopkins University to consult +the Thesaurus Linguae Latinae. Instead of devoting countless hours, or +the bulk of his research time, to gathering data concerning Virgil's use +of words, DALY--now freed by PHI's Latin authors disk from the +tyrannical, yet in some ways paradoxically happy scholarly drudgery-- +would have been able to devote that same bulk of time to analyzing and +interpreting Virgilian verbal usage. + +Citing Theodore Brunner, Gregory Crane, Elli MYLONAS, and Avra MICHELSON, +DALY argued that this reversal in his style of work, made possible by the +new technology, would perhaps have resulted in better, more productive +research. Indeed, even in the course of his browsing the Latin authors +disk at Rutgers, its powerful search, retrieval, and highlighting +capabilities suggested to him several new avenues of research into +Virgil's use of sound effects. This anecdotal account, DALY maintained, +may serve to illustrate in part the sudden and radical transformation +being wrought in the ways scholars work. + + ****** + +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +MICHELSON * Elements related to scholarship and technology * Electronic +texts within the context of broader trends within information technology +and scholarly communication * Evaluation of the prospects for the use of +electronic texts * Relationship of electronic texts to processes of +scholarly communication in humanities research * New exchange formats +created by scholars * Projects initiated to increase scholarly access to +converted text * Trend toward making electronic resources available +through research and education networks * Changes taking place in +scholarly communication among humanities scholars * Network-mediated +scholarship transforming traditional scholarly practices * Key +information technology trends affecting the conduct of scholarly +communication over the next decade * The trend toward end-user computing +* The trend toward greater connectivity * Effects of these trends * Key +transformations taking place * Summary of principal arguments * +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Avra MICHELSON, Archival Research and Evaluation Staff, National Archives +and Records Administration (NARA), argued that establishing who will use +electronic texts and what they will use them for involves a consideration +of both information technology and scholarship trends. This +consideration includes several elements related to scholarship and +technology: 1) the key trends in information technology that are most +relevant to scholarship; 2) the key trends in the use of currently +available technology by scholars in the nonscientific community; and 3) +the relationship between these two very distinct but interrelated trends. +The investment in understanding this relationship being made by +information providers, technologists, and public policy developers, as +well as by scholars themselves, seems to be pervasive and growing, +MICHELSON contended. She drew on collaborative work with Jeff Rothenberg +on the scholarly use of technology. + +MICHELSON sought to place the phenomenon of electronic texts within the +context of broader trends within information technology and scholarly +communication. She argued that electronic texts are of most use to +researchers to the extent that the researchers' working context (i.e., +their relevant bibliographic sources, collegial feedback, analytic tools, +notes, drafts, etc.), along with their field's primary and secondary +sources, also is accessible in electronic form and can be integrated in +ways that are unique to the on-line environment. + +Evaluation of the prospects for the use of electronic texts includes two +elements: 1) an examination of the ways in which researchers currently +are using electronic texts along with other electronic resources, and 2) +an analysis of key information technology trends that are affecting the +long-term conduct of scholarly communication. MICHELSON limited her +discussion of the use of electronic texts to the practices of humanists +and noted that the scientific community was outside the panel's overview. + +MICHELSON examined the nature of the current relationship of electronic +texts in particular, and electronic resources in general, to what she +maintained were, essentially, five processes of scholarly communication +in humanities research. Researchers 1) identify sources, 2) communicate +with their colleagues, 3) interpret and analyze data, 4) disseminate +their research findings, and 5) prepare curricula to instruct the next +generation of scholars and students. This examination would produce a +clearer understanding of the synergy among these five processes that +fuels the tendency of the use of electronic resources for one process to +stimulate its use for other processes of scholarly communication. + +For the first process of scholarly communication, the identification of +sources, MICHELSON remarked the opportunity scholars now enjoy to +supplement traditional word-of-mouth searches for sources among their +colleagues with new forms of electronic searching. So, for example, +instead of having to visit the library, researchers are able to explore +descriptions of holdings in their offices. Furthermore, if their own +institutions' holdings prove insufficient, scholars can access more than +200 major American library catalogues over Internet, including the +universities of California, Michigan, Pennsylvania, and Wisconsin. +Direct access to the bibliographic databases offers intellectual +empowerment to scholars by presenting a comprehensive means of browsing +through libraries from their homes and offices at their convenience. + +The second process of communication involves communication among +scholars. Beyond the most common methods of communication, scholars are +using E-mail and a variety of new electronic communications formats +derived from it for further academic interchange. E-mail exchanges are +growing at an astonishing rate, reportedly 15 percent a month. They +currently constitute approximately half the traffic on research and +education networks. Moreover, the global spread of E-mail has been so +rapid that it is now possible for American scholars to use it to +communicate with colleagues in close to 140 other countries. + +Other new exchange formats created by scholars and operating on Internet +include more than 700 conferences, with about 80 percent of these devoted +to topics in the social sciences and humanities. The rate of growth of +these scholarly electronic conferences also is astonishing. From l990 to +l991, 200 new conferences were identified on Internet. From October 1991 +to June 1992, an additional 150 conferences in the social sciences and +humanities were added to this directory of listings. Scholars have +established conferences in virtually every field, within every different +discipline. For example, there are currently close to 600 active social +science and humanities conferences on topics such as art and +architecture, ethnomusicology, folklore, Japanese culture, medical +education, and gifted and talented education. The appeal to scholars of +communicating through these conferences is that, unlike any other medium, +electronic conferences today provide a forum for global communication +with peers at the front end of the research process. + +Interpretation and analysis of sources constitutes the third process of +scholarly communication that MICHELSON discussed in terms of texts and +textual resources. The methods used to analyze sources fall somewhere on +a continuum from quantitative analysis to qualitative analysis. +Typically, evidence is culled and evaluated using methods drawn from both +ends of this continuum. At one end, quantitative analysis involves the +use of mathematical processes such as a count of frequencies and +distributions of occurrences or, on a higher level, regression analysis. +At the other end of the continuum, qualitative analysis typically +involves nonmathematical processes oriented toward language +interpretation or the building of theory. Aspects of this work involve +the processing--either manual or computational--of large and sometimes +massive amounts of textual sources, although the use of nontextual +sources as evidence, such as photographs, sound recordings, film footage, +and artifacts, is significant as well. + +Scholars have discovered that many of the methods of interpretation and +analysis that are related to both quantitative and qualitative methods +are processes that can be performed by computers. For example, computers +can count. They can count brush strokes used in a Rembrandt painting or +perform regression analysis for understanding cause and effect. By means +of advanced technologies, computers can recognize patterns, analyze text, +and model concepts. Furthermore, computers can complete these processes +faster with more sources and with greater precision than scholars who +must rely on manual interpretation of data. But if scholars are to use +computers for these processes, source materials must be in a form +amenable to computer-assisted analysis. For this reason many scholars, +once they have identified the sources that are key to their research, are +converting them to machine-readable form. Thus, a representative example +of the numerous textual conversion projects organized by scholars around +the world in recent years to support computational text analysis is the +TLG, the Thesaurus Linguae Graecae. This project is devoted to +converting the extant ancient texts of classical Greece. (Editor's note: +according to the TLG Newsletter of May l992, TLG was in use in thirty-two +different countries. This figure updates MICHELSON's previous count by one.) + +The scholars performing these conversions have been asked to recognize +that the electronic sources they are converting for one use possess value +for other research purposes as well. As a result, during the past few +years, humanities scholars have initiated a number of projects to +increase scholarly access to converted text. So, for example, the Text +Encoding Initiative (TEI), about which more is said later in the program, +was established as an effort by scholars to determine standard elements +and methods for encoding machine-readable text for electronic exchange. +In a second effort to facilitate the sharing of converted text, scholars +have created a new institution, the Center for Electronic Texts in the +Humanities (CETH). The center estimates that there are 8,000 series of +source texts in the humanities that have been converted to +machine-readable form worldwide. CETH is undertaking an international +search for converted text in the humanities, compiling it into an +electronic library, and preparing bibliographic descriptions of the +sources for the Research Libraries Information Network's (RLIN) +machine-readable data file. The library profession has begun to initiate +large conversion projects as well, such as American Memory. + +While scholars have been making converted text available to one another, +typically on disk or on CD-ROM, the clear trend is toward making these +resources available through research and education networks. Thus, the +American and French Research on the Treasury of the French Language +(ARTFL) and the Dante Project are already available on Internet. +MICHELSON summarized this section on interpretation and analysis by +noting that: 1) increasing numbers of humanities scholars in the library +community are recognizing the importance to the advancement of +scholarship of retrospective conversion of source materials in the arts +and humanities; and 2) there is a growing realization that making the +sources available on research and education networks maximizes their +usefulness for the analysis performed by humanities scholars. + +The fourth process of scholarly communication is dissemination of +research findings, that is, publication. Scholars are using existing +research and education networks to engineer a new type of publication: +scholarly-controlled journals that are electronically produced and +disseminated. Although such journals are still emerging as a +communication format, their number has grown, from approximately twelve +to thirty-six during the past year (July 1991 to June 1992). Most of +these electronic scholarly journals are devoted to topics in the +humanities. As with network conferences, scholarly enthusiasm for these +electronic journals stems from the medium's unique ability to advance +scholarship in a way that no other medium can do by supporting global +feedback and interchange, practically in real time, early in the research +process. Beyond scholarly journals, MICHELSON remarked the delivery of +commercial full-text products, such as articles in professional journals, +newsletters, magazines, wire services, and reference sources. These are +being delivered via on-line local library catalogues, especially through +CD-ROMs. Furthermore, according to MICHELSON, there is general optimism +that the copyright and fees issues impeding the delivery of full text on +existing research and education networks soon will be resolved. + +The final process of scholarly communication is curriculum development +and instruction, and this involves the use of computer information +technologies in two areas. The first is the development of +computer-oriented instructional tools, which includes simulations, +multimedia applications, and computer tools that are used to assist in +the analysis of sources in the classroom, etc. The Perseus Project, a +database that provides a multimedia curriculum on classical Greek +civilization, is a good example of the way in which entire curricula are +being recast using information technologies. It is anticipated that the +current difficulty in exchanging electronically computer-based +instructional software, which in turn makes it difficult for one scholar +to build upon the work of others, will be resolved before too long. +Stand-alone curricular applications that involve electronic text will be +sharable through networks, reinforcing their significance as intellectual +products as well as instructional tools. + +The second aspect of electronic learning involves the use of research and +education networks for distance education programs. Such programs +interactively link teachers with students in geographically scattered +locations and rely on the availability of electronic instructional +resources. Distance education programs are gaining wide appeal among +state departments of education because of their demonstrated capacity to +bring advanced specialized course work and an array of experts to many +classrooms. A recent report found that at least 32 states operated at +least one statewide network for education in 1991, with networks under +development in many of the remaining states. + +MICHELSON summarized this section by noting two striking changes taking +place in scholarly communication among humanities scholars. First is the +extent to which electronic text in particular, and electronic resources +in general, are being infused into each of the five processes described +above. As mentioned earlier, there is a certain synergy at work here. +The use of electronic resources for one process tends to stimulate its +use for other processes, because the chief course of movement is toward a +comprehensive on-line working context for humanities scholars that +includes on-line availability of key bibliographies, scholarly feedback, +sources, analytical tools, and publications. MICHELSON noted further +that the movement toward a comprehensive on-line working context for +humanities scholars is not new. In fact, it has been underway for more +than forty years in the humanities, since Father Roberto Busa began +developing an electronic concordance of the works of Saint Thomas Aquinas +in 1949. What we are witnessing today, MICHELSON contended, is not the +beginning of this on-line transition but, for at least some humanities +scholars, the turning point in the transition from a print to an +electronic working context. Coinciding with the on-line transition, the +second striking change is the extent to which research and education +networks are becoming the new medium of scholarly communication. The +existing Internet and the pending National Education and Research Network +(NREN) represent the new meeting ground where scholars are going for +bibliographic information, scholarly dialogue and feedback, the most +current publications in their field, and high-level educational +offerings. Traditional scholarly practices are undergoing tremendous +transformations as a result of the emergence and growing prominence of +what is called network-mediated scholarship. + +MICHELSON next turned to the second element of the framework she proposed +at the outset of her talk for evaluating the prospects for electronic +text, namely the key information technology trends affecting the conduct +of scholarly communication over the next decade: 1) end-user computing +and 2) connectivity. + +End-user computing means that the person touching the keyboard, or +performing computations, is the same as the person who initiates or +consumes the computation. The emergence of personal computers, along +with a host of other forces, such as ubiquitous computing, advances in +interface design, and the on-line transition, is prompting the consumers +of computation to do their own computing, and is thus rendering obsolete +the traditional distinction between end users and ultimate users. + +The trend toward end-user computing is significant to consideration of +the prospects for electronic texts because it means that researchers are +becoming more adept at doing their own computations and, thus, more +competent in the use of electronic media. By avoiding programmer +intermediaries, computation is becoming central to the researcher's +thought process. This direct involvement in computing is changing the +researcher's perspective on the nature of research itself, that is, the +kinds of questions that can be posed, the analytical methodologies that +can be used, the types and amount of sources that are appropriate for +analyses, and the form in which findings are presented. The trend toward +end-user computing means that, increasingly, electronic media and +computation are being infused into all processes of humanities +scholarship, inspiring remarkable transformations in scholarly +communication. + +The trend toward greater connectivity suggests that researchers are using +computation increasingly in network environments. Connectivity is +important to scholarship because it erases the distance that separates +students from teachers and scholars from their colleagues, while allowing +users to access remote databases, share information in many different +media, connect to their working context wherever they are, and +collaborate in all phases of research. + +The combination of the trend toward end-user computing and the trend +toward connectivity suggests that the scholarly use of electronic +resources, already evident among some researchers, will soon become an +established feature of scholarship. The effects of these trends, along +with ongoing changes in scholarly practices, point to a future in which +humanities researchers will use computation and electronic communication +to help them formulate ideas, access sources, perform research, +collaborate with colleagues, seek peer review, publish and disseminate +results, and engage in many other professional and educational activities. + +In summary, MICHELSON emphasized four points: 1) A portion of humanities +scholars already consider electronic texts the preferred format for +analysis and dissemination. 2) Scholars are using these electronic +texts, in conjunction with other electronic resources, in all the +processes of scholarly communication. 3) The humanities scholars' +working context is in the process of changing from print technology to +electronic technology, in many ways mirroring transformations that have +occurred or are occurring within the scientific community. 4) These +changes are occurring in conjunction with the development of a new +communication medium: research and education networks that are +characterized by their capacity to advance scholarship in a wholly unique +way. + +MICHELSON also reiterated her three principal arguments: l) Electronic +texts are best understood in terms of the relationship to other +electronic resources and the growing prominence of network-mediated +scholarship. 2) The prospects for electronic texts lie in their capacity +to be integrated into the on-line network of electronic resources that +comprise the new working context for scholars. 3) Retrospective conversion +of portions of the scholarly record should be a key strategy as information +providers respond to changes in scholarly communication practices. + + ****** + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +VECCIA * AM's evaluation project and public users of electronic resources +* AM and its design * Site selection and evaluating the Macintosh +implementation of AM * Characteristics of the six public libraries +selected * Characteristics of AM's users in these libraries * Principal +ways AM is being used * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Susan VECCIA, team leader, and Joanne FREEMAN, associate coordinator, +American Memory, Library of Congress, gave a joint presentation. First, +by way of introduction, VECCIA explained her and FREEMAN's roles in +American Memory (AM). Serving principally as an observer, VECCIA has +assisted with the evaluation project of AM, placing AM collections in a +variety of different sites around the country and helping to organize and +implement that project. FREEMAN has been an associate coordinator of AM +and has been involved principally with the interpretative materials, +preparing some of the electronic exhibits and printed historical +information that accompanies AM and that is requested by users. VECCIA +and FREEMAN shared anecdotal observations concerning AM with public users +of electronic resources. Notwithstanding a fairly structured evaluation +in progress, both VECCIA and FREEMAN chose not to report on specifics in +terms of numbers, etc., because they felt it was too early in the +evaluation project to do so. + +AM is an electronic archive of primary source materials from the Library +of Congress, selected collections representing a variety of formats-- +photographs, graphic arts, recorded sound, motion pictures, broadsides, +and soon, pamphlets and books. In terms of the design of this system, +the interpretative exhibits have been kept separate from the primary +resources, with good reason. Accompanying this collection are printed +documentation and user guides, as well as guides that FREEMAN prepared for +teachers so that they may begin using the content of the system at once. + +VECCIA described the evaluation project before talking about the public +users of AM, limiting her remarks to public libraries, because FREEMAN +would talk more specifically about schools from kindergarten to twelfth +grade (K-12). Having started in spring 1991, the evaluation currently +involves testing of the Macintosh implementation of AM. Since the +primary goal of this evaluation is to determine the most appropriate +audience or audiences for AM, very different sites were selected. This +makes evaluation difficult because of the varying degrees of technology +literacy among the sites. AM is situated in forty-four locations, of +which six are public libraries and sixteen are schools. Represented +among the schools are elementary, junior high, and high schools. +District offices also are involved in the evaluation, which will +conclude in summer 1993. + +VECCIA focused the remainder of her talk on the six public libraries, one +of which doubles as a state library. They represent a range of +geographic areas and a range of demographic characteristics. For +example, three are located in urban settings, two in rural settings, and +one in a suburban setting. A range of technical expertise is to be found +among these facilities as well. For example, one is an "Apple library of +the future," while two others are rural one-room libraries--in one, AM +sits at the front desk next to a tractor manual. + +All public libraries have been extremely enthusiastic, supportive, and +appreciative of the work that AM has been doing. VECCIA characterized +various users: Most users in public libraries describe themselves as +general readers; of the students who use AM in the public libraries, +those in fourth grade and above seem most interested. Public libraries +in rural sites tend to attract retired people, who have been highly +receptive to AM. Users tend to fall into two additional categories: +people interested in the content and historical connotations of these +primary resources, and those fascinated by the technology. The format +receiving the most comments has been motion pictures. The adult users in +public libraries are more comfortable with IBM computers, whereas young +people seem comfortable with either IBM or Macintosh, although most of +them seem to come from a Macintosh background. This same tendency is +found in the schools. + +What kinds of things do users do with AM? In a public library there are +two main goals or ways that AM is being used: as an individual learning +tool, and as a leisure activity. Adult learning was one area that VECCIA +would highlight as a possible application for a tool such as AM. She +described a patron of a rural public library who comes in every day on +his lunch hour and literally reads AM, methodically going through the +collection image by image. At the end of his hour he makes an electronic +bookmark, puts it in his pocket, and returns to work. The next day he +comes in and resumes where he left off. Interestingly, this man had +never been in the library before he used AM. In another small, rural +library, the coordinator reports that AM is a popular activity for some +of the older, retired people in the community, who ordinarily would not +use "those things,"--computers. Another example of adult learning in +public libraries is book groups, one of which, in particular, is using AM +as part of its reading on industrialization, integration, and urbanization +in the early 1900s. + +One library reports that a family is using AM to help educate their +children. In another instance, individuals from a local museum came in +to use AM to prepare an exhibit on toys of the past. These two examples +emphasize the mission of the public library as a cultural institution, +reaching out to people who do not have the same resources available to +those who live in a metropolitan area or have access to a major library. +One rural library reports that junior high school students in large +numbers came in one afternoon to use AM for entertainment. A number of +public libraries reported great interest among postcard collectors in the +Detroit collection, which was essentially a collection of images used on +postcards around the turn of the century. Train buffs are similarly +interested because that was a time of great interest in railroading. +People, it was found, relate to things that they know of firsthand. For +example, in both rural public libraries where AM was made available, +observers reported that the older people with personal remembrances of +the turn of the century were gravitating to the Detroit collection. +These examples served to underscore MICHELSON's observation re the +integration of electronic tools and ideas--that people learn best when +the material relates to something they know. + +VECCIA made the final point that in many cases AM serves as a +public-relations tool for the public libraries that are testing it. In +one case, AM is being used as a vehicle to secure additional funding for +the library. In another case, AM has served as an inspiration to the +staff of a major local public library in the South to think about ways to +make its own collection of photographs more accessible to the public. + + ****** + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +FREEMAN * AM and archival electronic resources in a school environment * +Questions concerning context * Questions concerning the electronic format +itself * Computer anxiety * Access and availability of the system * +Hardware * Strengths gained through the use of archival resources in +schools * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Reiterating an observation made by VECCIA, that AM is an archival +resource made up of primary materials with very little interpretation, +FREEMAN stated that the project has attempted to bridge the gap between +these bare primary materials and a school environment, and in that cause +has created guided introductions to AM collections. Loud demand from the +educational community, chiefly from teachers working with the upper +grades of elementary school through high school, greeted the announcement +that AM would be tested around the country. + +FREEMAN reported not only on what was learned about AM in a school +environment, but also on several universal questions that were raised +concerning archival electronic resources in schools. She discussed +several strengths of this type of material in a school environment as +opposed to a highly structured resource that offers a limited number of +paths to follow. + +FREEMAN first raised several questions about using AM in a school +environment. There is often some difficulty in developing a sense of +what the system contains. Many students sit down at a computer resource +and assume that, because AM comes from the Library of Congress, all of +American history is now at their fingertips. As a result of that sort of +mistaken judgment, some students are known to conclude that AM contains +nothing of use to them when they look for one or two things and do not +find them. It is difficult to discover that middle ground where one has +a sense of what the system contains. Some students grope toward the idea +of an archive, a new idea to them, since they have not previously +experienced what it means to have access to a vast body of somewhat +random information. + +Other questions raised by FREEMAN concerned the electronic format itself. +For instance, in a school environment it is often difficult both for +teachers and students to gain a sense of what it is they are viewing. +They understand that it is a visual image, but they do not necessarily +know that it is a postcard from the turn of the century, a panoramic +photograph, or even machine-readable text of an eighteenth-century +broadside, a twentieth-century printed book, or a nineteenth-century +diary. That distinction is often difficult for people in a school +environment to grasp. Because of that, it occasionally becomes difficult +to draw conclusions from what one is viewing. + +FREEMAN also noted the obvious fear of the computer, which constitutes a +difficulty in using an electronic resource. Though students in general +did not suffer from this anxiety, several older students feared that they +were computer-illiterate, an assumption that became self-fulfilling when +they searched for something but failed to find it. FREEMAN said she +believed that some teachers also fear computer resources, because they +believe they lack complete control. FREEMAN related the example of +teachers shooing away students because it was not their time to use the +system. This was a case in which the situation had to be extremely +structured so that the teachers would not feel that they had lost their +grasp on what the system contained. + +A final question raised by FREEMAN concerned access and availability of +the system. She noted the occasional existence of a gap in communication +between school librarians and teachers. Often AM sits in a school +library and the librarian is the person responsible for monitoring the +system. Teachers do not always take into their world new library +resources about which the librarian is excited. Indeed, at the sites +where AM had been used most effectively within a library, the librarian +was required to go to specific teachers and instruct them in its use. As +a result, several AM sites will have in-service sessions over a summer, +in the hope that perhaps, with a more individualized link, teachers will +be more likely to use the resource. + +A related issue in the school context concerned the number of +workstations available at any one location. Centralization of equipment +at the district level, with teachers invited to download things and walk +away with them, proved unsuccessful because the hours these offices were +open were also school hours. + +Another issue was hardware. As VECCIA observed, a range of sites exists, +some technologically advanced and others essentially acquiring their +first computer for the primary purpose of using it in conjunction with +AM's testing. Users at technologically sophisticated sites want even +more sophisticated hardware, so that they can perform even more +sophisticated tasks with the materials in AM. But once they acquire a +newer piece of hardware, they must learn how to use that also; at an +unsophisticated site it takes an extremely long time simply to become +accustomed to the computer, not to mention the program offered with the +computer. All of these small issues raise one large question, namely, +are systems like AM truly rewarding in a school environment, or do they +simply act as innovative toys that do little more than spark interest? + +FREEMAN contended that the evaluation project has revealed several strengths +that were gained through the use of archival resources in schools, including: + + * Psychic rewards from using AM as a vast, rich database, with + teachers assigning various projects to students--oral presentations, + written reports, a documentary, a turn-of-the-century newspaper-- + projects that start with the materials in AM but are completed using + other resources; AM thus is used as a research tool in conjunction + with other electronic resources, as well as with books and items in + the library where the system is set up. + + * Students are acquiring computer literacy in a humanities context. + + * This sort of system is overcoming the isolation between disciplines + that often exists in schools. For example, many English teachers are + requiring their students to write papers on historical topics + represented in AM. Numerous teachers have reported that their + students are learning critical thinking skills using the system. + + * On a broader level, AM is introducing primary materials, not only + to students but also to teachers, in an environment where often + simply none exist--an exciting thing for the students because it + helps them learn to conduct research, to interpret, and to draw + their own conclusions. In learning to conduct research and what it + means, students are motivated to seek knowledge. That relates to + another positive outcome--a high level of personal involvement of + students with the materials in this system and greater motivation to + conduct their own research and draw their own conclusions. + + * Perhaps the most ironic strength of these kinds of archival + electronic resources is that many of the teachers AM interviewed + were desperate, it is no exaggeration to say, not only for primary + materials but for unstructured primary materials. These would, they + thought, foster personally motivated research, exploration, and + excitement in their students. Indeed, these materials have done + just that. Ironically, however, this lack of structure produces + some of the confusion to which the newness of these kinds of + resources may also contribute. The key to effective use of archival + products in a school environment is a clear, effective introduction + to the system and to what it contains. + + ****** + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +DISCUSSION * Nothing known, quantitatively, about the number of +humanities scholars who must see the original versus those who would +settle for an edited transcript, or about the ways in which humanities +scholars are using information technology * Firm conclusions concerning +the manner and extent of the use of supporting materials in print +provided by AM to await completion of evaluative study * A listener's +reflections on additional applications of electronic texts * Role of +electronic resources in teaching elementary research skills to students * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +During the discussion that followed the presentations by MICHELSON, +VECCIA, and FREEMAN, additional points emerged. + +LESK asked if MICHELSON could give any quantitative estimate of the +number of humanities scholars who must see or want to see the original, +or the best possible version of the material, versus those who typically +would settle for an edited transcript. While unable to provide a figure, +she offered her impressions as an archivist who has done some reference +work and has discussed this issue with other archivists who perform +reference, that those who use archives and those who use primary sources +for what would be considered very high-level scholarly research, as +opposed to, say, undergraduate papers, were few in number, especially +given the public interest in using primary sources to conduct +genealogical or avocational research and the kind of professional +research done by people in private industry or the federal government. +More important in MICHELSON's view was that, quantitatively, nothing is +known about the ways in which, for example, humanities scholars are using +information technology. No studies exist to offer guidance in creating +strategies. The most recent study was conducted in 1985 by the American +Council of Learned Societies (ACLS), and what it showed was that 50 +percent of humanities scholars at that time were using computers. That +constitutes the extent of our knowledge. + +Concerning AM's strategy for orienting people toward the scope of +electronic resources, FREEMAN could offer no hard conclusions at this +point, because she and her colleagues were still waiting to see, +particularly in the schools, what has been made of their efforts. Within +the system, however, AM has provided what are called electronic exhibits- +-such as introductions to time periods and materials--and these are +intended to offer a student user a sense of what a broadside is and what +it might tell her or him. But FREEMAN conceded that the project staff +would have to talk with students next year, after teachers have had a +summer to use the materials, and attempt to discover what the students +were learning from the materials. In addition, FREEMAN described +supporting materials in print provided by AM at the request of local +teachers during a meeting held at LC. These included time lines, +bibliographies, and other materials that could be reproduced on a +photocopier in a classroom. Teachers could walk away with and use these, +and in this way gain a better understanding of the contents. But again, +reaching firm conclusions concerning the manner and extent of their use +would have to wait until next year. + +As to the changes she saw occurring at the National Archives and Records +Administration (NARA) as a result of the increasing emphasis on +technology in scholarly research, MICHELSON stated that NARA at this +point was absorbing the report by her and Jeff Rothenberg addressing +strategies for the archival profession in general, although not for the +National Archives specifically. NARA is just beginning to establish its +role and what it can do. In terms of changes and initiatives that NARA +can take, no clear response could be given at this time. + +GREENFIELD remarked two trends mentioned in the session. Reflecting on +DALY's opening comments on how he could have used a Latin collection of +text in an electronic form, he said that at first he thought most scholars +would be unwilling to do that. But as he thought of that in terms of the +original meaning of research--that is, having already mastered these texts, +researching them for critical and comparative purposes--for the first time, +the electronic format made a lot of sense. GREENFIELD could envision +growing numbers of scholars learning the new technologies for that very +aspect of their scholarship and for convenience's sake. + +Listening to VECCIA and FREEMAN, GREENFIELD thought of an additional +application of electronic texts. He realized that AM could be used as a +guide to lead someone to original sources. Students cannot be expected +to have mastered these sources, things they have never known about +before. Thus, AM is leading them, in theory, to a vast body of +information and giving them a superficial overview of it, enabling them +to select parts of it. GREENFIELD asked if any evidence exists that this +resource will indeed teach the new user, the K-12 students, how to do +research. Scholars already know how to do research and are applying +these new tools. But he wondered why students would go beyond picking +out things that were most exciting to them. + +FREEMAN conceded the correctness of GREENFIELD's observation as applied +to a school environment. The risk is that a student would sit down at a +system, play with it, find some things of interest, and then walk away. +But in the relatively controlled situation of a school library, much will +depend on the instructions a teacher or a librarian gives a student. She +viewed the situation not as one of fine-tuning research skills but of +involving students at a personal level in understanding and researching +things. Given the guidance one can receive at school, it then becomes +possible to teach elementary research skills to students, which in fact +one particular librarian said she was teaching her fifth graders. +FREEMAN concluded that introducing the idea of following one's own path +of inquiry, which is essentially what research entails, involves more +than teaching specific skills. To these comments VECCIA added the +observation that the individual teacher and the use of a creative +resource, rather than AM itself, seemed to make the key difference. +Some schools and some teachers are making excellent use of the nature +of critical thinking and teaching skills, she said. + +Concurring with these remarks, DALY closed the session with the thought that +the more that producers produced for teachers and for scholars to use with +their students, the more successful their electronic products would prove. + + ****** + +SESSION II. SHOW AND TELL + +Jacqueline HESS, director, National Demonstration Laboratory, served as +moderator of the "show-and-tell" session. She noted that a +question-and-answer period would follow each presentation. + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +MYLONAS * Overview and content of Perseus * Perseus' primary materials +exist in a system-independent, archival form * A concession * Textual +aspects of Perseus * Tools to use with the Greek text * Prepared indices +and full-text searches in Perseus * English-Greek word search leads to +close study of words and concepts * Navigating Perseus by tracing down +indices * Using the iconography to perform research * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Elli MYLONAS, managing editor, Perseus Project, Harvard University, first +gave an overview of Perseus, a large, collaborative effort based at +Harvard University but with contributors and collaborators located at +numerous universities and colleges in the United States (e.g., Bowdoin, +Maryland, Pomona, Chicago, Virginia). Funded primarily by the +Annenberg/CPB Project, with additional funding from Apple, Harvard, and +the Packard Humanities Institute, among others, Perseus is a multimedia, +hypertextual database for teaching and research on classical Greek +civilization, which was released in February 1992 in version 1.0 and +distributed by Yale University Press. + +Consisting entirely of primary materials, Perseus includes ancient Greek +texts and translations of those texts; catalog entries--that is, museum +catalog entries, not library catalog entries--on vases, sites, coins, +sculpture, and archaeological objects; maps; and a dictionary, among +other sources. The number of objects and the objects for which catalog +entries exist are accompanied by thousands of color images, which +constitute a major feature of the database. Perseus contains +approximately 30 megabytes of text, an amount that will double in +subsequent versions. In addition to these primary materials, the Perseus +Project has been building tools for using them, making access and +navigation easier, the goal being to build part of the electronic +environment discussed earlier in the morning in which students or +scholars can work with their sources. + +The demonstration of Perseus will show only a fraction of the real work +that has gone into it, because the project had to face the dilemma of +what to enter when putting something into machine-readable form: should +one aim for very high quality or make concessions in order to get the +material in? Since Perseus decided to opt for very high quality, all of +its primary materials exist in a system-independent--insofar as it is +possible to be system-independent--archival form. Deciding what that +archival form would be and attaining it required much work and thought. +For example, all the texts are marked up in SGML, which will be made +compatible with the guidelines of the Text Encoding Initiative (TEI) when +they are issued. + +Drawings are postscript files, not meeting international standards, but +at least designed to go across platforms. Images, or rather the real +archival forms, consist of the best available slides, which are being +digitized. Much of the catalog material exists in database form--a form +that the average user could use, manipulate, and display on a personal +computer, but only at great cost. Thus, this is where the concession +comes in: All of this rich, well-marked-up information is stripped of +much of its content; the images are converted into bit-maps and the text +into small formatted chunks. All this information can then be imported +into HyperCard and run on a mid-range Macintosh, which is what Perseus +users have. This fact has made it possible for Perseus to attain wide +use fairly rapidly. Without those archival forms the HyperCard version +being demonstrated could not be made easily, and the project could not +have the potential to move to other forms and machines and software as +they appear, none of which information is in Perseus on the CD. + +Of the numerous multimedia aspects of Perseus, MYLONAS focused on the +textual. Part of what makes Perseus such a pleasure to use, MYLONAS +said, is this effort at seamless integration and the ability to move +around both visual and textual material. Perseus also made the decision +not to attempt to interpret its material any more than one interprets by +selecting. But, MYLONAS emphasized, Perseus is not courseware: No +syllabus exists. There is no effort to define how one teaches a topic +using Perseus, although the project may eventually collect papers by +people who have used it to teach. Rather, Perseus aims to provide +primary material in a kind of electronic library, an electronic sandbox, +so to say, in which students and scholars who are working on this +material can explore by themselves. With that, MYLONAS demonstrated +Perseus, beginning with the Perseus gateway, the first thing one sees +upon opening Perseus--an effort in part to solve the contextualizing +problem--which tells the user what the system contains. + +MYLONAS demonstrated only a very small portion, beginning with primary +texts and running off the CD-ROM. Having selected Aeschylus' Prometheus +Bound, which was viewable in Greek and English pretty much in the same +segments together, MYLONAS demonstrated tools to use with the Greek text, +something not possible with a book: looking up the dictionary entry form +of an unfamiliar word in Greek after subjecting it to Perseus' +morphological analysis for all the texts. After finding out about a +word, a user may then decide to see if it is used anywhere else in Greek. +Because vast amounts of indexing support all of the primary material, one +can find out where else all forms of a particular Greek word appear-- +often not a trivial matter because Greek is highly inflected. Further, +since the story of Prometheus has to do with the origins of sacrifice, a +user may wish to study and explore sacrifice in Greek literature; by +typing sacrifice into a small window, a user goes to the English-Greek +word list--something one cannot do without the computer (Perseus has +indexed the definitions of its dictionary)--the string sacrifice appears +in the definitions of these sixty-five words. One may then find out +where any of those words is used in the work(s) of a particular author. +The English definitions are not lemmatized. + +All of the indices driving this kind of usage were originally devised for +speed, MYLONAS observed; in other words, all that kind of information-- +all forms of all words, where they exist, the dictionary form they belong +to--were collected into databases, which will expedite searching. Then +it was discovered that one can do things searching in these databases +that could not be done searching in the full texts. Thus, although there +are full-text searches in Perseus, much of the work is done behind the +scenes, using prepared indices. Re the indexing that is done behind the +scenes, MYLONAS pointed out that without the SGML forms of the text, it +could not be done effectively. Much of this indexing is based on the +structures that are made explicit by the SGML tagging. + +It was found that one of the things many of Perseus' non-Greek-reading +users do is start from the dictionary and then move into the close study +of words and concepts via this kind of English-Greek word search, by which +means they might select a concept. This exercise has been assigned to +students in core courses at Harvard--to study a concept by looking for the +English word in the dictionary, finding the Greek words, and then finding +the words in the Greek but, of course, reading across in the English. +That tells them a great deal about what a translation means as well. + +Should one also wish to see images that have to do with sacrifice, that +person would go to the object key word search, which allows one to +perform a similar kind of index retrieval on the database of +archaeological objects. Without words, pictures are useless; Perseus has +not reached the point where it can do much with images that are not +cataloged. Thus, although it is possible in Perseus with text and images +to navigate by knowing where one wants to end up--for example, a +red-figure vase from the Boston Museum of Fine Arts--one can perform this +kind of navigation very easily by tracing down indices. MYLONAS +illustrated several generic scenes of sacrifice on vases. The features +demonstrated derived from Perseus 1.0; version 2.0 will implement even +better means of retrieval. + +MYLONAS closed by looking at one of the pictures and noting again that +one can do a great deal of research using the iconography as well as the +texts. For instance, students in a core course at Harvard this year were +highly interested in Greek concepts of foreigners and representations of +non-Greeks. So they performed a great deal of research, both with texts +(e.g., Herodotus) and with iconography on vases and coins, on how the +Greeks portrayed non-Greeks. At the same time, art historians who study +iconography were also interested, and were able to use this material. + + ****** + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +DISCUSSION * Indexing and searchability of all English words in Perseus * +Several features of Perseus 1.0 * Several levels of customization +possible * Perseus used for general education * Perseus' effects on +education * Contextual information in Perseus * Main challenge and +emphasis of Perseus * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Several points emerged in the discussion that followed MYLONAS's presentation. + +Although MYLONAS had not demonstrated Perseus' ability to cross-search +documents, she confirmed that all English words in Perseus are indexed +and can be searched. So, for example, sacrifice could have been searched +in all texts, the historical essay, and all the catalogue entries with +their descriptions--in short, in all of Perseus. + +Boolean logic is not in Perseus 1.0 but will be added to the next +version, although an effort is being made not to restrict Perseus to a +database in which one just performs searching, Boolean or otherwise. It +is possible to move laterally through the documents by selecting a word +one is interested in and selecting an area of information one is +interested in and trying to look that word up in that area. + +Since Perseus was developed in HyperCard, several levels of customization +are possible. Simple authoring tools exist that allow one to create +annotated paths through the information, which are useful for note-taking +and for guided tours for teaching purposes and for expository writing. +With a little more ingenuity it is possible to begin to add or substitute +material in Perseus. + +Perseus has not been used so much for classics education as for general +education, where it seemed to have an impact on the students in the core +course at Harvard (a general required course that students must take in +certain areas). Students were able to use primary material much more. + +The Perseus Project has an evaluation team at the University of Maryland +that has been documenting Perseus' effects on education. Perseus is very +popular, and anecdotal evidence indicates that it is having an effect at +places other than Harvard, for example, test sites at Ball State +University, Drury College, and numerous small places where opportunities +to use vast amounts of primary data may not exist. One documented effect +is that archaeological, anthropological, and philological research is +being done by the same person instead of by three different people. + +The contextual information in Perseus includes an overview essay, a +fairly linear historical essay on the fifth century B.C. that provides +links into the primary material (e.g., Herodotus, Thucydides, and +Plutarch), via small gray underscoring (on the screen) of linked +passages. These are handmade links into other material. + +To different extents, most of the production work was done at Harvard, +where the people and the equipment are located. Much of the +collaborative activity involved data collection and structuring, because +the main challenge and the emphasis of Perseus is the gathering of +primary material, that is, building a useful environment for studying +classical Greece, collecting data, and making it useful. +Systems-building is definitely not the main concern. Thus, much of the +work has involved writing essays, collecting information, rewriting it, +and tagging it. That can be done off site. The creative link for the +overview essay as well as for both systems and data was collaborative, +and was forged via E-mail and paper mail with professors at Pomona and +Bowdoin. + + ****** + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +CALALUCA * PLD's principal focus and contribution to scholarship * +Various questions preparatory to beginning the project * Basis for +project * Basic rule in converting PLD * Concerning the images in PLD * +Running PLD under a variety of retrieval softwares * Encoding the +database a hard-fought issue * Various features demonstrated * Importance +of user documentation * Limitations of the CD-ROM version * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Eric CALALUCA, vice president, Chadwyck-Healey, Inc., demonstrated a +software interpretation of the Patrologia Latina Database (PLD). PLD's +principal focus from the beginning of the project about three-and-a-half +years ago was on converting Migne's Latin series, and in the end, +CALALUCA suggested, conversion of the text will be the major contribution +to scholarship. CALALUCA stressed that, as possibly the only private +publishing organization at the Workshop, Chadwyck-Healey had sought no +federal funds or national foundation support before embarking upon the +project, but instead had relied upon a great deal of homework and +marketing to accomplish the task of conversion. + +Ever since the possibilities of computer-searching have emerged, scholars +in the field of late ancient and early medieval studies (philosophers, +theologians, classicists, and those studying the history of natural law +and the history of the legal development of Western civilization) have +been longing for a fully searchable version of Western literature, for +example, all the texts of Augustine and Bernard of Clairvaux and +Boethius, not to mention all the secondary and tertiary authors. + +Various questions arose, CALALUCA said. Should one convert Migne? +Should the database be encoded? Is it necessary to do that? How should +it be delivered? What about CD-ROM? Since this is a transitional +medium, why even bother to create software to run on a CD-ROM? Since +everybody knows people will be networking information, why go to the +trouble--which is far greater with CD-ROM than with the production of +magnetic data? Finally, how does one make the data available? Can many +of the hurdles to using electronic information that some publishers have +imposed upon databases be eliminated? + +The PLD project was based on the principle that computer-searching of +texts is most effective when it is done with a large database. Because +PLD represented a collection that serves so many disciplines across so +many periods, it was irresistible. + +The basic rule in converting PLD was to do no harm, to avoid the sins of +intrusion in such a database: no introduction of newer editions, no +on-the-spot changes, no eradicating of all possible falsehoods from an +edition. Thus, PLD is not the final act in electronic publishing for +this discipline, but simply the beginning. The conversion of PLD has +evoked numerous unanticipated questions: How will information be used? +What about networking? Can the rights of a database be protected? +Should one protect the rights of a database? How can it be made +available? + +Those converting PLD also tried to avoid the sins of omission, that is, +excluding portions of the collections or whole sections. What about the +images? PLD is full of images, some are extremely pious +nineteenth-century representations of the Fathers, while others contain +highly interesting elements. The goal was to cover all the text of Migne +(including notes, in Greek and in Hebrew, the latter of which, in +particular, causes problems in creating a search structure), all the +indices, and even the images, which are being scanned in separately +searchable files. + +Several North American institutions that have placed acquisition requests +for the PLD database have requested it in magnetic form without software, +which means they are already running it without software, without +anything demonstrated at the Workshop. + +What cannot practically be done is go back and reconvert and re-encode +data, a time-consuming and extremely costly enterprise. CALALUCA sees +PLD as a database that can, and should, be run under a variety of +retrieval softwares. This will permit the widest possible searches. +Consequently, the need to produce a CD-ROM of PLD, as well as to develop +software that could handle some 1.3 gigabyte of heavily encoded text, +developed out of conversations with collection development and reference +librarians who wanted software both compassionate enough for the +pedestrian but also capable of incorporating the most detailed +lexicographical studies that a user desires to conduct. In the end, the +encoding and conversion of the data will prove the most enduring +testament to the value of the project. + +The encoding of the database was also a hard-fought issue: Did the +database need to be encoded? Were there normative structures for encoding +humanist texts? Should it be SGML? What about the TEI--will it last, +will it prove useful? CALALUCA expressed some minor doubts as to whether +a data bank can be fully TEI-conformant. Every effort can be made, but +in the end to be TEI-conformant means to accept the need to make some +firm encoding decisions that can, indeed, be disputed. The TEI points +the publisher in a proper direction but does not presume to make all the +decisions for him or her. Essentially, the goal of encoding was to +eliminate, as much as possible, the hindrances to information-networking, +so that if an institution acquires a database, everybody associated with +the institution can have access to it. + +CALALUCA demonstrated a portion of Volume 160, because it had the most +anomalies in it. The software was created by Electronic Book +Technologies of Providence, RI, and is called Dynatext. The software +works only with SGML-coded data. + +Viewing a table of contents on the screen, the audience saw how Dynatext +treats each element as a book and attempts to simplify movement through a +volume. Familiarity with the Patrologia in print (i.e., the text, its +source, and the editions) will make the machine-readable versions highly +useful. (Software with a Windows application was sought for PLD, +CALALUCA said, because this was the main trend for scholarly use.) + +CALALUCA also demonstrated how a user can perform a variety of searches +and quickly move to any part of a volume; the look-up screen provides +some basic, simple word-searching. + +CALALUCA argued that one of the major difficulties is not the software. +Rather, in creating a product that will be used by scholars representing +a broad spectrum of computer sophistication, user documentation proves +to be the most important service one can provide. + +CALALUCA next illustrated a truncated search under mysterium within ten +words of virtus and how one would be able to find its contents throughout +the entire database. He said that the exciting thing about PLD is that +many of the applications in the retrieval software being written for it +will exceed the capabilities of the software employed now for the CD-ROM +version. The CD-ROM faces genuine limitations, in terms of speed and +comprehensiveness, in the creation of a retrieval software to run it. +CALALUCA said he hoped that individual scholars will download the data, +if they wish, to their personal computers, and have ready access to +important texts on a constant basis, which they will be able to use in +their research and from which they might even be able to publish. + +(CALALUCA explained that the blue numbers represented Migne's column numbers, +which are the standard scholarly references. Pulling up a note, he stated +that these texts were heavily edited and the image files would appear simply +as a note as well, so that one could quickly access an image.) + + ****** + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +FLEISCHHAUER/ERWAY * Several problems with which AM is still wrestling * +Various search and retrieval capabilities * Illustration of automatic +stemming and a truncated search * AM's attempt to find ways to connect +cataloging to the texts * AM's gravitation towards SGML * Striking a +balance between quantity and quality * How AM furnishes users recourse to +images * Conducting a search in a full-text environment * Macintosh and +IBM prototypes of AM * Multimedia aspects of AM * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +A demonstration of American Memory by its coordinator, Carl FLEISCHHAUER, +and Ricky ERWAY, associate coordinator, Library of Congress, concluded +the morning session. Beginning with a collection of broadsides from the +Continental Congress and the Constitutional Convention, the only text +collection in a presentable form at the time of the Workshop, FLEISCHHAUER +highlighted several of the problems with which AM is still wrestling. +(In its final form, the disk will contain two collections, not only the +broadsides but also the full text with illustrations of a set of +approximately 300 African-American pamphlets from the period 1870 to 1910.) + +As FREEMAN had explained earlier, AM has attempted to use a small amount +of interpretation to introduce collections. In the present case, the +contractor, a company named Quick Source, in Silver Spring, MD., used +software called Toolbook and put together a modestly interactive +introduction to the collection. Like the two preceding speakers, +FLEISCHHAUER argued that the real asset was the underlying collection. + +FLEISCHHAUER proceeded to describe various search and retrieval +capabilities while ERWAY worked the computer. In this particular package +the "go to" pull-down allowed the user in effect to jump out of Toolbook, +where the interactive program was located, and enter the third-party +software used by AM for this text collection, which is called Personal +Librarian. This was the Windows version of Personal Librarian, a +software application put together by a company in Rockville, Md. + +Since the broadsides came from the Revolutionary War period, a search was +conducted using the words British or war, with the default operator reset +as or. FLEISCHHAUER demonstrated both automatic stemming (which finds +other forms of the same root) and a truncated search. One of Personal +Librarian's strongest features, the relevance ranking, was represented by +a chart that indicated how often words being sought appeared in +documents, with the one receiving the most "hits" obtaining the highest +score. The "hit list" that is supplied takes the relevance ranking into +account, making the first hit, in effect, the one the software has +selected as the most relevant example. + +While in the text of one of the broadside documents, FLEISCHHAUER +remarked AM's attempt to find ways to connect cataloging to the texts, +which it does in different ways in different manifestations. In the case +shown, the cataloging was pasted on: AM took MARC records that were +written as on-line records right into one of the Library's mainframe +retrieval programs, pulled them out, and handed them off to the contractor, +who massaged them somewhat to display them in the manner shown. One of +AM's questions is, Does the cataloguing normally performed in the mainframe +work in this context, or had AM ought to think through adjustments? + +FLEISCHHAUER made the additional point that, as far as the text goes, AM +has gravitated towards SGML (he pointed to the boldface in the upper part +of the screen). Although extremely limited in its ability to translate +or interpret SGML, Personal Librarian will furnish both bold and italics +on screen; a fairly easy thing to do, but it is one of the ways in which +SGML is useful. + +Striking a balance between quantity and quality has been a major concern +of AM, with accuracy being one of the places where project staff have +felt that less than 100-percent accuracy was not unacceptable. +FLEISCHHAUER cited the example of the standard of the rekeying industry, +namely 99.95 percent; as one service bureau informed him, to go from +99.95 to 100 percent would double the cost. + +FLEISCHHAUER next demonstrated how AM furnishes users recourse to images, +and at the same time recalled LESK's pointed question concerning the +number of people who would look at those images and the number who would +work only with the text. If the implication of LESK's question was +sound, FLEISCHHAUER said, it raised the stakes for text accuracy and +reduced the value of the strategy for images. + +Contending that preservation is always a bugaboo, FLEISCHHAUER +demonstrated several images derived from a scan of a preservation +microfilm that AM had made. He awarded a grade of C at best, perhaps a +C minus or a C plus, for how well it worked out. Indeed, the matter of +learning if other people had better ideas about scanning in general, and, +in particular, scanning from microfilm, was one of the factors that drove +AM to attempt to think through the agenda for the Workshop. Skew, for +example, was one of the issues that AM in its ignorance had not reckoned +would prove so difficult. + +Further, the handling of images of the sort shown, in a desktop computer +environment, involved a considerable amount of zooming and scrolling. +Ultimately, AM staff feel that perhaps the paper copy that is printed out +might be the most useful one, but they remain uncertain as to how much +on-screen reading users will do. + +Returning to the text, FLEISCHHAUER asked viewers to imagine a person who +might be conducting a search in a full-text environment. With this +scenario, he proceeded to illustrate other features of Personal Librarian +that he considered helpful; for example, it provides the ability to +notice words as one reads. Clicking the "include" button on the bottom +of the search window pops the words that have been highlighted into the +search. Thus, a user can refine the search as he or she reads, +re-executing the search and continuing to find things in the quest for +materials. This software not only contains relevance ranking, Boolean +operators, and truncation, it also permits one to perform word algebra, +so to say, where one puts two or three words in parentheses and links +them with one Boolean operator and then a couple of words in another set +of parentheses and asks for things within so many words of others. + +Until they became acquainted recently with some of the work being done in +classics, the AM staff had not realized that a large number of the +projects that involve electronic texts were being done by people with a +profound interest in language and linguistics. Their search strategies +and thinking are oriented to those fields, as is shown in particular by +the Perseus example. As amateur historians, the AM staff were thinking +more of searching for concepts and ideas than for particular words. +Obviously, FLEISCHHAUER conceded, searching for concepts and ideas and +searching for words may be two rather closely related things. + +While displaying several images, FLEISCHHAUER observed that the Macintosh +prototype built by AM contains a greater diversity of formats. Echoing a +previous speaker, he said that it was easier to stitch things together in +the Macintosh, though it tended to be a little more anemic in search and +retrieval. AM, therefore, increasingly has been investigating +sophisticated retrieval engines in the IBM format. + +FLEISCHHAUER demonstrated several additional examples of the prototype +interfaces: One was AM's metaphor for the network future, in which a +kind of reading-room graphic suggests how one would be able to go around +to different materials. AM contains a large number of photographs in +analog video form worked up from a videodisc, which enable users to make +copies to print or incorporate in digital documents. A frame-grabber is +built into the system, making it possible to bring an image into a window +and digitize or print it out. + +FLEISCHHAUER next demonstrated sound recording, which included texts. +Recycled from a previous project, the collection included sixty 78-rpm +phonograph records of political speeches that were made during and +immediately after World War I. These constituted approximately three +hours of audio, as AM has digitized it, which occupy 150 megabytes on a +CD. Thus, they are considerably compressed. From the catalogue card, +FLEISCHHAUER proceeded to a transcript of a speech with the audio +available and with highlighted text following it as it played. +A photograph has been added and a transcription made. + +Considerable value has been added beyond what the Library of Congress +normally would do in cataloguing a sound recording, which raises several +questions for AM concerning where to draw lines about how much value it can +afford to add and at what point, perhaps, this becomes more than AM could +reasonably do or reasonably wish to do. FLEISCHHAUER also demonstrated +a motion picture. As FREEMAN had reported earlier, the motion picture +materials have proved the most popular, not surprisingly. This says more +about the medium, he thought, than about AM's presentation of it. + +Because AM's goal was to bring together things that could be used by +historians or by people who were curious about history, +turn-of-the-century footage seemed to represent the most appropriate +collections from the Library of Congress in motion pictures. These were +the very first films made by Thomas Edison's company and some others at +that time. The particular example illustrated was a Biograph film, +brought in with a frame-grabber into a window. A single videodisc +contains about fifty titles and pieces of film from that period, all of +New York City. Taken together, AM believes, they provide an interesting +documentary resource. + + ****** + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +DISCUSSION * Using the frame-grabber in AM * Volume of material processed +and to be processed * Purpose of AM within LC * Cataloguing and the +nature of AM's material * SGML coding and the question of quality versus +quantity * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +During the question-and-answer period that followed FLEISCHHAUER's +presentation, several clarifications were made. + +AM is bringing in motion pictures from a videodisc. The frame-grabber +devices create a window on a computer screen, which permits users to +digitize a single frame of the movie or one of the photographs. It +produces a crude, rough-and-ready image that high school students can +incorporate into papers, and that has worked very nicely in this way. + +Commenting on FLEISCHHAUER's assertion that AM was looking more at +searching ideas than words, MYLONAS argued that without words an idea +does not exist. FLEISCHHAUER conceded that he ought to have articulated +his point more clearly. MYLONAS stated that they were in fact both +talking about the same thing. By searching for words and by forcing +people to focus on the word, the Perseus Project felt that they would get +them to the idea. The way one reviews results is tailored more to one +kind of user than another. + +Concerning the total volume of material that has been processed in this +way, AM at this point has in retrievable form seven or eight collections, +all of them photographic. In the Macintosh environment, for example, +there probably are 35,000-40,000 photographs. The sound recordings +number sixty items. The broadsides number about 300 items. There are +500 political cartoons in the form of drawings. The motion pictures, as +individual items, number sixty to seventy. + +AM also has a manuscript collection, the life history portion of one of +the federal project series, which will contain 2,900 individual +documents, all first-person narratives. AM has in process about 350 +African-American pamphlets, or about 12,000 printed pages for the period +1870-1910. Also in the works are some 4,000 panoramic photographs. AM +has recycled a fair amount of the work done by LC's Prints and +Photographs Division during the Library's optical disk pilot project in +the 1980s. For example, a special division of LC has tooled up and +thought through all the ramifications of electronic presentation of +photographs. Indeed, they are wheeling them out in great barrel loads. +The purpose of AM within the Library, it is hoped, is to catalyze several +of the other special collection divisions which have no particular +experience with, in some cases, mixed feelings about, an activity such as +AM. Moreover, in many cases the divisions may be characterized as not +only lacking experience in "electronifying" things but also in automated +cataloguing. MARC cataloguing as practiced in the United States is +heavily weighted toward the description of monograph and serial +materials, but is much thinner when one enters the world of manuscripts +and things that are held in the Library's music collection and other +units. In response to a comment by LESK, that AM's material is very +heavily photographic, and is so primarily because individual records have +been made for each photograph, FLEISCHHAUER observed that an item-level +catalog record exists, for example, for each photograph in the Detroit +Publishing collection of 25,000 pictures. In the case of the Federal +Writers Project, for which nearly 3,000 documents exist, representing +information from twenty-six different states, AM with the assistance of +Karen STUART of the Manuscript Division will attempt to find some way not +only to have a collection-level record but perhaps a MARC record for each +state, which will then serve as an umbrella for the 100-200 documents +that come under it. But that drama remains to be enacted. The AM staff +is conservative and clings to cataloguing, though of course visitors tout +artificial intelligence and neural networks in a manner that suggests that +perhaps one need not have cataloguing or that much of it could be put aside. + +The matter of SGML coding, FLEISCHHAUER conceded, returned the discussion +to the earlier treated question of quality versus quantity in the Library +of Congress. Of course, text conversion can be done with 100-percent +accuracy, but it means that when one's holdings are as vast as LC's only +a tiny amount will be exposed, whereas permitting lower levels of +accuracy can lead to exposing or sharing larger amounts, but with the +quality correspondingly impaired. + + ****** + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +TWOHIG * A contrary experience concerning electronic options * Volume of +material in the Washington papers and a suggestion of David Packard * +Implications of Packard's suggestion * Transcribing the documents for the +CD-ROM * Accuracy of transcriptions * The CD-ROM edition of the Founding +Fathers documents * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Finding encouragement in a comment of MICHELSON's from the morning +session--that numerous people in the humanities were choosing electronic +options to do their work--Dorothy TWOHIG, editor, The Papers of George +Washington, opened her illustrated talk by noting that her experience +with literary scholars and numerous people in editing was contrary to +MICHELSON's. TWOHIG emphasized literary scholars' complete ignorance of +the technological options available to them or their reluctance or, in +some cases, their downright hostility toward these options. + +After providing an overview of the five Founding Fathers projects +(Jefferson at Princeton, Franklin at Yale, John Adams at the +Massachusetts Historical Society, and Madison down the hall from her at +the University of Virginia), TWOHIG observed that the Washington papers, +like all of the projects, include both sides of the Washington +correspondence and deal with some 135,000 documents to be published with +extensive annotation in eighty to eighty-five volumes, a project that +will not be completed until well into the next century. Thus, it was +with considerable enthusiasm several years ago that the Washington Papers +Project (WPP) greeted David Packard's suggestion that the papers of the +Founding Fathers could be published easily and inexpensively, and to the +great benefit of American scholarship, via CD-ROM. + +In pragmatic terms, funding from the Packard Foundation would expedite +the transcription of thousands of documents waiting to be put on disk in +the WPP offices. Further, since the costs of collecting, editing, and +converting the Founding Fathers documents into letterpress editions were +running into the millions of dollars, and the considerable staffs +involved in all of these projects were devoting their careers to +producing the work, the Packard Foundation's suggestion had a +revolutionary aspect: Transcriptions of the entire corpus of the +Founding Fathers papers would be available on CD-ROM to public and +college libraries, even high schools, at a fraction of the cost-- +$100-$150 for the annual license fee--to produce a limited university +press run of 1,000 of each volume of the published papers at $45-$150 per +printed volume. Given the current budget crunch in educational systems +and the corresponding constraints on librarians in smaller institutions +who wish to add these volumes to their collections, producing the +documents on CD-ROM would likely open a greatly expanded audience for the +papers. TWOHIG stressed, however, that development of the Founding +Fathers CD-ROM is still in its infancy. Serious software problems remain +to be resolved before the material can be put into readable form. + +Funding from the Packard Foundation resulted in a major push to +transcribe the 75,000 or so documents of the Washington papers remaining +to be transcribed onto computer disks. Slides illustrated several of the +problems encountered, for example, the present inability of CD-ROM to +indicate the cross-outs (deleted material) in eighteenth century +documents. TWOHIG next described documents from various periods in the +eighteenth century that have been transcribed in chronological order and +delivered to the Packard offices in California, where they are converted +to the CD-ROM, a process that is expected to consume five years to +complete (that is, reckoning from David Packard's suggestion made several +years ago, until about July 1994). TWOHIG found an encouraging +indication of the project's benefits in the ongoing use made by scholars +of the search functions of the CD-ROM, particularly in reducing the time +spent in manually turning the pages of the Washington papers. + +TWOHIG next furnished details concerning the accuracy of transcriptions. +For instance, the insertion of thousands of documents on the CD-ROM +currently does not permit each document to be verified against the +original manuscript several times as in the case of documents that appear +in the published edition. However, the transcriptions receive a cursory +check for obvious typos, the misspellings of proper names, and other +errors from the WPP CD-ROM editor. Eventually, all documents that appear +in the electronic version will be checked by project editors. Although +this process has met with opposition from some of the editors on the +grounds that imperfect work may leave their offices, the advantages in +making this material available as a research tool outweigh fears about the +misspelling of proper names and other relatively minor editorial matters. + +Completion of all five Founding Fathers projects (i.e., retrievability +and searchability of all of the documents by proper names, alternate +spellings, or varieties of subjects) will provide one of the richest +sources of this size for the history of the United States in the latter +part of the eighteenth century. Further, publication on CD-ROM will +allow editors to include even minutiae, such as laundry lists, not +included in the printed volumes. + +It seems possible that the extensive annotation provided in the printed +volumes eventually will be added to the CD-ROM edition, pending +negotiations with the publishers of the papers. At the moment, the +Founding Fathers CD-ROM is accessible only on the IBYCUS, a computer +developed out of the Thesaurus Linguae Graecae project and designed for +the use of classical scholars. There are perhaps 400 IBYCUS computers in +the country, most of which are in university classics departments. +Ultimately, it is anticipated that the CD-ROM edition of the Founding +Fathers documents will run on any IBM-compatible or Macintosh computer +with a CD-ROM drive. Numerous changes in the software will also occur +before the project is completed. (Editor's note: an IBYCUS was +unavailable to demonstrate the CD-ROM.) + + ****** + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +DISCUSSION * Several additional features of WPP clarified * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Discussion following TWOHIG's presentation served to clarify several +additional features, including (1) that the project's primary +intellectual product consists in the electronic transcription of the +material; (2) that the text transmitted to the CD-ROM people is not +marked up; (3) that cataloging and subject-indexing of the material +remain to be worked out (though at this point material can be retrieved +by name); and (4) that because all the searching is done in the hardware, +the IBYCUS is designed to read a CD-ROM which contains only sequential +text files. Technically, it then becomes very easy to read the material +off and put it on another device. + + ****** + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +LEBRON * Overview of the history of the joint project between AAAS and +OCLC * Several practices the on-line environment shares with traditional +publishing on hard copy * Several technical and behavioral barriers to +electronic publishing * How AAAS and OCLC arrived at the subject of +clinical trials * Advantages of the electronic format and other features +of OJCCT * An illustrated tour of the journal * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Maria LEBRON, managing editor, The Online Journal of Current Clinical +Trials (OJCCT), presented an illustrated overview of the history of the +joint project between the American Association for the Advancement of +Science (AAAS) and the Online Computer Library Center, Inc. (OCLC). The +joint venture between AAAS and OCLC owes its beginning to a +reorganization launched by the new chief executive officer at OCLC about +three years ago and combines the strengths of these two disparate +organizations. In short, OJCCT represents the process of scholarly +publishing on line. + +LEBRON next discussed several practices the on-line environment shares +with traditional publishing on hard copy--for example, peer review of +manuscripts--that are highly important in the academic world. LEBRON +noted in particular the implications of citation counts for tenure +committees and grants committees. In the traditional hard-copy +environment, citation counts are readily demonstrable, whereas the +on-line environment represents an ethereal medium to most academics. + +LEBRON remarked several technical and behavioral barriers to electronic +publishing, for instance, the problems in transmission created by special +characters or by complex graphics and halftones. In addition, she noted +economic limitations such as the storage costs of maintaining back issues +and market or audience education. + +Manuscripts cannot be uploaded to OJCCT, LEBRON explained, because it is +not a bulletin board or E-mail, forms of electronic transmission of +information that have created an ambience clouding people's understanding +of what the journal is attempting to do. OJCCT, which publishes +peer-reviewed medical articles dealing with the subject of clinical +trials, includes text, tabular material, and graphics, although at this +time it can transmit only line illustrations. + +Next, LEBRON described how AAAS and OCLC arrived at the subject of +clinical trials: It is 1) a highly statistical discipline that 2) does +not require halftones but can satisfy the needs of its audience with line +illustrations and graphic material, and 3) there is a need for the speedy +dissemination of high-quality research results. Clinical trials are +research activities that involve the administration of a test treatment +to some experimental unit in order to test its usefulness before it is +made available to the general population. LEBRON proceeded to give +additional information on OJCCT concerning its editor-in-chief, editorial +board, editorial content, and the types of articles it publishes +(including peer-reviewed research reports and reviews), as well as +features shared by other traditional hard-copy journals. + +Among the advantages of the electronic format are faster dissemination of +information, including raw data, and the absence of space constraints +because pages do not exist. (This latter fact creates an interesting +situation when it comes to citations.) Nor are there any issues. AAAS's +capacity to download materials directly from the journal to a +subscriber's printer, hard drive, or floppy disk helps ensure highly +accurate transcription. Other features of OJCCT include on-screen alerts +that allow linkage of subsequently published documents to the original +documents; on-line searching by subject, author, title, etc.; indexing of +every single word that appears in an article; viewing access to an +article by component (abstract, full text, or graphs); numbered +paragraphs to replace page counts; publication in Science every thirty +days of indexing of all articles published in the journal; +typeset-quality screens; and Hypertext links that enable subscribers to +bring up Medline abstracts directly without leaving the journal. + +After detailing the two primary ways to gain access to the journal, +through the OCLC network and Compuserv if one desires graphics or through +the Internet if just an ASCII file is desired, LEBRON illustrated the +speedy editorial process and the coding of the document using SGML tags +after it has been accepted for publication. She also gave an illustrated +tour of the journal, its search-and-retrieval capabilities in particular, +but also including problems associated with scanning in illustrations, +and the importance of on-screen alerts to the medical profession re +retractions or corrections, or more frequently, editorials, letters to +the editors, or follow-up reports. She closed by inviting the audience +to join AAAS on 1 July, when OJCCT was scheduled to go on-line. + + ****** + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +DISCUSSION * Additional features of OJCCT * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +In the lengthy discussion that followed LEBRON's presentation, these +points emerged: + + * The SGML text can be tailored as users wish. + + * All these articles have a fairly simple document definition. + + * Document-type definitions (DTDs) were developed and given to OJCCT + for coding. + + * No articles will be removed from the journal. (Because there are + no back issues, there are no lost issues either. Once a subscriber + logs onto the journal he or she has access not only to the currently + published materials, but retrospectively to everything that has been + published in it. Thus the table of contents grows bigger. The date + of publication serves to distinguish between currently published + materials and older materials.) + + * The pricing system for the journal resembles that for most medical + journals: for 1992, $95 for a year, plus telecommunications charges + (there are no connect time charges); for 1993, $110 for the + entire year for single users, though the journal can be put on a + local area network (LAN). However, only one person can access the + journal at a time. Site licenses may come in the future. + + * AAAS is working closely with colleagues at OCLC to display + mathematical equations on screen. + + * Without compromising any steps in the editorial process, the + technology has reduced the time lag between when a manuscript is + originally submitted and the time it is accepted; the review process + does not differ greatly from the standard six-to-eight weeks + employed by many of the hard-copy journals. The process still + depends on people. + + * As far as a preservation copy is concerned, articles will be + maintained on the computer permanently and subscribers, as part of + their subscription, will receive a microfiche-quality archival copy + of everything published during that year; in addition, reprints can + be purchased in much the same way as in a hard-copy environment. + Hard copies are prepared but are not the primary medium for the + dissemination of the information. + + * Because OJCCT is not yet on line, it is difficult to know how many + people would simply browse through the journal on the screen as + opposed to downloading the whole thing and printing it out; a mix of + both types of users likely will result. + + ****** + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +PERSONIUS * Developments in technology over the past decade * The CLASS +Project * Advantages for technology and for the CLASS Project * +Developing a network application an underlying assumption of the project +* Details of the scanning process * Print-on-demand copies of books * +Future plans include development of a browsing tool * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Lynne PERSONIUS, assistant director, Cornell Information Technologies for +Scholarly Information Services, Cornell University, first commented on +the tremendous impact that developments in technology over the past ten +years--networking, in particular--have had on the way information is +handled, and how, in her own case, these developments have counterbalanced +Cornell's relative geographical isolation. Other significant technologies +include scanners, which are much more sophisticated than they were ten years +ago; mass storage and the dramatic savings that result from it in terms of +both space and money relative to twenty or thirty years ago; new and +improved printing technologies, which have greatly affected the distribution +of information; and, of course, digital technologies, whose applicability to +library preservation remains at issue. + +Given that context, PERSONIUS described the College Library Access and +Storage System (CLASS) Project, a library preservation project, +primarily, and what has been accomplished. Directly funded by the +Commission on Preservation and Access and by the Xerox Corporation, which +has provided a significant amount of hardware, the CLASS Project has been +working with a development team at Xerox to develop a software +application tailored to library preservation requirements. Within +Cornell, participants in the project have been working jointly with both +library and information technologies. The focus of the project has been +on reformatting and saving books that are in brittle condition. +PERSONIUS showed Workshop participants a brittle book, and described how +such books were the result of developments in papermaking around the +beginning of the Industrial Revolution. The papermaking process was +changed so that a significant amount of acid was introduced into the +actual paper itself, which deteriorates as it sits on library shelves. + +One of the advantages for technology and for the CLASS Project is that +the information in brittle books is mostly out of copyright and thus +offers an opportunity to work with material that requires library +preservation, and to create and work on an infrastructure to save the +material. Acknowledging the familiarity of those working in preservation +with this information, PERSONIUS noted that several things are being +done: the primary preservation technology used today is photocopying of +brittle material. Saving the intellectual content of the material is the +main goal. With microfilm copy, the intellectual content is preserved on +the assumption that in the future the image can be reformatted in any +other way that then exists. + +An underlying assumption of the CLASS Project from the beginning was +that it would develop a network application. Project staff scan books +at a workstation located in the library, near the brittle material. +An image-server filing system is located at a distance from that +workstation, and a printer is located in another building. All of the +materials digitized and stored on the image-filing system are cataloged +in the on-line catalogue. In fact, a record for each of these electronic +books is stored in the RLIN database so that a record exists of what is +in the digital library throughout standard catalogue procedures. In the +future, researchers working from their own workstations in their offices, +or their networks, will have access--wherever they might be--through a +request server being built into the new digital library. A second +assumption is that the preferred means of finding the material will be by +looking through a catalogue. PERSONIUS described the scanning process, +which uses a prototype scanner being developed by Xerox and which scans a +very high resolution image at great speed. Another significant feature, +because this is a preservation application, is the placing of the pages +that fall apart one for one on the platen. Ordinarily, a scanner could +be used with some sort of a document feeder, but because of this +application that is not feasible. Further, because CLASS is a +preservation application, after the paper replacement is made there, a +very careful quality control check is performed. An original book is +compared to the printed copy and verification is made, before proceeding, +that all of the image, all of the information, has been captured. Then, +a new library book is produced: The printed images are rebound by a +commercial binder and a new book is returned to the shelf. +Significantly, the books returned to the library shelves are beautiful +and useful replacements on acid-free paper that should last a long time, +in effect, the equivalent of preservation photocopies. Thus, the project +has a library of digital books. In essence, CLASS is scanning and +storing books as 600 dot-per-inch bit-mapped images, compressed using +Group 4 CCITT (i.e., the French acronym for International Consultative +Committee for Telegraph and Telephone) compression. They are stored as +TIFF files on an optical filing system that is composed of a database +used for searching and locating the books and an optical jukebox that +stores 64 twelve-inch platters. A very-high-resolution printed copy of +these books at 600 dots per inch is created, using a Xerox DocuTech +printer to make the paper replacements on acid-free paper. + +PERSONIUS maintained that the CLASS Project presents an opportunity to +introduce people to books as digital images by using a paper medium. +Books are returned to the shelves while people are also given the ability +to print on demand--to make their own copies of books. (PERSONIUS +distributed copies of an engineering journal published by engineering +students at Cornell around 1900 as an example of what a print-on-demand +copy of material might be like. This very cheap copy would be available +to people to use for their own research purposes and would bridge the gap +between an electronic work and the paper that readers like to have.) +PERSONIUS then attempted to illustrate a very early prototype of +networked access to this digital library. Xerox Corporation has +developed a prototype of a view station that can send images across the +network to be viewed. + +The particular library brought down for demonstration contained two +mathematics books. CLASS is developing and will spend the next year +developing an application that allows people at workstations to browse +the books. Thus, CLASS is developing a browsing tool, on the assumption +that users do not want to read an entire book from a workstation, but +would prefer to be able to look through and decide if they would like to +have a printed copy of it. + + ****** + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +DISCUSSION * Re retrieval software * "Digital file copyright" * Scanning +rate during production * Autosegmentation * Criteria employed in +selecting books for scanning * Compression and decompression of images * +OCR not precluded * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +During the question-and-answer period that followed her presentation, +PERSONIUS made these additional points: + + * Re retrieval software, Cornell is developing a Unix-based server + as well as clients for the server that support multiple platforms + (Macintosh, IBM and Sun workstations), in the hope that people from + any of those platforms will retrieve books; a further operating + assumption is that standard interfaces will be used as much as + possible, where standards can be put in place, because CLASS + considers this retrieval software a library application and would + like to be able to look at material not only at Cornell but at other + institutions. + + * The phrase "digital file copyright by Cornell University" was + added at the advice of Cornell's legal staff with the caveat that it + probably would not hold up in court. Cornell does not want people + to copy its books and sell them but would like to keep them + available for use in a library environment for library purposes. + + * In production the scanner can scan about 300 pages per hour, + capturing 600 dots per inch. + + * The Xerox software has filters to scan halftone material and avoid + the moire patterns that occur when halftone material is scanned. + Xerox has been working on hardware and software that would enable + the scanner itself to recognize this situation and deal with it + appropriately--a kind of autosegmentation that would enable the + scanner to handle halftone material as well as text on a single page. + + * The books subjected to the elaborate process described above were + selected because CLASS is a preservation project, with the first 500 + books selected coming from Cornell's mathematics collection, because + they were still being heavily used and because, although they were + in need of preservation, the mathematics library and the mathematics + faculty were uncomfortable having them microfilmed. (They wanted a + printed copy.) Thus, these books became a logical choice for this + project. Other books were chosen by the project's selection committees + for experiments with the technology, as well as to meet a demand or need. + + * Images will be decompressed before they are sent over the line; at + this time they are compressed and sent to the image filing system + and then sent to the printer as compressed images; they are returned + to the workstation as compressed 600-dpi images and the workstation + decompresses and scales them for display--an inefficient way to + access the material though it works quite well for printing and + other purposes. + + * CLASS is also decompressing on Macintosh and IBM, a slow process + right now. Eventually, compression and decompression will take + place on an image conversion server. Trade-offs will be made, based + on future performance testing, concerning where the file is + compressed and what resolution image is sent. + + * OCR has not been precluded; images are being stored that have been + scanned at a high resolution, which presumably would suit them well + to an OCR process. Because the material being scanned is about 100 + years old and was printed with less-than-ideal technologies, very + early and preliminary tests have not produced good results. But the + project is capturing an image that is of sufficient resolution to be + subjected to OCR in the future. Moreover, the system architecture + and the system plan have a logical place to store an OCR image if it + has been captured. But that is not being done now. + + ****** + +SESSION III. DISTRIBUTION, NETWORKS, AND NETWORKING: OPTIONS FOR +DISSEMINATION + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +ZICH * Issues pertaining to CD-ROMs * Options for publishing in CD-ROM * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Robert ZICH, special assistant to the associate librarian for special +projects, Library of Congress, and moderator of this session, first noted +the blessed but somewhat awkward circumstance of having four very +distinguished people representing networks and networking or at least +leaning in that direction, while lacking anyone to speak from the +strongest possible background in CD-ROMs. ZICH expressed the hope that +members of the audience would join the discussion. He stressed the +subtitle of this particular session, "Options for Dissemination," and, +concerning CD-ROMs, the importance of determining when it would be wise +to consider dissemination in CD-ROM versus networks. A shopping list of +issues pertaining to CD-ROMs included: the grounds for selecting +commercial publishers, and in-house publication where possible versus +nonprofit or government publication. A similar list for networks +included: determining when one should consider dissemination through a +network, identifying the mechanisms or entities that exist to place items +on networks, identifying the pool of existing networks, determining how a +producer would choose between networks, and identifying the elements of +a business arrangement in a network. + +Options for publishing in CD-ROM: an outside publisher versus +self-publication. If an outside publisher is used, it can be nonprofit, +such as the Government Printing Office (GPO) or the National Technical +Information Service (NTIS), in the case of government. The pros and cons +associated with employing an outside publisher are obvious. Among the +pros, there is no trouble getting accepted. One pays the bill and, in +effect, goes one's way. Among the cons, when one pays an outside +publisher to perform the work, that publisher will perform the work it is +obliged to do, but perhaps without the production expertise and skill in +marketing and dissemination that some would seek. There is the body of +commercial publishers that do possess that kind of expertise in +distribution and marketing but that obviously are selective. In +self-publication, one exercises full control, but then one must handle +matters such as distribution and marketing. Such are some of the options +for publishing in the case of CD-ROM. + +In the case of technical and design issues, which are also important, +there are many matters which many at the Workshop already knew a good +deal about: retrieval system requirements and costs, what to do about +images, the various capabilities and platforms, the trade-offs between +cost and performance, concerns about local-area networkability, +interoperability, etc. + + ****** + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +LYNCH * Creating networked information is different from using networks +as an access or dissemination vehicle * Networked multimedia on a large +scale does not yet work * Typical CD-ROM publication model a two-edged +sword * Publishing information on a CD-ROM in the present world of +immature standards * Contrast between CD-ROM and network pricing * +Examples demonstrated earlier in the day as a set of insular information +gems * Paramount need to link databases * Layering to become increasingly +necessary * Project NEEDS and the issues of information reuse and active +versus passive use * X-Windows as a way of differentiating between +network access and networked information * Barriers to the distribution +of networked multimedia information * Need for good, real-time delivery +protocols * The question of presentation integrity in client-server +computing in the academic world * Recommendations for producing multimedia ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Clifford LYNCH, director, Library Automation, University of California, +opened his talk with the general observation that networked information +constituted a difficult and elusive topic because it is something just +starting to develop and not yet fully understood. LYNCH contended that +creating genuinely networked information was different from using +networks as an access or dissemination vehicle and was more sophisticated +and more subtle. He invited the members of the audience to extrapolate, +from what they heard about the preceding demonstration projects, to what +sort of a world of electronics information--scholarly, archival, +cultural, etc.--they wished to end up with ten or fifteen years from now. +LYNCH suggested that to extrapolate directly from these projects would +produce unpleasant results. + +Putting the issue of CD-ROM in perspective before getting into +generalities on networked information, LYNCH observed that those engaged +in multimedia today who wish to ship a product, so to say, probably do +not have much choice except to use CD-ROM: networked multimedia on a +large scale basically does not yet work because the technology does not +exist. For example, anybody who has tried moving images around over the +Internet knows that this is an exciting touch-and-go process, a +fascinating and fertile area for experimentation, research, and +development, but not something that one can become deeply enthusiastic +about committing to production systems at this time. + +This situation will change, LYNCH said. He differentiated CD-ROM from +the practices that have been followed up to now in distributing data on +CD-ROM. For LYNCH the problem with CD-ROM is not its portability or its +slowness but the two-edged sword of having the retrieval application and +the user interface inextricably bound up with the data, which is the +typical CD-ROM publication model. It is not a case of publishing data +but of distributing a typically stand-alone, typically closed system, +all--software, user interface, and data--on a little disk. Hence, all +the between-disk navigational issues as well as the impossibility in most +cases of integrating data on one disk with that on another. Most CD-ROM +retrieval software does not network very gracefully at present. However, +in the present world of immature standards and lack of understanding of +what network information is or what the ground rules are for creating or +using it, publishing information on a CD-ROM does add value in a very +real sense. + +LYNCH drew a contrast between CD-ROM and network pricing and in doing so +highlighted something bizarre in information pricing. A large +institution such as the University of California has vendors who will +offer to sell information on CD-ROM for a price per year in four digits, +but for the same data (e.g., an abstracting and indexing database) on +magnetic tape, regardless of how many people may use it concurrently, +will quote a price in six digits. + +What is packaged with the CD-ROM in one sense adds value--a complete +access system, not just raw, unrefined information--although it is not +generally perceived that way. This is because the access software, +although it adds value, is viewed by some people, particularly in the +university environment where there is a very heavy commitment to +networking, as being developed in the wrong direction. + +Given that context, LYNCH described the examples demonstrated as a set of +insular information gems--Perseus, for example, offers nicely linked +information, but would be very difficult to integrate with other +databases, that is, to link together seamlessly with other source files +from other sources. It resembles an island, and in this respect is +similar to numerous stand-alone projects that are based on videodiscs, +that is, on the single-workstation concept. + +As scholarship evolves in a network environment, the paramount need will +be to link databases. We must link personal databases to public +databases, to group databases, in fairly seamless ways--which is +extremely difficult in the environments under discussion with copies of +databases proliferating all over the place. + +The notion of layering also struck LYNCH as lurking in several of the +projects demonstrated. Several databases in a sense constitute +information archives without a significant amount of navigation built in. +Educators, critics, and others will want a layered structure--one that +defines or links paths through the layers to allow users to reach +specific points. In LYNCH's view, layering will become increasingly +necessary, and not just within a single resource but across resources +(e.g., tracing mythology and cultural themes across several classics +databases as well as a database of Renaissance culture). This ability to +organize resources, to build things out of multiple other things on the +network or select pieces of it, represented for LYNCH one of the key +aspects of network information. + +Contending that information reuse constituted another significant issue, +LYNCH commended to the audience's attention Project NEEDS (i.e., National +Engineering Education Delivery System). This project's objective is to +produce a database of engineering courseware as well as the components +that can be used to develop new courseware. In a number of the existing +applications, LYNCH said, the issue of reuse (how much one can take apart +and reuse in other applications) was not being well considered. He also +raised the issue of active versus passive use, one aspect of which is +how much information will be manipulated locally by users. Most people, +he argued, may do a little browsing and then will wish to print. LYNCH +was uncertain how these resources would be used by the vast majority of +users in the network environment. + +LYNCH next said a few words about X-Windows as a way of differentiating +between network access and networked information. A number of the +applications demonstrated at the Workshop could be rewritten to use X +across the network, so that one could run them from any X-capable device- +-a workstation, an X terminal--and transact with a database across the +network. Although this opens up access a little, assuming one has enough +network to handle it, it does not provide an interface to develop a +program that conveniently integrates information from multiple databases. +X is a viewing technology that has limits. In a real sense, it is just a +graphical version of remote log-in across the network. X-type applications +represent only one step in the progression towards real access. + +LYNCH next discussed barriers to the distribution of networked multimedia +information. The heart of the problem is a lack of standards to provide +the ability for computers to talk to each other, retrieve information, +and shuffle it around fairly casually. At the moment, little progress is +being made on standards for networked information; for example, present +standards do not cover images, digital voice, and digital video. A +useful tool kit of exchange formats for basic texts is only now being +assembled. The synchronization of content streams (i.e., synchronizing a +voice track to a video track, establishing temporal relations between +different components in a multimedia object) constitutes another issue +for networked multimedia that is just beginning to receive attention. + +Underlying network protocols also need some work; good, real-time +delivery protocols on the Internet do not yet exist. In LYNCH's view, +highly important in this context is the notion of networked digital +object IDs, the ability of one object on the network to point to another +object (or component thereof) on the network. Serious bandwidth issues +also exist. LYNCH was uncertain if billion-bit-per-second networks would +prove sufficient if numerous people ran video in parallel. + +LYNCH concluded by offering an issue for database creators to consider, +as well as several comments about what might constitute good trial +multimedia experiments. In a networked information world the database +builder or service builder (publisher) does not exercise the same +extensive control over the integrity of the presentation; strange +programs "munge" with one's data before the user sees it. Serious +thought must be given to what guarantees integrity of presentation. Part +of that is related to where one draws the boundaries around a networked +information service. This question of presentation integrity in +client-server computing has not been stressed enough in the academic +world, LYNCH argued, though commercial service providers deal with it +regularly. + +Concerning multimedia, LYNCH observed that good multimedia at the moment +is hideously expensive to produce. He recommended producing multimedia +with either very high sale value, or multimedia with a very long life +span, or multimedia that will have a very broad usage base and whose +costs therefore can be amortized among large numbers of users. In this +connection, historical and humanistically oriented material may be a good +place to start, because it tends to have a longer life span than much of +the scientific material, as well as a wider user base. LYNCH noted, for +example, that American Memory fits many of the criteria outlined. He +remarked the extensive discussion about bringing the Internet or the +National Research and Education Network (NREN) into the K-12 environment +as a way of helping the American educational system. + +LYNCH closed by noting that the kinds of applications demonstrated struck +him as excellent justifications of broad-scale networking for K-12, but +that at this time no "killer" application exists to mobilize the K-12 +community to obtain connectivity. + + ****** + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +DISCUSSION * Dearth of genuinely interesting applications on the network +a slow-changing situation * The issue of the integrity of presentation in +a networked environment * Several reasons why CD-ROM software does not +network * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +During the discussion period that followed LYNCH's presentation, several +additional points were made. + +LYNCH reiterated even more strongly his contention that, historically, +once one goes outside high-end science and the group of those who need +access to supercomputers, there is a great dearth of genuinely +interesting applications on the network. He saw this situation changing +slowly, with some of the scientific databases and scholarly discussion +groups and electronic journals coming on as well as with the availability +of Wide Area Information Servers (WAIS) and some of the databases that +are being mounted there. However, many of those things do not seem to +have piqued great popular interest. For instance, most high school +students of LYNCH's acquaintance would not qualify as devotees of serious +molecular biology. + +Concerning the issue of the integrity of presentation, LYNCH believed +that a couple of information providers have laid down the law at least on +certain things. For example, his recollection was that the National +Library of Medicine feels strongly that one needs to employ the +identifier field if he or she is to mount a database commercially. The +problem with a real networked environment is that one does not know who +is reformatting and reprocessing one's data when one enters a client +server mode. It becomes anybody's guess, for example, if the network +uses a Z39.50 server, or what clients are doing with one's data. A data +provider can say that his contract will only permit clients to have +access to his data after he vets them and their presentation and makes +certain it suits him. But LYNCH held out little expectation that the +network marketplace would evolve in that way, because it required too +much prior negotiation. + +CD-ROM software does not network for a variety of reasons, LYNCH said. +He speculated that CD-ROM publishers are not eager to have their products +really hook into wide area networks, because they fear it will make their +data suppliers nervous. Moreover, until relatively recently, one had to +be rather adroit to run a full TCP/IP stack plus applications on a +PC-size machine, whereas nowadays it is becoming easier as PCs grow +bigger and faster. LYNCH also speculated that software providers had not +heard from their customers until the last year or so, or had not heard +from enough of their customers. + + ****** + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +BESSER * Implications of disseminating images on the network; planning +the distribution of multimedia documents poses two critical +implementation problems * Layered approach represents the way to deal +with users' capabilities * Problems in platform design; file size and its +implications for networking * Transmission of megabyte size images +impractical * Compression and decompression at the user's end * Promising +trends for compression * A disadvantage of using X-Windows * A project at +the Smithsonian that mounts images on several networks * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Howard BESSER, School of Library and Information Science, University of +Pittsburgh, spoke primarily about multimedia, focusing on images and the +broad implications of disseminating them on the network. He argued that +planning the distribution of multimedia documents posed two critical +implementation problems, which he framed in the form of two questions: +1) What platform will one use and what hardware and software will users +have for viewing of the material? and 2) How can one deliver a +sufficiently robust set of information in an accessible format in a +reasonable amount of time? Depending on whether network or CD-ROM is the +medium used, this question raises different issues of storage, +compression, and transmission. + +Concerning the design of platforms (e.g., sound, gray scale, simple +color, etc.) and the various capabilities users may have, BESSER +maintained that a layered approach was the way to deal with users' +capabilities. A result would be that users with less powerful +workstations would simply have less functionality. He urged members of +the audience to advocate standards and accompanying software that handle +layered functionality across a wide variety of platforms. + +BESSER also addressed problems in platform design, namely, deciding how +large a machine to design for situations when the largest number of users +have the lowest level of the machine, and one desires higher +functionality. BESSER then proceeded to the question of file size and +its implications for networking. He discussed still images in the main. +For example, a digital color image that fills the screen of a standard +mega-pel workstation (Sun or Next) will require one megabyte of storage +for an eight-bit image or three megabytes of storage for a true color or +twenty-four-bit image. Lossless compression algorithms (that is, +computational procedures in which no data is lost in the process of +compressing [and decompressing] an image--the exact bit-representation is +maintained) might bring storage down to a third of a megabyte per image, +but not much further than that. The question of size makes it difficult +to fit an appropriately sized set of these images on a single disk or to +transmit them quickly enough on a network. + +With these full screen mega-pel images that constitute a third of a +megabyte, one gets 1,000-3,000 full-screen images on a one-gigabyte disk; +a standard CD-ROM represents approximately 60 percent of that. Storing +images the size of a PC screen (just 8 bit color) increases storage +capacity to 4,000-12,000 images per gigabyte; 60 percent of that gives +one the size of a CD-ROM, which in turn creates a major problem. One +cannot have full-screen, full-color images with lossless compression; one +must compress them or use a lower resolution. For megabyte-size images, +anything slower than a T-1 speed is impractical. For example, on a +fifty-six-kilobaud line, it takes three minutes to transfer a +one-megabyte file, if it is not compressed; and this speed assumes ideal +circumstances (no other user contending for network bandwidth). Thus, +questions of disk access, remote display, and current telephone +connection speed make transmission of megabyte-size images impractical. + +BESSER then discussed ways to deal with these large images, for example, +compression and decompression at the user's end. In this connection, the +issues of how much one is willing to lose in the compression process and +what image quality one needs in the first place are unknown. But what is +known is that compression entails some loss of data. BESSER urged that +more studies be conducted on image quality in different situations, for +example, what kind of images are needed for what kind of disciplines, and +what kind of image quality is needed for a browsing tool, an intermediate +viewing tool, and archiving. + +BESSER remarked two promising trends for compression: from a technical +perspective, algorithms that use what is called subjective redundancy +employ principles from visual psycho-physics to identify and remove +information from the image that the human eye cannot perceive; from an +interchange and interoperability perspective, the JPEG (i.e., Joint +Photographic Experts Group, an ISO standard) compression algorithms also +offer promise. These issues of compression and decompression, BESSER +argued, resembled those raised earlier concerning the design of different +platforms. Gauging the capabilities of potential users constitutes a +primary goal. BESSER advocated layering or separating the images from +the applications that retrieve and display them, to avoid tying them to +particular software. + +BESSER detailed several lessons learned from his work at Berkeley with +Imagequery, especially the advantages and disadvantages of using +X-Windows. In the latter category, for example, retrieval is tied +directly to one's data, an intolerable situation in the long run on a +networked system. Finally, BESSER described a project of Jim Wallace at +the Smithsonian Institution, who is mounting images in a extremely +rudimentary way on the Compuserv and Genie networks and is preparing to +mount them on America On Line. Although the average user takes over +thirty minutes to download these images (assuming a fairly fast modem), +nevertheless, images have been downloaded 25,000 times. + +BESSER concluded his talk with several comments on the business +arrangement between the Smithsonian and Compuserv. He contended that not +enough is known concerning the value of images. + + ****** + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +DISCUSSION * Creating digitized photographic collections nearly +impossible except with large organizations like museums * Need for study +to determine quality of images users will tolerate * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +During the brief exchange between LESK and BESSER that followed, several +clarifications emerged. + +LESK argued that the photographers were far ahead of BESSER: It is +almost impossible to create such digitized photographic collections +except with large organizations like museums, because all the +photographic agencies have been going crazy about this and will not sign +licensing agreements on any sort of reasonable terms. LESK had heard +that National Geographic, for example, had tried to buy the right to use +some image in some kind of educational production for $100 per image, but +the photographers will not touch it. They want accounting and payment +for each use, which cannot be accomplished within the system. BESSER +responded that a consortium of photographers, headed by a former National +Geographic photographer, had started assembling its own collection of +electronic reproductions of images, with the money going back to the +cooperative. + +LESK contended that BESSER was unnecessarily pessimistic about multimedia +images, because people are accustomed to low-quality images, particularly +from video. BESSER urged the launching of a study to determine what +users would tolerate, what they would feel comfortable with, and what +absolutely is the highest quality they would ever need. Conceding that +he had adopted a dire tone in order to arouse people about the issue, +BESSER closed on a sanguine note by saying that he would not be in this +business if he did not think that things could be accomplished. + + ****** + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +LARSEN * Issues of scalability and modularity * Geometric growth of the +Internet and the role played by layering * Basic functions sustaining +this growth * A library's roles and functions in a network environment * +Effects of implementation of the Z39.50 protocol for information +retrieval on the library system * The trade-off between volumes of data +and its potential usage * A snapshot of current trends * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Ronald LARSEN, associate director for information technology, University +of Maryland at College Park, first addressed the issues of scalability +and modularity. He noted the difficulty of anticipating the effects of +orders-of-magnitude growth, reflecting on the twenty years of experience +with the Arpanet and Internet. Recalling the day's demonstrations of +CD-ROM and optical disk material, he went on to ask if the field has yet +learned how to scale new systems to enable delivery and dissemination +across large-scale networks. + +LARSEN focused on the geometric growth of the Internet from its inception +circa 1969 to the present, and the adjustments required to respond to +that rapid growth. To illustrate the issue of scalability, LARSEN +considered computer networks as including three generic components: +computers, network communication nodes, and communication media. Each +component scales (e.g., computers range from PCs to supercomputers; +network nodes scale from interface cards in a PC through sophisticated +routers and gateways; and communication media range from 2,400-baud +dial-up facilities through 4.5-Mbps backbone links, and eventually to +multigigabit-per-second communication lines), and architecturally, the +components are organized to scale hierarchically from local area networks +to international-scale networks. Such growth is made possible by +building layers of communication protocols, as BESSER pointed out. +By layering both physically and logically, a sense of scalability is +maintained from local area networks in offices, across campuses, through +bridges, routers, campus backbones, fiber-optic links, etc., up into +regional networks and ultimately into national and international +networks. + +LARSEN then illustrated the geometric growth over a two-year period-- +through September 1991--of the number of networks that comprise the +Internet. This growth has been sustained largely by the availability of +three basic functions: electronic mail, file transfer (ftp), and remote +log-on (telnet). LARSEN also reviewed the growth in the kind of traffic +that occurs on the network. Network traffic reflects the joint contributions +of a larger population of users and increasing use per user. Today one sees +serious applications involving moving images across the network--a rarity +ten years ago. LARSEN recalled and concurred with BESSER's main point +that the interesting problems occur at the application level. + +LARSEN then illustrated a model of a library's roles and functions in a +network environment. He noted, in particular, the placement of on-line +catalogues onto the network and patrons obtaining access to the library +increasingly through local networks, campus networks, and the Internet. +LARSEN supported LYNCH's earlier suggestion that we need to address +fundamental questions of networked information in order to build +environments that scale in the information sense as well as in the +physical sense. + +LARSEN supported the role of the library system as the access point into +the nation's electronic collections. Implementation of the Z39.50 +protocol for information retrieval would make such access practical and +feasible. For example, this would enable patrons in Maryland to search +California libraries, or other libraries around the world that are +conformant with Z39.50 in a manner that is familiar to University of +Maryland patrons. This client-server model also supports moving beyond +secondary content into primary content. (The notion of how one links +from secondary content to primary content, LARSEN said, represents a +fundamental problem that requires rigorous thought.) After noting +numerous network experiments in accessing full-text materials, including +projects supporting the ordering of materials across the network, LARSEN +revisited the issue of transmitting high-density, high-resolution color +images across the network and the large amounts of bandwidth they +require. He went on to address the bandwidth and synchronization +problems inherent in sending full-motion video across the network. + +LARSEN illustrated the trade-off between volumes of data in bytes or +orders of magnitude and the potential usage of that data. He discussed +transmission rates (particularly, the time it takes to move various forms +of information), and what one could do with a network supporting +multigigabit-per-second transmission. At the moment, the network +environment includes a composite of data-transmission requirements, +volumes and forms, going from steady to bursty (high-volume) and from +very slow to very fast. This aggregate must be considered in the design, +construction, and operation of multigigabyte networks. + +LARSEN's objective is to use the networks and library systems now being +constructed to increase access to resources wherever they exist, and +thus, to evolve toward an on-line electronic virtual library. + +LARSEN concluded by offering a snapshot of current trends: continuing +geometric growth in network capacity and number of users; slower +development of applications; and glacial development and adoption of +standards. The challenge is to design and develop each new application +system with network access and scalability in mind. + + ****** + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +BROWNRIGG * Access to the Internet cannot be taken for granted * Packet +radio and the development of MELVYL in 1980-81 in the Division of Library +Automation at the University of California * Design criteria for packet +radio * A demonstration project in San Diego and future plans * Spread +spectrum * Frequencies at which the radios will run and plans to +reimplement the WAIS server software in the public domain * Need for an +infrastructure of radios that do not move around * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Edwin BROWNRIGG, executive director, Memex Research Institute, first +polled the audience in order to seek out regular users of the Internet as +well as those planning to use it some time in the future. With nearly +everybody in the room falling into one category or the other, BROWNRIGG +made a point re access, namely that numerous individuals, especially those +who use the Internet every day, take for granted their access to it, the +speeds with which they are connected, and how well it all works. +However, as BROWNRIGG discovered between 1987 and 1989 in Australia, +if one wants access to the Internet but cannot afford it or has some +physical boundary that prevents her or him from gaining access, it can +be extremely frustrating. He suggested that because of economics and +physical barriers we were beginning to create a world of haves and have-nots +in the process of scholarly communication, even in the United States. + +BROWNRIGG detailed the development of MELVYL in academic year 1980-81 in +the Division of Library Automation at the University of California, in +order to underscore the issue of access to the system, which at the +outset was extremely limited. In short, the project needed to build a +network, which at that time entailed use of satellite technology, that is, +putting earth stations on campus and also acquiring some terrestrial links +from the State of California's microwave system. The installation of +satellite links, however, did not solve the problem (which actually +formed part of a larger problem involving politics and financial resources). +For while the project team could get a signal onto a campus, it had no means +of distributing the signal throughout the campus. The solution involved +adopting a recent development in wireless communication called packet radio, +which combined the basic notion of packet-switching with radio. The project +used this technology to get the signal from a point on campus where it +came down, an earth station for example, into the libraries, because it +found that wiring the libraries, especially the older marble buildings, +would cost $2,000-$5,000 per terminal. + +BROWNRIGG noted that, ten years ago, the project had neither the public +policy nor the technology that would have allowed it to use packet radio +in any meaningful way. Since then much had changed. He proceeded to +detail research and development of the technology, how it is being +deployed in California, and what direction he thought it would take. +The design criteria are to produce a high-speed, one-time, low-cost, +high-quality, secure, license-free device (packet radio) that one can +plug in and play today, forget about it, and have access to the Internet. +By high speed, BROWNRIGG meant 1 megabyte and 1.5 megabytes. Those units +have been built, he continued, and are in the process of being +type-certified by an independent underwriting laboratory so that they can +be type-licensed by the Federal Communications Commission. As is the +case with citizens band, one will be able to purchase a unit and not have +to worry about applying for a license. + +The basic idea, BROWNRIGG elaborated, is to take high-speed radio data +transmission and create a backbone network that at certain strategic +points in the network will "gateway" into a medium-speed packet radio +(i.e., one that runs at 38.4 kilobytes), so that perhaps by 1994-1995 +people, like those in the audience for the price of a VCR could purchase +a medium-speed radio for the office or home, have full network connectivity +to the Internet, and partake of all its services, with no need for an FCC +license and no regular bill from the local common carrier. BROWNRIGG +presented several details of a demonstration project currently taking +place in San Diego and described plans, pending funding, to install a +full-bore network in the San Francisco area. This network will have 600 +nodes running at backbone speeds, and 100 of these nodes will be libraries, +which in turn will be the gateway ports to the 38.4 kilobyte radios that +will give coverage for the neighborhoods surrounding the libraries. + +BROWNRIGG next explained Part 15.247, a new rule within Title 47 of the +Code of Federal Regulations enacted by the FCC in 1985. This rule +challenged the industry, which has only now risen to the occasion, to +build a radio that would run at no more than one watt of output power and +use a fairly exotic method of modulating the radio wave called spread +spectrum. Spread spectrum in fact permits the building of networks so +that numerous data communications can occur simultaneously, without +interfering with each other, within the same wide radio channel. + +BROWNRIGG explained that the frequencies at which the radios would run +are very short wave signals. They are well above standard microwave and +radar. With a radio wave that small, one watt becomes a tremendous punch +per bit and thus makes transmission at reasonable speed possible. In +order to minimize the potential for congestion, the project is +undertaking to reimplement software which has been available in the +networking business and is taken for granted now, for example, TCP/IP, +routing algorithms, bridges, and gateways. In addition, the project +plans to take the WAIS server software in the public domain and +reimplement it so that one can have a WAIS server on a Mac instead of a +Unix machine. The Memex Research Institute believes that libraries, in +particular, will want to use the WAIS servers with packet radio. This +project, which has a team of about twelve people, will run through 1993 +and will include the 100 libraries already mentioned as well as other +professionals such as those in the medical profession, engineering, and +law. Thus, the need is to create an infrastructure of radios that do not +move around, which, BROWNRIGG hopes, will solve a problem not only for +libraries but for individuals who, by and large today, do not have access +to the Internet from their homes and offices. + + ****** + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +DISCUSSION * Project operating frequencies * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +During a brief discussion period, which also concluded the day's +proceedings, BROWNRIGG stated that the project was operating in four +frequencies. The slow speed is operating at 435 megahertz, and it would +later go up to 920 megahertz. With the high-speed frequency, the +one-megabyte radios will run at 2.4 gigabits, and 1.5 will run at 5.7. +At 5.7, rain can be a factor, but it would have to be tropical rain, +unlike what falls in most parts of the United States. + + ****** + +SESSION IV. IMAGE CAPTURE, TEXT CAPTURE, OVERVIEW OF TEXT AND + IMAGE STORAGE FORMATS + +William HOOTON, vice president of operations, I-NET, moderated this session. + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +KENNEY * Factors influencing development of CXP * Advantages of using +digital technology versus photocopy and microfilm * A primary goal of +CXP; publishing challenges * Characteristics of copies printed * Quality +of samples achieved in image capture * Several factors to be considered +in choosing scanning * Emphasis of CXP on timely and cost-effective +production of black-and-white printed facsimiles * Results of producing +microfilm from digital files * Advantages of creating microfilm * Details +concerning production * Costs * Role of digital technology in library +preservation * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Anne KENNEY, associate director, Department of Preservation and +Conservation, Cornell University, opened her talk by observing that the +Cornell Xerox Project (CXP) has been guided by the assumption that the +ability to produce printed facsimiles or to replace paper with paper +would be important, at least for the present generation of users and +equipment. She described three factors that influenced development of +the project: 1) Because the project has emphasized the preservation of +deteriorating brittle books, the quality of what was produced had to be +sufficiently high to return a paper replacement to the shelf. CXP was +only interested in using: 2) a system that was cost-effective, which +meant that it had to be cost-competitive with the processes currently +available, principally photocopy and microfilm, and 3) new or currently +available product hardware and software. + +KENNEY described the advantages that using digital technology offers over +both photocopy and microfilm: 1) The potential exists to create a higher +quality reproduction of a deteriorating original than conventional +light-lens technology. 2) Because a digital image is an encoded +representation, it can be reproduced again and again with no resulting +loss of quality, as opposed to the situation with light-lens processes, +in which there is discernible difference between a second and a +subsequent generation of an image. 3) A digital image can be manipulated +in a number of ways to improve image capture; for example, Xerox has +developed a windowing application that enables one to capture a page +containing both text and illustrations in a manner that optimizes the +reproduction of both. (With light-lens technology, one must choose which +to optimize, text or the illustration; in preservation microfilming, the +current practice is to shoot an illustrated page twice, once to highlight +the text and the second time to provide the best capture for the +illustration.) 4) A digital image can also be edited, density levels +adjusted to remove underlining and stains, and to increase legibility for +faint documents. 5) On-screen inspection can take place at the time of +initial setup and adjustments made prior to scanning, factors that +substantially reduce the number of retakes required in quality control. + +A primary goal of CXP has been to evaluate the paper output printed on +the Xerox DocuTech, a high-speed printer that produces 600-dpi pages from +scanned images at a rate of 135 pages a minute. KENNEY recounted several +publishing challenges to represent faithful and legible reproductions of +the originals that the 600-dpi copy for the most part successfully +captured. For example, many of the deteriorating volumes in the project +were heavily illustrated with fine line drawings or halftones or came in +languages such as Japanese, in which the buildup of characters comprised +of varying strokes is difficult to reproduce at lower resolutions; a +surprising number of them came with annotations and mathematical +formulas, which it was critical to be able to duplicate exactly. + +KENNEY noted that 1) the copies are being printed on paper that meets the +ANSI standards for performance, 2) the DocuTech printer meets the machine +and toner requirements for proper adhesion of print to page, as described +by the National Archives, and thus 3) paper product is considered to be +the archival equivalent of preservation photocopy. + +KENNEY then discussed several samples of the quality achieved in the +project that had been distributed in a handout, for example, a copy of a +print-on-demand version of the 1911 Reed lecture on the steam turbine, +which contains halftones, line drawings, and illustrations embedded in +text; the first four loose pages in the volume compared the capture +capabilities of scanning to photocopy for a standard test target, the +IEEE standard 167A 1987 test chart. In all instances scanning proved +superior to photocopy, though only slightly more so in one. + +Conceding the simplistic nature of her review of the quality of scanning +to photocopy, KENNEY described it as one representation of the kinds of +settings that could be used with scanning capabilities on the equipment +CXP uses. KENNEY also pointed out that CXP investigated the quality +achieved with binary scanning only, and noted the great promise in gray +scale and color scanning, whose advantages and disadvantages need to be +examined. She argued further that scanning resolutions and file formats +can represent a complex trade-off between the time it takes to capture +material, file size, fidelity to the original, and on-screen display; and +printing and equipment availability. All these factors must be taken +into consideration. + +CXP placed primary emphasis on the production in a timely and +cost-effective manner of printed facsimiles that consisted largely of +black-and-white text. With binary scanning, large files may be +compressed efficiently and in a lossless manner (i.e., no data is lost in +the process of compressing [and decompressing] an image--the exact +bit-representation is maintained) using Group 4 CCITT (i.e., the French +acronym for International Consultative Committee for Telegraph and +Telephone) compression. CXP was getting compression ratios of about +forty to one. Gray-scale compression, which primarily uses JPEG, is much +less economical and can represent a lossy compression (i.e., not +lossless), so that as one compresses and decompresses, the illustration +is subtly changed. While binary files produce a high-quality printed +version, it appears 1) that other combinations of spatial resolution with +gray and/or color hold great promise as well, and 2) that gray scale can +represent a tremendous advantage for on-screen viewing. The quality +associated with binary and gray scale also depends on the equipment used. +For instance, binary scanning produces a much better copy on a binary +printer. + +Among CXP's findings concerning the production of microfilm from digital +files, KENNEY reported that the digital files for the same Reed lecture +were used to produce sample film using an electron beam recorder. The +resulting film was faithful to the image capture of the digital files, +and while CXP felt that the text and image pages represented in the Reed +lecture were superior to that of the light-lens film, the resolution +readings for the 600 dpi were not as high as standard microfilming. +KENNEY argued that the standards defined for light-lens technology are +not totally transferable to a digital environment. Moreover, they are +based on definition of quality for a preservation copy. Although making +this case will prove to be a long, uphill struggle, CXP plans to continue +to investigate the issue over the course of the next year. + +KENNEY concluded this portion of her talk with a discussion of the +advantages of creating film: it can serve as a primary backup and as a +preservation master to the digital file; it could then become the print +or production master and service copies could be paper, film, optical +disks, magnetic media, or on-screen display. + +Finally, KENNEY presented details re production: + + * Development and testing of a moderately-high resolution production + scanning workstation represented a third goal of CXP; to date, 1,000 + volumes have been scanned, or about 300,000 images. + + * The resulting digital files are stored and used to produce + hard-copy replacements for the originals and additional prints on + demand; although the initial costs are high, scanning technology + offers an affordable means for reformatting brittle material. + + * A technician in production mode can scan 300 pages per hour when + performing single-sheet scanning, which is a necessity when working + with truly brittle paper; this figure is expected to increase + significantly with subsequent iterations of the software from Xerox; + a three-month time-and-cost study of scanning found that the average + 300-page book would take about an hour and forty minutes to scan + (this figure included the time for setup, which involves keying in + primary bibliographic data, going into quality control mode to + define page size, establishing front-to-back registration, and + scanning sample pages to identify a default range of settings for + the entire book--functions not dissimilar to those performed by + filmers or those preparing a book for photocopy). + + * The final step in the scanning process involved rescans, which + happily were few and far between, representing well under 1 percent + of the total pages scanned. + +In addition to technician time, CXP costed out equipment, amortized over +four years, the cost of storing and refreshing the digital files every +four years, and the cost of printing and binding, book-cloth binding, a +paper reproduction. The total amounted to a little under $65 per single +300-page volume, with 30 percent overhead included--a figure competitive +with the prices currently charged by photocopy vendors. + +Of course, with scanning, in addition to the paper facsimile, one is left +with a digital file from which subsequent copies of the book can be +produced for a fraction of the cost of photocopy, with readers afforded +choices in the form of these copies. + +KENNEY concluded that digital technology offers an electronic means for a +library preservation effort to pay for itself. If a brittle-book program +included the means of disseminating reprints of books that are in demand +by libraries and researchers alike, the initial investment in capture +could be recovered and used to preserve additional but less popular +books. She disclosed that an economic model for a self-sustaining +program could be developed for CXP's report to the Commission on +Preservation and Access (CPA). + +KENNEY stressed that the focus of CXP has been on obtaining high quality +in a production environment. The use of digital technology is viewed as +an affordable alternative to other reformatting options. + + ****** + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +ANDRE * Overview and history of NATDP * Various agricultural CD-ROM +products created inhouse and by service bureaus * Pilot project on +Internet transmission * Additional products in progress * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Pamela ANDRE, associate director for automation, National Agricultural +Text Digitizing Program (NATDP), National Agricultural Library (NAL), +presented an overview of NATDP, which has been underway at NAL the last +four years, before Judith ZIDAR discussed the technical details. ANDRE +defined agricultural information as a broad range of material going from +basic and applied research in the hard sciences to the one-page pamphlets +that are distributed by the cooperative state extension services on such +things as how to grow blueberries. + +NATDP began in late 1986 with a meeting of representatives from the +land-grant library community to deal with the issue of electronic +information. NAL and forty-five of these libraries banded together to +establish this project--to evaluate the technology for converting what +were then source documents in paper form into electronic form, to provide +access to that digital information, and then to distribute it. +Distributing that material to the community--the university community as +well as the extension service community, potentially down to the county +level--constituted the group's chief concern. + +Since January 1988 (when the microcomputer-based scanning system was +installed at NAL), NATDP has done a variety of things, concerning which +ZIDAR would provide further details. For example, the first technology +considered in the project's discussion phase was digital videodisc, which +indicates how long ago it was conceived. + +Over the four years of this project, four separate CD-ROM products on +four different agricultural topics were created, two at a +scanning-and-OCR station installed at NAL, and two by service bureaus. +Thus, NATDP has gained comparative information in terms of those relative +costs. Each of these products contained the full ASCII text as well as +page images of the material, or between 4,000 and 6,000 pages of material +on these disks. Topics included aquaculture, food, agriculture and +science (i.e., international agriculture and research), acid rain, and +Agent Orange, which was the final product distributed (approximately +eighteen months before the Workshop). + +The third phase of NATDP focused on delivery mechanisms other than +CD-ROM. At the suggestion of Clifford LYNCH, who was a technical +consultant to the project at this point, NATDP became involved with the +Internet and initiated a project with the help of North Carolina State +University, in which fourteen of the land-grant university libraries are +transmitting digital images over the Internet in response to interlibrary +loan requests--a topic for another meeting. At this point, the pilot +project had been completed for about a year and the final report would be +available shortly after the Workshop. In the meantime, the project's +success had led to its extension. (ANDRE noted that one of the first +things done under the program title was to select a retrieval package to +use with subsequent products; Windows Personal Librarian was the package +of choice after a lengthy evaluation.) + +Three additional products had been planned and were in progress: + + 1) An arrangement with the American Society of Agronomy--a + professional society that has published the Agronomy Journal since + about 1908--to scan and create bit-mapped images of its journal. + ASA granted permission first to put and then to distribute this + material in electronic form, to hold it at NAL, and to use these + electronic images as a mechanism to deliver documents or print out + material for patrons, among other uses. Effectively, NAL has the + right to use this material in support of its program. + (Significantly, this arrangement offers a potential cooperative + model for working with other professional societies in agriculture + to try to do the same thing--put the journals of particular interest + to agriculture research into electronic form.) + + 2) An extension of the earlier product on aquaculture. + + 3) The George Washington Carver Papers--a joint project with + Tuskegee University to scan and convert from microfilm some 3,500 + images of Carver's papers, letters, and drawings. + +It was anticipated that all of these products would appear no more than +six months after the Workshop. + + ****** + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +ZIDAR * (A separate arena for scanning) * Steps in creating a database * +Image capture, with and without performing OCR * Keying in tracking data +* Scanning, with electronic and manual tracking * Adjustments during +scanning process * Scanning resolutions * Compression * De-skewing and +filtering * Image capture from microform: the papers and letters of +George Washington Carver * Equipment used for a scanning system * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Judith ZIDAR, coordinator, National Agricultural Text Digitizing Program +(NATDP), National Agricultural Library (NAL), illustrated the technical +details of NATDP, including her primary responsibility, scanning and +creating databases on a topic and putting them on CD-ROM. + +(ZIDAR remarked a separate arena from the CD-ROM projects, although the +processing of the material is nearly identical, in which NATDP is also +scanning material and loading it on a Next microcomputer, which in turn +is linked to NAL's integrated library system. Thus, searches in NAL's +bibliographic database will enable people to pull up actual page images +and text for any documents that have been entered.) + +In accordance with the session's topic, ZIDAR focused her illustrated +talk on image capture, offering a primer on the three main steps in the +process: 1) assemble the printed publications; 2) design the database +(database design occurs in the process of preparing the material for +scanning; this step entails reviewing and organizing the material, +defining the contents--what will constitute a record, what kinds of +fields will be captured in terms of author, title, etc.); 3) perform a +certain amount of markup on the paper publications. NAL performs this +task record by record, preparing work sheets or some other sort of +tracking material and designing descriptors and other enhancements to be +added to the data that will not be captured from the printed publication. +Part of this process also involves determining NATDP's file and directory +structure: NATDP attempts to avoid putting more than approximately 100 +images in a directory, because placing more than that on a CD-ROM would +reduce the access speed. + +This up-front process takes approximately two weeks for a +6,000-7,000-page database. The next step is to capture the page images. +How long this process takes is determined by the decision whether or not +to perform OCR. Not performing OCR speeds the process, whereas text +capture requires greater care because of the quality of the image: it +has to be straighter and allowance must be made for text on a page, not +just for the capture of photographs. + +NATDP keys in tracking data, that is, a standard bibliographic record +including the title of the book and the title of the chapter, which will +later either become the access information or will be attached to the +front of a full-text record so that it is searchable. + +Images are scanned from a bound or unbound publication, chiefly from +bound publications in the case of NATDP, however, because often they are +the only copies and the publications are returned to the shelves. NATDP +usually scans one record at a time, because its database tracking system +tracks the document in that way and does not require further logical +separating of the images. After performing optical character +recognition, NATDP moves the images off the hard disk and maintains a +volume sheet. Though the system tracks electronically, all the +processing steps are also tracked manually with a log sheet. + +ZIDAR next illustrated the kinds of adjustments that one can make when +scanning from paper and microfilm, for example, redoing images that need +special handling, setting for dithering or gray scale, and adjusting for +brightness or for the whole book at one time. + +NATDP is scanning at 300 dots per inch, a standard scanning resolution. +Though adequate for capturing text that is all of a standard size, 300 +dpi is unsuitable for any kind of photographic material or for very small +text. Many scanners allow for different image formats, TIFF, of course, +being a de facto standard. But if one intends to exchange images with +other people, the ability to scan other image formats, even if they are +less common, becomes highly desirable. + +CCITT Group 4 is the standard compression for normal black-and-white +images, JPEG for gray scale or color. ZIDAR recommended 1) using the +standard compressions, particularly if one attempts to make material +available and to allow users to download images and reuse them from +CD-ROMs; and 2) maintaining the ability to output an uncompressed image, +because in image exchange uncompressed images are more likely to be able +to cross platforms. + +ZIDAR emphasized the importance of de-skewing and filtering as +requirements on NATDP's upgraded system. For instance, scanning bound +books, particularly books published by the federal government whose pages +are skewed, and trying to scan them straight if OCR is to be performed, +is extremely time-consuming. The same holds for filtering of +poor-quality or older materials. + +ZIDAR described image capture from microform, using as an example three +reels from a sixty-seven-reel set of the papers and letters of George +Washington Carver that had been produced by Tuskegee University. These +resulted in approximately 3,500 images, which NATDP had had scanned by +its service contractor, Science Applications International Corporation +(SAIC). NATDP also created bibliographic records for access. (NATDP did +not have such specialized equipment as a microfilm scanner. + +Unfortunately, the process of scanning from microfilm was not an +unqualified success, ZIDAR reported: because microfilm frame sizes vary, +occasionally some frames were missed, which without spending much time +and money could not be recaptured. + +OCR could not be performed from the scanned images of the frames. The +bleeding in the text simply output text, when OCR was run, that could not +even be edited. NATDP tested for negative versus positive images, +landscape versus portrait orientation, and single- versus dual-page +microfilm, none of which seemed to affect the quality of the image; but +also on none of them could OCR be performed. + +In selecting the microfilm they would use, therefore, NATDP had other +factors in mind. ZIDAR noted two factors that influenced the quality of +the images: 1) the inherent quality of the original and 2) the amount of +size reduction on the pages. + +The Carver papers were selected because they are informative and visually +interesting, treat a single subject, and are valuable in their own right. +The images were scanned and divided into logical records by SAIC, then +delivered, and loaded onto NATDP's system, where bibliographic +information taken directly from the images was added. Scanning was +completed in summer 1991 and by the end of summer 1992 the disk was +scheduled to be published. + +Problems encountered during processing included the following: Because +the microfilm scanning had to be done in a batch, adjustment for +individual page variations was not possible. The frame size varied on +account of the nature of the material, and therefore some of the frames +were missed while others were just partial frames. The only way to go +back and capture this material was to print out the page with the +microfilm reader from the missing frame and then scan it in from the +page, which was extremely time-consuming. The quality of the images +scanned from the printout of the microfilm compared unfavorably with that +of the original images captured directly from the microfilm. The +inability to perform OCR also was a major disappointment. At the time, +computer output microfilm was unavailable to test. + +The equipment used for a scanning system was the last topic addressed by +ZIDAR. The type of equipment that one would purchase for a scanning +system included: a microcomputer, at least a 386, but preferably a 486; +a large hard disk, 380 megabyte at minimum; a multi-tasking operating +system that allows one to run some things in batch in the background +while scanning or doing text editing, for example, Unix or OS/2 and, +theoretically, Windows; a high-speed scanner and scanning software that +allows one to make the various adjustments mentioned earlier; a +high-resolution monitor (150 dpi ); OCR software and hardware to perform +text recognition; an optical disk subsystem on which to archive all the +images as the processing is done; file management and tracking software. + +ZIDAR opined that the software one purchases was more important than the +hardware and might also cost more than the hardware, but it was likely to +prove critical to the success or failure of one's system. In addition to +a stand-alone scanning workstation for image capture, then, text capture +requires one or two editing stations networked to this scanning station +to perform editing. Editing the text takes two or three times as long as +capturing the images. + +Finally, ZIDAR stressed the importance of buying an open system that allows +for more than one vendor, complies with standards, and can be upgraded. + + ****** + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +WATERS *Yale University Library's master plan to convert microfilm to +digital imagery (POB) * The place of electronic tools in the library of +the future * The uses of images and an image library * Primary input from +preservation microfilm * Features distinguishing POB from CXP and key +hypotheses guiding POB * Use of vendor selection process to facilitate +organizational work * Criteria for selecting vendor * Finalists and +results of process for Yale * Key factor distinguishing vendors * +Components, design principles, and some estimated costs of POB * Role of +preservation materials in developing imaging market * Factors affecting +quality and cost * Factors affecting the usability of complex documents +in image form * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Donald WATERS, head of the Systems Office, Yale University Library, +reported on the progress of a master plan for a project at Yale to +convert microfilm to digital imagery, Project Open Book (POB). Stating +that POB was in an advanced stage of planning, WATERS detailed, in +particular, the process of selecting a vendor partner and several key +issues under discussion as Yale prepares to move into the project itself. +He commented first on the vision that serves as the context of POB and +then described its purpose and scope. + +WATERS sees the library of the future not necessarily as an electronic +library but as a place that generates, preserves, and improves for its +clients ready access to both intellectual and physical recorded +knowledge. Electronic tools must find a place in the library in the +context of this vision. Several roles for electronic tools include +serving as: indirect sources of electronic knowledge or as "finding" +aids (the on-line catalogues, the article-level indices, registers for +documents and archives); direct sources of recorded knowledge; full-text +images; and various kinds of compound sources of recorded knowledge (the +so-called compound documents of Hypertext, mixed text and image, +mixed-text image format, and multimedia). + +POB is looking particularly at images and an image library, the uses to +which images will be put (e.g., storage, printing, browsing, and then use +as input for other processes), OCR as a subsequent process to image +capture, or creating an image library, and also possibly generating +microfilm. + +While input will come from a variety of sources, POB is considering +especially input from preservation microfilm. A possible outcome is that +the film and paper which provide the input for the image library +eventually may go off into remote storage, and that the image library may +be the primary access tool. + +The purpose and scope of POB focus on imaging. Though related to CXP, +POB has two features which distinguish it: 1) scale--conversion of +10,000 volumes into digital image form; and 2) source--conversion from +microfilm. Given these features, several key working hypotheses guide +POB, including: 1) Since POB is using microfilm, it is not concerned with +the image library as a preservation medium. 2) Digital imagery can improve +access to recorded knowledge through printing and network distribution at +a modest incremental cost of microfilm. 3) Capturing and storing documents +in a digital image form is necessary to further improvements in access. +(POB distinguishes between the imaging, digitizing process and OCR, +which at this stage it does not plan to perform.) + +Currently in its first or organizational phase, POB found that it could +use a vendor selection process to facilitate a good deal of the +organizational work (e.g., creating a project team and advisory board, +confirming the validity of the plan, establishing the cost of the project +and a budget, selecting the materials to convert, and then raising the +necessary funds). + +POB developed numerous selection criteria, including: a firm committed +to image-document management, the ability to serve as systems integrator +in a large-scale project over several years, interest in developing the +requisite software as a standard rather than a custom product, and a +willingness to invest substantial resources in the project itself. + +Two vendors, DEC and Xerox, were selected as finalists in October 1991, +and with the support of the Commission on Preservation and Access, each +was commissioned to generate a detailed requirements analysis for the +project and then to submit a formal proposal for the completion of the +project, which included a budget and costs. The terms were that POB would +pay the loser. The results for Yale of involving a vendor included: +broad involvement of Yale staff across the board at a relatively low +cost, which may have long-term significance in carrying out the project +(twenty-five to thirty university people are engaged in POB); better +understanding of the factors that affect corporate response to markets +for imaging products; a competitive proposal; and a more sophisticated +view of the imaging markets. + +The most important factor that distinguished the vendors under +consideration was their identification with the customer. The size and +internal complexity of the company also was an important factor. POB was +looking at large companies that had substantial resources. In the end, +the process generated for Yale two competitive proposals, with Xerox's +the clear winner. WATERS then described the components of the proposal, +the design principles, and some of the costs estimated for the process. + +Components are essentially four: a conversion subsystem, a +network-accessible storage subsystem for 10,000 books (and POB expects +200 to 600 dpi storage), browsing stations distributed on the campus +network, and network access to the image printers. + +Among the design principles, POB wanted conversion at the highest +possible resolution. Assuming TIFF files, TIFF files with Group 4 +compression, TCP/IP, and ethernet network on campus, POB wanted a +client-server approach with image documents distributed to the +workstations and made accessible through native workstation interfaces +such as Windows. POB also insisted on a phased approach to +implementation: 1) a stand-alone, single-user, low-cost entry into the +business with a workstation focused on conversion and allowing POB to +explore user access; 2) movement into a higher-volume conversion with +network-accessible storage and multiple access stations; and 3) a +high-volume conversion, full-capacity storage, and multiple browsing +stations distributed throughout the campus. + +The costs proposed for start-up assumed the existence of the Yale network +and its two DocuTech image printers. Other start-up costs are estimated +at $1 million over the three phases. At the end of the project, the annual +operating costs estimated primarily for the software and hardware proposed +come to about $60,000, but these exclude costs for labor needed in the +conversion process, network and printer usage, and facilities management. + +Finally, the selection process produced for Yale a more sophisticated +view of the imaging markets: the management of complex documents in +image form is not a preservation problem, not a library problem, but a +general problem in a broad, general industry. Preservation materials are +useful for developing that market because of the qualities of the +material. For example, much of it is out of copyright. The resolution +of key issues such as the quality of scanning and image browsing also +will affect development of that market. + +The technology is readily available but changing rapidly. In this +context of rapid change, several factors affect quality and cost, to +which POB intends to pay particular attention, for example, the various +levels of resolution that can be achieved. POB believes it can bring +resolution up to 600 dpi, but an interpolation process from 400 to 600 is +more likely. The variation quality in microfilm will prove to be a +highly important factor. POB may reexamine the standards used to film in +the first place by looking at this process as a follow-on to microfilming. + +Other important factors include: the techniques available to the +operator for handling material, the ways of integrating quality control +into the digitizing work flow, and a work flow that includes indexing and +storage. POB's requirement was to be able to deal with quality control +at the point of scanning. Thus, thanks to Xerox, POB anticipates having +a mechanism which will allow it not only to scan in batch form, but to +review the material as it goes through the scanner and control quality +from the outset. + +The standards for measuring quality and costs depend greatly on the uses +of the material, including subsequent OCR, storage, printing, and +browsing. But especially at issue for POB is the facility for browsing. +This facility, WATERS said, is perhaps the weakest aspect of imaging +technology and the most in need of development. + +A variety of factors affect the usability of complex documents in image +form, among them: 1) the ability of the system to handle the full range +of document types, not just monographs but serials, multi-part +monographs, and manuscripts; 2) the location of the database of record +for bibliographic information about the image document, which POB wants +to enter once and in the most useful place, the on-line catalog; 3) a +document identifier for referencing the bibliographic information in one +place and the images in another; 4) the technique for making the basic +internal structure of the document accessible to the reader; and finally, +5) the physical presentation on the CRT of those documents. POB is ready +to complete this phase now. One last decision involves deciding which +material to scan. + + ****** + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +DISCUSSION * TIFF files constitute de facto standard * NARA's experience +with image conversion software and text conversion * RFC 1314 * +Considerable flux concerning available hardware and software solutions * +NAL through-put rate during scanning * Window management questions * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +In the question-and-answer period that followed WATERS's presentation, +the following points emerged: + + * ZIDAR's statement about using TIFF files as a standard meant de + facto standard. This is what most people use and typically exchange + with other groups, across platforms, or even occasionally across + display software. + + * HOLMES commented on the unsuccessful experience of NARA in + attempting to run image-conversion software or to exchange between + applications: What are supposedly TIFF files go into other software + that is supposed to be able to accept TIFF but cannot recognize the + format and cannot deal with it, and thus renders the exchange + useless. Re text conversion, he noted the different recognition + rates obtained by substituting the make and model of scanners in + NARA's recent test of an "intelligent" character-recognition product + for a new company. In the selection of hardware and software, + HOLMES argued, software no longer constitutes the overriding factor + it did until about a year ago; rather it is perhaps important to + look at both now. + + * Danny Cohen and Alan Katz of the University of Southern California + Information Sciences Institute began circulating as an Internet RFC + (RFC 1314) about a month ago a standard for a TIFF interchange + format for Internet distribution of monochrome bit-mapped images, + which LYNCH said he believed would be used as a de facto standard. + + * FLEISCHHAUER's impression from hearing these reports and thinking + about AM's experience was that there is considerable flux concerning + available hardware and software solutions. HOOTON agreed and + commented at the same time on ZIDAR's statement that the equipment + employed affects the results produced. One cannot draw a complete + conclusion by saying it is difficult or impossible to perform OCR + from scanning microfilm, for example, with that device, that set of + parameters, and system requirements, because numerous other people + are accomplishing just that, using other components, perhaps. + HOOTON opined that both the hardware and the software were highly + important. Most of the problems discussed today have been solved in + numerous different ways by other people. Though it is good to be + cognizant of various experiences, this is not to say that it will + always be thus. + + * At NAL, the through-put rate of the scanning process for paper, + page by page, performing OCR, ranges from 300 to 600 pages per day; + not performing OCR is considerably faster, although how much faster + is not known. This is for scanning from bound books, which is much + slower. + + * WATERS commented on window management questions: DEC proposed an + X-Windows solution which was problematical for two reasons. One was + POB's requirement to be able to manipulate images on the workstation + and bring them down to the workstation itself and the other was + network usage. + + ****** + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +THOMA * Illustration of deficiencies in scanning and storage process * +Image quality in this process * Different costs entailed by better image +quality * Techniques for overcoming various de-ficiencies: fixed +thresholding, dynamic thresholding, dithering, image merge * Page edge +effects * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +George THOMA, chief, Communications Engineering Branch, National Library +of Medicine (NLM), illustrated several of the deficiencies discussed by +the previous speakers. He introduced the topic of special problems by +noting the advantages of electronic imaging. For example, it is regenerable +because it is a coded file, and real-time quality control is possible with +electronic capture, whereas in photographic capture it is not. + +One of the difficulties discussed in the scanning and storage process was +image quality which, without belaboring the obvious, means different +things for maps, medical X-rays, or broadcast television. In the case of +documents, THOMA said, image quality boils down to legibility of the +textual parts, and fidelity in the case of gray or color photo print-type +material. Legibility boils down to scan density, the standard in most +cases being 300 dpi. Increasing the resolution with scanners that +perform 600 or 1200 dpi, however, comes at a cost. + +Better image quality entails at least four different kinds of costs: 1) +equipment costs, because the CCD (i.e., charge-couple device) with +greater number of elements costs more; 2) time costs that translate to +the actual capture costs, because manual labor is involved (the time is +also dependent on the fact that more data has to be moved around in the +machine in the scanning or network devices that perform the scanning as +well as the storage); 3) media costs, because at high resolutions larger +files have to be stored; and 4) transmission costs, because there is just +more data to be transmitted. + +But while resolution takes care of the issue of legibility in image +quality, other deficiencies have to do with contrast and elements on the +page scanned or the image that needed to be removed or clarified. Thus, +THOMA proceeded to illustrate various deficiencies, how they are +manifested, and several techniques to overcome them. + +Fixed thresholding was the first technique described, suitable for +black-and-white text, when the contrast does not vary over the page. One +can have many different threshold levels in scanning devices. Thus, +THOMA offered an example of extremely poor contrast, which resulted from +the fact that the stock was a heavy red. This is the sort of image that +when microfilmed fails to provide any legibility whatsoever. Fixed +thresholding is the way to change the black-to-red contrast to the +desired black-to-white contrast. + +Other examples included material that had been browned or yellowed by +age. This was also a case of contrast deficiency, and correction was +done by fixed thresholding. A final example boils down to the same +thing, slight variability, but it is not significant. Fixed thresholding +solves this problem as well. The microfilm equivalent is certainly legible, +but it comes with dark areas. Though THOMA did not have a slide of the +microfilm in this case, he did show the reproduced electronic image. + +When one has variable contrast over a page or the lighting over the page +area varies, especially in the case where a bound volume has light +shining on it, the image must be processed by a dynamic thresholding +scheme. One scheme, dynamic averaging, allows the threshold level not to +be fixed but to be recomputed for every pixel from the neighboring +characteristics. The neighbors of a pixel determine where the threshold +should be set for that pixel. + +THOMA showed an example of a page that had been made deficient by a +variety of techniques, including a burn mark, coffee stains, and a yellow +marker. Application of a fixed-thresholding scheme, THOMA argued, might +take care of several deficiencies on the page but not all of them. +Performing the calculation for a dynamic threshold setting, however, +removes most of the deficiencies so that at least the text is legible. + +Another problem is representing a gray level with black-and-white pixels +by a process known as dithering or electronic screening. But dithering +does not provide good image quality for pure black-and-white textual +material. THOMA illustrated this point with examples. Although its +suitability for photoprint is the reason for electronic screening or +dithering, it cannot be used for every compound image. In the document +that was distributed by CXP, THOMA noticed that the dithered image of the +IEEE test chart evinced some deterioration in the text. He presented an +extreme example of deterioration in the text in which compounded +documents had to be set right by other techniques. The technique +illustrated by the present example was an image merge in which the page +is scanned twice and the settings go from fixed threshold to the +dithering matrix; the resulting images are merged to give the best +results with each technique. + +THOMA illustrated how dithering is also used in nonphotographic or +nonprint materials with an example of a grayish page from a medical text, +which was reproduced to show all of the gray that appeared in the +original. Dithering provided a reproduction of all the gray in the +original of another example from the same text. + +THOMA finally illustrated the problem of bordering, or page-edge, +effects. Books and bound volumes that are placed on a photocopy machine +or a scanner produce page-edge effects that are undesirable for two +reasons: 1) the aesthetics of the image; after all, if the image is to +be preserved, one does not necessarily want to keep all of its +deficiencies; 2) compression (with the bordering problem THOMA +illustrated, the compression ratio deteriorated tremendously). One way +to eliminate this more serious problem is to have the operator at the +point of scanning window the part of the image that is desirable and +automatically turn all of the pixels out of that picture to white. + + ****** + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +FLEISCHHAUER * AM's experience with scanning bound materials * Dithering +* ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Carl FLEISCHHAUER, coordinator, American Memory, Library of Congress, +reported AM's experience with scanning bound materials, which he likened +to the problems involved in using photocopying machines. Very few +devices in the industry offer book-edge scanning, let alone book cradles. +The problem may be unsolvable, FLEISCHHAUER said, because a large enough +market does not exist for a preservation-quality scanner. AM is using a +Kurzweil scanner, which is a book-edge scanner now sold by Xerox. + +Devoting the remainder of his brief presentation to dithering, +FLEISCHHAUER related AM's experience with a contractor who was using +unsophisticated equipment and software to reduce moire patterns from +printed halftones. AM took the same image and used the dithering +algorithm that forms part of the same Kurzweil Xerox scanner; it +disguised moire patterns much more effectively. + +FLEISCHHAUER also observed that dithering produces a binary file which is +useful for numerous purposes, for example, printing it on a laser printer +without having to "re-halftone" it. But it tends to defeat efficient +compression, because the very thing that dithers to reduce moire patterns +also tends to work against compression schemes. AM thought the +difference in image quality was worth it. + + ****** + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +DISCUSSION * Relative use as a criterion for POB's selection of books to +be converted into digital form * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +During the discussion period, WATERS noted that one of the criteria for +selecting books among the 10,000 to be converted into digital image form +would be how much relative use they would receive--a subject still +requiring evaluation. The challenge will be to understand whether +coherent bodies of material will increase usage or whether POB should +seek material that is being used, scan that, and make it more accessible. +POB might decide to digitize materials that are already heavily used, in +order to make them more accessible and decrease wear on them. Another +approach would be to provide a large body of intellectually coherent +material that may be used more in digital form than it is currently used +in microfilm. POB would seek material that was out of copyright. + + ****** + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +BARONAS * Origin and scope of AIIM * Types of documents produced in +AIIM's standards program * Domain of AIIM's standardization work * AIIM's +structure * TC 171 and MS23 * Electronic image management standards * +Categories of EIM standardization where AIIM standards are being +developed * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Jean BARONAS, senior manager, Department of Standards and Technology, +Association for Information and Image Management (AIIM), described the +not-for-profit association and the national and international programs +for standardization in which AIIM is active. + +Accredited for twenty-five years as the nation's standards development +organization for document image management, AIIM began life in a library +community developing microfilm standards. Today the association +maintains both its library and business-image management standardization +activities--and has moved into electronic image-management +standardization (EIM). + +BARONAS defined the program's scope. AIIM deals with: 1) the +terminology of standards and of the technology it uses; 2) methods of +measurement for the systems, as well as quality; 3) methodologies for +users to evaluate and measure quality; 4) the features of apparatus used +to manage and edit images; and 5) the procedures used to manage images. + +BARONAS noted that three types of documents are produced in the AIIM +standards program: the first two, accredited by the American National +Standards Institute (ANSI), are standards and standard recommended +practices. Recommended practices differ from standards in that they +contain more tutorial information. A technical report is not an ANSI +standard. Because AIIM's policies and procedures for developing +standards are approved by ANSI, its standards are labeled ANSI/AIIM, +followed by the number and title of the standard. + +BARONAS then illustrated the domain of AIIM's standardization work. For +example, AIIM is the administrator of the U.S. Technical Advisory Group +(TAG) to the International Standards Organization's (ISO) technical +committee, TC l7l Micrographics and Optical Memories for Document and +Image Recording, Storage, and Use. AIIM officially works through ANSI in +the international standardization process. + +BARONAS described AIIM's structure, including its board of directors, its +standards board of twelve individuals active in the image-management +industry, its strategic planning and legal admissibility task forces, and +its National Standards Council, which is comprised of the members of a +number of organizations who vote on every AIIM standard before it is +published. BARONAS pointed out that AIIM's liaisons deal with numerous +other standards developers, including the optical disk community, office +and publishing systems, image-codes-and-character set committees, and the +National Information Standards Organization (NISO). + +BARONAS illustrated the procedures of TC l7l, which covers all aspects of +image management. When AIIM's national program has conceptualized a new +project, it is usually submitted to the international level, so that the +member countries of TC l7l can simultaneously work on the development of +the standard or the technical report. BARONAS also illustrated a classic +microfilm standard, MS23, which deals with numerous imaging concepts that +apply to electronic imaging. Originally developed in the l970s, revised +in the l980s, and revised again in l991, this standard is scheduled for +another revision. MS23 is an active standard whereby users may propose +new density ranges and new methods of evaluating film images in the +standard's revision. + +BARONAS detailed several electronic image-management standards, for +instance, ANSI/AIIM MS44, a quality-control guideline for scanning 8.5" +by 11" black-and-white office documents. This standard is used with the +IEEE fax image--a continuous tone photographic image with gray scales, +text, and several continuous tone pictures--and AIIM test target number +2, a representative document used in office document management. + +BARONAS next outlined the four categories of EIM standardization in which +AIIM standards are being developed: transfer and retrieval, evaluation, +optical disc and document scanning applications, and design and +conversion of documents. She detailed several of the main projects of +each: 1) in the category of image transfer and retrieval, a bi-level +image transfer format, ANSI/AIIM MS53, which is a proposed standard that +describes a file header for image transfer between unlike systems when +the images are compressed using G3 and G4 compression; 2) the category of +image evaluation, which includes the AIIM-proposed TR26 tutorial on image +resolution (this technical report will treat the differences and +similarities between classical or photographic and electronic imaging); +3) design and conversion, which includes a proposed technical report +called "Forms Design Optimization for EIM" (this report considers how +general-purpose business forms can be best designed so that scanning is +optimized; reprographic characteristics such as type, rules, background, +tint, and color will likewise be treated in the technical report); 4) +disk and document scanning applications includes a project a) on planning +platters and disk management, b) on generating an application profile for +EIM when images are stored and distributed on CD-ROM, and c) on +evaluating SCSI2, and how a common command set can be generated for SCSI2 +so that document scanners are more easily integrated. (ANSI/AIIM MS53 +will also apply to compressed images.) + + ****** + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +BATTIN * The implications of standards for preservation * A major +obstacle to successful cooperation * A hindrance to access in the digital +environment * Standards a double-edged sword for those concerned with the +preservation of the human record * Near-term prognosis for reliable +archival standards * Preservation concerns for electronic media * Need +for reconceptualizing our preservation principles * Standards in the real +world and the politics of reproduction * Need to redefine the concept of +archival and to begin to think in terms of life cycles * Cooperation and +the La Guardia Eight * Concerns generated by discussions on the problems +of preserving text and image * General principles to be adopted in a +world without standards * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Patricia BATTIN, president, the Commission on Preservation and Access +(CPA), addressed the implications of standards for preservation. She +listed several areas where the library profession and the analog world of +the printed book had made enormous contributions over the past hundred +years--for example, in bibliographic formats, binding standards, and, most +important, in determining what constitutes longevity or archival quality. + +Although standards have lightened the preservation burden through the +development of national and international collaborative programs, +nevertheless, a pervasive mistrust of other people's standards remains a +major obstacle to successful cooperation, BATTIN said. + +The zeal to achieve perfection, regardless of the cost, has hindered +rather than facilitated access in some instances, and in the digital +environment, where no real standards exist, has brought an ironically +just reward. + +BATTIN argued that standards are a double-edged sword for those concerned +with the preservation of the human record, that is, the provision of +access to recorded knowledge in a multitude of media as far into the +future as possible. Standards are essential to facilitate +interconnectivity and access, but, BATTIN said, as LYNCH pointed out +yesterday, if set too soon they can hinder creativity, expansion of +capability, and the broadening of access. The characteristics of +standards for digital imagery differ radically from those for analog +imagery. And the nature of digital technology implies continuing +volatility and change. To reiterate, precipitous standard-setting can +inhibit creativity, but delayed standard-setting results in chaos. + +Since in BATTIN'S opinion the near-term prognosis for reliable archival +standards, as defined by librarians in the analog world, is poor, two +alternatives remain: standing pat with the old technology, or +reconceptualizing. + +Preservation concerns for electronic media fall into two general domains. +One is the continuing assurance of access to knowledge originally +generated, stored, disseminated, and used in electronic form. This +domain contains several subdivisions, including 1) the closed, +proprietary systems discussed the previous day, bundled information such +as electronic journals and government agency records, and electronically +produced or captured raw data; and 2) the application of digital +technologies to the reformatting of materials originally published on a +deteriorating analog medium such as acid paper or videotape. + +The preservation of electronic media requires a reconceptualizing of our +preservation principles during a volatile, standardless transition which +may last far longer than any of us envision today. BATTIN urged the +necessity of shifting focus from assessing, measuring, and setting +standards for the permanence of the medium to the concept of managing +continuing access to information stored on a variety of media and +requiring a variety of ever-changing hardware and software for access--a +fundamental shift for the library profession. + +BATTIN offered a primer on how to move forward with reasonable confidence +in a world without standards. Her comments fell roughly into two sections: +1) standards in the real world and 2) the politics of reproduction. + +In regard to real-world standards, BATTIN argued the need to redefine the +concept of archive and to begin to think in terms of life cycles. In +the past, the naive assumption that paper would last forever produced a +cavalier attitude toward life cycles. The transient nature of the +electronic media has compelled people to recognize and accept upfront the +concept of life cycles in place of permanency. + +Digital standards have to be developed and set in a cooperative context +to ensure efficient exchange of information. Moreover, during this +transition period, greater flexibility concerning how concepts such as +backup copies and archival copies in the CXP are defined is necessary, +or the opportunity to move forward will be lost. + +In terms of cooperation, particularly in the university setting, BATTIN +also argued the need to avoid going off in a hundred different +directions. The CPA has catalyzed a small group of universities called +the La Guardia Eight--because La Guardia Airport is where meetings take +place--Harvard, Yale, Cornell, Princeton, Penn State, Tennessee, +Stanford, and USC, to develop a digital preservation consortium to look +at all these issues and develop de facto standards as we move along, +instead of waiting for something that is officially blessed. Continuing +to apply analog values and definitions of standards to the digital +environment, BATTIN said, will effectively lead to forfeiture of the +benefits of digital technology to research and scholarship. + +Under the second rubric, the politics of reproduction, BATTIN reiterated +an oft-made argument concerning the electronic library, namely, that it +is more difficult to transform than to create, and nowhere is that belief +expressed more dramatically than in the conversion of brittle books to +new media. Preserving information published in electronic media involves +making sure the information remains accessible and that digital +information is not lost through reproduction. In the analog world of +photocopies and microfilm, the issue of fidelity to the original becomes +paramount, as do issues of "Whose fidelity?" and "Whose original?" + +BATTIN elaborated these arguments with a few examples from a recent study +conducted by the CPA on the problems of preserving text and image. +Discussions with scholars, librarians, and curators in a variety of +disciplines dependent on text and image generated a variety of concerns, +for example: 1) Copy what is, not what the technology is capable of. +This is very important for the history of ideas. Scholars wish to know +what the author saw and worked from. And make available at the +workstation the opportunity to erase all the defects and enhance the +presentation. 2) The fidelity of reproduction--what is good enough, what +can we afford, and the difference it makes--issues of subjective versus +objective resolution. 3) The differences between primary and secondary +users. Restricting the definition of primary user to the one in whose +discipline the material has been published runs one headlong into the +reality that these printed books have had a host of other users from a +host of other disciplines, who not only were looking for very different +things, but who also shared values very different from those of the +primary user. 4) The relationship of the standard of reproduction to new +capabilities of scholarship--the browsing standard versus an archival +standard. How good must the archival standard be? Can a distinction be +drawn between potential users in setting standards for reproduction? +Archival storage, use copies, browsing copies--ought an attempt to set +standards even be made? 5) Finally, costs. How much are we prepared to +pay to capture absolute fidelity? What are the trade-offs between vastly +enhanced access, degrees of fidelity, and costs? + +These standards, BATTIN concluded, serve to complicate further the +reproduction process, and add to the long list of technical standards +that are necessary to ensure widespread access. Ways to articulate and +analyze the costs that are attached to the different levels of standards +must be found. + +Given the chaos concerning standards, which promises to linger for the +foreseeable future, BATTIN urged adoption of the following general +principles: + + * Strive to understand the changing information requirements of + scholarly disciplines as more and more technology is integrated into + the process of research and scholarly communication in order to meet + future scholarly needs, not to build for the past. Capture + deteriorating information at the highest affordable resolution, even + though the dissemination and display technologies will lag. + + * Develop cooperative mechanisms to foster agreement on protocols + for document structure and other interchange mechanisms necessary + for widespread dissemination and use before official standards are + set. + + * Accept that, in a transition period, de facto standards will have + to be developed. + + * Capture information in a way that keeps all options open and + provides for total convertibility: OCR, scanning of microfilm, + producing microfilm from scanned documents, etc. + + * Work closely with the generators of information and the builders + of networks and databases to ensure that continuing accessibility is + a primary concern from the beginning. + + * Piggyback on standards under development for the broad market, and + avoid library-specific standards; work with the vendors, in order to + take advantage of that which is being standardized for the rest of + the world. + + * Concentrate efforts on managing permanence in the digital world, + rather than perfecting the longevity of a particular medium. + + ****** + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +DISCUSSION * Additional comments on TIFF * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +During the brief discussion period that followed BATTIN's presentation, +BARONAS explained that TIFF was not developed in collaboration with or +under the auspices of AIIM. TIFF is a company product, not a standard, +is owned by two corporations, and is always changing. BARONAS also +observed that ANSI/AIIM MS53, a bi-level image file transfer format that +allows unlike systems to exchange images, is compatible with TIFF as well +as with DEC's architecture and IBM's MODCA/IOCA. + + ****** + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +HOOTON * Several questions to be considered in discussing text conversion +* ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +HOOTON introduced the final topic, text conversion, by noting that it is +becoming an increasingly important part of the imaging business. Many +people now realize that it enhances their system to be able to have more +and more character data as part of their imaging system. Re the issue of +OCR versus rekeying, HOOTON posed several questions: How does one get +text into computer-readable form? Does one use automated processes? +Does one attempt to eliminate the use of operators where possible? +Standards for accuracy, he said, are extremely important: it makes a +major difference in cost and time whether one sets as a standard 98.5 +percent acceptance or 99.5 percent. He mentioned outsourcing as a +possibility for converting text. Finally, what one does with the image +to prepare it for the recognition process is also important, he said, +because such preparation changes how recognition is viewed, as well as +facilitates recognition itself. + + ****** + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +LESK * Roles of participants in CORE * Data flow * The scanning process * +The image interface * Results of experiments involving the use of +electronic resources and traditional paper copies * Testing the issue of +serendipity * Conclusions * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Michael LESK, executive director, Computer Science Research, Bell +Communications Research, Inc. (Bellcore), discussed the Chemical Online +Retrieval Experiment (CORE), a cooperative project involving Cornell +University, OCLC, Bellcore, and the American Chemical Society (ACS). + +LESK spoke on 1) how the scanning was performed, including the unusual +feature of page segmentation, and 2) the use made of the text and the +image in experiments. + +Working with the chemistry journals (because ACS has been saving its +typesetting tapes since the mid-1970s and thus has a significant back-run +of the most important chemistry journals in the United States), CORE is +attempting to create an automated chemical library. Approximately a +quarter of the pages by square inch are made up of images of +quasi-pictorial material; dealing with the graphic components of the +pages is extremely important. LESK described the roles of participants +in CORE: 1) ACS provides copyright permission, journals on paper, +journals on microfilm, and some of the definitions of the files; 2) at +Bellcore, LESK chiefly performs the data preparation, while Dennis Egan +performs experiments on the users of chemical abstracts, and supplies the +indexing and numerous magnetic tapes; 3) Cornell provides the site of the +experiment; 4) OCLC develops retrieval software and other user interfaces. +Various manufacturers and publishers have furnished other help. + +Concerning data flow, Bellcore receives microfilm and paper from ACS; the +microfilm is scanned by outside vendors, while the paper is scanned +inhouse on an Improvision scanner, twenty pages per minute at 300 dpi, +which provides sufficient quality for all practical uses. LESK would +prefer to have more gray level, because one of the ACS journals prints on +some colored pages, which creates a problem. + +Bellcore performs all this scanning, creates a page-image file, and also +selects from the pages the graphics, to mix with the text file (which is +discussed later in the Workshop). The user is always searching the ASCII +file, but she or he may see a display based on the ASCII or a display +based on the images. + +LESK illustrated how the program performs page analysis, and the image +interface. (The user types several words, is presented with a list-- +usually of the titles of articles contained in an issue--that derives +from the ASCII, clicks on an icon and receives an image that mirrors an +ACS page.) LESK also illustrated an alternative interface, based on text +on the ASCII, the so-called SuperBook interface from Bellcore. + +LESK next presented the results of an experiment conducted by Dennis Egan +and involving thirty-six students at Cornell, one third of them +undergraduate chemistry majors, one third senior undergraduate chemistry +majors, and one third graduate chemistry students. A third of them +received the paper journals, the traditional paper copies and chemical +abstracts on paper. A third received image displays of the pictures of +the pages, and a third received the text display with pop-up graphics. + +The students were given several questions made up by some chemistry +professors. The questions fell into five classes, ranging from very easy +to very difficult, and included questions designed to simulate browsing +as well as a traditional information retrieval-type task. + +LESK furnished the following results. In the straightforward question +search--the question being, what is the phosphorus oxygen bond distance +and hydroxy phosphate?--the students were told that they could take +fifteen minutes and, then, if they wished, give up. The students with +paper took more than fifteen minutes on average, and yet most of them +gave up. The students with either electronic format, text or image, +received good scores in reasonable time, hardly ever had to give up, and +usually found the right answer. + +In the browsing study, the students were given a list of eight topics, +told to imagine that an issue of the Journal of the American Chemical +Society had just appeared on their desks, and were also told to flip +through it and to find topics mentioned in the issue. The average scores +were about the same. (The students were told to answer yes or no about +whether or not particular topics appeared.) The errors, however, were +quite different. The students with paper rarely said that something +appeared when it had not. But they often failed to find something +actually mentioned in the issue. The computer people found numerous +things, but they also frequently said that a topic was mentioned when it +was not. (The reason, of course, was that they were performing word +searches. They were finding that words were mentioned and they were +concluding that they had accomplished their task.) + +This question also contained a trick to test the issue of serendipity. +The students were given another list of eight topics and instructed, +without taking a second look at the journal, to recall how many of this +new list of eight topics were in this particular issue. This was an +attempt to see if they performed better at remembering what they were not +looking for. They all performed about the same, paper or electronics, +about 62 percent accurate. In short, LESK said, people were not very +good when it came to serendipity, but they were no worse at it with +computers than they were with paper. + +(LESK gave a parenthetical illustration of the learning curve of students +who used SuperBook.) + +The students using the electronic systems started off worse than the ones +using print, but by the third of the three sessions in the series had +caught up to print. As one might expect, electronics provide a much +better means of finding what one wants to read; reading speeds, once the +object of the search has been found, are about the same. + +Almost none of the students could perform the hard task--the analogous +transformation. (It would require the expertise of organic chemists to +complete.) But an interesting result was that the students using the text +search performed terribly, while those using the image system did best. +That the text search system is driven by text offers the explanation. +Everything is focused on the text; to see the pictures, one must press +on an icon. Many students found the right article containing the answer +to the question, but they did not click on the icon to bring up the right +figure and see it. They did not know that they had found the right place, +and thus got it wrong. + +The short answer demonstrated by this experiment was that in the event +one does not know what to read, one needs the electronic systems; the +electronic systems hold no advantage at the moment if one knows what to +read, but neither do they impose a penalty. + +LESK concluded by commenting that, on one hand, the image system was easy +to use. On the other hand, the text display system, which represented +twenty man-years of work in programming and polishing, was not winning, +because the text was not being read, just searched. The much easier +system is highly competitive as well as remarkably effective for the +actual chemists. + + ****** + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +ERWAY * Most challenging aspect of working on AM * Assumptions guiding +AM's approach * Testing different types of service bureaus * AM's +requirement for 99.95 percent accuracy * Requirements for text-coding * +Additional factors influencing AM's approach to coding * Results of AM's +experience with rekeying * Other problems in dealing with service bureaus +* Quality control the most time-consuming aspect of contracting out +conversion * Long-term outlook uncertain * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +To Ricky ERWAY, associate coordinator, American Memory, Library of +Congress, the constant variety of conversion projects taking place +simultaneously represented perhaps the most challenging aspect of working +on AM. Thus, the challenge was not to find a solution for text +conversion but a tool kit of solutions to apply to LC's varied +collections that need to be converted. ERWAY limited her remarks to the +process of converting text to machine-readable form, and the variety of +LC's text collections, for example, bound volumes, microfilm, and +handwritten manuscripts. + +Two assumptions have guided AM's approach, ERWAY said: 1) A desire not +to perform the conversion inhouse. Because of the variety of formats and +types of texts, to capitalize the equipment and have the talents and +skills to operate them at LC would be extremely expensive. Further, the +natural inclination to upgrade to newer and better equipment each year +made it reasonable for AM to focus on what it did best and seek external +conversion services. Using service bureaus also allowed AM to have +several types of operations take place at the same time. 2) AM was not a +technology project, but an effort to improve access to library +collections. Hence, whether text was converted using OCR or rekeying +mattered little to AM. What mattered were cost and accuracy of results. + +AM considered different types of service bureaus and selected three to +perform several small tests in order to acquire a sense of the field. +The sample collections with which they worked included handwritten +correspondence, typewritten manuscripts from the 1940s, and +eighteenth-century printed broadsides on microfilm. On none of these +samples was OCR performed; they were all rekeyed. AM had several special +requirements for the three service bureaus it had engaged. For instance, +any errors in the original text were to be retained. Working from bound +volumes or anything that could not be sheet-fed also constituted a factor +eliminating companies that would have performed OCR. + +AM requires 99.95 percent accuracy, which, though it sounds high, often +means one or two errors per page. The initial batch of test samples +contained several handwritten materials for which AM did not require +text-coding. The results, ERWAY reported, were in all cases fairly +comparable: for the most part, all three service bureaus achieved 99.95 +percent accuracy. AM was satisfied with the work but surprised at the cost. + +As AM began converting whole collections, it retained the requirement for +99.95 percent accuracy and added requirements for text-coding. AM needed +to begin performing work more than three years ago before LC requirements +for SGML applications had been established. Since AM's goal was simply +to retain any of the intellectual content represented by the formatting +of the document (which would be lost if one performed a straight ASCII +conversion), AM used "SGML-like" codes. These codes resembled SGML tags +but were used without the benefit of document-type definitions. AM found +that many service bureaus were not yet SGML-proficient. + +Additional factors influencing the approach AM took with respect to +coding included: 1) the inability of any known microcomputer-based +user-retrieval software to take advantage of SGML coding; and 2) the +multiple inconsistencies in format of the older documents, which +confirmed AM in its desire not to attempt to force the different formats +to conform to a single document-type definition (DTD) and thus create the +need for a separate DTD for each document. + +The five text collections that AM has converted or is in the process of +converting include a collection of eighteenth-century broadsides, a +collection of pamphlets, two typescript document collections, and a +collection of 150 books. + +ERWAY next reviewed the results of AM's experience with rekeying, noting +again that because the bulk of AM's materials are historical, the quality +of the text often does not lend itself to OCR. While non-English +speakers are less likely to guess or elaborate or correct typos in the +original text, they are also less able to infer what we would; they also +are nearly incapable of converting handwritten text. Another +disadvantage of working with overseas keyers is that they are much less +likely to telephone with questions, especially on the coding, with the +result that they develop their own rules as they encounter new +situations. + +Government contracting procedures and time frames posed a major challenge +to performing the conversion. Many service bureaus are not accustomed to +retaining the image, even if they perform OCR. Thus, questions of image +format and storage media were somewhat novel to many of them. ERWAY also +remarked other problems in dealing with service bureaus, for example, +their inability to perform text conversion from the kind of microfilm +that LC uses for preservation purposes. + +But quality control, in ERWAY's experience, was the most time-consuming +aspect of contracting out conversion. AM has been attempting to perform +a 10-percent quality review, looking at either every tenth document or +every tenth page to make certain that the service bureaus are maintaining +99.95 percent accuracy. But even if they are complying with the +requirement for accuracy, finding errors produces a desire to correct +them and, in turn, to clean up the whole collection, which defeats the +purpose to some extent. Even a double entry requires a +character-by-character comparison to the original to meet the accuracy +requirement. LC is not accustomed to publish imperfect texts, which +makes attempting to deal with the industry standard an emotionally +fraught issue for AM. As was mentioned in the previous day's discussion, +going from 99.95 to 99.99 percent accuracy usually doubles costs and +means a third keying or another complete run-through of the text. + +Although AM has learned much from its experiences with various collections +and various service bureaus, ERWAY concluded pessimistically that no +breakthrough has been achieved. Incremental improvements have occurred +in some of the OCR technology, some of the processes, and some of the +standards acceptances, which, though they may lead to somewhat lower costs, +do not offer much encouragement to many people who are anxiously awaiting +the day that the entire contents of LC are available on-line. + + ****** + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +ZIDAR * Several answers to why one attempts to perform full-text +conversion * Per page cost of performing OCR * Typical problems +encountered during editing * Editing poor copy OCR vs. rekeying * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Judith ZIDAR, coordinator, National Agricultural Text Digitizing Program +(NATDP), National Agricultural Library (NAL), offered several answers to +the question of why one attempts to perform full-text conversion: 1) +Text in an image can be read by a human but not by a computer, so of +course it is not searchable and there is not much one can do with it. 2) +Some material simply requires word-level access. For instance, the legal +profession insists on full-text access to its material; with taxonomic or +geographic material, which entails numerous names, one virtually requires +word-level access. 3) Full text permits rapid browsing and searching, +something that cannot be achieved in an image with today's technology. +4) Text stored as ASCII and delivered in ASCII is standardized and highly +portable. 5) People just want full-text searching, even those who do not +know how to do it. NAL, for the most part, is performing OCR at an +actual cost per average-size page of approximately $7. NAL scans the +page to create the electronic image and passes it through the OCR device. + +ZIDAR next rehearsed several typical problems encountered during editing. +Praising the celerity of her student workers, ZIDAR observed that editing +requires approximately five to ten minutes per page, assuming that there +are no large tables to audit. Confusion among the three characters I, 1, +and l, constitutes perhaps the most common problem encountered. Zeroes +and O's also are frequently confused. Double M's create a particular +problem, even on clean pages. They are so wide in most fonts that they +touch, and the system simply cannot tell where one letter ends and the +other begins. Complex page formats occasionally fail to columnate +properly, which entails rescanning as though one were working with a +single column, entering the ASCII, and decolumnating for better +searching. With proportionally spaced text, OCR can have difficulty +discerning what is a space and what are merely spaces between letters, as +opposed to spaces between words, and therefore will merge text or break +up words where it should not. + +ZIDAR said that it can often take longer to edit a poor-copy OCR than to +key it from scratch. NAL has also experimented with partial editing of +text, whereby project workers go into and clean up the format, removing +stray characters but not running a spell-check. NAL corrects typos in +the title and authors' names, which provides a foothold for searching and +browsing. Even extremely poor-quality OCR (e.g., 60-percent accuracy) +can still be searched, because numerous words are correct, while the +important words are probably repeated often enough that they are likely +to be found correct somewhere. Librarians, however, cannot tolerate this +situation, though end users seem more willing to use this text for +searching, provided that NAL indicates that it is unedited. ZIDAR +concluded that rekeying of text may be the best route to take, in spite +of numerous problems with quality control and cost. + + ****** + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +DISCUSSION * Modifying an image before performing OCR * NAL's costs per +page *AM's costs per page and experience with Federal Prison Industries * +Elements comprising NATDP's costs per page * OCR and structured markup * +Distinction between the structure of a document and its representation +when put on the screen or printed * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +HOOTON prefaced the lengthy discussion that followed with several +comments about modifying an image before one reaches the point of +performing OCR. For example, in regard to an application containing a +significant amount of redundant data, such as form-type data, numerous +companies today are working on various kinds of form renewal, prior to +going through a recognition process, by using dropout colors. Thus, +acquiring access to form design or using electronic means are worth +considering. HOOTON also noted that conversion usually makes or breaks +one's imaging system. It is extremely important, extremely costly in +terms of either capital investment or service, and determines the quality +of the remainder of one's system, because it determines the character of +the raw material used by the system. + +Concerning the four projects undertaken by NAL, two inside and two +performed by outside contractors, ZIDAR revealed that an in-house service +bureau executed the first at a cost between $8 and $10 per page for +everything, including building of the database. The project undertaken +by the Consultative Group on International Agricultural Research (CGIAR) +cost approximately $10 per page for the conversion, plus some expenses +for the software and building of the database. The Acid Rain Project--a +two-disk set produced by the University of Vermont, consisting of +Canadian publications on acid rain--cost $6.70 per page for everything, +including keying of the text, which was double keyed, scanning of the +images, and building of the database. The in-house project offered +considerable ease of convenience and greater control of the process. On +the other hand, the service bureaus know their job and perform it +expeditiously, because they have more people. + +As a useful comparison, ERWAY revealed AM's costs as follows: $0.75 +cents to $0.85 cents per thousand characters, with an average page +containing 2,700 characters. Requirements for coding and imaging +increase the costs. Thus, conversion of the text, including the coding, +costs approximately $3 per page. (This figure does not include the +imaging and database-building included in the NAL costs.) AM also +enjoyed a happy experience with Federal Prison Industries, which +precluded the necessity of going through the request-for-proposal process +to award a contract, because it is another government agency. The +prisoners performed AM's rekeying just as well as other service bureaus +and proved handy as well. AM shipped them the books, which they would +photocopy on a book-edge scanner. They would perform the markup on +photocopies, return the books as soon as they were done with them, +perform the keying, and return the material to AM on WORM disks. + +ZIDAR detailed the elements that constitute the previously noted cost of +approximately $7 per page. Most significant is the editing, correction +of errors, and spell-checkings, which though they may sound easy to +perform require, in fact, a great deal of time. Reformatting text also +takes a while, but a significant amount of NAL's expenses are for equipment, +which was extremely expensive when purchased because it was one of the few +systems on the market. The costs of equipment are being amortized over +five years but are still quite high, nearly $2,000 per month. + +HOCKEY raised a general question concerning OCR and the amount of editing +required (substantial in her experience) to generate the kind of +structured markup necessary for manipulating the text on the computer or +loading it into any retrieval system. She wondered if the speakers could +extend the previous question about the cost-benefit of adding or exerting +structured markup. ERWAY noted that several OCR systems retain italics, +bolding, and other spatial formatting. While the material may not be in +the format desired, these systems possess the ability to remove the +original materials quickly from the hands of the people performing the +conversion, as well as to retain that information so that users can work +with it. HOCKEY rejoined that the current thinking on markup is that one +should not say that something is italic or bold so much as why it is that +way. To be sure, one needs to know that something was italicized, but +how can one get from one to the other? One can map from the structure to +the typographic representation. + +FLEISCHHAUER suggested that, given the 100 million items the Library +holds, it may not be possible for LC to do more than report that a thing +was in italics as opposed to why it was italics, although that may be +desirable in some contexts. Promising to talk a bit during the afternoon +session about several experiments OCLC performed on automatic recognition +of document elements, and which they hoped to extend, WEIBEL said that in +fact one can recognize the major elements of a document with a fairly +high degree of reliability, at least as good as OCR. STEVENS drew a +useful distinction between standard, generalized markup (i.e., defining +for a document-type definition the structure of the document), and what +he termed a style sheet, which had to do with italics, bolding, and other +forms of emphasis. Thus, two different components are at work, one being +the structure of the document itself (its logic), and the other being its +representation when it is put on the screen or printed. + + ****** + +SESSION V. APPROACHES TO PREPARING ELECTRONIC TEXTS + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +HOCKEY * Text in ASCII and the representation of electronic text versus +an image * The need to look at ways of using markup to assist retrieval * +The need for an encoding format that will be reusable and multifunctional ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Susan HOCKEY, director, Center for Electronic Texts in the Humanities +(CETH), Rutgers and Princeton Universities, announced that one talk +(WEIBEL's) was moved into this session from the morning and that David +Packard was unable to attend. The session would attempt to focus more on +what one can do with a text in ASCII and the representation of electronic +text rather than just an image, what one can do with a computer that +cannot be done with a book or an image. It would be argued that one can +do much more than just read a text, and from that starting point one can +use markup and methods of preparing the text to take full advantage of +the capability of the computer. That would lead to a discussion of what +the European Community calls REUSABILITY, what may better be termed +DURABILITY, that is, how to prepare or make a text that will last a long +time and that can be used for as many applications as possible, which +would lead to issues of improving intellectual access. + +HOCKEY urged the need to look at ways of using markup to facilitate retrieval, +not just for referencing or to help locate an item that is retrieved, but also to put markup tags in +a text to help retrieve the thing sought either with linguistic tagging or +interpretation. HOCKEY also argued that little advancement had occurred in +the software tools currently available for retrieving and searching text. +She pressed the desideratum of going beyond Boolean searches and performing +more sophisticated searching, which the insertion of more markup in the text +would facilitate. Thinking about electronic texts as opposed to images means +considering material that will never appear in print form, or print will not +be its primary form, that is, material which only appears in electronic form. +HOCKEY alluded to the history and the need for markup and tagging and +electronic text, which was developed through the use of computers in the +humanities; as MICHELSON had observed, Father Busa had started in 1949 +to prepare the first-ever text on the computer. + +HOCKEY remarked several large projects, particularly in Europe, for the +compilation of dictionaries, language studies, and language analysis, in +which people have built up archives of text and have begun to recognize +the need for an encoding format that will be reusable and multifunctional, +that can be used not just to print the text, which may be assumed to be a +byproduct of what one wants to do, but to structure it inside the computer +so that it can be searched, built into a Hypertext system, etc. + + ****** + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +WEIBEL * OCLC's approach to preparing electronic text: retroconversion, +keying of texts, more automated ways of developing data * Project ADAPT +and the CORE Project * Intelligent character recognition does not exist * +Advantages of SGML * Data should be free of procedural markup; +descriptive markup strongly advocated * OCLC's interface illustrated * +Storage requirements and costs for putting a lot of information on line * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Stuart WEIBEL, senior research scientist, Online Computer Library Center, +Inc. (OCLC), described OCLC's approach to preparing electronic text. He +argued that the electronic world into which we are moving must +accommodate not only the future but the past as well, and to some degree +even the present. Thus, starting out at one end with retroconversion and +keying of texts, one would like to move toward much more automated ways +of developing data. + +For example, Project ADAPT had to do with automatically converting +document images into a structured document database with OCR text as +indexing and also a little bit of automatic formatting and tagging of +that text. The CORE project hosted by Cornell University, Bellcore, +OCLC, the American Chemical Society, and Chemical Abstracts, constitutes +WEIBEL's principal concern at the moment. This project is an example of +converting text for which one already has a machine-readable version into +a format more suitable for electronic delivery and database searching. +(Since Michael LESK had previously described CORE, WEIBEL would say +little concerning it.) Borrowing a chemical phrase, de novo synthesis, +WEIBEL cited the Online Journal of Current Clinical Trials as an example +of de novo electronic publishing, that is, a form in which the primary +form of the information is electronic. + +Project ADAPT, then, which OCLC completed a couple of years ago and in +fact is about to resume, is a model in which one takes page images either +in paper or microfilm and converts them automatically to a searchable +electronic database, either on-line or local. The operating assumption +is that accepting some blemishes in the data, especially for +retroconversion of materials, will make it possible to accomplish more. +Not enough money is available to support perfect conversion. + +WEIBEL related several steps taken to perform image preprocessing +(processing on the image before performing optical character +recognition), as well as image postprocessing. He denied the existence +of intelligent character recognition and asserted that what is wanted is +page recognition, which is a long way off. OCLC has experimented with +merging of multiple optical character recognition systems that will +reduce errors from an unacceptable rate of 5 characters out of every +l,000 to an unacceptable rate of 2 characters out of every l,000, but it +is not good enough. It will never be perfect. + +Concerning the CORE Project, WEIBEL observed that Bellcore is taking the +topography files, extracting the page images, and converting those +topography files to SGML markup. LESK hands that data off to OCLC, which +builds that data into a Newton database, the same system that underlies +the on-line system in virtually all of the reference products at OCLC. +The long-term goal is to make the systems interoperable so that not just +Bellcore's system and OCLC's system can access this data, but other +systems can as well, and the key to that is the Z39.50 common command +language and the full-text extension. Z39.50 is fine for MARC records, +but is not enough to do it for full text (that is, make full texts +interoperable). + +WEIBEL next outlined the critical role of SGML for a variety of purposes, +for example, as noted by HOCKEY, in the world of extremely large +databases, using highly structured data to perform field searches. +WEIBEL argued that by building the structure of the data in (i.e., the +structure of the data originally on a printed page), it becomes easy to +look at a journal article even if one cannot read the characters and know +where the title or author is, or what the sections of that document would be. +OCLC wants to make that structure explicit in the database, because it will +be important for retrieval purposes. + +The second big advantage of SGML is that it gives one the ability to +build structure into the database that can be used for display purposes +without contaminating the data with instructions about how to format +things. The distinction lies between procedural markup, which tells one +where to put dots on the page, and descriptive markup, which describes +the elements of a document. + +WEIBEL believes that there should be no procedural markup in the data at +all, that the data should be completely unsullied by information about +italics or boldness. That should be left up to the display device, +whether that display device is a page printer or a screen display device. +By keeping one's database free of that kind of contamination, one can +make decisions down the road, for example, reorganize the data in ways +that are not cramped by built-in notions of what should be italic and +what should be bold. WEIBEL strongly advocated descriptive markup. As +an example, he illustrated the index structure in the CORE data. With +subsequent illustrated examples of markup, WEIBEL acknowledged the common +complaint that SGML is hard to read in its native form, although markup +decreases considerably once one gets into the body. Without the markup, +however, one would not have the structure in the data. One can pass +markup through a LaTeX processor and convert it relatively easily to a +printed version of the document. + +WEIBEL next illustrated an extremely cluttered screen dump of OCLC's +system, in order to show as much as possible the inherent capability on +the screen. (He noted parenthetically that he had become a supporter of +X-Windows as a result of the progress of the CORE Project.) WEIBEL also +illustrated the two major parts of the interface: l) a control box that +allows one to generate lists of items, which resembles a small table of +contents based on key words one wishes to search, and 2) a document +viewer, which is a separate process in and of itself. He demonstrated +how to follow links through the electronic database simply by selecting +the appropriate button and bringing them up. He also noted problems that +remain to be accommodated in the interface (e.g., as pointed out by LESK, +what happens when users do not click on the icon for the figure). + +Given the constraints of time, WEIBEL omitted a large number of ancillary +items in order to say a few words concerning storage requirements and +what will be required to put a lot of things on line. Since it is +extremely expensive to reconvert all of this data, especially if it is +just in paper form (and even if it is in electronic form in typesetting +tapes), he advocated building journals electronically from the start. In +that case, if one only has text graphics and indexing (which is all that +one needs with de novo electronic publishing, because there is no need to +go back and look at bit-maps of pages), one can get 10,000 journals of +full text, or almost 6 million pages per year. These pages can be put in +approximately 135 gigabytes of storage, which is not all that much, +WEIBEL said. For twenty years, something less than three terabytes would +be required. WEIBEL calculated the costs of storing this information as +follows: If a gigabyte costs approximately $1,000, then a terabyte costs +approximately $1 million to buy in terms of hardware. One also needs a +building to put it in and a staff like OCLC to handle that information. +So, to support a terabyte, multiply by five, which gives $5 million per +year for a supported terabyte of data. + + ****** + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +DISCUSSION * Tapes saved by ACS are the typography files originally +supporting publication of the journal * Cost of building tagged text into +the database * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +During the question-and-answer period that followed WEIBEL's +presentation, these clarifications emerged. The tapes saved by the +American Chemical Society are the typography files that originally +supported the publication of the journal. Although they are not tagged +in SGML, they are tagged in very fine detail. Every single sentence is +marked, all the registry numbers, all the publications issues, dates, and +volumes. No cost figures on tagging material on a per-megabyte basis +were available. Because ACS's typesetting system runs from tagged text, +there is no extra cost per article. It was unknown what it costs ACS to +keyboard the tagged text rather than just keyboard the text in the +cheapest process. In other words, since one intends to publish things +and will need to build tagged text into a typography system in any case, +if one does that in such a way that it can drive not only typography but +an electronic system (which is what ACS intends to do--move to SGML +publishing), the marginal cost is zero. The marginal cost represents the +cost of building tagged text into the database, which is small. + + ****** + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +SPERBERG-McQUEEN * Distinction between texts and computers * Implications +of recognizing that all representation is encoding * Dealing with +complicated representations of text entails the need for a grammar of +documents * Variety of forms of formal grammars * Text as a bit-mapped +image does not represent a serious attempt to represent text in +electronic form * SGML, the TEI, document-type declarations, and the +reusability and longevity of data * TEI conformance explicitly allows +extension or modification of the TEI tag set * Administrative background +of the TEI * Several design goals for the TEI tag set * An absolutely +fixed requirement of the TEI Guidelines * Challenges the TEI has +attempted to face * Good texts not beyond economic feasibility * The +issue of reproducibility or processability * The issue of mages as +simulacra for the text redux * One's model of text determines what one's +software can do with a text and has economic consequences * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Prior to speaking about SGML and markup, Michael SPERBERG-McQUEEN, editor, +Text Encoding Initiative (TEI), University of Illinois-Chicago, first drew +a distinction between texts and computers: Texts are abstract cultural +and linguistic objects while computers are complicated physical devices, +he said. Abstract objects cannot be placed inside physical devices; with +computers one can only represent text and act upon those representations. + +The recognition that all representation is encoding, SPERBERG-McQUEEN +argued, leads to the recognition of two things: 1) The topic description +for this session is slightly misleading, because there can be no discussion +of pros and cons of text-coding unless what one means is pros and cons of +working with text with computers. 2) No text can be represented in a +computer without some sort of encoding; images are one way of encoding text, +ASCII is another, SGML yet another. There is no encoding without some +information loss, that is, there is no perfect reproduction of a text that +allows one to do away with the original. Thus, the question becomes, +What is the most useful representation of text for a serious work? +This depends on what kind of serious work one is talking about. + +The projects demonstrated the previous day all involved highly complex +information and fairly complex manipulation of the textual material. +In order to use that complicated information, one has to calculate it +slowly or manually and store the result. It needs to be stored, therefore, +as part of one's representation of the text. Thus, one needs to store the +structure in the text. To deal with complicated representations of text, +one needs somehow to control the complexity of the representation of a text; +that means one needs a way of finding out whether a document and an +electronic representation of a document is legal or not; and that +means one needs a grammar of documents. + +SPERBERG-McQUEEN discussed the variety of forms of formal grammars, +implicit and explicit, as applied to text, and their capabilities. He +argued that these grammars correspond to different models of text that +different developers have. For example, one implicit model of the text +is that there is no internal structure, but just one thing after another, +a few characters and then perhaps a start-title command, and then a few +more characters and an end-title command. SPERBERG-McQUEEN also +distinguished several kinds of text that have a sort of hierarchical +structure that is not very well defined, which, typically, corresponds +to grammars that are not very well defined, as well as hierarchies that +are very well defined (e.g., the Thesaurus Linguae Graecae) and extremely +complicated things such as SGML, which handle strictly hierarchical data +very nicely. + +SPERBERG-McQUEEN conceded that one other model not illustrated on his two +displays was the model of text as a bit-mapped image, an image of a page, +and confessed to having been converted to a limited extent by the +Workshop to the view that electronic images constitute a promising, +probably superior alternative to microfilming. But he was not convinced +that electronic images represent a serious attempt to represent text in +electronic form. Many of their problems stem from the fact that they are +not direct attempts to represent the text but attempts to represent the +page, thus making them representations of representations. + +In this situation of increasingly complicated textual information and the +need to control that complexity in a useful way (which begs the question +of the need for good textual grammars), one has the introduction of SGML. +With SGML, one can develop specific document-type declarations +for specific text types or, as with the TEI, attempts to generate +general document-type declarations that can handle all sorts of text. +The TEI is an attempt to develop formats for text representation that +will ensure the kind of reusability and longevity of data discussed earlier. +It offers a way to stay alive in the state of permanent technological +revolution. + +It has been a continuing challenge in the TEI to create document grammars +that do some work in controlling the complexity of the textual object but +also allowing one to represent the real text that one will find. +Fundamental to the notion of the TEI is that TEI conformance allows one +the ability to extend or modify the TEI tag set so that it fits the text +that one is attempting to represent. + +SPERBERG-McQUEEN next outlined the administrative background of the TEI. +The TEI is an international project to develop and disseminate guidelines +for the encoding and interchange of machine-readable text. It is +sponsored by the Association for Computers in the Humanities, the +Association for Computational Linguistics, and the Association for +Literary and Linguistic Computing. Representatives of numerous other +professional societies sit on its advisory board. The TEI has a number +of affiliated projects that have provided assistance by testing drafts of +the guidelines. + +Among the design goals for the TEI tag set, the scheme first of all must +meet the needs of research, because the TEI came out of the research +community, which did not feel adequately served by existing tag sets. +The tag set must be extensive as well as compatible with existing and +emerging standards. In 1990, version 1.0 of the Guidelines was released +(SPERBERG-McQUEEN illustrated their contents). + +SPERBERG-McQUEEN noted that one problem besetting electronic text has +been the lack of adequate internal or external documentation for many +existing electronic texts. The TEI guidelines as currently formulated +contain few fixed requirements, but one of them is this: There must +always be a document header, an in-file SGML tag that provides +1) a bibliographic description of the electronic object one is talking +about (that is, who included it, when, what for, and under which title); +and 2) the copy text from which it was derived, if any. If there was +no copy text or if the copy text is unknown, then one states as much. +Version 2.0 of the Guidelines was scheduled to be completed in fall 1992 +and a revised third version is to be presented to the TEI advisory board +for its endorsement this coming winter. The TEI itself exists to provide +a markup language, not a marked-up text. + +Among the challenges the TEI has attempted to face is the need for a +markup language that will work for existing projects, that is, handle the +level of markup that people are using now to tag only chapter, section, +and paragraph divisions and not much else. At the same time, such a +language also will be able to scale up gracefully to handle the highly +detailed markup which many people foresee as the future destination of +much electronic text, and which is not the future destination but the +present home of numerous electronic texts in specialized areas. + +SPERBERG-McQUEEN dismissed the lowest-common-denominator approach as +unable to support the kind of applications that draw people who have +never been in the public library regularly before, and make them come +back. He advocated more interesting text and more intelligent text. +Asserting that it is not beyond economic feasibility to have good texts, +SPERBERG-McQUEEN noted that the TEI Guidelines listing 200-odd tags +contains tags that one is expected to enter every time the relevant +textual feature occurs. It contains all the tags that people need now, +and it is not expected that everyone will tag things in the same way. + +The question of how people will tag the text is in large part a function +of their reaction to what SPERBERG-McQUEEN termed the issue of +reproducibility. What one needs to be able to reproduce are the things +one wants to work with. Perhaps a more useful concept than that of +reproducibility or recoverability is that of processability, that is, +what can one get from an electronic text without reading it again +in the original. He illustrated this contention with a page from +Jan Comenius's bilingual Introduction to Latin. + +SPERBERG-McQUEEN returned at length to the issue of images as simulacra +for the text, in order to reiterate his belief that in the long run more +than images of pages of particular editions of the text are needed, +because just as second-generation photocopies and second-generation +microfilm degenerate, so second-generation representations tend to +degenerate, and one tends to overstress some relatively trivial aspects +of the text such as its layout on the page, which is not always +significant, despite what the text critics might say, and slight other +pieces of information such as the very important lexical ties between the +English and Latin versions of Comenius's bilingual text, for example. +Moreover, in many crucial respects it is easy to fool oneself concerning +what a scanned image of the text will accomplish. For example, in order +to study the transmission of texts, information concerning the text +carrier is necessary, which scanned images simply do not always handle. +Further, even the high-quality materials being produced at Cornell use +much of the information that one would need if studying those books as +physical objects. It is a choice that has been made. It is an arguably +justifiable choice, but one does not know what color those pen strokes in +the margin are or whether there was a stain on the page, because it has +been filtered out. One does not know whether there were rips in the page +because they do not show up, and on a couple of the marginal marks one +loses half of the mark because the pen is very light and the scanner +failed to pick it up, and so what is clearly a checkmark in the margin of +the original becomes a little scoop in the margin of the facsimile. +Standard problems for facsimile editions, not new to electronics, but +also true of light-lens photography, and are remarked here because it is +important that we not fool ourselves that even if we produce a very nice +image of this page with good contrast, we are not replacing the +manuscript any more than microfilm has replaced the manuscript. + +The TEI comes from the research community, where its first allegiance +lies, but it is not just an academic exercise. It has relevance far +beyond those who spend all of their time studying text, because one's +model of text determines what one's software can do with a text. Good +models lead to good software. Bad models lead to bad software. That has +economic consequences, and it is these economic consequences that have +led the European Community to help support the TEI, and that will lead, +SPERBERG-McQUEEN hoped, some software vendors to realize that if they +provide software with a better model of the text they can make a killing. + + ****** + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +DISCUSSION * Implications of different DTDs and tag sets * ODA versus SGML * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +During the discussion that followed, several additional points were made. +Neither AAP (i.e., Association of American Publishers) nor CALS (i.e., +Computer-aided Acquisition and Logistics Support) has a document-type +definition for ancient Greek drama, although the TEI will be able to +handle that. Given this state of affairs and assuming that the +technical-journal producers and the commercial vendors decide to use the +other two types, then an institution like the Library of Congress, which +might receive all of their publications, would have to be able to handle +three different types of document definitions and tag sets and be able to +distinguish among them. + +Office Document Architecture (ODA) has some advantages that flow from its +tight focus on office documents and clear directions for implementation. +Much of the ODA standard is easier to read and clearer at first reading +than the SGML standard, which is extremely general. What that means is +that if one wants to use graphics in TIFF and ODA, one is stuck, because +ODA defines graphics formats while TIFF does not, whereas SGML says the +world is not waiting for this work group to create another graphics format. +What is needed is an ability to use whatever graphics format one wants. + +The TEI provides a socket that allows one to connect the SGML document to +the graphics. The notation that the graphics are in is clearly a choice +that one needs to make based on her or his environment, and that is one +advantage. SGML is less megalomaniacal in attempting to define formats +for all kinds of information, though more megalomaniacal in attempting to +cover all sorts of documents. The other advantage is that the model of +text represented by SGML is simply an order of magnitude richer and more +flexible than the model of text offered by ODA. Both offer hierarchical +structures, but SGML recognizes that the hierarchical model of the text +that one is looking at may not have been in the minds of the designers, +whereas ODA does not. + +ODA is not really aiming for the kind of document that the TEI wants to +encompass. The TEI can handle the kind of material ODA has, as well as a +significantly broader range of material. ODA seems to be very much +focused on office documents, which is what it started out being called-- +office document architecture. + + ****** + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +CALALUCA * Text-encoding from a publisher's perspective * +Responsibilities of a publisher * Reproduction of Migne's Latin series +whole and complete with SGML tags based on perceived need and expected +use * Particular decisions arising from the general decision to produce +and publish PLD * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +The final speaker in this session, Eric CALALUCA, vice president, +Chadwyck-Healey, Inc., spoke from the perspective of a publisher re +text-encoding, rather than as one qualified to discuss methods of +encoding data, and observed that the presenters sitting in the room, +whether they had chosen to or not, were acting as publishers: making +choices, gathering data, gathering information, and making assessments. +CALALUCA offered the hard-won conviction that in publishing very large +text files (such as PLD), one cannot avoid making personal judgments of +appropriateness and structure. + +In CALALUCA's view, encoding decisions stem from prior judgments. Two +notions have become axioms for him in the consideration of future sources +for electronic publication: 1) electronic text publishing is as personal +as any other kind of publishing, and questions of if and how to encode +the data are simply a consequence of that prior decision; 2) all +personal decisions are open to criticism, which is unavoidable. + +CALALUCA rehearsed his role as a publisher or, better, as an intermediary +between what is viewed as a sound idea and the people who would make use +of it. Finding the specialist to advise in this process is the core of +that function. The publisher must monitor and hug the fine line between +giving users what they want and suggesting what they might need. One +responsibility of a publisher is to represent the desires of scholars and +research librarians as opposed to bullheadedly forcing them into areas +they would not choose to enter. + +CALALUCA likened the questions being raised today about data structure +and standards to the decisions faced by the Abbe Migne himself during +production of the Patrologia series in the mid-nineteenth century. +Chadwyck-Healey's decision to reproduce Migne's Latin series whole and +complete with SGML tags was also based upon a perceived need and an +expected use. In the same way that Migne's work came to be far more than +a simple handbook for clerics, PLD is already far more than a database +for theologians. It is a bedrock source for the study of Western +civilization, CALALUCA asserted. + +In regard to the decision to produce and publish PLD, the editorial board +offered direct judgments on the question of appropriateness of these +texts for conversion, their encoding and their distribution, and +concluded that the best possible project was one that avoided overt +intrusions or exclusions in so important a resource. Thus, the general +decision to transmit the original collection as clearly as possible with +the widest possible avenues for use led to other decisions: 1) To encode +the data or not, SGML or not, TEI or not. Again, the expected user +community asserted the need for normative tagging structures of important +humanities texts, and the TEI seemed the most appropriate structure for +that purpose. Research librarians, who are trained to view the larger +impact of electronic text sources on 80 or 90 or 100 doctoral +disciplines, loudly approved the decision to include tagging. They see +what is coming better than the specialist who is completely focused on +one edition of Ambrose's De Anima, and they also understand that the +potential uses exceed present expectations. 2) What will be tagged and +what will not. Once again, the board realized that one must tag the +obvious. But in no way should one attempt to identify through encoding +schemes every single discrete area of a text that might someday be +searched. That was another decision. Searching by a column number, an +author, a word, a volume, permitting combination searches, and tagging +notations seemed logical choices as core elements. 3) How does one make +the data available? Tieing it to a CD-ROM edition creates limitations, +but a magnetic tape file that is very large, is accompanied by the +encoding specifications, and that allows one to make local modifications +also allows one to incorporate any changes one may desire within the +bounds of private research, though exporting tag files from a CD-ROM +could serve just as well. Since no one on the board could possibly +anticipate each and every way in which a scholar might choose to mine +this data bank, it was decided to satisfy the basics and make some +provisions for what might come. 4) Not to encode the database would rob +it of the interchangeability and portability these important texts should +accommodate. For CALALUCA, the extensive options presented by full-text +searching require care in text selection and strongly support encoding of +data to facilitate the widest possible search strategies. Better +software can always be created, but summoning the resources, the people, +and the energy to reconvert the text is another matter. + +PLD is being encoded, captured, and distributed, because to +Chadwyck-Healey and the board it offers the widest possible array of +future research applications that can be seen today. CALALUCA concluded +by urging the encoding of all important text sources in whatever way +seems most appropriate and durable at the time, without blanching at the +thought that one's work may require emendation in the future. (Thus, +Chadwyck-Healey produced a very large humanities text database before the +final release of the TEI Guidelines.) + + ****** + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +DISCUSSION * Creating texts with markup advocated * Trends in encoding * +The TEI and the issue of interchangeability of standards * A +misconception concerning the TEI * Implications for an institution like +LC in the event that a multiplicity of DTDs develops * Producing images +as a first step towards possible conversion to full text through +character recognition * The AAP tag sets as a common starting point and +the need for caution * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +HOCKEY prefaced the discussion that followed with several comments in +favor of creating texts with markup and on trends in encoding. In the +future, when many more texts are available for on-line searching, real +problems in finding what is wanted will develop, if one is faced with +millions of words of data. It therefore becomes important to consider +putting markup in texts to help searchers home in on the actual things +they wish to retrieve. Various approaches to refining retrieval methods +toward this end include building on a computer version of a dictionary +and letting the computer look up words in it to obtain more information +about the semantic structure or semantic field of a word, its grammatical +structure, and syntactic structure. + +HOCKEY commented on the present keen interest in the encoding world +in creating: 1) machine-readable versions of dictionaries that can be +initially tagged in SGML, which gives a structure to the dictionary entry; +these entries can then be converted into a more rigid or otherwise +different database structure inside the computer, which can be treated as +a dynamic tool for searching mechanisms; 2) large bodies of text to study +the language. In order to incorporate more sophisticated mechanisms, +more about how words behave needs to be known, which can be learned in +part from information in dictionaries. However, the last ten years have +seen much interest in studying the structure of printed dictionaries +converted into computer-readable form. The information one derives about +many words from those is only partial, one or two definitions of the +common or the usual meaning of a word, and then numerous definitions of +unusual usages. If the computer is using a dictionary to help retrieve +words in a text, it needs much more information about the common usages, +because those are the ones that occur over and over again. Hence the +current interest in developing large bodies of text in computer-readable +form in order to study the language. Several projects are engaged in +compiling, for example, 100 million words. HOCKEY described one with +which she was associated briefly at Oxford University involving +compilation of 100 million words of British English: about 10 percent of +that will contain detailed linguistic tagging encoded in SGML; it will +have word class taggings, with words identified as nouns, verbs, +adjectives, or other parts of speech. This tagging can then be used by +programs which will begin to learn a bit more about the structure of the +language, and then, can go to tag more text. + +HOCKEY said that the more that is tagged accurately, the more one can +refine the tagging process and thus the bigger body of text one can build +up with linguistic tagging incorporated into it. Hence, the more tagging +or annotation there is in the text, the more one may begin to learn about +language and the more it will help accomplish more intelligent OCR. She +recommended the development of software tools that will help one begin to +understand more about a text, which can then be applied to scanning +images of that text in that format and to using more intelligence to help +one interpret or understand the text. + +HOCKEY posited the need to think about common methods of text-encoding +for a long time to come, because building these large bodies of text is +extremely expensive and will only be done once. + +In the more general discussion on approaches to encoding that followed, +these points were made: + +BESSER identified the underlying problem with standards that all have to +struggle with in adopting a standard, namely, the tension between a very +highly defined standard that is very interchangeable but does not work +for everyone because something is lacking, and a standard that is less +defined, more open, more adaptable, but less interchangeable. Contending +that the way in which people use SGML is not sufficiently defined, BESSER +wondered 1) if people resist the TEI because they think it is too defined +in certain things they do not fit into, and 2) how progress with +interchangeability can be made without frightening people away. + +SPERBERG-McQUEEN replied that the published drafts of the TEI had met +with surprisingly little objection on the grounds that they do not allow +one to handle X or Y or Z. Particular concerns of the affiliated +projects have led, in practice, to discussions of how extensions are to +be made; the primary concern of any project has to be how it can be +represented locally, thus making interchange secondary. The TEI has +received much criticism based on the notion that everything in it is +required or even recommended, which, as it happens, is a misconception +from the beginning, because none of it is required and very little is +actually actively recommended for all cases, except that one document +one's source. + +SPERBERG-McQUEEN agreed with BESSER about this trade-off: all the +projects in a set of twenty TEI-conformant projects will not necessarily +tag the material in the same way. One result of the TEI will be that the +easiest problems will be solved--those dealing with the external form of +the information; but the problem that is hardest in interchange is that +one is not encoding what another wants, and vice versa. Thus, after +the adoption of a common notation, the differences in the underlying +conceptions of what is interesting about texts become more visible. +The success of a standard like the TEI will lie in the ability of +the recipient of interchanged texts to use some of what it contains +and to add the information that was not encoded that one wants, in a +layered way, so that texts can be gradually enriched and one does not +have to put in everything all at once. Hence, having a well-behaved +markup scheme is important. + +STEVENS followed up on the paradoxical analogy that BESSER alluded to in +the example of the MARC records, namely, the formats that are the same +except that they are different. STEVENS drew a parallel between +document-type definitions and MARC records for books and serials and maps, +where one has a tagging structure and there is a text-interchange. +STEVENS opined that the producers of the information will set the terms +for the standard (i.e., develop document-type definitions for the users +of their products), creating a situation that will be problematical for +an institution like the Library of Congress, which will have to deal with +the DTDs in the event that a multiplicity of them develops. Thus, +numerous people are seeking a standard but cannot find the tag set that +will be acceptable to them and their clients. SPERBERG-McQUEEN agreed +with this view, and said that the situation was in a way worse: attempting +to unify arbitrary DTDs resembled attempting to unify a MARC record with a +bibliographic record done according to the Prussian instructions. +According to STEVENS, this situation occurred very early in the process. + +WATERS recalled from early discussions on Project Open Book the concern +of many people that merely by producing images, POB was not really +enhancing intellectual access to the material. Nevertheless, not wishing +to overemphasize the opposition between imaging and full text, WATERS +stated that POB views getting the images as a first step toward possibly +converting to full text through character recognition, if the technology +is appropriate. WATERS also emphasized that encoding is involved even +with a set of images. + +SPERBERG-McQUEEN agreed with WATERS that one can create an SGML document +consisting wholly of images. At first sight, organizing graphic images +with an SGML document may not seem to offer great advantages, but the +advantages of the scheme WATERS described would be precisely that +ability to move into something that is more of a multimedia document: +a combination of transcribed text and page images. WEIBEL concurred in +this judgment, offering evidence from Project ADAPT, where a page is +divided into text elements and graphic elements, and in fact the text +elements are organized by columns and lines. These lines may be used as +the basis for distributing documents in a network environment. As one +develops software intelligent enough to recognize what those elements +are, it makes sense to apply SGML to an image initially, that may, in +fact, ultimately become more and more text, either through OCR or edited +OCR or even just through keying. For WATERS, the labor of composing the +document and saying this set of documents or this set of images belongs +to this document constitutes a significant investment. + +WEIBEL also made the point that the AAP tag sets, while not excessively +prescriptive, offer a common starting point; they do not define the +structure of the documents, though. They have some recommendations about +DTDs one could use as examples, but they do just suggest tag sets. For +example, the CORE project attempts to use the AAP markup as much as +possible, but there are clearly areas where structure must be added. +That in no way contradicts the use of AAP tag sets. + +SPERBERG-McQUEEN noted that the TEI prepared a long working paper early +on about the AAP tag set and what it lacked that the TEI thought it +needed, and a fairly long critique of the naming conventions, which has +led to a very different style of naming in the TEI. He stressed the +importance of the opposition between prescriptive markup, the kind that a +publisher or anybody can do when producing documents de novo, and +descriptive markup, in which one has to take what the text carrier +provides. In these particular tag sets it is easy to overemphasize this +opposition, because the AAP tag set is extremely flexible. Even if one +just used the DTDs, they allow almost anything to appear almost anywhere. + + ****** + +SESSION VI. COPYRIGHT ISSUES + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +PETERS * Several cautions concerning copyright in an electronic +environment * Review of copyright law in the United States * The notion +of the public good and the desirability of incentives to promote it * +What copyright protects * Works not protected by copyright * The rights +of copyright holders * Publishers' concerns in today's electronic +environment * Compulsory licenses * The price of copyright in a digital +medium and the need for cooperation * Additional clarifications * Rough +justice oftentimes the outcome in numerous copyright matters * Copyright +in an electronic society * Copyright law always only sets up the +boundaries; anything can be changed by contract * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Marybeth PETERS, policy planning adviser to the Register of Copyrights, +Library of Congress, made several general comments and then opened the +floor to discussion of subjects of interest to the audience. + +Having attended several sessions in an effort to gain a sense of what +people did and where copyright would affect their lives, PETERS expressed +the following cautions: + + * If one takes and converts materials and puts them in new forms, + then, from a copyright point of view, one is creating something and + will receive some rights. + + * However, if what one is converting already exists, a question + immediately arises about the status of the materials in question. + + * Putting something in the public domain in the United States offers + some freedom from anxiety, but distributing it throughout the world + on a network is another matter, even if one has put it in the public + domain in the United States. Re foreign laws, very frequently a + work can be in the public domain in the United States but protected + in other countries. Thus, one must consider all of the places a + work may reach, lest one unwittingly become liable to being faced + with a suit for copyright infringement, or at least a letter + demanding discussion of what one is doing. + +PETERS reviewed copyright law in the United States. The U.S. +Constitution effectively states that Congress has the power to enact +copyright laws for two purposes: 1) to encourage the creation and +dissemination of intellectual works for the good of society as a whole; +and, significantly, 2) to give creators and those who package and +disseminate materials the economic rewards that are due them. + +Congress strives to strike a balance, which at times can become an +emotional issue. The United States has never accepted the notion of the +natural right of an author so much as it has accepted the notion of the +public good and the desirability of incentives to promote it. This state +of affairs, however, has created strains on the international level and +is the reason for several of the differences in the laws that we have. +Today the United States protects almost every kind of work that can be +called an expression of an author. The standard for gaining copyright +protection is simply originality. This is a low standard and means that +a work is not copied from something else, as well as shows a certain +minimal amount of authorship. One can also acquire copyright protection +for making a new version of preexisting material, provided it manifests +some spark of creativity. + +However, copyright does not protect ideas, methods, systems--only the way +that one expresses those things. Nor does copyright protect anything +that is mechanical, anything that does not involve choice, or criteria +concerning whether or not one should do a thing. For example, the +results of a process called declicking, in which one mechanically removes +impure sounds from old recordings, are not copyrightable. On the other +hand, the choice to record a song digitally and to increase the sound of +violins or to bring up the tympani constitutes the results of conversion +that are copyrightable. Moreover, if a work is protected by copyright in +the United States, one generally needs the permission of the copyright +owner to convert it. Normally, who will own the new--that is, converted- +-material is a matter of contract. In the absence of a contract, the +person who creates the new material is the author and owner. But people +do not generally think about the copyright implications until after the +fact. PETERS stressed the need when dealing with copyrighted works to +think about copyright in advance. One's bargaining power is much greater +up front than it is down the road. + +PETERS next discussed works not protected by copyright, for example, any +work done by a federal employee as part of his or her official duties is +in the public domain in the United States. The issue is not wholly free +of doubt concerning whether or not the work is in the public domain +outside the United States. Other materials in the public domain include: +any works published more than seventy-five years ago, and any work +published in the United States more than twenty-eight years ago, whose +copyright was not renewed. In talking about the new technology and +putting material in a digital form to send all over the world, PETERS +cautioned, one must keep in mind that while the rights may not be an +issue in the United States, they may be in different parts of the world, +where most countries previously employed a copyright term of the life of +the author plus fifty years. + +PETERS next reviewed the economics of copyright holding. Simply, +economic rights are the rights to control the reproduction of a work in +any form. They belong to the author, or in the case of a work made for +hire, the employer. The second right, which is critical to conversion, +is the right to change a work. The right to make new versions is perhaps +one of the most significant rights of authors, particularly in an +electronic world. The third right is the right to publish the work and +the right to disseminate it, something that everyone who deals in an +electronic medium needs to know. The basic rule is if a copy is sold, +all rights of distribution are extinguished with the sale of that copy. +The key is that it must be sold. A number of companies overcome this +obstacle by leasing or renting their product. These companies argue that +if the material is rented or leased and not sold, they control the uses +of a work. The fourth right, and one very important in a digital world, +is a right of public performance, which means the right to show the work +sequentially. For example, copyright owners control the showing of a +CD-ROM product in a public place such as a public library. The reverse +side of public performance is something called the right of public +display. Moral rights also exist, which at the federal level apply only +to very limited visual works of art, but in theory may apply under +contract and other principles. Moral rights may include the right of an +author to have his or her name on a work, the right of attribution, and +the right to object to distortion or mutilation--the right of integrity. + +The way copyright law is worded gives much latitude to activities such as +preservation; to use of material for scholarly and research purposes when +the user does not make multiple copies; and to the generation of +facsimile copies of unpublished works by libraries for themselves and +other libraries. But the law does not allow anyone to become the +distributor of the product for the entire world. In today's electronic +environment, publishers are extremely concerned that the entire world is +networked and can obtain the information desired from a single copy in a +single library. Hence, if there is to be only one sale, which publishers +may choose to live with, they will obtain their money in other ways, for +example, from access and use. Hence, the development of site licenses +and other kinds of agreements to cover what publishers believe they +should be compensated for. Any solution that the United States takes +today has to consider the international arena. + +Noting that the United States is a member of the Berne Convention and +subscribes to its provisions, PETERS described the permissions process. +She also defined compulsory licenses. A compulsory license, of which the +United States has had a few, builds into the law the right to use a work +subject to certain terms and conditions. In the international arena, +however, the ability to use compulsory licenses is extremely limited. +Thus, clearinghouses and other collectives comprise one option that has +succeeded in providing for use of a work. Often overlooked when one +begins to use copyrighted material and put products together is how +expensive the permissions process and managing it is. According to +PETERS, the price of copyright in a digital medium, whatever solution is +worked out, will include managing and assembling the database. She +strongly recommended that publishers and librarians or people with +various backgrounds cooperate to work out administratively feasible +systems, in order to produce better results. + +In the lengthy question-and-answer period that followed PETERS's +presentation, the following points emerged: + + * The Copyright Office maintains that anything mechanical and + totally exhaustive probably is not protected. In the event that + what an individual did in developing potentially copyrightable + material is not understood, the Copyright Office will ask about the + creative choices the applicant chose to make or not to make. As a + practical matter, if one believes she or he has made enough of those + choices, that person has a right to assert a copyright and someone + else must assert that the work is not copyrightable. The more + mechanical, the more automatic, a thing is, the less likely it is to + be copyrightable. + + * Nearly all photographs are deemed to be copyrightable, but no one + worries about them much, because everyone is free to take the same + image. Thus, a photographic copyright represents what is called a + "thin" copyright. The photograph itself must be duplicated, in + order for copyright to be violated. + + * The Copyright Office takes the position that X-rays are not + copyrightable because they are mechanical. It can be argued + whether or not image enhancement in scanning can be protected. One + must exercise care with material created with public funds and + generally in the public domain. An article written by a federal + employee, if written as part of official duties, is not + copyrightable. However, control over a scientific article written + by a National Institutes of Health grantee (i.e., someone who + receives money from the U.S. government), depends on NIH policy. If + the government agency has no policy (and that policy can be + contained in its regulations, the contract, or the grant), the + author retains copyright. If a provision of the contract, grant, or + regulation states that there will be no copyright, then it does not + exist. When a work is created, copyright automatically comes into + existence unless something exists that says it does not. + + * An enhanced electronic copy of a print copy of an older reference + work in the public domain that does not contain copyrightable new + material is a purely mechanical rendition of the original work, and + is not copyrightable. + + * Usually, when a work enters the public domain, nothing can remove + it. For example, Congress recently passed into law the concept of + automatic renewal, which means that copyright on any work published + between l964 and l978 does not have to be renewed in order to + receive a seventy-five-year term. But any work not renewed before + 1964 is in the public domain. + + * Concerning whether or not the United States keeps track of when + authors die, nothing was ever done, nor is anything being done at + the moment by the Copyright Office. + + * Software that drives a mechanical process is itself copyrightable. + If one changes platforms, the software itself has a copyright. The + World Intellectual Property Organization will hold a symposium 28 + March through 2 April l993, at Harvard University, on digital + technology, and will study this entire issue. If one purchases a + computer software package, such as MacPaint, and creates something + new, one receives protection only for that which has been added. + +PETERS added that often in copyright matters, rough justice is the +outcome, for example, in collective licensing, ASCAP (i.e., American +Society of Composers, Authors, and Publishers), and BMI (i.e., Broadcast +Music, Inc.), where it may seem that the big guys receive more than their +due. Of course, people ought not to copy a creative product without +paying for it; there should be some compensation. But the truth of the +world, and it is not a great truth, is that the big guy gets played on +the radio more frequently than the little guy, who has to do much more +until he becomes a big guy. That is true of every author, every +composer, everyone, and, unfortunately, is part of life. + +Copyright always originates with the author, except in cases of works +made for hire. (Most software falls into this category.) When an author +sends his article to a journal, he has not relinquished copyright, though +he retains the right to relinquish it. The author receives absolutely +everything. The less prominent the author, the more leverage the +publisher will have in contract negotiations. In order to transfer the +rights, the author must sign an agreement giving them away. + +In an electronic society, it is important to be able to license a writer +and work out deals. With regard to use of a work, it usually is much +easier when a publisher holds the rights. In an electronic era, a real +problem arises when one is digitizing and making information available. +PETERS referred again to electronic licensing clearinghouses. Copyright +ought to remain with the author, but as one moves forward globally in the +electronic arena, a middleman who can handle the various rights becomes +increasingly necessary. + +The notion of copyright law is that it resides with the individual, but +in an on-line environment, where a work can be adapted and tinkered with +by many individuals, there is concern. If changes are authorized and +there is no agreement to the contrary, the person who changes a work owns +the changes. To put it another way, the person who acquires permission +to change a work technically will become the author and the owner, unless +some agreement to the contrary has been made. It is typical for the +original publisher to try to control all of the versions and all of the +uses. Copyright law always only sets up the boundaries. Anything can be +changed by contract. + + ****** + +SESSION VII. CONCLUSION + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +GENERAL DISCUSSION * Two questions for discussion * Different emphases in +the Workshop * Bringing the text and image partisans together * +Desiderata in planning the long-term development of something * Questions +surrounding the issue of electronic deposit * Discussion of electronic +deposit as an allusion to the issue of standards * Need for a directory +of preservation projects in digital form and for access to their +digitized files * CETH's catalogue of machine-readable texts in the +humanities * What constitutes a publication in the electronic world? * +Need for LC to deal with the concept of on-line publishing * LC's Network +Development Office exploring the limits of MARC as a standard in terms +of handling electronic information * Magnitude of the problem and the +need for distributed responsibility in order to maintain and store +electronic information * Workshop participants to be viewed as a starting +point * Development of a network version of AM urged * A step toward AM's +construction of some sort of apparatus for network access * A delicate +and agonizing policy question for LC * Re the issue of electronic +deposit, LC urged to initiate a catalytic process in terms of distributed +responsibility * Suggestions for cooperative ventures * Commercial +publishers' fears * Strategic questions for getting the image and text +people to think through long-term cooperation * Clarification of the +driving force behind both the Perseus and the Cornell Xerox projects * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +In his role as moderator of the concluding session, GIFFORD raised two +questions he believed would benefit from discussion: 1) Are there enough +commonalities among those of us that have been here for two days so that +we can see courses of action that should be taken in the future? And, if +so, what are they and who might take them? 2) Partly derivative from +that, but obviously very dangerous to LC as host, do you see a role for +the Library of Congress in all this? Of course, the Library of Congress +holds a rather special status in a number of these matters, because it is +not perceived as a player with an economic stake in them, but are there +roles that LC can play that can help advance us toward where we are heading? + +Describing himself as an uninformed observer of the technicalities of the +last two days, GIFFORD detected three different emphases in the Workshop: +1) people who are very deeply committed to text; 2) people who are almost +passionate about images; and 3) a few people who are very committed to +what happens to the networks. In other words, the new networking +dimension, the accessibility of the processability, the portability of +all this across the networks. How do we pull those three together? + +Adding a question that reflected HOCKEY's comment that this was the +fourth workshop she had attended in the previous thirty days, FLEISCHHAUER +wondered to what extent this meeting had reinvented the wheel, or if it +had contributed anything in the way of bringing together a different group +of people from those who normally appear on the workshop circuit. + +HOCKEY confessed to being struck at this meeting and the one the +Electronic Pierce Consortium organized the previous week that this was a +coming together of people working on texts and not images. Attempting to +bring the two together is something we ought to be thinking about for the +future: How one can think about working with image material to begin +with, but structuring it and digitizing it in such a way that at a later +stage it can be interpreted into text, and find a common way of building +text and images together so that they can be used jointly in the future, +with the network support to begin there because that is how people will +want to access it. + +In planning the long-term development of something, which is what is +being done in electronic text, HOCKEY stressed the importance not only +of discussing the technical aspects of how one does it but particularly +of thinking about what the people who use the stuff will want to do. +But conversely, there are numerous things that people start to do with +electronic text or material that nobody ever thought of in the beginning. + +LESK, in response to the question concerning the role of the Library of +Congress, remarked the often suggested desideratum of having electronic +deposit: Since everything is now computer-typeset, an entire decade of +material that was machine-readable exists, but the publishers frequently +did not save it; has LC taken any action to have its copyright deposit +operation start collecting these machine-readable versions? In the +absence of PETERS, GIFFORD replied that the question was being +actively considered but that that was only one dimension of the problem. +Another dimension is the whole question of the integrity of the original +electronic document. It becomes highly important in science to prove +authorship. How will that be done? + +ERWAY explained that, under the old policy, to make a claim for a +copyright for works that were published in electronic form, including +software, one had to submit a paper copy of the first and last twenty +pages of code--something that represented the work but did not include +the entire work itself and had little value to anyone. As a temporary +measure, LC has claimed the right to demand electronic versions of +electronic publications. This measure entails a proactive role for the +Library to say that it wants a particular electronic version. Publishers +then have perhaps a year to submit it. But the real problem for LC is +what to do with all this material in all these different formats. Will +the Library mount it? How will it give people access to it? How does LC +keep track of the appropriate computers, software, and media? The situation +is so hard to control, ERWAY said, that it makes sense for each publishing +house to maintain its own archive. But LC cannot enforce that either. + +GIFFORD acknowledged LESK's suggestion that establishing a priority +offered the solution, albeit a fairly complicated one. But who maintains +that register?, he asked. GRABER noted that LC does attempt to collect a +Macintosh version and the IBM-compatible version of software. It does +not collect other versions. But while true for software, BYRUM observed, +this reply does not speak to materials, that is, all the materials that +were published that were on somebody's microcomputer or driver tapes +at a publishing office across the country. LC does well to acquire +specific machine-readable products selectively that were intended to be +machine-readable. Materials that were in machine-readable form at one time, +BYRUM said, would be beyond LC's capability at the moment, insofar as +attempting to acquire, organize, and preserve them are concerned--and +preservation would be the most important consideration. In this +connection, GIFFORD reiterated the need to work out some sense of +distributive responsibility for a number of these issues, which +inevitably will require significant cooperation and discussion. +Nobody can do it all. + +LESK suggested that some publishers may look with favor on LC beginning +to serve as a depository of tapes in an electronic manuscript standard. +Publishers may view this as a service that they did not have to perform +and they might send in tapes. However, SPERBERG-McQUEEN countered, +although publishers have had equivalent services available to them for a +long time, the electronic text archive has never turned away or been +flooded with tapes and is forever sending feedback to the depositor. +Some publishers do send in tapes. + +ANDRE viewed this discussion as an allusion to the issue of standards. +She recommended that the AAP standard and the TEI, which has already been +somewhat harmonized internationally and which also shares several +compatibilities with the AAP, be harmonized to ensure sufficient +compatibility in the software. She drew the line at saying LC ought to +be the locus or forum for such harmonization. + +Taking the group in a slightly different direction, but one where at +least in the near term LC might play a helpful role, LYNCH remarked the +plans of a number of projects to carry out preservation by creating +digital images that will end up in on-line or near-line storage at some +institution. Presumably, LC will link this material somehow to its +on-line catalog in most cases. Thus, it is in a digital form. LYNCH had +the impression that many of these institutions would be willing to make +those files accessible to other people outside the institution, provided +that there is no copyright problem. This desideratum will require +propagating the knowledge that those digitized files exist, so that they +can end up in other on-line catalogs. Although uncertain about the +mechanism for achieving this result, LYNCH said that it warranted +scrutiny because it seemed to be connected to some of the basic issues of +cataloging and distribution of records. It would be foolish, given the +amount of work that all of us have to do and our meager resources, to +discover multiple institutions digitizing the same work. Re microforms, +LYNCH said, we are in pretty good shape. + +BATTIN called this a big problem and noted that the Cornell people (who +had already departed) were working on it. At issue from the beginning +was to learn how to catalog that information into RLIN and then into +OCLC, so that it would be accessible. That issue remains to be resolved. +LYNCH rejoined that putting it into OCLC or RLIN was helpful insofar as +somebody who is thinking of performing preservation activity on that work +could learn about it. It is not necessarily helpful for institutions to +make that available. BATTIN opined that the idea was that it not only be +for preservation purposes but for the convenience of people looking for +this material. She endorsed LYNCH's dictum that duplication of this +effort was to be avoided by every means. + +HOCKEY informed the Workshop about one major current activity of CETH, +namely a catalogue of machine-readable texts in the humanities. Held on +RLIN at present, the catalogue has been concentrated on ASCII as opposed +to digitized images of text. She is exploring ways to improve the +catalogue and make it more widely available, and welcomed suggestions +about these concerns. CETH owns the records, which are not just +restricted to RLIN, and can distribute them however it wishes. + +Taking up LESK's earlier question, BATTIN inquired whether LC, since it +is accepting electronic files and designing a mechanism for dealing with +that rather than putting books on shelves, would become responsible for +the National Copyright Depository of Electronic Materials. Of course +that could not be accomplished overnight, but it would be something LC +could plan for. GIFFORD acknowledged that much thought was being devoted +to that set of problems and returned the discussion to the issue raised +by LYNCH--whether or not putting the kind of records that both BATTIN and +HOCKEY have been talking about in RLIN is not a satisfactory solution. +It seemed to him that RLIN answered LYNCH's original point concerning +some kind of directory for these kinds of materials. In a situation +where somebody is attempting to decide whether or not to scan this or +film that or to learn whether or not someone has already done so, LYNCH +suggested, RLIN is helpful, but it is not helpful in the case of a local, +on-line catalogue. Further, one would like to have her or his system be +aware that that exists in digital form, so that one can present it to a +patron, even though one did not digitize it, if it is out of copyright. +The only way to make those linkages would be to perform a tremendous +amount of real-time look-up, which would be awkward at best, or +periodically to yank the whole file from RLIN and match it against one's +own stuff, which is a nuisance. + +But where, ERWAY inquired, does one stop including things that are +available with Internet, for instance, in one's local catalogue? +It almost seems that that is LC's means to acquire access to them. +That represents LC's new form of library loan. Perhaps LC's new on-line +catalogue is an amalgamation of all these catalogues on line. LYNCH +conceded that perhaps that was true in the very long term, but was not +applicable to scanning in the short term. In his view, the totals cited +by Yale, 10,000 books over perhaps a four-year period, and 1,000-1,500 +books from Cornell, were not big numbers, while searching all over +creation for relatively rare occurrences will prove to be less efficient. +As GIFFORD wondered if this would not be a separable file on RLIN and +could be requested from them, BATTIN interjected that it was easily +accessible to an institution. SEVERTSON pointed out that that file, cum +enhancements, was available with reference information on CD-ROM, which +makes it a little more available. + +In HOCKEY's view, the real question facing the Workshop is what to put in +this catalogue, because that raises the question of what constitutes a +publication in the electronic world. (WEIBEL interjected that Eric Joule +in OCLC's Office of Research is also wrestling with this particular +problem, while GIFFORD thought it sounded fairly generic.) HOCKEY +contended that a majority of texts in the humanities are in the hands +of either a small number of large research institutions or individuals +and are not generally available for anyone else to access at all. +She wondered if these texts ought to be catalogued. + +After argument proceeded back and forth for several minutes over why +cataloguing might be a necessary service, LEBRON suggested that this +issue involved the responsibility of a publisher. The fact that someone +has created something electronically and keeps it under his or her +control does not constitute publication. Publication implies +dissemination. While it would be important for a scholar to let other +people know that this creation exists, in many respects this is no +different from an unpublished manuscript. That is what is being accessed +in there, except that now one is not looking at it in the hard-copy but +in the electronic environment. + +LEBRON expressed puzzlement at the variety of ways electronic publishing +has been viewed. Much of what has been discussed throughout these two +days has concerned CD-ROM publishing, whereas in the on-line environment +that she confronts, the constraints and challenges are very different. +Sooner or later LC will have to deal with the concept of on-line +publishing. Taking up the comment ERWAY made earlier about storing +copies, LEBRON gave her own journal as an example. How would she deposit +OJCCT for copyright?, she asked, because the journal will exist in the +mainframe at OCLC and people will be able to access it. Here the +situation is different, ownership versus access, and is something that +arises with publication in the on-line environment, faster than is +sometimes realized. Lacking clear answers to all of these questions +herself, LEBRON did not anticipate that LC would be able to take a role +in helping to define some of them for quite a while. + +GREENFIELD observed that LC's Network Development Office is attempting, +among other things, to explore the limits of MARC as a standard in terms +of handling electronic information. GREENFIELD also noted that Rebecca +GUENTHER from that office gave a paper to the American Society for +Information Science (ASIS) summarizing several of the discussion papers +that were coming out of the Network Development Office. GREENFIELD said +he understood that that office had a list-server soliciting just the kind +of feedback received today concerning the difficulties of identifying and +cataloguing electronic information. GREENFIELD hoped that everybody +would be aware of that and somehow contribute to that conversation. + +Noting two of LC's roles, first, to act as a repository of record for +material that is copyrighted in this country, and second, to make +materials it holds available in some limited form to a clientele that +goes beyond Congress, BESSER suggested that it was incumbent on LC to +extend those responsibilities to all the things being published in +electronic form. This would mean eventually accepting electronic +formats. LC could require that at some point they be in a certain +limited set of formats, and then develop mechanisms for allowing people +to access those in the same way that other things are accessed. This +does not imply that they are on the network and available to everyone. +LC does that with most of its bibliographic records, BESSER said, which +end up migrating to the utility (e.g., OCLC) or somewhere else. But just +as most of LC's books are available in some form through interlibrary +loan or some other mechanism, so in the same way electronic formats ought +to be available to others in some format, though with some copyright +considerations. BESSER was not suggesting that these mechanisms be +established tomorrow, only that they seemed to fall within LC's purview, +and that there should be long-range plans to establish them. + +Acknowledging that those from LC in the room agreed with BESSER +concerning the need to confront difficult questions, GIFFORD underscored +the magnitude of the problem of what to keep and what to select. GIFFORD +noted that LC currently receives some 31,000 items per day, not counting +electronic materials, and argued for much more distributed responsibility +in order to maintain and store electronic information. + +BESSER responded that the assembled group could be viewed as a starting +point, whose initial operating premise could be helping to move in this +direction and defining how LC could do so, for example, in areas of +standardization or distribution of responsibility. + +FLEISCHHAUER added that AM was fully engaged, wrestling with some of the +questions that pertain to the conversion of older historical materials, +which would be one thing that the Library of Congress might do. Several +points mentioned by BESSER and several others on this question have a +much greater impact on those who are concerned with cataloguing and the +networking of bibliographic information, as well as preservation itself. + +Speaking directly to AM, which he considered was a largely uncopyrighted +database, LYNCH urged development of a network version of AM, or +consideration of making the data in it available to people interested in +doing network multimedia. On account of the current great shortage of +digital data that is both appealing and unencumbered by complex rights +problems, this course of action could have a significant effect on making +network multimedia a reality. + +In this connection, FLEISCHHAUER reported on a fragmentary prototype in +LC's Office of Information Technology Services that attempts to associate +digital images of photographs with cataloguing information in ways that +work within a local area network--a step, so to say, toward AM's +construction of some sort of apparatus for access. Further, AM has +attempted to use standard data forms in order to help make that +distinction between the access tools and the underlying data, and thus +believes that the database is networkable. + +A delicate and agonizing policy question for LC, however, which comes +back to resources and unfortunately has an impact on this, is to find +some appropriate, honorable, and legal cost-recovery possibilities. A +certain skittishness concerning cost-recovery has made people unsure +exactly what to do. AM would be highly receptive to discussing further +LYNCH's offer to test or demonstrate its database in a network +environment, FLEISCHHAUER said. + +Returning the discussion to what she viewed as the vital issue of +electronic deposit, BATTIN recommended that LC initiate a catalytic +process in terms of distributed responsibility, that is, bring together +the distributed organizations and set up a study group to look at all +these issues and see where we as a nation should move. The broader +issues of how we deal with the management of electronic information will +not disappear, but only grow worse. + +LESK took up this theme and suggested that LC attempt to persuade one +major library in each state to deal with its state equivalent publisher, +which might produce a cooperative project that would be equitably +distributed around the country, and one in which LC would be dealing with +a minimal number of publishers and minimal copyright problems. + +GRABER remarked the recent development in the scientific community of a +willingness to use SGML and either deposit or interchange on a fairly +standardized format. He wondered if a similar movement was taking place +in the humanities. Although the National Library of Medicine found only +a few publishers to cooperate in a like venture two or three years ago, a +new effort might generate a much larger number willing to cooperate. + +KIMBALL recounted his unit's (Machine-Readable Collections Reading Room) +troubles with the commercial publishers of electronic media in acquiring +materials for LC's collections, in particular the publishers' fear that +they would not be able to cover their costs and would lose control of +their products, that LC would give them away or sell them and make +profits from them. He doubted that the publishing industry was prepared +to move into this area at the moment, given its resistance to allowing LC +to use its machine-readable materials as the Library would like. + +The copyright law now addresses compact disk as a medium, and LC can +request one copy of that, or two copies if it is the only version, and +can request copies of software, but that fails to address magazines or +books or anything like that which is in machine-readable form. + +GIFFORD acknowledged the thorny nature of this issue, which he illustrated +with the example of the cumbersome process involved in putting a copy of a +scientific database on a LAN in LC's science reading room. He also +acknowledged that LC needs help and could enlist the energies and talents +of Workshop participants in thinking through a number of these problems. + +GIFFORD returned the discussion to getting the image and text people to +think through together where they want to go in the long term. MYLONAS +conceded that her experience at the Pierce Symposium the previous week at +Georgetown University and this week at LC had forced her to reevaluate +her perspective on the usefulness of text as images. MYLONAS framed the +issues in a series of questions: How do we acquire machine-readable +text? Do we take pictures of it and perform OCR on it later? Is it +important to obtain very high-quality images and text, etc.? +FLEISCHHAUER agreed with MYLONAS's framing of strategic questions, adding +that a large institution such as LC probably has to do all of those +things at different times. Thus, the trick is to exercise judgment. The +Workshop had added to his and AM's considerations in making those +judgments. Concerning future meetings or discussions, MYLONAS suggested +that screening priorities would be helpful. + +WEIBEL opined that the diversity reflected in this group was a sign both +of the health and of the immaturity of the field, and more time would +have to pass before we convince one another concerning standards. + +An exchange between MYLONAS and BATTIN clarified the point that the +driving force behind both the Perseus and the Cornell Xerox projects was +the preservation of knowledge for the future, not simply for particular +research use. In the case of Perseus, MYLONAS said, the assumption was +that the texts would not be entered again into electronically readable +form. SPERBERG-McQUEEN added that a scanned image would not serve as an +archival copy for purposes of preservation in the case of, say, the Bill +of Rights, in the sense that the scanned images are effectively the +archival copies for the Cornell mathematics books. + + + *** *** *** ****** *** *** *** + + + Appendix I: PROGRAM + + + + WORKSHOP + ON + ELECTRONIC + TEXTS + + + + 9-10 June 1992 + + Library of Congress + Washington, D.C. + + + + Supported by a Grant from the David and Lucile Packard Foundation + + +Tuesday, 9 June 1992 + +NATIONAL DEMONSTRATION LAB, ATRIUM, LIBRARY MADISON + +8:30 AM Coffee and Danish, registration + +9:00 AM Welcome + + Prosser Gifford, Director for Scholarly Programs, and Carl + Fleischhauer, Coordinator, American Memory, Library of + Congress + +9:l5 AM Session I. Content in a New Form: Who Will Use It and What + Will They Do? + + Broad description of the range of electronic information. + Characterization of who uses it and how it is or may be used. + In addition to a look at scholarly uses, this session will + include a presentation on use by students (K-12 and college) + and the general public. + + Moderator: James Daly + Avra Michelson, Archival Research and Evaluation Staff, + National Archives and Records Administration (Overview) + Susan H. Veccia, Team Leader, American Memory, User Evaluation, + and + Joanne Freeman, Associate Coordinator, American Memory, Library + of Congress (Beyond the scholar) + +10:30- +11:00 AM Break + +11:00 AM Session II. Show and Tell. + + Each presentation to consist of a fifteen-minute + statement/show; group discussion will follow lunch. + + Moderator: Jacqueline Hess, Director, National Demonstration + Lab + + 1. A classics project, stressing texts and text retrieval + more than multimedia: Perseus Project, Harvard + University + Elli Mylonas, Managing Editor + + 2. Other humanities projects employing the emerging norms of + the Text Encoding Initiative (TEI): Chadwyck-Healey's + The English Poetry Full Text Database and/or Patrologia + Latina Database + Eric M. Calaluca, Vice President, Chadwyck-Healey, Inc. + + 3. American Memory + Carl Fleischhauer, Coordinator, and + Ricky Erway, Associate Coordinator, Library of Congress + + 4. Founding Fathers example from Packard Humanities + Institute: The Papers of George Washington, University + of Virginia + Dorothy Twohig, Managing Editor, and/or + David Woodley Packard + + 5. An electronic medical journal offering graphics and + full-text searchability: The Online Journal of Current + Clinical Trials, American Association for the Advancement + of Science + Maria L. Lebron, Managing Editor + + 6. A project that offers facsimile images of pages but omits + searchable text: Cornell math books + Lynne K. Personius, Assistant Director, Cornell + Information Technologies for Scholarly Information + Sources, Cornell University + +12:30 PM Lunch (Dining Room A, Library Madison 620. Exhibits + available.) + +1:30 PM Session II. Show and Tell (Cont'd.). + +3:00- +3:30 PM Break + +3:30- +5:30 PM Session III. Distribution, Networks, and Networking: Options + for Dissemination. + + Published disks: University presses and public-sector + publishers, private-sector publishers + Computer networks + + Moderator: Robert G. Zich, Special Assistant to the Associate + Librarian for Special Projects, Library of Congress + Clifford A. Lynch, Director, Library Automation, University of + California + Howard Besser, School of Library and Information Science, + University of Pittsburgh + Ronald L. Larsen, Associate Director of Libraries for + Information Technology, University of Maryland at College + Park + Edwin B. Brownrigg, Executive Director, Memex Research + Institute + +6:30 PM Reception (Montpelier Room, Library Madison 619.) + + ****** + +Wednesday, 10 June 1992 + +DINING ROOM A, LIBRARY MADISON 620 + +8:30 AM Coffee and Danish + +9:00 AM Session IV. Image Capture, Text Capture, Overview of Text and + Image Storage Formats. + + Moderator: William L. Hooton, Vice President of Operations, + I-NET + + A) Principal Methods for Image Capture of Text: + Direct scanning + Use of microform + + Anne R. Kenney, Assistant Director, Department of Preservation + and Conservation, Cornell University + Pamela Q.J. Andre, Associate Director, Automation, and + Judith A. Zidar, Coordinator, National Agricultural Text + Digitizing Program (NATDP), National Agricultural Library + (NAL) + Donald J. Waters, Head, Systems Office, Yale University Library + + B) Special Problems: + Bound volumes + Conservation + Reproducing printed halftones + + Carl Fleischhauer, Coordinator, American Memory, Library of + Congress + George Thoma, Chief, Communications Engineering Branch, + National Library of Medicine (NLM) + +10:30- +11:00 AM Break + +11:00 AM Session IV. Image Capture, Text Capture, Overview of Text and + Image Storage Formats (Cont'd.). + + C) Image Standards and Implications for Preservation + + Jean Baronas, Senior Manager, Department of Standards and + Technology, Association for Information and Image Management + (AIIM) + Patricia Battin, President, The Commission on Preservation and + Access (CPA) + + D) Text Conversion: + OCR vs. rekeying + Standards of accuracy and use of imperfect texts + Service bureaus + + Stuart Weibel, Senior Research Specialist, Online Computer + Library Center, Inc. (OCLC) + Michael Lesk, Executive Director, Computer Science Research, + Bellcore + Ricky Erway, Associate Coordinator, American Memory, Library of + Congress + Pamela Q.J. Andre, Associate Director, Automation, and + Judith A. Zidar, Coordinator, National Agricultural Text + Digitizing Program (NATDP), National Agricultural Library + (NAL) + +12:30- +1:30 PM Lunch + +1:30 PM Session V. Approaches to Preparing Electronic Texts. + + Discussion of approaches to structuring text for the computer; + pros and cons of text coding, description of methods in + practice, and comparison of text-coding methods. + + Moderator: Susan Hockey, Director, Center for Electronic Texts + in the Humanities (CETH), Rutgers and Princeton Universities + David Woodley Packard + C.M. Sperberg-McQueen, Editor, Text Encoding Initiative (TEI), + University of Illinois-Chicago + Eric M. Calaluca, Vice President, Chadwyck-Healey, Inc. + +3:30- +4:00 PM Break + +4:00 PM Session VI. Copyright Issues. + + Marybeth Peters, Policy Planning Adviser to the Register of + Copyrights, Library of Congress + +5:00 PM Session VII. Conclusion. + + General discussion. + What topics were omitted or given short shrift that anyone + would like to talk about now? + Is there a "group" here? What should the group do next, if + anything? What should the Library of Congress do next, if + anything? + Moderator: Prosser Gifford, Director for Scholarly Programs, + Library of Congress + +6:00 PM Adjourn + + + *** *** *** ****** *** *** *** + + + Appendix II: ABSTRACTS + + +SESSION I + +Avra MICHELSON Forecasting the Use of Electronic Texts by + Social Sciences and Humanities Scholars + +This presentation explores the ways in which electronic texts are likely +to be used by the non-scientific scholarly community. Many of the +remarks are drawn from a report the speaker coauthored with Jeff +Rothenberg, a computer scientist at The RAND Corporation. + +The speaker assesses 1) current scholarly use of information technology +and 2) the key trends in information technology most relevant to the +research process, in order to predict how social sciences and humanities +scholars are apt to use electronic texts. In introducing the topic, +current use of electronic texts is explored broadly within the context of +scholarly communication. From the perspective of scholarly +communication, the work of humanities and social sciences scholars +involves five processes: 1) identification of sources, 2) communication +with colleagues, 3) interpretation and analysis of data, 4) dissemination +of research findings, and 5) curriculum development and instruction. The +extent to which computation currently permeates aspects of scholarly +communication represents a viable indicator of the prospects for +electronic texts. + +The discussion of current practice is balanced by an analysis of key +trends in the scholarly use of information technology. These include the +trends toward end-user computing and connectivity, which provide a +framework for forecasting the use of electronic texts through this +millennium. The presentation concludes with a summary of the ways in +which the nonscientific scholarly community can be expected to use +electronic texts, and the implications of that use for information +providers. + +Susan VECCIA and Joanne FREEMAN Electronic Archives for the Public: + Use of American Memory in Public and + School Libraries + +This joint discussion focuses on nonscholarly applications of electronic +library materials, specifically addressing use of the Library of Congress +American Memory (AM) program in a small number of public and school +libraries throughout the United States. AM consists of selected Library +of Congress primary archival materials, stored on optical media +(CD-ROM/videodisc), and presented with little or no editing. Many +collections are accompanied by electronic introductions and user's guides +offering background information and historical context. Collections +represent a variety of formats including photographs, graphic arts, +motion pictures, recorded sound, music, broadsides and manuscripts, +books, and pamphlets. + +In 1991, the Library of Congress began a nationwide evaluation of AM in +different types of institutions. Test sites include public libraries, +elementary and secondary school libraries, college and university +libraries, state libraries, and special libraries. Susan VECCIA and +Joanne FREEMAN will discuss their observations on the use of AM by the +nonscholarly community, using evidence gleaned from this ongoing +evaluation effort. + +VECCIA will comment on the overall goals of the evaluation project, and +the types of public and school libraries included in this study. Her +comments on nonscholarly use of AM will focus on the public library as a +cultural and community institution, often bridging the gap between formal +and informal education. FREEMAN will discuss the use of AM in school +libraries. Use by students and teachers has revealed some broad +questions about the use of electronic resources, as well as definite +benefits gained by the "nonscholar." Topics will include the problem of +grasping content and context in an electronic environment, the stumbling +blocks created by "new" technologies, and the unique skills and interests +awakened through use of electronic resources. + +SESSION II + +Elli MYLONAS The Perseus Project: Interactive Sources and + Studies in Classical Greece + +The Perseus Project (5) has just released Perseus 1.0, the first publicly +available version of its hypertextual database of multimedia materials on +classical Greece. Perseus is designed to be used by a wide audience, +comprised of readers at the student and scholar levels. As such, it must +be able to locate information using different strategies, and it must +contain enough detail to serve the different needs of its users. In +addition, it must be delivered so that it is affordable to its target +audience. [These problems and the solutions we chose are described in +Mylonas, "An Interface to Classical Greek Civilization," JASIS 43:2, +March 1992.] + +In order to achieve its objective, the project staff decided to make a +conscious separation between selecting and converting textual, database, +and image data on the one hand, and putting it into a delivery system on +the other. That way, it is possible to create the electronic data +without thinking about the restrictions of the delivery system. We have +made a great effort to choose system-independent formats for our data, +and to put as much thought and work as possible into structuring it so +that the translation from paper to electronic form will enhance the value +of the data. [A discussion of these solutions as of two years ago is in +Elli Mylonas, Gregory Crane, Kenneth Morrell, and D. Neel Smith, "The +Perseus Project: Data in the Electronic Age," in Accessing Antiquity: +The Computerization of Classical Databases, J. Solomon and T. Worthen +(eds.), University of Arizona Press, in press.] + +Much of the work on Perseus is focused on collecting and converting the +data on which the project is based. At the same time, it is necessary to +provide means of access to the information, in order to make it usable, +and them to investigate how it is used. As we learn more about what +students and scholars from different backgrounds do with Perseus, we can +adjust our data collection, and also modify the system to accommodate +them. In creating a delivery system for general use, we have tried to +avoid favoring any one type of use by allowing multiple forms of access +to and navigation through the system. + +The way text is handled exemplifies some of these principles. All text +in Perseus is tagged using SGML, following the guidelines of the Text +Encoding Initiative (TEI). This markup is used to index the text, and +process it so that it can be imported into HyperCard. No SGML markup +remains in the text that reaches the user, because currently it would be +too expensive to create a system that acts on SGML in real time. +However, the regularity provided by SGML is essential for verifying the +content of the texts, and greatly speeds all the processing performed on +them. The fact that the texts exist in SGML ensures that they will be +relatively easy to port to different hardware and software, and so will +outlast the current delivery platform. Finally, the SGML markup +incorporates existing canonical reference systems (chapter, verse, line, +etc.); indexing and navigation are based on these features. This ensures +that the same canonical reference will always resolve to the same point +within a text, and that all versions of our texts, regardless of delivery +platform (even paper printouts) will function the same way. + +In order to provide tools for users, the text is processed by a +morphological analyzer, and the results are stored in a database. +Together with the index, the Greek-English Lexicon, and the index of all +the English words in the definitions of the lexicon, the morphological +analyses comprise a set of linguistic tools that allow users of all +levels to work with the textual information, and to accomplish different +tasks. For example, students who read no Greek may explore a concept as +it appears in Greek texts by using the English-Greek index, and then +looking up works in the texts and translations, or scholars may do +detailed morphological studies of word use by using the morphological +analyses of the texts. Because these tools were not designed for any one +use, the same tools and the same data can be used by both students and +scholars. + +NOTES: + (5) Perseus is based at Harvard University, with collaborators at + several other universities. The project has been funded primarily + by the Annenberg/CPB Project, as well as by Harvard University, + Apple Computer, and others. It is published by Yale University + Press. Perseus runs on Macintosh computers, under the HyperCard + program. + +Eric CALALUCA + +Chadwyck-Healey embarked last year on two distinct yet related full-text +humanities database projects. + +The English Poetry Full-Text Database and the Patrologia Latina Database +represent new approaches to linguistic research resources. The size and +complexity of the projects present problems for electronic publishers, +but surmountable ones if they remain abreast of the latest possibilities +in data capture and retrieval software techniques. + +The issues which required address prior to the commencement of the +projects were legion: + + 1. Editorial selection (or exclusion) of materials in each + database + + 2. Deciding whether or not to incorporate a normative encoding + structure into the databases? + A. If one is selected, should it be SGML? + B. If SGML, then the TEI? + + 3. Deliver as CD-ROM, magnetic tape, or both? + + 4. Can one produce retrieval software advanced enough for the + postdoctoral linguist, yet accessible enough for unattended + general use? Should one try? + + 5. Re fair and liberal networking policies, what are the risks to + an electronic publisher? + + 6. How does the emergence of national and international education + networks affect the use and viability of research projects + requiring high investment? Do the new European Community + directives concerning database protection necessitate two + distinct publishing projects, one for North America and one for + overseas? + +From new notions of "scholarly fair use" to the future of optical media, +virtually every issue related to electronic publishing was aired. The +result is two projects which have been constructed to provide the quality +research resources with the fewest encumbrances to use by teachers and +private scholars. + +Dorothy TWOHIG + +In spring 1988 the editors of the papers of George Washington, John +Adams, Thomas Jefferson, James Madison, and Benjamin Franklin were +approached by classics scholar David Packard on behalf of the Packard +Humanities Foundation with a proposal to produce a CD-ROM edition of the +complete papers of each of the Founding Fathers. This electronic edition +will supplement the published volumes, making the documents widely +available to students and researchers at reasonable cost. We estimate +that our CD-ROM edition of Washington's Papers will be substantially +completed within the next two years and ready for publication. Within +the next ten years or so, similar CD-ROM editions of the Franklin, Adams, +Jefferson, and Madison papers also will be available. At the Library of +Congress's session on technology, I would like to discuss not only the +experience of the Washington Papers in producing the CD-ROM edition, but +the impact technology has had on these major editorial projects. +Already, we are editing our volumes with an eye to the material that will +be readily available in the CD-ROM edition. The completed electronic +edition will provide immense possibilities for the searching of documents +for information in a way never possible before. The kind of technical +innovations that are currently available and on the drawing board will +soon revolutionize historical research and the production of historical +documents. Unfortunately, much of this new technology is not being used +in the planning stages of historical projects, simply because many +historians are aware only in the vaguest way of its existence. At least +two major new historical editing projects are considering microfilm +editions, simply because they are not aware of the possibilities of +electronic alternatives and the advantages of the new technology in terms +of flexibility and research potential compared to microfilm. In fact, +too many of us in history and literature are still at the stage of +struggling with our PCs. There are many historical editorial projects in +progress presently, and an equal number of literary projects. While the +two fields have somewhat different approaches to textual editing, there +are ways in which electronic technology can be of service to both. + +Since few of the editors involved in the Founding Fathers CD-ROM editions +are technical experts in any sense, I hope to point out in my discussion +of our experience how many of these electronic innovations can be used +successfully by scholars who are novices in the world of new technology. +One of the major concerns of the sponsors of the multitude of new +scholarly editions is the limited audience reached by the published +volumes. Most of these editions are being published in small quantities +and the publishers' price for them puts them out of the reach not only of +individual scholars but of most public libraries and all but the largest +educational institutions. However, little attention is being given to +ways in which technology can bypass conventional publication to make +historical and literary documents more widely available. + +What attracted us most to the CD-ROM edition of The Papers of George +Washington was the fact that David Packard's aim was to make a complete +edition of all of the 135,000 documents we have collected available in an +inexpensive format that would be placed in public libraries, small +colleges, and even high schools. This would provide an audience far +beyond our present 1,000-copy, $45 published edition. Since the CD-ROM +edition will carry none of the explanatory annotation that appears in the +published volumes, we also feel that the use of the CD-ROM will lead many +researchers to seek out the published volumes. + +In addition to ignorance of new technical advances, I have found that too +many editors--and historians and literary scholars--are resistant and +even hostile to suggestions that electronic technology may enhance their +work. I intend to discuss some of the arguments traditionalists are +advancing to resist technology, ranging from distrust of the speed with +which it changes (we are already wondering what is out there that is +better than CD-ROM) to suspicion of the technical language used to +describe electronic developments. + +Maria LEBRON + +The Online Journal of Current Clinical Trials, a joint venture of the +American Association for the Advancement of Science (AAAS) and the Online +Computer Library Center, Inc. (OCLC), is the first peer-reviewed journal +to provide full text, tabular material, and line illustrations on line. +This presentation will discuss the genesis and start-up period of the +journal. Topics of discussion will include historical overview, +day-to-day management of the editorial peer review, and manuscript +tagging and publication. A demonstration of the journal and its features +will accompany the presentation. + +Lynne PERSONIUS + +Cornell University Library, Cornell Information Technologies, and Xerox +Corporation, with the support of the Commission on Preservation and +Access, and Sun Microsystems, Inc., have been collaborating in a project +to test a prototype system for recording brittle books as digital images +and producing, on demand, high-quality archival paper replacements. The +project goes beyond that, however, to investigate some of the issues +surrounding scanning, storing, retrieving, and providing access to +digital images in a network environment. + +The Joint Study in Digital Preservation began in January 1990. Xerox +provided the College Library Access and Storage System (CLASS) software, +a prototype 600-dots-per-inch (dpi) scanner, and the hardware necessary +to support network printing on the DocuTech printer housed in Cornell's +Computing and Communications Center (CCC). + +The Cornell staff using the hardware and software became an integral part +of the development and testing process for enhancements to the CLASS +software system. The collaborative nature of this relationship is +resulting in a system that is specifically tailored to the preservation +application. + +A digital library of 1,000 volumes (or approximately 300,000 images) has +been created and is stored on an optical jukebox that resides in CCC. +The library includes a collection of select mathematics monographs that +provides mathematics faculty with an opportunity to use the electronic +library. The remaining volumes were chosen for the library to test the +various capabilities of the scanning system. + +One project objective is to provide users of the Cornell library and the +library staff with the ability to request facsimiles of digitized images +or to retrieve the actual electronic image for browsing. A prototype +viewing workstation has been created by Xerox, with input into the design +by a committee of Cornell librarians and computer professionals. This +will allow us to experiment with patron access to the images that make up +the digital library. The viewing station provides search, retrieval, and +(ultimately) printing functions with enhancements to facilitate +navigation through multiple documents. + +Cornell currently is working to extend access to the digital library to +readers using workstations from their offices. This year is devoted to +the development of a network resident image conversion and delivery +server, and client software that will support readers who use Apple +Macintosh computers, IBM windows platforms, and Sun workstations. +Equipment for this development was provided by Sun Microsystems with +support from the Commission on Preservation and Access. + +During the show-and-tell session of the Workshop on Electronic Texts, a +prototype view station will be demonstrated. In addition, a display of +original library books that have been digitized will be available for +review with associated printed copies for comparison. The fifteen-minute +overview of the project will include a slide presentation that +constitutes a "tour" of the preservation digitizing process. + +The final network-connected version of the viewing station will provide +library users with another mechanism for accessing the digital library, +and will also provide the capability of viewing images directly. This +will not require special software, although a powerful computer with good +graphics will be needed. + +The Joint Study in Digital Preservation has generated a great deal of +interest in the library community. Unfortunately, or perhaps +fortunately, this project serves to raise a vast number of other issues +surrounding the use of digital technology for the preservation and use of +deteriorating library materials, which subsequent projects will need to +examine. Much work remains. + +SESSION III + +Howard BESSER Networking Multimedia Databases + +What do we have to consider in building and distributing databases of +visual materials in a multi-user environment? This presentation examines +a variety of concerns that need to be addressed before a multimedia +database can be set up in a networked environment. + +In the past it has not been feasible to implement databases of visual +materials in shared-user environments because of technological barriers. +Each of the two basic models for multi-user multimedia databases has +posed its own problem. The analog multimedia storage model (represented +by Project Athena's parallel analog and digital networks) has required an +incredibly complex (and expensive) infrastructure. The economies of +scale that make multi-user setups cheaper per user served do not operate +in an environment that requires a computer workstation, videodisc player, +and two display devices for each user. + +The digital multimedia storage model has required vast amounts of storage +space (as much as one gigabyte per thirty still images). In the past the +cost of such a large amount of storage space made this model a +prohibitive choice as well. But plunging storage costs are finally +making this second alternative viable. + +If storage no longer poses such an impediment, what do we need to +consider in building digitally stored multi-user databases of visual +materials? This presentation will examine the networking and +telecommunication constraints that must be overcome before such databases +can become commonplace and useful to a large number of people. + +The key problem is the vast size of multimedia documents, and how this +affects not only storage but telecommunications transmission time. +Anything slower than T-1 speed is impractical for files of 1 megabyte or +larger (which is likely to be small for a multimedia document). For +instance, even on a 56 Kb line it would take three minutes to transfer a +1-megabyte file. And these figures assume ideal circumstances, and do +not take into consideration other users contending for network bandwidth, +disk access time, or the time needed for remote display. Current common +telephone transmission rates would be completely impractical; few users +would be willing to wait the hour necessary to transmit a single image at +2400 baud. + +This necessitates compression, which itself raises a number of other +issues. In order to decrease file sizes significantly, we must employ +lossy compression algorithms. But how much quality can we afford to +lose? To date there has been only one significant study done of +image-quality needs for a particular user group, and this study did not +look at loss resulting from compression. Only after identifying +image-quality needs can we begin to address storage and network bandwidth +needs. + +Experience with X-Windows-based applications (such as Imagequery, the +University of California at Berkeley image database) demonstrates the +utility of a client-server topology, but also points to the limitation of +current software for a distributed environment. For example, +applications like Imagequery can incorporate compression, but current X +implementations do not permit decompression at the end user's +workstation. Such decompression at the host computer alleviates storage +capacity problems while doing nothing to address problems of +telecommunications bandwidth. + +We need to examine the effects on network through-put of moving +multimedia documents around on a network. We need to examine various +topologies that will help us avoid bottlenecks around servers and +gateways. Experience with applications such as these raise still broader +questions. How closely is the multimedia document tied to the software +for viewing it? Can it be accessed and viewed from other applications? +Experience with the MARC format (and more recently with the Z39.50 +protocols) shows how useful it can be to store documents in a form in +which they can be accessed by a variety of application software. + +Finally, from an intellectual-access standpoint, we need to address the +issue of providing access to these multimedia documents in +interdisciplinary environments. We need to examine terminology and +indexing strategies that will allow us to provide access to this material +in a cross-disciplinary way. + +Ronald LARSEN Directions in High-Performance Networking for + Libraries + +The pace at which computing technology has advanced over the past forty +years shows no sign of abating. Roughly speaking, each five-year period +has yielded an order-of-magnitude improvement in price and performance of +computing equipment. No fundamental hurdles are likely to prevent this +pace from continuing for at least the next decade. It is only in the +past five years, though, that computing has become ubiquitous in +libraries, affecting all staff and patrons, directly or indirectly. + +During these same five years, communications rates on the Internet, the +principal academic computing network, have grown from 56 kbps to 1.5 +Mbps, and the NSFNet backbone is now running 45 Mbps. Over the next five +years, communication rates on the backbone are expected to exceed 1 Gbps. +Growth in both the population of network users and the volume of network +traffic has continued to grow geometrically, at rates approaching 15 +percent per month. This flood of capacity and use, likened by some to +"drinking from a firehose," creates immense opportunities and challenges +for libraries. Libraries must anticipate the future implications of this +technology, participate in its development, and deploy it to ensure +access to the world's information resources. + +The infrastructure for the information age is being put in place. +Libraries face strategic decisions about their role in the development, +deployment, and use of this infrastructure. The emerging infrastructure +is much more than computers and communication lines. It is more than the +ability to compute at a remote site, send electronic mail to a peer +across the country, or move a file from one library to another. The next +five years will witness substantial development of the information +infrastructure of the network. + +In order to provide appropriate leadership, library professionals must +have a fundamental understanding of and appreciation for computer +networking, from local area networks to the National Research and +Education Network (NREN). This presentation addresses these +fundamentals, and how they relate to libraries today and in the near +future. + +Edwin BROWNRIGG Electronic Library Visions and Realities + +The electronic library has been a vision desired by many--and rejected by +some--since Vannevar Bush coined the term memex to describe an automated, +intelligent, personal information system. Variations on this vision have +included Ted Nelson's Xanadau, Alan Kay's Dynabook, and Lancaster's +"paperless library," with the most recent incarnation being the +"Knowledge Navigator" described by John Scully of Apple. But the reality +of library service has been less visionary and the leap to the electronic +library has eluded universities, publishers, and information technology +files. + +The Memex Research Institute (MemRI), an independent, nonprofit research +and development organization, has created an Electronic Library Program +of shared research and development in order to make the collective vision +more concrete. The program is working toward the creation of large, +indexed publicly available electronic image collections of published +documents in academic, special, and public libraries. This strategic +plan is the result of the first stage of the program, which has been an +investigation of the information technologies available to support such +an effort, the economic parameters of electronic service compared to +traditional library operations, and the business and political factors +affecting the shift from print distribution to electronic networked +access. + +The strategic plan envisions a combination of publicly searchable access +databases, image (and text) document collections stored on network "file +servers," local and remote network access, and an intellectual property +management-control system. This combination of technology and +information content is defined in this plan as an E-library or E-library +collection. Some participating sponsors are already developing projects +based on MemRI's recommended directions. + +The E-library strategy projected in this plan is a visionary one that can +enable major changes and improvements in academic, public, and special +library service. This vision is, though, one that can be realized with +today's technology. At the same time, it will challenge the political +and social structure within which libraries operate: in academic +libraries, the traditional emphasis on local collections, extending to +accreditation issues; in public libraries, the potential of electronic +branch and central libraries fully available to the public; and for +special libraries, new opportunities for shared collections and networks. + +The environment in which this strategic plan has been developed is, at +the moment, dominated by a sense of library limits. The continued +expansion and rapid growth of local academic library collections is now +clearly at an end. Corporate libraries, and even law libraries, are +faced with operating within a difficult economic climate, as well as with +very active competition from commercial information sources. For +example, public libraries may be seen as a desirable but not critical +municipal service in a time when the budgets of safety and health +agencies are being cut back. + +Further, libraries in general have a very high labor-to-cost ratio in +their budgets, and labor costs are still increasing, notwithstanding +automation investments. It is difficult for libraries to obtain capital, +startup, or seed funding for innovative activities, and those +technology-intensive initiatives that offer the potential of decreased +labor costs can provoke the opposition of library staff. + +However, libraries have achieved some considerable successes in the past +two decades by improving both their service and their credibility within +their organizations--and these positive changes have been accomplished +mostly with judicious use of information technologies. The advances in +computing and information technology have been well-chronicled: the +continuing precipitous drop in computing costs, the growth of the +Internet and private networks, and the explosive increase in publicly +available information databases. + +For example, OCLC has become one of the largest computer network +organizations in the world by creating a cooperative cataloging network +of more than 6,000 libraries worldwide. On-line public access catalogs +now serve millions of users on more than 50,000 dedicated terminals in +the United States alone. The University of California MELVYL on-line +catalog system has now expanded into an index database reference service +and supports more than six million searches a year. And, libraries have +become the largest group of customers of CD-ROM publishing technology; +more than 30,000 optical media publications such as those offered by +InfoTrac and Silver Platter are subscribed to by U.S. libraries. + +This march of technology continues and in the next decade will result in +further innovations that are extremely difficult to predict. What is +clear is that libraries can now go beyond automation of their order files +and catalogs to automation of their collections themselves--and it is +possible to circumvent the fiscal limitations that appear to obtain +today. + +This Electronic Library Strategic Plan recommends a paradigm shift in +library service, and demonstrates the steps necessary to provide improved +library services with limited capacities and operating investments. + +SESSION IV-A + +Anne KENNEY + +The Cornell/Xerox Joint Study in Digital Preservation resulted in the +recording of 1,000 brittle books as 600-dpi digital images and the +production, on demand, of high-quality and archivally sound paper +replacements. The project, which was supported by the Commission on +Preservation and Access, also investigated some of the issues surrounding +scanning, storing, retrieving, and providing access to digital images in +a network environment. + +Anne Kenney will focus on some of the issues surrounding direct scanning +as identified in the Cornell Xerox Project. Among those to be discussed +are: image versus text capture; indexing and access; image-capture +capabilities; a comparison to photocopy and microfilm; production and +cost analysis; storage formats, protocols, and standards; and the use of +this scanning technology for preservation purposes. + +The 600-dpi digital images produced in the Cornell Xerox Project proved +highly acceptable for creating paper replacements of deteriorating +originals. The 1,000 scanned volumes provided an array of image-capture +challenges that are common to nineteenth-century printing techniques and +embrittled material, and that defy the use of text-conversion processes. +These challenges include diminished contrast between text and background, +fragile and deteriorated pages, uneven printing, elaborate type faces, +faint and bold text adjacency, handwritten text and annotations, nonRoman +languages, and a proliferation of illustrated material embedded in text. +The latter category included high-frequency and low-frequency halftones, +continuous tone photographs, intricate mathematical drawings, maps, +etchings, reverse-polarity drawings, and engravings. + +The Xerox prototype scanning system provided a number of important +features for capturing this diverse material. Technicians used multiple +threshold settings, filters, line art and halftone definitions, +autosegmentation, windowing, and software-editing programs to optimize +image capture. At the same time, this project focused on production. +The goal was to make scanning as affordable and acceptable as +photocopying and microfilming for preservation reformatting. A +time-and-cost study conducted during the last three months of this +project confirmed the economic viability of digital scanning, and these +findings will be discussed here. + +From the outset, the Cornell Xerox Project was predicated on the use of +nonproprietary standards and the use of common protocols when standards +did not exist. Digital files were created as TIFF images which were +compressed prior to storage using Group 4 CCITT compression. The Xerox +software is MS DOS based and utilizes off-the shelf programs such as +Microsoft Windows and Wang Image Wizard. The digital library is designed +to be hardware-independent and to provide interchangeability with other +institutions through network connections. Access to the digital files +themselves is two-tiered: Bibliographic records for the computer files +are created in RLIN and Cornell's local system and access into the actual +digital images comprising a book is provided through a document control +structure and a networked image file-server, both of which will be +described. + +The presentation will conclude with a discussion of some of the issues +surrounding the use of this technology as a preservation tool (storage, +refreshing, backup). + +Pamela ANDRE and Judith ZIDAR + +The National Agricultural Library (NAL) has had extensive experience with +raster scanning of printed materials. Since 1987, the Library has +participated in the National Agricultural Text Digitizing Project (NATDP) +a cooperative effort between NAL and forty-five land grant university +libraries. An overview of the project will be presented, giving its +history and NAL's strategy for the future. + +An in-depth discussion of NATDP will follow, including a description of +the scanning process, from the gathering of the printed materials to the +archiving of the electronic pages. The type of equipment required for a +stand-alone scanning workstation and the importance of file management +software will be discussed. Issues concerning the images themselves will +be addressed briefly, such as image format; black and white versus color; +gray scale versus dithering; and resolution. + +Also described will be a study currently in progress by NAL to evaluate +the usefulness of converting microfilm to electronic images in order to +improve access. With the cooperation of Tuskegee University, NAL has +selected three reels of microfilm from a collection of sixty-seven reels +containing the papers, letters, and drawings of George Washington Carver. +The three reels were converted into 3,500 electronic images using a +specialized microfilm scanner. The selection, filming, and indexing of +this material will be discussed. + +Donald WATERS + +Project Open Book, the Yale University Library's effort to convert 10, +000 books from microfilm to digital imagery, is currently in an advanced +state of planning and organization. The Yale Library has selected a +major vendor to serve as a partner in the project and as systems +integrator. In its proposal, the successful vendor helped isolate areas +of risk and uncertainty as well as key issues to be addressed during the +life of the project. The Yale Library is now poised to decide what +material it will convert to digital image form and to seek funding, +initially for the first phase and then for the entire project. + +The proposal that Yale accepted for the implementation of Project Open +Book will provide at the end of three phases a conversion subsystem, +browsing stations distributed on the campus network within the Yale +Library, a subsystem for storing 10,000 books at 200 and 600 dots per +inch, and network access to the image printers. Pricing for the system +implementation assumes the existence of Yale's campus ethernet network +and its high-speed image printers, and includes other requisite hardware +and software, as well as system integration services. Proposed operating +costs include hardware and software maintenance, but do not include +estimates for the facilities management of the storage devices and image +servers. + +Yale selected its vendor partner in a formal process, partly funded by +the Commission for Preservation and Access. Following a request for +proposal, the Yale Library selected two vendors as finalists to work with +Yale staff to generate a detailed analysis of requirements for Project +Open Book. Each vendor used the results of the requirements analysis to +generate and submit a formal proposal for the entire project. This +competitive process not only enabled the Yale Library to select its +primary vendor partner but also revealed much about the state of the +imaging industry, about the varying, corporate commitments to the markets +for imaging technology, and about the varying organizational dynamics +through which major companies are responding to and seeking to develop +these markets. + +Project Open Book is focused specifically on the conversion of images +from microfilm to digital form. The technology for scanning microfilm is +readily available but is changing rapidly. In its project requirements, +the Yale Library emphasized features of the technology that affect the +technical quality of digital image production and the costs of creating +and storing the image library: What levels of digital resolution can be +achieved by scanning microfilm? How does variation in the quality of +microfilm, particularly in film produced to preservation standards, +affect the quality of the digital images? What technologies can an +operator effectively and economically apply when scanning film to +separate two-up images and to control for and correct image +imperfections? How can quality control best be integrated into +digitizing work flow that includes document indexing and storage? + +The actual and expected uses of digital images--storage, browsing, +printing, and OCR--help determine the standards for measuring their +quality. Browsing is especially important, but the facilities available +for readers to browse image documents is perhaps the weakest aspect of +imaging technology and most in need of development. As it defined its +requirements, the Yale Library concentrated on some fundamental aspects +of usability for image documents: Does the system have sufficient +flexibility to handle the full range of document types, including +monographs, multi-part and multivolume sets, and serials, as well as +manuscript collections? What conventions are necessary to identify a +document uniquely for storage and retrieval? Where is the database of +record for storing bibliographic information about the image document? +How are basic internal structures of documents, such as pagination, made +accessible to the reader? How are the image documents physically +presented on the screen to the reader? + +The Yale Library designed Project Open Book on the assumption that +microfilm is more than adequate as a medium for preserving the content of +deteriorated library materials. As planning in the project has advanced, +it is increasingly clear that the challenge of digital image technology +and the key to the success of efforts like Project Open Book is to +provide a means of both preserving and improving access to those +deteriorated materials. + +SESSION IV-B + +George THOMA + +In the use of electronic imaging for document preservation, there are +several issues to consider, such as: ensuring adequate image quality, +maintaining substantial conversion rates (through-put), providing unique +identification for automated access and retrieval, and accommodating +bound volumes and fragile material. + +To maintain high image quality, image processing functions are required +to correct the deficiencies in the scanned image. Some commercially +available systems include these functions, while some do not. The +scanned raw image must be processed to correct contrast deficiencies-- +both poor overall contrast resulting from light print and/or dark +background, and variable contrast resulting from stains and +bleed-through. Furthermore, the scan density must be adequate to allow +legibility of print and sufficient fidelity in the pseudo-halftoned gray +material. Borders or page-edge effects must be removed for both +compactibility and aesthetics. Page skew must be corrected for aesthetic +reasons and to enable accurate character recognition if desired. +Compound images consisting of both two-toned text and gray-scale +illustrations must be processed appropriately to retain the quality of +each. + +SESSION IV-C + +Jean BARONAS + +Standards publications being developed by scientists, engineers, and +business managers in Association for Information and Image Management +(AIIM) standards committees can be applied to electronic image management +(EIM) processes including: document (image) transfer, retrieval and +evaluation; optical disk and document scanning; and document design and +conversion. When combined with EIM system planning and operations, +standards can assist in generating image databases that are +interchangeable among a variety of systems. The applications of +different approaches for image-tagging, indexing, compression, and +transfer often cause uncertainty concerning EIM system compatibility, +calibration, performance, and upward compatibility, until standard +implementation parameters are established. The AIIM standards that are +being developed for these applications can be used to decrease the +uncertainty, successfully integrate imaging processes, and promote "open +systems." AIIM is an accredited American National Standards Institute +(ANSI) standards developer with more than twenty committees comprised of +300 volunteers representing users, vendors, and manufacturers. The +standards publications that are developed in these committees have +national acceptance and provide the basis for international harmonization +in the development of new International Organization for Standardization +(ISO) standards. + +This presentation describes the development of AIIM's EIM standards and a +new effort at AIIM, a database on standards projects in a wide framework +of imaging industries including capture, recording, processing, +duplication, distribution, display, evaluation, and preservation. The +AIIM Imagery Database will cover imaging standards being developed by +many organizations in many different countries. It will contain +standards publications' dates, origins, related national and +international projects, status, key words, and abstracts. The ANSI Image +Technology Standards Board requested that such a database be established, +as did the ISO/International Electrotechnical Commission Joint Task Force +on Imagery. AIIM will take on the leadership role for the database and +coordinate its development with several standards developers. + +Patricia BATTIN + + Characteristics of standards for digital imagery: + + * Nature of digital technology implies continuing volatility. + + * Precipitous standard-setting not possible and probably not + desirable. + + * Standards are a complex issue involving the medium, the + hardware, the software, and the technical capacity for + reproductive fidelity and clarity. + + * The prognosis for reliable archival standards (as defined by + librarians) in the foreseeable future is poor. + + Significant potential and attractiveness of digital technology as a + preservation medium and access mechanism. + + Productive use of digital imagery for preservation requires a + reconceptualizing of preservation principles in a volatile, + standardless world. + + Concept of managing continuing access in the digital environment + rather than focusing on the permanence of the medium and long-term + archival standards developed for the analog world. + + Transition period: How long and what to do? + + * Redefine "archival." + + * Remove the burden of "archival copy" from paper artifacts. + + * Use digital technology for storage, develop management + strategies for refreshing medium, hardware and software. + + * Create acid-free paper copies for transition period backup + until we develop reliable procedures for ensuring continuing + access to digital files. + +SESSION IV-D + +Stuart WEIBEL The Role of SGML Markup in the CORE Project (6) + +The emergence of high-speed telecommunications networks as a basic +feature of the scholarly workplace is driving the demand for electronic +document delivery. Three distinct categories of electronic +publishing/republishing are necessary to support access demands in this +emerging environment: + + 1.) Conversion of paper or microfilm archives to electronic format + 2.) Conversion of electronic files to formats tailored to + electronic retrieval and display + 3.) Primary electronic publishing (materials for which the + electronic version is the primary format) + +OCLC has experimental or product development activities in each of these +areas. Among the challenges that lie ahead is the integration of these +three types of information stores in coherent distributed systems. + +The CORE (Chemistry Online Retrieval Experiment) Project is a model for +the conversion of large text and graphics collections for which +electronic typesetting files are available (category 2). The American +Chemical Society has made available computer typography files dating from +1980 for its twenty journals. This collection of some 250 journal-years +is being converted to an electronic format that will be accessible +through several end-user applications. + +The use of Standard Generalized Markup Language (SGML) offers the means +to capture the structural richness of the original articles in a way that +will support a variety of retrieval, navigation, and display options +necessary to navigate effectively in very large text databases. + +An SGML document consists of text that is marked up with descriptive tags +that specify the function of a given element within the document. As a +formal language construct, an SGML document can be parsed against a +document-type definition (DTD) that unambiguously defines what elements +are allowed and where in the document they can (or must) occur. This +formalized map of article structure allows the user interface design to +be uncoupled from the underlying database system, an important step +toward interoperability. Demonstration of this separability is a part of +the CORE project, wherein user interface designs born of very different +philosophies will access the same database. + +NOTES: + (6) The CORE project is a collaboration among Cornell University's + Mann Library, Bell Communications Research (Bellcore), the American + Chemical Society (ACS), the Chemical Abstracts Service (CAS), and + OCLC. + +Michael LESK The CORE Electronic Chemistry Library + +A major on-line file of chemical journal literature complete with +graphics is being developed to test the usability of fully electronic +access to documents, as a joint project of Cornell University, the +American Chemical Society, the Chemical Abstracts Service, OCLC, and +Bellcore (with additional support from Sun Microsystems, Springer-Verlag, +DigitaI Equipment Corporation, Sony Corporation of America, and Apple +Computers). Our file contains the American Chemical Society's on-line +journals, supplemented with the graphics from the paper publication. The +indexing of the articles from Chemical Abstracts Documents is available +in both image and text format, and several different interfaces can be +used. Our goals are (1) to assess the effectiveness and acceptability of +electronic access to primary journals as compared with paper, and (2) to +identify the most desirable functions of the user interface to an +electronic system of journals, including in particular a comparison of +page-image display with ASCII display interfaces. Early experiments with +chemistry students on a variety of tasks suggest that searching tasks are +completed much faster with any electronic system than with paper, but +that for reading all versions of the articles are roughly equivalent. + +Pamela ANDRE and Judith ZIDAR + +Text conversion is far more expensive and time-consuming than image +capture alone. NAL's experience with optical character recognition (OCR) +will be related and compared with the experience of having text rekeyed. +What factors affect OCR accuracy? How accurate does full text have to be +in order to be useful? How do different users react to imperfect text? +These are questions that will be explored. For many, a service bureau +may be a better solution than performing the work inhouse; this will also +be discussed. + +SESSION VI + +Marybeth PETERS + +Copyright law protects creative works. Protection granted by the law to +authors and disseminators of works includes the right to do or authorize +the following: reproduce the work, prepare derivative works, distribute +the work to the public, and publicly perform or display the work. In +addition, copyright owners of sound recordings and computer programs have +the right to control rental of their works. These rights are not +unlimited; there are a number of exceptions and limitations. + +An electronic environment places strains on the copyright system. +Copyright owners want to control uses of their work and be paid for any +use; the public wants quick and easy access at little or no cost. The +marketplace is working in this area. Contracts, guidelines on electronic +use, and collective licensing are in use and being refined. + +Issues concerning the ability to change works without detection are more +difficult to deal with. Questions concerning the integrity of the work +and the status of the changed version under the copyright law are to be +addressed. These are public policy issues which require informed +dialogue. + + + *** *** *** ****** *** *** *** + + + Appendix III: DIRECTORY OF PARTICIPANTS + + +PRESENTERS: + + Pamela Q.J. Andre + Associate Director, Automation + National Agricultural Library + 10301 Baltimore Boulevard + Beltsville, MD 20705-2351 + Phone: (301) 504-6813 + Fax: (301) 504-7473 + E-mail: INTERNET: PANDRE@ASRR.ARSUSDA.GOV + + Jean Baronas, Senior Manager + Department of Standards and Technology + Association for Information and Image Management (AIIM) + 1100 Wayne Avenue, Suite 1100 + Silver Spring, MD 20910 + Phone: (301) 587-8202 + Fax: (301) 587-2711 + + Patricia Battin, President + The Commission on Preservation and Access + 1400 16th Street, N.W. + Suite 740 + Washington, DC 20036-2217 + Phone: (202) 939-3400 + Fax: (202) 939-3407 + E-mail: CPA@GWUVM.BITNET + + Howard Besser + Centre Canadien d'Architecture + (Canadian Center for Architecture) + 1920, rue Baile + Montreal, Quebec H3H 2S6 + CANADA + Phone: (514) 939-7001 + Fax: (514) 939-7020 + E-mail: howard@lis.pitt.edu + + Edwin B. Brownrigg, Executive Director + Memex Research Institute + 422 Bonita Avenue + Roseville, CA 95678 + Phone: (916) 784-2298 + Fax: (916) 786-7559 + E-mail: BITNET: MEMEX@CALSTATE.2 + + Eric M. Calaluca, Vice President + Chadwyck-Healey, Inc. + 1101 King Street + Alexandria, VA 223l4 + Phone: (800) 752-05l5 + Fax: (703) 683-7589 + + James Daly + 4015 Deepwood Road + Baltimore, MD 21218-1404 + Phone: (410) 235-0763 + + Ricky Erway, Associate Coordinator + American Memory + Library of Congress + Phone: (202) 707-6233 + Fax: (202) 707-3764 + + Carl Fleischhauer, Coordinator + American Memory + Library of Congress + Phone: (202) 707-6233 + Fax: (202) 707-3764 + + Joanne Freeman + 2000 Jefferson Park Avenue, No. 7 + Charlottesville, VA 22903 + + Prosser Gifford + Director for Scholarly Programs + Library of Congress + Phone: (202) 707-1517 + Fax: (202) 707-9898 + E-mail: pgif@seq1.loc.gov + + Jacqueline Hess, Director + National Demonstration Laboratory + for Interactive Information Technologies + Library of Congress + Phone: (202) 707-4157 + Fax: (202) 707-2829 + + Susan Hockey, Director + Center for Electronic Texts in the Humanities (CETH) + Alexander Library + Rutgers University + 169 College Avenue + New Brunswick, NJ 08903 + Phone: (908) 932-1384 + Fax: (908) 932-1386 + E-mail: hockey@zodiac.rutgers.edu + + William L. Hooton, Vice President + Business & Technical Development + Imaging & Information Systems Group + I-NET + 6430 Rockledge Drive, Suite 400 + Bethesda, MD 208l7 + Phone: (301) 564-6750 + Fax: (513) 564-6867 + + Anne R. Kenney, Associate Director + Department of Preservation and Conservation + 701 Olin Library + Cornell University + Ithaca, NY 14853 + Phone: (607) 255-6875 + Fax: (607) 255-9346 + E-mail: LYDY@CORNELLA.BITNET + + Ronald L. Larsen + Associate Director for Information Technology + University of Maryland at College Park + Room B0224, McKeldin Library + College Park, MD 20742-7011 + Phone: (301) 405-9194 + Fax: (301) 314-9865 + E-mail: rlarsen@libr.umd.edu + + Maria L. Lebron, Managing Editor + The Online Journal of Current Clinical Trials + l333 H Street, N.W. + Washington, DC 20005 + Phone: (202) 326-6735 + Fax: (202) 842-2868 + E-mail: PUBSAAAS@GWUVM.BITNET + + Michael Lesk, Executive Director + Computer Science Research + Bell Communications Research, Inc. + Rm 2A-385 + 445 South Street + Morristown, NJ 07960-l9l0 + Phone: (201) 829-4070 + Fax: (201) 829-5981 + E-mail: lesk@bellcore.com (Internet) or bellcore!lesk (uucp) + + Clifford A. Lynch + Director, Library Automation + University of California, + Office of the President + 300 Lakeside Drive, 8th Floor + Oakland, CA 94612-3350 + Phone: (510) 987-0522 + Fax: (510) 839-3573 + E-mail: calur@uccmvsa + + Avra Michelson + National Archives and Records Administration + NSZ Rm. 14N + 7th & Pennsylvania, N.W. + Washington, D.C. 20408 + Phone: (202) 501-5544 + Fax: (202) 501-5533 + E-mail: tmi@cu.nih.gov + + Elli Mylonas, Managing Editor + Perseus Project + Department of the Classics + Harvard University + 319 Boylston Hall + Cambridge, MA 02138 + Phone: (617) 495-9025, (617) 495-0456 (direct) + Fax: (617) 496-8886 + E-mail: Elli@IKAROS.Harvard.EDU or elli@wjh12.harvard.edu + + David Woodley Packard + Packard Humanities Institute + 300 Second Street, Suite 201 + Los Altos, CA 94002 + Phone: (415) 948-0150 (PHI) + Fax: (415) 948-5793 + + Lynne K. Personius, Assistant Director + Cornell Information Technologies for + Scholarly Information Sources + 502 Olin Library + Cornell University + Ithaca, NY 14853 + Phone: (607) 255-3393 + Fax: (607) 255-9346 + E-mail: JRN@CORNELLC.BITNET + + Marybeth Peters + Policy Planning Adviser to the + Register of Copyrights + Library of Congress + Office LM 403 + Phone: (202) 707-8350 + Fax: (202) 707-8366 + + C. Michael Sperberg-McQueen + Editor, Text Encoding Initiative + Computer Center (M/C 135) + University of Illinois at Chicago + Box 6998 + Chicago, IL 60680 + Phone: (312) 413-0317 + Fax: (312) 996-6834 + E-mail: u35395@uicvm..cc.uic.edu or u35395@uicvm.bitnet + + George R. Thoma, Chief + Communications Engineering Branch + National Library of Medicine + 8600 Rockville Pike + Bethesda, MD 20894 + Phone: (301) 496-4496 + Fax: (301) 402-0341 + E-mail: thoma@lhc.nlm.nih.gov + + Dorothy Twohig, Editor + The Papers of George Washington + 504 Alderman Library + University of Virginia + Charlottesville, VA 22903-2498 + Phone: (804) 924-0523 + Fax: (804) 924-4337 + + Susan H. Veccia, Team leader + American Memory, User Evaluation + Library of Congress + American Memory Evaluation Project + Phone: (202) 707-9104 + Fax: (202) 707-3764 + E-mail: svec@seq1.loc.gov + + Donald J. Waters, Head + Systems Office + Yale University Library + New Haven, CT 06520 + Phone: (203) 432-4889 + Fax: (203) 432-7231 + E-mail: DWATERS@YALEVM.BITNET or DWATERS@YALEVM.YCC.YALE.EDU + + Stuart Weibel, Senior Research Scientist + OCLC + 6565 Frantz Road + Dublin, OH 43017 + Phone: (614) 764-608l + Fax: (614) 764-2344 + E-mail: INTERNET: Stu@rsch.oclc.org + + Robert G. Zich + Special Assistant to the Associate Librarian + for Special Projects + Library of Congress + Phone: (202) 707-6233 + Fax: (202) 707-3764 + E-mail: rzic@seq1.loc.gov + + Judith A. Zidar, Coordinator + National Agricultural Text Digitizing Program + Information Systems Division + National Agricultural Library + 10301 Baltimore Boulevard + Beltsville, MD 20705-2351 + Phone: (301) 504-6813 or 504-5853 + Fax: (301) 504-7473 + E-mail: INTERNET: JZIDAR@ASRR.ARSUSDA.GOV + + +OBSERVERS: + + Helen Aguera, Program Officer + Division of Research + Room 318 + National Endowment for the Humanities + 1100 Pennsylvania Avenue, N.W. + Washington, D.C. 20506 + Phone: (202) 786-0358 + Fax: (202) 786-0243 + + M. Ellyn Blanton, Deputy Director + National Demonstration Laboratory + for Interactive Information Technologies + Library of Congress + Phone: (202) 707-4157 + Fax: (202) 707-2829 + + Charles M. Dollar + National Archives and Records Administration + NSZ Rm. 14N + 7th & Pennsylvania, N.W. + Washington, DC 20408 + Phone: (202) 501-5532 + Fax: (202) 501-5512 + + Jeffrey Field, Deputy to the Director + Division of Preservation and Access + Room 802 + National Endowment for the Humanities + 1100 Pennsylvania Avenue, N.W. + Washington, DC 20506 + Phone: (202) 786-0570 + Fax: (202) 786-0243 + + Lorrin Garson + American Chemical Society + Research and Development Department + 1155 16th Street, N.W. + Washington, D.C. 20036 + Phone: (202) 872-4541 + Fax: E-mail: INTERNET: LRG96@ACS.ORG + + William M. Holmes, Jr. + National Archives and Records Administration + NSZ Rm. 14N + 7th & Pennsylvania, N.W. + Washington, DC 20408 + Phone: (202) 501-5540 + Fax: (202) 501-5512 + E-mail: WHOLMES@AMERICAN.EDU + + Sperling Martin + Information Resource Management + 20030 Doolittle Street + Gaithersburg, MD 20879 + Phone: (301) 924-1803 + + Michael Neuman, Director + The Center for Text and Technology + Academic Computing Center + 238 Reiss Science Building + Georgetown University + Washington, DC 20057 + Phone: (202) 687-6096 + Fax: (202) 687-6003 + E-mail: neuman@guvax.bitnet, neuman@guvax.georgetown.edu + + Barbara Paulson, Program Officer + Division of Preservation and Access + Room 802 + National Endowment for the Humanities + 1100 Pennsylvania Avenue, N.W. + Washington, DC 20506 + Phone: (202) 786-0577 + Fax: (202) 786-0243 + + Allen H. Renear + Senior Academic Planning Analyst + Brown University Computing and Information Services + 115 Waterman Street + Campus Box 1885 + Providence, R.I. 02912 + Phone: (401) 863-7312 + Fax: (401) 863-7329 + E-mail: BITNET: Allen@BROWNVM or + INTERNET: Allen@brownvm.brown.edu + + Susan M. Severtson, President + Chadwyck-Healey, Inc. + 1101 King Street + Alexandria, VA 223l4 + Phone: (800) 752-05l5 + Fax: (703) 683-7589 + + Frank Withrow + U.S. Department of Education + 555 New Jersey Avenue, N.W. + Washington, DC 20208-5644 + Phone: (202) 219-2200 + Fax: (202) 219-2106 + + +(LC STAFF) + + Linda L. Arret + Machine-Readable Collections Reading Room LJ 132 + (202) 707-1490 + + John D. Byrum, Jr. + Descriptive Cataloging Division LM 540 + (202) 707-5194 + + Mary Jane Cavallo + Science and Technology Division LA 5210 + (202) 707-1219 + + Susan Thea David + Congressional Research Service LM 226 + (202) 707-7169 + + Robert Dierker + Senior Adviser for Multimedia Activities LM 608 + (202) 707-6151 + + William W. Ellis + Associate Librarian for Science and Technology LM 611 + (202) 707-6928 + + Ronald Gephart + Manuscript Division LM 102 + (202) 707-5097 + + James Graber + Information Technology Services LM G51 + (202) 707-9628 + + Rich Greenfield + American Memory LM 603 + (202) 707-6233 + + Rebecca Guenther + Network Development LM 639 + (202) 707-5092 + + Kenneth E. Harris + Preservation LM G21 + (202) 707-5213 + + Staley Hitchcock + Manuscript Division LM 102 + (202) 707-5383 + + Bohdan Kantor + Office of Special Projects LM 612 + (202) 707-0180 + + John W. Kimball, Jr + Machine-Readable Collections Reading Room LJ 132 + (202) 707-6560 + + Basil Manns + Information Technology Services LM G51 + (202) 707-8345 + + Sally Hart McCallum + Network Development LM 639 + (202) 707-6237 + + Dana J. Pratt + Publishing Office LM 602 + (202) 707-6027 + + Jane Riefenhauser + American Memory LM 603 + (202) 707-6233 + + William Z. Schenck + Collections Development LM 650 + (202) 707-7706 + + Chandru J. Shahani + Preservation Research and Testing Office (R&T) LM G38 + (202) 707-5607 + + William J. Sittig + Collections Development LM 650 + (202) 707-7050 + + Paul Smith + Manuscript Division LM 102 + (202) 707-5097 + + James L. Stevens + Information Technology Services LM G51 + (202) 707-9688 + + Karen Stuart + Manuscript Division LM 130 + (202) 707-5389 + + Tamara Swora + Preservation Microfilming Office LM G05 + (202) 707-6293 + + Sarah Thomas + Collections Cataloging LM 642 + (202) 707-5333 + + + END + ************************************************************* + +Note: This file has been edited for use on computer networks. This +editing required the removal of diacritics, underlining, and fonts such +as italics and bold. + +kde 11/92 + +[A few of the italics (when used for emphasis) were replaced by CAPS mh] + +*End of The Project Gutenberg Etext of LOC WORKSHOP ON ELECTRONIC ETEXTS + diff --git a/web/server/h2o/libh2o/deps/brotli/tests/testdata/lcet10.txt.compressed b/web/server/h2o/libh2o/deps/brotli/tests/testdata/lcet10.txt.compressed new file mode 100644 index 00000000..b7d0f633 Binary files /dev/null and b/web/server/h2o/libh2o/deps/brotli/tests/testdata/lcet10.txt.compressed differ diff --git a/web/server/h2o/libh2o/deps/brotli/tests/testdata/mapsdatazrh b/web/server/h2o/libh2o/deps/brotli/tests/testdata/mapsdatazrh new file mode 100644 index 00000000..03711836 Binary files /dev/null and b/web/server/h2o/libh2o/deps/brotli/tests/testdata/mapsdatazrh differ diff --git a/web/server/h2o/libh2o/deps/brotli/tests/testdata/mapsdatazrh.compressed b/web/server/h2o/libh2o/deps/brotli/tests/testdata/mapsdatazrh.compressed new file mode 100644 index 00000000..77bfa471 Binary files /dev/null and b/web/server/h2o/libh2o/deps/brotli/tests/testdata/mapsdatazrh.compressed differ diff --git a/web/server/h2o/libh2o/deps/brotli/tests/testdata/monkey b/web/server/h2o/libh2o/deps/brotli/tests/testdata/monkey new file mode 100644 index 00000000..47408cd6 --- /dev/null +++ b/web/server/h2o/libh2o/deps/brotli/tests/testdata/monkey @@ -0,0 +1 @@ +znxcvnmz,xvnm.,zxcnv.,xcn.z,vn.zvn.zxcvn.,zxcn.vn.v,znm.,vnzx.,vnzxc.vn.z,vnz.,nv.z,nvmzxc,nvzxcvcnm.,vczxvnzxcnvmxc.zmcnvzm.,nvmc,nzxmc,vn.mnnmzxc,vnxcnmv,znvzxcnmv,.xcnvm,zxcnzxv.zx,qweryweurqioweupropqwutioweupqrioweutiopweuriopweuriopqwurioputiopqwuriowuqerioupqweropuweropqwurweuqriopuropqwuriopuqwriopuqweopruioqweurqweuriouqweopruioupqiytioqtyiowtyqptypryoqweutioioqtweqruowqeytiowquiourowetyoqwupiotweuqiorweuqroipituqwiorqwtioweuriouytuioerytuioweryuitoweytuiweyuityeruirtyuqriqweuropqweiruioqweurioqwuerioqwyuituierwotueryuiotweyrtuiwertyioweryrueioqptyioruyiopqwtjkasdfhlafhlasdhfjklashjkfhasjklfhklasjdfhklasdhfjkalsdhfklasdhjkflahsjdkfhklasfhjkasdfhasfjkasdhfklsdhalghhaf;hdklasfhjklashjklfasdhfasdjklfhsdjklafsd;hkldadfjjklasdhfjasddfjklfhakjklasdjfkl;asdjfasfljasdfhjklasdfhjkaghjkashf;djfklasdjfkljasdklfjklasdjfkljasdfkljaklfj \ No newline at end of file diff --git a/web/server/h2o/libh2o/deps/brotli/tests/testdata/monkey.compressed b/web/server/h2o/libh2o/deps/brotli/tests/testdata/monkey.compressed new file mode 100644 index 00000000..bbcf1344 Binary files /dev/null and b/web/server/h2o/libh2o/deps/brotli/tests/testdata/monkey.compressed differ diff --git a/web/server/h2o/libh2o/deps/brotli/tests/testdata/plrabn12.txt b/web/server/h2o/libh2o/deps/brotli/tests/testdata/plrabn12.txt new file mode 100644 index 00000000..34088b82 --- /dev/null +++ b/web/server/h2o/libh2o/deps/brotli/tests/testdata/plrabn12.txt @@ -0,0 +1,10699 @@ + +This is the February 1992 Project Gutenberg release of: + +Paradise Lost by John Milton + +The oldest etext known to Project Gutenberg (ca. 1964-1965) +(If you know of any older ones, please let us know.) + + +Introduction (one page) + +This etext was originally created in 1964-1965 according to Dr. +Joseph Raben of Queens College, NY, to whom it is attributed by +Project Gutenberg. We had heard of this etext for years but it +was not until 1991 that we actually managed to track it down to +a specific location, and then it took months to convince people +to let us have a copy, then more months for them actually to do +the copying and get it to us. Then another month to convert to +something we could massage with our favorite 486 in DOS. After +that is was only a matter of days to get it into this shape you +will see below. The original was, of course, in CAPS only, and +so were all the other etexts of the 60's and early 70's. Don't +let anyone fool you into thinking any etext with both upper and +lower case is an original; all those original Project Gutenberg +etexts were also in upper case and were translated or rewritten +many times to get them into their current condition. They have +been worked on by many people throughout the world. + +In the course of our searches for Professor Raben and his etext +we were never able to determine where copies were or which of a +variety of editions he may have used as a source. We did get a +little information here and there, but even after we received a +copy of the etext we were unwilling to release it without first +determining that it was in fact Public Domain and finding Raben +to verify this and get his permission. Interested enough, in a +totally unrelated action to our searches for him, the professor +subscribed to the Project Gutenberg listserver and we happened, +by accident, to notice his name. (We don't really look at every +subscription request as the computers usually handle them.) The +etext was then properly identified, copyright analyzed, and the +current edition prepared. + +To give you an estimation of the difference in the original and +what we have today: the original was probably entered on cards +commonly known at the time as "IBM cards" (Do Not Fold, Spindle +or Mutilate) and probably took in excess of 100,000 of them. A +single card could hold 80 characters (hence 80 characters is an +accepted standard for so many computer margins), and the entire +original edition we received in all caps was over 800,000 chars +in length, including line enumeration, symbols for caps and the +punctuation marks, etc., since they were not available keyboard +characters at the time (probably the keyboards operated at baud +rates of around 113, meaning the typists had to type slowly for +the keyboard to keep up). + +This is the second version of Paradise Lost released by Project +Gutenberg. The first was released as our October, 1991 etext. + + + + + +Paradise Lost + + + + +Book I + + +Of Man's first disobedience, and the fruit +Of that forbidden tree whose mortal taste +Brought death into the World, and all our woe, +With loss of Eden, till one greater Man +Restore us, and regain the blissful seat, +Sing, Heavenly Muse, that, on the secret top +Of Oreb, or of Sinai, didst inspire +That shepherd who first taught the chosen seed +In the beginning how the heavens and earth +Rose out of Chaos: or, if Sion hill +Delight thee more, and Siloa's brook that flowed +Fast by the oracle of God, I thence +Invoke thy aid to my adventurous song, +That with no middle flight intends to soar +Above th' Aonian mount, while it pursues +Things unattempted yet in prose or rhyme. +And chiefly thou, O Spirit, that dost prefer +Before all temples th' upright heart and pure, +Instruct me, for thou know'st; thou from the first +Wast present, and, with mighty wings outspread, +Dove-like sat'st brooding on the vast Abyss, +And mad'st it pregnant: what in me is dark +Illumine, what is low raise and support; +That, to the height of this great argument, +I may assert Eternal Providence, +And justify the ways of God to men. + Say first--for Heaven hides nothing from thy view, +Nor the deep tract of Hell--say first what cause +Moved our grand parents, in that happy state, +Favoured of Heaven so highly, to fall off +From their Creator, and transgress his will +For one restraint, lords of the World besides. +Who first seduced them to that foul revolt? + Th' infernal Serpent; he it was whose guile, +Stirred up with envy and revenge, deceived +The mother of mankind, what time his pride +Had cast him out from Heaven, with all his host +Of rebel Angels, by whose aid, aspiring +To set himself in glory above his peers, +He trusted to have equalled the Most High, +If he opposed, and with ambitious aim +Against the throne and monarchy of God, +Raised impious war in Heaven and battle proud, +With vain attempt. Him the Almighty Power +Hurled headlong flaming from th' ethereal sky, +With hideous ruin and combustion, down +To bottomless perdition, there to dwell +In adamantine chains and penal fire, +Who durst defy th' Omnipotent to arms. + Nine times the space that measures day and night +To mortal men, he, with his horrid crew, +Lay vanquished, rolling in the fiery gulf, +Confounded, though immortal. But his doom +Reserved him to more wrath; for now the thought +Both of lost happiness and lasting pain +Torments him: round he throws his baleful eyes, +That witnessed huge affliction and dismay, +Mixed with obdurate pride and steadfast hate. +At once, as far as Angels ken, he views +The dismal situation waste and wild. +A dungeon horrible, on all sides round, +As one great furnace flamed; yet from those flames +No light; but rather darkness visible +Served only to discover sights of woe, +Regions of sorrow, doleful shades, where peace +And rest can never dwell, hope never comes +That comes to all, but torture without end +Still urges, and a fiery deluge, fed +With ever-burning sulphur unconsumed. +Such place Eternal Justice has prepared +For those rebellious; here their prison ordained +In utter darkness, and their portion set, +As far removed from God and light of Heaven +As from the centre thrice to th' utmost pole. +Oh how unlike the place from whence they fell! +There the companions of his fall, o'erwhelmed +With floods and whirlwinds of tempestuous fire, +He soon discerns; and, weltering by his side, +One next himself in power, and next in crime, +Long after known in Palestine, and named +Beelzebub. To whom th' Arch-Enemy, +And thence in Heaven called Satan, with bold words +Breaking the horrid silence, thus began:-- + "If thou beest he--but O how fallen! how changed +From him who, in the happy realms of light +Clothed with transcendent brightness, didst outshine +Myriads, though bright!--if he whom mutual league, +United thoughts and counsels, equal hope +And hazard in the glorious enterprise +Joined with me once, now misery hath joined +In equal ruin; into what pit thou seest +From what height fallen: so much the stronger proved +He with his thunder; and till then who knew +The force of those dire arms? Yet not for those, +Nor what the potent Victor in his rage +Can else inflict, do I repent, or change, +Though changed in outward lustre, that fixed mind, +And high disdain from sense of injured merit, +That with the Mightiest raised me to contend, +And to the fierce contentions brought along +Innumerable force of Spirits armed, +That durst dislike his reign, and, me preferring, +His utmost power with adverse power opposed +In dubious battle on the plains of Heaven, +And shook his throne. What though the field be lost? +All is not lost--the unconquerable will, +And study of revenge, immortal hate, +And courage never to submit or yield: +And what is else not to be overcome? +That glory never shall his wrath or might +Extort from me. To bow and sue for grace +With suppliant knee, and deify his power +Who, from the terror of this arm, so late +Doubted his empire--that were low indeed; +That were an ignominy and shame beneath +This downfall; since, by fate, the strength of Gods, +And this empyreal sybstance, cannot fail; +Since, through experience of this great event, +In arms not worse, in foresight much advanced, +We may with more successful hope resolve +To wage by force or guile eternal war, +Irreconcilable to our grand Foe, +Who now triumphs, and in th' excess of joy +Sole reigning holds the tyranny of Heaven." + So spake th' apostate Angel, though in pain, +Vaunting aloud, but racked with deep despair; +And him thus answered soon his bold compeer:-- + "O Prince, O Chief of many throned Powers +That led th' embattled Seraphim to war +Under thy conduct, and, in dreadful deeds +Fearless, endangered Heaven's perpetual King, +And put to proof his high supremacy, +Whether upheld by strength, or chance, or fate, +Too well I see and rue the dire event +That, with sad overthrow and foul defeat, +Hath lost us Heaven, and all this mighty host +In horrible destruction laid thus low, +As far as Gods and heavenly Essences +Can perish: for the mind and spirit remains +Invincible, and vigour soon returns, +Though all our glory extinct, and happy state +Here swallowed up in endless misery. +But what if he our Conqueror (whom I now +Of force believe almighty, since no less +Than such could have o'erpowered such force as ours) +Have left us this our spirit and strength entire, +Strongly to suffer and support our pains, +That we may so suffice his vengeful ire, +Or do him mightier service as his thralls +By right of war, whate'er his business be, +Here in the heart of Hell to work in fire, +Or do his errands in the gloomy Deep? +What can it the avail though yet we feel +Strength undiminished, or eternal being +To undergo eternal punishment?" + Whereto with speedy words th' Arch-Fiend replied:-- +"Fallen Cherub, to be weak is miserable, +Doing or suffering: but of this be sure-- +To do aught good never will be our task, +But ever to do ill our sole delight, +As being the contrary to his high will +Whom we resist. If then his providence +Out of our evil seek to bring forth good, +Our labour must be to pervert that end, +And out of good still to find means of evil; +Which ofttimes may succeed so as perhaps +Shall grieve him, if I fail not, and disturb +His inmost counsels from their destined aim. +But see! the angry Victor hath recalled +His ministers of vengeance and pursuit +Back to the gates of Heaven: the sulphurous hail, +Shot after us in storm, o'erblown hath laid +The fiery surge that from the precipice +Of Heaven received us falling; and the thunder, +Winged with red lightning and impetuous rage, +Perhaps hath spent his shafts, and ceases now +To bellow through the vast and boundless Deep. +Let us not slip th' occasion, whether scorn +Or satiate fury yield it from our Foe. +Seest thou yon dreary plain, forlorn and wild, +The seat of desolation, void of light, +Save what the glimmering of these livid flames +Casts pale and dreadful? Thither let us tend +From off the tossing of these fiery waves; +There rest, if any rest can harbour there; +And, re-assembling our afflicted powers, +Consult how we may henceforth most offend +Our enemy, our own loss how repair, +How overcome this dire calamity, +What reinforcement we may gain from hope, +If not, what resolution from despair." + Thus Satan, talking to his nearest mate, +With head uplift above the wave, and eyes +That sparkling blazed; his other parts besides +Prone on the flood, extended long and large, +Lay floating many a rood, in bulk as huge +As whom the fables name of monstrous size, +Titanian or Earth-born, that warred on Jove, +Briareos or Typhon, whom the den +By ancient Tarsus held, or that sea-beast +Leviathan, which God of all his works +Created hugest that swim th' ocean-stream. +Him, haply slumbering on the Norway foam, +The pilot of some small night-foundered skiff, +Deeming some island, oft, as seamen tell, +With fixed anchor in his scaly rind, +Moors by his side under the lee, while night +Invests the sea, and wished morn delays. +So stretched out huge in length the Arch-fiend lay, +Chained on the burning lake; nor ever thence +Had risen, or heaved his head, but that the will +And high permission of all-ruling Heaven +Left him at large to his own dark designs, +That with reiterated crimes he might +Heap on himself damnation, while he sought +Evil to others, and enraged might see +How all his malice served but to bring forth +Infinite goodness, grace, and mercy, shewn +On Man by him seduced, but on himself +Treble confusion, wrath, and vengeance poured. + Forthwith upright he rears from off the pool +His mighty stature; on each hand the flames +Driven backward slope their pointing spires, and,rolled +In billows, leave i' th' midst a horrid vale. +Then with expanded wings he steers his flight +Aloft, incumbent on the dusky air, +That felt unusual weight; till on dry land +He lights--if it were land that ever burned +With solid, as the lake with liquid fire, +And such appeared in hue as when the force +Of subterranean wind transprots a hill +Torn from Pelorus, or the shattered side +Of thundering Etna, whose combustible +And fuelled entrails, thence conceiving fire, +Sublimed with mineral fury, aid the winds, +And leave a singed bottom all involved +With stench and smoke. Such resting found the sole +Of unblest feet. Him followed his next mate; +Both glorying to have scaped the Stygian flood +As gods, and by their own recovered strength, +Not by the sufferance of supernal Power. + "Is this the region, this the soil, the clime," +Said then the lost Archangel, "this the seat +That we must change for Heaven?--this mournful gloom +For that celestial light? Be it so, since he +Who now is sovereign can dispose and bid +What shall be right: farthest from him is best +Whom reason hath equalled, force hath made supreme +Above his equals. Farewell, happy fields, +Where joy for ever dwells! Hail, horrors! hail, +Infernal world! and thou, profoundest Hell, +Receive thy new possessor--one who brings +A mind not to be changed by place or time. +The mind is its own place, and in itself +Can make a Heaven of Hell, a Hell of Heaven. +What matter where, if I be still the same, +And what I should be, all but less than he +Whom thunder hath made greater? Here at least +We shall be free; th' Almighty hath not built +Here for his envy, will not drive us hence: +Here we may reigh secure; and, in my choice, +To reign is worth ambition, though in Hell: +Better to reign in Hell than serve in Heaven. +But wherefore let we then our faithful friends, +Th' associates and co-partners of our loss, +Lie thus astonished on th' oblivious pool, +And call them not to share with us their part +In this unhappy mansion, or once more +With rallied arms to try what may be yet +Regained in Heaven, or what more lost in Hell?" + So Satan spake; and him Beelzebub +Thus answered:--"Leader of those armies bright +Which, but th' Omnipotent, none could have foiled! +If once they hear that voice, their liveliest pledge +Of hope in fears and dangers--heard so oft +In worst extremes, and on the perilous edge +Of battle, when it raged, in all assaults +Their surest signal--they will soon resume +New courage and revive, though now they lie +Grovelling and prostrate on yon lake of fire, +As we erewhile, astounded and amazed; +No wonder, fallen such a pernicious height!" + He scare had ceased when the superior Fiend +Was moving toward the shore; his ponderous shield, +Ethereal temper, massy, large, and round, +Behind him cast. The broad circumference +Hung on his shoulders like the moon, whose orb +Through optic glass the Tuscan artist views +At evening, from the top of Fesole, +Or in Valdarno, to descry new lands, +Rivers, or mountains, in her spotty globe. +His spear--to equal which the tallest pine +Hewn on Norwegian hills, to be the mast +Of some great ammiral, were but a wand-- +He walked with, to support uneasy steps +Over the burning marl, not like those steps +On Heaven's azure; and the torrid clime +Smote on him sore besides, vaulted with fire. +Nathless he so endured, till on the beach +Of that inflamed sea he stood, and called +His legions--Angel Forms, who lay entranced +Thick as autumnal leaves that strow the brooks +In Vallombrosa, where th' Etrurian shades +High over-arched embower; or scattered sedge +Afloat, when with fierce winds Orion armed +Hath vexed the Red-Sea coast, whose waves o'erthrew +Busiris and his Memphian chivalry, +While with perfidious hatred they pursued +The sojourners of Goshen, who beheld +From the safe shore their floating carcases +And broken chariot-wheels. So thick bestrown, +Abject and lost, lay these, covering the flood, +Under amazement of their hideous change. +He called so loud that all the hollow deep +Of Hell resounded:--"Princes, Potentates, +Warriors, the Flower of Heaven--once yours; now lost, +If such astonishment as this can seize +Eternal Spirits! Or have ye chosen this place +After the toil of battle to repose +Your wearied virtue, for the ease you find +To slumber here, as in the vales of Heaven? +Or in this abject posture have ye sworn +To adore the Conqueror, who now beholds +Cherub and Seraph rolling in the flood +With scattered arms and ensigns, till anon +His swift pursuers from Heaven-gates discern +Th' advantage, and, descending, tread us down +Thus drooping, or with linked thunderbolts +Transfix us to the bottom of this gulf? +Awake, arise, or be for ever fallen!" + They heard, and were abashed, and up they sprung +Upon the wing, as when men wont to watch +On duty, sleeping found by whom they dread, +Rouse and bestir themselves ere well awake. +Nor did they not perceive the evil plight +In which they were, or the fierce pains not feel; +Yet to their General's voice they soon obeyed +Innumerable. As when the potent rod +Of Amram's son, in Egypt's evil day, +Waved round the coast, up-called a pitchy cloud +Of locusts, warping on the eastern wind, +That o'er the realm of impious Pharaoh hung +Like Night, and darkened all the land of Nile; +So numberless were those bad Angels seen +Hovering on wing under the cope of Hell, +'Twixt upper, nether, and surrounding fires; +Till, as a signal given, th' uplifted spear +Of their great Sultan waving to direct +Their course, in even balance down they light +On the firm brimstone, and fill all the plain: +A multitude like which the populous North +Poured never from her frozen loins to pass +Rhene or the Danaw, when her barbarous sons +Came like a deluge on the South, and spread +Beneath Gibraltar to the Libyan sands. +Forthwith, form every squadron and each band, +The heads and leaders thither haste where stood +Their great Commander--godlike Shapes, and Forms +Excelling human; princely Dignities; +And Powers that erst in Heaven sat on thrones, +Though on their names in Heavenly records now +Be no memorial, blotted out and rased +By their rebellion from the Books of Life. +Nor had they yet among the sons of Eve +Got them new names, till, wandering o'er the earth, +Through God's high sufferance for the trial of man, +By falsities and lies the greatest part +Of mankind they corrupted to forsake +God their Creator, and th' invisible +Glory of him that made them to transform +Oft to the image of a brute, adorned +With gay religions full of pomp and gold, +And devils to adore for deities: +Then were they known to men by various names, +And various idols through the heathen world. + Say, Muse, their names then known, who first, who last, +Roused from the slumber on that fiery couch, +At their great Emperor's call, as next in worth +Came singly where he stood on the bare strand, +While the promiscuous crowd stood yet aloof? + The chief were those who, from the pit of Hell +Roaming to seek their prey on Earth, durst fix +Their seats, long after, next the seat of God, +Their altars by his altar, gods adored +Among the nations round, and durst abide +Jehovah thundering out of Sion, throned +Between the Cherubim; yea, often placed +Within his sanctuary itself their shrines, +Abominations; and with cursed things +His holy rites and solemn feasts profaned, +And with their darkness durst affront his light. +First, Moloch, horrid king, besmeared with blood +Of human sacrifice, and parents' tears; +Though, for the noise of drums and timbrels loud, +Their children's cries unheard that passed through fire +To his grim idol. Him the Ammonite +Worshiped in Rabba and her watery plain, +In Argob and in Basan, to the stream +Of utmost Arnon. Nor content with such +Audacious neighbourhood, the wisest heart +Of Solomon he led by fraoud to build +His temple right against the temple of God +On that opprobrious hill, and made his grove +The pleasant valley of Hinnom, Tophet thence +And black Gehenna called, the type of Hell. +Next Chemos, th' obscene dread of Moab's sons, +From Aroar to Nebo and the wild +Of southmost Abarim; in Hesebon +And Horonaim, Seon's real, beyond +The flowery dale of Sibma clad with vines, +And Eleale to th' Asphaltic Pool: +Peor his other name, when he enticed +Israel in Sittim, on their march from Nile, +To do him wanton rites, which cost them woe. +Yet thence his lustful orgies he enlarged +Even to that hill of scandal, by the grove +Of Moloch homicide, lust hard by hate, +Till good Josiah drove them thence to Hell. +With these came they who, from the bordering flood +Of old Euphrates to the brook that parts +Egypt from Syrian ground, had general names +Of Baalim and Ashtaroth--those male, +These feminine. For Spirits, when they please, +Can either sex assume, or both; so soft +And uncompounded is their essence pure, +Not tried or manacled with joint or limb, +Nor founded on the brittle strength of bones, +Like cumbrous flesh; but, in what shape they choose, +Dilated or condensed, bright or obscure, +Can execute their airy purposes, +And works of love or enmity fulfil. +For those the race of Israel oft forsook +Their Living Strength, and unfrequented left +His righteous altar, bowing lowly down +To bestial gods; for which their heads as low +Bowed down in battle, sunk before the spear +Of despicable foes. With these in troop +Came Astoreth, whom the Phoenicians called +Astarte, queen of heaven, with crescent horns; +To whose bright image nigntly by the moon +Sidonian virgins paid their vows and songs; +In Sion also not unsung, where stood +Her temple on th' offensive mountain, built +By that uxorious king whose heart, though large, +Beguiled by fair idolatresses, fell +To idols foul. Thammuz came next behind, +Whose annual wound in Lebanon allured +The Syrian damsels to lament his fate +In amorous ditties all a summer's day, +While smooth Adonis from his native rock +Ran purple to the sea, supposed with blood +Of Thammuz yearly wounded: the love-tale +Infected Sion's daughters with like heat, +Whose wanton passions in the sacred proch +Ezekiel saw, when, by the vision led, +His eye surveyed the dark idolatries +Of alienated Judah. Next came one +Who mourned in earnest, when the captive ark +Maimed his brute image, head and hands lopt off, +In his own temple, on the grunsel-edge, +Where he fell flat and shamed his worshippers: +Dagon his name, sea-monster,upward man +And downward fish; yet had his temple high +Reared in Azotus, dreaded through the coast +Of Palestine, in Gath and Ascalon, +And Accaron and Gaza's frontier bounds. +Him followed Rimmon, whose delightful seat +Was fair Damascus, on the fertile banks +Of Abbana and Pharphar, lucid streams. +He also against the house of God was bold: +A leper once he lost, and gained a king-- +Ahaz, his sottish conqueror, whom he drew +God's altar to disparage and displace +For one of Syrian mode, whereon to burn +His odious offerings, and adore the gods +Whom he had vanquished. After these appeared +A crew who, under names of old renown-- +Osiris, Isis, Orus, and their train-- +With monstrous shapes and sorceries abused +Fanatic Egypt and her priests to seek +Their wandering gods disguised in brutish forms +Rather than human. Nor did Israel scape +Th' infection, when their borrowed gold composed +The calf in Oreb; and the rebel king +Doubled that sin in Bethel and in Dan, +Likening his Maker to the grazed ox-- +Jehovah, who, in one night, when he passed +From Egypt marching, equalled with one stroke +Both her first-born and all her bleating gods. +Belial came last; than whom a Spirit more lewd +Fell not from Heaven, or more gross to love +Vice for itself. To him no temple stood +Or altar smoked; yet who more oft than he +In temples and at altars, when the priest +Turns atheist, as did Eli's sons, who filled +With lust and violence the house of God? +In courts and palaces he also reigns, +And in luxurious cities, where the noise +Of riot ascends above their loftiest towers, +And injury and outrage; and, when night +Darkens the streets, then wander forth the sons +Of Belial, flown with insolence and wine. +Witness the streets of Sodom, and that night +In Gibeah, when the hospitable door +Exposed a matron, to avoid worse rape. + These were the prime in order and in might: +The rest were long to tell; though far renowned +Th' Ionian gods--of Javan's issue held +Gods, yet confessed later than Heaven and Earth, +Their boasted parents;--Titan, Heaven's first-born, +With his enormous brood, and birthright seized +By younger Saturn: he from mightier Jove, +His own and Rhea's son, like measure found; +So Jove usurping reigned. These, first in Crete +And Ida known, thence on the snowy top +Of cold Olympus ruled the middle air, +Their highest heaven; or on the Delphian cliff, +Or in Dodona, and through all the bounds +Of Doric land; or who with Saturn old +Fled over Adria to th' Hesperian fields, +And o'er the Celtic roamed the utmost Isles. + All these and more came flocking; but with looks +Downcast and damp; yet such wherein appeared +Obscure some glimpse of joy to have found their Chief +Not in despair, to have found themselves not lost +In loss itself; which on his countenance cast +Like doubtful hue. But he, his wonted pride +Soon recollecting, with high words, that bore +Semblance of worth, not substance, gently raised +Their fainting courage, and dispelled their fears. +Then straight commands that, at the warlike sound +Of trumpets loud and clarions, be upreared +His mighty standard. That proud honour claimed +Azazel as his right, a Cherub tall: +Who forthwith from the glittering staff unfurled +Th' imperial ensign; which, full high advanced, +Shone like a meteor streaming to the wind, +With gems and golden lustre rich emblazed, +Seraphic arms and trophies; all the while +Sonorous metal blowing martial sounds: +At which the universal host up-sent +A shout that tore Hell's concave, and beyond +Frighted the reign of Chaos and old Night. +All in a moment through the gloom were seen +Ten thousand banners rise into the air, +With orient colours waving: with them rose +A forest huge of spears; and thronging helms +Appeared, and serried shields in thick array +Of depth immeasurable. Anon they move +In perfect phalanx to the Dorian mood +Of flutes and soft recorders--such as raised +To height of noblest temper heroes old +Arming to battle, and instead of rage +Deliberate valour breathed, firm, and unmoved +With dread of death to flight or foul retreat; +Nor wanting power to mitigate and swage +With solemn touches troubled thoughts, and chase +Anguish and doubt and fear and sorrow and pain +From mortal or immortal minds. Thus they, +Breathing united force with fixed thought, +Moved on in silence to soft pipes that charmed +Their painful steps o'er the burnt soil. And now +Advanced in view they stand--a horrid front +Of dreadful length and dazzling arms, in guise +Of warriors old, with ordered spear and shield, +Awaiting what command their mighty Chief +Had to impose. He through the armed files +Darts his experienced eye, and soon traverse +The whole battalion views--their order due, +Their visages and stature as of gods; +Their number last he sums. And now his heart +Distends with pride, and, hardening in his strength, +Glories: for never, since created Man, +Met such embodied force as, named with these, +Could merit more than that small infantry +Warred on by cranes--though all the giant brood +Of Phlegra with th' heroic race were joined +That fought at Thebes and Ilium, on each side +Mixed with auxiliar gods; and what resounds +In fable or romance of Uther's son, +Begirt with British and Armoric knights; +And all who since, baptized or infidel, +Jousted in Aspramont, or Montalban, +Damasco, or Marocco, or Trebisond, +Or whom Biserta sent from Afric shore +When Charlemain with all his peerage fell +By Fontarabbia. Thus far these beyond +Compare of mortal prowess, yet observed +Their dread Commander. He, above the rest +In shape and gesture proudly eminent, +Stood like a tower. His form had yet not lost +All her original brightness, nor appeared +Less than Archangel ruined, and th' excess +Of glory obscured: as when the sun new-risen +Looks through the horizontal misty air +Shorn of his beams, or, from behind the moon, +In dim eclipse, disastrous twilight sheds +On half the nations, and with fear of change +Perplexes monarchs. Darkened so, yet shone +Above them all th' Archangel: but his face +Deep scars of thunder had intrenched, and care +Sat on his faded cheek, but under brows +Of dauntless courage, and considerate pride +Waiting revenge. Cruel his eye, but cast +Signs of remorse and passion, to behold +The fellows of his crime, the followers rather +(Far other once beheld in bliss), condemned +For ever now to have their lot in pain-- +Millions of Spirits for his fault amerced +Of Heaven, and from eteranl splendours flung +For his revolt--yet faithful how they stood, +Their glory withered; as, when heaven's fire +Hath scathed the forest oaks or mountain pines, +With singed top their stately growth, though bare, +Stands on the blasted heath. He now prepared +To speak; whereat their doubled ranks they bend +From wing to wing, and half enclose him round +With all his peers: attention held them mute. +Thrice he assayed, and thrice, in spite of scorn, +Tears, such as Angels weep, burst forth: at last +Words interwove with sighs found out their way:-- + "O myriads of immortal Spirits! O Powers +Matchless, but with th' Almighth!--and that strife +Was not inglorious, though th' event was dire, +As this place testifies, and this dire change, +Hateful to utter. But what power of mind, +Forseeing or presaging, from the depth +Of knowledge past or present, could have feared +How such united force of gods, how such +As stood like these, could ever know repulse? +For who can yet believe, though after loss, +That all these puissant legions, whose exile +Hath emptied Heaven, shall fail to re-ascend, +Self-raised, and repossess their native seat? +For me, be witness all the host of Heaven, +If counsels different, or danger shunned +By me, have lost our hopes. But he who reigns +Monarch in Heaven till then as one secure +Sat on his throne, upheld by old repute, +Consent or custom, and his regal state +Put forth at full, but still his strength concealed-- +Which tempted our attempt, and wrought our fall. +Henceforth his might we know, and know our own, +So as not either to provoke, or dread +New war provoked: our better part remains +To work in close design, by fraud or guile, +What force effected not; that he no less +At length from us may find, who overcomes +By force hath overcome but half his foe. +Space may produce new Worlds; whereof so rife +There went a fame in Heaven that he ere long +Intended to create, and therein plant +A generation whom his choice regard +Should favour equal to the Sons of Heaven. +Thither, if but to pry, shall be perhaps +Our first eruption--thither, or elsewhere; +For this infernal pit shall never hold +Celestial Spirits in bondage, nor th' Abyss +Long under darkness cover. But these thoughts +Full counsel must mature. Peace is despaired; +For who can think submission? War, then, war +Open or understood, must be resolved." + He spake; and, to confirm his words, outflew +Millions of flaming swords, drawn from the thighs +Of mighty Cherubim; the sudden blaze +Far round illumined Hell. Highly they raged +Against the Highest, and fierce with grasped arms +Clashed on their sounding shields the din of war, +Hurling defiance toward the vault of Heaven. + There stood a hill not far, whose grisly top +Belched fire and rolling smoke; the rest entire +Shone with a glossy scurf--undoubted sign +That in his womb was hid metallic ore, +The work of sulphur. Thither, winged with speed, +A numerous brigade hastened: as when bands +Of pioneers, with spade and pickaxe armed, +Forerun the royal camp, to trench a field, +Or cast a rampart. Mammon led them on-- +Mammon, the least erected Spirit that fell +From Heaven; for even in Heaven his looks and thoughts +Were always downward bent, admiring more +The riches of heaven's pavement, trodden gold, +Than aught divine or holy else enjoyed +In vision beatific. By him first +Men also, and by his suggestion taught, +Ransacked the centre, and with impious hands +Rifled the bowels of their mother Earth +For treasures better hid. Soon had his crew +Opened into the hill a spacious wound, +And digged out ribs of gold. Let none admire +That riches grow in Hell; that soil may best +Deserve the precious bane. And here let those +Who boast in mortal things, and wondering tell +Of Babel, and the works of Memphian kings, +Learn how their greatest monuments of fame +And strength, and art, are easily outdone +By Spirits reprobate, and in an hour +What in an age they, with incessant toil +And hands innumerable, scarce perform. +Nigh on the plain, in many cells prepared, +That underneath had veins of liquid fire +Sluiced from the lake, a second multitude +With wondrous art founded the massy ore, +Severing each kind, and scummed the bullion-dross. +A third as soon had formed within the ground +A various mould, and from the boiling cells +By strange conveyance filled each hollow nook; +As in an organ, from one blast of wind, +To many a row of pipes the sound-board breathes. +Anon out of the earth a fabric huge +Rose like an exhalation, with the sound +Of dulcet symphonies and voices sweet-- +Built like a temple, where pilasters round +Were set, and Doric pillars overlaid +With golden architrave; nor did there want +Cornice or frieze, with bossy sculptures graven; +The roof was fretted gold. Not Babylon +Nor great Alcairo such magnificence +Equalled in all their glories, to enshrine +Belus or Serapis their gods, or seat +Their kings, when Egypt with Assyria strove +In wealth and luxury. Th' ascending pile +Stood fixed her stately height, and straight the doors, +Opening their brazen folds, discover, wide +Within, her ample spaces o'er the smooth +And level pavement: from the arched roof, +Pendent by subtle magic, many a row +Of starry lamps and blazing cressets, fed +With naptha and asphaltus, yielded light +As from a sky. The hasty multitude +Admiring entered; and the work some praise, +And some the architect. His hand was known +In Heaven by many a towered structure high, +Where sceptred Angels held their residence, +And sat as Princes, whom the supreme King +Exalted to such power, and gave to rule, +Each in his Hierarchy, the Orders bright. +Nor was his name unheard or unadored +In ancient Greece; and in Ausonian land +Men called him Mulciber; and how he fell +From Heaven they fabled, thrown by angry Jove +Sheer o'er the crystal battlements: from morn +To noon he fell, from noon to dewy eve, +A summer's day, and with the setting sun +Dropt from the zenith, like a falling star, +On Lemnos, th' Aegaean isle. Thus they relate, +Erring; for he with this rebellious rout +Fell long before; nor aught aviled him now +To have built in Heaven high towers; nor did he scape +By all his engines, but was headlong sent, +With his industrious crew, to build in Hell. + Meanwhile the winged Heralds, by command +Of sovereign power, with awful ceremony +And trumpet's sound, throughout the host proclaim +A solemn council forthwith to be held +At Pandemonium, the high capital +Of Satan and his peers. Their summons called +From every band and squared regiment +By place or choice the worthiest: they anon +With hundreds and with thousands trooping came +Attended. All access was thronged; the gates +And porches wide, but chief the spacious hall +(Though like a covered field, where champions bold +Wont ride in armed, and at the Soldan's chair +Defied the best of Paynim chivalry +To mortal combat, or career with lance), +Thick swarmed, both on the ground and in the air, +Brushed with the hiss of rustling wings. As bees +In spring-time, when the Sun with Taurus rides. +Pour forth their populous youth about the hive +In clusters; they among fresh dews and flowers +Fly to and fro, or on the smoothed plank, +The suburb of their straw-built citadel, +New rubbed with balm, expatiate, and confer +Their state-affairs: so thick the airy crowd +Swarmed and were straitened; till, the signal given, +Behold a wonder! They but now who seemed +In bigness to surpass Earth's giant sons, +Now less than smallest dwarfs, in narrow room +Throng numberless--like that pygmean race +Beyond the Indian mount; or faery elves, +Whose midnight revels, by a forest-side +Or fountain, some belated peasant sees, +Or dreams he sees, while overhead the Moon +Sits arbitress, and nearer to the Earth +Wheels her pale course: they, on their mirth and dance +Intent, with jocund music charm his ear; +At once with joy and fear his heart rebounds. +Thus incorporeal Spirits to smallest forms +Reduced their shapes immense, and were at large, +Though without number still, amidst the hall +Of that infernal court. But far within, +And in their own dimensions like themselves, +The great Seraphic Lords and Cherubim +In close recess and secret conclave sat, +A thousand demi-gods on golden seats, +Frequent and full. After short silence then, +And summons read, the great consult began. + + + +Book II + + +High on a throne of royal state, which far +Outshone the wealth or Ormus and of Ind, +Or where the gorgeous East with richest hand +Showers on her kings barbaric pearl and gold, +Satan exalted sat, by merit raised +To that bad eminence; and, from despair +Thus high uplifted beyond hope, aspires +Beyond thus high, insatiate to pursue +Vain war with Heaven; and, by success untaught, +His proud imaginations thus displayed:-- + "Powers and Dominions, Deities of Heaven!-- +For, since no deep within her gulf can hold +Immortal vigour, though oppressed and fallen, +I give not Heaven for lost: from this descent +Celestial Virtues rising will appear +More glorious and more dread than from no fall, +And trust themselves to fear no second fate!-- +Me though just right, and the fixed laws of Heaven, +Did first create your leader--next, free choice +With what besides in council or in fight +Hath been achieved of merit--yet this loss, +Thus far at least recovered, hath much more +Established in a safe, unenvied throne, +Yielded with full consent. The happier state +In Heaven, which follows dignity, might draw +Envy from each inferior; but who here +Will envy whom the highest place exposes +Foremost to stand against the Thunderer's aim +Your bulwark, and condemns to greatest share +Of endless pain? Where there is, then, no good +For which to strive, no strife can grow up there +From faction: for none sure will claim in Hell +Precedence; none whose portion is so small +Of present pain that with ambitious mind +Will covet more! With this advantage, then, +To union, and firm faith, and firm accord, +More than can be in Heaven, we now return +To claim our just inheritance of old, +Surer to prosper than prosperity +Could have assured us; and by what best way, +Whether of open war or covert guile, +We now debate. Who can advise may speak." + He ceased; and next him Moloch, sceptred king, +Stood up--the strongest and the fiercest Spirit +That fought in Heaven, now fiercer by despair. +His trust was with th' Eternal to be deemed +Equal in strength, and rather than be less +Cared not to be at all; with that care lost +Went all his fear: of God, or Hell, or worse, +He recked not, and these words thereafter spake:-- + "My sentence is for open war. Of wiles, +More unexpert, I boast not: them let those +Contrive who need, or when they need; not now. +For, while they sit contriving, shall the rest-- +Millions that stand in arms, and longing wait +The signal to ascend--sit lingering here, +Heaven's fugitives, and for their dwelling-place +Accept this dark opprobrious den of shame, +The prison of his ryranny who reigns +By our delay? No! let us rather choose, +Armed with Hell-flames and fury, all at once +O'er Heaven's high towers to force resistless way, +Turning our tortures into horrid arms +Against the Torturer; when, to meet the noise +Of his almighty engine, he shall hear +Infernal thunder, and, for lightning, see +Black fire and horror shot with equal rage +Among his Angels, and his throne itself +Mixed with Tartarean sulphur and strange fire, +His own invented torments. But perhaps +The way seems difficult, and steep to scale +With upright wing against a higher foe! +Let such bethink them, if the sleepy drench +Of that forgetful lake benumb not still, +That in our porper motion we ascend +Up to our native seat; descent and fall +To us is adverse. Who but felt of late, +When the fierce foe hung on our broken rear +Insulting, and pursued us through the Deep, +With what compulsion and laborious flight +We sunk thus low? Th' ascent is easy, then; +Th' event is feared! Should we again provoke +Our stronger, some worse way his wrath may find +To our destruction, if there be in Hell +Fear to be worse destroyed! What can be worse +Than to dwell here, driven out from bliss, condemned +In this abhorred deep to utter woe! +Where pain of unextinguishable fire +Must exercise us without hope of end +The vassals of his anger, when the scourge +Inexorably, and the torturing hour, +Calls us to penance? More destroyed than thus, +We should be quite abolished, and expire. +What fear we then? what doubt we to incense +His utmost ire? which, to the height enraged, +Will either quite consume us, and reduce +To nothing this essential--happier far +Than miserable to have eternal being!-- +Or, if our substance be indeed divine, +And cannot cease to be, we are at worst +On this side nothing; and by proof we feel +Our power sufficient to disturb his Heaven, +And with perpetual inroads to alarm, +Though inaccessible, his fatal throne: +Which, if not victory, is yet revenge." + He ended frowning, and his look denounced +Desperate revenge, and battle dangerous +To less than gods. On th' other side up rose +Belial, in act more graceful and humane. +A fairer person lost not Heaven; he seemed +For dignity composed, and high exploit. +But all was false and hollow; though his tongue +Dropped manna, and could make the worse appear +The better reason, to perplex and dash +Maturest counsels: for his thoughts were low-- + To vice industrious, but to nobler deeds +Timorous and slothful. Yet he pleased the ear, +And with persuasive accent thus began:-- + "I should be much for open war, O Peers, +As not behind in hate, if what was urged +Main reason to persuade immediate war +Did not dissuade me most, and seem to cast +Ominous conjecture on the whole success; +When he who most excels in fact of arms, +In what he counsels and in what excels +Mistrustful, grounds his courage on despair +And utter dissolution, as the scope +Of all his aim, after some dire revenge. +First, what revenge? The towers of Heaven are filled +With armed watch, that render all access +Impregnable: oft on the bodering Deep +Encamp their legions, or with obscure wing +Scout far and wide into the realm of Night, +Scorning surprise. Or, could we break our way +By force, and at our heels all Hell should rise +With blackest insurrection to confound +Heaven's purest light, yet our great Enemy, +All incorruptible, would on his throne +Sit unpolluted, and th' ethereal mould, +Incapable of stain, would soon expel +Her mischief, and purge off the baser fire, +Victorious. Thus repulsed, our final hope +Is flat despair: we must exasperate +Th' Almighty Victor to spend all his rage; +And that must end us; that must be our cure-- +To be no more. Sad cure! for who would lose, +Though full of pain, this intellectual being, +Those thoughts that wander through eternity, +To perish rather, swallowed up and lost +In the wide womb of uncreated Night, +Devoid of sense and motion? And who knows, +Let this be good, whether our angry Foe +Can give it, or will ever? How he can +Is doubtful; that he never will is sure. +Will he, so wise, let loose at once his ire, +Belike through impotence or unaware, +To give his enemies their wish, and end +Them in his anger whom his anger saves +To punish endless? 'Wherefore cease we, then?' +Say they who counsel war; 'we are decreed, +Reserved, and destined to eternal woe; +Whatever doing, what can we suffer more, +What can we suffer worse?' Is this, then, worst-- +Thus sitting, thus consulting, thus in arms? +What when we fled amain, pursued and struck +With Heaven's afflicting thunder, and besought +The Deep to shelter us? This Hell then seemed +A refuge from those wounds. Or when we lay +Chained on the burning lake? That sure was worse. +What if the breath that kindled those grim fires, +Awaked, should blow them into sevenfold rage, +And plunge us in the flames; or from above +Should intermitted vengeance arm again +His red right hand to plague us? What if all +Her stores were opened, and this firmament +Of Hell should spout her cataracts of fire, +Impendent horrors, threatening hideous fall +One day upon our heads; while we perhaps, +Designing or exhorting glorious war, +Caught in a fiery tempest, shall be hurled, +Each on his rock transfixed, the sport and prey +Or racking whirlwinds, or for ever sunk +Under yon boiling ocean, wrapt in chains, +There to converse with everlasting groans, +Unrespited, unpitied, unreprieved, +Ages of hopeless end? This would be worse. +War, therefore, open or concealed, alike +My voice dissuades; for what can force or guile +With him, or who deceive his mind, whose eye +Views all things at one view? He from Heaven's height +All these our motions vain sees and derides, +Not more almighty to resist our might +Than wise to frustrate all our plots and wiles. +Shall we, then, live thus vile--the race of Heaven +Thus trampled, thus expelled, to suffer here +Chains and these torments? Better these than worse, +By my advice; since fate inevitable +Subdues us, and omnipotent decree, +The Victor's will. To suffer, as to do, +Our strength is equal; nor the law unjust +That so ordains. This was at first resolved, +If we were wise, against so great a foe +Contending, and so doubtful what might fall. +I laugh when those who at the spear are bold +And venturous, if that fail them, shrink, and fear +What yet they know must follow--to endure +Exile, or igominy, or bonds, or pain, +The sentence of their Conqueror. This is now +Our doom; which if we can sustain and bear, +Our Supreme Foe in time may much remit +His anger, and perhaps, thus far removed, +Not mind us not offending, satisfied +With what is punished; whence these raging fires +Will slacken, if his breath stir not their flames. +Our purer essence then will overcome +Their noxious vapour; or, inured, not feel; +Or, changed at length, and to the place conformed +In temper and in nature, will receive +Familiar the fierce heat; and, void of pain, +This horror will grow mild, this darkness light; +Besides what hope the never-ending flight +Of future days may bring, what chance, what change +Worth waiting--since our present lot appears +For happy though but ill, for ill not worst, +If we procure not to ourselves more woe." + Thus Belial, with words clothed in reason's garb, +Counselled ignoble ease and peaceful sloth, +Not peace; and after him thus Mammon spake:-- + "Either to disenthrone the King of Heaven +We war, if war be best, or to regain +Our own right lost. Him to unthrone we then +May hope, when everlasting Fate shall yield +To fickle Chance, and Chaos judge the strife. +The former, vain to hope, argues as vain +The latter; for what place can be for us +Within Heaven's bound, unless Heaven's Lord supreme +We overpower? Suppose he should relent +And publish grace to all, on promise made +Of new subjection; with what eyes could we +Stand in his presence humble, and receive +Strict laws imposed, to celebrate his throne +With warbled hyms, and to his Godhead sing +Forced hallelujahs, while he lordly sits +Our envied sovereign, and his altar breathes +Ambrosial odours and ambrosial flowers, +Our servile offerings? This must be our task +In Heaven, this our delight. How wearisome +Eternity so spent in worship paid +To whom we hate! Let us not then pursue, +By force impossible, by leave obtained +Unacceptable, though in Heaven, our state +Of splendid vassalage; but rather seek +Our own good from ourselves, and from our own +Live to ourselves, though in this vast recess, +Free and to none accountable, preferring +Hard liberty before the easy yoke +Of servile pomp. Our greatness will appear +Then most conspicuous when great things of small, +Useful of hurtful, prosperous of adverse, +We can create, and in what place soe'er +Thrive under evil, and work ease out of pain +Through labour and endurance. This deep world +Of darkness do we dread? How oft amidst +Thick clouds and dark doth Heaven's all-ruling Sire +Choose to reside, his glory unobscured, +And with the majesty of darkness round +Covers his throne, from whence deep thunders roar. +Mustering their rage, and Heaven resembles Hell! +As he our darkness, cannot we his light +Imitate when we please? This desert soil +Wants not her hidden lustre, gems and gold; +Nor want we skill or art from whence to raise +Magnificence; and what can Heaven show more? +Our torments also may, in length of time, +Become our elements, these piercing fires +As soft as now severe, our temper changed +Into their temper; which must needs remove +The sensible of pain. All things invite +To peaceful counsels, and the settled state +Of order, how in safety best we may +Compose our present evils, with regard +Of what we are and where, dismissing quite +All thoughts of war. Ye have what I advise." + He scarce had finished, when such murmur filled +Th' assembly as when hollow rocks retain +The sound of blustering winds, which all night long +Had roused the sea, now with hoarse cadence lull +Seafaring men o'erwatched, whose bark by chance +Or pinnace, anchors in a craggy bay +After the tempest. Such applause was heard +As Mammon ended, and his sentence pleased, +Advising peace: for such another field +They dreaded worse than Hell; so much the fear +Of thunder and the sword of Michael +Wrought still within them; and no less desire +To found this nether empire, which might rise, +By policy and long process of time, +In emulation opposite to Heaven. +Which when Beelzebub perceived--than whom, +Satan except, none higher sat--with grave +Aspect he rose, and in his rising seemed +A pillar of state. Deep on his front engraven +Deliberation sat, and public care; +And princely counsel in his face yet shone, +Majestic, though in ruin. Sage he stood +With Atlantean shoulders, fit to bear +The weight of mightiest monarchies; his look +Drew audience and attention still as night +Or summer's noontide air, while thus he spake:-- + "Thrones and Imperial Powers, Offspring of Heaven, +Ethereal Virtues! or these titles now +Must we renounce, and, changing style, be called +Princes of Hell? for so the popular vote +Inclines--here to continue, and build up here +A growing empire; doubtless! while we dream, +And know not that the King of Heaven hath doomed +This place our dungeon, not our safe retreat +Beyond his potent arm, to live exempt +From Heaven's high jurisdiction, in new league +Banded against his throne, but to remain +In strictest bondage, though thus far removed, +Under th' inevitable curb, reserved +His captive multitude. For he, to be sure, +In height or depth, still first and last will reign +Sole king, and of his kingdom lose no part +By our revolt, but over Hell extend +His empire, and with iron sceptre rule +Us here, as with his golden those in Heaven. +What sit we then projecting peace and war? +War hath determined us and foiled with loss +Irreparable; terms of peace yet none +Vouchsafed or sought; for what peace will be given +To us enslaved, but custody severe, +And stripes and arbitrary punishment +Inflicted? and what peace can we return, +But, to our power, hostility and hate, +Untamed reluctance, and revenge, though slow, +Yet ever plotting how the Conqueror least +May reap his conquest, and may least rejoice +In doing what we most in suffering feel? +Nor will occasion want, nor shall we need +With dangerous expedition to invade +Heaven, whose high walls fear no assault or siege, +Or ambush from the Deep. What if we find +Some easier enterprise? There is a place +(If ancient and prophetic fame in Heaven +Err not)--another World, the happy seat +Of some new race, called Man, about this time +To be created like to us, though less +In power and excellence, but favoured more +Of him who rules above; so was his will +Pronounced among the Gods, and by an oath +That shook Heaven's whole circumference confirmed. +Thither let us bend all our thoughts, to learn +What creatures there inhabit, of what mould +Or substance, how endued, and what their power +And where their weakness: how attempted best, +By force of subtlety. Though Heaven be shut, +And Heaven's high Arbitrator sit secure +In his own strength, this place may lie exposed, +The utmost border of his kingdom, left +To their defence who hold it: here, perhaps, +Some advantageous act may be achieved +By sudden onset--either with Hell-fire +To waste his whole creation, or possess +All as our own, and drive, as we were driven, +The puny habitants; or, if not drive, +Seduce them to our party, that their God +May prove their foe, and with repenting hand +Abolish his own works. This would surpass +Common revenge, and interrupt his joy +In our confusion, and our joy upraise +In his disturbance; when his darling sons, +Hurled headlong to partake with us, shall curse +Their frail original, and faded bliss-- +Faded so soon! Advise if this be worth +Attempting, or to sit in darkness here +Hatching vain empires." Thus beelzebub +Pleaded his devilish counsel--first devised +By Satan, and in part proposed: for whence, +But from the author of all ill, could spring +So deep a malice, to confound the race +Of mankind in one root, and Earth with Hell +To mingle and involve, done all to spite +The great Creator? But their spite still serves +His glory to augment. The bold design +Pleased highly those infernal States, and joy +Sparkled in all their eyes: with full assent +They vote: whereat his speech he thus renews:-- +"Well have ye judged, well ended long debate, +Synod of Gods, and, like to what ye are, +Great things resolved, which from the lowest deep +Will once more lift us up, in spite of fate, +Nearer our ancient seat--perhaps in view +Of those bright confines, whence, with neighbouring arms, +And opportune excursion, we may chance +Re-enter Heaven; or else in some mild zone +Dwell, not unvisited of Heaven's fair light, +Secure, and at the brightening orient beam +Purge off this gloom: the soft delicious air, +To heal the scar of these corrosive fires, +Shall breathe her balm. But, first, whom shall we send +In search of this new World? whom shall we find +Sufficient? who shall tempt with wandering feet +The dark, unbottomed, infinite Abyss, +And through the palpable obscure find out +His uncouth way, or spread his airy flight, +Upborne with indefatigable wings +Over the vast abrupt, ere he arrive +The happy Isle? What strength, what art, can then +Suffice, or what evasion bear him safe, +Through the strict senteries and stations thick +Of Angels watching round? Here he had need +All circumspection: and we now no less +Choice in our suffrage; for on whom we send +The weight of all, and our last hope, relies." + This said, he sat; and expectation held +His look suspense, awaiting who appeared +To second, or oppose, or undertake +The perilous attempt. But all sat mute, +Pondering the danger with deep thoughts; and each +In other's countenance read his own dismay, +Astonished. None among the choice and prime +Of those Heaven-warring champions could be found +So hardy as to proffer or accept, +Alone, the dreadful voyage; till, at last, +Satan, whom now transcendent glory raised +Above his fellows, with monarchal pride +Conscious of highest worth, unmoved thus spake:-- + "O Progeny of Heaven! Empyreal Thrones! +With reason hath deep silence and demur +Seized us, though undismayed. Long is the way +And hard, that out of Hell leads up to light. +Our prison strong, this huge convex of fire, +Outrageous to devour, immures us round +Ninefold; and gates of burning adamant, +Barred over us, prohibit all egress. +These passed, if any pass, the void profound +Of unessential Night receives him next, +Wide-gaping, and with utter loss of being +Threatens him, plunged in that abortive gulf. +If thence he scape, into whatever world, +Or unknown region, what remains him less +Than unknown dangers, and as hard escape? +But I should ill become this throne, O Peers, +And this imperial sovereignty, adorned +With splendour, armed with power, if aught proposed +And judged of public moment in the shape +Of difficulty or danger, could deter +Me from attempting. Wherefore do I assume +These royalties, and not refuse to reign, +Refusing to accept as great a share +Of hazard as of honour, due alike +To him who reigns, and so much to him due +Of hazard more as he above the rest +High honoured sits? Go, therefore, mighty Powers, +Terror of Heaven, though fallen; intend at home, +While here shall be our home, what best may ease +The present misery, and render Hell +More tolerable; if there be cure or charm +To respite, or deceive, or slack the pain +Of this ill mansion: intermit no watch +Against a wakeful foe, while I abroad +Through all the coasts of dark destruction seek +Deliverance for us all. This enterprise +None shall partake with me." Thus saying, rose +The Monarch, and prevented all reply; +Prudent lest, from his resolution raised, +Others among the chief might offer now, +Certain to be refused, what erst they feared, +And, so refused, might in opinion stand +His rivals, winning cheap the high repute +Which he through hazard huge must earn. But they +Dreaded not more th' adventure than his voice +Forbidding; and at once with him they rose. +Their rising all at once was as the sound +Of thunder heard remote. Towards him they bend +With awful reverence prone, and as a God +Extol him equal to the Highest in Heaven. +Nor failed they to express how much they praised +That for the general safety he despised +His own: for neither do the Spirits damned +Lose all their virtue; lest bad men should boast +Their specious deeds on earth, which glory excites, +Or close ambition varnished o'er with zeal. + Thus they their doubtful consultations dark +Ended, rejoicing in their matchless Chief: +As, when from mountain-tops the dusky clouds +Ascending, while the north wind sleeps, o'erspread +Heaven's cheerful face, the louring element +Scowls o'er the darkened landscape snow or shower, +If chance the radiant sun, with farewell sweet, +Extend his evening beam, the fields revive, +The birds their notes renew, and bleating herds +Attest their joy, that hill and valley rings. +O shame to men! Devil with devil damned +Firm concord holds; men only disagree +Of creatures rational, though under hope +Of heavenly grace, and, God proclaiming peace, +Yet live in hatred, enmity, and strife +Among themselves, and levy cruel wars +Wasting the earth, each other to destroy: +As if (which might induce us to accord) +Man had not hellish foes enow besides, +That day and night for his destruction wait! + The Stygian council thus dissolved; and forth +In order came the grand infernal Peers: +Midst came their mighty Paramount, and seemed +Alone th' antagonist of Heaven, nor less +Than Hell's dread Emperor, with pomp supreme, +And god-like imitated state: him round +A globe of fiery Seraphim enclosed +With bright emblazonry, and horrent arms. +Then of their session ended they bid cry +With trumpet's regal sound the great result: +Toward the four winds four speedy Cherubim +Put to their mouths the sounding alchemy, +By herald's voice explained; the hollow Abyss +Heard far adn wide, and all the host of Hell +With deafening shout returned them loud acclaim. +Thence more at ease their minds, and somewhat raised +By false presumptuous hope, the ranged Powers +Disband; and, wandering, each his several way +Pursues, as inclination or sad choice +Leads him perplexed, where he may likeliest find +Truce to his restless thoughts, and entertain +The irksome hours, till his great Chief return. +Part on the plain, or in the air sublime, +Upon the wing or in swift race contend, +As at th' Olympian games or Pythian fields; +Part curb their fiery steeds, or shun the goal +With rapid wheels, or fronted brigades form: +As when, to warn proud cities, war appears +Waged in the troubled sky, and armies rush +To battle in the clouds; before each van +Prick forth the airy knights, and couch their spears, +Till thickest legions close; with feats of arms +From either end of heaven the welkin burns. +Others, with vast Typhoean rage, more fell, +Rend up both rocks and hills, and ride the air +In whirlwind; Hell scarce holds the wild uproar:-- +As when Alcides, from Oechalia crowned +With conquest, felt th' envenomed robe, and tore +Through pain up by the roots Thessalian pines, +And Lichas from the top of Oeta threw +Into th' Euboic sea. Others, more mild, +Retreated in a silent valley, sing +With notes angelical to many a harp +Their own heroic deeds, and hapless fall +By doom of battle, and complain that Fate +Free Virtue should enthrall to Force or Chance. +Their song was partial; but the harmony +(What could it less when Spirits immortal sing?) +Suspended Hell, and took with ravishment +The thronging audience. In discourse more sweet +(For Eloquence the Soul, Song charms the Sense) +Others apart sat on a hill retired, +In thoughts more elevate, and reasoned high +Of Providence, Foreknowledge, Will, and Fate-- +Fixed fate, free will, foreknowledge absolute, +And found no end, in wandering mazes lost. +Of good and evil much they argued then, +Of happiness and final misery, +Passion and apathy, and glory and shame: +Vain wisdom all, and false philosophy!-- +Yet, with a pleasing sorcery, could charm +Pain for a while or anguish, and excite +Fallacious hope, or arm th' obdured breast +With stubborn patience as with triple steel. +Another part, in squadrons and gross bands, +On bold adventure to discover wide +That dismal world, if any clime perhaps +Might yield them easier habitation, bend +Four ways their flying march, along the banks +Of four infernal rivers, that disgorge +Into the burning lake their baleful streams-- +Abhorred Styx, the flood of deadly hate; +Sad Acheron of sorrow, black and deep; +Cocytus, named of lamentation loud +Heard on the rueful stream; fierce Phlegeton, +Whose waves of torrent fire inflame with rage. +Far off from these, a slow and silent stream, +Lethe, the river of oblivion, rolls +Her watery labyrinth, whereof who drinks +Forthwith his former state and being forgets-- +Forgets both joy and grief, pleasure and pain. +Beyond this flood a frozen continent +Lies dark and wild, beat with perpetual storms +Of whirlwind and dire hail, which on firm land +Thaws not, but gathers heap, and ruin seems +Of ancient pile; all else deep snow and ice, +A gulf profound as that Serbonian bog +Betwixt Damiata and Mount Casius old, +Where armies whole have sunk: the parching air +Burns frore, and cold performs th' effect of fire. +Thither, by harpy-footed Furies haled, +At certain revolutions all the damned +Are brought; and feel by turns the bitter change +Of fierce extremes, extremes by change more fierce, +From beds of raging fire to starve in ice +Their soft ethereal warmth, and there to pine +Immovable, infixed, and frozen round +Periods of time,--thence hurried back to fire. +They ferry over this Lethean sound +Both to and fro, their sorrow to augment, +And wish and struggle, as they pass, to reach +The tempting stream, with one small drop to lose +In sweet forgetfulness all pain and woe, +All in one moment, and so near the brink; +But Fate withstands, and, to oppose th' attempt, +Medusa with Gorgonian terror guards +The ford, and of itself the water flies +All taste of living wight, as once it fled +The lip of Tantalus. Thus roving on +In confused march forlorn, th' adventurous bands, +With shuddering horror pale, and eyes aghast, +Viewed first their lamentable lot, and found +No rest. Through many a dark and dreary vale +They passed, and many a region dolorous, +O'er many a frozen, many a fiery alp, +Rocks, caves, lakes, fens, bogs, dens, and shades of death-- +A universe of death, which God by curse +Created evil, for evil only good; +Where all life dies, death lives, and Nature breeds, +Perverse, all monstrous, all prodigious things, +Obominable, inutterable, and worse +Than fables yet have feigned or fear conceived, +Gorgons, and Hydras, and Chimeras dire. + Meanwhile the Adversary of God and Man, +Satan, with thoughts inflamed of highest design, +Puts on swift wings, and toward the gates of Hell +Explores his solitary flight: sometimes +He scours the right hand coast, sometimes the left; +Now shaves with level wing the deep, then soars +Up to the fiery concave towering high. +As when far off at sea a fleet descried +Hangs in the clouds, by equinoctial winds +Close sailing from Bengala, or the isles +Of Ternate and Tidore, whence merchants bring +Their spicy drugs; they on the trading flood, +Through the wide Ethiopian to the Cape, +Ply stemming nightly toward the pole: so seemed +Far off the flying Fiend. At last appear +Hell-bounds, high reaching to the horrid roof, +And thrice threefold the gates; three folds were brass, +Three iron, three of adamantine rock, +Impenetrable, impaled with circling fire, +Yet unconsumed. Before the gates there sat +On either side a formidable Shape. +The one seemed woman to the waist, and fair, +But ended foul in many a scaly fold, +Voluminous and vast--a serpent armed +With mortal sting. About her middle round +A cry of Hell-hounds never-ceasing barked +With wide Cerberean mouths full loud, and rung +A hideous peal; yet, when they list, would creep, +If aught disturbed their noise, into her womb, +And kennel there; yet there still barked and howled +Within unseen. Far less abhorred than these +Vexed Scylla, bathing in the sea that parts +Calabria from the hoarse Trinacrian shore; +Nor uglier follow the night-hag, when, called +In secret, riding through the air she comes, +Lured with the smell of infant blood, to dance +With Lapland witches, while the labouring moon +Eclipses at their charms. The other Shape-- +If shape it might be called that shape had none +Distinguishable in member, joint, or limb; +Or substance might be called that shadow seemed, +For each seemed either--black it stood as Night, +Fierce as ten Furies, terrible as Hell, +And shook a dreadful dart: what seemed his head +The likeness of a kingly crown had on. +Satan was now at hand, and from his seat +The monster moving onward came as fast +With horrid strides; Hell trembled as he strode. +Th' undaunted Fiend what this might be admired-- +Admired, not feared (God and his Son except, +Created thing naught valued he nor shunned), +And with disdainful look thus first began:-- + "Whence and what art thou, execrable Shape, +That dar'st, though grim and terrible, advance +Thy miscreated front athwart my way +To yonder gates? Through them I mean to pass, +That be assured, without leave asked of thee. +Retire; or taste thy folly, and learn by proof, +Hell-born, not to contend with Spirits of Heaven." + To whom the Goblin, full of wrath, replied:-- +"Art thou that traitor Angel? art thou he, +Who first broke peace in Heaven and faith, till then +Unbroken, and in proud rebellious arms +Drew after him the third part of Heaven's sons, +Conjured against the Highest--for which both thou +And they, outcast from God, are here condemned +To waste eternal days in woe and pain? +And reckon'st thou thyself with Spirits of Heaven +Hell-doomed, and breath'st defiance here and scorn, +Where I reign king, and, to enrage thee more, +Thy king and lord? Back to thy punishment, +False fugitive; and to thy speed add wings, +Lest with a whip of scorpions I pursue +Thy lingering, or with one stroke of this dart +Strange horror seize thee, and pangs unfelt before." + So spake the grisly Terror, and in shape, +So speaking and so threatening, grew tenfold, +More dreadful and deform. On th' other side, +Incensed with indignation, Satan stood +Unterrified, and like a comet burned, +That fires the length of Ophiuchus huge +In th' arctic sky, and from his horrid hair +Shakes pestilence and war. Each at the head +Levelled his deadly aim; their fatal hands +No second stroke intend; and such a frown +Each cast at th' other as when two black clouds, +With heaven's artillery fraught, came rattling on +Over the Caspian,--then stand front to front +Hovering a space, till winds the signal blow +To join their dark encounter in mid-air. +So frowned the mighty combatants that Hell +Grew darker at their frown; so matched they stood; +For never but once more was wither like +To meet so great a foe. And now great deeds +Had been achieved, whereof all Hell had rung, +Had not the snaky Sorceress, that sat +Fast by Hell-gate and kept the fatal key, +Risen, and with hideous outcry rushed between. + "O father, what intends thy hand," she cried, +"Against thy only son? What fury, O son, +Possesses thee to bend that mortal dart +Against thy father's head? And know'st for whom? +For him who sits above, and laughs the while +At thee, ordained his drudge to execute +Whate'er his wrath, which he calls justice, bids-- +His wrath, which one day will destroy ye both!" + She spake, and at her words the hellish Pest +Forbore: then these to her Satan returned:-- + "So strange thy outcry, and thy words so strange +Thou interposest, that my sudden hand, +Prevented, spares to tell thee yet by deeds +What it intends, till first I know of thee +What thing thou art, thus double-formed, and why, +In this infernal vale first met, thou call'st +Me father, and that phantasm call'st my son. +I know thee not, nor ever saw till now +Sight more detestable than him and thee." + T' whom thus the Portress of Hell-gate replied:-- +"Hast thou forgot me, then; and do I seem +Now in thine eye so foul?--once deemed so fair +In Heaven, when at th' assembly, and in sight +Of all the Seraphim with thee combined +In bold conspiracy against Heaven's King, +All on a sudden miserable pain +Surprised thee, dim thine eyes and dizzy swum +In darkness, while thy head flames thick and fast +Threw forth, till on the left side opening wide, +Likest to thee in shape and countenance bright, +Then shining heavenly fair, a goddess armed, +Out of thy head I sprung. Amazement seized +All th' host of Heaven; back they recoiled afraid +At first, and called me Sin, and for a sign +Portentous held me; but, familiar grown, +I pleased, and with attractive graces won +The most averse--thee chiefly, who, full oft +Thyself in me thy perfect image viewing, +Becam'st enamoured; and such joy thou took'st +With me in secret that my womb conceived +A growing burden. Meanwhile war arose, +And fields were fought in Heaven: wherein remained +(For what could else?) to our Almighty Foe +Clear victory; to our part loss and rout +Through all the Empyrean. Down they fell, +Driven headlong from the pitch of Heaven, down +Into this Deep; and in the general fall +I also: at which time this powerful key +Into my hands was given, with charge to keep +These gates for ever shut, which none can pass +Without my opening. Pensive here I sat +Alone; but long I sat not, till my womb, +Pregnant by thee, and now excessive grown, +Prodigious motion felt and rueful throes. +At last this odious offspring whom thou seest, +Thine own begotten, breaking violent way, +Tore through my entrails, that, with fear and pain +Distorted, all my nether shape thus grew +Transformed: but he my inbred enemy +Forth issued, brandishing his fatal dart, +Made to destroy. I fled, and cried out Death! +Hell trembled at the hideous name, and sighed +From all her caves, and back resounded Death! +I fled; but he pursued (though more, it seems, +Inflamed with lust than rage), and, swifter far, +Me overtook, his mother, all dismayed, +And, in embraces forcible and foul +Engendering with me, of that rape begot +These yelling monsters, that with ceaseless cry +Surround me, as thou saw'st--hourly conceived +And hourly born, with sorrow infinite +To me; for, when they list, into the womb +That bred them they return, and howl, and gnaw +My bowels, their repast; then, bursting forth +Afresh, with conscious terrors vex me round, +That rest or intermission none I find. +Before mine eyes in opposition sits +Grim Death, my son and foe, who set them on, +And me, his parent, would full soon devour +For want of other prey, but that he knows +His end with mine involved, and knows that I +Should prove a bitter morsel, and his bane, +Whenever that shall be: so Fate pronounced. +But thou, O father, I forewarn thee, shun +His deadly arrow; neither vainly hope +To be invulnerable in those bright arms, +Through tempered heavenly; for that mortal dint, +Save he who reigns above, none can resist." + She finished; and the subtle Fiend his lore +Soon learned, now milder, and thus answered smooth:-- + "Dear daughter--since thou claim'st me for thy sire, +And my fair son here show'st me, the dear pledge +Of dalliance had with thee in Heaven, and joys +Then sweet, now sad to mention, through dire change +Befallen us unforeseen, unthought-of--know, +I come no enemy, but to set free +From out this dark and dismal house of pain +Both him and thee, and all the heavenly host +Of Spirits that, in our just pretences armed, +Fell with us from on high. From them I go +This uncouth errand sole, and one for all +Myself expose, with lonely steps to tread +Th' unfounded Deep, and through the void immense +To search, with wandering quest, a place foretold +Should be--and, by concurring signs, ere now +Created vast and round--a place of bliss +In the purlieus of Heaven; and therein placed +A race of upstart creatures, to supply +Perhaps our vacant room, though more removed, +Lest Heaven, surcharged with potent multitude, +Might hap to move new broils. Be this, or aught +Than this more secret, now designed, I haste +To know; and, this once known, shall soon return, +And bring ye to the place where thou and Death +Shall dwell at ease, and up and down unseen +Wing silently the buxom air, embalmed +With odours. There ye shall be fed and filled +Immeasurably; all things shall be your prey." + He ceased; for both seemed highly pleased, and Death +Grinned horrible a ghastly smile, to hear +His famine should be filled, and blessed his maw +Destined to that good hour. No less rejoiced +His mother bad, and thus bespake her sire:-- + "The key of this infernal Pit, by due +And by command of Heaven's all-powerful King, +I keep, by him forbidden to unlock +These adamantine gates; against all force +Death ready stands to interpose his dart, +Fearless to be o'ermatched by living might. +But what owe I to his commands above, +Who hates me, and hath hither thrust me down +Into this gloom of Tartarus profound, +To sit in hateful office here confined, +Inhabitant of Heaven and heavenly born-- +Here in perpetual agony and pain, +With terrors and with clamours compassed round +Of mine own brood, that on my bowels feed? +Thou art my father, thou my author, thou +My being gav'st me; whom should I obey +But thee? whom follow? Thou wilt bring me soon +To that new world of light and bliss, among +The gods who live at ease, where I shall reign +At thy right hand voluptuous, as beseems +Thy daughter and thy darling, without end." + Thus saying, from her side the fatal key, +Sad instrument of all our woe, she took; +And, towards the gate rolling her bestial train, +Forthwith the huge portcullis high up-drew, +Which, but herself, not all the Stygian Powers +Could once have moved; then in the key-hole turns +Th' intricate wards, and every bolt and bar +Of massy iron or solid rock with ease +Unfastens. On a sudden open fly, +With impetuous recoil and jarring sound, +Th' infernal doors, and on their hinges grate +Harsh thunder, that the lowest bottom shook +Of Erebus. She opened; but to shut +Excelled her power: the gates wide open stood, +That with extended wings a bannered host, +Under spread ensigns marching, mibht pass through +With horse and chariots ranked in loose array; +So wide they stood, and like a furnace-mouth +Cast forth redounding smoke and ruddy flame. +Before their eyes in sudden view appear +The secrets of the hoary Deep--a dark +Illimitable ocean, without bound, +Without dimension; where length, breadth, and height, +And time, and place, are lost; where eldest Night +And Chaos, ancestors of Nature, hold +Eternal anarchy, amidst the noise +Of endless wars, and by confusion stand. +For Hot, Cold, Moist, and Dry, four champions fierce, +Strive here for mastery, and to battle bring +Their embryon atoms: they around the flag +Of each his faction, in their several clans, +Light-armed or heavy, sharp, smooth, swift, or slow, +Swarm populous, unnumbered as the sands +Of Barca or Cyrene's torrid soil, +Levied to side with warring winds, and poise +Their lighter wings. To whom these most adhere +He rules a moment: Chaos umpire sits, +And by decision more embroils the fray +By which he reigns: next him, high arbiter, +Chance governs all. Into this wild Abyss, +The womb of Nature, and perhaps her grave, +Of neither sea, nor shore, nor air, nor fire, +But all these in their pregnant causes mixed +Confusedly, and which thus must ever fight, +Unless th' Almighty Maker them ordain +His dark materials to create more worlds-- +Into this wild Abyss the wary Fiend +Stood on the brink of Hell and looked a while, +Pondering his voyage; for no narrow frith +He had to cross. Nor was his ear less pealed +With noises loud and ruinous (to compare +Great things with small) than when Bellona storms +With all her battering engines, bent to rase +Some capital city; or less than if this frame +Of Heaven were falling, and these elements +In mutiny had from her axle torn +The steadfast Earth. At last his sail-broad vans +He spread for flight, and, in the surging smoke +Uplifted, spurns the ground; thence many a league, +As in a cloudy chair, ascending rides +Audacious; but, that seat soon failing, meets +A vast vacuity. All unawares, +Fluttering his pennons vain, plumb-down he drops +Ten thousand fathom deep, and to this hour +Down had been falling, had not, by ill chance, +The strong rebuff of some tumultuous cloud, +Instinct with fire and nitre, hurried him +As many miles aloft. That fury stayed-- +Quenched in a boggy Syrtis, neither sea, +Nor good dry land--nigh foundered, on he fares, +Treading the crude consistence, half on foot, +Half flying; behoves him now both oar and sail. +As when a gryphon through the wilderness +With winged course, o'er hill or moory dale, +Pursues the Arimaspian, who by stealth +Had from his wakeful custody purloined +The guarded gold; so eagerly the Fiend +O'er bog or steep, through strait, rough, dense, or rare, +With head, hands, wings, or feet, pursues his way, +And swims, or sinks, or wades, or creeps, or flies. +At length a universal hubbub wild +Of stunning sounds, and voices all confused, +Borne through the hollow dark, assaults his ear +With loudest vehemence. Thither he plies +Undaunted, to meet there whatever Power +Or Spirit of the nethermost Abyss +Might in that noise reside, of whom to ask +Which way the nearest coast of darkness lies +Bordering on light; when straight behold the throne +Of Chaos, and his dark pavilion spread +Wide on the wasteful Deep! With him enthroned +Sat sable-vested Night, eldest of things, +The consort of his reign; and by them stood +Orcus and Ades, and the dreaded name +Of Demogorgon; Rumour next, and Chance, +And Tumult, and Confusion, all embroiled, +And Discord with a thousand various mouths. + T' whom Satan, turning boldly, thus:--"Ye Powers +And Spirtis of this nethermost Abyss, +Chaos and ancient Night, I come no spy +With purpose to explore or to disturb +The secrets of your realm; but, by constraint +Wandering this darksome desert, as my way +Lies through your spacious empire up to light, +Alone and without guide, half lost, I seek, +What readiest path leads where your gloomy bounds +Confine with Heaven; or, if some other place, +From your dominion won, th' Ethereal King +Possesses lately, thither to arrive +I travel this profound. Direct my course: +Directed, no mean recompense it brings +To your behoof, if I that region lost, +All usurpation thence expelled, reduce +To her original darkness and your sway +(Which is my present journey), and once more +Erect the standard there of ancient Night. +Yours be th' advantage all, mine the revenge!" + Thus Satan; and him thus the Anarch old, +With faltering speech and visage incomposed, +Answered: "I know thee, stranger, who thou art-- *** +That mighty leading Angel, who of late +Made head against Heaven's King, though overthrown. +I saw and heard; for such a numerous host +Fled not in silence through the frighted Deep, +With ruin upon ruin, rout on rout, +Confusion worse confounded; and Heaven-gates +Poured out by millions her victorious bands, +Pursuing. I upon my frontiers here +Keep residence; if all I can will serve +That little which is left so to defend, +Encroached on still through our intestine broils +Weakening the sceptre of old Night: first, Hell, +Your dungeon, stretching far and wide beneath; +Now lately Heaven and Earth, another world +Hung o'er my realm, linked in a golden chain +To that side Heaven from whence your legions fell! +If that way be your walk, you have not far; +So much the nearer danger. Go, and speed; +Havoc, and spoil, and ruin, are my gain." + He ceased; and Satan stayed not to reply, +But, glad that now his sea should find a shore, +With fresh alacrity and force renewed +Springs upward, like a pyramid of fire, +Into the wild expanse, and through the shock +Of fighting elements, on all sides round +Environed, wins his way; harder beset +And more endangered than when Argo passed +Through Bosporus betwixt the justling rocks, +Or when Ulysses on the larboard shunned +Charybdis, and by th' other whirlpool steered. +So he with difficulty and labour hard +Moved on, with difficulty and labour he; +But, he once passed, soon after, when Man fell, +Strange alteration! Sin and Death amain, +Following his track (such was the will of Heaven) +Paved after him a broad and beaten way +Over the dark Abyss, whose boiling gulf +Tamely endured a bridge of wondrous length, +From Hell continued, reaching th' utmost orb +Of this frail World; by which the Spirits perverse +With easy intercourse pass to and fro +To tempt or punish mortals, except whom +God and good Angels guard by special grace. + But now at last the sacred influence +Of light appears, and from the walls of Heaven +Shoots far into the bosom of dim Night +A glimmering dawn. Here Nature first begins +Her farthest verge, and Chaos to retire, +As from her outmost works, a broken foe, +With tumult less and with less hostile din; +That Satan with less toil, and now with ease, +Wafts on the calmer wave by dubious light, +And, like a weather-beaten vessel, holds +Gladly the port, though shrouds and tackle torn; +Or in the emptier waste, resembling air, +Weighs his spread wings, at leisure to behold +Far off th' empyreal Heaven, extended wide +In circuit, undetermined square or round, +With opal towers and battlements adorned +Of living sapphire, once his native seat; +And, fast by, hanging in a golden chain, +This pendent World, in bigness as a star +Of smallest magnitude close by the moon. +Thither, full fraught with mischievous revenge, +Accursed, and in a cursed hour, he hies. + + + +Book III + + +Hail, holy Light, offspring of Heaven firstborn, +Or of the Eternal coeternal beam +May I express thee unblam'd? since God is light, +And never but in unapproached light +Dwelt from eternity, dwelt then in thee +Bright effluence of bright essence increate. +Or hear"st thou rather pure ethereal stream, +Whose fountain who shall tell? before the sun, +Before the Heavens thou wert, and at the voice +Of God, as with a mantle, didst invest *** +The rising world of waters dark and deep, +Won from the void and formless infinite. +Thee I re-visit now with bolder wing, +Escap'd the Stygian pool, though long detain'd +In that obscure sojourn, while in my flight +Through utter and through middle darkness borne, +With other notes than to the Orphean lyre +I sung of Chaos and eternal Night; +Taught by the heavenly Muse to venture down +The dark descent, and up to re-ascend, +Though hard and rare: Thee I revisit safe, +And feel thy sovran vital lamp; but thou +Revisit'st not these eyes, that roll in vain +To find thy piercing ray, and find no dawn; +So thick a drop serene hath quench'd their orbs, +Or dim suffusion veil'd. Yet not the more +Cease I to wander, where the Muses haunt, +Clear spring, or shady grove, or sunny hill, +Smit with the love of sacred song; but chief +Thee, Sion, and the flowery brooks beneath, +That wash thy hallow'd feet, and warbling flow, +Nightly I visit: nor sometimes forget +So were I equall'd with them in renown, +Thy sovran command, that Man should find grace; +Blind Thamyris, and blind Maeonides, +And Tiresias, and Phineus, prophets old: +Then feed on thoughts, that voluntary move +Harmonious numbers; as the wakeful bird +Sings darkling, and in shadiest covert hid +Tunes her nocturnal note. Thus with the year +Seasons return; but not to me returns +Day, or the sweet approach of even or morn, +Or sight of vernal bloom, or summer's rose, +Or flocks, or herds, or human face divine; +But cloud instead, and ever-during dark +Surrounds me, from the cheerful ways of men +Cut off, and for the book of knowledge fair +Presented with a universal blank +Of nature's works to me expung'd and ras'd, +And wisdom at one entrance quite shut out. +So much the rather thou, celestial Light, +Shine inward, and the mind through all her powers +Irradiate; there plant eyes, all mist from thence +Purge and disperse, that I may see and tell +Of things invisible to mortal sight. +Now had the Almighty Father from above, +From the pure empyrean where he sits +High thron'd above all highth, bent down his eye +His own works and their works at once to view: +About him all the Sanctities of Heaven +Stood thick as stars, and from his sight receiv'd +Beatitude past utterance; on his right +The radiant image of his glory sat, +His only son; on earth he first beheld +Our two first parents, yet the only two +Of mankind in the happy garden plac'd +Reaping immortal fruits of joy and love, +Uninterrupted joy, unrivall'd love, +In blissful solitude; he then survey'd +Hell and the gulf between, and Satan there +Coasting the wall of Heaven on this side Night +In the dun air sublime, and ready now +To stoop with wearied wings, and willing feet, +On the bare outside of this world, that seem'd +Firm land imbosom'd, without firmament, +Uncertain which, in ocean or in air. +Him God beholding from his prospect high, +Wherein past, present, future, he beholds, +Thus to his only Son foreseeing spake. +Only begotten Son, seest thou what rage +Transports our Adversary? whom no bounds +Prescrib'd no bars of Hell, nor all the chains +Heap'd on him there, nor yet the main abyss +Wide interrupt, can hold; so bent he seems +On desperate revenge, that shall redound +Upon his own rebellious head. And now, +Through all restraint broke loose, he wings his way +Not far off Heaven, in the precincts of light, +Directly towards the new created world, +And man there plac'd, with purpose to assay +If him by force he can destroy, or, worse, +By some false guile pervert; and shall pervert; +For man will hearken to his glozing lies, +And easily transgress the sole command, +Sole pledge of his obedience: So will fall +He and his faithless progeny: Whose fault? +Whose but his own? ingrate, he had of me +All he could have; I made him just and right, +Sufficient to have stood, though free to fall. +Such I created all the ethereal Powers +And Spirits, both them who stood, and them who fail'd; +Freely they stood who stood, and fell who fell. +Not free, what proof could they have given sincere +Of true allegiance, constant faith or love, +Where only what they needs must do appear'd, +Not what they would? what praise could they receive? +What pleasure I from such obedience paid, +When will and reason (reason also is choice) +Useless and vain, of freedom both despoil'd, +Made passive both, had serv'd necessity, +Not me? they therefore, as to right belong$ 'd, +So were created, nor can justly accuse +Their Maker, or their making, or their fate, +As if predestination over-rul'd +Their will dispos'd by absolute decree +Or high foreknowledge they themselves decreed +Their own revolt, not I; if I foreknew, +Foreknowledge had no influence on their fault, +Which had no less proved certain unforeknown. +So without least impulse or shadow of fate, +Or aught by me immutably foreseen, +They trespass, authors to themselves in all +Both what they judge, and what they choose; for so +I form'd them free: and free they must remain, +Till they enthrall themselves; I else must change +Their nature, and revoke the high decree +Unchangeable, eternal, which ordain'd +$THeir freedom: they themselves ordain'd their fall. +The first sort by their own suggestion fell, +Self-tempted, self-deprav'd: Man falls, deceiv'd +By the other first: Man therefore shall find grace, +The other none: In mercy and justice both, +Through Heaven and Earth, so shall my glory excel; +But Mercy, first and last, shall brightest shine. +Thus while God spake, ambrosial fragrance fill'd +All Heaven, and in the blessed Spirits elect +Sense of new joy ineffable diffus'd. +Beyond compare the Son of God was seen +Most glorious; in him all his Father shone +Substantially express'd; and in his face +Divine compassion visibly appear'd, +Love without end, and without measure grace, +Which uttering, thus he to his Father spake. +O Father, gracious was that word which clos'd +Thy sovran command, that Man should find grace; +, that Man should find grace; +For which both Heaven and earth shall high extol +Thy praises, with the innumerable sound +Of hymns and sacred songs, wherewith thy throne +Encompass'd shall resound thee ever blest. +For should Man finally be lost, should Man, +Thy creature late so lov'd, thy youngest son, +Fall circumvented thus by fraud, though join'd +With his own folly? that be from thee far, +That far be from thee, Father, who art judge +Of all things made, and judgest only right. +Or shall the Adversary thus obtain +His end, and frustrate thine? shall he fulfill +His malice, and thy goodness bring to nought, +Or proud return, though to his heavier doom, +Yet with revenge accomplish'd, and to Hell +Draw after him the whole race of mankind, +By him corrupted? or wilt thou thyself +Abolish thy creation, and unmake +For him, what for thy glory thou hast made? +So should thy goodness and thy greatness both +Be question'd and blasphem'd without defence. +To whom the great Creator thus replied. +O son, in whom my soul hath chief delight, +Son of my bosom, Son who art alone. +My word, my wisdom, and effectual might, +All hast thou spoken as my thoughts are, all +As my eternal purpose hath decreed; +Man shall not quite be lost, but sav'd who will; +Yet not of will in him, but grace in me +Freely vouchsaf'd; once more I will renew +His lapsed powers, though forfeit; and enthrall'd +By sin to foul exorbitant desires; +Upheld by me, yet once more he shall stand +On even ground against his mortal foe; +By me upheld, that he may know how frail +His fallen condition is, and to me owe +All his deliverance, and to none but me. +Some I have chosen of peculiar grace, +Elect above the rest; so is my will: +The rest shall hear me call, and oft be warn'd +Their sinful state, and to appease betimes +The incensed Deity, while offer'd grace +Invites; for I will clear their senses dark, +What may suffice, and soften stony hearts +To pray, repent, and bring obedience due. +To prayer, repentance, and obedience due, +Though but endeavour'd with sincere intent, +Mine ear shall not be slow, mine eye not shut. +And I will place within them as a guide, +My umpire Conscience; whom if they will hear, +Light after light, well us'd, they shall attain, +And to the end, persisting, safe arrive. +This my long sufferance, and my day of grace, +They who neglect and scorn, shall never taste; +But hard be harden'd, blind be blinded more, +That they may stumble on, and deeper fall; +And none but such from mercy I exclude. +But yet all is not done; Man disobeying, +Disloyal, breaks his fealty, and sins +Against the high supremacy of Heaven, +Affecting God-head, and, so losing all, +To expiate his treason hath nought left, +But to destruction sacred and devote, +He, with his whole posterity, must die, +Die he or justice must; unless for him +Some other able, and as willing, pay +The rigid satisfaction, death for death. +Say, heavenly Powers, where shall we find such love? +Which of you will be mortal, to redeem +Man's mortal crime, and just the unjust to save? +Dwells in all Heaven charity so dear? +And silence was in Heaven: $ on Man's behalf +He ask'd, but all the heavenly quire stood mute, +Patron or intercessour none appear'd, +Much less that durst upon his own head draw +The deadly forfeiture, and ransom set. +And now without redemption all mankind +Must have been lost, adjudg'd to Death and Hell +By doom severe, had not the Son of God, +In whom the fulness dwells of love divine, +His dearest mediation thus renew'd. +Father, thy word is past, Man shall find grace; +And shall grace not find means, that finds her way, +The speediest of thy winged messengers, +To visit all thy creatures, and to all +Comes unprevented, unimplor'd, unsought? +Happy for Man, so coming; he her aid +Can never seek, once dead in sins, and lost; +Atonement for himself, or offering meet, +Indebted and undone, hath none to bring; +Behold me then: me for him, life for life +I offer: on me let thine anger fall; +Account me Man; I for his sake will leave + Thy bosom, and this glory next to thee + Freely put off, and for him lastly die + Well pleased; on me let Death wreak all his rage. + Under his gloomy power I shall not long + Lie vanquished. Thou hast given me to possess + Life in myself for ever; by thee I live; + Though now to Death I yield, and am his due, + All that of me can die, yet, that debt paid, + $ thou wilt not leave me in the loathsome grave + His prey, nor suffer my unspotted soul + For ever with corruption there to dwell; + But I shall rise victorious, and subdue + My vanquisher, spoiled of his vaunted spoil. + Death his death's wound shall then receive, and stoop + Inglorious, of his mortal sting disarmed; + I through the ample air in triumph high + Shall lead Hell captive maugre Hell, and show +The powers of darkness bound. Thou, at the sight + Pleased, out of Heaven shalt look down and smile, + While, by thee raised, I ruin all my foes; + Death last, and with his carcase glut the grave; + Then, with the multitude of my redeemed, + Shall enter Heaven, long absent, and return, + Father, to see thy face, wherein no cloud + Of anger shall remain, but peace assured + And reconcilement: wrath shall be no more + Thenceforth, but in thy presence joy entire. + His words here ended; but his meek aspect + Silent yet spake, and breathed immortal love + To mortal men, above which only shone + Filial obedience: as a sacrifice + Glad to be offered, he attends the will + Of his great Father. Admiration seized + All Heaven, what this might mean, and whither tend, + Wondering; but soon th' Almighty thus replied. + O thou in Heaven and Earth the only peace + Found out for mankind under wrath, O thou + My sole complacence! Well thou know'st how dear + To me are all my works; nor Man the least, + Though last created, that for him I spare + Thee from my bosom and right hand, to save, + By losing thee a while, the whole race lost. + + 00021053 + Thou, therefore, whom thou only canst redeem, + Their nature also to thy nature join; + And be thyself Man among men on Earth, + Made flesh, when time shall be, of virgin seed, + By wondrous birth; be thou in Adam's room +The head of all mankind, though Adam's son. +As in him perish all men, so in thee, +As from a second root, shall be restored +As many as are restored, without thee none. +His crime makes guilty all his sons; thy merit, +Imputed, shall absolve them who renounce +Their own both righteous and unrighteous deeds, +And live in thee transplanted, and from thee +Receive new life. So Man, as is most just, +Shall satisfy for Man, be judged and die, +And dying rise, and rising with him raise +His brethren, ransomed with his own dear life. +So heavenly love shall outdo hellish hate, +Giving to death, and dying to redeem, +So dearly to redeem what hellish hate +So easily destroyed, and still destroys +In those who, when they may, accept not grace. +Nor shalt thou, by descending to assume +Man's nature, lessen or degrade thine own. +Because thou hast, though throned in highest bliss +Equal to God, and equally enjoying +God-like fruition, quitted all, to save +A world from utter loss, and hast been found +By merit more than birthright Son of God, +Found worthiest to be so by being good, +Far more than great or high; because in thee +Love hath abounded more than glory abounds; +Therefore thy humiliation shall exalt +With thee thy manhood also to this throne: +Here shalt thou sit incarnate, here shalt reign +Both God and Man, Son both of God and Man, +Anointed universal King; all power +I give thee; reign for ever, and assume +Thy merits; under thee, as head supreme, +Thrones, Princedoms, Powers, Dominions, I reduce: +All knees to thee shall bow, of them that bide +In Heaven, or Earth, or under Earth in Hell. +When thou, attended gloriously from Heaven, +Shalt in the sky appear, and from thee send +The summoning Arch-Angels to proclaim +Thy dread tribunal; forthwith from all winds, +The living, and forthwith the cited dead +Of all past ages, to the general doom +Shall hasten; such a peal shall rouse their sleep. +Then, all thy saints assembled, thou shalt judge +Bad Men and Angels; they, arraigned, shall sink +Beneath thy sentence; Hell, her numbers full, +Thenceforth shall be for ever shut. Mean while +The world shall burn, and from her ashes spring +New Heaven and Earth, wherein the just shall dwell, +And, after all their tribulations long, +See golden days, fruitful of golden deeds, +With joy and peace triumphing, and fair truth. +Then thou thy regal scepter shalt lay by, +For regal scepter then no more shall need, +God shall be all in all. But, all ye Gods, +Adore him, who to compass all this dies; +Adore the Son, and honour him as me. +No sooner had the Almighty ceased, but all +The multitude of Angels, with a shout +Loud as from numbers without number, sweet +As from blest voices, uttering joy, Heaven rung +With jubilee, and loud Hosannas filled +The eternal regions: Lowly reverent +Towards either throne they bow, and to the ground +With solemn adoration down they cast +Their crowns inwove with amarant and gold; +Immortal amarant, a flower which once +In Paradise, fast by the tree of life, +Began to bloom; but soon for man's offence +To Heaven removed, where first it grew, there grows, +And flowers aloft shading the fount of life, +And where the river of bliss through midst of Heaven +Rolls o'er Elysian flowers her amber stream; +With these that never fade the Spirits elect +Bind their resplendent locks inwreathed with beams; +Now in loose garlands thick thrown off, the bright +Pavement, that like a sea of jasper shone, +Impurpled with celestial roses smiled. +Then, crowned again, their golden harps they took, +Harps ever tuned, that glittering by their side +Like quivers hung, and with preamble sweet +Of charming symphony they introduce +Their sacred song, and waken raptures high; +No voice exempt, no voice but well could join +Melodious part, such concord is in Heaven. +Thee, Father, first they sung Omnipotent, +Immutable, Immortal, Infinite, +Eternal King; the Author of all being, +Fonntain of light, thyself invisible +Amidst the glorious brightness where thou sit'st +Throned inaccessible, but when thou shadest +The full blaze of thy beams, and, through a cloud +Drawn round about thee like a radiant shrine, +Dark with excessive bright thy skirts appear, +Yet dazzle Heaven, that brightest Seraphim +Approach not, but with both wings veil their eyes. +Thee next they sang of all creation first, +Begotten Son, Divine Similitude, +In whose conspicuous countenance, without cloud +Made visible, the Almighty Father shines, +Whom else no creature can behold; on thee +Impressed the effulgence of his glory abides, +Transfused on thee his ample Spirit rests. +He Heaven of Heavens and all the Powers therein +By thee created; and by thee threw down +The aspiring Dominations: Thou that day +Thy Father's dreadful thunder didst not spare, +Nor stop thy flaming chariot-wheels, that shook +Heaven's everlasting frame, while o'er the necks +Thou drovest of warring Angels disarrayed. +Back from pursuit thy Powers with loud acclaim +Thee only extolled, Son of thy Father's might, +To execute fierce vengeance on his foes, +Not so on Man: Him through their malice fallen, +Father of mercy and grace, thou didst not doom +So strictly, but much more to pity incline: +No sooner did thy dear and only Son +Perceive thee purposed not to doom frail Man +So strictly, but much more to pity inclined, +He to appease thy wrath, and end the strife +Of mercy and justice in thy face discerned, +Regardless of the bliss wherein he sat +Second to thee, offered himself to die +For Man's offence. O unexampled love, +Love no where to be found less than Divine! +Hail, Son of God, Saviour of Men! Thy name +Shall be the copious matter of my song +Henceforth, and never shall my heart thy praise +Forget, nor from thy Father's praise disjoin. +Thus they in Heaven, above the starry sphere, +Their happy hours in joy and hymning spent. +Mean while upon the firm opacous globe +Of this round world, whose first convex divides +The luminous inferiour orbs, enclosed +From Chaos, and the inroad of Darkness old, +Satan alighted walks: A globe far off +It seemed, now seems a boundless continent +Dark, waste, and wild, under the frown of Night +Starless exposed, and ever-threatening storms +Of Chaos blustering round, inclement sky; +Save on that side which from the wall of Heaven, +Though distant far, some small reflection gains +Of glimmering air less vexed with tempest loud: +Here walked the Fiend at large in spacious field. +As when a vultur on Imaus bred, +Whose snowy ridge the roving Tartar bounds, +Dislodging from a region scarce of prey +To gorge the flesh of lambs or yeanling kids, +On hills where flocks are fed, flies toward the springs +Of Ganges or Hydaspes, Indian streams; +But in his way lights on the barren plains +Of Sericana, where Chineses drive +With sails and wind their cany waggons light: +So, on this windy sea of land, the Fiend +Walked up and down alone, bent on his prey; +Alone, for other creature in this place, +Living or lifeless, to be found was none; +None yet, but store hereafter from the earth +Up hither like aereal vapours flew +Of all things transitory and vain, when sin +With vanity had filled the works of men: +Both all things vain, and all who in vain things +Built their fond hopes of glory or lasting fame, +Or happiness in this or the other life; +All who have their reward on earth, the fruits +Of painful superstition and blind zeal, +Nought seeking but the praise of men, here find +Fit retribution, empty as their deeds; +All the unaccomplished works of Nature's hand, +Abortive, monstrous, or unkindly mixed, +Dissolved on earth, fleet hither, and in vain, +Till final dissolution, wander here; +Not in the neighbouring moon as some have dreamed; +Those argent fields more likely habitants, +Translated Saints, or middle Spirits hold +Betwixt the angelical and human kind. +Hither of ill-joined sons and daughters born +First from the ancient world those giants came +With many a vain exploit, though then renowned: +The builders next of Babel on the plain +Of Sennaar, and still with vain design, +New Babels, had they wherewithal, would build: +Others came single; he, who, to be deemed +A God, leaped fondly into Aetna flames, +Empedocles; and he, who, to enjoy +Plato's Elysium, leaped into the sea, +Cleombrotus; and many more too long, +Embryos, and idiots, eremites, and friars +White, black, and gray, with all their trumpery. +Here pilgrims roam, that strayed so far to seek +In Golgotha him dead, who lives in Heaven; +And they, who to be sure of Paradise, +Dying, put on the weeds of Dominick, +Or in Franciscan think to pass disguised; +They pass the planets seven, and pass the fixed, +And that crystalling sphere whose balance weighs +The trepidation talked, and that first moved; +And now Saint Peter at Heaven's wicket seems +To wait them with his keys, and now at foot +Of Heaven's ascent they lift their feet, when lo +A violent cross wind from either coast +Blows them transverse, ten thousand leagues awry +Into the devious air: Then might ye see +Cowls, hoods, and habits, with their wearers, tost +And fluttered into rags; then reliques, beads, +Indulgences, dispenses, pardons, bulls, +The sport of winds: All these, upwhirled aloft, +Fly o'er the backside of the world far off +Into a Limbo large and broad, since called +The Paradise of Fools, to few unknown +Long after; now unpeopled, and untrod. +All this dark globe the Fiend found as he passed, +And long he wandered, till at last a gleam +Of dawning light turned thither-ward in haste +His travelled steps: far distant he descries +Ascending by degrees magnificent +Up to the wall of Heaven a structure high; +At top whereof, but far more rich, appeared +The work as of a kingly palace-gate, +With frontispiece of diamond and gold +Embellished; thick with sparkling orient gems +The portal shone, inimitable on earth +By model, or by shading pencil, drawn. +These stairs were such as whereon Jacob saw +Angels ascending and descending, bands +Of guardians bright, when he from Esau fled +To Padan-Aram, in the field of Luz +Dreaming by night under the open sky +And waking cried, This is the gate of Heaven. +Each stair mysteriously was meant, nor stood +There always, but drawn up to Heaven sometimes +Viewless; and underneath a bright sea flowed +Of jasper, or of liquid pearl, whereon +Who after came from earth, failing arrived +Wafted by Angels, or flew o'er the lake +Rapt in a chariot drawn by fiery steeds. +The stairs were then let down, whether to dare +The Fiend by easy ascent, or aggravate +His sad exclusion from the doors of bliss: +Direct against which opened from beneath, +Just o'er the blissful seat of Paradise, +A passage down to the Earth, a passage wide, +Wider by far than that of after-times +Over mount Sion, and, though that were large, +Over the Promised Land to God so dear; +By which, to visit oft those happy tribes, +On high behests his angels to and fro +Passed frequent, and his eye with choice regard +From Paneas, the fount of Jordan's flood, +To Beersaba, where the Holy Land +Borders on Egypt and the Arabian shore; +So wide the opening seemed, where bounds were set +To darkness, such as bound the ocean wave. +Satan from hence, now on the lower stair, +That scaled by steps of gold to Heaven-gate, +Looks down with wonder at the sudden view +Of all this world at once. As when a scout, +Through dark?;nd desart ways with?oeril gone +All?might,?;t?kast by break of cheerful dawn +Obtains the brow of some high-climbing hill, +Which to his eye discovers unaware +The goodly prospect of some foreign land +First seen, or some renowned metropolis +With glistering spires and pinnacles adorned, +Which now the rising sun gilds with his beams: +Such wonder seised, though after Heaven seen, +The Spirit malign, but much more envy seised, +At sight of all this world beheld so fair. +Round he surveys (and well might, where he stood +So high above the circling canopy +Of night's extended shade,) from eastern point +Of Libra to the fleecy star that bears +Andromeda far off Atlantick seas +Beyond the horizon; then from pole to pole +He views in breadth, and without longer pause +Down right into the world's first region throws +His flight precipitant, and winds with ease +Through the pure marble air his oblique way +Amongst innumerable stars, that shone +Stars distant, but nigh hand seemed other worlds; +Or other worlds they seemed, or happy isles, +Like those Hesperian gardens famed of old, +Fortunate fields, and groves, and flowery vales, +Thrice happy isles; but who dwelt happy there +He staid not to inquire: Above them all +The golden sun, in splendour likest Heaven, +Allured his eye; thither his course he bends +Through the calm firmament, (but up or down, +By center, or eccentrick, hard to tell, +Or longitude,) where the great luminary +Aloof the vulgar constellations thick, +That from his lordly eye keep distance due, +Dispenses light from far; they, as they move +Their starry dance in numbers that compute +Days, months, and years, towards his all-cheering lamp +Turn swift their various motions, or are turned +By his magnetick beam, that gently warms +The universe, and to each inward part +With gentle penetration, though unseen, +Shoots invisible virtue even to the deep; +So wonderously was set his station bright. +There lands the Fiend, a spot like which perhaps +Astronomer in the sun's lucent orb +Through his glazed optick tube yet never saw. +The place he found beyond expression bright, +Compared with aught on earth, metal or stone; +Not all parts like, but all alike informed +With radiant light, as glowing iron with fire; +If metal, part seemed gold, part silver clear; +If stone, carbuncle most or chrysolite, +Ruby or topaz, to the twelve that shone +In Aaron's breast-plate, and a stone besides +Imagined rather oft than elsewhere seen, +That stone, or like to that which here below +Philosophers in vain so long have sought, +In vain, though by their powerful art they bind +Volatile Hermes, and call up unbound +In various shapes old Proteus from the sea, +Drained through a limbeck to his native form. +What wonder then if fields and regions here +Breathe forth Elixir pure, and rivers run +Potable gold, when with one virtuous touch +The arch-chemick sun, so far from us remote, +Produces, with terrestrial humour mixed, +Here in the dark so many precious things +Of colour glorious, and effect so rare? +Here matter new to gaze the Devil met +Undazzled; far and wide his eye commands; +For sight no obstacle found here, nor shade, +But all sun-shine, as when his beams at noon +Culminate from the equator, as they now +Shot upward still direct, whence no way round +Shadow from body opaque can fall; and the air, +No where so clear, sharpened his visual ray +To objects distant far, whereby he soon +Saw within ken a glorious Angel stand, +The same whom John saw also in the sun: +His back was turned, but not his brightness hid; +Of beaming sunny rays a golden tiar +Circled his head, nor less his locks behind +Illustrious on his shoulders fledge with wings +Lay waving round; on some great charge employed +He seemed, or fixed in cogitation deep. +Glad was the Spirit impure, as now in hope +To find who might direct his wandering flight +To Paradise, the happy seat of Man, +His journey's end and our beginning woe. +But first he casts to change his proper shape, +Which else might work him danger or delay: +And now a stripling Cherub he appears, +Not of the prime, yet such as in his face +Youth smiled celestial, and to every limb +Suitable grace diffused, so well he feigned: +Under a coronet his flowing hair +In curls on either cheek played; wings he wore +Of many a coloured plume, sprinkled with gold; +His habit fit for speed succinct, and held +Before his decent steps a silver wand. +He drew not nigh unheard; the Angel bright, +Ere he drew nigh, his radiant visage turned, +Admonished by his ear, and straight was known +The Arch-Angel Uriel, one of the seven +Who in God's presence, nearest to his throne, +Stand ready at command, and are his eyes +That run through all the Heavens, or down to the Earth +Bear his swift errands over moist and dry, +O'er sea and land: him Satan thus accosts. +Uriel, for thou of those seven Spirits that stand +In sight of God's high throne, gloriously bright, +The first art wont his great authentick will +Interpreter through highest Heaven to bring, +Where all his sons thy embassy attend; +And here art likeliest by supreme decree +Like honour to obtain, and as his eye +To visit oft this new creation round; +Unspeakable desire to see, and know +All these his wonderous works, but chiefly Man, +His chief delight and favour, him for whom +All these his works so wonderous he ordained, +Hath brought me from the quires of Cherubim +Alone thus wandering. Brightest Seraph, tell +In which of all these shining orbs hath Man +His fixed seat, or fixed seat hath none, +But all these shining orbs his choice to dwell; +That I may find him, and with secret gaze +Or open admiration him behold, +On whom the great Creator hath bestowed +Worlds, and on whom hath all these graces poured; +That both in him and all things, as is meet, +The universal Maker we may praise; +Who justly hath driven out his rebel foes +To deepest Hell, and, to repair that loss, +Created this new happy race of Men +To serve him better: Wise are all his ways. +So spake the false dissembler unperceived; +For neither Man nor Angel can discern +Hypocrisy, the only evil that walks +Invisible, except to God alone, +By his permissive will, through Heaven and Earth: +And oft, though wisdom wake, suspicion sleeps +At wisdom's gate, and to simplicity +Resigns her charge, while goodness thinks no ill +Where no ill seems: Which now for once beguiled +Uriel, though regent of the sun, and held +The sharpest-sighted Spirit of all in Heaven; +Who to the fraudulent impostor foul, +In his uprightness, answer thus returned. +Fair Angel, thy desire, which tends to know +The works of God, thereby to glorify +The great Work-master, leads to no excess +That reaches blame, but rather merits praise +The more it seems excess, that led thee hither +From thy empyreal mansion thus alone, +To witness with thine eyes what some perhaps, +Contented with report, hear only in Heaven: +For wonderful indeed are all his works, +Pleasant to know, and worthiest to be all +Had in remembrance always with delight; +But what created mind can comprehend +Their number, or the wisdom infinite +That brought them forth, but hid their causes deep? +I saw when at his word the formless mass, +This world's material mould, came to a heap: +Confusion heard his voice, and wild uproar +Stood ruled, stood vast infinitude confined; +Till at his second bidding Darkness fled, +Light shone, and order from disorder sprung: +Swift to their several quarters hasted then +The cumbrous elements, earth, flood, air, fire; +And this ethereal quintessence of Heaven +Flew upward, spirited with various forms, +That rolled orbicular, and turned to stars +Numberless, as thou seest, and how they move; +Each had his place appointed, each his course; +The rest in circuit walls this universe. +Look downward on that globe, whose hither side +With light from hence, though but reflected, shines; +That place is Earth, the seat of Man; that light +His day, which else, as the other hemisphere, +Night would invade; but there the neighbouring moon +So call that opposite fair star) her aid +Timely interposes, and her monthly round +Still ending, still renewing, through mid Heaven, +With borrowed light her countenance triform +Hence fills and empties to enlighten the Earth, +And in her pale dominion checks the night. +That spot, to which I point, is Paradise, +Adam's abode; those lofty shades, his bower. +Thy way thou canst not miss, me mine requires. +Thus said, he turned; and Satan, bowing low, +As to superiour Spirits is wont in Heaven, +Where honour due and reverence none neglects, +Took leave, and toward the coast of earth beneath, +Down from the ecliptick, sped with hoped success, +Throws his steep flight in many an aery wheel; +Nor staid, till on Niphates' top he lights. + + + +Book IV + + +O, for that warning voice, which he, who saw +The Apocalypse, heard cry in Heaven aloud, +Then when the Dragon, put to second rout, +Came furious down to be revenged on men, +Woe to the inhabitants on earth! that now, +While time was, our first parents had been warned +The coming of their secret foe, and 'scaped, +Haply so 'scaped his mortal snare: For now +Satan, now first inflamed with rage, came down, +The tempter ere the accuser of mankind, +To wreak on innocent frail Man his loss +Of that first battle, and his flight to Hell: +Yet, not rejoicing in his speed, though bold +Far off and fearless, nor with cause to boast, +Begins his dire attempt; which nigh the birth +Now rolling boils in his tumultuous breast, +And like a devilish engine back recoils +Upon himself; horrour and doubt distract +His troubled thoughts, and from the bottom stir +The Hell within him; for within him Hell +He brings, and round about him, nor from Hell +One step, no more than from himself, can fly +By change of place: Now conscience wakes despair, +That slumbered; wakes the bitter memory +Of what he was, what is, and what must be +Worse; of worse deeds worse sufferings must ensue. +Sometimes towards Eden, which now in his view +Lay pleasant, his grieved look he fixes sad; +Sometimes towards Heaven, and the full-blazing sun, +Which now sat high in his meridian tower: +Then, much revolving, thus in sighs began. +O thou, that, with surpassing glory crowned, +Lookest from thy sole dominion like the God +Of this new world; at whose sight all the stars +Hide their diminished heads; to thee I call, +But with no friendly voice, and add thy name, +Of Sun! to tell thee how I hate thy beams, +That bring to my remembrance from what state +I fell, how glorious once above thy sphere; +Till pride and worse ambition threw me down +Warring in Heaven against Heaven's matchless King: +Ah, wherefore! he deserved no such return +From me, whom he created what I was +In that bright eminence, and with his good +Upbraided none; nor was his service hard. +What could be less than to afford him praise, +The easiest recompence, and pay him thanks, +How due! yet all his good proved ill in me, +And wrought but malice; lifted up so high +I sdeined subjection, and thought one step higher +Would set me highest, and in a moment quit +The debt immense of endless gratitude, +So burdensome still paying, still to owe, +Forgetful what from him I still received, +And understood not that a grateful mind +By owing owes not, but still pays, at once +Indebted and discharged; what burden then +O, had his powerful destiny ordained +Me some inferiour Angel, I had stood +Then happy; no unbounded hope had raised +Ambition! Yet why not some other Power +As great might have aspired, and me, though mean, +Drawn to his part; but other Powers as great +Fell not, but stand unshaken, from within +Or from without, to all temptations armed. +Hadst thou the same free will and power to stand? +Thou hadst: whom hast thou then or what to accuse, +But Heaven's free love dealt equally to all? +Be then his love accursed, since love or hate, +To me alike, it deals eternal woe. +Nay, cursed be thou; since against his thy will +Chose freely what it now so justly rues. +Me miserable! which way shall I fly +Infinite wrath, and infinite despair? +Which way I fly is Hell; myself am Hell; +And, in the lowest deep, a lower deep +Still threatening to devour me opens wide, +To which the Hell I suffer seems a Heaven. +O, then, at last relent: Is there no place +Left for repentance, none for pardon left? +None left but by submission; and that word +Disdain forbids me, and my dread of shame +Among the Spirits beneath, whom I seduced +With other promises and other vaunts +Than to submit, boasting I could subdue +The Omnipotent. Ay me! they little know +How dearly I abide that boast so vain, +Under what torments inwardly I groan, +While they adore me on the throne of Hell. +With diadem and scepter high advanced, +The lower still I fall, only supreme +In misery: Such joy ambition finds. +But say I could repent, and could obtain, +By act of grace, my former state; how soon +Would highth recall high thoughts, how soon unsay +What feigned submission swore? Ease would recant +Vows made in pain, as violent and void. +For never can true reconcilement grow, +Where wounds of deadly hate have pierced so deep: +Which would but lead me to a worse relapse +And heavier fall: so should I purchase dear +Short intermission bought with double smart. +This knows my Punisher; therefore as far +From granting he, as I from begging, peace; +All hope excluded thus, behold, in stead +Mankind created, and for him this world. +So farewell, hope; and with hope farewell, fear; +Farewell, remorse! all good to me is lost; +Evil, be thou my good; by thee at least +Divided empire with Heaven's King I hold, +By thee, and more than half perhaps will reign; +As Man ere long, and this new world, shall know. +Thus while he spake, each passion dimmed his face +Thrice changed with pale, ire, envy, and despair; +Which marred his borrowed visage, and betrayed +Him counterfeit, if any eye beheld. +For heavenly minds from such distempers foul +Are ever clear. Whereof he soon aware, +Each perturbation smoothed with outward calm, +Artificer of fraud; and was the first +That practised falsehood under saintly show, +Deep malice to conceal, couched with revenge: +Yet not enough had practised to deceive +Uriel once warned; whose eye pursued him down + The way he went, and on the Assyrian mount + Saw him disfigured, more than could befall + Spirit of happy sort; his gestures fierce + He marked and mad demeanour, then alone, + As he supposed, all unobserved, unseen. + So on he fares, and to the border comes + Of Eden, where delicious Paradise, + Now nearer, crowns with her enclosure green, + As with a rural mound, the champaign head + Of a steep wilderness, whose hairy sides +Access denied; and overhead upgrew + Insuperable height of loftiest shade, + Cedar, and pine, and fir, and branching palm, + A sylvan scene, and, as the ranks ascend, + Shade above shade, a woody theatre + Of stateliest view. Yet higher than their tops + The verdurous wall of Paradise upsprung; + + 00081429 +Which to our general sire gave prospect large +Into his nether empire neighbouring round. +And higher than that wall a circling row +Of goodliest trees, loaden with fairest fruit, +Blossoms and fruits at once of golden hue, +Appeared, with gay enamelled colours mixed: +On which the sun more glad impressed his beams +Than in fair evening cloud, or humid bow, +When God hath showered the earth; so lovely seemed +That landskip: And of pure now purer air +Meets his approach, and to the heart inspires +Vernal delight and joy, able to drive +All sadness but despair: Now gentle gales, +Fanning their odoriferous wings, dispense +Native perfumes, and whisper whence they stole +Those balmy spoils. As when to them who fail +Beyond the Cape of Hope, and now are past +Mozambick, off at sea north-east winds blow +Sabean odours from the spicy shore +Of Araby the blest; with such delay +Well pleased they slack their course, and many a league +Cheered with the grateful smell old Ocean smiles: +So entertained those odorous sweets the Fiend, +Who came their bane; though with them better pleased +Than Asmodeus with the fishy fume +That drove him, though enamoured, from the spouse +Of Tobit's son, and with a vengeance sent +From Media post to Egypt, there fast bound. +Now to the ascent of that steep savage hill +Satan had journeyed on, pensive and slow; +But further way found none, so thick entwined, +As one continued brake, the undergrowth +Of shrubs and tangling bushes had perplexed +All path of man or beast that passed that way. +One gate there only was, and that looked east +On the other side: which when the arch-felon saw, +Due entrance he disdained; and, in contempt, +At one flight bound high over-leaped all bound +Of hill or highest wall, and sheer within +Lights on his feet. As when a prowling wolf, +Whom hunger drives to seek new haunt for prey, +Watching where shepherds pen their flocks at eve +In hurdled cotes amid the field secure, +Leaps o'er the fence with ease into the fold: +Or as a thief, bent to unhoard the cash +Of some rich burgher, whose substantial doors, +Cross-barred and bolted fast, fear no assault, +In at the window climbs, or o'er the tiles: +So clomb this first grand thief into God's fold; +So since into his church lewd hirelings climb. +Thence up he flew, and on the tree of life, +The middle tree and highest there that grew, +Sat like a cormorant; yet not true life +Thereby regained, but sat devising death +To them who lived; nor on the virtue thought +Of that life-giving plant, but only used +For prospect, what well used had been the pledge +Of immortality. So little knows +Any, but God alone, to value right +The good before him, but perverts best things +To worst abuse, or to their meanest use. +Beneath him with new wonder now he views, +To all delight of human sense exposed, +In narrow room, Nature's whole wealth, yea more, +A Heaven on Earth: For blissful Paradise +Of God the garden was, by him in the east +Of Eden planted; Eden stretched her line +From Auran eastward to the royal towers +Of great Seleucia, built by Grecian kings, +Of where the sons of Eden long before +Dwelt in Telassar: In this pleasant soil +His far more pleasant garden God ordained; +Out of the fertile ground he caused to grow +All trees of noblest kind for sight, smell, taste; +And all amid them stood the tree of life, +High eminent, blooming ambrosial fruit +Of vegetable gold; and next to life, +Our death, the tree of knowledge, grew fast by, +Knowledge of good bought dear by knowing ill. +Southward through Eden went a river large, +Nor changed his course, but through the shaggy hill +Passed underneath ingulfed; for God had thrown +That mountain as his garden-mould high raised +Upon the rapid current, which, through veins +Of porous earth with kindly thirst up-drawn, +Rose a fresh fountain, and with many a rill +Watered the garden; thence united fell +Down the steep glade, and met the nether flood, +Which from his darksome passage now appears, +And now, divided into four main streams, +Runs diverse, wandering many a famous realm +And country, whereof here needs no account; +But rather to tell how, if Art could tell, +How from that sapphire fount the crisped brooks, +Rolling on orient pearl and sands of gold, +With mazy errour under pendant shades +Ran nectar, visiting each plant, and fed +Flowers worthy of Paradise, which not nice Art +In beds and curious knots, but Nature boon +Poured forth profuse on hill, and dale, and plain, +Both where the morning sun first warmly smote +The open field, and where the unpierced shade +Imbrowned the noontide bowers: Thus was this place +A happy rural seat of various view; +Groves whose rich trees wept odorous gums and balm, +Others whose fruit, burnished with golden rind, +Hung amiable, Hesperian fables true, +If true, here only, and of delicious taste: +Betwixt them lawns, or level downs, and flocks +Grazing the tender herb, were interposed, +Or palmy hillock; or the flowery lap +Of some irriguous valley spread her store, +Flowers of all hue, and without thorn the rose: +Another side, umbrageous grots and caves +Of cool recess, o'er which the mantling vine +Lays forth her purple grape, and gently creeps +Luxuriant; mean while murmuring waters fall +Down the slope hills, dispersed, or in a lake, +That to the fringed bank with myrtle crowned +Her crystal mirrour holds, unite their streams. +The birds their quire apply; airs, vernal airs, +Breathing the smell of field and grove, attune +The trembling leaves, while universal Pan, +Knit with the Graces and the Hours in dance, +Led on the eternal Spring. Not that fair field +Of Enna, where Proserpine gathering flowers, +Herself a fairer flower by gloomy Dis +Was gathered, which cost Ceres all that pain +To seek her through the world; nor that sweet grove +Of Daphne by Orontes, and the inspired +Castalian spring, might with this Paradise +Of Eden strive; nor that Nyseian isle +Girt with the river Triton, where old Cham, +Whom Gentiles Ammon call and Libyan Jove, +Hid Amalthea, and her florid son +Young Bacchus, from his stepdame Rhea's eye; +Nor where Abassin kings their issue guard, +Mount Amara, though this by some supposed +True Paradise under the Ethiop line +By Nilus' head, enclosed with shining rock, +A whole day's journey high, but wide remote +From this Assyrian garden, where the Fiend +Saw, undelighted, all delight, all kind +Of living creatures, new to sight, and strange +Two of far nobler shape, erect and tall, +Godlike erect, with native honour clad +In naked majesty seemed lords of all: +And worthy seemed; for in their looks divine +The image of their glorious Maker shone, +Truth, wisdom, sanctitude severe and pure, +(Severe, but in true filial freedom placed,) +Whence true authority in men; though both +Not equal, as their sex not equal seemed; +For contemplation he and valour formed; +For softness she and sweet attractive grace; +He for God only, she for God in him: +His fair large front and eye sublime declared +Absolute rule; and hyacinthine locks +Round from his parted forelock manly hung +Clustering, but not beneath his shoulders broad: +She, as a veil, down to the slender waist +Her unadorned golden tresses wore +Dishevelled, but in wanton ringlets waved +As the vine curls her tendrils, which implied +Subjection, but required with gentle sway, +And by her yielded, by him best received, +Yielded with coy submission, modest pride, +And sweet, reluctant, amorous delay. +Nor those mysterious parts were then concealed; +Then was not guilty shame, dishonest shame +Of nature's works, honour dishonourable, +Sin-bred, how have ye troubled all mankind +With shows instead, mere shows of seeming pure, +And banished from man's life his happiest life, +Simplicity and spotless innocence! +So passed they naked on, nor shunned the sight +Of God or Angel; for they thought no ill: +So hand in hand they passed, the loveliest pair, +That ever since in love's embraces met; +Adam the goodliest man of men since born +His sons, the fairest of her daughters Eve. +Under a tuft of shade that on a green +Stood whispering soft, by a fresh fountain side +They sat them down; and, after no more toil +Of their sweet gardening labour than sufficed +To recommend cool Zephyr, and made ease +More easy, wholesome thirst and appetite +More grateful, to their supper-fruits they fell, +Nectarine fruits which the compliant boughs +Yielded them, side-long as they sat recline +On the soft downy bank damasked with flowers: +The savoury pulp they chew, and in the rind, +Still as they thirsted, scoop the brimming stream; +Nor gentle purpose, nor endearing smiles +Wanted, nor youthful dalliance, as beseems +Fair couple, linked in happy nuptial league, +Alone as they. About them frisking played +All beasts of the earth, since wild, and of all chase +In wood or wilderness, forest or den; +Sporting the lion ramped, and in his paw +Dandled the kid; bears, tigers, ounces, pards, +Gambolled before them; the unwieldy elephant, +To make them mirth, used all his might, and wreathed +His?kithetmroboscis; close the serpent sly, +Insinuating, wove with Gordian twine +His braided train, and of his fatal guile +Gave proof unheeded; others on the grass +Couched, and now filled with pasture gazing sat, +Or bedward ruminating; for the sun, +Declined, was hasting now with prone career +To the ocean isles, and in the ascending scale +Of Heaven the stars that usher evening rose: +When Satan still in gaze, as first he stood, +Scarce thus at length failed speech recovered sad. +O Hell! what do mine eyes with grief behold! +Into our room of bliss thus high advanced +Creatures of other mould, earth-born perhaps, +Not Spirits, yet to heavenly Spirits bright +Little inferiour; whom my thoughts pursue +With wonder, and could love, so lively shines +In them divine resemblance, and such grace +The hand that formed them on their shape hath poured. +Ah! gentle pair, ye little think how nigh +Your change approaches, when all these delights +Will vanish, and deliver ye to woe; +More woe, the more your taste is now of joy; +Happy, but for so happy ill secured +Long to continue, and this high seat your Heaven +Ill fenced for Heaven to keep out such a foe +As now is entered; yet no purposed foe +To you, whom I could pity thus forlorn, +Though I unpitied: League with you I seek, +And mutual amity, so strait, so close, +That I with you must dwell, or you with me +Henceforth; my dwelling haply may not please, +Like this fair Paradise, your sense; yet such +Accept your Maker's work; he gave it me, +Which I as freely give: Hell shall unfold, +To entertain you two, her widest gates, +And send forth all her kings; there will be room, +Not like these narrow limits, to receive +Your numerous offspring; if no better place, +Thank him who puts me loth to this revenge +On you who wrong me not for him who wronged. +And should I at your harmless innocence +Melt, as I do, yet publick reason just, +Honour and empire with revenge enlarged, +By conquering this new world, compels me now +To do what else, though damned, I should abhor. +So spake the Fiend, and with necessity, +The tyrant's plea, excused his devilish deeds. +Then from his lofty stand on that high tree +Down he alights among the sportful herd +Of those four-footed kinds, himself now one, +Now other, as their shape served best his end +Nearer to view his prey, and, unespied, +To mark what of their state he more might learn, +By word or action marked. About them round +A lion now he stalks with fiery glare; +Then as a tiger, who by chance hath spied +In some purlieu two gentle fawns at play, +Straight couches close, then, rising, changes oft +His couchant watch, as one who chose his ground, +Whence rushing, he might surest seize them both, +Griped in each paw: when, Adam first of men +To first of women Eve thus moving speech, +Turned him, all ear to hear new utterance flow. +Sole partner, and sole part, of all these joys, +Dearer thyself than all; needs must the Power +That made us, and for us this ample world, +Be infinitely good, and of his good +As liberal and free as infinite; +That raised us from the dust, and placed us here +In all this happiness, who at his hand +Have nothing merited, nor can perform +Aught whereof he hath need; he who requires +From us no other service than to keep +This one, this easy charge, of all the trees +In Paradise that bear delicious fruit +So various, not to taste that only tree +Of knowledge, planted by the tree of life; +So near grows death to life, whate'er death is, +Some dreadful thing no doubt; for well thou knowest +God hath pronounced it death to taste that tree, +The only sign of our obedience left, +Among so many signs of power and rule +Conferred upon us, and dominion given +Over all other creatures that possess +Earth, air, and sea. Then let us not think hard +One easy prohibition, who enjoy +Free leave so large to all things else, and choice +Unlimited of manifold delights: +But let us ever praise him, and extol +His bounty, following our delightful task, +To prune these growing plants, and tend these flowers, +Which were it toilsome, yet with thee were sweet. +To whom thus Eve replied. O thou for whom +And from whom I was formed, flesh of thy flesh, +And without whom am to no end, my guide +And head! what thou hast said is just and right. +For we to him indeed all praises owe, +And daily thanks; I chiefly, who enjoy +So far the happier lot, enjoying thee +Pre-eminent by so much odds, while thou +Like consort to thyself canst no where find. +That day I oft remember, when from sleep +I first awaked, and found myself reposed +Under a shade on flowers, much wondering where +And what I was, whence thither brought, and how. +Not distant far from thence a murmuring sound +Of waters issued from a cave, and spread +Into a liquid plain, then stood unmoved +Pure as the expanse of Heaven; I thither went +With unexperienced thought, and laid me down +On the green bank, to look into the clear +Smooth lake, that to me seemed another sky. +As I bent down to look, just opposite +A shape within the watery gleam appeared, +Bending to look on me: I started back, +It started back; but pleased I soon returned, +Pleased it returned as soon with answering looks +Of sympathy and love: There I had fixed +Mine eyes till now, and pined with vain desire, +Had not a voice thus warned me; 'What thou seest, +'What there thou seest, fair Creature, is thyself; +'With thee it came and goes: but follow me, +'And I will bring thee where no shadow stays +'Thy coming, and thy soft embraces, he +'Whose image thou art; him thou shalt enjoy +'Inseparably thine, to him shalt bear +'Multitudes like thyself, and thence be called +'Mother of human race.' What could I do, +But follow straight, invisibly thus led? +Till I espied thee, fair indeed and tall, +Under a platane; yet methought less fair, +Less winning soft, less amiably mild, +Than that smooth watery image: Back I turned; +Thou following cryedst aloud, 'Return, fair Eve; +'Whom flyest thou? whom thou flyest, of him thou art, +'His flesh, his bone; to give thee being I lent +'Out of my side to thee, nearest my heart, +'Substantial life, to have thee by my side +'Henceforth an individual solace dear; +'Part of my soul I seek thee, and thee claim +'My other half:' With that thy gentle hand +Seised mine: I yielded;and from that time see +How beauty is excelled by manly grace, +And wisdom, which alone is truly fair. +So spake our general mother, and with eyes +Of conjugal attraction unreproved, +And meek surrender, half-embracing leaned +On our first father; half her swelling breast +Naked met his, under the flowing gold +Of her loose tresses hid: he in delight +Both of her beauty, and submissive charms, +Smiled with superiour love, as Jupiter +On Juno smiles, when he impregns the clouds +That shed Mayflowers; and pressed her matron lip +With kisses pure: Aside the Devil turned +For envy; yet with jealous leer malign +Eyed them askance, and to himself thus plained. +Sight hateful, sight tormenting! thus these two, +Imparadised in one another's arms, +The happier Eden, shall enjoy their fill +Of bliss on bliss; while I to Hell am thrust, +Where neither joy nor love, but fierce desire, +Among our other torments not the least, +Still unfulfilled with pain of longing pines. +Yet let me not forget what I have gained +From their own mouths: All is not theirs, it seems; +One fatal tree there stands, of knowledge called, +Forbidden them to taste: Knowledge forbidden +Suspicious, reasonless. Why should their Lord +Envy them that? Can it be sin to know? +Can it be death? And do they only stand +By ignorance? Is that their happy state, +The proof of their obedience and their faith? +O fair foundation laid whereon to build +Their ruin! hence I will excite their minds +With more desire to know, and to reject +Envious commands, invented with design +To keep them low, whom knowledge might exalt +Equal with Gods: aspiring to be such, +They taste and die: What likelier can ensue +But first with narrow search I must walk round +This garden, and no corner leave unspied; +A chance but chance may lead where I may meet +Some wandering Spirit of Heaven by fountain side, +Or in thick shade retired, from him to draw +What further would be learned. Live while ye may, +Yet happy pair; enjoy, till I return, +Short pleasures, for long woes are to succeed! +So saying, his proud step he scornful turned, +But with sly circumspection, and began +Through wood, through waste, o'er hill, o'er dale, his roam +Mean while in utmost longitude, where Heaven +With earth and ocean meets, the setting sun +Slowly descended, and with right aspect +Against the eastern gate of Paradise +Levelled his evening rays: It was a rock +Of alabaster, piled up to the clouds, +Conspicuous far, winding with one ascent +Accessible from earth, one entrance high; +The rest was craggy cliff, that overhung +Still as it rose, impossible to climb. +Betwixt these rocky pillars Gabriel sat, +Chief of the angelick guards, awaiting night; +About him exercised heroick games +The unarmed youth of Heaven, but nigh at hand +Celestial armoury, shields, helms, and spears, +Hung high with diamond flaming, and with gold. +Thither came Uriel, gliding through the even +On a sun-beam, swift as a shooting star +In autumn thwarts the night, when vapours fired +Impress the air, and shows the mariner +From what point of his compass to beware +Impetuous winds: He thus began in haste. +Gabriel, to thee thy course by lot hath given +Charge and strict watch, that to this happy place +No evil thing approach or enter in. +This day at highth of noon came to my sphere +A Spirit, zealous, as he seemed, to know +More of the Almighty's works, and chiefly Man, +God's latest image: I described his way +Bent all on speed, and marked his aery gait; +But in the mount that lies from Eden north, +Where he first lighted, soon discerned his looks +Alien from Heaven, with passions foul obscured: +Mine eye pursued him still, but under shade +Lost sight of him: One of the banished crew, +I fear, hath ventured from the deep, to raise +New troubles; him thy care must be to find. +To whom the winged warriour thus returned. +Uriel, no wonder if thy perfect sight, +Amid the sun's bright circle where thou sitst, +See far and wide: In at this gate none pass +The vigilance here placed, but such as come +Well known from Heaven; and since meridian hour +No creature thence: If Spirit of other sort, +So minded, have o'er-leaped these earthly bounds +On purpose, hard thou knowest it to exclude +Spiritual substance with corporeal bar. +But if within the circuit of these walks, +In whatsoever shape he lurk, of whom +Thou tellest, by morrow dawning I shall know. +So promised he; and Uriel to his charge +Returned on that bright beam, whose point now raised +Bore him slope downward to the sun now fallen +Beneath the Azores; whether the prime orb, +Incredible how swift, had thither rolled +Diurnal, or this less volubil earth, +By shorter flight to the east, had left him there +Arraying with reflected purple and gold +The clouds that on his western throne attend. +Now came still Evening on, and Twilight gray +Had in her sober livery all things clad; +Silence accompanied; for beast and bird, +They to their grassy couch, these to their nests +Were slunk, all but the wakeful nightingale; +She all night long her amorous descant sung; +Silence was pleased: Now glowed the firmament +With living sapphires: Hesperus, that led +The starry host, rode brightest, till the moon, +Rising in clouded majesty, at length +Apparent queen unveiled her peerless light, +And o'er the dark her silver mantle threw. +When Adam thus to Eve. Fair Consort, the hour +Of night, and all things now retired to rest, +Mind us of like repose; since God hath set +Labour and rest, as day and night, to men +Successive; and the timely dew of sleep, +Now falling with soft slumbrous weight, inclines +Our eye-lids: Other creatures all day long +Rove idle, unemployed, and less need rest; +Man hath his daily work of body or mind +Appointed, which declares his dignity, +And the regard of Heaven on all his ways; +While other animals unactive range, +And of their doings God takes no account. +To-morrow, ere fresh morning streak the east +With first approach of light, we must be risen, +And at our pleasant labour, to reform +Yon flowery arbours, yonder alleys green, +Our walk at noon, with branches overgrown, +That mock our scant manuring, and require +More hands than ours to lop their wanton growth: +Those blossoms also, and those dropping gums, +That lie bestrown, unsightly and unsmooth, +Ask riddance, if we mean to tread with ease; +Mean while, as Nature wills, night bids us rest. +To whom thus Eve, with perfect beauty adorned +My Author and Disposer, what thou bidst +Unargued I obey: So God ordains; +God is thy law, thou mine: To know no more +Is woman's happiest knowledge, and her praise. +With thee conversing I forget all time; +All seasons, and their change, all please alike. +Sweet is the breath of Morn, her rising sweet, +With charm of earliest birds: pleasant the sun, +When first on this delightful land he spreads +His orient beams, on herb, tree, fruit, and flower, +Glistering with dew; fragrant the fertile earth +After soft showers; and sweet the coming on +Of grateful Evening mild; then silent Night, +With this her solemn bird, and this fair moon, +And these the gems of Heaven, her starry train: +But neither breath of Morn, when she ascends +With charm of earliest birds; nor rising sun +On this delightful land; nor herb, fruit, flower, +Glistering with dew; nor fragrance after showers; +Nor grateful Evening mild; nor silent Night, +With this her solemn bird, nor walk by moon, +Or glittering star-light, without thee is sweet. +But wherefore all night long shine these? for whom +This glorious sight, when sleep hath shut all eyes? +To whom our general ancestor replied. +Daughter of God and Man, accomplished Eve, +These have their course to finish round the earth, +By morrow evening, and from land to land +In order, though to nations yet unborn, +Ministring light prepared, they set and rise; +Lest total Darkness should by night regain +Her old possession, and extinguish life +In Nature and all things; which these soft fires +Not only enlighten, but with kindly heat +Of various influence foment and warm, +Temper or nourish, or in part shed down +Their stellar virtue on all kinds that grow +On earth, made hereby apter to receive +Perfection from the sun's more potent ray. +These then, though unbeheld in deep of night, +Shine not in vain; nor think, though men were none, +That Heaven would want spectators, God want praise: +Millions of spiritual creatures walk the earth +Unseen, both when we wake, and when we sleep: +All these with ceaseless praise his works behold +Both day and night: How often from the steep +Of echoing hill or thicket have we heard +Celestial voices to the midnight air, +Sole, or responsive each to others note, +Singing their great Creator? oft in bands +While they keep watch, or nightly rounding walk, +With heavenly touch of instrumental sounds +In full harmonick number joined, their songs +Divide the night, and lift our thoughts to Heaven. +Thus talking, hand in hand alone they passed +On to their blissful bower: it was a place +Chosen by the sovran Planter, when he framed +All things to Man's delightful use; the roof +Of thickest covert was inwoven shade +Laurel and myrtle, and what higher grew +Of firm and fragrant leaf; on either side +Acanthus, and each odorous bushy shrub, +Fenced up the verdant wall; each beauteous flower, +Iris all hues, roses, and jessamin, +Reared high their flourished heads between, and wrought +Mosaick; underfoot the violet, +Crocus, and hyacinth, with rich inlay +Broidered the ground, more coloured than with stone +Of costliest emblem: Other creature here, +Bird, beast, insect, or worm, durst enter none, +Such was their awe of Man. In shadier bower +More sacred and sequestered, though but feigned, +Pan or Sylvanus never slept, nor Nymph +Nor Faunus haunted. Here, in close recess, +With flowers, garlands, and sweet-smelling herbs, +Espoused Eve decked first her nuptial bed; +And heavenly quires the hymenaean sung, +What day the genial Angel to our sire +Brought her in naked beauty more adorned, +More lovely, than Pandora, whom the Gods +Endowed with all their gifts, and O! too like +In sad event, when to the unwiser son +Of Japhet brought by Hermes, she ensnared +Mankind with her fair looks, to be avenged +On him who had stole Jove's authentick fire. +Thus, at their shady lodge arrived, both stood, +Both turned, and under open sky adored +The God that made both sky, air, earth, and heaven, +Which they beheld, the moon's resplendent globe, +And starry pole: Thou also madest the night, +Maker Omnipotent, and thou the day, +Which we, in our appointed work employed, +Have finished, happy in our mutual help +And mutual love, the crown of all our bliss +Ordained by thee; and this delicious place +For us too large, where thy abundance wants +Partakers, and uncropt falls to the ground. +But thou hast promised from us two a race +To fill the earth, who shall with us extol +Thy goodness infinite, both when we wake, +And when we seek, as now, thy gift of sleep. +This said unanimous, and other rites +Observing none, but adoration pure +Which God likes best, into their inmost bower +Handed they went; and, eased the putting off +These troublesome disguises which we wear, +Straight side by side were laid; nor turned, I ween, +Adam from his fair spouse, nor Eve the rites +Mysterious of connubial love refused: +Whatever hypocrites austerely talk +Of purity, and place, and innocence, +Defaming as impure what God declares +Pure, and commands to some, leaves free to all. +Our Maker bids encrease; who bids abstain +But our Destroyer, foe to God and Man? +Hail, wedded Love, mysterious law, true source +Of human offspring, sole propriety +In Paradise of all things common else! +By thee adulterous Lust was driven from men +Among the bestial herds to range; by thee +Founded in reason, loyal, just, and pure, +Relations dear, and all the charities +Of father, son, and brother, first were known. +Far be it, that I should write thee sin or blame, +Or think thee unbefitting holiest place, +Perpetual fountain of domestick sweets, +Whose bed is undefiled and chaste pronounced, +Present, or past, as saints and patriarchs used. +Here Love his golden shafts employs, here lights +His constant lamp, and waves his purple wings, +Reigns here and revels; not in the bought smile +Of harlots, loveless, joyless, unendeared, +Casual fruition; nor in court-amours, +Mixed dance, or wanton mask, or midnight ball, +Or serenate, which the starved lover sings +To his proud fair, best quitted with disdain. +These, lulled by nightingales, embracing slept, +And on their naked limbs the flowery roof +Showered roses, which the morn repaired. Sleep on, +Blest pair; and O!yet happiest, if ye seek +No happier state, and know to know no more. +Now had night measured with her shadowy cone +Half way up hill this vast sublunar vault, +And from their ivory port the Cherubim, +Forth issuing at the accustomed hour, stood armed +To their night watches in warlike parade; +When Gabriel to his next in power thus spake. +Uzziel, half these draw off, and coast the south +With strictest watch; these other wheel the north; +Our circuit meets full west. As flame they part, +Half wheeling to the shield, half to the spear. +From these, two strong and subtle Spirits he called +That near him stood, and gave them thus in charge. +Ithuriel and Zephon, with winged speed +Search through this garden, leave unsearched no nook; +But chiefly where those two fair creatures lodge, +Now laid perhaps asleep, secure of harm. +This evening from the sun's decline arrived, +Who tells of some infernal Spirit seen +Hitherward bent (who could have thought?) escaped +The bars of Hell, on errand bad no doubt: +Such, where ye find, seise fast, and hither bring. +So saying, on he led his radiant files, +Dazzling the moon; these to the bower direct +In search of whom they sought: Him there they found +Squat like a toad, close at the ear of Eve, +Assaying by his devilish art to reach +The organs of her fancy, and with them forge +Illusions, as he list, phantasms and dreams; +Or if, inspiring venom, he might taint +The animal spirits, that from pure blood arise +Like gentle breaths from rivers pure, thence raise +At least distempered, discontented thoughts, +Vain hopes, vain aims, inordinate desires, +Blown up with high conceits ingendering pride. +Him thus intent Ithuriel with his spear +Touched lightly; for no falshood can endure +Touch of celestial temper, but returns +Of force to its own likeness: Up he starts +Discovered and surprised. As when a spark +Lights on a heap of nitrous powder, laid +Fit for the tun some magazine to store +Against a rumoured war, the smutty grain, +With sudden blaze diffused, inflames the air; +So started up in his own shape the Fiend. +Back stept those two fair Angels, half amazed +So sudden to behold the grisly king; +Yet thus, unmoved with fear, accost him soon. +Which of those rebel Spirits adjudged to Hell +Comest thou, escaped thy prison? and, transformed, +Why sat'st thou like an enemy in wait, +Here watching at the head of these that sleep? +Know ye not then said Satan, filled with scorn, +Know ye not me? ye knew me once no mate +For you, there sitting where ye durst not soar: +Not to know me argues yourselves unknown, +The lowest of your throng; or, if ye know, +Why ask ye, and superfluous begin +Your message, like to end as much in vain? +To whom thus Zephon, answering scorn with scorn. +Think not, revolted Spirit, thy shape the same, +Or undiminished brightness to be known, +As when thou stoodest in Heaven upright and pure; +That glory then, when thou no more wast good, +Departed from thee; and thou resemblest now +Thy sin and place of doom obscure and foul. +But come, for thou, be sure, shalt give account +To him who sent us, whose charge is to keep +This place inviolable, and these from harm. +So spake the Cherub; and his grave rebuke, +Severe in youthful beauty, added grace +Invincible: Abashed the Devil stood, +And felt how awful goodness is, and saw +Virtue in her shape how lovely; saw, and pined +His loss; but chiefly to find here observed +His lustre visibly impaired; yet seemed +Undaunted. If I must contend, said he, +Best with the best, the sender, not the sent, +Or all at once; more glory will be won, +Or less be lost. Thy fear, said Zephon bold, +Will save us trial what the least can do +Single against thee wicked, and thence weak. +The Fiend replied not, overcome with rage; +But, like a proud steed reined, went haughty on, +Champing his iron curb: To strive or fly +He held it vain; awe from above had quelled +His heart, not else dismayed. Now drew they nigh +The western point, where those half-rounding guards +Just met, and closing stood in squadron joined, +A waiting next command. To whom their Chief, +Gabriel, from the front thus called aloud. +O friends! I hear the tread of nimble feet +Hasting this way, and now by glimpse discern +Ithuriel and Zephon through the shade; +And with them comes a third of regal port, +But faded splendour wan; who by his gait +And fierce demeanour seems the Prince of Hell, +Not likely to part hence without contest; +Stand firm, for in his look defiance lours. +He scarce had ended, when those two approached, +And brief related whom they brought, where found, +How busied, in what form and posture couched. +To whom with stern regard thus Gabriel spake. +Why hast thou, Satan, broke the bounds prescribed +To thy transgressions, and disturbed the charge +Of others, who approve not to transgress +By thy example, but have power and right +To question thy bold entrance on this place; +Employed, it seems, to violate sleep, and those +Whose dwelling God hath planted here in bliss! +To whom thus Satan with contemptuous brow. +Gabriel? thou hadst in Heaven the esteem of wise, +And such I held thee; but this question asked +Puts me in doubt. Lives there who loves his pain! +Who would not, finding way, break loose from Hell, +Though thither doomed! Thou wouldst thyself, no doubt +And boldly venture to whatever place +Farthest from pain, where thou mightst hope to change +Torment with ease, and soonest recompense +Dole with delight, which in this place I sought; +To thee no reason, who knowest only good, +But evil hast not tried: and wilt object +His will who bounds us! Let him surer bar +His iron gates, if he intends our stay +In that dark durance: Thus much what was asked. +The rest is true, they found me where they say; +But that implies not violence or harm. +Thus he in scorn. The warlike Angel moved, +Disdainfully half smiling, thus replied. +O loss of one in Heaven to judge of wise +Since Satan fell, whom folly overthrew, +And now returns him from his prison 'scaped, +Gravely in doubt whether to hold them wise +Or not, who ask what boldness brought him hither +Unlicensed from his bounds in Hell prescribed; +So wise he judges it to fly from pain +However, and to 'scape his punishment! +So judge thou still, presumptuous! till the wrath, +Which thou incurrest by flying, meet thy flight +Sevenfold, and scourge that wisdom back to Hell, +Which taught thee yet no better, that no pain +Can equal anger infinite provoked. +But wherefore thou alone? wherefore with thee +Came not all hell broke loose? or thou than they +Less hardy to endure? Courageous Chief! +The first in flight from pain! hadst thou alleged +To thy deserted host this cause of flight, +Thou surely hadst not come sole fugitive. +To which the Fiend thus answered, frowning stern. +Not that I less endure, or shrink from pain, +Insulting Angel! well thou knowest I stood +Thy fiercest, when in battle to thy aid +The blasting vollied thunder made all speed, +And seconded thy else not dreaded spear. +But still thy words at random, as before, +Argue thy inexperience what behoves +From hard assays and ill successes past +A faithful leader, not to hazard all +Through ways of danger by himself untried: +I, therefore, I alone first undertook +To wing the desolate abyss, and spy +This new created world, whereof in Hell +Fame is not silent, here in hope to find +Better abode, and my afflicted Powers +To settle here on earth, or in mid air; +Though for possession put to try once more +What thou and thy gay legions dare against; +Whose easier business were to serve their Lord +High up in Heaven, with songs to hymn his throne, +And practised distances to cringe, not fight, +To whom the warriour Angel soon replied. +To say and straight unsay, pretending first +Wise to fly pain, professing next the spy, +Argues no leader but a liear traced, +Satan, and couldst thou faithful add? O name, +O sacred name of faithfulness profaned! +Faithful to whom? to thy rebellious crew? +Army of Fiends, fit body to fit head. +Was this your discipline and faith engaged, +Your military obedience, to dissolve +Allegiance to the acknowledged Power supreme? +And thou, sly hypocrite, who now wouldst seem +Patron of liberty, who more than thou +Once fawned, and cringed, and servily adored +Heaven's awful Monarch? wherefore, but in hope +To dispossess him, and thyself to reign? +But mark what I arreed thee now, Avant; +Fly neither whence thou fledst! If from this hour +Within these hallowed limits thou appear, +Back to the infernal pit I drag thee chained, +And seal thee so, as henceforth not to scorn +The facile gates of Hell too slightly barred. +So threatened he; but Satan to no threats +Gave heed, but waxing more in rage replied. +Then when I am thy captive talk of chains, +Proud limitary Cherub! but ere then +Far heavier load thyself expect to feel +From my prevailing arm, though Heaven's King +Ride on thy wings, and thou with thy compeers, +Us'd to the yoke, drawest his triumphant wheels +In progress through the road of Heaven star-paved. +While thus he spake, the angelick squadron bright +Turned fiery red, sharpening in mooned horns +Their phalanx, and began to hem him round +With ported spears, as thick as when a field +Of Ceres ripe for harvest waving bends +Her bearded grove of ears, which way the wind +Sways them; the careful plowman doubting stands, +Left on the threshing floor his hopeless sheaves +Prove chaff. On the other side, Satan, alarmed, +Collecting all his might, dilated stood, +Like Teneriff or Atlas, unremoved: +His stature reached the sky, and on his crest +Sat Horrour plumed; nor wanted in his grasp +What seemed both spear and shield: Now dreadful deeds +Might have ensued, nor only Paradise +In this commotion, but the starry cope +Of Heaven perhaps, or all the elements +At least had gone to wrack, disturbed and torn +With violence of this conflict, had not soon +The Eternal, to prevent such horrid fray, +Hung forth in Heaven his golden scales, yet seen +Betwixt Astrea and the Scorpion sign, +Wherein all things created first he weighed, +The pendulous round earth with balanced air +In counterpoise, now ponders all events, +Battles and realms: In these he put two weights, +The sequel each of parting and of fight: +The latter quick up flew, and kicked the beam, +Which Gabriel spying, thus bespake the Fiend. +Satan, I know thy strength, and thou knowest mine; +Neither our own, but given: What folly then +To boast what arms can do? since thine no more +Than Heaven permits, nor mine, though doubled now +To trample thee as mire: For proof look up, +And read thy lot in yon celestial sign; +Where thou art weighed, and shown how light, how weak, +If thou resist. The Fiend looked up, and knew +His mounted scale aloft: Nor more;but fled +Murmuring, and with him fled the shades of night. + + + +Book V + + +Now Morn, her rosy steps in the eastern clime +Advancing, sowed the earth with orient pearl, +When Adam waked, so customed; for his sleep +Was aery-light, from pure digestion bred, +And temperate vapours bland, which the only sound +Of leaves and fuming rills, Aurora's fan, +Lightly dispersed, and the shrill matin song +Of birds on every bough; so much the more +His wonder was to find unwakened Eve +With tresses discomposed, and glowing cheek, +As through unquiet rest: He, on his side +Leaning half raised, with looks of cordial love +Hung over her enamoured, and beheld +Beauty, which, whether waking or asleep, +Shot forth peculiar graces; then with voice +Mild, as when Zephyrus on Flora breathes, +Her hand soft touching, whispered thus. Awake, +My fairest, my espoused, my latest found, +Heaven's last best gift, my ever new delight! +Awake: The morning shines, and the fresh field +Calls us; we lose the prime, to mark how spring +Our tender plants, how blows the citron grove, +What drops the myrrh, and what the balmy reed, +How nature paints her colours, how the bee +Sits on the bloom extracting liquid sweet. +Such whispering waked her, but with startled eye +On Adam, whom embracing, thus she spake. +O sole in whom my thoughts find all repose, +My glory, my perfection! glad I see +Thy face, and morn returned; for I this night +(Such night till this I never passed) have dreamed, +If dreamed, not, as I oft am wont, of thee, +Works of day past, or morrow's next design, +But of offence and trouble, which my mind +Knew never till this irksome night: Methought, +Close at mine ear one called me forth to walk +With gentle voice; I thought it thine: It said, +'Why sleepest thou, Eve? now is the pleasant time, +'The cool, the silent, save where silence yields +'To the night-warbling bird, that now awake +'Tunes sweetest his love-laboured song; now reigns +'Full-orbed the moon, and with more pleasing light +'Shadowy sets off the face of things; in vain, +'If none regard; Heaven wakes with all his eyes, +'Whom to behold but thee, Nature's desire? +'In whose sight all things joy, with ravishment +'Attracted by thy beauty still to gaze.' +I rose as at thy call, but found thee not; +To find thee I directed then my walk; +And on, methought, alone I passed through ways +That brought me on a sudden to the tree +Of interdicted knowledge: fair it seemed, +Much fairer to my fancy than by day: +And, as I wondering looked, beside it stood +One shaped and winged like one of those from Heaven +By us oft seen; his dewy locks distilled +Ambrosia; on that tree he also gazed; +And 'O fair plant,' said he, 'with fruit surcharged, +'Deigns none to ease thy load, and taste thy sweet, +'Nor God, nor Man? Is knowledge so despised? +'Or envy, or what reserve forbids to taste? +'Forbid who will, none shall from me withhold +'Longer thy offered good; why else set here? +This said, he paused not, but with venturous arm +He plucked, he tasted; me damp horrour chilled +At such bold words vouched with a deed so bold: +But he thus, overjoyed; 'O fruit divine, +'Sweet of thyself, but much more sweet thus cropt, +'Forbidden here, it seems, as only fit +'For Gods, yet able to make Gods of Men: +'And why not Gods of Men; since good, the more +'Communicated, more abundant grows, +'The author not impaired, but honoured more? +'Here, happy creature, fair angelick Eve! +'Partake thou also; happy though thou art, +'Happier thou mayest be, worthier canst not be: +'Taste this, and be henceforth among the Gods +'Thyself a Goddess, not to earth confined, +'But sometimes in the air, as we, sometimes +'Ascend to Heaven, by merit thine, and see +'What life the Gods live there, and such live thou!' +So saying, he drew nigh, and to me held, +Even to my mouth of that same fruit held part +Which he had plucked; the pleasant savoury smell +So quickened appetite, that I, methought, +Could not but taste. Forthwith up to the clouds +With him I flew, and underneath beheld +The earth outstretched immense, a prospect wide +And various: Wondering at my flight and change +To this high exaltation; suddenly +My guide was gone, and I, methought, sunk down, +And fell asleep; but O, how glad I waked +To find this but a dream! Thus Eve her night +Related, and thus Adam answered sad. +Best image of myself, and dearer half, +The trouble of thy thoughts this night in sleep +Affects me equally; nor can I like +This uncouth dream, of evil sprung, I fear; +Yet evil whence? in thee can harbour none, +Created pure. But know that in the soul +Are many lesser faculties, that serve +Reason as chief; among these Fancy next +Her office holds; of all external things +Which the five watchful senses represent, +She forms imaginations, aery shapes, +Which Reason, joining or disjoining, frames +All what we affirm or what deny, and call +Our knowledge or opinion; then retires +Into her private cell, when nature rests. +Oft in her absence mimick Fancy wakes +To imitate her; but, misjoining shapes, +Wild work produces oft, and most in dreams; +Ill matching words and deeds long past or late. +Some such resemblances, methinks, I find +Of our last evening's talk, in this thy dream, +But with addition strange; yet be not sad. +Evil into the mind of God or Man +May come and go, so unreproved, and leave +No spot or blame behind: Which gives me hope +That what in sleep thou didst abhor to dream, +Waking thou never will consent to do. +Be not disheartened then, nor cloud those looks, +That wont to be more cheerful and serene, +Than when fair morning first smiles on the world; +And let us to our fresh employments rise +Among the groves, the fountains, and the flowers +That open now their choisest bosomed smells, +Reserved from night, and kept for thee in store. +So cheered he his fair spouse, and she was cheered; +But silently a gentle tear let fall +From either eye, and wiped them with her hair; +Two other precious drops that ready stood, +Each in their crystal sluice, he ere they fell +Kissed, as the gracious signs of sweet remorse +And pious awe, that feared to have offended. +So all was cleared, and to the field they haste. +But first, from under shady arborous roof +Soon as they forth were come to open sight +Of day-spring, and the sun, who, scarce up-risen, +With wheels yet hovering o'er the ocean-brim, +Shot parallel to the earth his dewy ray, +Discovering in wide landskip all the east +Of Paradise and Eden's happy plains, +Lowly they bowed adoring, and began +Their orisons, each morning duly paid +In various style; for neither various style +Nor holy rapture wanted they to praise +Their Maker, in fit strains pronounced, or sung +Unmeditated; such prompt eloquence +Flowed from their lips, in prose or numerous verse, +More tuneable than needed lute or harp +To add more sweetness; and they thus began. +These are thy glorious works, Parent of good, +Almighty! Thine this universal frame, +Thus wonderous fair; Thyself how wonderous then! +Unspeakable, who sitst above these heavens +To us invisible, or dimly seen +In these thy lowest works; yet these declare +Thy goodness beyond thought, and power divine. +Speak, ye who best can tell, ye sons of light, +Angels; for ye behold him, and with songs +And choral symphonies, day without night, +Circle his throne rejoicing; ye in Heaven +On Earth join all ye Creatures to extol +Him first, him last, him midst, and without end. +Fairest of stars, last in the train of night, +If better thou belong not to the dawn, +Sure pledge of day, that crownest the smiling morn +With thy bright circlet, praise him in thy sphere, +While day arises, that sweet hour of prime. +Thou Sun, of this great world both eye and soul, +Acknowledge him thy greater; sound his praise +In thy eternal course, both when thou climbest, +And when high noon hast gained, and when thou fallest. +Moon, that now meetest the orient sun, now flyest, +With the fixed Stars, fixed in their orb that flies; +And ye five other wandering Fires, that move +In mystick dance not without song, resound +His praise, who out of darkness called up light. +Air, and ye Elements, the eldest birth +Of Nature's womb, that in quaternion run +Perpetual circle, multiform; and mix +And nourish all things; let your ceaseless change +Vary to our great Maker still new praise. +Ye Mists and Exhalations, that now rise +From hill or steaming lake, dusky or gray, +Till the sun paint your fleecy skirts with gold, +In honour to the world's great Author rise; +Whether to deck with clouds the uncoloured sky, +Or wet the thirsty earth with falling showers, +Rising or falling still advance his praise. +His praise, ye Winds, that from four quarters blow, +Breathe soft or loud; and, wave your tops, ye Pines, +With every plant, in sign of worship wave. +Fountains, and ye that warble, as ye flow, +Melodious murmurs, warbling tune his praise. +Join voices, all ye living Souls: Ye Birds, +That singing up to Heaven-gate ascend, +Bear on your wings and in your notes his praise. +Ye that in waters glide, and ye that walk +The earth, and stately tread, or lowly creep; +Witness if I be silent, morn or even, +To hill, or valley, fountain, or fresh shade, +Made vocal by my song, and taught his praise. +Hail, universal Lord, be bounteous still +To give us only good; and if the night +Have gathered aught of evil, or concealed, +Disperse it, as now light dispels the dark! +So prayed they innocent, and to their thoughts +Firm peace recovered soon, and wonted calm. +On to their morning's rural work they haste, +Among sweet dews and flowers; where any row +Of fruit-trees over-woody reached too far +Their pampered boughs, and needed hands to check +Fruitless embraces: or they led the vine +To wed her elm; she, spoused, about him twines +Her marriageable arms, and with him brings +Her dower, the adopted clusters, to adorn +His barren leaves. Them thus employed beheld +With pity Heaven's high King, and to him called +Raphael, the sociable Spirit, that deigned +To travel with Tobias, and secured +His marriage with the seventimes-wedded maid. +Raphael, said he, thou hearest what stir on Earth +Satan, from Hell 'scaped through the darksome gulf, +Hath raised in Paradise; and how disturbed +This night the human pair; how he designs +In them at once to ruin all mankind. +Go therefore, half this day as friend with friend +Converse with Adam, in what bower or shade +Thou findest him from the heat of noon retired, +To respite his day-labour with repast, +Or with repose; and such discourse bring on, +As may advise him of his happy state, +Happiness in his power left free to will, +Left to his own free will, his will though free, +Yet mutable; whence warn him to beware +He swerve not, too secure: Tell him withal +His danger, and from whom; what enemy, +Late fallen himself from Heaven, is plotting now +The fall of others from like state of bliss; +By violence? no, for that shall be withstood; +But by deceit and lies: This let him know, +Lest, wilfully transgressing, he pretend +Surprisal, unadmonished, unforewarned. +So spake the Eternal Father, and fulfilled +All justice: Nor delayed the winged Saint +After his charge received; but from among +Thousand celestial Ardours, where he stood +Veiled with his gorgeous wings, up springing light, +Flew through the midst of Heaven; the angelick quires, +On each hand parting, to his speed gave way +Through all the empyreal road; till, at the gate +Of Heaven arrived, the gate self-opened wide +On golden hinges turning, as by work +Divine the sovran Architect had framed. +From hence no cloud, or, to obstruct his sight, +Star interposed, however small he sees, +Not unconformed to other shining globes, +Earth, and the garden of God, with cedars crowned +Above all hills. As when by night the glass +Of Galileo, less assured, observes +Imagined lands and regions in the moon: +Or pilot, from amidst the Cyclades +Delos or Samos first appearing, kens +A cloudy spot. Down thither prone in flight +He speeds, and through the vast ethereal sky +Sails between worlds and worlds, with steady wing +Now on the polar winds, then with quick fan +Winnows the buxom air; till, within soar +Of towering eagles, to all the fowls he seems +A phoenix, gazed by all as that sole bird, +When, to enshrine his reliques in the Sun's +Bright temple, to Egyptian Thebes he flies. +At once on the eastern cliff of Paradise +He lights, and to his proper shape returns +A Seraph winged: Six wings he wore, to shade +His lineaments divine; the pair that clad +Each shoulder broad, came mantling o'er his breast +With regal ornament; the middle pair +Girt like a starry zone his waist, and round +Skirted his loins and thighs with downy gold +And colours dipt in Heaven; the third his feet +Shadowed from either heel with feathered mail, +Sky-tinctured grain. Like Maia's son he stood, +And shook his plumes, that heavenly fragrance filled +The circuit wide. Straight knew him all the bands +Of Angels under watch; and to his state, +And to his message high, in honour rise; +For on some message high they guessed him bound. +Their glittering tents he passed, and now is come +Into the blissful field, through groves of myrrh, +And flowering odours, cassia, nard, and balm; +A wilderness of sweets; for Nature here +Wantoned as in her prime, and played at will +Her virgin fancies pouring forth more sweet, +Wild above rule or art, enormous bliss. +Him through the spicy forest onward come +Adam discerned, as in the door he sat +Of his cool bower, while now the mounted sun +Shot down direct his fervid rays to warm +Earth's inmost womb, more warmth than Adam needs: +And Eve within, due at her hour prepared +For dinner savoury fruits, of taste to please +True appetite, and not disrelish thirst +Of nectarous draughts between, from milky stream, +Berry or grape: To whom thus Adam called. +Haste hither, Eve, and worth thy sight behold +Eastward among those trees, what glorious shape +Comes this way moving; seems another morn +Risen on mid-noon; some great behest from Heaven +To us perhaps he brings, and will vouchsafe +This day to be our guest. But go with speed, +And, what thy stores contain, bring forth, and pour +Abundance, fit to honour and receive +Our heavenly stranger: Well we may afford +Our givers their own gifts, and large bestow +From large bestowed, where Nature multiplies +Her fertile growth, and by disburthening grows +More fruitful, which instructs us not to spare. +To whom thus Eve. Adam, earth's hallowed mould, +Of God inspired! small store will serve, where store, +All seasons, ripe for use hangs on the stalk; +Save what by frugal storing firmness gains +To nourish, and superfluous moist consumes: +But I will haste, and from each bough and brake, +Each plant and juciest gourd, will pluck such choice +To entertain our Angel-guest, as he +Beholding shall confess, that here on Earth +God hath dispensed his bounties as in Heaven. +So saying, with dispatchful looks in haste +She turns, on hospitable thoughts intent +What choice to choose for delicacy best, +What order, so contrived as not to mix +Tastes, not well joined, inelegant, but bring +Taste after taste upheld with kindliest change; +Bestirs her then, and from each tender stalk +Whatever Earth, all-bearing mother, yields +In India East or West, or middle shore +In Pontus or the Punick coast, or where +Alcinous reigned, fruit of all kinds, in coat +Rough, or smooth rind, or bearded husk, or shell, +She gathers, tribute large, and on the board +Heaps with unsparing hand; for drink the grape +She crushes, inoffensive must, and meaths +From many a berry, and from sweet kernels pressed +She tempers dulcet creams; nor these to hold +Wants her fit vessels pure; then strows the ground +With rose and odours from the shrub unfumed. +Mean while our primitive great sire, to meet +His God-like guest, walks forth, without more train +Accompanied than with his own complete +Perfections; in himself was all his state, +More solemn than the tedious pomp that waits +On princes, when their rich retinue long +Of horses led, and grooms besmeared with gold, +Dazzles the croud, and sets them all agape. +Nearer his presence Adam, though not awed, +Yet with submiss approach and reverence meek, +As to a superiour nature bowing low, +Thus said. Native of Heaven, for other place +None can than Heaven such glorious shape contain; +Since, by descending from the thrones above, +Those happy places thou hast deigned a while +To want, and honour these, vouchsafe with us +Two only, who yet by sovran gift possess +This spacious ground, in yonder shady bower +To rest; and what the garden choicest bears +To sit and taste, till this meridian heat +Be over, and the sun more cool decline. +Whom thus the angelick Virtue answered mild. +Adam, I therefore came; nor art thou such +Created, or such place hast here to dwell, +As may not oft invite, though Spirits of Heaven, +To visit thee; lead on then where thy bower +O'ershades; for these mid-hours, till evening rise, +I have at will. So to the sylvan lodge +They came, that like Pomona's arbour smiled, +With flowerets decked, and fragrant smells; but Eve, +Undecked save with herself, more lovely fair +Than Wood-Nymph, or the fairest Goddess feigned +Of three that in mount Ida naked strove, +Stood to entertain her guest from Heaven; no veil +She needed, virtue-proof; no thought infirm +Altered her cheek. On whom the Angel Hail +Bestowed, the holy salutation used +Long after to blest Mary, second Eve. +Hail, Mother of Mankind, whose fruitful womb +Shall fill the world more numerous with thy sons, +Than with these various fruits the trees of God +Have heaped this table!--Raised of grassy turf +Their table was, and mossy seats had round, +And on her ample square from side to side +All autumn piled, though spring and autumn here +Danced hand in hand. A while discourse they hold; +No fear lest dinner cool; when thus began +Our author. Heavenly stranger, please to taste +These bounties, which our Nourisher, from whom +All perfect good, unmeasured out, descends, +To us for food and for delight hath caused +The earth to yield; unsavoury food perhaps +To spiritual natures; only this I know, +That one celestial Father gives to all. +To whom the Angel. Therefore what he gives +(Whose praise be ever sung) to Man in part +Spiritual, may of purest Spirits be found +No ingrateful food: And food alike those pure +Intelligential substances require, +As doth your rational; and both contain +Within them every lower faculty +Of sense, whereby they hear, see, smell, touch, taste, +Tasting concoct, digest, assimilate, +And corporeal to incorporeal turn. +For know, whatever was created, needs +To be sustained and fed: Of elements +The grosser feeds the purer, earth the sea, +Earth and the sea feed air, the air those fires +Ethereal, and as lowest first the moon; +Whence in her visage round those spots, unpurged +Vapours not yet into her substance turned. +Nor doth the moon no nourishment exhale +From her moist continent to higher orbs. +The sun that light imparts to all, receives +From all his alimental recompence +In humid exhalations, and at even +Sups with the ocean. Though in Heaven the trees +Of life ambrosial fruitage bear, and vines +Yield nectar; though from off the boughs each morn +We brush mellifluous dews, and find the ground +Covered with pearly grain: Yet God hath here +Varied his bounty so with new delights, +As may compare with Heaven; and to taste +Think not I shall be nice. So down they sat, +And to their viands fell; nor seemingly +The Angel, nor in mist, the common gloss +Of Theologians; but with keen dispatch +Of real hunger, and concoctive heat +To transubstantiate: What redounds, transpires +Through Spirits with ease; nor wonder;if by fire +Of sooty coal the empirick alchemist +Can turn, or holds it possible to turn, +Metals of drossiest ore to perfect gold, +As from the mine. Mean while at table Eve +Ministered naked, and their flowing cups +With pleasant liquours crowned: O innocence +Deserving Paradise! if ever, then, +Then had the sons of God excuse to have been +Enamoured at that sight; but in those hearts +Love unlibidinous reigned, nor jealousy +Was understood, the injured lover's hell. +Thus when with meats and drinks they had sufficed, +Not burdened nature, sudden mind arose +In Adam, not to let the occasion pass +Given him by this great conference to know +Of things above his world, and of their being +Who dwell in Heaven, whose excellence he saw +Transcend his own so far; whose radiant forms, +Divine effulgence, whose high power, so far +Exceeded human; and his wary speech +Thus to the empyreal minister he framed. +Inhabitant with God, now know I well +Thy favour, in this honour done to Man; +Under whose lowly roof thou hast vouchsafed +To enter, and these earthly fruits to taste, +Food not of Angels, yet accepted so, +As that more willingly thou couldst not seem +At Heaven's high feasts to have fed: yet what compare +To whom the winged Hierarch replied. +O Adam, One Almighty is, from whom +All things proceed, and up to him return, +If not depraved from good, created all +Such to perfection, one first matter all, +Endued with various forms, various degrees +Of substance, and, in things that live, of life; +But more refined, more spiritous, and pure, +As nearer to him placed, or nearer tending +Each in their several active spheres assigned, +Till body up to spirit work, in bounds +Proportioned to each kind. So from the root +Springs lighter the green stalk, from thence the leaves +More aery, last the bright consummate flower +Spirits odorous breathes: flowers and their fruit, +Man's nourishment, by gradual scale sublimed, +To vital spirits aspire, to animal, +To intellectual; give both life and sense, +Fancy and understanding; whence the soul +Reason receives, and reason is her being, +Discursive, or intuitive; discourse +Is oftest yours, the latter most is ours, +Differing but in degree, of kind the same. +Wonder not then, what God for you saw good +If I refuse not, but convert, as you +To proper substance. Time may come, when Men +With Angels may participate, and find +No inconvenient diet, nor too light fare; +And from these corporal nutriments perhaps +Your bodies may at last turn all to spirit, +Improved by tract of time, and, winged, ascend +Ethereal, as we; or may, at choice, +Here or in heavenly Paradises dwell; +If ye be found obedient, and retain +Unalterably firm his love entire, +Whose progeny you are. Mean while enjoy +Your fill what happiness this happy state +Can comprehend, incapable of more. +To whom the patriarch of mankind replied. +O favourable Spirit, propitious guest, +Well hast thou taught the way that might direct +Our knowledge, and the scale of nature set +From center to circumference; whereon, +In contemplation of created things, +By steps we may ascend to God. But say, +What meant that caution joined, If ye be found +Obedient? Can we want obedience then +To him, or possibly his love desert, +Who formed us from the dust and placed us here +Full to the utmost measure of what bliss +Human desires can seek or apprehend? +To whom the Angel. Son of Heaven and Earth, +Attend! That thou art happy, owe to God; +That thou continuest such, owe to thyself, +That is, to thy obedience; therein stand. +This was that caution given thee; be advised. +God made thee perfect, not immutable; +And good he made thee, but to persevere +He left it in thy power; ordained thy will +By nature free, not over-ruled by fate +Inextricable, or strict necessity: +Our voluntary service he requires, +Not our necessitated; such with him +Finds no acceptance, nor can find; for how +Can hearts, not free, be tried whether they serve +Willing or no, who will but what they must +By destiny, and can no other choose? +Myself, and all the angelick host, that stand +In sight of God, enthroned, our happy state +Hold, as you yours, while our obedience holds; +On other surety none: Freely we serve, +Because we freely love, as in our will +To love or not; in this we stand or fall: +And some are fallen, to disobedience fallen, +And so from Heaven to deepest Hell; O fall +From what high state of bliss, into what woe! +To whom our great progenitor. Thy words +Attentive, and with more delighted ear, +Divine instructer, I have heard, than when +Cherubick songs by night from neighbouring hills +Aereal musick send: Nor knew I not +To be both will and deed created free; +Yet that we never shall forget to love +Our Maker, and obey him whose command +Single is yet so just, my constant thoughts +Assured me, and still assure: Though what thou tellest +Hath passed in Heaven, some doubt within me move, +But more desire to hear, if thou consent, +The full relation, which must needs be strange, +Worthy of sacred silence to be heard; +And we have yet large day, for scarce the sun +Hath finished half his journey, and scarce begins +His other half in the great zone of Heaven. +Thus Adam made request; and Raphael, +After short pause assenting, thus began. +High matter thou enjoinest me, O prime of men, +Sad task and hard: For how shall I relate +To human sense the invisible exploits +Of warring Spirits? how, without remorse, +The ruin of so many glorious once +And perfect while they stood? how last unfold +The secrets of another world, perhaps +Not lawful to reveal? yet for thy good +This is dispensed; and what surmounts the reach +Of human sense, I shall delineate so, +By likening spiritual to corporal forms, +As may express them best; though what if Earth +Be but a shadow of Heaven, and things therein +Each to other like, more than on earth is thought? +As yet this world was not, and Chaos wild +Reigned where these Heavens now roll, where Earth now rests +Upon her center poised; when on a day +(For time, though in eternity, applied +To motion, measures all things durable +By present, past, and future,) on such day +As Heaven's great year brings forth, the empyreal host +Of Angels by imperial summons called, +Innumerable before the Almighty's throne +Forthwith, from all the ends of Heaven, appeared +Under their Hierarchs in orders bright: +Ten thousand thousand ensigns high advanced, +Standards and gonfalons 'twixt van and rear +Stream in the air, and for distinction serve +Of hierarchies, of orders, and degrees; +Or in their glittering tissues bear imblazed +Holy memorials, acts of zeal and love +Recorded eminent. Thus when in orbs +Of circuit inexpressible they stood, +Orb within orb, the Father Infinite, +By whom in bliss imbosomed sat the Son, +Amidst as from a flaming mount, whose top +Brightness had made invisible, thus spake. +Hear, all ye Angels, progeny of light, +Thrones, Dominations, Princedoms, Virtues, Powers; +Hear my decree, which unrevoked shall stand. +This day I have begot whom I declare +My only Son, and on this holy hill +Him have anointed, whom ye now behold +At my right hand; your head I him appoint; +And by myself have sworn, to him shall bow +All knees in Heaven, and shall confess him Lord: +Under his great vice-gerent reign abide +United, as one individual soul, +For ever happy: Him who disobeys, +Me disobeys, breaks union, and that day, +Cast out from God and blessed vision, falls +Into utter darkness, deep ingulfed, his place +Ordained without redemption, without end. +So spake the Omnipotent, and with his words +All seemed well pleased; all seemed, but were not all. +That day, as other solemn days, they spent +In song and dance about the sacred hill; +Mystical dance, which yonder starry sphere +Of planets, and of fixed, in all her wheels +Resembles nearest, mazes intricate, +Eccentrick, intervolved, yet regular +Then most, when most irregular they seem; +And in their motions harmony divine +So smooths her charming tones, that God's own ear +Listens delighted. Evening now approached, +(For we have also our evening and our morn, +We ours for change delectable, not need;) +Forthwith from dance to sweet repast they turn +Desirous; all in circles as they stood, +Tables are set, and on a sudden piled +With Angels food, and rubied nectar flows +In pearl, in diamond, and massy gold, +Fruit of delicious vines, the growth of Heaven. +On flowers reposed, and with fresh flowerets crowned, +They eat, they drink, and in communion sweet +Quaff immortality and joy, secure +Of surfeit, where full measure only bounds +Excess, before the all-bounteous King, who showered +With copious hand, rejoicing in their joy. +Now when ambrosial night with clouds exhaled +From that high mount of God, whence light and shade +Spring both, the face of brightest Heaven had changed +To grateful twilight, (for night comes not there +In darker veil,) and roseat dews disposed +All but the unsleeping eyes of God to rest; +Wide over all the plain, and wider far +Than all this globous earth in plain outspread, +(Such are the courts of God) the angelick throng, +Dispersed in bands and files, their camp extend +By living streams among the trees of life, +Pavilions numberless, and sudden reared, +Celestial tabernacles, where they slept +Fanned with cool winds; save those, who, in their course, +Melodious hymns about the sovran throne +Alternate all night long: but not so waked +Satan; so call him now, his former name +Is heard no more in Heaven; he of the first, +If not the first Arch-Angel, great in power, +In favour and pre-eminence, yet fraught +With envy against the Son of God, that day +Honoured by his great Father, and proclaimed +Messiah King anointed, could not bear +Through pride that sight, and thought himself impaired. +Deep malice thence conceiving and disdain, +Soon as midnight brought on the dusky hour +Friendliest to sleep and silence, he resolved +With all his legions to dislodge, and leave +Unworshipt, unobeyed, the throne supreme, +Contemptuous; and his next subordinate +Awakening, thus to him in secret spake. +Sleepest thou, Companion dear? What sleep can close +Thy eye-lids? and rememberest what decree +Of yesterday, so late hath passed the lips +Of Heaven's Almighty. Thou to me thy thoughts +Wast wont, I mine to thee was wont to impart; +Both waking we were one; how then can now +Thy sleep dissent? New laws thou seest imposed; +New laws from him who reigns, new minds may raise +In us who serve, new counsels to debate +What doubtful may ensue: More in this place +To utter is not safe. Assemble thou +Of all those myriads which we lead the chief; +Tell them, that by command, ere yet dim night +Her shadowy cloud withdraws, I am to haste, +And all who under me their banners wave, +Homeward, with flying march, where we possess +The quarters of the north; there to prepare +Fit entertainment to receive our King, +The great Messiah, and his new commands, +Who speedily through all the hierarchies +Intends to pass triumphant, and give laws. +So spake the false Arch-Angel, and infused +Bad influence into the unwary breast +Of his associate: He together calls, +Or several one by one, the regent Powers, +Under him Regent; tells, as he was taught, +That the Most High commanding, now ere night, +Now ere dim night had disincumbered Heaven, +The great hierarchal standard was to move; +Tells the suggested cause, and casts between +Ambiguous words and jealousies, to sound +Or taint integrity: But all obeyed +The wonted signal, and superiour voice +Of their great Potentate; for great indeed +His name, and high was his degree in Heaven; +His countenance, as the morning-star that guides +The starry flock, allured them, and with lies +Drew after him the third part of Heaven's host. +Mean while the Eternal eye, whose sight discerns +Abstrusest thoughts, from forth his holy mount, +And from within the golden lamps that burn +Nightly before him, saw without their light +Rebellion rising; saw in whom, how spread +Among the sons of morn, what multitudes +Were banded to oppose his high decree; +And, smiling, to his only Son thus said. +Son, thou in whom my glory I behold +In full resplendence, Heir of all my might, +Nearly it now concerns us to be sure +Of our Omnipotence, and with what arms +We mean to hold what anciently we claim +Of deity or empire: Such a foe +Is rising, who intends to erect his throne +Equal to ours, throughout the spacious north; +Nor so content, hath in his thought to try +In battle, what our power is, or our right. +Let us advise, and to this hazard draw +With speed what force is left, and all employ +In our defence; lest unawares we lose +This our high place, our sanctuary, our hill. +To whom the Son with calm aspect and clear, +Lightning divine, ineffable, serene, +Made answer. Mighty Father, thou thy foes +Justly hast in derision, and, secure, +Laughest at their vain designs and tumults vain, +Matter to me of glory, whom their hate +Illustrates, when they see all regal power +Given me to quell their pride, and in event +Know whether I be dextrous to subdue +Thy rebels, or be found the worst in Heaven. +So spake the Son; but Satan, with his Powers, +Far was advanced on winged speed; an host +Innumerable as the stars of night, +Or stars of morning, dew-drops, which the sun +Impearls on every leaf and every flower. +Regions they passed, the mighty regencies +Of Seraphim, and Potentates, and Thrones, +In their triple degrees; regions to which +All thy dominion, Adam, is no more +Than what this garden is to all the earth, +And all the sea, from one entire globose +Stretched into longitude; which having passed, +At length into the limits of the north +They came; and Satan to his royal seat +High on a hill, far blazing, as a mount +Raised on a mount, with pyramids and towers +From diamond quarries hewn, and rocks of gold; +The palace of great Lucifer, (so call +That structure in the dialect of men +Interpreted,) which not long after, he +Affecting all equality with God, +In imitation of that mount whereon +Messiah was declared in sight of Heaven, +The Mountain of the Congregation called; +For thither he assembled all his train, +Pretending so commanded to consult +About the great reception of their King, +Thither to come, and with calumnious art +Of counterfeited truth thus held their ears. +Thrones, Dominations, Princedoms, Virtues, Powers; +If these magnifick titles yet remain +Not merely titular, since by decree +Another now hath to himself engrossed +All power, and us eclipsed under the name +Of King anointed, for whom all this haste +Of midnight-march, and hurried meeting here, +This only to consult how we may best, +With what may be devised of honours new, +Receive him coming to receive from us +Knee-tribute yet unpaid, prostration vile! +Too much to one! but double how endured, +To one, and to his image now proclaimed? +But what if better counsels might erect +Our minds, and teach us to cast off this yoke? +Will ye submit your necks, and choose to bend +The supple knee? Ye will not, if I trust +To know ye right, or if ye know yourselves +Natives and sons of Heaven possessed before +By none; and if not equal all, yet free, +Equally free; for orders and degrees +Jar not with liberty, but well consist. +Who can in reason then, or right, assume +Monarchy over such as live by right +His equals, if in power and splendour less, +In freedom equal? or can introduce +Law and edict on us, who without law +Err not? much less for this to be our Lord, +And look for adoration, to the abuse +Of those imperial titles, which assert +Our being ordained to govern, not to serve. +Thus far his bold discourse without controul +Had audience; when among the Seraphim +Abdiel, than whom none with more zeal adored +The Deity, and divine commands obeyed, +Stood up, and in a flame of zeal severe +The current of his fury thus opposed. +O argument blasphemous, false, and proud! +Words which no ear ever to hear in Heaven +Expected, least of all from thee, Ingrate, +In place thyself so high above thy peers. +Canst thou with impious obloquy condemn +The just decree of God, pronounced and sworn, +That to his only Son, by right endued +With regal scepter, every soul in Heaven +Shall bend the knee, and in that honour due +Confess him rightful King? unjust, thou sayest, +Flatly unjust, to bind with laws the free, +And equal over equals to let reign, +One over all with unsucceeded power. +Shalt thou give law to God? shalt thou dispute +With him the points of liberty, who made +Thee what thou art, and formed the Powers of Heaven +Such as he pleased, and circumscribed their being? +Yet, by experience taught, we know how good, +And of our good and of our dignity +How provident he is; how far from thought +To make us less, bent rather to exalt +Our happy state, under one head more near +United. But to grant it thee unjust, +That equal over equals monarch reign: +Thyself, though great and glorious, dost thou count, +Or all angelick nature joined in one, +Equal to him begotten Son? by whom, +As by his Word, the Mighty Father made +All things, even thee; and all the Spirits of Heaven +By him created in their bright degrees, +Crowned them with glory, and to their glory named +Thrones, Dominations, Princedoms, Virtues, Powers, +Essential Powers; nor by his reign obscured, +But more illustrious made; since he the head +One of our number thus reduced becomes; +His laws our laws; all honour to him done +Returns our own. Cease then this impious rage, +And tempt not these; but hasten to appease +The incensed Father, and the incensed Son, +While pardon may be found in time besought. +So spake the fervent Angel; but his zeal +None seconded, as out of season judged, +Or singular and rash: Whereat rejoiced +The Apostate, and, more haughty, thus replied. +That we were formed then sayest thou? and the work +Of secondary hands, by task transferred +From Father to his Son? strange point and new! +Doctrine which we would know whence learned: who saw +When this creation was? rememberest thou +Thy making, while the Maker gave thee being? +We know no time when we were not as now; +Know none before us, self-begot, self-raised +By our own quickening power, when fatal course +Had circled his full orb, the birth mature +Of this our native Heaven, ethereal sons. +Our puissance is our own; our own right hand +Shall teach us highest deeds, by proof to try +Who is our equal: Then thou shalt behold +Whether by supplication we intend +Address, and to begirt the almighty throne +Beseeching or besieging. This report, +These tidings carry to the anointed King; +And fly, ere evil intercept thy flight. +He said; and, as the sound of waters deep, +Hoarse murmur echoed to his words applause +Through the infinite host; nor less for that +The flaming Seraph fearless, though alone +Encompassed round with foes, thus answered bold. +O alienate from God, O Spirit accursed, +Forsaken of all good! I see thy fall +Determined, and thy hapless crew involved +In this perfidious fraud, contagion spread +Both of thy crime and punishment: Henceforth +No more be troubled how to quit the yoke +Of God's Messiah; those indulgent laws +Will not be now vouchsafed; other decrees +Against thee are gone forth without recall; +That golden scepter, which thou didst reject, +Is now an iron rod to bruise and break +Thy disobedience. Well thou didst advise; +Yet not for thy advice or threats I fly +These wicked tents devoted, lest the wrath +Impendent, raging into sudden flame, +Distinguish not: For soon expect to feel +His thunder on thy head, devouring fire. +Then who created thee lamenting learn, +When who can uncreate thee thou shalt know. +So spake the Seraph Abdiel, faithful found +Among the faithless, faithful only he; +Among innumerable false, unmoved, +Unshaken, unseduced, unterrified, +His loyalty he kept, his love, his zeal; +Nor number, nor example, with him wrought +To swerve from truth, or change his constant mind, +Though single. From amidst them forth he passed, +Long way through hostile scorn, which he sustained +Superiour, nor of violence feared aught; +And, with retorted scorn, his back he turned +On those proud towers to swift destruction doomed. + + + +Book VI + + +All night the dreadless Angel, unpursued, +Through Heaven's wide champain held his way; till Morn, +Waked by the circling Hours, with rosy hand +Unbarred the gates of light. There is a cave +Within the mount of God, fast by his throne, +Where light and darkness in perpetual round +Lodge and dislodge by turns, which makes through Heaven +Grateful vicissitude, like day and night; +Light issues forth, and at the other door +Obsequious darkness enters, till her hour +To veil the Heaven, though darkness there might well +Seem twilight here: And now went forth the Morn +Such as in highest Heaven arrayed in gold +Empyreal; from before her vanished Night, +Shot through with orient beams; when all the plain +Covered with thick embattled squadrons bright, +Chariots, and flaming arms, and fiery steeds, +Reflecting blaze on blaze, first met his view: +War he perceived, war in procinct; and found +Already known what he for news had thought +To have reported: Gladly then he mixed +Among those friendly Powers, who him received +With joy and acclamations loud, that one, +That of so many myriads fallen, yet one +Returned not lost. On to the sacred hill +They led him high applauded, and present +Before the seat supreme; from whence a voice, +From midst a golden cloud, thus mild was heard. +Servant of God. Well done; well hast thou fought +The better fight, who single hast maintained +Against revolted multitudes the cause +Of truth, in word mightier than they in arms; +And for the testimony of truth hast borne +Universal reproach, far worse to bear +Than violence; for this was all thy care +To stand approved in sight of God, though worlds +Judged thee perverse: The easier conquest now +Remains thee, aided by this host of friends, +Back on thy foes more glorious to return, +Than scorned thou didst depart; and to subdue +By force, who reason for their law refuse, +Right reason for their law, and for their King +Messiah, who by right of merit reigns. +Go, Michael, of celestial armies prince, +And thou, in military prowess next, +Gabriel, lead forth to battle these my sons +Invincible; lead forth my armed Saints, +By thousands and by millions, ranged for fight, +Equal in number to that Godless crew +Rebellious: Them with fire and hostile arms +Fearless assault; and, to the brow of Heaven +Pursuing, drive them out from God and bliss, +Into their place of punishment, the gulf +Of Tartarus, which ready opens wide +His fiery Chaos to receive their fall. +So spake the Sovran Voice, and clouds began +To darken all the hill, and smoke to roll +In dusky wreaths, reluctant flames, the sign +Of wrath awaked; nor with less dread the loud +Ethereal trumpet from on high 'gan blow: +At which command the Powers militant, +That stood for Heaven, in mighty quadrate joined +Of union irresistible, moved on +In silence their bright legions, to the sound +Of instrumental harmony, that breathed +Heroick ardour to adventurous deeds +Under their God-like leaders, in the cause +Of God and his Messiah. On they move +Indissolubly firm; nor obvious hill, +Nor straitening vale, nor wood, nor stream, divides +Their perfect ranks; for high above the ground +Their march was, and the passive air upbore +Their nimble tread; as when the total kind +Of birds, in orderly array on wing, +Came summoned over Eden to receive +Their names of thee; so over many a tract +Of Heaven they marched, and many a province wide, +Tenfold the length of this terrene: At last, +Far in the horizon to the north appeared +From skirt to skirt a fiery region, stretched +In battailous aspect, and nearer view +Bristled with upright beams innumerable +Of rigid spears, and helmets thronged, and shields +Various, with boastful argument portrayed, +The banded Powers of Satan hasting on +With furious expedition; for they weened +That self-same day, by fight or by surprise, +To win the mount of God, and on his throne +To set the Envier of his state, the proud +Aspirer; but their thoughts proved fond and vain +In the mid way: Though strange to us it seemed +At first, that Angel should with Angel war, +And in fierce hosting meet, who wont to meet +So oft in festivals of joy and love +Unanimous, as sons of one great Sire, +Hymning the Eternal Father: But the shout +Of battle now began, and rushing sound +Of onset ended soon each milder thought. +High in the midst, exalted as a God, +The Apostate in his sun-bright chariot sat, +Idol of majesty divine, enclosed +With flaming Cherubim, and golden shields; +Then lighted from his gorgeous throne, for now +"twixt host and host but narrow space was left, +A dreadful interval, and front to front +Presented stood in terrible array +Of hideous length: Before the cloudy van, +On the rough edge of battle ere it joined, +Satan, with vast and haughty strides advanced, +Came towering, armed in adamant and gold; +Abdiel that sight endured not, where he stood +Among the mightiest, bent on highest deeds, +And thus his own undaunted heart explores. +O Heaven! that such resemblance of the Highest +Should yet remain, where faith and realty +Remain not: Wherefore should not strength and might +There fail where virtue fails, or weakest prove +Where boldest, though to fight unconquerable? +His puissance, trusting in the Almighty's aid, +I mean to try, whose reason I have tried +Unsound and false; nor is it aught but just, +That he, who in debate of truth hath won, +Should win in arms, in both disputes alike +Victor; though brutish that contest and foul, +When reason hath to deal with force, yet so +Most reason is that reason overcome. +So pondering, and from his armed peers +Forth stepping opposite, half-way he met +His daring foe, at this prevention more +Incensed, and thus securely him defied. +Proud, art thou met? thy hope was to have reached +The highth of thy aspiring unopposed, +The throne of God unguarded, and his side +Abandoned, at the terrour of thy power +Or potent tongue: Fool!not to think how vain +Against the Omnipotent to rise in arms; +Who out of smallest things could, without end, +Have raised incessant armies to defeat +Thy folly; or with solitary hand +Reaching beyond all limit, at one blow, +Unaided, could have finished thee, and whelmed +Thy legions under darkness: But thou seest +All are not of thy train; there be, who faith +Prefer, and piety to God, though then +To thee not visible, when I alone +Seemed in thy world erroneous to dissent +From all: My sect thou seest;now learn too late +How few sometimes may know, when thousands err. +Whom the grand foe, with scornful eye askance, +Thus answered. Ill for thee, but in wished hour +Of my revenge, first sought for, thou returnest +From flight, seditious Angel! to receive +Thy merited reward, the first assay +Of this right hand provoked, since first that tongue, +Inspired with contradiction, durst oppose +A third part of the Gods, in synod met +Their deities to assert; who, while they feel +Vigour divine within them, can allow +Omnipotence to none. But well thou comest +Before thy fellows, ambitious to win +From me some plume, that thy success may show +Destruction to the rest: This pause between, +(Unanswered lest thou boast) to let thee know, +At first I thought that Liberty and Heaven +To heavenly souls had been all one; but now +I see that most through sloth had rather serve, +Ministring Spirits, trained up in feast and song! +Such hast thou armed, the minstrelsy of Heaven, +Servility with freedom to contend, +As both their deeds compared this day shall prove. +To whom in brief thus Abdiel stern replied. +Apostate! still thou errest, nor end wilt find +Of erring, from the path of truth remote: +Unjustly thou depravest it with the name +Of servitude, to serve whom God ordains, +Or Nature: God and Nature bid the same, +When he who rules is worthiest, and excels +Them whom he governs. This is servitude, +To serve the unwise, or him who hath rebelled +Against his worthier, as thine now serve thee, +Thyself not free, but to thyself enthralled; +Yet lewdly darest our ministring upbraid. +Reign thou in Hell, thy kingdom; let me serve +In Heaven God ever blest, and his divine +Behests obey, worthiest to be obeyed; +Yet chains in Hell, not realms, expect: Mean while +From me returned, as erst thou saidst, from flight, +This greeting on thy impious crest receive. +So saying, a noble stroke he lifted high, +Which hung not, but so swift with tempest fell +On the proud crest of Satan, that no sight, +Nor motion of swift thought, less could his shield, +Such ruin intercept: Ten paces huge +He back recoiled; the tenth on bended knee +His massy spear upstaid; as if on earth +Winds under ground, or waters forcing way, +Sidelong had pushed a mountain from his seat, +Half sunk with all his pines. Amazement seised +The rebel Thrones, but greater rage, to see +Thus foiled their mightiest; ours joy filled, and shout, +Presage of victory, and fierce desire +Of battle: Whereat Michael bid sound +The Arch-Angel trumpet; through the vast of Heaven +It sounded, and the faithful armies rung +Hosanna to the Highest: Nor stood at gaze +The adverse legions, nor less hideous joined +The horrid shock. Now storming fury rose, +And clamour such as heard in Heaven till now +Was never; arms on armour clashing brayed +Horrible discord, and the madding wheels +Of brazen chariots raged; dire was the noise +Of conflict; over head the dismal hiss +Of fiery darts in flaming vollies flew, +And flying vaulted either host with fire. +So under fiery cope together rushed +Both battles main, with ruinous assault +And inextinguishable rage. All Heaven +Resounded; and had Earth been then, all Earth +Had to her center shook. What wonder? when +Millions of fierce encountering Angels fought +On either side, the least of whom could wield +These elements, and arm him with the force +Of all their regions: How much more of power +Army against army numberless to raise +Dreadful combustion warring, and disturb, +Though not destroy, their happy native seat; +Had not the Eternal King Omnipotent, +From his strong hold of Heaven, high over-ruled +And limited their might; though numbered such +As each divided legion might have seemed +A numerous host; in strength each armed hand +A legion; led in fight, yet leader seemed +Each warriour single as in chief, expert +When to advance, or stand, or turn the sway +Of battle, open when, and when to close +The ridges of grim war: No thought of flight, +None of retreat, no unbecoming deed +That argued fear; each on himself relied, +As only in his arm the moment lay +Of victory: Deeds of eternal fame +Were done, but infinite; for wide was spread +That war and various; sometimes on firm ground +A standing fight, then, soaring on main wing, +Tormented all the air; all air seemed then +Conflicting fire. Long time in even scale +The battle hung; till Satan, who that day +Prodigious power had shown, and met in arms +No equal, ranging through the dire attack +Of fighting Seraphim confused, at length +Saw where the sword of Michael smote, and felled +Squadrons at once; with huge two-handed sway +Brandished aloft, the horrid edge came down +Wide-wasting; such destruction to withstand +He hasted, and opposed the rocky orb +Of tenfold adamant, his ample shield, +A vast circumference. At his approach +The great Arch-Angel from his warlike toil +Surceased, and glad, as hoping here to end +Intestine war in Heaven, the arch-foe subdued +Or captive dragged in chains, with hostile frown +And visage all inflamed first thus began. +Author of evil, unknown till thy revolt, +Unnamed in Heaven, now plenteous as thou seest +These acts of hateful strife, hateful to all, +Though heaviest by just measure on thyself, +And thy adherents: How hast thou disturbed +Heaven's blessed peace, and into nature brought +Misery, uncreated till the crime +Of thy rebellion! how hast thou instilled +Thy malice into thousands, once upright +And faithful, now proved false! But think not here +To trouble holy rest; Heaven casts thee out +From all her confines. Heaven, the seat of bliss, +Brooks not the works of violence and war. +Hence then, and evil go with thee along, +Thy offspring, to the place of evil, Hell; +Thou and thy wicked crew! there mingle broils, +Ere this avenging sword begin thy doom, +Or some more sudden vengeance, winged from God, +Precipitate thee with augmented pain. +So spake the Prince of Angels; to whom thus +The Adversary. Nor think thou with wind +Of aery threats to awe whom yet with deeds +Thou canst not. Hast thou turned the least of these +To flight, or if to fall, but that they rise +Unvanquished, easier to transact with me +That thou shouldst hope, imperious, and with threats +To chase me hence? err not, that so shall end +The strife which thou callest evil, but we style +The strife of glory; which we mean to win, +Or turn this Heaven itself into the Hell +Thou fablest; here however to dwell free, +If not to reign: Mean while thy utmost force, +And join him named Almighty to thy aid, +I fly not, but have sought thee far and nigh. +They ended parle, and both addressed for fight +Unspeakable; for who, though with the tongue +Of Angels, can relate, or to what things +Liken on earth conspicuous, that may lift +Human imagination to such highth +Of Godlike power? for likest Gods they seemed, +Stood they or moved, in stature, motion, arms, +Fit to decide the empire of great Heaven. +Now waved their fiery swords, and in the air +Made horrid circles; two broad suns their shields +Blazed opposite, while Expectation stood +In horrour: From each hand with speed retired, +Where erst was thickest fight, the angelick throng, +And left large field, unsafe within the wind +Of such commotion; such as, to set forth +Great things by small, if, nature's concord broke, +Among the constellations war were sprung, +Two planets, rushing from aspect malign +Of fiercest opposition, in mid sky +Should combat, and their jarring spheres confound. +Together both with next to almighty arm +Up-lifted imminent, one stroke they aimed +That might determine, and not need repeat, +As not of power at once; nor odds appeared +In might or swift prevention: But the sword +Of Michael from the armoury of God +Was given him tempered so, that neither keen +Nor solid might resist that edge: it met +The sword of Satan, with steep force to smite +Descending, and in half cut sheer; nor staid, +But with swift wheel reverse, deep entering, shared +All his right side: Then Satan first knew pain, +And writhed him to and fro convolved; so sore +The griding sword with discontinuous wound +Passed through him: But the ethereal substance closed, +Not long divisible; and from the gash +A stream of necturous humour issuing flowed +Sanguine, such as celestial Spirits may bleed, +And all his armour stained, ere while so bright. +Forthwith on all sides to his aid was run +By Angels many and strong, who interposed +Defence, while others bore him on their shields +Back to his chariot, where it stood retired +From off the files of war: There they him laid +Gnashing for anguish, and despite, and shame, +To find himself not matchless, and his pride +Humbled by such rebuke, so far beneath +His confidence to equal God in power. +Yet soon he healed; for Spirits that live throughout +Vital in every part, not as frail man +In entrails, heart of head, liver or reins, +Cannot but by annihilating die; +Nor in their liquid texture mortal wound +Receive, no more than can the fluid air: +All heart they live, all head, all eye, all ear, +All intellect, all sense; and, as they please, +They limb themselves, and colour, shape, or size +Assume, as?kikes them best, condense or rare. +Mean while in other parts like deeds deserved +Memorial, where the might of Gabriel fought, +And with fierce ensigns pierced the deep array +Of Moloch, furious king; who him defied, +And at his chariot-wheels to drag him bound +Threatened, nor from the Holy One of Heaven +Refrained his tongue blasphemous; but anon +Down cloven to the waist, with shattered arms +And uncouth pain fled bellowing. On each wing +Uriel, and Raphael, his vaunting foe, +Though huge, and in a rock of diamond armed, +Vanquished Adramelech, and Asmadai, +Two potent Thrones, that to be less than Gods +Disdained, but meaner thoughts learned in their flight, +Mangled with ghastly wounds through plate and mail. +Nor stood unmindful Abdiel to annoy +The atheist crew, but with redoubled blow +Ariel, and Arioch, and the violence +Of Ramiel scorched and blasted, overthrew. +I might relate of thousands, and their names +Eternize here on earth; but those elect +Angels, contented with their fame in Heaven, +Seek not the praise of men: The other sort, +In might though wonderous and in acts of war, +Nor of renown less eager, yet by doom +Cancelled from Heaven and sacred memory, +Nameless in dark oblivion let them dwell. +For strength from truth divided, and from just, +Illaudable, nought merits but dispraise +And ignominy; yet to glory aspires +Vain-glorious, and through infamy seeks fame: +Therefore eternal silence be their doom. +And now, their mightiest quelled, the battle swerved, +With many an inroad gored; deformed rout +Entered, and foul disorder; all the ground +With shivered armour strown, and on a heap +Chariot and charioteer lay overturned, +And fiery-foaming steeds; what stood, recoiled +O'er-wearied, through the faint Satanick host +Defensive scarce, or with pale fear surprised, +Then first with fear surprised, and sense of pain, +Fled ignominious, to such evil brought +By sin of disobedience; till that hour +Not liable to fear, or flight, or pain. +Far otherwise the inviolable Saints, +In cubick phalanx firm, advanced entire, +Invulnerable, impenetrably armed; +Such high advantages their innocence +Gave them above their foes; not to have sinned, +Not to have disobeyed; in fight they stood +Unwearied, unobnoxious to be pained +By wound, though from their place by violence moved, +Now Night her course began, and, over Heaven +Inducing darkness, grateful truce imposed, +And silence on the odious din of war: +Under her cloudy covert both retired, +Victor and vanquished: On the foughten field +Michael and his Angels prevalent +Encamping, placed in guard their watches round, +Cherubick waving fires: On the other part, +Satan with his rebellious disappeared, +Far in the dark dislodged; and, void of rest, +His potentates to council called by night; +And in the midst thus undismayed began. +O now in danger tried, now known in arms +Not to be overpowered, Companions dear, +Found worthy not of liberty alone, +Too mean pretence! but what we more affect, +Honour, dominion, glory, and renown; +Who have sustained one day in doubtful fight, +(And if one day, why not eternal days?) +What Heaven's Lord had powerfullest to send +Against us from about his throne, and judged +Sufficient to subdue us to his will, +But proves not so: Then fallible, it seems, +Of future we may deem him, though till now +Omniscient thought. True is, less firmly armed, +Some disadvantage we endured and pain, +Till now not known, but, known, as soon contemned; +Since now we find this our empyreal form +Incapable of mortal injury, +Imperishable, and, though pierced with wound, +Soon closing, and by native vigour healed. +Of evil then so small as easy think +The remedy; perhaps more valid arms, +Weapons more violent, when next we meet, +May serve to better us, and worse our foes, +Or equal what between us made the odds, +In nature none: If other hidden cause +Left them superiour, while we can preserve +Unhurt our minds, and understanding sound, +Due search and consultation will disclose. +He sat; and in the assembly next upstood +Nisroch, of Principalities the prime; +As one he stood escaped from cruel fight, +Sore toiled, his riven arms to havock hewn, +And cloudy in aspect thus answering spake. +Deliverer from new Lords, leader to free +Enjoyment of our right as Gods; yet hard +For Gods, and too unequal work we find, +Against unequal arms to fight in pain, +Against unpained, impassive; from which evil +Ruin must needs ensue; for what avails +Valour or strength, though matchless, quelled with pain +Which all subdues, and makes remiss the hands +Of mightiest? Sense of pleasure we may well +Spare out of life perhaps, and not repine, +But live content, which is the calmest life: +But pain is perfect misery, the worst +Of evils, and, excessive, overturns +All patience. He, who therefore can invent +With what more forcible we may offend +Our yet unwounded enemies, or arm +Ourselves with like defence, to me deserves +No less than for deliverance what we owe. +Whereto with look composed Satan replied. +Not uninvented that, which thou aright +Believest so main to our success, I bring. +Which of us who beholds the bright surface +Of this ethereous mould whereon we stand, +This continent of spacious Heaven, adorned +With plant, fruit, flower ambrosial, gems, and gold; +Whose eye so superficially surveys +These things, as not to mind from whence they grow +Deep under ground, materials dark and crude, +Of spiritous and fiery spume, till touched +With Heaven's ray, and tempered, they shoot forth +So beauteous, opening to the ambient light? +These in their dark nativity the deep +Shall yield us, pregnant with infernal flame; +Which, into hollow engines, long and round, +Thick rammed, at the other bore with touch of fire +Dilated and infuriate, shall send forth +From far, with thundering noise, among our foes +Such implements of mischief, as shall dash +To pieces, and o'erwhelm whatever stands +Adverse, that they shall fear we have disarmed +The Thunderer of his only dreaded bolt. +Nor long shall be our labour; yet ere dawn, +Effect shall end our wish. Mean while revive; +Abandon fear; to strength and counsel joined +Think nothing hard, much less to be despaired. +He ended, and his words their drooping cheer +Enlightened, and their languished hope revived. +The invention all admired, and each, how he +To be the inventer missed; so easy it seemed +Once found, which yet unfound most would have thought +Impossible: Yet, haply, of thy race +In future days, if malice should abound, +Some one intent on mischief, or inspired +With devilish machination, might devise +Like instrument to plague the sons of men +For sin, on war and mutual slaughter bent. +Forthwith from council to the work they flew; +None arguing stood; innumerable hands +Were ready; in a moment up they turned +Wide the celestial soil, and saw beneath +The originals of nature in their crude +Conception; sulphurous and nitrous foam +They found, they mingled, and, with subtle art, +Concocted and adusted they reduced +To blackest grain, and into store conveyed: +Part hidden veins digged up (nor hath this earth +Entrails unlike) of mineral and stone, +Whereof to found their engines and their balls +Of missive ruin; part incentive reed +Provide, pernicious with one touch to fire. +So all ere day-spring, under conscious night, +Secret they finished, and in order set, +With silent circumspection, unespied. +Now when fair morn orient in Heaven appeared, +Up rose the victor-Angels, and to arms +The matin trumpet sung: In arms they stood +Of golden panoply, refulgent host, +Soon banded; others from the dawning hills +Look round, and scouts each coast light-armed scour, +Each quarter to descry the distant foe, +Where lodged, or whither fled, or if for fight, +In motion or in halt: Him soon they met +Under spread ensigns moving nigh, in slow +But firm battalion; back with speediest sail +Zophiel, of Cherubim the swiftest wing, +Came flying, and in mid air aloud thus cried. +Arm, Warriours, arm for fight; the foe at hand, +Whom fled we thought, will save us long pursuit +This day; fear not his flight;so thick a cloud +He comes, and settled in his face I see +Sad resolution, and secure: Let each +His adamantine coat gird well, and each +Fit well his helm, gripe fast his orbed shield, +Borne even or high; for this day will pour down, +If I conjecture aught, no drizzling shower, +But rattling storm of arrows barbed with fire. +So warned he them, aware themselves, and soon +In order, quit of all impediment; +Instant without disturb they took alarm, +And onward moved embattled: When behold! +Not distant far with heavy pace the foe +Approaching gross and huge, in hollow cube +Training his devilish enginery, impaled +On every side with shadowing squadrons deep, +To hide the fraud. At interview both stood +A while; but suddenly at head appeared +Satan, and thus was heard commanding loud. +Vanguard, to right and left the front unfold; +That all may see who hate us, how we seek +Peace and composure, and with open breast +Stand ready to receive them, if they like +Our overture; and turn not back perverse: +But that I doubt; however witness, Heaven! +Heaven, witness thou anon! while we discharge +Freely our part: ye, who appointed stand +Do as you have in charge, and briefly touch +What we propound, and loud that all may hear! +So scoffing in ambiguous words, he scarce +Had ended; when to right and left the front +Divided, and to either flank retired: +Which to our eyes discovered, new and strange, +A triple mounted row of pillars laid +On wheels (for like to pillars most they seemed, +Or hollowed bodies made of oak or fir, +With branches lopt, in wood or mountain felled,) +Brass, iron, stony mould, had not their mouths +With hideous orifice gaped on us wide, +Portending hollow truce: At each behind +A Seraph stood, and in his hand a reed +Stood waving tipt with fire; while we, suspense, +Collected stood within our thoughts amused, +Not long; for sudden all at once their reeds +Put forth, and to a narrow vent applied +With nicest touch. Immediate in a flame, +But soon obscured with smoke, all Heaven appeared, +From those deep-throated engines belched, whose roar +Embowelled with outrageous noise the air, +And all her entrails tore, disgorging foul +Their devilish glut, chained thunderbolts and hail +Of iron globes; which, on the victor host +Levelled, with such impetuous fury smote, +That, whom they hit, none on their feet might stand, +Though standing else as rocks, but down they fell +By thousands, Angel on Arch-Angel rolled; +The sooner for their arms; unarmed, they might +Have easily, as Spirits, evaded swift +By quick contraction or remove; but now +Foul dissipation followed, and forced rout; +Nor served it to relax their serried files. +What should they do? if on they rushed, repulse +Repeated, and indecent overthrow +Doubled, would render them yet more despised, +And to their foes a laughter; for in view +Stood ranked of Seraphim another row, +In posture to displode their second tire +Of thunder: Back defeated to return +They worse abhorred. Satan beheld their plight, +And to his mates thus in derision called. +O Friends! why come not on these victors proud +Ere while they fierce were coming; and when we, +To entertain them fair with open front +And breast, (what could we more?) propounded terms +Of composition, straight they changed their minds, +Flew off, and into strange vagaries fell, +As they would dance; yet for a dance they seemed +Somewhat extravagant and wild; perhaps +For joy of offered peace: But I suppose, +If our proposals once again were heard, +We should compel them to a quick result. +To whom thus Belial, in like gamesome mood. +Leader! the terms we sent were terms of weight, +Of hard contents, and full of force urged home; +Such as we might perceive amused them all, +And stumbled many: Who receives them right, +Had need from head to foot well understand; +Not understood, this gift they have besides, +They show us when our foes walk not upright. +So they among themselves in pleasant vein +Stood scoffing, hightened in their thoughts beyond +All doubt of victory: Eternal Might +To match with their inventions they presumed +So easy, and of his thunder made a scorn, +And all his host derided, while they stood +A while in trouble: But they stood not long; +Rage prompted them at length, and found them arms +Against such hellish mischief fit to oppose. +Forthwith (behold the excellence, the power, +Which God hath in his mighty Angels placed!) +Their arms away they threw, and to the hills +(For Earth hath this variety from Heaven +Of pleasure situate in hill and dale,) +Light as the lightning glimpse they ran, they flew; +From their foundations loosening to and fro, +They plucked the seated hills, with all their load, +Rocks, waters, woods, and by the shaggy tops +Up-lifting bore them in their hands: Amaze, +Be sure, and terrour, seized the rebel host, +When coming towards them so dread they saw +The bottom of the mountains upward turned; +Till on those cursed engines' triple-row +They saw them whelmed, and all their confidence +Under the weight of mountains buried deep; +Themselves invaded next, and on their heads +Main promontories flung, which in the air +Came shadowing, and oppressed whole legions armed; +Their armour helped their harm, crushed in and bruised +Into their substance pent, which wrought them pain +Implacable, and many a dolorous groan; +Long struggling underneath, ere they could wind +Out of such prison, though Spirits of purest light, +Purest at first, now gross by sinning grown. +The rest, in imitation, to like arms +Betook them, and the neighbouring hills uptore: +So hills amid the air encountered hills, +Hurled to and fro with jaculation dire; +That under ground they fought in dismal shade; +Infernal noise! war seemed a civil game +To this uproar; horrid confusion heaped +Upon confusion rose: And now all Heaven +Had gone to wrack, with ruin overspread; +Had not the Almighty Father, where he sits +Shrined in his sanctuary of Heaven secure, +Consulting on the sum of things, foreseen +This tumult, and permitted all, advised: +That his great purpose he might so fulfil, +To honour his anointed Son avenged +Upon his enemies, and to declare +All power on him transferred: Whence to his Son, +The Assessour of his throne, he thus began. +Effulgence of my glory, Son beloved, +Son, in whose face invisible is beheld +Visibly, what by Deity I am; +And in whose hand what by decree I do, +Second Omnipotence! two days are past, +Two days, as we compute the days of Heaven, +Since Michael and his Powers went forth to tame +These disobedient: Sore hath been their fight, +As likeliest was, when two such foes met armed; +For to themselves I left them; and thou knowest, +Equal in their creation they were formed, +Save what sin hath impaired; which yet hath wrought +Insensibly, for I suspend their doom; +Whence in perpetual fight they needs must last +Endless, and no solution will be found: +War wearied hath performed what war can do, +And to disordered rage let loose the reins +With mountains, as with weapons, armed; which makes +Wild work in Heaven, and dangerous to the main. +Two days are therefore past, the third is thine; +For thee I have ordained it; and thus far +Have suffered, that the glory may be thine +Of ending this great war, since none but Thou +Can end it. Into thee such virtue and grace +Immense I have transfused, that all may know +In Heaven and Hell thy power above compare; +And, this perverse commotion governed thus, +To manifest thee worthiest to be Heir +Of all things; to be Heir, and to be King +By sacred unction, thy deserved right. +Go then, Thou Mightiest, in thy Father's might; +Ascend my chariot, guide the rapid wheels +That shake Heaven's basis, bring forth all my war, +My bow and thunder, my almighty arms +Gird on, and sword upon thy puissant thigh; +Pursue these sons of darkness, drive them out +From all Heaven's bounds into the utter deep: +There let them learn, as likes them, to despise +God, and Messiah his anointed King. +He said, and on his Son with rays direct +Shone full; he all his Father full expressed +Ineffably into his face received; +And thus the Filial Godhead answering spake. +O Father, O Supreme of heavenly Thrones, +First, Highest, Holiest, Best; thou always seek'st +To glorify thy Son, I always thee, +As is most just: This I my glory account, +My exaltation, and my whole delight, +That thou, in me well pleased, declarest thy will +Fulfilled, which to fulfil is all my bliss. +Scepter and power, thy giving, I assume, +And gladlier shall resign, when in the end +Thou shalt be all in all, and I in thee +For ever; and in me all whom thou lovest: +But whom thou hatest, I hate, and can put on +Thy terrours, as I put thy mildness on, +Image of thee in all things; and shall soon, +Armed with thy might, rid Heaven of these rebelled; +To their prepared ill mansion driven down, +To chains of darkness, and the undying worm; +That from thy just obedience could revolt, +Whom to obey is happiness entire. +Then shall thy Saints unmixed, and from the impure +Far separate, circling thy holy mount, +Unfeigned Halleluiahs to thee sing, +Hymns of high praise, and I among them Chief. +So said, he, o'er his scepter bowing, rose +From the right hand of Glory where he sat; +And the third sacred morn began to shine, +Dawning through Heaven. Forth rushed with whirlwind sound +The chariot of Paternal Deity, +Flashing thick flames, wheel within wheel undrawn, +Itself instinct with Spirit, but convoyed +By four Cherubick shapes; four faces each +Had wonderous; as with stars, their bodies all +And wings were set with eyes; with eyes the wheels +Of beryl, and careering fires between; +Over their heads a crystal firmament, +Whereon a sapphire throne, inlaid with pure +Amber, and colours of the showery arch. +He, in celestial panoply all armed +Of radiant Urim, work divinely wrought, +Ascended; at his right hand Victory +Sat eagle-winged; beside him hung his bow +And quiver with three-bolted thunder stored; +And from about him fierce effusion rolled +Of smoke, and bickering flame, and sparkles dire: +Attended with ten thousand thousand Saints, +He onward came; far off his coming shone; +And twenty thousand (I their number heard) +Chariots of God, half on each hand, were seen; +He on the wings of Cherub rode sublime +On the crystalline sky, in sapphire throned, +Illustrious far and wide; but by his own +First seen: Them unexpected joy surprised, +When the great ensign of Messiah blazed +Aloft by Angels borne, his sign in Heaven; +Under whose conduct Michael soon reduced +His army, circumfused on either wing, +Under their Head imbodied all in one. +Before him Power Divine his way prepared; +At his command the uprooted hills retired +Each to his place; they heard his voice, and went +Obsequious; Heaven his wonted face renewed, +And with fresh flowerets hill and valley smiled. +This saw his hapless foes, but stood obdured, +And to rebellious fight rallied their Powers, +Insensate, hope conceiving from despair. +In heavenly Spirits could such perverseness dwell? +But to convince the proud what signs avail, +Or wonders move the obdurate to relent? +They, hardened more by what might most reclaim, +Grieving to see his glory, at the sight +Took envy; and, aspiring to his highth, +Stood re-embattled fierce, by force or fraud +Weening to prosper, and at length prevail +Against God and Messiah, or to fall +In universal ruin last; and now +To final battle drew, disdaining flight, +Or faint retreat; when the great Son of God +To all his host on either hand thus spake. +Stand still in bright array, ye Saints; here stand, +Ye Angels armed; this day from battle rest: +Faithful hath been your warfare, and of God +Accepted, fearless in his righteous cause; +And as ye have received, so have ye done, +Invincibly: But of this cursed crew +The punishment to other hand belongs; +Vengeance is his, or whose he sole appoints: +Number to this day's work is not ordained, +Nor multitude; stand only, and behold +God's indignation on these godless poured +By me; not you, but me, they have despised, +Yet envied; against me is all their rage, +Because the Father, to whom in Heaven s'preme +Kingdom, and power, and glory appertains, +Hath honoured me, according to his will. +Therefore to me their doom he hath assigned; +That they may have their wish, to try with me +In battle which the stronger proves; they all, +Or I alone against them; since by strength +They measure all, of other excellence +Not emulous, nor care who them excels; +Nor other strife with them do I vouchsafe. +So spake the Son, and into terrour changed +His countenance too severe to be beheld, +And full of wrath bent on his enemies. +At once the Four spread out their starry wings +With dreadful shade contiguous, and the orbs +Of his fierce chariot rolled, as with the sound +Of torrent floods, or of a numerous host. +He on his impious foes right onward drove, +Gloomy as night; under his burning wheels +The stedfast empyrean shook throughout, +All but the throne itself of God. Full soon +Among them he arrived; in his right hand +Grasping ten thousand thunders, which he sent +Before him, such as in their souls infixed +Plagues: They, astonished, all resistance lost, +All courage; down their idle weapons dropt: +O'er shields, and helms, and helmed heads he rode +Of Thrones and mighty Seraphim prostrate, +That wished the mountains now might be again +Thrown on them, as a shelter from his ire. +Nor less on either side tempestuous fell +His arrows, from the fourfold-visaged Four +Distinct with eyes, and from the living wheels +Distinct alike with multitude of eyes; +One Spirit in them ruled; and every eye +Glared lightning, and shot forth pernicious fire +Among the accursed, that withered all their strength, +And of their wonted vigour left them drained, +Exhausted, spiritless, afflicted, fallen. +Yet half his strength he put not forth, but checked +His thunder in mid volley; for he meant +Not to destroy, but root them out of Heaven: +The overthrown he raised, and as a herd +Of goats or timorous flock together thronged +Drove them before him thunder-struck, pursued +With terrours, and with furies, to the bounds +And crystal wall of Heaven; which, opening wide, +Rolled inward, and a spacious gap disclosed +Into the wasteful deep: The monstrous sight +Struck them with horrour backward, but far worse +Urged them behind: Headlong themselves they threw +Down from the verge of Heaven; eternal wrath +Burnt after them to the bottomless pit. +Hell heard the unsufferable noise, Hell saw +Heaven ruining from Heaven, and would have fled +Affrighted; but strict Fate had cast too deep +Her dark foundations, and too fast had bound. +Nine days they fell: Confounded Chaos roared, +And felt tenfold confusion in their fall +Through his wild anarchy, so huge a rout +Incumbered him with ruin: Hell at last +Yawning received them whole, and on them closed; +Hell, their fit habitation, fraught with fire +Unquenchable, the house of woe and pain. +Disburdened Heaven rejoiced, and soon repaired +Her mural breach, returning whence it rolled. +Sole victor, from the expulsion of his foes, +Messiah his triumphal chariot turned: +To meet him all his Saints, who silent stood +Eye-witnesses of his almighty acts, +With jubilee advanced; and, as they went, +Shaded with branching palm, each Order bright, +Sung triumph, and him sung victorious King, +Son, Heir, and Lord, to him dominion given, +Worthiest to reign: He, celebrated, rode +Triumphant through mid Heaven, into the courts +And temple of his Mighty Father throned +On high; who into glory him received, +Where now he sits at the right hand of bliss. +Thus, measuring things in Heaven by things on Earth, +At thy request, and that thou mayest beware +By what is past, to thee I have revealed +What might have else to human race been hid; +The discord which befel, and war in Heaven +Among the angelick Powers, and the deep fall +Of those too high aspiring, who rebelled +With Satan; he who envies now thy state, +Who now is plotting how he may seduce +Thee also from obedience, that, with him +Bereaved of happiness, thou mayest partake +His punishment, eternal misery; +Which would be all his solace and revenge, +As a despite done against the Most High, +Thee once to gain companion of his woe. +But listen not to his temptations, warn +Thy weaker; let it profit thee to have heard, +By terrible example, the reward +Of disobedience; firm they might have stood, +Yet fell; remember, and fear to transgress. + + + +Book VII + + +Descend from Heaven, Urania, by that name +If rightly thou art called, whose voice divine +Following, above the Olympian hill I soar, +Above the flight of Pegasean wing! +The meaning, not the name, I call: for thou +Nor of the Muses nine, nor on the top +Of old Olympus dwellest; but, heavenly-born, +Before the hills appeared, or fountain flowed, +Thou with eternal Wisdom didst converse, +Wisdom thy sister, and with her didst play +In presence of the Almighty Father, pleased +With thy celestial song. Up led by thee +Into the Heaven of Heavens I have presumed, +An earthly guest, and drawn empyreal air, +Thy tempering: with like safety guided down +Return me to my native element: +Lest from this flying steed unreined, (as once +Bellerophon, though from a lower clime,) +Dismounted, on the Aleian field I fall, +Erroneous there to wander, and forlorn. +Half yet remains unsung, but narrower bound +Within the visible diurnal sphere; +Standing on earth, not rapt above the pole, +More safe I sing with mortal voice, unchanged +To hoarse or mute, though fallen on evil days, +On evil days though fallen, and evil tongues; +In darkness, and with dangers compassed round, +And solitude; yet not alone, while thou +Visitest my slumbers nightly, or when morn +Purples the east: still govern thou my song, +Urania, and fit audience find, though few. +But drive far off the barbarous dissonance +Of Bacchus and his revellers, the race +Of that wild rout that tore the Thracian bard +In Rhodope, where woods and rocks had ears +To rapture, till the savage clamour drowned +Both harp and voice; nor could the Muse defend +Her son. So fail not thou, who thee implores: +For thou art heavenly, she an empty dream. +Say, Goddess, what ensued when Raphael, +The affable Arch-Angel, had forewarned +Adam, by dire example, to beware +Apostasy, by what befel in Heaven +To those apostates; lest the like befall +In Paradise to Adam or his race, +Charged not to touch the interdicted tree, +If they transgress, and slight that sole command, +So easily obeyed amid the choice +Of all tastes else to please their appetite, +Though wandering. He, with his consorted Eve, +The story heard attentive, and was filled +With admiration and deep muse, to hear +Of things so high and strange; things, to their thought +So unimaginable, as hate in Heaven, +And war so near the peace of God in bliss, +With such confusion: but the evil, soon +Driven back, redounded as a flood on those +From whom it sprung; impossible to mix +With blessedness. Whence Adam soon repealed +The doubts that in his heart arose: and now +Led on, yet sinless, with desire to know +What nearer might concern him, how this world +Of Heaven and Earth conspicuous first began; +When, and whereof created; for what cause; +What within Eden, or without, was done +Before his memory; as one whose drouth +Yet scarce allayed still eyes the current stream, +Whose liquid murmur heard new thirst excites, +Proceeded thus to ask his heavenly guest. +Great things, and full of wonder in our ears, +Far differing from this world, thou hast revealed, +Divine interpreter! by favour sent +Down from the empyrean, to forewarn +Us timely of what might else have been our loss, +Unknown, which human knowledge could not reach; +For which to the infinitely Good we owe +Immortal thanks, and his admonishment +Receive, with solemn purpose to observe +Immutably his sovran will, the end +Of what we are. But since thou hast vouchsafed +Gently, for our instruction, to impart +Things above earthly thought, which yet concerned +Our knowing, as to highest wisdom seemed, +Deign to descend now lower, and relate +What may no less perhaps avail us known, +How first began this Heaven which we behold +Distant so high, with moving fires adorned +Innumerable; and this which yields or fills +All space, the ambient air wide interfused +Embracing round this floried Earth; what cause +Moved the Creator, in his holy rest +Through all eternity, so late to build +In Chaos; and the work begun, how soon +Absolved; if unforbid thou mayest unfold +What we, not to explore the secrets ask +Of his eternal empire, but the more +To magnify his works, the more we know. +And the great light of day yet wants to run +Much of his race though steep; suspense in Heaven, +Held by thy voice, thy potent voice, he hears, +And longer will delay to hear thee tell +His generation, and the rising birth +Of Nature from the unapparent Deep: +Or if the star of evening and the moon +Haste to thy audience, Night with her will bring, +Silence; and Sleep, listening to thee, will watch; +Or we can bid his absence, till thy song +End, and dismiss thee ere the morning shine. +Thus Adam his illustrious guest besought: +And thus the Godlike Angel answered mild. +This also thy request, with caution asked, +Obtain; though to recount almighty works +What words or tongue of Seraph can suffice, +Or heart of man suffice to comprehend? +Yet what thou canst attain, which best may serve +To glorify the Maker, and infer +Thee also happier, shall not be withheld +Thy hearing; such commission from above +I have received, to answer thy desire +Of knowledge within bounds; beyond, abstain +To ask; nor let thine own inventions hope +Things not revealed, which the invisible King, +Only Omniscient, hath suppressed in night; +To none communicable in Earth or Heaven: +Enough is left besides to search and know. +But knowledge is as food, and needs no less +Her temperance over appetite, to know +In measure what the mind may well contain; +Oppresses else with surfeit, and soon turns +Wisdom to folly, as nourishment to wind. +Know then, that, after Lucifer from Heaven +(So call him, brighter once amidst the host +Of Angels, than that star the stars among,) +Fell with his flaming legions through the deep +Into his place, and the great Son returned +Victorious with his Saints, the Omnipotent +Eternal Father from his throne beheld +Their multitude, and to his Son thus spake. +At least our envious Foe hath failed, who thought +All like himself rebellious, by whose aid +This inaccessible high strength, the seat +Of Deity supreme, us dispossessed, +He trusted to have seised, and into fraud +Drew many, whom their place knows here no more: +Yet far the greater part have kept, I see, +Their station; Heaven, yet populous, retains +Number sufficient to possess her realms +Though wide, and this high temple to frequent +With ministeries due, and solemn rites: +But, lest his heart exalt him in the harm +Already done, to have dispeopled Heaven, +My damage fondly deemed, I can repair +That detriment, if such it be to lose +Self-lost; and in a moment will create +Another world, out of one man a race +Of men innumerable, there to dwell, +Not here; till, by degrees of merit raised, +They open to themselves at length the way +Up hither, under long obedience tried; +And Earth be changed to Heaven, and Heaven to Earth, +One kingdom, joy and union without end. +Mean while inhabit lax, ye Powers of Heaven; +And thou my Word, begotten Son, by thee +This I perform; speak thou, and be it done! +My overshadowing Spirit and Might with thee +I send along; ride forth, and bid the Deep +Within appointed bounds be Heaven and Earth; +Boundless the Deep, because I Am who fill +Infinitude, nor vacuous the space. +Though I, uncircumscribed myself, retire, +And put not forth my goodness, which is free +To act or not, Necessity and Chance +Approach not me, and what I will is Fate. +So spake the Almighty, and to what he spake +His Word, the Filial Godhead, gave effect. +Immediate are the acts of God, more swift +Than time or motion, but to human ears +Cannot without process of speech be told, +So told as earthly notion can receive. +Great triumph and rejoicing was in Heaven, +When such was heard declared the Almighty's will; +Glory they sung to the Most High, good will +To future men, and in their dwellings peace; +Glory to Him, whose just avenging ire +Had driven out the ungodly from his sight +And the habitations of the just; to Him +Glory and praise, whose wisdom had ordained +Good out of evil to create; instead +Of Spirits malign, a better race to bring +Into their vacant room, and thence diffuse +His good to worlds and ages infinite. +So sang the Hierarchies: Mean while the Son +On his great expedition now appeared, +Girt with Omnipotence, with radiance crowned +Of Majesty Divine; sapience and love +Immense, and all his Father in him shone. +About his chariot numberless were poured +Cherub, and Seraph, Potentates, and Thrones, +And Virtues, winged Spirits, and chariots winged +From the armoury of God; where stand of old +Myriads, between two brazen mountains lodged +Against a solemn day, harnessed at hand, +Celestial equipage; and now came forth +Spontaneous, for within them Spirit lived, +Attendant on their Lord: Heaven opened wide +Her ever-during gates, harmonious sound +On golden hinges moving, to let forth +The King of Glory, in his powerful Word +And Spirit, coming to create new worlds. +On heavenly ground they stood; and from the shore +They viewed the vast immeasurable abyss +Outrageous as a sea, dark, wasteful, wild, +Up from the bottom turned by furious winds +And surging waves, as mountains, to assault +Heaven's highth, and with the center mix the pole. +Silence, ye troubled Waves, and thou Deep, peace, +Said then the Omnifick Word; your discord end! +Nor staid; but, on the wings of Cherubim +Uplifted, in paternal glory rode +Far into Chaos, and the world unborn; +For Chaos heard his voice: Him all his train +Followed in bright procession, to behold +Creation, and the wonders of his might. +Then staid the fervid wheels, and in his hand +He took the golden compasses, prepared +In God's eternal store, to circumscribe +This universe, and all created things: +One foot he centered, and the other turned +Round through the vast profundity obscure; +And said, Thus far extend, thus far thy bounds, +This be thy just circumference, O World! +Thus God the Heaven created, thus the Earth, +Matter unformed and void: Darkness profound +Covered the abyss: but on the watery calm +His brooding wings the Spirit of God outspread, +And vital virtue infused, and vital warmth +Throughout the fluid mass; but downward purged +The black tartareous cold infernal dregs, +Adverse to life: then founded, then conglobed +Like things to like; the rest to several place +Disparted, and between spun out the air; +And Earth self-balanced on her center hung. +Let there be light, said God; and forthwith Light +Ethereal, first of things, quintessence pure, +Sprung from the deep; and from her native east +To journey through the aery gloom began, +Sphered in a radiant cloud, for yet the sun +Was not; she in a cloudy tabernacle +Sojourned the while. God saw the light was good; +And light from darkness by the hemisphere +Divided: light the Day, and darkness Night, +He named. Thus was the first day even and morn: +Nor past uncelebrated, nor unsung +By the celestial quires, when orient light +Exhaling first from darkness they beheld; +Birth-day of Heaven and Earth; with joy and shout +The hollow universal orb they filled, +And touched their golden harps, and hymning praised +God and his works; Creator him they sung, +Both when first evening was, and when first morn. +Again, God said, Let there be firmament +Amid the waters, and let it divide +The waters from the waters; and God made +The firmament, expanse of liquid, pure, +Transparent, elemental air, diffused +In circuit to the uttermost convex +Of this great round; partition firm and sure, +The waters underneath from those above +Dividing: for as earth, so he the world +Built on circumfluous waters calm, in wide +Crystalline ocean, and the loud misrule +Of Chaos far removed; lest fierce extremes +Contiguous might distemper the whole frame: +And Heaven he named the Firmament: So even +And morning chorus sung the second day. +The Earth was formed, but in the womb as yet +Of waters, embryon immature involved, +Appeared not: over all the face of Earth +Main ocean flowed, not idle; but, with warm +Prolifick humour softening all her globe, +Fermented the great mother to conceive, +Satiate with genial moisture; when God said, +Be gathered now ye waters under Heaven +Into one place, and let dry land appear. +Immediately the mountains huge appear +Emergent, and their broad bare backs upheave +Into the clouds; their tops ascend the sky: +So high as heaved the tumid hills, so low +Down sunk a hollow bottom broad and deep, +Capacious bed of waters: Thither they +Hasted with glad precipitance, uprolled, +As drops on dust conglobing from the dry: +Part rise in crystal wall, or ridge direct, +For haste; such flight the great command impressed +On the swift floods: As armies at the call +Of trumpet (for of armies thou hast heard) +Troop to their standard; so the watery throng, +Wave rolling after wave, where way they found, +If steep, with torrent rapture, if through plain, +Soft-ebbing; nor withstood them rock or hill; +But they, or under ground, or circuit wide +With serpent errour wandering, found their way, +And on the washy oose deep channels wore; +Easy, ere God had bid the ground be dry, +All but within those banks, where rivers now +Stream, and perpetual draw their humid train. +The dry land, Earth; and the great receptacle +Of congregated waters, he called Seas: +And saw that it was good; and said, Let the Earth +Put forth the verdant grass, herb yielding seed, +And fruit-tree yielding fruit after her kind, +Whose seed is in herself upon the Earth. +He scarce had said, when the bare Earth, till then +Desart and bare, unsightly, unadorned, +Brought forth the tender grass, whose verdure clad +Her universal face with pleasant green; +Then herbs of every leaf, that sudden flowered +Opening their various colours, and made gay +Her bosom, smelling sweet: and, these scarce blown, +Forth flourished thick the clustering vine, forth crept +The swelling gourd, up stood the corny reed +Embattled in her field, and the humble shrub, +And bush with frizzled hair implicit: Last +Rose, as in dance, the stately trees, and spread +Their branches hung with copious fruit, or gemmed +Their blossoms: With high woods the hills were crowned; +With tufts the valleys, and each fountain side; +With borders long the rivers: that Earth now +Seemed like to Heaven, a seat where Gods might dwell, +Or wander with delight, and love to haunt +Her sacred shades: though God had yet not rained +Upon the Earth, and man to till the ground +None was; but from the Earth a dewy mist +Went up, and watered all the ground, and each +Plant of the field; which, ere it was in the Earth, +God made, and every herb, before it grew +On the green stem: God saw that it was good: +So even and morn recorded the third day. +Again the Almighty spake, Let there be lights +High in the expanse of Heaven, to divide +The day from night; and let them be for signs, +For seasons, and for days, and circling years; +And let them be for lights, as I ordain +Their office in the firmament of Heaven, +To give light on the Earth; and it was so. +And God made two great lights, great for their use +To Man, the greater to have rule by day, +The less by night, altern; and made the stars, +And set them in the firmament of Heaven +To illuminate the Earth, and rule the day +In their vicissitude, and rule the night, +And light from darkness to divide. God saw, +Surveying his great work, that it was good: +For of celestial bodies first the sun +A mighty sphere he framed, unlightsome first, +Though of ethereal mould: then formed the moon +Globose, and every magnitude of stars, +And sowed with stars the Heaven, thick as a field: +Of light by far the greater part he took, +Transplanted from her cloudy shrine, and placed +In the sun's orb, made porous to receive +And drink the liquid light; firm to retain +Her gathered beams, great palace now of light. +Hither, as to their fountain, other stars +Repairing, in their golden urns draw light, +And hence the morning-planet gilds her horns; +By tincture or reflection they augment +Their small peculiar, though from human sight +So far remote, with diminution seen, +First in his east the glorious lamp was seen, +Regent of day, and all the horizon round +Invested with bright rays, jocund to run +His longitude through Heaven's high road; the gray +Dawn, and the Pleiades, before him danced, +Shedding sweet influence: Less bright the moon, +But opposite in levelled west was set, +His mirrour, with full face borrowing her light +From him; for other light she needed none +In that aspect, and still that distance keeps +Till night; then in the east her turn she shines, +Revolved on Heaven's great axle, and her reign +With thousand lesser lights dividual holds, +With thousand thousand stars, that then appeared +Spangling the hemisphere: Then first adorned +With their bright luminaries that set and rose, +Glad evening and glad morn crowned the fourth day. +And God said, Let the waters generate +Reptile with spawn abundant, living soul: +And let fowl fly above the Earth, with wings +Displayed on the open firmament of Heaven. +And God created the great whales, and each +Soul living, each that crept, which plenteously +The waters generated by their kinds; +And every bird of wing after his kind; +And saw that it was good, and blessed them, saying. +Be fruitful, multiply, and in the seas, +And lakes, and running streams, the waters fill; +And let the fowl be multiplied, on the Earth. +Forthwith the sounds and seas, each creek and bay, +With fry innumerable swarm, and shoals +Of fish that with their fins, and shining scales, +Glide under the green wave, in sculls that oft +Bank the mid sea: part single, or with mate, +Graze the sea-weed their pasture, and through groves +Of coral stray; or, sporting with quick glance, +Show to the sun their waved coats dropt with gold; +Or, in their pearly shells at ease, attend +Moist nutriment; or under rocks their food +In jointed armour watch: on smooth the seal +And bended dolphins play: part huge of bulk +Wallowing unwieldy, enormous in their gait, +Tempest the ocean: there leviathan, +Hugest of living creatures, on the deep +Stretched like a promontory sleeps or swims, +And seems a moving land; and at his gills +Draws in, and at his trunk spouts out, a sea. +Mean while the tepid caves, and fens, and shores, +Their brood as numerous hatch, from the egg that soon +Bursting with kindly rupture forth disclosed +Their callow young; but feathered soon and fledge +They summed their pens; and, soaring the air sublime, +With clang despised the ground, under a cloud +In prospect; there the eagle and the stork +On cliffs and cedar tops their eyries build: +Part loosely wing the region, part more wise +In common, ranged in figure, wedge their way, +Intelligent of seasons, and set forth +Their aery caravan, high over seas +Flying, and over lands, with mutual wing +Easing their flight; so steers the prudent crane +Her annual voyage, borne on winds; the air +Floats as they pass, fanned with unnumbered plumes: +From branch to branch the smaller birds with song +Solaced the woods, and spread their painted wings +Till even; nor then the solemn nightingale +Ceased warbling, but all night tun'd her soft lays: +Others, on silver lakes and rivers, bathed +Their downy breast; the swan with arched neck, +Between her white wings mantling proudly, rows +Her state with oary feet; yet oft they quit +The dank, and, rising on stiff pennons, tower +The mid aereal sky: Others on ground +Walked firm; the crested cock whose clarion sounds +The silent hours, and the other whose gay train +Adorns him, coloured with the florid hue +Of rainbows and starry eyes. The waters thus +With fish replenished, and the air with fowl, +Evening and morn solemnized the fifth day. +The sixth, and of creation last, arose +With evening harps and matin; when God said, +Let the Earth bring forth soul living in her kind, +Cattle, and creeping things, and beast of the Earth, +Each in their kind. The Earth obeyed, and straight +Opening her fertile womb teemed at a birth +Innumerous living creatures, perfect forms, +Limbed and full grown: Out of the ground up rose, +As from his lair, the wild beast where he wons +In forest wild, in thicket, brake, or den; +Among the trees in pairs they rose, they walked: +The cattle in the fields and meadows green: +Those rare and solitary, these in flocks +Pasturing at once, and in broad herds upsprung. +The grassy clods now calved; now half appeared +The tawny lion, pawing to get free +His hinder parts, then springs as broke from bonds, +And rampant shakes his brinded mane; the ounce, +The libbard, and the tiger, as the mole +Rising, the crumbled earth above them threw +In hillocks: The swift stag from under ground +Bore up his branching head: Scarce from his mould +Behemoth biggest born of earth upheaved +His vastness: Fleeced the flocks and bleating rose, +As plants: Ambiguous between sea and land +The river-horse, and scaly crocodile. +At once came forth whatever creeps the ground, +Insect or worm: those waved their limber fans +For wings, and smallest lineaments exact +In all the liveries decked of summer's pride +With spots of gold and purple, azure and green: +These, as a line, their long dimension drew, +Streaking the ground with sinuous trace; not all +Minims of nature; some of serpent-kind, +Wonderous in length and corpulence, involved +Their snaky folds, and added wings. First crept +The parsimonious emmet, provident +Of future; in small room large heart enclosed; +Pattern of just equality perhaps +Hereafter, joined in her popular tribes +Of commonalty: Swarming next appeared +The female bee, that feeds her husband drone +Deliciously, and builds her waxen cells +With honey stored: The rest are numberless, +And thou their natures knowest, and gavest them names, +Needless to thee repeated; nor unknown +The serpent, subtlest beast of all the field, +Of huge extent sometimes, with brazen eyes +And hairy mane terrifick, though to thee +Not noxious, but obedient at thy call. +Now Heaven in all her glory shone, and rolled +Her motions, as the great first Mover's hand +First wheeled their course: Earth in her rich attire +Consummate lovely smiled; air, water, earth, +By fowl, fish, beast, was flown, was swum, was walked, +Frequent; and of the sixth day yet remained: +There wanted yet the master-work, the end +Of all yet done; a creature, who, not prone +And brute as other creatures, but endued +With sanctity of reason, might erect +His stature, and upright with front serene +Govern the rest, self-knowing; and from thence +Magnanimous to correspond with Heaven, +But grateful to acknowledge whence his good +Descends, thither with heart, and voice, and eyes +Directed in devotion, to adore +And worship God Supreme, who made him chief +Of all his works: therefore the Omnipotent +Eternal Father (for where is not he +Present?) thus to his Son audibly spake. +Let us make now Man in our image, Man +In our similitude, and let them rule +Over the fish and fowl of sea and air, +Beast of the field, and over all the Earth, +And every creeping thing that creeps the ground. +This said, he formed thee, Adam, thee, O Man, +Dust of the ground, and in thy nostrils breathed +The breath of life; in his own image he +Created thee, in the image of God +Express; and thou becamest a living soul. +Male he created thee; but thy consort +Female, for race; then blessed mankind, and said, +Be fruitful, multiply, and fill the Earth; +Subdue it, and throughout dominion hold +Over fish of the sea, and fowl of the air, +And every living thing that moves on the Earth. +Wherever thus created, for no place +Is yet distinct by name, thence, as thou knowest, +He brought thee into this delicious grove, +This garden, planted with the trees of God, +Delectable both to behold and taste; +And freely all their pleasant fruit for food +Gave thee; all sorts are here that all the Earth yields, +Variety without end; but of the tree, +Which, tasted, works knowledge of good and evil, +Thou mayest not; in the day thou eatest, thou diest; +Death is the penalty imposed; beware, +And govern well thy appetite; lest Sin +Surprise thee, and her black attendant Death. +Here finished he, and all that he had made +Viewed, and behold all was entirely good; +So even and morn accomplished the sixth day: +Yet not till the Creator from his work +Desisting, though unwearied, up returned, +Up to the Heaven of Heavens, his high abode; +Thence to behold this new created world, +The addition of his empire, how it showed +In prospect from his throne, how good, how fair, +Answering his great idea. Up he rode +Followed with acclamation, and the sound +Symphonious of ten thousand harps, that tuned +Angelick harmonies: The earth, the air +Resounded, (thou rememberest, for thou heardst,) +The heavens and all the constellations rung, +The planets in their station listening stood, +While the bright pomp ascended jubilant. +Open, ye everlasting gates! they sung, +Open, ye Heavens! your living doors;let in +The great Creator from his work returned +Magnificent, his six days work, a World; +Open, and henceforth oft; for God will deign +To visit oft the dwellings of just men, +Delighted; and with frequent intercourse +Thither will send his winged messengers +On errands of supernal grace. So sung +The glorious train ascending: He through Heaven, +That opened wide her blazing portals, led +To God's eternal house direct the way; +A broad and ample road, whose dust is gold +And pavement stars, as stars to thee appear, +Seen in the galaxy, that milky way, +Which nightly, as a circling zone, thou seest +Powdered with stars. And now on Earth the seventh +Evening arose in Eden, for the sun +Was set, and twilight from the east came on, +Forerunning night; when at the holy mount +Of Heaven's high-seated top, the imperial throne +Of Godhead, fixed for ever firm and sure, +The Filial Power arrived, and sat him down +With his great Father; for he also went +Invisible, yet staid, (such privilege +Hath Omnipresence) and the work ordained, +Author and End of all things; and, from work +Now resting, blessed and hallowed the seventh day, +As resting on that day from all his work, +But not in silence holy kept: the harp +Had work and rested not; the solemn pipe, +And dulcimer, all organs of sweet stop, +All sounds on fret by string or golden wire, +Tempered soft tunings, intermixed with voice +Choral or unison: of incense clouds, +Fuming from golden censers, hid the mount. +Creation and the six days acts they sung: +Great are thy works, Jehovah! infinite +Thy power! what thought can measure thee, or tongue +Relate thee! Greater now in thy return +Than from the giant Angels: Thee that day +Thy thunders magnified; but to create +Is greater than created to destroy. +Who can impair thee, Mighty King, or bound +Thy empire! Easily the proud attempt +Of Spirits apostate, and their counsels vain, +Thou hast repelled; while impiously they thought +Thee to diminish, and from thee withdraw +The number of thy worshippers. Who seeks +To lessen thee, against his purpose serves +To manifest the more thy might: his evil +Thou usest, and from thence createst more good. +Witness this new-made world, another Heaven +From Heaven-gate not far, founded in view +On the clear hyaline, the glassy sea; +Of amplitude almost immense, with stars +Numerous, and every star perhaps a world +Of destined habitation; but thou knowest +Their seasons: among these the seat of Men, +Earth, with her nether ocean circumfused, +Their pleasant dwelling-place. Thrice happy Men, +And sons of Men, whom God hath thus advanced! +Created in his image, there to dwell +And worship him; and in reward to rule +Over his works, on earth, in sea, or air, +And multiply a race of worshippers +Holy and just: Thrice happy, if they know +Their happiness, and persevere upright! +So sung they, and the empyrean rung +With halleluiahs: Thus was sabbath kept. +And thy request think now fulfilled, that asked +How first this world and face of things began, +And what before thy memory was done +From the beginning; that posterity, +Informed by thee, might know: If else thou seekest +Aught, not surpassing human measure, say. + + + +Book VIII + + +The Angel ended, and in Adam's ear +So charming left his voice, that he a while +Thought him still speaking, still stood fixed to hear; +Then, as new waked, thus gratefully replied. +What thanks sufficient, or what recompence +Equal, have I to render thee, divine +Historian, who thus largely hast allayed +The thirst I had of knowledge, and vouchsafed +This friendly condescension to relate +Things, else by me unsearchable; now heard +With wonder, but delight, and, as is due, +With glory attributed to the high +Creator! Something yet of doubt remains, +Which only thy solution can resolve. +When I behold this goodly frame, this world, +Of Heaven and Earth consisting; and compute +Their magnitudes; this Earth, a spot, a grain, +An atom, with the firmament compared +And all her numbered stars, that seem to roll +Spaces incomprehensible, (for such +Their distance argues, and their swift return +Diurnal,) merely to officiate light +Round this opacous Earth, this punctual spot, +One day and night; in all her vast survey +Useless besides; reasoning I oft admire, +How Nature wise and frugal could commit +Such disproportions, with superfluous hand +So many nobler bodies to create, +Greater so manifold, to this one use, +For aught appears, and on their orbs impose +Such restless revolution day by day +Repeated; while the sedentary Earth, +That better might with far less compass move, +Served by more noble than herself, attains +Her end without least motion, and receives, +As tribute, such a sumless journey brought +Of incorporeal speed, her warmth and light; +Speed, to describe whose swiftness number fails. +So spake our sire, and by his countenance seemed +Entering on studious thoughts abstruse; which Eve +Perceiving, where she sat retired in sight, +With lowliness majestick from her seat, +And grace that won who saw to wish her stay, +Rose, and went forth among her fruits and flowers, +To visit how they prospered, bud and bloom, +Her nursery; they at her coming sprung, +And, touched by her fair tendance, gladlier grew. +Yet went she not, as not with such discourse +Delighted, or not capable her ear +Of what was high: such pleasure she reserved, +Adam relating, she sole auditress; +Her husband the relater she preferred +Before the Angel, and of him to ask +Chose rather; he, she knew, would intermix +Grateful digressions, and solve high dispute +With conjugal caresses: from his lip +Not words alone pleased her. O! when meet now +Such pairs, in love and mutual honour joined? +With Goddess-like demeanour forth she went, +Not unattended; for on her, as Queen, +A pomp of winning Graces waited still, +And from about her shot darts of desire +Into all eyes, to wish her still in sight. +And Raphael now, to Adam's doubt proposed, +Benevolent and facile thus replied. +To ask or search, I blame thee not; for Heaven +Is as the book of God before thee set, +Wherein to read his wonderous works, and learn +His seasons, hours, or days, or months, or years: +This to attain, whether Heaven move or Earth, +Imports not, if thou reckon right; the rest +From Man or Angel the great Architect +Did wisely to conceal, and not divulge +His secrets to be scanned by them who ought +Rather admire; or, if they list to try +Conjecture, he his fabrick of the Heavens +Hath left to their disputes, perhaps to move +His laughter at their quaint opinions wide +Hereafter; when they come to model Heaven +And calculate the stars, how they will wield +The mighty frame; how build, unbuild, contrive +To save appearances; how gird the sphere +With centrick and eccentrick scribbled o'er, +Cycle and epicycle, orb in orb: +Already by thy reasoning this I guess, +Who art to lead thy offspring, and supposest +That bodies bright and greater should not serve +The less not bright, nor Heaven such journeys run, +Earth sitting still, when she alone receives +The benefit: Consider first, that great +Or bright infers not excellence: the Earth +Though, in comparison of Heaven, so small, +Nor glistering, may of solid good contain +More plenty than the sun that barren shines; +Whose virtue on itself works no effect, +But in the fruitful Earth; there first received, +His beams, unactive else, their vigour find. +Yet not to Earth are those bright luminaries +Officious; but to thee, Earth's habitant. +And for the Heaven's wide circuit, let it speak +The Maker's high magnificence, who built +So spacious, and his line stretched out so far; +That Man may know he dwells not in his own; +An edifice too large for him to fill, +Lodged in a small partition; and the rest +Ordained for uses to his Lord best known. +The swiftness of those circles attribute, +Though numberless, to his Omnipotence, +That to corporeal substances could add +Speed almost spiritual: Me thou thinkest not slow, +Who since the morning-hour set out from Heaven +Where God resides, and ere mid-day arrived +In Eden; distance inexpressible +By numbers that have name. But this I urge, +Admitting motion in the Heavens, to show +Invalid that which thee to doubt it moved; +Not that I so affirm, though so it seem +To thee who hast thy dwelling here on Earth. +God, to remove his ways from human sense, +Placed Heaven from Earth so far, that earthly sight, +If it presume, might err in things too high, +And no advantage gain. What if the sun +Be center to the world; and other stars, +By his attractive virtue and their own +Incited, dance about him various rounds? +Their wandering course now high, now low, then hid, +Progressive, retrograde, or standing still, +In six thou seest; and what if seventh to these +The planet earth, so stedfast though she seem, +Insensibly three different motions move? +Which else to several spheres thou must ascribe, +Moved contrary with thwart obliquities; +Or save the sun his labour, and that swift +Nocturnal and diurnal rhomb supposed, +Invisible else above all stars, the wheel +Of day and night; which needs not thy belief, +If earth, industrious of herself, fetch day +Travelling east, and with her part averse +From the sun's beam meet night, her other part +Still luminous by his ray. What if that light, +Sent from her through the wide transpicuous air, +To the terrestrial moon be as a star, +Enlightening her by day, as she by night +This earth? reciprocal, if land be there, +Fields and inhabitants: Her spots thou seest +As clouds, and clouds may rain, and rain produce +Fruits in her softened soil for some to eat +Allotted there; and other suns perhaps, +With their attendant moons, thou wilt descry, +Communicating male and female light; +Which two great sexes animate the world, +Stored in each orb perhaps with some that live. +For such vast room in Nature unpossessed +By living soul, desart and desolate, +Only to shine, yet scarce to contribute +Each orb a glimpse of light, conveyed so far +Down to this habitable, which returns +Light back to them, is obvious to dispute. +But whether thus these things, or whether not; +But whether the sun, predominant in Heaven, +Rise on the earth; or earth rise on the sun; +He from the east his flaming road begin; +Or she from west her silent course advance, +With inoffensive pace that spinning sleeps +On her soft axle, while she paces even, +And bears thee soft with the smooth hair along; +Sollicit not thy thoughts with matters hid; +Leave them to God above; him serve, and fear! +Of other creatures, as him pleases best, +Wherever placed, let him dispose; joy thou +In what he gives to thee, this Paradise +And thy fair Eve; Heaven is for thee too high +To know what passes there; be lowly wise: +Think only what concerns thee, and thy being; +Dream not of other worlds, what creatures there +Live, in what state, condition, or degree; +Contented that thus far hath been revealed +Not of Earth only, but of highest Heaven. +To whom thus Adam, cleared of doubt, replied. +How fully hast thou satisfied me, pure +Intelligence of Heaven, Angel serene! +And, freed from intricacies, taught to live +The easiest way; nor with perplexing thoughts +To interrupt the sweet of life, from which +God hath bid dwell far off all anxious cares, +And not molest us; unless we ourselves +Seek them with wandering thoughts, and notions vain. +But apt the mind or fancy is to rove +Unchecked, and of her roving is no end; +Till warned, or by experience taught, she learn, +That, not to know at large of things remote +From use, obscure and subtle; but, to know +That which before us lies in daily life, +Is the prime wisdom: What is more, is fume, +Or emptiness, or fond impertinence: +And renders us, in things that most concern, +Unpractised, unprepared, and still to seek. +Therefore from this high pitch let us descend +A lower flight, and speak of things at hand +Useful; whence, haply, mention may arise +Of something not unseasonable to ask, +By sufferance, and thy wonted favour, deigned. +Thee I have heard relating what was done +Ere my remembrance: now, hear me relate +My story, which perhaps thou hast not heard; +And day is not yet spent; till then thou seest +How subtly to detain thee I devise; +Inviting thee to hear while I relate; +Fond! were it not in hope of thy reply: +For, while I sit with thee, I seem in Heaven; +And sweeter thy discourse is to my ear +Than fruits of palm-tree pleasantest to thirst +And hunger both, from labour, at the hour +Of sweet repast; they satiate, and soon fill, +Though pleasant; but thy words, with grace divine +Imbued, bring to their sweetness no satiety. +To whom thus Raphael answered heavenly meek. +Nor are thy lips ungraceful, Sire of men, +Nor tongue ineloquent; for God on thee +Abundantly his gifts hath also poured +Inward and outward both, his image fair: +Speaking, or mute, all comeliness and grace +Attends thee; and each word, each motion, forms; +Nor less think we in Heaven of thee on Earth +Than of our fellow-servant, and inquire +Gladly into the ways of God with Man: +For God, we see, hath honoured thee, and set +On Man his equal love: Say therefore on; +For I that day was absent, as befel, +Bound on a voyage uncouth and obscure, +Far on excursion toward the gates of Hell; +Squared in full legion (such command we had) +To see that none thence issued forth a spy, +Or enemy, while God was in his work; +Lest he, incensed at such eruption bold, +Destruction with creation might have mixed. +Not that they durst without his leave attempt; +But us he sends upon his high behests +For state, as Sovran King; and to inure +Our prompt obedience. Fast we found, fast shut, +The dismal gates, and barricadoed strong; +But long ere our approaching heard within +Noise, other than the sound of dance or song, +Torment, and loud lament, and furious rage. +Glad we returned up to the coasts of light +Ere sabbath-evening: so we had in charge. +But thy relation now; for I attend, +Pleased with thy words no less than thou with mine. +So spake the Godlike Power, and thus our Sire. +For Man to tell how human life began +Is hard; for who himself beginning knew +Desire with thee still longer to converse +Induced me. As new waked from soundest sleep, +Soft on the flowery herb I found me laid, +In balmy sweat; which with his beams the sun +Soon dried, and on the reeking moisture fed. +Straight toward Heaven my wondering eyes I turned, +And gazed a while the ample sky; till, raised +By quick instinctive motion, up I sprung, +As thitherward endeavouring, and upright +Stood on my feet: about me round I saw +Hill, dale, and shady woods, and sunny plains, +And liquid lapse of murmuring streams; by these, +Creatures that lived and moved, and walked, or flew; +Birds on the branches warbling; all things smiled; +With fragrance and with joy my heart o'erflowed. +Myself I then perused, and limb by limb +Surveyed, and sometimes went, and sometimes ran +With supple joints, as lively vigour led: +But who I was, or where, or from what cause, +Knew not; to speak I tried, and forthwith spake; +My tongue obeyed, and readily could name +Whate'er I saw. Thou Sun, said I, fair light, +And thou enlightened Earth, so fresh and gay, +Ye Hills, and Dales, ye Rivers, Woods, and Plains, +And ye that live and move, fair Creatures, tell, +Tell, if ye saw, how I came thus, how here?-- +Not of myself;--by some great Maker then, +In goodness and in power pre-eminent: +Tell me, how may I know him, how adore, +From whom I have that thus I move and live, +And feel that I am happier than I know.-- +While thus I called, and strayed I knew not whither, +From where I first drew air, and first beheld +This happy light; when, answer none returned, +On a green shady bank, profuse of flowers, +Pensive I sat me down: There gentle sleep +First found me, and with soft oppression seised +My droused sense, untroubled, though I thought +I then was passing to my former state +Insensible, and forthwith to dissolve: +When suddenly stood at my head a dream, +Whose inward apparition gently moved +My fancy to believe I yet had being, +And lived: One came, methought, of shape divine, +And said, 'Thy mansion wants thee, Adam; rise, +'First Man, of men innumerable ordained +'First Father! called by thee, I come thy guide +'To the garden of bliss, thy seat prepared.' +So saying, by the hand he took me raised, +And over fields and waters, as in air +Smooth-sliding without step, last led me up +A woody mountain; whose high top was plain, +A circuit wide, enclosed, with goodliest trees +Planted, with walks, and bowers; that what I saw +Of Earth before scarce pleasant seemed. Each tree, +Loaden with fairest fruit that hung to the eye +Tempting, stirred in me sudden appetite +To pluck and eat; whereat I waked, and found +Before mine eyes all real, as the dream +Had lively shadowed: Here had new begun +My wandering, had not he, who was my guide +Up hither, from among the trees appeared, +Presence Divine. Rejoicing, but with awe, +In adoration at his feet I fell +Submiss: He reared me, and 'Whom thou soughtest I am,' +Said mildly, 'Author of all this thou seest +'Above, or round about thee, or beneath. +'This Paradise I give thee, count it thine +'To till and keep, and of the fruit to eat: +'Of every tree that in the garden grows +'Eat freely with glad heart; fear here no dearth: +'But of the tree whose operation brings +'Knowledge of good and ill, which I have set +'The pledge of thy obedience and thy faith, +'Amid the garden by the tree of life, +'Remember what I warn thee, shun to taste, +'And shun the bitter consequence: for know, +'The day thou eatest thereof, my sole command +'Transgressed, inevitably thou shalt die, +'From that day mortal; and this happy state +'Shalt lose, expelled from hence into a world +'Of woe and sorrow.' Sternly he pronounced +The rigid interdiction, which resounds +Yet dreadful in mine ear, though in my choice +Not to incur; but soon his clear aspect +Returned, and gracious purpose thus renewed. +'Not only these fair bounds, but all the Earth +'To thee and to thy race I give; as lords +'Possess it, and all things that therein live, +'Or live in sea, or air; beast, fish, and fowl. +'In sign whereof, each bird and beast behold +'After their kinds; I bring them to receive +'From thee their names, and pay thee fealty +'With low subjection; understand the same +'Of fish within their watery residence, +'Not hither summoned, since they cannot change +'Their element, to draw the thinner air.' +As thus he spake, each bird and beast behold +Approaching two and two; these cowering low +With blandishment; each bird stooped on his wing. +I named them, as they passed, and understood +Their nature, with such knowledge God endued +My sudden apprehension: But in these +I found not what methought I wanted still; +And to the heavenly Vision thus presumed. +O, by what name, for thou above all these, +Above mankind, or aught than mankind higher, +Surpassest far my naming; how may I +Adore thee, Author of this universe, +And all this good to man? for whose well being +So amply, and with hands so liberal, +Thou hast provided all things: But with me +I see not who partakes. In solitude +What happiness, who can enjoy alone, +Or, all enjoying, what contentment find? +Thus I presumptuous; and the Vision bright, +As with a smile more brightened, thus replied. +What callest thou solitude? Is not the Earth +With various living creatures, and the air +Replenished, and all these at thy command +To come and play before thee? Knowest thou not +Their language and their ways? They also know, +And reason not contemptibly: With these +Find pastime, and bear rule; thy realm is large. +So spake the Universal Lord, and seemed +So ordering: I, with leave of speech implored, +And humble deprecation, thus replied. +Let not my words offend thee, Heavenly Power; +My Maker, be propitious while I speak. +Hast thou not made me here thy substitute, +And these inferiour far beneath me set? +Among unequals what society +Can sort, what harmony, or true delight? +Which must be mutual, in proportion due +Given and received; but, in disparity +The one intense, the other still remiss, +Cannot well suit with either, but soon prove +Tedious alike: Of fellowship I speak +Such as I seek, fit to participate +All rational delight: wherein the brute +Cannot be human consort: They rejoice +Each with their kind, lion with lioness; +So fitly them in pairs thou hast combined: +Much less can bird with beast, or fish with fowl +So well converse, nor with the ox the ape; +Worse then can man with beast, and least of all. +Whereto the Almighty answered, not displeased. +A nice and subtle happiness, I see, +Thou to thyself proposest, in the choice +Of thy associates, Adam! and wilt taste +No pleasure, though in pleasure, solitary. +What thinkest thou then of me, and this my state? +Seem I to thee sufficiently possessed +Of happiness, or not? who am alone +From all eternity; for none I know +Second to me or like, equal much less. +How have I then with whom to hold converse, +Save with the creatures which I made, and those +To me inferiour, infinite descents +Beneath what other creatures are to thee? +He ceased; I lowly answered. To attain +The highth and depth of thy eternal ways +All human thoughts come short, Supreme of things! +Thou in thyself art perfect, and in thee +Is no deficience found: Not so is Man, +But in degree; the cause of his desire +By conversation with his like to help +Or solace his defects. No need that thou +Shouldst propagate, already Infinite; +And through all numbers absolute, though One: +But Man by number is to manifest +His single imperfection, and beget +Like of his like, his image multiplied, +In unity defective; which requires +Collateral love, and dearest amity. +Thou in thy secresy although alone, +Best with thyself accompanied, seekest not +Social communication; yet, so pleased, +Canst raise thy creature to what highth thou wilt +Of union or communion, deified: +I, by conversing, cannot these erect +From prone; nor in their ways complacence find. +Thus I emboldened spake, and freedom used +Permissive, and acceptance found; which gained +This answer from the gracious Voice Divine. +Thus far to try thee, Adam, I was pleased; +And find thee knowing, not of beasts alone, +Which thou hast rightly named, but of thyself; +Expressing well the spirit within thee free, +My image, not imparted to the brute; +Whose fellowship therefore unmeet for thee +Good reason was thou freely shouldst dislike; +And be so minded still: I, ere thou spakest, +Knew it not good for Man to be alone; +And no such company as then thou sawest +Intended thee; for trial only brought, +To see how thou couldest judge of fit and meet: +What next I bring shall please thee, be assured, +Thy likeness, thy fit help, thy other self, +Thy wish exactly to thy heart's desire. +He ended, or I heard no more; for now +My earthly by his heavenly overpowered, +Which it had long stood under, strained to the highth +In that celestial colloquy sublime, +As with an object that excels the sense +Dazzled and spent, sunk down; and sought repair +Of sleep, which instantly fell on me, called +By Nature as in aid, and closed mine eyes. +Mine eyes he closed, but open left the cell +Of fancy, my internal sight; by which, +Abstract as in a trance, methought I saw, +Though sleeping, where I lay, and saw the shape +Still glorious before whom awake I stood: +Who stooping opened my left side, and took +From thence a rib, with cordial spirits warm, +And life-blood streaming fresh; wide was the wound, +But suddenly with flesh filled up and healed: +The rib he formed and fashioned with his hands; +Under his forming hands a creature grew, +Man-like, but different sex; so lovely fair, +That what seemed fair in all the world, seemed now +Mean, or in her summed up, in her contained +And in her looks; which from that time infused +Sweetness into my heart, unfelt before, +And into all things from her air inspired +The spirit of love and amorous delight. +She disappeared, and left me dark; I waked +To find her, or for ever to deplore +Her loss, and other pleasures all abjure: +When out of hope, behold her, not far off, +Such as I saw her in my dream, adorned +With what all Earth or Heaven could bestow +To make her amiable: On she came, +Led by her heavenly Maker, though unseen, +And guided by his voice; nor uninformed +Of nuptial sanctity, and marriage rites: +Grace was in all her steps, Heaven in her eye, +In every gesture dignity and love. +I, overjoyed, could not forbear aloud. +This turn hath made amends; thou hast fulfilled +Thy words, Creator bounteous and benign, +Giver of all things fair! but fairest this +Of all thy gifts! nor enviest. I now see +Bone of my bone, flesh of my flesh, myself +Before me: Woman is her name;of Man +Extracted: for this cause he shall forego +Father and mother, and to his wife adhere; +And they shall be one flesh, one heart, one soul. +She heard me thus; and though divinely brought, +Yet innocence, and virgin modesty, +Her virtue, and the conscience of her worth, +That would be wooed, and not unsought be won, +Not obvious, not obtrusive, but, retired, +The more desirable; or, to say all, +Nature herself, though pure of sinful thought, +Wrought in her so, that, seeing me, she turned: +I followed her; she what was honour knew, +And with obsequious majesty approved +My pleaded reason. To the nuptial bower +I led her blushing like the morn: All Heaven, +And happy constellations, on that hour +Shed their selectest influence; the Earth +Gave sign of gratulation, and each hill; +Joyous the birds; fresh gales and gentle airs +Whispered it to the woods, and from their wings +Flung rose, flung odours from the spicy shrub, +Disporting, till the amorous bird of night +Sung spousal, and bid haste the evening-star +On his hill top, to light the bridal lamp. +Thus have I told thee all my state, and brought +My story to the sum of earthly bliss, +Which I enjoy; and must confess to find +In all things else delight indeed, but such +As, used or not, works in the mind no change, +Nor vehement desire; these delicacies +I mean of taste, sight, smell, herbs, fruits, and flowers, +Walks, and the melody of birds: but here +Far otherwise, transported I behold, +Transported touch; here passion first I felt, +Commotion strange! in all enjoyments else +Superiour and unmoved; here only weak +Against the charm of Beauty's powerful glance. +Or Nature failed in me, and left some part +Not proof enough such object to sustain; +Or, from my side subducting, took perhaps +More than enough; at least on her bestowed +Too much of ornament, in outward show +Elaborate, of inward less exact. +For well I understand in the prime end +Of Nature her the inferiour, in the mind +And inward faculties, which most excel; +In outward also her resembling less +His image who made both, and less expressing +The character of that dominion given +O'er other creatures: Yet when I approach +Her loveliness, so absolute she seems +And in herself complete, so well to know +Her own, that what she wills to do or say, +Seems wisest, virtuousest, discreetest, best: +All higher knowledge in her presence falls +Degraded; Wisdom in discourse with her +Loses discountenanced, and like Folly shows; +Authority and Reason on her wait, +As one intended first, not after made +Occasionally; and, to consummate all, +Greatness of mind and Nobleness their seat +Build in her loveliest, and create an awe +About her, as a guard angelick placed. +To whom the Angel with contracted brow. +Accuse not Nature, she hath done her part; +Do thou but thine; and be not diffident +Of Wisdom; she deserts thee not, if thou +Dismiss not her, when most thou needest her nigh, +By attributing overmuch to things +Less excellent, as thou thyself perceivest. +For, what admirest thou, what transports thee so, +An outside? fair, no doubt, and worthy well +Thy cherishing, thy honouring, and thy love; +Not thy subjection: Weigh with her thyself; +Then value: Oft-times nothing profits more +Than self-esteem, grounded on just and right +Well managed; of that skill the more thou knowest, +The more she will acknowledge thee her head, +And to realities yield all her shows: +Made so adorn for thy delight the more, +So awful, that with honour thou mayest love +Thy mate, who sees when thou art seen least wise. +But if the sense of touch, whereby mankind +Is propagated, seem such dear delight +Beyond all other; think the same vouchsafed +To cattle and each beast; which would not be +To them made common and divulged, if aught +Therein enjoyed were worthy to subdue +The soul of man, or passion in him move. +What higher in her society thou findest +Attractive, human, rational, love still; +In loving thou dost well, in passion not, +Wherein true love consists not: Love refines +The thoughts, and heart enlarges; hath his seat +In reason, and is judicious; is the scale +By which to heavenly love thou mayest ascend, +Not sunk in carnal pleasure; for which cause, +Among the beasts no mate for thee was found. +To whom thus, half abashed, Adam replied. +Neither her outside formed so fair, nor aught +In procreation common to all kinds, +(Though higher of the genial bed by far, +And with mysterious reverence I deem,) +So much delights me, as those graceful acts, +Those thousand decencies, that daily flow +From all her words and actions mixed with love +And sweet compliance, which declare unfeigned +Union of mind, or in us both one soul; +Harmony to behold in wedded pair +More grateful than harmonious sound to the ear. +Yet these subject not; I to thee disclose +What inward thence I feel, not therefore foiled, +Who meet with various objects, from the sense +Variously representing; yet, still free, +Approve the best, and follow what I approve. +To love, thou blamest me not; for Love, thou sayest, +Leads up to Heaven, is both the way and guide; +Bear with me then, if lawful what I ask: +Love not the heavenly Spirits, and how their love +Express they? by looks only? or do they mix +Irradiance, virtual or immediate touch? +To whom the Angel, with a smile that glowed +Celestial rosy red, Love's proper hue, +Answered. Let it suffice thee that thou knowest +Us happy, and without love no happiness. +Whatever pure thou in the body enjoyest, +(And pure thou wert created) we enjoy +In eminence; and obstacle find none +Of membrane, joint, or limb, exclusive bars; +Easier than air with air, if Spirits embrace, +Total they mix, union of pure with pure +Desiring, nor restrained conveyance need, +As flesh to mix with flesh, or soul with soul. +But I can now no more; the parting sun +Beyond the Earth's green Cape and verdant Isles +Hesperian sets, my signal to depart. +Be strong, live happy, and love! But, first of all, +Him, whom to love is to obey, and keep +His great command; take heed lest passion sway +Thy judgement to do aught, which else free will +Would not admit: thine, and of all thy sons, +The weal or woe in thee is placed; beware! +I in thy persevering shall rejoice, +And all the Blest: Stand fast;to stand or fall +Free in thine own arbitrement it lies. +Perfect within, no outward aid require; +And all temptation to transgress repel. +So saying, he arose; whom Adam thus +Followed with benediction. Since to part, +Go, heavenly guest, ethereal Messenger, +Sent from whose sovran goodness I adore! +Gentle to me and affable hath been +Thy condescension, and shall be honoured ever +With grateful memory: Thou to mankind +Be good and friendly still, and oft return! +So parted they; the Angel up to Heaven +From the thick shade, and Adam to his bower. + + + +Book IX + + +No more of talk where God or Angel guest +With Man, as with his friend, familiar us'd, +To sit indulgent, and with him partake +Rural repast; permitting him the while +Venial discourse unblam'd. I now must change +Those notes to tragick; foul distrust, and breach +Disloyal on the part of Man, revolt, +And disobedience: on the part of Heaven +Now alienated, distance and distaste, +Anger and just rebuke, and judgement given, +That brought into this world a world of woe, +Sin and her shadow Death, and Misery +Death's harbinger: Sad talk!yet argument +Not less but more heroick than the wrath +Of stern Achilles on his foe pursued +Thrice fugitive about Troy wall; or rage +Of Turnus for Lavinia disespous'd; +Or Neptune's ire, or Juno's, that so long +Perplexed the Greek, and Cytherea's son: + + 00482129 +If answerable style I can obtain +Of my celestial patroness, who deigns +Her nightly visitation unimplor'd, +And dictates to me slumbering; or inspires +Easy my unpremeditated verse: +Since first this subject for heroick song +Pleas'd me long choosing, and beginning late; +Not sedulous by nature to indite +Wars, hitherto the only argument +Heroick deem'd chief mastery to dissect +With long and tedious havock fabled knights +In battles feign'd; the better fortitude +Of patience and heroick martyrdom +Unsung; or to describe races and games, +Or tilting furniture, imblazon'd shields, +Impresses quaint, caparisons and steeds, +Bases and tinsel trappings, gorgeous knights +At joust and tournament; then marshall'd feast +Serv'd up in hall with sewers and seneshals; +The skill of artifice or office mean, +Not that which justly gives heroick name +To person, or to poem. Me, of these +Nor skill'd nor studious, higher argument +Remains; sufficient of itself to raise +That name, unless an age too late, or cold +Climate, or years, damp my intended wing +Depress'd; and much they may, if all be mine, +Not hers, who brings it nightly to my ear. +The sun was sunk, and after him the star +Of Hesperus, whose office is to bring +Twilight upon the earth, short arbiter +"twixt day and night, and now from end to end +Night's hemisphere had veil'd the horizon round: +When satan, who late fled before the threats +Of Gabriel out of Eden, now improv'd +In meditated fraud and malice, bent +On Man's destruction, maugre what might hap +Of heavier on himself, fearless returned +From compassing the earth; cautious of day, +Since Uriel, regent of the sun, descried +His entrance, and foreworned the Cherubim +That kept their watch; thence full of anguish driven, +The space of seven continued nights he rode +With darkness; thrice the equinoctial line +He circled; four times crossed the car of night +From pole to pole, traversing each colure; +On the eighth returned; and, on the coast averse +From entrance or Cherubick watch, by stealth +Found unsuspected way. There was a place, +Now not, though sin, not time, first wrought the change, +Where Tigris, at the foot of Paradise, +Into a gulf shot under ground, till part +Rose up a fountain by the tree of life: +In with the river sunk, and with it rose +Satan, involved in rising mist; then sought +Where to lie hid; sea he had searched, and land, +From Eden over Pontus and the pool +Maeotis, up beyond the river Ob; +Downward as far antarctick; and in length, +West from Orontes to the ocean barred +At Darien ; thence to the land where flows +Ganges and Indus: Thus the orb he roamed +With narrow search; and with inspection deep +Considered every creature, which of all +Most opportune might serve his wiles; and found +The Serpent subtlest beast of all the field. +Him after long debate, irresolute +Of thoughts revolved, his final sentence chose +Fit vessel, fittest imp of fraud, in whom +To enter, and his dark suggestions hide +From sharpest sight: for, in the wily snake +Whatever sleights, none would suspicious mark, +As from his wit and native subtlety +Proceeding; which, in other beasts observed, +Doubt might beget of diabolick power +Active within, beyond the sense of brute. +Thus he resolved, but first from inward grief +His bursting passion into plaints thus poured. +More justly, seat worthier of Gods, as built +With second thoughts, reforming what was old! +O Earth, how like to Heaven, if not preferred +For what God, after better, worse would build? +Terrestrial Heaven, danced round by other Heavens +That shine, yet bear their bright officious lamps, +Light above light, for thee alone, as seems, +In thee concentring all their precious beams +Of sacred influence! As God in Heaven +Is center, yet extends to all; so thou, +Centring, receivest from all those orbs: in thee, +Not in themselves, all their known virtue appears +Productive in herb, plant, and nobler birth +Of creatures animate with gradual life +Of growth, sense, reason, all summed up in Man. +With what delight could I have walked thee round, +If I could joy in aught, sweet interchange +Of hill, and valley, rivers, woods, and plains, +Now land, now sea and shores with forest crowned, +Rocks, dens, and caves! But I in none of these +Find place or refuge; and the more I see +Pleasures about me, so much more I feel +Torment within me, as from the hateful siege +Of contraries: all good to me becomes +Bane, and in Heaven much worse would be my state. +But neither here seek I, no nor in Heaven +To dwell, unless by mastering Heaven's Supreme; +Nor hope to be myself less miserable +By what I seek, but others to make such +As I, though thereby worse to me redound: +For only in destroying I find ease +To my relentless thoughts; and, him destroyed, +Or won to what may work his utter loss, +For whom all this was made, all this will soon +Follow, as to him linked in weal or woe; +In woe then; that destruction wide may range: +To me shall be the glory sole among +The infernal Powers, in one day to have marred +What he, Almighty styled, six nights and days +Continued making; and who knows how long +Before had been contriving? though perhaps +Not longer than since I, in one night, freed +From servitude inglorious well nigh half +The angelick name, and thinner left the throng +Of his adorers: He, to be avenged, +And to repair his numbers thus impaired, +Whether such virtue spent of old now failed +More Angels to create, if they at least +Are his created, or, to spite us more, +Determined to advance into our room +A creature formed of earth, and him endow, +Exalted from so base original, +With heavenly spoils, our spoils: What he decreed, +He effected; Man he made, and for him built +Magnificent this world, and earth his seat, +Him lord pronounced; and, O indignity! +Subjected to his service angel-wings, +And flaming ministers to watch and tend +Their earthly charge: Of these the vigilance +I dread; and, to elude, thus wrapt in mist +Of midnight vapour glide obscure, and pry +In every bush and brake, where hap may find +The serpent sleeping; in whose mazy folds +To hide me, and the dark intent I bring. +O foul descent! that I, who erst contended +With Gods to sit the highest, am now constrained +Into a beast; and, mixed with bestial slime, +This essence to incarnate and imbrute, +That to the highth of Deity aspired! +But what will not ambition and revenge +Descend to? Who aspires, must down as low +As high he soared; obnoxious, first or last, +To basest things. Revenge, at first though sweet, +Bitter ere long, back on itself recoils: +Let it; I reck not, so it light well aimed, +Since higher I fall short, on him who next +Provokes my envy, this new favourite +Of Heaven, this man of clay, son of despite, +Whom, us the more to spite, his Maker raised +From dust: Spite then with spite is best repaid. +So saying, through each thicket dank or dry, +Like a black mist low-creeping, he held on +His midnight-search, where soonest he might find +The serpent; him fast-sleeping soon he found +In labyrinth of many a round self-rolled, +His head the midst, well stored with subtile wiles: +Not yet in horrid shade or dismal den, +Nor nocent yet; but, on the grassy herb, +Fearless unfeared he slept: in at his mouth +The Devil entered; and his brutal sense, +In heart or head, possessing, soon inspired +With act intelligential; but his sleep +Disturbed not, waiting close the approach of morn. +Now, when as sacred light began to dawn +In Eden on the humid flowers, that breathed +Their morning incense, when all things, that breathe, +From the Earth's great altar send up silent praise +To the Creator, and his nostrils fill +With grateful smell, forth came the human pair, +And joined their vocal worship to the quire +Of creatures wanting voice; that done, partake +The season prime for sweetest scents and airs: +Then commune, how that day they best may ply +Their growing work: for much their work out-grew +The hands' dispatch of two gardening so wide, +And Eve first to her husband thus began. +Adam, well may we labour still to dress +This garden, still to tend plant, herb, and flower, +Our pleasant task enjoined; but, till more hands +Aid us, the work under our labour grows, +Luxurious by restraint; what we by day +Lop overgrown, or prune, or prop, or bind, +One night or two with wanton growth derides +Tending to wild. Thou therefore now advise, +Or bear what to my mind first thoughts present: +Let us divide our labours; thou, where choice +Leads thee, or where most needs, whether to wind +The woodbine round this arbour, or direct +The clasping ivy where to climb; while I, +In yonder spring of roses intermixed +With myrtle, find what to redress till noon: +For, while so near each other thus all day +Our task we choose, what wonder if so near +Looks intervene and smiles, or object new +Casual discourse draw on; which intermits +Our day's work, brought to little, though begun +Early, and the hour of supper comes unearned? +To whom mild answer Adam thus returned. +Sole Eve, associate sole, to me beyond +Compare above all living creatures dear! +Well hast thou motioned, well thy thoughts employed, +How we might best fulfil the work which here +God hath assigned us; nor of me shalt pass +Unpraised: for nothing lovelier can be found +In woman, than to study houshold good, +And good works in her husband to promote. +Yet not so strictly hath our Lord imposed +Labour, as to debar us when we need +Refreshment, whether food, or talk between, +Food of the mind, or this sweet intercourse +Of looks and smiles; for smiles from reason flow, +To brute denied, and are of love the food; +Love, not the lowest end of human life. +For not to irksome toil, but to delight, +He made us, and delight to reason joined. +These paths and bowers doubt not but our joint hands +Will keep from wilderness with ease, as wide +As we need walk, till younger hands ere long +Assist us; But, if much converse perhaps +Thee satiate, to short absence I could yield: +For solitude sometimes is best society, +And short retirement urges sweet return. +But other doubt possesses me, lest harm +Befall thee severed from me; for thou knowest +What hath been warned us, what malicious foe +Envying our happiness, and of his own +Despairing, seeks to work us woe and shame +By sly assault; and somewhere nigh at hand +Watches, no doubt, with greedy hope to find +His wish and best advantage, us asunder; +Hopeless to circumvent us joined, where each +To other speedy aid might lend at need: +Whether his first design be to withdraw +Our fealty from God, or to disturb +Conjugal love, than which perhaps no bliss +Enjoyed by us excites his envy more; +Or this, or worse, leave not the faithful side +That gave thee being, still shades thee, and protects. +The wife, where danger or dishonour lurks, +Safest and seemliest by her husband stays, +Who guards her, or with her the worst endures. +To whom the virgin majesty of Eve, +As one who loves, and some unkindness meets, +With sweet austere composure thus replied. +Offspring of Heaven and Earth, and all Earth's Lord! +That such an enemy we have, who seeks +Our ruin, both by thee informed I learn, +And from the parting Angel over-heard, +As in a shady nook I stood behind, +Just then returned at shut of evening flowers. +But, that thou shouldst my firmness therefore doubt +To God or thee, because we have a foe +May tempt it, I expected not to hear. +His violence thou fearest not, being such +As we, not capable of death or pain, +Can either not receive, or can repel. +His fraud is then thy fear; which plain infers +Thy equal fear, that my firm faith and love +Can by his fraud be shaken or seduced; +Thoughts, which how found they harbour in thy breast, +Adam, mis-thought of her to thee so dear? +To whom with healing words Adam replied. +Daughter of God and Man, immortal Eve! +For such thou art; from sin and blame entire: +Not diffident of thee do I dissuade +Thy absence from my sight, but to avoid +The attempt itself, intended by our foe. +For he who tempts, though in vain, at least asperses +The tempted with dishonour foul; supposed +Not incorruptible of faith, not proof +Against temptation: Thou thyself with scorn +And anger wouldst resent the offered wrong, +Though ineffectual found: misdeem not then, +If such affront I labour to avert +From thee alone, which on us both at once +The enemy, though bold, will hardly dare; +Or daring, first on me the assault shall light. +Nor thou his malice and false guile contemn; +Subtle he needs must be, who could seduce +Angels; nor think superfluous other's aid. +I, from the influence of thy looks, receive +Access in every virtue; in thy sight +More wise, more watchful, stronger, if need were +Of outward strength; while shame, thou looking on, +Shame to be overcome or over-reached, +Would utmost vigour raise, and raised unite. +Why shouldst not thou like sense within thee feel +When I am present, and thy trial choose +With me, best witness of thy virtue tried? +So spake domestick Adam in his care +And matrimonial love; but Eve, who thought +Less attributed to her faith sincere, +Thus her reply with accent sweet renewed. +If this be our condition, thus to dwell +In narrow circuit straitened by a foe, +Subtle or violent, we not endued +Single with like defence, wherever met; +How are we happy, still in fear of harm? +But harm precedes not sin: only our foe, +Tempting, affronts us with his foul esteem +Of our integrity: his foul esteem +Sticks no dishonour on our front, but turns +Foul on himself; then wherefore shunned or feared +By us? who rather double honour gain +From his surmise proved false; find peace within, +Favour from Heaven, our witness, from the event. +And what is faith, love, virtue, unassayed +Alone, without exteriour help sustained? +Let us not then suspect our happy state +Left so imperfect by the Maker wise, +As not secure to single or combined. +Frail is our happiness, if this be so, +And Eden were no Eden, thus exposed. +To whom thus Adam fervently replied. +O Woman, best are all things as the will +Of God ordained them: His creating hand +Nothing imperfect or deficient left +Of all that he created, much less Man, +Or aught that might his happy state secure, +Secure from outward force; within himself +The danger lies, yet lies within his power: +Against his will he can receive no harm. +But God left free the will; for what obeys +Reason, is free; and Reason he made right, +But bid her well be ware, and still erect; +Lest, by some fair-appearing good surprised, +She dictate false; and mis-inform the will +To do what God expressly hath forbid. +Not then mistrust, but tender love, enjoins, +That I should mind thee oft; and mind thou me. +Firm we subsist, yet possible to swerve; +Since Reason not impossibly may meet +Some specious object by the foe suborned, +And fall into deception unaware, +Not keeping strictest watch, as she was warned. +Seek not temptation then, which to avoid +Were better, and most likely if from me +Thou sever not: Trial will come unsought. +Wouldst thou approve thy constancy, approve +First thy obedience; the other who can know, +Not seeing thee attempted, who attest? +But, if thou think, trial unsought may find +Us both securer than thus warned thou seemest, +Go; for thy stay, not free, absents thee more; +Go in thy native innocence, rely +On what thou hast of virtue; summon all! +For God towards thee hath done his part, do thine. +So spake the patriarch of mankind; but Eve +Persisted; yet submiss, though last, replied. +With thy permission then, and thus forewarned +Chiefly by what thy own last reasoning words +Touched only; that our trial, when least sought, +May find us both perhaps far less prepared, +The willinger I go, nor much expect +A foe so proud will first the weaker seek; +So bent, the more shall shame him his repulse. +Thus saying, from her husband's hand her hand +Soft she withdrew; and, like a Wood-Nymph light, +Oread or Dryad, or of Delia's train, +Betook her to the groves; but Delia's self +In gait surpassed, and Goddess-like deport, +Though not as she with bow and quiver armed, +But with such gardening tools as Art yet rude, +Guiltless of fire, had formed, or Angels brought. +To Pales, or Pomona, thus adorned, +Likest she seemed, Pomona when she fled +Vertumnus, or to Ceres in her prime, +Yet virgin of Proserpina from Jove. +Her long with ardent look his eye pursued +Delighted, but desiring more her stay. +Oft he to her his charge of quick return +Repeated; she to him as oft engaged +To be returned by noon amid the bower, +And all things in best order to invite +Noontide repast, or afternoon's repose. +O much deceived, much failing, hapless Eve, +Of thy presumed return! event perverse! +Thou never from that hour in Paradise +Foundst either sweet repast, or sound repose; +Such ambush, hid among sweet flowers and shades, +Waited with hellish rancour imminent +To intercept thy way, or send thee back +Despoiled of innocence, of faith, of bliss! +For now, and since first break of dawn, the Fiend, +Mere serpent in appearance, forth was come; +And on his quest, where likeliest he might find +The only two of mankind, but in them +The whole included race, his purposed prey. +In bower and field he sought, where any tuft +Of grove or garden-plot more pleasant lay, +Their tendance, or plantation for delight; +By fountain or by shady rivulet +He sought them both, but wished his hap might find +Eve separate; he wished, but not with hope +Of what so seldom chanced; when to his wish, +Beyond his hope, Eve separate he spies, +Veiled in a cloud of fragrance, where she stood, +Half spied, so thick the roses blushing round +About her glowed, oft stooping to support +Each flower of slender stalk, whose head, though gay +Carnation, purple, azure, or specked with gold, +Hung drooping unsustained; them she upstays +Gently with myrtle band, mindless the while +Herself, though fairest unsupported flower, +From her best prop so far, and storm so nigh. +Nearer he drew, and many a walk traversed +Of stateliest covert, cedar, pine, or palm; +Then voluble and bold, now hid, now seen, +Among thick-woven arborets, and flowers +Imbordered on each bank, the hand of Eve: +Spot more delicious than those gardens feigned +Or of revived Adonis, or renowned +Alcinous, host of old Laertes' son; +Or that, not mystick, where the sapient king +Held dalliance with his fair Egyptian spouse. +Much he the place admired, the person more. +As one who long in populous city pent, +Where houses thick and sewers annoy the air, +Forth issuing on a summer's morn, to breathe +Among the pleasant villages and farms +Adjoined, from each thing met conceives delight; +The smell of grain, or tedded grass, or kine, +Or dairy, each rural sight, each rural sound; +If chance, with nymph-like step, fair virgin pass, +What pleasing seemed, for her now pleases more; +She most, and in her look sums all delight: +Such pleasure took the Serpent to behold +This flowery plat, the sweet recess of Eve +Thus early, thus alone: Her heavenly form +Angelick, but more soft, and feminine, +Her graceful innocence, her every air +Of gesture, or least action, overawed +His malice, and with rapine sweet bereaved +His fierceness of the fierce intent it brought: +That space the Evil-one abstracted stood +From his own evil, and for the time remained +Stupidly good; of enmity disarmed, +Of guile, of hate, of envy, of revenge: +But the hot Hell that always in him burns, +Though in mid Heaven, soon ended his delight, +And tortures him now more, the more he sees +Of pleasure, not for him ordained: then soon +Fierce hate he recollects, and all his thoughts +Of mischief, gratulating, thus excites. +Thoughts, whither have ye led me! with what sweet +Compulsion thus transported, to forget +What hither brought us! hate, not love;nor hope +Of Paradise for Hell, hope here to taste +Of pleasure; but all pleasure to destroy, +Save what is in destroying; other joy +To me is lost. Then, let me not let pass +Occasion which now smiles; behold alone +The woman, opportune to all attempts, +Her husband, for I view far round, not nigh, +Whose higher intellectual more I shun, +And strength, of courage haughty, and of limb +Heroick built, though of terrestrial mould; +Foe not informidable! exempt from wound, +I not; so much hath Hell debased, and pain +Enfeebled me, to what I was in Heaven. +She fair, divinely fair, fit love for Gods! +Not terrible, though terrour be in love +And beauty, not approached by stronger hate, +Hate stronger, under show of love well feigned; +The way which to her ruin now I tend. +So spake the enemy of mankind, enclosed +In serpent, inmate bad! and toward Eve +Addressed his way: not with indented wave, +Prone on the ground, as since; but on his rear, +Circular base of rising folds, that towered +Fold above fold, a surging maze! his head +Crested aloft, and carbuncle his eyes; +With burnished neck of verdant gold, erect +Amidst his circling spires, that on the grass +Floated redundant: pleasing was his shape +And lovely; never since of serpent-kind +Lovelier, not those that in Illyria changed, +Hermione and Cadmus, or the god +In Epidaurus; nor to which transformed +Ammonian Jove, or Capitoline, was seen; +He with Olympias; this with her who bore +Scipio, the highth of Rome. With tract oblique +At first, as one who sought access, but feared +To interrupt, side-long he works his way. +As when a ship, by skilful steersmen wrought +Nigh river's mouth or foreland, where the wind +Veers oft, as oft so steers, and shifts her sail: +So varied he, and of his tortuous train +Curled many a wanton wreath in sight of Eve, +To lure her eye; she, busied, heard the sound +Of rusling leaves, but minded not, as used +To such disport before her through the field, +From every beast; more duteous at her call, +Than at Circean call the herd disguised. +He, bolder now, uncalled before her stood, +But as in gaze admiring: oft he bowed +His turret crest, and sleek enamelled neck, +Fawning; and licked the ground whereon she trod. +His gentle dumb expression turned at length +The eye of Eve to mark his play; he, glad +Of her attention gained, with serpent-tongue +Organick, or impulse of vocal air, +His fraudulent temptation thus began. +Wonder not, sovran Mistress, if perhaps +Thou canst, who art sole wonder! much less arm +Thy looks, the Heaven of mildness, with disdain, +Displeased that I approach thee thus, and gaze +Insatiate; I thus single;nor have feared +Thy awful brow, more awful thus retired. +Fairest resemblance of thy Maker fair, +Thee all things living gaze on, all things thine +By gift, and thy celestial beauty adore +With ravishment beheld! there best beheld, +Where universally admired; but here +In this enclosure wild, these beasts among, +Beholders rude, and shallow to discern +Half what in thee is fair, one man except, +Who sees thee? and what is one? who should be seen +A Goddess among Gods, adored and served +By Angels numberless, thy daily train. +So glozed the Tempter, and his proem tuned: +Into the heart of Eve his words made way, +Though at the voice much marvelling; at length, +Not unamazed, she thus in answer spake. +What may this mean? language of man pronounced +By tongue of brute, and human sense expressed? +The first, at least, of these I thought denied +To beasts; whom God, on their creation-day, +Created mute to all articulate sound: +The latter I demur; for in their looks +Much reason, and in their actions, oft appears. +Thee, Serpent, subtlest beast of all the field +I knew, but not with human voice endued; +Redouble then this miracle, and say, +How camest thou speakable of mute, and how +To me so friendly grown above the rest +Of brutal kind, that daily are in sight? +Say, for such wonder claims attention due. +To whom the guileful Tempter thus replied. +Empress of this fair world, resplendent Eve! +Easy to me it is to tell thee all +What thou commandest; and right thou shouldst be obeyed: +I was at first as other beasts that graze +The trodden herb, of abject thoughts and low, +As was my food; nor aught but food discerned +Or sex, and apprehended nothing high: +Till, on a day roving the field, I chanced +A goodly tree far distant to behold +Loaden with fruit of fairest colours mixed, +Ruddy and gold: I nearer drew to gaze; +When from the boughs a savoury odour blown, +Grateful to appetite, more pleased my sense +Than smell of sweetest fennel, or the teats +Of ewe or goat dropping with milk at even, +Unsucked of lamb or kid, that tend their play. +To satisfy the sharp desire I had +Of tasting those fair apples, I resolved +Not to defer; hunger and thirst at once, +Powerful persuaders, quickened at the scent +Of that alluring fruit, urged me so keen. +About the mossy trunk I wound me soon; +For, high from ground, the branches would require +Thy utmost reach or Adam's: Round the tree +All other beasts that saw, with like desire +Longing and envying stood, but could not reach. +Amid the tree now got, where plenty hung +Tempting so nigh, to pluck and eat my fill +I spared not; for, such pleasure till that hour, +At feed or fountain, never had I found. +Sated at length, ere long I might perceive +Strange alteration in me, to degree +Of reason in my inward powers; and speech +Wanted not long; though to this shape retained. +Thenceforth to speculations high or deep +I turned my thoughts, and with capacious mind +Considered all things visible in Heaven, +Or Earth, or Middle; all things fair and good: +But all that fair and good in thy divine +Semblance, and in thy beauty's heavenly ray, +United I beheld; no fair to thine +Equivalent or second! which compelled +Me thus, though importune perhaps, to come +And gaze, and worship thee of right declared +Sovran of creatures, universal Dame! +So talked the spirited sly Snake; and Eve, +Yet more amazed, unwary thus replied. +Serpent, thy overpraising leaves in doubt +The virtue of that fruit, in thee first proved: +But say, where grows the tree? from hence how far? +For many are the trees of God that grow +In Paradise, and various, yet unknown +To us; in such abundance lies our choice, +As leaves a greater store of fruit untouched, +Still hanging incorruptible, till men +Grow up to their provision, and more hands +Help to disburden Nature of her birth. +To whom the wily Adder, blithe and glad. +Empress, the way is ready, and not long; +Beyond a row of myrtles, on a flat, +Fast by a fountain, one small thicket past +Of blowing myrrh and balm: if thou accept +My conduct, I can bring thee thither soon +Lead then, said Eve. He, leading, swiftly rolled +In tangles, and made intricate seem straight, +To mischief swift. Hope elevates, and joy +Brightens his crest; as when a wandering fire, +Compact of unctuous vapour, which the night +Condenses, and the cold environs round, +Kindled through agitation to a flame, +Which oft, they say, some evil Spirit attends, +Hovering and blazing with delusive light, +Misleads the amazed night-wanderer from his way +To bogs and mires, and oft through pond or pool; +There swallowed up and lost, from succour far. +So glistered the dire Snake, and into fraud +Led Eve, our credulous mother, to the tree +Of prohibition, root of all our woe; +Which when she saw, thus to her guide she spake. +Serpent, we might have spared our coming hither, +Fruitless to me, though fruit be here to excess, +The credit of whose virtue rest with thee; +Wonderous indeed, if cause of such effects. +But of this tree we may not taste nor touch; +God so commanded, and left that command +Sole daughter of his voice; the rest, we live +Law to ourselves; our reason is our law. +To whom the Tempter guilefully replied. +Indeed! hath God then said that of the fruit +Of all these garden-trees ye shall not eat, +Yet Lords declared of all in earth or air$? +To whom thus Eve, yet sinless. Of the fruit +Of each tree in the garden we may eat; +But of the fruit of this fair tree amidst +The garden, God hath said, Ye shall not eat +Thereof, nor shall ye touch it, lest ye die. +She scarce had said, though brief, when now more bold +The Tempter, but with show of zeal and love +To Man, and indignation at his wrong, +New part puts on; and, as to passion moved, +Fluctuates disturbed, yet comely and in act +Raised, as of some great matter to begin. +As when of old some orator renowned, +In Athens or free Rome, where eloquence +Flourished, since mute! to some great cause addressed, +Stood in himself collected; while each part, +Motion, each act, won audience ere the tongue; +Sometimes in highth began, as no delay +Of preface brooking, through his zeal of right: +So standing, moving, or to highth up grown, +The Tempter, all impassioned, thus began. +O sacred, wise, and wisdom-giving Plant, +Mother of science! now I feel thy power +Within me clear; not only to discern +Things in their causes, but to trace the ways +Of highest agents, deemed however wise. +Queen of this universe! do not believe +Those rigid threats of death: ye shall not die: +How should you? by the fruit? it gives you life +To knowledge; by the threatener? look on me, +Me, who have touched and tasted; yet both live, +And life more perfect have attained than Fate +Meant me, by venturing higher than my lot. +Shall that be shut to Man, which to the Beast +Is open? or will God incense his ire +For such a petty trespass? and not praise +Rather your dauntless virtue, whom the pain +Of death denounced, whatever thing death be, +Deterred not from achieving what might lead +To happier life, knowledge of good and evil; +Of good, how just? of evil, if what is evil +Be real, why not known, since easier shunned? +God therefore cannot hurt ye, and be just; +Not just, not God; not feared then, nor obeyed: +Your fear itself of death removes the fear. +Why then was this forbid? Why, but to awe; +Why, but to keep ye low and ignorant, +His worshippers? He knows that in the day +Ye eat thereof, your eyes that seem so clear, +Yet are but dim, shall perfectly be then +Opened and cleared, and ye shall be as Gods, +Knowing both good and evil, as they know. +That ye shall be as Gods, since I as Man, +Internal Man, is but proportion meet; +I, of brute, human; ye, of human, Gods. +So ye shall die perhaps, by putting off +Human, to put on Gods; death to be wished, +Though threatened, which no worse than this can bring. +And what are Gods, that Man may not become +As they, participating God-like food? +The Gods are first, and that advantage use +On our belief, that all from them proceeds: +I question it; for this fair earth I see, +Warmed by the sun, producing every kind; +Them, nothing: if they all things, who enclosed +Knowledge of good and evil in this tree, +That whoso eats thereof, forthwith attains +Wisdom without their leave? and wherein lies +The offence, that Man should thus attain to know? +What can your knowledge hurt him, or this tree +Impart against his will, if all be his? +Or is it envy? and can envy dwell +In heavenly breasts? These, these, and many more +Causes import your need of this fair fruit. +Goddess humane, reach then, and freely taste! +He ended; and his words, replete with guile, +Into her heart too easy entrance won: +Fixed on the fruit she gazed, which to behold +Might tempt alone; and in her ears the sound +Yet rung of his persuasive words, impregned +With reason, to her seeming, and with truth: +Mean while the hour of noon drew on, and waked +An eager appetite, raised by the smell +So savoury of that fruit, which with desire, +Inclinable now grown to touch or taste, +Solicited her longing eye; yet first +Pausing a while, thus to herself she mused. +Great are thy virtues, doubtless, best of fruits, +Though kept from man, and worthy to be admired; +Whose taste, too long forborn, at first assay +Gave elocution to the mute, and taught +The tongue not made for speech to speak thy praise: +Thy praise he also, who forbids thy use, +Conceals not from us, naming thee the tree +Of knowledge, knowledge both of good and evil; +Forbids us then to taste! but his forbidding +Commends thee more, while it infers the good +By thee communicated, and our want: +For good unknown sure is not had; or, had +And yet unknown, is as not had at all. +In plain then, what forbids he but to know, +Forbids us good, forbids us to be wise? +Such prohibitions bind not. But, if death +Bind us with after-bands, what profits then +Our inward freedom? In the day we eat +Of this fair fruit, our doom is, we shall die! +How dies the Serpent? he hath eaten and lives, +And knows, and speaks, and reasons, and discerns, +Irrational till then. For us alone +Was death invented? or to us denied +This intellectual food, for beasts reserved? +For beasts it seems: yet that one beast which first +Hath tasted envies not, but brings with joy +The good befallen him, author unsuspect, +Friendly to man, far from deceit or guile. +What fear I then? rather, what know to fear +Under this ignorance of good and evil, +Of God or death, of law or penalty? +Here grows the cure of all, this fruit divine, +Fair to the eye, inviting to the taste, +Of virtue to make wise: What hinders then +To reach, and feed at once both body and mind? +So saying, her rash hand in evil hour +Forth reaching to the fruit, she plucked, she eat! +Earth felt the wound; and Nature from her seat, +Sighing through all her works, gave signs of woe, +That all was lost. Back to the thicket slunk +The guilty Serpent; and well might;for Eve, +Intent now wholly on her taste, nought else +Regarded; such delight till then, as seemed, +In fruit she never tasted, whether true +Or fancied so, through expectation high +Of knowledge; not was Godhead from her thought. +Greedily she ingorged without restraint, +And knew not eating death: Satiate at length, +And hightened as with wine, jocund and boon, +Thus to herself she pleasingly began. +O sovran, virtuous, precious of all trees +In Paradise! of operation blest +To sapience, hitherto obscured, infamed. +And thy fair fruit let hang, as to no end +Created; but henceforth my early care, +Not without song, each morning, and due praise, +Shall tend thee, and the fertile burden ease +Of thy full branches offered free to all; +Till, dieted by thee, I grow mature +In knowledge, as the Gods, who all things know; +Though others envy what they cannot give: +For, had the gift been theirs, it had not here +Thus grown. Experience, next, to thee I owe, +Best guide; not following thee, I had remained +In ignorance; thou openest wisdom's way, +And givest access, though secret she retire. +And I perhaps am secret: Heaven is high, +High, and remote to see from thence distinct +Each thing on Earth; and other care perhaps +May have diverted from continual watch +Our great Forbidder, safe with all his spies +About him. But to Adam in what sort +Shall I appear? shall I to him make known +As yet my change, and give him to partake +Full happiness with me, or rather not, +But keeps the odds of knowledge in my power +Without copartner? so to add what wants +In female sex, the more to draw his love, +And render me more equal; and perhaps, +A thing not undesirable, sometime +Superiour; for, inferiour, who is free +This may be well: But what if God have seen, +And death ensue? then I shall be no more! +And Adam, wedded to another Eve, +Shall live with her enjoying, I extinct; +A death to think! Confirmed then I resolve, +Adam shall share with me in bliss or woe: +So dear I love him, that with him all deaths +I could endure, without him live no life. +So saying, from the tree her step she turned; +But first low reverence done, as to the Power +That dwelt within, whose presence had infused +Into the plant sciential sap, derived +From nectar, drink of Gods. Adam the while, +Waiting desirous her return, had wove +Of choicest flowers a garland, to adorn +Her tresses, and her rural labours crown; +As reapers oft are wont their harvest-queen. +Great joy he promised to his thoughts, and new +Solace in her return, so long delayed: +Yet oft his heart, divine of something ill, +Misgave him; he the faltering measure felt; +And forth to meet her went, the way she took +That morn when first they parted: by the tree +Of knowledge he must pass; there he her met, +Scarce from the tree returning; in her hand +A bough of fairest fruit, that downy smiled, +New gathered, and ambrosial smell diffused. +To him she hasted; in her face excuse +Came prologue, and apology too prompt; +Which, with bland words at will, she thus addressed. +Hast thou not wondered, Adam, at my stay? +Thee I have missed, and thought it long, deprived +Thy presence; agony of love till now +Not felt, nor shall be twice; for never more +Mean I to try, what rash untried I sought, +The pain of absence from thy sight. But strange +Hath been the cause, and wonderful to hear: +This tree is not, as we are told, a tree +Of danger tasted, nor to evil unknown +Opening the way, but of divine effect +To open eyes, and make them Gods who taste; +And hath been tasted such: The serpent wise, +Or not restrained as we, or not obeying, +Hath eaten of the fruit; and is become, +Not dead, as we are threatened, but thenceforth +Endued with human voice and human sense, +Reasoning to admiration; and with me +Persuasively hath so prevailed, that I +Have also tasted, and have also found +The effects to correspond; opener mine eyes, +Dim erst, dilated spirits, ampler heart, +And growing up to Godhead; which for thee +Chiefly I sought, without thee can despise. +For bliss, as thou hast part, to me is bliss; +Tedious, unshared with thee, and odious soon. +Thou therefore also taste, that equal lot +May join us, equal joy, as equal love; +Lest, thou not tasting, different degree +Disjoin us, and I then too late renounce +Deity for thee, when Fate will not permit. +Thus Eve with countenance blithe her story told; +But in her cheek distemper flushing glowed. +On the other side Adam, soon as he heard +The fatal trespass done by Eve, amazed, +Astonied stood and blank, while horrour chill +Ran through his veins, and all his joints relaxed; +From his slack hand the garland wreathed for Eve +Down dropt, and all the faded roses shed: +Speechless he stood and pale, till thus at length +First to himself he inward silence broke. +O fairest of Creation, last and best +Of all God's works, Creature in whom excelled +Whatever can to sight or thought be formed, +Holy, divine, good, amiable, or sweet! +How art thou lost! how on a sudden lost, +Defaced, deflowered, and now to death devote! +Rather, how hast thou yielded to transgress +The strict forbiddance, how to violate +The sacred fruit forbidden! Some cursed fraud +Of enemy hath beguiled thee, yet unknown, +And me with thee hath ruined; for with thee +Certain my resolution is to die: +How can I live without thee! how forego +Thy sweet converse, and love so dearly joined, +To live again in these wild woods forlorn! +Should God create another Eve, and I +Another rib afford, yet loss of thee +Would never from my heart: no, no!I feel +The link of Nature draw me: flesh of flesh, +Bone of my bone thou art, and from thy state +Mine never shall be parted, bliss or woe. +So having said, as one from sad dismay +Recomforted, and after thoughts disturbed +Submitting to what seemed remediless, +Thus in calm mood his words to Eve he turned. +Bold deed thou hast presumed, adventurous Eve, +And peril great provoked, who thus hast dared, +Had it been only coveting to eye +That sacred fruit, sacred to abstinence, +Much more to taste it under ban to touch. +But past who can recall, or done undo? +Not God Omnipotent, nor Fate; yet so +Perhaps thou shalt not die, perhaps the fact +Is not so heinous now, foretasted fruit, +Profaned first by the serpent, by him first +Made common, and unhallowed, ere our taste; +Nor yet on him found deadly; yet he lives; +Lives, as thou saidst, and gains to live, as Man, +Higher degree of life; inducement strong +To us, as likely tasting to attain +Proportional ascent; which cannot be +But to be Gods, or Angels, demi-Gods. +Nor can I think that God, Creator wise, +Though threatening, will in earnest so destroy +Us his prime creatures, dignified so high, +Set over all his works; which in our fall, +For us created, needs with us must fail, +Dependant made; so God shall uncreate, +Be frustrate, do, undo, and labour lose; +Not well conceived of God, who, though his power +Creation could repeat, yet would be loth +Us to abolish, lest the Adversary +Triumph, and say; "Fickle their state whom God +"Most favours; who can please him long? Me first +"He ruined, now Mankind; whom will he next?" +Matter of scorn, not to be given the Foe. +However I with thee have fixed my lot, +Certain to undergo like doom: If death +Consort with thee, death is to me as life; +So forcible within my heart I feel +The bond of Nature draw me to my own; +My own in thee, for what thou art is mine; +Our state cannot be severed; we are one, +One flesh; to lose thee were to lose myself. +So Adam; and thus Eve to him replied. +O glorious trial of exceeding love, +Illustrious evidence, example high! +Engaging me to emulate; but, short +Of thy perfection, how shall I attain, +Adam, from whose dear side I boast me sprung, +And gladly of our union hear thee speak, +One heart, one soul in both; whereof good proof +This day affords, declaring thee resolved, +Rather than death, or aught than death more dread, +Shall separate us, linked in love so dear, +To undergo with me one guilt, one crime, +If any be, of tasting this fair fruit; +Whose virtue for of good still good proceeds, +Direct, or by occasion, hath presented +This happy trial of thy love, which else +So eminently never had been known? +Were it I thought death menaced would ensue +This my attempt, I would sustain alone +The worst, and not persuade thee, rather die +Deserted, than oblige thee with a fact +Pernicious to thy peace; chiefly assured +Remarkably so late of thy so true, +So faithful, love unequalled: but I feel +Far otherwise the event; not death, but life +Augmented, opened eyes, new hopes, new joys, +Taste so divine, that what of sweet before +Hath touched my sense, flat seems to this, and harsh. +On my experience, Adam, freely taste, +And fear of death deliver to the winds. +So saying, she embraced him, and for joy +Tenderly wept; much won, that he his love +Had so ennobled, as of choice to incur +Divine displeasure for her sake, or death. +In recompence for such compliance bad +Such recompence best merits from the bough +She gave him of that fair enticing fruit +With liberal hand: he scrupled not to eat, +Against his better knowledge; not deceived, +But fondly overcome with female charm. +Earth trembled from her entrails, as again +In pangs; and Nature gave a second groan; +Sky loured; and, muttering thunder, some sad drops +Wept at completing of the mortal sin +Original: while Adam took no thought, +Eating his fill; nor Eve to iterate +Her former trespass feared, the more to sooth +Him with her loved society; that now, +As with new wine intoxicated both, +They swim in mirth, and fancy that they feel +Divinity within them breeding wings, +Wherewith to scorn the earth: But that false fruit +Far other operation first displayed, +Carnal desire inflaming; he on Eve +Began to cast lascivious eyes; she him +As wantonly repaid; in lust they burn: +Till Adam thus 'gan Eve to dalliance move. +Eve, now I see thou art exact of taste, +And elegant, of sapience no small part; +Since to each meaning savour we apply, +And palate call judicious; I the praise +Yield thee, so well this day thou hast purveyed. +Much pleasure we have lost, while we abstained +From this delightful fruit, nor known till now +True relish, tasting; if such pleasure be +In things to us forbidden, it might be wished, +For this one tree had been forbidden ten. +But come, so well refreshed, now let us play, +As meet is, after such delicious fare; +For never did thy beauty, since the day +I saw thee first and wedded thee, adorned +With all perfections, so inflame my sense +With ardour to enjoy thee, fairer now +Than ever; bounty of this virtuous tree! +So said he, and forbore not glance or toy +Of amorous intent; well understood +Of Eve, whose eye darted contagious fire. +Her hand he seised; and to a shady bank, +Thick over-head with verdant roof imbowered, +He led her nothing loth; flowers were the couch, +Pansies, and violets, and asphodel, +And hyacinth; Earth's freshest softest lap. +There they their fill of love and love's disport +Took largely, of their mutual guilt the seal, +The solace of their sin; till dewy sleep +Oppressed them, wearied with their amorous play, +Soon as the force of that fallacious fruit, +That with exhilarating vapour bland +About their spirits had played, and inmost powers +Made err, was now exhaled; and grosser sleep, +Bred of unkindly fumes, with conscious dreams +Incumbered, now had left them; up they rose +As from unrest; and, each the other viewing, +Soon found their eyes how opened, and their minds +How darkened; innocence, that as a veil +Had shadowed them from knowing ill, was gone; +Just confidence, and native righteousness, +And honour, from about them, naked left +To guilty Shame; he covered, but his robe +Uncovered more. So rose the Danite strong, +Herculean Samson, from the harlot-lap +Of Philistean Dalilah, and waked +Shorn of his strength. They destitute and bare +Of all their virtue: Silent, and in face +Confounded, long they sat, as strucken mute: +Till Adam, though not less than Eve abashed, +At length gave utterance to these words constrained. +O Eve, in evil hour thou didst give ear +To that false worm, of whomsoever taught +To counterfeit Man's voice; true in our fall, +False in our promised rising; since our eyes +Opened we find indeed, and find we know +Both good and evil; good lost, and evil got; +Bad fruit of knowledge, if this be to know; +Which leaves us naked thus, of honour void, +Of innocence, of faith, of purity, +Our wonted ornaments now soiled and stained, +And in our faces evident the signs +Of foul concupiscence; whence evil store; +Even shame, the last of evils; of the first +Be sure then.--How shall I behold the face +Henceforth of God or Angel, erst with joy +And rapture so oft beheld? Those heavenly shapes +Will dazzle now this earthly with their blaze +Insufferably bright. O! might I here +In solitude live savage; in some glade +Obscured, where highest woods, impenetrable +To star or sun-light, spread their umbrage broad +And brown as evening: Cover me, ye Pines! +Ye Cedars, with innumerable boughs +Hide me, where I may never see them more!-- +But let us now, as in bad plight, devise +What best may for the present serve to hide +The parts of each from other, that seem most +To shame obnoxious, and unseemliest seen; +Some tree, whose broad smooth leaves together sewed, +And girded on our loins, may cover round +Those middle parts; that this new comer, Shame, +There sit not, and reproach us as unclean. +So counselled he, and both together went +Into the thickest wood; there soon they chose +The fig-tree; not that kind for fruit renowned, +But such as at this day, to Indians known, +In Malabar or Decan spreads her arms +Branching so broad and long, that in the ground +The bended twigs take root, and daughters grow +About the mother tree, a pillared shade +High over-arched, and echoing walks between: +There oft the Indian herdsman, shunning heat, +Shelters in cool, and tends his pasturing herds +At loop-holes cut through thickest shade: Those leaves +They gathered, broad as Amazonian targe; +And, with what skill they had, together sewed, +To gird their waist; vain covering, if to hide +Their guilt and dreaded shame! O, how unlike +To that first naked glory! Such of late +Columbus found the American, so girt +With feathered cincture; naked else, and wild +Among the trees on isles and woody shores. +Thus fenced, and, as they thought, their shame in part +Covered, but not at rest or ease of mind, +They sat them down to weep; nor only tears +Rained at their eyes, but high winds worse within +Began to rise, high passions, anger, hate, +Mistrust, suspicion, discord; and shook sore +Their inward state of mind, calm region once +And full of peace, now tost and turbulent: +For Understanding ruled not, and the Will +Heard not her lore; both in subjection now +To sensual Appetite, who from beneath +Usurping over sovran Reason claimed +Superiour sway: From thus distempered breast, +Adam, estranged in look and altered style, +Speech intermitted thus to Eve renewed. +Would thou hadst hearkened to my words, and staid +With me, as I besought thee, when that strange +Desire of wandering, this unhappy morn, +I know not whence possessed thee; we had then +Remained still happy; not, as now, despoiled +Of all our good; shamed, naked, miserable! +Let none henceforth seek needless cause to approve +The faith they owe; when earnestly they seek +Such proof, conclude, they then begin to fail. +To whom, soon moved with touch of blame, thus Eve. +What words have passed thy lips, Adam severe! +Imputest thou that to my default, or will +Of wandering, as thou callest it, which who knows +But might as ill have happened thou being by, +Or to thyself perhaps? Hadst thou been there, +Or here the attempt, thou couldst not have discerned +Fraud in the Serpent, speaking as he spake; +No ground of enmity between us known, +Why he should mean me ill, or seek to harm. +Was I to have never parted from thy side? +As good have grown there still a lifeless rib. +Being as I am, why didst not thou, the head, +Command me absolutely not to go, +Going into such danger, as thou saidst? +Too facile then, thou didst not much gainsay; +Nay, didst permit, approve, and fair dismiss. +Hadst thou been firm and fixed in thy dissent, +Neither had I transgressed, nor thou with me. +To whom, then first incensed, Adam replied. +Is this the love, is this the recompence +Of mine to thee, ingrateful Eve! expressed +Immutable, when thou wert lost, not I; +Who might have lived, and joyed immortal bliss, +Yet willingly chose rather death with thee? +And am I now upbraided as the cause +Of thy transgressing? Not enough severe, +It seems, in thy restraint: What could I more +I warned thee, I admonished thee, foretold +The danger, and the lurking enemy +That lay in wait; beyond this, had been force; +And force upon free will hath here no place. +But confidence then bore thee on; secure +Either to meet no danger, or to find +Matter of glorious trial; and perhaps +I also erred, in overmuch admiring +What seemed in thee so perfect, that I thought +No evil durst attempt thee; but I rue +The errour now, which is become my crime, +And thou the accuser. Thus it shall befall +Him, who, to worth in women overtrusting, +Lets her will rule: restraint she will not brook; +And, left to herself, if evil thence ensue, +She first his weak indulgence will accuse. +Thus they in mutual accusation spent +The fruitless hours, but neither self-condemning; +And of their vain contest appeared no end. + + + +Book X + + +Mean while the heinous and despiteful act +Of Satan, done in Paradise; and how +He, in the serpent, had perverted Eve, +Her husband she, to taste the fatal fruit, +Was known in Heaven; for what can 'scape the eye +Of God all-seeing, or deceive his heart +Omniscient? who, in all things wise and just, +Hindered not Satan to attempt the mind +Of Man, with strength entire and free will armed, +Complete to have discovered and repulsed +Whatever wiles of foe or seeming friend. +For still they knew, and ought to have still remembered, +The high injunction, not to taste that fruit, +Whoever tempted; which they not obeying, +(Incurred what could they less?) the penalty; +And, manifold in sin, deserved to fall. +Up into Heaven from Paradise in haste +The angelick guards ascended, mute, and sad, +For Man; for of his state by this they knew, +Much wondering how the subtle Fiend had stolen +Entrance unseen. Soon as the unwelcome news +From Earth arrived at Heaven-gate, displeased +All were who heard; dim sadness did not spare +That time celestial visages, yet, mixed +With pity, violated not their bliss. +About the new-arrived, in multitudes +The ethereal people ran, to hear and know +How all befel: They towards the throne supreme, +Accountable, made haste, to make appear, +With righteous plea, their utmost vigilance +And easily approved; when the Most High +Eternal Father, from his secret cloud, +Amidst in thunder uttered thus his voice. +Assembled Angels, and ye Powers returned +From unsuccessful charge; be not dismayed, +Nor troubled at these tidings from the earth, +Which your sincerest care could not prevent; +Foretold so lately what would come to pass, +When first this tempter crossed the gulf from Hell. +I told ye then he should prevail, and speed +On his bad errand; Man should be seduced, +And flattered out of all, believing lies +Against his Maker; no decree of mine +Concurring to necessitate his fall, +Or touch with lightest moment of impulse +His free will, to her own inclining left +In even scale. But fallen he is; and now +What rests, but that the mortal sentence pass +On his transgression,--death denounced that day? +Which he presumes already vain and void, +Because not yet inflicted, as he feared, +By some immediate stroke; but soon shall find +Forbearance no acquittance, ere day end. +Justice shall not return as bounty scorned. +But whom send I to judge them? whom but thee, +Vicegerent Son? To thee I have transferred +All judgement, whether in Heaven, or Earth, or Hell. +Easy it may be seen that I intend +Mercy colleague with justice, sending thee +Man's friend, his Mediator, his designed +Both ransom and Redeemer voluntary, +And destined Man himself to judge Man fallen. +So spake the Father; and, unfolding bright +Toward the right hand his glory, on the Son +Blazed forth unclouded Deity: He full +Resplendent all his Father manifest +Expressed, and thus divinely answered mild. +Father Eternal, thine is to decree; +Mine, both in Heaven and Earth, to do thy will +Supreme; that thou in me, thy Son beloved, +Mayest ever rest well pleased. I go to judge +On earth these thy transgressours; but thou knowest, +Whoever judged, the worst on me must light, +When time shall be; for so I undertook +Before thee; and, not repenting, this obtain +Of right, that I may mitigate their doom +On me derived; yet I shall temper so +Justice with mercy, as may illustrate most +Them fully satisfied, and thee appease. +Attendance none shall need, nor train, where none +Are to behold the judgement, but the judged, +Those two; the third best absent is condemned, +Convict by flight, and rebel to all law: +Conviction to the serpent none belongs. +Thus saying, from his radiant seat he rose +Of high collateral glory: Him Thrones, and Powers, +Princedoms, and Dominations ministrant, +Accompanied to Heaven-gate; from whence +Eden, and all the coast, in prospect lay. +Down he descended straight; the speed of Gods +Time counts not, though with swiftest minutes winged. +Now was the sun in western cadence low +From noon, and gentle airs, due at their hour, +To fan the earth now waked, and usher in +The evening cool; when he, from wrath more cool, +Came the mild Judge, and Intercessour both, +To sentence Man: The voice of God they heard +Now walking in the garden, by soft winds +Brought to their ears, while day declined; they heard, +And from his presence hid themselves among +The thickest trees, both man and wife; till God, +Approaching, thus to Adam called aloud. +Where art thou, Adam, wont with joy to meet +My coming seen far off? I miss thee here, +Not pleased, thus entertained with solitude, +Where obvious duty ere while appeared unsought: +Or come I less conspicuous, or what change +Absents thee, or what chance detains?--Come forth! +He came; and with him Eve, more loth, though first +To offend; discountenanced both, and discomposed; +Love was not in their looks, either to God, +Or to each other; but apparent guilt, +And shame, and perturbation, and despair, +Anger, and obstinacy, and hate, and guile. +Whence Adam, faltering long, thus answered brief. +I heard thee in the garden, and of thy voice +Afraid, being naked, hid myself. To whom +The gracious Judge without revile replied. +My voice thou oft hast heard, and hast not feared, +But still rejoiced; how is it now become +So dreadful to thee? That thou art naked, who +Hath told thee? Hast thou eaten of the tree, +Whereof I gave thee charge thou shouldst not eat? +To whom thus Adam sore beset replied. +O Heaven! in evil strait this day I stand +Before my Judge; either to undergo +Myself the total crime, or to accuse +My other self, the partner of my life; +Whose failing, while her faith to me remains, +I should conceal, and not expose to blame +By my complaint: but strict necessity +Subdues me, and calamitous constraint; +Lest on my head both sin and punishment, +However insupportable, be all +Devolved; though should I hold my peace, yet thou +Wouldst easily detect what I conceal.-- +This Woman, whom thou madest to be my help, +And gavest me as thy perfect gift, so good, +So fit, so acceptable, so divine, +That from her hand I could suspect no ill, +And what she did, whatever in itself, +Her doing seemed to justify the deed; +She gave me of the tree, and I did eat. +To whom the Sovran Presence thus replied. +Was she thy God, that her thou didst obey +Before his voice? or was she made thy guide, +Superiour, or but equal, that to her +Thou didst resign thy manhood, and the place +Wherein God set thee above her made of thee, +And for thee, whose perfection far excelled +Hers in all real dignity? Adorned +She was indeed, and lovely, to attract +Thy love, not thy subjection; and her gifts +Were such, as under government well seemed; +Unseemly to bear rule; which was thy part +And person, hadst thou known thyself aright. +So having said, he thus to Eve in few. +Say, Woman, what is this which thou hast done? +To whom sad Eve, with shame nigh overwhelmed, +Confessing soon, yet not before her Judge +Bold or loquacious, thus abashed replied. +The Serpent me beguiled, and I did eat. +Which when the Lord God heard, without delay +To judgement he proceeded on the accused +Serpent, though brute; unable to transfer +The guilt on him, who made him instrument +Of mischief, and polluted from the end +Of his creation; justly then accursed, +As vitiated in nature: More to know +Concerned not Man, (since he no further knew) +Nor altered his offence; yet God at last +To Satan first in sin his doom applied, +Though in mysterious terms, judged as then best: +And on the Serpent thus his curse let fall. +Because thou hast done this, thou art accursed +Above all cattle, each beast of the field; +Upon thy belly groveling thou shalt go, +And dust shalt eat all the days of thy life. +Between thee and the woman I will put +Enmity, and between thine and her seed; +Her seed shall bruise thy head, thou bruise his heel. +So spake this oracle, then verified +When Jesus, Son of Mary, second Eve, +Saw Satan fall, like lightning, down from Heaven, +Prince of the air; then, rising from his grave +Spoiled Principalities and Powers, triumphed +In open show; and, with ascension bright, +Captivity led captive through the air, +The realm itself of Satan, long usurped; +Whom he shall tread at last under our feet; +Even he, who now foretold his fatal bruise; +And to the Woman thus his sentence turned. +Thy sorrow I will greatly multiply +By thy conception; children thou shalt bring +In sorrow forth; and to thy husband's will +Thine shall submit; he over thee shall rule. +On Adam last thus judgement he pronounced. +Because thou hast hearkened to the voice of thy wife, +And eaten of the tree, concerning which +I charged thee, saying, Thou shalt not eat thereof: +Cursed is the ground for thy sake; thou in sorrow +Shalt eat thereof, all the days of thy life; +Thorns also and thistles it shall bring thee forth +Unbid; and thou shalt eat the herb of the field; +In the sweat of thy face shalt thou eat bread, +Till thou return unto the ground; for thou +Out of the ground wast taken, know thy birth, +For dust thou art, and shalt to dust return. +So judged he Man, both Judge and Saviour sent; +And the instant stroke of death, denounced that day, +Removed far off; then, pitying how they stood +Before him naked to the air, that now +Must suffer change, disdained not to begin +Thenceforth the form of servant to assume; +As when he washed his servants feet; so now, +As father of his family, he clad +Their nakedness with skins of beasts, or slain, +Or as the snake with youthful coat repaid; +And thought not much to clothe his enemies; +Nor he their outward only with the skins +Of beasts, but inward nakedness, much more. +Opprobrious, with his robe of righteousness, +Arraying, covered from his Father's sight. +To him with swift ascent he up returned, +Into his blissful bosom reassumed +In glory, as of old; to him appeased +All, though all-knowing, what had passed with Man +Recounted, mixing intercession sweet. +Mean while, ere thus was sinned and judged on Earth, +Within the gates of Hell sat Sin and Death, +In counterview within the gates, that now +Stood open wide, belching outrageous flame +Far into Chaos, since the Fiend passed through, +Sin opening; who thus now to Death began. +O Son, why sit we here each other viewing +Idly, while Satan, our great author, thrives +In other worlds, and happier seat provides +For us, his offspring dear? It cannot be +But that success attends him; if mishap, +Ere this he had returned, with fury driven +By his avengers; since no place like this +Can fit his punishment, or their revenge. +Methinks I feel new strength within me rise, +Wings growing, and dominion given me large +Beyond this deep; whatever draws me on, +Or sympathy, or some connatural force, +Powerful at greatest distance to unite, +With secret amity, things of like kind, +By secretest conveyance. Thou, my shade +Inseparable, must with me along; +For Death from Sin no power can separate. +But, lest the difficulty of passing back +Stay his return perhaps over this gulf +Impassable, impervious; let us try +Adventurous work, yet to thy power and mine +Not unagreeable, to found a path +Over this main from Hell to that new world, +Where Satan now prevails; a monument +Of merit high to all the infernal host, +Easing their passage hence, for intercourse, +Or transmigration, as their lot shall lead. +Nor can I miss the way, so strongly drawn +By this new-felt attraction and instinct. +Whom thus the meager Shadow answered soon. +Go, whither Fate, and inclination strong, +Leads thee; I shall not lag behind, nor err +The way, thou leading; such a scent I draw +Of carnage, prey innumerable, and taste +The savour of death from all things there that live: +Nor shall I to the work thou enterprisest +Be wanting, but afford thee equal aid. +So saying, with delight he snuffed the smell +Of mortal change on earth. As when a flock +Of ravenous fowl, though many a league remote, +Against the day of battle, to a field, +Where armies lie encamped, come flying, lured +With scent of living carcasses designed +For death, the following day, in bloody fight: +So scented the grim Feature, and upturned +His nostril wide into the murky air; +Sagacious of his quarry from so far. +Then both from out Hell-gates, into the waste +Wide anarchy of Chaos, damp and dark, +Flew diverse; and with power (their power was great) +Hovering upon the waters, what they met +Solid or slimy, as in raging sea +Tost up and down, together crouded drove, +From each side shoaling towards the mouth of Hell; +As when two polar winds, blowing adverse +Upon the Cronian sea, together drive +Mountains of ice, that stop the imagined way +Beyond Petsora eastward, to the rich +Cathaian coast. The aggregated soil +Death with his mace petrifick, cold and dry, +As with a trident, smote; and fixed as firm +As Delos, floating once; the rest his look +Bound with Gorgonian rigour not to move; +And with Asphaltick slime, broad as the gate, +Deep to the roots of Hell the gathered beach +They fastened, and the mole immense wrought on +Over the foaming deep high-arched, a bridge +Of length prodigious, joining to the wall +Immoveable of this now fenceless world, +Forfeit to Death; from hence a passage broad, +Smooth, easy, inoffensive, down to Hell. +So, if great things to small may be compared, +Xerxes, the liberty of Greece to yoke, +From Susa, his Memnonian palace high, +Came to the sea: and, over Hellespont +Bridging his way, Europe with Asia joined, +And scourged with many a stroke the indignant waves. +Now had they brought the work by wonderous art +Pontifical, a ridge of pendant rock, +Over the vexed abyss, following the track +Of Satan to the self-same place where he +First lighted from his wing, and landed safe +From out of Chaos, to the outside bare +Of this round world: With pins of adamant +And chains they made all fast, too fast they made +And durable! And now in little space +The confines met of empyrean Heaven, +And of this World; and, on the left hand, Hell +With long reach interposed; three several ways +In sight, to each of these three places led. +And now their way to Earth they had descried, +To Paradise first tending; when, behold! +Satan, in likeness of an Angel bright, +Betwixt the Centaur and the Scorpion steering +His zenith, while the sun in Aries rose: +Disguised he came; but those his children dear +Their parent soon discerned, though in disguise. +He, after Eve seduced, unminded slunk +Into the wood fast by; and, changing shape, +To observe the sequel, saw his guileful act +By Eve, though all unweeting, seconded +Upon her husband; saw their shame that sought +Vain covertures; but when he saw descend +The Son of God to judge them, terrified +He fled; not hoping to escape, but shun +The present; fearing, guilty, what his wrath +Might suddenly inflict; that past, returned +By night, and listening where the hapless pair +Sat in their sad discourse, and various plaint, +Thence gathered his own doom; which understood +Not instant, but of future time, with joy +And tidings fraught, to Hell he now returned; +And at the brink of Chaos, near the foot +Of this new wonderous pontifice, unhoped +Met, who to meet him came, his offspring dear. +Great joy was at their meeting, and at sight +Of that stupendious bridge his joy encreased. +Long he admiring stood, till Sin, his fair +Enchanting daughter, thus the silence broke. +O Parent, these are thy magnifick deeds, +Thy trophies! which thou viewest as not thine own; +Thou art their author, and prime architect: +For I no sooner in my heart divined, +My heart, which by a secret harmony +Still moves with thine, joined in connexion sweet, +That thou on earth hadst prospered, which thy looks +Now also evidence, but straight I felt, +Though distant from thee worlds between, yet felt, +That I must after thee, with this thy son; +Such fatal consequence unites us three! +Hell could no longer hold us in our bounds, +Nor this unvoyageable gulf obscure +Detain from following thy illustrious track. +Thou hast achieved our liberty, confined +Within Hell-gates till now; thou us impowered +To fortify thus far, and overlay, +With this portentous bridge, the dark abyss. +Thine now is all this world; thy virtue hath won +What thy hands builded not; thy wisdom gained +With odds what war hath lost, and fully avenged +Our foil in Heaven; here thou shalt monarch reign, +There didst not; there let him still victor sway, +As battle hath adjudged; from this new world +Retiring, by his own doom alienated; +And henceforth monarchy with thee divide +Of all things, parted by the empyreal bounds, +His quadrature, from thy orbicular world; +Or try thee now more dangerous to his throne. +Whom thus the Prince of darkness answered glad. +Fair Daughter, and thou Son and Grandchild both; +High proof ye now have given to be the race +Of Satan (for I glory in the name, +Antagonist of Heaven's Almighty King,) +Amply have merited of me, of all +The infernal empire, that so near Heaven's door +Triumphal with triumphal act have met, +Mine, with this glorious work; and made one realm, +Hell and this world, one realm, one continent +Of easy thorough-fare. Therefore, while I +Descend through darkness, on your road with ease, +To my associate Powers, them to acquaint +With these successes, and with them rejoice; +You two this way, among these numerous orbs, +All yours, right down to Paradise descend; +There dwell, and reign in bliss; thence on the earth +Dominion exercise and in the air, +Chiefly on Man, sole lord of all declared; +Him first make sure your thrall, and lastly kill. +My substitutes I send ye, and create +Plenipotent on earth, of matchless might +Issuing from me: on your joint vigour now +My hold of this new kingdom all depends, +Through Sin to Death exposed by my exploit. +If your joint power prevail, the affairs of Hell +No detriment need fear; go, and be strong! +So saying he dismissed them; they with speed +Their course through thickest constellations held, +Spreading their bane; the blasted stars looked wan, +And planets, planet-struck, real eclipse +Then suffered. The other way Satan went down +The causey to Hell-gate: On either side +Disparted Chaos overbuilt exclaimed, +And with rebounding surge the bars assailed, +That scorned his indignation: Through the gate, +Wide open and unguarded, Satan passed, +And all about found desolate; for those, +Appointed to sit there, had left their charge, +Flown to the upper world; the rest were all +Far to the inland retired, about the walls +Of Pandemonium; city and proud seat +Of Lucifer, so by allusion called +Of that bright star to Satan paragoned; +There kept their watch the legions, while the Grand +In council sat, solicitous what chance +Might intercept their emperour sent; so he +Departing gave command, and they observed. +As when the Tartar from his Russian foe, +By Astracan, over the snowy plains, +Retires; or Bactrin Sophi, from the horns +Of Turkish crescent, leaves all waste beyond +The realm of Aladule, in his retreat +To Tauris or Casbeen: So these, the late +Heaven-banished host, left desart utmost Hell +Many a dark league, reduced in careful watch +Round their metropolis; and now expecting +Each hour their great adventurer, from the search +Of foreign worlds: He through the midst unmarked, +In show plebeian Angel militant +Of lowest order, passed; and from the door +Of that Plutonian hall, invisible +Ascended his high throne; which, under state +Of richest texture spread, at the upper end +Was placed in regal lustre. Down a while +He sat, and round about him saw unseen: +At last, as from a cloud, his fulgent head +And shape star-bright appeared, or brighter; clad +With what permissive glory since his fall +Was left him, or false glitter: All amazed +At that so sudden blaze the Stygian throng +Bent their aspect, and whom they wished beheld, +Their mighty Chief returned: loud was the acclaim: +Forth rushed in haste the great consulting peers, +Raised from their dark Divan, and with like joy +Congratulant approached him; who with hand +Silence, and with these words attention, won. +Thrones, Dominations, Princedoms, Virtues, Powers; +For in possession such, not only of right, +I call ye, and declare ye now; returned +Successful beyond hope, to lead ye forth +Triumphant out of this infernal pit +Abominable, accursed, the house of woe, +And dungeon of our tyrant: Now possess, +As Lords, a spacious world, to our native Heaven +Little inferiour, by my adventure hard +With peril great achieved. Long were to tell +What I have done; what suffered;with what pain +Voyaged th' unreal, vast, unbounded deep +Of horrible confusion; over which +By Sin and Death a broad way now is paved, +To expedite your glorious march; but I +Toiled out my uncouth passage, forced to ride +The untractable abyss, plunged in the womb +Of unoriginal Night and Chaos wild; +That, jealous of their secrets, fiercely opposed +My journey strange, with clamorous uproar +Protesting Fate supreme; thence how I found +The new created world, which fame in Heaven +Long had foretold, a fabrick wonderful +Of absolute perfection! therein Man +Placed in a Paradise, by our exile +Made happy: Him by fraud I have seduced +From his Creator; and, the more to encrease +Your wonder, with an apple; he, thereat +Offended, worth your laughter! hath given up +Both his beloved Man, and all his world, +To Sin and Death a prey, and so to us, +Without our hazard, labour, or alarm; +To range in, and to dwell, and over Man +To rule, as over all he should have ruled. +True is, me also he hath judged, or rather +Me not, but the brute serpent in whose shape +Man I deceived: that which to me belongs, +Is enmity which he will put between +Me and mankind; I am to bruise his heel; +His seed, when is not set, shall bruise my head: +A world who would not purchase with a bruise, +Or much more grievous pain?--Ye have the account +Of my performance: What remains, ye Gods, +But up, and enter now into full bliss? +So having said, a while he stood, expecting +Their universal shout, and high applause, +To fill his ear; when, contrary, he hears +On all sides, from innumerable tongues, +A dismal universal hiss, the sound +Of publick scorn; he wondered, but not long +Had leisure, wondering at himself now more, +His visage drawn he felt to sharp and spare; +His arms clung to his ribs; his legs entwining +Each other, till supplanted down he fell +A monstrous serpent on his belly prone, +Reluctant, but in vain; a greater power +Now ruled him, punished in the shape he sinned, +According to his doom: he would have spoke, +But hiss for hiss returned with forked tongue +To forked tongue; for now were all transformed +Alike, to serpents all, as accessories +To his bold riot: Dreadful was the din +Of hissing through the hall, thick swarming now +With complicated monsters head and tail, +Scorpion, and Asp, and Amphisbaena dire, +Cerastes horned, Hydrus, and Elops drear, +And Dipsas; (not so thick swarmed once the soil +Bedropt with blood of Gorgon, or the isle +Ophiusa,) but still greatest he the midst, +Now Dragon grown, larger than whom the sun +Ingendered in the Pythian vale or slime, +Huge Python, and his power no less he seemed +Above the rest still to retain; they all +Him followed, issuing forth to the open field, +Where all yet left of that revolted rout, +Heaven-fallen, in station stood or just array; +Sublime with expectation when to see +In triumph issuing forth their glorious Chief; +They saw, but other sight instead! a croud +Of ugly serpents; horrour on them fell, +And horrid sympathy; for, what they saw, +They felt themselves, now changing; down their arms, +Down fell both spear and shield; down they as fast; +And the dire hiss renewed, and the dire form +Catched, by contagion; like in punishment, +As in their crime. Thus was the applause they meant, +Turned to exploding hiss, triumph to shame +Cast on themselves from their own mouths. There stood +A grove hard by, sprung up with this their change, +His will who reigns above, to aggravate +Their penance, laden with fair fruit, like that +Which grew in Paradise, the bait of Eve +Used by the Tempter: on that prospect strange +Their earnest eyes they fixed, imagining +For one forbidden tree a multitude +Now risen, to work them further woe or shame; +Yet, parched with scalding thirst and hunger fierce, +Though to delude them sent, could not abstain; +But on they rolled in heaps, and, up the trees +Climbing, sat thicker than the snaky locks +That curled Megaera: greedily they plucked +The fruitage fair to sight, like that which grew +Near that bituminous lake where Sodom flamed; +This more delusive, not the touch, but taste +Deceived; they, fondly thinking to allay +Their appetite with gust, instead of fruit +Chewed bitter ashes, which the offended taste +With spattering noise rejected: oft they assayed, +Hunger and thirst constraining; drugged as oft, +With hatefullest disrelish writhed their jaws, +With soot and cinders filled; so oft they fell +Into the same illusion, not as Man +Whom they triumphed once lapsed. Thus were they plagued +And worn with famine, long and ceaseless hiss, +Till their lost shape, permitted, they resumed; +Yearly enjoined, some say, to undergo, +This annual humbling certain numbered days, +To dash their pride, and joy, for Man seduced. +However, some tradition they dispersed +Among the Heathen, of their purchase got, +And fabled how the Serpent, whom they called +Ophion, with Eurynome, the wide-- +Encroaching Eve perhaps, had first the rule +Of high Olympus; thence by Saturn driven +And Ops, ere yet Dictaean Jove was born. +Mean while in Paradise the hellish pair +Too soon arrived; Sin, there in power before, +Once actual; now in body, and to dwell +Habitual habitant; behind her Death, +Close following pace for pace, not mounted yet +On his pale horse: to whom Sin thus began. +Second of Satan sprung, all-conquering Death! +What thinkest thou of our empire now, though earned +With travel difficult, not better far +Than still at Hell's dark threshold to have sat watch, +Unnamed, undreaded, and thyself half starved? +Whom thus the Sin-born monster answered soon. +To me, who with eternal famine pine, +Alike is Hell, or Paradise, or Heaven; +There best, where most with ravine I may meet; +Which here, though plenteous, all too little seems +To stuff this maw, this vast unhide-bound corps. +To whom the incestuous mother thus replied. +Thou therefore on these herbs, and fruits, and flowers, +Feed first; on each beast next, and fish, and fowl; +No homely morsels! and, whatever thing +The sithe of Time mows down, devour unspared; +Till I, in Man residing, through the race, +His thoughts, his looks, words, actions, all infect; +And season him thy last and sweetest prey. +This said, they both betook them several ways, +Both to destroy, or unimmortal make +All kinds, and for destruction to mature +Sooner or later; which the Almighty seeing, +From his transcendent seat the Saints among, +To those bright Orders uttered thus his voice. +See, with what heat these dogs of Hell advance +To waste and havock yonder world, which I +So fair and good created; and had still +Kept in that state, had not the folly of Man +Let in these wasteful furies, who impute +Folly to me; so doth the Prince of Hell +And his adherents, that with so much ease +I suffer them to enter and possess +A place so heavenly; and, conniving, seem +To gratify my scornful enemies, +That laugh, as if, transported with some fit +Of passion, I to them had quitted all, +At random yielded up to their misrule; +And know not that I called, and drew them thither, +My Hell-hounds, to lick up the draff and filth +Which Man's polluting sin with taint hath shed +On what was pure; til, crammed and gorged, nigh burst +With sucked and glutted offal, at one sling +Of thy victorious arm, well-pleasing Son, +Both Sin, and Death, and yawning Grave, at last, +Through Chaos hurled, obstruct the mouth of Hell +For ever, and seal up his ravenous jaws. +Then Heaven and Earth renewed shall be made pure +To sanctity, that shall receive no stain: +Till then, the curse pronounced on both precedes. +He ended, and the heavenly audience loud +Sung Halleluiah, as the sound of seas, +Through multitude that sung: Just are thy ways, +Righteous are thy decrees on all thy works; +Who can extenuate thee? Next, to the Son, +Destined Restorer of mankind, by whom +New Heaven and Earth shall to the ages rise, +Or down from Heaven descend.--Such was their song; +While the Creator, calling forth by name +His mighty Angels, gave them several charge, +As sorted best with present things. The sun +Had first his precept so to move, so shine, +As might affect the earth with cold and heat +Scarce tolerable; and from the north to call +Decrepit winter; from the south to bring +Solstitial summer's heat. To the blanc moon +Her office they prescribed; to the other five +Their planetary motions, and aspects, +In sextile, square, and trine, and opposite, +Of noxious efficacy, and when to join +In synod unbenign; and taught the fixed +Their influence malignant when to shower, +Which of them rising with the sun, or falling, +Should prove tempestuous: To the winds they set +Their corners, when with bluster to confound +Sea, air, and shore; the thunder when to roll +With terrour through the dark aereal hall. +Some say, he bid his Angels turn ascanse +The poles of earth, twice ten degrees and more, +From the sun's axle; they with labour pushed +Oblique the centrick globe: Some say, the sun +Was bid turn reins from the equinoctial road +Like distant breadth to Taurus with the seven +Atlantick Sisters, and the Spartan Twins, +Up to the Tropick Crab: thence down amain +By Leo, and the Virgin, and the Scales, +As deep as Capricorn; to bring in change +Of seasons to each clime; else had the spring +Perpetual smiled on earth with vernant flowers, +Equal in days and nights, except to those +Beyond the polar circles; to them day +Had unbenighted shone, while the low sun, +To recompense his distance, in their sight +Had rounded still the horizon, and not known +Or east or west; which had forbid the snow +From cold Estotiland, and south as far +Beneath Magellan. At that tasted fruit +The sun, as from Thyestean banquet, turned +His course intended; else, how had the world +Inhabited, though sinless, more than now, +Avoided pinching cold and scorching heat? +These changes in the Heavens, though slow, produced +Like change on sea and land; sideral blast, +Vapour, and mist, and exhalation hot, +Corrupt and pestilent: Now from the north +Of Norumbega, and the Samoed shore, +Bursting their brazen dungeon, armed with ice, +And snow, and hail, and stormy gust and flaw, +Boreas, and Caecias, and Argestes loud, +And Thrascias, rend the woods, and seas upturn; +With adverse blast upturns them from the south +Notus, and Afer black with thunderous clouds +From Serraliona; thwart of these, as fierce, +Forth rush the Levant and the Ponent winds, +Eurus and Zephyr, with their lateral noise, +Sirocco and Libecchio. Thus began +Outrage from lifeless things; but Discord first, +Daughter of Sin, among the irrational +Death introduced, through fierce antipathy: +Beast now with beast 'gan war, and fowl with fowl, +And fish with fish; to graze the herb all leaving, +Devoured each other; nor stood much in awe +Of Man, but fled him; or, with countenance grim, +Glared on him passing. These were from without +The growing miseries, which Adam saw +Already in part, though hid in gloomiest shade, +To sorrow abandoned, but worse felt within; +And, in a troubled sea of passion tost, +Thus to disburden sought with sad complaint. +O miserable of happy! Is this the end +Of this new glorious world, and me so late +The glory of that glory, who now become +Accursed, of blessed? hide me from the face +Of God, whom to behold was then my highth +Of happiness!--Yet well, if here would end +The misery; I deserved it, and would bear +My own deservings; but this will not serve: +All that I eat or drink, or shall beget, +Is propagated curse. O voice, once heard +Delightfully, Encrease and multiply; +Now death to hear! for what can I encrease, +Or multiply, but curses on my head? +Who of all ages to succeed, but, feeling +The evil on him brought by me, will curse +My head? Ill fare our ancestor impure, +For this we may thank Adam! but his thanks +Shall be the execration: so, besides +Mine own that bide upon me, all from me +Shall with a fierce reflux on me rebound; +On me, as on their natural center, light +Heavy, though in their place. O fleeting joys +Of Paradise, dear bought with lasting woes! +Did I request thee, Maker, from my clay +To mould me Man? did I solicit thee +From darkness to promote me, or here place +In this delicious garden? As my will +Concurred not to my being, it were but right +And equal to reduce me to my dust; +Desirous to resign and render back +All I received; unable to perform +Thy terms too hard, by which I was to hold +The good I sought not. To the loss of that, +Sufficient penalty, why hast thou added +The sense of endless woes? Inexplicable +Why am I mocked with death, and lengthened out +To deathless pain? How gladly would I meet +Mortality my sentence, and be earth +Insensible! How glad would lay me down +As in my mother's lap! There I should rest, +And sleep secure; his dreadful voice no more +Would thunder in my ears; no fear of worse +To me, and to my offspring, would torment me +With cruel expectation. Yet one doubt +Pursues me still, lest all I cannot die; +Lest that pure breath of life, the spirit of Man +Which God inspired, cannot together perish +With this corporeal clod; then, in the grave, +Or in some other dismal place, who knows +But I shall die a living death? O thought +Horrid, if true! Yet why? It was but breath +Of life that sinned; what dies but what had life +And sin? The body properly had neither, +All of me then shall die: let this appease +The doubt, since human reach no further knows. +For though the Lord of all be infinite, +Is his wrath also? Be it, Man is not so, +But mortal doomed. How can he exercise +Wrath without end on Man, whom death must end? +Can he make deathless death? That were to make +Strange contradiction, which to God himself +Impossible is held; as argument +Of weakness, not of power. Will he draw out, +For anger's sake, finite to infinite, +In punished Man, to satisfy his rigour, +Satisfied never? That were to extend +His sentence beyond dust and Nature's law; +By which all causes else, according still +To the reception of their matter, act; +Not to the extent of their own sphere. But say +That death be not one stroke, as I supposed, +Bereaving sense, but endless misery +From this day onward; which I feel begun +Both in me, and without me; and so last +To perpetuity;--Ay me!that fear +Comes thundering back with dreadful revolution +On my defenceless head; both Death and I +Am found eternal, and incorporate both; +Nor I on my part single; in me all +Posterity stands cursed: Fair patrimony +That I must leave ye, Sons! O, were I able +To waste it all myself, and leave ye none! +So disinherited, how would you bless +Me, now your curse! Ah, why should all mankind, +For one man's fault, thus guiltless be condemned, +It guiltless? But from me what can proceed, +But all corrupt; both mind and will depraved +Not to do only, but to will the same +With me? How can they then acquitted stand +In sight of God? Him, after all disputes, +Forced I absolve: all my evasions vain, +And reasonings, though through mazes, lead me still +But to my own conviction: first and last +On me, me only, as the source and spring +Of all corruption, all the blame lights due; +So might the wrath! Fond wish!couldst thou support +That burden, heavier than the earth to bear; +Than all the world much heavier, though divided +With that bad Woman? Thus, what thou desirest, +And what thou fearest, alike destroys all hope +Of refuge, and concludes thee miserable +Beyond all past example and future; +To Satan only like both crime and doom. +O Conscience! into what abyss of fears +And horrours hast thou driven me; out of which +I find no way, from deep to deeper plunged! +Thus Adam to himself lamented loud, +Through the still night; not now, as ere Man fell, +Wholesome, and cool, and mild, but with black air +Accompanied; with damps, and dreadful gloom; +Which to his evil conscience represented +All things with double terrour: On the ground +Outstretched he lay, on the cold ground; and oft +Cursed his creation; Death as oft accused +Of tardy execution, since denounced +The day of his offence. Why comes not Death, +Said he, with one thrice-acceptable stroke +To end me? Shall Truth fail to keep her word, +Justice Divine not hasten to be just? +But Death comes not at call; Justice Divine +Mends not her slowest pace for prayers or cries, +O woods, O fountains, hillocks, dales, and bowers! +With other echo late I taught your shades +To answer, and resound far other song.-- +Whom thus afflicted when sad Eve beheld, +Desolate where she sat, approaching nigh, +Soft words to his fierce passion she assayed: +But her with stern regard he thus repelled. +Out of my sight, thou Serpent! That name best +Befits thee with him leagued, thyself as false +And hateful; nothing wants, but that thy shape, +Like his, and colour serpentine, may show +Thy inward fraud; to warn all creatures from thee +Henceforth; lest that too heavenly form, pretended +To hellish falshood, snare them! But for thee +I had persisted happy; had not thy pride +And wandering vanity, when least was safe, +Rejected my forewarning, and disdained +Not to be trusted; longing to be seen, +Though by the Devil himself; him overweening +To over-reach; but, with the serpent meeting, +Fooled and beguiled; by him thou, I by thee +To trust thee from my side; imagined wise, +Constant, mature, proof against all assaults; +And understood not all was but a show, +Rather than solid virtue; all but a rib +Crooked by nature, bent, as now appears, +More to the part sinister, from me drawn; +Well if thrown out, as supernumerary +To my just number found. O! why did God, +Creator wise, that peopled highest Heaven +With Spirits masculine, create at last +This novelty on earth, this fair defect +Of nature, and not fill the world at once +With Men, as Angels, without feminine; +Or find some other way to generate +Mankind? This mischief had not been befallen, +And more that shall befall; innumerable +Disturbances on earth through female snares, +And strait conjunction with this sex: for either +He never shall find out fit mate, but such +As some misfortune brings him, or mistake; +Or whom he wishes most shall seldom gain +Through her perverseness, but shall see her gained +By a far worse; or, if she love, withheld +By parents; or his happiest choice too late +Shall meet, already linked and wedlock-bound +To a fell adversary, his hate or shame: +Which infinite calamity shall cause +To human life, and houshold peace confound. +He added not, and from her turned; but Eve, +Not so repulsed, with tears that ceased not flowing +And tresses all disordered, at his feet +Fell humble; and, embracing them, besought +His peace, and thus proceeded in her plaint. +Forsake me not thus, Adam! witness Heaven +What love sincere, and reverence in my heart +I bear thee, and unweeting have offended, +Unhappily deceived! Thy suppliant +I beg, and clasp thy knees; bereave me not, +Whereon I live, thy gentle looks, thy aid, +Thy counsel, in this uttermost distress, +My only strength and stay: Forlorn of thee, +Whither shall I betake me, where subsist? +While yet we live, scarce one short hour perhaps, +Between us two let there be peace; both joining, +As joined in injuries, one enmity +Against a foe by doom express assigned us, +That cruel Serpent: On me exercise not +Thy hatred for this misery befallen; +On me already lost, me than thyself +More miserable! Both have sinned;but thou +Against God only; I against God and thee; +And to the place of judgement will return, +There with my cries importune Heaven; that all +The sentence, from thy head removed, may light +On me, sole cause to thee of all this woe; +Me, me only, just object of his ire! +She ended weeping; and her lowly plight, +Immoveable, till peace obtained from fault +Acknowledged and deplored, in Adam wrought +Commiseration: Soon his heart relented +Towards her, his life so late, and sole delight, +Now at his feet submissive in distress; +Creature so fair his reconcilement seeking, +His counsel, whom she had displeased, his aid: +As one disarmed, his anger all he lost, +And thus with peaceful words upraised her soon. +Unwary, and too desirous, as before, +So now of what thou knowest not, who desirest +The punishment all on thyself; alas! +Bear thine own first, ill able to sustain +His full wrath, whose thou feelest as yet least part, +And my displeasure bearest so ill. If prayers +Could alter high decrees, I to that place +Would speed before thee, and be louder heard, +That on my head all might be visited; +Thy frailty and infirmer sex forgiven, +To me committed, and by me exposed. +But rise;--let us no more contend, nor blame +Each other, blamed enough elsewhere; but strive +In offices of love, how we may lighten +Each other's burden, in our share of woe; +Since this day's death denounced, if aught I see, +Will prove no sudden, but a slow-paced evil; +A long day's dying, to augment our pain; +And to our seed (O hapless seed!) derived. +To whom thus Eve, recovering heart, replied. +Adam, by sad experiment I know +How little weight my words with thee can find, +Found so erroneous; thence by just event +Found so unfortunate: Nevertheless, +Restored by thee, vile as I am, to place +Of new acceptance, hopeful to regain +Thy love, the sole contentment of my heart +Living or dying, from thee I will not hide +What thoughts in my unquiet breast are risen, +Tending to some relief of our extremes, +Or end; though sharp and sad, yet tolerable, +As in our evils, and of easier choice. +If care of our descent perplex us most, +Which must be born to certain woe, devoured +By Death at last; and miserable it is +To be to others cause of misery, +Our own begotten, and of our loins to bring +Into this cursed world a woeful race, +That after wretched life must be at last +Food for so foul a monster; in thy power +It lies, yet ere conception to prevent +The race unblest, to being yet unbegot. +Childless thou art, childless remain: so Death +Shall be deceived his glut, and with us two +Be forced to satisfy his ravenous maw. +But if thou judge it hard and difficult, +Conversing, looking, loving, to abstain +From love's due rights, nuptial embraces sweet; +And with desire to languish without hope, +Before the present object languishing +With like desire; which would be misery +And torment less than none of what we dread; +Then, both ourselves and seed at once to free +From what we fear for both, let us make short, -- +Let us seek Death; -- or, he not found, supply +With our own hands his office on ourselves: +Why stand we longer shivering under fears, +That show no end but death, and have the power, +Of many ways to die the shortest choosing, +Destruction with destruction to destroy? -- +She ended here, or vehement despair +Broke off the rest: so much of death her thoughts +Had entertained, as dyed her cheeks with pale. +But Adam, with such counsel nothing swayed, +To better hopes his more attentive mind +Labouring had raised; and thus to Eve replied. +Eve, thy contempt of life and pleasure seems +To argue in thee something more sublime +And excellent, than what thy mind contemns; +But self-destruction therefore sought, refutes +That excellence thought in thee; and implies, +Not thy contempt, but anguish and regret +For loss of life and pleasure overloved. +Or if thou covet death, as utmost end +Of misery, so thinking to evade +The penalty pronounced; doubt not but God +Hath wiselier armed his vengeful ire, than so +To be forestalled; much more I fear lest death, +So snatched, will not exempt us from the pain +We are by doom to pay; rather, such acts +Of contumacy will provoke the Highest +To make death in us live: Then let us seek +Some safer resolution, which methinks +I have in view, calling to mind with heed +Part of our sentence, that thy seed shall bruise +The Serpent's head; piteous amends! unless +Be meant, whom I conjecture, our grand foe, +Satan; who, in the serpent, hath contrived +Against us this deceit: To crush his head +Would be revenge indeed! which will be lost +By death brought on ourselves, or childless days +Resolved, as thou proposest; so our foe +Shal 'scape his punishment ordained, and we +Instead shall double ours upon our heads. +No more be mentioned then of violence +Against ourselves; and wilful barrenness, +That cuts us off from hope; and savours only +Rancour and pride, impatience and despite, +Reluctance against God and his just yoke +Laid on our necks. Remember with what mild +And gracious temper he both heard, and judged, +Without wrath or reviling; we expected +Immediate dissolution, which we thought +Was meant by death that day; when lo!to thee +Pains only in child-bearing were foretold, +And bringing forth; soon recompensed with joy, +Fruit of thy womb: On me the curse aslope +Glanced on the ground; with labour I must earn +My bread; what harm? Idleness had been worse; +My labour will sustain me; and, lest cold +Or heat should injure us, his timely care +Hath, unbesought, provided; and his hands +Clothed us unworthy, pitying while he judged; +How much more, if we pray him, will his ear +Be open, and his heart to pity incline, +And teach us further by what means to shun +The inclement seasons, rain, ice, hail, and snow! +Which now the sky, with various face, begins +To show us in this mountain; while the winds +Blow moist and keen, shattering the graceful locks +Of these fair spreading trees; which bids us seek +Some better shroud, some better warmth to cherish +Our limbs benummed, ere this diurnal star +Leave cold the night, how we his gathered beams +Reflected may with matter sere foment; +Or, by collision of two bodies, grind +The air attrite to fire; as late the clouds +Justling, or pushed with winds, rude in their shock, +Tine the slant lightning; whose thwart flame, driven down +Kindles the gummy bark of fir or pine; +And sends a comfortable heat from far, +Which might supply the sun: Such fire to use, +And what may else be remedy or cure +To evils which our own misdeeds have wrought, +He will instruct us praying, and of grace +Beseeching him; so as we need not fear +To pass commodiously this life, sustained +By him with many comforts, till we end +In dust, our final rest and native home. +What better can we do, than, to the place +Repairing where he judged us, prostrate fall +Before him reverent; and there confess +Humbly our faults, and pardon beg; with tears +Watering the ground, and with our sighs the air +Frequenting, sent from hearts contrite, in sign +Of sorrow unfeigned, and humiliation meek + + + +Book XI + + +Undoubtedly he will relent, and turn +From his displeasure; in whose look serene, +When angry most he seemed and most severe, +What else but favour, grace, and mercy, shone? +So spake our father penitent; nor Eve +Felt less remorse: they, forthwith to the place +Repairing where he judged them, prostrate fell +Before him reverent; and both confessed +Humbly their faults, and pardon begged; with tears +Watering the ground, and with their sighs the air +Frequenting, sent from hearts contrite, in sign +Of sorrow unfeigned, and humiliation meek. +Thus they, in lowliest plight, repentant stood +Praying; for from the mercy-seat above +Prevenient grace descending had removed +The stony from their hearts, and made new flesh +Regenerate grow instead; that sighs now breathed +Unutterable; which the Spirit of prayer +Inspired, and winged for Heaven with speedier flight +Than loudest oratory: Yet their port +Not of mean suitors; nor important less +Seemed their petition, than when the ancient pair +In fables old, less ancient yet than these, +Deucalion and chaste Pyrrha, to restore +The race of mankind drowned, before the shrine +Of Themis stood devout. To Heaven their prayers +Flew up, nor missed the way, by envious winds +Blown vagabond or frustrate: in they passed +Dimensionless through heavenly doors; then clad +With incense, where the golden altar fumed, +By their great intercessour, came in sight +Before the Father's throne: them the glad Son +Presenting, thus to intercede began. +See$ Father, what first-fruits on earth are sprung +From thy implanted grace in Man; these sighs +And prayers, which in this golden censer mixed +With incense, I thy priest before thee bring; +Fruits of more pleasing savour, from thy seed +Sown with contrition in his heart, than those +Which, his own hand manuring, all the trees +Of Paradise could have produced, ere fallen +From innocence. Now therefore, bend thine ear +To supplication; hear his sighs, though mute; +Unskilful with what words to pray, let me +Interpret for him; me, his advocate +And propitiation; all his works on me, +Good, or not good, ingraft; my merit those +Shall perfect, and for these my death shall pay. +Accept me; and, in me, from these receive +The smell of peace toward mankind: let him live +Before thee reconciled, at least his days +Numbered, though sad; till death, his doom, (which I +To mitigate thus plead, not to reverse,) +To better life shall yield him: where with me +All my redeemed may dwell in joy and bliss; +Made one with me, as I with thee am one. +To whom the Father, without cloud, serene. +All thy request for Man, accepted Son, +Obtain; all thy request was my decree: +But, longer in that Paradise to dwell, +The law I gave to Nature him forbids: +Those pure immortal elements, that know, +No gross, no unharmonious mixture foul, +Eject him, tainted now; and purge him off, +As a distemper, gross, to air as gross, +And mortal food; as may dispose him best +For dissolution wrought by sin, that first +Distempered all things, and of incorrupt +Corrupted. I, at first, with two fair gifts +Created him endowed; with happiness, +And immortality: that fondly lost, +This other served but to eternize woe; +Till I provided death: so death becomes +His final remedy; and, after life, +Tried in sharp tribulation, and refined +By faith and faithful works, to second life, +Waked in the renovation of the just, +Resigns him up with Heaven and Earth renewed. +But let us call to synod all the Blest, +Through Heaven's wide bounds: from them I will not hide +My judgements; how with mankind I proceed, +As how with peccant Angels late they saw, +And in their state, though firm, stood more confirmed. +He ended, and the Son gave signal high +To the bright minister that watched; he blew +His trumpet, heard in Oreb since perhaps +When God descended, and perhaps once more +To sound at general doom. The angelick blast +Filled all the regions: from their blisful bowers +Of amarantine shade, fountain or spring, +By the waters of life, where'er they sat +In fellowships of joy, the sons of light +Hasted, resorting to the summons high; +And took their seats; till from his throne supreme +The Almighty thus pronounced his sovran will. +O Sons, like one of us Man is become +To know both good and evil, since his taste +Of that defended fruit; but let him boast +His knowledge of good lost, and evil got; +Happier! had it sufficed him to have known +Good by itself, and evil not at all. +He sorrows now, repents, and prays contrite, +My motions in him; longer than they move, +His heart I know, how variable and vain, +Self-left. Lest therefore his now bolder hand +Reach also of the tree of life, and eat, +And live for ever, dream at least to live +For ever, to remove him I decree, +And send him from the garden forth to till +The ground whence he was taken, fitter soil. +Michael, this my behest have thou in charge; +Take to thee from among the Cherubim +Thy choice of flaming warriours, lest the Fiend, +Or in behalf of Man, or to invade +Vacant possession, some new trouble raise: +Haste thee, and from the Paradise of God +Without remorse drive out the sinful pair; +From hallowed ground the unholy; and denounce +To them, and to their progeny, from thence +Perpetual banishment. Yet, lest they faint +At the sad sentence rigorously urged, +(For I behold them softened, and with tears +Bewailing their excess,) all terrour hide. +If patiently thy bidding they obey, +Dismiss them not disconsolate; reveal +To Adam what shall come in future days, +As I shall thee enlighten; intermix +My covenant in the Woman's seed renewed; +So send them forth, though sorrowing, yet in peace: +And on the east side of the garden place, +Where entrance up from Eden easiest climbs, +Cherubick watch; and of a sword the flame +Wide-waving; all approach far off to fright, +And guard all passage to the tree of life: +Lest Paradise a receptacle prove +To Spirits foul, and all my trees their prey; +With whose stolen fruit Man once more to delude. +He ceased; and the arch-angelick Power prepared +For swift descent; with him the cohort bright +Of watchful Cherubim: four faces each +Had, like a double Janus; all their shape +Spangled with eyes more numerous than those +Of Argus, and more wakeful than to drouse, +Charmed with Arcadian pipe, the pastoral reed +Of Hermes, or his opiate rod. Mean while, +To re-salute the world with sacred light, +Leucothea waked; and with fresh dews imbalmed +The earth; when Adam and first matron Eve +Had ended now their orisons, and found +Strength added from above; new hope to spring +Out of despair; joy, but with fear yet linked; +Which thus to Eve his welcome words renewed. +Eve, easily my faith admit, that all +The good which we enjoy from Heaven descends; +But, that from us aught should ascend to Heaven +So prevalent as to concern the mind +Of God high-blest, or to incline his will, +Hard to belief may seem; yet this will prayer +Or one short sigh of human breath, upborne +Even to the seat of God. For since I sought +By prayer the offended Deity to appease; +Kneeled, and before him humbled all my heart; +Methought I saw him placable and mild, +Bending his ear; persuasion in me grew +That I was heard with favour; peace returned +Home to my breast, and to my memory +His promise, that thy seed shall bruise our foe; +Which, then not minded in dismay, yet now +Assures me that the bitterness of death +Is past, and we shall live. Whence hail to thee, +Eve rightly called, mother of all mankind, +Mother of all things living, since by thee +Man is to live; and all things live for Man. +To whom thus Eve with sad demeanour meek. +Ill-worthy I such title should belong +To me transgressour; who, for thee ordained +A help, became thy snare; to me reproach +Rather belongs, distrust, and all dispraise: +But infinite in pardon was my Judge, +That I, who first brought death on all, am graced +The source of life; next favourable thou, +Who highly thus to entitle me vouchsaf'st, +Far other name deserving. But the field +To labour calls us, now with sweat imposed, +Though after sleepless night; for see!the morn, +All unconcerned with our unrest, begins +Her rosy progress smiling: let us forth; +I never from thy side henceforth to stray, +Where'er our day's work lies, though now enjoined +Laborious, till day droop; while here we dwell, +What can be toilsome in these pleasant walks? +Here let us live, though in fallen state, content. +So spake, so wished much humbled Eve; but Fate +Subscribed not: Nature first gave signs, impressed +On bird, beast, air; air suddenly eclipsed, +After short blush of morn; nigh in her sight +The bird of Jove, stooped from his aery tour, +Two birds of gayest plume before him drove; +Down from a hill the beast that reigns in woods, +First hunter then, pursued a gentle brace, +Goodliest of all the forest, hart and hind; +Direct to the eastern gate was bent their flight. +Adam observed, and with his eye the chase +Pursuing, not unmoved, to Eve thus spake. +O Eve, some further change awaits us nigh, +Which Heaven, by these mute signs in Nature, shows +Forerunners of his purpose; or to warn +Us, haply too secure, of our discharge +From penalty, because from death released +Some days: how long, and what till then our life, +Who knows? or more than this, that we are dust, +And thither must return, and be no more? +Why else this double object in our sight +Of flight pursued in the air, and o'er the ground, +One way the self-same hour? why in the east +Darkness ere day's mid-course, and morning-light +More orient in yon western cloud, that draws +O'er the blue firmament a radiant white, +And slow descends with something heavenly fraught? +He erred not; for by this the heavenly bands +Down from a sky of jasper lighted now +In Paradise, and on a hill made halt; +A glorious apparition, had not doubt +And carnal fear that day dimmed Adam's eye. +Not that more glorious, when the Angels met +Jacob in Mahanaim, where he saw +The field pavilioned with his guardians bright; +Nor that, which on the flaming mount appeared +In Dothan, covered with a camp of fire, +Against the Syrian king, who to surprise +One man, assassin-like, had levied war, +War unproclaimed. The princely Hierarch +In their bright stand there left his Powers, to seise +Possession of the garden; he alone, +To find where Adam sheltered, took his way, +Not unperceived of Adam; who to Eve, +While the great visitant approached, thus spake. +Eve$ now expect great tidings, which perhaps +Of us will soon determine, or impose +New laws to be observed; for I descry, +From yonder blazing cloud that veils the hill, +One of the heavenly host; and, by his gait, +None of the meanest; some great Potentate +Or of the Thrones above; such majesty +Invests him coming! yet not terrible, +That I should fear; nor sociably mild, +As Raphael, that I should much confide; +But solemn and sublime; whom not to offend, +With reverence I must meet, and thou retire. +He ended: and the Arch-Angel soon drew nigh, +Not in his shape celestial, but as man +Clad to meet man; over his lucid arms +A military vest of purple flowed, +Livelier than Meliboean, or the grain +Of Sarra, worn by kings and heroes old +In time of truce; Iris had dipt the woof; +His starry helm unbuckled showed him prime +In manhood where youth ended; by his side, +As in a glistering zodiack, hung the sword, +Satan's dire dread; and in his hand the spear. +Adam bowed low; he, kingly, from his state +Inclined not, but his coming thus declared. +Adam, Heaven's high behest no preface needs: +Sufficient that thy prayers are heard; and Death, +Then due by sentence when thou didst transgress, +Defeated of his seisure many days +Given thee of grace; wherein thou mayest repent, +And one bad act with many deeds well done +Mayest cover: Well may then thy Lord, appeased, +Redeem thee quite from Death's rapacious claim; +But longer in this Paradise to dwell +Permits not: to remove thee I am come, +And send thee from the garden forth to till +The ground whence thou wast taken, fitter soil. +He added not; for Adam at the news +Heart-struck with chilling gripe of sorrow stood, +That all his senses bound; Eve, who unseen +Yet all had heard, with audible lament +Discovered soon the place of her retire. +O unexpected stroke, worse than of Death! +Must I thus leave thee$ Paradise? thus leave +Thee, native soil! these happy walks and shades, +Fit haunt of Gods? where I had hope to spend, +Quiet though sad, the respite of that day +That must be mortal to us both. O flowers, +That never will in other climate grow, +My early visitation, and my last + ;t even, which I bred up with tender hand +From the first opening bud, and gave ye names! +Who now shall rear ye to the sun, or rank +Your tribes, and water from the ambrosial fount? +Thee lastly, nuptial bower! by me adorned +With what to sight or smell was sweet! from thee +How shall I part, and whither wander down +Into a lower world; to this obscure +And wild? how shall we breathe in other air +Less pure, accustomed to immortal fruits? +Whom thus the Angel interrupted mild. +Lament not, Eve, but patiently resign +What justly thou hast lost, nor set thy heart, +Thus over-fond, on that which is not thine: +Thy going is not lonely; with thee goes +Thy husband; whom to follow thou art bound; +Where he abides, think there thy native soil. +Adam, by this from the cold sudden damp +Recovering, and his scattered spirits returned, +To Michael thus his humble words addressed. +Celestial, whether among the Thrones, or named +Of them the highest; for such of shape may seem +Prince above princes! gently hast thou told +Thy message, which might else in telling wound, +And in performing end us; what besides +Of sorrow, and dejection, and despair, +Our frailty can sustain, thy tidings bring, +Departure from this happy place, our sweet +Recess, and only consolation left +Familiar to our eyes! all places else +Inhospitable appear, and desolate; +Nor knowing us, nor known: And, if by prayer +Incessant I could hope to change the will +Of Him who all things can, I would not cease +To weary him with my assiduous cries: +But prayer against his absolute decree +No more avails than breath against the wind, +Blown stifling back on him that breathes it forth: +Therefore to his great bidding I submit. +This most afflicts me, that, departing hence, +As from his face I shall be hid, deprived +His blessed countenance: Here I could frequent +With worship place by place where he vouchsafed +Presence Divine; and to my sons relate, +'On this mount he appeared; under this tree +'Stood visible; among these pines his voice +'I heard; here with him at this fountain talked: +So many grateful altars I would rear +Of grassy turf, and pile up every stone +Of lustre from the brook, in memory, +Or monument to ages; and theron +Offer sweet-smelling gums, and fruits, and flowers: +In yonder nether world where shall I seek +His bright appearances, or foot-step trace? +For though I fled him angry, yet recalled +To life prolonged and promised race, I now +Gladly behold though but his utmost skirts +Of glory; and far off his steps adore. +To whom thus Michael with regard benign. +Adam, thou knowest Heaven his, and all the Earth; +Not this rock only; his Omnipresence fills +Land, sea, and air, and every kind that lives, +Fomented by his virtual power and warmed: +All the earth he gave thee to possess and rule, +No despicable gift; surmise not then +His presence to these narrow bounds confined +Of Paradise, or Eden: this had been +Perhaps thy capital seat, from whence had spread +All generations; and had hither come +From all the ends of the earth, to celebrate +And reverence thee, their great progenitor. +But this pre-eminence thou hast lost, brought down +To dwell on even ground now with thy sons: +Yet doubt not but in valley, and in plain, +God is, as here; and will be found alike +Present; and of his presence many a sign +Still following thee, still compassing thee round +With goodness and paternal love, his face +Express, and of his steps the track divine. +Which that thou mayest believe, and be confirmed +Ere thou from hence depart; know, I am sent +To show thee what shall come in future days +To thee, and to thy offspring: good with bad +Expect to hear; supernal grace contending +With sinfulness of men; thereby to learn +True patience, and to temper joy with fear +And pious sorrow; equally inured +By moderation either state to bear, +Prosperous or adverse: so shalt thou lead +Safest thy life, and best prepared endure +Thy mortal passage when it comes.--Ascend +This hill; let Eve (for I have drenched her eyes) +Here sleep below; while thou to foresight wakest; +As once thou sleptst, while she to life was formed. +To whom thus Adam gratefully replied. +Ascend, I follow thee, safe Guide, the path +Thou leadest me; and to the hand of Heaven submit, +However chastening; to the evil turn +My obvious breast; arming to overcome +By suffering, and earn rest from labour won, +If so I may attain. -- So both ascend +In the visions of God. It was a hill, +Of Paradise the highest; from whose top +The hemisphere of earth, in clearest ken, +Stretched out to the amplest reach of prospect lay. +Not higher that hill, nor wider looking round, +Whereon, for different cause, the Tempter set +Our second Adam, in the wilderness; +To show him all Earth's kingdoms, and their glory. +His eye might there command wherever stood +City of old or modern fame, the seat +Of mightiest empire, from the destined walls +Of Cambalu, seat of Cathaian Can, +And Samarchand by Oxus, Temir's throne, +To Paquin of Sinaean kings; and thence +To Agra and Lahor of great Mogul, +Down to the golden Chersonese; or where +The Persian in Ecbatan sat, or since +In Hispahan; or where the Russian Ksar +In Mosco; or the Sultan in Bizance, +Turchestan-born; nor could his eye not ken +The empire of Negus to his utmost port +Ercoco, and the less maritim kings +Mombaza, and Quiloa, and Melind, +And Sofala, thought Ophir, to the realm +Of Congo, and Angola farthest south; +Or thence from Niger flood to Atlas mount +The kingdoms of Almansor, Fez and Sus, +Morocco, and Algiers, and Tremisen; +On Europe thence, and where Rome was to sway +The world: in spirit perhaps he also saw +Rich Mexico, the seat of Montezume, +And Cusco in Peru, the richer seat +Of Atabalipa; and yet unspoiled +Guiana, whose great city Geryon's sons +Call El Dorado. But to nobler sights +Michael from Adam's eyes the film removed, +Which that false fruit that promised clearer sight +Had bred; then purged with euphrasy and rue +The visual nerve, for he had much to see; +And from the well of life three drops instilled. +So deep the power of these ingredients pierced, +Even to the inmost seat of mental sight, +That Adam, now enforced to close his eyes, +Sunk down, and all his spirits became entranced; +But him the gentle Angel by the hand +Soon raised, and his attention thus recalled. +Adam, now ope thine eyes; and first behold +The effects, which thy original crime hath wrought +In some to spring from thee; who never touched +The excepted tree; nor with the snake conspired; +Nor sinned thy sin; yet from that sin derive +Corruption, to bring forth more violent deeds. +His eyes he opened, and beheld a field, +Part arable and tilth, whereon were sheaves +New reaped; the other part sheep-walks and folds; +I' the midst an altar as the land-mark stood, +Rustick, of grassy sord; thither anon +A sweaty reaper from his tillage brought +First fruits, the green ear, and the yellow sheaf, +Unculled, as came to hand; a shepherd next, +More meek, came with the firstlings of his flock, +Choicest and best; then, sacrificing, laid +The inwards and their fat, with incense strowed, +On the cleft wood, and all due rights performed: +His offering soon propitious fire from Heaven +Consumed with nimble glance, and grateful steam; +The other's not, for his was not sincere; +Whereat he inly raged, and, as they talked, +Smote him into the midriff with a stone +That beat out life; he fell;and, deadly pale, +Groaned out his soul with gushing blood effused. +Much at that sight was Adam in his heart +Dismayed, and thus in haste to the Angel cried. +O Teacher, some great mischief hath befallen +To that meek man, who well had sacrificed; +Is piety thus and pure devotion paid? +To whom Michael thus, he also moved, replied. +These two are brethren, Adam, and to come +Out of thy loins; the unjust the just hath slain, +For envy that his brother's offering found +From Heaven acceptance; but the bloody fact +Will be avenged; and the other's faith, approved, +Lose no reward; though here thou see him die, +Rolling in dust and gore. To which our sire. +Alas! both for the deed, and for the cause! +But have I now seen Death? Is this the way +I must return to native dust? O sight +Of terrour, foul and ugly to behold, +Horrid to think, how horrible to feel! +To whom thus Michael. Death thou hast seen +In his first shape on Man; but many shapes +Of Death, and many are the ways that lead +To his grim cave, all dismal; yet to sense +More terrible at the entrance, than within. +Some, as thou sawest, by violent stroke shall die; +By fire, flood, famine, by intemperance more +In meats and drinks, which on the earth shall bring +Diseases dire, of which a monstrous crew +Before thee shall appear; that thou mayest know +What misery the inabstinence of Eve +Shall bring on Men. Immediately a place +Before his eyes appeared, sad, noisome, dark; +A lazar-house it seemed; wherein were laid +Numbers of all diseased; all maladies +Of ghastly spasm, or racking torture, qualms +Of heart-sick agony, all feverous kinds, +Convulsions, epilepsies, fierce catarrhs, +Intestine stone and ulcer, colick-pangs, +Demoniack phrenzy, moaping melancholy, +And moon-struck madness, pining atrophy, +Marasmus, and wide-wasting pestilence, +Dropsies, and asthmas, and joint-racking rheums. +Dire was the tossing, deep the groans; Despair +Tended the sick busiest from couch to couch; +And over them triumphant Death his dart +Shook, but delayed to strike, though oft invoked +With vows, as their chief good, and final hope. +Sight so deform what heart of rock could long +Dry-eyed behold? Adam could not, but wept, +Though not of woman born; compassion quelled +His best of man, and gave him up to tears +A space, till firmer thoughts restrained excess; +And, scarce recovering words, his plaint renewed. +O miserable mankind, to what fall +Degraded, to what wretched state reserved! +Better end here unborn. Why is life given +To be thus wrested from us? rather, why +Obtruded on us thus? who, if we knew +What we receive, would either no accept +Life offered, or soon beg to lay it down; +Glad to be so dismissed in peace. Can thus +The image of God in Man, created once +So goodly and erect, though faulty since, +To such unsightly sufferings be debased +Under inhuman pains? Why should not Man, +Retaining still divine similitude +In part, from such deformities be free, +And, for his Maker's image sake, exempt? +Their Maker's image, answered Michael, then +Forsook them, when themselves they vilified +To serve ungoverned Appetite; and took +His image whom they served, a brutish vice, +Inductive mainly to the sin of Eve. +Therefore so abject is their punishment, +Disfiguring not God's likeness, but their own; +Or if his likeness, by themselves defaced; +While they pervert pure Nature's healthful rules +To loathsome sickness; worthily, since they +God's image did not reverence in themselves. +I yield it just, said Adam, and submit. +But is there yet no other way, besides +These painful passages, how we may come +To death, and mix with our connatural dust? +There is, said Michael, if thou well observe +The rule of Not too much; by temperance taught, +In what thou eatest and drinkest; seeking from thence +Due nourishment, not gluttonous delight, +Till many years over thy head return: +So mayest thou live; till, like ripe fruit, thou drop +Into thy mother's lap; or be with ease +Gathered, nor harshly plucked; for death mature: +This is Old Age; but then, thou must outlive +Thy youth, thy strength, thy beauty; which will change +To withered, weak, and gray; thy senses then, +Obtuse, all taste of pleasure must forego, +To what thou hast; and, for the air of youth, +Hopeful and cheerful, in thy blood will reign +A melancholy damp of cold and dry +To weigh thy spirits down, and last consume +The balm of life. To whom our ancestor. +Henceforth I fly not death, nor would prolong +Life much; bent rather, how I may be quit, +Fairest and easiest, of this cumbrous charge; +Which I must keep till my appointed day +Of rendering up, and patiently attend +My dissolution. Michael replied. +Nor love thy life, nor hate; but what thou livest +Live well; how long, or short, permit to Heaven: +And now prepare thee for another sight. +He looked, and saw a spacious plain, whereon +Were tents of various hue; by some, were herds +Of cattle grazing; others, whence the sound +Of instruments, that made melodious chime, +Was heard, of harp and organ; and, who moved +Their stops and chords, was seen; his volant touch, +Instinct through all proportions, low and high, +Fled and pursued transverse the resonant fugue. +In other part stood one who, at the forge +Labouring, two massy clods of iron and brass +Had melted, (whether found where casual fire +Had wasted woods on mountain or in vale, +Down to the veins of earth; thence gliding hot +To some cave's mouth; or whether washed by stream +From underground;) the liquid ore he drained +Into fit moulds prepared; from which he formed +First his own tools; then, what might else be wrought +Fusil or graven in metal. After these, +But on the hither side, a different sort +From the high neighbouring hills, which was their seat, +Down to the plain descended; by their guise +Just men they seemed, and all their study bent +To worship God aright, and know his works +Not hid; nor those things last, which might preserve +Freedom and peace to Men; they on the plain +Long had not walked, when from the tents, behold! +A bevy of fair women, richly gay +In gems and wanton dress; to the harp they sung +Soft amorous ditties, and in dance came on: +The men, though grave, eyed them; and let their eyes +Rove without rein; till, in the amorous net +Fast caught, they liked; and each his liking chose; +And now of love they treat, till the evening-star, +Love's harbinger, appeared; then, all in heat +They light the nuptial torch, and bid invoke +Hymen, then first to marriage rites invoked: +With feast and musick all the tents resound. +Such happy interview, and fair event +Of love and youth not lost, songs, garlands, flowers, +And charming symphonies, attached the heart +Of Adam, soon inclined to admit delight, +The bent of nature; which he thus expressed. +True opener of mine eyes, prime Angel blest; +Much better seems this vision, and more hope +Of peaceful days portends, than those two past; +Those were of hate and death, or pain much worse; +Here Nature seems fulfilled in all her ends. +To whom thus Michael. Judge not what is best +By pleasure, though to nature seeming meet; +Created, as thou art, to nobler end +Holy and pure, conformity divine. +Those tents thou sawest so pleasant, were the tents +Of wickedness, wherein shall dwell his race +Who slew his brother; studious they appear +Of arts that polish life, inventers rare; +Unmindful of their Maker, though his Spirit +Taught them; but they his gifts acknowledged none. +Yet they a beauteous offspring shall beget; +For that fair female troop thou sawest, that seemed +Of Goddesses, so blithe, so smooth, so gay, +Yet empty of all good wherein consists +Woman's domestick honour and chief praise; +Bred only and completed to the taste +Of lustful appetence, to sing, to dance, +To dress, and troll the tongue, and roll the eye: +To these that sober race of men, whose lives +Religious titled them the sons of God, +Shall yield up all their virtue, all their fame +Ignobly, to the trains and to the smiles +Of these fair atheists; and now swim in joy, +Erelong to swim at large; and laugh, for which +The world erelong a world of tears must weep. +To whom thus Adam, of short joy bereft. +O pity and shame, that they, who to live well +Entered so fair, should turn aside to tread +Paths indirect, or in the mid way faint! +But still I see the tenour of Man's woe +Holds on the same, from Woman to begin. +From Man's effeminate slackness it begins, +Said the Angel, who should better hold his place +By wisdom, and superiour gifts received. +But now prepare thee for another scene. +He looked, and saw wide territory spread +Before him, towns, and rural works between; +Cities of men with lofty gates and towers, +Concourse in arms, fierce faces threatening war, +Giants of mighty bone and bold emprise; +Part wield their arms, part curb the foaming steed, +Single or in array of battle ranged +Both horse and foot, nor idly mustering stood; +One way a band select from forage drives +A herd of beeves, fair oxen and fair kine, +From a fat meadow ground; or fleecy flock, +Ewes and their bleating lambs over the plain, +Their booty; scarce with life the shepherds fly, +But call in aid, which makes a bloody fray; +With cruel tournament the squadrons join; +Where cattle pastured late, now scattered lies +With carcasses and arms the ensanguined field, +Deserted: Others to a city strong +Lay siege, encamped; by battery, scale, and mine, +Assaulting; others from the wall defend +With dart and javelin, stones, and sulphurous fire; +On each hand slaughter, and gigantick deeds. +In other part the sceptered heralds call +To council, in the city-gates; anon +Gray-headed men and grave, with warriours mixed, +Assemble, and harangues are heard; but soon, +In factious opposition; till at last, +Of middle age one rising, eminent +In wise deport, spake much of right and wrong, +Of justice, or religion, truth, and peace, +And judgement from above: him old and young +Exploded, and had seized with violent hands, +Had not a cloud descending snatched him thence +Unseen amid the throng: so violence +Proceeded, and oppression, and sword-law, +Through all the plain, and refuge none was found. +Adam was all in tears, and to his guide +Lamenting turned full sad; O!what are these, +Death's ministers, not men? who thus deal death +Inhumanly to men, and multiply +Ten thousandfold the sin of him who slew +His brother: for of whom such massacre +Make they, but of their brethren; men of men +But who was that just man, whom had not Heaven +Rescued, had in his righteousness been lost? +To whom thus Michael. These are the product +Of those ill-mated marriages thou sawest; +Where good with bad were matched, who of themselves +Abhor to join; and, by imprudence mixed, +Produce prodigious births of body or mind. +Such were these giants, men of high renown; +For in those days might only shall be admired, +And valour and heroick virtue called; +To overcome in battle, and subdue +Nations, and bring home spoils with infinite +Man-slaughter, shall be held the highest pitch +Of human glory; and for glory done +Of triumph, to be styled great conquerours +Patrons of mankind, Gods, and sons of Gods; +Destroyers rightlier called, and plagues of men. +Thus fame shall be achieved, renown on earth; +And what most merits fame, in silence hid. +But he, the seventh from thee, whom thou beheldst +The only righteous in a world preverse, +And therefore hated, therefore so beset +With foes, for daring single to be just, +And utter odious truth, that God would come +To judge them with his Saints; him the Most High +Rapt in a balmy cloud with winged steeds +Did, as thou sawest, receive, to walk with God +High in salvation and the climes of bliss, +Exempt from death; to show thee what reward +Awaits the good; the rest what punishment; +Which now direct thine eyes and soon behold. +He looked, and saw the face of things quite changed; +The brazen throat of war had ceased to roar; +All now was turned to jollity and game, +To luxury and riot, feast and dance; +Marrying or prostituting, as befel, +Rape or adultery, where passing fair +Allured them; thence from cups to civil broils. +At length a reverend sire among them came, +And of their doings great dislike declared, +And testified against their ways; he oft +Frequented their assemblies, whereso met, +Triumphs or festivals; and to them preached +Conversion and repentance, as to souls +In prison, under judgements imminent: +But all in vain: which when he saw, he ceased +Contending, and removed his tents far off; +Then, from the mountain hewing timber tall, +Began to build a vessel of huge bulk; +Measured by cubit, length, and breadth, and highth; +Smeared round with pitch; and in the side a door +Contrived; and of provisions laid in large, +For man and beast: when lo, a wonder strange! +Of every beast, and bird, and insect small, +Came sevens, and pairs; and entered in as taught +Their order: last the sire and his three sons, +With their four wives; and God made fast the door. +Mean while the south-wind rose, and, with black wings +Wide-hovering, all the clouds together drove +From under Heaven; the hills to their supply +Vapour, and exhalation dusk and moist, +Sent up amain; and now the thickened sky +Like a dark cieling stood; down rushed the rain +Impetuous; and continued, till the earth +No more was seen: the floating vessel swum +Uplifted, and secure with beaked prow +Rode tilting o'er the waves; all dwellings else +Flood overwhelmed, and them with all their pomp +Deep under water rolled; sea covered sea, +Sea without shore; and in their palaces, +Where luxury late reigned, sea-monsters whelped +And stabled; of mankind, so numerous late, +All left, in one small bottom swum imbarked. +How didst thou grieve then, Adam, to behold +The end of all thy offspring, end so sad, +Depopulation! Thee another flood, +Of tears and sorrow a flood, thee also drowned, +And sunk thee as thy sons; till, gently reared +By the Angel, on thy feet thou stoodest at last, +Though comfortless; as when a father mourns +His children, all in view destroyed at once; +And scarce to the Angel utter'dst thus thy plaint. +O visions ill foreseen! Better had I +Lived ignorant of future! so had borne +My part of evil only, each day's lot +Enough to bear; those now, that were dispensed +The burden of many ages, on me light +At once, by my foreknowledge gaining birth +Abortive, to torment me ere their being, +With thought that they must be. Let no man seek +Henceforth to be foretold, what shall befall +Him or his children; evil he may be sure, +Which neither his foreknowing can prevent; +And he the future evil shall no less +In apprehension than in substance feel, +Grievous to bear: but that care now is past, +Man is not whom to warn: those few escaped +Famine and anguish will at last consume, +Wandering that watery desart: I had hope, +When violence was ceased, and war on earth, +All would have then gone well; peace would have crowned +With length of happy days the race of Man; +But I was far deceived; for now I see +Peace to corrupt no less than war to waste. +How comes it thus? unfold, celestial Guide, +And whether here the race of Man will end. +To whom thus Michael. Those, whom last thou sawest +In triumph and luxurious wealth, are they +First seen in acts of prowess eminent +And great exploits, but of true virtue void; +Who, having spilt much blood, and done much wast +Subduing nations, and achieved thereby +Fame in the world, high titles, and rich prey; +Shall change their course to pleasure, ease, and sloth, +Surfeit, and lust; till wantonness and pride +Raise out of friendship hostile deeds in peace. +The conquered also, and enslaved by war, +Shall, with their freedom lost, all virtue lose +And fear of God; from whom their piety feigned +In sharp contest of battle found no aid +Against invaders; therefore, cooled in zeal, +Thenceforth shall practice how to live secure, +Worldly or dissolute, on what their lords +Shall leave them to enjoy; for the earth shall bear +More than enough, that temperance may be tried: +So all shall turn degenerate, all depraved; +Justice and temperance, truth and faith, forgot; +One man except, the only son of light +In a dark age, against example good, +Against allurement, custom, and a world +Offended: fearless of reproach and scorn, +The grand-child, with twelve sons encreased, departs +From Canaan, to a land hereafter called +Egypt, divided by the river Nile; +See where it flows, disgorging at seven mouths +Into the sea: To sojourn in that land +He comes, invited by a younger son +In time of dearth; a son, whose worthy deeds +Raise him to be the second in that realm +Of Pharaoh: There he dies, and leaves his race +Growing into a nation, and now grown +Suspected to a sequent king, who seeks +To stop their overgrowth, as inmate guests +Or violence, he of their wicked ways +Shall them admonish; and before them set +The paths of righteousness, how much more safe +And full of peace; denouncing wrath to come +On their impenitence; and shall return +Of them derided, but of God observed +The one just man alive; by his command +Shall build a wonderous ark, as thou beheldst, +To save himself, and houshold, from amidst +A world devote to universal wrack. +No sooner he, with them of man and beast +Select for life, shall in the ark be lodged, +And sheltered round; but all the cataracts +Of Heaven set open on the Earth shall pour +Rain, day and night; all fountains of the deep, +Broke up, shall heave the ocean to usurp +Beyond all bounds; till inundation rise +Above the highest hills: Then shall this mount +Of Paradise by might of waves be moved +Out of his place, pushed by the horned flood, +With all his verdure spoiled, and trees adrift, +Down the great river to the opening gulf, +And there take root an island salt and bare, +The haunt of seals, and orcs, and sea-mews' clang: +To teach thee that God attributes to place +No sanctity, if none be thither brought +By men who there frequent, or therein dwell. +And now, what further shall ensue, behold. +He looked, and saw the ark hull on the flood, +Which now abated; for the clouds were fled, +Driven by a keen north-wind, that, blowing dry, +Wrinkled the face of deluge, as decayed; +And the clear sun on his wide watery glass +Gazed hot, and of the fresh wave largely drew, +As after thirst; which made their flowing shrink +From standing lake to tripping ebb, that stole +With soft foot towards the deep; who now had stopt +His sluces, as the Heaven his windows shut. +The ark no more now floats, but seems on ground, +Fast on the top of some high mountain fixed. +And now the tops of hills, as rocks, appear; +With clamour thence the rapid currents drive, +Towards the retreating sea, their furious tide. +Forthwith from out the ark a raven flies, +And after him, the surer messenger, +A dove sent forth once and again to spy +Green tree or ground, whereon his foot may light: +The second time returning, in his bill +An olive-leaf he brings, pacifick sign: +Anon dry ground appears, and from his ark +The ancient sire descends, with all his train; +Then with uplifted hands, and eyes devout, +Grateful to Heaven, over his head beholds +A dewy cloud, and in the cloud a bow +Conspicuous with three lifted colours gay, +Betokening peace from God, and covenant new. +Whereat the heart of Adam, erst so sad, +Greatly rejoiced; and thus his joy broke forth. +O thou, who future things canst represent +As present, heavenly Instructer! I revive +At this last sight; assured that Man shall live, +With all the creatures, and their seed preserve. +Far less I now lament for one whole world +Of wicked sons destroyed, than I rejoice +For one man found so perfect, and so just, +That God vouchsafes to raise another world +From him, and all his anger to forget. +But say, what mean those coloured streaks in Heaven +Distended, as the brow of God appeased? +Or serve they, as a flowery verge, to bind +The fluid skirts of that same watery cloud, +Lest it again dissolve, and shower the earth? +To whom the Arch-Angel. Dextrously thou aimest; +So willingly doth God remit his ire, +Though late repenting him of Man depraved; +Grieved at his heart, when looking down he saw +The whole earth filled with violence, and all flesh +Corrupting each their way; yet, those removed, +Such grace shall one just man find in his sight, +That he relents, not to blot out mankind; +And makes a covenant never to destroy +The earth again by flood; nor let the sea +Surpass his bounds; nor rain to drown the world, +With man therein or beast; but, when he brings +Over the earth a cloud, will therein set +His triple-coloured bow, whereon to look, +And call to mind his covenant: Day and night, +Seed-time and harvest, heat and hoary frost, +Shall hold their course; till fire purge all things new, +Both Heaven and Earth, wherein the just shall dwell. + + + +Book XII + + +As one who in his journey bates at noon, +Though bent on speed; so here the Arch-Angel paused +Betwixt the world destroyed and world restored, +If Adam aught perhaps might interpose; +Then, with transition sweet, new speech resumes. +Thus thou hast seen one world begin, and end; +And Man, as from a second stock, proceed. +Much thou hast yet to see; but I perceive +Thy mortal sight to fail; objects divine +Must needs impair and weary human sense: +Henceforth what is to come I will relate; +Thou therefore give due audience, and attend. +This second source of Men, while yet but few, +And while the dread of judgement past remains +Fresh in their minds, fearing the Deity, +With some regard to what is just and right +Shall lead their lives, and multiply apace; +Labouring the soil, and reaping plenteous crop, +Corn, wine, and oil; and, from the herd or flock, +Oft sacrificing bullock, lamb, or kid, +With large wine-offerings poured, and sacred feast, +Shall spend their days in joy unblamed; and dwell +Long time in peace, by families and tribes, +Under paternal rule: till one shall rise +Of proud ambitious heart; who, not content +With fair equality, fraternal state, +Will arrogate dominion undeserved +Over his brethren, and quite dispossess +Concord and law of nature from the earth; +Hunting (and men not beasts shall be his game) +With war, and hostile snare, such as refuse +Subjection to his empire tyrannous: +A mighty hunter thence he shall be styled +Before the Lord; as in despite of Heaven, +Or from Heaven, claiming second sovranty; +And from rebellion shall derive his name, +Though of rebellion others he accuse. +He with a crew, whom like ambition joins +With him or under him to tyrannize, +Marching from Eden towards the west, shall find +The plain, wherein a black bituminous gurge +Boils out from under ground, the mouth of Hell: +Of brick, and of that stuff, they cast to build +A city and tower, whose top may reach to Heaven; +And get themselves a name; lest, far dispersed +In foreign lands, their memory be lost; +Regardless whether good or evil fame. +But God, who oft descends to visit men +Unseen, and through their habitations walks +To mark their doings, them beholding soon, +Comes down to see their city, ere the tower +Obstruct Heaven-towers, and in derision sets +Upon their tongues a various spirit, to rase +Quite out their native language; and, instead, +To sow a jangling noise of words unknown: +Forthwith a hideous gabble rises loud, +Among the builders; each to other calls +Not understood; till hoarse, and all in rage, +As mocked they storm: great laughter was in Heaven, +And looking down, to see the hubbub strange, +And hear the din: Thus was the building left +Ridiculous, and the work Confusion named. +Whereto thus Adam, fatherly displeased. +O execrable son! so to aspire +Above his brethren; to himself assuming +Authority usurped, from God not given: +He gave us only over beast, fish, fowl, +Dominion absolute; that right we hold +By his donation; but man over men +He made not lord; such title to himself +Reserving, human left from human free. +But this usurper his encroachment proud +Stays not on Man; to God his tower intends +Siege and defiance: Wretched man!what food +Will he convey up thither, to sustain +Himself and his rash army; where thin air +Above the clouds will pine his entrails gross, +And famish him of breath, if not of bread? +To whom thus Michael. Justly thou abhorrest +That son, who on the quiet state of men +Such trouble brought, affecting to subdue +Rational liberty; yet know withal, +Since thy original lapse, true liberty +Is lost, which always with right reason dwells +Twinned, and from her hath no dividual being: +Reason in man obscured, or not obeyed, +Immediately inordinate desires, +And upstart passions, catch the government +From reason; and to servitude reduce +Man, till then free. Therefore, since he permits +Within himself unworthy powers to reign +Over free reason, God, in judgement just, +Subjects him from without to violent lords; +Who oft as undeservedly enthrall +His outward freedom: Tyranny must be; +Though to the tyrant thereby no excuse. +Yet sometimes nations will decline so low +From virtue, which is reason, that no wrong, +But justice, and some fatal curse annexed, +Deprives them of their outward liberty; +Their inward lost: Witness the irreverent son +Of him who built the ark; who, for the shame +Done to his father, heard this heavy curse, +Servant of servants, on his vicious race. +Thus will this latter, as the former world, +Still tend from bad to worse; till God at last, +Wearied with their iniquities, withdraw +His presence from among them, and avert +His holy eyes; resolving from thenceforth +To leave them to their own polluted ways; +And one peculiar nation to select +From all the rest, of whom to be invoked, +A nation from one faithful man to spring: +Him on this side Euphrates yet residing, +Bred up in idol-worship: O, that men +(Canst thou believe?) should be so stupid grown, +While yet the patriarch lived, who 'scaped the flood, +As to forsake the living God, and fall +To worship their own work in wood and stone +For Gods! Yet him God the Most High vouchsafes +To call by vision, from his father's house, +His kindred, and false Gods, into a land +Which he will show him; and from him will raise +A mighty nation; and upon him shower +His benediction so, that in his seed +All nations shall be blest: he straight obeys; +Not knowing to what land, yet firm believes: +I see him, but thou canst not, with what faith +He leaves his Gods, his friends, and native soil, +Ur of Chaldaea, passing now the ford +To Haran; after him a cumbrous train +Of herds and flocks, and numerous servitude; +Not wandering poor, but trusting all his wealth +With God, who called him, in a land unknown. +Canaan he now attains; I see his tents +Pitched about Sechem, and the neighbouring plain +Of Moreh; there by promise he receives +Gift to his progeny of all that land, +From Hameth northward to the Desart south; +(Things by their names I call, though yet unnamed;) +From Hermon east to the great western Sea; +Mount Hermon, yonder sea; each place behold +In prospect, as I point them; on the shore +Mount Carmel; here, the double-founted stream, +Jordan, true limit eastward; but his sons +Shall dwell to Senir, that long ridge of hills. +This ponder, that all nations of the earth +Shall in his seed be blessed: By that seed +Is meant thy great Deliverer, who shall bruise +The Serpent's head; whereof to thee anon +Plainlier shall be revealed. This patriarch blest, +Whom faithful Abraham due time shall call, +A son, and of his son a grand-child, leaves; +Like him in faith, in wisdom, and renown: +The grandchild, with twelve sons increased, departs +From Canaan to a land hereafter called +Egypt, divided by the river Nile +See where it flows, disgorging at seven mouths +Into the sea. To sojourn in that land +He comes, invited by a younger son +In time of dearth, a son whose worthy deeds +Raise him to be the second in that realm +Of Pharaoh. There he dies, and leaves his race +Growing into a nation, and now grown +Suspected to a sequent king, who seeks +To stop their overgrowth, as inmate guests +Too numerous; whence of guests he makes them slaves +Inhospitably, and kills their infant males: +Till by two brethren (these two brethren call +Moses and Aaron) sent from God to claim +His people from enthralment, they return, +With glory and spoil, back to their promised land. +But first, the lawless tyrant, who denies +To know their God, or message to regard, +Must be compelled by signs and judgements dire; +To blood unshed the rivers must be turned; +Frogs, lice, and flies, must all his palace fill +With loathed intrusion, and fill all the land; +His cattle must of rot and murren die; +Botches and blains must all his flesh emboss, +And all his people; thunder mixed with hail, +Hail mixed with fire, must rend the Egyptians sky, +And wheel on the earth, devouring where it rolls; +What it devours not, herb, or fruit, or grain, +A darksome cloud of locusts swarming down +Must eat, and on the ground leave nothing green; +Darkness must overshadow all his bounds, +Palpable darkness, and blot out three days; +Last, with one midnight stroke, all the first-born +Of Egypt must lie dead. Thus with ten wounds +The river-dragon tamed at length submits +To let his sojourners depart, and oft +Humbles his stubborn heart; but still, as ice +More hardened after thaw; till, in his rage +Pursuing whom he late dismissed, the sea +Swallows him with his host; but them lets pass, +As on dry land, between two crystal walls; +Awed by the rod of Moses so to stand +Divided, till his rescued gain their shore: +Such wondrous power God to his saint will lend, +Though present in his Angel; who shall go +Before them in a cloud, and pillar of fire; +By day a cloud, by night a pillar of fire; +To guide them in their journey, and remove +Behind them, while the obdurate king pursues: +All night he will pursue; but his approach +Darkness defends between till morning watch; +Then through the fiery pillar, and the cloud, +God looking forth will trouble all his host, +And craze their chariot-wheels: when by command +Moses once more his potent rod extends +Over the sea; the sea his rod obeys; +On their embattled ranks the waves return, +And overwhelm their war: The race elect +Safe toward Canaan from the shore advance +Through the wild Desart, not the readiest way; +Lest, entering on the Canaanite alarmed, +War terrify them inexpert, and fear +Return them back to Egypt, choosing rather +Inglorious life with servitude; for life +To noble and ignoble is more sweet +Untrained in arms, where rashness leads not on. +This also shall they gain by their delay +In the wide wilderness; there they shall found +Their government, and their great senate choose +Through the twelve tribes, to rule by laws ordained: +God from the mount of Sinai, whose gray top +Shall tremble, he descending, will himself +In thunder, lightning, and loud trumpets' sound, +Ordain them laws; part, such as appertain +To civil justice; part, religious rites +Of sacrifice; informing them, by types +And shadows, of that destined Seed to bruise +The Serpent, by what means he shall achieve +Mankind's deliverance. But the voice of God +To mortal ear is dreadful: They beseech +That Moses might report to them his will, +And terrour cease; he grants what they besought, +Instructed that to God is no access +Without Mediator, whose high office now +Moses in figure bears; to introduce +One greater, of whose day he shall foretel, +And all the Prophets in their age the times +Of great Messiah shall sing. Thus, laws and rites +Established, such delight hath God in Men +Obedient to his will, that he vouchsafes +Among them to set up his tabernacle; +The Holy One with mortal Men to dwell: +By his prescript a sanctuary is framed +Of cedar, overlaid with gold; therein +An ark, and in the ark his testimony, +The records of his covenant; over these +A mercy-seat of gold, between the wings +Of two bright Cherubim; before him burn +Seven lamps as in a zodiack representing +The heavenly fires; over the tent a cloud +Shall rest by day, a fiery gleam by night; +Save when they journey, and at length they come, +Conducted by his Angel, to the land +Promised to Abraham and his seed:--The rest +Were long to tell; how many battles fought +How many kings destroyed; and kingdoms won; +Or how the sun shall in mid Heaven stand still +A day entire, and night's due course adjourn, +Man's voice commanding, 'Sun, in Gibeon stand, +'And thou moon in the vale of Aialon, +'Till Israel overcome! so call the third +From Abraham, son of Isaac; and from him +His whole descent, who thus shall Canaan win. +Here Adam interposed. O sent from Heaven, +Enlightener of my darkness, gracious things +Thou hast revealed; those chiefly, which concern +Just Abraham and his seed: now first I find +Mine eyes true-opening, and my heart much eased; +Erewhile perplexed with thoughts, what would become +Of me and all mankind: But now I see +His day, in whom all nations shall be blest; +Favour unmerited by me, who sought +Forbidden knowledge by forbidden means. +This yet I apprehend not, why to those +Among whom God will deign to dwell on earth +So many and so various laws are given; +So many laws argue so many sins +Among them; how can God with such reside? +To whom thus Michael. Doubt not but that sin +Will reign among them, as of thee begot; +And therefore was law given them, to evince +Their natural pravity, by stirring up +Sin against law to fight: that when they see +Law can discover sin, but not remove, +Save by those shadowy expiations weak, +The blood of bulls and goats, they may conclude +Some blood more precious must be paid for Man; +Just for unjust; that, in such righteousness +To them by faith imputed, they may find +Justification towards God, and peace +Of conscience; which the law by ceremonies +Cannot appease; nor Man the mortal part +Perform; and, not performing, cannot live. +So law appears imperfect; and but given +With purpose to resign them, in full time, +Up to a better covenant; disciplined +From shadowy types to truth; from flesh to spirit; +From imposition of strict laws to free +Acceptance of large grace; from servile fear +To filial; works of law to works of faith. +And therefore shall not Moses, though of God +Highly beloved, being but the minister +Of law, his people into Canaan lead; +But Joshua, whom the Gentiles Jesus call, +His name and office bearing, who shall quell +The adversary-Serpent, and bring back +Through the world's wilderness long-wandered Man +Safe to eternal Paradise of rest. +Mean while they, in their earthly Canaan placed, +Long time shall dwell and prosper, but when sins +National interrupt their publick peace, +Provoking God to raise them enemies; +From whom as oft he saves them penitent +By Judges first, then under Kings; of whom +The second, both for piety renowned +And puissant deeds, a promise shall receive +Irrevocable, that his regal throne +For ever shall endure; the like shall sing +All Prophecy, that of the royal stock +Of David (so I name this king) shall rise +A Son, the Woman's seed to thee foretold, +Foretold to Abraham, as in whom shall trust +All nations; and to kings foretold, of kings +The last; for of his reign shall be no end. +But first, a long succession must ensue; +And his next son, for wealth and wisdom famed, +The clouded ark of God, till then in tents +Wandering, shall in a glorious temple enshrine. +Such follow him, as shall be registered +Part good, part bad; of bad the longer scroll; +Whose foul idolatries, and other faults +Heaped to the popular sum, will so incense +God, as to leave them, and expose their land, +Their city, his temple, and his holy ark, +With all his sacred things, a scorn and prey +To that proud city, whose high walls thou sawest +Left in confusion; Babylon thence called. +There in captivity he lets them dwell +The space of seventy years; then brings them back, +Remembering mercy, and his covenant sworn +To David, stablished as the days of Heaven. +Returned from Babylon by leave of kings +Their lords, whom God disposed, the house of God +They first re-edify; and for a while +In mean estate live moderate; till, grown +In wealth and multitude, factious they grow; +But first among the priests dissention springs, +Men who attend the altar, and should most +Endeavour peace: their strife pollution brings +Upon the temple itself: at last they seise +The scepter, and regard not David's sons; +Then lose it to a stranger, that the true +Anointed King Messiah might be born +Barred of his right; yet at his birth a star, +Unseen before in Heaven, proclaims him come; +And guides the eastern sages, who inquire +His place, to offer incense, myrrh, and gold: +His place of birth a solemn Angel tells +To simple shepherds, keeping watch by night; +They gladly thither haste, and by a quire +Of squadroned Angels hear his carol sung. +A virgin is his mother, but his sire +The power of the Most High: He shall ascend +The throne hereditary, and bound his reign +With Earth's wide bounds, his glory with the Heavens. +He ceased, discerning Adam with such joy +Surcharged, as had like grief been dewed in tears, +Without the vent of words; which these he breathed. +O prophet of glad tidings, finisher +Of utmost hope! now clear I understand +What oft my steadiest thoughts have searched in vain; +Why our great Expectation should be called +The seed of Woman: Virgin Mother, hail, +High in the love of Heaven; yet from my loins +Thou shalt proceed, and from thy womb the Son +Of God Most High: so God with Man unites! +Needs must the Serpent now his capital bruise +Expect with mortal pain: Say where and when +Their fight, what stroke shall bruise the victor's heel. +To whom thus Michael. Dream not of their fight, +As of a duel, or the local wounds +Of head or heel: Not therefore joins the Son +Manhood to Godhead, with more strength to foil +Thy enemy; nor so is overcome +Satan, whose fall from Heaven, a deadlier bruise, +Disabled, not to give thee thy death's wound: +Which he, who comes thy Saviour, shall recure, +Not by destroying Satan, but his works +In thee, and in thy seed: Nor can this be, +But by fulfilling that which thou didst want, +Obedience to the law of God, imposed +On penalty of death, and suffering death; +The penalty to thy transgression due, +And due to theirs which out of thine will grow: +So only can high Justice rest appaid. +The law of God exact he shall fulfil +Both by obedience and by love, though love +Alone fulfil the law; thy punishment +He shall endure, by coming in the flesh +To a reproachful life, and cursed death; +Proclaiming life to all who shall believe +In his redemption; and that his obedience, +Imputed, becomes theirs by faith; his merits +To save them, not their own, though legal, works. +For this he shall live hated, be blasphemed, +Seised on by force, judged, and to death condemned +A shameful and accursed, nailed to the cross +By his own nation; slain for bringing life: +But to the cross he nails thy enemies, +The law that is against thee, and the sins +Of all mankind, with him there crucified, +Never to hurt them more who rightly trust +In this his satisfaction; so he dies, +But soon revives; Death over him no power +Shall long usurp; ere the third dawning light +Return, the stars of morn shall see him rise +Out of his grave, fresh as the dawning light, +Thy ransom paid, which Man from death redeems, +His death for Man, as many as offered life +Neglect not, and the benefit embrace +By faith not void of works: This God-like act +Annuls thy doom, the death thou shouldest have died, +In sin for ever lost from life; this act +Shall bruise the head of Satan, crush his strength, +Defeating Sin and Death, his two main arms; +And fix far deeper in his head their stings +Than temporal death shall bruise the victor's heel, +Or theirs whom he redeems; a death, like sleep, +A gentle wafting to immortal life. +Nor after resurrection shall he stay +Longer on earth, than certain times to appear +To his disciples, men who in his life +Still followed him; to them shall leave in charge +To teach all nations what of him they learned +And his salvation; them who shall believe +Baptizing in the profluent stream, the sign +Of washing them from guilt of sin to life +Pure, and in mind prepared, if so befall, +For death, like that which the Redeemer died. +All nations they shall teach; for, from that day, +Not only to the sons of Abraham's loins +Salvation shall be preached, but to the sons +Of Abraham's faith wherever through the world; +So in his seed all nations shall be blest. +Then to the Heaven of Heavens he shall ascend +With victory, triumphing through the air +Over his foes and thine; there shall surprise +The Serpent, prince of air, and drag in chains +Through all his realm, and there confounded leave; +Then enter into glory, and resume +His seat at God's right hand, exalted high +Above all names in Heaven; and thence shall come, +When this world's dissolution shall be ripe, +With glory and power to judge both quick and dead; +To judge the unfaithful dead, but to reward +His faithful, and receive them into bliss, +Whether in Heaven or Earth; for then the Earth +Shall all be Paradise, far happier place +Than this of Eden, and far happier days. +So spake the Arch-Angel Michael; then paused, +As at the world's great period; and our sire, +Replete with joy and wonder, thus replied. +O Goodness infinite, Goodness immense! +That all this good of evil shall produce, +And evil turn to good; more wonderful +Than that which by creation first brought forth +Light out of darkness! Full of doubt I stand, +Whether I should repent me now of sin +By me done, and occasioned; or rejoice +Much more, that much more good thereof shall spring; +To God more glory, more good-will to Men +From God, and over wrath grace shall abound. +But say, if our Deliverer up to Heaven +Must re-ascend, what will betide the few +His faithful, left among the unfaithful herd, +The enemies of truth? Who then shall guide +His people, who defend? Will they not deal +Worse with his followers than with him they dealt? +Be sure they will, said the Angel; but from Heaven +He to his own a Comforter will send, +The promise of the Father, who shall dwell +His Spirit within them; and the law of faith, +Working through love, upon their hearts shall write, +To guide them in all truth; and also arm +With spiritual armour, able to resist +Satan's assaults, and quench his fiery darts; +What man can do against them, not afraid, +Though to the death; against such cruelties +With inward consolations recompensed, +And oft supported so as shall amaze +Their proudest persecutors: For the Spirit, +Poured first on his Apostles, whom he sends +To evangelize the nations, then on all +Baptized, shall them with wonderous gifts endue +To speak all tongues, and do all miracles, +As did their Lord before them. Thus they win +Great numbers of each nation to receive +With joy the tidings brought from Heaven: At length +Their ministry performed, and race well run, +Their doctrine and their story written left, +They die; but in their room, as they forewarn, +Wolves shall succeed for teachers, grievous wolves, +Who all the sacred mysteries of Heaven +To their own vile advantages shall turn +Of lucre and ambition; and the truth +With superstitions and traditions taint, +Left only in those written records pure, +Though not but by the Spirit understood. +Then shall they seek to avail themselves of names, +Places, and titles, and with these to join +Secular power; though feigning still to act +By spiritual, to themselves appropriating +The Spirit of God, promised alike and given +To all believers; and, from that pretence, +Spiritual laws by carnal power shall force +On every conscience; laws which none shall find +Left them inrolled, or what the Spirit within +Shall on the heart engrave. What will they then +But force the Spirit of Grace itself, and bind +His consort Liberty? what, but unbuild +His living temples, built by faith to stand, +Their own faith, not another's? for, on earth, +Who against faith and conscience can be heard +Infallible? yet many will presume: +Whence heavy persecution shall arise +On all, who in the worship persevere +Of spirit and truth; the rest, far greater part, +Will deem in outward rites and specious forms +Religion satisfied; Truth shall retire +Bestuck with slanderous darts, and works of faith +Rarely be found: So shall the world go on, +To good malignant, to bad men benign; +Under her own weight groaning; till the day +Appear of respiration to the just, +And vengeance to the wicked, at return +Of him so lately promised to thy aid, +The Woman's Seed; obscurely then foretold, +Now ampler known thy Saviour and thy Lord; +Last, in the clouds, from Heaven to be revealed +In glory of the Father, to dissolve +Satan with his perverted world; then raise +From the conflagrant mass, purged and refined, +New Heavens, new Earth, ages of endless date, +Founded in righteousness, and peace, and love; +To bring forth fruits, joy and eternal bliss. +He ended; and thus Adam last replied. +How soon hath thy prediction, Seer blest, +Measured this transient world, the race of time, +Till time stand fixed! Beyond is all abyss, +Eternity, whose end no eye can reach. +Greatly-instructed I shall hence depart; +Greatly in peace of thought; and have my fill +Of knowledge, what this vessel can contain; +Beyond which was my folly to aspire. +Henceforth I learn, that to obey is best, +And love with fear the only God; to walk +As in his presence; ever to observe +His providence; and on him sole depend, +Merciful over all his works, with good +Still overcoming evil, and by small +Accomplishing great things, by things deemed weak +Subverting worldly strong, and worldly wise +By simply meek: that suffering for truth's sake +Is fortitude to highest victory, +And, to the faithful, death the gate of life; +Taught this by his example, whom I now +Acknowledge my Redeemer ever blest. +To whom thus also the Angel last replied. +This having learned, thou hast attained the sum +Of wisdom; hope no higher, though all the stars +Thou knewest by name, and all the ethereal powers, +All secrets of the deep, all Nature's works, +Or works of God in Heaven, air, earth, or sea, +And all the riches of this world enjoyedst, +And all the rule, one empire; only add +Deeds to thy knowledge answerable; add faith, +Add virtue, patience, temperance; add love, +By name to come called charity, the soul +Of all the rest: then wilt thou not be loth +To leave this Paradise, but shalt possess +A Paradise within thee, happier far.-- +Let us descend now therefore from this top +Of speculation; for the hour precise +Exacts our parting hence; and see!the guards, +By me encamped on yonder hill, expect +Their motion; at whose front a flaming sword, +In signal of remove, waves fiercely round: +We may no longer stay: go, waken Eve; +Her also I with gentle dreams have calmed +Portending good, and all her spirits composed +To meek submission: thou, at season fit, +Let her with thee partake what thou hast heard; +Chiefly what may concern her faith to know, +The great deliverance by her seed to come +(For by the Woman's seed) on all mankind: +That ye may live, which will be many days, +Both in one faith unanimous, though sad, +With cause, for evils past; yet much more cheered +With meditation on the happy end. +He ended, and they both descend the hill; +Descended, Adam to the bower, where Eve +Lay sleeping, ran before; but found her waked; +And thus with words not sad she him received. +Whence thou returnest, and whither wentest, I know; +For God is also in sleep; and dreams advise, +Which he hath sent propitious, some great good +Presaging, since with sorrow and heart's distress +Wearied I fell asleep: But now lead on; +In me is no delay; with thee to go, +Is to stay here; without thee here to stay, +Is to go hence unwilling; thou to me +Art all things under $Heaven, all places thou, +Who for my wilful crime art banished hence. +This further consolation yet secure +I carry hence; though all by me is lost, +Such favour I unworthy am vouchsafed, +By me the Promised Seed shall all restore. +So spake our mother Eve; and Adam heard +Well pleased, but answered not: For now, too nigh +The Arch-Angel stood; and, from the other hill +To their fixed station, all in bright array +The Cherubim descended; on the ground +Gliding meteorous, as evening-mist +Risen from a river o'er the marish glides, +And gathers ground fast at the labourer's heel +Homeward returning. High in front advanced, +The brandished sword of God before them blazed, +Fierce as a comet; which with torrid heat, +And vapour as the Libyan air adust, +Began to parch that temperate clime; whereat +In either hand the hastening Angel caught +Our lingering parents, and to the eastern gate +Led them direct, and down the cliff as fast +To the subjected plain; then disappeared. +They, looking back, all the eastern side beheld +Of Paradise, so late their happy seat, +Waved over by that flaming brand; the gate +With dreadful faces thronged, and fiery arms: +Some natural tears they dropt, but wiped them soon; +The world was all before them, where to choose +Their place of rest, and Providence their guide: +They, hand in hand, with wandering steps and slow, +Through Eden took their solitary way. + +[The End] diff --git a/web/server/h2o/libh2o/deps/brotli/tests/testdata/plrabn12.txt.compressed b/web/server/h2o/libh2o/deps/brotli/tests/testdata/plrabn12.txt.compressed new file mode 100644 index 00000000..1750fa5c Binary files /dev/null and b/web/server/h2o/libh2o/deps/brotli/tests/testdata/plrabn12.txt.compressed differ diff --git a/web/server/h2o/libh2o/deps/brotli/tests/testdata/quickfox b/web/server/h2o/libh2o/deps/brotli/tests/testdata/quickfox new file mode 100644 index 00000000..ff3bb639 --- /dev/null +++ b/web/server/h2o/libh2o/deps/brotli/tests/testdata/quickfox @@ -0,0 +1 @@ +The quick brown fox jumps over the lazy dog \ No newline at end of file diff --git a/web/server/h2o/libh2o/deps/brotli/tests/testdata/quickfox.compressed b/web/server/h2o/libh2o/deps/brotli/tests/testdata/quickfox.compressed new file mode 100644 index 00000000..b5deebc4 --- /dev/null +++ b/web/server/h2o/libh2o/deps/brotli/tests/testdata/quickfox.compressed @@ -0,0 +1 @@ + €The quick brown fox jumps over the lazy dog \ No newline at end of file diff --git a/web/server/h2o/libh2o/deps/brotli/tests/testdata/quickfox_repeated b/web/server/h2o/libh2o/deps/brotli/tests/testdata/quickfox_repeated new file mode 100644 index 00000000..2ed134eb --- /dev/null +++ b/web/server/h2o/libh2o/deps/brotli/tests/testdata/quickfox_repeated @@ -0,0 +1 @@ +The quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dog \ No newline at end of file diff --git a/web/server/h2o/libh2o/deps/brotli/tests/testdata/quickfox_repeated.compressed b/web/server/h2o/libh2o/deps/brotli/tests/testdata/quickfox_repeated.compressed new file mode 100644 index 00000000..f9d79767 --- /dev/null +++ b/web/server/h2o/libh2o/deps/brotli/tests/testdata/quickfox_repeated.compressed @@ -0,0 +1,2 @@ +[ÿ¯À"y\ûZŒB;ô%UZ’™±5Èžž +{K¹<˜È @óæÙMäme'‡_¦é0–{<ØS \ No newline at end of file diff --git a/web/server/h2o/libh2o/deps/brotli/tests/testdata/random_chunks b/web/server/h2o/libh2o/deps/brotli/tests/testdata/random_chunks new file mode 100644 index 00000000..c014f0b3 Binary files /dev/null and b/web/server/h2o/libh2o/deps/brotli/tests/testdata/random_chunks differ diff --git a/web/server/h2o/libh2o/deps/brotli/tests/testdata/random_org_10k.bin b/web/server/h2o/libh2o/deps/brotli/tests/testdata/random_org_10k.bin new file mode 100644 index 00000000..faf8a3a7 Binary files /dev/null and b/web/server/h2o/libh2o/deps/brotli/tests/testdata/random_org_10k.bin differ diff --git a/web/server/h2o/libh2o/deps/brotli/tests/testdata/random_org_10k.bin.compressed b/web/server/h2o/libh2o/deps/brotli/tests/testdata/random_org_10k.bin.compressed new file mode 100644 index 00000000..5ffbaa04 Binary files /dev/null and b/web/server/h2o/libh2o/deps/brotli/tests/testdata/random_org_10k.bin.compressed differ diff --git a/web/server/h2o/libh2o/deps/brotli/tests/testdata/ukkonooa b/web/server/h2o/libh2o/deps/brotli/tests/testdata/ukkonooa new file mode 100644 index 00000000..1072b69b --- /dev/null +++ b/web/server/h2o/libh2o/deps/brotli/tests/testdata/ukkonooa @@ -0,0 +1 @@ +ukko nooa, ukko nooa oli kunnon mies, kun han meni saunaan, pisti laukun naulaan, ukko nooa, ukko nooa oli kunnon mies. \ No newline at end of file diff --git a/web/server/h2o/libh2o/deps/brotli/tests/testdata/ukkonooa.compressed b/web/server/h2o/libh2o/deps/brotli/tests/testdata/ukkonooa.compressed new file mode 100644 index 00000000..f39f068d Binary files /dev/null and b/web/server/h2o/libh2o/deps/brotli/tests/testdata/ukkonooa.compressed differ diff --git a/web/server/h2o/libh2o/deps/brotli/tests/testdata/x b/web/server/h2o/libh2o/deps/brotli/tests/testdata/x new file mode 100644 index 00000000..500c0709 --- /dev/null +++ b/web/server/h2o/libh2o/deps/brotli/tests/testdata/x @@ -0,0 +1 @@ +X \ No newline at end of file diff --git a/web/server/h2o/libh2o/deps/brotli/tests/testdata/x.compressed b/web/server/h2o/libh2o/deps/brotli/tests/testdata/x.compressed new file mode 100644 index 00000000..2a44b5de Binary files /dev/null and b/web/server/h2o/libh2o/deps/brotli/tests/testdata/x.compressed differ diff --git a/web/server/h2o/libh2o/deps/brotli/tests/testdata/x.compressed.00 b/web/server/h2o/libh2o/deps/brotli/tests/testdata/x.compressed.00 new file mode 100644 index 00000000..33e3a98e Binary files /dev/null and b/web/server/h2o/libh2o/deps/brotli/tests/testdata/x.compressed.00 differ diff --git a/web/server/h2o/libh2o/deps/brotli/tests/testdata/x.compressed.01 b/web/server/h2o/libh2o/deps/brotli/tests/testdata/x.compressed.01 new file mode 100644 index 00000000..9c8249b1 Binary files /dev/null and b/web/server/h2o/libh2o/deps/brotli/tests/testdata/x.compressed.01 differ diff --git a/web/server/h2o/libh2o/deps/brotli/tests/testdata/x.compressed.02 b/web/server/h2o/libh2o/deps/brotli/tests/testdata/x.compressed.02 new file mode 100644 index 00000000..3a5890db Binary files /dev/null and b/web/server/h2o/libh2o/deps/brotli/tests/testdata/x.compressed.02 differ diff --git a/web/server/h2o/libh2o/deps/brotli/tests/testdata/x.compressed.03 b/web/server/h2o/libh2o/deps/brotli/tests/testdata/x.compressed.03 new file mode 100644 index 00000000..842e7995 Binary files /dev/null and b/web/server/h2o/libh2o/deps/brotli/tests/testdata/x.compressed.03 differ diff --git a/web/server/h2o/libh2o/deps/brotli/tests/testdata/xyzzy b/web/server/h2o/libh2o/deps/brotli/tests/testdata/xyzzy new file mode 100644 index 00000000..fbfb23d1 --- /dev/null +++ b/web/server/h2o/libh2o/deps/brotli/tests/testdata/xyzzy @@ -0,0 +1 @@ +Xyzzy \ No newline at end of file diff --git a/web/server/h2o/libh2o/deps/brotli/tests/testdata/xyzzy.compressed b/web/server/h2o/libh2o/deps/brotli/tests/testdata/xyzzy.compressed new file mode 100644 index 00000000..e6982cef --- /dev/null +++ b/web/server/h2o/libh2o/deps/brotli/tests/testdata/xyzzy.compressed @@ -0,0 +1 @@ + €Xyzzy \ No newline at end of file diff --git a/web/server/h2o/libh2o/deps/brotli/tests/testdata/zeros b/web/server/h2o/libh2o/deps/brotli/tests/testdata/zeros new file mode 100644 index 00000000..6d23118f Binary files /dev/null and b/web/server/h2o/libh2o/deps/brotli/tests/testdata/zeros differ diff --git a/web/server/h2o/libh2o/deps/brotli/tests/testdata/zeros.compressed b/web/server/h2o/libh2o/deps/brotli/tests/testdata/zeros.compressed new file mode 100644 index 00000000..bf05b53c Binary files /dev/null and b/web/server/h2o/libh2o/deps/brotli/tests/testdata/zeros.compressed differ diff --git a/web/server/h2o/libh2o/deps/brotli/tools/Makefile b/web/server/h2o/libh2o/deps/brotli/tools/Makefile new file mode 100644 index 00000000..6b46ad88 --- /dev/null +++ b/web/server/h2o/libh2o/deps/brotli/tools/Makefile @@ -0,0 +1,25 @@ +#brotli/tools + +include ../shared.mk + +BROTLI = .. +ENCOBJ = $(BROTLI)/enc/*.o +DECOBJ = $(BROTLI)/dec/*.o + +EXECUTABLES=bro + +EXE_OBJS=$(patsubst %, %.o, $(EXECUTABLES)) + +all : $(EXECUTABLES) + +$(EXECUTABLES) : $(EXE_OBJS) deps + $(CXX) $(LDFLAGS) $(ENCOBJ) $(DECOBJ) $@.o -o $@ + +deps : + $(MAKE) -C $(BROTLI)/dec + $(MAKE) -C $(BROTLI)/enc nodict + +clean : + rm -f $(OBJS) $(EXE_OBJS) $(EXECUTABLES) + $(MAKE) -C $(BROTLI)/dec clean + $(MAKE) -C $(BROTLI)/enc clean diff --git a/web/server/h2o/libh2o/deps/brotli/tools/bro.cc b/web/server/h2o/libh2o/deps/brotli/tools/bro.cc new file mode 100644 index 00000000..635751c8 --- /dev/null +++ b/web/server/h2o/libh2o/deps/brotli/tools/bro.cc @@ -0,0 +1,303 @@ +/* Copyright 2014 Google Inc. All Rights Reserved. + + Distributed under MIT license. + See file LICENSE for detail or copy at https://opensource.org/licenses/MIT +*/ + +/* Example main() function for Brotli library. */ + +#include +#include +#include +#include +#include + +#include +#include + +#include "../dec/decode.h" +#include "../enc/encode.h" + + +static bool ParseQuality(const char* s, int* quality) { + if (s[0] >= '0' && s[0] <= '9') { + *quality = s[0] - '0'; + if (s[1] >= '0' && s[1] <= '9') { + *quality = *quality * 10 + s[1] - '0'; + return s[2] == 0; + } + return s[1] == 0; + } + return false; +} + +static void ParseArgv(int argc, char **argv, + char **input_path, + char **output_path, + int *force, + int *quality, + int *decompress, + int *repeat, + int *verbose, + int *lgwin) { + *force = 0; + *input_path = 0; + *output_path = 0; + *repeat = 1; + *verbose = 0; + *lgwin = 22; + { + size_t argv0_len = strlen(argv[0]); + *decompress = + argv0_len >= 5 && strcmp(&argv[0][argv0_len - 5], "unbro") == 0; + } + for (int k = 1; k < argc; ++k) { + if (!strcmp("--force", argv[k]) || + !strcmp("-f", argv[k])) { + if (*force != 0) { + goto error; + } + *force = 1; + continue; + } else if (!strcmp("--decompress", argv[k]) || + !strcmp("--uncompress", argv[k]) || + !strcmp("-d", argv[k])) { + *decompress = 1; + continue; + } else if (!strcmp("--verbose", argv[k]) || + !strcmp("-v", argv[k])) { + if (*verbose != 0) { + goto error; + } + *verbose = 1; + continue; + } + if (k < argc - 1) { + if (!strcmp("--input", argv[k]) || + !strcmp("--in", argv[k]) || + !strcmp("-i", argv[k])) { + if (*input_path != 0) { + goto error; + } + *input_path = argv[k + 1]; + ++k; + continue; + } else if (!strcmp("--output", argv[k]) || + !strcmp("--out", argv[k]) || + !strcmp("-o", argv[k])) { + if (*output_path != 0) { + goto error; + } + *output_path = argv[k + 1]; + ++k; + continue; + } else if (!strcmp("--quality", argv[k]) || + !strcmp("-q", argv[k])) { + if (!ParseQuality(argv[k + 1], quality)) { + goto error; + } + ++k; + continue; + } else if (!strcmp("--repeat", argv[k]) || + !strcmp("-r", argv[k])) { + if (!ParseQuality(argv[k + 1], repeat)) { + goto error; + } + ++k; + continue; + } else if (!strcmp("--window", argv[k]) || + !strcmp("-w", argv[k])) { + if (!ParseQuality(argv[k + 1], lgwin)) { + goto error; + } + if (*lgwin < 10 || *lgwin >= 25) { + goto error; + } + ++k; + continue; + } + } + goto error; + } + return; +error: + fprintf(stderr, + "Usage: %s [--force] [--quality n] [--decompress]" + " [--input filename] [--output filename] [--repeat iters]" + " [--verbose] [--window n]\n", + argv[0]); + exit(1); +} + +static FILE* OpenInputFile(const char* input_path) { + if (input_path == 0) { + return fdopen(STDIN_FILENO, "rb"); + } + FILE* f = fopen(input_path, "rb"); + if (f == 0) { + perror("fopen"); + exit(1); + } + return f; +} + +static FILE *OpenOutputFile(const char *output_path, const int force) { + if (output_path == 0) { + return fdopen(STDOUT_FILENO, "wb"); + } + int excl = force ? 0 : O_EXCL; +#if defined(_WIN32) + int fd = open(output_path, O_CREAT | excl | O_WRONLY | O_TRUNC | O_BINARY, + S_IREAD | S_IWRITE); +#else + int fd = open(output_path, O_CREAT | excl | O_WRONLY | O_TRUNC, + S_IRUSR | S_IWUSR); +#endif + if (fd < 0) { + if (!force) { + struct stat statbuf; + if (stat(output_path, &statbuf) == 0) { + fprintf(stderr, "output file exists\n"); + exit(1); + } + } + perror("open"); + exit(1); + } + return fdopen(fd, "wb"); +} + +int64_t FileSize(char *path) { + FILE *f = fopen(path, "rb"); + if (f == NULL) { + return -1; + } + if (fseek(f, 0L, SEEK_END) != 0) { + fclose(f); + return -1; + } + int64_t retval = ftell(f); + if (fclose(f) != 0) { + return -1; + } + return retval; +} + +static const size_t kFileBufferSize = 65536; + +void Decompresss(FILE* fin, FILE* fout) { + uint8_t* input = new uint8_t[kFileBufferSize]; + uint8_t* output = new uint8_t[kFileBufferSize]; + size_t total_out; + size_t available_in; + const uint8_t* next_in; + size_t available_out = kFileBufferSize; + uint8_t* next_out = output; + BrotliResult result = BROTLI_RESULT_NEEDS_MORE_INPUT; + BrotliState s; + BrotliStateInit(&s); + while (1) { + if (result == BROTLI_RESULT_NEEDS_MORE_INPUT) { + if (feof(fin)) { + break; + } + available_in = fread(input, 1, kFileBufferSize, fin); + next_in = input; + if (ferror(fin)) { + break; + } + } else if (result == BROTLI_RESULT_NEEDS_MORE_OUTPUT) { + fwrite(output, 1, kFileBufferSize, fout); + if (ferror(fout)) { + break; + } + available_out = kFileBufferSize; + next_out = output; + } else { + break; /* Error or success. */ + } + result = BrotliDecompressStream(&available_in, &next_in, + &available_out, &next_out, &total_out, &s); + } + if (next_out != output) { + fwrite(output, 1, next_out - output, fout); + } + BrotliStateCleanup(&s); + delete[] input; + delete[] output; + if ((result == BROTLI_RESULT_NEEDS_MORE_OUTPUT) || ferror(fout)) { + fprintf(stderr, "failed to write output\n"); + exit(1); + } else if (result != BROTLI_RESULT_SUCCESS) { /* Error or needs more input. */ + fprintf(stderr, "corrupt input\n"); + exit(1); + } +} + +int main(int argc, char** argv) { + char *input_path = 0; + char *output_path = 0; + int force = 0; + int quality = 11; + int decompress = 0; + int repeat = 1; + int verbose = 0; + int lgwin = 0; + ParseArgv(argc, argv, &input_path, &output_path, &force, + &quality, &decompress, &repeat, &verbose, &lgwin); + const clock_t clock_start = clock(); + for (int i = 0; i < repeat; ++i) { + FILE* fin = OpenInputFile(input_path); + FILE* fout = OpenOutputFile(output_path, force); + if (decompress) { + Decompresss(fin, fout); + } else { + brotli::BrotliParams params; + params.lgwin = lgwin; + params.quality = quality; + try { + brotli::BrotliFileIn in(fin, 1 << 16); + brotli::BrotliFileOut out(fout); + if (!BrotliCompress(params, &in, &out)) { + fprintf(stderr, "compression failed\n"); + unlink(output_path); + exit(1); + } + } catch (std::bad_alloc&) { + fprintf(stderr, "not enough memory\n"); + unlink(output_path); + exit(1); + } + } + if (fclose(fin) != 0) { + perror("fclose"); + exit(1); + } + if (fclose(fout) != 0) { + perror("fclose"); + exit(1); + } + } + if (verbose) { + const clock_t clock_end = clock(); + double duration = + static_cast(clock_end - clock_start) / CLOCKS_PER_SEC; + if (duration < 1e-9) { + duration = 1e-9; + } + int64_t uncompressed_size = FileSize(decompress ? output_path : input_path); + if (uncompressed_size == -1) { + fprintf(stderr, "failed to determine uncompressed file size\n"); + exit(1); + } + double uncompressed_bytes_in_MB = + (repeat * uncompressed_size) / (1024.0 * 1024.0); + if (decompress) { + printf("Brotli decompression speed: "); + } else { + printf("Brotli compression speed: "); + } + printf("%g MB/s\n", uncompressed_bytes_in_MB / duration); + } + return 0; +} diff --git a/web/server/h2o/libh2o/deps/brotli/tools/rfc-format.py b/web/server/h2o/libh2o/deps/brotli/tools/rfc-format.py new file mode 100755 index 00000000..61696a0c --- /dev/null +++ b/web/server/h2o/libh2o/deps/brotli/tools/rfc-format.py @@ -0,0 +1,92 @@ +#!/usr/bin/python +# +# Takes an .nroff source file and prints a text file in RFC format. +# +# Usage: rfc-format.py + +import re +import sys +from subprocess import Popen, PIPE + + +def Readfile(fn): + f = open(fn, "r") + return f.read() + + +def FixNroffOutput(buf): + p = re.compile(r'(.*)FORMFEED(\[Page\s+\d+\])$') + strip_empty = False + out = "" + for line in buf.split("\n"): + line = line.replace("\xe2\x80\x99", "'") + line = line.replace("\xe2\x80\x90", "-") + for i in range(len(line)): + if ord(line[i]) > 128: + print >>sys.stderr, "Invalid character %d\n" % ord(line[i]) + m = p.search(line) + if strip_empty and len(line) == 0: + continue + if m: + out += p.sub(r'\1 \2\n\f', line) + out += "\n" + strip_empty = True + else: + out += "%s\n" % line + strip_empty = False + return out.rstrip("\n") + + +def Nroff(buf): + p = Popen(["nroff", "-ms"], stdin=PIPE, stdout=PIPE) + out, err = p.communicate(input=buf) + return FixNroffOutput(out) + + +def FormatTocLine(section, title, page): + line = "" + level = 1 + if section: + level = section.count(".") + for i in range(level): + line += " " + if section: + line += "%s " % section + line += "%s " % title + pagenum = "%d" % page + nspace = 72 - len(line) - len(pagenum) + if nspace % 2: + line += " " + for i in range(nspace / 2): + line += ". " + line += "%d\n" % page + return line + + +def CreateToc(buf): + p1 = re.compile(r'^((\d+\.)+)\s+(.*)$') + p2 = re.compile(r'^(Appendix [A-Z].)\s+(.*)$') + p3 = re.compile(r'\[Page (\d+)\]$') + found = 0 + page = 1 + out = "" + for line in buf.split("\n"): + m1 = p1.search(line) + m2 = p2.search(line) + m3 = p3.search(line) + if m1: + out += FormatTocLine(m1.group(1), m1.group(3), page) + elif m2: + out += FormatTocLine(m2.group(1), m2.group(2), page) + elif line.startswith("Authors"): + out += FormatTocLine(None, line, page) + elif m3: + page = int(m3.group(1)) + 1 + return out + + +src = Readfile(sys.argv[1]) +out = Nroff(src) +toc = CreateToc(out) +src = src.replace("INSERT_TOC_HERE", toc) +print Nroff(src) diff --git a/web/server/h2o/libh2o/deps/brotli/tools/version.h b/web/server/h2o/libh2o/deps/brotli/tools/version.h new file mode 100644 index 00000000..6125a73e --- /dev/null +++ b/web/server/h2o/libh2o/deps/brotli/tools/version.h @@ -0,0 +1,14 @@ +/* Copyright 2015 Google Inc. All Rights Reserved. + + Distributed under MIT license. + See file LICENSE for detail or copy at https://opensource.org/licenses/MIT +*/ + +/* Defines a common version string used by all of the brotli tools. */ + +#ifndef BROTLI_TOOLS_VERSION_H_ +#define BROTLI_TOOLS_VERSION_H_ + +#define BROTLI_VERSION "0.3.0" + +#endif /* BROTLI_TOOLS_VERSION_H_ */ diff --git a/web/server/h2o/libh2o/deps/cloexec/cloexec.c b/web/server/h2o/libh2o/deps/cloexec/cloexec.c new file mode 100644 index 00000000..bc67c395 --- /dev/null +++ b/web/server/h2o/libh2o/deps/cloexec/cloexec.c @@ -0,0 +1,93 @@ +/* + * Copyright (c) 2015 DeNA Co., Ltd. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ +#include +#include "cloexec.h" + +pthread_mutex_t cloexec_mutex = PTHREAD_MUTEX_INITIALIZER; + +static int set_cloexec(int fd) +{ + return fcntl(fd, F_SETFD, FD_CLOEXEC) != -1 ? 0 : -1; +} + +/* + * note: the socket must be in non-blocking mode, or the call might block while the mutex is being locked + */ +int cloexec_accept(int socket, struct sockaddr *addr, socklen_t *addrlen) +{ + int fd = -1; + pthread_mutex_lock(&cloexec_mutex); + + if ((fd = accept(socket, addr, addrlen)) == -1) + goto Exit; + if (set_cloexec(fd) != 0) { + close(fd); + fd = -1; + goto Exit; + } + +Exit: + pthread_mutex_unlock(&cloexec_mutex); + return fd; +} + +int cloexec_pipe(int fds[2]) +{ +#ifdef __linux__ + return pipe2(fds, O_CLOEXEC); +#else + int ret = -1; + pthread_mutex_lock(&cloexec_mutex); + + if (pipe(fds) != 0) + goto Exit; + if (set_cloexec(fds[0]) != 0 || set_cloexec(fds[1]) != 0) + goto Exit; + ret = 0; + +Exit: + pthread_mutex_unlock(&cloexec_mutex); + return ret; +#endif +} + +int cloexec_socket(int domain, int type, int protocol) +{ +#ifdef __linux__ + return socket(domain, type | SOCK_CLOEXEC, protocol); +#else + int fd = -1; + pthread_mutex_lock(&cloexec_mutex); + + if ((fd = socket(domain, type, protocol)) == -1) + goto Exit; + if (set_cloexec(fd) != 0) { + close(fd); + fd = -1; + goto Exit; + } + +Exit: + pthread_mutex_unlock(&cloexec_mutex); + return fd; +#endif +} diff --git a/web/server/h2o/libh2o/deps/cloexec/cloexec.h b/web/server/h2o/libh2o/deps/cloexec/cloexec.h new file mode 100644 index 00000000..53987ed6 --- /dev/null +++ b/web/server/h2o/libh2o/deps/cloexec/cloexec.h @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2015 DeNA Co., Ltd. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ +#ifndef CLOEXEC_H +#define CLOEXEC_H + +#include +#include +#include +#include + +extern pthread_mutex_t cloexec_mutex; + +int cloexec_accept(int socket, struct sockaddr *addr, socklen_t *addrlen); +int cloexec_pipe(int fds[2]); +int cloexec_socket(int domain, int type, int protocol); + +#endif diff --git a/web/server/h2o/libh2o/deps/golombset/README.md b/web/server/h2o/libh2o/deps/golombset/README.md new file mode 100644 index 00000000..5bebfb77 --- /dev/null +++ b/web/server/h2o/libh2o/deps/golombset/README.md @@ -0,0 +1,26 @@ +golombset +=== + +Golombset is a pure-C, header-file-only implementation of Golomb coded set, which is an compressed form of [Bloom filter](https://en.wikipedia.org/Bloom_filter). + +It is compresses every zero-range of Bloom filter (e.g. `0000...1`) using [Golomb coding](https://en.wikipedia.org/wiki/Golomb_coding). +Please refer to [Golomb-coded sets: smaller than Bloom filters](http://giovanni.bajo.it/post/47119962313/golomb-coded-sets-smaller-than-bloom-filters) for more information about the algorithm. + +API +--- + +__`int golombset_encode(unsigned fixed_bits, const unsigned *keys, size_t num_keys, void *buf, size_t *bufsize);`__ + +The function encodes an pre-sorted array of keys into given buffer. + +The function returns zero if successful, or -1 if otherwise (e.g. the size of the buffer is not sufficient). +`bufsize` is an input-output parameter. +Upon calling the function the value of the pointer must specify the size of the buffer being supplied. +When the function returns successfully, the value is updated the length of the bytes actually used to store the encoded data. + +__`int golombset_decode(unsigned fixed_bits, const void *buf, size_t bufsize, unsigned *keys, size_t *num_keys);`__ + +The function decodes the compressed data into an array of keys. + +The function returns zero if successful, or -1 if the size of the `keys` buffer is too small (specified by `*num_keys` when the function is being called). +Upon successful return, the number of keys decoded will be stored in `*num_keys`. diff --git a/web/server/h2o/libh2o/deps/golombset/golombset.h b/web/server/h2o/libh2o/deps/golombset/golombset.h new file mode 100644 index 00000000..207f0d61 --- /dev/null +++ b/web/server/h2o/libh2o/deps/golombset/golombset.h @@ -0,0 +1,162 @@ +/* + * Copyright (c) 2015 Kazuho Oku + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ +#ifndef GOLOMBSET_H +#define GOLOMBSET_H + +#include + +struct st_golombset_encode_t { + unsigned char *dst; + unsigned char *dst_max; + unsigned dst_shift; +}; + +struct st_golombset_decode_t { + const unsigned char *src; + const unsigned char *src_max; + unsigned src_shift; +}; + +static int golombset_encode_bit(struct st_golombset_encode_t *ctx, int bit) +{ + if (ctx->dst_shift == 0) { + if (++ctx->dst == ctx->dst_max) + return -1; + *ctx->dst = 0; + ctx->dst_shift = 8; + } + --ctx->dst_shift; + if (bit) + *ctx->dst |= 1 << ctx->dst_shift; + return 0; +} + +static int golombset_encode_bits(struct st_golombset_encode_t *ctx, unsigned bits, uint64_t value) +{ + if (bits != 0) { + do { + --bits; + if (golombset_encode_bit(ctx, (value >> bits) & 1) != 0) + return -1; + } while (bits != 0); + } + return 0; +} + +static int golombset_decode_bit(struct st_golombset_decode_t *ctx) +{ + if (ctx->src_shift == 0) { + if (++ctx->src == ctx->src_max) + return -1; + ctx->src_shift = 8; + } + return (*ctx->src >> --ctx->src_shift) & 1; +} + +static int golombset_decode_bits(struct st_golombset_decode_t *ctx, unsigned bits, uint64_t *value) +{ + int bit; + + *value = 0; + for (; bits != 0; --bits) { + if ((bit = golombset_decode_bit(ctx)) == -1) + return -1; + *value = (*value * 2) + bit; + } + + return 0; +} + +static int golombset_encode_value(struct st_golombset_encode_t *ctx, unsigned fixed_bits, uint64_t value) +{ + /* emit quontient */ + uint64_t unary_bits = value >> fixed_bits; + for (; unary_bits != 0; --unary_bits) + if (golombset_encode_bit(ctx, 0) != 0) + return -1; + if (golombset_encode_bit(ctx, 1) != 0) + return -1; + /* emit remainder */ + return golombset_encode_bits(ctx, fixed_bits, value); +} + +static int golombset_decode_value(struct st_golombset_decode_t *ctx, unsigned fixed_bits, uint64_t *value) +{ + uint64_t q; + int bit; + + /* decode quontient */ + for (q = 0; ; ++q) { + if ((bit = golombset_decode_bit(ctx)) == -1) + return -1; + if (bit) + break; + } + /* decode remainder */ + if (golombset_decode_bits(ctx, fixed_bits, value) == -1) + return -1; + /* merge q and r */ + *value += q << fixed_bits; + + return 0; +} + +static int golombset_encode(unsigned fixed_bits, uint64_t *keys, size_t num_keys, void *buf, size_t *bufsize) +{ + struct st_golombset_encode_t ctx = {(unsigned char *)buf - 1, (unsigned char *)buf + *bufsize}; + size_t i; + uint64_t next_min = 0; + + for (i = 0; i != num_keys; ++i) { + if (golombset_encode_value(&ctx, fixed_bits, keys[i] - next_min) != 0) + return -1; + next_min = keys[i] + 1; + } + + *bufsize = ctx.dst + 1 - (unsigned char *)buf; + + return 0; +} + +static int golombset_decode(unsigned fixed_bits, const void *buf, size_t bufsize, uint64_t *keys, size_t *num_keys) +{ + struct st_golombset_decode_t ctx = {buf, (unsigned char *)buf + bufsize, 8}; + size_t index = 0; + uint64_t next_min = 0; + + while (1) { + uint64_t value; + if (golombset_decode_value(&ctx, fixed_bits, &value) != 0) + break; + if (index == *num_keys) { + /* not enough space */ + return -1; + } + value += next_min; + keys[index++] = value; + next_min = value + 1; + } + *num_keys = index; + return 0; +} + +#endif diff --git a/web/server/h2o/libh2o/deps/golombset/test.c b/web/server/h2o/libh2o/deps/golombset/test.c new file mode 100644 index 00000000..42a8ac8f --- /dev/null +++ b/web/server/h2o/libh2o/deps/golombset/test.c @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2015 Kazuho Oku + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ +#include +#include +#include +#include "golombset.h" + +int main(int argc, char **argv) +{ + uint64_t keys[] = {151, 192, 208, 269, 461, 512, 526, 591, 662, 806, 831, 866, 890, + 997, 1005, 1017, 1134, 1207, 1231, 1327, 1378, 1393, 1418, 1525, 1627, 1630}; + const size_t num_keys = sizeof(keys) / sizeof(keys[0]); + unsigned char buf[1024]; + size_t bufsize = sizeof(buf); + + if (golombset_encode(6, keys, num_keys, buf, &bufsize) != 0) { + fprintf(stderr, "golombset_encode failed\n"); + return 111; + } + printf("encoded %zu entries into %zu bytes\n", num_keys, bufsize); + + uint64_t decoded_keys[num_keys]; + size_t num_decoded_keys = num_keys; + if (golombset_decode(6, buf, bufsize, decoded_keys, &num_decoded_keys) != 0) { + fprintf(stderr, "golombset_decode failed\n"); + return 111; + } + + if (num_decoded_keys != num_keys) { + fprintf(stderr, "unexpected number of outputs\n"); + return 111; + } + if (memcmp(keys, decoded_keys, sizeof(keys[0]) * num_keys) != 0) { + fprintf(stderr, "output mismatch\n"); + return 111; + } + + return 0; +} diff --git a/web/server/h2o/libh2o/deps/klib/.gitignore b/web/server/h2o/libh2o/deps/klib/.gitignore new file mode 100644 index 00000000..010a8ebe --- /dev/null +++ b/web/server/h2o/libh2o/deps/klib/.gitignore @@ -0,0 +1,40 @@ +# General +*.a +*.dSYM/ +*.la +*.lo +*.o +*.opensdf +*.orig +*.sdf +*.suo +*.swp +*.tests +*.vcxproj.filters +*.vcxproj.user +*~ +.git +TAGS + +# Mac/Xcode-specfic +xcuserdata +contents.xcworkspacedata +.DS_Store +._* + +# Test byproducts +test/kbtree_test +test/khash_keith +test/khash_keith2 +test/khash_test +test/klist_test +test/kmin_test +test/kseq_bench +test/kseq_bench2 +test/kseq_test +test/ksort_test +test/ksort_test-stl +test/kstring_bench +test/kstring_bench2 +test/kstring_test +test/kvec_test diff --git a/web/server/h2o/libh2o/deps/klib/README.md b/web/server/h2o/libh2o/deps/klib/README.md new file mode 100644 index 00000000..ddd74f47 --- /dev/null +++ b/web/server/h2o/libh2o/deps/klib/README.md @@ -0,0 +1,237 @@ +#Klib: a Generic Library in C + +##Overview + +Klib is a standalone and lightweight C library distributed under [MIT/X11 +license][1]. Most components are independent of external libraries, except the +standard C library, and independent of each other. To use a component of this +library, you only need to copy a couple of files to your source code tree +without worrying about library dependencies. + +Klib strives for efficiency and a small memory footprint. Some components, such +as khash.h, kbtree.h, ksort.h and kvec.h, are among the most efficient +implementations of similar algorithms or data structures in all programming +languages, in terms of both speed and memory use. + +A new documentation is available [here](http://attractivechaos.github.io/klib/) +which includes most information in this README file. + +####Common components + +* [khash.h][khash]: generic hash table based on [double hashing][2]. +* [kbtree.h][kbtree]: generic search tree based on [B-tree][3]. +* [ksort.h][ksort]: generic sort, including [introsort][4], [merge sort][5], [heap sort][6], [comb sort][7], [Knuth shuffle][8] and the [k-small][9] algorithm. +* [kseq.h][kseq]: generic stream buffer and a [FASTA][10]/[FASTQ][11] format parser. +* kvec.h: generic dynamic array. +* klist.h: generic single-linked list and [memory pool][12]. +* kstring.{h,c}: basic string library. +* kmath.{h,c}: numerical routines including [MT19937-64][13] [pseudorandom generator][14], basic [nonlinear programming][15] and a few special math functions. + +####Components for more specific use cases + +* ksa.c: constructing [suffix arrays][16] for strings with multiple sentinels, based on a revised [SAIS algorithm][17]. +* knetfile.{h,c}: random access to remote files on HTTP or FTP. +* kopen.c: smart stream opening. +* khmm.{h,c}: basic [HMM][18] library. +* ksw.(h,c}: Striped [Smith-Waterman algorithm][19]. +* knhx.{h,c}: [Newick tree format][20] parser. + + +##Methodology + +For the implementation of generic [containers][21], klib extensively uses C +macros. To use these data structures, we usually need to instantiate methods by +expanding a long macro. This makes the source code look unusual or even ugly +and adds difficulty to debugging. Unfortunately, for efficient generic +programming in C that lacks [template][22], using macros is the only +solution. Only with macros, we can write a generic container which, once +instantiated, compete with a type-specific container in efficiency. Some +generic libraries in C, such as [Glib][23], use the `void*` type to implement +containers. These implementations are usually slower and use more memory than +klib (see [this benchmark][31]). + +To effectively use klib, it is important to understand how it achieves generic +programming. We will use the hash table library as an example: + + #include "khash.h" + KHASH_MAP_INIT_INT(m32, char) // instantiate structs and methods + int main() { + int ret, is_missing; + khint_t k; + khash_t(m32) *h = kh_init(m32); // allocate a hash table + k = kh_put(m32, h, 5, &ret); // insert a key to the hash table + if (!ret) kh_del(m32, h, k); + kh_value(h, k) = 10; // set the value + k = kh_get(m32, h, 10); // query the hash table + is_missing = (k == kh_end(h)); // test if the key is present + k = kh_get(m32, h, 5); + kh_del(m32, h, k); // remove a key-value pair + for (k = kh_begin(h); k != kh_end(h); ++k) // traverse + if (kh_exist(h, k)) // test if a bucket contains data + kh_value(h, k) = 1; + kh_destroy(m32, h); // deallocate the hash table + return 0; + } + +In this example, the second line instantiates a hash table with `unsigned` as +the key type and `char` as the value type. `m32` names such a type of hash table. +All types and functions associated with this name are macros, which will be +explained later. Macro `kh_init()` initiates a hash table and `kh_destroy()` +frees it. `kh_put()` inserts a key and returns the iterator (or the position) +in the hash table. `kh_get()` and `kh_del()` get a key and delete an element, +respectively. Macro `kh_exist()` tests if an iterator (or a position) is filled +with data. + +An immediate question is this piece of code does not look like a valid C +program (e.g. lacking semicolon, assignment to an _apparent_ function call and +_apparent_ undefined `m32` 'variable'). To understand why the code is correct, +let's go a bit further into the source code of `khash.h`, whose skeleton looks +like: + + #define KHASH_INIT(name, SCOPE, key_t, val_t, is_map, _hashf, _hasheq) \ + typedef struct { \ + int n_buckets, size, n_occupied, upper_bound; \ + unsigned *flags; \ + key_t *keys; \ + val_t *vals; \ + } kh_##name##_t; \ + SCOPE inline kh_##name##_t *init_##name() { \ + return (kh_##name##_t*)calloc(1, sizeof(kh_##name##_t)); \ + } \ + SCOPE inline int get_##name(kh_##name##_t *h, key_t k) \ + ... \ + SCOPE inline void destroy_##name(kh_##name##_t *h) { \ + if (h) { \ + free(h->keys); free(h->flags); free(h->vals); free(h); \ + } \ + } + + #define _int_hf(key) (unsigned)(key) + #define _int_heq(a, b) (a == b) + #define khash_t(name) kh_##name##_t + #define kh_value(h, k) ((h)->vals[k]) + #define kh_begin(h, k) 0 + #define kh_end(h) ((h)->n_buckets) + #define kh_init(name) init_##name() + #define kh_get(name, h, k) get_##name(h, k) + #define kh_destroy(name, h) destroy_##name(h) + ... + #define KHASH_MAP_INIT_INT(name, val_t) \ + KHASH_INIT(name, static, unsigned, val_t, is_map, _int_hf, _int_heq) + +`KHASH_INIT()` is a huge macro defining all the structs and methods. When this +macro is called, all the code inside it will be inserted by the [C +preprocess][37] to the place where it is called. If the macro is called +multiple times, multiple copies of the code will be inserted. To avoid naming +conflict of hash tables with different key-value types, the library uses [token +concatenation][36], which is a preprocessor feature whereby we can substitute +part of a symbol based on the parameter of the macro. In the end, the C +preprocessor will generate the following code and feed it to the compiler +(macro `kh_exist(h,k)` is a little complex and not expanded for simplicity): + + typedef struct { + int n_buckets, size, n_occupied, upper_bound; + unsigned *flags; + unsigned *keys; + char *vals; + } kh_m32_t; + static inline kh_m32_t *init_m32() { + return (kh_m32_t*)calloc(1, sizeof(kh_m32_t)); + } + static inline int get_m32(kh_m32_t *h, unsigned k) + ... + static inline void destroy_m32(kh_m32_t *h) { + if (h) { + free(h->keys); free(h->flags); free(h->vals); free(h); + } + } + + int main() { + int ret, is_missing; + khint_t k; + kh_m32_t *h = init_m32(); + k = put_m32(h, 5, &ret); + if (!ret) del_m32(h, k); + h->vals[k] = 10; + k = get_m32(h, 10); + is_missing = (k == h->n_buckets); + k = get_m32(h, 5); + del_m32(h, k); + for (k = 0; k != h->n_buckets; ++k) + if (kh_exist(h, k)) h->vals[k] = 1; + destroy_m32(h); + return 0; + } + +This is the C program we know. + +From this example, we can see that macros and the C preprocessor plays a key +role in klib. Klib is fast partly because the compiler knows the key-value +type at the compile time and is able to optimize the code to the same level +as type-specific code. A generic library written with `void*` will not get such +performance boost. + +Massively inserting code upon instantiation may remind us of C++'s slow +compiling speed and huge binary size when STL/boost is in use. Klib is much +better in this respect due to its small code size and component independency. +Inserting several hundreds lines of code won't make compiling obviously slower. + +##Resources + +* Library documentation, if present, is available in the header files. Examples +can be found in the [test/][24] directory. +* **Obsolete** documentation of the hash table library can be found at +[SourceForge][25]. This README is partly adapted from the old documentation. +* [Blog post][26] describing the hash table library. +* [Blog post][27] on why using `void*` for generic programming may be inefficient. +* [Blog post][28] on the generic stream buffer. +* [Blog post][29] evaluating the performance of `kvec.h`. +* [Blog post][30] arguing B-tree may be a better data structure than a binary search tree. +* [Blog post][31] evaluating the performance of `khash.h` and `kbtree.h` among many other implementations. +[An older version][33] of the benchmark is also available. +* [Blog post][34] benchmarking internal sorting algorithms and implementations. +* [Blog post][32] on the k-small algorithm. +* [Blog post][35] on the Hooke-Jeeve's algorithm for nonlinear programming. + +[1]: http://en.wikipedia.org/wiki/MIT_License +[2]: http://en.wikipedia.org/wiki/Double_hashing +[3]: http://en.wikipedia.org/wiki/B-tree +[4]: http://en.wikipedia.org/wiki/Introsort +[5]: http://en.wikipedia.org/wiki/Merge_sort +[6]: http://en.wikipedia.org/wiki/Heapsort +[7]: http://en.wikipedia.org/wiki/Comb_sort +[8]: http://en.wikipedia.org/wiki/Fisher-Yates_shuffle +[9]: http://en.wikipedia.org/wiki/Selection_algorithm +[10]: http://en.wikipedia.org/wiki/FASTA_format +[11]: http://en.wikipedia.org/wiki/FASTQ_format +[12]: http://en.wikipedia.org/wiki/Memory_pool +[13]: http://en.wikipedia.org/wiki/Mersenne_twister +[14]: http://en.wikipedia.org/wiki/Pseudorandom_generator +[15]: http://en.wikipedia.org/wiki/Nonlinear_programming +[16]: http://en.wikipedia.org/wiki/Suffix_array +[17]: https://sites.google.com/site/yuta256/sais +[18]: http://en.wikipedia.org/wiki/Hidden_Markov_model +[19]: http://en.wikipedia.org/wiki/Smith-Waterman_algorithm +[20]: http://en.wikipedia.org/wiki/Newick_format +[21]: http://en.wikipedia.org/wiki/Container_(abstract_data_type) +[22]: http://en.wikipedia.org/wiki/Template_(C%2B%2B) +[23]: http://en.wikipedia.org/wiki/GLib +[24]: https://github.com/attractivechaos/klib/tree/master/test +[25]: http://klib.sourceforge.net/ +[26]: http://attractivechaos.wordpress.com/2008/09/02/implementing-generic-hash-library-in-c/ +[27]: http://attractivechaos.wordpress.com/2008/10/02/using-void-in-generic-c-programming-may-be-inefficient/ +[28]: http://attractivechaos.wordpress.com/2008/10/11/a-generic-buffered-stream-wrapper/ +[29]: http://attractivechaos.wordpress.com/2008/09/19/c-array-vs-c-vector/ +[30]: http://attractivechaos.wordpress.com/2008/09/24/b-tree-vs-binary-search-tree/ +[31]: http://attractivechaos.wordpress.com/2008/10/07/another-look-at-my-old-benchmark/ +[32]: http://attractivechaos.wordpress.com/2008/09/13/calculating-median/ +[33]: http://attractivechaos.wordpress.com/2008/08/28/comparison-of-hash-table-libraries/ +[34]: http://attractivechaos.wordpress.com/2008/08/28/comparison-of-internal-sorting-algorithms/ +[35]: http://attractivechaos.wordpress.com/2008/08/24/derivative-free-optimization-dfo/ +[36]: http://en.wikipedia.org/wiki/C_preprocessor#Token_concatenation +[37]: http://en.wikipedia.org/wiki/C_preprocessor + +[kbtree]: http://attractivechaos.github.io/klib/#KBtree%3A%20generic%20ordered%20map:%5B%5BKBtree%3A%20generic%20ordered%20map%5D%5D +[khash]: http://attractivechaos.github.io/klib/#Khash%3A%20generic%20hash%20table:%5B%5BKhash%3A%20generic%20hash%20table%5D%5D +[kseq]: http://attractivechaos.github.io/klib/#Kseq%3A%20stream%20buffer%20and%20FASTA%2FQ%20parser:%5B%5BKseq%3A%20stream%20buffer%20and%20FASTA%2FQ%20parser%5D%5D +[ksort]: http://attractivechaos.github.io/klib/#Ksort%3A%20sorting%2C%20shuffling%2C%20heap%20and%20k-small:%5B%5BKsort%3A%20sorting%2C%20shuffling%2C%20heap%20and%20k-small%5D%5D diff --git a/web/server/h2o/libh2o/deps/klib/bgzf.c b/web/server/h2o/libh2o/deps/klib/bgzf.c new file mode 100644 index 00000000..9833414f --- /dev/null +++ b/web/server/h2o/libh2o/deps/klib/bgzf.c @@ -0,0 +1,555 @@ +/* The MIT License + + Copyright (c) 2008 Broad Institute / Massachusetts Institute of Technology + 2011 Attractive Chaos + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + +#include +#include +#include +#include +#include +#include +#include "bgzf.h" + +#ifdef _USE_KNETFILE +#include "knetfile.h" +typedef knetFile *_bgzf_file_t; +#define _bgzf_open(fn, mode) knet_open(fn, mode) +#define _bgzf_dopen(fp, mode) knet_dopen(fp, mode) +#define _bgzf_close(fp) knet_close(fp) +#define _bgzf_fileno(fp) ((fp)->fd) +#define _bgzf_tell(fp) knet_tell(fp) +#define _bgzf_seek(fp, offset, whence) knet_seek(fp, offset, whence) +#define _bgzf_read(fp, buf, len) knet_read(fp, buf, len) +#define _bgzf_write(fp, buf, len) knet_write(fp, buf, len) +#else // ~defined(_USE_KNETFILE) +#if defined(_WIN32) || defined(_MSC_VER) +#define ftello(fp) ftell(fp) +#define fseeko(fp, offset, whence) fseek(fp, offset, whence) +#else // ~defined(_WIN32) +extern off_t ftello(FILE *stream); +extern int fseeko(FILE *stream, off_t offset, int whence); +#endif // ~defined(_WIN32) +typedef FILE *_bgzf_file_t; +#define _bgzf_open(fn, mode) fopen(fn, mode) +#define _bgzf_dopen(fp, mode) fdopen(fp, mode) +#define _bgzf_close(fp) fclose(fp) +#define _bgzf_fileno(fp) fileno(fp) +#define _bgzf_tell(fp) ftello(fp) +#define _bgzf_seek(fp, offset, whence) fseeko(fp, offset, whence) +#define _bgzf_read(fp, buf, len) fread(buf, 1, len, fp) +#define _bgzf_write(fp, buf, len) fwrite(buf, 1, len, fp) +#endif // ~define(_USE_KNETFILE) + +#define BLOCK_HEADER_LENGTH 18 +#define BLOCK_FOOTER_LENGTH 8 + +/* BGZF/GZIP header (speciallized from RFC 1952; little endian): + +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ + | 31|139| 8| 4| 0| 0|255| 6| 66| 67| 2|BLK_LEN| + +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ +*/ +static const uint8_t g_magic[19] = "\037\213\010\4\0\0\0\0\0\377\6\0\102\103\2\0\0\0"; + +#ifdef BGZF_CACHE +typedef struct { + int size; + uint8_t *block; + int64_t end_offset; +} cache_t; +#include "khash.h" +KHASH_MAP_INIT_INT64(cache, cache_t) +#endif + +static inline void packInt16(uint8_t *buffer, uint16_t value) +{ + buffer[0] = value; + buffer[1] = value >> 8; +} + +static inline int unpackInt16(const uint8_t *buffer) +{ + return buffer[0] | buffer[1] << 8; +} + +static inline void packInt32(uint8_t *buffer, uint32_t value) +{ + buffer[0] = value; + buffer[1] = value >> 8; + buffer[2] = value >> 16; + buffer[3] = value >> 24; +} + +static BGZF *bgzf_read_init() +{ + BGZF *fp; + fp = calloc(1, sizeof(BGZF)); + fp->open_mode = 'r'; + fp->uncompressed_block = malloc(BGZF_MAX_BLOCK_SIZE); + fp->compressed_block = malloc(BGZF_MAX_BLOCK_SIZE); +#ifdef BGZF_CACHE + fp->cache = kh_init(cache); +#endif + return fp; +} + +static BGZF *bgzf_write_init(int compress_level) // compress_level==-1 for the default level +{ + BGZF *fp; + fp = calloc(1, sizeof(BGZF)); + fp->open_mode = 'w'; + fp->uncompressed_block = malloc(BGZF_MAX_BLOCK_SIZE); + fp->compressed_block = malloc(BGZF_MAX_BLOCK_SIZE); + fp->compress_level = compress_level < 0? Z_DEFAULT_COMPRESSION : compress_level; // Z_DEFAULT_COMPRESSION==-1 + if (fp->compress_level > 9) fp->compress_level = Z_DEFAULT_COMPRESSION; + return fp; +} +// get the compress level from the mode string +static int mode2level(const char *__restrict mode) +{ + int i, compress_level = -1; + for (i = 0; mode[i]; ++i) + if (mode[i] >= '0' && mode[i] <= '9') break; + if (mode[i]) compress_level = (int)mode[i] - '0'; + if (strchr(mode, 'u')) compress_level = 0; + return compress_level; +} + +BGZF *bgzf_open(const char *path, const char *mode) +{ + BGZF *fp = 0; + if (strchr(mode, 'r') || strchr(mode, 'R')) { + _bgzf_file_t fpr; + if ((fpr = _bgzf_open(path, "r")) == 0) return 0; + fp = bgzf_read_init(); + fp->fp = fpr; + } else if (strchr(mode, 'w') || strchr(mode, 'W')) { + FILE *fpw; + if ((fpw = fopen(path, "w")) == 0) return 0; + fp = bgzf_write_init(mode2level(mode)); + fp->fp = fpw; + } + return fp; +} + +BGZF *bgzf_dopen(int fd, const char *mode) +{ + BGZF *fp = 0; + if (strchr(mode, 'r') || strchr(mode, 'R')) { + _bgzf_file_t fpr; + if ((fpr = _bgzf_dopen(fd, "r")) == 0) return 0; + fp = bgzf_read_init(); + fp->fp = fpr; + } else if (strchr(mode, 'w') || strchr(mode, 'W')) { + FILE *fpw; + if ((fpw = fdopen(fd, "w")) == 0) return 0; + fp = bgzf_write_init(mode2level(mode)); + fp->fp = fpw; + } + return fp; +} + +// Deflate the block in fp->uncompressed_block into fp->compressed_block. Also adds an extra field that stores the compressed block length. +static int deflate_block(BGZF *fp, int block_length) +{ + uint8_t *buffer = fp->compressed_block; + int buffer_size = BGZF_BLOCK_SIZE; + int input_length = block_length; + int compressed_length = 0; + int remaining; + uint32_t crc; + + assert(block_length <= BGZF_BLOCK_SIZE); // guaranteed by the caller + memcpy(buffer, g_magic, BLOCK_HEADER_LENGTH); // the last two bytes are a place holder for the length of the block + while (1) { // loop to retry for blocks that do not compress enough + int status; + z_stream zs; + zs.zalloc = NULL; + zs.zfree = NULL; + zs.next_in = fp->uncompressed_block; + zs.avail_in = input_length; + zs.next_out = (void*)&buffer[BLOCK_HEADER_LENGTH]; + zs.avail_out = buffer_size - BLOCK_HEADER_LENGTH - BLOCK_FOOTER_LENGTH; + status = deflateInit2(&zs, fp->compress_level, Z_DEFLATED, -15, 8, Z_DEFAULT_STRATEGY); // -15 to disable zlib header/footer + if (status != Z_OK) { + fp->errcode |= BGZF_ERR_ZLIB; + return -1; + } + status = deflate(&zs, Z_FINISH); + if (status != Z_STREAM_END) { // not compressed enough + deflateEnd(&zs); // reset the stream + if (status == Z_OK) { // reduce the size and recompress + input_length -= 1024; + assert(input_length > 0); // logically, this should not happen + continue; + } + fp->errcode |= BGZF_ERR_ZLIB; + return -1; + } + if (deflateEnd(&zs) != Z_OK) { + fp->errcode |= BGZF_ERR_ZLIB; + return -1; + } + compressed_length = zs.total_out; + compressed_length += BLOCK_HEADER_LENGTH + BLOCK_FOOTER_LENGTH; + assert(compressed_length <= BGZF_BLOCK_SIZE); + break; + } + + assert(compressed_length > 0); + packInt16((uint8_t*)&buffer[16], compressed_length - 1); // write the compressed_length; -1 to fit 2 bytes + crc = crc32(0L, NULL, 0L); + crc = crc32(crc, fp->uncompressed_block, input_length); + packInt32((uint8_t*)&buffer[compressed_length-8], crc); + packInt32((uint8_t*)&buffer[compressed_length-4], input_length); + + remaining = block_length - input_length; + if (remaining > 0) { + assert(remaining <= input_length); + memcpy(fp->uncompressed_block, fp->uncompressed_block + input_length, remaining); + } + fp->block_offset = remaining; + return compressed_length; +} + +// Inflate the block in fp->compressed_block into fp->uncompressed_block +static int inflate_block(BGZF* fp, int block_length) +{ + z_stream zs; + zs.zalloc = NULL; + zs.zfree = NULL; + zs.next_in = fp->compressed_block + 18; + zs.avail_in = block_length - 16; + zs.next_out = fp->uncompressed_block; + zs.avail_out = BGZF_BLOCK_SIZE; + + if (inflateInit2(&zs, -15) != Z_OK) { + fp->errcode |= BGZF_ERR_ZLIB; + return -1; + } + if (inflate(&zs, Z_FINISH) != Z_STREAM_END) { + inflateEnd(&zs); + fp->errcode |= BGZF_ERR_ZLIB; + return -1; + } + if (inflateEnd(&zs) != Z_OK) { + fp->errcode |= BGZF_ERR_ZLIB; + return -1; + } + return zs.total_out; +} + +static int check_header(const uint8_t *header) +{ + return (header[0] == 31 && header[1] == 139 && header[2] == 8 && (header[3] & 4) != 0 + && unpackInt16((uint8_t*)&header[10]) == 6 + && header[12] == 'B' && header[13] == 'C' + && unpackInt16((uint8_t*)&header[14]) == 2); +} + +#ifdef BGZF_CACHE +static void free_cache(BGZF *fp) +{ + khint_t k; + khash_t(cache) *h = (khash_t(cache)*)fp->cache; + if (fp->open_mode != 'r') return; + for (k = kh_begin(h); k < kh_end(h); ++k) + if (kh_exist(h, k)) free(kh_val(h, k).block); + kh_destroy(cache, h); +} + +static int load_block_from_cache(BGZF *fp, int64_t block_address) +{ + khint_t k; + cache_t *p; + khash_t(cache) *h = (khash_t(cache)*)fp->cache; + k = kh_get(cache, h, block_address); + if (k == kh_end(h)) return 0; + p = &kh_val(h, k); + if (fp->block_length != 0) fp->block_offset = 0; + fp->block_address = block_address; + fp->block_length = p->size; + memcpy(fp->uncompressed_block, p->block, BGZF_BLOCK_SIZE); + _bgzf_seek((_bgzf_file_t)fp->fp, p->end_offset, SEEK_SET); + return p->size; +} + +static void cache_block(BGZF *fp, int size) +{ + int ret; + khint_t k; + cache_t *p; + khash_t(cache) *h = (khash_t(cache)*)fp->cache; + if (BGZF_BLOCK_SIZE >= fp->cache_size) return; + if ((kh_size(h) + 1) * BGZF_BLOCK_SIZE > fp->cache_size) { + /* A better way would be to remove the oldest block in the + * cache, but here we remove a random one for simplicity. This + * should not have a big impact on performance. */ + for (k = kh_begin(h); k < kh_end(h); ++k) + if (kh_exist(h, k)) break; + if (k < kh_end(h)) { + free(kh_val(h, k).block); + kh_del(cache, h, k); + } + } + k = kh_put(cache, h, fp->block_address, &ret); + if (ret == 0) return; // if this happens, a bug! + p = &kh_val(h, k); + p->size = fp->block_length; + p->end_offset = fp->block_address + size; + p->block = malloc(BGZF_BLOCK_SIZE); + memcpy(kh_val(h, k).block, fp->uncompressed_block, BGZF_BLOCK_SIZE); +} +#else +static void free_cache(BGZF *fp) {} +static int load_block_from_cache(BGZF *fp, int64_t block_address) {return 0;} +static void cache_block(BGZF *fp, int size) {} +#endif + +int bgzf_read_block(BGZF *fp) +{ + uint8_t header[BLOCK_HEADER_LENGTH], *compressed_block; + int count, size = 0, block_length, remaining; + int64_t block_address; + block_address = _bgzf_tell((_bgzf_file_t)fp->fp); + if (load_block_from_cache(fp, block_address)) return 0; + count = _bgzf_read(fp->fp, header, sizeof(header)); + if (count == 0) { // no data read + fp->block_length = 0; + return 0; + } + if (count != sizeof(header) || !check_header(header)) { + fp->errcode |= BGZF_ERR_HEADER; + return -1; + } + size = count; + block_length = unpackInt16((uint8_t*)&header[16]) + 1; // +1 because when writing this number, we used "-1" + compressed_block = (uint8_t*)fp->compressed_block; + memcpy(compressed_block, header, BLOCK_HEADER_LENGTH); + remaining = block_length - BLOCK_HEADER_LENGTH; + count = _bgzf_read(fp->fp, &compressed_block[BLOCK_HEADER_LENGTH], remaining); + if (count != remaining) { + fp->errcode |= BGZF_ERR_IO; + return -1; + } + size += count; + if ((count = inflate_block(fp, block_length)) < 0) return -1; + if (fp->block_length != 0) fp->block_offset = 0; // Do not reset offset if this read follows a seek. + fp->block_address = block_address; + fp->block_length = count; + cache_block(fp, size); + return 0; +} + +ssize_t bgzf_read(BGZF *fp, void *data, ssize_t length) +{ + ssize_t bytes_read = 0; + uint8_t *output = data; + if (length <= 0) return 0; + assert(fp->open_mode == 'r'); + while (bytes_read < length) { + int copy_length, available = fp->block_length - fp->block_offset; + uint8_t *buffer; + if (available <= 0) { + if (bgzf_read_block(fp) != 0) return -1; + available = fp->block_length - fp->block_offset; + if (available <= 0) break; + } + copy_length = length - bytes_read < available? length - bytes_read : available; + buffer = fp->uncompressed_block; + memcpy(output, buffer + fp->block_offset, copy_length); + fp->block_offset += copy_length; + output += copy_length; + bytes_read += copy_length; + } + if (fp->block_offset == fp->block_length) { + fp->block_address = _bgzf_tell((_bgzf_file_t)fp->fp); + fp->block_offset = fp->block_length = 0; + } + return bytes_read; +} + +int bgzf_flush(BGZF *fp) +{ + assert(fp->open_mode == 'w'); + while (fp->block_offset > 0) { + int block_length; + block_length = deflate_block(fp, fp->block_offset); + if (block_length < 0) return -1; + if (fwrite(fp->compressed_block, 1, block_length, fp->fp) != block_length) { + fp->errcode |= BGZF_ERR_IO; // possibly truncated file + return -1; + } + fp->block_address += block_length; + } + return 0; +} + +int bgzf_flush_try(BGZF *fp, ssize_t size) +{ + if (fp->block_offset + size > BGZF_BLOCK_SIZE) + return bgzf_flush(fp); + return -1; +} + +ssize_t bgzf_write(BGZF *fp, const void *data, ssize_t length) +{ + const uint8_t *input = data; + int block_length = BGZF_BLOCK_SIZE, bytes_written; + assert(fp->open_mode == 'w'); + input = data; + bytes_written = 0; + while (bytes_written < length) { + uint8_t* buffer = fp->uncompressed_block; + int copy_length = block_length - fp->block_offset < length - bytes_written? block_length - fp->block_offset : length - bytes_written; + memcpy(buffer + fp->block_offset, input, copy_length); + fp->block_offset += copy_length; + input += copy_length; + bytes_written += copy_length; + if (fp->block_offset == block_length && bgzf_flush(fp)) break; + } + return bytes_written; +} + +int bgzf_close(BGZF* fp) +{ + int ret, count, block_length; + if (fp == 0) return -1; + if (fp->open_mode == 'w') { + if (bgzf_flush(fp) != 0) return -1; + block_length = deflate_block(fp, 0); // write an empty block + count = fwrite(fp->compressed_block, 1, block_length, fp->fp); + if (fflush(fp->fp) != 0) { + fp->errcode |= BGZF_ERR_IO; + return -1; + } + } + ret = fp->open_mode == 'w'? fclose(fp->fp) : _bgzf_close(fp->fp); + if (ret != 0) return -1; + free(fp->uncompressed_block); + free(fp->compressed_block); + free_cache(fp); + free(fp); + return 0; +} + +void bgzf_set_cache_size(BGZF *fp, int cache_size) +{ + if (fp) fp->cache_size = cache_size; +} + +int bgzf_check_EOF(BGZF *fp) +{ + static uint8_t magic[28] = "\037\213\010\4\0\0\0\0\0\377\6\0\102\103\2\0\033\0\3\0\0\0\0\0\0\0\0\0"; + uint8_t buf[28]; + off_t offset; + offset = _bgzf_tell((_bgzf_file_t)fp->fp); + if (_bgzf_seek(fp->fp, -28, SEEK_END) < 0) return 0; + _bgzf_read(fp->fp, buf, 28); + _bgzf_seek(fp->fp, offset, SEEK_SET); + return (memcmp(magic, buf, 28) == 0)? 1 : 0; +} + +int64_t bgzf_seek(BGZF* fp, int64_t pos, int where) +{ + int block_offset; + int64_t block_address; + + if (fp->open_mode != 'r' || where != SEEK_SET) { + fp->errcode |= BGZF_ERR_MISUSE; + return -1; + } + block_offset = pos & 0xFFFF; + block_address = pos >> 16; + if (_bgzf_seek(fp->fp, block_address, SEEK_SET) < 0) { + fp->errcode |= BGZF_ERR_IO; + return -1; + } + fp->block_length = 0; // indicates current block has not been loaded + fp->block_address = block_address; + fp->block_offset = block_offset; + return 0; +} + +int bgzf_is_bgzf(const char *fn) +{ + uint8_t buf[16]; + int n; + _bgzf_file_t fp; + if ((fp = _bgzf_open(fn, "r")) == 0) return 0; + n = _bgzf_read(fp, buf, 16); + _bgzf_close(fp); + if (n != 16) return 0; + return memcmp(g_magic, buf, 16) == 0? 1 : 0; +} + +int bgzf_getc(BGZF *fp) +{ + int c; + if (fp->block_offset >= fp->block_length) { + if (bgzf_read_block(fp) != 0) return -2; /* error */ + if (fp->block_length == 0) return -1; /* end-of-file */ + } + c = ((unsigned char*)fp->uncompressed_block)[fp->block_offset++]; + if (fp->block_offset == fp->block_length) { + fp->block_address = _bgzf_tell((_bgzf_file_t)fp->fp); + fp->block_offset = 0; + fp->block_length = 0; + } + return c; +} + +#ifndef kroundup32 +#define kroundup32(x) (--(x), (x)|=(x)>>1, (x)|=(x)>>2, (x)|=(x)>>4, (x)|=(x)>>8, (x)|=(x)>>16, ++(x)) +#endif + +int bgzf_getline(BGZF *fp, int delim, kstring_t *str) +{ + int l, state = 0; + unsigned char *buf = (unsigned char*)fp->uncompressed_block; + str->l = 0; + do { + if (fp->block_offset >= fp->block_length) { + if (bgzf_read_block(fp) != 0) { state = -2; break; } + if (fp->block_length == 0) { state = -1; break; } + } + for (l = fp->block_offset; l < fp->block_length && buf[l] != delim; ++l); + if (l < fp->block_length) state = 1; + l -= fp->block_offset; + if (str->l + l + 1 >= str->m) { + str->m = str->l + l + 2; + kroundup32(str->m); + str->s = (char*)realloc(str->s, str->m); + } + memcpy(str->s + str->l, buf + fp->block_offset, l); + str->l += l; + fp->block_offset += l + 1; + if (fp->block_offset >= fp->block_length) { + fp->block_address = _bgzf_tell((_bgzf_file_t)fp->fp); + fp->block_offset = 0; + fp->block_length = 0; + } + } while (state == 0); + if (str->l == 0 && state < 0) return state; + str->s[str->l] = 0; + return str->l; +} diff --git a/web/server/h2o/libh2o/deps/klib/bgzf.h b/web/server/h2o/libh2o/deps/klib/bgzf.h new file mode 100644 index 00000000..29fe0e5d --- /dev/null +++ b/web/server/h2o/libh2o/deps/klib/bgzf.h @@ -0,0 +1,196 @@ +/* The MIT License + + Copyright (c) 2008 Broad Institute / Massachusetts Institute of Technology + 2011 Attractive Chaos + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + +/* The BGZF library was originally written by Bob Handsaker from the Broad + * Institute. It was later improved by the SAMtools developers. */ + +#ifndef __BGZF_H +#define __BGZF_H + +#include +#include +#include + +#define BGZF_BLOCK_SIZE 0x10000 +#define BGZF_MAX_BLOCK_SIZE 0x10000 + +#define BGZF_ERR_ZLIB 1 +#define BGZF_ERR_HEADER 2 +#define BGZF_ERR_IO 4 +#define BGZF_ERR_MISUSE 8 + +typedef struct { + int open_mode:8, compress_level:8, errcode:16; + int cache_size; + int block_length, block_offset; + int64_t block_address; + void *uncompressed_block, *compressed_block; + void *cache; // a pointer to a hash table + void *fp; // actual file handler; FILE* on writing; FILE* or knetFile* on reading +} BGZF; + +#ifndef KSTRING_T +#define KSTRING_T kstring_t +typedef struct __kstring_t { + size_t l, m; + char *s; +} kstring_t; +#endif + +#ifdef __cplusplus +extern "C" { +#endif + + /****************** + * Basic routines * + ******************/ + + /** + * Open an existing file descriptor for reading or writing. + * + * @param fd file descriptor + * @param mode mode matching /[rwu0-9]+/: 'r' for reading, 'w' for writing and a digit specifies + * the zlib compression level; if both 'r' and 'w' are present, 'w' is ignored. + * @return BGZF file handler; 0 on error + */ + BGZF* bgzf_dopen(int fd, const char *mode); + + #define bgzf_fdopen(fd, mode) bgzf_dopen((fd), (mode)) // for backward compatibility + + /** + * Open the specified file for reading or writing. + */ + BGZF* bgzf_open(const char* path, const char *mode); + + /** + * Close the BGZF and free all associated resources. + * + * @param fp BGZF file handler + * @return 0 on success and -1 on error + */ + int bgzf_close(BGZF *fp); + + /** + * Read up to _length_ bytes from the file storing into _data_. + * + * @param fp BGZF file handler + * @param data data array to read into + * @param length size of data to read + * @return number of bytes actually read; 0 on end-of-file and -1 on error + */ + ssize_t bgzf_read(BGZF *fp, void *data, ssize_t length); + + /** + * Write _length_ bytes from _data_ to the file. + * + * @param fp BGZF file handler + * @param data data array to write + * @param length size of data to write + * @return number of bytes actually written; -1 on error + */ + ssize_t bgzf_write(BGZF *fp, const void *data, ssize_t length); + + /** + * Write the data in the buffer to the file. + */ + int bgzf_flush(BGZF *fp); + + /** + * Return a virtual file pointer to the current location in the file. + * No interpetation of the value should be made, other than a subsequent + * call to bgzf_seek can be used to position the file at the same point. + * Return value is non-negative on success. + */ + #define bgzf_tell(fp) ((fp->block_address << 16) | (fp->block_offset & 0xFFFF)) + + /** + * Set the file to read from the location specified by _pos_. + * + * @param fp BGZF file handler + * @param pos virtual file offset returned by bgzf_tell() + * @param whence must be SEEK_SET + * @return 0 on success and -1 on error + */ + int64_t bgzf_seek(BGZF *fp, int64_t pos, int whence); + + /** + * Check if the BGZF end-of-file (EOF) marker is present + * + * @param fp BGZF file handler opened for reading + * @return 1 if EOF is present; 0 if not or on I/O error + */ + int bgzf_check_EOF(BGZF *fp); + + /** + * Check if a file is in the BGZF format + * + * @param fn file name + * @return 1 if _fn_ is BGZF; 0 if not or on I/O error + */ + int bgzf_is_bgzf(const char *fn); + + /********************* + * Advanced routines * + *********************/ + + /** + * Set the cache size. Only effective when compiled with -DBGZF_CACHE. + * + * @param fp BGZF file handler + * @param size size of cache in bytes; 0 to disable caching (default) + */ + void bgzf_set_cache_size(BGZF *fp, int size); + + /** + * Flush the file if the remaining buffer size is smaller than _size_ + */ + int bgzf_flush_try(BGZF *fp, ssize_t size); + + /** + * Read one byte from a BGZF file. It is faster than bgzf_read() + * @param fp BGZF file handler + * @return byte read; -1 on end-of-file or error + */ + int bgzf_getc(BGZF *fp); + + /** + * Read one line from a BGZF file. It is faster than bgzf_getc() + * + * @param fp BGZF file handler + * @param delim delimitor + * @param str string to write to; must be initialized + * @return length of the string; 0 on end-of-file; negative on error + */ + int bgzf_getline(BGZF *fp, int delim, kstring_t *str); + + /** + * Read the next BGZF block. + */ + int bgzf_read_block(BGZF *fp); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/web/server/h2o/libh2o/deps/klib/kbit.h b/web/server/h2o/libh2o/deps/klib/kbit.h new file mode 100644 index 00000000..3793cf83 --- /dev/null +++ b/web/server/h2o/libh2o/deps/klib/kbit.h @@ -0,0 +1,30 @@ +#ifndef KBIT_H +#define KBIT_H + +#include + +static inline uint64_t kbi_popcount64(uint64_t y) // standard popcount; from wikipedia +{ + y -= ((y >> 1) & 0x5555555555555555ull); + y = (y & 0x3333333333333333ull) + (y >> 2 & 0x3333333333333333ull); + return ((y + (y >> 4)) & 0xf0f0f0f0f0f0f0full) * 0x101010101010101ull >> 56; +} + +static inline uint64_t kbi_DNAcount64(uint64_t y, int c) // count #A/C/G/T from a 2-bit encoded integer; from BWA +{ + // reduce nucleotide counting to bits counting + y = ((c&2)? y : ~y) >> 1 & ((c&1)? y : ~y) & 0x5555555555555555ull; + // count the number of 1s in y + y = (y & 0x3333333333333333ull) + (y >> 2 & 0x3333333333333333ull); + return ((y + (y >> 4)) & 0xf0f0f0f0f0f0f0full) * 0x101010101010101ull >> 56; +} + +#ifndef kroundup32 // round a 32-bit integer to the next closet integer; from "bit twiddling hacks" +#define kroundup32(x) (--(x), (x)|=(x)>>1, (x)|=(x)>>2, (x)|=(x)>>4, (x)|=(x)>>8, (x)|=(x)>>16, ++(x)) +#endif + +#ifndef kbi_swap +#define kbi_swap(a, b) (((a) ^= (b)), ((b) ^= (a)), ((a) ^= (b))) // from "bit twiddling hacks" +#endif + +#endif diff --git a/web/server/h2o/libh2o/deps/klib/kbtree.h b/web/server/h2o/libh2o/deps/klib/kbtree.h new file mode 100644 index 00000000..5ed5330b --- /dev/null +++ b/web/server/h2o/libh2o/deps/klib/kbtree.h @@ -0,0 +1,384 @@ +/*- + * Copyright 1997-1999, 2001, John-Mark Gurney. + * 2008-2009, Attractive Chaos + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef __AC_KBTREE_H +#define __AC_KBTREE_H + +#include +#include +#include + +typedef struct { + int32_t is_internal:1, n:31; +} kbnode_t; + +#define __KB_KEY(type, x) ((type*)((char*)x + 4)) +#define __KB_PTR(btr, x) ((kbnode_t**)((char*)x + btr->off_ptr)) + +#define __KB_TREE_T(name) \ + typedef struct { \ + kbnode_t *root; \ + int off_key, off_ptr, ilen, elen; \ + int n, t; \ + int n_keys, n_nodes; \ + } kbtree_##name##_t; + +#define __KB_INIT(name, key_t) \ + kbtree_##name##_t *kb_init_##name(int size) \ + { \ + kbtree_##name##_t *b; \ + b = (kbtree_##name##_t*)calloc(1, sizeof(kbtree_##name##_t)); \ + b->t = ((size - 4 - sizeof(void*)) / (sizeof(void*) + sizeof(key_t)) + 1) >> 1; \ + if (b->t < 2) { \ + free(b); return 0; \ + } \ + b->n = 2 * b->t - 1; \ + b->off_ptr = 4 + b->n * sizeof(key_t); \ + b->ilen = (4 + sizeof(void*) + b->n * (sizeof(void*) + sizeof(key_t)) + 3) >> 2 << 2; \ + b->elen = (b->off_ptr + 3) >> 2 << 2; \ + b->root = (kbnode_t*)calloc(1, b->ilen); \ + ++b->n_nodes; \ + return b; \ + } + +#define __kb_destroy(b) do { \ + int i, max = 8; \ + kbnode_t *x, **top, **stack = 0; \ + if (b) { \ + top = stack = (kbnode_t**)calloc(max, sizeof(kbnode_t*)); \ + *top++ = (b)->root; \ + while (top != stack) { \ + x = *--top; \ + if (x->is_internal == 0) { free(x); continue; } \ + for (i = 0; i <= x->n; ++i) \ + if (__KB_PTR(b, x)[i]) { \ + if (top - stack == max) { \ + max <<= 1; \ + stack = (kbnode_t**)realloc(stack, max * sizeof(kbnode_t*)); \ + top = stack + (max>>1); \ + } \ + *top++ = __KB_PTR(b, x)[i]; \ + } \ + free(x); \ + } \ + } \ + free(b); free(stack); \ + } while (0) + +#define __kb_get_first(key_t, b, ret) do { \ + kbnode_t *__x = (b)->root; \ + while (__KB_PTR(b, __x)[0] != 0) \ + __x = __KB_PTR(b, __x)[0]; \ + (ret) = __KB_KEY(key_t, __x)[0]; \ + } while (0) + +#define __KB_GET_AUX0(name, key_t, __cmp) \ + static inline int __kb_get_aux_##name(const kbnode_t * __restrict x, const key_t * __restrict k, int *r) \ + { \ + int tr, *rr, begin, end, n = x->n >> 1; \ + if (x->n == 0) return -1; \ + if (__cmp(*k, __KB_KEY(key_t, x)[n]) < 0) { \ + begin = 0; end = n; \ + } else { begin = n; end = x->n - 1; } \ + rr = r? r : &tr; \ + n = end; \ + while (n >= begin && (*rr = __cmp(*k, __KB_KEY(key_t, x)[n])) < 0) --n; \ + return n; \ + } + +#define __KB_GET_AUX1(name, key_t, __cmp) \ + static inline int __kb_getp_aux_##name(const kbnode_t * __restrict x, const key_t * __restrict k, int *r) \ + { \ + int tr, *rr, begin = 0, end = x->n; \ + if (x->n == 0) return -1; \ + rr = r? r : &tr; \ + while (begin < end) { \ + int mid = (begin + end) >> 1; \ + if (__cmp(__KB_KEY(key_t, x)[mid], *k) < 0) begin = mid + 1; \ + else end = mid; \ + } \ + if (begin == x->n) { *rr = 1; return x->n - 1; } \ + if ((*rr = __cmp(*k, __KB_KEY(key_t, x)[begin])) < 0) --begin; \ + return begin; \ + } + +#define __KB_GET(name, key_t) \ + static key_t *kb_getp_##name(kbtree_##name##_t *b, const key_t * __restrict k) \ + { \ + int i, r = 0; \ + kbnode_t *x = b->root; \ + while (x) { \ + i = __kb_getp_aux_##name(x, k, &r); \ + if (i >= 0 && r == 0) return &__KB_KEY(key_t, x)[i]; \ + if (x->is_internal == 0) return 0; \ + x = __KB_PTR(b, x)[i + 1]; \ + } \ + return 0; \ + } \ + static inline key_t *kb_get_##name(kbtree_##name##_t *b, const key_t k) \ + { \ + return kb_getp_##name(b, &k); \ + } + +#define __KB_INTERVAL(name, key_t) \ + static void kb_intervalp_##name(kbtree_##name##_t *b, const key_t * __restrict k, key_t **lower, key_t **upper) \ + { \ + int i, r = 0; \ + kbnode_t *x = b->root; \ + *lower = *upper = 0; \ + while (x) { \ + i = __kb_getp_aux_##name(x, k, &r); \ + if (i >= 0 && r == 0) { \ + *lower = *upper = &__KB_KEY(key_t, x)[i]; \ + return; \ + } \ + if (i >= 0) *lower = &__KB_KEY(key_t, x)[i]; \ + if (i < x->n - 1) *upper = &__KB_KEY(key_t, x)[i + 1]; \ + if (x->is_internal == 0) return; \ + x = __KB_PTR(b, x)[i + 1]; \ + } \ + } \ + static inline void kb_interval_##name(kbtree_##name##_t *b, const key_t k, key_t **lower, key_t **upper) \ + { \ + kb_intervalp_##name(b, &k, lower, upper); \ + } + +#define __KB_PUT(name, key_t, __cmp) \ + /* x must be an internal node */ \ + static void __kb_split_##name(kbtree_##name##_t *b, kbnode_t *x, int i, kbnode_t *y) \ + { \ + kbnode_t *z; \ + z = (kbnode_t*)calloc(1, y->is_internal? b->ilen : b->elen); \ + ++b->n_nodes; \ + z->is_internal = y->is_internal; \ + z->n = b->t - 1; \ + memcpy(__KB_KEY(key_t, z), __KB_KEY(key_t, y) + b->t, sizeof(key_t) * (b->t - 1)); \ + if (y->is_internal) memcpy(__KB_PTR(b, z), __KB_PTR(b, y) + b->t, sizeof(void*) * b->t); \ + y->n = b->t - 1; \ + memmove(__KB_PTR(b, x) + i + 2, __KB_PTR(b, x) + i + 1, sizeof(void*) * (x->n - i)); \ + __KB_PTR(b, x)[i + 1] = z; \ + memmove(__KB_KEY(key_t, x) + i + 1, __KB_KEY(key_t, x) + i, sizeof(key_t) * (x->n - i)); \ + __KB_KEY(key_t, x)[i] = __KB_KEY(key_t, y)[b->t - 1]; \ + ++x->n; \ + } \ + static void __kb_putp_aux_##name(kbtree_##name##_t *b, kbnode_t *x, const key_t * __restrict k) \ + { \ + int i = x->n - 1; \ + if (x->is_internal == 0) { \ + i = __kb_getp_aux_##name(x, k, 0); \ + if (i != x->n - 1) \ + memmove(__KB_KEY(key_t, x) + i + 2, __KB_KEY(key_t, x) + i + 1, (x->n - i - 1) * sizeof(key_t)); \ + __KB_KEY(key_t, x)[i + 1] = *k; \ + ++x->n; \ + } else { \ + i = __kb_getp_aux_##name(x, k, 0) + 1; \ + if (__KB_PTR(b, x)[i]->n == 2 * b->t - 1) { \ + __kb_split_##name(b, x, i, __KB_PTR(b, x)[i]); \ + if (__cmp(*k, __KB_KEY(key_t, x)[i]) > 0) ++i; \ + } \ + __kb_putp_aux_##name(b, __KB_PTR(b, x)[i], k); \ + } \ + } \ + static void kb_putp_##name(kbtree_##name##_t *b, const key_t * __restrict k) \ + { \ + kbnode_t *r, *s; \ + ++b->n_keys; \ + r = b->root; \ + if (r->n == 2 * b->t - 1) { \ + ++b->n_nodes; \ + s = (kbnode_t*)calloc(1, b->ilen); \ + b->root = s; s->is_internal = 1; s->n = 0; \ + __KB_PTR(b, s)[0] = r; \ + __kb_split_##name(b, s, 0, r); \ + r = s; \ + } \ + __kb_putp_aux_##name(b, r, k); \ + } \ + static inline void kb_put_##name(kbtree_##name##_t *b, const key_t k) \ + { \ + kb_putp_##name(b, &k); \ + } + + +#define __KB_DEL(name, key_t) \ + static key_t __kb_delp_aux_##name(kbtree_##name##_t *b, kbnode_t *x, const key_t * __restrict k, int s) \ + { \ + int yn, zn, i, r = 0; \ + kbnode_t *xp, *y, *z; \ + key_t kp; \ + if (x == 0) return *k; \ + if (s) { /* s can only be 0, 1 or 2 */ \ + r = x->is_internal == 0? 0 : s == 1? 1 : -1; \ + i = s == 1? x->n - 1 : -1; \ + } else i = __kb_getp_aux_##name(x, k, &r); \ + if (x->is_internal == 0) { \ + if (s == 2) ++i; \ + kp = __KB_KEY(key_t, x)[i]; \ + memmove(__KB_KEY(key_t, x) + i, __KB_KEY(key_t, x) + i + 1, (x->n - i - 1) * sizeof(key_t)); \ + --x->n; \ + return kp; \ + } \ + if (r == 0) { \ + if ((yn = __KB_PTR(b, x)[i]->n) >= b->t) { \ + xp = __KB_PTR(b, x)[i]; \ + kp = __KB_KEY(key_t, x)[i]; \ + __KB_KEY(key_t, x)[i] = __kb_delp_aux_##name(b, xp, 0, 1); \ + return kp; \ + } else if ((zn = __KB_PTR(b, x)[i + 1]->n) >= b->t) { \ + xp = __KB_PTR(b, x)[i + 1]; \ + kp = __KB_KEY(key_t, x)[i]; \ + __KB_KEY(key_t, x)[i] = __kb_delp_aux_##name(b, xp, 0, 2); \ + return kp; \ + } else if (yn == b->t - 1 && zn == b->t - 1) { \ + y = __KB_PTR(b, x)[i]; z = __KB_PTR(b, x)[i + 1]; \ + __KB_KEY(key_t, y)[y->n++] = *k; \ + memmove(__KB_KEY(key_t, y) + y->n, __KB_KEY(key_t, z), z->n * sizeof(key_t)); \ + if (y->is_internal) memmove(__KB_PTR(b, y) + y->n, __KB_PTR(b, z), (z->n + 1) * sizeof(void*)); \ + y->n += z->n; \ + memmove(__KB_KEY(key_t, x) + i, __KB_KEY(key_t, x) + i + 1, (x->n - i - 1) * sizeof(key_t)); \ + memmove(__KB_PTR(b, x) + i + 1, __KB_PTR(b, x) + i + 2, (x->n - i - 1) * sizeof(void*)); \ + --x->n; \ + free(z); \ + return __kb_delp_aux_##name(b, y, k, s); \ + } \ + } \ + ++i; \ + if ((xp = __KB_PTR(b, x)[i])->n == b->t - 1) { \ + if (i > 0 && (y = __KB_PTR(b, x)[i - 1])->n >= b->t) { \ + memmove(__KB_KEY(key_t, xp) + 1, __KB_KEY(key_t, xp), xp->n * sizeof(key_t)); \ + if (xp->is_internal) memmove(__KB_PTR(b, xp) + 1, __KB_PTR(b, xp), (xp->n + 1) * sizeof(void*)); \ + __KB_KEY(key_t, xp)[0] = __KB_KEY(key_t, x)[i - 1]; \ + __KB_KEY(key_t, x)[i - 1] = __KB_KEY(key_t, y)[y->n - 1]; \ + if (xp->is_internal) __KB_PTR(b, xp)[0] = __KB_PTR(b, y)[y->n]; \ + --y->n; ++xp->n; \ + } else if (i < x->n && (y = __KB_PTR(b, x)[i + 1])->n >= b->t) { \ + __KB_KEY(key_t, xp)[xp->n++] = __KB_KEY(key_t, x)[i]; \ + __KB_KEY(key_t, x)[i] = __KB_KEY(key_t, y)[0]; \ + if (xp->is_internal) __KB_PTR(b, xp)[xp->n] = __KB_PTR(b, y)[0]; \ + --y->n; \ + memmove(__KB_KEY(key_t, y), __KB_KEY(key_t, y) + 1, y->n * sizeof(key_t)); \ + if (y->is_internal) memmove(__KB_PTR(b, y), __KB_PTR(b, y) + 1, (y->n + 1) * sizeof(void*)); \ + } else if (i > 0 && (y = __KB_PTR(b, x)[i - 1])->n == b->t - 1) { \ + __KB_KEY(key_t, y)[y->n++] = __KB_KEY(key_t, x)[i - 1]; \ + memmove(__KB_KEY(key_t, y) + y->n, __KB_KEY(key_t, xp), xp->n * sizeof(key_t)); \ + if (y->is_internal) memmove(__KB_PTR(b, y) + y->n, __KB_PTR(b, xp), (xp->n + 1) * sizeof(void*)); \ + y->n += xp->n; \ + memmove(__KB_KEY(key_t, x) + i - 1, __KB_KEY(key_t, x) + i, (x->n - i) * sizeof(key_t)); \ + memmove(__KB_PTR(b, x) + i, __KB_PTR(b, x) + i + 1, (x->n - i) * sizeof(void*)); \ + --x->n; \ + free(xp); \ + xp = y; \ + } else if (i < x->n && (y = __KB_PTR(b, x)[i + 1])->n == b->t - 1) { \ + __KB_KEY(key_t, xp)[xp->n++] = __KB_KEY(key_t, x)[i]; \ + memmove(__KB_KEY(key_t, xp) + xp->n, __KB_KEY(key_t, y), y->n * sizeof(key_t)); \ + if (xp->is_internal) memmove(__KB_PTR(b, xp) + xp->n, __KB_PTR(b, y), (y->n + 1) * sizeof(void*)); \ + xp->n += y->n; \ + memmove(__KB_KEY(key_t, x) + i, __KB_KEY(key_t, x) + i + 1, (x->n - i - 1) * sizeof(key_t)); \ + memmove(__KB_PTR(b, x) + i + 1, __KB_PTR(b, x) + i + 2, (x->n - i - 1) * sizeof(void*)); \ + --x->n; \ + free(y); \ + } \ + } \ + return __kb_delp_aux_##name(b, xp, k, s); \ + } \ + static key_t kb_delp_##name(kbtree_##name##_t *b, const key_t * __restrict k) \ + { \ + kbnode_t *x; \ + key_t ret; \ + ret = __kb_delp_aux_##name(b, b->root, k, 0); \ + --b->n_keys; \ + if (b->root->n == 0 && b->root->is_internal) { \ + --b->n_nodes; \ + x = b->root; \ + b->root = __KB_PTR(b, x)[0]; \ + free(x); \ + } \ + return ret; \ + } \ + static inline key_t kb_del_##name(kbtree_##name##_t *b, const key_t k) \ + { \ + return kb_delp_##name(b, &k); \ + } + +typedef struct { + kbnode_t *x; + int i; +} __kbstack_t; + +#define __kb_traverse(key_t, b, __func) do { \ + int __kmax = 8; \ + __kbstack_t *__kstack, *__kp; \ + __kp = __kstack = (__kbstack_t*)calloc(__kmax, sizeof(__kbstack_t)); \ + __kp->x = (b)->root; __kp->i = 0; \ + for (;;) { \ + while (__kp->x && __kp->i <= __kp->x->n) { \ + if (__kp - __kstack == __kmax - 1) { \ + __kmax <<= 1; \ + __kstack = (__kbstack_t*)realloc(__kstack, __kmax * sizeof(__kbstack_t)); \ + __kp = __kstack + (__kmax>>1) - 1; \ + } \ + (__kp+1)->i = 0; (__kp+1)->x = __kp->x->is_internal? __KB_PTR(b, __kp->x)[__kp->i] : 0; \ + ++__kp; \ + } \ + --__kp; \ + if (__kp >= __kstack) { \ + if (__kp->x && __kp->i < __kp->x->n) __func(&__KB_KEY(key_t, __kp->x)[__kp->i]); \ + ++__kp->i; \ + } else break; \ + } \ + free(__kstack); \ + } while (0) + +#define KBTREE_INIT(name, key_t, __cmp) \ + __KB_TREE_T(name) \ + __KB_INIT(name, key_t) \ + __KB_GET_AUX1(name, key_t, __cmp) \ + __KB_GET(name, key_t) \ + __KB_INTERVAL(name, key_t) \ + __KB_PUT(name, key_t, __cmp) \ + __KB_DEL(name, key_t) + +#define KB_DEFAULT_SIZE 512 + +#define kbtree_t(name) kbtree_##name##_t +#define kb_init(name, s) kb_init_##name(s) +#define kb_destroy(name, b) __kb_destroy(b) +#define kb_get(name, b, k) kb_get_##name(b, k) +#define kb_put(name, b, k) kb_put_##name(b, k) +#define kb_del(name, b, k) kb_del_##name(b, k) +#define kb_interval(name, b, k, l, u) kb_interval_##name(b, k, l, u) +#define kb_getp(name, b, k) kb_getp_##name(b, k) +#define kb_putp(name, b, k) kb_putp_##name(b, k) +#define kb_delp(name, b, k) kb_delp_##name(b, k) +#define kb_intervalp(name, b, k, l, u) kb_intervalp_##name(b, k, l, u) + +#define kb_size(b) ((b)->n_keys) + +#define kb_generic_cmp(a, b) (((b) < (a)) - ((a) < (b))) +#define kb_str_cmp(a, b) strcmp(a, b) + +#endif diff --git a/web/server/h2o/libh2o/deps/klib/kgraph.h b/web/server/h2o/libh2o/deps/klib/kgraph.h new file mode 100644 index 00000000..af008ef7 --- /dev/null +++ b/web/server/h2o/libh2o/deps/klib/kgraph.h @@ -0,0 +1,79 @@ +#ifndef AC_KGRAPH_H +#define AC_KGRAPH_H + +#include +#include +#include "khash.h" +#include "kbtree.h" + +typedef unsigned kgint_t; + +#define kgraph_t(name) kh_##name##_t + +#define __KG_BASIC(name, SCOPE, vertex_t, arc_t, ehn) \ + SCOPE kgraph_t(name) *kg_init_##name(void) { return kh_init(name); } \ + SCOPE void kg_destroy_##name(kgraph_t(name) *g) { \ + khint_t k; \ + if (g == 0) return; \ + for (k = kh_begin(g); k != kh_end(g); ++k) \ + if (kh_exist(g, k)) kh_destroy(ehn, kh_val(g, k)._arc); \ + kh_destroy(name, g); \ + } \ + SCOPE vertex_t *kg_get_v_##name(kgraph_t(name) *g, kgint_t v) { \ + khint_t k = kh_get(name, g, v); \ + return k == kh_end(g)? 0 : &kh_val(g, k); \ + } \ + SCOPE vertex_t *kg_put_v_##name(kgraph_t(name) *g, kgint_t v, int *absent) { \ + khint_t k; \ + k = kh_put(name, g, v, absent); \ + if (*absent) kh_val(g, k)._arc = kh_init(ehn); \ + return &kh_val(g, k); \ + } \ + SCOPE void kg_put_a_##name(kgraph_t(name) *g, kgint_t vbeg, kgint_t vend, int dir, arc_t **pb, arc_t **pe) { \ + vertex_t *p; \ + khint_t k; \ + int absent; \ + p = kg_put_v_##name(g, vbeg, &absent); \ + k = kh_put(ehn, p->_arc, vend<<2|dir, &absent); \ + *pb = &kh_val(p->_arc, k); \ + p = kg_put_v_##name(g, vend, &absent); \ + k = kh_put(ehn, p->_arc, vbeg<<2|(~dir&3), &absent); \ + *pe = &kh_val(p->_arc, k); \ + } \ + SCOPE vertex_t *kg_del_v_##name(kgraph_t(name) *g, kgint_t v) { \ + khint_t k, k0, k2, k3; \ + khash_t(ehn) *h; \ + k0 = k = kh_get(name, g, v); \ + if (k == kh_end(g)) return 0; /* not present in the graph */ \ + h = kh_val(g, k)._arc; \ + for (k = kh_begin(h); k != kh_end(h); ++k) /* remove v from its neighbors */ \ + if (kh_exist(h, k)) { \ + k2 = kh_get(name, g, kh_key(h, k)>>2); \ + /* assert(k2 != kh_end(g)); */ \ + k3 = kh_get(ehn, kh_val(g, k2)._arc, v<<2|(~kh_key(h, k)&3)); \ + /* assert(k3 != kh_end(kh_val(g, k2)._arc)); */ \ + kh_del(ehn, kh_val(g, k2)._arc, k3); \ + } \ + kh_destroy(ehn, h); \ + kh_del(name, g, k0); \ + return &kh_val(g, k0); \ + } + +#define KGRAPH_PRINT(name, SCOPE) \ + SCOPE void kg_print_##name(kgraph_t(name) *g) { \ + khint_t k, k2; \ + for (k = kh_begin(g); k != kh_end(g); ++k) \ + if (kh_exist(g, k)) { \ + printf("v %u\n", kh_key(g, k)); \ + for (k2 = kh_begin(kh_val(g, k)._arc); k2 != kh_end(kh_val(g, k)._arc); ++k2) \ + if (kh_exist(kh_val(g, k)._arc, k2) && kh_key(g, k) < kh_key(kh_val(g, k)._arc, k2)>>2) \ + printf("a %u%c%c%u\n", kh_key(g, k), "><"[kh_key(kh_val(g, k)._arc, k2)>>1&1], \ + "><"[kh_key(kh_val(g, k)._arc, k2)&1], kh_key(kh_val(g, k)._arc, k2)>>2); \ + } \ + } + +#define KGRAPH_INIT(name, SCOPE, vertex_t, arc_t, ehn) \ + KHASH_INIT2(name, SCOPE, kgint_t, vertex_t, 1, kh_int_hash_func, kh_int_hash_equal) \ + __KG_BASIC(name, SCOPE, vertex_t, arc_t, ehn) + +#endif diff --git a/web/server/h2o/libh2o/deps/klib/khash.h b/web/server/h2o/libh2o/deps/klib/khash.h new file mode 100644 index 00000000..5e55088b --- /dev/null +++ b/web/server/h2o/libh2o/deps/klib/khash.h @@ -0,0 +1,619 @@ +/* The MIT License + + Copyright (c) 2008, 2009, 2011 by Attractive Chaos + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. +*/ + +/* + An example: + +#include "khash.h" +KHASH_MAP_INIT_INT(32, char) +int main() { + int ret, is_missing; + khiter_t k; + khash_t(32) *h = kh_init(32); + k = kh_put(32, h, 5, &ret); + kh_value(h, k) = 10; + k = kh_get(32, h, 10); + is_missing = (k == kh_end(h)); + k = kh_get(32, h, 5); + kh_del(32, h, k); + for (k = kh_begin(h); k != kh_end(h); ++k) + if (kh_exist(h, k)) kh_value(h, k) = 1; + kh_destroy(32, h); + return 0; +} +*/ + +/* + 2013-05-02 (0.2.8): + + * Use quadratic probing. When the capacity is power of 2, stepping function + i*(i+1)/2 guarantees to traverse each bucket. It is better than double + hashing on cache performance and is more robust than linear probing. + + In theory, double hashing should be more robust than quadratic probing. + However, my implementation is probably not for large hash tables, because + the second hash function is closely tied to the first hash function, + which reduce the effectiveness of double hashing. + + Reference: http://research.cs.vt.edu/AVresearch/hashing/quadratic.php + + 2011-12-29 (0.2.7): + + * Minor code clean up; no actual effect. + + 2011-09-16 (0.2.6): + + * The capacity is a power of 2. This seems to dramatically improve the + speed for simple keys. Thank Zilong Tan for the suggestion. Reference: + + - http://code.google.com/p/ulib/ + - http://nothings.org/computer/judy/ + + * Allow to optionally use linear probing which usually has better + performance for random input. Double hashing is still the default as it + is more robust to certain non-random input. + + * Added Wang's integer hash function (not used by default). This hash + function is more robust to certain non-random input. + + 2011-02-14 (0.2.5): + + * Allow to declare global functions. + + 2009-09-26 (0.2.4): + + * Improve portability + + 2008-09-19 (0.2.3): + + * Corrected the example + * Improved interfaces + + 2008-09-11 (0.2.2): + + * Improved speed a little in kh_put() + + 2008-09-10 (0.2.1): + + * Added kh_clear() + * Fixed a compiling error + + 2008-09-02 (0.2.0): + + * Changed to token concatenation which increases flexibility. + + 2008-08-31 (0.1.2): + + * Fixed a bug in kh_get(), which has not been tested previously. + + 2008-08-31 (0.1.1): + + * Added destructor +*/ + + +#ifndef __AC_KHASH_H +#define __AC_KHASH_H + +/*! + @header + + Generic hash table library. + */ + +#define AC_VERSION_KHASH_H "0.2.8" + +#include +#include +#include + +/* compiler specific configuration */ + +#if UINT_MAX == 0xffffffffu +typedef unsigned int khint32_t; +#elif ULONG_MAX == 0xffffffffu +typedef unsigned long khint32_t; +#endif + +#if ULONG_MAX == ULLONG_MAX +typedef unsigned long khint64_t; +#else +typedef unsigned long long khint64_t; +#endif + +#ifndef kh_inline +#ifdef _MSC_VER +#define kh_inline __inline +#else +#define kh_inline inline +#endif +#endif /* kh_inline */ + +typedef khint32_t khint_t; +typedef khint_t khiter_t; + +#define __ac_isempty(flag, i) ((flag[i>>4]>>((i&0xfU)<<1))&2) +#define __ac_isdel(flag, i) ((flag[i>>4]>>((i&0xfU)<<1))&1) +#define __ac_iseither(flag, i) ((flag[i>>4]>>((i&0xfU)<<1))&3) +#define __ac_set_isdel_false(flag, i) (flag[i>>4]&=~(1ul<<((i&0xfU)<<1))) +#define __ac_set_isempty_false(flag, i) (flag[i>>4]&=~(2ul<<((i&0xfU)<<1))) +#define __ac_set_isboth_false(flag, i) (flag[i>>4]&=~(3ul<<((i&0xfU)<<1))) +#define __ac_set_isdel_true(flag, i) (flag[i>>4]|=1ul<<((i&0xfU)<<1)) + +#define __ac_fsize(m) ((m) < 16? 1 : (m)>>4) + +#ifndef kroundup32 +#define kroundup32(x) (--(x), (x)|=(x)>>1, (x)|=(x)>>2, (x)|=(x)>>4, (x)|=(x)>>8, (x)|=(x)>>16, ++(x)) +#endif + +#ifndef kcalloc +#define kcalloc(N,Z) calloc(N,Z) +#endif +#ifndef kmalloc +#define kmalloc(Z) malloc(Z) +#endif +#ifndef krealloc +#define krealloc(P,Z) realloc(P,Z) +#endif +#ifndef kfree +#define kfree(P) free(P) +#endif + +static const double __ac_HASH_UPPER = 0.77; + +#define __KHASH_TYPE(name, khkey_t, khval_t) \ + typedef struct kh_##name##_s { \ + khint_t n_buckets, size, n_occupied, upper_bound; \ + khint32_t *flags; \ + khkey_t *keys; \ + khval_t *vals; \ + } kh_##name##_t; + +#define __KHASH_PROTOTYPES(name, khkey_t, khval_t) \ + extern kh_##name##_t *kh_init_##name(void); \ + extern void kh_destroy_##name(kh_##name##_t *h); \ + extern void kh_clear_##name(kh_##name##_t *h); \ + extern khint_t kh_get_##name(const kh_##name##_t *h, khkey_t key); \ + extern int kh_resize_##name(kh_##name##_t *h, khint_t new_n_buckets); \ + extern khint_t kh_put_##name(kh_##name##_t *h, khkey_t key, int *ret); \ + extern void kh_del_##name(kh_##name##_t *h, khint_t x); + +#define __KHASH_IMPL(name, SCOPE, khkey_t, khval_t, kh_is_map, __hash_func, __hash_equal) \ + SCOPE kh_##name##_t *kh_init_##name(void) { \ + return (kh_##name##_t*)kcalloc(1, sizeof(kh_##name##_t)); \ + } \ + SCOPE void kh_destroy_##name(kh_##name##_t *h) \ + { \ + if (h) { \ + kfree((void *)h->keys); kfree(h->flags); \ + kfree((void *)h->vals); \ + kfree(h); \ + } \ + } \ + SCOPE void kh_clear_##name(kh_##name##_t *h) \ + { \ + if (h && h->flags) { \ + memset(h->flags, 0xaa, __ac_fsize(h->n_buckets) * sizeof(khint32_t)); \ + h->size = h->n_occupied = 0; \ + } \ + } \ + SCOPE khint_t kh_get_##name(const kh_##name##_t *h, khkey_t key) \ + { \ + if (h->n_buckets) { \ + khint_t k, i, last, mask, step = 0; \ + mask = h->n_buckets - 1; \ + k = __hash_func(key); i = k & mask; \ + last = i; \ + while (!__ac_isempty(h->flags, i) && (__ac_isdel(h->flags, i) || !__hash_equal(h->keys[i], key))) { \ + i = (i + (++step)) & mask; \ + if (i == last) return h->n_buckets; \ + } \ + return __ac_iseither(h->flags, i)? h->n_buckets : i; \ + } else return 0; \ + } \ + SCOPE int kh_resize_##name(kh_##name##_t *h, khint_t new_n_buckets) \ + { /* This function uses 0.25*n_buckets bytes of working space instead of [sizeof(key_t+val_t)+.25]*n_buckets. */ \ + khint32_t *new_flags = 0; \ + khint_t j = 1; \ + { \ + kroundup32(new_n_buckets); \ + if (new_n_buckets < 4) new_n_buckets = 4; \ + if (h->size >= (khint_t)(new_n_buckets * __ac_HASH_UPPER + 0.5)) j = 0; /* requested size is too small */ \ + else { /* hash table size to be changed (shrink or expand); rehash */ \ + new_flags = (khint32_t*)kmalloc(__ac_fsize(new_n_buckets) * sizeof(khint32_t)); \ + if (!new_flags) return -1; \ + memset(new_flags, 0xaa, __ac_fsize(new_n_buckets) * sizeof(khint32_t)); \ + if (h->n_buckets < new_n_buckets) { /* expand */ \ + khkey_t *new_keys = (khkey_t*)krealloc((void *)h->keys, new_n_buckets * sizeof(khkey_t)); \ + if (!new_keys) { kfree(new_flags); return -1; } \ + h->keys = new_keys; \ + if (kh_is_map) { \ + khval_t *new_vals = (khval_t*)krealloc((void *)h->vals, new_n_buckets * sizeof(khval_t)); \ + if (!new_vals) { kfree(new_flags); return -1; } \ + h->vals = new_vals; \ + } \ + } /* otherwise shrink */ \ + } \ + } \ + if (j) { /* rehashing is needed */ \ + for (j = 0; j != h->n_buckets; ++j) { \ + if (__ac_iseither(h->flags, j) == 0) { \ + khkey_t key = h->keys[j]; \ + khval_t val; \ + khint_t new_mask; \ + new_mask = new_n_buckets - 1; \ + if (kh_is_map) val = h->vals[j]; \ + __ac_set_isdel_true(h->flags, j); \ + while (1) { /* kick-out process; sort of like in Cuckoo hashing */ \ + khint_t k, i, step = 0; \ + k = __hash_func(key); \ + i = k & new_mask; \ + while (!__ac_isempty(new_flags, i)) i = (i + (++step)) & new_mask; \ + __ac_set_isempty_false(new_flags, i); \ + if (i < h->n_buckets && __ac_iseither(h->flags, i) == 0) { /* kick out the existing element */ \ + { khkey_t tmp = h->keys[i]; h->keys[i] = key; key = tmp; } \ + if (kh_is_map) { khval_t tmp = h->vals[i]; h->vals[i] = val; val = tmp; } \ + __ac_set_isdel_true(h->flags, i); /* mark it as deleted in the old hash table */ \ + } else { /* write the element and jump out of the loop */ \ + h->keys[i] = key; \ + if (kh_is_map) h->vals[i] = val; \ + break; \ + } \ + } \ + } \ + } \ + if (h->n_buckets > new_n_buckets) { /* shrink the hash table */ \ + h->keys = (khkey_t*)krealloc((void *)h->keys, new_n_buckets * sizeof(khkey_t)); \ + if (kh_is_map) h->vals = (khval_t*)krealloc((void *)h->vals, new_n_buckets * sizeof(khval_t)); \ + } \ + kfree(h->flags); /* free the working space */ \ + h->flags = new_flags; \ + h->n_buckets = new_n_buckets; \ + h->n_occupied = h->size; \ + h->upper_bound = (khint_t)(h->n_buckets * __ac_HASH_UPPER + 0.5); \ + } \ + return 0; \ + } \ + SCOPE khint_t kh_put_##name(kh_##name##_t *h, khkey_t key, int *ret) \ + { \ + khint_t x; \ + if (h->n_occupied >= h->upper_bound) { /* update the hash table */ \ + if (h->n_buckets > (h->size<<1)) { \ + if (kh_resize_##name(h, h->n_buckets - 1) < 0) { /* clear "deleted" elements */ \ + *ret = -1; return h->n_buckets; \ + } \ + } else if (kh_resize_##name(h, h->n_buckets + 1) < 0) { /* expand the hash table */ \ + *ret = -1; return h->n_buckets; \ + } \ + } /* TODO: to implement automatically shrinking; resize() already support shrinking */ \ + { \ + khint_t k, i, site, last, mask = h->n_buckets - 1, step = 0; \ + x = site = h->n_buckets; k = __hash_func(key); i = k & mask; \ + if (__ac_isempty(h->flags, i)) x = i; /* for speed up */ \ + else { \ + last = i; \ + while (!__ac_isempty(h->flags, i) && (__ac_isdel(h->flags, i) || !__hash_equal(h->keys[i], key))) { \ + if (__ac_isdel(h->flags, i)) site = i; \ + i = (i + (++step)) & mask; \ + if (i == last) { x = site; break; } \ + } \ + if (x == h->n_buckets) { \ + if (__ac_isempty(h->flags, i) && site != h->n_buckets) x = site; \ + else x = i; \ + } \ + } \ + } \ + if (__ac_isempty(h->flags, x)) { /* not present at all */ \ + h->keys[x] = key; \ + __ac_set_isboth_false(h->flags, x); \ + ++h->size; ++h->n_occupied; \ + *ret = 1; \ + } else if (__ac_isdel(h->flags, x)) { /* deleted */ \ + h->keys[x] = key; \ + __ac_set_isboth_false(h->flags, x); \ + ++h->size; \ + *ret = 2; \ + } else *ret = 0; /* Don't touch h->keys[x] if present and not deleted */ \ + return x; \ + } \ + SCOPE void kh_del_##name(kh_##name##_t *h, khint_t x) \ + { \ + if (x != h->n_buckets && !__ac_iseither(h->flags, x)) { \ + __ac_set_isdel_true(h->flags, x); \ + --h->size; \ + } \ + } + +#define KHASH_DECLARE(name, khkey_t, khval_t) \ + __KHASH_TYPE(name, khkey_t, khval_t) \ + __KHASH_PROTOTYPES(name, khkey_t, khval_t) + +#define KHASH_INIT2(name, SCOPE, khkey_t, khval_t, kh_is_map, __hash_func, __hash_equal) \ + __KHASH_TYPE(name, khkey_t, khval_t) \ + __KHASH_IMPL(name, SCOPE, khkey_t, khval_t, kh_is_map, __hash_func, __hash_equal) + +#define KHASH_INIT(name, khkey_t, khval_t, kh_is_map, __hash_func, __hash_equal) \ + KHASH_INIT2(name, static kh_inline, khkey_t, khval_t, kh_is_map, __hash_func, __hash_equal) + +/* --- BEGIN OF HASH FUNCTIONS --- */ + +/*! @function + @abstract Integer hash function + @param key The integer [khint32_t] + @return The hash value [khint_t] + */ +#define kh_int_hash_func(key) (khint32_t)(key) +/*! @function + @abstract Integer comparison function + */ +#define kh_int_hash_equal(a, b) ((a) == (b)) +/*! @function + @abstract 64-bit integer hash function + @param key The integer [khint64_t] + @return The hash value [khint_t] + */ +#define kh_int64_hash_func(key) (khint32_t)((key)>>33^(key)^(key)<<11) +/*! @function + @abstract 64-bit integer comparison function + */ +#define kh_int64_hash_equal(a, b) ((a) == (b)) +/*! @function + @abstract const char* hash function + @param s Pointer to a null terminated string + @return The hash value + */ +static kh_inline khint_t __ac_X31_hash_string(const char *s) +{ + khint_t h = (khint_t)*s; + if (h) for (++s ; *s; ++s) h = (h << 5) - h + (khint_t)*s; + return h; +} +/*! @function + @abstract Another interface to const char* hash function + @param key Pointer to a null terminated string [const char*] + @return The hash value [khint_t] + */ +#define kh_str_hash_func(key) __ac_X31_hash_string(key) +/*! @function + @abstract Const char* comparison function + */ +#define kh_str_hash_equal(a, b) (strcmp(a, b) == 0) + +static kh_inline khint_t __ac_Wang_hash(khint_t key) +{ + key += ~(key << 15); + key ^= (key >> 10); + key += (key << 3); + key ^= (key >> 6); + key += ~(key << 11); + key ^= (key >> 16); + return key; +} +#define kh_int_hash_func2(k) __ac_Wang_hash((khint_t)key) + +/* --- END OF HASH FUNCTIONS --- */ + +/* Other convenient macros... */ + +/*! + @abstract Type of the hash table. + @param name Name of the hash table [symbol] + */ +#define khash_t(name) kh_##name##_t + +/*! @function + @abstract Initiate a hash table. + @param name Name of the hash table [symbol] + @return Pointer to the hash table [khash_t(name)*] + */ +#define kh_init(name) kh_init_##name() + +/*! @function + @abstract Destroy a hash table. + @param name Name of the hash table [symbol] + @param h Pointer to the hash table [khash_t(name)*] + */ +#define kh_destroy(name, h) kh_destroy_##name(h) + +/*! @function + @abstract Reset a hash table without deallocating memory. + @param name Name of the hash table [symbol] + @param h Pointer to the hash table [khash_t(name)*] + */ +#define kh_clear(name, h) kh_clear_##name(h) + +/*! @function + @abstract Resize a hash table. + @param name Name of the hash table [symbol] + @param h Pointer to the hash table [khash_t(name)*] + @param s New size [khint_t] + */ +#define kh_resize(name, h, s) kh_resize_##name(h, s) + +/*! @function + @abstract Insert a key to the hash table. + @param name Name of the hash table [symbol] + @param h Pointer to the hash table [khash_t(name)*] + @param k Key [type of keys] + @param r Extra return code: -1 if the operation failed; + 0 if the key is present in the hash table; + 1 if the bucket is empty (never used); 2 if the element in + the bucket has been deleted [int*] + @return Iterator to the inserted element [khint_t] + */ +#define kh_put(name, h, k, r) kh_put_##name(h, k, r) + +/*! @function + @abstract Retrieve a key from the hash table. + @param name Name of the hash table [symbol] + @param h Pointer to the hash table [khash_t(name)*] + @param k Key [type of keys] + @return Iterator to the found element, or kh_end(h) if the element is absent [khint_t] + */ +#define kh_get(name, h, k) kh_get_##name(h, k) + +/*! @function + @abstract Remove a key from the hash table. + @param name Name of the hash table [symbol] + @param h Pointer to the hash table [khash_t(name)*] + @param k Iterator to the element to be deleted [khint_t] + */ +#define kh_del(name, h, k) kh_del_##name(h, k) + +/*! @function + @abstract Test whether a bucket contains data. + @param h Pointer to the hash table [khash_t(name)*] + @param x Iterator to the bucket [khint_t] + @return 1 if containing data; 0 otherwise [int] + */ +#define kh_exist(h, x) (!__ac_iseither((h)->flags, (x))) + +/*! @function + @abstract Get key given an iterator + @param h Pointer to the hash table [khash_t(name)*] + @param x Iterator to the bucket [khint_t] + @return Key [type of keys] + */ +#define kh_key(h, x) ((h)->keys[x]) + +/*! @function + @abstract Get value given an iterator + @param h Pointer to the hash table [khash_t(name)*] + @param x Iterator to the bucket [khint_t] + @return Value [type of values] + @discussion For hash sets, calling this results in segfault. + */ +#define kh_val(h, x) ((h)->vals[x]) + +/*! @function + @abstract Alias of kh_val() + */ +#define kh_value(h, x) ((h)->vals[x]) + +/*! @function + @abstract Get the start iterator + @param h Pointer to the hash table [khash_t(name)*] + @return The start iterator [khint_t] + */ +#define kh_begin(h) (khint_t)(0) + +/*! @function + @abstract Get the end iterator + @param h Pointer to the hash table [khash_t(name)*] + @return The end iterator [khint_t] + */ +#define kh_end(h) ((h)->n_buckets) + +/*! @function + @abstract Get the number of elements in the hash table + @param h Pointer to the hash table [khash_t(name)*] + @return Number of elements in the hash table [khint_t] + */ +#define kh_size(h) ((h)->size) + +/*! @function + @abstract Get the number of buckets in the hash table + @param h Pointer to the hash table [khash_t(name)*] + @return Number of buckets in the hash table [khint_t] + */ +#define kh_n_buckets(h) ((h)->n_buckets) + +/*! @function + @abstract Iterate over the entries in the hash table + @param h Pointer to the hash table [khash_t(name)*] + @param kvar Variable to which key will be assigned + @param vvar Variable to which value will be assigned + @param code Block of code to execute + */ +#define kh_foreach(h, kvar, vvar, code) { khint_t __i; \ + for (__i = kh_begin(h); __i != kh_end(h); ++__i) { \ + if (!kh_exist(h,__i)) continue; \ + (kvar) = kh_key(h,__i); \ + (vvar) = kh_val(h,__i); \ + code; \ + } } + +/*! @function + @abstract Iterate over the values in the hash table + @param h Pointer to the hash table [khash_t(name)*] + @param vvar Variable to which value will be assigned + @param code Block of code to execute + */ +#define kh_foreach_value(h, vvar, code) { khint_t __i; \ + for (__i = kh_begin(h); __i != kh_end(h); ++__i) { \ + if (!kh_exist(h,__i)) continue; \ + (vvar) = kh_val(h,__i); \ + code; \ + } } + +/* More conenient interfaces */ + +/*! @function + @abstract Instantiate a hash set containing integer keys + @param name Name of the hash table [symbol] + */ +#define KHASH_SET_INIT_INT(name) \ + KHASH_INIT(name, khint32_t, char, 0, kh_int_hash_func, kh_int_hash_equal) + +/*! @function + @abstract Instantiate a hash map containing integer keys + @param name Name of the hash table [symbol] + @param khval_t Type of values [type] + */ +#define KHASH_MAP_INIT_INT(name, khval_t) \ + KHASH_INIT(name, khint32_t, khval_t, 1, kh_int_hash_func, kh_int_hash_equal) + +/*! @function + @abstract Instantiate a hash map containing 64-bit integer keys + @param name Name of the hash table [symbol] + */ +#define KHASH_SET_INIT_INT64(name) \ + KHASH_INIT(name, khint64_t, char, 0, kh_int64_hash_func, kh_int64_hash_equal) + +/*! @function + @abstract Instantiate a hash map containing 64-bit integer keys + @param name Name of the hash table [symbol] + @param khval_t Type of values [type] + */ +#define KHASH_MAP_INIT_INT64(name, khval_t) \ + KHASH_INIT(name, khint64_t, khval_t, 1, kh_int64_hash_func, kh_int64_hash_equal) + +typedef const char *kh_cstr_t; +/*! @function + @abstract Instantiate a hash map containing const char* keys + @param name Name of the hash table [symbol] + */ +#define KHASH_SET_INIT_STR(name) \ + KHASH_INIT(name, kh_cstr_t, char, 0, kh_str_hash_func, kh_str_hash_equal) + +/*! @function + @abstract Instantiate a hash map containing const char* keys + @param name Name of the hash table [symbol] + @param khval_t Type of values [type] + */ +#define KHASH_MAP_INIT_STR(name, khval_t) \ + KHASH_INIT(name, kh_cstr_t, khval_t, 1, kh_str_hash_func, kh_str_hash_equal) + +#endif /* __AC_KHASH_H */ diff --git a/web/server/h2o/libh2o/deps/klib/khmm.c b/web/server/h2o/libh2o/deps/klib/khmm.c new file mode 100644 index 00000000..711ade5a --- /dev/null +++ b/web/server/h2o/libh2o/deps/klib/khmm.c @@ -0,0 +1,423 @@ +#include +#include +#include +#include +#include +#include "khmm.h" + +// new/delete hmm_par_t + +hmm_par_t *hmm_new_par(int m, int n) +{ + hmm_par_t *hp; + int i; + assert(m > 0 && n > 0); + hp = (hmm_par_t*)calloc(1, sizeof(hmm_par_t)); + hp->m = m; hp->n = n; + hp->a0 = (FLOAT*)calloc(n, sizeof(FLOAT)); + hp->a = (FLOAT**)calloc2(n, n, sizeof(FLOAT)); + hp->e = (FLOAT**)calloc2(m + 1, n, sizeof(FLOAT)); + hp->ae = (FLOAT**)calloc2((m + 1) * n, n, sizeof(FLOAT)); + for (i = 0; i != n; ++i) hp->e[m][i] = 1.0; + return hp; +} +void hmm_delete_par(hmm_par_t *hp) +{ + int i; + if (hp == 0) return; + for (i = 0; i != hp->n; ++i) free(hp->a[i]); + for (i = 0; i <= hp->m; ++i) free(hp->e[i]); + for (i = 0; i < (hp->m + 1) * hp->n; ++i) free(hp->ae[i]); + free(hp->a); free(hp->e); free(hp->a0); free(hp->ae); + free(hp); +} + +// new/delete hmm_data_t + +hmm_data_t *hmm_new_data(int L, const char *seq, const hmm_par_t *hp) +{ + hmm_data_t *hd; + hd = (hmm_data_t*)calloc(1, sizeof(hmm_data_t)); + hd->L = L; + hd->seq = (char*)malloc(L + 1); + memcpy(hd->seq + 1, seq, L); + return hd; +} +void hmm_delete_data(hmm_data_t *hd) +{ + int i; + if (hd == 0) return; + for (i = 0; i <= hd->L; ++i) { + if (hd->f) free(hd->f[i]); + if (hd->b) free(hd->b[i]); + } + free(hd->f); free(hd->b); free(hd->s); free(hd->v); free(hd->p); free(hd->seq); + free(hd); +} + +// new/delete hmm_exp_t + +hmm_exp_t *hmm_new_exp(const hmm_par_t *hp) +{ + hmm_exp_t *he; + assert(hp); + he = (hmm_exp_t*)calloc(1, sizeof(hmm_exp_t)); + he->m = hp->m; he->n = hp->n; + he->A0 = (FLOAT*)calloc(hp->n, sizeof(FLOAT)); + he->A = (FLOAT**)calloc2(hp->n, hp->n, sizeof(FLOAT)); + he->E = (FLOAT**)calloc2(hp->m + 1, hp->n, sizeof(FLOAT)); + return he; +} +void hmm_delete_exp(hmm_exp_t *he) +{ + int i; + if (he == 0) return; + for (i = 0; i != he->n; ++i) free(he->A[i]); + for (i = 0; i <= he->m; ++i) free(he->E[i]); + free(he->A); free(he->E); free(he->A0); + free(he); +} + +// Viterbi algorithm + +FLOAT hmm_Viterbi(const hmm_par_t *hp, hmm_data_t *hd) +{ + FLOAT **la, **le, *preV, *curV, max; + int **Vmax, max_l; // backtrace matrix + int k, l, b, u; + + if (hd->v) free(hd->v); + hd->v = (int*)calloc(hd->L+1, sizeof(int)); + la = (FLOAT**)calloc2(hp->n, hp->n, sizeof(FLOAT)); + le = (FLOAT**)calloc2(hp->m + 1, hp->n, sizeof(FLOAT)); + Vmax = (int**)calloc2(hd->L+1, hp->n, sizeof(int)); + preV = (FLOAT*)malloc(sizeof(FLOAT) * hp->n); + curV = (FLOAT*)malloc(sizeof(FLOAT) * hp->n); + for (k = 0; k != hp->n; ++k) + for (l = 0; l != hp->n; ++l) + la[k][l] = log(hp->a[l][k]); // this is not a bug + for (b = 0; b != hp->m; ++b) + for (k = 0; k != hp->n; ++k) + le[b][k] = log(hp->e[b][k]); + for (k = 0; k != hp->n; ++k) le[hp->m][k] = 0.0; + // V_k(1) + for (k = 0; k != hp->n; ++k) { + preV[k] = le[(int)hd->seq[1]][k] + log(hp->a0[k]); + Vmax[1][k] = 0; + } + // all the rest + for (u = 2; u <= hd->L; ++u) { + FLOAT *tmp, *leu = le[(int)hd->seq[u]]; + for (k = 0; k != hp->n; ++k) { + FLOAT *laa = la[k]; + for (l = 0, max = -HMM_INF, max_l = -1; l != hp->n; ++l) { + if (max < preV[l] + laa[l]) { + max = preV[l] + laa[l]; + max_l = l; + } + } + assert(max_l >= 0); // cannot be zero + curV[k] = leu[k] + max; + Vmax[u][k] = max_l; + } + tmp = curV; curV = preV; preV = tmp; // swap + } + // backtrace + for (k = 0, max_l = -1, max = -HMM_INF; k != hp->n; ++k) { + if (max < preV[k]) { + max = preV[k]; max_l = k; + } + } + assert(max_l >= 0); // cannot be zero + hd->v[hd->L] = max_l; + for (u = hd->L; u >= 1; --u) + hd->v[u-1] = Vmax[u][hd->v[u]]; + for (k = 0; k != hp->n; ++k) free(la[k]); + for (b = 0; b < hp->m; ++b) free(le[b]); + for (u = 0; u <= hd->L; ++u) free(Vmax[u]); + free(la); free(le); free(Vmax); free(preV); free(curV); + hd->status |= HMM_VITERBI; + return max; +} + +// forward algorithm + +void hmm_forward(const hmm_par_t *hp, hmm_data_t *hd) +{ + FLOAT sum, tmp, **at; + int u, k, l; + int n, m, L; + assert(hp && hd); + // allocate memory for hd->f and hd->s + n = hp->n; m = hp->m; L = hd->L; + if (hd->s) free(hd->s); + if (hd->f) { + for (k = 0; k <= hd->L; ++k) free(hd->f[k]); + free(hd->f); + } + hd->f = (FLOAT**)calloc2(hd->L+1, hp->n, sizeof(FLOAT)); + hd->s = (FLOAT*)calloc(hd->L+1, sizeof(FLOAT)); + hd->status &= ~(unsigned)HMM_FORWARD; + // at[][] array helps to improve the cache efficiency + at = (FLOAT**)calloc2(n, n, sizeof(FLOAT)); + // transpose a[][] + for (k = 0; k != n; ++k) + for (l = 0; l != n; ++l) + at[k][l] = hp->a[l][k]; + // f[0], but it should never be used + hd->s[0] = 1.0; + for (k = 0; k != n; ++k) hd->f[0][k] = 0.0; + // f[1] + for (k = 0, sum = 0.0; k != n; ++k) + sum += (hd->f[1][k] = hp->a0[k] * hp->e[(int)hd->seq[1]][k]); + for (k = 0; k != n; ++k) hd->f[1][k] /= sum; + hd->s[1] = sum; + // f[2..hmmL], the core loop + for (u = 2; u <= L; ++u) { + FLOAT *fu = hd->f[u], *fu1 = hd->f[u-1], *eu = hp->e[(int)hd->seq[u]]; + for (k = 0, sum = 0.0; k != n; ++k) { + FLOAT *aa = at[k]; + for (l = 0, tmp = 0.0; l != n; ++l) tmp += fu1[l] * aa[l]; + sum += (fu[k] = eu[k] * tmp); + } + for (k = 0; k != n; ++k) fu[k] /= sum; + hd->s[u] = sum; + } + // free at array + for (k = 0; k != hp->n; ++k) free(at[k]); + free(at); + hd->status |= HMM_FORWARD; +} + +// precalculate hp->ae + +void hmm_pre_backward(hmm_par_t *hp) +{ + int m, n, b, k, l; + assert(hp); + m = hp->m; n = hp->n; + for (b = 0; b <= m; ++b) { + for (k = 0; k != n; ++k) { + FLOAT *p = hp->ae[b * hp->n + k]; + for (l = 0; l != n; ++l) + p[l] = hp->e[b][l] * hp->a[k][l]; + } + } +} + +// backward algorithm + +void hmm_backward(const hmm_par_t *hp, hmm_data_t *hd) +{ + FLOAT tmp; + int k, l, u; + int m, n, L; + assert(hp && hd); + assert(hd->status & HMM_FORWARD); + // allocate memory for hd->b + m = hp->m; n = hp->n; L = hd->L; + if (hd->b) { + for (k = 0; k <= hd->L; ++k) free(hd->b[k]); + free(hd->b); + } + hd->status &= ~(unsigned)HMM_BACKWARD; + hd->b = (FLOAT**)calloc2(L+1, hp->n, sizeof(FLOAT)); + // b[L] + for (k = 0; k != hp->n; ++k) hd->b[L][k] = 1.0 / hd->s[L]; + // b[1..L-1], the core loop + for (u = L-1; u >= 1; --u) { + FLOAT *bu1 = hd->b[u+1], **p = hp->ae + (int)hd->seq[u+1] * n; + for (k = 0; k != n; ++k) { + FLOAT *q = p[k]; + for (l = 0, tmp = 0.0; l != n; ++l) tmp += q[l] * bu1[l]; + hd->b[u][k] = tmp / hd->s[u]; + } + } + hd->status |= HMM_BACKWARD; + for (l = 0, tmp = 0.0; l != n; ++l) + tmp += hp->a0[l] * hd->b[1][l] * hp->e[(int)hd->seq[1]][l]; + if (tmp > 1.0 + 1e-6 || tmp < 1.0 - 1e-6) // in theory, tmp should always equal to 1 + fprintf(stderr, "++ Underflow may have happened (%lg).\n", tmp); +} + +// log-likelihood of the observation + +FLOAT hmm_lk(const hmm_data_t *hd) +{ + FLOAT sum = 0.0, prod = 1.0; + int u, L; + L = hd->L; + assert(hd->status & HMM_FORWARD); + for (u = 1; u <= L; ++u) { + prod *= hd->s[u]; + if (prod < HMM_TINY || prod >= 1.0/HMM_TINY) { // reset + sum += log(prod); + prod = 1.0; + } + } + sum += log(prod); + return sum; +} + +// posterior decoding + +void hmm_post_decode(const hmm_par_t *hp, hmm_data_t *hd) +{ + int u, k; + assert(hd->status && HMM_BACKWARD); + if (hd->p) free(hd->p); + hd->p = (int*)calloc(hd->L + 1, sizeof(int)); + for (u = 1; u <= hd->L; ++u) { + FLOAT prob, max, *fu = hd->f[u], *bu = hd->b[u], su = hd->s[u]; + int max_k; + for (k = 0, max = -1.0, max_k = -1; k != hp->n; ++k) { + if (max < (prob = fu[k] * bu[k] * su)) { + max = prob; max_k = k; + } + } + assert(max_k >= 0); + hd->p[u] = max_k; + } + hd->status |= HMM_POSTDEC; +} + +// posterior probability of states + +FLOAT hmm_post_state(const hmm_par_t *hp, const hmm_data_t *hd, int u, FLOAT *prob) +{ + FLOAT sum = 0.0, ss = hd->s[u], *fu = hd->f[u], *bu = hd->b[u]; + int k; + for (k = 0; k != hp->n; ++k) + sum += (prob[k] = fu[k] * bu[k] * ss); + return sum; // in theory, this should always equal to 1.0 +} + +// expected counts + +hmm_exp_t *hmm_expect(const hmm_par_t *hp, const hmm_data_t *hd) +{ + int k, l, u, b, m, n; + hmm_exp_t *he; + assert(hd->status & HMM_BACKWARD); + he = hmm_new_exp(hp); + // initialization + m = hp->m; n = hp->n; + for (k = 0; k != n; ++k) + for (l = 0; l != n; ++l) he->A[k][l] = HMM_TINY; + for (b = 0; b <= m; ++b) + for (l = 0; l != n; ++l) he->E[b][l] = HMM_TINY; + // calculate A_{kl} and E_k(b), k,l\in[0,n) + for (u = 1; u < hd->L; ++u) { + FLOAT *fu = hd->f[u], *bu = hd->b[u], *bu1 = hd->b[u+1], ss = hd->s[u]; + FLOAT *Ec = he->E[(int)hd->seq[u]], **p = hp->ae + (int)hd->seq[u+1] * n; + for (k = 0; k != n; ++k) { + FLOAT *q = p[k], *AA = he->A[k], fuk = fu[k]; + for (l = 0; l != n; ++l) // this is cache-efficient + AA[l] += fuk * q[l] * bu1[l]; + Ec[k] += fuk * bu[k] * ss; + } + } + // calculate A0_l + for (l = 0; l != n; ++l) + he->A0[l] += hp->a0[l] * hp->e[(int)hd->seq[1]][l] * hd->b[1][l]; + return he; +} + +FLOAT hmm_Q0(const hmm_par_t *hp, hmm_exp_t *he) +{ + int k, l, b; + FLOAT sum = 0.0; + for (k = 0; k != hp->n; ++k) { + FLOAT tmp; + for (b = 0, tmp = 0.0; b != hp->m; ++b) tmp += he->E[b][k]; + for (b = 0; b != hp->m; ++b) + sum += he->E[b][k] * log(he->E[b][k] / tmp); + } + for (k = 0; k != hp->n; ++k) { + FLOAT tmp, *A = he->A[k]; + for (l = 0, tmp = 0.0; l != hp->n; ++l) tmp += A[l]; + for (l = 0; l != hp->n; ++l) sum += A[l] * log(A[l] / tmp); + } + return (he->Q0 = sum); +} + +// add he0 to he1 + +void hmm_add_expect(const hmm_exp_t *he0, hmm_exp_t *he1) +{ + int b, k, l; + assert(he0->m == he1->m && he0->n == he1->n); + for (k = 0; k != he1->n; ++k) { + he1->A0[k] += he0->A0[k]; + for (l = 0; l != he1->n; ++l) + he1->A[k][l] += he0->A[k][l]; + } + for (b = 0; b != he1->m; ++b) { + for (l = 0; l != he1->n; ++l) + he1->E[b][l] += he0->E[b][l]; + } +} + +// the EM-Q function + +FLOAT hmm_Q(const hmm_par_t *hp, const hmm_exp_t *he) +{ + FLOAT sum = 0.0; + int bb, k, l; + for (bb = 0; bb != he->m; ++bb) { + FLOAT *eb = hp->e[bb], *Eb = he->E[bb]; + for (k = 0; k != hp->n; ++k) { + if (eb[k] <= 0.0) return -HMM_INF; + sum += Eb[k] * log(eb[k]); + } + } + for (k = 0; k != he->n; ++k) { + FLOAT *Ak = he->A[k], *ak = hp->a[k]; + for (l = 0; l != he->n; ++l) { + if (ak[l] <= 0.0) return -HMM_INF; + sum += Ak[l] * log(ak[l]); + } + } + return (sum -= he->Q0); +} + +// simulate sequence + +char *hmm_simulate(const hmm_par_t *hp, int L) +{ + int i, k, l, b; + FLOAT x, y, **et; + char *seq; + seq = (char*)calloc(L+1, 1); + // calculate the transpose of hp->e[][] + et = (FLOAT**)calloc2(hp->n, hp->m, sizeof(FLOAT)); + for (k = 0; k != hp->n; ++k) + for (b = 0; b != hp->m; ++b) + et[k][b] = hp->e[b][k]; + // the initial state, drawn from a0[] + x = drand48(); + for (k = 0, y = 0.0; k != hp->n; ++k) { + y += hp->a0[k]; + if (y >= x) break; + } + // main loop + for (i = 0; i != L; ++i) { + FLOAT *el, *ak = hp->a[k]; + x = drand48(); + for (l = 0, y = 0.0; l != hp->n; ++l) { + y += ak[l]; + if (y >= x) break; + } + el = et[l]; + x = drand48(); + for (b = 0, y = 0.0; b != hp->m; ++b) { + y += el[b]; + if (y >= x) break; + } + seq[i] = b; + k = l; + } + for (k = 0; k != hp->n; ++k) free(et[k]); + free(et); + return seq; +} diff --git a/web/server/h2o/libh2o/deps/klib/khmm.h b/web/server/h2o/libh2o/deps/klib/khmm.h new file mode 100644 index 00000000..d87673b9 --- /dev/null +++ b/web/server/h2o/libh2o/deps/klib/khmm.h @@ -0,0 +1,107 @@ +#ifndef AC_SCHMM_H_ +#define AC_SCHMM_H_ + +/* + * Last Modified: 2008-03-10 + * Version: 0.1.0-8 + * + * 2008-03-10, 0.1.0-8: make icc report two more "VECTORIZED" + * 2008-03-10, 0.1.0-7: accelerate for some CPU + * 2008-02-07, 0.1.0-6: simulate sequences + * 2008-01-15, 0.1.0-5: goodness of fit + * 2007-11-20, 0.1.0-4: add function declaration of hmm_post_decode() + * 2007-11-09: fix a memory leak + */ + +#include + +#define HMM_VERSION "0.1.0-7" + +#define HMM_FORWARD 0x02 +#define HMM_BACKWARD 0x04 +#define HMM_VITERBI 0x40 +#define HMM_POSTDEC 0x80 + +#ifndef FLOAT +#define FLOAT double +#endif +#define HMM_TINY 1e-25 +#define HMM_INF 1e300 + +typedef struct +{ + int m, n; // number of symbols, number of states + FLOAT **a, **e; // transition matrix and emitting probilities + FLOAT **ae; // auxiliary array for acceleration, should be calculated by hmm_pre_backward() + FLOAT *a0; // trasition matrix from the start state +} hmm_par_t; + +typedef struct +{ + int L; + unsigned status; + char *seq; + FLOAT **f, **b, *s; + int *v; // Viterbi path + int *p; // posterior decoding +} hmm_data_t; + +typedef struct +{ + int m, n; + FLOAT Q0, **A, **E, *A0; +} hmm_exp_t; + +typedef struct +{ + int l, *obs; + FLOAT *thr; +} hmm_gof_t; + +#ifdef __cplusplus +extern "C" { +#endif + /* initialize and destroy hmm_par_t */ + hmm_par_t *hmm_new_par(int m, int n); + void hmm_delete_par(hmm_par_t *hp); + /* initialize and destroy hmm_data_t */ + hmm_data_t *hmm_new_data(int L, const char *seq, const hmm_par_t *hp); + void hmm_delete_data(hmm_data_t *hd); + /* initialize and destroy hmm_exp_t */ + hmm_exp_t *hmm_new_exp(const hmm_par_t *hp); + void hmm_delete_exp(hmm_exp_t *he); + /* Viterbi, forward and backward algorithms */ + FLOAT hmm_Viterbi(const hmm_par_t *hp, hmm_data_t *hd); + void hmm_pre_backward(hmm_par_t *hp); + void hmm_forward(const hmm_par_t *hp, hmm_data_t *hd); + void hmm_backward(const hmm_par_t *hp, hmm_data_t *hd); + /* log-likelihood of the observations (natural based) */ + FLOAT hmm_lk(const hmm_data_t *hd); + /* posterior probability at the position on the sequence */ + FLOAT hmm_post_state(const hmm_par_t *hp, const hmm_data_t *hd, int u, FLOAT *prob); + /* posterior decoding */ + void hmm_post_decode(const hmm_par_t *hp, hmm_data_t *hd); + /* expected counts of transitions and emissions */ + hmm_exp_t *hmm_expect(const hmm_par_t *hp, const hmm_data_t *hd); + /* add he0 counts to he1 counts*/ + void hmm_add_expect(const hmm_exp_t *he0, hmm_exp_t *he1); + /* the Q function that should be maximized in EM */ + FLOAT hmm_Q(const hmm_par_t *hp, const hmm_exp_t *he); + FLOAT hmm_Q0(const hmm_par_t *hp, hmm_exp_t *he); + /* simulate sequences */ + char *hmm_simulate(const hmm_par_t *hp, int L); +#ifdef __cplusplus +} +#endif + +static inline void **calloc2(int n_row, int n_col, int size) +{ + char **p; + int k; + p = (char**)malloc(sizeof(char*) * n_row); + for (k = 0; k != n_row; ++k) + p[k] = (char*)calloc(n_col, size); + return (void**)p; +} + +#endif diff --git a/web/server/h2o/libh2o/deps/klib/klist.h b/web/server/h2o/libh2o/deps/klib/klist.h new file mode 100644 index 00000000..8b33f271 --- /dev/null +++ b/web/server/h2o/libh2o/deps/klib/klist.h @@ -0,0 +1,121 @@ +/* The MIT License + + Copyright (c) 2008-2009, by Attractive Chaos + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. +*/ + +#ifndef _AC_KLIST_H +#define _AC_KLIST_H + +#include + +#define KMEMPOOL_INIT(name, kmptype_t, kmpfree_f) \ + typedef struct { \ + size_t cnt, n, max; \ + kmptype_t **buf; \ + } kmp_##name##_t; \ + static inline kmp_##name##_t *kmp_init_##name(void) { \ + return calloc(1, sizeof(kmp_##name##_t)); \ + } \ + static inline void kmp_destroy_##name(kmp_##name##_t *mp) { \ + size_t k; \ + for (k = 0; k < mp->n; ++k) { \ + kmpfree_f(mp->buf[k]); free(mp->buf[k]); \ + } \ + free(mp->buf); free(mp); \ + } \ + static inline kmptype_t *kmp_alloc_##name(kmp_##name##_t *mp) { \ + ++mp->cnt; \ + if (mp->n == 0) return calloc(1, sizeof(kmptype_t)); \ + return mp->buf[--mp->n]; \ + } \ + static inline void kmp_free_##name(kmp_##name##_t *mp, kmptype_t *p) { \ + --mp->cnt; \ + if (mp->n == mp->max) { \ + mp->max = mp->max? mp->max<<1 : 16; \ + mp->buf = realloc(mp->buf, sizeof(kmptype_t *) * mp->max); \ + } \ + mp->buf[mp->n++] = p; \ + } + +#define kmempool_t(name) kmp_##name##_t +#define kmp_init(name) kmp_init_##name() +#define kmp_destroy(name, mp) kmp_destroy_##name(mp) +#define kmp_alloc(name, mp) kmp_alloc_##name(mp) +#define kmp_free(name, mp, p) kmp_free_##name(mp, p) + +#define KLIST_INIT(name, kltype_t, kmpfree_t) \ + struct __kl1_##name { \ + kltype_t data; \ + struct __kl1_##name *next; \ + }; \ + typedef struct __kl1_##name kl1_##name; \ + KMEMPOOL_INIT(name, kl1_##name, kmpfree_t) \ + typedef struct { \ + kl1_##name *head, *tail; \ + kmp_##name##_t *mp; \ + size_t size; \ + } kl_##name##_t; \ + static inline kl_##name##_t *kl_init_##name(void) { \ + kl_##name##_t *kl = calloc(1, sizeof(kl_##name##_t)); \ + kl->mp = kmp_init(name); \ + kl->head = kl->tail = kmp_alloc(name, kl->mp); \ + kl->head->next = 0; \ + return kl; \ + } \ + static inline void kl_destroy_##name(kl_##name##_t *kl) { \ + kl1_##name *p; \ + for (p = kl->head; p != kl->tail; p = p->next) \ + kmp_free(name, kl->mp, p); \ + kmp_free(name, kl->mp, p); \ + kmp_destroy(name, kl->mp); \ + free(kl); \ + } \ + static inline kltype_t *kl_pushp_##name(kl_##name##_t *kl) { \ + kl1_##name *q, *p = kmp_alloc(name, kl->mp); \ + q = kl->tail; p->next = 0; kl->tail->next = p; kl->tail = p; \ + ++kl->size; \ + return &q->data; \ + } \ + static inline int kl_shift_##name(kl_##name##_t *kl, kltype_t *d) { \ + kl1_##name *p; \ + if (kl->head->next == 0) return -1; \ + --kl->size; \ + p = kl->head; kl->head = kl->head->next; \ + if (d) *d = p->data; \ + kmp_free(name, kl->mp, p); \ + return 0; \ + } + +#define kliter_t(name) kl1_##name +#define klist_t(name) kl_##name##_t +#define kl_val(iter) ((iter)->data) +#define kl_next(iter) ((iter)->next) +#define kl_begin(kl) ((kl)->head) +#define kl_end(kl) ((kl)->tail) + +#define kl_init(name) kl_init_##name() +#define kl_destroy(name, kl) kl_destroy_##name(kl) +#define kl_pushp(name, kl) kl_pushp_##name(kl) +#define kl_shift(name, kl, d) kl_shift_##name(kl, d) + +#endif diff --git a/web/server/h2o/libh2o/deps/klib/kmath.c b/web/server/h2o/libh2o/deps/klib/kmath.c new file mode 100644 index 00000000..9807b00e --- /dev/null +++ b/web/server/h2o/libh2o/deps/klib/kmath.c @@ -0,0 +1,456 @@ +#include +#include +#include +#include "kmath.h" + +/************************************** + *** Pseudo-random number generator *** + **************************************/ + +/* + 64-bit Mersenne Twister pseudorandom number generator. Adapted from: + + http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/VERSIONS/C-LANG/mt19937-64.c + + which was written by Takuji Nishimura and Makoto Matsumoto and released + under the 3-clause BSD license. +*/ + +#define KR_NN 312 +#define KR_MM 156 +#define KR_UM 0xFFFFFFFF80000000ULL /* Most significant 33 bits */ +#define KR_LM 0x7FFFFFFFULL /* Least significant 31 bits */ + +struct _krand_t { + int mti; + krint64_t mt[KR_NN]; +}; + +static void kr_srand0(krint64_t seed, krand_t *kr) +{ + kr->mt[0] = seed; + for (kr->mti = 1; kr->mti < KR_NN; ++kr->mti) + kr->mt[kr->mti] = 6364136223846793005ULL * (kr->mt[kr->mti - 1] ^ (kr->mt[kr->mti - 1] >> 62)) + kr->mti; +} + +krand_t *kr_srand(krint64_t seed) +{ + krand_t *kr; + kr = malloc(sizeof(krand_t)); + kr_srand0(seed, kr); + return kr; +} + +krint64_t kr_rand(krand_t *kr) +{ + krint64_t x; + static const krint64_t mag01[2] = { 0, 0xB5026F5AA96619E9ULL }; + if (kr->mti >= KR_NN) { + int i; + if (kr->mti == KR_NN + 1) kr_srand0(5489ULL, kr); + for (i = 0; i < KR_NN - KR_MM; ++i) { + x = (kr->mt[i] & KR_UM) | (kr->mt[i+1] & KR_LM); + kr->mt[i] = kr->mt[i + KR_MM] ^ (x>>1) ^ mag01[(int)(x&1)]; + } + for (; i < KR_NN - 1; ++i) { + x = (kr->mt[i] & KR_UM) | (kr->mt[i+1] & KR_LM); + kr->mt[i] = kr->mt[i + (KR_MM - KR_NN)] ^ (x>>1) ^ mag01[(int)(x&1)]; + } + x = (kr->mt[KR_NN - 1] & KR_UM) | (kr->mt[0] & KR_LM); + kr->mt[KR_NN - 1] = kr->mt[KR_MM - 1] ^ (x>>1) ^ mag01[(int)(x&1)]; + kr->mti = 0; + } + x = kr->mt[kr->mti++]; + x ^= (x >> 29) & 0x5555555555555555ULL; + x ^= (x << 17) & 0x71D67FFFEDA60000ULL; + x ^= (x << 37) & 0xFFF7EEE000000000ULL; + x ^= (x >> 43); + return x; +} + +#ifdef _KR_MAIN +int main(int argc, char *argv[]) +{ + long i, N = 200000000; + krand_t *kr; + if (argc > 1) N = atol(argv[1]); + kr = kr_srand(11); + for (i = 0; i < N; ++i) kr_rand(kr); +// for (i = 0; i < N; ++i) lrand48(); + free(kr); + return 0; +} +#endif + +/****************************** + *** Non-linear programming *** + ******************************/ + +/* Hooke-Jeeves algorithm for nonlinear minimization + + Based on the pseudocodes by Bell and Pike (CACM 9(9):684-685), and + the revision by Tomlin and Smith (CACM 12(11):637-638). Both of the + papers are comments on Kaupe's Algorithm 178 "Direct Search" (ACM + 6(6):313-314). The original algorithm was designed by Hooke and + Jeeves (ACM 8:212-229). This program is further revised according to + Johnson's implementation at Netlib (opt/hooke.c). + + Hooke-Jeeves algorithm is very simple and it works quite well on a + few examples. However, it might fail to converge due to its heuristic + nature. A possible improvement, as is suggested by Johnson, may be to + choose a small r at the beginning to quickly approach to the minimum + and a large r at later step to hit the minimum. + */ + +static double __kmin_hj_aux(kmin_f func, int n, double *x1, void *data, double fx1, double *dx, int *n_calls) +{ + int k, j = *n_calls; + double ftmp; + for (k = 0; k != n; ++k) { + x1[k] += dx[k]; + ftmp = func(n, x1, data); ++j; + if (ftmp < fx1) fx1 = ftmp; + else { /* search the opposite direction */ + dx[k] = 0.0 - dx[k]; + x1[k] += dx[k] + dx[k]; + ftmp = func(n, x1, data); ++j; + if (ftmp < fx1) fx1 = ftmp; + else x1[k] -= dx[k]; /* back to the original x[k] */ + } + } + *n_calls = j; + return fx1; /* here: fx1=f(n,x1) */ +} + +double kmin_hj(kmin_f func, int n, double *x, void *data, double r, double eps, int max_calls) +{ + double fx, fx1, *x1, *dx, radius; + int k, n_calls = 0; + x1 = (double*)calloc(n, sizeof(double)); + dx = (double*)calloc(n, sizeof(double)); + for (k = 0; k != n; ++k) { /* initial directions, based on MGJ */ + dx[k] = fabs(x[k]) * r; + if (dx[k] == 0) dx[k] = r; + } + radius = r; + fx1 = fx = func(n, x, data); ++n_calls; + for (;;) { + memcpy(x1, x, n * sizeof(double)); /* x1 = x */ + fx1 = __kmin_hj_aux(func, n, x1, data, fx, dx, &n_calls); + while (fx1 < fx) { + for (k = 0; k != n; ++k) { + double t = x[k]; + dx[k] = x1[k] > x[k]? fabs(dx[k]) : 0.0 - fabs(dx[k]); + x[k] = x1[k]; + x1[k] = x1[k] + x1[k] - t; + } + fx = fx1; + if (n_calls >= max_calls) break; + fx1 = func(n, x1, data); ++n_calls; + fx1 = __kmin_hj_aux(func, n, x1, data, fx1, dx, &n_calls); + if (fx1 >= fx) break; + for (k = 0; k != n; ++k) + if (fabs(x1[k] - x[k]) > .5 * fabs(dx[k])) break; + if (k == n) break; + } + if (radius >= eps) { + if (n_calls >= max_calls) break; + radius *= r; + for (k = 0; k != n; ++k) dx[k] *= r; + } else break; /* converge */ + } + free(x1); free(dx); + return fx1; +} + +// I copied this function somewhere several years ago with some of my modifications, but I forgot the source. +double kmin_brent(kmin1_f func, double a, double b, void *data, double tol, double *xmin) +{ + double bound, u, r, q, fu, tmp, fa, fb, fc, c; + const double gold1 = 1.6180339887; + const double gold2 = 0.3819660113; + const double tiny = 1e-20; + const int max_iter = 100; + + double e, d, w, v, mid, tol1, tol2, p, eold, fv, fw; + int iter; + + fa = func(a, data); fb = func(b, data); + if (fb > fa) { // swap, such that f(a) > f(b) + tmp = a; a = b; b = tmp; + tmp = fa; fa = fb; fb = tmp; + } + c = b + gold1 * (b - a), fc = func(c, data); // golden section extrapolation + while (fb > fc) { + bound = b + 100.0 * (c - b); // the farthest point where we want to go + r = (b - a) * (fb - fc); + q = (b - c) * (fb - fa); + if (fabs(q - r) < tiny) { // avoid 0 denominator + tmp = q > r? tiny : 0.0 - tiny; + } else tmp = q - r; + u = b - ((b - c) * q - (b - a) * r) / (2.0 * tmp); // u is the parabolic extrapolation point + if ((b > u && u > c) || (b < u && u < c)) { // u lies between b and c + fu = func(u, data); + if (fu < fc) { // (b,u,c) bracket the minimum + a = b; b = u; fa = fb; fb = fu; + break; + } else if (fu > fb) { // (a,b,u) bracket the minimum + c = u; fc = fu; + break; + } + u = c + gold1 * (c - b); fu = func(u, data); // golden section extrapolation + } else if ((c > u && u > bound) || (c < u && u < bound)) { // u lies between c and bound + fu = func(u, data); + if (fu < fc) { // fb > fc > fu + b = c; c = u; u = c + gold1 * (c - b); + fb = fc; fc = fu; fu = func(u, data); + } else { // (b,c,u) bracket the minimum + a = b; b = c; c = u; + fa = fb; fb = fc; fc = fu; + break; + } + } else if ((u > bound && bound > c) || (u < bound && bound < c)) { // u goes beyond the bound + u = bound; fu = func(u, data); + } else { // u goes the other way around, use golden section extrapolation + u = c + gold1 * (c - b); fu = func(u, data); + } + a = b; b = c; c = u; + fa = fb; fb = fc; fc = fu; + } + if (a > c) u = a, a = c, c = u; // swap + + // now, afb and fb tol1) { + // related to parabolic interpolation + r = (b - w) * (fb - fv); + q = (b - v) * (fb - fw); + p = (b - v) * q - (b - w) * r; + q = 2.0 * (q - r); + if (q > 0.0) p = 0.0 - p; + else q = 0.0 - q; + eold = e; e = d; + if (fabs(p) >= fabs(0.5 * q * eold) || p <= q * (a - b) || p >= q * (c - b)) { + d = gold2 * (e = (b >= mid ? a - b : c - b)); + } else { + d = p / q; u = b + d; // actual parabolic interpolation happens here + if (u - a < tol2 || c - u < tol2) + d = (mid > b)? tol1 : 0.0 - tol1; + } + } else d = gold2 * (e = (b >= mid ? a - b : c - b)); // golden section interpolation + u = fabs(d) >= tol1 ? b + d : b + (d > 0.0? tol1 : -tol1); + fu = func(u, data); + if (fu <= fb) { // u is the minimum point so far + if (u >= b) a = b; + else c = b; + v = w; w = b; b = u; fv = fw; fw = fb; fb = fu; + } else { // adjust (a,c) and (u,v,w) + if (u < b) a = u; + else c = u; + if (fu <= fw || w == b) { + v = w; w = u; + fv = fw; fw = fu; + } else if (fu <= fv || v == b || v == w) { + v = u; fv = fu; + } + } + } + *xmin = b; + return fb; +} + +/************************* + *** Special functions *** + *************************/ + +/* Log gamma function + * \log{\Gamma(z)} + * AS245, 2nd algorithm, http://lib.stat.cmu.edu/apstat/245 + */ +double kf_lgamma(double z) +{ + double x = 0; + x += 0.1659470187408462e-06 / (z+7); + x += 0.9934937113930748e-05 / (z+6); + x -= 0.1385710331296526 / (z+5); + x += 12.50734324009056 / (z+4); + x -= 176.6150291498386 / (z+3); + x += 771.3234287757674 / (z+2); + x -= 1259.139216722289 / (z+1); + x += 676.5203681218835 / z; + x += 0.9999999999995183; + return log(x) - 5.58106146679532777 - z + (z-0.5) * log(z+6.5); +} + +/* complementary error function + * \frac{2}{\sqrt{\pi}} \int_x^{\infty} e^{-t^2} dt + * AS66, 2nd algorithm, http://lib.stat.cmu.edu/apstat/66 + */ +double kf_erfc(double x) +{ + const double p0 = 220.2068679123761; + const double p1 = 221.2135961699311; + const double p2 = 112.0792914978709; + const double p3 = 33.912866078383; + const double p4 = 6.37396220353165; + const double p5 = .7003830644436881; + const double p6 = .03526249659989109; + const double q0 = 440.4137358247522; + const double q1 = 793.8265125199484; + const double q2 = 637.3336333788311; + const double q3 = 296.5642487796737; + const double q4 = 86.78073220294608; + const double q5 = 16.06417757920695; + const double q6 = 1.755667163182642; + const double q7 = .08838834764831844; + double expntl, z, p; + z = fabs(x) * M_SQRT2; + if (z > 37.) return x > 0.? 0. : 2.; + expntl = exp(z * z * - .5); + if (z < 10. / M_SQRT2) // for small z + p = expntl * ((((((p6 * z + p5) * z + p4) * z + p3) * z + p2) * z + p1) * z + p0) + / (((((((q7 * z + q6) * z + q5) * z + q4) * z + q3) * z + q2) * z + q1) * z + q0); + else p = expntl / 2.506628274631001 / (z + 1. / (z + 2. / (z + 3. / (z + 4. / (z + .65))))); + return x > 0.? 2. * p : 2. * (1. - p); +} + +/* The following computes regularized incomplete gamma functions. + * Formulas are taken from Wiki, with additional input from Numerical + * Recipes in C (for modified Lentz's algorithm) and AS245 + * (http://lib.stat.cmu.edu/apstat/245). + * + * A good online calculator is available at: + * + * http://www.danielsoper.com/statcalc/calc23.aspx + * + * It calculates upper incomplete gamma function, which equals + * kf_gammaq(s,z)*tgamma(s). + */ + +#define KF_GAMMA_EPS 1e-14 +#define KF_TINY 1e-290 + +// regularized lower incomplete gamma function, by series expansion +static double _kf_gammap(double s, double z) +{ + double sum, x; + int k; + for (k = 1, sum = x = 1.; k < 100; ++k) { + sum += (x *= z / (s + k)); + if (x / sum < KF_GAMMA_EPS) break; + } + return exp(s * log(z) - z - kf_lgamma(s + 1.) + log(sum)); +} +// regularized upper incomplete gamma function, by continued fraction +static double _kf_gammaq(double s, double z) +{ + int j; + double C, D, f; + f = 1. + z - s; C = f; D = 0.; + // Modified Lentz's algorithm for computing continued fraction + // See Numerical Recipes in C, 2nd edition, section 5.2 + for (j = 1; j < 100; ++j) { + double a = j * (s - j), b = (j<<1) + 1 + z - s, d; + D = b + a * D; + if (D < KF_TINY) D = KF_TINY; + C = b + a / C; + if (C < KF_TINY) C = KF_TINY; + D = 1. / D; + d = C * D; + f *= d; + if (fabs(d - 1.) < KF_GAMMA_EPS) break; + } + return exp(s * log(z) - z - kf_lgamma(s) - log(f)); +} + +double kf_gammap(double s, double z) +{ + return z <= 1. || z < s? _kf_gammap(s, z) : 1. - _kf_gammaq(s, z); +} + +double kf_gammaq(double s, double z) +{ + return z <= 1. || z < s? 1. - _kf_gammap(s, z) : _kf_gammaq(s, z); +} + +/* Regularized incomplete beta function. The method is taken from + * Numerical Recipe in C, 2nd edition, section 6.4. The following web + * page calculates the incomplete beta function, which equals + * kf_betai(a,b,x) * gamma(a) * gamma(b) / gamma(a+b): + * + * http://www.danielsoper.com/statcalc/calc36.aspx + */ +static double kf_betai_aux(double a, double b, double x) +{ + double C, D, f; + int j; + if (x == 0.) return 0.; + if (x == 1.) return 1.; + f = 1.; C = f; D = 0.; + // Modified Lentz's algorithm for computing continued fraction + for (j = 1; j < 200; ++j) { + double aa, d; + int m = j>>1; + aa = (j&1)? -(a + m) * (a + b + m) * x / ((a + 2*m) * (a + 2*m + 1)) + : m * (b - m) * x / ((a + 2*m - 1) * (a + 2*m)); + D = 1. + aa * D; + if (D < KF_TINY) D = KF_TINY; + C = 1. + aa / C; + if (C < KF_TINY) C = KF_TINY; + D = 1. / D; + d = C * D; + f *= d; + if (fabs(d - 1.) < KF_GAMMA_EPS) break; + } + return exp(kf_lgamma(a+b) - kf_lgamma(a) - kf_lgamma(b) + a * log(x) + b * log(1.-x)) / a / f; +} +double kf_betai(double a, double b, double x) +{ + return x < (a + 1.) / (a + b + 2.)? kf_betai_aux(a, b, x) : 1. - kf_betai_aux(b, a, 1. - x); +} + +/****************** + *** Statistics *** + ******************/ + +double km_ks_dist(int na, const double a[], int nb, const double b[]) // a[] and b[] MUST BE sorted +{ + int ia = 0, ib = 0; + double fa = 0, fb = 0, sup = 0, na1 = 1. / na, nb1 = 1. / nb; + while (ia < na || ib < nb) { + if (ia == na) fb += nb1, ++ib; + else if (ib == nb) fa += na1, ++ia; + else if (a[ia] < b[ib]) fa += na1, ++ia; + else if (a[ia] > b[ib]) fb += nb1, ++ib; + else fa += na1, fb += nb1, ++ia, ++ib; + if (sup < fabs(fa - fb)) sup = fabs(fa - fb); + } + return sup; +} + +#ifdef KF_MAIN +#include +#include "ksort.h" +KSORT_INIT_GENERIC(double) +int main(int argc, char *argv[]) +{ + double x = 5.5, y = 3; + double a, b; + double xx[] = {0.22, -0.87, -2.39, -1.79, 0.37, -1.54, 1.28, -0.31, -0.74, 1.72, 0.38, -0.17, -0.62, -1.10, 0.30, 0.15, 2.30, 0.19, -0.50, -0.09}; + double yy[] = {-5.13, -2.19, -2.43, -3.83, 0.50, -3.25, 4.32, 1.63, 5.18, -0.43, 7.11, 4.87, -3.10, -5.81, 3.76, 6.31, 2.58, 0.07, 5.76, 3.50}; + ks_introsort(double, 20, xx); ks_introsort(double, 20, yy); + printf("K-S distance: %f\n", km_ks_dist(20, xx, 20, yy)); + printf("erfc(%lg): %lg, %lg\n", x, erfc(x), kf_erfc(x)); + printf("upper-gamma(%lg,%lg): %lg\n", x, y, kf_gammaq(y, x)*tgamma(y)); + a = 2; b = 2; x = 0.5; + printf("incomplete-beta(%lg,%lg,%lg): %lg\n", a, b, x, kf_betai(a, b, x) / exp(kf_lgamma(a+b) - kf_lgamma(a) - kf_lgamma(b))); + return 0; +} +#endif diff --git a/web/server/h2o/libh2o/deps/klib/kmath.h b/web/server/h2o/libh2o/deps/klib/kmath.h new file mode 100644 index 00000000..2c3e7796 --- /dev/null +++ b/web/server/h2o/libh2o/deps/klib/kmath.h @@ -0,0 +1,53 @@ +#ifndef AC_KMATH_H +#define AC_KMATH_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + + /********************************** + * Pseudo-random number generator * + **********************************/ + + typedef uint64_t krint64_t; + + struct _krand_t; + typedef struct _krand_t krand_t; + + #define kr_drand(_kr) ((kr_rand(_kr) >> 11) * (1.0/9007199254740992.0)) + #define kr_sample(_kr, _k, _cnt) ((*(_cnt))++ < (_k)? *(_cnt) - 1 : kr_rand(_kr) % *(_cnt)) + + krand_t *kr_srand(krint64_t seed); + krint64_t kr_rand(krand_t *kr); + + /************************** + * Non-linear programming * + **************************/ + + #define KMIN_RADIUS 0.5 + #define KMIN_EPS 1e-7 + #define KMIN_MAXCALL 50000 + + typedef double (*kmin_f)(int, double*, void*); + typedef double (*kmin1_f)(double, void*); + + double kmin_hj(kmin_f func, int n, double *x, void *data, double r, double eps, int max_calls); // Hooke-Jeeves' + double kmin_brent(kmin1_f func, double a, double b, void *data, double tol, double *xmin); // Brent's 1-dimenssion + + /********************* + * Special functions * + *********************/ + + double kf_lgamma(double z); // log gamma function + double kf_erfc(double x); // complementary error function + double kf_gammap(double s, double z); // regularized lower incomplete gamma function + double kf_gammaq(double s, double z); // regularized upper incomplete gamma function + double kf_betai(double a, double b, double x); // regularized incomplete beta function + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/web/server/h2o/libh2o/deps/klib/knetfile.c b/web/server/h2o/libh2o/deps/klib/knetfile.c new file mode 100644 index 00000000..158add91 --- /dev/null +++ b/web/server/h2o/libh2o/deps/klib/knetfile.c @@ -0,0 +1,628 @@ +/* The MIT License + + Copyright (c) 2008 by Genome Research Ltd (GRL). + 2010 by Attractive Chaos + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. +*/ + +/* Probably I will not do socket programming in the next few years and + therefore I decide to heavily annotate this file, for Linux and + Windows as well. -ac */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#ifndef _WIN32 +#include +#include +#include +#endif + +#include "knetfile.h" + +/* In winsock.h, the type of a socket is SOCKET, which is: "typedef + * u_int SOCKET". An invalid SOCKET is: "(SOCKET)(~0)", or signed + * integer -1. In knetfile.c, I use "int" for socket type + * throughout. This should be improved to avoid confusion. + * + * In Linux/Mac, recv() and read() do almost the same thing. You can see + * in the header file that netread() is simply an alias of read(). In + * Windows, however, they are different and using recv() is mandatory. + */ + +/* This function tests if the file handler is ready for reading (or + * writing if is_read==0). */ +static int socket_wait(int fd, int is_read) +{ + fd_set fds, *fdr = 0, *fdw = 0; + struct timeval tv; + int ret; + tv.tv_sec = 5; tv.tv_usec = 0; // 5 seconds time out + FD_ZERO(&fds); + FD_SET(fd, &fds); + if (is_read) fdr = &fds; + else fdw = &fds; + ret = select(fd+1, fdr, fdw, 0, &tv); +#ifndef _WIN32 + if (ret == -1) perror("select"); +#else + if (ret == 0) + fprintf(stderr, "select time-out\n"); + else if (ret == SOCKET_ERROR) + fprintf(stderr, "select: %d\n", WSAGetLastError()); +#endif + return ret; +} + +#ifndef _WIN32 +/* This function does not work with Windows due to the lack of + * getaddrinfo() in winsock. It is addapted from an example in "Beej's + * Guide to Network Programming" (http://beej.us/guide/bgnet/). */ +static int socket_connect(const char *host, const char *port) +{ +#define __err_connect(func) do { perror(func); freeaddrinfo(res); return -1; } while (0) + + int on = 1, fd; + struct linger lng = { 0, 0 }; + struct addrinfo hints, *res = 0; + memset(&hints, 0, sizeof(struct addrinfo)); + hints.ai_family = AF_UNSPEC; + hints.ai_socktype = SOCK_STREAM; + /* In Unix/Mac, getaddrinfo() is the most convenient way to get + * server information. */ + if (getaddrinfo(host, port, &hints, &res) != 0) __err_connect("getaddrinfo"); + if ((fd = socket(res->ai_family, res->ai_socktype, res->ai_protocol)) == -1) __err_connect("socket"); + /* The following two setsockopt() are used by ftplib + * (http://nbpfaus.net/~pfau/ftplib/). I am not sure if they + * necessary. */ + if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) == -1) __err_connect("setsockopt"); + if (setsockopt(fd, SOL_SOCKET, SO_LINGER, &lng, sizeof(lng)) == -1) __err_connect("setsockopt"); + if (connect(fd, res->ai_addr, res->ai_addrlen) != 0) __err_connect("connect"); + freeaddrinfo(res); + return fd; +} +#else +/* MinGW's printf has problem with "%lld" */ +char *int64tostr(char *buf, int64_t x) +{ + int cnt; + int i = 0; + do { + buf[i++] = '0' + x % 10; + x /= 10; + } while (x); + buf[i] = 0; + for (cnt = i, i = 0; i < cnt/2; ++i) { + int c = buf[i]; buf[i] = buf[cnt-i-1]; buf[cnt-i-1] = c; + } + return buf; +} + +int64_t strtoint64(const char *buf) +{ + int64_t x; + for (x = 0; *buf != '\0'; ++buf) + x = x * 10 + ((int64_t) *buf - 48); + return x; +} +/* In windows, the first thing is to establish the TCP connection. */ +int knet_win32_init() +{ + WSADATA wsaData; + return WSAStartup(MAKEWORD(2, 2), &wsaData); +} +void knet_win32_destroy() +{ + WSACleanup(); +} +/* A slightly modfied version of the following function also works on + * Mac (and presummably Linux). However, this function is not stable on + * my Mac. It sometimes works fine but sometimes does not. Therefore for + * non-Windows OS, I do not use this one. */ +static SOCKET socket_connect(const char *host, const char *port) +{ +#define __err_connect(func) \ + do { \ + fprintf(stderr, "%s: %d\n", func, WSAGetLastError()); \ + return -1; \ + } while (0) + + int on = 1; + SOCKET fd; + struct linger lng = { 0, 0 }; + struct sockaddr_in server; + struct hostent *hp = 0; + // open socket + if ((fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == INVALID_SOCKET) __err_connect("socket"); + if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char*)&on, sizeof(on)) == -1) __err_connect("setsockopt"); + if (setsockopt(fd, SOL_SOCKET, SO_LINGER, (char*)&lng, sizeof(lng)) == -1) __err_connect("setsockopt"); + // get host info + if (isalpha(host[0])) hp = gethostbyname(host); + else { + struct in_addr addr; + addr.s_addr = inet_addr(host); + hp = gethostbyaddr((char*)&addr, 4, AF_INET); + } + if (hp == 0) __err_connect("gethost"); + // connect + server.sin_addr.s_addr = *((unsigned long*)hp->h_addr); + server.sin_family= AF_INET; + server.sin_port = htons(atoi(port)); + if (connect(fd, (struct sockaddr*)&server, sizeof(server)) != 0) __err_connect("connect"); + // freehostent(hp); // strangely in MSDN, hp is NOT freed (memory leak?!) + return fd; +} +#endif + +static off_t my_netread(int fd, void *buf, off_t len) +{ + off_t rest = len, curr, l = 0; + /* recv() and read() may not read the required length of data with + * one call. They have to be called repeatedly. */ + while (rest) { + if (socket_wait(fd, 1) <= 0) break; // socket is not ready for reading + curr = netread(fd, buf + l, rest); + /* According to the glibc manual, section 13.2, a zero returned + * value indicates end-of-file (EOF), which should mean that + * read() will not return zero if EOF has not been met but data + * are not immediately available. */ + if (curr == 0) break; + l += curr; rest -= curr; + } + return l; +} + +/************************* + * FTP specific routines * + *************************/ + +static int kftp_get_response(knetFile *ftp) +{ +#ifndef _WIN32 + unsigned char c; +#else + char c; +#endif + int n = 0; + char *p; + if (socket_wait(ftp->ctrl_fd, 1) <= 0) return 0; + while (netread(ftp->ctrl_fd, &c, 1)) { // FIXME: this is *VERY BAD* for unbuffered I/O + //fputc(c, stderr); + if (n >= ftp->max_response) { + ftp->max_response = ftp->max_response? ftp->max_response<<1 : 256; + ftp->response = (char*)realloc(ftp->response, ftp->max_response); + } + ftp->response[n++] = c; + if (c == '\n') { + if (n >= 4 && isdigit(ftp->response[0]) && isdigit(ftp->response[1]) && isdigit(ftp->response[2]) + && ftp->response[3] != '-') break; + n = 0; + continue; + } + } + if (n < 2) return -1; + ftp->response[n-2] = 0; + return strtol(ftp->response, &p, 0); +} + +static int kftp_send_cmd(knetFile *ftp, const char *cmd, int is_get) +{ + if (socket_wait(ftp->ctrl_fd, 0) <= 0) return -1; // socket is not ready for writing + netwrite(ftp->ctrl_fd, cmd, strlen(cmd)); + return is_get? kftp_get_response(ftp) : 0; +} + +static int kftp_pasv_prep(knetFile *ftp) +{ + char *p; + int v[6]; + kftp_send_cmd(ftp, "PASV\r\n", 1); + for (p = ftp->response; *p && *p != '('; ++p); + if (*p != '(') return -1; + ++p; + sscanf(p, "%d,%d,%d,%d,%d,%d", &v[0], &v[1], &v[2], &v[3], &v[4], &v[5]); + memcpy(ftp->pasv_ip, v, 4 * sizeof(int)); + ftp->pasv_port = (v[4]<<8&0xff00) + v[5]; + return 0; +} + + +static int kftp_pasv_connect(knetFile *ftp) +{ + char host[80], port[10]; + if (ftp->pasv_port == 0) { + fprintf(stderr, "[kftp_pasv_connect] kftp_pasv_prep() is not called before hand.\n"); + return -1; + } + sprintf(host, "%d.%d.%d.%d", ftp->pasv_ip[0], ftp->pasv_ip[1], ftp->pasv_ip[2], ftp->pasv_ip[3]); + sprintf(port, "%d", ftp->pasv_port); + ftp->fd = socket_connect(host, port); + if (ftp->fd == -1) return -1; + return 0; +} + +int kftp_connect(knetFile *ftp) +{ + ftp->ctrl_fd = socket_connect(ftp->host, ftp->port); + if (ftp->ctrl_fd == -1) return -1; + kftp_get_response(ftp); + kftp_send_cmd(ftp, "USER anonymous\r\n", 1); + kftp_send_cmd(ftp, "PASS kftp@\r\n", 1); + kftp_send_cmd(ftp, "TYPE I\r\n", 1); + return 0; +} + +int kftp_reconnect(knetFile *ftp) +{ + if (ftp->ctrl_fd != -1) { + netclose(ftp->ctrl_fd); + ftp->ctrl_fd = -1; + } + netclose(ftp->fd); + ftp->fd = -1; + return kftp_connect(ftp); +} + +// initialize ->type, ->host, ->retr and ->size +knetFile *kftp_parse_url(const char *fn, const char *mode) +{ + knetFile *fp; + char *p; + int l; + if (strstr(fn, "ftp://") != fn) return 0; + for (p = (char*)fn + 6; *p && *p != '/'; ++p); + if (*p != '/') return 0; + l = p - fn - 6; + fp = (knetFile*)calloc(1, sizeof(knetFile)); + fp->type = KNF_TYPE_FTP; + fp->fd = -1; + /* the Linux/Mac version of socket_connect() also recognizes a port + * like "ftp", but the Windows version does not. */ + fp->port = strdup("21"); + fp->host = (char*)calloc(l + 1, 1); + if (strchr(mode, 'c')) fp->no_reconnect = 1; + strncpy(fp->host, fn + 6, l); + fp->retr = (char*)calloc(strlen(p) + 8, 1); + sprintf(fp->retr, "RETR %s\r\n", p); + fp->size_cmd = (char*)calloc(strlen(p) + 8, 1); + sprintf(fp->size_cmd, "SIZE %s\r\n", p); + fp->seek_offset = 0; + return fp; +} +// place ->fd at offset off +int kftp_connect_file(knetFile *fp) +{ + int ret; + long long file_size; + if (fp->fd != -1) { + netclose(fp->fd); + if (fp->no_reconnect) kftp_get_response(fp); + } + kftp_pasv_prep(fp); + kftp_send_cmd(fp, fp->size_cmd, 1); +#ifndef _WIN32 + if ( sscanf(fp->response,"%*d %lld", &file_size) != 1 ) + { + fprintf(stderr,"[kftp_connect_file] %s\n", fp->response); + return -1; + } +#else + const char *p = fp->response; + while (*p != ' ') ++p; + while (*p < '0' || *p > '9') ++p; + file_size = strtoint64(p); +#endif + fp->file_size = file_size; + if (fp->offset>=0) { + char tmp[32]; +#ifndef _WIN32 + sprintf(tmp, "REST %lld\r\n", (long long)fp->offset); +#else + strcpy(tmp, "REST "); + int64tostr(tmp + 5, fp->offset); + strcat(tmp, "\r\n"); +#endif + kftp_send_cmd(fp, tmp, 1); + } + kftp_send_cmd(fp, fp->retr, 0); + kftp_pasv_connect(fp); + ret = kftp_get_response(fp); + if (ret != 150) { + fprintf(stderr, "[kftp_connect_file] %s\n", fp->response); + netclose(fp->fd); + fp->fd = -1; + return -1; + } + fp->is_ready = 1; + return 0; +} + + +/************************** + * HTTP specific routines * + **************************/ + +knetFile *khttp_parse_url(const char *fn, const char *mode) +{ + knetFile *fp; + char *p, *proxy, *q; + int l; + if (strstr(fn, "http://") != fn) return 0; + // set ->http_host + for (p = (char*)fn + 7; *p && *p != '/'; ++p); + l = p - fn - 7; + fp = (knetFile*)calloc(1, sizeof(knetFile)); + fp->http_host = (char*)calloc(l + 1, 1); + strncpy(fp->http_host, fn + 7, l); + fp->http_host[l] = 0; + for (q = fp->http_host; *q && *q != ':'; ++q); + if (*q == ':') *q++ = 0; + // get http_proxy + proxy = getenv("http_proxy"); + // set ->host, ->port and ->path + if (proxy == 0) { + fp->host = strdup(fp->http_host); // when there is no proxy, server name is identical to http_host name. + fp->port = strdup(*q? q : "80"); + fp->path = strdup(*p? p : "/"); + } else { + fp->host = (strstr(proxy, "http://") == proxy)? strdup(proxy + 7) : strdup(proxy); + for (q = fp->host; *q && *q != ':'; ++q); + if (*q == ':') *q++ = 0; + fp->port = strdup(*q? q : "80"); + fp->path = strdup(fn); + } + fp->type = KNF_TYPE_HTTP; + fp->ctrl_fd = fp->fd = -1; + fp->seek_offset = 0; + return fp; +} + +int khttp_connect_file(knetFile *fp) +{ + int ret, l = 0; + char *buf, *p; + if (fp->fd != -1) netclose(fp->fd); + fp->fd = socket_connect(fp->host, fp->port); + buf = (char*)calloc(0x10000, 1); // FIXME: I am lazy... But in principle, 64KB should be large enough. + l += sprintf(buf + l, "GET %s HTTP/1.0\r\nHost: %s\r\n", fp->path, fp->http_host); + l += sprintf(buf + l, "Range: bytes=%lld-\r\n", (long long)fp->offset); + l += sprintf(buf + l, "\r\n"); + netwrite(fp->fd, buf, l); + l = 0; + while (netread(fp->fd, buf + l, 1)) { // read HTTP header; FIXME: bad efficiency + if (buf[l] == '\n' && l >= 3) + if (strncmp(buf + l - 3, "\r\n\r\n", 4) == 0) break; + ++l; + } + buf[l] = 0; + if (l < 14) { // prematured header + netclose(fp->fd); + fp->fd = -1; + return -1; + } + ret = strtol(buf + 8, &p, 0); // HTTP return code + if (ret == 200 && fp->offset>0) { // 200 (complete result); then skip beginning of the file + off_t rest = fp->offset; + while (rest) { + off_t l = rest < 0x10000? rest : 0x10000; + rest -= my_netread(fp->fd, buf, l); + } + } else if (ret != 206 && ret != 200) { + free(buf); + fprintf(stderr, "[khttp_connect_file] fail to open file (HTTP code: %d).\n", ret); + netclose(fp->fd); + fp->fd = -1; + return -1; + } + free(buf); + fp->is_ready = 1; + return 0; +} + +/******************** + * Generic routines * + ********************/ + +knetFile *knet_open(const char *fn, const char *mode) +{ + knetFile *fp = 0; + if (mode[0] != 'r') { + fprintf(stderr, "[kftp_open] only mode \"r\" is supported.\n"); + return 0; + } + if (strstr(fn, "ftp://") == fn) { + fp = kftp_parse_url(fn, mode); + if (fp == 0) return 0; + if (kftp_connect(fp) == -1) { + knet_close(fp); + return 0; + } + kftp_connect_file(fp); + } else if (strstr(fn, "http://") == fn) { + fp = khttp_parse_url(fn, mode); + if (fp == 0) return 0; + khttp_connect_file(fp); + } else { // local file +#ifdef _WIN32 + /* In windows, O_BINARY is necessary. In Linux/Mac, O_BINARY may + * be undefined on some systems, although it is defined on my + * Mac and the Linux I have tested on. */ + int fd = open(fn, O_RDONLY | O_BINARY); +#else + int fd = open(fn, O_RDONLY); +#endif + if (fd == -1) { + perror("open"); + return 0; + } + fp = (knetFile*)calloc(1, sizeof(knetFile)); + fp->type = KNF_TYPE_LOCAL; + fp->fd = fd; + fp->ctrl_fd = -1; + } + if (fp && fp->fd == -1) { + knet_close(fp); + return 0; + } + return fp; +} + +knetFile *knet_dopen(int fd, const char *mode) +{ + knetFile *fp = (knetFile*)calloc(1, sizeof(knetFile)); + fp->type = KNF_TYPE_LOCAL; + fp->fd = fd; + return fp; +} + +off_t knet_read(knetFile *fp, void *buf, off_t len) +{ + off_t l = 0; + if (fp->fd == -1) return 0; + if (fp->type == KNF_TYPE_FTP) { + if (fp->is_ready == 0) { + if (!fp->no_reconnect) kftp_reconnect(fp); + kftp_connect_file(fp); + } + } else if (fp->type == KNF_TYPE_HTTP) { + if (fp->is_ready == 0) + khttp_connect_file(fp); + } + if (fp->type == KNF_TYPE_LOCAL) { // on Windows, the following block is necessary; not on UNIX + off_t rest = len, curr; + while (rest) { + do { + curr = read(fp->fd, buf + l, rest); + } while (curr < 0 && EINTR == errno); + if (curr < 0) return -1; + if (curr == 0) break; + l += curr; rest -= curr; + } + } else l = my_netread(fp->fd, buf, len); + fp->offset += l; + return l; +} + +off_t knet_seek(knetFile *fp, int64_t off, int whence) +{ + if (whence == SEEK_SET && off == fp->offset) return 0; + if (fp->type == KNF_TYPE_LOCAL) { + /* Be aware that lseek() returns the offset after seeking, + * while fseek() returns zero on success. */ + off_t offset = lseek(fp->fd, off, whence); + if (offset == -1) { + // Be silent, it is OK for knet_seek to fail when the file is streamed + // fprintf(stderr,"[knet_seek] %s\n", strerror(errno)); + return -1; + } + fp->offset = offset; + return off; + } else if (fp->type == KNF_TYPE_FTP) { + if (whence==SEEK_CUR) + fp->offset += off; + else if (whence==SEEK_SET) + fp->offset = off; + else if ( whence==SEEK_END) + fp->offset = fp->file_size+off; + fp->is_ready = 0; + return off; + } else if (fp->type == KNF_TYPE_HTTP) { + if (whence == SEEK_END) { // FIXME: can we allow SEEK_END in future? + fprintf(stderr, "[knet_seek] SEEK_END is not supported for HTTP. Offset is unchanged.\n"); + errno = ESPIPE; + return -1; + } + if (whence==SEEK_CUR) + fp->offset += off; + else if (whence==SEEK_SET) + fp->offset = off; + fp->is_ready = 0; + return off; + } + errno = EINVAL; + fprintf(stderr,"[knet_seek] %s\n", strerror(errno)); + return -1; +} + +int knet_close(knetFile *fp) +{ + if (fp == 0) return 0; + if (fp->ctrl_fd != -1) netclose(fp->ctrl_fd); // FTP specific + if (fp->fd != -1) { + /* On Linux/Mac, netclose() is an alias of close(), but on + * Windows, it is an alias of closesocket(). */ + if (fp->type == KNF_TYPE_LOCAL) close(fp->fd); + else netclose(fp->fd); + } + free(fp->host); free(fp->port); + free(fp->response); free(fp->retr); // FTP specific + free(fp->path); free(fp->http_host); // HTTP specific + free(fp); + return 0; +} + +#ifdef KNETFILE_MAIN +int main(void) +{ + char *buf; + knetFile *fp; + int type = 4, l; +#ifdef _WIN32 + knet_win32_init(); +#endif + buf = calloc(0x100000, 1); + if (type == 0) { + fp = knet_open("knetfile.c", "r"); + knet_seek(fp, 1000, SEEK_SET); + } else if (type == 1) { // NCBI FTP, large file + fp = knet_open("ftp://ftp.ncbi.nih.gov/1000genomes/ftp/data/NA12878/alignment/NA12878.chrom6.SLX.SRP000032.2009_06.bam", "r"); + knet_seek(fp, 2500000000ll, SEEK_SET); + l = knet_read(fp, buf, 255); + } else if (type == 2) { + fp = knet_open("ftp://ftp.sanger.ac.uk/pub4/treefam/tmp/index.shtml", "r"); + knet_seek(fp, 1000, SEEK_SET); + } else if (type == 3) { + fp = knet_open("http://www.sanger.ac.uk/Users/lh3/index.shtml", "r"); + knet_seek(fp, 1000, SEEK_SET); + } else if (type == 4) { + fp = knet_open("http://www.sanger.ac.uk/Users/lh3/ex1.bam", "r"); + knet_read(fp, buf, 10000); + knet_seek(fp, 20000, SEEK_SET); + knet_seek(fp, 10000, SEEK_SET); + l = knet_read(fp, buf+10000, 10000000) + 10000; + } + if (type != 4 && type != 1) { + knet_read(fp, buf, 255); + buf[255] = 0; + printf("%s\n", buf); + } else write(fileno(stdout), buf, l); + knet_close(fp); + free(buf); + return 0; +} +#endif diff --git a/web/server/h2o/libh2o/deps/klib/knetfile.h b/web/server/h2o/libh2o/deps/klib/knetfile.h new file mode 100644 index 00000000..0a0e66f7 --- /dev/null +++ b/web/server/h2o/libh2o/deps/klib/knetfile.h @@ -0,0 +1,75 @@ +#ifndef KNETFILE_H +#define KNETFILE_H + +#include +#include + +#ifndef _WIN32 +#define netread(fd, ptr, len) read(fd, ptr, len) +#define netwrite(fd, ptr, len) write(fd, ptr, len) +#define netclose(fd) close(fd) +#else +#include +#define netread(fd, ptr, len) recv(fd, ptr, len, 0) +#define netwrite(fd, ptr, len) send(fd, ptr, len, 0) +#define netclose(fd) closesocket(fd) +#endif + +// FIXME: currently I/O is unbuffered + +#define KNF_TYPE_LOCAL 1 +#define KNF_TYPE_FTP 2 +#define KNF_TYPE_HTTP 3 + +typedef struct knetFile_s { + int type, fd; + int64_t offset; + char *host, *port; + + // the following are for FTP only + int ctrl_fd, pasv_ip[4], pasv_port, max_response, no_reconnect, is_ready; + char *response, *retr, *size_cmd; + int64_t seek_offset; // for lazy seek + int64_t file_size; + + // the following are for HTTP only + char *path, *http_host; +} knetFile; + +#define knet_tell(fp) ((fp)->offset) +#define knet_fileno(fp) ((fp)->fd) + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef _WIN32 + int knet_win32_init(); + void knet_win32_destroy(); +#endif + + knetFile *knet_open(const char *fn, const char *mode); + + /* + This only works with local files. + */ + knetFile *knet_dopen(int fd, const char *mode); + + /* + If ->is_ready==0, this routine updates ->fd; otherwise, it simply + reads from ->fd. + */ + off_t knet_read(knetFile *fp, void *buf, off_t len); + + /* + This routine only sets ->offset and ->is_ready=0. It does not + communicate with the FTP server. + */ + off_t knet_seek(knetFile *fp, int64_t off, int whence); + int knet_close(knetFile *fp); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/web/server/h2o/libh2o/deps/klib/knhx.c b/web/server/h2o/libh2o/deps/klib/knhx.c new file mode 100644 index 00000000..8dbd3b6e --- /dev/null +++ b/web/server/h2o/libh2o/deps/klib/knhx.c @@ -0,0 +1,166 @@ +#include +#include +#include +#include +#include "knhx.h" + +typedef struct { + int error, n, max; + knhx1_t *node; +} knaux_t; + +static inline char *add_node(const char *s, knaux_t *aux, int x) +{ + char *p, *nbeg, *nend = 0; + knhx1_t *r; + if (aux->n == aux->max) { + aux->max = aux->max? aux->max<<1 : 8; + aux->node = (knhx1_t*)realloc(aux->node, sizeof(knhx1_t) * aux->max); + } + r = aux->node + (aux->n++); + r->n = x; r->parent = -1; + for (p = (char*)s, nbeg = p, r->d = -1.0; *p && *p != ',' && *p != ')'; ++p) { + if (*p == '[') { + if (nend == 0) nend = p; + do ++p; while (*p && *p != ']'); + if (*p == 0) { + aux->error |= KNERR_BRACKET; + break; + } + } else if (*p == ':') { + if (nend == 0) nend = p; + r->d = strtod(p + 1, &p); + --p; + } else if (!isgraph(*p)) if (nend == 0) nend = p; + } + if (nend == 0) nend = p; + if (nend != nbeg) { + r->name = (char*)calloc(nend - nbeg + 1, 1); + strncpy(r->name, nbeg, nend - nbeg); + } else r->name = strdup(""); + return p; +} + +knhx1_t *kn_parse(const char *nhx, int *_n, int *_error) +{ + char *p; + int *stack, top, max; + knaux_t *aux; + knhx1_t *ret; + +#define __push_back(y) do { \ + if (top == max) { \ + max = max? max<<1 : 16; \ + stack = (int*)realloc(stack, sizeof(int) * max); \ + } \ + stack[top++] = (y); \ + } while (0) \ + + stack = 0; top = max = 0; + p = (char*)nhx; + aux = (knaux_t*)calloc(1, sizeof(knaux_t)); + while (*p) { + while (*p && !isgraph(*p)) ++p; + if (*p == 0) break; + if (*p == ',') ++p; + else if (*p == '(') { + __push_back(-1); + ++p; + } else if (*p == ')') { + int x = aux->n, m, i; + for (i = top - 1; i >= 0; --i) + if (stack[i] < 0) break; + m = top - 1 - i; + p = add_node(p + 1, aux, m); + aux->node[x].child = (int*)calloc(m, sizeof(int)); + for (i = top - 1, m = m - 1; m >= 0; --m, --i) { + aux->node[x].child[m] = stack[i]; + aux->node[stack[i]].parent = x; + } + top = i; + __push_back(x); + } else { + __push_back(aux->n); + p = add_node(p, aux, 0); + } + } + *_n = aux->n; + *_error = aux->error; + ret = aux->node; + free(aux); free(stack); + return ret; +} + +#ifndef kroundup32 +#define kroundup32(x) (--(x), (x)|=(x)>>1, (x)|=(x)>>2, (x)|=(x)>>4, (x)|=(x)>>8, (x)|=(x)>>16, ++(x)) +#endif + +static inline int kputsn(const char *p, int l, kstring_t *s) +{ + if (s->l + l + 1 >= s->m) { + s->m = s->l + l + 2; + kroundup32(s->m); + s->s = (char*)realloc(s->s, s->m); + } + memcpy(s->s + s->l, p, l); + s->l += l; s->s[s->l] = 0; + return l; +} + +static inline int kputc(int c, kstring_t *s) +{ + if (s->l + 1 >= s->m) { + s->m = s->l + 2; + kroundup32(s->m); + s->s = (char*)realloc(s->s, s->m); + } + s->s[s->l++] = c; s->s[s->l] = 0; + return c; +} + +static void format_node_recur(const knhx1_t *node, const knhx1_t *p, kstring_t *s, char *numbuf) +{ + if (p->n) { + int i; + kputc('(', s); + for (i = 0; i < p->n; ++i) { + if (i) kputc(',', s); + format_node_recur(node, &node[p->child[i]], s, numbuf); + } + kputc(')', s); + if (p->name) kputsn(p->name, strlen(p->name), s); + if (p->d >= 0) { + sprintf(numbuf, ":%g", p->d); + kputsn(numbuf, strlen(numbuf), s); + } + } else kputsn(p->name, strlen(p->name), s); +} + +void kn_format(const knhx1_t *node, int root, kstring_t *s) // TODO: get rid of recursion +{ + char numbuf[128]; + format_node_recur(node, &node[root], s, numbuf); +} + +#ifdef KNHX_MAIN +int main(int argc, char *argv[]) +{ + char *s = "((a[abc],d1)x:0.5,((b[&&NHX:S=MOUSE],h2)[&&NHX:S=HUMAN:B=99][blabla][&&NHX:K=foo],c))"; + knhx1_t *node; + int i, j, n, error; + kstring_t str; + node = kn_parse(s, &n, &error); + for (i = 0; i < n; ++i) { + knhx1_t *p = node + i; + printf("[%d] %s\t%d\t%d\t%g", i, p->name, p->parent, p->n, p->d); + for (j = 0; j < p->n; ++j) + printf("\t%d", p->child[j]); + putchar('\n'); + } + str.l = str.m = 0; str.s = 0; + kn_format(node, n-1, &str); + puts(str.s); + free(str.s); + return 0; +} +#endif diff --git a/web/server/h2o/libh2o/deps/klib/knhx.h b/web/server/h2o/libh2o/deps/klib/knhx.h new file mode 100644 index 00000000..dbad7dd9 --- /dev/null +++ b/web/server/h2o/libh2o/deps/klib/knhx.h @@ -0,0 +1,35 @@ +#ifndef KNHX_H_ +#define KNHX_H_ + +#define KNERR_MISSING_LEFT 0x01 +#define KNERR_MISSING_RGHT 0x02 +#define KNERR_BRACKET 0x04 +#define KNERR_COLON 0x08 + +typedef struct { + int parent, n; + int *child; + char *name; + double d; +} knhx1_t; + +#ifndef KSTRING_T +#define KSTRING_T kstring_t +typedef struct __kstring_t { + size_t l, m; + char *s; +} kstring_t; +#endif + +#ifdef __cplusplus +extern "C" { +#endif + + knhx1_t *kn_parse(const char *nhx, int *_n, int *_error); + void kn_format(const knhx1_t *node, int root, kstring_t *s); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/web/server/h2o/libh2o/deps/klib/kopen.c b/web/server/h2o/libh2o/deps/klib/kopen.c new file mode 100644 index 00000000..f72735c4 --- /dev/null +++ b/web/server/h2o/libh2o/deps/klib/kopen.c @@ -0,0 +1,343 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifndef _WIN32 +#include +#include +#include +#endif + +#ifdef _WIN32 +#define _KO_NO_NET +#endif + +#ifndef _KO_NO_NET +static int socket_wait(int fd, int is_read) +{ + fd_set fds, *fdr = 0, *fdw = 0; + struct timeval tv; + int ret; + tv.tv_sec = 5; tv.tv_usec = 0; // 5 seconds time out + FD_ZERO(&fds); + FD_SET(fd, &fds); + if (is_read) fdr = &fds; + else fdw = &fds; + ret = select(fd+1, fdr, fdw, 0, &tv); + if (ret == -1) perror("select"); + return ret; +} + +static int socket_connect(const char *host, const char *port) +{ +#define __err_connect(func) do { perror(func); freeaddrinfo(res); return -1; } while (0) + + int on = 1, fd; + struct linger lng = { 0, 0 }; + struct addrinfo hints, *res = 0; + memset(&hints, 0, sizeof(struct addrinfo)); + hints.ai_family = AF_UNSPEC; + hints.ai_socktype = SOCK_STREAM; + if (getaddrinfo(host, port, &hints, &res) != 0) __err_connect("getaddrinfo"); + if ((fd = socket(res->ai_family, res->ai_socktype, res->ai_protocol)) == -1) __err_connect("socket"); + if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) == -1) __err_connect("setsockopt"); + if (setsockopt(fd, SOL_SOCKET, SO_LINGER, &lng, sizeof(lng)) == -1) __err_connect("setsockopt"); + if (connect(fd, res->ai_addr, res->ai_addrlen) != 0) __err_connect("connect"); + freeaddrinfo(res); + return fd; +#undef __err_connect +} + +static int http_open(const char *fn) +{ + char *p, *proxy, *q, *http_host, *host, *port, *path, *buf; + int fd, ret, l; + + /* parse URL; adapted from khttp_parse_url() in knetfile.c */ + if (strstr(fn, "http://") != fn) return 0; + // set ->http_host + for (p = (char*)fn + 7; *p && *p != '/'; ++p); + l = p - fn - 7; + http_host = calloc(l + 1, 1); + strncpy(http_host, fn + 7, l); + http_host[l] = 0; + for (q = http_host; *q && *q != ':'; ++q); + if (*q == ':') *q++ = 0; + // get http_proxy + proxy = getenv("http_proxy"); + // set host, port and path + if (proxy == 0) { + host = strdup(http_host); // when there is no proxy, server name is identical to http_host name. + port = strdup(*q? q : "80"); + path = strdup(*p? p : "/"); + } else { + host = (strstr(proxy, "http://") == proxy)? strdup(proxy + 7) : strdup(proxy); + for (q = host; *q && *q != ':'; ++q); + if (*q == ':') *q++ = 0; + port = strdup(*q? q : "80"); + path = strdup(fn); + } + + /* connect; adapted from khttp_connect() in knetfile.c */ + l = 0; + fd = socket_connect(host, port); + buf = calloc(0x10000, 1); // FIXME: I am lazy... But in principle, 64KB should be large enough. + l += sprintf(buf + l, "GET %s HTTP/1.0\r\nHost: %s\r\n", path, http_host); + l += sprintf(buf + l, "\r\n"); + write(fd, buf, l); + l = 0; + while (read(fd, buf + l, 1)) { // read HTTP header; FIXME: bad efficiency + if (buf[l] == '\n' && l >= 3) + if (strncmp(buf + l - 3, "\r\n\r\n", 4) == 0) break; + ++l; + } + buf[l] = 0; + if (l < 14) { // prematured header + close(fd); + fd = -1; + } + ret = strtol(buf + 8, &p, 0); // HTTP return code + if (ret != 200) { + close(fd); + fd = -1; + } + free(buf); free(http_host); free(host); free(port); free(path); + return fd; +} + +typedef struct { + int max_response, ctrl_fd; + char *response; +} ftpaux_t; + +static int kftp_get_response(ftpaux_t *aux) +{ + unsigned char c; + int n = 0; + char *p; + if (socket_wait(aux->ctrl_fd, 1) <= 0) return 0; + while (read(aux->ctrl_fd, &c, 1)) { // FIXME: this is *VERY BAD* for unbuffered I/O + if (n >= aux->max_response) { + aux->max_response = aux->max_response? aux->max_response<<1 : 256; + aux->response = realloc(aux->response, aux->max_response); + } + aux->response[n++] = c; + if (c == '\n') { + if (n >= 4 && isdigit(aux->response[0]) && isdigit(aux->response[1]) && isdigit(aux->response[2]) + && aux->response[3] != '-') break; + n = 0; + continue; + } + } + if (n < 2) return -1; + aux->response[n-2] = 0; + return strtol(aux->response, &p, 0); +} + +static int kftp_send_cmd(ftpaux_t *aux, const char *cmd, int is_get) +{ + if (socket_wait(aux->ctrl_fd, 0) <= 0) return -1; // socket is not ready for writing + write(aux->ctrl_fd, cmd, strlen(cmd)); + return is_get? kftp_get_response(aux) : 0; +} + +static int ftp_open(const char *fn) +{ + char *p, *host = 0, *port = 0, *retr = 0; + char host2[80], port2[10]; + int v[6], l, fd = -1, ret, pasv_port, pasv_ip[4]; + ftpaux_t aux; + + /* parse URL */ + if (strstr(fn, "ftp://") != fn) return 0; + for (p = (char*)fn + 6; *p && *p != '/'; ++p); + if (*p != '/') return 0; + l = p - fn - 6; + port = strdup("21"); + host = calloc(l + 1, 1); + strncpy(host, fn + 6, l); + retr = calloc(strlen(p) + 8, 1); + sprintf(retr, "RETR %s\r\n", p); + + /* connect to ctrl */ + memset(&aux, 0, sizeof(ftpaux_t)); + aux.ctrl_fd = socket_connect(host, port); + if (aux.ctrl_fd == -1) goto ftp_open_end; /* fail to connect ctrl */ + + /* connect to the data stream */ + kftp_get_response(&aux); + kftp_send_cmd(&aux, "USER anonymous\r\n", 1); + kftp_send_cmd(&aux, "PASS kopen@\r\n", 1); + kftp_send_cmd(&aux, "TYPE I\r\n", 1); + kftp_send_cmd(&aux, "PASV\r\n", 1); + for (p = aux.response; *p && *p != '('; ++p); + if (*p != '(') goto ftp_open_end; + ++p; + sscanf(p, "%d,%d,%d,%d,%d,%d", &v[0], &v[1], &v[2], &v[3], &v[4], &v[5]); + memcpy(pasv_ip, v, 4 * sizeof(int)); + pasv_port = (v[4]<<8&0xff00) + v[5]; + kftp_send_cmd(&aux, retr, 0); + sprintf(host2, "%d.%d.%d.%d", pasv_ip[0], pasv_ip[1], pasv_ip[2], pasv_ip[3]); + sprintf(port2, "%d", pasv_port); + fd = socket_connect(host2, port2); + if (fd == -1) goto ftp_open_end; + ret = kftp_get_response(&aux); + if (ret != 150) { + close(fd); + fd = -1; + } + close(aux.ctrl_fd); + +ftp_open_end: + free(host); free(port); free(retr); free(aux.response); + return fd; +} +#endif /* !defined(_KO_NO_NET) */ + +static char **cmd2argv(const char *cmd) +{ + int i, beg, end, argc; + char **argv, *p, *q, *str; + end = strlen(cmd); + for (i = end - 1; i >= 0; --i) + if (!isspace(cmd[i])) break; + end = i + 1; + for (beg = 0; beg < end; ++beg) + if (!isspace(cmd[beg])) break; + if (beg == end) return 0; + for (i = beg + 1, argc = 0; i < end; ++i) + if (isspace(cmd[i]) && !isspace(cmd[i-1])) + ++argc; + argv = (char**)calloc(argc + 2, sizeof(void*)); + argv[0] = str = (char*)calloc(end - beg + 1, 1); + strncpy(argv[0], cmd + beg, end - beg); + for (i = argc = 1, q = p = str; i < end - beg; ++i) + if (isspace(str[i])) str[i] = 0; + else if (str[i] && str[i-1] == 0) argv[argc++] = &str[i]; + return argv; +} + +#define KO_STDIN 1 +#define KO_FILE 2 +#define KO_PIPE 3 +#define KO_HTTP 4 +#define KO_FTP 5 + +typedef struct { + int type, fd; + pid_t pid; +} koaux_t; + +void *kopen(const char *fn, int *_fd) +{ + koaux_t *aux = 0; + *_fd = -1; + if (strstr(fn, "http://") == fn) { + aux = calloc(1, sizeof(koaux_t)); + aux->type = KO_HTTP; + aux->fd = http_open(fn); + } else if (strstr(fn, "ftp://") == fn) { + aux = calloc(1, sizeof(koaux_t)); + aux->type = KO_FTP; + aux->fd = ftp_open(fn); + } else if (strcmp(fn, "-") == 0) { + aux = calloc(1, sizeof(koaux_t)); + aux->type = KO_STDIN; + aux->fd = STDIN_FILENO; + } else { + const char *p, *q; + for (p = fn; *p; ++p) + if (!isspace(*p)) break; + if (*p == '<') { // pipe open + int need_shell, pfd[2]; + pid_t pid; + // a simple check to see if we need to invoke a shell; not always working + for (q = p + 1; *q; ++q) + if (ispunct(*q) && *q != '.' && *q != '_' && *q != '-' && *q != ':') + break; + need_shell = (*q != 0); + pipe(pfd); + pid = vfork(); + if (pid == -1) { /* vfork() error */ + close(pfd[0]); close(pfd[1]); + return 0; + } + if (pid == 0) { /* the child process */ + char **argv; /* FIXME: I do not know if this will lead to a memory leak */ + close(pfd[0]); + dup2(pfd[1], STDOUT_FILENO); + close(pfd[1]); + if (!need_shell) { + argv = cmd2argv(p + 1); + execvp(argv[0], argv); + free(argv[0]); free(argv); + } else execl("/bin/sh", "sh", "-c", p + 1, NULL); + exit(1); + } else { /* parent process */ + close(pfd[1]); + aux = calloc(1, sizeof(koaux_t)); + aux->type = KO_PIPE; + aux->fd = pfd[0]; + aux->pid = pid; + } + } else { +#ifdef _WIN32 + *_fd = open(fn, O_RDONLY | O_BINARY); +#else + *_fd = open(fn, O_RDONLY); +#endif + if (*_fd) { + aux = calloc(1, sizeof(koaux_t)); + aux->type = KO_FILE; + aux->fd = *_fd; + } + } + } + *_fd = aux->fd; + return aux; +} + +int kclose(void *a) +{ + koaux_t *aux = (koaux_t*)a; + if (aux->type == KO_PIPE) { + int status; + pid_t pid; + pid = waitpid(aux->pid, &status, WNOHANG); + if (pid != aux->pid) kill(aux->pid, 15); + } + return 0; +} + +#ifdef _KO_MAIN +#define BUF_SIZE 0x10000 +int main(int argc, char *argv[]) +{ + void *x; + int l, fd; + unsigned char buf[BUF_SIZE]; + FILE *fp; + if (argc == 1) { + fprintf(stderr, "Usage: kopen \n"); + return 1; + } + x = kopen(argv[1], &fd); + fp = fdopen(fd, "r"); + if (fp == 0) { + fprintf(stderr, "ERROR: fail to open the input\n"); + return 1; + } + do { + if ((l = fread(buf, 1, BUF_SIZE, fp)) != 0) + fwrite(buf, 1, l, stdout); + } while (l == BUF_SIZE); + fclose(fp); + kclose(x); + return 0; +} +#endif diff --git a/web/server/h2o/libh2o/deps/klib/ksa.c b/web/server/h2o/libh2o/deps/klib/ksa.c new file mode 100644 index 00000000..18f686d1 --- /dev/null +++ b/web/server/h2o/libh2o/deps/klib/ksa.c @@ -0,0 +1,242 @@ +/* + * Copyright (c) 2008 Yuta Mori All Rights Reserved. + * 2011 Attractive Chaos + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +/* This is a library for constructing the suffix array for a string containing + * multiple sentinels with sentinels all represented by 0. The last symbol in + * the string must be a sentinel. The library is modified from an early version + * of Yuta Mori's SAIS library, but is slower than the lastest SAIS by about + * 30%, partly due to the recent optimization Yuta has applied and partly due + * to the extra comparisons between sentinels. This is not the first effort in + * supporting multi-sentinel strings, but is probably the easiest to use. */ + +#include + +#ifdef _KSA64 +#include +typedef int64_t saint_t; +#define SAINT_MAX INT64_MAX +#define SAIS_CORE ksa_core64 +#define SAIS_BWT ksa_bwt64 +#define SAIS_MAIN ksa_sa64 +#else +#include +typedef int saint_t; +#define SAINT_MAX INT_MAX +#define SAIS_CORE ksa_core +#define SAIS_BWT ksa_bwt +#define SAIS_MAIN ksa_sa +#endif + +/* T is of type "const unsigned char*". If T[i] is a sentinel, chr(i) takes a negative value */ +#define chr(i) (cs == sizeof(saint_t) ? ((const saint_t *)T)[i] : (T[i]? (saint_t)T[i] : i - SAINT_MAX)) + +/** Count the occurrences of each symbol */ +static void getCounts(const unsigned char *T, saint_t *C, saint_t n, saint_t k, int cs) +{ + saint_t i; + for (i = 0; i < k; ++i) C[i] = 0; + for (i = 0; i < n; ++i) { + saint_t c = chr(i); + ++C[c > 0? c : 0]; + } +} + +/** + * Find the end of each bucket + * + * @param C occurrences computed by getCounts(); input + * @param B start/end of each bucket; output + * @param k size of alphabet + * @param end compute the end of bucket if true; otherwise compute the end + */ +static inline void getBuckets(const saint_t *C, saint_t *B, saint_t k, saint_t end) +{ + saint_t i, sum = 0; + if (end) for (i = 0; i < k; ++i) sum += C[i], B[i] = sum; + else for (i = 0; i < k; ++i) sum += C[i], B[i] = sum - C[i]; +} + +/** Induced sort */ +static void induceSA(const unsigned char *T, saint_t *SA, saint_t *C, saint_t *B, saint_t n, saint_t k, saint_t cs) +{ + saint_t *b, i, j; + saint_t c0, c1; + /* left-to-right induced sort (for L-type) */ + if (C == B) getCounts(T, C, n, k, cs); + getBuckets(C, B, k, 0); /* find starts of buckets */ + for (i = 0, b = 0, c1 = -1; i < n; ++i) { + j = SA[i], SA[i] = ~j; + if (0 < j) { /* >0 if j-1 is L-type; <0 if S-type; ==0 undefined */ + --j; + if ((c0 = chr(j)) != c1) { + B[c1 > 0? c1 : 0] = b - SA; + c1 = c0; + b = SA + B[c1 > 0? c1 : 0]; + } + *b++ = (0 < j && chr(j - 1) < c1) ? ~j : j; + } + } + /* right-to-left induced sort (for S-type) */ + if (C == B) getCounts(T, C, n, k, cs); + getBuckets(C, B, k, 1); /* find ends of buckets */ + for (i = n - 1, b = 0, c1 = -1; 0 <= i; --i) { + if (0 < (j = SA[i])) { /* the prefix is S-type */ + --j; + if ((c0 = chr(j)) != c1) { + B[c1 > 0? c1 : 0] = b - SA; + c1 = c0; + b = SA + B[c1 > 0? c1 : 0]; + } + if (c0 > 0) *--b = (j == 0 || chr(j - 1) > c1) ? ~j : j; + } else SA[i] = ~j; /* if L-type, change the sign */ + } +} + +/** + * Recursively construct the suffix array for a string containing multiple + * sentinels. NULL is taken as the sentinel. + * + * @param T NULL terminated input string (there can be multiple NULLs) + * @param SA output suffix array + * @param fs working space available in SA (typically 0 when first called) + * @param n length of T, including the trailing NULL + * @param k size of the alphabet (typically 256 when first called) + * @param cs # bytes per element in T; 1 or sizeof(saint_t) (typically 1 when first called) + * + * @return 0 upon success + */ +int SAIS_CORE(const unsigned char *T, saint_t *SA, saint_t fs, saint_t n, saint_t k, int cs) +{ + saint_t *C, *B; + saint_t i, j, c, m, q, qlen, name; + saint_t c0, c1; + + /* STAGE I: reduce the problem by at least 1/2 sort all the S-substrings */ + if (k <= fs) C = SA + n, B = (k <= fs - k) ? C + k : C; + else { + if ((C = (saint_t*)malloc(k * (1 + (cs == 1)) * sizeof(saint_t))) == NULL) return -2; + B = cs == 1? C + k : C; + } + getCounts(T, C, n, k, cs); + getBuckets(C, B, k, 1); /* find ends of buckets */ + for (i = 0; i < n; ++i) SA[i] = 0; + /* mark L and S (the t array in Nong et al.), and keep the positions of LMS in the buckets */ + for (i = n - 2, c = 1, c1 = chr(n - 1); 0 <= i; --i, c1 = c0) { + if ((c0 = chr(i)) < c1 + c) c = 1; /* c1 = chr(i+1); c==1 if in an S run */ + else if (c) SA[--B[c1 > 0? c1 : 0]] = i + 1, c = 0; + } + induceSA(T, SA, C, B, n, k, cs); + if (fs < k) free(C); + /* pack all the sorted LMS into the first m items of SA + 2*m must be not larger than n (see Nong et al. for the proof) */ + for (i = 0, m = 0; i < n; ++i) { + saint_t p = SA[i]; + if (p == n - 1) SA[m++] = p; + else if (0 < p && chr(p - 1) > (c0 = chr(p))) { + for (j = p + 1; j < n && c0 == (c1 = chr(j)); ++j); + if (j < n && c0 < c1) SA[m++] = p; + } + } + for (i = m; i < n; ++i) SA[i] = 0; /* init the name array buffer */ + /* store the length of all substrings */ + for (i = n - 2, j = n, c = 1, c1 = chr(n - 1); 0 <= i; --i, c1 = c0) { + if ((c0 = chr(i)) < c1 + c) c = 1; /* c1 = chr(i+1) */ + else if (c) SA[m + ((i + 1) >> 1)] = j - i - 1, j = i + 1, c = 0; + } + /* find the lexicographic names of all substrings */ + for (i = 0, name = 0, q = n, qlen = 0; i < m; ++i) { + saint_t p = SA[i], plen = SA[m + (p >> 1)], diff = 1; + if (plen == qlen) { + for (j = 0; j < plen && chr(p + j) == chr(q + j); j++); + if (j == plen) diff = 0; + } + if (diff) ++name, q = p, qlen = plen; + SA[m + (p >> 1)] = name; + } + + /* STAGE II: solve the reduced problem; recurse if names are not yet unique */ + if (name < m) { + saint_t *RA = SA + n + fs - m - 1; + for (i = n - 1, j = m - 1; m <= i; --i) + if (SA[i] != 0) RA[j--] = SA[i]; + RA[m] = 0; // add a sentinel; in the resulting SA, SA[0]==m always stands + if (SAIS_CORE((unsigned char *)RA, SA, fs + n - m * 2 - 2, m + 1, name + 1, sizeof(saint_t)) != 0) return -2; + for (i = n - 2, j = m - 1, c = 1, c1 = chr(n - 1); 0 <= i; --i, c1 = c0) { + if ((c0 = chr(i)) < c1 + c) c = 1; + else if (c) RA[j--] = i + 1, c = 0; /* get p1 */ + } + for (i = 0; i < m; ++i) SA[i] = RA[SA[i+1]]; /* get index */ + } + + /* STAGE III: induce the result for the original problem */ + if (k <= fs) C = SA + n, B = (k <= fs - k) ? C + k : C; + else { + if ((C = (saint_t*)malloc(k * (1 + (cs == 1)) * sizeof(saint_t))) == NULL) return -2; + B = cs == 1? C + k : C; + } + /* put all LMS characters into their buckets */ + getCounts(T, C, n, k, cs); + getBuckets(C, B, k, 1); /* find ends of buckets */ + for (i = m; i < n; ++i) SA[i] = 0; /* init SA[m..n-1] */ + for (i = m - 1; 0 <= i; --i) { + j = SA[i], SA[i] = 0; + c = chr(j); + SA[--B[c > 0? c : 0]] = j; + } + induceSA(T, SA, C, B, n, k, cs); + if (fs < k) free(C); + return 0; +} + +/** + * Construct the suffix array for a NULL terminated string possibly containing + * multiple sentinels (NULLs). + * + * @param T[0..n-1] NULL terminated input string + * @param SA[0..n-1] output suffix array + * @param n length of the given string, including NULL + * @param k size of the alphabet including the sentinel; no more than 256 + * @return 0 upon success + */ +int SAIS_MAIN(const unsigned char *T, saint_t *SA, saint_t n, int k) +{ + if (T == NULL || SA == NULL || T[n - 1] != '\0' || n <= 0) return -1; + if (k < 0 || k > 256) k = 256; + return SAIS_CORE(T, SA, 0, n, (saint_t)k, 1); +} + +int SAIS_BWT(unsigned char *T, saint_t n, int k) +{ + saint_t *SA, i; + int ret; + if ((SA = malloc(n * sizeof(saint_t))) == 0) return -1; + if ((ret = SAIS_MAIN(T, SA, n, k)) != 0) return ret; + for (i = 0; i < n; ++i) + if (SA[i]) SA[i] = T[SA[i] - 1]; // if SA[i]==0, SA[i]=0 + for (i = 0; i < n; ++i) T[i] = SA[i]; + free(SA); + return 0; +} diff --git a/web/server/h2o/libh2o/deps/klib/kseq.h b/web/server/h2o/libh2o/deps/klib/kseq.h new file mode 100644 index 00000000..b2238d1d --- /dev/null +++ b/web/server/h2o/libh2o/deps/klib/kseq.h @@ -0,0 +1,235 @@ +/* The MIT License + + Copyright (c) 2008, 2009, 2011 Attractive Chaos + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. +*/ + +/* Last Modified: 05MAR2012 */ + +#ifndef AC_KSEQ_H +#define AC_KSEQ_H + +#include +#include +#include + +#define KS_SEP_SPACE 0 // isspace(): \t, \n, \v, \f, \r +#define KS_SEP_TAB 1 // isspace() && !' ' +#define KS_SEP_LINE 2 // line separator: "\n" (Unix) or "\r\n" (Windows) +#define KS_SEP_MAX 2 + +#define __KS_TYPE(type_t) \ + typedef struct __kstream_t { \ + unsigned char *buf; \ + int begin, end, is_eof; \ + type_t f; \ + } kstream_t; + +#define ks_eof(ks) ((ks)->is_eof && (ks)->begin >= (ks)->end) +#define ks_rewind(ks) ((ks)->is_eof = (ks)->begin = (ks)->end = 0) + +#define __KS_BASIC(type_t, __bufsize) \ + static inline kstream_t *ks_init(type_t f) \ + { \ + kstream_t *ks = (kstream_t*)calloc(1, sizeof(kstream_t)); \ + ks->f = f; \ + ks->buf = (unsigned char*)malloc(__bufsize); \ + return ks; \ + } \ + static inline void ks_destroy(kstream_t *ks) \ + { \ + if (ks) { \ + free(ks->buf); \ + free(ks); \ + } \ + } + +#define __KS_GETC(__read, __bufsize) \ + static inline int ks_getc(kstream_t *ks) \ + { \ + if (ks->is_eof && ks->begin >= ks->end) return -1; \ + if (ks->begin >= ks->end) { \ + ks->begin = 0; \ + ks->end = __read(ks->f, ks->buf, __bufsize); \ + if (ks->end == 0) { ks->is_eof = 1; return -1;} \ + } \ + return (int)ks->buf[ks->begin++]; \ + } + +#ifndef KSTRING_T +#define KSTRING_T kstring_t +typedef struct __kstring_t { + size_t l, m; + char *s; +} kstring_t; +#endif + +#ifndef kroundup32 +#define kroundup32(x) (--(x), (x)|=(x)>>1, (x)|=(x)>>2, (x)|=(x)>>4, (x)|=(x)>>8, (x)|=(x)>>16, ++(x)) +#endif + +#define __KS_GETUNTIL(__read, __bufsize) \ + static int ks_getuntil2(kstream_t *ks, int delimiter, kstring_t *str, int *dret, int append) \ + { \ + int gotany = 0; \ + if (dret) *dret = 0; \ + str->l = append? str->l : 0; \ + for (;;) { \ + int i; \ + if (ks->begin >= ks->end) { \ + if (!ks->is_eof) { \ + ks->begin = 0; \ + ks->end = __read(ks->f, ks->buf, __bufsize); \ + if (ks->end == 0) { ks->is_eof = 1; break; } \ + } else break; \ + } \ + if (delimiter == KS_SEP_LINE) { \ + for (i = ks->begin; i < ks->end; ++i) \ + if (ks->buf[i] == '\n') break; \ + } else if (delimiter > KS_SEP_MAX) { \ + for (i = ks->begin; i < ks->end; ++i) \ + if (ks->buf[i] == delimiter) break; \ + } else if (delimiter == KS_SEP_SPACE) { \ + for (i = ks->begin; i < ks->end; ++i) \ + if (isspace(ks->buf[i])) break; \ + } else if (delimiter == KS_SEP_TAB) { \ + for (i = ks->begin; i < ks->end; ++i) \ + if (isspace(ks->buf[i]) && ks->buf[i] != ' ') break; \ + } else i = 0; /* never come to here! */ \ + if (str->m - str->l < (size_t)(i - ks->begin + 1)) { \ + str->m = str->l + (i - ks->begin) + 1; \ + kroundup32(str->m); \ + str->s = (char*)realloc(str->s, str->m); \ + } \ + gotany = 1; \ + memcpy(str->s + str->l, ks->buf + ks->begin, i - ks->begin); \ + str->l = str->l + (i - ks->begin); \ + ks->begin = i + 1; \ + if (i < ks->end) { \ + if (dret) *dret = ks->buf[i]; \ + break; \ + } \ + } \ + if (!gotany && ks_eof(ks)) return -1; \ + if (str->s == 0) { \ + str->m = 1; \ + str->s = (char*)calloc(1, 1); \ + } else if (delimiter == KS_SEP_LINE && str->l > 1 && str->s[str->l-1] == '\r') --str->l; \ + str->s[str->l] = '\0'; \ + return str->l; \ + } \ + static inline int ks_getuntil(kstream_t *ks, int delimiter, kstring_t *str, int *dret) \ + { return ks_getuntil2(ks, delimiter, str, dret, 0); } + +#define KSTREAM_INIT(type_t, __read, __bufsize) \ + __KS_TYPE(type_t) \ + __KS_BASIC(type_t, __bufsize) \ + __KS_GETC(__read, __bufsize) \ + __KS_GETUNTIL(__read, __bufsize) + +#define kseq_rewind(ks) ((ks)->last_char = (ks)->f->is_eof = (ks)->f->begin = (ks)->f->end = 0) + +#define __KSEQ_BASIC(SCOPE, type_t) \ + SCOPE kseq_t *kseq_init(type_t fd) \ + { \ + kseq_t *s = (kseq_t*)calloc(1, sizeof(kseq_t)); \ + s->f = ks_init(fd); \ + return s; \ + } \ + SCOPE void kseq_destroy(kseq_t *ks) \ + { \ + if (!ks) return; \ + free(ks->name.s); free(ks->comment.s); free(ks->seq.s); free(ks->qual.s); \ + ks_destroy(ks->f); \ + free(ks); \ + } + +/* Return value: + >=0 length of the sequence (normal) + -1 end-of-file + -2 truncated quality string + */ +#define __KSEQ_READ(SCOPE) \ + SCOPE int kseq_read(kseq_t *seq) \ + { \ + int c; \ + kstream_t *ks = seq->f; \ + if (seq->last_char == 0) { /* then jump to the next header line */ \ + while ((c = ks_getc(ks)) != -1 && c != '>' && c != '@'); \ + if (c == -1) return -1; /* end of file */ \ + seq->last_char = c; \ + } /* else: the first header char has been read in the previous call */ \ + seq->comment.l = seq->seq.l = seq->qual.l = 0; /* reset all members */ \ + if (ks_getuntil(ks, 0, &seq->name, &c) < 0) return -1; /* normal exit: EOF */ \ + if (c != '\n') ks_getuntil(ks, KS_SEP_LINE, &seq->comment, 0); /* read FASTA/Q comment */ \ + if (seq->seq.s == 0) { /* we can do this in the loop below, but that is slower */ \ + seq->seq.m = 256; \ + seq->seq.s = (char*)malloc(seq->seq.m); \ + } \ + while ((c = ks_getc(ks)) != -1 && c != '>' && c != '+' && c != '@') { \ + if (c == '\n') continue; /* skip empty lines */ \ + seq->seq.s[seq->seq.l++] = c; /* this is safe: we always have enough space for 1 char */ \ + ks_getuntil2(ks, KS_SEP_LINE, &seq->seq, 0, 1); /* read the rest of the line */ \ + } \ + if (c == '>' || c == '@') seq->last_char = c; /* the first header char has been read */ \ + if (seq->seq.l + 1 >= seq->seq.m) { /* seq->seq.s[seq->seq.l] below may be out of boundary */ \ + seq->seq.m = seq->seq.l + 2; \ + kroundup32(seq->seq.m); /* rounded to the next closest 2^k */ \ + seq->seq.s = (char*)realloc(seq->seq.s, seq->seq.m); \ + } \ + seq->seq.s[seq->seq.l] = 0; /* null terminated string */ \ + if (c != '+') return seq->seq.l; /* FASTA */ \ + if (seq->qual.m < seq->seq.m) { /* allocate memory for qual in case insufficient */ \ + seq->qual.m = seq->seq.m; \ + seq->qual.s = (char*)realloc(seq->qual.s, seq->qual.m); \ + } \ + while ((c = ks_getc(ks)) != -1 && c != '\n'); /* skip the rest of '+' line */ \ + if (c == -1) return -2; /* error: no quality string */ \ + while (ks_getuntil2(ks, KS_SEP_LINE, &seq->qual, 0, 1) >= 0 && seq->qual.l < seq->seq.l); \ + seq->last_char = 0; /* we have not come to the next header line */ \ + if (seq->seq.l != seq->qual.l) return -2; /* error: qual string is of a different length */ \ + return seq->seq.l; \ + } + +#define __KSEQ_TYPE(type_t) \ + typedef struct { \ + kstring_t name, comment, seq, qual; \ + int last_char; \ + kstream_t *f; \ + } kseq_t; + +#define KSEQ_INIT2(SCOPE, type_t, __read) \ + KSTREAM_INIT(type_t, __read, 16384) \ + __KSEQ_TYPE(type_t) \ + __KSEQ_BASIC(SCOPE, type_t) \ + __KSEQ_READ(SCOPE) + +#define KSEQ_INIT(type_t, __read) KSEQ_INIT2(static, type_t, __read) + +#define KSEQ_DECLARE(type_t) \ + __KS_TYPE(type_t) \ + __KSEQ_TYPE(type_t) \ + extern kseq_t *kseq_init(type_t fd); \ + void kseq_destroy(kseq_t *ks); \ + int kseq_read(kseq_t *seq); + +#endif diff --git a/web/server/h2o/libh2o/deps/klib/kson.c b/web/server/h2o/libh2o/deps/klib/kson.c new file mode 100644 index 00000000..a8bf1601 --- /dev/null +++ b/web/server/h2o/libh2o/deps/klib/kson.c @@ -0,0 +1,253 @@ +#include +#include +#include +#include +#include +#include +#include "kson.h" + +/************* + *** Parse *** + *************/ + +kson_node_t *kson_parse_core(const char *json, long *_n, int *error, long *parsed_len) +{ + long *stack = 0, top = 0, max = 0, n_a = 0, m_a = 0, i, j; + kson_node_t *a = 0, *u; + const char *p, *q; + size_t *tmp; + +#define __push_back(y) do { \ + if (top == max) { \ + max = max? max<<1 : 4; \ + stack = (long*)realloc(stack, sizeof(long) * max); \ + } \ + stack[top++] = (y); \ + } while (0) + +#define __new_node(z) do { \ + if (n_a == m_a) { \ + long old_m = m_a; \ + m_a = m_a? m_a<<1 : 4; \ + a = (kson_node_t*)realloc(a, sizeof(kson_node_t) * m_a); \ + memset(a + old_m, 0, sizeof(kson_node_t) * (m_a - old_m)); \ + } \ + *(z) = &a[n_a++]; \ + } while (0) + + assert(sizeof(size_t) == sizeof(kson_node_t*)); + *error = KSON_OK; + for (p = json; *p; ++p) { + while (*p && isspace(*p)) ++p; + if (*p == 0) break; + if (*p == ',') { // comma is somewhat redundant + } else if (*p == '[' || *p == '{') { + int t = *p == '['? -1 : -2; + if (top < 2 || stack[top-1] != -3) { // unnamed internal node + __push_back(n_a); + __new_node(&u); + __push_back(t); + } else stack[top-1] = t; // named internal node + } else if (*p == ']' || *p == '}') { + long i, start, t = *p == ']'? -1 : -2; + for (i = top - 1; i >= 0 && stack[i] != t; --i); + if (i < 0) { // error: an extra right bracket + *error = KSON_ERR_EXTRA_RIGHT; + break; + } + start = i; + u = &a[stack[start-1]]; + u->key = u->v.str; + u->n = top - 1 - start; + u->v.child = (kson_node_t**)malloc(u->n * sizeof(kson_node_t*)); + tmp = (size_t*)u->v.child; + for (i = start + 1; i < top; ++i) + tmp[i - start - 1] = stack[i]; + u->type = *p == ']'? KSON_TYPE_BRACKET : KSON_TYPE_BRACE; + if ((top = start) == 1) break; // completed one object; remaining characters discarded + } else if (*p == ':') { + if (top == 0 || stack[top-1] == -3) { + *error = KSON_ERR_NO_KEY; + break; + } + __push_back(-3); + } else { + int c = *p; + // get the node to modify + if (top >= 2 && stack[top-1] == -3) { // we have a key:value pair here + --top; + u = &a[stack[top-1]]; + u->key = u->v.str; // move old value to key + } else { // don't know if this is a bare value or a key:value pair; keep it as a value for now + __push_back(n_a); + __new_node(&u); + } + // parse string + if (c == '\'' || c == '"') { + for (q = ++p; *q && *q != c; ++q) + if (*q == '\\') ++q; + } else { + for (q = p; *q && *q != ']' && *q != '}' && *q != ',' && *q != ':' && *q != '\n'; ++q) + if (*q == '\\') ++q; + } + u->v.str = (char*)malloc(q - p + 1); strncpy(u->v.str, p, q - p); u->v.str[q-p] = 0; // equivalent to u->v.str=strndup(p, q-p) + u->type = c == '\''? KSON_TYPE_SGL_QUOTE : c == '"'? KSON_TYPE_DBL_QUOTE : KSON_TYPE_NO_QUOTE; + p = c == '\'' || c == '"'? q : q - 1; + } + } + while (*p && isspace(*p)) ++p; // skip trailing blanks + if (parsed_len) *parsed_len = p - json; + if (top != 1) *error = KSON_ERR_EXTRA_LEFT; + + for (i = 0; i < n_a; ++i) + for (j = 0, u = &a[i], tmp = (size_t*)u->v.child; j < (long)u->n; ++j) + u->v.child[j] = &a[tmp[j]]; + + free(stack); + *_n = n_a; + return a; +} + +void kson_destroy(kson_t *kson) +{ + long i; + if (kson == 0) return; + for (i = 0; i < kson->n_nodes; ++i) { + free(kson->root[i].key); free(kson->root[i].v.str); + } + free(kson->root); free(kson); +} + +kson_t *kson_parse(const char *json) +{ + kson_t *kson; + int error; + kson = (kson_t*)calloc(1, sizeof(kson_t)); + kson->root = kson_parse_core(json, &kson->n_nodes, &error, 0); + if (error) { + kson_destroy(kson); + return 0; + } + return kson; +} + +/************* + *** Query *** + *************/ + +const kson_node_t *kson_by_path(const kson_node_t *p, int depth, ...) +{ + va_list ap; + va_start(ap, depth); + while (p && depth > 0) { + if (p->type == KSON_TYPE_BRACE) { + p = kson_by_key(p, va_arg(ap, const char*)); + } else if (p->type == KSON_TYPE_BRACKET) { + p = kson_by_index(p, va_arg(ap, long)); + } else break; + --depth; + } + va_end(ap); + return p; +} + +/************** + *** Fromat *** + **************/ + +void kson_format_recur(const kson_node_t *p, int depth) +{ + long i; + if (p->key) printf("\"%s\":", p->key); + if (p->type == KSON_TYPE_BRACKET || p->type == KSON_TYPE_BRACE) { + putchar(p->type == KSON_TYPE_BRACKET? '[' : '{'); + if (p->n) { + putchar('\n'); for (i = 0; i <= depth; ++i) fputs(" ", stdout); + for (i = 0; i < (long)p->n; ++i) { + if (i) { + int i; + putchar(','); + putchar('\n'); for (i = 0; i <= depth; ++i) fputs(" ", stdout); + } + kson_format_recur(p->v.child[i], depth + 1); + } + putchar('\n'); for (i = 0; i < depth; ++i) fputs(" ", stdout); + } + putchar(p->type == KSON_TYPE_BRACKET? ']' : '}'); + } else { + if (p->type != KSON_TYPE_NO_QUOTE) + putchar(p->type == KSON_TYPE_SGL_QUOTE? '\'' : '"'); + fputs(p->v.str, stdout); + if (p->type != KSON_TYPE_NO_QUOTE) + putchar(p->type == KSON_TYPE_SGL_QUOTE? '\'' : '"'); + } +} + +void kson_format(const kson_node_t *root) +{ + kson_format_recur(root, 0); + putchar('\n'); +} + +/********************* + *** Main function *** + *********************/ + +#ifdef KSON_MAIN +#define kroundup32(x) (--(x), (x)|=(x)>>1, (x)|=(x)>>2, (x)|=(x)>>4, (x)|=(x)>>8, (x)|=(x)>>16, ++(x)) +int main(int argc, char *argv[]) +{ + kson_t *kson = 0; + if (argc > 1) { + FILE *fp; + int len = 0, max = 0, tmp, i; + char *json = 0, buf[0x10000]; + if ((fp = fopen(argv[1], "rb")) != 0) { + // read the entire file into a string + while ((tmp = fread(buf, 1, 0x10000, fp)) != 0) { + if (len + tmp + 1 > max) { + max = len + tmp + 1; + kroundup32(max); + json = (char*)realloc(json, max); + } + memcpy(json + len, buf, tmp); + len += tmp; + } + fclose(fp); + // parse + kson = kson_parse(json); + free(json); + if (kson) { + kson_format(kson->root); + if (argc > 2) { + // path finding + const kson_node_t *p = kson->root; + for (i = 2; i < argc && p; ++i) { + if (p->type == KSON_TYPE_BRACKET) + p = kson_by_index(p, atoi(argv[i])); + else if (p->type == KSON_TYPE_BRACE) + p = kson_by_key(p, argv[i]); + else p = 0; + } + if (p) { + if (kson_is_internal(p)) printf("Reached an internal node\n"); + else printf("Value: %s\n", p->v.str); + } else printf("Failed to find the slot\n"); + } + } else printf("Failed to parse\n"); + } + } else { + kson = kson_parse("{'a' : 1,'b':[0,'isn\\'t',true],'d':[{\n\n\n}]}"); + if (kson) { + const kson_node_t *p = kson_by_path(kson->root, 2, "b", 1); + if (p) printf("*** %s\n", p->v.str); + else printf("!!! not found\n"); + kson_format(kson->root); + } else { + printf("Failed to parse\n"); + } + } + kson_destroy(kson); + return 0; +} +#endif diff --git a/web/server/h2o/libh2o/deps/klib/kson.h b/web/server/h2o/libh2o/deps/klib/kson.h new file mode 100644 index 00000000..a03eb52f --- /dev/null +++ b/web/server/h2o/libh2o/deps/klib/kson.h @@ -0,0 +1,64 @@ +#ifndef KSON_H +#define KSON_H + +#include + +#define KSON_TYPE_NO_QUOTE 1 +#define KSON_TYPE_SGL_QUOTE 2 +#define KSON_TYPE_DBL_QUOTE 3 +#define KSON_TYPE_BRACKET 4 +#define KSON_TYPE_BRACE 5 + +#define KSON_OK 0 +#define KSON_ERR_EXTRA_LEFT 1 +#define KSON_ERR_EXTRA_RIGHT 2 +#define KSON_ERR_NO_KEY 3 + +typedef struct kson_node_s { + unsigned long long type:3, n:61; + char *key; + union { + struct kson_node_s **child; + char *str; + } v; +} kson_node_t; + +typedef struct { + long n_nodes; + kson_node_t *root; +} kson_t; + +#ifdef __cplusplus +extern "C" { +#endif + + kson_t *kson_parse(const char *json); + void kson_destroy(kson_t *kson); + const kson_node_t *kson_by_path(const kson_node_t *root, int path_len, ...); + void kson_format(const kson_node_t *root); + +#ifdef __cplusplus +} +#endif + +#define kson_is_internal(p) ((p)->type == KSON_TYPE_BRACKET || (p)->type == KSON_TYPE_BRACE) + +static inline const kson_node_t *kson_by_key(const kson_node_t *p, const char *key) +{ + long i; + if (!kson_is_internal(p)) return 0; + for (i = 0; i < (long)p->n; ++i) { + const kson_node_t *q = p->v.child[i]; + if (q->key && strcmp(q->key, key) == 0) + return q; + } + return 0; +} + +static inline const kson_node_t *kson_by_index(const kson_node_t *p, long i) +{ + if (!kson_is_internal(p)) return 0; + return 0 <= i && i < (long)p->n? p->v.child[i] : 0; +} + +#endif diff --git a/web/server/h2o/libh2o/deps/klib/ksort.h b/web/server/h2o/libh2o/deps/klib/ksort.h new file mode 100644 index 00000000..4da7a13e --- /dev/null +++ b/web/server/h2o/libh2o/deps/klib/ksort.h @@ -0,0 +1,298 @@ +/* The MIT License + + Copyright (c) 2008, 2011 Attractive Chaos + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. +*/ + +/* + 2011-04-10 (0.1.6): + + * Added sample + + 2011-03 (0.1.5): + + * Added shuffle/permutation + + 2008-11-16 (0.1.4): + + * Fixed a bug in introsort() that happens in rare cases. + + 2008-11-05 (0.1.3): + + * Fixed a bug in introsort() for complex comparisons. + + * Fixed a bug in mergesort(). The previous version is not stable. + + 2008-09-15 (0.1.2): + + * Accelerated introsort. On my Mac (not on another Linux machine), + my implementation is as fast as std::sort on random input. + + * Added combsort and in introsort, switch to combsort if the + recursion is too deep. + + 2008-09-13 (0.1.1): + + * Added k-small algorithm + + 2008-09-05 (0.1.0): + + * Initial version + +*/ + +#ifndef AC_KSORT_H +#define AC_KSORT_H + +#include +#include + +typedef struct { + void *left, *right; + int depth; +} ks_isort_stack_t; + +#define KSORT_SWAP(type_t, a, b) { register type_t t=(a); (a)=(b); (b)=t; } + +#define KSORT_INIT(name, type_t, __sort_lt) \ + void ks_mergesort_##name(size_t n, type_t array[], type_t temp[]) \ + { \ + type_t *a2[2], *a, *b; \ + int curr, shift; \ + \ + a2[0] = array; \ + a2[1] = temp? temp : (type_t*)malloc(sizeof(type_t) * n); \ + for (curr = 0, shift = 0; (1ul<> 1) - 1; i != (size_t)(-1); --i) \ + ks_heapadjust_##name(i, lsize, l); \ + } \ + void ks_heapsort_##name(size_t lsize, type_t l[]) \ + { \ + size_t i; \ + for (i = lsize - 1; i > 0; --i) { \ + type_t tmp; \ + tmp = *l; *l = l[i]; l[i] = tmp; ks_heapadjust_##name(0, i, l); \ + } \ + } \ + static inline void __ks_insertsort_##name(type_t *s, type_t *t) \ + { \ + type_t *i, *j, swap_tmp; \ + for (i = s + 1; i < t; ++i) \ + for (j = i; j > s && __sort_lt(*j, *(j-1)); --j) { \ + swap_tmp = *j; *j = *(j-1); *(j-1) = swap_tmp; \ + } \ + } \ + void ks_combsort_##name(size_t n, type_t a[]) \ + { \ + const double shrink_factor = 1.2473309501039786540366528676643; \ + int do_swap; \ + size_t gap = n; \ + type_t tmp, *i, *j; \ + do { \ + if (gap > 2) { \ + gap = (size_t)(gap / shrink_factor); \ + if (gap == 9 || gap == 10) gap = 11; \ + } \ + do_swap = 0; \ + for (i = a; i < a + n - gap; ++i) { \ + j = i + gap; \ + if (__sort_lt(*j, *i)) { \ + tmp = *i; *i = *j; *j = tmp; \ + do_swap = 1; \ + } \ + } \ + } while (do_swap || gap > 2); \ + if (gap != 1) __ks_insertsort_##name(a, a + n); \ + } \ + void ks_introsort_##name(size_t n, type_t a[]) \ + { \ + int d; \ + ks_isort_stack_t *top, *stack; \ + type_t rp, swap_tmp; \ + type_t *s, *t, *i, *j, *k; \ + \ + if (n < 1) return; \ + else if (n == 2) { \ + if (__sort_lt(a[1], a[0])) { swap_tmp = a[0]; a[0] = a[1]; a[1] = swap_tmp; } \ + return; \ + } \ + for (d = 2; 1ul<>1) + 1; \ + if (__sort_lt(*k, *i)) { \ + if (__sort_lt(*k, *j)) k = j; \ + } else k = __sort_lt(*j, *i)? i : j; \ + rp = *k; \ + if (k != t) { swap_tmp = *k; *k = *t; *t = swap_tmp; } \ + for (;;) { \ + do ++i; while (__sort_lt(*i, rp)); \ + do --j; while (i <= j && __sort_lt(rp, *j)); \ + if (j <= i) break; \ + swap_tmp = *i; *i = *j; *j = swap_tmp; \ + } \ + swap_tmp = *i; *i = *t; *t = swap_tmp; \ + if (i-s > t-i) { \ + if (i-s > 16) { top->left = s; top->right = i-1; top->depth = d; ++top; } \ + s = t-i > 16? i+1 : t; \ + } else { \ + if (t-i > 16) { top->left = i+1; top->right = t; top->depth = d; ++top; } \ + t = i-s > 16? i-1 : s; \ + } \ + } else { \ + if (top == stack) { \ + free(stack); \ + __ks_insertsort_##name(a, a+n); \ + return; \ + } else { --top; s = (type_t*)top->left; t = (type_t*)top->right; d = top->depth; } \ + } \ + } \ + } \ + /* This function is adapted from: http://ndevilla.free.fr/median/ */ \ + /* 0 <= kk < n */ \ + type_t ks_ksmall_##name(size_t n, type_t arr[], size_t kk) \ + { \ + type_t *low, *high, *k, *ll, *hh, *mid; \ + low = arr; high = arr + n - 1; k = arr + kk; \ + for (;;) { \ + if (high <= low) return *k; \ + if (high == low + 1) { \ + if (__sort_lt(*high, *low)) KSORT_SWAP(type_t, *low, *high); \ + return *k; \ + } \ + mid = low + (high - low) / 2; \ + if (__sort_lt(*high, *mid)) KSORT_SWAP(type_t, *mid, *high); \ + if (__sort_lt(*high, *low)) KSORT_SWAP(type_t, *low, *high); \ + if (__sort_lt(*low, *mid)) KSORT_SWAP(type_t, *mid, *low); \ + KSORT_SWAP(type_t, *mid, *(low+1)); \ + ll = low + 1; hh = high; \ + for (;;) { \ + do ++ll; while (__sort_lt(*ll, *low)); \ + do --hh; while (__sort_lt(*low, *hh)); \ + if (hh < ll) break; \ + KSORT_SWAP(type_t, *ll, *hh); \ + } \ + KSORT_SWAP(type_t, *low, *hh); \ + if (hh <= k) low = ll; \ + if (hh >= k) high = hh - 1; \ + } \ + } \ + void ks_shuffle_##name(size_t n, type_t a[]) \ + { \ + int i, j; \ + for (i = n; i > 1; --i) { \ + type_t tmp; \ + j = (int)(drand48() * i); \ + tmp = a[j]; a[j] = a[i-1]; a[i-1] = tmp; \ + } \ + } \ + void ks_sample_##name(size_t n, size_t r, type_t a[]) /* FIXME: NOT TESTED!!! */ \ + { /* reference: http://code.activestate.com/recipes/272884/ */ \ + int i, k, pop = n; \ + for (i = (int)r, k = 0; i >= 0; --i) { \ + double z = 1., x = drand48(); \ + type_t tmp; \ + while (x < z) z -= z * i / (pop--); \ + if (k != n - pop - 1) tmp = a[k], a[k] = a[n-pop-1], a[n-pop-1] = tmp; \ + ++k; \ + } \ + } + +#define ks_mergesort(name, n, a, t) ks_mergesort_##name(n, a, t) +#define ks_introsort(name, n, a) ks_introsort_##name(n, a) +#define ks_combsort(name, n, a) ks_combsort_##name(n, a) +#define ks_heapsort(name, n, a) ks_heapsort_##name(n, a) +#define ks_heapmake(name, n, a) ks_heapmake_##name(n, a) +#define ks_heapadjust(name, i, n, a) ks_heapadjust_##name(i, n, a) +#define ks_ksmall(name, n, a, k) ks_ksmall_##name(n, a, k) +#define ks_shuffle(name, n, a) ks_shuffle_##name(n, a) + +#define ks_lt_generic(a, b) ((a) < (b)) +#define ks_lt_str(a, b) (strcmp((a), (b)) < 0) + +typedef const char *ksstr_t; + +#define KSORT_INIT_GENERIC(type_t) KSORT_INIT(type_t, type_t, ks_lt_generic) +#define KSORT_INIT_STR KSORT_INIT(str, ksstr_t, ks_lt_str) + +#endif diff --git a/web/server/h2o/libh2o/deps/klib/kstring.c b/web/server/h2o/libh2o/deps/klib/kstring.c new file mode 100644 index 00000000..f0293172 --- /dev/null +++ b/web/server/h2o/libh2o/deps/klib/kstring.c @@ -0,0 +1,229 @@ +#include +#include +#include +#include +#include +#include "kstring.h" + +int kvsprintf(kstring_t *s, const char *fmt, va_list ap) +{ + va_list args; + int l; + va_copy(args, ap); + l = vsnprintf(s->s + s->l, s->m - s->l, fmt, args); // This line does not work with glibc 2.0. See `man snprintf'. + va_end(args); + if (l + 1 > s->m - s->l) { + s->m = s->l + l + 2; + kroundup32(s->m); + s->s = (char*)realloc(s->s, s->m); + va_copy(args, ap); + l = vsnprintf(s->s + s->l, s->m - s->l, fmt, args); + va_end(args); + } + s->l += l; + return l; +} + +int ksprintf(kstring_t *s, const char *fmt, ...) +{ + va_list ap; + int l; + va_start(ap, fmt); + l = kvsprintf(s, fmt, ap); + va_end(ap); + return l; +} + +char *kstrtok(const char *str, const char *sep, ks_tokaux_t *aux) +{ + const char *p, *start; + if (sep) { // set up the table + if (str == 0 && (aux->tab[0]&1)) return 0; // no need to set up if we have finished + aux->finished = 0; + if (sep[1]) { + aux->sep = -1; + aux->tab[0] = aux->tab[1] = aux->tab[2] = aux->tab[3] = 0; + for (p = sep; *p; ++p) aux->tab[*p>>6] |= 1ull<<(*p&0x3f); + } else aux->sep = sep[0]; + } + if (aux->finished) return 0; + else if (str) aux->p = str - 1, aux->finished = 0; + if (aux->sep < 0) { + for (p = start = aux->p + 1; *p; ++p) + if (aux->tab[*p>>6]>>(*p&0x3f)&1) break; + } else { + for (p = start = aux->p + 1; *p; ++p) + if (*p == aux->sep) break; + } + aux->p = p; // end of token + if (*p == 0) aux->finished = 1; // no more tokens + return (char*)start; +} + +// s MUST BE a null terminated string; l = strlen(s) +int ksplit_core(char *s, int delimiter, int *_max, int **_offsets) +{ + int i, n, max, last_char, last_start, *offsets, l; + n = 0; max = *_max; offsets = *_offsets; + l = strlen(s); + +#define __ksplit_aux do { \ + if (_offsets) { \ + s[i] = 0; \ + if (n == max) { \ + int *tmp; \ + max = max? max<<1 : 2; \ + if ((tmp = (int*)realloc(offsets, sizeof(int) * max))) { \ + offsets = tmp; \ + } else { \ + free(offsets); \ + *_offsets = NULL; \ + return 0; \ + } \ + } \ + offsets[n++] = last_start; \ + } else ++n; \ + } while (0) + + for (i = 0, last_char = last_start = 0; i <= l; ++i) { + if (delimiter == 0) { + if (isspace(s[i]) || s[i] == 0) { + if (isgraph(last_char)) __ksplit_aux; // the end of a field + } else { + if (isspace(last_char) || last_char == 0) last_start = i; + } + } else { + if (s[i] == delimiter || s[i] == 0) { + if (last_char != 0 && last_char != delimiter) __ksplit_aux; // the end of a field + } else { + if (last_char == delimiter || last_char == 0) last_start = i; + } + } + last_char = s[i]; + } + *_max = max; *_offsets = offsets; + return n; +} + +/********************** + * Boyer-Moore search * + **********************/ + +typedef unsigned char ubyte_t; + +// reference: http://www-igm.univ-mlv.fr/~lecroq/string/node14.html +static int *ksBM_prep(const ubyte_t *pat, int m) +{ + int i, *suff, *prep, *bmGs, *bmBc; + prep = (int*)calloc(m + 256, sizeof(int)); + bmGs = prep; bmBc = prep + m; + { // preBmBc() + for (i = 0; i < 256; ++i) bmBc[i] = m; + for (i = 0; i < m - 1; ++i) bmBc[pat[i]] = m - i - 1; + } + suff = (int*)calloc(m, sizeof(int)); + { // suffixes() + int f = 0, g; + suff[m - 1] = m; + g = m - 1; + for (i = m - 2; i >= 0; --i) { + if (i > g && suff[i + m - 1 - f] < i - g) + suff[i] = suff[i + m - 1 - f]; + else { + if (i < g) g = i; + f = i; + while (g >= 0 && pat[g] == pat[g + m - 1 - f]) --g; + suff[i] = f - g; + } + } + } + { // preBmGs() + int j = 0; + for (i = 0; i < m; ++i) bmGs[i] = m; + for (i = m - 1; i >= 0; --i) + if (suff[i] == i + 1) + for (; j < m - 1 - i; ++j) + if (bmGs[j] == m) + bmGs[j] = m - 1 - i; + for (i = 0; i <= m - 2; ++i) + bmGs[m - 1 - suff[i]] = m - 1 - i; + } + free(suff); + return prep; +} + +void *kmemmem(const void *_str, int n, const void *_pat, int m, int **_prep) +{ + int i, j, *prep = 0, *bmGs, *bmBc; + const ubyte_t *str, *pat; + str = (const ubyte_t*)_str; pat = (const ubyte_t*)_pat; + prep = (_prep == 0 || *_prep == 0)? ksBM_prep(pat, m) : *_prep; + if (_prep && *_prep == 0) *_prep = prep; + bmGs = prep; bmBc = prep + m; + j = 0; + while (j <= n - m) { + for (i = m - 1; i >= 0 && pat[i] == str[i+j]; --i); + if (i >= 0) { + int max = bmBc[str[i+j]] - m + 1 + i; + if (max < bmGs[i]) max = bmGs[i]; + j += max; + } else return (void*)(str + j); + } + if (_prep == 0) free(prep); + return 0; +} + +char *kstrstr(const char *str, const char *pat, int **_prep) +{ + return (char*)kmemmem(str, strlen(str), pat, strlen(pat), _prep); +} + +char *kstrnstr(const char *str, const char *pat, int n, int **_prep) +{ + return (char*)kmemmem(str, n, pat, strlen(pat), _prep); +} + +/*********************** + * The main() function * + ***********************/ + +#ifdef KSTRING_MAIN +#include +int main() +{ + kstring_t *s; + int *fields, n, i; + ks_tokaux_t aux; + char *p; + s = (kstring_t*)calloc(1, sizeof(kstring_t)); + // test ksprintf() + ksprintf(s, " abcdefg: %d ", 100); + printf("'%s'\n", s->s); + // test ksplit() + fields = ksplit(s, 0, &n); + for (i = 0; i < n; ++i) + printf("field[%d] = '%s'\n", i, s->s + fields[i]); + // test kstrtok() + s->l = 0; + for (p = kstrtok("ab:cde:fg/hij::k", ":/", &aux); p; p = kstrtok(0, 0, &aux)) { + kputsn(p, aux.p - p, s); + kputc('\n', s); + } + printf("%s", s->s); + // free + free(s->s); free(s); free(fields); + + { + static char *str = "abcdefgcdgcagtcakcdcd"; + static char *pat = "cd"; + char *ret, *s = str; + int *prep = 0; + while ((ret = kstrstr(s, pat, &prep)) != 0) { + printf("match: %s\n", ret); + s = ret + prep[0]; + } + free(prep); + } + return 0; +} +#endif diff --git a/web/server/h2o/libh2o/deps/klib/kstring.h b/web/server/h2o/libh2o/deps/klib/kstring.h new file mode 100644 index 00000000..0e654cb8 --- /dev/null +++ b/web/server/h2o/libh2o/deps/klib/kstring.h @@ -0,0 +1,259 @@ +/* The MIT License + + Copyright (c) by Attractive Chaos + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. +*/ + +#ifndef KSTRING_H +#define KSTRING_H + +#include +#include +#include +#include +#include + +#ifndef kroundup32 +#define kroundup32(x) (--(x), (x)|=(x)>>1, (x)|=(x)>>2, (x)|=(x)>>4, (x)|=(x)>>8, (x)|=(x)>>16, ++(x)) +#endif + +#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ > 4) +#define KS_ATTR_PRINTF(fmt, arg) __attribute__((__format__ (__printf__, fmt, arg))) +#else +#define KS_ATTR_PRINTF(fmt, arg) +#endif + + +/* kstring_t is a simple non-opaque type whose fields are likely to be + * used directly by user code (but see also ks_str() and ks_len() below). + * A kstring_t object is initialised by either of + * kstring_t str = { 0, 0, NULL }; + * kstring_t str; ...; str.l = str.m = 0; str.s = NULL; + * and either ownership of the underlying buffer should be given away before + * the object disappears (i.e., the str.s pointer copied and something else + * responsible for freeing it), or the kstring_t should be destroyed with + * free(str.s); */ +#ifndef KSTRING_T +#define KSTRING_T kstring_t +typedef struct __kstring_t { + size_t l, m; + char *s; +} kstring_t; +#endif + +typedef struct { + uint64_t tab[4]; + int sep, finished; + const char *p; // end of the current token +} ks_tokaux_t; + +#ifdef __cplusplus +extern "C" { +#endif + + int kvsprintf(kstring_t *s, const char *fmt, va_list ap) KS_ATTR_PRINTF(2,0); + int ksprintf(kstring_t *s, const char *fmt, ...) KS_ATTR_PRINTF(2,3); + int ksplit_core(char *s, int delimiter, int *_max, int **_offsets); + char *kstrstr(const char *str, const char *pat, int **_prep); + char *kstrnstr(const char *str, const char *pat, int n, int **_prep); + void *kmemmem(const void *_str, int n, const void *_pat, int m, int **_prep); + + /* kstrtok() is similar to strtok_r() except that str is not + * modified and both str and sep can be NULL. For efficiency, it is + * actually recommended to set both to NULL in the subsequent calls + * if sep is not changed. */ + char *kstrtok(const char *str, const char *sep, ks_tokaux_t *aux); + +#ifdef __cplusplus +} +#endif + +static inline int ks_resize(kstring_t *s, size_t size) +{ + if (s->m < size) { + char *tmp; + s->m = size; + kroundup32(s->m); + if ((tmp = (char*)realloc(s->s, s->m))) + s->s = tmp; + else + return -1; + } + return 0; +} + +static inline char *ks_str(kstring_t *s) +{ + return s->s; +} + +static inline size_t ks_len(kstring_t *s) +{ + return s->l; +} + +static inline int kputsn(const char *p, int l, kstring_t *s) +{ + if (s->l + l + 1 >= s->m) { + char *tmp; + s->m = s->l + l + 2; + kroundup32(s->m); + if ((tmp = (char*)realloc(s->s, s->m))) + s->s = tmp; + else + return EOF; + } + memcpy(s->s + s->l, p, l); + s->l += l; + s->s[s->l] = 0; + return l; +} + +static inline int kputs(const char *p, kstring_t *s) +{ + return kputsn(p, strlen(p), s); +} + +static inline int kputc(int c, kstring_t *s) +{ + if (s->l + 1 >= s->m) { + char *tmp; + s->m = s->l + 2; + kroundup32(s->m); + if ((tmp = (char*)realloc(s->s, s->m))) + s->s = tmp; + else + return EOF; + } + s->s[s->l++] = c; + s->s[s->l] = 0; + return c; +} + +static inline int kputc_(int c, kstring_t *s) +{ + if (s->l + 1 > s->m) { + char *tmp; + s->m = s->l + 1; + kroundup32(s->m); + if ((tmp = (char*)realloc(s->s, s->m))) + s->s = tmp; + else + return EOF; + } + s->s[s->l++] = c; + return 1; +} + +static inline int kputsn_(const void *p, int l, kstring_t *s) +{ + if (s->l + l > s->m) { + char *tmp; + s->m = s->l + l; + kroundup32(s->m); + if ((tmp = (char*)realloc(s->s, s->m))) + s->s = tmp; + else + return EOF; + } + memcpy(s->s + s->l, p, l); + s->l += l; + return l; +} + +static inline int kputw(int c, kstring_t *s) +{ + char buf[16]; + int i, l = 0; + unsigned int x = c; + if (c < 0) x = -x; + do { buf[l++] = x%10 + '0'; x /= 10; } while (x > 0); + if (c < 0) buf[l++] = '-'; + if (s->l + l + 1 >= s->m) { + char *tmp; + s->m = s->l + l + 2; + kroundup32(s->m); + if ((tmp = (char*)realloc(s->s, s->m))) + s->s = tmp; + else + return EOF; + } + for (i = l - 1; i >= 0; --i) s->s[s->l++] = buf[i]; + s->s[s->l] = 0; + return 0; +} + +static inline int kputuw(unsigned c, kstring_t *s) +{ + char buf[16]; + int l, i; + unsigned x; + if (c == 0) return kputc('0', s); + for (l = 0, x = c; x > 0; x /= 10) buf[l++] = x%10 + '0'; + if (s->l + l + 1 >= s->m) { + char *tmp; + s->m = s->l + l + 2; + kroundup32(s->m); + if ((tmp = (char*)realloc(s->s, s->m))) + s->s = tmp; + else + return EOF; + } + for (i = l - 1; i >= 0; --i) s->s[s->l++] = buf[i]; + s->s[s->l] = 0; + return 0; +} + +static inline int kputl(long c, kstring_t *s) +{ + char buf[32]; + int i, l = 0; + unsigned long x = c; + if (c < 0) x = -x; + do { buf[l++] = x%10 + '0'; x /= 10; } while (x > 0); + if (c < 0) buf[l++] = '-'; + if (s->l + l + 1 >= s->m) { + char *tmp; + s->m = s->l + l + 2; + kroundup32(s->m); + if ((tmp = (char*)realloc(s->s, s->m))) + s->s = tmp; + else + return EOF; + } + for (i = l - 1; i >= 0; --i) s->s[s->l++] = buf[i]; + s->s[s->l] = 0; + return 0; +} + +/* + * Returns 's' split by delimiter, with *n being the number of components; + * NULL on failue. + */ +static inline int *ksplit(kstring_t *s, int delimiter, int *n) +{ + int max = 0, *offsets = 0; + *n = ksplit_core(s->s, delimiter, &max, &offsets); + return offsets; +} + +#endif diff --git a/web/server/h2o/libh2o/deps/klib/ksw.c b/web/server/h2o/libh2o/deps/klib/ksw.c new file mode 100644 index 00000000..742fec90 --- /dev/null +++ b/web/server/h2o/libh2o/deps/klib/ksw.c @@ -0,0 +1,633 @@ +/* The MIT License + + Copyright (c) 2011 by Attractive Chaos + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. +*/ + +#include +#include +#include +#include "ksw.h" + +#ifdef __GNUC__ +#define LIKELY(x) __builtin_expect((x),1) +#define UNLIKELY(x) __builtin_expect((x),0) +#else +#define LIKELY(x) (x) +#define UNLIKELY(x) (x) +#endif + +const kswr_t g_defr = { 0, -1, -1, -1, -1, -1, -1 }; + +struct _kswq_t { + int qlen, slen; + uint8_t shift, mdiff, max, size; + __m128i *qp, *H0, *H1, *E, *Hmax; +}; + +/** + * Initialize the query data structure + * + * @param size Number of bytes used to store a score; valid valures are 1 or 2 + * @param qlen Length of the query sequence + * @param query Query sequence + * @param m Size of the alphabet + * @param mat Scoring matrix in a one-dimension array + * + * @return Query data structure + */ +kswq_t *ksw_qinit(int size, int qlen, const uint8_t *query, int m, const int8_t *mat) +{ + kswq_t *q; + int slen, a, tmp, p; + + size = size > 1? 2 : 1; + p = 8 * (3 - size); // # values per __m128i + slen = (qlen + p - 1) / p; // segmented length + q = (kswq_t*)malloc(sizeof(kswq_t) + 256 + 16 * slen * (m + 4)); // a single block of memory + q->qp = (__m128i*)(((size_t)q + sizeof(kswq_t) + 15) >> 4 << 4); // align memory + q->H0 = q->qp + slen * m; + q->H1 = q->H0 + slen; + q->E = q->H1 + slen; + q->Hmax = q->E + slen; + q->slen = slen; q->qlen = qlen; q->size = size; + // compute shift + tmp = m * m; + for (a = 0, q->shift = 127, q->mdiff = 0; a < tmp; ++a) { // find the minimum and maximum score + if (mat[a] < (int8_t)q->shift) q->shift = mat[a]; + if (mat[a] > (int8_t)q->mdiff) q->mdiff = mat[a]; + } + q->max = q->mdiff; + q->shift = 256 - q->shift; // NB: q->shift is uint8_t + q->mdiff += q->shift; // this is the difference between the min and max scores + // An example: p=8, qlen=19, slen=3 and segmentation: + // {{0,3,6,9,12,15,18,-1},{1,4,7,10,13,16,-1,-1},{2,5,8,11,14,17,-1,-1}} + if (size == 1) { + int8_t *t = (int8_t*)q->qp; + for (a = 0; a < m; ++a) { + int i, k, nlen = slen * p; + const int8_t *ma = mat + a * m; + for (i = 0; i < slen; ++i) + for (k = i; k < nlen; k += slen) // p iterations + *t++ = (k >= qlen? 0 : ma[query[k]]) + q->shift; + } + } else { + int16_t *t = (int16_t*)q->qp; + for (a = 0; a < m; ++a) { + int i, k, nlen = slen * p; + const int8_t *ma = mat + a * m; + for (i = 0; i < slen; ++i) + for (k = i; k < nlen; k += slen) // p iterations + *t++ = (k >= qlen? 0 : ma[query[k]]); + } + } + return q; +} + +kswr_t ksw_u8(kswq_t *q, int tlen, const uint8_t *target, int _gapo, int _gape, int xtra) // the first gap costs -(_o+_e) +{ + int slen, i, m_b, n_b, te = -1, gmax = 0, minsc, endsc; + uint64_t *b; + __m128i zero, gapoe, gape, shift, *H0, *H1, *E, *Hmax; + kswr_t r; + +#define __max_16(ret, xx) do { \ + (xx) = _mm_max_epu8((xx), _mm_srli_si128((xx), 8)); \ + (xx) = _mm_max_epu8((xx), _mm_srli_si128((xx), 4)); \ + (xx) = _mm_max_epu8((xx), _mm_srli_si128((xx), 2)); \ + (xx) = _mm_max_epu8((xx), _mm_srli_si128((xx), 1)); \ + (ret) = _mm_extract_epi16((xx), 0) & 0x00ff; \ + } while (0) + + // initialization + r = g_defr; + minsc = (xtra&KSW_XSUBO)? xtra&0xffff : 0x10000; + endsc = (xtra&KSW_XSTOP)? xtra&0xffff : 0x10000; + m_b = n_b = 0; b = 0; + zero = _mm_set1_epi32(0); + gapoe = _mm_set1_epi8(_gapo + _gape); + gape = _mm_set1_epi8(_gape); + shift = _mm_set1_epi8(q->shift); + H0 = q->H0; H1 = q->H1; E = q->E; Hmax = q->Hmax; + slen = q->slen; + for (i = 0; i < slen; ++i) { + _mm_store_si128(E + i, zero); + _mm_store_si128(H0 + i, zero); + _mm_store_si128(Hmax + i, zero); + } + // the core loop + for (i = 0; i < tlen; ++i) { + int j, k, cmp, imax; + __m128i e, h, f = zero, max = zero, *S = q->qp + target[i] * slen; // s is the 1st score vector + h = _mm_load_si128(H0 + slen - 1); // h={2,5,8,11,14,17,-1,-1} in the above example + h = _mm_slli_si128(h, 1); // h=H(i-1,-1); << instead of >> because x64 is little-endian + for (j = 0; LIKELY(j < slen); ++j) { + /* SW cells are computed in the following order: + * H(i,j) = max{H(i-1,j-1)+S(i,j), E(i,j), F(i,j)} + * E(i+1,j) = max{H(i,j)-q, E(i,j)-r} + * F(i,j+1) = max{H(i,j)-q, F(i,j)-r} + */ + // compute H'(i,j); note that at the beginning, h=H'(i-1,j-1) + h = _mm_adds_epu8(h, _mm_load_si128(S + j)); + h = _mm_subs_epu8(h, shift); // h=H'(i-1,j-1)+S(i,j) + e = _mm_load_si128(E + j); // e=E'(i,j) + h = _mm_max_epu8(h, e); + h = _mm_max_epu8(h, f); // h=H'(i,j) + max = _mm_max_epu8(max, h); // set max + _mm_store_si128(H1 + j, h); // save to H'(i,j) + // now compute E'(i+1,j) + h = _mm_subs_epu8(h, gapoe); // h=H'(i,j)-gapo + e = _mm_subs_epu8(e, gape); // e=E'(i,j)-gape + e = _mm_max_epu8(e, h); // e=E'(i+1,j) + _mm_store_si128(E + j, e); // save to E'(i+1,j) + // now compute F'(i,j+1) + f = _mm_subs_epu8(f, gape); + f = _mm_max_epu8(f, h); + // get H'(i-1,j) and prepare for the next j + h = _mm_load_si128(H0 + j); // h=H'(i-1,j) + } + // NB: we do not need to set E(i,j) as we disallow adjecent insertion and then deletion + for (k = 0; LIKELY(k < 16); ++k) { // this block mimics SWPS3; NB: H(i,j) updated in the lazy-F loop cannot exceed max + f = _mm_slli_si128(f, 1); + for (j = 0; LIKELY(j < slen); ++j) { + h = _mm_load_si128(H1 + j); + h = _mm_max_epu8(h, f); // h=H'(i,j) + _mm_store_si128(H1 + j, h); + h = _mm_subs_epu8(h, gapoe); + f = _mm_subs_epu8(f, gape); + cmp = _mm_movemask_epi8(_mm_cmpeq_epi8(_mm_subs_epu8(f, h), zero)); + if (UNLIKELY(cmp == 0xffff)) goto end_loop16; + } + } +end_loop16: + //int k;for (k=0;k<16;++k)printf("%d ", ((uint8_t*)&max)[k]);printf("\n"); + __max_16(imax, max); // imax is the maximum number in max + if (imax >= minsc) { // write the b array; this condition adds branching unfornately + if (n_b == 0 || (int32_t)b[n_b-1] + 1 != i) { // then append + if (n_b == m_b) { + m_b = m_b? m_b<<1 : 8; + b = (uint64_t*)realloc(b, 8 * m_b); + } + b[n_b++] = (uint64_t)imax<<32 | i; + } else if ((int)(b[n_b-1]>>32) < imax) b[n_b-1] = (uint64_t)imax<<32 | i; // modify the last + } + if (imax > gmax) { + gmax = imax; te = i; // te is the end position on the target + for (j = 0; LIKELY(j < slen); ++j) // keep the H1 vector + _mm_store_si128(Hmax + j, _mm_load_si128(H1 + j)); + if (gmax + q->shift >= 255 || gmax >= endsc) break; + } + S = H1; H1 = H0; H0 = S; // swap H0 and H1 + } + r.score = gmax + q->shift < 255? gmax : 255; + r.te = te; + if (r.score != 255) { // get a->qe, the end of query match; find the 2nd best score + int max = -1, low, high, qlen = slen * 16; + uint8_t *t = (uint8_t*)Hmax; + for (i = 0; i < qlen; ++i, ++t) + if ((int)*t > max) max = *t, r.qe = i / 16 + i % 16 * slen; + //printf("%d,%d\n", max, gmax); + if (b) { + i = (r.score + q->max - 1) / q->max; + low = te - i; high = te + i; + for (i = 0; i < n_b; ++i) { + int e = (int32_t)b[i]; + if ((e < low || e > high) && (int)(b[i]>>32) > r.score2) + r.score2 = b[i]>>32, r.te2 = e; + } + } + } + free(b); + return r; +} + +kswr_t ksw_i16(kswq_t *q, int tlen, const uint8_t *target, int _gapo, int _gape, int xtra) // the first gap costs -(_o+_e) +{ + int slen, i, m_b, n_b, te = -1, gmax = 0, minsc, endsc; + uint64_t *b; + __m128i zero, gapoe, gape, *H0, *H1, *E, *Hmax; + kswr_t r; + +#define __max_8(ret, xx) do { \ + (xx) = _mm_max_epi16((xx), _mm_srli_si128((xx), 8)); \ + (xx) = _mm_max_epi16((xx), _mm_srli_si128((xx), 4)); \ + (xx) = _mm_max_epi16((xx), _mm_srli_si128((xx), 2)); \ + (ret) = _mm_extract_epi16((xx), 0); \ + } while (0) + + // initialization + r = g_defr; + minsc = (xtra&KSW_XSUBO)? xtra&0xffff : 0x10000; + endsc = (xtra&KSW_XSTOP)? xtra&0xffff : 0x10000; + m_b = n_b = 0; b = 0; + zero = _mm_set1_epi32(0); + gapoe = _mm_set1_epi16(_gapo + _gape); + gape = _mm_set1_epi16(_gape); + H0 = q->H0; H1 = q->H1; E = q->E; Hmax = q->Hmax; + slen = q->slen; + for (i = 0; i < slen; ++i) { + _mm_store_si128(E + i, zero); + _mm_store_si128(H0 + i, zero); + _mm_store_si128(Hmax + i, zero); + } + // the core loop + for (i = 0; i < tlen; ++i) { + int j, k, imax; + __m128i e, h, f = zero, max = zero, *S = q->qp + target[i] * slen; // s is the 1st score vector + h = _mm_load_si128(H0 + slen - 1); // h={2,5,8,11,14,17,-1,-1} in the above example + h = _mm_slli_si128(h, 2); + for (j = 0; LIKELY(j < slen); ++j) { + h = _mm_adds_epi16(h, *S++); + e = _mm_load_si128(E + j); + h = _mm_max_epi16(h, e); + h = _mm_max_epi16(h, f); + max = _mm_max_epi16(max, h); + _mm_store_si128(H1 + j, h); + h = _mm_subs_epu16(h, gapoe); + e = _mm_subs_epu16(e, gape); + e = _mm_max_epi16(e, h); + _mm_store_si128(E + j, e); + f = _mm_subs_epu16(f, gape); + f = _mm_max_epi16(f, h); + h = _mm_load_si128(H0 + j); + } + for (k = 0; LIKELY(k < 16); ++k) { + f = _mm_slli_si128(f, 2); + for (j = 0; LIKELY(j < slen); ++j) { + h = _mm_load_si128(H1 + j); + h = _mm_max_epi16(h, f); + _mm_store_si128(H1 + j, h); + h = _mm_subs_epu16(h, gapoe); + f = _mm_subs_epu16(f, gape); + if(UNLIKELY(!_mm_movemask_epi8(_mm_cmpgt_epi16(f, h)))) goto end_loop8; + } + } +end_loop8: + __max_8(imax, max); + if (imax >= minsc) { + if (n_b == 0 || (int32_t)b[n_b-1] + 1 != i) { + if (n_b == m_b) { + m_b = m_b? m_b<<1 : 8; + b = (uint64_t*)realloc(b, 8 * m_b); + } + b[n_b++] = (uint64_t)imax<<32 | i; + } else if ((int)(b[n_b-1]>>32) < imax) b[n_b-1] = (uint64_t)imax<<32 | i; // modify the last + } + if (imax > gmax) { + gmax = imax; te = i; + for (j = 0; LIKELY(j < slen); ++j) + _mm_store_si128(Hmax + j, _mm_load_si128(H1 + j)); + if (gmax >= endsc) break; + } + S = H1; H1 = H0; H0 = S; + } + r.score = gmax; r.te = te; + { + int max = -1, low, high, qlen = slen * 8; + uint16_t *t = (uint16_t*)Hmax; + for (i = 0, r.qe = -1; i < qlen; ++i, ++t) + if ((int)*t > max) max = *t, r.qe = i / 8 + i % 8 * slen; + if (b) { + i = (r.score + q->max - 1) / q->max; + low = te - i; high = te + i; + for (i = 0; i < n_b; ++i) { + int e = (int32_t)b[i]; + if ((e < low || e > high) && (int)(b[i]>>32) > r.score2) + r.score2 = b[i]>>32, r.te2 = e; + } + } + } + free(b); + return r; +} + +static void revseq(int l, uint8_t *s) +{ + int i, t; + for (i = 0; i < l>>1; ++i) + t = s[i], s[i] = s[l - 1 - i], s[l - 1 - i] = t; +} + +kswr_t ksw_align(int qlen, uint8_t *query, int tlen, uint8_t *target, int m, const int8_t *mat, int gapo, int gape, int xtra, kswq_t **qry) +{ + int size; + kswq_t *q; + kswr_t r, rr; + kswr_t (*func)(kswq_t*, int, const uint8_t*, int, int, int); + + q = (qry && *qry)? *qry : ksw_qinit((xtra&KSW_XBYTE)? 1 : 2, qlen, query, m, mat); + if (qry && *qry == 0) *qry = q; + func = q->size == 2? ksw_i16 : ksw_u8; + size = q->size; + r = func(q, tlen, target, gapo, gape, xtra); + if (qry == 0) free(q); + if ((xtra&KSW_XSTART) == 0 || ((xtra&KSW_XSUBO) && r.score < (xtra&0xffff))) return r; + revseq(r.qe + 1, query); revseq(r.te + 1, target); // +1 because qe/te points to the exact end, not the position after the end + q = ksw_qinit(size, r.qe + 1, query, m, mat); + rr = func(q, tlen, target, gapo, gape, KSW_XSTOP | r.score); + revseq(r.qe + 1, query); revseq(r.te + 1, target); + free(q); + if (r.score == rr.score) + r.tb = r.te - rr.te, r.qb = r.qe - rr.qe; + return r; +} + +/******************** + *** SW extension *** + ********************/ + +typedef struct { + int32_t h, e; +} eh_t; + +int ksw_extend(int qlen, const uint8_t *query, int tlen, const uint8_t *target, int m, const int8_t *mat, int gapo, int gape, int w, int h0, int *_qle, int *_tle) +{ + eh_t *eh; // score array + int8_t *qp; // query profile + int i, j, k, gapoe = gapo + gape, beg, end, max, max_i, max_j, max_gap; + if (h0 < 0) h0 = 0; + // allocate memory + qp = malloc(qlen * m); + eh = calloc(qlen + 1, 8); + // generate the query profile + for (k = i = 0; k < m; ++k) { + const int8_t *p = &mat[k * m]; + for (j = 0; j < qlen; ++j) qp[i++] = p[query[j]]; + } + // fill the first row + eh[0].h = h0; eh[1].h = h0 > gapoe? h0 - gapoe : 0; + for (j = 2; j <= qlen && eh[j-1].h > gape; ++j) + eh[j].h = eh[j-1].h - gape; + // adjust $w if it is too large + k = m * m; + for (i = 0, max = 0; i < k; ++i) // get the max score + max = max > mat[i]? max : mat[i]; + max_gap = (int)((double)(qlen * max - gapo) / gape + 1.); + max_gap = max_gap > 1? max_gap : 1; + w = w < max_gap? w : max_gap; + // DP loop + max = h0, max_i = max_j = -1; + beg = 0, end = qlen; + for (i = 0; LIKELY(i < tlen); ++i) { + int f = 0, h1, m = 0, mj = -1; + int8_t *q = &qp[target[i] * qlen]; + // compute the first column + h1 = h0 - (gapo + gape * (i + 1)); + if (h1 < 0) h1 = 0; + // apply the band and the constraint (if provided) + if (beg < i - w) beg = i - w; + if (end > i + w + 1) end = i + w + 1; + if (end > qlen) end = qlen; + for (j = beg; LIKELY(j < end); ++j) { + // At the beginning of the loop: eh[j] = { H(i-1,j-1), E(i,j) }, f = F(i,j) and h1 = H(i,j-1) + // Similar to SSE2-SW, cells are computed in the following order: + // H(i,j) = max{H(i-1,j-1)+S(i,j), E(i,j), F(i,j)} + // E(i+1,j) = max{H(i,j)-gapo, E(i,j)} - gape + // F(i,j+1) = max{H(i,j)-gapo, F(i,j)} - gape + eh_t *p = &eh[j]; + int h = p->h, e = p->e; // get H(i-1,j-1) and E(i-1,j) + p->h = h1; // set H(i,j-1) for the next row + h += q[j]; + h = h > e? h : e; + h = h > f? h : f; + h1 = h; // save H(i,j) to h1 for the next column + mj = m > h? mj : j; + m = m > h? m : h; // m is stored at eh[mj+1] + h -= gapoe; + h = h > 0? h : 0; + e -= gape; + e = e > h? e : h; // computed E(i+1,j) + p->e = e; // save E(i+1,j) for the next row + f -= gape; + f = f > h? f : h; // computed F(i,j+1) + } + eh[end].h = h1; eh[end].e = 0; + if (m == 0) break; + if (m > max) max = m, max_i = i, max_j = mj; + // update beg and end for the next round + for (j = mj; j >= beg && eh[j].h; --j); + beg = j + 1; + for (j = mj + 2; j <= end && eh[j].h; ++j); + end = j; + //beg = 0; end = qlen; // uncomment this line for debugging + } + free(eh); free(qp); + if (_qle) *_qle = max_j + 1; + if (_tle) *_tle = max_i + 1; + return max; +} + +/******************** + * Global alignment * + ********************/ + +#define MINUS_INF -0x40000000 + +static inline uint32_t *push_cigar(int *n_cigar, int *m_cigar, uint32_t *cigar, int op, int len) +{ + if (*n_cigar == 0 || op != (cigar[(*n_cigar) - 1]&0xf)) { + if (*n_cigar == *m_cigar) { + *m_cigar = *m_cigar? (*m_cigar)<<1 : 4; + cigar = realloc(cigar, (*m_cigar) << 2); + } + cigar[(*n_cigar)++] = len<<4 | op; + } else cigar[(*n_cigar)-1] += len<<4; + return cigar; +} + +int ksw_global(int qlen, const uint8_t *query, int tlen, const uint8_t *target, int m, const int8_t *mat, int gapo, int gape, int w, int *n_cigar_, uint32_t **cigar_) +{ + eh_t *eh; + int8_t *qp; // query profile + int i, j, k, gapoe = gapo + gape, score, n_col; + uint8_t *z; // backtrack matrix; in each cell: f<<4|e<<2|h; in principle, we can halve the memory, but backtrack will be a little more complex + if (n_cigar_) *n_cigar_ = 0; + // allocate memory + n_col = qlen < 2*w+1? qlen : 2*w+1; // maximum #columns of the backtrack matrix + z = malloc(n_col * tlen); + qp = malloc(qlen * m); + eh = calloc(qlen + 1, 8); + // generate the query profile + for (k = i = 0; k < m; ++k) { + const int8_t *p = &mat[k * m]; + for (j = 0; j < qlen; ++j) qp[i++] = p[query[j]]; + } + // fill the first row + eh[0].h = 0; eh[0].e = MINUS_INF; + for (j = 1; j <= qlen && j <= w; ++j) + eh[j].h = -(gapo + gape * j), eh[j].e = MINUS_INF; + for (; j <= qlen; ++j) eh[j].h = eh[j].e = MINUS_INF; // everything is -inf outside the band + // DP loop + for (i = 0; LIKELY(i < tlen); ++i) { // target sequence is in the outer loop + int32_t f = MINUS_INF, h1, beg, end; + int8_t *q = &qp[target[i] * qlen]; + uint8_t *zi = &z[i * n_col]; + beg = i > w? i - w : 0; + end = i + w + 1 < qlen? i + w + 1 : qlen; // only loop through [beg,end) of the query sequence + h1 = beg == 0? -(gapo + gape * (i + 1)) : MINUS_INF; + for (j = beg; LIKELY(j < end); ++j) { + // This loop is organized in a similar way to ksw_extend() and ksw_sse2(), except: + // 1) not checking h>0; 2) recording direction for backtracking + eh_t *p = &eh[j]; + int32_t h = p->h, e = p->e; + uint8_t d; // direction + p->h = h1; + h += q[j]; + d = h > e? 0 : 1; + h = h > e? h : e; + d = h > f? d : 2; + h = h > f? h : f; + h1 = h; + h -= gapoe; + e -= gape; + d |= e > h? 1<<2 : 0; + e = e > h? e : h; + p->e = e; + f -= gape; + d |= f > h? 2<<4 : 0; // if we want to halve the memory, use one bit only, instead of two + f = f > h? f : h; + zi[j - beg] = d; // z[i,j] keeps h for the current cell and e/f for the next cell + } + eh[end].h = h1; eh[end].e = MINUS_INF; + } + score = eh[qlen].h; + if (n_cigar_ && cigar_) { // backtrack + int n_cigar = 0, m_cigar = 0, which = 0; + uint32_t *cigar = 0, tmp; + i = tlen - 1; k = (i + w + 1 < qlen? i + w + 1 : qlen) - 1; // (i,k) points to the last cell + while (i >= 0 && k >= 0) { + which = z[i * n_col + (k - (i > w? i - w : 0))] >> (which<<1) & 3; + if (which == 0) cigar = push_cigar(&n_cigar, &m_cigar, cigar, 0, 1), --i, --k; + else if (which == 1) cigar = push_cigar(&n_cigar, &m_cigar, cigar, 2, 1), --i; + else cigar = push_cigar(&n_cigar, &m_cigar, cigar, 1, 1), --k; + } + if (i >= 0) cigar = push_cigar(&n_cigar, &m_cigar, cigar, 2, i + 1); + if (k >= 0) cigar = push_cigar(&n_cigar, &m_cigar, cigar, 1, k + 1); + for (i = 0; i < n_cigar>>1; ++i) // reverse CIGAR + tmp = cigar[i], cigar[i] = cigar[n_cigar-1-i], cigar[n_cigar-1-i] = tmp; + *n_cigar_ = n_cigar, *cigar_ = cigar; + } + free(eh); free(qp); free(z); + return score; +} + +/******************************************* + * Main function (not compiled by default) * + *******************************************/ + +#ifdef _KSW_MAIN + +#include +#include +#include +#include "kseq.h" +KSEQ_INIT(gzFile, gzread) + +unsigned char seq_nt4_table[256] = { + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 0, 4, 1, 4, 4, 4, 2, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 0, 4, 1, 4, 4, 4, 2, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4 +}; + +int main(int argc, char *argv[]) +{ + int c, sa = 1, sb = 3, i, j, k, forward_only = 0, max_rseq = 0; + int8_t mat[25]; + int gapo = 5, gape = 2, minsc = 0, xtra = KSW_XSTART; + uint8_t *rseq = 0; + gzFile fpt, fpq; + kseq_t *kst, *ksq; + + // parse command line + while ((c = getopt(argc, argv, "a:b:q:r:ft:1")) >= 0) { + switch (c) { + case 'a': sa = atoi(optarg); break; + case 'b': sb = atoi(optarg); break; + case 'q': gapo = atoi(optarg); break; + case 'r': gape = atoi(optarg); break; + case 't': minsc = atoi(optarg); break; + case 'f': forward_only = 1; break; + case '1': xtra |= KSW_XBYTE; break; + } + } + if (optind + 2 > argc) { + fprintf(stderr, "Usage: ksw [-1] [-f] [-a%d] [-b%d] [-q%d] [-r%d] [-t%d] \n", sa, sb, gapo, gape, minsc); + return 1; + } + if (minsc > 0xffff) minsc = 0xffff; + xtra |= KSW_XSUBO | minsc; + // initialize scoring matrix + for (i = k = 0; i < 4; ++i) { + for (j = 0; j < 4; ++j) + mat[k++] = i == j? sa : -sb; + mat[k++] = 0; // ambiguous base + } + for (j = 0; j < 5; ++j) mat[k++] = 0; + // open file + fpt = gzopen(argv[optind], "r"); kst = kseq_init(fpt); + fpq = gzopen(argv[optind+1], "r"); ksq = kseq_init(fpq); + // all-pair alignment + while (kseq_read(ksq) > 0) { + kswq_t *q[2] = {0, 0}; + kswr_t r; + for (i = 0; i < (int)ksq->seq.l; ++i) ksq->seq.s[i] = seq_nt4_table[(int)ksq->seq.s[i]]; + if (!forward_only) { // reverse + if ((int)ksq->seq.m > max_rseq) { + max_rseq = ksq->seq.m; + rseq = (uint8_t*)realloc(rseq, max_rseq); + } + for (i = 0, j = ksq->seq.l - 1; i < (int)ksq->seq.l; ++i, --j) + rseq[j] = ksq->seq.s[i] == 4? 4 : 3 - ksq->seq.s[i]; + } + gzrewind(fpt); kseq_rewind(kst); + while (kseq_read(kst) > 0) { + for (i = 0; i < (int)kst->seq.l; ++i) kst->seq.s[i] = seq_nt4_table[(int)kst->seq.s[i]]; + r = ksw_align(ksq->seq.l, (uint8_t*)ksq->seq.s, kst->seq.l, (uint8_t*)kst->seq.s, 5, mat, gapo, gape, xtra, &q[0]); + if (r.score >= minsc) + printf("%s\t%d\t%d\t%s\t%d\t%d\t%d\t%d\t%d\n", kst->name.s, r.tb, r.te+1, ksq->name.s, r.qb, r.qe+1, r.score, r.score2, r.te2); + if (rseq) { + r = ksw_align(ksq->seq.l, rseq, kst->seq.l, (uint8_t*)kst->seq.s, 5, mat, gapo, gape, xtra, &q[1]); + if (r.score >= minsc) + printf("%s\t%d\t%d\t%s\t%d\t%d\t%d\t%d\t%d\n", kst->name.s, r.tb, r.te+1, ksq->name.s, (int)ksq->seq.l - r.qb, (int)ksq->seq.l - 1 - r.qe, r.score, r.score2, r.te2); + } + } + free(q[0]); free(q[1]); + } + free(rseq); + kseq_destroy(kst); gzclose(fpt); + kseq_destroy(ksq); gzclose(fpq); + return 0; +} +#endif diff --git a/web/server/h2o/libh2o/deps/klib/ksw.h b/web/server/h2o/libh2o/deps/klib/ksw.h new file mode 100644 index 00000000..5162dc03 --- /dev/null +++ b/web/server/h2o/libh2o/deps/klib/ksw.h @@ -0,0 +1,72 @@ +#ifndef __AC_KSW_H +#define __AC_KSW_H + +#include + +#define KSW_XBYTE 0x10000 +#define KSW_XSTOP 0x20000 +#define KSW_XSUBO 0x40000 +#define KSW_XSTART 0x80000 + +struct _kswq_t; +typedef struct _kswq_t kswq_t; + +typedef struct { + int score; // best score + int te, qe; // target end and query end + int score2, te2; // second best score and ending position on the target + int tb, qb; // target start and query start +} kswr_t; + +#ifdef __cplusplus +extern "C" { +#endif + + /** + * Aligning two sequences + * + * @param qlen length of the query sequence (typically +#include +#include + +/************ + * kt_for() * + ************/ + +struct kt_for_t; + +typedef struct { + struct kt_for_t *t; + long i; +} ktf_worker_t; + +typedef struct kt_for_t { + int n_threads; + long n; + ktf_worker_t *w; + void (*func)(void*,long,int); + void *data; +} kt_for_t; + +static inline long steal_work(kt_for_t *t) +{ + int i, min_i = -1; + long k, min = LONG_MAX; + for (i = 0; i < t->n_threads; ++i) + if (min > t->w[i].i) min = t->w[i].i, min_i = i; + k = __sync_fetch_and_add(&t->w[min_i].i, t->n_threads); + return k >= t->n? -1 : k; +} + +static void *ktf_worker(void *data) +{ + ktf_worker_t *w = (ktf_worker_t*)data; + long i; + for (;;) { + i = __sync_fetch_and_add(&w->i, w->t->n_threads); + if (i >= w->t->n) break; + w->t->func(w->t->data, i, w - w->t->w); + } + while ((i = steal_work(w->t)) >= 0) + w->t->func(w->t->data, i, w - w->t->w); + pthread_exit(0); +} + +void kt_for(int n_threads, void (*func)(void*,long,int), void *data, long n) +{ + int i; + kt_for_t t; + pthread_t *tid; + t.func = func, t.data = data, t.n_threads = n_threads, t.n = n; + t.w = (ktf_worker_t*)alloca(n_threads * sizeof(ktf_worker_t)); + tid = (pthread_t*)alloca(n_threads * sizeof(pthread_t)); + for (i = 0; i < n_threads; ++i) + t.w[i].t = &t, t.w[i].i = i; + for (i = 0; i < n_threads; ++i) pthread_create(&tid[i], 0, ktf_worker, &t.w[i]); + for (i = 0; i < n_threads; ++i) pthread_join(tid[i], 0); +} + +/***************** + * kt_pipeline() * + *****************/ + +struct ktp_t; + +typedef struct { + struct ktp_t *pl; + int step, running; + void *data; +} ktp_worker_t; + +typedef struct ktp_t { + void *shared; + void *(*func)(void*, int, void*); + int n_workers, n_steps; + ktp_worker_t *workers; + pthread_mutex_t mutex; + pthread_cond_t cv; +} ktp_t; + +static void *ktp_worker(void *data) +{ + ktp_worker_t *w = (ktp_worker_t*)data; + ktp_t *p = w->pl; + while (w->step < p->n_steps) { + // test whether we can kick off the job with this worker + pthread_mutex_lock(&p->mutex); + for (;;) { + int i; + // test whether another worker is doing the same step + for (i = 0; i < p->n_workers; ++i) { + if (w == &p->workers[i]) continue; // ignore itself + if (p->workers[i].running && p->workers[i].step == w->step) + break; + } + if (i == p->n_workers) break; // no other workers doing w->step; then this worker will + pthread_cond_wait(&p->cv, &p->mutex); + } + w->running = 1; + pthread_mutex_unlock(&p->mutex); + + // working on w->step + w->data = p->func(p->shared, w->step, w->step? w->data : 0); // for the first step, input is NULL + + // update step and let other workers know + pthread_mutex_lock(&p->mutex); + w->step = w->step == p->n_steps - 1 || w->data? (w->step + 1) % p->n_steps : p->n_steps; + w->running = 0; + pthread_cond_broadcast(&p->cv); + pthread_mutex_unlock(&p->mutex); + } + pthread_exit(0); +} + +void kt_pipeline(int n_threads, void *(*func)(void*, int, void*), void *shared_data, int n_steps) +{ + ktp_t aux; + pthread_t *tid; + int i; + + if (n_threads < 1) n_threads = 1; + aux.n_workers = n_threads; + aux.n_steps = n_steps; + aux.func = func; + aux.shared = shared_data; + pthread_mutex_init(&aux.mutex, 0); + pthread_cond_init(&aux.cv, 0); + + aux.workers = alloca(n_threads * sizeof(ktp_worker_t)); + for (i = 0; i < n_threads; ++i) { + ktp_worker_t *w = &aux.workers[i]; + w->step = w->running = 0; w->pl = &aux; w->data = 0; + } + + tid = alloca(n_threads * sizeof(pthread_t)); + for (i = 0; i < n_threads; ++i) pthread_create(&tid[i], 0, ktp_worker, &aux.workers[i]); + for (i = 0; i < n_threads; ++i) pthread_join(tid[i], 0); + + pthread_mutex_destroy(&aux.mutex); + pthread_cond_destroy(&aux.cv); +} diff --git a/web/server/h2o/libh2o/deps/klib/kurl.c b/web/server/h2o/libh2o/deps/klib/kurl.c new file mode 100644 index 00000000..3bf92901 --- /dev/null +++ b/web/server/h2o/libh2o/deps/klib/kurl.c @@ -0,0 +1,583 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "kurl.h" + +/********************** + *** Core kurl APIs *** + **********************/ + +#define KU_DEF_BUFLEN 0x8000 +#define KU_MAX_SKIP (KU_DEF_BUFLEN<<1) // if seek step is smaller than this, skip + +#define kurl_isfile(u) ((u)->fd >= 0) + +#ifndef kroundup32 +#define kroundup32(x) (--(x), (x)|=(x)>>1, (x)|=(x)>>2, (x)|=(x)>>4, (x)|=(x)>>8, (x)|=(x)>>16, ++(x)) +#endif + +struct kurl_t { + CURLM *multi; // cURL multi handler + CURL *curl; // cURL easy handle + uint8_t *buf; // buffer + off_t off0; // offset of the first byte in the buffer; the actual file offset equals off0 + p_buf + int fd; // file descriptor for a normal file; <0 for a remote file + int m_buf; // max buffer size; for a remote file, CURL_MAX_WRITE_SIZE*2 is recommended + int l_buf; // length of the buffer; l_buf == 0 iff the input read entirely; l_buf <= m_buf + int p_buf; // file position in the buffer; p_buf <= l_buf + int done_reading; // true if we can read nothing from the file; buffer may not be empty even if done_reading is set + int err; // error code + struct curl_slist *hdr; +}; + +typedef struct { + char *url, *date, *auth; +} s3aux_t; + +int kurl_init(void) // required for SSL and win32 socket; NOT thread safe +{ + return curl_global_init(CURL_GLOBAL_DEFAULT); +} + +void kurl_destroy(void) +{ + curl_global_cleanup(); +} + +static int prepare(kurl_t *ku, int do_seek) +{ + if (kurl_isfile(ku)) { + if (do_seek && lseek(ku->fd, ku->off0, SEEK_SET) != ku->off0) + return -1; + } else { // FIXME: for S3, we need to re-authorize + int rc; + rc = curl_multi_remove_handle(ku->multi, ku->curl); + rc = curl_easy_setopt(ku->curl, CURLOPT_RESUME_FROM, ku->off0); + rc = curl_multi_add_handle(ku->multi, ku->curl); + } + ku->p_buf = ku->l_buf = 0; // empty the buffer + return 0; +} + +static size_t write_cb(char *ptr, size_t size, size_t nmemb, void *data) // callback required by cURL +{ + kurl_t *ku = (kurl_t*)data; + ssize_t nbytes = size * nmemb; + if (nbytes + ku->l_buf > ku->m_buf) + return CURL_WRITEFUNC_PAUSE; + memcpy(ku->buf + ku->l_buf, ptr, nbytes); + ku->l_buf += nbytes; + return nbytes; +} + +static int fill_buffer(kurl_t *ku) // fill the buffer +{ + assert(ku->p_buf == ku->l_buf); // buffer is always used up when fill_buffer() is called; otherwise a bug + ku->off0 += ku->l_buf; + ku->p_buf = ku->l_buf = 0; + if (ku->done_reading) return 0; + if (kurl_isfile(ku)) { + // The following block is equivalent to "ku->l_buf = read(ku->fd, ku->buf, ku->m_buf)" on Mac. + // On Linux, the man page does not specify whether read() guarantees to read ku->m_buf bytes + // even if ->fd references a normal file with sufficient remaining bytes. + while (ku->l_buf < ku->m_buf) { + int l; + l = read(ku->fd, ku->buf + ku->l_buf, ku->m_buf - ku->l_buf); + if (l == 0) break; + ku->l_buf += l; + } + if (ku->l_buf < ku->m_buf) ku->done_reading = 1; + } else { + int n_running, rc; + fd_set fdr, fdw, fde; + do { + int maxfd = -1; + long curl_to = -1; + struct timeval to; + // the following is adaped from docs/examples/fopen.c + to.tv_sec = 10, to.tv_usec = 0; // 10 seconds + curl_multi_timeout(ku->multi, &curl_to); + if (curl_to >= 0) { + to.tv_sec = curl_to / 1000; + if (to.tv_sec > 1) to.tv_sec = 1; + else to.tv_usec = (curl_to % 1000) * 1000; + } + FD_ZERO(&fdr); FD_ZERO(&fdw); FD_ZERO(&fde); + curl_multi_fdset(ku->multi, &fdr, &fdw, &fde, &maxfd); // FIXME: check return code + if (maxfd >= 0 && (rc = select(maxfd+1, &fdr, &fdw, &fde, &to)) < 0) break; + if (maxfd < 0) { // check curl_multi_fdset.3 about why we wait for 100ms here + struct timespec req, rem; + req.tv_sec = 0; req.tv_nsec = 100000000; // this is 100ms + nanosleep(&req, &rem); + } + curl_easy_pause(ku->curl, CURLPAUSE_CONT); + rc = curl_multi_perform(ku->multi, &n_running); // FIXME: check return code + } while (n_running && ku->l_buf < ku->m_buf - CURL_MAX_WRITE_SIZE); + if (ku->l_buf < ku->m_buf - CURL_MAX_WRITE_SIZE) ku->done_reading = 1; + } + return ku->l_buf; +} + +int kurl_close(kurl_t *ku) +{ + if (ku == 0) return 0; + if (ku->fd < 0) { + curl_multi_remove_handle(ku->multi, ku->curl); + curl_easy_cleanup(ku->curl); + curl_multi_cleanup(ku->multi); + if (ku->hdr) curl_slist_free_all(ku->hdr); + } else close(ku->fd); + free(ku->buf); + free(ku); + return 0; +} + +kurl_t *kurl_open(const char *url, kurl_opt_t *opt) +{ + extern s3aux_t s3_parse(const char *url, const char *_id, const char *_secret, const char *fn); + const char *p, *q; + kurl_t *ku; + int fd = -1, is_file = 1, failed = 0; + + p = strstr(url, "://"); + if (p && *p) { + for (q = url; q != p; ++q) + if (!isalnum(*q)) break; + if (q == p) is_file = 0; + } + if (is_file && (fd = open(url, O_RDONLY)) < 0) return 0; + + ku = (kurl_t*)calloc(1, sizeof(kurl_t)); + ku->fd = is_file? fd : -1; + if (!kurl_isfile(ku)) { + ku->multi = curl_multi_init(); + ku->curl = curl_easy_init(); + if (strstr(url, "s3://") == url) { + s3aux_t a; + a = s3_parse(url, (opt? opt->s3keyid : 0), (opt? opt->s3secretkey : 0), (opt? opt->s3key_fn : 0)); + if (a.url == 0 || a.date == 0 || a.auth == 0) { + kurl_close(ku); + return 0; + } + ku->hdr = curl_slist_append(ku->hdr, a.date); + ku->hdr = curl_slist_append(ku->hdr, a.auth); + curl_easy_setopt(ku->curl, CURLOPT_URL, a.url); + curl_easy_setopt(ku->curl, CURLOPT_HTTPHEADER, ku->hdr); + free(a.date); free(a.auth); free(a.url); + } else curl_easy_setopt(ku->curl, CURLOPT_URL, url); + curl_easy_setopt(ku->curl, CURLOPT_WRITEDATA, ku); + curl_easy_setopt(ku->curl, CURLOPT_VERBOSE, 0L); + curl_easy_setopt(ku->curl, CURLOPT_NOSIGNAL, 1L); + curl_easy_setopt(ku->curl, CURLOPT_WRITEFUNCTION, write_cb); + curl_easy_setopt(ku->curl, CURLOPT_SSL_VERIFYPEER, 0L); + curl_easy_setopt(ku->curl, CURLOPT_SSL_VERIFYHOST, 0L); + curl_easy_setopt(ku->curl, CURLOPT_FOLLOWLOCATION, 1L); + } + ku->m_buf = KU_DEF_BUFLEN; + if (!kurl_isfile(ku) && ku->m_buf < CURL_MAX_WRITE_SIZE * 2) + ku->m_buf = CURL_MAX_WRITE_SIZE * 2; // for remote files, the buffer set to 2*CURL_MAX_WRITE_SIZE + ku->buf = (uint8_t*)calloc(ku->m_buf, 1); + if (kurl_isfile(ku)) failed = (fill_buffer(ku) <= 0); + else failed = (prepare(ku, 0) < 0 || fill_buffer(ku) <= 0); + if (failed) { + kurl_close(ku); + return 0; + } + return ku; +} + +kurl_t *kurl_dopen(int fd) +{ + kurl_t *ku; + ku = (kurl_t*)calloc(1, sizeof(kurl_t)); + ku->fd = fd; + ku->m_buf = KU_DEF_BUFLEN; + ku->buf = (uint8_t*)calloc(ku->m_buf, 1); + if (prepare(ku, 0) < 0 || fill_buffer(ku) <= 0) { + kurl_close(ku); + return 0; + } + return ku; +} + +int kurl_buflen(kurl_t *ku, int len) +{ + if (len <= 0 || len < ku->l_buf) return ku->m_buf; + if (!kurl_isfile(ku) && len < CURL_MAX_WRITE_SIZE * 2) return ku->m_buf; + ku->m_buf = len; + kroundup32(ku->m_buf); + ku->buf = (uint8_t*)realloc(ku->buf, ku->m_buf); + return ku->m_buf; +} + +ssize_t kurl_read(kurl_t *ku, void *buf, size_t nbytes) +{ + ssize_t rest = nbytes; + if (ku->l_buf == 0) return 0; // end-of-file + while (rest) { + if (ku->l_buf - ku->p_buf >= rest) { + if (buf) memcpy((uint8_t*)buf + (nbytes - rest), ku->buf + ku->p_buf, rest); + ku->p_buf += rest; + rest = 0; + } else { + int ret; + if (buf && ku->l_buf > ku->p_buf) + memcpy((uint8_t*)buf + (nbytes - rest), ku->buf + ku->p_buf, ku->l_buf - ku->p_buf); + rest -= ku->l_buf - ku->p_buf; + ku->p_buf = ku->l_buf; + ret = fill_buffer(ku); + if (ret <= 0) break; + } + } + return nbytes - rest; +} + +off_t kurl_seek(kurl_t *ku, off_t offset, int whence) // FIXME: sometimes when seek() fails, read() will fail as well. +{ + off_t new_off = -1, cur_off; + int failed = 0, seek_end = 0; + if (ku == 0) return -1; + cur_off = ku->off0 + ku->p_buf; + if (whence == SEEK_SET) new_off = offset; + else if (whence == SEEK_CUR) new_off += cur_off + offset; + else if (whence == SEEK_END && kurl_isfile(ku)) new_off = lseek(ku->fd, offset, SEEK_END), seek_end = 1; + else { // not supported whence + ku->err = KURL_INV_WHENCE; + return -1; + } + if (new_off < 0) { // negtive absolute offset + ku->err = KURL_SEEK_OUT; + return -1; + } + if (!seek_end && new_off >= cur_off && new_off - cur_off + ku->p_buf < ku->l_buf) { + ku->p_buf += new_off - cur_off; + return ku->off0 + ku->p_buf; + } + if (seek_end || new_off < cur_off || new_off - cur_off > KU_MAX_SKIP) { // if jump is large, do actual seek + ku->off0 = new_off; + ku->done_reading = 0; + if (prepare(ku, 1) < 0 || fill_buffer(ku) <= 0) failed = 1; + } else { // if jump is small, read through + off_t r; + r = kurl_read(ku, 0, new_off - cur_off); + if (r + cur_off != new_off) failed = 1; // out of range + } + if (failed) ku->err = KURL_SEEK_OUT, ku->l_buf = ku->p_buf = 0, new_off = -1; + return new_off; +} + +off_t kurl_tell(const kurl_t *ku) +{ + if (ku == 0) return -1; + return ku->off0 + ku->p_buf; +} + +int kurl_eof(const kurl_t *ku) +{ + if (ku == 0) return 1; + return (ku->l_buf == 0); // unless file end, buffer should never be empty +} + +int kurl_fileno(const kurl_t *ku) +{ + if (ku == 0) return -1; + return ku->fd; +} + +int kurl_error(const kurl_t *ku) +{ + if (ku == 0) return KURL_NULL; + return ku->err; +} + +/***************** + *** HMAC-SHA1 *** + *****************/ + +/* This code is public-domain - it is based on libcrypt placed in the public domain by Wei Dai and other contributors. */ + +#define HASH_LENGTH 20 +#define BLOCK_LENGTH 64 + +typedef struct sha1nfo { + union { uint8_t b[BLOCK_LENGTH]; uint32_t w[BLOCK_LENGTH/4]; } buf; + uint8_t bufOffset; + union { uint8_t b[HASH_LENGTH]; uint32_t w[HASH_LENGTH/4]; } state; + uint32_t byteCount; + uint8_t keyBuffer[BLOCK_LENGTH]; + uint8_t innerHash[HASH_LENGTH]; +} sha1nfo; + +void sha1_init(sha1nfo *s) +{ + const uint8_t table[] = { 0x01,0x23,0x45,0x67, 0x89,0xab,0xcd,0xef, 0xfe,0xdc,0xba,0x98, 0x76,0x54,0x32,0x10, 0xf0,0xe1,0xd2,0xc3 }; + memcpy(s->state.b, table, HASH_LENGTH); + s->byteCount = 0; + s->bufOffset = 0; +} + +#define rol32(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits)))) + +static void sha1_hashBlock(sha1nfo *s) +{ + uint32_t i, t, a = s->state.w[0], b = s->state.w[1], c = s->state.w[2], d = s->state.w[3], e = s->state.w[4]; + for (i = 0; i < 80; i++) { + if (i >= 16) { + t = s->buf.w[(i+13)&15] ^ s->buf.w[(i+8)&15] ^ s->buf.w[(i+2)&15] ^ s->buf.w[i&15]; + s->buf.w[i&15] = rol32(t, 1); + } + if (i < 20) t = 0x5a827999 + (d ^ (b & (c ^ d))); + else if (i < 40) t = 0x6ed9eba1 + (b ^ c ^ d); + else if (i < 60) t = 0x8f1bbcdc + ((b & c) | (d & (b | c))); + else t = 0xca62c1d6 + (b ^ c ^ d); + t += rol32(a, 5) + e + s->buf.w[i&15]; + e = d; d = c; c = rol32(b, 30); b = a; a = t; + } + s->state.w[0] += a; s->state.w[1] += b; s->state.w[2] += c; s->state.w[3] += d; s->state.w[4] += e; +} + +static inline void sha1_add(sha1nfo *s, uint8_t data) +{ + s->buf.b[s->bufOffset ^ 3] = data; + if (++s->bufOffset == BLOCK_LENGTH) { + sha1_hashBlock(s); + s->bufOffset = 0; + } +} + +void sha1_write1(sha1nfo *s, uint8_t data) +{ + ++s->byteCount; + sha1_add(s, data); +} + +void sha1_write(sha1nfo *s, const char *data, size_t len) +{ + while (len--) sha1_write1(s, (uint8_t)*data++); +} + +const uint8_t *sha1_final(sha1nfo *s) +{ + int i; + sha1_add(s, 0x80); + while (s->bufOffset != 56) sha1_add(s, 0); + sha1_add(s, 0); + sha1_add(s, 0); + sha1_add(s, 0); + sha1_add(s, s->byteCount >> 29); + sha1_add(s, s->byteCount >> 21); + sha1_add(s, s->byteCount >> 13); + sha1_add(s, s->byteCount >> 5); + sha1_add(s, s->byteCount << 3); + for (i = 0; i < 5; ++i) { + uint32_t a = s->state.w[i]; + s->state.w[i] = a<<24 | (a<<8&0x00ff0000) | (a>>8&0x0000ff00) | a>>24; + } + return s->state.b; +} + +#define HMAC_IPAD 0x36 +#define HMAC_OPAD 0x5c + +void sha1_init_hmac(sha1nfo *s, const uint8_t* key, int l_key) +{ + uint8_t i; + memset(s->keyBuffer, 0, BLOCK_LENGTH); + if (l_key > BLOCK_LENGTH) { + sha1_init(s); + while (l_key--) sha1_write1(s, *key++); + memcpy(s->keyBuffer, sha1_final(s), HASH_LENGTH); + } else memcpy(s->keyBuffer, key, l_key); + sha1_init(s); + for (i = 0; i < BLOCK_LENGTH; ++i) + sha1_write1(s, s->keyBuffer[i] ^ HMAC_IPAD); +} + +const uint8_t *sha1_final_hmac(sha1nfo *s) +{ + uint8_t i; + memcpy(s->innerHash, sha1_final(s), HASH_LENGTH); + sha1_init(s); + for (i = 0; i < BLOCK_LENGTH; ++i) sha1_write1(s, s->keyBuffer[i] ^ HMAC_OPAD); + for (i = 0; i < HASH_LENGTH; ++i) sha1_write1(s, s->innerHash[i]); + return sha1_final(s); +} + +/******************* + *** S3 protocol *** + *******************/ + +#include +#include + +static void s3_sign(const char *key, const char *data, char out[29]) +{ + const char *b64tab = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + const uint8_t *digest; + int i, j, rest; + sha1nfo s; + sha1_init_hmac(&s, (uint8_t*)key, strlen(key)); + sha1_write(&s, data, strlen(data)); + digest = sha1_final_hmac(&s); + for (j = i = 0, rest = 8; i < 20; ++j) { // base64 encoding + if (rest <= 6) { + int next = i < 19? digest[i+1] : 0; + out[j] = b64tab[(int)(digest[i] << (6-rest) & 0x3f) | next >> (rest+2)], ++i, rest += 2; + } else out[j] = b64tab[(int)digest[i] >> (rest-6) & 0x3f], rest -= 6; + } + out[j++] = '='; out[j] = 0; // SHA1 digest always has 160 bits, or 20 bytes. We need one '=' at the end. +} + +static char *s3_read_awssecret(const char *fn) +{ + char *p, *secret, buf[128], *path; + FILE *fp; + int l; + if (fn == 0) { + char *home; + home = getenv("HOME"); + if (home == 0) return 0; + l = strlen(home) + 12; + path = (char*)malloc(strlen(home) + 12); + strcat(strcpy(path, home), "/.awssecret"); + } else path = (char*)fn; + fp = fopen(path, "r"); + if (path != fn) free(path); + if (fp == 0) return 0; + l = fread(buf, 1, 127, fp); + fclose(fp); + buf[l] = 0; + for (p = buf; *p != 0 && *p != '\n'; ++p); + if (*p == 0) return 0; + *p = 0; secret = p + 1; + for (++p; *p != 0 && *p != '\n'; ++p); + *p = 0; + l = p - buf + 1; + p = (char*)malloc(l); + memcpy(p, buf, l); + return p; +} + +typedef struct { int l, m; char *s; } kstring_t; + +static inline int kputsn(const char *p, int l, kstring_t *s) +{ + if (s->l + l + 1 >= s->m) { + s->m = s->l + l + 2; + kroundup32(s->m); + s->s = (char*)realloc(s->s, s->m); + } + memcpy(s->s + s->l, p, l); + s->l += l; + s->s[s->l] = 0; + return l; +} + +s3aux_t s3_parse(const char *url, const char *_id, const char *_secret, const char *fn_secret) +{ + const char *id, *secret, *bucket, *obj; + char *id_secret = 0, date[64], sig[29]; + time_t t; + struct tm tmt; + s3aux_t a = {0,0}; + kstring_t str = {0,0,0}; + // parse URL + if (strstr(url, "s3://") != url) return a; + bucket = url + 5; + for (obj = bucket; *obj && *obj != '/'; ++obj); + if (*obj == 0) return a; // no object + // acquire AWS credential and time + if (_id == 0 || _secret == 0) { + id_secret = s3_read_awssecret(fn_secret); + if (id_secret == 0) return a; // fail to read the AWS credential + id = id_secret; + secret = id_secret + strlen(id) + 1; + } else id = _id, secret = _secret; + // compose URL for curl + kputsn("https://", 8, &str); + kputsn(bucket, obj - bucket, &str); + kputsn(".s3.amazonaws.com", 17, &str); + kputsn(obj, strlen(obj), &str); + a.url = str.s; + // compose the Date line + str.l = str.m = 0; str.s = 0; + t = time(0); + strftime(date, 64, "%a, %d %b %Y %H:%M:%S +0000", gmtime_r(&t, &tmt)); + kputsn("Date: ", 6, &str); + kputsn(date, strlen(date), &str); + a.date = str.s; + // compose the string to sign and sign it + str.l = str.m = 0; str.s = 0; + kputsn("GET\n\n\n", 6, &str); + kputsn(date, strlen(date), &str); + kputsn("\n", 1, &str); + kputsn(bucket-1, strlen(bucket-1), &str); + s3_sign(secret, str.s, sig); + // compose the Authorization line + str.l = 0; + kputsn("Authorization: AWS ", 19, &str); + kputsn(id, strlen(id), &str); + kputsn(":", 1, &str); + kputsn(sig, strlen(sig), &str); + a.auth = str.s; +// printf("curl -H '%s' -H '%s' %s\n", a.date, a.auth, a.url); + return a; +} + +/********************* + *** Main function *** + *********************/ + +#ifdef KURL_MAIN +int main(int argc, char *argv[]) +{ + kurl_t *f; + int c, l, l_buf = 0x10000; + off_t start = 0, rest = -1; + uint8_t *buf; + char *p; + kurl_opt_t opt; + + memset(&opt, 0, sizeof(kurl_opt_t)); + while ((c = getopt(argc, argv, "c:l:a:")) >= 0) { + if (c == 'c') start = strtol(optarg, &p, 0); + else if (c == 'l') rest = strtol(optarg, &p, 0); + else if (c == 'a') opt.s3key_fn = optarg; + } + if (optind == argc) { + fprintf(stderr, "Usage: kurl [-c start] [-l length] \n"); + return 1; + } + kurl_init(); + f = kurl_open(argv[optind], &opt); + if (f == 0) { + fprintf(stderr, "ERROR: fail to open URL\n"); + return 2; + } + if (start > 0) { + if (kurl_seek(f, start, SEEK_SET) < 0) { + kurl_close(f); + fprintf(stderr, "ERROR: fail to seek\n"); + return 3; + } + } + buf = (uint8_t*)calloc(l_buf, 1); + while (rest != 0) { + int to_read = rest > 0 && rest < l_buf? rest : l_buf; + l = kurl_read(f, buf, to_read); + if (l == 0) break; + fwrite(buf, 1, l, stdout); + rest -= l; + } + free(buf); + kurl_close(f); + kurl_destroy(); + return 0; +} +#endif diff --git a/web/server/h2o/libh2o/deps/klib/kurl.h b/web/server/h2o/libh2o/deps/klib/kurl.h new file mode 100644 index 00000000..f07f6411 --- /dev/null +++ b/web/server/h2o/libh2o/deps/klib/kurl.h @@ -0,0 +1,57 @@ +#ifndef KURL_H +#define KURL_H + +#include + +#define KURL_NULL 1 +#define KURL_INV_WHENCE 2 +#define KURL_SEEK_OUT 3 +#define KURL_NO_AUTH 4 + +struct kurl_t; +typedef struct kurl_t kurl_t; + +typedef struct { + const char *s3keyid; + const char *s3secretkey; + const char *s3key_fn; +} kurl_opt_t; + +#ifdef __cplusplus +extern "C" { +#endif + +int kurl_init(void); +void kurl_destroy(void); + +kurl_t *kurl_open(const char *url, kurl_opt_t *opt); +kurl_t *kurl_dopen(int fd); +int kurl_close(kurl_t *ku); +ssize_t kurl_read(kurl_t *ku, void *buf, size_t nbytes); +off_t kurl_seek(kurl_t *ku, off_t offset, int whence); +int kurl_buflen(kurl_t *ku, int len); + +off_t kurl_tell(const kurl_t *ku); +int kurl_eof(const kurl_t *ku); +int kurl_fileno(const kurl_t *ku); +int kurl_error(const kurl_t *ku); + +#ifdef __cplusplus +} +#endif + +#ifndef KNETFILE_H +#define KNETFILE_H +typedef kurl_t knetFile; +#define knet_open(fn, mode) kurl_open(fn, 0) +#define knet_dopen(fd, mode) kurl_dopen(fd) +#define knet_close(fp) kurl_close(fp) +#define knet_read(fp, buf, len) kurl_read(fp, buf, len) +#define knet_seek(fp, off, whence) kurl_seek(fp, off, whence) +#define knet_tell(fp) kurl_tell(fp) +#define knet_fileno(fp) kurl_fileno(fp) +#define knet_win32_init() kurl_init() +#define knet_win32_destroy() kurl_destroy() +#endif + +#endif diff --git a/web/server/h2o/libh2o/deps/klib/kvec.h b/web/server/h2o/libh2o/deps/klib/kvec.h new file mode 100644 index 00000000..676be8b8 --- /dev/null +++ b/web/server/h2o/libh2o/deps/klib/kvec.h @@ -0,0 +1,90 @@ +/* The MIT License + + Copyright (c) 2008, by Attractive Chaos + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. +*/ + +/* + An example: + +#include "kvec.h" +int main() { + kvec_t(int) array; + kv_init(array); + kv_push(int, array, 10); // append + kv_a(int, array, 20) = 5; // dynamic + kv_A(array, 20) = 4; // static + kv_destroy(array); + return 0; +} +*/ + +/* + 2008-09-22 (0.1.0): + + * The initial version. + +*/ + +#ifndef AC_KVEC_H +#define AC_KVEC_H + +#include + +#define kv_roundup32(x) (--(x), (x)|=(x)>>1, (x)|=(x)>>2, (x)|=(x)>>4, (x)|=(x)>>8, (x)|=(x)>>16, ++(x)) + +#define kvec_t(type) struct { size_t n, m; type *a; } +#define kv_init(v) ((v).n = (v).m = 0, (v).a = 0) +#define kv_destroy(v) free((v).a) +#define kv_A(v, i) ((v).a[(i)]) +#define kv_pop(v) ((v).a[--(v).n]) +#define kv_size(v) ((v).n) +#define kv_max(v) ((v).m) + +#define kv_resize(type, v, s) ((v).m = (s), (v).a = (type*)realloc((v).a, sizeof(type) * (v).m)) + +#define kv_copy(type, v1, v0) do { \ + if ((v1).m < (v0).n) kv_resize(type, v1, (v0).n); \ + (v1).n = (v0).n; \ + memcpy((v1).a, (v0).a, sizeof(type) * (v0).n); \ + } while (0) \ + +#define kv_push(type, v, x) do { \ + if ((v).n == (v).m) { \ + (v).m = (v).m? (v).m<<1 : 2; \ + (v).a = (type*)realloc((v).a, sizeof(type) * (v).m); \ + } \ + (v).a[(v).n++] = (x); \ + } while (0) + +#define kv_pushp(type, v) (((v).n == (v).m)? \ + ((v).m = ((v).m? (v).m<<1 : 2), \ + (v).a = (type*)realloc((v).a, sizeof(type) * (v).m), 0) \ + : 0), ((v).a + ((v).n++)) + +#define kv_a(type, v, i) (((v).m <= (size_t)(i)? \ + ((v).m = (v).n = (i) + 1, kv_roundup32((v).m), \ + (v).a = (type*)realloc((v).a, sizeof(type) * (v).m), 0) \ + : (v).n <= (size_t)(i)? (v).n = (i) + 1 \ + : 0), (v).a[(i)]) + +#endif diff --git a/web/server/h2o/libh2o/deps/klib/lua/bio.lua b/web/server/h2o/libh2o/deps/klib/lua/bio.lua new file mode 100644 index 00000000..c9f22005 --- /dev/null +++ b/web/server/h2o/libh2o/deps/klib/lua/bio.lua @@ -0,0 +1,149 @@ +-- bioinformatics routines + +-- Description: read a fasta/fastq file +local function readseq(fp) + local finished, last = false, nil; + return function() + local match; + if finished then return nil end + if (last == nil) then -- the first record or a record following a fastq + for l in fp:lines() do + if l:byte(1) == 62 or l:byte(1) == 64 then -- ">" || "@" + last = l; + break; + end + end + if last == nil then + finished = true; + return nil; + end + end + local tmp = last:find("%s"); + name = (tmp and last:sub(2, tmp-1)) or last:sub(2); -- sequence name + local seqs = {}; + local c; -- the first character of the last line + last = nil; + for l in fp:lines() do -- read sequence + c = l:byte(1); + if c == 62 or c == 64 or c == 43 then + last = l; + break; + end + table.insert(seqs, l); + end + if last == nil then finished = true end -- end of file + if c ~= 43 then return name, table.concat(seqs) end -- a fasta record + local seq, len = table.concat(seqs), 0; -- prepare to parse quality + seqs = {}; + for l in fp:lines() do -- read quality + table.insert(seqs, l); + len = len + #l; + if len >= #seq then + last = nil; + return name, seq, table.concat(seqs); + end + end + finished = true; + return name, seq; + end +end + +-- extract subsequence from a fasta file indexe by samtools faidx +local function faidxsub(fn) + local fpidx = io.open(fn .. ".fai"); + if fpidx == nil then + io.stderr:write("[faidxsub] fail to open the FASTA index file.\n"); + return nil + end + local idx = {}; + for l in fpidx:lines() do + local name, len, offset, line_blen, line_len = l:match("(%S+)%s(%d+)%s(%d+)%s(%d+)%s(%d+)"); + if name then + idx[name] = {tonumber(len), offset, line_blen, line_len}; + end + end + fpidx:close(); + local fp = io.open(fn); + return function(name, beg_, end_) -- 0-based coordinate + if name == nil then fp:close(); return nil; end + if idx[name] then + local a = idx[name]; + beg_ = beg_ or 0; + end_ = end_ or a[1]; + end_ = (end_ <= a[1] and end_) or a[1]; + local fb, fe = math.floor(beg_ / a[3]), math.floor(end_ / a[3]); + local qb, qe = beg_ - fb * a[3], end_ - fe * a[3]; + fp:seek("set", a[2] + fb * a[4] + qb); + local s = fp:read((fe - fb) * a[4] + (qe - qb)):gsub("%s", ""); + return s; + end + end +end + +--Description: Index a list of intervals and test if a given interval overlaps with the list +--Example: lua -lbio -e 'a={{100,201},{200,300},{400,600}};f=bio.intvovlp(a);print(f(600,700))' +--[[ + By default, we keep for each tiling 8192 window the interval overlaping the + window while having the smallest start position. This method may not work + well when most intervals are small but few intervals span a long distance. +]]-- +local function intvovlp(intv, bits) + bits = bits or 13 -- the default bin size is 8192 = 1<<13 + table.sort(intv, function(a,b) return a[1] < b[1] end) -- sort by the start + -- merge intervals; the step speeds up testing, but can be skipped + local b, e, k = -1, -1, 1 + for i = 1, #intv do + if e < intv[i][1] then + if e >= 0 then intv[k], k = {b, e}, k + 1 end + b, e = intv[i][1], intv[i][2] + else e = intv[i][2] end + end + if e >= 0 then intv[k] = {b, e} end + while #a > k do table.remove(a) end -- truncate the interval list + -- build the index for the list of intervals + local idx, size, max = {}, math.pow(2, bits), 0 + for i = 1, #a do + b = math.modf(intv[i][1] / size) + e = math.modf(intv[i][2] / size) + if b == e then idx[b] = idx[b] or i + else for j = b, e do idx[j] = idx[j] or i end end + max = (max > e and max) or e + end + -- return a function (closure) + return function(_beg, _end) + local x = math.modf(_beg / size) + if x > max then return false end + local off = idx[x]; -- the start bin + if off == nil then -- the following is not the best in efficiency + for i = x - 1, 0, -1 do -- find the minimum bin with a value + if idx[i] ~= nil then off = idx[i]; break; end + end + if off == nil then return false end + end + for i = off, #intv do -- start from off and search for overlaps + if intv[i][1] >= _end then return false + elseif intv[i][2] > _beg then return true end + end + return false + end +end + +bio = { + readseq = readseq, + faidxsub = faidxsub, + intvovlp = intvovlp +} + +bio.nt16 = { +[0]=15,15,15,15, 15,15,15,15, 15,15,15,15, 15,15,15,15, 15,15,15,15, 15,15,15,15, 15,15,15,15, 15,15,15,15, + 15,15,15,15, 15,15,15,15, 15,15,15,15, 15,15,15,15, 15,15,15,15, 15,15,15,15, 15,15,15,15, 15,15,15,15, + 15, 1,14, 2, 13,15,15, 4, 11,15,15,12, 15, 3,15,15, 15,15, 5, 6, 8,15, 7, 9, 0,10,15,15, 15,15,15,15, + 15, 1,14, 2, 13,15,15, 4, 11,15,15,12, 15, 3,15,15, 15,15, 5, 6, 8,15, 7, 9, 0,10,15,15, 15,15,15,15, + 15,15,15,15, 15,15,15,15, 15,15,15,15, 15,15,15,15, 15,15,15,15, 15,15,15,15, 15,15,15,15, 15,15,15,15, + 15,15,15,15, 15,15,15,15, 15,15,15,15, 15,15,15,15, 15,15,15,15, 15,15,15,15, 15,15,15,15, 15,15,15,15, + 15,15,15,15, 15,15,15,15, 15,15,15,15, 15,15,15,15, 15,15,15,15, 15,15,15,15, 15,15,15,15, 15,15,15,15, + 15,15,15,15, 15,15,15,15, 15,15,15,15, 15,15,15,15, 15,15,15,15, 15,15,15,15, 15,15,15,15, 15,15,15,15 +} +bio.ntcnt = { [0]=4, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4 } +bio.ntcomp = { [0]=0, 8, 4, 12, 2, 10, 9, 14, 1, 6, 5, 13, 3, 11, 7, 15 } +bio.ntrev = 'XACMGRSVTWYHKDBN' diff --git a/web/server/h2o/libh2o/deps/klib/lua/klib.lua b/web/server/h2o/libh2o/deps/klib/lua/klib.lua new file mode 100644 index 00000000..bfe52f7f --- /dev/null +++ b/web/server/h2o/libh2o/deps/klib/lua/klib.lua @@ -0,0 +1,677 @@ +--[[ + The MIT License + + Copyright (c) 2011, Attractive Chaos + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. +]]-- + +--[[ + This is a Lua library, more exactly a collection of Lua snippets, covering + utilities (e.g. getopt), string operations (e.g. split), statistics (e.g. + Fisher's exact test), special functions (e.g. logarithm gamma) and matrix + operations (e.g. Gauss-Jordan elimination). The routines are designed to be + as independent as possible, such that one can copy-paste relevant pieces of + code without worrying about additional library dependencies. + + If you use routines from this library, please include the licensing + information above where appropriate. +]]-- + +--[[ + Library functions and dependencies. "a>b" means "a is required by b"; "bmath.lbinom() >math.igamma() + math.igamma() matrix.chi2() + math.erfc() + math.lbinom() math.fisher_exact() + math.bernstein_poly() matrix.mul() + matrix.mul() = 2 then + place = place + 1 + if args[1]:sub(2, 2) == '-' then -- found "--" + place = 0 + table.remove(args, 1); + return nil; + end + end + end + local optopt = args[1]:sub(place, place); + place = place + 1; + local oli = ostr:find(optopt); + if optopt == ':' or oli == nil then -- unknown option + if optopt == '-' then return nil end + if place > #args[1] then + table.remove(args, 1); + place = 0; + end + return '?'; + end + oli = oli + 1; + if ostr:sub(oli, oli) ~= ':' then -- do not need argument + arg = nil; + if place > #args[1] then + table.remove(args, 1); + place = 0; + end + else -- need an argument + if place <= #args[1] then -- no white space + arg = args[1]:sub(place); + else + table.remove(args, 1); + if #args == 0 then -- an option requiring argument is the last one + place = 0; + if ostr:sub(1, 1) == ':' then return ':' end + return '?'; + else arg = args[1] end + end + table.remove(args, 1); + place = 0; + end + return optopt, arg; + end +end + +-- Description: string split +function string:split(sep, n) + local a, start = {}, 1; + sep = sep or "%s+"; + repeat + local b, e = self:find(sep, start); + if b == nil then + table.insert(a, self:sub(start)); + break + end + a[#a+1] = self:sub(start, b - 1); + start = e + 1; + if n and #a == n then + table.insert(a, self:sub(start)); + break + end + until start > #self; + return a; +end + +-- Description: smart file open +function io.xopen(fn, mode) + mode = mode or 'r'; + if fn == nil then return io.stdin; + elseif fn == '-' then return (mode == 'r' and io.stdin) or io.stdout; + elseif fn:sub(-3) == '.gz' then return (mode == 'r' and io.popen('gzip -dc ' .. fn, 'r')) or io.popen('gzip > ' .. fn, 'w'); + elseif fn:sub(-4) == '.bz2' then return (mode == 'r' and io.popen('bzip2 -dc ' .. fn, 'r')) or io.popen('bgzip2 > ' .. fn, 'w'); + else return io.open(fn, mode) end +end + +-- Description: find the k-th smallest element in an array (Ref. http://ndevilla.free.fr/median/) +function table.ksmall(arr, k) + local low, high = 1, #arr; + while true do + if high <= low then return arr[k] end + if high == low + 1 then + if arr[high] < arr[low] then arr[high], arr[low] = arr[low], arr[high] end; + return arr[k]; + end + local mid = math.floor((high + low) / 2); + if arr[high] < arr[mid] then arr[mid], arr[high] = arr[high], arr[mid] end + if arr[high] < arr[low] then arr[low], arr[high] = arr[high], arr[low] end + if arr[low] < arr[mid] then arr[low], arr[mid] = arr[mid], arr[low] end + arr[mid], arr[low+1] = arr[low+1], arr[mid]; + local ll, hh = low + 1, high; + while true do + repeat ll = ll + 1 until arr[ll] >= arr[low] + repeat hh = hh - 1 until arr[low] >= arr[hh] + if hh < ll then break end + arr[ll], arr[hh] = arr[hh], arr[ll]; + end + arr[low], arr[hh] = arr[hh], arr[low]; + if hh <= k then low = ll end + if hh >= k then high = hh - 1 end + end +end + +-- Description: shuffle/permutate an array +function table.shuffle(a) + for i = #a, 1, -1 do + local j = math.random(i) + a[j], a[i] = a[i], a[j] + end +end + +-- +-- Mathematics +-- + +-- Description: log gamma function +-- Required by: math.lbinom() +-- Reference: AS245, 2nd algorithm, http://lib.stat.cmu.edu/apstat/245 +function math.lgamma(z) + local x; + x = 0.1659470187408462e-06 / (z+7); + x = x + 0.9934937113930748e-05 / (z+6); + x = x - 0.1385710331296526 / (z+5); + x = x + 12.50734324009056 / (z+4); + x = x - 176.6150291498386 / (z+3); + x = x + 771.3234287757674 / (z+2); + x = x - 1259.139216722289 / (z+1); + x = x + 676.5203681218835 / z; + x = x + 0.9999999999995183; + return math.log(x) - 5.58106146679532777 - z + (z-0.5) * math.log(z+6.5); +end + +-- Description: regularized incomplete gamma function +-- Dependent on: math.lgamma() +--[[ + Formulas are taken from Wiki, with additional input from Numerical + Recipes in C (for modified Lentz's algorithm) and AS245 + (http://lib.stat.cmu.edu/apstat/245). + + A good online calculator is available at: + + http://www.danielsoper.com/statcalc/calc23.aspx + + It calculates upper incomplete gamma function, which equals + math.igamma(s,z,true)*math.exp(math.lgamma(s)) +]]-- +function math.igamma(s, z, complement) + + local function _kf_gammap(s, z) + local sum, x = 1, 1; + for k = 1, 100 do + x = x * z / (s + k); + sum = sum + x; + if x / sum < 1e-14 then break end + end + return math.exp(s * math.log(z) - z - math.lgamma(s + 1.) + math.log(sum)); + end + + local function _kf_gammaq(s, z) + local C, D, f, TINY; + f = 1. + z - s; C = f; D = 0.; TINY = 1e-290; + -- Modified Lentz's algorithm for computing continued fraction. See Numerical Recipes in C, 2nd edition, section 5.2 + for j = 1, 100 do + local d; + local a, b = j * (s - j), j*2 + 1 + z - s; + D = b + a * D; + if D < TINY then D = TINY end + C = b + a / C; + if C < TINY then C = TINY end + D = 1. / D; + d = C * D; + f = f * d; + if math.abs(d - 1) < 1e-14 then break end + end + return math.exp(s * math.log(z) - z - math.lgamma(s) - math.log(f)); + end + + if complement then + return ((z <= 1 or z < s) and 1 - _kf_gammap(s, z)) or _kf_gammaq(s, z); + else + return ((z <= 1 or z < s) and _kf_gammap(s, z)) or (1 - _kf_gammaq(s, z)); + end +end + +math.M_SQRT2 = 1.41421356237309504880 -- sqrt(2) +math.M_SQRT1_2 = 0.70710678118654752440 -- 1/sqrt(2) + +-- Description: complement error function erfc(x): \Phi(x) = 0.5 * erfc(-x/M_SQRT2) +function math.erfc(x) + local z = math.abs(x) * math.M_SQRT2 + if z > 37 then return (x > 0 and 0) or 2 end + local expntl = math.exp(-0.5 * z * z) + local p + if z < 10. / math.M_SQRT2 then -- for small z + p = expntl * ((((((.03526249659989109 * z + .7003830644436881) * z + 6.37396220353165) * z + 33.912866078383) + * z + 112.0792914978709) * z + 221.2135961699311) * z + 220.2068679123761) + / (((((((.08838834764831844 * z + 1.755667163182642) * z + 16.06417757920695) * z + 86.78073220294608) + * z + 296.5642487796737) * z + 637.3336333788311) * z + 793.8265125199484) * z + 440.4137358247522); + else p = expntl / 2.506628274631001 / (z + 1. / (z + 2. / (z + 3. / (z + 4. / (z + .65))))) end + return (x > 0 and 2 * p) or 2 * (1 - p) +end + +-- Description: log binomial coefficient +-- Dependent on: math.lgamma() +-- Required by: math.fisher_exact() +function math.lbinom(n, m) + if m == nil then + local a = {}; + a[0], a[n] = 0, 0; + local t = math.lgamma(n+1); + for m = 1, n-1 do a[m] = t - math.lgamma(m+1) - math.lgamma(n-m+1) end + return a; + else return math.lgamma(n+1) - math.lgamma(m+1) - math.lgamma(n-m+1) end +end + +-- Description: Berstein polynomials (mainly for Bezier curves) +-- Dependent on: math.lbinom() +-- Note: to compute derivative: let beta_new[i]=beta[i+1]-beta[i] +function math.bernstein_poly(beta) + local n = #beta - 1; + local lbc = math.lbinom(n); -- log binomial coefficients + return function (t) + assert(t >= 0 and t <= 1); + if t == 0 then return beta[1] end + if t == 1 then return beta[n+1] end + local sum, logt, logt1 = 0, math.log(t), math.log(1-t); + for i = 0, n do sum = sum + beta[i+1] * math.exp(lbc[i] + i * logt + (n-i) * logt1) end + return sum; + end +end + +-- Description: Fisher's exact test +-- Dependent on: math.lbinom() +-- Return: left-, right- and two-tail P-values +--[[ + Fisher's exact test for 2x2 congintency tables: + + n11 n12 | n1_ + n21 n22 | n2_ + -----------+---- + n_1 n_2 | n + + Reference: http://www.langsrud.com/fisher.htm +]]-- +function math.fisher_exact(n11, n12, n21, n22) + local aux; -- keep the states of n* for acceleration + + -- Description: hypergeometric function + local function hypergeo(n11, n1_, n_1, n) + return math.exp(math.lbinom(n1_, n11) + math.lbinom(n-n1_, n_1-n11) - math.lbinom(n, n_1)); + end + + -- Description: incremental hypergeometric function + -- Note: aux = {n11, n1_, n_1, n, p} + local function hypergeo_inc(n11, n1_, n_1, n) + if n1_ ~= 0 or n_1 ~= 0 or n ~= 0 then + aux = {n11, n1_, n_1, n, 1}; + else -- then only n11 is changed + local mod; + _, mod = math.modf(n11 / 11); + if mod ~= 0 and n11 + aux[4] - aux[2] - aux[3] ~= 0 then + if n11 == aux[1] + 1 then -- increase by 1 + aux[5] = aux[5] * (aux[2] - aux[1]) / n11 * (aux[3] - aux[1]) / (n11 + aux[4] - aux[2] - aux[3]); + aux[1] = n11; + return aux[5]; + end + if n11 == aux[1] - 1 then -- descrease by 1 + aux[5] = aux[5] * aux[1] / (aux[2] - n11) * (aux[1] + aux[4] - aux[2] - aux[3]) / (aux[3] - n11); + aux[1] = n11; + return aux[5]; + end + end + aux[1] = n11; + end + aux[5] = hypergeo(aux[1], aux[2], aux[3], aux[4]); + return aux[5]; + end + + -- Description: computing the P-value by Fisher's exact test + local max, min, left, right, n1_, n_1, n, two, p, q, i, j; + n1_, n_1, n = n11 + n12, n11 + n21, n11 + n12 + n21 + n22; + max = (n_1 < n1_ and n_1) or n1_; -- max n11, for the right tail + min = n1_ + n_1 - n; + if min < 0 then min = 0 end -- min n11, for the left tail + two, left, right = 1, 1, 1; + if min == max then return 1 end -- no need to do test + q = hypergeo_inc(n11, n1_, n_1, n); -- the probability of the current table + -- left tail + i, left, p = min + 1, 0, hypergeo_inc(min, 0, 0, 0); + while p < 0.99999999 * q do + left, p, i = left + p, hypergeo_inc(i, 0, 0, 0), i + 1; + end + i = i - 1; + if p < 1.00000001 * q then left = left + p; + else i = i - 1 end + -- right tail + j, right, p = max - 1, 0, hypergeo_inc(max, 0, 0, 0); + while p < 0.99999999 * q do + right, p, j = right + p, hypergeo_inc(j, 0, 0, 0), j - 1; + end + j = j + 1; + if p < 1.00000001 * q then right = right + p; + else j = j + 1 end + -- two-tail + two = left + right; + if two > 1 then two = 1 end + -- adjust left and right + if math.abs(i - n11) < math.abs(j - n11) then right = 1 - left + q; + else left = 1 - right + q end + return left, right, two; +end + +-- Description: Delete-m Jackknife +--[[ + Given g groups of values with a statistics estimated from m[i] samples in + i-th group being t[i], compute the mean and the variance. t0 below is the + estimate from all samples. Reference: + + Busing et al. (1999) Delete-m Jackknife for unequal m. Statistics and Computing, 9:3-8. +]]-- +function math.jackknife(g, m, t, t0) + local h, n, sum = {}, 0, 0; + for j = 1, g do n = n + m[j] end + if t0 == nil then -- When t0 is absent, estimate it in a naive way + t0 = 0; + for j = 1, g do t0 = t0 + m[j] * t[j] end + t0 = t0 / n; + end + local mean, var = 0, 0; + for j = 1, g do + h[j] = n / m[j]; + mean = mean + (1 - m[j] / n) * t[j]; + end + mean = g * t0 - mean; -- Eq. (8) + for j = 1, g do + local x = h[j] * t0 - (h[j] - 1) * t[j] - mean; + var = var + 1 / (h[j] - 1) * x * x; + end + var = var / g; + return mean, var; +end + +-- Description: Pearson correlation coefficient +-- Input: a is an n*2 table +function math.pearson(a) + -- compute the mean + local x1, y1 = 0, 0 + for _, v in pairs(a) do + x1, y1 = x1 + v[1], y1 + v[2] + end + -- compute the coefficient + x1, y1 = x1 / #a, y1 / #a + local x2, y2, xy = 0, 0, 0 + for _, v in pairs(a) do + local tx, ty = v[1] - x1, v[2] - y1 + xy, x2, y2 = xy + tx * ty, x2 + tx * tx, y2 + ty * ty + end + return xy / math.sqrt(x2) / math.sqrt(y2) +end + +-- Description: Spearman correlation coefficient +function math.spearman(a) + local function aux_func(t) -- auxiliary function + return (t == 1 and 0) or (t*t - 1) * t / 12 + end + + for _, v in pairs(a) do v.r = {} end + local T, S = {}, {} + -- compute the rank + for k = 1, 2 do + table.sort(a, function(u,v) return u[k] 1 then T[k], same = T[k] + aux_func(same), 1 end + end + end + S[k] = aux_func(#a) - T[k] + end + -- compute the coefficient + local sum = 0 + for _, v in pairs(a) do -- TODO: use nested loops to reduce loss of precision + local t = (v.r[1] - v.r[2]) / 2 + sum = sum + t * t + end + return (S[1] + S[2] - sum) / 2 / math.sqrt(S[1] * S[2]) +end + +-- Description: Hooke-Jeeves derivative-free optimization +function math.fmin(func, x, data, r, eps, max_calls) + local n, n_calls = #x, 0; + r = r or 0.5; + eps = eps or 1e-7; + max_calls = max_calls or 50000 + + function fmin_aux(x1, data, fx1, dx) -- auxiliary function + local ftmp; + for k = 1, n do + x1[k] = x1[k] + dx[k]; + local ftmp = func(x1, data); n_calls = n_calls + 1; + if ftmp < fx1 then fx1 = ftmp; + else -- search the opposite direction + dx[k] = -dx[k]; + x1[k] = x1[k] + dx[k] + dx[k]; + ftmp = func(x1, data); n_calls = n_calls + 1; + if ftmp < fx1 then fx1 = ftmp + else x1[k] = x1[k] - dx[k] end -- back to the original x[k] + end + end + return fx1; -- here: fx1=f(n,x1) + end + + local dx, x1 = {}, {}; + for k = 1, n do -- initial directions, based on MGJ + dx[k] = math.abs(x[k]) * r; + if dx[k] == 0 then dx[k] = r end; + end + local radius = r; + local fx1, fx; + fx = func(x, data); fx1 = fx; n_calls = n_calls + 1; + while true do + for i = 1, n do x1[i] = x[i] end; -- x1 = x + fx1 = fmin_aux(x1, data, fx, dx); + while fx1 < fx do + for k = 1, n do + local t = x[k]; + dx[k] = (x1[k] > x[k] and math.abs(dx[k])) or -math.abs(dx[k]); + x[k] = x1[k]; + x1[k] = x1[k] + x1[k] - t; + end + fx = fx1; + if n_calls >= max_calls then break end + fx1 = func(x1, data); n_calls = n_calls + 1; + fx1 = fmin_aux(x1, data, fx1, dx); + if fx1 >= fx then break end + local kk = n; + for k = 1, n do + if math.abs(x1[k] - x[k]) > .5 * math.abs(dx[k]) then + kk = k; + break; + end + end + if kk == n then break end + end + if radius >= eps then + if n_calls >= max_calls then break end + radius = radius * r; + for k = 1, n do dx[k] = dx[k] * r end + else break end + end + return fx1, n_calls; +end + +-- +-- Matrix +-- + +matrix = {} + +-- Description: matrix transpose +-- Required by: matrix.mul() +function matrix.T(a) + local m, n, x = #a, #a[1], {}; + for i = 1, n do + x[i] = {}; + for j = 1, m do x[i][j] = a[j][i] end + end + return x; +end + +-- Description: matrix add +function matrix.add(a, b) + assert(#a == #b and #a[1] == #b[1]); + local m, n, x = #a, #a[1], {}; + for i = 1, m do + x[i] = {}; + local ai, bi, xi = a[i], b[i], x[i]; + for j = 1, n do xi[j] = ai[j] + bi[j] end + end + return x; +end + +-- Description: matrix mul +-- Dependent on: matrix.T() +-- Note: much slower without transpose +function matrix.mul(a, b) + assert(#a[1] == #b); + local m, n, p, x = #a, #a[1], #b[1], {}; + local c = matrix.T(b); -- transpose for efficiency + for i = 1, m do + x[i] = {} + local xi = x[i]; + for j = 1, p do + local sum, ai, cj = 0, a[i], c[j]; + for k = 1, n do sum = sum + ai[k] * cj[k] end + xi[j] = sum; + end + end + return x; +end + +-- Description: matrix print +function matrix.tostring(a) + local z = {}; + for i = 1, #a do + z[i] = table.concat(a[i], "\t"); + end + return table.concat(z, "\n"); +end + +-- Description: chi^2 test for contingency tables +-- Dependent on: math.igamma() +function matrix.chi2(a) + if #a == 2 and #a[1] == 2 then -- 2x2 table + local x, z + x = (a[1][1] + a[1][2]) * (a[2][1] + a[2][2]) * (a[1][1] + a[2][1]) * (a[1][2] + a[2][2]) + if x == 0 then return 0, 1, false end + z = a[1][1] * a[2][2] - a[1][2] * a[2][1] + z = (a[1][1] + a[1][2] + a[2][1] + a[2][2]) * z * z / x + return z, math.igamma(.5, .5 * z, true), true + else -- generic table + local rs, cs, n, m, N, z = {}, {}, #a, #a[1], 0, 0 + for i = 1, n do rs[i] = 0 end + for j = 1, m do cs[j] = 0 end + for i = 1, n do -- compute column sum and row sum + for j = 1, m do cs[j], rs[i] = cs[j] + a[i][j], rs[i] + a[i][j] end + end + for i = 1, n do N = N + rs[i] end + for i = 1, n do -- compute the chi^2 statistics + for j = 1, m do + local E = rs[i] * cs[j] / N; + z = z + (a[i][j] - E) * (a[i][j] - E) / E + end + end + return z, math.igamma(.5 * (n-1) * (m-1), .5 * z, true), true; + end +end + +-- Description: Gauss-Jordan elimination (solving equations; computing inverse) +-- Note: on return, a[n][n] is the inverse; b[n][m] is the solution +-- Reference: Section 2.1, Numerical Recipes in C, 2nd edition +function matrix.solve(a, b) + assert(#a == #a[1]); + local n, m = #a, (b and #b[1]) or 0; + local xc, xr, ipiv = {}, {}, {}; + local ic, ir; + + for j = 1, n do ipiv[j] = 0 end + for i = 1, n do + local big = 0; + for j = 1, n do + local aj = a[j]; + if ipiv[j] ~= 1 then + for k = 1, n do + if ipiv[k] == 0 then + if math.abs(aj[k]) >= big then + big = math.abs(aj[k]); + ir, ic = j, k; + end + elseif ipiv[k] > 1 then return -2 end -- singular matrix + end + end + end + ipiv[ic] = ipiv[ic] + 1; + if ir ~= ic then + for l = 1, n do a[ir][l], a[ic][l] = a[ic][l], a[ir][l] end + if b then + for l = 1, m do b[ir][l], b[ic][l] = b[ic][l], b[ir][l] end + end + end + xr[i], xc[i] = ir, ic; + if a[ic][ic] == 0 then return -3 end -- singular matrix + local pivinv = 1 / a[ic][ic]; + a[ic][ic] = 1; + for l = 1, n do a[ic][l] = a[ic][l] * pivinv end + if b then + for l = 1, n do b[ic][l] = b[ic][l] * pivinv end + end + for ll = 1, n do + if ll ~= ic then + local tmp = a[ll][ic]; + a[ll][ic] = 0; + local all, aic = a[ll], a[ic]; + for l = 1, n do all[l] = all[l] - aic[l] * tmp end + if b then + local bll, bic = b[ll], b[ic]; + for l = 1, m do bll[l] = bll[l] - bic[l] * tmp end + end + end + end + end + for l = n, 1, -1 do + if xr[l] ~= xc[l] then + for k = 1, n do a[k][xr[l]], a[k][xc[l]] = a[k][xc[l]], a[k][xr[l]] end + end + end + return 0; +end diff --git a/web/server/h2o/libh2o/deps/klib/test/Makefile b/web/server/h2o/libh2o/deps/klib/test/Makefile new file mode 100644 index 00000000..a392c8ed --- /dev/null +++ b/web/server/h2o/libh2o/deps/klib/test/Makefile @@ -0,0 +1,60 @@ +CC=gcc +CXX=g++ +CFLAGS=-g -Wall -O2 -I.. +CXXFLAGS=$(CFLAGS) +PROGS=kbtree_test khash_keith khash_keith2 khash_test klist_test kseq_test kseq_bench \ + kseq_bench2 ksort_test ksort_test-stl kvec_test kmin_test kstring_bench kstring_bench2 kstring_test \ + kthread_test + +all:$(PROGS) + +clean: + rm -fr $(PROGS) *.dSYM a.out + +kbtree_test:kbtree_test.c ../kbtree.h + $(CC) $(CFLAGS) -o $@ kbtree_test.c + +khash_keith:khash_keith.c ../khash.h + $(CC) $(CFLAGS) -o $@ khash_keith.c + +khash_keith2:khash_keith2.c ../khash.h + $(CC) $(CFLAGS) -o $@ khash_keith2.c + +khash_test:khash_test.c ../khash.h + $(CC) $(CFLAGS) -o $@ khash_test.c + +klist_test:klist_test.c ../klist.h + $(CC) $(CFLAGS) -o $@ klist_test.c + +kseq_test:kseq_test.c ../kseq.h + $(CC) $(CFLAGS) -o $@ kseq_test.c -lz + +kseq_bench:kseq_bench.c ../kseq.h + $(CC) $(CFLAGS) -o $@ kseq_bench.c -lz + +kseq_bench2:kseq_bench2.c ../kseq.h + $(CC) $(CFLAGS) -o $@ kseq_bench2.c -lz + +ksort_test:ksort_test.c ../ksort.h + $(CC) $(CFLAGS) -o $@ ksort_test.c + +ksort_test-stl:ksort_test.cc ../ksort.h + $(CXX) $(CXXFLAGS) -o $@ ksort_test.cc + +kvec_test:kvec_test.cc ../kvec.h + $(CXX) $(CXXFLAGS) -o $@ kvec_test.cc + +kmin_test:kmin_test.c ../kmath.h ../kmath.c + $(CC) $(CFLAGS) -o $@ kmin_test.c ../kmath.c + +kstring_bench:kstring_bench.c ../kstring.h ../kstring.c + $(CC) $(CFLAGS) -o $@ kstring_bench.c ../kstring.c + +kstring_bench2:kstring_bench2.c ../kstring.h ../kstring.c + $(CC) $(CFLAGS) -o $@ kstring_bench2.c ../kstring.c + +kstring_test:kstring_test.c ../kstring.h ../kstring.c + $(CC) $(CFLAGS) -o $@ kstring_test.c ../kstring.c + +kthread_test:kthread_test.c ../kthread.c + $(CC) $(CFLAGS) -fopenmp -o $@ kthread_test.c ../kthread.c diff --git a/web/server/h2o/libh2o/deps/klib/test/kbit_test.c b/web/server/h2o/libh2o/deps/klib/test/kbit_test.c new file mode 100644 index 00000000..3ae3bd30 --- /dev/null +++ b/web/server/h2o/libh2o/deps/klib/test/kbit_test.c @@ -0,0 +1,137 @@ +#include +#include +#include +#include +#include "kbit.h" + +// from bowtie-0.9.8.1 +inline static int bt1_pop64(uint64_t x) // the kbi_popcount64() equivalence; similar to popcount_2() in wiki +{ + x -= ((x >> 1) & 0x5555555555555555llu); + x = (x & 0x3333333333333333llu) + ((x >> 2) & 0x3333333333333333llu); + x = (x + (x >> 4)) & 0x0F0F0F0F0F0F0F0Fllu; + x = x + (x >> 8); + x = x + (x >> 16); + x = x + (x >> 32); + return x & 0x3F; +} + +inline static int bt1_countInU64(uint64_t dw, int c) // the kbi_DNAcount64() equivalence +{ + uint64_t dwA = dw & 0xAAAAAAAAAAAAAAAAllu; + uint64_t dwNA = dw & ~0xAAAAAAAAAAAAAAAAllu; + uint64_t tmp; + switch (c) { + case 0: tmp = (dwA >> 1) | dwNA; break; + case 1: tmp = ~(dwA >> 1) & dwNA; break; + case 2: tmp = (dwA >> 1) & ~dwNA; break; + default: tmp = (dwA >> 1) & dwNA; + } + tmp = bt1_pop64(tmp); + if (c == 0) tmp = 32 - tmp; + return (int)tmp; +} + +// from bigmagic +static uint32_t sse2_bit_count32(const __m128i* block, const __m128i* block_end) +{ + const unsigned mu1 = 0x55555555; + const unsigned mu2 = 0x33333333; + const unsigned mu3 = 0x0F0F0F0F; + const unsigned mu4 = 0x0000003F; + + uint32_t tcnt[4]; + + // Loading masks + __m128i m1 = _mm_set_epi32 (mu1, mu1, mu1, mu1); + __m128i m2 = _mm_set_epi32 (mu2, mu2, mu2, mu2); + __m128i m3 = _mm_set_epi32 (mu3, mu3, mu3, mu3); + __m128i m4 = _mm_set_epi32 (mu4, mu4, mu4, mu4); + __m128i mcnt; + mcnt = _mm_xor_si128(m1, m1); // cnt = 0 + + __m128i tmp1, tmp2; + do + { + __m128i b = _mm_load_si128(block); + ++block; + + // b = (b & 0x55555555) + (b >> 1 & 0x55555555); + tmp1 = _mm_srli_epi32(b, 1); // tmp1 = (b >> 1 & 0x55555555) + tmp1 = _mm_and_si128(tmp1, m1); + tmp2 = _mm_and_si128(b, m1); // tmp2 = (b & 0x55555555) + b = _mm_add_epi32(tmp1, tmp2); // b = tmp1 + tmp2 + + // b = (b & 0x33333333) + (b >> 2 & 0x33333333); + tmp1 = _mm_srli_epi32(b, 2); // (b >> 2 & 0x33333333) + tmp1 = _mm_and_si128(tmp1, m2); + tmp2 = _mm_and_si128(b, m2); // (b & 0x33333333) + b = _mm_add_epi32(tmp1, tmp2); // b = tmp1 + tmp2 + + // b = (b + (b >> 4)) & 0x0F0F0F0F; + tmp1 = _mm_srli_epi32(b, 4); // tmp1 = b >> 4 + b = _mm_add_epi32(b, tmp1); // b = b + (b >> 4) + b = _mm_and_si128(b, m3); // & 0x0F0F0F0F + + // b = b + (b >> 8); + tmp1 = _mm_srli_epi32 (b, 8); // tmp1 = b >> 8 + b = _mm_add_epi32(b, tmp1); // b = b + (b >> 8) + + // b = (b + (b >> 16)) & 0x0000003F; + tmp1 = _mm_srli_epi32 (b, 16); // b >> 16 + b = _mm_add_epi32(b, tmp1); // b + (b >> 16) + b = _mm_and_si128(b, m4); // (b >> 16) & 0x0000003F; + + mcnt = _mm_add_epi32(mcnt, b); // mcnt += b + + } while (block < block_end); + + _mm_store_si128((__m128i*)tcnt, mcnt); + + return tcnt[0] + tcnt[1] + tcnt[2] + tcnt[3]; +} + +int main(void) +{ + int i, N = 100000000; + uint64_t *x, cnt; + clock_t t; + int c = 1; + + x = (uint64_t*)calloc(N, 8); + srand48(11); + for (i = 0; i < N; ++i) + x[i] = (uint64_t)lrand48() << 32 ^ lrand48(); + + fprintf(stderr, "\n===> Calculate # of 1 in an integer (popcount) <===\n"); + + t = clock(); cnt = 0; + for (i = 0; i < N; ++i) cnt += kbi_popcount64(x[i]); + fprintf(stderr, "%20s\t%20ld\t%10.6f\n", "kbit", (long)cnt, (double)(clock() - t) / CLOCKS_PER_SEC); + + t = clock(); cnt = 0; + for (i = 0; i < N; ++i) cnt += bt1_pop64(x[i]); + fprintf(stderr, "%20s\t%20ld\t%10.6f\n", "wiki-popcount_2", (long)cnt, (double)(clock() - t) / CLOCKS_PER_SEC); + + t = clock(); cnt = 0; + for (i = 0; i < N; ++i) cnt += __builtin_popcountl(x[i]); + fprintf(stderr, "%20s\t%20ld\t%10.6f\n", "__builtin_popcountl", (long)cnt, (double)(clock() - t) / CLOCKS_PER_SEC); + + t = clock(); cnt = 0; + cnt += sse2_bit_count32((__m128i*)x, (__m128i*)(x+N)); + fprintf(stderr, "%20s\t%20ld\t%10.6f\n", "SSE2-32bit", (long)cnt, (double)(clock() - t) / CLOCKS_PER_SEC); + + fprintf(stderr, "\n===> Count '%c' in 2-bit encoded integers <===\n", "ACGT"[c]); + + t = clock(); cnt = 0; + for (i = 0; i < N; ++i) cnt += kbi_DNAcount64(x[i], c); + fprintf(stderr, "%20s\t%20ld\t%10.6f\n", "kbit", (long)cnt, (double)(clock() - t) / CLOCKS_PER_SEC); + + t = clock(); cnt = 0; + for (i = 0; i < N; ++i) cnt += bt1_countInU64(x[i], c); + fprintf(stderr, "%20s\t%20ld\t%10.6f\n", "bowtie1", (long)cnt, (double)(clock() - t) / CLOCKS_PER_SEC); + + fprintf(stderr, "\n"); + free(x); + return 0; +} diff --git a/web/server/h2o/libh2o/deps/klib/test/kbtree_test.c b/web/server/h2o/libh2o/deps/klib/test/kbtree_test.c new file mode 100644 index 00000000..8e106876 --- /dev/null +++ b/web/server/h2o/libh2o/deps/klib/test/kbtree_test.c @@ -0,0 +1,94 @@ +#include +#include +#include +#include +#include +#include + +typedef const char *str_t; + +#include "kbtree.h" +KBTREE_INIT(int, uint32_t, kb_generic_cmp) +KBTREE_INIT(str, str_t, kb_str_cmp) + +static int data_size = 5000000; +static unsigned *int_data; +static char **str_data; + +void ht_init_data() +{ + int i; + char buf[256]; + printf("--- generating data... "); + srand48(11); + int_data = (unsigned*)calloc(data_size, sizeof(unsigned)); + str_data = (char**)calloc(data_size, sizeof(char*)); + for (i = 0; i < data_size; ++i) { + int_data[i] = (unsigned)(data_size * drand48() / 4) * 271828183u; + sprintf(buf, "%x", int_data[i]); + str_data[i] = strdup(buf); + } + printf("done!\n"); +} +void ht_destroy_data() +{ + int i; + for (i = 0; i < data_size; ++i) free(str_data[i]); + free(str_data); free(int_data); +} + +void ht_khash_int() +{ + int i; + unsigned *data = int_data; + uint32_t *l, *u; + kbtree_t(int) *h; + + h = kb_init(int, KB_DEFAULT_SIZE); + for (i = 0; i < data_size; ++i) { + if (kb_get(int, h, data[i]) == 0) kb_put(int, h, data[i]); + else kb_del(int, h, data[i]); + } + printf("[ht_khash_int] size: %d\n", kb_size(h)); + if (1) { + int cnt = 0; + uint32_t x, y; + kb_interval(int, h, 2174625464u, &l, &u); + printf("interval for 2174625464: (%u, %u)\n", l? *l : 0, u? *u : 0); +#define traverse_f(p) { if (cnt == 0) y = *p; ++cnt; } + __kb_traverse(uint32_t, h, traverse_f); + __kb_get_first(uint32_t, h, x); + printf("# of elements from traversal: %d\n", cnt); + printf("first element: %d == %d\n", x, y); + } + __kb_destroy(h); +} +void ht_khash_str() +{ + int i; + char **data = str_data; + kbtree_t(str) *h; + + h = kb_init(str, KB_DEFAULT_SIZE); + for (i = 0; i < data_size; ++i) { + if (kb_get(str, h, data[i]) == 0) kb_put(str, h, data[i]); + else kb_del(str, h, data[i]); + } + printf("[ht_khash_int] size: %d\n", kb_size(h)); + __kb_destroy(h); +} +void ht_timing(void (*f)(void)) +{ + clock_t t = clock(); + (*f)(); + printf("[ht_timing] %.3lf sec\n", (double)(clock() - t) / CLOCKS_PER_SEC); +} +int main(int argc, char *argv[]) +{ + if (argc > 1) data_size = atoi(argv[1]); + ht_init_data(); + ht_timing(ht_khash_int); + ht_timing(ht_khash_str); + ht_destroy_data(); + return 0; +} diff --git a/web/server/h2o/libh2o/deps/klib/test/kgraph_test.c b/web/server/h2o/libh2o/deps/klib/test/kgraph_test.c new file mode 100644 index 00000000..3da1cd71 --- /dev/null +++ b/web/server/h2o/libh2o/deps/klib/test/kgraph_test.c @@ -0,0 +1,26 @@ +#include +#include "kgraph.h" + +KHASH_INIT2(e32, extern, uint32_t, int, 1, kh_int_hash_func, kh_int_hash_equal) + +typedef struct { + int i; + khash_t(e32) *_arc; +} vertex_t; + +KGRAPH_INIT(g, extern, vertex_t, int, e32) +KGRAPH_PRINT(g, extern) + +int main() +{ + int *pb, *pe; + kgraph_t(g) *g; + g = kg_init_g(); + kg_put_a_g(g, 10, 20, 0, &pb, &pe); + kg_put_a_g(g, 20, 30, 0, &pb, &pe); + kg_put_a_g(g, 30, 10, 1, &pb, &pe); + kg_del_v_g(g, 20); + kg_print_g(g); + kg_destroy_g(g); + return 0; +} diff --git a/web/server/h2o/libh2o/deps/klib/test/khash_keith.c b/web/server/h2o/libh2o/deps/klib/test/khash_keith.c new file mode 100644 index 00000000..ddd755ac --- /dev/null +++ b/web/server/h2o/libh2o/deps/klib/test/khash_keith.c @@ -0,0 +1,95 @@ +/* + * This is an optimized version of the following C++ program: + * + * http://keithlea.com/javabench/src/cpp/hash.cpp + * + * Keith in his benchmark (http://keithlea.com/javabench/data) showed that the + * Java implementation is twice as fast as the C++ version. In fact, this is + * only because the C++ implementation is substandard. Most importantly, Keith + * is using "sprintf()" to convert an integer to a string, which is known to be + * extremely inefficient. + */ +#include +#include "khash.h" +KHASH_MAP_INIT_STR(str, int) + +inline void int2str(int c, int base, char *ret) +{ + const char *tab = "0123456789abcdef"; + if (c == 0) ret[0] = '0', ret[1] = 0; + else { + int l, x, y; + char buf[16]; + for (l = 0, x = c < 0? -c : c; x > 0; x /= base) buf[l++] = tab[x%base]; + if (c < 0) buf[l++] = '-'; + for (x = l - 1, y = 0; x >= 0; --x) ret[y++] = buf[x]; + ret[y] = 0; + } +} + +#ifndef _USE_STRDUP +#define BLOCK_SIZE 0x100000 +int main(int argc, char *argv[]) +{ + char **mem = 0; + int i, l, n = 1000000, ret, block_end = 0, curr = 0, c = 0; + khash_t(str) *h; + h = kh_init(str); + if (argc > 1) n = atoi(argv[1]); + mem = malloc(sizeof(void*)); + mem[0] = malloc(BLOCK_SIZE); // memory buffer to avoid memory fragmentation + curr = block_end = 0; + for (i = 1; i <= n; ++i) { + char buf[16]; + int2str(i, 16, buf); + khint_t k = kh_put(str, h, buf, &ret); + l = strlen(buf) + 1; + if (block_end + l > BLOCK_SIZE) { + ++curr; block_end = 0; + mem = realloc(mem, (curr + 1) * sizeof(void*)); + mem[curr] = malloc(BLOCK_SIZE); + } + memcpy(mem[curr] + block_end, buf, l); + kh_key(h, k) = mem[curr] + block_end; + block_end += l; + kh_val(h, k) = i; + } + for (i = 1; i <= n; ++i) { + char buf[16]; + int2str(i, 10, buf); + khint_t k = kh_get(str, h, buf); + if (k != kh_end(h)) ++c; + } + printf("%d\n", c); + for (ret = 0; ret <= curr; ++ret) free(mem[ret]); + free(mem); + kh_destroy(str, h); + return 0; +} +#else // _USE_STRDUP +int main(int argc, char *argv[]) +{ + int i, l, n = 1000000, ret, c = 0; + khash_t(str) *h; + khint_t k; + h = kh_init(str); + if (argc > 1) n = atoi(argv[1]); + for (i = 1; i <= n; ++i) { + char buf[16]; + int2str(i, 16, buf); + k = kh_put(str, h, strdup(buf), &ret); + kh_val(h, k) = i; + } + for (i = 1; i <= n; ++i) { + char buf[16]; + int2str(i, 10, buf); + k = kh_get(str, h, buf); + if (k != kh_end(h)) ++c; + } + for (k = kh_begin(h); k != kh_end(h); ++k) // explicitly freeing memory takes 10-20% CPU time. + if (kh_exist(h, k)) free((char*)kh_key(h, k)); + printf("%d\n", c); + kh_destroy(str, h); + return 0; +} +#endif diff --git a/web/server/h2o/libh2o/deps/klib/test/khash_keith2.c b/web/server/h2o/libh2o/deps/klib/test/khash_keith2.c new file mode 100644 index 00000000..b9df9b7c --- /dev/null +++ b/web/server/h2o/libh2o/deps/klib/test/khash_keith2.c @@ -0,0 +1,67 @@ +/* + * This is an optimized version of the following C++ program: + * + * http://keithlea.com/javabench/src/cpp/hash.cpp + * + * Keith in his benchmark (http://keithlea.com/javabench/data) showed that the + * Java implementation is twice as fast as the C++ version. In fact, this is + * only because the C++ implementation is substandard. Most importantly, Keith + * is using "sprintf()" to convert an integer to a string, which is known to be + * extremely inefficient. + */ +#include +#include "khash.h" +KHASH_MAP_INIT_STR(str, int) + +inline void int2str(int c, int base, char *ret) +{ + const char *tab = "0123456789abcdef"; + if (c == 0) ret[0] = '0', ret[1] = 0; + else { + int l, x, y; + char buf[16]; + for (l = 0, x = c < 0? -c : c; x > 0; x /= base) buf[l++] = tab[x%base]; + if (c < 0) buf[l++] = '-'; + for (x = l - 1, y = 0; x >= 0; --x) ret[y++] = buf[x]; + ret[y] = 0; + } +} + +int main(int argc, char *argv[]) +{ + int i, l, n = 1000, ret; + khash_t(str) *h, *h2; + khint_t k; + h = kh_init(str); + h2 = kh_init(str); + if (argc > 1) n = atoi(argv[1]); + for (i = 0; i < 10000; ++i) { + char buf[32]; + strcpy(buf, "foo_"); + int2str(i, 10, buf+4); + k = kh_put(str, h, strdup(buf), &ret); + kh_val(h, k) = i; + } + for (i = 0; i < n; ++i) { + for (k = kh_begin(h); k != kh_end(h); ++k) { + if (kh_exist(h, k)) { + khint_t k2 = kh_put(str, h2, kh_key(h, k), &ret); + if (ret) { // absent + kh_key(h2, k2) = strdup(kh_key(h, k)); + kh_val(h2, k2) = kh_val(h, k); + } else kh_val(h2, k2) += kh_val(h, k); + } + } + } + k = kh_get(str, h, "foo_1"); printf("%d", kh_val(h, k)); + k = kh_get(str, h, "foo_9999"); printf(" %d", kh_val(h, k)); + k = kh_get(str, h2, "foo_1"); printf(" %d", kh_val(h2, k)); + k = kh_get(str, h2, "foo_9999"); printf(" %d\n", kh_val(h2, k)); + for (k = kh_begin(h); k != kh_end(h); ++k) + if (kh_exist(h, k)) free((char*)kh_key(h, k)); + for (k = kh_begin(h2); k != kh_end(h2); ++k) + if (kh_exist(h2, k)) free((char*)kh_key(h2, k)); + kh_destroy(str, h); + kh_destroy(str, h2); + return 0; +} diff --git a/web/server/h2o/libh2o/deps/klib/test/khash_test.c b/web/server/h2o/libh2o/deps/klib/test/khash_test.c new file mode 100644 index 00000000..8d6687ff --- /dev/null +++ b/web/server/h2o/libh2o/deps/klib/test/khash_test.c @@ -0,0 +1,141 @@ +#include +#include +#include +#include +#include + +#include "khash.h" +KHASH_SET_INIT_STR(str) +KHASH_MAP_INIT_INT(int, unsigned char) + +typedef struct { + unsigned key; + unsigned char val; +} int_unpack_t; + +typedef struct { + unsigned key; + unsigned char val; +} __attribute__ ((__packed__)) int_packed_t; + +#define hash_eq(a, b) ((a).key == (b).key) +#define hash_func(a) ((a).key) + +KHASH_INIT(iun, int_unpack_t, char, 0, hash_func, hash_eq) +KHASH_INIT(ipk, int_packed_t, char, 0, hash_func, hash_eq) + +static int data_size = 5000000; +static unsigned *int_data; +static char **str_data; + +void ht_init_data() +{ + int i; + char buf[256]; + khint32_t x = 11; + printf("--- generating data... "); + int_data = (unsigned*)calloc(data_size, sizeof(unsigned)); + str_data = (char**)calloc(data_size, sizeof(char*)); + for (i = 0; i < data_size; ++i) { + int_data[i] = (unsigned)(data_size * ((double)x / UINT_MAX) / 4) * 271828183u; + sprintf(buf, "%x", int_data[i]); + str_data[i] = strdup(buf); + x = 1664525L * x + 1013904223L; + } + printf("done!\n"); +} + +void ht_destroy_data() +{ + int i; + for (i = 0; i < data_size; ++i) free(str_data[i]); + free(str_data); free(int_data); +} + +void ht_khash_int() +{ + int i, ret; + unsigned *data = int_data; + khash_t(int) *h; + unsigned k; + + h = kh_init(int); + for (i = 0; i < data_size; ++i) { + k = kh_put(int, h, data[i], &ret); + kh_val(h, k) = i&0xff; + if (!ret) kh_del(int, h, k); + } + printf("[ht_khash_int] size: %u\n", kh_size(h)); + kh_destroy(int, h); +} + +void ht_khash_str() +{ + int i, ret; + char **data = str_data; + khash_t(str) *h; + unsigned k; + + h = kh_init(str); + for (i = 0; i < data_size; ++i) { + k = kh_put(str, h, data[i], &ret); + if (!ret) kh_del(str, h, k); + } + printf("[ht_khash_int] size: %u\n", kh_size(h)); + kh_destroy(str, h); +} + +void ht_khash_unpack() +{ + int i, ret; + unsigned *data = int_data; + khash_t(iun) *h; + unsigned k; + + h = kh_init(iun); + for (i = 0; i < data_size; ++i) { + int_unpack_t x; + x.key = data[i]; x.val = i&0xff; + k = kh_put(iun, h, x, &ret); + if (!ret) kh_del(iun, h, k); + } + printf("[ht_khash_unpack] size: %u (sizeof=%ld)\n", kh_size(h), sizeof(int_unpack_t)); + kh_destroy(iun, h); +} + +void ht_khash_packed() +{ + int i, ret; + unsigned *data = int_data; + khash_t(ipk) *h; + unsigned k; + + h = kh_init(ipk); + for (i = 0; i < data_size; ++i) { + int_packed_t x; + x.key = data[i]; x.val = i&0xff; + k = kh_put(ipk, h, x, &ret); + if (!ret) kh_del(ipk, h, k); + } + printf("[ht_khash_packed] size: %u (sizeof=%ld)\n", kh_size(h), sizeof(int_packed_t)); + kh_destroy(ipk, h); +} + +void ht_timing(void (*f)(void)) +{ + clock_t t = clock(); + (*f)(); + printf("[ht_timing] %.3lf sec\n", (double)(clock() - t) / CLOCKS_PER_SEC); +} + +int main(int argc, char *argv[]) +{ + if (argc > 1) data_size = atoi(argv[1]); + ht_init_data(); + ht_timing(ht_khash_int); + ht_timing(ht_khash_str); + ht_timing(ht_khash_unpack); + ht_timing(ht_khash_packed); + ht_destroy_data(); + return 0; +} diff --git a/web/server/h2o/libh2o/deps/klib/test/klist_test.c b/web/server/h2o/libh2o/deps/klib/test/klist_test.c new file mode 100644 index 00000000..cd13813d --- /dev/null +++ b/web/server/h2o/libh2o/deps/klib/test/klist_test.c @@ -0,0 +1,19 @@ +#include +#include "klist.h" + +#define __int_free(x) +KLIST_INIT(32, int, __int_free) + +int main() +{ + klist_t(32) *kl; + kliter_t(32) *p; + kl = kl_init(32); + *kl_pushp(32, kl) = 1; + *kl_pushp(32, kl) = 10; + kl_shift(32, kl, 0); + for (p = kl_begin(kl); p != kl_end(kl); p = kl_next(p)) + printf("%d\n", kl_val(p)); + kl_destroy(32, kl); + return 0; +} diff --git a/web/server/h2o/libh2o/deps/klib/test/kmin_test.c b/web/server/h2o/libh2o/deps/klib/test/kmin_test.c new file mode 100644 index 00000000..33ccd1cb --- /dev/null +++ b/web/server/h2o/libh2o/deps/klib/test/kmin_test.c @@ -0,0 +1,48 @@ +#include +#include +#include "kmath.h" + +static int n_evals; + +double f_Chebyquad(int n, double *x, void *data) +{ + int i, j; + double y[20][20], f; + int np, iw; + double sum; + for (j = 0; j != n; ++j) { + y[0][j] = 1.; + y[1][j] = 2. * x[j] - 1.; + } + for (i = 1; i != n; ++i) + for (j = 0; j != n; ++j) + y[i+1][j] = 2. * y[1][j] * y[i][j] - y[i-1][j]; + f = 0.; + np = n + 1; + iw = 1; + for (i = 0; i != np; ++i) { + sum = 0.; + for (j = 0; j != n; ++j) sum += y[i][j]; + sum /= n; + if (iw > 0) sum += 1. / ((i - 1) * (i + 1)); + iw = -iw; + f += sum * sum; + } + ++n_evals; + return f; +} + +int main() +{ + double x[20], y; + int n, i; + printf("\nMinimizer: Hooke-Jeeves\n"); + for (n = 2; n <= 8; n += 2) { + for (i = 0; i != n; ++i) x[i] = (double)(i + 1) / n; + n_evals = 0; + y = kmin_hj(f_Chebyquad, n, x, 0, KMIN_RADIUS, KMIN_EPS, KMIN_MAXCALL); + printf("n=%d,min=%.8lg,n_evals=%d\n", n, y, n_evals); + } + printf("\n"); + return 0; +} diff --git a/web/server/h2o/libh2o/deps/klib/test/kseq_bench.c b/web/server/h2o/libh2o/deps/klib/test/kseq_bench.c new file mode 100644 index 00000000..eeda13f7 --- /dev/null +++ b/web/server/h2o/libh2o/deps/klib/test/kseq_bench.c @@ -0,0 +1,69 @@ +#include +#include +#include +#include +#include +#include "kseq.h" + +#define BUF_SIZE 4096 +KSTREAM_INIT(gzFile, gzread, BUF_SIZE) + +int main(int argc, char *argv[]) +{ + gzFile fp; + clock_t t; + if (argc == 1) { + fprintf(stderr, "Usage: kseq_bench \n"); + return 1; + } + { + uint8_t *buf = malloc(BUF_SIZE); + fp = gzopen(argv[1], "r"); + t = clock(); + while (gzread(fp, buf, BUF_SIZE) > 0); + fprintf(stderr, "[gzread] %.2f sec\n", (float)(clock() - t) / CLOCKS_PER_SEC); + gzclose(fp); + free(buf); + } + { + kstream_t *ks; + fp = gzopen(argv[1], "r"); + ks = ks_init(fp); + t = clock(); + while (ks_getc(ks) >= 0); + fprintf(stderr, "[ks_getc] %.2f sec\n", (float)(clock() - t) / CLOCKS_PER_SEC); + ks_destroy(ks); + gzclose(fp); + } + { + kstream_t *ks; + kstring_t *s; + int dret; + s = calloc(1, sizeof(kstring_t)); + fp = gzopen(argv[1], "r"); + ks = ks_init(fp); + t = clock(); + while (ks_getuntil(ks, '\n', s, &dret) >= 0); + fprintf(stderr, "[ks_getuntil] %.2f sec\n", (float)(clock() - t) / CLOCKS_PER_SEC); + ks_destroy(ks); + gzclose(fp); + free(s->s); free(s); + } + if (argc == 2) { + fp = gzopen(argv[1], "r"); + t = clock(); + while (gzgetc(fp) >= 0); + fprintf(stderr, "[gzgetc] %.2f sec\n", (float)(clock() - t) / CLOCKS_PER_SEC); + gzclose(fp); + } + if (argc == 2) { + char *buf = malloc(BUF_SIZE); + fp = gzopen(argv[1], "r"); + t = clock(); + while (gzgets(fp, buf, BUF_SIZE) > 0); + fprintf(stderr, "[gzgets] %.2f sec\n", (float)(clock() - t) / CLOCKS_PER_SEC); + gzclose(fp); + free(buf); + } + return 0; +} diff --git a/web/server/h2o/libh2o/deps/klib/test/kseq_bench2.c b/web/server/h2o/libh2o/deps/klib/test/kseq_bench2.c new file mode 100644 index 00000000..b4154583 --- /dev/null +++ b/web/server/h2o/libh2o/deps/klib/test/kseq_bench2.c @@ -0,0 +1,43 @@ +#include +#include +#include +#include +#include +#include "kseq.h" +KSTREAM_INIT(int, read, 4096) + +#define BUF_SIZE 65536 + +int main(int argc, char *argv[]) +{ + clock_t t; + if (argc == 1) { + fprintf(stderr, "Usage: %s \n", argv[0]); + return 1; + } + { + FILE *fp; + char *s; + t = clock(); + s = malloc(BUF_SIZE); + fp = fopen(argv[1], "r"); + while (fgets(s, BUF_SIZE, fp)); + fclose(fp); + fprintf(stderr, "[fgets] %.2f sec\n", (float)(clock() - t) / CLOCKS_PER_SEC); + } + { + int fd, dret; + kstream_t *ks; + kstring_t s; + t = clock(); + s.l = s.m = 0; s.s = 0; + fd = open(argv[1], O_RDONLY); + ks = ks_init(fd); + while (ks_getuntil(ks, '\n', &s, &dret) >= 0); + free(s.s); + ks_destroy(ks); + close(fd); + fprintf(stderr, "[kstream] %.2f sec\n", (float)(clock() - t) / CLOCKS_PER_SEC); + } + return 0; +} diff --git a/web/server/h2o/libh2o/deps/klib/test/kseq_test.c b/web/server/h2o/libh2o/deps/klib/test/kseq_test.c new file mode 100644 index 00000000..0304dea3 --- /dev/null +++ b/web/server/h2o/libh2o/deps/klib/test/kseq_test.c @@ -0,0 +1,27 @@ +#include +#include +#include "kseq.h" +KSEQ_INIT(gzFile, gzread) + +int main(int argc, char *argv[]) +{ + gzFile fp; + kseq_t *seq; + int l; + if (argc == 1) { + fprintf(stderr, "Usage: %s \n", argv[0]); + return 1; + } + fp = gzopen(argv[1], "r"); + seq = kseq_init(fp); + while ((l = kseq_read(seq)) >= 0) { + printf("name: %s\n", seq->name.s); + if (seq->comment.l) printf("comment: %s\n", seq->comment.s); + printf("seq: %s\n", seq->seq.s); + if (seq->qual.l) printf("qual: %s\n", seq->qual.s); + } + printf("return value: %d\n", l); + kseq_destroy(seq); + gzclose(fp); + return 0; +} diff --git a/web/server/h2o/libh2o/deps/klib/test/kseq_test.dat b/web/server/h2o/libh2o/deps/klib/test/kseq_test.dat new file mode 100644 index 00000000..b774ae28 --- /dev/null +++ b/web/server/h2o/libh2o/deps/klib/test/kseq_test.dat @@ -0,0 +1,12 @@ +>1 +acgtacgtacgtagc +>2 test +acgatcgatc +@3 test2 +cgctagcatagc +cgatatgactta ++ +78wo82usd980 +d88fau + +238ud8 diff --git a/web/server/h2o/libh2o/deps/klib/test/ksort_test.c b/web/server/h2o/libh2o/deps/klib/test/ksort_test.c new file mode 100644 index 00000000..92c7d3d1 --- /dev/null +++ b/web/server/h2o/libh2o/deps/klib/test/ksort_test.c @@ -0,0 +1,104 @@ +#include +#include +#include +#include +#include "ksort.h" + +KSORT_INIT_GENERIC(int) + +int main(int argc, char *argv[]) +{ + int i, N = 10000000; + int *array, x; + clock_t t1, t2; + if (argc > 1) N = atoi(argv[1]); + array = (int*)malloc(sizeof(int) * N); + + srand48(11); + for (i = 0; i < N; ++i) array[i] = (int)lrand48(); + t1 = clock(); + x = ks_ksmall(int, N, array, 10500); + t2 = clock(); + fprintf(stderr, "ksmall [%d]: %.3lf\n", x, (double)(t2-t1)/CLOCKS_PER_SEC); + + srand48(11); + for (i = 0; i < N; ++i) array[i] = (int)lrand48(); + t1 = clock(); + ks_introsort(int, N, array); + t2 = clock(); + fprintf(stderr, "introsort [%d]: %.3lf\n", array[10500], (double)(t2-t1)/CLOCKS_PER_SEC); + for (i = 0; i < N-1; ++i) { + if (array[i] > array[i+1]) { + fprintf(stderr, "Bug in introsort!\n"); + exit(1); + } + } + +#ifndef _ALIGNED_ONLY + { // test unaligned ksmall + srand48(11); + unsigned char *a; + int *b; + a = malloc(N * sizeof(int) + 1); + b = (int*)(a + 1); + for (i = 0; i < N; ++i) b[i] = (int)lrand48(); + t1 = clock(); + ks_introsort(int, N, b); + t2 = clock(); + fprintf(stderr, "introsort [%d]: %.3lf (unaligned: 0x%lx) \n", b[10500], (double)(t2-t1)/CLOCKS_PER_SEC, (size_t)b); + } +#endif + + t1 = clock(); + ks_introsort(int, N, array); + t2 = clock(); + fprintf(stderr, "introsort (sorted): %.3lf\n", (double)(t2-t1)/CLOCKS_PER_SEC); + + srand48(11); + for (i = 0; i < N; ++i) array[i] = (int)lrand48(); + t1 = clock(); + ks_combsort(int, N, array); + t2 = clock(); + fprintf(stderr, "combsort: %.3lf\n", (double)(t2-t1)/CLOCKS_PER_SEC); + for (i = 0; i < N-1; ++i) { + if (array[i] > array[i+1]) { + fprintf(stderr, "Bug in combsort!\n"); + exit(1); + } + } + + srand48(11); + for (i = 0; i < N; ++i) array[i] = (int)lrand48(); + t1 = clock(); + ks_mergesort(int, N, array, 0); + t2 = clock(); + fprintf(stderr, "mergesort: %.3lf\n", (double)(t2-t1)/CLOCKS_PER_SEC); + for (i = 0; i < N-1; ++i) { + if (array[i] > array[i+1]) { + fprintf(stderr, "Bug in mergesort!\n"); + exit(1); + } + } + + t1 = clock(); + ks_mergesort(int, N, array, 0); + t2 = clock(); + fprintf(stderr, "mergesort (sorted): %.3lf\n", (double)(t2-t1)/CLOCKS_PER_SEC); + + srand48(11); + for (i = 0; i < N; ++i) array[i] = (int)lrand48(); + t1 = clock(); + ks_heapmake(int, N, array); + ks_heapsort(int, N, array); + t2 = clock(); + fprintf(stderr, "heapsort: %.3lf\n", (double)(t2-t1)/CLOCKS_PER_SEC); + for (i = 0; i < N-1; ++i) { + if (array[i] > array[i+1]) { + fprintf(stderr, "Bug in heapsort!\n"); + exit(1); + } + } + + free(array); + return 0; +} diff --git a/web/server/h2o/libh2o/deps/klib/test/ksort_test.cc b/web/server/h2o/libh2o/deps/klib/test/ksort_test.cc new file mode 100644 index 00000000..8950d806 --- /dev/null +++ b/web/server/h2o/libh2o/deps/klib/test/ksort_test.cc @@ -0,0 +1,997 @@ +#include +#include +#include +#include +#include + +#include "ksort.h" +KSORT_INIT_GENERIC(int) + +using namespace std; + +/********************************** + * BEGIN OF PAUL'S IMPLEMENTATION * + **********************************/ + +/* Attractive Chaos: I have added inline where necessary. */ + +/* +Copyright (c) 2004 Paul Hsieh +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + Neither the name of sorttest nor the names of its contributors may be + used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +*/ + +/* + +Recommended flags: +------------------ + +Intel C/C++: +icl /O2 /G6 /Qaxi /Qxi /Qip sorttest.c + +WATCOM C/C++: +wcl386 /otexan /6r sorttest.c + +GCC: +gcc -O3 -mcpu=athlon-xp -march=athlon-xp sorttest.c + +MSVC: +cl /O2 /Ot /Og /G6 sorttest.c + +*/ + +static inline void sort2 (int * numbers) { +int tmp; + + if (numbers[0] <= numbers[1]) return; + tmp = numbers[0]; + numbers[0] = numbers[1]; + numbers[1] = tmp; +} + +static inline void sort3 (int * numbers) { +int tmp; + + if (numbers[0] <= numbers[1]) { + if (numbers[1] <= numbers[2]) return; + if (numbers[2] <= numbers[0]) { + tmp = numbers[0]; + numbers[0] = numbers[2]; + numbers[2] = numbers[1]; + numbers[1] = tmp; + return; + } + tmp = numbers[1]; + } else { + tmp = numbers[0]; + if (numbers[0] <= numbers[2]) { + numbers[0] = numbers[1]; + numbers[1] = tmp; + return; + } + if (numbers[2] <= numbers[1]) { + numbers[0] = numbers[2]; + numbers[2] = tmp; + return; + } + numbers[0] = numbers[1]; + } + numbers[1] = numbers[2]; + numbers[2] = tmp; +} + +static inline void sort4 (int * num) { +int tmp; + if (num[0] < num[1]) { + if (num[1] < num[2]) { + if (num[1] < num[3]) { + if (num[2] >= num[3]) { + tmp = num[2]; + num[2] = num[3]; + num[3] = tmp; + } + } else { + tmp = num[1]; + if (num[0] < num[3]) { + num[1] = num[3]; + } else { + num[1] = num[0]; + num[0] = num[3]; + } + num[3] = num[2]; + num[2] = tmp; + } + } else { + if (num[0] < num[2]) { + if (num[2] < num[3]) { + if (num[1] < num[3]) { + tmp = num[1]; + } else { + tmp = num[3]; + num[3] = num[1]; + } + num[1] = num[2]; + num[2] = tmp; + } else { + if (num[0] < num[3]) { + tmp = num[3]; + } else { + tmp = num[0]; + num[0] = num[3]; + } + num[3] = num[1]; + num[1] = tmp; + } + } else { + if (num[0] < num[3]) { + tmp = num[0]; + num[0] = num[2]; + if (num[1] < num[3]) { + num[2] = num[1]; + } else { + num[2] = num[3]; + num[3] = num[1]; + } + num[1] = tmp; + } else { + if (num[2] < num[3]) { + tmp = num[0]; + num[0] = num[2]; + num[2] = tmp; + tmp = num[1]; + num[1] = num[3]; + } else { + tmp = num[1]; + num[1] = num[2]; + num[2] = num[0]; + num[0] = num[3]; + } + num[3] = tmp; + } + } + } + } else { + tmp = num[0]; + if (tmp < num[2]) { + if (tmp < num[3]) { + num[0] = num[1]; + num[1] = tmp; + if (num[2] >= num[3]) { + tmp = num[2]; + num[2] = num[3]; + num[3] = tmp; + } + } else { + if (num[1] < num[3]) { + num[0] = num[1]; + num[1] = num[3]; + } else { + num[0] = num[3]; + } + num[3] = num[2]; + num[2] = tmp; + } + } else { + if (num[1] < num[2]) { + if (num[2] < num[3]) { + num[0] = num[1]; + num[1] = num[2]; + if (tmp < num[3]) { + num[2] = tmp; + } else { + num[2] = num[3]; + num[3] = tmp; + } + } else { + if (num[1] < num[3]) { + num[0] = num[1]; + num[1] = num[3]; + } else { + num[0] = num[3]; + } + num[3] = tmp; + } + } else { + if (num[1] < num[3]) { + num[0] = num[2]; + if (tmp < num[3]) { + num[2] = tmp; + } else { + num[2] = num[3]; + num[3] = tmp; + } + } else { + if (num[2] < num[3]) { + num[0] = num[2]; + num[2] = num[1]; + num[1] = num[3]; + num[3] = tmp; + } else { + num[0] = num[3]; + num[3] = tmp; + tmp = num[1]; + num[1] = num[2]; + num[2] = tmp; + } + } + } + } + } +} + +static inline void sortAlt2 (int * numbers, int * altNumbers) { + if (numbers[0] <= numbers[1]) { + altNumbers[0] = numbers[0]; + altNumbers[1] = numbers[1]; + } else { + altNumbers[0] = numbers[1]; + altNumbers[1] = numbers[0]; + } +} + +static inline void sortAlt3 (int * numbers, int * altNumbers) { + if (numbers[0] <= numbers[1]) { + if (numbers[1] <= numbers[2]) { + altNumbers[0] = numbers[0]; + altNumbers[1] = numbers[1]; + altNumbers[2] = numbers[2]; + } else if (numbers[2] <= numbers[0]) { + altNumbers[0] = numbers[2]; + altNumbers[1] = numbers[0]; + altNumbers[2] = numbers[1]; + } else { + altNumbers[0] = numbers[0]; + altNumbers[1] = numbers[2]; + altNumbers[2] = numbers[1]; + } + } else { + if (numbers[0] <= numbers[2]) { + altNumbers[0] = numbers[1]; + altNumbers[1] = numbers[0]; + altNumbers[2] = numbers[2]; + } else if (numbers[2] <= numbers[1]) { + altNumbers[0] = numbers[2]; + altNumbers[1] = numbers[1]; + altNumbers[2] = numbers[0]; + } else { + altNumbers[0] = numbers[1]; + altNumbers[1] = numbers[2]; + altNumbers[2] = numbers[0]; + } + } +} + +/* + * Insert Sort + */ + +inline void insertSort (int numbers[], int qty) { +int i, j, idx, q4; +int tmp; + + if (qty <= 4) { + if (qty == 4) sort4 (numbers); + else if (qty == 3) sort3 (numbers); + else if (qty == 2) sort2 (numbers); + return; + } + + q4 = qty - 4; + + for (i=0; i < q4; i++) { + idx = i; + for (j=i+1; j < qty; j++) { + if (numbers[j] < numbers[idx]) idx = j; + } + if (idx != i) { + tmp = numbers[idx]; + numbers[idx] = numbers[i]; + numbers[i] = tmp; + } + } + + sort4 (numbers + q4); +} + +/* + * Heap Sort + */ + +/* Assure the heap property for entries from top to last */ +static void siftDown (int numbers[], int top, int last) { +int tmp = numbers[top]; +int maxIdx = top; + + while (last >= (maxIdx += maxIdx)) { + + /* This is where the comparison occurrs and where a sufficiently + good compiler can use a computed conditional result rather + than using control logic. */ + if (maxIdx != last && numbers[maxIdx] < numbers[maxIdx + 1]) maxIdx++; + + if (tmp >= numbers[maxIdx]) break; + numbers[top] = numbers[maxIdx]; + top = maxIdx; + } + numbers[top] = tmp; +} + +/* Peel off the top siftDown operation since its parameters are trivial to + fill in directly (and this saves us some moves.) */ +static void siftDown0 (int numbers[], int last) { +int tmp; + + if (numbers[0] < numbers[1]) { + tmp = numbers[1]; + numbers[1] = numbers[0]; + siftDown (numbers, 1, last); + } else { + tmp = numbers[0]; + } + numbers[0] = numbers[last]; + numbers[last] = tmp; +} + +void heapSort (int numbers[], int qty) { +int i; + + if (qty <= 4) { + if (qty == 4) sort4 (numbers); + else if (qty == 3) sort3 (numbers); + else if (qty == 2) sort2 (numbers); + return; + } + + i = qty / 2; + /* Enforce the heap property for each position in the tree */ + for ( qty--; i > 0; i--) siftDown (numbers, i, qty); + for (i = qty; i > 0; i--) siftDown0 (numbers, i); +} + +/* + * Quick Sort + */ + +static int medianOf3 (int * numbers, int i, int j) { +int tmp; + + if (numbers[0] <= numbers[i]) { + if (numbers[j] <= numbers[0]) return numbers[0]; /* j 0 i */ + if (numbers[i] <= numbers[j]) j = i; /* 0 i j */ + /* 0 j i */ + } else { + if (numbers[0] <= numbers[j]) return numbers[0]; /* i 0 j */ + if (numbers[j] <= numbers[i]) j = i; /* j i 0 */ + /* i j 0 */ + } + tmp = numbers[j]; + numbers[j] = numbers[0]; + numbers[0] = tmp; + return tmp; +} + +static void quickSortRecurse (int * numbers, int left, int right) { +int pivot, lTmp, rTmp; + + qsrStart:; + +#if defined(__GNUC__) + if (right <= left + 8) { + insertSort (numbers + left, right - left + 1); + return; + } +#else + if (right <= left + 3) { + if (right == left + 1) { + sort2 (numbers + left); + } else if (right == left + 2) { + sort3 (numbers + left); + } else if (right == left + 3) { + sort4 (numbers + left); + } + return; + } +#endif + + lTmp = left; + rTmp = right; + + pivot = medianOf3 (numbers + left, (right-left) >> 1, right-1-left); + + goto QStart; + while (1) { + do { + right--; + if (left >= right) goto QEnd; + QStart:; + } while (numbers[right] > pivot); + numbers[left] = numbers[right]; + do { + left++; + if (left >= right) { + left = right; + goto QEnd; + } + } while (numbers[ left] < pivot); + numbers[right] = numbers[left]; + } + QEnd:; + numbers[left] = pivot; + + /* Only recurse the smaller partition */ + + if (left-1 - lTmp <= rTmp - left - 1) { + if (lTmp < left) quickSortRecurse (numbers, lTmp, left-1); + + /* Set up for larger partition */ + left++; + right = rTmp; + } else { + if (rTmp > left) quickSortRecurse (numbers, left+1, rTmp); + + /* Set up for larger partition */ + right = left - 1; + left = lTmp; + } + + /* Rerun with larger partition (recursion not required.) */ + goto qsrStart; +} + +void quickSort (int numbers[], int qty) { + if (qty < 2) return; + quickSortRecurse (numbers, 0, qty - 1); +} + +/* + * Merge Sort + */ + +static void mergesortInPlace (int * numbers, int * altNumbers, int qty); + +/* Perform mergesort, but store results in altNumbers */ + +static void mergesortExchange (int * numbers, int * altNumbers, int qty) { +int half, i0, i1, i; + + if (qty == 2) { + sortAlt2 (numbers, altNumbers); + return; + } + if (qty == 3) { + sortAlt3 (numbers, altNumbers); + return; + } + + half = (qty + 1)/2; + + mergesortInPlace (numbers, altNumbers, half); + mergesortInPlace (numbers + half, altNumbers, qty - half); + + i0 = 0; i1 = half; + + for (i=0; i < qty; i++) { + if (i1 >= qty || (i0 < half && numbers[i0] < numbers[i1])) { + altNumbers[i] = numbers[i0]; + i0++; + } else { + altNumbers[i] = numbers[i1]; + i1++; + } + } +} + +/* Perform mergesort and store results in numbers */ + +static void mergesortInPlace (int * numbers, int * altNumbers, int qty) { +int half, i0, i1, i; + +#if 0 + if (qty == 2) { + sort2 (numbers); + return; + } + if (qty == 3) { + sort3 (numbers); + return; + } + if (qty == 4) { + sort4 (numbers); + return; + } +#else + if (qty <= 12) { + insertSort (numbers, qty); + return; + } +#endif + + half = (qty + 1)/2; + + mergesortExchange (numbers, altNumbers, half); + mergesortExchange (numbers + half, altNumbers + half, qty - half); + + i0 = 0; i1 = half; + + for (i=0; i < qty; i++) { + if (i1 >= qty || (i0 < half && altNumbers[i0] < altNumbers[i1])) { + numbers[i] = altNumbers[i0]; + i0++; + } else { + numbers[i] = altNumbers[i1]; + i1++; + } + } +} + +#include + +void mergeSort (int numbers[], int qty) { +int * tmpArray; + + if (qty <= 12) { + insertSort (numbers, qty); + return; + } + + tmpArray = (int *) malloc (qty * sizeof (int)); + mergesortInPlace (numbers, tmpArray, qty); + free (tmpArray); +} + +/******************************** + * END OF PAUL'S IMPLEMENTATION * + ********************************/ + +/************************************************* + *** Implementation 1: faster on sorted arrays *** + *************************************************/ + +#define rstype_t unsigned +#define rskey(x) (x) + +#define RS_MIN_SIZE 64 + +typedef struct { + rstype_t *b, *e; +} rsbucket_t; + +void rs_sort(rstype_t *beg, rstype_t *end, int n_bits, int s) +{ + rstype_t *i; + int size = 1<b = k->e = beg; + for (i = beg; i != end; ++i) ++b[rskey(*i)>>s&m].e; + for (k = b + 1; k != be; ++k) + k->e += (k-1)->e - beg, k->b = (k-1)->e; + for (k = b; k != be;) { + if (k->b != k->e) { + rsbucket_t *l; + if ((l = b + (rskey(*k->b)>>s&m)) != k) { + rstype_t tmp = *k->b, swap; + do { + swap = tmp; tmp = *l->b; *l->b++ = swap; + l = b + (rskey(tmp)>>s&m); + } while (l != k); + *k->b++ = tmp; + } else ++k->b; + } else ++k; + } + for (b->b = beg, k = b + 1; k != be; ++k) k->b = (k-1)->e; + if (s) { + s = s > n_bits? s - n_bits : 0; + for (k = b; k != be; ++k) + if (k->e - k->b > RS_MIN_SIZE) rs_sort(k->b, k->e, n_bits, s); + else if (k->e - k->b > 1) + for (i = k->b + 1; i < k->e; ++i) + if (rskey(*i) < rskey(*(i - 1))) { + rstype_t *j, tmp = *i; + for (j = i; j > k->b && rskey(tmp) < rskey(*(j-1)); --j) + *j = *(j - 1); + *j = tmp; + } + } +} + +/************************************************* + *** Implementation 2: faster on random arrays *** + *************************************************/ + +static inline void rs_insertsort(rstype_t *s, rstype_t *t) +{ + rstype_t *i; + for (i = s + 1; i < t; ++i) { + if (rskey(*i) < rskey(*(i - 1))) { + rstype_t *j, tmp = *i; + for (j = i; j > s && rskey(tmp) < rskey(*(j-1)); --j) + *j = *(j - 1); + *j = tmp; + } + } +} +/* +void rs_sort2(rstype_t *beg, rstype_t *end, int n_bits, int s) +{ + int j, size = 1<>s&m]; + b[0] = e[0] = beg; + for (j = 1; j != size; ++j) b[j] = e[j] = b[j - 1] + c[j - 1]; + for (i = beg, j = 0; i != end;) { + rstype_t tmp = *i, swap; + int x; + for (;;) { + x = rskey(tmp)>>s&m; + if (e[x] == i) break; + swap = tmp; tmp = *e[x]; *e[x]++ = swap; + } + *i++ = tmp; + ++e[x]; + while (j != size && i >= b[j]) ++j; + while (j != size && e[j-1] == b[j]) ++j; + if (i < e[j-1]) i = e[j-1]; + } + if (s) { + s = s > n_bits? s - n_bits : 0; + for (j = 0; j < size; ++j) { + if (c[j] >= RS_MIN_SIZE) rs_sort2(b[j], e[j], n_bits, s); + else if (c[j] >= 2) rs_insertsort(b[j], e[j]); + } + } +} +*/ +void radix_sort(unsigned *array, int offset, int end, int shift) { + int x, y, value, temp; + int last[256] = { 0 }, pointer[256]; + + for (x=offset; x> shift) & 0xFF]; + } + + last[0] += offset; + pointer[0] = offset; + for (x=1; x<256; ++x) { + pointer[x] = last[x-1]; + last[x] += last[x-1]; + } + + for (x=0; x<256; ++x) { + while (pointer[x] != last[x]) { + value = array[pointer[x]]; + y = (value >> shift) & 0xFF; + while (x != y) { + temp = array[pointer[y]]; + array[pointer[y]++] = value; + value = temp; + y = (value >> shift) & 0xFF; + } + array[pointer[x]++] = value; + } + } + + if (shift > 0) { + shift -= 8; + for (x=0; x<256; ++x) { + temp = x > 0 ? pointer[x] - pointer[x-1] : pointer[0] - offset; + if (temp > 64) { + radix_sort(array, pointer[x] - temp, pointer[x], shift); + } else if (temp > 1) rs_insertsort(array + pointer[x] - temp, array + pointer[x]); + } + } +} +/************************* + *** END OF RADIX SORT *** + *************************/ + +template< class _Type, unsigned long PowerOfTwoRadix, unsigned long Log2ofPowerOfTwoRadix, long Threshold > +inline void _RadixSort_Unsigned_PowerOf2Radix_1( _Type* a, long last, _Type bitMask, unsigned long shiftRightAmount ) +{ + const unsigned long numberOfBins = PowerOfTwoRadix; + unsigned long count[ numberOfBins ]; + for( unsigned long i = 0; i < numberOfBins; i++ ) + count[ i ] = 0; + for ( long _current = 0; _current <= last; _current++ ) // Scan the array and count the number of times each value appears + { + unsigned long digit = (unsigned long)(( a[ _current ] & bitMask ) >> shiftRightAmount ); // extract the digit we are sorting based on + count[ digit ]++; + } + long startOfBin[ numberOfBins ], endOfBin[ numberOfBins ], nextBin; + startOfBin[ 0 ] = endOfBin[ 0 ] = nextBin = 0; + for( unsigned long i = 1; i < numberOfBins; i++ ) + startOfBin[ i ] = endOfBin[ i ] = startOfBin[ i - 1 ] + count[ i - 1 ]; + for ( long _current = 0; _current <= last; ) + { + unsigned long digit; + _Type tmp = a[ _current ]; // get the compiler to recognize that a register can be used for the loop instead of a[_current] memory location + while ( true ) { + digit = (unsigned long)(( tmp & bitMask ) >> shiftRightAmount ); // extract the digit we are sorting based on + if ( endOfBin[ digit ] == _current ) + break; + _Type tmp2; + //_swap( tmp, a[ endOfBin[ digit ] ] ); + tmp2 = a[endOfBin[digit]]; a[endOfBin[digit]] = tmp; tmp = tmp2; + endOfBin[ digit ]++; + } + a[ _current ] = tmp; + endOfBin[ digit ]++; // leave the element at its location and grow the bin + _current++; // advance the current pointer to the next element + while( _current >= startOfBin[ nextBin ] && nextBin < numberOfBins ) + nextBin++; + while( endOfBin[ nextBin - 1 ] == startOfBin[ nextBin ] && nextBin < numberOfBins ) + nextBin++; + if ( _current < endOfBin[ nextBin - 1 ] ) + _current = endOfBin[ nextBin - 1 ]; + } + bitMask >>= Log2ofPowerOfTwoRadix; + if ( bitMask != 0 ) // end recursion when all the bits have been processes + { + if ( shiftRightAmount >= Log2ofPowerOfTwoRadix ) shiftRightAmount -= Log2ofPowerOfTwoRadix; + else shiftRightAmount = 0; + for( unsigned long i = 0; i < numberOfBins; i++ ) + { + long numberOfElements = endOfBin[ i ] - startOfBin[ i ]; + if ( numberOfElements >= Threshold ) // endOfBin actually points to one beyond the bin + _RadixSort_Unsigned_PowerOf2Radix_1< _Type, PowerOfTwoRadix, Log2ofPowerOfTwoRadix, Threshold >( &a[ startOfBin[ i ]], numberOfElements - 1, bitMask, shiftRightAmount ); + else if ( numberOfElements >= 2 ) + rs_insertsort(&a[ startOfBin[ i ]], &a[ endOfBin[ i ]]); + } + } +} +inline void RadixSortInPlace_HybridUnsigned_Radix256( unsigned* a, unsigned long a_size ) +{ + if ( a_size < 2 ) return; + unsigned long bitMask = 0xFF000000; // bitMask controls how many bits we process at a time + unsigned long shiftRightAmount = 24; + if ( a_size >= 32 ) + _RadixSort_Unsigned_PowerOf2Radix_1(a, a_size - 1, bitMask, shiftRightAmount ); + else + rs_insertsort(a, a + a_size); +} + +struct intcmp_t { + inline int operator() (int a, int b) const { + return a < b? -1 : a > b? 1 : 0; + } +}; + +int compare_int(int a, int b) +{ + return a < b? -1 : a > b? 1 : 0; +} +int compare(const void *a, const void *b) +{ + return *((int*)a) - *((int*)b); +} + +int main(int argc, char *argv[]) +{ + int i, N = 50000000; + int *array, *temp; + clock_t t1, t2; + if (argc == 1) fprintf(stderr, "Usage: %s [%d]\n", argv[0], N); + if (argc > 1) N = atoi(argv[1]); + temp = (int*)malloc(sizeof(int) * N); + array = (int*)malloc(sizeof(int) * N); + + srand48(11); + for (i = 0; i < N; ++i) array[i] = (int)lrand48(); + t1 = clock(); + rs_sort((unsigned*)array, (unsigned*)array + N, 8, 24); + t2 = clock(); + fprintf(stderr, "radix sort: %.3lf\n", (double)(t2-t1)/CLOCKS_PER_SEC); + for (i = 0; i < N-1; ++i) { + if (array[i] > array[i+1]) { + fprintf(stderr, "Bug in radix sort!\n"); + exit(1); + } + } + t1 = clock(); + rs_sort((unsigned*)array, (unsigned*)array + N, 8, 24); + t2 = clock(); + fprintf(stderr, "radix sort (sorted): %.3lf\n", (double)(t2-t1)/CLOCKS_PER_SEC); + + srand48(11); + for (i = 0; i < N; ++i) array[i] = (int)lrand48(); + t1 = clock(); + RadixSortInPlace_HybridUnsigned_Radix256((unsigned*)array, N); +// radix_sort((unsigned*)array, 0, N, 24); + t2 = clock(); + fprintf(stderr, "vd's radix sort: %.3lf\n", (double)(t2-t1)/CLOCKS_PER_SEC); + for (i = 0; i < N-1; ++i) { + if (array[i] > array[i+1]) { + fprintf(stderr, "Bug in radix sort!\n"); + exit(1); + } + } + t1 = clock(); + RadixSortInPlace_HybridUnsigned_Radix256((unsigned*)array, N); +// radix_sort((unsigned*)array, 0, N, 24); + t2 = clock(); + fprintf(stderr, "vd's radix sort (sorted): %.3lf\n", (double)(t2-t1)/CLOCKS_PER_SEC); + + srand48(11); + for (i = 0; i < N; ++i) array[i] = (int)lrand48(); + t1 = clock(); + sort(array, array+N); + t2 = clock(); + fprintf(stderr, "STL introsort: %.3lf\n", (double)(t2-t1)/CLOCKS_PER_SEC); + t1 = clock(); + sort(array, array+N); + t2 = clock(); + fprintf(stderr, "STL introsort (sorted): %.3lf\n", (double)(t2-t1)/CLOCKS_PER_SEC); + + srand48(11); + for (i = 0; i < N; ++i) array[i] = (int)lrand48(); + t1 = clock(); + stable_sort(array, array+N); + t2 = clock(); + fprintf(stderr, "STL stablesort: %.3lf\n", (double)(t2-t1)/CLOCKS_PER_SEC); + t1 = clock(); + stable_sort(array, array+N); + t2 = clock(); + fprintf(stderr, "STL stablesort (sorted): %.3lf\n", (double)(t2-t1)/CLOCKS_PER_SEC); + + srand48(11); + for (i = 0; i < N; ++i) array[i] = (int)lrand48(); + t1 = clock(); + make_heap(array, array+N); + sort_heap(array, array+N); + t2 = clock(); + fprintf(stderr, "STL heapsort: %.3lf\n", (double)(t2-t1)/CLOCKS_PER_SEC); + for (i = 0; i < N-1; ++i) { + if (array[i] > array[i+1]) { + fprintf(stderr, "Bug in heap_sort!\n"); + exit(1); + } + } + t1 = clock(); + make_heap(array, array+N); + sort_heap(array, array+N); + t2 = clock(); + fprintf(stderr, "STL heapsort (sorted): %.3lf\n", (double)(t2-t1)/CLOCKS_PER_SEC); + + srand48(11); + for (i = 0; i < N; ++i) array[i] = (int)lrand48(); + t1 = clock(); + ks_combsort(int, N, array); + t2 = clock(); + fprintf(stderr, "combsort: %.3lf\n", (double)(t2-t1)/CLOCKS_PER_SEC); + for (i = 0; i < N-1; ++i) { + if (array[i] > array[i+1]) { + fprintf(stderr, "Bug in combsort!\n"); + exit(1); + } + } + + srand48(11); + for (i = 0; i < N; ++i) array[i] = (int)lrand48(); + t1 = clock(); + qsort(array, N, sizeof(int), compare); + t2 = clock(); + fprintf(stderr, "libc qsort: %.3lf\n", (double)(t2-t1)/CLOCKS_PER_SEC); + + srand48(11); + for (i = 0; i < N; ++i) array[i] = (int)lrand48(); + t1 = clock(); + ks_introsort(int, N, array); + t2 = clock(); + fprintf(stderr, "my introsort: %.3lf\n", (double)(t2-t1)/CLOCKS_PER_SEC); + for (i = 0; i < N-1; ++i) { + if (array[i] > array[i+1]) { + fprintf(stderr, "Bug in intro_sort!\n"); + exit(1); + } + } + t1 = clock(); + ks_introsort(int, N, array); + t2 = clock(); + fprintf(stderr, "introsort (sorted): %.3lf\n", (double)(t2-t1)/CLOCKS_PER_SEC); + + srand48(11); + for (i = 0; i < N; ++i) array[i] = (int)lrand48(); + t1 = clock(); + ks_mergesort(int, N, array, 0); + t2 = clock(); + fprintf(stderr, "iterative mergesort: %.3lf\n", (double)(t2-t1)/CLOCKS_PER_SEC); + for (i = 0; i < N-1; ++i) { + if (array[i] > array[i+1]) { + fprintf(stderr, "Bug in merge_sort!\n"); + exit(1); + } + } + t1 = clock(); + ks_mergesort(int, N, array, 0); + t2 = clock(); + fprintf(stderr, "iterative mergesort (sorted): %.3lf\n", (double)(t2-t1)/CLOCKS_PER_SEC); + + srand48(11); + for (i = 0; i < N; ++i) array[i] = (int)lrand48(); + t1 = clock(); + ks_heapmake(int, N, array); + ks_heapsort(int, N, array); + t2 = clock(); + fprintf(stderr, "my heapsort: %.3lf\n", (double)(t2-t1)/CLOCKS_PER_SEC); + for (i = 0; i < N-1; ++i) { + if (array[i] > array[i+1]) { + fprintf(stderr, "Bug in heap_sort!\n"); + exit(1); + } + } + t1 = clock(); + ks_heapmake(int, N, array); + ks_heapsort(int, N, array); + t2 = clock(); + fprintf(stderr, "heapsort (sorted): %.3lf\n", (double)(t2-t1)/CLOCKS_PER_SEC); + + srand48(11); + for (i = 0; i < N; ++i) array[i] = (int)lrand48(); + t1 = clock(); + heapSort(array, N); + t2 = clock(); + fprintf(stderr, "Paul's heapsort: %.3lf\n", (double)(t2-t1)/CLOCKS_PER_SEC); + for (i = 0; i < N-1; ++i) { + if (array[i] > array[i+1]) { + fprintf(stderr, "Bug in intro_sort!\n"); + exit(1); + } + } + + srand48(11); + for (i = 0; i < N; ++i) array[i] = (int)lrand48(); + t1 = clock(); + quickSort(array, N); + t2 = clock(); + fprintf(stderr, "Paul's quicksort: %.3lf\n", (double)(t2-t1)/CLOCKS_PER_SEC); + for (i = 0; i < N-1; ++i) { + if (array[i] > array[i+1]) { + fprintf(stderr, "Bug in intro_sort!\n"); + exit(1); + } + } + + srand48(11); + for (i = 0; i < N; ++i) array[i] = (int)lrand48(); + t1 = clock(); + mergeSort(array, N); + t2 = clock(); + fprintf(stderr, "Paul's mergesort: %.3lf\n", (double)(t2-t1)/CLOCKS_PER_SEC); + for (i = 0; i < N-1; ++i) { + if (array[i] > array[i+1]) { + fprintf(stderr, "Bug in intro_sort!\n"); + exit(1); + } + } + + free(array); free(temp); + return 0; +} diff --git a/web/server/h2o/libh2o/deps/klib/test/kstring_bench.c b/web/server/h2o/libh2o/deps/klib/test/kstring_bench.c new file mode 100644 index 00000000..82598e88 --- /dev/null +++ b/web/server/h2o/libh2o/deps/klib/test/kstring_bench.c @@ -0,0 +1,51 @@ +#include +#include +#include +#include "kstring.h" + +#define N 10000000 + +int main() +{ + int i; + clock_t t; + kstring_t s, s2; + srand48(11); + s.l = s.m = 0; s.s = 0; + t = clock(); + for (i = 0; i < N; ++i) { + int x = lrand48(); + s.l = 0; + kputw(x, &s); + } + fprintf(stderr, "kputw: %lf\n", (double)(clock() - t) / CLOCKS_PER_SEC); + srand48(11); + t = clock(); + for (i = 0; i < N; ++i) { + int x = lrand48(); + s.l = 0; + ksprintf(&s, "%d", x); + } + fprintf(stderr, "ksprintf: %lf\n", (double)(clock() - t) / CLOCKS_PER_SEC); + + srand48(11); + s2.l = s2.m = 0; s2.s = 0; + t = clock(); + for (i = 0; i < N; ++i) { + int x = lrand48(); + s2.l = s.l = 0; + kputw(x, &s2); + kputs(s2.s, &s); + } + fprintf(stderr, "kputw+kputs: %lf\n", (double)(clock() - t) / CLOCKS_PER_SEC); + srand48(11); + t = clock(); + for (i = 0; i < N; ++i) { + int x = lrand48(); + s2.l = s.l = 0; + kputw(x, &s2); + ksprintf(&s, "%s", s2.s); + } + fprintf(stderr, "kputw+ksprintf: %lf\n", (double)(clock() - t) / CLOCKS_PER_SEC); + return 0; +} diff --git a/web/server/h2o/libh2o/deps/klib/test/kstring_bench2.c b/web/server/h2o/libh2o/deps/klib/test/kstring_bench2.c new file mode 100644 index 00000000..b7707a8e --- /dev/null +++ b/web/server/h2o/libh2o/deps/klib/test/kstring_bench2.c @@ -0,0 +1,131 @@ +#include +#include +#include +#include +#include "kstring.h" + +#ifdef __APPLE__ +#define HAVE_STRNSTR +#endif + +#ifdef __linux__ +#define HAVE_MEMMEM +#endif + +static int str_len = 1024*1024*128; +static int pat_len = 30; +static int alphabet = 2; +static int repeat = 50; + +char *gen_data(int len, int a) +{ + char *data; + int i; + long x; + srand48(11); + data = malloc(len); + for (i = 0; i < len; ++i) + data[i] = (int)(a * drand48()) + '!'; + data[str_len - 1] = 0; + return data; +} +// http://srcvault.scali.eu.org/cgi-bin/Syntax/c/BoyerMoore.c +char *BoyerMoore( unsigned char *data, unsigned int dataLength, unsigned char *string, unsigned int strLength ) +{ + unsigned int skipTable[256], i; + unsigned char *search; + register unsigned char lastChar; + + if (strLength == 0) + return NULL; + + for (i = 0; i < 256; i++) + skipTable[i] = strLength; + search = string; + i = --strLength; + do { + skipTable[*search++] = i; + } while (i--); + lastChar = *--search; + search = data + strLength; + dataLength -= strLength+(strLength-1); + while ((int)dataLength > 0 ) { + unsigned int skip; + skip = skipTable[*search]; + search += skip; + dataLength -= skip; + skip = skipTable[*search]; + search += skip; + dataLength -= skip; + skip = skipTable[*search]; + if (*search != lastChar) { + search += skip; + dataLength -= skip; + continue; + } + i = strLength; + do { + if (i-- == 0) return search; + } while (*--search == string[i]); + search += (strLength - i + 1); + dataLength--; + } + return NULL; +} + +int main() +{ + char *data; + int i; + clock_t t; + t = clock(); + data = gen_data(str_len, alphabet); + fprintf(stderr, "Generate data in %.3f sec\n", (float)(clock() - t) / CLOCKS_PER_SEC); + { + t = clock(); srand48(1331); + for (i = 0; i < repeat; ++i) { + int y = lrand48() % (str_len - pat_len); + char *ret; + ret = kmemmem(data, str_len, data + y, pat_len, 0); +// printf("%d, %d\n", (int)(ret - data), y); + } + fprintf(stderr, "Search patterns in %.3f sec\n", (float)(clock() - t) / CLOCKS_PER_SEC); + } + if (1) { + t = clock(); srand48(1331); + for (i = 0; i < repeat; ++i) { + int y = lrand48() % (str_len - pat_len); + char *ret; + ret = BoyerMoore(data, str_len, data + y, pat_len); +// printf("%d, %d\n", (int)(ret - data), y); + } + fprintf(stderr, "Search patterns in %.3f sec\n", (float)(clock() - t) / CLOCKS_PER_SEC); + } +#ifdef HAVE_STRNSTR + if (1) { + char *tmp; + t = clock(); srand48(1331); + tmp = calloc(pat_len+1, 1); + for (i = 0; i < repeat; ++i) { + int y = lrand48() % (str_len - pat_len); + char *ret; + memcpy(tmp, data + y, pat_len); + ret = strnstr(data, tmp, str_len); + } + fprintf(stderr, "Search patterns in %.3f sec\n", (float)(clock() - t) / CLOCKS_PER_SEC); + } +#endif +#ifdef HAVE_MEMMEM + if (1) { + t = clock(); srand48(1331); + for (i = 0; i < repeat; ++i) { + int y = lrand48() % (str_len - pat_len); + char *ret; + ret = memmem(data, str_len, data + y, pat_len); +// printf("%d, %d\n", (int)(ret - data), y); + } + fprintf(stderr, "Search patterns in %.3f sec\n", (float)(clock() - t) / CLOCKS_PER_SEC); + } +#endif + return 0; +} diff --git a/web/server/h2o/libh2o/deps/klib/test/kstring_test.c b/web/server/h2o/libh2o/deps/klib/test/kstring_test.c new file mode 100644 index 00000000..76f9532e --- /dev/null +++ b/web/server/h2o/libh2o/deps/klib/test/kstring_test.c @@ -0,0 +1,76 @@ +#include +#include +#include +#include + +#include "kstring.h" + +int nfail = 0; + +void check(const char *what, const kstring_t *ks, const char *correct) +{ + if (ks->l != strlen(correct) || strcmp(ks->s, correct) != 0) { + fprintf(stderr, "%s produced \"%.*s\" (\"%s\" is correct)\tFAIL\n", what, (int)(ks->l), ks->s, correct); + nfail++; + } +} + +void test_kputw(kstring_t *ks, int n) +{ + char buf[16]; + + ks->l = 0; + kputw(n, ks); + + sprintf(buf, "%d", n); + check("kputw()", ks, buf); +} + +void test_kputl(kstring_t *ks, long n) +{ + char buf[24]; + + ks->l = 0; + kputl(n, ks); + + sprintf(buf, "%ld", n); + check("kputl()", ks, buf); +} + +int main() +{ + kstring_t ks; + + ks.l = ks.m = 0; + ks.s = NULL; + + test_kputw(&ks, 0); + test_kputw(&ks, 1); + test_kputw(&ks, 37); + test_kputw(&ks, 12345); + test_kputw(&ks, -12345); + test_kputw(&ks, INT_MAX); + test_kputw(&ks, -INT_MAX); + test_kputw(&ks, INT_MIN); + + test_kputl(&ks, 0); + test_kputl(&ks, 1); + test_kputl(&ks, 37); + test_kputl(&ks, 12345); + test_kputl(&ks, -12345); + test_kputl(&ks, INT_MAX); + test_kputl(&ks, -INT_MAX); + test_kputl(&ks, INT_MIN); + test_kputl(&ks, LONG_MAX); + test_kputl(&ks, -LONG_MAX); + test_kputl(&ks, LONG_MIN); + + free(ks.s); + + if (nfail > 0) { + fprintf(stderr, "Total failures: %d\n", nfail); + return EXIT_FAILURE; + } + + return EXIT_SUCCESS; +} diff --git a/web/server/h2o/libh2o/deps/klib/test/kthread_test.c b/web/server/h2o/libh2o/deps/klib/test/kthread_test.c new file mode 100644 index 00000000..1b67ed4e --- /dev/null +++ b/web/server/h2o/libh2o/deps/klib/test/kthread_test.c @@ -0,0 +1,69 @@ +#include +#include +#include +#include +#if HAVE_CILK +#include +#include +#endif + +typedef struct { + int max_iter, w, h; + double xmin, xmax, ymin, ymax; + int *k; +} global_t; + +static void compute(void *_g, int i, int tid) +{ + global_t *g = (global_t*)_g; + double x, x0 = g->xmin + (g->xmax - g->xmin) * (i%g->w) / g->w; + double y, y0 = g->ymin + (g->ymax - g->ymin) * (i/g->w) / g->h; + int k; + + assert(g->k[i] < 0); + x = x0, y = y0; + for (k = 0; k < g->max_iter; ++k) { + double z = x * y; + x *= x; y *= y; + if (x + y >= 4) break; + x = x - y + x0; + y = z + z + y0; + } + g->k[i] = k; +} + +void kt_for(int n_threads, int n_items, void (*func)(void*,int,int), void *data); + +int main(int argc, char *argv[]) +{ + int i, tmp, tot, type = 0, n_threads = 2; + global_t global = { 10240*100, 800, 600, -2., -1.2, -1.2, 1.2, 0 }; +// global_t global = { 10240*1, 8, 6, -2., -1.2, -1.2, 1.2, 0 }; + + if (argc > 1) { + type = argv[1][0] == 'o'? 2 : argv[1][0] == 'c'? 3 : argv[1][0] == 'n'? 1 : 0; + if (argv[1][0] >= '0' && argv[1][0] <= '9') + n_threads = atoi(argv[1]); + } else { + fprintf(stderr, "Usage: ./a.out [openmp | cilk | #threads]\n"); + } + tot = global.w * global.h; + global.k = calloc(tot, sizeof(int)); + for (i = 0; i < tot; ++i) global.k[i] = -1; + if (type == 0) { + kt_for(n_threads, tot, compute, &global); + } else if (type == 2) { + #pragma omp parallel for + for (i = 0; i < tot; ++i) + compute(&global, i, 0); + } else if (type == 3) { + #if HAVE_CILK + cilk_for (i = 0; i < tot; ++i) + compute(&global, i, 0); + #endif + } + for (i = tmp = 0; i < tot; ++i) tmp += (global.k[i] < 0); + free(global.k); + assert(tmp == 0); + return 0; +} diff --git a/web/server/h2o/libh2o/deps/klib/test/kvec_test.cc b/web/server/h2o/libh2o/deps/klib/test/kvec_test.cc new file mode 100644 index 00000000..1015574e --- /dev/null +++ b/web/server/h2o/libh2o/deps/klib/test/kvec_test.cc @@ -0,0 +1,69 @@ +#include +#include +#include +#include +#include "kvec.h" + +int main() +{ + int M = 10, N = 20000000, i, j; + clock_t t; + t = clock(); + for (i = 0; i < M; ++i) { + int *array = (int*)malloc(N * sizeof(int)); + for (j = 0; j < N; ++j) array[j] = j; + free(array); + } + printf("C array, preallocated: %.3f sec\n", + (float)(clock() - t) / CLOCKS_PER_SEC); + t = clock(); + for (i = 0; i < M; ++i) { + int *array = 0, max = 0; + for (j = 0; j < N; ++j) { + if (j == max) { + max = !max? 1 : max << 1; + array = (int*)realloc(array, sizeof(int)*max); + } + array[j] = j; + } + free(array); + } + printf("C array, dynamic: %.3f sec\n", + (float)(clock() - t) / CLOCKS_PER_SEC); + t = clock(); + for (i = 0; i < M; ++i) { + kvec_t(int) array; + kv_init(array); + kv_resize(int, array, N); + for (j = 0; j < N; ++j) kv_a(int, array, j) = j; + kv_destroy(array); + } + printf("C vector, dynamic(kv_a): %.3f sec\n", + (float)(clock() - t) / CLOCKS_PER_SEC); + t = clock(); + for (i = 0; i < M; ++i) { + kvec_t(int) array; + kv_init(array); + for (j = 0; j < N; ++j) + kv_push(int, array, j); + kv_destroy(array); + } + printf("C vector, dynamic(kv_push): %.3f sec\n", + (float)(clock() - t) / CLOCKS_PER_SEC); + t = clock(); + for (i = 0; i < M; ++i) { + std::vector array; + array.reserve(N); + for (j = 0; j < N; ++j) array[j] = j; + } + printf("C++ vector, preallocated: %.3f sec\n", + (float)(clock() - t) / CLOCKS_PER_SEC); + t = clock(); + for (i = 0; i < M; ++i) { + std::vector array; + for (j = 0; j < N; ++j) array.push_back(j); + } + printf("C++ vector, dynamic: %.3f sec\n", + (float)(clock() - t) / CLOCKS_PER_SEC); + return 0; +} diff --git a/web/server/h2o/libh2o/deps/libgkc/gkc.c b/web/server/h2o/libh2o/deps/libgkc/gkc.c new file mode 100644 index 00000000..2d4b6173 --- /dev/null +++ b/web/server/h2o/libh2o/deps/libgkc/gkc.c @@ -0,0 +1,439 @@ +/* + * Copyright (c) 2016 Fastly, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +/* + * A streaming quantile library. + * + * + * A `gkc_summary` structure is used to summarize observations + * within a given error range. Observations are inserted using + * `gkc_insert_value`, quantile queries can then be performed with + * `gkc_query` against the summary. + * Provided two summaries are using the same epsilon, they can be merged + * by calling `gkc_combine`. + * + * The algorithm guaranties a bounded memory usage to: + * (11/(2 x epsilon))*log(2 * epsilon * N) + * + * For epsilon = 0.01 and N = 2^64, this is only 10k max in the + * theoritical worse case. In practice, it's reliably using less: + * inserting random data gets us * ~100 max insertions for > 50 millions + * of entries. + * + * See www.cis.upenn.edu/~sanjeev/papers/sigmod01_quantiles.pdf for + * the paper describing this algorithm and data structure. + * + */ + +#include +#include +#include +#include +#include + +struct list { + struct list *prev, *next; +}; + +struct gkc_summary { + size_t nr_elems; + double epsilon; + uint64_t alloced; + uint64_t max_alloced; + struct list head; + struct freelist *fl; +}; + + +static inline int list_empty(struct list *l) +{ + return l->next == l; +} +static inline void list_init(struct list *n) +{ + n->next = n; + n->prev = n; +} + +static inline void list_del(struct list *n) +{ + n->next->prev = n->prev; + n->prev->next = n->next; +} + +static inline void list_add(struct list *l, struct list *n) +{ + n->next = l->next; + n->next->prev = n; + l->next = n; + n->prev = l; +} + +static inline void list_add_tail(struct list *l, struct list *n) +{ + list_add(l->prev, n); +} + +#undef offsetof +#ifdef __compiler_offsetof +#define offsetof(TYPE,MEMBER) __compiler_offsetof(TYPE,MEMBER) +#else +#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER) +#endif + +#define container_of(ptr, type, member) ((type *)((char *)(ptr) - offsetof(type, member))) + +struct freelist { + struct freelist *next; +}; + +static uint64_t ullog2(uint64_t x) +{ + static const uint64_t debruijn_magic = 0x022fdd63cc95386dULL; + + static const uint64_t magic_table[] = { + 0, 1, 2, 53, 3, 7, 54, 27, 4, 38, 41, 8, 34, 55, 48, 28, + 62, 5, 39, 46, 44, 42, 22, 9, 24, 35, 59, 56, 49, 18, 29, 11, + 63, 52, 6, 26, 37, 40, 33, 47, 61, 45, 43, 21, 23, 58, 17, 10, + 51, 25, 36, 32, 60, 20, 57, 16, 50, 31, 19, 15, 30, 14, 13, 12, + }; + + x |= (x >> 1); + x |= (x >> 2); + x |= (x >> 4); + x |= (x >> 8); + x |= (x >> 16); + x |= (x >> 32); + return (magic_table[((x & ~(x>>1))*debruijn_magic)>>58]); +} + +struct gkc_tuple { + uint64_t value; + double g; + uint64_t delta; + struct list node; +}; +#define list_to_tuple(ln) (container_of((ln), struct gkc_tuple, node)) + + +void gkc_summary_init(struct gkc_summary *s, double epsilon) +{ + list_init(&s->head); + s->epsilon = epsilon; +} + +struct gkc_summary *gkc_summary_alloc(double epsilon) +{ + struct gkc_summary *s; + s = calloc(1, sizeof(*s)); + gkc_summary_init(s, epsilon); + return s; +} + +#include +/* debug only, checks a number of properties that s must satisfy at all times */ +void gkc_sanity_check(struct gkc_summary *s) +{ + uint64_t nr_elems, nr_alloced; + struct list *cur; + struct gkc_tuple *tcur; + + nr_elems = 0; + nr_alloced = 0; + cur = s->head.next; + while (cur != &s->head) { + tcur = list_to_tuple(cur); + cur = cur->next; + nr_elems += tcur->g; + nr_alloced++; + if (s->nr_elems > (1/s->epsilon)) { + /* there must be enough observations for this to become true */ + assert(tcur->g + tcur->delta <= (s->nr_elems * s->epsilon * 2)); + } + assert(nr_alloced <= s->alloced); + } + assert(nr_elems == s->nr_elems); + assert(nr_alloced == s->alloced); +} + +static struct gkc_tuple *gkc_alloc(struct gkc_summary *s) +{ + s->alloced++; + if (s->alloced > s->max_alloced) { + s->max_alloced = s->alloced; + } + + if (s->fl) { + void *ret; + ret = s->fl; + s->fl = s->fl->next; + return ret; + } + return malloc(sizeof(struct gkc_tuple)); +} + +static void gkc_free(struct gkc_summary *s, struct gkc_tuple *p) +{ + struct freelist *flp = (void *)p; + s->alloced--; + + flp->next = s->fl; + s->fl = flp; +} + +void gkc_summary_free(struct gkc_summary *s) +{ + struct freelist *fl; + struct list *cur; + + cur = s->head.next; + while (cur != &s->head) { + struct list *next; + next = cur->next; + gkc_free(s, list_to_tuple(cur)); + cur = next; + } + fl = s->fl; + while (fl) { + void *p; + p = fl; + fl = fl->next; + free(p); + } + free(s); +} + +uint64_t gkc_query(struct gkc_summary *s, double q) +{ + struct list *cur, *next; + int rank; + double gi; + double ne; + + rank = 0.5 + q * s->nr_elems; + ne = s->nr_elems * s->epsilon; + gi = 0; + if (list_empty(&s->head)) { + return 0; + } + + cur = s->head.next; + + while (1) { + struct gkc_tuple *tcur, *tnext; + + tcur = list_to_tuple(cur); + next = cur->next; + if (next == &s->head) { + return tcur->value; + } + tnext = list_to_tuple(next); + + gi += tcur->g; + if ((rank + ne) < (gi + tnext->g + tnext->delta)) { + if ((rank + ne) < (gi + tnext->g)) { + return tcur->value; + } + return tnext->value; + } + cur = next; + } +} + +static uint64_t band(struct gkc_summary *s, uint64_t delta) +{ + uint64_t diff; + + diff = 1 + (s->epsilon * s->nr_elems * 2) - delta; + + if (diff == 1) { + return 0; + } else { + return ullog2(diff)/ullog2(2); + } +} + +static void gkc_compress(struct gkc_summary *s) +{ + int max_compress; + struct list *cur, *prev; + struct gkc_tuple *tcur, *tprev; + uint64_t bi, b_plus_1; + + max_compress = 2 * s->epsilon * s->nr_elems; + if (s->nr_elems < 2) { + return; + } + + prev = s->head.prev; + cur = prev->prev; + + while (cur != &s->head) { + tcur = list_to_tuple(cur); + tprev = list_to_tuple(prev); + + b_plus_1 = band(s, tprev->delta); + bi = band(s, tcur->delta); + + if (bi <= b_plus_1 && ((tcur->g + tprev->g + tprev->delta) <= max_compress)) { + tprev->g += tcur->g; + list_del(cur); + gkc_free(s, tcur); + cur = prev->prev; + continue; + } + prev = cur; + cur = cur->prev; + } +} + +void gkc_insert_value(struct gkc_summary *s, double value) +{ + struct list *cur = NULL; + struct gkc_tuple *new, *tcur, *tnext = NULL; + + new = gkc_alloc(s); + memset(new, 0, sizeof(*new)); + new->value = value; + new->g = 1; + list_init(&new->node); + + + s->nr_elems++; + + + /* first insert */ + if (list_empty(&s->head)) { + list_add(&s->head, &new->node); + return; + } + + cur = s->head.next; + tcur = list_to_tuple(cur); + /* v < v0, new min */ + if (tcur->value > new->value) { + list_add(&s->head, &new->node); + goto out; + } + + double gi = 0; + while (cur->next != &s->head) { + tnext = list_to_tuple(cur->next); + tcur = list_to_tuple(cur); + + gi += tcur->g; + if (tcur->value <= new->value && new->value < tnext->value) { + /* INSERT "(v, 1, Δ)" into S between vi and vi+1; */ + new->delta = tcur->g + tcur->delta - 1; + list_add(cur, &new->node); + goto out; + } + cur = cur->next; + } + /* v > vs-1, new max */ + list_add_tail(&s->head, &new->node); +out: + if (s->nr_elems % (int)(1/(2*s->epsilon))) { + gkc_compress(s); + } +} + +void gkc_print_summary(struct gkc_summary *s) +{ + struct gkc_tuple *tcur; + struct list *cur; + + fprintf(stderr, "nr_elems: %zu, epsilon: %.02f, alloced: %" PRIu64 ", overfilled: %.02f, max_alloced: %" PRIu64 "\n", + s->nr_elems, s->epsilon, s->alloced, 2 * s->epsilon * s->nr_elems, s->max_alloced); + if (list_empty(&s->head)) { + fprintf(stderr, "Empty summary\n"); + return; + } + + cur = s->head.next; + while (cur != &s->head) { + tcur = list_to_tuple(cur); + fprintf(stderr, "(v: %" PRIu64 ", g: %.02f, d: %" PRIu64 ") ", tcur->value, tcur->g, tcur->delta); + cur = cur->next; + } + fprintf(stderr, "\n"); +} + +struct gkc_summary *gkc_combine(struct gkc_summary *s1, struct gkc_summary *s2) +{ + struct gkc_summary *snew; + struct list *cur1, *cur2; + struct gkc_tuple *tcur1, *tcur2, *tnew; + + if (s1->epsilon != s2->epsilon) { + return NULL; + } + snew = gkc_summary_alloc(s1->epsilon); + + cur1 = s1->head.next; + cur2 = s2->head.next; + while (cur1 != &s1->head && cur2 != &s2->head) { + tcur1 = list_to_tuple(cur1); + tcur2 = list_to_tuple(cur2); + + tnew = gkc_alloc(snew); + if (tcur1->value < tcur2->value) { + tnew->value = tcur1->value; + tnew->g = tcur1->g; + tnew->delta = tcur1->delta; + cur1 = cur1->next; + } else { + tnew->value = tcur2->value; + tnew->g = tcur2->g; + tnew->delta = tcur2->delta; + cur2 = cur2->next; + } + list_add_tail(&snew->head, &tnew->node); + snew->nr_elems += tnew->g; + } + while (cur1 != &s1->head) { + tcur1 = list_to_tuple(cur1); + + tnew = gkc_alloc(snew); + tnew->value = tcur1->value; + tnew->g = tcur1->g; + tnew->delta = tcur1->delta; + list_add_tail(&snew->head, &tnew->node); + snew->nr_elems += tnew->g; + cur1 = cur1->next; + } + while (cur2 != &s2->head) { + tcur2 = list_to_tuple(cur2); + + tnew = gkc_alloc(snew); + tnew->value = tcur2->value; + tnew->g = tcur2->g; + tnew->delta = tcur2->delta; + list_add_tail(&snew->head, &tnew->node); + snew->nr_elems += tnew->g; + cur2 = cur2->next; + } + snew->max_alloced = snew->alloced; + gkc_compress(snew); + + return snew; +} diff --git a/web/server/h2o/libh2o/deps/libgkc/gkc.h b/web/server/h2o/libh2o/deps/libgkc/gkc.h new file mode 100644 index 00000000..cbf0878f --- /dev/null +++ b/web/server/h2o/libh2o/deps/libgkc/gkc.h @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2016 Fastly, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#ifndef __GKC_H__ +#define __GKC_H__ + +struct gkc_summary; + +void gkc_print_summary(struct gkc_summary *s); +void gkc_insert_value(struct gkc_summary *s, double value); +unsigned long gkc_query(struct gkc_summary *s, double q); +void gkc_summary_free(struct gkc_summary *s); +struct gkc_summary *gkc_summary_alloc(double epsilon); +void gkc_summary_init(struct gkc_summary *s, double epsilon); +void gkc_sanity_check(struct gkc_summary *s); +struct gkc_summary *gkc_combine(struct gkc_summary *s1, struct gkc_summary *s2); + +#endif /* __GKC_H__ */ diff --git a/web/server/h2o/libh2o/deps/libgkc/test.c b/web/server/h2o/libh2o/deps/libgkc/test.c new file mode 100644 index 00000000..d0cc251b --- /dev/null +++ b/web/server/h2o/libh2o/deps/libgkc/test.c @@ -0,0 +1,141 @@ +/* + * Copyright (c) 2016 Fastly, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include +#include +#include + +#include "gkc.h" + +void print_query(struct gkc_summary *s, double q) +{ + double v = gkc_query(s, q); + fprintf(stderr, "queried: %.02f, found: %.02f\n", q, v); +} + +int main(void) +{ +#define ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0])) + unsigned int i; +#if 0 + double input[] = { + 3658, 3673, 3693, 3715, 3723, 3724, 3724, 3690, 3695, 3689, 3695, 3700, + 3690, 3699, 3699, 3701, 3704, 3704, 3714, 3707, 3698, 3701, 3697, 3697, + 3712, 3713, 3714, 3715, 3717, 3712, 3712, 3717, 3728, 3728, 3744, 3751, + 3764, 3751, 3798, 3802, 3800, 3824, 3810, 3824, 3811, 3802, 3811, 3801, + 3791, 3796, 3803, 3817, 3819, 3818, 3815, 3804, 3796, 3784, 3783, 3784, + 3774, 3776, 3776, 3764, 3763, 3806, 3819, 3835, 3825, 3786, 3795, 3795, + 3776, 3760, 3789, 3786, 3771, 3778, 3782, 3776, 3781, 3784, 3801, 3810, + 3815, 3792, 3764, 3770, 3746, 3741, 3746, 3756, 3755, 3775, 3776, 3773, + 3777, 3801, 3804, 3807 + }; +#else + double input[] = { 12, 6, 10, 1 }; +#endif + FILE *out; + struct gkc_summary *summary; + struct gkc_summary *s1, *s2, *snew; + + summary = gkc_summary_alloc(0.01); + print_query(summary, 0.1); + goto test_combine; + summary = gkc_summary_alloc(0.01); + +#if 0 + for (i = 0; i < ARRAY_SIZE(input); i++) { + gkc_insert_value(&summary, input[i]); + } + gkc_print_summary(&summary); + print_query(&summary, 0); + print_query(&summary, .25); + print_query(&summary, .5); + print_query(&summary, .75); + print_query(&summary, 1); + return 0; +#else + (void)input; +#endif + +#define tofile 0 + if (tofile) { + out = fopen("data", "w+"); + } + srandom(time(NULL)); + for (i = 0; i < 10 * 1000 * 1000; i++) { + long r = random() % 10000; + gkc_insert_value(summary, r); + if (tofile) { + fprintf(out, "%ld\n", r); + } + } + if (tofile) { + fclose(out); + } + gkc_print_summary(summary); + print_query(summary, .02); + print_query(summary, .1); + print_query(summary, .25); + print_query(summary, .5); + print_query(summary, .75); + print_query(summary, .82); + print_query(summary, .88); + print_query(summary, .86); + print_query(summary, .99); + + gkc_sanity_check(summary); + + gkc_summary_free(summary); + +test_combine: + s1 = gkc_summary_alloc(0.01); + s2 = gkc_summary_alloc(0.01); + + for (i = 0; i < 1 * 10 * 1000; i++) { + long r = random() % 10000; + gkc_insert_value(s1, r); + } +#if 0 + for (i = 0; i < 1 * 1 * 1000; i++) { + gkc_insert_value(s2, 111); + } +#endif + snew = gkc_combine(s1, s2); + gkc_summary_free(s1); + gkc_summary_free(s2); + + gkc_print_summary(snew); + print_query(snew, .02); + print_query(snew, .1); + print_query(snew, .25); + print_query(snew, .5); + print_query(snew, .75); + print_query(snew, .82); + print_query(snew, .88); + print_query(snew, .86); + print_query(snew, .99); + + gkc_sanity_check(snew); + + gkc_summary_free(snew); + + return 0; +} diff --git a/web/server/h2o/libh2o/deps/libyrmcds/.gitignore b/web/server/h2o/libh2o/deps/libyrmcds/.gitignore new file mode 100644 index 00000000..12c3d251 --- /dev/null +++ b/web/server/h2o/libh2o/deps/libyrmcds/.gitignore @@ -0,0 +1,13 @@ +# C/C++ +*.[oa] + +# Editors +*~ +.*.swp + +# misc +yc +yc-cnt +html +lz4 +t/*.exe diff --git a/web/server/h2o/libh2o/deps/libyrmcds/.travis.yml b/web/server/h2o/libh2o/deps/libyrmcds/.travis.yml new file mode 100644 index 00000000..a1fa4fac --- /dev/null +++ b/web/server/h2o/libh2o/deps/libyrmcds/.travis.yml @@ -0,0 +1,16 @@ +language: c +os: + - linux + - osx +compiler: + - gcc + - clang +services: + - memcached +before_install: + - if [ "$TRAVIS_OS_NAME" = osx ]; then brew update; fi + - if [ "$TRAVIS_OS_NAME" = osx ]; then brew install memcached; fi + - if [ "$TRAVIS_OS_NAME" = osx ]; then /usr/local/opt/memcached/bin/memcached -d; fi +script: + - make + - env YRMCDS_HOST=localhost make test diff --git a/web/server/h2o/libh2o/deps/libyrmcds/COPYING b/web/server/h2o/libh2o/deps/libyrmcds/COPYING new file mode 100644 index 00000000..c3869aaa --- /dev/null +++ b/web/server/h2o/libh2o/deps/libyrmcds/COPYING @@ -0,0 +1,25 @@ +Copyright (c) 2013-2015, Cybozu et al. +Copyright belongs to the authors or to the authors' employers of +each contribution. Refer to https://github.com/cybozu/libyrmcds/commits/ + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + +* Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. diff --git a/web/server/h2o/libh2o/deps/libyrmcds/Doxyfile b/web/server/h2o/libh2o/deps/libyrmcds/Doxyfile new file mode 100644 index 00000000..4c8617cc --- /dev/null +++ b/web/server/h2o/libh2o/deps/libyrmcds/Doxyfile @@ -0,0 +1,1748 @@ +# Doxyfile 1.7.6.1 + +# This file describes the settings to be used by the documentation system +# doxygen (www.doxygen.org) for a project. +# +# All text after a hash (#) is considered a comment and will be ignored. +# The format is: +# TAG = value [value, ...] +# For lists items can also be appended using: +# TAG += value [value, ...] +# Values that contain spaces should be placed between quotes (" "). + +#--------------------------------------------------------------------------- +# Project related configuration options +#--------------------------------------------------------------------------- + +# This tag specifies the encoding used for all characters in the config file +# that follow. The default is UTF-8 which is also the encoding used for all +# text before the first occurrence of this tag. Doxygen uses libiconv (or the +# iconv built into libc) for the transcoding. See +# http://www.gnu.org/software/libiconv for the list of possible encodings. + +DOXYFILE_ENCODING = UTF-8 + +# The PROJECT_NAME tag is a single word (or sequence of words) that should +# identify the project. Note that if you do not use Doxywizard you need +# to put quotes around the project name if it contains spaces. + +PROJECT_NAME = "libyrmcds" + +# The PROJECT_NUMBER tag can be used to enter a project or revision number. +# This could be handy for archiving the generated documentation or +# if some version control system is used. + +PROJECT_NUMBER = + +# Using the PROJECT_BRIEF tag one can provide an optional one line description +# for a project that appears at the top of each page and should give viewer +# a quick idea about the purpose of the project. Keep the description short. + +PROJECT_BRIEF = "memcached/yrmcds client library for C" + +# With the PROJECT_LOGO tag one can specify an logo or icon that is +# included in the documentation. The maximum height of the logo should not +# exceed 55 pixels and the maximum width should not exceed 200 pixels. +# Doxygen will copy the logo to the output directory. + +PROJECT_LOGO = + +# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) +# base path where the generated documentation will be put. +# If a relative path is entered, it will be relative to the location +# where doxygen was started. If left blank the current directory will be used. + +OUTPUT_DIRECTORY = + +# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create +# 4096 sub-directories (in 2 levels) under the output directory of each output +# format and will distribute the generated files over these directories. +# Enabling this option can be useful when feeding doxygen a huge amount of +# source files, where putting all generated files in the same directory would +# otherwise cause performance problems for the file system. + +CREATE_SUBDIRS = NO + +# The OUTPUT_LANGUAGE tag is used to specify the language in which all +# documentation generated by doxygen is written. Doxygen will use this +# information to generate all constant output in the proper language. +# The default language is English, other supported languages are: +# Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional, +# Croatian, Czech, Danish, Dutch, Esperanto, Farsi, Finnish, French, German, +# Greek, Hungarian, Italian, Japanese, Japanese-en (Japanese with English +# messages), Korean, Korean-en, Lithuanian, Norwegian, Macedonian, Persian, +# Polish, Portuguese, Romanian, Russian, Serbian, Serbian-Cyrillic, Slovak, +# Slovene, Spanish, Swedish, Ukrainian, and Vietnamese. + +OUTPUT_LANGUAGE = English + +# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will +# include brief member descriptions after the members that are listed in +# the file and class documentation (similar to JavaDoc). +# Set to NO to disable this. + +BRIEF_MEMBER_DESC = YES + +# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend +# the brief description of a member or function before the detailed description. +# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the +# brief descriptions will be completely suppressed. + +REPEAT_BRIEF = YES + +# This tag implements a quasi-intelligent brief description abbreviator +# that is used to form the text in various listings. Each string +# in this list, if found as the leading text of the brief description, will be +# stripped from the text and the result after processing the whole list, is +# used as the annotated text. Otherwise, the brief description is used as-is. +# If left blank, the following values are used ("$name" is automatically +# replaced with the name of the entity): "The $name class" "The $name widget" +# "The $name file" "is" "provides" "specifies" "contains" +# "represents" "a" "an" "the" + +ABBREVIATE_BRIEF = + +# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then +# Doxygen will generate a detailed section even if there is only a brief +# description. + +ALWAYS_DETAILED_SEC = NO + +# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all +# inherited members of a class in the documentation of that class as if those +# members were ordinary class members. Constructors, destructors and assignment +# operators of the base classes will not be shown. + +INLINE_INHERITED_MEMB = NO + +# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full +# path before files name in the file list and in the header files. If set +# to NO the shortest path that makes the file name unique will be used. + +FULL_PATH_NAMES = YES + +# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag +# can be used to strip a user-defined part of the path. Stripping is +# only done if one of the specified strings matches the left-hand part of +# the path. The tag can be used to show relative paths in the file list. +# If left blank the directory from which doxygen is run is used as the +# path to strip. + +STRIP_FROM_PATH = + +# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of +# the path mentioned in the documentation of a class, which tells +# the reader which header file to include in order to use a class. +# If left blank only the name of the header file containing the class +# definition is used. Otherwise one should specify the include paths that +# are normally passed to the compiler using the -I flag. + +STRIP_FROM_INC_PATH = + +# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter +# (but less readable) file names. This can be useful if your file system +# doesn't support long names like on DOS, Mac, or CD-ROM. + +SHORT_NAMES = NO + +# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen +# will interpret the first line (until the first dot) of a JavaDoc-style +# comment as the brief description. If set to NO, the JavaDoc +# comments will behave just like regular Qt-style comments +# (thus requiring an explicit @brief command for a brief description.) + +JAVADOC_AUTOBRIEF = YES + +# If the QT_AUTOBRIEF tag is set to YES then Doxygen will +# interpret the first line (until the first dot) of a Qt-style +# comment as the brief description. If set to NO, the comments +# will behave just like regular Qt-style comments (thus requiring +# an explicit \brief command for a brief description.) + +QT_AUTOBRIEF = NO + +# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen +# treat a multi-line C++ special comment block (i.e. a block of //! or /// +# comments) as a brief description. This used to be the default behaviour. +# The new default is to treat a multi-line C++ comment block as a detailed +# description. Set this tag to YES if you prefer the old behaviour instead. + +MULTILINE_CPP_IS_BRIEF = NO + +# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented +# member inherits the documentation from any documented member that it +# re-implements. + +INHERIT_DOCS = YES + +# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce +# a new page for each member. If set to NO, the documentation of a member will +# be part of the file/class/namespace that contains it. + +SEPARATE_MEMBER_PAGES = YES + +# The TAB_SIZE tag can be used to set the number of spaces in a tab. +# Doxygen uses this value to replace tabs by spaces in code fragments. + +TAB_SIZE = 8 + +# This tag can be used to specify a number of aliases that acts +# as commands in the documentation. An alias has the form "name=value". +# For example adding "sideeffect=\par Side Effects:\n" will allow you to +# put the command \sideeffect (or @sideeffect) in the documentation, which +# will result in a user-defined paragraph with heading "Side Effects:". +# You can put \n's in the value part of an alias to insert newlines. + +ALIASES = + +# This tag can be used to specify a number of word-keyword mappings (TCL only). +# A mapping has the form "name=value". For example adding +# "class=itcl::class" will allow you to use the command class in the +# itcl::class meaning. + +TCL_SUBST = + +# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C +# sources only. Doxygen will then generate output that is more tailored for C. +# For instance, some of the names that are used will be different. The list +# of all members will be omitted, etc. + +OPTIMIZE_OUTPUT_FOR_C = YES + +# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java +# sources only. Doxygen will then generate output that is more tailored for +# Java. For instance, namespaces will be presented as packages, qualified +# scopes will look different, etc. + +OPTIMIZE_OUTPUT_JAVA = NO + +# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran +# sources only. Doxygen will then generate output that is more tailored for +# Fortran. + +OPTIMIZE_FOR_FORTRAN = NO + +# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL +# sources. Doxygen will then generate output that is tailored for +# VHDL. + +OPTIMIZE_OUTPUT_VHDL = NO + +# Doxygen selects the parser to use depending on the extension of the files it +# parses. With this tag you can assign which parser to use for a given extension. +# Doxygen has a built-in mapping, but you can override or extend it using this +# tag. The format is ext=language, where ext is a file extension, and language +# is one of the parsers supported by doxygen: IDL, Java, Javascript, CSharp, C, +# C++, D, PHP, Objective-C, Python, Fortran, VHDL, C, C++. For instance to make +# doxygen treat .inc files as Fortran files (default is PHP), and .f files as C +# (default is Fortran), use: inc=Fortran f=C. Note that for custom extensions +# you also need to set FILE_PATTERNS otherwise the files are not read by doxygen. + +EXTENSION_MAPPING = + +# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want +# to include (a tag file for) the STL sources as input, then you should +# set this tag to YES in order to let doxygen match functions declarations and +# definitions whose arguments contain STL classes (e.g. func(std::string); v.s. +# func(std::string) {}). This also makes the inheritance and collaboration +# diagrams that involve STL classes more complete and accurate. + +BUILTIN_STL_SUPPORT = NO + +# If you use Microsoft's C++/CLI language, you should set this option to YES to +# enable parsing support. + +CPP_CLI_SUPPORT = NO + +# Set the SIP_SUPPORT tag to YES if your project consists of sip sources only. +# Doxygen will parse them like normal C++ but will assume all classes use public +# instead of private inheritance when no explicit protection keyword is present. + +SIP_SUPPORT = NO + +# For Microsoft's IDL there are propget and propput attributes to indicate getter +# and setter methods for a property. Setting this option to YES (the default) +# will make doxygen replace the get and set methods by a property in the +# documentation. This will only work if the methods are indeed getting or +# setting a simple type. If this is not the case, or you want to show the +# methods anyway, you should set this option to NO. + +IDL_PROPERTY_SUPPORT = YES + +# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC +# tag is set to YES, then doxygen will reuse the documentation of the first +# member in the group (if any) for the other members of the group. By default +# all members of a group must be documented explicitly. + +DISTRIBUTE_GROUP_DOC = NO + +# Set the SUBGROUPING tag to YES (the default) to allow class member groups of +# the same type (for instance a group of public functions) to be put as a +# subgroup of that type (e.g. under the Public Functions section). Set it to +# NO to prevent subgrouping. Alternatively, this can be done per class using +# the \nosubgrouping command. + +SUBGROUPING = YES + +# When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and +# unions are shown inside the group in which they are included (e.g. using +# @ingroup) instead of on a separate page (for HTML and Man pages) or +# section (for LaTeX and RTF). + +INLINE_GROUPED_CLASSES = NO + +# When the INLINE_SIMPLE_STRUCTS tag is set to YES, structs, classes, and +# unions with only public data fields will be shown inline in the documentation +# of the scope in which they are defined (i.e. file, namespace, or group +# documentation), provided this scope is documented. If set to NO (the default), +# structs, classes, and unions are shown on a separate page (for HTML and Man +# pages) or section (for LaTeX and RTF). + +INLINE_SIMPLE_STRUCTS = NO + +# When TYPEDEF_HIDES_STRUCT is enabled, a typedef of a struct, union, or enum +# is documented as struct, union, or enum with the name of the typedef. So +# typedef struct TypeS {} TypeT, will appear in the documentation as a struct +# with name TypeT. When disabled the typedef will appear as a member of a file, +# namespace, or class. And the struct will be named TypeS. This can typically +# be useful for C code in case the coding convention dictates that all compound +# types are typedef'ed and only the typedef is referenced, never the tag name. + +TYPEDEF_HIDES_STRUCT = NO + +# Similar to the SYMBOL_CACHE_SIZE the size of the symbol lookup cache can be +# set using LOOKUP_CACHE_SIZE. This cache is used to resolve symbols given +# their name and scope. Since this can be an expensive process and often the +# same symbol appear multiple times in the code, doxygen keeps a cache of +# pre-resolved symbols. If the cache is too small doxygen will become slower. +# If the cache is too large, memory is wasted. The cache size is given by this +# formula: 2^(16+LOOKUP_CACHE_SIZE). The valid range is 0..9, the default is 0, +# corresponding to a cache size of 2^16 = 65536 symbols. + +LOOKUP_CACHE_SIZE = 0 + +#--------------------------------------------------------------------------- +# Build related configuration options +#--------------------------------------------------------------------------- + +# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in +# documentation are documented, even if no documentation was available. +# Private class members and static file members will be hidden unless +# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES + +EXTRACT_ALL = NO + +# If the EXTRACT_PRIVATE tag is set to YES all private members of a class +# will be included in the documentation. + +EXTRACT_PRIVATE = NO + +# If the EXTRACT_STATIC tag is set to YES all static members of a file +# will be included in the documentation. + +EXTRACT_STATIC = NO + +# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) +# defined locally in source files will be included in the documentation. +# If set to NO only classes defined in header files are included. + +EXTRACT_LOCAL_CLASSES = YES + +# This flag is only useful for Objective-C code. When set to YES local +# methods, which are defined in the implementation section but not in +# the interface are included in the documentation. +# If set to NO (the default) only methods in the interface are included. + +EXTRACT_LOCAL_METHODS = NO + +# If this flag is set to YES, the members of anonymous namespaces will be +# extracted and appear in the documentation as a namespace called +# 'anonymous_namespace{file}', where file will be replaced with the base +# name of the file that contains the anonymous namespace. By default +# anonymous namespaces are hidden. + +EXTRACT_ANON_NSPACES = NO + +# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all +# undocumented members of documented classes, files or namespaces. +# If set to NO (the default) these members will be included in the +# various overviews, but no documentation section is generated. +# This option has no effect if EXTRACT_ALL is enabled. + +HIDE_UNDOC_MEMBERS = NO + +# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all +# undocumented classes that are normally visible in the class hierarchy. +# If set to NO (the default) these classes will be included in the various +# overviews. This option has no effect if EXTRACT_ALL is enabled. + +HIDE_UNDOC_CLASSES = NO + +# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all +# friend (class|struct|union) declarations. +# If set to NO (the default) these declarations will be included in the +# documentation. + +HIDE_FRIEND_COMPOUNDS = NO + +# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any +# documentation blocks found inside the body of a function. +# If set to NO (the default) these blocks will be appended to the +# function's detailed documentation block. + +HIDE_IN_BODY_DOCS = NO + +# The INTERNAL_DOCS tag determines if documentation +# that is typed after a \internal command is included. If the tag is set +# to NO (the default) then the documentation will be excluded. +# Set it to YES to include the internal documentation. + +INTERNAL_DOCS = NO + +# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate +# file names in lower-case letters. If set to YES upper-case letters are also +# allowed. This is useful if you have classes or files whose names only differ +# in case and if your file system supports case sensitive file names. Windows +# and Mac users are advised to set this option to NO. + +CASE_SENSE_NAMES = YES + +# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen +# will show members with their full class and namespace scopes in the +# documentation. If set to YES the scope will be hidden. + +HIDE_SCOPE_NAMES = NO + +# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen +# will put a list of the files that are included by a file in the documentation +# of that file. + +SHOW_INCLUDE_FILES = YES + +# If the FORCE_LOCAL_INCLUDES tag is set to YES then Doxygen +# will list include files with double quotes in the documentation +# rather than with sharp brackets. + +FORCE_LOCAL_INCLUDES = NO + +# If the INLINE_INFO tag is set to YES (the default) then a tag [inline] +# is inserted in the documentation for inline members. + +INLINE_INFO = YES + +# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen +# will sort the (detailed) documentation of file and class members +# alphabetically by member name. If set to NO the members will appear in +# declaration order. + +SORT_MEMBER_DOCS = YES + +# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the +# brief documentation of file, namespace and class members alphabetically +# by member name. If set to NO (the default) the members will appear in +# declaration order. + +SORT_BRIEF_DOCS = NO + +# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen +# will sort the (brief and detailed) documentation of class members so that +# constructors and destructors are listed first. If set to NO (the default) +# the constructors will appear in the respective orders defined by +# SORT_MEMBER_DOCS and SORT_BRIEF_DOCS. +# This tag will be ignored for brief docs if SORT_BRIEF_DOCS is set to NO +# and ignored for detailed docs if SORT_MEMBER_DOCS is set to NO. + +SORT_MEMBERS_CTORS_1ST = NO + +# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the +# hierarchy of group names into alphabetical order. If set to NO (the default) +# the group names will appear in their defined order. + +SORT_GROUP_NAMES = NO + +# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be +# sorted by fully-qualified names, including namespaces. If set to +# NO (the default), the class list will be sorted only by class name, +# not including the namespace part. +# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. +# Note: This option applies only to the class list, not to the +# alphabetical list. + +SORT_BY_SCOPE_NAME = NO + +# If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to +# do proper type resolution of all parameters of a function it will reject a +# match between the prototype and the implementation of a member function even +# if there is only one candidate or it is obvious which candidate to choose +# by doing a simple string match. By disabling STRICT_PROTO_MATCHING doxygen +# will still accept a match between prototype and implementation in such cases. + +STRICT_PROTO_MATCHING = NO + +# The GENERATE_TODOLIST tag can be used to enable (YES) or +# disable (NO) the todo list. This list is created by putting \todo +# commands in the documentation. + +GENERATE_TODOLIST = YES + +# The GENERATE_TESTLIST tag can be used to enable (YES) or +# disable (NO) the test list. This list is created by putting \test +# commands in the documentation. + +GENERATE_TESTLIST = YES + +# The GENERATE_BUGLIST tag can be used to enable (YES) or +# disable (NO) the bug list. This list is created by putting \bug +# commands in the documentation. + +GENERATE_BUGLIST = YES + +# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or +# disable (NO) the deprecated list. This list is created by putting +# \deprecated commands in the documentation. + +GENERATE_DEPRECATEDLIST= YES + +# The ENABLED_SECTIONS tag can be used to enable conditional +# documentation sections, marked by \if sectionname ... \endif. + +ENABLED_SECTIONS = + +# The MAX_INITIALIZER_LINES tag determines the maximum number of lines +# the initial value of a variable or macro consists of for it to appear in +# the documentation. If the initializer consists of more lines than specified +# here it will be hidden. Use a value of 0 to hide initializers completely. +# The appearance of the initializer of individual variables and macros in the +# documentation can be controlled using \showinitializer or \hideinitializer +# command in the documentation regardless of this setting. + +MAX_INITIALIZER_LINES = 30 + +# Set the SHOW_USED_FILES tag to NO to disable the list of files generated +# at the bottom of the documentation of classes and structs. If set to YES the +# list will mention the files that were used to generate the documentation. + +SHOW_USED_FILES = YES + +# Set the SHOW_FILES tag to NO to disable the generation of the Files page. +# This will remove the Files entry from the Quick Index and from the +# Folder Tree View (if specified). The default is YES. + +SHOW_FILES = YES + +# Set the SHOW_NAMESPACES tag to NO to disable the generation of the +# Namespaces page. +# This will remove the Namespaces entry from the Quick Index +# and from the Folder Tree View (if specified). The default is YES. + +SHOW_NAMESPACES = YES + +# The FILE_VERSION_FILTER tag can be used to specify a program or script that +# doxygen should invoke to get the current version for each file (typically from +# the version control system). Doxygen will invoke the program by executing (via +# popen()) the command , where is the value of +# the FILE_VERSION_FILTER tag, and is the name of an input file +# provided by doxygen. Whatever the program writes to standard output +# is used as the file version. See the manual for examples. + +FILE_VERSION_FILTER = + +# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed +# by doxygen. The layout file controls the global structure of the generated +# output files in an output format independent way. The create the layout file +# that represents doxygen's defaults, run doxygen with the -l option. +# You can optionally specify a file name after the option, if omitted +# DoxygenLayout.xml will be used as the name of the layout file. + +LAYOUT_FILE = + +# The CITE_BIB_FILES tag can be used to specify one or more bib files +# containing the references data. This must be a list of .bib files. The +# .bib extension is automatically appended if omitted. Using this command +# requires the bibtex tool to be installed. See also +# http://en.wikipedia.org/wiki/BibTeX for more info. For LaTeX the style +# of the bibliography can be controlled using LATEX_BIB_STYLE. To use this +# feature you need bibtex and perl available in the search path. + +CITE_BIB_FILES = + +#--------------------------------------------------------------------------- +# configuration options related to warning and progress messages +#--------------------------------------------------------------------------- + +# The QUIET tag can be used to turn on/off the messages that are generated +# by doxygen. Possible values are YES and NO. If left blank NO is used. + +QUIET = NO + +# The WARNINGS tag can be used to turn on/off the warning messages that are +# generated by doxygen. Possible values are YES and NO. If left blank +# NO is used. + +WARNINGS = YES + +# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings +# for undocumented members. If EXTRACT_ALL is set to YES then this flag will +# automatically be disabled. + +WARN_IF_UNDOCUMENTED = YES + +# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for +# potential errors in the documentation, such as not documenting some +# parameters in a documented function, or documenting parameters that +# don't exist or using markup commands wrongly. + +WARN_IF_DOC_ERROR = YES + +# The WARN_NO_PARAMDOC option can be enabled to get warnings for +# functions that are documented, but have no documentation for their parameters +# or return value. If set to NO (the default) doxygen will only warn about +# wrong or incomplete parameter documentation, but not about the absence of +# documentation. + +WARN_NO_PARAMDOC = NO + +# The WARN_FORMAT tag determines the format of the warning messages that +# doxygen can produce. The string should contain the $file, $line, and $text +# tags, which will be replaced by the file and line number from which the +# warning originated and the warning text. Optionally the format may contain +# $version, which will be replaced by the version of the file (if it could +# be obtained via FILE_VERSION_FILTER) + +WARN_FORMAT = "$file:$line: $text" + +# The WARN_LOGFILE tag can be used to specify a file to which warning +# and error messages should be written. If left blank the output is written +# to stderr. + +WARN_LOGFILE = + +#--------------------------------------------------------------------------- +# configuration options related to the input files +#--------------------------------------------------------------------------- + +# The INPUT tag can be used to specify the files and/or directories that contain +# documented source files. You may enter file names like "myfile.cpp" or +# directories like "/usr/src/myproject". Separate the files or directories +# with spaces. + +INPUT = yrmcds.h + +# This tag can be used to specify the character encoding of the source files +# that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is +# also the default input encoding. Doxygen uses libiconv (or the iconv built +# into libc) for the transcoding. See http://www.gnu.org/software/libiconv for +# the list of possible encodings. + +INPUT_ENCODING = UTF-8 + +# If the value of the INPUT tag contains directories, you can use the +# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left +# blank the following patterns are tested: +# *.c *.cc *.cxx *.cpp *.c++ *.d *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh +# *.hxx *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.dox *.py +# *.f90 *.f *.for *.vhd *.vhdl + +FILE_PATTERNS = + +# The RECURSIVE tag can be used to turn specify whether or not subdirectories +# should be searched for input files as well. Possible values are YES and NO. +# If left blank NO is used. + +RECURSIVE = NO + +# The EXCLUDE tag can be used to specify files and/or directories that should be +# excluded from the INPUT source files. This way you can easily exclude a +# subdirectory from a directory tree whose root is specified with the INPUT tag. +# Note that relative paths are relative to the directory from which doxygen is +# run. + +EXCLUDE = + +# The EXCLUDE_SYMLINKS tag can be used to select whether or not files or +# directories that are symbolic links (a Unix file system feature) are excluded +# from the input. + +EXCLUDE_SYMLINKS = NO + +# If the value of the INPUT tag contains directories, you can use the +# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude +# certain files from those directories. Note that the wildcards are matched +# against the file with absolute path, so to exclude all test directories +# for example use the pattern */test/* + +EXCLUDE_PATTERNS = + +# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names +# (namespaces, classes, functions, etc.) that should be excluded from the +# output. The symbol name can be a fully qualified name, a word, or if the +# wildcard * is used, a substring. Examples: ANamespace, AClass, +# AClass::ANamespace, ANamespace::*Test + +EXCLUDE_SYMBOLS = + +# The EXAMPLE_PATH tag can be used to specify one or more files or +# directories that contain example code fragments that are included (see +# the \include command). + +EXAMPLE_PATH = + +# If the value of the EXAMPLE_PATH tag contains directories, you can use the +# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left +# blank all files are included. + +EXAMPLE_PATTERNS = + +# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be +# searched for input files to be used with the \include or \dontinclude +# commands irrespective of the value of the RECURSIVE tag. +# Possible values are YES and NO. If left blank NO is used. + +EXAMPLE_RECURSIVE = NO + +# The IMAGE_PATH tag can be used to specify one or more files or +# directories that contain image that are included in the documentation (see +# the \image command). + +IMAGE_PATH = + +# The INPUT_FILTER tag can be used to specify a program that doxygen should +# invoke to filter for each input file. Doxygen will invoke the filter program +# by executing (via popen()) the command , where +# is the value of the INPUT_FILTER tag, and is the name of an +# input file. Doxygen will then use the output that the filter program writes +# to standard output. +# If FILTER_PATTERNS is specified, this tag will be +# ignored. + +INPUT_FILTER = + +# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern +# basis. +# Doxygen will compare the file name with each pattern and apply the +# filter if there is a match. +# The filters are a list of the form: +# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further +# info on how filters are used. If FILTER_PATTERNS is empty or if +# non of the patterns match the file name, INPUT_FILTER is applied. + +FILTER_PATTERNS = + +# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using +# INPUT_FILTER) will be used to filter the input files when producing source +# files to browse (i.e. when SOURCE_BROWSER is set to YES). + +FILTER_SOURCE_FILES = NO + +# The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file +# pattern. A pattern will override the setting for FILTER_PATTERN (if any) +# and it is also possible to disable source filtering for a specific pattern +# using *.ext= (so without naming a filter). This option only has effect when +# FILTER_SOURCE_FILES is enabled. + +FILTER_SOURCE_PATTERNS = + +#--------------------------------------------------------------------------- +# configuration options related to source browsing +#--------------------------------------------------------------------------- + +# If the SOURCE_BROWSER tag is set to YES then a list of source files will +# be generated. Documented entities will be cross-referenced with these sources. +# Note: To get rid of all source code in the generated output, make sure also +# VERBATIM_HEADERS is set to NO. + +SOURCE_BROWSER = NO + +# Setting the INLINE_SOURCES tag to YES will include the body +# of functions and classes directly in the documentation. + +INLINE_SOURCES = NO + +# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct +# doxygen to hide any special comment blocks from generated source code +# fragments. Normal C and C++ comments will always remain visible. + +STRIP_CODE_COMMENTS = YES + +# If the REFERENCED_BY_RELATION tag is set to YES +# then for each documented function all documented +# functions referencing it will be listed. + +REFERENCED_BY_RELATION = NO + +# If the REFERENCES_RELATION tag is set to YES +# then for each documented function all documented entities +# called/used by that function will be listed. + +REFERENCES_RELATION = NO + +# If the REFERENCES_LINK_SOURCE tag is set to YES (the default) +# and SOURCE_BROWSER tag is set to YES, then the hyperlinks from +# functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will +# link to the source code. +# Otherwise they will link to the documentation. + +REFERENCES_LINK_SOURCE = YES + +# If the USE_HTAGS tag is set to YES then the references to source code +# will point to the HTML generated by the htags(1) tool instead of doxygen +# built-in source browser. The htags tool is part of GNU's global source +# tagging system (see http://www.gnu.org/software/global/global.html). You +# will need version 4.8.6 or higher. + +USE_HTAGS = NO + +# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen +# will generate a verbatim copy of the header file for each class for +# which an include is specified. Set to NO to disable this. + +VERBATIM_HEADERS = NO + +#--------------------------------------------------------------------------- +# configuration options related to the alphabetical class index +#--------------------------------------------------------------------------- + +# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index +# of all compounds will be generated. Enable this if the project +# contains a lot of classes, structs, unions or interfaces. + +ALPHABETICAL_INDEX = YES + +# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then +# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns +# in which this list will be split (can be a number in the range [1..20]) + +COLS_IN_ALPHA_INDEX = 5 + +# In case all classes in a project start with a common prefix, all +# classes will be put under the same header in the alphabetical index. +# The IGNORE_PREFIX tag can be used to specify one or more prefixes that +# should be ignored while generating the index headers. + +IGNORE_PREFIX = + +#--------------------------------------------------------------------------- +# configuration options related to the HTML output +#--------------------------------------------------------------------------- + +# If the GENERATE_HTML tag is set to YES (the default) Doxygen will +# generate HTML output. + +GENERATE_HTML = YES + +# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `html' will be used as the default path. + +HTML_OUTPUT = html + +# The HTML_FILE_EXTENSION tag can be used to specify the file extension for +# each generated HTML page (for example: .htm,.php,.asp). If it is left blank +# doxygen will generate files with .html extension. + +HTML_FILE_EXTENSION = .html + +# The HTML_HEADER tag can be used to specify a personal HTML header for +# each generated HTML page. If it is left blank doxygen will generate a +# standard header. Note that when using a custom header you are responsible +# for the proper inclusion of any scripts and style sheets that doxygen +# needs, which is dependent on the configuration options used. +# It is advised to generate a default header using "doxygen -w html +# header.html footer.html stylesheet.css YourConfigFile" and then modify +# that header. Note that the header is subject to change so you typically +# have to redo this when upgrading to a newer version of doxygen or when +# changing the value of configuration settings such as GENERATE_TREEVIEW! + +HTML_HEADER = + +# The HTML_FOOTER tag can be used to specify a personal HTML footer for +# each generated HTML page. If it is left blank doxygen will generate a +# standard footer. + +HTML_FOOTER = + +# The HTML_STYLESHEET tag can be used to specify a user-defined cascading +# style sheet that is used by each HTML page. It can be used to +# fine-tune the look of the HTML output. If the tag is left blank doxygen +# will generate a default style sheet. Note that doxygen will try to copy +# the style sheet file to the HTML output directory, so don't put your own +# style sheet in the HTML output directory as well, or it will be erased! + +HTML_STYLESHEET = + +# The HTML_EXTRA_FILES tag can be used to specify one or more extra images or +# other source files which should be copied to the HTML output directory. Note +# that these files will be copied to the base HTML output directory. Use the +# $relpath$ marker in the HTML_HEADER and/or HTML_FOOTER files to load these +# files. In the HTML_STYLESHEET file, use the file name only. Also note that +# the files will be copied as-is; there are no commands or markers available. + +HTML_EXTRA_FILES = + +# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. +# Doxygen will adjust the colors in the style sheet and background images +# according to this color. Hue is specified as an angle on a colorwheel, +# see http://en.wikipedia.org/wiki/Hue for more information. +# For instance the value 0 represents red, 60 is yellow, 120 is green, +# 180 is cyan, 240 is blue, 300 purple, and 360 is red again. +# The allowed range is 0 to 359. + +HTML_COLORSTYLE_HUE = 220 + +# The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of +# the colors in the HTML output. For a value of 0 the output will use +# grayscales only. A value of 255 will produce the most vivid colors. + +HTML_COLORSTYLE_SAT = 100 + +# The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to +# the luminance component of the colors in the HTML output. Values below +# 100 gradually make the output lighter, whereas values above 100 make +# the output darker. The value divided by 100 is the actual gamma applied, +# so 80 represents a gamma of 0.8, The value 220 represents a gamma of 2.2, +# and 100 does not change the gamma. + +HTML_COLORSTYLE_GAMMA = 80 + +# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML +# page will contain the date and time when the page was generated. Setting +# this to NO can help when comparing the output of multiple runs. + +HTML_TIMESTAMP = YES + +# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML +# documentation will contain sections that can be hidden and shown after the +# page has loaded. For this to work a browser that supports +# JavaScript and DHTML is required (for instance Mozilla 1.0+, Firefox +# Netscape 6.0+, Internet explorer 5.0+, Konqueror, or Safari). + +HTML_DYNAMIC_SECTIONS = NO + +# If the GENERATE_DOCSET tag is set to YES, additional index files +# will be generated that can be used as input for Apple's Xcode 3 +# integrated development environment, introduced with OSX 10.5 (Leopard). +# To create a documentation set, doxygen will generate a Makefile in the +# HTML output directory. Running make will produce the docset in that +# directory and running "make install" will install the docset in +# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find +# it at startup. +# See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html +# for more information. + +GENERATE_DOCSET = NO + +# When GENERATE_DOCSET tag is set to YES, this tag determines the name of the +# feed. A documentation feed provides an umbrella under which multiple +# documentation sets from a single provider (such as a company or product suite) +# can be grouped. + +DOCSET_FEEDNAME = "Doxygen generated docs" + +# When GENERATE_DOCSET tag is set to YES, this tag specifies a string that +# should uniquely identify the documentation set bundle. This should be a +# reverse domain-name style string, e.g. com.mycompany.MyDocSet. Doxygen +# will append .docset to the name. + +DOCSET_BUNDLE_ID = org.doxygen.Project + +# When GENERATE_PUBLISHER_ID tag specifies a string that should uniquely identify +# the documentation publisher. This should be a reverse domain-name style +# string, e.g. com.mycompany.MyDocSet.documentation. + +DOCSET_PUBLISHER_ID = org.doxygen.Publisher + +# The GENERATE_PUBLISHER_NAME tag identifies the documentation publisher. + +DOCSET_PUBLISHER_NAME = Publisher + +# If the GENERATE_HTMLHELP tag is set to YES, additional index files +# will be generated that can be used as input for tools like the +# Microsoft HTML help workshop to generate a compiled HTML help file (.chm) +# of the generated HTML documentation. + +GENERATE_HTMLHELP = NO + +# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can +# be used to specify the file name of the resulting .chm file. You +# can add a path in front of the file if the result should not be +# written to the html output directory. + +CHM_FILE = + +# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can +# be used to specify the location (absolute path including file name) of +# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run +# the HTML help compiler on the generated index.hhp. + +HHC_LOCATION = + +# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag +# controls if a separate .chi index file is generated (YES) or that +# it should be included in the master .chm file (NO). + +GENERATE_CHI = NO + +# If the GENERATE_HTMLHELP tag is set to YES, the CHM_INDEX_ENCODING +# is used to encode HtmlHelp index (hhk), content (hhc) and project file +# content. + +CHM_INDEX_ENCODING = + +# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag +# controls whether a binary table of contents is generated (YES) or a +# normal table of contents (NO) in the .chm file. + +BINARY_TOC = NO + +# The TOC_EXPAND flag can be set to YES to add extra items for group members +# to the contents of the HTML help documentation and to the tree view. + +TOC_EXPAND = NO + +# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and +# QHP_VIRTUAL_FOLDER are set, an additional index file will be generated +# that can be used as input for Qt's qhelpgenerator to generate a +# Qt Compressed Help (.qch) of the generated HTML documentation. + +GENERATE_QHP = NO + +# If the QHG_LOCATION tag is specified, the QCH_FILE tag can +# be used to specify the file name of the resulting .qch file. +# The path specified is relative to the HTML output folder. + +QCH_FILE = + +# The QHP_NAMESPACE tag specifies the namespace to use when generating +# Qt Help Project output. For more information please see +# http://doc.trolltech.com/qthelpproject.html#namespace + +QHP_NAMESPACE = org.doxygen.Project + +# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating +# Qt Help Project output. For more information please see +# http://doc.trolltech.com/qthelpproject.html#virtual-folders + +QHP_VIRTUAL_FOLDER = doc + +# If QHP_CUST_FILTER_NAME is set, it specifies the name of a custom filter to +# add. For more information please see +# http://doc.trolltech.com/qthelpproject.html#custom-filters + +QHP_CUST_FILTER_NAME = + +# The QHP_CUST_FILT_ATTRS tag specifies the list of the attributes of the +# custom filter to add. For more information please see +# +# Qt Help Project / Custom Filters. + +QHP_CUST_FILTER_ATTRS = + +# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this +# project's +# filter section matches. +# +# Qt Help Project / Filter Attributes. + +QHP_SECT_FILTER_ATTRS = + +# If the GENERATE_QHP tag is set to YES, the QHG_LOCATION tag can +# be used to specify the location of Qt's qhelpgenerator. +# If non-empty doxygen will try to run qhelpgenerator on the generated +# .qhp file. + +QHG_LOCATION = + +# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files +# will be generated, which together with the HTML files, form an Eclipse help +# plugin. To install this plugin and make it available under the help contents +# menu in Eclipse, the contents of the directory containing the HTML and XML +# files needs to be copied into the plugins directory of eclipse. The name of +# the directory within the plugins directory should be the same as +# the ECLIPSE_DOC_ID value. After copying Eclipse needs to be restarted before +# the help appears. + +GENERATE_ECLIPSEHELP = NO + +# A unique identifier for the eclipse help plugin. When installing the plugin +# the directory name containing the HTML and XML files should also have +# this name. + +ECLIPSE_DOC_ID = org.doxygen.Project + +# The DISABLE_INDEX tag can be used to turn on/off the condensed index (tabs) +# at top of each HTML page. The value NO (the default) enables the index and +# the value YES disables it. Since the tabs have the same information as the +# navigation tree you can set this option to NO if you already set +# GENERATE_TREEVIEW to YES. + +DISABLE_INDEX = NO + +# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index +# structure should be generated to display hierarchical information. +# If the tag value is set to YES, a side panel will be generated +# containing a tree-like index structure (just like the one that +# is generated for HTML Help). For this to work a browser that supports +# JavaScript, DHTML, CSS and frames is required (i.e. any modern browser). +# Windows users are probably better off using the HTML help feature. +# Since the tree basically has the same information as the tab index you +# could consider to set DISABLE_INDEX to NO when enabling this option. + +GENERATE_TREEVIEW = NO + +# The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values +# (range [0,1..20]) that doxygen will group on one line in the generated HTML +# documentation. Note that a value of 0 will completely suppress the enum +# values from appearing in the overview section. + +ENUM_VALUES_PER_LINE = 4 + +# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be +# used to set the initial width (in pixels) of the frame in which the tree +# is shown. + +TREEVIEW_WIDTH = 250 + +# When the EXT_LINKS_IN_WINDOW option is set to YES doxygen will open +# links to external symbols imported via tag files in a separate window. + +EXT_LINKS_IN_WINDOW = NO + +# Use this tag to change the font size of Latex formulas included +# as images in the HTML documentation. The default is 10. Note that +# when you change the font size after a successful doxygen run you need +# to manually remove any form_*.png images from the HTML output directory +# to force them to be regenerated. + +FORMULA_FONTSIZE = 10 + +# Use the FORMULA_TRANPARENT tag to determine whether or not the images +# generated for formulas are transparent PNGs. Transparent PNGs are +# not supported properly for IE 6.0, but are supported on all modern browsers. +# Note that when changing this option you need to delete any form_*.png files +# in the HTML output before the changes have effect. + +FORMULA_TRANSPARENT = YES + +# Enable the USE_MATHJAX option to render LaTeX formulas using MathJax +# (see http://www.mathjax.org) which uses client side Javascript for the +# rendering instead of using prerendered bitmaps. Use this if you do not +# have LaTeX installed or if you want to formulas look prettier in the HTML +# output. When enabled you also need to install MathJax separately and +# configure the path to it using the MATHJAX_RELPATH option. + +USE_MATHJAX = NO + +# When MathJax is enabled you need to specify the location relative to the +# HTML output directory using the MATHJAX_RELPATH option. The destination +# directory should contain the MathJax.js script. For instance, if the mathjax +# directory is located at the same level as the HTML output directory, then +# MATHJAX_RELPATH should be ../mathjax. The default value points to the +# mathjax.org site, so you can quickly see the result without installing +# MathJax, but it is strongly recommended to install a local copy of MathJax +# before deployment. + +MATHJAX_RELPATH = http://www.mathjax.org/mathjax + +# The MATHJAX_EXTENSIONS tag can be used to specify one or MathJax extension +# names that should be enabled during MathJax rendering. + +MATHJAX_EXTENSIONS = + +# When the SEARCHENGINE tag is enabled doxygen will generate a search box +# for the HTML output. The underlying search engine uses javascript +# and DHTML and should work on any modern browser. Note that when using +# HTML help (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets +# (GENERATE_DOCSET) there is already a search function so this one should +# typically be disabled. For large projects the javascript based search engine +# can be slow, then enabling SERVER_BASED_SEARCH may provide a better solution. + +SEARCHENGINE = YES + +# When the SERVER_BASED_SEARCH tag is enabled the search engine will be +# implemented using a PHP enabled web server instead of at the web client +# using Javascript. Doxygen will generate the search PHP script and index +# file to put on the web server. The advantage of the server +# based approach is that it scales better to large projects and allows +# full text search. The disadvantages are that it is more difficult to setup +# and does not have live searching capabilities. + +SERVER_BASED_SEARCH = NO + +#--------------------------------------------------------------------------- +# configuration options related to the LaTeX output +#--------------------------------------------------------------------------- + +# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will +# generate Latex output. + +GENERATE_LATEX = NO + +# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `latex' will be used as the default path. + +LATEX_OUTPUT = latex + +# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be +# invoked. If left blank `latex' will be used as the default command name. +# Note that when enabling USE_PDFLATEX this option is only used for +# generating bitmaps for formulas in the HTML output, but not in the +# Makefile that is written to the output directory. + +LATEX_CMD_NAME = latex + +# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to +# generate index for LaTeX. If left blank `makeindex' will be used as the +# default command name. + +MAKEINDEX_CMD_NAME = makeindex + +# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact +# LaTeX documents. This may be useful for small projects and may help to +# save some trees in general. + +COMPACT_LATEX = NO + +# The PAPER_TYPE tag can be used to set the paper type that is used +# by the printer. Possible values are: a4, letter, legal and +# executive. If left blank a4wide will be used. + +PAPER_TYPE = a4 + +# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX +# packages that should be included in the LaTeX output. + +EXTRA_PACKAGES = + +# The LATEX_HEADER tag can be used to specify a personal LaTeX header for +# the generated latex document. The header should contain everything until +# the first chapter. If it is left blank doxygen will generate a +# standard header. Notice: only use this tag if you know what you are doing! + +LATEX_HEADER = + +# The LATEX_FOOTER tag can be used to specify a personal LaTeX footer for +# the generated latex document. The footer should contain everything after +# the last chapter. If it is left blank doxygen will generate a +# standard footer. Notice: only use this tag if you know what you are doing! + +LATEX_FOOTER = + +# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated +# is prepared for conversion to pdf (using ps2pdf). The pdf file will +# contain links (just like the HTML output) instead of page references +# This makes the output suitable for online browsing using a pdf viewer. + +PDF_HYPERLINKS = YES + +# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of +# plain latex in the generated Makefile. Set this option to YES to get a +# higher quality PDF documentation. + +USE_PDFLATEX = YES + +# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. +# command to the generated LaTeX files. This will instruct LaTeX to keep +# running if errors occur, instead of asking the user for help. +# This option is also used when generating formulas in HTML. + +LATEX_BATCHMODE = NO + +# If LATEX_HIDE_INDICES is set to YES then doxygen will not +# include the index chapters (such as File Index, Compound Index, etc.) +# in the output. + +LATEX_HIDE_INDICES = NO + +# If LATEX_SOURCE_CODE is set to YES then doxygen will include +# source code with syntax highlighting in the LaTeX output. +# Note that which sources are shown also depends on other settings +# such as SOURCE_BROWSER. + +LATEX_SOURCE_CODE = NO + +# The LATEX_BIB_STYLE tag can be used to specify the style to use for the +# bibliography, e.g. plainnat, or ieeetr. The default style is "plain". See +# http://en.wikipedia.org/wiki/BibTeX for more info. + +LATEX_BIB_STYLE = plain + +#--------------------------------------------------------------------------- +# configuration options related to the RTF output +#--------------------------------------------------------------------------- + +# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output +# The RTF output is optimized for Word 97 and may not look very pretty with +# other RTF readers or editors. + +GENERATE_RTF = NO + +# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `rtf' will be used as the default path. + +RTF_OUTPUT = rtf + +# If the COMPACT_RTF tag is set to YES Doxygen generates more compact +# RTF documents. This may be useful for small projects and may help to +# save some trees in general. + +COMPACT_RTF = NO + +# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated +# will contain hyperlink fields. The RTF file will +# contain links (just like the HTML output) instead of page references. +# This makes the output suitable for online browsing using WORD or other +# programs which support those fields. +# Note: wordpad (write) and others do not support links. + +RTF_HYPERLINKS = NO + +# Load style sheet definitions from file. Syntax is similar to doxygen's +# config file, i.e. a series of assignments. You only have to provide +# replacements, missing definitions are set to their default value. + +RTF_STYLESHEET_FILE = + +# Set optional variables used in the generation of an rtf document. +# Syntax is similar to doxygen's config file. + +RTF_EXTENSIONS_FILE = + +#--------------------------------------------------------------------------- +# configuration options related to the man page output +#--------------------------------------------------------------------------- + +# If the GENERATE_MAN tag is set to YES (the default) Doxygen will +# generate man pages + +GENERATE_MAN = NO + +# The MAN_OUTPUT tag is used to specify where the man pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `man' will be used as the default path. + +MAN_OUTPUT = man + +# The MAN_EXTENSION tag determines the extension that is added to +# the generated man pages (default is the subroutine's section .3) + +MAN_EXTENSION = .3 + +# If the MAN_LINKS tag is set to YES and Doxygen generates man output, +# then it will generate one additional man file for each entity +# documented in the real man page(s). These additional files +# only source the real man page, but without them the man command +# would be unable to find the correct page. The default is NO. + +MAN_LINKS = NO + +#--------------------------------------------------------------------------- +# configuration options related to the XML output +#--------------------------------------------------------------------------- + +# If the GENERATE_XML tag is set to YES Doxygen will +# generate an XML file that captures the structure of +# the code including all documentation. + +GENERATE_XML = NO + +# The XML_OUTPUT tag is used to specify where the XML pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `xml' will be used as the default path. + +XML_OUTPUT = xml + +# The XML_SCHEMA tag can be used to specify an XML schema, +# which can be used by a validating XML parser to check the +# syntax of the XML files. + +XML_SCHEMA = + +# The XML_DTD tag can be used to specify an XML DTD, +# which can be used by a validating XML parser to check the +# syntax of the XML files. + +XML_DTD = + +# If the XML_PROGRAMLISTING tag is set to YES Doxygen will +# dump the program listings (including syntax highlighting +# and cross-referencing information) to the XML output. Note that +# enabling this will significantly increase the size of the XML output. + +XML_PROGRAMLISTING = YES + +#--------------------------------------------------------------------------- +# configuration options for the AutoGen Definitions output +#--------------------------------------------------------------------------- + +# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will +# generate an AutoGen Definitions (see autogen.sf.net) file +# that captures the structure of the code including all +# documentation. Note that this feature is still experimental +# and incomplete at the moment. + +GENERATE_AUTOGEN_DEF = NO + +#--------------------------------------------------------------------------- +# configuration options related to the Perl module output +#--------------------------------------------------------------------------- + +# If the GENERATE_PERLMOD tag is set to YES Doxygen will +# generate a Perl module file that captures the structure of +# the code including all documentation. Note that this +# feature is still experimental and incomplete at the +# moment. + +GENERATE_PERLMOD = NO + +# If the PERLMOD_LATEX tag is set to YES Doxygen will generate +# the necessary Makefile rules, Perl scripts and LaTeX code to be able +# to generate PDF and DVI output from the Perl module output. + +PERLMOD_LATEX = NO + +# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be +# nicely formatted so it can be parsed by a human reader. +# This is useful +# if you want to understand what is going on. +# On the other hand, if this +# tag is set to NO the size of the Perl module output will be much smaller +# and Perl will parse it just the same. + +PERLMOD_PRETTY = YES + +# The names of the make variables in the generated doxyrules.make file +# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. +# This is useful so different doxyrules.make files included by the same +# Makefile don't overwrite each other's variables. + +PERLMOD_MAKEVAR_PREFIX = + +#--------------------------------------------------------------------------- +# Configuration options related to the preprocessor +#--------------------------------------------------------------------------- + +# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will +# evaluate all C-preprocessor directives found in the sources and include +# files. + +ENABLE_PREPROCESSING = YES + +# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro +# names in the source code. If set to NO (the default) only conditional +# compilation will be performed. Macro expansion can be done in a controlled +# way by setting EXPAND_ONLY_PREDEF to YES. + +MACRO_EXPANSION = NO + +# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES +# then the macro expansion is limited to the macros specified with the +# PREDEFINED and EXPAND_AS_DEFINED tags. + +EXPAND_ONLY_PREDEF = NO + +# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files +# pointed to by INCLUDE_PATH will be searched when a #include is found. + +SEARCH_INCLUDES = YES + +# The INCLUDE_PATH tag can be used to specify one or more directories that +# contain include files that are not input files but should be processed by +# the preprocessor. + +INCLUDE_PATH = + +# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard +# patterns (like *.h and *.hpp) to filter out the header-files in the +# directories. If left blank, the patterns specified with FILE_PATTERNS will +# be used. + +INCLUDE_FILE_PATTERNS = + +# The PREDEFINED tag can be used to specify one or more macro names that +# are defined before the preprocessor is started (similar to the -D option of +# gcc). The argument of the tag is a list of macros of the form: name +# or name=definition (no spaces). If the definition and the = are +# omitted =1 is assumed. To prevent a macro definition from being +# undefined via #undef or recursively expanded use the := operator +# instead of the = operator. + +PREDEFINED = + +# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then +# this tag can be used to specify a list of macro names that should be expanded. +# The macro definition that is found in the sources will be used. +# Use the PREDEFINED tag if you want to use a different macro definition that +# overrules the definition found in the source code. + +EXPAND_AS_DEFINED = + +# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then +# doxygen's preprocessor will remove all references to function-like macros +# that are alone on a line, have an all uppercase name, and do not end with a +# semicolon, because these will confuse the parser if not removed. + +SKIP_FUNCTION_MACROS = YES + +#--------------------------------------------------------------------------- +# Configuration::additions related to external references +#--------------------------------------------------------------------------- + +# The TAGFILES option can be used to specify one or more tagfiles. +# Optionally an initial location of the external documentation +# can be added for each tagfile. The format of a tag file without +# this location is as follows: +# +# TAGFILES = file1 file2 ... +# Adding location for the tag files is done as follows: +# +# TAGFILES = file1=loc1 "file2 = loc2" ... +# where "loc1" and "loc2" can be relative or absolute paths or +# URLs. If a location is present for each tag, the installdox tool +# does not have to be run to correct the links. +# Note that each tag file must have a unique name +# (where the name does NOT include the path) +# If a tag file is not located in the directory in which doxygen +# is run, you must also specify the path to the tagfile here. + +TAGFILES = + +# When a file name is specified after GENERATE_TAGFILE, doxygen will create +# a tag file that is based on the input files it reads. + +GENERATE_TAGFILE = + +# If the ALLEXTERNALS tag is set to YES all external classes will be listed +# in the class index. If set to NO only the inherited external classes +# will be listed. + +ALLEXTERNALS = NO + +# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed +# in the modules index. If set to NO, only the current project's groups will +# be listed. + +EXTERNAL_GROUPS = YES + +# The PERL_PATH should be the absolute path and name of the perl script +# interpreter (i.e. the result of `which perl'). + +PERL_PATH = /usr/bin/perl + +#--------------------------------------------------------------------------- +# Configuration options related to the dot tool +#--------------------------------------------------------------------------- + +# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will +# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base +# or super classes. Setting the tag to NO turns the diagrams off. Note that +# this option also works with HAVE_DOT disabled, but it is recommended to +# install and use dot, since it yields more powerful graphs. + +CLASS_DIAGRAMS = YES + +# You can define message sequence charts within doxygen comments using the \msc +# command. Doxygen will then run the mscgen tool (see +# http://www.mcternan.me.uk/mscgen/) to produce the chart and insert it in the +# documentation. The MSCGEN_PATH tag allows you to specify the directory where +# the mscgen tool resides. If left empty the tool is assumed to be found in the +# default search path. + +MSCGEN_PATH = + +# If set to YES, the inheritance and collaboration graphs will hide +# inheritance and usage relations if the target is undocumented +# or is not a class. + +HIDE_UNDOC_RELATIONS = YES + +# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is +# available from the path. This tool is part of Graphviz, a graph visualization +# toolkit from AT&T and Lucent Bell Labs. The other options in this section +# have no effect if this option is set to NO (the default) + +HAVE_DOT = NO + +# The DOT_NUM_THREADS specifies the number of dot invocations doxygen is +# allowed to run in parallel. When set to 0 (the default) doxygen will +# base this on the number of processors available in the system. You can set it +# explicitly to a value larger than 0 to get control over the balance +# between CPU load and processing speed. + +DOT_NUM_THREADS = 0 + +# By default doxygen will use the Helvetica font for all dot files that +# doxygen generates. When you want a differently looking font you can specify +# the font name using DOT_FONTNAME. You need to make sure dot is able to find +# the font, which can be done by putting it in a standard location or by setting +# the DOTFONTPATH environment variable or by setting DOT_FONTPATH to the +# directory containing the font. + +DOT_FONTNAME = Helvetica + +# The DOT_FONTSIZE tag can be used to set the size of the font of dot graphs. +# The default size is 10pt. + +DOT_FONTSIZE = 10 + +# By default doxygen will tell dot to use the Helvetica font. +# If you specify a different font using DOT_FONTNAME you can use DOT_FONTPATH to +# set the path where dot can find it. + +DOT_FONTPATH = + +# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect inheritance relations. Setting this tag to YES will force the +# CLASS_DIAGRAMS tag to NO. + +CLASS_GRAPH = YES + +# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect implementation dependencies (inheritance, containment, and +# class references variables) of the class with other documented classes. + +COLLABORATION_GRAPH = YES + +# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for groups, showing the direct groups dependencies + +GROUP_GRAPHS = YES + +# If the UML_LOOK tag is set to YES doxygen will generate inheritance and +# collaboration diagrams in a style similar to the OMG's Unified Modeling +# Language. + +UML_LOOK = NO + +# If set to YES, the inheritance and collaboration graphs will show the +# relations between templates and their instances. + +TEMPLATE_RELATIONS = NO + +# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT +# tags are set to YES then doxygen will generate a graph for each documented +# file showing the direct and indirect include dependencies of the file with +# other documented files. + +INCLUDE_GRAPH = YES + +# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and +# HAVE_DOT tags are set to YES then doxygen will generate a graph for each +# documented header file showing the documented files that directly or +# indirectly include this file. + +INCLUDED_BY_GRAPH = YES + +# If the CALL_GRAPH and HAVE_DOT options are set to YES then +# doxygen will generate a call dependency graph for every global function +# or class method. Note that enabling this option will significantly increase +# the time of a run. So in most cases it will be better to enable call graphs +# for selected functions only using the \callgraph command. + +CALL_GRAPH = NO + +# If the CALLER_GRAPH and HAVE_DOT tags are set to YES then +# doxygen will generate a caller dependency graph for every global function +# or class method. Note that enabling this option will significantly increase +# the time of a run. So in most cases it will be better to enable caller +# graphs for selected functions only using the \callergraph command. + +CALLER_GRAPH = NO + +# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen +# will generate a graphical hierarchy of all classes instead of a textual one. + +GRAPHICAL_HIERARCHY = YES + +# If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES +# then doxygen will show the dependencies a directory has on other directories +# in a graphical way. The dependency relations are determined by the #include +# relations between the files in the directories. + +DIRECTORY_GRAPH = YES + +# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images +# generated by dot. Possible values are svg, png, jpg, or gif. +# If left blank png will be used. If you choose svg you need to set +# HTML_FILE_EXTENSION to xhtml in order to make the SVG files +# visible in IE 9+ (other browsers do not have this requirement). + +DOT_IMAGE_FORMAT = png + +# If DOT_IMAGE_FORMAT is set to svg, then this option can be set to YES to +# enable generation of interactive SVG images that allow zooming and panning. +# Note that this requires a modern browser other than Internet Explorer. +# Tested and working are Firefox, Chrome, Safari, and Opera. For IE 9+ you +# need to set HTML_FILE_EXTENSION to xhtml in order to make the SVG files +# visible. Older versions of IE do not have SVG support. + +INTERACTIVE_SVG = NO + +# The tag DOT_PATH can be used to specify the path where the dot tool can be +# found. If left blank, it is assumed the dot tool can be found in the path. + +DOT_PATH = + +# The DOTFILE_DIRS tag can be used to specify one or more directories that +# contain dot files that are included in the documentation (see the +# \dotfile command). + +DOTFILE_DIRS = + +# The MSCFILE_DIRS tag can be used to specify one or more directories that +# contain msc files that are included in the documentation (see the +# \mscfile command). + +MSCFILE_DIRS = + +# The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of +# nodes that will be shown in the graph. If the number of nodes in a graph +# becomes larger than this value, doxygen will truncate the graph, which is +# visualized by representing a node as a red box. Note that doxygen if the +# number of direct children of the root node in a graph is already larger than +# DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note +# that the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH. + +DOT_GRAPH_MAX_NODES = 50 + +# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the +# graphs generated by dot. A depth value of 3 means that only nodes reachable +# from the root by following a path via at most 3 edges will be shown. Nodes +# that lay further from the root node will be omitted. Note that setting this +# option to 1 or 2 may greatly reduce the computation time needed for large +# code bases. Also note that the size of a graph can be further restricted by +# DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction. + +MAX_DOT_GRAPH_DEPTH = 0 + +# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent +# background. This is disabled by default, because dot on Windows does not +# seem to support this out of the box. Warning: Depending on the platform used, +# enabling this option may lead to badly anti-aliased labels on the edges of +# a graph (i.e. they become hard to read). + +DOT_TRANSPARENT = NO + +# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output +# files in one run (i.e. multiple -o and -T options on the command line). This +# makes dot run faster, but since only newer versions of dot (>1.8.10) +# support this, this feature is disabled by default. + +DOT_MULTI_TARGETS = YES + +# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will +# generate a legend page explaining the meaning of the various boxes and +# arrows in the dot generated graphs. + +GENERATE_LEGEND = YES + +# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will +# remove the intermediate dot files that are used to generate +# the various graphs. + +DOT_CLEANUP = YES diff --git a/web/server/h2o/libh2o/deps/libyrmcds/Makefile b/web/server/h2o/libh2o/deps/libyrmcds/Makefile new file mode 100644 index 00000000..d8614c04 --- /dev/null +++ b/web/server/h2o/libh2o/deps/libyrmcds/Makefile @@ -0,0 +1,87 @@ +# Makefile for libyrmcds + +PREFIX = /usr/local + +CC = gcc +CXX = g++ -std=gnu++11 +CPPFLAGS = -D_GNU_SOURCE + +# Uncomment the next line to remove the internal lock used to +# serialize sending commands. +# +#CPPFLAGS += -DLIBYRMCDS_NO_INTERNAL_LOCK + +OPTFLAGS = -gdwarf-3 -O2 +CFLAGS = -Wall -Wconversion $(OPTFLAGS) +CXXFLAGS = $(CFLAGS) -Wnon-virtual-dtor -Woverloaded-virtual +LDFLAGS = -L. +LDLIBS = -lyrmcds -lpthread + +EXE = yc yc-cnt +LIB = libyrmcds.a +PACKAGES = build-essential subversion doxygen + +CHEADERS = $(wildcard *.h) +CSOURCES = $(wildcard *.c) +COBJECTS = $(patsubst %.c,%.o,$(CSOURCES)) +LIB_OBJECTS = $(filter-out yc.o yc-cnt.o,$(COBJECTS)) +TEST_SOURCES = $(wildcard t/*.c) +TESTS = $(patsubst %.c,%,$(TEST_SOURCES)) + +all: lib $(EXE) +lib: $(LIB) + +# LZ4 is optional. Run "make lz4; make" to build LZ4 enabled library. +LZ4_TAG = r127 +WGET = wget -q -P lz4/lib +lz4: + mkdir -p lz4/lib + $(WGET) https://raw.githubusercontent.com/Cyan4973/lz4/$(LZ4_TAG)/lib/lz4.c + $(WGET) https://raw.githubusercontent.com/Cyan4973/lz4/$(LZ4_TAG)/lib/lz4.h + +ifeq ($(wildcard lz4), lz4) +$(info LZ4 transparent compression is *enabled*) +CPPFLAGS += -DLIBYRMCDS_USE_LZ4 +LZ4_CFLAGS = -std=c99 -O3 +lz4/lib/lz4.o: lz4/lib/lz4.c + $(CC) $(LZ4_CFLAGS) -Ilz4/lib -c -o $@ $< +LIB_OBJECTS += lz4/lib/lz4.o +endif + +yc: yc.o + $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $< $(LDLIBS) + +yc-cnt: yc-cnt.o + $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $< $(LDLIBS) + +$(COBJECTS): $(CHEADERS) +$(EXE): $(LIB) + +$(LIB): $(LIB_OBJECTS) + $(AR) rcs $@ $^ + +t/%.exe: t/%.c $(LIB) + $(CC) -I$(shell pwd) $(CFLAGS) $(LDFLAGS) -o $@ $< $(LDLIBS) + +$(TESTS): $(LIB) + @$(MAKE) -s $@.exe + @echo Running ./$@.exe + @./$@.exe + @echo + +test: $(TESTS) + +html: + rm -rf html + doxygen + +serve: html + @cd html; python -m SimpleHTTPServer 8888 || true + +clean: + rm -rf *.o t/*.exe html $(EXE) $(LIB) + +setup: + sudo apt-get install -y $(PACKAGES) + +.PHONY: all lib test html serve clean setup diff --git a/web/server/h2o/libh2o/deps/libyrmcds/README.md b/web/server/h2o/libh2o/deps/libyrmcds/README.md new file mode 100644 index 00000000..c6683fdf --- /dev/null +++ b/web/server/h2o/libh2o/deps/libyrmcds/README.md @@ -0,0 +1,78 @@ +[![Build Status](https://travis-ci.org/cybozu/libyrmcds.png)](https://travis-ci.org/cybozu/libyrmcds) +libyrmcds +========= + +libyrmcds is a [memcached][] client library written in C. +This is a companion to [yrmcds][], a memcached compatible KVS. + +In addition to the library itself, a client program called `yc` is included. + +Features +-------- + +* Minimalistic. + + libyrmcds does *not* provide any rich features like consistent hashing. + Instead, it can be used as a base library to implement such rich + features. + +* Designed for binary protocol. + + In order to access the true power of the binary protocol, libyrmcds + is designed primarily for binary protocol. Limited support for the + text protocol is provided, though. + +* Support for [yrmcds][] extensions. + + Specifically, [the server-side locking][locking] and [the counter extension][counter] is supported. + +* Separated send / recv operations. + + Although the socket used in libyrmcds is blocking, receiving results + from the server is separated from the sending operations. You can + even use a different thread to receive results asynchronously. + +* Optional compression with [LZ4][]. + + Large objects can be transparently compressed/uncompressed with + [LZ4][] compression algorithm. + +Build +----- + +Just run `make`. + +To support [transparent LZ4 compression][compress], obtain LZ4 source +code and rebuild the library as follows: + +``` +$ make lz4 +$ make clean; make +``` + +Install +------- + +Place `yrmcds.h` and `libyrmcds.a` to appropriate directories. + +Usage +----- + +See [USAGE.md](USAGE.md). + +Authors & Contributors +---------------------- + +* Yamamoto, Hirotaka [@ymmt2005](https://github.com/ymmt2005) +* Nojima, Yusuke [@nojima](https://github.com/nojima) +* Tanuma, Shuhei [@chobie](https://github.com/chobie) +* Oku, Kazuho [@kazuho](https://github.com/kazuho) +* Fazal Majid [@fazalmajid](https://github.com/fazalmajid) + +[memcached]: http://memcached.org/ +[yrmcds]: http://cybozu.github.io/yrmcds/ +[binprot]: https://code.google.com/p/memcached/wiki/BinaryProtocolRevamped +[locking]: https://github.com/cybozu/yrmcds/blob/master/docs/locking.md +[counter]: https://github.com/cybozu/yrmcds/blob/master/docs/counter.md +[LZ4]: https://code.google.com/p/lz4/ +[compress]: USAGE.md#transparent-compression diff --git a/web/server/h2o/libh2o/deps/libyrmcds/USAGE.md b/web/server/h2o/libh2o/deps/libyrmcds/USAGE.md new file mode 100644 index 00000000..40871193 --- /dev/null +++ b/web/server/h2o/libh2o/deps/libyrmcds/USAGE.md @@ -0,0 +1,221 @@ +Usage +===== + +`yc` +---- + +`yc` is a memcached/yrmcds client program. It provides access to all +libyrmcds library functions therefore access to all server functions. + +`yc` prints out its usage when invoked without command-line arguments. + +Minimal example +--------------- + +```c +#include + +#include +#include +#include +#include + +void check_error(yrmcds_error e) { + if( e != 0 ) { + if( e == YRMCDS_SYSTEM_ERROR ) { + error(0, errno, "system error"); + } else { + fprintf(stderr, "yrmcds error: %s\n", yrmcds_strerror(e)); + } + exit(2); + } +} + +void check_response(const yrmcds_response* r) { + if( r->status != YRMCDS_STATUS_OK ) { + fprintf(stderr, "Command failed: 0x%04x %.*s\n", + r->status, (int)r->data_len, r->data); + exit(3); + } +} + +int main(int argc, char** argv) { + yrmcds c; + yrmcds_response r; + + check_error( yrmcds_connect(&c, "localhost", 11211) ); + check_error( yrmcds_noop(&c, NULL) ); + check_error( yrmcds_recv(&c, &r) ); + check_response(&r); + check_error( yrmcds_close(&c) ); + + return 0; +} +``` + +Compilation and linking +----------------------- + +Link with `-lyrmcds -lpthread` as follows: + +``` +gcc -g -O2 -o foo foo.c -lyrmcds -lpthread +``` + +Request serial number +--------------------- + +All command sending functions can issue a unique serial number of the +command. This can be used when you receive responses asynchronously +as described in the next section. + +```c +uint32_t async_cas(yrmcds* c) { + uint32_t serial; + // try compare-and-swap + check_error( yrmcds_set(&c, "abc", 3, "12345", 5, 0, 0, 5, 0, &serial) ); + return serial; +} +``` + +Multi-threading +--------------- + +All functions in libyrmcds are thread-safe as long as different `yrmcds` +structs are used. Additionally, any number of threads can use command +sending functions such as `yrmcds_get()` or `yrmcds_set()` even when +they share the same `yrmcds` struct. + +Further, `yrmcds_recv()` can be used in parallel with command sending +functions. You can create a dedicated thread to receive server responses +asynchronously. Use request serial numbers to identify a response's +request. + +```c +void async_recv(yrmcds* c, void (*notify)(uint32_t, yrmcds_response* r)) { + yrmcds_respone r; + while( 1 ) { + check_error( yrmcds_recv(&c, &r) ); + (*notify)(r.serial, &r); + } +} +``` + +You can use `yrmcds_shutdown()` to interrupt the thread blocking in +`yrmcds_recv()` for graceful exit. + + +Transparent compression +----------------------- + +libyrmcds provides optional transparent data compression by [LZ4][]. + +To use this feature, the library must be built with LZ4 as follows: + +``` +$ make lz4 +$ make +``` + +If the library supports LZ4 compression, you can enable transparent +LZ4 (de)compression for large objects. The threshold for compression +can be set by `yrmcds_set_compression()`. The compression is disabled +by default. + +Note that all clients must support and enable the compression to +properly handle compressed data. + +Text protocol support +--------------------- + +Although libyrmcds is designed for binary protocol, yet it provides +limited access to text protocol commands. Use `yrmcds_text_mode()` +to put the connection into the text protocol mode: + +```c + check_error( yrmcds_connect(&c, "localhost", 11211) ); + check_error( yrmcds_text_mode(&c) ); + + // Use the library API just in the same way as binary protocol. +``` + +Limitations: + +* Only subset of commands can be used. + + `yrmcds_get_touch`, lock related functions, `yrmcds_incr2` and + `yrmcds_decr2`, stat functions, key dump extension are not supported. + +* Quiet mutation cannot be used. + + `quiet` arguments must be 0. You need to receive a response for + every command. + +* `yrmcds_response::cas_unique` is always 0 for storage commands. + + The response for `yrmcds_set`, `yrmcds_add`, or `yrmcds_replace` + will not bring the correct CAS value. Use `yrmcds_get` or + `yrmcds_getk` to retrieve the correct value. + +* `yrmcds_response::command` value is dummy. + + Because `command` is one of binary protocol command numbers. + +Counter extension +----------------- + +yrmcds has a distributed counter extension for resource management. +If the extension is enabled in server, you can access counters by `yrmcds_cnt_*` functions. +The usage of each function is very similar to the corresponding `yrmcds_` function. + +The minimum example is: + +```c +#include + +#include +#include +#include +#include + +void check_error(yrmcds_error e) { + if( e != YRMCDS_OK ) { + if( e == YRMCDS_SYSTEM_ERROR ) { + error(0, errno, "system error"); + } else { + fprintf(stderr, "yrmcds error: %s\n", yrmcds_strerror(e)); + } + exit(2); + } +} + +void check_response(const yrmcds_cnt_response* r) { + if( r->status != YRMCDS_STATUS_OK ) { + fprintf(stderr, "Command failed: 0x%02x %.*s\n", + r->status, (int)r->body_length, r->body); + exit(3); + } +} + +int main(void) { + yrmcds_cnt c; + yrmcds_cnt_response r; + + check_error( yrmcds_cnt_connect(&c, "localhost", 11215) ); + check_error( yrmcds_cnt_noop(&c, NULL) ); + check_error( yrmcds_cnt_recv(&c, &r) ); + check_response(&r); + check_error( yrmcds_cnt_close(&c) ); + + return 0; +} +``` + +API documents +------------- + +HTML documents generated with Doxygen is available [here][api]. + + +[api]: http://cybozu.github.io/libyrmcds/html/ +[LZ4]: https://code.google.com/p/lz4/ diff --git a/web/server/h2o/libh2o/deps/libyrmcds/close.c b/web/server/h2o/libh2o/deps/libyrmcds/close.c new file mode 100644 index 00000000..d19ae765 --- /dev/null +++ b/web/server/h2o/libh2o/deps/libyrmcds/close.c @@ -0,0 +1,24 @@ +// (C) 2013 Cybozu. + +#include "yrmcds.h" + +#include +#include + +yrmcds_error yrmcds_close(yrmcds* c) { + if( c == NULL ) + return YRMCDS_BAD_ARGUMENT; + if( c->sock == -1 ) + return YRMCDS_OK; + + close(c->sock); + c->sock = -1; +#ifndef LIBYRMCDS_NO_INTERNAL_LOCK + pthread_mutex_destroy(&(c->lock)); +#endif + free(c->recvbuf); + c->recvbuf = NULL; + free(c->decompressed); + c->decompressed = NULL; + return YRMCDS_OK; +} diff --git a/web/server/h2o/libh2o/deps/libyrmcds/connect.c b/web/server/h2o/libh2o/deps/libyrmcds/connect.c new file mode 100644 index 00000000..8ddf770c --- /dev/null +++ b/web/server/h2o/libh2o/deps/libyrmcds/connect.c @@ -0,0 +1,199 @@ +// (C) 2013, 2016 Cybozu. + +#include "yrmcds.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// workaround for a known-bug in NetBSD, from https://lists.gnu.org/archive/html/bug-gnulib/2010-02/msg00071.html +#ifndef AI_V4MAPPED +#define AI_V4MAPPED 0 +#endif + +static yrmcds_error connect_to_server(const char* node, uint16_t port, int* server_fd) { + if( node == NULL ) + return YRMCDS_BAD_ARGUMENT; + + long fl; + char sport[8]; + snprintf(sport, sizeof(sport), "%u", (unsigned int)port); + + struct addrinfo hint, *res; + memset(&hint, 0, sizeof(hint)); + hint.ai_family = AF_INET; // prefer IPv4 + hint.ai_socktype = SOCK_STREAM; + hint.ai_flags = AI_NUMERICSERV|AI_ADDRCONFIG; + int e = getaddrinfo(node, sport, &hint, &res); + if( e == EAI_FAMILY || e == EAI_NONAME +#ifdef EAI_ADDRFAMILY + || e == EAI_ADDRFAMILY +#endif +#ifdef EAI_NODATA + || e == EAI_NODATA +#endif + ) { + hint.ai_family = AF_INET6; + // intentionally drop AI_ADDRCONFIG to support IPv6 link-local address. + // see https://github.com/cybozu/yrmcds/issues/40 + hint.ai_flags = AI_NUMERICSERV|AI_V4MAPPED; + e = getaddrinfo(node, sport, &hint, &res); + } + if( e == EAI_SYSTEM ) { + return YRMCDS_SYSTEM_ERROR; + } else if( e != 0 ) { + return YRMCDS_NOT_RESOLVED; + } + + int s = socket(res->ai_family, + res->ai_socktype +#ifdef __linux__ + | SOCK_NONBLOCK | SOCK_CLOEXEC +#endif + , res->ai_protocol); + if( s == -1 ) { + e = errno; + freeaddrinfo(res); + errno = e; + return YRMCDS_SYSTEM_ERROR; + } +#ifndef __linux__ + fl = fcntl(s, F_GETFD, 0); + fcntl(s, F_SETFD, fl | FD_CLOEXEC); + fl = fcntl(s, F_GETFL, 0); + fcntl(s, F_SETFL, fl | O_NONBLOCK); +#endif + e = connect(s, res->ai_addr, res->ai_addrlen); + freeaddrinfo(res); + if( e == -1 && errno != EINPROGRESS ) { + e = errno; + close(s); + errno = e; + return YRMCDS_SYSTEM_ERROR; + } + + if( e != 0 ) { + struct pollfd fds; + fds.fd = s; + fds.events = POLLOUT; + int n = poll(&fds, 1, 5000); + if( n == 0 ) { // timeout + close(s); + return YRMCDS_TIMEOUT; + } + if( n == -1 ) { + e = errno; + close(s); + errno = e; + return YRMCDS_SYSTEM_ERROR; + } + + if( fds.revents & (POLLERR|POLLHUP|POLLNVAL) ) { + close(s); + return YRMCDS_DISCONNECTED; + } + socklen_t l = sizeof(e); + if( getsockopt(s, SOL_SOCKET, SO_ERROR, &e, &l) == -1 ) { + close(s); + return YRMCDS_SYSTEM_ERROR; + } + if( e != 0 ) { + close(s); + errno = e; + return YRMCDS_SYSTEM_ERROR; + } + } + fl = fcntl(s, F_GETFL, 0); + if( fcntl(s, F_SETFL, fl & ~O_NONBLOCK) == -1 ) { + e = errno; + close(s); + errno = e; + return YRMCDS_SYSTEM_ERROR; + } + int ok = 1; + if( setsockopt(s, IPPROTO_TCP, TCP_NODELAY, &ok, sizeof(ok)) == -1 ) { + e = errno; + close(s); + errno = e; + return YRMCDS_SYSTEM_ERROR; + } + *server_fd = s; + return YRMCDS_OK; +} + +yrmcds_error yrmcds_connect(yrmcds* c, const char* node, uint16_t port) { + if( c == NULL ) + return YRMCDS_BAD_ARGUMENT; +#ifndef LIBYRMCDS_NO_INTERNAL_LOCK + int e = pthread_mutex_init(&(c->lock), NULL); + if( e != 0 ) { + errno = e; + return YRMCDS_SYSTEM_ERROR; + } +#endif // ! LIBYRMCDS_NO_INTERNAL_LOCK + int server_fd; + yrmcds_error err = connect_to_server(node, port, &server_fd); + if( err != YRMCDS_OK ) + return err; + c->sock = server_fd; + c->serial = 0; + c->compress_size = 0; + c->recvbuf = (char*)malloc(1 << 20); + if( c->recvbuf == NULL ) { + close(server_fd); +#ifndef LIBYRMCDS_NO_INTERNAL_LOCK + pthread_mutex_destroy(&(c->lock)); +#endif + return YRMCDS_OUT_OF_MEMORY; + } + c->capacity = 1 << 20; + c->used = 0; + c->last_size = 0; + c->decompressed = NULL; + c->invalid = 0; + c->text_mode = 0; + c->rserial = 0; + return YRMCDS_OK; +} + +yrmcds_error yrmcds_cnt_connect(yrmcds_cnt* c, const char* node, uint16_t port) { + if( c == NULL ) + return YRMCDS_BAD_ARGUMENT; +#ifndef LIBYRMCDS_NO_INTERNAL_LOCK + int e = pthread_mutex_init(&(c->lock), NULL); + if( e != 0 ) { + errno = e; + return YRMCDS_SYSTEM_ERROR; + } +#endif // ! LIBYRMCDS_NO_INTERNAL_LOCK + int server_fd; + yrmcds_error err = connect_to_server(node, port, &server_fd); + if( err != YRMCDS_OK ) + return err; + c->sock = server_fd; + c->serial = 0; + c->recvbuf = (char*)malloc(4096); + if( c->recvbuf == NULL ) { + close(server_fd); +#ifndef LIBYRMCDS_NO_INTERNAL_LOCK + pthread_mutex_destroy(&(c->lock)); +#endif + return YRMCDS_OUT_OF_MEMORY; + } + c->capacity = 4096; + c->used = 0; + c->last_size = 0; + c->invalid = 0; + c->stats.count = c->stats.capacity = 0; + c->stats.records = NULL; + return YRMCDS_OK; +} diff --git a/web/server/h2o/libh2o/deps/libyrmcds/counter.c b/web/server/h2o/libh2o/deps/libyrmcds/counter.c new file mode 100644 index 00000000..748a2310 --- /dev/null +++ b/web/server/h2o/libh2o/deps/libyrmcds/counter.c @@ -0,0 +1,408 @@ +// (C) 2013-2015 Cybozu et al. + +#include "yrmcds.h" +#include "yrmcds_portability.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static const size_t HEADER_SIZE = 12; +static const size_t RECV_SIZE = 4096; +static const size_t INITIAL_STATS_CAPACITY = 16; + +static inline void hton32(uint32_t i, char* p) { + uint32_t n = htobe32(i); + memcpy(p, &n, sizeof(n)); +} + +static inline void hton16(uint16_t i, char* p) { + uint16_t n = htobe16(i); + memcpy(p, &n, sizeof(n)); +} + +static inline uint32_t ntoh32(const char* p) { + uint32_t n; + memcpy(&n, p, sizeof(n)); + return be32toh(n); +} + +static inline uint16_t ntoh16(const char* p) { + uint16_t n; + memcpy(&n, p, sizeof(n)); + return be16toh(n); +} + +yrmcds_error +yrmcds_cnt_set_timeout(yrmcds_cnt* c, int timeout) { + if( c == NULL || timeout < 0 ) + return YRMCDS_BAD_ARGUMENT; + + struct timeval tv; + tv.tv_sec = timeout; + tv.tv_usec = 0; + + if( setsockopt(c->sock, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)) == -1 ) + return YRMCDS_SYSTEM_ERROR; + if( setsockopt(c->sock, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv)) == -1 ) + return YRMCDS_SYSTEM_ERROR; + return YRMCDS_OK; +} + +yrmcds_error +yrmcds_cnt_close(yrmcds_cnt* c) { + if( c == NULL ) + return YRMCDS_BAD_ARGUMENT; + if( c->sock == -1 ) + return YRMCDS_OK; + + close(c->sock); + c->sock = -1; +#ifndef LIBYRMCDS_NO_INTERNAL_LOCK + pthread_mutex_destroy(&(c->lock)); +#endif + free(c->recvbuf); + c->recvbuf = NULL; + free(c->stats.records); + c->stats.records = NULL; + return YRMCDS_OK; +} + +yrmcds_error +yrmcds_cnt_shutdown(yrmcds_cnt* c) { + if( c == NULL ) + return YRMCDS_BAD_ARGUMENT; + if( shutdown(c->sock, SHUT_RD) == -1 ) + return YRMCDS_SYSTEM_ERROR; + return YRMCDS_OK; +} + +int +yrmcds_cnt_fileno(yrmcds_cnt* c) { + return c->sock; +} + +static yrmcds_error +recv_data(yrmcds_cnt* c) { + if( (c->capacity - c->used) < RECV_SIZE ) { + size_t new_capacity = c->capacity * 2; + char* new_buffer = (char*)realloc(c->recvbuf, new_capacity); + if( new_buffer == NULL ) + return YRMCDS_OUT_OF_MEMORY; + c->recvbuf = new_buffer; + c->capacity = new_capacity; + } + + ssize_t n; + AGAIN: + n = recv(c->sock, c->recvbuf + c->used, RECV_SIZE, 0); + if( n == -1 ) { + if( errno == EINTR ) goto AGAIN; + return YRMCDS_SYSTEM_ERROR; + } + if( n == 0 ) + return YRMCDS_DISCONNECTED; + c->used += (size_t)n; + return YRMCDS_OK; +} + +static yrmcds_error +append_stat(yrmcds_cnt_statistics* s, + uint16_t name_len, uint16_t value_len, + const char* name, const char* value) { + if( s->count == s->capacity ) { + size_t new_capacity = s->capacity * 2; + if( new_capacity < INITIAL_STATS_CAPACITY ) + new_capacity = INITIAL_STATS_CAPACITY; + yrmcds_cnt_stat* new_records = + realloc(s->records, sizeof(yrmcds_cnt_stat) * new_capacity); + if( new_records == NULL ) + return YRMCDS_OUT_OF_MEMORY; + s->capacity = new_capacity; + s->records = new_records; + } + + s->records[s->count].name_length = name_len; + s->records[s->count].value_length = value_len; + s->records[s->count].name = name; + s->records[s->count].value = value; + s->count += 1; + return YRMCDS_OK; +} + +static yrmcds_error +parse_statistics(yrmcds_cnt* c, const yrmcds_cnt_response* r) { + yrmcds_cnt_statistics* s = &c->stats; + s->count = 0; + + const char* p = r->body; + const char* end = r->body + r->body_length; + while( p < end ) { + if( p + 4 > end ) + return YRMCDS_PROTOCOL_ERROR; + uint16_t name_len = ntoh16(p); + uint16_t value_len = ntoh16(p + 2); + if( p + 4 + name_len + value_len > end ) + return YRMCDS_PROTOCOL_ERROR; + yrmcds_error err = + append_stat(s, name_len, value_len, p + 4, p + 4 + name_len); + if( err != YRMCDS_OK ) + return err; + p += 4 + name_len + value_len; + } + return YRMCDS_OK; +} + +static yrmcds_error +parse_dump_record(yrmcds_cnt* c, yrmcds_cnt_response* r) { + if( r->body_length == 0 ) { + // End of dump + return YRMCDS_OK; + } + if( r->body_length < 10 ) { + c->invalid = 1; + return YRMCDS_PROTOCOL_ERROR; + } + r->current_consumption = ntoh32(r->body); + r->max_consumption = ntoh32(r->body + 4); + r->name_length = ntoh16(r->body + 8); + if( r->body_length < 10 + r->name_length ) { + c->invalid = 1; + return YRMCDS_PROTOCOL_ERROR; + } + r->name = r->body + 10; + return YRMCDS_OK; +} + +yrmcds_error +yrmcds_cnt_recv(yrmcds_cnt* c, yrmcds_cnt_response* r) { + if( c == NULL || r == NULL ) + return YRMCDS_BAD_ARGUMENT; + if( c->invalid ) + return YRMCDS_PROTOCOL_ERROR; + + if( c->last_size > 0 ) { + size_t remain = c->used - c->last_size; + if( remain > 0 ) + memmove(c->recvbuf, c->recvbuf + c->last_size, remain); + c->used = remain; + c->last_size = 0; + } + + while( c->used < HEADER_SIZE ) { + yrmcds_error e = recv_data(c); + if( e != YRMCDS_OK ) return e; + } + + if( (uint8_t)c->recvbuf[0] != 0x91 ) { + c->invalid = 1; + return YRMCDS_PROTOCOL_ERROR; + } + + r->command = (yrmcds_cnt_command)c->recvbuf[1]; + r->status = (yrmcds_cnt_status)c->recvbuf[2]; + r->body_length = ntoh32(c->recvbuf + 4); + memcpy(&r->serial, c->recvbuf + 8, sizeof(r->serial)); + r->body = NULL; + r->resources = 0; + r->current_consumption = 0; + r->max_consumption = 0; + r->name_length = 0; + r->stats = NULL; + + if( r->body_length > 0 ) { + while( c->used < HEADER_SIZE + r->body_length ) { + yrmcds_error e = recv_data(c); + if( e != YRMCDS_OK ) return e; + } + r->body = c->recvbuf + HEADER_SIZE; + } + c->last_size = HEADER_SIZE + r->body_length; + + if( r->status != YRMCDS_STATUS_OK ) + return YRMCDS_OK; + + yrmcds_error err; + switch( r->command ) { + case YRMCDS_CNT_CMD_GET: + if( r->body_length < 4 ) { + c->invalid = 1; + return YRMCDS_PROTOCOL_ERROR; + } + r->current_consumption = ntoh32(r->body); + break; + + case YRMCDS_CNT_CMD_ACQUIRE: + if( r->body_length < 4 ) { + c->invalid = 1; + return YRMCDS_PROTOCOL_ERROR; + } + r->resources = ntoh32(r->body); + break; + + case YRMCDS_CNT_CMD_STATS: + err = parse_statistics(c, r); + if( err != YRMCDS_OK ) { + c->invalid = 1; + return err; + } + r->stats = &c->stats; + break; + + case YRMCDS_CNT_CMD_DUMP: + err = parse_dump_record(c, r); + if( err != YRMCDS_OK ) { + c->invalid = 1; + return err; + } + break; + + default: + // No body + break; + } + return YRMCDS_OK; +} + +static yrmcds_error +send_command(yrmcds_cnt* c, yrmcds_cnt_command cmd, uint32_t* serial, + size_t body1_len, const char* body1, + size_t body2_len, const char* body2) { + if( c == NULL || + body1_len > UINT32_MAX - body2_len || + (body1_len != 0 && body1 == NULL) || + (body2_len != 0 && body2 == NULL) ) + return YRMCDS_BAD_ARGUMENT; + +#ifndef LIBYRMCDS_NO_INTERNAL_LOCK + int e = pthread_mutex_lock(&c->lock); + if( e != 0 ) { + errno = e; + return YRMCDS_SYSTEM_ERROR; + } +#endif // ! LIBYRMCDS_NO_INTERNAL_LOCK + + c->serial += 1; + if( serial != NULL ) + *serial = c->serial; + + char header[HEADER_SIZE]; + header[0] = '\x90'; + header[1] = (char)cmd; + header[2] = 0; + header[3] = 0; + hton32((uint32_t)(body1_len + body2_len), header + 4); + memcpy(header + 8, &c->serial, 4); + + yrmcds_error ret = YRMCDS_OK; + + struct iovec iov[3]; + size_t iovcnt = 1; + + iov[0].iov_base = header; + iov[0].iov_len = HEADER_SIZE; + + if( body1_len != 0 ) { + iov[iovcnt].iov_base = (void*)body1; + iov[iovcnt].iov_len = body1_len; + ++iovcnt; + } + if( body2_len != 0 ) { + iov[iovcnt].iov_base = (void*)body2; + iov[iovcnt].iov_len = body2_len; + ++iovcnt; + } + + size_t i; + for( i = 0; i < iovcnt; ) { + ssize_t n = writev(c->sock, iov + i, (int)(iovcnt - i)); + size_t n2 = (size_t)n; + if( n == -1 ) { + if( errno == EINTR ) continue; + ret = YRMCDS_SYSTEM_ERROR; + break; + } + while( n2 > 0 ) { + if( n2 < iov[i].iov_len ) { + iov[i].iov_base = (char*)iov[i].iov_base + n2; + iov[i].iov_len -= n2; + break; + } + n2 -= iov[i].iov_len; + ++i; + } + } + +#ifndef LIBYRMCDS_NO_INTERNAL_LOCK + pthread_mutex_unlock(&c->lock); +#endif + return ret; +} + +yrmcds_error +yrmcds_cnt_noop(yrmcds_cnt* c, uint32_t* serial) { + return send_command(c, YRMCDS_CNT_CMD_NOOP, serial, + 0, NULL, 0, NULL); +} + +yrmcds_error +yrmcds_cnt_get(yrmcds_cnt* c, const char* name, size_t name_len, + uint32_t* serial) { + if( name == NULL || name_len == 0 || name_len > UINT16_MAX ) + return YRMCDS_BAD_ARGUMENT; + + char body[2]; + hton16((uint16_t)name_len, body); + return send_command(c, YRMCDS_CNT_CMD_GET, serial, + sizeof(body), body, name_len, name); +} + +yrmcds_error +yrmcds_cnt_acquire(yrmcds_cnt* c, const char* name, size_t name_len, + uint32_t resources, uint32_t initial, uint32_t* serial) { + if( name == NULL || name_len == 0 || name_len > UINT16_MAX || + resources == 0 || resources > initial ) + return YRMCDS_BAD_ARGUMENT; + + char body[10]; + hton32(resources, body); + hton32(initial, body + 4); + hton16((uint16_t)name_len, body + 8); + return send_command(c, YRMCDS_CNT_CMD_ACQUIRE, serial, + sizeof(body), body, name_len, name); +} + +yrmcds_error +yrmcds_cnt_release(yrmcds_cnt* c, const char* name, size_t name_len, + uint32_t resources, uint32_t* serial) { + if( name == NULL || name_len == 0 || name_len > UINT16_MAX ) + return YRMCDS_BAD_ARGUMENT; + + char body[6]; + hton32(resources, body); + hton16((uint16_t)name_len, body + 4); + return send_command(c, YRMCDS_CNT_CMD_RELEASE, serial, + sizeof(body), body, name_len, name); +} + +yrmcds_error +yrmcds_cnt_stats(yrmcds_cnt* c, uint32_t* serial) { + return send_command(c, YRMCDS_CNT_CMD_STATS, serial, + 0, NULL, 0, NULL); +} + +yrmcds_error +yrmcds_cnt_dump(yrmcds_cnt* c, uint32_t* serial) { + return send_command(c, YRMCDS_CNT_CMD_DUMP, serial, + 0, NULL, 0, NULL); +} diff --git a/web/server/h2o/libh2o/deps/libyrmcds/example/counter.c b/web/server/h2o/libh2o/deps/libyrmcds/example/counter.c new file mode 100644 index 00000000..f08a1b12 --- /dev/null +++ b/web/server/h2o/libh2o/deps/libyrmcds/example/counter.c @@ -0,0 +1,38 @@ +#include + +#include +#include +#include +#include + +void check_error(yrmcds_error e) { + if( e != YRMCDS_OK ) { + if( e == YRMCDS_SYSTEM_ERROR ) { + error(0, errno, "system error"); + } else { + fprintf(stderr, "yrmcds error: %s\n", yrmcds_strerror(e)); + } + exit(2); + } +} + +void check_response(const yrmcds_cnt_response* r) { + if( r->status != YRMCDS_STATUS_OK ) { + fprintf(stderr, "Command failed: 0x%02x %.*s\n", + r->status, (int)r->body_length, r->body); + exit(3); + } +} + +int main(void) { + yrmcds_cnt c; + yrmcds_cnt_response r; + + check_error( yrmcds_cnt_connect(&c, "localhost", 11215) ); + check_error( yrmcds_cnt_noop(&c, NULL) ); + check_error( yrmcds_cnt_recv(&c, &r) ); + check_response(&r); + check_error( yrmcds_cnt_close(&c) ); + + return 0; +} diff --git a/web/server/h2o/libh2o/deps/libyrmcds/example/memcache.c b/web/server/h2o/libh2o/deps/libyrmcds/example/memcache.c new file mode 100644 index 00000000..eb879286 --- /dev/null +++ b/web/server/h2o/libh2o/deps/libyrmcds/example/memcache.c @@ -0,0 +1,38 @@ +#include + +#include +#include +#include +#include + +void check_error(yrmcds_error e) { + if( e != 0 ) { + if( e == YRMCDS_SYSTEM_ERROR ) { + error(0, errno, "system error"); + } else { + fprintf(stderr, "yrmcds error: %s\n", yrmcds_strerror(e)); + } + exit(2); + } +} + +void check_response(const yrmcds_response* r) { + if( r->status != YRMCDS_STATUS_OK ) { + fprintf(stderr, "Command failed: 0x%04x %.*s\n", + r->status, (int)r->data_len, r->data); + exit(3); + } +} + +int main(int argc, char** argv) { + yrmcds c; + yrmcds_response r; + + check_error( yrmcds_connect(&c, "localhost", 11211) ); + check_error( yrmcds_noop(&c, NULL) ); + check_error( yrmcds_recv(&c, &r) ); + check_response(&r); + check_error( yrmcds_close(&c) ); + + return 0; +} diff --git a/web/server/h2o/libh2o/deps/libyrmcds/recv.c b/web/server/h2o/libh2o/deps/libyrmcds/recv.c new file mode 100644 index 00000000..fe6cf94b --- /dev/null +++ b/web/server/h2o/libh2o/deps/libyrmcds/recv.c @@ -0,0 +1,354 @@ +// (C) 2013 Cybozu et al. + +#include "yrmcds.h" +#include "yrmcds_portability.h" + +#ifdef LIBYRMCDS_USE_LZ4 +# include "lz4/lib/lz4.h" +#endif + +#include +#include +#include +#include +#include +#include +#include + +static const size_t BINARY_HEADER_SIZE = 24; +static const size_t RECV_SIZE = 256 << 10; +static const size_t MAX_CAPACITY = 50 << 20; // 50 MiB + +static inline yrmcds_error recv_data(yrmcds* c) { + if( (c->capacity - c->used) < RECV_SIZE ) { + size_t new_capacity = c->capacity * 2; + char* new_buffer = (char*)realloc(c->recvbuf, new_capacity); + if( new_buffer == NULL ) + return YRMCDS_OUT_OF_MEMORY; + c->recvbuf = new_buffer; + c->capacity = new_capacity; + } + + ssize_t n; + AGAIN: + n = recv(c->sock, c->recvbuf + c->used, RECV_SIZE, 0); + if( n == -1 ) { + if( errno == EINTR ) goto AGAIN; + return YRMCDS_SYSTEM_ERROR; + } + if( n == 0 ) + return YRMCDS_DISCONNECTED; + c->used += (size_t)n; + return YRMCDS_OK; +} + +static inline uint64_t ntoh64(const char* p) { + uint64_t n; + memcpy(&n, p, sizeof(n)); + return be64toh(n); +} + +static inline uint32_t ntoh32(const char* p) { + uint32_t n; + memcpy(&n, p, sizeof(n)); + return be32toh(n); +} + +static inline uint16_t ntoh16(const char* p) { + uint16_t n; + memcpy(&n, p, sizeof(n)); + return be16toh(n); +} + +static yrmcds_error text_recv(yrmcds* c, yrmcds_response* r); + +yrmcds_error yrmcds_recv(yrmcds* c, yrmcds_response* r) { + if( c == NULL || r == NULL ) + return YRMCDS_BAD_ARGUMENT; + if( c->invalid ) + return YRMCDS_PROTOCOL_ERROR; + + if( c->last_size > 0 ) { + size_t remain = c->used - c->last_size; + if( remain > 0 ) + memmove(c->recvbuf, c->recvbuf + c->last_size, remain); + c->used = remain; + c->last_size = 0; + free(c->decompressed); + c->decompressed = NULL; + } + + if( c->text_mode ) { + return text_recv(c, r); + } + + while( c->used < BINARY_HEADER_SIZE ) { + yrmcds_error e = recv_data(c); + if( e != 0 ) return e; + } + + if( *c->recvbuf != '\x81' ) { + c->invalid = 1; + return YRMCDS_PROTOCOL_ERROR; + } + uint32_t total_len = ntoh32(c->recvbuf + 8); + if( total_len > MAX_CAPACITY ) { + c->invalid = 1; + return YRMCDS_PROTOCOL_ERROR; + } + while( c->used < (BINARY_HEADER_SIZE + total_len) ) { + yrmcds_error e = recv_data(c); + if( e != 0 ) return e; + } + + uint16_t key_len = ntoh16(c->recvbuf + 2); + uint8_t extras_len = *(unsigned char*)(c->recvbuf + 4); + if( total_len < (key_len + extras_len) ) { + c->invalid = 1; + return YRMCDS_PROTOCOL_ERROR; + } + + const char* pkey = c->recvbuf + (BINARY_HEADER_SIZE + extras_len); + r->length = BINARY_HEADER_SIZE + total_len; + r->command = *(unsigned char*)(c->recvbuf + 1); + r->key = key_len ? pkey : NULL; + r->key_len = key_len; + r->status = ntoh16(c->recvbuf + 6); + memcpy(&(r->serial), c->recvbuf + 12, 4); + r->cas_unique = ntoh64(c->recvbuf + 16); + r->flags = 0; + if( extras_len > 0 ) { + if( extras_len != 4 ) { + c->invalid = 1; + return YRMCDS_PROTOCOL_ERROR; + } + r->flags = ntoh32(c->recvbuf + BINARY_HEADER_SIZE); + } + + size_t data_len = total_len - key_len - extras_len; + const char* pdata = pkey + key_len; + + if( (r->command == YRMCDS_CMD_INCREMENT || + r->command == YRMCDS_CMD_DECREMENT) && + (r->status == YRMCDS_STATUS_OK) ) { + r->data = NULL; + r->data_len = 0; + if( data_len != 8 ) { + c->invalid = 1; + return YRMCDS_PROTOCOL_ERROR; + } + r->value = ntoh64(pdata); + c->last_size = r->length; + return YRMCDS_OK; + } + r->value = 0; + r->data = data_len ? pdata : NULL; + r->data_len = data_len; + +#ifdef LIBYRMCDS_USE_LZ4 + if( c->compress_size && (r->flags & YRMCDS_FLAG_COMPRESS) ) { + if( data_len == 0 ) { + c->invalid = 1; + return YRMCDS_PROTOCOL_ERROR; + } + r->flags &= ~(uint32_t)YRMCDS_FLAG_COMPRESS; + uint32_t decompress_size = ntoh32(pdata); + if( UINT32_MAX > INT_MAX ) { + if( decompress_size > INT_MAX ) { + c->invalid = 1; + return YRMCDS_PROTOCOL_ERROR; + } + } + c->decompressed = (char*)malloc(decompress_size); + if( c->decompressed == NULL ) + return YRMCDS_OUT_OF_MEMORY; + int d = LZ4_decompress_safe(pdata + sizeof(uint32_t), + c->decompressed, + (int)(data_len - sizeof(uint32_t)), + (int)decompress_size); + if( d != decompress_size ) { + c->invalid = 1; + return YRMCDS_PROTOCOL_ERROR; + } + r->data = c->decompressed; + r->data_len = decompress_size; + } +#endif // LIBYRMCDS_USE_LZ4 + + c->last_size = r->length; + return YRMCDS_OK; +} + + +// text protocol +#define PARSE_UINT(name) \ + uint64_t name = 0; \ + while( *p == ' ' ) p++; \ + while( '0' <= *p && *p <= '9' ) { \ + name *= 10; \ + name += (uint64_t)(*p - '0'); \ + p++; \ + } + +static yrmcds_error text_recv(yrmcds* c, yrmcds_response* r) { + char* pos; + while( c->used == 0 || + (pos = (char*)memchr(c->recvbuf, '\n', c->used)) == NULL ) { + yrmcds_error e = recv_data(c); + if( e != 0 ) return e; + } + // make sure the buffer contains CRLF. + if( (pos - c->recvbuf) < 2 || *(pos-1) != '\r' ) { + c->invalid = 1; + return YRMCDS_PROTOCOL_ERROR; + } + pos--; + size_t resp_len = (size_t)(pos - c->recvbuf); + + memset(r, 0, sizeof(yrmcds_response)); + r->serial = ++c->rserial; + r->length = resp_len + 2; + r->status = YRMCDS_STATUS_OK; + r->command = YRMCDS_CMD_BOTTOM; // dummy for emulating binary protocol + + if( resp_len == 2 && memcmp(c->recvbuf, "OK", 2) == 0 ) { + // successful response for flush_all + goto FINISH; + } + if( resp_len == 3 && memcmp(c->recvbuf, "END", 3) == 0 ) { + // get failed for non-existing object. + r->status = YRMCDS_STATUS_NOTFOUND; + goto FINISH; + } + if( resp_len == 5 && memcmp(c->recvbuf, "ERROR", 5) == 0 ) { + r->status = YRMCDS_STATUS_UNKNOWNCOMMAND; + goto FINISH; + } + if( resp_len == 6 ) { + if( memcmp(c->recvbuf, "STORED", 6) == 0 ) { + // successful response for storage commands. + goto FINISH; + } + if( memcmp(c->recvbuf, "EXISTS", 6) == 0 ) { + // failure response for cas. + r->status = YRMCDS_STATUS_EXISTS; + goto FINISH; + } + } + if( resp_len == 7 ) { + if( memcmp(c->recvbuf, "DELETED", 7) == 0 ) + // successful response for delete. + goto FINISH; + if( memcmp(c->recvbuf, "TOUCHED", 7) == 0 ) + // successful response for touch. + goto FINISH; + } + if( resp_len == 9 && memcmp(c->recvbuf, "NOT_FOUND", 9) == 0 ) { + // failure response for cas, delete, incr, decr, or touch. + r->status = YRMCDS_STATUS_NOTFOUND; + goto FINISH; + } + if( resp_len == 10 && memcmp(c->recvbuf, "NOT_STORED", 10) == 0 ) { + // failure response for add, replace, append, or prepend. + r->status = YRMCDS_STATUS_NOTSTORED; + goto FINISH; + } + if( resp_len > 0 && '0' <= c->recvbuf[0] && c->recvbuf[0] <= '9' ) { + // successful response for incr or decr. + const char* p = c->recvbuf; + PARSE_UINT(value); + r->value = value; + goto FINISH; + } + if( resp_len > 8 && memcmp(c->recvbuf, "VERSION ", 8) == 0 ) { + // successful response for version. + r->data_len = resp_len - 8; + r->data = c->recvbuf + 8; + goto FINISH; + } + if( resp_len > 6 && memcmp(c->recvbuf, "VALUE ", 6) == 0 ) { + // successful response for gets. + const char* p = c->recvbuf + 6; + while( *p == ' ' ) p++; + if( p == pos ) goto UNKNOWN; + + const char* key_end = memchr(p, ' ', (size_t)(pos - p)); + if( key_end == NULL ) goto UNKNOWN; + r->key = p; + r->key_len = (size_t)(key_end - p); + + p = key_end; + PARSE_UINT(flags); + if( *p != ' ' ) goto UNKNOWN; + r->flags = (uint32_t)flags; + + PARSE_UINT(bytes); + if( bytes > MAX_CAPACITY ) { + c->invalid = 1; + return YRMCDS_PROTOCOL_ERROR; + } + size_t data_len = (size_t)bytes; + + while( *p == ' ' ) p++; + if( *p < '0' || '9' < *p ) goto UNKNOWN; + PARSE_UINT(cas); + + size_t required = resp_len + 2 + data_len + 7; // CRLF "END" CRLF + while( c->used < required ) { + yrmcds_error e = recv_data(c); + if( e != 0 ) return e; + } + + const char* data = c->recvbuf + (resp_len + 2); + if( memcmp(data + data_len, "\r\nEND\r\n", 7) != 0 ) { + c->invalid = 1; + return YRMCDS_PROTOCOL_ERROR; + } + r->length = required; + r->flags = (uint32_t)flags; + +#ifdef LIBYRMCDS_USE_LZ4 + if( c->compress_size && (r->flags & YRMCDS_FLAG_COMPRESS) ) { + if( data_len == 0 ) { + c->invalid = 1; + return YRMCDS_PROTOCOL_ERROR; + } + r->flags &= ~(uint32_t)YRMCDS_FLAG_COMPRESS; + uint32_t decompress_size = ntoh32(data); + if( UINT32_MAX > INT_MAX ) { + if( decompress_size > INT_MAX ) { + c->invalid = 1; + return YRMCDS_PROTOCOL_ERROR; + } + } + c->decompressed = (char*)malloc(decompress_size); + if( c->decompressed == NULL ) + return YRMCDS_OUT_OF_MEMORY; + int d = LZ4_decompress_safe(data + sizeof(uint32_t), + c->decompressed, + (int)(data_len - sizeof(uint32_t)), + (int)decompress_size); + if( d != decompress_size ) { + c->invalid = 1; + return YRMCDS_PROTOCOL_ERROR; + } + data = c->decompressed; + data_len = (size_t)decompress_size; + } +#endif // LIBYRMCDS_USE_LZ4 + r->data = data; + r->data_len = data_len; + r->cas_unique = cas; + goto FINISH; + } + + UNKNOWN: + r->status = YRMCDS_STATUS_OTHER; + fprintf(stderr, "[libyrmcds] unknown response: %.*s\n", + (int)resp_len, c->recvbuf); + + FINISH: + c->last_size = r->length; + return YRMCDS_OK; +} + diff --git a/web/server/h2o/libh2o/deps/libyrmcds/send.c b/web/server/h2o/libh2o/deps/libyrmcds/send.c new file mode 100644 index 00000000..b1eb48f7 --- /dev/null +++ b/web/server/h2o/libh2o/deps/libyrmcds/send.c @@ -0,0 +1,564 @@ +// (C) 2013-2016 Cybozu et al. + +#include "yrmcds.h" +#include "yrmcds_portability.h" +#include "yrmcds_text.h" + +#ifdef LIBYRMCDS_USE_LZ4 +# include "lz4/lib/lz4.h" +#endif + +#include +#include +#include +#include +#include +#include + +static const size_t BINARY_HEADER_SIZE = 24; +static const size_t MAX_DATA_SIZE = ((size_t)1) << 30; + +static inline void hton64(uint64_t i, char* p) { + uint64_t n = htobe64(i); + memcpy(p, &n, sizeof(n)); +} + +static inline void hton32(uint32_t i, char* p) { + uint32_t n = htobe32(i); + memcpy(p, &n, sizeof(n)); +} + +static inline void hton16(uint16_t i, char* p) { + uint16_t n = htobe16(i); + memcpy(p, &n, sizeof(n)); +} + +static yrmcds_error send_command( + yrmcds* c, yrmcds_command cmd, uint64_t cas, uint32_t* serial, + size_t key_len, const char* key, + size_t extras_len, const char* extras, + size_t data_len, const char* data) { + if( cmd >= YRMCDS_CMD_BOTTOM || + key_len > 65535 || extras_len > 127 || data_len > MAX_DATA_SIZE || + (key_len != 0 && key == NULL) || + (extras_len != 0 && extras == NULL) || + (data_len != 0 && data == NULL) ) + return YRMCDS_BAD_ARGUMENT; + + char h[BINARY_HEADER_SIZE]; + memset(h, 0, sizeof(h)); + h[0] = '\x80'; + h[1] = (char)cmd; + hton16((uint16_t)key_len, &h[2]); + h[4] = (char)extras_len; + size_t total_len = (key_len + extras_len + data_len); + hton32((uint32_t)total_len, &h[8]); + hton64(cas, &h[16]); + +#ifndef LIBYRMCDS_NO_INTERNAL_LOCK + int e = pthread_mutex_lock(&c->lock); + if( e != 0 ) { + errno = e; + return YRMCDS_SYSTEM_ERROR; + } +#endif // ! LIBYRMCDS_NO_INTERNAL_LOCK + + yrmcds_error ret = YRMCDS_OK; + c->serial = c->serial + 1; + memcpy(&h[12], &c->serial, 4); + if( serial != NULL ) + *serial = c->serial; + + struct iovec iov[4]; + int iovcnt = 1; + iov[0].iov_base = h; + iov[0].iov_len = sizeof(h); + + if( extras_len > 0 ) { + iov[iovcnt].iov_base = (void*)extras; + iov[iovcnt].iov_len = extras_len; + iovcnt++; + } + if( key_len > 0 ) { + iov[iovcnt].iov_base = (void*)key; + iov[iovcnt].iov_len = key_len; + iovcnt++; + } + if( data_len > 0 ) { + iov[iovcnt].iov_base = (void*)data; + iov[iovcnt].iov_len = data_len; + iovcnt++; + } + + while( iovcnt > 0 ) { + ssize_t n = writev(c->sock, iov, iovcnt); + size_t n2 = (size_t)n; + if( n == -1 ) { + if( errno == EINTR ) continue; + ret = YRMCDS_SYSTEM_ERROR; + goto OUT; + } + while( n2 > 0 ) { + if( n2 < iov[0].iov_len ) { + iov[0].iov_base = (char*)iov[0].iov_base + n2; + iov[0].iov_len -= n2; + break; + } + n2 -= iov[0].iov_len; + iovcnt --; + if( iovcnt == 0 ) + break; + + int i; + for( i = 0; i < iovcnt; ++i ) + iov[i] = iov[i+1]; + } + } + + OUT: +#ifndef LIBYRMCDS_NO_INTERNAL_LOCK + pthread_mutex_unlock(&c->lock); +#endif + return ret; +} + +static yrmcds_error send_data( + yrmcds* c, yrmcds_command cmd, const char* key, size_t key_len, + const char* data, size_t data_len, uint32_t flags, uint32_t expire, + uint64_t cas, uint32_t* serial) { + if( c == NULL || key == NULL || key_len == 0 || + data == NULL || data_len == 0 ) + return YRMCDS_BAD_ARGUMENT; + + int compressed = 0; +#ifdef LIBYRMCDS_USE_LZ4 + if( (c->compress_size > 0) && (data_len > c->compress_size) ) { + if( flags & YRMCDS_FLAG_COMPRESS ) + return YRMCDS_BAD_ARGUMENT; + + size_t bound = (size_t)LZ4_compressBound((int)data_len); + char* new_data = (char*)malloc(bound + sizeof(uint32_t)); + if( new_data == NULL ) + return YRMCDS_OUT_OF_MEMORY; + uint32_t new_size = + (uint32_t)LZ4_compress(data, new_data + sizeof(uint32_t), + (int)data_len); + if( new_size == 0 ) { + free(new_data); + return YRMCDS_COMPRESS_FAILED; + } + hton32((uint32_t)data_len, new_data); + flags |= YRMCDS_FLAG_COMPRESS; + data_len = sizeof(uint32_t) + new_size; + data = new_data; + compressed = 1; + } +#endif // LIBYRMCDS_USE_LZ4 + + char extras[8]; + hton32(flags, extras); + hton32(expire, &extras[4]); + yrmcds_error e = send_command(c, cmd, cas, serial, key_len, key, + sizeof(extras), extras, data_len, data); + if( compressed ) + free((void*)data); + return e; +} + +yrmcds_error yrmcds_noop(yrmcds* c, uint32_t* serial) { + if( c == NULL ) + return YRMCDS_BAD_ARGUMENT; + + if( c->text_mode ) + return YRMCDS_NOT_IMPLEMENTED; + + return send_command(c, YRMCDS_CMD_NOOP, 0, serial, + 0, NULL, 0, NULL, 0, NULL); +} + +yrmcds_error yrmcds_get(yrmcds* c, const char* key, size_t key_len, + int quiet, uint32_t* serial) { + if( c == NULL || key == NULL || key_len == 0 ) + return YRMCDS_BAD_ARGUMENT; + + if( c->text_mode ) + return yrmcds_text_get(c, key, key_len, quiet, serial); + + return send_command(c, quiet ? YRMCDS_CMD_GETQ : YRMCDS_CMD_GET, + 0, serial, key_len, key, 0, NULL, 0, NULL); +} + +yrmcds_error yrmcds_getk(yrmcds* c, const char* key, size_t key_len, + int quiet, uint32_t* serial) { + if( c == NULL || key == NULL || key_len == 0 ) + return YRMCDS_BAD_ARGUMENT; + + if( c->text_mode ) + return yrmcds_text_get(c, key, key_len, quiet, serial); + + return send_command(c, quiet ? YRMCDS_CMD_GETKQ : YRMCDS_CMD_GETK, + 0, serial, key_len, key, 0, NULL, 0, NULL); +} + +yrmcds_error yrmcds_get_touch(yrmcds* c, const char* key, size_t key_len, + uint32_t expire, int quiet, uint32_t* serial) { + if( c == NULL || key == NULL || key_len == 0 ) + return YRMCDS_BAD_ARGUMENT; + + if( c->text_mode ) + return YRMCDS_NOT_IMPLEMENTED; + + char extras[4]; + hton32(expire, extras); + return send_command(c, quiet ? YRMCDS_CMD_GATQ : YRMCDS_CMD_GAT, + 0, serial, key_len, key, + sizeof(extras), extras, 0, NULL); +} + +yrmcds_error yrmcds_getk_touch(yrmcds* c, const char* key, size_t key_len, + uint32_t expire, int quiet, uint32_t* serial) { + if( c == NULL || key == NULL || key_len == 0 ) + return YRMCDS_BAD_ARGUMENT; + + if( c->text_mode ) + return YRMCDS_NOT_IMPLEMENTED; + + char extras[4]; + hton32(expire, extras); + return send_command(c, quiet ? YRMCDS_CMD_GATKQ : YRMCDS_CMD_GATK, + 0, serial, key_len, key, + sizeof(extras), extras, 0, NULL); +} + +yrmcds_error yrmcds_lock_get(yrmcds* c, const char* key, size_t key_len, + int quiet, uint32_t* serial) { + if( c == NULL || key == NULL || key_len == 0 ) + return YRMCDS_BAD_ARGUMENT; + + if( c->text_mode ) + return YRMCDS_NOT_IMPLEMENTED; + + return send_command(c, quiet ? YRMCDS_CMD_LAGQ : YRMCDS_CMD_LAG, + 0, serial, key_len, key, 0, NULL, 0, NULL); +} + +yrmcds_error yrmcds_lock_getk(yrmcds* c, const char* key, size_t key_len, + int quiet, uint32_t* serial) { + if( c == NULL || key == NULL || key_len == 0 ) + return YRMCDS_BAD_ARGUMENT; + + if( c->text_mode ) + return YRMCDS_NOT_IMPLEMENTED; + + return send_command(c, quiet ? YRMCDS_CMD_LAGKQ : YRMCDS_CMD_LAGK, + 0, serial, key_len, key, 0, NULL, 0, NULL); +} + +yrmcds_error yrmcds_touch(yrmcds* c, const char* key, size_t key_len, + uint32_t expire, int quiet, uint32_t* serial) { + if( c == NULL || key == NULL || key_len == 0 ) + return YRMCDS_BAD_ARGUMENT; + + if( c->text_mode ) + return yrmcds_text_touch(c, key, key_len, expire, quiet, serial); + + char extras[4]; + hton32(expire, extras); + return send_command(c, YRMCDS_CMD_TOUCH, 0, serial, key_len, key, + sizeof(extras), extras, 0, NULL); +} + +yrmcds_error yrmcds_set(yrmcds* c, const char* key, size_t key_len, + const char* data, size_t data_len, + uint32_t flags, uint32_t expire, uint64_t cas, + int quiet, uint32_t* serial) { + if( c && c->text_mode ) + return yrmcds_text_set(c, key, key_len, data, data_len, + flags, expire, cas, quiet, serial); + + return send_data(c, quiet ? YRMCDS_CMD_SETQ : YRMCDS_CMD_SET, + key, key_len, data, data_len, flags, expire, cas, serial); +} + +yrmcds_error yrmcds_replace(yrmcds* c, const char* key, size_t key_len, + const char* data, size_t data_len, + uint32_t flags, uint32_t expire, uint64_t cas, + int quiet, uint32_t* serial) { + if( c && c->text_mode ) + return yrmcds_text_replace(c, key, key_len, data, data_len, + flags, expire, cas, quiet, serial); + + return send_data(c, quiet ? YRMCDS_CMD_REPLACEQ : YRMCDS_CMD_REPLACE, + key, key_len, data, data_len, flags, expire, cas, serial); +} + +yrmcds_error yrmcds_add(yrmcds* c, const char* key, size_t key_len, + const char* data, size_t data_len, + uint32_t flags, uint32_t expire, uint64_t cas, + int quiet, uint32_t* serial) { + if( c && c->text_mode ) + return yrmcds_text_add(c, key, key_len, data, data_len, + flags, expire, cas, quiet, serial); + + return send_data(c, quiet ? YRMCDS_CMD_ADDQ : YRMCDS_CMD_ADD, + key, key_len, data, data_len, flags, expire, cas, serial); +} + +yrmcds_error yrmcds_replace_unlock(yrmcds* c, const char* key, size_t key_len, + const char* data, size_t data_len, + uint32_t flags, uint32_t expire, + int quiet, uint32_t* serial) { + if( c && c->text_mode ) + return YRMCDS_NOT_IMPLEMENTED; + + return send_data(c, quiet ? YRMCDS_CMD_RAUQ : YRMCDS_CMD_RAU, + key, key_len, data, data_len, flags, expire, 0, serial); +} + +yrmcds_error yrmcds_incr(yrmcds* c, const char* key, size_t key_len, + uint64_t value, int quiet, uint32_t* serial) { + if( c == NULL || key == NULL || key_len == 0 ) + return YRMCDS_BAD_ARGUMENT; + + if( c->text_mode ) + return yrmcds_text_incr(c, key, key_len, value, quiet, serial); + + char extras[20]; + hton64(value, extras); + hton64((uint64_t)0, &extras[8]); + hton32(~(uint32_t)0, &extras[16]); + return send_command(c, quiet ? YRMCDS_CMD_INCREMENTQ : YRMCDS_CMD_INCREMENT, + 0, serial, key_len, key, + sizeof(extras), extras, 0, NULL); +} + +yrmcds_error yrmcds_incr2(yrmcds* c, const char* key, size_t key_len, + uint64_t value, uint64_t initial, uint32_t expire, + int quiet, uint32_t* serial) { + if( c == NULL || key == NULL || key_len == 0 ) + return YRMCDS_BAD_ARGUMENT; + + if( c->text_mode ) + return YRMCDS_NOT_IMPLEMENTED; + + char extras[20]; + hton64(value, extras); + hton64(initial, &extras[8]); + hton32(expire, &extras[16]); + return send_command(c, quiet ? YRMCDS_CMD_INCREMENTQ : YRMCDS_CMD_INCREMENT, + 0, serial, key_len, key, + sizeof(extras), extras, 0, NULL); +} + +yrmcds_error yrmcds_decr(yrmcds* c, const char* key, size_t key_len, + uint64_t value, int quiet, uint32_t* serial) { + if( c == NULL || key == NULL || key_len == 0 ) + return YRMCDS_BAD_ARGUMENT; + + if( c->text_mode ) + return yrmcds_text_decr(c, key, key_len, value, quiet, serial); + + char extras[20]; + hton64(value, extras); + hton64((uint64_t)0, &extras[8]); + hton32(~(uint32_t)0, &extras[16]); + return send_command(c, quiet ? YRMCDS_CMD_DECREMENTQ : YRMCDS_CMD_DECREMENT, + 0, serial, key_len, key, + sizeof(extras), extras, 0, NULL); +} + +yrmcds_error yrmcds_decr2(yrmcds* c, const char* key, size_t key_len, + uint64_t value, uint64_t initial, uint32_t expire, + int quiet, uint32_t* serial) { + if( c == NULL || key == NULL || key_len == 0 ) + return YRMCDS_BAD_ARGUMENT; + + if( c->text_mode ) + return YRMCDS_NOT_IMPLEMENTED; + + char extras[20]; + hton64(value, extras); + hton64(initial, &extras[8]); + hton32(expire, &extras[16]); + return send_command(c, quiet ? YRMCDS_CMD_DECREMENTQ : YRMCDS_CMD_DECREMENT, + 0, serial, key_len, key, + sizeof(extras), extras, 0, NULL); +} + +yrmcds_error yrmcds_append(yrmcds* c, const char* key, size_t key_len, + const char* data, size_t data_len, + int quiet, uint32_t* serial) { + if( c == NULL || key == NULL || key_len == 0 || + data == NULL || data_len == 0 ) + return YRMCDS_BAD_ARGUMENT; + + if( c->text_mode ) + return yrmcds_text_append(c, key, key_len, data, data_len, + quiet, serial); + + return send_command(c, quiet ? YRMCDS_CMD_APPENDQ : YRMCDS_CMD_APPEND, + 0, serial, key_len, key, 0, NULL, data_len, data); +} + +yrmcds_error yrmcds_prepend(yrmcds* c, const char* key, size_t key_len, + const char* data, size_t data_len, + int quiet, uint32_t* serial) { + if( c == NULL || key == NULL || key_len == 0 || + data == NULL || data_len == 0 ) + return YRMCDS_BAD_ARGUMENT; + + if( c->text_mode ) + return yrmcds_text_prepend(c, key, key_len, data, data_len, + quiet, serial); + + return send_command(c, quiet ? YRMCDS_CMD_PREPENDQ : YRMCDS_CMD_PREPEND, + 0, serial, key_len, key, 0, NULL, data_len, data); +} + +yrmcds_error yrmcds_remove(yrmcds* c, const char* key, size_t key_len, + int quiet, uint32_t* serial) { + if( c == NULL || key == NULL || key_len == 0 ) + return YRMCDS_BAD_ARGUMENT; + + if( c->text_mode ) + return yrmcds_text_remove(c, key, key_len, quiet, serial); + + return send_command(c, quiet ? YRMCDS_CMD_DELETEQ : YRMCDS_CMD_DELETE, + 0, serial, key_len, key, 0, NULL, 0, NULL); +} + +yrmcds_error yrmcds_lock(yrmcds* c, const char* key, size_t key_len, + int quiet, uint32_t* serial) { + if( c == NULL || key == NULL || key_len == 0 ) + return YRMCDS_BAD_ARGUMENT; + + if( c->text_mode ) + return YRMCDS_NOT_IMPLEMENTED; + + return send_command(c, quiet ? YRMCDS_CMD_LOCKQ : YRMCDS_CMD_LOCK, + 0, serial, key_len, key, 0, NULL, 0, NULL); +} + +yrmcds_error yrmcds_unlock(yrmcds* c, const char* key, size_t key_len, + int quiet, uint32_t* serial) { + if( c == NULL || key == NULL || key_len == 0 ) + return YRMCDS_BAD_ARGUMENT; + + if( c->text_mode ) + return YRMCDS_NOT_IMPLEMENTED; + + return send_command(c, quiet ? YRMCDS_CMD_UNLOCKQ : YRMCDS_CMD_UNLOCK, + 0, serial, key_len, key, 0, NULL, 0, NULL); +} + +yrmcds_error yrmcds_unlockall(yrmcds* c, int quiet, uint32_t* serial) { + if( c == NULL ) + return YRMCDS_BAD_ARGUMENT; + + if( c->text_mode ) + return YRMCDS_NOT_IMPLEMENTED; + + return send_command(c, quiet ? YRMCDS_CMD_UNLOCKALLQ : YRMCDS_CMD_UNLOCKALL, + 0, serial, 0, NULL, 0, NULL, 0, NULL); +} + +yrmcds_error yrmcds_flush(yrmcds* c, uint32_t delay, + int quiet, uint32_t* serial) { + if( c == NULL ) + return YRMCDS_BAD_ARGUMENT; + + if( c->text_mode ) + return yrmcds_text_flush(c, delay, quiet, serial); + + if( delay == 0 ) + return send_command(c, quiet ? YRMCDS_CMD_FLUSHQ : YRMCDS_CMD_FLUSH, + 0, serial, 0, NULL, 0, NULL, 0, NULL); + + char extra[4]; + hton32(delay, extra); + return send_command(c, quiet ? YRMCDS_CMD_FLUSHQ : YRMCDS_CMD_FLUSH, + 0, serial, 0, NULL, sizeof(extra), extra, 0, NULL); +} + +yrmcds_error yrmcds_stat_general(yrmcds* c, uint32_t* serial) { + if( c == NULL ) + return YRMCDS_BAD_ARGUMENT; + + if( c->text_mode ) + return YRMCDS_NOT_IMPLEMENTED; + + return send_command(c, YRMCDS_CMD_STAT, + 0, serial, 0, NULL, 0, NULL, 0, NULL); +} + +yrmcds_error yrmcds_stat_settings(yrmcds* c, uint32_t* serial) { + if( c == NULL ) + return YRMCDS_BAD_ARGUMENT; + + if( c->text_mode ) + return YRMCDS_NOT_IMPLEMENTED; + + const char key[] = "settings"; + return send_command(c, YRMCDS_CMD_STAT, + 0, serial, sizeof(key) - 1, key, 0, NULL, 0, NULL); +} + +yrmcds_error yrmcds_stat_items(yrmcds* c, uint32_t* serial) { + if( c == NULL ) + return YRMCDS_BAD_ARGUMENT; + + if( c->text_mode ) + return YRMCDS_NOT_IMPLEMENTED; + + const char key[] = "items"; + return send_command(c, YRMCDS_CMD_STAT, + 0, serial, sizeof(key) - 1, key, 0, NULL, 0, NULL); +} + +yrmcds_error yrmcds_stat_sizes(yrmcds* c, uint32_t* serial) { + if( c == NULL ) + return YRMCDS_BAD_ARGUMENT; + + if( c->text_mode ) + return YRMCDS_NOT_IMPLEMENTED; + + const char key[] = "sizes"; + return send_command(c, YRMCDS_CMD_STAT, + 0, serial, sizeof(key) - 1, key, 0, NULL, 0, NULL); +} + +yrmcds_error yrmcds_keys(yrmcds* c, const char* prefix, size_t prefix_len, + uint32_t* serial) { + if( c == NULL || + (prefix == NULL && prefix_len != 0) || + (prefix != NULL && prefix_len == 0) ) + return YRMCDS_BAD_ARGUMENT; + + if( c->text_mode ) + return YRMCDS_NOT_IMPLEMENTED; + + return send_command(c, YRMCDS_CMD_KEYS, + 0, serial, prefix_len, prefix, 0, NULL, 0, NULL); +} + +yrmcds_error yrmcds_version(yrmcds* c, uint32_t* serial) { + if( c == NULL ) + return YRMCDS_BAD_ARGUMENT; + + if( c->text_mode ) + return yrmcds_text_version(c, serial); + + return send_command(c, YRMCDS_CMD_VERSION, + 0, serial, 0, NULL, 0, NULL, 0, NULL); +} + +yrmcds_error yrmcds_quit(yrmcds* c, int quiet, uint32_t* serial) { + if( c == NULL ) + return YRMCDS_BAD_ARGUMENT; + + if( c->text_mode ) + return yrmcds_text_quit(c, serial); + + return send_command(c, quiet ? YRMCDS_CMD_QUITQ : YRMCDS_CMD_QUIT, + 0, serial, 0, NULL, 0, NULL, 0, NULL); +} diff --git a/web/server/h2o/libh2o/deps/libyrmcds/send_text.c b/web/server/h2o/libh2o/deps/libyrmcds/send_text.c new file mode 100644 index 00000000..b84fdce0 --- /dev/null +++ b/web/server/h2o/libh2o/deps/libyrmcds/send_text.c @@ -0,0 +1,414 @@ +// (C) 2016 Cybozu + +#include "yrmcds_text.h" +#include "yrmcds_portability.h" + +#ifdef LIBYRMCDS_USE_LZ4 +# include "lz4/lib/lz4.h" +#endif + +#include +#include +#include +#include +#include +#include +#include + +#define MAX_KEY_LENGTH 250 // from memcached spec. +#define TEXTBUF_SIZE 1000 // enough for any command & parameters. +#define EXPAND_STR(s) (s), (sizeof(s) - 1) +static const char CRLF[2] = {'\r', '\n'}; + +#ifdef LIBYRMCDS_USE_LZ4 +static inline void +hton32(uint32_t i, char* p) { + uint32_t n = htobe32(i); + memcpy(p, &n, sizeof(n)); +} +#endif + +static inline yrmcds_error +check_key(const char* key, size_t key_len) { + if( key_len > MAX_KEY_LENGTH ) + return YRMCDS_BAD_KEY; + + size_t i; + for( i = 0; i < key_len; i++ ) { + char c = key[i]; + if( c <= ' ' ) return YRMCDS_BAD_KEY; // SPC and control chars + if( c == 127 ) return YRMCDS_BAD_KEY; // DEL + } + + return YRMCDS_OK; +} + +typedef struct { + char* pos; + char buffer[TEXTBUF_SIZE]; +} textbuf_t; + +static inline size_t +textbuf_length(const textbuf_t* buf) { + return (size_t)(buf->pos - buf->buffer); +} + +static inline void +textbuf_init(textbuf_t* buf) { + buf->pos = buf->buffer; +} + +static inline void +textbuf_append_char(textbuf_t* buf, char c) { + *buf->pos = c; + ++buf->pos; +} + +static inline void +textbuf_append_string(textbuf_t* buf, const char* s, size_t len) { + memcpy(buf->pos, s, len); + buf->pos += len; +} + +#define textbuf_append_const_string(b, s) \ + textbuf_append_string(b, s, sizeof(s) - 1) + +static void +textbuf_append_uint64(textbuf_t* buf, uint64_t n) { + // UINT64_MAX = 18446744073709551615 -> char[20] + char nbuf[20]; + char* pos = (nbuf) + 20; + + do { + pos--; + uint64_t m = n % 10; + n /= 10; + *pos = (char)('0' + m); + } while( n != 0 ); + + textbuf_append_string(buf, pos, (size_t)(nbuf - pos + 20)); +} + + +static yrmcds_error +send_command(yrmcds* c, textbuf_t* buf, uint32_t* serial) { + memcpy(buf->pos, CRLF, sizeof(CRLF)); + buf->pos += sizeof(CRLF); + const char* p = buf->buffer; + size_t len = textbuf_length(buf); + +#ifndef LIBYRMCDS_NO_INTERNAL_LOCK + int e = pthread_mutex_lock(&c->lock); + if( e != 0 ) { + errno = e; + return YRMCDS_SYSTEM_ERROR; + } +#endif // ! LIBYRMCDS_NO_INTERNAL_LOCK + + c->serial = c->serial + 1; + if( serial != NULL ) + *serial = c->serial; + + yrmcds_error ret = YRMCDS_OK; + while( len > 0 ) { + ssize_t n = send(c->sock, p, len, 0); + if( n == -1 ) { + if( errno == EINTR ) continue; + ret = YRMCDS_SYSTEM_ERROR; + goto OUT; + } + size_t n2 = (size_t)n; + p += n2; + len -= n2; + } + + OUT: +#ifndef LIBYRMCDS_NO_INTERNAL_LOCK + pthread_mutex_unlock(&c->lock); +#endif + return ret; +} + +static yrmcds_error +send_data(yrmcds* c, const char* cmd, size_t cmd_len, + const char* key, size_t key_len, + const char* data, size_t data_len, + uint32_t flags, uint32_t expire, uint64_t cas, + int quiet, uint32_t* serial) { + if( key == NULL || key_len == 0 || data == NULL || data_len == 0 || quiet ) + return YRMCDS_BAD_ARGUMENT; + + yrmcds_error ret; + ret = check_key(key, key_len); + if( ret != YRMCDS_OK ) return ret; + + if( cas != 0 ) { + cmd = "cas"; + cmd_len = 3; + } + + int compressed = 0; +#ifdef LIBYRMCDS_USE_LZ4 + if( (c->compress_size > 0) && (data_len > c->compress_size) ) { + if( flags & YRMCDS_FLAG_COMPRESS ) + return YRMCDS_BAD_ARGUMENT; + + size_t bound = (size_t)LZ4_compressBound((int)data_len); + char* new_data = (char*)malloc(bound + sizeof(uint32_t)); + if( new_data == NULL ) + return YRMCDS_OUT_OF_MEMORY; + uint32_t new_size = + (uint32_t)LZ4_compress(data, new_data + sizeof(uint32_t), + (int)data_len); + if( new_size == 0 ) { + free(new_data); + return YRMCDS_COMPRESS_FAILED; + } + hton32((uint32_t)data_len, new_data); + flags |= YRMCDS_FLAG_COMPRESS; + data_len = sizeof(uint32_t) + new_size; + data = new_data; + compressed = 1; + } +#endif // LIBYRMCDS_USE_LZ4 + + textbuf_t buf[1]; + textbuf_init(buf); + + // "cmd key flags expire bytes (cas)" + textbuf_append_string(buf, cmd, cmd_len); + textbuf_append_char(buf, ' '); + textbuf_append_string(buf, key, key_len); + textbuf_append_char(buf, ' '); + textbuf_append_uint64(buf, flags); + textbuf_append_char(buf, ' '); + textbuf_append_uint64(buf, expire); + textbuf_append_char(buf, ' '); + textbuf_append_uint64(buf, (uint64_t)data_len); + if( cas != 0 ) { + textbuf_append_char(buf, ' '); + textbuf_append_uint64(buf, cas); + } + textbuf_append_string(buf, CRLF, sizeof(CRLF)); + + struct iovec iov[3]; + int iovcnt = 3; + iov[0].iov_base = buf[0].buffer; + iov[0].iov_len = textbuf_length(buf); + iov[1].iov_base = (void*)data; + iov[1].iov_len = data_len; + iov[2].iov_base = (void*)CRLF; + iov[2].iov_len = sizeof(CRLF); + +#ifndef LIBYRMCDS_NO_INTERNAL_LOCK + int e = pthread_mutex_lock(&c->lock); + if( e != 0 ) { + errno = e; + return YRMCDS_SYSTEM_ERROR; + } +#endif // ! LIBYRMCDS_NO_INTERNAL_LOCK + + c->serial = c->serial + 1; + if( serial != NULL ) + *serial = c->serial; + + while( iovcnt > 0 ) { + ssize_t n = writev(c->sock, iov, iovcnt); + if( n == -1 ) { + if( errno == EINTR ) continue; + ret = YRMCDS_SYSTEM_ERROR; + goto OUT; + } + size_t n2 = (size_t)n; + while( n2 > 0 ) { + if( n2 < iov[0].iov_len ) { + iov[0].iov_base = (char*)iov[0].iov_base + n2; + iov[0].iov_len -= n2; + break; + } + n2 -= iov[0].iov_len; + iovcnt --; + if( iovcnt == 0 ) + break; + + int i; + for( i = 0; i < iovcnt; ++i ) + iov[i] = iov[i+1]; + } + } + + OUT: +#ifndef LIBYRMCDS_NO_INTERNAL_LOCK + pthread_mutex_unlock(&c->lock); +#endif + if( compressed ) + free((void*)data); + return ret; +} + + +// public functions. +yrmcds_error yrmcds_text_get(yrmcds* c, const char* key, size_t key_len, + int quiet, uint32_t* serial) { + if( key == NULL || key_len == 0 || quiet ) + return YRMCDS_BAD_ARGUMENT; + + yrmcds_error ret; + ret = check_key(key, key_len); + if( ret != YRMCDS_OK ) return ret; + + textbuf_t buf[1]; + textbuf_init(buf); + + textbuf_append_const_string(buf, "gets "); + textbuf_append_string(buf, key, key_len); + + return send_command(c, buf, serial); +} + +yrmcds_error yrmcds_text_touch(yrmcds* c, const char* key, size_t key_len, + uint32_t expire, int quiet, uint32_t* serial) { + if( key == NULL || key_len == 0 || quiet ) + return YRMCDS_BAD_ARGUMENT; + + yrmcds_error ret; + ret = check_key(key, key_len); + if( ret != YRMCDS_OK ) return ret; + + textbuf_t buf[1]; + textbuf_init(buf); + + textbuf_append_const_string(buf, "touch "); + textbuf_append_string(buf, key, key_len); + textbuf_append_char(buf, ' '); + textbuf_append_uint64(buf, expire); + + return send_command(c, buf, serial); +} + +yrmcds_error yrmcds_text_set(yrmcds* c, const char* key, size_t key_len, + const char* data, size_t data_len, + uint32_t flags, uint32_t expire, uint64_t cas, + int quiet, uint32_t* serial) { + return send_data(c, EXPAND_STR("set"), key, key_len, data, data_len, + flags, expire, cas, quiet, serial); +} + +yrmcds_error yrmcds_text_replace(yrmcds* c, const char* key, size_t key_len, + const char* data, size_t data_len, + uint32_t flags, uint32_t expire, uint64_t cas, + int quiet, uint32_t* serial) { + return send_data(c, EXPAND_STR("replace"), key, key_len, data, data_len, + flags, expire, cas, quiet, serial); +} + +yrmcds_error yrmcds_text_add(yrmcds* c, const char* key, size_t key_len, + const char* data, size_t data_len, + uint32_t flags, uint32_t expire, uint64_t cas, + int quiet, uint32_t* serial) { + return send_data(c, EXPAND_STR("add"), key, key_len, data, data_len, + flags, expire, cas, quiet, serial); +} + +yrmcds_error yrmcds_text_append(yrmcds* c, const char* key, size_t key_len, + const char* data, size_t data_len, + int quiet, uint32_t* serial) { + return send_data(c, EXPAND_STR("append"), key, key_len, data, data_len, + 0, 0, 0, quiet, serial); +} + +yrmcds_error yrmcds_text_prepend(yrmcds* c, const char* key, size_t key_len, + const char* data, size_t data_len, + int quiet, uint32_t* serial) { + return send_data(c, EXPAND_STR("prepend"), key, key_len, data, data_len, + 0, 0, 0, quiet, serial); +} + +yrmcds_error yrmcds_text_incr(yrmcds* c, const char* key, size_t key_len, + uint64_t value, int quiet, uint32_t* serial) { + if( key == NULL || key_len == 0 || quiet ) + return YRMCDS_BAD_ARGUMENT; + + yrmcds_error ret; + ret = check_key(key, key_len); + if( ret != YRMCDS_OK ) return ret; + + textbuf_t buf[1]; + textbuf_init(buf); + + textbuf_append_const_string(buf, "incr "); + textbuf_append_string(buf, key, key_len); + textbuf_append_char(buf, ' '); + textbuf_append_uint64(buf, value); + + return send_command(c, buf, serial); +} + +yrmcds_error yrmcds_text_decr(yrmcds* c, const char* key, size_t key_len, + uint64_t value, int quiet, uint32_t* serial) { + if( key == NULL || key_len == 0 || quiet ) + return YRMCDS_BAD_ARGUMENT; + + yrmcds_error ret; + ret = check_key(key, key_len); + if( ret != YRMCDS_OK ) return ret; + + textbuf_t buf[1]; + textbuf_init(buf); + + textbuf_append_const_string(buf, "decr "); + textbuf_append_string(buf, key, key_len); + textbuf_append_char(buf, ' '); + textbuf_append_uint64(buf, value); + + return send_command(c, buf, serial); +} + +yrmcds_error yrmcds_text_remove(yrmcds* c, const char* key, size_t key_len, + int quiet, uint32_t* serial) { + if( key == NULL || key_len == 0 || quiet ) + return YRMCDS_BAD_ARGUMENT; + + yrmcds_error ret; + ret = check_key(key, key_len); + if( ret != YRMCDS_OK ) return ret; + + textbuf_t buf[1]; + textbuf_init(buf); + + textbuf_append_const_string(buf, "delete "); + textbuf_append_string(buf, key, key_len); + + return send_command(c, buf, serial); +} + +yrmcds_error yrmcds_text_flush(yrmcds* c, uint32_t delay, + int quiet, uint32_t* serial) { + if( quiet ) + return YRMCDS_BAD_ARGUMENT; + + textbuf_t buf[1]; + textbuf_init(buf); + + textbuf_append_const_string(buf, "flush_all"); + if( delay != 0 ) { + textbuf_append_char(buf, ' '); + textbuf_append_uint64(buf, delay); + } + + return send_command(c, buf, serial); +} + +yrmcds_error yrmcds_text_version(yrmcds* c, uint32_t* serial) { + textbuf_t buf[1]; + textbuf_init(buf); + textbuf_append_const_string(buf, "version"); + return send_command(c, buf, serial); +} + +yrmcds_error yrmcds_text_quit(yrmcds* c, uint32_t* serial) { + textbuf_t buf[1]; + textbuf_init(buf); + textbuf_append_const_string(buf, "quit"); + return send_command(c, buf, serial); +} diff --git a/web/server/h2o/libh2o/deps/libyrmcds/set_compression.c b/web/server/h2o/libh2o/deps/libyrmcds/set_compression.c new file mode 100644 index 00000000..f3d39370 --- /dev/null +++ b/web/server/h2o/libh2o/deps/libyrmcds/set_compression.c @@ -0,0 +1,14 @@ +// (C) 2013-2015 Cybozu. + +#include "yrmcds.h" + +yrmcds_error yrmcds_set_compression(yrmcds* c, size_t threshold) { +#ifdef LIBYRMCDS_USE_LZ4 + if( c == NULL ) + return YRMCDS_BAD_ARGUMENT; + c->compress_size = threshold; + return YRMCDS_OK; +#else + return YRMCDS_NOT_IMPLEMENTED; +#endif +} diff --git a/web/server/h2o/libh2o/deps/libyrmcds/socket.c b/web/server/h2o/libh2o/deps/libyrmcds/socket.c new file mode 100644 index 00000000..6d30ee16 --- /dev/null +++ b/web/server/h2o/libh2o/deps/libyrmcds/socket.c @@ -0,0 +1,35 @@ +// (C) 2013 Cybozu et al. + +#include "yrmcds.h" + +#include +#include +#include + +yrmcds_error yrmcds_shutdown(yrmcds* c) { + if( c == NULL ) + return YRMCDS_BAD_ARGUMENT; + if( shutdown(c->sock, SHUT_RD) == -1 ) { + return YRMCDS_SYSTEM_ERROR; + } + return YRMCDS_OK; +} + +int yrmcds_fileno(yrmcds* c) { + return c->sock; +} + +yrmcds_error yrmcds_set_timeout(yrmcds* c, int timeout) { + if( c == NULL || timeout < 0 ) + return YRMCDS_BAD_ARGUMENT; + + struct timeval tv; + tv.tv_sec = timeout; + tv.tv_usec = 0; + + if( setsockopt(c->sock, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)) == -1 ) + return YRMCDS_SYSTEM_ERROR; + if( setsockopt(c->sock, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv)) == -1 ) + return YRMCDS_SYSTEM_ERROR; + return YRMCDS_OK; +} diff --git a/web/server/h2o/libh2o/deps/libyrmcds/strerror.c b/web/server/h2o/libh2o/deps/libyrmcds/strerror.c new file mode 100644 index 00000000..e9359b59 --- /dev/null +++ b/web/server/h2o/libh2o/deps/libyrmcds/strerror.c @@ -0,0 +1,34 @@ +// (C) 2013-2015 Cybozu. + +#include "yrmcds.h" + +const char* yrmcds_strerror(yrmcds_error e) { + switch( e ) { + case YRMCDS_OK: + return "OK"; + case YRMCDS_SYSTEM_ERROR: + return "Check errno for details"; + case YRMCDS_BAD_ARGUMENT: + return "Bad argument"; + case YRMCDS_NOT_RESOLVED: + return "Host not found"; + case YRMCDS_TIMEOUT: + return "Timeout"; + case YRMCDS_DISCONNECTED: + return "Connection was reset by peer"; + case YRMCDS_OUT_OF_MEMORY: + return "Failed to allocate memory"; + case YRMCDS_COMPRESS_FAILED: + return "Failed to compress data"; + case YRMCDS_PROTOCOL_ERROR: + return "Received malformed packet"; + case YRMCDS_NOT_IMPLEMENTED: + return "Not implemented"; + case YRMCDS_IN_BINARY: + return "Connection is fixed for binary protocol"; + case YRMCDS_BAD_KEY: + return "Bad key"; + default: + return "Unknown error"; + }; +} diff --git a/web/server/h2o/libh2o/deps/libyrmcds/t/t.h b/web/server/h2o/libh2o/deps/libyrmcds/t/t.h new file mode 100644 index 00000000..fd79d59c --- /dev/null +++ b/web/server/h2o/libh2o/deps/libyrmcds/t/t.h @@ -0,0 +1,75 @@ +// test utilities + +#include +#include +#include +#include + +static int n_failures = 0; + +static void check_error(yrmcds_error e) { + if( e == YRMCDS_OK ) + return; + + fprintf(stderr, "yrmcds error: %s\n", yrmcds_strerror(e)); + exit(1); +} + +static yrmcds* get_yrmcds(yrmcds* c) { + const char* host = getenv("YRMCDS_HOST"); + if( host == NULL ) { + return NULL; + } + uint16_t port = 11211; + if( getenv("YRMCDS_PORT") ) { + port = (uint16_t)atoi(getenv("YRMCDS_PORT")); + } + + check_error( yrmcds_connect(c, host, port) ); + return c; +} + +static void test_main(yrmcds* c); + +#define TEST_MAIN() static void test_main(yrmcds* c) + +int main(int argc, char** argv) { + yrmcds c_; + yrmcds* c = get_yrmcds(&c_); + if( c == NULL ) { + fprintf(stderr, "No YRMCDS_HOST. Skipped.\n"); + return 0; + } + + test_main(c); + yrmcds_close(c); + + if( n_failures > 0 ) { + fprintf(stderr, "%d tests failed.\n", n_failures); + return 1; + } + fprintf(stderr, "Passed.\n"); + return 0; +} + +#define DEF_TEST(name) void test_##name(yrmcds* c) + +#define CALL_TEST(name) \ + fprintf(stderr, "[%s]\n", #name); \ + test_##name(c); \ + uint32_t serial_##name; \ + check_error( yrmcds_flush(c, 0, 0, &serial_##name) ); \ + while( 1 ) { \ + yrmcds_response r; \ + check_error( yrmcds_recv(c, &r) ); \ + if( r.serial == serial_##name ) break; \ + } \ + sleep(1) + +#define ASSERT(expr, to_return) \ + if( ! (expr) ) { \ + fprintf(stderr, "assertion failure at line %d: %s\n", \ + __LINE__, #expr); \ + n_failures++; \ + if( to_return ) return; \ + } diff --git a/web/server/h2o/libh2o/deps/libyrmcds/t/text.c b/web/server/h2o/libh2o/deps/libyrmcds/t/text.c new file mode 100644 index 00000000..9419cb41 --- /dev/null +++ b/web/server/h2o/libh2o/deps/libyrmcds/t/text.c @@ -0,0 +1,294 @@ +#include "t.h" +#include +#include + +DEF_TEST(set) { + // quiet cannot be used + ASSERT( yrmcds_set(c, "a", 1, "a", 1, 0, 0, 0, 1, NULL) == YRMCDS_BAD_ARGUMENT, 0 ); + + uint32_t serial; + check_error( yrmcds_set(c, "hoge", 4, "hoge", 4, 1, 0, 0, 0, &serial) ); + + yrmcds_response r; + check_error( yrmcds_recv(c, &r) ); + ASSERT( r.serial == serial, 0 ); + ASSERT( r.status == YRMCDS_STATUS_OK, 1 ); + + check_error( yrmcds_get(c, "hoge", 4, 0, &serial) ); + check_error( yrmcds_recv(c, &r) ); + ASSERT( r.serial == serial, 0 ); + ASSERT( r.status == YRMCDS_STATUS_OK, 1 ); + ASSERT( r.data_len == 4, 0 ); + ASSERT( memcmp(r.data, "hoge", 4) == 0, 0 ); + ASSERT( r.flags == 1, 0 ); + + // CAS failure + check_error( yrmcds_set(c, "hoge", 4, "fu", 2, 2, 0, r.cas_unique+1, + 0, &serial) ); + check_error( yrmcds_recv(c, &r) ); + ASSERT( r.serial == serial, 0 ); + ASSERT( r.status == YRMCDS_STATUS_EXISTS, 1 ); + + check_error( yrmcds_getk(c, "hoge", 4, 0, &serial) ); + check_error( yrmcds_recv(c, &r) ); + ASSERT( r.serial == serial, 0 ); + ASSERT( r.status == YRMCDS_STATUS_OK, 1 ); + ASSERT( r.key_len == 4, 0 ); + ASSERT( memcmp(r.key, "hoge", 4) == 0, 0 ); + ASSERT( r.data_len == 4, 0 ); + ASSERT( memcmp(r.data, "hoge", 4) == 0, 0 ); + ASSERT( r.flags == 1, 0 ); + + // CAS success + check_error( yrmcds_set(c, "hoge", 4, "fu", 2, 4097, 0, r.cas_unique, + 0, &serial) ); + check_error( yrmcds_recv(c, &r) ); + ASSERT( r.serial == serial, 0 ); + ASSERT( r.status == YRMCDS_STATUS_OK, 1 ); + + check_error( yrmcds_getk(c, "hoge", 4, 0, &serial) ); + check_error( yrmcds_recv(c, &r) ); + ASSERT( r.serial == serial, 0 ); + ASSERT( r.status == YRMCDS_STATUS_OK, 1 ); + ASSERT( r.key_len == 4, 0 ); + ASSERT( memcmp(r.key, "hoge", 4) == 0, 0 ); + ASSERT( r.data_len == 2, 0 ); + ASSERT( memcmp(r.data, "fu", 2) == 0, 0 ); + ASSERT( r.flags == 4097, 0 ); + + // set exptime + check_error( yrmcds_set(c, "hoge", 4, "999", 3, 0, 1, 0, 0, &serial) ); + check_error( yrmcds_recv(c, &r) ); + ASSERT( r.serial == serial, 0 ); + ASSERT( r.status == YRMCDS_STATUS_OK, 1 ); + + sleep(2); + + check_error( yrmcds_getk(c, "hoge", 4, 0, &serial) ); + check_error( yrmcds_recv(c, &r) ); + ASSERT( r.serial == serial, 0 ); + ASSERT( r.status == YRMCDS_STATUS_NOTFOUND, 1 ); +} + +DEF_TEST(add) { + // quiet cannot be used + ASSERT( yrmcds_add(c, "a", 1, "a", 1, 0, 0, 0, 1, NULL) == YRMCDS_BAD_ARGUMENT, 0 ); + + uint32_t serial; + check_error( yrmcds_add(c, "hoge", 4, "hoge", 4, 1, 0, 0, 0, &serial) ); + + yrmcds_response r; + check_error( yrmcds_recv(c, &r) ); + ASSERT( r.serial == serial, 0 ); + ASSERT( r.status == YRMCDS_STATUS_OK, 1 ); + + check_error( yrmcds_add(c, "hoge", 4, "fu", 2, 16, 0, 0, 0, &serial) ); + check_error( yrmcds_recv(c, &r) ); + ASSERT( r.serial == serial, 0 ); + ASSERT( r.status == YRMCDS_STATUS_NOTSTORED, 1 ); +} + +DEF_TEST(replace) { + // quiet cannot be used + ASSERT( yrmcds_replace(c, "a", 1, "a", 1, 0, 0, 0, 1, NULL) == YRMCDS_BAD_ARGUMENT, 0 ); + + uint32_t serial; + check_error( yrmcds_replace(c, "abc", 3, "hoge", 4, 1, 0, 0, 0, &serial) ); + + yrmcds_response r; + check_error( yrmcds_recv(c, &r) ); + ASSERT( r.serial == serial, 0 ); + ASSERT( r.status == YRMCDS_STATUS_NOTSTORED, 1 ); + + check_error( yrmcds_set(c, "abc", 3, "def", 3, 16, 0, 0, 0, &serial) ); + check_error( yrmcds_recv(c, &r) ); + ASSERT( r.serial == serial, 0 ); + ASSERT( r.status == YRMCDS_STATUS_OK, 1 ); + + check_error( yrmcds_replace(c, "abc", 3, "hoge", 4, 1, 0, 0, 0, &serial) ); + check_error( yrmcds_recv(c, &r) ); + ASSERT( r.serial == serial, 0 ); + ASSERT( r.status == YRMCDS_STATUS_OK, 1 ); +} + +DEF_TEST(append) { + uint32_t serial; + yrmcds_response r; + + // quiet cannot be used + ASSERT( yrmcds_append(c, "a", 1, "a", 1, 1, NULL) == YRMCDS_BAD_ARGUMENT, 0 ); + + check_error( yrmcds_append(c, "012", 3, "345", 3, 0, &serial) ); + check_error( yrmcds_recv(c, &r) ); + ASSERT( r.serial == serial, 0 ); + ASSERT( r.status == YRMCDS_STATUS_NOTSTORED, 1 ); + + check_error( yrmcds_set(c, "012", 3, "345", 3, 1, 0, 0, 0, &serial) ); + check_error( yrmcds_recv(c, &r) ); + ASSERT( r.serial == serial, 0 ); + ASSERT( r.status == YRMCDS_STATUS_OK, 1 ); + + check_error( yrmcds_append(c, "012", 3, "6789", 4, 0, &serial) ); + check_error( yrmcds_recv(c, &r) ); + ASSERT( r.serial == serial, 0 ); + ASSERT( r.status == YRMCDS_STATUS_OK, 1 ); + + check_error( yrmcds_getk(c, "012", 3, 0, &serial) ); + check_error( yrmcds_recv(c, &r) ); + ASSERT( r.serial == serial, 0 ); + ASSERT( r.status == YRMCDS_STATUS_OK, 1 ); + ASSERT( r.data_len == 7, 1 ); + ASSERT( memcmp(r.data, "3456789", 7) == 0, 0 ); +} + +DEF_TEST(prepend) { + uint32_t serial; + yrmcds_response r; + + // quiet cannot be used + ASSERT( yrmcds_prepend(c, "a", 1, "a", 1, 1, NULL) == YRMCDS_BAD_ARGUMENT, 0 ); + + check_error( yrmcds_prepend(c, "012", 3, "345", 3, 0, &serial) ); + check_error( yrmcds_recv(c, &r) ); + ASSERT( r.serial == serial, 0 ); + ASSERT( r.status == YRMCDS_STATUS_NOTSTORED, 1 ); + + check_error( yrmcds_set(c, "012", 3, "345", 3, 1, 0, 0, 0, &serial) ); + check_error( yrmcds_recv(c, &r) ); + ASSERT( r.serial == serial, 0 ); + ASSERT( r.status == YRMCDS_STATUS_OK, 1 ); + + check_error( yrmcds_prepend(c, "012", 3, "6789", 4, 0, &serial) ); + check_error( yrmcds_recv(c, &r) ); + ASSERT( r.serial == serial, 0 ); + ASSERT( r.status == YRMCDS_STATUS_OK, 1 ); + + check_error( yrmcds_getk(c, "012", 3, 0, &serial) ); + check_error( yrmcds_recv(c, &r) ); + ASSERT( r.serial == serial, 0 ); + ASSERT( r.status == YRMCDS_STATUS_OK, 1 ); + ASSERT( r.data_len == 7, 1 ); + ASSERT( memcmp(r.data, "6789345", 7) == 0, 0 ); +} + +DEF_TEST(touch) { + uint32_t serial; + yrmcds_response r; + + // quiet cannot be used + ASSERT( yrmcds_touch(c, "a", 1, 0, 1, NULL) == YRMCDS_BAD_ARGUMENT, 0 ); + + check_error( yrmcds_set(c, "a", 1, "345", 3, 0, 1, 0, 0, &serial) ); + check_error( yrmcds_recv(c, &r) ); + ASSERT( r.serial == serial, 0 ); + ASSERT( r.status == YRMCDS_STATUS_OK, 1 ); + + check_error( yrmcds_touch(c, "a", 1, 0, 0, &serial) ); + check_error( yrmcds_recv(c, &r) ); + ASSERT( r.serial == serial, 0 ); + ASSERT( r.status == YRMCDS_STATUS_OK, 1 ); + + sleep(2); + + check_error( yrmcds_getk(c, "a", 1, 0, &serial) ); + check_error( yrmcds_recv(c, &r) ); + ASSERT( r.serial == serial, 0 ); + ASSERT( r.status == YRMCDS_STATUS_OK, 1 ); +} + +DEF_TEST(incdec) { + uint32_t serial; + yrmcds_response r; + + // quiet cannot be used + ASSERT( yrmcds_incr(c, "a", 1, 100, 1, NULL) == YRMCDS_BAD_ARGUMENT, 0 ); + ASSERT( yrmcds_decr(c, "a", 1, 100, 1, NULL) == YRMCDS_BAD_ARGUMENT, 0 ); + + check_error( yrmcds_incr(c, "a", 1, 100, 0, &serial) ); + check_error( yrmcds_recv(c, &r) ); + ASSERT( r.serial == serial, 0 ); + ASSERT( r.status == YRMCDS_STATUS_NOTFOUND, 0 ); + + check_error( yrmcds_decr(c, "a", 1, 100, 0, &serial) ); + check_error( yrmcds_recv(c, &r) ); + ASSERT( r.serial == serial, 0 ); + ASSERT( r.status == YRMCDS_STATUS_NOTFOUND, 0 ); + + check_error( yrmcds_set(c, "a", 1, "345", 3, 0, 1, 0, 0, &serial) ); + check_error( yrmcds_recv(c, &r) ); + ASSERT( r.serial == serial, 0 ); + ASSERT( r.status == YRMCDS_STATUS_OK, 1 ); + + check_error( yrmcds_incr(c, "a", 1, 1000, 0, &serial) ); + check_error( yrmcds_recv(c, &r) ); + ASSERT( r.serial == serial, 0 ); + ASSERT( r.status == YRMCDS_STATUS_OK, 1 ); + ASSERT( r.value == 1345, 1 ); + + check_error( yrmcds_decr(c, "a", 1, 1, 0, &serial) ); + check_error( yrmcds_recv(c, &r) ); + ASSERT( r.serial == serial, 0 ); + ASSERT( r.status == YRMCDS_STATUS_OK, 1 ); + ASSERT( r.value == 1344, 1 ); + + check_error( yrmcds_getk(c, "a", 1, 0, &serial) ); + check_error( yrmcds_recv(c, &r) ); + ASSERT( r.serial == serial, 0 ); + ASSERT( r.status == YRMCDS_STATUS_OK, 1 ); + ASSERT( r.data_len == 4, 1 ); + ASSERT( memcmp(r.data, "1344", 4) == 0, 0 ); +} + +DEF_TEST(remove) { + uint32_t serial; + yrmcds_response r; + + // quiet cannot be used + ASSERT( yrmcds_remove(c, "a", 1, 1, NULL) == YRMCDS_BAD_ARGUMENT, 0 ); + + check_error( yrmcds_remove(c, "uuu", 3, 0, &serial) ); + check_error( yrmcds_recv(c, &r) ); + ASSERT( r.serial == serial, 0 ); + ASSERT( r.status == YRMCDS_STATUS_NOTFOUND, 0 ); + + check_error( yrmcds_set(c, "uuu", 3, "345", 3, 111, 0, 0, 0, &serial) ); + check_error( yrmcds_recv(c, &r) ); + ASSERT( r.serial == serial, 0 ); + ASSERT( r.status == YRMCDS_STATUS_OK, 1 ); + + check_error( yrmcds_remove(c, "uuu", 3, 0, &serial) ); + check_error( yrmcds_recv(c, &r) ); + ASSERT( r.serial == serial, 0 ); + ASSERT( r.status == YRMCDS_STATUS_OK, 1 ); + + check_error( yrmcds_getk(c, "uuu", 3, 0, &serial) ); + check_error( yrmcds_recv(c, &r) ); + ASSERT( r.serial == serial, 0 ); + ASSERT( r.status == YRMCDS_STATUS_NOTFOUND, 1 ); +} + +DEF_TEST(version) { + uint32_t serial; + yrmcds_response r; + + check_error( yrmcds_version(c, &serial) ); + check_error( yrmcds_recv(c, &r) ); + ASSERT( r.serial == serial, 0 ); + ASSERT( r.status == YRMCDS_STATUS_OK, 1 ); + ASSERT( r.data_len > 0, 1 ); + fprintf(stderr, "version=%.*s\n", (int)r.data_len, r.data); +} + +TEST_MAIN() { + check_error( yrmcds_text_mode(c) ); + + CALL_TEST(set); + CALL_TEST(add); + CALL_TEST(replace); + CALL_TEST(append); + CALL_TEST(prepend); + CALL_TEST(touch); + CALL_TEST(incdec); + CALL_TEST(remove); + CALL_TEST(version); +} diff --git a/web/server/h2o/libh2o/deps/libyrmcds/text_mode.c b/web/server/h2o/libh2o/deps/libyrmcds/text_mode.c new file mode 100644 index 00000000..77f95086 --- /dev/null +++ b/web/server/h2o/libh2o/deps/libyrmcds/text_mode.c @@ -0,0 +1,32 @@ +// (C) 2016 Cybozu. + +#include "yrmcds.h" + +#include + +yrmcds_error yrmcds_text_mode(yrmcds* c) { + if( c == NULL ) + return YRMCDS_BAD_ARGUMENT; + +#ifndef LIBYRMCDS_NO_INTERNAL_LOCK + int e = pthread_mutex_lock(&c->lock); + if( e != 0 ) { + errno = e; + return YRMCDS_SYSTEM_ERROR; + } +#endif // ! LIBYRMCDS_NO_INTERNAL_LOCK + + yrmcds_error ret = YRMCDS_OK; + if( c->serial != 0 ) { + ret = YRMCDS_IN_BINARY; + goto OUT; + } + + c->text_mode = 1; + + OUT: +#ifndef LIBYRMCDS_NO_INTERNAL_LOCK + pthread_mutex_unlock(&c->lock); +#endif + return ret; +} diff --git a/web/server/h2o/libh2o/deps/libyrmcds/yc-cnt.c b/web/server/h2o/libh2o/deps/libyrmcds/yc-cnt.c new file mode 100644 index 00000000..f25178c2 --- /dev/null +++ b/web/server/h2o/libh2o/deps/libyrmcds/yc-cnt.c @@ -0,0 +1,306 @@ +#include "yrmcds.h" +#include +#include +#include +#include +#include +#include +#include + +static const char USAGE[] = + "Usage: yc-cnt [-s SERVER] [-p PORT] [-h] SUBCOMMAND\n" + "\n" + "Subcommands:\n" + " noop\n" + " get NAME\n" + " acquire RESOURCES MAXIMUM\n" + " release RESOURCES\n" + " stats\n" + " dump\n"; + +static const char DEFAULT_SERVER[] = "localhost"; +static const uint16_t DEFAULT_PORT = 11215; + +static void recv_or_die(yrmcds_cnt* c, yrmcds_cnt_response* r, uint32_t serial) { + yrmcds_error e; + while( 1 ) { + e = yrmcds_cnt_recv(c, r); + if( e != YRMCDS_OK ) { + fprintf(stderr, "yc-cnt: failed to recv: %s\n", + yrmcds_strerror(e)); + yrmcds_cnt_close(c); + exit(1); + } + if( r->serial == serial ) + break; + } +} + +static void cmd_noop(yrmcds_cnt* c) { + yrmcds_error e; + uint32_t serial; + + e = yrmcds_cnt_noop(c, &serial); + if( e != YRMCDS_OK ) { + fprintf(stderr, "yc-cnt: failed to send noop: %s\n", + yrmcds_strerror(e)); + yrmcds_cnt_close(c); + exit(1); + } + + yrmcds_cnt_response r; + recv_or_die(c, &r, serial); + + if( r.status == YRMCDS_STATUS_OK ) { + puts("OK"); + } else { + printf("ERROR: %02x %.*s\n", r.status, (int)r.body_length, r.body); + yrmcds_cnt_close(c); + exit(2); + } +} + +static void cmd_get(yrmcds_cnt* c, + const char* name, size_t name_len) { + yrmcds_error e; + uint32_t serial; + + e = yrmcds_cnt_get(c, name, name_len, &serial); + if( e != YRMCDS_OK ) { + fprintf(stderr, "yc-cnt: failed to send get: %s\n", + yrmcds_strerror(e)); + yrmcds_cnt_close(c); + exit(1); + } + + yrmcds_cnt_response r; + recv_or_die(c, &r, serial); + + if( r.status == YRMCDS_STATUS_OK ) { + printf("%" PRIu32 "\n", r.current_consumption); + } else { + printf("ERROR: %02x %.*s\n", r.status, (int)r.body_length, r.body); + yrmcds_cnt_close(c); + exit(2); + } +} + +static void cmd_acquire(yrmcds_cnt* c, + const char* name, size_t name_len, + uint32_t resouces, uint32_t initial) { + yrmcds_error e; + uint32_t serial; + + e = yrmcds_cnt_acquire(c, name, name_len, resouces, initial, &serial); + if( e != YRMCDS_OK ) { + fprintf(stderr, "yc-cnt: failed to send acquire: %s\n", + yrmcds_strerror(e)); + yrmcds_cnt_close(c); + exit(1); + } + + yrmcds_cnt_response r; + recv_or_die(c, &r, serial); + + if( r.status == YRMCDS_STATUS_OK ) { + printf("%" PRIu32 "\n", r.resources); + } else { + printf("ERROR: %02x %.*s\n", r.status, (int)r.body_length, r.body); + yrmcds_cnt_close(c); + exit(2); + } +} + +static void cmd_release(yrmcds_cnt* c, + const char* name, size_t name_len, + uint32_t resouces) { + yrmcds_error e; + uint32_t serial; + + e = yrmcds_cnt_release(c, name, name_len, resouces, &serial); + if( e != YRMCDS_OK ) { + fprintf(stderr, "yc-cnt: failed to send release: %s\n", + yrmcds_strerror(e)); + yrmcds_cnt_close(c); + exit(1); + } + + yrmcds_cnt_response r; + recv_or_die(c, &r, serial); + + if( r.status == YRMCDS_STATUS_OK ) { + puts("OK"); + } else { + printf("ERROR: %02x %.*s\n", r.status, (int)r.body_length, r.body); + yrmcds_cnt_close(c); + exit(2); + } +} + +static void cmd_stats(yrmcds_cnt* c) { + yrmcds_error e; + uint32_t serial; + + e = yrmcds_cnt_stats(c, &serial); + if( e != YRMCDS_OK ) { + fprintf(stderr, "yc-cnt: failed to send stats: %s\n", + yrmcds_strerror(e)); + yrmcds_cnt_close(c); + exit(1); + } + + yrmcds_cnt_response r; + recv_or_die(c, &r, serial); + + if( r.status == YRMCDS_STATUS_OK ) { + size_t i; + for( i = 0; i < r.stats->count; ++i ) { + yrmcds_cnt_stat* stat = &r.stats->records[i]; + printf("%.*s %.*s\n", (int)stat->name_length, stat->name, + (int)stat->value_length, stat->value); + } + } else { + printf("ERROR: %02x %.*s\n", r.status, (int)r.body_length, r.body); + yrmcds_cnt_close(c); + exit(2); + } +} + +static void cmd_dump(yrmcds_cnt* c) { + yrmcds_error e; + uint32_t serial; + + e = yrmcds_cnt_dump(c, &serial); + if( e != YRMCDS_OK ) { + fprintf(stderr, "yc-cnt: failed to send stats: %s\n", + yrmcds_strerror(e)); + yrmcds_cnt_close(c); + exit(1); + } + + for(;;) { + yrmcds_cnt_response r; + recv_or_die(c, &r, serial); + + if( r.status != YRMCDS_STATUS_OK ) { + printf("ERROR: %02x %.*s\n", r.status, (int)r.body_length, r.body); + yrmcds_cnt_close(c); + exit(2); + } + if( r.body_length == 0 ) + break; + printf("%" PRIu32 " %" PRIu32 " %.*s\n", + r.current_consumption, r.max_consumption, + (int)r.name_length, r.name); + } +} + +void usage() { + fprintf(stderr, "%s", USAGE); + exit(1); +} + +int main(int argc, char** argv) { + const char* server = DEFAULT_SERVER; + uint16_t port = DEFAULT_PORT; + + while( 1 ) { + int n; + int c = getopt(argc, argv, "s:p:h"); + if( c == -1 ) break; + switch( c ) { + case 's': + server = optarg; + break; + case 'p': + n = atoi(optarg); + if( n <= 0 || n > 65535 ) { + fprintf(stderr, "yc-cnt: invalid TCP port.\n"); + return 1; + } + port = (uint16_t)n; + break; + case 'h': + usage(); + default: + return 1; + } + } + + if( optind == argc ) + usage(); + + argc -= optind; + argv += optind; + + yrmcds_cnt c; + yrmcds_error e = yrmcds_cnt_connect(&c, server, port); + if( e != YRMCDS_OK ) { + fprintf(stderr, "yc-cnt: failed to connect to '%s:%d': %s\n", + server, port, yrmcds_strerror(e)); + exit(1); + } + yrmcds_cnt_set_timeout(&c, 1); + + if( strcmp(argv[0], "noop") == 0 ) { + if( argc != 1 ) { + fprintf(stderr, "yc-cnt: invalid number of arguments.\n"); + goto EXIT; + } + cmd_noop(&c); + } else if( strcmp(argv[0], "get") == 0 ) { + if( argc != 2 ) { + fprintf(stderr, "yc-cnt: invalid number of arguments.\n"); + goto EXIT; + } + cmd_get(&c, argv[1], strlen(argv[1])); + } else if( strcmp(argv[0], "acquire") == 0 ){ + if( argc != 4 ) { + fprintf(stderr, "yc-cnt: invalid number of arguments.\n"); + goto EXIT; + } + uint32_t resources, initial; + if( sscanf(argv[2], "%" PRIu32, &resources) != 1 ) { + fprintf(stderr, "yc-cnt: RESOURCES must be a unsigned 4-byte integer.\n"); + goto EXIT; + } + if( sscanf(argv[3], "%" PRIu32, &initial) != 1 ) { + fprintf(stderr, "yc-cnt: MAXIMUM must be a unsigned 4-byte integer.\n"); + goto EXIT; + } + cmd_acquire(&c, argv[1], strlen(argv[1]), resources, initial); + } else if( strcmp(argv[0], "release") == 0 ){ + if( argc != 3 ) { + fprintf(stderr, "yc-cnt: invalid number of arguments.\n"); + goto EXIT; + } + uint32_t resources; + if( sscanf(argv[2], "%" PRIu32, &resources) != 1 ) { + fprintf(stderr, "yc-cnt: RESOURCES must be a unsigned 4-byte integer.\n"); + goto EXIT; + } + cmd_release(&c, argv[1], strlen(argv[1]), resources); + } else if( strcmp(argv[0], "stats") == 0 ) { + if( argc != 1 ) { + fprintf(stderr, "yc-cnt: invalid number of arguments.\n"); + goto EXIT; + } + cmd_stats(&c); + } else if( strcmp(argv[0], "dump") == 0 ) { + if( argc != 1 ) { + fprintf(stderr, "yc-cnt: invalid number of arguments.\n"); + goto EXIT; + } + cmd_dump(&c); + } else { + fprintf(stderr, "yc-cnt: unknown command: %s\n", argv[0]); + goto EXIT; + } + + yrmcds_cnt_close(&c); + return 0; + +EXIT: + yrmcds_cnt_close(&c); + exit(1); +} diff --git a/web/server/h2o/libh2o/deps/libyrmcds/yc.c b/web/server/h2o/libh2o/deps/libyrmcds/yc.c new file mode 100644 index 00000000..78d3df45 --- /dev/null +++ b/web/server/h2o/libh2o/deps/libyrmcds/yc.c @@ -0,0 +1,1099 @@ +// (C) 2013-2015 Cybozu. + +#include "yrmcds.h" + +#include +#include +#include +#include +#include +#include +#include + +static const uint16_t DEFAULT_PORT = 11211; +static const char DEFAULT_SERVER[] = "localhost"; +static const size_t DEFAULT_COMPRESS = 16384; +static int debug = 0; +static int quiet = 0; + +static void version() { + printf("yc with libyrmcds " LIBYRMCDS_VERSION "\n"); +} + +static void usage() { + printf("Usage: yc " + "[-h] [-v] [-d] [-t] [-s SERVER] [-p PORT] [-c COMPRESS] COMMAND ...\n\n" + "Options:\n" + " -h print help and exit.\n" + " -v print version information.\n" + " -d turn on debug messages.\n" + " -t turn on text protocol mode.\n" + " -q Use quiet commands, if possible.\n" + " -s connect to SERVER. Default: localhost\n" + " -p TCP port number. Default: 11211\n" + " -c compression threshold. Default: 16384\n\n" + "Commands:\n" + " noop\n" + " ping the server.\n" + " get KEY\n" + " get an object.\n" + " getk KEY\n" + " get an object with key.\n" + " gat KEY EXPIRE\n" + " get and touch an object.\n" + " gatk KEY EXPIRE\n" + " get and touch an object with key.\n" + " lag KEY\n" + " lock and get an object.\n" + " lagk KEY\n" + " lock and get an object with key.\n" + " touch KEY EXPIRE\n" + " touch an object.\n" + " set KEY FILE [EXPIRE [FLAGS [CAS]]]\n" + " store FILE data. If FILE is \"-\", stdin is used.\n" + " replace KEY FILE [EXPIRE [FLAGS [CAS]]]\n" + " update an existing object. FILE is the same as set.\n" + " add KEY FILE [EXPIRE [FLAGS [CAS]]]\n" + " create a new object. FILE is the same as set.\n" + " rau KEY FILE [EXPIRE [FLAGS]]\n" + " replace a locked object then unlock it.\n" + " Since this command always fails, do not use this.\n" + " incr KEY VALUE [INITIAL [EXPIRE]]\n" + " increments an exiting object's value by VALUE.\n" + " If INITIAL is given, new object is created when KEY\n" + " is not found. EXPIRE is used only when an object is\n" + " created.\n" + " decr KEY VALUE [INITIAL [EXPIRE]]\n" + " decrements an exiting object's value by VALUE.\n" + " If INITIAL is given, new object is created when KEY\n" + " is not found. EXPIRE is used only when an object is\n" + " created.\n" + " append KEY FILE\n" + " append FILE data FILE is the same as set.\n" + " prepend KEY FILE\n" + " prepend FILE data FILE is the same as set.\n" + " delete KEY\n" + " delete an object.\n" + " lock KEY\n" + " locks an object.\n" + " unlock KEY\n" + " this command always fails. Do not use this.\n" + " unlockall\n" + " this command has no effect.\n" + " flush [DELAY]\n" + " flush all unlocked items immediately or after DELAY seconds.\n" + " stat [settings|items|sizes]\n" + " obtain general or specified statistics.\n" + " keys [PREFIX]\n" + " dump keys matching PREFIX.\n" + " version\n" + " shows the server version.\n" + " quit\n" + " just quits. Not much interesting.\n" + ); +} + +static void print_response(const yrmcds_response* r) { + fprintf(stderr, "dump response:\n" + " serial: %u\n" + " length: %lu\n" + " status: 0x%04x\n" + " command: 0x%02x\n" + " cas: %" PRIu64 "\n" + " flags: 0x%08x\n" + " value: %" PRIu64 "\n", + r->serial, (unsigned long)r->length, r->status, r->command, + r->cas_unique, r->flags, r->value); + if( r->key_len ) + fprintf(stderr, " key: %.*s (%lu bytes)\n", + (int)r->key_len, r->key, (unsigned long)r->key_len); + if( r->data_len ) + fprintf(stderr, " data: %.*s (%lu bytes)\n", + (int)r->data_len, r->data, (unsigned long)r->data_len); +} + +static void write_data(const yrmcds_response* r) { + const char* p = r->data; + size_t to_write = r->data_len; + while( to_write > 0 ) { + ssize_t n = write(STDOUT_FILENO, p, to_write); + if( n == -1 ) return; + p += n; + to_write -= (size_t)n; + } + // writing a newline breaks data equality... + //char nl = '\n'; + //write(STDOUT_FILENO, &nl, 1); +} + +static size_t read_data(const char* filename, char** pdata) { + int fd; + if( strcmp(filename, "-") == 0 ) { + fd = STDIN_FILENO; + } else { + fd = open(filename, O_RDONLY); + if( fd == -1 ) return 0; + } + + size_t data_len = 0; + size_t capacity = 1 << 20; + *pdata = (char*)malloc(capacity); + if( *pdata == NULL ) return 0; + while( 1 ) { + if( (capacity - data_len) < (1 << 20) ) { + char* new_data = (char*)realloc(*pdata, capacity * 2); + if( new_data == NULL ) { + free(*pdata); + *pdata = NULL; + return 0; + } + *pdata = new_data; + capacity *= 2; + } + ssize_t n = read(fd, *pdata + data_len, 1 << 20); + if( n == -1 ) { + free(*pdata); + *pdata = NULL; + return 0; + } + if( n == 0 ) break; + data_len += (size_t)n; + } + + if( fd != STDIN_FILENO ) + close(fd); + return data_len; +} + + +#define CHECK_ERROR(e) \ + if( e != 0 ) { \ + if( e == YRMCDS_SYSTEM_ERROR ) { \ + fprintf(stderr, "system error: %s\n", strerror(errno)); \ + } else { \ + fprintf(stderr, "yrmcds error: %s\n", yrmcds_strerror(e)); \ + } \ + return 2; \ + } + +#define CHECK_RESPONSE(r) \ + if( r->status != YRMCDS_STATUS_OK ) { \ + fprintf(stderr, "Command failed: 0x%04x %.*s\n", \ + r->status, (int)r->data_len, r->data); \ + return 3; \ + } + +int cmd_noop(int argc, char** argv, yrmcds* s) { + yrmcds_response r[1]; + uint32_t serial; + yrmcds_error e = yrmcds_noop(s, &serial); + CHECK_ERROR(e); + if( debug ) + fprintf(stderr, "request serial = %u\n", serial); + e = yrmcds_recv(s, r); + CHECK_ERROR(e); + if( debug ) + print_response(r); + CHECK_RESPONSE(r); + printf("OK\n"); + return 0; +} + +int cmd_get(int argc, char** argv, yrmcds* s) { + if( argc != 1 ) { + fprintf(stderr, "Wrong number of arguments.\n"); + return 1; + } + yrmcds_response r[1]; + uint32_t serial; + yrmcds_error e = yrmcds_get(s, argv[0], strlen(argv[0]), quiet, &serial); + CHECK_ERROR(e); + if( quiet ) { + e = yrmcds_noop(s, &serial); + CHECK_ERROR(e); + } + if( debug ) + fprintf(stderr, "request serial = %u\n", serial); + while( 1 ) { + e = yrmcds_recv(s, r); + CHECK_ERROR(e); + if( debug ) + print_response(r); + CHECK_RESPONSE(r); + if( r->serial == serial ) + break; + } + write_data(r); + return 0; +} + +int cmd_getk(int argc, char** argv, yrmcds* s) { + if( argc != 1 ) { + fprintf(stderr, "Wrong number of arguments.\n"); + return 1; + } + yrmcds_response r[1]; + uint32_t serial; + yrmcds_error e = yrmcds_getk(s, argv[0], strlen(argv[0]), quiet, &serial); + CHECK_ERROR(e); + if( quiet ) { + e = yrmcds_noop(s, &serial); + CHECK_ERROR(e); + } + if( debug ) + fprintf(stderr, "request serial = %u\n", serial); + while( 1 ) { + e = yrmcds_recv(s, r); + CHECK_ERROR(e); + if( debug ) + print_response(r); + CHECK_RESPONSE(r); + if( r->serial == serial ) + break; + } + write_data(r); + return 0; +} + +int cmd_gat(int argc, char** argv, yrmcds* s) { + if( argc != 2 ) { + fprintf(stderr, "Wrong number of arguments.\n"); + return 1; + } + const char* key = argv[0]; + uint32_t expire = (uint32_t)strtoull(argv[1], NULL, 0); + + yrmcds_response r[1]; + uint32_t serial; + yrmcds_error e = yrmcds_get_touch(s, key, strlen(key), expire, quiet, &serial); + CHECK_ERROR(e); + if( quiet ) { + e = yrmcds_noop(s, &serial); + CHECK_ERROR(e); + } + if( debug ) + fprintf(stderr, "request serial = %u\n", serial); + while( 1 ) { + e = yrmcds_recv(s, r); + CHECK_ERROR(e); + if( debug ) + print_response(r); + CHECK_RESPONSE(r); + if( r->serial == serial ) + break; + } + write_data(r); + return 0; +} + +int cmd_gatk(int argc, char** argv, yrmcds* s) { + if( argc != 2 ) { + fprintf(stderr, "Wrong number of arguments.\n"); + return 1; + } + const char* key = argv[0]; + uint32_t expire = (uint32_t)strtoull(argv[1], NULL, 0); + + yrmcds_response r[1]; + uint32_t serial; + yrmcds_error e = yrmcds_getk_touch(s, key, strlen(key), expire, quiet, &serial); + CHECK_ERROR(e); + if( quiet ) { + e = yrmcds_noop(s, &serial); + CHECK_ERROR(e); + } + if( debug ) + fprintf(stderr, "request serial = %u\n", serial); + while( 1 ) { + e = yrmcds_recv(s, r); + CHECK_ERROR(e); + if( debug ) + print_response(r); + CHECK_RESPONSE(r); + if( r->serial == serial ) + break; + } + write_data(r); + return 0; +} + +int cmd_lag(int argc, char** argv, yrmcds* s) { + if( argc != 1 ) { + fprintf(stderr, "Wrong number of arguments.\n"); + return 1; + } + yrmcds_response r[1]; + uint32_t serial; + yrmcds_error e = yrmcds_lock_get(s, argv[0], strlen(argv[0]), quiet, &serial); + CHECK_ERROR(e); + if( quiet ) { + e = yrmcds_noop(s, &serial); + CHECK_ERROR(e); + } + if( debug ) + fprintf(stderr, "request serial = %u\n", serial); + while( 1 ) { + e = yrmcds_recv(s, r); + CHECK_ERROR(e); + if( debug ) + print_response(r); + CHECK_RESPONSE(r); + if( r->serial == serial ) + break; + } + write_data(r); + fprintf(stderr, "Press enter to unlock.\n"); + getchar(); + return 0; +} + +int cmd_lagk(int argc, char** argv, yrmcds* s) { + if( argc != 1 ) { + fprintf(stderr, "Wrong number of arguments.\n"); + return 1; + } + yrmcds_response r[1]; + uint32_t serial; + yrmcds_error e = yrmcds_lock_getk(s, argv[0], strlen(argv[0]), quiet, &serial); + CHECK_ERROR(e); + if( quiet ) { + e = yrmcds_noop(s, &serial); + CHECK_ERROR(e); + } + if( debug ) + fprintf(stderr, "request serial = %u\n", serial); + while( 1 ) { + e = yrmcds_recv(s, r); + CHECK_ERROR(e); + if( debug ) + print_response(r); + CHECK_RESPONSE(r); + if( r->serial == serial ) + break; + } + write_data(r); + fprintf(stderr, "Press enter to unlock.\n"); + getchar(); + return 0; +} + +int cmd_touch(int argc, char** argv, yrmcds* s) { + if( argc != 2 ) { + fprintf(stderr, "Wrong number of arguments.\n"); + return 1; + } + const char* key = argv[0]; + uint32_t expire = (uint32_t)strtoull(argv[1], NULL, 0); + + yrmcds_response r[1]; + uint32_t serial; + yrmcds_error e = yrmcds_touch(s, key, strlen(key), expire, quiet, &serial); + CHECK_ERROR(e); + if( quiet ) { + e = yrmcds_noop(s, &serial); + CHECK_ERROR(e); + } + if( debug ) + fprintf(stderr, "request serial = %u\n", serial); + while( 1 ) { + e = yrmcds_recv(s, r); + CHECK_ERROR(e); + if( debug ) + print_response(r); + CHECK_RESPONSE(r); + if( r->serial == serial ) + break; + } + return 0; +} + +int cmd_set(int argc, char** argv, yrmcds* s) { + if( argc < 2 || 5 < argc ) { + fprintf(stderr, "Wrong number of arguments.\n"); + return 1; + } + const char* key = argv[0]; + char* data = NULL; + size_t data_len = read_data(argv[1], &data); + if( data == NULL ) { + fprintf(stderr, "Failed to read data.\n"); + return 2; + } + uint32_t expire = 0; + uint32_t flags = 0; + uint64_t cas = 0; + + if( argc > 2 ) + expire = (uint32_t)strtoull(argv[2], NULL, 0); + if( argc > 3 ) + flags = (uint32_t)strtoull(argv[3], NULL, 0); + if( argc > 4 ) + cas = (uint64_t)strtoull(argv[4], NULL, 0); + + yrmcds_response r[1]; + uint32_t serial; + yrmcds_error e = yrmcds_set(s, key, strlen(key), data, data_len, + flags, expire, cas, quiet, &serial); + free(data); + CHECK_ERROR(e); + if( quiet ) { + e = yrmcds_noop(s, &serial); + CHECK_ERROR(e); + } + if( debug ) + fprintf(stderr, "request serial = %u\n", serial); + while( 1 ) { + e = yrmcds_recv(s, r); + CHECK_ERROR(e); + if( debug ) + print_response(r); + CHECK_RESPONSE(r); + if( r->serial == serial ) + break; + } + return 0; +} + +int cmd_replace(int argc, char** argv, yrmcds* s) { + if( argc < 2 || 5 < argc ) { + fprintf(stderr, "Wrong number of arguments.\n"); + return 1; + } + const char* key = argv[0]; + char* data = NULL; + size_t data_len = read_data(argv[1], &data); + if( data == NULL ) { + fprintf(stderr, "Failed to read data.\n"); + return 2; + } + uint32_t expire = 0; + uint32_t flags = 0; + uint64_t cas = 0; + + if( argc > 2 ) + expire = (uint32_t)strtoull(argv[2], NULL, 0); + if( argc > 3 ) + flags = (uint32_t)strtoull(argv[3], NULL, 0); + if( argc > 4 ) + cas = (uint64_t)strtoull(argv[4], NULL, 0); + + yrmcds_response r[1]; + uint32_t serial; + yrmcds_error e = yrmcds_replace(s, key, strlen(key), data, data_len, + flags, expire, cas, quiet, &serial); + free(data); + CHECK_ERROR(e); + if( quiet ) { + e = yrmcds_noop(s, &serial); + CHECK_ERROR(e); + } + if( debug ) + fprintf(stderr, "request serial = %u\n", serial); + while( 1 ) { + e = yrmcds_recv(s, r); + CHECK_ERROR(e); + if( debug ) + print_response(r); + CHECK_RESPONSE(r); + if( r->serial == serial ) + break; + } + return 0; +} + +int cmd_add(int argc, char** argv, yrmcds* s) { + if( argc < 2 || 5 < argc ) { + fprintf(stderr, "Wrong number of arguments.\n"); + return 1; + } + const char* key = argv[0]; + char* data = NULL; + size_t data_len = read_data(argv[1], &data); + if( data == NULL ) { + fprintf(stderr, "Failed to read data.\n"); + return 2; + } + uint32_t expire = 0; + uint32_t flags = 0; + uint64_t cas = 0; + + if( argc > 2 ) + expire = (uint32_t)strtoull(argv[2], NULL, 0); + if( argc > 3 ) + flags = (uint32_t)strtoull(argv[3], NULL, 0); + if( argc > 4 ) + cas = (uint64_t)strtoull(argv[4], NULL, 0); + + yrmcds_response r[1]; + uint32_t serial; + yrmcds_error e = yrmcds_add(s, key, strlen(key), data, data_len, + flags, expire, cas, quiet, &serial); + free(data); + CHECK_ERROR(e); + if( quiet ) { + e = yrmcds_noop(s, &serial); + CHECK_ERROR(e); + } + if( debug ) + fprintf(stderr, "request serial = %u\n", serial); + while( 1 ) { + e = yrmcds_recv(s, r); + CHECK_ERROR(e); + if( debug ) + print_response(r); + CHECK_RESPONSE(r); + if( r->serial == serial ) + break; + } + return 0; +} + +int cmd_rau(int argc, char** argv, yrmcds* s) { + if( argc < 2 || 4 < argc ) { + fprintf(stderr, "Wrong number of arguments.\n"); + return 1; + } + const char* key = argv[0]; + char* data = NULL; + size_t data_len = read_data(argv[1], &data); + if( data == NULL ) { + fprintf(stderr, "Failed to read data.\n"); + return 2; + } + uint32_t expire = 0; + uint32_t flags = 0; + + if( argc > 2 ) + expire = (uint32_t)strtoull(argv[2], NULL, 0); + if( argc > 3 ) + flags = (uint32_t)strtoull(argv[3], NULL, 0); + + yrmcds_response r[1]; + uint32_t serial; + yrmcds_error e = yrmcds_replace_unlock(s, key, strlen(key), data, data_len, + flags, expire, quiet, &serial); + free(data); + CHECK_ERROR(e); + if( quiet ) { + e = yrmcds_noop(s, &serial); + CHECK_ERROR(e); + } + if( debug ) + fprintf(stderr, "request serial = %u\n", serial); + while( 1 ) { + e = yrmcds_recv(s, r); + CHECK_ERROR(e); + if( debug ) + print_response(r); + CHECK_RESPONSE(r); + if( r->serial == serial ) + break; + } + return 0; +} + +int cmd_incr(int argc, char** argv, yrmcds* s) { + if( argc < 2 || 4 < argc ) { + fprintf(stderr, "Wrong number of arguments.\n"); + return 1; + } + const char* key = argv[0]; + uint64_t value = (uint64_t)strtoull(argv[1], NULL, 0); + uint64_t initial = 0; + uint32_t expire = ~(uint32_t)0; + + if( argc > 2 ) { + initial = (uint64_t)strtoull(argv[2], NULL, 0); + expire = 0; + } + if( argc > 3 ) + expire = (uint32_t)strtoull(argv[3], NULL, 0); + + yrmcds_response r[1]; + uint32_t serial; + yrmcds_error e; + if( argc == 2 ) { + e = yrmcds_incr(s, key, strlen(key), value, quiet, &serial); + } else { + e = yrmcds_incr2(s, key, strlen(key), value, initial, expire, + quiet, &serial); + } + CHECK_ERROR(e); + if( quiet ) { + e = yrmcds_noop(s, &serial); + CHECK_ERROR(e); + } + if( debug ) + fprintf(stderr, "request serial = %u\n", serial); + while( 1 ) { + e = yrmcds_recv(s, r); + CHECK_ERROR(e); + if( debug ) + print_response(r); + CHECK_RESPONSE(r); + if( r->serial == serial ) + break; + } + printf("%" PRIu64 "\n", r->value); + return 0; +} + +int cmd_decr(int argc, char** argv, yrmcds* s) { + if( argc < 2 || 4 < argc ) { + fprintf(stderr, "Wrong number of arguments.\n"); + return 1; + } + const char* key = argv[0]; + uint64_t value = (uint64_t)strtoull(argv[1], NULL, 0); + uint64_t initial = 0; + uint32_t expire = ~(uint32_t)0; + + if( argc > 2 ) { + initial = (uint64_t)strtoull(argv[2], NULL, 0); + expire = 0; + } + if( argc > 3 ) + expire = (uint32_t)strtoull(argv[3], NULL, 0); + + yrmcds_response r[1]; + uint32_t serial; + yrmcds_error e; + if( argc == 2 ) { + e = yrmcds_decr(s, key, strlen(key), value, quiet, &serial); + } else { + e = yrmcds_decr2(s, key, strlen(key), value, initial, expire, + quiet, &serial); + } + CHECK_ERROR(e); + if( quiet ) { + e = yrmcds_noop(s, &serial); + CHECK_ERROR(e); + } + if( debug ) + fprintf(stderr, "request serial = %u\n", serial); + while( 1 ) { + e = yrmcds_recv(s, r); + CHECK_ERROR(e); + if( debug ) + print_response(r); + CHECK_RESPONSE(r); + if( r->serial == serial ) + break; + } + printf("%" PRIu64 "\n", r->value); + return 0; +} + +int cmd_append(int argc, char** argv, yrmcds* s) { + if( argc != 2 ) { + fprintf(stderr, "Wrong number of arguments.\n"); + return 1; + } + const char* key = argv[0]; + char* data = NULL; + size_t data_len = read_data(argv[1], &data); + if( data == NULL ) { + fprintf(stderr, "Failed to read data.\n"); + return 2; + } + + yrmcds_response r[1]; + uint32_t serial; + yrmcds_error e = yrmcds_append(s, key, strlen(key), + data, data_len, quiet, &serial); + free(data); + CHECK_ERROR(e); + if( quiet ) { + e = yrmcds_noop(s, &serial); + CHECK_ERROR(e); + } + if( debug ) + fprintf(stderr, "request serial = %u\n", serial); + while( 1 ) { + e = yrmcds_recv(s, r); + CHECK_ERROR(e); + if( debug ) + print_response(r); + CHECK_RESPONSE(r); + if( r->serial == serial ) + break; + } + return 0; +} + +int cmd_prepend(int argc, char** argv, yrmcds* s) { + if( argc != 2 ) { + fprintf(stderr, "Wrong number of arguments.\n"); + return 1; + } + const char* key = argv[0]; + char* data = NULL; + size_t data_len = read_data(argv[1], &data); + if( data == NULL ) { + fprintf(stderr, "Failed to read data.\n"); + return 2; + } + + yrmcds_response r[1]; + uint32_t serial; + yrmcds_error e = yrmcds_prepend(s, key, strlen(key), + data, data_len, quiet, &serial); + free(data); + CHECK_ERROR(e); + if( quiet ) { + e = yrmcds_noop(s, &serial); + CHECK_ERROR(e); + } + if( debug ) + fprintf(stderr, "request serial = %u\n", serial); + while( 1 ) { + e = yrmcds_recv(s, r); + CHECK_ERROR(e); + if( debug ) + print_response(r); + CHECK_RESPONSE(r); + if( r->serial == serial ) + break; + } + return 0; +} + +int cmd_delete(int argc, char** argv, yrmcds* s) { + if( argc != 1 ) { + fprintf(stderr, "Wrong number of arguments.\n"); + return 1; + } + yrmcds_response r[1]; + uint32_t serial; + yrmcds_error e = yrmcds_remove(s, argv[0], strlen(argv[0]), quiet, &serial); + CHECK_ERROR(e); + if( quiet ) { + e = yrmcds_noop(s, &serial); + CHECK_ERROR(e); + } + if( debug ) + fprintf(stderr, "request serial = %u\n", serial); + while( 1 ) { + e = yrmcds_recv(s, r); + CHECK_ERROR(e); + if( debug ) + print_response(r); + CHECK_RESPONSE(r); + if( r->serial == serial ) + break; + } + write_data(r); + return 0; +} + +int cmd_lock(int argc, char** argv, yrmcds* s) { + if( argc != 1 ) { + fprintf(stderr, "Wrong number of arguments.\n"); + return 1; + } + yrmcds_response r[1]; + uint32_t serial; + yrmcds_error e = yrmcds_lock(s, argv[0], strlen(argv[0]), quiet, &serial); + CHECK_ERROR(e); + if( quiet ) { + e = yrmcds_noop(s, &serial); + CHECK_ERROR(e); + } + if( debug ) + fprintf(stderr, "request serial = %u\n", serial); + while( 1 ) { + e = yrmcds_recv(s, r); + CHECK_ERROR(e); + if( debug ) + print_response(r); + CHECK_RESPONSE(r); + if( r->serial == serial ) + break; + } + fprintf(stderr, "Press enter to unlock.\n"); + getchar(); + return 0; +} + +int cmd_unlock(int argc, char** argv, yrmcds* s) { + if( argc != 1 ) { + fprintf(stderr, "Wrong number of arguments.\n"); + return 1; + } + yrmcds_response r[1]; + uint32_t serial; + yrmcds_error e = yrmcds_unlock(s, argv[0], strlen(argv[0]), quiet, &serial); + CHECK_ERROR(e); + if( quiet ) { + e = yrmcds_noop(s, &serial); + CHECK_ERROR(e); + } + if( debug ) + fprintf(stderr, "request serial = %u\n", serial); + while( 1 ) { + e = yrmcds_recv(s, r); + CHECK_ERROR(e); + if( debug ) + print_response(r); + CHECK_RESPONSE(r); + if( r->serial == serial ) + break; + } + return 0; +} + +int cmd_unlockall(int argc, char** argv, yrmcds* s) { + yrmcds_response r[1]; + uint32_t serial; + yrmcds_error e = yrmcds_unlockall(s, quiet, &serial); + CHECK_ERROR(e); + if( quiet ) { + e = yrmcds_noop(s, &serial); + CHECK_ERROR(e); + } + if( debug ) + fprintf(stderr, "request serial = %u\n", serial); + while( 1 ) { + e = yrmcds_recv(s, r); + CHECK_ERROR(e); + if( debug ) + print_response(r); + CHECK_RESPONSE(r); + if( r->serial == serial ) + break; + } + return 0; +} + +int cmd_flush(int argc, char** argv, yrmcds* s) { + uint32_t delay = 0; + if( argc == 1 ) + delay = (uint32_t)strtoull(argv[0], NULL, 0); + + yrmcds_response r[1]; + uint32_t serial; + yrmcds_error e = yrmcds_flush(s, delay, quiet, &serial); + CHECK_ERROR(e); + if( quiet ) { + e = yrmcds_noop(s, &serial); + CHECK_ERROR(e); + } + if( debug ) + fprintf(stderr, "request serial = %u\n", serial); + while( 1 ) { + e = yrmcds_recv(s, r); + CHECK_ERROR(e); + if( debug ) + print_response(r); + CHECK_RESPONSE(r); + if( r->serial == serial ) + break; + } + return 0; +} + +int cmd_stat(int argc, char** argv, yrmcds* s) { + yrmcds_response r[1]; + uint32_t serial; + yrmcds_error e; + if( argc > 0 ) { + if( strcmp(argv[0], "settings") == 0 ) { + e = yrmcds_stat_settings(s, &serial); + } else if( strcmp(argv[0], "items") == 0 ) { + e = yrmcds_stat_items(s, &serial); + } else if( strcmp(argv[0], "sizes") == 0 ) { + e = yrmcds_stat_sizes(s, &serial); + } else { + fprintf(stderr, "No such statistics.\n"); + return 1; + } + } else { + e = yrmcds_stat_general(s, &serial); + } + CHECK_ERROR(e); + while( 1 ) { + e = yrmcds_recv(s, r); + CHECK_ERROR(e); + if( debug ) + print_response(r); + CHECK_RESPONSE(r); + if( r->key_len == 0 ) + break; + if( r->data_len == 0 ) + continue; + printf("%.*s: %.*s\n", (int)r->key_len, r->key, + (int)r->data_len, r->data); + } + return 0; +} + +int cmd_keys(int argc, char** argv, yrmcds* s) { + const char* prefix = NULL; + size_t prefix_len = 0; + if( argc == 1 ) { + prefix = argv[0]; + prefix_len = strlen(prefix); + } + yrmcds_response r[1]; + uint32_t serial; + yrmcds_error e = yrmcds_keys(s, prefix, prefix_len, &serial); + CHECK_ERROR(e); + if( debug ) + fprintf(stderr, "request serial = %u\n", serial); + while( 1 ) { + e = yrmcds_recv(s, r); + CHECK_ERROR(e); + if( debug ) + print_response(r); + CHECK_RESPONSE(r); + if( r->serial != serial ) + continue; + if( r->key_len == 0 ) + break; + printf("%.*s\n", (int)r->key_len, r->key); + } + return 0; +} + +int cmd_version(int argc, char** argv, yrmcds* s) { + yrmcds_response r[1]; + uint32_t serial; + yrmcds_error e = yrmcds_version(s, &serial); + CHECK_ERROR(e); + e = yrmcds_recv(s, r); + CHECK_ERROR(e); + if( debug ) + print_response(r); + CHECK_RESPONSE(r); + printf("%.*s\n", (int)r->data_len, r->data); + return 0; +} + +int cmd_quit(int argc, char** argv, yrmcds* s) { + yrmcds_response r[1]; + uint32_t serial; + yrmcds_error e = yrmcds_quit(s, quiet, &serial); + CHECK_ERROR(e); + if( debug ) + fprintf(stderr, "request serial = %u\n", serial); + if( ! quiet ) { + e = yrmcds_recv(s, r); + CHECK_ERROR(e); + if( debug ) + print_response(r); + CHECK_RESPONSE(r); + } + return 0; +} + +int main(int argc, char** argv) { + const char* server = DEFAULT_SERVER; + uint16_t port = DEFAULT_PORT; + size_t compression = DEFAULT_COMPRESS; + int text_mode = 0; + + while( 1 ) { + int n; + int c = getopt(argc, argv, "s:p:c:dtqvh"); + if( c == -1 ) break; + switch( c ) { + case 's': + server = optarg; + break; + case 'p': + n = atoi(optarg); + if( n <= 0 || n > 65535 ) { + fprintf(stderr, "Invalid TCP port.\n"); + return 1; + } + port = (uint16_t)n; + break; + case 'c': + n = atoi(optarg); + if( n <= 0 ) { + fprintf(stderr, "Invalid compression thoreshold.\n"); + return 1; + } + compression = (size_t)n; + break; + case 'd': + debug = 1; + break; + case 't': + text_mode = 1; + break; + case 'q': + quiet = 1; + break; + case 'v': + version(); + return 0; + case 'h': + usage(); + return 0; + default: + return 1; + } + } + + if( optind == argc ) { + usage(); + return 0; + } + + const char* cmd = argv[optind]; + argc -= optind + 1; + argv += optind + 1; + + yrmcds s[1]; + yrmcds_error e = yrmcds_connect(s, server, port); + CHECK_ERROR(e); + if( text_mode ) { + e = yrmcds_text_mode(s); + CHECK_ERROR(e); + } + e = yrmcds_set_compression(s, compression); + if( e != 0 && e != YRMCDS_NOT_IMPLEMENTED ) { + yrmcds_close(s); + CHECK_ERROR(e); + } + + int ret = 1; +#define do_cmd(name) \ + if( strcmp(cmd, #name) == 0 ) { \ + ret = cmd_##name(argc, argv, s); \ + goto OUT; \ + } + + do_cmd(noop); + do_cmd(get); + do_cmd(getk); + do_cmd(gat); + do_cmd(gatk); + do_cmd(lag); + do_cmd(lagk); + do_cmd(touch); + do_cmd(set); + do_cmd(replace); + do_cmd(add); + do_cmd(rau); + do_cmd(incr); + do_cmd(decr); + do_cmd(append); + do_cmd(prepend); + do_cmd(delete); + do_cmd(lock); + do_cmd(unlock); + do_cmd(unlockall); + do_cmd(flush); + do_cmd(stat); + do_cmd(keys); + do_cmd(version); + do_cmd(quit); + + fprintf(stderr, "No such command: %s\n", cmd); + + OUT: + yrmcds_close(s); + return ret; +} diff --git a/web/server/h2o/libh2o/deps/libyrmcds/yrmcds.h b/web/server/h2o/libh2o/deps/libyrmcds/yrmcds.h new file mode 100644 index 00000000..758f1bdc --- /dev/null +++ b/web/server/h2o/libh2o/deps/libyrmcds/yrmcds.h @@ -0,0 +1,1071 @@ +/** @file yrmcds.h + * libyrmcds public API. + * (C) 2013-2016 Cybozu. + */ + +#pragma once + +#ifndef YRMCDS_H_INCLUDED +#define YRMCDS_H_INCLUDED + +/// Library version string such as "1.3.0". +#define LIBYRMCDS_VERSION "1.3.0" + +/// Library version number such as 10201. +#define LIBYRMCDS_VERSION_NUMBER 10300 + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Data structure of a connection to memcached/yrmcds server. + */ +typedef struct { + int sock; ///< the socket file descriptor. + + /* for sending */ + pthread_mutex_t lock; ///< guard lock to serialize sends. + uint32_t serial; ///< last issued serial number. + size_t compress_size; ///< threshold data size for LZ4 compression. + + /* for receiving */ + char* recvbuf; ///< received data buffer. + size_t capacity; ///< buffer capacity + size_t used; ///< used bytes. + size_t last_size; ///< size of the last response. + char* decompressed; ///< decompressed data. + int invalid; ///< invalid flag. + + /* for text mode */ + int text_mode; ///< text mode flag. + uint32_t rserial; ///< serial emulation. +} yrmcds; + + +/** + * Server status codes. + */ +typedef enum { + YRMCDS_STATUS_OK = 0, + YRMCDS_STATUS_NOTFOUND = 0x0001, + YRMCDS_STATUS_EXISTS = 0x0002, + YRMCDS_STATUS_TOOLARGEVALUE = 0x0003, + YRMCDS_STATUS_INVALID = 0x0004, + YRMCDS_STATUS_NOTSTORED = 0x0005, + YRMCDS_STATUS_NONNUMERIC = 0x0006, + YRMCDS_STATUS_LOCKED = 0x0010, + YRMCDS_STATUS_NOTLOCKED = 0x0011, + YRMCDS_STATUS_UNKNOWNCOMMAND = 0x0081, + YRMCDS_STATUS_OUTOFMEMORY = 0x0082, + + YRMCDS_STATUS_OTHER = 0xffff, ///< unknown error in text protocol. +} yrmcds_status; + + +/** + * Binary commands. + */ +typedef enum { + YRMCDS_CMD_GET = '\x00', + YRMCDS_CMD_SET = '\x01', + YRMCDS_CMD_ADD = '\x02', + YRMCDS_CMD_REPLACE = '\x03', + YRMCDS_CMD_DELETE = '\x04', + YRMCDS_CMD_INCREMENT = '\x05', + YRMCDS_CMD_DECREMENT = '\x06', + YRMCDS_CMD_QUIT = '\x07', + YRMCDS_CMD_FLUSH = '\x08', + YRMCDS_CMD_GETQ = '\x09', + YRMCDS_CMD_NOOP = '\x0a', + YRMCDS_CMD_VERSION = '\x0b', + YRMCDS_CMD_GETK = '\x0c', + YRMCDS_CMD_GETKQ = '\x0d', + YRMCDS_CMD_APPEND = '\x0e', + YRMCDS_CMD_PREPEND = '\x0f', + YRMCDS_CMD_STAT = '\x10', + YRMCDS_CMD_SETQ = '\x11', + YRMCDS_CMD_ADDQ = '\x12', + YRMCDS_CMD_REPLACEQ = '\x13', + YRMCDS_CMD_DELETEQ = '\x14', + YRMCDS_CMD_INCREMENTQ = '\x15', + YRMCDS_CMD_DECREMENTQ = '\x16', + YRMCDS_CMD_QUITQ = '\x17', + YRMCDS_CMD_FLUSHQ = '\x18', + YRMCDS_CMD_APPENDQ = '\x19', + YRMCDS_CMD_PREPENDQ = '\x1a', + YRMCDS_CMD_TOUCH = '\x1c', + YRMCDS_CMD_GAT = '\x1d', + YRMCDS_CMD_GATQ = '\x1e', + YRMCDS_CMD_GATK = '\x23', + YRMCDS_CMD_GATKQ = '\x24', + + YRMCDS_CMD_LOCK = '\x40', + YRMCDS_CMD_LOCKQ = '\x41', + YRMCDS_CMD_UNLOCK = '\x42', + YRMCDS_CMD_UNLOCKQ = '\x43', + YRMCDS_CMD_UNLOCKALL = '\x44', + YRMCDS_CMD_UNLOCKALLQ = '\x45', + YRMCDS_CMD_LAG = '\x46', + YRMCDS_CMD_LAGQ = '\x47', + YRMCDS_CMD_LAGK = '\x48', + YRMCDS_CMD_LAGKQ = '\x49', + YRMCDS_CMD_RAU = '\x4a', + YRMCDS_CMD_RAUQ = '\x4b', + + YRMCDS_CMD_KEYS = '\x50', + + YRMCDS_CMD_BOTTOM // place this at the bottom. +} yrmcds_command; + + +/** + * Data structure to store a response packet. + */ +typedef struct { + uint32_t serial; ///< serial number of the corresponding request. + size_t length; ///< the length of the response packet. + yrmcds_status status; ///< the response status. + yrmcds_command command; ///< the request command. + uint64_t cas_unique; ///< CAS unique value. + uint32_t flags; ///< The object's flags. + const char* key; ///< Returned key for GetK/GaTK/LaGK. + size_t key_len; ///< The length of \p key. + const char* data; ///< Returned data for Get commands. + size_t data_len; ///< The length of \p data. + uint64_t value; ///< The new value after Increment or Decrement. +} yrmcds_response; + + +/** + * Library error numbers. + */ +typedef enum { + YRMCDS_OK = 0, + YRMCDS_SYSTEM_ERROR, ///< check \p errno for details. + YRMCDS_BAD_ARGUMENT, ///< bad arguments. + YRMCDS_NOT_RESOLVED, ///< host name cannot be resolved. + YRMCDS_TIMEOUT, ///< time out for some network operations. + YRMCDS_DISCONNECTED, ///< connection was reset unexpectedly. + YRMCDS_OUT_OF_MEMORY, ///< malloc/realloc failed. + YRMCDS_COMPRESS_FAILED, ///< LZ4 compression failed. + YRMCDS_PROTOCOL_ERROR, ///< received malformed packet. + YRMCDS_NOT_IMPLEMENTED, ///< the function is not available. + YRMCDS_IN_BINARY, ///< connection is fixed for binary protocol. + YRMCDS_BAD_KEY, ///< bad key. +} yrmcds_error; + + +/** + * Reserved flag bits. + */ +typedef enum { + YRMCDS_FLAG_COMPRESS = 1 << 30, ///< transparent LZ4 compression. +} yrmcds_flags; + + +/** + * @defgroup yrmcds_functions Public functions + * @{ + */ + +/** + * Return a string to describe a library error. + * @param e An error number returned from a library function. + * @return A pointer to a constant string. + */ +const char* yrmcds_strerror(yrmcds_error e); + + +/** + * Connecct to a memcached/yrmcds server. + * @param c A pointer to ::yrmcds. + * @param node The server name. + * @param port TCP port number of the server (normally 11211). + * @return 0 if connected successfully. Other values indicate an error. + * + * This function connects to a memcached/yrmcds server and initializes + * \p c. TCP_NODELAY flag will be set for the returned socket. + */ +yrmcds_error yrmcds_connect(yrmcds* c, const char* node, uint16_t port); + + +/** + * Close the connection. + * @param c A pointer to ::yrmcds. + * @return 0 if \p c is valid. Other values indicate an error. + * + * This function closes the connection and frees buffers in \p c. + */ +yrmcds_error yrmcds_close(yrmcds* c); + + +/** + * Shutdown the receiving end of the socket. + * @param c A pointer to ::yrmcds. + * @return 0 if \p c is valid. Other values indicate an error. + * + * This function simply calls \p shutdown system call with \p SHUT_RD . + * This can be used to interrupt a thread waiting in ::yrmcds_recv. + * + * Note that interrupted ::yrmcds_recv will return ::YRMCDS_DISCONNECTED. + * + * \see https://github.com/cybozu/libyrmcds/issues/8 + */ +yrmcds_error yrmcds_shutdown(yrmcds* c); + + +/** + * Turn on text protocol mode. + * @param c A pointer to ::yrmcds. + * @return 0 if succeeded. Other values indicate an error. + * + * This function puts the connection into text protocol mode. + * \p c should be a newly connected object; if any (binary) request + * has been sent, this function will return an error. + * + * Text protocol mode has overheads and limitations; most notably, + * \p quiet option for command sending functions cannot be enabled. + */ +yrmcds_error yrmcds_text_mode(yrmcds* c); + + +/** + * Enable/disable (de)compression for large objects. + * @param c A pointer to ::yrmcds. + * @param threshold The threshold for compression. + * @return 0 if arguments are valid. Other values indicate an error. + * + * This function enables transparent compression using LZ4 if \p threshold + * is greater than 0. If \p threshold is 0, then compression is disabled. + * + * The compression is disabled by default. + * + * If the library is built without LZ4, this function always return + * ::YRMCDS_NOT_IMPLEMENTED. + * + * Note that ::YRMCDS_FLAG_COMPRESS bit in the flags of compressed objects + * will be used by the library iff the compression is enabled. + */ +yrmcds_error yrmcds_set_compression(yrmcds* c, size_t threshold); + + +/** + * Return the underlying socket in ::yrmcds. + * @param c A pointer to ::yrmcds. + * @return A UNIX file descriptor of a socket. + */ +int yrmcds_fileno(yrmcds* c); + + +/** + * Set timeout seconds for send/recv operations. + * @param c A pointer to ::yrmcds. + * @param timeout Seconds before network operations time out. + * @return 0 if arguments are valid. Other values indicate an error. + */ +yrmcds_error yrmcds_set_timeout(yrmcds* c, int timeout); + + +/** + * Receives a response packet. + * @param c A pointer to ::yrmcds. + * @param r A pointer to ::yrmcds_response. + * @return 0 if succeeded. Other values indicate an error. + * + * This function receives a response packet. If no response is available, + * the function will be blocked. For each \p c, only one thread can use + * this function, though command sending functions can be used in parallel. + * + * The response data stored in \p r keep valid until the next call of this + * function or until ::yrmcds_close is called. \p r can be reused for the + * next call of ::yrmcds_recv. + * + * This will return ::YRMCDS_DISCONNECTED when the socket is closed or + * ::yrmcds_shutdown is called from another thread. + */ +yrmcds_error yrmcds_recv(yrmcds* c, yrmcds_response* r); + + +/** + * Send Noop command. + * @param c A pointer to ::yrmcds. + * @param serial A pointer to \p uint32_t, or \p NULL. + * @return 0 if succeeded. Other values indicate an error. + * + * This function sends Noop command to the server. + * If \p serial is not \p NULL, the serial number of the request will be + * stored if the command was sent successfully. + */ +yrmcds_error yrmcds_noop(yrmcds* c, uint32_t* serial); + + +/** + * Send Get/GetQ command. + * @param c A pointer to ::yrmcds. + * @param key Key data. + * @param key_len Length of \p key. + * @param quiet 0 to send Get, other values to send GetQ. + * @param serial A pointer to \p uint32_t, or \p NULL. + * @return 0 if succeeded. Other values indicate an error. + * + * This function sends Get/GetQ command to the server. + * If \p serial is not \p NULL, the serial number of the request will be + * stored if the command was sent successfully. + */ +yrmcds_error yrmcds_get(yrmcds* c, const char* key, size_t key_len, + int quiet, uint32_t* serial); + + +/** + * Send GetK/GetKQ command. + * @param c A pointer to ::yrmcds. + * @param key Key data. + * @param key_len Length of \p key. + * @param quiet 0 to send GetK, other values to send GetKQ. + * @param serial A pointer to \p uint32_t, or \p NULL. + * @return 0 if succeeded. Other values indicate an error. + * + * This function sends GetK/GetKQ command to the server. + * Unlike yrmcds_get(), the response to this request brings the key. + * + * If \p serial is not \p NULL, the serial number of the request will be + * stored if the command was sent successfully. + */ +yrmcds_error yrmcds_getk(yrmcds* c, const char* key, size_t key_len, + int quiet, uint32_t* serial); + + +/** + * Send GaT/GaTQ command. + * @param c A pointer to ::yrmcds. + * @param key Key data. + * @param key_len Length of \p key. + * @param expire Expiration time. 0 disables expiration. + * @param quiet 0 to send GaT, other values to send GaTQ. + * @param serial A pointer to \p uint32_t, or \p NULL. + * @return 0 if succeeded. Other values indicate an error. + * + * This function sends GaT/GaTQ (get and touch) command to the server. + * If \p serial is not \p NULL, the serial number of the request will be + * stored if the command was sent successfully. + */ +yrmcds_error yrmcds_get_touch(yrmcds* c, const char* key, size_t key_len, + uint32_t expire, int quiet, uint32_t* serial); + + +/** + * Send GaTK/GaTKQ command. + * @param c A pointer to ::yrmcds. + * @param key Key data. + * @param key_len Length of \p key. + * @param expire Expiration time. 0 disables expiration. + * @param quiet 0 to send GaTK, other values to send GaTKQ. + * @param serial A pointer to \p uint32_t, or \p NULL. + * @return 0 if succeeded. Other values indicate an error. + * + * This function sends GaTK/GaTKQ (get and touch) command to the server. + * Unlike yrmcds_get_touch(), the response to this request brings the key. + * + * If \p serial is not \p NULL, the serial number of the request will be + * stored if the command was sent successfully. + */ +yrmcds_error yrmcds_getk_touch(yrmcds* c, const char* key, size_t key_len, + uint32_t expire, int quiet, uint32_t* serial); + + +/** + * Send LaG/LaGQ command. + * @param c A pointer to ::yrmcds. + * @param key Key data. + * @param key_len Length of \p key. + * @param quiet 0 to send LaG, other values to send LaGQ. + * @param serial A pointer to \p uint32_t, or \p NULL. + * @return 0 if succeeded. Other values indicate an error. + * + * This function sends LaG/LaGQ command to the server. + * If \p serial is not \p NULL, the serial number of the request will be + * stored if the command was sent successfully. + */ +yrmcds_error yrmcds_lock_get(yrmcds* c, const char* key, size_t key_len, + int quiet, uint32_t* serial); + + +/** + * Send LaGK/LaGKQ command. + * @param c A pointer to ::yrmcds. + * @param key Key data. + * @param key_len Length of \p key. + * @param quiet 0 to send LaGK, other values to send LaGKQ. + * @param serial A pointer to \p uint32_t, or \p NULL. + * @return 0 if succeeded. Other values indicate an error. + * + * This function sends LaGK/LaGKQ command to the server. + * Unlike yrmcds_lock_get(), the response to this request brings the key. + * + * If \p serial is not \p NULL, the serial number of the request will be + * stored if the command was sent successfully. + */ +yrmcds_error yrmcds_lock_getk(yrmcds* c, const char* key, size_t key_len, + int quiet, uint32_t* serial); + + +/** + * Send Touch command. + * @param c A pointer to ::yrmcds. + * @param key Key data. + * @param key_len Length of \p key. + * @param expire Expiration time. 0 disables expiration. + * @param quiet Reserved for future enhancement. + * @param serial A pointer to \p uint32_t, or \p NULL. + * @return 0 if succeeded. Other values indicate an error. + * + * This function sends Touch command to the server. + * If \p serial is not \p NULL, the serial number of the request will be + * stored if the command was sent successfully. + */ +yrmcds_error yrmcds_touch(yrmcds* c, const char* key, size_t key_len, + uint32_t expire, int quiet, uint32_t* serial); + + +/** + * Send Set/SetQ command. + * @param c A pointer to ::yrmcds. + * @param key Key data. + * @param key_len Length of \p key. + * @param data Data to be stored. + * @param data_len Length of \p data. + * @param flags Flags stored along with the data. + * @param expire Expiration time. 0 disables expiration. + * @param cas Try compare-and-swap. 0 disables CAS. + * @param quiet 0 to send Set, other values to send SetQ. + * @param serial A pointer to \p uint32_t, or \p NULL. + * @return 0 if succeeded. Other values indicate an error. + * + * This function sends Set/SetQ command to the server. + * If \p serial is not \p NULL, the serial number of the request will be + * stored if the command was sent successfully. + */ +yrmcds_error yrmcds_set(yrmcds* c, const char* key, size_t key_len, + const char* data, size_t data_len, + uint32_t flags, uint32_t expire, uint64_t cas, + int quiet, uint32_t* serial); + + +/** + * Send Replace/ReplaceQ command. + * @param c A pointer to ::yrmcds. + * @param key Key data. + * @param key_len Length of \p key. + * @param data Data to be stored. + * @param data_len Length of \p data. + * @param flags Flags stored along with the data. + * @param expire Expiration time. 0 disables expiration. + * @param cas Try compare-and-swap. 0 disables CAS. + * @param quiet 0 to send Replace, other values to send ReplaceQ. + * @param serial A pointer to \p uint32_t, or \p NULL. + * @return 0 if succeeded. Other values indicate an error. + * + * This function sends Replace/ReplaceQ command to the server. + * If \p serial is not \p NULL, the serial number of the request will be + * stored if the command was sent successfully. + */ +yrmcds_error yrmcds_replace(yrmcds* c, const char* key, size_t key_len, + const char* data, size_t data_len, + uint32_t flags, uint32_t expire, uint64_t cas, + int quiet, uint32_t* serial); + + +/** + * Send Add/AddQ command. + * @param c A pointer to ::yrmcds. + * @param key Key data. + * @param key_len Length of \p key. + * @param data Data to be stored. + * @param data_len Length of \p data. + * @param flags Flags stored along with the data. + * @param expire Expiration time. 0 disables expiration. + * @param cas Try compare-and-swap. 0 disables CAS. + * @param quiet 0 to send Add, other values to send AddQ. + * @param serial A pointer to \p uint32_t, or \p NULL. + * @return 0 if succeeded. Other values indicate an error. + * + * This function sends Add/AddQ command to the server. + * If \p serial is not \p NULL, the serial number of the request will be + * stored if the command was sent successfully. + */ +yrmcds_error yrmcds_add(yrmcds* c, const char* key, size_t key_len, + const char* data, size_t data_len, + uint32_t flags, uint32_t expire, uint64_t cas, + int quiet, uint32_t* serial); + + +/** + * Send RaU/RaUQ command. + * @param c A pointer to ::yrmcds. + * @param key Key data. + * @param key_len Length of \p key. + * @param data Data to be stored. + * @param data_len Length of \p data. + * @param flags Flags stored along with the data. + * @param expire Expiration time. 0 disables expiration. + * @param quiet 0 to send RaU, other values to send RaUQ. + * @param serial A pointer to \p uint32_t, or \p NULL. + * @return 0 if succeeded. Other values indicate an error. + * + * This function sends RaU/RaUQ (replace and unlock) command to the server. + * The command will fail unless the object is locked by the same session. + * + * If \p serial is not \p NULL, the serial number of the request will be + * stored if the command was sent successfully. + */ +yrmcds_error yrmcds_replace_unlock(yrmcds* c, const char* key, size_t key_len, + const char* data, size_t data_len, + uint32_t flags, uint32_t expire, + int quiet, uint32_t* serial); + + +/** + * Send Increment/IncrementQ command. + * @param c A pointer to ::yrmcds. + * @param key Key data. + * @param key_len Length of \p key. + * @param value Amount to add. + * @param quiet 0 to send Increment, other values to send IncrementQ. + * @param serial A pointer to \p uint32_t, or \p NULL. + * @return 0 if succeeded. Other values indicate an error. + * + * This function sends Increment/IncrementQ command to the server. + * If \p key is not found, the command will fail. + * + * If \p serial is not \p NULL, the serial number of the request will be + * stored if the command was sent successfully. + */ +yrmcds_error yrmcds_incr(yrmcds* c, const char* key, size_t key_len, + uint64_t value, int quiet, uint32_t* serial); + + +/** + * Send Increment/IncrementQ command. + * @param c A pointer to ::yrmcds. + * @param key Key data. + * @param key_len Length of \p key. + * @param value Amount to add. + * @param initial Initial value used when \p key does not exist. + * @param expire Expiration time. 0 disables expiration. + * @param quiet 0 to send Increment, other values to send IncrementQ. + * @param serial A pointer to \p uint32_t, or \p NULL. + * @return 0 if succeeded. Other values indicate an error. + * + * This function sends Increment/IncrementQ command to the server. + * Unlike yrmcds_incr(), this function creates a new object with + * \p initial and \p expire when \p key is not found. + * + * If \p serial is not \p NULL, the serial number of the request will be + * stored if the command was sent successfully. + */ +yrmcds_error yrmcds_incr2(yrmcds* c, const char* key, size_t key_len, + uint64_t value, uint64_t initial, uint32_t expire, + int quiet, uint32_t* serial); + + +/** + * Send Decrement/DecrementQ command. + * @param c A pointer to ::yrmcds. + * @param key Key data. + * @param key_len Length of \p key. + * @param value Amount to add. + * @param quiet 0 to send Decrement, other values to send DecrementQ. + * @param serial A pointer to \p uint32_t, or \p NULL. + * @return 0 if succeeded. Other values indicate an error. + * + * This function sends Decrement/DecrementQ command to the server. + * If \p key is not found, the command will fail. + * + * If \p serial is not \p NULL, the serial number of the request will be + * stored if the command was sent successfully. + */ +yrmcds_error yrmcds_decr(yrmcds* c, const char* key, size_t key_len, + uint64_t value, int quiet, uint32_t* serial); + + +/** + * Send Decrement/DecrementQ command. + * @param c A pointer to ::yrmcds. + * @param key Key data. + * @param key_len Length of \p key. + * @param value Amount to add. + * @param initial Initial value used when \p key does not exist. + * @param expire Expiration time. 0 disables expiration. + * @param quiet 0 to send Decrement, other values to send DecrementQ. + * @param serial A pointer to \p uint32_t, or \p NULL. + * @return 0 if succeeded. Other values indicate an error. + * + * This function sends Decrement/DecrementQ command to the server. + * Unlike yrmcds_decr(), this function creates a new object with + * \p initial and \p expire when \p key is not found. + * + * If \p serial is not \p NULL, the serial number of the request will be + * stored if the command was sent successfully. + */ +yrmcds_error yrmcds_decr2(yrmcds* c, const char* key, size_t key_len, + uint64_t value, uint64_t initial, uint32_t expire, + int quiet, uint32_t* serial); + + +/** + * Send Append/AppendQ command. + * @param c A pointer to ::yrmcds. + * @param key Key data. + * @param key_len Length of \p key. + * @param data Data. + * @param data_len Length of \p data. + * @param quiet 0 to send Append, other values to send AppendQ. + * @param serial A pointer to \p uint32_t, or \p NULL. + * @return 0 if succeeded. Other values indicate an error. + * + * This function sends Append/AppendQ command to the server. + * If \p serial is not \p NULL, the serial number of the request will be + * stored if the command was sent successfully. + * + * \b WARNING: if compression is enabled, this may collapse the data! + */ +yrmcds_error yrmcds_append(yrmcds* c, const char* key, size_t key_len, + const char* data, size_t data_len, + int quiet, uint32_t* serial); + + +/** + * Send Prepend/PrependQ command. + * @param c A pointer to ::yrmcds. + * @param key Key data. + * @param key_len Length of \p key. + * @param data Data. + * @param data_len Length of \p data. + * @param quiet 0 to send Prepend, other values to send PrependQ. + * @param serial A pointer to \p uint32_t, or \p NULL. + * @return 0 if succeeded. Other values indicate an error. + * + * This function sends Prepend/PrependQ command to the server. + * If \p serial is not \p NULL, the serial number of the request will be + * stored if the command was sent successfully. + * + * \b WARNING: if compression is enabled, this may collapse the data! + */ +yrmcds_error yrmcds_prepend(yrmcds* c, const char* key, size_t key_len, + const char* data, size_t data_len, + int quiet, uint32_t* serial); + + +/** + * Send Delete/DeleteQ command. + * @param c A pointer to ::yrmcds. + * @param key Key data. + * @param key_len Length of \p key. + * @param quiet 0 to send Delete, other values to send DeleteQ. + * @param serial A pointer to \p uint32_t, or \p NULL. + * @return 0 if succeeded. Other values indicate an error. + * + * This function sends Delete/DeleteQ command to the server. + * If \p serial is not \p NULL, the serial number of the request will be + * stored if the command was sent successfully. + */ +yrmcds_error yrmcds_remove(yrmcds* c, const char* key, size_t key_len, + int quiet, uint32_t* serial); + + +/** + * Send Lock/LockQ command. + * @param c A pointer to ::yrmcds. + * @param key Key data. + * @param key_len Length of \p key. + * @param quiet 0 to send Lock, other values to send LockQ. + * @param serial A pointer to \p uint32_t, or \p NULL. + * @return 0 if succeeded. Other values indicate an error. + * + * This function sends Lock/LockQ command to the server. + * If \p serial is not \p NULL, the serial number of the request will be + * stored if the command was sent successfully. + */ +yrmcds_error yrmcds_lock(yrmcds* c, const char* key, size_t key_len, + int quiet, uint32_t* serial); + + +/** + * Send Unlock/UnlockQ command. + * @param c A pointer to ::yrmcds. + * @param key Key data. + * @param key_len Length of \p key. + * @param quiet 0 to send Unlock, other values to send UnlockQ. + * @param serial A pointer to \p uint32_t, or \p NULL. + * @return 0 if succeeded. Other values indicate an error. + * + * This function sends Unlock/UnlockQ command to the server. + * If \p serial is not \p NULL, the serial number of the request will be + * stored if the command was sent successfully. + */ +yrmcds_error yrmcds_unlock(yrmcds* c, const char* key, size_t key_len, + int quiet, uint32_t* serial); + + +/** + * Send UnlockAll/UnlockAllQ command. + * @param c A pointer to ::yrmcds. + * @param quiet 0 to send UnlockAll, other values to send UnlockAllQ. + * @param serial A pointer to \p uint32_t, or \p NULL. + * @return 0 if succeeded. Other values indicate an error. + * + * This function sends UnlockAll/UnlockAllQ command to the server. + * If \p serial is not \p NULL, the serial number of the request will be + * stored if the command was sent successfully. + */ +yrmcds_error yrmcds_unlockall(yrmcds* c, int quiet, uint32_t* serial); + + +/** + * Send Flush/FlushQ command. + * @param c A pointer to ::yrmcds. + * @param delay delay seconds before flush. + * @param quiet 0 to send Flush, other values to send FlushQ. + * @param serial A pointer to \p uint32_t, or \p NULL. + * @return 0 if succeeded. Other values indicate an error. + * + * This function sends Flush/FlushQ command to the server. + * If \p serial is not \p NULL, the serial number of the request will be + * stored if the command was sent successfully. + */ +yrmcds_error yrmcds_flush(yrmcds* c, uint32_t delay, + int quiet, uint32_t* serial); + +/** + * Send Stat command to obtain general statistics. + * @param c A pointer to ::yrmcds. + * @param serial A pointer to \p uint32_t, or \p NULL. + * @return 0 if succeeded. Other values indicate an error. + */ +yrmcds_error yrmcds_stat_general(yrmcds* c, uint32_t* serial); + + +/** + * Send Stat command to obtain setting statistics. + * @param c A pointer to ::yrmcds. + * @param serial A pointer to \p uint32_t, or \p NULL. + * @return 0 if succeeded. Other values indicate an error. + */ +yrmcds_error yrmcds_stat_settings(yrmcds* c, uint32_t* serial); + + +/** + * Send Stat command to obtain item statistics. + * @param c A pointer to ::yrmcds. + * @param serial A pointer to \p uint32_t, or \p NULL. + * @return 0 if succeeded. Other values indicate an error. + */ +yrmcds_error yrmcds_stat_items(yrmcds* c, uint32_t* serial); + + +/** + * Send Stat command to obtain size statistics. + * @param c A pointer to ::yrmcds. + * @param serial A pointer to \p uint32_t, or \p NULL. + * @return 0 if succeeded. Other values indicate an error. + */ +yrmcds_error yrmcds_stat_sizes(yrmcds* c, uint32_t* serial); + + +/** + * Send Keys command to list all keys matching the given prefix. + * To retrieve all keys, pass \p NULL and 0 as \p prefix and \p prefix_len. + * @param c A pointer to ::yrmcds. + * @param prefix Prefix data. + * @param prefix_len Length of \p prefix. + * @param serial A pointer to \p uint32_t, or \p NULL. + * @return 0 if succeeded. Other values indicate an error. + */ +yrmcds_error yrmcds_keys(yrmcds* c, const char* prefix, size_t prefix_len, + uint32_t* serial); + + +/** + * Send Version command. + * @param c A pointer to ::yrmcds. + * @param serial A pointer to \p uint32_t, or \p NULL. + * @return 0 if succeeded. Other values indicate an error. + */ +yrmcds_error yrmcds_version(yrmcds* c, uint32_t* serial); + + +/** + * Send Quit/QuitQ command. + * @param c A pointer to ::yrmcds. + * @param quiet 0 to send Quit, other values to send QuitQ. + * @param serial A pointer to \p uint32_t, or \p NULL. + * @return 0 if succeeded. Other values indicate an error. + */ +yrmcds_error yrmcds_quit(yrmcds* c, int quiet, uint32_t* serial); + + +/** + * @} + * @mainpage A memcached/yrmcds client library for C. + * + * - \ref yrmcds_functions + * - \ref yrmcds_cnt_functions + */ + +/** + * Data structure to store the reference to a statistic data for the counter extension. + */ +typedef struct { + const char* name; ///< the name of a statistic item + size_t name_length; ///< the length of \p name + const char* value; ///< the ASCII text information + size_t value_length; ///< the length of \p value +} yrmcds_cnt_stat; + +/** + * Data structure to store statistics for the counter extension. + */ +typedef struct { + yrmcds_cnt_stat* records; ///< the array of the statistic information + size_t count; ///< the number of statistics + size_t capacity; ///< the maximum number of records that \p records can hold. +} yrmcds_cnt_statistics; + +/** + * Data structure of a connection to yrmcds counter server. + */ +typedef struct { + pthread_mutex_t lock; ///< guard lock to serialize sends. + yrmcds_cnt_statistics stats; ///< the result of `stats` command. + char* recvbuf; ///< received data buffer. + size_t capacity; ///< buffer capacity. + size_t used; ///< used bytes. + size_t last_size; ///< size of the last response. + int sock; ///< the socket file descriptor. + int invalid; ///< invalid flag. + uint32_t serial; ///< last issued serial number. +} yrmcds_cnt; + +/** + * Server status codes for the counter extension. + */ +typedef enum { + YRMCDS_CNT_STATUS_OK = 0x00, + YRMCDS_CNT_STATUS_NOT_FOUND = 0x01, + YRMCDS_CNT_STATUS_INVALID = 0x04, + YRMCDS_CNT_STATUS_RESOURCE_NOT_AVAILABLE = 0x21, + YRMCDS_CNT_STATUS_NOT_ACQUIRED = 0x22, + YRMCDS_CNT_STATUS_UNKNOWN_COMMAND = 0x81, + YRMCDS_CNT_STATUS_OUT_OF_MEMORY = 0x82, +} yrmcds_cnt_status; + +/** + * Binary commands for the counter extension. + */ +typedef enum { + YRMCDS_CNT_CMD_NOOP = 0x00, + YRMCDS_CNT_CMD_GET = 0x01, + YRMCDS_CNT_CMD_ACQUIRE = 0x02, + YRMCDS_CNT_CMD_RELEASE = 0x03, + YRMCDS_CNT_CMD_STATS = 0x10, + YRMCDS_CNT_CMD_DUMP = 0x11, +} yrmcds_cnt_command; + +/** + * Data structure to store a response packet for the counter extension. + */ +typedef struct { + yrmcds_cnt_statistics* stats; ///< the result of `stats` command. + const char* body; ///< the pointer to the response body. + size_t body_length; ///< the body length of the response packet. + const char* name; ///< the name of the semaphore (only for Dump command). + size_t name_length; ///< the length of \p name (only for Dump command). + uint32_t serial; ///< serial number of the corresponding request. + uint32_t resources; ///< the number of acquired resources. + uint32_t current_consumption; ///< the current consumption of resources. + uint32_t max_consumption; ///< maximum consumption (only for Dump command). + uint8_t status; ///< the response status. + uint8_t command; ///< the request command. +} yrmcds_cnt_response; + +/** + * @defgroup yrmcds_cnt_functions Public functions for the counter extension + * @{ + */ + +/** + * Connecct to a yrmcds server. + * @param c A pointer to ::yrmcds_cnt. + * @param node The server name. + * @param port TCP port number of the server (normally 11215). + * @return 0 if connected successfully. Other values indicate an error. + * + * This function connects to a yrmcds server and initializes + * \p c. TCP_NODELAY flag will be set for the returned socket. + */ +yrmcds_error +yrmcds_cnt_connect(yrmcds_cnt* c, const char* node, uint16_t port); + +/** + * Close the connection. + * @param c A pointer to ::yrmcds_cnt. + * @return 0 if \p c is valid. Other values indicate an error. + * + * This function closes the connection and frees buffers in \p c. + */ +yrmcds_error +yrmcds_cnt_close(yrmcds_cnt* c); + +/** + * Shutdown the receiving end of the socket. + * @param c A pointer to ::yrmcds_cnt. + * @return 0 if \p c is valid. Other values indicate an error. + * + * This function simply calls \p shutdown system call with \p SHUT_RD . + * This can be used to interrupt a thread waiting in ::yrmcds_cnt_recv. + * + * Note that interrupted ::yrmcds_cnt_recv will return ::YRMCDS_DISCONNECTED. + * + * \see https://github.com/cybozu/libyrmcds/issues/8 + */ +yrmcds_error +yrmcds_cnt_shutdown(yrmcds_cnt* c); + +/** + * Return the underlying socket in ::yrmcds_cnt. + * @param c A pointer to ::yrmcds_cnt. + * @return A UNIX file descriptor of a socket. + */ +int +yrmcds_cnt_fileno(yrmcds_cnt* c); + +/** + * Set timeout seconds for send/recv operations. + * @param c A pointer to ::yrmcds_cnt. + * @param timeout Seconds before network operations time out. + * @return 0 if arguments are valid. Other values indicate an error. + */ +yrmcds_error +yrmcds_cnt_set_timeout(yrmcds_cnt* c, int timeout); + +/** + * Receives a response packet. + * @param c A pointer to ::yrmcds_cnt. + * @param r A pointer to ::yrmcds_cnt_response. + * @return 0 if succeeded. Other values indicate an error. + * + * This function receives a response packet. If no response is available, + * the function will be blocked. For each \p c, only one thread can use + * this function, though command sending functions can be used in parallel. + * + * The response data stored in \p r keep valid until the next call of this + * function or until yrmcds_cnt_close() is called. \p r can be reused for the + * next call of yrmcds_cnt_recv(). + */ +yrmcds_error +yrmcds_cnt_recv(yrmcds_cnt* c, yrmcds_cnt_response* r); + +/** + * Send Noop command. + * @param c A pointer to ::yrmcds_cnt. + * @param serial A pointer to \p uint32_t, or \p NULL. + * @return 0 if succeeded. Other values indicate an error. + * + * This function sends Noop command to the server. + * If \p serial is not \p NULL, the serial number of the request will be + * stored if the command was sent successfully. + */ +yrmcds_error +yrmcds_cnt_noop(yrmcds_cnt* c, uint32_t* serial); + +/** + * Send Get command. + * @param c A pointer to ::yrmcds_cnt. + * @param name Name. + * @param name_len Length of \p name. + * @param serial A pointer to \p uint32_t, or \p NULL. + * @return 0 if succeeded. Other values indicate an error. + * + * This function sends Get command to the server. + * If \p serial is not \p NULL, the serial number of the request will be + * stored if the command was sent successfully. + */ +yrmcds_error +yrmcds_cnt_get(yrmcds_cnt* c, + const char* name, size_t name_len, uint32_t* serial); + +/** + * Send Acquire command. + * @param c A pointer to ::yrmcds_cnt. + * @param name Name. + * @param name_len Length of \p name. + * @param resources The number of resources to acquire. + * @param maximum The maximum number of resources. + * @param serial A pointer to \p uint32_t, or \p NULL. + * @return 0 if succeeded. Other values indicate an error. + * + * This function sends Acquire command to the server. + * If \p serial is not \p NULL, the serial number of the request will be + * stored if the command was sent successfully. + */ +yrmcds_error +yrmcds_cnt_acquire(yrmcds_cnt* c, const char* name, size_t name_len, + uint32_t resources, uint32_t maximum, uint32_t* serial); + +/** + * Send Release command. + * @param c A pointer to ::yrmcds_cnt. + * @param name Name. + * @param name_len Length of \p name. + * @param resources The number of resources to release. + * @param serial A pointer to \p uint32_t, or \p NULL. + * @return 0 if succeeded. Other values indicate an error. + * + * This function sends Release command to the server. + * If \p serial is not \p NULL, the serial number of the request will be + * stored if the command was sent successfully. + */ +yrmcds_error +yrmcds_cnt_release(yrmcds_cnt* c, const char* name, size_t name_len, + uint32_t resources, uint32_t* serial); + +/** + * Send Stats command. + * @param c A pointer to ::yrmcds_cnt. + * @param serial A pointer to \p uint32_t, or \p NULL. + * @return 0 if succeeded. Other values indicate an error. + * + * This function sends Stats command to the server. + * If \p serial is not \p NULL, the serial number of the request will be + * stored if the command was sent successfully. + */ +yrmcds_error +yrmcds_cnt_stats(yrmcds_cnt* c, uint32_t* serial); + +/** + * Send Dump command. + * @param c A pointer to ::yrmcds_cnt. + * @param serial A pointer to \p uint32_t, or \p NULL. + * @return 0 if succeeded. Other values indicate an error. + * + * This function sends Dump command to the server. + * If \p serial is not \p NULL, the serial number of the request will be + * stored if the command was sent successfully. + */ +yrmcds_error +yrmcds_cnt_dump(yrmcds_cnt* c, uint32_t* serial); + +/** + * @} + */ + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif // YRMCDS_H_INCLUDED diff --git a/web/server/h2o/libh2o/deps/libyrmcds/yrmcds_portability.h b/web/server/h2o/libh2o/deps/libyrmcds/yrmcds_portability.h new file mode 100644 index 00000000..c9fd4d91 --- /dev/null +++ b/web/server/h2o/libh2o/deps/libyrmcds/yrmcds_portability.h @@ -0,0 +1,50 @@ +/** @file yrmcds_portability.h + * + * Private header file for OS portability. + * + * Some code are copied from a public domain source at: + * https://gist.github.com/yinyin/2027912 + * + * This is public domain, too. + */ + +#pragma once + +#ifndef YRMCDS_PORTABILITY_H_INCLUDED +#define YRMCDS_PORTABILITY_H_INCLUDED + +#if defined(__APPLE__) +# include +# define htobe16(x) OSSwapHostToBigInt16(x) +# define htole16(x) OSSwapHostToLittleInt16(x) +# define be16toh(x) OSSwapBigToHostInt16(x) +# define le16toh(x) OSSwapLittleToHostInt16(x) +# define htobe32(x) OSSwapHostToBigInt32(x) +# define htole32(x) OSSwapHostToLittleInt32(x) +# define be32toh(x) OSSwapBigToHostInt32(x) +# define le32toh(x) OSSwapLittleToHostInt32(x) +# define htobe64(x) OSSwapHostToBigInt64(x) +# define htole64(x) OSSwapHostToLittleInt64(x) +# define be64toh(x) OSSwapBigToHostInt64(x) +# define le64toh(x) OSSwapLittleToHostInt64(x) +#elif defined(__linux__) +# include +#elif defined(sun) // Solaris +# include +# define htobe16(x) BE_16(x) +# define htole16(x) LE_16(x) +# define be16toh(x) BE_IN16(x) +# define le16toh(x) LE_IN16(x) +# define htobe32(x) BE_32(x) +# define htole32(x) LE_32(x) +# define be32toh(x) BE_IN32(x) +# define le32toh(x) LE_IN32(x) +# define htobe64(x) BE_64(x) +# define htole64(x) LE_64(x) +# define be64toh(x) BE_IN64(x) +# define le64toh(x) LE_IN64(x) +#else // *BSD +# include +#endif + +#endif // YRMCDS_PORTABILITY_H_INCLUDED diff --git a/web/server/h2o/libh2o/deps/libyrmcds/yrmcds_text.h b/web/server/h2o/libh2o/deps/libyrmcds/yrmcds_text.h new file mode 100644 index 00000000..d1cb69aa --- /dev/null +++ b/web/server/h2o/libh2o/deps/libyrmcds/yrmcds_text.h @@ -0,0 +1,47 @@ +/** @file yrmcds_text.h + * + * Private header file for text protocol. + */ + +#pragma once + +#ifndef YRMCDS_TEXT_H_INCLUDED +#define YRMCDS_TEXT_H_INCLUDED + +#include "yrmcds.h" + +yrmcds_error yrmcds_text_get(yrmcds* c, const char* key, size_t key_len, + int quiet, uint32_t* serial); +yrmcds_error yrmcds_text_touch(yrmcds* c, const char* key, size_t key_len, + uint32_t expire, int quiet, uint32_t* serial); +yrmcds_error yrmcds_text_set(yrmcds* c, const char* key, size_t key_len, + const char* data, size_t data_len, + uint32_t flags, uint32_t expire, uint64_t cas, + int quiet, uint32_t* serial); +yrmcds_error yrmcds_text_replace(yrmcds* c, const char* key, size_t key_len, + const char* data, size_t data_len, + uint32_t flags, uint32_t expire, uint64_t cas, + int quiet, uint32_t* serial); +yrmcds_error yrmcds_text_add(yrmcds* c, const char* key, size_t key_len, + const char* data, size_t data_len, + uint32_t flags, uint32_t expire, uint64_t cas, + int quiet, uint32_t* serial); +yrmcds_error yrmcds_text_append(yrmcds* c, const char* key, size_t key_len, + const char* data, size_t data_len, + int quiet, uint32_t* serial); +yrmcds_error yrmcds_text_prepend(yrmcds* c, const char* key, size_t key_len, + const char* data, size_t data_len, + int quiet, uint32_t* serial); +yrmcds_error yrmcds_text_incr(yrmcds* c, const char* key, size_t key_len, + uint64_t value, int quiet, uint32_t* serial); +yrmcds_error yrmcds_text_decr(yrmcds* c, const char* key, size_t key_len, + uint64_t value, int quiet, uint32_t* serial); +yrmcds_error yrmcds_text_remove(yrmcds* c, const char* key, size_t key_len, + int quiet, uint32_t* serial); +yrmcds_error yrmcds_text_flush(yrmcds* c, uint32_t delay, + int quiet, uint32_t* serial); +yrmcds_error yrmcds_text_version(yrmcds* c, uint32_t* serial); +yrmcds_error yrmcds_text_quit(yrmcds* c, uint32_t* serial); + + +#endif // YRMCDS_TEXT_H_INCLUDED diff --git a/web/server/h2o/libh2o/deps/mruby-digest/.gitignore b/web/server/h2o/libh2o/deps/mruby-digest/.gitignore new file mode 100644 index 00000000..55ef3162 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby-digest/.gitignore @@ -0,0 +1,5 @@ +gem_* +gem-* +mrb-*.a +src/*.o +/tmp diff --git a/web/server/h2o/libh2o/deps/mruby-digest/.travis.yml b/web/server/h2o/libh2o/deps/mruby-digest/.travis.yml new file mode 100644 index 00000000..ffe22728 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby-digest/.travis.yml @@ -0,0 +1,2 @@ +script: + - "ruby run_test.rb all test" diff --git a/web/server/h2o/libh2o/deps/mruby-digest/Makefile b/web/server/h2o/libh2o/deps/mruby-digest/Makefile new file mode 100644 index 00000000..21f8afe0 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby-digest/Makefile @@ -0,0 +1,14 @@ +GEM := mruby-digest + +include $(MAKEFILE_4_GEM) + +GEM_C_FILES := $(wildcard $(SRC_DIR)/*.c) +GEM_OBJECTS := $(patsubst %.c, %.o, $(GEM_C_FILES)) + +GEM_RB_FILES := $(wildcard $(MRB_DIR)/*.rb) + +gem-all : $(GEM_OBJECTS) gem-c-and-rb-files + +gem-clean : gem-clean-c-and-rb-files + +gem-test : gem-test-c-and-rb-files diff --git a/web/server/h2o/libh2o/deps/mruby-digest/README.md b/web/server/h2o/libh2o/deps/mruby-digest/README.md new file mode 100644 index 00000000..2ae6552c --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby-digest/README.md @@ -0,0 +1,55 @@ +mruby-digest +========= + +This library is a fork of [github.com/iij/mruby-digest](https://github.com/iij/mruby-digest). +Unlike the original, this fork does not have any dependencies; it uses [picohash](https://github.com/kazuho/picohash) - a public domain library for hash calculation. + +## Features + +Message Digest and HMAC classes are available. They are compatible with CRuby's ones. + +- Digest::MD5, Digest::RMD160, Digest::SHA1, Digest::SHA256, Digest::SHA384 and + Digest::SHA512 + - Note: some of them are not available if libcrypto.a does not support them on your system. +- Digest::HMAC + +## Install + - add conf.gem line to `build_config.rb` + +```ruby +MRuby::Build.new do |conf| + + # ... (snip) ... + + conf.gem :git => 'https://github.com/iij/mruby-digest.git' +end +``` + +## Usage +```ruby +Digest::MD5.digest('ruby') +Digest::MD5.hexdigest('ruby') +``` + +## License + +Copyright (c) 2012-2015 Internet Initiative Japan Inc., Kazuho Oku + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the "Software"), +to deal in the Software without restriction, including without limitation +the rights to use, copy, modify, merge, publish, distribute, sublicense, +and/or sell copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. + diff --git a/web/server/h2o/libh2o/deps/mruby-digest/mrbgem.rake b/web/server/h2o/libh2o/deps/mruby-digest/mrbgem.rake new file mode 100644 index 00000000..9324f169 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby-digest/mrbgem.rake @@ -0,0 +1,4 @@ +MRuby::Gem::Specification.new('mruby-digest') do |spec| + spec.license = 'MIT' + spec.authors = 'Internet Initiative Japan Inc.' +end diff --git a/web/server/h2o/libh2o/deps/mruby-digest/mrblib/digest.rb b/web/server/h2o/libh2o/deps/mruby-digest/mrblib/digest.rb new file mode 100644 index 00000000..7779f54b --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby-digest/mrblib/digest.rb @@ -0,0 +1,46 @@ +if Object.const_defined? :Digest +module Digest + class Base + def self.digest(data) + self.new.update(data).digest + end + def self.file(path) + self.new.update(File.open(path).read) + end + def self.hexdigest(data) + self.new.update(data).hexdigest + end + def ==(other) + if other.kind_of? String + self.hexdigest == other + else + self.digest == other.digest + end + end + def file(path) + self.update(File.open(path).read) + end + def hexdigest! + x = self.hexdigest + self.reset + x + end + + alias length digest_length + alias size digest_length + alias to_s hexdigest + alias << update + end + + class HMAC + def self.digest(data, key, digest) + self.new(key, digest).update(data).digest + end + def self.hexdigest(data, key, digest) + self.new(key, digest).update(data).hexdigest + end + + alias << update + end +end +end diff --git a/web/server/h2o/libh2o/deps/mruby-digest/run_test.rb b/web/server/h2o/libh2o/deps/mruby-digest/run_test.rb new file mode 100644 index 00000000..3401ed86 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby-digest/run_test.rb @@ -0,0 +1,28 @@ +#!/usr/bin/env ruby +# +# mrbgems test runner +# + +gemname = File.basename(File.dirname(File.expand_path __FILE__)) + +if __FILE__ == $0 + repository, dir = 'https://github.com/mruby/mruby.git', 'tmp/mruby' + build_args = ARGV + build_args = ['all', 'test'] if build_args.nil? or build_args.empty? + + Dir.mkdir 'tmp' unless File.exist?('tmp') + unless File.exist?(dir) + system "git clone #{repository} #{dir}" + end + + exit system(%Q[cd #{dir}; MRUBY_CONFIG=#{File.expand_path __FILE__} ruby minirake #{build_args.join(' ')}]) +end + +MRuby::Build.new do |conf| + toolchain :gcc + enable_debug + enable_test + conf.gembox 'default' + + conf.gem File.expand_path(File.dirname(__FILE__)) +end diff --git a/web/server/h2o/libh2o/deps/mruby-digest/src/digest.c b/web/server/h2o/libh2o/deps/mruby-digest/src/digest.c new file mode 100644 index 00000000..634376d9 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby-digest/src/digest.c @@ -0,0 +1,1007 @@ +/* +** digest.c - Digest and subclasses +** +** See Copyright Notice in mruby.h +*/ + +#include "mruby.h" + +#define USE_DIGEST_PICOHASH + +#if !defined(USE_DIGEST_PICOHASH) +#elif defined(__APPLE__) +#define USE_DIGEST_OSX_COMMONCRYPTO +#else +#define USE_DIGEST_OPENSSL +#endif + +#if defined(USE_DIGEST_PICOHASH) +#include "picohash.h" +#elif defined(USE_DIGEST_OPENSSL) +#include +#include +#include +#elif defined(USE_DIGEST_OSX_COMMONCRYPTO) +#include +#include +#else +#error "define USE_DIGEST_PICOHASH or USE_DIGEST_OPENSSL or USE_DIGEST_OSX_COMMONCRYPTO" +#endif +#include +#include +#include +#include "mruby/array.h" +#include "mruby/class.h" +#include "mruby/data.h" +#include "mruby/string.h" +#include "mruby/variable.h" + +#define TYPESYM "__type__" + + +/* + * library-independent layer API + */ +enum { + MD_TYPE_MD5, + MD_TYPE_RMD160, + MD_TYPE_SHA1, + MD_TYPE_SHA256, + MD_TYPE_SHA384, + MD_TYPE_SHA512, +}; + +struct mrb_md; +struct mrb_hmac; + +static void lib_init(void); +static int lib_md_block_length(const struct mrb_md *); +static mrb_value lib_md_digest(mrb_state *, const struct mrb_md *); +static mrb_value lib_md_digest_bang(mrb_state *, struct mrb_md *); +static int lib_md_digest_length(const struct mrb_md *); +static void lib_md_free(mrb_state *, void *); +static void lib_md_init(mrb_state *, struct mrb_md *, int); +static void lib_md_init_copy(mrb_state *, struct mrb_md *, struct mrb_md *); +static void lib_md_reset(mrb_state *, struct mrb_md *); +static void lib_md_update(mrb_state *, struct mrb_md *, unsigned char *, mrb_int); + +static mrb_value lib_hmac_digest(mrb_state *, const struct mrb_hmac *); +static int lib_hmac_block_length(const struct mrb_hmac *); +static int lib_hmac_digest_length(const struct mrb_hmac *); +static void lib_hmac_free(mrb_state *, void *); +static void lib_hmac_init(mrb_state *, struct mrb_hmac *, int, const unsigned char *, mrb_int); +static void lib_hmac_update(mrb_state *, struct mrb_hmac *, unsigned char *, mrb_int); + + +#if defined(USE_DIGEST_PICOHASH) + +#define HAVE_MD5 +#define HAVE_SHA1 + +struct mrb_md { + picohash_ctx_t ctx; +}; + +struct mrb_hmac { + picohash_ctx_t ctx; +}; + +static void +lib_md_free(mrb_state *mrb, void *ptr) +{ + struct mrb_md *md = ptr; + if (md != NULL) + mrb_free(mrb, md); +} + +static void +lib_hmac_free(mrb_state *mrb, void *ptr) +{ + struct mrb_hmac *hmac = ptr; + if (hmac != NULL) + mrb_free(mrb, hmac); +} + +static struct mrb_data_type mrb_md_type = { "MD", lib_md_free }; +static struct mrb_data_type mrb_hmac_type = { "HMAC", lib_hmac_free }; + +static void +lib_init(void) +{ +} + +static int +lib_md_block_length(const struct mrb_md *md) +{ + return (int)md->ctx.block_length; +} + +static mrb_value +lib_md_digest(mrb_state *mrb, const struct mrb_md *md) +{ + picohash_ctx_t ctx; + unsigned char mdstr[PICOHASH_MAX_DIGEST_LENGTH]; + + ctx = md->ctx; + picohash_final(&ctx, mdstr); + return mrb_str_new(mrb, (char *)mdstr, ctx.digest_length); +} + +static mrb_value +lib_md_digest_bang(mrb_state *mrb, struct mrb_md *md) +{ + unsigned char mdstr[PICOHASH_MAX_DIGEST_LENGTH]; + + picohash_final(&md->ctx, mdstr); + picohash_reset(&md->ctx); + return mrb_str_new(mrb, (char *)mdstr, md->ctx.digest_length); +} + +static int +lib_md_digest_length(const struct mrb_md *md) +{ + return md->ctx.digest_length; +} + +static void (*md_type_md(int type))(picohash_ctx_t *) +{ + switch (type) { + case MD_TYPE_MD5: return picohash_init_md5; + case MD_TYPE_SHA1: return picohash_init_sha1; + default: return NULL; + } +} + +static void +lib_md_init(mrb_state *mrb, struct mrb_md *md, int type) +{ + void (*ctor)(picohash_ctx_t *) = md_type_md(type); + if (ctor == NULL) + mrb_raise(mrb, E_NOTIMP_ERROR, "not supported"); + ctor(&md->ctx); +} + +static void +lib_md_init_copy(mrb_state *mrb, struct mrb_md *mdnew, struct mrb_md *mdold) +{ + mdnew->ctx = mdold->ctx; + picohash_reset(&mdnew->ctx); +} + +static void +lib_md_reset(mrb_state *mrb, struct mrb_md *md) +{ + picohash_reset(&md->ctx); +} + +static void +lib_md_update(mrb_state *mrb, struct mrb_md *md, unsigned char *str, mrb_int len) +{ +#if MRB_INT_MAX > SIZE_MAX + if (len > SIZE_MAX) + mrb_raise(mrb, E_ARGUMENT_ERROR, "too long string (not supported yet)"); +#endif + picohash_update(&md->ctx, str, len); +} + +static mrb_value +lib_hmac_digest(mrb_state *mrb, const struct mrb_hmac *hmac) +{ + picohash_ctx_t ctx; + unsigned char mdstr[PICOHASH_MAX_DIGEST_LENGTH]; + + ctx = hmac->ctx; + picohash_final(&ctx, mdstr); + return mrb_str_new(mrb, (char *)mdstr, ctx.digest_length); +} + +static int +lib_hmac_block_length(const struct mrb_hmac *hmac) +{ + return hmac->ctx.block_length; +} + +static int +lib_hmac_digest_length(const struct mrb_hmac *hmac) +{ + return hmac->ctx.digest_length; +} + +static void +lib_hmac_init(mrb_state *mrb, struct mrb_hmac *hmac, int type, const unsigned char *key, mrb_int keylen) +{ + void (*ctor)(picohash_ctx_t *) = md_type_md(type); + +#if MRB_INT_MAX > SIZE_MAX + if (keylen > SIZE_MAX) + mrb_raise(mrb, E_ARGUMENT_ERROR, "too long key"); +#endif + if (ctor == NULL) + mrb_raise(mrb, E_NOTIMP_ERROR, "not supported"); + picohash_init_hmac(&hmac->ctx, ctor, key, keylen); +} + +static void +lib_hmac_update(mrb_state *mrb, struct mrb_hmac *hmac, unsigned char *data, mrb_int len) +{ +#if MRB_INT_MAX > SIZE_MAX + if (len > SIZE_MAX) { + mrb_raise(mrb, E_ARGUMENT_ERROR, "too long string (not supported yet)"); + } +#endif + picohash_update(&hmac->ctx, data, len); +} + +#elif defined(USE_DIGEST_OPENSSL) +/* + * OpenSSL Implementation + */ + +#define HAVE_MD5 + +#ifndef OPENSSL_NO_RIPEMD +#define HAVE_RMD160 +#endif + +#define HAVE_SHA1 +#ifdef SHA256_DIGEST_LENGTH +#define HAVE_SHA256 +#endif +#ifdef SHA512_DIGEST_LENGTH +#define HAVE_SHA384 +#define HAVE_SHA512 +#endif + +struct mrb_md { + EVP_MD_CTX *ctx; +}; + +struct mrb_hmac { + HMAC_CTX ctx; + const EVP_MD *md; +}; + +static void +lib_md_free(mrb_state *mrb, void *ptr) +{ + struct mrb_md *md = ptr; + + if (md != NULL) { + if (md->ctx != NULL) { + EVP_MD_CTX_destroy(md->ctx); + } + mrb_free(mrb, md); + } +} + +static void +lib_hmac_free(mrb_state *mrb, void *ptr) +{ + struct mrb_hmac *hmac = ptr; + + if (hmac != NULL) { + HMAC_CTX_cleanup(&hmac->ctx); + mrb_free(mrb, hmac); + } +} + +static struct mrb_data_type mrb_md_type = { "MD", lib_md_free }; +static struct mrb_data_type mrb_hmac_type = { "HMAC", lib_hmac_free }; + +static void +lib_init(void) +{ + OpenSSL_add_all_digests(); +} + +static int +lib_md_block_length(const struct mrb_md *md) +{ + return EVP_MD_CTX_block_size(md->ctx); +} + +static mrb_value +lib_md_digest(mrb_state *mrb, const struct mrb_md *md) +{ + EVP_MD_CTX ctx; + unsigned int mdlen; + unsigned char mdstr[EVP_MAX_MD_SIZE]; + + EVP_MD_CTX_copy(&ctx, md->ctx); + EVP_DigestFinal(&ctx, mdstr, &mdlen); + return mrb_str_new(mrb, (char *)mdstr, mdlen); +} + +static mrb_value +lib_md_digest_bang(mrb_state *mrb, struct mrb_md *md) +{ + unsigned int mdlen; + unsigned char mdstr[EVP_MAX_MD_SIZE]; + + EVP_DigestFinal_ex(md->ctx, mdstr, &mdlen); + EVP_DigestInit_ex(md->ctx, EVP_MD_CTX_md(md->ctx), NULL); + return mrb_str_new(mrb, (char *)mdstr, mdlen); +} + +static int +lib_md_digest_length(const struct mrb_md *md) +{ + return EVP_MD_CTX_size(md->ctx); +} + +const EVP_MD * +md_type_md(int type) +{ + switch (type) { + case MD_TYPE_MD5: return EVP_md5(); +#ifdef HAVE_RMD160 + case MD_TYPE_RMD160: return EVP_ripemd160(); +#endif + case MD_TYPE_SHA1: return EVP_sha1(); +#ifdef HAVE_SHA256 + case MD_TYPE_SHA256: return EVP_sha256(); +#endif +#ifdef HAVE_SHA512 + case MD_TYPE_SHA384: return EVP_sha384(); + case MD_TYPE_SHA512: return EVP_sha512(); +#endif + default: return NULL; + } +} + +static void +lib_md_init(mrb_state *mrb, struct mrb_md *md, int type) +{ + const EVP_MD *evpmd; + + md->ctx = NULL; + evpmd = md_type_md(type); + if (!evpmd) { + mrb_raise(mrb, E_NOTIMP_ERROR, "not supported"); + } + md->ctx = EVP_MD_CTX_create(); + EVP_DigestInit_ex(md->ctx, evpmd, NULL); +} + +static void +lib_md_init_copy(mrb_state *mrb, struct mrb_md *mdnew, struct mrb_md *mdold) +{ + mdnew->ctx = EVP_MD_CTX_create(); + EVP_DigestInit_ex(mdnew->ctx, EVP_MD_CTX_md(mdold->ctx), NULL); +} + +static void +lib_md_reset(mrb_state *mrb, struct mrb_md *md) +{ + //EVP_MD_CTX_init(&md->ctx); + EVP_DigestInit_ex(md->ctx, EVP_MD_CTX_md(md->ctx), NULL); +} + +static void +lib_md_update(mrb_state *mrb, struct mrb_md *md, unsigned char *str, mrb_int len) +{ +#if MRB_INT_MAX > SIZE_MAX + if (len > SIZE_MAX) { + mrb_raise(mrb, E_ARGUMENT_ERROR, "too long string (not supported yet)"); + } +#endif + EVP_DigestUpdate(md->ctx, str, len); +} + +static mrb_value +lib_hmac_digest(mrb_state *mrb, const struct mrb_hmac *hmac) +{ + HMAC_CTX ctx; + unsigned int mdlen; + unsigned char mdstr[EVP_MAX_MD_SIZE]; + + memcpy(&ctx, &hmac->ctx, sizeof(ctx)); + HMAC_Final(&ctx, mdstr, &mdlen); + return mrb_str_new(mrb, (char *)mdstr, mdlen); +} + +static int +lib_hmac_block_length(const struct mrb_hmac *hmac) +{ + return EVP_MD_block_size(hmac->md); +} + +static int +lib_hmac_digest_length(const struct mrb_hmac *hmac) +{ + return EVP_MD_size(hmac->md); +} + +static void +lib_hmac_init(mrb_state *mrb, struct mrb_hmac *hmac, int type, const unsigned char *key, mrb_int keylen) +{ +#if MRB_INT_MAX > INT_MAX + if (keylen > INT_MAX) { + mrb_raise(mrb, E_ARGUMENT_ERROR, "too long key"); + } +#endif + hmac->md = md_type_md(type); + HMAC_CTX_init(&hmac->ctx); + HMAC_Init_ex(&hmac->ctx, key, keylen, hmac->md, NULL); +} + +static void +lib_hmac_update(mrb_state *mrb, struct mrb_hmac *hmac, unsigned char *data, mrb_int len) +{ +#if MRB_INT_MAX > INT_MAX + if (len > INT_MAX) { + mrb_raise(mrb, E_ARGUMENT_ERROR, "too long string (not supported yet)"); + } +#endif + HMAC_Update(&hmac->ctx, data, len); +} + +#elif defined(USE_DIGEST_OSX_COMMONCRYPTO) +/* + * Mac OS X CommonCrypto Implementation + */ + +#define HAVE_MD5 +/* #define HAVE_RMD160 */ +#define HAVE_SHA1 +#define HAVE_SHA256 +#define HAVE_SHA384 +#define HAVE_SHA512 + +struct mrb_md { + int type; + void *ctx; + int ctx_size; +}; + +struct mrb_hmac { + int type; + CCHmacContext ctx; +}; + +static int +md_ctx_size(int type) +{ + switch (type) { + case MD_TYPE_MD5: return sizeof(CC_MD5_CTX); + case MD_TYPE_SHA1: return sizeof(CC_SHA1_CTX); + case MD_TYPE_SHA256: return sizeof(CC_SHA256_CTX); + case MD_TYPE_SHA384: return sizeof(CC_SHA512_CTX); /* ! */ + case MD_TYPE_SHA512: return sizeof(CC_SHA512_CTX); + default: return 0; + } +} + +static void +lib_md_free(mrb_state *mrb, void *ptr) +{ + struct mrb_md *md = ptr; + + memset(md->ctx, 0, md_ctx_size(md->type)); + mrb_free(mrb, md->ctx); + mrb_free(mrb, md); +} + +static void +lib_hmac_free(mrb_state *mrb, void *ptr) +{ + struct mrb_hmac *hmac = ptr; + + memset(&hmac->ctx, 0, sizeof(hmac->ctx)); + mrb_free(mrb, hmac); +} + +static struct mrb_data_type mrb_md_type = { "MD", lib_md_free }; +static struct mrb_data_type mrb_hmac_type = { "HMAC", lib_hmac_free }; + +#define MAX_DIGEST_LENGTH CC_SHA512_DIGEST_LENGTH + +union ctx_union { + CC_MD5_CTX md5; + CC_SHA1_CTX sha1; + CC_SHA256_CTX sha256; + /* we don't have CC_SHA384_CTX! */ + CC_SHA512_CTX sha512; +}; + +static void +lib_init(void) +{ +} + +static int +md_block_length(int type) +{ + switch (type) { + case MD_TYPE_MD5: return CC_MD5_BLOCK_BYTES; + case MD_TYPE_SHA1: return CC_SHA1_BLOCK_BYTES; + case MD_TYPE_SHA256: return CC_SHA256_BLOCK_BYTES; + case MD_TYPE_SHA384: return CC_SHA384_BLOCK_BYTES; + case MD_TYPE_SHA512: return CC_SHA512_BLOCK_BYTES; + default: return 0; + } +} + +static int +lib_md_block_length(const struct mrb_md *md) +{ + return md_block_length(md->type); +} + +static void +md_init(int type, void *ctxp) +{ + switch (type) { + case MD_TYPE_MD5: CC_MD5_Init(ctxp); break; + case MD_TYPE_SHA1: CC_SHA1_Init(ctxp); break; + case MD_TYPE_SHA256: CC_SHA256_Init(ctxp); break; + case MD_TYPE_SHA384: CC_SHA384_Init(ctxp); break; + case MD_TYPE_SHA512: CC_SHA512_Init(ctxp); break; + default: break; + } +} + +static void +md_final(int type, unsigned char *str, void *ctx) +{ + switch (type) { + case MD_TYPE_MD5: CC_MD5_Final(str, ctx); break; + case MD_TYPE_SHA1: CC_SHA1_Final(str, ctx); break; + case MD_TYPE_SHA256: CC_SHA256_Final(str, ctx); break; + case MD_TYPE_SHA384: CC_SHA384_Final(str, ctx); break; + case MD_TYPE_SHA512: CC_SHA512_Final(str, ctx); break; + default: break; + } +} + +static int +md_digest_length(int type) +{ + switch (type) { + case MD_TYPE_MD5: return 16; + case MD_TYPE_SHA1: return 20; + case MD_TYPE_SHA256: return 32; + case MD_TYPE_SHA384: return 48; + case MD_TYPE_SHA512: return 64; + default: return 0; + } +} + +static mrb_value +lib_md_digest(mrb_state *mrb, const struct mrb_md *md) +{ + union ctx_union ctx; + unsigned char mdstr[MAX_DIGEST_LENGTH]; + + memcpy(&ctx, md->ctx, md_ctx_size(md->type)); + md_final(md->type, mdstr, &ctx); + return mrb_str_new(mrb, (char *)mdstr, md_digest_length(md->type)); +} + +static mrb_value +lib_md_digest_bang(mrb_state *mrb, struct mrb_md *md) +{ + unsigned char mdstr[MAX_DIGEST_LENGTH]; + + md_final(md->type, mdstr, md->ctx); + md_init(md->type, md->ctx); + return mrb_str_new(mrb, (char *)mdstr, md_digest_length(md->type)); +} + +static int +lib_md_digest_length(const struct mrb_md *md) +{ + return md_digest_length(md->type); +} + +static void +lib_md_init(mrb_state *mrb, struct mrb_md *md, int type) +{ + int ctxsize; + + ctxsize = md_ctx_size(type); + if (ctxsize == 0) { + mrb_raise(mrb, E_NOTIMP_ERROR, "not supported"); + } + md->type = type; + md->ctx = NULL; + md->ctx = mrb_malloc(mrb, ctxsize); + md_init(type, md->ctx); +} + +static void +lib_md_init_copy(mrb_state *mrb, struct mrb_md *mdnew, struct mrb_md *mdold) +{ + lib_md_init(mrb, mdnew, mdold->type); +} + +static void +lib_md_reset(mrb_state *mrb, struct mrb_md *md) +{ + md_init(md->type, md->ctx); +} + +static void +lib_md_update(mrb_state *mrb, struct mrb_md *md, unsigned char *data, mrb_int len) +{ + if (sizeof(len) > sizeof(CC_LONG)) { + if (len != (CC_LONG)len) { + mrb_raise(mrb, E_ARGUMENT_ERROR, "too long string (not supported yet)"); + } + } + switch (md->type) { + case MD_TYPE_MD5: CC_MD5_Update(md->ctx, data, len); break; + case MD_TYPE_SHA1: CC_SHA1_Update(md->ctx, data, len); break; + case MD_TYPE_SHA256: CC_SHA256_Update(md->ctx, data, len); break; + case MD_TYPE_SHA384: CC_SHA384_Update(md->ctx, data, len); break; + case MD_TYPE_SHA512: CC_SHA512_Update(md->ctx, data, len); break; + default: break; + } +} + +static int +lib_hmac_block_length(const struct mrb_hmac *hmac) +{ + return md_block_length(hmac->type); +} + +static mrb_value +lib_hmac_digest(mrb_state *mrb, const struct mrb_hmac *hmac) +{ + CCHmacContext ctx; + unsigned char str[MAX_DIGEST_LENGTH]; + + memcpy(&ctx, &hmac->ctx, sizeof(ctx)); + CCHmacFinal(&ctx, str); + return mrb_str_new(mrb, (const char *)str, md_digest_length(hmac->type)); +} + +static int +lib_hmac_digest_length(const struct mrb_hmac *hmac) +{ + return md_digest_length(hmac->type); +} + +static void +lib_hmac_init(mrb_state *mrb, struct mrb_hmac *hmac, int type, const unsigned char *key, mrb_int keylen) +{ + CCHmacAlgorithm algorithm; + +#if MRB_INT_MAX > SIZE_MAX + if (len > SIZE_MAX) { + mrb_raise(mrb, E_ARGUMENT_ERROR, "too long key"); + } +#endif + switch (type) { + case MD_TYPE_MD5: algorithm = kCCHmacAlgMD5; break; + case MD_TYPE_SHA1: algorithm = kCCHmacAlgSHA1; break; + case MD_TYPE_SHA256: algorithm = kCCHmacAlgSHA256; break; + case MD_TYPE_SHA384: algorithm = kCCHmacAlgSHA384; break; + case MD_TYPE_SHA512: algorithm = kCCHmacAlgSHA512; break; + default: + mrb_raisef(mrb, E_RUNTIME_ERROR, "mruby-digest: internal error: unexpected HMAC type: %S", mrb_fixnum_value(type)); + algorithm = 0; + break; + } + hmac->type = type; + CCHmacInit(&hmac->ctx, algorithm, key, keylen); +} + +static void +lib_hmac_update(mrb_state *mrb, struct mrb_hmac *hmac, unsigned char *data, mrb_int len) +{ +#if MRB_INT_MAX > SIZE_MAX + if (len > SIZE_MAX) { + mrb_raise(mrb, E_ARGUMENT_ERROR, "too long string"); + } +#endif + CCHmacUpdate(&hmac->ctx, data, len); +} + +#endif + +static void +basecheck(mrb_state *mrb, mrb_value self, struct mrb_md **mdp) +{ + struct RClass *c; + struct mrb_md *md; + mrb_value t; + + c = mrb_obj_class(mrb, self); + t = mrb_const_get(mrb, mrb_obj_value(c), mrb_intern_lit(mrb, TYPESYM)); + if (mrb_nil_p(t)) { + mrb_raise(mrb, E_NOTIMP_ERROR, "Digest::Base is an abstract class"); + } + md = (struct mrb_md *)DATA_PTR(self); + if (!md) { + mrb_raise(mrb, E_RUNTIME_ERROR, "no md found (BUG?)"); + } + if (mdp) *mdp = md; +} + +static mrb_value +mrb_digest_block_length(mrb_state *mrb, mrb_value self) +{ + struct mrb_md *md; + + basecheck(mrb, self, &md); + return mrb_fixnum_value(lib_md_block_length(md)); +} + +static mrb_value +mrb_digest_digest(mrb_state *mrb, mrb_value self) +{ + struct mrb_md *md; + + md = (struct mrb_md *)DATA_PTR(self); + if (!md) return mrb_nil_value(); + return lib_md_digest(mrb, md); +} + +static mrb_value +mrb_digest_digest_bang(mrb_state *mrb, mrb_value self) +{ + struct mrb_md *md; + + md = (struct mrb_md *)DATA_PTR(self); + if (!md) return mrb_nil_value(); + return lib_md_digest_bang(mrb, md); +} + +static mrb_value +mrb_digest_digest_length(mrb_state *mrb, mrb_value self) +{ + struct mrb_md *md; + + basecheck(mrb, self, &md); + return mrb_fixnum_value(lib_md_digest_length(md)); +} + +static mrb_value +digest2hexdigest(mrb_state *mrb, mrb_value b) +{ + mrb_value h; + int i, len; + char *bp, buf[3]; + + bp = RSTRING_PTR(b); + len = RSTRING_LEN(b); + h = mrb_str_buf_new(mrb, len * 2); + for (i = 0; i < len; i++) { + snprintf(buf, sizeof(buf), "%02x", (unsigned char )bp[i]); + mrb_str_buf_cat(mrb, h, buf, 2); + } + return h; +} + +static mrb_value +mrb_digest_hexdigest(mrb_state *mrb, mrb_value self) +{ + return digest2hexdigest(mrb, mrb_digest_digest(mrb, self)); +} + +static mrb_value +mrb_digest_init(mrb_state *mrb, mrb_value self) +{ + struct RClass *c; + struct mrb_md *md; + mrb_value t; + + md = (struct mrb_md *)DATA_PTR(self); + if (md) { + lib_md_free(mrb, md); + } + DATA_TYPE(self) = &mrb_md_type; + DATA_PTR(self) = NULL; + + c = mrb_obj_class(mrb, self); + if (!mrb_const_defined(mrb, mrb_obj_value(c), mrb_intern_lit(mrb, TYPESYM))) { + mrb_raise(mrb, E_NOTIMP_ERROR, "Digest::Base is an abstract class"); + } + t = mrb_const_get(mrb, mrb_obj_value(c), mrb_intern_lit(mrb, TYPESYM)); +#if 0 + if (lib_md_supported(t)) { + mrb_raise(mrb, E_NOTIMP_ERROR, "unknown algorithm"); + } +#endif + + md = (struct mrb_md *)mrb_malloc(mrb, sizeof(*md)); + DATA_PTR(self) = md; + lib_md_init(mrb, md, mrb_fixnum(t)); + return self; +} + +static mrb_value +mrb_digest_init_copy(mrb_state *mrb, mrb_value copy) +{ + struct mrb_md *m1, *m2; + mrb_value src; + + mrb_get_args(mrb, "o", &src); + if (mrb_obj_equal(mrb, copy, src)) return copy; + if (!mrb_obj_is_instance_of(mrb, src, mrb_obj_class(mrb, copy))) { + mrb_raise(mrb, E_TYPE_ERROR, "wrong argument class"); + } + if (!DATA_PTR(copy)) { + DATA_PTR(copy) = mrb_malloc(mrb, sizeof(struct mrb_md)); + DATA_TYPE(copy) = &mrb_md_type; + } + m1 = DATA_PTR(src); + m2 = DATA_PTR(copy); + lib_md_init_copy(mrb, m2, m1); + return copy; +} + +static mrb_value +mrb_digest_reset(mrb_state *mrb, mrb_value self) +{ + struct mrb_md *md; + + md = (struct mrb_md *)DATA_PTR(self); + if (!md) return mrb_nil_value(); + lib_md_reset(mrb, md); + return self; +} + +static mrb_value +mrb_digest_update(mrb_state *mrb, mrb_value self) +{ + struct mrb_md *md; + mrb_int len; + char *str; + + md = (struct mrb_md *)DATA_PTR(self); + if (!md) return mrb_nil_value(); + mrb_get_args(mrb, "s", &str, &len); + lib_md_update(mrb, md, (unsigned char *)str, len); + return self; +} + +static mrb_value +mrb_hmac_block_length(mrb_state *mrb, mrb_value self) +{ + struct mrb_hmac *hmac; + + hmac = (struct mrb_hmac *)DATA_PTR(self); + if (!hmac) return mrb_nil_value(); + return mrb_fixnum_value(lib_hmac_block_length(hmac)); +} + +static mrb_value +mrb_hmac_digest(mrb_state *mrb, mrb_value self) +{ + struct mrb_hmac *hmac; + + hmac = (struct mrb_hmac *)DATA_PTR(self); + if (!hmac) return mrb_nil_value(); + return lib_hmac_digest(mrb, hmac); +} + +static mrb_value +mrb_hmac_digest_length(mrb_state *mrb, mrb_value self) +{ + struct mrb_hmac *hmac; + + hmac = (struct mrb_hmac *)DATA_PTR(self); + if (!hmac) return mrb_nil_value(); + return mrb_fixnum_value(lib_hmac_digest_length(hmac)); +} + +static mrb_value +mrb_hmac_hexdigest(mrb_state *mrb, mrb_value self) +{ + return digest2hexdigest(mrb, mrb_hmac_digest(mrb, self)); +} + +static mrb_value +mrb_hmac_init(mrb_state *mrb, mrb_value self) +{ + struct mrb_hmac *hmac; + mrb_value digest, t; + mrb_int keylen; + char *key; + + hmac = (struct mrb_hmac *)DATA_PTR(self); + if (hmac) { + lib_hmac_free(mrb, hmac); + } + DATA_TYPE(self) = &mrb_hmac_type; + DATA_PTR(self) = NULL; + + mrb_get_args(mrb, "so", &key, &keylen, &digest); + t = mrb_const_get(mrb, digest, mrb_intern_lit(mrb, TYPESYM)); + if (mrb_nil_p(t)) { + mrb_raise(mrb, E_RUNTIME_ERROR, "not a digester"); + } + + hmac = (struct mrb_hmac *)mrb_malloc(mrb, sizeof(*hmac)); + DATA_PTR(self) = hmac; + lib_hmac_init(mrb, hmac, mrb_fixnum(t), (unsigned char *)key, keylen); + return self; +} + +static mrb_value +mrb_hmac_init_copy(mrb_state *mrb, mrb_value copy) +{ + mrb_raise(mrb, E_RUNTIME_ERROR, "cannot duplicate HMAC"); + return copy; +} + +static mrb_value +mrb_hmac_update(mrb_state *mrb, mrb_value self) +{ + struct mrb_hmac *hmac; + mrb_int len; + char *str; + + hmac = (struct mrb_hmac *)DATA_PTR(self); + if (!hmac) return mrb_nil_value(); + mrb_get_args(mrb, "s", &str, &len); + lib_hmac_update(mrb, hmac, (unsigned char *)str, len); + return self; +} + + +void +mrb_mruby_digest_gem_init(mrb_state *mrb) +{ + struct RClass *b, *d, *h; + + lib_init(); + + d = mrb_define_module(mrb, "Digest"); + + b = mrb_define_class_under(mrb, d, "Base", mrb->object_class); + mrb_define_method(mrb, b, "block_length", mrb_digest_block_length, MRB_ARGS_NONE()); + mrb_define_method(mrb, b, "digest", mrb_digest_digest, MRB_ARGS_NONE()); + mrb_define_method(mrb, b, "digest!", mrb_digest_digest_bang, MRB_ARGS_NONE()); /* XXX: can be defined in mrblib... */ + mrb_define_method(mrb, b, "digest_length", mrb_digest_digest_length, MRB_ARGS_NONE()); + //mrb_define_method(mrb, b, "file", mrb_digest_file, MRB_ARGS_REQ(1)); + mrb_define_method(mrb, b, "hexdigest", mrb_digest_hexdigest, MRB_ARGS_NONE()); + //mrb_define_method(mrb, b, "hexdigest!", mrb_digest_hexdigest_bang, MRB_ARGS_NONE()); /* XXX: can be defined in mrblib... */ + mrb_define_method(mrb, b, "initialize", mrb_digest_init, MRB_ARGS_NONE()); + mrb_define_method(mrb, b, "initialize_copy", mrb_digest_init_copy, MRB_ARGS_REQ(1)); + mrb_define_method(mrb, b, "reset", mrb_digest_reset, MRB_ARGS_NONE()); + mrb_define_method(mrb, b, "update", mrb_digest_update, MRB_ARGS_REQ(1)); + +#define DEFCLASS(n) \ +do { \ + struct RClass *a = mrb_define_class_under(mrb, d, #n, b); \ + MRB_SET_INSTANCE_TT(a, MRB_TT_DATA); \ + mrb_define_const(mrb, a, TYPESYM, mrb_fixnum_value(MD_TYPE_##n)); \ +} while (0) + +#ifdef HAVE_MD5 + DEFCLASS(MD5); +#endif +#ifdef HAVE_RMD160 + DEFCLASS(RMD160); +#endif +#ifdef HAVE_SHA1 + DEFCLASS(SHA1); +#endif +#ifdef HAVE_SHA256 + DEFCLASS(SHA256); +#endif +#ifdef HAVE_SHA384 + DEFCLASS(SHA384); +#endif +#ifdef HAVE_SHA512 + DEFCLASS(SHA512); +#endif + + h = mrb_define_class_under(mrb, d, "HMAC", mrb->object_class); + MRB_SET_INSTANCE_TT(h, MRB_TT_DATA); + mrb_define_method(mrb, h, "block_length", mrb_hmac_block_length, MRB_ARGS_NONE()); + mrb_define_method(mrb, h, "digest", mrb_hmac_digest, MRB_ARGS_NONE()); + mrb_define_method(mrb, h, "digest_length", mrb_hmac_digest_length, MRB_ARGS_NONE()); + mrb_define_method(mrb, h, "hexdigest", mrb_hmac_hexdigest, MRB_ARGS_NONE()); + mrb_define_method(mrb, h, "initialize", mrb_hmac_init, MRB_ARGS_REQ(2)); + mrb_define_method(mrb, h, "initialize_copy", mrb_hmac_init_copy, MRB_ARGS_REQ(1)); + mrb_define_method(mrb, h, "update", mrb_hmac_update, MRB_ARGS_REQ(1)); +} + +void +mrb_mruby_digest_gem_final(mrb_state *mrb) +{ +} diff --git a/web/server/h2o/libh2o/deps/mruby-digest/src/picohash.h b/web/server/h2o/libh2o/deps/mruby-digest/src/picohash.h new file mode 100644 index 00000000..4c0206d9 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby-digest/src/picohash.h @@ -0,0 +1,751 @@ +/* + * The code is placed under public domain by Kazuho Oku . + * + * The MD5 implementation is based on a public domain implementation written by + * Solar Designer in 2001, which is used by Dovecot. + * + * The SHA1 implementation is based on a public domain implementation written + * by Wei Dai and other contributors for libcrypt, used also in liboauth. + * + * The SHA224/SHA256 implementation is based on a public domain implementation + * by Sam Hocevar for LibTomCrypt. + */ +#ifndef _picohash_h_ +#define _picohash_h_ + +#include +#include +#include + +#ifdef __BIG_ENDIAN__ +#define _PICOHASH_BIG_ENDIAN +#elif defined __LITTLE_ENDIAN__ +/* override */ +#elif defined __BYTE_ORDER +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ +#define _PICOHASH_BIG_ENDIAN +#endif +#else // ! defined __LITTLE_ENDIAN__ +#include // machine/endian.h +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ +#define _PICOHASH_BIG_ENDIAN +#endif +#endif + +#define PICOHASH_MD5_BLOCK_LENGTH 64 +#define PICOHASH_MD5_DIGEST_LENGTH 16 + +typedef struct { + uint_fast32_t lo, hi; + uint_fast32_t a, b, c, d; + unsigned char buffer[64]; + uint_fast32_t block[PICOHASH_MD5_DIGEST_LENGTH]; +} _picohash_md5_ctx_t; + +static void _picohash_md5_init(_picohash_md5_ctx_t *ctx); +static void _picohash_md5_update(_picohash_md5_ctx_t *ctx, const void *data, size_t size); +static void _picohash_md5_final(_picohash_md5_ctx_t *ctx, void *digest); + +#define PICOHASH_SHA1_BLOCK_LENGTH 64 +#define PICOHASH_SHA1_DIGEST_LENGTH 20 + +typedef struct { + uint32_t buffer[PICOHASH_SHA1_BLOCK_LENGTH / 4]; + uint32_t state[PICOHASH_SHA1_DIGEST_LENGTH / 4]; + uint64_t byteCount; + uint8_t bufferOffset; +} _picohash_sha1_ctx_t; + +static void _picohash_sha1_init(_picohash_sha1_ctx_t *ctx); +static void _picohash_sha1_update(_picohash_sha1_ctx_t *ctx, const void *input, size_t len); +static void _picohash_sha1_final(_picohash_sha1_ctx_t *ctx, void *digest); + +#define PICOHASH_SHA256_BLOCK_LENGTH 64 +#define PICOHASH_SHA256_DIGEST_LENGTH 32 +#define PICOHASH_SHA224_BLOCK_LENGTH PICOHASH_SHA256_BLOCK_LENGTH +#define PICOHASH_SHA224_DIGEST_LENGTH 28 + +typedef struct { + uint64_t length; + uint32_t state[PICOHASH_SHA256_DIGEST_LENGTH / 4]; + uint32_t curlen; + unsigned char buf[PICOHASH_SHA256_BLOCK_LENGTH]; +} _picohash_sha256_ctx_t; + +static void _picohash_sha256_init(_picohash_sha256_ctx_t *ctx); +static void _picohash_sha256_update(_picohash_sha256_ctx_t *ctx, const void *data, size_t len); +static void _picohash_sha256_final(_picohash_sha256_ctx_t *ctx, void *digest); +static void _picohash_sha224_init(_picohash_sha256_ctx_t *ctx); +static void _picohash_sha224_final(_picohash_sha256_ctx_t *ctx, void *digest); + +#define PICOHASH_MAX_BLOCK_LENGTH 64 +#define PICOHASH_MAX_DIGEST_LENGTH 32 + +typedef struct { + union { + _picohash_md5_ctx_t _md5; + _picohash_sha1_ctx_t _sha1; + _picohash_sha256_ctx_t _sha256; + }; + size_t block_length; + size_t digest_length; + void (*_reset)(void *ctx); + void (*_update)(void *ctx, const void *input, size_t len); + void (*_final)(void *ctx, void *digest); + struct { + unsigned char key[PICOHASH_MAX_BLOCK_LENGTH]; + void (*hash_reset)(void *ctx); + void (*hash_final)(void *ctx, void *digest); + } _hmac; +} picohash_ctx_t; + +static void picohash_init_md5(picohash_ctx_t *ctx); +static void picohash_init_sha1(picohash_ctx_t *ctx); +static void picohash_init_sha224(picohash_ctx_t *ctx); +static void picohash_init_sha256(picohash_ctx_t *ctx); +static void picohash_update(picohash_ctx_t *ctx, const void *input, size_t len); +static void picohash_final(picohash_ctx_t *ctx, void *digest); +static void picohash_reset(picohash_ctx_t *ctx); + +static void picohash_init_hmac(picohash_ctx_t *ctx, void (*initf)(picohash_ctx_t *), const void *key, size_t key_len); + +/* following are private definitions */ + +/* + * The basic MD5 functions. + * + * F is optimized compared to its RFC 1321 definition just like in Colin + * Plumb's implementation. + */ +#define _PICOHASH_MD5_F(x, y, z) ((z) ^ ((x) & ((y) ^ (z)))) +#define _PICOHASH_MD5_G(x, y, z) ((y) ^ ((z) & ((x) ^ (y)))) +#define _PICOHASH_MD5_H(x, y, z) ((x) ^ (y) ^ (z)) +#define _PICOHASH_MD5_I(x, y, z) ((y) ^ ((x) | ~(z))) + +/* + * The MD5 transformation for all four rounds. + */ +#define _PICOHASH_MD5_STEP(f, a, b, c, d, x, t, s) \ + (a) += f((b), (c), (d)) + (x) + (t); \ + (a) = (((a) << (s)) | (((a)&0xffffffff) >> (32 - (s)))); \ + (a) += (b); + +/* + * SET reads 4 input bytes in little-endian byte order and stores them + * in a properly aligned word in host byte order. + * + * The check for little-endian architectures which tolerate unaligned + * memory accesses is just an optimization. Nothing will break if it + * doesn't work. + */ +#if defined(__i386__) || defined(__x86_64__) || defined(__vax__) +#define _PICOHASH_MD5_SET(n) (*(const uint32_t *)&ptr[(n)*4]) +#define _PICOHASH_MD5_GET(n) _PICOHASH_MD5_SET(n) +#else +#define _PICOHASH_MD5_SET(n) \ + (ctx->block[(n)] = (uint_fast32_t)ptr[(n)*4] | ((uint_fast32_t)ptr[(n)*4 + 1] << 8) | ((uint_fast32_t)ptr[(n)*4 + 2] << 16) | \ + ((uint_fast32_t)ptr[(n)*4 + 3] << 24)) +#define _PICOHASH_MD5_GET(n) (ctx->block[(n)]) +#endif + +/* + * This processes one or more 64-byte data blocks, but does NOT update + * the bit counters. There're no alignment requirements. + */ +static const void *_picohash_md5_body(_picohash_md5_ctx_t *ctx, const void *data, size_t size) +{ + const unsigned char *ptr; + uint_fast32_t a, b, c, d; + uint_fast32_t saved_a, saved_b, saved_c, saved_d; + + ptr = data; + + a = ctx->a; + b = ctx->b; + c = ctx->c; + d = ctx->d; + + do { + saved_a = a; + saved_b = b; + saved_c = c; + saved_d = d; + + /* Round 1 */ + _PICOHASH_MD5_STEP(_PICOHASH_MD5_F, a, b, c, d, _PICOHASH_MD5_SET(0), 0xd76aa478, 7) + _PICOHASH_MD5_STEP(_PICOHASH_MD5_F, d, a, b, c, _PICOHASH_MD5_SET(1), 0xe8c7b756, 12) + _PICOHASH_MD5_STEP(_PICOHASH_MD5_F, c, d, a, b, _PICOHASH_MD5_SET(2), 0x242070db, 17) + _PICOHASH_MD5_STEP(_PICOHASH_MD5_F, b, c, d, a, _PICOHASH_MD5_SET(3), 0xc1bdceee, 22) + _PICOHASH_MD5_STEP(_PICOHASH_MD5_F, a, b, c, d, _PICOHASH_MD5_SET(4), 0xf57c0faf, 7) + _PICOHASH_MD5_STEP(_PICOHASH_MD5_F, d, a, b, c, _PICOHASH_MD5_SET(5), 0x4787c62a, 12) + _PICOHASH_MD5_STEP(_PICOHASH_MD5_F, c, d, a, b, _PICOHASH_MD5_SET(6), 0xa8304613, 17) + _PICOHASH_MD5_STEP(_PICOHASH_MD5_F, b, c, d, a, _PICOHASH_MD5_SET(7), 0xfd469501, 22) + _PICOHASH_MD5_STEP(_PICOHASH_MD5_F, a, b, c, d, _PICOHASH_MD5_SET(8), 0x698098d8, 7) + _PICOHASH_MD5_STEP(_PICOHASH_MD5_F, d, a, b, c, _PICOHASH_MD5_SET(9), 0x8b44f7af, 12) + _PICOHASH_MD5_STEP(_PICOHASH_MD5_F, c, d, a, b, _PICOHASH_MD5_SET(10), 0xffff5bb1, 17) + _PICOHASH_MD5_STEP(_PICOHASH_MD5_F, b, c, d, a, _PICOHASH_MD5_SET(11), 0x895cd7be, 22) + _PICOHASH_MD5_STEP(_PICOHASH_MD5_F, a, b, c, d, _PICOHASH_MD5_SET(12), 0x6b901122, 7) + _PICOHASH_MD5_STEP(_PICOHASH_MD5_F, d, a, b, c, _PICOHASH_MD5_SET(13), 0xfd987193, 12) + _PICOHASH_MD5_STEP(_PICOHASH_MD5_F, c, d, a, b, _PICOHASH_MD5_SET(14), 0xa679438e, 17) + _PICOHASH_MD5_STEP(_PICOHASH_MD5_F, b, c, d, a, _PICOHASH_MD5_SET(15), 0x49b40821, 22) + + /* Round 2 */ + _PICOHASH_MD5_STEP(_PICOHASH_MD5_G, a, b, c, d, _PICOHASH_MD5_GET(1), 0xf61e2562, 5) + _PICOHASH_MD5_STEP(_PICOHASH_MD5_G, d, a, b, c, _PICOHASH_MD5_GET(6), 0xc040b340, 9) + _PICOHASH_MD5_STEP(_PICOHASH_MD5_G, c, d, a, b, _PICOHASH_MD5_GET(11), 0x265e5a51, 14) + _PICOHASH_MD5_STEP(_PICOHASH_MD5_G, b, c, d, a, _PICOHASH_MD5_GET(0), 0xe9b6c7aa, 20) + _PICOHASH_MD5_STEP(_PICOHASH_MD5_G, a, b, c, d, _PICOHASH_MD5_GET(5), 0xd62f105d, 5) + _PICOHASH_MD5_STEP(_PICOHASH_MD5_G, d, a, b, c, _PICOHASH_MD5_GET(10), 0x02441453, 9) + _PICOHASH_MD5_STEP(_PICOHASH_MD5_G, c, d, a, b, _PICOHASH_MD5_GET(15), 0xd8a1e681, 14) + _PICOHASH_MD5_STEP(_PICOHASH_MD5_G, b, c, d, a, _PICOHASH_MD5_GET(4), 0xe7d3fbc8, 20) + _PICOHASH_MD5_STEP(_PICOHASH_MD5_G, a, b, c, d, _PICOHASH_MD5_GET(9), 0x21e1cde6, 5) + _PICOHASH_MD5_STEP(_PICOHASH_MD5_G, d, a, b, c, _PICOHASH_MD5_GET(14), 0xc33707d6, 9) + _PICOHASH_MD5_STEP(_PICOHASH_MD5_G, c, d, a, b, _PICOHASH_MD5_GET(3), 0xf4d50d87, 14) + _PICOHASH_MD5_STEP(_PICOHASH_MD5_G, b, c, d, a, _PICOHASH_MD5_GET(8), 0x455a14ed, 20) + _PICOHASH_MD5_STEP(_PICOHASH_MD5_G, a, b, c, d, _PICOHASH_MD5_GET(13), 0xa9e3e905, 5) + _PICOHASH_MD5_STEP(_PICOHASH_MD5_G, d, a, b, c, _PICOHASH_MD5_GET(2), 0xfcefa3f8, 9) + _PICOHASH_MD5_STEP(_PICOHASH_MD5_G, c, d, a, b, _PICOHASH_MD5_GET(7), 0x676f02d9, 14) + _PICOHASH_MD5_STEP(_PICOHASH_MD5_G, b, c, d, a, _PICOHASH_MD5_GET(12), 0x8d2a4c8a, 20) + + /* Round 3 */ + _PICOHASH_MD5_STEP(_PICOHASH_MD5_H, a, b, c, d, _PICOHASH_MD5_GET(5), 0xfffa3942, 4) + _PICOHASH_MD5_STEP(_PICOHASH_MD5_H, d, a, b, c, _PICOHASH_MD5_GET(8), 0x8771f681, 11) + _PICOHASH_MD5_STEP(_PICOHASH_MD5_H, c, d, a, b, _PICOHASH_MD5_GET(11), 0x6d9d6122, 16) + _PICOHASH_MD5_STEP(_PICOHASH_MD5_H, b, c, d, a, _PICOHASH_MD5_GET(14), 0xfde5380c, 23) + _PICOHASH_MD5_STEP(_PICOHASH_MD5_H, a, b, c, d, _PICOHASH_MD5_GET(1), 0xa4beea44, 4) + _PICOHASH_MD5_STEP(_PICOHASH_MD5_H, d, a, b, c, _PICOHASH_MD5_GET(4), 0x4bdecfa9, 11) + _PICOHASH_MD5_STEP(_PICOHASH_MD5_H, c, d, a, b, _PICOHASH_MD5_GET(7), 0xf6bb4b60, 16) + _PICOHASH_MD5_STEP(_PICOHASH_MD5_H, b, c, d, a, _PICOHASH_MD5_GET(10), 0xbebfbc70, 23) + _PICOHASH_MD5_STEP(_PICOHASH_MD5_H, a, b, c, d, _PICOHASH_MD5_GET(13), 0x289b7ec6, 4) + _PICOHASH_MD5_STEP(_PICOHASH_MD5_H, d, a, b, c, _PICOHASH_MD5_GET(0), 0xeaa127fa, 11) + _PICOHASH_MD5_STEP(_PICOHASH_MD5_H, c, d, a, b, _PICOHASH_MD5_GET(3), 0xd4ef3085, 16) + _PICOHASH_MD5_STEP(_PICOHASH_MD5_H, b, c, d, a, _PICOHASH_MD5_GET(6), 0x04881d05, 23) + _PICOHASH_MD5_STEP(_PICOHASH_MD5_H, a, b, c, d, _PICOHASH_MD5_GET(9), 0xd9d4d039, 4) + _PICOHASH_MD5_STEP(_PICOHASH_MD5_H, d, a, b, c, _PICOHASH_MD5_GET(12), 0xe6db99e5, 11) + _PICOHASH_MD5_STEP(_PICOHASH_MD5_H, c, d, a, b, _PICOHASH_MD5_GET(15), 0x1fa27cf8, 16) + _PICOHASH_MD5_STEP(_PICOHASH_MD5_H, b, c, d, a, _PICOHASH_MD5_GET(2), 0xc4ac5665, 23) + + /* Round 4 */ + _PICOHASH_MD5_STEP(_PICOHASH_MD5_I, a, b, c, d, _PICOHASH_MD5_GET(0), 0xf4292244, 6) + _PICOHASH_MD5_STEP(_PICOHASH_MD5_I, d, a, b, c, _PICOHASH_MD5_GET(7), 0x432aff97, 10) + _PICOHASH_MD5_STEP(_PICOHASH_MD5_I, c, d, a, b, _PICOHASH_MD5_GET(14), 0xab9423a7, 15) + _PICOHASH_MD5_STEP(_PICOHASH_MD5_I, b, c, d, a, _PICOHASH_MD5_GET(5), 0xfc93a039, 21) + _PICOHASH_MD5_STEP(_PICOHASH_MD5_I, a, b, c, d, _PICOHASH_MD5_GET(12), 0x655b59c3, 6) + _PICOHASH_MD5_STEP(_PICOHASH_MD5_I, d, a, b, c, _PICOHASH_MD5_GET(3), 0x8f0ccc92, 10) + _PICOHASH_MD5_STEP(_PICOHASH_MD5_I, c, d, a, b, _PICOHASH_MD5_GET(10), 0xffeff47d, 15) + _PICOHASH_MD5_STEP(_PICOHASH_MD5_I, b, c, d, a, _PICOHASH_MD5_GET(1), 0x85845dd1, 21) + _PICOHASH_MD5_STEP(_PICOHASH_MD5_I, a, b, c, d, _PICOHASH_MD5_GET(8), 0x6fa87e4f, 6) + _PICOHASH_MD5_STEP(_PICOHASH_MD5_I, d, a, b, c, _PICOHASH_MD5_GET(15), 0xfe2ce6e0, 10) + _PICOHASH_MD5_STEP(_PICOHASH_MD5_I, c, d, a, b, _PICOHASH_MD5_GET(6), 0xa3014314, 15) + _PICOHASH_MD5_STEP(_PICOHASH_MD5_I, b, c, d, a, _PICOHASH_MD5_GET(13), 0x4e0811a1, 21) + _PICOHASH_MD5_STEP(_PICOHASH_MD5_I, a, b, c, d, _PICOHASH_MD5_GET(4), 0xf7537e82, 6) + _PICOHASH_MD5_STEP(_PICOHASH_MD5_I, d, a, b, c, _PICOHASH_MD5_GET(11), 0xbd3af235, 10) + _PICOHASH_MD5_STEP(_PICOHASH_MD5_I, c, d, a, b, _PICOHASH_MD5_GET(2), 0x2ad7d2bb, 15) + _PICOHASH_MD5_STEP(_PICOHASH_MD5_I, b, c, d, a, _PICOHASH_MD5_GET(9), 0xeb86d391, 21) + + a += saved_a; + b += saved_b; + c += saved_c; + d += saved_d; + + ptr += 64; + } while (size -= 64); + + ctx->a = a; + ctx->b = b; + ctx->c = c; + ctx->d = d; + + return ptr; +} + +inline void _picohash_md5_init(_picohash_md5_ctx_t *ctx) +{ + ctx->a = 0x67452301; + ctx->b = 0xefcdab89; + ctx->c = 0x98badcfe; + ctx->d = 0x10325476; + + ctx->lo = 0; + ctx->hi = 0; +} + +inline void _picohash_md5_update(_picohash_md5_ctx_t *ctx, const void *data, size_t size) +{ + uint_fast32_t saved_lo; + unsigned long used, free; + + saved_lo = ctx->lo; + if ((ctx->lo = (saved_lo + size) & 0x1fffffff) < saved_lo) + ctx->hi++; + ctx->hi += size >> 29; + + used = saved_lo & 0x3f; + + if (used) { + free = 64 - used; + + if (size < free) { + memcpy(&ctx->buffer[used], data, size); + return; + } + + memcpy(&ctx->buffer[used], data, free); + data = (const unsigned char *)data + free; + size -= free; + _picohash_md5_body(ctx, ctx->buffer, 64); + } + + if (size >= 64) { + data = _picohash_md5_body(ctx, data, size & ~(unsigned long)0x3f); + size &= 0x3f; + } + + memcpy(ctx->buffer, data, size); +} + +inline void _picohash_md5_final(_picohash_md5_ctx_t *ctx, void *_digest) +{ + unsigned char *digest = _digest; + unsigned long used, free; + + used = ctx->lo & 0x3f; + + ctx->buffer[used++] = 0x80; + + free = 64 - used; + + if (free < 8) { + memset(&ctx->buffer[used], 0, free); + _picohash_md5_body(ctx, ctx->buffer, 64); + used = 0; + free = 64; + } + + memset(&ctx->buffer[used], 0, free - 8); + + ctx->lo <<= 3; + ctx->buffer[56] = ctx->lo; + ctx->buffer[57] = ctx->lo >> 8; + ctx->buffer[58] = ctx->lo >> 16; + ctx->buffer[59] = ctx->lo >> 24; + ctx->buffer[60] = ctx->hi; + ctx->buffer[61] = ctx->hi >> 8; + ctx->buffer[62] = ctx->hi >> 16; + ctx->buffer[63] = ctx->hi >> 24; + + _picohash_md5_body(ctx, ctx->buffer, 64); + + digest[0] = ctx->a; + digest[1] = ctx->a >> 8; + digest[2] = ctx->a >> 16; + digest[3] = ctx->a >> 24; + digest[4] = ctx->b; + digest[5] = ctx->b >> 8; + digest[6] = ctx->b >> 16; + digest[7] = ctx->b >> 24; + digest[8] = ctx->c; + digest[9] = ctx->c >> 8; + digest[10] = ctx->c >> 16; + digest[11] = ctx->c >> 24; + digest[12] = ctx->d; + digest[13] = ctx->d >> 8; + digest[14] = ctx->d >> 16; + digest[15] = ctx->d >> 24; + + memset(ctx, 0, sizeof(*ctx)); +} + +#define _PICOHASH_SHA1_K0 0x5a827999 +#define _PICOHASH_SHA1_K20 0x6ed9eba1 +#define _PICOHASH_SHA1_K40 0x8f1bbcdc +#define _PICOHASH_SHA1_K60 0xca62c1d6 + +static inline uint32_t _picohash_sha1_rol32(uint32_t number, uint8_t bits) +{ + return ((number << bits) | (number >> (32 - bits))); +} + +static inline void _picohash_sha1_hash_block(_picohash_sha1_ctx_t *s) +{ + uint8_t i; + uint32_t a, b, c, d, e, t; + + a = s->state[0]; + b = s->state[1]; + c = s->state[2]; + d = s->state[3]; + e = s->state[4]; + for (i = 0; i < 80; i++) { + if (i >= 16) { + t = s->buffer[(i + 13) & 15] ^ s->buffer[(i + 8) & 15] ^ s->buffer[(i + 2) & 15] ^ s->buffer[i & 15]; + s->buffer[i & 15] = _picohash_sha1_rol32(t, 1); + } + if (i < 20) { + t = (d ^ (b & (c ^ d))) + _PICOHASH_SHA1_K0; + } else if (i < 40) { + t = (b ^ c ^ d) + _PICOHASH_SHA1_K20; + } else if (i < 60) { + t = ((b & c) | (d & (b | c))) + _PICOHASH_SHA1_K40; + } else { + t = (b ^ c ^ d) + _PICOHASH_SHA1_K60; + } + t += _picohash_sha1_rol32(a, 5) + e + s->buffer[i & 15]; + e = d; + d = c; + c = _picohash_sha1_rol32(b, 30); + b = a; + a = t; + } + s->state[0] += a; + s->state[1] += b; + s->state[2] += c; + s->state[3] += d; + s->state[4] += e; +} + +static inline void _picohash_sha1_add_uncounted(_picohash_sha1_ctx_t *s, uint8_t data) +{ + uint8_t *const b = (uint8_t *)s->buffer; +#ifdef _PICOHASH_BIG_ENDIAN + b[s->bufferOffset] = data; +#else + b[s->bufferOffset ^ 3] = data; +#endif + s->bufferOffset++; + if (s->bufferOffset == PICOHASH_SHA1_BLOCK_LENGTH) { + _picohash_sha1_hash_block(s); + s->bufferOffset = 0; + } +} + +inline void _picohash_sha1_init(_picohash_sha1_ctx_t *s) +{ + s->state[0] = 0x67452301; + s->state[1] = 0xefcdab89; + s->state[2] = 0x98badcfe; + s->state[3] = 0x10325476; + s->state[4] = 0xc3d2e1f0; + s->byteCount = 0; + s->bufferOffset = 0; +} + +inline void _picohash_sha1_update(_picohash_sha1_ctx_t *s, const void *_data, size_t len) +{ + const uint8_t *data = _data; + for (; len != 0; --len) { + ++s->byteCount; + _picohash_sha1_add_uncounted(s, *data++); + } +} + +inline void _picohash_sha1_final(_picohash_sha1_ctx_t *s, void *digest) +{ + // Pad with 0x80 followed by 0x00 until the end of the block + _picohash_sha1_add_uncounted(s, 0x80); + while (s->bufferOffset != 56) + _picohash_sha1_add_uncounted(s, 0x00); + + // Append length in the last 8 bytes + _picohash_sha1_add_uncounted(s, s->byteCount >> 53); // Shifting to multiply by 8 + _picohash_sha1_add_uncounted(s, s->byteCount >> 45); // as SHA-1 supports bitstreams as well as + _picohash_sha1_add_uncounted(s, s->byteCount >> 37); // byte. + _picohash_sha1_add_uncounted(s, s->byteCount >> 29); + _picohash_sha1_add_uncounted(s, s->byteCount >> 21); + _picohash_sha1_add_uncounted(s, s->byteCount >> 13); + _picohash_sha1_add_uncounted(s, s->byteCount >> 5); + _picohash_sha1_add_uncounted(s, s->byteCount << 3); + +#ifndef SHA_BIG_ENDIAN + { // Swap byte order back + int i; + for (i = 0; i < 5; i++) { + s->state[i] = (((s->state[i]) << 24) & 0xff000000) | (((s->state[i]) << 8) & 0x00ff0000) | + (((s->state[i]) >> 8) & 0x0000ff00) | (((s->state[i]) >> 24) & 0x000000ff); + } + } +#endif + + memcpy(digest, s->state, sizeof(s->state)); +} + +#define _picohash_sha256_ch(x, y, z) (z ^ (x & (y ^ z))) +#define _picohash_sha256_maj(x, y, z) (((x | y) & z) | (x & y)) +#define _picohash_sha256_s(x, y) \ + (((((uint32_t)(x)&0xFFFFFFFFUL) >> (uint32_t)((y)&31)) | ((uint32_t)(x) << (uint32_t)(32 - ((y)&31)))) & 0xFFFFFFFFUL) +#define _picohash_sha256_r(x, n) (((x)&0xFFFFFFFFUL) >> (n)) +#define _picohash_sha256_sigma0(x) (_picohash_sha256_s(x, 2) ^ _picohash_sha256_s(x, 13) ^ _picohash_sha256_s(x, 22)) +#define _picohash_sha256_sigma1(x) (_picohash_sha256_s(x, 6) ^ _picohash_sha256_s(x, 11) ^ _picohash_sha256_s(x, 25)) +#define _picohash_sha256_gamma0(x) (_picohash_sha256_s(x, 7) ^ _picohash_sha256_s(x, 18) ^ _picohash_sha256_r(x, 3)) +#define _picohash_sha256_gamma1(x) (_picohash_sha256_s(x, 17) ^ _picohash_sha256_s(x, 19) ^ _picohash_sha256_r(x, 10)) +#define _picohash_sha256_rnd(a, b, c, d, e, f, g, h, i) \ + t0 = h + _picohash_sha256_sigma1(e) + _picohash_sha256_ch(e, f, g) + K[i] + W[i]; \ + t1 = _picohash_sha256_sigma0(a) + _picohash_sha256_maj(a, b, c); \ + d += t0; \ + h = t0 + t1; + +static inline void _picohash_sha256_compress(_picohash_sha256_ctx_t *ctx, unsigned char *buf) +{ + static const uint32_t K[64] = { + 0x428a2f98UL, 0x71374491UL, 0xb5c0fbcfUL, 0xe9b5dba5UL, 0x3956c25bUL, 0x59f111f1UL, 0x923f82a4UL, 0xab1c5ed5UL, + 0xd807aa98UL, 0x12835b01UL, 0x243185beUL, 0x550c7dc3UL, 0x72be5d74UL, 0x80deb1feUL, 0x9bdc06a7UL, 0xc19bf174UL, + 0xe49b69c1UL, 0xefbe4786UL, 0x0fc19dc6UL, 0x240ca1ccUL, 0x2de92c6fUL, 0x4a7484aaUL, 0x5cb0a9dcUL, 0x76f988daUL, + 0x983e5152UL, 0xa831c66dUL, 0xb00327c8UL, 0xbf597fc7UL, 0xc6e00bf3UL, 0xd5a79147UL, 0x06ca6351UL, 0x14292967UL, + 0x27b70a85UL, 0x2e1b2138UL, 0x4d2c6dfcUL, 0x53380d13UL, 0x650a7354UL, 0x766a0abbUL, 0x81c2c92eUL, 0x92722c85UL, + 0xa2bfe8a1UL, 0xa81a664bUL, 0xc24b8b70UL, 0xc76c51a3UL, 0xd192e819UL, 0xd6990624UL, 0xf40e3585UL, 0x106aa070UL, + 0x19a4c116UL, 0x1e376c08UL, 0x2748774cUL, 0x34b0bcb5UL, 0x391c0cb3UL, 0x4ed8aa4aUL, 0x5b9cca4fUL, 0x682e6ff3UL, + 0x748f82eeUL, 0x78a5636fUL, 0x84c87814UL, 0x8cc70208UL, 0x90befffaUL, 0xa4506cebUL, 0xbef9a3f7UL, 0xc67178f2UL}; + uint32_t S[8], W[64], t, t0, t1; + int i; + + /* copy state into S */ + for (i = 0; i < 8; i++) + S[i] = ctx->state[i]; + + /* copy the state into 512-bits into W[0..15] */ + for (i = 0; i < 16; i++) + W[i] = + (uint32_t)buf[4 * i] << 24 | (uint32_t)buf[4 * i + 1] << 16 | (uint32_t)buf[4 * i + 2] << 8 | (uint32_t)buf[4 * i + 3]; + + /* fill W[16..63] */ + for (i = 16; i < 64; i++) + W[i] = _picohash_sha256_gamma1(W[i - 2]) + W[i - 7] + _picohash_sha256_gamma0(W[i - 15]) + W[i - 16]; + + /* Compress */ + for (i = 0; i < 64; ++i) { + _picohash_sha256_rnd(S[0], S[1], S[2], S[3], S[4], S[5], S[6], S[7], i); + t = S[7]; + S[7] = S[6]; + S[6] = S[5]; + S[5] = S[4]; + S[4] = S[3]; + S[3] = S[2]; + S[2] = S[1]; + S[1] = S[0]; + S[0] = t; + } + + /* feedback */ + for (i = 0; i < 8; i++) + ctx->state[i] = ctx->state[i] + S[i]; +} + +static inline void _picohash_sha256_do_final(_picohash_sha256_ctx_t *ctx, void *digest, size_t len) +{ + unsigned char *out = digest; + size_t i; + + /* increase the length of the message */ + ctx->length += ctx->curlen * 8; + + /* append the '1' bit */ + ctx->buf[ctx->curlen++] = (unsigned char)0x80; + + /* if the length is currently above 56 bytes we append zeros + * then compress. Then we can fall back to padding zeros and length + * encoding like normal. + */ + if (ctx->curlen > 56) { + while (ctx->curlen < 64) { + ctx->buf[ctx->curlen++] = (unsigned char)0; + } + _picohash_sha256_compress(ctx, ctx->buf); + ctx->curlen = 0; + } + + /* pad upto 56 bytes of zeroes */ + while (ctx->curlen < 56) { + ctx->buf[ctx->curlen++] = (unsigned char)0; + } + + /* store length */ + for (i = 0; i != 8; ++i) + ctx->buf[56 + i] = ctx->length >> (56 - 8 * i); + _picohash_sha256_compress(ctx, ctx->buf); + + /* copy output */ + for (i = 0; i != len / 4; ++i) { + out[i * 4] = ctx->state[i] >> 24; + out[i * 4 + 1] = ctx->state[i] >> 16; + out[i * 4 + 2] = ctx->state[i] >> 8; + out[i * 4 + 3] = ctx->state[i]; + } +} + +inline void _picohash_sha256_init(_picohash_sha256_ctx_t *ctx) +{ + ctx->curlen = 0; + ctx->length = 0; + ctx->state[0] = 0x6A09E667UL; + ctx->state[1] = 0xBB67AE85UL; + ctx->state[2] = 0x3C6EF372UL; + ctx->state[3] = 0xA54FF53AUL; + ctx->state[4] = 0x510E527FUL; + ctx->state[5] = 0x9B05688CUL; + ctx->state[6] = 0x1F83D9ABUL; + ctx->state[7] = 0x5BE0CD19UL; +} + +inline void _picohash_sha256_update(_picohash_sha256_ctx_t *ctx, const void *data, size_t len) +{ + const unsigned char *in = data; + size_t n; + + while (len > 0) { + if (ctx->curlen == 0 && len >= PICOHASH_SHA256_BLOCK_LENGTH) { + _picohash_sha256_compress(ctx, (unsigned char *)in); + ctx->length += PICOHASH_SHA256_BLOCK_LENGTH * 8; + in += PICOHASH_SHA256_BLOCK_LENGTH; + len -= PICOHASH_SHA256_BLOCK_LENGTH; + } else { + n = PICOHASH_SHA256_BLOCK_LENGTH - ctx->curlen; + if (n > len) + n = len; + memcpy(ctx->buf + ctx->curlen, in, (size_t)n); + ctx->curlen += n; + in += n; + len -= n; + if (ctx->curlen == 64) { + _picohash_sha256_compress(ctx, ctx->buf); + ctx->length += 8 * PICOHASH_SHA256_BLOCK_LENGTH; + ctx->curlen = 0; + } + } + } +} + +inline void _picohash_sha256_final(_picohash_sha256_ctx_t *ctx, void *digest) +{ + _picohash_sha256_do_final(ctx, digest, PICOHASH_SHA256_DIGEST_LENGTH); +} + +inline void _picohash_sha224_init(_picohash_sha256_ctx_t *ctx) +{ + ctx->curlen = 0; + ctx->length = 0; + ctx->state[0] = 0xc1059ed8UL; + ctx->state[1] = 0x367cd507UL; + ctx->state[2] = 0x3070dd17UL; + ctx->state[3] = 0xf70e5939UL; + ctx->state[4] = 0xffc00b31UL; + ctx->state[5] = 0x68581511UL; + ctx->state[6] = 0x64f98fa7UL; + ctx->state[7] = 0xbefa4fa4UL; +} + +inline void _picohash_sha224_final(_picohash_sha256_ctx_t *ctx, void *digest) +{ + _picohash_sha256_do_final(ctx, digest, PICOHASH_SHA224_DIGEST_LENGTH); +} + +inline void picohash_init_md5(picohash_ctx_t *ctx) +{ + ctx->block_length = PICOHASH_MD5_BLOCK_LENGTH; + ctx->digest_length = PICOHASH_MD5_DIGEST_LENGTH; + ctx->_reset = (void *)_picohash_md5_init; + ctx->_update = (void *)_picohash_md5_update; + ctx->_final = (void *)_picohash_md5_final; + + _picohash_md5_init(&ctx->_md5); +} + +inline void picohash_init_sha1(picohash_ctx_t *ctx) +{ + ctx->block_length = PICOHASH_SHA1_BLOCK_LENGTH; + ctx->digest_length = PICOHASH_SHA1_DIGEST_LENGTH; + ctx->_reset = (void *)_picohash_sha1_init; + ctx->_update = (void *)_picohash_sha1_update; + ctx->_final = (void *)_picohash_sha1_final; + _picohash_sha1_init(&ctx->_sha1); +} + +inline void picohash_init_sha224(picohash_ctx_t *ctx) +{ + ctx->block_length = PICOHASH_SHA224_BLOCK_LENGTH; + ctx->digest_length = PICOHASH_SHA224_DIGEST_LENGTH; + ctx->_reset = (void *)_picohash_sha224_init; + ctx->_update = (void *)_picohash_sha256_update; + ctx->_final = (void *)_picohash_sha224_final; + _picohash_sha224_init(&ctx->_sha256); +} + +inline void picohash_init_sha256(picohash_ctx_t *ctx) +{ + ctx->block_length = PICOHASH_SHA256_BLOCK_LENGTH; + ctx->digest_length = PICOHASH_SHA256_DIGEST_LENGTH; + ctx->_reset = (void *)_picohash_sha256_init; + ctx->_update = (void *)_picohash_sha256_update; + ctx->_final = (void *)_picohash_sha256_final; + _picohash_sha256_init(&ctx->_sha256); +} + +inline void picohash_update(picohash_ctx_t *ctx, const void *input, size_t len) +{ + ctx->_update(ctx, input, len); +} + +inline void picohash_final(picohash_ctx_t *ctx, void *digest) +{ + ctx->_final(ctx, digest); +} + +inline void picohash_reset(picohash_ctx_t *ctx) +{ + ctx->_reset(ctx); +} + +static inline void _picohash_hmac_apply_key(picohash_ctx_t *ctx, unsigned char delta) +{ + size_t i; + for (i = 0; i != ctx->block_length; ++i) + ctx->_hmac.key[i] ^= delta; + picohash_update(ctx, ctx->_hmac.key, ctx->block_length); + for (i = 0; i != ctx->block_length; ++i) + ctx->_hmac.key[i] ^= delta; +} + +static void _picohash_hmac_final(picohash_ctx_t *ctx, void *digest) +{ + unsigned char inner_digest[PICOHASH_MAX_DIGEST_LENGTH]; + + ctx->_hmac.hash_final(ctx, inner_digest); + + ctx->_hmac.hash_reset(ctx); + _picohash_hmac_apply_key(ctx, 0x5c); + picohash_update(ctx, inner_digest, ctx->digest_length); + memset(inner_digest, 0, ctx->digest_length); + + ctx->_hmac.hash_final(ctx, digest); +} + +static inline void _picohash_hmac_reset(picohash_ctx_t *ctx) +{ + ctx->_hmac.hash_reset(ctx); + _picohash_hmac_apply_key(ctx, 0x36); +} + +inline void picohash_init_hmac(picohash_ctx_t *ctx, void (*initf)(picohash_ctx_t *), const void *key, size_t key_len) +{ + initf(ctx); + + memset(ctx->_hmac.key, 0, ctx->block_length); + if (key_len > ctx->block_length) { + /* hash the key if it is too long */ + picohash_update(ctx, key, key_len); + picohash_final(ctx, ctx->_hmac.key); + ctx->_hmac.hash_reset(ctx); + } else { + memcpy(ctx->_hmac.key, key, key_len); + } + + /* replace reset and final function */ + ctx->_hmac.hash_reset = ctx->_reset; + ctx->_hmac.hash_final = ctx->_final; + ctx->_reset = (void *)_picohash_hmac_reset; + ctx->_final = (void *)_picohash_hmac_final; + + /* start calculating the inner hash */ + _picohash_hmac_apply_key(ctx, 0x36); +} + +#endif diff --git a/web/server/h2o/libh2o/deps/mruby-digest/test/digest.rb b/web/server/h2o/libh2o/deps/mruby-digest/test/digest.rb new file mode 100644 index 00000000..fd13fa43 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby-digest/test/digest.rb @@ -0,0 +1,203 @@ +## +# Digest Test + +if Object.const_defined?(:Digest) + assert('Digest') do + Digest.class == Module + end + + assert('Digest::Base') do + Digest::Base.class == Class + end + + assert('Digest::Base#new') do + e1 = nil + begin + Digest::Base.new + rescue NotImplementedError => e + e1 = e + end + e1.class == NotImplementedError + end + + assert('Digest::MD5') do + Digest::MD5.class == Class + end + + assert('Digest::MD5 superclass') do + Digest::MD5.superclass == Digest::Base + end + + assert('Digest::MD5.digest') do + Digest::MD5.digest('ruby') == "X\xE5=\x13$\xEE\xF6&_\xDB\x97\xB0\x8E\xD9\xAA\xDF" + end + + #assert('Digest::MD5.file') + + assert('Digest::MD5.hexdigest') do + Digest::MD5.hexdigest('ruby') == "58e53d1324eef6265fdb97b08ed9aadf" + end + + assert('Digest::MD5#update') do + d = Digest::MD5.new + d.update('ruby') + d.hexdigest == "58e53d1324eef6265fdb97b08ed9aadf" + end + + assert('Digest::MD5#update 2') do + d = Digest::MD5.new + d.update('ruby') + d.update('digest') + d.hexdigest == "2ac1b3e3db06239e3244817f281450f1" + end + + assert('Digest::MD5#<<') do + a = Digest::MD5.new + b = Digest::MD5.new + a.update('ruby') + b << "r" << "u" << "b" << "y" + a.hexdigest == b.hexdigest + end + + assert('Digest::MD5#== with Digest::XXX') do + x1 = Digest::MD5.new.update("ruby") + x2 = Digest::MD5.new.update("ruby") + x3 = Digest::MD5.new.update("RUBY") + (x1 == x2) == true and + (x1 == x3) == false + end + + assert('Digest::MD5#== with String') do + Digest::MD5.new.update("ruby") == "58e53d1324eef6265fdb97b08ed9aadf" + end + + assert('Digest::MD5#block_length') do + Digest::MD5.new.block_length == 64 + end + + assert('Digest::MD5#digest') do + Digest::MD5.new.update("ruby").digest == "X\xE5=\x13$\xEE\xF6&_\xDB\x97\xB0\x8E\xD9\xAA\xDF" + end + + assert('Digest::MD5#digest!') do + d = Digest::MD5.new.update("ruby") + d.digest! + #d.digest! == "\xD4\x1D\x8C\xD9\x8F\x00\xB2\x04\xE9\x80\t\x98\xEC\xF8B~" + # XXX: mrbtest dumps core! + d.digest! == Digest::MD5.new.digest + end + + assert('Digest::MD5#digest_length') do + d = Digest::MD5.new + n = 16 + d.digest_length == n and + d.length == n and + d.size == n + end + + #assert('Digest::MD5#file') + + assert('Digest::MD5#hexdigest') do + d = Digest::MD5.new.update("ruby") + s = "58e53d1324eef6265fdb97b08ed9aadf" + d.hexdigest == s and + d.to_s == s + end + + assert('Digest::MD5#hexdigest!') do + d = Digest::MD5.new.update("ruby") + d.hexdigest! + d.hexdigest! == "d41d8cd98f00b204e9800998ecf8427e" + end + + assert('Digest::MD5#reset') do + d = Digest::MD5.new.update("ruby") + d.reset + d.hexdigest! == "d41d8cd98f00b204e9800998ecf8427e" + end + + if Digest.const_defined? :RMD160 + assert('Digest::RMD160#hexdigest') do + d = Digest::RMD160.new.update("ruby") + s = "29d9b710bc50866fa2399c3061cd02c0c8ffa197" + d.hexdigest == s + end + end + + if Digest.const_defined? :SHA1 + assert('Digest::SHA1#hexdigest') do + d = Digest::SHA1.new.update("ruby") + s = "18e40e1401eef67e1ae69efab09afb71f87ffb81" + d.hexdigest == s + end + end + + if Digest.const_defined? :SHA256 + assert('Digest::SHA256#hexdigest') do + d = Digest::SHA256.new.update("ruby") + s = "b9138194ffe9e7c8bb6d79d1ed56259553d18d9cb60b66e3ba5aa2e5b078055a" + d.hexdigest == s + end + end + + if Digest.const_defined? :SHA384 + assert('Digest::SHA384#hexdigest') do + d = Digest::SHA384.new.update("ruby") + s = "635365ef93ebf2c7a4e40b0b497da727ab8c2914eb9f052e6be40476f95d3daf44786790f5f0e843fab419b43022e069" + d.hexdigest == s + end + end + + if Digest.const_defined? :SHA512 + assert('Digest::SHA512#hexdigest') do + d = Digest::SHA512.new.update("ruby") + s = "423408d7723a3d80baefa804bd50b61a89667efec1713386a7b8efe28e5d13968307a908778cad210d7aa2dfe7db9a2aa86895f9fc1eeefcc99814310b207a6b" + d.hexdigest == s + end + end + + assert('Digest::HMAC') do + Digest::HMAC.class == Class + end + + assert('Digest::HMAC.digest') do + Digest::HMAC.digest("data", "hash key", Digest::SHA1) == "\xFD \xECC=\xFD\x97\x0E\xEC!FW\xCF\xB5Gl]\x913f" + end + + assert('Digest::HMAC.hexdigest') do + Digest::HMAC.hexdigest("data", "hash key", Digest::SHA1) == "fd20ec433dfd970eec214657cfb5476c5d913366" + end + + assert('Digest::HMAC#<<') do + a = Digest::HMAC.new('hash key', Digest::SHA1) + b = Digest::HMAC.new('hash key', Digest::SHA1) + a.update('ruby') + b << "r" << "u" << "b" << "y" + a.hexdigest == b.hexdigest + end + + assert('Digest::HMAC#block_length') do + d = Digest::HMAC.new("hash key", Digest::SHA1) + d.block_length == 64 + end + + assert('Digest::HMAC#digest_length') do + d = Digest::HMAC.new("hash key", Digest::SHA1) + d.digest_length == 20 + end + + # assert('Digest::HMAC#reset') + + assert('Digest::HMAC#update') do + d = Digest::HMAC.new("hash key", Digest::SHA1) + d.update('data') + d.hexdigest == "fd20ec433dfd970eec214657cfb5476c5d913366" + end + + assert('Digest::HMAC#update 2') do + d = Digest::HMAC.new("hash key", Digest::SHA1) + d.update('ruby') + d.update('digest') + d.hexdigest == "e4be3728777e43deba3aa522a4247ea83b19a1c7" + end +end diff --git a/web/server/h2o/libh2o/deps/mruby-dir/.gitignore b/web/server/h2o/libh2o/deps/mruby-dir/.gitignore new file mode 100644 index 00000000..55ef3162 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby-dir/.gitignore @@ -0,0 +1,5 @@ +gem_* +gem-* +mrb-*.a +src/*.o +/tmp diff --git a/web/server/h2o/libh2o/deps/mruby-dir/.travis.yml b/web/server/h2o/libh2o/deps/mruby-dir/.travis.yml new file mode 100644 index 00000000..ffe22728 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby-dir/.travis.yml @@ -0,0 +1,2 @@ +script: + - "ruby run_test.rb all test" diff --git a/web/server/h2o/libh2o/deps/mruby-dir/README.md b/web/server/h2o/libh2o/deps/mruby-dir/README.md new file mode 100644 index 00000000..d7953036 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby-dir/README.md @@ -0,0 +1,56 @@ +mruby-dir +========= + +Dir class for mruby. Supported methods are: + +`.chdir` +`.delete` +`.entries` +`.exist?` +`.foreach` +`.getwd` +`.mkdir` +`.open` +`#close` +`#each` +`#read` +`#rewind` +`#seek` +`#tell` + + +## License + +Copyright (c) 2012 Internet Initiative Japan Inc. + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the "Software"), +to deal in the Software without restriction, including without limitation +the rights to use, copy, modify, merge, publish, distribute, sublicense, +and/or sell copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. + + +- On Windows platforms, you must agree on addional license too: + +Copyright Kevlin Henney, 1997, 2003, 2012. All rights reserved. + +Permission to use, copy, modify, and distribute this software and its +documentation for any purpose is hereby granted without fee, provided +that this copyright and permissions notice appear in all copies and +derivatives. + +This software is supplied "as is" without express or implied warranty. + +But that said, if there are any problems please get in touch. diff --git a/web/server/h2o/libh2o/deps/mruby-dir/mrbgem.rake b/web/server/h2o/libh2o/deps/mruby-dir/mrbgem.rake new file mode 100644 index 00000000..10864c81 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby-dir/mrbgem.rake @@ -0,0 +1,6 @@ +MRuby::Gem::Specification.new('mruby-dir') do |spec| + spec.license = 'MIT and MIT-like license' + spec.authors = [ 'Internet Initiative Japan Inc.', 'Kevlin Henney'] + + spec.cc.include_paths << "#{build.root}/src" +end diff --git a/web/server/h2o/libh2o/deps/mruby-dir/mrblib/dir.rb b/web/server/h2o/libh2o/deps/mruby-dir/mrblib/dir.rb new file mode 100644 index 00000000..065ca1c2 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby-dir/mrblib/dir.rb @@ -0,0 +1,64 @@ +class Dir + def each(&block) + while s = self.read + block.call(s) + end + self + end + + alias pos tell + alias pos= seek + + def self.entries(path) + a = [] + self.open(path) { |d| + while s = d.read + a << s + end + } + a + end + + def self.foreach(path, &block) + if block + self.open(path).each { |f| block.call(f) } + else + self.open(path).each + end + end + + def self.open(path, &block) + if block + d = self.new(path) + begin + block.call(d) + ensure + d.close + end + else + self.new(path) + end + end + + def self.chdir(path, &block) + my = self # workaround for https://github.com/mruby/mruby/issues/1579 + if block + wd = self.getwd + begin + self._chdir(path) + block.call(path) + ensure + my._chdir(wd) + end + else + self._chdir(path) + end + end + + class << self + alias exists? exist? + alias pwd getwd + alias rmdir delete + alias unlink delete + end +end diff --git a/web/server/h2o/libh2o/deps/mruby-dir/run_test.rb b/web/server/h2o/libh2o/deps/mruby-dir/run_test.rb new file mode 100644 index 00000000..d9566a2a --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby-dir/run_test.rb @@ -0,0 +1,26 @@ +#!/usr/bin/env ruby +# +# mrbgems test runner +# + +gemname = File.basename(File.dirname(File.expand_path __FILE__)) + +if __FILE__ == $0 + repository, dir = 'https://github.com/mruby/mruby.git', 'tmp/mruby' + build_args = ARGV + build_args = ['all', 'test'] if build_args.nil? or build_args.empty? + + Dir.mkdir 'tmp' unless File.exist?('tmp') + unless File.exist?(dir) + system "git clone #{repository} #{dir}" + end + + exit system(%Q[cd #{dir}; MRUBY_CONFIG=#{File.expand_path __FILE__} ruby minirake #{build_args.join(' ')}]) +end + +MRuby::Build.new do |conf| + toolchain :gcc + conf.gembox 'default' + + conf.gem File.expand_path(File.dirname(__FILE__)) +end diff --git a/web/server/h2o/libh2o/deps/mruby-dir/src/Win/dirent.c b/web/server/h2o/libh2o/deps/mruby-dir/src/Win/dirent.c new file mode 100644 index 00000000..98728bcf --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby-dir/src/Win/dirent.c @@ -0,0 +1,154 @@ +/* + + Implementation of POSIX directory browsing functions and types for Win32. + + Author: Kevlin Henney (kevlin@acm.org, kevlin@curbralan.com) + History: Created March 1997. Updated June 2003 and July 2012. + Rights: See end of file. + +*/ + +#include +#include /* _findfirst and _findnext set errno iff they return -1 */ +#include +#include + +#ifdef __cplusplus +extern "C" +{ +#endif + +typedef ptrdiff_t handle_type; /* C99's intptr_t not sufficiently portable */ + +struct dirent +{ + char *d_name; +}; + +struct DIR +{ + handle_type handle; /* -1 for failed rewind */ + struct _finddata_t info; + struct dirent result; /* d_name null iff first time */ + char *name; /* null-terminated char string */ +}; + +typedef struct DIR DIR; + +DIR *opendir(const char *name) +{ + DIR *dir = 0; + + if(name && name[0]) + { + size_t base_length = strlen(name); + const char *all = /* search pattern must end with suitable wildcard */ + strchr("/\\", name[base_length - 1]) ? "*" : "/*"; + + if((dir = (DIR *) malloc(sizeof *dir)) != 0 && + (dir->name = (char *) malloc(base_length + strlen(all) + 1)) != 0) + { + strcat(strcpy(dir->name, name), all); + + if((dir->handle = + (handle_type) _findfirst(dir->name, &dir->info)) != -1) + { + dir->result.d_name = 0; + } + else /* rollback */ + { + free(dir->name); + free(dir); + dir = 0; + } + } + else /* rollback */ + { + free(dir); + dir = 0; + errno = ENOMEM; + } + } + else + { + errno = EINVAL; + } + + return dir; +} + +int closedir(DIR *dir) +{ + int result = -1; + + if(dir) + { + if(dir->handle != -1) + { + result = _findclose(dir->handle); + } + + free(dir->name); + free(dir); + } + + if(result == -1) /* map all errors to EBADF */ + { + errno = EBADF; + } + + return result; +} + +struct dirent *readdir(DIR *dir) +{ + struct dirent *result = 0; + + if(dir && dir->handle != -1) + { + if(!dir->result.d_name || _findnext(dir->handle, &dir->info) != -1) + { + result = &dir->result; + result->d_name = dir->info.name; + } + } + else + { + errno = EBADF; + } + + return result; +} + +void rewinddir(DIR *dir) +{ + if(dir && dir->handle != -1) + { + _findclose(dir->handle); + dir->handle = (handle_type) _findfirst(dir->name, &dir->info); + dir->result.d_name = 0; + } + else + { + errno = EBADF; + } +} + +#ifdef __cplusplus +} +#endif + +/* + + Copyright Kevlin Henney, 1997, 2003, 2012. All rights reserved. + + Permission to use, copy, modify, and distribute this software and its + documentation for any purpose is hereby granted without fee, provided + that this copyright and permissions notice appear in all copies and + derivatives. + + This software is supplied "as is" without express or implied warranty. + + But that said, if there are any problems please get in touch. + +*/ diff --git a/web/server/h2o/libh2o/deps/mruby-dir/src/dir.c b/web/server/h2o/libh2o/deps/mruby-dir/src/dir.c new file mode 100644 index 00000000..0f55ed93 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby-dir/src/dir.c @@ -0,0 +1,281 @@ +/* +** dir.c - Dir +** +** See Copyright Notice in mruby.h +*/ + +#include "mruby.h" +#include "mruby/class.h" +#include "mruby/data.h" +#include "mruby/string.h" +#include "error.h" +#include +#if defined(_WIN32) || defined(_WIN64) + #define MAXPATHLEN 1024 + #if !defined(PATH_MAX) + #define PATH_MAX MAX_PATH + #endif + #define S_ISDIR(B) ((B)&_S_IFDIR) + #include "Win/dirent.c" + #include + #define rmdir _rmdir + #define getcwd _getcwd + #define mkdir _mkdir + #define chdir _chdir +#else + #include + #include + #include +#endif +#include +#include +#include +#include +#include +#include + +/* with/without IO module */ +#ifdef ENABLE_IO +#include "mruby/ext/io.h" +#else +#define E_IO_ERROR E_RUNTIME_ERROR +#endif + +struct mrb_dir { + DIR *dir; +}; + +void +mrb_dir_free(mrb_state *mrb, void *ptr) +{ + struct mrb_dir *mdir = ptr; + + if (mdir->dir) { + closedir(mdir->dir); + mdir->dir = NULL; + } + mrb_free(mrb, mdir); +} + +static struct mrb_data_type mrb_dir_type = { "DIR", mrb_dir_free }; + +mrb_value +mrb_dir_close(mrb_state *mrb, mrb_value self) +{ + struct mrb_dir *mdir; + mdir = (struct mrb_dir *)mrb_get_datatype(mrb, self, &mrb_dir_type); + if (!mdir) return mrb_nil_value(); + if (!mdir->dir) { + mrb_raise(mrb, E_IO_ERROR, "closed directory"); + } + if (closedir(mdir->dir) == -1) { + mrb_sys_fail(mrb, "closedir"); + } + mdir->dir = NULL; + return mrb_nil_value(); +} + +mrb_value +mrb_dir_init(mrb_state *mrb, mrb_value self) +{ + DIR *dir; + struct mrb_dir *mdir; + mrb_value path; + char *cpath; + + mdir = (struct mrb_dir *)DATA_PTR(self); + if (mdir) { + mrb_dir_free(mrb, mdir); + } + DATA_TYPE(self) = &mrb_dir_type; + DATA_PTR(self) = NULL; + + mdir = (struct mrb_dir *)mrb_malloc(mrb, sizeof(*mdir)); + mdir->dir = NULL; + DATA_PTR(self) = mdir; + + mrb_get_args(mrb, "S", &path); + cpath = mrb_str_to_cstr(mrb, path); + if ((dir = opendir(cpath)) == NULL) { + mrb_sys_fail(mrb, cpath); + } + mdir->dir = dir; + return self; +} + +mrb_value +mrb_dir_delete(mrb_state *mrb, mrb_value klass) +{ + mrb_value path; + char *cpath; + + mrb_get_args(mrb, "S", &path); + cpath = mrb_str_to_cstr(mrb, path); + if (rmdir(cpath) == -1) { + mrb_sys_fail(mrb, cpath); + } + return mrb_fixnum_value(0); +} + +mrb_value +mrb_dir_existp(mrb_state *mrb, mrb_value klass) +{ + mrb_value path; + struct stat sb; + char *cpath; + + mrb_get_args(mrb, "S", &path); + cpath = mrb_str_to_cstr(mrb, path); + if (stat(cpath, &sb) == 0 && S_ISDIR(sb.st_mode)) { + return mrb_true_value(); + } else { + return mrb_false_value(); + } +} + +mrb_value +mrb_dir_getwd(mrb_state *mrb, mrb_value klass) +{ + mrb_value path; + + path = mrb_str_buf_new(mrb, MAXPATHLEN); + if (getcwd(RSTRING_PTR(path), MAXPATHLEN) == NULL) { + mrb_sys_fail(mrb, "getcwd(2)"); + } + mrb_str_resize(mrb, path, strlen(RSTRING_PTR(path))); + return path; +} + +mrb_value +mrb_dir_mkdir(mrb_state *mrb, mrb_value klass) +{ + mrb_int mode; + mrb_value spath; + char *path; + + mode = 0777; + mrb_get_args(mrb, "S|i", &spath, &mode); + path = mrb_str_to_cstr(mrb, spath); +#ifndef _WIN32 + if (mkdir(path, mode) == -1) { +#else + if (mkdir(path) == -1) { +#endif + mrb_sys_fail(mrb, path); + } + return mrb_fixnum_value(0); +} + +mrb_value +mrb_dir_chdir(mrb_state *mrb, mrb_value klass) +{ + mrb_value spath; + char *path; + + mrb_get_args(mrb, "S", &spath); + path = mrb_str_to_cstr(mrb, spath); + if (chdir(path) == -1) { + mrb_sys_fail(mrb, path); + } + return mrb_fixnum_value(0); +} + +mrb_value +mrb_dir_read(mrb_state *mrb, mrb_value self) +{ + struct mrb_dir *mdir; + struct dirent *dp; + + mdir = (struct mrb_dir *)mrb_get_datatype(mrb, self, &mrb_dir_type); + if (!mdir) return mrb_nil_value(); + if (!mdir->dir) { + mrb_raise(mrb, E_IO_ERROR, "closed directory"); + } + dp = readdir(mdir->dir); + if (dp != NULL) { + return mrb_str_new_cstr(mrb, dp->d_name); + } else { + return mrb_nil_value(); + } +} + +mrb_value +mrb_dir_rewind(mrb_state *mrb, mrb_value self) +{ + struct mrb_dir *mdir; + + mdir = (struct mrb_dir *)mrb_get_datatype(mrb, self, &mrb_dir_type); + if (!mdir) return mrb_nil_value(); + if (!mdir->dir) { + mrb_raise(mrb, E_IO_ERROR, "closed directory"); + } + rewinddir(mdir->dir); + return self; +} + +mrb_value +mrb_dir_seek(mrb_state *mrb, mrb_value self) +{ + #if defined(_WIN32) || defined(_WIN64) || defined(__android__) + mrb_raise(mrb, E_RUNTIME_ERROR, "dirseek() unreliable on Win platforms"); + return self; + #else + struct mrb_dir *mdir; + mrb_int pos; + + mdir = (struct mrb_dir *)mrb_get_datatype(mrb, self, &mrb_dir_type); + if (!mdir) return mrb_nil_value(); + if (!mdir->dir) { + mrb_raise(mrb, E_IO_ERROR, "closed directory"); + } + mrb_get_args(mrb, "i", &pos); + seekdir(mdir->dir, (long)pos); + return self; + #endif +} + +mrb_value +mrb_dir_tell(mrb_state *mrb, mrb_value self) +{ + #if defined(_WIN32) || defined(_WIN64) || defined(__android__) + mrb_raise(mrb, E_RUNTIME_ERROR, "dirtell() unreliable on Win platforms"); + return mrb_fixnum_value(0); + #else + struct mrb_dir *mdir; + mrb_int pos; + + mdir = (struct mrb_dir *)mrb_get_datatype(mrb, self, &mrb_dir_type); + if (!mdir) return mrb_nil_value(); + if (!mdir->dir) { + mrb_raise(mrb, E_IO_ERROR, "closed directory"); + } + pos = (mrb_int)telldir(mdir->dir); + return mrb_fixnum_value(pos); + #endif +} + +void +mrb_mruby_dir_gem_init(mrb_state *mrb) +{ + struct RClass *d; + + d = mrb_define_class(mrb, "Dir", mrb->object_class); + MRB_SET_INSTANCE_TT(d, MRB_TT_DATA); + mrb_define_class_method(mrb, d, "delete", mrb_dir_delete, MRB_ARGS_REQ(1)); + mrb_define_class_method(mrb, d, "exist?", mrb_dir_existp, MRB_ARGS_REQ(1)); + mrb_define_class_method(mrb, d, "getwd", mrb_dir_getwd, MRB_ARGS_NONE()); + mrb_define_class_method(mrb, d, "mkdir", mrb_dir_mkdir, MRB_ARGS_REQ(1)|MRB_ARGS_OPT(1)); + mrb_define_class_method(mrb, d, "_chdir", mrb_dir_chdir, MRB_ARGS_REQ(1)); + + mrb_define_method(mrb, d, "close", mrb_dir_close, MRB_ARGS_NONE()); + mrb_define_method(mrb, d, "initialize", mrb_dir_init, MRB_ARGS_REQ(1)); + mrb_define_method(mrb, d, "read", mrb_dir_read, MRB_ARGS_NONE()); + mrb_define_method(mrb, d, "rewind", mrb_dir_rewind, MRB_ARGS_NONE()); + mrb_define_method(mrb, d, "seek", mrb_dir_seek, MRB_ARGS_REQ(1)); + mrb_define_method(mrb, d, "tell", mrb_dir_tell, MRB_ARGS_NONE()); +} + +void +mrb_mruby_dir_gem_final(mrb_state *mrb) +{ +} diff --git a/web/server/h2o/libh2o/deps/mruby-dir/test/dir.rb b/web/server/h2o/libh2o/deps/mruby-dir/test/dir.rb new file mode 100644 index 00000000..cb1f1e31 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby-dir/test/dir.rb @@ -0,0 +1,128 @@ +assert('Dir') do + assert_equal(Class, Dir.class) +end + +assert('DirTest.setup') do + DirTest.setup +end + +assert('Dir.chdir') do + assert_equal 0, Dir.chdir(DirTest.sandbox) +end + +assert('Dir.entries') do + a = Dir.entries(DirTest.sandbox) + assert_true a.include? "a" + assert_true a.include? "b" +end + +assert('Dir.exist?') do + assert_true Dir.exist?(DirTest.sandbox) + assert_false Dir.exist?(DirTest.sandbox + "/nosuchdir") +end + +assert('Dir.foreach') do + a = [] + Dir.foreach(DirTest.sandbox) { |s| a << s } + assert_true a.include? "a" + assert_true a.include? "b" +end + +assert('Dir.getwd') do + s = Dir.getwd + assert_true s.kind_of? String +end + +assert('Dir.mkdir') do + m1 = DirTest.sandbox + "/mkdir1" + m2 = DirTest.sandbox + "/mkdir2" + assert_equal 0, Dir.mkdir(m1) + assert_equal 0, Dir.mkdir(m2, 0765) +end + +assert('Dir.delete') do + s = DirTest.sandbox + "/delete" + Dir.mkdir(s) + assert_true Dir.exist?(s) + + Dir.delete(s) + assert_false Dir.exist?(s) +end + +assert('Dir.open') do + a = [] + Dir.open(DirTest.sandbox) { |d| + d.each { |s| a << s } + } + assert_true a.include? "a" + assert_true a.include? "b" +end + +assert('Dir#initialize and Dir#close') do + d = Dir.new(".") + assert_true d.instance_of? Dir + assert_nil d.close +end + +assert('Dir#close') do + d = Dir.new(".") +end + +assert('Dir#each') do + a = [] + d = Dir.open(DirTest.sandbox) + d.each { |s| a << s } + d.close + assert_true a.include? "a" + assert_true a.include? "b" +end + +assert('Dir#read') do + a = [] + d = Dir.open(DirTest.sandbox) + while s = d.read + a << s + end + d.close + assert_true a.include? "a" + assert_true a.include? "b" +end + +assert('Dir#rewind') do + d = Dir.open(DirTest.sandbox) + while d.read; end + + assert_equal d, d.rewind + + a = [] + while s = d.read + a << s + end + d.close + assert_true a.include? "a" + assert_true a.include? "b" +end + +# Note: behaviors of seekdir(3) and telldir(3) are so platform-dependent +# that we cannot write portable tests here. + +assert('Dir#tell') do + n = nil + Dir.open(DirTest.sandbox) { |d| + n = d.tell + } + assert_true n.is_a? Integer +end + +assert('Dir#seek') do + d1 = Dir.open(DirTest.sandbox) + d1.read + n = d1.tell + d1.read + d2 = d1.seek(n) + assert_equal d1, d2 +end + +assert('DirTest.teardown') do + DirTest.teardown +end diff --git a/web/server/h2o/libh2o/deps/mruby-dir/test/dirtest.c b/web/server/h2o/libh2o/deps/mruby-dir/test/dirtest.c new file mode 100644 index 00000000..070f23a8 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby-dir/test/dirtest.c @@ -0,0 +1,114 @@ +#include +#include + +#include +#include + +#include +#include +#include + +#include "mruby.h" +#include "mruby/string.h" +#include "mruby/variable.h" + + +mrb_value +mrb_dirtest_setup(mrb_state *mrb, mrb_value klass) +{ + mrb_value s; + char buf[1024]; + const char *aname = "a"; + const char *bname = "b"; + + /* save current working directory */ + if (getcwd(buf, sizeof(buf)) == NULL) { + mrb_raise(mrb, E_RUNTIME_ERROR, "getcwd() failed"); + } + mrb_cv_set(mrb, klass, mrb_intern_cstr(mrb, "pwd"), mrb_str_new_cstr(mrb, buf)); + + /* create sandbox */ + snprintf(buf, sizeof(buf), "%s/mruby-dir-test.XXXXXX", P_tmpdir); + if (mkdtemp(buf) == NULL) { + mrb_raisef(mrb, E_RUNTIME_ERROR, "mkdtemp(%S) failed", mrb_str_new_cstr(mrb, buf)); + } + s = mrb_str_new_cstr(mrb, buf); + mrb_cv_set(mrb, klass, mrb_intern_cstr(mrb, "sandbox"), s); + + /* go to sandbox */ + if (chdir(buf) == -1) { + rmdir(buf); + mrb_raisef(mrb, E_RUNTIME_ERROR, "chdir(%S) failed", s); + } + + /* make some directories in the sandbox */ + if (mkdir(aname, 0) == -1) { + chdir(".."); + rmdir(buf); + mrb_raisef(mrb, E_RUNTIME_ERROR, "mkdir(%S) failed", mrb_str_new_cstr(mrb, aname)); + } + if (mkdir(bname, 0) == -1) { + rmdir(aname); + chdir(".."); + rmdir(buf); + mrb_raisef(mrb, E_RUNTIME_ERROR, "mkdir(%S) failed", mrb_str_new_cstr(mrb, bname)); + } + + return mrb_true_value(); +} + +mrb_value +mrb_dirtest_teardown(mrb_state *mrb, mrb_value klass) +{ + mrb_value d, sandbox; + DIR *dirp; + struct dirent *dp; + const char *path; + + /* cleanup sandbox */ + sandbox = mrb_cv_get(mrb, klass, mrb_intern_cstr(mrb, "sandbox")); + path = mrb_str_to_cstr(mrb, sandbox); + + dirp = opendir(path); + while ((dp = readdir(dirp)) != NULL) { + if (strcmp(dp->d_name, ".") == 0 || strcmp(dp->d_name, "..") == 0) + continue; + if (rmdir(dp->d_name) == -1) { + mrb_raisef(mrb, E_RUNTIME_ERROR, "rmdir(%S) failed", mrb_str_new_cstr(mrb, dp->d_name)); + } + } + closedir(dirp); + + /* back to original pwd */ + d = mrb_cv_get(mrb, klass, mrb_intern_cstr(mrb, "pwd")); + path = mrb_str_to_cstr(mrb, d); + if (chdir(path) == -1) { + mrb_raisef(mrb, E_RUNTIME_ERROR, "chdir(%S) failed", d); + } + + /* remove sandbox directory */ + sandbox = mrb_cv_get(mrb, klass, mrb_intern_cstr(mrb, "sandbox")); + path = mrb_str_to_cstr(mrb, sandbox); + if (rmdir(path) == -1) { + mrb_raisef(mrb, E_RUNTIME_ERROR, "rmdir(%S) failed", sandbox); + } + + return mrb_true_value(); +} + +mrb_value +mrb_dirtest_sandbox(mrb_state *mrb, mrb_value klass) +{ + return mrb_cv_get(mrb, klass, mrb_intern_cstr(mrb, "sandbox")); +} + +void +mrb_mruby_dir_gem_test(mrb_state *mrb) +{ + struct RClass *c = mrb_define_module(mrb, "DirTest"); + + mrb_define_class_method(mrb, c, "sandbox", mrb_dirtest_sandbox, MRB_ARGS_NONE()); + mrb_define_class_method(mrb, c, "setup", mrb_dirtest_setup, MRB_ARGS_NONE()); + mrb_define_class_method(mrb, c, "teardown", mrb_dirtest_teardown, MRB_ARGS_NONE()); +} + diff --git a/web/server/h2o/libh2o/deps/mruby-env/.gitignore b/web/server/h2o/libh2o/deps/mruby-env/.gitignore new file mode 100644 index 00000000..ceeb05b4 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby-env/.gitignore @@ -0,0 +1 @@ +/tmp diff --git a/web/server/h2o/libh2o/deps/mruby-env/.travis.yml b/web/server/h2o/libh2o/deps/mruby-env/.travis.yml new file mode 100644 index 00000000..ffe22728 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby-env/.travis.yml @@ -0,0 +1,2 @@ +script: + - "ruby run_test.rb all test" diff --git a/web/server/h2o/libh2o/deps/mruby-env/README.md b/web/server/h2o/libh2o/deps/mruby-env/README.md new file mode 100644 index 00000000..b6db2248 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby-env/README.md @@ -0,0 +1,52 @@ +mruby-env +========= + +mruby-env provides "ENV" object, which is a hash-like accessor +for environment variables. + +### Methods + +``` +[] []= clear delete has_key? include? inspect key? keys +member? size store to_a to_hash to_s values +``` + + +### To build: + +Prerequisites: + + * mruby + * libc + + activate GEMs in *build_config.rb* + * conf.gem :github => 'iij/mruby-env' + ruby ./minirake + +### To run the tests: + + ruby ./minirake test + + +## License + +Copyright (c) 2012 Internet Initiative Japan Inc. + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the "Software"), +to deal in the Software without restriction, including without limitation +the rights to use, copy, modify, merge, publish, distribute, sublicense, +and/or sell copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. + diff --git a/web/server/h2o/libh2o/deps/mruby-env/mrbgem.rake b/web/server/h2o/libh2o/deps/mruby-env/mrbgem.rake new file mode 100644 index 00000000..03249be2 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby-env/mrbgem.rake @@ -0,0 +1,4 @@ +MRuby::Gem::Specification.new('mruby-env') do |spec| + spec.license = 'MIT' + spec.authors = 'Internet Initiative Japan Inc.' +end diff --git a/web/server/h2o/libh2o/deps/mruby-env/mrblib/env.rb b/web/server/h2o/libh2o/deps/mruby-env/mrblib/env.rb new file mode 100644 index 00000000..67f9811a --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby-env/mrblib/env.rb @@ -0,0 +1,16 @@ +class << ENV + alias include? has_key? + alias key? has_key? + alias member? has_key? + + def clear + self.keys.each { |k| self.delete(k) } + self + end + + def delete(key) + old = self[key] + self[key] = nil + old + end +end diff --git a/web/server/h2o/libh2o/deps/mruby-env/run_test.rb b/web/server/h2o/libh2o/deps/mruby-env/run_test.rb new file mode 100644 index 00000000..eefc9143 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby-env/run_test.rb @@ -0,0 +1,27 @@ +#!/usr/bin/env ruby +# +# mrbgems test runner +# + +if __FILE__ == $0 + repository, dir = 'https://github.com/mruby/mruby.git', 'tmp/mruby' + build_args = ARGV + + Dir.mkdir 'tmp' unless File.exist?('tmp') + unless File.exist?(dir) + system "git clone #{repository} #{dir}" + end + + exit system(%Q[cd #{dir}; MRUBY_CONFIG=#{File.expand_path __FILE__} ruby minirake #{build_args.join(' ')}]) +end + +MRuby::Build.new do |conf| + toolchain :gcc + conf.gembox 'default' + + conf.gem :core => 'mruby-time' + conf.gem :github => 'iij/mruby-io' + conf.gem :github => 'iij/mruby-mtest' + + conf.gem File.expand_path(File.dirname(__FILE__)) +end diff --git a/web/server/h2o/libh2o/deps/mruby-env/src/env.c b/web/server/h2o/libh2o/deps/mruby-env/src/env.c new file mode 100644 index 00000000..0395e1bc --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby-env/src/env.c @@ -0,0 +1,243 @@ +/* +** env.c - ENV is a Hash-like accessor for environment variables. +** +*/ + +#include "mruby.h" +#include "mruby/hash.h" +#include "mruby/khash.h" +#include "mruby/class.h" +#include "mruby/array.h" +#include "mruby/string.h" +#include "mruby/variable.h" +#include +#include +#include + +#ifdef _WIN32 +int +unsetenv(const char* name) +{ + int r; + char* p = malloc(strlen(name) + 2); + if (!p) return -1; + strcpy(p, name); + strcat(p, "="); + r = _putenv(p); + free(p); + return r; +} + +int +setenv(const char* name, const char* value, int overwrite) +{ + int r; + char* p = malloc(strlen(name) + strlen(value) + 2); + if (!p) return -1; + strcpy(p, name); + strcat(p, "="); + strcat(p, value); + r = _putenv(p); + free(p); + return r; +} +#define environ _environ +#else +extern char **environ; +#endif + + +mrb_value +mrb_env_aget(mrb_state *mrb, mrb_value self) +{ + mrb_value key; + const char *cname, *cvalue; + + mrb_get_args(mrb, "S", &key); + cname = mrb_string_value_cstr(mrb, &key); + cvalue = getenv(cname); + if (cvalue != NULL) { + return mrb_str_new_cstr(mrb, cvalue); + } else { + return mrb_nil_value(); + } +} + +mrb_value +mrb_env_has_key(mrb_state *mrb, mrb_value self) +{ + mrb_value name; + const char *key; + mrb_get_args(mrb, "S", &name); + key = mrb_str_to_cstr(mrb, name); + if (getenv(key) != NULL) { + return mrb_true_value(); + } else { + return mrb_false_value(); + } +} + +mrb_value +mrb_env_keys(mrb_state *mrb, mrb_value self) +{ + int i; + mrb_value ary; + + ary = mrb_ary_new(mrb); + for (i = 0; environ[i] != NULL; i++) { + char *str = strchr(environ[i], '='); + if (str != NULL) { + int len = str - environ[i]; + mrb_ary_push(mrb, ary, mrb_str_new(mrb, environ[i], len)); + } + } + + return ary; +} + +mrb_value +mrb_env_values(mrb_state *mrb, mrb_value self) +{ + int i; + mrb_value ary; + + ary = mrb_ary_new(mrb); + for (i = 0; environ[i] != NULL; i++) { + char *str = strchr(environ[i], '='); + if (str) { + int len; + str++; + len = strlen(str); + mrb_ary_push(mrb, ary, mrb_str_new(mrb, str, len)); + } + } + + return ary; +} + +static mrb_value +mrb_env_size(mrb_state *mrb, mrb_value self) +{ + int i; + + for (i = 0; environ[i] != NULL; i++) + ; + + return mrb_fixnum_value(i); +} + +static mrb_value +mrb_env_to_hash(mrb_state *mrb, mrb_value self) +{ + int i; + mrb_value hash; + + hash = mrb_hash_new(mrb); + for (i = 0; environ[i] != NULL; i++) { + char *str = strchr(environ[i], '='); + if (str != NULL) { + mrb_value val; + int ai = mrb_gc_arena_save(mrb); + int len = str - environ[i]; + mrb_value key = mrb_str_new(mrb, environ[i], len); + str++; + val = mrb_str_new(mrb, str, strlen(str)); + mrb_hash_set(mrb, hash, key, val); + mrb_gc_arena_restore(mrb, ai); + } + } + + return hash; +} + +static mrb_value +mrb_env_to_a(mrb_state *mrb, mrb_value self) +{ + int i; + mrb_value ary; + + ary = mrb_ary_new(mrb); + for (i = 0; environ[i] != NULL; i++) { + char *str = strchr(environ[i], '='); + if (str != NULL) { + int ai = mrb_gc_arena_save(mrb); + mrb_value elem = mrb_ary_new(mrb); + int len = str - environ[i]; + mrb_ary_push(mrb, elem, mrb_str_new(mrb, environ[i], len)); + str++; + mrb_ary_push(mrb, elem, mrb_str_new(mrb, str, strlen(str))); + mrb_ary_push(mrb, ary, elem); + mrb_gc_arena_restore(mrb, ai); + } + } + + return ary; +} + +static mrb_value +mrb_env_inspect(mrb_state *mrb, mrb_value self) +{ + mrb_value hash = mrb_env_to_hash(mrb, self); + return mrb_funcall(mrb, hash, "inspect", 0); +} + +static mrb_value +mrb_env_to_s(mrb_state *mrb, mrb_value self) +{ + return mrb_str_new_cstr(mrb, "ENV"); +} + +static mrb_value +mrb_env_aset(mrb_state *mrb, mrb_value self) +{ + mrb_value name, value; + const char *cname, *cvalue; + + mrb_get_args(mrb, "So", &name, &value); + cname = mrb_string_value_cstr(mrb, &name); + + if (mrb_nil_p(value)) { + if (unsetenv(cname) != 0) { + mrb_raise(mrb, E_RUNTIME_ERROR, "can't delete environment variable"); + } + } else { + mrb_convert_type(mrb, value, MRB_TT_STRING, "String", "to_str"); + cvalue = mrb_string_value_cstr(mrb, &value); + if (setenv(cname, cvalue, 1) != 0) { + mrb_raise(mrb, E_RUNTIME_ERROR, "can't change environment variable"); + } + } + return value; +} + +void +mrb_mruby_env_gem_init(mrb_state *mrb) +{ + struct RObject *e; + + e = (struct RObject*) mrb_obj_alloc(mrb, MRB_TT_OBJECT, mrb->object_class); +#if defined(MRUBY_RELEASE_NO) && MRUBY_RELEASE_NO >= 10000 + mrb_include_module(mrb, (struct RClass*)e, mrb_module_get(mrb, "Enumerable")); +#else + mrb_include_module(mrb, (struct RClass*)e, mrb_class_get(mrb, "Enumerable")); +#endif + + mrb_define_singleton_method(mrb, e,"[]", mrb_env_aget, MRB_ARGS_REQ(1)); + mrb_define_singleton_method(mrb, e,"[]=", mrb_env_aset, MRB_ARGS_REQ(2)); + mrb_define_singleton_method(mrb, e,"has_key?", mrb_env_has_key, MRB_ARGS_REQ(1)); + mrb_define_singleton_method(mrb, e,"inspect", mrb_env_inspect, MRB_ARGS_NONE()); + mrb_define_singleton_method(mrb, e,"keys", mrb_env_keys, MRB_ARGS_NONE()); + mrb_define_singleton_method(mrb, e,"size", mrb_env_size, MRB_ARGS_NONE()); + mrb_define_singleton_method(mrb, e,"store", mrb_env_aset, MRB_ARGS_REQ(2)); + mrb_define_singleton_method(mrb, e,"to_a", mrb_env_to_a, MRB_ARGS_NONE()); + mrb_define_singleton_method(mrb, e,"to_hash", mrb_env_to_hash, MRB_ARGS_NONE()); + mrb_define_singleton_method(mrb, e,"to_s", mrb_env_to_s, MRB_ARGS_NONE()); + mrb_define_singleton_method(mrb, e,"values", mrb_env_values, MRB_ARGS_NONE()); + + mrb_define_global_const(mrb, "ENV", mrb_obj_value(e)); +} + +void +mrb_mruby_env_gem_final(mrb_state *mrb) +{ +} diff --git a/web/server/h2o/libh2o/deps/mruby-env/test/env_test.rb b/web/server/h2o/libh2o/deps/mruby-env/test/env_test.rb new file mode 100644 index 00000000..2aa3dab2 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby-env/test/env_test.rb @@ -0,0 +1,121 @@ +## +# ENV test +# + +if Object.const_defined?(:MTest) + class ENVTest < MTest::Unit::TestCase + def test_env_class + assert_equal(Object, ENV.class) + end + + def setup + @env_hash = ENV.to_hash + ENV.clear + end + + def teardown + ENV.clear + @env_hash.each do |k, v| + ENV[k] = v + end + end + + def set_dummy_env + ENV['FOO'] = 'bar' + end + + def test_size_empty + assert_equal(0, ENV.size) + end + + def test_keys_empty + assert_empty(ENV.keys) + end + + def test_values_empty + assert_empty(ENV.values) + end + + def test_env_to_s_empty + assert_equal("ENV", ENV.to_s) + end + + def test_env_inspect_empty + assert_equal("{}", ENV.inspect) + end + + def test_env_to_hash_empty + assert_equal({}, ENV.to_hash) + end + + def test_env_get_val + set_dummy_env + assert_equal('bar', ENV['FOO']) + end + + def test_env_keys + set_dummy_env + assert_equal(['FOO'], ENV.keys) + end + + def test_env_values + set_dummy_env + assert_equal(['bar'], ENV.values) + end + + def test_env_to_s + set_dummy_env + assert_equal("ENV", ENV.to_s) + end + + def test_env_has_key + set_dummy_env + assert_true ENV.has_key?("FOO") + assert_false ENV.has_key?("BAR") + end + + def test_env_inspect + set_dummy_env + assert_equal("{\"FOO\"=>\"bar\"}", ENV.inspect) + end + + def test_env_delete + set_dummy_env + old = ENV['FOO'] + ret = ENV.delete('FOO') + assert_equal(0, ENV.size) + assert_equal(old, ret) + assert_equal(nil, ENV.delete('nosuchenv')) + end + + def test_env_subst_nil + set_dummy_env + ENV['FOO'] = nil + assert_equal(0, ENV.size) + end + + def test_env_store + ENV['a'] = 'b' + assert_equal 'b', ENV['a'] + + ENV['a'] = 'c' + assert_equal 'c', ENV['a'] + + ENV['a'] = nil + assert_equal nil, ENV['a'] + + ENV['b'] = nil + assert_equal nil, ENV['b'] + assert_equal 0, ENV.size + end + end + + if $ok_test + MTest::Unit.new.mrbtest + else + MTest::Unit.new.run + end +else + $asserts << "test skip of mruby-env/test/env_test.rb" if $asserts +end + diff --git a/web/server/h2o/libh2o/deps/mruby-errno/.gitignore b/web/server/h2o/libh2o/deps/mruby-errno/.gitignore new file mode 100644 index 00000000..ceeb05b4 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby-errno/.gitignore @@ -0,0 +1 @@ +/tmp diff --git a/web/server/h2o/libh2o/deps/mruby-errno/.travis.yml b/web/server/h2o/libh2o/deps/mruby-errno/.travis.yml new file mode 100644 index 00000000..ffe22728 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby-errno/.travis.yml @@ -0,0 +1,2 @@ +script: + - "ruby run_test.rb all test" diff --git a/web/server/h2o/libh2o/deps/mruby-errno/README.md b/web/server/h2o/libh2o/deps/mruby-errno/README.md new file mode 100644 index 00000000..e3c594cb --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby-errno/README.md @@ -0,0 +1,27 @@ +mruby-errno +=========== + +Errno module for mruby + + +## License + +Copyright (c) 2013 Internet Initiative Japan Inc. + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the "Software"), +to deal in the Software without restriction, including without limitation +the rights to use, copy, modify, merge, publish, distribute, sublicense, +and/or sell copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. diff --git a/web/server/h2o/libh2o/deps/mruby-errno/mrbgem.rake b/web/server/h2o/libh2o/deps/mruby-errno/mrbgem.rake new file mode 100644 index 00000000..ba3d60da --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby-errno/mrbgem.rake @@ -0,0 +1,6 @@ +MRuby::Gem::Specification.new('mruby-errno') do |spec| + spec.license = 'MIT' + spec.authors = 'Internet Initiative Japan Inc.' + + spec.cc.include_paths << "#{build.root}/src" +end diff --git a/web/server/h2o/libh2o/deps/mruby-errno/run_test.rb b/web/server/h2o/libh2o/deps/mruby-errno/run_test.rb new file mode 100644 index 00000000..d9566a2a --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby-errno/run_test.rb @@ -0,0 +1,26 @@ +#!/usr/bin/env ruby +# +# mrbgems test runner +# + +gemname = File.basename(File.dirname(File.expand_path __FILE__)) + +if __FILE__ == $0 + repository, dir = 'https://github.com/mruby/mruby.git', 'tmp/mruby' + build_args = ARGV + build_args = ['all', 'test'] if build_args.nil? or build_args.empty? + + Dir.mkdir 'tmp' unless File.exist?('tmp') + unless File.exist?(dir) + system "git clone #{repository} #{dir}" + end + + exit system(%Q[cd #{dir}; MRUBY_CONFIG=#{File.expand_path __FILE__} ruby minirake #{build_args.join(' ')}]) +end + +MRuby::Build.new do |conf| + toolchain :gcc + conf.gembox 'default' + + conf.gem File.expand_path(File.dirname(__FILE__)) +end diff --git a/web/server/h2o/libh2o/deps/mruby-errno/src/errno.c b/web/server/h2o/libh2o/deps/mruby-errno/src/errno.c new file mode 100644 index 00000000..3617efd4 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby-errno/src/errno.c @@ -0,0 +1,175 @@ +#include "mruby.h" +#include "mruby/array.h" +#include "mruby/class.h" +#include "mruby/hash.h" +#include "mruby/numeric.h" +#include "mruby/string.h" +#include "mruby/variable.h" +#include +#include +#include + +#if MRUBY_RELEASE_NO < 10000 +static struct RClass * +mrb_module_get(mrb_state *mrb, const char *name) +{ + return mrb_class_get(mrb, name); +} +#endif + +static mrb_value +mrb_sce_init(mrb_state *mrb, mrb_value self) +{ + mrb_value c, e2c, m, str; + mrb_int n; + int argc, no_errno = 0; + char buf[20]; + + argc = mrb_get_args(mrb, "o|i", &m, &n); + if (argc == 1) { + if (mrb_type(m) == MRB_TT_FIXNUM) { + n = mrb_fixnum(m); + m = mrb_nil_value(); + } else { + no_errno = 1; + } + } + if (!no_errno) { + e2c = mrb_const_get(mrb, mrb_obj_value(mrb_module_get(mrb, "Errno")), mrb_intern_lit(mrb, "Errno2class")); + c = mrb_hash_fetch(mrb, e2c, mrb_fixnum_value(n), mrb_nil_value()); + if (!mrb_nil_p(c)) { + mrb_basic_ptr(self)->c = mrb_class_ptr(c); + str = mrb_str_new_cstr(mrb, strerror(n)); + } else { + mrb_iv_set(mrb, self, mrb_intern_lit(mrb, "errno"), mrb_fixnum_value(n)); + str = mrb_str_new_cstr(mrb, "Unknown error: "); + snprintf(buf, sizeof(buf), "%d", (int)n); + mrb_str_cat2(mrb, str, buf); + } + } else { + str = mrb_str_new_cstr(mrb, "unknown error"); + } + if (!mrb_nil_p(m)) { + mrb_str_cat2(mrb, str, " - "); + mrb_str_append(mrb, str, m); + } + mrb_iv_set(mrb, self, mrb_intern_lit(mrb, "mesg"), str); + return self; +} + +static mrb_value +mrb_sce_errno(mrb_state *mrb, mrb_value self) +{ + struct RClass *c; + mrb_sym sym; + + c = mrb_class(mrb, self); + sym = mrb_intern_lit(mrb, "Errno"); +#if MRUBY_RELEASE_NO < 10000 + if (mrb_const_defined_at(mrb, c, sym)) { +#else + if (mrb_const_defined_at(mrb, mrb_obj_value(c), sym)) { +#endif + return mrb_const_get(mrb, mrb_obj_value(c), sym); + } else { + sym = mrb_intern_lit(mrb, "errno"); + return mrb_attr_get(mrb, self, sym); + } +} + +static mrb_value +mrb_sce_to_s(mrb_state *mrb, mrb_value self) +{ + return mrb_attr_get(mrb, self, mrb_intern_lit(mrb, "mesg")); +} + +static mrb_value +mrb_sce_sys_fail(mrb_state *mrb, mrb_value cls) +{ + struct RClass *cl, *sce; + mrb_value e, msg; + mrb_int no; + int argc; + char name[8]; + + sce = mrb_class_get(mrb, "SystemCallError"); + argc = mrb_get_args(mrb, "i|S", &no, &msg); + if (argc == 1) { + e = mrb_funcall(mrb, mrb_obj_value(sce), "new", 1, mrb_fixnum_value(no)); + } else { + e = mrb_funcall(mrb, mrb_obj_value(sce), "new", 2, msg, mrb_fixnum_value(no)); + } + if (mrb_obj_class(mrb, e) == sce) { + snprintf(name, sizeof(name), "E%03ld", (long)no); + cl = mrb_define_class_under(mrb, mrb_module_get(mrb, "Errno"), name, sce); + mrb_define_const(mrb, cl, "Errno", mrb_fixnum_value(no)); + mrb_basic_ptr(e)->c = cl; + } + mrb_exc_raise(mrb, e); + return mrb_nil_value(); /* NOTREACHED */ +} + +static mrb_value +mrb_exxx_init(mrb_state *mrb, mrb_value self) +{ + mrb_value m, no, str; + + no = mrb_const_get(mrb, mrb_obj_value(mrb_class(mrb, self)), mrb_intern_lit(mrb, "Errno")); + str = mrb_str_new_cstr(mrb, strerror(mrb_fixnum(no))); + + m = mrb_nil_value(); + mrb_get_args(mrb, "|S", &m); + if (!mrb_nil_p(m)) { + mrb_str_cat2(mrb, str, " - "); + mrb_str_append(mrb, str, m); + } + mrb_iv_set(mrb, self, mrb_intern_lit(mrb, "mesg"), str); + return self; +} + +void +mrb_mruby_errno_gem_init(mrb_state *mrb) +{ + struct RClass *e, *eno, *sce, *ste; + mrb_value h, noerror; + + ste = mrb_class_get(mrb, "StandardError"); + + sce = mrb_define_class(mrb, "SystemCallError", ste); + mrb_define_class_method(mrb, sce, "_sys_fail", mrb_sce_sys_fail, MRB_ARGS_REQ(1)); + mrb_define_method(mrb, sce, "errno", mrb_sce_errno, MRB_ARGS_NONE()); + mrb_define_method(mrb, sce, "to_s", mrb_sce_to_s, MRB_ARGS_NONE()); + mrb_define_method(mrb, sce, "initialize", mrb_sce_init, MRB_ARGS_ARG(1, 1)); + + eno = mrb_define_module(mrb, "Errno"); + h = mrb_hash_new(mrb); + mrb_define_const(mrb, eno, "Errno2class", h); + + e = mrb_define_class_under(mrb, eno, "NOERROR", sce); + mrb_define_const(mrb, e, "Errno", mrb_fixnum_value(0)); + mrb_define_method(mrb, e, "initialize", mrb_exxx_init, MRB_ARGS_OPT(1)); + //mrb_define_method(mrb, e, "===", mrb_exxx_cmp, MRB_ARGS_REQ(1)); + noerror = mrb_obj_value(e); + +#define itsdefined(SYM) \ + do { \ + int ai = mrb_gc_arena_save(mrb); \ + e = mrb_define_class_under(mrb, eno, #SYM, sce); \ + mrb_define_const(mrb, e, "Errno", mrb_fixnum_value(SYM)); \ + mrb_define_method(mrb, e, "initialize", mrb_exxx_init, MRB_ARGS_OPT(1)); \ + mrb_hash_set(mrb, h, mrb_fixnum_value(SYM), mrb_obj_value(e)); \ + mrb_gc_arena_restore(mrb, ai); \ + } while (0) + +#define itsnotdefined(SYM) \ + do { \ + mrb_define_const(mrb, eno, #SYM, noerror); \ + } while (0) + +#include "known_errors_def.cstub" +} + +void +mrb_mruby_errno_gem_final(mrb_state *mrb) +{ +} diff --git a/web/server/h2o/libh2o/deps/mruby-errno/src/gen.rb b/web/server/h2o/libh2o/deps/mruby-errno/src/gen.rb new file mode 100755 index 00000000..12e6b302 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby-errno/src/gen.rb @@ -0,0 +1,25 @@ +#!/usr/bin/env ruby + +Dir.chdir(File.dirname($0)) + +e = File.open("known_errors_e2c.cstub", "w") +d = File.open("known_errors_def.cstub", "w") + +IO.readlines("known_errors.def").each { |name| + next if name =~ /^#/ + name.strip! + + e.write < device id +stat.dev_major #=> device major id +stat.dev_minor #=> device minor id +stat.ino #=> i-node number +stat.mode #=> permission value (st_mode) +stat.nlink #=> hard link count +stat.uid #=> user id +stat.gid #=> group id +stat.rdev #=> device type +stat.rdev_major #=> rdev major id +stat.rdev_minor #=> rdev minor id +stat.atime #=> last access time +stat.mtime #=> last modify time +stat.ctime #=> last change attribute time +stat.birthtime #=> file created time +stat.size #=> file size(byte) +stat.blksize #=> file I/O block size +stat.blocks #=> attached block num +stat.grpowned #=> same gid? +stat.<=> #=> comparate mtime (-1,0,1 or nil) +stat.size? +stat.zero? +stat.symlink? +stat.file? +stat.directory? +stat.chardev? +stat.blockdev? +stat.pipe? +stat.socket? +stat.owned? +stat.owned_real? +stat.readable? +stat.readable_real? +stat.writable? +stat.writable_real? +stat.executable? +stat.executable_real? +stat.world_readable? +stat.world_writable? +stat.setuid? +stat.setgid? +stat.sticky? +stat.ftype #=> socket, link, file, blockSpecial, directory, characterSpecial, fifo or unknown +``` + +This library is wrap of struct stat. + +## Installation + +### use github repository + +Write in /mruby/build_config.rb + +```ruby +MRuby::Build.new do |conf| + # by mgem + conf.gem :mgem => 'mruby-file-stat' + # by github + conf.gem :github => 'ksss/mruby-file-stat', :branch => 'master' +end +``` + +## Homepage + +https://github.com/ksss/mruby-file-stat + +## License + +See [https://github.com/ruby/ruby/blob/trunk/file.c](https://github.com/ruby/ruby/blob/trunk/file.c) + +## Doc + +[http://ruby-doc.org/core-2.1.5/File/Stat.html](http://ruby-doc.org/core-2.1.5/File/Stat.html) diff --git a/web/server/h2o/libh2o/deps/mruby-file-stat/appveyor.yml b/web/server/h2o/libh2o/deps/mruby-file-stat/appveyor.yml new file mode 100644 index 00000000..f47afa99 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby-file-stat/appveyor.yml @@ -0,0 +1,19 @@ +--- +version: "#{build}" +environment: + MRUBY_CONFIG: "C:/projects/mruby-file-stat/.travis_build_config.rb" + matrix: + - Compiler: mingw + +install: + - SET PATH=C:\Ruby%ruby_version%\bin;%PATH% + - set PATH=C:\MinGW\bin;C:\MinGW\msys\1.0\bin;%PATH% + - ruby --version + - gem --version + - gcc --version + - gem install rake --force + - cd .. + - git clone --depth 1 https://github.com/mruby/mruby.git + - cd mruby +build_script: + - ruby minirake all test --trace --verbose diff --git a/web/server/h2o/libh2o/deps/mruby-file-stat/config.h.in b/web/server/h2o/libh2o/deps/mruby-file-stat/config.h.in new file mode 100644 index 00000000..27cc7e6f --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby-file-stat/config.h.in @@ -0,0 +1,19 @@ +/* config.h.in. Generated from configure.ac by autoheader. */ + +/* Define to 1 if your system has a working `getgroups' function. */ +#undef HAVE_GETGROUPS + +/* Define to 1 if you have the `lstat' function. */ +#undef HAVE_LSTAT + +/* Define to 1 if `st_blksize' is a member of `struct stat'. */ +#undef HAVE_STRUCT_STAT_ST_BLKSIZE + +/* Define to 1 if `st_blocks' is a member of `struct stat'. */ +#undef HAVE_STRUCT_STAT_ST_BLOCKS + +/* Define to 1 if `st_rdev' is a member of `struct stat'. */ +#undef HAVE_STRUCT_STAT_ST_RDEV + +/* Define to 1 if `st_birthtimespec' is a member of `struct stat'. */ +#undef HAVE_STRUCT_STAT_ST_BIRTHTIMESPEC diff --git a/web/server/h2o/libh2o/deps/mruby-file-stat/configure b/web/server/h2o/libh2o/deps/mruby-file-stat/configure new file mode 100755 index 00000000..517c66c4 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby-file-stat/configure @@ -0,0 +1,4320 @@ +#! /bin/sh +# Guess values for system-dependent variables and create Makefiles. +# Generated by GNU Autoconf 2.69. +# +# +# Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc. +# +# +# This configure script is free software; the Free Software Foundation +# gives unlimited permission to copy, distribute and modify it. +## -------------------- ## +## M4sh Initialization. ## +## -------------------- ## + +# Be more Bourne compatible +DUALCASE=1; export DUALCASE # for MKS sh +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : + emulate sh + NULLCMD=: + # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in #( + *posix*) : + set -o posix ;; #( + *) : + ;; +esac +fi + + +as_nl=' +' +export as_nl +# Printing a long string crashes Solaris 7 /usr/bin/printf. +as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo +# Prefer a ksh shell builtin over an external printf program on Solaris, +# but without wasting forks for bash or zsh. +if test -z "$BASH_VERSION$ZSH_VERSION" \ + && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='print -r --' + as_echo_n='print -rn --' +elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='printf %s\n' + as_echo_n='printf %s' +else + if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then + as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' + as_echo_n='/usr/ucb/echo -n' + else + as_echo_body='eval expr "X$1" : "X\\(.*\\)"' + as_echo_n_body='eval + arg=$1; + case $arg in #( + *"$as_nl"*) + expr "X$arg" : "X\\(.*\\)$as_nl"; + arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; + esac; + expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" + ' + export as_echo_n_body + as_echo_n='sh -c $as_echo_n_body as_echo' + fi + export as_echo_body + as_echo='sh -c $as_echo_body as_echo' +fi + +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + PATH_SEPARATOR=: + (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { + (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || + PATH_SEPARATOR=';' + } +fi + + +# IFS +# We need space, tab and new line, in precisely that order. Quoting is +# there to prevent editors from complaining about space-tab. +# (If _AS_PATH_WALK were called with IFS unset, it would disable word +# splitting by setting IFS to empty value.) +IFS=" "" $as_nl" + +# Find who we are. Look in the path if we contain no directory separator. +as_myself= +case $0 in #(( + *[\\/]* ) as_myself=$0 ;; + *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break + done +IFS=$as_save_IFS + + ;; +esac +# We did not find ourselves, most probably we were run as `sh COMMAND' +# in which case we are not to be found in the path. +if test "x$as_myself" = x; then + as_myself=$0 +fi +if test ! -f "$as_myself"; then + $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 + exit 1 +fi + +# Unset variables that we do not need and which cause bugs (e.g. in +# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" +# suppresses any "Segmentation fault" message there. '((' could +# trigger a bug in pdksh 5.2.14. +for as_var in BASH_ENV ENV MAIL MAILPATH +do eval test x\${$as_var+set} = xset \ + && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : +done +PS1='$ ' +PS2='> ' +PS4='+ ' + +# NLS nuisances. +LC_ALL=C +export LC_ALL +LANGUAGE=C +export LANGUAGE + +# CDPATH. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + +# Use a proper internal environment variable to ensure we don't fall + # into an infinite loop, continuously re-executing ourselves. + if test x"${_as_can_reexec}" != xno && test "x$CONFIG_SHELL" != x; then + _as_can_reexec=no; export _as_can_reexec; + # We cannot yet assume a decent shell, so we have to provide a +# neutralization value for shells without unset; and this also +# works around shells that cannot unset nonexistent variables. +# Preserve -v and -x to the replacement shell. +BASH_ENV=/dev/null +ENV=/dev/null +(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV +case $- in # (((( + *v*x* | *x*v* ) as_opts=-vx ;; + *v* ) as_opts=-v ;; + *x* ) as_opts=-x ;; + * ) as_opts= ;; +esac +exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} +# Admittedly, this is quite paranoid, since all the known shells bail +# out after a failed `exec'. +$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2 +as_fn_exit 255 + fi + # We don't want this to propagate to other subprocesses. + { _as_can_reexec=; unset _as_can_reexec;} +if test "x$CONFIG_SHELL" = x; then + as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then : + emulate sh + NULLCMD=: + # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which + # is contrary to our usage. Disable this feature. + alias -g '\${1+\"\$@\"}'='\"\$@\"' + setopt NO_GLOB_SUBST +else + case \`(set -o) 2>/dev/null\` in #( + *posix*) : + set -o posix ;; #( + *) : + ;; +esac +fi +" + as_required="as_fn_return () { (exit \$1); } +as_fn_success () { as_fn_return 0; } +as_fn_failure () { as_fn_return 1; } +as_fn_ret_success () { return 0; } +as_fn_ret_failure () { return 1; } + +exitcode=0 +as_fn_success || { exitcode=1; echo as_fn_success failed.; } +as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; } +as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; } +as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; } +if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then : + +else + exitcode=1; echo positional parameters were not saved. +fi +test x\$exitcode = x0 || exit 1 +test -x / || exit 1" + as_suggested=" as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO + as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO + eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" && + test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1 +test \$(( 1 + 1 )) = 2 || exit 1" + if (eval "$as_required") 2>/dev/null; then : + as_have_required=yes +else + as_have_required=no +fi + if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null; then : + +else + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +as_found=false +for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + as_found=: + case $as_dir in #( + /*) + for as_base in sh bash ksh sh5; do + # Try only shells that exist, to save several forks. + as_shell=$as_dir/$as_base + if { test -f "$as_shell" || test -f "$as_shell.exe"; } && + { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$as_shell"; } 2>/dev/null; then : + CONFIG_SHELL=$as_shell as_have_required=yes + if { $as_echo "$as_bourne_compatible""$as_suggested" | as_run=a "$as_shell"; } 2>/dev/null; then : + break 2 +fi +fi + done;; + esac + as_found=false +done +$as_found || { if { test -f "$SHELL" || test -f "$SHELL.exe"; } && + { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$SHELL"; } 2>/dev/null; then : + CONFIG_SHELL=$SHELL as_have_required=yes +fi; } +IFS=$as_save_IFS + + + if test "x$CONFIG_SHELL" != x; then : + export CONFIG_SHELL + # We cannot yet assume a decent shell, so we have to provide a +# neutralization value for shells without unset; and this also +# works around shells that cannot unset nonexistent variables. +# Preserve -v and -x to the replacement shell. +BASH_ENV=/dev/null +ENV=/dev/null +(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV +case $- in # (((( + *v*x* | *x*v* ) as_opts=-vx ;; + *v* ) as_opts=-v ;; + *x* ) as_opts=-x ;; + * ) as_opts= ;; +esac +exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} +# Admittedly, this is quite paranoid, since all the known shells bail +# out after a failed `exec'. +$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2 +exit 255 +fi + + if test x$as_have_required = xno; then : + $as_echo "$0: This script requires a shell more modern than all" + $as_echo "$0: the shells that I found on your system." + if test x${ZSH_VERSION+set} = xset ; then + $as_echo "$0: In particular, zsh $ZSH_VERSION has bugs and should" + $as_echo "$0: be upgraded to zsh 4.3.4 or later." + else + $as_echo "$0: Please tell bug-autoconf@gnu.org about your system, +$0: including any error possibly output before this +$0: message. Then install a modern shell, or manually run +$0: the script under such a shell if you do have one." + fi + exit 1 +fi +fi +fi +SHELL=${CONFIG_SHELL-/bin/sh} +export SHELL +# Unset more variables known to interfere with behavior of common tools. +CLICOLOR_FORCE= GREP_OPTIONS= +unset CLICOLOR_FORCE GREP_OPTIONS + +## --------------------- ## +## M4sh Shell Functions. ## +## --------------------- ## +# as_fn_unset VAR +# --------------- +# Portably unset VAR. +as_fn_unset () +{ + { eval $1=; unset $1;} +} +as_unset=as_fn_unset + +# as_fn_set_status STATUS +# ----------------------- +# Set $? to STATUS, without forking. +as_fn_set_status () +{ + return $1 +} # as_fn_set_status + +# as_fn_exit STATUS +# ----------------- +# Exit the shell with STATUS, even in a "trap 0" or "set -e" context. +as_fn_exit () +{ + set +e + as_fn_set_status $1 + exit $1 +} # as_fn_exit + +# as_fn_mkdir_p +# ------------- +# Create "$as_dir" as a directory, including parents if necessary. +as_fn_mkdir_p () +{ + + case $as_dir in #( + -*) as_dir=./$as_dir;; + esac + test -d "$as_dir" || eval $as_mkdir_p || { + as_dirs= + while :; do + case $as_dir in #( + *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( + *) as_qdir=$as_dir;; + esac + as_dirs="'$as_qdir' $as_dirs" + as_dir=`$as_dirname -- "$as_dir" || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + test -d "$as_dir" && break + done + test -z "$as_dirs" || eval "mkdir $as_dirs" + } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" + + +} # as_fn_mkdir_p + +# as_fn_executable_p FILE +# ----------------------- +# Test if FILE is an executable regular file. +as_fn_executable_p () +{ + test -f "$1" && test -x "$1" +} # as_fn_executable_p +# as_fn_append VAR VALUE +# ---------------------- +# Append the text in VALUE to the end of the definition contained in VAR. Take +# advantage of any shell optimizations that allow amortized linear growth over +# repeated appends, instead of the typical quadratic growth present in naive +# implementations. +if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : + eval 'as_fn_append () + { + eval $1+=\$2 + }' +else + as_fn_append () + { + eval $1=\$$1\$2 + } +fi # as_fn_append + +# as_fn_arith ARG... +# ------------------ +# Perform arithmetic evaluation on the ARGs, and store the result in the +# global $as_val. Take advantage of shells that can avoid forks. The arguments +# must be portable across $(()) and expr. +if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : + eval 'as_fn_arith () + { + as_val=$(( $* )) + }' +else + as_fn_arith () + { + as_val=`expr "$@" || test $? -eq 1` + } +fi # as_fn_arith + + +# as_fn_error STATUS ERROR [LINENO LOG_FD] +# ---------------------------------------- +# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are +# provided, also output the error to LOG_FD, referencing LINENO. Then exit the +# script with STATUS, using 1 if that was 0. +as_fn_error () +{ + as_status=$1; test $as_status -eq 0 && as_status=1 + if test "$4"; then + as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 + fi + $as_echo "$as_me: error: $2" >&2 + as_fn_exit $as_status +} # as_fn_error + +if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; then + as_expr=expr +else + as_expr=false +fi + +if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then + as_basename=basename +else + as_basename=false +fi + +if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then + as_dirname=dirname +else + as_dirname=false +fi + +as_me=`$as_basename -- "$0" || +$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ + s//\1/ + q + } + /^X\/\(\/\/\)$/{ + s//\1/ + q + } + /^X\/\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + +# Avoid depending upon Character Ranges. +as_cr_letters='abcdefghijklmnopqrstuvwxyz' +as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' +as_cr_Letters=$as_cr_letters$as_cr_LETTERS +as_cr_digits='0123456789' +as_cr_alnum=$as_cr_Letters$as_cr_digits + + + as_lineno_1=$LINENO as_lineno_1a=$LINENO + as_lineno_2=$LINENO as_lineno_2a=$LINENO + eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" && + test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || { + # Blame Lee E. McMahon (1931-1989) for sed's syntax. :-) + sed -n ' + p + /[$]LINENO/= + ' <$as_myself | + sed ' + s/[$]LINENO.*/&-/ + t lineno + b + :lineno + N + :loop + s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ + t loop + s/-\n.*// + ' >$as_me.lineno && + chmod +x "$as_me.lineno" || + { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; } + + # If we had to re-execute with $CONFIG_SHELL, we're ensured to have + # already done that, so ensure we don't try to do so again and fall + # in an infinite loop. This has already happened in practice. + _as_can_reexec=no; export _as_can_reexec + # Don't try to exec as it changes $[0], causing all sort of problems + # (the dirname of $[0] is not the place where we might find the + # original and so on. Autoconf is especially sensitive to this). + . "./$as_me.lineno" + # Exit status is that of the last command. + exit +} + +ECHO_C= ECHO_N= ECHO_T= +case `echo -n x` in #((((( +-n*) + case `echo 'xy\c'` in + *c*) ECHO_T=' ';; # ECHO_T is single tab character. + xy) ECHO_C='\c';; + *) echo `echo ksh88 bug on AIX 6.1` > /dev/null + ECHO_T=' ';; + esac;; +*) + ECHO_N='-n';; +esac + +rm -f conf$$ conf$$.exe conf$$.file +if test -d conf$$.dir; then + rm -f conf$$.dir/conf$$.file +else + rm -f conf$$.dir + mkdir conf$$.dir 2>/dev/null +fi +if (echo >conf$$.file) 2>/dev/null; then + if ln -s conf$$.file conf$$ 2>/dev/null; then + as_ln_s='ln -s' + # ... but there are two gotchas: + # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. + # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. + # In both cases, we have to default to `cp -pR'. + ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || + as_ln_s='cp -pR' + elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln + else + as_ln_s='cp -pR' + fi +else + as_ln_s='cp -pR' +fi +rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file +rmdir conf$$.dir 2>/dev/null + +if mkdir -p . 2>/dev/null; then + as_mkdir_p='mkdir -p "$as_dir"' +else + test -d ./-p && rmdir ./-p + as_mkdir_p=false +fi + +as_test_x='test -x' +as_executable_p=as_fn_executable_p + +# Sed expression to map a string onto a valid CPP name. +as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" + +# Sed expression to map a string onto a valid variable name. +as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" + + +test -n "$DJDIR" || exec 7<&0 &1 + +# Name of the host. +# hostname on some systems (SVR3.2, old GNU/Linux) returns a bogus exit status, +# so uname gets run too. +ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` + +# +# Initializations. +# +ac_default_prefix=/usr/local +ac_clean_files= +ac_config_libobj_dir=. +LIBOBJS= +cross_compiling=no +subdirs= +MFLAGS= +MAKEFLAGS= + +# Identity of this package. +PACKAGE_NAME= +PACKAGE_TARNAME= +PACKAGE_VERSION= +PACKAGE_STRING= +PACKAGE_BUGREPORT= +PACKAGE_URL= + +ac_unique_file="src/file-stat.c" +# Factoring default headers for most tests. +ac_includes_default="\ +#include +#ifdef HAVE_SYS_TYPES_H +# include +#endif +#ifdef HAVE_SYS_STAT_H +# include +#endif +#ifdef STDC_HEADERS +# include +# include +#else +# ifdef HAVE_STDLIB_H +# include +# endif +#endif +#ifdef HAVE_STRING_H +# if !defined STDC_HEADERS && defined HAVE_MEMORY_H +# include +# endif +# include +#endif +#ifdef HAVE_STRINGS_H +# include +#endif +#ifdef HAVE_INTTYPES_H +# include +#endif +#ifdef HAVE_STDINT_H +# include +#endif +#ifdef HAVE_UNISTD_H +# include +#endif" + +ac_subst_vars='LTLIBOBJS +LIBOBJS +EGREP +GREP +CPP +OBJEXT +EXEEXT +ac_ct_CC +CPPFLAGS +LDFLAGS +CFLAGS +CC +target_alias +host_alias +build_alias +LIBS +ECHO_T +ECHO_N +ECHO_C +DEFS +mandir +localedir +libdir +psdir +pdfdir +dvidir +htmldir +infodir +docdir +oldincludedir +includedir +localstatedir +sharedstatedir +sysconfdir +datadir +datarootdir +libexecdir +sbindir +bindir +program_transform_name +prefix +exec_prefix +PACKAGE_URL +PACKAGE_BUGREPORT +PACKAGE_STRING +PACKAGE_VERSION +PACKAGE_TARNAME +PACKAGE_NAME +PATH_SEPARATOR +SHELL' +ac_subst_files='' +ac_user_opts=' +enable_option_checking +' + ac_precious_vars='build_alias +host_alias +target_alias +CC +CFLAGS +LDFLAGS +LIBS +CPPFLAGS +CPP' + + +# Initialize some variables set by options. +ac_init_help= +ac_init_version=false +ac_unrecognized_opts= +ac_unrecognized_sep= +# The variables have the same names as the options, with +# dashes changed to underlines. +cache_file=/dev/null +exec_prefix=NONE +no_create= +no_recursion= +prefix=NONE +program_prefix=NONE +program_suffix=NONE +program_transform_name=s,x,x, +silent= +site= +srcdir= +verbose= +x_includes=NONE +x_libraries=NONE + +# Installation directory options. +# These are left unexpanded so users can "make install exec_prefix=/foo" +# and all the variables that are supposed to be based on exec_prefix +# by default will actually change. +# Use braces instead of parens because sh, perl, etc. also accept them. +# (The list follows the same order as the GNU Coding Standards.) +bindir='${exec_prefix}/bin' +sbindir='${exec_prefix}/sbin' +libexecdir='${exec_prefix}/libexec' +datarootdir='${prefix}/share' +datadir='${datarootdir}' +sysconfdir='${prefix}/etc' +sharedstatedir='${prefix}/com' +localstatedir='${prefix}/var' +includedir='${prefix}/include' +oldincludedir='/usr/include' +docdir='${datarootdir}/doc/${PACKAGE}' +infodir='${datarootdir}/info' +htmldir='${docdir}' +dvidir='${docdir}' +pdfdir='${docdir}' +psdir='${docdir}' +libdir='${exec_prefix}/lib' +localedir='${datarootdir}/locale' +mandir='${datarootdir}/man' + +ac_prev= +ac_dashdash= +for ac_option +do + # If the previous option needs an argument, assign it. + if test -n "$ac_prev"; then + eval $ac_prev=\$ac_option + ac_prev= + continue + fi + + case $ac_option in + *=?*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;; + *=) ac_optarg= ;; + *) ac_optarg=yes ;; + esac + + # Accept the important Cygnus configure options, so we can diagnose typos. + + case $ac_dashdash$ac_option in + --) + ac_dashdash=yes ;; + + -bindir | --bindir | --bindi | --bind | --bin | --bi) + ac_prev=bindir ;; + -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) + bindir=$ac_optarg ;; + + -build | --build | --buil | --bui | --bu) + ac_prev=build_alias ;; + -build=* | --build=* | --buil=* | --bui=* | --bu=*) + build_alias=$ac_optarg ;; + + -cache-file | --cache-file | --cache-fil | --cache-fi \ + | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) + ac_prev=cache_file ;; + -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ + | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) + cache_file=$ac_optarg ;; + + --config-cache | -C) + cache_file=config.cache ;; + + -datadir | --datadir | --datadi | --datad) + ac_prev=datadir ;; + -datadir=* | --datadir=* | --datadi=* | --datad=*) + datadir=$ac_optarg ;; + + -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \ + | --dataroo | --dataro | --datar) + ac_prev=datarootdir ;; + -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \ + | --dataroot=* | --dataroo=* | --dataro=* | --datar=*) + datarootdir=$ac_optarg ;; + + -disable-* | --disable-*) + ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid feature name: $ac_useropt" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"enable_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval enable_$ac_useropt=no ;; + + -docdir | --docdir | --docdi | --doc | --do) + ac_prev=docdir ;; + -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*) + docdir=$ac_optarg ;; + + -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv) + ac_prev=dvidir ;; + -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*) + dvidir=$ac_optarg ;; + + -enable-* | --enable-*) + ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid feature name: $ac_useropt" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"enable_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval enable_$ac_useropt=\$ac_optarg ;; + + -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ + | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ + | --exec | --exe | --ex) + ac_prev=exec_prefix ;; + -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ + | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ + | --exec=* | --exe=* | --ex=*) + exec_prefix=$ac_optarg ;; + + -gas | --gas | --ga | --g) + # Obsolete; use --with-gas. + with_gas=yes ;; + + -help | --help | --hel | --he | -h) + ac_init_help=long ;; + -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) + ac_init_help=recursive ;; + -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) + ac_init_help=short ;; + + -host | --host | --hos | --ho) + ac_prev=host_alias ;; + -host=* | --host=* | --hos=* | --ho=*) + host_alias=$ac_optarg ;; + + -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht) + ac_prev=htmldir ;; + -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \ + | --ht=*) + htmldir=$ac_optarg ;; + + -includedir | --includedir | --includedi | --included | --include \ + | --includ | --inclu | --incl | --inc) + ac_prev=includedir ;; + -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ + | --includ=* | --inclu=* | --incl=* | --inc=*) + includedir=$ac_optarg ;; + + -infodir | --infodir | --infodi | --infod | --info | --inf) + ac_prev=infodir ;; + -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) + infodir=$ac_optarg ;; + + -libdir | --libdir | --libdi | --libd) + ac_prev=libdir ;; + -libdir=* | --libdir=* | --libdi=* | --libd=*) + libdir=$ac_optarg ;; + + -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ + | --libexe | --libex | --libe) + ac_prev=libexecdir ;; + -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ + | --libexe=* | --libex=* | --libe=*) + libexecdir=$ac_optarg ;; + + -localedir | --localedir | --localedi | --localed | --locale) + ac_prev=localedir ;; + -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*) + localedir=$ac_optarg ;; + + -localstatedir | --localstatedir | --localstatedi | --localstated \ + | --localstate | --localstat | --localsta | --localst | --locals) + ac_prev=localstatedir ;; + -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ + | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*) + localstatedir=$ac_optarg ;; + + -mandir | --mandir | --mandi | --mand | --man | --ma | --m) + ac_prev=mandir ;; + -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) + mandir=$ac_optarg ;; + + -nfp | --nfp | --nf) + # Obsolete; use --without-fp. + with_fp=no ;; + + -no-create | --no-create | --no-creat | --no-crea | --no-cre \ + | --no-cr | --no-c | -n) + no_create=yes ;; + + -no-recursion | --no-recursion | --no-recursio | --no-recursi \ + | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) + no_recursion=yes ;; + + -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ + | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ + | --oldin | --oldi | --old | --ol | --o) + ac_prev=oldincludedir ;; + -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ + | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ + | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) + oldincludedir=$ac_optarg ;; + + -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) + ac_prev=prefix ;; + -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) + prefix=$ac_optarg ;; + + -program-prefix | --program-prefix | --program-prefi | --program-pref \ + | --program-pre | --program-pr | --program-p) + ac_prev=program_prefix ;; + -program-prefix=* | --program-prefix=* | --program-prefi=* \ + | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) + program_prefix=$ac_optarg ;; + + -program-suffix | --program-suffix | --program-suffi | --program-suff \ + | --program-suf | --program-su | --program-s) + ac_prev=program_suffix ;; + -program-suffix=* | --program-suffix=* | --program-suffi=* \ + | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) + program_suffix=$ac_optarg ;; + + -program-transform-name | --program-transform-name \ + | --program-transform-nam | --program-transform-na \ + | --program-transform-n | --program-transform- \ + | --program-transform | --program-transfor \ + | --program-transfo | --program-transf \ + | --program-trans | --program-tran \ + | --progr-tra | --program-tr | --program-t) + ac_prev=program_transform_name ;; + -program-transform-name=* | --program-transform-name=* \ + | --program-transform-nam=* | --program-transform-na=* \ + | --program-transform-n=* | --program-transform-=* \ + | --program-transform=* | --program-transfor=* \ + | --program-transfo=* | --program-transf=* \ + | --program-trans=* | --program-tran=* \ + | --progr-tra=* | --program-tr=* | --program-t=*) + program_transform_name=$ac_optarg ;; + + -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd) + ac_prev=pdfdir ;; + -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*) + pdfdir=$ac_optarg ;; + + -psdir | --psdir | --psdi | --psd | --ps) + ac_prev=psdir ;; + -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*) + psdir=$ac_optarg ;; + + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + silent=yes ;; + + -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) + ac_prev=sbindir ;; + -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ + | --sbi=* | --sb=*) + sbindir=$ac_optarg ;; + + -sharedstatedir | --sharedstatedir | --sharedstatedi \ + | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ + | --sharedst | --shareds | --shared | --share | --shar \ + | --sha | --sh) + ac_prev=sharedstatedir ;; + -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ + | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ + | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ + | --sha=* | --sh=*) + sharedstatedir=$ac_optarg ;; + + -site | --site | --sit) + ac_prev=site ;; + -site=* | --site=* | --sit=*) + site=$ac_optarg ;; + + -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) + ac_prev=srcdir ;; + -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) + srcdir=$ac_optarg ;; + + -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ + | --syscon | --sysco | --sysc | --sys | --sy) + ac_prev=sysconfdir ;; + -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ + | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) + sysconfdir=$ac_optarg ;; + + -target | --target | --targe | --targ | --tar | --ta | --t) + ac_prev=target_alias ;; + -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) + target_alias=$ac_optarg ;; + + -v | -verbose | --verbose | --verbos | --verbo | --verb) + verbose=yes ;; + + -version | --version | --versio | --versi | --vers | -V) + ac_init_version=: ;; + + -with-* | --with-*) + ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid package name: $ac_useropt" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"with_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval with_$ac_useropt=\$ac_optarg ;; + + -without-* | --without-*) + ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid package name: $ac_useropt" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"with_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval with_$ac_useropt=no ;; + + --x) + # Obsolete; use --with-x. + with_x=yes ;; + + -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ + | --x-incl | --x-inc | --x-in | --x-i) + ac_prev=x_includes ;; + -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ + | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) + x_includes=$ac_optarg ;; + + -x-libraries | --x-libraries | --x-librarie | --x-librari \ + | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) + ac_prev=x_libraries ;; + -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ + | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) + x_libraries=$ac_optarg ;; + + -*) as_fn_error $? "unrecognized option: \`$ac_option' +Try \`$0 --help' for more information" + ;; + + *=*) + ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` + # Reject names that are not valid shell variable names. + case $ac_envvar in #( + '' | [0-9]* | *[!_$as_cr_alnum]* ) + as_fn_error $? "invalid variable name: \`$ac_envvar'" ;; + esac + eval $ac_envvar=\$ac_optarg + export $ac_envvar ;; + + *) + # FIXME: should be removed in autoconf 3.0. + $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2 + expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && + $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2 + : "${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}" + ;; + + esac +done + +if test -n "$ac_prev"; then + ac_option=--`echo $ac_prev | sed 's/_/-/g'` + as_fn_error $? "missing argument to $ac_option" +fi + +if test -n "$ac_unrecognized_opts"; then + case $enable_option_checking in + no) ;; + fatal) as_fn_error $? "unrecognized options: $ac_unrecognized_opts" ;; + *) $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;; + esac +fi + +# Check all directory arguments for consistency. +for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ + datadir sysconfdir sharedstatedir localstatedir includedir \ + oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ + libdir localedir mandir +do + eval ac_val=\$$ac_var + # Remove trailing slashes. + case $ac_val in + */ ) + ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'` + eval $ac_var=\$ac_val;; + esac + # Be sure to have absolute directory names. + case $ac_val in + [\\/$]* | ?:[\\/]* ) continue;; + NONE | '' ) case $ac_var in *prefix ) continue;; esac;; + esac + as_fn_error $? "expected an absolute directory name for --$ac_var: $ac_val" +done + +# There might be people who depend on the old broken behavior: `$host' +# used to hold the argument of --host etc. +# FIXME: To remove some day. +build=$build_alias +host=$host_alias +target=$target_alias + +# FIXME: To remove some day. +if test "x$host_alias" != x; then + if test "x$build_alias" = x; then + cross_compiling=maybe + elif test "x$build_alias" != "x$host_alias"; then + cross_compiling=yes + fi +fi + +ac_tool_prefix= +test -n "$host_alias" && ac_tool_prefix=$host_alias- + +test "$silent" = yes && exec 6>/dev/null + + +ac_pwd=`pwd` && test -n "$ac_pwd" && +ac_ls_di=`ls -di .` && +ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` || + as_fn_error $? "working directory cannot be determined" +test "X$ac_ls_di" = "X$ac_pwd_ls_di" || + as_fn_error $? "pwd does not report name of working directory" + + +# Find the source files, if location was not specified. +if test -z "$srcdir"; then + ac_srcdir_defaulted=yes + # Try the directory containing this script, then the parent directory. + ac_confdir=`$as_dirname -- "$as_myself" || +$as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_myself" : 'X\(//\)[^/]' \| \ + X"$as_myself" : 'X\(//\)$' \| \ + X"$as_myself" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$as_myself" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + srcdir=$ac_confdir + if test ! -r "$srcdir/$ac_unique_file"; then + srcdir=.. + fi +else + ac_srcdir_defaulted=no +fi +if test ! -r "$srcdir/$ac_unique_file"; then + test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .." + as_fn_error $? "cannot find sources ($ac_unique_file) in $srcdir" +fi +ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work" +ac_abs_confdir=`( + cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error $? "$ac_msg" + pwd)` +# When building in place, set srcdir=. +if test "$ac_abs_confdir" = "$ac_pwd"; then + srcdir=. +fi +# Remove unnecessary trailing slashes from srcdir. +# Double slashes in file names in object file debugging info +# mess up M-x gdb in Emacs. +case $srcdir in +*/) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;; +esac +for ac_var in $ac_precious_vars; do + eval ac_env_${ac_var}_set=\${${ac_var}+set} + eval ac_env_${ac_var}_value=\$${ac_var} + eval ac_cv_env_${ac_var}_set=\${${ac_var}+set} + eval ac_cv_env_${ac_var}_value=\$${ac_var} +done + +# +# Report the --help message. +# +if test "$ac_init_help" = "long"; then + # Omit some internal or obsolete options to make the list less imposing. + # This message is too long to be a string in the A/UX 3.1 sh. + cat <<_ACEOF +\`configure' configures this package to adapt to many kinds of systems. + +Usage: $0 [OPTION]... [VAR=VALUE]... + +To assign environment variables (e.g., CC, CFLAGS...), specify them as +VAR=VALUE. See below for descriptions of some of the useful variables. + +Defaults for the options are specified in brackets. + +Configuration: + -h, --help display this help and exit + --help=short display options specific to this package + --help=recursive display the short help of all the included packages + -V, --version display version information and exit + -q, --quiet, --silent do not print \`checking ...' messages + --cache-file=FILE cache test results in FILE [disabled] + -C, --config-cache alias for \`--cache-file=config.cache' + -n, --no-create do not create output files + --srcdir=DIR find the sources in DIR [configure dir or \`..'] + +Installation directories: + --prefix=PREFIX install architecture-independent files in PREFIX + [$ac_default_prefix] + --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX + [PREFIX] + +By default, \`make install' will install all the files in +\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify +an installation prefix other than \`$ac_default_prefix' using \`--prefix', +for instance \`--prefix=\$HOME'. + +For better control, use the options below. + +Fine tuning of the installation directories: + --bindir=DIR user executables [EPREFIX/bin] + --sbindir=DIR system admin executables [EPREFIX/sbin] + --libexecdir=DIR program executables [EPREFIX/libexec] + --sysconfdir=DIR read-only single-machine data [PREFIX/etc] + --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] + --localstatedir=DIR modifiable single-machine data [PREFIX/var] + --libdir=DIR object code libraries [EPREFIX/lib] + --includedir=DIR C header files [PREFIX/include] + --oldincludedir=DIR C header files for non-gcc [/usr/include] + --datarootdir=DIR read-only arch.-independent data root [PREFIX/share] + --datadir=DIR read-only architecture-independent data [DATAROOTDIR] + --infodir=DIR info documentation [DATAROOTDIR/info] + --localedir=DIR locale-dependent data [DATAROOTDIR/locale] + --mandir=DIR man documentation [DATAROOTDIR/man] + --docdir=DIR documentation root [DATAROOTDIR/doc/PACKAGE] + --htmldir=DIR html documentation [DOCDIR] + --dvidir=DIR dvi documentation [DOCDIR] + --pdfdir=DIR pdf documentation [DOCDIR] + --psdir=DIR ps documentation [DOCDIR] +_ACEOF + + cat <<\_ACEOF +_ACEOF +fi + +if test -n "$ac_init_help"; then + + cat <<\_ACEOF + +Some influential environment variables: + CC C compiler command + CFLAGS C compiler flags + LDFLAGS linker flags, e.g. -L if you have libraries in a + nonstandard directory + LIBS libraries to pass to the linker, e.g. -l + CPPFLAGS (Objective) C/C++ preprocessor flags, e.g. -I if + you have headers in a nonstandard directory + CPP C preprocessor + +Use these variables to override the choices made by `configure' or to help +it to find libraries and programs with nonstandard names/locations. + +Report bugs to the package provider. +_ACEOF +ac_status=$? +fi + +if test "$ac_init_help" = "recursive"; then + # If there are subdirs, report their specific --help. + for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue + test -d "$ac_dir" || + { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } || + continue + ac_builddir=. + +case "$ac_dir" in +.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; +*) + ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` + # A ".." for each directory in $ac_dir_suffix. + ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` + case $ac_top_builddir_sub in + "") ac_top_builddir_sub=. ac_top_build_prefix= ;; + *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; + esac ;; +esac +ac_abs_top_builddir=$ac_pwd +ac_abs_builddir=$ac_pwd$ac_dir_suffix +# for backward compatibility: +ac_top_builddir=$ac_top_build_prefix + +case $srcdir in + .) # We are building in place. + ac_srcdir=. + ac_top_srcdir=$ac_top_builddir_sub + ac_abs_top_srcdir=$ac_pwd ;; + [\\/]* | ?:[\\/]* ) # Absolute name. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir + ac_abs_top_srcdir=$srcdir ;; + *) # Relative name. + ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_build_prefix$srcdir + ac_abs_top_srcdir=$ac_pwd/$srcdir ;; +esac +ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix + + cd "$ac_dir" || { ac_status=$?; continue; } + # Check for guested configure. + if test -f "$ac_srcdir/configure.gnu"; then + echo && + $SHELL "$ac_srcdir/configure.gnu" --help=recursive + elif test -f "$ac_srcdir/configure"; then + echo && + $SHELL "$ac_srcdir/configure" --help=recursive + else + $as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 + fi || ac_status=$? + cd "$ac_pwd" || { ac_status=$?; break; } + done +fi + +test -n "$ac_init_help" && exit $ac_status +if $ac_init_version; then + cat <<\_ACEOF +configure +generated by GNU Autoconf 2.69 + +Copyright (C) 2012 Free Software Foundation, Inc. +This configure script is free software; the Free Software Foundation +gives unlimited permission to copy, distribute and modify it. +_ACEOF + exit +fi + +## ------------------------ ## +## Autoconf initialization. ## +## ------------------------ ## + +# ac_fn_c_try_compile LINENO +# -------------------------- +# Try to compile conftest.$ac_ext, and return whether this succeeded. +ac_fn_c_try_compile () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + rm -f conftest.$ac_objext + if { { ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compile") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_c_try_compile + +# ac_fn_c_check_member LINENO AGGR MEMBER VAR INCLUDES +# ---------------------------------------------------- +# Tries to find if the field MEMBER exists in type AGGR, after including +# INCLUDES, setting cache variable VAR accordingly. +ac_fn_c_check_member () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2.$3" >&5 +$as_echo_n "checking for $2.$3... " >&6; } +if eval \${$4+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$5 +int +main () +{ +static $2 ac_aggr; +if (ac_aggr.$3) +return 0; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + eval "$4=yes" +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$5 +int +main () +{ +static $2 ac_aggr; +if (sizeof ac_aggr.$3) +return 0; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + eval "$4=yes" +else + eval "$4=no" +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +eval ac_res=\$$4 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + +} # ac_fn_c_check_member + +# ac_fn_c_try_cpp LINENO +# ---------------------- +# Try to preprocess conftest.$ac_ext, and return whether this succeeded. +ac_fn_c_try_cpp () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + if { { ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } > conftest.i && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_c_try_cpp + +# ac_fn_c_try_run LINENO +# ---------------------- +# Try to link conftest.$ac_ext, and return whether this succeeded. Assumes +# that executables *can* be run. +ac_fn_c_try_run () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + if { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { ac_try='./conftest$ac_exeext' + { { case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; }; then : + ac_retval=0 +else + $as_echo "$as_me: program exited with status $ac_status" >&5 + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=$ac_status +fi + rm -rf conftest.dSYM conftest_ipa8_conftest.oo + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_c_try_run + +# ac_fn_c_check_header_compile LINENO HEADER VAR INCLUDES +# ------------------------------------------------------- +# Tests whether HEADER exists and can be compiled using the include files in +# INCLUDES, setting the cache variable VAR accordingly. +ac_fn_c_check_header_compile () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +#include <$2> +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + eval "$3=yes" +else + eval "$3=no" +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + +} # ac_fn_c_check_header_compile + +# ac_fn_c_try_link LINENO +# ----------------------- +# Try to link conftest.$ac_ext, and return whether this succeeded. +ac_fn_c_try_link () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + rm -f conftest.$ac_objext conftest$ac_exeext + if { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && { + test "$cross_compiling" = yes || + test -x conftest$ac_exeext + }; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information + # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would + # interfere with the next link command; also delete a directory that is + # left behind by Apple's compiler. We do this before executing the actions. + rm -rf conftest.dSYM conftest_ipa8_conftest.oo + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_c_try_link + +# ac_fn_c_check_func LINENO FUNC VAR +# ---------------------------------- +# Tests whether FUNC exists, setting the cache variable VAR accordingly +ac_fn_c_check_func () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +/* Define $2 to an innocuous variant, in case declares $2. + For example, HP-UX 11i declares gettimeofday. */ +#define $2 innocuous_$2 + +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $2 (); below. + Prefer to if __STDC__ is defined, since + exists even on freestanding compilers. */ + +#ifdef __STDC__ +# include +#else +# include +#endif + +#undef $2 + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char $2 (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined __stub_$2 || defined __stub___$2 +choke me +#endif + +int +main () +{ +return $2 (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + eval "$3=yes" +else + eval "$3=no" +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + +} # ac_fn_c_check_func +cat >config.log <<_ACEOF +This file contains any messages produced by compilers while +running configure, to aid debugging if configure makes a mistake. + +It was created by $as_me, which was +generated by GNU Autoconf 2.69. Invocation command line was + + $ $0 $@ + +_ACEOF +exec 5>>config.log +{ +cat <<_ASUNAME +## --------- ## +## Platform. ## +## --------- ## + +hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` +uname -m = `(uname -m) 2>/dev/null || echo unknown` +uname -r = `(uname -r) 2>/dev/null || echo unknown` +uname -s = `(uname -s) 2>/dev/null || echo unknown` +uname -v = `(uname -v) 2>/dev/null || echo unknown` + +/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` +/bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` + +/bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` +/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` +/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` +/usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown` +/bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` +/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` +/bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` + +_ASUNAME + +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + $as_echo "PATH: $as_dir" + done +IFS=$as_save_IFS + +} >&5 + +cat >&5 <<_ACEOF + + +## ----------- ## +## Core tests. ## +## ----------- ## + +_ACEOF + + +# Keep a trace of the command line. +# Strip out --no-create and --no-recursion so they do not pile up. +# Strip out --silent because we don't want to record it for future runs. +# Also quote any args containing shell meta-characters. +# Make two passes to allow for proper duplicate-argument suppression. +ac_configure_args= +ac_configure_args0= +ac_configure_args1= +ac_must_keep_next=false +for ac_pass in 1 2 +do + for ac_arg + do + case $ac_arg in + -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;; + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + continue ;; + *\'*) + ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; + esac + case $ac_pass in + 1) as_fn_append ac_configure_args0 " '$ac_arg'" ;; + 2) + as_fn_append ac_configure_args1 " '$ac_arg'" + if test $ac_must_keep_next = true; then + ac_must_keep_next=false # Got value, back to normal. + else + case $ac_arg in + *=* | --config-cache | -C | -disable-* | --disable-* \ + | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \ + | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \ + | -with-* | --with-* | -without-* | --without-* | --x) + case "$ac_configure_args0 " in + "$ac_configure_args1"*" '$ac_arg' "* ) continue ;; + esac + ;; + -* ) ac_must_keep_next=true ;; + esac + fi + as_fn_append ac_configure_args " '$ac_arg'" + ;; + esac + done +done +{ ac_configure_args0=; unset ac_configure_args0;} +{ ac_configure_args1=; unset ac_configure_args1;} + +# When interrupted or exit'd, cleanup temporary files, and complete +# config.log. We remove comments because anyway the quotes in there +# would cause problems or look ugly. +# WARNING: Use '\'' to represent an apostrophe within the trap. +# WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug. +trap 'exit_status=$? + # Save into config.log some information that might help in debugging. + { + echo + + $as_echo "## ---------------- ## +## Cache variables. ## +## ---------------- ##" + echo + # The following way of writing the cache mishandles newlines in values, +( + for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do + eval ac_val=\$$ac_var + case $ac_val in #( + *${as_nl}*) + case $ac_var in #( + *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 +$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; + esac + case $ac_var in #( + _ | IFS | as_nl) ;; #( + BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( + *) { eval $ac_var=; unset $ac_var;} ;; + esac ;; + esac + done + (set) 2>&1 | + case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #( + *${as_nl}ac_space=\ *) + sed -n \ + "s/'\''/'\''\\\\'\'''\''/g; + s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p" + ;; #( + *) + sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" + ;; + esac | + sort +) + echo + + $as_echo "## ----------------- ## +## Output variables. ## +## ----------------- ##" + echo + for ac_var in $ac_subst_vars + do + eval ac_val=\$$ac_var + case $ac_val in + *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; + esac + $as_echo "$ac_var='\''$ac_val'\''" + done | sort + echo + + if test -n "$ac_subst_files"; then + $as_echo "## ------------------- ## +## File substitutions. ## +## ------------------- ##" + echo + for ac_var in $ac_subst_files + do + eval ac_val=\$$ac_var + case $ac_val in + *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; + esac + $as_echo "$ac_var='\''$ac_val'\''" + done | sort + echo + fi + + if test -s confdefs.h; then + $as_echo "## ----------- ## +## confdefs.h. ## +## ----------- ##" + echo + cat confdefs.h + echo + fi + test "$ac_signal" != 0 && + $as_echo "$as_me: caught signal $ac_signal" + $as_echo "$as_me: exit $exit_status" + } >&5 + rm -f core *.core core.conftest.* && + rm -f -r conftest* confdefs* conf$$* $ac_clean_files && + exit $exit_status +' 0 +for ac_signal in 1 2 13 15; do + trap 'ac_signal='$ac_signal'; as_fn_exit 1' $ac_signal +done +ac_signal=0 + +# confdefs.h avoids OS command line length limits that DEFS can exceed. +rm -f -r conftest* confdefs.h + +$as_echo "/* confdefs.h */" > confdefs.h + +# Predefined preprocessor variables. + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_NAME "$PACKAGE_NAME" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_TARNAME "$PACKAGE_TARNAME" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_VERSION "$PACKAGE_VERSION" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_STRING "$PACKAGE_STRING" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_URL "$PACKAGE_URL" +_ACEOF + + +# Let the site file select an alternate cache file if it wants to. +# Prefer an explicitly selected file to automatically selected ones. +ac_site_file1=NONE +ac_site_file2=NONE +if test -n "$CONFIG_SITE"; then + # We do not want a PATH search for config.site. + case $CONFIG_SITE in #(( + -*) ac_site_file1=./$CONFIG_SITE;; + */*) ac_site_file1=$CONFIG_SITE;; + *) ac_site_file1=./$CONFIG_SITE;; + esac +elif test "x$prefix" != xNONE; then + ac_site_file1=$prefix/share/config.site + ac_site_file2=$prefix/etc/config.site +else + ac_site_file1=$ac_default_prefix/share/config.site + ac_site_file2=$ac_default_prefix/etc/config.site +fi +for ac_site_file in "$ac_site_file1" "$ac_site_file2" +do + test "x$ac_site_file" = xNONE && continue + if test /dev/null != "$ac_site_file" && test -r "$ac_site_file"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5 +$as_echo "$as_me: loading site script $ac_site_file" >&6;} + sed 's/^/| /' "$ac_site_file" >&5 + . "$ac_site_file" \ + || { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "failed to load site script $ac_site_file +See \`config.log' for more details" "$LINENO" 5; } + fi +done + +if test -r "$cache_file"; then + # Some versions of bash will fail to source /dev/null (special files + # actually), so we avoid doing that. DJGPP emulates it as a regular file. + if test /dev/null != "$cache_file" && test -f "$cache_file"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5 +$as_echo "$as_me: loading cache $cache_file" >&6;} + case $cache_file in + [\\/]* | ?:[\\/]* ) . "$cache_file";; + *) . "./$cache_file";; + esac + fi +else + { $as_echo "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5 +$as_echo "$as_me: creating cache $cache_file" >&6;} + >$cache_file +fi + +# Check that the precious variables saved in the cache have kept the same +# value. +ac_cache_corrupted=false +for ac_var in $ac_precious_vars; do + eval ac_old_set=\$ac_cv_env_${ac_var}_set + eval ac_new_set=\$ac_env_${ac_var}_set + eval ac_old_val=\$ac_cv_env_${ac_var}_value + eval ac_new_val=\$ac_env_${ac_var}_value + case $ac_old_set,$ac_new_set in + set,) + { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 +$as_echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} + ac_cache_corrupted=: ;; + ,set) + { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5 +$as_echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} + ac_cache_corrupted=: ;; + ,);; + *) + if test "x$ac_old_val" != "x$ac_new_val"; then + # differences in whitespace do not lead to failure. + ac_old_val_w=`echo x $ac_old_val` + ac_new_val_w=`echo x $ac_new_val` + if test "$ac_old_val_w" != "$ac_new_val_w"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5 +$as_echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} + ac_cache_corrupted=: + else + { $as_echo "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5 +$as_echo "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;} + eval $ac_var=\$ac_old_val + fi + { $as_echo "$as_me:${as_lineno-$LINENO}: former value: \`$ac_old_val'" >&5 +$as_echo "$as_me: former value: \`$ac_old_val'" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: current value: \`$ac_new_val'" >&5 +$as_echo "$as_me: current value: \`$ac_new_val'" >&2;} + fi;; + esac + # Pass precious variables to config.status. + if test "$ac_new_set" = set; then + case $ac_new_val in + *\'*) ac_arg=$ac_var=`$as_echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; + *) ac_arg=$ac_var=$ac_new_val ;; + esac + case " $ac_configure_args " in + *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. + *) as_fn_append ac_configure_args " '$ac_arg'" ;; + esac + fi +done +if $ac_cache_corrupted; then + { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5 +$as_echo "$as_me: error: changes in the environment can compromise the build" >&2;} + as_fn_error $? "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5 +fi +## -------------------- ## +## Main body of script. ## +## -------------------- ## + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. +set dummy ${ac_tool_prefix}gcc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="${ac_tool_prefix}gcc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_CC"; then + ac_ct_CC=$CC + # Extract the first word of "gcc", so it can be a program name with args. +set dummy gcc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_CC="gcc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 +$as_echo "$ac_ct_CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_CC" = x; then + CC="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + CC=$ac_ct_CC + fi +else + CC="$ac_cv_prog_CC" +fi + +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. +set dummy ${ac_tool_prefix}cc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="${ac_tool_prefix}cc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + fi +fi +if test -z "$CC"; then + # Extract the first word of "cc", so it can be a program name with args. +set dummy cc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + ac_prog_rejected=no +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then + ac_prog_rejected=yes + continue + fi + ac_cv_prog_CC="cc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +if test $ac_prog_rejected = yes; then + # We found a bogon in the path, so make sure we never use it. + set dummy $ac_cv_prog_CC + shift + if test $# != 0; then + # We chose a different compiler from the bogus one. + # However, it has the same basename, so the bogon will be chosen + # first if we set CC to just the basename; use the full file name. + shift + ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" + fi +fi +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + for ac_prog in cl.exe + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="$ac_tool_prefix$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$CC" && break + done +fi +if test -z "$CC"; then + ac_ct_CC=$CC + for ac_prog in cl.exe +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_CC="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 +$as_echo "$ac_ct_CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$ac_ct_CC" && break +done + + if test "x$ac_ct_CC" = x; then + CC="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + CC=$ac_ct_CC + fi +fi + +fi + + +test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "no acceptable C compiler found in \$PATH +See \`config.log' for more details" "$LINENO" 5; } + +# Provide some information about the compiler. +$as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5 +set X $ac_compile +ac_compiler=$2 +for ac_option in --version -v -V -qversion; do + { { ac_try="$ac_compiler $ac_option >&5" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compiler $ac_option >&5") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + sed '10a\ +... rest of stderr output deleted ... + 10q' conftest.err >conftest.er1 + cat conftest.er1 >&5 + fi + rm -f conftest.er1 conftest.err + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } +done + +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +ac_clean_files_save=$ac_clean_files +ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out" +# Try to create an executable without -o first, disregard a.out. +# It will help us diagnose broken compilers, and finding out an intuition +# of exeext. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler works" >&5 +$as_echo_n "checking whether the C compiler works... " >&6; } +ac_link_default=`$as_echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` + +# The possible output files: +ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*" + +ac_rmfiles= +for ac_file in $ac_files +do + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; + * ) ac_rmfiles="$ac_rmfiles $ac_file";; + esac +done +rm -f $ac_rmfiles + +if { { ac_try="$ac_link_default" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link_default") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then : + # Autoconf-2.13 could set the ac_cv_exeext variable to `no'. +# So ignore a value of `no', otherwise this would lead to `EXEEXT = no' +# in a Makefile. We should not override ac_cv_exeext if it was cached, +# so that the user can short-circuit this test for compilers unknown to +# Autoconf. +for ac_file in $ac_files '' +do + test -f "$ac_file" || continue + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) + ;; + [ab].out ) + # We found the default executable, but exeext='' is most + # certainly right. + break;; + *.* ) + if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no; + then :; else + ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` + fi + # We set ac_cv_exeext here because the later test for it is not + # safe: cross compilers may not add the suffix if given an `-o' + # argument, so we may need to know it at that point already. + # Even if this section looks crufty: it has the advantage of + # actually working. + break;; + * ) + break;; + esac +done +test "$ac_cv_exeext" = no && ac_cv_exeext= + +else + ac_file='' +fi +if test -z "$ac_file"; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +$as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error 77 "C compiler cannot create executables +See \`config.log' for more details" "$LINENO" 5; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler default output file name" >&5 +$as_echo_n "checking for C compiler default output file name... " >&6; } +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5 +$as_echo "$ac_file" >&6; } +ac_exeext=$ac_cv_exeext + +rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out +ac_clean_files=$ac_clean_files_save +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5 +$as_echo_n "checking for suffix of executables... " >&6; } +if { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then : + # If both `conftest.exe' and `conftest' are `present' (well, observable) +# catch `conftest.exe'. For instance with Cygwin, `ls conftest' will +# work properly (i.e., refer to `conftest.exe'), while it won't with +# `rm'. +for ac_file in conftest.exe conftest conftest.*; do + test -f "$ac_file" || continue + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; + *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` + break;; + * ) break;; + esac +done +else + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "cannot compute suffix of executables: cannot compile and link +See \`config.log' for more details" "$LINENO" 5; } +fi +rm -f conftest conftest$ac_cv_exeext +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5 +$as_echo "$ac_cv_exeext" >&6; } + +rm -f conftest.$ac_ext +EXEEXT=$ac_cv_exeext +ac_exeext=$EXEEXT +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +int +main () +{ +FILE *f = fopen ("conftest.out", "w"); + return ferror (f) || fclose (f) != 0; + + ; + return 0; +} +_ACEOF +ac_clean_files="$ac_clean_files conftest.out" +# Check that the compiler produces executables we can run. If not, either +# the compiler is broken, or we cross compile. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5 +$as_echo_n "checking whether we are cross compiling... " >&6; } +if test "$cross_compiling" != yes; then + { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } + if { ac_try='./conftest$ac_cv_exeext' + { { case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; }; then + cross_compiling=no + else + if test "$cross_compiling" = maybe; then + cross_compiling=yes + else + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "cannot run C compiled programs. +If you meant to cross compile, use \`--host'. +See \`config.log' for more details" "$LINENO" 5; } + fi + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5 +$as_echo "$cross_compiling" >&6; } + +rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out +ac_clean_files=$ac_clean_files_save +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5 +$as_echo_n "checking for suffix of object files... " >&6; } +if ${ac_cv_objext+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.o conftest.obj +if { { ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compile") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then : + for ac_file in conftest.o conftest.obj conftest.*; do + test -f "$ac_file" || continue; + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;; + *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` + break;; + esac +done +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "cannot compute suffix of object files: cannot compile +See \`config.log' for more details" "$LINENO" 5; } +fi +rm -f conftest.$ac_cv_objext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5 +$as_echo "$ac_cv_objext" >&6; } +OBJEXT=$ac_cv_objext +ac_objext=$OBJEXT +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5 +$as_echo_n "checking whether we are using the GNU C compiler... " >&6; } +if ${ac_cv_c_compiler_gnu+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ +#ifndef __GNUC__ + choke me +#endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_compiler_gnu=yes +else + ac_compiler_gnu=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +ac_cv_c_compiler_gnu=$ac_compiler_gnu + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5 +$as_echo "$ac_cv_c_compiler_gnu" >&6; } +if test $ac_compiler_gnu = yes; then + GCC=yes +else + GCC= +fi +ac_test_CFLAGS=${CFLAGS+set} +ac_save_CFLAGS=$CFLAGS +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5 +$as_echo_n "checking whether $CC accepts -g... " >&6; } +if ${ac_cv_prog_cc_g+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_save_c_werror_flag=$ac_c_werror_flag + ac_c_werror_flag=yes + ac_cv_prog_cc_g=no + CFLAGS="-g" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_prog_cc_g=yes +else + CFLAGS="" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + +else + ac_c_werror_flag=$ac_save_c_werror_flag + CFLAGS="-g" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_prog_cc_g=yes +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ac_c_werror_flag=$ac_save_c_werror_flag +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5 +$as_echo "$ac_cv_prog_cc_g" >&6; } +if test "$ac_test_CFLAGS" = set; then + CFLAGS=$ac_save_CFLAGS +elif test $ac_cv_prog_cc_g = yes; then + if test "$GCC" = yes; then + CFLAGS="-g -O2" + else + CFLAGS="-g" + fi +else + if test "$GCC" = yes; then + CFLAGS="-O2" + else + CFLAGS= + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5 +$as_echo_n "checking for $CC option to accept ISO C89... " >&6; } +if ${ac_cv_prog_cc_c89+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_cv_prog_cc_c89=no +ac_save_CC=$CC +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +#include +struct stat; +/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ +struct buf { int x; }; +FILE * (*rcsopen) (struct buf *, struct stat *, int); +static char *e (p, i) + char **p; + int i; +{ + return p[i]; +} +static char *f (char * (*g) (char **, int), char **p, ...) +{ + char *s; + va_list v; + va_start (v,p); + s = g (p, va_arg (v,int)); + va_end (v); + return s; +} + +/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has + function prototypes and stuff, but not '\xHH' hex character constants. + These don't provoke an error unfortunately, instead are silently treated + as 'x'. The following induces an error, until -std is added to get + proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an + array size at least. It's necessary to write '\x00'==0 to get something + that's true only with -std. */ +int osf4_cc_array ['\x00' == 0 ? 1 : -1]; + +/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters + inside strings and character constants. */ +#define FOO(x) 'x' +int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1]; + +int test (int i, double x); +struct s1 {int (*f) (int a);}; +struct s2 {int (*f) (double a);}; +int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); +int argc; +char **argv; +int +main () +{ +return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; + ; + return 0; +} +_ACEOF +for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \ + -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" +do + CC="$ac_save_CC $ac_arg" + if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_prog_cc_c89=$ac_arg +fi +rm -f core conftest.err conftest.$ac_objext + test "x$ac_cv_prog_cc_c89" != "xno" && break +done +rm -f conftest.$ac_ext +CC=$ac_save_CC + +fi +# AC_CACHE_VAL +case "x$ac_cv_prog_cc_c89" in + x) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 +$as_echo "none needed" >&6; } ;; + xno) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 +$as_echo "unsupported" >&6; } ;; + *) + CC="$CC $ac_cv_prog_cc_c89" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5 +$as_echo "$ac_cv_prog_cc_c89" >&6; } ;; +esac +if test "x$ac_cv_prog_cc_c89" != xno; then : + +fi + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + + +ac_config_headers="$ac_config_headers config.h" + + + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5 +$as_echo_n "checking how to run the C preprocessor... " >&6; } +# On Suns, sometimes $CPP names a directory. +if test -n "$CPP" && test -d "$CPP"; then + CPP= +fi +if test -z "$CPP"; then + if ${ac_cv_prog_CPP+:} false; then : + $as_echo_n "(cached) " >&6 +else + # Double quotes because CPP needs to be expanded + for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp" + do + ac_preproc_ok=false +for ac_c_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer to if __STDC__ is defined, since + # exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#ifdef __STDC__ +# include +#else +# include +#endif + Syntax error +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + +else + # Broken: fails on valid input. +continue +fi +rm -f conftest.err conftest.i conftest.$ac_ext + + # OK, works on sane cases. Now check whether nonexistent headers + # can be detected and how. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + # Broken: success on invalid input. +continue +else + # Passes both tests. +ac_preproc_ok=: +break +fi +rm -f conftest.err conftest.i conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.i conftest.err conftest.$ac_ext +if $ac_preproc_ok; then : + break +fi + + done + ac_cv_prog_CPP=$CPP + +fi + CPP=$ac_cv_prog_CPP +else + ac_cv_prog_CPP=$CPP +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5 +$as_echo "$CPP" >&6; } +ac_preproc_ok=false +for ac_c_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer to if __STDC__ is defined, since + # exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#ifdef __STDC__ +# include +#else +# include +#endif + Syntax error +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + +else + # Broken: fails on valid input. +continue +fi +rm -f conftest.err conftest.i conftest.$ac_ext + + # OK, works on sane cases. Now check whether nonexistent headers + # can be detected and how. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + # Broken: success on invalid input. +continue +else + # Passes both tests. +ac_preproc_ok=: +break +fi +rm -f conftest.err conftest.i conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.i conftest.err conftest.$ac_ext +if $ac_preproc_ok; then : + +else + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "C preprocessor \"$CPP\" fails sanity check +See \`config.log' for more details" "$LINENO" 5; } +fi + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5 +$as_echo_n "checking for grep that handles long lines and -e... " >&6; } +if ${ac_cv_path_GREP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -z "$GREP"; then + ac_path_GREP_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in grep ggrep; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext" + as_fn_executable_p "$ac_path_GREP" || continue +# Check for GNU ac_path_GREP and select it if it is found. + # Check for GNU $ac_path_GREP +case `"$ac_path_GREP" --version 2>&1` in +*GNU*) + ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;; +*) + ac_count=0 + $as_echo_n 0123456789 >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + $as_echo 'GREP' >> "conftest.nl" + "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + as_fn_arith $ac_count + 1 && ac_count=$as_val + if test $ac_count -gt ${ac_path_GREP_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_GREP="$ac_path_GREP" + ac_path_GREP_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + $ac_path_GREP_found && break 3 + done + done + done +IFS=$as_save_IFS + if test -z "$ac_cv_path_GREP"; then + as_fn_error $? "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 + fi +else + ac_cv_path_GREP=$GREP +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5 +$as_echo "$ac_cv_path_GREP" >&6; } + GREP="$ac_cv_path_GREP" + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5 +$as_echo_n "checking for egrep... " >&6; } +if ${ac_cv_path_EGREP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if echo a | $GREP -E '(a|b)' >/dev/null 2>&1 + then ac_cv_path_EGREP="$GREP -E" + else + if test -z "$EGREP"; then + ac_path_EGREP_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in egrep; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext" + as_fn_executable_p "$ac_path_EGREP" || continue +# Check for GNU ac_path_EGREP and select it if it is found. + # Check for GNU $ac_path_EGREP +case `"$ac_path_EGREP" --version 2>&1` in +*GNU*) + ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;; +*) + ac_count=0 + $as_echo_n 0123456789 >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + $as_echo 'EGREP' >> "conftest.nl" + "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + as_fn_arith $ac_count + 1 && ac_count=$as_val + if test $ac_count -gt ${ac_path_EGREP_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_EGREP="$ac_path_EGREP" + ac_path_EGREP_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + $ac_path_EGREP_found && break 3 + done + done + done +IFS=$as_save_IFS + if test -z "$ac_cv_path_EGREP"; then + as_fn_error $? "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 + fi +else + ac_cv_path_EGREP=$EGREP +fi + + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5 +$as_echo "$ac_cv_path_EGREP" >&6; } + EGREP="$ac_cv_path_EGREP" + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5 +$as_echo_n "checking for ANSI C header files... " >&6; } +if ${ac_cv_header_stdc+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +#include +#include +#include + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_header_stdc=yes +else + ac_cv_header_stdc=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + +if test $ac_cv_header_stdc = yes; then + # SunOS 4.x string.h does not declare mem*, contrary to ANSI. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "memchr" >/dev/null 2>&1; then : + +else + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "free" >/dev/null 2>&1; then : + +else + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. + if test "$cross_compiling" = yes; then : + : +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +#include +#if ((' ' & 0x0FF) == 0x020) +# define ISLOWER(c) ('a' <= (c) && (c) <= 'z') +# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) +#else +# define ISLOWER(c) \ + (('a' <= (c) && (c) <= 'i') \ + || ('j' <= (c) && (c) <= 'r') \ + || ('s' <= (c) && (c) <= 'z')) +# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) +#endif + +#define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) +int +main () +{ + int i; + for (i = 0; i < 256; i++) + if (XOR (islower (i), ISLOWER (i)) + || toupper (i) != TOUPPER (i)) + return 2; + return 0; +} +_ACEOF +if ac_fn_c_try_run "$LINENO"; then : + +else + ac_cv_header_stdc=no +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + +fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5 +$as_echo "$ac_cv_header_stdc" >&6; } +if test $ac_cv_header_stdc = yes; then + +$as_echo "#define STDC_HEADERS 1" >>confdefs.h + +fi + +# On IRIX 5.3, sys/types and inttypes.h are conflicting. +for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \ + inttypes.h stdint.h unistd.h +do : + as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` +ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default +" +if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + + +ac_fn_c_check_member "$LINENO" "struct stat" "st_blksize" "ac_cv_member_struct_stat_st_blksize" "$ac_includes_default" +if test "x$ac_cv_member_struct_stat_st_blksize" = xyes; then : + +cat >>confdefs.h <<_ACEOF +#define HAVE_STRUCT_STAT_ST_BLKSIZE 1 +_ACEOF + + +fi + +ac_fn_c_check_member "$LINENO" "struct stat" "st_blocks" "ac_cv_member_struct_stat_st_blocks" "$ac_includes_default" +if test "x$ac_cv_member_struct_stat_st_blocks" = xyes; then : + +cat >>confdefs.h <<_ACEOF +#define HAVE_STRUCT_STAT_ST_BLOCKS 1 +_ACEOF + + +fi + +ac_fn_c_check_member "$LINENO" "struct stat" "st_rdev" "ac_cv_member_struct_stat_st_rdev" "$ac_includes_default" +if test "x$ac_cv_member_struct_stat_st_rdev" = xyes; then : + +cat >>confdefs.h <<_ACEOF +#define HAVE_STRUCT_STAT_ST_RDEV 1 +_ACEOF + + +fi + +ac_fn_c_check_member "$LINENO" "struct stat" "st_birthtimespec" "ac_cv_member_struct_stat_st_birthtimespec" "$ac_includes_default" +if test "x$ac_cv_member_struct_stat_st_birthtimespec" = xyes; then : + +cat >>confdefs.h <<_ACEOF +#define HAVE_STRUCT_STAT_ST_BIRTHTIMESPEC 1 +_ACEOF + + +fi + + +for ac_func in getgroups +do : + ac_fn_c_check_func "$LINENO" "getgroups" "ac_cv_func_getgroups" +if test "x$ac_cv_func_getgroups" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_GETGROUPS 1 +_ACEOF + +fi +done + +for ac_func in lstat +do : + ac_fn_c_check_func "$LINENO" "lstat" "ac_cv_func_lstat" +if test "x$ac_cv_func_lstat" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_LSTAT 1 +_ACEOF + +fi +done + + +cat >confcache <<\_ACEOF +# This file is a shell script that caches the results of configure +# tests run on this system so they can be shared between configure +# scripts and configure runs, see configure's option --config-cache. +# It is not useful on other systems. If it contains results you don't +# want to keep, you may remove or edit it. +# +# config.status only pays attention to the cache file if you give it +# the --recheck option to rerun configure. +# +# `ac_cv_env_foo' variables (set or unset) will be overridden when +# loading this file, other *unset* `ac_cv_foo' will be assigned the +# following values. + +_ACEOF + +# The following way of writing the cache mishandles newlines in values, +# but we know of no workaround that is simple, portable, and efficient. +# So, we kill variables containing newlines. +# Ultrix sh set writes to stderr and can't be redirected directly, +# and sets the high bit in the cache file unless we assign to the vars. +( + for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do + eval ac_val=\$$ac_var + case $ac_val in #( + *${as_nl}*) + case $ac_var in #( + *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 +$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; + esac + case $ac_var in #( + _ | IFS | as_nl) ;; #( + BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( + *) { eval $ac_var=; unset $ac_var;} ;; + esac ;; + esac + done + + (set) 2>&1 | + case $as_nl`(ac_space=' '; set) 2>&1` in #( + *${as_nl}ac_space=\ *) + # `set' does not quote correctly, so add quotes: double-quote + # substitution turns \\\\ into \\, and sed turns \\ into \. + sed -n \ + "s/'/'\\\\''/g; + s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" + ;; #( + *) + # `set' quotes correctly as required by POSIX, so do not add quotes. + sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" + ;; + esac | + sort +) | + sed ' + /^ac_cv_env_/b end + t clear + :clear + s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ + t end + s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ + :end' >>confcache +if diff "$cache_file" confcache >/dev/null 2>&1; then :; else + if test -w "$cache_file"; then + if test "x$cache_file" != "x/dev/null"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5 +$as_echo "$as_me: updating cache $cache_file" >&6;} + if test ! -f "$cache_file" || test -h "$cache_file"; then + cat confcache >"$cache_file" + else + case $cache_file in #( + */* | ?:*) + mv -f confcache "$cache_file"$$ && + mv -f "$cache_file"$$ "$cache_file" ;; #( + *) + mv -f confcache "$cache_file" ;; + esac + fi + fi + else + { $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5 +$as_echo "$as_me: not updating unwritable cache $cache_file" >&6;} + fi +fi +rm -f confcache + +test "x$prefix" = xNONE && prefix=$ac_default_prefix +# Let make expand exec_prefix. +test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' + +DEFS=-DHAVE_CONFIG_H + +ac_libobjs= +ac_ltlibobjs= +U= +for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue + # 1. Remove the extension, and $U if already installed. + ac_script='s/\$U\././;s/\.o$//;s/\.obj$//' + ac_i=`$as_echo "$ac_i" | sed "$ac_script"` + # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR + # will be set to the directory where LIBOBJS objects are built. + as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext" + as_fn_append ac_ltlibobjs " \${LIBOBJDIR}$ac_i"'$U.lo' +done +LIBOBJS=$ac_libobjs + +LTLIBOBJS=$ac_ltlibobjs + + + +: "${CONFIG_STATUS=./config.status}" +ac_write_fail=0 +ac_clean_files_save=$ac_clean_files +ac_clean_files="$ac_clean_files $CONFIG_STATUS" +{ $as_echo "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5 +$as_echo "$as_me: creating $CONFIG_STATUS" >&6;} +as_write_fail=0 +cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1 +#! $SHELL +# Generated by $as_me. +# Run this file to recreate the current configuration. +# Compiler output produced by configure, useful for debugging +# configure, is in config.log if it exists. + +debug=false +ac_cs_recheck=false +ac_cs_silent=false + +SHELL=\${CONFIG_SHELL-$SHELL} +export SHELL +_ASEOF +cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1 +## -------------------- ## +## M4sh Initialization. ## +## -------------------- ## + +# Be more Bourne compatible +DUALCASE=1; export DUALCASE # for MKS sh +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : + emulate sh + NULLCMD=: + # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in #( + *posix*) : + set -o posix ;; #( + *) : + ;; +esac +fi + + +as_nl=' +' +export as_nl +# Printing a long string crashes Solaris 7 /usr/bin/printf. +as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo +# Prefer a ksh shell builtin over an external printf program on Solaris, +# but without wasting forks for bash or zsh. +if test -z "$BASH_VERSION$ZSH_VERSION" \ + && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='print -r --' + as_echo_n='print -rn --' +elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='printf %s\n' + as_echo_n='printf %s' +else + if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then + as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' + as_echo_n='/usr/ucb/echo -n' + else + as_echo_body='eval expr "X$1" : "X\\(.*\\)"' + as_echo_n_body='eval + arg=$1; + case $arg in #( + *"$as_nl"*) + expr "X$arg" : "X\\(.*\\)$as_nl"; + arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; + esac; + expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" + ' + export as_echo_n_body + as_echo_n='sh -c $as_echo_n_body as_echo' + fi + export as_echo_body + as_echo='sh -c $as_echo_body as_echo' +fi + +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + PATH_SEPARATOR=: + (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { + (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || + PATH_SEPARATOR=';' + } +fi + + +# IFS +# We need space, tab and new line, in precisely that order. Quoting is +# there to prevent editors from complaining about space-tab. +# (If _AS_PATH_WALK were called with IFS unset, it would disable word +# splitting by setting IFS to empty value.) +IFS=" "" $as_nl" + +# Find who we are. Look in the path if we contain no directory separator. +as_myself= +case $0 in #(( + *[\\/]* ) as_myself=$0 ;; + *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break + done +IFS=$as_save_IFS + + ;; +esac +# We did not find ourselves, most probably we were run as `sh COMMAND' +# in which case we are not to be found in the path. +if test "x$as_myself" = x; then + as_myself=$0 +fi +if test ! -f "$as_myself"; then + $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 + exit 1 +fi + +# Unset variables that we do not need and which cause bugs (e.g. in +# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" +# suppresses any "Segmentation fault" message there. '((' could +# trigger a bug in pdksh 5.2.14. +for as_var in BASH_ENV ENV MAIL MAILPATH +do eval test x\${$as_var+set} = xset \ + && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : +done +PS1='$ ' +PS2='> ' +PS4='+ ' + +# NLS nuisances. +LC_ALL=C +export LC_ALL +LANGUAGE=C +export LANGUAGE + +# CDPATH. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + + +# as_fn_error STATUS ERROR [LINENO LOG_FD] +# ---------------------------------------- +# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are +# provided, also output the error to LOG_FD, referencing LINENO. Then exit the +# script with STATUS, using 1 if that was 0. +as_fn_error () +{ + as_status=$1; test $as_status -eq 0 && as_status=1 + if test "$4"; then + as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 + fi + $as_echo "$as_me: error: $2" >&2 + as_fn_exit $as_status +} # as_fn_error + + +# as_fn_set_status STATUS +# ----------------------- +# Set $? to STATUS, without forking. +as_fn_set_status () +{ + return $1 +} # as_fn_set_status + +# as_fn_exit STATUS +# ----------------- +# Exit the shell with STATUS, even in a "trap 0" or "set -e" context. +as_fn_exit () +{ + set +e + as_fn_set_status $1 + exit $1 +} # as_fn_exit + +# as_fn_unset VAR +# --------------- +# Portably unset VAR. +as_fn_unset () +{ + { eval $1=; unset $1;} +} +as_unset=as_fn_unset +# as_fn_append VAR VALUE +# ---------------------- +# Append the text in VALUE to the end of the definition contained in VAR. Take +# advantage of any shell optimizations that allow amortized linear growth over +# repeated appends, instead of the typical quadratic growth present in naive +# implementations. +if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : + eval 'as_fn_append () + { + eval $1+=\$2 + }' +else + as_fn_append () + { + eval $1=\$$1\$2 + } +fi # as_fn_append + +# as_fn_arith ARG... +# ------------------ +# Perform arithmetic evaluation on the ARGs, and store the result in the +# global $as_val. Take advantage of shells that can avoid forks. The arguments +# must be portable across $(()) and expr. +if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : + eval 'as_fn_arith () + { + as_val=$(( $* )) + }' +else + as_fn_arith () + { + as_val=`expr "$@" || test $? -eq 1` + } +fi # as_fn_arith + + +if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; then + as_expr=expr +else + as_expr=false +fi + +if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then + as_basename=basename +else + as_basename=false +fi + +if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then + as_dirname=dirname +else + as_dirname=false +fi + +as_me=`$as_basename -- "$0" || +$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ + s//\1/ + q + } + /^X\/\(\/\/\)$/{ + s//\1/ + q + } + /^X\/\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + +# Avoid depending upon Character Ranges. +as_cr_letters='abcdefghijklmnopqrstuvwxyz' +as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' +as_cr_Letters=$as_cr_letters$as_cr_LETTERS +as_cr_digits='0123456789' +as_cr_alnum=$as_cr_Letters$as_cr_digits + +ECHO_C= ECHO_N= ECHO_T= +case `echo -n x` in #((((( +-n*) + case `echo 'xy\c'` in + *c*) ECHO_T=' ';; # ECHO_T is single tab character. + xy) ECHO_C='\c';; + *) echo `echo ksh88 bug on AIX 6.1` > /dev/null + ECHO_T=' ';; + esac;; +*) + ECHO_N='-n';; +esac + +rm -f conf$$ conf$$.exe conf$$.file +if test -d conf$$.dir; then + rm -f conf$$.dir/conf$$.file +else + rm -f conf$$.dir + mkdir conf$$.dir 2>/dev/null +fi +if (echo >conf$$.file) 2>/dev/null; then + if ln -s conf$$.file conf$$ 2>/dev/null; then + as_ln_s='ln -s' + # ... but there are two gotchas: + # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. + # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. + # In both cases, we have to default to `cp -pR'. + ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || + as_ln_s='cp -pR' + elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln + else + as_ln_s='cp -pR' + fi +else + as_ln_s='cp -pR' +fi +rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file +rmdir conf$$.dir 2>/dev/null + + +# as_fn_mkdir_p +# ------------- +# Create "$as_dir" as a directory, including parents if necessary. +as_fn_mkdir_p () +{ + + case $as_dir in #( + -*) as_dir=./$as_dir;; + esac + test -d "$as_dir" || eval $as_mkdir_p || { + as_dirs= + while :; do + case $as_dir in #( + *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( + *) as_qdir=$as_dir;; + esac + as_dirs="'$as_qdir' $as_dirs" + as_dir=`$as_dirname -- "$as_dir" || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + test -d "$as_dir" && break + done + test -z "$as_dirs" || eval "mkdir $as_dirs" + } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" + + +} # as_fn_mkdir_p +if mkdir -p . 2>/dev/null; then + as_mkdir_p='mkdir -p "$as_dir"' +else + test -d ./-p && rmdir ./-p + as_mkdir_p=false +fi + + +# as_fn_executable_p FILE +# ----------------------- +# Test if FILE is an executable regular file. +as_fn_executable_p () +{ + test -f "$1" && test -x "$1" +} # as_fn_executable_p +as_test_x='test -x' +as_executable_p=as_fn_executable_p + +# Sed expression to map a string onto a valid CPP name. +as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" + +# Sed expression to map a string onto a valid variable name. +as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" + + +exec 6>&1 +## ----------------------------------- ## +## Main body of $CONFIG_STATUS script. ## +## ----------------------------------- ## +_ASEOF +test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1 + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +# Save the log message, to keep $0 and so on meaningful, and to +# report actual input values of CONFIG_FILES etc. instead of their +# values after options handling. +ac_log=" +This file was extended by $as_me, which was +generated by GNU Autoconf 2.69. Invocation command line was + + CONFIG_FILES = $CONFIG_FILES + CONFIG_HEADERS = $CONFIG_HEADERS + CONFIG_LINKS = $CONFIG_LINKS + CONFIG_COMMANDS = $CONFIG_COMMANDS + $ $0 $@ + +on `(hostname || uname -n) 2>/dev/null | sed 1q` +" + +_ACEOF + + +case $ac_config_headers in *" +"*) set x $ac_config_headers; shift; ac_config_headers=$*;; +esac + + +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +# Files that config.status was made for. +config_headers="$ac_config_headers" + +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +ac_cs_usage="\ +\`$as_me' instantiates files and other configuration actions +from templates according to the current configuration. Unless the files +and actions are specified as TAGs, all are instantiated by default. + +Usage: $0 [OPTION]... [TAG]... + + -h, --help print this help, then exit + -V, --version print version number and configuration settings, then exit + --config print configuration, then exit + -q, --quiet, --silent + do not print progress messages + -d, --debug don't remove temporary files + --recheck update $as_me by reconfiguring in the same conditions + --header=FILE[:TEMPLATE] + instantiate the configuration header FILE + +Configuration headers: +$config_headers + +Report bugs to the package provider." + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" +ac_cs_version="\\ +config.status +configured by $0, generated by GNU Autoconf 2.69, + with options \\"\$ac_cs_config\\" + +Copyright (C) 2012 Free Software Foundation, Inc. +This config.status script is free software; the Free Software Foundation +gives unlimited permission to copy, distribute and modify it." + +ac_pwd='$ac_pwd' +srcdir='$srcdir' +test -n "\$AWK" || AWK=awk +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +# The default lists apply if the user does not specify any file. +ac_need_defaults=: +while test $# != 0 +do + case $1 in + --*=?*) + ac_option=`expr "X$1" : 'X\([^=]*\)='` + ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'` + ac_shift=: + ;; + --*=) + ac_option=`expr "X$1" : 'X\([^=]*\)='` + ac_optarg= + ac_shift=: + ;; + *) + ac_option=$1 + ac_optarg=$2 + ac_shift=shift + ;; + esac + + case $ac_option in + # Handling of the options. + -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) + ac_cs_recheck=: ;; + --version | --versio | --versi | --vers | --ver | --ve | --v | -V ) + $as_echo "$ac_cs_version"; exit ;; + --config | --confi | --conf | --con | --co | --c ) + $as_echo "$ac_cs_config"; exit ;; + --debug | --debu | --deb | --de | --d | -d ) + debug=: ;; + --header | --heade | --head | --hea ) + $ac_shift + case $ac_optarg in + *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; + esac + as_fn_append CONFIG_HEADERS " '$ac_optarg'" + ac_need_defaults=false;; + --he | --h) + # Conflict between --help and --header + as_fn_error $? "ambiguous option: \`$1' +Try \`$0 --help' for more information.";; + --help | --hel | -h ) + $as_echo "$ac_cs_usage"; exit ;; + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil | --si | --s) + ac_cs_silent=: ;; + + # This is an error. + -*) as_fn_error $? "unrecognized option: \`$1' +Try \`$0 --help' for more information." ;; + + *) as_fn_append ac_config_targets " $1" + ac_need_defaults=false ;; + + esac + shift +done + +ac_configure_extra_args= + +if $ac_cs_silent; then + exec 6>/dev/null + ac_configure_extra_args="$ac_configure_extra_args --silent" +fi + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +if \$ac_cs_recheck; then + set X $SHELL '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion + shift + \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6 + CONFIG_SHELL='$SHELL' + export CONFIG_SHELL + exec "\$@" +fi + +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +exec 5>>config.log +{ + echo + sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX +## Running $as_me. ## +_ASBOX + $as_echo "$ac_log" +} >&5 + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 + +# Handling of arguments. +for ac_config_target in $ac_config_targets +do + case $ac_config_target in + "config.h") CONFIG_HEADERS="$CONFIG_HEADERS config.h" ;; + + *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;; + esac +done + + +# If the user did not use the arguments to specify the items to instantiate, +# then the envvar interface is used. Set only those that are not. +# We use the long form for the default assignment because of an extremely +# bizarre bug on SunOS 4.1.3. +if $ac_need_defaults; then + test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers +fi + +# Have a temporary directory for convenience. Make it in the build tree +# simply because there is no reason against having it here, and in addition, +# creating and moving files from /tmp can sometimes cause problems. +# Hook for its removal unless debugging. +# Note that there is a small window in which the directory will not be cleaned: +# after its creation but before its name has been assigned to `$tmp'. +$debug || +{ + tmp= ac_tmp= + trap 'exit_status=$? + : "${ac_tmp:=$tmp}" + { test ! -d "$ac_tmp" || rm -fr "$ac_tmp"; } && exit $exit_status +' 0 + trap 'as_fn_exit 1' 1 2 13 15 +} +# Create a (secure) tmp directory for tmp files. + +{ + tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` && + test -d "$tmp" +} || +{ + tmp=./conf$$-$RANDOM + (umask 077 && mkdir "$tmp") +} || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5 +ac_tmp=$tmp + +# Set up the scripts for CONFIG_HEADERS section. +# No need to generate them if there are no CONFIG_HEADERS. +# This happens for instance with `./config.status Makefile'. +if test -n "$CONFIG_HEADERS"; then +cat >"$ac_tmp/defines.awk" <<\_ACAWK || +BEGIN { +_ACEOF + +# Transform confdefs.h into an awk script `defines.awk', embedded as +# here-document in config.status, that substitutes the proper values into +# config.h.in to produce config.h. + +# Create a delimiter string that does not exist in confdefs.h, to ease +# handling of long lines. +ac_delim='%!_!# ' +for ac_last_try in false false :; do + ac_tt=`sed -n "/$ac_delim/p" confdefs.h` + if test -z "$ac_tt"; then + break + elif $ac_last_try; then + as_fn_error $? "could not make $CONFIG_HEADERS" "$LINENO" 5 + else + ac_delim="$ac_delim!$ac_delim _$ac_delim!! " + fi +done + +# For the awk script, D is an array of macro values keyed by name, +# likewise P contains macro parameters if any. Preserve backslash +# newline sequences. + +ac_word_re=[_$as_cr_Letters][_$as_cr_alnum]* +sed -n ' +s/.\{148\}/&'"$ac_delim"'/g +t rset +:rset +s/^[ ]*#[ ]*define[ ][ ]*/ / +t def +d +:def +s/\\$// +t bsnl +s/["\\]/\\&/g +s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ +D["\1"]=" \3"/p +s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2"/p +d +:bsnl +s/["\\]/\\&/g +s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ +D["\1"]=" \3\\\\\\n"\\/p +t cont +s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2\\\\\\n"\\/p +t cont +d +:cont +n +s/.\{148\}/&'"$ac_delim"'/g +t clear +:clear +s/\\$// +t bsnlc +s/["\\]/\\&/g; s/^/"/; s/$/"/p +d +:bsnlc +s/["\\]/\\&/g; s/^/"/; s/$/\\\\\\n"\\/p +b cont +' >$CONFIG_STATUS || ac_write_fail=1 + +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 + for (key in D) D_is_set[key] = 1 + FS = "" +} +/^[\t ]*#[\t ]*(define|undef)[\t ]+$ac_word_re([\t (]|\$)/ { + line = \$ 0 + split(line, arg, " ") + if (arg[1] == "#") { + defundef = arg[2] + mac1 = arg[3] + } else { + defundef = substr(arg[1], 2) + mac1 = arg[2] + } + split(mac1, mac2, "(") #) + macro = mac2[1] + prefix = substr(line, 1, index(line, defundef) - 1) + if (D_is_set[macro]) { + # Preserve the white space surrounding the "#". + print prefix "define", macro P[macro] D[macro] + next + } else { + # Replace #undef with comments. This is necessary, for example, + # in the case of _POSIX_SOURCE, which is predefined and required + # on some systems where configure will not decide to define it. + if (defundef == "undef") { + print "/*", prefix defundef, macro, "*/" + next + } + } +} +{ print } +_ACAWK +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 + as_fn_error $? "could not setup config headers machinery" "$LINENO" 5 +fi # test -n "$CONFIG_HEADERS" + + +eval set X " :H $CONFIG_HEADERS " +shift +for ac_tag +do + case $ac_tag in + :[FHLC]) ac_mode=$ac_tag; continue;; + esac + case $ac_mode$ac_tag in + :[FHL]*:*);; + :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5;; + :[FH]-) ac_tag=-:-;; + :[FH]*) ac_tag=$ac_tag:$ac_tag.in;; + esac + ac_save_IFS=$IFS + IFS=: + set x $ac_tag + IFS=$ac_save_IFS + shift + ac_file=$1 + shift + + case $ac_mode in + :L) ac_source=$1;; + :[FH]) + ac_file_inputs= + for ac_f + do + case $ac_f in + -) ac_f="$ac_tmp/stdin";; + *) # Look for the file first in the build tree, then in the source tree + # (if the path is not absolute). The absolute path cannot be DOS-style, + # because $ac_f cannot contain `:'. + test -f "$ac_f" || + case $ac_f in + [\\/$]*) false;; + *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";; + esac || + as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5;; + esac + case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac + as_fn_append ac_file_inputs " '$ac_f'" + done + + # Let's still pretend it is `configure' which instantiates (i.e., don't + # use $as_me), people would be surprised to read: + # /* config.h. Generated by config.status. */ + configure_input='Generated from '` + $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g' + `' by configure.' + if test x"$ac_file" != x-; then + configure_input="$ac_file. $configure_input" + { $as_echo "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5 +$as_echo "$as_me: creating $ac_file" >&6;} + fi + # Neutralize special characters interpreted by sed in replacement strings. + case $configure_input in #( + *\&* | *\|* | *\\* ) + ac_sed_conf_input=`$as_echo "$configure_input" | + sed 's/[\\\\&|]/\\\\&/g'`;; #( + *) ac_sed_conf_input=$configure_input;; + esac + + case $ac_tag in + *:-:* | *:-) cat >"$ac_tmp/stdin" \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; + esac + ;; + esac + + ac_dir=`$as_dirname -- "$ac_file" || +$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$ac_file" : 'X\(//\)[^/]' \| \ + X"$ac_file" : 'X\(//\)$' \| \ + X"$ac_file" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$ac_file" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + as_dir="$ac_dir"; as_fn_mkdir_p + ac_builddir=. + +case "$ac_dir" in +.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; +*) + ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` + # A ".." for each directory in $ac_dir_suffix. + ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` + case $ac_top_builddir_sub in + "") ac_top_builddir_sub=. ac_top_build_prefix= ;; + *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; + esac ;; +esac +ac_abs_top_builddir=$ac_pwd +ac_abs_builddir=$ac_pwd$ac_dir_suffix +# for backward compatibility: +ac_top_builddir=$ac_top_build_prefix + +case $srcdir in + .) # We are building in place. + ac_srcdir=. + ac_top_srcdir=$ac_top_builddir_sub + ac_abs_top_srcdir=$ac_pwd ;; + [\\/]* | ?:[\\/]* ) # Absolute name. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir + ac_abs_top_srcdir=$srcdir ;; + *) # Relative name. + ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_build_prefix$srcdir + ac_abs_top_srcdir=$ac_pwd/$srcdir ;; +esac +ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix + + + case $ac_mode in + + :H) + # + # CONFIG_HEADER + # + if test x"$ac_file" != x-; then + { + $as_echo "/* $configure_input */" \ + && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" + } >"$ac_tmp/config.h" \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + if diff "$ac_file" "$ac_tmp/config.h" >/dev/null 2>&1; then + { $as_echo "$as_me:${as_lineno-$LINENO}: $ac_file is unchanged" >&5 +$as_echo "$as_me: $ac_file is unchanged" >&6;} + else + rm -f "$ac_file" + mv "$ac_tmp/config.h" "$ac_file" \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + fi + else + $as_echo "/* $configure_input */" \ + && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" \ + || as_fn_error $? "could not create -" "$LINENO" 5 + fi + ;; + + + esac + +done # for ac_tag + + +as_fn_exit 0 +_ACEOF +ac_clean_files=$ac_clean_files_save + +test $ac_write_fail = 0 || + as_fn_error $? "write failure creating $CONFIG_STATUS" "$LINENO" 5 + + +# configure is writing to config.log, and then calls config.status. +# config.status does its own redirection, appending to config.log. +# Unfortunately, on DOS this fails, as config.log is still kept open +# by configure, so config.status won't be able to write to it; its +# output is simply discarded. So we exec the FD to /dev/null, +# effectively closing config.log, so it can be properly (re)opened and +# appended to by config.status. When coming back to configure, we +# need to make the FD available again. +if test "$no_create" != yes; then + ac_cs_success=: + ac_config_status_args= + test "$silent" = yes && + ac_config_status_args="$ac_config_status_args --quiet" + exec 5>/dev/null + $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false + exec 5>>config.log + # Use ||, not &&, to avoid exiting from the if with $? = 1, which + # would make configure fail if this is the last instruction. + $ac_cs_success || as_fn_exit 1 +fi +if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5 +$as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;} +fi + diff --git a/web/server/h2o/libh2o/deps/mruby-file-stat/configure.ac b/web/server/h2o/libh2o/deps/mruby-file-stat/configure.ac new file mode 100644 index 00000000..ce6be3fa --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby-file-stat/configure.ac @@ -0,0 +1,20 @@ +# -*- Autoconf -*- +# Process this file with autoconf to produce a configure script. + +AC_PREREQ([2.69]) +AC_INIT() + +AC_PROG_CC + +AC_CONFIG_SRCDIR([src/file-stat.c]) +AC_CONFIG_HEADERS([config.h]) + +AC_CHECK_MEMBERS([struct stat.st_blksize]) +AC_CHECK_MEMBERS([struct stat.st_blocks]) +AC_CHECK_MEMBERS([struct stat.st_rdev]) +AC_CHECK_MEMBERS([struct stat.st_birthtimespec]) + +AC_CHECK_FUNCS(getgroups) +AC_CHECK_FUNCS(lstat) + +AC_OUTPUT diff --git a/web/server/h2o/libh2o/deps/mruby-file-stat/mrbgem.rake b/web/server/h2o/libh2o/deps/mruby-file-stat/mrbgem.rake new file mode 100644 index 00000000..ff7d076b --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby-file-stat/mrbgem.rake @@ -0,0 +1,32 @@ +MRuby::Gem::Specification.new('mruby-file-stat') do |spec| + spec.license = 'MIT' + spec.author = 'ksss ' + spec.add_dependency('mruby-time') + + env = { + 'CC' => "#{build.cc.command} #{build.cc.flags.join(' ')}", + 'CXX' => "#{build.cxx.command} #{build.cxx.flags.join(' ')}", + 'LD' => "#{build.linker.command} #{build.linker.flags.join(' ')}", + 'AR' => build.archiver.command + } + config = "#{build_dir}/config.h" + + file config do + FileUtils.mkdir_p build_dir, :verbose => true + Dir.chdir build_dir do + if ENV['OS'] == 'Windows_NT' + _pp 'on Windows', dir + FileUtils.touch "#{build_dir}/config.h", :verbose => true + else + _pp './configure', dir + system env, "#{dir}/configure" + end + end + end + file "#{dir}/src/file-stat.c" => config + task :clean do + FileUtils.rm_f config, :verbose => true + end + + cc.include_paths << build_dir +end diff --git a/web/server/h2o/libh2o/deps/mruby-file-stat/mrblib/ext.rb b/web/server/h2o/libh2o/deps/mruby-file-stat/mrblib/ext.rb new file mode 100644 index 00000000..1fda1869 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby-file-stat/mrblib/ext.rb @@ -0,0 +1,5 @@ +class File + def self.stat(fname) + File::Stat.new(fname) + end +end diff --git a/web/server/h2o/libh2o/deps/mruby-file-stat/mrblib/file-stat.rb b/web/server/h2o/libh2o/deps/mruby-file-stat/mrblib/file-stat.rb new file mode 100644 index 00000000..23ded179 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby-file-stat/mrblib/file-stat.rb @@ -0,0 +1,52 @@ +class File + class Stat + include Comparable + + def <=>(other) + if other.kind_of?(self.class) + self.mtime <=> other.mtime + else + nil + end + end + + def inspect + _dev = dev + _dev = "0x#{_dev.to_s(16)}" if _dev.kind_of?(Fixnum) + _mode = mode + _mode = "0#{_mode.to_s(8)}" if _mode.kind_of?(Fixnum) + _rdev = rdev + _rdev = "0x#{_rdev.to_s(16)}" if _rdev.kind_of?(Fixnum) + + stats = { + 'dev' => _dev, + 'ino' => ino, + 'mode' => _mode, + 'nlink' => nlink, + 'uid' => uid, + 'gid' => gid, + 'rdev' => _rdev, + 'size' => size, + 'blksize' => blksize, + 'blocks' => blocks, + 'atime' => atime, + 'mtime' => mtime, + 'ctime' => ctime, + } + if respond_to? :birthtime + stats['birthtime'] = birthtime + end + + "#<#{self.class.to_s} #{stats.map{|k, v| "#{k}=#{v}"}.join(', ')}>" + end + + def size? + s = size + s == 0 ? nil : s + end + + def zero? + size == 0 + end + end +end diff --git a/web/server/h2o/libh2o/deps/mruby-file-stat/src/file-stat.c b/web/server/h2o/libh2o/deps/mruby-file-stat/src/file-stat.c new file mode 100644 index 00000000..f36ed197 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby-file-stat/src/file-stat.c @@ -0,0 +1,873 @@ +/** + * original is https://github.com/ruby/ruby/blob/trunk/file.c + */ + +#include "mruby.h" +#include "mruby/string.h" +#include "mruby/data.h" +#include "mruby/error.h" +#include "mruby/class.h" + +#include +#include +#include + +#if defined(_WIN32) || defined(_WIN64) + +#if !defined S_IXUSR && !defined __MINGW32__ +# define S_IXUSR 0100 +#endif +#ifndef S_IXGRP +# define S_IXGRP 0010 +#endif +#ifndef S_IXOTH +# define S_IXOTH 0001 +#endif + +#else +#include +#endif + +#ifndef S_IRUGO +# define S_IRUGO (S_IRUSR | S_IRGRP | S_IROTH) +#endif + +#ifndef S_IWUGO +# define S_IWUGO (S_IWUSR | S_IWGRP | S_IWOTH) +#endif + +#ifndef S_IXUGO +# define S_IXUGO (S_IXUSR | S_IXGRP | S_IXOTH) +#endif + +#ifndef S_ISLNK +# ifdef _S_ISLNK +# define S_ISLNK(m) _S_ISLNK(m) +# else +# ifdef _S_IFLNK +# define S_ISLNK(m) (((m) & S_IFMT) == _S_IFLNK) +# else +# ifdef S_IFLNK +# define S_ISLNK(m) (((m) & S_IFMT) == S_IFLNK) +# endif +# endif +# endif +#endif + +#ifdef S_IFIFO +# ifndef S_ISFIFO +# define S_ISFIFO(m) (((m) & S_IFMT) == S_IFIFO) +# endif +#endif + +#ifndef S_ISSOCK +# ifdef _S_ISSOCK +# define S_ISSOCK(m) _S_ISSOCK(m) +# else +# ifdef _S_IFSOCK +# define S_ISSOCK(m) (((m) & S_IFMT) == _S_IFSOCK) +# else +# ifdef S_IFSOCK +# define S_ISSOCK(m) (((m) & S_IFMT) == S_IFSOCK) +# endif +# endif +# endif +#endif + +#ifndef S_ISBLK +# ifdef S_IFBLK +# define S_ISBLK(m) (((m) & S_IFMT) == S_IFBLK) +# else +# define S_ISBLK(m) (0) /* anytime false */ +# endif +#endif + +#ifndef S_ISCHR +# define S_ISCHR(m) (((m) & S_IFMT) == S_IFCHR) +#endif + +#ifndef S_ISREG +# define S_ISREG(m) (((m) & S_IFMT) == S_IFREG) +#endif + +#ifndef S_ISDIR +# define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR) +#endif + +#include "config.h" + +#define STAT(p,s) stat(p,s) +#ifdef HAVE_LSTAT +# define LSTAT(p,s) lstat(p,s) +#else +# define LSTAT(p,s) stat(p,s) +#endif +#define MRB_MAX_GROUPS (65536) + +#if defined(_WIN32) || defined(_WIN64) +typedef unsigned int uid_t; +typedef unsigned int gid_t; +uid_t +getuid(void) +{ + return 0; +} +uid_t +geteuid(void) +{ + return 0; +} +gid_t +getgid(void) +{ + return 0; +} +gid_t +getegid(void) +{ + return 0; +} +#endif +#define GETGROUPS_T gid_t + +#if defined(S_IXGRP) && !defined(_WIN32) && !defined(__CYGWIN__) +# define USE_GETEUID 1 +#endif + +#ifdef __native_client__ +# undef USE_GETEUID +#endif + +struct mrb_data_type mrb_stat_type = { "File::Stat", mrb_free }; + +static struct stat * +mrb_stat_alloc(mrb_state *mrb) +{ + return (struct stat *)mrb_malloc(mrb, sizeof(struct stat)); +} + +static mrb_value +file_s_lstat(mrb_state *mrb, mrb_value klass) +{ + struct RClass *file_class; + struct RClass *stat_class; + struct stat st, *ptr; + mrb_value fname, tmp; + char *path; + + mrb_get_args(mrb, "o", &fname); + + tmp = mrb_check_convert_type(mrb, fname, MRB_TT_STRING, "String", "to_path"); + if (mrb_nil_p(tmp)) { + tmp = mrb_convert_type(mrb, fname, MRB_TT_STRING, "String", "to_str"); + } + path = mrb_str_to_cstr(mrb, tmp); + if (LSTAT(path, &st) == -1) { + mrb_sys_fail(mrb, path); + } + + file_class = mrb_class_ptr(klass); + stat_class = mrb_class_get_under(mrb, file_class, "Stat"); + ptr = mrb_stat_alloc(mrb); + *ptr = st; + + return mrb_obj_value(Data_Wrap_Struct(mrb, stat_class, &mrb_stat_type, ptr)); +} + +static mrb_value +stat_initialize(mrb_state *mrb, mrb_value self) +{ + struct stat st, *ptr; + mrb_value fname, tmp; + char *path; + + mrb_get_args(mrb, "o", &fname); + + tmp = mrb_check_convert_type(mrb, fname, MRB_TT_STRING, "String", "to_path"); + if (mrb_nil_p(tmp)) { + tmp = mrb_convert_type(mrb, fname, MRB_TT_STRING, "String", "to_str"); + } + path = mrb_str_to_cstr(mrb, tmp); + if (STAT(path, &st) == -1) { + mrb_sys_fail(mrb, path); + } + + ptr = (struct stat *)DATA_PTR(self); + if (ptr) { + mrb_free(mrb, ptr); + } + + ptr = mrb_stat_alloc(mrb); + *ptr = st; + + DATA_TYPE(self) = &mrb_stat_type; + DATA_PTR(self) = ptr; + + return mrb_nil_value(); +} + +static mrb_value +stat_initialize_copy(mrb_state *mrb, mrb_value copy) +{ + mrb_value orig; + + mrb_get_args(mrb, "o", &orig); + + if (mrb_obj_equal(mrb, copy, orig)) return copy; + + if (!mrb_obj_is_instance_of(mrb, orig, mrb_obj_class(mrb, copy))) { + mrb_raise(mrb, E_TYPE_ERROR, "wrong argument class"); + } + + if (DATA_PTR(copy)) { + mrb_free(mrb, DATA_PTR(copy)); + DATA_PTR(copy) = 0; + } + + if (DATA_PTR(orig)) { + DATA_PTR(copy) = mrb_malloc(mrb, sizeof(struct stat)); + DATA_TYPE(copy) = &mrb_stat_type; + *(struct stat *)DATA_PTR(copy) = *(struct stat *)DATA_PTR(orig); + } + return copy; +} + +static struct stat * +get_stat(mrb_state *mrb, mrb_value self) +{ + struct stat *st; + + st = (struct stat *)mrb_data_get_ptr(mrb, self, &mrb_stat_type); + if (!st) mrb_raise(mrb, E_TYPE_ERROR, "uninitialized File::Stat"); + return st; +} + +static mrb_value +mrb_ll2num(mrb_state *mrb, long long t) +{ + if (MRB_INT_MIN <= t && t <= MRB_INT_MAX) { + return mrb_fixnum_value((mrb_int)t); + } else { + return mrb_float_value(mrb, (mrb_float)t); + } +} + +static mrb_value +io_stat(mrb_state *mrb, mrb_value self) +{ + struct RClass *file_class; + struct RClass *stat_class; + struct stat st, *ptr; + mrb_value fileno; + + if (mrb_respond_to(mrb, self, mrb_intern_lit(mrb, "fileno"))) { + fileno = mrb_funcall(mrb, self, "fileno", 0); + } + else { + mrb_raise(mrb, E_NOTIMP_ERROR, "`fileno' is not implemented"); + } + + if (fstat(mrb_fixnum(fileno), &st) == -1) { + mrb_sys_fail(mrb, "fstat"); + } + + file_class = mrb_class_get(mrb, "File"); + stat_class = mrb_class_get_under(mrb, file_class, "Stat"); + ptr = mrb_stat_alloc(mrb); + *ptr = st; + + return mrb_obj_value(Data_Wrap_Struct(mrb, stat_class, &mrb_stat_type, ptr)); +} + +static mrb_value +stat_dev(mrb_state *mrb, mrb_value self) +{ + return mrb_fixnum_value(get_stat(mrb, self)->st_dev); +} + +static mrb_value +stat_dev_major(mrb_state *mrb, mrb_value self) +{ +#if defined(major) + return mrb_fixnum_value(major(get_stat(mrb, self)->st_dev)); +#else + return mrb_nil_value(); // NotImplemented +#endif +} + +static mrb_value +stat_dev_minor(mrb_state *mrb, mrb_value self) +{ +#if defined(minor) + return mrb_fixnum_value(minor(get_stat(mrb, self)->st_dev)); +#else + return mrb_nil_value(); // NotImplemented +#endif +} + +static mrb_value +stat_ino(mrb_state *mrb, mrb_value self) +{ + return mrb_ll2num(mrb, get_stat(mrb, self)->st_ino); +} + +static mrb_value +stat_mode(mrb_state *mrb, mrb_value self) +{ + return mrb_fixnum_value(get_stat(mrb, self)->st_mode); +} + +static mrb_value +stat_nlink(mrb_state *mrb, mrb_value self) +{ + return mrb_fixnum_value(get_stat(mrb, self)->st_nlink); +} + +static mrb_value +stat_uid(mrb_state *mrb, mrb_value self) +{ + return mrb_ll2num(mrb, get_stat(mrb, self)->st_uid); +} + +static mrb_value +stat_gid(mrb_state *mrb, mrb_value self) +{ + return mrb_ll2num(mrb, get_stat(mrb, self)->st_gid); +} + +static mrb_value +stat_rdev(mrb_state *mrb, mrb_value self) +{ + return mrb_fixnum_value(get_stat(mrb, self)->st_rdev); +} + +static mrb_value +stat_rdev_major(mrb_state *mrb, mrb_value self) +{ +#if defined(major) + return mrb_fixnum_value(major(get_stat(mrb, self)->st_rdev)); +#else + return mrb_nil_value(); // NotImplemented +#endif +} + +static mrb_value +stat_rdev_minor(mrb_state *mrb, mrb_value self) +{ +#if defined(minor) + return mrb_fixnum_value(minor(get_stat(mrb, self)->st_rdev)); +#else + return mrb_nil_value(); // NotImplemented +#endif +} + +static mrb_value +time_at_with_sec(mrb_state *mrb, long long sec) +{ + return mrb_funcall(mrb, mrb_obj_value(mrb_class_get(mrb, "Time")), "at", 1, mrb_ll2num(mrb, sec)); +} + +static mrb_value +stat_atime(mrb_state *mrb, mrb_value self) +{ + return time_at_with_sec(mrb, get_stat(mrb, self)->st_atime); +} + +static mrb_value +stat_mtime(mrb_state *mrb, mrb_value self) +{ + return time_at_with_sec(mrb, get_stat(mrb, self)->st_mtime); +} + +static mrb_value +stat_ctime(mrb_state *mrb, mrb_value self) +{ + return time_at_with_sec(mrb, get_stat(mrb, self)->st_ctime); +} + +#if defined(HAVE_STRUCT_STAT_ST_BIRTHTIMESPEC) +static mrb_value +stat_birthtime(mrb_state *mrb, mrb_value self) +{ + return time_at_with_sec(mrb, get_stat(mrb, self)->st_birthtimespec.tv_sec); +} +# define HAVE_METHOD_BIRTHTIME 1 +#elif defined(_WIN32) +# define stat_birthtime stat_ctime +# define HAVE_METHOD_BIRTHTIME 1 +#endif + +static mrb_value +stat_size(mrb_state *mrb, mrb_value self) +{ + return mrb_ll2num(mrb, get_stat(mrb, self)->st_size); +} + +static mrb_value +stat_blksize(mrb_state *mrb, mrb_value self) +{ +#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE + return mrb_fixnum_value(get_stat(mrb, self)->st_blksize); +#else + return mrb_nil_value(); +#endif +} + +static mrb_value +stat_blocks(mrb_state *mrb, mrb_value self) +{ +#ifdef HAVE_STRUCT_STAT_ST_BLOCKS + return mrb_ll2num(mrb, get_stat(mrb, self)->st_blocks); +#else + return mrb_nil_value(); +#endif +} + +static int +mrb_group_member(mrb_state *mrb, GETGROUPS_T gid) +{ +#if defined(_WIN32) || !defined(HAVE_GETGROUPS) + return FALSE; +#else + int rv = FALSE; + int groups = 16; + GETGROUPS_T *gary = NULL; + int anum = -1; + + if (getgid() == gid || getegid() == gid) + return TRUE; + + /* + * On Mac OS X (Mountain Lion), NGROUPS is 16. But libc and kernel + * accept more larger value. + * So we don't trunk NGROUPS anymore. + */ + while (groups <= MRB_MAX_GROUPS) { + gary = (GETGROUPS_T*)mrb_malloc(mrb, sizeof(GETGROUPS_T) * (unsigned int)groups); + anum = getgroups(groups, gary); + if (anum != -1 && anum != groups) + break; + groups *= 2; + if (gary) { + mrb_free(mrb, gary); + gary = 0; + } + } + if (anum == -1) + return FALSE; + + while (--anum >= 0) { + if (gary[anum] == gid) { + rv = TRUE; + break; + } + } + + if (gary) { + mrb_free(mrb, gary); + } + return rv; +#endif +} + +static mrb_value +stat_grpowned_p(mrb_state *mrb, mrb_value self) +{ +#ifndef _WIN32 + if (mrb_group_member(mrb, get_stat(mrb, self)->st_gid)) return mrb_true_value(); +#endif + return mrb_false_value(); +} + +static mrb_value +stat_readable_p(mrb_state *mrb, mrb_value self) +{ + struct stat *st; +#ifdef USE_GETEUID + if (geteuid() == 0) + return mrb_true_value(); +#endif + st = get_stat(mrb, self); +#ifdef S_IRUSR + if (st->st_uid == geteuid()) + return st->st_mode & S_IRUSR ? mrb_true_value() : mrb_false_value(); +#endif +#ifdef S_IRGRP + if (mrb_group_member(mrb, st->st_gid)) + return st->st_mode & S_IRGRP ? mrb_true_value() : mrb_false_value(); +#endif +#ifdef S_IROTH + if (!(st->st_mode & S_IROTH)) + return mrb_false_value(); +#endif + return mrb_true_value(); +} + +static mrb_value +stat_readable_real_p(mrb_state *mrb, mrb_value self) +{ + struct stat *st; + +#ifdef USE_GETEUID + if (getuid() == 0) + return mrb_true_value(); +#endif + st = get_stat(mrb, self); +#ifdef S_IRUSR + if (st->st_uid == getuid()) + return st->st_mode & S_IRUSR ? mrb_true_value() : mrb_false_value(); +#endif +#ifdef S_IRGRP + if (mrb_group_member(mrb, st->st_gid)) + return st->st_mode & S_IRGRP ? mrb_true_value() : mrb_false_value(); +#endif +#ifdef S_IROTH + if (!(st->st_mode & S_IROTH)) return mrb_false_value(); +#endif + return mrb_true_value(); +} + +static mrb_value +stat_world_readable_p(mrb_state *mrb, mrb_value self) +{ +#ifdef S_IROTH + struct stat *st = get_stat(mrb, self); + if ((st->st_mode & (S_IROTH)) == S_IROTH) { + return mrb_fixnum_value(st->st_mode & (S_IRUGO|S_IWUGO|S_IXUGO)); + } + else { + return mrb_nil_value(); + } +#else + return mrb_nil_value(); +#endif +} + + +static mrb_value +stat_writable_p(mrb_state *mrb, mrb_value self) +{ + struct stat *st; + +#ifdef USE_GETEUID + if (geteuid() == 0) + return mrb_true_value(); +#endif + st = get_stat(mrb, self); +#ifdef S_IWUSR + if (st->st_uid == geteuid()) + return st->st_mode & S_IWUSR ? mrb_true_value() : mrb_false_value(); +#endif +#ifdef S_IWGRP + if (mrb_group_member(mrb, st->st_gid)) + return st->st_mode & S_IWGRP ? mrb_true_value() : mrb_false_value(); +#endif +#ifdef S_IWOTH + if (!(st->st_mode & S_IWOTH)) + return mrb_false_value(); +#endif + return mrb_true_value(); +} + +static mrb_value +stat_writable_real_p(mrb_state *mrb, mrb_value self) +{ + struct stat *st; + +#ifdef USE_GETEUID + if (getuid() == 0) + return mrb_true_value(); +#endif + st = get_stat(mrb, self); +#ifdef S_IWUSR + if (st->st_uid == getuid()) + return st->st_mode & S_IWUSR ? mrb_true_value() : mrb_false_value(); +#endif +#ifdef S_IWGRP + if (mrb_group_member(mrb, st->st_gid)) + return st->st_mode & S_IWGRP ? mrb_true_value() : mrb_false_value(); +#endif +#ifdef S_IWOTH + if (!(st->st_mode & S_IWOTH)) return mrb_false_value(); +#endif + return mrb_true_value(); +} + +static mrb_value +stat_world_writable_p(mrb_state *mrb, mrb_value self) +{ +#ifdef S_IROTH + struct stat *st = get_stat(mrb, self); + if ((st->st_mode & (S_IROTH)) == S_IROTH) { + return mrb_fixnum_value(st->st_mode & (S_IRUGO|S_IWUGO|S_IXUGO)); + } + else { + return mrb_nil_value(); + } +#else + return mrb_nil_value(); +#endif +} + +static mrb_value +stat_executable_p(mrb_state *mrb, mrb_value self) +{ + struct stat *st = get_stat(mrb, self); + +#ifdef USE_GETEUID + if (geteuid() == 0) { + return st->st_mode & S_IXUGO ? mrb_true_value() : mrb_false_value(); +} +#endif +#ifdef S_IXUSR + if (st->st_uid == geteuid()) + return st->st_mode & S_IXUSR ? mrb_true_value() : mrb_false_value(); +#endif +#ifdef S_IXGRP + if (mrb_group_member(mrb, st->st_gid)) + return st->st_mode & S_IXGRP ? mrb_true_value() : mrb_false_value(); +#endif +#ifdef S_IXOTH + if (!(st->st_mode & S_IXOTH)) + return mrb_false_value(); +#endif + return mrb_true_value(); +} + +static mrb_value +stat_executable_real_p(mrb_state *mrb, mrb_value self) +{ + struct stat *st = get_stat(mrb, self); + +#ifdef USE_GETEUID + if (getuid() == 0) + return st->st_mode & S_IXUGO ? mrb_true_value() : mrb_false_value(); +#endif +#ifdef S_IXUSR + if (st->st_uid == getuid()) + return st->st_mode & S_IXUSR ? mrb_true_value() : mrb_false_value(); +#endif +#ifdef S_IXGRP + if (mrb_group_member(mrb, st->st_gid)) + return st->st_mode & S_IXGRP ? mrb_true_value() : mrb_false_value(); +#endif +#ifdef S_IXOTH + if (!(st->st_mode & S_IXOTH)) return mrb_false_value(); +#endif + return mrb_true_value(); +} + +static mrb_value +stat_symlink_p(mrb_state *mrb, mrb_value self) +{ +#ifdef S_ISLNK + if (S_ISLNK(get_stat(mrb, self)->st_mode)) + return mrb_true_value(); +#endif + return mrb_false_value(); +} + +static mrb_value +stat_file_p(mrb_state *mrb, mrb_value self) +{ + if (S_ISREG(get_stat(mrb, self)->st_mode)) + return mrb_true_value(); + return mrb_false_value(); +} + +static mrb_value +stat_directory_p(mrb_state *mrb, mrb_value self) +{ + if (S_ISDIR(get_stat(mrb, self)->st_mode)) + return mrb_true_value(); + return mrb_false_value(); +} + +static mrb_value +stat_chardev_p(mrb_state *mrb, mrb_value self) +{ + if (S_ISCHR(get_stat(mrb, self)->st_mode)) + return mrb_true_value(); + return mrb_false_value(); +} + +static mrb_value +stat_blockdev_p(mrb_state *mrb, mrb_value self) +{ +#ifdef S_ISBLK + if (S_ISBLK(get_stat(mrb, self)->st_mode)) + return mrb_true_value(); +#endif + return mrb_false_value(); +} + +static mrb_value +stat_pipe_p(mrb_state *mrb, mrb_value self) +{ +#ifdef S_ISFIFO + if (S_ISFIFO(get_stat(mrb, self)->st_mode)) + return mrb_true_value(); +#endif + return mrb_false_value(); +} + +static mrb_value +stat_socket_p(mrb_state *mrb, mrb_value self) +{ +#ifdef S_ISSOCK + if (S_ISSOCK(get_stat(mrb, self)->st_mode)) + return mrb_true_value(); +#endif + return mrb_false_value(); +} + +static mrb_value +stat_setuid_p(mrb_state *mrb, mrb_value self) +{ +#ifdef S_ISUID + if (get_stat(mrb, self)->st_mode & S_ISUID) + return mrb_true_value(); +#endif + return mrb_false_value(); +} + +static mrb_value +stat_setgid_p(mrb_state *mrb, mrb_value self) +{ +#ifdef S_ISGID + if (get_stat(mrb, self)->st_mode & S_ISGID) + return mrb_true_value(); +#endif + return mrb_false_value(); +} + +static mrb_value +stat_sticky_p(mrb_state *mrb, mrb_value self) +{ +#ifdef S_ISVTX + if (get_stat(mrb, self)->st_mode & S_ISVTX) + return mrb_true_value(); +#endif + return mrb_false_value(); +} + +static mrb_value +stat_ftype(mrb_state *mrb, mrb_value self) +{ + struct stat *st = get_stat(mrb, self); + const char *t; + + if (S_ISREG(st->st_mode)) { + t = "file"; + } + else if (S_ISDIR(st->st_mode)) { + t = "directory"; + } + else if (S_ISCHR(st->st_mode)) { + t = "characterSpecial"; + } +#ifdef S_ISBLK + else if (S_ISBLK(st->st_mode)) { + t = "blockSpecial"; + } +#endif +#ifdef S_ISFIFO + else if (S_ISFIFO(st->st_mode)) { + t = "fifo"; + } +#endif +#ifdef S_ISLNK + else if (S_ISLNK(st->st_mode)) { + t = "link"; + } +#endif +#ifdef S_ISSOCK + else if (S_ISSOCK(st->st_mode)) { + t = "socket"; + } +#endif + else { + t = "unknown"; + } + return mrb_str_new_static(mrb, t, (size_t)strlen(t)); +} + +static mrb_value +stat_owned_p(mrb_state *mrb, mrb_value self) +{ + return get_stat(mrb, self)->st_uid == geteuid() ? mrb_true_value() : mrb_false_value(); +} + +static mrb_value +stat_owned_real_p(mrb_state *mrb, mrb_value self) +{ + return get_stat(mrb, self)->st_uid == getuid() ? mrb_true_value() : mrb_false_value(); +} + +void +mrb_mruby_file_stat_gem_init(mrb_state* mrb) +{ + struct RClass *io = mrb_define_class(mrb, "IO", mrb->object_class); + struct RClass *file = mrb_define_class(mrb, "File", io); + struct RClass *stat = mrb_define_class_under(mrb, file, "Stat", mrb->object_class); + + MRB_SET_INSTANCE_TT(stat, MRB_TT_DATA); + + mrb_define_method(mrb, io, "stat", io_stat, MRB_ARGS_NONE()); + + mrb_define_class_method(mrb, file, "lstat", file_s_lstat, MRB_ARGS_REQ(1)); + + mrb_define_method(mrb, stat, "initialize", stat_initialize, MRB_ARGS_REQ(1)); + mrb_define_method(mrb, stat, "initialize_copy", stat_initialize_copy, MRB_ARGS_REQ(1)); + mrb_define_method(mrb, stat, "dev", stat_dev, MRB_ARGS_NONE()); + mrb_define_method(mrb, stat, "dev_major", stat_dev_major, MRB_ARGS_NONE()); + mrb_define_method(mrb, stat, "dev_minor", stat_dev_minor, MRB_ARGS_NONE()); + mrb_define_method(mrb, stat, "ino", stat_ino, MRB_ARGS_NONE()); + mrb_define_method(mrb, stat, "mode", stat_mode, MRB_ARGS_NONE()); + mrb_define_method(mrb, stat, "nlink", stat_nlink, MRB_ARGS_NONE()); + mrb_define_method(mrb, stat, "uid", stat_uid, MRB_ARGS_NONE()); + mrb_define_method(mrb, stat, "gid", stat_gid, MRB_ARGS_NONE()); + mrb_define_method(mrb, stat, "rdev", stat_rdev, MRB_ARGS_NONE()); + mrb_define_method(mrb, stat, "rdev_major", stat_rdev_major, MRB_ARGS_NONE()); + mrb_define_method(mrb, stat, "rdev_minor", stat_rdev_minor, MRB_ARGS_NONE()); + mrb_define_method(mrb, stat, "atime", stat_atime, MRB_ARGS_NONE()); + mrb_define_method(mrb, stat, "mtime", stat_mtime, MRB_ARGS_NONE()); + mrb_define_method(mrb, stat, "ctime", stat_ctime, MRB_ARGS_NONE()); +#ifdef HAVE_METHOD_BIRTHTIME + mrb_define_method(mrb, stat, "birthtime", stat_birthtime, MRB_ARGS_NONE()); +#endif + mrb_define_method(mrb, stat, "size", stat_size, MRB_ARGS_NONE()); + mrb_define_method(mrb, stat, "blksize", stat_blksize, MRB_ARGS_NONE()); + mrb_define_method(mrb, stat, "blocks", stat_blocks, MRB_ARGS_NONE()); + mrb_define_method(mrb, stat, "grpowned?", stat_grpowned_p, MRB_ARGS_NONE()); + mrb_define_method(mrb, stat, "readable?", stat_readable_p, MRB_ARGS_NONE()); + mrb_define_method(mrb, stat, "readable_real?", stat_readable_real_p, MRB_ARGS_NONE()); + mrb_define_method(mrb, stat, "world_readable?", stat_world_readable_p, MRB_ARGS_NONE()); + mrb_define_method(mrb, stat, "writable?", stat_writable_p, MRB_ARGS_NONE()); + mrb_define_method(mrb, stat, "writable_real?", stat_writable_real_p, MRB_ARGS_NONE()); + mrb_define_method(mrb, stat, "world_writable?", stat_world_writable_p, MRB_ARGS_NONE()); + mrb_define_method(mrb, stat, "executable?", stat_executable_p, MRB_ARGS_NONE()); + mrb_define_method(mrb, stat, "executable_real?", stat_executable_real_p, MRB_ARGS_NONE()); + + mrb_define_method(mrb, stat, "symlink?", stat_symlink_p, MRB_ARGS_NONE()); + mrb_define_method(mrb, stat, "file?", stat_file_p, MRB_ARGS_NONE()); + mrb_define_method(mrb, stat, "directory?", stat_directory_p, MRB_ARGS_NONE()); + mrb_define_method(mrb, stat, "chardev?", stat_chardev_p, MRB_ARGS_NONE()); + mrb_define_method(mrb, stat, "blockdev?", stat_blockdev_p, MRB_ARGS_NONE()); + mrb_define_method(mrb, stat, "pipe?", stat_pipe_p, MRB_ARGS_NONE()); + mrb_define_method(mrb, stat, "socket?", stat_socket_p, MRB_ARGS_NONE()); + + mrb_define_method(mrb, stat, "setuid?", stat_setuid_p, MRB_ARGS_NONE()); + mrb_define_method(mrb, stat, "setgid?", stat_setgid_p, MRB_ARGS_NONE()); + mrb_define_method(mrb, stat, "sticky?", stat_sticky_p, MRB_ARGS_NONE()); + + mrb_define_method(mrb, stat, "ftype", stat_ftype, MRB_ARGS_NONE()); + + mrb_define_method(mrb, stat, "owned?", stat_owned_p, MRB_ARGS_NONE()); + mrb_define_method(mrb, stat, "owned_real?", stat_owned_real_p, MRB_ARGS_NONE()); +} + +void +mrb_mruby_file_stat_gem_final(mrb_state* mrb) +{ +} diff --git a/web/server/h2o/libh2o/deps/mruby-file-stat/test/executable b/web/server/h2o/libh2o/deps/mruby-file-stat/test/executable new file mode 100644 index 00000000..e69de29b diff --git a/web/server/h2o/libh2o/deps/mruby-file-stat/test/file-stat.c b/web/server/h2o/libh2o/deps/mruby-file-stat/test/file-stat.c new file mode 100644 index 00000000..4e596648 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby-file-stat/test/file-stat.c @@ -0,0 +1,30 @@ +#include +#include + +static mrb_value +test_system(mrb_state *mrb, mrb_value klass) +{ + char *cmd = NULL; + mrb_get_args(mrb, "z", &cmd); + system(cmd); + return mrb_nil_value(); +} + +static mrb_value +test_win_p(mrb_state *mrb, mrb_value klass) +{ +#if defined(_WIN32) + return mrb_true_value(); +#else + return mrb_false_value(); +#endif +} + +void mrb_mruby_file_stat_gem_test(mrb_state *mrb) +{ + struct RClass *t; + + t = mrb_define_class(mrb, "FileStatTest", mrb->object_class); + mrb_define_module_function(mrb, t, "system", test_system, MRB_ARGS_REQ(1)); + mrb_define_module_function(mrb, t, "win?", test_win_p, MRB_ARGS_NONE()); +} diff --git a/web/server/h2o/libh2o/deps/mruby-file-stat/test/file-stat.rb b/web/server/h2o/libh2o/deps/mruby-file-stat/test/file-stat.rb new file mode 100644 index 00000000..63906d01 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby-file-stat/test/file-stat.rb @@ -0,0 +1,369 @@ +class FileStatTest + class << self + def chmod(mode, path) + system("chmod #{mode} #{path}") + yield + ensure + system("chmod 644 #{path}") + end + end +end + +assert 'File::Stat.new' do + assert_kind_of File::Stat, File::Stat.new('README.md') + assert_raise(RuntimeError){ File::Stat.new('unknown.file') } +end + +assert 'File.stat' do + assert_kind_of File::Stat, File.stat('README.md') +end + +assert 'File.lstat' do + assert_kind_of File::Stat, File.lstat('README.md') +end + +assert 'File::Stat#initialize_copy' do + orig = File::Stat.new('README.md') + copy = orig.dup + assert_equal orig.inspect, copy.inspect +end + +assert 'File::Stat#<=>' do + stat1 = File::Stat.new('README.md') + stat2 = File::Stat.new('README.md') + assert_equal 0, stat1.<=>(stat2) + assert_equal nil, stat1.<=>(1) + assert_raise(ArgumentError) { stat1 < 1 } +end + +assert 'File::Stat#dev' do + stat = File::Stat.new('README.md') + assert_kind_of Fixnum, stat.dev +end + +assert 'File::Stat#dev_major' do + stat = File::Stat.new('README.md') + if stat.dev_major + assert_equal Fixnum, stat.dev_major.class + else + assert_nil stat.dev_major ## not supported + end +end + +assert 'File::Stat#dev_minor' do + stat = File::Stat.new('README.md') + if stat.dev_minor + assert_equal Fixnum, stat.dev_minor.class + else + assert_nil stat.dev_minor ## not supported + end +end + +assert 'File::Stat#ino' do + stat = File::Stat.new('README.md') + assert_kind_of Numeric, stat.ino +end + +assert 'File::Stat#mode' do + stat = File::Stat.new('README.md') + assert_kind_of Fixnum, stat.mode +end + +assert 'File::Stat#nlink' do + stat = File::Stat.new('README.md') + assert_kind_of Fixnum, stat.nlink +end + +assert 'File::Stat#uid' do + stat = File::Stat.new('README.md') + assert_kind_of Numeric, stat.uid +end + +assert 'File::Stat#gid' do + stat = File::Stat.new('README.md') + assert_kind_of Numeric, stat.gid +end + +assert 'File::Stat#rdev' do + stat = File::Stat.new('README.md') + assert_kind_of Fixnum, stat.rdev +end + +assert 'File::Stat#rdev_major' do + stat = File::Stat.new('README.md') + if stat.rdev_major + assert_equal Fixnum, stat.rdev_major.class + else + assert_nil stat.rdev_major ## not supported + end +end + +assert 'File::Stat#rdev_minor' do + stat = File::Stat.new('README.md') + if stat.rdev_minor + assert_equal Fixnum, stat.rdev_minor.class + else + assert_nil stat.rdev_minor ## not supported + end +end + +assert 'File::Stat#blocks' do + stat = File::Stat.new('README.md') + blocks = stat.blocks + skip "This system not support `struct stat.st_blocks`" if blocks.nil? + + assert_kind_of Integer, blocks +end + +assert 'File::Stat#atime' do + stat = File::Stat.new('README.md') + assert_kind_of Time, stat.atime +end + +assert 'File::Stat#mtime' do + stat = File::Stat.new('README.md') + assert_kind_of Time, stat.mtime +end + +assert 'File::Stat#ctime' do + stat = File::Stat.new('README.md') + assert_kind_of Time, stat.ctime +end + +assert 'File::Stat#birthtime' do + stat = File::Stat.new('README.md') + begin + assert_kind_of Time, stat.birthtime + rescue NameError + skip 'This system not support `struct stat.birthtimespec`' + end +end + +assert 'File::Stat#size' do + stat = File::Stat.new('README.md') + assert_true 0 < stat.size +end + +assert 'File::Stat#blksize' do + stat = File::Stat.new('README.md') + blksize = stat.blksize + skip "This system not support `struct stat.st_blksize`" if blksize.nil? + + assert_kind_of Integer, blksize +end + +assert 'File::Stat#inspect' do + stat = File::Stat.new('README.md') + %w(dev ino mode nlink uid gid size blksize blocks atime mtime ctime).all? do |name| + assert_include stat.inspect, name + end +end + +assert 'File::Stat#ftype' do + stat = File::Stat.new('README.md') + assert_equal "file", stat.ftype + + stat = File::Stat.new('bin') + assert_equal "directory", stat.ftype +end + +assert 'File::Stat#directory?' do + stat = File::Stat.new('README.md') + assert_false stat.directory? + + stat = File::Stat.new('bin') + assert_true stat.directory? +end + +assert 'File::Stat#readable?' do + skip "when windows" if FileStatTest.win? + + dir = __FILE__[0..-18] # 18 = /test/file-stat.rb + FileStatTest.chmod("+r-w-x", "#{dir}/test/readable") do + assert_true File::Stat.new("#{dir}/test/readable").readable? + end + FileStatTest.chmod("-r+w-x", "#{dir}/test/writable") do + assert_false File::Stat.new("#{dir}/test/writable").readable? + end + FileStatTest.chmod("-r-w+x", "#{dir}/test/executable") do + assert_false File::Stat.new("#{dir}/test/executable").readable? + end +end + +assert 'File::Stat#readable_real?' do + skip "when windows" if FileStatTest.win? + + dir = __FILE__[0..-18] # 18 = /test/file-stat.rb + FileStatTest.chmod("+r-w-x", "#{dir}/test/readable") do + assert_true File::Stat.new("#{dir}/test/readable").readable_real? + end + FileStatTest.chmod("-r+w-x", "#{dir}/test/writable") do + assert_false File::Stat.new("#{dir}/test/writable").readable_real? + end + FileStatTest.chmod("-r-w+x", "#{dir}/test/executable") do + assert_false File::Stat.new("#{dir}/test/executable").readable_real? + end +end + +assert 'File::Stat#world_readable?' do + skip "when windows" if FileStatTest.win? + + dir = __FILE__[0..-18] # 18 = /test/file-stat.rb + FileStatTest.system("chmod 0400 #{dir}/test/readable") + assert_equal nil, File::Stat.new("#{dir}/test/readable").world_readable? + FileStatTest.system("chmod 0444 #{dir}/test/readable") + assert_equal 0444, File::Stat.new("#{dir}/test/readable").world_readable? +end + +assert 'File::Stat#writable?' do + dir = __FILE__[0..-18] # 18 = /test/file-stat.rb + FileStatTest.chmod("+r-w-x", "#{dir}/test/readable") do + assert_false File::Stat.new("#{dir}/test/readable").writable? + end + FileStatTest.chmod("-r+w-x", "#{dir}/test/writable") do + assert_true File::Stat.new("#{dir}/test/writable").writable? + end + FileStatTest.chmod("-r-w+x", "#{dir}/test/executable") do + assert_false File::Stat.new("#{dir}/test/executable").writable? + end +end + +assert 'File::Stat#writable_real?' do + dir = __FILE__[0..-18] # 18 = /test/file-stat.rb + FileStatTest.chmod("+r-w-x", "#{dir}/test/readable") do + assert_false File::Stat.new("#{dir}/test/readable").writable_real? + end + FileStatTest.chmod("-r+w-x", "#{dir}/test/writable") do + assert_true File::Stat.new("#{dir}/test/writable").writable_real? + end + FileStatTest.chmod("-r-w+x", "#{dir}/test/executable") do + assert_false File::Stat.new("#{dir}/test/executable").writable_real? + end +end + +assert 'File::Stat#world_writable?' do + skip "when windows" if FileStatTest.win? + + dir = __FILE__[0..-18] # 18 = /test/file-stat.rb + FileStatTest.chmod("0600", "#{dir}/test/writable") do + assert_equal nil, File::Stat.new("#{dir}/test/writable").world_writable? + end + FileStatTest.chmod("0666", "#{dir}/test/writable") do + assert_equal 0666, File::Stat.new("#{dir}/test/writable").world_writable? + end +end + +assert 'File::Stat#executable?' do + skip "when windows" if FileStatTest.win? + + dir = __FILE__[0..-18] # 18 = /test/file-stat.rb + FileStatTest.chmod("+r-w-x", "#{dir}/test/readable") do + assert_false File::Stat.new("#{dir}/test/readable").executable? + end + FileStatTest.chmod("-r+w-x", "#{dir}/test/writable") do + assert_false File::Stat.new("#{dir}/test/writable").executable? + end + FileStatTest.chmod("-r-w+x", "#{dir}/test/executable") do + assert_true File::Stat.new("#{dir}/test/executable").executable? + end +end + +assert 'File::Stat#executable_real?' do + skip "when windows" if FileStatTest.win? + + dir = __FILE__[0..-18] # 18 = /test/file-stat.rb + FileStatTest.chmod("+r-w-x", "#{dir}/test/readable") do + assert_false File::Stat.new("#{dir}/test/readable").executable_real? + end + FileStatTest.chmod("-r+w-x", "#{dir}/test/writable") do + assert_false File::Stat.new("#{dir}/test/writable").executable_real? + end + FileStatTest.chmod("-r-w+x", "#{dir}/test/executable") do + assert_true File::Stat.new("#{dir}/test/executable").executable_real? + end +end + +assert 'File::Stat#file?' do + stat = File::Stat.new('README.md') + assert_true stat.file? + + stat = File::Stat.new('bin') + assert_false stat.file? +end + +assert 'File::Stat#zero?' do + stat = File::Stat.new('README.md') + assert_false stat.zero? +end + +assert 'File::Stat#size?' do + stat = File::Stat.new('README.md') + assert_true 0 < stat.size? +end + +assert 'File::Stat#owned?' do + stat = File::Stat.new('README.md') + assert_true stat.owned? +end + +assert 'File::Stat#owned_real?' do + stat = File::Stat.new('README.md') + assert_true stat.owned_real? +end + +assert 'File::Stat#grpowned?' do + is_unix = File::Stat.new('/dev/tty') rescue false + if is_unix + stat = File::Stat.new('README.md') + assert_true stat.grpowned? + else + skip "is not supported" + end +end + +assert 'File::Stat#pipe?' do + stat = File::Stat.new('README.md') + assert_false stat.pipe? +end + +assert 'File::Stat#symlink?' do + stat = File::Stat.new('README.md') + assert_false stat.symlink? +end + +assert 'File::Stat#socket?' do + stat = File::Stat.new('README.md') + assert_false stat.socket? +end + +assert 'File::Stat#blockdev?' do + stat = File::Stat.new('README.md') + assert_false stat.blockdev? +end + +assert 'File::Stat#chardev?' do + stat = File::Stat.new('README.md') + assert_false stat.chardev? + + begin + stat = File::Stat.new('/dev/tty') + assert_true stat.chardev? + rescue RuntimeError + skip '/dev/tty is not found' + end +end + +assert 'File::Stat#setuid?' do + stat = File::Stat.new('README.md') + assert_false stat.setuid? +end + +assert 'File::Stat#setgid?' do + stat = File::Stat.new('README.md') + assert_false stat.setgid? +end + +assert 'File::Stat#sticky?' do + stat = File::Stat.new('README.md') + assert_false stat.sticky? +end diff --git a/web/server/h2o/libh2o/deps/mruby-file-stat/test/io.rb b/web/server/h2o/libh2o/deps/mruby-file-stat/test/io.rb new file mode 100644 index 00000000..47e63089 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby-file-stat/test/io.rb @@ -0,0 +1,7 @@ +assert 'IO#stat' do + # You can use IO#stat if implemented to IO#fileno + # mruby-file-stat is just not implemented this. + assert_raise(NotImplementedError) do + IO.new(1).stat + end +end diff --git a/web/server/h2o/libh2o/deps/mruby-file-stat/test/readable b/web/server/h2o/libh2o/deps/mruby-file-stat/test/readable new file mode 100644 index 00000000..e69de29b diff --git a/web/server/h2o/libh2o/deps/mruby-file-stat/test/writable b/web/server/h2o/libh2o/deps/mruby-file-stat/test/writable new file mode 100644 index 00000000..e69de29b diff --git a/web/server/h2o/libh2o/deps/mruby-iijson/.gitignore b/web/server/h2o/libh2o/deps/mruby-iijson/.gitignore new file mode 100644 index 00000000..ceeb05b4 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby-iijson/.gitignore @@ -0,0 +1 @@ +/tmp diff --git a/web/server/h2o/libh2o/deps/mruby-iijson/.travis.yml b/web/server/h2o/libh2o/deps/mruby-iijson/.travis.yml new file mode 100644 index 00000000..ffe22728 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby-iijson/.travis.yml @@ -0,0 +1,2 @@ +script: + - "ruby run_test.rb all test" diff --git a/web/server/h2o/libh2o/deps/mruby-iijson/README.md b/web/server/h2o/libh2o/deps/mruby-iijson/README.md new file mode 100644 index 00000000..bbbfeba6 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby-iijson/README.md @@ -0,0 +1,87 @@ +# mruby-iijson +[![Build Status](https://travis-ci.org/iij/mruby-iijson.svg?branch=master)](https://travis-ci.org/iij/mruby-iijson) + +"mruby-iijson" is JSON module for mruby. + + +## Implemented Methods: + - [JSON.dump](http://docs.ruby-lang.org/en/2.2.0/JSON.html#method-i-dump) + - [JSON.generate](http://docs.ruby-lang.org/en/2.2.0/JSON.html#method-i-generate) + - [JSON.load](http://docs.ruby-lang.org/en/2.2.0/JSON.html#method-i-load) + - [JSON.parse](http://docs.ruby-lang.org/en/2.2.0/JSON.html#method-i-parse) + - `Array#to_json`, `Fixnum#to_json`, `Float#to_json`, `Hash#to_json`, `String#to_json`, ... + +## Example: + +```Ruby +str = '{ + "Image": { + "Width": 800, + "Height": 600, + "Title": "View from 15th Floor", + "Thumbnail": { + "Url": "http://www.example.com/image/481989943", + "Height": 125, + "Width": "100" + }, + "IDs": [116, 943, 234, 38793] + } +}' +p JSON.parse(str) + +h = { + :precision => "zip", + :Latitude => 37.7668, + :Longitude => -122.3959, + :Address => "", + :City => "SAN FRANCISCO", + :State => "CA", + :Zip => "94107", + :Country => "US" +} +p h.to_json +puts JSON.generate(h, {:pretty_print => true, :indent_with => 2}) +``` + +``` +{"Image"=>{"Width"=>800, "Height"=>600, "Title"=>"View from 15th Floor", "Thumbnail"=>{"Url"=>"http://www.example.com/image/481989943", "Height"=>125, "Width"=>"100"}, "IDs"=>[116, 943, 234, 38793]}} +"{\"precision\":\"zip\",\"Latitude\":37.766800000000003,\"Longitude\":-122.3959,\"Address\":\"\",\"City\":\"SAN FRANCISCO\",\"State\":\"CA\",\"Zip\":\"94107\",\"Country\":\"US\"}" +{ + "precision": "zip", + "Latitude": 37.766800000000003, + "Longitude": -122.3959, + "Address": "", + "City": "SAN FRANCISCO", + "State": "CA", + "Zip": "94107", + "Country": "US" +} +``` + + +## Caveats + + - JSON.generate won't return if input Array/Hash has circular reference. + + +## License + +Copyright (c) 2014 Internet Initiative Japan Inc. + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the "Software"), +to deal in the Software without restriction, including without limitation +the rights to use, copy, modify, merge, publish, distribute, sublicense, +and/or sell copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. diff --git a/web/server/h2o/libh2o/deps/mruby-iijson/mrbgem.rake b/web/server/h2o/libh2o/deps/mruby-iijson/mrbgem.rake new file mode 100644 index 00000000..fef1c3dd --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby-iijson/mrbgem.rake @@ -0,0 +1,6 @@ +MRuby::Gem::Specification.new('mruby-iijson') do |spec| + spec.license = 'MIT' + spec.author = 'Internet Initiative Japan Inc.' + + spec.add_dependency "mruby-sprintf", :core => "mruby-sprintf" +end diff --git a/web/server/h2o/libh2o/deps/mruby-iijson/mrblib/json.rb b/web/server/h2o/libh2o/deps/mruby-iijson/mrblib/json.rb new file mode 100755 index 00000000..87b5a6bd --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby-iijson/mrblib/json.rb @@ -0,0 +1,129 @@ +module JSON + def self.dump(object, io=nil, limit=nil) + state = {} + state[:max_nesting] = limit if limit + begin + js = JSON.generate(object, nil, state) + rescue JSON::NestingError + raise ArgumentError, "exceeded depth limit" + end + if io + io.write js + io + else + js + end + end + + def self.generate(obj, options=nil, state=nil) + options = (options || {}).to_hash unless options.is_a? Hash + options[:pretty_print] ||= false + options[:indent_with] ||= 2 + state = (state || {}).to_hash unless state.is_a? Hash + state[:max_nesting] ||= 100 + state[:nesting] = 0 + self.generate0(obj, options, state) + end + + def self.generate0(obj, options, state) + if state[:nesting] >= state[:max_nesting] + raise JSON::NestingError, "nesting of #{state[:nesting]} is too deep" + end + + pretty = options[:pretty_print] + + if pretty + indent = options[:indent_with].class == Fixnum ? " " * options[:indent_with] : options[:indent_with] + else + indent = "" + end + + nl = pretty ? "\n" : "" + + if obj == false + return "false" + + elsif obj == nil + return "null" + + elsif obj == true + return "true" + + elsif obj.is_a? Hash + members = [] + state[:nesting] += 1 + obj.each { |k, v| + members << JSON.generate0(k, options, state) + ":" + (pretty ? " " : "") + JSON.generate0(v, options, state) + } + if pretty + members.map! { |k| (indent * state[:nesting]) + "#{k}" }.join("_") + end + state[:nesting] -= 1 + return "{" + nl + members.join("," + nl) + nl + (indent * state[:nesting]) + "}" + + elsif obj.is_a? Array + state[:nesting] += 1 + members = obj.map { |v| JSON.generate0(v, options, state) } + if pretty + members.map! { |k| (indent * state[:nesting]) + "#{k}" }.join("_") + end + state[:nesting] -= 1 + return "[" + nl + members.join("," + nl) + nl + (indent * state[:nesting]) + "]" + + elsif obj.is_a? Fixnum + return obj.to_s + + elsif obj.is_a? Float + if obj.infinite? or obj.nan? + raise GeneratorError, "#{obj.to_s} not allowed in JSON" + end + sprintf "%.17g", obj + + else + a = [] + obj.to_s.each_char { |ch| + a << if ch < "\x20" + case ch + when "\x08" + "\\b" + when "\x0c" + "\\f" + when "\x0a" + "\\n" + when "\x0d" + "\\r" + when "\x09" + "\\t" + else + raise GeneratorError, "cannot convert #{ch.inspect} to JSON" + end + elsif ch == '"' + '\\"' + elsif ch == '\\' + "\\\\" + else + ch + end + } + return '"' + a.join + '"' + end + end + + def self.load(source) # TODO: proc, options + source = source.read unless source.is_a? String + JSON.parse source + end + + class JSONError < StandardError; end + class GeneratorError < JSONError; end + class ParserError < JSONError; end + class NestingError < ParserError; end +end + +unless Float.method_defined? :nan? + class Float + def nan? + not (self == self) + end + end +end diff --git a/web/server/h2o/libh2o/deps/mruby-iijson/mrblib/to_json.rb b/web/server/h2o/libh2o/deps/mruby-iijson/mrblib/to_json.rb new file mode 100644 index 00000000..ee97ac2c --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby-iijson/mrblib/to_json.rb @@ -0,0 +1,47 @@ +class Array + def to_json + JSON.generate(self) + end +end + +class FalseClass + def to_json + JSON.generate(self) + end +end + +class Fixnum + def to_json + JSON.generate(self) + end +end + +class Float + def to_json + JSON.generate(self) + end +end + +class Hash + def to_json + JSON.generate(self) + end +end + +class NilClass + def to_json + JSON.generate(self) + end +end + +class String + def to_json + JSON.generate(self) + end +end + +class TrueClass + def to_json + JSON.generate(self) + end +end diff --git a/web/server/h2o/libh2o/deps/mruby-iijson/run_test.rb b/web/server/h2o/libh2o/deps/mruby-iijson/run_test.rb new file mode 100644 index 00000000..dece5070 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby-iijson/run_test.rb @@ -0,0 +1,23 @@ +#!/usr/bin/env ruby +# +# mrbgems test runner +# + +if __FILE__ == $0 + repository, dir = 'https://github.com/mruby/mruby.git', 'tmp/mruby' + build_args = ARGV + + Dir.mkdir 'tmp' unless File.exist?('tmp') + unless File.exist?(dir) + system "git clone #{repository} #{dir}" + end + + exit system(%Q[cd #{dir}; MRUBY_CONFIG=#{File.expand_path __FILE__} ruby minirake #{build_args.join(' ')}]) +end + +MRuby::Build.new do |conf| + toolchain :gcc + conf.gembox 'default' + + conf.gem File.expand_path(File.dirname(__FILE__)) +end diff --git a/web/server/h2o/libh2o/deps/mruby-iijson/src/json.c b/web/server/h2o/libh2o/deps/mruby-iijson/src/json.c new file mode 100644 index 00000000..6836e090 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby-iijson/src/json.c @@ -0,0 +1,641 @@ +#include +#include +#include + +#include "mruby.h" +#include "mruby/array.h" +#include "mruby/hash.h" +#include "mruby/string.h" +#include "mruby/value.h" + +#define E_JSON_PARSER_ERROR (mrb_class_get_under(mrb, mrb_module_get(mrb, "JSON"), "ParserError")) + +#define JSON_EOF -1 + +#define DEFAULT_MAX_NESTING 100 + +struct json_parser { + mrb_state *mrb; + mrb_value src; + unsigned int cursor; + unsigned int lineno; + int nesting; + + int max_nesting; +}; + +static void json_check_nesting(struct json_parser *); +static int json_delimiter_p(char ch); +static int json_getc(struct json_parser *); +static void json_skip_ws(struct json_parser *); +static void json_ungetc(struct json_parser *); +static int json_unicode2utf8(uint32_t, char *); +static int json_whitespace_p(char ch); + +static int json_parse_array(struct json_parser *, mrb_value *); +static int json_parse_object(struct json_parser *, mrb_value *); +static int json_parse_number2(struct json_parser *, int, mrb_value *, mrb_int, int); +static int json_parse_string(struct json_parser *, mrb_value *); +static int json_parse_value(struct json_parser *, mrb_value *); + +#if MRUBY_RELEASE_NO < 10000 +static struct RClass * +mrb_module_get(mrb_state *mrb, const char *name) +{ + return mrb_class_get(mrb, name); +} +#endif +#if !defined(MRB_PRId) +#if defined(MRB_INT64) +# define MRB_PRId PRId64 +#elif defined(MRB_INT16) +# define MRB_PRId PRId16 +#else +# define MRB_PRId PRId32 +#endif +#endif /* !defined(MRB_PRId) */ + +static void +json_check_nesting(struct json_parser *parser) +{ + mrb_state *mrb = parser->mrb; + + if (parser->max_nesting != -1) { + if (parser->nesting >= parser->max_nesting) { + // +1 for compatibility with CRuby + mrb_raisef(mrb, E_JSON_PARSER_ERROR, "nesting of %S is too deep", mrb_fixnum_value(parser->nesting+1)); + } + } +} + +static int +json_delimiter_p(char ch) +{ + return (json_whitespace_p(ch) || ch == ',' || ch == ']' || ch == '}'); +} + +static int +json_getc(struct json_parser *parser) +{ + if (parser->cursor < RSTRING_LEN(parser->src)) { + unsigned char ch = RSTRING_PTR(parser->src)[parser->cursor]; + parser->cursor++; + return ch; + } else { + return JSON_EOF; + } +} + +static int +json_parse_readstring(struct json_parser *parser, const char *str) +{ + size_t len; + int ch; + + len = strlen(str); + if (parser->cursor + len > RSTRING_LEN(parser->src)) + return 0; + if (memcmp(str, RSTRING_PTR(parser->src) + parser->cursor, len) != 0) + return -1; + parser->cursor += len; + if (parser->cursor == RSTRING_LEN(parser->src)) + return 1; + ch = RSTRING_PTR(parser->src)[parser->cursor]; + if (!json_delimiter_p(ch)) + return -1; + return 1; +} + +static void +json_skip_ws(struct json_parser *parser) +{ + int ch; + + do { + ch = json_getc(parser); + if (ch == 0x0a) + parser->lineno++; + } while (json_whitespace_p(ch)); + if (ch != JSON_EOF) { + json_ungetc(parser); + } +} + +static void +json_ungetc(struct json_parser *parser) +{ + if (parser->cursor > 0) + parser->cursor--; +} + +static int +json_unicode2utf8(uint32_t unicode, char *cp) +{ + int n = 0; + if (unicode < 0x80) { + cp[n++] = unicode; + } else if (unicode < 0x800) { + cp[n++] = 0xc0 + (unicode >> 6); + cp[n++] = 0x80 + (unicode & 0x3f); + } else if (unicode < 0x10000) { + cp[n++] = 0xe0 + (unicode >> 12); + cp[n++] = 0x80 + ((unicode >> 6) & 0x3f); + cp[n++] = 0x80 + (unicode & 0x3f); + } else { + cp[n++] = 0xf0 + (unicode >> 18); + cp[n++] = 0x80 + ((unicode >> 12) & 0x3f); + cp[n++] = 0x80 + ((unicode >> 6) & 0x3f); + cp[n++] = 0x80 + (unicode & 0x3f); + } + return n; +} + +static int +json_whitespace_p(char ch) +{ + return (ch == 0x20 || ch == 0x09 || ch == 0x0a || ch == 0x0d); +} + +static int +json_parse_array(struct json_parser *parser, mrb_value *result) +{ + mrb_state *mrb = parser->mrb; + mrb_value ary, v; + int ch; + + json_check_nesting(parser); + + ary = mrb_ary_new(mrb); + + json_skip_ws(parser); + ch = json_getc(parser); + if (ch == ']') { /* easy case */ + *result = ary; + return 1; + } + if (ch == JSON_EOF) { + mrb_raise(mrb, E_JSON_PARSER_ERROR, "JSON_EOF in array(1)"); + } + json_ungetc(parser); + + while (1) { + parser->nesting++; + if (json_parse_value(parser, &v) != 1) { + mrb_raise(mrb, E_JSON_PARSER_ERROR, "error in array"); + } + parser->nesting--; + + mrb_ary_push(mrb, ary, v); + + json_skip_ws(parser); + ch = json_getc(parser); + if (ch == ']') { + break; + } + if (ch == JSON_EOF) { + mrb_raise(mrb, E_JSON_PARSER_ERROR, "JSON_EOF in array(2)"); + } + if (ch != ',') { + mrb_raise(mrb, E_JSON_PARSER_ERROR, "not ',' in array"); + } + } + *result = ary; + return 1; +} + +static int +json_parse_object(struct json_parser *parser, mrb_value *result) +{ + mrb_state *mrb = parser->mrb; + mrb_value h, k, v; + int ch; + + json_check_nesting(parser); + + h = mrb_hash_new(mrb); + + json_skip_ws(parser); + ch = json_getc(parser); + if (ch == '}') { /* easy case */ + *result = h; + return 1; + } + if (ch == JSON_EOF) { + mrb_raise(mrb, E_JSON_PARSER_ERROR, "EOF in object(1)"); + } + json_ungetc(parser); + + while (1) { + parser->nesting++; + if (json_parse_value(parser, &k) != 1) { + mrb_raise(mrb, E_JSON_PARSER_ERROR, "error in object key"); + } + parser->nesting--; + if (! mrb_string_p(k)) { + mrb_raise(mrb, E_JSON_PARSER_ERROR, "key is not a string"); + } + + json_skip_ws(parser); + + ch = json_getc(parser); + if (ch == JSON_EOF) { + mrb_raise(mrb, E_JSON_PARSER_ERROR, "EOF in object(2)"); + } + if (ch != ':') { + mrb_raise(mrb, E_JSON_PARSER_ERROR, "no ':' in object"); + } + + parser->nesting++; + if (json_parse_value(parser, &v) != 1) { + mrb_raise(mrb, E_JSON_PARSER_ERROR, "error in object value"); + } + parser->nesting--; + + mrb_hash_set(mrb, h, k, v); + + json_skip_ws(parser); + ch = json_getc(parser); + if (ch == '}') { + break; + } + if (ch == JSON_EOF) { + mrb_raise(mrb, E_JSON_PARSER_ERROR, "EOF in object(3)"); + } + if (ch != ',') { + mrb_raise(mrb, E_JSON_PARSER_ERROR, "no ',' in object"); + } + } + *result = h; + return 1; +} + +static int +json_parse_number(struct json_parser *parser, int ch, mrb_value *result) +{ + mrb_state *mrb = parser->mrb; + mrb_int num; + int d, sign; + + if (ch == '-') { + sign = -1; + ch = json_getc(parser); + if (ch == JSON_EOF) { + mrb_raise(mrb, E_JSON_PARSER_ERROR, "no character following minus"); + } + if (!isdigit(ch)) { + mrb_raise(mrb, E_JSON_PARSER_ERROR, "character following minus is not a digit"); + } + } else { + sign = 1; + } + num = (ch - '0') * sign; + while (1) { + ch = json_getc(parser); + if (ch == JSON_EOF) { + break; + } + if (isdigit(ch)) { + if (num == 0) { + mrb_raise(mrb, E_JSON_PARSER_ERROR, "leading zeros are not allowed"); + } + d = (ch - '0') * sign; + if (num < MRB_INT_MIN / 10 || + (num == MRB_INT_MIN / 10 && d < MRB_INT_MIN - num * 10) || + num > MRB_INT_MAX / 10 || + (num == MRB_INT_MAX / 10 && d > MRB_INT_MAX - num * 10)) { + return json_parse_number2(parser, ch, result, num, sign); + } + num = num * 10 + d; + } else if (ch == '.' || ch == 'e' || ch == 'E') { + return json_parse_number2(parser, ch, result, num, sign); + } else if (json_delimiter_p(ch)) { + json_ungetc(parser); + break; + } else { + mrb_raise(mrb, E_JSON_PARSER_ERROR, "invalid number"); + } + } + *result = mrb_fixnum_value(num); + return 1; +} + +static int +json_parse_number2(struct json_parser *parser, int ch, mrb_value *result, mrb_int num, int sign) +{ + mrb_state *mrb = parser->mrb; + double d; + int i, state; + char buf[64]; + + /* + * "-"? ("0" | [1-9] digit* ) ("." digit+ )? ([eE][-+] digit+)? + * state: 000000 111 222222 33334444 555555 + */ + i = snprintf(buf, sizeof(buf), "%s%"MRB_PRId"%c", + (num == 0 && sign < 0) ? "-" : "", + num, ch); + + if (isdigit(ch)) + state = 0; + else if (ch == '.') + state = 1; + else /* (ch == 'e' || ch == 'E') */ + state = 3; + + while (1) { + ch = json_getc(parser); + if (ch == JSON_EOF) + break; + switch (state) { + case 0: + if (isdigit(ch)) + ; /* read more digits */ + else if (ch == '.') + state = 1; + else if (ch == 'e' || ch == 'E') + state = 3; + else if (json_delimiter_p(ch)) { + json_ungetc(parser); + state = -1; + } else + goto formaterr; + break; + case 1: + if (!isdigit(ch)) + goto formaterr; + state = 2; + break; + case 2: + if (isdigit(ch)) + ; /* read more digits */ + else if (ch == 'e' || ch == 'E') + state = 3; + else if (json_delimiter_p(ch)) { + json_ungetc(parser); + state = -1; + } else + goto formaterr; + break; + case 3: + if (ch == '-' || ch == '+') + state = 4; + else if (isdigit(ch)) + state = 5; + else + goto formaterr; + break; + case 4: + if (!isdigit(ch)) + goto formaterr; + state = 5; + break; + case 5: + default: + if (isdigit(ch)) + ; /* read more digits */ + else { + json_ungetc(parser); + state = -1; + } + break; + } + if (state == -1) + break; + if (i == sizeof(buf) - 1) { + mrb_raise(mrb, E_JSON_PARSER_ERROR, "floating point number too long"); + } + buf[i++] = ch; + } + buf[i] = '\0'; + sscanf(buf, "%lf", &d); + *result = mrb_float_value(mrb, d); + return 1; + +formaterr: + mrb_raise(mrb, E_JSON_PARSER_ERROR, "floating point number error"); + return -1; +} + +static int +json_parse_string(struct json_parser *parser, mrb_value *result) +{ + mrb_state *mrb = parser->mrb; + mrb_value str; + uint32_t unicode; + uint16_t utf16; + int ch, i, n; + char *cp; + + str = mrb_str_buf_new(mrb, 30); + cp = RSTRING_PTR(str); + n = 0; + unicode = 0; + + while (1) { + ch = json_getc(parser); + if (ch == JSON_EOF) { + mrb_raise(mrb, E_JSON_PARSER_ERROR, "EOF in string"); + } + + if (ch == '"') { + break; + } else if (ch == '\\') { + ch = json_getc(parser); + if (ch == JSON_EOF) { + mrb_raise(mrb, E_JSON_PARSER_ERROR, "EOF following escape char"); + } + switch (ch) { + case '"': + case '\\': + case '/': + break; + case 'b': + ch = 0x08; + break; + case 'f': + ch = 0x0c; + break; + case 'n': + ch = 0x0a; + break; + case 'r': + ch = 0x0d; + break; + case 't': + ch = 0x09; + break; + case 'u': + utf16 = 0; + for (i = 0; i < 4; i++) { + ch = json_getc(parser); + if (ch == JSON_EOF) { + mrb_raise(mrb, E_JSON_PARSER_ERROR, "invalid unicode escape"); + } + if (ch >= '0' && ch <= '9') { + ch -= '0'; + } else if (ch >= 'A' && ch <= 'F') { + ch = (ch - 'A') + 10; + } else if (ch >= 'a' && ch <= 'f') { + ch = (ch - 'a') + 10; + } else { + mrb_raise(mrb, E_JSON_PARSER_ERROR, "invalid unicode character"); + } + utf16 *= 16; + utf16 += ch; + } + + if (n + 8 >= RSTRING_CAPA(str)) { + mrb_str_resize(mrb, str, RSTRING_CAPA(str)*2); + cp = RSTRING_PTR(str); + } + + if ((utf16 & 0xf800) == 0xd800) { + if ((utf16 & 0xfc00) == 0xd800) { + /* high surrogate */ + unicode = utf16; + continue; + } else { + /* low surrogate */ + if (unicode > 0) { + unicode = ((unicode & 0x03ff) + 0x040) << 10; + unicode += utf16 & 0x03ff; + } else { + /* error: low surrogate comes first... */ + } + } + } else { + if (unicode > 0) { + /* error: high surrogate not followed by low surrogate */ + n += json_unicode2utf8(unicode, &cp[n]); + } + unicode = utf16; + } + + n += json_unicode2utf8(unicode, &cp[n]); + unicode = 0; + continue; + default: + mrb_raise(mrb, E_JSON_PARSER_ERROR, "invalid escape char"); + break; + } + } else if (ch < 0x20) { + mrb_raise(mrb, E_JSON_PARSER_ERROR, "invalid char"); + } + + if (n + 1 == RSTRING_CAPA(str)) { + mrb_str_resize(mrb, str, RSTRING_CAPA(str)*2); + cp = RSTRING_PTR(str); + } + cp[n++] = ch; + } + cp[n] = '\0'; + mrb_str_resize(mrb, str, n); + *result = str; + return 1; +} + +static int +json_parse_value(struct json_parser *parser, mrb_value *result) +{ + mrb_state *mrb = parser->mrb; + int ch; + + do { + ch = json_getc(parser); + if (ch == JSON_EOF) + return 0; + } while (json_whitespace_p(ch)); + + switch (ch) { + case '0': case '1': case '2': case '3': case '4': + case '5': case '6': case '7': case '8': case '9': + case '-': + if (json_parse_number(parser, ch, result) != 1) { + mrb_raise(mrb, E_JSON_PARSER_ERROR, "number...?"); + } + break; + + case '"': + if (json_parse_string(parser, result) != 1) { + mrb_raise(mrb, E_JSON_PARSER_ERROR, "string...?"); + } + break; + + case '[': + if (json_parse_array(parser, result) != 1) { + mrb_raise(mrb, E_JSON_PARSER_ERROR, "array...?"); + } + break; + + case '{': + if (json_parse_object(parser, result) != 1) { + mrb_raise(mrb, E_JSON_PARSER_ERROR, "object...?"); + } + break; + + case 'f': + if (json_parse_readstring(parser, "alse") != 1) { + mrb_raise(mrb, E_JSON_PARSER_ERROR, "unexpected f"); + } + *result = mrb_false_value(); + break; + + case 'n': + if (json_parse_readstring(parser, "ull") != 1) { + mrb_raise(mrb, E_JSON_PARSER_ERROR, "unexpected n"); + } + *result = mrb_nil_value(); + break; + + case 't': + if (json_parse_readstring(parser, "rue") != 1) { + mrb_raise(mrb, E_JSON_PARSER_ERROR, "unexpected t"); + } + *result = mrb_true_value(); + break; + + default: + mrb_raise(mrb, E_JSON_PARSER_ERROR, "unexpected character"); + } + + return 1; +} + +static mrb_value +mrb_json_parse(mrb_state *mrb, mrb_value mod) +{ + struct json_parser parser; + mrb_value obj, options, source; + + mrb_get_args(mrb, "S|H", &source, &options); + + parser.mrb = mrb; + parser.src = source; + parser.cursor = 0; + parser.lineno = 0; + parser.nesting = 0; + parser.max_nesting = DEFAULT_MAX_NESTING; + + if (json_parse_value(&parser, &obj) == 0) { + mrb_raise(mrb, E_JSON_PARSER_ERROR, "no JSON value"); + } + + // if we have extra characters: + // unexpected token at '3' (JSON::ParserError) + + return obj; +} + +void +mrb_mruby_iijson_gem_init(mrb_state *mrb) +{ + struct RClass *m; + + m = mrb_define_module(mrb, "JSON"); + mrb_define_module_function(mrb, m, "parse", mrb_json_parse, MRB_ARGS_REQ(1)|MRB_ARGS_OPT(1)); +} + +void +mrb_mruby_iijson_gem_final(mrb_state *mrb) +{ +} diff --git a/web/server/h2o/libh2o/deps/mruby-iijson/test/json.rb b/web/server/h2o/libh2o/deps/mruby-iijson/test/json.rb new file mode 100644 index 00000000..5b1e759c --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby-iijson/test/json.rb @@ -0,0 +1,145 @@ +assert('JSON.dump') do + class JsonTestIo + def initialize + @buf = "" + end + def write(str) + @buf += str + end + attr_reader :buf + end + assert_equal "[1]", JSON.dump([1]) + + jio = JsonTestIo.new + JSON.dump(["abc"], jio) + assert_equal '["abc"]', jio.buf + + assert_raise(ArgumentError) do + JSON.dump({:a => {:b => {} } }, nil, 2) + end + JSON.dump({:a=>{:b=>{}}}, nil, 3) # should not raise +end + +assert('JSON.generate: false') do + assert_equal "false", JSON.generate(false) +end + +assert('JSON.generate: null') do + assert_equal "null", JSON.generate(nil) +end + +assert('JSON.generate: true') do + assert_equal "true", JSON.generate(true) +end + +assert('JSON.generate: object') do + assert_equal '{"key":"value"}', JSON.generate({ "key" => "value" }) + assert_equal '{"ten":10}', JSON.generate({ :ten => 10 }) +end + +assert('JSON.generate: array') do + assert_equal '[null,1,"two"]', JSON.generate([ nil, 1, "two"]) +end + +assert('JSON.generate: number (Fixnum)') do + str = JSON.generate [1] + assert_equal "[1]", str +end + +assert('JSON.generate: number (Float)') do + str = JSON.generate [134.625] + assert_equal "[134.625]", str +end + +assert('JSON.generate: string') do + assert_equal "\"abc\"", JSON.generate("abc") + assert_equal "\"\\\"\\\\/\\b\\f\\n\\r\\t\"", + JSON.generate("\x22\x5c\x2f\x08\x0c\x0a\x0d\x09") +end + +assert('JSON.load') do + assert_equal [1,2,3], JSON.load("[1,2,3]") + + class JsonTestReader + def read + '{"abc":123}' + end + end + assert_equal({"abc"=>123}, JSON.load(JsonTestReader.new)) +end + +assert('JSON.parse: text from RFC4726') do + str = '{ + "Image": { + "Width": 800, + "Height": 600, + "Title": "View from 15th Floor", + "Thumbnail": { + "Url": "http://www.example.com/image/481989943", + "Height": 125, + "Width": "100" + }, + "IDs": [116, 943, 234, 38793] + } + }' + hash = { + "Image" => { + "Width" => 800, + "Height" => 600, + "Title" => "View from 15th Floor", + "Thumbnail" => { + "Url" => "http://www.example.com/image/481989943", + "Height" => 125, + "Width" => "100" + }, + "IDs" => [116, 943, 234, 38793] + } + } + assert_equal hash, JSON.parse(str) + + # We cannot compare `str` with `JSON.generate(hash)` because Hash entries + # will be in a random order. + assert_equal hash, JSON.parse(JSON.generate(hash)) +end + +assert('JSON::ParserError') do + assert_raise(JSON::ParserError) do + JSON.parse "[xxx]" + end +end + +assert('JSON.parse: empty string is not a valid JSON text') do + assert_raise(JSON::ParserError) do + JSON.parse "" + end +end + +assert('JSON.parse: parsing numbers around MRB_INT_MIN/MRB_INT_MAX') do + int_min = TestJSON::MRB_INT_MIN + int_max = TestJSON::MRB_INT_MAX + + assert_kind_of Fixnum, JSON.load(int_min.to_s) + assert_equal int_min, JSON.load(int_min.to_s) + + assert_kind_of Fixnum, JSON.load(int_max.to_s) + assert_equal int_max, JSON.load(int_max.to_s) + + assert_kind_of Float, JSON.load((int_min-1).to_s) + assert_float (int_min-1)/int_min, JSON.load((int_min-1).to_s)/int_min + + assert_kind_of Float, JSON.load((int_max+1).to_s) + assert_float (int_max+1)/int_max, JSON.load((int_max+1).to_s)/int_max +end + +assert('#to_json') do + assert_equal 'false', false.to_json + assert_equal 'null', nil.to_json + assert_equal 'true', true.to_json + assert_equal '1', 1.to_json + assert_equal '3.125', 3.125.to_json + assert_equal '"str"', "str".to_json + assert_equal '["one",2]', [ "one", 2 ].to_json + assert_equal '{"a":1}', { "a" => 1 }.to_json + assert_equal TestJSON::MRB_INT_MIN.to_s, TestJSON::MRB_INT_MIN.to_json + assert_equal TestJSON::MRB_INT_MAX.to_s, TestJSON::MRB_INT_MAX.to_json +end diff --git a/web/server/h2o/libh2o/deps/mruby-iijson/test/testjson.c b/web/server/h2o/libh2o/deps/mruby-iijson/test/testjson.c new file mode 100644 index 00000000..f254e8bb --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby-iijson/test/testjson.c @@ -0,0 +1,11 @@ +#include "mruby.h" +#include "mruby/value.h" +#include "mruby/variable.h" + +void +mrb_mruby_iijson_gem_test(mrb_state* mrb) +{ + struct RClass *c = mrb_define_module(mrb, "TestJSON"); + mrb_const_set(mrb, mrb_obj_value(c), mrb_intern_lit(mrb, "MRB_INT_MIN"), mrb_fixnum_value(MRB_INT_MIN)); + mrb_const_set(mrb, mrb_obj_value(c), mrb_intern_lit(mrb, "MRB_INT_MAX"), mrb_fixnum_value(MRB_INT_MAX)); +} diff --git a/web/server/h2o/libh2o/deps/mruby-input-stream/.travis.yml b/web/server/h2o/libh2o/deps/mruby-input-stream/.travis.yml new file mode 100644 index 00000000..fc81cada --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby-input-stream/.travis.yml @@ -0,0 +1,6 @@ +sudo: false +script: + - export MRUBY_CONFIG="$TRAVIS_BUILD_DIR/build_config_sample.rb" + - git clone --depth 1 "https://github.com/mruby/mruby.git" + - cd mruby + - ./minirake test diff --git a/web/server/h2o/libh2o/deps/mruby-input-stream/LICENSE b/web/server/h2o/libh2o/deps/mruby-input-stream/LICENSE new file mode 100644 index 00000000..6e817bb5 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby-input-stream/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2015 Masayoshi Takahashi + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the "Software"), +to deal in the Software without restriction, including without limitation +the rights to use, copy, modify, merge, publish, distribute, sublicense, +and/or sell copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. diff --git a/web/server/h2o/libh2o/deps/mruby-input-stream/README.md b/web/server/h2o/libh2o/deps/mruby-input-stream/README.md new file mode 100644 index 00000000..a9efe87f --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby-input-stream/README.md @@ -0,0 +1,28 @@ +# mruby-input-stream + +[![Build Status](https://travis-ci.org/takahashim/mruby-input-stream.svg?branch=master)](https://travis-ci.org/takahashim/mruby-input-stream) + +Input Stream class for Rack. + + +## Install + +add conf.gem to `build_config.rb`: + + MRuby::Build.new do |conf| + + # ... (snip) ... + + conf.gem :github => 'takahashim/mruby-input-stream' + end + +## License + +MIT + +## Author + +Masayoshi Takahashi + + + diff --git a/web/server/h2o/libh2o/deps/mruby-input-stream/Rakefile b/web/server/h2o/libh2o/deps/mruby-input-stream/Rakefile new file mode 100644 index 00000000..0c0c78ea --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby-input-stream/Rakefile @@ -0,0 +1,28 @@ +MRUBY_CONFIG=File.expand_path(ENV["MRUBY_CONFIG"] || "./build_config_sample.rb") +RAKE="ruby ./minirake" + +file :mruby do + sh "git clone --depth 1 git://github.com/mruby/mruby.git" +end + +task :default => :test + +desc "test this mrbgem" +task :test => :mruby do + sh "cd mruby && MRUBY_CONFIG=#{MRUBY_CONFIG} #{RAKE} test" +end + +desc "build mruby with this mrbgem" +task :build => :mruby do + sh "cd mruby && MRUBY_CONFIG=#{MRUBY_CONFIG} #{RAKE} all" +end + +desc "cleanup" +task :clean do + sh "cd mruby && rake deep_clean" if File.exist?("mruby") +end + +desc "cleanup including temporary files" +task :realclean do + sh "rm -rf mruby" +end diff --git a/web/server/h2o/libh2o/deps/mruby-input-stream/build_config_sample.rb b/web/server/h2o/libh2o/deps/mruby-input-stream/build_config_sample.rb new file mode 100644 index 00000000..9d2321d9 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby-input-stream/build_config_sample.rb @@ -0,0 +1,17 @@ +MRuby::Build.new do |conf| + toolchain :gcc + + conf.gembox 'default' + conf.gem File.expand_path(File.dirname(__FILE__)) +end + +MRuby::Build.new('test') do |conf| + toolchain :gcc + + enable_debug + conf.enable_bintest + conf.enable_test + + conf.gembox 'default' + conf.gem File.expand_path(File.dirname(__FILE__)) +end diff --git a/web/server/h2o/libh2o/deps/mruby-input-stream/mrbgem.rake b/web/server/h2o/libh2o/deps/mruby-input-stream/mrbgem.rake new file mode 100644 index 00000000..082a128a --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby-input-stream/mrbgem.rake @@ -0,0 +1,6 @@ +MRuby::Gem::Specification.new('mruby-input-stream') do |spec| + spec.license = 'MIT' + spec.authors = 'Masayoshi Takahashi' + spec.summary = 'InputStream class for Rack' + spec.version = '1.0.0' +end diff --git a/web/server/h2o/libh2o/deps/mruby-input-stream/mrblib/input_stream.rb b/web/server/h2o/libh2o/deps/mruby-input-stream/mrblib/input_stream.rb new file mode 100644 index 00000000..d452f7ff --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby-input-stream/mrblib/input_stream.rb @@ -0,0 +1,16 @@ +class InputStream + include Enumerable + + # + # from String#each + def each(&block) + self.rewind + while pos = self.byteindex(0x0a) + block.call(self.read(pos+1)) + end + rest = self.read() + if rest + block.call(rest) + end + end +end diff --git a/web/server/h2o/libh2o/deps/mruby-input-stream/src/mruby_input_stream.c b/web/server/h2o/libh2o/deps/mruby-input-stream/src/mruby_input_stream.c new file mode 100644 index 00000000..a5f90b98 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby-input-stream/src/mruby_input_stream.c @@ -0,0 +1,278 @@ +#include +#include "mruby.h" +#include "mruby/value.h" +#include "mruby/data.h" +#include "mruby/string.h" +#include "mruby_input_stream.h" + +typedef struct mrb_input_stream_t { + const char *base; + mrb_int len; + mrb_int pos; + mrb_input_stream_free_callback free_cb; + void *free_cb_data; +} mrb_input_stream_t; + +static mrb_input_stream_t* +mrb_input_stream_create(mrb_state *mrb, const char *base, mrb_int len, mrb_input_stream_free_callback cb, void *cb_data); + +static void +mrb_mruby_input_stream_free(mrb_state *mrb, void *ptr); + +static mrb_int +seek_char(mrb_input_stream_t *stream, const char chr); + +const static struct mrb_data_type mrb_input_stream_type = { + "InputStream", + mrb_mruby_input_stream_free, +}; + +static void +assert_is_open(mrb_state *mrb, mrb_input_stream_t *stream) +{ + if (stream->len < 0) { + struct RClass *klass = mrb_class_get(mrb, "IOError"); + if (klass == NULL) + klass = E_RUNTIME_ERROR; + mrb_raise(mrb, klass, "stream closed"); + } +} + +static mrb_value +mrb_input_stream_init(mrb_state *mrb, mrb_value self) +{ + mrb_value str; + mrb_int len; + char *ptr; + mrb_input_stream_t *stream; + mrb_int n = mrb_get_args(mrb, "|S", &str); + if (n > 1) { + mrb_raisef(mrb, E_ARGUMENT_ERROR, "wrong number of arguments (%S for 1)", mrb_fixnum_value(n)); + } + + if (n == 1) { + len = RSTRING_LEN(str); + ptr = RSTRING_PTR(str); + stream = mrb_input_stream_create(mrb, ptr, len, NULL, NULL); + } else { + stream = mrb_input_stream_create(mrb, NULL, 0, NULL, NULL); + } + + DATA_TYPE(self) = &mrb_input_stream_type; + DATA_PTR(self) = stream; + return self; +} + +static void +default_free_cb(mrb_state *mrb, const char *base, mrb_int len, void *cb_data) +{ + if (base != NULL) + mrb_free(mrb, (void *)base); +} + +static void +mrb_mruby_input_stream_free(mrb_state *mrb, void *ptr) +{ + mrb_input_stream_t *stream = (mrb_input_stream_t *)ptr; + if (stream->free_cb != NULL) + stream->free_cb(mrb, stream->base, stream->len, stream->free_cb_data); + mrb_free(mrb, stream); +} + +static void setup_stream(mrb_state *mrb, mrb_input_stream_t *stream, const char *base, mrb_int len, mrb_int pos, mrb_input_stream_free_callback free_cb, void *free_cb_data) +{ + if (free_cb == NULL) { + if (len > 0) { + char *dst_base = (char *)mrb_malloc(mrb, sizeof(char)*len); + memcpy(dst_base, base, len); + stream->base = dst_base; + stream->len = len; + } else { + stream->base = NULL; + stream->len = len; + } + stream->free_cb = default_free_cb; + stream->free_cb_data = NULL; + } else { + stream->base = base; + stream->len = len; + stream->free_cb = free_cb; + stream->free_cb_data = free_cb_data; + } + + stream->pos = pos; +} + +mrb_input_stream_t* +mrb_input_stream_create(mrb_state *mrb, const char *base, mrb_int len, mrb_input_stream_free_callback free_cb, void *free_cb_data) +{ + mrb_input_stream_t *stream = (mrb_input_stream_t *)mrb_malloc(mrb, sizeof(mrb_input_stream_t)); + + setup_stream(mrb, stream, base, len, 0, free_cb, free_cb_data); + return stream; +} + +mrb_value +mrb_input_stream_value(mrb_state *mrb, const char *base, mrb_int len) +{ + mrb_input_stream_t *stream = mrb_input_stream_create(mrb, base, len, NULL, NULL); + struct RClass *c = mrb_class_get(mrb, "InputStream"); + struct RData *d = mrb_data_object_alloc(mrb, c, stream, &mrb_input_stream_type); + + return mrb_obj_value(d); +} + +void +mrb_input_stream_get_data(mrb_state *mrb, mrb_value self, const char **base, mrb_int *len, mrb_int *pos, mrb_input_stream_free_callback *free_cb, void **free_cb_data) +{ + mrb_input_stream_t *stream = DATA_PTR(self); + + if (base != NULL) + *base = stream->base; + if (len != NULL) + *len = stream->len; + if (pos != NULL) + *pos = stream->pos; + if (free_cb != NULL) + *free_cb = stream->free_cb; + if (free_cb_data != NULL) + *free_cb_data = stream->free_cb_data; +} + +void +mrb_input_stream_set_data(mrb_state *mrb, mrb_value self, const char *base, mrb_int len, mrb_int pos, mrb_input_stream_free_callback free_cb, void *free_cb_data) +{ + mrb_input_stream_t *stream = DATA_PTR(self); + + if (stream->free_cb != NULL) + stream->free_cb(mrb, stream->base, stream->len, stream->free_cb_data); + setup_stream(mrb, stream, base, len, pos, free_cb, free_cb_data); +} + +static mrb_value +mrb_input_stream_gets(mrb_state *mrb, mrb_value self) +{ + mrb_input_stream_t *stream = DATA_PTR(self); + mrb_int pos, len; + + assert_is_open(mrb, stream); + + pos = stream->pos; + len = seek_char(stream, '\n'); + if (len < 0) { + return mrb_nil_value(); + } + if (stream->pos + len < stream->len) { + len++; + } + stream->pos += len; + return mrb_str_new(mrb, (stream->base + pos), len); +} + +static mrb_int +seek_char(mrb_input_stream_t *stream, char chr){ + const char *base = stream->base; + size_t len = stream->len; + mrb_int pos = stream->pos; + const char *end = base + len; + const char *start = base + pos; + const char *s = start; + + if (pos >= len) { + return -1; + } + + while (s < end) { + if (*s == chr) { + break; + } + s++; + } + return (s - start); +} + +static mrb_value +mrb_input_stream_read(mrb_state *mrb, mrb_value self) +{ + mrb_int len; + mrb_value buf; + mrb_int n = mrb_get_args(mrb, "|iS", &len, &buf), pos; + mrb_input_stream_t *stream = DATA_PTR(self); + const char *start; + + assert_is_open(mrb, stream); + + pos = stream->pos; + start = stream->base + pos; + + if (pos >= stream->len) { + return mrb_nil_value(); + } + if (n == 0) { + stream->pos = stream->len; + return mrb_str_new(mrb, start, stream->len - pos); + } else { + mrb_int newpos = pos + len; + if (newpos > stream->len) { + newpos = stream->len; + } + stream->pos = newpos; + if (n == 1) { + return mrb_str_new(mrb, start, newpos - pos); + } else { + return mrb_str_cat(mrb, buf, start, newpos - pos); + } + } +} + +static mrb_value +mrb_input_stream_rewind(mrb_state *mrb, mrb_value self) +{ + mrb_input_stream_t *stream = DATA_PTR(self); + assert_is_open(mrb, stream); + stream->pos = 0; + return self; +} + + +static mrb_value +mrb_input_stream_byteindex(mrb_state *mrb, mrb_value self) +{ + mrb_input_stream_t *stream = DATA_PTR(self); + mrb_int chr, n, len; + + assert_is_open(mrb, stream); + + n = mrb_get_args(mrb, "i", &chr); + if (n != 1) { + mrb_raisef(mrb, E_ARGUMENT_ERROR, "wrong number of arguments (%S for 1)", mrb_fixnum_value(n)); + } + if (chr < 0 || chr > 255) { + mrb_raise(mrb, E_ARGUMENT_ERROR, "index should be a byte (0 - 255)"); + } + + len = seek_char(stream, chr); + if (len < 0) { + return mrb_nil_value(); + } + + return mrb_fixnum_value(len); +} + + +void +mrb_mruby_input_stream_gem_init(mrb_state* mrb) +{ + struct RClass * c = mrb_define_class(mrb, "InputStream", mrb->object_class); + + mrb_define_method(mrb, c, "gets", mrb_input_stream_gets, MRB_ARGS_NONE()); + mrb_define_method(mrb, c, "read", mrb_input_stream_read, MRB_ARGS_ANY()); + mrb_define_method(mrb, c, "initialize", mrb_input_stream_init, MRB_ARGS_BLOCK()); + mrb_define_method(mrb, c, "rewind", mrb_input_stream_rewind, MRB_ARGS_NONE()); + mrb_define_method(mrb, c, "byteindex", mrb_input_stream_byteindex, MRB_ARGS_ANY()); +} + +void +mrb_mruby_input_stream_gem_final(mrb_state* mrb) +{ +} diff --git a/web/server/h2o/libh2o/deps/mruby-input-stream/src/mruby_input_stream.h b/web/server/h2o/libh2o/deps/mruby-input-stream/src/mruby_input_stream.h new file mode 100644 index 00000000..39150ad6 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby-input-stream/src/mruby_input_stream.h @@ -0,0 +1,19 @@ +/* + * input_stream.h + * + */ +#ifndef mruby_input_stream_h +#define mruby_input_stream_h + +typedef void (*mrb_input_stream_free_callback)(mrb_state *mrb, const char *base, mrb_int len, void *cb_data); + +mrb_value +mrb_input_stream_value(mrb_state *mrb, const char *base, mrb_int len); + +void +mrb_input_stream_get_data(mrb_state *mrb, mrb_value self, const char **base, mrb_int *len, mrb_int *pos, mrb_input_stream_free_callback *free_cb, void **free_cb_data); + +void +mrb_input_stream_set_data(mrb_state *mrb, mrb_value self, const char *base, mrb_int len, mrb_int pos, mrb_input_stream_free_callback free_cb, void *free_cb_data); + +#endif /* input_stream_h */ diff --git a/web/server/h2o/libh2o/deps/mruby-input-stream/test/input_stream.rb b/web/server/h2o/libh2o/deps/mruby-input-stream/test/input_stream.rb new file mode 100644 index 00000000..8201786b --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby-input-stream/test/input_stream.rb @@ -0,0 +1,111 @@ +assert('InputStream.new()') do + vec = InputStream.new + assert_equal InputStream, vec.class +end + +assert('InputStream.new("foo")') do + vec = InputStream.new("foo") + assert_equal InputStream, vec.class +end + +assert('InputStream#read') do + vec = InputStream.new("foo") + assert_equal "foo", vec.read +end + +assert('InputStream#read(2)') do + vec = InputStream.new("abcdef") + assert_equal "ab", vec.read(2) + assert_equal "cde", vec.read(3) + assert_equal "f", vec.read(4) + assert_equal nil, vec.read(5) +end + +assert('InputStream#read(2, "")') do + vec = InputStream.new("abcdef") + s1 = "" + assert_equal "ab", vec.read(2, s1) + assert_equal "ab", s1 + assert_equal "abcde", vec.read(3, s1) + assert_equal "abcde", s1 + assert_equal "abcdef", vec.read(4, s1) + assert_equal "abcdef", s1 + assert_equal nil, vec.read(5, s1) + assert_equal "abcdef", s1 +end + +assert('InputStream#read(10)') do + vec = InputStream.new("abc") + assert_equal "abc", vec.read(10) + assert_equal nil, vec.read(10) +end + +assert('InputStream#read ""') do + vec = InputStream.new("") + assert_equal nil, vec.read(2) + assert_equal nil, vec.read(0) + assert_equal nil, vec.read(2) +end + +assert('InputStream#read(0)') do + vec = InputStream.new("foo") + assert_equal "", vec.read(0) + assert_equal "", vec.read(0) + assert_equal "f", vec.read(1) +end + + +assert('InputStream#gets') do + vec = InputStream.new("foo") + assert_equal "foo", vec.gets + assert_equal nil, vec.gets +end + +assert('InputStream#gets ""') do + vec = InputStream.new("") + assert_equal nil, vec.gets +end + +assert('InputStream#gets long') do + vec = InputStream.new("foo\nbar\nbuz\n") + assert_equal "foo\n", vec.gets + assert_equal "bar\n", vec.gets + assert_equal "buz\n", vec.gets + assert_equal nil, vec.gets +end + +assert('InputStream#gets NN') do + vec = InputStream.new("\n\nbuz") + assert_equal "\n", vec.gets + assert_equal "\n", vec.gets + assert_equal "buz", vec.gets + assert_equal nil, vec.gets +end + +assert('InputStream#each') do + vec = InputStream.new("foo\nbar\nbuz\nzzz") + buf = [] + vec.each do |line| + buf << line + end + assert_equal ["foo\n", "bar\n", "buz\n", "zzz"], buf +end + +assert('InputStream#each ""') do + vec = InputStream.new("") + buf = [] + vec.each do |line| + buf << line + end + assert_equal [], buf +end + +assert('InputStream#rewind') do + vec = InputStream.new("abcdef") + assert_equal "ab", vec.read(2) + assert_equal "cde", vec.read(3) + vec.rewind + assert_equal "abcd", vec.read(4) + assert_equal "ef", vec.read(5) +end + diff --git a/web/server/h2o/libh2o/deps/mruby-io/.gitignore b/web/server/h2o/libh2o/deps/mruby-io/.gitignore new file mode 100644 index 00000000..ceeb05b4 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby-io/.gitignore @@ -0,0 +1 @@ +/tmp diff --git a/web/server/h2o/libh2o/deps/mruby-io/.travis.yml b/web/server/h2o/libh2o/deps/mruby-io/.travis.yml new file mode 100644 index 00000000..ffe22728 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby-io/.travis.yml @@ -0,0 +1,2 @@ +script: + - "ruby run_test.rb all test" diff --git a/web/server/h2o/libh2o/deps/mruby-io/README.md b/web/server/h2o/libh2o/deps/mruby-io/README.md new file mode 100644 index 00000000..d7fa6945 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby-io/README.md @@ -0,0 +1,185 @@ +mruby-io +======== + +IO, File module for mruby + + +## Implemented methods + +### IO + - http://doc.ruby-lang.org/ja/1.9.3/class/IO.html + +| method | mruby-io | memo | +| ------------------------- | -------- | ---- | +| IO.binread | | | +| IO.binwrite | | | +| IO.copy_stream | | | +| IO.new, IO.for_fd, IO.open | o | | +| IO.foreach | | | +| IO.pipe | | | +| IO.popen | o | | +| IO.read | o | | +| IO.readlines | | | +| IO.select | o | | +| IO.sysopen | o | | +| IO.try_convert | | | +| IO.write | | | +| IO#<< | | | +| IO#advise | | | +| IO#autoclose= | | | +| IO#autoclose? | | | +| IO#binmode | | | +| IO#binmode? | | | +| IO#bytes | | obsolete | +| IO#chars | | obsolete | +| IO#clone, IO#dup | | | +| IO#close | o | | +| IO#close_on_exec= | o | | +| IO#close_on_exec? | o | | +| IO#close_read | | | +| IO#close_write | | | +| IO#closed? | o | | +| IO#codepoints | | obsolete | +| IO#each_byte | o | | +| IO#each_char | o | | +| IO#each_codepoint | | | +| IO#each_line | o | | +| IO#eof, IO#eof? | o | | +| IO#external_encoding | | | +| IO#fcntl | | | +| IO#fdatasync | | | +| IO#fileno, IO#to_i | o | | +| IO#flush | o | | +| IO#fsync | | | +| IO#getbyte | | | +| IO#getc | o | | +| IO#gets | o | | +| IO#internal_encoding | | | +| IO#ioctl | | | +| IO#isatty, IO#tty? | | | +| IO#lineno | | | +| IO#lineno= | | | +| IO#lines | | obsolete | +| IO#pid | o | | +| IO#pos, IO#tell | o | | +| IO#pos= | o | | +| IO#print | o | | +| IO#printf | o | | +| IO#putc | | | +| IO#puts | o | | +| IO#read | o | | +| IO#read_nonblock | | | +| IO#readbyte | | | +| IO#readchar | o | | +| IO#readline | o | | +| IO#readlines | o | | +| IO#readpartial | | | +| IO#reopen | | | +| IO#rewind | | | +| IO#seek | o | | +| IO#set_encoding | | | +| IO#stat | | | +| IO#sync | o | | +| IO#sync= | o | | +| IO#sysread | o | | +| IO#sysseek | o | | +| IO#syswrite | o | | +| IO#to_io | | | +| IO#ungetbyte | | | +| IO#ungetc | o | | +| IO#write | o | | +| IO#write_nonblock | | | + +### File + - http://doc.ruby-lang.org/ja/1.9.3/class/File.html + +| method | mruby-io | memo | +| --------------------------- | -------- | ---- | +| File.absolute_path | | | +| File.atime | | | +| File.basename | o | | +| File.blockdev? | | FileTest | +| File.chardev? | | FileTest | +| File.chmod | | | +| File.chown | | | +| File.ctime | | | +| File.delete, File.unlink | o | | +| File.directory? | o | FileTest | +| File.dirname | o | | +| File.executable? | | FileTest | +| File.executable_real? | | FileTest | +| File.exist?, exists? | o | FileTest | +| File.expand_path | o | | +| File.extname | o | | +| File.file? | o | FileTest | +| File.fnmatch, File.fnmatch? | | | +| File.ftype | | | +| File.grpowned? | | FileTest | +| File.identical? | | FileTest | +| File.join | o | | +| File.lchmod | | | +| File.lchown | | | +| File.link | | | +| File.lstat | | | +| File.mtime | | | +| File.new, File.open | o | | +| File.owned? | | FileTest | +| File.path | | | +| File.pipe? | o | FileTest | +| File.readable? | | FileTest | +| File.readable_real? | | FileTest | +| File.readlink | | | +| File.realdirpath | | | +| File.realpath | o | | +| File.rename | o | | +| File.setgid? | | FileTest | +| File.setuid? | | FileTest | +| File.size | o | | +| File.size? | o | FileTest | +| File.socket? | o | FileTest | +| File.split | | | +| File.stat | | | +| File.sticky? | | FileTest | +| File.symlink | | | +| File.symlink? | o | FileTest | +| File.truncate | | | +| File.umask | o | | +| File.utime | | | +| File.world_readable? | | | +| File.world_writable? | | | +| File.writable? | | FileTest | +| File.writable_real? | | FileTest | +| File.zero? | o | FileTest | +| File#atime | | | +| File#chmod | | | +| File#chown | | | +| File#ctime | | | +| File#flock | o | | +| File#lstat | | | +| File#mtime | | | +| File#path, File#to_path | o | | +| File#size | | | +| File#truncate | | | + + +## License + +Copyright (c) 2013 Internet Initiative Japan Inc. + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the "Software"), +to deal in the Software without restriction, including without limitation +the rights to use, copy, modify, merge, publish, distribute, sublicense, +and/or sell copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. diff --git a/web/server/h2o/libh2o/deps/mruby-io/include/mruby/ext/io.h b/web/server/h2o/libh2o/deps/mruby-io/include/mruby/ext/io.h new file mode 100644 index 00000000..3107f105 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby-io/include/mruby/ext/io.h @@ -0,0 +1,36 @@ +/* +** io.h - IO class +*/ + +#ifndef MRUBY_IO_H +#define MRUBY_IO_H + +#if defined(__cplusplus) +extern "C" { +#endif + +struct mrb_io { + int fd; /* file descriptor, or -1 */ + int fd2; /* file descriptor to write if it's different from fd, or -1 */ + int pid; /* child's pid (for pipes) */ + unsigned int writable:1, + sync:1; +}; + +#define FMODE_READABLE 0x00000001 +#define FMODE_WRITABLE 0x00000002 +#define FMODE_READWRITE (FMODE_READABLE|FMODE_WRITABLE) +#define FMODE_BINMODE 0x00000004 +#define FMODE_APPEND 0x00000040 +#define FMODE_CREATE 0x00000080 +#define FMODE_TRUNC 0x00000800 + +#define E_IO_ERROR (mrb_class_get(mrb, "IOError")) +#define E_EOF_ERROR (mrb_class_get(mrb, "EOFError")) + +mrb_value mrb_io_fileno(mrb_state *mrb, mrb_value io); + +#if defined(__cplusplus) +} /* extern "C" { */ +#endif +#endif /* MRUBY_IO_H */ diff --git a/web/server/h2o/libh2o/deps/mruby-io/mrbgem.rake b/web/server/h2o/libh2o/deps/mruby-io/mrbgem.rake new file mode 100644 index 00000000..8120f783 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby-io/mrbgem.rake @@ -0,0 +1,16 @@ +MRuby::Gem::Specification.new('mruby-io') do |spec| + spec.license = 'MIT' + spec.authors = 'Internet Initiative Japan Inc.' + + spec.cc.include_paths << "#{build.root}/src" + + case RUBY_PLATFORM + when /mingw|mswin/ + spec.linker.libraries += ['Ws2_32'] + #spec.cc.include_paths += ["C:/Windows/system/include"] + spec.linker.library_paths += ["C:/Windows/system"] + end + if build.kind_of?(MRuby::CrossBuild) && %w(x86_64-w64-mingw32 i686-w64-mingw32).include?(build.host_target) + spec.linker.libraries += ['ws2_32'] + end +end diff --git a/web/server/h2o/libh2o/deps/mruby-io/mrblib/file.rb b/web/server/h2o/libh2o/deps/mruby-io/mrblib/file.rb new file mode 100644 index 00000000..aa098193 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby-io/mrblib/file.rb @@ -0,0 +1,173 @@ +class File < IO + include Enumerable + + class FileError < Exception; end + class NoFileError < FileError; end + class UnableToStat < FileError; end + class PermissionError < FileError; end + + attr_accessor :path + + def initialize(fd_or_path, mode = "r", perm = 0666) + if fd_or_path.kind_of? Fixnum + super(fd_or_path, mode) + else + @path = fd_or_path + fd = IO.sysopen(@path, mode, perm) + super(fd, mode) + end + end + + def self.join(*names) + if names.size == 0 + "" + elsif names.size == 1 + names[0] + else + if names[0][-1] == File::SEPARATOR + s = names[0][0..-2] + else + s = names[0].dup + end + (1..names.size-2).each { |i| + t = names[i] + if t[0] == File::SEPARATOR and t[-1] == File::SEPARATOR + t = t[1..-2] + elsif t[0] == File::SEPARATOR + t = t[1..-1] + elsif t[-1] == File::SEPARATOR + t = t[0..-2] + end + s += File::SEPARATOR + t if t != "" + } + if names[-1][0] == File::SEPARATOR + s += File::SEPARATOR + names[-1][1..-1] + else + s += File::SEPARATOR + names[-1] + end + s + end + end + + def self.expand_path(path, default_dir = '.') + def concat_path(path, base_path) + if path[0] == "/" || path[1] == ':' # Windows root! + expanded_path = path + elsif path[0] == "~" + if (path[1] == "/" || path[1] == nil) + dir = path[1, path.size] + home_dir = _gethome + + unless home_dir + raise ArgumentError, "couldn't find HOME environment -- expanding '~'" + end + + expanded_path = home_dir + expanded_path += dir if dir + expanded_path += "/" + else + splitted_path = path.split("/") + user = splitted_path[0][1, splitted_path[0].size] + dir = "/" + splitted_path[1, splitted_path.size].join("/") + + home_dir = _gethome(user) + + unless home_dir + raise ArgumentError, "user #{user} doesn't exist" + end + + expanded_path = home_dir + expanded_path += dir if dir + expanded_path += "/" + end + else + expanded_path = concat_path(base_path, _getwd) + expanded_path += "/" + path + end + + expanded_path + end + + expanded_path = concat_path(path, default_dir) + expand_path_array = [] + while expanded_path.include?('//') + expanded_path = expanded_path.gsub('//', '/') + end + + if expanded_path == "/" + expanded_path + else + expanded_path.split('/').each do |path_token| + if path_token == '..' + if expand_path_array.size > 1 + expand_path_array.pop + end + elsif path_token == '.' + # nothing to do. + else + expand_path_array << path_token + end + end + + expand_path = expand_path_array.join("/") + expand_path.empty? ? '/' : expand_path + end + end + + def self.foreach(file) + if block_given? + self.open(file) do |f| + f.each {|l| yield l} + end + else + return self.new(file) + end + end + + def self.directory?(file) + FileTest.directory?(file) + end + + def self.exist?(file) + FileTest.exist?(file) + end + + def self.exists?(file) + FileTest.exists?(file) + end + + def self.file?(file) + FileTest.file?(file) + end + + def self.pipe?(file) + FileTest.pipe?(file) + end + + def self.size(file) + FileTest.size(file) + end + + def self.size?(file) + FileTest.size?(file) + end + + def self.socket?(file) + FileTest.socket?(file) + end + + def self.symlink?(file) + FileTest.symlink?(file) + end + + def self.zero?(file) + FileTest.zero?(file) + end + + def self.extname(filename) + fname = self.basename(filename) + return '' if fname[0] == '.' || fname.index('.').nil? + ext = fname.split('.').last + ext.empty? ? '' : ".#{ext}" + end +end diff --git a/web/server/h2o/libh2o/deps/mruby-io/mrblib/file_constants.rb b/web/server/h2o/libh2o/deps/mruby-io/mrblib/file_constants.rb new file mode 100644 index 00000000..a68ee259 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby-io/mrblib/file_constants.rb @@ -0,0 +1,29 @@ +class File + module Constants + RDONLY = 0 + WRONLY = 1 + RDWR = 2 + NONBLOCK = 4 + APPEND = 8 + + BINARY = 0 + SYNC = 128 + NOFOLLOW = 256 + CREAT = 512 + TRUNC = 1024 + EXCL = 2048 + + NOCTTY = 131072 + DSYNC = 4194304 + + FNM_SYSCASE = 0 + FNM_NOESCAPE = 1 + FNM_PATHNAME = 2 + FNM_DOTMATCH = 4 + FNM_CASEFOLD = 8 + end +end + +class File + include File::Constants +end diff --git a/web/server/h2o/libh2o/deps/mruby-io/mrblib/io.rb b/web/server/h2o/libh2o/deps/mruby-io/mrblib/io.rb new file mode 100644 index 00000000..c838b96e --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby-io/mrblib/io.rb @@ -0,0 +1,372 @@ +## +# IO + +class IOError < StandardError; end +class EOFError < IOError; end + +class IO + SEEK_SET = 0 + SEEK_CUR = 1 + SEEK_END = 2 + + BUF_SIZE = 4096 + + def self.open(*args, &block) + io = self.new(*args) + + return io unless block + + begin + yield io + ensure + begin + io.close unless io.closed? + rescue StandardError + end + end + end + + def self.popen(command, mode = 'r', &block) + io = self._popen(command, mode) + return io unless block + + begin + yield io + ensure + begin + io.close unless io.closed? + rescue IOError + # nothing + end + end + end + + + def self.read(path, length=nil, offset=nil, opt=nil) + if not opt.nil? # 4 arguments + offset ||= 0 + elsif not offset.nil? # 3 arguments + if offset.is_a? Hash + opt = offset + offset = 0 + else + opt = {} + end + elsif not length.nil? # 2 arguments + if length.is_a? Hash + opt = length + offset = 0 + length = nil + else + offset = 0 + opt = {} + end + else # only 1 argument + opt = {} + offset = 0 + length = nil + end + + str = "" + fd = -1 + io = nil + begin + if path[0] == "|" + io = IO.popen(path[1..-1], (opt[:mode] || "r")) + else + fd = IO.sysopen(path) + io = IO.open(fd, opt[:mode] || "r") + end + io.seek(offset) if offset > 0 + str = io.read(length) + ensure + if io + io.close + elsif fd != -1 + IO._sysclose(fd) + end + end + str + end + + def flush + # mruby-io always writes immediately (no output buffer). + raise IOError, "closed stream" if self.closed? + self + end + + def write(string) + str = string.is_a?(String) ? string : string.to_s + return str.size unless str.size > 0 + + len = syswrite(str) + if len != -1 + @pos += len + return len + end + + raise IOError + end + + def eof? + return true if @buf && @buf.size > 0 + + ret = false + char = '' + + begin + char = sysread(1) + rescue EOFError => e + ret = true + ensure + _ungets(char) + end + + ret + end + alias_method :eof, :eof? + + def pos + raise IOError if closed? + @pos + end + alias_method :tell, :pos + + def pos=(i) + seek(i, SEEK_SET) + end + + def seek(i, whence = SEEK_SET) + raise IOError if closed? + @pos = sysseek(i, whence) + @buf = '' + 0 + end + + def _read_buf + return @buf if @buf && @buf.size > 0 + @buf = sysread(BUF_SIZE) + end + + def _ungets(substr) + raise TypeError.new "expect String, got #{substr.class}" unless substr.is_a?(String) + raise IOError if @pos == 0 || @pos.nil? + @pos -= substr.size + if @buf.empty? + @buf = substr + else + @buf = substr + @buf + end + nil + end + + def ungetc(char) + raise IOError if @pos == 0 || @pos.nil? + _ungets(char) + nil + end + + def read(length = nil) + unless length.nil? + unless length.is_a? Fixnum + raise TypeError.new "can't convert #{length.class} into Integer" + end + if length < 0 + raise ArgumentError.new "negative length: #{length} given" + end + if length == 0 + return "" # easy case + end + end + + array = [] + start_pos = @pos + while 1 + begin + _read_buf + rescue EOFError => e + array = nil if array.empty? and (not length.nil?) and length != 0 + break + end + + if length && (@pos - start_pos + @buf.size) >= length + len = length - (@pos - start_pos) + array.push @buf[0, len] + @pos += len + @buf = @buf[len, @buf.size - len] + break + else + array.push @buf + @pos += @buf.size + @buf = '' + end + end + + array && array.join + end + + def readline(arg = $/, limit = nil) + case arg + when String + rs = arg + when Fixnum + rs = $/ + limit = arg + else + raise ArgumentError + end + + if rs.nil? + return read + end + + if rs == "" + rs = $/ + $/ + end + + array = [] + start_pos = @pos + while 1 + begin + _read_buf + rescue EOFError => e + array = nil if array.empty? + break + end + + if limit && (@pos - start_pos + @buf.size) >= limit + len = limit - (@pos - start_pos) + array.push @buf[0, len] + @pos += len + @buf = @buf[len, @buf.size - len] + break + elsif idx = @buf.index(rs) + len = idx + rs.size + array.push @buf[0, len] + @pos += len + @buf = @buf[len, @buf.size - len] + break + else + array.push @buf + @pos += @buf.size + @buf = '' + end + end + + raise EOFError.new "end of file reached" if array.nil? + + array.join + end + + def gets(*args) + begin + readline(*args) + rescue EOFError => e + nil + end + end + + def readchar + _read_buf + c = @buf[0] + @buf = @buf[1, @buf.size] + @pos += 1 + c + end + + def getc + begin + readchar + rescue EOFError => e + nil + end + end + + # 15.2.20.5.3 + def each(&block) + while line = self.gets + block.call(line) + end + self + end + + # 15.2.20.5.4 + def each_byte(&block) + while char = self.getc + block.call(char) + end + self + end + + # 15.2.20.5.5 + alias each_line each + + alias each_char each_byte + + def readlines + ary = [] + while (line = gets) + ary << line + end + ary + end + + def puts(*args) + i = 0 + len = args.size + while i < len + s = args[i].to_s + write s + write "\n" if (s[-1] != "\n") + i += 1 + end + write "\n" if len == 0 + nil + end + + def print(*args) + i = 0 + len = args.size + while i < len + write args[i].to_s + i += 1 + end + end + + def printf(*args) + write sprintf(*args) + nil + end + + alias_method :to_i, :fileno +end + +STDIN = IO.open(0, "r") +STDOUT = IO.open(1, "w") +STDERR = IO.open(2, "w") + +$stdin = STDIN +$stdout = STDOUT +$stderr = STDERR + +module Kernel + def print(*args) + STDOUT.print(*args) + end + + def puts(*args) + STDOUT.puts(*args) + end + + def printf(*args) + STDOUT.printf(*args) + end + + def gets(*args) + STDIN.gets(*args) + end + + def getc(*args) + STDIN.getc(*args) + end +end diff --git a/web/server/h2o/libh2o/deps/mruby-io/mrblib/kernel.rb b/web/server/h2o/libh2o/deps/mruby-io/mrblib/kernel.rb new file mode 100644 index 00000000..484b5016 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby-io/mrblib/kernel.rb @@ -0,0 +1,15 @@ +module Kernel + def self.`(cmd) + IO.popen(cmd) { |io| io.read } + end + + def open(file, *rest, &block) + raise ArgumentError unless file.is_a?(String) + + if file[0] == "|" + IO.popen(file[1..-1], *rest, &block) + else + File.open(file, *rest, &block) + end + end +end diff --git a/web/server/h2o/libh2o/deps/mruby-io/run_test.rb b/web/server/h2o/libh2o/deps/mruby-io/run_test.rb new file mode 100644 index 00000000..444d18fd --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby-io/run_test.rb @@ -0,0 +1,25 @@ +#!/usr/bin/env ruby +# +# mrbgems test runner +# + +if __FILE__ == $0 + repository, dir = 'https://github.com/mruby/mruby.git', 'tmp/mruby' + build_args = ARGV + + Dir.mkdir 'tmp' unless File.exist?('tmp') + unless File.exist?(dir) + system "git clone #{repository} #{dir}" + end + + exit system(%Q[cd #{dir}; MRUBY_CONFIG=#{File.expand_path __FILE__} ruby minirake #{build_args.join(' ')}]) +end + +MRuby::Build.new do |conf| + toolchain :gcc + conf.gembox 'default' + + conf.gem :git => 'https://github.com/iij/mruby-env.git' + + conf.gem File.expand_path(File.dirname(__FILE__)) +end diff --git a/web/server/h2o/libh2o/deps/mruby-io/src/file.c b/web/server/h2o/libh2o/deps/mruby-io/src/file.c new file mode 100644 index 00000000..feb8558e --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby-io/src/file.c @@ -0,0 +1,325 @@ +/* +** file.c - File class +*/ + +#include "mruby.h" +#include "mruby/class.h" +#include "mruby/data.h" +#include "mruby/string.h" +#include "mruby/ext/io.h" + +#if MRUBY_RELEASE_NO < 10000 +#include "error.h" +#else +#include "mruby/error.h" +#endif + +#include +#include + +#include +#include + +#include +#include +#include +#if defined(_WIN32) || defined(_WIN64) + #define NULL_FILE "NUL" + #define UNLINK _unlink + #define GETCWD _getcwd + #define CHMOD(a, b) 0 + #define MAXPATHLEN 1024 + #if !defined(PATH_MAX) + #define PATH_MAX _MAX_PATH + #endif + #define realpath(N,R) _fullpath((R),(N),_MAX_PATH) + #include +#else + #define NULL_FILE "/dev/null" + #include + #define UNLINK unlink + #define GETCWD getcwd + #define CHMOD(a, b) chmod(a,b) + #include + #include + #include + #include +#endif + +#if defined(_WIN32) || defined(_WIN64) + #define PATH_SEPARATOR ";" + #define FILE_SEPARATOR "\\" +#else + #define PATH_SEPARATOR ":" + #define FILE_SEPARATOR "/" +#endif + +#ifndef LOCK_SH +#define LOCK_SH 1 +#endif +#ifndef LOCK_EX +#define LOCK_EX 2 +#endif +#ifndef LOCK_NB +#define LOCK_NB 4 +#endif +#ifndef LOCK_UN +#define LOCK_UN 8 +#endif + +#define STAT(p, s) stat(p, s) + + +mrb_value +mrb_file_s_umask(mrb_state *mrb, mrb_value klass) +{ +#if defined(_WIN32) || defined(_WIN64) + /* nothing to do on windows */ + return mrb_fixnum_value(0); + +#else + mrb_int mask, omask; + if (mrb_get_args(mrb, "|i", &mask) == 0) { + omask = umask(0); + umask(omask); + } else { + omask = umask(mask); + } + return mrb_fixnum_value(omask); +#endif +} + +static mrb_value +mrb_file_s_unlink(mrb_state *mrb, mrb_value obj) +{ + mrb_value *argv; + mrb_value pathv; + mrb_int argc, i; + const char *path; + + mrb_get_args(mrb, "*", &argv, &argc); + for (i = 0; i < argc; i++) { + pathv = mrb_convert_type(mrb, argv[i], MRB_TT_STRING, "String", "to_str"); + path = mrb_string_value_cstr(mrb, &pathv); + if (UNLINK(path) < 0) { + mrb_sys_fail(mrb, path); + } + } + return mrb_fixnum_value(argc); +} + +static mrb_value +mrb_file_s_rename(mrb_state *mrb, mrb_value obj) +{ + mrb_value from, to; + const char *src, *dst; + + mrb_get_args(mrb, "SS", &from, &to); + src = mrb_string_value_cstr(mrb, &from); + dst = mrb_string_value_cstr(mrb, &to); + if (rename(src, dst) < 0) { + if (CHMOD(dst, 0666) == 0 && UNLINK(dst) == 0 && rename(src, dst) == 0) { + return mrb_fixnum_value(0); + } + mrb_sys_fail(mrb, mrb_str_to_cstr(mrb, mrb_format(mrb, "(%S, %S)", from, to))); + } + return mrb_fixnum_value(0); +} + +static mrb_value +mrb_file_dirname(mrb_state *mrb, mrb_value klass) +{ + #if defined(_WIN32) || defined(_WIN64) + char dname[_MAX_DIR], vname[_MAX_DRIVE]; + char buffer[_MAX_DRIVE + _MAX_DIR]; + char *path; + mrb_value s; + mrb_get_args(mrb, "S", &s); + path = mrb_str_to_cstr(mrb, s); + _splitpath((const char*)path, vname, dname, NULL, NULL); + snprintf(buffer, _MAX_DRIVE + _MAX_DIR, "%s%s", vname, dname); + return mrb_str_new_cstr(mrb, buffer); + #else + char *dname, *path; + mrb_value s; + mrb_get_args(mrb, "S", &s); + path = mrb_str_to_cstr(mrb, s); + + if ((dname = dirname(path)) == NULL) { + mrb_sys_fail(mrb, "dirname"); + } + #endif + return mrb_str_new_cstr(mrb, dname); +} + +static mrb_value +mrb_file_basename(mrb_state *mrb, mrb_value klass) +{ + #if defined(_WIN32) || defined(_WIN64) + char bname[_MAX_DIR]; + char extname[_MAX_EXT]; + char *path; + char buffer[_MAX_DIR + _MAX_EXT]; + mrb_value s; + mrb_get_args(mrb, "S", &s); + path = mrb_str_to_cstr(mrb, s); + _splitpath((const char*)path, NULL, NULL, bname, extname); + snprintf(buffer, _MAX_DIR + _MAX_EXT, "%s%s", bname, extname); + return mrb_str_new_cstr(mrb, buffer); + #else + char *bname, *path; + mrb_value s; + mrb_get_args(mrb, "S", &s); + path = mrb_str_to_cstr(mrb, s); + if ((bname = basename(path)) == NULL) { + mrb_sys_fail(mrb, "basename"); + } + return mrb_str_new_cstr(mrb, bname); + #endif +} + +static mrb_value +mrb_file_realpath(mrb_state *mrb, mrb_value klass) +{ + mrb_value pathname, dir_string, s, result; + int argc; + char *cpath; + + argc = mrb_get_args(mrb, "S|S", &pathname, &dir_string); + if (argc == 2) { + s = mrb_str_dup(mrb, dir_string); + s = mrb_str_append(mrb, s, mrb_str_new_cstr(mrb, FILE_SEPARATOR)); + s = mrb_str_append(mrb, s, pathname); + pathname = s; + } + cpath = mrb_str_to_cstr(mrb, pathname); + result = mrb_str_buf_new(mrb, PATH_MAX); + if (realpath(cpath, RSTRING_PTR(result)) == NULL) + mrb_sys_fail(mrb, cpath); + mrb_str_resize(mrb, result, strlen(RSTRING_PTR(result))); + return result; +} + +mrb_value +mrb_file__getwd(mrb_state *mrb, mrb_value klass) +{ + mrb_value path; + + path = mrb_str_buf_new(mrb, MAXPATHLEN); + if (GETCWD(RSTRING_PTR(path), MAXPATHLEN) == NULL) { + mrb_sys_fail(mrb, "getcwd(2)"); + } + mrb_str_resize(mrb, path, strlen(RSTRING_PTR(path))); + return path; +} + +static int +mrb_file_is_absolute_path(const char *path) +{ + return (path[0] == '/'); +} + +static mrb_value +mrb_file__gethome(mrb_state *mrb, mrb_value klass) +{ +#ifndef _WIN32 + mrb_value username; + int argc; + char *home; + + argc = mrb_get_args(mrb, "|S", &username); + if (argc == 0) { + home = getenv("HOME"); + if (home == NULL) { + return mrb_nil_value(); + } + if (!mrb_file_is_absolute_path(home)) { + mrb_raise(mrb, E_ARGUMENT_ERROR, "non-absolute home"); + } + } else { + const char *cuser = mrb_str_to_cstr(mrb, username); + struct passwd *pwd = getpwnam(cuser); + if (pwd == NULL) { + return mrb_nil_value(); + } + home = pwd->pw_dir; + if (!mrb_file_is_absolute_path(home)) { + mrb_raisef(mrb, E_ARGUMENT_ERROR, "non-absolute home of ~%S", username); + } + } + return mrb_str_new_cstr(mrb, home); +#else + + return mrb_nil_value(); +#endif +} + +#ifndef _WIN32 +mrb_value +mrb_file_flock(mrb_state *mrb, mrb_value self) +{ +#if defined(sun) + mrb_raise(mrb, E_RUNTIME_ERROR, "flock is not supported on Illumos/Solaris"); +#else + mrb_int operation; + int fd; + + mrb_get_args(mrb, "i", &operation); + fd = mrb_fixnum(mrb_io_fileno(mrb, self)); + + while (flock(fd, operation) == -1) { + switch (errno) { + case EINTR: + /* retry */ + break; + case EAGAIN: /* NetBSD */ +#if defined(EWOULDBLOCK) && EWOULDBLOCK != EAGAIN + case EWOULDBLOCK: /* FreeBSD OpenBSD Linux */ +#endif + if (operation & LOCK_NB) { + return mrb_false_value(); + } + /* FALLTHRU - should not happen */ + default: + mrb_sys_fail(mrb, "flock failed"); + break; + } + } +#endif + return mrb_fixnum_value(0); +} +#endif + +void +mrb_init_file(mrb_state *mrb) +{ + struct RClass *io, *file, *cnst; + + io = mrb_class_get(mrb, "IO"); + file = mrb_define_class(mrb, "File", io); + MRB_SET_INSTANCE_TT(file, MRB_TT_DATA); + mrb_define_class_method(mrb, file, "umask", mrb_file_s_umask, MRB_ARGS_REQ(1)); + mrb_define_class_method(mrb, file, "delete", mrb_file_s_unlink, MRB_ARGS_ANY()); + mrb_define_class_method(mrb, file, "unlink", mrb_file_s_unlink, MRB_ARGS_ANY()); + mrb_define_class_method(mrb, file, "rename", mrb_file_s_rename, MRB_ARGS_REQ(2)); + + mrb_define_class_method(mrb, file, "dirname", mrb_file_dirname, MRB_ARGS_REQ(1)); + mrb_define_class_method(mrb, file, "basename", mrb_file_basename, MRB_ARGS_REQ(1)); + mrb_define_class_method(mrb, file, "realpath", mrb_file_realpath, MRB_ARGS_REQ(1)|MRB_ARGS_OPT(1)); + mrb_define_class_method(mrb, file, "_getwd", mrb_file__getwd, MRB_ARGS_NONE()); + mrb_define_class_method(mrb, file, "_gethome", mrb_file__gethome, MRB_ARGS_OPT(1)); + + #ifndef _WIN32 + mrb_define_method(mrb, file, "flock", mrb_file_flock, MRB_ARGS_REQ(1)); + #endif + + cnst = mrb_define_module_under(mrb, file, "Constants"); + mrb_define_const(mrb, cnst, "LOCK_SH", mrb_fixnum_value(LOCK_SH)); + mrb_define_const(mrb, cnst, "LOCK_EX", mrb_fixnum_value(LOCK_EX)); + mrb_define_const(mrb, cnst, "LOCK_UN", mrb_fixnum_value(LOCK_UN)); + mrb_define_const(mrb, cnst, "LOCK_NB", mrb_fixnum_value(LOCK_NB)); + mrb_define_const(mrb, cnst, "SEPARATOR", mrb_str_new_cstr(mrb, FILE_SEPARATOR)); + mrb_define_const(mrb, cnst, "PATH_SEPARATOR", mrb_str_new_cstr(mrb, PATH_SEPARATOR)); + mrb_define_const(mrb, cnst, "NULL", mrb_str_new_cstr(mrb, NULL_FILE)); + +} diff --git a/web/server/h2o/libh2o/deps/mruby-io/src/file_test.c b/web/server/h2o/libh2o/deps/mruby-io/src/file_test.c new file mode 100644 index 00000000..6c380c4a --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby-io/src/file_test.c @@ -0,0 +1,365 @@ +/* +** file.c - File class +*/ + +#include "mruby.h" +#include "mruby/class.h" +#include "mruby/data.h" +#include "mruby/string.h" +#include "mruby/ext/io.h" + +#if MRUBY_RELEASE_NO < 10000 +#include "error.h" +#else +#include "mruby/error.h" +#endif + +#include +#include + +#if defined(_WIN32) || defined(_WIN64) + #define LSTAT stat + #include +#else + #define LSTAT lstat + #include + #include + #include + #include + #include + #include +#endif + +#include + +#include +#include +#include +#include + +extern struct mrb_data_type mrb_io_type; + +static int +mrb_stat0(mrb_state *mrb, mrb_value obj, struct stat *st, int do_lstat) +{ + mrb_value tmp; + mrb_value io_klass, str_klass; + + io_klass = mrb_obj_value(mrb_class_get(mrb, "IO")); + str_klass = mrb_obj_value(mrb_class_get(mrb, "String")); + + tmp = mrb_funcall(mrb, obj, "is_a?", 1, io_klass); + if (mrb_test(tmp)) { + struct mrb_io *fptr; + fptr = (struct mrb_io *)mrb_get_datatype(mrb, obj, &mrb_io_type); + + if (fptr && fptr->fd >= 0) { + return fstat(fptr->fd, st); + } + + mrb_raise(mrb, E_IO_ERROR, "closed stream"); + return -1; + } + + tmp = mrb_funcall(mrb, obj, "is_a?", 1, str_klass); + if (mrb_test(tmp)) { + if (do_lstat) { + return LSTAT(mrb_str_to_cstr(mrb, obj), st); + } else { + return stat(mrb_str_to_cstr(mrb, obj), st); + } + } + + return -1; +} + +static int +mrb_stat(mrb_state *mrb, mrb_value obj, struct stat *st) +{ + return mrb_stat0(mrb, obj, st, 0); +} + +static int +mrb_lstat(mrb_state *mrb, mrb_value obj, struct stat *st) +{ + return mrb_stat0(mrb, obj, st, 1); +} + +/* + * Document-method: directory? + * + * call-seq: + * File.directory?(file_name) -> true or false + * + * Returns true if the named file is a directory, + * or a symlink that points at a directory, and false + * otherwise. + * + * File.directory?(".") + */ + +mrb_value +mrb_filetest_s_directory_p(mrb_state *mrb, mrb_value klass) +{ +#ifndef S_ISDIR +# define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR) +#endif + + struct stat st; + mrb_value obj; + + mrb_get_args(mrb, "o", &obj); + + if (mrb_stat(mrb, obj, &st) < 0) + return mrb_false_value(); + if (S_ISDIR(st.st_mode)) + return mrb_true_value(); + + return mrb_false_value(); +} + +/* + * call-seq: + * File.pipe?(file_name) -> true or false + * + * Returns true if the named file is a pipe. + */ + +mrb_value +mrb_filetest_s_pipe_p(mrb_state *mrb, mrb_value klass) +{ +#ifdef S_IFIFO +# ifndef S_ISFIFO +# define S_ISFIFO(m) (((m) & S_IFMT) == S_IFIFO) +# endif + + struct stat st; + mrb_value obj; + + mrb_get_args(mrb, "o", &obj); + + if (mrb_stat(mrb, obj, &st) < 0) + return mrb_false_value(); + if (S_ISFIFO(st.st_mode)) + return mrb_true_value(); + +#endif + return mrb_false_value(); +} + +/* + * call-seq: + * File.symlink?(file_name) -> true or false + * + * Returns true if the named file is a symbolic link. + */ + +mrb_value +mrb_filetest_s_symlink_p(mrb_state *mrb, mrb_value klass) +{ +#ifndef S_ISLNK +# ifdef _S_ISLNK +# define S_ISLNK(m) _S_ISLNK(m) +# else +# ifdef _S_IFLNK +# define S_ISLNK(m) (((m) & S_IFMT) == _S_IFLNK) +# else +# ifdef S_IFLNK +# define S_ISLNK(m) (((m) & S_IFMT) == S_IFLNK) +# endif +# endif +# endif +#endif + +#ifdef S_ISLNK + struct stat st; + mrb_value obj; + + mrb_get_args(mrb, "o", &obj); + + if (mrb_lstat(mrb, obj, &st) == -1) + return mrb_false_value(); + if (S_ISLNK(st.st_mode)) + return mrb_true_value(); +#endif + + return mrb_false_value(); +} + +/* + * call-seq: + * File.socket?(file_name) -> true or false + * + * Returns true if the named file is a socket. + */ + +mrb_value +mrb_filetest_s_socket_p(mrb_state *mrb, mrb_value klass) +{ +#ifndef S_ISSOCK +# ifdef _S_ISSOCK +# define S_ISSOCK(m) _S_ISSOCK(m) +# else +# ifdef _S_IFSOCK +# define S_ISSOCK(m) (((m) & S_IFMT) == _S_IFSOCK) +# else +# ifdef S_IFSOCK +# define S_ISSOCK(m) (((m) & S_IFMT) == S_IFSOCK) +# endif +# endif +# endif +#endif + +#ifdef S_ISSOCK + struct stat st; + mrb_value obj; + + mrb_get_args(mrb, "o", &obj); + + if (mrb_stat(mrb, obj, &st) < 0) + return mrb_false_value(); + if (S_ISSOCK(st.st_mode)) + return mrb_true_value(); +#endif + + return mrb_false_value(); +} + +/* + * call-seq: + * File.exist?(file_name) -> true or false + * File.exists?(file_name) -> true or false + * + * Return true if the named file exists. + */ + +mrb_value +mrb_filetest_s_exist_p(mrb_state *mrb, mrb_value klass) +{ + struct stat st; + mrb_value obj; + + mrb_get_args(mrb, "o", &obj); + if (mrb_stat(mrb, obj, &st) < 0) + return mrb_false_value(); + + return mrb_true_value(); +} + +/* + * call-seq: + * File.file?(file_name) -> true or false + * + * Returns true if the named file exists and is a + * regular file. + */ + +mrb_value +mrb_filetest_s_file_p(mrb_state *mrb, mrb_value klass) +{ +#ifndef S_ISREG +# define S_ISREG(m) (((m) & S_IFMT) == S_IFREG) +#endif + + struct stat st; + mrb_value obj; + + mrb_get_args(mrb, "o", &obj); + + if (mrb_stat(mrb, obj, &st) < 0) + return mrb_false_value(); + if (S_ISREG(st.st_mode)) + return mrb_true_value(); + + return mrb_false_value(); +} + +/* + * call-seq: + * File.zero?(file_name) -> true or false + * + * Returns true if the named file exists and has + * a zero size. + */ + +mrb_value +mrb_filetest_s_zero_p(mrb_state *mrb, mrb_value klass) +{ + struct stat st; + mrb_value obj; + + mrb_get_args(mrb, "o", &obj); + + if (mrb_stat(mrb, obj, &st) < 0) + return mrb_false_value(); + if (st.st_size == 0) + return mrb_true_value(); + + return mrb_false_value(); +} + +/* + * call-seq: + * File.size(file_name) -> integer + * + * Returns the size of file_name. + * + * _file_name_ can be an IO object. + */ + +mrb_value +mrb_filetest_s_size(mrb_state *mrb, mrb_value klass) +{ + struct stat st; + mrb_value obj; + + mrb_get_args(mrb, "o", &obj); + + if (mrb_stat(mrb, obj, &st) < 0) + mrb_sys_fail(mrb, "mrb_stat"); + + return mrb_fixnum_value(st.st_size); +} + +/* + * call-seq: + * File.size?(file_name) -> Integer or nil + * + * Returns +nil+ if +file_name+ doesn't exist or has zero size, the size of the + * file otherwise. + */ + +mrb_value +mrb_filetest_s_size_p(mrb_state *mrb, mrb_value klass) +{ + struct stat st; + mrb_value obj; + + mrb_get_args(mrb, "o", &obj); + + if (mrb_stat(mrb, obj, &st) < 0) + return mrb_nil_value(); + if (st.st_size == 0) + return mrb_nil_value(); + + return mrb_fixnum_value(st.st_size); +} + +void +mrb_init_file_test(mrb_state *mrb) +{ + struct RClass *f; + + f = mrb_define_class(mrb, "FileTest", mrb->object_class); + + mrb_define_class_method(mrb, f, "directory?", mrb_filetest_s_directory_p, MRB_ARGS_REQ(1)); + mrb_define_class_method(mrb, f, "exist?", mrb_filetest_s_exist_p, MRB_ARGS_REQ(1)); + mrb_define_class_method(mrb, f, "exists?", mrb_filetest_s_exist_p, MRB_ARGS_REQ(1)); + mrb_define_class_method(mrb, f, "file?", mrb_filetest_s_file_p, MRB_ARGS_REQ(1)); + mrb_define_class_method(mrb, f, "pipe?", mrb_filetest_s_pipe_p, MRB_ARGS_REQ(1)); + mrb_define_class_method(mrb, f, "size", mrb_filetest_s_size, MRB_ARGS_REQ(1)); + mrb_define_class_method(mrb, f, "size?", mrb_filetest_s_size_p, MRB_ARGS_REQ(1)); + mrb_define_class_method(mrb, f, "socket?", mrb_filetest_s_socket_p, MRB_ARGS_REQ(1)); + mrb_define_class_method(mrb, f, "symlink?", mrb_filetest_s_symlink_p, MRB_ARGS_REQ(1)); + mrb_define_class_method(mrb, f, "zero?", mrb_filetest_s_zero_p, MRB_ARGS_REQ(1)); +} diff --git a/web/server/h2o/libh2o/deps/mruby-io/src/io.c b/web/server/h2o/libh2o/deps/mruby-io/src/io.c new file mode 100644 index 00000000..1d2f98f3 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby-io/src/io.c @@ -0,0 +1,941 @@ +/* +** io.c - IO class +*/ + +#include "mruby.h" +#include "mruby/array.h" +#include "mruby/class.h" +#include "mruby/data.h" +#include "mruby/hash.h" +#include "mruby/string.h" +#include "mruby/variable.h" +#include "mruby/ext/io.h" + +#if MRUBY_RELEASE_NO < 10000 +#include "error.h" +#else +#include "mruby/error.h" +#endif + +#include +#include + +#if defined(_WIN32) || defined(_WIN64) + #include + #include + #define open _open + #define close _close + #define read _read + #define write _write + #define lseek _lseek +#else + #include + #include +#endif + +#include + +#include +#include +#include + + +static int mrb_io_modestr_to_flags(mrb_state *mrb, const char *modestr); +static int mrb_io_flags_to_modenum(mrb_state *mrb, int flags); +static void fptr_finalize(mrb_state *mrb, struct mrb_io *fptr, int noraise); + +#if MRUBY_RELEASE_NO < 10000 +static struct RClass * +mrb_module_get(mrb_state *mrb, const char *name) +{ + return mrb_class_get(mrb, name); +} +#endif + +static int +mrb_io_modestr_to_flags(mrb_state *mrb, const char *mode) +{ + int flags = 0; + const char *m = mode; + + switch (*m++) { + case 'r': + flags |= FMODE_READABLE; + break; + case 'w': + flags |= FMODE_WRITABLE | FMODE_CREATE | FMODE_TRUNC; + break; + case 'a': + flags |= FMODE_WRITABLE | FMODE_APPEND | FMODE_CREATE; + break; + default: + mrb_raisef(mrb, E_ARGUMENT_ERROR, "illegal access mode %S", mrb_str_new_cstr(mrb, mode)); + } + + while (*m) { + switch (*m++) { + case 'b': + flags |= FMODE_BINMODE; + break; + case '+': + flags |= FMODE_READWRITE; + break; + case ':': + /* XXX: PASSTHROUGH*/ + default: + mrb_raisef(mrb, E_ARGUMENT_ERROR, "illegal access mode %S", mrb_str_new_cstr(mrb, mode)); + } + } + + return flags; +} + +static int +mrb_io_flags_to_modenum(mrb_state *mrb, int flags) +{ + int modenum = 0; + + switch(flags & (FMODE_READABLE|FMODE_WRITABLE|FMODE_READWRITE)) { + case FMODE_READABLE: + modenum = O_RDONLY; + break; + case FMODE_WRITABLE: + modenum = O_WRONLY; + break; + case FMODE_READWRITE: + modenum = O_RDWR; + break; + } + + if (flags & FMODE_APPEND) { + modenum |= O_APPEND; + } + if (flags & FMODE_TRUNC) { + modenum |= O_TRUNC; + } + if (flags & FMODE_CREATE) { + modenum |= O_CREAT; + } +#ifdef O_BINARY + if (flags & FMODE_BINMODE) { + modenum |= O_BINARY; + } +#endif + + return modenum; +} + +void +mrb_fd_cloexec(mrb_state *mrb, int fd) +{ + int flags, flags2; + +#if defined(F_GETFD) && defined(F_SETFD) && defined(FD_CLOEXEC) + flags = fcntl(fd, F_GETFD); + if (flags == -1) { + mrb_sys_fail(mrb, "fcntl"); + } + if (fd <= 2) { + flags2 = flags & ~FD_CLOEXEC; /* Clear CLOEXEC for standard file descriptors: 0, 1, 2. */ + } + else { + flags2 = flags | FD_CLOEXEC; /* Set CLOEXEC for non-standard file descriptors: 3, 4, 5, ... */ + } + if (flags != flags2) { + if (fcntl(fd, F_SETFD, flags2) == -1) { + mrb_sys_fail(mrb, "fcntl"); + } + } +#endif +} + +#ifndef _WIN32 +static int +mrb_proc_exec(const char *pname) +{ + const char *s; + s = pname; + + while (*s == ' ' || *s == '\t' || *s == '\n') + s++; + + if (!*s) { + errno = ENOENT; + return -1; + } + + execl("/bin/sh", "sh", "-c", pname, (char *)NULL); + return -1; +} +#endif + +static void +mrb_io_free(mrb_state *mrb, void *ptr) +{ + struct mrb_io *io = (struct mrb_io *)ptr; + if (io != NULL) { + fptr_finalize(mrb, io, TRUE); + mrb_free(mrb, io); + } +} + +struct mrb_data_type mrb_io_type = { "IO", mrb_io_free }; + +static struct mrb_io * +mrb_io_alloc(mrb_state *mrb) +{ + struct mrb_io *fptr; + + fptr = (struct mrb_io *)mrb_malloc(mrb, sizeof(struct mrb_io)); + fptr->fd = -1; + fptr->fd2 = -1; + fptr->pid = 0; + fptr->writable = 0; + fptr->sync = 0; + return fptr; +} + +#ifndef NOFILE +#define NOFILE 64 +#endif + +#ifndef _WIN32 +mrb_value +mrb_io_s_popen(mrb_state *mrb, mrb_value klass) +{ + mrb_value cmd, io, result; + mrb_value mode = mrb_str_new_cstr(mrb, "r"); + mrb_value opt = mrb_hash_new(mrb); + + struct mrb_io *fptr; + const char *pname; + int pid, flags, fd, write_fd = -1; + int pr[2] = { -1, -1 }; + int pw[2] = { -1, -1 }; + int doexec; + int saved_errno; + + mrb_get_args(mrb, "S|SH", &cmd, &mode, &opt); + io = mrb_obj_value(mrb_data_object_alloc(mrb, mrb_class_ptr(klass), NULL, &mrb_io_type)); + + pname = mrb_string_value_cstr(mrb, &cmd); + flags = mrb_io_modestr_to_flags(mrb, mrb_string_value_cstr(mrb, &mode)); + + doexec = (strcmp("-", pname) != 0); + + if (flags & FMODE_READABLE) { + if (pipe(pr) == -1) { + mrb_sys_fail(mrb, "pipe"); + } + mrb_fd_cloexec(mrb, pr[0]); + mrb_fd_cloexec(mrb, pr[1]); + } + + if (flags & FMODE_WRITABLE) { + if (pipe(pw) == -1) { + if (pr[0] != -1) close(pr[0]); + if (pr[1] != -1) close(pr[1]); + mrb_sys_fail(mrb, "pipe"); + } + mrb_fd_cloexec(mrb, pw[0]); + mrb_fd_cloexec(mrb, pw[1]); + } + + if (!doexec) { + // XXX + fflush(stdin); + fflush(stdout); + fflush(stderr); + } + + result = mrb_nil_value(); + switch (pid = fork()) { + case 0: /* child */ + if (flags & FMODE_READABLE) { + close(pr[0]); + if (pr[1] != 1) { + dup2(pr[1], 1); + close(pr[1]); + } + } + if (flags & FMODE_WRITABLE) { + close(pw[1]); + if (pw[0] != 0) { + dup2(pw[0], 0); + close(pw[0]); + } + } + if (doexec) { + for (fd = 3; fd < NOFILE; fd++) { + close(fd); + } + mrb_proc_exec(pname); + mrb_raisef(mrb, E_IO_ERROR, "command not found: %S", cmd); + _exit(127); + } + result = mrb_nil_value(); + break; + + default: /* parent */ + if ((flags & FMODE_READABLE) && (flags & FMODE_WRITABLE)) { + close(pr[1]); + fd = pr[0]; + close(pw[0]); + write_fd = pw[1]; + } else if (flags & FMODE_READABLE) { + close(pr[1]); + fd = pr[0]; + } else { + close(pw[0]); + fd = pw[1]; + } + + mrb_iv_set(mrb, io, mrb_intern_cstr(mrb, "@buf"), mrb_str_new_cstr(mrb, "")); + mrb_iv_set(mrb, io, mrb_intern_cstr(mrb, "@pos"), mrb_fixnum_value(0)); + + fptr = mrb_io_alloc(mrb); + fptr->fd = fd; + fptr->fd2 = write_fd; + fptr->pid = pid; + fptr->writable = ((flags & FMODE_WRITABLE) != 0); + fptr->sync = 0; + + DATA_TYPE(io) = &mrb_io_type; + DATA_PTR(io) = fptr; + result = io; + break; + + case -1: /* error */ + saved_errno = errno; + if (flags & FMODE_READABLE) { + close(pr[0]); + close(pr[1]); + } + if (flags & FMODE_WRITABLE) { + close(pw[0]); + close(pw[1]); + } + errno = saved_errno; + mrb_sys_fail(mrb, "pipe_open failed."); + break; + } + return result; +} +#endif + +mrb_value +mrb_io_initialize(mrb_state *mrb, mrb_value io) +{ + struct mrb_io *fptr; + mrb_int fd; + mrb_value mode, opt; + int flags; + + mode = opt = mrb_nil_value(); + + mrb_get_args(mrb, "i|So", &fd, &mode, &opt); + if (mrb_nil_p(mode)) { + mode = mrb_str_new_cstr(mrb, "r"); + } + if (mrb_nil_p(opt)) { + opt = mrb_hash_new(mrb); + } + + flags = mrb_io_modestr_to_flags(mrb, mrb_string_value_cstr(mrb, &mode)); + + mrb_iv_set(mrb, io, mrb_intern_cstr(mrb, "@buf"), mrb_str_new_cstr(mrb, "")); + mrb_iv_set(mrb, io, mrb_intern_cstr(mrb, "@pos"), mrb_fixnum_value(0)); + + fptr = DATA_PTR(io); + if (fptr != NULL) { + fptr_finalize(mrb, fptr, 0); + mrb_free(mrb, fptr); + } + fptr = mrb_io_alloc(mrb); + + DATA_TYPE(io) = &mrb_io_type; + DATA_PTR(io) = fptr; + + fptr->fd = fd; + fptr->writable = ((flags & FMODE_WRITABLE) != 0); + fptr->sync = 0; + return io; +} + +static void +fptr_finalize(mrb_state *mrb, struct mrb_io *fptr, int noraise) +{ + int n = 0; + + if (fptr == NULL) { + return; + } + + if (fptr->fd > 2) { + n = close(fptr->fd); + if (n == 0) { + fptr->fd = -1; + } + } + if (fptr->fd2 > 2) { + n = close(fptr->fd2); + if (n == 0) { + fptr->fd2 = -1; + } + } + +#if !defined(_WIN32) && !defined(_WIN64) + if (fptr->pid != 0) { + pid_t pid; + do { + pid = waitpid(fptr->pid, NULL, 0); + } while (pid == -1 && errno == EINTR); + } +#endif + + if (!noraise && n != 0) { + mrb_sys_fail(mrb, "fptr_finalize failed."); + } +} + +mrb_value +mrb_io_s_for_fd(mrb_state *mrb, mrb_value klass) +{ + struct RClass *c = mrb_class_ptr(klass); + enum mrb_vtype ttype = MRB_INSTANCE_TT(c); + mrb_value obj; + + /* copied from mrb_instance_alloc() */ + if (ttype == 0) ttype = MRB_TT_OBJECT; + obj = mrb_obj_value((struct RObject*)mrb_obj_alloc(mrb, ttype, c)); + return mrb_io_initialize(mrb, obj); +} + +mrb_value +mrb_io_s_sysclose(mrb_state *mrb, mrb_value klass) +{ + mrb_int fd; + mrb_get_args(mrb, "i", &fd); + if (close(fd) == -1) { + mrb_sys_fail(mrb, "close"); + } + return mrb_fixnum_value(0); +} + +int +mrb_cloexec_open(mrb_state *mrb, const char *pathname, mrb_int flags, mrb_int mode) +{ + int fd, retry = FALSE; + +#ifdef O_CLOEXEC + /* O_CLOEXEC is available since Linux 2.6.23. Linux 2.6.18 silently ignore it. */ + flags |= O_CLOEXEC; +#elif defined O_NOINHERIT + flags |= O_NOINHERIT; +#endif +reopen: + fd = open(pathname, flags, mode); + if (fd == -1) { + if (!retry) { + switch (errno) { + case ENFILE: + case EMFILE: + mrb_garbage_collect(mrb); + retry = TRUE; + goto reopen; + } + } + mrb_sys_fail(mrb, "open"); + } + + if (fd <= 2) { + mrb_fd_cloexec(mrb, fd); + } + return fd; +} + +mrb_value +mrb_io_s_sysopen(mrb_state *mrb, mrb_value klass) +{ + mrb_value path = mrb_nil_value(); + mrb_value mode = mrb_nil_value(); + mrb_int fd, flags, perm = -1; + const char *pat; + int modenum; + + mrb_get_args(mrb, "S|Si", &path, &mode, &perm); + if (mrb_nil_p(mode)) { + mode = mrb_str_new_cstr(mrb, "r"); + } + if (perm < 0) { + perm = 0666; + } + + pat = mrb_string_value_cstr(mrb, &path); + flags = mrb_io_modestr_to_flags(mrb, mrb_string_value_cstr(mrb, &mode)); + modenum = mrb_io_flags_to_modenum(mrb, flags); + fd = mrb_cloexec_open(mrb, pat, modenum, perm); + return mrb_fixnum_value(fd); +} + +mrb_value +mrb_io_sysread(mrb_state *mrb, mrb_value io) +{ + struct mrb_io *fptr; + mrb_value buf = mrb_nil_value(); + mrb_int maxlen; + int ret; + + mrb_get_args(mrb, "i|S", &maxlen, &buf); + if (maxlen < 0) { + return mrb_nil_value(); + } + + if (mrb_nil_p(buf)) { + buf = mrb_str_new(mrb, NULL, maxlen); + } + if (RSTRING_LEN(buf) != maxlen) { + buf = mrb_str_resize(mrb, buf, maxlen); + } + + fptr = (struct mrb_io *)mrb_get_datatype(mrb, io, &mrb_io_type); + ret = read(fptr->fd, RSTRING_PTR(buf), maxlen); + switch (ret) { + case 0: /* EOF */ + if (maxlen == 0) { + buf = mrb_str_new_cstr(mrb, ""); + } else { + mrb_raise(mrb, E_EOF_ERROR, "sysread failed: End of File"); + } + break; + case -1: /* Error */ + mrb_sys_fail(mrb, "sysread failed"); + break; + default: + if (RSTRING_LEN(buf) != ret) { + buf = mrb_str_resize(mrb, buf, ret); + } + break; + } + + return buf; +} + +mrb_value +mrb_io_sysseek(mrb_state *mrb, mrb_value io) +{ + struct mrb_io *fptr; + int pos; + mrb_int offset, whence = -1; + + mrb_get_args(mrb, "i|i", &offset, &whence); + if (whence < 0) { + whence = 0; + } + + fptr = (struct mrb_io *)mrb_get_datatype(mrb, io, &mrb_io_type); + pos = lseek(fptr->fd, offset, whence); + if (pos < 0) { + mrb_raise(mrb, E_IO_ERROR, "sysseek faield"); + } + + return mrb_fixnum_value(pos); +} + +mrb_value +mrb_io_syswrite(mrb_state *mrb, mrb_value io) +{ + struct mrb_io *fptr; + mrb_value str, buf; + int fd, length; + + fptr = (struct mrb_io *)mrb_get_datatype(mrb, io, &mrb_io_type); + if (! fptr->writable) { + mrb_raise(mrb, E_IO_ERROR, "not opened for writing"); + } + + mrb_get_args(mrb, "S", &str); + if (mrb_type(str) != MRB_TT_STRING) { + buf = mrb_funcall(mrb, str, "to_s", 0); + } else { + buf = str; + } + + if (fptr->fd2 == -1) { + fd = fptr->fd; + } else { + fd = fptr->fd2; + } + length = write(fd, RSTRING_PTR(buf), RSTRING_LEN(buf)); + + return mrb_fixnum_value(length); +} + +mrb_value +mrb_io_close(mrb_state *mrb, mrb_value io) +{ + struct mrb_io *fptr; + fptr = (struct mrb_io *)mrb_get_datatype(mrb, io, &mrb_io_type); + if (fptr && fptr->fd < 0) { + mrb_raise(mrb, E_IO_ERROR, "closed stream."); + } + fptr_finalize(mrb, fptr, FALSE); + return mrb_nil_value(); +} + +mrb_value +mrb_io_closed(mrb_state *mrb, mrb_value io) +{ + struct mrb_io *fptr; + fptr = (struct mrb_io *)mrb_get_datatype(mrb, io, &mrb_io_type); + if (fptr->fd >= 0) { + return mrb_false_value(); + } + + return mrb_true_value(); +} + +mrb_value +mrb_io_pid(mrb_state *mrb, mrb_value io) +{ + struct mrb_io *fptr; + fptr = (struct mrb_io *)mrb_get_datatype(mrb, io, &mrb_io_type); + + if (fptr->pid > 0) { + return mrb_fixnum_value(fptr->pid); + } + + return mrb_nil_value(); +} + +static struct timeval +time2timeval(mrb_state *mrb, mrb_value time) +{ + struct timeval t = { 0, 0 }; + + switch (mrb_type(time)) { + case MRB_TT_FIXNUM: + t.tv_sec = mrb_fixnum(time); + t.tv_usec = 0; + break; + + case MRB_TT_FLOAT: + t.tv_sec = mrb_float(time); + t.tv_usec = (mrb_float(time) - t.tv_sec) * 1000000.0; + break; + + default: + mrb_raise(mrb, E_TYPE_ERROR, "wrong argument class"); + } + + return t; +} + +static int +mrb_io_read_data_pending(mrb_state *mrb, mrb_value io) +{ + mrb_value buf = mrb_iv_get(mrb, io, mrb_intern_cstr(mrb, "@buf")); + if (mrb_type(buf) == MRB_TT_STRING && RSTRING_LEN(buf) > 0) { + return 1; + } + return 0; +} + +static mrb_value +mrb_io_s_select(mrb_state *mrb, mrb_value klass) +{ + mrb_value *argv; + mrb_int argc; + mrb_value read, read_io, write, except, timeout, list; + struct timeval *tp, timerec; + fd_set pset, rset, wset, eset; + fd_set *rp, *wp, *ep; + struct mrb_io *fptr; + int pending = 0; + mrb_value result; + int max = 0; + int interrupt_flag = 0; + int i, n; + + mrb_get_args(mrb, "*", &argv, &argc); + + if (argc < 1 || argc > 4) { + mrb_raisef(mrb, E_ARGUMENT_ERROR, "wrong number of arguments (%S for 1..4)", mrb_fixnum_value(argc)); + } + + timeout = mrb_nil_value(); + except = mrb_nil_value(); + write = mrb_nil_value(); + if (argc > 3) + timeout = argv[3]; + if (argc > 2) + except = argv[2]; + if (argc > 1) + write = argv[1]; + read = argv[0]; + + if (mrb_nil_p(timeout)) { + tp = NULL; + } else { + timerec = time2timeval(mrb, timeout); + tp = &timerec; + } + + FD_ZERO(&pset); + if (!mrb_nil_p(read)) { + mrb_check_type(mrb, read, MRB_TT_ARRAY); + rp = &rset; + FD_ZERO(rp); + for (i = 0; i < RARRAY_LEN(read); i++) { + read_io = RARRAY_PTR(read)[i]; + fptr = (struct mrb_io *)mrb_get_datatype(mrb, read_io, &mrb_io_type); + FD_SET(fptr->fd, rp); + if (mrb_io_read_data_pending(mrb, read_io)) { + pending++; + FD_SET(fptr->fd, &pset); + } + if (max < fptr->fd) + max = fptr->fd; + } + if (pending) { + timerec.tv_sec = timerec.tv_usec = 0; + tp = &timerec; + } + } else { + rp = NULL; + } + + if (!mrb_nil_p(write)) { + mrb_check_type(mrb, write, MRB_TT_ARRAY); + wp = &wset; + FD_ZERO(wp); + for (i = 0; i < RARRAY_LEN(write); i++) { + fptr = (struct mrb_io *)mrb_get_datatype(mrb, RARRAY_PTR(write)[i], &mrb_io_type); + FD_SET(fptr->fd, wp); + if (max < fptr->fd) + max = fptr->fd; + if (fptr->fd2 >= 0) { + FD_SET(fptr->fd2, wp); + if (max < fptr->fd2) + max = fptr->fd2; + } + } + } else { + wp = NULL; + } + + if (!mrb_nil_p(except)) { + mrb_check_type(mrb, except, MRB_TT_ARRAY); + ep = &eset; + FD_ZERO(ep); + for (i = 0; i < RARRAY_LEN(except); i++) { + fptr = (struct mrb_io *)mrb_get_datatype(mrb, RARRAY_PTR(except)[i], &mrb_io_type); + FD_SET(fptr->fd, ep); + if (max < fptr->fd) + max = fptr->fd; + if (fptr->fd2 >= 0) { + FD_SET(fptr->fd2, ep); + if (max < fptr->fd2) + max = fptr->fd2; + } + } + } else { + ep = NULL; + } + + max++; + +retry: + n = select(max, rp, wp, ep, tp); + if (n < 0) { + if (errno != EINTR) + mrb_sys_fail(mrb, "select failed"); + if (tp == NULL) + goto retry; + interrupt_flag = 1; + } + + if (!pending && n == 0) + return mrb_nil_value(); + + result = mrb_ary_new_capa(mrb, 3); + mrb_ary_push(mrb, result, rp? mrb_ary_new(mrb) : mrb_ary_new_capa(mrb, 0)); + mrb_ary_push(mrb, result, wp? mrb_ary_new(mrb) : mrb_ary_new_capa(mrb, 0)); + mrb_ary_push(mrb, result, ep? mrb_ary_new(mrb) : mrb_ary_new_capa(mrb, 0)); + + if (interrupt_flag == 0) { + if (rp) { + list = RARRAY_PTR(result)[0]; + for (i = 0; i < RARRAY_LEN(read); i++) { + fptr = (struct mrb_io *)mrb_get_datatype(mrb, RARRAY_PTR(read)[i], &mrb_io_type); + if (FD_ISSET(fptr->fd, rp) || + FD_ISSET(fptr->fd, &pset)) { + mrb_ary_push(mrb, list, RARRAY_PTR(read)[i]); + } + } + } + + if (wp) { + list = RARRAY_PTR(result)[1]; + for (i = 0; i < RARRAY_LEN(write); i++) { + fptr = (struct mrb_io *)mrb_get_datatype(mrb, RARRAY_PTR(write)[i], &mrb_io_type); + if (FD_ISSET(fptr->fd, wp)) { + mrb_ary_push(mrb, list, RARRAY_PTR(write)[i]); + } else if (fptr->fd2 >= 0 && FD_ISSET(fptr->fd2, wp)) { + mrb_ary_push(mrb, list, RARRAY_PTR(write)[i]); + } + } + } + + if (ep) { + list = RARRAY_PTR(result)[2]; + for (i = 0; i < RARRAY_LEN(except); i++) { + fptr = (struct mrb_io *)mrb_get_datatype(mrb, RARRAY_PTR(except)[i], &mrb_io_type); + if (FD_ISSET(fptr->fd, ep)) { + mrb_ary_push(mrb, list, RARRAY_PTR(except)[i]); + } else if (fptr->fd2 >= 0 && FD_ISSET(fptr->fd2, ep)) { + mrb_ary_push(mrb, list, RARRAY_PTR(except)[i]); + } + } + } + } + + return result; +} + +mrb_value +mrb_io_fileno(mrb_state *mrb, mrb_value io) +{ + struct mrb_io *fptr; + fptr = (struct mrb_io *)mrb_get_datatype(mrb, io, &mrb_io_type); + return mrb_fixnum_value(fptr->fd); +} + +mrb_value +mrb_io_close_on_exec_p(mrb_state *mrb, mrb_value io) +{ +#if defined(F_GETFD) && defined(F_SETFD) && defined(FD_CLOEXEC) + struct mrb_io *fptr; + int ret; + + fptr = (struct mrb_io *)mrb_get_datatype(mrb, io, &mrb_io_type); + if (fptr->fd < 0) { + mrb_raise(mrb, E_IO_ERROR, "closed stream"); + } + + if (fptr->fd2 >= 0) { + if ((ret = fcntl(fptr->fd2, F_GETFD)) == -1) mrb_sys_fail(mrb, "F_GETFD failed"); + if (!(ret & FD_CLOEXEC)) return mrb_false_value(); + } + + if ((ret = fcntl(fptr->fd, F_GETFD)) == -1) mrb_sys_fail(mrb, "F_GETFD failed"); + if (!(ret & FD_CLOEXEC)) return mrb_false_value(); + return mrb_true_value(); + +#else + mrb_raise(mrb, E_NOTIMP_ERROR, "IO#close_on_exec? is not supported on the platform"); + return mrb_false_value(); +#endif +} + +mrb_value +mrb_io_set_close_on_exec(mrb_state *mrb, mrb_value io) +{ +#if defined(F_GETFD) && defined(F_SETFD) && defined(FD_CLOEXEC) + struct mrb_io *fptr; + int flag, ret; + mrb_bool b; + + fptr = (struct mrb_io *)mrb_get_datatype(mrb, io, &mrb_io_type); + if (fptr->fd < 0) { + mrb_raise(mrb, E_IO_ERROR, "closed stream"); + } + + mrb_get_args(mrb, "b", &b); + flag = b ? FD_CLOEXEC : 0; + + if (fptr->fd2 >= 0) { + if ((ret = fcntl(fptr->fd2, F_GETFD)) == -1) mrb_sys_fail(mrb, "F_GETFD failed"); + if ((ret & FD_CLOEXEC) != flag) { + ret = (ret & ~FD_CLOEXEC) | flag; + ret = fcntl(fptr->fd2, F_SETFD, ret); + + if (ret == -1) mrb_sys_fail(mrb, "F_SETFD failed"); + } + } + + if ((ret = fcntl(fptr->fd, F_GETFD)) == -1) mrb_sys_fail(mrb, "F_GETFD failed"); + if ((ret & FD_CLOEXEC) != flag) { + ret = (ret & ~FD_CLOEXEC) | flag; + ret = fcntl(fptr->fd, F_SETFD, ret); + if (ret == -1) mrb_sys_fail(mrb, "F_SETFD failed"); + } + + return mrb_bool_value(b); +#else + mrb_raise(mrb, E_NOTIMP_ERROR, "IO#close_on_exec= is not supported on the platform"); + return mrb_nil_value(); +#endif +} + +mrb_value +mrb_io_set_sync(mrb_state *mrb, mrb_value self) +{ + struct mrb_io *fptr; + mrb_bool b; + + fptr = (struct mrb_io *)mrb_get_datatype(mrb, self, &mrb_io_type); + if (fptr->fd < 0) { + mrb_raise(mrb, E_IO_ERROR, "closed stream."); + } + + mrb_get_args(mrb, "b", &b); + fptr->sync = b; + return mrb_bool_value(b); +} + +mrb_value +mrb_io_sync(mrb_state *mrb, mrb_value self) +{ + struct mrb_io *fptr; + + fptr = (struct mrb_io *)mrb_get_datatype(mrb, self, &mrb_io_type); + if (fptr->fd < 0) { + mrb_raise(mrb, E_IO_ERROR, "closed stream."); + } + return mrb_bool_value(fptr->sync); +} + +void +mrb_init_io(mrb_state *mrb) +{ + struct RClass *io; + + io = mrb_define_class(mrb, "IO", mrb->object_class); + MRB_SET_INSTANCE_TT(io, MRB_TT_DATA); + + mrb_include_module(mrb, io, mrb_module_get(mrb, "Enumerable")); /* 15.2.20.3 */ +#ifndef _WIN32 + mrb_define_class_method(mrb, io, "_popen", mrb_io_s_popen, MRB_ARGS_ANY()); + mrb_define_class_method(mrb, io, "_sysclose", mrb_io_s_sysclose, MRB_ARGS_REQ(1)); +#endif + mrb_define_class_method(mrb, io, "for_fd", mrb_io_s_for_fd, MRB_ARGS_ANY()); + mrb_define_class_method(mrb, io, "select", mrb_io_s_select, MRB_ARGS_ANY()); + mrb_define_class_method(mrb, io, "sysopen", mrb_io_s_sysopen, MRB_ARGS_ANY()); + + mrb_define_method(mrb, io, "initialize", mrb_io_initialize, MRB_ARGS_ANY()); /* 15.2.20.5.21 (x)*/ + mrb_define_method(mrb, io, "sync", mrb_io_sync, MRB_ARGS_NONE()); + mrb_define_method(mrb, io, "sync=", mrb_io_set_sync, MRB_ARGS_REQ(1)); + mrb_define_method(mrb, io, "sysread", mrb_io_sysread, MRB_ARGS_ANY()); + mrb_define_method(mrb, io, "sysseek", mrb_io_sysseek, MRB_ARGS_REQ(1)); + mrb_define_method(mrb, io, "syswrite", mrb_io_syswrite, MRB_ARGS_REQ(1)); + mrb_define_method(mrb, io, "close", mrb_io_close, MRB_ARGS_NONE()); /* 15.2.20.5.1 */ + mrb_define_method(mrb, io, "close_on_exec=", mrb_io_set_close_on_exec, MRB_ARGS_REQ(1)); + mrb_define_method(mrb, io, "close_on_exec?", mrb_io_close_on_exec_p, MRB_ARGS_NONE()); + mrb_define_method(mrb, io, "closed?", mrb_io_closed, MRB_ARGS_NONE()); /* 15.2.20.5.2 */ + mrb_define_method(mrb, io, "pid", mrb_io_pid, MRB_ARGS_NONE()); /* 15.2.20.5.2 */ + mrb_define_method(mrb, io, "fileno", mrb_io_fileno, MRB_ARGS_NONE()); + + + mrb_gv_set(mrb, mrb_intern_cstr(mrb, "$/"), mrb_str_new_cstr(mrb, "\n")); +} diff --git a/web/server/h2o/libh2o/deps/mruby-io/src/mruby_io_gem.c b/web/server/h2o/libh2o/deps/mruby-io/src/mruby_io_gem.c new file mode 100644 index 00000000..6880e667 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby-io/src/mruby_io_gem.c @@ -0,0 +1,20 @@ +#include "mruby.h" + +void mrb_init_io(mrb_state *mrb); +void mrb_init_file(mrb_state *mrb); +void mrb_init_file_test(mrb_state *mrb); + +#define DONE mrb_gc_arena_restore(mrb, 0) + +void +mrb_mruby_io_gem_init(mrb_state* mrb) +{ + mrb_init_io(mrb); DONE; + mrb_init_file(mrb); DONE; + mrb_init_file_test(mrb); DONE; +} + +void +mrb_mruby_io_gem_final(mrb_state* mrb) +{ +} diff --git a/web/server/h2o/libh2o/deps/mruby-io/test/file.rb b/web/server/h2o/libh2o/deps/mruby-io/test/file.rb new file mode 100644 index 00000000..d6f39ceb --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby-io/test/file.rb @@ -0,0 +1,108 @@ +## +# IO Test + +assert('File', '15.2.21') do + File.class == Class +end + +assert('File', '15.2.21.2') do + File.superclass == IO +end + +assert('File TEST SETUP') do + MRubyIOTestUtil.io_test_setup +end + +assert('File#initialize', '15.2.21.4.1') do + io = File.open($mrbtest_io_rfname, "r") + assert_nil io.close + assert_raise IOError do + io.close + end +end + +assert('File#path', '15.2.21.4.2') do + io = File.open($mrbtest_io_rfname, "r") + assert_equal $mrbtest_io_msg, io.read + assert_equal $mrbtest_io_rfname, io.path + io.close + assert_equal $mrbtest_io_rfname, io.path + io.closed? +end + +assert('File.basename') do + assert_equal '/', File.basename('//') + assert_equal 'a', File.basename('/a/') + assert_equal 'b', File.basename('/a/b') + assert_equal 'b', File.basename('../a/b') +end + +assert('File.dirname') do + assert_equal '.', File.dirname('') + assert_equal '.', File.dirname('a') + assert_equal '/', File.dirname('/a') + assert_equal 'a', File.dirname('a/b') + assert_equal '/a', File.dirname('/a/b') +end + +assert('File.extname') do + assert_equal '.txt', File.extname('foo/foo.txt') + assert_equal '.gz', File.extname('foo/foo.tar.gz') + assert_equal '', File.extname('foo/bar') + assert_equal '', File.extname('foo/.bar') + assert_equal '', File.extname('foo.txt/bar') + assert_equal '', File.extname('.foo') +end + +assert('IO#flock') do + f = File.open $mrbtest_io_rfname + assert_equal(f.flock(File::LOCK_SH), 0) + assert_equal(f.flock(File::LOCK_UN), 0) + assert_equal(f.flock(File::LOCK_EX | File::LOCK_NB), 0) + assert_equal(f.flock(File::LOCK_UN), 0) + f.close + true +end + +assert('File.join') do + File.join() == "" and + File.join("a") == "a" and + File.join("/a") == "/a" and + File.join("a/") == "a/" and + File.join("a", "b", "c") == "a/b/c" and + File.join("/a", "b", "c") == "/a/b/c" and + File.join("a", "b", "c/") == "a/b/c/" and + File.join("a/", "/b/", "/c") == "a/b/c" +end + +assert('File.realpath') do + usrbin = IO.popen("cd bin; /bin/pwd -P") { |f| f.read.chomp } + assert_equal usrbin, File.realpath("bin") +end + +assert('File TEST CLEANUP') do + assert_nil MRubyIOTestUtil.io_test_cleanup +end + +assert('File.expand_path') do + assert_equal "/", File.expand_path("..", "/tmp"), "parent path with base_dir (1)" + assert_equal "/tmp", File.expand_path("..", "/tmp/mruby"), "parent path with base_dir (2)" + + assert_equal "/home", File.expand_path("/home"), "absolute" + assert_equal "/home", File.expand_path("/home", "."), "absolute with base_dir" + + assert_equal "/hoge", File.expand_path("/tmp/..//hoge") + assert_equal "/hoge", File.expand_path("////tmp/..///////hoge") + + assert_equal "/", File.expand_path("../../../..", "/") + assert_equal "/", File.expand_path(([".."] * 100).join("/")) +end + +assert('File.expand_path (with ENV)') do + skip unless Object.const_defined?(:ENV) && ENV['HOME'] + + assert_equal ENV['HOME'], File.expand_path("~/"), "home" + assert_equal ENV['HOME'], File.expand_path("~/", "/"), "home with base_dir" + + assert_equal "#{ENV['HOME']}/user", File.expand_path("user", ENV['HOME']), "relative with base_dir" +end diff --git a/web/server/h2o/libh2o/deps/mruby-io/test/file_test.rb b/web/server/h2o/libh2o/deps/mruby-io/test/file_test.rb new file mode 100644 index 00000000..11742f2d --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby-io/test/file_test.rb @@ -0,0 +1,95 @@ +## +# FileTest + +assert('FileTest TEST SETUP') do + MRubyIOTestUtil.io_test_setup +end + +assert("FileTest.directory?") do + assert_equal true, FileTest.directory?("/tmp") + assert_equal false, FileTest.directory?("/bin/sh") +end + +assert("FileTest.exist?") do + assert_equal true, FileTest.exist?($mrbtest_io_rfname), "filename - exist" + assert_equal false, FileTest.exist?($mrbtest_io_rfname + "-"), "filename - not exist" + io = IO.new(IO.sysopen($mrbtest_io_rfname)) + assert_equal true, FileTest.exist?(io), "io obj - exist" + io.close + assert_equal true, io.closed? + assert_raise IOError do + FileTest.exist?(io) + end +end + +assert("FileTest.file?") do + assert_equal false, FileTest.file?("/tmp") + assert_equal true, FileTest.file?("/bin/sh") +end + +assert("FileTest.pipe?") do + io = IO.popen("ls") + assert_equal true, FileTest.pipe?(io) + assert_equal false, FileTest.pipe?("/tmp") +end + +assert('FileTest.size') do + assert_equal FileTest.size($mrbtest_io_rfname), $mrbtest_io_msg.size + assert_equal FileTest.size($mrbtest_io_wfname), 0 +end + +assert("FileTest.size?") do + assert_equal $mrbtest_io_msg.size, FileTest.size?($mrbtest_io_rfname) + assert_equal nil, FileTest.size?($mrbtest_io_wfname) + assert_equal nil, FileTest.size?("not-exist-test-target-file") + + fp1 = File.open($mrbtest_io_rfname) + fp2 = File.open($mrbtest_io_wfname) + assert_equal $mrbtest_io_msg.size, FileTest.size?(fp1) + assert_equal nil, FileTest.size?(fp2) + fp1.close + fp2.close + + assert_raise IOError do + FileTest.size?(fp1) + end + assert_raise IOError do + FileTest.size?(fp2) + end + + fp1.closed? && fp2.closed? +end + +assert("FileTest.socket?") do + assert_true FileTest.socket?($mrbtest_io_socketname) +end + +assert("FileTest.symlink?") do + assert_true FileTest.symlink?($mrbtest_io_symlinkname) +end + +assert("FileTest.zero?") do + assert_equal false, FileTest.zero?($mrbtest_io_rfname) + assert_equal true, FileTest.zero?($mrbtest_io_wfname) + assert_equal false, FileTest.zero?("not-exist-test-target-file") + + fp1 = File.open($mrbtest_io_rfname) + fp2 = File.open($mrbtest_io_wfname) + assert_equal false, FileTest.zero?(fp1) + assert_equal true, FileTest.zero?(fp2) + fp1.close + fp2.close + + assert_raise IOError do + FileTest.zero?(fp1) + end + assert_raise IOError do + FileTest.zero?(fp2) + end + + fp1.closed? && fp2.closed? +end + +assert('FileTest TEST CLEANUP') do + assert_nil MRubyIOTestUtil.io_test_cleanup +end diff --git a/web/server/h2o/libh2o/deps/mruby-io/test/gc_filedes.sh b/web/server/h2o/libh2o/deps/mruby-io/test/gc_filedes.sh new file mode 100644 index 00000000..6e5d1bbf --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby-io/test/gc_filedes.sh @@ -0,0 +1,4 @@ +#!/bin/sh + +ulimit -n 20 +mruby -e '100.times { File.open "'$0'" }' diff --git a/web/server/h2o/libh2o/deps/mruby-io/test/io.rb b/web/server/h2o/libh2o/deps/mruby-io/test/io.rb new file mode 100644 index 00000000..b828fef4 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby-io/test/io.rb @@ -0,0 +1,416 @@ +## +# IO Test + +assert('IO TEST SETUP') do + MRubyIOTestUtil.io_test_setup +end + +assert('IO', '15.2.20') do + assert_equal(Class, IO.class) +end + +assert('IO', '15.2.20.2') do + assert_equal(Object, IO.superclass) +end + +assert('IO', '15.2.20.3') do + assert_include(IO.included_modules, Enumerable) +end + +assert('IO.open', '15.2.20.4.1') do + fd = IO.sysopen $mrbtest_io_rfname + assert_equal Fixnum, fd.class + io = IO.open fd + assert_equal IO, io.class + assert_equal $mrbtest_io_msg, io.read + io.close + + fd = IO.sysopen $mrbtest_io_rfname + IO.open(fd) do |io| + assert_equal $mrbtest_io_msg, io.read + end + + true +end + +assert('IO#close', '15.2.20.5.1') do + io = IO.new(IO.sysopen($mrbtest_io_rfname)) + assert_nil io.close +end + +assert('IO#closed?', '15.2.20.5.2') do + io = IO.new(IO.sysopen($mrbtest_io_rfname)) + assert_false io.closed? + io.close + assert_true io.closed? +end + +#assert('IO#each', '15.2.20.5.3') do +#assert('IO#each_byte', '15.2.20.5.4') do +#assert('IO#each_line', '15.2.20.5.5') do + +assert('IO#eof?', '15.2.20.5.6') do + io = IO.new(IO.sysopen($mrbtest_io_rfname)) + $mrbtest_io_msg.each_char { |ch| + # XXX + #assert_false io.eof? + io.getc + } + assert_true io.eof? + io.close + true +end + +assert('IO#flush', '15.2.20.5.7') do + # Note: mruby-io does not have any buffer to be flushed now. + io = IO.new(IO.sysopen($mrbtest_io_wfname)) + assert_equal io, io.flush + io.close + assert_raise(IOError) do + io.flush + end +end + +assert('IO#getc', '15.2.20.5.8') do + io = IO.new(IO.sysopen($mrbtest_io_rfname)) + $mrbtest_io_msg.each_char { |ch| + assert_equal ch, io.getc + } + assert_equal nil, io.getc + io.close + true +end + +#assert('IO#gets', '15.2.20.5.9') do +#assert('IO#initialize_copy', '15.2.20.5.10') do +#assert('IO#print', '15.2.20.5.11') do +#assert('IO#putc', '15.2.20.5.12') do +#assert('IO#puts', '15.2.20.5.13') do + +assert('IO#read', '15.2.20.5.14') do + IO.open(IO.sysopen($mrbtest_io_rfname)) do |io| + assert_raise(ArgumentError) { io.read(-5) } + assert_raise(TypeError) { io.read("str") } + + len = $mrbtest_io_msg.length + assert_equal '', io.read(0) + assert_equal 'mruby', io.read(5) + assert_equal $mrbtest_io_msg[5,len], io.read(len) + + assert_equal "", io.read + assert_nil io.read(1) + end + + IO.open(IO.sysopen($mrbtest_io_rfname)) do |io| + assert_equal $mrbtest_io_msg, io.read + end +end + +assert('IO#readchar', '15.2.20.5.15') do + # almost same as IO#getc + IO.open(IO.sysopen($mrbtest_io_rfname)) do |io| + $mrbtest_io_msg.each_char { |ch| + assert_equal ch, io.readchar + } + assert_raise(EOFError) do + io.readchar + end + end +end + +#assert('IO#readline', '15.2.20.5.16') do +#assert('IO#readlines', '15.2.20.5.17') do + +assert('IO#sync', '15.2.20.5.18') do + io = IO.new(IO.sysopen($mrbtest_io_rfname)) + s = io.sync + assert_true(s == true || s == false) + io.close + assert_raise(IOError) do + io.sync + end +end + +assert('IO#sync=', '15.2.20.5.19') do + io = IO.new(IO.sysopen($mrbtest_io_rfname)) + io.sync = true + assert_true io.sync + io.sync = false + assert_false io.sync + io.close + assert_raise(IOError) do + io.sync = true + end +end + +assert('IO#write', '15.2.20.5.20') do + io = IO.open(IO.sysopen($mrbtest_io_wfname)) + assert_equal 0, io.write("") + io.close + true +end + +assert('IO.for_fd') do + fd = IO.sysopen($mrbtest_io_rfname) + io = IO.for_fd(fd) + assert_equal $mrbtest_io_msg, io.read + io.close + true +end + +assert('IO.new') do + io = IO.new(0) + io.close + true +end + +assert('IO gc check') do + 100.times { IO.new(0) } +end + +assert('IO.sysopen("./nonexistent")') do + if Object.const_defined? :Errno + eclass = Errno::ENOENT + else + eclass = RuntimeError + end + assert_raise eclass do + fd = IO.sysopen "./nonexistent" + IO._sysclose fd + end +end + +assert('IO.sysopen, IO#sysread') do + fd = IO.sysopen $mrbtest_io_rfname + io = IO.new fd + str1 = " " + str2 = io.sysread(5, str1) + assert_equal $mrbtest_io_msg[0,5], str1 + assert_equal $mrbtest_io_msg[0,5], str2 + assert_raise EOFError do + io.sysread(10000) + io.sysread(10000) + end + io.close + io.closed? +end + +assert('IO.sysopen, IO#syswrite') do + fd = IO.sysopen $mrbtest_io_wfname, "w" + io = IO.new fd, "w" + str = "abcdefg" + len = io.syswrite(str) + assert_equal str.size, len + io.close + + io = IO.new(IO.sysopen($mrbtest_io_rfname), "r") + assert_raise(IOError) { io.syswrite("a") } + io.close + + true +end + +assert('IO#_read_buf') do + fd = IO.sysopen $mrbtest_io_rfname + io = IO.new fd + def io._buf + @buf + end + msg_len = $mrbtest_io_msg.size + assert_equal '', io._buf + assert_equal $mrbtest_io_msg, io._read_buf + assert_equal $mrbtest_io_msg, io._buf + assert_equal 'mruby', io.read(5) + assert_equal 5, io.pos + assert_equal msg_len - 5, io._buf.size + assert_equal $mrbtest_io_msg[5,100], io.read + assert_equal 0, io._buf.size + assert_raise EOFError do + io._read_buf + end + assert_equal true, io.eof + assert_equal true, io.eof? + io.close + io.closed? +end + +assert('IO#pos=, IO#seek') do + fd = IO.sysopen $mrbtest_io_rfname + io = IO.new fd + def io._buf + @buf + end + assert_equal 'm', io.getc + assert_equal 1, io.pos + assert_equal 0, io.seek(0) + assert_equal 0, io.pos + io.close + io.closed? +end + +assert('IO#gets') do + fd = IO.sysopen $mrbtest_io_rfname + io = IO.new fd + + # gets without arguments + assert_equal $mrbtest_io_msg, io.gets, "gets without arguments" + assert_equal nil, io.gets, "gets returns nil, when EOF" + + # gets with limit + io.pos = 0 + assert_equal $mrbtest_io_msg[0, 5], io.gets(5), "gets with limit" + + # gets with rs + io.pos = 0 + assert_equal $mrbtest_io_msg[0, 6], io.gets(' '), "gets with rs" + + # gets with rs, limit + io.pos = 0 + assert_equal $mrbtest_io_msg[0, 5], io.gets(' ', 5), "gets with rs, limit" + io.close + assert_equal true, io.closed?, "close success" + + # reading many-lines file. + fd = IO.sysopen $mrbtest_io_wfname, "w" + io = IO.new fd, "w" + io.write "0123456789" * 2 + "\na" + assert_equal 22, io.pos + io.close + assert_equal true, io.closed? + + fd = IO.sysopen $mrbtest_io_wfname + io = IO.new fd + line = io.gets + + # gets first line + assert_equal "0123456789" * 2 + "\n", line, "gets first line" + assert_equal 21, line.size + assert_equal 21, io.pos + + # gets second line + assert_equal "a", io.gets, "gets second line" + + # gets third line + assert_equal nil, io.gets, "gets third line; returns nil" + + io.close + io.closed? +end + +assert('IO#gets - paragraph mode') do + fd = IO.sysopen $mrbtest_io_wfname, "w" + io = IO.new fd, "w" + io.write "0" * 10 + "\n" + io.write "1" * 10 + "\n\n" + io.write "2" * 10 + "\n" + assert_equal 34, io.pos + io.close + assert_equal true, io.closed? + + fd = IO.sysopen $mrbtest_io_wfname + io = IO.new fd + para1 = "#{'0' * 10}\n#{'1' * 10}\n\n" + text1 = io.gets("") + assert_equal para1, text1 + para2 = "#{'2' * 10}\n" + text2 = io.gets("") + assert_equal para2, text2 + io.close + io.closed? +end + +assert('IO.popen') do + io = IO.popen("ls") + assert_true io.close_on_exec? + assert_equal Fixnum, io.pid.class + ls = io.read + assert_equal ls.class, String + assert_include ls, 'AUTHORS' + assert_include ls, 'mrblib' + io.close + io.closed? +end + +assert('IO.read') do + # empty file + fd = IO.sysopen $mrbtest_io_wfname, "w" + io = IO.new fd, "w" + io.close + assert_equal "", IO.read($mrbtest_io_wfname) + assert_equal nil, IO.read($mrbtest_io_wfname, 1) + + # one byte file + fd = IO.sysopen $mrbtest_io_wfname, "w" + io = IO.new fd, "w" + io.write "123" + io.close + assert_equal "123", IO.read($mrbtest_io_wfname) + assert_equal "", IO.read($mrbtest_io_wfname, 0) + assert_equal "1", IO.read($mrbtest_io_wfname, 1) + assert_equal "", IO.read($mrbtest_io_wfname, 0, 10) + assert_equal "23", IO.read($mrbtest_io_wfname, 2, 1) + assert_equal "23", IO.read($mrbtest_io_wfname, 10, 1) + assert_equal "", IO.read($mrbtest_io_wfname, nil, 10) + assert_equal nil, IO.read($mrbtest_io_wfname, 1, 10) +end + +assert('IO#fileno') do + fd = IO.sysopen $mrbtest_io_rfname + io = IO.new fd + assert_equal io.fileno, fd + assert_equal io.to_i, fd + io.close + io.closed? +end + +assert('IO#close_on_exec') do + fd = IO.sysopen $mrbtest_io_wfname, "w" + io = IO.new fd, "w" + begin + # IO.sysopen opens a file descripter with O_CLOEXEC flag. + assert_true io.close_on_exec? + rescue ScriptError + skip "IO\#close_on_exec is not implemented." + end + + io.close_on_exec = false + assert_equal(false, io.close_on_exec?) + io.close_on_exec = true + assert_equal(true, io.close_on_exec?) + io.close_on_exec = false + assert_equal(false, io.close_on_exec?) + + io.close + io.closed? + + # # Use below when IO.pipe is implemented. + # begin + # r, w = IO.pipe + # assert_equal(false, r.close_on_exec?) + # r.close_on_exec = true + # assert_equal(true, r.close_on_exec?) + # r.close_on_exec = false + # assert_equal(false, r.close_on_exec?) + # r.close_on_exec = true + # assert_equal(true, r.close_on_exec?) + + # assert_equal(false, w.close_on_exec?) + # w.close_on_exec = true + # assert_equal(true, w.close_on_exec?) + # w.close_on_exec = false + # assert_equal(false, w.close_on_exec?) + # w.close_on_exec = true + # assert_equal(true, w.close_on_exec?) + # ensure + # r.close unless r.closed? + # w.close unless w.closed? + # end +end + +assert('`cmd`') do + assert_equal `echo foo`, "foo\n" +end + +assert('IO TEST CLEANUP') do + assert_nil MRubyIOTestUtil.io_test_cleanup +end diff --git a/web/server/h2o/libh2o/deps/mruby-io/test/mruby_io_test.c b/web/server/h2o/libh2o/deps/mruby-io/test/mruby_io_test.c new file mode 100644 index 00000000..f58f9ff8 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby-io/test/mruby_io_test.c @@ -0,0 +1,141 @@ +#include +#include +#include +#include +#include +#include +#include + +#include "mruby.h" +#include "mruby/array.h" +#include "mruby/string.h" +#include "mruby/variable.h" + +static mrb_value +mrb_io_test_io_setup(mrb_state *mrb, mrb_value self) +{ + char rfname[] = "tmp.mruby-io-test.XXXXXXXX"; + char wfname[] = "tmp.mruby-io-test.XXXXXXXX"; + char symlinkname[] = "tmp.mruby-io-test.XXXXXXXX"; + char socketname[] = "tmp.mruby-io-test.XXXXXXXX"; + char msg[] = "mruby io test\n"; + mode_t mask; + int fd0, fd1, fd2, fd3; + FILE *fp; + struct sockaddr_un sun0; + + mask = umask(077); + fd0 = mkstemp(rfname); + fd1 = mkstemp(wfname); + fd2 = mkstemp(symlinkname); + fd3 = mkstemp(socketname); + if (fd0 == -1 || fd1 == -1 || fd2 == -1 || fd3 == -1) { + mrb_raise(mrb, E_RUNTIME_ERROR, "can't create temporary file"); + return mrb_nil_value(); + } + umask(mask); + + mrb_gv_set(mrb, mrb_intern_cstr(mrb, "$mrbtest_io_rfname"), mrb_str_new_cstr(mrb, rfname)); + mrb_gv_set(mrb, mrb_intern_cstr(mrb, "$mrbtest_io_wfname"), mrb_str_new_cstr(mrb, wfname)); + mrb_gv_set(mrb, mrb_intern_cstr(mrb, "$mrbtest_io_symlinkname"), mrb_str_new_cstr(mrb, symlinkname)); + mrb_gv_set(mrb, mrb_intern_cstr(mrb, "$mrbtest_io_socketname"), mrb_str_new_cstr(mrb, socketname)); + mrb_gv_set(mrb, mrb_intern_cstr(mrb, "$mrbtest_io_msg"), mrb_str_new_cstr(mrb, msg)); + + fp = fopen(rfname, "w"); + if (fp == NULL) { + mrb_raise(mrb, E_RUNTIME_ERROR, "can't open temporary file"); + return mrb_nil_value(); + } + fputs(msg, fp); + fclose(fp); + + fp = fopen(wfname, "w"); + if (fp == NULL) { + mrb_raise(mrb, E_RUNTIME_ERROR, "can't open temporary file"); + return mrb_nil_value(); + } + fclose(fp); + + unlink(symlinkname); + close(fd2); + if (symlink("hoge", symlinkname) == -1) { + mrb_raise(mrb, E_RUNTIME_ERROR, "can't make a symbolic link"); + } + + unlink(socketname); + close(fd3); + fd3 = socket(AF_UNIX, SOCK_STREAM, 0); + if (fd3 == -1) { + mrb_raise(mrb, E_RUNTIME_ERROR, "can't make a socket"); + } + sun0.sun_family = AF_UNIX; + snprintf(sun0.sun_path, sizeof(sun0.sun_path), "%s", socketname); + if (bind(fd3, (struct sockaddr *)&sun0, sizeof(sun0)) == -1) { + mrb_raise(mrb, E_RUNTIME_ERROR, "can't make a socket bi"); + } + close(fd3); + + return mrb_true_value(); +} + +static mrb_value +mrb_io_test_io_cleanup(mrb_state *mrb, mrb_value self) +{ + mrb_value rfname = mrb_gv_get(mrb, mrb_intern_cstr(mrb, "$mrbtest_io_rfname")); + mrb_value wfname = mrb_gv_get(mrb, mrb_intern_cstr(mrb, "$mrbtest_io_wfname")); + mrb_value symlinkname = mrb_gv_get(mrb, mrb_intern_cstr(mrb, "$mrbtest_io_symlinkname")); + mrb_value socketname = mrb_gv_get(mrb, mrb_intern_cstr(mrb, "$mrbtest_io_socketname")); + + if (mrb_type(rfname) == MRB_TT_STRING) { + remove(RSTRING_PTR(rfname)); + } + if (mrb_type(wfname) == MRB_TT_STRING) { + remove(RSTRING_PTR(wfname)); + } + if (mrb_type(symlinkname) == MRB_TT_STRING) { + remove(RSTRING_PTR(symlinkname)); + } + if (mrb_type(socketname) == MRB_TT_STRING) { + remove(RSTRING_PTR(socketname)); + } + + mrb_gv_set(mrb, mrb_intern_cstr(mrb, "$mrbtest_io_rfname"), mrb_nil_value()); + mrb_gv_set(mrb, mrb_intern_cstr(mrb, "$mrbtest_io_wfname"), mrb_nil_value()); + mrb_gv_set(mrb, mrb_intern_cstr(mrb, "$mrbtest_io_symlinkname"), mrb_nil_value()); + mrb_gv_set(mrb, mrb_intern_cstr(mrb, "$mrbtest_io_socketname"), mrb_nil_value()); + mrb_gv_set(mrb, mrb_intern_cstr(mrb, "$mrbtest_io_msg"), mrb_nil_value()); + + return mrb_nil_value(); +} + +static mrb_value +mrb_io_test_file_setup(mrb_state *mrb, mrb_value self) +{ + mrb_value ary = mrb_io_test_io_setup(mrb, self); + if (symlink("/usr/bin", "test-bin") == -1) { + mrb_raise(mrb, E_RUNTIME_ERROR, "can't make a symbolic link"); + } + + return ary; +} + +static mrb_value +mrb_io_test_file_cleanup(mrb_state *mrb, mrb_value self) +{ + mrb_io_test_io_cleanup(mrb, self); + remove("test-bin"); + + return mrb_nil_value(); +} + +void +mrb_mruby_io_gem_test(mrb_state* mrb) +{ + struct RClass *io_test = mrb_define_module(mrb, "MRubyIOTestUtil"); + mrb_define_class_method(mrb, io_test, "io_test_setup", mrb_io_test_io_setup, MRB_ARGS_NONE()); + mrb_define_class_method(mrb, io_test, "io_test_cleanup", mrb_io_test_io_cleanup, MRB_ARGS_NONE()); + + mrb_define_class_method(mrb, io_test, "file_test_setup", mrb_io_test_file_setup, MRB_ARGS_NONE()); + mrb_define_class_method(mrb, io_test, "file_test_cleanup", mrb_io_test_file_cleanup, MRB_ARGS_NONE()); + +} diff --git a/web/server/h2o/libh2o/deps/mruby-onig-regexp/.travis.yml b/web/server/h2o/libh2o/deps/mruby-onig-regexp/.travis.yml new file mode 100644 index 00000000..5a0d1ddf --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby-onig-regexp/.travis.yml @@ -0,0 +1,10 @@ +sudo: false +addons: + apt: + packages: + - gperf +script: + - export MRUBY_CONFIG="$TRAVIS_BUILD_DIR/.travis_config.rb" + - git clone --depth 1 "https://github.com/mruby/mruby.git" + - cd mruby + - ./minirake all test diff --git a/web/server/h2o/libh2o/deps/mruby-onig-regexp/.travis_config.rb b/web/server/h2o/libh2o/deps/mruby-onig-regexp/.travis_config.rb new file mode 100644 index 00000000..769446c4 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby-onig-regexp/.travis_config.rb @@ -0,0 +1,21 @@ +MRuby::Build.new do |conf| + toolchain :gcc + enable_debug + enable_test + + gem :core => 'mruby-print' + gem :core => 'mruby-sprintf' + gem "#{MRUBY_ROOT}/.." +end + +MRuby::Build.new("onigmo-bundled") do |conf| + toolchain :gcc + enable_debug + enable_test + + gem :core => 'mruby-print' + gem :core => 'mruby-sprintf' + gem "#{MRUBY_ROOT}/.." do |g| + g.bundle_onigmo + end +end diff --git a/web/server/h2o/libh2o/deps/mruby-onig-regexp/Onigmo-6.1.1.tar.gz b/web/server/h2o/libh2o/deps/mruby-onig-regexp/Onigmo-6.1.1.tar.gz new file mode 100644 index 00000000..13922658 Binary files /dev/null and b/web/server/h2o/libh2o/deps/mruby-onig-regexp/Onigmo-6.1.1.tar.gz differ diff --git a/web/server/h2o/libh2o/deps/mruby-onig-regexp/README.md b/web/server/h2o/libh2o/deps/mruby-onig-regexp/README.md new file mode 100644 index 00000000..41eada48 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby-onig-regexp/README.md @@ -0,0 +1,45 @@ +# mruby-onig-regexp + +[![Build Status](https://travis-ci.org/mattn/mruby-onig-regexp.svg)](https://travis-ci.org/mattn/mruby-onig-regexp) + +## install by mrbgems +```ruby +MRuby::Build.new do |conf| + + # ... (snip) ... + + conf.gem :github => 'mattn/mruby-onig-regexp' +end +``` + +## Example +```ruby + +def matchstr(str) + reg = Regexp.compile("abc") + + if reg =~ str then + p "match" + else + p "not match" + end +end + +matchstr("abcdef") # => match +matchstr("ghijkl") # => not match +matchstr("xyzabc") # => match +``` + +## License + +MIT + +### License of Onigmo +BSD licensed. + + Onigmo (Oniguruma-mod) -- (C) K.Takata + Oniguruma ---- (C) K.Kosako + +## Author + +Yasuhiro Matsumoto (a.k.a mattn) diff --git a/web/server/h2o/libh2o/deps/mruby-onig-regexp/mrbgem.rake b/web/server/h2o/libh2o/deps/mruby-onig-regexp/mrbgem.rake new file mode 100644 index 00000000..67998670 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby-onig-regexp/mrbgem.rake @@ -0,0 +1,113 @@ +MRuby::Gem::Specification.new('mruby-onig-regexp') do |spec| + spec.license = 'MIT' + spec.authors = 'mattn' + + def spec.bundle_onigmo + return if @onigmo_bundled + @onigmo_bundled = true + + visualcpp = ENV['VisualStudioVersion'] || ENV['VSINSTALLDIR'] + + require 'open3' + + # remove libonig, instead link directly against pthread + unless ENV['OS'] == 'Windows_NT' + linker.libraries = ['pthread'] + end + + version = '6.1.1' + oniguruma_dir = "#{build_dir}/onigmo-#{version}" + oniguruma_lib = libfile "#{oniguruma_dir}/.libs/libonigmo" + unless ENV['OS'] == 'Windows_NT' + oniguruma_lib = libfile "#{oniguruma_dir}/.libs/libonigmo" + else + if ENV['PROCESSOR_ARCHITECTURE'] == 'AMD64' + oniguruma_lib = libfile "#{oniguruma_dir}/build-x86-64/onigmo" + else + oniguruma_lib = libfile "#{oniguruma_dir}/build-i686/onigmo" + end + end + header = "#{oniguruma_dir}/onigmo.h" + + task :clean do + FileUtils.rm_rf [oniguruma_dir] + end + + file header do |t| + FileUtils.mkdir_p oniguruma_dir + Dir.chdir(build_dir) do + _pp 'extracting', "Onigmo-#{version}" + `gzip -dc "#{dir}/Onigmo-#{version}.tar.gz" | tar xf -` + end + end + + def run_command(env, command) + STDOUT.sync = true + Open3.popen2e(env, command) do |stdin, stdout, thread| + print stdout.read + fail "#{command} failed" if thread.value != 0 + end + end + + libonig_objs_dir = "#{oniguruma_dir}/libonig_objs" + libmruby_a = libfile("#{build.build_dir}/lib/libmruby") + objext = visualcpp ? '.obj' : '.o' + + file oniguruma_lib => header do |t| + Dir.chdir(oniguruma_dir) do + e = { + 'CC' => "#{build.cc.command} #{build.cc.flags.join(' ')}", + 'CXX' => "#{build.cxx.command} #{build.cxx.flags.join(' ')}", + 'LD' => "#{build.linker.command} #{build.linker.flags.join(' ')}", + 'AR' => build.archiver.command } + unless ENV['OS'] == 'Windows_NT' + if build.kind_of? MRuby::CrossBuild + host = "--host #{build.name}" + end + + _pp 'autotools', oniguruma_dir + run_command e, './autogen.sh' if File.exists? 'autogen.sh' + run_command e, "./configure --disable-shared --enable-static #{host}" + run_command e, 'make' + else + run_command e, 'cmd /c "copy /Y win32 > NUL"' + if visualcpp + run_command e, 'nmake -f Makefile' + else + run_command e, 'make -f Makefile.mingw' + end + end + end + + FileUtils.mkdir_p libonig_objs_dir + Dir.chdir(libonig_objs_dir) do + unless visualcpp + `ar x #{oniguruma_lib}` + else + winname = oniguruma_lib.gsub(%'/', '\\') + `lib -nologo -list #{winname}`.each_line do |line| + line.chomp! + `lib -nologo -extract:#{line} #{winname}` + end + end + end + file libmruby_a => Dir.glob("#{libonig_objs_dir}/*#{objext}") + end + + file libmruby_a => Dir.glob("#{libonig_objs_dir}/*#{objext}") if File.exists? oniguruma_lib + + file "#{dir}/src/mruby_onig_regexp.c" => oniguruma_lib + cc.include_paths << oniguruma_dir + cc.defines += ['HAVE_ONIGMO_H'] + end + + if spec.respond_to? :search_package and spec.search_package 'onigmo' + spec.cc.defines += ['HAVE_ONIGMO_H'] + elsif spec.respond_to? :search_package and spec.search_package 'oniguruma' + spec.cc.defines += ['HAVE_ONIGURUMA_H'] + elsif build.cc.respond_to? :search_header_path and build.cc.search_header_path 'oniguruma.h' + spec.linker.libraries << 'onig' + else + spec.bundle_onigmo + end +end diff --git a/web/server/h2o/libh2o/deps/mruby-onig-regexp/mrblib/onig_regexp.rb b/web/server/h2o/libh2o/deps/mruby-onig-regexp/mrblib/onig_regexp.rb new file mode 100644 index 00000000..2dc8d55e --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby-onig-regexp/mrblib/onig_regexp.rb @@ -0,0 +1,140 @@ +class OnigRegexp + @memo = {} + + # ISO 15.2.15.6.1 + def self.compile(*args) + as = args.to_s + unless @memo.key? as + @memo[as] = self.new(*args) + end + @memo[as] + end + + # ISO 15.2.15.6.3 + def self.last_match + @last_match + end + + # ISO 15.2.15.7.2 + def initialize_copy(other) + initialize(other.source, other.options) + end + + # ISO 15.2.15.7.4 + def ===(str) + not self.match(str).nil? + end + + # ISO 15.2.15.7.5 + def =~(str) + m = self.match(str) + m ? m.begin(0) : nil + end + + # ISO 15.2.15.7.8 + attr_reader :source +end + +class String + # ISO 15.2.10.5.5 + def =~(a) + begin + (a.class.to_s == 'String' ? Regexp.new(a.to_s) : a) =~ self + rescue + false + end + end + + # redefine methods with oniguruma regexp version + [:sub, :gsub, :split, :scan].each do |v| + alias_method "string_#{v}".to_sym, v + alias_method v, "onig_regexp_#{v}".to_sym + end + + alias_method :old_slice, :slice + alias_method :old_square_brancket, :[] + + def [](*args) + return old_square_brancket(*args) unless args[0].class == Regexp + + if args.size == 2 + match = args[0].match(self) + if match + if args[1] == 0 + str = match[0] + else + str = match.captures[args[1] - 1] + end + return str + end + end + + match_data = args[0].match(self) + if match_data + result = match_data.to_s + return result + end + end + + alias_method :slice, :[] + + def slice!(*args) + if args.size < 2 + result = slice(*args) + nth = args[0] + + if nth.class == Regexp + lm = Regexp.last_match + self[nth] = '' if result + Regexp.last_match = lm + else + self[nth] = '' if result + end + else + result = slice(*args) + + nth = args[0] + len = args[1] + + if nth.class == Regexp + lm = Regexp.last_match + self[nth, len] = '' if result + Regexp.last_match = lm + else + self[nth, len] = '' if result && nth != self.size + end + end + + result + end + + alias_method :old_index, :index + + def index(pattern, pos=0) + if pattern.class == Regexp + str = self[pos..-1] + if str + if num = (pattern =~ str) + if pos < 0 + num += self.size + end + return num + pos + end + end + nil + else + self.old_index(pattern, pos) + end + end +end + +module Kernel + def =~(_) + nil + end +end + +Regexp = OnigRegexp unless Object.const_defined?(:Regexp) +MatchData = OnigMatchData unless Object.const_defined? :MatchData + +# This is based on https://github.com/masamitsu-murase/mruby-hs-regexp diff --git a/web/server/h2o/libh2o/deps/mruby-onig-regexp/src/mruby_onig_regexp.c b/web/server/h2o/libh2o/deps/mruby-onig-regexp/src/mruby_onig_regexp.c new file mode 100644 index 00000000..38d93ccb --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby-onig-regexp/src/mruby_onig_regexp.c @@ -0,0 +1,1064 @@ +/* +The MIT License (MIT) + +Copyright (c) 2015 mattn. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +*/ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef _MSC_VER +#define ONIG_EXTERN extern +#endif +#ifdef HAVE_ONIGMO_H +#include +#elif defined(HAVE_ONIGURUMA_H) +#include +#else +#include "oniguruma.h" +#endif + +#ifdef MRUBY_VERSION +#define mrb_args_int mrb_int +#else +#define mrb_args_int int +#endif + +static const char utf8len_codepage[256] = +{ + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, + 3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,1,1,1,1,1,1,1,1,1,1,1, +}; + +static mrb_int +utf8len(const char* p, const char* e) +{ + mrb_int len; + mrb_int i; + + len = utf8len_codepage[(unsigned char)*p]; + if (p + len > e) return 1; + for (i = 1; i < len; ++i) + if ((p[i] & 0xc0) != 0x80) + return 1; + return len; +} + +static void +onig_regexp_free(mrb_state *mrb, void *p) { + onig_free((OnigRegex) p); +} + +static struct mrb_data_type mrb_onig_regexp_type = { + "PosixRegexp", onig_regexp_free +}; + +static void +match_data_free(mrb_state* mrb, void* p) { + (void)mrb; + onig_region_free((OnigRegion*)p, 1); +} + +static struct mrb_data_type mrb_onig_region_type = { + "OnigRegion", match_data_free +}; + +static mrb_value +onig_regexp_initialize(mrb_state *mrb, mrb_value self) { + mrb_value str, flag = mrb_nil_value(), code = mrb_nil_value(); + mrb_get_args(mrb, "S|oo", &str, &flag, &code); + + int cflag = 0; + OnigEncoding enc = ONIG_ENCODING_UTF8; + if(mrb_string_p(code)) { + char const* str_code = mrb_string_value_ptr(mrb, code); + if(strchr(str_code, 'n') || strchr(str_code, 'N')) { + enc = ONIG_ENCODING_ASCII; + } + } + if(mrb_nil_p(flag)) { + } else if(mrb_type(flag) == MRB_TT_TRUE) { + cflag |= ONIG_OPTION_IGNORECASE; + } else if(mrb_fixnum_p(flag)) { + int int_flags = mrb_fixnum(flag); + if(int_flags & 0x1) { cflag |= ONIG_OPTION_IGNORECASE; } + if(int_flags & 0x2) { cflag |= ONIG_OPTION_EXTEND; } + if(int_flags & 0x4) { cflag |= ONIG_OPTION_MULTILINE; } + } else if(mrb_string_p(flag)) { + char const* str_flags = mrb_string_value_ptr(mrb, flag); + if(strchr(str_flags, 'i')) { cflag |= ONIG_OPTION_IGNORECASE; } + if(strchr(str_flags, 'x')) { cflag |= ONIG_OPTION_EXTEND; } + if(strchr(str_flags, 'm')) { cflag |= ONIG_OPTION_MULTILINE; } + } else { + mrb_raisef(mrb, E_ARGUMENT_ERROR, "unknown regexp flag: %S", flag); + } + + OnigErrorInfo einfo; + OnigRegex reg; + int result = onig_new(®, (OnigUChar*)RSTRING_PTR(str), (OnigUChar*) RSTRING_PTR(str) + RSTRING_LEN(str), + cflag, enc, ONIG_SYNTAX_RUBY, &einfo); + if (result != ONIG_NORMAL) { + char err[ONIG_MAX_ERROR_MESSAGE_LEN] = ""; + onig_error_code_to_str((OnigUChar*)err, result); + mrb_raisef(mrb, E_ARGUMENT_ERROR, "'%S' is an invalid regular expression because %S.", + str, mrb_str_new_cstr(mrb, err)); + } + mrb_iv_set(mrb, self, mrb_intern_lit(mrb, "@source"), str); + + DATA_PTR(self) = reg; + DATA_TYPE(self) = &mrb_onig_regexp_type; + + return self; +} + +static mrb_value +create_onig_region(mrb_state* mrb, mrb_value const str, mrb_value rex) { + mrb_assert(mrb_string_p(str)); + mrb_assert(mrb_type(rex) == MRB_TT_DATA && DATA_TYPE(rex) == &mrb_onig_regexp_type); + mrb_value const c = mrb_obj_value(mrb_data_object_alloc( + mrb, mrb_class_get(mrb, "OnigMatchData"), onig_region_new(), &mrb_onig_region_type)); + mrb_iv_set(mrb, c, mrb_intern_lit(mrb, "string"), mrb_str_dup(mrb, str)); + mrb_iv_set(mrb, c, mrb_intern_lit(mrb, "regexp"), rex); + return c; +} + +static int +onig_match_common(mrb_state* mrb, OnigRegex reg, mrb_value match_value, mrb_value str, int pos) { + mrb_assert(mrb_string_p(str)); + mrb_assert(DATA_TYPE(match_value) == &mrb_onig_region_type); + OnigRegion* const match = (OnigRegion*)DATA_PTR(match_value); + OnigUChar const* str_ptr = (OnigUChar const*)RSTRING_PTR(str); + int const result = onig_search(reg, str_ptr, str_ptr + RSTRING_LEN(str), + str_ptr + pos, str_ptr + RSTRING_LEN(str), match, 0); + if (result != ONIG_MISMATCH && result < 0) { + char err[ONIG_MAX_ERROR_MESSAGE_LEN] = ""; + onig_error_code_to_str((OnigUChar*)err, result); + mrb_raise(mrb, E_REGEXP_ERROR, err); + } + + struct RObject* const cls = (struct RObject*)mrb_class_get(mrb, "OnigRegexp"); + mrb_obj_iv_set(mrb, cls, mrb_intern_lit(mrb, "@last_match"), match_value); + + if (result != ONIG_MISMATCH && + mrb_class_get(mrb, "Regexp") == (struct RClass*)cls && + mrb_bool(mrb_obj_iv_get(mrb, (struct RObject*)cls, mrb_intern_lit(mrb, "@set_global_variables")))) + { + mrb_gv_set(mrb, mrb_intern_lit(mrb, "$~"), match_value); + mrb_gv_set(mrb, mrb_intern_lit(mrb, "$&"), + mrb_funcall(mrb, match_value, "[]", 1, mrb_fixnum_value(0))); + mrb_gv_set(mrb, mrb_intern_lit(mrb, "$`"), mrb_funcall(mrb, match_value, "pre_match", 0)); + mrb_gv_set(mrb, mrb_intern_lit(mrb, "$'"), mrb_funcall(mrb, match_value, "post_match", 0)); + mrb_gv_set(mrb, mrb_intern_lit(mrb, "$+"), + mrb_funcall(mrb, match_value, "[]", 1, mrb_fixnum_value(match->num_regs - 1))); + + // $1 to $9 + int idx = 1; + int const idx_max = match->num_regs > 10? 10 : match->num_regs; + for(; idx < idx_max; ++idx) { + char const n[] = { '$', '0' + idx }; + mrb_gv_set(mrb, mrb_intern(mrb, n, 2), + mrb_funcall(mrb, match_value, "[]", 1, mrb_fixnum_value(idx))); + } + + for(; idx < 10; ++idx) { + char const n[] = { '$', '0' + idx }; + mrb_gv_remove(mrb, mrb_intern(mrb, n, 2)); + } + } + + return result; +} + +static mrb_value +onig_regexp_match(mrb_state *mrb, mrb_value self) { + mrb_value str = mrb_nil_value(); + OnigRegex reg; + mrb_int pos = 0; + + mrb_get_args(mrb, "o|i", &str, &pos); + if (pos < 0 || (pos > 0 && pos >= RSTRING_LEN(str))) { + return mrb_nil_value(); + } + + if (mrb_nil_p(str)) { + return mrb_nil_value(); + } + str = mrb_string_type(mrb, str); + + Data_Get_Struct(mrb, self, &mrb_onig_regexp_type, reg); + + mrb_value const ret = create_onig_region(mrb, str, self); + return (onig_match_common(mrb, reg, ret, str, pos) == ONIG_MISMATCH) + ? mrb_nil_value() : ret; +} + +static mrb_value +onig_regexp_equal(mrb_state *mrb, mrb_value self) { + mrb_value other; + OnigRegex self_reg, other_reg; + + mrb_get_args(mrb, "o", &other); + if (mrb_obj_equal(mrb, self, other)){ + return mrb_true_value(); + } + if (mrb_nil_p(other)) { + return mrb_false_value(); + } + if (!mrb_obj_is_kind_of(mrb, other, mrb_class_get(mrb, "OnigRegexp"))) { + return mrb_false_value(); + } + Data_Get_Struct(mrb, self, &mrb_onig_regexp_type, self_reg); + Data_Get_Struct(mrb, other, &mrb_onig_regexp_type, other_reg); + + if (!self_reg || !other_reg){ + mrb_raise(mrb, E_RUNTIME_ERROR, "Invalid OnigRegexp"); + } + if (onig_get_options(self_reg) != onig_get_options(other_reg)){ + return mrb_false_value(); + } + return mrb_str_equal(mrb, mrb_iv_get(mrb, self, mrb_intern_lit(mrb, "@source")), mrb_iv_get(mrb, other, mrb_intern_lit(mrb, "@source"))) ? + mrb_true_value() : mrb_false_value(); +} + +static mrb_value +onig_regexp_casefold_p(mrb_state *mrb, mrb_value self) { + OnigRegex reg; + + Data_Get_Struct(mrb, self, &mrb_onig_regexp_type, reg); + return (onig_get_options(reg) & ONIG_OPTION_IGNORECASE) ? mrb_true_value() : mrb_false_value(); +} + +static mrb_value +onig_regexp_options(mrb_state *mrb, mrb_value self) { + OnigRegex reg; + Data_Get_Struct(mrb, self, &mrb_onig_regexp_type, reg); + return mrb_fixnum_value(onig_get_options(reg)); +} + +static char * +option_to_str(char str[4], int options) { + char *p = str; + if (options & ONIG_OPTION_MULTILINE) *p++ = 'm'; + if (options & ONIG_OPTION_IGNORECASE) *p++ = 'i'; + if (options & ONIG_OPTION_EXTEND) *p++ = 'x'; + *p = 0; + return str; +} + +static mrb_value +regexp_expr_str(mrb_state *mrb, mrb_value str, const char *p, int len) { + const char *pend; + char buf[5]; + + pend = (const char *) p + len; + for (;p < pend; p++) { + unsigned char c, cc; + + c = *p; + if (c == '/'|| c == '\\') { + buf[0] = '\\'; buf[1] = c; + mrb_str_cat(mrb, str, buf, 2); + continue; + } + if (ISPRINT(c)) { + buf[0] = c; + mrb_str_cat(mrb, str, buf, 1); + continue; + } + switch (c) { + case '\n': cc = 'n'; break; + case '\r': cc = 'r'; break; + case '\t': cc = 't'; break; + default: cc = 0; break; + } + if (cc) { + buf[0] = '\\'; + buf[1] = (char)cc; + mrb_str_cat(mrb, str, buf, 2); + continue; + } + else { + buf[0] = '\\'; + buf[3] = '0' + c % 8; c /= 8; + buf[2] = '0' + c % 8; c /= 8; + buf[1] = '0' + c % 8; + mrb_str_cat(mrb, str, buf, 4); + continue; + } + } + return str; +} + +static mrb_value +onig_regexp_inspect(mrb_state *mrb, mrb_value self) { + OnigRegex reg; + Data_Get_Struct(mrb, self, &mrb_onig_regexp_type, reg); + mrb_value str = mrb_str_new_lit(mrb, "/"); + mrb_value src = mrb_iv_get(mrb, self, mrb_intern_lit(mrb, "@source")); + regexp_expr_str(mrb, str, (const char *)RSTRING_PTR(src), RSTRING_LEN(src)); + mrb_str_cat_lit(mrb, str, "/"); + char opts[4]; + if (*option_to_str(opts, onig_get_options(reg))) { + mrb_str_cat_cstr(mrb, str, opts); + } + if (onig_get_encoding(reg) == ONIG_ENCODING_ASCII) { + mrb_str_cat_lit(mrb, str, "n"); + } + return str; +} + +static mrb_value +onig_regexp_to_s(mrb_state *mrb, mrb_value self) { + int options; + const int embeddable = ONIG_OPTION_MULTILINE|ONIG_OPTION_IGNORECASE|ONIG_OPTION_EXTEND; + long len; + const char* ptr; + mrb_value str = mrb_str_new_lit(mrb, "(?"); + char optbuf[5]; + + OnigRegex reg; + Data_Get_Struct(mrb, self, &mrb_onig_regexp_type, reg); + options = onig_get_options(reg); + mrb_value src = mrb_iv_get(mrb, self, mrb_intern_lit(mrb, "@source")); + ptr = RSTRING_PTR(src); + len = RSTRING_LEN(src); + + again: + if (len >= 4 && ptr[0] == '(' && ptr[1] == '?') { + int err = 1; + ptr += 2; + if ((len -= 2) > 0) { + do { + if(strchr(ptr, 'i')) { options |= ONIG_OPTION_IGNORECASE; } + if(strchr(ptr, 'x')) { options |= ONIG_OPTION_EXTEND; } + if(strchr(ptr, 'm')) { options |= ONIG_OPTION_MULTILINE; } + ++ptr; + } while (--len > 0); + } + if (len > 1 && *ptr == '-') { + ++ptr; + --len; + do { + if(strchr(ptr, 'i')) { options &= ~ONIG_OPTION_IGNORECASE; } + if(strchr(ptr, 'x')) { options &= ~ONIG_OPTION_EXTEND; } + if(strchr(ptr, 'm')) { options &= ~ONIG_OPTION_MULTILINE; } + ++ptr; + } while (--len > 0); + } + if (*ptr == ')') { + --len; + ++ptr; + goto again; + } + if (*ptr == ':' && ptr[len-1] == ')') { + OnigRegex rp; + ++ptr; + len -= 2; + err = onig_new(&rp, (OnigUChar*)ptr, (OnigUChar*)ptr + len, ONIG_OPTION_DEFAULT, + ONIG_ENCODING_UTF8, OnigDefaultSyntax, NULL); + onig_free(rp); + } + if (err) { + options = onig_get_options(reg); + ptr = RSTRING_PTR(src); + len = RSTRING_LEN(src); + } + } + + if (*option_to_str(optbuf, options)) mrb_str_cat_cstr(mrb, str, optbuf); + + if ((options & embeddable) != embeddable) { + optbuf[0] = '-'; + option_to_str(optbuf + 1, ~options); + mrb_str_cat_cstr(mrb, str, optbuf); + } + + mrb_str_cat_cstr(mrb, str, ":"); + regexp_expr_str(mrb, str, ptr, len); + mrb_str_cat_cstr(mrb, str, ")"); + return str; +} + + +static mrb_value +onig_regexp_version(mrb_state* mrb, mrb_value self) { + (void)self; + return mrb_str_new_cstr(mrb, onig_version()); +} + +static mrb_value +match_data_to_a(mrb_state* mrb, mrb_value self); + +static mrb_int +match_data_actual_index(mrb_state* mrb, mrb_value self, mrb_value idx_value) { + if(mrb_fixnum_p(idx_value)) { return mrb_fixnum(idx_value); } + + char const* name = NULL; + char const* name_end = NULL; + if(mrb_symbol_p(idx_value)) { + mrb_int sym_len; + name = mrb_sym2name_len(mrb, mrb_symbol(idx_value), &sym_len); + name_end = name + sym_len; + } else if(mrb_string_p(idx_value)) { + name = mrb_string_value_ptr(mrb, idx_value); + name_end = name + strlen(name); + } else { mrb_assert(FALSE); } + mrb_assert(name && name_end); + + mrb_value const regexp = mrb_iv_get(mrb, self, mrb_intern_lit(mrb, "regexp")); + mrb_assert(!mrb_nil_p(regexp)); + mrb_assert(DATA_TYPE(regexp) == &mrb_onig_regexp_type); + mrb_assert(DATA_TYPE(self) == &mrb_onig_region_type); + int const idx = onig_name_to_backref_number( + (OnigRegex)DATA_PTR(regexp), (OnigUChar const*)name, (OnigUChar const*)name_end, + (OnigRegion*)DATA_PTR(self)); + if (idx < 0) { + mrb_raisef(mrb, E_INDEX_ERROR, "undefined group name reference: %S", idx_value); + } + return idx; +} + +// ISO 15.2.16.3.1 +static mrb_value +match_data_index(mrb_state* mrb, mrb_value self) { + mrb_value src; + mrb_int argc; mrb_value *argv; + + mrb_get_args(mrb, "*", &argv, &argc); + + src = match_data_to_a(mrb, self); + + if (argc == 1) { + switch (mrb_type(argv[0])) { + case MRB_TT_FIXNUM: + case MRB_TT_SYMBOL: + case MRB_TT_STRING: + return mrb_ary_entry(src, match_data_actual_index(mrb, self, argv[0])); + default: break; + } + } + + return mrb_funcall_argv(mrb, src, mrb_intern_lit(mrb, "[]"), argc, argv); +} + +#define match_data_check_index(idx) \ + if(idx < 0 || reg->num_regs <= idx) \ + mrb_raisef(mrb, E_INDEX_ERROR, "index %S out of matches", mrb_fixnum_value(idx)) \ + +// ISO 15.2.16.3.2 +static mrb_value +match_data_begin(mrb_state* mrb, mrb_value self) { + mrb_value idx_value; + mrb_get_args(mrb, "o", &idx_value); + OnigRegion* reg; + Data_Get_Struct(mrb, self, &mrb_onig_region_type, reg); + mrb_int const idx = match_data_actual_index(mrb, self, idx_value); + match_data_check_index(idx); + return mrb_fixnum_value(reg->beg[idx]); +} + +// ISO 15.2.16.3.3 +static mrb_value +match_data_captures(mrb_state* mrb, mrb_value self) { + mrb_value ary = match_data_to_a(mrb, self); + return mrb_ary_new_from_values(mrb, RARRAY_LEN(ary) - 1, RARRAY_PTR(ary) + 1); +} + +// ISO 15.2.16.3.4 +static mrb_value +match_data_end(mrb_state* mrb, mrb_value self) { + mrb_value idx_value; + mrb_get_args(mrb, "o", &idx_value); + OnigRegion* reg; + Data_Get_Struct(mrb, self, &mrb_onig_region_type, reg); + mrb_int const idx = match_data_actual_index(mrb, self, idx_value); + match_data_check_index(idx); + return mrb_fixnum_value(reg->end[idx]); +} + +// ISO 15.2.16.3.5 +static mrb_value +match_data_copy(mrb_state* mrb, mrb_value self) { + mrb_value src_val; + mrb_get_args(mrb, "o", &src_val); + + OnigRegion* src; + Data_Get_Struct(mrb, src_val, &mrb_onig_region_type, src); + + OnigRegion* dst = onig_region_new(); + onig_region_copy(dst, src); + + DATA_PTR(self) = dst; + DATA_TYPE(self) = &mrb_onig_region_type; + mrb_iv_set(mrb, self, mrb_intern_lit(mrb, "string"), mrb_iv_get(mrb, src_val, mrb_intern_lit(mrb, "string"))); + mrb_iv_set(mrb, self, mrb_intern_lit(mrb, "regexp"), mrb_iv_get(mrb, src_val, mrb_intern_lit(mrb, "regexp"))); + return self; +} + +// ISO 15.2.16.3.6 +// ISO 15.2.16.3.10 +static mrb_value +match_data_length(mrb_state* mrb, mrb_value self) { + OnigRegion* reg; + Data_Get_Struct(mrb, self, &mrb_onig_region_type, reg); + return mrb_fixnum_value(reg->num_regs); +} + +// ISO 15.2.16.3.7 +static mrb_value +match_data_offset(mrb_state* mrb, mrb_value self) { + mrb_value idx_value; + mrb_get_args(mrb, "o", &idx_value); + OnigRegion* reg; + Data_Get_Struct(mrb, self, &mrb_onig_region_type, reg); + mrb_int const idx = match_data_actual_index(mrb, self, idx_value); + match_data_check_index(idx); + mrb_value ret = mrb_ary_new_capa(mrb, 2); + mrb_ary_push(mrb, ret, mrb_fixnum_value(reg->beg[idx])); + mrb_ary_push(mrb, ret, mrb_fixnum_value(reg->end[idx])); + return ret; +} + +// ISO 15.2.16.3.8 +static mrb_value +match_data_post_match(mrb_state* mrb, mrb_value self) { + OnigRegion* reg; + Data_Get_Struct(mrb, self, &mrb_onig_region_type, reg); + mrb_value str = mrb_iv_get(mrb, self, mrb_intern_lit(mrb, "string")); + return mrb_str_substr(mrb, str, reg->end[0], RSTRING_LEN(str) - reg->end[0]); +} + +// ISO 15.2.16.3.9 +static mrb_value +match_data_pre_match(mrb_state* mrb, mrb_value self) { + OnigRegion* reg; + Data_Get_Struct(mrb, self, &mrb_onig_region_type, reg); + mrb_value str = mrb_iv_get(mrb, self, mrb_intern_lit(mrb, "string")); + return mrb_str_substr(mrb, str, 0, reg->beg[0]); +} + +// ISO 15.2.16.3.11 +static mrb_value +match_data_string(mrb_state* mrb, mrb_value self) { + return mrb_iv_get(mrb, self, mrb_intern_lit(mrb, "string")); +} + +static mrb_value +match_data_regexp(mrb_state* mrb, mrb_value self) { + return mrb_iv_get(mrb, self, mrb_intern_lit(mrb, "regexp")); +} + +// ISO 15.2.16.3.12 +static mrb_value +match_data_to_a(mrb_state* mrb, mrb_value self) { + mrb_value cache = mrb_iv_get(mrb, self, mrb_intern_lit(mrb, "cache")); + if(!mrb_nil_p(cache)) { + return cache; + } + + mrb_value str = mrb_iv_get(mrb, self, mrb_intern_lit(mrb, "string")); + OnigRegion* reg; + Data_Get_Struct(mrb, self, &mrb_onig_region_type, reg); + + mrb_value ret = mrb_ary_new_capa(mrb, reg->num_regs); + int i, ai = mrb_gc_arena_save(mrb); + for(i = 0; i < reg->num_regs; ++i) { + if(reg->beg[i] == ONIG_REGION_NOTPOS) { + mrb_ary_push(mrb, ret, mrb_nil_value()); + } else { + mrb_ary_push(mrb, ret, mrb_str_substr(mrb, str, reg->beg[i], reg->end[i] - reg->beg[i])); + } + mrb_gc_arena_restore(mrb, ai); + } + return ret; +} + +// ISO 15.2.16.3.13 +static mrb_value +match_data_to_s(mrb_state* mrb, mrb_value self) { + mrb_value str = mrb_iv_get(mrb, self, mrb_intern_lit(mrb, "string")); + OnigRegion* reg; + Data_Get_Struct(mrb, self, &mrb_onig_region_type, reg); + return mrb_str_substr(mrb, str, reg->beg[0], reg->end[0] - reg->beg[0]); +} + +static void +append_replace_str(mrb_state* mrb, mrb_value result, mrb_value replace, + mrb_value src, OnigRegex reg, OnigRegion* match) +{ + mrb_assert(mrb_string_p(replace)); + char const* ch; + char const* const end = RSTRING_PTR(replace) + RSTRING_LEN(replace); + for(ch = RSTRING_PTR(replace); ch < end; ++ch) { + if (*ch != '\\' || (ch + 1) >= end) { + mrb_str_cat(mrb, result, ch, 1); + continue; + } + + switch(*(++ch)) { // skip back slash and get next char + case 'k': { // group name + if ((ch + 2) >= end || ch[1] != '<') { goto replace_expr_error; } + char const* name_beg = ch += 2; + while (*ch != '>') { if(++ch == end) { goto replace_expr_error; } } + mrb_assert(ch < end); + mrb_assert(*ch == '>'); + int const idx = onig_name_to_backref_number( + reg, (OnigUChar const*)name_beg, (OnigUChar const*)ch, match); + if (idx < 0) { + mrb_raisef(mrb, E_INDEX_ERROR, "undefined group name reference: %S", + mrb_str_substr(mrb, replace, name_beg - RSTRING_PTR(replace), ch - name_beg)); + } + mrb_str_cat(mrb, result, RSTRING_PTR(src) + match->beg[idx], match->end[idx] - match->beg[idx]); + } break; + + case '\\': // escaped back slash + mrb_str_cat(mrb, result, ch, 1); + break; + + default: + if (isdigit(*ch)) { // group number 0-9 + int const idx = *ch - '0'; + if (idx < match->num_regs) { + mrb_str_cat(mrb, result, RSTRING_PTR(src) + match->beg[idx], match->end[idx] - match->beg[idx]); + } + } else { + char const str[] = { '\\', *ch }; + mrb_str_cat(mrb, result, str, 2); + } + break; + } + } + + if(ch == end) { return; } + +replace_expr_error: + mrb_raisef(mrb, E_REGEXP_ERROR, "invalid replace expression: %S", replace); +} + +// ISO 15.2.10.5.18 +static mrb_value +string_gsub(mrb_state* mrb, mrb_value self) { + mrb_value blk, match_expr, replace_expr = mrb_nil_value(); + int const argc = mrb_get_args(mrb, "&o|S", &blk, &match_expr, &replace_expr); + + if(mrb_string_p(match_expr)) { + mrb_value argv[] = { match_expr, replace_expr }; + return mrb_funcall_with_block(mrb, self, mrb_intern_lit(mrb, "string_gsub"), argc, argv, blk); + } + + if(!mrb_nil_p(blk) && !mrb_nil_p(replace_expr)) { + blk = mrb_nil_value(); + } + + OnigRegex reg; + Data_Get_Struct(mrb, match_expr, &mrb_onig_regexp_type, reg); + mrb_value const result = mrb_str_new(mrb, NULL, 0); + mrb_value const match_value = create_onig_region(mrb, self, match_expr); + OnigRegion* const match = (OnigRegion*)DATA_PTR(match_value); + int last_end_pos = 0; + + while(1) { + if(onig_match_common(mrb, reg, match_value, self, last_end_pos) == ONIG_MISMATCH) { break; } + + mrb_str_cat(mrb, result, RSTRING_PTR(self) + last_end_pos, match->beg[0] - last_end_pos); + + if(mrb_nil_p(blk)) { + append_replace_str(mrb, result, replace_expr, self, reg, match); + } else { + mrb_value const tmp_str = mrb_str_to_str(mrb, mrb_yield(mrb, blk, mrb_str_substr( + mrb, self, match->beg[0], match->end[0] - match->beg[0]))); + mrb_assert(mrb_string_p(tmp_str)); + mrb_str_concat(mrb, result, tmp_str); + } + + last_end_pos = match->end[0]; + if (match->beg[0] == match->end[0]) { + /* + * Always consume at least one character of the input string + * in order to prevent infinite loops. + */ + char* p = RSTRING_PTR(self) + last_end_pos; + char* e = p + RSTRING_LEN(self); + int len = utf8len(p, e); + if (RSTRING_LEN(self) < last_end_pos + len) break; + mrb_str_cat(mrb, result, p, len); + last_end_pos += len; + } + } + + mrb_str_cat(mrb, result, RSTRING_PTR(self) + last_end_pos, RSTRING_LEN(self) - last_end_pos); + return result; +} + +// ISO 15.2.10.5.32 +static mrb_value +string_scan(mrb_state* mrb, mrb_value self) { + mrb_value blk, match_expr; + mrb_get_args(mrb, "&o", &blk, &match_expr); + + if(mrb_string_p(match_expr)) { + return mrb_funcall_with_block(mrb, self, mrb_intern_lit(mrb, "string_scan"), + 1, &match_expr, blk); + } + + OnigRegex reg; + Data_Get_Struct(mrb, match_expr, &mrb_onig_regexp_type, reg); + mrb_value const result = mrb_nil_p(blk)? mrb_ary_new(mrb) : self; + mrb_value m_value = create_onig_region(mrb, self, match_expr); + OnigRegion* const m = (OnigRegion*)DATA_PTR(m_value); + int last_end_pos = 0; + int i; + + while (1) { + if(onig_match_common(mrb, reg, m_value, self, last_end_pos) == ONIG_MISMATCH) { break; } + + if(mrb_nil_p(blk)) { + mrb_assert(mrb_array_p(result)); + if(m->num_regs == 1) { + mrb_ary_push(mrb, result, mrb_str_substr(mrb, self, m->beg[0], m->end[0] - m->beg[0])); + } else { + mrb_value const elem = mrb_ary_new_capa(mrb, m->num_regs - 1); + for(i = 1; i < m->num_regs; ++i) { + mrb_ary_push(mrb, elem, mrb_str_substr(mrb, self, m->beg[i], m->end[i] - m->beg[i])); + } + mrb_ary_push(mrb, result, elem); + } + } else { // call block + mrb_assert(mrb_string_p(result)); + if(m->num_regs == 1) { + mrb_yield(mrb, blk, mrb_str_substr(mrb, self, m->beg[0], m->end[0] - m->beg[0])); + } else { + mrb_value argv = mrb_ary_new_capa(mrb, m->num_regs - 1); + for(i = 1; i < m->num_regs; ++i) { + mrb_ary_push(mrb, argv, mrb_str_substr(mrb, self, m->beg[i], m->end[i] - m->beg[i])); + } + mrb_yield(mrb, blk, argv); + } + } + + last_end_pos = m->end[0]; + } + + return result; +} + +// ISO 15.2.10.5.35 +static mrb_value +string_split(mrb_state* mrb, mrb_value self) { + mrb_value pattern = mrb_nil_value(); mrb_int limit = 0; + int argc = mrb_get_args(mrb, "|oi", &pattern, &limit); + + if(argc == 0) { // check $; global variable + pattern = mrb_gv_get(mrb, mrb_intern_lit(mrb, "$;")); + if(!mrb_nil_p(pattern)) { argc = 1; } + } + + if(mrb_nil_p(pattern) || mrb_string_p(pattern)) { + return mrb_funcall(mrb, self, "string_split", argc, pattern, mrb_fixnum_value(limit)); + } + + mrb_value const result = mrb_ary_new(mrb); + if(RSTRING_LEN(self) == 0) { return result; } + + OnigRegex reg; + Data_Get_Struct(mrb, pattern, &mrb_onig_regexp_type, reg); + mrb_value const match_value = create_onig_region(mrb, self, pattern); + OnigRegion* const match = (OnigRegion*)DATA_PTR(match_value); + int last_end_pos = 0, next_match_pos = 0; + mrb_int num_matches = 0; + + while (limit <= 0 || (limit - 1) > num_matches) { + int i; + if(next_match_pos >= RSTRING_LEN(self) || + onig_match_common(mrb, reg, match_value, self, next_match_pos) == ONIG_MISMATCH) { break; } + + if (last_end_pos == match->end[0]) { + ++next_match_pos; + // Remove this loop if not using UTF-8 + for (; next_match_pos < RSTRING_LEN(self) && (RSTRING_PTR(self)[next_match_pos] & 0xC0) == 0x80; + ++next_match_pos) {} + } else { + mrb_ary_push(mrb, result, mrb_str_substr( + mrb, self, last_end_pos, match->beg[0] - last_end_pos)); + // If there are captures, add them to the array + for (i = 1; i < match->num_regs; ++i) { + mrb_ary_push(mrb, result, mrb_str_substr( + mrb, self, match->beg[i], match->end[i] - match->beg[i])); + } + last_end_pos = match->end[0]; + next_match_pos = last_end_pos; + ++num_matches; + } + } + if (last_end_pos <= RSTRING_LEN(self)) { + mrb_ary_push(mrb, result, mrb_str_substr( + mrb, self, last_end_pos, RSTRING_LEN(self) - last_end_pos)); + } + + if (limit == 0) { // remove empty trailing elements + int count = 0, i; + for (i = RARRAY_LEN(result); i > 0; --i) { + mrb_assert(mrb_string_p(RARRAY_PTR(result)[i - 1])); + if (RSTRING_LEN(RARRAY_PTR(result)[i - 1]) != 0) { break; } + else { ++count; } + } + if(count > 0) { + return mrb_ary_new_from_values(mrb, RARRAY_LEN(result) - count, RARRAY_PTR(result)); + } + } + + return result; +} + +// ISO 15.2.10.5.36 +static mrb_value +string_sub(mrb_state* mrb, mrb_value self) { + mrb_value blk, match_expr, replace_expr = mrb_nil_value(); + int const argc = mrb_get_args(mrb, "&o|S", &blk, &match_expr, &replace_expr); + + if(mrb_string_p(match_expr)) { + mrb_value argv[] = { match_expr, replace_expr }; + return mrb_funcall_with_block(mrb, self, mrb_intern_lit(mrb, "string_sub"), argc, argv, blk); + } + + if(!mrb_nil_p(blk) && !mrb_nil_p(replace_expr)) { + mrb_raise(mrb, E_ARGUMENT_ERROR, "both block and replace expression must not be passed"); + } + + OnigRegex reg; + Data_Get_Struct(mrb, match_expr, &mrb_onig_regexp_type, reg); + mrb_value const result = mrb_str_new(mrb, NULL, 0); + mrb_value const match_value = create_onig_region(mrb, self, match_expr); + OnigRegion* const match = (OnigRegion*)DATA_PTR(match_value); + + int const onig_result = onig_match_common(mrb, reg, match_value, self, 0); + if(onig_result == ONIG_MISMATCH) { return self; } + + mrb_str_cat(mrb, result, RSTRING_PTR(self), match->beg[0]); + + if(mrb_nil_p(blk)) { + append_replace_str(mrb, result, replace_expr, self, reg, match); + } else { + mrb_value const tmp_str = mrb_str_to_str(mrb, mrb_yield(mrb, blk, mrb_str_substr( + mrb, self, match->beg[0], match->end[0] - match->beg[0]))); + mrb_assert(mrb_string_p(tmp_str)); + mrb_str_concat(mrb, result, tmp_str); + } + + int const last_end_pos = match->end[0]; + mrb_str_cat(mrb, result, RSTRING_PTR(self) + last_end_pos, RSTRING_LEN(self) - last_end_pos); + + return result; +} + +static mrb_value +onig_regexp_clear_global_variables(mrb_state* mrb, mrb_value self) { + mrb_gv_remove(mrb, mrb_intern_lit(mrb, "$~")); + mrb_gv_remove(mrb, mrb_intern_lit(mrb, "$&")); + mrb_gv_remove(mrb, mrb_intern_lit(mrb, "$`")); + mrb_gv_remove(mrb, mrb_intern_lit(mrb, "$'")); + mrb_gv_remove(mrb, mrb_intern_lit(mrb, "$+")); + + int idx; + for(idx = 1; idx < 10; ++idx) { + char const n[] = { '$', '0' + idx }; + mrb_gv_remove(mrb, mrb_intern(mrb, n, 2)); + } + + return self; +} + +static mrb_value +onig_regexp_does_set_global_variables(mrb_state* mrb, mrb_value self) { + (void)self; + return mrb_obj_iv_get(mrb, (struct RObject*)mrb_class_get(mrb, "OnigRegexp"), + mrb_intern_lit(mrb, "@set_global_variables")); +} +static mrb_value +onig_regexp_set_set_global_variables(mrb_state* mrb, mrb_value self) { + mrb_value arg; + mrb_get_args(mrb, "o", &arg); + mrb_value const ret = mrb_bool_value(mrb_bool(arg)); + mrb_obj_iv_set(mrb, (struct RObject*)mrb_class_get(mrb, "OnigRegexp"), + mrb_intern_lit(mrb, "@set_global_variables"), ret); + onig_regexp_clear_global_variables(mrb, self); + return ret; +} + +// ISO 15.2.15.6.2 +static mrb_value +onig_regexp_escape(mrb_state* mrb, mrb_value self) { + char* str_begin; mrb_args_int str_len; + mrb_get_args(mrb, "s", &str_begin, &str_len); + + mrb_value const ret = mrb_str_new(mrb, NULL, 0); + char escaped_char = 0; + int substr_count = 0; + char const* str = str_begin; + + for(; str < (str_begin + str_len); ++str) { + switch(*str) { + case '\n': escaped_char = 'n'; break; + case '\t': escaped_char = 't'; break; + case '\r': escaped_char = 'r'; break; + case '\f': escaped_char = 'f'; break; + + case ' ': + case '#': + case '$': + case '(': + case ')': + case '*': + case '+': + case '-': + case '.': + case '?': + case '[': + case '\\': + case ']': + case '^': + case '{': + case '|': + case '}': + escaped_char = *str; break; + + default: ++substr_count; continue; + } + + mrb_str_cat(mrb, ret, str - substr_count, substr_count); + substr_count = 0; + + char const c[] = { '\\', escaped_char }; + mrb_str_cat(mrb, ret, c, 2); + } + mrb_str_cat(mrb, ret, str - substr_count, substr_count); + return ret; +} + +void +mrb_mruby_onig_regexp_gem_init(mrb_state* mrb) { + struct RClass *clazz; + + clazz = mrb_define_class(mrb, "OnigRegexp", mrb->object_class); + MRB_SET_INSTANCE_TT(clazz, MRB_TT_DATA); + + // enable global variables setting in onig_match_common by default + mrb_obj_iv_set(mrb, (struct RObject*)clazz, mrb_intern_lit(mrb, "@set_global_variables"), mrb_true_value()); + + mrb_define_const(mrb, clazz, "IGNORECASE", mrb_fixnum_value(ONIG_OPTION_IGNORECASE)); + mrb_define_const(mrb, clazz, "EXTENDED", mrb_fixnum_value(ONIG_OPTION_EXTEND)); + mrb_define_const(mrb, clazz, "MULTILINE", mrb_fixnum_value(ONIG_OPTION_MULTILINE)); + mrb_define_const(mrb, clazz, "SINGLELINE", mrb_fixnum_value(ONIG_OPTION_SINGLELINE)); + mrb_define_const(mrb, clazz, "FIND_LONGEST", mrb_fixnum_value(ONIG_OPTION_FIND_LONGEST)); + mrb_define_const(mrb, clazz, "FIND_NOT_EMPTY", mrb_fixnum_value(ONIG_OPTION_FIND_NOT_EMPTY)); + mrb_define_const(mrb, clazz, "NEGATE_SINGLELINE", mrb_fixnum_value(ONIG_OPTION_NEGATE_SINGLELINE)); + mrb_define_const(mrb, clazz, "DONT_CAPTURE_GROUP", mrb_fixnum_value(ONIG_OPTION_DONT_CAPTURE_GROUP)); + mrb_define_const(mrb, clazz, "CAPTURE_GROUP", mrb_fixnum_value(ONIG_OPTION_CAPTURE_GROUP)); + mrb_define_const(mrb, clazz, "NOTBOL", mrb_fixnum_value(ONIG_OPTION_NOTBOL)); + mrb_define_const(mrb, clazz, "NOTEOL", mrb_fixnum_value(ONIG_OPTION_NOTEOL)); +#ifdef ONIG_OPTION_POSIX_REGION + mrb_define_const(mrb, clazz, "POSIX_REGION", mrb_fixnum_value(ONIG_OPTION_POSIX_REGION)); +#endif +#ifdef ONIG_OPTION_ASCII_RANGE + mrb_define_const(mrb, clazz, "ASCII_RANGE", mrb_fixnum_value(ONIG_OPTION_ASCII_RANGE)); +#endif +#ifdef ONIG_OPTION_POSIX_BRACKET_ALL_RANGE + mrb_define_const(mrb, clazz, "POSIX_BRACKET_ALL_RANGE", mrb_fixnum_value(ONIG_OPTION_POSIX_BRACKET_ALL_RANGE)); +#endif +#ifdef ONIG_OPTION_WORD_BOUND_ALL_RANGE + mrb_define_const(mrb, clazz, "WORD_BOUND_ALL_RANGE", mrb_fixnum_value(ONIG_OPTION_WORD_BOUND_ALL_RANGE)); +#endif +#ifdef ONIG_OPTION_NEWLINE_CRLF + mrb_define_const(mrb, clazz, "NEWLINE_CRLF", mrb_fixnum_value(ONIG_OPTION_NEWLINE_CRLF)); +#endif +#ifdef ONIG_OPTION_NOTBOS + mrb_define_const(mrb, clazz, "NOTBOS", mrb_fixnum_value(ONIG_OPTION_NOTBOS)); +#endif +#ifdef ONIG_OPTION_NOTEOS + mrb_define_const(mrb, clazz, "NOTEOS", mrb_fixnum_value(ONIG_OPTION_NOTEOS)); +#endif + + mrb_define_method(mrb, clazz, "initialize", onig_regexp_initialize, MRB_ARGS_REQ(1) | MRB_ARGS_OPT(2)); + mrb_define_method(mrb, clazz, "==", onig_regexp_equal, MRB_ARGS_REQ(1)); + mrb_define_method(mrb, clazz, "match", onig_regexp_match, MRB_ARGS_REQ(1) | MRB_ARGS_OPT(1)); + mrb_define_method(mrb, clazz, "casefold?", onig_regexp_casefold_p, MRB_ARGS_NONE()); + + mrb_define_method(mrb, clazz, "options", onig_regexp_options, MRB_ARGS_NONE()); + mrb_define_method(mrb, clazz, "inspect", onig_regexp_inspect, MRB_ARGS_NONE()); + mrb_define_method(mrb, clazz, "to_s", onig_regexp_to_s, MRB_ARGS_NONE()); + + mrb_define_module_function(mrb, clazz, "escape", onig_regexp_escape, MRB_ARGS_REQ(1)); + mrb_define_module_function(mrb, clazz, "quote", onig_regexp_escape, MRB_ARGS_REQ(1)); + mrb_define_module_function(mrb, clazz, "version", onig_regexp_version, MRB_ARGS_NONE()); + mrb_define_module_function(mrb, clazz, "set_global_variables?", onig_regexp_does_set_global_variables, MRB_ARGS_NONE()); + mrb_define_module_function(mrb, clazz, "set_global_variables=", onig_regexp_set_set_global_variables, MRB_ARGS_REQ(1)); + mrb_define_module_function(mrb, clazz, "clear_global_variables", onig_regexp_clear_global_variables, MRB_ARGS_NONE()); + + struct RClass* match_data = mrb_define_class(mrb, "OnigMatchData", mrb->object_class); + MRB_SET_INSTANCE_TT(clazz, MRB_TT_DATA); + mrb_undef_class_method(mrb, match_data, "new"); + + // mrb_define_method(mrb, match_data, "==", &match_data_eq); + mrb_define_method(mrb, match_data, "[]", &match_data_index, MRB_ARGS_REQ(1)); + mrb_define_method(mrb, match_data, "begin", &match_data_begin, MRB_ARGS_REQ(1)); + mrb_define_method(mrb, match_data, "captures", &match_data_captures, MRB_ARGS_NONE()); + mrb_define_method(mrb, match_data, "end", &match_data_end, MRB_ARGS_REQ(1)); + // mrb_define_method(mrb, match_data, "eql?", &match_data_eq); + // mrb_define_method(mrb, match_data, "hash", &match_data_hash); + mrb_define_method(mrb, match_data, "initialize_copy", &match_data_copy, MRB_ARGS_REQ(1)); + // mrb_define_method(mrb, match_data, "inspect", &match_data_inspect); + mrb_define_method(mrb, match_data, "length", &match_data_length, MRB_ARGS_NONE()); + // mrb_define_method(mrb, match_data, "names", &match_data_names); + mrb_define_method(mrb, match_data, "offset", &match_data_offset, MRB_ARGS_REQ(1)); + mrb_define_method(mrb, match_data, "post_match", &match_data_post_match, MRB_ARGS_NONE()); + mrb_define_method(mrb, match_data, "pre_match", &match_data_pre_match, MRB_ARGS_NONE()); + mrb_define_method(mrb, match_data, "regexp", &match_data_regexp, MRB_ARGS_NONE()); + mrb_define_method(mrb, match_data, "size", &match_data_length, MRB_ARGS_NONE()); + mrb_define_method(mrb, match_data, "string", &match_data_string, MRB_ARGS_NONE()); + mrb_define_method(mrb, match_data, "to_a", &match_data_to_a, MRB_ARGS_NONE()); + mrb_define_method(mrb, match_data, "to_s", &match_data_to_s, MRB_ARGS_NONE()); + // mrb_define_method(mrb, match_data, "values_at", &match_data_values_at); + + mrb_define_method(mrb, mrb->string_class, "onig_regexp_gsub", &string_gsub, MRB_ARGS_REQ(1) | MRB_ARGS_OPT(1) | MRB_ARGS_BLOCK()); + mrb_define_method(mrb, mrb->string_class, "onig_regexp_sub", &string_sub, MRB_ARGS_REQ(1) | MRB_ARGS_OPT(1) | MRB_ARGS_BLOCK()); + mrb_define_method(mrb, mrb->string_class, "onig_regexp_split", &string_split, MRB_ARGS_REQ(1)); + mrb_define_method(mrb, mrb->string_class, "onig_regexp_scan", &string_scan, MRB_ARGS_REQ(1) | MRB_ARGS_BLOCK()); +} + +void +mrb_mruby_onig_regexp_gem_final(mrb_state* mrb) { + (void)mrb; +} + +// vim:set et: diff --git a/web/server/h2o/libh2o/deps/mruby-onig-regexp/test/mruby_onig_regexp.rb b/web/server/h2o/libh2o/deps/mruby-onig-regexp/test/mruby_onig_regexp.rb new file mode 100644 index 00000000..e70b06fd --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby-onig-regexp/test/mruby_onig_regexp.rb @@ -0,0 +1,398 @@ + +# Constant +assert("OnigRegexp::CONSTANT") do + OnigRegexp::IGNORECASE == 1 and OnigRegexp::EXTENDED == 2 and OnigRegexp::MULTILINE == 4 +end + + +# Class method +assert('OnigRgexp.compile', '15.2.15.6.2') do + assert_equal OnigRegexp.compile('.*'), OnigRegexp.compile('.*') +end + +assert('OnigRegexp.escape', '15.2.15.6.2') do + escaping_chars = "\n\t\r\f #$()*+-.?[\\]^{|}" + assert_equal '\n\t\r\f\\ \#\$\(\)\*\+\-\.\?\[\\\\\]\^\{\|\}', OnigRegexp.escape(escaping_chars) + assert_equal 'cute\nmruby\tcute', OnigRegexp.escape("cute\nmruby\tcute") +end + +assert('OnigRegexp.last_match', '15.2.15.6.3') do + OnigRegexp.new('.*') =~ 'ginka' + assert_equal 'ginka', OnigRegexp.last_match[0] +end + +assert('OnigRegexp.quote', '15.2.15.6.4') do + assert_equal '\n', OnigRegexp.quote("\n") +end + +# Instance method +assert('OnigRegexp#initialize', '15.2.15.7.1') do + OnigRegexp.new(".*") and OnigRegexp.new(".*", OnigRegexp::MULTILINE) +end + +assert('OnigRegexp#initialize_copy', '15.2.15.7.2') do + r1 = OnigRegexp.new(".*") + r2 = r1.dup + assert_equal r1, r2 + assert_equal 'kawa', r2.match('kawa')[0] +end + +assert("OnigRegexp#==", '15.2.15.7.3') do + reg1 = reg2 = OnigRegexp.new("(https?://[^/]+)[-a-zA-Z0-9./]+") + reg3 = OnigRegexp.new("(https?://[^/]+)[-a-zA-Z0-9./]+") + reg4 = OnigRegexp.new("(https://[^/]+)[-a-zA-Z0-9./]+") + + assert_true(reg1 == reg2 && reg1 == reg3 && !(reg1 == reg4)) + + assert_false(OnigRegexp.new("a") == "a") +end + +assert("OnigRegexp#===", '15.2.15.7.4') do + reg = OnigRegexp.new("(https?://[^/]+)[-a-zA-Z0-9./]+") + assert_true reg === "http://example.com" + assert_false reg === "htt://example.com" +end + +assert('OnigRegexp#=~', '15.2.15.7.5') do + assert_equal(0) { OnigRegexp.new('.*') =~ 'akari' } + assert_equal(nil) { OnigRegexp.new('t') =~ 'akari' } +end + +assert("OnigRegexp#casefold?", '15.2.15.7.6') do + assert_false OnigRegexp.new("(https?://[^/]+)[-a-zA-Z0-9./]+", OnigRegexp::MULTILINE).casefold? + assert_true OnigRegexp.new("(https?://[^/]+)[-a-zA-Z0-9./]+", OnigRegexp::IGNORECASE | OnigRegexp::EXTENDED).casefold? + assert_true OnigRegexp.new("(https?://[^/]+)[-a-zA-Z0-9./]+", OnigRegexp::MULTILINE | OnigRegexp::IGNORECASE).casefold? + assert_false OnigRegexp.new("(https?://[^/]+)[-a-zA-Z0-9./]+").casefold? + assert_true OnigRegexp.new("(https?://[^/]+)[-a-zA-Z0-9./]+", true).casefold? +end + +assert("OnigRegexp#match", '15.2.15.7.7') do + reg = OnigRegexp.new("(https?://[^/]+)[-a-zA-Z0-9./]+") + assert_false reg.match("http://masamitsu-murase.12345/hoge.html").nil? + assert_nil reg.match("http:///masamitsu-murase.12345/hoge.html") +end + +assert("OnigRegexp#source", '15.2.15.7.8') do + str = "(https?://[^/]+)[-a-zA-Z0-9./]+" + reg = OnigRegexp.new(str) + + reg.source == str +end + +if OnigRegexp.const_defined? :ASCII_RANGE + assert('OnigRegexp#options (no options)') do + assert_equal OnigRegexp::ASCII_RANGE | OnigRegexp::POSIX_BRACKET_ALL_RANGE | OnigRegexp::WORD_BOUND_ALL_RANGE, OnigRegexp.new(".*").options + end + + assert('OnigRegexp#options (multiline)') do + assert_equal OnigRegexp::MULTILINE | OnigRegexp::ASCII_RANGE | OnigRegexp::POSIX_BRACKET_ALL_RANGE | OnigRegexp::WORD_BOUND_ALL_RANGE, OnigRegexp.new(".*", OnigRegexp::MULTILINE).options + end +end + +assert("OnigRegexp#inspect") do + reg = OnigRegexp.new("(https?://[^/]+)[-a-zA-Z0-9./]+") + + assert_equal '/(https?:\/\/[^\/]+)[-a-zA-Z0-9.\/]+/', reg.inspect + assert_equal '/abc\nd\te/mi', OnigRegexp.new("abc\nd\te", OnigRegexp::MULTILINE | OnigRegexp::IGNORECASE).inspect + assert_equal '/abc/min', OnigRegexp.new("abc", OnigRegexp::MULTILINE | OnigRegexp::IGNORECASE, "none").inspect +end + +assert("OnigRegexp#to_s") do + assert_equal '(?-mix:ab+c)', OnigRegexp.new("ab+c").to_s + assert_equal '(?-mix:ab+c)', /ab+c/.to_s + assert_equal '(?mx-i:ab+c)', OnigRegexp.new("ab+c", OnigRegexp::MULTILINE | OnigRegexp::EXTENDED).to_s + assert_equal '(?mi-x:ab+c)', /ab+c/im.to_s + assert_equal '(?mi-x:ab+c)', /ab+c/imn.to_s +end + +assert("OnigRegexp#to_s (composition)") do + re1 = OnigRegexp.new("ab+c") + re2 = OnigRegexp.new("xy#{re1}z") + assert_equal '(?-mix:xy(?-mix:ab+c)z)', re2.to_s + + re3 = OnigRegexp.new("ab.+c", OnigRegexp::MULTILINE) + re4 = OnigRegexp.new("xy#{re3}z", OnigRegexp::IGNORECASE) + assert_equal '(?i-mx:xy(?m-ix:ab.+c)z)', re4.to_s +end + +# Extended patterns. +assert("OnigRegexp#match (no flags)") do + [ + [ ".*", "abcd\nefg", "abcd" ], + [ "^a.", "abcd\naefg", "ab" ], + [ "^a.", "bacd\naefg", "ae" ], + [ ".$", "bacd\naefg", "d" ] + ].each do |reg, str, result| + m = OnigRegexp.new(reg).match(str) + assert_equal result, m[0] if assert_false m.nil? + end +end + +assert("OnigRegexp#match (multiline)") do + patterns = [ + [ OnigRegexp.new(".*", OnigRegexp::MULTILINE), "abcd\nefg", "abcd\nefg" ] + ] + + patterns.all?{ |reg, str, result| reg.match(str)[0] == result } +end + +assert("OnigRegexp#match (ignorecase)") do + [ + [ "aBcD", "00AbcDef", "AbcD" ], + [ "0x[a-f]+", "00XaBCdefG", "0XaBCdef" ], + [ "0x[^c-f]+", "00XaBCdefG", "0XaB" ] + ].each do |reg, str, result| + m = OnigRegexp.new(reg, OnigRegexp::IGNORECASE|OnigRegexp::EXTENDED).match(str) + assert_equal result, m[0] if assert_false m.nil? + end +end + +assert("OnigRegexp#match (none encoding)") do + assert_equal 2, /\x82/n =~ "ã‚" +end + +assert('OnigRegexp.version') do + OnigRegexp.version.kind_of? String +end + +def onig_match_data_example + OnigRegexp.new('(\w+)(\w)').match('+aaabb-') +end + +assert('OnigMatchData.new') do + assert_raise(NoMethodError) { OnigMatchData.new('aaa', 'i') } +end + +assert('OnigMatchData#[]', '15.2.16.3.1') do + m = onig_match_data_example + assert_equal 'aaabb', m[0] + assert_equal 'aaab', m[1] + assert_equal 'b', m[2] + assert_nil m[3] + + m = OnigRegexp.new('(?\w\w)').match('aba') + assert_raise(TypeError) { m[[]] } + assert_raise(IndexError) { m['nam'] } + assert_equal 'ab', m[:name] + assert_equal 'ab', m['name'] + assert_equal 'ab', m[1] + + m = OnigRegexp.new('(\w) (\w) (\w) (\w)').match('a b c d') + assert_equal %w(a b c d), m[1..-1] +end + +assert('OnigMatchData#begin', '15.2.16.3.2') do + m = onig_match_data_example + assert_equal 1, m.begin(0) + assert_equal 1, m.begin(1) + assert_raise(IndexError) { m.begin 3 } +end + +assert('OnigMatchData#captures', '15.2.16.3.3') do + m = onig_match_data_example + assert_equal ['aaab', 'b'], m.captures + + m = OnigRegexp.new('(\w+)(\d)?').match('+aaabb-') + assert_equal ['aaabb', nil], m.captures +end + +assert('OnigMatchData#end', '15.2.16.3.4') do + m = onig_match_data_example + assert_equal 6, m.end(0) + assert_equal 5, m.end(1) + assert_raise(IndexError) { m.end 3 } +end + +assert('OnigMatchData#initialize_copy', '15.2.16.3.5') do + m = onig_match_data_example + c = m.dup + assert_equal m.to_a, c.to_a +end + +assert('OnigMatchData#length', '15.2.16.3.6') do + assert_equal 3, onig_match_data_example.length +end + +assert('OnigMatchData#offset', '15.2.16.3.7') do + assert_equal [1, 6], onig_match_data_example.offset(0) + assert_equal [1, 5], onig_match_data_example.offset(1) +end + +assert('OnigMatchData#post_match', '15.2.16.3.8') do + assert_equal '-', onig_match_data_example.post_match +end + +assert('OnigMatchData#pre_match', '15.2.16.3.9') do + assert_equal '+', onig_match_data_example.pre_match +end + +assert('OnigMatchData#size', '15.2.16.3.10') do + assert_equal 3, onig_match_data_example.length +end + +assert('OnigMatchData#string', '15.2.16.3.11') do + assert_equal '+aaabb-', onig_match_data_example.string +end + +assert('OnigMatchData#to_a', '15.2.16.3.12') do + assert_equal ['aaabb', 'aaab', 'b'], onig_match_data_example.to_a +end + +assert('OnigMatchData#to_s', '15.2.16.3.13') do + assert_equal 'aaabb', onig_match_data_example.to_s +end + +assert('OnigMatchData#regexp') do + assert_equal '(\w+)(\w)', onig_match_data_example.regexp.source +end + +assert('Invalid regexp') do + assert_raise(ArgumentError) { OnigRegexp.new '[aio' } +end + +assert('String#onig_regexp_gsub') do + test_str = 'hello mruby' + assert_equal 'h*ll* mr*by', test_str.onig_regexp_gsub(OnigRegexp.new('[aeiou]'), '*') + assert_equal 'hll mrby', test_str.onig_regexp_gsub(OnigRegexp.new('([aeiou])'), '<\1>') + assert_equal 'h e l l o m r u b y ', test_str.onig_regexp_gsub(OnigRegexp.new('\w')) { |v| v + ' ' } + assert_equal 'h{e}ll{o} mr{u}by', test_str.onig_regexp_gsub(OnigRegexp.new('(?[aeiou])'), '{\k}') + assert_equal '.h.e.l.l.o. .m.r.u.b.y.', test_str.onig_regexp_gsub(OnigRegexp.new(''), '.') + assert_equal " hello\n mruby", "hello\nmruby".onig_regexp_gsub(OnigRegexp.new('^'), ' ') + assert_equal "he<><>o mruby", test_str.onig_regexp_gsub(OnigRegexp.new('(l)'), '<\1><\2>') +end + +assert('String#onig_regexp_scan') do + test_str = 'mruby world' + assert_equal ['mruby', 'world'], test_str.onig_regexp_scan(OnigRegexp.new('\w+')) + assert_equal ['mru', 'by ', 'wor'], test_str.onig_regexp_scan(OnigRegexp.new('...')) + assert_equal [['mru'], ['by '], ['wor']], test_str.onig_regexp_scan(OnigRegexp.new('(...)')) + assert_equal [['mr', 'ub'], ['y ', 'wo']], test_str.onig_regexp_scan(OnigRegexp.new('(..)(..)')) + + result = [] + assert_equal test_str, test_str.onig_regexp_scan(OnigRegexp.new('\w+')) { |v| result << "<<#{v}>>" } + assert_equal ['<>', '<>'], result + + result = '' + assert_equal test_str, test_str.onig_regexp_scan(OnigRegexp.new('(.)(.)')) { |x, y| result += y; result += x } + assert_equal 'rmbu yowlr', result +end + +assert('String#onig_regexp_sub') do + test_str = 'hello mruby' + assert_equal 'h*llo mruby', test_str.onig_regexp_sub(OnigRegexp.new('[aeiou]'), '*') + assert_equal 'hllo mruby', test_str.onig_regexp_sub(OnigRegexp.new('([aeiou])'), '<\1>') + assert_equal 'h ello mruby', test_str.onig_regexp_sub(OnigRegexp.new('\w')) { |v| v + ' ' } + assert_equal 'h{e}llo mruby', test_str.onig_regexp_sub(OnigRegexp.new('(?[aeiou])'), '{\k}') +end + +assert('String#onig_regexp_split') do + test_str = 'cute mruby cute' + assert_equal ['cute', 'mruby', 'cute'], test_str.onig_regexp_split + assert_equal ['cute', 'mruby', 'cute'], test_str.onig_regexp_split(OnigRegexp.new(' ')) + + prev_splitter = $; + $; = OnigRegexp.new ' \w' + assert_equal ['cute', 'ruby', 'ute'], test_str.onig_regexp_split + $; = 't' + assert_equal ['cu', 'e mruby cu', 'e'], test_str.onig_regexp_split + $; = prev_splitter + + assert_equal ['h', 'e', 'l', 'l', 'o'], 'hello'.onig_regexp_split(OnigRegexp.new('')) + assert_equal ['h', 'e', 'llo'], 'hello'.onig_regexp_split(OnigRegexp.new(''), 3) + assert_equal ['h', 'i', 'd', 'a', 'd'], 'hi dad'.onig_regexp_split(OnigRegexp.new('\s*')) + + test_str = '1, 2, 3, 4, 5,, 6' + assert_equal ['1', '2', '3', '4', '5', '', '6'], test_str.onig_regexp_split(OnigRegexp.new(',\s*')) + + test_str = '1,,2,3,,4,,' + assert_equal ['1', '', '2', '3', '', '4'], test_str.onig_regexp_split(OnigRegexp.new(',')) + assert_equal ['1', '', '2', '3,,4,,'], test_str.onig_regexp_split(OnigRegexp.new(','), 4) + assert_equal ['1', '', '2', '3', '', '4', '', ''], test_str.onig_regexp_split(OnigRegexp.new(','), -4) + + assert_equal [], ''.onig_regexp_split(OnigRegexp.new(','), -1) +end + +assert('String#index') do + assert_equal 0, 'abc'.index('a') + assert_nil 'abc'.index('d') + assert_equal 3, 'abcabc'.index('a', 1) + assert_equal 1, "hello".index(?e) + + assert_equal 0, 'abcabc'.index(/a/) + assert_nil 'abc'.index(/d/) + assert_equal 3, 'abcabc'.index(/a/, 1) + assert_equal 4, "hello".index(/[aeiou]/, -3) + assert_equal 3, "regexpindex".index(/e.*x/, 2) +end + +prev_regexp = Regexp + +Regexp = OnigRegexp + +# global variables +assert('$~') do + m = onig_match_data_example + assert_equal m[0], $~[0] +end + +assert('$&') do + m = onig_match_data_example + assert_equal m[0], $& +end + +assert('$`') do + m = onig_match_data_example + assert_equal m.pre_match, $` +end + +assert('$\'') do + m = onig_match_data_example + assert_equal m.post_match, $' +end + +assert('$+') do + m = onig_match_data_example + assert_equal m[-1], $+ +end + +assert('$1 to $9') do + onig_match_data_example + assert_equal 'aaab', $1 + assert_equal 'b', $2 + assert_nil $3 + assert_nil $4 + assert_nil $5 + assert_nil $6 + assert_nil $7 + assert_nil $8 + assert_nil $9 +end + +assert('default OnigRegexp.set_global_variables?') do + assert_true OnigRegexp.set_global_variables? +end + +assert('change set_global_variables') do + m = onig_match_data_example + assert_equal m[0], $~[0] + + OnigRegexp.set_global_variables = false + assert_false OnigRegexp.set_global_variables? + + # global variables must be cleared when OnigRegexp.set_global_variables gets change + assert_nil $~ + + onig_match_data_example + assert_nil $~ + + OnigRegexp.set_global_variables = true +end + +Regexp = Object + +assert('OnigRegexp not default') do + onig_match_data_example + assert_nil $~ +end + +Regexp = prev_regexp diff --git a/web/server/h2o/libh2o/deps/mruby-pack/.gitignore b/web/server/h2o/libh2o/deps/mruby-pack/.gitignore new file mode 100644 index 00000000..55ef3162 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby-pack/.gitignore @@ -0,0 +1,5 @@ +gem_* +gem-* +mrb-*.a +src/*.o +/tmp diff --git a/web/server/h2o/libh2o/deps/mruby-pack/.travis.yml b/web/server/h2o/libh2o/deps/mruby-pack/.travis.yml new file mode 100644 index 00000000..ffe22728 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby-pack/.travis.yml @@ -0,0 +1,2 @@ +script: + - "ruby run_test.rb all test" diff --git a/web/server/h2o/libh2o/deps/mruby-pack/README.md b/web/server/h2o/libh2o/deps/mruby-pack/README.md new file mode 100644 index 00000000..91addce8 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby-pack/README.md @@ -0,0 +1,67 @@ +mruby-pack (pack / unpack) +========= + +mruby-pack provides `Array#pack` and `String#unpack` for mruby. + + +## Installation +Add the line below into your `build_config.rb`: + +``` + conf.gem :github => 'iij/mruby-pack' +``` + +There is no dependency on other mrbgems. + + +## Supported template string + - A : arbitrary binary string (space padded, count is width) + - a : arbitrary binary string (null padded, count is width) + - C : 8-bit unsigned (unsigned char) + - c : 8-bit signed (signed char) + - D, d: 64-bit float, native format + - E : 64-bit float, little endian byte order + - e : 32-bit float, little endian byte order + - F, f: 32-bit float, native format + - G : 64-bit float, network (big-endian) byte order + - g : 32-bit float, network (big-endian) byte order + - H : hex string (high nibble first) + - h : hex string (low nibble first) + - I : unsigned integer, native endian (`unsigned int` in C) + - i : signed integer, native endian (`int` in C) + - L : 32-bit unsigned, native endian (`uint32_t`) + - l : 32-bit signed, native endian (`int32_t`) + - m : base64 encoded string (see RFC 2045, count is width) + - N : 32-bit unsigned, network (big-endian) byte order + - n : 16-bit unsigned, network (big-endian) byte order + - Q : 64-bit unsigned, native endian (`uint64_t`) + - q : 64-bit signed, native endian (`int64_t`) + - S : 16-bit unsigned, native endian (`uint16_t`) + - s : 16-bit signed, native endian (`int16_t`) + - V : 32-bit unsigned, VAX (little-endian) byte order + - v : 16-bit unsigned, VAX (little-endian) byte order + - Z : same as "a", except that null is added with * + + +## License + +Copyright (c) 2012 Internet Initiative Japan Inc. + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the "Software"), +to deal in the Software without restriction, including without limitation +the rights to use, copy, modify, merge, publish, distribute, sublicense, +and/or sell copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. + diff --git a/web/server/h2o/libh2o/deps/mruby-pack/mrbgem.rake b/web/server/h2o/libh2o/deps/mruby-pack/mrbgem.rake new file mode 100644 index 00000000..2b9dea5b --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby-pack/mrbgem.rake @@ -0,0 +1,6 @@ +MRuby::Gem::Specification.new('mruby-pack') do |spec| + spec.license = 'MIT' + spec.authors = 'Internet Initiative Japan Inc.' + + spec.cc.include_paths << "#{build.root}/src" +end diff --git a/web/server/h2o/libh2o/deps/mruby-pack/packtest.rb b/web/server/h2o/libh2o/deps/mruby-pack/packtest.rb new file mode 100644 index 00000000..e8be7c76 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby-pack/packtest.rb @@ -0,0 +1,154 @@ +# encoding: ascii + +# a = Array, s = String, t = Template + +def packtest(a, s, t) + begin + r = a.pack(t) + return if r == s + puts "#{a.inspect}.pack(#{t.inspect}) -> #{r.inspect} should be #{s.inspect}" + rescue => r + unless r.is_a? s + puts "#{a.inspect}.pack(#{t.inspect}) -> #{r.inspect} should be #{s.inspect}" + end + end +end + +def unpacktest(a, s, t) + r = s.unpack(t) + return if r == a + puts "#{s.inspect}.unpack(#{t.inspect}) -> #{r.inspect} should be #{a.inspect}" +end + +def pptest(a, s, t) + packtest(a, s, t) + unpacktest(a, s, t) +end + +pptest [1], "\x01", "C" + +packtest [1.1], "\x01", "C" +packtest [-1], "\xff", "C" +packtest [1,2], "\x01\x02", "C2" +#packtest [1], "X", ArgumentError + +unpacktest [48, nil], "0", "CC" +unpacktest [160, -96], "\xa0\xa0", "Cc" +unpacktest [49, 50, 51], "123", "C*" + +pptest [12849], "12", "S" +unpacktest [nil], "0", "S" +unpacktest [12849, nil], "123", "SS" +unpacktest [12849], "123", "S*" + +pptest [10000], "\x27\x10", "s>" +pptest [-10000], "\xd8\xf0", "s>" +pptest [50000], "\xc3\x50", "S>" + +pptest [10000], "\x10\x27", "s<" +pptest [-10000], "\xf0\xd8", "s<" +pptest [50000], "\x50\xc3", "S<" + +pptest [1000000000], "\x3b\x9a\xca\x00", "l>" +pptest [-1000000000], "\xc4\x65\x36\x00", "l>" + +pptest [1], "\x01\x00\x00\x00", "L<" +pptest [258], "\x02\x01\x00\x00", "L<" +pptest [66051], "\x03\x02\x01\x00", "L<" +pptest [16909060], "\x04\x03\x02\x01", "L<" +pptest [16909060], "\x01\x02\x03\x04", "L>" + +packtest [-1], "\xff\xff\xff\xff", "L<" + +pptest [1000000000], "\x00\x00\x00\x00\x3b\x9a\xca\x00", "q>" +pptest [-1000000000], "\xff\xff\xff\xff\xc4\x65\x36\x00", "q>" + +if (2**33).is_a? Fixnum + pptest [81985529216486895], "\x01\x23\x45\x67\x89\xab\xcd\xef", "q>" + pptest [-1167088121787636991], "\x01\x23\x45\x67\x89\xab\xcd\xef", "q<" +end + +pptest [16909060], "\x01\x02\x03\x04", "N" +pptest [258], "\x01\x02", "n" +pptest [32769], "\x80\x01", "n" + +pptest [16909060], "\x04\x03\x02\x01", "V" +pptest [258], "\x02\x01", "v" + +packtest [""], "", "m" +packtest ["a"], "YQ==\n", "m" +packtest ["ab"], "YWI=\n", "m" +packtest ["abc"], "YWJj\n", "m" +packtest ["abcd"], "YWJjZA==\n", "m" + +unpacktest [""], "", "m" +unpacktest ["a"], "YQ==\n", "m" +unpacktest ["ab"], "YWI=\n", "m" +unpacktest ["abc"], "YWJj\n", "m" +unpacktest ["abcd"], "YWJjZA==\n", "m" + +packtest [""], "\0", "H" +packtest ["3"], "0", "H" +packtest ["34"], "", "H0" +packtest ["34"], "0", "H" +packtest ["34"], "4", "H2" +packtest ["34"], "4\0", "H3" +packtest ["3456"], "4P", "H3" +packtest ["34563"], "4V0", "H*" +packtest ["5a"], "Z", "H*" +packtest ["5A"], "Z", "H*" + +unpacktest [""], "", "H" +unpacktest [""], "0", "H0" +unpacktest ["3"], "0", "H" +unpacktest ["30"], "0", "H2" +unpacktest ["30"], "0", "H3" +unpacktest ["303"], "01", "H3" +unpacktest ["303132"], "012", "H*" +unpacktest ["3031", 50], "012", "H4C" +unpacktest ["5a"], "Z", "H*" + +packtest [""], "\0", "h" +packtest ["3"], "\03", "h" +packtest ["34"], "", "h0" +packtest ["34"], "\03", "h" +packtest ["34"], "C", "h2" +packtest ["34"], "C\0", "h3" +packtest ["3456"], "C\05", "h3" +packtest ["34563"], "Ce\03", "h*" + +packtest [""], " ", "A" +unpacktest [""], "", "A" +pptest ["1"], "1", "A" +pptest ["1"], "1 ", "A2" +unpacktest ["1"], "1", "A2" +unpacktest ["1"], "1 ", "A2" +unpacktest ["1"], "1\0", "A2" +packtest ["12"], "1", "A" +unpacktest ["1"], "12", "A" +pptest ["123"], "123", "A*" +packtest ["1","2"], "2", "A0A" +unpacktest ["","2"], "2", "A0A" + +packtest [""], "\0", "a" +unpacktest [""], "", "a" +pptest ["1"], "1", "a" +pptest ["1 "], "1 ", "a2" +pptest ["1\0"], "1\0", "a2" +packtest ["1"], "1\0", "a2" +pptest ["123"], "123", "a*" + +packtest [""], "\0", "Z" +unpacktest [""], "", "Z" +pptest ["1"], "1", "Z" +pptest ["1"], "1\0", "Z2" +pptest ["1 "], "1 ", "Z2" +pptest ["123"], "123\0", "Z*" +pptest ["1","2"], "12", "ZZ" +pptest ["1","2"], "1\0002", "Z*Z" +unpacktest ["1","3"], "1\00023", "Z3Z" + +packtest [1, 2], "\x01\x02", "CyC" + +packtest [65], "A", 'U' +packtest [59411], "\xEE\xA0\x93", 'U' diff --git a/web/server/h2o/libh2o/deps/mruby-pack/run_test.rb b/web/server/h2o/libh2o/deps/mruby-pack/run_test.rb new file mode 100644 index 00000000..d9566a2a --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby-pack/run_test.rb @@ -0,0 +1,26 @@ +#!/usr/bin/env ruby +# +# mrbgems test runner +# + +gemname = File.basename(File.dirname(File.expand_path __FILE__)) + +if __FILE__ == $0 + repository, dir = 'https://github.com/mruby/mruby.git', 'tmp/mruby' + build_args = ARGV + build_args = ['all', 'test'] if build_args.nil? or build_args.empty? + + Dir.mkdir 'tmp' unless File.exist?('tmp') + unless File.exist?(dir) + system "git clone #{repository} #{dir}" + end + + exit system(%Q[cd #{dir}; MRUBY_CONFIG=#{File.expand_path __FILE__} ruby minirake #{build_args.join(' ')}]) +end + +MRuby::Build.new do |conf| + toolchain :gcc + conf.gembox 'default' + + conf.gem File.expand_path(File.dirname(__FILE__)) +end diff --git a/web/server/h2o/libh2o/deps/mruby-pack/src/pack.c b/web/server/h2o/libh2o/deps/mruby-pack/src/pack.c new file mode 100644 index 00000000..9095ad03 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby-pack/src/pack.c @@ -0,0 +1,1144 @@ +/* + ** pack.c - Array#pack, String#unpack + */ + +#include "mruby.h" +#include "error.h" +#include "mruby/array.h" +#include "mruby/class.h" +#include "mruby/numeric.h" +#include "mruby/string.h" +#include "mruby/variable.h" + +#include +#include +#include +#include +#include + +struct tmpl { + mrb_value str; + int idx; +}; + +enum { + PACK_DIR_CHAR, /* C */ + PACK_DIR_SHORT, /* S */ + PACK_DIR_LONG, /* L */ + PACK_DIR_QUAD, /* Q */ + //PACK_DIR_INT, /* i */ + //PACK_DIR_VAX, + PACK_DIR_UTF8, /* U */ + //PACK_DIR_BER, + PACK_DIR_DOUBLE, /* E */ + PACK_DIR_FLOAT, /* f */ + PACK_DIR_STR, /* A */ + PACK_DIR_HEX, /* h */ + PACK_DIR_BASE64, /* m */ + PACK_DIR_INVALID +}; + +enum { + PACK_TYPE_INTEGER, + PACK_TYPE_FLOAT, + PACK_TYPE_STRING, + PACK_TYPE_NONE +}; + +#define PACK_FLAG_s 0x00000001 /* native size ("_" "!") */ +#define PACK_FLAG_a 0x00000002 /* null padding ("a") */ +#define PACK_FLAG_Z 0x00000004 /* append nul char ("z") */ +#define PACK_FLAG_SIGNED 0x00000008 /* native size ("_" "!") */ +#define PACK_FLAG_GT 0x00000010 /* big endian (">") */ +#define PACK_FLAG_LT 0x00000020 /* little endian ("<") */ +#define PACK_FLAG_WIDTH 0x00000040 /* "count" is "width" */ +#define PACK_FLAG_LSB 0x00000080 /* LSB / low nibble first */ +#define PACK_FLAG_COUNT2 0x00000100 /* "count" is special... */ +#define PACK_FLAG_LITTLEENDIAN 0x00000200 /* little endian actually */ + +#define PACK_BASE64_IGNORE 0xff +#define PACK_BASE64_PADDING 0xfe + +static int littleendian = 0; + +const static unsigned char base64chars[] = + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; +static signed char base64_dec_tab[128]; + + +static int +check_little_endian(void) +{ + unsigned int n = 1; + return (*(unsigned char *)&n == 1); +} + +static unsigned int +hex2int(unsigned char ch) +{ + if (ch >= '0' && ch <= '9') + return ch - '0'; + else if (ch >= 'A' && ch <= 'F') + return 10 + (ch - 'A'); + else if (ch >= 'a' && ch <= 'f') + return 10 + (ch - 'a'); + else + return 0; +} + +static void +make_base64_dec_tab(void) +{ + int i; + memset(base64_dec_tab, PACK_BASE64_IGNORE, sizeof(base64_dec_tab)); + for (i = 0; i < 26; i++) + base64_dec_tab['A' + i] = i; + for (i = 0; i < 26; i++) + base64_dec_tab['a' + i] = i + 26; + for (i = 0; i < 10; i++) + base64_dec_tab['0' + i] = i + 52; + base64_dec_tab['+'] = 62; + base64_dec_tab['/'] = 63; + base64_dec_tab['='] = PACK_BASE64_PADDING; +} + +static mrb_value +str_len_ensure(mrb_state *mrb, mrb_value str, int len) +{ + int n = RSTRING_LEN(str); + if (len > n) { + do { + n *= 2; + } while (len > n); + str = mrb_str_resize(mrb, str, n); + } + return str; +} + + +static int +pack_c(mrb_state *mrb, mrb_value o, mrb_value str, mrb_int sidx, unsigned int flags) +{ + str = str_len_ensure(mrb, str, sidx + 1); + RSTRING_PTR(str)[sidx] = mrb_fixnum(o); + return 1; +} + +static int +unpack_c(mrb_state *mrb, const void *src, int srclen, mrb_value ary, unsigned int flags) +{ + if (flags & PACK_FLAG_SIGNED) + mrb_ary_push(mrb, ary, mrb_fixnum_value(*(signed char *)src)); + else + mrb_ary_push(mrb, ary, mrb_fixnum_value(*(unsigned char *)src)); + return 1; +} + +static int +pack_s(mrb_state *mrb, mrb_value o, mrb_value str, mrb_int sidx, unsigned int flags) +{ + unsigned short n; + + str = str_len_ensure(mrb, str, sidx + 2); + n = mrb_fixnum(o); + if (flags & PACK_FLAG_LITTLEENDIAN) { + RSTRING_PTR(str)[sidx+0] = n % 256; + RSTRING_PTR(str)[sidx+1] = n / 256; + } else { + RSTRING_PTR(str)[sidx+0] = n / 256; + RSTRING_PTR(str)[sidx+1] = n % 256; + } + return 2; +} + +static int +unpack_s(mrb_state *mrb, const unsigned char *src, int srclen, mrb_value ary, unsigned int flags) +{ + int n; + + if (flags & PACK_FLAG_LITTLEENDIAN) { + n = src[1] * 256 + src[0]; + } else { + n = src[0] * 256 + src[1]; + } + if ((flags & PACK_FLAG_SIGNED) && (n >= 0x8000)) { + n -= 0x10000; + } + mrb_ary_push(mrb, ary, mrb_fixnum_value(n)); + return 2; +} + +static int +pack_l(mrb_state *mrb, mrb_value o, mrb_value str, mrb_int sidx, unsigned int flags) +{ + unsigned long n; + str = str_len_ensure(mrb, str, sidx + 4); + n = mrb_fixnum(o); + if (flags & PACK_FLAG_LITTLEENDIAN) { + RSTRING_PTR(str)[sidx+0] = n & 0xff; + RSTRING_PTR(str)[sidx+1] = n >> 8; + RSTRING_PTR(str)[sidx+2] = n >> 16; + RSTRING_PTR(str)[sidx+3] = n >> 24; + } else { + RSTRING_PTR(str)[sidx+0] = n >> 24; + RSTRING_PTR(str)[sidx+1] = n >> 16; + RSTRING_PTR(str)[sidx+2] = n >> 8; + RSTRING_PTR(str)[sidx+3] = n & 0xff; + } + return 4; +} + +static int +unpack_l(mrb_state *mrb, const unsigned char *src, int srclen, mrb_value ary, unsigned int flags) +{ + char msg[60]; + uint32_t ul; + mrb_int n; + + if (flags & PACK_FLAG_LITTLEENDIAN) { + ul = (uint32_t)src[3] * 256*256*256; + ul += (uint32_t)src[2] *256*256; + ul += (uint32_t)src[1] *256; + ul += (uint32_t)src[0]; + } else { + ul = (uint32_t)src[0] * 256*256*256; + ul += (uint32_t)src[1] *256*256; + ul += (uint32_t)src[2] *256; + ul += (uint32_t)src[3]; + } + if (flags & PACK_FLAG_SIGNED) { + int32_t sl = ul; + if (!FIXABLE(sl)) { + snprintf(msg, sizeof(msg), "cannot unpack to Fixnum: %ld", (long)sl); + mrb_raise(mrb, E_RANGE_ERROR, msg); + } + n = sl; + } else { + if (!POSFIXABLE(ul)) { + snprintf(msg, sizeof(msg), "cannot unpack to Fixnum: %lu", (unsigned long)ul); + mrb_raise(mrb, E_RANGE_ERROR, msg); + } + n = ul; + } + mrb_ary_push(mrb, ary, mrb_fixnum_value(n)); + return 4; +} + +static int +pack_q(mrb_state *mrb, mrb_value o, mrb_value str, mrb_int sidx, unsigned int flags) +{ + unsigned long long n; + str = str_len_ensure(mrb, str, sidx + 8); + n = mrb_fixnum(o); + if (flags & PACK_FLAG_LITTLEENDIAN) { + RSTRING_PTR(str)[sidx+0] = n & 0xff; + RSTRING_PTR(str)[sidx+1] = n >> 8; + RSTRING_PTR(str)[sidx+2] = n >> 16; + RSTRING_PTR(str)[sidx+3] = n >> 24; + RSTRING_PTR(str)[sidx+4] = n >> 32; + RSTRING_PTR(str)[sidx+5] = n >> 40; + RSTRING_PTR(str)[sidx+6] = n >> 48; + RSTRING_PTR(str)[sidx+7] = n >> 56; + } else { + RSTRING_PTR(str)[sidx+0] = n >> 56; + RSTRING_PTR(str)[sidx+1] = n >> 48; + RSTRING_PTR(str)[sidx+2] = n >> 40; + RSTRING_PTR(str)[sidx+3] = n >> 32; + RSTRING_PTR(str)[sidx+4] = n >> 24; + RSTRING_PTR(str)[sidx+5] = n >> 16; + RSTRING_PTR(str)[sidx+6] = n >> 8; + RSTRING_PTR(str)[sidx+7] = n & 0xff; + } + return 8; +} + +static int +unpack_q(mrb_state *mrb, const unsigned char *src, int srclen, mrb_value ary, unsigned int flags) +{ + char msg[60]; + uint64_t ull; + int i, pos, step; + mrb_int n; + + if (flags & PACK_FLAG_LITTLEENDIAN) { + pos = 7; + step = -1; + } else { + pos = 0; + step = 1; + } + ull = 0; + for (i = 0; i < 8; i++) { + ull = ull * 256 + (uint64_t)src[pos]; + pos += step; + } + if (flags & PACK_FLAG_SIGNED) { + int64_t sll = ull; + if (!FIXABLE(sll)) { + snprintf(msg, sizeof(msg), "cannot unpack to Fixnum: %lld", (long long)sll); + mrb_raise(mrb, E_RANGE_ERROR, msg); + } + n = sll; + } else { + if (!POSFIXABLE(ull)) { + snprintf(msg, sizeof(msg), "cannot unpack to Fixnum: %llu", (unsigned long long)ull); + mrb_raise(mrb, E_RANGE_ERROR, msg); + } + n = ull; + } + mrb_ary_push(mrb, ary, mrb_fixnum_value(n)); + return 8; +} + +static int +pack_double(mrb_state *mrb, mrb_value o, mrb_value str, mrb_int sidx, unsigned int flags) +{ + int i; + double d; + uint8_t *buffer = (uint8_t *)&d; + str = str_len_ensure(mrb, str, sidx + 8); + d = mrb_float(o); + + if (flags & PACK_FLAG_LITTLEENDIAN) { +#ifdef MRB_ENDIAN_BIG + for (i = 0; i < 8; ++i) { + RSTRING_PTR(str)[sidx + i] = buffer[8 - i - 1]; + } +#else + memcpy(RSTRING_PTR(str) + sidx, buffer, 8); +#endif + } else { +#ifdef MRB_ENDIAN_BIG + memcpy(RSTRING_PTR(str) + sidx, buffer, 8); +#else + for (i = 0; i < 8; ++i) { + RSTRING_PTR(str)[sidx + i] = buffer[8 - i - 1]; + } +#endif + } + + return 8; +} + +static int +unpack_double(mrb_state *mrb, const unsigned char * src, int srclen, mrb_value ary, unsigned int flags) +{ + int i; + double d; + uint8_t *buffer = (uint8_t *)&d; + + if (flags & PACK_FLAG_LITTLEENDIAN) { +#ifdef MRB_ENDIAN_BIG + for (i = 0; i < 8; ++i) { + buffer[8 - i - 1] = src[i]; + } +#else + memcpy(buffer, src, 8); +#endif + } else { +#ifdef MRB_ENDIAN_BIG + memcpy(buffer, src, 8); +#else + for (i = 0; i < 8; ++i) { + buffer[8 - i - 1] = src[i]; + } +#endif + } + mrb_ary_push(mrb, ary, mrb_float_value(mrb, d)); + + return 8; +} + +static int +pack_float(mrb_state *mrb, mrb_value o, mrb_value str, mrb_int sidx, unsigned int flags) +{ + int i; + float f; + uint8_t *buffer = (uint8_t *)&f; + str = str_len_ensure(mrb, str, sidx + 4); + f = mrb_float(o); + + if (flags & PACK_FLAG_LITTLEENDIAN) { +#ifdef MRB_ENDIAN_BIG + for (i = 0; i < 4; ++i) { + RSTRING_PTR(str)[sidx + i] = buffer[4 - i - 1]; + } +#else + memcpy(RSTRING_PTR(str) + sidx, buffer, 4); +#endif + } else { +#ifdef MRB_ENDIAN_BIG + memcpy(RSTRING_PTR(str) + sidx, buffer, 4); +#else + for (i = 0; i < 4; ++i) { + RSTRING_PTR(str)[sidx + i] = buffer[4 - i - 1]; + } +#endif + } + + return 4; +} + +static int +unpack_float(mrb_state *mrb, const unsigned char * src, int srclen, mrb_value ary, unsigned int flags) +{ + int i; + float f; + uint8_t *buffer = (uint8_t *)&f; + + if (flags & PACK_FLAG_LITTLEENDIAN) { +#ifdef MRB_ENDIAN_BIG + for (i = 0; i < 4; ++i) { + buffer[4 - i - 1] = src[i]; + } +#else + memcpy(buffer, src, 4); +#endif + } else { +#ifdef MRB_ENDIAN_BIG + memcpy(buffer, src, 4); +#else + for (i = 0; i < 4; ++i) { + buffer[4 - i - 1] = src[i]; + } +#endif + } + mrb_ary_push(mrb, ary, mrb_float_value(mrb, f)); + + return 4; +} + +static int +pack_utf8(mrb_state *mrb, mrb_value o, mrb_value str, mrb_int sidx, long count, unsigned int flags) +{ + char utf8[4]; + int len; + + unsigned long c = mrb_fixnum(o); + + /* Unicode character */ + /* from mruby-compiler gem */ + if (c < 0x80) { + utf8[0] = (char)c; + len = 1; + } + else if (c < 0x800) { + utf8[0] = (char)(0xC0 | (c >> 6)); + utf8[1] = (char)(0x80 | (c & 0x3F)); + len = 2; + } + else if (c < 0x10000) { + utf8[0] = (char)(0xE0 | (c >> 12) ); + utf8[1] = (char)(0x80 | ((c >> 6) & 0x3F)); + utf8[2] = (char)(0x80 | ( c & 0x3F)); + len = 3; + } + else { + utf8[0] = (char)(0xF0 | (c >> 18) ); + utf8[1] = (char)(0x80 | ((c >> 12) & 0x3F)); + utf8[2] = (char)(0x80 | ((c >> 6) & 0x3F)); + utf8[3] = (char)(0x80 | ( c & 0x3F)); + len = 4; + } + + str = str_len_ensure(mrb, str, sidx + len); + memcpy(RSTRING_PTR(str) + sidx, utf8, len); + + return len; +} + +static int +pack_a(mrb_state *mrb, mrb_value src, mrb_value dst, mrb_int didx, long count, unsigned int flags) +{ + int copylen, slen, padlen; + char *dptr, *dptr0, pad, *sptr; + + sptr = RSTRING_PTR(src); + slen = RSTRING_LEN(src); + + if ((flags & PACK_FLAG_a) || (flags & PACK_FLAG_Z)) + pad = '\0'; + else + pad = ' '; + + if (count == 0) { + return 0; + } else if (count == -1) { + copylen = slen; + padlen = (flags & PACK_FLAG_Z) ? 1 : 0; + } else if (count < slen) { + copylen = count; + padlen = 0; + } else { + copylen = slen; + padlen = count - slen; + } + + dst = str_len_ensure(mrb, dst, didx + copylen + padlen); + dptr0 = dptr = RSTRING_PTR(dst) + didx; + memcpy(dptr, sptr, copylen); + dptr += copylen; + while (padlen-- > 0) { + *dptr++ = pad; + } + + return dptr - dptr0; +} + +static int +unpack_a(mrb_state *mrb, const void *src, int slen, mrb_value ary, long count, unsigned int flags) +{ + mrb_value dst; + const char *cp, *sptr; + long copylen; + + sptr = (const char *)src; + if (count != -1 && count < slen) { + slen = count; + } + copylen = slen; + + if (flags & PACK_FLAG_Z) { /* "Z" */ + if ((cp = (const char *)memchr(sptr, '\0', slen)) != NULL) { + copylen = cp - sptr; + if (count == -1) { + slen = copylen + 1; + } + } + } else if (!(flags & PACK_FLAG_a)) { /* "A" */ + while (copylen > 0 && (sptr[copylen - 1] == '\0' || isspace(sptr[copylen - 1]))) { + copylen--; + } + } + + dst = mrb_str_new(mrb, sptr, copylen); + mrb_ary_push(mrb, ary, dst); + return slen; +} + + +static int +pack_h(mrb_state *mrb, mrb_value src, mrb_value dst, mrb_int didx, long count, unsigned int flags) +{ + unsigned int a, ashift, b, bshift; + int slen; + char *dptr, *dptr0, *sptr; + + sptr = RSTRING_PTR(src); + slen = RSTRING_LEN(src); + + if (flags & PACK_FLAG_LSB) { + ashift = 0; + bshift = 4; + } else { + ashift = 4; + bshift = 0; + } + + if (count == -1) { + count = slen; + } else if (slen > count) { + slen = count; + } + + dst = str_len_ensure(mrb, dst, didx + count); + dptr = RSTRING_PTR(dst) + didx; + + dptr0 = dptr; + for (; count > 0; count -= 2) { + a = b = 0; + if (slen > 0) { + a = hex2int(*sptr++); + slen--; + } + if (slen > 0) { + b = hex2int(*sptr++); + slen--; + } + *dptr++ = (a << ashift) + (b << bshift); + } + + return dptr - dptr0; +} + +static int +unpack_h(mrb_state *mrb, const void *src, int slen, mrb_value ary, int count, unsigned int flags) +{ + mrb_value dst; + int a, ashift, b, bshift; + const char *sptr, *sptr0; + char *dptr, *dptr0; + const char hexadecimal[] = "0123456789abcdef"; + + if (flags & PACK_FLAG_LSB) { + ashift = 0; + bshift = 4; + } else { + ashift = 4; + bshift = 0; + } + + sptr = (const char *)src; + + if (count == -1) + count = slen * 2; + + dst = mrb_str_new(mrb, NULL, count); + dptr = RSTRING_PTR(dst); + + sptr0 = sptr; + dptr0 = dptr; + while (slen > 0 && count > 0) { + a = (*sptr >> ashift) & 0x0f; + b = (*sptr >> bshift) & 0x0f; + sptr++; + slen--; + + *dptr++ = hexadecimal[a]; + count--; + + if (count > 0) { + *dptr++ = hexadecimal[b]; + count--; + } + } + + dst = mrb_str_resize(mrb, dst, dptr - dptr0); + mrb_ary_push(mrb, ary, dst); + return sptr - sptr0; +} + + +static int +pack_m(mrb_state *mrb, mrb_value src, mrb_value dst, mrb_int didx, long count, unsigned int flags) +{ + mrb_int dstlen; + unsigned long l; + int column, srclen; + char *srcptr, *dstptr, *dstptr0; + + srcptr = RSTRING_PTR(src); + srclen = RSTRING_LEN(src); + + if (srclen == 0) /* easy case */ + return 0; + + if (count != 0 && count < 3) { /* -1, 1 or 2 */ + count = 45; + } else if (count >= 3) { + count -= count % 3; + } + + dstlen = srclen / 3 * 4; + if (count > 0) { + dstlen += (srclen / count) + ((srclen % count) == 0 ? 0 : 1); + } + dst = str_len_ensure(mrb, dst, didx + dstlen); + dstptr = RSTRING_PTR(dst) + didx; + + dstptr0 = dstptr; + for (column = 3; srclen >= 3; srclen -= 3, column += 3) { + l = (unsigned char)*srcptr++ << 16; + l += (unsigned char)*srcptr++ << 8; + l += (unsigned char)*srcptr++; + + *dstptr++ = base64chars[(l >> 18) & 0x3f]; + *dstptr++ = base64chars[(l >> 12) & 0x3f]; + *dstptr++ = base64chars[(l >> 6) & 0x3f]; + *dstptr++ = base64chars[ l & 0x3f]; + + if (column == count) { + *dstptr++ = '\n'; + column = 0; + } + } + if (srclen == 1) { + l = (unsigned char)*srcptr++ << 16; + *dstptr++ = base64chars[(l >> 18) & 0x3f]; + *dstptr++ = base64chars[(l >> 12) & 0x3f]; + *dstptr++ = '='; + *dstptr++ = '='; + column += 3; + } else if (srclen == 2) { + l = (unsigned char)*srcptr++ << 16; + l += (unsigned char)*srcptr++ << 8; + *dstptr++ = base64chars[(l >> 18) & 0x3f]; + *dstptr++ = base64chars[(l >> 12) & 0x3f]; + *dstptr++ = base64chars[(l >> 6) & 0x3f]; + *dstptr++ = '='; + column += 3; + } + if (column > 0 && count > 0) { + *dstptr++ = '\n'; + } + + return dstptr - dstptr0; +} + +static int +unpack_m(mrb_state *mrb, const void *src, int slen, mrb_value ary, unsigned int flags) +{ + mrb_value dst; + int dlen; + unsigned long l; + int i, padding; + unsigned char c, ch[4]; + const char *sptr, *sptr0; + char *dptr, *dptr0; + + sptr0 = sptr = (const char *)src; + + dlen = slen / 4 * 3; /* an estimated value - may be shorter */ + dst = mrb_str_new(mrb, NULL, dlen); + dptr0 = dptr = RSTRING_PTR(dst); + + padding = 0; + while (slen >= 4) { + for (i = 0; i < 4; i++) { + do { + if (slen-- == 0) + goto done; + c = *sptr++; + if (c >= sizeof(base64_dec_tab)) + continue; + ch[i] = base64_dec_tab[c]; + if (ch[i] == PACK_BASE64_PADDING) { + ch[i] = 0; + padding++; + } + } while (ch[i] == PACK_BASE64_IGNORE); + } + + l = (ch[0] << 18) + (ch[1] << 12) + (ch[2] << 6) + ch[3]; + + if (padding == 0) { + *dptr++ = (l >> 16) & 0xff; + *dptr++ = (l >> 8) & 0xff; + *dptr++ = l & 0xff; + } else if (padding == 1) { + *dptr++ = (l >> 16) & 0xff; + *dptr++ = (l >> 8) & 0xff; + break; + } else { + *dptr++ = (l >> 16) & 0xff; + break; + } + } + +done: + dst = mrb_str_resize(mrb, dst, dptr - dptr0); + mrb_ary_push(mrb, ary, dst); + return sptr - sptr0; +} + + +static void +prepare_tmpl(mrb_state *mrb, struct tmpl *tmpl) +{ + mrb_get_args(mrb, "S", &tmpl->str); + tmpl->idx = 0; +} + +static int +has_tmpl(const struct tmpl *tmpl) +{ + return (tmpl->idx < RSTRING_LEN(tmpl->str)); +} + +static void +read_tmpl(mrb_state *mrb, struct tmpl *tmpl, int *dirp, int *typep, int *sizep, long *countp, unsigned int *flagsp) +{ + int ch, dir, t, tlen, type; + int size = 0; + long count = 1; + unsigned int flags = 0; + const char *tptr; + + tptr = RSTRING_PTR(tmpl->str); + tlen = RSTRING_LEN(tmpl->str); + + t = tptr[tmpl->idx++]; +alias: + switch (t) { + case 'A': + dir = PACK_DIR_STR; + type = PACK_TYPE_STRING; + flags |= PACK_FLAG_WIDTH | PACK_FLAG_COUNT2; + break; + case 'a': + dir = PACK_DIR_STR; + type = PACK_TYPE_STRING; + flags |= PACK_FLAG_WIDTH | PACK_FLAG_COUNT2 | PACK_FLAG_a; + break; + case 'C': + dir = PACK_DIR_CHAR; + type = PACK_TYPE_INTEGER; + size = 1; + break; + case 'c': + dir = PACK_DIR_CHAR; + type = PACK_TYPE_INTEGER; + size = 1; + flags |= PACK_FLAG_SIGNED; + break; + case 'D': case 'd': + dir = PACK_DIR_DOUBLE; + type = PACK_TYPE_FLOAT; + size = 8; + flags |= PACK_FLAG_SIGNED; + break; + case 'F': case 'f': + dir = PACK_DIR_FLOAT; + type = PACK_TYPE_FLOAT; + size = 4; + flags |= PACK_FLAG_SIGNED; + break; + case 'E': + dir = PACK_DIR_DOUBLE; + type = PACK_TYPE_FLOAT; + size = 8; + flags |= PACK_FLAG_SIGNED | PACK_FLAG_LT; + break; + case 'e': + dir = PACK_DIR_FLOAT; + type = PACK_TYPE_FLOAT; + size = 4; + flags |= PACK_FLAG_SIGNED | PACK_FLAG_LT; + break; + case 'G': + dir = PACK_DIR_DOUBLE; + type = PACK_TYPE_FLOAT; + size = 8; + flags |= PACK_FLAG_SIGNED | PACK_FLAG_GT; + break; + case 'g': + dir = PACK_DIR_FLOAT; + type = PACK_TYPE_FLOAT; + size = 4; + flags |= PACK_FLAG_SIGNED | PACK_FLAG_GT; + break; + case 'H': + dir = PACK_DIR_HEX; + type = PACK_TYPE_STRING; + flags |= PACK_FLAG_COUNT2; + break; + case 'h': + dir = PACK_DIR_HEX; + type = PACK_TYPE_STRING; + flags |= PACK_FLAG_COUNT2 | PACK_FLAG_LSB; + break; + case 'I': + switch (sizeof(int)) { + case 2: t = 'S'; goto alias; + case 4: t = 'L'; goto alias; + case 8: t = 'Q'; goto alias; + default: + mrb_raisef(mrb, E_RUNTIME_ERROR, "mruby-pack does not support sizeof(int) == %S", mrb_fixnum_value(sizeof(int))); + } + break; + case 'i': + switch (sizeof(int)) { + case 2: t = 's'; goto alias; + case 4: t = 'l'; goto alias; + case 8: t = 'q'; goto alias; + default: + mrb_raisef(mrb, E_RUNTIME_ERROR, "mruby-pack does not support sizeof(int) == %S", mrb_fixnum_value(sizeof(int))); + } + break; + case 'L': + dir = PACK_DIR_LONG; + type = PACK_TYPE_INTEGER; + size = 4; + break; + case 'l': + dir = PACK_DIR_LONG; + type = PACK_TYPE_INTEGER; + size = 4; + flags |= PACK_FLAG_SIGNED; + break; + case 'm': + dir = PACK_DIR_BASE64; + type = PACK_TYPE_STRING; + flags |= PACK_FLAG_WIDTH; + break; + case 'N': /* = "L>" */ + dir = PACK_DIR_LONG; + type = PACK_TYPE_INTEGER; + size = 4; + flags |= PACK_FLAG_GT; + break; + case 'n': /* = "S>" */ + dir = PACK_DIR_SHORT; + type = PACK_TYPE_INTEGER; + size = 2; + flags |= PACK_FLAG_GT; + break; + case 'Q': + dir = PACK_DIR_QUAD; + type = PACK_TYPE_INTEGER; + size = 8; + break; + case 'q': + dir = PACK_DIR_QUAD; + type = PACK_TYPE_INTEGER; + size = 8; + flags |= PACK_FLAG_SIGNED; + break; + case 'S': + dir = PACK_DIR_SHORT; + type = PACK_TYPE_INTEGER; + size = 2; + break; + case 's': + dir = PACK_DIR_SHORT; + type = PACK_TYPE_INTEGER; + size = 2; + flags |= PACK_FLAG_SIGNED; + break; + case 'U': + dir = PACK_DIR_UTF8; + type = PACK_TYPE_INTEGER; + break; + case 'V': /* = "L<" */ + dir = PACK_DIR_LONG; + type = PACK_TYPE_INTEGER; + size = 4; + flags |= PACK_FLAG_LT; + break; + case 'v': /* = "S<" */ + dir = PACK_DIR_SHORT; + type = PACK_TYPE_INTEGER; + size = 2; + flags |= PACK_FLAG_LT; + break; + case 'Z': + dir = PACK_DIR_STR; + type = PACK_TYPE_STRING; + flags |= PACK_FLAG_WIDTH | PACK_FLAG_COUNT2 | PACK_FLAG_Z; + break; + default: + dir = PACK_DIR_INVALID; + type = PACK_TYPE_NONE; + break; + } + + /* read suffix [0-9*_!<>] */ + while (tmpl->idx < tlen) { + ch = tptr[tmpl->idx++]; + if (isdigit(ch)) { + count = ch - '0'; + while (tmpl->idx < tlen && isdigit(tptr[tmpl->idx])) { + count = count * 10 + (tptr[tmpl->idx++] - '0'); + } + continue; /* special case */ + } else if (ch == '*') { + count = -1; + } else if (ch == '_' || ch == '!' || ch == '<' || ch == '>') { + if (strchr("sSiIlLqQ", t) == NULL) { + char ch_str = ch; + mrb_raisef(mrb, E_ARGUMENT_ERROR, "'%S' allowed only after types sSiIlLqQ", mrb_str_new(mrb, &ch_str, 1)); + } + if (ch == '_' || ch == '!') { + flags |= PACK_FLAG_s; + } else if (ch == '<') { + flags |= PACK_FLAG_LT; + } else if (ch == '>') { + flags |= PACK_FLAG_GT; + } + } else { + tmpl->idx--; + break; + } + } + + if ((flags & PACK_FLAG_LT) || (!(flags & PACK_FLAG_GT) && littleendian)) { + flags |= PACK_FLAG_LITTLEENDIAN; + } + + *dirp = dir; + *typep = type; + *sizep = size; + *countp = count; + *flagsp = flags; +} + +static mrb_value +mrb_pack_pack(mrb_state *mrb, mrb_value ary) +{ + mrb_value o, result; + mrb_int aidx; + struct tmpl tmpl; + long count; + unsigned int flags; + int dir, ridx, size, type; + + prepare_tmpl(mrb, &tmpl); + + result = mrb_str_new(mrb, NULL, 128); /* allocate initial buffer */ + aidx = 0; + ridx = 0; + while (has_tmpl(&tmpl)) { + read_tmpl(mrb, &tmpl, &dir, &type, &size, &count, &flags); + + if (dir == PACK_DIR_INVALID) + continue; + + for (; aidx < RARRAY_LEN(ary); aidx++) { + if (count == 0 && !(flags & PACK_FLAG_WIDTH)) + break; + + o = mrb_ary_ref(mrb, ary, aidx); + if (type == PACK_TYPE_INTEGER) { + if (mrb_float_p(o)) { + o = mrb_funcall(mrb, o, "to_i", 0); + } else if (!mrb_fixnum_p(o)) { + mrb_raisef(mrb, E_TYPE_ERROR, "can't convert %S into Integer", mrb_class_path(mrb, mrb_obj_class(mrb, o))); + } + } else if (type == PACK_TYPE_FLOAT) { + if (!mrb_float_p(o)) { + o = mrb_funcall(mrb, o, "to_f", 0); + } + } else if (type == PACK_TYPE_STRING) { + if (!mrb_string_p(o)) { + mrb_raisef(mrb, E_TYPE_ERROR, "can't convert %S into String", mrb_class_path(mrb, mrb_obj_class(mrb, o))); + } + } + + switch (dir) { + case PACK_DIR_CHAR: + ridx += pack_c(mrb, o, result, ridx, flags); + break; + case PACK_DIR_SHORT: + ridx += pack_s(mrb, o, result, ridx, flags); + break; + case PACK_DIR_LONG: + ridx += pack_l(mrb, o, result, ridx, flags); + break; + case PACK_DIR_QUAD: + ridx += pack_q(mrb, o, result, ridx, flags); + break; + case PACK_DIR_BASE64: + ridx += pack_m(mrb, o, result, ridx, count, flags); + break; + case PACK_DIR_HEX: + ridx += pack_h(mrb, o, result, ridx, count, flags); + break; + case PACK_DIR_STR: + ridx += pack_a(mrb, o, result, ridx, count, flags); + break; + case PACK_DIR_DOUBLE: + ridx += pack_double(mrb, o, result, ridx, flags); + break; + case PACK_DIR_FLOAT: + ridx += pack_float(mrb, o, result, ridx, flags); + break; + case PACK_DIR_UTF8: + ridx += pack_utf8(mrb, o, result, ridx, count, flags); + break; + default: + break; + } + if (dir == PACK_DIR_STR) { /* always consumes 1 entry */ + aidx++; + break; + } + if (count > 0) { + count--; + } + } + } + + mrb_str_resize(mrb, result, ridx); + return result; +} + +static mrb_value +mrb_pack_unpack(mrb_state *mrb, mrb_value str) +{ + mrb_value result; + struct tmpl tmpl; + long count; + unsigned int flags; + int dir, size, srcidx, srclen, type; + const unsigned char *sptr; + + prepare_tmpl(mrb, &tmpl); + + srcidx = 0; + srclen = RSTRING_LEN(str); + + result = mrb_ary_new(mrb); + while (has_tmpl(&tmpl)) { + read_tmpl(mrb, &tmpl, &dir, &type, &size, &count, &flags); + + if (dir == PACK_DIR_INVALID) + continue; + + if (flags & PACK_FLAG_COUNT2) { + sptr = (const unsigned char *)RSTRING_PTR(str) + srcidx; + switch (dir) { + case PACK_DIR_HEX: + srcidx += unpack_h(mrb, sptr, srclen - srcidx, result, count, flags); + break; + case PACK_DIR_STR: + srcidx += unpack_a(mrb, sptr, srclen - srcidx, result, count, flags); + break; + } + continue; + } + + while (count != 0) { + if (srclen - srcidx < size) { + while (count-- > 0) { + mrb_ary_push(mrb, result, mrb_nil_value()); + } + break; + } + + sptr = (const unsigned char *)RSTRING_PTR(str) + srcidx; + switch (dir) { + case PACK_DIR_CHAR: + srcidx += unpack_c(mrb, sptr, srclen - srcidx, result, flags); + break; + case PACK_DIR_SHORT: + srcidx += unpack_s(mrb, sptr, srclen - srcidx, result, flags); + break; + case PACK_DIR_LONG: + srcidx += unpack_l(mrb, sptr, srclen - srcidx, result, flags); + break; + case PACK_DIR_QUAD: + srcidx += unpack_q(mrb, sptr, srclen - srcidx, result, flags); + break; + case PACK_DIR_BASE64: + srcidx += unpack_m(mrb, sptr, srclen - srcidx, result, flags); + break; + case PACK_DIR_FLOAT: + srcidx += unpack_float(mrb, sptr, srclen - srcidx, result, flags); + break; + case PACK_DIR_DOUBLE: + srcidx += unpack_double(mrb, sptr, srclen - srcidx, result, flags); + break; + } + if (count > 0) { + count--; + } + } + } + + return result; +} + +void +mrb_mruby_pack_gem_init(mrb_state *mrb) +{ + littleendian = check_little_endian(); + make_base64_dec_tab(); + + mrb_define_method(mrb, mrb->array_class, "pack", mrb_pack_pack, MRB_ARGS_REQ(1)); + mrb_define_method(mrb, mrb->string_class, "unpack", mrb_pack_unpack, MRB_ARGS_REQ(1)); +} + +void +mrb_mruby_pack_gem_final(mrb_state *mrb) +{ +} diff --git a/web/server/h2o/libh2o/deps/mruby-pack/test/pack.rb b/web/server/h2o/libh2o/deps/mruby-pack/test/pack.rb new file mode 100644 index 00000000..5e9932f4 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby-pack/test/pack.rb @@ -0,0 +1,147 @@ +# pack & unpack 'm' (base64) +assert('[""].pack("m")') do + ary = "" + str = "" + [ary].pack("m") == str and + str.unpack("m") == [ary] +end + +assert('["\0"].pack("m")') do + ary = "\0" + str = "AA==\n" + [ary].pack("m") == str and + str.unpack("m") == [ary] +end + +assert('["\0\0"].pack("m")') do + ary = "\0\0" + str = "AAA=\n" + [ary].pack("m") == str and + str.unpack("m") == [ary] +end + +assert('["\0\0\0"].pack("m")') do + ary = "\0\0\0" + str = "AAAA\n" + [ary].pack("m") == str and + str.unpack("m") == [ary] +end + +assert('["abc..xyzABC..XYZ"].pack("m")') do + ["abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"].pack("m") == "YWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXpBQkNERUZHSElKS0xNTk9QUVJT\nVFVWV1hZWg==\n" +end + +assert('"YWJ...".unpack("m") should "abc..xyzABC..XYZ"') do + str = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" + "YWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXpBQkNERUZHSElKS0xNTk9QUVJT\nVFVWV1hZWg==\n".unpack("m") == [str] and + "YWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXpBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWg==\n".unpack("m") == [str] +end + +# pack & unpack 'H' +assert('["3031"].pack("H*")') do + ary = "3031" + str = "01" + [ary].pack("H*") == str and + str.unpack("H*") == [ary] +end + +assert('["10"].pack("H*")') do + ary = "10" + str = "\020" + [ary].pack("H*") == str and + str.unpack("H*") == [ary] +end + +assert('[0,1,127,128,255].pack("C*")') do + ary = [ 0, 1, 127, 128, 255 ] + str = "\x00\x01\x7F\x80\xFF" + ary.pack("C*") == str and str.unpack("C*") == ary +end + +# pack "a" +assert('["abc"].pack("a")') do + ["abc"].pack("a") == "a" and + ["abc"].pack("a*") == "abc" and + ["abc"].pack("a4") == "abc\0" +end + +# upack "a" +assert('["abc"].pack("a")') do + "abc\0".unpack("a4") == ["abc\0"] and + "abc ".unpack("a4") == ["abc "] +end + +# pack "A" +assert('["abc"].pack("A")') do + ["abc"].pack("A") == "a" and + ["abc"].pack("A*") == "abc" and + ["abc"].pack("A4") == "abc " +end + +# upack "A" +assert('["abc"].pack("A")') do + "abc\0".unpack("A4") == ["abc"] and + "abc ".unpack("A4") == ["abc"] +end + +# regression tests +assert('issue #1') do + [1, 2].pack("nn") == "\000\001\000\002" +end + +def assert_pack tmpl, packed, unpacked + assert_equal packed, unpacked.pack(tmpl) + assert_equal unpacked, packed.unpack(tmpl) +end + +PACK_IS_LITTLE_ENDIAN = "\x01\00".unpack('S')[0] == 0x01 + +assert 'pack float' do + assert_pack 'e', "\x00\x00@@", [3.0] + assert_pack 'g', "@@\x00\x00", [3.0] + + if PACK_IS_LITTLE_ENDIAN + assert_pack 'f', "\x00\x00@@", [3.0] + assert_pack 'F', "\x00\x00@@", [3.0] + else + assert_pack 'f', "@@\x00\x00", [3.0] + assert_pack 'F', "@@\x00\x00", [3.0] + end +end + +assert 'pack double' do + assert_pack 'E', "\x00\x00\x00\x00\x00\x00\b@", [3.0] + assert_pack 'G', "@\b\x00\x00\x00\x00\x00\x00", [3.0] + + if PACK_IS_LITTLE_ENDIAN + assert_pack 'd', "\x00\x00\x00\x00\x00\x00\b@", [3.0] + assert_pack 'D', "\x00\x00\x00\x00\x00\x00\b@", [3.0] + else + assert_pack 'd', "@\b\x00\x00\x00\x00\x00\x00", [3.0] + assert_pack 'D', "@\b\x00\x00\x00\x00\x00\x00", [3.0] + end +end + +assert 'pack/unpack "i"' do + int_size = [0].pack('i').size + raise "pack('i').size is too small (#{int_size})" if int_size < 2 + + if PACK_IS_LITTLE_ENDIAN + str = "\xC7\xCF" + "\xFF" * (int_size-2) + else + str = "\xFF" * (int_size-2) + "\xC7\xCF" + end + assert_pack 'i', str, [-12345] +end + +assert 'pack/unpack "I"' do + uint_size = [0].pack('I').size + raise "pack('I').size is too small (#{uint_size})" if uint_size < 2 + + if PACK_IS_LITTLE_ENDIAN + str = "\x39\x30" + "\0" * (uint_size-2) + else + str = "\0" * (uint_size-2) + "\x39\x30" + end + assert_pack 'I', str, [12345] +end diff --git a/web/server/h2o/libh2o/deps/mruby-require/.gitignore b/web/server/h2o/libh2o/deps/mruby-require/.gitignore new file mode 100644 index 00000000..ceeb05b4 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby-require/.gitignore @@ -0,0 +1 @@ +/tmp diff --git a/web/server/h2o/libh2o/deps/mruby-require/.travis.yml b/web/server/h2o/libh2o/deps/mruby-require/.travis.yml new file mode 100644 index 00000000..ffe22728 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby-require/.travis.yml @@ -0,0 +1,2 @@ +script: + - "ruby run_test.rb all test" diff --git a/web/server/h2o/libh2o/deps/mruby-require/README.md b/web/server/h2o/libh2o/deps/mruby-require/README.md new file mode 100644 index 00000000..70818ffb --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby-require/README.md @@ -0,0 +1,59 @@ +mruby-require +============= + +"mruby-require" is a mrbgem, provides +[require](http://docs.ruby-lang.org/ja/2.0.0/class/Kernel.html#M_REQUIRE) and +[load](http://docs.ruby-lang.org/ja/2.0.0/class/Kernel.html#M_LOAD) for mruby. + +### Example: + +```Ruby +# a.rb + +require "b" + +b = Bclass.new +p b.method +``` +```Ruby +# b.rb + +class Bclass + def method + "BBB" + end +end +``` +```sh +% mruby a.rb +"BBB" +``` + + +### To run the tests: + + ruby run_test.rb + + +## License + +Copyright (c) 2013 Internet Initiative Japan Inc. + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the "Software"), +to deal in the Software without restriction, including without limitation +the rights to use, copy, modify, merge, publish, distribute, sublicense, +and/or sell copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. + diff --git a/web/server/h2o/libh2o/deps/mruby-require/mrbgem.rake b/web/server/h2o/libh2o/deps/mruby-require/mrbgem.rake new file mode 100644 index 00000000..e95cdb8c --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby-require/mrbgem.rake @@ -0,0 +1,15 @@ +MRuby::Gem::Specification.new('mruby-require') do |spec| + spec.license = 'MIT' + spec.authors = 'Internet Initiative Japan Inc.' + + spec.add_dependency 'mruby-array-ext' + spec.add_dependency 'mruby-dir' + spec.add_dependency 'mruby-io' +# only used for testing? +# spec.add_dependency 'mruby-tempfile' + spec.add_dependency 'mruby-time' + spec.add_dependency 'mruby-eval' + + spec.cc.include_paths << "#{build.root}/src" +end + diff --git a/web/server/h2o/libh2o/deps/mruby-require/mrblib/require.rb b/web/server/h2o/libh2o/deps/mruby-require/mrblib/require.rb new file mode 100644 index 00000000..cdf25ace --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby-require/mrblib/require.rb @@ -0,0 +1,97 @@ +class LoadError < ScriptError; end + +begin + eval "1", nil + def _require_eval_load(*args) + self.eval(*args) + end +rescue ArgumentError + def _require_eval_load(*args) + self.eval(args[0]) + end +end + +module Kernel + def load(path) + raise TypeError unless path.class == String + + if File.exist?(path) && File.extname(path) == ".mrb" + _load_mrb_file path + elsif File.exist?(path) + # _load_rb_str File.open(path).read.to_s, path + _require_eval_load File.open(path).read.to_s, nil, path + else + raise LoadError.new "File not found -- #{path}" + end + + true + end + + def require(path) + raise TypeError unless path.class == String + + # require method can load .rb, .mrb or without-ext filename only. + unless ["", ".rb", ".mrb"].include? File.extname(path) + raise LoadError.new "cannot load such file -- #{path}" + end + + filenames = [] + if File.extname(path).size == 0 + filenames << "#{path}.rb" + filenames << "#{path}.mrb" + else + filenames << path + end + + dir = nil + filename = nil + if ['/', '.'].include? path[0] + path0 = filenames.find do |fname| + File.file?(fname) && File.exist?(fname) + end + else + dir = ($LOAD_PATH || []).find do |dir0| + filename = filenames.find do |fname| + path0 = File.join dir0, fname + File.file?(path0) && File.exist?(path0) + end + end + path0 = dir && filename ? File.join(dir, filename) : nil + end + + if path0 && File.exist?(path0) && File.file?(path0) + __require__ path0 + else + raise LoadError.new "cannot load such file -- #{path}" + end + end + + def __require__(realpath) + raise LoadError.new "File not found -- #{realpath}" unless File.exist? realpath + $" ||= [] + $__mruby_loading_files__ ||= [] + + # already required + return false if ($" + $__mruby_loading_files__).include?(realpath) + + $__mruby_loading_files__ << realpath + load realpath + $" << realpath + $__mruby_loading_files__.delete realpath + + true + end +end + + +$LOAD_PATH ||= [] +$LOAD_PATH << '.' + +if Object.const_defined?(:ENV) + $LOAD_PATH.unshift(*ENV['MRBLIB'].split(':')) unless ENV['MRBLIB'].nil? +end + +$LOAD_PATH.uniq! + +$" ||= [] +$__mruby_loading_files__ ||= [] diff --git a/web/server/h2o/libh2o/deps/mruby-require/run_test.rb b/web/server/h2o/libh2o/deps/mruby-require/run_test.rb new file mode 100644 index 00000000..2a99a9dd --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby-require/run_test.rb @@ -0,0 +1,29 @@ +#!/usr/bin/env ruby +# +# mrbgems test runner +# + +if __FILE__ == $0 + repository, dir = 'https://github.com/mruby/mruby.git', 'tmp/mruby' + + build_args = ARGV + + Dir.mkdir 'tmp' unless File.exist?('tmp') + unless File.exist?(dir) + system "git clone #{repository} #{dir}" + end + + exit system(%Q[cd #{dir}; MRUBY_CONFIG=#{File.expand_path __FILE__} ruby minirake #{build_args.join(' ')}]) +end + +MRuby::Build.new do |conf| + toolchain :gcc + conf.gembox 'default' + + conf.gem :core => 'mruby-eval' + conf.gem :git => 'https://github.com/iij/mruby-io.git' + conf.gem :git => 'https://github.com/iij/mruby-dir.git' + conf.gem :git => 'https://github.com/iij/mruby-tempfile.git' + + conf.gem File.expand_path(File.dirname(__FILE__)) +end diff --git a/web/server/h2o/libh2o/deps/mruby-require/src/require.c b/web/server/h2o/libh2o/deps/mruby-require/src/require.c new file mode 100644 index 00000000..0f48c037 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby-require/src/require.c @@ -0,0 +1,208 @@ +#if !(defined(_WIN32) || defined(_WIN64)) +#include +#endif +#include +#include +#include + +#include "mruby.h" +#include "mruby/compile.h" +#include "mruby/dump.h" +#include "mruby/string.h" +#include "mruby/proc.h" + +#include "opcode.h" +#include "error.h" + +#include +#include + +#define E_LOAD_ERROR (mrb_class_get(mrb, "LoadError")) + +#if MRUBY_RELEASE_NO < 10000 +mrb_value mrb_yield_internal(mrb_state *mrb, mrb_value b, int argc, mrb_value *argv, mrb_value self, struct RClass *c); +#define mrb_yield_with_class mrb_yield_internal +#endif + +#if defined(_WIN32) || defined(_WIN64) + #include + int mkstemp(char *template) + { + DWORD pathSize; + char pathBuffer[1000]; + char tempFilename[MAX_PATH]; + UINT uniqueNum; + pathSize = GetTempPath(1000, pathBuffer); + if (pathSize < 1000) { pathBuffer[pathSize] = 0; } + else { pathBuffer[0] = 0; } + uniqueNum = GetTempFileName(pathBuffer, template, 0, tempFilename); + if (uniqueNum == 0) return -1; + strncpy(template, tempFilename, MAX_PATH); + return open(tempFilename, _O_RDWR|_O_BINARY); + } +#endif + +static void +replace_stop_with_return(mrb_state *mrb, mrb_irep *irep) +{ + if (irep->iseq[irep->ilen - 1] == MKOP_A(OP_STOP, 0)) { + irep->iseq = mrb_realloc(mrb, irep->iseq, (irep->ilen + 1) * sizeof(mrb_code)); + irep->iseq[irep->ilen - 1] = MKOP_A(OP_LOADNIL, 0); + irep->iseq[irep->ilen] = MKOP_AB(OP_RETURN, 0, OP_R_NORMAL); + irep->ilen++; + } +} + +static int +compile_rb2mrb(mrb_state *mrb0, const char *code, int code_len, const char *path, FILE* tmpfp) +{ + mrb_state *mrb = mrb_open(); + mrb_value result; + mrbc_context *c; + int ret = -1; + int debuginfo = 1; + mrb_irep *irep; + + c = mrbc_context_new(mrb); + c->no_exec = 1; + if (path != NULL) { + mrbc_filename(mrb, c, path); + } + + result = mrb_load_nstring_cxt(mrb, code, code_len, c); + if (mrb_undef_p(result)) { + mrbc_context_free(mrb, c); + mrb_close(mrb); + return MRB_DUMP_GENERAL_FAILURE; + } + + irep = mrb_proc_ptr(result)->body.irep; + ret = mrb_dump_irep_binary(mrb, irep, debuginfo, tmpfp); + + mrbc_context_free(mrb, c); + mrb_close(mrb); + + return ret; +} + +static void +eval_load_irep(mrb_state *mrb, mrb_irep *irep) +{ + int ai; + struct RProc *proc; + + replace_stop_with_return(mrb, irep); + proc = mrb_proc_new(mrb, irep); + proc->target_class = mrb->object_class; + + ai = mrb_gc_arena_save(mrb); + mrb_yield_with_class(mrb, mrb_obj_value(proc), 0, NULL, mrb_top_self(mrb), mrb->object_class); + mrb_gc_arena_restore(mrb, ai); +} + +static mrb_value +mrb_require_load_rb_str(mrb_state *mrb, mrb_value self) +{ + char *path_ptr = NULL; +#if defined(_WIN32) || defined(_WIN64) + char tmpname[MAX_PATH] = "tmp.XXXXXXXX"; +#else + char tmpname[] = "tmp.XXXXXXXX"; +#endif + mode_t mask; + FILE *tmpfp = NULL; + int fd = -1, ret; + mrb_irep *irep; + mrb_value code, path = mrb_nil_value(); + + mrb_get_args(mrb, "S|S", &code, &path); + if (!mrb_string_p(path)) { + path = mrb_str_new_cstr(mrb, "-"); + } + path_ptr = mrb_str_to_cstr(mrb, path); + + mask = umask(077); + fd = mkstemp(tmpname); + if (fd == -1) { + mrb_sys_fail(mrb, "can't create mkstemp() at mrb_require_load_rb_str"); + } + umask(mask); + + tmpfp = fdopen(fd, "r+"); + if (tmpfp == NULL) { + close(fd); + mrb_sys_fail(mrb, "can't open temporay file at mrb_require_load_rb_str"); + } + + ret = compile_rb2mrb(mrb, RSTRING_PTR(code), RSTRING_LEN(code), path_ptr, tmpfp); + if (ret != MRB_DUMP_OK) { + fclose(tmpfp); + remove(tmpname); + mrb_raisef(mrb, E_LOAD_ERROR, "can't load file -- %S", path); + return mrb_nil_value(); + } + + rewind(tmpfp); + irep = mrb_read_irep_file(mrb, tmpfp); + fclose(tmpfp); + remove(tmpname); + + if (irep) { + eval_load_irep(mrb, irep); + } else if (mrb->exc) { + // fail to load + longjmp(*(jmp_buf*)mrb->jmp, 1); + } else { + mrb_raisef(mrb, E_LOAD_ERROR, "can't load file -- %S", path); + return mrb_nil_value(); + } + + return mrb_true_value(); +} + +static mrb_value +mrb_require_load_mrb_file(mrb_state *mrb, mrb_value self) +{ + char *path_ptr = NULL; + FILE *fp = NULL; + mrb_irep *irep; + mrb_value path; + + mrb_get_args(mrb, "S", &path); + path_ptr = mrb_str_to_cstr(mrb, path); + + fp = fopen(path_ptr, "rb"); + if (fp == NULL) { + mrb_raisef(mrb, E_LOAD_ERROR, "can't open file -- %S", path); + } + + irep = mrb_read_irep_file(mrb, fp); + fclose(fp); + + if (irep) { + eval_load_irep(mrb, irep); + } else if (mrb->exc) { + // fail to load + longjmp(*(jmp_buf*)mrb->jmp, 1); + } else { + mrb_raisef(mrb, E_LOAD_ERROR, "can't load file -- %S", path); + return mrb_nil_value(); + } + + return mrb_true_value(); +} + +void +mrb_mruby_require_gem_init(mrb_state *mrb) +{ + struct RClass *krn; + krn = mrb->kernel_module; + + mrb_define_method(mrb, krn, "_load_rb_str", mrb_require_load_rb_str, MRB_ARGS_ANY()); + mrb_define_method(mrb, krn, "_load_mrb_file", mrb_require_load_mrb_file, MRB_ARGS_REQ(1)); +} + +void +mrb_mruby_require_gem_final(mrb_state *mrb) +{ +} diff --git a/web/server/h2o/libh2o/deps/mruby-require/test/d/required.rb b/web/server/h2o/libh2o/deps/mruby-require/test/d/required.rb new file mode 100644 index 00000000..d6218cd0 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby-require/test/d/required.rb @@ -0,0 +1,19 @@ +# global variables +$gvar0 = 1 +$gvar1 = 1 + +# toplevel local variables +lvar0 = 1 +lvar1 = 1 + +# define a procedure +def proc0 + :proc0 +end + +# define a new method of an existing class. +class MrubyRequireClass + def foo + :foo + end +end diff --git a/web/server/h2o/libh2o/deps/mruby-require/test/require.rb b/web/server/h2o/libh2o/deps/mruby-require/test/require.rb new file mode 100644 index 00000000..95e1ef02 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby-require/test/require.rb @@ -0,0 +1,28 @@ +assert("Kernel.require") do + # see d/required.rb + $gvar1 = 0 + lvar1 = 0 + class MrubyRequireClass; end + + assert_true require(File.join(File.dirname(__FILE__), "d", "required.rb")) + + # Kernel.require can create a global variable + assert_equal 1, $gvar0 + + # Kernel.require can change value of a global variable + assert_equal 1, $gvar1 + + # Kernel.require cannot create a local variable + assert_raise(NoMethodError) do + lvar0 + end + + # Kernel.require cannot change value of a local variable + assert_equal 0, lvar1 + + # Kernel.require can define a toplevel procedure + assert_equal :proc0, proc0 + + # Kernel.require can add a method to an existing class + assert_equal :foo, MrubyRequireClass.new.foo +end diff --git a/web/server/h2o/libh2o/deps/mruby-require/test/test.rb b/web/server/h2o/libh2o/deps/mruby-require/test/test.rb new file mode 100644 index 00000000..0886cabe --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby-require/test/test.rb @@ -0,0 +1,34 @@ +$" = [] # init + +assert "Kernel#_load_rb_str" do + assert_equal true, self.methods.include?(:_load_rb_str) + assert_equal false, Object.const_defined?(:LOAD_RB_STR_TEST) + _load_rb_str("LOAD_RB_STR_TEST = 1") + assert_equal true, Object.const_defined?(:LOAD_RB_STR_TEST) +end + +assert "$LOAD_PATH check" do + assert_equal Array, $LOAD_PATH.class +end + +assert '$" check' do + assert_equal [], $" +end + +assert('load - error check') do + assert_raise TypeError, "load(nil) should raise TypeError" do + load nil + end + assert_raise LoadError, "load('notfound') should raise LoadError" do + load 'notfound' + end +end + +assert('require - error check') do + assert_raise TypeError, "require(nil) should raise TypeError" do + require nil + end + assert_raise LoadError, "require('notfound') should raise LoadError" do + require "notfound" + end +end diff --git a/web/server/h2o/libh2o/deps/mruby-require/test/test2.rb b/web/server/h2o/libh2o/deps/mruby-require/test/test2.rb new file mode 100644 index 00000000..b66b9fdf --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby-require/test/test2.rb @@ -0,0 +1,139 @@ +$dir = File.join(Dir.tmpdir, "mruby-require-test-#{Time.now.to_i}.#{Time.now.usec}") + +def test_setup + Dir.mkdir($dir) unless File.exist?($dir) + + File.open(File.join($dir, "test.rb"), "w") do |fp| + fp.puts "$require_test_variable = 123" + end + + File.open(File.join($dir, "test_dir.rb"), "w") do |fp| + fp.puts "$test_dir = 'test_dir'" + end + Dir.mkdir(File.join($dir, "test_dir")) + File.open(File.join($dir, "test_dir", "test_dir.rb"), "w") do |fp| + fp.puts "$test_dir2 = 'test_dir/test_dir'" + end + + File.open(File.join($dir, "test_conf.conf"), "w") do |fp| + fp.puts "$test_conf = 'test_conf'" + end + + File.open(File.join($dir, "empty.rb"), "w") + + test_reset +end + +def test_reset + $require_test_variable = nil + $test_dir = nil + $test_dir2 = nil + $test_conf = nil + $LOAD_PATH = [$dir] + $" = [] +end + +def remove_file_recursive(path) + if File.directory? path + Dir.entries(path).each do |entry| + next if ['.', '..'].include?(entry) + remove_file_recursive File.join(path, entry) + end + Dir.unlink path + else + File.unlink path + end +end + +def test_cleanup + if $dir && File.exist?($dir) + remove_file_recursive $dir + end +end + +##### +test_setup +##### + +assert("require 'test' should be success") do + test_reset + + assert_true require("test"), "require returns true when success" + assert_equal [File.join($dir, "test.rb")], $" + assert_equal 123, $require_test_variable + $require_test_variable = 789 + assert_false require("test"), "2nd require should returns false" + assert_equal 789, $require_test_variable + + test_reset + + assert_true require("test.rb"), "require should be success with '.rb'" + assert_equal [File.join($dir, "test.rb")], $" +end + +assert("require with absolute path should be success") do + test_reset + assert_true require(File.join($dir, "test")) + assert_equal [File.join($dir, "test.rb")], $" + + test_reset + assert_true require(File.join($dir, "test.rb")) + assert_equal [File.join($dir, "test.rb")], $" +end + +assert("require with absolute path && empty load_path") do + test_reset + $LOAD_PATH = [] + + assert_raise LoadError, "cannot load test.rb" do + require "test" + end + assert_equal true, require(File.join($dir, "test")) +end + +assert("require 'test_dir' should be success") do + test_reset + + assert_true require("test_dir"), "require 'test_dir' should be load 'test_dir.rb'" + assert_equal [File.join($dir, "test_dir.rb")], $" + assert_true require("test_dir/test_dir"), "require 'test_dir/test_dir' should be success" + assert_equal 'test_dir/test_dir', $test_dir2 +end + +assert("require 'test_conf' should be fail") do + test_reset + + assert_raise LoadError, "require 'test_conf.conf' should be fail" do + require("test_conf.conf") + end + assert_raise LoadError, "require method can't load *.conf" do + require File.join($dir, "test_conf.conf") + end +end + +assert("require 'empty' should be success") do + test_reset + + assert_true require("empty") + assert_equal 0, File.size(File.join($dir, "empty.rb")) +end + +assert("load 'test.rb' should be success") do + test_reset + + assert_true load(File.join($dir, "test.rb")) + assert_equal 123, $require_test_variable + assert_true $".empty? +end + +assert("load 'test_conf.conf' should be success") do + test_reset + + assert_equal true, load(File.join($dir, "test_conf.conf")) + assert_equal "test_conf", $test_conf +end + + +##### +test_cleanup +##### diff --git a/web/server/h2o/libh2o/deps/mruby-require/test/test_context.rb b/web/server/h2o/libh2o/deps/mruby-require/test/test_context.rb new file mode 100644 index 00000000..00117474 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby-require/test/test_context.rb @@ -0,0 +1,33 @@ +$dir = File.join(Dir.tmpdir, "mruby-require-test-#{Time.now.to_i}.#{Time.now.usec}") + +def test_setup + Dir.mkdir($dir) unless File.exist?($dir) + + File.open(File.join($dir, "foo.rb"), "w") do |f| + f.puts "$require_context = self" + end +end + +def test_cleanup + if $dir && File.exist?($dir) + Dir.entries($dir).each do |e| + next if ['.', '..'].include? e + File.unlink File.join($dir,e) + end + Dir.unlink $dir + end +end + + +##### +test_setup +##### + +assert("require context") do + require File.join($dir, 'foo.rb') + assert_equal self, $require_context +end + +##### +test_cleanup +##### diff --git a/web/server/h2o/libh2o/deps/mruby-require/test/test_nest_loop.rb b/web/server/h2o/libh2o/deps/mruby-require/test/test_nest_loop.rb new file mode 100644 index 00000000..c5a4b18b --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby-require/test/test_nest_loop.rb @@ -0,0 +1,58 @@ +$dir = File.join(Dir.tmpdir, "mruby-require-test-#{Time.now.to_i}.#{Time.now.usec}") + +def test_setup + Dir.mkdir($dir) + + File.open(File.join($dir, "loop1.rb"), "w") do |fp| + fp.puts "require 'loop2.rb'" + fp.puts "$loop1 = 'loop1'" + end + File.open(File.join($dir, "loop2.rb"), "w") do |fp| + fp.puts "require 'loop1.rb'" + fp.puts "$loop2 = 'loop2'" + end + + $require_test_count = 10 + (1..$require_test_count-1).each do |i| + File.open(File.join($dir, "#{i+1}.rb"), "w") do |fp| + fp.puts "require '#{i}'" + fp.puts "s = 0" + (0..100).each{|num| fp.puts "s += #{num}" } + end + end + File.open(File.join($dir, "1.rb"), "w") do |fp| + fp.puts "$require_test_0 = 123" + end + + $LOAD_PATH = [$dir] +end + +def test_cleanup + if $dir && File.exist?($dir) + Dir.entries($dir).each do |e| + next if ['.', '..'].include? e + File.unlink File.join($dir,e) + end + Dir.unlink $dir + end +end + +##### +test_setup +##### + +assert("require loop check") do + require 'loop1' + assert_equal 'loop1', $loop1 + assert_equal 'loop2', $loop2 +end + +assert("require nest") do + before = $".size + require "#{$require_test_count}" + assert_equal before + $require_test_count, $".size +end + +##### +test_cleanup +##### diff --git a/web/server/h2o/libh2o/deps/mruby/.gitignore b/web/server/h2o/libh2o/deps/mruby/.gitignore new file mode 100644 index 00000000..4af3005e --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/.gitignore @@ -0,0 +1,26 @@ +# / +*.bak +*.d +*.o +/benchmark/**/*.dat +/benchmark/*.pdf +/benchmark/*.png +*.orig +*.pdb +*.rej +*.sav +*.swp +*.tmp +*~ +.DS_Store +.ccmalloc +.svn +/.git +cscope.out +tags +/src/y.tab.c +/bin +/build +/mruby-source-*.gem +doc/api +.yardoc diff --git a/web/server/h2o/libh2o/deps/mruby/.gitlab-ci.yml b/web/server/h2o/libh2o/deps/mruby/.gitlab-ci.yml new file mode 100644 index 00000000..8f417923 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/.gitlab-ci.yml @@ -0,0 +1,3214 @@ +--- +stages: +- pretest +- test +pretest: + stage: pretest + image: registry.gitlab.com/dabroz/mruby:gcc47_0.1 + tags: + - linux + variables: + CC: gcc-4.7 + CXX: g++-4.7 + LD: gcc-4.7 + script: "./minirake all test" +Test gcc-4.7 32bit: + stage: test + image: registry.gitlab.com/dabroz/mruby:gcc47_0.7 + variables: + CC: gcc-4.7 + CXX: g++-4.7 + LD: gcc-4.7 + CFLAGS: "-m32 -DMRB_WORD_BOXING=1" + LDFLAGS: "-m32" + script: env; ./minirake --verbose all test +Test gcc-4.7 32bit_utf8: + stage: test + image: registry.gitlab.com/dabroz/mruby:gcc47_0.7 + variables: + CC: gcc-4.7 + CXX: g++-4.7 + LD: gcc-4.7 + CFLAGS: "-m32 -DMRB_WORD_BOXING=1 -DMRB_UTF8_STRING=1" + LDFLAGS: "-m32" + script: env; ./minirake --verbose all test +Test gcc-4.7 32bit_nan: + stage: test + image: registry.gitlab.com/dabroz/mruby:gcc47_0.7 + variables: + CC: gcc-4.7 + CXX: g++-4.7 + LD: gcc-4.7 + CFLAGS: "-m32 -DMRB_NAN_BOXING=1" + LDFLAGS: "-m32" + script: env; ./minirake --verbose all test +Test gcc-4.7 32bit_nan_utf8: + stage: test + image: registry.gitlab.com/dabroz/mruby:gcc47_0.7 + variables: + CC: gcc-4.7 + CXX: g++-4.7 + LD: gcc-4.7 + CFLAGS: "-m32 -DMRB_NAN_BOXING=1 -DMRB_UTF8_STRING=1" + LDFLAGS: "-m32" + script: env; ./minirake --verbose all test +Test gcc-4.7 32bit_int16: + stage: test + image: registry.gitlab.com/dabroz/mruby:gcc47_0.7 + variables: + CC: gcc-4.7 + CXX: g++-4.7 + LD: gcc-4.7 + CFLAGS: "-m32 -DMRB_INT16=1" + LDFLAGS: "-m32" + script: env; ./minirake --verbose all test +Test gcc-4.7 32bit_int16_utf8: + stage: test + image: registry.gitlab.com/dabroz/mruby:gcc47_0.7 + variables: + CC: gcc-4.7 + CXX: g++-4.7 + LD: gcc-4.7 + CFLAGS: "-m32 -DMRB_INT16=1 -DMRB_UTF8_STRING=1" + LDFLAGS: "-m32" + script: env; ./minirake --verbose all test +Test gcc-4.7 32bit_int16_nan: + stage: test + image: registry.gitlab.com/dabroz/mruby:gcc47_0.7 + variables: + CC: gcc-4.7 + CXX: g++-4.7 + LD: gcc-4.7 + CFLAGS: "-m32 -DMRB_INT16=1 -DMRB_NAN_BOXING=1" + LDFLAGS: "-m32" + script: env; ./minirake --verbose all test +Test gcc-4.7 32bit_int16_nan_utf8: + stage: test + image: registry.gitlab.com/dabroz/mruby:gcc47_0.7 + variables: + CC: gcc-4.7 + CXX: g++-4.7 + LD: gcc-4.7 + CFLAGS: "-m32 -DMRB_INT16=1 -DMRB_NAN_BOXING=1 -DMRB_UTF8_STRING=1" + LDFLAGS: "-m32" + script: env; ./minirake --verbose all test +Test gcc-4.7 32bit_int64: + stage: test + image: registry.gitlab.com/dabroz/mruby:gcc47_0.7 + variables: + CC: gcc-4.7 + CXX: g++-4.7 + LD: gcc-4.7 + CFLAGS: "-m32 -DMRB_INT64=1" + LDFLAGS: "-m32" + script: env; ./minirake --verbose all test +Test gcc-4.7 32bit_int64_utf8: + stage: test + image: registry.gitlab.com/dabroz/mruby:gcc47_0.7 + variables: + CC: gcc-4.7 + CXX: g++-4.7 + LD: gcc-4.7 + CFLAGS: "-m32 -DMRB_INT64=1 -DMRB_UTF8_STRING=1" + LDFLAGS: "-m32" + script: env; ./minirake --verbose all test +Test gcc-4.7 32bit_float: + stage: test + image: registry.gitlab.com/dabroz/mruby:gcc47_0.7 + variables: + CC: gcc-4.7 + CXX: g++-4.7 + LD: gcc-4.7 + CFLAGS: "-m32 -DMRB_USE_FLOAT=1 -DMRB_WORD_BOXING=1" + LDFLAGS: "-m32" + script: env; ./minirake --verbose all test +Test gcc-4.7 32bit_float_utf8: + stage: test + image: registry.gitlab.com/dabroz/mruby:gcc47_0.7 + variables: + CC: gcc-4.7 + CXX: g++-4.7 + LD: gcc-4.7 + CFLAGS: "-m32 -DMRB_USE_FLOAT=1 -DMRB_WORD_BOXING=1 -DMRB_UTF8_STRING=1" + LDFLAGS: "-m32" + script: env; ./minirake --verbose all test +Test gcc-4.7 32bit_float_int16: + stage: test + image: registry.gitlab.com/dabroz/mruby:gcc47_0.7 + variables: + CC: gcc-4.7 + CXX: g++-4.7 + LD: gcc-4.7 + CFLAGS: "-m32 -DMRB_USE_FLOAT=1 -DMRB_INT16=1" + LDFLAGS: "-m32" + script: env; ./minirake --verbose all test +Test gcc-4.7 32bit_float_int16_utf8: + stage: test + image: registry.gitlab.com/dabroz/mruby:gcc47_0.7 + variables: + CC: gcc-4.7 + CXX: g++-4.7 + LD: gcc-4.7 + CFLAGS: "-m32 -DMRB_USE_FLOAT=1 -DMRB_INT16=1 -DMRB_UTF8_STRING=1" + LDFLAGS: "-m32" + script: env; ./minirake --verbose all test +Test gcc-4.7 32bit_float_int64: + stage: test + image: registry.gitlab.com/dabroz/mruby:gcc47_0.7 + variables: + CC: gcc-4.7 + CXX: g++-4.7 + LD: gcc-4.7 + CFLAGS: "-m32 -DMRB_USE_FLOAT=1 -DMRB_INT64=1" + LDFLAGS: "-m32" + script: env; ./minirake --verbose all test +Test gcc-4.7 32bit_float_int64_utf8: + stage: test + image: registry.gitlab.com/dabroz/mruby:gcc47_0.7 + variables: + CC: gcc-4.7 + CXX: g++-4.7 + LD: gcc-4.7 + CFLAGS: "-m32 -DMRB_USE_FLOAT=1 -DMRB_INT64=1 -DMRB_UTF8_STRING=1" + LDFLAGS: "-m32" + script: env; ./minirake --verbose all test +Test gcc-4.7 64bit: + stage: test + image: registry.gitlab.com/dabroz/mruby:gcc47_0.7 + variables: + CC: gcc-4.7 + CXX: g++-4.7 + LD: gcc-4.7 + CFLAGS: "-DMRB_WORD_BOXING=1" + LDFLAGS: '' + script: env; ./minirake --verbose all test +Test gcc-4.7 64bit_utf8: + stage: test + image: registry.gitlab.com/dabroz/mruby:gcc47_0.7 + variables: + CC: gcc-4.7 + CXX: g++-4.7 + LD: gcc-4.7 + CFLAGS: "-DMRB_WORD_BOXING=1 -DMRB_UTF8_STRING=1" + LDFLAGS: '' + script: env; ./minirake --verbose all test +Test gcc-4.7 64bit_nan: + stage: test + image: registry.gitlab.com/dabroz/mruby:gcc47_0.7 + variables: + CC: gcc-4.7 + CXX: g++-4.7 + LD: gcc-4.7 + CFLAGS: "-DMRB_NAN_BOXING=1" + LDFLAGS: '' + script: env; ./minirake --verbose all test +Test gcc-4.7 64bit_nan_utf8: + stage: test + image: registry.gitlab.com/dabroz/mruby:gcc47_0.7 + variables: + CC: gcc-4.7 + CXX: g++-4.7 + LD: gcc-4.7 + CFLAGS: "-DMRB_NAN_BOXING=1 -DMRB_UTF8_STRING=1" + LDFLAGS: '' + script: env; ./minirake --verbose all test +Test gcc-4.7 64bit_int16: + stage: test + image: registry.gitlab.com/dabroz/mruby:gcc47_0.7 + variables: + CC: gcc-4.7 + CXX: g++-4.7 + LD: gcc-4.7 + CFLAGS: "-DMRB_INT16=1" + LDFLAGS: '' + script: env; ./minirake --verbose all test +Test gcc-4.7 64bit_int16_utf8: + stage: test + image: registry.gitlab.com/dabroz/mruby:gcc47_0.7 + variables: + CC: gcc-4.7 + CXX: g++-4.7 + LD: gcc-4.7 + CFLAGS: "-DMRB_INT16=1 -DMRB_UTF8_STRING=1" + LDFLAGS: '' + script: env; ./minirake --verbose all test +Test gcc-4.7 64bit_int16_nan: + stage: test + image: registry.gitlab.com/dabroz/mruby:gcc47_0.7 + variables: + CC: gcc-4.7 + CXX: g++-4.7 + LD: gcc-4.7 + CFLAGS: "-DMRB_INT16=1 -DMRB_NAN_BOXING=1" + LDFLAGS: '' + script: env; ./minirake --verbose all test +Test gcc-4.7 64bit_int16_nan_utf8: + stage: test + image: registry.gitlab.com/dabroz/mruby:gcc47_0.7 + variables: + CC: gcc-4.7 + CXX: g++-4.7 + LD: gcc-4.7 + CFLAGS: "-DMRB_INT16=1 -DMRB_NAN_BOXING=1 -DMRB_UTF8_STRING=1" + LDFLAGS: '' + script: env; ./minirake --verbose all test +Test gcc-4.7 64bit_int64: + stage: test + image: registry.gitlab.com/dabroz/mruby:gcc47_0.7 + variables: + CC: gcc-4.7 + CXX: g++-4.7 + LD: gcc-4.7 + CFLAGS: "-DMRB_INT64=1 -DMRB_WORD_BOXING=1" + LDFLAGS: '' + script: env; ./minirake --verbose all test +Test gcc-4.7 64bit_int64_utf8: + stage: test + image: registry.gitlab.com/dabroz/mruby:gcc47_0.7 + variables: + CC: gcc-4.7 + CXX: g++-4.7 + LD: gcc-4.7 + CFLAGS: "-DMRB_INT64=1 -DMRB_WORD_BOXING=1 -DMRB_UTF8_STRING=1" + LDFLAGS: '' + script: env; ./minirake --verbose all test +Test gcc-4.7 64bit_float: + stage: test + image: registry.gitlab.com/dabroz/mruby:gcc47_0.7 + variables: + CC: gcc-4.7 + CXX: g++-4.7 + LD: gcc-4.7 + CFLAGS: "-DMRB_USE_FLOAT=1 -DMRB_WORD_BOXING=1" + LDFLAGS: '' + script: env; ./minirake --verbose all test +Test gcc-4.7 64bit_float_utf8: + stage: test + image: registry.gitlab.com/dabroz/mruby:gcc47_0.7 + variables: + CC: gcc-4.7 + CXX: g++-4.7 + LD: gcc-4.7 + CFLAGS: "-DMRB_USE_FLOAT=1 -DMRB_WORD_BOXING=1 -DMRB_UTF8_STRING=1" + LDFLAGS: '' + script: env; ./minirake --verbose all test +Test gcc-4.7 64bit_float_int16: + stage: test + image: registry.gitlab.com/dabroz/mruby:gcc47_0.7 + variables: + CC: gcc-4.7 + CXX: g++-4.7 + LD: gcc-4.7 + CFLAGS: "-DMRB_USE_FLOAT=1 -DMRB_INT16=1" + LDFLAGS: '' + script: env; ./minirake --verbose all test +Test gcc-4.7 64bit_float_int16_utf8: + stage: test + image: registry.gitlab.com/dabroz/mruby:gcc47_0.7 + variables: + CC: gcc-4.7 + CXX: g++-4.7 + LD: gcc-4.7 + CFLAGS: "-DMRB_USE_FLOAT=1 -DMRB_INT16=1 -DMRB_UTF8_STRING=1" + LDFLAGS: '' + script: env; ./minirake --verbose all test +Test gcc-4.7 64bit_float_int64: + stage: test + image: registry.gitlab.com/dabroz/mruby:gcc47_0.7 + variables: + CC: gcc-4.7 + CXX: g++-4.7 + LD: gcc-4.7 + CFLAGS: "-DMRB_USE_FLOAT=1 -DMRB_INT64=1 -DMRB_WORD_BOXING=1" + LDFLAGS: '' + script: env; ./minirake --verbose all test +Test gcc-4.7 64bit_float_int64_utf8: + stage: test + image: registry.gitlab.com/dabroz/mruby:gcc47_0.7 + variables: + CC: gcc-4.7 + CXX: g++-4.7 + LD: gcc-4.7 + CFLAGS: "-DMRB_USE_FLOAT=1 -DMRB_INT64=1 -DMRB_WORD_BOXING=1 -DMRB_UTF8_STRING=1" + LDFLAGS: '' + script: env; ./minirake --verbose all test +Test gcc-4.8 32bit: + stage: test + image: registry.gitlab.com/dabroz/mruby:gcc48_0.7 + variables: + CC: gcc-4.8 + CXX: g++-4.8 + LD: gcc-4.8 + CFLAGS: "-m32 -DMRB_WORD_BOXING=1" + LDFLAGS: "-m32" + script: env; ./minirake --verbose all test +Test gcc-4.8 32bit_utf8: + stage: test + image: registry.gitlab.com/dabroz/mruby:gcc48_0.7 + variables: + CC: gcc-4.8 + CXX: g++-4.8 + LD: gcc-4.8 + CFLAGS: "-m32 -DMRB_WORD_BOXING=1 -DMRB_UTF8_STRING=1" + LDFLAGS: "-m32" + script: env; ./minirake --verbose all test +Test gcc-4.8 32bit_nan: + stage: test + image: registry.gitlab.com/dabroz/mruby:gcc48_0.7 + variables: + CC: gcc-4.8 + CXX: g++-4.8 + LD: gcc-4.8 + CFLAGS: "-m32 -DMRB_NAN_BOXING=1" + LDFLAGS: "-m32" + script: env; ./minirake --verbose all test +Test gcc-4.8 32bit_nan_utf8: + stage: test + image: registry.gitlab.com/dabroz/mruby:gcc48_0.7 + variables: + CC: gcc-4.8 + CXX: g++-4.8 + LD: gcc-4.8 + CFLAGS: "-m32 -DMRB_NAN_BOXING=1 -DMRB_UTF8_STRING=1" + LDFLAGS: "-m32" + script: env; ./minirake --verbose all test +Test gcc-4.8 32bit_int16: + stage: test + image: registry.gitlab.com/dabroz/mruby:gcc48_0.7 + variables: + CC: gcc-4.8 + CXX: g++-4.8 + LD: gcc-4.8 + CFLAGS: "-m32 -DMRB_INT16=1" + LDFLAGS: "-m32" + script: env; ./minirake --verbose all test +Test gcc-4.8 32bit_int16_utf8: + stage: test + image: registry.gitlab.com/dabroz/mruby:gcc48_0.7 + variables: + CC: gcc-4.8 + CXX: g++-4.8 + LD: gcc-4.8 + CFLAGS: "-m32 -DMRB_INT16=1 -DMRB_UTF8_STRING=1" + LDFLAGS: "-m32" + script: env; ./minirake --verbose all test +Test gcc-4.8 32bit_int16_nan: + stage: test + image: registry.gitlab.com/dabroz/mruby:gcc48_0.7 + variables: + CC: gcc-4.8 + CXX: g++-4.8 + LD: gcc-4.8 + CFLAGS: "-m32 -DMRB_INT16=1 -DMRB_NAN_BOXING=1" + LDFLAGS: "-m32" + script: env; ./minirake --verbose all test +Test gcc-4.8 32bit_int16_nan_utf8: + stage: test + image: registry.gitlab.com/dabroz/mruby:gcc48_0.7 + variables: + CC: gcc-4.8 + CXX: g++-4.8 + LD: gcc-4.8 + CFLAGS: "-m32 -DMRB_INT16=1 -DMRB_NAN_BOXING=1 -DMRB_UTF8_STRING=1" + LDFLAGS: "-m32" + script: env; ./minirake --verbose all test +Test gcc-4.8 32bit_int64: + stage: test + image: registry.gitlab.com/dabroz/mruby:gcc48_0.7 + variables: + CC: gcc-4.8 + CXX: g++-4.8 + LD: gcc-4.8 + CFLAGS: "-m32 -DMRB_INT64=1" + LDFLAGS: "-m32" + script: env; ./minirake --verbose all test +Test gcc-4.8 32bit_int64_utf8: + stage: test + image: registry.gitlab.com/dabroz/mruby:gcc48_0.7 + variables: + CC: gcc-4.8 + CXX: g++-4.8 + LD: gcc-4.8 + CFLAGS: "-m32 -DMRB_INT64=1 -DMRB_UTF8_STRING=1" + LDFLAGS: "-m32" + script: env; ./minirake --verbose all test +Test gcc-4.8 32bit_float: + stage: test + image: registry.gitlab.com/dabroz/mruby:gcc48_0.7 + variables: + CC: gcc-4.8 + CXX: g++-4.8 + LD: gcc-4.8 + CFLAGS: "-m32 -DMRB_USE_FLOAT=1 -DMRB_WORD_BOXING=1" + LDFLAGS: "-m32" + script: env; ./minirake --verbose all test +Test gcc-4.8 32bit_float_utf8: + stage: test + image: registry.gitlab.com/dabroz/mruby:gcc48_0.7 + variables: + CC: gcc-4.8 + CXX: g++-4.8 + LD: gcc-4.8 + CFLAGS: "-m32 -DMRB_USE_FLOAT=1 -DMRB_WORD_BOXING=1 -DMRB_UTF8_STRING=1" + LDFLAGS: "-m32" + script: env; ./minirake --verbose all test +Test gcc-4.8 32bit_float_int16: + stage: test + image: registry.gitlab.com/dabroz/mruby:gcc48_0.7 + variables: + CC: gcc-4.8 + CXX: g++-4.8 + LD: gcc-4.8 + CFLAGS: "-m32 -DMRB_USE_FLOAT=1 -DMRB_INT16=1" + LDFLAGS: "-m32" + script: env; ./minirake --verbose all test +Test gcc-4.8 32bit_float_int16_utf8: + stage: test + image: registry.gitlab.com/dabroz/mruby:gcc48_0.7 + variables: + CC: gcc-4.8 + CXX: g++-4.8 + LD: gcc-4.8 + CFLAGS: "-m32 -DMRB_USE_FLOAT=1 -DMRB_INT16=1 -DMRB_UTF8_STRING=1" + LDFLAGS: "-m32" + script: env; ./minirake --verbose all test +Test gcc-4.8 32bit_float_int64: + stage: test + image: registry.gitlab.com/dabroz/mruby:gcc48_0.7 + variables: + CC: gcc-4.8 + CXX: g++-4.8 + LD: gcc-4.8 + CFLAGS: "-m32 -DMRB_USE_FLOAT=1 -DMRB_INT64=1" + LDFLAGS: "-m32" + script: env; ./minirake --verbose all test +Test gcc-4.8 32bit_float_int64_utf8: + stage: test + image: registry.gitlab.com/dabroz/mruby:gcc48_0.7 + variables: + CC: gcc-4.8 + CXX: g++-4.8 + LD: gcc-4.8 + CFLAGS: "-m32 -DMRB_USE_FLOAT=1 -DMRB_INT64=1 -DMRB_UTF8_STRING=1" + LDFLAGS: "-m32" + script: env; ./minirake --verbose all test +Test gcc-4.8 64bit: + stage: test + image: registry.gitlab.com/dabroz/mruby:gcc48_0.7 + variables: + CC: gcc-4.8 + CXX: g++-4.8 + LD: gcc-4.8 + CFLAGS: "-DMRB_WORD_BOXING=1" + LDFLAGS: '' + script: env; ./minirake --verbose all test +Test gcc-4.8 64bit_utf8: + stage: test + image: registry.gitlab.com/dabroz/mruby:gcc48_0.7 + variables: + CC: gcc-4.8 + CXX: g++-4.8 + LD: gcc-4.8 + CFLAGS: "-DMRB_WORD_BOXING=1 -DMRB_UTF8_STRING=1" + LDFLAGS: '' + script: env; ./minirake --verbose all test +Test gcc-4.8 64bit_nan: + stage: test + image: registry.gitlab.com/dabroz/mruby:gcc48_0.7 + variables: + CC: gcc-4.8 + CXX: g++-4.8 + LD: gcc-4.8 + CFLAGS: "-DMRB_NAN_BOXING=1" + LDFLAGS: '' + script: env; ./minirake --verbose all test +Test gcc-4.8 64bit_nan_utf8: + stage: test + image: registry.gitlab.com/dabroz/mruby:gcc48_0.7 + variables: + CC: gcc-4.8 + CXX: g++-4.8 + LD: gcc-4.8 + CFLAGS: "-DMRB_NAN_BOXING=1 -DMRB_UTF8_STRING=1" + LDFLAGS: '' + script: env; ./minirake --verbose all test +Test gcc-4.8 64bit_int16: + stage: test + image: registry.gitlab.com/dabroz/mruby:gcc48_0.7 + variables: + CC: gcc-4.8 + CXX: g++-4.8 + LD: gcc-4.8 + CFLAGS: "-DMRB_INT16=1" + LDFLAGS: '' + script: env; ./minirake --verbose all test +Test gcc-4.8 64bit_int16_utf8: + stage: test + image: registry.gitlab.com/dabroz/mruby:gcc48_0.7 + variables: + CC: gcc-4.8 + CXX: g++-4.8 + LD: gcc-4.8 + CFLAGS: "-DMRB_INT16=1 -DMRB_UTF8_STRING=1" + LDFLAGS: '' + script: env; ./minirake --verbose all test +Test gcc-4.8 64bit_int16_nan: + stage: test + image: registry.gitlab.com/dabroz/mruby:gcc48_0.7 + variables: + CC: gcc-4.8 + CXX: g++-4.8 + LD: gcc-4.8 + CFLAGS: "-DMRB_INT16=1 -DMRB_NAN_BOXING=1" + LDFLAGS: '' + script: env; ./minirake --verbose all test +Test gcc-4.8 64bit_int16_nan_utf8: + stage: test + image: registry.gitlab.com/dabroz/mruby:gcc48_0.7 + variables: + CC: gcc-4.8 + CXX: g++-4.8 + LD: gcc-4.8 + CFLAGS: "-DMRB_INT16=1 -DMRB_NAN_BOXING=1 -DMRB_UTF8_STRING=1" + LDFLAGS: '' + script: env; ./minirake --verbose all test +Test gcc-4.8 64bit_int64: + stage: test + image: registry.gitlab.com/dabroz/mruby:gcc48_0.7 + variables: + CC: gcc-4.8 + CXX: g++-4.8 + LD: gcc-4.8 + CFLAGS: "-DMRB_INT64=1 -DMRB_WORD_BOXING=1" + LDFLAGS: '' + script: env; ./minirake --verbose all test +Test gcc-4.8 64bit_int64_utf8: + stage: test + image: registry.gitlab.com/dabroz/mruby:gcc48_0.7 + variables: + CC: gcc-4.8 + CXX: g++-4.8 + LD: gcc-4.8 + CFLAGS: "-DMRB_INT64=1 -DMRB_WORD_BOXING=1 -DMRB_UTF8_STRING=1" + LDFLAGS: '' + script: env; ./minirake --verbose all test +Test gcc-4.8 64bit_float: + stage: test + image: registry.gitlab.com/dabroz/mruby:gcc48_0.7 + variables: + CC: gcc-4.8 + CXX: g++-4.8 + LD: gcc-4.8 + CFLAGS: "-DMRB_USE_FLOAT=1 -DMRB_WORD_BOXING=1" + LDFLAGS: '' + script: env; ./minirake --verbose all test +Test gcc-4.8 64bit_float_utf8: + stage: test + image: registry.gitlab.com/dabroz/mruby:gcc48_0.7 + variables: + CC: gcc-4.8 + CXX: g++-4.8 + LD: gcc-4.8 + CFLAGS: "-DMRB_USE_FLOAT=1 -DMRB_WORD_BOXING=1 -DMRB_UTF8_STRING=1" + LDFLAGS: '' + script: env; ./minirake --verbose all test +Test gcc-4.8 64bit_float_int16: + stage: test + image: registry.gitlab.com/dabroz/mruby:gcc48_0.7 + variables: + CC: gcc-4.8 + CXX: g++-4.8 + LD: gcc-4.8 + CFLAGS: "-DMRB_USE_FLOAT=1 -DMRB_INT16=1" + LDFLAGS: '' + script: env; ./minirake --verbose all test +Test gcc-4.8 64bit_float_int16_utf8: + stage: test + image: registry.gitlab.com/dabroz/mruby:gcc48_0.7 + variables: + CC: gcc-4.8 + CXX: g++-4.8 + LD: gcc-4.8 + CFLAGS: "-DMRB_USE_FLOAT=1 -DMRB_INT16=1 -DMRB_UTF8_STRING=1" + LDFLAGS: '' + script: env; ./minirake --verbose all test +Test gcc-4.8 64bit_float_int64: + stage: test + image: registry.gitlab.com/dabroz/mruby:gcc48_0.7 + variables: + CC: gcc-4.8 + CXX: g++-4.8 + LD: gcc-4.8 + CFLAGS: "-DMRB_USE_FLOAT=1 -DMRB_INT64=1 -DMRB_WORD_BOXING=1" + LDFLAGS: '' + script: env; ./minirake --verbose all test +Test gcc-4.8 64bit_float_int64_utf8: + stage: test + image: registry.gitlab.com/dabroz/mruby:gcc48_0.7 + variables: + CC: gcc-4.8 + CXX: g++-4.8 + LD: gcc-4.8 + CFLAGS: "-DMRB_USE_FLOAT=1 -DMRB_INT64=1 -DMRB_WORD_BOXING=1 -DMRB_UTF8_STRING=1" + LDFLAGS: '' + script: env; ./minirake --verbose all test +Test gcc-4.9 32bit: + stage: test + image: registry.gitlab.com/dabroz/mruby:gcc49_0.7 + variables: + CC: gcc-4.9 + CXX: g++-4.9 + LD: gcc-4.9 + CFLAGS: "-m32 -DMRB_WORD_BOXING=1" + LDFLAGS: "-m32" + script: env; ./minirake --verbose all test +Test gcc-4.9 32bit_utf8: + stage: test + image: registry.gitlab.com/dabroz/mruby:gcc49_0.7 + variables: + CC: gcc-4.9 + CXX: g++-4.9 + LD: gcc-4.9 + CFLAGS: "-m32 -DMRB_WORD_BOXING=1 -DMRB_UTF8_STRING=1" + LDFLAGS: "-m32" + script: env; ./minirake --verbose all test +Test gcc-4.9 32bit_nan: + stage: test + image: registry.gitlab.com/dabroz/mruby:gcc49_0.7 + variables: + CC: gcc-4.9 + CXX: g++-4.9 + LD: gcc-4.9 + CFLAGS: "-m32 -DMRB_NAN_BOXING=1" + LDFLAGS: "-m32" + script: env; ./minirake --verbose all test +Test gcc-4.9 32bit_nan_utf8: + stage: test + image: registry.gitlab.com/dabroz/mruby:gcc49_0.7 + variables: + CC: gcc-4.9 + CXX: g++-4.9 + LD: gcc-4.9 + CFLAGS: "-m32 -DMRB_NAN_BOXING=1 -DMRB_UTF8_STRING=1" + LDFLAGS: "-m32" + script: env; ./minirake --verbose all test +Test gcc-4.9 32bit_int16: + stage: test + image: registry.gitlab.com/dabroz/mruby:gcc49_0.7 + variables: + CC: gcc-4.9 + CXX: g++-4.9 + LD: gcc-4.9 + CFLAGS: "-m32 -DMRB_INT16=1" + LDFLAGS: "-m32" + script: env; ./minirake --verbose all test +Test gcc-4.9 32bit_int16_utf8: + stage: test + image: registry.gitlab.com/dabroz/mruby:gcc49_0.7 + variables: + CC: gcc-4.9 + CXX: g++-4.9 + LD: gcc-4.9 + CFLAGS: "-m32 -DMRB_INT16=1 -DMRB_UTF8_STRING=1" + LDFLAGS: "-m32" + script: env; ./minirake --verbose all test +Test gcc-4.9 32bit_int16_nan: + stage: test + image: registry.gitlab.com/dabroz/mruby:gcc49_0.7 + variables: + CC: gcc-4.9 + CXX: g++-4.9 + LD: gcc-4.9 + CFLAGS: "-m32 -DMRB_INT16=1 -DMRB_NAN_BOXING=1" + LDFLAGS: "-m32" + script: env; ./minirake --verbose all test +Test gcc-4.9 32bit_int16_nan_utf8: + stage: test + image: registry.gitlab.com/dabroz/mruby:gcc49_0.7 + variables: + CC: gcc-4.9 + CXX: g++-4.9 + LD: gcc-4.9 + CFLAGS: "-m32 -DMRB_INT16=1 -DMRB_NAN_BOXING=1 -DMRB_UTF8_STRING=1" + LDFLAGS: "-m32" + script: env; ./minirake --verbose all test +Test gcc-4.9 32bit_int64: + stage: test + image: registry.gitlab.com/dabroz/mruby:gcc49_0.7 + variables: + CC: gcc-4.9 + CXX: g++-4.9 + LD: gcc-4.9 + CFLAGS: "-m32 -DMRB_INT64=1" + LDFLAGS: "-m32" + script: env; ./minirake --verbose all test +Test gcc-4.9 32bit_int64_utf8: + stage: test + image: registry.gitlab.com/dabroz/mruby:gcc49_0.7 + variables: + CC: gcc-4.9 + CXX: g++-4.9 + LD: gcc-4.9 + CFLAGS: "-m32 -DMRB_INT64=1 -DMRB_UTF8_STRING=1" + LDFLAGS: "-m32" + script: env; ./minirake --verbose all test +Test gcc-4.9 32bit_float: + stage: test + image: registry.gitlab.com/dabroz/mruby:gcc49_0.7 + variables: + CC: gcc-4.9 + CXX: g++-4.9 + LD: gcc-4.9 + CFLAGS: "-m32 -DMRB_USE_FLOAT=1 -DMRB_WORD_BOXING=1" + LDFLAGS: "-m32" + script: env; ./minirake --verbose all test +Test gcc-4.9 32bit_float_utf8: + stage: test + image: registry.gitlab.com/dabroz/mruby:gcc49_0.7 + variables: + CC: gcc-4.9 + CXX: g++-4.9 + LD: gcc-4.9 + CFLAGS: "-m32 -DMRB_USE_FLOAT=1 -DMRB_WORD_BOXING=1 -DMRB_UTF8_STRING=1" + LDFLAGS: "-m32" + script: env; ./minirake --verbose all test +Test gcc-4.9 32bit_float_int16: + stage: test + image: registry.gitlab.com/dabroz/mruby:gcc49_0.7 + variables: + CC: gcc-4.9 + CXX: g++-4.9 + LD: gcc-4.9 + CFLAGS: "-m32 -DMRB_USE_FLOAT=1 -DMRB_INT16=1" + LDFLAGS: "-m32" + script: env; ./minirake --verbose all test +Test gcc-4.9 32bit_float_int16_utf8: + stage: test + image: registry.gitlab.com/dabroz/mruby:gcc49_0.7 + variables: + CC: gcc-4.9 + CXX: g++-4.9 + LD: gcc-4.9 + CFLAGS: "-m32 -DMRB_USE_FLOAT=1 -DMRB_INT16=1 -DMRB_UTF8_STRING=1" + LDFLAGS: "-m32" + script: env; ./minirake --verbose all test +Test gcc-4.9 32bit_float_int64: + stage: test + image: registry.gitlab.com/dabroz/mruby:gcc49_0.7 + variables: + CC: gcc-4.9 + CXX: g++-4.9 + LD: gcc-4.9 + CFLAGS: "-m32 -DMRB_USE_FLOAT=1 -DMRB_INT64=1" + LDFLAGS: "-m32" + script: env; ./minirake --verbose all test +Test gcc-4.9 32bit_float_int64_utf8: + stage: test + image: registry.gitlab.com/dabroz/mruby:gcc49_0.7 + variables: + CC: gcc-4.9 + CXX: g++-4.9 + LD: gcc-4.9 + CFLAGS: "-m32 -DMRB_USE_FLOAT=1 -DMRB_INT64=1 -DMRB_UTF8_STRING=1" + LDFLAGS: "-m32" + script: env; ./minirake --verbose all test +Test gcc-4.9 64bit: + stage: test + image: registry.gitlab.com/dabroz/mruby:gcc49_0.7 + variables: + CC: gcc-4.9 + CXX: g++-4.9 + LD: gcc-4.9 + CFLAGS: "-DMRB_WORD_BOXING=1" + LDFLAGS: '' + script: env; ./minirake --verbose all test +Test gcc-4.9 64bit_utf8: + stage: test + image: registry.gitlab.com/dabroz/mruby:gcc49_0.7 + variables: + CC: gcc-4.9 + CXX: g++-4.9 + LD: gcc-4.9 + CFLAGS: "-DMRB_WORD_BOXING=1 -DMRB_UTF8_STRING=1" + LDFLAGS: '' + script: env; ./minirake --verbose all test +Test gcc-4.9 64bit_nan: + stage: test + image: registry.gitlab.com/dabroz/mruby:gcc49_0.7 + variables: + CC: gcc-4.9 + CXX: g++-4.9 + LD: gcc-4.9 + CFLAGS: "-DMRB_NAN_BOXING=1" + LDFLAGS: '' + script: env; ./minirake --verbose all test +Test gcc-4.9 64bit_nan_utf8: + stage: test + image: registry.gitlab.com/dabroz/mruby:gcc49_0.7 + variables: + CC: gcc-4.9 + CXX: g++-4.9 + LD: gcc-4.9 + CFLAGS: "-DMRB_NAN_BOXING=1 -DMRB_UTF8_STRING=1" + LDFLAGS: '' + script: env; ./minirake --verbose all test +Test gcc-4.9 64bit_int16: + stage: test + image: registry.gitlab.com/dabroz/mruby:gcc49_0.7 + variables: + CC: gcc-4.9 + CXX: g++-4.9 + LD: gcc-4.9 + CFLAGS: "-DMRB_INT16=1" + LDFLAGS: '' + script: env; ./minirake --verbose all test +Test gcc-4.9 64bit_int16_utf8: + stage: test + image: registry.gitlab.com/dabroz/mruby:gcc49_0.7 + variables: + CC: gcc-4.9 + CXX: g++-4.9 + LD: gcc-4.9 + CFLAGS: "-DMRB_INT16=1 -DMRB_UTF8_STRING=1" + LDFLAGS: '' + script: env; ./minirake --verbose all test +Test gcc-4.9 64bit_int16_nan: + stage: test + image: registry.gitlab.com/dabroz/mruby:gcc49_0.7 + variables: + CC: gcc-4.9 + CXX: g++-4.9 + LD: gcc-4.9 + CFLAGS: "-DMRB_INT16=1 -DMRB_NAN_BOXING=1" + LDFLAGS: '' + script: env; ./minirake --verbose all test +Test gcc-4.9 64bit_int16_nan_utf8: + stage: test + image: registry.gitlab.com/dabroz/mruby:gcc49_0.7 + variables: + CC: gcc-4.9 + CXX: g++-4.9 + LD: gcc-4.9 + CFLAGS: "-DMRB_INT16=1 -DMRB_NAN_BOXING=1 -DMRB_UTF8_STRING=1" + LDFLAGS: '' + script: env; ./minirake --verbose all test +Test gcc-4.9 64bit_int64: + stage: test + image: registry.gitlab.com/dabroz/mruby:gcc49_0.7 + variables: + CC: gcc-4.9 + CXX: g++-4.9 + LD: gcc-4.9 + CFLAGS: "-DMRB_INT64=1 -DMRB_WORD_BOXING=1" + LDFLAGS: '' + script: env; ./minirake --verbose all test +Test gcc-4.9 64bit_int64_utf8: + stage: test + image: registry.gitlab.com/dabroz/mruby:gcc49_0.7 + variables: + CC: gcc-4.9 + CXX: g++-4.9 + LD: gcc-4.9 + CFLAGS: "-DMRB_INT64=1 -DMRB_WORD_BOXING=1 -DMRB_UTF8_STRING=1" + LDFLAGS: '' + script: env; ./minirake --verbose all test +Test gcc-4.9 64bit_float: + stage: test + image: registry.gitlab.com/dabroz/mruby:gcc49_0.7 + variables: + CC: gcc-4.9 + CXX: g++-4.9 + LD: gcc-4.9 + CFLAGS: "-DMRB_USE_FLOAT=1 -DMRB_WORD_BOXING=1" + LDFLAGS: '' + script: env; ./minirake --verbose all test +Test gcc-4.9 64bit_float_utf8: + stage: test + image: registry.gitlab.com/dabroz/mruby:gcc49_0.7 + variables: + CC: gcc-4.9 + CXX: g++-4.9 + LD: gcc-4.9 + CFLAGS: "-DMRB_USE_FLOAT=1 -DMRB_WORD_BOXING=1 -DMRB_UTF8_STRING=1" + LDFLAGS: '' + script: env; ./minirake --verbose all test +Test gcc-4.9 64bit_float_int16: + stage: test + image: registry.gitlab.com/dabroz/mruby:gcc49_0.7 + variables: + CC: gcc-4.9 + CXX: g++-4.9 + LD: gcc-4.9 + CFLAGS: "-DMRB_USE_FLOAT=1 -DMRB_INT16=1" + LDFLAGS: '' + script: env; ./minirake --verbose all test +Test gcc-4.9 64bit_float_int16_utf8: + stage: test + image: registry.gitlab.com/dabroz/mruby:gcc49_0.7 + variables: + CC: gcc-4.9 + CXX: g++-4.9 + LD: gcc-4.9 + CFLAGS: "-DMRB_USE_FLOAT=1 -DMRB_INT16=1 -DMRB_UTF8_STRING=1" + LDFLAGS: '' + script: env; ./minirake --verbose all test +Test gcc-4.9 64bit_float_int64: + stage: test + image: registry.gitlab.com/dabroz/mruby:gcc49_0.7 + variables: + CC: gcc-4.9 + CXX: g++-4.9 + LD: gcc-4.9 + CFLAGS: "-DMRB_USE_FLOAT=1 -DMRB_INT64=1 -DMRB_WORD_BOXING=1" + LDFLAGS: '' + script: env; ./minirake --verbose all test +Test gcc-4.9 64bit_float_int64_utf8: + stage: test + image: registry.gitlab.com/dabroz/mruby:gcc49_0.7 + variables: + CC: gcc-4.9 + CXX: g++-4.9 + LD: gcc-4.9 + CFLAGS: "-DMRB_USE_FLOAT=1 -DMRB_INT64=1 -DMRB_WORD_BOXING=1 -DMRB_UTF8_STRING=1" + LDFLAGS: '' + script: env; ./minirake --verbose all test +Test gcc-5 32bit: + stage: test + image: registry.gitlab.com/dabroz/mruby:gcc5_0.7 + variables: + CC: gcc-5 + CXX: g++-5 + LD: gcc-5 + CFLAGS: "-m32 -DMRB_WORD_BOXING=1" + LDFLAGS: "-m32" + script: env; ./minirake --verbose all test +Test gcc-5 32bit_utf8: + stage: test + image: registry.gitlab.com/dabroz/mruby:gcc5_0.7 + variables: + CC: gcc-5 + CXX: g++-5 + LD: gcc-5 + CFLAGS: "-m32 -DMRB_WORD_BOXING=1 -DMRB_UTF8_STRING=1" + LDFLAGS: "-m32" + script: env; ./minirake --verbose all test +Test gcc-5 32bit_nan: + stage: test + image: registry.gitlab.com/dabroz/mruby:gcc5_0.7 + variables: + CC: gcc-5 + CXX: g++-5 + LD: gcc-5 + CFLAGS: "-m32 -DMRB_NAN_BOXING=1" + LDFLAGS: "-m32" + script: env; ./minirake --verbose all test +Test gcc-5 32bit_nan_utf8: + stage: test + image: registry.gitlab.com/dabroz/mruby:gcc5_0.7 + variables: + CC: gcc-5 + CXX: g++-5 + LD: gcc-5 + CFLAGS: "-m32 -DMRB_NAN_BOXING=1 -DMRB_UTF8_STRING=1" + LDFLAGS: "-m32" + script: env; ./minirake --verbose all test +Test gcc-5 32bit_int16: + stage: test + image: registry.gitlab.com/dabroz/mruby:gcc5_0.7 + variables: + CC: gcc-5 + CXX: g++-5 + LD: gcc-5 + CFLAGS: "-m32 -DMRB_INT16=1" + LDFLAGS: "-m32" + script: env; ./minirake --verbose all test +Test gcc-5 32bit_int16_utf8: + stage: test + image: registry.gitlab.com/dabroz/mruby:gcc5_0.7 + variables: + CC: gcc-5 + CXX: g++-5 + LD: gcc-5 + CFLAGS: "-m32 -DMRB_INT16=1 -DMRB_UTF8_STRING=1" + LDFLAGS: "-m32" + script: env; ./minirake --verbose all test +Test gcc-5 32bit_int16_nan: + stage: test + image: registry.gitlab.com/dabroz/mruby:gcc5_0.7 + variables: + CC: gcc-5 + CXX: g++-5 + LD: gcc-5 + CFLAGS: "-m32 -DMRB_INT16=1 -DMRB_NAN_BOXING=1" + LDFLAGS: "-m32" + script: env; ./minirake --verbose all test +Test gcc-5 32bit_int16_nan_utf8: + stage: test + image: registry.gitlab.com/dabroz/mruby:gcc5_0.7 + variables: + CC: gcc-5 + CXX: g++-5 + LD: gcc-5 + CFLAGS: "-m32 -DMRB_INT16=1 -DMRB_NAN_BOXING=1 -DMRB_UTF8_STRING=1" + LDFLAGS: "-m32" + script: env; ./minirake --verbose all test +Test gcc-5 32bit_int64: + stage: test + image: registry.gitlab.com/dabroz/mruby:gcc5_0.7 + variables: + CC: gcc-5 + CXX: g++-5 + LD: gcc-5 + CFLAGS: "-m32 -DMRB_INT64=1" + LDFLAGS: "-m32" + script: env; ./minirake --verbose all test +Test gcc-5 32bit_int64_utf8: + stage: test + image: registry.gitlab.com/dabroz/mruby:gcc5_0.7 + variables: + CC: gcc-5 + CXX: g++-5 + LD: gcc-5 + CFLAGS: "-m32 -DMRB_INT64=1 -DMRB_UTF8_STRING=1" + LDFLAGS: "-m32" + script: env; ./minirake --verbose all test +Test gcc-5 32bit_float: + stage: test + image: registry.gitlab.com/dabroz/mruby:gcc5_0.7 + variables: + CC: gcc-5 + CXX: g++-5 + LD: gcc-5 + CFLAGS: "-m32 -DMRB_USE_FLOAT=1 -DMRB_WORD_BOXING=1" + LDFLAGS: "-m32" + script: env; ./minirake --verbose all test +Test gcc-5 32bit_float_utf8: + stage: test + image: registry.gitlab.com/dabroz/mruby:gcc5_0.7 + variables: + CC: gcc-5 + CXX: g++-5 + LD: gcc-5 + CFLAGS: "-m32 -DMRB_USE_FLOAT=1 -DMRB_WORD_BOXING=1 -DMRB_UTF8_STRING=1" + LDFLAGS: "-m32" + script: env; ./minirake --verbose all test +Test gcc-5 32bit_float_int16: + stage: test + image: registry.gitlab.com/dabroz/mruby:gcc5_0.7 + variables: + CC: gcc-5 + CXX: g++-5 + LD: gcc-5 + CFLAGS: "-m32 -DMRB_USE_FLOAT=1 -DMRB_INT16=1" + LDFLAGS: "-m32" + script: env; ./minirake --verbose all test +Test gcc-5 32bit_float_int16_utf8: + stage: test + image: registry.gitlab.com/dabroz/mruby:gcc5_0.7 + variables: + CC: gcc-5 + CXX: g++-5 + LD: gcc-5 + CFLAGS: "-m32 -DMRB_USE_FLOAT=1 -DMRB_INT16=1 -DMRB_UTF8_STRING=1" + LDFLAGS: "-m32" + script: env; ./minirake --verbose all test +Test gcc-5 32bit_float_int64: + stage: test + image: registry.gitlab.com/dabroz/mruby:gcc5_0.7 + variables: + CC: gcc-5 + CXX: g++-5 + LD: gcc-5 + CFLAGS: "-m32 -DMRB_USE_FLOAT=1 -DMRB_INT64=1" + LDFLAGS: "-m32" + script: env; ./minirake --verbose all test +Test gcc-5 32bit_float_int64_utf8: + stage: test + image: registry.gitlab.com/dabroz/mruby:gcc5_0.7 + variables: + CC: gcc-5 + CXX: g++-5 + LD: gcc-5 + CFLAGS: "-m32 -DMRB_USE_FLOAT=1 -DMRB_INT64=1 -DMRB_UTF8_STRING=1" + LDFLAGS: "-m32" + script: env; ./minirake --verbose all test +Test gcc-5 64bit: + stage: test + image: registry.gitlab.com/dabroz/mruby:gcc5_0.7 + variables: + CC: gcc-5 + CXX: g++-5 + LD: gcc-5 + CFLAGS: "-DMRB_WORD_BOXING=1" + LDFLAGS: '' + script: env; ./minirake --verbose all test +Test gcc-5 64bit_utf8: + stage: test + image: registry.gitlab.com/dabroz/mruby:gcc5_0.7 + variables: + CC: gcc-5 + CXX: g++-5 + LD: gcc-5 + CFLAGS: "-DMRB_WORD_BOXING=1 -DMRB_UTF8_STRING=1" + LDFLAGS: '' + script: env; ./minirake --verbose all test +Test gcc-5 64bit_nan: + stage: test + image: registry.gitlab.com/dabroz/mruby:gcc5_0.7 + variables: + CC: gcc-5 + CXX: g++-5 + LD: gcc-5 + CFLAGS: "-DMRB_NAN_BOXING=1" + LDFLAGS: '' + script: env; ./minirake --verbose all test +Test gcc-5 64bit_nan_utf8: + stage: test + image: registry.gitlab.com/dabroz/mruby:gcc5_0.7 + variables: + CC: gcc-5 + CXX: g++-5 + LD: gcc-5 + CFLAGS: "-DMRB_NAN_BOXING=1 -DMRB_UTF8_STRING=1" + LDFLAGS: '' + script: env; ./minirake --verbose all test +Test gcc-5 64bit_int16: + stage: test + image: registry.gitlab.com/dabroz/mruby:gcc5_0.7 + variables: + CC: gcc-5 + CXX: g++-5 + LD: gcc-5 + CFLAGS: "-DMRB_INT16=1" + LDFLAGS: '' + script: env; ./minirake --verbose all test +Test gcc-5 64bit_int16_utf8: + stage: test + image: registry.gitlab.com/dabroz/mruby:gcc5_0.7 + variables: + CC: gcc-5 + CXX: g++-5 + LD: gcc-5 + CFLAGS: "-DMRB_INT16=1 -DMRB_UTF8_STRING=1" + LDFLAGS: '' + script: env; ./minirake --verbose all test +Test gcc-5 64bit_int16_nan: + stage: test + image: registry.gitlab.com/dabroz/mruby:gcc5_0.7 + variables: + CC: gcc-5 + CXX: g++-5 + LD: gcc-5 + CFLAGS: "-DMRB_INT16=1 -DMRB_NAN_BOXING=1" + LDFLAGS: '' + script: env; ./minirake --verbose all test +Test gcc-5 64bit_int16_nan_utf8: + stage: test + image: registry.gitlab.com/dabroz/mruby:gcc5_0.7 + variables: + CC: gcc-5 + CXX: g++-5 + LD: gcc-5 + CFLAGS: "-DMRB_INT16=1 -DMRB_NAN_BOXING=1 -DMRB_UTF8_STRING=1" + LDFLAGS: '' + script: env; ./minirake --verbose all test +Test gcc-5 64bit_int64: + stage: test + image: registry.gitlab.com/dabroz/mruby:gcc5_0.7 + variables: + CC: gcc-5 + CXX: g++-5 + LD: gcc-5 + CFLAGS: "-DMRB_INT64=1 -DMRB_WORD_BOXING=1" + LDFLAGS: '' + script: env; ./minirake --verbose all test +Test gcc-5 64bit_int64_utf8: + stage: test + image: registry.gitlab.com/dabroz/mruby:gcc5_0.7 + variables: + CC: gcc-5 + CXX: g++-5 + LD: gcc-5 + CFLAGS: "-DMRB_INT64=1 -DMRB_WORD_BOXING=1 -DMRB_UTF8_STRING=1" + LDFLAGS: '' + script: env; ./minirake --verbose all test +Test gcc-5 64bit_float: + stage: test + image: registry.gitlab.com/dabroz/mruby:gcc5_0.7 + variables: + CC: gcc-5 + CXX: g++-5 + LD: gcc-5 + CFLAGS: "-DMRB_USE_FLOAT=1 -DMRB_WORD_BOXING=1" + LDFLAGS: '' + script: env; ./minirake --verbose all test +Test gcc-5 64bit_float_utf8: + stage: test + image: registry.gitlab.com/dabroz/mruby:gcc5_0.7 + variables: + CC: gcc-5 + CXX: g++-5 + LD: gcc-5 + CFLAGS: "-DMRB_USE_FLOAT=1 -DMRB_WORD_BOXING=1 -DMRB_UTF8_STRING=1" + LDFLAGS: '' + script: env; ./minirake --verbose all test +Test gcc-5 64bit_float_int16: + stage: test + image: registry.gitlab.com/dabroz/mruby:gcc5_0.7 + variables: + CC: gcc-5 + CXX: g++-5 + LD: gcc-5 + CFLAGS: "-DMRB_USE_FLOAT=1 -DMRB_INT16=1" + LDFLAGS: '' + script: env; ./minirake --verbose all test +Test gcc-5 64bit_float_int16_utf8: + stage: test + image: registry.gitlab.com/dabroz/mruby:gcc5_0.7 + variables: + CC: gcc-5 + CXX: g++-5 + LD: gcc-5 + CFLAGS: "-DMRB_USE_FLOAT=1 -DMRB_INT16=1 -DMRB_UTF8_STRING=1" + LDFLAGS: '' + script: env; ./minirake --verbose all test +Test gcc-5 64bit_float_int64: + stage: test + image: registry.gitlab.com/dabroz/mruby:gcc5_0.7 + variables: + CC: gcc-5 + CXX: g++-5 + LD: gcc-5 + CFLAGS: "-DMRB_USE_FLOAT=1 -DMRB_INT64=1 -DMRB_WORD_BOXING=1" + LDFLAGS: '' + script: env; ./minirake --verbose all test +Test gcc-5 64bit_float_int64_utf8: + stage: test + image: registry.gitlab.com/dabroz/mruby:gcc5_0.7 + variables: + CC: gcc-5 + CXX: g++-5 + LD: gcc-5 + CFLAGS: "-DMRB_USE_FLOAT=1 -DMRB_INT64=1 -DMRB_WORD_BOXING=1 -DMRB_UTF8_STRING=1" + LDFLAGS: '' + script: env; ./minirake --verbose all test +Test gcc-6 32bit: + stage: test + image: registry.gitlab.com/dabroz/mruby:gcc6_0.7 + variables: + CC: gcc-6 + CXX: g++-6 + LD: gcc-6 + CFLAGS: "-m32 -DMRB_WORD_BOXING=1" + LDFLAGS: "-m32" + script: env; ./minirake --verbose all test +Test gcc-6 32bit_utf8: + stage: test + image: registry.gitlab.com/dabroz/mruby:gcc6_0.7 + variables: + CC: gcc-6 + CXX: g++-6 + LD: gcc-6 + CFLAGS: "-m32 -DMRB_WORD_BOXING=1 -DMRB_UTF8_STRING=1" + LDFLAGS: "-m32" + script: env; ./minirake --verbose all test +Test gcc-6 32bit_nan: + stage: test + image: registry.gitlab.com/dabroz/mruby:gcc6_0.7 + variables: + CC: gcc-6 + CXX: g++-6 + LD: gcc-6 + CFLAGS: "-m32 -DMRB_NAN_BOXING=1" + LDFLAGS: "-m32" + script: env; ./minirake --verbose all test +Test gcc-6 32bit_nan_utf8: + stage: test + image: registry.gitlab.com/dabroz/mruby:gcc6_0.7 + variables: + CC: gcc-6 + CXX: g++-6 + LD: gcc-6 + CFLAGS: "-m32 -DMRB_NAN_BOXING=1 -DMRB_UTF8_STRING=1" + LDFLAGS: "-m32" + script: env; ./minirake --verbose all test +Test gcc-6 32bit_int16: + stage: test + image: registry.gitlab.com/dabroz/mruby:gcc6_0.7 + variables: + CC: gcc-6 + CXX: g++-6 + LD: gcc-6 + CFLAGS: "-m32 -DMRB_INT16=1" + LDFLAGS: "-m32" + script: env; ./minirake --verbose all test +Test gcc-6 32bit_int16_utf8: + stage: test + image: registry.gitlab.com/dabroz/mruby:gcc6_0.7 + variables: + CC: gcc-6 + CXX: g++-6 + LD: gcc-6 + CFLAGS: "-m32 -DMRB_INT16=1 -DMRB_UTF8_STRING=1" + LDFLAGS: "-m32" + script: env; ./minirake --verbose all test +Test gcc-6 32bit_int16_nan: + stage: test + image: registry.gitlab.com/dabroz/mruby:gcc6_0.7 + variables: + CC: gcc-6 + CXX: g++-6 + LD: gcc-6 + CFLAGS: "-m32 -DMRB_INT16=1 -DMRB_NAN_BOXING=1" + LDFLAGS: "-m32" + script: env; ./minirake --verbose all test +Test gcc-6 32bit_int16_nan_utf8: + stage: test + image: registry.gitlab.com/dabroz/mruby:gcc6_0.7 + variables: + CC: gcc-6 + CXX: g++-6 + LD: gcc-6 + CFLAGS: "-m32 -DMRB_INT16=1 -DMRB_NAN_BOXING=1 -DMRB_UTF8_STRING=1" + LDFLAGS: "-m32" + script: env; ./minirake --verbose all test +Test gcc-6 32bit_int64: + stage: test + image: registry.gitlab.com/dabroz/mruby:gcc6_0.7 + variables: + CC: gcc-6 + CXX: g++-6 + LD: gcc-6 + CFLAGS: "-m32 -DMRB_INT64=1" + LDFLAGS: "-m32" + script: env; ./minirake --verbose all test +Test gcc-6 32bit_int64_utf8: + stage: test + image: registry.gitlab.com/dabroz/mruby:gcc6_0.7 + variables: + CC: gcc-6 + CXX: g++-6 + LD: gcc-6 + CFLAGS: "-m32 -DMRB_INT64=1 -DMRB_UTF8_STRING=1" + LDFLAGS: "-m32" + script: env; ./minirake --verbose all test +Test gcc-6 32bit_float: + stage: test + image: registry.gitlab.com/dabroz/mruby:gcc6_0.7 + variables: + CC: gcc-6 + CXX: g++-6 + LD: gcc-6 + CFLAGS: "-m32 -DMRB_USE_FLOAT=1 -DMRB_WORD_BOXING=1" + LDFLAGS: "-m32" + script: env; ./minirake --verbose all test +Test gcc-6 32bit_float_utf8: + stage: test + image: registry.gitlab.com/dabroz/mruby:gcc6_0.7 + variables: + CC: gcc-6 + CXX: g++-6 + LD: gcc-6 + CFLAGS: "-m32 -DMRB_USE_FLOAT=1 -DMRB_WORD_BOXING=1 -DMRB_UTF8_STRING=1" + LDFLAGS: "-m32" + script: env; ./minirake --verbose all test +Test gcc-6 32bit_float_int16: + stage: test + image: registry.gitlab.com/dabroz/mruby:gcc6_0.7 + variables: + CC: gcc-6 + CXX: g++-6 + LD: gcc-6 + CFLAGS: "-m32 -DMRB_USE_FLOAT=1 -DMRB_INT16=1" + LDFLAGS: "-m32" + script: env; ./minirake --verbose all test +Test gcc-6 32bit_float_int16_utf8: + stage: test + image: registry.gitlab.com/dabroz/mruby:gcc6_0.7 + variables: + CC: gcc-6 + CXX: g++-6 + LD: gcc-6 + CFLAGS: "-m32 -DMRB_USE_FLOAT=1 -DMRB_INT16=1 -DMRB_UTF8_STRING=1" + LDFLAGS: "-m32" + script: env; ./minirake --verbose all test +Test gcc-6 32bit_float_int64: + stage: test + image: registry.gitlab.com/dabroz/mruby:gcc6_0.7 + variables: + CC: gcc-6 + CXX: g++-6 + LD: gcc-6 + CFLAGS: "-m32 -DMRB_USE_FLOAT=1 -DMRB_INT64=1" + LDFLAGS: "-m32" + script: env; ./minirake --verbose all test +Test gcc-6 32bit_float_int64_utf8: + stage: test + image: registry.gitlab.com/dabroz/mruby:gcc6_0.7 + variables: + CC: gcc-6 + CXX: g++-6 + LD: gcc-6 + CFLAGS: "-m32 -DMRB_USE_FLOAT=1 -DMRB_INT64=1 -DMRB_UTF8_STRING=1" + LDFLAGS: "-m32" + script: env; ./minirake --verbose all test +Test gcc-6 64bit: + stage: test + image: registry.gitlab.com/dabroz/mruby:gcc6_0.7 + variables: + CC: gcc-6 + CXX: g++-6 + LD: gcc-6 + CFLAGS: "-DMRB_WORD_BOXING=1" + LDFLAGS: '' + script: env; ./minirake --verbose all test +Test gcc-6 64bit_utf8: + stage: test + image: registry.gitlab.com/dabroz/mruby:gcc6_0.7 + variables: + CC: gcc-6 + CXX: g++-6 + LD: gcc-6 + CFLAGS: "-DMRB_WORD_BOXING=1 -DMRB_UTF8_STRING=1" + LDFLAGS: '' + script: env; ./minirake --verbose all test +Test gcc-6 64bit_nan: + stage: test + image: registry.gitlab.com/dabroz/mruby:gcc6_0.7 + variables: + CC: gcc-6 + CXX: g++-6 + LD: gcc-6 + CFLAGS: "-DMRB_NAN_BOXING=1" + LDFLAGS: '' + script: env; ./minirake --verbose all test +Test gcc-6 64bit_nan_utf8: + stage: test + image: registry.gitlab.com/dabroz/mruby:gcc6_0.7 + variables: + CC: gcc-6 + CXX: g++-6 + LD: gcc-6 + CFLAGS: "-DMRB_NAN_BOXING=1 -DMRB_UTF8_STRING=1" + LDFLAGS: '' + script: env; ./minirake --verbose all test +Test gcc-6 64bit_int16: + stage: test + image: registry.gitlab.com/dabroz/mruby:gcc6_0.7 + variables: + CC: gcc-6 + CXX: g++-6 + LD: gcc-6 + CFLAGS: "-DMRB_INT16=1" + LDFLAGS: '' + script: env; ./minirake --verbose all test +Test gcc-6 64bit_int16_utf8: + stage: test + image: registry.gitlab.com/dabroz/mruby:gcc6_0.7 + variables: + CC: gcc-6 + CXX: g++-6 + LD: gcc-6 + CFLAGS: "-DMRB_INT16=1 -DMRB_UTF8_STRING=1" + LDFLAGS: '' + script: env; ./minirake --verbose all test +Test gcc-6 64bit_int16_nan: + stage: test + image: registry.gitlab.com/dabroz/mruby:gcc6_0.7 + variables: + CC: gcc-6 + CXX: g++-6 + LD: gcc-6 + CFLAGS: "-DMRB_INT16=1 -DMRB_NAN_BOXING=1" + LDFLAGS: '' + script: env; ./minirake --verbose all test +Test gcc-6 64bit_int16_nan_utf8: + stage: test + image: registry.gitlab.com/dabroz/mruby:gcc6_0.7 + variables: + CC: gcc-6 + CXX: g++-6 + LD: gcc-6 + CFLAGS: "-DMRB_INT16=1 -DMRB_NAN_BOXING=1 -DMRB_UTF8_STRING=1" + LDFLAGS: '' + script: env; ./minirake --verbose all test +Test gcc-6 64bit_int64: + stage: test + image: registry.gitlab.com/dabroz/mruby:gcc6_0.7 + variables: + CC: gcc-6 + CXX: g++-6 + LD: gcc-6 + CFLAGS: "-DMRB_INT64=1 -DMRB_WORD_BOXING=1" + LDFLAGS: '' + script: env; ./minirake --verbose all test +Test gcc-6 64bit_int64_utf8: + stage: test + image: registry.gitlab.com/dabroz/mruby:gcc6_0.7 + variables: + CC: gcc-6 + CXX: g++-6 + LD: gcc-6 + CFLAGS: "-DMRB_INT64=1 -DMRB_WORD_BOXING=1 -DMRB_UTF8_STRING=1" + LDFLAGS: '' + script: env; ./minirake --verbose all test +Test gcc-6 64bit_float: + stage: test + image: registry.gitlab.com/dabroz/mruby:gcc6_0.7 + variables: + CC: gcc-6 + CXX: g++-6 + LD: gcc-6 + CFLAGS: "-DMRB_USE_FLOAT=1 -DMRB_WORD_BOXING=1" + LDFLAGS: '' + script: env; ./minirake --verbose all test +Test gcc-6 64bit_float_utf8: + stage: test + image: registry.gitlab.com/dabroz/mruby:gcc6_0.7 + variables: + CC: gcc-6 + CXX: g++-6 + LD: gcc-6 + CFLAGS: "-DMRB_USE_FLOAT=1 -DMRB_WORD_BOXING=1 -DMRB_UTF8_STRING=1" + LDFLAGS: '' + script: env; ./minirake --verbose all test +Test gcc-6 64bit_float_int16: + stage: test + image: registry.gitlab.com/dabroz/mruby:gcc6_0.7 + variables: + CC: gcc-6 + CXX: g++-6 + LD: gcc-6 + CFLAGS: "-DMRB_USE_FLOAT=1 -DMRB_INT16=1" + LDFLAGS: '' + script: env; ./minirake --verbose all test +Test gcc-6 64bit_float_int16_utf8: + stage: test + image: registry.gitlab.com/dabroz/mruby:gcc6_0.7 + variables: + CC: gcc-6 + CXX: g++-6 + LD: gcc-6 + CFLAGS: "-DMRB_USE_FLOAT=1 -DMRB_INT16=1 -DMRB_UTF8_STRING=1" + LDFLAGS: '' + script: env; ./minirake --verbose all test +Test gcc-6 64bit_float_int64: + stage: test + image: registry.gitlab.com/dabroz/mruby:gcc6_0.7 + variables: + CC: gcc-6 + CXX: g++-6 + LD: gcc-6 + CFLAGS: "-DMRB_USE_FLOAT=1 -DMRB_INT64=1 -DMRB_WORD_BOXING=1" + LDFLAGS: '' + script: env; ./minirake --verbose all test +Test gcc-6 64bit_float_int64_utf8: + stage: test + image: registry.gitlab.com/dabroz/mruby:gcc6_0.7 + variables: + CC: gcc-6 + CXX: g++-6 + LD: gcc-6 + CFLAGS: "-DMRB_USE_FLOAT=1 -DMRB_INT64=1 -DMRB_WORD_BOXING=1 -DMRB_UTF8_STRING=1" + LDFLAGS: '' + script: env; ./minirake --verbose all test +Test clang-3.5 32bit: + stage: test + image: registry.gitlab.com/dabroz/mruby:clang35_0.7 + variables: + CC: clang-3.5 + CXX: clang++-3.5 + LD: clang-3.5 + CFLAGS: "-m32 -DMRB_WORD_BOXING=1" + LDFLAGS: "-m32" + script: env; ./minirake --verbose all test +Test clang-3.5 32bit_utf8: + stage: test + image: registry.gitlab.com/dabroz/mruby:clang35_0.7 + variables: + CC: clang-3.5 + CXX: clang++-3.5 + LD: clang-3.5 + CFLAGS: "-m32 -DMRB_WORD_BOXING=1 -DMRB_UTF8_STRING=1" + LDFLAGS: "-m32" + script: env; ./minirake --verbose all test +Test clang-3.5 32bit_nan: + stage: test + image: registry.gitlab.com/dabroz/mruby:clang35_0.7 + variables: + CC: clang-3.5 + CXX: clang++-3.5 + LD: clang-3.5 + CFLAGS: "-m32 -DMRB_NAN_BOXING=1" + LDFLAGS: "-m32" + script: env; ./minirake --verbose all test +Test clang-3.5 32bit_nan_utf8: + stage: test + image: registry.gitlab.com/dabroz/mruby:clang35_0.7 + variables: + CC: clang-3.5 + CXX: clang++-3.5 + LD: clang-3.5 + CFLAGS: "-m32 -DMRB_NAN_BOXING=1 -DMRB_UTF8_STRING=1" + LDFLAGS: "-m32" + script: env; ./minirake --verbose all test +Test clang-3.5 32bit_int16: + stage: test + image: registry.gitlab.com/dabroz/mruby:clang35_0.7 + variables: + CC: clang-3.5 + CXX: clang++-3.5 + LD: clang-3.5 + CFLAGS: "-m32 -DMRB_INT16=1" + LDFLAGS: "-m32" + script: env; ./minirake --verbose all test +Test clang-3.5 32bit_int16_utf8: + stage: test + image: registry.gitlab.com/dabroz/mruby:clang35_0.7 + variables: + CC: clang-3.5 + CXX: clang++-3.5 + LD: clang-3.5 + CFLAGS: "-m32 -DMRB_INT16=1 -DMRB_UTF8_STRING=1" + LDFLAGS: "-m32" + script: env; ./minirake --verbose all test +Test clang-3.5 32bit_int16_nan: + stage: test + image: registry.gitlab.com/dabroz/mruby:clang35_0.7 + variables: + CC: clang-3.5 + CXX: clang++-3.5 + LD: clang-3.5 + CFLAGS: "-m32 -DMRB_INT16=1 -DMRB_NAN_BOXING=1" + LDFLAGS: "-m32" + script: env; ./minirake --verbose all test +Test clang-3.5 32bit_int16_nan_utf8: + stage: test + image: registry.gitlab.com/dabroz/mruby:clang35_0.7 + variables: + CC: clang-3.5 + CXX: clang++-3.5 + LD: clang-3.5 + CFLAGS: "-m32 -DMRB_INT16=1 -DMRB_NAN_BOXING=1 -DMRB_UTF8_STRING=1" + LDFLAGS: "-m32" + script: env; ./minirake --verbose all test +Test clang-3.5 32bit_int64: + stage: test + image: registry.gitlab.com/dabroz/mruby:clang35_0.7 + variables: + CC: clang-3.5 + CXX: clang++-3.5 + LD: clang-3.5 + CFLAGS: "-m32 -DMRB_INT64=1" + LDFLAGS: "-m32" + script: env; ./minirake --verbose all test +Test clang-3.5 32bit_int64_utf8: + stage: test + image: registry.gitlab.com/dabroz/mruby:clang35_0.7 + variables: + CC: clang-3.5 + CXX: clang++-3.5 + LD: clang-3.5 + CFLAGS: "-m32 -DMRB_INT64=1 -DMRB_UTF8_STRING=1" + LDFLAGS: "-m32" + script: env; ./minirake --verbose all test +Test clang-3.5 32bit_float: + stage: test + image: registry.gitlab.com/dabroz/mruby:clang35_0.7 + variables: + CC: clang-3.5 + CXX: clang++-3.5 + LD: clang-3.5 + CFLAGS: "-m32 -DMRB_USE_FLOAT=1 -DMRB_WORD_BOXING=1" + LDFLAGS: "-m32" + script: env; ./minirake --verbose all test +Test clang-3.5 32bit_float_utf8: + stage: test + image: registry.gitlab.com/dabroz/mruby:clang35_0.7 + variables: + CC: clang-3.5 + CXX: clang++-3.5 + LD: clang-3.5 + CFLAGS: "-m32 -DMRB_USE_FLOAT=1 -DMRB_WORD_BOXING=1 -DMRB_UTF8_STRING=1" + LDFLAGS: "-m32" + script: env; ./minirake --verbose all test +Test clang-3.5 32bit_float_int16: + stage: test + image: registry.gitlab.com/dabroz/mruby:clang35_0.7 + variables: + CC: clang-3.5 + CXX: clang++-3.5 + LD: clang-3.5 + CFLAGS: "-m32 -DMRB_USE_FLOAT=1 -DMRB_INT16=1" + LDFLAGS: "-m32" + script: env; ./minirake --verbose all test +Test clang-3.5 32bit_float_int16_utf8: + stage: test + image: registry.gitlab.com/dabroz/mruby:clang35_0.7 + variables: + CC: clang-3.5 + CXX: clang++-3.5 + LD: clang-3.5 + CFLAGS: "-m32 -DMRB_USE_FLOAT=1 -DMRB_INT16=1 -DMRB_UTF8_STRING=1" + LDFLAGS: "-m32" + script: env; ./minirake --verbose all test +Test clang-3.5 32bit_float_int64: + stage: test + image: registry.gitlab.com/dabroz/mruby:clang35_0.7 + variables: + CC: clang-3.5 + CXX: clang++-3.5 + LD: clang-3.5 + CFLAGS: "-m32 -DMRB_USE_FLOAT=1 -DMRB_INT64=1" + LDFLAGS: "-m32" + script: env; ./minirake --verbose all test +Test clang-3.5 32bit_float_int64_utf8: + stage: test + image: registry.gitlab.com/dabroz/mruby:clang35_0.7 + variables: + CC: clang-3.5 + CXX: clang++-3.5 + LD: clang-3.5 + CFLAGS: "-m32 -DMRB_USE_FLOAT=1 -DMRB_INT64=1 -DMRB_UTF8_STRING=1" + LDFLAGS: "-m32" + script: env; ./minirake --verbose all test +Test clang-3.5 64bit: + stage: test + image: registry.gitlab.com/dabroz/mruby:clang35_0.7 + variables: + CC: clang-3.5 + CXX: clang++-3.5 + LD: clang-3.5 + CFLAGS: "-DMRB_WORD_BOXING=1" + LDFLAGS: '' + script: env; ./minirake --verbose all test +Test clang-3.5 64bit_utf8: + stage: test + image: registry.gitlab.com/dabroz/mruby:clang35_0.7 + variables: + CC: clang-3.5 + CXX: clang++-3.5 + LD: clang-3.5 + CFLAGS: "-DMRB_WORD_BOXING=1 -DMRB_UTF8_STRING=1" + LDFLAGS: '' + script: env; ./minirake --verbose all test +Test clang-3.5 64bit_nan: + stage: test + image: registry.gitlab.com/dabroz/mruby:clang35_0.7 + variables: + CC: clang-3.5 + CXX: clang++-3.5 + LD: clang-3.5 + CFLAGS: "-DMRB_NAN_BOXING=1" + LDFLAGS: '' + script: env; ./minirake --verbose all test +Test clang-3.5 64bit_nan_utf8: + stage: test + image: registry.gitlab.com/dabroz/mruby:clang35_0.7 + variables: + CC: clang-3.5 + CXX: clang++-3.5 + LD: clang-3.5 + CFLAGS: "-DMRB_NAN_BOXING=1 -DMRB_UTF8_STRING=1" + LDFLAGS: '' + script: env; ./minirake --verbose all test +Test clang-3.5 64bit_int16: + stage: test + image: registry.gitlab.com/dabroz/mruby:clang35_0.7 + variables: + CC: clang-3.5 + CXX: clang++-3.5 + LD: clang-3.5 + CFLAGS: "-DMRB_INT16=1" + LDFLAGS: '' + script: env; ./minirake --verbose all test +Test clang-3.5 64bit_int16_utf8: + stage: test + image: registry.gitlab.com/dabroz/mruby:clang35_0.7 + variables: + CC: clang-3.5 + CXX: clang++-3.5 + LD: clang-3.5 + CFLAGS: "-DMRB_INT16=1 -DMRB_UTF8_STRING=1" + LDFLAGS: '' + script: env; ./minirake --verbose all test +Test clang-3.5 64bit_int16_nan: + stage: test + image: registry.gitlab.com/dabroz/mruby:clang35_0.7 + variables: + CC: clang-3.5 + CXX: clang++-3.5 + LD: clang-3.5 + CFLAGS: "-DMRB_INT16=1 -DMRB_NAN_BOXING=1" + LDFLAGS: '' + script: env; ./minirake --verbose all test +Test clang-3.5 64bit_int16_nan_utf8: + stage: test + image: registry.gitlab.com/dabroz/mruby:clang35_0.7 + variables: + CC: clang-3.5 + CXX: clang++-3.5 + LD: clang-3.5 + CFLAGS: "-DMRB_INT16=1 -DMRB_NAN_BOXING=1 -DMRB_UTF8_STRING=1" + LDFLAGS: '' + script: env; ./minirake --verbose all test +Test clang-3.5 64bit_int64: + stage: test + image: registry.gitlab.com/dabroz/mruby:clang35_0.7 + variables: + CC: clang-3.5 + CXX: clang++-3.5 + LD: clang-3.5 + CFLAGS: "-DMRB_INT64=1 -DMRB_WORD_BOXING=1" + LDFLAGS: '' + script: env; ./minirake --verbose all test +Test clang-3.5 64bit_int64_utf8: + stage: test + image: registry.gitlab.com/dabroz/mruby:clang35_0.7 + variables: + CC: clang-3.5 + CXX: clang++-3.5 + LD: clang-3.5 + CFLAGS: "-DMRB_INT64=1 -DMRB_WORD_BOXING=1 -DMRB_UTF8_STRING=1" + LDFLAGS: '' + script: env; ./minirake --verbose all test +Test clang-3.5 64bit_float: + stage: test + image: registry.gitlab.com/dabroz/mruby:clang35_0.7 + variables: + CC: clang-3.5 + CXX: clang++-3.5 + LD: clang-3.5 + CFLAGS: "-DMRB_USE_FLOAT=1 -DMRB_WORD_BOXING=1" + LDFLAGS: '' + script: env; ./minirake --verbose all test +Test clang-3.5 64bit_float_utf8: + stage: test + image: registry.gitlab.com/dabroz/mruby:clang35_0.7 + variables: + CC: clang-3.5 + CXX: clang++-3.5 + LD: clang-3.5 + CFLAGS: "-DMRB_USE_FLOAT=1 -DMRB_WORD_BOXING=1 -DMRB_UTF8_STRING=1" + LDFLAGS: '' + script: env; ./minirake --verbose all test +Test clang-3.5 64bit_float_int16: + stage: test + image: registry.gitlab.com/dabroz/mruby:clang35_0.7 + variables: + CC: clang-3.5 + CXX: clang++-3.5 + LD: clang-3.5 + CFLAGS: "-DMRB_USE_FLOAT=1 -DMRB_INT16=1" + LDFLAGS: '' + script: env; ./minirake --verbose all test +Test clang-3.5 64bit_float_int16_utf8: + stage: test + image: registry.gitlab.com/dabroz/mruby:clang35_0.7 + variables: + CC: clang-3.5 + CXX: clang++-3.5 + LD: clang-3.5 + CFLAGS: "-DMRB_USE_FLOAT=1 -DMRB_INT16=1 -DMRB_UTF8_STRING=1" + LDFLAGS: '' + script: env; ./minirake --verbose all test +Test clang-3.5 64bit_float_int64: + stage: test + image: registry.gitlab.com/dabroz/mruby:clang35_0.7 + variables: + CC: clang-3.5 + CXX: clang++-3.5 + LD: clang-3.5 + CFLAGS: "-DMRB_USE_FLOAT=1 -DMRB_INT64=1 -DMRB_WORD_BOXING=1" + LDFLAGS: '' + script: env; ./minirake --verbose all test +Test clang-3.5 64bit_float_int64_utf8: + stage: test + image: registry.gitlab.com/dabroz/mruby:clang35_0.7 + variables: + CC: clang-3.5 + CXX: clang++-3.5 + LD: clang-3.5 + CFLAGS: "-DMRB_USE_FLOAT=1 -DMRB_INT64=1 -DMRB_WORD_BOXING=1 -DMRB_UTF8_STRING=1" + LDFLAGS: '' + script: env; ./minirake --verbose all test +Test clang-3.6 32bit: + stage: test + image: registry.gitlab.com/dabroz/mruby:clang36_0.7 + variables: + CC: clang-3.6 + CXX: clang++-3.6 + LD: clang-3.6 + CFLAGS: "-m32 -DMRB_WORD_BOXING=1" + LDFLAGS: "-m32" + script: env; ./minirake --verbose all test +Test clang-3.6 32bit_utf8: + stage: test + image: registry.gitlab.com/dabroz/mruby:clang36_0.7 + variables: + CC: clang-3.6 + CXX: clang++-3.6 + LD: clang-3.6 + CFLAGS: "-m32 -DMRB_WORD_BOXING=1 -DMRB_UTF8_STRING=1" + LDFLAGS: "-m32" + script: env; ./minirake --verbose all test +Test clang-3.6 32bit_nan: + stage: test + image: registry.gitlab.com/dabroz/mruby:clang36_0.7 + variables: + CC: clang-3.6 + CXX: clang++-3.6 + LD: clang-3.6 + CFLAGS: "-m32 -DMRB_NAN_BOXING=1" + LDFLAGS: "-m32" + script: env; ./minirake --verbose all test +Test clang-3.6 32bit_nan_utf8: + stage: test + image: registry.gitlab.com/dabroz/mruby:clang36_0.7 + variables: + CC: clang-3.6 + CXX: clang++-3.6 + LD: clang-3.6 + CFLAGS: "-m32 -DMRB_NAN_BOXING=1 -DMRB_UTF8_STRING=1" + LDFLAGS: "-m32" + script: env; ./minirake --verbose all test +Test clang-3.6 32bit_int16: + stage: test + image: registry.gitlab.com/dabroz/mruby:clang36_0.7 + variables: + CC: clang-3.6 + CXX: clang++-3.6 + LD: clang-3.6 + CFLAGS: "-m32 -DMRB_INT16=1" + LDFLAGS: "-m32" + script: env; ./minirake --verbose all test +Test clang-3.6 32bit_int16_utf8: + stage: test + image: registry.gitlab.com/dabroz/mruby:clang36_0.7 + variables: + CC: clang-3.6 + CXX: clang++-3.6 + LD: clang-3.6 + CFLAGS: "-m32 -DMRB_INT16=1 -DMRB_UTF8_STRING=1" + LDFLAGS: "-m32" + script: env; ./minirake --verbose all test +Test clang-3.6 32bit_int16_nan: + stage: test + image: registry.gitlab.com/dabroz/mruby:clang36_0.7 + variables: + CC: clang-3.6 + CXX: clang++-3.6 + LD: clang-3.6 + CFLAGS: "-m32 -DMRB_INT16=1 -DMRB_NAN_BOXING=1" + LDFLAGS: "-m32" + script: env; ./minirake --verbose all test +Test clang-3.6 32bit_int16_nan_utf8: + stage: test + image: registry.gitlab.com/dabroz/mruby:clang36_0.7 + variables: + CC: clang-3.6 + CXX: clang++-3.6 + LD: clang-3.6 + CFLAGS: "-m32 -DMRB_INT16=1 -DMRB_NAN_BOXING=1 -DMRB_UTF8_STRING=1" + LDFLAGS: "-m32" + script: env; ./minirake --verbose all test +Test clang-3.6 32bit_int64: + stage: test + image: registry.gitlab.com/dabroz/mruby:clang36_0.7 + variables: + CC: clang-3.6 + CXX: clang++-3.6 + LD: clang-3.6 + CFLAGS: "-m32 -DMRB_INT64=1" + LDFLAGS: "-m32" + script: env; ./minirake --verbose all test +Test clang-3.6 32bit_int64_utf8: + stage: test + image: registry.gitlab.com/dabroz/mruby:clang36_0.7 + variables: + CC: clang-3.6 + CXX: clang++-3.6 + LD: clang-3.6 + CFLAGS: "-m32 -DMRB_INT64=1 -DMRB_UTF8_STRING=1" + LDFLAGS: "-m32" + script: env; ./minirake --verbose all test +Test clang-3.6 32bit_float: + stage: test + image: registry.gitlab.com/dabroz/mruby:clang36_0.7 + variables: + CC: clang-3.6 + CXX: clang++-3.6 + LD: clang-3.6 + CFLAGS: "-m32 -DMRB_USE_FLOAT=1 -DMRB_WORD_BOXING=1" + LDFLAGS: "-m32" + script: env; ./minirake --verbose all test +Test clang-3.6 32bit_float_utf8: + stage: test + image: registry.gitlab.com/dabroz/mruby:clang36_0.7 + variables: + CC: clang-3.6 + CXX: clang++-3.6 + LD: clang-3.6 + CFLAGS: "-m32 -DMRB_USE_FLOAT=1 -DMRB_WORD_BOXING=1 -DMRB_UTF8_STRING=1" + LDFLAGS: "-m32" + script: env; ./minirake --verbose all test +Test clang-3.6 32bit_float_int16: + stage: test + image: registry.gitlab.com/dabroz/mruby:clang36_0.7 + variables: + CC: clang-3.6 + CXX: clang++-3.6 + LD: clang-3.6 + CFLAGS: "-m32 -DMRB_USE_FLOAT=1 -DMRB_INT16=1" + LDFLAGS: "-m32" + script: env; ./minirake --verbose all test +Test clang-3.6 32bit_float_int16_utf8: + stage: test + image: registry.gitlab.com/dabroz/mruby:clang36_0.7 + variables: + CC: clang-3.6 + CXX: clang++-3.6 + LD: clang-3.6 + CFLAGS: "-m32 -DMRB_USE_FLOAT=1 -DMRB_INT16=1 -DMRB_UTF8_STRING=1" + LDFLAGS: "-m32" + script: env; ./minirake --verbose all test +Test clang-3.6 32bit_float_int64: + stage: test + image: registry.gitlab.com/dabroz/mruby:clang36_0.7 + variables: + CC: clang-3.6 + CXX: clang++-3.6 + LD: clang-3.6 + CFLAGS: "-m32 -DMRB_USE_FLOAT=1 -DMRB_INT64=1" + LDFLAGS: "-m32" + script: env; ./minirake --verbose all test +Test clang-3.6 32bit_float_int64_utf8: + stage: test + image: registry.gitlab.com/dabroz/mruby:clang36_0.7 + variables: + CC: clang-3.6 + CXX: clang++-3.6 + LD: clang-3.6 + CFLAGS: "-m32 -DMRB_USE_FLOAT=1 -DMRB_INT64=1 -DMRB_UTF8_STRING=1" + LDFLAGS: "-m32" + script: env; ./minirake --verbose all test +Test clang-3.6 64bit: + stage: test + image: registry.gitlab.com/dabroz/mruby:clang36_0.7 + variables: + CC: clang-3.6 + CXX: clang++-3.6 + LD: clang-3.6 + CFLAGS: "-DMRB_WORD_BOXING=1" + LDFLAGS: '' + script: env; ./minirake --verbose all test +Test clang-3.6 64bit_utf8: + stage: test + image: registry.gitlab.com/dabroz/mruby:clang36_0.7 + variables: + CC: clang-3.6 + CXX: clang++-3.6 + LD: clang-3.6 + CFLAGS: "-DMRB_WORD_BOXING=1 -DMRB_UTF8_STRING=1" + LDFLAGS: '' + script: env; ./minirake --verbose all test +Test clang-3.6 64bit_nan: + stage: test + image: registry.gitlab.com/dabroz/mruby:clang36_0.7 + variables: + CC: clang-3.6 + CXX: clang++-3.6 + LD: clang-3.6 + CFLAGS: "-DMRB_NAN_BOXING=1" + LDFLAGS: '' + script: env; ./minirake --verbose all test +Test clang-3.6 64bit_nan_utf8: + stage: test + image: registry.gitlab.com/dabroz/mruby:clang36_0.7 + variables: + CC: clang-3.6 + CXX: clang++-3.6 + LD: clang-3.6 + CFLAGS: "-DMRB_NAN_BOXING=1 -DMRB_UTF8_STRING=1" + LDFLAGS: '' + script: env; ./minirake --verbose all test +Test clang-3.6 64bit_int16: + stage: test + image: registry.gitlab.com/dabroz/mruby:clang36_0.7 + variables: + CC: clang-3.6 + CXX: clang++-3.6 + LD: clang-3.6 + CFLAGS: "-DMRB_INT16=1" + LDFLAGS: '' + script: env; ./minirake --verbose all test +Test clang-3.6 64bit_int16_utf8: + stage: test + image: registry.gitlab.com/dabroz/mruby:clang36_0.7 + variables: + CC: clang-3.6 + CXX: clang++-3.6 + LD: clang-3.6 + CFLAGS: "-DMRB_INT16=1 -DMRB_UTF8_STRING=1" + LDFLAGS: '' + script: env; ./minirake --verbose all test +Test clang-3.6 64bit_int16_nan: + stage: test + image: registry.gitlab.com/dabroz/mruby:clang36_0.7 + variables: + CC: clang-3.6 + CXX: clang++-3.6 + LD: clang-3.6 + CFLAGS: "-DMRB_INT16=1 -DMRB_NAN_BOXING=1" + LDFLAGS: '' + script: env; ./minirake --verbose all test +Test clang-3.6 64bit_int16_nan_utf8: + stage: test + image: registry.gitlab.com/dabroz/mruby:clang36_0.7 + variables: + CC: clang-3.6 + CXX: clang++-3.6 + LD: clang-3.6 + CFLAGS: "-DMRB_INT16=1 -DMRB_NAN_BOXING=1 -DMRB_UTF8_STRING=1" + LDFLAGS: '' + script: env; ./minirake --verbose all test +Test clang-3.6 64bit_int64: + stage: test + image: registry.gitlab.com/dabroz/mruby:clang36_0.7 + variables: + CC: clang-3.6 + CXX: clang++-3.6 + LD: clang-3.6 + CFLAGS: "-DMRB_INT64=1 -DMRB_WORD_BOXING=1" + LDFLAGS: '' + script: env; ./minirake --verbose all test +Test clang-3.6 64bit_int64_utf8: + stage: test + image: registry.gitlab.com/dabroz/mruby:clang36_0.7 + variables: + CC: clang-3.6 + CXX: clang++-3.6 + LD: clang-3.6 + CFLAGS: "-DMRB_INT64=1 -DMRB_WORD_BOXING=1 -DMRB_UTF8_STRING=1" + LDFLAGS: '' + script: env; ./minirake --verbose all test +Test clang-3.6 64bit_float: + stage: test + image: registry.gitlab.com/dabroz/mruby:clang36_0.7 + variables: + CC: clang-3.6 + CXX: clang++-3.6 + LD: clang-3.6 + CFLAGS: "-DMRB_USE_FLOAT=1 -DMRB_WORD_BOXING=1" + LDFLAGS: '' + script: env; ./minirake --verbose all test +Test clang-3.6 64bit_float_utf8: + stage: test + image: registry.gitlab.com/dabroz/mruby:clang36_0.7 + variables: + CC: clang-3.6 + CXX: clang++-3.6 + LD: clang-3.6 + CFLAGS: "-DMRB_USE_FLOAT=1 -DMRB_WORD_BOXING=1 -DMRB_UTF8_STRING=1" + LDFLAGS: '' + script: env; ./minirake --verbose all test +Test clang-3.6 64bit_float_int16: + stage: test + image: registry.gitlab.com/dabroz/mruby:clang36_0.7 + variables: + CC: clang-3.6 + CXX: clang++-3.6 + LD: clang-3.6 + CFLAGS: "-DMRB_USE_FLOAT=1 -DMRB_INT16=1" + LDFLAGS: '' + script: env; ./minirake --verbose all test +Test clang-3.6 64bit_float_int16_utf8: + stage: test + image: registry.gitlab.com/dabroz/mruby:clang36_0.7 + variables: + CC: clang-3.6 + CXX: clang++-3.6 + LD: clang-3.6 + CFLAGS: "-DMRB_USE_FLOAT=1 -DMRB_INT16=1 -DMRB_UTF8_STRING=1" + LDFLAGS: '' + script: env; ./minirake --verbose all test +Test clang-3.6 64bit_float_int64: + stage: test + image: registry.gitlab.com/dabroz/mruby:clang36_0.7 + variables: + CC: clang-3.6 + CXX: clang++-3.6 + LD: clang-3.6 + CFLAGS: "-DMRB_USE_FLOAT=1 -DMRB_INT64=1 -DMRB_WORD_BOXING=1" + LDFLAGS: '' + script: env; ./minirake --verbose all test +Test clang-3.6 64bit_float_int64_utf8: + stage: test + image: registry.gitlab.com/dabroz/mruby:clang36_0.7 + variables: + CC: clang-3.6 + CXX: clang++-3.6 + LD: clang-3.6 + CFLAGS: "-DMRB_USE_FLOAT=1 -DMRB_INT64=1 -DMRB_WORD_BOXING=1 -DMRB_UTF8_STRING=1" + LDFLAGS: '' + script: env; ./minirake --verbose all test +Test clang-3.7 32bit: + stage: test + image: registry.gitlab.com/dabroz/mruby:clang37_0.7 + variables: + CC: clang-3.7 + CXX: clang++-3.7 + LD: clang-3.7 + CFLAGS: "-m32 -DMRB_WORD_BOXING=1" + LDFLAGS: "-m32" + script: env; ./minirake --verbose all test +Test clang-3.7 32bit_utf8: + stage: test + image: registry.gitlab.com/dabroz/mruby:clang37_0.7 + variables: + CC: clang-3.7 + CXX: clang++-3.7 + LD: clang-3.7 + CFLAGS: "-m32 -DMRB_WORD_BOXING=1 -DMRB_UTF8_STRING=1" + LDFLAGS: "-m32" + script: env; ./minirake --verbose all test +Test clang-3.7 32bit_nan: + stage: test + image: registry.gitlab.com/dabroz/mruby:clang37_0.7 + variables: + CC: clang-3.7 + CXX: clang++-3.7 + LD: clang-3.7 + CFLAGS: "-m32 -DMRB_NAN_BOXING=1" + LDFLAGS: "-m32" + script: env; ./minirake --verbose all test +Test clang-3.7 32bit_nan_utf8: + stage: test + image: registry.gitlab.com/dabroz/mruby:clang37_0.7 + variables: + CC: clang-3.7 + CXX: clang++-3.7 + LD: clang-3.7 + CFLAGS: "-m32 -DMRB_NAN_BOXING=1 -DMRB_UTF8_STRING=1" + LDFLAGS: "-m32" + script: env; ./minirake --verbose all test +Test clang-3.7 32bit_int16: + stage: test + image: registry.gitlab.com/dabroz/mruby:clang37_0.7 + variables: + CC: clang-3.7 + CXX: clang++-3.7 + LD: clang-3.7 + CFLAGS: "-m32 -DMRB_INT16=1" + LDFLAGS: "-m32" + script: env; ./minirake --verbose all test +Test clang-3.7 32bit_int16_utf8: + stage: test + image: registry.gitlab.com/dabroz/mruby:clang37_0.7 + variables: + CC: clang-3.7 + CXX: clang++-3.7 + LD: clang-3.7 + CFLAGS: "-m32 -DMRB_INT16=1 -DMRB_UTF8_STRING=1" + LDFLAGS: "-m32" + script: env; ./minirake --verbose all test +Test clang-3.7 32bit_int16_nan: + stage: test + image: registry.gitlab.com/dabroz/mruby:clang37_0.7 + variables: + CC: clang-3.7 + CXX: clang++-3.7 + LD: clang-3.7 + CFLAGS: "-m32 -DMRB_INT16=1 -DMRB_NAN_BOXING=1" + LDFLAGS: "-m32" + script: env; ./minirake --verbose all test +Test clang-3.7 32bit_int16_nan_utf8: + stage: test + image: registry.gitlab.com/dabroz/mruby:clang37_0.7 + variables: + CC: clang-3.7 + CXX: clang++-3.7 + LD: clang-3.7 + CFLAGS: "-m32 -DMRB_INT16=1 -DMRB_NAN_BOXING=1 -DMRB_UTF8_STRING=1" + LDFLAGS: "-m32" + script: env; ./minirake --verbose all test +Test clang-3.7 32bit_int64: + stage: test + image: registry.gitlab.com/dabroz/mruby:clang37_0.7 + variables: + CC: clang-3.7 + CXX: clang++-3.7 + LD: clang-3.7 + CFLAGS: "-m32 -DMRB_INT64=1" + LDFLAGS: "-m32" + script: env; ./minirake --verbose all test +Test clang-3.7 32bit_int64_utf8: + stage: test + image: registry.gitlab.com/dabroz/mruby:clang37_0.7 + variables: + CC: clang-3.7 + CXX: clang++-3.7 + LD: clang-3.7 + CFLAGS: "-m32 -DMRB_INT64=1 -DMRB_UTF8_STRING=1" + LDFLAGS: "-m32" + script: env; ./minirake --verbose all test +Test clang-3.7 32bit_float: + stage: test + image: registry.gitlab.com/dabroz/mruby:clang37_0.7 + variables: + CC: clang-3.7 + CXX: clang++-3.7 + LD: clang-3.7 + CFLAGS: "-m32 -DMRB_USE_FLOAT=1 -DMRB_WORD_BOXING=1" + LDFLAGS: "-m32" + script: env; ./minirake --verbose all test +Test clang-3.7 32bit_float_utf8: + stage: test + image: registry.gitlab.com/dabroz/mruby:clang37_0.7 + variables: + CC: clang-3.7 + CXX: clang++-3.7 + LD: clang-3.7 + CFLAGS: "-m32 -DMRB_USE_FLOAT=1 -DMRB_WORD_BOXING=1 -DMRB_UTF8_STRING=1" + LDFLAGS: "-m32" + script: env; ./minirake --verbose all test +Test clang-3.7 32bit_float_int16: + stage: test + image: registry.gitlab.com/dabroz/mruby:clang37_0.7 + variables: + CC: clang-3.7 + CXX: clang++-3.7 + LD: clang-3.7 + CFLAGS: "-m32 -DMRB_USE_FLOAT=1 -DMRB_INT16=1" + LDFLAGS: "-m32" + script: env; ./minirake --verbose all test +Test clang-3.7 32bit_float_int16_utf8: + stage: test + image: registry.gitlab.com/dabroz/mruby:clang37_0.7 + variables: + CC: clang-3.7 + CXX: clang++-3.7 + LD: clang-3.7 + CFLAGS: "-m32 -DMRB_USE_FLOAT=1 -DMRB_INT16=1 -DMRB_UTF8_STRING=1" + LDFLAGS: "-m32" + script: env; ./minirake --verbose all test +Test clang-3.7 32bit_float_int64: + stage: test + image: registry.gitlab.com/dabroz/mruby:clang37_0.7 + variables: + CC: clang-3.7 + CXX: clang++-3.7 + LD: clang-3.7 + CFLAGS: "-m32 -DMRB_USE_FLOAT=1 -DMRB_INT64=1" + LDFLAGS: "-m32" + script: env; ./minirake --verbose all test +Test clang-3.7 32bit_float_int64_utf8: + stage: test + image: registry.gitlab.com/dabroz/mruby:clang37_0.7 + variables: + CC: clang-3.7 + CXX: clang++-3.7 + LD: clang-3.7 + CFLAGS: "-m32 -DMRB_USE_FLOAT=1 -DMRB_INT64=1 -DMRB_UTF8_STRING=1" + LDFLAGS: "-m32" + script: env; ./minirake --verbose all test +Test clang-3.7 64bit: + stage: test + image: registry.gitlab.com/dabroz/mruby:clang37_0.7 + variables: + CC: clang-3.7 + CXX: clang++-3.7 + LD: clang-3.7 + CFLAGS: "-DMRB_WORD_BOXING=1" + LDFLAGS: '' + script: env; ./minirake --verbose all test +Test clang-3.7 64bit_utf8: + stage: test + image: registry.gitlab.com/dabroz/mruby:clang37_0.7 + variables: + CC: clang-3.7 + CXX: clang++-3.7 + LD: clang-3.7 + CFLAGS: "-DMRB_WORD_BOXING=1 -DMRB_UTF8_STRING=1" + LDFLAGS: '' + script: env; ./minirake --verbose all test +Test clang-3.7 64bit_nan: + stage: test + image: registry.gitlab.com/dabroz/mruby:clang37_0.7 + variables: + CC: clang-3.7 + CXX: clang++-3.7 + LD: clang-3.7 + CFLAGS: "-DMRB_NAN_BOXING=1" + LDFLAGS: '' + script: env; ./minirake --verbose all test +Test clang-3.7 64bit_nan_utf8: + stage: test + image: registry.gitlab.com/dabroz/mruby:clang37_0.7 + variables: + CC: clang-3.7 + CXX: clang++-3.7 + LD: clang-3.7 + CFLAGS: "-DMRB_NAN_BOXING=1 -DMRB_UTF8_STRING=1" + LDFLAGS: '' + script: env; ./minirake --verbose all test +Test clang-3.7 64bit_int16: + stage: test + image: registry.gitlab.com/dabroz/mruby:clang37_0.7 + variables: + CC: clang-3.7 + CXX: clang++-3.7 + LD: clang-3.7 + CFLAGS: "-DMRB_INT16=1" + LDFLAGS: '' + script: env; ./minirake --verbose all test +Test clang-3.7 64bit_int16_utf8: + stage: test + image: registry.gitlab.com/dabroz/mruby:clang37_0.7 + variables: + CC: clang-3.7 + CXX: clang++-3.7 + LD: clang-3.7 + CFLAGS: "-DMRB_INT16=1 -DMRB_UTF8_STRING=1" + LDFLAGS: '' + script: env; ./minirake --verbose all test +Test clang-3.7 64bit_int16_nan: + stage: test + image: registry.gitlab.com/dabroz/mruby:clang37_0.7 + variables: + CC: clang-3.7 + CXX: clang++-3.7 + LD: clang-3.7 + CFLAGS: "-DMRB_INT16=1 -DMRB_NAN_BOXING=1" + LDFLAGS: '' + script: env; ./minirake --verbose all test +Test clang-3.7 64bit_int16_nan_utf8: + stage: test + image: registry.gitlab.com/dabroz/mruby:clang37_0.7 + variables: + CC: clang-3.7 + CXX: clang++-3.7 + LD: clang-3.7 + CFLAGS: "-DMRB_INT16=1 -DMRB_NAN_BOXING=1 -DMRB_UTF8_STRING=1" + LDFLAGS: '' + script: env; ./minirake --verbose all test +Test clang-3.7 64bit_int64: + stage: test + image: registry.gitlab.com/dabroz/mruby:clang37_0.7 + variables: + CC: clang-3.7 + CXX: clang++-3.7 + LD: clang-3.7 + CFLAGS: "-DMRB_INT64=1 -DMRB_WORD_BOXING=1" + LDFLAGS: '' + script: env; ./minirake --verbose all test +Test clang-3.7 64bit_int64_utf8: + stage: test + image: registry.gitlab.com/dabroz/mruby:clang37_0.7 + variables: + CC: clang-3.7 + CXX: clang++-3.7 + LD: clang-3.7 + CFLAGS: "-DMRB_INT64=1 -DMRB_WORD_BOXING=1 -DMRB_UTF8_STRING=1" + LDFLAGS: '' + script: env; ./minirake --verbose all test +Test clang-3.7 64bit_float: + stage: test + image: registry.gitlab.com/dabroz/mruby:clang37_0.7 + variables: + CC: clang-3.7 + CXX: clang++-3.7 + LD: clang-3.7 + CFLAGS: "-DMRB_USE_FLOAT=1 -DMRB_WORD_BOXING=1" + LDFLAGS: '' + script: env; ./minirake --verbose all test +Test clang-3.7 64bit_float_utf8: + stage: test + image: registry.gitlab.com/dabroz/mruby:clang37_0.7 + variables: + CC: clang-3.7 + CXX: clang++-3.7 + LD: clang-3.7 + CFLAGS: "-DMRB_USE_FLOAT=1 -DMRB_WORD_BOXING=1 -DMRB_UTF8_STRING=1" + LDFLAGS: '' + script: env; ./minirake --verbose all test +Test clang-3.7 64bit_float_int16: + stage: test + image: registry.gitlab.com/dabroz/mruby:clang37_0.7 + variables: + CC: clang-3.7 + CXX: clang++-3.7 + LD: clang-3.7 + CFLAGS: "-DMRB_USE_FLOAT=1 -DMRB_INT16=1" + LDFLAGS: '' + script: env; ./minirake --verbose all test +Test clang-3.7 64bit_float_int16_utf8: + stage: test + image: registry.gitlab.com/dabroz/mruby:clang37_0.7 + variables: + CC: clang-3.7 + CXX: clang++-3.7 + LD: clang-3.7 + CFLAGS: "-DMRB_USE_FLOAT=1 -DMRB_INT16=1 -DMRB_UTF8_STRING=1" + LDFLAGS: '' + script: env; ./minirake --verbose all test +Test clang-3.7 64bit_float_int64: + stage: test + image: registry.gitlab.com/dabroz/mruby:clang37_0.7 + variables: + CC: clang-3.7 + CXX: clang++-3.7 + LD: clang-3.7 + CFLAGS: "-DMRB_USE_FLOAT=1 -DMRB_INT64=1 -DMRB_WORD_BOXING=1" + LDFLAGS: '' + script: env; ./minirake --verbose all test +Test clang-3.7 64bit_float_int64_utf8: + stage: test + image: registry.gitlab.com/dabroz/mruby:clang37_0.7 + variables: + CC: clang-3.7 + CXX: clang++-3.7 + LD: clang-3.7 + CFLAGS: "-DMRB_USE_FLOAT=1 -DMRB_INT64=1 -DMRB_WORD_BOXING=1 -DMRB_UTF8_STRING=1" + LDFLAGS: '' + script: env; ./minirake --verbose all test +Test clang-3.8 32bit: + stage: test + image: registry.gitlab.com/dabroz/mruby:clang38_0.7 + variables: + CC: clang-3.8 + CXX: clang++-3.8 + LD: clang-3.8 + CFLAGS: "-m32 -DMRB_WORD_BOXING=1" + LDFLAGS: "-m32" + script: env; ./minirake --verbose all test +Test clang-3.8 32bit_utf8: + stage: test + image: registry.gitlab.com/dabroz/mruby:clang38_0.7 + variables: + CC: clang-3.8 + CXX: clang++-3.8 + LD: clang-3.8 + CFLAGS: "-m32 -DMRB_WORD_BOXING=1 -DMRB_UTF8_STRING=1" + LDFLAGS: "-m32" + script: env; ./minirake --verbose all test +Test clang-3.8 32bit_nan: + stage: test + image: registry.gitlab.com/dabroz/mruby:clang38_0.7 + variables: + CC: clang-3.8 + CXX: clang++-3.8 + LD: clang-3.8 + CFLAGS: "-m32 -DMRB_NAN_BOXING=1" + LDFLAGS: "-m32" + script: env; ./minirake --verbose all test +Test clang-3.8 32bit_nan_utf8: + stage: test + image: registry.gitlab.com/dabroz/mruby:clang38_0.7 + variables: + CC: clang-3.8 + CXX: clang++-3.8 + LD: clang-3.8 + CFLAGS: "-m32 -DMRB_NAN_BOXING=1 -DMRB_UTF8_STRING=1" + LDFLAGS: "-m32" + script: env; ./minirake --verbose all test +Test clang-3.8 32bit_int16: + stage: test + image: registry.gitlab.com/dabroz/mruby:clang38_0.7 + variables: + CC: clang-3.8 + CXX: clang++-3.8 + LD: clang-3.8 + CFLAGS: "-m32 -DMRB_INT16=1" + LDFLAGS: "-m32" + script: env; ./minirake --verbose all test +Test clang-3.8 32bit_int16_utf8: + stage: test + image: registry.gitlab.com/dabroz/mruby:clang38_0.7 + variables: + CC: clang-3.8 + CXX: clang++-3.8 + LD: clang-3.8 + CFLAGS: "-m32 -DMRB_INT16=1 -DMRB_UTF8_STRING=1" + LDFLAGS: "-m32" + script: env; ./minirake --verbose all test +Test clang-3.8 32bit_int16_nan: + stage: test + image: registry.gitlab.com/dabroz/mruby:clang38_0.7 + variables: + CC: clang-3.8 + CXX: clang++-3.8 + LD: clang-3.8 + CFLAGS: "-m32 -DMRB_INT16=1 -DMRB_NAN_BOXING=1" + LDFLAGS: "-m32" + script: env; ./minirake --verbose all test +Test clang-3.8 32bit_int16_nan_utf8: + stage: test + image: registry.gitlab.com/dabroz/mruby:clang38_0.7 + variables: + CC: clang-3.8 + CXX: clang++-3.8 + LD: clang-3.8 + CFLAGS: "-m32 -DMRB_INT16=1 -DMRB_NAN_BOXING=1 -DMRB_UTF8_STRING=1" + LDFLAGS: "-m32" + script: env; ./minirake --verbose all test +Test clang-3.8 32bit_int64: + stage: test + image: registry.gitlab.com/dabroz/mruby:clang38_0.7 + variables: + CC: clang-3.8 + CXX: clang++-3.8 + LD: clang-3.8 + CFLAGS: "-m32 -DMRB_INT64=1" + LDFLAGS: "-m32" + script: env; ./minirake --verbose all test +Test clang-3.8 32bit_int64_utf8: + stage: test + image: registry.gitlab.com/dabroz/mruby:clang38_0.7 + variables: + CC: clang-3.8 + CXX: clang++-3.8 + LD: clang-3.8 + CFLAGS: "-m32 -DMRB_INT64=1 -DMRB_UTF8_STRING=1" + LDFLAGS: "-m32" + script: env; ./minirake --verbose all test +Test clang-3.8 32bit_float: + stage: test + image: registry.gitlab.com/dabroz/mruby:clang38_0.7 + variables: + CC: clang-3.8 + CXX: clang++-3.8 + LD: clang-3.8 + CFLAGS: "-m32 -DMRB_USE_FLOAT=1 -DMRB_WORD_BOXING=1" + LDFLAGS: "-m32" + script: env; ./minirake --verbose all test +Test clang-3.8 32bit_float_utf8: + stage: test + image: registry.gitlab.com/dabroz/mruby:clang38_0.7 + variables: + CC: clang-3.8 + CXX: clang++-3.8 + LD: clang-3.8 + CFLAGS: "-m32 -DMRB_USE_FLOAT=1 -DMRB_WORD_BOXING=1 -DMRB_UTF8_STRING=1" + LDFLAGS: "-m32" + script: env; ./minirake --verbose all test +Test clang-3.8 32bit_float_int16: + stage: test + image: registry.gitlab.com/dabroz/mruby:clang38_0.7 + variables: + CC: clang-3.8 + CXX: clang++-3.8 + LD: clang-3.8 + CFLAGS: "-m32 -DMRB_USE_FLOAT=1 -DMRB_INT16=1" + LDFLAGS: "-m32" + script: env; ./minirake --verbose all test +Test clang-3.8 32bit_float_int16_utf8: + stage: test + image: registry.gitlab.com/dabroz/mruby:clang38_0.7 + variables: + CC: clang-3.8 + CXX: clang++-3.8 + LD: clang-3.8 + CFLAGS: "-m32 -DMRB_USE_FLOAT=1 -DMRB_INT16=1 -DMRB_UTF8_STRING=1" + LDFLAGS: "-m32" + script: env; ./minirake --verbose all test +Test clang-3.8 32bit_float_int64: + stage: test + image: registry.gitlab.com/dabroz/mruby:clang38_0.7 + variables: + CC: clang-3.8 + CXX: clang++-3.8 + LD: clang-3.8 + CFLAGS: "-m32 -DMRB_USE_FLOAT=1 -DMRB_INT64=1" + LDFLAGS: "-m32" + script: env; ./minirake --verbose all test +Test clang-3.8 32bit_float_int64_utf8: + stage: test + image: registry.gitlab.com/dabroz/mruby:clang38_0.7 + variables: + CC: clang-3.8 + CXX: clang++-3.8 + LD: clang-3.8 + CFLAGS: "-m32 -DMRB_USE_FLOAT=1 -DMRB_INT64=1 -DMRB_UTF8_STRING=1" + LDFLAGS: "-m32" + script: env; ./minirake --verbose all test +Test clang-3.8 64bit: + stage: test + image: registry.gitlab.com/dabroz/mruby:clang38_0.7 + variables: + CC: clang-3.8 + CXX: clang++-3.8 + LD: clang-3.8 + CFLAGS: "-DMRB_WORD_BOXING=1" + LDFLAGS: '' + script: env; ./minirake --verbose all test +Test clang-3.8 64bit_utf8: + stage: test + image: registry.gitlab.com/dabroz/mruby:clang38_0.7 + variables: + CC: clang-3.8 + CXX: clang++-3.8 + LD: clang-3.8 + CFLAGS: "-DMRB_WORD_BOXING=1 -DMRB_UTF8_STRING=1" + LDFLAGS: '' + script: env; ./minirake --verbose all test +Test clang-3.8 64bit_nan: + stage: test + image: registry.gitlab.com/dabroz/mruby:clang38_0.7 + variables: + CC: clang-3.8 + CXX: clang++-3.8 + LD: clang-3.8 + CFLAGS: "-DMRB_NAN_BOXING=1" + LDFLAGS: '' + script: env; ./minirake --verbose all test +Test clang-3.8 64bit_nan_utf8: + stage: test + image: registry.gitlab.com/dabroz/mruby:clang38_0.7 + variables: + CC: clang-3.8 + CXX: clang++-3.8 + LD: clang-3.8 + CFLAGS: "-DMRB_NAN_BOXING=1 -DMRB_UTF8_STRING=1" + LDFLAGS: '' + script: env; ./minirake --verbose all test +Test clang-3.8 64bit_int16: + stage: test + image: registry.gitlab.com/dabroz/mruby:clang38_0.7 + variables: + CC: clang-3.8 + CXX: clang++-3.8 + LD: clang-3.8 + CFLAGS: "-DMRB_INT16=1" + LDFLAGS: '' + script: env; ./minirake --verbose all test +Test clang-3.8 64bit_int16_utf8: + stage: test + image: registry.gitlab.com/dabroz/mruby:clang38_0.7 + variables: + CC: clang-3.8 + CXX: clang++-3.8 + LD: clang-3.8 + CFLAGS: "-DMRB_INT16=1 -DMRB_UTF8_STRING=1" + LDFLAGS: '' + script: env; ./minirake --verbose all test +Test clang-3.8 64bit_int16_nan: + stage: test + image: registry.gitlab.com/dabroz/mruby:clang38_0.7 + variables: + CC: clang-3.8 + CXX: clang++-3.8 + LD: clang-3.8 + CFLAGS: "-DMRB_INT16=1 -DMRB_NAN_BOXING=1" + LDFLAGS: '' + script: env; ./minirake --verbose all test +Test clang-3.8 64bit_int16_nan_utf8: + stage: test + image: registry.gitlab.com/dabroz/mruby:clang38_0.7 + variables: + CC: clang-3.8 + CXX: clang++-3.8 + LD: clang-3.8 + CFLAGS: "-DMRB_INT16=1 -DMRB_NAN_BOXING=1 -DMRB_UTF8_STRING=1" + LDFLAGS: '' + script: env; ./minirake --verbose all test +Test clang-3.8 64bit_int64: + stage: test + image: registry.gitlab.com/dabroz/mruby:clang38_0.7 + variables: + CC: clang-3.8 + CXX: clang++-3.8 + LD: clang-3.8 + CFLAGS: "-DMRB_INT64=1 -DMRB_WORD_BOXING=1" + LDFLAGS: '' + script: env; ./minirake --verbose all test +Test clang-3.8 64bit_int64_utf8: + stage: test + image: registry.gitlab.com/dabroz/mruby:clang38_0.7 + variables: + CC: clang-3.8 + CXX: clang++-3.8 + LD: clang-3.8 + CFLAGS: "-DMRB_INT64=1 -DMRB_WORD_BOXING=1 -DMRB_UTF8_STRING=1" + LDFLAGS: '' + script: env; ./minirake --verbose all test +Test clang-3.8 64bit_float: + stage: test + image: registry.gitlab.com/dabroz/mruby:clang38_0.7 + variables: + CC: clang-3.8 + CXX: clang++-3.8 + LD: clang-3.8 + CFLAGS: "-DMRB_USE_FLOAT=1 -DMRB_WORD_BOXING=1" + LDFLAGS: '' + script: env; ./minirake --verbose all test +Test clang-3.8 64bit_float_utf8: + stage: test + image: registry.gitlab.com/dabroz/mruby:clang38_0.7 + variables: + CC: clang-3.8 + CXX: clang++-3.8 + LD: clang-3.8 + CFLAGS: "-DMRB_USE_FLOAT=1 -DMRB_WORD_BOXING=1 -DMRB_UTF8_STRING=1" + LDFLAGS: '' + script: env; ./minirake --verbose all test +Test clang-3.8 64bit_float_int16: + stage: test + image: registry.gitlab.com/dabroz/mruby:clang38_0.7 + variables: + CC: clang-3.8 + CXX: clang++-3.8 + LD: clang-3.8 + CFLAGS: "-DMRB_USE_FLOAT=1 -DMRB_INT16=1" + LDFLAGS: '' + script: env; ./minirake --verbose all test +Test clang-3.8 64bit_float_int16_utf8: + stage: test + image: registry.gitlab.com/dabroz/mruby:clang38_0.7 + variables: + CC: clang-3.8 + CXX: clang++-3.8 + LD: clang-3.8 + CFLAGS: "-DMRB_USE_FLOAT=1 -DMRB_INT16=1 -DMRB_UTF8_STRING=1" + LDFLAGS: '' + script: env; ./minirake --verbose all test +Test clang-3.8 64bit_float_int64: + stage: test + image: registry.gitlab.com/dabroz/mruby:clang38_0.7 + variables: + CC: clang-3.8 + CXX: clang++-3.8 + LD: clang-3.8 + CFLAGS: "-DMRB_USE_FLOAT=1 -DMRB_INT64=1 -DMRB_WORD_BOXING=1" + LDFLAGS: '' + script: env; ./minirake --verbose all test +Test clang-3.8 64bit_float_int64_utf8: + stage: test + image: registry.gitlab.com/dabroz/mruby:clang38_0.7 + variables: + CC: clang-3.8 + CXX: clang++-3.8 + LD: clang-3.8 + CFLAGS: "-DMRB_USE_FLOAT=1 -DMRB_INT64=1 -DMRB_WORD_BOXING=1 -DMRB_UTF8_STRING=1" + LDFLAGS: '' + script: env; ./minirake --verbose all test +Test clang-3.9 32bit: + stage: test + image: registry.gitlab.com/dabroz/mruby:clang39_0.7 + variables: + CC: clang-3.9 + CXX: clang++-3.9 + LD: clang-3.9 + CFLAGS: "-m32 -DMRB_WORD_BOXING=1" + LDFLAGS: "-m32" + script: env; ./minirake --verbose all test +Test clang-3.9 32bit_utf8: + stage: test + image: registry.gitlab.com/dabroz/mruby:clang39_0.7 + variables: + CC: clang-3.9 + CXX: clang++-3.9 + LD: clang-3.9 + CFLAGS: "-m32 -DMRB_WORD_BOXING=1 -DMRB_UTF8_STRING=1" + LDFLAGS: "-m32" + script: env; ./minirake --verbose all test +Test clang-3.9 32bit_nan: + stage: test + image: registry.gitlab.com/dabroz/mruby:clang39_0.7 + variables: + CC: clang-3.9 + CXX: clang++-3.9 + LD: clang-3.9 + CFLAGS: "-m32 -DMRB_NAN_BOXING=1" + LDFLAGS: "-m32" + script: env; ./minirake --verbose all test +Test clang-3.9 32bit_nan_utf8: + stage: test + image: registry.gitlab.com/dabroz/mruby:clang39_0.7 + variables: + CC: clang-3.9 + CXX: clang++-3.9 + LD: clang-3.9 + CFLAGS: "-m32 -DMRB_NAN_BOXING=1 -DMRB_UTF8_STRING=1" + LDFLAGS: "-m32" + script: env; ./minirake --verbose all test +Test clang-3.9 32bit_int16: + stage: test + image: registry.gitlab.com/dabroz/mruby:clang39_0.7 + variables: + CC: clang-3.9 + CXX: clang++-3.9 + LD: clang-3.9 + CFLAGS: "-m32 -DMRB_INT16=1" + LDFLAGS: "-m32" + script: env; ./minirake --verbose all test +Test clang-3.9 32bit_int16_utf8: + stage: test + image: registry.gitlab.com/dabroz/mruby:clang39_0.7 + variables: + CC: clang-3.9 + CXX: clang++-3.9 + LD: clang-3.9 + CFLAGS: "-m32 -DMRB_INT16=1 -DMRB_UTF8_STRING=1" + LDFLAGS: "-m32" + script: env; ./minirake --verbose all test +Test clang-3.9 32bit_int16_nan: + stage: test + image: registry.gitlab.com/dabroz/mruby:clang39_0.7 + variables: + CC: clang-3.9 + CXX: clang++-3.9 + LD: clang-3.9 + CFLAGS: "-m32 -DMRB_INT16=1 -DMRB_NAN_BOXING=1" + LDFLAGS: "-m32" + script: env; ./minirake --verbose all test +Test clang-3.9 32bit_int16_nan_utf8: + stage: test + image: registry.gitlab.com/dabroz/mruby:clang39_0.7 + variables: + CC: clang-3.9 + CXX: clang++-3.9 + LD: clang-3.9 + CFLAGS: "-m32 -DMRB_INT16=1 -DMRB_NAN_BOXING=1 -DMRB_UTF8_STRING=1" + LDFLAGS: "-m32" + script: env; ./minirake --verbose all test +Test clang-3.9 32bit_int64: + stage: test + image: registry.gitlab.com/dabroz/mruby:clang39_0.7 + variables: + CC: clang-3.9 + CXX: clang++-3.9 + LD: clang-3.9 + CFLAGS: "-m32 -DMRB_INT64=1" + LDFLAGS: "-m32" + script: env; ./minirake --verbose all test +Test clang-3.9 32bit_int64_utf8: + stage: test + image: registry.gitlab.com/dabroz/mruby:clang39_0.7 + variables: + CC: clang-3.9 + CXX: clang++-3.9 + LD: clang-3.9 + CFLAGS: "-m32 -DMRB_INT64=1 -DMRB_UTF8_STRING=1" + LDFLAGS: "-m32" + script: env; ./minirake --verbose all test +Test clang-3.9 32bit_float: + stage: test + image: registry.gitlab.com/dabroz/mruby:clang39_0.7 + variables: + CC: clang-3.9 + CXX: clang++-3.9 + LD: clang-3.9 + CFLAGS: "-m32 -DMRB_USE_FLOAT=1 -DMRB_WORD_BOXING=1" + LDFLAGS: "-m32" + script: env; ./minirake --verbose all test +Test clang-3.9 32bit_float_utf8: + stage: test + image: registry.gitlab.com/dabroz/mruby:clang39_0.7 + variables: + CC: clang-3.9 + CXX: clang++-3.9 + LD: clang-3.9 + CFLAGS: "-m32 -DMRB_USE_FLOAT=1 -DMRB_WORD_BOXING=1 -DMRB_UTF8_STRING=1" + LDFLAGS: "-m32" + script: env; ./minirake --verbose all test +Test clang-3.9 32bit_float_int16: + stage: test + image: registry.gitlab.com/dabroz/mruby:clang39_0.7 + variables: + CC: clang-3.9 + CXX: clang++-3.9 + LD: clang-3.9 + CFLAGS: "-m32 -DMRB_USE_FLOAT=1 -DMRB_INT16=1" + LDFLAGS: "-m32" + script: env; ./minirake --verbose all test +Test clang-3.9 32bit_float_int16_utf8: + stage: test + image: registry.gitlab.com/dabroz/mruby:clang39_0.7 + variables: + CC: clang-3.9 + CXX: clang++-3.9 + LD: clang-3.9 + CFLAGS: "-m32 -DMRB_USE_FLOAT=1 -DMRB_INT16=1 -DMRB_UTF8_STRING=1" + LDFLAGS: "-m32" + script: env; ./minirake --verbose all test +Test clang-3.9 32bit_float_int64: + stage: test + image: registry.gitlab.com/dabroz/mruby:clang39_0.7 + variables: + CC: clang-3.9 + CXX: clang++-3.9 + LD: clang-3.9 + CFLAGS: "-m32 -DMRB_USE_FLOAT=1 -DMRB_INT64=1" + LDFLAGS: "-m32" + script: env; ./minirake --verbose all test +Test clang-3.9 32bit_float_int64_utf8: + stage: test + image: registry.gitlab.com/dabroz/mruby:clang39_0.7 + variables: + CC: clang-3.9 + CXX: clang++-3.9 + LD: clang-3.9 + CFLAGS: "-m32 -DMRB_USE_FLOAT=1 -DMRB_INT64=1 -DMRB_UTF8_STRING=1" + LDFLAGS: "-m32" + script: env; ./minirake --verbose all test +Test clang-3.9 64bit: + stage: test + image: registry.gitlab.com/dabroz/mruby:clang39_0.7 + variables: + CC: clang-3.9 + CXX: clang++-3.9 + LD: clang-3.9 + CFLAGS: "-DMRB_WORD_BOXING=1" + LDFLAGS: '' + script: env; ./minirake --verbose all test +Test clang-3.9 64bit_utf8: + stage: test + image: registry.gitlab.com/dabroz/mruby:clang39_0.7 + variables: + CC: clang-3.9 + CXX: clang++-3.9 + LD: clang-3.9 + CFLAGS: "-DMRB_WORD_BOXING=1 -DMRB_UTF8_STRING=1" + LDFLAGS: '' + script: env; ./minirake --verbose all test +Test clang-3.9 64bit_nan: + stage: test + image: registry.gitlab.com/dabroz/mruby:clang39_0.7 + variables: + CC: clang-3.9 + CXX: clang++-3.9 + LD: clang-3.9 + CFLAGS: "-DMRB_NAN_BOXING=1" + LDFLAGS: '' + script: env; ./minirake --verbose all test +Test clang-3.9 64bit_nan_utf8: + stage: test + image: registry.gitlab.com/dabroz/mruby:clang39_0.7 + variables: + CC: clang-3.9 + CXX: clang++-3.9 + LD: clang-3.9 + CFLAGS: "-DMRB_NAN_BOXING=1 -DMRB_UTF8_STRING=1" + LDFLAGS: '' + script: env; ./minirake --verbose all test +Test clang-3.9 64bit_int16: + stage: test + image: registry.gitlab.com/dabroz/mruby:clang39_0.7 + variables: + CC: clang-3.9 + CXX: clang++-3.9 + LD: clang-3.9 + CFLAGS: "-DMRB_INT16=1" + LDFLAGS: '' + script: env; ./minirake --verbose all test +Test clang-3.9 64bit_int16_utf8: + stage: test + image: registry.gitlab.com/dabroz/mruby:clang39_0.7 + variables: + CC: clang-3.9 + CXX: clang++-3.9 + LD: clang-3.9 + CFLAGS: "-DMRB_INT16=1 -DMRB_UTF8_STRING=1" + LDFLAGS: '' + script: env; ./minirake --verbose all test +Test clang-3.9 64bit_int16_nan: + stage: test + image: registry.gitlab.com/dabroz/mruby:clang39_0.7 + variables: + CC: clang-3.9 + CXX: clang++-3.9 + LD: clang-3.9 + CFLAGS: "-DMRB_INT16=1 -DMRB_NAN_BOXING=1" + LDFLAGS: '' + script: env; ./minirake --verbose all test +Test clang-3.9 64bit_int16_nan_utf8: + stage: test + image: registry.gitlab.com/dabroz/mruby:clang39_0.7 + variables: + CC: clang-3.9 + CXX: clang++-3.9 + LD: clang-3.9 + CFLAGS: "-DMRB_INT16=1 -DMRB_NAN_BOXING=1 -DMRB_UTF8_STRING=1" + LDFLAGS: '' + script: env; ./minirake --verbose all test +Test clang-3.9 64bit_int64: + stage: test + image: registry.gitlab.com/dabroz/mruby:clang39_0.7 + variables: + CC: clang-3.9 + CXX: clang++-3.9 + LD: clang-3.9 + CFLAGS: "-DMRB_INT64=1 -DMRB_WORD_BOXING=1" + LDFLAGS: '' + script: env; ./minirake --verbose all test +Test clang-3.9 64bit_int64_utf8: + stage: test + image: registry.gitlab.com/dabroz/mruby:clang39_0.7 + variables: + CC: clang-3.9 + CXX: clang++-3.9 + LD: clang-3.9 + CFLAGS: "-DMRB_INT64=1 -DMRB_WORD_BOXING=1 -DMRB_UTF8_STRING=1" + LDFLAGS: '' + script: env; ./minirake --verbose all test +Test clang-3.9 64bit_float: + stage: test + image: registry.gitlab.com/dabroz/mruby:clang39_0.7 + variables: + CC: clang-3.9 + CXX: clang++-3.9 + LD: clang-3.9 + CFLAGS: "-DMRB_USE_FLOAT=1 -DMRB_WORD_BOXING=1" + LDFLAGS: '' + script: env; ./minirake --verbose all test +Test clang-3.9 64bit_float_utf8: + stage: test + image: registry.gitlab.com/dabroz/mruby:clang39_0.7 + variables: + CC: clang-3.9 + CXX: clang++-3.9 + LD: clang-3.9 + CFLAGS: "-DMRB_USE_FLOAT=1 -DMRB_WORD_BOXING=1 -DMRB_UTF8_STRING=1" + LDFLAGS: '' + script: env; ./minirake --verbose all test +Test clang-3.9 64bit_float_int16: + stage: test + image: registry.gitlab.com/dabroz/mruby:clang39_0.7 + variables: + CC: clang-3.9 + CXX: clang++-3.9 + LD: clang-3.9 + CFLAGS: "-DMRB_USE_FLOAT=1 -DMRB_INT16=1" + LDFLAGS: '' + script: env; ./minirake --verbose all test +Test clang-3.9 64bit_float_int16_utf8: + stage: test + image: registry.gitlab.com/dabroz/mruby:clang39_0.7 + variables: + CC: clang-3.9 + CXX: clang++-3.9 + LD: clang-3.9 + CFLAGS: "-DMRB_USE_FLOAT=1 -DMRB_INT16=1 -DMRB_UTF8_STRING=1" + LDFLAGS: '' + script: env; ./minirake --verbose all test +Test clang-3.9 64bit_float_int64: + stage: test + image: registry.gitlab.com/dabroz/mruby:clang39_0.7 + variables: + CC: clang-3.9 + CXX: clang++-3.9 + LD: clang-3.9 + CFLAGS: "-DMRB_USE_FLOAT=1 -DMRB_INT64=1 -DMRB_WORD_BOXING=1" + LDFLAGS: '' + script: env; ./minirake --verbose all test +Test clang-3.9 64bit_float_int64_utf8: + stage: test + image: registry.gitlab.com/dabroz/mruby:clang39_0.7 + variables: + CC: clang-3.9 + CXX: clang++-3.9 + LD: clang-3.9 + CFLAGS: "-DMRB_USE_FLOAT=1 -DMRB_INT64=1 -DMRB_WORD_BOXING=1 -DMRB_UTF8_STRING=1" + LDFLAGS: '' + script: env; ./minirake --verbose all test diff --git a/web/server/h2o/libh2o/deps/mruby/.travis.yml b/web/server/h2o/libh2o/deps/mruby/.travis.yml new file mode 100644 index 00000000..8d201515 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/.travis.yml @@ -0,0 +1,18 @@ +language: c + +sudo: false + +matrix: + include: + - os: linux + sudo: 9000 + - os: osx + osx_image: xcode7.1 + +addons: + apt: + packages: + - gperf + +env: MRUBY_CONFIG=travis_config.rb +script: "./minirake all test" diff --git a/web/server/h2o/libh2o/deps/mruby/.yardopts b/web/server/h2o/libh2o/deps/mruby/.yardopts new file mode 100644 index 00000000..27f6d59a --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/.yardopts @@ -0,0 +1,17 @@ +--markup markdown +--plugin mruby +--plugin coderay +--output-dir doc/api + +src/**/*.c +mrblib/**/*.rb +include/**/*.h + +mrbgems/*/src/**/*.c +mrbgems/*/mrblib/**/*.rb +mrbgems/*/include/**/*.h +- +AUTHORS +MITL +CONTRIBUTING.md +doc/guides/*.md diff --git a/web/server/h2o/libh2o/deps/mruby/AUTHORS b/web/server/h2o/libh2o/deps/mruby/AUTHORS new file mode 100644 index 00000000..a918ecda --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/AUTHORS @@ -0,0 +1,39 @@ +Original Authors "mruby developers" are: + Yukihiro Matsumoto + SCSK KYUSHU CORPORATION + Kyushu Institute of Technology + Network Applied Communication Laboratory, Inc. + Daniel Bovensiepen + Jon Maken + Bjorn De Meyer + Yuichiro MASUI + Masamitsu MURASE + Masaki Muranaka + Internet Initiative Japan Inc. + Tadashi FUKUZAWA + MATSUMOTO Ryosuke + Yasuhiro Matsumoto + Koji Yoshioka + Jun Hiroe + Narihiro Nakamura + Yuichi Nishiwaki + Tatsuhiko Kubo + Takeshi Watanabe + Yuki Kurihara + specified non-profit corporation mruby Forum + Kazuaki Tanaka + Hiromasa Ishii + Hiroshi Mimaki + Satoshi Odawara + Mitsubishi Electric Micro-Computer Application Software Co.,Ltd. + Ralph Desir(Mav7) + Hiroyuki Matsuzaki + Yuhei Okazaki + Manycolors, Inc. + Shota Nakano + Yuichi Osawa + Terence Lee + Zachary Scott + Tomasz DÄ…browski + Christopher Aue + Masahiro Wakame diff --git a/web/server/h2o/libh2o/deps/mruby/CONTRIBUTING.md b/web/server/h2o/libh2o/deps/mruby/CONTRIBUTING.md new file mode 100644 index 00000000..6bababb8 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/CONTRIBUTING.md @@ -0,0 +1,68 @@ +# How to contribute + +mruby is an open-source project which is looking forward to each contribution. + +## Your Pull Request + +To make it easy to review and understand your change please keep the following +things in mind before submitting your pull request: + +* Work on the latest possible state of **mruby/master** +* Create a branch which is dedicated to your change +* Test your changes before creating a pull request (```./minirake test```) +* If possible write a test case which confirms your change +* Don't mix several features or bug-fixes in one pull request +* Create a meaningful commit message +* Explain your change (i.e. with a link to the issue you are fixing) +* Use mrbgem to provide non ISO features (classes, modules and methods) unless + you have a special reason to implement them in the core + +## Coding conventions + +How to style your C and Ruby code which you want to submit. + +### C code + +The core part (parser, bytecode-interpreter, core-lib, etc.) of mruby is +written in the C programming language. Please note the following hints for your +C code: + +#### Comply with C99 (ISO/IEC 9899:1999) + +mruby should be highly portable to other systems and compilers. For this it is +recommended to keep your code as close as possible to the C99 standard +(http://www.open-std.org/jtc1/sc22/WG14/www/docs/n1256.pdf). + +Although we target C99, Visual C++ is also an important target for mruby. For +this reason a declaration of a local variable has to be at the beginning of a +scope block. + +#### Reduce library dependencies to a minimum + +The dependencies to libraries should be kept to an absolute minimum. This +increases the portability but makes it also easier to cut away parts of mruby +on-demand. + +#### Don't use C++ style comments + + /* This is the preferred comment style */ + +Use C++ style comments only for temporary comment e.g. commenting out some code lines. + +#### Insert a break after the method return value: + + int + main(void) + { + ... + } + +### Ruby code + +Parts of the standard library of mruby are written in the Ruby programming +language itself. Please note the following hints for your Ruby code: + +#### Comply with the Ruby standard (ISO/IEC 30170:2012) + +mruby is currently targeting to execute Ruby code which complies to ISO/IEC +30170:2012 (http://www.iso.org/iso/iso_catalogue/catalogue_tc/catalogue_detail.htm?csnumber=59579). diff --git a/web/server/h2o/libh2o/deps/mruby/LEGAL b/web/server/h2o/libh2o/deps/mruby/LEGAL new file mode 100644 index 00000000..84929998 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/LEGAL @@ -0,0 +1,6 @@ +LEGAL NOTICE INFORMATION +------------------------ + +All the files in this distribution are covered under the MIT license +(see the file MITL) except some files mentioned below: + diff --git a/web/server/h2o/libh2o/deps/mruby/MITL b/web/server/h2o/libh2o/deps/mruby/MITL new file mode 100644 index 00000000..d02b8fe1 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/MITL @@ -0,0 +1,20 @@ +Copyright (c) 2017 mruby developers + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the "Software"), +to deal in the Software without restriction, including without limitation +the rights to use, copy, modify, merge, publish, distribute, sublicense, +and/or sell copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. + diff --git a/web/server/h2o/libh2o/deps/mruby/Makefile b/web/server/h2o/libh2o/deps/mruby/Makefile new file mode 100644 index 00000000..4912f17e --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/Makefile @@ -0,0 +1,17 @@ +# mruby is using Rake (http://rake.rubyforge.org) as a build tool. +# We provide a minimalistic version called minirake inside of our +# codebase. + +RAKE = ruby ./minirake + +all : + $(RAKE) +.PHONY : all + +test : all + $(RAKE) test +.PHONY : test + +clean : + $(RAKE) clean +.PHONY : clean diff --git a/web/server/h2o/libh2o/deps/mruby/NEWS b/web/server/h2o/libh2o/deps/mruby/NEWS new file mode 100644 index 00000000..5c252382 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/NEWS @@ -0,0 +1,13 @@ +* NEWS + +This document is a list of user visible feature changes made between +releases except for bug fixes. + +Note that each entry is kept so brief that no reason behind or +reference information is supplied with. For a full list of changes +with all sufficient information, see the ChangeLog file. + + +** Information about first release v1.0.0 + + diff --git a/web/server/h2o/libh2o/deps/mruby/README.md b/web/server/h2o/libh2o/deps/mruby/README.md new file mode 100644 index 00000000..9d0c611b --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/README.md @@ -0,0 +1,92 @@ +[![Build Status][build-status-img]][travis-ci] + +## What is mruby + +mruby is the lightweight implementation of the Ruby language complying to (part +of) the [ISO standard][ISO-standard]. Its syntax is Ruby 1.9 compatible. + +mruby can be linked and embedded within your application. We provide the +interpreter program "mruby" and the interactive mruby shell "mirb" as examples. +You can also compile Ruby programs into compiled byte code using the mruby +compiler "mrbc". All those tools reside in the "bin" directory. "mrbc" is +also able to generate compiled byte code in a C source file, see the "mrbtest" +program under the "test" directory for an example. + +This achievement was sponsored by the Regional Innovation Creation R&D Programs +of the Ministry of Economy, Trade and Industry of Japan. + +## How to get mruby + +The stable version 1.3.0 of mruby can be downloaded via the following URL: [https://github.com/mruby/mruby/archive/1.3.0.zip](https://github.com/mruby/mruby/archive/1.3.0.zip) + +The latest development version of mruby can be downloaded via the following URL: [https://github.com/mruby/mruby/zipball/master](https://github.com/mruby/mruby/zipball/master) + +The trunk of the mruby source tree can be checked out with the +following command: + + $ git clone https://github.com/mruby/mruby.git + +You can also install and compile mruby using [ruby-install](https://github.com/postmodern/ruby-install), [ruby-build](https://github.com/rbenv/ruby-build) or [rvm](https://github.com/rvm/rvm). + +## mruby home-page + +The URL of the mruby home-page is: [http://www.mruby.org](http://www.mruby.org). + +## Mailing list + +We don't have a mailing list, but you can use [GitHub issues](https://github.com/mruby/mruby). + +## How to compile and install (mruby and gems) + +See the [doc/guides/compile.md](doc/guides/compile.md) file. + +## Running Tests + +To run the tests, execute the following from the project's root directory. + + $ make test + +Or + + $ ruby ./minirake test + +## How to customize mruby (mrbgems) + +mruby contains a package manager called *mrbgems*. To create extensions +in C and/or Ruby you should create a *GEM*. For a documentation of how to +use mrbgems consult the file [doc/guides/mrbgems.md](doc/guides/mrbgems.md). For example code of +how to use mrbgems look into the folder *examples/mrbgems/*. + +## License + +mruby is released under the [MIT License](MITL). + +## Note for License + +mruby has chosen a MIT License due to its permissive license allowing +developers to target various environments such as embedded systems. +However, the license requires the display of the copyright notice and license +information in manuals for instance. Doing so for big projects can be +complicated or troublesome. This is why mruby has decided to display "mruby +developers" as the copyright name to make it simple conventionally. +In the future, mruby might ask you to distribute your new code +(that you will commit,) under the MIT License as a member of +"mruby developers" but contributors will keep their copyright. +(We did not intend for contributors to transfer or waive their copyrights, +Actual copyright holder name (contributors) will be listed in the AUTHORS +file.) + +Please ask us if you want to distribute your code under another license. + +## How to Contribute + +See the [contribution guidelines][contribution-guidelines], and then send a pull +request to . We consider you have granted +non-exclusive right to your contributed code under MIT license. If you want to +be named as one of mruby developers, please include an update to the AUTHORS +file in your pull request. + +[ISO-standard]: http://www.iso.org/iso/iso_catalogue/catalogue_tc/catalogue_detail.htm?csnumber=59579 +[build-status-img]: https://travis-ci.org/mruby/mruby.svg?branch=master +[contribution-guidelines]: CONTRIBUTING.md +[travis-ci]: https://travis-ci.org/mruby/mruby diff --git a/web/server/h2o/libh2o/deps/mruby/Rakefile b/web/server/h2o/libh2o/deps/mruby/Rakefile new file mode 100644 index 00000000..2f6fa056 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/Rakefile @@ -0,0 +1,152 @@ +# encoding: utf-8 +# Build description. +# basic build file for mruby +MRUBY_ROOT = File.dirname(File.expand_path(__FILE__)) +MRUBY_BUILD_HOST_IS_CYGWIN = RUBY_PLATFORM.include?('cygwin') +MRUBY_BUILD_HOST_IS_OPENBSD = RUBY_PLATFORM.include?('openbsd') + +$LOAD_PATH << File.join(MRUBY_ROOT, "lib") + +# load build systems +require "mruby-core-ext" +require "mruby/build" +require "mruby/gem" + +# load configuration file +MRUBY_CONFIG = (ENV['MRUBY_CONFIG'] && ENV['MRUBY_CONFIG'] != '') ? ENV['MRUBY_CONFIG'] : "#{MRUBY_ROOT}/build_config.rb" +load MRUBY_CONFIG + +# load basic rules +MRuby.each_target do |build| + build.define_rules +end + +# load custom rules +load "#{MRUBY_ROOT}/src/mruby_core.rake" +load "#{MRUBY_ROOT}/mrblib/mrblib.rake" + +load "#{MRUBY_ROOT}/tasks/mrbgems.rake" +load "#{MRUBY_ROOT}/tasks/libmruby.rake" + +load "#{MRUBY_ROOT}/tasks/benchmark.rake" + +load "#{MRUBY_ROOT}/tasks/gitlab.rake" + +############################## +# generic build targets, rules +task :default => :all + +bin_path = ENV['INSTALL_DIR'] || "#{MRUBY_ROOT}/bin" +FileUtils.mkdir_p bin_path, { :verbose => $verbose } + +depfiles = MRuby.targets['host'].bins.map do |bin| + install_path = MRuby.targets['host'].exefile("#{bin_path}/#{bin}") + source_path = MRuby.targets['host'].exefile("#{MRuby.targets['host'].build_dir}/bin/#{bin}") + + file install_path => source_path do |t| + FileUtils.rm_f t.name, { :verbose => $verbose } + FileUtils.cp t.prerequisites.first, t.name, { :verbose => $verbose } + end + + install_path +end + +MRuby.each_target do |target| + gems.map do |gem| + current_dir = gem.dir.relative_path_from(Dir.pwd) + relative_from_root = gem.dir.relative_path_from(MRUBY_ROOT) + current_build_dir = File.expand_path "#{build_dir}/#{relative_from_root}" + + if current_build_dir !~ /^#{build_dir}/ + current_build_dir = "#{build_dir}/mrbgems/#{gem.name}" + end + + gem.bins.each do |bin| + exec = exefile("#{build_dir}/bin/#{bin}") + objs = Dir.glob("#{current_dir}/tools/#{bin}/*.{c,cpp,cxx,cc}").map { |f| objfile(f.pathmap("#{current_build_dir}/tools/#{bin}/%n")) } + + file exec => objs + [libfile("#{build_dir}/lib/libmruby")] do |t| + gem_flags = gems.map { |g| g.linker.flags } + gem_flags_before_libraries = gems.map { |g| g.linker.flags_before_libraries } + gem_flags_after_libraries = gems.map { |g| g.linker.flags_after_libraries } + gem_libraries = gems.map { |g| g.linker.libraries } + gem_library_paths = gems.map { |g| g.linker.library_paths } + linker.run t.name, t.prerequisites, gem_libraries, gem_library_paths, gem_flags, gem_flags_before_libraries, gem_flags_after_libraries + end + + if target == MRuby.targets['host'] + install_path = MRuby.targets['host'].exefile("#{bin_path}/#{bin}") + + file install_path => exec do |t| + FileUtils.rm_f t.name, { :verbose => $verbose } + FileUtils.cp t.prerequisites.first, t.name, { :verbose => $verbose } + end + depfiles += [ install_path ] + elsif target == MRuby.targets['host-debug'] + unless MRuby.targets['host'].gems.map {|g| g.bins}.include?([bin]) + install_path = MRuby.targets['host-debug'].exefile("#{bin_path}/#{bin}") + + file install_path => exec do |t| + FileUtils.rm_f t.name, { :verbose => $verbose } + FileUtils.cp t.prerequisites.first, t.name, { :verbose => $verbose } + end + depfiles += [ install_path ] + end + else + depfiles += [ exec ] + end + end + end +end + +depfiles += MRuby.targets.map { |n, t| + [t.libfile("#{t.build_dir}/lib/libmruby")] +}.flatten + +depfiles += MRuby.targets.reject { |n, t| n == 'host' }.map { |n, t| + t.bins.map { |bin| t.exefile("#{t.build_dir}/bin/#{bin}") } +}.flatten + +desc "build all targets, install (locally) in-repo" +task :all => depfiles do + puts + puts "Build summary:" + puts + MRuby.each_target do + print_build_summary + end +end + +desc "run all mruby tests" +task :test => ["all"] do + MRuby.each_target do + run_test if test_enabled? + end +end + +desc "clean all built and in-repo installed artifacts" +task :clean do + MRuby.each_target do |t| + FileUtils.rm_rf t.build_dir, { :verbose => $verbose } + end + FileUtils.rm_f depfiles, { :verbose => $verbose } + puts "Cleaned up target build folder" +end + +desc "clean everything!" +task :deep_clean => ["clean"] do + MRuby.each_target do |t| + FileUtils.rm_rf t.gem_clone_dir, { :verbose => $verbose } + end + puts "Cleaned up mrbgems build folder" +end + +desc 'generate document' +task :doc do + begin + sh "mrbdoc" + rescue + puts "ERROR: To generate documents, you should install yard-mruby gem." + puts " $ gem install yard-mruby" + end +end diff --git a/web/server/h2o/libh2o/deps/mruby/TODO b/web/server/h2o/libh2o/deps/mruby/TODO new file mode 100644 index 00000000..3e195f99 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/TODO @@ -0,0 +1,10 @@ +Things to do (Things that are not done yet) + +* special variables ($1,$2..) +* super in aliased methods +* multi-assignment decomposing +* keyword arguments in def statement + +Things to improve (Done but things to fix) + +* Make additions as they are noticed. diff --git a/web/server/h2o/libh2o/deps/mruby/appveyor.yml b/web/server/h2o/libh2o/deps/mruby/appveyor.yml new file mode 100644 index 00000000..c62b1357 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/appveyor.yml @@ -0,0 +1,27 @@ +version: "{build}" + +os: Visual Studio 2015 + +clone_depth: 50 + + +environment: + matrix: + # Visual Studio 2015 64bit + - visualcpp: C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat + machine: amd64 + + # Visual Studio 2013 64bit + - visualcpp: C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\vcvarsall.bat + machine: amd64 + + +init: + - call "%visualcpp%" %machine% + # For using bison.exe + - set PATH=%PATH%;C:\cygwin\bin; + + +build_script: + - set MRUBY_CONFIG=appveyor_config.rb + - ruby .\minirake test diff --git a/web/server/h2o/libh2o/deps/mruby/appveyor_config.rb b/web/server/h2o/libh2o/deps/mruby/appveyor_config.rb new file mode 100644 index 00000000..57e10330 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/appveyor_config.rb @@ -0,0 +1,50 @@ +MRuby::Build.new('debug') do |conf| + toolchain :visualcpp + enable_debug + + # include all core GEMs + conf.gembox 'full-core' + conf.compilers.each do |c| + c.defines += %w(MRB_GC_STRESS MRB_GC_FIXED_ARENA) + end + + build_mrbc_exec +end + +MRuby::Build.new('full-debug') do |conf| + toolchain :visualcpp + enable_debug + + # include all core GEMs + conf.gembox 'full-core' + conf.cc.defines = %w(MRB_ENABLE_DEBUG_HOOK) + + conf.enable_test +end + +MRuby::Build.new do |conf| + toolchain :visualcpp + + # include all core GEMs + conf.gembox 'full-core' + conf.compilers.each do |c| + c.defines += %w(MRB_GC_FIXED_ARENA) + end + conf.enable_bintest + conf.enable_test +end + +MRuby::Build.new('cxx_abi') do |conf| + toolchain :visualcpp + + conf.gembox 'full-core' + conf.compilers.each do |c| + c.defines += %w(MRB_GC_FIXED_ARENA) + end + conf.enable_bintest + conf.enable_test + + enable_cxx_abi + + build_mrbc_exec +end diff --git a/web/server/h2o/libh2o/deps/mruby/benchmark/bm_ao_render.rb b/web/server/h2o/libh2o/deps/mruby/benchmark/bm_ao_render.rb new file mode 100644 index 00000000..8212c3a1 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/benchmark/bm_ao_render.rb @@ -0,0 +1,314 @@ +# AO render benchmark +# Original program (C) Syoyo Fujita in Javascript (and other languages) +# https://code.google.com/p/aobench/ +# Ruby(yarv2llvm) version by Hideki Miura +# mruby version by Hideki Miura +# + +IMAGE_WIDTH = 64 +IMAGE_HEIGHT = 64 +NSUBSAMPLES = 2 +NAO_SAMPLES = 8 + +module Rand + # Use xorshift + @@x = 123456789 + @@y = 362436069 + @@z = 521288629 + @@w = 88675123 + BNUM = 1 << 29 + BNUMF = BNUM.to_f + def self.rand + x = @@x + t = x ^ ((x & 0xfffff) << 11) + w = @@w + @@x, @@y, @@z = @@y, @@z, w + w = @@w = (w ^ (w >> 19) ^ (t ^ (t >> 8))) + (w % BNUM) / BNUMF + end +end + +class Vec + def initialize(x, y, z) + @x = x + @y = y + @z = z + end + + def x=(v); @x = v; end + def y=(v); @y = v; end + def z=(v); @z = v; end + def x; @x; end + def y; @y; end + def z; @z; end + + def vadd(b) + Vec.new(@x + b.x, @y + b.y, @z + b.z) + end + + def vsub(b) + Vec.new(@x - b.x, @y - b.y, @z - b.z) + end + + def vcross(b) + Vec.new(@y * b.z - @z * b.y, + @z * b.x - @x * b.z, + @x * b.y - @y * b.x) + end + + def vdot(b) + r = @x * b.x + @y * b.y + @z * b.z + r + end + + def vlength + Math.sqrt(@x * @x + @y * @y + @z * @z) + end + + def vnormalize + len = vlength + v = Vec.new(@x, @y, @z) + if len > 1.0e-17 then + v.x = v.x / len + v.y = v.y / len + v.z = v.z / len + end + v + end +end + + +class Sphere + def initialize(center, radius) + @center = center + @radius = radius + end + + def center; @center; end + def radius; @radius; end + + def intersect(ray, isect) + rs = ray.org.vsub(@center) + b = rs.vdot(ray.dir) + c = rs.vdot(rs) - (@radius * @radius) + d = b * b - c + if d > 0.0 then + t = - b - Math.sqrt(d) + + if t > 0.0 and t < isect.t then + isect.t = t + isect.hit = true + isect.pl = Vec.new(ray.org.x + ray.dir.x * t, + ray.org.y + ray.dir.y * t, + ray.org.z + ray.dir.z * t) + n = isect.pl.vsub(@center) + isect.n = n.vnormalize + end + end + end +end + +class Plane + def initialize(p, n) + @p = p + @n = n + end + + def intersect(ray, isect) + d = -@p.vdot(@n) + v = ray.dir.vdot(@n) + v0 = v + if v < 0.0 then + v0 = -v + end + if v0 < 1.0e-17 then + return + end + + t = -(ray.org.vdot(@n) + d) / v + + if t > 0.0 and t < isect.t then + isect.hit = true + isect.t = t + isect.n = @n + isect.pl = Vec.new(ray.org.x + t * ray.dir.x, + ray.org.y + t * ray.dir.y, + ray.org.z + t * ray.dir.z) + end + end +end + +class Ray + def initialize(org, dir) + @org = org + @dir = dir + end + + def org; @org; end + def org=(v); @org = v; end + def dir; @dir; end + def dir=(v); @dir = v; end +end + +class Isect + def initialize + @t = 10000000.0 + @hit = false + @pl = Vec.new(0.0, 0.0, 0.0) + @n = Vec.new(0.0, 0.0, 0.0) + end + + def t; @t; end + def t=(v); @t = v; end + def hit; @hit; end + def hit=(v); @hit = v; end + def pl; @pl; end + def pl=(v); @pl = v; end + def n; @n; end + def n=(v); @n = v; end +end + +def clamp(f) + i = f * 255.5 + if i > 255.0 then + i = 255.0 + end + if i < 0.0 then + i = 0.0 + end + i.to_i +end + +def otherBasis(basis, n) + basis[2] = Vec.new(n.x, n.y, n.z) + basis[1] = Vec.new(0.0, 0.0, 0.0) + + if n.x < 0.6 and n.x > -0.6 then + basis[1].x = 1.0 + elsif n.y < 0.6 and n.y > -0.6 then + basis[1].y = 1.0 + elsif n.z < 0.6 and n.z > -0.6 then + basis[1].z = 1.0 + else + basis[1].x = 1.0 + end + + basis[0] = basis[1].vcross(basis[2]) + basis[0] = basis[0].vnormalize + + basis[1] = basis[2].vcross(basis[0]) + basis[1] = basis[1].vnormalize +end + +class Scene + def initialize + @spheres = Array.new + @spheres[0] = Sphere.new(Vec.new(-2.0, 0.0, -3.5), 0.5) + @spheres[1] = Sphere.new(Vec.new(-0.5, 0.0, -3.0), 0.5) + @spheres[2] = Sphere.new(Vec.new(1.0, 0.0, -2.2), 0.5) + @plane = Plane.new(Vec.new(0.0, -0.5, 0.0), Vec.new(0.0, 1.0, 0.0)) + end + + def ambient_occlusion(isect) + basis = Array.new(3) + otherBasis(basis, isect.n) + + ntheta = NAO_SAMPLES + nphi = NAO_SAMPLES + eps = 0.0001 + occlusion = 0.0 + + p0 = Vec.new(isect.pl.x + eps * isect.n.x, + isect.pl.y + eps * isect.n.y, + isect.pl.z + eps * isect.n.z) + nphi.times do |j| + ntheta.times do |i| + r = Rand::rand + phi = 2.0 * 3.14159265 * Rand::rand + x = Math.cos(phi) * Math.sqrt(1.0 - r) + y = Math.sin(phi) * Math.sqrt(1.0 - r) + z = Math.sqrt(r) + + rx = x * basis[0].x + y * basis[1].x + z * basis[2].x + ry = x * basis[0].y + y * basis[1].y + z * basis[2].y + rz = x * basis[0].z + y * basis[1].z + z * basis[2].z + + raydir = Vec.new(rx, ry, rz) + ray = Ray.new(p0, raydir) + + occisect = Isect.new + @spheres[0].intersect(ray, occisect) + @spheres[1].intersect(ray, occisect) + @spheres[2].intersect(ray, occisect) + @plane.intersect(ray, occisect) + if occisect.hit then + occlusion = occlusion + 1.0 + else + 0.0 + end + end + end + + occlusion = (ntheta.to_f * nphi.to_f - occlusion) / (ntheta.to_f * nphi.to_f) + Vec.new(occlusion, occlusion, occlusion) + end + + def render(w, h, nsubsamples) + cnt = 0 + nsf = nsubsamples.to_f + h.times do |y| + w.times do |x| + rad = Vec.new(0.0, 0.0, 0.0) + + # Subsmpling + nsubsamples.times do |v| + nsubsamples.times do |u| + cnt = cnt + 1 + wf = w.to_f + hf = h.to_f + xf = x.to_f + yf = y.to_f + uf = u.to_f + vf = v.to_f + + px = (xf + (uf / nsf) - (wf / 2.0)) / (wf / 2.0) + py = -(yf + (vf / nsf) - (hf / 2.0)) / (hf / 2.0) + + eye = Vec.new(px, py, -1.0).vnormalize + + ray = Ray.new(Vec.new(0.0, 0.0, 0.0), eye) + + isect = Isect.new + @spheres[0].intersect(ray, isect) + @spheres[1].intersect(ray, isect) + @spheres[2].intersect(ray, isect) + @plane.intersect(ray, isect) + if isect.hit then + col = ambient_occlusion(isect) + rad.x = rad.x + col.x + rad.y = rad.y + col.y + rad.z = rad.z + col.z + else + 0.0 + end + end + end + + r = rad.x / (nsf * nsf) + g = rad.y / (nsf * nsf) + b = rad.z / (nsf * nsf) + printf("%c", clamp(r)) + printf("%c", clamp(g)) + printf("%c", clamp(b)) + end + end + end +end + +# File.open("ao.ppm", "w") do |fp| + printf("P6\n") + printf("%d %d\n", IMAGE_WIDTH, IMAGE_HEIGHT) + printf("255\n", IMAGE_WIDTH, IMAGE_HEIGHT) + Scene.new.render(IMAGE_WIDTH, IMAGE_HEIGHT, NSUBSAMPLES) +# Scene.new.render(256, 256, 2) +# end diff --git a/web/server/h2o/libh2o/deps/mruby/benchmark/bm_app_lc_fizzbuzz.rb b/web/server/h2o/libh2o/deps/mruby/benchmark/bm_app_lc_fizzbuzz.rb new file mode 100644 index 00000000..26283cc3 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/benchmark/bm_app_lc_fizzbuzz.rb @@ -0,0 +1,52 @@ +# +# FizzBuzz program using only lambda calculus +# +# This program is quoted from +# "Understanding Computation" by Tom Stuart +# http://computationbook.com/ +# +# You can understand why this program works fine by reading this book. +# + +solution = -> k { -> f { -> f { -> x { f[-> y { x[x][y] }] }[-> x { f[-> y { x[x][y] }] }] }[-> f { -> l { -> x { -> g { -> b { b }[-> p { p[-> x { -> y { x } }] }[l]][x][-> y { g[f[-> l { -> p { p[-> x { -> y { y } }] }[-> p { p[-> x { -> y { y } }] }[l]] }[l]][x][g]][-> l { -> p { p[-> x { -> y { x } }] }[-> p { p[-> x { -> y { y } }] }[l]] }[l]][y] }] } } } }][k][-> x { -> y { -> f { f[x][y] } } }[-> x { -> y { x } }][-> x { -> y { x } }]][-> l { -> x { -> l { -> x { -> x { -> y { -> f { f[x][y] } } }[-> x { -> y { y } }][-> x { -> y { -> f { f[x][y] } } }[x][l]] } }[l][f[x]] } }] } }[-> f { -> x { f[-> y { x[x][y] }] }[-> x { f[-> y { x[x][y] }] }] }[-> f { -> m { -> n { -> b { b }[-> m { -> n { -> n { n[-> x { -> x { -> y { y } } }][-> x { -> y { x } }] }[-> m { -> n { n[-> n { -> p { p[-> x { -> y { x } }] }[n[-> p { -> x { -> y { -> f { f[x][y] } } }[-> p { p[-> x { -> y { y } }] }[p]][-> n { -> p { -> x { p[n[p][x]] } } }[-> p { p[-> x { -> y { y } }] }[p]]] }][-> x { -> y { -> f { f[x][y] } } }[-> p { -> x { x } }][-> p { -> x { x } }]]] }][m] } }[m][n]] } }[m][n]][-> x { -> l { -> x { -> x { -> y { -> f { f[x][y] } } }[-> x { -> y { y } }][-> x { -> y { -> f { f[x][y] } } }[x][l]] } }[f[-> n { -> p { -> x { p[n[p][x]] } } }[m]][n]][m][x] }][-> x { -> y { -> f { f[x][y] } } }[-> x { -> y { x } }][-> x { -> y { x } }]] } } }][-> p { -> x { p[x] } }][-> p { -> x { p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[x]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]] } }]][-> n { -> b { b }[-> n { n[-> x { -> x { -> y { y } } }][-> x { -> y { x } }] }[-> f { -> x { f[-> y { x[x][y] }] }[-> x { f[-> y { x[x][y] }] }] }[-> f { -> m { -> n { -> b { b }[-> m { -> n { -> n { n[-> x { -> x { -> y { y } } }][-> x { -> y { x } }] }[-> m { -> n { n[-> n { -> p { p[-> x { -> y { x } }] }[n[-> p { -> x { -> y { -> f { f[x][y] } } }[-> p { p[-> x { -> y { y } }] }[p]][-> n { -> p { -> x { p[n[p][x]] } } }[-> p { p[-> x { -> y { y } }] }[p]]] }][-> x { -> y { -> f { f[x][y] } } }[-> p { -> x { x } }][-> p { -> x { x } }]]] }][m] } }[m][n]] } }[n][m]][-> x { f[-> m { -> n { n[-> n { -> p { p[-> x { -> y { x } }] }[n[-> p { -> x { -> y { -> f { f[x][y] } } }[-> p { p[-> x { -> y { y } }] }[p]][-> n { -> p { -> x { p[n[p][x]] } } }[-> p { p[-> x { -> y { y } }] }[p]]] }][-> x { -> y { -> f { f[x][y] } } }[-> p { -> x { x } }][-> p { -> x { x } }]]] }][m] } }[m][n]][n][x] }][m] } } }][n][-> p { -> x { p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[x]]]]]]]]]]]]]]] } }]]][-> l { -> x { -> x { -> y { -> f { f[x][y] } } }[-> x { -> y { y } }][-> x { -> y { -> f { f[x][y] } } }[x][l]] } }[-> l { -> x { -> x { -> y { -> f { f[x][y] } } }[-> x { -> y { y } }][-> x { -> y { -> f { f[x][y] } } }[x][l]] } }[-> l { -> x { -> x { -> y { -> f { f[x][y] } } }[-> x { -> y { y } }][-> x { -> y { -> f { f[x][y] } } }[x][l]] } }[-> l { -> x { -> x { -> y { -> f { f[x][y] } } }[-> x { -> y { y } }][-> x { -> y { -> f { f[x][y] } } }[x][l]] } }[-> l { -> x { -> x { -> y { -> f { f[x][y] } } }[-> x { -> y { y } }][-> x { -> y { -> f { f[x][y] } } }[x][l]] } }[-> l { -> x { -> x { -> y { -> f { f[x][y] } } }[-> x { -> y { y } }][-> x { -> y { -> f { f[x][y] } } }[x][l]] } }[-> l { -> x { -> x { -> y { -> f { f[x][y] } } }[-> x { -> y { y } }][-> x { -> y { -> f { f[x][y] } } }[x][l]] } }[-> l { -> x { -> x { -> y { -> f { f[x][y] } } }[-> x { -> y { y } }][-> x { -> y { -> f { f[x][y] } } }[x][l]] } }[-> x { -> y { -> f { f[x][y] } } }[-> x { -> y { x } }][-> x { -> y { x } }]][-> n { -> p { -> x { p[n[p][x]] } } }[-> n { -> p { -> x { p[n[p][x]] } } }[-> n { -> p { -> x { p[n[p][x]] } } }[-> n { -> p { -> x { p[n[p][x]] } } }[-> m { -> n { n[-> m { -> n { n[-> n { -> p { -> x { p[n[p][x]] } } }][m] } }[m]][-> p { -> x { x } }] } }[-> p { -> x { p[p[x]] } }][-> p { -> x { p[p[p[p[p[x]]]]] } }]]]]]]][-> n { -> p { -> x { p[n[p][x]] } } }[-> n { -> p { -> x { p[n[p][x]] } } }[-> n { -> p { -> x { p[n[p][x]] } } }[-> n { -> p { -> x { p[n[p][x]] } } }[-> m { -> n { n[-> m { -> n { n[-> n { -> p { -> x { p[n[p][x]] } } }][m] } }[m]][-> p { -> x { x } }] } }[-> p { -> x { p[p[x]] } }][-> p { -> x { p[p[p[p[p[x]]]]] } }]]]]]]][-> n { -> p { -> x { p[n[p][x]] } } }[-> n { -> p { -> x { p[n[p][x]] } } }[-> n { -> p { -> x { p[n[p][x]] } } }[-> m { -> n { n[-> m { -> n { n[-> n { -> p { -> x { p[n[p][x]] } } }][m] } }[m]][-> p { -> x { x } }] } }[-> p { -> x { p[p[x]] } }][-> p { -> x { p[p[p[p[p[x]]]]] } }]]]]]][-> m { -> n { n[-> m { -> n { n[-> n { -> p { -> x { p[n[p][x]] } } }][m] } }[m]][-> p { -> x { x } }] } }[-> p { -> x { p[p[x]] } }][-> p { -> x { p[p[p[p[p[x]]]]] } }]]][-> n { -> p { -> x { p[n[p][x]] } } }[-> n { -> p { -> x { p[n[p][x]] } } }[-> n { -> p { -> x { p[n[p][x]] } } }[-> n { -> p { -> x { p[n[p][x]] } } }[-> m { -> n { n[-> m { -> n { n[-> n { -> p { -> x { p[n[p][x]] } } }][m] } }[m]][-> p { -> x { x } }] } }[-> p { -> x { p[p[x]] } }][-> p { -> x { p[p[p[p[p[x]]]]] } }]]]]]]][-> n { -> p { -> x { p[n[p][x]] } } }[-> n { -> p { -> x { p[n[p][x]] } } }[-> n { -> p { -> x { p[n[p][x]] } } }[-> n { -> p { -> x { p[n[p][x]] } } }[-> m { -> n { n[-> m { -> n { n[-> n { -> p { -> x { p[n[p][x]] } } }][m] } }[m]][-> p { -> x { x } }] } }[-> p { -> x { p[p[x]] } }][-> p { -> x { p[p[p[p[p[x]]]]] } }]]]]]]][-> n { -> p { -> x { p[n[p][x]] } } }[-> n { -> p { -> x { p[n[p][x]] } } }[-> m { -> n { n[-> m { -> n { n[-> n { -> p { -> x { p[n[p][x]] } } }][m] } }[m]][-> p { -> x { x } }] } }[-> p { -> x { p[p[x]] } }][-> p { -> x { p[p[p[p[p[x]]]]] } }]]]]][-> n { -> p { -> x { p[n[p][x]] } } }[-> m { -> n { n[-> m { -> n { n[-> n { -> p { -> x { p[n[p][x]] } } }][m] } }[m]][-> p { -> x { x } }] } }[-> p { -> x { p[p[x]] } }][-> p { -> x { p[p[p[p[p[x]]]]] } }]]]][-> b { b }[-> n { n[-> x { -> x { -> y { y } } }][-> x { -> y { x } }] }[-> f { -> x { f[-> y { x[x][y] }] }[-> x { f[-> y { x[x][y] }] }] }[-> f { -> m { -> n { -> b { b }[-> m { -> n { -> n { n[-> x { -> x { -> y { y } } }][-> x { -> y { x } }] }[-> m { -> n { n[-> n { -> p { p[-> x { -> y { x } }] }[n[-> p { -> x { -> y { -> f { f[x][y] } } }[-> p { p[-> x { -> y { y } }] }[p]][-> n { -> p { -> x { p[n[p][x]] } } }[-> p { p[-> x { -> y { y } }] }[p]]] }][-> x { -> y { -> f { f[x][y] } } }[-> p { -> x { x } }][-> p { -> x { x } }]]] }][m] } }[m][n]] } }[n][m]][-> x { f[-> m { -> n { n[-> n { -> p { p[-> x { -> y { x } }] }[n[-> p { -> x { -> y { -> f { f[x][y] } } }[-> p { p[-> x { -> y { y } }] }[p]][-> n { -> p { -> x { p[n[p][x]] } } }[-> p { p[-> x { -> y { y } }] }[p]]] }][-> x { -> y { -> f { f[x][y] } } }[-> p { -> x { x } }][-> p { -> x { x } }]]] }][m] } }[m][n]][n][x] }][m] } } }][n][-> p { -> x { p[p[p[x]]] } }]]][-> l { -> x { -> x { -> y { -> f { f[x][y] } } }[-> x { -> y { y } }][-> x { -> y { -> f { f[x][y] } } }[x][l]] } }[-> l { -> x { -> x { -> y { -> f { f[x][y] } } }[-> x { -> y { y } }][-> x { -> y { -> f { f[x][y] } } }[x][l]] } }[-> l { -> x { -> x { -> y { -> f { f[x][y] } } }[-> x { -> y { y } }][-> x { -> y { -> f { f[x][y] } } }[x][l]] } }[-> l { -> x { -> x { -> y { -> f { f[x][y] } } }[-> x { -> y { y } }][-> x { -> y { -> f { f[x][y] } } }[x][l]] } }[-> x { -> y { -> f { f[x][y] } } }[-> x { -> y { x } }][-> x { -> y { x } }]][-> n { -> p { -> x { p[n[p][x]] } } }[-> n { -> p { -> x { p[n[p][x]] } } }[-> n { -> p { -> x { p[n[p][x]] } } }[-> n { -> p { -> x { p[n[p][x]] } } }[-> m { -> n { n[-> m { -> n { n[-> n { -> p { -> x { p[n[p][x]] } } }][m] } }[m]][-> p { -> x { x } }] } }[-> p { -> x { p[p[x]] } }][-> p { -> x { p[p[p[p[p[x]]]]] } }]]]]]]][-> n { -> p { -> x { p[n[p][x]] } } }[-> n { -> p { -> x { p[n[p][x]] } } }[-> n { -> p { -> x { p[n[p][x]] } } }[-> n { -> p { -> x { p[n[p][x]] } } }[-> m { -> n { n[-> m { -> n { n[-> n { -> p { -> x { p[n[p][x]] } } }][m] } }[m]][-> p { -> x { x } }] } }[-> p { -> x { p[p[x]] } }][-> p { -> x { p[p[p[p[p[x]]]]] } }]]]]]]][-> n { -> p { -> x { p[n[p][x]] } } }[-> n { -> p { -> x { p[n[p][x]] } } }[-> m { -> n { n[-> m { -> n { n[-> n { -> p { -> x { p[n[p][x]] } } }][m] } }[m]][-> p { -> x { x } }] } }[-> p { -> x { p[p[x]] } }][-> p { -> x { p[p[p[p[p[x]]]]] } }]]]]][-> n { -> p { -> x { p[n[p][x]] } } }[-> m { -> n { n[-> m { -> n { n[-> n { -> p { -> x { p[n[p][x]] } } }][m] } }[m]][-> p { -> x { x } }] } }[-> p { -> x { p[p[x]] } }][-> p { -> x { p[p[p[p[p[x]]]]] } }]]]][-> b { b }[-> n { n[-> x { -> x { -> y { y } } }][-> x { -> y { x } }] }[-> f { -> x { f[-> y { x[x][y] }] }[-> x { f[-> y { x[x][y] }] }] }[-> f { -> m { -> n { -> b { b }[-> m { -> n { -> n { n[-> x { -> x { -> y { y } } }][-> x { -> y { x } }] }[-> m { -> n { n[-> n { -> p { p[-> x { -> y { x } }] }[n[-> p { -> x { -> y { -> f { f[x][y] } } }[-> p { p[-> x { -> y { y } }] }[p]][-> n { -> p { -> x { p[n[p][x]] } } }[-> p { p[-> x { -> y { y } }] }[p]]] }][-> x { -> y { -> f { f[x][y] } } }[-> p { -> x { x } }][-> p { -> x { x } }]]] }][m] } }[m][n]] } }[n][m]][-> x { f[-> m { -> n { n[-> n { -> p { p[-> x { -> y { x } }] }[n[-> p { -> x { -> y { -> f { f[x][y] } } }[-> p { p[-> x { -> y { y } }] }[p]][-> n { -> p { -> x { p[n[p][x]] } } }[-> p { p[-> x { -> y { y } }] }[p]]] }][-> x { -> y { -> f { f[x][y] } } }[-> p { -> x { x } }][-> p { -> x { x } }]]] }][m] } }[m][n]][n][x] }][m] } } }][n][-> p { -> x { p[p[p[p[p[x]]]]] } }]]][-> l { -> x { -> x { -> y { -> f { f[x][y] } } }[-> x { -> y { y } }][-> x { -> y { -> f { f[x][y] } } }[x][l]] } }[-> l { -> x { -> x { -> y { -> f { f[x][y] } } }[-> x { -> y { y } }][-> x { -> y { -> f { f[x][y] } } }[x][l]] } }[-> l { -> x { -> x { -> y { -> f { f[x][y] } } }[-> x { -> y { y } }][-> x { -> y { -> f { f[x][y] } } }[x][l]] } }[-> l { -> x { -> x { -> y { -> f { f[x][y] } } }[-> x { -> y { y } }][-> x { -> y { -> f { f[x][y] } } }[x][l]] } }[-> x { -> y { -> f { f[x][y] } } }[-> x { -> y { x } }][-> x { -> y { x } }]][-> n { -> p { -> x { p[n[p][x]] } } }[-> n { -> p { -> x { p[n[p][x]] } } }[-> n { -> p { -> x { p[n[p][x]] } } }[-> n { -> p { -> x { p[n[p][x]] } } }[-> m { -> n { n[-> m { -> n { n[-> n { -> p { -> x { p[n[p][x]] } } }][m] } }[m]][-> p { -> x { x } }] } }[-> p { -> x { p[p[x]] } }][-> p { -> x { p[p[p[p[p[x]]]]] } }]]]]]]][-> n { -> p { -> x { p[n[p][x]] } } }[-> n { -> p { -> x { p[n[p][x]] } } }[-> n { -> p { -> x { p[n[p][x]] } } }[-> n { -> p { -> x { p[n[p][x]] } } }[-> m { -> n { n[-> m { -> n { n[-> n { -> p { -> x { p[n[p][x]] } } }][m] } }[m]][-> p { -> x { x } }] } }[-> p { -> x { p[p[x]] } }][-> p { -> x { p[p[p[p[p[x]]]]] } }]]]]]]][-> n { -> p { -> x { p[n[p][x]] } } }[-> n { -> p { -> x { p[n[p][x]] } } }[-> n { -> p { -> x { p[n[p][x]] } } }[-> m { -> n { n[-> m { -> n { n[-> n { -> p { -> x { p[n[p][x]] } } }][m] } }[m]][-> p { -> x { x } }] } }[-> p { -> x { p[p[x]] } }][-> p { -> x { p[p[p[p[p[x]]]]] } }]]]]]][-> m { -> n { n[-> m { -> n { n[-> n { -> p { -> x { p[n[p][x]] } } }][m] } }[m]][-> p { -> x { x } }] } }[-> p { -> x { p[p[x]] } }][-> p { -> x { p[p[p[p[p[x]]]]] } }]]][-> f { -> x { f[-> y { x[x][y] }] }[-> x { f[-> y { x[x][y] }] }] }[-> f { -> n { -> l { -> x { -> f { -> x { f[-> y { x[x][y] }] }[-> x { f[-> y { x[x][y] }] }] }[-> f { -> l { -> x { -> g { -> b { b }[-> p { p[-> x { -> y { x } }] }[l]][x][-> y { g[f[-> l { -> p { p[-> x { -> y { y } }] }[-> p { p[-> x { -> y { y } }] }[l]] }[l]][x][g]][-> l { -> p { p[-> x { -> y { x } }] }[-> p { p[-> x { -> y { y } }] }[l]] }[l]][y] }] } } } }][l][-> l { -> x { -> x { -> y { -> f { f[x][y] } } }[-> x { -> y { y } }][-> x { -> y { -> f { f[x][y] } } }[x][l]] } }[-> x { -> y { -> f { f[x][y] } } }[-> x { -> y { x } }][-> x { -> y { x } }]][x]][-> l { -> x { -> x { -> y { -> f { f[x][y] } } }[-> x { -> y { y } }][-> x { -> y { -> f { f[x][y] } } }[x][l]] } }] } }[-> b { b }[-> m { -> n { -> n { n[-> x { -> x { -> y { y } } }][-> x { -> y { x } }] }[-> m { -> n { n[-> n { -> p { p[-> x { -> y { x } }] }[n[-> p { -> x { -> y { -> f { f[x][y] } } }[-> p { p[-> x { -> y { y } }] }[p]][-> n { -> p { -> x { p[n[p][x]] } } }[-> p { p[-> x { -> y { y } }] }[p]]] }][-> x { -> y { -> f { f[x][y] } } }[-> p { -> x { x } }][-> p { -> x { x } }]]] }][m] } }[m][n]] } }[n][-> n { -> p { p[-> x { -> y { x } }] }[n[-> p { -> x { -> y { -> f { f[x][y] } } }[-> p { p[-> x { -> y { y } }] }[p]][-> n { -> p { -> x { p[n[p][x]] } } }[-> p { p[-> x { -> y { y } }] }[p]]] }][-> x { -> y { -> f { f[x][y] } } }[-> p { -> x { x } }][-> p { -> x { x } }]]] }[-> m { -> n { n[-> m { -> n { n[-> n { -> p { -> x { p[n[p][x]] } } }][m] } }[m]][-> p { -> x { x } }] } }[-> p { -> x { p[p[x]] } }][-> p { -> x { p[p[p[p[p[x]]]]] } }]]]][-> x { -> y { -> f { f[x][y] } } }[-> x { -> y { x } }][-> x { -> y { x } }]][-> x { f[-> f { -> x { f[-> y { x[x][y] }] }[-> x { f[-> y { x[x][y] }] }] }[-> f { -> m { -> n { -> b { b }[-> m { -> n { -> n { n[-> x { -> x { -> y { y } } }][-> x { -> y { x } }] }[-> m { -> n { n[-> n { -> p { p[-> x { -> y { x } }] }[n[-> p { -> x { -> y { -> f { f[x][y] } } }[-> p { p[-> x { -> y { y } }] }[p]][-> n { -> p { -> x { p[n[p][x]] } } }[-> p { p[-> x { -> y { y } }] }[p]]] }][-> x { -> y { -> f { f[x][y] } } }[-> p { -> x { x } }][-> p { -> x { x } }]]] }][m] } }[m][n]] } }[n][m]][-> x { -> n { -> p { -> x { p[n[p][x]] } } }[f[-> m { -> n { n[-> n { -> p { p[-> x { -> y { x } }] }[n[-> p { -> x { -> y { -> f { f[x][y] } } }[-> p { p[-> x { -> y { y } }] }[p]][-> n { -> p { -> x { p[n[p][x]] } } }[-> p { p[-> x { -> y { y } }] }[p]]] }][-> x { -> y { -> f { f[x][y] } } }[-> p { -> x { x } }][-> p { -> x { x } }]]] }][m] } }[m][n]][n]][x] }][-> p { -> x { x } }] } } }][n][-> m { -> n { n[-> m { -> n { n[-> n { -> p { -> x { p[n[p][x]] } } }][m] } }[m]][-> p { -> x { x } }] } }[-> p { -> x { p[p[x]] } }][-> p { -> x { p[p[p[p[p[x]]]]] } }]]][x] }]][-> f { -> x { f[-> y { x[x][y] }] }[-> x { f[-> y { x[x][y] }] }] }[-> f { -> m { -> n { -> b { b }[-> m { -> n { -> n { n[-> x { -> x { -> y { y } } }][-> x { -> y { x } }] }[-> m { -> n { n[-> n { -> p { p[-> x { -> y { x } }] }[n[-> p { -> x { -> y { -> f { f[x][y] } } }[-> p { p[-> x { -> y { y } }] }[p]][-> n { -> p { -> x { p[n[p][x]] } } }[-> p { p[-> x { -> y { y } }] }[p]]] }][-> x { -> y { -> f { f[x][y] } } }[-> p { -> x { x } }][-> p { -> x { x } }]]] }][m] } }[m][n]] } }[n][m]][-> x { f[-> m { -> n { n[-> n { -> p { p[-> x { -> y { x } }] }[n[-> p { -> x { -> y { -> f { f[x][y] } } }[-> p { p[-> x { -> y { y } }] }[p]][-> n { -> p { -> x { p[n[p][x]] } } }[-> p { p[-> x { -> y { y } }] }[p]]] }][-> x { -> y { -> f { f[x][y] } } }[-> p { -> x { x } }][-> p { -> x { x } }]]] }][m] } }[m][n]][n][x] }][m] } } }][n][-> m { -> n { n[-> m { -> n { n[-> n { -> p { -> x { p[n[p][x]] } } }][m] } }[m]][-> p { -> x { x } }] } }[-> p { -> x { p[p[x]] } }][-> p { -> x { p[p[p[p[p[x]]]]] } }]]] } }][n]]]] }] + +FIRST = -> l { LEFT[RIGHT[l]] } +IF = -> b { b } +LEFT = -> p { p[-> x { -> y { x } } ] } +RIGHT = -> p { p[-> x { -> y { y } } ] } +IS_EMPTY = LEFT +REST = -> l { RIGHT[RIGHT[l]] } + +def to_integer(proc) + proc[-> n { n + 1 }][0] +end + +def to_boolean(proc) + IF[proc][true][false] +end + +def to_array(proc) + array = [] + + until to_boolean(IS_EMPTY[proc]) + array.push(FIRST[proc]) + proc = REST[proc] + end + + array +end + +def to_char(c) + '0123456789BFiuz'.slice(to_integer(c)) +end + +def to_string(s) + to_array(s).map { |c| to_char(c) }.join +end + +answer = to_array(solution).map do |p| + to_string(p) +end + +answer_str = answer.to_a +# puts answer_str diff --git a/web/server/h2o/libh2o/deps/mruby/benchmark/bm_fib.rb b/web/server/h2o/libh2o/deps/mruby/benchmark/bm_fib.rb new file mode 100644 index 00000000..4b395f9c --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/benchmark/bm_fib.rb @@ -0,0 +1,7 @@ + +def fib n + return n if n < 2 + fib(n-2) + fib(n-1) +end + +puts fib(37) diff --git a/web/server/h2o/libh2o/deps/mruby/benchmark/bm_so_lists.rb b/web/server/h2o/libh2o/deps/mruby/benchmark/bm_so_lists.rb new file mode 100644 index 00000000..e8f4a2a5 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/benchmark/bm_so_lists.rb @@ -0,0 +1,47 @@ +#from http://www.bagley.org/~doug/shootout/bench/lists/lists.ruby + +NUM = 300 +SIZE = 10000 + +def test_lists() + # create a list of integers (Li1) from 1 to SIZE + li1 = (1..SIZE).to_a + # copy the list to li2 (not by individual items) + li2 = li1.dup + # remove each individual item from left side of li2 and + # append to right side of li3 (preserving order) + li3 = Array.new + while (not li2.empty?) + li3.push(li2.shift) + end + # li2 must now be empty + # remove each individual item from right side of li3 and + # append to right side of li2 (reversing list) + while (not li3.empty?) + li2.push(li3.pop) + end + # li3 must now be empty + # reverse li1 in place + li1.reverse! + # check that first item is now SIZE + if li1[0] != SIZE then + p "not SIZE" + 0 + else + # compare li1 and li2 for equality + if li1 != li2 then + return(0) + else + # return the length of the list + li1.length + end + end +end + +i = 0 +while i 'mruby-eval' + # conf.gem :mgem => 'mruby-io' + # conf.gem :github => 'iij/mruby-io' + # conf.gem :git => 'git@github.com:iij/mruby-io.git', :branch => 'master', :options => '-v' + + # include the default GEMs + conf.gembox 'default' + # C compiler settings + # conf.cc do |cc| + # cc.command = ENV['CC'] || 'gcc' + # cc.flags = [ENV['CFLAGS'] || %w()] + # cc.include_paths = ["#{root}/include"] + # cc.defines = %w(DISABLE_GEMS) + # cc.option_include_path = '-I%s' + # cc.option_define = '-D%s' + # cc.compile_options = "%{flags} -MMD -o %{outfile} -c %{infile}" + # end + + # mrbc settings + # conf.mrbc do |mrbc| + # mrbc.compile_options = "-g -B%{funcname} -o-" # The -g option is required for line numbers + # end + + # Linker settings + # conf.linker do |linker| + # linker.command = ENV['LD'] || 'gcc' + # linker.flags = [ENV['LDFLAGS'] || []] + # linker.flags_before_libraries = [] + # linker.libraries = %w() + # linker.flags_after_libraries = [] + # linker.library_paths = [] + # linker.option_library = '-l%s' + # linker.option_library_path = '-L%s' + # linker.link_options = "%{flags} -o %{outfile} %{objs} %{libs}" + # end + + # Archiver settings + # conf.archiver do |archiver| + # archiver.command = ENV['AR'] || 'ar' + # archiver.archive_options = 'rs %{outfile} %{objs}' + # end + + # Parser generator settings + # conf.yacc do |yacc| + # yacc.command = ENV['YACC'] || 'bison' + # yacc.compile_options = '-o %{outfile} %{infile}' + # end + + # gperf settings + # conf.gperf do |gperf| + # gperf.command = 'gperf' + # gperf.compile_options = '-L ANSI-C -C -p -j1 -i 1 -g -o -t -N mrb_reserved_word -k"1,3,$" %{infile} > %{outfile}' + # end + + # file extensions + # conf.exts do |exts| + # exts.object = '.o' + # exts.executable = '' # '.exe' if Windows + # exts.library = '.a' + # end + + # file separetor + # conf.file_separator = '/' + + # bintest + # conf.enable_bintest +end + +MRuby::Build.new('host-debug') do |conf| + # load specific toolchain settings + + # Gets set by the VS command prompts. + if ENV['VisualStudioVersion'] || ENV['VSINSTALLDIR'] + toolchain :visualcpp + else + toolchain :gcc + end + + enable_debug + + # include the default GEMs + conf.gembox 'default' + + # C compiler settings + conf.cc.defines = %w(MRB_ENABLE_DEBUG_HOOK) + + # Generate mruby debugger command (require mruby-eval) + conf.gem :core => "mruby-bin-debugger" + + # bintest + # conf.enable_bintest +end + +MRuby::Build.new('test') do |conf| + # Gets set by the VS command prompts. + if ENV['VisualStudioVersion'] || ENV['VSINSTALLDIR'] + toolchain :visualcpp + else + toolchain :gcc + end + + enable_debug + conf.enable_bintest + conf.enable_test + + conf.gembox 'default' +end + +MRuby::Build.new('bench') do |conf| + # Gets set by the VS command prompts. + if ENV['VisualStudioVersion'] || ENV['VSINSTALLDIR'] + toolchain :visualcpp + else + toolchain :gcc + conf.cc.flags << '-O3' + end + + conf.gembox 'default' +end + +# Define cross build settings +# MRuby::CrossBuild.new('32bit') do |conf| +# toolchain :gcc +# +# conf.cc.flags << "-m32" +# conf.linker.flags << "-m32" +# +# conf.build_mrbtest_lib_only +# +# conf.gem 'examples/mrbgems/c_and_ruby_extension_example' +# +# conf.test_runner.command = 'env' +# +# end diff --git a/web/server/h2o/libh2o/deps/mruby/doc/guides/compile.md b/web/server/h2o/libh2o/deps/mruby/doc/guides/compile.md new file mode 100644 index 00000000..2aaf6f1f --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/doc/guides/compile.md @@ -0,0 +1,488 @@ +# Compile + +mruby uses Rake to compile and cross-compile all libraries and +binaries. + +## Prerequisites + +To compile mruby out of the source code you need the following tools: +* C Compiler (i.e. ```gcc```) +* Linker (i.e. ```gcc```) +* Archive utility (i.e. ```ar```) +* Parser generator (i.e. ```bison```) +* Ruby 1.8 or 1.9 (i.e. ```ruby``` or ```jruby```) + +Optional: +* GIT (to update mruby source and integrate mrbgems easier) +* C++ compiler (to use GEMs which include \*.cpp, \*.cxx, \*.cc) +* Assembler (to use GEMs which include \*.asm) + +## Usage + +Inside of the root directory of the mruby source a file exists +called *build_config.rb*. This file contains the build configuration +of mruby and looks like this for example: +```ruby +MRuby::Build.new do |conf| + toolchain :gcc +end +``` + +All tools necessary to compile mruby can be set or modified here. In case +you want to maintain an additional *build_config.rb* you can define a +customized path using the *$MRUBY_CONFIG* environment variable. + +To compile just call ```./minirake``` inside of the mruby source root. To +generate and execute the test tools call ```./minirake test```. To clean +all build files call ```./minirake clean```. To see full command line on +build, call ```./minirake -v```. + +## Build Configuration + +Inside of the *build_config.rb* the following options can be configured +based on your environment. + +### Toolchains + +The mruby build system already contains a set of toolchain templates which +configure the build environment for specific compiler infrastructures. + +#### GCC + +Toolchain configuration for the GNU C Compiler. +```ruby +toolchain :gcc +``` + +#### clang + +Toolchain configuration for the LLVM C Compiler clang. Mainly equal to the +GCC toolchain. +```ruby +toolchain :clang +``` + +#### Visual Studio 2010, 2012 and 2013 + +Toolchain configuration for Visual Studio on Windows. If you use the +[Visual Studio Command Prompt](http://msdn.microsoft.com/en-us/library/ms229859\(v=vs.110\).aspx), +you normally do not have to specify this manually, since it gets automatically detected by our build process. +```ruby +toolchain :visualcpp +``` + +#### Android + +Toolchain configuration for Android. +```ruby +toolchain :android +``` + +Requires the custom standalone Android NDK and the toolchain path +in ```ANDROID_STANDALONE_TOOLCHAIN```. + +### Binaries + +It is possible to select which tools should be compiled during the compilation +process. The following tools can be selected: +* mruby (mruby interpreter) +* mirb (mruby interactive shell) + +To select them declare conf.gem as follows: +```ruby +conf.gem "#{root}/mrbgems/mruby-bin-mruby" +conf.gem "#{root}/mrbgems/mruby-bin-mirb" +``` + +### File Separator + +Some environments require a different file separator character. It is possible to +set the character via ```conf.file_separator```. +```ruby +conf.file_separator = '/' +``` + +### C Compiler + +Configuration of the C compiler binary, flags and include paths. +```ruby +conf.cc do |cc| + cc.command = ... + cc.flags = ... + cc.include_paths = ... + cc.defines = ... + cc.option_include_path = ... + cc.option_define = ... + cc.compile_options = ... +end +``` + +C Compiler has header searcher to detect installed library. + +If you need a include path of header file use ```search_header_path```: +```ruby +# Searches ```iconv.h```. +# If found it will return include path of the header file. +# Otherwise it will return nil . +fail 'iconv.h not found' unless conf.cc.search_header_path 'iconv.h' +``` + +If you need a full file name of header file use ```search_header```: +```ruby +# Searches ```iconv.h```. +# If found it will return full path of the header file. +# Otherwise it will return nil . +iconv_h = conf.cc.search_header 'iconv.h' +print "iconv.h found: #{iconv_h}\n" +``` + +Header searcher uses compiler's ```include_paths``` by default. +When you are using GCC toolchain (including clang toolchain since its base is gcc toolchain) +it will use compiler specific include paths too. (For example ```/usr/local/include```, ```/usr/include```) + +If you need a special header search paths define a singleton method ```header_search_paths``` to C compiler: +```ruby +def conf.cc.header_search_paths + ['/opt/local/include'] + include_paths +end +``` + +### Linker + +Configuration of the Linker binary, flags and library paths. +```ruby +conf.linker do |linker| + linker.command = ... + linker.flags = ... + linker.flags_before_libraries = ... + linker.libraries = ... + linker.flags_after_libraries = ... + linker.library_paths = .... + linker.option_library = ... + linker.option_library_path = ... + linker.link_options = ... +end +``` + +### Archiver + +Configuration of the Archiver binary and flags. +```ruby +conf.archiver do |archiver| + archiver.command = ... + archiver.archive_options = ... +end +``` + +### Parser Generator + +Configuration of the Parser Generator binary and flags. +```ruby +conf.yacc do |yacc| + yacc.command = ... + yacc.compile_options = ... +end +``` + +### GPerf + +Configuration of the GPerf binary and flags. +```ruby +conf.gperf do |gperf| + gperf.command = ... + gperf.compile_options = ... +end +``` + +### File Extensions +```ruby +conf.exts do |exts| + exts.object = ... + exts.executable = ... + exts.library = ... +end +``` + +### Mrbgems + +Integrate GEMs in the build process. +```ruby +# Integrate GEM with additional configuration +conf.gem 'path/to/gem' do |g| + g.cc.flags << ... +end + +# Integrate GEM without additional configuration +conf.gem 'path/to/another/gem' +``` + +See doc/mrbgems/README.md for more option about mrbgems. + +### Mrbtest + +Configuration Mrbtest build process. + +If you want mrbtest.a only, You should set ```conf.build_mrbtest_lib_only``` +```ruby +conf.build_mrbtest_lib_only +``` + +### Bintest + +Tests for mrbgem tools using CRuby. +To have bintests place \*.rb scripts to ```bintest/``` directory of mrbgems. +See ```mruby-bin-*/bintest/*.rb``` if you need examples. +If you want a temporary files use `tempfile` module of CRuby instead of ```/tmp/```. + +You can enable it with following: +```ruby +conf.enable_bintest +``` + +### C++ ABI + +By default, mruby uses setjmp/longjmp to implement its +exceptions. But it doesn't release C++ stack object +correctly. To support mrbgems written in C++, mruby can be +configured to use C++ exception. + +There are two levels of C++ exception handling. The one is +```enable_cxx_exception``` that enables C++ exception, but +uses C ABI. The other is ```enable_cxx_abi``` where all +files are compiled by C++ compiler. + +When you mix C++ code, C++ exception would be enabled automatically. +If you need to enable C++ exception explicitly add the following: +```ruby +conf.enable_cxx_exception +``` + +#### C++ exception disabling. + +If your compiler does not support C++ and you want to ensure +you don't use mrbgem written in C++, you can explicitly disable +C++ exception, add following: +```ruby +conf.disable_cxx_exception +``` +and you will get an error when you try to use C++ gem. +Note that it must be called before ```enable_cxx_exception``` or ```gem``` method. + +### Debugging mode + +To enable debugging mode add the following: +```ruby +conf.enable_debug +``` + +When debugging mode is enabled +* Macro ```MRB_DEBUG``` would be defined. + * Which means ```mrb_assert()``` macro is enabled. +* Debug information of irep would be generated by ```mrbc```. + * Because ```-g``` flag would be added to ```mrbc``` runner. + * You can have better backtrace of mruby scripts with this. + +## Cross-Compilation + +mruby can also be cross-compiled from one platform to another. To +achieve this the *build_config.rb* needs to contain an instance of +```MRuby::CrossBuild```. This instance defines the compilation +tools and flags for the target platform. An example could look +like this: +```ruby +MRuby::CrossBuild.new('32bit') do |conf| + toolchain :gcc + + conf.cc.flags << "-m32" + conf.linker.flags << "-m32" +end +``` + +All configuration options of ```MRuby::Build``` can also be used +in ```MRuby::CrossBuild```. + +### Mrbtest in Cross-Compilation + +In cross compilation, you can run ```mrbtest``` on emulator if +you have it by changing configuration of test runner. +```ruby +conf.test_runner do |t| + t.command = ... # set emulator. this value must be non nil or false + t.flags = ... # set flags of emulator + + def t.run(bin) # override `run` if you need to change the behavior of it + ... # `bin` is the full path of mrbtest + end +end +``` + +## Build process + +During the build process the directory *build* will be created in the +root directory. The structure of this directory will look like this: + + +- build + | + +- host + | + +- bin <- Binaries (mirb, mrbc and mruby) + | + +- lib <- Libraries (libmruby.a and libmruby_core.a) + | + +- mrblib + | + +- src + | + +- test <- mrbtest tool + | + +- tools + | + +- mirb + | + +- mrbc + | + +- mruby + +The compilation workflow will look like this: +* compile all files under *src* (object files will be stored +in *build/host/src*) +* generate parser grammar out of *src/parse.y* (generated +result will be stored in *build/host/src/y.tab.c*) +* compile *build/host/src/y.tab.c* to *build/host/src/y.tab.o* +* create *build/host/lib/libmruby_core.a* out of all object files (C only) +* create ```build/host/bin/mrbc``` by compiling *tools/mrbc/mrbc.c* and +linking with *build/host/lib/libmruby_core.a* +* create *build/host/mrblib/mrblib.c* by compiling all \*.rb files +under *mrblib* with ```build/host/bin/mrbc``` +* compile *build/host/mrblib/mrblib.c* to *build/host/mrblib/mrblib.o* +* create *build/host/lib/libmruby.a* out of all object files (C and Ruby) +* create ```build/host/bin/mruby``` by compiling *mrbgems/mruby-bin-mruby/tools/mruby/mruby.c* and +linking with *build/host/lib/libmruby.a* +* create ```build/host/bin/mirb``` by compiling *mrbgems/mruby-bin-mirb/tools/mirb/mirb.c* and +linking with *build/host/lib/libmruby.a* + +``` + _____ _____ ______ ____ ____ _____ _____ ____ +| CC |->|GEN |->|AR |->|CC |->|CC |->|AR |->|CC |->|CC | +| *.c | |y.tab| |core.a| |mrbc| |*.rb| |lib.a| |mruby| |mirb| + ----- ----- ------ ---- ---- ----- ----- ---- +``` + +### Cross-Compilation + +In case of a cross-compilation to *i386* the *build* directory structure looks +like this: + + +- build + | + +- host + | | + | +- bin <- Native Binaries + | | + | +- lib <- Native Libraries + | | + | +- mrblib + | | + | +- src + | | + | +- test <- Native mrbtest tool + | | + | +- tools + | | + | +- mirb + | | + | +- mrbc + | | + | +- mruby + +- i386 + | + +- bin <- Cross-compiled Binaries + | + +- lib <- Cross-compiled Libraries + | + +- mrblib + | + +- src + | + +- test <- Cross-compiled mrbtest tool + | + +- tools + | + +- mirb + | + +- mrbc + | + +- mruby + +An extra directory is created for the target platform. In case you +compile for *i386* a directory called *i386* is created under the +build directory. + +The cross compilation workflow starts in the same way as the normal +compilation by compiling all *native* libraries and binaries. +Afterwards the cross compilation process proceeds like this: +* cross-compile all files under *src* (object files will be stored +in *build/i386/src*) +* generate parser grammar out of *src/parse.y* (generated +result will be stored in *build/i386/src/y.tab.c*) +* cross-compile *build/i386/src/y.tab.c* to *build/i386/src/y.tab.o* +* create *build/i386/mrblib/mrblib.c* by compiling all \*.rb files +under *mrblib* with the native ```build/host/bin/mrbc``` +* cross-compile *build/host/mrblib/mrblib.c* to *build/host/mrblib/mrblib.o* +* create *build/i386/lib/libmruby.a* out of all object files (C and Ruby) +* create ```build/i386/bin/mruby``` by cross-compiling *mrbgems/mruby-bin-mruby/tools/mruby/mruby.c* and +linking with *build/i386/lib/libmruby.a* +* create ```build/i386/bin/mirb``` by cross-compiling *mrbgems/mruby-bin-mirb/tools/mirb/mirb.c* and +linking with *build/i386/lib/libmruby.a* +* create *build/i386/lib/libmruby_core.a* out of all object files (C only) +* create ```build/i386/bin/mrbc``` by cross-compiling *tools/mrbc/mrbc.c* and +linking with *build/i386/lib/libmruby_core.a* + +``` + _______________________________________________________________ +| Native Compilation for Host System | +| _____ ______ _____ ____ ____ _____ | +| | CC | -> |AR | -> |GEN | -> |CC | -> |CC | -> |AR | | +| | *.c | |core.a| |y.tab| |mrbc| |*.rb| |lib.a| | +| ----- ------ ----- ---- ---- ----- | + --------------------------------------------------------------- + || + \||/ + \/ + ________________________________________________________________ +| Cross Compilation for Target System | +| _____ _____ _____ ____ ______ _____ | +| | CC | -> |AR | -> |CC | -> |CC | -> |AR | -> |CC | | +| | *.c | |lib.a| |mruby| |mirb| |core.a| |mrbc | | +| ----- ----- ----- ---- ------ ----- | + ---------------------------------------------------------------- +``` + +## Build Configuration Examples + +### Minimal Library + +To build a minimal mruby library you need to use the Cross Compiling +feature due to the reason that there are functions (i.e. stdio) which +can't be disabled for the main build. + +```ruby +MRuby::CrossBuild.new('Minimal') do |conf| + toolchain :gcc + + conf.cc.defines = %w(MRB_DISABLE_STDIO) + conf.bins = [] +end +``` + +This configuration defines a cross compile build called 'Minimal' which +is using the GCC and compiles for the host machine. It also disables +all usages of stdio and doesn't compile any binaries (i.e. mrbc). + +## Test Environment + +mruby's build process includes a test environment. In case you start the testing +of mruby, a native binary called ```mrbtest``` will be generated and executed. +This binary contains all test cases which are defined under *test/t*. In case +of a cross-compilation an additional cross-compiled *mrbtest* binary is +generated. You can copy this binary and run on your target system. diff --git a/web/server/h2o/libh2o/deps/mruby/doc/guides/debugger.md b/web/server/h2o/libh2o/deps/mruby/doc/guides/debugger.md new file mode 100644 index 00000000..72f2c2b3 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/doc/guides/debugger.md @@ -0,0 +1,370 @@ +# How to Use the mruby Debugger + +copyright (c) 2014 Specified Non-Profit Corporation mruby Forum + +## 1. Summary + +This file documents the mruby debugger ('mrdb') methods. + +## 2 Debugging with mrdb + +## 2.1 Building mrdb + +The trunk of the mruby source tree, with the most recent mrdb, can be checked out with the following command: + +```bash +$ git clone https://github.com/mruby/mruby.git +``` + +To run the `make` command: + +```bash +$ cd mruby +$ make +``` + +By default, the `make` command will install the debugger files into mruby/bin. + +You can add the path for mrdb on your host environment with the following command: + +```bash +$ echo "export PATH=\$PATH:MRUBY_ROOT/bin" >> ~/.bashrc +$ source ~/.bashrc +``` + +`*MRUBY_ROOT` is the directory in which mruby source code will be installed. + +To confirm mrdb was installed properly, run mrdb with the `--version` option: + +```bash +$ mrdb --version +mruby 1.3.0 (2017-7-4) +``` + +## 2.2 Basic Operation + +### 2.2.1 Debugging mruby Script Files (rb file) with mrdb + +To invoke the mruby debugger, just type `mrdb`. + +To specify the script file: + +```bash +$ mrdb [option] file name +``` + +For example: Debugging sample.rb + +```bash +$ mrdb sample.rb +``` + +You can execute the shell commands listed below: + +|command|description| +|:-:|:--| +|run|execute programs| +|step|execute stepping| +|continue|execute continuing program| +|break|configure the breaking point| +|delete|deleting the breaking points| +|disable|disabling the breaking points| +|enable|enabling the breaking points| +|info breakpoints|showing list of the breaking points| +|print|evaluating and printing the values of the mruby expressions in the script| +|list|displaying the source cords| +|help|showing help| +|quit|terminating the mruby debugger| + +### 2.2.2 Debugging mruby Binary Files (mrb file) with mrdb + +You can debug the mruby binary files. + +#### 2.2.2.1 Debugging the binary files + +* notice +To debug mruby binary files, you need to compile mruby files with option `-g`. + +```bash +$ mrbc -g sample.rb +``` + +You can debug the mruby binary files with following command and the option `-b`. + +```bash +$ mrdb -b sample.mrb +``` + +Then you can execute all debugger shell commands. + +#### Break Command + +You can use any breakpoint to stop the program by specifying the line number and method name. +The breakpoint list will be displayed after you have set the breakpoint successfully. + +Usage: + +``` +break [file:]linenum +b [file:]linenum +break [class:]method +b [class:]method +``` + +The breakpoint will be ordered in serial from 1. +The number, which was given to the deleted breakpoint, will never be given to another breakpoint again. + +You can give multiple breakpoints to specified the line number and method. +Be ware that breakpoint command will not check the validity of the class name and method name. + +You can get the current breakpoint information by the following options. + +breakpoint breakpoint number : file name. line number + +breakpoint breakpoint number : [class name,] method name + +#### Continue Command + +Usage: + +``` +continue [N] +c [N] +``` + +N: the next breakpoint number + +When resuming the program, it will stop at breakpoint N (N-1 breakpoint will be ignored). + +When you run the `continue` command without specifying N, the program will be stopped at the next breakpoint. + +Example: + +``` +(foo.rb:1) continue 3 +``` + +This will resume the program and stop it at the third breakpoint. + +#### Delete Command + +This will delete the specified breakpoint. + +Usage: + +``` +delete [breakpoint-no] +d [breakpoint-no] +``` + +breakpoint-no: breakpoint number + +Example: + +``` +(foo.rb:1) delete +``` + +This will delete all of the breakpoints. + +``` +(foo.rb:1) delete 1 3 +``` + +This will delete the breakpoint at 1 and 3. + +#### Disable Command + +This will disable the specified breakpoint. + +Usage: + +``` +disable [breakpoint-no] +dis [breakpoint-no] +``` + +reappointing: breakpoint number + +Example: + +``` +(foo.rb:1) disable +``` + +Use `disable` if you would like to disable all of the breakpoints. + +``` +(foo.rb:1) disable 1 3 +``` + +This will disable the breakpoints at 1 and 3. + +#### Enable Command + +This will enable the specified breakpoints. + +Usage: + +``` +enable [breakpoint-no] +e [breakpoint-no] +``` + +breakpoint-no: breakpoint number + +Example: + +``` +(foo.rb:1) enable +``` + +Enabling all breakpoints +``` +(foo.rb:1) enable 1 3 +``` + +Enabling the breakpoint 1 and 3 + +#### eval command + +Evaluating the string as source code and printing the value. + +Same as print command, please see print command. + +#### help command + +Displaying the help message. + +Usage: + +``` +help [command] +h [command] +``` + +Typing `help` without any options will display the command list. + +#### Info Breakpoints Command + +Displaying the specified breakpoint information. + +Usage: + +``` +info breakpoints [breakpoint-no] +i b [breakpoint-no] +``` + +breakpoint-no: breakpoint number + +Typing "info breakpoints" without ant option will display all breakpoint information. +Example: + +``` +(sample.rb:1) info breakpoints +Num Type Enb What +1 breakpoint y at sample.rb:3 -> file name,line number +2 breakpoint n in Sample_class:sample_class_method -> [class:]method name +3 breakpoint y in sample_global_method +``` + +Displaying the specified breakpoint number: + +``` +(foo.rb:1) info breakpoints 1 3 +Num Type Enb What +1 breakpoint y at sample.rb:3 +3 breakpoint y in sample_global_method +``` + +#### List Command + +To display the code of the source file. + +Usage: + +``` +list [filename:]first[,last] +l [filename]:first[,last] +``` + +first: the opening row number +last : the closing row number + +When you specify the `first`, but not the `last` option, you will receive 10 rows. +When you do not specify both the `first` and `last` options, you will receive the next 10 rows. + +Example: + +``` +Specifying file name and first row number +sample.rb:1) list sample2.rb:5 +``` + +Specifying the file name and the first and last row number: + +``` +(sample.rb:1) list sample2.rb:6,7 +``` + +#### Print Command + +Evaluating the string as source code and printing the value. + +Usage: + +``` +print [expr] +p [expr] +``` + +expr: expression + +The expression is mandatory. +The displayed expressions will be serially ordered from 1. +If an exception occurs, the exception information will be displayed and the debugging will be continued. + +Example: + +``` +(sample.rb:1) print 1+2 +$1 = 3 +(sample.rb:1) print self +$2 = main +``` + +Below is the case of the exception: + +``` +(sample.rb:1) print (1+2 +$1 = SyntaxError: line 1: syntax error, unexpected $end, expecting ')' +``` + +#### Quit Command + +Quitting the debugger. + +Usage: + +``` +quit +q +``` + +#### Run Command + +Running the program and stopping at the first breakpoint. + +Usage: + +``` +run +r +``` + +#### Step Command + +This will run the program step by step. +When the method and the block are invoked, the program will be stop at the first row. +The program, which is developed in C, will be ignored. diff --git a/web/server/h2o/libh2o/deps/mruby/doc/guides/gc-arena-howto.md b/web/server/h2o/libh2o/deps/mruby/doc/guides/gc-arena-howto.md new file mode 100644 index 00000000..aff7360e --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/doc/guides/gc-arena-howto.md @@ -0,0 +1,177 @@ +# How to use `mrb_gc_arena_save()`/`mrb_gc_arena_restore()`/`mrb_gc_protect()` + +_This is an English translation of [Matz's blog post][matz blog post] +written in Japanese._ +_Some parts are updated to reflect recent changes._ +[matz blog post]: http://www.rubyist.net/~matz/20130731.html + +When you are extending mruby using C language, you may encounter +mysterious "arena overflow error" or memory leak or very slow +execution speed. This is an error indicating overflow of "GC arena" +implementing "conservative GC". + +GC (garbage collector) must ensure that object is "alive", in other +words, that it is referenced by somewhere from program. This can be +determined by checking if the object can be directly or indirectly +referenced by root. The local variables, global variables and +constants etc are root. + +If program execution is performed inside mruby VM, there is nothing to +worry about because GC can access all roots owned by VM. + +The problem arises when executing C functions. The object referenced +by C variable is also "alive", but mruby GC cannot aware of this, so +it might mistakenly recognize the objects referenced by only C +variables as dead. + +This can be a fatal bug if the GC tries to collect a live object. + +In CRuby, we scan C stack area, and use C variable as root to check +whether object is alive or not. Of course, because we are accessing C +stack just as memory region, we never know it is an integer or a +pointer. We workaround this by assuming that if it looks like a +pointer, then assume it as a pointer. We call it "conservative". + +By the way, CRuby's "conservative GC" has some problems. + +The biggest problem is we have no way to access to the stack area in +portable way. Therefore, we cannot use this method if we'd like to +implement highly portable runtime, like mruby. + +So we came up with an another plan to implement "conservative GC" in mruby. + +Again, the problem is when an object which was created in C function, becomes +no longer referenced in the Ruby world, and cannot be treated as garbage. + +In mruby, we recognize all objects created in C function are alive. +Then we have no problem such as confusing a live object as dead. + +This means that because we cannot collect truly dead object, we may +lose efficiency, but as a trade-off the GC itself is highly portable. +We can say goodbye to the problem that GC deletes live objects due to +optimization which sometimes occurs in CRuby. + +According to this idea, we have a table, called "GC arena", which +remembers objects created in C function. + +The arena is stack structure, when C function execution is returned to mruby +VM, all objects registered in the arena are popped. + +This works very well, but can cause another problem: "arena overflow error" or +memory leak. + +As of this writing, mruby automatically extend arena to remember +objects (See `MRB_GC_FIXED_ARENA` and `MRB_GC_ARENA_SIZE` in +doc/guides/mrbconf.md). + +If you create many objects in C functions, memory usage will increase, since +GC never kick in. This memory usage may look like memory leak, but will also +make execution slower as more memory will need to be allocated. + +With the build time configuration, you can limit the maximum size of +arena (e.g., 100). Then if you create many objects, arena overflows, +thus you will get an "arena overflow error". + +To workaround these problems, we have `mrb_gc_arena_save()` and +`mrb_gc_arena_restore()` functions. + +`int mrb_gc_arena_save(mrb)` returns the current position of the stack +top of GC arena, and `void mrb_gc_arena_restore(mrb, idx)` sets the +stack top position to back to given `idx`. + +We can use them like this: + +```c +int arena_idx = mrb_gc_arena_save(mrb); + +// ...create objects... +mrb_gc_arena_restore(mrb, arena_idx); + +``` + +In mruby, C function calls are surrounded by this save/restore, but we +can further optimize memory usage by surrounding save/restore, and can +avoid creating arena overflow bugs. + +Let's take a real example. Here is the source code of `Array#inspect`: + +```c +static mrb_value +inspect_ary(mrb_state *mrb, mrb_value ary, mrb_value list) +{ + mrb_int i; + mrb_value s, arystr; + char head[] = { '[' }; + char sep[] = { ',', ' ' }; + char tail[] = { ']' }; + + /* check recursive */ + for(i=0; i 0) { + mrb_str_cat(mrb, arystr, sep, sizeof(sep)); + } + if (mrb_array_p(RARRAY_PTR(ary)[i])) { + s = inspect_ary(mrb, RARRAY_PTR(ary)[i], list); + } + else { + s = mrb_inspect(mrb, RARRAY_PTR(ary)[i]); + } + mrb_str_cat(mrb, arystr, RSTRING_PTR(s), RSTRING_LEN(s)); + mrb_gc_arena_restore(mrb, ai); + } + + mrb_str_cat(mrb, arystr, tail, sizeof(tail)); + mrb_ary_pop(mrb, list); + + return arystr; +} +``` + +This is a real example, so a little bit complicated, but bear with me. +The essence of `Array#inspect` is that after stringifying each element +of array using `inspect` method, we join them together so that we can +get `inspect` representation of the entire array. + +After the `inspect` representation is created, we no longer require the +individual string representation. This means that we don't have to register +these temporal objects into GC arena. + +Therefore, in order to keep the arena size small; the `ary_inspect()` function +will do the following: + +* save the position of the stack top using `mrb_gc_arena_save()`. +* get `inspect` representation of each element. +* append it to the constructing entire `inspect` representation of array. +* restore stack top position using `mrb_gc_arena_restore()`. + +Please note that the final `inspect` representation of entire array +was created before the call of `mrb_gc_arena_restore()`. Otherwise, +required temporal object may be deleted by GC. + +We may have a usecase where after creating many temporal objects, we'd +like to keep some of them. In this case, we cannot use the same idea +in `ary_inspect()` like appending objects to existing one. +Instead, after `mrb_gc_arena_restore()`, we must re-register the objects we +want to keep in the arena using `mrb_gc_protect(mrb, obj)`. +Use `mrb_gc_protect()` with caution because it could also lead to an "arena +overflow error". + +We must also mention that when `mrb_funcall` is called in top level, the return +value is also registered to GC arena, so repeated use of `mrb_funcall` may +eventually lead to an "arena overflow error". + +Use `mrb_gc_arena_save()` and `mrb_gc_arena_restore()` or possible use of +`mrb_gc_protect()` to workaround this. diff --git a/web/server/h2o/libh2o/deps/mruby/doc/guides/mrbconf.md b/web/server/h2o/libh2o/deps/mruby/doc/guides/mrbconf.md new file mode 100644 index 00000000..f957f8ce --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/doc/guides/mrbconf.md @@ -0,0 +1,146 @@ +# mruby configuration macros. + +## How to use these macros. +You can use mrbconfs with following ways: +* Write them in `mrbconf.h`. + * Using compiler flags is preferred when building a cross binaries or multiple mruby binaries + since it's easier to use different mrbconf per each `MRuby::Build`. + * Most flags can be enabled by just commenting in. +* Pass them as compiler flags. + * Make sure you pass the same flags to all compilers since some mrbconf(e.g., `MRB_GC_FIXED_ARENA`) + changes `struct` layout and cause memory access error when C and other language(e.g., C++) is mixed. + +## stdio setting. +`MRB_DISABLE_STDIO` +* When defined `` functions won't be used. +* Some features will be disabled when this is enabled: + * `mrb_irep` load/dump from/to file. + * Compiling mruby script from file. + * Printing features in **src/print.c**. + +## Debug macros. +`MRB_ENABLE_DEBUG_HOOK` +* When defined code fetch hook and debug OP hook will be enabled. +* When using any of the hook set function pointer `code_fetch_hook` and/or `debug_op_hook` of `mrb_state`. +* Fetch hook will be called before any OP. +* Debug OP hook will be called when dispatching `OP_DEBUG`. + +`MRB_DEBUG` +* When defined `mrb_assert*` macro will be defined with macros from ``. +* Could be enabled via `enable_debug` method of `MRuby::Build`. + +## Stack configuration + +`MRB_STACK_EXTEND_DOUBLING` +* If defined doubles the stack size when extending it. +* Else extends stack with `MRB_STACK_GROWTH`. + +`MRB_STACK_GROWTH` +* Default value is `128`. +* Used in stack extending. +* Ignored when `MRB_STACK_EXTEND_DOUBLING` is defined. + +`MRB_STACK_MAX` +* Default value is `0x40000 - MRB_STACK_GROWTH`. +* Raises `RuntimeError` when stack size exceeds this value. + +## Primitive type configuration. + +`MRB_USE_FLOAT` +* When defined single precision floating point type(C type `float`) is used as `mrb_float`. +* Else double precision floating point type(C type `double`) is used as `mrb_float`. + +`MRB_INT16` +* When defined `int16_t` will be defined as `mrb_int`. +* Conflicts with `MRB_INT64`. + +`MRB_INT64` +* When defined `int64_t` will be defined as `mrb_int`. +* Conflicts with `MRB_INT16`. +* When `MRB_INT16` or `MRB_INT64` isn't defined `int`(most of the times 32-bit integer) +will be defined as `mrb_int`. + +## Garbage collector configuration. + +`MRB_GC_STRESS` +* When defined full GC is emitted per each `RBasic` allocation. +* Mainly used in memory manager debugging. + +`MRB_GC_TURN_OFF_GENERATIONAL` +* When defined turns generational GC by default. + +`MRB_GC_FIXED_ARENA` +* When defined used fixed size GC arena. +* Raises `RuntimeError` when this is defined and GC arena size exceeds `MRB_GC_ARENA_SIZE`. +* Useful tracking unnecessary mruby object allocation. + +`MRB_GC_ARENA_SIZE` +* Default value is `100`. +* Ignored when `MRB_GC_FIXED_ARENA` isn't defined. +* Defines fixed GC arena size. + +`MRB_HEAP_PAGE_SIZE` +* Defines value is `1024`. +* Specifies number of `RBasic` per each heap page. + +## Memory pool configuration. + +`POOL_ALIGNMENT` +* Default value is `4`. +* If you're allocating data types that requires alignment more than default value define the +largest value of required alignment. + +`POOL_PAGE_SIZE` +* Default value is `16000`. +* Specifies page size of pool page. +* Smaller the value is increases memory overhead. + +## State atexit configuration. + +`MRB_FIXED_STATE_ATEXIT_STACK` +* If defined enables fixed size `mrb_state` atexit stack. +* Raises `RuntimeError` when `mrb_state_atexit` call count to same `mrb_state` exceeds +`MRB_FIXED_STATE_ATEXIT_STACK_SIZE`'s value. + +`MRB_FIXED_STATE_ATEXIT_STACK_SIZE` +* Default value is `5`. +* If `MRB_FIXED_STATE_ATEXIT_STACK` isn't defined this macro is ignored. + +## `mrb_value` configuration. + +`MRB_ENDIAN_BIG` +* If defined compiles mruby for big endian machines. +* Used in `MRB_NAN_BOXING`. +* Some mrbgem use this mrbconf. + +`MRB_NAN_BOXING` +* If defined represent `mrb_value` in boxed `double`. +* Conflicts with `MRB_USE_FLOAT`. + +`MRB_WORD_BOXING` +* If defined represent `mrb_value` as a word. +* If defined `Float` will be a mruby object with `RBasic`. + +## Instance variable configuration. +`MRB_IV_SEGMENT_SIZE` +* Default value is `4`. +* Specifies size of each segment in segment list. + +## Other configuration. +`MRB_UTF8_STRING` +* Adds UTF-8 encoding support to character-oriented String instance methods. +* If it isn't defined, they only support the US-ASCII encoding. + +`MRB_FUNCALL_ARGC_MAX` +* Default value is `16`. +* Specifies 4th argument(`argc`) max value of `mrb_funcall`. +* Raises `ArgumentError` when the `argc` argument is bigger then this value `mrb_funcall`. + +`KHASH_DEFAULT_SIZE` +* Default value is `32`. +* Specifies default size of khash table bucket. +* Used in `kh_init_ ## name` function. + +`MRB_STR_BUF_MIN_SIZE` +* Default value is `128`. +* Specifies initial capacity of `RString` created by `mrb_str_buf_new` function.. diff --git a/web/server/h2o/libh2o/deps/mruby/doc/guides/mrbgems.md b/web/server/h2o/libh2o/deps/mruby/doc/guides/mrbgems.md new file mode 100644 index 00000000..258f405b --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/doc/guides/mrbgems.md @@ -0,0 +1,340 @@ +# mrbgems + +mrbgems is a library manager to integrate C and Ruby extension in an easy and +standardised way into mruby. + +## Usage + +By default mrbgems is currently deactivated. As soon as you add a GEM to your +build configuration (i.e. *build_config.rb*), mrbgems will be activated and the +extension integrated. + +To add a GEM into the *build_config.rb* add the following line for example: +```ruby +conf.gem '/path/to/your/gem/dir' +``` + +You can also use a relative path which would be relative from the mruby root: +```ruby +conf.gem 'examples/mrbgems/ruby_extension_example' +``` + +A remote GIT repository location for a GEM is also supported: +```ruby +conf.gem :git => 'https://github.com/masuidrive/mrbgems-example.git', :branch => 'master' +conf.gem :github => 'masuidrive/mrbgems-example', :branch => 'master' +conf.gem :bitbucket => 'mruby/mrbgems-example', :branch => 'master' +``` + +To use mrbgem from [mgem-list](https://github.com/mruby/mgem-list) use `:mgem` option: +```ruby +conf.gem :mgem => 'mruby-yaml' +conf.gem :mgem => 'yaml' # 'mruby-' prefix could be omitted +``` + +If there is missing dependencies, mrbgem dependencies solver will reference +mrbgem from core or mgem-list. + +To pull all gems from remote GIT repository on build, call ```./minirake -p```, +or ```./minirake --pull-gems```. + +NOTE: `:bitbucket` option supports only git. Hg is unsupported in this version. + +## GemBox + +There are instances when you wish to add a collection of mrbgems into mruby at +once, or be able to substitute mrbgems based on configuration, without having to +add each gem to the *build_config.rb* file. A packaged collection of mrbgems +is called a GemBox. A GemBox is a file that contains a list of mrbgems to load +into mruby, in the same format as if you were adding them to *build_config.rb* +via `config.gem`, but wrapped in an `MRuby::GemBox` object. GemBoxes are +loaded into mruby via `config.gembox 'boxname'`. + +Below we have created a GemBox containing *mruby-time* and *mrbgems-example*: +```ruby +MRuby::GemBox.new do |conf| + conf.gem "#{root}/mrbgems/mruby-time" + conf.gem :github => 'masuidrive/mrbgems-example' +end +``` + +As mentioned, the GemBox uses the same conventions as `MRuby::Build`. The GemBox +must be saved with a *.gembox* extension inside the *mrbgems* directory to to be +picked up by mruby. + +To use this example GemBox, we save it as `custom.gembox` inside the *mrbgems* +directory in mruby, and add the following to our *build_config.rb* file inside +the build block: +```ruby +conf.gembox 'custom' +``` +This will cause the *custom* GemBox to be read in during the build process, +adding *mruby-time* and *mrbgems-example* to the build. + +If you want, you can put GemBox outside of mruby directory. In that case you must +specify an absolute path like below. +```ruby +conf.gembox "#{ENV["HOME"]}/mygemboxes/custom" +``` + +There are two GemBoxes that ship with mruby: [default](../../mrbgems/default.gembox) +and [full-core](../../mrbgems/full-core.gembox). The [default](../../mrbgems/default.gembox) GemBox +contains several core components of mruby, and [full-core](../../mrbgems/full-core.gembox) +contains every gem found in the *mrbgems* directory. + +## GEM Structure + +The maximal GEM structure looks like this: + + +- GEM_NAME <- Name of GEM + | + +- include/ <- Header for Ruby extension (will exported) + | + +- mrblib/ <- Source for Ruby extension + | + +- src/ <- Source for C extension + | + +- test/ <- Test code (Ruby) + | + +- mrbgem.rake <- GEM Specification + | + +- README.md <- Readme for GEM + +The folder *mrblib* contains pure Ruby files to extend mruby. The folder *src* +contains C/C++ files to extend mruby. The folder *include* contains C/C++ header +files. The folder *test* contains C/C++ and pure Ruby files for testing purposes +which will be used by `mrbtest`. *mrbgem.rake* contains the specification +to compile C and Ruby files. *README.md* is a short description of your GEM. + +## Build process + +mrbgems expects a specification file called *mrbgem.rake* inside of your +GEM directory. A typical GEM specification could look like this for example: +```ruby +MRuby::Gem::Specification.new('c_and_ruby_extension_example') do |spec| + spec.license = 'MIT' + spec.author = 'mruby developers' + spec.summary = 'Example mrbgem using C and ruby' +end +``` + +The mrbgems build process will use this specification to compile Object and Ruby +files. The compilation results will be added to *lib/libmruby.a*. This file exposes +the GEM functionality to tools like `mruby` and `mirb`. + +The following properties can be set inside of your `MRuby::Gem::Specification` for +information purpose: + +* `spec.license` or `spec.licenses` (A single license or a list of them under which this GEM is licensed) +* `spec.author` or `spec.authors` (Developer name or a list of them) +* `spec.version` (Current version) +* `spec.description` (Detailed description) +* `spec.summary` + * One line short description of mrbgem. + * Printed in build summary of rake when set. +* `spec.homepage` (Homepage) +* `spec.requirements` (External requirements as information for user) + +The `license` and `author` properties are required in every GEM! + +In case your GEM is depending on other GEMs please use +`spec.add_dependency(gem, *requirements[, default_get_info])` like: +```ruby +MRuby::Gem::Specification.new('c_and_ruby_extension_example') do |spec| + spec.license = 'MIT' + spec.author = 'mruby developers' + + # Add GEM dependency mruby-parser. + # The version must be between 1.0.0 and 1.5.2 . + spec.add_dependency('mruby-parser', '>= 1.0.0', '<= 1.5.2') + + # Use any version of mruby-uv from github. + spec.add_dependency('mruby-uv', '>= 0.0.0', :github => 'mattn/mruby-uv') + + # Use latest mruby-onig-regexp from github. (version requirements can be omitted) + spec.add_dependency('mruby-onig-regexp', :github => 'mattn/mruby-onig-regexp') + + # You can add extra mgems active only on test + spec.add_test_dependency('mruby-process', :github => 'iij/mruby-process') +end +``` + +The version requirements and default gem information are optional. + +Version requirement supports following operators: +* '=': is equal +* '!=': is not equal +* '>': is greater +* '<': is lesser +* '>=': is equal or greater +* '<=': is equal or lesser +* '~>': is equal or greater and is lesser than the next major version + * example 1: '~> 2.2.2' means '>= 2.2.2' and '< 2.3.0' + * example 2: '~> 2.2' means '>= 2.2.0' and '< 3.0.0' + +When more than one version requirements is passed, the dependency must satisfy all of it. + +You can have default gem to use as depedency when it's not defined in *build_config.rb*. +When the last argument of `add_dependency` call is `Hash`, it will be treated as default gem information. +Its format is same as argument of method `MRuby::Build#gem`, expect that it can't be treated as path gem location. + +When a special version of depedency is required, +use `MRuby::Build#gem` in *build_config.rb* to override default gem. + +If you have conflicting GEMs use the following method: +* `spec.add_conflict(gem, *requirements)` + * The `requirements` argument is same as in `add_dependency` method. + +like following code: +```ruby +MRuby::Gem::Specification.new 'some-regexp-binding' do |spec| + spec.license = 'BSD' + spec.author = 'John Doe' + + spec.add_conflict 'mruby-onig-regexp', '> 0.0.0' + spec.add_conflict 'mruby-hs-regexp' + spec.add_conflict 'mruby-pcre-regexp' + spec.add_conflict 'mruby-regexp-pcre' +end +``` + +In case your GEM has more complex build requirements you can use +the following options additionally inside of your GEM specification: + +* `spec.cc.flags` (C compiler flags) +* `spec.cc.defines` (C compiler defines) +* `spec.cc.include_paths` (C compiler include paths) +* `spec.linker.flags` (Linker flags) +* `spec.linker.libraries` (Linker libraries) +* `spec.linker.library_paths` (Linker additional library path) +* `spec.bins` (Generate binary file) +* `spec.rbfiles` (Ruby files to compile) +* `spec.objs` (Object files to compile) +* `spec.test_rbfiles` (Ruby test files for integration into mrbtest) +* `spec.test_objs` (Object test files for integration into mrbtest) +* `spec.test_preload` (Initialization files for mrbtest) + +You also can use `spec.mruby.cc` and `spec.mruby.linker` to add extra global parameters for compiler and linker. + +### include_paths and dependency + +Your GEM can export include paths to another GEMs that depends on your GEM. +By default, `/...absolute path.../{GEM_NAME}/include` will be exported. +So it is recommended not to put GEM's local header files on include/. + +These exports are retroactive. +For example: when B depends to C and A depends to B, A will get include paths exported by C. + +Exported include_paths are automatically appended to GEM local include_paths by Minirake. +You can use `spec.export_include_paths` accessor if you want more complex build. + + +## C Extension + +mruby can be extended with C. This is possible by using the C API to +integrate C libraries into mruby. + +### Preconditions + +mrbgems expects that you have implemented a C method called +`mrb_YOURGEMNAME_gem_init(mrb_state)`. `YOURGEMNAME` will be replaced +by the name of your GEM. If you call your GEM *c_extension_example*, your +initialisation method could look like this: +```C +void +mrb_c_extension_example_gem_init(mrb_state* mrb) { + struct RClass *class_cextension = mrb_define_module(mrb, "CExtension"); + mrb_define_class_method(mrb, class_cextension, "c_method", mrb_c_method, MRB_ARGS_NONE()); +} +``` + +### Finalize + +mrbgems expects that you have implemented a C method called +`mrb_YOURGEMNAME_gem_final(mrb_state)`. `YOURGEMNAME` will be replaced +by the name of your GEM. If you call your GEM *c_extension_example*, your +finalizer method could look like this: + +```C +void +mrb_c_extension_example_gem_final(mrb_state* mrb) { + free(someone); +} +``` + +### Example + + +- c_extension_example/ + | + +- src/ + | | + | +- example.c <- C extension source + | + +- test/ + | | + | +- example.rb <- Test code for C extension + | + +- mrbgem.rake <- GEM specification + | + +- README.md + +## Ruby Extension + +mruby can be extended with pure Ruby. It is possible to override existing +classes or add new ones in this way. Put all Ruby files into the *mrblib* +folder. + + +### Pre-Conditions + +none + +### Example + + +- ruby_extension_example/ + | + +- mrblib/ + | | + | +- example.rb <- Ruby extension source + | + +- test/ + | | + | +- example.rb <- Test code for Ruby extension + | + +- mrbgem.rake <- GEM specification + | + +- README.md + +## C and Ruby Extension + +mruby can be extended with C and Ruby at the same time. It is possible to +override existing classes or add new ones in this way. Put all Ruby files +into the *mrblib* folder and all C files into the *src* folder. + +mruby codes under *mrblib* directory would be executed after gem init C +function is called. Make sure *mruby script* depends on *C code* and +*C code* doesn't depend on *mruby script*. + +### Pre-Conditions + +See C and Ruby example. + +### Example + + +- c_and_ruby_extension_example/ + | + +- mrblib/ + | | + | +- example.rb <- Ruby extension source + | + +- src/ + | | + | +- example.c <- C extension source + | + +- test/ + | | + | +- example.rb <- Test code for C and Ruby extension + | + +- mrbgem.rake <- GEM specification + | + +- README.md diff --git a/web/server/h2o/libh2o/deps/mruby/doc/limitations.md b/web/server/h2o/libh2o/deps/mruby/doc/limitations.md new file mode 100644 index 00000000..db8db9a5 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/doc/limitations.md @@ -0,0 +1,208 @@ +# Limitations and Differences + +The philosophy of mruby is to be a lightweight implementation of +the Ruby ISO standard. These two objectives are partially contradicting. +Ruby is an expressive language with complex implementation details which +are difficult to implement in a lightweight manner. To cope with this, +limitations to the "Ruby Compatibility" are defined. + +This document is collecting these limitations. + +## Integrity + +This document does not contain a complete list of limitations. +Please help to improve it by submitting your findings. + + +## ```1/2``` gives ```0.5``` + +Since mruby does not have ```Bignum```, bigger integers are represented +by ```Float``` numbers. To enhance interoperability between ```Fixnum``` +and ```Float```, mruby provides ```Float#upto``` and other iterating +methods for the ```Float``` class. As a side effect, ```1/2``` gives ```0.5``` +not ```0```. + +## ```Array``` passed to ```puts``` + +Passing an Array to ```puts``` results in different output. + +```ruby +puts [1,2,3] +``` + +#### Ruby [ruby 2.0.0p645 (2015-04-13 revision 50299)] + +``` +1 +2 +3 +``` + +#### mruby [1.3.0 (2017-7-4)] + +``` +[1, 2, 3] +``` + +## ```Kernel.raise``` in rescue clause + +```Kernel.raise``` without arguments does not raise the current exception within +a rescue clause. + +```ruby +begin + 1 / 0 +rescue + raise +end +``` + +#### Ruby [ruby 2.0.0p645 (2015-04-13 revision 50299)] + +```ZeroDivisionError``` is raised. + +#### mruby [1.3.0 (2017-7-4)] + +No exception is raised. + +## Check of infinite recursion + +mruby does not check infinite recursion across C extensions. + +```ruby +def test; eval 'test'; end; test +``` + +#### Ruby [ruby 2.0.0p645 (2015-04-13 revision 50299)] + +```SystemStackError``` is raised. + +#### mruby [1.3.0 (2017-7-4)] + +Segmentation fault. + +## Fiber execution can't cross C function boundary + +mruby's ```Fiber``` is implemented in a similar way to Lua's co-routine. This +results in the consequence that you can't switch context within C functions. +Only exception is ```mrb_fiber_yield``` at return. + +## ```Array``` does not support instance variables + +To reduce memory consumption ```Array``` does not support instance variables. + +```ruby +class Liste < Array + def initialize(str = nil) + @feld = str + end +end + +p Liste.new "foobar" +``` + +#### Ruby [ruby 2.0.0p645 (2015-04-13 revision 50299)] + +``` [] ``` + +#### mruby [1.3.0 (2017-7-4)] + +```ArgumentError``` is raised. + +## Method visibility + +For simplicity reasons no method visibility (public/private/protected) is +supported. + +```ruby +class VisibleTest + + def public_method; end + + private + def private_method; end + +end + +p VisibleTest.new.respond_to?(:private_method, false) +p VisibleTest.new.respond_to?(:private_method, true) +``` + +#### Ruby [ruby 2.0.0p645 (2015-04-13 revision 50299)] + +``` +false +true +``` + +#### mruby [1.3.0 (2017-7-4)] + +``` +true +true +``` + +## defined? + +The ```defined?``` keyword is considered too complex to be fully +implemented. It is recommended to use ```const_defined?``` and +other reflection methods instead. + +```ruby +defined?(Foo) +``` + +#### Ruby [ruby 2.0.0p645 (2015-04-13 revision 50299)] + +``` +nil +``` + +#### mruby [1.3.0 (2017-7-4)] + +```NameError``` is raised. + +## ```alias``` on global variables + +Aliasing a global variable works in CRuby but is not part +of the ISO standard. + +```ruby +alias $a $__a__ +``` + +#### Ruby [ruby 2.0.0p645 (2015-04-13 revision 50299)] + +``` nil ``` + +#### mruby [1.3.0 (2017-7-4)] + +Syntax error + +## Operator modification + +An operator can't be overwritten by the user. + +```ruby +class String + def + + end +end + +'a' + 'b' +``` + +#### Ruby [ruby 2.0.0p645 (2015-04-13 revision 50299)] + +```ArgumentError``` is raised. +The re-defined ```+``` operator does not accept any arguments. + +#### mruby [1.3.0 (2017-7-4)] + +``` 'ab' ``` +Behavior of the operator wasn't changed. + +## ```Kernel.binding``` missing + +```Kernel.binding``` is not implemented as it is not in the +ISO standard. diff --git a/web/server/h2o/libh2o/deps/mruby/examples/mrbgems/c_and_ruby_extension_example/README.md b/web/server/h2o/libh2o/deps/mruby/examples/mrbgems/c_and_ruby_extension_example/README.md new file mode 100644 index 00000000..0b428b0b --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/examples/mrbgems/c_and_ruby_extension_example/README.md @@ -0,0 +1,4 @@ +C and Ruby Extension Example +========= + +This is an example gem which implements a C and Ruby extension. diff --git a/web/server/h2o/libh2o/deps/mruby/examples/mrbgems/c_and_ruby_extension_example/mrbgem.rake b/web/server/h2o/libh2o/deps/mruby/examples/mrbgems/c_and_ruby_extension_example/mrbgem.rake new file mode 100644 index 00000000..6b4595b3 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/examples/mrbgems/c_and_ruby_extension_example/mrbgem.rake @@ -0,0 +1,23 @@ +MRuby::Gem::Specification.new('c_and_ruby_extension_example') do |spec| + spec.license = 'MIT' + spec.author = 'mruby developers' + + # Add compile flags + # spec.cc.flags << '' + + # Add cflags to all + # spec.mruby.cc.flags << '-g' + + # Add libraries + # spec.linker.libraries << 'external_lib' + + # Default build files + # spec.rbfiles = Dir.glob("#{dir}/mrblib/*.rb") + # spec.objs = Dir.glob("#{dir}/src/*.{c,cpp,m,asm,S}").map { |f| objfile(f.relative_path_from(dir).pathmap("#{build_dir}/%X")) } + # spec.test_rbfiles = Dir.glob("#{dir}/test/*.rb") + # spec.test_objs = Dir.glob("#{dir}/test/*.{c,cpp,m,asm,S}").map { |f| objfile(f.relative_path_from(dir).pathmap("#{build_dir}/%X")) } + # spec.test_preload = 'test/assert.rb' + + # Values accessible as TEST_ARGS inside test scripts + # spec.test_args = {'tmp_dir' => Dir::tmpdir} +end diff --git a/web/server/h2o/libh2o/deps/mruby/examples/mrbgems/c_and_ruby_extension_example/mrblib/example.rb b/web/server/h2o/libh2o/deps/mruby/examples/mrbgems/c_and_ruby_extension_example/mrblib/example.rb new file mode 100644 index 00000000..d3899c30 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/examples/mrbgems/c_and_ruby_extension_example/mrblib/example.rb @@ -0,0 +1,5 @@ +module CRubyExtension + def CRubyExtension.ruby_method + puts "A Ruby Extension" + end +end diff --git a/web/server/h2o/libh2o/deps/mruby/examples/mrbgems/c_and_ruby_extension_example/src/example.c b/web/server/h2o/libh2o/deps/mruby/examples/mrbgems/c_and_ruby_extension_example/src/example.c new file mode 100644 index 00000000..7b780d01 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/examples/mrbgems/c_and_ruby_extension_example/src/example.c @@ -0,0 +1,20 @@ +#include +#include + +static mrb_value +mrb_c_method(mrb_state *mrb, mrb_value self) +{ + puts("A C Extension"); + return self; +} + +void +mrb_c_and_ruby_extension_example_gem_init(mrb_state* mrb) { + struct RClass *class_cextension = mrb_define_module(mrb, "CRubyExtension"); + mrb_define_class_method(mrb, class_cextension, "c_method", mrb_c_method, MRB_ARGS_NONE()); +} + +void +mrb_c_and_ruby_extension_example_gem_final(mrb_state* mrb) { + /* finalizer */ +} diff --git a/web/server/h2o/libh2o/deps/mruby/examples/mrbgems/c_and_ruby_extension_example/test/example.rb b/web/server/h2o/libh2o/deps/mruby/examples/mrbgems/c_and_ruby_extension_example/test/example.rb new file mode 100644 index 00000000..fffad710 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/examples/mrbgems/c_and_ruby_extension_example/test/example.rb @@ -0,0 +1,7 @@ +assert('C and Ruby Extension Example 1') do + CRubyExtension.respond_to? :c_method +end + +assert('C and Ruby Extension Example 2') do + CRubyExtension.respond_to? :ruby_method +end diff --git a/web/server/h2o/libh2o/deps/mruby/examples/mrbgems/c_extension_example/README.md b/web/server/h2o/libh2o/deps/mruby/examples/mrbgems/c_extension_example/README.md new file mode 100644 index 00000000..3803c206 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/examples/mrbgems/c_extension_example/README.md @@ -0,0 +1,4 @@ +C Extension Example +========= + +This is an example gem which implements a C extension. diff --git a/web/server/h2o/libh2o/deps/mruby/examples/mrbgems/c_extension_example/mrbgem.rake b/web/server/h2o/libh2o/deps/mruby/examples/mrbgems/c_extension_example/mrbgem.rake new file mode 100644 index 00000000..6e4c5b16 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/examples/mrbgems/c_extension_example/mrbgem.rake @@ -0,0 +1,23 @@ +MRuby::Gem::Specification.new('c_extension_example') do |spec| + spec.license = 'MIT' + spec.author = 'mruby developers' + + # Add compile flags + # spec.cc.flags << '-g' + + # Add cflags to all + # spec.mruby.cc.flags << '-g' + + # Add libraries + # spec.linker.libraries << 'external_lib' + + # Default build files + # spec.rbfiles = Dir.glob("#{dir}/mrblib/*.rb") + # spec.objs = Dir.glob("#{dir}/src/*.{c,cpp,m,asm,S}").map { |f| objfile(f.relative_path_from(dir).pathmap("#{build_dir}/%X")) } + # spec.test_rbfiles = Dir.glob("#{dir}/test/*.rb") + # spec.test_objs = Dir.glob("#{dir}/test/*.{c,cpp,m,asm,S}").map { |f| objfile(f.relative_path_from(dir).pathmap("#{build_dir}/%X")) } + # spec.test_preload = 'test/assert.rb' + + # Values accessible as TEST_ARGS inside test scripts + # spec.test_args = {'tmp_dir' => Dir::tmpdir} +end diff --git a/web/server/h2o/libh2o/deps/mruby/examples/mrbgems/c_extension_example/src/example.c b/web/server/h2o/libh2o/deps/mruby/examples/mrbgems/c_extension_example/src/example.c new file mode 100644 index 00000000..e70ee42f --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/examples/mrbgems/c_extension_example/src/example.c @@ -0,0 +1,20 @@ +#include +#include + +static mrb_value +mrb_c_method(mrb_state *mrb, mrb_value self) +{ + puts("A C Extension"); + return self; +} + +void +mrb_c_extension_example_gem_init(mrb_state* mrb) { + struct RClass *class_cextension = mrb_define_module(mrb, "CExtension"); + mrb_define_class_method(mrb, class_cextension, "c_method", mrb_c_method, MRB_ARGS_NONE()); +} + +void +mrb_c_extension_example_gem_final(mrb_state* mrb) { + /* finalizer */ +} diff --git a/web/server/h2o/libh2o/deps/mruby/examples/mrbgems/c_extension_example/test/example.c b/web/server/h2o/libh2o/deps/mruby/examples/mrbgems/c_extension_example/test/example.c new file mode 100644 index 00000000..ab410333 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/examples/mrbgems/c_extension_example/test/example.c @@ -0,0 +1,7 @@ +#include + +void +mrb_c_extension_example_gem_test(mrb_state *mrb) +{ + /* test initializer in C */ +} diff --git a/web/server/h2o/libh2o/deps/mruby/examples/mrbgems/c_extension_example/test/example.rb b/web/server/h2o/libh2o/deps/mruby/examples/mrbgems/c_extension_example/test/example.rb new file mode 100644 index 00000000..367d1802 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/examples/mrbgems/c_extension_example/test/example.rb @@ -0,0 +1,3 @@ +assert('C Extension Example') do + CExtension.respond_to? :c_method +end diff --git a/web/server/h2o/libh2o/deps/mruby/examples/mrbgems/ruby_extension_example/README.md b/web/server/h2o/libh2o/deps/mruby/examples/mrbgems/ruby_extension_example/README.md new file mode 100644 index 00000000..906a0d8f --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/examples/mrbgems/ruby_extension_example/README.md @@ -0,0 +1,4 @@ +Pure Ruby Extension Example +========= + +This is an example gem which implements a pure Ruby extension. diff --git a/web/server/h2o/libh2o/deps/mruby/examples/mrbgems/ruby_extension_example/mrbgem.rake b/web/server/h2o/libh2o/deps/mruby/examples/mrbgems/ruby_extension_example/mrbgem.rake new file mode 100644 index 00000000..6e5a5b72 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/examples/mrbgems/ruby_extension_example/mrbgem.rake @@ -0,0 +1,25 @@ +MRuby::Gem::Specification.new('ruby_extension_example') do |spec| + spec.license = 'MIT' + spec.author = 'mruby developers' + + # Add compile flags + # spec.cc.flags << '' + + # Add cflags to all + # spec.mruby.cc.flags << '-g' + + # Add libraries + # spec.linker.libraries << 'external_lib' + + spec.add_dependency('mruby-print', :core => 'mruby-print') + + # Default build files + # spec.rbfiles = Dir.glob("#{dir}/mrblib/*.rb") + # spec.objs = Dir.glob("#{dir}/src/*.{c,cpp,m,asm,S}").map { |f| objfile(f.relative_path_from(dir).pathmap("#{build_dir}/%X")) } + # spec.test_rbfiles = Dir.glob("#{dir}/test/*.rb") + # spec.test_objs = Dir.glob("#{dir}/test/*.{c,cpp,m,asm,S}").map { |f| objfile(f.relative_path_from(dir).pathmap("#{build_dir}/%X")) } + # spec.test_preload = 'test/assert.rb' + + # Values accessible as TEST_ARGS inside test scripts + # spec.test_args = {'tmp_dir' => Dir::tmpdir} +end diff --git a/web/server/h2o/libh2o/deps/mruby/examples/mrbgems/ruby_extension_example/mrblib/example.rb b/web/server/h2o/libh2o/deps/mruby/examples/mrbgems/ruby_extension_example/mrblib/example.rb new file mode 100644 index 00000000..b07a2b58 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/examples/mrbgems/ruby_extension_example/mrblib/example.rb @@ -0,0 +1,5 @@ +class RubyExtension + def RubyExtension.ruby_method + puts "A Ruby Extension" + end +end diff --git a/web/server/h2o/libh2o/deps/mruby/examples/mrbgems/ruby_extension_example/test/example.rb b/web/server/h2o/libh2o/deps/mruby/examples/mrbgems/ruby_extension_example/test/example.rb new file mode 100644 index 00000000..0c1b6346 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/examples/mrbgems/ruby_extension_example/test/example.rb @@ -0,0 +1,3 @@ +assert('Ruby Extension Example') do + RubyExtension.respond_to? :ruby_method +end diff --git a/web/server/h2o/libh2o/deps/mruby/examples/targets/build_config_ArduinoDue.rb b/web/server/h2o/libh2o/deps/mruby/examples/targets/build_config_ArduinoDue.rb new file mode 100644 index 00000000..527aaa4f --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/examples/targets/build_config_ArduinoDue.rb @@ -0,0 +1,90 @@ +MRuby::Build.new do |conf| + + # Gets set by the VS command prompts. + if ENV['VisualStudioVersion'] || ENV['VSINSTALLDIR'] + toolchain :visualcpp + else + toolchain :gcc + end + + enable_debug + + # include the default GEMs + conf.gembox 'default' + +end + +# Cross Compiling configuration for Arduino Due +# http://arduino.cc/en/Main/ArduinoBoardDue +# +# Requires Arduino IDE >= 1.5 +MRuby::CrossBuild.new("ArduinoDue") do |conf| + toolchain :gcc + + # Mac OS X, Arduino IDE <= 1.5.6 + # ARDUINO_PATH = '/Applications/Arduino.app/Contents/Resources/Java' + # Mac OS X, Arduino IDE >= 1.5.7 + # ARDUINO_PATH = '/Applications/Arduino.app/Contents/Java' + # GNU Linux + ARDUINO_PATH = '/opt/arduino' + # Arduino IDE <= 1.5.6 + BIN_PATH = "#{ARDUINO_PATH}/hardware/tools/g++_arm_none_eabi/bin" + # Arduino IDE >= 1.5.7 + # BIN_PATH = "#{ARDUINO_PATH}/hardware/tools/gcc-arm-none-eabi-4.8.3-2014q1/bin" + SAM_PATH = "#{ARDUINO_PATH}/hardware/arduino/sam" + TARGET_PATH = "#{SAM_PATH}/variants/arduino_due_x" + + conf.cc do |cc| + cc.command = "#{BIN_PATH}/arm-none-eabi-gcc" + cc.include_paths << ["#{SAM_PATH}/system/libsam", "#{SAM_PATH}/system/CMSIS/CMSIS/Include/", + "#{SAM_PATH}/system/CMSIS/Device/ATMEL/", + "#{SAM_PATH}/cores/arduino", "#{SAM_PATH}/libraries","#{TARGET_PATH}"] + cc.flags = %w(-g -Os -w -ffunction-sections -fdata-sections -nostdlib --param max-inline-insns-single=500 + -Dprintf=iprintf -mcpu=cortex-m3 -DF_CPU=84000000L -DARDUINO=156 -DARDUINO_SAM_DUE -DARDUINO_ARCH_SAM + -D__SAM3X8E__ -mthumb -DUSB_PID=0x003e -DUSB_VID=0x2341 -DUSBCON -DUSB_MANUFACTURER="Unknown" -DUSB_PRODUCT="Arduino Due") + cc.compile_options = "%{flags} -o %{outfile} -c %{infile}" + + #configuration for low memory environment + cc.defines << %w(MRB_HEAP_PAGE_SIZE=64) + cc.defines << %w(KHASH_DEFAULT_SIZE=8) + cc.defines << %w(MRB_STR_BUF_MIN_SIZE=20) + cc.defines << %w(MRB_GC_STRESS) + #cc.defines << %w(MRB_DISABLE_STDIO) #if you dont need stdio. + #cc.defines << %w(POOL_PAGE_SIZE=1000) #effective only for use with mruby-eval + end + + conf.cxx do |cxx| + cxx.command = conf.cc.command.dup + cxx.include_paths = conf.cc.include_paths.dup + cxx.flags = conf.cc.flags.dup + cxx.flags << %w(-fno-rtti -fno-exceptions) + cxx.defines = conf.cc.defines.dup + cxx.compile_options = conf.cc.compile_options.dup + end + + conf.archiver do |archiver| + archiver.command = "#{BIN_PATH}/arm-none-eabi-ar" + archiver.archive_options = 'rcs %{outfile} %{objs}' + end + + #no executables + conf.bins = [] + + #do not build executable test + conf.build_mrbtest_lib_only + + #disable C++ exception + conf.disable_cxx_exception + + #gems from core + conf.gem :core => "mruby-print" + conf.gem :core => "mruby-math" + conf.gem :core => "mruby-enum-ext" + + #light-weight regular expression + conf.gem :github => "masamitsu-murase/mruby-hs-regexp", :branch => "master" + + #Arduino API + #conf.gem :github =>"kyab/mruby-arduino", :branch => "master" + +end diff --git a/web/server/h2o/libh2o/deps/mruby/examples/targets/build_config_IntelEdison.rb b/web/server/h2o/libh2o/deps/mruby/examples/targets/build_config_IntelEdison.rb new file mode 100644 index 00000000..8fa3aa0c --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/examples/targets/build_config_IntelEdison.rb @@ -0,0 +1,69 @@ +# Cross-compiling setup for Intel Edison (poky linux) platform +# Get SDK from here: https://software.intel.com/en-us/iot/hardware/edison/downloads +# REMEMBER to check and update the SDK root in the constant POKY_EDISON_PATH + +MRuby::Build.new do |conf| + toolchain :gcc + conf.gembox 'default' + conf.cc.defines = %w(ENABLE_READLINE) + conf.gembox 'default' + + #lightweight regular expression + conf.gem :github => "pbosetti/mruby-hs-regexp", :branch => "master" + +end + +# Define cross build settings +MRuby::CrossBuild.new('core2-32-poky-linux') do |conf| + toolchain :gcc + + # Mac OS X + # + POKY_EDISON_PATH = '/opt/poky-edison/1.7.2' + + POKY_EDISON_SYSROOT = "#{POKY_EDISON_PATH}/sysroots/core2-32-poky-linux" + POKY_EDISON_X86_PATH = "#{POKY_EDISON_PATH}/sysroots/i386-pokysdk-darwin" + POKY_EDISON_BIN_PATH = "#{POKY_EDISON_X86_PATH}/usr/bin/i586-poky-linux" + + + conf.cc do |cc| + cc.command = "#{POKY_EDISON_BIN_PATH}/i586-poky-linux-gcc" + cc.include_paths << ["#{POKY_EDISON_SYSROOT}/usr/include", "#{POKY_EDISON_X86_PATH}/usr/include"] + cc.flags = %w(-m32 -march=core2 -mtune=core2 -msse3 -mfpmath=sse -mstackrealign -fno-omit-frame-pointer) + cc.flags << %w(-O2 -pipe -g -feliminate-unused-debug-types) + cc.flags << "--sysroot=#{POKY_EDISON_SYSROOT}" + cc.compile_options = "%{flags} -o %{outfile} -c %{infile}" + cc.defines = %w(ENABLE_READLINE) + end + + conf.cxx do |cxx| + cxx.command = "#{POKY_EDISON_BIN_PATH}/i586-poky-linux-g++" + cxx.include_paths = conf.cc.include_paths.dup + cxx.include_paths << ["#{POKY_EDISON_SYSROOT}/usr/include/c++/4.9.1"] + cxx.flags = conf.cc.flags.dup + cxx.defines = conf.cc.defines.dup + cxx.compile_options = conf.cc.compile_options.dup + end + + conf.archiver do |archiver| + archiver.command = "#{POKY_EDISON_BIN_PATH}/i586-poky-linux-ar" + archiver.archive_options = 'rcs %{outfile} %{objs}' + end + + conf.linker do |linker| + linker.command = "#{POKY_EDISON_BIN_PATH}/i586-poky-linux-g++" + linker.flags = %w(-m32 -march=i586) + linker.flags << "--sysroot=#{POKY_EDISON_SYSROOT}" + linker.flags << %w(-O1) + linker.libraries = %w(m pthread) + end + + #do not build executable test + conf.build_mrbtest_lib_only + + conf.gembox 'default' + + #lightweight regular expression + conf.gem :github => "pbosetti/mruby-hs-regexp", :branch => "master" + +end diff --git a/web/server/h2o/libh2o/deps/mruby/examples/targets/build_config_IntelGalileo.rb b/web/server/h2o/libh2o/deps/mruby/examples/targets/build_config_IntelGalileo.rb new file mode 100644 index 00000000..42f800d9 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/examples/targets/build_config_IntelGalileo.rb @@ -0,0 +1,106 @@ +MRuby::Build.new do |conf| + + # Gets set by the VS command prompts. + if ENV['VisualStudioVersion'] || ENV['VSINSTALLDIR'] + toolchain :visualcpp + else + toolchain :gcc + end + + enable_debug + + # include the default GEMs + conf.gembox 'default' + +end + + +# Cross Compiling configuration for Intel Galileo on Arduino environment +# http://arduino.cc/en/ArduinoCertified/IntelGalileo +# +# Requires Arduino IDE for Intel Galileo +MRuby::CrossBuild.new("Galileo") do |conf| + toolchain :gcc + + # Mac OS X + # Assume you renamed Arduino.app to Arduino_Galileo.app + GALILEO_ARDUINO_PATH = '/Applications/Arduino_Galileo.app/Contents/Resources/Java' + # GNU Linux + #ARDUINO_GALILEO_PATH = '/opt/arduino' + + GALILEO_BIN_PATH = "#{GALILEO_ARDUINO_PATH}/hardware/tools/x86/i386-pokysdk-darwin/usr/bin/i586-poky-linux-uclibc" + GALILEO_SYSROOT = "#{GALILEO_ARDUINO_PATH}/hardware/tools/x86/i586-poky-linux-uclibc" + GALILEO_X86_PATH = "#{GALILEO_ARDUINO_PATH}/hardware/arduino/x86" + + + conf.cc do |cc| + cc.command = "#{GALILEO_BIN_PATH}/i586-poky-linux-uclibc-gcc" + cc.include_paths << ["#{GALILEO_X86_PATH}/cores/arduino", "#{GALILEO_X86_PATH}/variants/galileo_fab_d"] + cc.flags = %w(-m32 -march=i586 -c -g -Os -w + -ffunction-sections -fdata-sections -MMD -DARDUINO=153) + cc.flags << "--sysroot=#{GALILEO_SYSROOT}" + cc.compile_options = "%{flags} -o %{outfile} -c %{infile}" + end + + conf.cxx do |cxx| + cxx.command = "#{GALILEO_BIN_PATH}/i586-poky-linux-uclibc-g++" + cxx.include_paths = conf.cc.include_paths.dup + cxx.include_paths << "#{GALILEO_ARDUINO_PATH}/hardware/tools/x86/i586-poky-linux-uclibc/usr/include/c++" + cxx.include_paths << "#{GALILEO_ARDUINO_PATH}/hardware/tools/x86/i586-poky-linux-uclibc/usr/include/c++/i586-poky-linux-uclibc" + cxx.flags = conf.cc.flags.dup + cxx.defines = conf.cc.defines.dup + cxx.compile_options = conf.cc.compile_options.dup + end + + conf.archiver do |archiver| + archiver.command = "#{GALILEO_BIN_PATH}/i586-poky-linux-uclibc-ar" + archiver.archive_options = 'rcs %{outfile} %{objs}' + end + + conf.linker do |linker| + linker.command = "#{GALILEO_BIN_PATH}/i586-poky-linux-uclibc-g++" + linker.flags = %w(-m32 -march=i586) + linker.flags << "--sysroot=#{GALILEO_SYSROOT}" + linker.flags << %w(-Os -Wl,--gc-sections) + linker.libraries = %w(m pthread) + end + + #no executables + conf.bins = [] + + #do not build executable test + conf.build_mrbtest_lib_only + + #official mrbgems + conf.gem :core => "mruby-sprintf" + conf.gem :core => "mruby-print" + conf.gem :core => "mruby-math" + conf.gem :core => "mruby-time" + conf.gem :core => "mruby-struct" + conf.gem :core => "mruby-enum-ext" + conf.gem :core => "mruby-string-ext" + conf.gem :core => "mruby-numeric-ext" + conf.gem :core => "mruby-array-ext" + conf.gem :core => "mruby-hash-ext" + conf.gem :core => "mruby-range-ext" + conf.gem :core => "mruby-proc-ext" + conf.gem :core => "mruby-symbol-ext" + conf.gem :core => "mruby-random" + conf.gem :core => "mruby-object-ext" + conf.gem :core => "mruby-objectspace" + conf.gem :core => "mruby-fiber" + conf.gem :core => "mruby-toplevel-ext" + + #lightweigh regular expression + conf.gem :github => "masamitsu-murase/mruby-hs-regexp", :branch => "master" + + #Arduino API + #conf.gem :github =>"kyab/mruby-arduino", :branch => "master" do |g| + # g.cxx.include_paths << "#{GALILEO_X86_PATH}/libraries/Wire" + # g.cxx.include_paths << "#{GALILEO_X86_PATH}/libraries/Servo" + + #enable unsupported Servo class + # g.cxx.defines << "MRUBY_ARDUINO_GALILEO_ENABLE_SERVO" + #end + +end diff --git a/web/server/h2o/libh2o/deps/mruby/examples/targets/build_config_RX630.rb b/web/server/h2o/libh2o/deps/mruby/examples/targets/build_config_RX630.rb new file mode 100644 index 00000000..fd17eae9 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/examples/targets/build_config_RX630.rb @@ -0,0 +1,81 @@ +MRuby::Build.new do |conf| + + # Gets set by the VS command prompts. + if ENV['VisualStudioVersion'] || ENV['VSINSTALLDIR'] + toolchain :visualcpp + else + toolchain :gcc + end + + enable_debug + + # include the default GEMs + conf.gembox 'default' + +end + +# Cross Compiling configuration for RX630 +# http://gadget.renesas.com/ +# +# Requires gnurx_v14.03 +MRuby::CrossBuild.new("RX630") do |conf| + toolchain :gcc + + # Linux + BIN_PATH = "/usr/share/gnurx_v14.03_elf-1/bin" + + conf.cc do |cc| + cc.command = "#{BIN_PATH}/rx-elf-gcc" + cc.flags = "-Wall -g -O2 -flto -mcpu=rx600 -m64bit-doubles" + cc.compile_options = "%{flags} -o %{outfile} -c %{infile}" + + #configuration for low memory environment + cc.defines << %w(MRB_USE_FLOAT) + cc.defines << %w(MRB_HEAP_PAGE_SIZE=64) + cc.defines << %w(KHASH_DEFAULT_SIZE=8) + cc.defines << %w(MRB_STR_BUF_MIN_SIZE=20) + cc.defines << %w(MRB_GC_STRESS) + cc.defines << %w(MRB_DISABLE_STDIO) #if you dont need stdio. + #cc.defines << %w(POOL_PAGE_SIZE=1000) #effective only for use with mruby-eval + end + + conf.cxx do |cxx| + cxx.command = conf.cc.command.dup + cxx.include_paths = conf.cc.include_paths.dup + cxx.flags = conf.cc.flags.dup + cxx.defines = conf.cc.defines.dup + cxx.compile_options = conf.cc.compile_options.dup + end + + conf.linker do |linker| + linker.command="#{BIN_PATH}/rx-elf-ld" + end + + conf.archiver do |archiver| + archiver.command = "#{BIN_PATH}/rx-elf-ar" + archiver.archive_options = 'rcs %{outfile} %{objs}' + end + + #no executables + conf.bins = [] + + #do not build executable test + conf.build_mrbtest_lib_only + + #disable C++ exception + conf.disable_cxx_exception + + #gems from core + conf.gem :core => "mruby-sprintf" + conf.gem :core => "mruby-print" + conf.gem :core => "mruby-math" + conf.gem :core => "mruby-enum-ext" + conf.gem :core => "mruby-numeric-ext" + + #light-weight regular expression + #conf.gem :github => "masamitsu-murase/mruby-hs-regexp", :branch => "master" + + #Arduino API + #conf.gem :github =>"kyab/mruby-arduino", :branch => "master" + +end diff --git a/web/server/h2o/libh2o/deps/mruby/examples/targets/build_config_android_arm64-v8a.rb b/web/server/h2o/libh2o/deps/mruby/examples/targets/build_config_android_arm64-v8a.rb new file mode 100644 index 00000000..6188c13e --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/examples/targets/build_config_android_arm64-v8a.rb @@ -0,0 +1,26 @@ +MRuby::Build.new do |conf| + + # Gets set by the VS command prompts. + if ENV['VisualStudioVersion'] || ENV['VSINSTALLDIR'] + toolchain :visualcpp + else + toolchain :gcc + end + + enable_debug + + # include the default GEMs + conf.gembox 'default' +end + +# Requires Android NDK r13 or later. +MRuby::CrossBuild.new('android-arm64-v8a') do |conf| + params = { + :arch => 'arm64-v8a', + :platform => 'android-24', + :toolchain => :clang, + } + toolchain :android, params + + conf.gembox 'default' +end diff --git a/web/server/h2o/libh2o/deps/mruby/examples/targets/build_config_android_armeabi.rb b/web/server/h2o/libh2o/deps/mruby/examples/targets/build_config_android_armeabi.rb new file mode 100644 index 00000000..b7eb33a9 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/examples/targets/build_config_android_armeabi.rb @@ -0,0 +1,26 @@ +MRuby::Build.new do |conf| + + # Gets set by the VS command prompts. + if ENV['VisualStudioVersion'] || ENV['VSINSTALLDIR'] + toolchain :visualcpp + else + toolchain :gcc + end + + enable_debug + + # include the default GEMs + conf.gembox 'default' +end + +# Requires Android NDK r13 or later. +MRuby::CrossBuild.new('android-armeabi') do |conf| + params = { + :arch => 'armeabi', + :platform => 'android-24', + :toolchain => :clang, + } + toolchain :android, params + + conf.gembox 'default' +end diff --git a/web/server/h2o/libh2o/deps/mruby/examples/targets/build_config_android_armeabi_v7a_neon_hard.rb b/web/server/h2o/libh2o/deps/mruby/examples/targets/build_config_android_armeabi_v7a_neon_hard.rb new file mode 100644 index 00000000..3788bba7 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/examples/targets/build_config_android_armeabi_v7a_neon_hard.rb @@ -0,0 +1,28 @@ +MRuby::Build.new do |conf| + + # Gets set by the VS command prompts. + if ENV['VisualStudioVersion'] || ENV['VSINSTALLDIR'] + toolchain :visualcpp + else + toolchain :gcc + end + + enable_debug + + # include the default GEMs + conf.gembox 'default' +end + +# Requires Android NDK r13 or later. +MRuby::CrossBuild.new('android-armeabi-v7a-neon-hard') do |conf| + params = { + :arch => 'armeabi-v7a', + :mfpu => 'neon', + :mfloat_abi => 'hard', + :platform => 'android-24', + :toolchain => :clang, + } + toolchain :android, params + + conf.gembox 'default' +end diff --git a/web/server/h2o/libh2o/deps/mruby/examples/targets/build_config_chipKITMax32.rb b/web/server/h2o/libh2o/deps/mruby/examples/targets/build_config_chipKITMax32.rb new file mode 100644 index 00000000..951f7148 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/examples/targets/build_config_chipKITMax32.rb @@ -0,0 +1,86 @@ +MRuby::Build.new do |conf| + + # Gets set by the VS command prompts. + if ENV['VisualStudioVersion'] || ENV['VSINSTALLDIR'] + toolchain :visualcpp + else + toolchain :gcc + end + + enable_debug + + # include the default GEMs + conf.gembox 'default' + +end + +# Cross Compiling configuration for Digilent chipKIT Max32 +# http://www.digilentinc.com/Products/Detail.cfm?Prod=CHIPKIT-MAX32 +# +# Requires MPIDE (https://github.com/chipKIT32/chipKIT32-MAX) +# +# This configuration is based on @kyab's version +# http://d.hatena.ne.jp/kyab/20130201 +MRuby::CrossBuild.new("chipKITMax32") do |conf| + toolchain :gcc + + # Mac OS X + # MPIDE_PATH = '/Applications/Mpide.app/Contents/Resources/Java' + # GNU Linux + MPIDE_PATH = '/opt/mpide-0023-linux-20120903' + + PIC32_PATH = "#{MPIDE_PATH}/hardware/pic32" + + conf.cc do |cc| + cc.command = "#{PIC32_PATH}/compiler/pic32-tools/bin/pic32-gcc" + cc.include_paths << ["#{PIC32_PATH}/cores/pic32", + "#{PIC32_PATH}/variants/Max32", + "#{PIC32_PATH}/libraries"] + cc.flags = %w(-O2 -mno-smart-io -w -ffunction-sections -fdata-sections -g -mdebugger -Wcast-align + -fno-short-double -mprocessor=32MX795F512L -DF_CPU=80000000L -DARDUINO=23 -D_BOARD_MEGA_ + -DMPIDEVER=0x01000202 -DMPIDE=23) + cc.compile_options = "%{flags} -o %{outfile} -c %{infile}" + + #configuration for low memory environment + cc.defines << %w(MRB_HEAP_PAGE_SIZE=64) + cc.defines << %w(KHASH_DEFAULT_SIZE=8) + cc.defines << %w(MRB_STR_BUF_MIN_SIZE=20) + cc.defines << %w(MRB_GC_STRESS) + #cc.defines << %w(MRB_DISABLE_STDIO) #if you dont need stdio. + #cc.defines << %w(POOL_PAGE_SIZE=1000) #effective only for use with mruby-eval + end + + conf.cxx do |cxx| + cxx.command = conf.cc.command.dup + cxx.include_paths = conf.cc.include_paths.dup + cxx.flags = conf.cc.flags.dup + cxx.defines = conf.cc.defines.dup + cxx.compile_options = conf.cc.compile_options.dup + end + + conf.archiver do |archiver| + archiver.command = "#{PIC32_PATH}/compiler/pic32-tools/bin/pic32-ar" + archiver.archive_options = 'rcs %{outfile} %{objs}' + end + + #no executables + conf.bins = [] + + #do not build test executable + conf.build_mrbtest_lib_only + + #disable C++ exception + conf.disable_cxx_exception + + #gems from core + conf.gem :core => "mruby-print" + conf.gem :core => "mruby-math" + conf.gem :core => "mruby-enum-ext" + + #light-weight regular expression + conf.gem :github => "masamitsu-murase/mruby-hs-regexp", :branch => "master" + + #Arduino API + #conf.gem :github =>"kyab/mruby-arduino", :branch => "master" + +end diff --git a/web/server/h2o/libh2o/deps/mruby/include/mrbconf.h b/web/server/h2o/libh2o/deps/mruby/include/mrbconf.h new file mode 100644 index 00000000..b8d603e1 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/include/mrbconf.h @@ -0,0 +1,130 @@ +/* +** mrbconf.h - mruby core configuration +** +** See Copyright Notice in mruby.h +*/ + +#ifndef MRUBYCONF_H +#define MRUBYCONF_H + +#include +#include + +/* architecture selection: */ +/* specify -DMRB_32BIT or -DMRB_64BIT to override */ +#if !defined(MRB_32BIT) && !defined(MRB_64BIT) +#if UINT64_MAX == SIZE_MAX +#define MRB_64BIT +#else +#define MRB_32BIT +#endif +#endif + +#if defined(MRB_32BIT) && defined(MRB_64BIT) +#error Cannot build for 32 and 64 bit architecture at the same time +#endif + +/* configuration options: */ +/* add -DMRB_USE_FLOAT to use float instead of double for floating point numbers */ +//#define MRB_USE_FLOAT + +/* add -DMRB_INT16 to use 16bit integer for mrb_int; conflict with MRB_INT64 */ +//#define MRB_INT16 + +/* add -DMRB_INT64 to use 64bit integer for mrb_int; conflict with MRB_INT16 */ +//#define MRB_INT64 + +/* if no specific integer type is chosen */ +#if !defined(MRB_INT16) && !defined(MRB_INT32) && !defined(MRB_INT64) +# if defined(MRB_64BIT) && !defined(MRB_NAN_BOXING) +/* Use 64bit integers on 64bit architecture (without MRB_NAN_BOXING) */ +# define MRB_INT64 +# else +/* Otherwise use 32bit integers */ +# define MRB_INT32 +# endif +#endif + +/* represent mrb_value in boxed double; conflict with MRB_USE_FLOAT */ +//#define MRB_NAN_BOXING + +/* define on big endian machines; used by MRB_NAN_BOXING */ +//#define MRB_ENDIAN_BIG + +/* represent mrb_value as a word (natural unit of data for the processor) */ +//#define MRB_WORD_BOXING + +/* string class to handle UTF-8 encoding */ +//#define MRB_UTF8_STRING + +/* argv max size in mrb_funcall */ +//#define MRB_FUNCALL_ARGC_MAX 16 + +/* number of object per heap page */ +//#define MRB_HEAP_PAGE_SIZE 1024 + +/* if _etext and _edata available, mruby can reduce memory used by symbols */ +//#define MRB_USE_ETEXT_EDATA + +/* do not use __init_array_start to determine readonly data section; + effective only when MRB_USE_ETEXT_EDATA is defined */ +//#define MRB_NO_INIT_ARRAY_START + +/* turn off generational GC by default */ +//#define MRB_GC_TURN_OFF_GENERATIONAL + +/* default size of khash table bucket */ +//#define KHASH_DEFAULT_SIZE 32 + +/* allocated memory address alignment */ +//#define POOL_ALIGNMENT 4 + +/* page size of memory pool */ +//#define POOL_PAGE_SIZE 16000 + +/* initial minimum size for string buffer */ +//#define MRB_STR_BUF_MIN_SIZE 128 + +/* arena size */ +//#define MRB_GC_ARENA_SIZE 100 + +/* fixed size GC arena */ +//#define MRB_GC_FIXED_ARENA + +/* state atexit stack size */ +//#define MRB_FIXED_STATE_ATEXIT_STACK_SIZE 5 + +/* fixed size state atexit stack */ +//#define MRB_FIXED_STATE_ATEXIT_STACK + +/* -DMRB_DISABLE_XXXX to drop following features */ +//#define MRB_DISABLE_STDIO /* use of stdio */ + +/* -DMRB_ENABLE_XXXX to enable following features */ +//#define MRB_ENABLE_DEBUG_HOOK /* hooks for debugger */ + +/* end of configuration */ + +/* define MRB_DISABLE_XXXX from DISABLE_XXX (for compatibility) */ +#ifdef DISABLE_STDIO +#define MRB_DISABLE_STDIO +#endif + +/* define MRB_ENABLE_XXXX from ENABLE_XXX (for compatibility) */ +#ifdef ENABLE_DEBUG +#define MRB_ENABLE_DEBUG_HOOK +#endif + +#ifndef MRB_DISABLE_STDIO +# include +#endif + +#ifndef FALSE +# define FALSE 0 +#endif + +#ifndef TRUE +# define TRUE 1 +#endif + +#endif /* MRUBYCONF_H */ diff --git a/web/server/h2o/libh2o/deps/mruby/include/mruby.h b/web/server/h2o/libh2o/deps/mruby/include/mruby.h new file mode 100644 index 00000000..ced9c104 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/include/mruby.h @@ -0,0 +1,1257 @@ +/* +** mruby - An embeddable Ruby implementation +** +** Copyright (c) mruby developers 2010-2017 +** +** Permission is hereby granted, free of charge, to any person obtaining +** a copy of this software and associated documentation files (the +** "Software"), to deal in the Software without restriction, including +** without limitation the rights to use, copy, modify, merge, publish, +** distribute, sublicense, and/or sell copies of the Software, and to +** permit persons to whom the Software is furnished to do so, subject to +** the following conditions: +** +** The above copyright notice and this permission notice shall be +** included in all copies or substantial portions of the Software. +** +** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +** SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +** +** [ MIT license: http://www.opensource.org/licenses/mit-license.php ] +*/ + +#ifndef MRUBY_H +#define MRUBY_H + +#ifdef __cplusplus +#define __STDC_LIMIT_MACROS +#define __STDC_CONSTANT_MACROS +#define __STDC_FORMAT_MACROS +#endif + +#include +#include +#include + +#ifdef __cplusplus +#ifndef SIZE_MAX +#ifdef __SIZE_MAX__ +#define SIZE_MAX __SIZE_MAX__ +#else +#define SIZE_MAX std::numeric_limits::max() +#endif +#endif +#endif + +#ifdef MRB_DEBUG +#include +#define mrb_assert(p) assert(p) +#define mrb_assert_int_fit(t1,n,t2,max) assert((n)>=0 && ((sizeof(n)<=sizeof(t2))||(n<=(t1)(max)))) +#else +#define mrb_assert(p) ((void)0) +#define mrb_assert_int_fit(t1,n,t2,max) ((void)0) +#endif + +#if __STDC_VERSION__ >= 201112L +#define mrb_static_assert(exp, str) _Static_assert(exp, str) +#else +#define mrb_static_assert(exp, str) mrb_assert(exp) +#endif + +#include "mrbconf.h" + +#ifndef FLT_EPSILON +#define FLT_EPSILON (1.19209290e-07f) +#endif +#ifndef DBL_EPSILON +#define DBL_EPSILON ((double)2.22044604925031308085e-16L) +#endif +#ifndef LDBL_EPSILON +#define LDBL_EPSILON (1.08420217248550443401e-19L) +#endif + +#ifdef MRB_USE_FLOAT +#define MRB_FLOAT_EPSILON FLT_EPSILON +#else +#define MRB_FLOAT_EPSILON DBL_EPSILON +#endif + +#include "mruby/common.h" +#include +#include +#include + +/** + * MRuby C API entry point + */ +MRB_BEGIN_DECL + +typedef uint32_t mrb_code; + +/** + * Required arguments signature type. + */ +typedef uint32_t mrb_aspec; + + +struct mrb_irep; +struct mrb_state; + +/** + * Function pointer type of custom allocator used in @see mrb_open_allocf. + * + * The function pointing it must behave similarly as realloc except: + * - If ptr is NULL it must allocate new space. + * - If s is NULL, ptr must be freed. + * + * See @see mrb_default_allocf for the default implementation. + */ +typedef void* (*mrb_allocf) (struct mrb_state *mrb, void*, size_t, void *ud); + +#ifndef MRB_FIXED_STATE_ATEXIT_STACK_SIZE +#define MRB_FIXED_STATE_ATEXIT_STACK_SIZE 5 +#endif + +typedef struct { + mrb_sym mid; + struct RProc *proc; + mrb_value *stackent; + int nregs; + int ridx; + int epos; + struct REnv *env; + mrb_code *pc; /* return address */ + mrb_code *err; /* error position */ + int argc; + int acc; + struct RClass *target_class; +} mrb_callinfo; + +enum mrb_fiber_state { + MRB_FIBER_CREATED = 0, + MRB_FIBER_RUNNING, + MRB_FIBER_RESUMED, + MRB_FIBER_SUSPENDED, + MRB_FIBER_TRANSFERRED, + MRB_FIBER_TERMINATED, +}; + +struct mrb_context { + struct mrb_context *prev; + + mrb_value *stack; /* stack of virtual machine */ + mrb_value *stbase, *stend; + + mrb_callinfo *ci; + mrb_callinfo *cibase, *ciend; + + mrb_code **rescue; /* exception handler stack */ + int rsize; + struct RProc **ensure; /* ensure handler stack */ + int esize, eidx; + + enum mrb_fiber_state status; + mrb_bool vmexec; + struct RFiber *fib; +}; + +#ifdef MRB_METHOD_CACHE_SIZE +# define MRB_METHOD_CACHE +#else +/* default method cache size: 128 */ +/* cache size needs to be power of 2 */ +# define MRB_METHOD_CACHE_SIZE (1<<7) +#endif + +#ifdef MRB_METHOD_CACHE +struct mrb_cache_entry { + struct RClass *c; + mrb_sym mid; + struct RProc *m; +}; +#endif + +struct mrb_jmpbuf; + +typedef void (*mrb_atexit_func)(struct mrb_state*); + +#define MRB_STATE_NO_REGEXP 1 +#define MRB_STATE_REGEXP 2 + +typedef struct mrb_state { + struct mrb_jmpbuf *jmp; + + uint32_t flags; + mrb_allocf allocf; /* memory allocation function */ + void *allocf_ud; /* auxiliary data of allocf */ + + struct mrb_context *c; + struct mrb_context *root_c; + struct iv_tbl *globals; /* global variable table */ + + struct RObject *exc; /* exception */ + + struct RObject *top_self; + struct RClass *object_class; /* Object class */ + struct RClass *class_class; + struct RClass *module_class; + struct RClass *proc_class; + struct RClass *string_class; + struct RClass *array_class; + struct RClass *hash_class; + struct RClass *range_class; + + struct RClass *float_class; + struct RClass *fixnum_class; + struct RClass *true_class; + struct RClass *false_class; + struct RClass *nil_class; + struct RClass *symbol_class; + struct RClass *kernel_module; + + struct alloca_header *mems; + mrb_gc gc; + +#ifdef MRB_METHOD_CACHE + struct mrb_cache_entry cache[MRB_METHOD_CACHE_SIZE]; +#endif + + mrb_sym symidx; + struct kh_n2s *name2sym; /* symbol hash */ + struct symbol_name *symtbl; /* symbol table */ + size_t symcapa; + +#ifdef MRB_ENABLE_DEBUG_HOOK + void (*code_fetch_hook)(struct mrb_state* mrb, struct mrb_irep *irep, mrb_code *pc, mrb_value *regs); + void (*debug_op_hook)(struct mrb_state* mrb, struct mrb_irep *irep, mrb_code *pc, mrb_value *regs); +#endif + +#ifdef MRB_BYTECODE_DECODE_OPTION + mrb_code (*bytecode_decoder)(struct mrb_state* mrb, mrb_code code); +#endif + + struct RClass *eException_class; + struct RClass *eStandardError_class; + struct RObject *nomem_err; /* pre-allocated NoMemoryError */ + struct RObject *stack_err; /* pre-allocated SysStackError */ +#ifdef MRB_GC_FIXED_ARENA + struct RObject *arena_err; /* pre-allocated arena overfow error */ +#endif + + void *ud; /* auxiliary data */ + +#ifdef MRB_FIXED_STATE_ATEXIT_STACK + mrb_atexit_func atexit_stack[MRB_FIXED_STATE_ATEXIT_STACK_SIZE]; +#else + mrb_atexit_func *atexit_stack; +#endif + mrb_int atexit_stack_len; +} mrb_state; + + +typedef mrb_value (*mrb_func_t)(mrb_state *mrb, mrb_value); + +/** + * Defines a new class. + * + * If you're creating a gem it may look something like this: + * + * !!!c + * void mrb_example_gem_init(mrb_state* mrb) { + * struct RClass *example_class; + * example_class = mrb_define_class(mrb, "Example_Class", mrb->object_class); + * } + * + * void mrb_example_gem_final(mrb_state* mrb) { + * //free(TheAnimals); + * } + * + * @param [mrb_state *] mrb The current mruby state. + * @param [const char *] name The name of the defined class. + * @param [struct RClass *] super The new class parent. + * @return [struct RClass *] Reference to the newly defined class. + * @see mrb_define_class_under + */ +MRB_API struct RClass *mrb_define_class(mrb_state *mrb, const char *name, struct RClass *super); + +/** + * Defines a new module. + * + * @param [mrb_state *] mrb_state* The current mruby state. + * @param [const char *] char* The name of the module. + * @return [struct RClass *] Reference to the newly defined module. + */ +MRB_API struct RClass *mrb_define_module(mrb_state *, const char*); +MRB_API mrb_value mrb_singleton_class(mrb_state*, mrb_value); + +/** + * Include a module in another class or module. + * Equivalent to: + * + * module B + * include A + * end + * @param [mrb_state *] mrb_state* The current mruby state. + * @param [struct RClass *] RClass* A reference to module or a class. + * @param [struct RClass *] RClass* A reference to the module to be included. + */ +MRB_API void mrb_include_module(mrb_state*, struct RClass*, struct RClass*); + +/** + * Prepends a module in another class or module. + * + * Equivalent to: + * module B + * prepend A + * end + * @param [mrb_state *] mrb_state* The current mruby state. + * @param [struct RClass *] RClass* A reference to module or a class. + * @param [struct RClass *] RClass* A reference to the module to be prepended. + */ +MRB_API void mrb_prepend_module(mrb_state*, struct RClass*, struct RClass*); + +/** + * Defines a global function in ruby. + * + * If you're creating a gem it may look something like this + * + * Example: + * + * !!!c + * mrb_value example_method(mrb_state* mrb, mrb_value self) + * { + * puts("Executing example command!"); + * return self; + * } + * + * void mrb_example_gem_init(mrb_state* mrb) + * { + * mrb_define_method(mrb, mrb->kernel_module, "example_method", example_method, MRB_ARGS_NONE()); + * } + * + * @param [mrb_state *] mrb The MRuby state reference. + * @param [struct RClass *] cla The class pointer where the method will be defined. + * @param [const char *] name The name of the method being defined. + * @param [mrb_func_t] func The function pointer to the method definition. + * @param [mrb_aspec] aspec The method parameters declaration. + */ +MRB_API void mrb_define_method(mrb_state *mrb, struct RClass *cla, const char *name, mrb_func_t func, mrb_aspec aspec); + +/** + * Defines a class method. + * + * Example: + * + * # Ruby style + * class Foo + * def Foo.bar + * end + * end + * // C style + * mrb_value bar_method(mrb_state* mrb, mrb_value self){ + * return mrb_nil_value(); + * } + * void mrb_example_gem_init(mrb_state* mrb){ + * struct RClass *foo; + * foo = mrb_define_class(mrb, "Foo", mrb->object_class); + * mrb_define_class_method(mrb, foo, "bar", bar_method, MRB_ARGS_NONE()); + * } + * @param [mrb_state *] mrb_state* The MRuby state reference. + * @param [struct RClass *] RClass* The class where the class method will be defined. + * @param [const char *] char* The name of the class method being defined. + * @param [mrb_func_t] mrb_func_t The function pointer to the class method definition. + * @param [mrb_aspec] mrb_aspec The method parameters declaration. + */ +MRB_API void mrb_define_class_method(mrb_state *, struct RClass *, const char *, mrb_func_t, mrb_aspec); +MRB_API void mrb_define_singleton_method(mrb_state*, struct RObject*, const char*, mrb_func_t, mrb_aspec); + +/** + * Defines a module fuction. + * + * Example: + * + * # Ruby style + * module Foo + * def Foo.bar + * end + * end + * // C style + * mrb_value bar_method(mrb_state* mrb, mrb_value self){ + * return mrb_nil_value(); + * } + * void mrb_example_gem_init(mrb_state* mrb){ + * struct RClass *foo; + * foo = mrb_define_module(mrb, "Foo"); + * mrb_define_module_function(mrb, foo, "bar", bar_method, MRB_ARGS_NONE()); + * } + * @param [mrb_state *] mrb_state* The MRuby state reference. + * @param [struct RClass *] RClass* The module where the module function will be defined. + * @param [const char *] char* The name of the module function being defined. + * @param [mrb_func_t] mrb_func_t The function pointer to the module function definition. + * @param [mrb_aspec] mrb_aspec The method parameters declaration. + */ +MRB_API void mrb_define_module_function(mrb_state*, struct RClass*, const char*, mrb_func_t, mrb_aspec); + +/** + * Defines a constant. + * + * Example: + * + * # Ruby style + * class ExampleClass + * AGE = 22 + * end + * // C style + * #include + * #include + * + * void + * mrb_example_gem_init(mrb_state* mrb){ + * mrb_define_const(mrb, mrb->kernel_module, "AGE", mrb_fixnum_value(22)); + * } + * + * mrb_value + * mrb_example_gem_final(mrb_state* mrb){ + * } + * @param [mrb_state *] mrb_state* The MRuby state reference. + * @param [struct RClass *] RClass* A class or module the constant is defined in. + * @param [const char *] name The name of the constant being defined. + * @param [mrb_value] mrb_value The value for the constant. + */ +MRB_API void mrb_define_const(mrb_state*, struct RClass*, const char *name, mrb_value); + +/** + * Undefines a method. + * + * Example: + * + * # Ruby style + * + * class ExampleClassA + * def example_method + * "example" + * end + * end + * ExampleClassA.new.example_method # => example + * + * class ExampleClassB < ExampleClassA + * undef_method :example_method + * end + * + * ExampleClassB.new.example_method # => undefined method 'example_method' for ExampleClassB (NoMethodError) + * + * // C style + * #include + * #include + * + * mrb_value + * mrb_example_method(mrb_state *mrb){ + * return mrb_str_new_lit(mrb, "example"); + * } + * + * void + * mrb_example_gem_init(mrb_state* mrb){ + * struct RClass *example_class_a; + * struct RClass *example_class_b; + * struct RClass *example_class_c; + * + * example_class_a = mrb_define_class(mrb, "ExampleClassA", mrb->object_class); + * mrb_define_method(mrb, example_class_a, "example_method", mrb_example_method, MRB_ARGS_NONE()); + * example_class_b = mrb_define_class(mrb, "ExampleClassB", example_class_a); + * example_class_c = mrb_define_class(mrb, "ExampleClassC", example_class_b); + * mrb_undef_method(mrb, example_class_c, "example_method"); + * } + * + * mrb_example_gem_final(mrb_state* mrb){ + * } + * @param [mrb_state*] mrb_state* The mruby state reference. + * @param [struct RClass*] RClass* A class the method will be undefined from. + * @param [const char*] constchar* The name of the method to be undefined. + */ +MRB_API void mrb_undef_method(mrb_state*, struct RClass*, const char*); + +/** + * Undefine a class method. + * Example: + * + * # Ruby style + * class ExampleClass + * def self.example_method + * "example" + * end + * end + * + * ExampleClass.example_method + * + * // C style + * #include + * #include + * + * mrb_value + * mrb_example_method(mrb_state *mrb){ + * return mrb_str_new_lit(mrb, "example"); + * } + * + * void + * mrb_example_gem_init(mrb_state* mrb){ + * struct RClass *example_class; + * example_class = mrb_define_class(mrb, "ExampleClass", mrb->object_class); + * mrb_define_class_method(mrb, example_class, "example_method", mrb_example_method, MRB_ARGS_NONE()); + * mrb_undef_class_method(mrb, example_class, "example_method"); + * } + * + * void + * mrb_example_gem_final(mrb_state* mrb){ + * } + * @param [mrb_state*] mrb_state* The mruby state reference. + * @param [RClass*] RClass* A class the class method will be undefined from. + * @param [constchar*] constchar* The name of the class method to be undefined. + */ +MRB_API void mrb_undef_class_method(mrb_state*, struct RClass*, const char*); + +/** + * Initialize a new object instace of c class. + * + * Example: + * + * # Ruby style + * class ExampleClass + * end + * + * p ExampleClass # => # + * // C style + * #include + * #include + * + * void + * mrb_example_gem_init(mrb_state* mrb) { + * struct RClass *example_class; + * mrb_value obj; + * example_class = mrb_define_class(mrb, "ExampleClass", mrb->object_class); # => class ExampleClass; end + * obj = mrb_obj_new(mrb, example_class, 0, NULL); # => ExampleClass.new + * mrb_p(mrb, obj); // => Kernel#p + * } + * @param [mrb_state*] mrb The current mruby state. + * @param [RClass*] c Reference to the class of the new object. + * @param [mrb_int] argc Number of arguments in argv + * @param [const mrb_value *] argv Array of mrb_value to initialize the object + * @return [mrb_value] The newly initialized object + */ +MRB_API mrb_value mrb_obj_new(mrb_state *mrb, struct RClass *c, mrb_int argc, const mrb_value *argv); + +/** @see mrb_obj_new */ +MRB_INLINE mrb_value mrb_class_new_instance(mrb_state *mrb, mrb_int argc, const mrb_value *argv, struct RClass *c) +{ + return mrb_obj_new(mrb,c,argc,argv); +} + +MRB_API mrb_value mrb_instance_new(mrb_state *mrb, mrb_value cv); + +/** + * Creates a new instance of Class, Class. + * + * Example: + * + * void + * mrb_example_gem_init(mrb_state* mrb) { + * struct RClass *example_class; + * + * mrb_value obj; + * example_class = mrb_class_new(mrb, mrb->object_class); + * obj = mrb_obj_new(mrb, example_class, 0, NULL); // => #<#:0x9a94588> + * mrb_p(mrb, obj); // => Kernel#p + * } + * + * @param [mrb_state*] mrb The current mruby state. + * @param [struct RClass *] super The super class or parent. + * @return [struct RClass *] Reference to the new class. + */ +MRB_API struct RClass * mrb_class_new(mrb_state *mrb, struct RClass *super); + +/** + * Creates a new module, Module. + * + * Example: + * void + * mrb_example_gem_init(mrb_state* mrb) { + * struct RClass *example_module; + * + * example_module = mrb_module_new(mrb); + * } + * + * @param [mrb_state*] mrb The current mruby state. + * @return [struct RClass *] Reference to the new module. + */ +MRB_API struct RClass * mrb_module_new(mrb_state *mrb); + +/** + * Returns an mrb_bool. True if class was defined, and false if the class was not defined. + * + * Example: + * void + * mrb_example_gem_init(mrb_state* mrb) { + * struct RClass *example_class; + * mrb_bool cd; + * + * example_class = mrb_define_class(mrb, "ExampleClass", mrb->object_class); + * cd = mrb_class_defined(mrb, "ExampleClass"); + * + * // If mrb_class_defined returns 1 then puts "True" + * // If mrb_class_defined returns 0 then puts "False" + * if (cd == 1){ + * puts("True"); + * } + * else { + * puts("False"); + * } + * } + * + * @param [mrb_state*] mrb The current mruby state. + * @param [const char *] name A string representing the name of the class. + * @return [mrb_bool] A boolean value. + */ +MRB_API mrb_bool mrb_class_defined(mrb_state *mrb, const char *name); + +/** + * Gets a class. + * @param [mrb_state*] mrb The current mruby state. + * @param [const char *] name The name of the class. + * @return [struct RClass *] A reference to the class. +*/ +MRB_API struct RClass * mrb_class_get(mrb_state *mrb, const char *name); + +/** + * Gets a exception class. + * @param [mrb_state*] mrb The current mruby state. + * @param [const char *] name The name of the class. + * @return [struct RClass *] A reference to the class. +*/ +MRB_API struct RClass * mrb_exc_get(mrb_state *mrb, const char *name); + +/** + * Returns an mrb_bool. True if inner class was defined, and false if the inner class was not defined. + * + * Example: + * void + * mrb_example_gem_init(mrb_state* mrb) { + * struct RClass *example_outer, *example_inner; + * mrb_bool cd; + * + * example_outer = mrb_define_module(mrb, "ExampleOuter"); + * + * example_inner = mrb_define_class_under(mrb, example_outer, "ExampleInner", mrb->object_class); + * cd = mrb_class_defined_under(mrb, example_outer, "ExampleInner"); + * + * // If mrb_class_defined_under returns 1 then puts "True" + * // If mrb_class_defined_under returns 0 then puts "False" + * if (cd == 1){ + * puts("True"); + * } + * else { + * puts("False"); + * } + * } + * + * @param [mrb_state*] mrb The current mruby state. + * @param [struct RClass *] outer The name of the outer class. + * @param [const char *] name A string representing the name of the inner class. + * @return [mrb_bool] A boolean value. + */ +MRB_API mrb_bool mrb_class_defined_under(mrb_state *mrb, struct RClass *outer, const char *name); + +/** + * Gets a child class. + * @param [mrb_state*] mrb The current mruby state. + * @param [struct RClass *] outer The name of the parent class. + * @param [const char *] name The name of the class. + * @return [struct RClass *] A reference to the class. +*/ +MRB_API struct RClass * mrb_class_get_under(mrb_state *mrb, struct RClass *outer, const char *name); + +/** + * Gets a module. + * @param [mrb_state*] mrb The current mruby state. + * @param [const char *] name The name of the module. + * @return [struct RClass *] A reference to the module. +*/ +MRB_API struct RClass * mrb_module_get(mrb_state *mrb, const char *name); + +/** + * Gets a module defined under another module. + * @param [mrb_state*] mrb The current mruby state. + * @param [struct RClass *] outer The name of the outer module. + * @param [const char *] name The name of the module. + * @return [struct RClass *] A reference to the module. +*/ +MRB_API struct RClass * mrb_module_get_under(mrb_state *mrb, struct RClass *outer, const char *name); +MRB_API mrb_value mrb_notimplement_m(mrb_state*, mrb_value); + +/** + * Duplicate an object. + * + * Equivalent to: + * Object#dup + * @param [mrb_state*] mrb The current mruby state. + * @param [mrb_value] obj Object to be duplicate. + * @return [mrb_value] The newly duplicated object. + */ +MRB_API mrb_value mrb_obj_dup(mrb_state *mrb, mrb_value obj); +MRB_API mrb_value mrb_check_to_integer(mrb_state *mrb, mrb_value val, const char *method); + +/** + * Returns true if obj responds to the given method. If the method was defined for that + * class it returns true, it returns false otherwise. + * + * Example: + * # Ruby style + * class ExampleClass + * def example_method + * end + * end + * + * ExampleClass.new.respond_to?(:example_method) # => true + * + * // C style + * void + * mrb_example_gem_init(mrb_state* mrb) { + * struct RClass *example_class; + * mrb_sym mid; + * mrb_bool obj_resp; + * + * example_class = mrb_define_class(mrb, "ExampleClass", mrb->object_class); + * mrb_define_method(mrb, example_class, "example_method", exampleMethod, MRB_ARGS_NONE()); + * mid = mrb_intern_str(mrb, mrb_str_new_lit(mrb, "example_method" )); + * obj_resp = mrb_obj_respond_to(mrb, example_class, mid); // => 1(true in Ruby world) + * + * // If mrb_obj_respond_to returns 1 then puts "True" + * // If mrb_obj_respond_to returns 0 then puts "False" + * if (obj_resp == 1) { + * puts("True"); + * } + * else if (obj_resp == 0) { + * puts("False"); + * } + * } + * + * @param [mrb_state*] mrb The current mruby state. + * @param [struct RClass *] c A reference to a class. + * @param [mrb_sym] mid A symbol referencing a method id. + * @return [mrb_bool] A boolean value. + */ +MRB_API mrb_bool mrb_obj_respond_to(mrb_state *mrb, struct RClass* c, mrb_sym mid); + +/** + * Defines a new class under a given module + * + * @param [mrb_state*] mrb The current mruby state. + * @param [struct RClass *] outer Reference to the module under which the new class will be defined + * @param [const char *] name The name of the defined class + * @param [struct RClass *] super The new class parent + * @return [struct RClass *] Reference to the newly defined class + * @see mrb_define_class + */ +MRB_API struct RClass * mrb_define_class_under(mrb_state *mrb, struct RClass *outer, const char *name, struct RClass *super); + +MRB_API struct RClass * mrb_define_module_under(mrb_state *mrb, struct RClass *outer, const char *name); + +/** + * Function requires n arguments. + * + * @param n + * The number of required arguments. + */ +#define MRB_ARGS_REQ(n) ((mrb_aspec)((n)&0x1f) << 18) + +/** + * Funtion takes n optional arguments + * + * @param n + * The number of optional arguments. + */ +#define MRB_ARGS_OPT(n) ((mrb_aspec)((n)&0x1f) << 13) + +/** + * Funtion takes n1 mandatory arguments and n2 optional arguments + * + * @param n1 + * The number of required arguments. + * @param n2 + * The number of optional arguments. + */ +#define MRB_ARGS_ARG(n1,n2) (MRB_ARGS_REQ(n1)|MRB_ARGS_OPT(n2)) + +/** rest argument */ +#define MRB_ARGS_REST() ((mrb_aspec)(1 << 12)) + +/** required arguments after rest */ +#define MRB_ARGS_POST(n) ((mrb_aspec)((n)&0x1f) << 7) + +/** keyword arguments (n of keys, kdict) */ +#define MRB_ARGS_KEY(n1,n2) ((mrb_aspec)((((n1)&0x1f) << 2) | ((n2)?(1<<1):0))) + +/** + * Function takes a block argument + */ +#define MRB_ARGS_BLOCK() ((mrb_aspec)1) + +/** + * Function accepts any number of arguments + */ +#define MRB_ARGS_ANY() MRB_ARGS_REST() + +/** + * Function accepts no arguments + */ +#define MRB_ARGS_NONE() ((mrb_aspec)0) + +/** + * Format specifiers for {mrb_get_args} function + * + * Must be a C string composed of the following format specifiers: + * + * | char | Ruby type | C types | Notes | + * |:----:|----------------|-------------------|----------------------------------------------------| + * | `o` | {Object} | {mrb_value} | Could be used to retrieve any type of argument | + * | `C` | {Class}/{Module} | {mrb_value} | | + * | `S` | {String} | {mrb_value} | when `!` follows, the value may be `nil` | + * | `A` | {Array} | {mrb_value} | when `!` follows, the value may be `nil` | + * | `H` | {Hash} | {mrb_value} | when `!` follows, the value may be `nil` | + * | `s` | {String} | char *, {mrb_int} | Receive two arguments; `s!` gives (`NULL`,`0`) for `nil` | + * | `z` | {String} | char * | `NULL` terminated string; `z!` gives `NULL` for `nil` | + * | `a` | {Array} | {mrb_value} *, {mrb_int} | Receive two arguments; `a!` gives (`NULL`,`0`) for `nil` | + * | `f` | {Float} | {mrb_float} | | + * | `i` | {Integer} | {mrb_int} | | + * | `b` | boolean | {mrb_bool} | | + * | `n` | {Symbol} | {mrb_sym} | | + * | `&` | block | {mrb_value} | | + * | `*` | rest arguments | {mrb_value} *, {mrb_int} | Receive the rest of arguments as an array. | + * | | | optional | | After this spec following specs would be optional. | + * | `?` | optional given | {mrb_bool} | `TRUE` if preceding argument is given. Used to check optional argument is given. | + * + * @see mrb_get_args + */ +typedef const char *mrb_args_format; + +/** + * Retrieve arguments from mrb_state. + * + * When applicable, implicit conversions (such as `to_str`, `to_ary`, `to_hash`) are + * applied to received arguments. + * Used inside a function of mrb_func_t type. + * + * @param mrb The current MRuby state. + * @param format [mrb_args_format] is a list of format specifiers + * @param ... The passing variadic arguments must be a pointer of retrieving type. + * @return the number of arguments retrieved. + * @see mrb_args_format + */ +MRB_API mrb_int mrb_get_args(mrb_state *mrb, mrb_args_format format, ...); + +static inline mrb_sym +mrb_get_mid(mrb_state *mrb) /* get method symbol */ +{ + return mrb->c->ci->mid; +} + +static inline int +mrb_get_argc(mrb_state *mrb) /* get argc */ +{ + return mrb->c->ci->argc; +} + +/* `strlen` for character string literals (use with caution or `strlen` instead) + Adjacent string literals are concatenated in C/C++ in translation phase 6. + If `lit` is not one, the compiler will report a syntax error: + MSVC: "error C2143: syntax error : missing ')' before 'string'" + GCC: "error: expected ')' before string constant" +*/ +#define mrb_strlen_lit(lit) (sizeof(lit "") - 1) + +/** + * Call existing ruby functions. + * + * #include + * #include + * #include "mruby/compile.h" + * + * int + * main() + * { + * mrb_int i = 99; + * mrb_state *mrb = mrb_open(); + * + * if (!mrb) { } + * FILE *fp = fopen("test.rb","r"); + * mrb_value obj = mrb_load_file(mrb,fp); + * mrb_funcall(mrb, obj, "method_name", 1, mrb_fixnum_value(i)); + * fclose(fp); + * mrb_close(mrb); + * } + * @param [mrb_state*] mrb_state* The current mruby state. + * @param [mrb_value] mrb_value A reference to an mruby value. + * @param [const char*] const char* The name of the method. + * @param [mrb_int] mrb_int The number of arguments the method has. + * @param [...] ... Variadic values(not type safe!). + * @return [mrb_value] mrb_value mruby function value. + */ +MRB_API mrb_value mrb_funcall(mrb_state*, mrb_value, const char*, mrb_int,...); +/** + * Call existing ruby functions. This is basically the type safe version of mrb_funcall. + * + * #include + * #include + * #include "mruby/compile.h" + * int + * main() + * { + * mrb_int i = 99; + * mrb_state *mrb = mrb_open(); + * + * if (!mrb) { } + * mrb_sym m_sym = mrb_intern_lit(mrb, "method_name"); // Symbol for method. + * + * FILE *fp = fopen("test.rb","r"); + * mrb_value obj = mrb_load_file(mrb,fp); + * mrb_funcall_argv(mrb, obj, m_sym, 1, &obj); // Calling ruby function from test.rb. + * fclose(fp); + * mrb_close(mrb); + * } + * @param [mrb_state*] mrb_state* The current mruby state. + * @param [mrb_value] mrb_value A reference to an mruby value. + * @param [mrb_sym] mrb_sym The symbol representing the method. + * @param [mrb_int] mrb_int The number of arguments the method has. + * @param [const mrb_value*] mrb_value* Pointer to the object. + * @return [mrb_value] mrb_value mruby function value. + * @see mrb_funcall + */ +MRB_API mrb_value mrb_funcall_argv(mrb_state*, mrb_value, mrb_sym, mrb_int, const mrb_value*); +/** + * Call existing ruby functions with a block. + */ +MRB_API mrb_value mrb_funcall_with_block(mrb_state*, mrb_value, mrb_sym, mrb_int, const mrb_value*, mrb_value); +/** + * Create a symbol + * + * # Ruby style: + * :pizza # => :pizza + * + * // C style: + * mrb_sym m_sym = mrb_intern_lit(mrb, "pizza"); // => :pizza + * @param [mrb_state*] mrb_state* The current mruby state. + * @param [const char*] const char* The name of the method. + * @return [mrb_sym] mrb_sym A symbol. + */ +MRB_API mrb_sym mrb_intern_cstr(mrb_state*,const char*); +MRB_API mrb_sym mrb_intern(mrb_state*,const char*,size_t); +MRB_API mrb_sym mrb_intern_static(mrb_state*,const char*,size_t); +#define mrb_intern_lit(mrb, lit) mrb_intern_static(mrb, lit, mrb_strlen_lit(lit)) +MRB_API mrb_sym mrb_intern_str(mrb_state*,mrb_value); +MRB_API mrb_value mrb_check_intern_cstr(mrb_state*,const char*); +MRB_API mrb_value mrb_check_intern(mrb_state*,const char*,size_t); +MRB_API mrb_value mrb_check_intern_str(mrb_state*,mrb_value); +MRB_API const char *mrb_sym2name(mrb_state*,mrb_sym); +MRB_API const char *mrb_sym2name_len(mrb_state*,mrb_sym,mrb_int*); +MRB_API mrb_value mrb_sym2str(mrb_state*,mrb_sym); + +MRB_API void *mrb_malloc(mrb_state*, size_t); /* raise RuntimeError if no mem */ +MRB_API void *mrb_calloc(mrb_state*, size_t, size_t); /* ditto */ +MRB_API void *mrb_realloc(mrb_state*, void*, size_t); /* ditto */ +MRB_API void *mrb_realloc_simple(mrb_state*, void*, size_t); /* return NULL if no memory available */ +MRB_API void *mrb_malloc_simple(mrb_state*, size_t); /* return NULL if no memory available */ +MRB_API struct RBasic *mrb_obj_alloc(mrb_state*, enum mrb_vtype, struct RClass*); +MRB_API void mrb_free(mrb_state*, void*); + +MRB_API mrb_value mrb_str_new(mrb_state *mrb, const char *p, size_t len); + +/** + * Turns a C string into a Ruby string value. + */ +MRB_API mrb_value mrb_str_new_cstr(mrb_state*, const char*); +MRB_API mrb_value mrb_str_new_static(mrb_state *mrb, const char *p, size_t len); +#define mrb_str_new_lit(mrb, lit) mrb_str_new_static(mrb, (lit), mrb_strlen_lit(lit)) + +#ifdef _WIN32 +char* mrb_utf8_from_locale(const char *p, int len); +char* mrb_locale_from_utf8(const char *p, int len); +#define mrb_locale_free(p) free(p) +#define mrb_utf8_free(p) free(p) +#else +#define mrb_utf8_from_locale(p, l) (p) +#define mrb_locale_from_utf8(p, l) (p) +#define mrb_locale_free(p) +#define mrb_utf8_free(p) +#endif + +/** + * Creates new mrb_state. + * + * @return + * Pointer to the newly created mrb_state. + */ +MRB_API mrb_state* mrb_open(void); + +/** + * Create new mrb_state with custom allocators. + * + * @param f + * Reference to the allocation function. + * @param ud + * User data will be passed to custom allocator f. + * If user data isn't required just pass NULL. + * @return + * Pointer to the newly created mrb_state. + */ +MRB_API mrb_state* mrb_open_allocf(mrb_allocf f, void *ud); + +/** + * Create new mrb_state with just the MRuby core + * + * @param f + * Reference to the allocation function. + * Use mrb_default_allocf for the default + * @param ud + * User data will be passed to custom allocator f. + * If user data isn't required just pass NULL. + * @return + * Pointer to the newly created mrb_state. + */ +MRB_API mrb_state* mrb_open_core(mrb_allocf f, void *ud); + +/** + * Closes and frees a mrb_state. + * + * @param mrb + * Pointer to the mrb_state to be closed. + */ +MRB_API void mrb_close(mrb_state *mrb); + +/** + * The default allocation function. + * + * @see mrb_allocf + */ +MRB_API void* mrb_default_allocf(mrb_state*, void*, size_t, void*); + +MRB_API mrb_value mrb_top_self(mrb_state *); +MRB_API mrb_value mrb_run(mrb_state*, struct RProc*, mrb_value); +MRB_API mrb_value mrb_top_run(mrb_state*, struct RProc*, mrb_value, unsigned int); +MRB_API mrb_value mrb_vm_run(mrb_state*, struct RProc*, mrb_value, unsigned int); +MRB_API mrb_value mrb_vm_exec(mrb_state*, struct RProc*, mrb_code*); +/* compatibility macros */ +#define mrb_toplevel_run_keep(m,p,k) mrb_top_run((m),(p),mrb_top_self(m),(k)) +#define mrb_toplevel_run(m,p) mrb_toplevel_run_keep((m),(p),0) +#define mrb_context_run(m,p,s,k) mrb_vm_run((m),(p),(s),(k)) + +MRB_API void mrb_p(mrb_state*, mrb_value); +MRB_API mrb_int mrb_obj_id(mrb_value obj); +MRB_API mrb_sym mrb_obj_to_sym(mrb_state *mrb, mrb_value name); + +MRB_API mrb_bool mrb_obj_eq(mrb_state*, mrb_value, mrb_value); +MRB_API mrb_bool mrb_obj_equal(mrb_state*, mrb_value, mrb_value); +MRB_API mrb_bool mrb_equal(mrb_state *mrb, mrb_value obj1, mrb_value obj2); +MRB_API mrb_value mrb_convert_to_integer(mrb_state *mrb, mrb_value val, int base); +MRB_API mrb_value mrb_Integer(mrb_state *mrb, mrb_value val); +MRB_API mrb_value mrb_Float(mrb_state *mrb, mrb_value val); +MRB_API mrb_value mrb_inspect(mrb_state *mrb, mrb_value obj); +MRB_API mrb_bool mrb_eql(mrb_state *mrb, mrb_value obj1, mrb_value obj2); + +static inline int mrb_gc_arena_save(mrb_state*); +static inline void mrb_gc_arena_restore(mrb_state*,int); + +static inline int +mrb_gc_arena_save(mrb_state *mrb) +{ + return mrb->gc.arena_idx; +} + +static inline void +mrb_gc_arena_restore(mrb_state *mrb, int idx) +{ + mrb->gc.arena_idx = idx; +} + +MRB_API int mrb_gc_arena_save(mrb_state*); +MRB_API void mrb_gc_arena_restore(mrb_state*,int); + +MRB_API void mrb_garbage_collect(mrb_state*); +MRB_API void mrb_full_gc(mrb_state*); +MRB_API void mrb_incremental_gc(mrb_state *); +MRB_API void mrb_gc_mark(mrb_state*,struct RBasic*); +#define mrb_gc_mark_value(mrb,val) do {\ + if (!mrb_immediate_p(val)) mrb_gc_mark((mrb), mrb_basic_ptr(val)); \ +} while (0) +MRB_API void mrb_field_write_barrier(mrb_state *, struct RBasic*, struct RBasic*); +#define mrb_field_write_barrier_value(mrb, obj, val) do{\ + if (!mrb_immediate_p(val)) mrb_field_write_barrier((mrb), (obj), mrb_basic_ptr(val)); \ +} while (0) +MRB_API void mrb_write_barrier(mrb_state *, struct RBasic*); + +MRB_API mrb_value mrb_check_convert_type(mrb_state *mrb, mrb_value val, enum mrb_vtype type, const char *tname, const char *method); +MRB_API mrb_value mrb_any_to_s(mrb_state *mrb, mrb_value obj); +MRB_API const char * mrb_obj_classname(mrb_state *mrb, mrb_value obj); +MRB_API struct RClass* mrb_obj_class(mrb_state *mrb, mrb_value obj); +MRB_API mrb_value mrb_class_path(mrb_state *mrb, struct RClass *c); +MRB_API mrb_value mrb_convert_type(mrb_state *mrb, mrb_value val, enum mrb_vtype type, const char *tname, const char *method); +MRB_API mrb_bool mrb_obj_is_kind_of(mrb_state *mrb, mrb_value obj, struct RClass *c); +MRB_API mrb_value mrb_obj_inspect(mrb_state *mrb, mrb_value self); +MRB_API mrb_value mrb_obj_clone(mrb_state *mrb, mrb_value self); + +#ifndef ISPRINT +#define ISASCII(c) ((unsigned)(c) <= 0x7f) +#define ISPRINT(c) (((unsigned)(c) - 0x20) < 0x5f) +#define ISSPACE(c) ((c) == ' ' || (unsigned)(c) - '\t' < 5) +#define ISUPPER(c) (((unsigned)(c) - 'A') < 26) +#define ISLOWER(c) (((unsigned)(c) - 'a') < 26) +#define ISALPHA(c) ((((unsigned)(c) | 0x20) - 'a') < 26) +#define ISDIGIT(c) (((unsigned)(c) - '0') < 10) +#define ISXDIGIT(c) (ISDIGIT(c) || ((unsigned)(c) | 0x20) - 'a' < 6) +#define ISALNUM(c) (ISALPHA(c) || ISDIGIT(c)) +#define ISBLANK(c) ((c) == ' ' || (c) == '\t') +#define ISCNTRL(c) ((unsigned)(c) < 0x20 || (c) == 0x7f) +#define TOUPPER(c) (ISLOWER(c) ? ((c) & 0x5f) : (c)) +#define TOLOWER(c) (ISUPPER(c) ? ((c) | 0x20) : (c)) +#endif + +MRB_API mrb_value mrb_exc_new(mrb_state *mrb, struct RClass *c, const char *ptr, size_t len); +MRB_API mrb_noreturn void mrb_exc_raise(mrb_state *mrb, mrb_value exc); + +MRB_API mrb_noreturn void mrb_raise(mrb_state *mrb, struct RClass *c, const char *msg); +MRB_API mrb_noreturn void mrb_raisef(mrb_state *mrb, struct RClass *c, const char *fmt, ...); +MRB_API mrb_noreturn void mrb_name_error(mrb_state *mrb, mrb_sym id, const char *fmt, ...); +MRB_API void mrb_warn(mrb_state *mrb, const char *fmt, ...); +MRB_API mrb_noreturn void mrb_bug(mrb_state *mrb, const char *fmt, ...); +MRB_API void mrb_print_backtrace(mrb_state *mrb); +MRB_API void mrb_print_error(mrb_state *mrb); + +/* macros to get typical exception objects + note: + + those E_* macros requires mrb_state* variable named mrb. + + exception objects obtained from those macros are local to mrb +*/ +#define E_RUNTIME_ERROR (mrb_exc_get(mrb, "RuntimeError")) +#define E_TYPE_ERROR (mrb_exc_get(mrb, "TypeError")) +#define E_ARGUMENT_ERROR (mrb_exc_get(mrb, "ArgumentError")) +#define E_INDEX_ERROR (mrb_exc_get(mrb, "IndexError")) +#define E_RANGE_ERROR (mrb_exc_get(mrb, "RangeError")) +#define E_NAME_ERROR (mrb_exc_get(mrb, "NameError")) +#define E_NOMETHOD_ERROR (mrb_exc_get(mrb, "NoMethodError")) +#define E_SCRIPT_ERROR (mrb_exc_get(mrb, "ScriptError")) +#define E_SYNTAX_ERROR (mrb_exc_get(mrb, "SyntaxError")) +#define E_LOCALJUMP_ERROR (mrb_exc_get(mrb, "LocalJumpError")) +#define E_REGEXP_ERROR (mrb_exc_get(mrb, "RegexpError")) + +#define E_NOTIMP_ERROR (mrb_exc_get(mrb, "NotImplementedError")) +#define E_FLOATDOMAIN_ERROR (mrb_exc_get(mrb, "FloatDomainError")) + +#define E_KEY_ERROR (mrb_exc_get(mrb, "KeyError")) + +MRB_API mrb_value mrb_yield(mrb_state *mrb, mrb_value b, mrb_value arg); +MRB_API mrb_value mrb_yield_argv(mrb_state *mrb, mrb_value b, mrb_int argc, const mrb_value *argv); +MRB_API mrb_value mrb_yield_with_class(mrb_state *mrb, mrb_value b, mrb_int argc, const mrb_value *argv, mrb_value self, struct RClass *c); + +/* continue execution to the proc */ +/* this function should always be called as the last function of a method */ +/* e.g. return mrb_yield_cont(mrb, proc, self, argc, argv); */ +mrb_value mrb_yield_cont(mrb_state *mrb, mrb_value b, mrb_value self, mrb_int argc, const mrb_value *argv); + +/* mrb_gc_protect() leaves the object in the arena */ +MRB_API void mrb_gc_protect(mrb_state *mrb, mrb_value obj); +/* mrb_gc_register() keeps the object from GC. */ +MRB_API void mrb_gc_register(mrb_state *mrb, mrb_value obj); +/* mrb_gc_unregister() removes the object from GC root. */ +MRB_API void mrb_gc_unregister(mrb_state *mrb, mrb_value obj); + +MRB_API mrb_value mrb_to_int(mrb_state *mrb, mrb_value val); +#define mrb_int(mrb, val) mrb_fixnum(mrb_to_int(mrb, val)) +MRB_API void mrb_check_type(mrb_state *mrb, mrb_value x, enum mrb_vtype t); + +typedef enum call_type { + CALL_PUBLIC, + CALL_FCALL, + CALL_VCALL, + CALL_TYPE_MAX +} call_type; + +MRB_API void mrb_define_alias(mrb_state *mrb, struct RClass *klass, const char *name1, const char *name2); +MRB_API const char *mrb_class_name(mrb_state *mrb, struct RClass* klass); +MRB_API void mrb_define_global_const(mrb_state *mrb, const char *name, mrb_value val); + +MRB_API mrb_value mrb_attr_get(mrb_state *mrb, mrb_value obj, mrb_sym id); + +MRB_API mrb_bool mrb_respond_to(mrb_state *mrb, mrb_value obj, mrb_sym mid); +MRB_API mrb_bool mrb_obj_is_instance_of(mrb_state *mrb, mrb_value obj, struct RClass* c); +MRB_API mrb_bool mrb_func_basic_p(mrb_state *mrb, mrb_value obj, mrb_sym mid, mrb_func_t func); + + +/* + * Resume a Fiber + * + * @mrbgem mruby-fiber + */ +MRB_API mrb_value mrb_fiber_resume(mrb_state *mrb, mrb_value fib, mrb_int argc, const mrb_value *argv); + +/* + * Yield a Fiber + * + * @mrbgem mruby-fiber + */ +MRB_API mrb_value mrb_fiber_yield(mrb_state *mrb, mrb_int argc, const mrb_value *argv); + +/* + * FiberError reference + * + * @mrbgem mruby-fiber + */ +#define E_FIBER_ERROR (mrb_exc_get(mrb, "FiberError")) + +/* memory pool implementation */ +typedef struct mrb_pool mrb_pool; +MRB_API struct mrb_pool* mrb_pool_open(mrb_state*); +MRB_API void mrb_pool_close(struct mrb_pool*); +MRB_API void* mrb_pool_alloc(struct mrb_pool*, size_t); +MRB_API void* mrb_pool_realloc(struct mrb_pool*, void*, size_t oldlen, size_t newlen); +MRB_API mrb_bool mrb_pool_can_realloc(struct mrb_pool*, void*, size_t); +MRB_API void* mrb_alloca(mrb_state *mrb, size_t); + +MRB_API void mrb_state_atexit(mrb_state *mrb, mrb_atexit_func func); + +MRB_API void mrb_show_version(mrb_state *mrb); +MRB_API void mrb_show_copyright(mrb_state *mrb); + +MRB_API mrb_value mrb_format(mrb_state *mrb, const char *format, ...); + +#if 0 +/* memcpy and memset does not work with gdb reverse-next on my box */ +/* use naive memcpy and memset instead */ +#undef memcpy +#undef memset +static inline void* +mrbmemcpy(void *dst, const void *src, size_t n) +{ + char *d = (char*)dst; + const char *s = (const char*)src; + while (n--) + *d++ = *s++; + return d; +} +#define memcpy(a,b,c) mrbmemcpy(a,b,c) + +static inline void* +mrbmemset(void *s, int c, size_t n) +{ + char *t = (char*)s; + while (n--) + *t++ = c; + return s; +} +#define memset(a,b,c) mrbmemset(a,b,c) +#endif + +MRB_END_DECL + +#endif /* MRUBY_H */ diff --git a/web/server/h2o/libh2o/deps/mruby/include/mruby/array.h b/web/server/h2o/libh2o/deps/mruby/include/mruby/array.h new file mode 100644 index 00000000..54271555 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/include/mruby/array.h @@ -0,0 +1,279 @@ +/* +** mruby/array.h - Array class +** +** See Copyright Notice in mruby.h +*/ + +#ifndef MRUBY_ARRAY_H +#define MRUBY_ARRAY_H + +#include "common.h" + +/* + * Array class + */ +MRB_BEGIN_DECL + + +typedef struct mrb_shared_array { + int refcnt; + mrb_int len; + mrb_value *ptr; +} mrb_shared_array; + +#define MRB_ARY_EMBED_LEN_MAX ((mrb_int)(sizeof(void*)*3/sizeof(mrb_value))) +struct RArray { + MRB_OBJECT_HEADER; + union { + struct { + mrb_int len; + union { + mrb_int capa; + mrb_shared_array *shared; + } aux; + mrb_value *ptr; + } heap; + mrb_value embed[MRB_ARY_EMBED_LEN_MAX]; + } as; +}; + +#define mrb_ary_ptr(v) ((struct RArray*)(mrb_ptr(v))) +#define mrb_ary_value(p) mrb_obj_value((void*)(p)) +#define RARRAY(v) ((struct RArray*)(mrb_ptr(v))) + +#define MRB_ARY_EMBED_MASK 7 +#define ARY_EMBED_P(a) ((a)->flags & MRB_ARY_EMBED_MASK) +#define ARY_UNSET_EMBED_FLAG(a) ((a)->flags &= ~(MRB_ARY_EMBED_MASK)) +#define ARY_EMBED_LEN(a) ((mrb_int)(((a)->flags & MRB_ARY_EMBED_MASK) - 1)) +#define ARY_SET_EMBED_LEN(a,len) ((a)->flags = ((a)->flags&~MRB_ARY_EMBED_MASK) | (len + 1)) +#define ARY_EMBED_PTR(a) (&((a)->as.embed[0])) + +#define ARY_LEN(a) (ARY_EMBED_P(a)?ARY_EMBED_LEN(a):(a)->as.heap.len) +#define ARY_PTR(a) (ARY_EMBED_P(a)?ARY_EMBED_PTR(a):(a)->as.heap.ptr) +#define RARRAY_LEN(a) ARY_LEN(RARRAY(a)) +#define RARRAY_PTR(a) ARY_PTR(RARRAY(a)) +#define ARY_SET_LEN(a,n) do {\ + if (ARY_EMBED_P(a)) {\ + mrb_assert((n) <= MRB_ARY_EMBED_LEN_MAX); \ + ARY_SET_EMBED_LEN(a,n);\ + }\ + else\ + (a)->as.heap.len = (n);\ +} while (0) +#define ARY_CAPA(a) (ARY_EMBED_P(a)?MRB_ARY_EMBED_LEN_MAX:(a)->as.heap.aux.capa) +#define MRB_ARY_SHARED 256 +#define ARY_SHARED_P(a) ((a)->flags & MRB_ARY_SHARED) +#define ARY_SET_SHARED_FLAG(a) ((a)->flags |= MRB_ARY_SHARED) +#define ARY_UNSET_SHARED_FLAG(a) ((a)->flags &= ~MRB_ARY_SHARED) + +void mrb_ary_decref(mrb_state*, mrb_shared_array*); +MRB_API void mrb_ary_modify(mrb_state*, struct RArray*); +MRB_API mrb_value mrb_ary_new_capa(mrb_state*, mrb_int); + +/* + * Initializes a new array. + * + * Equivalent to: + * + * Array.new + * + * @param mrb The mruby state reference. + * @return The initialized array. + */ +MRB_API mrb_value mrb_ary_new(mrb_state *mrb); + +/* + * Initializes a new array with initial values + * + * Equivalent to: + * + * Array[value1, value2, ...] + * + * @param mrb The mruby state reference. + * @param size The numer of values. + * @param vals The actual values. + * @return The initialized array. + */ +MRB_API mrb_value mrb_ary_new_from_values(mrb_state *mrb, mrb_int size, const mrb_value *vals); + +/* + * Initializes a new array with two initial values + * + * Equivalent to: + * + * Array[car, cdr] + * + * @param mrb The mruby state reference. + * @param car The first value. + * @param cdr The second value. + * @return The initialized array. + */ +MRB_API mrb_value mrb_assoc_new(mrb_state *mrb, mrb_value car, mrb_value cdr); + +/* + * Concatenate two arrays. The target array will be modified + * + * Equivalent to: + * ary.concat(other) + * + * @param mrb The mruby state reference. + * @param self The target array. + * @param other The array that will be concatenated to self. + */ +MRB_API void mrb_ary_concat(mrb_state *mrb, mrb_value self, mrb_value other); + +/* + * Create an array from the input. It tries calling to_a on the + * value. If value does not respond to that, it creates a new + * array with just this value. + * + * @param mrb The mruby state reference. + * @param value The value to change into an array. + * @return An array representation of value. + */ +MRB_API mrb_value mrb_ary_splat(mrb_state *mrb, mrb_value value); + +/* + * Pushes value into array. + * + * Equivalent to: + * + * ary << value + * + * @param mrb The mruby state reference. + * @param ary The array in which the value will be pushed + * @param value The value to be pushed into array + */ +MRB_API void mrb_ary_push(mrb_state *mrb, mrb_value array, mrb_value value); + +/* + * Pops the last element from the array. + * + * Equivalent to: + * + * ary.pop + * + * @param mrb The mruby state reference. + * @param ary The array from which the value will be popped. + * @return The popped value. + */ +MRB_API mrb_value mrb_ary_pop(mrb_state *mrb, mrb_value ary); + +/* + * Returns a reference to an element of the array on the given index. + * + * Equivalent to: + * + * ary[n] + * + * @param mrb The mruby state reference. + * @param ary The target array. + * @param n The array index being referenced + * @return The referenced value. + */ +MRB_API mrb_value mrb_ary_ref(mrb_state *mrb, mrb_value ary, mrb_int n); + +/* + * Sets a value on an array at the given index + * + * Equivalent to: + * + * ary[n] = val + * + * @param mrb The mruby state reference. + * @param ary The target array. + * @param n The array index being referenced. + * @param val The value being setted. + */ +MRB_API void mrb_ary_set(mrb_state *mrb, mrb_value ary, mrb_int n, mrb_value val); + +/* + * Replace the array with another array + * + * Equivalent to: + * + * ary.replace(other) + * + * @param mrb The mruby state reference + * @param self The target array. + * @param other The array to replace it with. + */ +MRB_API void mrb_ary_replace(mrb_state *mrb, mrb_value self, mrb_value other); +MRB_API mrb_value mrb_check_array_type(mrb_state *mrb, mrb_value self); + +/* + * Unshift an element into the array + * + * Equivalent to: + * + * ary.unshift(item) + * + * @param mrb The mruby state reference. + * @param self The target array. + * @param item The item to unshift. + */ +MRB_API mrb_value mrb_ary_unshift(mrb_state *mrb, mrb_value self, mrb_value item); + +/* + * Get nth element in the array + * + * Equivalent to: + * + * ary[offset] + * + * @param ary The target array. + * @param offset The element position (negative counts from the tail). + */ +MRB_API mrb_value mrb_ary_entry(mrb_value ary, mrb_int offset); + +/* + * Shifts the first element from the array. + * + * Equivalent to: + * + * ary.shift + * + * @param mrb The mruby state reference. + * @param self The array from which the value will be shifted. + * @return The shifted value. + */ +MRB_API mrb_value mrb_ary_shift(mrb_state *mrb, mrb_value self); + +/* + * Removes all elements from the array + * + * Equivalent to: + * + * ary.clear + * + * @param mrb The mruby state reference. + * @param self The target array. + * @return self + */ +MRB_API mrb_value mrb_ary_clear(mrb_state *mrb, mrb_value self); + +/* + * Join the array elements together in a string + * + * Equivalent to: + * + * ary.join(sep="") + * + * @param mrb The mruby state reference. + * @param ary The target array + * @param sep The separater, can be NULL + */ +MRB_API mrb_value mrb_ary_join(mrb_state *mrb, mrb_value ary, mrb_value sep); + +/* + * Update the capacity of the array + * + * @param mrb The mruby state reference. + * @param ary The target array. + * @param new_len The new capacity of the array + */ +MRB_API mrb_value mrb_ary_resize(mrb_state *mrb, mrb_value ary, mrb_int new_len); + +MRB_END_DECL + +#endif /* MRUBY_ARRAY_H */ diff --git a/web/server/h2o/libh2o/deps/mruby/include/mruby/boxing_nan.h b/web/server/h2o/libh2o/deps/mruby/include/mruby/boxing_nan.h new file mode 100644 index 00000000..700ea2ed --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/include/mruby/boxing_nan.h @@ -0,0 +1,98 @@ +/* +** mruby/boxing_nan.h - nan boxing mrb_value definition +** +** See Copyright Notice in mruby.h +*/ + +#ifndef MRUBY_BOXING_NAN_H +#define MRUBY_BOXING_NAN_H + +#ifdef MRB_USE_FLOAT +# error ---->> MRB_NAN_BOXING and MRB_USE_FLOAT conflict <<---- +#endif + +#ifdef MRB_INT64 +# error ---->> MRB_NAN_BOXING and MRB_INT64 conflict <<---- +#endif + +#define MRB_FIXNUM_SHIFT 0 +#define MRB_TT_HAS_BASIC MRB_TT_OBJECT + +#ifdef MRB_ENDIAN_BIG +#define MRB_ENDIAN_LOHI(a,b) a b +#else +#define MRB_ENDIAN_LOHI(a,b) b a +#endif + +/* value representation by nan-boxing: + * float : FFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFF + * object: 111111111111TTTT TTPPPPPPPPPPPPPP PPPPPPPPPPPPPPPP PPPPPPPPPPPPPPPP + * int : 1111111111110001 0000000000000000 IIIIIIIIIIIIIIII IIIIIIIIIIIIIIII + * sym : 1111111111110001 0100000000000000 SSSSSSSSSSSSSSSS SSSSSSSSSSSSSSSS + * In order to get enough bit size to save TT, all pointers are shifted 2 bits + * in the right direction. Also, TTTTTT is the mrb_vtype + 1; + */ +typedef struct mrb_value { + union { + mrb_float f; + union { + void *p; + struct { + MRB_ENDIAN_LOHI( + uint32_t ttt; + ,union { + mrb_int i; + mrb_sym sym; + }; + ) + }; + } value; + }; +} mrb_value; + +#define mrb_float_pool(mrb,f) mrb_float_value(mrb,f) + +#define mrb_tt(o) ((enum mrb_vtype)(((o).value.ttt & 0xfc000)>>14)-1) +#define mrb_type(o) (enum mrb_vtype)((uint32_t)0xfff00000 < (o).value.ttt ? mrb_tt(o) : MRB_TT_FLOAT) +#define mrb_ptr(o) ((void*)((((uintptr_t)0x3fffffffffff)&((uintptr_t)((o).value.p)))<<2)) +#define mrb_float(o) (o).f +#define mrb_cptr(o) mrb_ptr(o) +#define mrb_fixnum(o) (o).value.i +#define mrb_symbol(o) (o).value.sym + +#ifdef MRB_64BIT +#define BOXNAN_SHIFT_LONG_POINTER(v) (((uintptr_t)(v)>>34)&0x3fff) +#else +#define BOXNAN_SHIFT_LONG_POINTER(v) 0 +#endif + +#define BOXNAN_SET_VALUE(o, tt, attr, v) do {\ + (o).attr = (v);\ + (o).value.ttt = 0xfff00000 | (((tt)+1)<<14);\ +} while (0) + +#define BOXNAN_SET_OBJ_VALUE(o, tt, v) do {\ + (o).value.p = (void*)((uintptr_t)(v)>>2);\ + (o).value.ttt = (0xfff00000|(((tt)+1)<<14)|BOXNAN_SHIFT_LONG_POINTER(v));\ +} while (0) + +#define SET_FLOAT_VALUE(mrb,r,v) do { \ + if (v != v) { \ + (r).value.ttt = 0x7ff80000; \ + (r).value.i = 0; \ + } \ + else { \ + (r).f = v; \ + }} while(0) + +#define SET_NIL_VALUE(r) BOXNAN_SET_VALUE(r, MRB_TT_FALSE, value.i, 0) +#define SET_FALSE_VALUE(r) BOXNAN_SET_VALUE(r, MRB_TT_FALSE, value.i, 1) +#define SET_TRUE_VALUE(r) BOXNAN_SET_VALUE(r, MRB_TT_TRUE, value.i, 1) +#define SET_BOOL_VALUE(r,b) BOXNAN_SET_VALUE(r, b ? MRB_TT_TRUE : MRB_TT_FALSE, value.i, 1) +#define SET_INT_VALUE(r,n) BOXNAN_SET_VALUE(r, MRB_TT_FIXNUM, value.i, (n)) +#define SET_SYM_VALUE(r,v) BOXNAN_SET_VALUE(r, MRB_TT_SYMBOL, value.sym, (v)) +#define SET_OBJ_VALUE(r,v) BOXNAN_SET_OBJ_VALUE(r, (((struct RObject*)(v))->tt), (v)) +#define SET_CPTR_VALUE(mrb,r,v) BOXNAN_SET_OBJ_VALUE(r, MRB_TT_CPTR, v) +#define SET_UNDEF_VALUE(r) BOXNAN_SET_VALUE(r, MRB_TT_UNDEF, value.i, 0) + +#endif /* MRUBY_BOXING_NAN_H */ diff --git a/web/server/h2o/libh2o/deps/mruby/include/mruby/boxing_no.h b/web/server/h2o/libh2o/deps/mruby/include/mruby/boxing_no.h new file mode 100644 index 00000000..7ee44a93 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/include/mruby/boxing_no.h @@ -0,0 +1,48 @@ +/* +** mruby/boxing_no.h - unboxed mrb_value definition +** +** See Copyright Notice in mruby.h +*/ + +#ifndef MRUBY_BOXING_NO_H +#define MRUBY_BOXING_NO_H + +#define MRB_FIXNUM_SHIFT 0 +#define MRB_TT_HAS_BASIC MRB_TT_OBJECT + +typedef struct mrb_value { + union { + mrb_float f; + void *p; + mrb_int i; + mrb_sym sym; + } value; + enum mrb_vtype tt; +} mrb_value; + +#define mrb_float_pool(mrb,f) mrb_float_value(mrb,f) + +#define mrb_ptr(o) (o).value.p +#define mrb_cptr(o) mrb_ptr(o) +#define mrb_float(o) (o).value.f +#define mrb_fixnum(o) (o).value.i +#define mrb_symbol(o) (o).value.sym +#define mrb_type(o) (o).tt + +#define BOXNIX_SET_VALUE(o, ttt, attr, v) do {\ + (o).tt = ttt;\ + (o).attr = v;\ +} while (0) + +#define SET_NIL_VALUE(r) BOXNIX_SET_VALUE(r, MRB_TT_FALSE, value.i, 0) +#define SET_FALSE_VALUE(r) BOXNIX_SET_VALUE(r, MRB_TT_FALSE, value.i, 1) +#define SET_TRUE_VALUE(r) BOXNIX_SET_VALUE(r, MRB_TT_TRUE, value.i, 1) +#define SET_BOOL_VALUE(r,b) BOXNIX_SET_VALUE(r, b ? MRB_TT_TRUE : MRB_TT_FALSE, value.i, 1) +#define SET_INT_VALUE(r,n) BOXNIX_SET_VALUE(r, MRB_TT_FIXNUM, value.i, (n)) +#define SET_FLOAT_VALUE(mrb,r,v) BOXNIX_SET_VALUE(r, MRB_TT_FLOAT, value.f, (v)) +#define SET_SYM_VALUE(r,v) BOXNIX_SET_VALUE(r, MRB_TT_SYMBOL, value.sym, (v)) +#define SET_OBJ_VALUE(r,v) BOXNIX_SET_VALUE(r, (((struct RObject*)(v))->tt), value.p, (v)) +#define SET_CPTR_VALUE(mrb,r,v) BOXNIX_SET_VALUE(r, MRB_TT_CPTR, value.p, v) +#define SET_UNDEF_VALUE(r) BOXNIX_SET_VALUE(r, MRB_TT_UNDEF, value.i, 0) + +#endif /* MRUBY_BOXING_NO_H */ diff --git a/web/server/h2o/libh2o/deps/mruby/include/mruby/boxing_word.h b/web/server/h2o/libh2o/deps/mruby/include/mruby/boxing_word.h new file mode 100644 index 00000000..d1c457fa --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/include/mruby/boxing_word.h @@ -0,0 +1,120 @@ +/* +** mruby/boxing_word.h - word boxing mrb_value definition +** +** See Copyright Notice in mruby.h +*/ + +#ifndef MRUBY_BOXING_WORD_H +#define MRUBY_BOXING_WORD_H + +#if defined(MRB_INT16) +# error MRB_INT16 is too small for MRB_WORD_BOXING. +#endif + +#if defined(MRB_INT64) && !defined(MRB_64BIT) +#error MRB_INT64 cannot be used with MRB_WORD_BOXING in 32-bit mode. +#endif + +struct RFloat { + MRB_OBJECT_HEADER; + mrb_float f; +}; + +struct RCptr { + MRB_OBJECT_HEADER; + void *p; +}; + +#define MRB_FIXNUM_SHIFT 1 +#define MRB_TT_HAS_BASIC MRB_TT_FLOAT + +enum mrb_special_consts { + MRB_Qnil = 0, + MRB_Qfalse = 2, + MRB_Qtrue = 4, + MRB_Qundef = 6, +}; + +#define MRB_FIXNUM_FLAG 0x01 +#define MRB_SYMBOL_FLAG 0x0e +#define MRB_SPECIAL_SHIFT 8 + +typedef union mrb_value { + union { + void *p; + struct { + unsigned int i_flag : MRB_FIXNUM_SHIFT; + mrb_int i : (MRB_INT_BIT - MRB_FIXNUM_SHIFT); + }; + struct { + unsigned int sym_flag : MRB_SPECIAL_SHIFT; + mrb_sym sym : (sizeof(mrb_sym) * CHAR_BIT); + }; + struct RBasic *bp; + struct RFloat *fp; + struct RCptr *vp; + } value; + unsigned long w; +} mrb_value; + +MRB_API mrb_value mrb_word_boxing_cptr_value(struct mrb_state*, void*); +MRB_API mrb_value mrb_word_boxing_float_value(struct mrb_state*, mrb_float); +MRB_API mrb_value mrb_word_boxing_float_pool(struct mrb_state*, mrb_float); + +#define mrb_float_pool(mrb,f) mrb_word_boxing_float_pool(mrb,f) + +#define mrb_ptr(o) (o).value.p +#define mrb_cptr(o) (o).value.vp->p +#define mrb_float(o) (o).value.fp->f +#define mrb_fixnum(o) ((mrb_int)(o).value.i) +#define mrb_symbol(o) (o).value.sym + +static inline enum mrb_vtype +mrb_type(mrb_value o) +{ + switch (o.w) { + case MRB_Qfalse: + case MRB_Qnil: + return MRB_TT_FALSE; + case MRB_Qtrue: + return MRB_TT_TRUE; + case MRB_Qundef: + return MRB_TT_UNDEF; + } + if (o.value.i_flag == MRB_FIXNUM_FLAG) { + return MRB_TT_FIXNUM; + } + if (o.value.sym_flag == MRB_SYMBOL_FLAG) { + return MRB_TT_SYMBOL; + } + return o.value.bp->tt; +} + +#define mrb_bool(o) ((o).w != MRB_Qnil && (o).w != MRB_Qfalse) +#define mrb_fixnum_p(o) ((o).value.i_flag == MRB_FIXNUM_FLAG) +#define mrb_undef_p(o) ((o).w == MRB_Qundef) +#define mrb_nil_p(o) ((o).w == MRB_Qnil) + +#define BOXWORD_SET_VALUE(o, ttt, attr, v) do { \ + switch (ttt) {\ + case MRB_TT_FALSE: (o).w = (v) ? MRB_Qfalse : MRB_Qnil; break;\ + case MRB_TT_TRUE: (o).w = MRB_Qtrue; break;\ + case MRB_TT_UNDEF: (o).w = MRB_Qundef; break;\ + case MRB_TT_FIXNUM: (o).w = 0;(o).value.i_flag = MRB_FIXNUM_FLAG; (o).attr = (v); break;\ + case MRB_TT_SYMBOL: (o).w = 0;(o).value.sym_flag = MRB_SYMBOL_FLAG; (o).attr = (v); break;\ + default: (o).w = 0; (o).attr = (v); if ((o).value.bp) (o).value.bp->tt = ttt; break;\ + }\ +} while (0) + +#define SET_FLOAT_VALUE(mrb,r,v) r = mrb_word_boxing_float_value(mrb, v) +#define SET_CPTR_VALUE(mrb,r,v) r = mrb_word_boxing_cptr_value(mrb, v) +#define SET_NIL_VALUE(r) BOXWORD_SET_VALUE(r, MRB_TT_FALSE, value.i, 0) +#define SET_FALSE_VALUE(r) BOXWORD_SET_VALUE(r, MRB_TT_FALSE, value.i, 1) +#define SET_TRUE_VALUE(r) BOXWORD_SET_VALUE(r, MRB_TT_TRUE, value.i, 1) +#define SET_BOOL_VALUE(r,b) BOXWORD_SET_VALUE(r, b ? MRB_TT_TRUE : MRB_TT_FALSE, value.i, 1) +#define SET_INT_VALUE(r,n) BOXWORD_SET_VALUE(r, MRB_TT_FIXNUM, value.i, (n)) +#define SET_SYM_VALUE(r,v) BOXWORD_SET_VALUE(r, MRB_TT_SYMBOL, value.sym, (v)) +#define SET_OBJ_VALUE(r,v) BOXWORD_SET_VALUE(r, (((struct RObject*)(v))->tt), value.p, (v)) +#define SET_UNDEF_VALUE(r) BOXWORD_SET_VALUE(r, MRB_TT_UNDEF, value.i, 0) + +#endif /* MRUBY_BOXING_WORD_H */ diff --git a/web/server/h2o/libh2o/deps/mruby/include/mruby/class.h b/web/server/h2o/libh2o/deps/mruby/include/mruby/class.h new file mode 100644 index 00000000..c0317b45 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/include/mruby/class.h @@ -0,0 +1,92 @@ +/* +** mruby/class.h - Class class +** +** See Copyright Notice in mruby.h +*/ + +#ifndef MRUBY_CLASS_H +#define MRUBY_CLASS_H + +#include "common.h" + +/** + * Class class + */ +MRB_BEGIN_DECL + +struct RClass { + MRB_OBJECT_HEADER; + struct iv_tbl *iv; + struct kh_mt *mt; + struct RClass *super; +}; + +#define mrb_class_ptr(v) ((struct RClass*)(mrb_ptr(v))) +#define RCLASS_SUPER(v) (((struct RClass*)(mrb_ptr(v)))->super) +#define RCLASS_IV_TBL(v) (((struct RClass*)(mrb_ptr(v)))->iv) +#define RCLASS_M_TBL(v) (((struct RClass*)(mrb_ptr(v)))->mt) + +static inline struct RClass* +mrb_class(mrb_state *mrb, mrb_value v) +{ + switch (mrb_type(v)) { + case MRB_TT_FALSE: + if (mrb_fixnum(v)) + return mrb->false_class; + return mrb->nil_class; + case MRB_TT_TRUE: + return mrb->true_class; + case MRB_TT_SYMBOL: + return mrb->symbol_class; + case MRB_TT_FIXNUM: + return mrb->fixnum_class; + case MRB_TT_FLOAT: + return mrb->float_class; + case MRB_TT_CPTR: + return mrb->object_class; + case MRB_TT_ENV: + return NULL; + default: + return mrb_obj_ptr(v)->c; + } +} + +/* TODO: figure out where to put user flags */ +#define MRB_FLAG_IS_FROZEN (1 << 18) +#define MRB_FLAG_IS_PREPENDED (1 << 19) +#define MRB_FLAG_IS_ORIGIN (1 << 20) +#define MRB_CLASS_ORIGIN(c) do {\ + if (c->flags & MRB_FLAG_IS_PREPENDED) {\ + c = c->super;\ + while (!(c->flags & MRB_FLAG_IS_ORIGIN)) {\ + c = c->super;\ + }\ + }\ +} while (0) +#define MRB_FLAG_IS_INHERITED (1 << 21) +#define MRB_INSTANCE_TT_MASK (0xFF) +#define MRB_SET_INSTANCE_TT(c, tt) c->flags = ((c->flags & ~MRB_INSTANCE_TT_MASK) | (char)tt) +#define MRB_INSTANCE_TT(c) (enum mrb_vtype)(c->flags & MRB_INSTANCE_TT_MASK) + +MRB_API struct RClass* mrb_define_class_id(mrb_state*, mrb_sym, struct RClass*); +MRB_API struct RClass* mrb_define_module_id(mrb_state*, mrb_sym); +MRB_API struct RClass *mrb_vm_define_class(mrb_state*, mrb_value, mrb_value, mrb_sym); +MRB_API struct RClass *mrb_vm_define_module(mrb_state*, mrb_value, mrb_sym); +MRB_API void mrb_define_method_raw(mrb_state*, struct RClass*, mrb_sym, struct RProc *); +MRB_API void mrb_define_method_id(mrb_state *mrb, struct RClass *c, mrb_sym mid, mrb_func_t func, mrb_aspec aspec); +MRB_API void mrb_alias_method(mrb_state *mrb, struct RClass *c, mrb_sym a, mrb_sym b); + +MRB_API struct RProc *mrb_method_search_vm(mrb_state*, struct RClass**, mrb_sym); +MRB_API struct RProc *mrb_method_search(mrb_state*, struct RClass*, mrb_sym); + +MRB_API struct RClass* mrb_class_real(struct RClass* cl); + +void mrb_class_name_class(mrb_state*, struct RClass*, struct RClass*, mrb_sym); +mrb_value mrb_class_find_path(mrb_state*, struct RClass*); +void mrb_gc_mark_mt(mrb_state*, struct RClass*); +size_t mrb_gc_mark_mt_size(mrb_state*, struct RClass*); +void mrb_gc_free_mt(mrb_state*, struct RClass*); + +MRB_END_DECL + +#endif /* MRUBY_CLASS_H */ diff --git a/web/server/h2o/libh2o/deps/mruby/include/mruby/common.h b/web/server/h2o/libh2o/deps/mruby/include/mruby/common.h new file mode 100644 index 00000000..d6ec78b0 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/include/mruby/common.h @@ -0,0 +1,72 @@ +/* +**"common.h - mruby common platform definition" +** +** See Copyright Notice in mruby.h +*/ + +#ifndef MRUBY_COMMON_H +#define MRUBY_COMMON_H + + +#ifdef __cplusplus +#ifdef MRB_ENABLE_CXX_ABI +#define MRB_BEGIN_DECL +#define MRB_END_DECL +#else +# define MRB_BEGIN_DECL extern "C" { +# define MRB_END_DECL } +#endif +#else +/** Start declarations in C mode */ +# define MRB_BEGIN_DECL +/** End declarations in C mode */ +# define MRB_END_DECL +#endif + +/** + * Shared compiler macros + */ +MRB_BEGIN_DECL + +/** Declare a function that never returns. */ +#if __STDC_VERSION__ >= 201112L +# define mrb_noreturn _Noreturn +#elif defined __GNUC__ && !defined __STRICT_ANSI__ +# define mrb_noreturn __attribute__((noreturn)) +#elif defined _MSC_VER +# define mrb_noreturn __declspec(noreturn) +#else +# define mrb_noreturn +#endif + +/** Mark a function as deprecated. */ +#if defined __GNUC__ && !defined __STRICT_ANSI__ +# define mrb_deprecated __attribute__((deprecated)) +#elif defined _MSC_VER +# define mrb_deprecated __declspec(deprecated) +#else +# define mrb_deprecated +#endif + +/** Declare a function as always inlined. */ +#if defined(_MSC_VER) +# define MRB_INLINE static __inline +#else +# define MRB_INLINE static inline +#endif + + +/** Declare a public MRuby API function. */ +#if defined(MRB_BUILD_AS_DLL) +#if defined(MRB_CORE) || defined(MRB_LIB) +# define MRB_API __declspec(dllexport) +#else +# define MRB_API __declspec(dllimport) +#endif +#else +# define MRB_API extern +#endif + +MRB_END_DECL + +#endif /* MRUBY_COMMON_H */ diff --git a/web/server/h2o/libh2o/deps/mruby/include/mruby/compile.h b/web/server/h2o/libh2o/deps/mruby/include/mruby/compile.h new file mode 100644 index 00000000..d1ff0530 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/include/mruby/compile.h @@ -0,0 +1,195 @@ +/* +** mruby/compile.h - mruby parser +** +** See Copyright Notice in mruby.h +*/ + +#ifndef MRUBY_COMPILE_H +#define MRUBY_COMPILE_H + +#include "common.h" + +/** + * MRuby Compiler + */ +MRB_BEGIN_DECL + +#include + +struct mrb_jmpbuf; + +struct mrb_parser_state; +/* load context */ +typedef struct mrbc_context { + mrb_sym *syms; + int slen; + char *filename; + short lineno; + int (*partial_hook)(struct mrb_parser_state*); + void *partial_data; + struct RClass *target_class; + mrb_bool capture_errors:1; + mrb_bool dump_result:1; + mrb_bool no_exec:1; + mrb_bool keep_lv:1; + mrb_bool no_optimize:1; + + size_t parser_nerr; +} mrbc_context; + +MRB_API mrbc_context* mrbc_context_new(mrb_state *mrb); +MRB_API void mrbc_context_free(mrb_state *mrb, mrbc_context *cxt); +MRB_API const char *mrbc_filename(mrb_state *mrb, mrbc_context *c, const char *s); +MRB_API void mrbc_partial_hook(mrb_state *mrb, mrbc_context *c, int (*partial_hook)(struct mrb_parser_state*), void*data); + +/* AST node structure */ +typedef struct mrb_ast_node { + struct mrb_ast_node *car, *cdr; + uint16_t lineno, filename_index; +} mrb_ast_node; + +/* lexer states */ +enum mrb_lex_state_enum { + EXPR_BEG, /* ignore newline, +/- is a sign. */ + EXPR_END, /* newline significant, +/- is an operator. */ + EXPR_ENDARG, /* ditto, and unbound braces. */ + EXPR_ENDFN, /* ditto, and unbound braces. */ + EXPR_ARG, /* newline significant, +/- is an operator. */ + EXPR_CMDARG, /* newline significant, +/- is an operator. */ + EXPR_MID, /* newline significant, +/- is an operator. */ + EXPR_FNAME, /* ignore newline, no reserved words. */ + EXPR_DOT, /* right after '.' or '::', no reserved words. */ + EXPR_CLASS, /* immediate after 'class', no here document. */ + EXPR_VALUE, /* alike EXPR_BEG but label is disallowed. */ + EXPR_MAX_STATE +}; + +/* saved error message */ +struct mrb_parser_message { + int lineno; + int column; + char* message; +}; + +#define STR_FUNC_PARSING 0x01 +#define STR_FUNC_EXPAND 0x02 +#define STR_FUNC_REGEXP 0x04 +#define STR_FUNC_WORD 0x08 +#define STR_FUNC_SYMBOL 0x10 +#define STR_FUNC_ARRAY 0x20 +#define STR_FUNC_HEREDOC 0x40 +#define STR_FUNC_XQUOTE 0x80 + +enum mrb_string_type { + str_not_parsing = (0), + str_squote = (STR_FUNC_PARSING), + str_dquote = (STR_FUNC_PARSING|STR_FUNC_EXPAND), + str_regexp = (STR_FUNC_PARSING|STR_FUNC_REGEXP|STR_FUNC_EXPAND), + str_sword = (STR_FUNC_PARSING|STR_FUNC_WORD|STR_FUNC_ARRAY), + str_dword = (STR_FUNC_PARSING|STR_FUNC_WORD|STR_FUNC_ARRAY|STR_FUNC_EXPAND), + str_ssym = (STR_FUNC_PARSING|STR_FUNC_SYMBOL), + str_ssymbols = (STR_FUNC_PARSING|STR_FUNC_SYMBOL|STR_FUNC_ARRAY), + str_dsymbols = (STR_FUNC_PARSING|STR_FUNC_SYMBOL|STR_FUNC_ARRAY|STR_FUNC_EXPAND), + str_heredoc = (STR_FUNC_PARSING|STR_FUNC_HEREDOC), + str_xquote = (STR_FUNC_PARSING|STR_FUNC_XQUOTE|STR_FUNC_EXPAND), +}; + +/* heredoc structure */ +struct mrb_parser_heredoc_info { + mrb_bool allow_indent:1; + mrb_bool line_head:1; + enum mrb_string_type type; + const char *term; + int term_len; + mrb_ast_node *doc; +}; + +#define MRB_PARSER_TOKBUF_MAX 65536 +#define MRB_PARSER_TOKBUF_SIZE 256 + +/* parser structure */ +struct mrb_parser_state { + mrb_state *mrb; + struct mrb_pool *pool; + mrb_ast_node *cells; + const char *s, *send; +#ifndef MRB_DISABLE_STDIO + FILE *f; +#endif + mrbc_context *cxt; + char const *filename; + int lineno; + int column; + + enum mrb_lex_state_enum lstate; + mrb_ast_node *lex_strterm; /* (type nest_level beg . end) */ + + unsigned int cond_stack; + unsigned int cmdarg_stack; + int paren_nest; + int lpar_beg; + int in_def, in_single; + mrb_bool cmd_start:1; + mrb_ast_node *locals; + + mrb_ast_node *pb; + char *tokbuf; + char buf[MRB_PARSER_TOKBUF_SIZE]; + int tidx; + int tsiz; + + mrb_ast_node *all_heredocs; /* list of mrb_parser_heredoc_info* */ + mrb_ast_node *heredocs_from_nextline; + mrb_ast_node *parsing_heredoc; + mrb_ast_node *lex_strterm_before_heredoc; + mrb_bool heredoc_end_now:1; /* for mirb */ + + void *ylval; + + size_t nerr; + size_t nwarn; + mrb_ast_node *tree; + + mrb_bool no_optimize:1; + mrb_bool capture_errors:1; + struct mrb_parser_message error_buffer[10]; + struct mrb_parser_message warn_buffer[10]; + + mrb_sym* filename_table; + size_t filename_table_length; + int current_filename_index; + + struct mrb_jmpbuf* jmp; +}; + +MRB_API struct mrb_parser_state* mrb_parser_new(mrb_state*); +MRB_API void mrb_parser_free(struct mrb_parser_state*); +MRB_API void mrb_parser_parse(struct mrb_parser_state*,mrbc_context*); +MRB_API double mrb_float_read(const char*, char**); + +MRB_API void mrb_parser_set_filename(struct mrb_parser_state*, char const*); +MRB_API char const* mrb_parser_get_filename(struct mrb_parser_state*, uint16_t idx); + +/* utility functions */ +#ifndef MRB_DISABLE_STDIO +MRB_API struct mrb_parser_state* mrb_parse_file(mrb_state*,FILE*,mrbc_context*); +#endif +MRB_API struct mrb_parser_state* mrb_parse_string(mrb_state*,const char*,mrbc_context*); +MRB_API struct mrb_parser_state* mrb_parse_nstring(mrb_state*,const char*,size_t,mrbc_context*); +MRB_API struct RProc* mrb_generate_code(mrb_state*, struct mrb_parser_state*); +MRB_API mrb_value mrb_load_exec(mrb_state *mrb, struct mrb_parser_state *p, mrbc_context *c); + +/* program load functions */ +#ifndef MRB_DISABLE_STDIO +MRB_API mrb_value mrb_load_file(mrb_state*,FILE*); +MRB_API mrb_value mrb_load_file_cxt(mrb_state*,FILE*, mrbc_context *cxt); +#endif +MRB_API mrb_value mrb_load_string(mrb_state *mrb, const char *s); +MRB_API mrb_value mrb_load_nstring(mrb_state *mrb, const char *s, size_t len); +MRB_API mrb_value mrb_load_string_cxt(mrb_state *mrb, const char *s, mrbc_context *cxt); +MRB_API mrb_value mrb_load_nstring_cxt(mrb_state *mrb, const char *s, size_t len, mrbc_context *cxt); + +/** @} */ +MRB_END_DECL + +#endif /* MRUBY_COMPILE_H */ diff --git a/web/server/h2o/libh2o/deps/mruby/include/mruby/data.h b/web/server/h2o/libh2o/deps/mruby/include/mruby/data.h new file mode 100644 index 00000000..59047052 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/include/mruby/data.h @@ -0,0 +1,75 @@ +/* +** mruby/data.h - Data class +** +** See Copyright Notice in mruby.h +*/ + +#ifndef MRUBY_DATA_H +#define MRUBY_DATA_H + +#include "common.h" + +/** + * Custom C wrapped data. + * + * Defining Ruby wrappers around native objects. + */ +MRB_BEGIN_DECL + +/** + * Custom data type description. + */ +typedef struct mrb_data_type { + /** data type name */ + const char *struct_name; + + /** data type release function pointer */ + void (*dfree)(mrb_state *mrb, void*); +} mrb_data_type; + +struct RData { + MRB_OBJECT_HEADER; + struct iv_tbl *iv; + const mrb_data_type *type; + void *data; +}; + +MRB_API struct RData *mrb_data_object_alloc(mrb_state *mrb, struct RClass* klass, void *datap, const mrb_data_type *type); + +#define Data_Wrap_Struct(mrb,klass,type,ptr)\ + mrb_data_object_alloc(mrb,klass,ptr,type) + +#define Data_Make_Struct(mrb,klass,strct,type,sval,data) do { \ + sval = mrb_malloc(mrb, sizeof(strct)); \ + { static const strct zero = { 0 }; *sval = zero; };\ + data = Data_Wrap_Struct(mrb,klass,type,sval);\ +} while (0) + +#define RDATA(obj) ((struct RData *)(mrb_ptr(obj))) +#define DATA_PTR(d) (RDATA(d)->data) +#define DATA_TYPE(d) (RDATA(d)->type) +MRB_API void mrb_data_check_type(mrb_state *mrb, mrb_value, const mrb_data_type*); +MRB_API void *mrb_data_get_ptr(mrb_state *mrb, mrb_value, const mrb_data_type*); +#define DATA_GET_PTR(mrb,obj,dtype,type) (type*)mrb_data_get_ptr(mrb,obj,dtype) +MRB_API void *mrb_data_check_get_ptr(mrb_state *mrb, mrb_value, const mrb_data_type*); +#define DATA_CHECK_GET_PTR(mrb,obj,dtype,type) (type*)mrb_data_check_get_ptr(mrb,obj,dtype) + +/* obsolete functions and macros */ +#define mrb_data_check_and_get(mrb,obj,dtype) mrb_data_get_ptr(mrb,obj,dtype) +#define mrb_get_datatype(mrb,val,type) mrb_data_get_ptr(mrb, val, type) +#define mrb_check_datatype(mrb,val,type) mrb_data_get_ptr(mrb, val, type) +#define Data_Get_Struct(mrb,obj,type,sval) do {\ + *(void**)&sval = mrb_data_get_ptr(mrb, obj, type); \ +} while (0) + +static inline void +mrb_data_init(mrb_value v, void *ptr, const mrb_data_type *type) +{ + mrb_assert(mrb_type(v) == MRB_TT_DATA); + DATA_PTR(v) = ptr; + DATA_TYPE(v) = type; +} + +MRB_END_DECL + +#endif /* MRUBY_DATA_H */ diff --git a/web/server/h2o/libh2o/deps/mruby/include/mruby/debug.h b/web/server/h2o/libh2o/deps/mruby/include/mruby/debug.h new file mode 100644 index 00000000..d1de3488 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/include/mruby/debug.h @@ -0,0 +1,66 @@ +/* +** mruby/debug.h - mruby debug info +** +** See Copyright Notice in mruby.h +*/ + +#ifndef MRUBY_DEBUG_H +#define MRUBY_DEBUG_H + +#include "common.h" + +/** + * MRuby Debugging. + */ +MRB_BEGIN_DECL + +typedef enum mrb_debug_line_type { + mrb_debug_line_ary = 0, + mrb_debug_line_flat_map = 1 +} mrb_debug_line_type; + +typedef struct mrb_irep_debug_info_line { + uint32_t start_pos; + uint16_t line; +} mrb_irep_debug_info_line; + +typedef struct mrb_irep_debug_info_file { + uint32_t start_pos; + const char *filename; + mrb_sym filename_sym; + uint32_t line_entry_count; + mrb_debug_line_type line_type; + union { + void *ptr; + mrb_irep_debug_info_line *flat_map; + uint16_t *ary; + } lines; +} mrb_irep_debug_info_file; + +typedef struct mrb_irep_debug_info { + uint32_t pc_count; + uint16_t flen; + mrb_irep_debug_info_file **files; +} mrb_irep_debug_info; + +/* + * get line from irep's debug info and program counter + * @return returns NULL if not found + */ +MRB_API const char *mrb_debug_get_filename(mrb_irep *irep, ptrdiff_t pc); + +/* + * get line from irep's debug info and program counter + * @return returns -1 if not found + */ +MRB_API int32_t mrb_debug_get_line(mrb_irep *irep, ptrdiff_t pc); + +MRB_API mrb_irep_debug_info_file *mrb_debug_info_append_file( + mrb_state *mrb, mrb_irep *irep, + uint32_t start_pos, uint32_t end_pos); +MRB_API mrb_irep_debug_info *mrb_debug_info_alloc(mrb_state *mrb, mrb_irep *irep); +MRB_API void mrb_debug_info_free(mrb_state *mrb, mrb_irep_debug_info *d); + +MRB_END_DECL + +#endif /* MRUBY_DEBUG_H */ diff --git a/web/server/h2o/libh2o/deps/mruby/include/mruby/dump.h b/web/server/h2o/libh2o/deps/mruby/include/mruby/dump.h new file mode 100644 index 00000000..f56d66a3 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/include/mruby/dump.h @@ -0,0 +1,196 @@ +/* +** mruby/dump.h - mruby binary dumper (mrbc binary format) +** +** See Copyright Notice in mruby.h +*/ + +#ifndef MRUBY_DUMP_H +#define MRUBY_DUMP_H + +#include +#include +#include "common.h" + +/** + * Dumping compiled mruby script. + */ +MRB_BEGIN_DECL + +#define DUMP_DEBUG_INFO 1 +#define DUMP_ENDIAN_BIG 2 +#define DUMP_ENDIAN_LIL 4 +#define DUMP_ENDIAN_NAT 6 +#define DUMP_ENDIAN_MASK 6 + +int mrb_dump_irep(mrb_state *mrb, mrb_irep *irep, uint8_t flags, uint8_t **bin, size_t *bin_size); +#ifndef MRB_DISABLE_STDIO +int mrb_dump_irep_binary(mrb_state*, mrb_irep*, uint8_t, FILE*); +int mrb_dump_irep_cfunc(mrb_state *mrb, mrb_irep*, uint8_t flags, FILE *f, const char *initname); +mrb_irep *mrb_read_irep_file(mrb_state*, FILE*); +MRB_API mrb_value mrb_load_irep_file(mrb_state*,FILE*); +MRB_API mrb_value mrb_load_irep_file_cxt(mrb_state*, FILE*, mrbc_context*); +#endif +MRB_API mrb_irep *mrb_read_irep(mrb_state*, const uint8_t*); + +/* dump/load error code + * + * NOTE: MRB_DUMP_GENERAL_FAILURE is caused by + * unspecified issues like malloc failed. + */ +#define MRB_DUMP_OK 0 +#define MRB_DUMP_GENERAL_FAILURE (-1) +#define MRB_DUMP_WRITE_FAULT (-2) +#define MRB_DUMP_READ_FAULT (-3) +#define MRB_DUMP_CRC_ERROR (-4) +#define MRB_DUMP_INVALID_FILE_HEADER (-5) +#define MRB_DUMP_INVALID_IREP (-6) +#define MRB_DUMP_INVALID_ARGUMENT (-7) + +/* null symbol length */ +#define MRB_DUMP_NULL_SYM_LEN 0xFFFF + +/* Rite Binary File header */ +#define RITE_BINARY_IDENT "RITE" +#define RITE_BINARY_IDENT_LIL "ETIR" +#define RITE_BINARY_FORMAT_VER "0004" +#define RITE_COMPILER_NAME "MATZ" +#define RITE_COMPILER_VERSION "0000" + +#define RITE_VM_VER "0000" + +#define RITE_BINARY_EOF "END\0" +#define RITE_SECTION_IREP_IDENT "IREP" +#define RITE_SECTION_LINENO_IDENT "LINE" +#define RITE_SECTION_DEBUG_IDENT "DBG\0" +#define RITE_SECTION_LV_IDENT "LVAR" + +#define MRB_DUMP_DEFAULT_STR_LEN 128 +#define MRB_DUMP_ALIGNMENT sizeof(uint32_t) + +/* binary header */ +struct rite_binary_header { + uint8_t binary_ident[4]; /* Binary Identifier */ + uint8_t binary_version[4]; /* Binary Format Version */ + uint8_t binary_crc[2]; /* Binary CRC */ + uint8_t binary_size[4]; /* Binary Size */ + uint8_t compiler_name[4]; /* Compiler name */ + uint8_t compiler_version[4]; +}; + +/* section header */ +#define RITE_SECTION_HEADER \ + uint8_t section_ident[4]; \ + uint8_t section_size[4] + +struct rite_section_header { + RITE_SECTION_HEADER; +}; + +struct rite_section_irep_header { + RITE_SECTION_HEADER; + + uint8_t rite_version[4]; /* Rite Instruction Specification Version */ +}; + +struct rite_section_lineno_header { + RITE_SECTION_HEADER; +}; + +struct rite_section_debug_header { + RITE_SECTION_HEADER; +}; + +struct rite_section_lv_header { + RITE_SECTION_HEADER; +}; + +#define RITE_LV_NULL_MARK UINT16_MAX + +struct rite_binary_footer { + RITE_SECTION_HEADER; +}; + +static inline int +bigendian_p() +{ + int i; + char *p; + + i = 1; + p = (char*)&i; + return p[0]?0:1; +} + +static inline size_t +uint8_to_bin(uint8_t s, uint8_t *bin) +{ + *bin = s; + return sizeof(uint8_t); +} + +static inline size_t +uint16_to_bin(uint16_t s, uint8_t *bin) +{ + *bin++ = (s >> 8) & 0xff; + *bin = s & 0xff; + return sizeof(uint16_t); +} + +static inline size_t +uint32_to_bin(uint32_t l, uint8_t *bin) +{ + *bin++ = (l >> 24) & 0xff; + *bin++ = (l >> 16) & 0xff; + *bin++ = (l >> 8) & 0xff; + *bin = l & 0xff; + return sizeof(uint32_t); +} + +static inline size_t +uint32l_to_bin(uint32_t l, uint8_t *bin) +{ + bin[3] = (l >> 24) & 0xff; + bin[2] = (l >> 16) & 0xff; + bin[1] = (l >> 8) & 0xff; + bin[0] = l & 0xff; + return sizeof(uint32_t); +} + +static inline uint32_t +bin_to_uint32(const uint8_t *bin) +{ + return (uint32_t)bin[0] << 24 | + (uint32_t)bin[1] << 16 | + (uint32_t)bin[2] << 8 | + (uint32_t)bin[3]; +} + +static inline uint32_t +bin_to_uint32l(const uint8_t *bin) +{ + return (uint32_t)bin[3] << 24 | + (uint32_t)bin[2] << 16 | + (uint32_t)bin[1] << 8 | + (uint32_t)bin[0]; +} + +static inline uint16_t +bin_to_uint16(const uint8_t *bin) +{ + return (uint16_t)bin[0] << 8 | + (uint16_t)bin[1]; +} + +static inline uint8_t +bin_to_uint8(const uint8_t *bin) +{ + return (uint8_t)bin[0]; +} + +MRB_END_DECL + +/** @internal crc.c */ +uint16_t +calc_crc_16_ccitt(const uint8_t *src, size_t nbytes, uint16_t crc); + +#endif /* MRUBY_DUMP_H */ diff --git a/web/server/h2o/libh2o/deps/mruby/include/mruby/error.h b/web/server/h2o/libh2o/deps/mruby/include/mruby/error.h new file mode 100644 index 00000000..0a262550 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/include/mruby/error.h @@ -0,0 +1,76 @@ +/* +** mruby/error.h - Exception class +** +** See Copyright Notice in mruby.h +*/ + +#ifndef MRUBY_ERROR_H +#define MRUBY_ERROR_H + +#include "common.h" + +/** + * MRuby error handling. + */ +MRB_BEGIN_DECL + +struct RException { + MRB_OBJECT_HEADER; + struct iv_tbl *iv; +}; + +#define mrb_exc_ptr(v) ((struct RException*)mrb_ptr(v)) + +MRB_API void mrb_sys_fail(mrb_state *mrb, const char *mesg); +MRB_API mrb_value mrb_exc_new_str(mrb_state *mrb, struct RClass* c, mrb_value str); +#define mrb_exc_new_str_lit(mrb, c, lit) mrb_exc_new_str(mrb, c, mrb_str_new_lit(mrb, lit)) +MRB_API mrb_value mrb_make_exception(mrb_state *mrb, int argc, const mrb_value *argv); +MRB_API mrb_value mrb_exc_backtrace(mrb_state *mrb, mrb_value exc); +MRB_API mrb_value mrb_get_backtrace(mrb_state *mrb); +MRB_API mrb_noreturn void mrb_no_method_error(mrb_state *mrb, mrb_sym id, mrb_value args, const char *fmt, ...); + +/* declaration for fail method */ +MRB_API mrb_value mrb_f_raise(mrb_state*, mrb_value); + +struct RBreak { + MRB_OBJECT_HEADER; + struct iv_tbl *iv; + struct RProc *proc; + mrb_value val; +}; + +/** + * Protect + * + * @mrbgem mruby-error + */ +MRB_API mrb_value mrb_protect(mrb_state *mrb, mrb_func_t body, mrb_value data, mrb_bool *state); + +/** + * Ensure + * + * @mrbgem mruby-error + */ +MRB_API mrb_value mrb_ensure(mrb_state *mrb, mrb_func_t body, mrb_value b_data, + mrb_func_t ensure, mrb_value e_data); + +/** + * Rescue + * + * @mrbgem mruby-error + */ +MRB_API mrb_value mrb_rescue(mrb_state *mrb, mrb_func_t body, mrb_value b_data, + mrb_func_t rescue, mrb_value r_data); + +/** + * Rescue exception + * + * @mrbgem mruby-error + */ +MRB_API mrb_value mrb_rescue_exceptions(mrb_state *mrb, mrb_func_t body, mrb_value b_data, + mrb_func_t rescue, mrb_value r_data, + mrb_int len, struct RClass **classes); + +MRB_END_DECL + +#endif /* MRUBY_ERROR_H */ diff --git a/web/server/h2o/libh2o/deps/mruby/include/mruby/gc.h b/web/server/h2o/libh2o/deps/mruby/include/mruby/gc.h new file mode 100644 index 00000000..ce214aa5 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/include/mruby/gc.h @@ -0,0 +1,80 @@ +/* +** mruby/gc.h - garbage collector for mruby +** +** See Copyright Notice in mruby.h +*/ + +#ifndef MRUBY_GC_H +#define MRUBY_GC_H + +#include "common.h" + +/** + * Uncommon memory management stuffs. + */ +MRB_BEGIN_DECL + + +struct mrb_state; + +#define MRB_EACH_OBJ_OK 0 +#define MRB_EACH_OBJ_BREAK 1 +typedef int (mrb_each_object_callback)(struct mrb_state *mrb, struct RBasic *obj, void *data); +void mrb_objspace_each_objects(struct mrb_state *mrb, mrb_each_object_callback *callback, void *data); +MRB_API void mrb_free_context(struct mrb_state *mrb, struct mrb_context *c); + +#ifndef MRB_GC_ARENA_SIZE +#define MRB_GC_ARENA_SIZE 100 +#endif + +typedef enum { + MRB_GC_STATE_ROOT = 0, + MRB_GC_STATE_MARK, + MRB_GC_STATE_SWEEP +} mrb_gc_state; + +typedef struct mrb_heap_page { + struct RBasic *freelist; + struct mrb_heap_page *prev; + struct mrb_heap_page *next; + struct mrb_heap_page *free_next; + struct mrb_heap_page *free_prev; + mrb_bool old:1; + void *objects[]; +} mrb_heap_page; + +typedef struct mrb_gc { + mrb_heap_page *heaps; /* heaps for GC */ + mrb_heap_page *sweeps; + mrb_heap_page *free_heaps; + size_t live; /* count of live objects */ +#ifdef MRB_GC_FIXED_ARENA + struct RBasic *arena[MRB_GC_ARENA_SIZE]; /* GC protection array */ +#else + struct RBasic **arena; /* GC protection array */ + int arena_capa; +#endif + int arena_idx; + + mrb_gc_state state; /* state of gc */ + int current_white_part; /* make white object by white_part */ + struct RBasic *gray_list; /* list of gray objects to be traversed incrementally */ + struct RBasic *atomic_gray_list; /* list of objects to be traversed atomically */ + size_t live_after_mark; + size_t threshold; + int interval_ratio; + int step_ratio; + mrb_bool iterating :1; + mrb_bool disabled :1; + mrb_bool full :1; + mrb_bool generational :1; + mrb_bool out_of_memory :1; + size_t majorgc_old_threshold; +} mrb_gc; + +MRB_API mrb_bool +mrb_object_dead_p(struct mrb_state *mrb, struct RBasic *object); + +MRB_END_DECL + +#endif /* MRUBY_GC_H */ diff --git a/web/server/h2o/libh2o/deps/mruby/include/mruby/hash.h b/web/server/h2o/libh2o/deps/mruby/include/mruby/hash.h new file mode 100644 index 00000000..1a870785 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/include/mruby/hash.h @@ -0,0 +1,182 @@ +/* +** mruby/hash.h - Hash class +** +** See Copyright Notice in mruby.h +*/ + +#ifndef MRUBY_HASH_H +#define MRUBY_HASH_H + +#include "common.h" +#include + +/** + * Hash class + */ +MRB_BEGIN_DECL + +struct RHash { + MRB_OBJECT_HEADER; + struct iv_tbl *iv; + struct kh_ht *ht; +}; + +#define mrb_hash_ptr(v) ((struct RHash*)(mrb_ptr(v))) +#define mrb_hash_value(p) mrb_obj_value((void*)(p)) + +MRB_API mrb_value mrb_hash_new_capa(mrb_state*, mrb_int); + +/* + * Initializes a new hash. + * + * Equivalent to: + * + * Hash.new + * + * @param mrb The mruby state reference. + * @return The initialized hash. + */ +MRB_API mrb_value mrb_hash_new(mrb_state *mrb); + +/* + * Sets a keys and values to hashes. + * + * Equivalent to: + * + * hash[key] = val + * + * @param mrb The mruby state reference. + * @param hash The target hash. + * @param key The key to set. + * @param val The value to set. + * @return The value. + */ +MRB_API void mrb_hash_set(mrb_state *mrb, mrb_value hash, mrb_value key, mrb_value val); + +/* + * Gets a value from a key. If the key is not found, the default of the + * hash is used. + * + * Equivalent to: + * + * hash[key] + * + * @param mrb The mruby state reference. + * @param hash The target hash. + * @param key The key to get. + * @return The found value. + */ +MRB_API mrb_value mrb_hash_get(mrb_state *mrb, mrb_value hash, mrb_value key); + +/* + * Gets a value from a key. If the key is not found, the default parameter is + * used. + * + * Equivalent to: + * + * hash.hash_key?(key) ? hash[key] : def + * + * @param mrb The mruby state reference. + * @param hash The target hash. + * @param key The key to get. + * @param def The default value. + * @return The found value. + */ +MRB_API mrb_value mrb_hash_fetch(mrb_state *mrb, mrb_value hash, mrb_value key, mrb_value def); + +/* + * Deletes hash key and value pair. + * + * Equivalent to: + * + * hash.delete(key) + * + * @param mrb The mruby state reference. + * @param hash The target hash. + * @param key The key to delete. + * @return The deleted value. + */ +MRB_API mrb_value mrb_hash_delete_key(mrb_state *mrb, mrb_value hash, mrb_value key); + +/* + * Gets an array of keys. + * + * Equivalent to: + * + * hash.keys + * + * @param mrb The mruby state reference. + * @param hash The target hash. + * @return An array with the keys of the hash. + */ +MRB_API mrb_value mrb_hash_keys(mrb_state *mrb, mrb_value hash); +MRB_API mrb_value mrb_check_hash_type(mrb_state *mrb, mrb_value hash); + +/* + * Check if the hash is empty + * + * Equivalent to: + * + * hash.empty? + * + * @param mrb The mruby state reference. + * @param self The target hash. + * @return True if the hash is empty, false otherwise. + */ +MRB_API mrb_value mrb_hash_empty_p(mrb_state *mrb, mrb_value self); + +/* + * Gets an array of values. + * + * Equivalent to: + * + * hash.values + * + * @param mrb The mruby state reference. + * @param hash The target hash. + * @return An array with the values of the hash. + */ +MRB_API mrb_value mrb_hash_values(mrb_state *mrb, mrb_value hash); + +/* + * Clears the hash. + * + * Equivalent to: + * + * hash.clear + * + * @param mrb The mruby state reference. + * @param hash The target hash. + * @return The hash + */ +MRB_API mrb_value mrb_hash_clear(mrb_state *mrb, mrb_value hash); + +/* declaration of struct kh_ht */ +/* be careful when you touch the internal */ +typedef struct { + mrb_value v; + mrb_int n; +} mrb_hash_value; + +KHASH_DECLARE(ht, mrb_value, mrb_hash_value, TRUE) + +/* RHASH_TBL allocates st_table if not available. */ +#define RHASH(obj) ((struct RHash*)(mrb_ptr(obj))) +#define RHASH_TBL(h) (RHASH(h)->ht) +#define RHASH_IFNONE(h) mrb_iv_get(mrb, (h), mrb_intern_lit(mrb, "ifnone")) +#define RHASH_PROCDEFAULT(h) RHASH_IFNONE(h) +MRB_API struct kh_ht * mrb_hash_tbl(mrb_state *mrb, mrb_value hash); + +#define MRB_HASH_DEFAULT 1 +#define MRB_HASH_PROC_DEFAULT 2 +#define MRB_RHASH_DEFAULT_P(h) (RHASH(h)->flags & MRB_HASH_DEFAULT) +#define MRB_RHASH_PROCDEFAULT_P(h) (RHASH(h)->flags & MRB_HASH_PROC_DEFAULT) + +/* GC functions */ +void mrb_gc_mark_hash(mrb_state*, struct RHash*); +size_t mrb_gc_mark_hash_size(mrb_state*, struct RHash*); +void mrb_gc_free_hash(mrb_state*, struct RHash*); + +MRB_END_DECL + +#endif /* MRUBY_HASH_H */ diff --git a/web/server/h2o/libh2o/deps/mruby/include/mruby/irep.h b/web/server/h2o/libh2o/deps/mruby/include/mruby/irep.h new file mode 100644 index 00000000..2717b09c --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/include/mruby/irep.h @@ -0,0 +1,64 @@ +/* +** mruby/irep.h - mrb_irep structure +** +** See Copyright Notice in mruby.h +*/ + +#ifndef MRUBY_IREP_H +#define MRUBY_IREP_H + +#include "common.h" +#include + +/** + * Compiled mruby scripts. + */ +MRB_BEGIN_DECL + +enum irep_pool_type { + IREP_TT_STRING, + IREP_TT_FIXNUM, + IREP_TT_FLOAT, +}; + +struct mrb_locals { + mrb_sym name; + uint16_t r; +}; + +/* Program data array struct */ +typedef struct mrb_irep { + uint16_t nlocals; /* Number of local variables */ + uint16_t nregs; /* Number of register variables */ + uint8_t flags; + + mrb_code *iseq; + mrb_value *pool; + mrb_sym *syms; + struct mrb_irep **reps; + + struct mrb_locals *lv; + /* debug info */ + mrb_bool own_filename; + const char *filename; + uint16_t *lines; + struct mrb_irep_debug_info* debug_info; + + int ilen, plen, slen, rlen, refcnt; + + struct mrb_irep *outer; /* Refers outer scope */ + struct RClass *target_class; +} mrb_irep; + +#define MRB_ISEQ_NO_FREE 1 + +MRB_API mrb_irep *mrb_add_irep(mrb_state *mrb); +MRB_API mrb_value mrb_load_irep(mrb_state*, const uint8_t*); +MRB_API mrb_value mrb_load_irep_cxt(mrb_state*, const uint8_t*, mrbc_context*); +void mrb_irep_free(mrb_state*, struct mrb_irep*); +void mrb_irep_incref(mrb_state*, struct mrb_irep*); +void mrb_irep_decref(mrb_state*, struct mrb_irep*); + +MRB_END_DECL + +#endif /* MRUBY_IREP_H */ diff --git a/web/server/h2o/libh2o/deps/mruby/include/mruby/istruct.h b/web/server/h2o/libh2o/deps/mruby/include/mruby/istruct.h new file mode 100644 index 00000000..4d2393cc --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/include/mruby/istruct.h @@ -0,0 +1,47 @@ +/* +** mruby/istruct.h - Inline structures +** +** See Copyright Notice in mruby.h +*/ + +#ifndef MRUBY_ISTRUCT_H +#define MRUBY_ISTRUCT_H + +#include "common.h" +#include + +/** + * Inline structures that fit in RVALUE + * + * They cannot have finalizer, and cannot have instance variables. + */ +MRB_BEGIN_DECL + +#define ISTRUCT_DATA_SIZE (sizeof(void*) * 3) + +struct RIstruct { + MRB_OBJECT_HEADER; + char inline_data[ISTRUCT_DATA_SIZE]; +}; + +#define RISTRUCT(obj) ((struct RIstruct*)(mrb_ptr(obj))) +#define ISTRUCT_PTR(obj) (RISTRUCT(obj)->inline_data) + +MRB_INLINE mrb_int mrb_istruct_size() +{ + return ISTRUCT_DATA_SIZE; +} + +MRB_INLINE void* mrb_istruct_ptr(mrb_value object) +{ + return ISTRUCT_PTR(object); +} + +MRB_INLINE void mrb_istruct_copy(mrb_value dest, mrb_value src) +{ + memcpy(ISTRUCT_PTR(dest), ISTRUCT_PTR(src), ISTRUCT_DATA_SIZE); +} + +MRB_END_DECL + +#endif /* MRUBY_ISTRUCT_H */ diff --git a/web/server/h2o/libh2o/deps/mruby/include/mruby/khash.h b/web/server/h2o/libh2o/deps/mruby/include/mruby/khash.h new file mode 100644 index 00000000..9c40c6b8 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/include/mruby/khash.h @@ -0,0 +1,274 @@ +/* +** mruby/khash.c - Hash for mruby +** +** See Copyright Notice in mruby.h +*/ + +#ifndef MRUBY_KHASH_H +#define MRUBY_KHASH_H + +#include + +#include +#include "common.h" + +/** + * khash definitions used in mruby's hash table. + */ +MRB_BEGIN_DECL + +typedef uint32_t khint_t; +typedef khint_t khiter_t; + +#ifndef KHASH_DEFAULT_SIZE +# define KHASH_DEFAULT_SIZE 32 +#endif +#define KHASH_MIN_SIZE 8 + +#define UPPER_BOUND(x) ((x)>>2|(x)>>1) + +/* extern uint8_t __m[]; */ + +/* mask for flags */ +static const uint8_t __m_empty[] = {0x02, 0x08, 0x20, 0x80}; +static const uint8_t __m_del[] = {0x01, 0x04, 0x10, 0x40}; +static const uint8_t __m_either[] = {0x03, 0x0c, 0x30, 0xc0}; + + +#define __ac_isempty(ed_flag, i) (ed_flag[(i)/4]&__m_empty[(i)%4]) +#define __ac_isdel(ed_flag, i) (ed_flag[(i)/4]&__m_del[(i)%4]) +#define __ac_iseither(ed_flag, i) (ed_flag[(i)/4]&__m_either[(i)%4]) +#define khash_power2(v) do { \ + v--;\ + v |= v >> 1;\ + v |= v >> 2;\ + v |= v >> 4;\ + v |= v >> 8;\ + v |= v >> 16;\ + v++;\ +} while (0) +#define khash_mask(h) ((h)->n_buckets-1) +#define khash_upper_bound(h) (UPPER_BOUND((h)->n_buckets)) + +/* declare struct kh_xxx and kh_xxx_funcs + + name: hash name + khkey_t: key data type + khval_t: value data type + kh_is_map: (0: hash set / 1: hash map) +*/ +#define KHASH_DECLARE(name, khkey_t, khval_t, kh_is_map) \ + typedef struct kh_##name { \ + khint_t n_buckets; \ + khint_t size; \ + khint_t n_occupied; \ + uint8_t *ed_flags; \ + khkey_t *keys; \ + khval_t *vals; \ + } kh_##name##_t; \ + void kh_alloc_##name(mrb_state *mrb, kh_##name##_t *h); \ + kh_##name##_t *kh_init_##name##_size(mrb_state *mrb, khint_t size); \ + kh_##name##_t *kh_init_##name(mrb_state *mrb); \ + void kh_destroy_##name(mrb_state *mrb, kh_##name##_t *h); \ + void kh_clear_##name(mrb_state *mrb, kh_##name##_t *h); \ + khint_t kh_get_##name(mrb_state *mrb, kh_##name##_t *h, khkey_t key); \ + khint_t kh_put_##name(mrb_state *mrb, kh_##name##_t *h, khkey_t key, int *ret); \ + void kh_resize_##name(mrb_state *mrb, kh_##name##_t *h, khint_t new_n_buckets); \ + void kh_del_##name(mrb_state *mrb, kh_##name##_t *h, khint_t x); \ + kh_##name##_t *kh_copy_##name(mrb_state *mrb, kh_##name##_t *h); + +static inline void +kh_fill_flags(uint8_t *p, uint8_t c, size_t len) +{ + while (len-- > 0) { + *p++ = c; + } +} + +/* define kh_xxx_funcs + + name: hash name + khkey_t: key data type + khval_t: value data type + kh_is_map: (0: hash set / 1: hash map) + __hash_func: hash function + __hash_equal: hash comparation function +*/ +#define KHASH_DEFINE(name, khkey_t, khval_t, kh_is_map, __hash_func, __hash_equal) \ + void kh_alloc_##name(mrb_state *mrb, kh_##name##_t *h) \ + { \ + khint_t sz = h->n_buckets; \ + size_t len = sizeof(khkey_t) + (kh_is_map ? sizeof(khval_t) : 0); \ + uint8_t *p = (uint8_t*)mrb_malloc(mrb, sizeof(uint8_t)*sz/4+len*sz); \ + h->size = h->n_occupied = 0; \ + h->keys = (khkey_t *)p; \ + h->vals = kh_is_map ? (khval_t *)(p+sizeof(khkey_t)*sz) : NULL; \ + h->ed_flags = p+len*sz; \ + kh_fill_flags(h->ed_flags, 0xaa, sz/4); \ + } \ + kh_##name##_t *kh_init_##name##_size(mrb_state *mrb, khint_t size) { \ + kh_##name##_t *h = (kh_##name##_t*)mrb_calloc(mrb, 1, sizeof(kh_##name##_t)); \ + if (size < KHASH_MIN_SIZE) \ + size = KHASH_MIN_SIZE; \ + khash_power2(size); \ + h->n_buckets = size; \ + kh_alloc_##name(mrb, h); \ + return h; \ + } \ + kh_##name##_t *kh_init_##name(mrb_state *mrb) { \ + return kh_init_##name##_size(mrb, KHASH_DEFAULT_SIZE); \ + } \ + void kh_destroy_##name(mrb_state *mrb, kh_##name##_t *h) \ + { \ + if (h) { \ + mrb_free(mrb, h->keys); \ + mrb_free(mrb, h); \ + } \ + } \ + void kh_clear_##name(mrb_state *mrb, kh_##name##_t *h) \ + { \ + (void)mrb; \ + if (h && h->ed_flags) { \ + kh_fill_flags(h->ed_flags, 0xaa, h->n_buckets/4); \ + h->size = h->n_occupied = 0; \ + } \ + } \ + khint_t kh_get_##name(mrb_state *mrb, kh_##name##_t *h, khkey_t key) \ + { \ + khint_t k = __hash_func(mrb,key) & khash_mask(h), step = 0; \ + (void)mrb; \ + while (!__ac_isempty(h->ed_flags, k)) { \ + if (!__ac_isdel(h->ed_flags, k)) { \ + if (__hash_equal(mrb,h->keys[k], key)) return k; \ + } \ + k = (k+(++step)) & khash_mask(h); \ + } \ + return kh_end(h); \ + } \ + void kh_resize_##name(mrb_state *mrb, kh_##name##_t *h, khint_t new_n_buckets) \ + { \ + if (new_n_buckets < KHASH_MIN_SIZE) \ + new_n_buckets = KHASH_MIN_SIZE; \ + khash_power2(new_n_buckets); \ + { \ + kh_##name##_t hh; \ + uint8_t *old_ed_flags = h->ed_flags; \ + khkey_t *old_keys = h->keys; \ + khval_t *old_vals = h->vals; \ + khint_t old_n_buckets = h->n_buckets; \ + khint_t i; \ + hh.n_buckets = new_n_buckets; \ + kh_alloc_##name(mrb, &hh); \ + /* relocate */ \ + for (i=0 ; in_occupied >= khash_upper_bound(h)) { \ + kh_resize_##name(mrb, h, h->n_buckets*2); \ + } \ + k = __hash_func(mrb,key) & khash_mask(h); \ + del_k = kh_end(h); \ + while (!__ac_isempty(h->ed_flags, k)) { \ + if (!__ac_isdel(h->ed_flags, k)) { \ + if (__hash_equal(mrb,h->keys[k], key)) { \ + if (ret) *ret = 0; \ + return k; \ + } \ + } \ + else if (del_k == kh_end(h)) { \ + del_k = k; \ + } \ + k = (k+(++step)) & khash_mask(h); \ + } \ + if (del_k != kh_end(h)) { \ + /* put at del */ \ + h->keys[del_k] = key; \ + h->ed_flags[del_k/4] &= ~__m_del[del_k%4]; \ + h->size++; \ + if (ret) *ret = 2; \ + return del_k; \ + } \ + else { \ + /* put at empty */ \ + h->keys[k] = key; \ + h->ed_flags[k/4] &= ~__m_empty[k%4]; \ + h->size++; \ + h->n_occupied++; \ + if (ret) *ret = 1; \ + return k; \ + } \ + } \ + void kh_del_##name(mrb_state *mrb, kh_##name##_t *h, khint_t x) \ + { \ + (void)mrb; \ + mrb_assert(x != h->n_buckets && !__ac_iseither(h->ed_flags, x)); \ + h->ed_flags[x/4] |= __m_del[x%4]; \ + h->size--; \ + } \ + kh_##name##_t *kh_copy_##name(mrb_state *mrb, kh_##name##_t *h) \ + { \ + kh_##name##_t *h2; \ + khiter_t k, k2; \ + \ + h2 = kh_init_##name(mrb); \ + for (k = kh_begin(h); k != kh_end(h); k++) { \ + if (kh_exist(h, k)) { \ + k2 = kh_put_##name(mrb, h2, kh_key(h, k), NULL); \ + if (kh_is_map) kh_value(h2, k2) = kh_value(h, k); \ + } \ + } \ + return h2; \ + } + + +#define khash_t(name) kh_##name##_t + +#define kh_init_size(name,mrb,size) kh_init_##name##_size(mrb,size) +#define kh_init(name,mrb) kh_init_##name(mrb) +#define kh_destroy(name, mrb, h) kh_destroy_##name(mrb, h) +#define kh_clear(name, mrb, h) kh_clear_##name(mrb, h) +#define kh_resize(name, mrb, h, s) kh_resize_##name(mrb, h, s) +#define kh_put(name, mrb, h, k) kh_put_##name(mrb, h, k, NULL) +#define kh_put2(name, mrb, h, k, r) kh_put_##name(mrb, h, k, r) +#define kh_get(name, mrb, h, k) kh_get_##name(mrb, h, k) +#define kh_del(name, mrb, h, k) kh_del_##name(mrb, h, k) +#define kh_copy(name, mrb, h) kh_copy_##name(mrb, h) + +#define kh_exist(h, x) (!__ac_iseither((h)->ed_flags, (x))) +#define kh_key(h, x) ((h)->keys[x]) +#define kh_val(h, x) ((h)->vals[x]) +#define kh_value(h, x) ((h)->vals[x]) +#define kh_begin(h) (khint_t)(0) +#define kh_end(h) ((h)->n_buckets) +#define kh_size(h) ((h)->size) +#define kh_n_buckets(h) ((h)->n_buckets) + +#define kh_int_hash_func(mrb,key) (khint_t)((key)^((key)<<2)^((key)>>2)) +#define kh_int_hash_equal(mrb,a, b) (a == b) +#define kh_int64_hash_func(mrb,key) (khint_t)((key)>>33^(key)^(key)<<11) +#define kh_int64_hash_equal(mrb,a, b) (a == b) +static inline khint_t __ac_X31_hash_string(const char *s) +{ + khint_t h = *s; + if (h) for (++s ; *s; ++s) h = (h << 5) - h + *s; + return h; +} +#define kh_str_hash_func(mrb,key) __ac_X31_hash_string(key) +#define kh_str_hash_equal(mrb,a, b) (strcmp(a, b) == 0) + +typedef const char *kh_cstr_t; + +MRB_END_DECL + +#endif /* MRUBY_KHASH_H */ diff --git a/web/server/h2o/libh2o/deps/mruby/include/mruby/numeric.h b/web/server/h2o/libh2o/deps/mruby/include/mruby/numeric.h new file mode 100644 index 00000000..40c8c4a2 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/include/mruby/numeric.h @@ -0,0 +1,155 @@ +/* +** mruby/numeric.h - Numeric, Integer, Float, Fixnum class +** +** See Copyright Notice in mruby.h +*/ + +#ifndef MRUBY_NUMERIC_H +#define MRUBY_NUMERIC_H + +#include "common.h" + +/** + * Numeric class and it's sub-classes. + * + * Integer, Float and Fixnum + */ +MRB_BEGIN_DECL + +#define TYPED_POSFIXABLE(f,t) ((f) <= (t)MRB_INT_MAX) +#define TYPED_NEGFIXABLE(f,t) ((f) >= (t)MRB_INT_MIN) +#define TYPED_FIXABLE(f,t) (TYPED_POSFIXABLE(f,t) && TYPED_NEGFIXABLE(f,t)) +#define POSFIXABLE(f) TYPED_POSFIXABLE(f,mrb_int) +#define NEGFIXABLE(f) TYPED_NEGFIXABLE(f,mrb_int) +#define FIXABLE(f) TYPED_FIXABLE(f,mrb_int) +#define FIXABLE_FLOAT(f) TYPED_FIXABLE(f,double) + +MRB_API mrb_value mrb_flo_to_fixnum(mrb_state *mrb, mrb_value val); +MRB_API mrb_value mrb_fixnum_to_str(mrb_state *mrb, mrb_value x, int base); +/* ArgumentError if format string doesn't match /%(\.[0-9]+)?[aAeEfFgG]/ */ +MRB_API mrb_value mrb_float_to_str(mrb_state *mrb, mrb_value x, const char *fmt); +MRB_API mrb_float mrb_to_flo(mrb_state *mrb, mrb_value x); + +mrb_value mrb_fixnum_plus(mrb_state *mrb, mrb_value x, mrb_value y); +mrb_value mrb_fixnum_minus(mrb_state *mrb, mrb_value x, mrb_value y); +mrb_value mrb_fixnum_mul(mrb_state *mrb, mrb_value x, mrb_value y); +mrb_value mrb_num_div(mrb_state *mrb, mrb_value x, mrb_value y); + +#ifndef __has_builtin + #define __has_builtin(x) 0 +#endif + +#if (defined(__GNUC__) && __GNUC__ >= 5) || \ + (__has_builtin(__builtin_add_overflow) && \ + __has_builtin(__builtin_sub_overflow) && \ + __has_builtin(__builtin_mul_overflow)) +# define MRB_HAVE_TYPE_GENERIC_CHECKED_ARITHMETIC_BUILTINS +#endif + +/* +// Clang 3.8 and 3.9 have problem compiling mruby in 32-bit mode, when MRB_INT64 is set +// because of missing __mulodi4 and similar functions in its runtime. We need to use custom +// implementation for them. +*/ +#ifdef MRB_HAVE_TYPE_GENERIC_CHECKED_ARITHMETIC_BUILTINS +#if defined(__clang__) && (__clang_major__ == 3) && (__clang_minor__ >= 8) && \ + defined(MRB_32BIT) && defined(MRB_INT64) +#undef MRB_HAVE_TYPE_GENERIC_CHECKED_ARITHMETIC_BUILTINS +#endif +#endif + +#ifdef MRB_HAVE_TYPE_GENERIC_CHECKED_ARITHMETIC_BUILTINS + +#ifndef MRB_WORD_BOXING +# define WBCHK(x) 0 +#else +# define WBCHK(x) !FIXABLE(x) +#endif + +static inline mrb_bool +mrb_int_add_overflow(mrb_int augend, mrb_int addend, mrb_int *sum) +{ + return __builtin_add_overflow(augend, addend, sum) || WBCHK(*sum); +} + +static inline mrb_bool +mrb_int_sub_overflow(mrb_int minuend, mrb_int subtrahend, mrb_int *difference) +{ + return __builtin_sub_overflow(minuend, subtrahend, difference) || WBCHK(*difference); +} + +static inline mrb_bool +mrb_int_mul_overflow(mrb_int multiplier, mrb_int multiplicand, mrb_int *product) +{ + return __builtin_mul_overflow(multiplier, multiplicand, product) || WBCHK(*product); +} + +#undef WBCHK + +#else + +#define MRB_UINT_MAKE2(n) uint ## n ## _t +#define MRB_UINT_MAKE(n) MRB_UINT_MAKE2(n) +#define mrb_uint MRB_UINT_MAKE(MRB_INT_BIT) + +#define MRB_INT_OVERFLOW_MASK ((mrb_uint)1 << (MRB_INT_BIT - 1 - MRB_FIXNUM_SHIFT)) + +static inline mrb_bool +mrb_int_add_overflow(mrb_int augend, mrb_int addend, mrb_int *sum) +{ + mrb_uint x = (mrb_uint)augend; + mrb_uint y = (mrb_uint)addend; + mrb_uint z = (mrb_uint)(x + y); + *sum = (mrb_int)z; + return !!(((x ^ z) & (y ^ z)) & MRB_INT_OVERFLOW_MASK); +} + +static inline mrb_bool +mrb_int_sub_overflow(mrb_int minuend, mrb_int subtrahend, mrb_int *difference) +{ + mrb_uint x = (mrb_uint)minuend; + mrb_uint y = (mrb_uint)subtrahend; + mrb_uint z = (mrb_uint)(x - y); + *difference = (mrb_int)z; + return !!(((x ^ z) & (~y ^ z)) & MRB_INT_OVERFLOW_MASK); +} + +static inline mrb_bool +mrb_int_mul_overflow(mrb_int multiplier, mrb_int multiplicand, mrb_int *product) +{ +#if MRB_INT_BIT == 32 + int64_t n = (int64_t)multiplier * multiplicand; + *product = (mrb_int)n; + return !FIXABLE(n); +#else + if (multiplier > 0) { + if (multiplicand > 0) { + if (multiplier > MRB_INT_MAX / multiplicand) return TRUE; + } + else { + if (multiplicand < MRB_INT_MAX / multiplier) return TRUE; + } + } + else { + if (multiplicand > 0) { + if (multiplier < MRB_INT_MAX / multiplicand) return TRUE; + } + else { + if (multiplier != 0 && multiplicand < MRB_INT_MAX / multiplier) return TRUE; + } + } + *product = multiplier * multiplicand; + return FALSE; +#endif +} + +#undef MRB_INT_OVERFLOW_MASK +#undef mrb_uint +#undef MRB_UINT_MAKE +#undef MRB_UINT_MAKE2 + +#endif + +MRB_END_DECL + +#endif /* MRUBY_NUMERIC_H */ diff --git a/web/server/h2o/libh2o/deps/mruby/include/mruby/object.h b/web/server/h2o/libh2o/deps/mruby/include/mruby/object.h new file mode 100644 index 00000000..9347981d --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/include/mruby/object.h @@ -0,0 +1,43 @@ +/* +** mruby/object.h - mruby object definition +** +** See Copyright Notice in mruby.h +*/ + +#ifndef MRUBY_OBJECT_H +#define MRUBY_OBJECT_H + +#define MRB_OBJECT_HEADER \ + enum mrb_vtype tt:8;\ + uint32_t color:3;\ + uint32_t flags:21;\ + struct RClass *c;\ + struct RBasic *gcnext + +#define MRB_FLAG_TEST(obj, flag) ((obj)->flags & flag) + + +struct RBasic { + MRB_OBJECT_HEADER; +}; +#define mrb_basic_ptr(v) ((struct RBasic*)(mrb_ptr(v))) + +#define MRB_FROZEN_P(o) ((o)->flags & MRB_FLAG_IS_FROZEN) +#define MRB_SET_FROZEN_FLAG(o) ((o)->flags |= MRB_FLAG_IS_FROZEN) +#define MRB_UNSET_FROZEN_FLAG(o) ((o)->flags &= ~MRB_FLAG_IS_FROZEN) + +struct RObject { + MRB_OBJECT_HEADER; + struct iv_tbl *iv; +}; +#define mrb_obj_ptr(v) ((struct RObject*)(mrb_ptr(v))) + +#define mrb_immediate_p(x) (mrb_type(x) < MRB_TT_HAS_BASIC) +#define mrb_special_const_p(x) mrb_immediate_p(x) + +struct RFiber { + MRB_OBJECT_HEADER; + struct mrb_context *cxt; +}; + +#endif /* MRUBY_OBJECT_H */ diff --git a/web/server/h2o/libh2o/deps/mruby/include/mruby/opcode.h b/web/server/h2o/libh2o/deps/mruby/include/mruby/opcode.h new file mode 100644 index 00000000..9a511627 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/include/mruby/opcode.h @@ -0,0 +1,161 @@ +/* +** mruby/opcode.h - RiteVM operation codes +** +** See Copyright Notice in mruby.h +*/ + +#ifndef MRUBY_OPCODE_H +#define MRUBY_OPCODE_H + +#define MAXARG_Bx (0xffff) +#define MAXARG_sBx (MAXARG_Bx>>1) /* 'sBx' is signed */ + +/* instructions: packed 32 bit */ +/* ------------------------------- */ +/* A:B:C:OP = 9: 9: 7: 7 */ +/* A:Bx:OP = 9:16: 7 */ +/* Ax:OP = 25: 7 */ +/* A:Bz:Cz:OP = 9:14: 2: 7 */ + +#define GET_OPCODE(i) ((int)(((mrb_code)(i)) & 0x7f)) +#define GETARG_A(i) ((int)((((mrb_code)(i)) >> 23) & 0x1ff)) +#define GETARG_B(i) ((int)((((mrb_code)(i)) >> 14) & 0x1ff)) +#define GETARG_C(i) ((int)((((mrb_code)(i)) >> 7) & 0x7f)) +#define GETARG_Bx(i) ((int)((((mrb_code)(i)) >> 7) & 0xffff)) +#define GETARG_sBx(i) ((int)(GETARG_Bx(i)-MAXARG_sBx)) +#define GETARG_Ax(i) ((int32_t)((((mrb_code)(i)) >> 7) & 0x1ffffff)) +#define GETARG_UNPACK_b(i,n1,n2) ((int)((((mrb_code)(i)) >> (7+(n2))) & (((1<<(n1))-1)))) +#define GETARG_UNPACK_c(i,n1,n2) ((int)((((mrb_code)(i)) >> 7) & (((1<<(n2))-1)))) +#define GETARG_b(i) GETARG_UNPACK_b(i,14,2) +#define GETARG_c(i) GETARG_UNPACK_c(i,14,2) + +#define MKOPCODE(op) ((op) & 0x7f) +#define MKARG_A(c) ((mrb_code)((c) & 0x1ff) << 23) +#define MKARG_B(c) ((mrb_code)((c) & 0x1ff) << 14) +#define MKARG_C(c) (((c) & 0x7f) << 7) +#define MKARG_Bx(v) ((mrb_code)((v) & 0xffff) << 7) +#define MKARG_sBx(v) MKARG_Bx((v)+MAXARG_sBx) +#define MKARG_Ax(v) ((mrb_code)((v) & 0x1ffffff) << 7) +#define MKARG_PACK(b,n1,c,n2) ((((b) & ((1<R(A+1) (Syms[B]=:>,C=1) */ + OP_GE,/* A B C R(A) := R(A)>=R(A+1) (Syms[B]=:>=,C=1) */ + + OP_ARRAY,/* A B C R(A) := ary_new(R(B),R(B+1)..R(B+C)) */ + OP_ARYCAT,/* A B ary_cat(R(A),R(B)) */ + OP_ARYPUSH,/* A B ary_push(R(A),R(B)) */ + OP_AREF,/* A B C R(A) := R(B)[C] */ + OP_ASET,/* A B C R(B)[C] := R(A) */ + OP_APOST,/* A B C *R(A),R(A+1)..R(A+C) := R(A) */ + + OP_STRING,/* A Bx R(A) := str_dup(Lit(Bx)) */ + OP_STRCAT,/* A B str_cat(R(A),R(B)) */ + + OP_HASH,/* A B C R(A) := hash_new(R(B),R(B+1)..R(B+C)) */ + OP_LAMBDA,/* A Bz Cz R(A) := lambda(SEQ[Bz],Cz) */ + OP_RANGE,/* A B C R(A) := range_new(R(B),R(B+1),C) */ + + OP_OCLASS,/* A R(A) := ::Object */ + OP_CLASS,/* A B R(A) := newclass(R(A),Syms(B),R(A+1)) */ + OP_MODULE,/* A B R(A) := newmodule(R(A),Syms(B)) */ + OP_EXEC,/* A Bx R(A) := blockexec(R(A),SEQ[Bx]) */ + OP_METHOD,/* A B R(A).newmethod(Syms(B),R(A+1)) */ + OP_SCLASS,/* A B R(A) := R(B).singleton_class */ + OP_TCLASS,/* A R(A) := target_class */ + + OP_DEBUG,/* A B C print R(A),R(B),R(C) */ + OP_STOP,/* stop VM */ + OP_ERR,/* Bx raise RuntimeError with message Lit(Bx) */ + + OP_RSVD1,/* reserved instruction #1 */ + OP_RSVD2,/* reserved instruction #2 */ + OP_RSVD3,/* reserved instruction #3 */ + OP_RSVD4,/* reserved instruction #4 */ + OP_RSVD5,/* reserved instruction #5 */ +}; + +#define OP_L_STRICT 1 +#define OP_L_CAPTURE 2 +#define OP_L_METHOD OP_L_STRICT +#define OP_L_LAMBDA (OP_L_STRICT|OP_L_CAPTURE) +#define OP_L_BLOCK OP_L_CAPTURE + +#define OP_R_NORMAL 0 +#define OP_R_BREAK 1 +#define OP_R_RETURN 2 + +#endif /* MRUBY_OPCODE_H */ diff --git a/web/server/h2o/libh2o/deps/mruby/include/mruby/proc.h b/web/server/h2o/libh2o/deps/mruby/include/mruby/proc.h new file mode 100644 index 00000000..9c266628 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/include/mruby/proc.h @@ -0,0 +1,83 @@ +/* +** mruby/proc.h - Proc class +** +** See Copyright Notice in mruby.h +*/ + +#ifndef MRUBY_PROC_H +#define MRUBY_PROC_H + +#include "common.h" +#include + +/** + * Proc class + */ +MRB_BEGIN_DECL + +struct REnv { + MRB_OBJECT_HEADER; + mrb_value *stack; + ptrdiff_t cioff; + union { + mrb_sym mid; + struct mrb_context *c; + } cxt; +}; + +#define MRB_SET_ENV_STACK_LEN(e,len) (e)->flags = (unsigned int)(len) +#define MRB_ENV_STACK_LEN(e) ((mrb_int)(e)->flags) +#define MRB_ENV_UNSHARE_STACK(e) ((e)->cioff = -1) +#define MRB_ENV_STACK_SHARED_P(e) ((e)->cioff >= 0) + +MRB_API void mrb_env_unshare(mrb_state*, struct REnv*); + +struct RProc { + MRB_OBJECT_HEADER; + union { + mrb_irep *irep; + mrb_func_t func; + } body; + struct RClass *target_class; + struct REnv *env; +}; + +/* aspec access */ +#define MRB_ASPEC_REQ(a) (((a) >> 18) & 0x1f) +#define MRB_ASPEC_OPT(a) (((a) >> 13) & 0x1f) +#define MRB_ASPEC_REST(a) (((a) >> 12) & 0x1) +#define MRB_ASPEC_POST(a) (((a) >> 7) & 0x1f) +#define MRB_ASPEC_KEY(a) (((a) >> 2) & 0x1f) +#define MRB_ASPEC_KDICT(a) ((a) & (1<<1)) +#define MRB_ASPEC_BLOCK(a) ((a) & 1) + +#define MRB_PROC_CFUNC 128 +#define MRB_PROC_CFUNC_P(p) (((p)->flags & MRB_PROC_CFUNC) != 0) +#define MRB_PROC_STRICT 256 +#define MRB_PROC_STRICT_P(p) (((p)->flags & MRB_PROC_STRICT) != 0) +#define MRB_PROC_ORPHAN 512 +#define MRB_PROC_ORPHAN_P(p) (((p)->flags & MRB_PROC_ORPHAN) != 0) + +#define mrb_proc_ptr(v) ((struct RProc*)(mrb_ptr(v))) + +struct RProc *mrb_proc_new(mrb_state*, mrb_irep*); +struct RProc *mrb_closure_new(mrb_state*, mrb_irep*); +MRB_API struct RProc *mrb_proc_new_cfunc(mrb_state*, mrb_func_t); +MRB_API struct RProc *mrb_closure_new_cfunc(mrb_state *mrb, mrb_func_t func, int nlocals); +void mrb_proc_copy(struct RProc *a, struct RProc *b); + +/* implementation of #send method */ +MRB_API mrb_value mrb_f_send(mrb_state *mrb, mrb_value self); + +/* following functions are defined in mruby-proc-ext so please include it when using */ +MRB_API struct RProc *mrb_proc_new_cfunc_with_env(mrb_state*, mrb_func_t, mrb_int, const mrb_value*); +MRB_API mrb_value mrb_proc_cfunc_env_get(mrb_state*, mrb_int); +/* old name */ +#define mrb_cfunc_env_get(mrb, idx) mrb_proc_cfunc_env_get(mrb, idx) + +#include +KHASH_DECLARE(mt, mrb_sym, struct RProc*, TRUE) + +MRB_END_DECL + +#endif /* MRUBY_PROC_H */ diff --git a/web/server/h2o/libh2o/deps/mruby/include/mruby/range.h b/web/server/h2o/libh2o/deps/mruby/include/mruby/range.h new file mode 100644 index 00000000..b166e586 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/include/mruby/range.h @@ -0,0 +1,49 @@ +/* +** mruby/range.h - Range class +** +** See Copyright Notice in mruby.h +*/ + +#ifndef MRUBY_RANGE_H +#define MRUBY_RANGE_H + +#include "common.h" + +/** + * Range class + */ +MRB_BEGIN_DECL + +typedef struct mrb_range_edges { + mrb_value beg; + mrb_value end; +} mrb_range_edges; + +struct RRange { + MRB_OBJECT_HEADER; + mrb_range_edges *edges; + mrb_bool excl : 1; +}; + +MRB_API struct RRange* mrb_range_ptr(mrb_state *mrb, mrb_value v); +#define mrb_range_raw_ptr(v) ((struct RRange*)mrb_ptr(v)) +#define mrb_range_value(p) mrb_obj_value((void*)(p)) + +/* + * Initializes a Range. + * + * If the third parameter is FALSE then it includes the last value in the range. + * If the third parameter is TRUE then it excludes the last value in the range. + * + * @param start the beginning value. + * @param end the ending value. + * @param exclude represents the inclusion or exclusion of the last value. + */ +MRB_API mrb_value mrb_range_new(mrb_state *mrb, mrb_value start, mrb_value end, mrb_bool exclude); + +MRB_API mrb_int mrb_range_beg_len(mrb_state *mrb, mrb_value range, mrb_int *begp, mrb_int *lenp, mrb_int len, mrb_bool trunc); +mrb_value mrb_get_values_at(mrb_state *mrb, mrb_value obj, mrb_int olen, mrb_int argc, const mrb_value *argv, mrb_value (*func)(mrb_state*, mrb_value, mrb_int)); + +MRB_END_DECL + +#endif /* MRUBY_RANGE_H */ diff --git a/web/server/h2o/libh2o/deps/mruby/include/mruby/re.h b/web/server/h2o/libh2o/deps/mruby/include/mruby/re.h new file mode 100644 index 00000000..1d09d06c --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/include/mruby/re.h @@ -0,0 +1,16 @@ +/* +** mruby/re.h - Regexp class +** +** See Copyright Notice in mruby.h +*/ + +#ifndef MRUBY_RE_H +#define MRUBY_RE_H + +MRB_BEGIN_DECL + +#define REGEXP_CLASS "Regexp" + +MRB_END_DECL + +#endif /* RE_H */ diff --git a/web/server/h2o/libh2o/deps/mruby/include/mruby/string.h b/web/server/h2o/libh2o/deps/mruby/include/mruby/string.h new file mode 100644 index 00000000..df6fb25c --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/include/mruby/string.h @@ -0,0 +1,430 @@ +/* +** mruby/string.h - String class +** +** See Copyright Notice in mruby.h +*/ + +#ifndef MRUBY_STRING_H +#define MRUBY_STRING_H + +#include "common.h" + +/** + * String class + */ +MRB_BEGIN_DECL + +extern const char mrb_digitmap[]; + +#define RSTRING_EMBED_LEN_MAX ((mrb_int)(sizeof(void*) * 3 - 1)) + +struct RString { + MRB_OBJECT_HEADER; + union { + struct { + mrb_int len; + union { + mrb_int capa; + struct mrb_shared_string *shared; + } aux; + char *ptr; + } heap; + char ary[RSTRING_EMBED_LEN_MAX + 1]; + } as; +}; + +#define RSTR_EMBED_P(s) ((s)->flags & MRB_STR_EMBED) +#define RSTR_SET_EMBED_FLAG(s) ((s)->flags |= MRB_STR_EMBED) +#define RSTR_UNSET_EMBED_FLAG(s) ((s)->flags &= ~(MRB_STR_EMBED|MRB_STR_EMBED_LEN_MASK)) +#define RSTR_SET_EMBED_LEN(s, n) do {\ + size_t tmp_n = (n);\ + s->flags &= ~MRB_STR_EMBED_LEN_MASK;\ + s->flags |= (tmp_n) << MRB_STR_EMBED_LEN_SHIFT;\ +} while (0) +#define RSTR_SET_LEN(s, n) do {\ + if (RSTR_EMBED_P(s)) {\ + RSTR_SET_EMBED_LEN((s),(n));\ + }\ + else {\ + s->as.heap.len = (mrb_int)(n);\ + }\ +} while (0) +#define RSTR_EMBED_LEN(s)\ + (mrb_int)(((s)->flags & MRB_STR_EMBED_LEN_MASK) >> MRB_STR_EMBED_LEN_SHIFT) +#define RSTR_PTR(s) ((RSTR_EMBED_P(s)) ? (s)->as.ary : (s)->as.heap.ptr) +#define RSTR_LEN(s) ((RSTR_EMBED_P(s)) ? RSTR_EMBED_LEN(s) : (s)->as.heap.len) +#define RSTR_CAPA(s) (RSTR_EMBED_P(s) ? RSTRING_EMBED_LEN_MAX : (s)->as.heap.aux.capa) + +#define RSTR_SHARED_P(s) ((s)->flags & MRB_STR_SHARED) +#define RSTR_SET_SHARED_FLAG(s) ((s)->flags |= MRB_STR_SHARED) +#define RSTR_UNSET_SHARED_FLAG(s) ((s)->flags &= ~MRB_STR_SHARED) + +#define RSTR_NOFREE_P(s) ((s)->flags & MRB_STR_NOFREE) +#define RSTR_SET_NOFREE_FLAG(s) ((s)->flags |= MRB_STR_NOFREE) +#define RSTR_UNSET_NOFREE_FLAG(s) ((s)->flags &= ~MRB_STR_NOFREE) + +/* + * Returns a pointer from a Ruby string + */ +#define mrb_str_ptr(s) ((struct RString*)(mrb_ptr(s))) +#define RSTRING(s) mrb_str_ptr(s) +#define RSTRING_PTR(s) RSTR_PTR(RSTRING(s)) +#define RSTRING_EMBED_LEN(s) RSTR_EMBED_LEN(RSTRING(s)) +#define RSTRING_LEN(s) RSTR_LEN(RSTRING(s)) +#define RSTRING_CAPA(s) RSTR_CAPA(RSTRING(s)) +#define RSTRING_END(s) (RSTRING_PTR(s) + RSTRING_LEN(s)) +MRB_API mrb_int mrb_str_strlen(mrb_state*, struct RString*); + +#define MRB_STR_SHARED 1 +#define MRB_STR_NOFREE 2 +#define MRB_STR_NO_UTF 8 +#define MRB_STR_EMBED 16 +#define MRB_STR_EMBED_LEN_MASK 0x3e0 +#define MRB_STR_EMBED_LEN_SHIFT 5 + +void mrb_gc_free_str(mrb_state*, struct RString*); +MRB_API void mrb_str_modify(mrb_state*, struct RString*); + +/* + * Finds the index of a substring in a string + */ +MRB_API mrb_int mrb_str_index(mrb_state*, mrb_value, const char*, mrb_int, mrb_int); +#define mrb_str_index_lit(mrb, str, lit, off) mrb_str_index(mrb, str, lit, mrb_strlen_lit(lit), off); + +/* + * Appends self to other. Returns self as a concatnated string. + * + * + * Example: + * + * !!!c + * int + * main(int argc, + * char **argv) + * { + * // Variable declarations. + * mrb_value str1; + * mrb_value str2; + * + * mrb_state *mrb = mrb_open(); + * if (!mrb) + * { + * // handle error + * } + * + * // Creates new Ruby strings. + * str1 = mrb_str_new_lit(mrb, "abc"); + * str2 = mrb_str_new_lit(mrb, "def"); + * + * // Concatnates str2 to str1. + * mrb_str_concat(mrb, str1, str2); + * + * // Prints new Concatnated Ruby string. + * mrb_p(mrb, str1); + * + * mrb_close(mrb); + * return 0; + * } + * + * + * Result: + * + * => "abcdef" + * + * @param [mrb_state] mrb The current mruby state. + * @param [mrb_value] self String to concatenate. + * @param [mrb_value] other String to append to self. + * @return [mrb_value] Returns a new String appending other to self. + */ +MRB_API void mrb_str_concat(mrb_state*, mrb_value, mrb_value); + +/* + * Adds two strings together. + * + * + * Example: + * + * !!!c + * int + * main(int argc, + * char **argv) + * { + * // Variable declarations. + * mrb_value a; + * mrb_value b; + * mrb_value c; + * + * mrb_state *mrb = mrb_open(); + * if (!mrb) + * { + * // handle error + * } + * + * // Creates two Ruby strings from the passed in C strings. + * a = mrb_str_new_lit(mrb, "abc"); + * b = mrb_str_new_lit(mrb, "def"); + * + * // Prints both C strings. + * mrb_p(mrb, a); + * mrb_p(mrb, b); + * + * // Concatnates both Ruby strings. + * c = mrb_str_plus(mrb, a, b); + * + * // Prints new Concatnated Ruby string. + * mrb_p(mrb, c); + * + * mrb_close(mrb); + * return 0; + * } + * + * + * Result: + * + * => "abc" # First string + * => "def" # Second string + * => "abcdef" # First & Second concatnated. + * + * @param [mrb_state] mrb The current mruby state. + * @param [mrb_value] a First string to concatenate. + * @param [mrb_value] b Second string to concatenate. + * @return [mrb_value] Returns a new String containing a concatenated to b. + */ +MRB_API mrb_value mrb_str_plus(mrb_state*, mrb_value, mrb_value); + +/* + * Converts pointer into a Ruby string. + * + * @param [mrb_state] mrb The current mruby state. + * @param [void*] p The pointer to convert to Ruby string. + * @return [mrb_value] Returns a new Ruby String. + */ +MRB_API mrb_value mrb_ptr_to_str(mrb_state *, void*); + +/* + * Returns an object as a Ruby string. + * + * @param [mrb_state] mrb The current mruby state. + * @param [mrb_value] obj An object to return as a Ruby string. + * @return [mrb_value] An object as a Ruby string. + */ +MRB_API mrb_value mrb_obj_as_string(mrb_state *mrb, mrb_value obj); + +/* + * Resizes the string's length. Returns the amount of characters + * in the specified by len. + * + * Example: + * + * !!!c + * int + * main(int argc, + * char **argv) + * { + * // Variable declaration. + * mrb_value str; + * + * mrb_state *mrb = mrb_open(); + * if (!mrb) + * { + * // handle error + * } + * // Creates a new string. + * str = mrb_str_new_lit(mrb, "Hello, world!"); + * // Returns 5 characters of + * mrb_str_resize(mrb, str, 5); + * mrb_p(mrb, str); + * + * mrb_close(mrb); + * return 0; + * } + * + * Result: + * + * => "Hello" + * + * @param [mrb_state] mrb The current mruby state. + * @param [mrb_value] str The Ruby string to resize. + * @param [mrb_value] len The length. + * @return [mrb_value] An object as a Ruby string. + */ +MRB_API mrb_value mrb_str_resize(mrb_state *mrb, mrb_value str, mrb_int len); + +/* + * Returns a sub string. + * + * Example: + * + * !!!c + * int + * main(int argc, + * char const **argv) + * { + * // Variable declarations. + * mrb_value str1; + * mrb_value str2; + * + * mrb_state *mrb = mrb_open(); + * if (!mrb) + * { + * // handle error + * } + * // Creates new string. + * str1 = mrb_str_new_lit(mrb, "Hello, world!"); + * // Returns a sub-string within the range of 0..2 + * str2 = mrb_str_substr(mrb, str1, 0, 2); + * + * // Prints sub-string. + * mrb_p(mrb, str2); + * + * mrb_close(mrb); + * return 0; + * } + * + * Result: + * + * => "He" + * + * @param [mrb_state] mrb The current mruby state. + * @param [mrb_value] str Ruby string. + * @param [mrb_int] beg The beginning point of the sub-string. + * @param [mrb_int] len The end point of the sub-string. + * @return [mrb_value] An object as a Ruby sub-string. + */ +MRB_API mrb_value mrb_str_substr(mrb_state *mrb, mrb_value str, mrb_int beg, mrb_int len); + +/* + * Returns a Ruby string type. + * + * + * @param [mrb_state] mrb The current mruby state. + * @param [mrb_value] str Ruby string. + * @return [mrb_value] A Ruby string. + */ +MRB_API mrb_value mrb_string_type(mrb_state *mrb, mrb_value str); + +MRB_API mrb_value mrb_check_string_type(mrb_state *mrb, mrb_value str); +MRB_API mrb_value mrb_str_new_capa(mrb_state *mrb, size_t capa); +MRB_API mrb_value mrb_str_buf_new(mrb_state *mrb, size_t capa); + +MRB_API const char *mrb_string_value_cstr(mrb_state *mrb, mrb_value *ptr); +MRB_API const char *mrb_string_value_ptr(mrb_state *mrb, mrb_value str); +/* + * Returns the length of the Ruby string. + * + * + * @param [mrb_state] mrb The current mruby state. + * @param [mrb_value] str Ruby string. + * @return [mrb_int] The length of the passed in Ruby string. + */ +MRB_API mrb_int mrb_string_value_len(mrb_state *mrb, mrb_value str); + +/* + * Duplicates a string object. + * + * + * @param [mrb_state] mrb The current mruby state. + * @param [mrb_value] str Ruby string. + * @return [mrb_value] Duplicated Ruby string. + */ +MRB_API mrb_value mrb_str_dup(mrb_state *mrb, mrb_value str); + +/* + * Returns a symbol from a passed in Ruby string. + * + * @param [mrb_state] mrb The current mruby state. + * @param [mrb_value] self Ruby string. + * @return [mrb_value] A symbol. + */ +MRB_API mrb_value mrb_str_intern(mrb_state *mrb, mrb_value self); + +MRB_API mrb_value mrb_str_to_inum(mrb_state *mrb, mrb_value str, mrb_int base, mrb_bool badcheck); +MRB_API double mrb_str_to_dbl(mrb_state *mrb, mrb_value str, mrb_bool badcheck); + +/* + * Returns a converted string type. + */ +MRB_API mrb_value mrb_str_to_str(mrb_state *mrb, mrb_value str); + +/* + * Returns true if the strings match and false if the strings don't match. + * + * @param [mrb_state] mrb The current mruby state. + * @param [mrb_value] str1 Ruby string to compare. + * @param [mrb_value] str2 Ruby string to compare. + * @return [mrb_value] boolean value. + */ +MRB_API mrb_bool mrb_str_equal(mrb_state *mrb, mrb_value str1, mrb_value str2); + +/* + * Returns a concated string comprised of a Ruby string and a C string. + * + * @param [mrb_state] mrb The current mruby state. + * @param [mrb_value] str Ruby string. + * @param [const char *] ptr A C string. + * @param [size_t] len length of C string. + * @return [mrb_value] A Ruby string. + * @see mrb_str_cat_cstr + */ +MRB_API mrb_value mrb_str_cat(mrb_state *mrb, mrb_value str, const char *ptr, size_t len); + +/* + * Returns a concated string comprised of a Ruby string and a C string. + * + * @param [mrb_state] mrb The current mruby state. + * @param [mrb_value] str Ruby string. + * @param [const char *] ptr A C string. + * @return [mrb_value] A Ruby string. + * @see mrb_str_cat + */ +MRB_API mrb_value mrb_str_cat_cstr(mrb_state *mrb, mrb_value str, const char *ptr); +MRB_API mrb_value mrb_str_cat_str(mrb_state *mrb, mrb_value str, mrb_value str2); +#define mrb_str_cat_lit(mrb, str, lit) mrb_str_cat(mrb, str, lit, mrb_strlen_lit(lit)) + +/* + * Adds str2 to the end of str1. + */ +MRB_API mrb_value mrb_str_append(mrb_state *mrb, mrb_value str, mrb_value str2); + +/* + * Returns 0 if both Ruby strings are equal. Returns a value < 0 if Ruby str1 is less than Ruby str2. Returns a value > 0 if Ruby str2 is greater than Ruby str1. + */ +MRB_API int mrb_str_cmp(mrb_state *mrb, mrb_value str1, mrb_value str2); + +/* + * Returns a newly allocated C string from a Ruby string. + * This is an utility function to pass a Ruby string to C library functions. + * + * - Returned string does not contain any NUL characters (but terminator). + * - It raises an ArgumentError exception if Ruby string contains + * NUL characters. + * - Retured string will be freed automatically on next GC. + * - Caller can modify returned string without affecting Ruby string + * (e.g. it can be used for mkstemp(3)). + * + * @param [mrb_state *] mrb The current mruby state. + * @param [mrb_value] str Ruby string. Must be an instance of String. + * @return [char *] A newly allocated C string. + */ +MRB_API char *mrb_str_to_cstr(mrb_state *mrb, mrb_value str); + +mrb_value mrb_str_pool(mrb_state *mrb, mrb_value str); +mrb_int mrb_str_hash(mrb_state *mrb, mrb_value str); +mrb_value mrb_str_dump(mrb_state *mrb, mrb_value str); + +/* + * Returns a printable version of str, surrounded by quote marks, with special characters escaped. + */ +mrb_value mrb_str_inspect(mrb_state *mrb, mrb_value str); + +void mrb_noregexp(mrb_state *mrb, mrb_value self); +void mrb_regexp_check(mrb_state *mrb, mrb_value obj); + +/* For backward compatibility */ +#define mrb_str_cat2(mrb, str, ptr) mrb_str_cat_cstr(mrb, str, ptr) +#define mrb_str_buf_cat(mrb, str, ptr, len) mrb_str_cat(mrb, str, ptr, len) +#define mrb_str_buf_append(mrb, str, str2) mrb_str_cat_str(mrb, str, str2) + +MRB_END_DECL + +#endif /* MRUBY_STRING_H */ diff --git a/web/server/h2o/libh2o/deps/mruby/include/mruby/throw.h b/web/server/h2o/libh2o/deps/mruby/include/mruby/throw.h new file mode 100644 index 00000000..5d3d214e --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/include/mruby/throw.h @@ -0,0 +1,55 @@ +/* +** mruby/throw.h - mruby exception throwing handler +** +** See Copyright Notice in mruby.h +*/ + +#ifndef MRB_THROW_H +#define MRB_THROW_H + +#if defined(MRB_ENABLE_CXX_ABI) +# if !defined(__cplusplus) +# error Trying to use C++ exception handling in C code +# endif +#endif + +#if defined(MRB_ENABLE_CXX_EXCEPTION) && defined(__cplusplus) + +#define MRB_TRY(buf) do { try { +#define MRB_CATCH(buf) } catch(mrb_jmpbuf_impl e) { if (e != (buf)->impl) { throw e; } +#define MRB_END_EXC(buf) } } while(0) + +#define MRB_THROW(buf) throw((buf)->impl) +typedef mrb_int mrb_jmpbuf_impl; + +#else + +#include + +#if defined(__APPLE__) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) +#define MRB_SETJMP _setjmp +#define MRB_LONGJMP _longjmp +#else +#define MRB_SETJMP setjmp +#define MRB_LONGJMP longjmp +#endif + +#define MRB_TRY(buf) do { if (MRB_SETJMP((buf)->impl) == 0) { +#define MRB_CATCH(buf) } else { +#define MRB_END_EXC(buf) } } while(0) + +#define MRB_THROW(buf) MRB_LONGJMP((buf)->impl, 1); +#define mrb_jmpbuf_impl jmp_buf + +#endif + +struct mrb_jmpbuf { + mrb_jmpbuf_impl impl; + +#if defined(MRB_ENABLE_CXX_EXCEPTION) && defined(__cplusplus) + static mrb_int jmpbuf_id; + mrb_jmpbuf() : impl(jmpbuf_id++) {} +#endif +}; + +#endif /* MRB_THROW_H */ diff --git a/web/server/h2o/libh2o/deps/mruby/include/mruby/value.h b/web/server/h2o/libh2o/deps/mruby/include/mruby/value.h new file mode 100644 index 00000000..98c68d65 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/include/mruby/value.h @@ -0,0 +1,303 @@ +/* +** mruby/value.h - mruby value definitions +** +** See Copyright Notice in mruby.h +*/ + +#ifndef MRUBY_VALUE_H +#define MRUBY_VALUE_H + +#include "common.h" + +/** + * MRuby Value definition functions and macros. + */ +MRB_BEGIN_DECL + +typedef uint32_t mrb_sym; +typedef uint8_t mrb_bool; +struct mrb_state; + +#if defined(MRB_INT16) && defined(MRB_INT64) +# error "You can't define MRB_INT16 and MRB_INT64 at the same time." +#endif + +#if defined _MSC_VER && _MSC_VER < 1800 +# define PRIo64 "llo" +# define PRId64 "lld" +# define PRIx64 "llx" +# define PRIo16 "ho" +# define PRId16 "hd" +# define PRIx16 "hx" +# define PRIo32 "o" +# define PRId32 "d" +# define PRIx32 "x" +#else +# include +#endif + +#if defined(MRB_INT64) + typedef int64_t mrb_int; +# define MRB_INT_BIT 64 +# define MRB_INT_MIN (INT64_MIN>>MRB_FIXNUM_SHIFT) +# define MRB_INT_MAX (INT64_MAX>>MRB_FIXNUM_SHIFT) +# define MRB_PRIo PRIo64 +# define MRB_PRId PRId64 +# define MRB_PRIx PRIx64 +#elif defined(MRB_INT16) + typedef int16_t mrb_int; +# define MRB_INT_BIT 16 +# define MRB_INT_MIN (INT16_MIN>>MRB_FIXNUM_SHIFT) +# define MRB_INT_MAX (INT16_MAX>>MRB_FIXNUM_SHIFT) +# define MRB_PRIo PRIo16 +# define MRB_PRId PRId16 +# define MRB_PRIx PRIx16 +#else + typedef int32_t mrb_int; +# define MRB_INT_BIT 32 +# define MRB_INT_MIN (INT32_MIN>>MRB_FIXNUM_SHIFT) +# define MRB_INT_MAX (INT32_MAX>>MRB_FIXNUM_SHIFT) +# define MRB_PRIo PRIo32 +# define MRB_PRId PRId32 +# define MRB_PRIx PRIx32 +#endif + + +MRB_API double mrb_float_read(const char*, char**); +#ifdef MRB_USE_FLOAT + typedef float mrb_float; +#else + typedef double mrb_float; +#endif + +#if defined _MSC_VER && _MSC_VER < 1900 +# ifndef __cplusplus +# define inline __inline +# endif +# include +MRB_API int mrb_msvc_vsnprintf(char *s, size_t n, const char *format, va_list arg); +MRB_API int mrb_msvc_snprintf(char *s, size_t n, const char *format, ...); +# define vsnprintf(s, n, format, arg) mrb_msvc_vsnprintf(s, n, format, arg) +# define snprintf(s, n, format, ...) mrb_msvc_snprintf(s, n, format, __VA_ARGS__) +# if _MSC_VER < 1800 +# include +# define isfinite(n) _finite(n) +# define isnan _isnan +# define isinf(n) (!_finite(n) && !_isnan(n)) +# define signbit(n) (_copysign(1.0, (n)) < 0.0) +static const unsigned int IEEE754_INFINITY_BITS_SINGLE = 0x7F800000; +# define INFINITY (*(float *)&IEEE754_INFINITY_BITS_SINGLE) +# define NAN ((float)(INFINITY - INFINITY)) +# endif +#endif + +enum mrb_vtype { + MRB_TT_FALSE = 0, /* 0 */ + MRB_TT_FREE, /* 1 */ + MRB_TT_TRUE, /* 2 */ + MRB_TT_FIXNUM, /* 3 */ + MRB_TT_SYMBOL, /* 4 */ + MRB_TT_UNDEF, /* 5 */ + MRB_TT_FLOAT, /* 6 */ + MRB_TT_CPTR, /* 7 */ + MRB_TT_OBJECT, /* 8 */ + MRB_TT_CLASS, /* 9 */ + MRB_TT_MODULE, /* 10 */ + MRB_TT_ICLASS, /* 11 */ + MRB_TT_SCLASS, /* 12 */ + MRB_TT_PROC, /* 13 */ + MRB_TT_ARRAY, /* 14 */ + MRB_TT_HASH, /* 15 */ + MRB_TT_STRING, /* 16 */ + MRB_TT_RANGE, /* 17 */ + MRB_TT_EXCEPTION, /* 18 */ + MRB_TT_FILE, /* 19 */ + MRB_TT_ENV, /* 20 */ + MRB_TT_DATA, /* 21 */ + MRB_TT_FIBER, /* 22 */ + MRB_TT_ISTRUCT, /* 23 */ + MRB_TT_BREAK, /* 24 */ + MRB_TT_MAXDEFINE /* 25 */ +}; + +#include + +#ifdef MRB_DOCUMENTATION_BLOCK + +/** + * @abstract + * MRuby value boxing. + * + * Actual implementation depends on configured boxing type. + * + * @see mruby/boxing_no.h Default boxing representation + * @see mruby/boxing_word.h Word representation + * @see mruby/boxing_nan.h Boxed double representation + */ +typedef void mrb_value; + +#endif + +#if defined(MRB_NAN_BOXING) +#include "boxing_nan.h" +#elif defined(MRB_WORD_BOXING) +#include "boxing_word.h" +#else +#include "boxing_no.h" +#endif + +#ifndef mrb_fixnum_p +#define mrb_fixnum_p(o) (mrb_type(o) == MRB_TT_FIXNUM) +#endif +#ifndef mrb_undef_p +#define mrb_undef_p(o) (mrb_type(o) == MRB_TT_UNDEF) +#endif +#ifndef mrb_nil_p +#define mrb_nil_p(o) (mrb_type(o) == MRB_TT_FALSE && !mrb_fixnum(o)) +#endif +#ifndef mrb_bool +#define mrb_bool(o) (mrb_type(o) != MRB_TT_FALSE) +#endif +#define mrb_float_p(o) (mrb_type(o) == MRB_TT_FLOAT) +#define mrb_symbol_p(o) (mrb_type(o) == MRB_TT_SYMBOL) +#define mrb_array_p(o) (mrb_type(o) == MRB_TT_ARRAY) +#define mrb_string_p(o) (mrb_type(o) == MRB_TT_STRING) +#define mrb_hash_p(o) (mrb_type(o) == MRB_TT_HASH) +#define mrb_cptr_p(o) (mrb_type(o) == MRB_TT_CPTR) +#define mrb_exception_p(o) (mrb_type(o) == MRB_TT_EXCEPTION) +#define mrb_test(o) mrb_bool(o) +MRB_API mrb_bool mrb_regexp_p(struct mrb_state*, mrb_value); + +/* + * Returns a float in Ruby. + */ +MRB_INLINE mrb_value mrb_float_value(struct mrb_state *mrb, mrb_float f) +{ + mrb_value v; + (void) mrb; + SET_FLOAT_VALUE(mrb, v, f); + return v; +} + +static inline mrb_value +mrb_cptr_value(struct mrb_state *mrb, void *p) +{ + mrb_value v; + (void) mrb; + SET_CPTR_VALUE(mrb,v,p); + return v; +} + +/* + * Returns a fixnum in Ruby. + */ +MRB_INLINE mrb_value mrb_fixnum_value(mrb_int i) +{ + mrb_value v; + SET_INT_VALUE(v, i); + return v; +} + +static inline mrb_value +mrb_symbol_value(mrb_sym i) +{ + mrb_value v; + SET_SYM_VALUE(v, i); + return v; +} + +static inline mrb_value +mrb_obj_value(void *p) +{ + mrb_value v; + SET_OBJ_VALUE(v, (struct RBasic*)p); + mrb_assert(p == mrb_ptr(v)); + mrb_assert(((struct RBasic*)p)->tt == mrb_type(v)); + return v; +} + + +/* + * Get a nil mrb_value object. + * + * @return + * nil mrb_value object reference. + */ +MRB_INLINE mrb_value mrb_nil_value(void) +{ + mrb_value v; + SET_NIL_VALUE(v); + return v; +} + +/* + * Returns false in Ruby. + */ +MRB_INLINE mrb_value mrb_false_value(void) +{ + mrb_value v; + SET_FALSE_VALUE(v); + return v; +} + +/* + * Returns true in Ruby. + */ +MRB_INLINE mrb_value mrb_true_value(void) +{ + mrb_value v; + SET_TRUE_VALUE(v); + return v; +} + +static inline mrb_value +mrb_bool_value(mrb_bool boolean) +{ + mrb_value v; + SET_BOOL_VALUE(v, boolean); + return v; +} + +static inline mrb_value +mrb_undef_value(void) +{ + mrb_value v; + SET_UNDEF_VALUE(v); + return v; +} + +#ifdef MRB_USE_ETEXT_EDATA +#if (defined(__APPLE__) && defined(__MACH__)) +#include +static inline mrb_bool +mrb_ro_data_p(const char *p) +{ + return (const char*)get_etext() < p && p < (const char*)get_edata(); +} +#else +extern char _etext[]; +#ifdef MRB_NO_INIT_ARRAY_START +extern char _edata[]; + +static inline mrb_bool +mrb_ro_data_p(const char *p) +{ + return _etext < p && p < _edata; +} +#else +extern char __init_array_start[]; + +static inline mrb_bool +mrb_ro_data_p(const char *p) +{ + return _etext < p && p < (char*)&__init_array_start; +} +#endif +#endif +#else +# define mrb_ro_data_p(p) FALSE +#endif + +MRB_END_DECL + +#endif /* MRUBY_VALUE_H */ diff --git a/web/server/h2o/libh2o/deps/mruby/include/mruby/variable.h b/web/server/h2o/libh2o/deps/mruby/include/mruby/variable.h new file mode 100644 index 00000000..5fef83fa --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/include/mruby/variable.h @@ -0,0 +1,138 @@ +/* +** mruby/variable.h - mruby variables +** +** See Copyright Notice in mruby.h +*/ + +#ifndef MRUBY_VARIABLE_H +#define MRUBY_VARIABLE_H + +#include "common.h" + +/** + * Functions to access mruby variables. + */ +MRB_BEGIN_DECL + +typedef struct global_variable { + int counter; + mrb_value *data; + mrb_value (*getter)(void); + void (*setter)(void); + /* void (*marker)(); */ + /* int block_trace; */ + /* struct trace_var *trace; */ +} global_variable; + +struct global_entry { + global_variable *var; + mrb_sym id; +}; + +mrb_value mrb_vm_special_get(mrb_state*, mrb_sym); +void mrb_vm_special_set(mrb_state*, mrb_sym, mrb_value); +mrb_value mrb_vm_iv_get(mrb_state*, mrb_sym); +void mrb_vm_iv_set(mrb_state*, mrb_sym, mrb_value); +mrb_value mrb_vm_cv_get(mrb_state*, mrb_sym); +void mrb_vm_cv_set(mrb_state*, mrb_sym, mrb_value); +mrb_value mrb_vm_const_get(mrb_state*, mrb_sym); +void mrb_vm_const_set(mrb_state*, mrb_sym, mrb_value); +MRB_API mrb_value mrb_const_get(mrb_state*, mrb_value, mrb_sym); +MRB_API void mrb_const_set(mrb_state*, mrb_value, mrb_sym, mrb_value); +MRB_API mrb_bool mrb_const_defined(mrb_state*, mrb_value, mrb_sym); +MRB_API void mrb_const_remove(mrb_state*, mrb_value, mrb_sym); + +MRB_API mrb_bool mrb_iv_p(mrb_state *mrb, mrb_sym sym); +MRB_API void mrb_iv_check(mrb_state *mrb, mrb_sym sym); +MRB_API mrb_value mrb_obj_iv_get(mrb_state *mrb, struct RObject *obj, mrb_sym sym); +MRB_API void mrb_obj_iv_set(mrb_state *mrb, struct RObject *obj, mrb_sym sym, mrb_value v); +MRB_API mrb_bool mrb_obj_iv_defined(mrb_state *mrb, struct RObject *obj, mrb_sym sym); +MRB_API mrb_value mrb_iv_get(mrb_state *mrb, mrb_value obj, mrb_sym sym); +MRB_API void mrb_iv_set(mrb_state *mrb, mrb_value obj, mrb_sym sym, mrb_value v); +MRB_API mrb_bool mrb_iv_defined(mrb_state*, mrb_value, mrb_sym); +MRB_API mrb_value mrb_iv_remove(mrb_state *mrb, mrb_value obj, mrb_sym sym); +MRB_API void mrb_iv_copy(mrb_state *mrb, mrb_value dst, mrb_value src); +MRB_API mrb_bool mrb_const_defined_at(mrb_state *mrb, mrb_value mod, mrb_sym id); + +/** + * Get a global variable. Will return nil if the var does not exist + * + * Example: + * + * !!!ruby + * # Ruby style + * var = $value + * + * !!!c + * // C style + * mrb_sym sym = mrb_intern_lit(mrb, "$value"); + * mrb_value var = mrb_gv_get(mrb, sym); + * + * @param mrb The mruby state reference + * @param sym The name of the global variable + * @return The value of that global variable. May be nil + */ +MRB_API mrb_value mrb_gv_get(mrb_state *mrb, mrb_sym sym); + +/** + * Set a global variable + * + * Example: + * + * !!!ruby + * # Ruby style + * $value = "foo" + * + * !!!c + * // C style + * mrb_sym sym = mrb_intern_lit(mrb, "$value"); + * mrb_gv_set(mrb, sym, mrb_str_new_lit("foo")); + * + * @param mrb The mruby state reference + * @param sym The name of the global variable + * @param val The value of the global variable + */ +MRB_API void mrb_gv_set(mrb_state *mrb, mrb_sym sym, mrb_value val); + +/** + * Remove a global variable. + * + * Example: + * + * !!!ruby + * # Ruby style + * $value = nil + * + * !!!c + * // C style + * mrb_sym sym = mrb_intern_lit(mrb, "$value"); + * mrb_gv_remove(mrb, sym); + * + * @param mrb The mruby state reference + * @param sym The name of the global variable + * @param val The value of the global variable + */ +MRB_API void mrb_gv_remove(mrb_state *mrb, mrb_sym sym); + +MRB_API mrb_value mrb_cv_get(mrb_state *mrb, mrb_value mod, mrb_sym sym); +MRB_API void mrb_mod_cv_set(mrb_state *mrb, struct RClass * c, mrb_sym sym, mrb_value v); +MRB_API void mrb_cv_set(mrb_state *mrb, mrb_value mod, mrb_sym sym, mrb_value v); +MRB_API mrb_bool mrb_cv_defined(mrb_state *mrb, mrb_value mod, mrb_sym sym); +mrb_value mrb_obj_iv_inspect(mrb_state*, struct RObject*); +mrb_value mrb_mod_constants(mrb_state *mrb, mrb_value mod); +mrb_value mrb_f_global_variables(mrb_state *mrb, mrb_value self); +mrb_value mrb_obj_instance_variables(mrb_state*, mrb_value); +mrb_value mrb_mod_class_variables(mrb_state*, mrb_value); +mrb_value mrb_mod_cv_get(mrb_state *mrb, struct RClass * c, mrb_sym sym); +mrb_bool mrb_mod_cv_defined(mrb_state *mrb, struct RClass * c, mrb_sym sym); + +/* GC functions */ +void mrb_gc_mark_gv(mrb_state*); +void mrb_gc_free_gv(mrb_state*); +void mrb_gc_mark_iv(mrb_state*, struct RObject*); +size_t mrb_gc_mark_iv_size(mrb_state*, struct RObject*); +void mrb_gc_free_iv(mrb_state*, struct RObject*); + +MRB_END_DECL + +#endif /* MRUBY_VARIABLE_H */ diff --git a/web/server/h2o/libh2o/deps/mruby/include/mruby/version.h b/web/server/h2o/libh2o/deps/mruby/include/mruby/version.h new file mode 100644 index 00000000..8414bf20 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/include/mruby/version.h @@ -0,0 +1,110 @@ +/* +** mruby/version.h - mruby version definition +** +** See Copyright Notice in mruby.h +*/ + +#ifndef MRUBY_VERSION_H +#define MRUBY_VERSION_H + +#include "common.h" + +/** + * mruby version definition macros + */ +MRB_BEGIN_DECL + +/* + * A passed in expression. + */ +#define MRB_STRINGIZE0(expr) #expr + +/* + * Passes in an expression to MRB_STRINGIZE0. + */ +#define MRB_STRINGIZE(expr) MRB_STRINGIZE0(expr) + +/* + * The version of Ruby used by mruby. + */ +#define MRUBY_RUBY_VERSION "1.9" + +/* + * Ruby engine. + */ +#define MRUBY_RUBY_ENGINE "mruby" + +/* + * Major release version number. + */ +#define MRUBY_RELEASE_MAJOR 1 + +/* + * Minor release version number. + */ +#define MRUBY_RELEASE_MINOR 3 + +/* + * Tiny release version number. + */ +#define MRUBY_RELEASE_TEENY 0 + +/* + * The mruby version. + */ +#define MRUBY_VERSION MRB_STRINGIZE(MRUBY_RELEASE_MAJOR) "." MRB_STRINGIZE(MRUBY_RELEASE_MINOR) "." MRB_STRINGIZE(MRUBY_RELEASE_TEENY) + +/* + * Release number. + */ +#define MRUBY_RELEASE_NO (MRUBY_RELEASE_MAJOR * 100 * 100 + MRUBY_RELEASE_MINOR * 100 + MRUBY_RELEASE_TEENY) + +/* + * Release year. + */ +#define MRUBY_RELEASE_YEAR 2017 + +/* + * Release month. + */ +#define MRUBY_RELEASE_MONTH 7 + +/* + * Release day. + */ +#define MRUBY_RELEASE_DAY 4 + +/* + * Release date as a string. + */ +#define MRUBY_RELEASE_DATE MRB_STRINGIZE(MRUBY_RELEASE_YEAR) "-" MRB_STRINGIZE(MRUBY_RELEASE_MONTH) "-" MRB_STRINGIZE(MRUBY_RELEASE_DAY) + +/* + * The year mruby was first created. + */ +#define MRUBY_BIRTH_YEAR 2010 + +/* + * MRuby's authors. + */ +#define MRUBY_AUTHOR "mruby developers" + +/* + * mruby's version, and release date. + */ +#define MRUBY_DESCRIPTION \ + "mruby " MRUBY_VERSION \ + " (" MRUBY_RELEASE_DATE ") " \ + +/* + * mruby's copyright information. + */ +#define MRUBY_COPYRIGHT \ + "mruby - Copyright (c) " \ + MRB_STRINGIZE(MRUBY_BIRTH_YEAR)"-" \ + MRB_STRINGIZE(MRUBY_RELEASE_YEAR)" " \ + MRUBY_AUTHOR \ + +MRB_END_DECL + +#endif /* MRUBY_VERSION_H */ diff --git a/web/server/h2o/libh2o/deps/mruby/lib/mruby-core-ext.rb b/web/server/h2o/libh2o/deps/mruby/lib/mruby-core-ext.rb new file mode 100644 index 00000000..4c6d3ca7 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/lib/mruby-core-ext.rb @@ -0,0 +1,79 @@ +class Object + class << self + def attr_block(*syms) + syms.flatten.each do |sym| + class_eval "def #{sym}(&block);block.call(@#{sym}) if block_given?;@#{sym};end" + end + end + end +end + +class String + def relative_path_from(dir) + Pathname.new(File.expand_path(self)).relative_path_from(Pathname.new(File.expand_path(dir))).to_s + end + + def relative_path + relative_path_from(Dir.pwd) + end + + # Compatible with 1.9 on 1.8 + def %(params) + if params.is_a?(Hash) + str = self.clone + params.each do |k, v| + str.gsub!("%{#{k}}") { v } + end + str + else + if params.is_a?(Array) + sprintf(self, *params) + else + sprintf(self, params) + end + end + end +end + +class Symbol + # Compatible with 1.9 on 1.8 + def to_proc + proc { |obj, *args| obj.send(self, *args) } + end +end + +module Enumerable + # Compatible with 1.9 on 1.8 + def each_with_object(memo) + return to_enum :each_with_object, memo unless block_given? + each { |obj| yield obj, memo } + memo + end +end + +$pp_show = true + +if $verbose.nil? + if Rake.respond_to?(:verbose) && !Rake.verbose.nil? + if Rake.verbose.class == TrueClass + # verbose message logging + $pp_show = false + else + $pp_show = true + Rake.verbose(false) + end + else + # could not identify rake version + $pp_show = false + end +else + $pp_show = false if $verbose +end + +def _pp(cmd, src, tgt=nil, options={}) + return unless $pp_show + + width = 5 + template = options[:indent] ? "%#{width*options[:indent]}s %s %s" : "%-#{width}s %s %s" + puts template % [cmd, src, tgt ? "-> #{tgt}" : nil] +end diff --git a/web/server/h2o/libh2o/deps/mruby/lib/mruby/build.rb b/web/server/h2o/libh2o/deps/mruby/lib/mruby/build.rb new file mode 100644 index 00000000..7d6aa49e --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/lib/mruby/build.rb @@ -0,0 +1,355 @@ +require "mruby/build/load_gems" +require "mruby/build/command" + +module MRuby + class << self + def targets + @targets ||= {} + end + + def each_target(&block) + return to_enum(:each_target) if block.nil? + @targets.each do |key, target| + target.instance_eval(&block) + end + end + end + + class Toolchain + class << self + attr_accessor :toolchains + end + + def initialize(name, &block) + @name, @initializer = name.to_s, block + MRuby::Toolchain.toolchains ||= {} + MRuby::Toolchain.toolchains[@name] = self + end + + def setup(conf,params={}) + conf.instance_exec(conf, params, &@initializer) + end + + def self.load + Dir.glob("#{MRUBY_ROOT}/tasks/toolchains/*.rake").each do |file| + Kernel.load file + end + end + end + Toolchain.load + + class Build + class << self + attr_accessor :current + end + include Rake::DSL + include LoadGems + attr_accessor :name, :bins, :exts, :file_separator, :build_dir, :gem_clone_dir + attr_reader :libmruby, :gems, :toolchains + attr_writer :enable_bintest, :enable_test + + COMPILERS = %w(cc cxx objc asm) + COMMANDS = COMPILERS + %w(linker archiver yacc gperf git exts mrbc) + attr_block MRuby::Build::COMMANDS + + Exts = Struct.new(:object, :executable, :library) + + def initialize(name='host', build_dir=nil, &block) + @name = name.to_s + + unless MRuby.targets[@name] + if ENV['OS'] == 'Windows_NT' + @exts = Exts.new('.o', '.exe', '.a') + else + @exts = Exts.new('.o', '', '.a') + end + + build_dir = build_dir || ENV['MRUBY_BUILD_DIR'] || "#{MRUBY_ROOT}/build" + + @file_separator = '/' + @build_dir = "#{build_dir}/#{@name}" + @gem_clone_dir = "#{build_dir}/mrbgems" + @cc = Command::Compiler.new(self, %w(.c)) + @cxx = Command::Compiler.new(self, %w(.cc .cxx .cpp)) + @objc = Command::Compiler.new(self, %w(.m)) + @asm = Command::Compiler.new(self, %w(.S .asm)) + @linker = Command::Linker.new(self) + @archiver = Command::Archiver.new(self) + @yacc = Command::Yacc.new(self) + @gperf = Command::Gperf.new(self) + @git = Command::Git.new(self) + @mrbc = Command::Mrbc.new(self) + + @bins = [] + @gems, @libmruby = MRuby::Gem::List.new, [] + @build_mrbtest_lib_only = false + @cxx_exception_enabled = false + @cxx_exception_disabled = false + @cxx_abi_enabled = false + @enable_bintest = false + @enable_test = false + @toolchains = [] + + MRuby.targets[@name] = self + end + + MRuby::Build.current = MRuby.targets[@name] + MRuby.targets[@name].instance_eval(&block) + + build_mrbc_exec if name == 'host' + build_mrbtest if test_enabled? + end + + def enable_debug + compilers.each do |c| + c.defines += %w(MRB_DEBUG) + if toolchains.any? { |toolchain| toolchain == "gcc" } + c.flags += %w(-g3 -O0) + end + end + @mrbc.compile_options += ' -g' + end + + def disable_cxx_exception + if @cxx_exception_enabled or @cxx_abi_enabled + raise "cxx_exception already enabled" + end + @cxx_exception_disabled = true + end + + def enable_cxx_exception + return if @cxx_exception_enabled + return if @cxx_abi_enabled + if @cxx_exception_disabled + raise "cxx_exception disabled" + end + @cxx_exception_enabled = true + compilers.each { |c| + c.defines += %w(MRB_ENABLE_CXX_EXCEPTION) + c.flags << c.cxx_exception_flag + } + linker.command = cxx.command if toolchains.find { |v| v == 'gcc' } + end + + def cxx_exception_enabled? + @cxx_exception_enabled + end + + def cxx_abi_enabled? + @cxx_abi_enabled + end + + def enable_cxx_abi + return if @cxx_abi_enabled + if @cxx_exception_enabled + raise "cxx_exception already enabled" + end + compilers.each { |c| + c.defines += %w(MRB_ENABLE_CXX_EXCEPTION MRB_ENABLE_CXX_ABI) + c.flags << c.cxx_compile_flag + } + compilers.each { |c| c.flags << c.cxx_compile_flag } + linker.command = cxx.command if toolchains.find { |v| v == 'gcc' } + @cxx_abi_enabled = true + end + + def compile_as_cxx src, cxx_src, obj = nil, includes = [] + src = File.absolute_path src + cxx_src = File.absolute_path cxx_src + obj = objfile(cxx_src) if obj.nil? + + file cxx_src => [src, __FILE__] do |t| + FileUtils.mkdir_p File.dirname t.name + IO.write t.name, < cxx_src do |t| + cxx.run t.name, t.prerequisites.first, [], ["#{MRUBY_ROOT}/src"] + includes + end + + obj + end + + def enable_bintest + @enable_bintest = true + end + + def bintest_enabled? + @enable_bintest + end + + def toolchain(name, params={}) + tc = Toolchain.toolchains[name.to_s] + fail "Unknown #{name} toolchain" unless tc + tc.setup(self, params) + @toolchains.unshift name.to_s + end + + def primary_toolchain + @toolchains.first + end + + def root + MRUBY_ROOT + end + + def enable_test + @enable_test = true + end + + def test_enabled? + @enable_test + end + + def build_mrbtest + gem :core => 'mruby-test' + end + + def build_mrbc_exec + gem :core => 'mruby-bin-mrbc' + end + + def mrbcfile + return @mrbcfile if @mrbcfile + + mrbc_build = MRuby.targets['host'] + gems.each { |v| mrbc_build = self if v.name == 'mruby-bin-mrbc' } + @mrbcfile = mrbc_build.exefile("#{mrbc_build.build_dir}/bin/mrbc") + end + + def compilers + COMPILERS.map do |c| + instance_variable_get("@#{c}") + end + end + + def define_rules + compilers.each do |compiler| + if respond_to?(:enable_gems?) && enable_gems? + compiler.defines -= %w(DISABLE_GEMS) + else + compiler.defines += %w(DISABLE_GEMS) + end + compiler.define_rules build_dir, File.expand_path(File.join(File.dirname(__FILE__), '..', '..')) + end + end + + def filename(name) + if name.is_a?(Array) + name.flatten.map { |n| filename(n) } + else + '"%s"' % name.gsub('/', file_separator) + end + end + + def cygwin_filename(name) + if name.is_a?(Array) + name.flatten.map { |n| cygwin_filename(n) } + else + '"%s"' % `cygpath -w "#{filename(name)}"`.strip + end + end + + def exefile(name) + if name.is_a?(Array) + name.flatten.map { |n| exefile(n) } + else + "#{name}#{exts.executable}" + end + end + + def objfile(name) + if name.is_a?(Array) + name.flatten.map { |n| objfile(n) } + else + "#{name}#{exts.object}" + end + end + + def libfile(name) + if name.is_a?(Array) + name.flatten.map { |n| libfile(n) } + else + "#{name}#{exts.library}" + end + end + + def build_mrbtest_lib_only + @build_mrbtest_lib_only = true + end + + def build_mrbtest_lib_only? + @build_mrbtest_lib_only + end + + def run_test + puts ">>> Test #{name} <<<" + mrbtest = exefile("#{build_dir}/bin/mrbtest") + sh "#{filename mrbtest.relative_path}#{$verbose ? ' -v' : ''}" + puts + run_bintest if bintest_enabled? + end + + def run_bintest + targets = @gems.select { |v| File.directory? "#{v.dir}/bintest" }.map { |v| filename v.dir } + targets << filename(".") if File.directory? "./bintest" + sh "ruby test/bintest.rb #{targets.join ' '}" + end + + def print_build_summary + puts "================================================" + puts " Config Name: #{@name}" + puts " Output Directory: #{self.build_dir.relative_path}" + puts " Binaries: #{@bins.join(', ')}" unless @bins.empty? + unless @gems.empty? + puts " Included Gems:" + @gems.map do |gem| + gem_version = " - #{gem.version}" if gem.version != '0.0.0' + gem_summary = " - #{gem.summary}" if gem.summary + puts " #{gem.name}#{gem_version}#{gem_summary}" + puts " - Binaries: #{gem.bins.join(', ')}" unless gem.bins.empty? + end + end + puts "================================================" + puts + end + end # Build + + class CrossBuild < Build + attr_block %w(test_runner) + # cross compiling targets for building native extensions. + # host - arch of where the built binary will run + # build - arch of the machine building the binary + attr_accessor :host_target, :build_target + + def initialize(name, build_dir=nil, &block) + @test_runner = Command::CrossTestRunner.new(self) + super + end + + def mrbcfile + MRuby.targets['host'].exefile("#{MRuby.targets['host'].build_dir}/bin/mrbc") + end + + def run_test + mrbtest = exefile("#{build_dir}/bin/mrbtest") + if (@test_runner.command == nil) + puts "You should run #{mrbtest} on target device." + puts + else + @test_runner.run(mrbtest) + end + end + end # CrossBuild +end # MRuby diff --git a/web/server/h2o/libh2o/deps/mruby/lib/mruby/build/command.rb b/web/server/h2o/libh2o/deps/mruby/lib/mruby/build/command.rb new file mode 100644 index 00000000..694b4a24 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/lib/mruby/build/command.rb @@ -0,0 +1,324 @@ +require 'forwardable' + +module MRuby + class Command + include Rake::DSL + extend Forwardable + def_delegators :@build, :filename, :objfile, :libfile, :exefile, :cygwin_filename + attr_accessor :build, :command + + def initialize(build) + @build = build + end + + # clone is deep clone without @build + def clone + target = super + excepts = %w(@build) + instance_variables.each do |attr| + unless excepts.include?(attr.to_s) + val = Marshal::load(Marshal.dump(instance_variable_get(attr))) # deep clone + target.instance_variable_set(attr, val) + end + end + target + end + + NotFoundCommands = {} + + private + def _run(options, params={}) + return sh command + ' ' + ( options % params ) if NotFoundCommands.key? @command + begin + sh build.filename(command) + ' ' + ( options % params ) + rescue RuntimeError + NotFoundCommands[@command] = true + _run options, params + end + end + end + + class Command::Compiler < Command + attr_accessor :flags, :include_paths, :defines, :source_exts + attr_accessor :compile_options, :option_define, :option_include_path, :out_ext + attr_accessor :cxx_compile_flag, :cxx_exception_flag + + def initialize(build, source_exts=[]) + super(build) + @command = ENV['CC'] || 'cc' + @flags = [ENV['CFLAGS'] || []] + @source_exts = source_exts + @include_paths = ["#{MRUBY_ROOT}/include"] + @defines = %w() + @option_include_path = '-I%s' + @option_define = '-D%s' + @compile_options = '%{flags} -o %{outfile} -c %{infile}' + end + + alias header_search_paths include_paths + def search_header_path(name) + header_search_paths.find do |v| + File.exist? build.filename("#{v}/#{name}").sub(/^"(.*)"$/, '\1') + end + end + + def search_header(name) + path = search_header_path name + path && build.filename("#{path}/#{name}").sub(/^"(.*)"$/, '\1') + end + + def all_flags(_defineds=[], _include_paths=[], _flags=[]) + define_flags = [defines, _defineds].flatten.map{ |d| option_define % d } + include_path_flags = [include_paths, _include_paths].flatten.map do |f| + if MRUBY_BUILD_HOST_IS_CYGWIN + option_include_path % cygwin_filename(f) + else + option_include_path % filename(f) + end + end + [flags, define_flags, include_path_flags, _flags].flatten.join(' ') + end + + def run(outfile, infile, _defineds=[], _include_paths=[], _flags=[]) + FileUtils.mkdir_p File.dirname(outfile) + _pp "CC", infile.relative_path, outfile.relative_path + if MRUBY_BUILD_HOST_IS_CYGWIN + _run compile_options, { :flags => all_flags(_defineds, _include_paths, _flags), + :infile => cygwin_filename(infile), :outfile => cygwin_filename(outfile) } + else + _run compile_options, { :flags => all_flags(_defineds, _include_paths, _flags), + :infile => filename(infile), :outfile => filename(outfile) } + end + end + + def define_rules(build_dir, source_dir='') + @out_ext = build.exts.object + gemrake = File.join(source_dir, "mrbgem.rake") + rakedep = File.exist?(gemrake) ? [ gemrake ] : [] + + if build_dir.include? "mrbgems/" + generated_file_matcher = Regexp.new("^#{Regexp.escape build_dir}/(.*)#{Regexp.escape out_ext}$") + else + generated_file_matcher = Regexp.new("^#{Regexp.escape build_dir}/(?!mrbgems/.+/)(.*)#{Regexp.escape out_ext}$") + end + source_exts.each do |ext, compile| + rule generated_file_matcher => [ + proc { |file| + file.sub(generated_file_matcher, "#{source_dir}/\\1#{ext}") + }, + proc { |file| + get_dependencies(file) + rakedep + } + ] do |t| + run t.name, t.prerequisites.first + end + + rule generated_file_matcher => [ + proc { |file| + file.sub(generated_file_matcher, "#{build_dir}/\\1#{ext}") + }, + proc { |file| + get_dependencies(file) + rakedep + } + ] do |t| + run t.name, t.prerequisites.first + end + end + end + + private + def get_dependencies(file) + file = file.ext('d') unless File.extname(file) == '.d' + if File.exist?(file) + File.read(file).gsub("\\\n ", "").scan(/^\S+:\s+(.+)$/).flatten.map {|s| s.split(' ') }.flatten + else + [] + end + [ MRUBY_CONFIG ] + end + end + + class Command::Linker < Command + attr_accessor :flags, :library_paths, :flags_before_libraries, :libraries, :flags_after_libraries + attr_accessor :link_options, :option_library, :option_library_path + + def initialize(build) + super + @command = ENV['LD'] || 'ld' + @flags = (ENV['LDFLAGS'] || []) + @flags_before_libraries, @flags_after_libraries = [], [] + @libraries = [] + @library_paths = [] + @option_library = '-l%s' + @option_library_path = '-L%s' + @link_options = "%{flags} -o %{outfile} %{objs} %{flags_before_libraries} %{libs} %{flags_after_libraries}" + end + + def all_flags(_library_paths=[], _flags=[]) + library_path_flags = [library_paths, _library_paths].flatten.map do |f| + if MRUBY_BUILD_HOST_IS_CYGWIN + option_library_path % cygwin_filename(f) + else + option_library_path % filename(f) + end + end + [flags, library_path_flags, _flags].flatten.join(' ') + end + + def library_flags(_libraries) + [libraries, _libraries].flatten.map{ |d| option_library % d }.join(' ') + end + + def run(outfile, objfiles, _libraries=[], _library_paths=[], _flags=[], _flags_before_libraries=[], _flags_after_libraries=[]) + FileUtils.mkdir_p File.dirname(outfile) + library_flags = [libraries, _libraries].flatten.map { |d| option_library % d } + + _pp "LD", outfile.relative_path + if MRUBY_BUILD_HOST_IS_CYGWIN + _run link_options, { :flags => all_flags(_library_paths, _flags), + :outfile => cygwin_filename(outfile) , :objs => cygwin_filename(objfiles).join(' '), + :flags_before_libraries => [flags_before_libraries, _flags_before_libraries].flatten.join(' '), + :flags_after_libraries => [flags_after_libraries, _flags_after_libraries].flatten.join(' '), + :libs => library_flags.join(' ') } + else + _run link_options, { :flags => all_flags(_library_paths, _flags), + :outfile => filename(outfile) , :objs => filename(objfiles).join(' '), + :flags_before_libraries => [flags_before_libraries, _flags_before_libraries].flatten.join(' '), + :flags_after_libraries => [flags_after_libraries, _flags_after_libraries].flatten.join(' '), + :libs => library_flags.join(' ') } + end + end + end + + class Command::Archiver < Command + attr_accessor :archive_options + + def initialize(build) + super + @command = ENV['AR'] || 'ar' + @archive_options = 'rs %{outfile} %{objs}' + end + + def run(outfile, objfiles) + FileUtils.mkdir_p File.dirname(outfile) + _pp "AR", outfile.relative_path + if MRUBY_BUILD_HOST_IS_CYGWIN + _run archive_options, { :outfile => cygwin_filename(outfile), :objs => cygwin_filename(objfiles).join(' ') } + else + _run archive_options, { :outfile => filename(outfile), :objs => filename(objfiles).join(' ') } + end + end + end + + class Command::Yacc < Command + attr_accessor :compile_options + + def initialize(build) + super + @command = 'bison' + @compile_options = '-o %{outfile} %{infile}' + end + + def run(outfile, infile) + FileUtils.mkdir_p File.dirname(outfile) + _pp "YACC", infile.relative_path, outfile.relative_path + _run compile_options, { :outfile => filename(outfile) , :infile => filename(infile) } + end + end + + class Command::Gperf < Command + attr_accessor :compile_options + + def initialize(build) + super + @command = 'gperf' + @compile_options = '-L ANSI-C -C -p -j1 -i 1 -g -o -t -N mrb_reserved_word -k"1,3,$" %{infile} > %{outfile}' + end + + def run(outfile, infile) + FileUtils.mkdir_p File.dirname(outfile) + _pp "GPERF", infile.relative_path, outfile.relative_path + _run compile_options, { :outfile => filename(outfile) , :infile => filename(infile) } + end + end + + class Command::Git < Command + attr_accessor :flags + attr_accessor :clone_options, :pull_options, :checkout_options + + def initialize(build) + super + @command = 'git' + @flags = %w[] + @clone_options = "clone %{flags} %{url} %{dir}" + @pull_options = "pull" + @checkout_options = "checkout %{checksum_hash}" + end + + def run_clone(dir, url, _flags = []) + _pp "GIT", url, dir.relative_path + _run clone_options, { :flags => [flags, _flags].flatten.join(' '), :url => url, :dir => filename(dir) } + end + + def run_pull(dir, url) + root = Dir.pwd + Dir.chdir dir + _pp "GIT PULL", url, dir.relative_path + _run pull_options + Dir.chdir root + end + + def run_checkout(dir, checksum_hash) + root = Dir.pwd + Dir.chdir dir + _pp "GIT CHECKOUT", checksum_hash + _run checkout_options, { :checksum_hash => checksum_hash } + Dir.chdir root + end + end + + class Command::Mrbc < Command + attr_accessor :compile_options + + def initialize(build) + super + @command = nil + @compile_options = "-B%{funcname} -o-" + end + + def run(out, infiles, funcname) + @command ||= @build.mrbcfile + infiles = [infiles].flatten + infiles.each do |f| + _pp "MRBC", f.relative_path, nil, :indent => 2 + end + IO.popen("#{filename @command} #{@compile_options % {:funcname => funcname}} #{filename(infiles).join(' ')}", 'r+') do |io| + out.puts io.read + end + # if mrbc execution fail, drop the file + if $?.exitstatus != 0 + File.delete(out.path) + exit(-1) + end + end + end + + class Command::CrossTestRunner < Command + attr_accessor :runner_options + attr_accessor :verbose_flag + attr_accessor :flags + + def initialize(build) + super + @command = nil + @runner_options = '%{flags} %{infile}' + @verbose_flag = '' + @flags = [] + end + + def run(testbinfile) + puts "TEST for " + @build.name + _run runner_options, { :flags => [flags, verbose_flag].flatten.join(' '), :infile => testbinfile } + end + end + +end diff --git a/web/server/h2o/libh2o/deps/mruby/lib/mruby/build/load_gems.rb b/web/server/h2o/libh2o/deps/mruby/lib/mruby/build/load_gems.rb new file mode 100644 index 00000000..b48df651 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/lib/mruby/build/load_gems.rb @@ -0,0 +1,122 @@ +module MRuby + module LoadGems + def gembox(gemboxfile) + gembox = File.expand_path("#{gemboxfile}.gembox", "#{MRUBY_ROOT}/mrbgems") + fail "Can't find gembox '#{gembox}'" unless File.exist?(gembox) + + GemBox.config = self + GemBox.path = gembox + + instance_eval File.read(gembox) + + GemBox.path = nil + end + + def gem(gemdir, &block) + caller_dir = File.expand_path(File.dirname(/^(.*?):\d/.match(caller.first).to_a[1])) + + if gemdir.is_a?(Hash) + gemdir = load_special_path_gem(gemdir) + elsif GemBox.path && gemdir.is_a?(String) + gemdir = File.expand_path(gemdir, File.dirname(GemBox.path)) + else + gemdir = File.expand_path(gemdir, caller_dir) + end + + gemrake = File.join(gemdir, "mrbgem.rake") + + fail "Can't find #{gemrake}" unless File.exist?(gemrake) + Gem.current = nil + load gemrake + return nil unless Gem.current + + Gem.current.dir = gemdir + Gem.current.build = self.is_a?(MRuby::Build) ? self : MRuby::Build.current + Gem.current.build_config_initializer = block + gems << Gem.current + + cxx_srcs = ['src', 'test', 'tools'].map do |subdir| + Dir.glob("#{Gem.current.dir}/#{subdir}/*.{cpp,cxx,cc}") + end.flatten + enable_cxx_exception unless cxx_srcs.empty? + + Gem.current + end + + def load_special_path_gem(params) + if params[:github] + params[:git] = "https://github.com/#{params[:github]}.git" + elsif params[:bitbucket] + if params[:method] == "ssh" + params[:git] = "git@bitbucket.org:#{params[:bitbucket]}.git" + else + params[:git] = "https://bitbucket.org/#{params[:bitbucket]}.git" + end + elsif params[:mgem] + mgem_list_dir = "#{gem_clone_dir}/mgem-list" + mgem_list_url = 'https://github.com/mruby/mgem-list.git' + if File.exist? mgem_list_dir + git.run_pull mgem_list_dir, mgem_list_url if $pull_gems + else + FileUtils.mkdir_p mgem_list_dir + git.run_clone mgem_list_dir, mgem_list_url, "--depth 1" + end + + require 'yaml' + + conf_path = "#{mgem_list_dir}/#{params[:mgem]}.gem" + conf_path = "#{mgem_list_dir}/mruby-#{params[:mgem]}.gem" unless File.exist? conf_path + fail "mgem not found: #{params[:mgem]}" unless File.exist? conf_path + conf = YAML.load File.read conf_path + + fail "unknown mgem protocol: #{conf['protocol']}" if conf['protocol'] != 'git' + params[:git] = conf['repository'] + params[:branch] = conf['branch'] if conf['branch'] + end + + if params[:core] + gemdir = "#{root}/mrbgems/#{params[:core]}" + elsif params[:path] + require 'pathname' + gemdir = Pathname.new(params[:path]).absolute? ? params[:path] : "#{root}/#{params[:path]}" + elsif params[:git] + url = params[:git] + gemdir = "#{gem_clone_dir}/#{url.match(/([-\w]+)(\.[-\w]+|)$/).to_a[1]}" + + # by default the 'master' branch is used + branch = params[:branch] ? params[:branch] : 'master' + + if File.exist?(gemdir) + if $pull_gems + git.run_pull gemdir, url + else + gemdir + end + else + options = [params[:options]] || [] + options << "--recursive" + options << "--branch \"#{branch}\"" + options << "--depth 1" unless params[:checksum_hash] + FileUtils.mkdir_p "#{gem_clone_dir}" + git.run_clone gemdir, url, options + end + + if params[:checksum_hash] + # Jump to the specified commit + git.run_checkout gemdir, params[:checksum_hash] + else + # Jump to the top of the branch + git.run_checkout gemdir, branch if $pull_gems + end + else + fail "unknown gem option #{params}" + end + + gemdir + end + + def enable_gems? + !@gems.empty? + end + end # LoadGems +end # MRuby diff --git a/web/server/h2o/libh2o/deps/mruby/lib/mruby/gem.rb b/web/server/h2o/libh2o/deps/mruby/lib/mruby/gem.rb new file mode 100644 index 00000000..27a1d358 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/lib/mruby/gem.rb @@ -0,0 +1,459 @@ +require 'pathname' +require 'forwardable' +require 'tsort' +require 'shellwords' + +module MRuby + module Gem + class << self + attr_accessor :current + end + LinkerConfig = Struct.new(:libraries, :library_paths, :flags, :flags_before_libraries, :flags_after_libraries) + + class Specification + include Rake::DSL + extend Forwardable + def_delegators :@build, :filename, :objfile, :libfile, :exefile + + attr_accessor :name, :dir, :build + alias mruby build + attr_accessor :build_config_initializer + attr_accessor :mrblib_dir, :objs_dir + + attr_accessor :version + attr_accessor :description, :summary + attr_accessor :homepage + attr_accessor :licenses, :authors + alias :license= :licenses= + alias :author= :authors= + + attr_accessor :rbfiles, :objs + attr_accessor :test_objs, :test_rbfiles, :test_args + attr_accessor :test_preload + + attr_accessor :bins + + attr_accessor :requirements + attr_reader :dependencies, :conflicts + + attr_accessor :export_include_paths + + attr_reader :generate_functions + + attr_block MRuby::Build::COMMANDS + + def initialize(name, &block) + @name = name + @initializer = block + @version = "0.0.0" + @mrblib_dir = "mrblib" + @objs_dir = "src" + MRuby::Gem.current = self + end + + def setup + MRuby::Gem.current = self + MRuby::Build::COMMANDS.each do |command| + instance_variable_set("@#{command}", @build.send(command).clone) + end + @linker = LinkerConfig.new([], [], [], [], []) + + @rbfiles = Dir.glob("#{@dir}/#{@mrblib_dir}/**/*.rb").sort + @objs = Dir.glob("#{@dir}/#{@objs_dir}/*.{c,cpp,cxx,cc,m,asm,s,S}").map do |f| + objfile(f.relative_path_from(@dir).to_s.pathmap("#{build_dir}/%X")) + end + + @test_rbfiles = Dir.glob("#{dir}/test/**/*.rb") + @test_objs = Dir.glob("#{dir}/test/*.{c,cpp,cxx,cc,m,asm,s,S}").map do |f| + objfile(f.relative_path_from(dir).to_s.pathmap("#{build_dir}/%X")) + end + @custom_test_init = !@test_objs.empty? + @test_preload = nil # 'test/assert.rb' + @test_args = {} + + @bins = [] + + @requirements = [] + @dependencies, @conflicts = [], [] + @export_include_paths = [] + @export_include_paths << "#{dir}/include" if File.directory? "#{dir}/include" + + instance_eval(&@initializer) + + @generate_functions = !(@rbfiles.empty? && @objs.empty?) + @objs << objfile("#{build_dir}/gem_init") if @generate_functions + + if !name || !licenses || !authors + fail "#{name || dir} required to set name, license(s) and author(s)" + end + + build.libmruby << @objs + + instance_eval(&@build_config_initializer) if @build_config_initializer + end + + def setup_compilers + compilers.each do |compiler| + compiler.define_rules build_dir, "#{dir}" + compiler.defines << %Q[MRBGEM_#{funcname.upcase}_VERSION=#{version}] + compiler.include_paths << "#{dir}/include" if File.directory? "#{dir}/include" + end + + define_gem_init_builder if @generate_functions + end + + def add_dependency(name, *requirements) + default_gem = requirements.last.kind_of?(Hash) ? requirements.pop : nil + requirements = ['>= 0.0.0'] if requirements.empty? + requirements.flatten! + @dependencies << {:gem => name, :requirements => requirements, :default => default_gem} + end + + def add_test_dependency(*args) + add_dependency(*args) if build.test_enabled? + end + + def add_conflict(name, *req) + @conflicts << {:gem => name, :requirements => req.empty? ? nil : req} + end + + def self.bin=(bin) + @bins = [bin].flatten + end + + def build_dir + "#{build.build_dir}/mrbgems/#{name}" + end + + def test_rbireps + "#{build_dir}/gem_test.c" + end + + def search_package(name, version_query=nil) + package_query = name + package_query += " #{version_query}" if version_query + _pp "PKG-CONFIG", package_query + escaped_package_query = Shellwords.escape(package_query) + if system("pkg-config --exists #{escaped_package_query}") + cc.flags += [`pkg-config --cflags #{escaped_package_query}`.strip] + cxx.flags += [`pkg-config --cflags #{escaped_package_query}`.strip] + linker.flags_before_libraries += [`pkg-config --libs #{escaped_package_query}`.strip] + true + else + false + end + end + + def funcname + @funcname ||= @name.gsub('-', '_') + end + + def compilers + MRuby::Build::COMPILERS.map do |c| + instance_variable_get("@#{c}") + end + end + + def define_gem_init_builder + file objfile("#{build_dir}/gem_init") => [ "#{build_dir}/gem_init.c", File.join(dir, "mrbgem.rake") ] + file "#{build_dir}/gem_init.c" => [build.mrbcfile, __FILE__] + [rbfiles].flatten do |t| + FileUtils.mkdir_p build_dir + generate_gem_init("#{build_dir}/gem_init.c") + end + end + + def generate_gem_init(fname) + open(fname, 'w') do |f| + print_gem_init_header f + build.mrbc.run f, rbfiles, "gem_mrblib_irep_#{funcname}" unless rbfiles.empty? + f.puts %Q[void mrb_#{funcname}_gem_init(mrb_state *mrb);] + f.puts %Q[void mrb_#{funcname}_gem_final(mrb_state *mrb);] + f.puts %Q[] + f.puts %Q[void GENERATED_TMP_mrb_#{funcname}_gem_init(mrb_state *mrb) {] + f.puts %Q[ int ai = mrb_gc_arena_save(mrb);] + f.puts %Q[ mrb_#{funcname}_gem_init(mrb);] if objs != [objfile("#{build_dir}/gem_init")] + unless rbfiles.empty? + f.puts %Q[ mrb_load_irep(mrb, gem_mrblib_irep_#{funcname});] + f.puts %Q[ if (mrb->exc) {] + f.puts %Q[ mrb_print_error(mrb);] + f.puts %Q[ exit(EXIT_FAILURE);] + f.puts %Q[ }] + end + f.puts %Q[ mrb_gc_arena_restore(mrb, ai);] + f.puts %Q[}] + f.puts %Q[] + f.puts %Q[void GENERATED_TMP_mrb_#{funcname}_gem_final(mrb_state *mrb) {] + f.puts %Q[ mrb_#{funcname}_gem_final(mrb);] if objs != [objfile("#{build_dir}/gem_init")] + f.puts %Q[}] + end + end # generate_gem_init + + def print_gem_comment(f) + f.puts %Q[/*] + f.puts %Q[ * This file is loading the irep] + f.puts %Q[ * Ruby GEM code.] + f.puts %Q[ *] + f.puts %Q[ * IMPORTANT:] + f.puts %Q[ * This file was generated!] + f.puts %Q[ * All manual changes will get lost.] + f.puts %Q[ */] + end + + def print_gem_init_header(f) + print_gem_comment(f) + f.puts %Q[#include ] unless rbfiles.empty? + f.puts %Q[#include ] + f.puts %Q[#include ] unless rbfiles.empty? + end + + def print_gem_test_header(f) + print_gem_comment(f) + f.puts %Q[#include ] + f.puts %Q[#include ] + f.puts %Q[#include ] + f.puts %Q[#include ] + f.puts %Q[#include ] + f.puts %Q[#include ] unless test_args.empty? + end + + def test_dependencies + [@name] + end + + def custom_test_init? + @custom_test_init + end + + def version_ok?(req_versions) + req_versions.map do |req| + cmp, ver = req.split + cmp_result = Version.new(version) <=> Version.new(ver) + case cmp + when '=' then cmp_result == 0 + when '!=' then cmp_result != 0 + when '>' then cmp_result == 1 + when '<' then cmp_result == -1 + when '>=' then cmp_result >= 0 + when '<=' then cmp_result <= 0 + when '~>' + Version.new(version).twiddle_wakka_ok?(Version.new(ver)) + else + fail "Comparison not possible with '#{cmp}'" + end + end.all? + end + end # Specification + + class Version + include Comparable + include Enumerable + + def <=>(other) + ret = 0 + own = to_enum + + other.each do |oth| + begin + ret = own.next <=> oth + rescue StopIteration + ret = 0 <=> oth + end + + break unless ret == 0 + end + + ret + end + + # ~> compare algorithm + # + # Example: + # ~> 2.2 means >= 2.2.0 and < 3.0.0 + # ~> 2.2.0 means >= 2.2.0 and < 2.3.0 + def twiddle_wakka_ok?(other) + gr_or_eql = (self <=> other) >= 0 + still_minor = (self <=> other.skip_minor) < 0 + gr_or_eql and still_minor + end + + def skip_minor + a = @ary.dup + a.slice!(-1) + a[-1] = a[-1].succ + a + end + + def initialize(str) + @str = str + @ary = @str.split('.').map(&:to_i) + end + + def each(&block); @ary.each(&block); end + def [](index); @ary[index]; end + def []=(index, value) + @ary[index] = value + @str = @ary.join('.') + end + def slice!(index) + @ary.slice!(index) + @str = @ary.join('.') + end + end # Version + + class List + include Enumerable + + def initialize + @ary = [] + end + + def each(&b) + @ary.each(&b) + end + + def <<(gem) + unless @ary.detect {|g| g.dir == gem.dir } + @ary << gem + else + # GEM was already added to this list + end + end + + def empty? + @ary.empty? + end + + def generate_gem_table build + gem_table = @ary.reduce({}) { |res,v| res[v.name] = v; res } + + default_gems = [] + each do |g| + g.dependencies.each do |dep| + unless gem_table.key? dep[:gem] + if dep[:default]; default_gems << dep + elsif File.exist? "#{MRUBY_ROOT}/mrbgems/#{dep[:gem]}" # check core + default_gems << { :gem => dep[:gem], :default => { :core => dep[:gem] } } + else # fallback to mgem-list + default_gems << { :gem => dep[:gem], :default => { :mgem => dep[:gem] } } + end + end + end + end + + until default_gems.empty? + def_gem = default_gems.pop + + spec = build.gem def_gem[:default] + fail "Invalid gem name: #{spec.name} (Expected: #{def_gem[:gem]})" if spec.name != def_gem[:gem] + spec.setup + + spec.dependencies.each do |dep| + unless gem_table.key? dep[:gem] + if dep[:default]; default_gems << dep + else default_gems << { :gem => dep[:gem], :default => { :mgem => dep[:gem] } } + end + end + end + gem_table[spec.name] = spec + end + + each do |g| + g.dependencies.each do |dep| + name = dep[:gem] + req_versions = dep[:requirements] + dep_g = gem_table[name] + + # check each GEM dependency against all available GEMs + if dep_g.nil? + fail "The GEM '#{g.name}' depends on the GEM '#{name}' but it could not be found" + end + unless dep_g.version_ok? req_versions + fail "#{name} version should be #{req_versions.join(' and ')} but was '#{dep_g.version}'" + end + end + + cfls = g.conflicts.select { |c| + cfl_g = gem_table[c[:gem]] + cfl_g and cfl_g.version_ok?(c[:requirements] || ['>= 0.0.0']) + }.map { |c| "#{c[:gem]}(#{gem_table[c[:gem]].version})" } + fail "Conflicts of gem `#{g.name}` found: #{cfls.join ', '}" unless cfls.empty? + end + + gem_table + end + + def tsort_dependencies ary, table, all_dependency_listed = false + unless all_dependency_listed + left = ary.dup + until left.empty? + v = left.pop + table[v].dependencies.each do |dep| + left.push dep[:gem] + ary.push dep[:gem] + end + end + end + + ary.uniq! + table.instance_variable_set :@root_gems, ary + class << table + include TSort + def tsort_each_node &b + @root_gems.each &b + end + + def tsort_each_child(n, &b) + fetch(n).dependencies.each do |v| + b.call v[:gem] + end + end + end + + begin + table.tsort.map { |v| table[v] } + rescue TSort::Cyclic => e + fail "Circular mrbgem dependency found: #{e.message}" + end + end + + def check(build) + gem_table = generate_gem_table build + + @ary = tsort_dependencies gem_table.keys, gem_table, true + + each(&:setup_compilers) + + each do |g| + import_include_paths(g) + end + end + + def import_include_paths(g) + gem_table = @ary.reduce({}) { |res,v| res[v.name] = v; res } + g.dependencies.each do |dep| + dep_g = gem_table[dep[:gem]] + # We can do recursive call safely + # as circular dependency has already detected in the caller. + import_include_paths(dep_g) + + dep_g.export_include_paths.uniq! + g.compilers.each do |compiler| + compiler.include_paths += dep_g.export_include_paths + g.export_include_paths += dep_g.export_include_paths + compiler.include_paths.uniq! + g.export_include_paths.uniq! + end + end + end + end # List + end # Gem + + GemBox = Object.new + class << GemBox + attr_accessor :path + + def new(&block); block.call(self); end + def config=(obj); @config = obj; end + def gem(gemdir, &block); @config.gem(gemdir, &block); end + end # GemBox +end # MRuby diff --git a/web/server/h2o/libh2o/deps/mruby/lib/mruby/source.rb b/web/server/h2o/libh2o/deps/mruby/lib/mruby/source.rb new file mode 100644 index 00000000..5819a322 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/lib/mruby/source.rb @@ -0,0 +1,30 @@ +require "pathname" + +module MRuby + module Source + # MRuby's source root directory + ROOT = Pathname.new(File.expand_path('../../../',__FILE__)) + + # Reads a constant defined at version.h + MRUBY_READ_VERSION_CONSTANT = Proc.new { |name| ROOT.join('include','mruby','version.h').read.match(/^#define #{name} +"?([\w\. ]+)"?$/)[1] } + + MRUBY_RUBY_VERSION = MRUBY_READ_VERSION_CONSTANT['MRUBY_RUBY_VERSION'] + MRUBY_RUBY_ENGINE = MRUBY_READ_VERSION_CONSTANT['MRUBY_RUBY_ENGINE'] + + MRUBY_RELEASE_MAJOR = Integer(MRUBY_READ_VERSION_CONSTANT['MRUBY_RELEASE_MAJOR']) + MRUBY_RELEASE_MINOR = Integer(MRUBY_READ_VERSION_CONSTANT['MRUBY_RELEASE_MINOR']) + MRUBY_RELEASE_TEENY = Integer(MRUBY_READ_VERSION_CONSTANT['MRUBY_RELEASE_TEENY']) + + MRUBY_VERSION = [MRUBY_RELEASE_MAJOR,MRUBY_RELEASE_MINOR,MRUBY_RELEASE_TEENY].join('.') + MRUBY_RELEASE_NO = (MRUBY_RELEASE_MAJOR * 100 * 100 + MRUBY_RELEASE_MINOR * 100 + MRUBY_RELEASE_TEENY) + + MRUBY_RELEASE_YEAR = Integer(MRUBY_READ_VERSION_CONSTANT['MRUBY_RELEASE_YEAR']) + MRUBY_RELEASE_MONTH = Integer(MRUBY_READ_VERSION_CONSTANT['MRUBY_RELEASE_MONTH']) + MRUBY_RELEASE_DAY = Integer(MRUBY_READ_VERSION_CONSTANT['MRUBY_RELEASE_DAY']) + MRUBY_RELEASE_DATE = [MRUBY_RELEASE_YEAR,MRUBY_RELEASE_MONTH,MRUBY_RELEASE_DAY].join('.') + + MRUBY_BIRTH_YEAR = Integer(MRUBY_READ_VERSION_CONSTANT['MRUBY_BIRTH_YEAR']) + + MRUBY_AUTHOR = MRUBY_READ_VERSION_CONSTANT['MRUBY_AUTHOR'] + end +end diff --git a/web/server/h2o/libh2o/deps/mruby/minirake b/web/server/h2o/libh2o/deps/mruby/minirake new file mode 100755 index 00000000..542c37a7 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/minirake @@ -0,0 +1,484 @@ +#!/usr/bin/env ruby + +# Original is https://github.com/jimweirich/rake/ +# Copyright (c) 2003 Jim Weirich +# License: MIT-LICENSE + +require 'getoptlong' +require 'fileutils' + +class String + def ext(newext='') + return self.dup if ['.', '..'].include? self + if newext != '' + newext = (newext =~ /^\./) ? newext : ("." + newext) + end + self.chomp(File.extname(self)) << newext + end + + def pathmap(spec=nil, &block) + return self if spec.nil? + result = '' + spec.scan(/%\{[^}]*\}-?\d*[sdpfnxX%]|%-?\d+d|%.|[^%]+/) do |frag| + case frag + when '%f' + result << File.basename(self) + when '%n' + result << File.basename(self).ext + when '%d' + result << File.dirname(self) + when '%x' + result << File.extname(self) + when '%X' + result << self.ext + when '%p' + result << self + when '%s' + result << (File::ALT_SEPARATOR || File::SEPARATOR) + when '%-' + # do nothing + when '%%' + result << "%" + when /%(-?\d+)d/ + result << pathmap_partial($1.to_i) + when /^%\{([^}]*)\}(\d*[dpfnxX])/ + patterns, operator = $1, $2 + result << pathmap('%' + operator).pathmap_replace(patterns, &block) + when /^%/ + fail ArgumentError, "Unknown pathmap specifier #{frag} in '#{spec}'" + else + result << frag + end + end + result + end +end + +module MiniRake + class Task + TASKS = Hash.new + RULES = Array.new + + # List of prerequisites for a task. + attr_reader :prerequisites + + # Source dependency for rule synthesized tasks. Nil if task was not + # sythesized from a rule. + attr_accessor :source + + # Create a task named +task_name+ with no actions or prerequisites.. + # use +enhance+ to add actions and prerequisites. + def initialize(task_name) + @name = task_name + @prerequisites = [] + @actions = [] + end + + # Enhance a task with prerequisites or actions. Returns self. + def enhance(deps=nil, &block) + @prerequisites |= deps if deps + @actions << block if block_given? + self + end + + # Name of the task. + def name + @name.to_s + end + + # Invoke the task if it is needed. Prerequites are invoked first. + def invoke + puts "Invoke #{name} (already=[#{@already_invoked}], needed=[#{needed?}])" if $trace + return if @already_invoked + @already_invoked = true + prerequisites = @prerequisites.collect{ |n| n.is_a?(Proc) ? n.call(name) : n }.flatten + prerequisites.each { |n| Task[n].invoke } + execute if needed? + end + + # Execute the actions associated with this task. + def execute + puts "Execute #{name}" if $trace + self.class.enhance_with_matching_rule(name) if @actions.empty? + unless $dryrun + @actions.each { |act| act.call(self) } + end + end + + # Is this task needed? + def needed? + true + end + + # Timestamp for this task. Basic tasks return the current time for + # their time stamp. Other tasks can be more sophisticated. + def timestamp + Time.now + end + + # Class Methods ---------------------------------------------------- + + class << self + + # Clear the task list. This cause rake to immediately forget all + # the tasks that have been assigned. (Normally used in the unit + # tests.) + def clear + TASKS.clear + RULES.clear + end + + # List of all defined tasks. + def tasks + TASKS.keys.sort.collect { |tn| Task[tn] } + end + + # Return a task with the given name. If the task is not currently + # known, try to synthesize one from the defined rules. If no + # rules are found, but an existing file matches the task name, + # assume it is a file task with no dependencies or actions. + def [](task_name) + task_name = task_name.to_s + if task = TASKS[task_name] + return task + end + if task = enhance_with_matching_rule(task_name) + return task + end + if File.exist?(task_name) + return FileTask.define_task(task_name) + end + fail "Don't know how to rake #{task_name}" + end + + # Define a task given +args+ and an option block. If a rule with + # the given name already exists, the prerequisites and actions are + # added to the existing task. + def define_task(args, &block) + task_name, deps = resolve_args(args) + lookup(task_name).enhance([deps].flatten, &block) + end + + # Define a rule for synthesizing tasks. + def create_rule(args, &block) + pattern, deps = resolve_args(args) + pattern = Regexp.new(Regexp.quote(pattern) + '$') if String === pattern + RULES << [pattern, deps, block] + end + + + # Lookup a task. Return an existing task if found, otherwise + # create a task of the current type. + def lookup(task_name) + name = task_name.to_s + TASKS[name] ||= self.new(name) + end + + # If a rule can be found that matches the task name, enhance the + # task with the prerequisites and actions from the rule. Set the + # source attribute of the task appropriately for the rule. Return + # the enhanced task or nil of no rule was found. + def enhance_with_matching_rule(task_name) + RULES.each do |pattern, extensions, block| + if pattern.match(task_name) + ext = extensions.first + deps = extensions[1..-1] + case ext + when String + source = task_name.sub(/\.[^.]*$/, ext) + when Proc + source = ext.call(task_name) + else + fail "Don't know how to handle rule dependent: #{ext.inspect}" + end + if File.exist?(source) + task = FileTask.define_task({task_name => [source]+deps}, &block) + task.source = source + return task + end + end + end + nil + end + + private + + # Resolve the arguments for a task/rule. + def resolve_args(args) + case args + when Hash + fail "Too Many Task Names: #{args.keys.join(' ')}" if args.size > 1 + fail "No Task Name Given" if args.size < 1 + task_name = args.keys[0] + deps = args[task_name] + deps = [deps] if (String===deps) || (Regexp===deps) || (Proc===deps) + else + task_name = args + deps = [] + end + [task_name, deps] + end + end + end + + + ###################################################################### + class FileTask < Task + # Is this file task needed? Yes if it doesn't exist, or if its time + # stamp is out of date. + def needed? + return true unless File.exist?(name) + prerequisites = @prerequisites.collect{ |n| n.is_a?(Proc) ? n.call(name) : n }.flatten + latest_prereq = prerequisites.collect{|n| Task[n].timestamp}.max + return false if latest_prereq.nil? + timestamp < latest_prereq + end + + # Time stamp for file task. + def timestamp + return Time.at(0) unless File.exist?(name) + stat = File::stat(name.to_s) + stat.directory? ? Time.at(0) : stat.mtime + end + end + + module DSL + # Declare a basic task. + def task(args, &block) + MiniRake::Task.define_task(args, &block) + end + + # Declare a file task. + def file(args, &block) + MiniRake::FileTask.define_task(args, &block) + end + + # Declare a set of files tasks to create the given directories on + # demand. + def directory(args, &block) + MiniRake::FileTask.define_task(args) do |t| + block.call(t) unless block.nil? + dir = args.is_a?(Hash) ? args.keys.first : args + (dir.split(File::SEPARATOR) + ['']).inject do |acc, part| + (acc + File::SEPARATOR).tap do |d| + Dir.mkdir(d) unless File.exists? d + end + part + end + end + end + + # Declare a rule for auto-tasks. + def rule(args, &block) + MiniRake::Task.create_rule(args, &block) + end + + # Write a message to standard out if $verbose is enabled. + def log(msg) + print " " if $trace && $verbose + puts msg if $verbose + end + + # Run the system command +cmd+. + def sh(cmd) + puts cmd if $verbose + system(cmd) or fail "Command Failed: [#{cmd}]" + end + + def desc(text) + end + end +end + +Rake = MiniRake +extend MiniRake::DSL + + +###################################################################### +# Task Definition Functions ... + +###################################################################### +# Rake main application object. When invoking +rake+ from the command +# line, a RakeApp object is created and run. +# +class RakeApp + RAKEFILES = ['rakefile', 'Rakefile'] + + OPTIONS = [ + ['--dry-run', '-n', GetoptLong::NO_ARGUMENT, + "Do a dry run without executing actions."], + ['--help', '-H', GetoptLong::NO_ARGUMENT, + "Display this help message."], + ['--libdir', '-I', GetoptLong::REQUIRED_ARGUMENT, + "Include LIBDIR in the search path for required modules."], + ['--nosearch', '-N', GetoptLong::NO_ARGUMENT, + "Do not search parent directories for the Rakefile."], + ['--quiet', '-q', GetoptLong::NO_ARGUMENT, + "Do not log messages to standard output (default)."], + ['--rakefile', '-f', GetoptLong::REQUIRED_ARGUMENT, + "Use FILE as the rakefile."], + ['--require', '-r', GetoptLong::REQUIRED_ARGUMENT, + "Require MODULE before executing rakefile."], + ['--tasks', '-T', GetoptLong::NO_ARGUMENT, + "Display the tasks and dependencies, then exit."], + ['--pull-gems','-p', GetoptLong::NO_ARGUMENT, + "Pull all git mrbgems."], + ['--trace', '-t', GetoptLong::NO_ARGUMENT, + "Turn on invoke/execute tracing."], + ['--usage', '-h', GetoptLong::NO_ARGUMENT, + "Display usage."], + ['--verbose', '-v', GetoptLong::NO_ARGUMENT, + "Log message to standard output."], + ['--directory', '-C', GetoptLong::REQUIRED_ARGUMENT, + "Change executing directory of rakefiles."] + ] + + # Create a RakeApp object. + def initialize + @rakefile = nil + @nosearch = false + end + + # True if one of the files in RAKEFILES is in the current directory. + # If a match is found, it is copied into @rakefile. + def have_rakefile + RAKEFILES.each do |fn| + if File.exist?(fn) + @rakefile = fn + return true + end + end + return false + end + + # Display the program usage line. + def usage + puts "rake [-f rakefile] {options} targets..." + end + + # Display the rake command line help. + def help + usage + puts + puts "Options are ..." + puts + OPTIONS.sort.each do |long, short, mode, desc| + if mode == GetoptLong::REQUIRED_ARGUMENT + if desc =~ /\b([A-Z]{2,})\b/ + long = long + "=#{$1}" + end + end + printf " %-20s (%s)\n", long, short + printf " %s\n", desc + end + end + + # Display the tasks and dependencies. + def display_tasks + MiniRake::Task.tasks.each do |t| + puts "#{t.class} #{t.name}" + t.prerequisites.each { |pre| puts " #{pre}" } + end + end + + # Return a list of the command line options supported by the + # program. + def command_line_options + OPTIONS.collect { |lst| lst[0..-2] } + end + + # Do the option defined by +opt+ and +value+. + def do_option(opt, value) + case opt + when '--dry-run' + $dryrun = true + $trace = true + when '--help' + help + exit + when '--libdir' + $:.push(value) + when '--nosearch' + @nosearch = true + when '--quiet' + $verbose = false + when '--rakefile' + RAKEFILES.clear + RAKEFILES << value + when '--require' + require value + when '--tasks' + $show_tasks = true + when '--pull-gems' + $pull_gems = true + when '--trace' + $trace = true + when '--usage' + usage + exit + when '--verbose' + $verbose = true + when '--version' + puts "rake, version #{RAKEVERSION}" + exit + when '--directory' + Dir.chdir value + else + fail "Unknown option: #{opt}" + end + end + + # Read and handle the command line options. + def handle_options + $verbose = false + $pull_gems = false + opts = GetoptLong.new(*command_line_options) + opts.each { |opt, value| do_option(opt, value) } + end + + # Run the +rake+ application. + def run + handle_options + begin + here = Dir.pwd + while ! have_rakefile + Dir.chdir("..") + if Dir.pwd == here || @nosearch + fail "No Rakefile found (looking for: #{RAKEFILES.join(', ')})" + end + here = Dir.pwd + end + tasks = [] + ARGV.each do |task_name| + if /^(\w+)=(.*)/.match(task_name) + ENV[$1] = $2 + else + tasks << task_name + end + end + puts "(in #{Dir.pwd})" + $rakefile = @rakefile + load @rakefile + if $show_tasks + display_tasks + else + tasks.push("default") if tasks.size == 0 + tasks.each do |task_name| + MiniRake::Task[task_name].invoke + end + end + rescue Exception => ex + puts "rake aborted!" + puts ex.message + if $trace + puts ex.backtrace.join("\n") + else + puts ex.backtrace.find {|str| str =~ /#{@rakefile}/ } || "" + end + exit 1 + end + end +end + +if __FILE__ == $0 then + RakeApp.new.run +end diff --git a/web/server/h2o/libh2o/deps/mruby/mrbgems/default.gembox b/web/server/h2o/libh2o/deps/mruby/mrbgems/default.gembox new file mode 100644 index 00000000..64f05de1 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/mrbgems/default.gembox @@ -0,0 +1,79 @@ +MRuby::GemBox.new do |conf| + # Use standard Kernel#sprintf method + conf.gem :core => "mruby-sprintf" + + # Use standard print/puts/p + conf.gem :core => "mruby-print" + + # Use standard Math module + conf.gem :core => "mruby-math" + + # Use standard Time class + conf.gem :core => "mruby-time" + + # Use standard Struct class + conf.gem :core => "mruby-struct" + + # Use Enumerable module extension + conf.gem :core => "mruby-enum-ext" + + # Use String class extension + conf.gem :core => "mruby-string-ext" + + # Use Numeric class extension + conf.gem :core => "mruby-numeric-ext" + + # Use Array class extension + conf.gem :core => "mruby-array-ext" + + # Use Hash class extension + conf.gem :core => "mruby-hash-ext" + + # Use Range class extension + conf.gem :core => "mruby-range-ext" + + # Use Proc class extension + conf.gem :core => "mruby-proc-ext" + + # Use Symbol class extension + conf.gem :core => "mruby-symbol-ext" + + # Use Random class + conf.gem :core => "mruby-random" + + # Use Object class extension + conf.gem :core => "mruby-object-ext" + + # Use ObjectSpace class + conf.gem :core => "mruby-objectspace" + + # Use Fiber class + conf.gem :core => "mruby-fiber" + + # Use Enumerator class (require mruby-fiber) + conf.gem :core => "mruby-enumerator" + + # Use Enumerator::Lazy class (require mruby-enumerator) + conf.gem :core => "mruby-enum-lazy" + + # Use toplevel object (main) methods extension + conf.gem :core => "mruby-toplevel-ext" + + # Generate mirb command + conf.gem :core => "mruby-bin-mirb" + + # Generate mruby command + conf.gem :core => "mruby-bin-mruby" + + # Generate mruby-strip command + conf.gem :core => "mruby-bin-strip" + + # Use Kernel module extension + conf.gem :core => "mruby-kernel-ext" + + # Use class/module extension + conf.gem :core => "mruby-class-ext" + + # Use mruby-compiler to build other mrbgems + conf.gem :core => "mruby-compiler" +end diff --git a/web/server/h2o/libh2o/deps/mruby/mrbgems/full-core.gembox b/web/server/h2o/libh2o/deps/mruby/mrbgems/full-core.gembox new file mode 100644 index 00000000..9a5b7081 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/mrbgems/full-core.gembox @@ -0,0 +1,9 @@ +MRuby::GemBox.new do |conf| + conf.gem :core => "mruby-sprintf" + conf.gem :core => "mruby-print" + + Dir.glob("#{root}/mrbgems/mruby-*/mrbgem.rake") do |x| + g = File.basename File.dirname x + conf.gem :core => g unless g =~ /^mruby-(print|sprintf|bin-debugger|test)$/ + end +end diff --git a/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-array-ext/mrbgem.rake b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-array-ext/mrbgem.rake new file mode 100644 index 00000000..882caf1a --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-array-ext/mrbgem.rake @@ -0,0 +1,5 @@ +MRuby::Gem::Specification.new('mruby-array-ext') do |spec| + spec.license = 'MIT' + spec.author = 'mruby developers' + spec.summary = 'Array class extension' +end diff --git a/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-array-ext/mrblib/array.rb b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-array-ext/mrblib/array.rb new file mode 100644 index 00000000..e28e5238 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-array-ext/mrblib/array.rb @@ -0,0 +1,811 @@ +class Array + ## + # call-seq: + # Array.try_convert(obj) -> array or nil + # + # Tries to convert +obj+ into an array, using +to_ary+ method. + # converted array or +nil+ if +obj+ cannot be converted for any reason. + # This method can be used to check if an argument is an array. + # + # Array.try_convert([1]) #=> [1] + # Array.try_convert("1") #=> nil + # + # if tmp = Array.try_convert(arg) + # # the argument is an array + # elsif tmp = String.try_convert(arg) + # # the argument is a string + # end + # + def self.try_convert(obj) + if obj.respond_to?(:to_ary) + obj.to_ary + else + nil + end + end + + ## + # call-seq: + # ary.uniq! -> ary or nil + # ary.uniq! { |item| ... } -> ary or nil + # + # Removes duplicate elements from +self+. + # Returns nil if no changes are made (that is, no + # duplicates are found). + # + # a = [ "a", "a", "b", "b", "c" ] + # a.uniq! #=> ["a", "b", "c"] + # b = [ "a", "b", "c" ] + # b.uniq! #=> nil + # c = [["student","sam"], ["student","george"], ["teacher","matz"]] + # c.uniq! { |s| s.first } # => [["student", "sam"], ["teacher", "matz"]] + # + def uniq!(&block) + ary = self.dup + result = [] + if block + hash = {} + while ary.size > 0 + val = ary.shift + key = block.call(val) + hash[key] = val unless hash.has_key?(key) + end + hash.each_value do |value| + result << value + end + else + while ary.size > 0 + result << ary.shift + ary.delete(result.last) + end + end + if result.size == self.size + nil + else + self.replace(result) + end + end + + ## + # call-seq: + # ary.uniq -> new_ary + # ary.uniq { |item| ... } -> new_ary + # + # Returns a new array by removing duplicate values in +self+. + # + # a = [ "a", "a", "b", "b", "c" ] + # a.uniq #=> ["a", "b", "c"] + # + # b = [["student","sam"], ["student","george"], ["teacher","matz"]] + # b.uniq { |s| s.first } # => [["student", "sam"], ["teacher", "matz"]] + # + def uniq(&block) + ary = self.dup + ary.uniq!(&block) + ary + end + + ## + # call-seq: + # ary - other_ary -> new_ary + # + # Array Difference---Returns a new array that is a copy of + # the original array, removing any items that also appear in + # other_ary. (If you need set-like behavior, see the + # library class Set.) + # + # [ 1, 1, 2, 2, 3, 3, 4, 5 ] - [ 1, 2, 4 ] #=> [ 3, 3, 5 ] + # + def -(elem) + raise TypeError, "can't convert #{elem.class} into Array" unless elem.class == Array + + hash = {} + array = [] + idx = 0 + len = elem.size + while idx < len + hash[elem[idx]] = true + idx += 1 + end + idx = 0 + len = size + while idx < len + v = self[idx] + array << v unless hash[v] + idx += 1 + end + array + end + + ## + # call-seq: + # ary | other_ary -> new_ary + # + # Set Union---Returns a new array by joining this array with + # other_ary, removing duplicates. + # + # [ "a", "b", "c" ] | [ "c", "d", "a" ] + # #=> [ "a", "b", "c", "d" ] + # + def |(elem) + raise TypeError, "can't convert #{elem.class} into Array" unless elem.class == Array + + ary = self + elem + ary.uniq! or ary + end + + ## + # call-seq: + # ary & other_ary -> new_ary + # + # Set Intersection---Returns a new array + # containing elements common to the two arrays, with no duplicates. + # + # [ 1, 1, 3, 5 ] & [ 1, 2, 3 ] #=> [ 1, 3 ] + # + def &(elem) + raise TypeError, "can't convert #{elem.class} into Array" unless elem.class == Array + + hash = {} + array = [] + idx = 0 + len = elem.size + while idx < len + hash[elem[idx]] = true + idx += 1 + end + idx = 0 + len = size + while idx < len + v = self[idx] + if hash[v] + array << v + hash.delete v + end + idx += 1 + end + array + end + + ## + # call-seq: + # ary.flatten -> new_ary + # ary.flatten(level) -> new_ary + # + # Returns a new array that is a one-dimensional flattening of this + # array (recursively). That is, for every element that is an array, + # extract its elements into the new array. If the optional + # level argument determines the level of recursion to flatten. + # + # s = [ 1, 2, 3 ] #=> [1, 2, 3] + # t = [ 4, 5, 6, [7, 8] ] #=> [4, 5, 6, [7, 8]] + # a = [ s, t, 9, 10 ] #=> [[1, 2, 3], [4, 5, 6, [7, 8]], 9, 10] + # a.flatten #=> [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] + # a = [ 1, 2, [3, [4, 5] ] ] + # a.flatten(1) #=> [1, 2, 3, [4, 5]] + # + def flatten(depth=nil) + res = dup + res.flatten! depth + res + end + + ## + # call-seq: + # ary.flatten! -> ary or nil + # ary.flatten!(level) -> array or nil + # + # Flattens +self+ in place. + # Returns nil if no modifications were made (i.e., + # ary contains no subarrays.) If the optional level + # argument determines the level of recursion to flatten. + # + # a = [ 1, 2, [3, [4, 5] ] ] + # a.flatten! #=> [1, 2, 3, 4, 5] + # a.flatten! #=> nil + # a #=> [1, 2, 3, 4, 5] + # a = [ 1, 2, [3, [4, 5] ] ] + # a.flatten!(1) #=> [1, 2, 3, [4, 5]] + # + def flatten!(depth=nil) + modified = false + ar = [] + idx = 0 + len = size + while idx < len + e = self[idx] + if e.is_a?(Array) && (depth.nil? || depth > 0) + ar += e.flatten(depth.nil? ? nil : depth - 1) + modified = true + else + ar << e + end + idx += 1 + end + if modified + self.replace(ar) + else + nil + end + end + + ## + # call-seq: + # ary.compact -> new_ary + # + # Returns a copy of +self+ with all +nil+ elements removed. + # + # [ "a", nil, "b", nil, "c", nil ].compact + # #=> [ "a", "b", "c" ] + # + def compact + result = self.dup + result.compact! + result + end + + ## + # call-seq: + # ary.compact! -> ary or nil + # + # Removes +nil+ elements from the array. + # Returns +nil+ if no changes were made, otherwise returns + # ary. + # + # [ "a", nil, "b", nil, "c" ].compact! #=> [ "a", "b", "c" ] + # [ "a", "b", "c" ].compact! #=> nil + # + def compact! + result = self.select { |e| !e.nil? } + if result.size == self.size + nil + else + self.replace(result) + end + end + + # for efficiency + def reverse_each(&block) + return to_enum :reverse_each unless block + + i = self.size - 1 + while i>=0 + block.call(self[i]) + i -= 1 + end + self + end + + NONE=Object.new + ## + # call-seq: + # ary.fetch(index) -> obj + # ary.fetch(index, default) -> obj + # ary.fetch(index) { |index| block } -> obj + # + # Tries to return the element at position +index+, but throws an IndexError + # exception if the referenced +index+ lies outside of the array bounds. This + # error can be prevented by supplying a second argument, which will act as a + # +default+ value. + # + # Alternatively, if a block is given it will only be executed when an + # invalid +index+ is referenced. + # + # Negative values of +index+ count from the end of the array. + # + # a = [ 11, 22, 33, 44 ] + # a.fetch(1) #=> 22 + # a.fetch(-1) #=> 44 + # a.fetch(4, 'cat') #=> "cat" + # a.fetch(100) { |i| puts "#{i} is out of bounds" } + # #=> "100 is out of bounds" + # + + def fetch(n=nil, ifnone=NONE, &block) + warn "block supersedes default value argument" if !n.nil? && ifnone != NONE && block + + idx = n + if idx < 0 + idx += size + end + if idx < 0 || size <= idx + return block.call(n) if block + if ifnone == NONE + raise IndexError, "index #{n} outside of array bounds: #{-size}...#{size}" + end + return ifnone + end + self[idx] + end + + ## + # call-seq: + # ary.fill(obj) -> ary + # ary.fill(obj, start [, length]) -> ary + # ary.fill(obj, range ) -> ary + # ary.fill { |index| block } -> ary + # ary.fill(start [, length] ) { |index| block } -> ary + # ary.fill(range) { |index| block } -> ary + # + # The first three forms set the selected elements of +self+ (which + # may be the entire array) to +obj+. + # + # A +start+ of +nil+ is equivalent to zero. + # + # A +length+ of +nil+ is equivalent to the length of the array. + # + # The last three forms fill the array with the value of the given block, + # which is passed the absolute index of each element to be filled. + # + # Negative values of +start+ count from the end of the array, where +-1+ is + # the last element. + # + # a = [ "a", "b", "c", "d" ] + # a.fill("x") #=> ["x", "x", "x", "x"] + # a.fill("w", -1) #=> ["x", "x", "x", "w"] + # a.fill("z", 2, 2) #=> ["x", "x", "z", "z"] + # a.fill("y", 0..1) #=> ["y", "y", "z", "z"] + # a.fill { |i| i*i } #=> [0, 1, 4, 9] + # a.fill(-2) { |i| i*i*i } #=> [0, 1, 8, 27] + # a.fill(1, 2) { |i| i+1 } #=> [0, 2, 3, 27] + # a.fill(0..1) { |i| i+1 } #=> [1, 2, 3, 27] + # + + def fill(arg0=nil, arg1=nil, arg2=nil, &block) + if arg0.nil? && arg1.nil? && arg2.nil? && !block + raise ArgumentError, "wrong number of arguments (0 for 1..3)" + end + + beg = len = 0 + ary = [] + if block + if arg0.nil? && arg1.nil? && arg2.nil? + # ary.fill { |index| block } -> ary + beg = 0 + len = self.size + elsif !arg0.nil? && arg0.kind_of?(Range) + # ary.fill(range) { |index| block } -> ary + beg = arg0.begin + beg += self.size if beg < 0 + len = arg0.end + len += self.size if len < 0 + len += 1 unless arg0.exclude_end? + elsif !arg0.nil? + # ary.fill(start [, length] ) { |index| block } -> ary + beg = arg0 + beg += self.size if beg < 0 + if arg1.nil? + len = self.size + else + len = arg0 + arg1 + end + end + else + if !arg0.nil? && arg1.nil? && arg2.nil? + # ary.fill(obj) -> ary + beg = 0 + len = self.size + elsif !arg0.nil? && !arg1.nil? && arg1.kind_of?(Range) + # ary.fill(obj, range ) -> ary + beg = arg1.begin + beg += self.size if beg < 0 + len = arg1.end + len += self.size if len < 0 + len += 1 unless arg1.exclude_end? + elsif !arg0.nil? && !arg1.nil? + # ary.fill(obj, start [, length]) -> ary + beg = arg1 + beg += self.size if beg < 0 + if arg2.nil? + len = self.size + else + len = beg + arg2 + end + end + end + + i = beg + if block + while i < len + self[i] = block.call(i) + i += 1 + end + else + while i < len + self[i] = arg0 + i += 1 + end + end + self + end + + ## + # call-seq: + # ary.rotate(count=1) -> new_ary + # + # Returns a new array by rotating +self+ so that the element at +count+ is + # the first element of the new array. + # + # If +count+ is negative then it rotates in the opposite direction, starting + # from the end of +self+ where +-1+ is the last element. + # + # a = [ "a", "b", "c", "d" ] + # a.rotate #=> ["b", "c", "d", "a"] + # a #=> ["a", "b", "c", "d"] + # a.rotate(2) #=> ["c", "d", "a", "b"] + # a.rotate(-3) #=> ["b", "c", "d", "a"] + + def rotate(count=1) + ary = [] + len = self.length + + if len > 0 + idx = (count < 0) ? (len - (~count % len) - 1) : (count % len) # rotate count + len.times do + ary << self[idx] + idx += 1 + idx = 0 if idx > len-1 + end + end + ary + end + + ## + # call-seq: + # ary.rotate!(count=1) -> ary + # + # Rotates +self+ in place so that the element at +count+ comes first, and + # returns +self+. + # + # If +count+ is negative then it rotates in the opposite direction, starting + # from the end of the array where +-1+ is the last element. + # + # a = [ "a", "b", "c", "d" ] + # a.rotate! #=> ["b", "c", "d", "a"] + # a #=> ["b", "c", "d", "a"] + # a.rotate!(2) #=> ["d", "a", "b", "c"] + # a.rotate!(-3) #=> ["a", "b", "c", "d"] + + def rotate!(count=1) + self.replace(self.rotate(count)) + end + + ## + # call-seq: + # ary.delete_if { |item| block } -> ary + # ary.delete_if -> Enumerator + # + # Deletes every element of +self+ for which block evaluates to +true+. + # + # The array is changed instantly every time the block is called, not after + # the iteration is over. + # + # See also Array#reject! + # + # If no block is given, an Enumerator is returned instead. + # + # scores = [ 97, 42, 75 ] + # scores.delete_if {|score| score < 80 } #=> [97] + + def delete_if(&block) + return to_enum :delete_if unless block + + idx = 0 + while idx < self.size do + if block.call(self[idx]) + self.delete_at(idx) + else + idx += 1 + end + end + self + end + + ## + # call-seq: + # ary.reject! { |item| block } -> ary or nil + # ary.reject! -> Enumerator + # + # Equivalent to Array#delete_if, deleting elements from +self+ for which the + # block evaluates to +true+, but returns +nil+ if no changes were made. + # + # The array is changed instantly every time the block is called, not after + # the iteration is over. + # + # See also Enumerable#reject and Array#delete_if. + # + # If no block is given, an Enumerator is returned instead. + + def reject!(&block) + return to_enum :reject! unless block + + len = self.size + idx = 0 + while idx < self.size do + if block.call(self[idx]) + self.delete_at(idx) + else + idx += 1 + end + end + if self.size == len + nil + else + self + end + end + + ## + # call-seq: + # ary.insert(index, obj...) -> ary + # + # Inserts the given values before the element with the given +index+. + # + # Negative indices count backwards from the end of the array, where +-1+ is + # the last element. + # + # a = %w{ a b c d } + # a.insert(2, 99) #=> ["a", "b", 99, "c", "d"] + # a.insert(-2, 1, 2, 3) #=> ["a", "b", 99, "c", 1, 2, 3, "d"] + + def insert(idx, *args) + idx += self.size + 1 if idx < 0 + self[idx, 0] = args + self + end + + ## + # call-seq: + # ary.bsearch {|x| block } -> elem + # + # By using binary search, finds a value from this array which meets + # the given condition in O(log n) where n is the size of the array. + # + # You can use this method in two use cases: a find-minimum mode and + # a find-any mode. In either case, the elements of the array must be + # monotone (or sorted) with respect to the block. + # + # In find-minimum mode (this is a good choice for typical use case), + # the block must return true or false, and there must be an index i + # (0 <= i <= ary.size) so that: + # + # - the block returns false for any element whose index is less than + # i, and + # - the block returns true for any element whose index is greater + # than or equal to i. + # + # This method returns the i-th element. If i is equal to ary.size, + # it returns nil. + # + # ary = [0, 4, 7, 10, 12] + # ary.bsearch {|x| x >= 4 } #=> 4 + # ary.bsearch {|x| x >= 6 } #=> 7 + # ary.bsearch {|x| x >= -1 } #=> 0 + # ary.bsearch {|x| x >= 100 } #=> nil + # + # In find-any mode (this behaves like libc's bsearch(3)), the block + # must return a number, and there must be two indices i and j + # (0 <= i <= j <= ary.size) so that: + # + # - the block returns a positive number for ary[k] if 0 <= k < i, + # - the block returns zero for ary[k] if i <= k < j, and + # - the block returns a negative number for ary[k] if + # j <= k < ary.size. + # + # Under this condition, this method returns any element whose index + # is within i...j. If i is equal to j (i.e., there is no element + # that satisfies the block), this method returns nil. + # + # ary = [0, 4, 7, 10, 12] + # # try to find v such that 4 <= v < 8 + # ary.bsearch {|x| 1 - (x / 4).truncate } #=> 4 or 7 + # # try to find v such that 8 <= v < 10 + # ary.bsearch {|x| 4 - (x / 2).truncate } #=> nil + # + # You must not mix the two modes at a time; the block must always + # return either true/false, or always return a number. It is + # undefined which value is actually picked up at each iteration. + + def bsearch(&block) + return to_enum :bsearch unless block + + if idx = bsearch_index(&block) + self[idx] + else + nil + end + end + + ## + # call-seq: + # ary.bsearch_index {|x| block } -> int or nil + # + # By using binary search, finds an index of a value from this array which + # meets the given condition in O(log n) where n is the size of the array. + # + # It supports two modes, depending on the nature of the block and they are + # exactly the same as in the case of #bsearch method with the only difference + # being that this method returns the index of the element instead of the + # element itself. For more details consult the documentation for #bsearch. + + def bsearch_index(&block) + return to_enum :bsearch_index unless block + + low = 0 + high = size + satisfied = false + + while low < high + mid = ((low+high)/2).truncate + res = block.call self[mid] + + case res + when 0 # find-any mode: Found! + return mid + when Numeric # find-any mode: Continue... + in_lower_half = res < 0 + when true # find-min mode + in_lower_half = true + satisfied = true + when false, nil # find-min mode + in_lower_half = false + else + raise TypeError, 'invalid block result (must be numeric, true, false or nil)' + end + + if in_lower_half + high = mid + else + low = mid + 1 + end + end + + satisfied ? low : nil + end + + ## + # call-seq: + # ary.delete_if { |item| block } -> ary + # ary.delete_if -> Enumerator + # + # Deletes every element of +self+ for which block evaluates to +true+. + # + # The array is changed instantly every time the block is called, not after + # the iteration is over. + # + # See also Array#reject! + # + # If no block is given, an Enumerator is returned instead. + # + # scores = [ 97, 42, 75 ] + # scores.delete_if {|score| score < 80 } #=> [97] + + def delete_if(&block) + return to_enum :delete_if unless block + + idx = 0 + while idx < self.size do + if block.call(self[idx]) + self.delete_at(idx) + else + idx += 1 + end + end + self + end + + ## + # call-seq: + # ary.keep_if { |item| block } -> ary + # ary.keep_if -> Enumerator + # + # Deletes every element of +self+ for which the given block evaluates to + # +false+. + # + # See also Array#select! + # + # If no block is given, an Enumerator is returned instead. + # + # a = [1, 2, 3, 4, 5] + # a.keep_if { |val| val > 3 } #=> [4, 5] + + def keep_if(&block) + return to_enum :keep_if unless block + + idx = 0 + len = self.size + while idx < self.size do + if block.call(self[idx]) + idx += 1 + else + self.delete_at(idx) + end + end + self + end + + ## + # call-seq: + # ary.select! {|item| block } -> ary or nil + # ary.select! -> Enumerator + # + # Invokes the given block passing in successive elements from +self+, + # deleting elements for which the block returns a +false+ value. + # + # If changes were made, it will return +self+, otherwise it returns +nil+. + # + # See also Array#keep_if + # + # If no block is given, an Enumerator is returned instead. + + def select!(&block) + return to_enum :select! unless block + + result = [] + idx = 0 + len = size + while idx < len + elem = self[idx] + result << elem if block.call(elem) + idx += 1 + end + return nil if len == result.size + self.replace(result) + end + + ## + # call-seq: + # ary.index(val) -> int or nil + # ary.index {|item| block } -> int or nil + # + # Returns the _index_ of the first object in +ary+ such that the object is + # == to +obj+. + # + # If a block is given instead of an argument, returns the _index_ of the + # first object for which the block returns +true+. Returns +nil+ if no + # match is found. + # + # ISO 15.2.12.5.14 + def index(val=NONE, &block) + return to_enum(:find_index, val) if !block && val == NONE + + if block + idx = 0 + len = size + while idx < len + return idx if block.call self[idx] + idx += 1 + end + else + return self.__ary_index(val) + end + nil + end + + ## + # call-seq: + # ary.to_ary -> ary + # + # Returns +self+. + # + def to_ary + self + end + + ## + # call-seq: + # ary.dig(idx, ...) -> object + # + # Extracts the nested value specified by the sequence of idx + # objects by calling +dig+ at each step, returning +nil+ if any + # intermediate step is +nil+. + # + def dig(idx,*args) + n = self[idx] + if args.size > 0 + n&.dig(*args) + else + n + end + end +end diff --git a/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-array-ext/src/array.c b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-array-ext/src/array.c new file mode 100644 index 00000000..e99599b0 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-array-ext/src/array.c @@ -0,0 +1,244 @@ +#include +#include +#include +#include +#include + +/* + * call-seq: + * ary.assoc(obj) -> new_ary or nil + * + * Searches through an array whose elements are also arrays + * comparing _obj_ with the first element of each contained array + * using obj.==. + * Returns the first contained array that matches (that + * is, the first associated array), + * or +nil+ if no match is found. + * See also Array#rassoc. + * + * s1 = [ "colors", "red", "blue", "green" ] + * s2 = [ "letters", "a", "b", "c" ] + * s3 = "foo" + * a = [ s1, s2, s3 ] + * a.assoc("letters") #=> [ "letters", "a", "b", "c" ] + * a.assoc("foo") #=> nil + */ + +static mrb_value +mrb_ary_assoc(mrb_state *mrb, mrb_value ary) +{ + mrb_int i; + mrb_value v, k; + + mrb_get_args(mrb, "o", &k); + + for (i = 0; i < RARRAY_LEN(ary); ++i) { + v = mrb_check_array_type(mrb, RARRAY_PTR(ary)[i]); + if (!mrb_nil_p(v) && RARRAY_LEN(v) > 0 && + mrb_equal(mrb, RARRAY_PTR(v)[0], k)) + return v; + } + return mrb_nil_value(); +} + +/* + * call-seq: + * ary.rassoc(obj) -> new_ary or nil + * + * Searches through the array whose elements are also arrays. Compares + * _obj_ with the second element of each contained array using + * ==. Returns the first contained array that matches. See + * also Array#assoc. + * + * a = [ [ 1, "one"], [2, "two"], [3, "three"], ["ii", "two"] ] + * a.rassoc("two") #=> [2, "two"] + * a.rassoc("four") #=> nil + */ + +static mrb_value +mrb_ary_rassoc(mrb_state *mrb, mrb_value ary) +{ + mrb_int i; + mrb_value v, value; + + mrb_get_args(mrb, "o", &value); + + for (i = 0; i < RARRAY_LEN(ary); ++i) { + v = RARRAY_PTR(ary)[i]; + if (mrb_type(v) == MRB_TT_ARRAY && + RARRAY_LEN(v) > 1 && + mrb_equal(mrb, RARRAY_PTR(v)[1], value)) + return v; + } + return mrb_nil_value(); +} + +/* + * call-seq: + * ary.at(index) -> obj or nil + * + * Returns the element at _index_. A + * negative index counts from the end of +self+. Returns +nil+ + * if the index is out of range. See also Array#[]. + * + * a = [ "a", "b", "c", "d", "e" ] + * a.at(0) #=> "a" + * a.at(-1) #=> "e" + */ + +static mrb_value +mrb_ary_at(mrb_state *mrb, mrb_value ary) +{ + mrb_int pos; + mrb_get_args(mrb, "i", &pos); + + return mrb_ary_entry(ary, pos); +} + +static mrb_value +mrb_ary_values_at(mrb_state *mrb, mrb_value self) +{ + mrb_int argc; + mrb_value *argv; + + mrb_get_args(mrb, "*", &argv, &argc); + + return mrb_get_values_at(mrb, self, RARRAY_LEN(self), argc, argv, mrb_ary_ref); +} + +/* + * call-seq: + * ary.to_h -> Hash + * + * Returns the result of interpreting aray as an array of + * [key, value] paris. + * + * [[:foo, :bar], [1, 2]].to_h + * # => {:foo => :bar, 1 => 2} + * + */ + +static mrb_value +mrb_ary_to_h(mrb_state *mrb, mrb_value ary) +{ + mrb_int i; + mrb_value v, hash; + + hash = mrb_hash_new_capa(mrb, 0); + + for (i = 0; i < RARRAY_LEN(ary); ++i) { + mrb_value elt = RARRAY_PTR(ary)[i]; + v = mrb_check_array_type(mrb, elt); + + if (mrb_nil_p(v)) { + mrb_raisef(mrb, E_TYPE_ERROR, "wrong element type %S at %S (expected array)", + mrb_str_new_cstr(mrb, mrb_obj_classname(mrb, elt)), + mrb_fixnum_value(i) + ); + } + + if (RARRAY_LEN(v) != 2) { + mrb_raisef(mrb, E_ARGUMENT_ERROR, "wrong array length at %S (expected 2, was %S)", + mrb_fixnum_value(i), + mrb_fixnum_value(RARRAY_LEN(v)) + ); + } + + mrb_hash_set(mrb, hash, RARRAY_PTR(v)[0], RARRAY_PTR(v)[1]); + } + + return hash; +} + +/* + * call-seq: + * ary.slice!(index) -> obj or nil + * ary.slice!(start, length) -> new_ary or nil + * ary.slice!(range) -> new_ary or nil + * + * Deletes the element(s) given by an +index+ (optionally up to +length+ + * elements) or by a +range+. + * + * Returns the deleted object (or objects), or +nil+ if the +index+ is out of + * range. + * + * a = [ "a", "b", "c" ] + * a.slice!(1) #=> "b" + * a #=> ["a", "c"] + * a.slice!(-1) #=> "c" + * a #=> ["a"] + * a.slice!(100) #=> nil + * a #=> ["a"] + */ + +static mrb_value +mrb_ary_slice_bang(mrb_state *mrb, mrb_value self) +{ + struct RArray *a = mrb_ary_ptr(self); + mrb_int i, j, k, len, alen = ARY_LEN(a); + mrb_value index; + mrb_value val; + mrb_value *ptr; + mrb_value ary; + + mrb_ary_modify(mrb, a); + + if (mrb_get_args(mrb, "o|i", &index, &len) == 1) { + switch (mrb_type(index)) { + case MRB_TT_RANGE: + if (mrb_range_beg_len(mrb, index, &i, &len, alen, TRUE) == 1) { + goto delete_pos_len; + } + else { + return mrb_nil_value(); + } + case MRB_TT_FIXNUM: + val = mrb_funcall(mrb, self, "delete_at", 1, index); + return val; + default: + val = mrb_funcall(mrb, self, "delete_at", 1, index); + return val; + } + } + + i = mrb_fixnum(index); + delete_pos_len: + if (i < 0) i += alen; + if (i < 0 || alen < i) return mrb_nil_value(); + if (len < 0) return mrb_nil_value(); + if (alen == i) return mrb_ary_new(mrb); + if (len > alen - i) len = alen - i; + + ary = mrb_ary_new_capa(mrb, len); + ptr = ARY_PTR(a); + for (j = i, k = 0; k < len; ++j, ++k) { + mrb_ary_push(mrb, ary, ptr[j]); + } + + ptr += i; + for (j = i; j < alen - len; ++j) { + *ptr = *(ptr+len); + ++ptr; + } + + mrb_ary_resize(mrb, self, alen - len); + return ary; +} + +void +mrb_mruby_array_ext_gem_init(mrb_state* mrb) +{ + struct RClass * a = mrb->array_class; + + mrb_define_method(mrb, a, "assoc", mrb_ary_assoc, MRB_ARGS_REQ(1)); + mrb_define_method(mrb, a, "at", mrb_ary_at, MRB_ARGS_REQ(1)); + mrb_define_method(mrb, a, "rassoc", mrb_ary_rassoc, MRB_ARGS_REQ(1)); + mrb_define_method(mrb, a, "values_at", mrb_ary_values_at, MRB_ARGS_ANY()); + mrb_define_method(mrb, a, "to_h", mrb_ary_to_h, MRB_ARGS_REQ(0)); + mrb_define_method(mrb, a, "slice!", mrb_ary_slice_bang, MRB_ARGS_ANY()); +} + +void +mrb_mruby_array_ext_gem_final(mrb_state* mrb) +{ +} diff --git a/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-array-ext/test/array.rb b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-array-ext/test/array.rb new file mode 100644 index 00000000..c0db1b1c --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-array-ext/test/array.rb @@ -0,0 +1,383 @@ +## +# Array(Ext) Test + +assert("Array.try_convert") do + assert_nil Array.try_convert(0) + assert_nil Array.try_convert(nil) + assert_equal [], Array.try_convert([]) + assert_equal [1,2,3], Array.try_convert([1,2,3]) +end + +assert("Array#assoc") do + s1 = [ "colors", "red", "blue", "green" ] + s2 = [ "letters", "a", "b", "c" ] + s3 = "foo" + a = [ s1, s2, s3 ] + + assert_equal [ "letters", "a", "b", "c" ], a.assoc("letters") + assert_nil a.assoc("foo") +end + +assert("Array#at") do + a = [ "a", "b", "c", "d", "e" ] + assert_equal "a", a.at(0) + assert_equal "e", a.at(-1) +end + +assert("Array#rassoc") do + a = [ [ 1, "one"], [2, "two"], [3, "three"], ["ii", "two"] ] + + assert_equal [2, "two"], a.rassoc("two") + assert_nil a.rassoc("four") +end + +assert("Array#uniq!") do + a = [1, 2, 3, 1] + a.uniq! + assert_equal [1, 2, 3], a + + b = [ "a", "b", "c" ] + assert_nil b.uniq! + + c = [["student","sam"], ["student","george"], ["teacher","matz"]] + assert_equal [["student", "sam"], ["teacher", "matz"]], c.uniq! { |s| s.first } + + d = [["student","sam"], ["teacher","matz"]] + assert_nil d.uniq! { |s| s.first } +end + +assert("Array#uniq") do + a = [1, 2, 3, 1] + assert_equal [1, 2, 3], a.uniq + assert_equal [1, 2, 3, 1], a + + b = [["student","sam"], ["student","george"], ["teacher","matz"]] + assert_equal [["student", "sam"], ["teacher", "matz"]], b.uniq { |s| s.first } +end + +assert("Array#-") do + a = [1, 2, 3, 1] + b = [1] + c = 1 + + assert_raise(TypeError) { a - c } + assert_equal [2, 3], (a - b) + assert_equal [1, 2, 3, 1], a +end + +assert("Array#|") do + a = [1, 2, 3, 1] + b = [1, 4] + c = 1 + + assert_raise(TypeError) { a | c } + assert_equal [1, 2, 3, 4], (a | b) + assert_equal [1, 2, 3, 1], a +end + +assert("Array#&") do + a = [1, 2, 3, 1] + b = [1, 4] + c = 1 + + assert_raise(TypeError) { a & c } + assert_equal [1], (a & b) + assert_equal [1, 2, 3, 1], a +end + +assert("Array#flatten") do + assert_equal [1, 2, "3", {4=>5}, :'6'], [1, 2, "3", {4=>5}, :'6'].flatten + assert_equal [1, 2, 3, 4, 5, 6], [1, 2, [3, 4, 5], 6].flatten + assert_equal [1, 2, 3, 4, 5, 6], [1, 2, [3, [4, 5], 6]].flatten + assert_equal [1, [2, [3, [4, [5, [6]]]]]], [1, [2, [3, [4, [5, [6]]]]]].flatten(0) + assert_equal [1, 2, [3, [4, [5, [6]]]]], [1, [2, [3, [4, [5, [6]]]]]].flatten(1) + assert_equal [1, 2, 3, [4, [5, [6]]]], [1, [2, [3, [4, [5, [6]]]]]].flatten(2) + assert_equal [1, 2, 3, 4, [5, [6]]], [1, [2, [3, [4, [5, [6]]]]]].flatten(3) + assert_equal [1, 2, 3, 4, 5, [6]], [1, [2, [3, [4, [5, [6]]]]]].flatten(4) + assert_equal [1, 2, 3, 4, 5, 6], [1, [2, [3, [4, [5, [6]]]]]].flatten(5) +end + +assert("Array#flatten!") do + assert_equal [1, 2, 3, 4, 5, 6], [1, 2, [3, [4, 5], 6]].flatten! +end + +assert("Array#compact") do + a = [1, nil, "2", nil, :t, false, nil] + assert_equal [1, "2", :t, false], a.compact + assert_equal [1, nil, "2", nil, :t, false, nil], a +end + +assert("Array#compact!") do + a = [1, nil, "2", nil, :t, false, nil] + a.compact! + assert_equal [1, "2", :t, false], a +end + +assert("Array#fetch") do + a = [ 11, 22, 33, 44 ] + assert_equal 22, a.fetch(1) + assert_equal 44, a.fetch(-1) + assert_equal 'cat', a.fetch(4, 'cat') + ret = 0 + a.fetch(100) { |i| ret = i } + assert_equal 100, ret + assert_raise(IndexError) { a.fetch(100) } +end + +assert("Array#fill") do + a = [ "a", "b", "c", "d" ] + assert_equal ["x", "x", "x", "x"], a.fill("x") + assert_equal ["x", "x", "x", "w"], a.fill("w", -1) + assert_equal ["x", "x", "z", "z"], a.fill("z", 2, 2) + assert_equal ["y", "y", "z", "z"], a.fill("y", 0..1) + assert_equal [0, 1, 4, 9], a.fill { |i| i*i } + assert_equal [0, 1, 8, 27], a.fill(-2) { |i| i*i*i } + assert_equal [0, 2, 3, 27], a.fill(1, 2) { |i| i+1 } + assert_equal [1, 2, 3, 27], a.fill(0..1) { |i| i+1 } + assert_raise(ArgumentError) { a.fill } + + assert_equal([0, 1, 2, 3, -1, 5], [0, 1, 2, 3, 4, 5].fill(-1, -2, 1)) + assert_equal([0, 1, 2, 3, -1, -1, -1], [0, 1, 2, 3, 4, 5].fill(-1, -2, 3)) + assert_equal([0, 1, 2, -1, -1, 5], [0, 1, 2, 3, 4, 5].fill(-1, 3..4)) + assert_equal([0, 1, 2, -1, 4, 5], [0, 1, 2, 3, 4, 5].fill(-1, 3...4)) + assert_equal([0, 1, -1, -1, -1, 5], [0, 1, 2, 3, 4, 5].fill(-1, 2..-2)) + assert_equal([0, 1, -1, -1, 4, 5], [0, 1, 2, 3, 4, 5].fill(-1, 2...-2)) + assert_equal([0, 1, 2, 13, 14, 5], [0, 1, 2, 3, 4, 5].fill(3..4){|i| i+10}) + assert_equal([0, 1, 2, 13, 4, 5], [0, 1, 2, 3, 4, 5].fill(3...4){|i| i+10}) + assert_equal([0, 1, 12, 13, 14, 5], [0, 1, 2, 3, 4, 5].fill(2..-2){|i| i+10}) + assert_equal([0, 1, 12, 13, 4, 5], [0, 1, 2, 3, 4, 5].fill(2...-2){|i| i+10}) + + assert_equal [1, 2, 3, 4, 'x', 'x'], [1, 2, 3, 4, 5, 6].fill('x', -2..-1) + assert_equal [1, 2, 3, 4, 'x', 6], [1, 2, 3, 4, 5, 6].fill('x', -2...-1) + assert_equal [1, 2, 3, 4, 5, 6], [1, 2, 3, 4, 5, 6].fill('x', -2...-2) + assert_equal [1, 2, 3, 4, 'x', 6], [1, 2, 3, 4, 5, 6].fill('x', -2..-2) + assert_equal [1, 2, 3, 4, 5, 6], [1, 2, 3, 4, 5, 6].fill('x', -2..0) +end + +assert("Array#reverse_each") do + a = [ "a", "b", "c", "d" ] + b = [] + a.reverse_each do |i| + b << i + end + assert_equal [ "d", "c", "b", "a" ], b + + if Object.const_defined?(:Enumerator) + assert_equal [ "d", "c", "b", "a" ], a.reverse_each.to_a + else + true + end +end + +assert("Array#rotate") do + a = ["a", "b", "c", "d"] + assert_equal ["b", "c", "d", "a"], a.rotate + assert_equal ["a", "b", "c", "d"], a + assert_equal ["c", "d", "a", "b"], a.rotate(2) + assert_equal ["b", "c", "d", "a"], a.rotate(-3) + assert_equal ["c", "d", "a", "b"], a.rotate(10) + assert_equal [], [].rotate +end + +assert("Array#rotate!") do + a = ["a", "b", "c", "d"] + assert_equal ["b", "c", "d", "a"], a.rotate! + assert_equal ["b", "c", "d", "a"], a + assert_equal ["d", "a", "b", "c"], a.rotate!(2) + assert_equal ["a", "b", "c", "d"], a.rotate!(-3) + assert_equal ["c", "d", "a", "b"], a.rotate(10) + assert_equal [], [].rotate! +end + +assert("Array#delete_if") do + a = [1, 2, 3, 4, 5] + assert_equal [1, 2, 3, 4, 5], a.delete_if { false } + assert_equal [1, 2, 3, 4, 5], a + + a = [1, 2, 3, 4, 5] + assert_equal [], a.delete_if { true } + assert_equal [], a + + a = [1, 2, 3, 4, 5] + assert_equal [1, 2, 3], a.delete_if { |i| i > 3 } + assert_equal [1, 2, 3], a +end + +assert("Array#reject!") do + a = [1, 2, 3, 4, 5] + assert_nil a.reject! { false } + assert_equal [1, 2, 3, 4, 5], a + + a = [1, 2, 3, 4, 5] + assert_equal [], a.reject! { true } + assert_equal [], a + + a = [1, 2, 3, 4, 5] + assert_equal [1, 2, 3], a.reject! { |val| val > 3 } + assert_equal [1, 2, 3], a +end + +assert("Array#insert") do + a = ["a", "b", "c", "d"] + assert_equal ["a", "b", 99, "c", "d"], a.insert(2, 99) + assert_equal ["a", "b", 99, "c", 1, 2, 3, "d"], a.insert(-2, 1, 2, 3) + + b = ["a", "b", "c", "d"] + assert_equal ["a", "b", "c", "d", nil, nil, 99], b.insert(6, 99) +end + +assert("Array#bsearch") do + # Find minimum mode + a = [0, 2, 4] + assert_equal 0, a.bsearch{ |x| x >= -1 } + assert_equal 0, a.bsearch{ |x| x >= 0 } + assert_equal 2, a.bsearch{ |x| x >= 1 } + assert_equal 2, a.bsearch{ |x| x >= 2 } + assert_equal 4, a.bsearch{ |x| x >= 3 } + assert_equal 4, a.bsearch{ |x| x >= 4 } + assert_nil a.bsearch{ |x| x >= 5 } + + # Find any mode + a = [0, 4, 8] + def between(lo, x, hi) + if x < lo + 1 + elsif x > hi + -1 + else + 0 + end + end + assert_nil a.bsearch{ |x| between(-3, x, -1) } + assert_equal 0, a.bsearch{ |x| between(-1, x, 1) } + assert_nil a.bsearch{ |x| between( 1, x, 3) } + assert_equal 4, a.bsearch{ |x| between( 3, x, 5) } + assert_nil a.bsearch{ |x| between( 5, x, 7) } + assert_equal 8, a.bsearch{ |x| between( 7, x, 9) } + assert_nil a.bsearch{ |x| between( 9, x, 11) } + + assert_equal 0, a.bsearch{ |x| between( 0, x, 3) } + assert_equal 4, a.bsearch{ |x| between( 0, x, 4) } + assert_equal 4, a.bsearch{ |x| between( 4, x, 8) } + assert_equal 8, a.bsearch{ |x| between( 5, x, 8) } + + # Invalid block result + assert_raise TypeError, 'invalid block result (must be numeric, true, false or nil)' do + a.bsearch{ 'I like to watch the world burn' } + end +end + +assert("Array#bsearch_index") do + # tested through Array#bsearch +end + +assert("Array#delete_if") do + a = [1, 2, 3, 4, 5] + assert_equal [1, 2, 3, 4, 5], a.delete_if { false } + assert_equal [1, 2, 3, 4, 5], a + + a = [1, 2, 3, 4, 5] + assert_equal [], a.delete_if { true } + assert_equal [], a + + a = [ 1, 2, 3, 4, 5 ] + assert_equal [1, 2, 3], a.delete_if { |val| val > 3 } +end + +assert("Array#keep_if") do + a = [1, 2, 3, 4, 5] + assert_equal [1, 2, 3, 4, 5], a.keep_if { true } + assert_equal [1, 2, 3, 4, 5], a + + a = [1, 2, 3, 4, 5] + assert_equal [], a.keep_if { false } + assert_equal [], a + + a = [1, 2, 3, 4, 5] + assert_equal [4, 5], a.keep_if { |val| val > 3 } + assert_equal [4, 5], a +end + +assert("Array#select!") do + a = [1, 2, 3, 4, 5] + assert_nil a.select! { true } + assert_equal [1, 2, 3, 4, 5], a + + a = [1, 2, 3, 4, 5] + assert_equal [], a.select! { false } + assert_equal [], a + + a = [1, 2, 3, 4, 5] + assert_equal [4, 5], a.select! { |val| val > 3 } + assert_equal [4, 5], a +end + +assert('Array#values_at') do + a = %w{red green purple white none} + + assert_equal %w{red purple none}, a.values_at(0, 2, 4) + assert_equal ['green', 'white', nil, nil], a.values_at(1, 3, 5, 7) + assert_equal ['none', 'white', 'white', nil], a.values_at(-1, -2, -2, -7) + assert_equal ['none', nil, nil, 'red', 'green', 'purple'], a.values_at(4..6, 0...3) + assert_raise(TypeError) { a.values_at 'tt' } +end + +assert('Array#to_h') do + assert_equal({}, [].to_h) + assert_equal({a: 1, b:2}, [[:a, 1], [:b, 2]].to_h) + + assert_raise(TypeError) { [1].to_h } + assert_raise(ArgumentError) { [[1]].to_h } +end + +assert('Array#to_h (Modified)') do + class A + def to_ary + $a.clear + nil + end + end + $a = [A.new] + assert_raise(TypeError) { $a.to_h } +end + +assert("Array#index (block)") do + assert_nil (1..10).to_a.index { |i| i % 5 == 0 and i % 7 == 0 } + assert_equal 34, (1..100).to_a.index { |i| i % 5 == 0 and i % 7 == 0 } +end + +assert("Array#to_ary") do + assert_equal [], [].to_ary + assert_equal [1,2,3], [1,2,3].to_ary +end + +assert("Array#dig") do + h = [[[1]], 0] + assert_equal(1, h.dig(0, 0, 0)) + assert_nil(h.dig(2, 0)) + assert_raise(TypeError) {h.dig(:a)} +end + +assert("Array#slice!") do + a = [1, 2, 3] + b = a.slice!(0) + c = [1, 2, 3, 4, 5] + d = c.slice!(0, 2) + e = [1, 2, 3, 4, 5] + f = e.slice!(1..3) + g = [1, 2, 3] + h = g.slice!(-1) + i = [1, 2, 3] + j = i.slice!(0, -1) + + assert_equal(a, [2, 3]) + assert_equal(b, 1) + assert_equal(c, [3, 4, 5]) + assert_equal(d, [1, 2]) + assert_equal(e, [1, 5]) + assert_equal(f, [2, 3, 4]) + assert_equal(g, [1, 2]) + assert_equal(h, 3) + assert_equal(i, [1, 2, 3]) + assert_equal(j, nil) +end diff --git a/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-bin-debugger/bintest/mrdb.rb b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-bin-debugger/bintest/mrdb.rb new file mode 100644 index 00000000..26f3138a --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-bin-debugger/bintest/mrdb.rb @@ -0,0 +1,286 @@ +require 'open3' +require 'tempfile' + +class BinTest_MrubyBinDebugger + @debug1=false + @debug2=true + @debug3=true + def self.test(rubysource, testcase) + script, bin = Tempfile.new(['test', '.rb']), Tempfile.new(['test', '.mrb']) + + # .rb + script.write rubysource + script.flush + + # compile + `./bin/mrbc -g -o "#{bin.path}" "#{script.path}"` + + # add mrdb quit + testcase << {:cmd=>"quit"} + + stdin_data = testcase.map{|t| t[:cmd]}.join("\n") << "\n" + + ["bin/mrdb #{script.path}","bin/mrdb -b #{bin.path}"].each do |cmd| + o, s = Open3.capture2(cmd, :stdin_data => stdin_data) + + exp_vals = testcase.map{|t| t.fetch(:exp, nil)} + unexp_vals = testcase.map{|t| t.fetch(:unexp, nil)} + +if @debug1 + o.split("\n").each_with_index do |i,actual| + p [i,actual] + end +end + # compare actual / expected + o.split("\n").each do |actual| + next if actual.empty? + exp = exp_vals.shift +if @debug2 + a = true + a = actual.include?(exp) unless exp.nil? + p [actual, exp] unless a +end + assert_true actual.include?(exp) unless exp.nil? + end + # compare actual / unexpected + o.split("\n").each do |actual| + next if actual.empty? + unexp = unexp_vals.shift +if @debug3 + a = false + a = actual.include?(unexp) unless unexp.nil? + p [actual, unexp] if a +end + assert_false actual.include?(unexp) unless unexp.nil? + end + end + end +end + +INVCMD = "invalid command" + +assert('mruby-bin-debugger(mrdb) command line') do + # ruby source + src = "foo = 'foo'\n" + + str = "" + 103.times { + str += "1234567890" + } + cmd = "p a=#{str}" + + # test case + BinTest_MrubyBinDebugger.test(src, [{:cmd=>cmd[0...1023], :unexp=>'command line too long.'}]) + BinTest_MrubyBinDebugger.test(src, [{:cmd=>cmd[0...1024], :unexp=>'command line too long.'}]) + BinTest_MrubyBinDebugger.test(src, [{:cmd=>cmd[0...1025], :exp=>'command line too long.'}]) +end + +assert('mruby-bin-debugger(mrdb) command: "break"') do + # ruby source + src = "foo = 'foo'\n" + + # test case + tc = [] + tc << {:cmd=>"b", :unexp=>INVCMD} + tc << {:cmd=>"br", :unexp=>INVCMD} + tc << {:cmd=>"brea", :unexp=>INVCMD} + tc << {:cmd=>"break", :unexp=>INVCMD} + BinTest_MrubyBinDebugger.test(src, tc) + + BinTest_MrubyBinDebugger.test(src, [{:cmd=>"bl", :exp=>INVCMD}]) + BinTest_MrubyBinDebugger.test(src, [{:cmd=>"breaka", :exp=>INVCMD}]) +end + +assert('mruby-bin-debugger(mrdb) command: "continue"') do + # ruby source + src = "foo = 'foo'\n" + + # test case + BinTest_MrubyBinDebugger.test(src, [{:cmd=>"c", :unexp=>INVCMD}]) + BinTest_MrubyBinDebugger.test(src, [{:cmd=>"co", :unexp=>INVCMD}]) + BinTest_MrubyBinDebugger.test(src, [{:cmd=>"continu", :unexp=>INVCMD}]) + BinTest_MrubyBinDebugger.test(src, [{:cmd=>"continue", :unexp=>INVCMD}]) + + BinTest_MrubyBinDebugger.test(src, [{:cmd=>"cn", :exp=>INVCMD}]) + BinTest_MrubyBinDebugger.test(src, [{:cmd=>"continuee", :exp=>INVCMD}]) +end + +assert('mruby-bin-debugger(mrdb) command: "delete"') do + # ruby source + src = "foo = 'foo'\n" + + # test case + tc = [] + tc << {:cmd=>"d 1", :unexp=>INVCMD} + tc << {:cmd=>"de 1", :unexp=>INVCMD} + tc << {:cmd=>"delet 1", :unexp=>INVCMD} + tc << {:cmd=>"delete 1", :unexp=>INVCMD} + BinTest_MrubyBinDebugger.test(src, tc) + + BinTest_MrubyBinDebugger.test(src, [{:cmd=>"dd 1", :exp=>INVCMD}]) + BinTest_MrubyBinDebugger.test(src, [{:cmd=>"deletee 1", :exp=>INVCMD}]) +end + +assert('mruby-bin-debugger(mrdb) command: "disable"') do + # ruby source + src = "foo = 'foo'\n" + + # test case + tc = [] + tc << {:cmd=>"dis", :unexp=>INVCMD} + tc << {:cmd=>"disa", :unexp=>INVCMD} + tc << {:cmd=>"disabl", :unexp=>INVCMD} + tc << {:cmd=>"disable", :unexp=>INVCMD} + BinTest_MrubyBinDebugger.test(src, tc) + + BinTest_MrubyBinDebugger.test(src, [{:cmd=>"di", :exp=>INVCMD}]) + BinTest_MrubyBinDebugger.test(src, [{:cmd=>"disb", :exp=>INVCMD}]) + BinTest_MrubyBinDebugger.test(src, [{:cmd=>"disablee", :exp=>INVCMD}]) +end + +assert('mruby-bin-debugger(mrdb) command: "enable"') do + # ruby source + src = "foo = 'foo'\n" + + # test case + tc = [] + tc << {:cmd=>"en", :unexp=>INVCMD} + tc << {:cmd=>"ena", :unexp=>INVCMD} + tc << {:cmd=>"enabl", :unexp=>INVCMD} + tc << {:cmd=>"enable", :unexp=>INVCMD} + BinTest_MrubyBinDebugger.test(src, tc) + + BinTest_MrubyBinDebugger.test(src, [{:cmd=>"e", :exp=>INVCMD}]) + BinTest_MrubyBinDebugger.test(src, [{:cmd=>"enb", :exp=>INVCMD}]) + BinTest_MrubyBinDebugger.test(src, [{:cmd=>"enablee", :exp=>INVCMD}]) +end + +assert('mruby-bin-debugger(mrdb) command: "eval"') do + # ruby source + src = "foo = 'foo'\n" + + # test case + tc = [] + tc << {:cmd=>"ev", :unexp=>INVCMD} + tc << {:cmd=>"eva", :unexp=>INVCMD} + tc << {:cmd=>"eval", :unexp=>INVCMD} + BinTest_MrubyBinDebugger.test(src, tc) + + BinTest_MrubyBinDebugger.test(src, [{:cmd=>"e", :exp=>INVCMD}]) + BinTest_MrubyBinDebugger.test(src, [{:cmd=>"evl", :exp=>INVCMD}]) + BinTest_MrubyBinDebugger.test(src, [{:cmd=>"evall", :exp=>INVCMD}]) +end + +assert('mruby-bin-debugger(mrdb) command: "help"') do + # ruby source + src = "foo = 'foo'\n" + + # test case + tc = [] + tc << {:cmd=>"h", :unexp=>INVCMD} + tc << {:cmd=>"he", :unexp=>INVCMD} + tc << {:cmd=>"hel", :unexp=>INVCMD} + tc << {:cmd=>"help", :unexp=>INVCMD} + BinTest_MrubyBinDebugger.test(src, tc) + + BinTest_MrubyBinDebugger.test(src, [{:cmd=>"hl", :exp=>INVCMD}]) + BinTest_MrubyBinDebugger.test(src, [{:cmd=>"helpp", :exp=>INVCMD}]) +end + +assert('mruby-bin-debugger(mrdb) command: "info breakpoints"') do + # ruby source + src = "foo = 'foo'\n" + + # test case + tc = [] + tc << {:cmd=>"i b", :unexp=>INVCMD} + tc << {:cmd=>"in b", :unexp=>INVCMD} + tc << {:cmd=>"i br", :unexp=>INVCMD} + tc << {:cmd=>"inf breakpoint", :unexp=>INVCMD} + tc << {:cmd=>"info breakpoints", :unexp=>INVCMD} + BinTest_MrubyBinDebugger.test(src, tc) + + BinTest_MrubyBinDebugger.test(src, [{:cmd=>"ii b", :exp=>INVCMD}]) + BinTest_MrubyBinDebugger.test(src, [{:cmd=>"i bb", :exp=>INVCMD}]) + BinTest_MrubyBinDebugger.test(src, [{:cmd=>"infoo breakpoints", :exp=>INVCMD}]) + BinTest_MrubyBinDebugger.test(src, [{:cmd=>"info breakpointss", :exp=>INVCMD}]) +end + +assert('mruby-bin-debugger(mrdb) command: "list"') do + # ruby source + src = "foo = 'foo'\n" + + # test case + tc = [] + tc << {:cmd=>"l", :unexp=>INVCMD} + tc << {:cmd=>"li", :unexp=>INVCMD} + tc << {:cmd=>"lis", :unexp=>INVCMD} + tc << {:cmd=>"list", :unexp=>INVCMD} + BinTest_MrubyBinDebugger.test(src, tc) + + BinTest_MrubyBinDebugger.test(src, [{:cmd=>"ll", :exp=>INVCMD}]) + BinTest_MrubyBinDebugger.test(src, [{:cmd=>"listt", :exp=>INVCMD}]) +end + +assert('mruby-bin-debugger(mrdb) command: "print"') do + # ruby source + src = "foo = 'foo'\n" + + # test case + tc = [] + tc << {:cmd=>"p", :unexp=>INVCMD} + tc << {:cmd=>"pr", :unexp=>INVCMD} + tc << {:cmd=>"prin", :unexp=>INVCMD} + tc << {:cmd=>"print", :unexp=>INVCMD} + BinTest_MrubyBinDebugger.test(src, tc) + + BinTest_MrubyBinDebugger.test(src, [{:cmd=>"pp", :exp=>INVCMD}]) + BinTest_MrubyBinDebugger.test(src, [{:cmd=>"printt", :exp=>INVCMD}]) +end + +assert('mruby-bin-debugger(mrdb) command: "quit"') do + # ruby source + src = "foo = 'foo'\n" + + # test case + BinTest_MrubyBinDebugger.test(src, [{:cmd=>"q", :unexp=>INVCMD}]) + BinTest_MrubyBinDebugger.test(src, [{:cmd=>"qu", :unexp=>INVCMD}]) + BinTest_MrubyBinDebugger.test(src, [{:cmd=>"qui", :unexp=>INVCMD}]) + BinTest_MrubyBinDebugger.test(src, [{:cmd=>"quit", :unexp=>INVCMD}]) + + BinTest_MrubyBinDebugger.test(src, [{:cmd=>"qq", :exp=>INVCMD}]) + BinTest_MrubyBinDebugger.test(src, [{:cmd=>"quitt", :exp=>INVCMD}]) +end + +assert('mruby-bin-debugger(mrdb) command: "run"') do + # ruby source + src = "foo = 'foo'\n" + + # test case + BinTest_MrubyBinDebugger.test(src, [{:cmd=>"r", :unexp=>INVCMD}]) + BinTest_MrubyBinDebugger.test(src, [{:cmd=>"ru", :unexp=>INVCMD}]) + BinTest_MrubyBinDebugger.test(src, [{:cmd=>"run", :unexp=>INVCMD}]) + + BinTest_MrubyBinDebugger.test(src, [{:cmd=>"rr", :exp=>INVCMD}]) + BinTest_MrubyBinDebugger.test(src, [{:cmd=>"runn", :exp=>INVCMD}]) +end + +assert('mruby-bin-debugger(mrdb) command: "step"') do + # ruby source + src = <<"SRC" +while true + foo = 'foo' +end +SRC + + # test case + tc = [] + tc << {:cmd=>"s", :unexp=>INVCMD} + tc << {:cmd=>"st", :unexp=>INVCMD} + tc << {:cmd=>"ste", :unexp=>INVCMD} + tc << {:cmd=>"step", :unexp=>INVCMD} + BinTest_MrubyBinDebugger.test(src, tc) + + BinTest_MrubyBinDebugger.test(src, [{:cmd=>"ss", :exp=>INVCMD}]) + BinTest_MrubyBinDebugger.test(src, [{:cmd=>"stepp", :exp=>INVCMD}]) +end diff --git a/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-bin-debugger/bintest/print.rb b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-bin-debugger/bintest/print.rb new file mode 100644 index 00000000..1bc96c47 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-bin-debugger/bintest/print.rb @@ -0,0 +1,701 @@ +require 'open3' +require 'tempfile' + +class BinTest_MrubyBinDebugger + @debug1=false + @debug2=true + def self.test(rubysource, testcase) + script, bin = Tempfile.new(['test', '.rb']), Tempfile.new(['test', '.mrb']) + + # .rb + script.write rubysource + script.flush + + # compile + `./bin/mrbc -g -o "#{bin.path}" "#{script.path}"` + + # add mrdb quit + testcase << {:cmd=>"quit"} + + stdin_data = testcase.map{|t| t[:cmd]}.join("\n") << "\n" + + ["bin/mrdb #{script.path}","bin/mrdb -b #{bin.path}"].each do |cmd| + o, s = Open3.capture2(cmd, :stdin_data => stdin_data) + + exp_vals = testcase.map{|t| t.fetch(:exp, nil)} +=begin +if @debug1 + o.split("\n").each_with_index do |i,actual| + p [i,actual] + end +end + # compare actual / expected + o.split("\n").each do |actual| + next if actual.empty? + exp = exp_vals.shift +if @debug2 + a = true + a = actual.include?(exp) unless exp.nil? + p [actual, exp] unless a +end + assert_true actual.include?(exp) unless exp.nil? + end +=end + idx = 0 + exp_vals.each do |exp| + next if exp.nil? + idx = o.index(exp, idx) + assert_false idx.nil? + break unless idx + idx += 1 + end + end + end +end + +assert('mruby-bin-debugger(print) invalid arguments') do + # ruby source + src = "foo = 'foo'\n" + + # test case + tc = [] + tc << {:cmd=>"p", :exp=>"Parameter not specified."} + + BinTest_MrubyBinDebugger.test(src, tc) +end + +assert('mruby-bin-debugger(print) nomal') do + # ruby source + src = <<"SRC" +foo = 'foo' +bar = foo +baz = bar +SRC + + # test case + tc = [] + tc << {:cmd=>"s"} + tc << {:cmd=>"p (1+2)", :exp=>'$1 = 3'} + tc << {:cmd=>"p foo", :exp=>'$2 = "foo"'} + tc << {:cmd=>"p foo*=2", :exp=>'$3 = "foofoo"'} + tc << {:cmd=>"s"} + tc << {:cmd=>"p bar", :exp=>'$4 = "foofoo"'} + + BinTest_MrubyBinDebugger.test(src, tc) +end + +assert('mruby-bin-debugger(print) error') do + # ruby source + src = "foo = 'foo'\n" + + # test case + tc = [] + tc << {:cmd=>"p (1+2", :exp=>'$1 = SyntaxError'} + tc << {:cmd=>"p bar", :exp=>'$2 = NoMethodError'} + + BinTest_MrubyBinDebugger.test(src, tc) +end + +# Kernel#instance_eval(string) does't work multiple statements. +=begin +assert('mruby-bin-debugger(print) multiple statements') do + # ruby source + src = <<"SRC" +x = 0 +y = 0 +z = 0 +SRC + + # test case + tc = [] + tc << {:cmd=>"s",} + tc << {:cmd=>"p x=1;x+=2", :exp=>"3"} + tc << {:cmd=>"s",} + tc << {:cmd=>"p x", :exp=>"3"} + + BinTest_MrubyBinDebugger.test(src, tc) +end +=end + +assert('mruby-bin-debugger(print) scope:top') do + # ruby source (bp is break point) + src = "bp=nil\n" + + # test case + tc = [] + tc << {:cmd=>"p self", :exp=>'$1 = main'} + + BinTest_MrubyBinDebugger.test(src, tc) +end + +assert('mruby-bin-debugger(print) scope:class') do + # ruby source (bp is break point) + src = <<"SRC" +class TestClassScope + bp = nil +end +SRC + + # test case + tc = [] + tc << {:cmd=>"s"} + tc << {:cmd=>"p self", :exp=>'$1 = TestClassScope'} + + BinTest_MrubyBinDebugger.test(src, tc) +end + +assert('mruby-bin-debugger(print) scope:module') do + # ruby source (bp is break point) + src = <<"SRC" +class TestModuleScope + bp = nil +end +SRC + + # test case + tc = [] + tc << {:cmd=>"s"} + tc << {:cmd=>"p self", :exp=>'$1 = TestModuleScope'} + + BinTest_MrubyBinDebugger.test(src, tc) +end + +assert('mruby-bin-debugger(print) scope:instance method') do + # ruby source (bp is break point) + src = <<"SRC" +class TestMethodScope + def m + bp = nil + end +end +TestMethodScope.new.m +SRC + + tc = [] + tc << {:cmd=>"b 3"} + tc << {:cmd=>"r"} + tc << {:cmd=>"p self", :exp=>'$1 = #"b 3"} + tc << {:cmd=>"r"} + tc << {:cmd=>"p self", :exp=>'$1 = TestClassMethodScope'} + + BinTest_MrubyBinDebugger.test(src, tc) +end + +assert('mruby-bin-debugger(print) scope:block') do + # ruby source (bp is break point) + src = <<"SRC" +1.times do + bp = nil +end +class TestBlockScope + 1.times do + bp = nil + end + def m + 1.times do + bp = nil + end + end +end +TestBlockScope.new.m +SRC + + tc = [] + tc << {:cmd=>"b 2"} + tc << {:cmd=>"b 6"} + tc << {:cmd=>"b 10"} + tc << {:cmd=>"c"} + tc << {:cmd=>"p self", :exp=>'$1 = main'} + tc << {:cmd=>"c"} + tc << {:cmd=>"p self", :exp=>'$2 = TestBlockScope'} + tc << {:cmd=>"c"} + tc << {:cmd=>"p self", :exp=>'$3 = #"b 6"} + tc << {:cmd=>"b 8"} + tc << {:cmd=>"b 11"} + tc << {:cmd=>"r"} + tc << {:cmd=>"p lv", :exp=>'$1 = "class"'} + tc << {:cmd=>"c"} + tc << {:cmd=>"p lv", :exp=>'$2 = "instance method"'} + tc << {:cmd=>"c"} + tc << {:cmd=>"p lv", :exp=>'$3 = "top"'} + + BinTest_MrubyBinDebugger.test(src, tc) +end + +assert('mruby-bin-debugger(print) same name:instance variabe') do + # ruby source (bp is break point) + src = <<"SRC" +@iv = 'top' +class TestInstanceVariableName + def initialize(v) + @iv = v + end + def m + bp = nil + end +end +i1 = TestInstanceVariableName.new('instance1') +i2 = TestInstanceVariableName.new('instance2') +i1.m +i2.m +bp = nil +SRC + + tc = [] + tc << {:cmd=>"b 7"} + tc << {:cmd=>"b 14"} + tc << {:cmd=>"r"} + tc << {:cmd=>"p @iv", :exp=>'$1 = "instance1"'} + tc << {:cmd=>"c"} + tc << {:cmd=>"p @iv", :exp=>'$2 = "instance2"'} + tc << {:cmd=>"c"} + tc << {:cmd=>"p @iv", :exp=>'$3 = "top"'} + + BinTest_MrubyBinDebugger.test(src, tc) +end + +# Kernel#instance_eval(string) does't work const. +=begin +assert('mruby-bin-debugger(print) same name:const') do + # ruby source (bp is break point) + src = <<"SRC" +CONST='top' +class TestConstNameSuperClass + CONST='super class' + def m + bp = nil + end +end +class TestConstNameSubClass < TestConstNameSuperClass + CONST='sub class' + def m + bp = nil + end +end + +TestConstNameSuperClass.new.m() +TestConstNameSubClass.new.m() +bp = nil +SRC + + # todo: wait for 'break' to be implimented + tc = [] + 9.times { tc << {:cmd=>"s"} } + tc << {:cmd=>"p CONST", :exp=>"super class"} + 3.times { tc << {:cmd=>"s"} } + tc << {:cmd=>"p CONST", :exp=>"sub class"} + 1.times { tc << {:cmd=>"s"} } + tc << {:cmd=>"p CONST", :exp=>"top"} + + BinTest_MrubyBinDebugger.test(src, tc) +end +=end + +assert('mruby-bin-debugger(print) Literal:Numeric') do + # ruby source + src = "foo = 'foo'\n" + + # test case + tc = [] + tc << {:cmd=>"p 100", :exp=>'$1 = 100'} + tc << {:cmd=>"p -0b100", :exp=>'$2 = -4'} + tc << {:cmd=>"p +0100", :exp=>'$3 = 64'} + tc << {:cmd=>"p 0x100", :exp=>'$4 = 256'} + tc << {:cmd=>"p 1_234", :exp=>'$5 = 1234'} + tc << {:cmd=>"p 0b1000_0000", :exp=>"$6 = #{0b1000_0000}"} + tc << {:cmd=>"p 0x1000_0000", :exp=>"$7 = #{0x1000_0000}"} + + tc << {:cmd=>"p 3.14", :exp=>'$8 = 3.14'} + tc << {:cmd=>"p -12.3", :exp=>'$9 = -12.3'} + tc << {:cmd=>"p +12.000", :exp=>'$10 = 12.0'} + tc << {:cmd=>"p 1e4", :exp=>'$11 = 10000.0'} + tc << {:cmd=>"p -0.1e-2", :exp=>'$12 = -0.001'} + + BinTest_MrubyBinDebugger.test(src, tc) +end + +assert('mruby-bin-debugger(print) Literal:String') do + # ruby source + src = <<"SRC" +foo = 'foo' +bar = "bar" +baz = "baz" +SRC + + # test case + tc = [] + tc << {:cmd=>"s"} + tc << {:cmd=>"s"} + + tc << {:cmd=>'p "str"', :exp=>'$1 = "str"'} + tc << {:cmd=>'p "s\tt\rr\n"', :exp=>'$2 = "s\\tt\\rr\\n"'} + tc << {:cmd=>'p "\C-a\C-z"', :exp=>'$3 = "\\001\\032"'} + tc << {:cmd=>'p "#{foo+bar}"', :exp=>'$4 = "foobar"'} + + tc << {:cmd=>'p \'str\'', :exp=>'$5 = "str"'} + tc << {:cmd=>'p \'s\\tt\\rr\\n\'', :exp=>'$6 = "s\\\\tt\\\\rr\\\\n"'} + tc << {:cmd=>'p \'\\C-a\\C-z\'', :exp=>'$7 = "\\\\C-a\\\\C-z"'} + tc << {:cmd=>'p \'#{foo+bar}\'', :exp=>'$8 = "#{foo+bar}"'} + + tc << {:cmd=>'p %!str!', :exp=>'$9 = "str"'} + tc << {:cmd=>'p %!s\tt\rr\n!', :exp=>'$10 = "s\\tt\\rr\\n"'} + tc << {:cmd=>'p %!\C-a\C-z!', :exp=>'$11 = "\\001\\032"'} + tc << {:cmd=>'p %!#{foo+bar}!', :exp=>'$12 = "foobar"'} + + tc << {:cmd=>'p %Q!str!', :exp=>'$13 = "str"'} + tc << {:cmd=>'p %Q!s\tt\rr\n!', :exp=>'$14 = "s\\tt\\rr\\n"'} + tc << {:cmd=>'p %Q!\C-a\C-z!', :exp=>'$15 = "\\001\\032"'} + tc << {:cmd=>'p %Q!#{foo+bar}!', :exp=>'$16 = "foobar"'} + + tc << {:cmd=>'p %q!str!', :exp=>'$17 = "str"'} + tc << {:cmd=>'p %q!s\\tt\\rr\\n!', :exp=>'$18 = "s\\\\tt\\\\rr\\\\n"'} + tc << {:cmd=>'p %q!\\C-a\\C-z!', :exp=>'$19 = "\\\\C-a\\\\C-z"'} + tc << {:cmd=>'p %q!#{foo+bar}!', :exp=>'$20 = "#{foo+bar}"'} + + BinTest_MrubyBinDebugger.test(src, tc) +end + +assert('mruby-bin-debugger(print) Literal:Array') do + # ruby source + src = <<"SRC" +foo = 'foo' +bar = "bar" +baz = "baz" +SRC + + # test case + tc = [] + tc << {:cmd=>"s"} + tc << {:cmd=>"s"} + + tc << {:cmd=>'p []', :exp=>'$1 = []'} + tc << {:cmd=>'p [ 5, 12, 8, 10, ]', :exp=>'$2 = [5, 12, 8, 10]'} + tc << {:cmd=>'p [1,2.5,"#{foo+bar}"]', :exp=>'$3 = [1, 2.5, "foobar"]'} + tc << {:cmd=>'p %w[3.14 A\ &\ B #{foo}]', :exp=>'$4 = ["3.14", "A & B", "#{foo}"]'} + tc << {:cmd=>'p %W[3.14 A\ &\ B #{foo}]', :exp=>'$5 = ["3.14", "A & B", "foo"]'} + + BinTest_MrubyBinDebugger.test(src, tc) +end + +assert('mruby-bin-debugger(print) Literal:Hash') do + # ruby source + src = <<"SRC" +foo = 'foo' +bar = "bar" +baz = "baz" +SRC + + # test case + tc = [] + tc << {:cmd=>"s"} + tc << {:cmd=>"s"} + + tc << {:cmd=>'p {}', :exp=>'$1 = {}'} + tc << {:cmd=>'p {"one"=>1,"two"=>2}', :exp=>'$2 = {"one"=>1, "two"=>2}'} + tc << {:cmd=>'p {:eins=>"1", :zwei=>"2", }', :exp=>'$3 = {:eins=>"1", :zwei=>"2"}'} + tc << {:cmd=>'p {uno:"one", dos: 2}', :exp=>'$4 = {:uno=>"one", :dos=>2}'} + tc << {:cmd=>'p {"one"=>1, :zwei=>2, tres:3}', :exp=>'$5 = {"one"=>1, :zwei=>2, :tres=>3}'} + tc << {:cmd=>'p {:foo=>"#{foo}",:bar=>"#{bar}"}', :exp=>'$6 = {:foo=>"foo", :bar=>"bar"}'} + + BinTest_MrubyBinDebugger.test(src, tc) +end + +assert('mruby-bin-debugger(print) Literal:Range') do + # ruby source + src = "foo = 'foo'\n" + + # test case + tc = [] + tc << {:cmd=>'p 1..10', :exp=>'$1 = 1..10'} + tc << {:cmd=>'p 1...10', :exp=>'$2 = 1...10'} + tc << {:cmd=>'p 100..10', :exp=>'$3 = 100..10'} + tc << {:cmd=>'p 1 ... 10', :exp=>'$4 = 1...10'} + + tc << {:cmd=>'p "1" .. "9"', :exp=>'$5 = "1".."9"'} + tc << {:cmd=>'p "A" ... "Z"', :exp=>'$6 = "A"..."Z"'} + + BinTest_MrubyBinDebugger.test(src, tc) +end + +assert('mruby-bin-debugger(print) Literal:Symbol') do + # ruby source + src = <<"SRC" +foo = 'foo' +bar = "bar" +baz = "baz" +SRC + + # test case + tc = [] + tc << {:cmd=>"s"} + tc << {:cmd=>"s"} + + tc << {:cmd=>'p :sym', :exp=>'$1 = :sym'} + tc << {:cmd=>'p :"sd"', :exp=>'$2 = :sd'} + tc << {:cmd=>"p :'ss'", :exp=>'$3 = :ss'} + tc << {:cmd=>'p :"123"', :exp=>'$4 = :"123"'} + tc << {:cmd=>'p :"#{foo} baz"', :exp=>'$5 = :"foo baz"'} + tc << {:cmd=>'p %s!symsym!', :exp=>'$6 = :symsym'} + + BinTest_MrubyBinDebugger.test(src, tc) +end + +assert('mruby-bin-debugger(print) Unary operation') do + # ruby source + src = "foo = 'foo'\n" + + # test case + tc = [] + tc << {:cmd=>'p +10', :exp=>'$1 = 10'} + tc << {:cmd=>'p -100', :exp=>'$2 = -100'} + tc << {:cmd=>'p !true', :exp=>'$3 = false'} + tc << {:cmd=>'p !false', :exp=>'$4 = true'} + tc << {:cmd=>'p !nil', :exp=>'$5 = true'} + tc << {:cmd=>'p !1', :exp=>'$6 = false'} + + BinTest_MrubyBinDebugger.test(src, tc) +end + +assert('mruby-bin-debugger(print) Binary operation') do + # ruby source + src = <<"SRC" +CONST = 100 +a,b,c = 1, 5, 8 +foo,bar,baz = 'foo','bar','baz' +ary = [] +SRC + + # test case + tc = [] + tc << {:cmd=>'s'} + tc << {:cmd=>'s'} + tc << {:cmd=>'s'} + + tc << {:cmd=>'p a+1', :exp=>'$1 = 2'} + tc << {:cmd=>'p 2-b', :exp=>'$2 = -3'} + tc << {:cmd=>'p c * 3', :exp=>'$3 = 24'} + tc << {:cmd=>'p a/b', :exp=>'$4 = 0.2'} + tc << {:cmd=>'p c%b', :exp=>'$5 = 3'} + tc << {:cmd=>'p 2**10', :exp=>'$6 = 1024'} + tc << {:cmd=>'p ~3', :exp=>'$7 = -4'} + + tc << {:cmd=>'p 1<<2', :exp=>'$8 = 4'} + tc << {:cmd=>'p 64>>5', :exp=>'$9 = 2'} + + tc << {:cmd=>'p a|c', :exp=>'$10 = 9'} + tc << {:cmd=>'p a&b', :exp=>'$11 = 1'} + tc << {:cmd=>'p a^b', :exp=>'$12 = 4'} + + tc << {:cmd=>'p a>b', :exp=>'$13 = false'} + tc << {:cmd=>'p a'$14 = true'} + tc << {:cmd=>'p b>=5', :exp=>'$15 = true'} + tc << {:cmd=>'p b<=5', :exp=>'$16 = true'} + + tc << {:cmd=>'p "A"<=>"B"', :exp=>'$17 = -1'} + tc << {:cmd=>'p "A"=="B"', :exp=>'$18 = false'} + tc << {:cmd=>'p "A"==="B"', :exp=>'$19 = false'} + tc << {:cmd=>'p "A"!="B"', :exp=>'$20 = true'} + + tc << {:cmd=>'p false || true', :exp=>'$21 = true'} + tc << {:cmd=>'p false && true', :exp=>'$22 = false'} + + tc << {:cmd=>'p not nil', :exp=>'$23 = true'} + tc << {:cmd=>'p false or true', :exp=>'$24 = true'} + tc << {:cmd=>'p false and true', :exp=>'$25 = false'} + + BinTest_MrubyBinDebugger.test(src, tc) +end + +assert('mruby-bin-debugger(print) Ternary operation') do + # ruby source + src = <<"SRC" +CONST = 100 +a,b,c = 1, 5, -10 +foo,bar,baz = 'foo','bar','baz' +ary = [] +SRC + + # test case + tc = [] + tc << {:cmd=>'s'} + tc << {:cmd=>'s'} + tc << {:cmd=>'s'} + + tc << {:cmd=>'p (a < b) ? a : b', :exp=>'$1 = 1'} + tc << {:cmd=>'p (a > b) ? a : b', :exp=>'$2 = 5'} + tc << {:cmd=>'p true ? "true" : "false"', :exp=>'$3 = "true"'} + tc << {:cmd=>'p false ? "true" : "false"', :exp=>'$4 = "false"'} + tc << {:cmd=>'p nil ? "true" : "false"', :exp=>'$5 = "false"'} + + BinTest_MrubyBinDebugger.test(src, tc) +end + +assert('mruby-bin-debugger(print) Substitution:simple') do + # ruby source + src = <<"SRC" +CONST = 100 +a,b,c = 1, 5, -10 +foo,bar,baz = 'foo','bar','baz' +ary = [] +SRC + + # test case + tc = [] + tc << {:cmd=>'s'} + tc << {:cmd=>'s'} + tc << {:cmd=>'s'} + + tc << {:cmd=>'p a=2', :exp=>'$1 = 2'} + tc << {:cmd=>'p foo=[foo,bar,baz]', :exp=>'$2 = ["foo", "bar", "baz"]'} + + tc << {:cmd=>'p undefined=-1', :exp=>'$3 = -1'} + tc << {:cmd=>'p "#{undefined}"', :exp=>'$4 = NoMethodError'} + + BinTest_MrubyBinDebugger.test(src, tc) +end + +assert('mruby-bin-debugger(print) Substitution:self') do + # ruby source + src = <<"SRC" +CONST = 100 +a,b,c = 1, 5, -10 +foo,bar,baz = 'foo','bar','baz' +ary = [] +SRC + + # test case + tc = [] + tc << {:cmd=>'s'} + tc << {:cmd=>'s'} + tc << {:cmd=>'s'} + + tc << {:cmd=>'p a+=9', :exp=>'$1 = 10'} + tc << {:cmd=>'p b-=c', :exp=>'$2 = 15'} + tc << {:cmd=>'p bar*=2', :exp=>'$3 = "barbar"'} + tc << {:cmd=>'p a/=4', :exp=>'$4 = 2.5'} + tc << {:cmd=>'p c%=4', :exp=>'$5 = 2'} + + tc << {:cmd=>'p b&=0b0101', :exp=>'$6 = 5'} + tc << {:cmd=>'p c|=0x10', :exp=>'$7 = 18'} + + tc << {:cmd=>'p "#{a} #{b} #{c}"', :exp=>'$8 = "2.5 5 18"'} + tc << {:cmd=>'p "#{foo}#{bar}#{baz}"', :exp=>'$9 = "foobarbarbaz"'} + + tc << {:cmd=>'p a,b,c=[10,20,30]',:exp=>'$10 = [10, 20, 30]'} + tc << {:cmd=>'p [a,b,c]', :exp=>'$11 = [10, 20, 30]'} + tc << {:cmd=>'p a,b=b,a', :exp=>'$12 = [20, 10]'} + tc << {:cmd=>'p [a,b]', :exp=>'$13 = [20, 10]'} + + tc << {:cmd=>'p undefined=-1', :exp=>'$14 = -1'} + tc << {:cmd=>'p "#{undefined}"', :exp=>'$15 = NoMethodError'} + + BinTest_MrubyBinDebugger.test(src, tc) +end + +assert('mruby-bin-debugger(print) Substitution:multiple') do + # ruby source + src = <<"SRC" +CONST = 100 +a,b,c = 1, 5, -10 +foo,bar,baz = 'foo','bar','baz' +ary = [] +SRC + + # test case + tc = [] + tc << {:cmd=>'s'} + tc << {:cmd=>'s'} + tc << {:cmd=>'s'} + + tc << {:cmd=>'p a,b=[10,20]', :exp=>'$1 = [10, 20]'} + tc << {:cmd=>'p [a,b,c]', :exp=>'$2 = [10, 20, -10]'} + + tc << {:cmd=>'p foo,bar=["FOO","BAR","BAZ"]', :exp=>'$3 = ["FOO", "BAR", "BAZ"]'} + tc << {:cmd=>'p [foo,bar,baz]', :exp=>'$4 = ["FOO", "BAR", "baz"]'} + + tc << {:cmd=>'p a,foo=foo,a', :exp=>'$5 = ["FOO", 10]'} + tc << {:cmd=>'p [a,foo]', :exp=>'$6 = ["FOO", 10]'} + +# tc << {:cmd=>'p a,*b=[123, 456, 789]'} +# tc << {:cmd=>'p [a,b]', :exp=>'[123, [456, 789]]'} + + BinTest_MrubyBinDebugger.test(src, tc) +end + +assert('mruby-bin-debugger(print) Substitution:self') do + # ruby source + src = <<"SRC" +CONST = 100 +a,b,c = 1, 5, -10 +foo,bar,baz = 'foo','bar','baz' +ary = [] +SRC + + # test case + tc = [] + tc << {:cmd=>'s'} + tc << {:cmd=>'s'} + tc << {:cmd=>'s'} + + tc << {:cmd=>'p a+=9', :exp=>'$1 = 10'} + tc << {:cmd=>'p b-=c', :exp=>'$2 = 15'} + tc << {:cmd=>'p bar*=2', :exp=>'$3 = "barbar"'} + tc << {:cmd=>'p a/=4', :exp=>'$4 = 2.5'} + tc << {:cmd=>'p c%=4', :exp=>'$5 = 2'} + + tc << {:cmd=>'p b&=0b0101', :exp=>'$6 = 5'} + tc << {:cmd=>'p c|=0x10', :exp=>'$7 = 18'} + + tc << {:cmd=>'p "#{a} #{b} #{c}"', :exp=>'$8 = "2.5 5 18"'} + tc << {:cmd=>'p "#{foo}#{bar}#{baz}"', :exp=>'$9 = "foobarbarbaz"'} + + tc << {:cmd=>'p a,b,c=[10,20,30]',:exp=>'$10 = [10, 20, 30]'} + tc << {:cmd=>'p [a,b,c]', :exp=>'$11 = [10, 20, 30]'} + tc << {:cmd=>'p a,b=b,a', :exp=>'$12 = [20, 10]'} + tc << {:cmd=>'p [a,b]', :exp=>'$13 = [20, 10]'} + + tc << {:cmd=>'p undefined=-1', :exp=>'$14 = -1'} + tc << {:cmd=>'p "#{undefined}"', :exp=>'$15 = NoMethodError'} + + BinTest_MrubyBinDebugger.test(src, tc) +end + diff --git a/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-bin-debugger/mrbgem.rake b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-bin-debugger/mrbgem.rake new file mode 100644 index 00000000..764f431a --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-bin-debugger/mrbgem.rake @@ -0,0 +1,9 @@ +MRuby::Gem::Specification.new('mruby-bin-debugger') do |spec| + spec.license = 'MIT' + spec.author = 'mruby developers' + spec.summary = 'mruby debugger command' + + spec.add_dependency('mruby-eval', :core => 'mruby-eval') + + spec.bins = %w(mrdb) +end diff --git a/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-bin-debugger/tools/mrdb/apibreak.c b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-bin-debugger/tools/mrdb/apibreak.c new file mode 100644 index 00000000..dead4b2a --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-bin-debugger/tools/mrdb/apibreak.c @@ -0,0 +1,507 @@ +/* +** apibreak.c +** +*/ + +#include +#include +#include +#include "mrdb.h" +#include +#include +#include +#include +#include +#include "mrdberror.h" +#include "apibreak.h" + +#define MAX_BREAKPOINTNO (MAX_BREAKPOINT * 1024) +#define MRB_DEBUG_BP_FILE_OK (0x0001) +#define MRB_DEBUG_BP_LINENO_OK (0x0002) + +static uint16_t +check_lineno(mrb_irep_debug_info_file *info_file, uint16_t lineno) +{ + uint32_t count = info_file->line_entry_count; + uint16_t l_idx; + + if (info_file->line_type == mrb_debug_line_ary) { + for (l_idx = 0; l_idx < count; ++l_idx) { + if (lineno == info_file->lines.ary[l_idx]) { + return lineno; + } + } + } + else { + for (l_idx = 0; l_idx < count; ++l_idx) { + if (lineno == info_file->lines.flat_map[l_idx].line) { + return lineno; + } + } + } + + return 0; +} + +static int32_t +get_break_index(mrb_debug_context *dbg, uint32_t bpno) +{ + uint32_t i; + int32_t index; + char hit = FALSE; + + for(i = 0 ; i < dbg->bpnum; i++) { + if (dbg->bp[i].bpno == bpno) { + hit = TRUE; + index = i; + break; + } + } + + if (hit == FALSE) { + return MRB_DEBUG_BREAK_INVALID_NO; + } + + return index; +} + +static void +free_breakpoint(mrb_state *mrb, mrb_debug_breakpoint *bp) +{ + switch(bp->type) { + case MRB_DEBUG_BPTYPE_LINE: + mrb_free(mrb, (void*)bp->point.linepoint.file); + break; + case MRB_DEBUG_BPTYPE_METHOD: + mrb_free(mrb, (void*)bp->point.methodpoint.method_name); + if (bp->point.methodpoint.class_name != NULL) { + mrb_free(mrb, (void*)bp->point.methodpoint.class_name); + } + break; + default: + break; + } +} + +static uint16_t +check_file_lineno(struct mrb_irep *irep, const char *file, uint16_t lineno) +{ + mrb_irep_debug_info_file *info_file; + uint16_t result = 0; + uint16_t f_idx; + uint16_t fix_lineno; + uint16_t i; + + for (f_idx = 0; f_idx < irep->debug_info->flen; ++f_idx) { + info_file = irep->debug_info->files[f_idx]; + if (!strcmp(info_file->filename, file)) { + result = MRB_DEBUG_BP_FILE_OK; + + fix_lineno = check_lineno(info_file, lineno); + if (fix_lineno != 0) { + return result | MRB_DEBUG_BP_LINENO_OK; + } + } + for (i=0; i < irep->rlen; ++i) { + result |= check_file_lineno(irep->reps[i], file, lineno); + if (result == (MRB_DEBUG_BP_FILE_OK | MRB_DEBUG_BP_LINENO_OK)) { + return result; + } + } + } + return result; +} + +static int32_t +compare_break_method(mrb_state *mrb, mrb_debug_breakpoint *bp, struct RClass *class_obj, mrb_sym method_sym, mrb_bool* isCfunc) +{ + const char* class_name; + const char* method_name; + struct RProc* m; + struct RClass* sc; + const char* sn; + mrb_sym ssym; + mrb_debug_methodpoint *method_p; + mrb_bool is_defined; + + method_name = mrb_sym2name(mrb, method_sym); + + method_p = &bp->point.methodpoint; + if (strcmp(method_p->method_name, method_name) == 0) { + class_name = mrb_class_name(mrb, class_obj); + if (class_name == NULL) { + if (method_p->class_name == NULL) { + return bp->bpno; + } + } + else if (method_p->class_name != NULL) { + m = mrb_method_search_vm(mrb, &class_obj, method_sym); + if (m == NULL) { + return MRB_DEBUG_OK; + } + if (MRB_PROC_CFUNC_P(m)) { + *isCfunc = TRUE; + } + + is_defined = mrb_class_defined(mrb, method_p->class_name); + if (is_defined == FALSE) { + return MRB_DEBUG_OK; + } + + sc = mrb_class_get(mrb, method_p->class_name); + ssym = mrb_symbol(mrb_check_intern_cstr(mrb, method_p->method_name)); + m = mrb_method_search_vm(mrb, &sc, ssym); + if (m == NULL) { + return MRB_DEBUG_OK; + } + + class_name = mrb_class_name(mrb, class_obj); + sn = mrb_class_name(mrb, sc); + if (strcmp(sn, class_name) == 0) { + return bp->bpno; + } + } + } + return MRB_DEBUG_OK; +} + +int32_t +mrb_debug_set_break_line(mrb_state *mrb, mrb_debug_context *dbg, const char *file, uint16_t lineno) +{ + int32_t index; + char* set_file; + uint16_t result; + + if ((mrb == NULL)||(dbg == NULL)||(file == NULL)) { + return MRB_DEBUG_INVALID_ARGUMENT; + } + + if (dbg->bpnum >= MAX_BREAKPOINT) { + return MRB_DEBUG_BREAK_NUM_OVER; + } + + if (dbg->next_bpno > MAX_BREAKPOINTNO) { + return MRB_DEBUG_BREAK_NO_OVER; + } + + /* file and lineno check (line type mrb_debug_line_ary only.) */ + result = check_file_lineno(dbg->root_irep, file, lineno); + if (result == 0) { + return MRB_DEBUG_BREAK_INVALID_FILE; + } + else if (result == MRB_DEBUG_BP_FILE_OK) { + return MRB_DEBUG_BREAK_INVALID_LINENO; + } + + set_file = mrb_malloc(mrb, strlen(file) + 1); + + index = dbg->bpnum; + dbg->bp[index].bpno = dbg->next_bpno; + dbg->next_bpno++; + dbg->bp[index].enable = TRUE; + dbg->bp[index].type = MRB_DEBUG_BPTYPE_LINE; + dbg->bp[index].point.linepoint.lineno = lineno; + dbg->bpnum++; + + strncpy(set_file, file, strlen(file) + 1); + + dbg->bp[index].point.linepoint.file = set_file; + + return dbg->bp[index].bpno; +} + +int32_t +mrb_debug_set_break_method(mrb_state *mrb, mrb_debug_context *dbg, const char *class_name, const char *method_name) +{ + int32_t index; + char* set_class; + char* set_method; + + if ((mrb == NULL) || (dbg == NULL) || (method_name == NULL)) { + return MRB_DEBUG_INVALID_ARGUMENT; + } + + if (dbg->bpnum >= MAX_BREAKPOINT) { + return MRB_DEBUG_BREAK_NUM_OVER; + } + + if (dbg->next_bpno > MAX_BREAKPOINTNO) { + return MRB_DEBUG_BREAK_NO_OVER; + } + + if (class_name != NULL) { + set_class = mrb_malloc(mrb, strlen(class_name) + 1); + strncpy(set_class, class_name, strlen(class_name) + 1); + } + else { + set_class = NULL; + } + + set_method = mrb_malloc(mrb, strlen(method_name) + 1); + + strncpy(set_method, method_name, strlen(method_name) + 1); + + index = dbg->bpnum; + dbg->bp[index].bpno = dbg->next_bpno; + dbg->next_bpno++; + dbg->bp[index].enable = TRUE; + dbg->bp[index].type = MRB_DEBUG_BPTYPE_METHOD; + dbg->bp[index].point.methodpoint.method_name = set_method; + dbg->bp[index].point.methodpoint.class_name = set_class; + dbg->bpnum++; + + return dbg->bp[index].bpno; +} + +int32_t +mrb_debug_get_breaknum(mrb_state *mrb, mrb_debug_context *dbg) +{ + if ((mrb == NULL) || (dbg == NULL)) { + return MRB_DEBUG_INVALID_ARGUMENT; + } + + return dbg->bpnum; +} + +int32_t +mrb_debug_get_break_all(mrb_state *mrb, mrb_debug_context *dbg, uint32_t size, mrb_debug_breakpoint *bp) +{ + uint32_t get_size = 0; + + if ((mrb == NULL) || (dbg == NULL) || (bp == NULL)) { + return MRB_DEBUG_INVALID_ARGUMENT; + } + + if (dbg->bpnum >= size) { + get_size = size; + } + else { + get_size = dbg->bpnum; + } + + memcpy(bp, dbg->bp, sizeof(mrb_debug_breakpoint) * get_size); + + return get_size; +} + +int32_t +mrb_debug_get_break(mrb_state *mrb, mrb_debug_context *dbg, uint32_t bpno, mrb_debug_breakpoint *bp) +{ + int32_t index; + + if ((mrb == NULL) || (dbg == NULL) || (bp == NULL)) { + return MRB_DEBUG_INVALID_ARGUMENT; + } + + index = get_break_index(dbg, bpno); + if (index == MRB_DEBUG_BREAK_INVALID_NO) { + return MRB_DEBUG_BREAK_INVALID_NO; + } + + bp->bpno = dbg->bp[index].bpno; + bp->enable = dbg->bp[index].enable; + bp->point = dbg->bp[index].point; + bp->type = dbg->bp[index].type; + + return 0; +} + +int32_t +mrb_debug_delete_break(mrb_state *mrb, mrb_debug_context *dbg, uint32_t bpno) +{ + uint32_t i; + int32_t index; + + if ((mrb == NULL) ||(dbg == NULL)) { + return MRB_DEBUG_INVALID_ARGUMENT; + } + + index = get_break_index(dbg, bpno); + if (index == MRB_DEBUG_BREAK_INVALID_NO) { + return MRB_DEBUG_BREAK_INVALID_NO; + } + + free_breakpoint(mrb, &dbg->bp[index]); + + for(i = index ; i < dbg->bpnum; i++) { + if ((i + 1) == dbg->bpnum) { + memset(&dbg->bp[i], 0, sizeof(mrb_debug_breakpoint)); + } + else { + memcpy(&dbg->bp[i], &dbg->bp[i + 1], sizeof(mrb_debug_breakpoint)); + } + } + + dbg->bpnum--; + + return MRB_DEBUG_OK; +} + +int32_t +mrb_debug_delete_break_all(mrb_state *mrb, mrb_debug_context *dbg) +{ + uint32_t i; + + if ((mrb == NULL) || (dbg == NULL)) { + return MRB_DEBUG_INVALID_ARGUMENT; + } + + for(i = 0 ; i < dbg->bpnum ; i++) { + free_breakpoint(mrb, &dbg->bp[i]); + } + + dbg->bpnum = 0; + + return MRB_DEBUG_OK; +} + +int32_t +mrb_debug_enable_break(mrb_state *mrb, mrb_debug_context *dbg, uint32_t bpno) +{ + int32_t index = 0; + + if ((mrb == NULL) || (dbg == NULL)) { + return MRB_DEBUG_INVALID_ARGUMENT; + } + + index = get_break_index(dbg, bpno); + if (index == MRB_DEBUG_BREAK_INVALID_NO) { + return MRB_DEBUG_BREAK_INVALID_NO; + } + + dbg->bp[index].enable = TRUE; + + return MRB_DEBUG_OK; +} + +int32_t +mrb_debug_enable_break_all(mrb_state *mrb, mrb_debug_context *dbg) +{ + uint32_t i; + + if ((mrb == NULL) || (dbg == NULL)) { + return MRB_DEBUG_INVALID_ARGUMENT; + } + + for(i = 0 ; i < dbg->bpnum; i++) { + dbg->bp[i].enable = TRUE; + } + + return MRB_DEBUG_OK; +} + +int32_t +mrb_debug_disable_break(mrb_state *mrb, mrb_debug_context *dbg, uint32_t bpno) +{ + int32_t index = 0; + + if ((mrb == NULL) || (dbg == NULL)) { + return MRB_DEBUG_INVALID_ARGUMENT; + } + + index = get_break_index(dbg, bpno); + if (index == MRB_DEBUG_BREAK_INVALID_NO) { + return MRB_DEBUG_BREAK_INVALID_NO; + } + + dbg->bp[index].enable = FALSE; + + return MRB_DEBUG_OK; +} + +int32_t +mrb_debug_disable_break_all(mrb_state *mrb, mrb_debug_context *dbg) +{ + uint32_t i; + + if ((mrb == NULL) || (dbg == NULL)) { + return MRB_DEBUG_INVALID_ARGUMENT; + } + + for(i = 0 ; i < dbg->bpnum; i++) { + dbg->bp[i].enable = FALSE; + } + + return MRB_DEBUG_OK; +} + +static mrb_bool +check_start_pc_for_line(mrb_irep *irep, mrb_code *pc, uint16_t line) +{ + if (pc > irep->iseq) { + if (line == mrb_debug_get_line(irep, pc - irep->iseq - 1)) { + return FALSE; + } + } + return TRUE; +} + +int32_t +mrb_debug_check_breakpoint_line(mrb_state *mrb, mrb_debug_context *dbg, const char *file, uint16_t line) +{ + mrb_debug_breakpoint *bp; + mrb_debug_linepoint *line_p; + uint32_t i; + + if ((mrb == NULL) || (dbg == NULL) || (file == NULL) || (line <= 0)) { + return MRB_DEBUG_INVALID_ARGUMENT; + } + + if (!check_start_pc_for_line(dbg->irep, dbg->pc, line)) { + return MRB_DEBUG_OK; + } + + bp = dbg->bp; + for(i=0; ibpnum; i++) { + switch (bp->type) { + case MRB_DEBUG_BPTYPE_LINE: + if (bp->enable == TRUE) { + line_p = &bp->point.linepoint; + if ((strcmp(line_p->file, file) == 0) && (line_p->lineno == line)) { + return bp->bpno; + } + } + break; + case MRB_DEBUG_BPTYPE_METHOD: + break; + case MRB_DEBUG_BPTYPE_NONE: + default: + return MRB_DEBUG_OK; + } + bp++; + } + return MRB_DEBUG_OK; +} + + +int32_t +mrb_debug_check_breakpoint_method(mrb_state *mrb, mrb_debug_context *dbg, struct RClass *class_obj, mrb_sym method_sym, mrb_bool* isCfunc) +{ + mrb_debug_breakpoint *bp; + int32_t bpno; + uint32_t i; + + if ((mrb == NULL) || (dbg == NULL) || (class_obj == NULL)) { + return MRB_DEBUG_INVALID_ARGUMENT; + } + + bp = dbg->bp; + for(i=0; ibpnum; i++) { + if (bp->type == MRB_DEBUG_BPTYPE_METHOD) { + if (bp->enable == TRUE) { + bpno = compare_break_method(mrb, bp, class_obj, method_sym, isCfunc); + if (bpno > 0) { + return bpno; + } + } + } + else if (bp->type == MRB_DEBUG_BPTYPE_NONE) { + break; + } + bp++; + } + + return 0; +} + + diff --git a/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-bin-debugger/tools/mrdb/apibreak.h b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-bin-debugger/tools/mrdb/apibreak.h new file mode 100644 index 00000000..08f1d808 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-bin-debugger/tools/mrdb/apibreak.h @@ -0,0 +1,26 @@ +/* +** apibreak.h +** +*/ + +#ifndef APIBREAK_H_ +#define APIBREAK_H_ + +#include +#include "mrdb.h" + +int32_t mrb_debug_set_break_line(mrb_state *, mrb_debug_context *, const char *, uint16_t); +int32_t mrb_debug_set_break_method(mrb_state *, mrb_debug_context *, const char *, const char *); +int32_t mrb_debug_get_breaknum(mrb_state *, mrb_debug_context *); +int32_t mrb_debug_get_break_all(mrb_state *, mrb_debug_context *, uint32_t, mrb_debug_breakpoint bp[]); +int32_t mrb_debug_get_break(mrb_state *, mrb_debug_context *, uint32_t, mrb_debug_breakpoint *); +int32_t mrb_debug_delete_break(mrb_state *, mrb_debug_context *, uint32_t); +int32_t mrb_debug_delete_break_all(mrb_state *, mrb_debug_context *); +int32_t mrb_debug_enable_break(mrb_state *, mrb_debug_context *, uint32_t); +int32_t mrb_debug_enable_break_all(mrb_state *, mrb_debug_context *); +int32_t mrb_debug_disable_break(mrb_state *, mrb_debug_context *, uint32_t); +int32_t mrb_debug_disable_break_all(mrb_state *, mrb_debug_context *); +int32_t mrb_debug_check_breakpoint_line(mrb_state *, mrb_debug_context *, const char *, uint16_t); +int32_t mrb_debug_check_breakpoint_method(mrb_state *, mrb_debug_context *, struct RClass *, mrb_sym, mrb_bool*); + +#endif /* APIBREAK_H_ */ diff --git a/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-bin-debugger/tools/mrdb/apilist.c b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-bin-debugger/tools/mrdb/apilist.c new file mode 100644 index 00000000..8aaa30bc --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-bin-debugger/tools/mrdb/apilist.c @@ -0,0 +1,239 @@ +/* + * apilist.c + */ + +#include +#include +#include + +#include "mrdb.h" +#include "mrdberror.h" +#include "apilist.h" +#include +#include +#include + +#define LINE_BUF_SIZE MAX_COMMAND_LINE + +typedef struct source_file { + char *path; + uint16_t lineno; + FILE *fp; +} source_file; + +static void +source_file_free(mrb_state *mrb, source_file *file) +{ + if (file != NULL) { + if (file->path != NULL) { + mrb_free(mrb, file->path); + } + if (file->fp != NULL) { + fclose(file->fp); + file->fp = NULL; + } + mrb_free(mrb, file); + } +} + +static char* +build_path(mrb_state *mrb, const char *dir, const char *base) +{ + int len; + char *path = NULL; + + len = strlen(base) + 1; + + if (strcmp(dir, ".")) { + len += strlen(dir) + sizeof("/") - 1; + } + + path = mrb_malloc(mrb, len); + memset(path, 0, len); + + if (strcmp(dir, ".")) { + strcat(path, dir); + strcat(path, "/"); + } + strcat(path, base); + + return path; +} + +static char* +dirname(mrb_state *mrb, const char *path) +{ + size_t len; + char *p, *dir; + + if (path == NULL) { + return NULL; + } + + p = strrchr(path, '/'); + len = p != NULL ? (size_t)(p - path) : strlen(path); + + dir = mrb_malloc(mrb, len + 1); + strncpy(dir, path, len); + dir[len] = '\0'; + + return dir; +} + +static source_file* +source_file_new(mrb_state *mrb, mrb_debug_context *dbg, char *filename) +{ + source_file *file = NULL; + + file = mrb_malloc(mrb, sizeof(source_file)); + + memset(file, '\0', sizeof(source_file)); + file->fp = fopen(filename, "rb"); + + if (file->fp == NULL) { + source_file_free(mrb, file); + return NULL; + } + + file->lineno = 1; + file->path = mrb_malloc(mrb, strlen(filename) + 1); + strcpy(file->path, filename); + return file; +} + +static mrb_bool +remove_newlines(char *s, FILE *fp) +{ + int c; + char *p; + size_t len; + + if ((len = strlen(s)) == 0) { + return FALSE; + } + + p = s + len - 1; + + if (*p != '\r' && *p != '\n') { + return FALSE; + } + + if (*p == '\r') { + /* peek the next character and skip '\n' */ + if ((c = fgetc(fp)) != '\n') { + ungetc(c, fp); + } + } + + /* remove trailing newline characters */ + while (s <= p && (*p == '\r' || *p == '\n')) { + *p-- = '\0'; + } + + return TRUE; +} + +static void +show_lines(source_file *file, uint16_t line_min, uint16_t line_max) +{ + char buf[LINE_BUF_SIZE]; + int show_lineno = 1, found_newline = 0, is_printed = 0; + + if (file->fp == NULL) { + return; + } + + while (fgets(buf, sizeof(buf), file->fp) != NULL) { + found_newline = remove_newlines(buf, file->fp); + + if (line_min <= file->lineno) { + if (show_lineno) { + printf("%-8d", file->lineno); + } + show_lineno = found_newline; + printf(found_newline ? "%s\n" : "%s", buf); + is_printed = 1; + } + + if (found_newline) { + if (line_max < ++file->lineno) { + break; + } + } + } + + if (is_printed && !found_newline) { + printf("\n"); + } +} + +char* +mrb_debug_get_source(mrb_state *mrb, mrdb_state *mrdb, const char *srcpath, const char *filename) +{ + int i; + FILE *fp; + const char *search_path[3]; + char *path = NULL; + const char *srcname = strrchr(filename, '/'); + + if (srcname) srcname++; + else srcname = filename; + + search_path[0] = srcpath; + search_path[1] = dirname(mrb, mrb_debug_get_filename(mrdb->dbg->irep, 0)); + search_path[2] = "."; + + for (i = 0; i < 3; i++) { + if (search_path[i] == NULL) { + continue; + } + + if ((path = build_path(mrb, search_path[i], srcname)) == NULL) { + continue; + } + + if ((fp = fopen(path, "rb")) == NULL) { + mrb_free(mrb, path); + path = NULL; + continue; + } + fclose(fp); + break; + } + + mrb_free(mrb, (void *)search_path[1]); + + return path; +} + +int32_t +mrb_debug_list(mrb_state *mrb, mrb_debug_context *dbg, char *filename, uint16_t line_min, uint16_t line_max) +{ + char *ext; + source_file *file; + + if (mrb == NULL || dbg == NULL || filename == NULL) { + return MRB_DEBUG_INVALID_ARGUMENT; + } + + ext = strrchr(filename, '.'); + + if (ext == NULL || strcmp(ext, ".rb")) { + printf("List command only supports .rb file.\n"); + return MRB_DEBUG_INVALID_ARGUMENT; + } + + if (line_min > line_max) { + return MRB_DEBUG_INVALID_ARGUMENT; + } + + if ((file = source_file_new(mrb, dbg, filename)) != NULL) { + show_lines(file, line_min, line_max); + source_file_free(mrb, file); + return MRB_DEBUG_OK; + } + else { + printf("Invalid source file named %s.\n", filename); + return MRB_DEBUG_INVALID_ARGUMENT; + } +} diff --git a/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-bin-debugger/tools/mrdb/apilist.h b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-bin-debugger/tools/mrdb/apilist.h new file mode 100644 index 00000000..6c410788 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-bin-debugger/tools/mrdb/apilist.h @@ -0,0 +1,14 @@ +/* + * apilist.h + */ + +#ifndef APILIST_H_ +#define APILIST_H_ + +#include +#include "mrdb.h" + +int32_t mrb_debug_list(mrb_state *, mrb_debug_context *, char *, uint16_t, uint16_t); +char* mrb_debug_get_source(mrb_state *, mrdb_state *, const char *, const char *); + +#endif /* APILIST_H_ */ diff --git a/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-bin-debugger/tools/mrdb/apiprint.c b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-bin-debugger/tools/mrdb/apiprint.c new file mode 100644 index 00000000..a9c895b5 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-bin-debugger/tools/mrdb/apiprint.c @@ -0,0 +1,78 @@ +/* +** apiprint.c +** +*/ + +#include +#include "mrdb.h" +#include +#include +#include +#include +#include +#include +#include "apiprint.h" + +static void +mrdb_check_syntax(mrb_state *mrb, mrb_debug_context *dbg, const char *expr, size_t len) +{ + mrbc_context *c; + + c = mrbc_context_new(mrb); + c->no_exec = TRUE; + c->capture_errors = TRUE; + c->filename = (char*)dbg->prvfile; + c->lineno = dbg->prvline; + + /* Load program */ + mrb_load_nstring_cxt(mrb, expr, len, c); + + mrbc_context_free(mrb, c); +} + +mrb_value +mrb_debug_eval(mrb_state *mrb, mrb_debug_context *dbg, const char *expr, size_t len, mrb_bool *exc) +{ + void (*tmp)(struct mrb_state *, struct mrb_irep *, mrb_code *, mrb_value *); + mrb_value ruby_code; + mrb_value s; + mrb_value v; + mrb_value recv; + + /* disable code_fetch_hook */ + tmp = mrb->code_fetch_hook; + mrb->code_fetch_hook = NULL; + + mrdb_check_syntax(mrb, dbg, expr, len); + if (mrb->exc) { + v = mrb_obj_value(mrb->exc); + mrb->exc = 0; + } + else { + /* + * begin + * expr + * rescue => e + * e + * end + */ + ruby_code = mrb_str_new_lit(mrb, "begin\n"); + ruby_code = mrb_str_cat(mrb, ruby_code, expr, len); + ruby_code = mrb_str_cat_lit(mrb, ruby_code, "\nrescue => e\ne\nend"); + + recv = dbg->regs[0]; + + v = mrb_funcall(mrb, recv, "instance_eval", 1, ruby_code); + } + + if (exc) { + *exc = mrb_obj_is_kind_of(mrb, v, mrb->eException_class); + } + + s = mrb_funcall(mrb, v, "inspect", 0); + + /* enable code_fetch_hook */ + mrb->code_fetch_hook = tmp; + + return s; +} diff --git a/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-bin-debugger/tools/mrdb/apiprint.h b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-bin-debugger/tools/mrdb/apiprint.h new file mode 100644 index 00000000..e256f626 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-bin-debugger/tools/mrdb/apiprint.h @@ -0,0 +1,13 @@ +/* + * apiprint.h + */ + +#ifndef APIPRINT_H_ +#define APIPRINT_H_ + +#include +#include "mrdb.h" + +mrb_value mrb_debug_eval(mrb_state*, mrb_debug_context*, const char*, size_t, mrb_bool*); + +#endif /* APIPRINT_H_ */ diff --git a/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-bin-debugger/tools/mrdb/cmdbreak.c b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-bin-debugger/tools/mrdb/cmdbreak.c new file mode 100644 index 00000000..8e590175 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-bin-debugger/tools/mrdb/cmdbreak.c @@ -0,0 +1,436 @@ +/* +** cmdbreak.c +** +*/ + +#include +#include +#include +#include +#include +#include +#include "mrdb.h" +#include "mrdberror.h" +#include "apibreak.h" + +#define BREAK_SET_MSG_LINE "Breakpoint %d: file %s, line %d.\n" +#define BREAK_SET_MSG_METHOD "Breakpoint %d: method %s.\n" +#define BREAK_SET_MSG_CLASS_METHOD "Breakpoint %d: class %s, method %s.\n" +#define BREAK_INFO_MSG_HEADER "Num Type Enb What" +#define BREAK_INFO_MSG_LINEBREAK "%-8ubreakpoint %s at %s:%u\n" +#define BREAK_INFO_MSG_METHODBREAK "%-8ubreakpoint %s in %s:%s\n" +#define BREAK_INFO_MSG_METHODBREAK_NOCLASS "%-8ubreakpoint %s in %s\n" +#define BREAK_INFO_MSG_ENABLE "y" +#define BREAK_INFO_MSG_DISABLE "n" + +#define BREAK_ERR_MSG_INVALIDARG "Internal error." +#define BREAK_ERR_MSG_BLANK "Try \'help break\' for more information." +#define BREAK_ERR_MSG_RANGEOVER "The line number range is from 1 to 65535." +#define BREAK_ERR_MSG_NUMOVER "Exceeded the setable number of breakpoint." +#define BREAK_ERR_MSG_NOOVER "Breakno is over the available number.Please 'quit' and restart mrdb." +#define BREAK_ERR_MSG_INVALIDSTR "String \'%s\' is invalid.\n" +#define BREAK_ERR_MSG_INVALIDLINENO "Line %d in file \"%s\" is unavailable.\n" +#define BREAK_ERR_MSG_INVALIDCLASS "Class name \'%s\' is invalid.\n" +#define BREAK_ERR_MSG_INVALIDMETHOD "Method name \'%s\' is invalid.\n" +#define BREAK_ERR_MSG_INVALIDFILE "Source file named \"%s\" is unavailable.\n" +#define BREAK_ERR_MSG_INVALIDBPNO "warning: bad breakpoint number at or near '%s'\n" +#define BREAK_ERR_MSG_INVALIDBPNO_INFO "Args must be numbers variables." +#define BREAK_ERR_MSG_NOBPNO "No breakpoint number %d.\n" +#define BREAK_ERR_MSG_NOBPNO_INFO "No breakpoint matching '%d'\n" +#define BREAK_ERR_MSG_NOBPNO_INFOALL "No breakpoints." + +#define LINENO_MAX_DIGIT 6 +#define BPNO_LETTER_NUM 9 + +typedef int32_t (*all_command_func)(mrb_state *, mrb_debug_context *); +typedef int32_t (*select_command_func)(mrb_state *, mrb_debug_context *, uint32_t); + +static void +print_api_common_error(int32_t error) +{ + switch(error) { + case MRB_DEBUG_INVALID_ARGUMENT: + puts(BREAK_ERR_MSG_INVALIDARG); + break; + default: + break; + } +} + +#undef STRTOUL +#define STRTOUL(ul,s) { \ + int i; \ + ul = 0; \ + for(i=0; ISDIGIT(s[i]); i++) ul = 10*ul + (s[i] -'0'); \ +} + +static int32_t +parse_breakpoint_no(char* args) +{ + char* ps = args; + uint32_t l; + + if ((*ps == '0')||(strlen(ps) >= BPNO_LETTER_NUM)) { + return 0; + } + + while (!(ISBLANK(*ps)||ISCNTRL(*ps))) { + if (!ISDIGIT(*ps)) { + return 0; + } + ps++; + } + + STRTOUL(l, args); + return l; +} + +static mrb_bool +exe_set_command_all(mrb_state *mrb, mrdb_state *mrdb, all_command_func func) +{ + int32_t ret = MRB_DEBUG_OK; + + if (mrdb->wcnt == 1) { + ret = func(mrb, mrdb->dbg); + print_api_common_error(ret); + return TRUE; + } + return FALSE; +} + +static void +exe_set_command_select(mrb_state *mrb, mrdb_state *mrdb, select_command_func func) +{ + char* ps; + int32_t ret = MRB_DEBUG_OK; + int32_t bpno = 0; + int32_t i; + + for(i=1; iwcnt; i++) { + ps = mrdb->words[i]; + bpno = parse_breakpoint_no(ps); + if (bpno == 0) { + printf(BREAK_ERR_MSG_INVALIDBPNO, ps); + break; + } + ret = func(mrb, mrdb->dbg, (uint32_t)bpno); + if (ret == MRB_DEBUG_BREAK_INVALID_NO) { + printf(BREAK_ERR_MSG_NOBPNO, bpno); + } + else if (ret != MRB_DEBUG_OK) { + print_api_common_error(ret); + } + } +} + +mrb_debug_bptype +check_bptype(char* args) +{ + char* ps = args; + + if (ISBLANK(*ps)||ISCNTRL(*ps)) { + puts(BREAK_ERR_MSG_BLANK); + return MRB_DEBUG_BPTYPE_NONE; + } + + if (!ISDIGIT(*ps)) { + return MRB_DEBUG_BPTYPE_METHOD; + } + + while (!(ISBLANK(*ps)||ISCNTRL(*ps))) { + if (!ISDIGIT(*ps)) { + printf(BREAK_ERR_MSG_INVALIDSTR, args); + return MRB_DEBUG_BPTYPE_NONE; + } + ps++; + } + + if ((*args == '0')||(strlen(args) >= LINENO_MAX_DIGIT)) { + puts(BREAK_ERR_MSG_RANGEOVER); + return MRB_DEBUG_BPTYPE_NONE; + } + + return MRB_DEBUG_BPTYPE_LINE; +} + +static void +print_breakpoint(mrb_debug_breakpoint *bp) +{ + const char* enable_letter[] = {BREAK_INFO_MSG_DISABLE, BREAK_INFO_MSG_ENABLE}; + + if (bp->type == MRB_DEBUG_BPTYPE_LINE) { + printf(BREAK_INFO_MSG_LINEBREAK, + bp->bpno, enable_letter[bp->enable], bp->point.linepoint.file, bp->point.linepoint.lineno); + } + else { + if (bp->point.methodpoint.class_name == NULL) { + printf(BREAK_INFO_MSG_METHODBREAK_NOCLASS, + bp->bpno, enable_letter[bp->enable], bp->point.methodpoint.method_name); + } + else { + printf(BREAK_INFO_MSG_METHODBREAK, + bp->bpno, enable_letter[bp->enable], bp->point.methodpoint.class_name, bp->point.methodpoint.method_name); + } + } +} + +static void +info_break_all(mrb_state *mrb, mrdb_state *mrdb) +{ + int32_t bpnum = 0; + int32_t i = 0; + int32_t ret = MRB_DEBUG_OK; + mrb_debug_breakpoint *bp_list; + + bpnum = mrb_debug_get_breaknum(mrb, mrdb->dbg); + if (bpnum < 0) { + print_api_common_error(bpnum); + return; + } + else if (bpnum == 0) { + puts(BREAK_ERR_MSG_NOBPNO_INFOALL); + return; + } + bp_list = (mrb_debug_breakpoint*)mrb_malloc(mrb, bpnum * sizeof(mrb_debug_breakpoint)); + + ret = mrb_debug_get_break_all(mrb, mrdb->dbg, (uint32_t)bpnum, bp_list); + if (ret < 0) { + print_api_common_error(ret); + return; + } + puts(BREAK_INFO_MSG_HEADER); + for(i = 0 ; i < bpnum ; i++) { + print_breakpoint(&bp_list[i]); + } + + mrb_free(mrb, bp_list); +} + +static void +info_break_select(mrb_state *mrb, mrdb_state *mrdb) +{ + int32_t ret = MRB_DEBUG_OK; + int32_t bpno = 0; + char* ps = mrdb->command; + mrb_debug_breakpoint bp; + mrb_bool isFirst = TRUE; + int32_t i; + + for(i=2; iwcnt; i++) { + ps = mrdb->words[i]; + bpno = parse_breakpoint_no(ps); + if (bpno == 0) { + puts(BREAK_ERR_MSG_INVALIDBPNO_INFO); + break; + } + + ret = mrb_debug_get_break(mrb, mrdb->dbg, bpno, &bp); + if (ret == MRB_DEBUG_BREAK_INVALID_NO) { + printf(BREAK_ERR_MSG_NOBPNO_INFO, bpno); + break; + } + else if (ret != MRB_DEBUG_OK) { + print_api_common_error(ret); + break; + } + else if (isFirst == TRUE) { + isFirst = FALSE; + puts(BREAK_INFO_MSG_HEADER); + } + print_breakpoint(&bp); + } +} + +mrb_debug_bptype +parse_breakcommand(mrdb_state *mrdb, const char **file, uint32_t *line, char **cname, char **method) +{ + mrb_debug_context *dbg = mrdb->dbg; + char *args; + char *body; + mrb_debug_bptype type; + uint32_t l; + + if (mrdb->wcnt <= 1) { + puts(BREAK_ERR_MSG_BLANK); + return MRB_DEBUG_BPTYPE_NONE; + } + + args = mrdb->words[1]; + if ((body = strrchr(args, ':')) == NULL) { + body = args; + type = check_bptype(body); + } + else { + if (body == args) { + printf(BREAK_ERR_MSG_INVALIDSTR, args); + return MRB_DEBUG_BPTYPE_NONE; + } + *body = '\0'; + type = check_bptype(++body); + } + + switch(type) { + case MRB_DEBUG_BPTYPE_LINE: + STRTOUL(l, body); + if (l <= 65535) { + *line = l; + *file = (body == args)? mrb_debug_get_filename(dbg->irep, dbg->pc - dbg->irep->iseq): args; + } + else { + puts(BREAK_ERR_MSG_RANGEOVER); + type = MRB_DEBUG_BPTYPE_NONE; + } + break; + case MRB_DEBUG_BPTYPE_METHOD: + if (body == args) { + /* method only */ + if (ISUPPER(*body)||ISLOWER(*body)||(*body == '_')) { + *method = body; + *cname = NULL; + } + else { + printf(BREAK_ERR_MSG_INVALIDMETHOD, args); + type = MRB_DEBUG_BPTYPE_NONE; + } + } + else { + if (ISUPPER(*args)) { + switch(*body) { + case '@': case '$': case '?': case '.': case ',': case ':': + case ';': case '#': case '\\': case '\'': case '\"': + printf(BREAK_ERR_MSG_INVALIDMETHOD, body); + type = MRB_DEBUG_BPTYPE_NONE; + break; + default: + *method = body; + *cname = args; + break; + } + } + else { + printf(BREAK_ERR_MSG_INVALIDCLASS, args); + type = MRB_DEBUG_BPTYPE_NONE; + } + } + break; + case MRB_DEBUG_BPTYPE_NONE: + default: + break; + } + + return type; +} + +dbgcmd_state +dbgcmd_break(mrb_state *mrb, mrdb_state *mrdb) +{ + mrb_debug_bptype type; + mrb_debug_context *dbg = mrdb->dbg; + const char *file = NULL; + uint32_t line = 0; + char *cname = NULL; + char *method = NULL; + int32_t ret; + + type = parse_breakcommand(mrdb, &file, &line, &cname, &method); + switch (type) { + case MRB_DEBUG_BPTYPE_LINE: + ret = mrb_debug_set_break_line(mrb, dbg, file, line); + break; + case MRB_DEBUG_BPTYPE_METHOD: + ret = mrb_debug_set_break_method(mrb, dbg, cname, method); + break; + case MRB_DEBUG_BPTYPE_NONE: + default: + return DBGST_PROMPT; + } + + if (ret >= 0) { + if (type == MRB_DEBUG_BPTYPE_LINE) { + printf(BREAK_SET_MSG_LINE, ret, file, line); + } + else if ((type == MRB_DEBUG_BPTYPE_METHOD)&&(cname == NULL)) { + printf(BREAK_SET_MSG_METHOD, ret, method); + } + else { + printf(BREAK_SET_MSG_CLASS_METHOD, ret, cname, method); + } + } + else { + switch (ret) { + case MRB_DEBUG_BREAK_INVALID_LINENO: + printf(BREAK_ERR_MSG_INVALIDLINENO, line, file); + break; + case MRB_DEBUG_BREAK_INVALID_FILE: + printf(BREAK_ERR_MSG_INVALIDFILE, file); + break; + case MRB_DEBUG_BREAK_NUM_OVER: + puts(BREAK_ERR_MSG_NUMOVER); + break; + case MRB_DEBUG_BREAK_NO_OVER: + puts(BREAK_ERR_MSG_NOOVER); + break; + case MRB_DEBUG_INVALID_ARGUMENT: + puts(BREAK_ERR_MSG_INVALIDARG); + break; + case MRB_DEBUG_NOBUF: + puts("T.B.D."); + break; + default: + break; + } + } + + return DBGST_PROMPT; +} + +dbgcmd_state +dbgcmd_info_break(mrb_state *mrb, mrdb_state *mrdb) +{ + if (mrdb->wcnt == 2) { + info_break_all(mrb, mrdb); + } + else { + info_break_select(mrb, mrdb); + } + + return DBGST_PROMPT; +} + +dbgcmd_state +dbgcmd_delete(mrb_state *mrb, mrdb_state *mrdb) +{ + mrb_bool ret = FALSE; + + ret = exe_set_command_all(mrb, mrdb, mrb_debug_delete_break_all); + if (ret != TRUE) { + exe_set_command_select(mrb, mrdb, mrb_debug_delete_break); + } + + return DBGST_PROMPT; +} + +dbgcmd_state +dbgcmd_enable(mrb_state *mrb, mrdb_state *mrdb) +{ + mrb_bool ret = FALSE; + + ret = exe_set_command_all(mrb, mrdb, mrb_debug_enable_break_all); + if (ret != TRUE) { + exe_set_command_select(mrb, mrdb, mrb_debug_enable_break); + } + + return DBGST_PROMPT; +} + +dbgcmd_state +dbgcmd_disable(mrb_state *mrb, mrdb_state *mrdb) +{ + mrb_bool ret = FALSE; + + ret = exe_set_command_all(mrb, mrdb, mrb_debug_disable_break_all); + if (ret != TRUE) { + exe_set_command_select(mrb, mrdb, mrb_debug_disable_break); + } + return DBGST_PROMPT; +} diff --git a/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-bin-debugger/tools/mrdb/cmdmisc.c b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-bin-debugger/tools/mrdb/cmdmisc.c new file mode 100644 index 00000000..5984b623 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-bin-debugger/tools/mrdb/cmdmisc.c @@ -0,0 +1,501 @@ +/* +** cmdmisc.c - mruby debugger miscellaneous command functions +** +*/ + +#include +#include +#include + +#include "apilist.h" +#include + +typedef struct help_msg { + const char *cmd1; + const char *cmd2; + const char *short_msg; + const char *long_msg; +} help_msg; + +static help_msg help_msg_list[] = { + { + "b[reak]", NULL, "Set breakpoint", + "Usage: break [file:]line\n" + " break [class:]method\n" + "\n" + "Set breakpoint at specified line or method.\n" + "If \'[file:]line\' is specified, break at start of code for that line (in a file).\n" + "If \'[class:]method\' is specified, break at start of code for that method (of the class).\n" + }, + { + "c[ontinue]", NULL, "Continue program being debugged", + "Usage: continue [N]\n" + "\n" + "Continue program stopped by a breakpoint.\n" + "If N, which is non negative value, is passed,\n" + "proceed program until the N-th breakpoint is coming.\n" + "If N is not passed, N is assumed 1.\n" + }, + { + "d[elete]", NULL, "Delete some breakpoints", + "Usage: delete [bpno1 [bpno2 [... [bpnoN]]]]\n" + "\n" + "Delete some breakpoints.\n" + "Arguments are breakpoint numbers with spaces in between.\n" + "To delete all breakpoints, give no argument.\n" + }, + { + "dis[able]", NULL, "Disable some breakpoints", + "Usage: disable [bpno1 [bpno2 [... [bpnoN]]]]\n" + "\n" + "Disable some breakpoints.\n" + "Arguments are breakpoint numbers with spaces in between.\n" + "To disable all breakpoints, give no argument.\n" + }, + { + "en[able]", NULL, "Enable some breakpoints", + "Usage: enable [bpno1 [bpno2 [... [bpnoN]]]]\n" + "\n" + "Enable some breakpoints.\n" + "Arguments are breakpoint numbers with spaces in between.\n" + "To enable all breakpoints, give no argument.\n" + }, + { + "ev[al]", NULL, "Evaluate expression", + "Usage: eval expr\n" + "\n" + "It evaluates and prints the value of the mruby expression.\n" + "This is equivalent to the \'print\' command.\n" + }, + { + "h[elp]", NULL, "Print this help", + "Usage: help [command]\n" + "\n" + "With no arguments, help displays a short list of commands.\n" + "With a command name as help argument, help displays how to use that command.\n" + }, + { + "i[nfo]", "b[reakpoints]", "Status of breakpoints", + "Usage: info breakpoints [bpno1 [bpno2 [... [bpnoN]]]]\n" + "\n" + "Status of specified breakpoints (all user-settable breakpoints if no argument).\n" + "Arguments are breakpoint numbers with spaces in between.\n" + }, + { + "l[ist]", NULL, "List specified line", + "Usage: list\n" + " list first[,last]\n" + " list filename:first[,last]\n" + "\n" + "Print lines from a source file.\n" + "\n" + "With first and last, list prints lines from first to last.\n" + "When last is empty, it stands for ten lines away from first.\n" + "With filename, list prints lines in the specified source file.\n" + }, + { + "p[rint]", NULL, "Print value of expression", + "Usage: print expr\n" + "\n" + "It evaluates and prints the value of the mruby expression.\n" + "This is equivalent to the \'eval\' command.\n" + }, + { + "q[uit]", NULL, "Exit mrdb", + "Usage: quit\n" + "\n" + "Exit mrdb.\n" + }, + { + "r[un]", NULL, "Start debugged program", + "Usage: run\n" + "\n" + "Start debugged program.\n" + }, + { + "s[tep]", NULL, "Step program until it reaches a different source line", + "Usage: step\n" + "\n" + "Step program until it reaches a different source line.\n" + }, + { NULL, NULL, NULL, NULL } +}; + +typedef struct listcmd_parser_state { + mrb_bool parse_error; + mrb_bool has_line_min; + mrb_bool has_line_max; + char *filename; + uint16_t line_min; + uint16_t line_max; +} listcmd_parser_state; + +static listcmd_parser_state* +listcmd_parser_state_new(mrb_state *mrb) +{ + listcmd_parser_state *st = mrb_malloc(mrb, sizeof(listcmd_parser_state)); + memset(st, 0, sizeof(listcmd_parser_state)); + return st; +} + +static void +listcmd_parser_state_free(mrb_state *mrb, listcmd_parser_state *st) +{ + if (st != NULL) { + if (st->filename != NULL) { + mrb_free(mrb, st->filename); + } + mrb_free(mrb, st); + } +} + +static mrb_bool +parse_uint(char **sp, uint16_t *n) +{ + char *p; + int i; + + if (*sp == NULL || **sp == '\0') { + return FALSE; + } + + for (p = *sp; *p != '\0' && ISDIGIT(*p); p++) ; + + if (p != *sp && (i = atoi(*sp)) >= 0) { + *n = (uint16_t)i; + *sp = p; + return TRUE; + } + return FALSE; +} + +static mrb_bool +skip_char(char **sp, char c) +{ + if (*sp != NULL && **sp == c) { + ++*sp; + return TRUE; + } + return FALSE; +} + +static mrb_bool +parse_lineno(mrb_state *mrb, char **sp, listcmd_parser_state *st) +{ + if (*sp == NULL || **sp == '\0') { + return FALSE; + } + + st->has_line_min = FALSE; + st->has_line_max = FALSE; + + if (parse_uint(sp, &st->line_min)) { + st->has_line_min = TRUE; + } + else { + return FALSE; + } + + if (skip_char(sp, ',')) { + if (parse_uint(sp, &st->line_max)) { + st->has_line_max = TRUE; + } + else { + st->parse_error = TRUE; + return FALSE; + } + } + return TRUE; +} + +static mrb_bool +parse_filename(mrb_state *mrb, char **sp, listcmd_parser_state *st) +{ + char *p; + int len; + + if (st->filename != NULL) { + mrb_free(mrb, st->filename); + st->filename = NULL; + } + + if ((p = strchr(*sp, ':')) != NULL) { + len = p - *sp; + } + else { + len = strlen(*sp); + } + + if (len > 0) { + st->filename = mrb_malloc(mrb, len + 1); + strncpy(st->filename, *sp, len); + st->filename[len] = '\0'; + *sp += len; + return TRUE; + } + else { + return FALSE; + } +} + +char* +replace_ext(mrb_state *mrb, const char *filename, const char *ext) +{ + size_t len; + char *p, *s; + + if (filename == NULL) { + return NULL; + } + + if ((p = strrchr(filename, '.')) != NULL && strchr(p, '/') == NULL) { + len = p - filename; + } + else { + len = strlen(filename); + } + + s = mrb_malloc(mrb, len + strlen(ext) + 1); + memset(s, '\0', len + strlen(ext) + 1); + strncpy(s, filename, len); + strcat(s, ext); + + return s; +} + +static mrb_bool +parse_listcmd_args(mrb_state *mrb, mrdb_state *mrdb, listcmd_parser_state *st) +{ + char *p; + + switch (mrdb->wcnt) { + case 2: + p = mrdb->words[1]; + + /* mrdb->words[1] ::= | ':' | */ + if (!parse_lineno(mrb, &p, st)) { + if (parse_filename(mrb, &p, st)) { + if (skip_char(&p, ':')) { + if (!parse_lineno(mrb, &p, st)) { + st->parse_error = TRUE; + } + } + } + else { + st->parse_error = TRUE; + } + } + if (*p != '\0') { + st->parse_error = TRUE; + } + break; + case 1: + case 0: + /* do nothing */ + break; + default: + st->parse_error = TRUE; + printf("too many arguments\n"); + break; + } + + if (!st->parse_error) { + if (!st->has_line_min) { + st->line_min = (!st->filename && mrdb->dbg->prvline > 0) ? mrdb->dbg->prvline : 1; + } + + if (!st->has_line_max) { + st->line_max = st->line_min + 9; + } + + if (st->filename == NULL) { + if (mrdb->dbg->prvfile && strcmp(mrdb->dbg->prvfile, "-")) { + st->filename = replace_ext(mrb, mrdb->dbg->prvfile, ".rb"); + } + } + } + + if (st->parse_error || st->filename == NULL) { + return FALSE; + } + + return TRUE; +} + +static mrb_bool +check_cmd_pattern(const char *pattern, const char *cmd) +{ + char *lbracket, *rbracket, *p, *q; + + if (pattern == NULL && cmd == NULL) { + return TRUE; + } + if (pattern == NULL || cmd == NULL) { + return FALSE; + } + if ((lbracket = strchr(pattern, '[')) == NULL) { + return !strcmp(pattern, cmd); + } + if ((rbracket = strchr(pattern, ']')) == NULL) { + return FALSE; + } + if (strncmp(pattern, cmd, lbracket - pattern)) { + return FALSE; + } + + p = lbracket + 1; + q = (char *)cmd + (lbracket - pattern); + + for ( ; p < rbracket && *q != '\0'; p++, q++) { + if (*p != *q) { + break; + } + } + return *q == '\0'; +} + +static help_msg* +get_help_msg(char *cmd1, char *cmd2) +{ + help_msg *p; + + if (cmd1 == NULL) { + return NULL; + } + for (p = help_msg_list; p->cmd1 != NULL; p++) { + if (check_cmd_pattern(p->cmd1, cmd1) && check_cmd_pattern(p->cmd2, cmd2)) { + return p; + } + } + return NULL; +} + +static mrb_bool +show_short_help(void) +{ + help_msg *p; + + printf("Commands\n"); + + for (p = help_msg_list; p->cmd1 != NULL; p++) { + if (p->cmd2 == NULL) { + printf(" %s -- %s\n", p->cmd1, p->short_msg); + } + else { + printf(" %s %s -- %s\n", p->cmd1, p->cmd2, p->short_msg); + } + } + return TRUE; +} + +static mrb_bool +show_long_help(char *cmd1, char *cmd2) +{ + help_msg *help; + + if ((help = get_help_msg(cmd1, cmd2)) == NULL) { + return FALSE; + } + printf("%s", help->long_msg); + return TRUE; +} + +dbgcmd_state +dbgcmd_list(mrb_state *mrb, mrdb_state *mrdb) +{ + char *filename; + listcmd_parser_state *st = listcmd_parser_state_new(mrb); + + if (parse_listcmd_args(mrb, mrdb, st)) { + if ((filename = mrb_debug_get_source(mrb, mrdb, mrdb->srcpath, st->filename)) == NULL) { + filename = st->filename; + } + mrb_debug_list(mrb, mrdb->dbg, filename, st->line_min, st->line_max); + + if (filename != NULL && filename != st->filename) { + mrb_free(mrb, filename); + } + listcmd_parser_state_free(mrb, st); + } + + return DBGST_PROMPT; +} + +dbgcmd_state +dbgcmd_help(mrb_state *mrb, mrdb_state *mrdb) +{ + mrb_bool is_valid; + int i; + + switch (mrdb->wcnt) { + case 0: + case 1: + is_valid = show_short_help(); + break; + case 2: + is_valid = show_long_help(mrdb->words[1], NULL); + break; + case 3: + is_valid = show_long_help(mrdb->words[1], mrdb->words[2]); + break; + default: + is_valid = FALSE; + break; + } + + if (!is_valid) { + printf("Invalid command \""); + for (i = 1; i < mrdb->wcnt; i++) { + printf("%s%s", i == 1 ? "" : " ", mrdb->words[i]); + } + printf("\". Try \"help\".\n"); + } + + return DBGST_PROMPT; +} + +dbgcmd_state +dbgcmd_quit(mrb_state *mrb, mrdb_state *mrdb) +{ + switch (mrdb->dbg->xm) { + case DBG_RUN: + case DBG_STEP: + case DBG_NEXT: + while (1) { + char c; + int buf; + + printf("The program is running. Exit anyway? (y or n) "); + fflush(stdout); + + if ((buf = getchar()) == EOF) { + mrdb->dbg->xm = DBG_QUIT; + break; + } + c = buf; + while (buf != '\n' && (buf = getchar()) != EOF) ; + + if (c == 'y' || c == 'Y') { + mrdb->dbg->xm = DBG_QUIT; + break; + } + else if (c == 'n' || c == 'N') { + break; + } + else { + printf("Please answer y or n.\n"); + } + } + break; + default: + mrdb->dbg->xm = DBG_QUIT; + break; + } + + if (mrdb->dbg->xm == DBG_QUIT) { + struct RClass *exc; + exc = mrb_define_class(mrb, "DebuggerExit", mrb_class_get(mrb, "Exception")); + mrb_raise(mrb, exc, "Exit mrdb."); + } + return DBGST_PROMPT; +} diff --git a/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-bin-debugger/tools/mrdb/cmdprint.c b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-bin-debugger/tools/mrdb/cmdprint.c new file mode 100644 index 00000000..cca63671 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-bin-debugger/tools/mrdb/cmdprint.c @@ -0,0 +1,58 @@ +/* +** cmdprint.c - mruby debugger print command functions +** +*/ + +#include +#include "mrdb.h" +#include +#include +#include +#include +#include +#include +#include "apiprint.h" + +dbgcmd_state +dbgcmd_print(mrb_state *mrb, mrdb_state *mrdb) +{ + mrb_value expr; + mrb_value result; + mrb_value s; + uint8_t wcnt; + int ai; + + if (mrdb->wcnt <= 1) { + puts("Parameter not specified."); + return DBGST_PROMPT; + } + + ai = mrb_gc_arena_save(mrb); + + /* eval expr */ + expr = mrb_str_new_cstr(mrb, NULL); + for (wcnt=1; wcntwcnt; wcnt++) { + expr = mrb_str_cat_lit(mrb, expr, " "); + expr = mrb_str_cat_cstr(mrb, expr, mrdb->words[wcnt]); + } + + result = mrb_debug_eval(mrb, mrdb->dbg, RSTRING_PTR(expr), RSTRING_LEN(expr), NULL); + + /* $print_no = result */ + s = mrb_str_cat_lit(mrb, result, "\0"); + printf("$%lu = %s\n", (unsigned long)mrdb->print_no++, RSTRING_PTR(s)); + + if (mrdb->print_no == 0) { + mrdb->print_no = 1; + } + + mrb_gc_arena_restore(mrb, ai); + + return DBGST_PROMPT; +} + +dbgcmd_state +dbgcmd_eval(mrb_state *mrb, mrdb_state *mrdb) +{ + return dbgcmd_print(mrb, mrdb); +} diff --git a/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-bin-debugger/tools/mrdb/cmdrun.c b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-bin-debugger/tools/mrdb/cmdrun.c new file mode 100644 index 00000000..cb4c738f --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-bin-debugger/tools/mrdb/cmdrun.c @@ -0,0 +1,64 @@ +/* +** cmdrun.c - mruby debugger run command functions +** +*/ + +#include +#include "mrdb.h" + +dbgcmd_state +dbgcmd_run(mrb_state *mrb, mrdb_state *mrdb) +{ + mrb_debug_context *dbg = mrdb->dbg; + + if (dbg->xm == DBG_INIT){ + dbg->xm = DBG_RUN; + } + else { + dbg->xm = DBG_QUIT; + if (dbg->xphase == DBG_PHASE_RUNNING){ + struct RClass *exc; + puts("Start it from the beginning."); + exc = mrb_define_class(mrb, "DebuggerRestart", mrb_class_get(mrb, "Exception")); + mrb_raise(mrb, exc, "Restart mrdb."); + } + } + + return DBGST_RESTART; +} + +dbgcmd_state +dbgcmd_continue(mrb_state *mrb, mrdb_state *mrdb) +{ + mrb_debug_context *dbg = mrdb->dbg; + int ccnt = 1; + + if (mrdb->wcnt > 1){ + sscanf(mrdb->words[1], "%d", &ccnt); + } + dbg->ccnt = (uint16_t)(ccnt > 0 ? ccnt : 1); /* count of continue */ + + if (dbg->xphase == DBG_PHASE_AFTER_RUN){ + puts("The program is not running."); + dbg->xm = DBG_QUIT; + } + else { + dbg->xm = DBG_RUN; + } + return DBGST_CONTINUE; +} + +dbgcmd_state +dbgcmd_step(mrb_state *mrb, mrdb_state *mrdb) +{ + mrdb->dbg->xm = DBG_STEP; + return DBGST_CONTINUE; +} + +dbgcmd_state +dbgcmd_next(mrb_state *mrb, mrdb_state *mrdb) +{ + mrdb->dbg->xm = DBG_NEXT; + mrdb->dbg->prvci = mrb->c->ci; + return DBGST_CONTINUE; +} diff --git a/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-bin-debugger/tools/mrdb/mrdb.c b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-bin-debugger/tools/mrdb/mrdb.c new file mode 100644 index 00000000..d12dcd5d --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-bin-debugger/tools/mrdb/mrdb.c @@ -0,0 +1,759 @@ +/* +** mrdb.c - mruby debugger +** +*/ + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include "mrdb.h" +#include "apibreak.h" +#include "apilist.h" + +void mrdb_state_free(mrb_state *); + +static mrb_debug_context *_debug_context = NULL; +static mrdb_state *_mrdb_state = NULL; + +struct _args { + FILE *rfp; + char* fname; + char* srcpath; + int argc; + char** argv; + mrb_bool mrbfile : 1; +}; + +typedef struct debug_command { + const char *cmd1; + const char *cmd2; + uint8_t len1; + uint8_t len2; + uint8_t div; + debug_command_id id; + debug_command_func func; +} debug_command; + +static const debug_command debug_command_list[] = { + {"break", NULL, 1, 0, 0, DBGCMD_BREAK, dbgcmd_break}, /* b[reak] */ + {"continue", NULL, 1, 0, 0, DBGCMD_CONTINUE, dbgcmd_continue}, /* c[ontinue] */ + {"delete", NULL, 1, 0, 1, DBGCMD_DELETE, dbgcmd_delete}, /* d[elete] */ + {"disable", NULL, 3, 0, 1, DBGCMD_DISABLE, dbgcmd_disable}, /* dis[able] */ + {"enable", NULL, 2, 0, 1, DBGCMD_ENABLE, dbgcmd_enable}, /* en[able] */ + {"eval", NULL, 2, 0, 0, DBGCMD_EVAL, dbgcmd_eval}, /* ev[al] */ + {"help", NULL, 1, 0, 1, DBGCMD_HELP, dbgcmd_help}, /* h[elp] */ + {"info", "breakpoints", 1, 1, 1, DBGCMD_INFO_BREAK, dbgcmd_info_break}, /* i[nfo] b[reakpoints] */ + {"list", NULL, 1, 0, 1, DBGCMD_LIST, dbgcmd_list}, /* l[ist] */ + {"print", NULL, 1, 0, 0, DBGCMD_PRINT, dbgcmd_print}, /* p[rint] */ + {"quit", NULL, 1, 0, 0, DBGCMD_QUIT, dbgcmd_quit}, /* q[uit] */ + {"run", NULL, 1, 0, 0, DBGCMD_RUN, dbgcmd_run}, /* r[un] */ + {"step", NULL, 1, 0, 1, DBGCMD_STEP, dbgcmd_step}, /* s[tep] */ + {"next", NULL, 1, 0, 1, DBGCMD_NEXT, dbgcmd_next}, /* n[ext] */ + {NULL} +}; + + +static void +usage(const char *name) +{ + static const char *const usage_msg[] = { + "switches:", + "-b load and execute RiteBinary (mrb) file", + "-d specify source directory", + "--version print the version", + "--copyright print the copyright", + NULL + }; + const char *const *p = usage_msg; + + printf("Usage: %s [switches] programfile\n", name); + while (*p) { + printf(" %s\n", *p++); + } +} + +static int +parse_args(mrb_state *mrb, int argc, char **argv, struct _args *args) +{ + char **origargv = argv; + static const struct _args args_zero = { 0 }; + + *args = args_zero; + + for (argc--,argv++; argc > 0; argc--,argv++) { + char *item; + if (argv[0][0] != '-') break; + + item = argv[0] + 1; + switch (*item++) { + case 'b': + args->mrbfile = TRUE; + break; + case 'd': + if (item[0]) { + goto append_srcpath; + } + else if (argc > 1) { + argc--; argv++; + item = argv[0]; +append_srcpath: + if (!args->srcpath) { + size_t buflen; + char *buf; + + buflen = strlen(item) + 1; + buf = (char *)mrb_malloc(mrb, buflen); + memcpy(buf, item, buflen); + args->srcpath = buf; + } + else { + size_t srcpathlen; + size_t itemlen; + + srcpathlen = strlen(args->srcpath); + itemlen = strlen(item); + args->srcpath = + (char *)mrb_realloc(mrb, args->srcpath, srcpathlen + itemlen + 2); + args->srcpath[srcpathlen] = '\n'; + memcpy(args->srcpath + srcpathlen + 1, item, itemlen + 1); + } + } + else { + printf("%s: No path specified for -d\n", *origargv); + return EXIT_SUCCESS; + } + break; + case '-': + if (strcmp((*argv) + 2, "version") == 0) { + mrb_show_version(mrb); + exit(EXIT_SUCCESS); + } + else if (strcmp((*argv) + 2, "copyright") == 0) { + mrb_show_copyright(mrb); + exit(EXIT_SUCCESS); + } + default: + return EXIT_FAILURE; + } + } + + if (args->rfp == NULL) { + if (*argv == NULL) { + printf("%s: Program file not specified.\n", *origargv); + return EXIT_FAILURE; + } + else { + args->rfp = fopen(argv[0], args->mrbfile ? "rb" : "r"); + if (args->rfp == NULL) { + printf("%s: Cannot open program file. (%s)\n", *origargv, *argv); + return EXIT_FAILURE; + } + args->fname = argv[0]; + argc--; argv++; + } + } + args->argv = (char **)mrb_realloc(mrb, args->argv, sizeof(char*) * (argc + 1)); + memcpy(args->argv, argv, (argc+1) * sizeof(char*)); + args->argc = argc; + + return EXIT_SUCCESS; +} + +static void +cleanup(mrb_state *mrb, struct _args *args) +{ + if (args->rfp) + fclose(args->rfp); + if (args->srcpath) + mrb_free(mrb, args->srcpath); + if (args->argv) + mrb_free(mrb, args->argv); + mrdb_state_free(mrb); + mrb_close(mrb); +} + +static mrb_debug_context* +mrb_debug_context_new(mrb_state *mrb) +{ + mrb_debug_context *dbg = mrb_malloc(mrb, sizeof(mrb_debug_context)); + + memset(dbg, 0, sizeof(mrb_debug_context)); + + dbg->xm = DBG_INIT; + dbg->xphase = DBG_PHASE_BEFORE_RUN; + dbg->next_bpno = 1; + + return dbg; +} + +mrb_debug_context* +mrb_debug_context_get(mrb_state *mrb) +{ + if (!_debug_context) { + _debug_context = mrb_debug_context_new(mrb); + } + return _debug_context; +} + +void +mrb_debug_context_set(mrb_debug_context *dbg) +{ + _debug_context = dbg; +} + +void +mrb_debug_context_free(mrb_state *mrb) +{ + if (_debug_context) { + mrb_debug_delete_break_all(mrb, _debug_context); + mrb_free(mrb, _debug_context); + _debug_context = NULL; + } +} + +static mrdb_state* +mrdb_state_new(mrb_state *mrb) +{ + mrdb_state *mrdb = mrb_malloc(mrb, sizeof(mrdb_state)); + + memset(mrdb, 0, sizeof(mrdb_state)); + + mrdb->dbg = mrb_debug_context_get(mrb); + mrdb->command = mrb_malloc(mrb, MAX_COMMAND_LINE+1); + mrdb->print_no = 1; + + return mrdb; +} + +mrdb_state* +mrdb_state_get(mrb_state *mrb) +{ + if (!_mrdb_state) { + _mrdb_state = mrdb_state_new(mrb); + } + return _mrdb_state; +} + +void +mrdb_state_set(mrdb_state *mrdb) +{ + _mrdb_state = mrdb; +} + +void +mrdb_state_free(mrb_state *mrb) +{ + mrb_debug_context_free(mrb); + if (_mrdb_state) { + mrb_free(mrb, _mrdb_state->command); + mrb_free(mrb, _mrdb_state); + _mrdb_state = NULL; + } +} + +static char* +get_command(mrb_state *mrb, mrdb_state *mrdb) +{ + int i; + int c; + + for (i=0; icommand[i] = c; + } + + if (i == 0 && feof(stdin)) { + clearerr(stdin); + strcpy(mrdb->command, "quit"); + i += sizeof("quit") - 1; + } + + if (i == MAX_COMMAND_LINE) { + for ( ; (c=getchar()) != EOF && c !='\n'; i++) ; + } + + if (i > MAX_COMMAND_LINE) { + printf("command line too long.\n"); + i = 0; /* discard command data */ + } + mrdb->command[i] = '\0'; + + return mrdb->command; +} + +static char* +pick_out_word(mrb_state *mrb, char **pp) +{ + char *ps; + + for (ps=*pp; ISBLANK(*ps); ps++) ; + if (*ps == '\0') { + return NULL; + } + + if (*ps == '\"' || *ps == '\'') { + *pp = strchr(ps+1, *ps); + if (*pp) (*pp)++; + } + else { + *pp = strpbrk(ps, " \t"); + } + + if (!*pp) { + *pp = ps + strlen(ps); + } + + if (**pp != '\0') { + **pp = '\0'; + (*pp)++; + } + + return ps; +} + +static debug_command* +parse_command(mrb_state *mrb, mrdb_state *mrdb, char *buf) +{ + debug_command *cmd = NULL; + char *p = buf; + size_t wlen; + + /* get word #1 */ + mrdb->words[0] = pick_out_word(mrb, &p); + if (!mrdb->words[0]) { + return NULL; + } + mrdb->wcnt = 1; + /* set remain parameter */ + for ( ; *p && ISBLANK(*p); p++) ; + if (*p) { + mrdb->words[mrdb->wcnt++] = p; + } + + /* check word #1 */ + for (cmd=(debug_command*)debug_command_list; cmd->cmd1; cmd++) { + wlen = strlen(mrdb->words[0]); + if (wlen >= cmd->len1 && + strncmp(mrdb->words[0], cmd->cmd1, wlen) == 0) { + break; + } + } + + if (cmd->cmd2) { + if (mrdb->wcnt > 1) { + /* get word #2 */ + mrdb->words[1] = pick_out_word(mrb, &p); + if (mrdb->words[1]) { + /* update remain parameter */ + for ( ; *p && ISBLANK(*p); p++) ; + if (*p) { + mrdb->words[mrdb->wcnt++] = p; + } + } + } + + /* check word #1,#2 */ + for ( ; cmd->cmd1; cmd++) { + wlen = strlen(mrdb->words[0]); + if (wlen < cmd->len1 || + strncmp(mrdb->words[0], cmd->cmd1, wlen)) { + continue; + } + + if (!cmd->cmd2) break; /* word #1 only */ + + if (mrdb->wcnt == 1) continue; /* word #2 not specified */ + + wlen = strlen(mrdb->words[1]); + if (wlen >= cmd->len2 && + strncmp(mrdb->words[1], cmd->cmd2, wlen) == 0) { + break; /* word #1 and #2 */ + } + } + } + + /* divide remain parameters */ + if (cmd->cmd1 && cmd->div) { + p = mrdb->words[--mrdb->wcnt]; + for ( ; mrdb->wcntwcnt++) { + mrdb->words[mrdb->wcnt] = pick_out_word(mrb, &p); + if (!mrdb->words[mrdb->wcnt]) { + break; + } + } + } + + return cmd->cmd1 ? cmd : NULL; +} + +static void +print_info_stopped_break(mrb_state *mrb, mrdb_state *mrdb) +{ + mrb_debug_breakpoint bp; + int32_t ret; + uint16_t lineno; + const char *file; + const char *method_name; + const char *class_name; + + ret = mrb_debug_get_break(mrb, mrdb->dbg, mrdb->dbg->stopped_bpno, &bp); + if (ret == 0) { + switch(bp.type) { + case MRB_DEBUG_BPTYPE_LINE: + file = bp.point.linepoint.file; + lineno = bp.point.linepoint.lineno; + printf("Breakpoint %d, at %s:%d\n", bp.bpno, file, lineno); + break; + case MRB_DEBUG_BPTYPE_METHOD: + method_name = bp.point.methodpoint.method_name; + class_name = bp.point.methodpoint.class_name; + if (class_name == NULL) { + printf("Breakpoint %d, %s\n", bp.bpno, method_name); + } + else { + printf("Breakpoint %d, %s:%s\n", bp.bpno, class_name, method_name); + } + if (mrdb->dbg->isCfunc) { + printf("Stopped before calling the C function.\n"); + } + break; + default: + break; + } + } +} + +static void +print_info_stopped_step_next(mrb_state *mrb, mrdb_state *mrdb) +{ + const char* file = mrdb->dbg->prvfile; + uint16_t lineno = mrdb->dbg->prvline; + printf("%s:%d\n", file, lineno); +} + +static void +print_info_stopped_code(mrb_state *mrb, mrdb_state *mrdb) +{ + char* file = mrb_debug_get_source(mrb, mrdb, mrdb->srcpath, mrdb->dbg->prvfile); + uint16_t lineno = mrdb->dbg->prvline; + if (file != NULL) { + mrb_debug_list(mrb, mrdb->dbg, file, lineno, lineno); + mrb_free(mrb, file); + } +} + +static void +print_info_stopped(mrb_state *mrb, mrdb_state *mrdb) +{ + switch(mrdb->dbg->bm) { + case BRK_BREAK: + print_info_stopped_break(mrb, mrdb); + print_info_stopped_code(mrb, mrdb); + break; + case BRK_STEP: + case BRK_NEXT: + print_info_stopped_step_next(mrb, mrdb); + print_info_stopped_code(mrb, mrdb); + break; + default: + break; + } +} + +static debug_command* +get_and_parse_command(mrb_state *mrb, mrdb_state *mrdb) +{ + debug_command *cmd = NULL; + char *p; + int i; + + while (!cmd) { + for (p=NULL; !p || *p=='\0'; ) { + printf("(%s:%d) ", mrdb->dbg->prvfile, mrdb->dbg->prvline); + fflush(stdout); + p = get_command(mrb, mrdb); + } + + cmd = parse_command(mrb, mrdb, p); +#ifdef _DBG_MRDB_PARSER_ + for (i=0; iwcnt; i++) { + printf("%d: %s\n", i, mrdb->words[i]); + } +#endif + if (!cmd) { + printf("invalid command ("); + for (i=0; iwcnt; i++) { + if (i>0) { + printf(" "); + } + printf("%s", mrdb->words[i]); + } + puts(")"); + } + } + return cmd; +} + +static int32_t +check_method_breakpoint(mrb_state *mrb, mrb_irep *irep, mrb_code *pc, mrb_value *regs) +{ + struct RClass* c; + mrb_sym sym; + int32_t bpno; + mrb_bool isCfunc; + + mrb_debug_context *dbg = mrb_debug_context_get(mrb); + + isCfunc = FALSE; + bpno = dbg->method_bpno; + dbg->method_bpno = 0; + + switch(GET_OPCODE(*pc)) { + case OP_SEND: + case OP_SENDB: + c = mrb_class(mrb, regs[GETARG_A(*pc)]); + sym = irep->syms[GETARG_B(*pc)]; + break; + case OP_SUPER: + c = mrb->c->ci->target_class->super; + sym = mrb->c->ci->mid; + break; + default: + sym = 0; + break; + } + if (sym != 0) { + dbg->method_bpno = mrb_debug_check_breakpoint_method(mrb, dbg, c, sym, &isCfunc); + if (isCfunc) { + bpno = dbg->method_bpno; + dbg->method_bpno = 0; + } + } + dbg->isCfunc = isCfunc; + return bpno; +} + +static void +mrb_code_fetch_hook(mrb_state *mrb, mrb_irep *irep, mrb_code *pc, mrb_value *regs) +{ + const char *file; + int32_t line; + int32_t bpno; + + mrb_debug_context *dbg = mrb_debug_context_get(mrb); + + mrb_assert(dbg); + + dbg->irep = irep; + dbg->pc = pc; + dbg->regs = regs; + + if (dbg->xphase == DBG_PHASE_RESTART) { + dbg->root_irep = irep; + dbg->prvfile = NULL; + dbg->prvline = 0; + dbg->prvci = NULL; + dbg->xm = DBG_RUN; + dbg->xphase = DBG_PHASE_RUNNING; + } + + file = mrb_debug_get_filename(irep, pc - irep->iseq); + line = mrb_debug_get_line(irep, pc - irep->iseq); + + switch (dbg->xm) { + case DBG_STEP: + if (!file || (dbg->prvfile == file && dbg->prvline == line)) { + return; + } + dbg->method_bpno = 0; + dbg->bm = BRK_STEP; + break; + + case DBG_NEXT: + if (!file || (dbg->prvfile == file && dbg->prvline == line)) { + return; + } + if ((intptr_t)(dbg->prvci) < (intptr_t)(mrb->c->ci)) { + return; + } + dbg->prvci = NULL; + dbg->method_bpno = 0; + dbg->bm = BRK_NEXT; + break; + + case DBG_RUN: + bpno = check_method_breakpoint(mrb, irep, pc, regs); + if (bpno > 0) { + dbg->stopped_bpno = bpno; + dbg->bm = BRK_BREAK; + break; + } + if (dbg->prvfile != file || dbg->prvline != line) { + bpno = mrb_debug_check_breakpoint_line(mrb, dbg, file, line); + if (bpno > 0) { + dbg->stopped_bpno = bpno; + dbg->bm = BRK_BREAK; + break; + } + } + dbg->prvfile = file; + dbg->prvline = line; + return; + case DBG_INIT: + dbg->root_irep = irep; + dbg->bm = BRK_INIT; + if (!file || line < 0) { + puts("Cannot get debugging information."); + } + break; + + default: + return; + } + + dbg->prvfile = file; + dbg->prvline = line; + + if (dbg->bm == BRK_BREAK && --dbg->ccnt > 0) { + return; + } + dbg->break_hook(mrb, dbg); + + dbg->xphase = DBG_PHASE_RUNNING; +} + +static mrdb_exemode +mrb_debug_break_hook(mrb_state *mrb, mrb_debug_context *dbg) +{ + debug_command *cmd; + dbgcmd_state st = DBGST_CONTINUE; + mrdb_state *mrdb = mrdb_state_get(mrb); + + print_info_stopped(mrb, mrdb); + + while (1) { + cmd = get_and_parse_command(mrb, mrdb); + mrb_assert(cmd); + + st = cmd->func(mrb, mrdb); + + if ((st == DBGST_CONTINUE) || (st == DBGST_RESTART)) break; + } + return dbg->xm; +} + +int +main(int argc, char **argv) +{ + mrb_state *mrb = mrb_open(); + int n = -1; + struct _args args; + mrb_value v; + mrdb_state *mrdb; + mrdb_state *mrdb_backup; + mrb_debug_context* dbg_backup; + debug_command *cmd; + + l_restart: + + if (mrb == NULL) { + fputs("Invalid mrb_state, exiting mruby\n", stderr); + return EXIT_FAILURE; + } + + /* parse command parameters */ + n = parse_args(mrb, argc, argv, &args); + if (n == EXIT_FAILURE || args.rfp == NULL) { + cleanup(mrb, &args); + usage(argv[0]); + return n; + } + + /* initialize debugger information */ + mrdb = mrdb_state_get(mrb); + mrb_assert(mrdb && mrdb->dbg); + mrdb->srcpath = args.srcpath; + + if (mrdb->dbg->xm == DBG_QUIT) { + mrdb->dbg->xphase = DBG_PHASE_RESTART; + } + else { + mrdb->dbg->xphase = DBG_PHASE_BEFORE_RUN; + } + mrdb->dbg->xm = DBG_INIT; + mrdb->dbg->ccnt = 1; + + /* setup hook functions */ + mrb->code_fetch_hook = mrb_code_fetch_hook; + mrdb->dbg->break_hook = mrb_debug_break_hook; + + if (args.mrbfile) { /* .mrb */ + v = mrb_load_irep_file(mrb, args.rfp); + } + else { /* .rb */ + mrbc_context *cc = mrbc_context_new(mrb); + mrbc_filename(mrb, cc, args.fname); + v = mrb_load_file_cxt(mrb, args.rfp, cc); + mrbc_context_free(mrb, cc); + } + if (mrdb->dbg->xm == DBG_QUIT && !mrb_undef_p(v) && mrb->exc) { + const char *classname = mrb_obj_classname(mrb, mrb_obj_value(mrb->exc)); + if (!strcmp(classname, "DebuggerExit")) { + cleanup(mrb, &args); + return 0; + } + if (!strcmp(classname, "DebuggerRestart")) { + mrdb_backup = mrdb_state_get(mrb); + dbg_backup = mrb_debug_context_get(mrb); + + mrdb_state_set(NULL); + mrb_debug_context_set(NULL); + + cleanup(mrb, &args); + mrb = mrb_open(); + + mrdb_state_set(mrdb_backup); + mrb_debug_context_set(dbg_backup); + + goto l_restart; + } + } + puts("mruby application exited."); + mrdb->dbg->xphase = DBG_PHASE_AFTER_RUN; + if (!mrb_undef_p(v)) { + if (mrb->exc) { + mrb_print_error(mrb); + } + else { + printf(" => "); + mrb_p(mrb, v); + } + } + + mrdb->dbg->prvfile = "-"; + mrdb->dbg->prvline = 0; + + while (1) { + cmd = get_and_parse_command(mrb, mrdb); + mrb_assert(cmd); + + if (cmd->id == DBGCMD_QUIT) { + break; + } + + if ( cmd->func(mrb, mrdb) == DBGST_RESTART ) goto l_restart; + } + + cleanup(mrb, &args); + + return 0; +} diff --git a/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-bin-debugger/tools/mrdb/mrdb.h b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-bin-debugger/tools/mrdb/mrdb.h new file mode 100644 index 00000000..5ac12c1c --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-bin-debugger/tools/mrdb/mrdb.h @@ -0,0 +1,165 @@ +/* +** mrdb.h - mruby debugger +** +*/ + +#ifndef MRDB_H +#define MRDB_H + +#include + +#include "mrdbconf.h" + +#ifdef _MSC_VER +# define __func__ __FUNCTION__ +#endif + +#define MAX_COMMAND_WORD (16) + +typedef enum debug_command_id { + DBGCMD_RUN, + DBGCMD_CONTINUE, + DBGCMD_NEXT, + DBGCMD_STEP, + DBGCMD_BREAK, + DBGCMD_INFO_BREAK, + DBGCMD_WATCH, + DBGCMD_INFO_WATCH, + DBGCMD_ENABLE, + DBGCMD_DISABLE, + DBGCMD_DELETE, + DBGCMD_PRINT, + DBGCMD_DISPLAY, + DBGCMD_INFO_DISPLAY, + DBGCMD_DELETE_DISPLAY, + DBGCMD_EVAL, + DBGCMD_BACKTRACE, + DBGCMD_LIST, + DBGCMD_HELP, + DBGCMD_QUIT, + DBGCMD_UNKNOWN +} debug_command_id; + +typedef enum dbgcmd_state { + DBGST_CONTINUE, + DBGST_PROMPT, + DBGST_COMMAND_ERROR, + DBGST_MAX, + DBGST_RESTART +} dbgcmd_state; + +typedef enum mrdb_exemode { + DBG_INIT, + DBG_RUN, + DBG_STEP, + DBG_NEXT, + DBG_QUIT, +} mrdb_exemode; + +typedef enum mrdb_exephase { + DBG_PHASE_BEFORE_RUN, + DBG_PHASE_RUNNING, + DBG_PHASE_AFTER_RUN, + DBG_PHASE_RESTART, +} mrdb_exephase; + +typedef enum mrdb_brkmode { + BRK_INIT, + BRK_BREAK, + BRK_STEP, + BRK_NEXT, + BRK_QUIT, +} mrdb_brkmode; + +typedef enum { + MRB_DEBUG_BPTYPE_NONE, + MRB_DEBUG_BPTYPE_LINE, + MRB_DEBUG_BPTYPE_METHOD, +} mrb_debug_bptype; + +struct mrb_irep; +struct mrbc_context; +struct mrb_debug_context; + +typedef struct mrb_debug_linepoint { + const char *file; + uint16_t lineno; +} mrb_debug_linepoint; + +typedef struct mrb_debug_methodpoint { + const char *class_name; + const char *method_name; +} mrb_debug_methodpoint; + +typedef struct mrb_debug_breakpoint { + uint32_t bpno; + uint8_t enable; + mrb_debug_bptype type; + union point { + mrb_debug_linepoint linepoint; + mrb_debug_methodpoint methodpoint; + } point; +} mrb_debug_breakpoint; + +typedef struct mrb_debug_context { + struct mrb_irep *root_irep; + struct mrb_irep *irep; + mrb_code *pc; + mrb_value *regs; + + const char *prvfile; + int32_t prvline; + mrb_callinfo *prvci; + + mrdb_exemode xm; + mrdb_exephase xphase; + mrdb_brkmode bm; + int16_t bmi; + + uint16_t ccnt; + uint16_t scnt; + + mrb_debug_breakpoint bp[MAX_BREAKPOINT]; + uint32_t bpnum; + int32_t next_bpno; + int32_t method_bpno; + int32_t stopped_bpno; + mrb_bool isCfunc; + + mrdb_exemode (*break_hook)(mrb_state *mrb, struct mrb_debug_context *dbg); + +} mrb_debug_context; + +typedef struct mrdb_state { + char *command; + uint8_t wcnt; + uint8_t pi; + char *words[MAX_COMMAND_WORD]; + const char *srcpath; + uint32_t print_no; + + mrb_debug_context *dbg; +} mrdb_state; + +typedef dbgcmd_state (*debug_command_func)(mrb_state*, mrdb_state*); + +/* cmdrun.c */ +dbgcmd_state dbgcmd_run(mrb_state*, mrdb_state*); +dbgcmd_state dbgcmd_continue(mrb_state*, mrdb_state*); +dbgcmd_state dbgcmd_step(mrb_state*, mrdb_state*); +dbgcmd_state dbgcmd_next(mrb_state*, mrdb_state*); +/* cmdbreak.c */ +dbgcmd_state dbgcmd_break(mrb_state*, mrdb_state*); +dbgcmd_state dbgcmd_info_break(mrb_state*, mrdb_state*); +dbgcmd_state dbgcmd_delete(mrb_state*, mrdb_state*); +dbgcmd_state dbgcmd_enable(mrb_state*, mrdb_state*); +dbgcmd_state dbgcmd_disable(mrb_state*, mrdb_state*); +/* cmdprint.c */ +dbgcmd_state dbgcmd_print(mrb_state*, mrdb_state*); +dbgcmd_state dbgcmd_eval(mrb_state*, mrdb_state*); +/* cmdmisc.c */ +dbgcmd_state dbgcmd_list(mrb_state*, mrdb_state*); +dbgcmd_state dbgcmd_help(mrb_state*, mrdb_state*); +dbgcmd_state dbgcmd_quit(mrb_state*, mrdb_state*); + +#endif diff --git a/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-bin-debugger/tools/mrdb/mrdbconf.h b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-bin-debugger/tools/mrdb/mrdbconf.h new file mode 100644 index 00000000..f17f9c57 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-bin-debugger/tools/mrdb/mrdbconf.h @@ -0,0 +1,16 @@ +/* +** mrdbconf.h - mruby debugger configuration +** +*/ + +#ifndef MRDBCONF_H +#define MRDBCONF_H + +/* configuration options: */ +/* maximum size for command buffer */ +#define MAX_COMMAND_LINE 1024 + +/* maximum number of setable breakpoint */ +#define MAX_BREAKPOINT 5 + +#endif diff --git a/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-bin-debugger/tools/mrdb/mrdberror.h b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-bin-debugger/tools/mrdb/mrdberror.h new file mode 100644 index 00000000..c7812b0d --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-bin-debugger/tools/mrdb/mrdberror.h @@ -0,0 +1,20 @@ +/* +** mrdberror.h - mruby debugger error code +** +*/ + +#ifndef MRDBERROR_H +#define MRDBERROR_H + +#define MRB_DEBUG_OK (0) +#define MRB_DEBUG_NOBUF (-1) +#define MRB_DEBUG_INVALID_ARGUMENT (-2) + +#define MRB_DEBUG_BREAK_INVALID_LINENO (-11) +#define MRB_DEBUG_BREAK_INVALID_FILE (-12) +#define MRB_DEBUG_BREAK_INVALID_NO (-13) +#define MRB_DEBUG_BREAK_NUM_OVER (-14) +#define MRB_DEBUG_BREAK_NO_OVER (-15) + +#endif + diff --git a/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-bin-mirb/bintest/mirb.rb b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-bin-mirb/bintest/mirb.rb new file mode 100644 index 00000000..ed53321b --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-bin-mirb/bintest/mirb.rb @@ -0,0 +1,12 @@ +require 'open3' + +assert('mirb normal operations') do + o, s = Open3.capture2('bin/mirb', :stdin_data => "a=1\nb=2\na+b\n") + assert_true o.include?('=> 3') + assert_true o.include?('=> 2') +end + +assert('regression for #1563') do + o, s = Open3.capture2('bin/mirb', :stdin_data => "a=1;b=2;c=3\nb\nc") + assert_true o.include?('=> 3') +end diff --git a/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-bin-mirb/mrbgem.rake b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-bin-mirb/mrbgem.rake new file mode 100644 index 00000000..a74871d8 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-bin-mirb/mrbgem.rake @@ -0,0 +1,33 @@ +MRuby::Gem::Specification.new('mruby-bin-mirb') do |spec| + spec.license = 'MIT' + spec.author = 'mruby developers' + spec.summary = 'mirb command' + + if spec.build.cc.search_header_path 'readline/readline.h' + spec.cc.defines << "ENABLE_READLINE" + if spec.build.cc.search_header_path 'termcap.h' + if MRUBY_BUILD_HOST_IS_CYGWIN || MRUBY_BUILD_HOST_IS_OPENBSD + if spec.build.cc.search_header_path 'termcap.h' + if MRUBY_BUILD_HOST_IS_CYGWIN then + spec.linker.libraries << 'ncurses' + else + spec.linker.libraries << 'termcap' + end + end + end + end + if RUBY_PLATFORM.include?('netbsd') + spec.linker.libraries << 'edit' + else + spec.linker.libraries << 'readline' + if spec.build.cc.search_header_path 'curses.h' + spec.linker.libraries << 'ncurses' + end + end + elsif spec.build.cc.search_header_path 'linenoise.h' + spec.cc.defines << "ENABLE_LINENOISE" + end + + spec.bins = %w(mirb) + spec.add_dependency('mruby-compiler', :core => 'mruby-compiler') +end diff --git a/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-bin-mirb/tools/mirb/mirb.c b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-bin-mirb/tools/mirb/mirb.c new file mode 100644 index 00000000..fe311d83 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-bin-mirb/tools/mirb/mirb.c @@ -0,0 +1,584 @@ +/* +** mirb - Embeddable Interactive Ruby Shell +** +** This program takes code from the user in +** an interactive way and executes it +** immediately. It's a REPL... +*/ + +#include +#include +#include +#include + +#include +#include + +#ifdef ENABLE_READLINE +#include +#include +#define MIRB_ADD_HISTORY(line) add_history(line) +#define MIRB_READLINE(ch) readline(ch) +#define MIRB_WRITE_HISTORY(path) write_history(path) +#define MIRB_READ_HISTORY(path) read_history(path) +#define MIRB_USING_HISTORY() using_history() +#elif defined(ENABLE_LINENOISE) +#define ENABLE_READLINE +#include +#define MIRB_ADD_HISTORY(line) linenoiseHistoryAdd(line) +#define MIRB_READLINE(ch) linenoise(ch) +#define MIRB_WRITE_HISTORY(path) linenoiseHistorySave(path) +#define MIRB_READ_HISTORY(path) linenoiseHistoryLoad(history_path) +#define MIRB_USING_HISTORY() +#endif + +#ifndef _WIN32 +#define MIRB_SIGSETJMP(env) sigsetjmp(env, 1) +#define MIRB_SIGLONGJMP(env, val) siglongjmp(env, val) +#define SIGJMP_BUF sigjmp_buf +#else +#define MIRB_SIGSETJMP(env) setjmp(env) +#define MIRB_SIGLONGJMP(env, val) longjmp(env, val) +#define SIGJMP_BUF jmp_buf +#endif + +#include +#include +#include +#include +#include + +#ifdef ENABLE_READLINE + +static const char history_file_name[] = ".mirb_history"; + +static char * +get_history_path(mrb_state *mrb) +{ + char *path = NULL; + const char *home = getenv("HOME"); + +#ifdef _WIN32 + if (home != NULL) { + home = getenv("USERPROFILE"); + } +#endif + + if (home != NULL) { + int len = snprintf(NULL, 0, "%s/%s", home, history_file_name); + if (len >= 0) { + size_t size = len + 1; + path = (char *)mrb_malloc_simple(mrb, size); + if (path != NULL) { + int n = snprintf(path, size, "%s/%s", home, history_file_name); + if (n != len) { + mrb_free(mrb, path); + path = NULL; + } + } + } + } + + return path; +} + +#endif + +static void +p(mrb_state *mrb, mrb_value obj, int prompt) +{ + mrb_value val; + + val = mrb_funcall(mrb, obj, "inspect", 0); + if (prompt) { + if (!mrb->exc) { + fputs(" => ", stdout); + } + else { + val = mrb_funcall(mrb, mrb_obj_value(mrb->exc), "inspect", 0); + } + } + if (!mrb_string_p(val)) { + val = mrb_obj_as_string(mrb, obj); + } + fwrite(RSTRING_PTR(val), RSTRING_LEN(val), 1, stdout); + putc('\n', stdout); +} + +/* Guess if the user might want to enter more + * or if he wants an evaluation of his code now */ +static mrb_bool +is_code_block_open(struct mrb_parser_state *parser) +{ + mrb_bool code_block_open = FALSE; + + /* check for heredoc */ + if (parser->parsing_heredoc != NULL) return TRUE; + if (parser->heredoc_end_now) { + parser->heredoc_end_now = FALSE; + return FALSE; + } + + /* check for unterminated string */ + if (parser->lex_strterm) return TRUE; + + /* check if parser error are available */ + if (0 < parser->nerr) { + const char unexpected_end[] = "syntax error, unexpected $end"; + const char *message = parser->error_buffer[0].message; + + /* a parser error occur, we have to check if */ + /* we need to read one more line or if there is */ + /* a different issue which we have to show to */ + /* the user */ + + if (strncmp(message, unexpected_end, sizeof(unexpected_end) - 1) == 0) { + code_block_open = TRUE; + } + else if (strcmp(message, "syntax error, unexpected keyword_end") == 0) { + code_block_open = FALSE; + } + else if (strcmp(message, "syntax error, unexpected tREGEXP_BEG") == 0) { + code_block_open = FALSE; + } + return code_block_open; + } + + switch (parser->lstate) { + + /* all states which need more code */ + + case EXPR_BEG: + /* beginning of a statement, */ + /* that means previous line ended */ + code_block_open = FALSE; + break; + case EXPR_DOT: + /* a message dot was the last token, */ + /* there has to come more */ + code_block_open = TRUE; + break; + case EXPR_CLASS: + /* a class keyword is not enough! */ + /* we need also a name of the class */ + code_block_open = TRUE; + break; + case EXPR_FNAME: + /* a method name is necessary */ + code_block_open = TRUE; + break; + case EXPR_VALUE: + /* if, elsif, etc. without condition */ + code_block_open = TRUE; + break; + + /* now all the states which are closed */ + + case EXPR_ARG: + /* an argument is the last token */ + code_block_open = FALSE; + break; + + /* all states which are unsure */ + + case EXPR_CMDARG: + break; + case EXPR_END: + /* an expression was ended */ + break; + case EXPR_ENDARG: + /* closing parenthese */ + break; + case EXPR_ENDFN: + /* definition end */ + break; + case EXPR_MID: + /* jump keyword like break, return, ... */ + break; + case EXPR_MAX_STATE: + /* don't know what to do with this token */ + break; + default: + /* this state is unexpected! */ + break; + } + + return code_block_open; +} + +struct _args { + FILE *rfp; + mrb_bool verbose : 1; + int argc; + char** argv; +}; + +static void +usage(const char *name) +{ + static const char *const usage_msg[] = { + "switches:", + "-v print version number, then run in verbose mode", + "--verbose run in verbose mode", + "--version print the version", + "--copyright print the copyright", + NULL + }; + const char *const *p = usage_msg; + + printf("Usage: %s [switches]\n", name); + while (*p) + printf(" %s\n", *p++); +} + +static int +parse_args(mrb_state *mrb, int argc, char **argv, struct _args *args) +{ + static const struct _args args_zero = { 0 }; + + *args = args_zero; + + for (argc--,argv++; argc > 0; argc--,argv++) { + char *item; + if (argv[0][0] != '-') break; + + item = argv[0] + 1; + switch (*item++) { + case 'v': + if (!args->verbose) mrb_show_version(mrb); + args->verbose = TRUE; + break; + case '-': + if (strcmp((*argv) + 2, "version") == 0) { + mrb_show_version(mrb); + exit(EXIT_SUCCESS); + } + else if (strcmp((*argv) + 2, "verbose") == 0) { + args->verbose = TRUE; + break; + } + else if (strcmp((*argv) + 2, "copyright") == 0) { + mrb_show_copyright(mrb); + exit(EXIT_SUCCESS); + } + default: + return EXIT_FAILURE; + } + } + + if (args->rfp == NULL) { + if (*argv != NULL) { + args->rfp = fopen(argv[0], "r"); + if (args->rfp == NULL) { + printf("Cannot open program file. (%s)\n", *argv); + return EXIT_FAILURE; + } + argc--; argv++; + } + } + args->argv = (char **)mrb_realloc(mrb, args->argv, sizeof(char*) * (argc + 1)); + memcpy(args->argv, argv, (argc+1) * sizeof(char*)); + args->argc = argc; + + return EXIT_SUCCESS; +} + +static void +cleanup(mrb_state *mrb, struct _args *args) +{ + if (args->rfp) + fclose(args->rfp); + mrb_free(mrb, args->argv); + mrb_close(mrb); +} + +/* Print a short remark for the user */ +static void +print_hint(void) +{ + printf("mirb - Embeddable Interactive Ruby Shell\n\n"); +} + +#ifndef ENABLE_READLINE +/* Print the command line prompt of the REPL */ +static void +print_cmdline(int code_block_open) +{ + if (code_block_open) { + printf("* "); + } + else { + printf("> "); + } + fflush(stdout); +} +#endif + +void mrb_codedump_all(mrb_state*, struct RProc*); + +static int +check_keyword(const char *buf, const char *word) +{ + const char *p = buf; + size_t len = strlen(word); + + /* skip preceding spaces */ + while (*p && isspace((unsigned char)*p)) { + p++; + } + /* check keyword */ + if (strncmp(p, word, len) != 0) { + return 0; + } + p += len; + /* skip trailing spaces */ + while (*p) { + if (!isspace((unsigned char)*p)) return 0; + p++; + } + return 1; +} + + +#ifndef ENABLE_READLINE +volatile sig_atomic_t input_canceled = 0; +void +ctrl_c_handler(int signo) +{ + input_canceled = 1; +} +#else +SIGJMP_BUF ctrl_c_buf; +void +ctrl_c_handler(int signo) +{ + MIRB_SIGLONGJMP(ctrl_c_buf, 1); +} +#endif + +int +main(int argc, char **argv) +{ + char ruby_code[4096] = { 0 }; + char last_code_line[1024] = { 0 }; +#ifndef ENABLE_READLINE + int last_char; + size_t char_index; +#else + char *history_path; + char* line; +#endif + mrbc_context *cxt; + struct mrb_parser_state *parser; + mrb_state *mrb; + mrb_value result; + struct _args args; + mrb_value ARGV; + int n; + int i; + mrb_bool code_block_open = FALSE; + int ai; + unsigned int stack_keep = 0; + + /* new interpreter instance */ + mrb = mrb_open(); + if (mrb == NULL) { + fputs("Invalid mrb interpreter, exiting mirb\n", stderr); + return EXIT_FAILURE; + } + + n = parse_args(mrb, argc, argv, &args); + if (n == EXIT_FAILURE) { + cleanup(mrb, &args); + usage(argv[0]); + return n; + } + + ARGV = mrb_ary_new_capa(mrb, args.argc); + for (i = 0; i < args.argc; i++) { + char* utf8 = mrb_utf8_from_locale(args.argv[i], -1); + if (utf8) { + mrb_ary_push(mrb, ARGV, mrb_str_new_cstr(mrb, utf8)); + mrb_utf8_free(utf8); + } + } + mrb_define_global_const(mrb, "ARGV", ARGV); + +#ifdef ENABLE_READLINE + history_path = get_history_path(mrb); + if (history_path == NULL) { + fputs("failed to get history path\n", stderr); + mrb_close(mrb); + return EXIT_FAILURE; + } + + MIRB_USING_HISTORY(); + MIRB_READ_HISTORY(history_path); +#endif + + print_hint(); + + cxt = mrbc_context_new(mrb); + cxt->capture_errors = TRUE; + cxt->lineno = 1; + mrbc_filename(mrb, cxt, "(mirb)"); + if (args.verbose) cxt->dump_result = TRUE; + + ai = mrb_gc_arena_save(mrb); + + while (TRUE) { + char *utf8; + + if (args.rfp) { + if (fgets(last_code_line, sizeof(last_code_line)-1, args.rfp) != NULL) + goto done; + break; + } + +#ifndef ENABLE_READLINE + print_cmdline(code_block_open); + + signal(SIGINT, ctrl_c_handler); + char_index = 0; + while ((last_char = getchar()) != '\n') { + if (last_char == EOF) break; + if (char_index >= sizeof(last_code_line)-2) { + fputs("input string too long\n", stderr); + continue; + } + last_code_line[char_index++] = last_char; + } + signal(SIGINT, SIG_DFL); + if (input_canceled) { + ruby_code[0] = '\0'; + last_code_line[0] = '\0'; + code_block_open = FALSE; + puts("^C"); + input_canceled = 0; + continue; + } + if (last_char == EOF) { + fputs("\n", stdout); + break; + } + + last_code_line[char_index++] = '\n'; + last_code_line[char_index] = '\0'; +#else + if (MIRB_SIGSETJMP(ctrl_c_buf) == 0) { + ; + } + else { + ruby_code[0] = '\0'; + last_code_line[0] = '\0'; + code_block_open = FALSE; + puts("^C"); + } + signal(SIGINT, ctrl_c_handler); + line = MIRB_READLINE(code_block_open ? "* " : "> "); + signal(SIGINT, SIG_DFL); + + if (line == NULL) { + printf("\n"); + break; + } + if (strlen(line) > sizeof(last_code_line)-2) { + fputs("input string too long\n", stderr); + continue; + } + strcpy(last_code_line, line); + strcat(last_code_line, "\n"); + MIRB_ADD_HISTORY(line); + free(line); +#endif + +done: + + if (code_block_open) { + if (strlen(ruby_code)+strlen(last_code_line) > sizeof(ruby_code)-1) { + fputs("concatenated input string too long\n", stderr); + continue; + } + strcat(ruby_code, last_code_line); + } + else { + if (check_keyword(last_code_line, "quit") || check_keyword(last_code_line, "exit")) { + break; + } + strcpy(ruby_code, last_code_line); + } + + utf8 = mrb_utf8_from_locale(ruby_code, -1); + if (!utf8) abort(); + + /* parse code */ + parser = mrb_parser_new(mrb); + if (parser == NULL) { + fputs("create parser state error\n", stderr); + break; + } + parser->s = utf8; + parser->send = utf8 + strlen(utf8); + parser->lineno = cxt->lineno; + mrb_parser_parse(parser, cxt); + code_block_open = is_code_block_open(parser); + mrb_utf8_free(utf8); + + if (code_block_open) { + /* no evaluation of code */ + } + else { + if (0 < parser->nerr) { + /* syntax error */ + printf("line %d: %s\n", parser->error_buffer[0].lineno, parser->error_buffer[0].message); + } + else { + /* generate bytecode */ + struct RProc *proc = mrb_generate_code(mrb, parser); + if (proc == NULL) { + fputs("codegen error\n", stderr); + mrb_parser_free(parser); + break; + } + + if (args.verbose) { + mrb_codedump_all(mrb, proc); + } + /* pass a proc for evaluation */ + /* evaluate the bytecode */ + result = mrb_vm_run(mrb, + proc, + mrb_top_self(mrb), + stack_keep); + stack_keep = proc->body.irep->nlocals; + /* did an exception occur? */ + if (mrb->exc) { + p(mrb, mrb_obj_value(mrb->exc), 0); + mrb->exc = 0; + } + else { + /* no */ + if (!mrb_respond_to(mrb, result, mrb_intern_lit(mrb, "inspect"))){ + result = mrb_any_to_s(mrb, result); + } + p(mrb, result, 1); + } + } + ruby_code[0] = '\0'; + last_code_line[0] = '\0'; + mrb_gc_arena_restore(mrb, ai); + } + mrb_parser_free(parser); + cxt->lineno++; + } + +#ifdef ENABLE_READLINE + MIRB_WRITE_HISTORY(history_path); + mrb_free(mrb, history_path); +#endif + + mrbc_context_free(mrb, cxt); + mrb_close(mrb); + + return 0; +} diff --git a/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-bin-mrbc/mrbgem.rake b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-bin-mrbc/mrbgem.rake new file mode 100644 index 00000000..e710b5a4 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-bin-mrbc/mrbgem.rake @@ -0,0 +1,16 @@ +MRuby::Gem::Specification.new 'mruby-bin-mrbc' do |spec| + spec.license = 'MIT' + spec.author = 'mruby developers' + spec.summary = 'mruby compiler executable' + + spec.add_dependency 'mruby-compiler', :core => 'mruby-compiler' + + exec = exefile("#{build.build_dir}/bin/mrbc") + mrbc_objs = Dir.glob("#{spec.dir}/tools/mrbc/*.c").map { |f| objfile(f.pathmap("#{spec.build_dir}/tools/mrbc/%n")) }.flatten + + file exec => mrbc_objs + [libfile("#{build.build_dir}/lib/libmruby_core")] do |t| + build.linker.run t.name, t.prerequisites + end + + build.bins << 'mrbc' unless build.bins.find { |v| v == 'mrbc' } +end diff --git a/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-bin-mrbc/tools/mrbc/mrbc.c b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-bin-mrbc/tools/mrbc/mrbc.c new file mode 100644 index 00000000..580c2e25 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-bin-mrbc/tools/mrbc/mrbc.c @@ -0,0 +1,336 @@ +#include +#include +#include +#include +#include +#include +#include + +#define RITEBIN_EXT ".mrb" +#define C_EXT ".c" + +struct mrbc_args { + int argc; + char **argv; + int idx; + const char *prog; + const char *outfile; + const char *initname; + mrb_bool check_syntax : 1; + mrb_bool verbose : 1; + unsigned int flags : 4; +}; + +static void +usage(const char *name) +{ + static const char *const usage_msg[] = { + "switches:", + "-c check syntax only", + "-o place the output into ", + "-v print version number, then turn on verbose mode", + "-g produce debugging information", + "-B binary output in C language format", + "-e generate little endian iseq data", + "-E generate big endian iseq data", + "--verbose run at verbose mode", + "--version print the version", + "--copyright print the copyright", + NULL + }; + const char *const *p = usage_msg; + + printf("Usage: %s [switches] programfile\n", name); + while (*p) + printf(" %s\n", *p++); +} + +static char * +get_outfilename(mrb_state *mrb, char *infile, const char *ext) +{ + size_t infilelen; + size_t extlen; + char *outfile; + char *p; + + infilelen = strlen(infile); + extlen = strlen(ext); + outfile = (char*)mrb_malloc(mrb, infilelen + extlen + 1); + memcpy(outfile, infile, infilelen + 1); + if (*ext) { + if ((p = strrchr(outfile, '.')) == NULL) + p = outfile + infilelen; + memcpy(p, ext, extlen + 1); + } + + return outfile; +} + +static int +parse_args(mrb_state *mrb, int argc, char **argv, struct mrbc_args *args) +{ + char *outfile = NULL; + static const struct mrbc_args args_zero = { 0 }; + int i; + + *args = args_zero; + args->argc = argc; + args->argv = argv; + args->prog = argv[0]; + + for (i=1; ioutfile) { + fprintf(stderr, "%s: an output file is already specified. (%s)\n", + args->prog, outfile); + return -1; + } + if (argv[i][2] == '\0' && argv[i+1]) { + i++; + args->outfile = get_outfilename(mrb, argv[i], ""); + } + else { + args->outfile = get_outfilename(mrb, argv[i] + 2, ""); + } + break; + case 'B': + if (argv[i][2] == '\0' && argv[i+1]) { + i++; + args->initname = argv[i]; + } + else { + args->initname = argv[i]+2; + } + if (*args->initname == '\0') { + fprintf(stderr, "%s: function name is not specified.\n", args->prog); + return -1; + } + break; + case 'c': + args->check_syntax = TRUE; + break; + case 'v': + if (!args->verbose) mrb_show_version(mrb); + args->verbose = TRUE; + break; + case 'g': + args->flags |= DUMP_DEBUG_INFO; + break; + case 'E': + args->flags = DUMP_ENDIAN_BIG | (args->flags & ~DUMP_ENDIAN_MASK); + break; + case 'e': + args->flags = DUMP_ENDIAN_LIL | (args->flags & ~DUMP_ENDIAN_MASK); + break; + case 'h': + return -1; + case '-': + if (argv[i][1] == '\n') { + return i; + } + if (strcmp(argv[i] + 2, "version") == 0) { + mrb_show_version(mrb); + exit(EXIT_SUCCESS); + } + else if (strcmp(argv[i] + 2, "verbose") == 0) { + args->verbose = TRUE; + break; + } + else if (strcmp(argv[i] + 2, "copyright") == 0) { + mrb_show_copyright(mrb); + exit(EXIT_SUCCESS); + } + return -1; + default: + return i; + } + } + else { + break; + } + } + if (args->verbose && args->initname && (args->flags & DUMP_ENDIAN_MASK) == 0) { + fprintf(stderr, "%s: generating %s endian C file. specify -e/-E for cross compiling.\n", + args->prog, bigendian_p() ? "big" : "little"); + } + return i; +} + +static void +cleanup(mrb_state *mrb, struct mrbc_args *args) +{ + mrb_free(mrb, (void*)args->outfile); + mrb_close(mrb); +} + +static int +partial_hook(struct mrb_parser_state *p) +{ + mrbc_context *c = p->cxt; + struct mrbc_args *args = (struct mrbc_args *)c->partial_data; + const char *fn; + + if (p->f) fclose(p->f); + if (args->idx >= args->argc) { + p->f = NULL; + return -1; + } + fn = args->argv[args->idx++]; + p->f = fopen(fn, "r"); + if (p->f == NULL) { + fprintf(stderr, "%s: cannot open program file. (%s)\n", args->prog, fn); + return -1; + } + mrb_parser_set_filename(p, fn); + return 0; +} + +static mrb_value +load_file(mrb_state *mrb, struct mrbc_args *args) +{ + mrbc_context *c; + mrb_value result; + char *input = args->argv[args->idx]; + FILE *infile; + mrb_bool need_close = FALSE; + + c = mrbc_context_new(mrb); + if (args->verbose) + c->dump_result = TRUE; + c->no_exec = TRUE; + if (input[0] == '-' && input[1] == '\0') { + infile = stdin; + } + else { + need_close = TRUE; + if ((infile = fopen(input, "r")) == NULL) { + fprintf(stderr, "%s: cannot open program file. (%s)\n", args->prog, input); + return mrb_nil_value(); + } + } + mrbc_filename(mrb, c, input); + args->idx++; + if (args->idx < args->argc) { + need_close = FALSE; + mrbc_partial_hook(mrb, c, partial_hook, (void*)args); + } + + result = mrb_load_file_cxt(mrb, infile, c); + if (need_close) fclose(infile); + mrbc_context_free(mrb, c); + if (mrb_undef_p(result)) { + return mrb_nil_value(); + } + return result; +} + +static int +dump_file(mrb_state *mrb, FILE *wfp, const char *outfile, struct RProc *proc, struct mrbc_args *args) +{ + int n = MRB_DUMP_OK; + mrb_irep *irep = proc->body.irep; + + if (args->initname) { + n = mrb_dump_irep_cfunc(mrb, irep, args->flags, wfp, args->initname); + if (n == MRB_DUMP_INVALID_ARGUMENT) { + fprintf(stderr, "%s: invalid C language symbol name\n", args->initname); + } + } + else { + n = mrb_dump_irep_binary(mrb, irep, args->flags, wfp); + } + if (n != MRB_DUMP_OK) { + fprintf(stderr, "%s: error in mrb dump (%s) %d\n", args->prog, outfile, n); + } + return n; +} + +int +main(int argc, char **argv) +{ + mrb_state *mrb = mrb_open(); + int n, result; + struct mrbc_args args; + FILE *wfp; + mrb_value load; + + if (mrb == NULL) { + fputs("Invalid mrb_state, exiting mrbc\n", stderr); + return EXIT_FAILURE; + } + + n = parse_args(mrb, argc, argv, &args); + if (n < 0) { + cleanup(mrb, &args); + usage(argv[0]); + return EXIT_FAILURE; + } + if (n == argc) { + fprintf(stderr, "%s: no program file given\n", args.prog); + return EXIT_FAILURE; + } + if (args.outfile == NULL && !args.check_syntax) { + if (n + 1 == argc) { + args.outfile = get_outfilename(mrb, argv[n], args.initname ? C_EXT : RITEBIN_EXT); + } + else { + fprintf(stderr, "%s: output file should be specified to compile multiple files\n", args.prog); + return EXIT_FAILURE; + } + } + + args.idx = n; + load = load_file(mrb, &args); + if (mrb_nil_p(load)) { + cleanup(mrb, &args); + return EXIT_FAILURE; + } + if (args.check_syntax) { + printf("%s:%s:Syntax OK\n", args.prog, argv[n]); + } + + if (args.check_syntax) { + cleanup(mrb, &args); + return EXIT_SUCCESS; + } + + if (args.outfile) { + if (strcmp("-", args.outfile) == 0) { + wfp = stdout; + } + else if ((wfp = fopen(args.outfile, "wb")) == NULL) { + fprintf(stderr, "%s: cannot open output file:(%s)\n", args.prog, args.outfile); + return EXIT_FAILURE; + } + } + else { + fprintf(stderr, "Output file is required\n"); + return EXIT_FAILURE; + } + result = dump_file(mrb, wfp, args.outfile, mrb_proc_ptr(load), &args); + fclose(wfp); + cleanup(mrb, &args); + if (result != MRB_DUMP_OK) { + return EXIT_FAILURE; + } + return EXIT_SUCCESS; +} + +void +mrb_init_mrblib(mrb_state *mrb) +{ +} + +#ifndef DISABLE_GEMS +void +mrb_init_mrbgems(mrb_state *mrb) +{ +} + +void +mrb_final_mrbgems(mrb_state *mrb) +{ +} +#endif diff --git a/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-bin-mruby-config/mrbgem.rake b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-bin-mruby-config/mrbgem.rake new file mode 100644 index 00000000..66d6ef80 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-bin-mruby-config/mrbgem.rake @@ -0,0 +1,30 @@ +module MRuby + class Build + def exefile(name) + if name.is_a?(Array) + name.flatten.map { |n| exefile(n) } + elsif name !~ /\./ + "#{name}#{exts.executable}" + else + name + end + end + end +end + +MRuby.each_target do + next if kind_of? MRuby::CrossBuild + + mruby_config = 'mruby-config' + (ENV['OS'] == 'Windows_NT' ? '.bat' : '') + mruby_config_path = "#{build_dir}/bin/#{mruby_config}" + @bins << mruby_config + + file mruby_config_path => libfile("#{build_dir}/lib/libmruby") do |t| + FileUtils.copy "#{File.dirname(__FILE__)}/#{mruby_config}", t.name + config = Hash[open("#{build_dir}/lib/libmruby.flags.mak").read.split("\n").map {|x| a = x.split(/\s*=\s*/, 2); [a[0], a[1].gsub('\\"', '"') ]}] + IO.write(t.name, File.open(t.name) {|f| + f.read.gsub (/echo (MRUBY_CFLAGS|MRUBY_LIBS|MRUBY_LDFLAGS_BEFORE_LIBS|MRUBY_LDFLAGS|MRUBY_LIBMRUBY_PATH)/) {|x| config[$1].empty? ? '' : "echo #{config[$1]}"} + }) + FileUtils.chmod(0755, t.name) + end +end diff --git a/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-bin-mruby-config/mruby-config b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-bin-mruby-config/mruby-config new file mode 100644 index 00000000..57346c03 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-bin-mruby-config/mruby-config @@ -0,0 +1,20 @@ +#!/bin/sh + +while [ $# -gt 0 ]; do + case $1 in + --cflags) echo MRUBY_CFLAGS;; + --ldflags) echo MRUBY_LDFLAGS;; + --ldflags-before-libs) echo MRUBY_LDFLAGS_BEFORE_LIBS;; + --libs) echo MRUBY_LIBS;; + --libmruby-path) echo MRUBY_LIBMRUBY_PATH;; + --help) echo "Usage: mruby-config [switches]" + echo " switches:" + echo " --cflags print flags passed to compiler" + echo " --ldflags print flags passed to linker" + echo " --ldflags-before-libs print flags passed to linker before linked libraries" + echo " --libs print linked libraries" + echo " --libmruby-path print libmruby path" + exit 0;; + esac + shift +done diff --git a/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-bin-mruby-config/mruby-config.bat b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-bin-mruby-config/mruby-config.bat new file mode 100644 index 00000000..a1f7bfdd --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-bin-mruby-config/mruby-config.bat @@ -0,0 +1,42 @@ +@echo off + +:top +shift +if "%0" equ "" goto :eof +if "%0" equ "--cflags" goto cflags +if "%0" equ "--ldflags" goto ldflags +if "%0" equ "--ldflags-before-libs" goto ldflagsbeforelibs +if "%0" equ "--libs" goto libs +if "%0" equ "--libmruby-path" goto libmrubypath +if "%0" equ "--help" goto showhelp +echo Invalid Option +goto :eof + +:cflags +echo MRUBY_CFLAGS +goto top + +:libs +echo MRUBY_LIBS +goto top + +:ldflags +echo MRUBY_LDFLAGS +goto top + +:ldflagsbeforelibs +echo MRUBY_LDFLAGS_BEFORE_LIBS +goto top + +:libmrubypath +echo MRUBY_LIBMRUBY_PATH +goto top + +:showhelp +echo Usage: mruby-config [switches] +echo switches: +echo --cflags print flags passed to compiler +echo --ldflags print flags passed to linker +echo --ldflags-before-libs print flags passed to linker before linked libraries +echo --libs print linked libraries +echo --libmruby-path print libmruby path diff --git a/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-bin-mruby/bintest/mruby.rb b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-bin-mruby/bintest/mruby.rb new file mode 100644 index 00000000..b6b09018 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-bin-mruby/bintest/mruby.rb @@ -0,0 +1,60 @@ +require 'tempfile' + +assert('regression for #1564') do + o = `#{cmd('mruby')} -e #{shellquote('<<')} 2>&1` + assert_include o, "-e:1:2: syntax error" + o = `#{cmd('mruby')} -e #{shellquote('<<-')} 2>&1` + assert_include o, "-e:1:3: syntax error" +end + +assert('regression for #1572') do + script, bin = Tempfile.new('test.rb'), Tempfile.new('test.mrb') + File.write script.path, 'p "ok"' + system "#{cmd('mrbc')} -g -o #{bin.path} #{script.path}" + o = `#{cmd('mruby')} -b #{bin.path}`.strip + assert_equal o, '"ok"' +end + +assert '$0 value' do + script, bin = Tempfile.new('test.rb'), Tempfile.new('test.mrb') + + # .rb script + script.write "p $0\n" + script.flush + assert_equal "\"#{script.path}\"", `#{cmd('mruby')} "#{script.path}"`.chomp + + # .mrb file + `#{cmd('mrbc')} -o "#{bin.path}" "#{script.path}"` + assert_equal "\"#{bin.path}\"", `#{cmd('mruby')} -b "#{bin.path}"`.chomp + + # one liner + assert_equal '"-e"', `#{cmd('mruby')} -e #{shellquote('p $0')}`.chomp +end + +assert '__END__', '8.6' do + script = Tempfile.new('test.rb') + + script.write < 'mruby-compiler') + spec.add_dependency('mruby-error', :core => 'mruby-error') + + if build.cxx_exception_enabled? + build.compile_as_cxx("#{spec.dir}/tools/mruby/mruby.c", "#{spec.build_dir}/tools/mruby/mruby.cxx") + end +end diff --git a/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-bin-mruby/tools/mruby/mruby.c b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-bin-mruby/tools/mruby/mruby.c new file mode 100644 index 00000000..61d4cde9 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-bin-mruby/tools/mruby/mruby.c @@ -0,0 +1,254 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef MRB_DISABLE_STDIO +static void +p(mrb_state *mrb, mrb_value obj) +{ + mrb_value val = mrb_inspect(mrb, obj); + + fwrite(RSTRING_PTR(val), RSTRING_LEN(val), 1, stdout); + putc('\n', stdout); +} +#else +#define p(mrb,obj) mrb_p(mrb,obj) +#endif + +struct _args { + FILE *rfp; + char* cmdline; + mrb_bool fname : 1; + mrb_bool mrbfile : 1; + mrb_bool check_syntax : 1; + mrb_bool verbose : 1; + int argc; + char** argv; +}; + +static void +usage(const char *name) +{ + static const char *const usage_msg[] = { + "switches:", + "-b load and execute RiteBinary (mrb) file", + "-c check syntax only", + "-e 'command' one line of script", + "-v print version number, then run in verbose mode", + "--verbose run in verbose mode", + "--version print the version", + "--copyright print the copyright", + NULL + }; + const char *const *p = usage_msg; + + printf("Usage: %s [switches] programfile\n", name); + while (*p) + printf(" %s\n", *p++); +} + +static int +parse_args(mrb_state *mrb, int argc, char **argv, struct _args *args) +{ + char **origargv = argv; + static const struct _args args_zero = { 0 }; + + *args = args_zero; + + for (argc--,argv++; argc > 0; argc--,argv++) { + char *item; + if (argv[0][0] != '-') break; + + if (strlen(*argv) <= 1) { + argc--; argv++; + args->rfp = stdin; + break; + } + + item = argv[0] + 1; + switch (*item++) { + case 'b': + args->mrbfile = TRUE; + break; + case 'c': + args->check_syntax = TRUE; + break; + case 'e': + if (item[0]) { + goto append_cmdline; + } + else if (argc > 1) { + argc--; argv++; + item = argv[0]; +append_cmdline: + if (!args->cmdline) { + size_t buflen; + char *buf; + + buflen = strlen(item) + 1; + buf = (char *)mrb_malloc(mrb, buflen); + memcpy(buf, item, buflen); + args->cmdline = buf; + } + else { + size_t cmdlinelen; + size_t itemlen; + + cmdlinelen = strlen(args->cmdline); + itemlen = strlen(item); + args->cmdline = + (char *)mrb_realloc(mrb, args->cmdline, cmdlinelen + itemlen + 2); + args->cmdline[cmdlinelen] = '\n'; + memcpy(args->cmdline + cmdlinelen + 1, item, itemlen + 1); + } + } + else { + printf("%s: No code specified for -e\n", *origargv); + return EXIT_SUCCESS; + } + break; + case 'v': + if (!args->verbose) mrb_show_version(mrb); + args->verbose = TRUE; + break; + case '-': + if (strcmp((*argv) + 2, "version") == 0) { + mrb_show_version(mrb); + exit(EXIT_SUCCESS); + } + else if (strcmp((*argv) + 2, "verbose") == 0) { + args->verbose = TRUE; + break; + } + else if (strcmp((*argv) + 2, "copyright") == 0) { + mrb_show_copyright(mrb); + exit(EXIT_SUCCESS); + } + default: + return EXIT_FAILURE; + } + } + + if (args->rfp == NULL && args->cmdline == NULL) { + if (*argv == NULL) args->rfp = stdin; + else { + args->rfp = fopen(argv[0], args->mrbfile ? "rb" : "r"); + if (args->rfp == NULL) { + printf("%s: Cannot open program file. (%s)\n", *origargv, *argv); + return EXIT_FAILURE; + } + args->fname = TRUE; + args->cmdline = argv[0]; + argc--; argv++; + } + } + args->argv = (char **)mrb_realloc(mrb, args->argv, sizeof(char*) * (argc + 1)); + memcpy(args->argv, argv, (argc+1) * sizeof(char*)); + args->argc = argc; + + return EXIT_SUCCESS; +} + +static void +cleanup(mrb_state *mrb, struct _args *args) +{ + if (args->rfp && args->rfp != stdin) + fclose(args->rfp); + if (!args->fname) + mrb_free(mrb, args->cmdline); + mrb_free(mrb, args->argv); + mrb_close(mrb); +} + +int +main(int argc, char **argv) +{ + mrb_state *mrb = mrb_open(); + int n = -1; + int i; + struct _args args; + mrb_value ARGV; + mrbc_context *c; + mrb_value v; + mrb_sym zero_sym; + + if (mrb == NULL) { + fputs("Invalid mrb_state, exiting mruby\n", stderr); + return EXIT_FAILURE; + } + + n = parse_args(mrb, argc, argv, &args); + if (n == EXIT_FAILURE || (args.cmdline == NULL && args.rfp == NULL)) { + cleanup(mrb, &args); + usage(argv[0]); + return n; + } + else { + int ai = mrb_gc_arena_save(mrb); + ARGV = mrb_ary_new_capa(mrb, args.argc); + for (i = 0; i < args.argc; i++) { + char* utf8 = mrb_utf8_from_locale(args.argv[i], -1); + if (utf8) { + mrb_ary_push(mrb, ARGV, mrb_str_new_cstr(mrb, utf8)); + mrb_utf8_free(utf8); + } + } + mrb_define_global_const(mrb, "ARGV", ARGV); + + c = mrbc_context_new(mrb); + if (args.verbose) + c->dump_result = TRUE; + if (args.check_syntax) + c->no_exec = TRUE; + + /* Set $0 */ + zero_sym = mrb_intern_lit(mrb, "$0"); + if (args.rfp) { + const char *cmdline; + cmdline = args.cmdline ? args.cmdline : "-"; + mrbc_filename(mrb, c, cmdline); + mrb_gv_set(mrb, zero_sym, mrb_str_new_cstr(mrb, cmdline)); + } + else { + mrbc_filename(mrb, c, "-e"); + mrb_gv_set(mrb, zero_sym, mrb_str_new_lit(mrb, "-e")); + } + + /* Load program */ + if (args.mrbfile) { + v = mrb_load_irep_file_cxt(mrb, args.rfp, c); + } + else if (args.rfp) { + v = mrb_load_file_cxt(mrb, args.rfp, c); + } + else { + char* utf8 = mrb_utf8_from_locale(args.cmdline, -1); + if (!utf8) abort(); + v = mrb_load_string_cxt(mrb, utf8, c); + mrb_utf8_free(utf8); + } + + mrb_gc_arena_restore(mrb, ai); + mrbc_context_free(mrb, c); + if (mrb->exc) { + if (mrb_undef_p(v)) { + mrb_p(mrb, mrb_obj_value(mrb->exc)); + } + else { + mrb_print_error(mrb); + } + n = -1; + } + else if (args.check_syntax) { + printf("Syntax OK\n"); + } + } + cleanup(mrb, &args); + + return n == 0 ? EXIT_SUCCESS : EXIT_FAILURE; +} diff --git a/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-bin-strip/bintest/mruby-strip.rb b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-bin-strip/bintest/mruby-strip.rb new file mode 100644 index 00000000..bb664a2b --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-bin-strip/bintest/mruby-strip.rb @@ -0,0 +1,73 @@ +require 'tempfile' + +assert('no files') do + o = `#{cmd('mruby-strip')} 2>&1` + assert_equal 1, $?.exitstatus + assert_equal "no files to strip", o.split("\n")[0] +end + +assert('file not found') do + o = `#{cmd('mruby-strip')} not_found.mrb 2>&1` + assert_equal 1, $?.exitstatus + assert_equal "can't open file for reading not_found.mrb\n", o +end + +assert('not irep file') do + t = Tempfile.new('script.rb') + t.write 'p test\n' + t.flush + o = `#{cmd('mruby-strip')} #{t.path} 2>&1` + assert_equal 1, $?.exitstatus + assert_equal "can't read irep file #{t.path}\n", o +end + +assert('success') do + script_file, compiled1, compiled2 = + Tempfile.new('script.rb'), Tempfile.new('c1.mrb'), Tempfile.new('c2.mrb') + script_file.write "p 'test'\n" + script_file.flush + `#{cmd('mrbc')} -g -o #{compiled1.path} #{script_file.path}` + `#{cmd('mrbc')} -g -o #{compiled2.path} #{script_file.path}` + + o = `#{cmd('mruby-strip')} #{compiled1.path}` + assert_equal 0, $?.exitstatus + assert_equal "", o + assert_equal `#{cmd('mruby')} #{script_file.path}`, `#{cmd('mruby')} -b #{compiled1.path}` + + o = `#{cmd('mruby-strip')} #{compiled1.path} #{compiled2.path}` + assert_equal 0, $?.exitstatus + assert_equal "", o +end + +assert('check debug section') do + script_file, with_debug, without_debug = + Tempfile.new('script.rb'), Tempfile.new('c1.mrb'), Tempfile.new('c2.mrb') + script_file.write "p 'test'\n" + script_file.flush + `#{cmd('mrbc')} -o #{without_debug.path} #{script_file.path}` + `#{cmd('mrbc')} -g -o #{with_debug.path} #{script_file.path}` + + assert_true with_debug.size >= without_debug.size + + `#{cmd('mruby-strip')} #{with_debug.path}` + assert_equal without_debug.size, with_debug.size +end + +assert('check lv section') do + script_file, with_lv, without_lv = + Tempfile.new('script.rb'), Tempfile.new('c1.mrb'), Tempfile.new('c2.mrb') + script_file.write < +#include +#include +#include +#include +#include + +struct strip_args { + int argc_start; + int argc; + char **argv; + mrb_bool lvar; +}; + + +static void +irep_remove_lv(mrb_state *mrb, mrb_irep *irep) +{ + int i; + + if (irep->lv) { + mrb_free(mrb, irep->lv); + irep->lv = NULL; + } + + for (i = 0; i < irep->rlen; ++i) { + irep_remove_lv(mrb, irep->reps[i]); + } +} + +static void +print_usage(const char *f) +{ + printf("Usage: %s [switches] irepfiles\n", f); + printf("switches:\n"); + printf(" -l, --lvar remove LVAR section too.\n"); +} + +static int +parse_args(int argc, char **argv, struct strip_args *args) +{ + int i; + + args->argc_start = 0; + args->argc = argc; + args->argv = argv; + args->lvar = FALSE; + + for (i = 1; i < argc; ++i) { + const size_t len = strlen(argv[i]); + if (len >= 2 && argv[i][0] == '-') { + switch (argv[i][1]) { + case 'l': + args->lvar = TRUE; + break; + case '-': + if (strncmp((*argv) + 2, "lvar", len) == 0) { + args->lvar = TRUE; + break; + } + default: + return -1; + } + } + else { + break; + } + } + + args->argc_start = i; + return i; +} + +static int +strip(mrb_state *mrb, struct strip_args *args) +{ + int i; + + for (i = args->argc_start; i < args->argc; ++i) { + char *filename; + FILE *rfile; + mrb_irep *irep; + FILE *wfile; + int dump_result; + + filename = args->argv[i]; + rfile = fopen(filename, "rb"); + if (rfile == NULL) { + fprintf(stderr, "can't open file for reading %s\n", filename); + return EXIT_FAILURE; + } + + irep = mrb_read_irep_file(mrb, rfile); + fclose(rfile); + if (irep == NULL) { + fprintf(stderr, "can't read irep file %s\n", filename); + return EXIT_FAILURE; + } + + /* clear lv if --lvar is enabled */ + if (args->lvar) { + irep_remove_lv(mrb, irep); + } + + wfile = fopen(filename, "wb"); + if (wfile == NULL) { + fprintf(stderr, "can't open file for writing %s\n", filename); + mrb_irep_decref(mrb, irep); + return EXIT_FAILURE; + } + + /* debug flag must always be false */ + dump_result = mrb_dump_irep_binary(mrb, irep, FALSE, wfile); + + fclose(wfile); + mrb_irep_decref(mrb, irep); + + if (dump_result != MRB_DUMP_OK) { + fprintf(stderr, "error occurred during dumping %s\n", filename); + return EXIT_FAILURE; + } + } + return EXIT_SUCCESS; +} + +int +main(int argc, char **argv) +{ + struct strip_args args; + int args_result; + mrb_state *mrb; + int ret; + + if (argc <= 1) { + printf("no files to strip\n"); + print_usage(argv[0]); + return EXIT_FAILURE; + } + + args_result = parse_args(argc, argv, &args); + if (args_result < 0) { + print_usage(argv[0]); + return EXIT_FAILURE; + } + mrb = mrb_open_core(mrb_default_allocf, NULL); + if (mrb == NULL) { + fputs("Invalid mrb_state, exiting mruby-strip\n", stderr); + return EXIT_FAILURE; + } + + ret = strip(mrb, &args); + + mrb_close(mrb); + return ret; +} diff --git a/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-class-ext/mrbgem.rake b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-class-ext/mrbgem.rake new file mode 100644 index 00000000..a384b1ee --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-class-ext/mrbgem.rake @@ -0,0 +1,5 @@ +MRuby::Gem::Specification.new('mruby-class-ext') do |spec| + spec.license = 'MIT' + spec.author = 'mruby developers' + spec.summary = 'class/module extension' +end diff --git a/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-class-ext/src/class.c b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-class-ext/src/class.c new file mode 100644 index 00000000..5506c482 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-class-ext/src/class.c @@ -0,0 +1,30 @@ +#include "mruby.h" +#include "mruby/class.h" +#include "mruby/string.h" + +static mrb_value +mrb_mod_name(mrb_state *mrb, mrb_value self) +{ + mrb_value name = mrb_class_path(mrb, mrb_class_ptr(self)); + return mrb_nil_p(name)? name : mrb_str_dup(mrb, name); +} + +static mrb_value +mrb_mod_singleton_class_p(mrb_state *mrb, mrb_value self) +{ + return mrb_bool_value(mrb_type(self) == MRB_TT_SCLASS); +} + +void +mrb_mruby_class_ext_gem_init(mrb_state *mrb) +{ + struct RClass *mod = mrb->module_class; + + mrb_define_method(mrb, mod, "name", mrb_mod_name, MRB_ARGS_NONE()); + mrb_define_method(mrb, mod, "singleton_class?", mrb_mod_singleton_class_p, MRB_ARGS_NONE()); +} + +void +mrb_mruby_class_ext_gem_final(mrb_state *mrb) +{ +} diff --git a/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-class-ext/test/module.rb b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-class-ext/test/module.rb new file mode 100644 index 00000000..65abde10 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-class-ext/test/module.rb @@ -0,0 +1,34 @@ +assert 'Module#name' do + module Outer + class Inner; end + const_set :SetInner, Class.new + end + + assert_equal 'Outer', Outer.name + assert_equal 'Outer::Inner', Outer::Inner.name + assert_equal 'Outer::SetInner', Outer::SetInner.name + + outer = Module.new do + const_set :SetInner, Class.new + end + Object.const_set :SetOuter, outer + + assert_equal 'SetOuter', SetOuter.name + assert_equal 'SetOuter::SetInner', SetOuter::SetInner.name + + mod = Module.new + cls = Class.new + + assert_nil mod.name + assert_nil cls.name +end + +assert 'Module#singleton_class?' do + mod = Module.new + cls = Class.new + scl = cls.singleton_class + + assert_false mod.singleton_class? + assert_false cls.singleton_class? + assert_true scl.singleton_class? +end diff --git a/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-compiler/bintest/mrbc.rb b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-compiler/bintest/mrbc.rb new file mode 100644 index 00000000..f4d9208b --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-compiler/bintest/mrbc.rb @@ -0,0 +1,30 @@ +require 'tempfile' + +assert('Compiling multiple files without new line in last line. #2361') do + a, b, out = Tempfile.new('a.rb'), Tempfile.new('b.rb'), Tempfile.new('out.mrb') + a.write('module A; end') + a.flush + b.write('module B; end') + b.flush + result = `#{cmd('mrbc')} -c -o #{out.path} #{a.path} #{b.path} 2>&1` + assert_equal "#{cmd('mrbc')}:#{a.path}:Syntax OK", result.chomp + assert_equal 0, $?.exitstatus +end + +assert('parsing function with void argument') do + a, out = Tempfile.new('a.rb'), Tempfile.new('out.mrb') + a.write('f ()') + a.flush + result = `#{cmd('mrbc')} -c -o #{out.path} #{a.path} 2>&1` + assert_equal "#{cmd('mrbc')}:#{a.path}:Syntax OK", result.chomp + assert_equal 0, $?.exitstatus +end + +assert('embedded document with invalid terminator') do + a, out = Tempfile.new('a.rb'), Tempfile.new('out.mrb') + a.write("=begin\n=endx\n") + a.flush + result = `#{cmd('mrbc')} -c -o #{out.path} #{a.path} 2>&1` + assert_equal "#{a.path}:3:0: embedded document meets end of file", result.chomp + assert_equal 1, $?.exitstatus +end diff --git a/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-compiler/core/codegen.c b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-compiler/core/codegen.c new file mode 100644 index 00000000..8f15a9b1 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-compiler/core/codegen.c @@ -0,0 +1,3026 @@ +/* +** codegen.c - mruby code generator +** +** See Copyright Notice in mruby.h +*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "node.h" +#include +#include +#include + +#ifndef MRB_CODEGEN_LEVEL_MAX +#define MRB_CODEGEN_LEVEL_MAX 1024 +#endif + +typedef mrb_ast_node node; +typedef struct mrb_parser_state parser_state; + +enum looptype { + LOOP_NORMAL, + LOOP_BLOCK, + LOOP_FOR, + LOOP_BEGIN, + LOOP_RESCUE, +}; + +struct loopinfo { + enum looptype type; + int pc1, pc2, pc3, acc; + int ensure_level; + struct loopinfo *prev; +}; + +typedef struct scope { + mrb_state *mrb; + mrb_pool *mpool; + struct mrb_jmpbuf jmp; + + struct scope *prev; + + node *lv; + + int sp; + int pc; + int lastlabel; + int ainfo:15; + mrb_bool mscope:1; + + struct loopinfo *loop; + int ensure_level; + char const *filename; + uint16_t lineno; + + mrb_code *iseq; + uint16_t *lines; + int icapa; + + mrb_irep *irep; + int pcapa, scapa, rcapa; + + uint16_t nlocals; + uint16_t nregs; + int ai; + + int debug_start_pos; + uint16_t filename_index; + parser_state* parser; + + int rlev; /* recursion levels */ +} codegen_scope; + +static codegen_scope* scope_new(mrb_state *mrb, codegen_scope *prev, node *lv); +static void scope_finish(codegen_scope *s); +static struct loopinfo *loop_push(codegen_scope *s, enum looptype t); +static void loop_break(codegen_scope *s, node *tree); +static void loop_pop(codegen_scope *s, int val); + +static void gen_assignment(codegen_scope *s, node *tree, int sp, int val); +static void gen_vmassignment(codegen_scope *s, node *tree, int rhs, int val); + +static void codegen(codegen_scope *s, node *tree, int val); +static void raise_error(codegen_scope *s, const char *msg); + +static void +codegen_error(codegen_scope *s, const char *message) +{ + if (!s) return; + while (s->prev) { + codegen_scope *tmp = s->prev; + mrb_free(s->mrb, s->iseq); + mrb_pool_close(s->mpool); + s = tmp; + } +#ifndef MRB_DISABLE_STDIO + if (s->filename && s->lineno) { + fprintf(stderr, "codegen error:%s:%d: %s\n", s->filename, s->lineno, message); + } + else { + fprintf(stderr, "codegen error: %s\n", message); + } +#endif + MRB_THROW(&s->jmp); +} + +static void* +codegen_palloc(codegen_scope *s, size_t len) +{ + void *p = mrb_pool_alloc(s->mpool, len); + + if (!p) codegen_error(s, "pool memory allocation"); + return p; +} + +static void* +codegen_malloc(codegen_scope *s, size_t len) +{ + void *p = mrb_malloc_simple(s->mrb, len); + + if (!p) codegen_error(s, "mrb_malloc"); + return p; +} + +static void* +codegen_realloc(codegen_scope *s, void *p, size_t len) +{ + p = mrb_realloc_simple(s->mrb, p, len); + + if (!p && len > 0) codegen_error(s, "mrb_realloc"); + return p; +} + +static int +new_label(codegen_scope *s) +{ + s->lastlabel = s->pc; + return s->pc; +} + +static inline int +genop(codegen_scope *s, mrb_code i) +{ + if (s->pc == s->icapa) { + s->icapa *= 2; + s->iseq = (mrb_code *)codegen_realloc(s, s->iseq, sizeof(mrb_code)*s->icapa); + if (s->lines) { + s->lines = (uint16_t*)codegen_realloc(s, s->lines, sizeof(short)*s->icapa); + s->irep->lines = s->lines; + } + } + s->iseq[s->pc] = i; + if (s->lines) { + s->lines[s->pc] = s->lineno; + } + return s->pc++; +} + +#define NOVAL 0 +#define VAL 1 + +static mrb_bool +no_optimize(codegen_scope *s) +{ + if (s && s->parser && s->parser->no_optimize) + return TRUE; + return FALSE; +} + +static int +genop_peep(codegen_scope *s, mrb_code i, int val) +{ + /* peephole optimization */ + if (!no_optimize(s) && s->lastlabel != s->pc && s->pc > 0) { + mrb_code i0 = s->iseq[s->pc-1]; + int c1 = GET_OPCODE(i); + int c0 = GET_OPCODE(i0); + + switch (c1) { + case OP_MOVE: + if (GETARG_A(i) == GETARG_B(i)) { + /* skip useless OP_MOVE */ + return 0; + } + if (val) break; + switch (c0) { + case OP_MOVE: + if (GETARG_A(i) == GETARG_A(i0)) { + /* skip overriden OP_MOVE */ + s->pc--; + s->iseq[s->pc] = i; + } + if (GETARG_B(i) == GETARG_A(i0) && GETARG_A(i) == GETARG_B(i0)) { + /* skip swapping OP_MOVE */ + return 0; + } + if (GETARG_B(i) == GETARG_A(i0) && GETARG_A(i0) >= s->nlocals) { + s->pc--; + return genop_peep(s, MKOP_AB(OP_MOVE, GETARG_A(i), GETARG_B(i0)), val); + } + break; + case OP_LOADI: + if (GETARG_B(i) == GETARG_A(i0) && GETARG_A(i0) >= s->nlocals) { + s->iseq[s->pc-1] = MKOP_AsBx(OP_LOADI, GETARG_A(i), GETARG_sBx(i0)); + return 0; + } + break; + case OP_ARRAY: + case OP_HASH: + case OP_RANGE: + case OP_AREF: + case OP_GETUPVAR: + if (GETARG_B(i) == GETARG_A(i0) && GETARG_A(i0) >= s->nlocals) { + s->iseq[s->pc-1] = MKOP_ABC(c0, GETARG_A(i), GETARG_B(i0), GETARG_C(i0)); + return 0; + } + break; + case OP_LOADSYM: + case OP_GETGLOBAL: + case OP_GETIV: + case OP_GETCV: + case OP_GETCONST: + case OP_GETSPECIAL: + case OP_LOADL: + case OP_STRING: + if (GETARG_B(i) == GETARG_A(i0) && GETARG_A(i0) >= s->nlocals) { + s->iseq[s->pc-1] = MKOP_ABx(c0, GETARG_A(i), GETARG_Bx(i0)); + return 0; + } + break; + case OP_SCLASS: + if (GETARG_B(i) == GETARG_A(i0) && GETARG_A(i0) >= s->nlocals) { + s->iseq[s->pc-1] = MKOP_AB(c0, GETARG_A(i), GETARG_B(i0)); + return 0; + } + break; + case OP_LOADNIL: + case OP_LOADSELF: + case OP_LOADT: + case OP_LOADF: + case OP_OCLASS: + if (GETARG_B(i) == GETARG_A(i0) && GETARG_A(i0) >= s->nlocals) { + s->iseq[s->pc-1] = MKOP_A(c0, GETARG_A(i)); + return 0; + } + break; + default: + break; + } + break; + case OP_SETIV: + case OP_SETCV: + case OP_SETCONST: + case OP_SETMCNST: + case OP_SETGLOBAL: + if (val) break; + if (c0 == OP_MOVE) { + if (GETARG_A(i) == GETARG_A(i0)) { + s->iseq[s->pc-1] = MKOP_ABx(c1, GETARG_B(i0), GETARG_Bx(i)); + return 0; + } + } + break; + case OP_SETUPVAR: + if (val) break; + if (c0 == OP_MOVE) { + if (GETARG_A(i) == GETARG_A(i0)) { + s->iseq[s->pc-1] = MKOP_ABC(c1, GETARG_B(i0), GETARG_B(i), GETARG_C(i)); + return 0; + } + } + break; + case OP_EPOP: + if (c0 == OP_EPOP) { + s->iseq[s->pc-1] = MKOP_A(OP_EPOP, GETARG_A(i0)+GETARG_A(i)); + return 0; + } + break; + case OP_POPERR: + if (c0 == OP_POPERR) { + s->iseq[s->pc-1] = MKOP_A(OP_POPERR, GETARG_A(i0)+GETARG_A(i)); + return 0; + } + break; + case OP_RETURN: + switch (c0) { + case OP_RETURN: + return 0; + case OP_MOVE: + if (GETARG_A(i0) >= s->nlocals) { + s->iseq[s->pc-1] = MKOP_AB(OP_RETURN, GETARG_B(i0), OP_R_NORMAL); + return 0; + } + break; + case OP_SETIV: + case OP_SETCV: + case OP_SETCONST: + case OP_SETMCNST: + case OP_SETUPVAR: + case OP_SETGLOBAL: + s->pc--; + genop_peep(s, i0, NOVAL); + i0 = s->iseq[s->pc-1]; + return genop(s, MKOP_AB(OP_RETURN, GETARG_A(i0), OP_R_NORMAL)); +#if 0 + case OP_SEND: + if (GETARG_B(i) == OP_R_NORMAL && GETARG_A(i) == GETARG_A(i0)) { + s->iseq[s->pc-1] = MKOP_ABC(OP_TAILCALL, GETARG_A(i0), GETARG_B(i0), GETARG_C(i0)); + return; + } + break; +#endif + default: + break; + } + break; + case OP_ADD: + case OP_SUB: + if (c0 == OP_LOADI) { + int c = GETARG_sBx(i0); + + if (c1 == OP_SUB) c = -c; + if (c > 127 || c < -127) break; + if (0 <= c) + s->iseq[s->pc-1] = MKOP_ABC(OP_ADDI, GETARG_A(i), GETARG_B(i), c); + else + s->iseq[s->pc-1] = MKOP_ABC(OP_SUBI, GETARG_A(i), GETARG_B(i), -c); + return 0; + } + case OP_STRCAT: + if (c0 == OP_STRING) { + mrb_value v = s->irep->pool[GETARG_Bx(i0)]; + + if (mrb_string_p(v) && RSTRING_LEN(v) == 0) { + s->pc--; + return 0; + } + } + if (c0 == OP_LOADNIL) { + if (GETARG_B(i) == GETARG_A(i0)) { + s->pc--; + return 0; + } + } + break; + case OP_JMPIF: + case OP_JMPNOT: + if (c0 == OP_MOVE && GETARG_A(i) == GETARG_A(i0)) { + s->iseq[s->pc-1] = MKOP_AsBx(c1, GETARG_B(i0), GETARG_sBx(i)); + return s->pc-1; + } + break; + default: + break; + } + } + return genop(s, i); +} + +static void +scope_error(codegen_scope *s) +{ + exit(EXIT_FAILURE); +} + +static inline void +dispatch(codegen_scope *s, int pc) +{ + int diff = s->pc - pc; + mrb_code i = s->iseq[pc]; + int c = GET_OPCODE(i); + + s->lastlabel = s->pc; + switch (c) { + case OP_JMP: + case OP_JMPIF: + case OP_JMPNOT: + case OP_ONERR: + break; + default: +#ifndef MRB_DISABLE_STDIO + fprintf(stderr, "bug: dispatch on non JMP op\n"); +#endif + scope_error(s); + break; + } + if (diff > MAXARG_sBx) { + codegen_error(s, "too distant jump address"); + } + s->iseq[pc] = MKOP_AsBx(c, GETARG_A(i), diff); +} + +static void +dispatch_linked(codegen_scope *s, int pc) +{ + mrb_code i; + int pos; + + if (!pc) return; + for (;;) { + i = s->iseq[pc]; + pos = GETARG_sBx(i); + dispatch(s, pc); + if (!pos) break; + pc = pos; + } +} + +#define nregs_update do {if (s->sp > s->nregs) s->nregs = s->sp;} while (0) +static void +push_(codegen_scope *s) +{ + if (s->sp > 511) { + codegen_error(s, "too complex expression"); + } + s->sp++; + nregs_update; +} + +static void +push_n_(codegen_scope *s, int n) +{ + if (s->sp+n > 511) { + codegen_error(s, "too complex expression"); + } + s->sp+=n; + nregs_update; +} + +#define push() push_(s) +#define push_n(n) push_n_(s,n) +#define pop_(s) ((s)->sp--) +#define pop() pop_(s) +#define pop_n(n) (s->sp-=(n)) +#define cursp() (s->sp) + +static inline int +new_lit(codegen_scope *s, mrb_value val) +{ + int i; + mrb_value *pv; + + switch (mrb_type(val)) { + case MRB_TT_STRING: + for (i=0; iirep->plen; i++) { + mrb_int len; + pv = &s->irep->pool[i]; + + if (mrb_type(*pv) != MRB_TT_STRING) continue; + if ((len = RSTRING_LEN(*pv)) != RSTRING_LEN(val)) continue; + if (memcmp(RSTRING_PTR(*pv), RSTRING_PTR(val), len) == 0) + return i; + } + break; + case MRB_TT_FLOAT: + for (i=0; iirep->plen; i++) { + pv = &s->irep->pool[i]; + if (mrb_type(*pv) != MRB_TT_FLOAT) continue; + if (mrb_float(*pv) == mrb_float(val)) return i; + } + break; + case MRB_TT_FIXNUM: + for (i=0; iirep->plen; i++) { + pv = &s->irep->pool[i]; + if (!mrb_fixnum_p(*pv)) continue; + if (mrb_fixnum(*pv) == mrb_fixnum(val)) return i; + } + break; + default: + /* should not happen */ + return 0; + } + + if (s->irep->plen == s->pcapa) { + s->pcapa *= 2; + s->irep->pool = (mrb_value *)codegen_realloc(s, s->irep->pool, sizeof(mrb_value)*s->pcapa); + } + + pv = &s->irep->pool[s->irep->plen]; + i = s->irep->plen++; + + switch (mrb_type(val)) { + case MRB_TT_STRING: + *pv = mrb_str_pool(s->mrb, val); + break; + + case MRB_TT_FLOAT: +#ifdef MRB_WORD_BOXING + *pv = mrb_float_pool(s->mrb, mrb_float(val)); + break; +#endif + case MRB_TT_FIXNUM: + *pv = val; + break; + + default: + /* should not happen */ + break; + } + return i; +} + +/* method symbols should be fit in 9 bits */ +#define MAXMSYMLEN 512 +/* maximum symbol numbers */ +#define MAXSYMLEN 65536 + +static int +new_msym(codegen_scope *s, mrb_sym sym) +{ + int i, len; + + mrb_assert(s->irep); + + len = s->irep->slen; + if (len > MAXMSYMLEN) len = MAXMSYMLEN; + for (i=0; iirep->syms[i] == sym) return i; + if (s->irep->syms[i] == 0) break; + } + if (i == MAXMSYMLEN) { + codegen_error(s, "too many symbols (max " MRB_STRINGIZE(MAXMSYMLEN) ")"); + } + s->irep->syms[i] = sym; + if (i == s->irep->slen) s->irep->slen++; + return i; +} + +static int +new_sym(codegen_scope *s, mrb_sym sym) +{ + int i; + + for (i=0; iirep->slen; i++) { + if (s->irep->syms[i] == sym) return i; + } + if (s->irep->slen == MAXSYMLEN) { + codegen_error(s, "too many symbols (max " MRB_STRINGIZE(MAXSYMLEN) ")"); + } + + if (s->irep->slen > MAXMSYMLEN/2 && s->scapa == MAXMSYMLEN) { + s->scapa = MAXSYMLEN; + s->irep->syms = (mrb_sym *)codegen_realloc(s, s->irep->syms, sizeof(mrb_sym)*MAXSYMLEN); + for (i = s->irep->slen; i < MAXMSYMLEN; i++) { + static const mrb_sym mrb_sym_zero = { 0 }; + s->irep->syms[i] = mrb_sym_zero; + } + s->irep->slen = MAXMSYMLEN; + } + s->irep->syms[s->irep->slen] = sym; + return s->irep->slen++; +} + +static int +node_len(node *tree) +{ + int n = 0; + + while (tree) { + n++; + tree = tree->cdr; + } + return n; +} + +#define nsym(x) ((mrb_sym)(intptr_t)(x)) +#define lv_name(lv) nsym((lv)->car) +static int +lv_idx(codegen_scope *s, mrb_sym id) +{ + node *lv = s->lv; + int n = 1; + + while (lv) { + if (lv_name(lv) == id) return n; + n++; + lv = lv->cdr; + } + return 0; +} + +static void +for_body(codegen_scope *s, node *tree) +{ + codegen_scope *prev = s; + int idx; + struct loopinfo *lp; + node *n2; + mrb_code c; + + /* generate receiver */ + codegen(s, tree->cdr->car, VAL); + /* generate loop-block */ + s = scope_new(s->mrb, s, NULL); + if (s == NULL) { + raise_error(prev, "unexpected scope"); + } + + push(); /* push for a block parameter */ + + /* generate loop variable */ + n2 = tree->car; + genop(s, MKOP_Ax(OP_ENTER, 0x40000)); + if (n2->car && !n2->car->cdr && !n2->cdr) { + gen_assignment(s, n2->car->car, 1, NOVAL); + } + else { + gen_vmassignment(s, n2, 1, VAL); + } + /* construct loop */ + lp = loop_push(s, LOOP_FOR); + lp->pc2 = new_label(s); + + /* loop body */ + codegen(s, tree->cdr->cdr->car, VAL); + pop(); + if (s->pc > 0) { + c = s->iseq[s->pc-1]; + if (GET_OPCODE(c) != OP_RETURN || GETARG_B(c) != OP_R_NORMAL || s->pc == s->lastlabel) + genop_peep(s, MKOP_AB(OP_RETURN, cursp(), OP_R_NORMAL), NOVAL); + } + loop_pop(s, NOVAL); + scope_finish(s); + s = prev; + genop(s, MKOP_Abc(OP_LAMBDA, cursp(), s->irep->rlen-1, OP_L_BLOCK)); + push();pop(); /* space for a block */ + pop(); + idx = new_msym(s, mrb_intern_lit(s->mrb, "each")); + genop(s, MKOP_ABC(OP_SENDB, cursp(), idx, 0)); +} + +static int +lambda_body(codegen_scope *s, node *tree, int blk) +{ + mrb_code c; + codegen_scope *parent = s; + s = scope_new(s->mrb, s, tree->car); + if (s == NULL) { + raise_error(parent, "unexpected scope"); + } + + s->mscope = !blk; + + if (blk) { + struct loopinfo *lp = loop_push(s, LOOP_BLOCK); + lp->pc1 = new_label(s); + } + tree = tree->cdr; + if (tree->car) { + mrb_aspec a; + int ma, oa, ra, pa, ka, kd, ba; + int pos, i; + node *n, *opt; + + ma = node_len(tree->car->car); + n = tree->car->car; + while (n) { + n = n->cdr; + } + oa = node_len(tree->car->cdr->car); + ra = tree->car->cdr->cdr->car ? 1 : 0; + pa = node_len(tree->car->cdr->cdr->cdr->car); + ka = kd = 0; + ba = tree->car->cdr->cdr->cdr->cdr ? 1 : 0; + + if (ma > 0x1f || oa > 0x1f || pa > 0x1f || ka > 0x1f) { + codegen_error(s, "too many formal arguments"); + } + a = ((mrb_aspec)(ma & 0x1f) << 18) + | ((mrb_aspec)(oa & 0x1f) << 13) + | ((ra & 1) << 12) + | ((pa & 0x1f) << 7) + | ((ka & 0x1f) << 2) + | ((kd & 1)<< 1) + | (ba & 1); + s->ainfo = (((ma+oa) & 0x3f) << 6) /* (12bits = 6:1:5) */ + | ((ra & 1) << 5) + | (pa & 0x1f); + genop(s, MKOP_Ax(OP_ENTER, a)); + pos = new_label(s); + for (i=0; i 0) { + genop(s, MKOP_sBx(OP_JMP, 0)); + } + opt = tree->car->cdr->car; + i = 0; + while (opt) { + int idx; + + dispatch(s, pos+i); + codegen(s, opt->car->cdr, VAL); + idx = lv_idx(s, nsym(opt->car->car)); + pop(); + genop_peep(s, MKOP_AB(OP_MOVE, idx, cursp()), NOVAL); + i++; + opt = opt->cdr; + } + if (oa > 0) { + dispatch(s, pos+i); + } + } + codegen(s, tree->cdr->car, VAL); + pop(); + if (s->pc > 0) { + c = s->iseq[s->pc-1]; + if (GET_OPCODE(c) != OP_RETURN || GETARG_B(c) != OP_R_NORMAL || s->pc == s->lastlabel) { + if (s->nregs == 0) { + genop(s, MKOP_A(OP_LOADNIL, 0)); + genop(s, MKOP_AB(OP_RETURN, 0, OP_R_NORMAL)); + } + else { + genop_peep(s, MKOP_AB(OP_RETURN, cursp(), OP_R_NORMAL), NOVAL); + } + } + } + if (blk) { + loop_pop(s, NOVAL); + } + scope_finish(s); + return parent->irep->rlen - 1; +} + +static int +scope_body(codegen_scope *s, node *tree, int val) +{ + codegen_scope *scope = scope_new(s->mrb, s, tree->car); + if (scope == NULL) { + raise_error(s, "unexpected scope"); + } + + codegen(scope, tree->cdr, VAL); + if (!s->iseq) { + genop(scope, MKOP_A(OP_STOP, 0)); + } + else if (!val) { + genop(scope, MKOP_AB(OP_RETURN, 0, OP_R_NORMAL)); + } + else { + if (scope->nregs == 0) { + genop(scope, MKOP_A(OP_LOADNIL, 0)); + genop(scope, MKOP_AB(OP_RETURN, 0, OP_R_NORMAL)); + } + else { + genop_peep(scope, MKOP_AB(OP_RETURN, scope->sp-1, OP_R_NORMAL), NOVAL); + } + } + scope_finish(scope); + if (!s->irep) { + /* should not happen */ + return 0; + } + return s->irep->rlen - 1; +} + +#define nint(x) ((int)(intptr_t)(x)) +#define nchar(x) ((char)(intptr_t)(x)) + +static mrb_bool +nosplat(node *t) +{ + while (t) { + if (nint(t->car->car) == NODE_SPLAT) return FALSE; + t = t->cdr; + } + return TRUE; +} + +static mrb_sym +attrsym(codegen_scope *s, mrb_sym a) +{ + const char *name; + mrb_int len; + char *name2; + + name = mrb_sym2name_len(s->mrb, a, &len); + name2 = (char *)codegen_palloc(s, + (size_t)len + + 1 /* '=' */ + + 1 /* '\0' */ + ); + mrb_assert_int_fit(mrb_int, len, size_t, SIZE_MAX); + memcpy(name2, name, (size_t)len); + name2[len] = '='; + name2[len+1] = '\0'; + + return mrb_intern(s->mrb, name2, len+1); +} + +#define CALL_MAXARGS 127 + +static int +gen_values(codegen_scope *s, node *t, int val, int extra) +{ + int n = 0; + int is_splat; + + while (t) { + is_splat = nint(t->car->car) == NODE_SPLAT; /* splat mode */ + if ( + n+extra >= CALL_MAXARGS - 1 /* need to subtract one because vm.c expects an array if n == CALL_MAXARGS */ + || is_splat) { + if (val) { + if (is_splat && n == 0 && nint(t->car->cdr->car) == NODE_ARRAY) { + codegen(s, t->car->cdr, VAL); + pop(); + } + else { + pop_n(n); + genop(s, MKOP_ABC(OP_ARRAY, cursp(), cursp(), n)); + push(); + codegen(s, t->car, VAL); + pop(); pop(); + if (is_splat) { + genop(s, MKOP_AB(OP_ARYCAT, cursp(), cursp()+1)); + } + else { + genop(s, MKOP_AB(OP_ARYPUSH, cursp(), cursp()+1)); + } + } + t = t->cdr; + while (t) { + push(); + codegen(s, t->car, VAL); + pop(); pop(); + if (nint(t->car->car) == NODE_SPLAT) { + genop(s, MKOP_AB(OP_ARYCAT, cursp(), cursp()+1)); + } + else { + genop(s, MKOP_AB(OP_ARYPUSH, cursp(), cursp()+1)); + } + t = t->cdr; + } + } + else { + while (t) { + codegen(s, t->car, NOVAL); + t = t->cdr; + } + } + return -1; + } + /* normal (no splat) mode */ + codegen(s, t->car, val); + n++; + t = t->cdr; + } + return n; +} + +static void +gen_call(codegen_scope *s, node *tree, mrb_sym name, int sp, int val, int safe) +{ + mrb_sym sym = name ? name : nsym(tree->cdr->car); + int idx, skip = 0; + int n = 0, noop = 0, sendv = 0, blk = 0; + + codegen(s, tree->car, VAL); /* receiver */ + if (safe) { + int recv = cursp()-1; + genop(s, MKOP_A(OP_LOADNIL, cursp())); + push(); + genop(s, MKOP_AB(OP_MOVE, cursp(), recv)); + push_n(2); pop_n(2); /* space for one arg and a block */ + pop(); + idx = new_msym(s, mrb_intern_lit(s->mrb, "==")); + genop(s, MKOP_ABC(OP_EQ, cursp(), idx, 1)); + skip = genop(s, MKOP_AsBx(OP_JMPIF, cursp(), 0)); + } + idx = new_msym(s, sym); + tree = tree->cdr->cdr->car; + if (tree) { + n = gen_values(s, tree->car, VAL, sp?1:0); + if (n < 0) { + n = noop = sendv = 1; + push(); + } + } + if (sp) { + if (sendv) { + pop(); + genop(s, MKOP_AB(OP_ARYPUSH, cursp(), sp)); + push(); + } + else { + genop(s, MKOP_AB(OP_MOVE, cursp(), sp)); + push(); + n++; + } + } + if (tree && tree->cdr) { + noop = 1; + codegen(s, tree->cdr, VAL); + pop(); + } + else { + blk = cursp(); + } + push();pop(); + pop_n(n+1); + { + mrb_int symlen; + const char *symname = mrb_sym2name_len(s->mrb, sym, &symlen); + + if (!noop && symlen == 1 && symname[0] == '+' && n == 1) { + genop_peep(s, MKOP_ABC(OP_ADD, cursp(), idx, n), val); + } + else if (!noop && symlen == 1 && symname[0] == '-' && n == 1) { + genop_peep(s, MKOP_ABC(OP_SUB, cursp(), idx, n), val); + } + else if (!noop && symlen == 1 && symname[0] == '*' && n == 1) { + genop(s, MKOP_ABC(OP_MUL, cursp(), idx, n)); + } + else if (!noop && symlen == 1 && symname[0] == '/' && n == 1) { + genop(s, MKOP_ABC(OP_DIV, cursp(), idx, n)); + } + else if (!noop && symlen == 1 && symname[0] == '<' && n == 1) { + genop(s, MKOP_ABC(OP_LT, cursp(), idx, n)); + } + else if (!noop && symlen == 2 && symname[0] == '<' && symname[1] == '=' && n == 1) { + genop(s, MKOP_ABC(OP_LE, cursp(), idx, n)); + } + else if (!noop && symlen == 1 && symname[0] == '>' && n == 1) { + genop(s, MKOP_ABC(OP_GT, cursp(), idx, n)); + } + else if (!noop && symlen == 2 && symname[0] == '>' && symname[1] == '=' && n == 1) { + genop(s, MKOP_ABC(OP_GE, cursp(), idx, n)); + } + else if (!noop && symlen == 2 && symname[0] == '=' && symname[1] == '=' && n == 1) { + genop(s, MKOP_ABC(OP_EQ, cursp(), idx, n)); + } + else { + if (sendv) n = CALL_MAXARGS; + if (blk > 0) { /* no block */ + genop(s, MKOP_ABC(OP_SEND, cursp(), idx, n)); + } + else { + genop(s, MKOP_ABC(OP_SENDB, cursp(), idx, n)); + } + } + } + if (safe) { + dispatch(s, skip); + } + if (val) { + push(); + } +} + +static void +gen_assignment(codegen_scope *s, node *tree, int sp, int val) +{ + int idx; + int type = nint(tree->car); + + tree = tree->cdr; + switch (type) { + case NODE_GVAR: + idx = new_sym(s, nsym(tree)); + genop_peep(s, MKOP_ABx(OP_SETGLOBAL, sp, idx), val); + break; + case NODE_LVAR: + idx = lv_idx(s, nsym(tree)); + if (idx > 0) { + if (idx != sp) { + genop_peep(s, MKOP_AB(OP_MOVE, idx, sp), val); + } + break; + } + else { /* upvar */ + int lv = 0; + codegen_scope *up = s->prev; + + while (up) { + idx = lv_idx(up, nsym(tree)); + if (idx > 0) { + genop_peep(s, MKOP_ABC(OP_SETUPVAR, sp, idx, lv), val); + break; + } + lv++; + up = up->prev; + } + } + break; + case NODE_IVAR: + idx = new_sym(s, nsym(tree)); + genop_peep(s, MKOP_ABx(OP_SETIV, sp, idx), val); + break; + case NODE_CVAR: + idx = new_sym(s, nsym(tree)); + genop_peep(s, MKOP_ABx(OP_SETCV, sp, idx), val); + break; + case NODE_CONST: + idx = new_sym(s, nsym(tree)); + genop_peep(s, MKOP_ABx(OP_SETCONST, sp, idx), val); + break; + case NODE_COLON2: + idx = new_sym(s, nsym(tree->cdr)); + genop_peep(s, MKOP_AB(OP_MOVE, cursp(), sp), NOVAL); + push(); + codegen(s, tree->car, VAL); + pop_n(2); + genop_peep(s, MKOP_ABx(OP_SETMCNST, cursp(), idx), val); + break; + + case NODE_CALL: + case NODE_SCALL: + push(); + gen_call(s, tree, attrsym(s, nsym(tree->cdr->car)), sp, NOVAL, + type == NODE_SCALL); + pop(); + if (val) { + genop_peep(s, MKOP_AB(OP_MOVE, cursp(), sp), val); + } + break; + + case NODE_MASGN: + gen_vmassignment(s, tree->car, sp, val); + break; + + /* splat without assignment */ + case NODE_NIL: + break; + + default: +#ifndef MRB_DISABLE_STDIO + fprintf(stderr, "unknown lhs %d\n", type); +#endif + break; + } + if (val) push(); +} + +static void +gen_vmassignment(codegen_scope *s, node *tree, int rhs, int val) +{ + int n = 0, post = 0; + node *t, *p; + + if (tree->car) { /* pre */ + t = tree->car; + n = 0; + while (t) { + genop(s, MKOP_ABC(OP_AREF, cursp(), rhs, n)); + gen_assignment(s, t->car, cursp(), NOVAL); + n++; + t = t->cdr; + } + } + t = tree->cdr; + if (t) { + if (t->cdr) { /* post count */ + p = t->cdr->car; + while (p) { + post++; + p = p->cdr; + } + } + if (val) { + genop(s, MKOP_AB(OP_MOVE, cursp(), rhs)); + } + else { + pop(); + } + push_n(post); + pop_n(post); + genop(s, MKOP_ABC(OP_APOST, cursp(), n, post)); + n = 1; + if (t->car) { /* rest */ + gen_assignment(s, t->car, cursp(), NOVAL); + } + if (t->cdr && t->cdr->car) { + t = t->cdr->car; + while (t) { + gen_assignment(s, t->car, cursp()+n, NOVAL); + t = t->cdr; + n++; + } + } + if (!val) { + push(); + } + } +} + +static void +gen_send_intern(codegen_scope *s) +{ + push();pop(); /* space for a block */ + pop(); + genop(s, MKOP_ABC(OP_SEND, cursp(), new_msym(s, mrb_intern_lit(s->mrb, "intern")), 0)); + push(); +} +static void +gen_literal_array(codegen_scope *s, node *tree, mrb_bool sym, int val) +{ + if (val) { + int i = 0, j = 0; + + while (tree) { + switch (nint(tree->car->car)) { + case NODE_STR: + if ((tree->cdr == NULL) && (nint(tree->car->cdr->cdr) == 0)) + break; + /* fall through */ + case NODE_BEGIN: + codegen(s, tree->car, VAL); + ++j; + break; + + case NODE_LITERAL_DELIM: + if (j > 0) { + j = 0; + ++i; + if (sym) + gen_send_intern(s); + } + break; + } + if (j >= 2) { + pop(); pop(); + genop_peep(s, MKOP_AB(OP_STRCAT, cursp(), cursp()+1), VAL); + push(); + j = 1; + } + tree = tree->cdr; + } + if (j > 0) { + ++i; + if (sym) + gen_send_intern(s); + } + pop_n(i); + genop(s, MKOP_ABC(OP_ARRAY, cursp(), cursp(), i)); + push(); + } + else { + while (tree) { + switch (nint(tree->car->car)) { + case NODE_BEGIN: case NODE_BLOCK: + codegen(s, tree->car, NOVAL); + } + tree = tree->cdr; + } + } +} + +static void +raise_error(codegen_scope *s, const char *msg) +{ + int idx = new_lit(s, mrb_str_new_cstr(s->mrb, msg)); + + genop(s, MKOP_ABx(OP_ERR, 1, idx)); +} + +static double +readint_float(codegen_scope *s, const char *p, int base) +{ + const char *e = p + strlen(p); + double f = 0; + int n; + + if (*p == '+') p++; + while (p < e) { + char c = *p; + c = tolower((unsigned char)c); + for (n=0; n= 2 && base <= 36); + if (*p == '+') p++; + while (p < e) { + char c = *p; + c = tolower((unsigned char)c); + for (n=0; n result) { + *overflow = TRUE; + return 0; + } + result *= base; + result -= n; + } + else { + if ((MRB_INT_MAX - n)/base < result) { + *overflow = TRUE; + return 0; + } + result *= base; + result += n; + } + p++; + } + *overflow = FALSE; + return result; +} + +static void +gen_retval(codegen_scope *s, node *tree) +{ + if (nint(tree->car) == NODE_SPLAT) { + genop(s, MKOP_ABC(OP_ARRAY, cursp(), cursp(), 0)); + push(); + codegen(s, tree, VAL); + pop(); pop(); + genop(s, MKOP_AB(OP_ARYCAT, cursp(), cursp()+1)); + } + else { + codegen(s, tree, VAL); + pop(); + } +} + +static void +codegen(codegen_scope *s, node *tree, int val) +{ + int nt; + int rlev = s->rlev; + + if (!tree) { + if (val) { + genop(s, MKOP_A(OP_LOADNIL, cursp())); + push(); + } + return; + } + + s->rlev++; + if (s->rlev > MRB_CODEGEN_LEVEL_MAX) { + codegen_error(s, "too complex expression"); + } + if (s->irep && s->filename_index != tree->filename_index) { + s->irep->filename = mrb_parser_get_filename(s->parser, s->filename_index); + mrb_debug_info_append_file(s->mrb, s->irep, s->debug_start_pos, s->pc); + s->debug_start_pos = s->pc; + s->filename_index = tree->filename_index; + s->filename = mrb_parser_get_filename(s->parser, tree->filename_index); + } + + nt = nint(tree->car); + s->lineno = tree->lineno; + tree = tree->cdr; + switch (nt) { + case NODE_BEGIN: + if (val && !tree) { + genop(s, MKOP_A(OP_LOADNIL, cursp())); + push(); + } + while (tree) { + codegen(s, tree->car, tree->cdr ? NOVAL : val); + tree = tree->cdr; + } + break; + + case NODE_RESCUE: + { + int onerr, noexc, exend, pos1, pos2, tmp; + struct loopinfo *lp; + + if (tree->car == NULL) goto exit; + onerr = genop(s, MKOP_Bx(OP_ONERR, 0)); + lp = loop_push(s, LOOP_BEGIN); + lp->pc1 = onerr; + codegen(s, tree->car, VAL); + pop(); + lp->type = LOOP_RESCUE; + noexc = genop(s, MKOP_Bx(OP_JMP, 0)); + dispatch(s, onerr); + tree = tree->cdr; + exend = 0; + pos1 = 0; + if (tree->car) { + node *n2 = tree->car; + int exc = cursp(); + + genop(s, MKOP_ABC(OP_RESCUE, exc, 0, 0)); + push(); + while (n2) { + node *n3 = n2->car; + node *n4 = n3->car; + + if (pos1) dispatch(s, pos1); + pos2 = 0; + do { + if (n4 && n4->car && nint(n4->car->car) == NODE_SPLAT) { + codegen(s, n4->car, VAL); + genop(s, MKOP_AB(OP_MOVE, cursp(), exc)); + push_n(2); pop_n(2); /* space for one arg and a block */ + pop(); + genop(s, MKOP_ABC(OP_SEND, cursp(), new_msym(s, mrb_intern_lit(s->mrb, "__case_eqq")), 1)); + } + else { + if (n4) { + codegen(s, n4->car, VAL); + } + else { + genop(s, MKOP_ABx(OP_GETCONST, cursp(), new_msym(s, mrb_intern_lit(s->mrb, "StandardError")))); + push(); + } + pop(); + genop(s, MKOP_ABC(OP_RESCUE, exc, cursp(), 1)); + } + tmp = genop(s, MKOP_AsBx(OP_JMPIF, cursp(), pos2)); + pos2 = tmp; + if (n4) { + n4 = n4->cdr; + } + } while (n4); + pos1 = genop(s, MKOP_sBx(OP_JMP, 0)); + dispatch_linked(s, pos2); + + pop(); + if (n3->cdr->car) { + gen_assignment(s, n3->cdr->car, exc, NOVAL); + } + if (n3->cdr->cdr->car) { + codegen(s, n3->cdr->cdr->car, val); + if (val) pop(); + } + tmp = genop(s, MKOP_sBx(OP_JMP, exend)); + exend = tmp; + n2 = n2->cdr; + push(); + } + if (pos1) { + dispatch(s, pos1); + genop(s, MKOP_A(OP_RAISE, exc)); + } + } + pop(); + tree = tree->cdr; + dispatch(s, noexc); + genop(s, MKOP_A(OP_POPERR, 1)); + if (tree->car) { + codegen(s, tree->car, val); + } + else if (val) { + push(); + } + dispatch_linked(s, exend); + loop_pop(s, NOVAL); + } + break; + + case NODE_ENSURE: + if (!tree->cdr || !tree->cdr->cdr || + (nint(tree->cdr->cdr->car) == NODE_BEGIN && + tree->cdr->cdr->cdr)) { + int idx; + int epush = s->pc; + + genop(s, MKOP_Bx(OP_EPUSH, 0)); + s->ensure_level++; + codegen(s, tree->car, val); + idx = scope_body(s, tree->cdr, NOVAL); + s->iseq[epush] = MKOP_Bx(OP_EPUSH, idx); + s->ensure_level--; + genop_peep(s, MKOP_A(OP_EPOP, 1), NOVAL); + } + else { /* empty ensure ignored */ + codegen(s, tree->car, val); + } + break; + + case NODE_LAMBDA: + if (val) { + int idx = lambda_body(s, tree, 1); + + genop(s, MKOP_Abc(OP_LAMBDA, cursp(), idx, OP_L_LAMBDA)); + push(); + } + break; + + case NODE_BLOCK: + if (val) { + int idx = lambda_body(s, tree, 1); + + genop(s, MKOP_Abc(OP_LAMBDA, cursp(), idx, OP_L_BLOCK)); + push(); + } + break; + + case NODE_IF: + { + int pos1, pos2; + node *e = tree->cdr->cdr->car; + + if (!tree->car) { + codegen(s, e, val); + goto exit; + } + switch (nint(tree->car->car)) { + case NODE_TRUE: + case NODE_INT: + case NODE_STR: + codegen(s, tree->cdr->car, val); + goto exit; + case NODE_FALSE: + case NODE_NIL: + codegen(s, e, val); + goto exit; + } + codegen(s, tree->car, VAL); + pop(); + pos1 = genop_peep(s, MKOP_AsBx(OP_JMPNOT, cursp(), 0), NOVAL); + + codegen(s, tree->cdr->car, val); + if (e) { + if (val) pop(); + pos2 = genop(s, MKOP_sBx(OP_JMP, 0)); + dispatch(s, pos1); + codegen(s, e, val); + dispatch(s, pos2); + } + else { + if (val) { + pop(); + pos2 = genop(s, MKOP_sBx(OP_JMP, 0)); + dispatch(s, pos1); + genop(s, MKOP_A(OP_LOADNIL, cursp())); + dispatch(s, pos2); + push(); + } + else { + dispatch(s, pos1); + } + } + } + break; + + case NODE_AND: + { + int pos; + + codegen(s, tree->car, VAL); + pop(); + pos = genop(s, MKOP_AsBx(OP_JMPNOT, cursp(), 0)); + codegen(s, tree->cdr, val); + dispatch(s, pos); + } + break; + + case NODE_OR: + { + int pos; + + codegen(s, tree->car, VAL); + pop(); + pos = genop(s, MKOP_AsBx(OP_JMPIF, cursp(), 0)); + codegen(s, tree->cdr, val); + dispatch(s, pos); + } + break; + + case NODE_WHILE: + { + struct loopinfo *lp = loop_push(s, LOOP_NORMAL); + + lp->pc1 = genop(s, MKOP_sBx(OP_JMP, 0)); + lp->pc2 = new_label(s); + codegen(s, tree->cdr, NOVAL); + dispatch(s, lp->pc1); + codegen(s, tree->car, VAL); + pop(); + genop(s, MKOP_AsBx(OP_JMPIF, cursp(), lp->pc2 - s->pc)); + + loop_pop(s, val); + } + break; + + case NODE_UNTIL: + { + struct loopinfo *lp = loop_push(s, LOOP_NORMAL); + + lp->pc1 = genop(s, MKOP_sBx(OP_JMP, 0)); + lp->pc2 = new_label(s); + codegen(s, tree->cdr, NOVAL); + dispatch(s, lp->pc1); + codegen(s, tree->car, VAL); + pop(); + genop(s, MKOP_AsBx(OP_JMPNOT, cursp(), lp->pc2 - s->pc)); + + loop_pop(s, val); + } + break; + + case NODE_FOR: + for_body(s, tree); + if (val) push(); + break; + + case NODE_CASE: + { + int head = 0; + int pos1, pos2, pos3, tmp; + node *n; + + pos3 = 0; + if (tree->car) { + head = cursp(); + codegen(s, tree->car, VAL); + } + tree = tree->cdr; + while (tree) { + n = tree->car->car; + pos1 = pos2 = 0; + while (n) { + codegen(s, n->car, VAL); + if (head) { + genop(s, MKOP_AB(OP_MOVE, cursp(), head)); + push_n(2); pop_n(2); /* space for one arg and a block */ + pop(); + if (nint(n->car->car) == NODE_SPLAT) { + genop(s, MKOP_ABC(OP_SEND, cursp(), new_msym(s, mrb_intern_lit(s->mrb, "__case_eqq")), 1)); + } + else { + genop(s, MKOP_ABC(OP_SEND, cursp(), new_msym(s, mrb_intern_lit(s->mrb, "===")), 1)); + } + } + else { + pop(); + } + tmp = genop(s, MKOP_AsBx(OP_JMPIF, cursp(), pos2)); + pos2 = tmp; + n = n->cdr; + } + if (tree->car->car) { + pos1 = genop(s, MKOP_sBx(OP_JMP, 0)); + dispatch_linked(s, pos2); + } + codegen(s, tree->car->cdr, val); + if (val) pop(); + tmp = genop(s, MKOP_sBx(OP_JMP, pos3)); + pos3 = tmp; + if (pos1) dispatch(s, pos1); + tree = tree->cdr; + } + if (val) { + int pos = cursp(); + genop(s, MKOP_A(OP_LOADNIL, cursp())); + if (pos3) dispatch_linked(s, pos3); + if (head) pop(); + if (cursp() != pos) { + genop(s, MKOP_AB(OP_MOVE, cursp(), pos)); + } + push(); + } + else { + if (pos3) { + dispatch_linked(s, pos3); + } + if (head) { + pop(); + } + } + } + break; + + case NODE_SCOPE: + scope_body(s, tree, NOVAL); + break; + + case NODE_FCALL: + case NODE_CALL: + gen_call(s, tree, 0, 0, val, 0); + break; + case NODE_SCALL: + gen_call(s, tree, 0, 0, val, 1); + break; + + case NODE_DOT2: + codegen(s, tree->car, val); + codegen(s, tree->cdr, val); + if (val) { + pop(); pop(); + genop(s, MKOP_ABC(OP_RANGE, cursp(), cursp(), FALSE)); + push(); + } + break; + + case NODE_DOT3: + codegen(s, tree->car, val); + codegen(s, tree->cdr, val); + if (val) { + pop(); pop(); + genop(s, MKOP_ABC(OP_RANGE, cursp(), cursp(), TRUE)); + push(); + } + break; + + case NODE_COLON2: + { + int sym = new_sym(s, nsym(tree->cdr)); + + codegen(s, tree->car, VAL); + pop(); + genop(s, MKOP_ABx(OP_GETMCNST, cursp(), sym)); + if (val) push(); + } + break; + + case NODE_COLON3: + { + int sym = new_sym(s, nsym(tree)); + + genop(s, MKOP_A(OP_OCLASS, cursp())); + genop(s, MKOP_ABx(OP_GETMCNST, cursp(), sym)); + if (val) push(); + } + break; + + case NODE_ARRAY: + { + int n; + + n = gen_values(s, tree, val, 0); + if (n >= 0) { + if (val) { + pop_n(n); + genop(s, MKOP_ABC(OP_ARRAY, cursp(), cursp(), n)); + push(); + } + } + else if (val) { + push(); + } + } + break; + + case NODE_HASH: + { + int len = 0; + mrb_bool update = FALSE; + + while (tree) { + codegen(s, tree->car->car, val); + codegen(s, tree->car->cdr, val); + len++; + tree = tree->cdr; + if (val && len == 126) { + pop_n(len*2); + genop(s, MKOP_ABC(OP_HASH, cursp(), cursp(), len)); + if (update) { + pop(); + genop(s, MKOP_ABC(OP_SEND, cursp(), new_msym(s, mrb_intern_lit(s->mrb, "__update")), 1)); + } + push(); + update = TRUE; + len = 0; + } + } + if (val) { + pop_n(len*2); + genop(s, MKOP_ABC(OP_HASH, cursp(), cursp(), len)); + if (update) { + pop(); + genop(s, MKOP_ABC(OP_SEND, cursp(), new_msym(s, mrb_intern_lit(s->mrb, "__update")), 1)); + } + push(); + } + } + break; + + case NODE_SPLAT: + codegen(s, tree, val); + break; + + case NODE_ASGN: + codegen(s, tree->cdr, VAL); + pop(); + gen_assignment(s, tree->car, cursp(), val); + break; + + case NODE_MASGN: + { + int len = 0, n = 0, post = 0; + node *t = tree->cdr, *p; + int rhs = cursp(); + + if (nint(t->car) == NODE_ARRAY && t->cdr && nosplat(t->cdr)) { + /* fixed rhs */ + t = t->cdr; + while (t) { + codegen(s, t->car, VAL); + len++; + t = t->cdr; + } + tree = tree->car; + if (tree->car) { /* pre */ + t = tree->car; + n = 0; + while (t) { + if (n < len) { + gen_assignment(s, t->car, rhs+n, NOVAL); + n++; + } + else { + genop(s, MKOP_A(OP_LOADNIL, rhs+n)); + gen_assignment(s, t->car, rhs+n, NOVAL); + } + t = t->cdr; + } + } + t = tree->cdr; + if (t) { + if (t->cdr) { /* post count */ + p = t->cdr->car; + while (p) { + post++; + p = p->cdr; + } + } + if (t->car) { /* rest (len - pre - post) */ + int rn; + + if (len < post + n) { + rn = 0; + } + else { + rn = len - post - n; + } + genop(s, MKOP_ABC(OP_ARRAY, cursp(), rhs+n, rn)); + gen_assignment(s, t->car, cursp(), NOVAL); + n += rn; + } + if (t->cdr && t->cdr->car) { + t = t->cdr->car; + while (ncar, rhs+n, NOVAL); + t = t->cdr; + n++; + } + } + } + pop_n(len); + if (val) { + genop(s, MKOP_ABC(OP_ARRAY, rhs, rhs, len)); + push(); + } + } + else { + /* variable rhs */ + codegen(s, t, VAL); + gen_vmassignment(s, tree->car, rhs, val); + if (!val) { + pop(); + } + } + } + break; + + case NODE_OP_ASGN: + { + mrb_sym sym = nsym(tree->cdr->car); + mrb_int len; + const char *name = mrb_sym2name_len(s->mrb, sym, &len); + int idx, callargs = -1, vsp = -1; + + if ((len == 2 && name[0] == '|' && name[1] == '|') && + (nint(tree->car->car) == NODE_CONST || + nint(tree->car->car) == NODE_CVAR)) { + int onerr, noexc, exc; + struct loopinfo *lp; + + onerr = genop(s, MKOP_Bx(OP_ONERR, 0)); + lp = loop_push(s, LOOP_BEGIN); + lp->pc1 = onerr; + exc = cursp(); + codegen(s, tree->car, VAL); + lp->type = LOOP_RESCUE; + genop(s, MKOP_A(OP_POPERR, 1)); + noexc = genop(s, MKOP_Bx(OP_JMP, 0)); + dispatch(s, onerr); + genop(s, MKOP_ABC(OP_RESCUE, exc, 0, 0)); + genop(s, MKOP_A(OP_LOADF, exc)); + dispatch(s, noexc); + loop_pop(s, NOVAL); + } + else if (nint(tree->car->car) == NODE_CALL) { + node *n = tree->car->cdr; + int base, i, nargs = 0; + callargs = 0; + + if (val) { + vsp = cursp(); + push(); + } + codegen(s, n->car, VAL); /* receiver */ + idx = new_msym(s, nsym(n->cdr->car)); + base = cursp()-1; + if (n->cdr->cdr->car) { + nargs = gen_values(s, n->cdr->cdr->car->car, VAL, 1); + if (nargs >= 0) { + callargs = nargs; + } + else { /* varargs */ + push(); + nargs = 1; + callargs = CALL_MAXARGS; + } + } + /* copy receiver and arguments */ + genop(s, MKOP_AB(OP_MOVE, cursp(), base)); + for (i=0; icar, VAL); + } + if (len == 2 && + ((name[0] == '|' && name[1] == '|') || + (name[0] == '&' && name[1] == '&'))) { + int pos; + + pop(); + if (val) { + if (vsp >= 0) { + genop(s, MKOP_AB(OP_MOVE, vsp, cursp())); + } + pos = genop(s, MKOP_AsBx(name[0]=='|'?OP_JMPIF:OP_JMPNOT, cursp(), 0)); + } + else { + pos = genop_peep(s, MKOP_AsBx(name[0]=='|'?OP_JMPIF:OP_JMPNOT, cursp(), 0), NOVAL); + } + codegen(s, tree->cdr->cdr->car, VAL); + pop(); + if (val && vsp >= 0) { + genop(s, MKOP_AB(OP_MOVE, vsp, cursp())); + } + if (nint(tree->car->car) == NODE_CALL) { + if (callargs == CALL_MAXARGS) { + pop(); + genop(s, MKOP_AB(OP_ARYPUSH, cursp(), cursp()+1)); + } + else { + pop_n(callargs); + callargs++; + } + pop(); + idx = new_msym(s, attrsym(s, nsym(tree->car->cdr->cdr->car))); + genop(s, MKOP_ABC(OP_SEND, cursp(), idx, callargs)); + } + else { + gen_assignment(s, tree->car, cursp(), val); + } + dispatch(s, pos); + goto exit; + } + codegen(s, tree->cdr->cdr->car, VAL); + push(); pop(); + pop(); pop(); + + idx = new_msym(s, sym); + if (len == 1 && name[0] == '+') { + genop_peep(s, MKOP_ABC(OP_ADD, cursp(), idx, 1), val); + } + else if (len == 1 && name[0] == '-') { + genop_peep(s, MKOP_ABC(OP_SUB, cursp(), idx, 1), val); + } + else if (len == 1 && name[0] == '*') { + genop(s, MKOP_ABC(OP_MUL, cursp(), idx, 1)); + } + else if (len == 1 && name[0] == '/') { + genop(s, MKOP_ABC(OP_DIV, cursp(), idx, 1)); + } + else if (len == 1 && name[0] == '<') { + genop(s, MKOP_ABC(OP_LT, cursp(), idx, 1)); + } + else if (len == 2 && name[0] == '<' && name[1] == '=') { + genop(s, MKOP_ABC(OP_LE, cursp(), idx, 1)); + } + else if (len == 1 && name[0] == '>') { + genop(s, MKOP_ABC(OP_GT, cursp(), idx, 1)); + } + else if (len == 2 && name[0] == '>' && name[1] == '=') { + genop(s, MKOP_ABC(OP_GE, cursp(), idx, 1)); + } + else { + genop(s, MKOP_ABC(OP_SEND, cursp(), idx, 1)); + } + if (callargs < 0) { + gen_assignment(s, tree->car, cursp(), val); + } + else { + if (val && vsp >= 0) { + genop(s, MKOP_AB(OP_MOVE, vsp, cursp())); + } + if (callargs == CALL_MAXARGS) { + pop(); + genop(s, MKOP_AB(OP_ARYPUSH, cursp(), cursp()+1)); + } + else { + pop_n(callargs); + callargs++; + } + pop(); + idx = new_msym(s, attrsym(s,nsym(tree->car->cdr->cdr->car))); + genop(s, MKOP_ABC(OP_SEND, cursp(), idx, callargs)); + } + } + break; + + case NODE_SUPER: + { + codegen_scope *s2 = s; + int lv = 0; + int n = 0, noop = 0, sendv = 0; + + push(); /* room for receiver */ + while (!s2->mscope) { + lv++; + s2 = s2->prev; + if (!s2) break; + } + genop(s, MKOP_ABx(OP_ARGARY, cursp(), (lv & 0xf))); + push(); push(); /* ARGARY pushes two values */ + pop(); pop(); + if (tree) { + node *args = tree->car; + if (args) { + n = gen_values(s, args, VAL, 0); + if (n < 0) { + n = noop = sendv = 1; + push(); + } + } + } + if (tree && tree->cdr) { + codegen(s, tree->cdr, VAL); + pop(); + } + else { + genop(s, MKOP_A(OP_LOADNIL, cursp())); + push(); pop(); + } + pop_n(n+1); + if (sendv) n = CALL_MAXARGS; + genop(s, MKOP_ABC(OP_SUPER, cursp(), 0, n)); + if (val) push(); + } + break; + + case NODE_ZSUPER: + { + codegen_scope *s2 = s; + int lv = 0, ainfo = 0; + + push(); /* room for receiver */ + while (!s2->mscope) { + lv++; + s2 = s2->prev; + if (!s2) break; + } + if (s2) ainfo = s2->ainfo; + genop(s, MKOP_ABx(OP_ARGARY, cursp(), (ainfo<<4)|(lv & 0xf))); + push(); push(); pop(); /* ARGARY pushes two values */ + if (tree && tree->cdr) { + codegen(s, tree->cdr, VAL); + pop(); + } + pop(); pop(); + genop(s, MKOP_ABC(OP_SUPER, cursp(), 0, CALL_MAXARGS)); + if (val) push(); + } + break; + + case NODE_RETURN: + if (tree) { + gen_retval(s, tree); + } + else { + genop(s, MKOP_A(OP_LOADNIL, cursp())); + } + if (s->loop) { + genop(s, MKOP_AB(OP_RETURN, cursp(), OP_R_RETURN)); + } + else { + genop_peep(s, MKOP_AB(OP_RETURN, cursp(), OP_R_NORMAL), NOVAL); + } + if (val) push(); + break; + + case NODE_YIELD: + { + codegen_scope *s2 = s; + int lv = 0, ainfo = 0; + int n = 0, sendv = 0; + + while (!s2->mscope) { + lv++; + s2 = s2->prev; + if (!s2) break; + } + if (s2) ainfo = s2->ainfo; + push(); + if (tree) { + n = gen_values(s, tree, VAL, 0); + if (n < 0) { + n = sendv = 1; + push(); + } + } + push();pop(); /* space for a block */ + pop_n(n+1); + genop(s, MKOP_ABx(OP_BLKPUSH, cursp(), (ainfo<<4)|(lv & 0xf))); + if (sendv) n = CALL_MAXARGS; + genop(s, MKOP_ABC(OP_SEND, cursp(), new_msym(s, mrb_intern_lit(s->mrb, "call")), n)); + if (val) push(); + } + break; + + case NODE_BREAK: + loop_break(s, tree); + if (val) push(); + break; + + case NODE_NEXT: + if (!s->loop) { + raise_error(s, "unexpected next"); + } + else if (s->loop->type == LOOP_NORMAL) { + if (s->ensure_level > s->loop->ensure_level) { + genop_peep(s, MKOP_A(OP_EPOP, s->ensure_level - s->loop->ensure_level), NOVAL); + } + codegen(s, tree, NOVAL); + genop(s, MKOP_sBx(OP_JMP, s->loop->pc1 - s->pc)); + } + else { + if (tree) { + codegen(s, tree, VAL); + pop(); + } + else { + genop(s, MKOP_A(OP_LOADNIL, cursp())); + } + genop_peep(s, MKOP_AB(OP_RETURN, cursp(), OP_R_NORMAL), NOVAL); + } + if (val) push(); + break; + + case NODE_REDO: + if (!s->loop || s->loop->type == LOOP_BEGIN || s->loop->type == LOOP_RESCUE) { + raise_error(s, "unexpected redo"); + } + else { + if (s->ensure_level > s->loop->ensure_level) { + genop_peep(s, MKOP_A(OP_EPOP, s->ensure_level - s->loop->ensure_level), NOVAL); + } + genop(s, MKOP_sBx(OP_JMP, s->loop->pc2 - s->pc)); + } + if (val) push(); + break; + + case NODE_RETRY: + { + const char *msg = "unexpected retry"; + + if (!s->loop) { + raise_error(s, msg); + } + else { + struct loopinfo *lp = s->loop; + int n = 0; + + while (lp && lp->type != LOOP_RESCUE) { + if (lp->type == LOOP_BEGIN) { + n++; + } + lp = lp->prev; + } + if (!lp) { + raise_error(s, msg); + } + else { + if (n > 0) { + genop_peep(s, MKOP_A(OP_POPERR, n), NOVAL); + } + if (s->ensure_level > lp->ensure_level) { + genop_peep(s, MKOP_A(OP_EPOP, s->ensure_level - lp->ensure_level), NOVAL); + } + genop(s, MKOP_sBx(OP_JMP, lp->pc1 - s->pc)); + } + } + if (val) push(); + } + break; + + case NODE_LVAR: + if (val) { + int idx = lv_idx(s, nsym(tree)); + + if (idx > 0) { + genop_peep(s, MKOP_AB(OP_MOVE, cursp(), idx), NOVAL); + } + else { + int lv = 0; + codegen_scope *up = s->prev; + + while (up) { + idx = lv_idx(up, nsym(tree)); + if (idx > 0) { + genop(s, MKOP_ABC(OP_GETUPVAR, cursp(), idx, lv)); + break; + } + lv++; + up = up->prev; + } + } + push(); + } + break; + + case NODE_GVAR: + if (val) { + int sym = new_sym(s, nsym(tree)); + + genop(s, MKOP_ABx(OP_GETGLOBAL, cursp(), sym)); + push(); + } + break; + + case NODE_IVAR: + if (val) { + int sym = new_sym(s, nsym(tree)); + + genop(s, MKOP_ABx(OP_GETIV, cursp(), sym)); + push(); + } + break; + + case NODE_CVAR: + if (val) { + int sym = new_sym(s, nsym(tree)); + + genop(s, MKOP_ABx(OP_GETCV, cursp(), sym)); + push(); + } + break; + + case NODE_CONST: + { + int sym = new_sym(s, nsym(tree)); + + genop(s, MKOP_ABx(OP_GETCONST, cursp(), sym)); + if (val) { + push(); + } + } + break; + + case NODE_DEFINED: + codegen(s, tree, VAL); + break; + + case NODE_BACK_REF: + if (val) { + char buf[3]; + int sym; + + buf[0] = '$'; + buf[1] = nchar(tree); + buf[2] = 0; + sym = new_sym(s, mrb_intern_cstr(s->mrb, buf)); + genop(s, MKOP_ABx(OP_GETGLOBAL, cursp(), sym)); + push(); + } + break; + + case NODE_NTH_REF: + if (val) { + mrb_state *mrb = s->mrb; + mrb_value str; + int sym; + + str = mrb_format(mrb, "$%S", mrb_fixnum_value(nint(tree))); + sym = new_sym(s, mrb_intern_str(mrb, str)); + genop(s, MKOP_ABx(OP_GETGLOBAL, cursp(), sym)); + push(); + } + break; + + case NODE_ARG: + /* should not happen */ + break; + + case NODE_BLOCK_ARG: + codegen(s, tree, VAL); + break; + + case NODE_INT: + if (val) { + char *p = (char*)tree->car; + int base = nint(tree->cdr->car); + mrb_int i; + mrb_code co; + mrb_bool overflow; + + i = readint_mrb_int(s, p, base, FALSE, &overflow); + if (overflow) { + double f = readint_float(s, p, base); + int off = new_lit(s, mrb_float_value(s->mrb, f)); + + genop(s, MKOP_ABx(OP_LOADL, cursp(), off)); + } + else { + if (i < MAXARG_sBx && i > -MAXARG_sBx) { + co = MKOP_AsBx(OP_LOADI, cursp(), i); + } + else { + int off = new_lit(s, mrb_fixnum_value(i)); + co = MKOP_ABx(OP_LOADL, cursp(), off); + } + genop(s, co); + } + push(); + } + break; + + case NODE_FLOAT: + if (val) { + char *p = (char*)tree; + mrb_float f = mrb_float_read(p, NULL); + int off = new_lit(s, mrb_float_value(s->mrb, f)); + + genop(s, MKOP_ABx(OP_LOADL, cursp(), off)); + push(); + } + break; + + case NODE_NEGATE: + { + nt = nint(tree->car); + tree = tree->cdr; + switch (nt) { + case NODE_FLOAT: + if (val) { + char *p = (char*)tree; + mrb_float f = mrb_float_read(p, NULL); + int off = new_lit(s, mrb_float_value(s->mrb, -f)); + + genop(s, MKOP_ABx(OP_LOADL, cursp(), off)); + push(); + } + break; + + case NODE_INT: + if (val) { + char *p = (char*)tree->car; + int base = nint(tree->cdr->car); + mrb_int i; + mrb_code co; + mrb_bool overflow; + + i = readint_mrb_int(s, p, base, TRUE, &overflow); + if (overflow) { + double f = readint_float(s, p, base); + int off = new_lit(s, mrb_float_value(s->mrb, -f)); + + genop(s, MKOP_ABx(OP_LOADL, cursp(), off)); + } + else { + if (i < MAXARG_sBx && i > -MAXARG_sBx) { + co = MKOP_AsBx(OP_LOADI, cursp(), i); + } + else { + int off = new_lit(s, mrb_fixnum_value(i)); + co = MKOP_ABx(OP_LOADL, cursp(), off); + } + genop(s, co); + } + push(); + } + break; + + default: + if (val) { + int sym = new_msym(s, mrb_intern_lit(s->mrb, "-")); + + genop(s, MKOP_ABx(OP_LOADI, cursp(), 0)); + push(); + codegen(s, tree, VAL); + pop(); pop(); + genop(s, MKOP_ABC(OP_SUB, cursp(), sym, 2)); + } + else { + codegen(s, tree, NOVAL); + } + break; + } + } + break; + + case NODE_STR: + if (val) { + char *p = (char*)tree->car; + size_t len = (intptr_t)tree->cdr; + int ai = mrb_gc_arena_save(s->mrb); + int off = new_lit(s, mrb_str_new(s->mrb, p, len)); + + mrb_gc_arena_restore(s->mrb, ai); + genop(s, MKOP_ABx(OP_STRING, cursp(), off)); + push(); + } + break; + + case NODE_HEREDOC: + tree = ((struct mrb_parser_heredoc_info *)tree)->doc; + /* fall through */ + case NODE_DSTR: + if (val) { + node *n = tree; + + if (!n) { + genop(s, MKOP_A(OP_LOADNIL, cursp())); + push(); + break; + } + codegen(s, n->car, VAL); + n = n->cdr; + while (n) { + codegen(s, n->car, VAL); + pop(); pop(); + genop_peep(s, MKOP_AB(OP_STRCAT, cursp(), cursp()+1), VAL); + push(); + n = n->cdr; + } + } + else { + node *n = tree; + + while (n) { + if (nint(n->car->car) != NODE_STR) { + codegen(s, n->car, NOVAL); + } + n = n->cdr; + } + } + break; + + case NODE_WORDS: + gen_literal_array(s, tree, FALSE, val); + break; + + case NODE_SYMBOLS: + gen_literal_array(s, tree, TRUE, val); + break; + + case NODE_DXSTR: + { + node *n; + int ai = mrb_gc_arena_save(s->mrb); + int sym = new_sym(s, mrb_intern_lit(s->mrb, "Kernel")); + + genop(s, MKOP_A(OP_LOADSELF, cursp())); + push(); + codegen(s, tree->car, VAL); + n = tree->cdr; + while (n) { + if (nint(n->car->car) == NODE_XSTR) { + n->car->car = (struct mrb_ast_node*)(intptr_t)NODE_STR; + mrb_assert(!n->cdr); /* must be the end */ + } + codegen(s, n->car, VAL); + pop(); pop(); + genop_peep(s, MKOP_AB(OP_STRCAT, cursp(), cursp()+1), VAL); + push(); + n = n->cdr; + } + push(); /* for block */ + pop_n(3); + sym = new_sym(s, mrb_intern_lit(s->mrb, "`")); + genop(s, MKOP_ABC(OP_SEND, cursp(), sym, 1)); + if (val) push(); + mrb_gc_arena_restore(s->mrb, ai); + } + break; + + case NODE_XSTR: + { + char *p = (char*)tree->car; + size_t len = (intptr_t)tree->cdr; + int ai = mrb_gc_arena_save(s->mrb); + int off = new_lit(s, mrb_str_new(s->mrb, p, len)); + int sym; + + genop(s, MKOP_A(OP_LOADSELF, cursp())); + push(); + genop(s, MKOP_ABx(OP_STRING, cursp(), off)); + push(); push(); + pop_n(3); + sym = new_sym(s, mrb_intern_lit(s->mrb, "`")); + genop(s, MKOP_ABC(OP_SEND, cursp(), sym, 1)); + if (val) push(); + mrb_gc_arena_restore(s->mrb, ai); + } + break; + + case NODE_REGX: + if (val) { + char *p1 = (char*)tree->car; + char *p2 = (char*)tree->cdr->car; + char *p3 = (char*)tree->cdr->cdr; + int ai = mrb_gc_arena_save(s->mrb); + int sym = new_sym(s, mrb_intern_lit(s->mrb, REGEXP_CLASS)); + int off = new_lit(s, mrb_str_new_cstr(s->mrb, p1)); + int argc = 1; + + genop(s, MKOP_A(OP_OCLASS, cursp())); + genop(s, MKOP_ABx(OP_GETMCNST, cursp(), sym)); + push(); + genop(s, MKOP_ABx(OP_STRING, cursp(), off)); + push(); + if (p2 || p3) { + if (p2) { /* opt */ + off = new_lit(s, mrb_str_new_cstr(s->mrb, p2)); + genop(s, MKOP_ABx(OP_STRING, cursp(), off)); + } + else { + genop(s, MKOP_A(OP_LOADNIL, cursp())); + } + push(); + argc++; + if (p3) { /* enc */ + off = new_lit(s, mrb_str_new(s->mrb, p3, 1)); + genop(s, MKOP_ABx(OP_STRING, cursp(), off)); + push(); + argc++; + } + } + push(); /* space for a block */ + pop_n(argc+2); + sym = new_sym(s, mrb_intern_lit(s->mrb, "compile")); + genop(s, MKOP_ABC(OP_SEND, cursp(), sym, argc)); + mrb_gc_arena_restore(s->mrb, ai); + push(); + } + break; + + case NODE_DREGX: + if (val) { + node *n = tree->car; + int ai = mrb_gc_arena_save(s->mrb); + int sym = new_sym(s, mrb_intern_lit(s->mrb, REGEXP_CLASS)); + int argc = 1; + int off; + char *p; + + genop(s, MKOP_A(OP_OCLASS, cursp())); + genop(s, MKOP_ABx(OP_GETMCNST, cursp(), sym)); + push(); + codegen(s, n->car, VAL); + n = n->cdr; + while (n) { + codegen(s, n->car, VAL); + pop(); pop(); + genop_peep(s, MKOP_AB(OP_STRCAT, cursp(), cursp()+1), VAL); + push(); + n = n->cdr; + } + n = tree->cdr->cdr; + if (n->car) { /* tail */ + p = (char*)n->car; + off = new_lit(s, mrb_str_new_cstr(s->mrb, p)); + codegen(s, tree->car, VAL); + genop(s, MKOP_ABx(OP_STRING, cursp(), off)); + pop(); + genop_peep(s, MKOP_AB(OP_STRCAT, cursp(), cursp()+1), VAL); + push(); + } + if (n->cdr->car) { /* opt */ + char *p2 = (char*)n->cdr->car; + off = new_lit(s, mrb_str_new_cstr(s->mrb, p2)); + genop(s, MKOP_ABx(OP_STRING, cursp(), off)); + push(); + argc++; + } + if (n->cdr->cdr) { /* enc */ + char *p2 = (char*)n->cdr->cdr; + off = new_lit(s, mrb_str_new_cstr(s->mrb, p2)); + genop(s, MKOP_ABx(OP_STRING, cursp(), off)); + push(); + argc++; + } + push(); /* space for a block */ + pop_n(argc+2); + sym = new_sym(s, mrb_intern_lit(s->mrb, "compile")); + genop(s, MKOP_ABC(OP_SEND, cursp(), sym, argc)); + mrb_gc_arena_restore(s->mrb, ai); + push(); + } + else { + node *n = tree->car; + + while (n) { + if (nint(n->car->car) != NODE_STR) { + codegen(s, n->car, NOVAL); + } + n = n->cdr; + } + } + break; + + case NODE_SYM: + if (val) { + int sym = new_sym(s, nsym(tree)); + + genop(s, MKOP_ABx(OP_LOADSYM, cursp(), sym)); + push(); + } + break; + + case NODE_DSYM: + codegen(s, tree, val); + if (val) { + gen_send_intern(s); + } + break; + + case NODE_SELF: + if (val) { + genop(s, MKOP_A(OP_LOADSELF, cursp())); + push(); + } + break; + + case NODE_NIL: + if (val) { + genop(s, MKOP_A(OP_LOADNIL, cursp())); + push(); + } + break; + + case NODE_TRUE: + if (val) { + genop(s, MKOP_A(OP_LOADT, cursp())); + push(); + } + break; + + case NODE_FALSE: + if (val) { + genop(s, MKOP_A(OP_LOADF, cursp())); + push(); + } + break; + + case NODE_ALIAS: + { + int a = new_msym(s, nsym(tree->car)); + int b = new_msym(s, nsym(tree->cdr)); + int c = new_msym(s, mrb_intern_lit(s->mrb, "alias_method")); + + genop(s, MKOP_A(OP_TCLASS, cursp())); + push(); + genop(s, MKOP_ABx(OP_LOADSYM, cursp(), a)); + push(); + genop(s, MKOP_ABx(OP_LOADSYM, cursp(), b)); + push(); + genop(s, MKOP_A(OP_LOADNIL, cursp())); + push(); /* space for a block */ + pop_n(4); + genop(s, MKOP_ABC(OP_SEND, cursp(), c, 2)); + if (val) { + push(); + } + } + break; + + case NODE_UNDEF: + { + int undef = new_msym(s, mrb_intern_lit(s->mrb, "undef_method")); + int num = 0; + node *t = tree; + + genop(s, MKOP_A(OP_TCLASS, cursp())); + push(); + while (t) { + int symbol; + if (num >= CALL_MAXARGS - 1) { + pop_n(num); + genop(s, MKOP_ABC(OP_ARRAY, cursp(), cursp(), num)); + while (t) { + symbol = new_msym(s, nsym(t->car)); + push(); + genop(s, MKOP_ABx(OP_LOADSYM, cursp(), symbol)); + pop(); + genop(s, MKOP_AB(OP_ARYPUSH, cursp(), cursp()+1)); + t = t->cdr; + } + num = CALL_MAXARGS; + break; + } + symbol = new_msym(s, nsym(t->car)); + genop(s, MKOP_ABx(OP_LOADSYM, cursp(), symbol)); + push(); + t = t->cdr; + num++; + } + push();pop(); /* space for a block */ + pop(); + if (num < CALL_MAXARGS) { + pop_n(num); + } + genop(s, MKOP_ABC(OP_SEND, cursp(), undef, num)); + if (val) { + push(); + } + } + break; + + case NODE_CLASS: + { + int idx; + + if (tree->car->car == (node*)0) { + genop(s, MKOP_A(OP_LOADNIL, cursp())); + push(); + } + else if (tree->car->car == (node*)1) { + genop(s, MKOP_A(OP_OCLASS, cursp())); + push(); + } + else { + codegen(s, tree->car->car, VAL); + } + if (tree->cdr->car) { + codegen(s, tree->cdr->car, VAL); + } + else { + genop(s, MKOP_A(OP_LOADNIL, cursp())); + push(); + } + pop(); pop(); + idx = new_msym(s, nsym(tree->car->cdr)); + genop(s, MKOP_AB(OP_CLASS, cursp(), idx)); + idx = scope_body(s, tree->cdr->cdr->car, val); + genop(s, MKOP_ABx(OP_EXEC, cursp(), idx)); + if (val) { + push(); + } + } + break; + + case NODE_MODULE: + { + int idx; + + if (tree->car->car == (node*)0) { + genop(s, MKOP_A(OP_LOADNIL, cursp())); + push(); + } + else if (tree->car->car == (node*)1) { + genop(s, MKOP_A(OP_OCLASS, cursp())); + push(); + } + else { + codegen(s, tree->car->car, VAL); + } + pop(); + idx = new_msym(s, nsym(tree->car->cdr)); + genop(s, MKOP_AB(OP_MODULE, cursp(), idx)); + idx = scope_body(s, tree->cdr->car, val); + genop(s, MKOP_ABx(OP_EXEC, cursp(), idx)); + if (val) { + push(); + } + } + break; + + case NODE_SCLASS: + { + int idx; + + codegen(s, tree->car, VAL); + pop(); + genop(s, MKOP_AB(OP_SCLASS, cursp(), cursp())); + idx = scope_body(s, tree->cdr->car, val); + genop(s, MKOP_ABx(OP_EXEC, cursp(), idx)); + if (val) { + push(); + } + } + break; + + case NODE_DEF: + { + int sym = new_msym(s, nsym(tree->car)); + int idx = lambda_body(s, tree->cdr, 0); + + genop(s, MKOP_A(OP_TCLASS, cursp())); + push(); + genop(s, MKOP_Abc(OP_LAMBDA, cursp(), idx, OP_L_METHOD)); + push(); pop(); + pop(); + genop(s, MKOP_AB(OP_METHOD, cursp(), sym)); + if (val) { + genop(s, MKOP_ABx(OP_LOADSYM, cursp(), sym)); + push(); + } + } + break; + + case NODE_SDEF: + { + node *recv = tree->car; + int sym = new_msym(s, nsym(tree->cdr->car)); + int idx = lambda_body(s, tree->cdr->cdr, 0); + + codegen(s, recv, VAL); + pop(); + genop(s, MKOP_AB(OP_SCLASS, cursp(), cursp())); + push(); + genop(s, MKOP_Abc(OP_LAMBDA, cursp(), idx, OP_L_METHOD)); + pop(); + genop(s, MKOP_AB(OP_METHOD, cursp(), sym)); + if (val) { + genop(s, MKOP_ABx(OP_LOADSYM, cursp(), sym)); + push(); + } + } + break; + + case NODE_POSTEXE: + codegen(s, tree, NOVAL); + break; + + default: + break; + } + exit: + s->rlev = rlev; +} + +static void +scope_add_irep(codegen_scope *s, mrb_irep *irep) +{ + if (s->irep == NULL) { + s->irep = irep; + return; + } + if (s->irep->rlen == s->rcapa) { + s->rcapa *= 2; + s->irep->reps = (mrb_irep**)codegen_realloc(s, s->irep->reps, sizeof(mrb_irep*)*s->rcapa); + } + s->irep->reps[s->irep->rlen] = irep; + s->irep->rlen++; +} + +static codegen_scope* +scope_new(mrb_state *mrb, codegen_scope *prev, node *lv) +{ + static const codegen_scope codegen_scope_zero = { 0 }; + mrb_pool *pool = mrb_pool_open(mrb); + codegen_scope *p = (codegen_scope *)mrb_pool_alloc(pool, sizeof(codegen_scope)); + + if (!p) return NULL; + *p = codegen_scope_zero; + p->mrb = mrb; + p->mpool = pool; + if (!prev) return p; + p->prev = prev; + p->ainfo = -1; + p->mscope = 0; + + p->irep = mrb_add_irep(mrb); + scope_add_irep(prev, p->irep); + + p->rcapa = 8; + p->irep->reps = (mrb_irep**)mrb_malloc(mrb, sizeof(mrb_irep*)*p->rcapa); + + p->icapa = 1024; + p->iseq = (mrb_code*)mrb_malloc(mrb, sizeof(mrb_code)*p->icapa); + p->irep->iseq = NULL; + + p->pcapa = 32; + p->irep->pool = (mrb_value*)mrb_malloc(mrb, sizeof(mrb_value)*p->pcapa); + p->irep->plen = 0; + + p->scapa = MAXMSYMLEN; + p->irep->syms = (mrb_sym*)mrb_malloc(mrb, sizeof(mrb_sym)*p->scapa); + p->irep->slen = 0; + + p->lv = lv; + p->sp += node_len(lv)+1; /* add self */ + p->nlocals = p->sp; + if (lv) { + node *n = lv; + size_t i = 0; + + p->irep->lv = (struct mrb_locals*)mrb_malloc(mrb, sizeof(struct mrb_locals) * (p->nlocals - 1)); + for (i=0, n=lv; n; i++,n=n->cdr) { + p->irep->lv[i].name = lv_name(n); + if (lv_name(n)) { + p->irep->lv[i].r = lv_idx(p, lv_name(n)); + } + else { + p->irep->lv[i].r = 0; + } + } + mrb_assert(i + 1 == p->nlocals); + } + p->ai = mrb_gc_arena_save(mrb); + + p->filename = prev->filename; + if (p->filename) { + p->lines = (uint16_t*)mrb_malloc(mrb, sizeof(short)*p->icapa); + } + p->lineno = prev->lineno; + + /* debug setting */ + p->debug_start_pos = 0; + if (p->filename) { + mrb_debug_info_alloc(mrb, p->irep); + p->irep->filename = p->filename; + p->irep->lines = p->lines; + } + else { + p->irep->debug_info = NULL; + } + p->parser = prev->parser; + p->filename_index = prev->filename_index; + + p->rlev = prev->rlev+1; + + return p; +} + +static void +scope_finish(codegen_scope *s) +{ + mrb_state *mrb = s->mrb; + mrb_irep *irep = s->irep; + size_t fname_len; + char *fname; + + irep->flags = 0; + if (s->iseq) { + irep->iseq = (mrb_code *)codegen_realloc(s, s->iseq, sizeof(mrb_code)*s->pc); + irep->ilen = s->pc; + if (s->lines) { + irep->lines = (uint16_t *)codegen_realloc(s, s->lines, sizeof(uint16_t)*s->pc); + } + else { + irep->lines = 0; + } + } + irep->pool = (mrb_value*)codegen_realloc(s, irep->pool, sizeof(mrb_value)*irep->plen); + irep->syms = (mrb_sym*)codegen_realloc(s, irep->syms, sizeof(mrb_sym)*irep->slen); + irep->reps = (mrb_irep**)codegen_realloc(s, irep->reps, sizeof(mrb_irep*)*irep->rlen); + if (s->filename) { + irep->filename = mrb_parser_get_filename(s->parser, s->filename_index); + mrb_debug_info_append_file(mrb, irep, s->debug_start_pos, s->pc); + + fname_len = strlen(s->filename); + fname = (char*)codegen_malloc(s, fname_len + 1); + memcpy(fname, s->filename, fname_len); + fname[fname_len] = '\0'; + irep->filename = fname; + irep->own_filename = TRUE; + } + + irep->nlocals = s->nlocals; + irep->nregs = s->nregs; + + mrb_gc_arena_restore(mrb, s->ai); + mrb_pool_close(s->mpool); +} + +static struct loopinfo* +loop_push(codegen_scope *s, enum looptype t) +{ + struct loopinfo *p = (struct loopinfo *)codegen_palloc(s, sizeof(struct loopinfo)); + + p->type = t; + p->pc1 = p->pc2 = p->pc3 = 0; + p->prev = s->loop; + p->ensure_level = s->ensure_level; + p->acc = cursp(); + s->loop = p; + + return p; +} + +static void +loop_break(codegen_scope *s, node *tree) +{ + if (!s->loop) { + codegen(s, tree, NOVAL); + raise_error(s, "unexpected break"); + } + else { + struct loopinfo *loop; + int n = 0; + + if (tree) { + gen_retval(s, tree); + } + + loop = s->loop; + while (loop) { + if (loop->type == LOOP_BEGIN) { + n++; + loop = loop->prev; + } + else if (loop->type == LOOP_RESCUE) { + loop = loop->prev; + } + else{ + break; + } + } + if (!loop) { + raise_error(s, "unexpected break"); + return; + } + if (n > 0) { + genop_peep(s, MKOP_A(OP_POPERR, n), NOVAL); + } + + if (loop->type == LOOP_NORMAL) { + int tmp; + + if (s->ensure_level > s->loop->ensure_level) { + genop_peep(s, MKOP_A(OP_EPOP, s->ensure_level - s->loop->ensure_level), NOVAL); + } + if (tree) { + genop_peep(s, MKOP_AB(OP_MOVE, loop->acc, cursp()), NOVAL); + } + tmp = genop(s, MKOP_sBx(OP_JMP, loop->pc3)); + loop->pc3 = tmp; + } + else { + if (!tree) { + genop(s, MKOP_A(OP_LOADNIL, cursp())); + } + genop(s, MKOP_AB(OP_RETURN, cursp(), OP_R_BREAK)); + } + } +} + +static void +loop_pop(codegen_scope *s, int val) +{ + if (val) { + genop(s, MKOP_A(OP_LOADNIL, cursp())); + } + dispatch_linked(s, s->loop->pc3); + s->loop = s->loop->prev; + if (val) push(); +} + +MRB_API struct RProc* +mrb_generate_code(mrb_state *mrb, parser_state *p) +{ + codegen_scope *scope = scope_new(mrb, 0, 0); + struct RProc *proc; + struct mrb_jmpbuf *prev_jmp = mrb->jmp; + + if (!scope) { + return NULL; + } + scope->mrb = mrb; + scope->parser = p; + scope->filename = p->filename; + scope->filename_index = p->current_filename_index; + + MRB_TRY(&scope->jmp) { + mrb->jmp = &scope->jmp; + /* prepare irep */ + codegen(scope, p->tree, NOVAL); + proc = mrb_proc_new(mrb, scope->irep); + mrb_irep_decref(mrb, scope->irep); + mrb_pool_close(scope->mpool); + proc->c = NULL; + mrb->jmp = prev_jmp; + return proc; + } + MRB_CATCH(&scope->jmp) { + mrb_irep_decref(mrb, scope->irep); + mrb_pool_close(scope->mpool); + mrb->jmp = prev_jmp; + return NULL; + } + MRB_END_EXC(&scope->jmp); +} diff --git a/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-compiler/core/keywords b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-compiler/core/keywords new file mode 100644 index 00000000..9cb86608 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-compiler/core/keywords @@ -0,0 +1,50 @@ +%{ +struct kwtable {const char *name; int id[2]; enum mrb_lex_state_enum state;}; +const struct kwtable *mrb_reserved_word(const char *, unsigned int); +static const struct kwtable *reserved_word(const char *, unsigned int); +#define mrb_reserved_word(str, len) reserved_word(str, len) +%} + +struct kwtable; +%% +__ENCODING__, {keyword__ENCODING__, keyword__ENCODING__}, EXPR_END +__FILE__, {keyword__FILE__, keyword__FILE__}, EXPR_END +__LINE__, {keyword__LINE__, keyword__LINE__}, EXPR_END +BEGIN, {keyword_BEGIN, keyword_BEGIN}, EXPR_END +END, {keyword_END, keyword_END}, EXPR_END +alias, {keyword_alias, keyword_alias}, EXPR_FNAME +and, {keyword_and, keyword_and}, EXPR_VALUE +begin, {keyword_begin, keyword_begin}, EXPR_BEG +break, {keyword_break, keyword_break}, EXPR_MID +case, {keyword_case, keyword_case}, EXPR_VALUE +class, {keyword_class, keyword_class}, EXPR_CLASS +def, {keyword_def, keyword_def}, EXPR_FNAME +do, {keyword_do, keyword_do}, EXPR_BEG +else, {keyword_else, keyword_else}, EXPR_BEG +elsif, {keyword_elsif, keyword_elsif}, EXPR_VALUE +end, {keyword_end, keyword_end}, EXPR_END +ensure, {keyword_ensure, keyword_ensure}, EXPR_BEG +false, {keyword_false, keyword_false}, EXPR_END +for, {keyword_for, keyword_for}, EXPR_VALUE +if, {keyword_if, modifier_if}, EXPR_VALUE +in, {keyword_in, keyword_in}, EXPR_VALUE +module, {keyword_module, keyword_module}, EXPR_VALUE +next, {keyword_next, keyword_next}, EXPR_MID +nil, {keyword_nil, keyword_nil}, EXPR_END +not, {keyword_not, keyword_not}, EXPR_ARG +or, {keyword_or, keyword_or}, EXPR_VALUE +redo, {keyword_redo, keyword_redo}, EXPR_END +rescue, {keyword_rescue, modifier_rescue}, EXPR_MID +retry, {keyword_retry, keyword_retry}, EXPR_END +return, {keyword_return, keyword_return}, EXPR_MID +self, {keyword_self, keyword_self}, EXPR_END +super, {keyword_super, keyword_super}, EXPR_ARG +then, {keyword_then, keyword_then}, EXPR_BEG +true, {keyword_true, keyword_true}, EXPR_END +undef, {keyword_undef, keyword_undef}, EXPR_FNAME +unless, {keyword_unless, modifier_unless}, EXPR_VALUE +until, {keyword_until, modifier_until}, EXPR_VALUE +when, {keyword_when, keyword_when}, EXPR_VALUE +while, {keyword_while, modifier_while}, EXPR_VALUE +yield, {keyword_yield, keyword_yield}, EXPR_ARG +%% diff --git a/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-compiler/core/lex.def b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-compiler/core/lex.def new file mode 100644 index 00000000..58e30296 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-compiler/core/lex.def @@ -0,0 +1,212 @@ +/* ANSI-C code produced by gperf version 3.0.4 */ +/* Command-line: gperf -L ANSI-C -C -p -j1 -i 1 -g -o -t -N mrb_reserved_word -k'1,3,$' /home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords */ + +#if !((' ' == 32) && ('!' == 33) && ('"' == 34) && ('#' == 35) \ + && ('%' == 37) && ('&' == 38) && ('\'' == 39) && ('(' == 40) \ + && (')' == 41) && ('*' == 42) && ('+' == 43) && (',' == 44) \ + && ('-' == 45) && ('.' == 46) && ('/' == 47) && ('0' == 48) \ + && ('1' == 49) && ('2' == 50) && ('3' == 51) && ('4' == 52) \ + && ('5' == 53) && ('6' == 54) && ('7' == 55) && ('8' == 56) \ + && ('9' == 57) && (':' == 58) && (';' == 59) && ('<' == 60) \ + && ('=' == 61) && ('>' == 62) && ('?' == 63) && ('A' == 65) \ + && ('B' == 66) && ('C' == 67) && ('D' == 68) && ('E' == 69) \ + && ('F' == 70) && ('G' == 71) && ('H' == 72) && ('I' == 73) \ + && ('J' == 74) && ('K' == 75) && ('L' == 76) && ('M' == 77) \ + && ('N' == 78) && ('O' == 79) && ('P' == 80) && ('Q' == 81) \ + && ('R' == 82) && ('S' == 83) && ('T' == 84) && ('U' == 85) \ + && ('V' == 86) && ('W' == 87) && ('X' == 88) && ('Y' == 89) \ + && ('Z' == 90) && ('[' == 91) && ('\\' == 92) && (']' == 93) \ + && ('^' == 94) && ('_' == 95) && ('a' == 97) && ('b' == 98) \ + && ('c' == 99) && ('d' == 100) && ('e' == 101) && ('f' == 102) \ + && ('g' == 103) && ('h' == 104) && ('i' == 105) && ('j' == 106) \ + && ('k' == 107) && ('l' == 108) && ('m' == 109) && ('n' == 110) \ + && ('o' == 111) && ('p' == 112) && ('q' == 113) && ('r' == 114) \ + && ('s' == 115) && ('t' == 116) && ('u' == 117) && ('v' == 118) \ + && ('w' == 119) && ('x' == 120) && ('y' == 121) && ('z' == 122) \ + && ('{' == 123) && ('|' == 124) && ('}' == 125) && ('~' == 126)) +/* The character set is not based on ISO-646. */ +#error "gperf generated tables don't work with this execution character set. Please report a bug to ." +#endif + +#line 1 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords" + +struct kwtable {const char *name; int id[2]; enum mrb_lex_state_enum state;}; +const struct kwtable *mrb_reserved_word(const char *, unsigned int); +static const struct kwtable *reserved_word(const char *, unsigned int); +#define mrb_reserved_word(str, len) reserved_word(str, len) +#line 8 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords" +struct kwtable; + +#define TOTAL_KEYWORDS 40 +#define MIN_WORD_LENGTH 2 +#define MAX_WORD_LENGTH 12 +#define MIN_HASH_VALUE 8 +#define MAX_HASH_VALUE 50 +/* maximum key range = 43, duplicates = 0 */ + +#ifdef __GNUC__ +__inline +#else +#ifdef __cplusplus +inline +#endif +#endif +static unsigned int +hash (register const char *str, register unsigned int len) +{ + static const unsigned char asso_values[] = + { + 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, + 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, + 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, + 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, + 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, + 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, + 51, 51, 51, 51, 51, 51, 14, 51, 16, 8, + 11, 13, 51, 51, 51, 51, 10, 51, 13, 51, + 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, + 51, 51, 51, 51, 51, 11, 51, 13, 1, 26, + 4, 1, 8, 28, 51, 23, 51, 1, 1, 27, + 5, 19, 21, 51, 8, 3, 3, 11, 51, 21, + 24, 16, 51, 51, 51, 51, 51, 51, 51, 51, + 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, + 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, + 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, + 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, + 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, + 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, + 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, + 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, + 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, + 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, + 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, + 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, + 51, 51, 51, 51, 51, 51 + }; + register int hval = len; + + switch (hval) + { + default: + hval += asso_values[(unsigned char)str[2]]; + /*FALLTHROUGH*/ + case 2: + case 1: + hval += asso_values[(unsigned char)str[0]]; + break; + } + return hval + asso_values[(unsigned char)str[len - 1]]; +} + +#ifdef __GNUC__ +__inline +#if defined __GNUC_STDC_INLINE__ || defined __GNUC_GNU_INLINE__ +__attribute__ ((__gnu_inline__)) +#endif +#endif +const struct kwtable * +mrb_reserved_word (register const char *str, register unsigned int len) +{ + static const struct kwtable wordlist[] = + { + {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, +#line 18 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords" + {"break", {keyword_break, keyword_break}, EXPR_MID}, +#line 23 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords" + {"else", {keyword_else, keyword_else}, EXPR_BEG}, +#line 33 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords" + {"nil", {keyword_nil, keyword_nil}, EXPR_END}, +#line 26 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords" + {"ensure", {keyword_ensure, keyword_ensure}, EXPR_BEG}, +#line 25 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords" + {"end", {keyword_end, keyword_end}, EXPR_END}, +#line 42 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords" + {"then", {keyword_then, keyword_then}, EXPR_BEG}, +#line 34 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords" + {"not", {keyword_not, keyword_not}, EXPR_ARG}, +#line 27 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords" + {"false", {keyword_false, keyword_false}, EXPR_END}, +#line 40 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords" + {"self", {keyword_self, keyword_self}, EXPR_END}, +#line 24 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords" + {"elsif", {keyword_elsif, keyword_elsif}, EXPR_VALUE}, +#line 37 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords" + {"rescue", {keyword_rescue, modifier_rescue}, EXPR_MID}, +#line 43 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords" + {"true", {keyword_true, keyword_true}, EXPR_END}, +#line 46 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords" + {"until", {keyword_until, modifier_until}, EXPR_VALUE}, +#line 45 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords" + {"unless", {keyword_unless, modifier_unless}, EXPR_VALUE}, +#line 39 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords" + {"return", {keyword_return, keyword_return}, EXPR_MID}, +#line 21 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords" + {"def", {keyword_def, keyword_def}, EXPR_FNAME}, +#line 16 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords" + {"and", {keyword_and, keyword_and}, EXPR_VALUE}, +#line 22 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords" + {"do", {keyword_do, keyword_do}, EXPR_BEG}, +#line 49 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords" + {"yield", {keyword_yield, keyword_yield}, EXPR_ARG}, +#line 28 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords" + {"for", {keyword_for, keyword_for}, EXPR_VALUE}, +#line 44 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords" + {"undef", {keyword_undef, keyword_undef}, EXPR_FNAME}, +#line 35 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords" + {"or", {keyword_or, keyword_or}, EXPR_VALUE}, +#line 30 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords" + {"in", {keyword_in, keyword_in}, EXPR_VALUE}, +#line 47 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords" + {"when", {keyword_when, keyword_when}, EXPR_VALUE}, +#line 38 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords" + {"retry", {keyword_retry, keyword_retry}, EXPR_END}, +#line 29 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords" + {"if", {keyword_if, modifier_if}, EXPR_VALUE}, +#line 19 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords" + {"case", {keyword_case, keyword_case}, EXPR_VALUE}, +#line 36 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords" + {"redo", {keyword_redo, keyword_redo}, EXPR_END}, +#line 32 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords" + {"next", {keyword_next, keyword_next}, EXPR_MID}, +#line 41 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords" + {"super", {keyword_super, keyword_super}, EXPR_ARG}, +#line 31 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords" + {"module", {keyword_module, keyword_module}, EXPR_VALUE}, +#line 17 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords" + {"begin", {keyword_begin, keyword_begin}, EXPR_BEG}, +#line 12 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords" + {"__LINE__", {keyword__LINE__, keyword__LINE__}, EXPR_END}, +#line 11 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords" + {"__FILE__", {keyword__FILE__, keyword__FILE__}, EXPR_END}, +#line 10 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords" + {"__ENCODING__", {keyword__ENCODING__, keyword__ENCODING__}, EXPR_END}, +#line 14 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords" + {"END", {keyword_END, keyword_END}, EXPR_END}, +#line 15 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords" + {"alias", {keyword_alias, keyword_alias}, EXPR_FNAME}, +#line 13 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords" + {"BEGIN", {keyword_BEGIN, keyword_BEGIN}, EXPR_END}, + {""}, +#line 20 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords" + {"class", {keyword_class, keyword_class}, EXPR_CLASS}, + {""}, {""}, +#line 48 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords" + {"while", {keyword_while, modifier_while}, EXPR_VALUE} + }; + + if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH) + { + register int key = hash (str, len); + + if (key <= MAX_HASH_VALUE && key >= 0) + { + register const char *s = wordlist[key].name; + + if (*str == *s && !strcmp (str + 1, s + 1)) + return &wordlist[key]; + } + } + return 0; +} +#line 50 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords" + diff --git a/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-compiler/core/node.h b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-compiler/core/node.h new file mode 100644 index 00000000..9636dd75 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-compiler/core/node.h @@ -0,0 +1,118 @@ +/* +** node.h - nodes of abstract syntax tree +** +** See Copyright Notice in mruby.h +*/ + +#ifndef MRUBY_COMPILER_NODE_H +#define MRUBY_COMPILER_NODE_H + +enum node_type { + NODE_METHOD, + NODE_FBODY, + NODE_CFUNC, + NODE_SCOPE, + NODE_BLOCK, + NODE_IF, + NODE_CASE, + NODE_WHEN, + NODE_OPT_N, + NODE_WHILE, + NODE_UNTIL, + NODE_ITER, + NODE_FOR, + NODE_BREAK, + NODE_NEXT, + NODE_REDO, + NODE_RETRY, + NODE_BEGIN, + NODE_RESCUE, + NODE_ENSURE, + NODE_AND, + NODE_OR, + NODE_NOT, + NODE_MASGN, + NODE_ASGN, + NODE_CDECL, + NODE_CVASGN, + NODE_CVDECL, + NODE_OP_ASGN, + NODE_CALL, + NODE_SCALL, + NODE_FCALL, + NODE_VCALL, + NODE_SUPER, + NODE_ZSUPER, + NODE_ARRAY, + NODE_ZARRAY, + NODE_HASH, + NODE_RETURN, + NODE_YIELD, + NODE_LVAR, + NODE_DVAR, + NODE_GVAR, + NODE_IVAR, + NODE_CONST, + NODE_CVAR, + NODE_NTH_REF, + NODE_BACK_REF, + NODE_MATCH, + NODE_MATCH2, + NODE_MATCH3, + NODE_INT, + NODE_FLOAT, + NODE_NEGATE, + NODE_LAMBDA, + NODE_SYM, + NODE_STR, + NODE_DSTR, + NODE_XSTR, + NODE_DXSTR, + NODE_REGX, + NODE_DREGX, + NODE_DREGX_ONCE, + NODE_LIST, + NODE_ARG, + NODE_ARGSCAT, + NODE_ARGSPUSH, + NODE_SPLAT, + NODE_TO_ARY, + NODE_SVALUE, + NODE_BLOCK_ARG, + NODE_DEF, + NODE_SDEF, + NODE_ALIAS, + NODE_UNDEF, + NODE_CLASS, + NODE_MODULE, + NODE_SCLASS, + NODE_COLON2, + NODE_COLON3, + NODE_CREF, + NODE_DOT2, + NODE_DOT3, + NODE_FLIP2, + NODE_FLIP3, + NODE_ATTRSET, + NODE_SELF, + NODE_NIL, + NODE_TRUE, + NODE_FALSE, + NODE_DEFINED, + NODE_NEWLINE, + NODE_POSTEXE, + NODE_ALLOCA, + NODE_DMETHOD, + NODE_BMETHOD, + NODE_MEMO, + NODE_IFUNC, + NODE_DSYM, + NODE_ATTRASGN, + NODE_HEREDOC, + NODE_LITERAL_DELIM, + NODE_WORDS, + NODE_SYMBOLS, + NODE_LAST +}; + +#endif /* MRUBY_COMPILER_NODE_H */ diff --git a/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-compiler/core/parse.y b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-compiler/core/parse.y new file mode 100644 index 00000000..0e425b18 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-compiler/core/parse.y @@ -0,0 +1,6652 @@ +/* +** parse.y - mruby parser +** +** See Copyright Notice in mruby.h +*/ + +%{ +#undef PARSER_DEBUG +#ifdef PARSER_DEBUG +# define YYDEBUG 1 +#endif +#define YYERROR_VERBOSE 1 +/* + * Force yacc to use our memory management. This is a little evil because + * the macros assume that "parser_state *p" is in scope + */ +#define YYMALLOC(n) mrb_malloc(p->mrb, (n)) +#define YYFREE(o) mrb_free(p->mrb, (o)) +#define YYSTACK_USE_ALLOCA 0 + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "node.h" + +#define YYLEX_PARAM p + +typedef mrb_ast_node node; +typedef struct mrb_parser_state parser_state; +typedef struct mrb_parser_heredoc_info parser_heredoc_info; + +static int yyparse(parser_state *p); +static int yylex(void *lval, parser_state *p); +static void yyerror(parser_state *p, const char *s); +static void yywarn(parser_state *p, const char *s); +static void yywarning(parser_state *p, const char *s); +static void backref_error(parser_state *p, node *n); +static void void_expr_error(parser_state *p, node *n); +static void tokadd(parser_state *p, int32_t c); + +#define identchar(c) (ISALNUM(c) || (c) == '_' || !ISASCII(c)) + +typedef unsigned int stack_type; + +#define BITSTACK_PUSH(stack, n) ((stack) = ((stack)<<1)|((n)&1)) +#define BITSTACK_POP(stack) ((stack) = (stack) >> 1) +#define BITSTACK_LEXPOP(stack) ((stack) = ((stack) >> 1) | ((stack) & 1)) +#define BITSTACK_SET_P(stack) ((stack)&1) + +#define COND_PUSH(n) BITSTACK_PUSH(p->cond_stack, (n)) +#define COND_POP() BITSTACK_POP(p->cond_stack) +#define COND_LEXPOP() BITSTACK_LEXPOP(p->cond_stack) +#define COND_P() BITSTACK_SET_P(p->cond_stack) + +#define CMDARG_PUSH(n) BITSTACK_PUSH(p->cmdarg_stack, (n)) +#define CMDARG_POP() BITSTACK_POP(p->cmdarg_stack) +#define CMDARG_LEXPOP() BITSTACK_LEXPOP(p->cmdarg_stack) +#define CMDARG_P() BITSTACK_SET_P(p->cmdarg_stack) + +#define SET_LINENO(c,n) ((c)->lineno = (n)) +#define NODE_LINENO(c,n) do {\ + if (n) {\ + (c)->filename_index = (n)->filename_index;\ + (c)->lineno = (n)->lineno;\ + }\ +} while (0) + +#define sym(x) ((mrb_sym)(intptr_t)(x)) +#define nsym(x) ((node*)(intptr_t)(x)) +#define nint(x) ((node*)(intptr_t)(x)) +#define intn(x) ((int)(intptr_t)(x)) + +static inline mrb_sym +intern_cstr_gen(parser_state *p, const char *s) +{ + return mrb_intern_cstr(p->mrb, s); +} +#define intern_cstr(s) intern_cstr_gen(p,(s)) + +static inline mrb_sym +intern_gen(parser_state *p, const char *s, size_t len) +{ + return mrb_intern(p->mrb, s, len); +} +#define intern(s,len) intern_gen(p,(s),(len)) + +static inline mrb_sym +intern_gen_c(parser_state *p, const char c) +{ + return mrb_intern(p->mrb, &c, 1); +} +#define intern_c(c) intern_gen_c(p,(c)) + +static void +cons_free_gen(parser_state *p, node *cons) +{ + cons->cdr = p->cells; + p->cells = cons; +} +#define cons_free(c) cons_free_gen(p, (c)) + +static void* +parser_palloc(parser_state *p, size_t size) +{ + void *m = mrb_pool_alloc(p->pool, size); + + if (!m) { + MRB_THROW(p->jmp); + } + return m; +} + +static node* +cons_gen(parser_state *p, node *car, node *cdr) +{ + node *c; + + if (p->cells) { + c = p->cells; + p->cells = p->cells->cdr; + } + else { + c = (node *)parser_palloc(p, sizeof(mrb_ast_node)); + } + + c->car = car; + c->cdr = cdr; + c->lineno = p->lineno; + c->filename_index = p->current_filename_index; + return c; +} +#define cons(a,b) cons_gen(p,(a),(b)) + +static node* +list1_gen(parser_state *p, node *a) +{ + return cons(a, 0); +} +#define list1(a) list1_gen(p, (a)) + +static node* +list2_gen(parser_state *p, node *a, node *b) +{ + return cons(a, cons(b,0)); +} +#define list2(a,b) list2_gen(p, (a),(b)) + +static node* +list3_gen(parser_state *p, node *a, node *b, node *c) +{ + return cons(a, cons(b, cons(c,0))); +} +#define list3(a,b,c) list3_gen(p, (a),(b),(c)) + +static node* +list4_gen(parser_state *p, node *a, node *b, node *c, node *d) +{ + return cons(a, cons(b, cons(c, cons(d, 0)))); +} +#define list4(a,b,c,d) list4_gen(p, (a),(b),(c),(d)) + +static node* +list5_gen(parser_state *p, node *a, node *b, node *c, node *d, node *e) +{ + return cons(a, cons(b, cons(c, cons(d, cons(e, 0))))); +} +#define list5(a,b,c,d,e) list5_gen(p, (a),(b),(c),(d),(e)) + +static node* +list6_gen(parser_state *p, node *a, node *b, node *c, node *d, node *e, node *f) +{ + return cons(a, cons(b, cons(c, cons(d, cons(e, cons(f, 0)))))); +} +#define list6(a,b,c,d,e,f) list6_gen(p, (a),(b),(c),(d),(e),(f)) + +static node* +append_gen(parser_state *p, node *a, node *b) +{ + node *c = a; + + if (!a) return b; + while (c->cdr) { + c = c->cdr; + } + if (b) { + c->cdr = b; + } + return a; +} +#define append(a,b) append_gen(p,(a),(b)) +#define push(a,b) append_gen(p,(a),list1(b)) + +static char* +parser_strndup(parser_state *p, const char *s, size_t len) +{ + char *b = (char *)parser_palloc(p, len+1); + + memcpy(b, s, len); + b[len] = '\0'; + return b; +} +#undef strndup +#define strndup(s,len) parser_strndup(p, s, len) + +static char* +parser_strdup(parser_state *p, const char *s) +{ + return parser_strndup(p, s, strlen(s)); +} +#undef strdup +#define strdup(s) parser_strdup(p, s) + +/* xxx ----------------------------- */ + +static node* +local_switch(parser_state *p) +{ + node *prev = p->locals; + + p->locals = cons(0, 0); + return prev; +} + +static void +local_resume(parser_state *p, node *prev) +{ + p->locals = prev; +} + +static void +local_nest(parser_state *p) +{ + p->locals = cons(0, p->locals); +} + +static void +local_unnest(parser_state *p) +{ + if (p->locals) { + p->locals = p->locals->cdr; + } +} + +static mrb_bool +local_var_p(parser_state *p, mrb_sym sym) +{ + node *l = p->locals; + + while (l) { + node *n = l->car; + while (n) { + if (sym(n->car) == sym) return TRUE; + n = n->cdr; + } + l = l->cdr; + } + return FALSE; +} + +static void +local_add_f(parser_state *p, mrb_sym sym) +{ + if (p->locals) { + p->locals->car = push(p->locals->car, nsym(sym)); + } +} + +static void +local_add(parser_state *p, mrb_sym sym) +{ + if (!local_var_p(p, sym)) { + local_add_f(p, sym); + } +} + +static node* +locals_node(parser_state *p) +{ + return p->locals ? p->locals->car : NULL; +} + +/* (:scope (vars..) (prog...)) */ +static node* +new_scope(parser_state *p, node *body) +{ + return cons((node*)NODE_SCOPE, cons(locals_node(p), body)); +} + +/* (:begin prog...) */ +static node* +new_begin(parser_state *p, node *body) +{ + if (body) { + return list2((node*)NODE_BEGIN, body); + } + return cons((node*)NODE_BEGIN, 0); +} + +#define newline_node(n) (n) + +/* (:rescue body rescue else) */ +static node* +new_rescue(parser_state *p, node *body, node *resq, node *els) +{ + return list4((node*)NODE_RESCUE, body, resq, els); +} + +static node* +new_mod_rescue(parser_state *p, node *body, node *resq) +{ + return new_rescue(p, body, list1(list3(0, 0, resq)), 0); +} + +/* (:ensure body ensure) */ +static node* +new_ensure(parser_state *p, node *a, node *b) +{ + return cons((node*)NODE_ENSURE, cons(a, cons(0, b))); +} + +/* (:nil) */ +static node* +new_nil(parser_state *p) +{ + return list1((node*)NODE_NIL); +} + +/* (:true) */ +static node* +new_true(parser_state *p) +{ + return list1((node*)NODE_TRUE); +} + +/* (:false) */ +static node* +new_false(parser_state *p) +{ + return list1((node*)NODE_FALSE); +} + +/* (:alias new old) */ +static node* +new_alias(parser_state *p, mrb_sym a, mrb_sym b) +{ + return cons((node*)NODE_ALIAS, cons(nsym(a), nsym(b))); +} + +/* (:if cond then else) */ +static node* +new_if(parser_state *p, node *a, node *b, node *c) +{ + void_expr_error(p, a); + return list4((node*)NODE_IF, a, b, c); +} + +/* (:unless cond then else) */ +static node* +new_unless(parser_state *p, node *a, node *b, node *c) +{ + void_expr_error(p, a); + return list4((node*)NODE_IF, a, c, b); +} + +/* (:while cond body) */ +static node* +new_while(parser_state *p, node *a, node *b) +{ + void_expr_error(p, a); + return cons((node*)NODE_WHILE, cons(a, b)); +} + +/* (:until cond body) */ +static node* +new_until(parser_state *p, node *a, node *b) +{ + void_expr_error(p, a); + return cons((node*)NODE_UNTIL, cons(a, b)); +} + +/* (:for var obj body) */ +static node* +new_for(parser_state *p, node *v, node *o, node *b) +{ + void_expr_error(p, o); + return list4((node*)NODE_FOR, v, o, b); +} + +/* (:case a ((when ...) body) ((when...) body)) */ +static node* +new_case(parser_state *p, node *a, node *b) +{ + node *n = list2((node*)NODE_CASE, a); + node *n2 = n; + + void_expr_error(p, a); + while (n2->cdr) { + n2 = n2->cdr; + } + n2->cdr = b; + return n; +} + +/* (:postexe a) */ +static node* +new_postexe(parser_state *p, node *a) +{ + return cons((node*)NODE_POSTEXE, a); +} + +/* (:self) */ +static node* +new_self(parser_state *p) +{ + return list1((node*)NODE_SELF); +} + +/* (:call a b c) */ +static node* +new_call(parser_state *p, node *a, mrb_sym b, node *c, int pass) +{ + node *n = list4(nint(pass?NODE_CALL:NODE_SCALL), a, nsym(b), c); + void_expr_error(p, a); + NODE_LINENO(n, a); + return n; +} + +/* (:fcall self mid args) */ +static node* +new_fcall(parser_state *p, mrb_sym b, node *c) +{ + node *n = new_self(p); + NODE_LINENO(n, c); + n = list4((node*)NODE_FCALL, n, nsym(b), c); + NODE_LINENO(n, c); + return n; +} + +/* (:super . c) */ +static node* +new_super(parser_state *p, node *c) +{ + return cons((node*)NODE_SUPER, c); +} + +/* (:zsuper) */ +static node* +new_zsuper(parser_state *p) +{ + return list1((node*)NODE_ZSUPER); +} + +/* (:yield . c) */ +static node* +new_yield(parser_state *p, node *c) +{ + if (c) { + if (c->cdr) { + yyerror(p, "both block arg and actual block given"); + } + return cons((node*)NODE_YIELD, c->car); + } + return cons((node*)NODE_YIELD, 0); +} + +/* (:return . c) */ +static node* +new_return(parser_state *p, node *c) +{ + return cons((node*)NODE_RETURN, c); +} + +/* (:break . c) */ +static node* +new_break(parser_state *p, node *c) +{ + return cons((node*)NODE_BREAK, c); +} + +/* (:next . c) */ +static node* +new_next(parser_state *p, node *c) +{ + return cons((node*)NODE_NEXT, c); +} + +/* (:redo) */ +static node* +new_redo(parser_state *p) +{ + return list1((node*)NODE_REDO); +} + +/* (:retry) */ +static node* +new_retry(parser_state *p) +{ + return list1((node*)NODE_RETRY); +} + +/* (:dot2 a b) */ +static node* +new_dot2(parser_state *p, node *a, node *b) +{ + return cons((node*)NODE_DOT2, cons(a, b)); +} + +/* (:dot3 a b) */ +static node* +new_dot3(parser_state *p, node *a, node *b) +{ + return cons((node*)NODE_DOT3, cons(a, b)); +} + +/* (:colon2 b c) */ +static node* +new_colon2(parser_state *p, node *b, mrb_sym c) +{ + void_expr_error(p, b); + return cons((node*)NODE_COLON2, cons(b, nsym(c))); +} + +/* (:colon3 . c) */ +static node* +new_colon3(parser_state *p, mrb_sym c) +{ + return cons((node*)NODE_COLON3, nsym(c)); +} + +/* (:and a b) */ +static node* +new_and(parser_state *p, node *a, node *b) +{ + return cons((node*)NODE_AND, cons(a, b)); +} + +/* (:or a b) */ +static node* +new_or(parser_state *p, node *a, node *b) +{ + return cons((node*)NODE_OR, cons(a, b)); +} + +/* (:array a...) */ +static node* +new_array(parser_state *p, node *a) +{ + return cons((node*)NODE_ARRAY, a); +} + +/* (:splat . a) */ +static node* +new_splat(parser_state *p, node *a) +{ + return cons((node*)NODE_SPLAT, a); +} + +/* (:hash (k . v) (k . v)...) */ +static node* +new_hash(parser_state *p, node *a) +{ + return cons((node*)NODE_HASH, a); +} + +/* (:sym . a) */ +static node* +new_sym(parser_state *p, mrb_sym sym) +{ + return cons((node*)NODE_SYM, nsym(sym)); +} + +static mrb_sym +new_strsym(parser_state *p, node* str) +{ + const char *s = (const char*)str->cdr->car; + size_t len = (size_t)str->cdr->cdr; + + return mrb_intern(p->mrb, s, len); +} + +/* (:lvar . a) */ +static node* +new_lvar(parser_state *p, mrb_sym sym) +{ + return cons((node*)NODE_LVAR, nsym(sym)); +} + +/* (:gvar . a) */ +static node* +new_gvar(parser_state *p, mrb_sym sym) +{ + return cons((node*)NODE_GVAR, nsym(sym)); +} + +/* (:ivar . a) */ +static node* +new_ivar(parser_state *p, mrb_sym sym) +{ + return cons((node*)NODE_IVAR, nsym(sym)); +} + +/* (:cvar . a) */ +static node* +new_cvar(parser_state *p, mrb_sym sym) +{ + return cons((node*)NODE_CVAR, nsym(sym)); +} + +/* (:const . a) */ +static node* +new_const(parser_state *p, mrb_sym sym) +{ + return cons((node*)NODE_CONST, nsym(sym)); +} + +/* (:undef a...) */ +static node* +new_undef(parser_state *p, mrb_sym sym) +{ + return list2((node*)NODE_UNDEF, nsym(sym)); +} + +/* (:class class super body) */ +static node* +new_class(parser_state *p, node *c, node *s, node *b) +{ + void_expr_error(p, s); + return list4((node*)NODE_CLASS, c, s, cons(locals_node(p), b)); +} + +/* (:sclass obj body) */ +static node* +new_sclass(parser_state *p, node *o, node *b) +{ + void_expr_error(p, o); + return list3((node*)NODE_SCLASS, o, cons(locals_node(p), b)); +} + +/* (:module module body) */ +static node* +new_module(parser_state *p, node *m, node *b) +{ + return list3((node*)NODE_MODULE, m, cons(locals_node(p), b)); +} + +/* (:def m lv (arg . body)) */ +static node* +new_def(parser_state *p, mrb_sym m, node *a, node *b) +{ + return list5((node*)NODE_DEF, nsym(m), locals_node(p), a, b); +} + +/* (:sdef obj m lv (arg . body)) */ +static node* +new_sdef(parser_state *p, node *o, mrb_sym m, node *a, node *b) +{ + void_expr_error(p, o); + return list6((node*)NODE_SDEF, o, nsym(m), locals_node(p), a, b); +} + +/* (:arg . sym) */ +static node* +new_arg(parser_state *p, mrb_sym sym) +{ + return cons((node*)NODE_ARG, nsym(sym)); +} + +/* (m o r m2 b) */ +/* m: (a b c) */ +/* o: ((a . e1) (b . e2)) */ +/* r: a */ +/* m2: (a b c) */ +/* b: a */ +static node* +new_args(parser_state *p, node *m, node *opt, mrb_sym rest, node *m2, mrb_sym blk) +{ + node *n; + + n = cons(m2, nsym(blk)); + n = cons(nsym(rest), n); + n = cons(opt, n); + return cons(m, n); +} + +/* (:block_arg . a) */ +static node* +new_block_arg(parser_state *p, node *a) +{ + return cons((node*)NODE_BLOCK_ARG, a); +} + +/* (:block arg body) */ +static node* +new_block(parser_state *p, node *a, node *b) +{ + return list4((node*)NODE_BLOCK, locals_node(p), a, b); +} + +/* (:lambda arg body) */ +static node* +new_lambda(parser_state *p, node *a, node *b) +{ + return list4((node*)NODE_LAMBDA, locals_node(p), a, b); +} + +/* (:asgn lhs rhs) */ +static node* +new_asgn(parser_state *p, node *a, node *b) +{ + void_expr_error(p, b); + return cons((node*)NODE_ASGN, cons(a, b)); +} + +/* (:masgn mlhs=(pre rest post) mrhs) */ +static node* +new_masgn(parser_state *p, node *a, node *b) +{ + void_expr_error(p, b); + return cons((node*)NODE_MASGN, cons(a, b)); +} + +/* (:asgn lhs rhs) */ +static node* +new_op_asgn(parser_state *p, node *a, mrb_sym op, node *b) +{ + void_expr_error(p, b); + return list4((node*)NODE_OP_ASGN, a, nsym(op), b); +} + +/* (:int . i) */ +static node* +new_int(parser_state *p, const char *s, int base) +{ + return list3((node*)NODE_INT, (node*)strdup(s), nint(base)); +} + +/* (:float . i) */ +static node* +new_float(parser_state *p, const char *s) +{ + return cons((node*)NODE_FLOAT, (node*)strdup(s)); +} + +/* (:str . (s . len)) */ +static node* +new_str(parser_state *p, const char *s, size_t len) +{ + return cons((node*)NODE_STR, cons((node*)strndup(s, len), nint(len))); +} + +/* (:dstr . a) */ +static node* +new_dstr(parser_state *p, node *a) +{ + return cons((node*)NODE_DSTR, a); +} + +/* (:str . (s . len)) */ +static node* +new_xstr(parser_state *p, const char *s, int len) +{ + return cons((node*)NODE_XSTR, cons((node*)strndup(s, len), nint(len))); +} + +/* (:xstr . a) */ +static node* +new_dxstr(parser_state *p, node *a) +{ + return cons((node*)NODE_DXSTR, a); +} + +/* (:dsym . a) */ +static node* +new_dsym(parser_state *p, node *a) +{ + return cons((node*)NODE_DSYM, new_dstr(p, a)); +} + +/* (:regx . (s . (opt . enc))) */ +static node* +new_regx(parser_state *p, const char *p1, const char* p2, const char* p3) +{ + return cons((node*)NODE_REGX, cons((node*)p1, cons((node*)p2, (node*)p3))); +} + +/* (:dregx . (a . b)) */ +static node* +new_dregx(parser_state *p, node *a, node *b) +{ + return cons((node*)NODE_DREGX, cons(a, b)); +} + +/* (:backref . n) */ +static node* +new_back_ref(parser_state *p, int n) +{ + return cons((node*)NODE_BACK_REF, nint(n)); +} + +/* (:nthref . n) */ +static node* +new_nth_ref(parser_state *p, int n) +{ + return cons((node*)NODE_NTH_REF, nint(n)); +} + +/* (:heredoc . a) */ +static node* +new_heredoc(parser_state *p) +{ + parser_heredoc_info *inf = (parser_heredoc_info *)parser_palloc(p, sizeof(parser_heredoc_info)); + return cons((node*)NODE_HEREDOC, (node*)inf); +} + +static void +new_bv(parser_state *p, mrb_sym id) +{ +} + +static node* +new_literal_delim(parser_state *p) +{ + return cons((node*)NODE_LITERAL_DELIM, 0); +} + +/* (:words . a) */ +static node* +new_words(parser_state *p, node *a) +{ + return cons((node*)NODE_WORDS, a); +} + +/* (:symbols . a) */ +static node* +new_symbols(parser_state *p, node *a) +{ + return cons((node*)NODE_SYMBOLS, a); +} + +/* xxx ----------------------------- */ + +/* (:call a op) */ +static node* +call_uni_op(parser_state *p, node *recv, const char *m) +{ + void_expr_error(p, recv); + return new_call(p, recv, intern_cstr(m), 0, 1); +} + +/* (:call a op b) */ +static node* +call_bin_op(parser_state *p, node *recv, const char *m, node *arg1) +{ + return new_call(p, recv, intern_cstr(m), list1(list1(arg1)), 1); +} + +static void +args_with_block(parser_state *p, node *a, node *b) +{ + if (b) { + if (a->cdr) { + yyerror(p, "both block arg and actual block given"); + } + a->cdr = b; + } +} + +static void +call_with_block(parser_state *p, node *a, node *b) +{ + node *n; + + switch ((enum node_type)intn(a->car)) { + case NODE_SUPER: + case NODE_ZSUPER: + if (!a->cdr) a->cdr = cons(0, b); + else { + args_with_block(p, a->cdr, b); + } + break; + case NODE_CALL: + case NODE_FCALL: + case NODE_SCALL: + n = a->cdr->cdr->cdr; + if (!n->car) n->car = cons(0, b); + else { + args_with_block(p, n->car, b); + } + break; + default: + break; + } +} + +static node* +negate_lit(parser_state *p, node *n) +{ + return cons((node*)NODE_NEGATE, n); +} + +static node* +cond(node *n) +{ + return n; +} + +static node* +ret_args(parser_state *p, node *n) +{ + if (n->cdr) { + yyerror(p, "block argument should not be given"); + return NULL; + } + if (!n->car->cdr) return n->car->car; + return new_array(p, n->car); +} + +static void +assignable(parser_state *p, node *lhs) +{ + if (intn(lhs->car) == NODE_LVAR) { + local_add(p, sym(lhs->cdr)); + } +} + +static node* +var_reference(parser_state *p, node *lhs) +{ + node *n; + + if (intn(lhs->car) == NODE_LVAR) { + if (!local_var_p(p, sym(lhs->cdr))) { + n = new_fcall(p, sym(lhs->cdr), 0); + cons_free(lhs); + return n; + } + } + + return lhs; +} + +typedef enum mrb_string_type string_type; + +static node* +new_strterm(parser_state *p, string_type type, int term, int paren) +{ + return cons(nint(type), cons((node*)0, cons(nint(paren), nint(term)))); +} + +static void +end_strterm(parser_state *p) +{ + cons_free(p->lex_strterm->cdr->cdr); + cons_free(p->lex_strterm->cdr); + cons_free(p->lex_strterm); + p->lex_strterm = NULL; +} + +static parser_heredoc_info * +parsing_heredoc_inf(parser_state *p) +{ + node *nd = p->parsing_heredoc; + if (nd == NULL) + return NULL; + /* mrb_assert(nd->car->car == NODE_HEREDOC); */ + return (parser_heredoc_info*)nd->car->cdr; +} + +static void +heredoc_treat_nextline(parser_state *p) +{ + if (p->heredocs_from_nextline == NULL) + return; + if (p->parsing_heredoc == NULL) { + node *n; + p->parsing_heredoc = p->heredocs_from_nextline; + p->lex_strterm_before_heredoc = p->lex_strterm; + p->lex_strterm = new_strterm(p, parsing_heredoc_inf(p)->type, 0, 0); + n = p->all_heredocs; + if (n) { + while (n->cdr) + n = n->cdr; + n->cdr = p->parsing_heredoc; + } + else { + p->all_heredocs = p->parsing_heredoc; + } + } + else { + node *n, *m; + m = p->heredocs_from_nextline; + while (m->cdr) + m = m->cdr; + n = p->all_heredocs; + mrb_assert(n != NULL); + if (n == p->parsing_heredoc) { + m->cdr = n; + p->all_heredocs = p->heredocs_from_nextline; + p->parsing_heredoc = p->heredocs_from_nextline; + } + else { + while (n->cdr != p->parsing_heredoc) { + n = n->cdr; + mrb_assert(n != NULL); + } + m->cdr = n->cdr; + n->cdr = p->heredocs_from_nextline; + p->parsing_heredoc = p->heredocs_from_nextline; + } + } + p->heredocs_from_nextline = NULL; +} + +static void +heredoc_end(parser_state *p) +{ + p->parsing_heredoc = p->parsing_heredoc->cdr; + if (p->parsing_heredoc == NULL) { + p->lstate = EXPR_BEG; + p->cmd_start = TRUE; + end_strterm(p); + p->lex_strterm = p->lex_strterm_before_heredoc; + p->lex_strterm_before_heredoc = NULL; + p->heredoc_end_now = TRUE; + } + else { + /* next heredoc */ + p->lex_strterm->car = nint(parsing_heredoc_inf(p)->type); + } +} +#define is_strterm_type(p,str_func) (intn((p)->lex_strterm->car) & (str_func)) + +/* xxx ----------------------------- */ + +%} + +%pure-parser +%parse-param {parser_state *p} +%lex-param {parser_state *p} + +%union { + node *nd; + mrb_sym id; + int num; + stack_type stack; + const struct vtable *vars; +} + +%token + keyword_class + keyword_module + keyword_def + keyword_begin + keyword_if + keyword_unless + keyword_while + keyword_until + keyword_for + +%token + keyword_undef + keyword_rescue + keyword_ensure + keyword_end + keyword_then + keyword_elsif + keyword_else + keyword_case + keyword_when + keyword_break + keyword_next + keyword_redo + keyword_retry + keyword_in + keyword_do + keyword_do_cond + keyword_do_block + keyword_do_LAMBDA + keyword_return + keyword_yield + keyword_super + keyword_self + keyword_nil + keyword_true + keyword_false + keyword_and + keyword_or + keyword_not + modifier_if + modifier_unless + modifier_while + modifier_until + modifier_rescue + keyword_alias + keyword_BEGIN + keyword_END + keyword__LINE__ + keyword__FILE__ + keyword__ENCODING__ + +%token tIDENTIFIER tFID tGVAR tIVAR tCONSTANT tCVAR tLABEL +%token tINTEGER tFLOAT tCHAR tXSTRING tREGEXP +%token tSTRING tSTRING_PART tSTRING_MID tLABEL_END +%token tNTH_REF tBACK_REF +%token tREGEXP_END + +%type singleton string string_rep string_interp xstring regexp +%type literal numeric cpath symbol +%type top_compstmt top_stmts top_stmt +%type bodystmt compstmt stmts stmt expr arg primary command command_call method_call +%type expr_value arg_rhs primary_value +%type if_tail opt_else case_body cases opt_rescue exc_list exc_var opt_ensure +%type args call_args opt_call_args +%type paren_args opt_paren_args variable +%type command_args aref_args opt_block_arg block_arg var_ref var_lhs +%type command_asgn command_rhs mrhs superclass block_call block_command +%type f_block_optarg f_block_opt +%type f_arglist f_args f_arg f_arg_item f_optarg f_marg f_marg_list f_margs +%type assoc_list assocs assoc undef_list backref for_var +%type block_param opt_block_param block_param_def f_opt +%type bv_decls opt_bv_decl bvar f_larglist lambda_body +%type brace_block cmd_brace_block do_block lhs none f_bad_arg +%type mlhs mlhs_list mlhs_post mlhs_basic mlhs_item mlhs_node mlhs_inner +%type fsym sym basic_symbol operation operation2 operation3 +%type cname fname op f_rest_arg f_block_arg opt_f_block_arg f_norm_arg f_opt_asgn +%type heredoc words symbols +%type call_op call_op2 /* 0:'&.', 1:'.', 2:'::' */ + +%token tUPLUS /* unary+ */ +%token tUMINUS /* unary- */ +%token tPOW /* ** */ +%token tCMP /* <=> */ +%token tEQ /* == */ +%token tEQQ /* === */ +%token tNEQ /* != */ +%token tGEQ /* >= */ +%token tLEQ /* <= */ +%token tANDOP tOROP /* && and || */ +%token tMATCH tNMATCH /* =~ and !~ */ +%token tDOT2 tDOT3 /* .. and ... */ +%token tAREF tASET /* [] and []= */ +%token tLSHFT tRSHFT /* << and >> */ +%token tCOLON2 /* :: */ +%token tCOLON3 /* :: at EXPR_BEG */ +%token tOP_ASGN /* +=, -= etc. */ +%token tASSOC /* => */ +%token tLPAREN /* ( */ +%token tLPAREN_ARG /* ( */ +%token tRPAREN /* ) */ +%token tLBRACK /* [ */ +%token tLBRACE /* { */ +%token tLBRACE_ARG /* { */ +%token tSTAR /* * */ +%token tAMPER /* & */ +%token tLAMBDA /* -> */ +%token tANDDOT /* &. */ +%token tSYMBEG tREGEXP_BEG tWORDS_BEG tSYMBOLS_BEG +%token tSTRING_BEG tXSTRING_BEG tSTRING_DVAR tLAMBEG +%token tHEREDOC_BEG /* <<, <<- */ +%token tHEREDOC_END tLITERAL_DELIM tHD_LITERAL_DELIM +%token tHD_STRING_PART tHD_STRING_MID + +/* + * precedence table + */ + +%nonassoc tLOWEST +%nonassoc tLBRACE_ARG + +%nonassoc modifier_if modifier_unless modifier_while modifier_until +%left keyword_or keyword_and +%right keyword_not +%right '=' tOP_ASGN +%left modifier_rescue +%right '?' ':' +%nonassoc tDOT2 tDOT3 +%left tOROP +%left tANDOP +%nonassoc tCMP tEQ tEQQ tNEQ tMATCH tNMATCH +%left '>' tGEQ '<' tLEQ +%left '|' '^' +%left '&' +%left tLSHFT tRSHFT +%left '+' '-' +%left '*' '/' '%' +%right tUMINUS_NUM tUMINUS +%right tPOW +%right '!' '~' tUPLUS + +%token tLAST_TOKEN + +%% +program : { + p->lstate = EXPR_BEG; + if (!p->locals) p->locals = cons(0,0); + } + top_compstmt + { + p->tree = new_scope(p, $2); + NODE_LINENO(p->tree, $2); + } + ; + +top_compstmt : top_stmts opt_terms + { + $$ = $1; + } + ; + +top_stmts : none + { + $$ = new_begin(p, 0); + } + | top_stmt + { + $$ = new_begin(p, $1); + NODE_LINENO($$, $1); + } + | top_stmts terms top_stmt + { + $$ = push($1, newline_node($3)); + } + | error top_stmt + { + $$ = new_begin(p, 0); + } + ; + +top_stmt : stmt + | keyword_BEGIN + { + $$ = local_switch(p); + } + '{' top_compstmt '}' + { + yyerror(p, "BEGIN not supported"); + local_resume(p, $2); + $$ = 0; + } + ; + +bodystmt : compstmt + opt_rescue + opt_else + opt_ensure + { + if ($2) { + $$ = new_rescue(p, $1, $2, $3); + NODE_LINENO($$, $1); + } + else if ($3) { + yywarn(p, "else without rescue is useless"); + $$ = push($1, $3); + } + else { + $$ = $1; + } + if ($4) { + if ($$) { + $$ = new_ensure(p, $$, $4); + } + else { + $$ = push($4, new_nil(p)); + } + } + } + ; + +compstmt : stmts opt_terms + { + $$ = $1; + } + ; + +stmts : none + { + $$ = new_begin(p, 0); + } + | stmt + { + $$ = new_begin(p, $1); + NODE_LINENO($$, $1); + } + | stmts terms stmt + { + $$ = push($1, newline_node($3)); + } + | error stmt + { + $$ = new_begin(p, $2); + } + ; + +stmt : keyword_alias fsym {p->lstate = EXPR_FNAME;} fsym + { + $$ = new_alias(p, $2, $4); + } + | keyword_undef undef_list + { + $$ = $2; + } + | stmt modifier_if expr_value + { + $$ = new_if(p, cond($3), $1, 0); + } + | stmt modifier_unless expr_value + { + $$ = new_unless(p, cond($3), $1, 0); + } + | stmt modifier_while expr_value + { + $$ = new_while(p, cond($3), $1); + } + | stmt modifier_until expr_value + { + $$ = new_until(p, cond($3), $1); + } + | stmt modifier_rescue stmt + { + $$ = new_mod_rescue(p, $1, $3); + } + | keyword_END '{' compstmt '}' + { + yyerror(p, "END not supported"); + $$ = new_postexe(p, $3); + } + | command_asgn + | mlhs '=' command_call + { + $$ = new_masgn(p, $1, $3); + } + | lhs '=' mrhs + { + $$ = new_asgn(p, $1, new_array(p, $3)); + } + | mlhs '=' arg + { + $$ = new_masgn(p, $1, $3); + } + | mlhs '=' mrhs + { + $$ = new_masgn(p, $1, new_array(p, $3)); + } + | expr + ; + +command_asgn : lhs '=' command_rhs + { + $$ = new_asgn(p, $1, $3); + } + | var_lhs tOP_ASGN command_rhs + { + $$ = new_op_asgn(p, $1, $2, $3); + } + | primary_value '[' opt_call_args rbracket tOP_ASGN command_rhs + { + $$ = new_op_asgn(p, new_call(p, $1, intern("[]",2), $3, '.'), $5, $6); + } + | primary_value call_op tIDENTIFIER tOP_ASGN command_rhs + { + $$ = new_op_asgn(p, new_call(p, $1, $3, 0, $2), $4, $5); + } + | primary_value call_op tCONSTANT tOP_ASGN command_rhs + { + $$ = new_op_asgn(p, new_call(p, $1, $3, 0, $2), $4, $5); + } + | primary_value tCOLON2 tCONSTANT tOP_ASGN command_call + { + yyerror(p, "constant re-assignment"); + $$ = 0; + } + | primary_value tCOLON2 tIDENTIFIER tOP_ASGN command_rhs + { + $$ = new_op_asgn(p, new_call(p, $1, $3, 0, tCOLON2), $4, $5); + } + | backref tOP_ASGN command_rhs + { + backref_error(p, $1); + $$ = new_begin(p, 0); + } + ; + +command_rhs : command_call %prec tOP_ASGN + | command_call modifier_rescue stmt + { + $$ = new_mod_rescue(p, $1, $3); + } + | command_asgn + ; + + +expr : command_call + | expr keyword_and expr + { + $$ = new_and(p, $1, $3); + } + | expr keyword_or expr + { + $$ = new_or(p, $1, $3); + } + | keyword_not opt_nl expr + { + $$ = call_uni_op(p, cond($3), "!"); + } + | '!' command_call + { + $$ = call_uni_op(p, cond($2), "!"); + } + | arg + ; + +expr_value : expr + { + if (!$1) $$ = new_nil(p); + else { + $$ = $1; + } + } + ; + +command_call : command + | block_command + ; + +block_command : block_call + | block_call call_op2 operation2 command_args + { + $$ = new_call(p, $1, $3, $4, $2); + } + ; + +cmd_brace_block : tLBRACE_ARG + { + local_nest(p); + } + opt_block_param + compstmt + '}' + { + $$ = new_block(p, $3, $4); + local_unnest(p); + } + ; + +command : operation command_args %prec tLOWEST + { + $$ = new_fcall(p, $1, $2); + } + | operation command_args cmd_brace_block + { + args_with_block(p, $2, $3); + $$ = new_fcall(p, $1, $2); + } + | primary_value call_op operation2 command_args %prec tLOWEST + { + $$ = new_call(p, $1, $3, $4, $2); + } + | primary_value call_op operation2 command_args cmd_brace_block + { + args_with_block(p, $4, $5); + $$ = new_call(p, $1, $3, $4, $2); + } + | primary_value tCOLON2 operation2 command_args %prec tLOWEST + { + $$ = new_call(p, $1, $3, $4, tCOLON2); + } + | primary_value tCOLON2 operation2 command_args cmd_brace_block + { + args_with_block(p, $4, $5); + $$ = new_call(p, $1, $3, $4, tCOLON2); + } + | keyword_super command_args + { + $$ = new_super(p, $2); + } + | keyword_yield command_args + { + $$ = new_yield(p, $2); + } + | keyword_return call_args + { + $$ = new_return(p, ret_args(p, $2)); + } + | keyword_break call_args + { + $$ = new_break(p, ret_args(p, $2)); + } + | keyword_next call_args + { + $$ = new_next(p, ret_args(p, $2)); + } + ; + +mlhs : mlhs_basic + { + $$ = $1; + } + | tLPAREN mlhs_inner rparen + { + $$ = $2; + } + ; + +mlhs_inner : mlhs_basic + | tLPAREN mlhs_inner rparen + { + $$ = $2; + } + ; + +mlhs_basic : mlhs_list + { + $$ = list1($1); + } + | mlhs_list mlhs_item + { + $$ = list1(push($1,$2)); + } + | mlhs_list tSTAR mlhs_node + { + $$ = list2($1, $3); + } + | mlhs_list tSTAR mlhs_node ',' mlhs_post + { + $$ = list3($1, $3, $5); + } + | mlhs_list tSTAR + { + $$ = list2($1, new_nil(p)); + } + | mlhs_list tSTAR ',' mlhs_post + { + $$ = list3($1, new_nil(p), $4); + } + | tSTAR mlhs_node + { + $$ = list2(0, $2); + } + | tSTAR mlhs_node ',' mlhs_post + { + $$ = list3(0, $2, $4); + } + | tSTAR + { + $$ = list2(0, new_nil(p)); + } + | tSTAR ',' mlhs_post + { + $$ = list3(0, new_nil(p), $3); + } + ; + +mlhs_item : mlhs_node + | tLPAREN mlhs_inner rparen + { + $$ = new_masgn(p, $2, NULL); + } + ; + +mlhs_list : mlhs_item ',' + { + $$ = list1($1); + } + | mlhs_list mlhs_item ',' + { + $$ = push($1, $2); + } + ; + +mlhs_post : mlhs_item + { + $$ = list1($1); + } + | mlhs_list mlhs_item + { + $$ = push($1, $2); + } + ; + +mlhs_node : variable + { + assignable(p, $1); + } + | primary_value '[' opt_call_args rbracket + { + $$ = new_call(p, $1, intern("[]",2), $3, '.'); + } + | primary_value call_op tIDENTIFIER + { + $$ = new_call(p, $1, $3, 0, $2); + } + | primary_value tCOLON2 tIDENTIFIER + { + $$ = new_call(p, $1, $3, 0, tCOLON2); + } + | primary_value call_op tCONSTANT + { + $$ = new_call(p, $1, $3, 0, $2); + } + | primary_value tCOLON2 tCONSTANT + { + if (p->in_def || p->in_single) + yyerror(p, "dynamic constant assignment"); + $$ = new_colon2(p, $1, $3); + } + | tCOLON3 tCONSTANT + { + if (p->in_def || p->in_single) + yyerror(p, "dynamic constant assignment"); + $$ = new_colon3(p, $2); + } + | backref + { + backref_error(p, $1); + $$ = 0; + } + ; + +lhs : variable + { + assignable(p, $1); + } + | primary_value '[' opt_call_args rbracket + { + $$ = new_call(p, $1, intern("[]",2), $3, '.'); + } + | primary_value call_op tIDENTIFIER + { + $$ = new_call(p, $1, $3, 0, $2); + } + | primary_value tCOLON2 tIDENTIFIER + { + $$ = new_call(p, $1, $3, 0, tCOLON2); + } + | primary_value call_op tCONSTANT + { + $$ = new_call(p, $1, $3, 0, $2); + } + | primary_value tCOLON2 tCONSTANT + { + if (p->in_def || p->in_single) + yyerror(p, "dynamic constant assignment"); + $$ = new_colon2(p, $1, $3); + } + | tCOLON3 tCONSTANT + { + if (p->in_def || p->in_single) + yyerror(p, "dynamic constant assignment"); + $$ = new_colon3(p, $2); + } + | backref + { + backref_error(p, $1); + $$ = 0; + } + ; + +cname : tIDENTIFIER + { + yyerror(p, "class/module name must be CONSTANT"); + } + | tCONSTANT + ; + +cpath : tCOLON3 cname + { + $$ = cons((node*)1, nsym($2)); + } + | cname + { + $$ = cons((node*)0, nsym($1)); + } + | primary_value tCOLON2 cname + { + void_expr_error(p, $1); + $$ = cons($1, nsym($3)); + } + ; + +fname : tIDENTIFIER + | tCONSTANT + | tFID + | op + { + p->lstate = EXPR_ENDFN; + $$ = $1; + } + | reswords + { + p->lstate = EXPR_ENDFN; + $$ = $1; + } + ; + +fsym : fname + | basic_symbol + ; + +undef_list : fsym + { + $$ = new_undef(p, $1); + } + | undef_list ',' {p->lstate = EXPR_FNAME;} fsym + { + $$ = push($1, nsym($4)); + } + ; + +op : '|' { $$ = intern_c('|'); } + | '^' { $$ = intern_c('^'); } + | '&' { $$ = intern_c('&'); } + | tCMP { $$ = intern("<=>",3); } + | tEQ { $$ = intern("==",2); } + | tEQQ { $$ = intern("===",3); } + | tMATCH { $$ = intern("=~",2); } + | tNMATCH { $$ = intern("!~",2); } + | '>' { $$ = intern_c('>'); } + | tGEQ { $$ = intern(">=",2); } + | '<' { $$ = intern_c('<'); } + | tLEQ { $$ = intern("<=",2); } + | tNEQ { $$ = intern("!=",2); } + | tLSHFT { $$ = intern("<<",2); } + | tRSHFT { $$ = intern(">>",2); } + | '+' { $$ = intern_c('+'); } + | '-' { $$ = intern_c('-'); } + | '*' { $$ = intern_c('*'); } + | tSTAR { $$ = intern_c('*'); } + | '/' { $$ = intern_c('/'); } + | '%' { $$ = intern_c('%'); } + | tPOW { $$ = intern("**",2); } + | '!' { $$ = intern_c('!'); } + | '~' { $$ = intern_c('~'); } + | tUPLUS { $$ = intern("+@",2); } + | tUMINUS { $$ = intern("-@",2); } + | tAREF { $$ = intern("[]",2); } + | tASET { $$ = intern("[]=",3); } + | '`' { $$ = intern_c('`'); } + ; + +reswords : keyword__LINE__ | keyword__FILE__ | keyword__ENCODING__ + | keyword_BEGIN | keyword_END + | keyword_alias | keyword_and | keyword_begin + | keyword_break | keyword_case | keyword_class | keyword_def + | keyword_do | keyword_else | keyword_elsif + | keyword_end | keyword_ensure | keyword_false + | keyword_for | keyword_in | keyword_module | keyword_next + | keyword_nil | keyword_not | keyword_or | keyword_redo + | keyword_rescue | keyword_retry | keyword_return | keyword_self + | keyword_super | keyword_then | keyword_true | keyword_undef + | keyword_when | keyword_yield | keyword_if | keyword_unless + | keyword_while | keyword_until + ; + +arg : lhs '=' arg_rhs + { + $$ = new_asgn(p, $1, $3); + } + | var_lhs tOP_ASGN arg_rhs + { + $$ = new_op_asgn(p, $1, $2, $3); + } + | primary_value '[' opt_call_args rbracket tOP_ASGN arg_rhs + { + $$ = new_op_asgn(p, new_call(p, $1, intern("[]",2), $3, '.'), $5, $6); + } + | primary_value call_op tIDENTIFIER tOP_ASGN arg_rhs + { + $$ = new_op_asgn(p, new_call(p, $1, $3, 0, $2), $4, $5); + } + | primary_value call_op tCONSTANT tOP_ASGN arg_rhs + { + $$ = new_op_asgn(p, new_call(p, $1, $3, 0, $2), $4, $5); + } + | primary_value tCOLON2 tIDENTIFIER tOP_ASGN arg_rhs + { + $$ = new_op_asgn(p, new_call(p, $1, $3, 0, tCOLON2), $4, $5); + } + | primary_value tCOLON2 tCONSTANT tOP_ASGN arg_rhs + { + yyerror(p, "constant re-assignment"); + $$ = new_begin(p, 0); + } + | tCOLON3 tCONSTANT tOP_ASGN arg_rhs + { + yyerror(p, "constant re-assignment"); + $$ = new_begin(p, 0); + } + | backref tOP_ASGN arg_rhs + { + backref_error(p, $1); + $$ = new_begin(p, 0); + } + | arg tDOT2 arg + { + $$ = new_dot2(p, $1, $3); + } + | arg tDOT3 arg + { + $$ = new_dot3(p, $1, $3); + } + | arg '+' arg + { + $$ = call_bin_op(p, $1, "+", $3); + } + | arg '-' arg + { + $$ = call_bin_op(p, $1, "-", $3); + } + | arg '*' arg + { + $$ = call_bin_op(p, $1, "*", $3); + } + | arg '/' arg + { + $$ = call_bin_op(p, $1, "/", $3); + } + | arg '%' arg + { + $$ = call_bin_op(p, $1, "%", $3); + } + | arg tPOW arg + { + $$ = call_bin_op(p, $1, "**", $3); + } + | tUMINUS_NUM tINTEGER tPOW arg + { + $$ = call_uni_op(p, call_bin_op(p, $2, "**", $4), "-@"); + } + | tUMINUS_NUM tFLOAT tPOW arg + { + $$ = call_uni_op(p, call_bin_op(p, $2, "**", $4), "-@"); + } + | tUPLUS arg + { + $$ = call_uni_op(p, $2, "+@"); + } + | tUMINUS arg + { + $$ = call_uni_op(p, $2, "-@"); + } + | arg '|' arg + { + $$ = call_bin_op(p, $1, "|", $3); + } + | arg '^' arg + { + $$ = call_bin_op(p, $1, "^", $3); + } + | arg '&' arg + { + $$ = call_bin_op(p, $1, "&", $3); + } + | arg tCMP arg + { + $$ = call_bin_op(p, $1, "<=>", $3); + } + | arg '>' arg + { + $$ = call_bin_op(p, $1, ">", $3); + } + | arg tGEQ arg + { + $$ = call_bin_op(p, $1, ">=", $3); + } + | arg '<' arg + { + $$ = call_bin_op(p, $1, "<", $3); + } + | arg tLEQ arg + { + $$ = call_bin_op(p, $1, "<=", $3); + } + | arg tEQ arg + { + $$ = call_bin_op(p, $1, "==", $3); + } + | arg tEQQ arg + { + $$ = call_bin_op(p, $1, "===", $3); + } + | arg tNEQ arg + { + $$ = call_bin_op(p, $1, "!=", $3); + } + | arg tMATCH arg + { + $$ = call_bin_op(p, $1, "=~", $3); + } + | arg tNMATCH arg + { + $$ = call_bin_op(p, $1, "!~", $3); + } + | '!' arg + { + $$ = call_uni_op(p, cond($2), "!"); + } + | '~' arg + { + $$ = call_uni_op(p, cond($2), "~"); + } + | arg tLSHFT arg + { + $$ = call_bin_op(p, $1, "<<", $3); + } + | arg tRSHFT arg + { + $$ = call_bin_op(p, $1, ">>", $3); + } + | arg tANDOP arg + { + $$ = new_and(p, $1, $3); + } + | arg tOROP arg + { + $$ = new_or(p, $1, $3); + } + | arg '?' arg opt_nl ':' arg + { + $$ = new_if(p, cond($1), $3, $6); + } + | primary + { + $$ = $1; + } + ; + +aref_args : none + | args trailer + { + $$ = $1; + NODE_LINENO($$, $1); + } + | args comma assocs trailer + { + $$ = push($1, new_hash(p, $3)); + } + | assocs trailer + { + $$ = cons(new_hash(p, $1), 0); + NODE_LINENO($$, $1); + } + ; + +arg_rhs : arg %prec tOP_ASGN + { + $$ = $1; + } + | arg modifier_rescue arg + { + void_expr_error(p, $1); + void_expr_error(p, $3); + $$ = new_mod_rescue(p, $1, $3); + } + ; + +paren_args : '(' opt_call_args rparen + { + $$ = $2; + } + ; + +opt_paren_args : none + | paren_args + ; + +opt_call_args : none + | call_args + | args ',' + { + $$ = cons($1,0); + NODE_LINENO($$, $1); + } + | args comma assocs ',' + { + $$ = cons(push($1, new_hash(p, $3)), 0); + NODE_LINENO($$, $1); + } + | assocs ',' + { + $$ = cons(list1(new_hash(p, $1)), 0); + NODE_LINENO($$, $1); + } + ; + +call_args : command + { + void_expr_error(p, $1); + $$ = cons(list1($1), 0); + NODE_LINENO($$, $1); + } + | args opt_block_arg + { + $$ = cons($1, $2); + NODE_LINENO($$, $1); + } + | assocs opt_block_arg + { + $$ = cons(list1(new_hash(p, $1)), $2); + NODE_LINENO($$, $1); + } + | args comma assocs opt_block_arg + { + $$ = cons(push($1, new_hash(p, $3)), $4); + NODE_LINENO($$, $1); + } + | block_arg + { + $$ = cons(0, $1); + NODE_LINENO($$, $1); + } + ; + +command_args : { + $$ = p->cmdarg_stack; + CMDARG_PUSH(1); + } + call_args + { + p->cmdarg_stack = $1; + $$ = $2; + } + ; + +block_arg : tAMPER arg + { + $$ = new_block_arg(p, $2); + } + ; + +opt_block_arg : comma block_arg + { + $$ = $2; + } + | none + { + $$ = 0; + } + ; + +comma : ',' + | ',' heredoc_bodies + ; + +args : arg + { + void_expr_error(p, $1); + $$ = cons($1, 0); + NODE_LINENO($$, $1); + } + | tSTAR arg + { + void_expr_error(p, $2); + $$ = cons(new_splat(p, $2), 0); + NODE_LINENO($$, $2); + } + | args comma arg + { + void_expr_error(p, $3); + $$ = push($1, $3); + } + | args comma tSTAR arg + { + void_expr_error(p, $4); + $$ = push($1, new_splat(p, $4)); + } + ; + +mrhs : args comma arg + { + void_expr_error(p, $3); + $$ = push($1, $3); + } + | args comma tSTAR arg + { + void_expr_error(p, $4); + $$ = push($1, new_splat(p, $4)); + } + | tSTAR arg + { + void_expr_error(p, $2); + $$ = list1(new_splat(p, $2)); + } + ; + +primary : literal + | string + | xstring + | regexp + | heredoc + | var_ref + | backref + | tFID + { + $$ = new_fcall(p, $1, 0); + } + | keyword_begin + { + $$ = p->cmdarg_stack; + p->cmdarg_stack = 0; + } + bodystmt + keyword_end + { + p->cmdarg_stack = $2; + $$ = $3; + } + | tLPAREN_ARG + { + $$ = p->cmdarg_stack; + p->cmdarg_stack = 0; + } + stmt {p->lstate = EXPR_ENDARG;} rparen + { + p->cmdarg_stack = $2; + $$ = $3; + } + | tLPAREN_ARG {p->lstate = EXPR_ENDARG;} rparen + { + $$ = new_nil(p); + } + | tLPAREN compstmt ')' + { + $$ = $2; + } + | primary_value tCOLON2 tCONSTANT + { + $$ = new_colon2(p, $1, $3); + } + | tCOLON3 tCONSTANT + { + $$ = new_colon3(p, $2); + } + | tLBRACK aref_args ']' + { + $$ = new_array(p, $2); + NODE_LINENO($$, $2); + } + | tLBRACE assoc_list '}' + { + $$ = new_hash(p, $2); + NODE_LINENO($$, $2); + } + | keyword_return + { + $$ = new_return(p, 0); + } + | keyword_yield opt_paren_args + { + $$ = new_yield(p, $2); + } + | keyword_not '(' expr rparen + { + $$ = call_uni_op(p, cond($3), "!"); + } + | keyword_not '(' rparen + { + $$ = call_uni_op(p, new_nil(p), "!"); + } + | operation brace_block + { + $$ = new_fcall(p, $1, cons(0, $2)); + } + | method_call + | method_call brace_block + { + call_with_block(p, $1, $2); + $$ = $1; + } + | tLAMBDA + { + local_nest(p); + $$ = p->lpar_beg; + p->lpar_beg = ++p->paren_nest; + } + f_larglist + { + $$ = p->cmdarg_stack; + p->cmdarg_stack = 0; + } + lambda_body + { + p->lpar_beg = $2; + $$ = new_lambda(p, $3, $5); + local_unnest(p); + p->cmdarg_stack = $4; + CMDARG_LEXPOP(); + } + | keyword_if expr_value then + compstmt + if_tail + keyword_end + { + $$ = new_if(p, cond($2), $4, $5); + SET_LINENO($$, $1); + } + | keyword_unless expr_value then + compstmt + opt_else + keyword_end + { + $$ = new_unless(p, cond($2), $4, $5); + SET_LINENO($$, $1); + } + | keyword_while {COND_PUSH(1);} expr_value do {COND_POP();} + compstmt + keyword_end + { + $$ = new_while(p, cond($3), $6); + SET_LINENO($$, $1); + } + | keyword_until {COND_PUSH(1);} expr_value do {COND_POP();} + compstmt + keyword_end + { + $$ = new_until(p, cond($3), $6); + SET_LINENO($$, $1); + } + | keyword_case expr_value opt_terms + case_body + keyword_end + { + $$ = new_case(p, $2, $4); + } + | keyword_case opt_terms case_body keyword_end + { + $$ = new_case(p, 0, $3); + } + | keyword_for for_var keyword_in + {COND_PUSH(1);} + expr_value do + {COND_POP();} + compstmt + keyword_end + { + $$ = new_for(p, $2, $5, $8); + SET_LINENO($$, $1); + } + | keyword_class + cpath superclass + { + if (p->in_def || p->in_single) + yyerror(p, "class definition in method body"); + $$ = local_switch(p); + } + bodystmt + keyword_end + { + $$ = new_class(p, $2, $3, $5); + SET_LINENO($$, $1); + local_resume(p, $4); + } + | keyword_class + tLSHFT expr + { + $$ = p->in_def; + p->in_def = 0; + } + term + { + $$ = cons(local_switch(p), nint(p->in_single)); + p->in_single = 0; + } + bodystmt + keyword_end + { + $$ = new_sclass(p, $3, $7); + SET_LINENO($$, $1); + local_resume(p, $6->car); + p->in_def = $4; + p->in_single = intn($6->cdr); + } + | keyword_module + cpath + { + if (p->in_def || p->in_single) + yyerror(p, "module definition in method body"); + $$ = local_switch(p); + } + bodystmt + keyword_end + { + $$ = new_module(p, $2, $4); + SET_LINENO($$, $1); + local_resume(p, $3); + } + | keyword_def fname + { + $$ = p->cmdarg_stack; + p->cmdarg_stack = 0; + } + { + p->in_def++; + $$ = local_switch(p); + } + f_arglist + bodystmt + keyword_end + { + $$ = new_def(p, $2, $5, $6); + SET_LINENO($$, $1); + local_resume(p, $4); + p->in_def--; + p->cmdarg_stack = $3; + } + | keyword_def singleton dot_or_colon + { + p->lstate = EXPR_FNAME; + $$ = p->cmdarg_stack; + p->cmdarg_stack = 0; + } + fname + { + p->in_single++; + p->lstate = EXPR_ENDFN; /* force for args */ + $$ = local_switch(p); + } + f_arglist + bodystmt + keyword_end + { + $$ = new_sdef(p, $2, $5, $7, $8); + SET_LINENO($$, $1); + local_resume(p, $6); + p->in_single--; + p->cmdarg_stack = $4; + } + | keyword_break + { + $$ = new_break(p, 0); + } + | keyword_next + { + $$ = new_next(p, 0); + } + | keyword_redo + { + $$ = new_redo(p); + } + | keyword_retry + { + $$ = new_retry(p); + } + ; + +primary_value : primary + { + $$ = $1; + if (!$$) $$ = new_nil(p); + } + ; + +then : term + | keyword_then + | term keyword_then + ; + +do : term + | keyword_do_cond + ; + +if_tail : opt_else + | keyword_elsif expr_value then + compstmt + if_tail + { + $$ = new_if(p, cond($2), $4, $5); + } + ; + +opt_else : none + | keyword_else compstmt + { + $$ = $2; + } + ; + +for_var : lhs + { + $$ = list1(list1($1)); + } + | mlhs + ; + +f_marg : f_norm_arg + { + $$ = new_arg(p, $1); + } + | tLPAREN f_margs rparen + { + $$ = new_masgn(p, $2, 0); + } + ; + +f_marg_list : f_marg + { + $$ = list1($1); + } + | f_marg_list ',' f_marg + { + $$ = push($1, $3); + } + ; + +f_margs : f_marg_list + { + $$ = list3($1,0,0); + } + | f_marg_list ',' tSTAR f_norm_arg + { + $$ = list3($1, new_arg(p, $4), 0); + } + | f_marg_list ',' tSTAR f_norm_arg ',' f_marg_list + { + $$ = list3($1, new_arg(p, $4), $6); + } + | f_marg_list ',' tSTAR + { + $$ = list3($1, (node*)-1, 0); + } + | f_marg_list ',' tSTAR ',' f_marg_list + { + $$ = list3($1, (node*)-1, $5); + } + | tSTAR f_norm_arg + { + $$ = list3(0, new_arg(p, $2), 0); + } + | tSTAR f_norm_arg ',' f_marg_list + { + $$ = list3(0, new_arg(p, $2), $4); + } + | tSTAR + { + $$ = list3(0, (node*)-1, 0); + } + | tSTAR ',' f_marg_list + { + $$ = list3(0, (node*)-1, $3); + } + ; + +block_param : f_arg ',' f_block_optarg ',' f_rest_arg opt_f_block_arg + { + $$ = new_args(p, $1, $3, $5, 0, $6); + } + | f_arg ',' f_block_optarg ',' f_rest_arg ',' f_arg opt_f_block_arg + { + $$ = new_args(p, $1, $3, $5, $7, $8); + } + | f_arg ',' f_block_optarg opt_f_block_arg + { + $$ = new_args(p, $1, $3, 0, 0, $4); + } + | f_arg ',' f_block_optarg ',' f_arg opt_f_block_arg + { + $$ = new_args(p, $1, $3, 0, $5, $6); + } + | f_arg ',' f_rest_arg opt_f_block_arg + { + $$ = new_args(p, $1, 0, $3, 0, $4); + } + | f_arg ',' + { + $$ = new_args(p, $1, 0, 0, 0, 0); + } + | f_arg ',' f_rest_arg ',' f_arg opt_f_block_arg + { + $$ = new_args(p, $1, 0, $3, $5, $6); + } + | f_arg opt_f_block_arg + { + $$ = new_args(p, $1, 0, 0, 0, $2); + } + | f_block_optarg ',' f_rest_arg opt_f_block_arg + { + $$ = new_args(p, 0, $1, $3, 0, $4); + } + | f_block_optarg ',' f_rest_arg ',' f_arg opt_f_block_arg + { + $$ = new_args(p, 0, $1, $3, $5, $6); + } + | f_block_optarg opt_f_block_arg + { + $$ = new_args(p, 0, $1, 0, 0, $2); + } + | f_block_optarg ',' f_arg opt_f_block_arg + { + $$ = new_args(p, 0, $1, 0, $3, $4); + } + | f_rest_arg opt_f_block_arg + { + $$ = new_args(p, 0, 0, $1, 0, $2); + } + | f_rest_arg ',' f_arg opt_f_block_arg + { + $$ = new_args(p, 0, 0, $1, $3, $4); + } + | f_block_arg + { + $$ = new_args(p, 0, 0, 0, 0, $1); + } + ; + +opt_block_param : none + | block_param_def + { + p->cmd_start = TRUE; + $$ = $1; + } + ; + +block_param_def : '|' opt_bv_decl '|' + { + $$ = 0; + } + | tOROP + { + $$ = 0; + } + | '|' block_param opt_bv_decl '|' + { + $$ = $2; + } + ; + + +opt_bv_decl : opt_nl + { + $$ = 0; + } + | opt_nl ';' bv_decls opt_nl + { + $$ = 0; + } + ; + +bv_decls : bvar + | bv_decls ',' bvar + ; + +bvar : tIDENTIFIER + { + local_add_f(p, $1); + new_bv(p, $1); + } + | f_bad_arg + ; + +f_larglist : '(' f_args opt_bv_decl ')' + { + $$ = $2; + } + | f_args + { + $$ = $1; + } + ; + +lambda_body : tLAMBEG compstmt '}' + { + $$ = $2; + } + | keyword_do_LAMBDA compstmt keyword_end + { + $$ = $2; + } + ; + +do_block : keyword_do_block + { + local_nest(p); + } + opt_block_param + compstmt + keyword_end + { + $$ = new_block(p,$3,$4); + local_unnest(p); + } + ; + +block_call : command do_block + { + if ($1->car == (node*)NODE_YIELD) { + yyerror(p, "block given to yield"); + } + else { + call_with_block(p, $1, $2); + } + $$ = $1; + } + | block_call call_op2 operation2 opt_paren_args + { + $$ = new_call(p, $1, $3, $4, $2); + } + | block_call call_op2 operation2 opt_paren_args brace_block + { + $$ = new_call(p, $1, $3, $4, $2); + call_with_block(p, $$, $5); + } + | block_call call_op2 operation2 command_args do_block + { + $$ = new_call(p, $1, $3, $4, $2); + call_with_block(p, $$, $5); + } + ; + +method_call : operation paren_args + { + $$ = new_fcall(p, $1, $2); + } + | primary_value call_op operation2 opt_paren_args + { + $$ = new_call(p, $1, $3, $4, $2); + } + | primary_value tCOLON2 operation2 paren_args + { + $$ = new_call(p, $1, $3, $4, tCOLON2); + } + | primary_value tCOLON2 operation3 + { + $$ = new_call(p, $1, $3, 0, tCOLON2); + } + | primary_value call_op paren_args + { + $$ = new_call(p, $1, intern("call",4), $3, $2); + } + | primary_value tCOLON2 paren_args + { + $$ = new_call(p, $1, intern("call",4), $3, tCOLON2); + } + | keyword_super paren_args + { + $$ = new_super(p, $2); + } + | keyword_super + { + $$ = new_zsuper(p); + } + | primary_value '[' opt_call_args rbracket + { + $$ = new_call(p, $1, intern("[]",2), $3, '.'); + } + ; + +brace_block : '{' + { + local_nest(p); + $$ = p->lineno; + } + opt_block_param + compstmt '}' + { + $$ = new_block(p,$3,$4); + SET_LINENO($$, $2); + local_unnest(p); + } + | keyword_do + { + local_nest(p); + $$ = p->lineno; + } + opt_block_param + compstmt keyword_end + { + $$ = new_block(p,$3,$4); + SET_LINENO($$, $2); + local_unnest(p); + } + ; + +case_body : keyword_when args then + compstmt + cases + { + $$ = cons(cons($2, $4), $5); + } + ; + +cases : opt_else + { + if ($1) { + $$ = cons(cons(0, $1), 0); + } + else { + $$ = 0; + } + } + | case_body + ; + +opt_rescue : keyword_rescue exc_list exc_var then + compstmt + opt_rescue + { + $$ = list1(list3($2, $3, $5)); + if ($6) $$ = append($$, $6); + } + | none + ; + +exc_list : arg + { + $$ = list1($1); + } + | mrhs + | none + ; + +exc_var : tASSOC lhs + { + $$ = $2; + } + | none + ; + +opt_ensure : keyword_ensure compstmt + { + $$ = $2; + } + | none + ; + +literal : numeric + | symbol + | words + | symbols + ; + +string : tCHAR + | tSTRING + | tSTRING_BEG tSTRING + { + $$ = $2; + } + | tSTRING_BEG string_rep tSTRING + { + $$ = new_dstr(p, push($2, $3)); + } + ; + +string_rep : string_interp + | string_rep string_interp + { + $$ = append($1, $2); + } + ; + +string_interp : tSTRING_MID + { + $$ = list1($1); + } + | tSTRING_PART + { + $$ = p->lex_strterm; + p->lex_strterm = NULL; + } + compstmt + '}' + { + p->lex_strterm = $2; + $$ = list2($1, $3); + } + | tLITERAL_DELIM + { + $$ = list1(new_literal_delim(p)); + } + | tHD_LITERAL_DELIM heredoc_bodies + { + $$ = list1(new_literal_delim(p)); + } + ; + +xstring : tXSTRING_BEG tXSTRING + { + $$ = $2; + } + | tXSTRING_BEG string_rep tXSTRING + { + $$ = new_dxstr(p, push($2, $3)); + } + ; + +regexp : tREGEXP_BEG tREGEXP + { + $$ = $2; + } + | tREGEXP_BEG string_rep tREGEXP + { + $$ = new_dregx(p, $2, $3); + } + ; + +heredoc : tHEREDOC_BEG + ; + +heredoc_bodies : heredoc_body + | heredoc_bodies heredoc_body + ; + +heredoc_body : tHEREDOC_END + { + parser_heredoc_info * inf = parsing_heredoc_inf(p); + inf->doc = push(inf->doc, new_str(p, "", 0)); + heredoc_end(p); + } + | heredoc_string_rep tHEREDOC_END + { + heredoc_end(p); + } + ; + +heredoc_string_rep : heredoc_string_interp + | heredoc_string_rep heredoc_string_interp + ; + +heredoc_string_interp : tHD_STRING_MID + { + parser_heredoc_info * inf = parsing_heredoc_inf(p); + inf->doc = push(inf->doc, $1); + heredoc_treat_nextline(p); + } + | tHD_STRING_PART + { + $$ = p->lex_strterm; + p->lex_strterm = NULL; + } + compstmt + '}' + { + parser_heredoc_info * inf = parsing_heredoc_inf(p); + p->lex_strterm = $2; + inf->doc = push(push(inf->doc, $1), $3); + } + ; + +words : tWORDS_BEG tSTRING + { + $$ = new_words(p, list1($2)); + } + | tWORDS_BEG string_rep tSTRING + { + $$ = new_words(p, push($2, $3)); + } + ; + + +symbol : basic_symbol + { + $$ = new_sym(p, $1); + } + | tSYMBEG tSTRING_BEG string_rep tSTRING + { + p->lstate = EXPR_END; + $$ = new_dsym(p, push($3, $4)); + } + ; + +basic_symbol : tSYMBEG sym + { + p->lstate = EXPR_END; + $$ = $2; + } + ; + +sym : fname + | tIVAR + | tGVAR + | tCVAR + | tSTRING + { + $$ = new_strsym(p, $1); + } + | tSTRING_BEG tSTRING + { + $$ = new_strsym(p, $2); + } + ; + +symbols : tSYMBOLS_BEG tSTRING + { + $$ = new_symbols(p, list1($2)); + } + | tSYMBOLS_BEG string_rep tSTRING + { + $$ = new_symbols(p, push($2, $3)); + } + ; + +numeric : tINTEGER + | tFLOAT + | tUMINUS_NUM tINTEGER %prec tLOWEST + { + $$ = negate_lit(p, $2); + } + | tUMINUS_NUM tFLOAT %prec tLOWEST + { + $$ = negate_lit(p, $2); + } + ; + +variable : tIDENTIFIER + { + $$ = new_lvar(p, $1); + } + | tIVAR + { + $$ = new_ivar(p, $1); + } + | tGVAR + { + $$ = new_gvar(p, $1); + } + | tCVAR + { + $$ = new_cvar(p, $1); + } + | tCONSTANT + { + $$ = new_const(p, $1); + } + ; + +var_lhs : variable + { + assignable(p, $1); + } + ; + +var_ref : variable + { + $$ = var_reference(p, $1); + } + | keyword_nil + { + $$ = new_nil(p); + } + | keyword_self + { + $$ = new_self(p); + } + | keyword_true + { + $$ = new_true(p); + } + | keyword_false + { + $$ = new_false(p); + } + | keyword__FILE__ + { + const char *fn = p->filename; + if (!fn) { + fn = "(null)"; + } + $$ = new_str(p, fn, strlen(fn)); + } + | keyword__LINE__ + { + char buf[16]; + + snprintf(buf, sizeof(buf), "%d", p->lineno); + $$ = new_int(p, buf, 10); + } + | keyword__ENCODING__ + { +#ifdef MRB_UTF8_STRING + const char *enc = "UTF-8"; +#else + const char *enc = "ASCII-8BIT"; +#endif + $$ = new_str(p, enc, strlen(enc)); + } + ; + +backref : tNTH_REF + | tBACK_REF + ; + +superclass : /* term */ + { + $$ = 0; + } + | '<' + { + p->lstate = EXPR_BEG; + p->cmd_start = TRUE; + } + expr_value term + { + $$ = $3; + } /* + | error term + { + yyerrok; + $$ = 0; + } */ + ; + +f_arglist : '(' f_args rparen + { + $$ = $2; + p->lstate = EXPR_BEG; + p->cmd_start = TRUE; + } + | f_args term + { + $$ = $1; + } + ; + +f_args : f_arg ',' f_optarg ',' f_rest_arg opt_f_block_arg + { + $$ = new_args(p, $1, $3, $5, 0, $6); + } + | f_arg ',' f_optarg ',' f_rest_arg ',' f_arg opt_f_block_arg + { + $$ = new_args(p, $1, $3, $5, $7, $8); + } + | f_arg ',' f_optarg opt_f_block_arg + { + $$ = new_args(p, $1, $3, 0, 0, $4); + } + | f_arg ',' f_optarg ',' f_arg opt_f_block_arg + { + $$ = new_args(p, $1, $3, 0, $5, $6); + } + | f_arg ',' f_rest_arg opt_f_block_arg + { + $$ = new_args(p, $1, 0, $3, 0, $4); + } + | f_arg ',' f_rest_arg ',' f_arg opt_f_block_arg + { + $$ = new_args(p, $1, 0, $3, $5, $6); + } + | f_arg opt_f_block_arg + { + $$ = new_args(p, $1, 0, 0, 0, $2); + } + | f_optarg ',' f_rest_arg opt_f_block_arg + { + $$ = new_args(p, 0, $1, $3, 0, $4); + } + | f_optarg ',' f_rest_arg ',' f_arg opt_f_block_arg + { + $$ = new_args(p, 0, $1, $3, $5, $6); + } + | f_optarg opt_f_block_arg + { + $$ = new_args(p, 0, $1, 0, 0, $2); + } + | f_optarg ',' f_arg opt_f_block_arg + { + $$ = new_args(p, 0, $1, 0, $3, $4); + } + | f_rest_arg opt_f_block_arg + { + $$ = new_args(p, 0, 0, $1, 0, $2); + } + | f_rest_arg ',' f_arg opt_f_block_arg + { + $$ = new_args(p, 0, 0, $1, $3, $4); + } + | f_block_arg + { + $$ = new_args(p, 0, 0, 0, 0, $1); + } + | /* none */ + { + local_add_f(p, 0); + $$ = new_args(p, 0, 0, 0, 0, 0); + } + ; + +f_bad_arg : tCONSTANT + { + yyerror(p, "formal argument cannot be a constant"); + $$ = 0; + } + | tIVAR + { + yyerror(p, "formal argument cannot be an instance variable"); + $$ = 0; + } + | tGVAR + { + yyerror(p, "formal argument cannot be a global variable"); + $$ = 0; + } + | tCVAR + { + yyerror(p, "formal argument cannot be a class variable"); + $$ = 0; + } + ; + +f_norm_arg : f_bad_arg + { + $$ = 0; + } + | tIDENTIFIER + { + local_add_f(p, $1); + $$ = $1; + } + ; + +f_arg_item : f_norm_arg + { + $$ = new_arg(p, $1); + } + | tLPAREN f_margs rparen + { + $$ = new_masgn(p, $2, 0); + } + ; + +f_arg : f_arg_item + { + $$ = list1($1); + } + | f_arg ',' f_arg_item + { + $$ = push($1, $3); + } + ; + +f_opt_asgn : tIDENTIFIER '=' + { + local_add_f(p, $1); + $$ = $1; + } + ; + +f_opt : f_opt_asgn arg + { + void_expr_error(p, $2); + $$ = cons(nsym($1), $2); + } + ; + +f_block_opt : f_opt_asgn primary_value + { + void_expr_error(p, $2); + $$ = cons(nsym($1), $2); + } + ; + +f_block_optarg : f_block_opt + { + $$ = list1($1); + } + | f_block_optarg ',' f_block_opt + { + $$ = push($1, $3); + } + ; + +f_optarg : f_opt + { + $$ = list1($1); + } + | f_optarg ',' f_opt + { + $$ = push($1, $3); + } + ; + +restarg_mark : '*' + | tSTAR + ; + +f_rest_arg : restarg_mark tIDENTIFIER + { + local_add_f(p, $2); + $$ = $2; + } + | restarg_mark + { + local_add_f(p, 0); + $$ = -1; + } + ; + +blkarg_mark : '&' + | tAMPER + ; + +f_block_arg : blkarg_mark tIDENTIFIER + { + local_add_f(p, $2); + $$ = $2; + } + ; + +opt_f_block_arg : ',' f_block_arg + { + $$ = $2; + } + | none + { + local_add_f(p, 0); + $$ = 0; + } + ; + +singleton : var_ref + { + $$ = $1; + if (!$$) $$ = new_nil(p); + } + | '(' {p->lstate = EXPR_BEG;} expr rparen + { + if ($3 == 0) { + yyerror(p, "can't define singleton method for ()."); + } + else { + switch ((enum node_type)intn($3->car)) { + case NODE_STR: + case NODE_DSTR: + case NODE_XSTR: + case NODE_DXSTR: + case NODE_DREGX: + case NODE_MATCH: + case NODE_FLOAT: + case NODE_ARRAY: + case NODE_HEREDOC: + yyerror(p, "can't define singleton method for literals"); + default: + break; + } + } + $$ = $3; + } + ; + +assoc_list : none + | assocs trailer + { + $$ = $1; + } + ; + +assocs : assoc + { + $$ = list1($1); + NODE_LINENO($$, $1); + } + | assocs ',' assoc + { + $$ = push($1, $3); + } + ; + +assoc : arg tASSOC arg + { + void_expr_error(p, $1); + void_expr_error(p, $3); + $$ = cons($1, $3); + } + | tLABEL arg + { + void_expr_error(p, $2); + $$ = cons(new_sym(p, $1), $2); + } + | tLABEL_END arg + { + void_expr_error(p, $2); + $$ = cons(new_sym(p, new_strsym(p, $1)), $2); + } + | tSTRING_BEG tLABEL_END arg + { + void_expr_error(p, $3); + $$ = cons(new_sym(p, new_strsym(p, $2)), $3); + } + | tSTRING_BEG string_rep tLABEL_END arg + { + void_expr_error(p, $4); + $$ = cons(new_dsym(p, push($2, $3)), $4); + } + ; + +operation : tIDENTIFIER + | tCONSTANT + | tFID + ; + +operation2 : tIDENTIFIER + | tCONSTANT + | tFID + | op + ; + +operation3 : tIDENTIFIER + | tFID + | op + ; + +dot_or_colon : '.' + | tCOLON2 + ; + +call_op : '.' + { + $$ = '.'; + } + | tANDDOT + { + $$ = 0; + } + ; + +call_op2 : call_op + | tCOLON2 + { + $$ = tCOLON2; + } + ; + +opt_terms : /* none */ + | terms + ; + +opt_nl : /* none */ + | nl + ; + +rparen : opt_nl ')' + ; + +rbracket : opt_nl ']' + ; + +trailer : /* none */ + | nl + | comma + ; + +term : ';' {yyerrok;} + | nl + | heredoc_body + ; + +nl : '\n' + { + p->lineno++; + p->column = 0; + } + ; + +terms : term + | terms term + ; + +none : /* none */ + { + $$ = 0; + } + ; +%% +#define pylval (*((YYSTYPE*)(p->ylval))) + +static void +yyerror(parser_state *p, const char *s) +{ + char* c; + size_t n; + + if (! p->capture_errors) { +#ifndef MRB_DISABLE_STDIO + if (p->filename) { + fprintf(stderr, "%s:%d:%d: %s\n", p->filename, p->lineno, p->column, s); + } + else { + fprintf(stderr, "line %d:%d: %s\n", p->lineno, p->column, s); + } +#endif + } + else if (p->nerr < sizeof(p->error_buffer) / sizeof(p->error_buffer[0])) { + n = strlen(s); + c = (char *)parser_palloc(p, n + 1); + memcpy(c, s, n + 1); + p->error_buffer[p->nerr].message = c; + p->error_buffer[p->nerr].lineno = p->lineno; + p->error_buffer[p->nerr].column = p->column; + } + p->nerr++; +} + +static void +yyerror_i(parser_state *p, const char *fmt, int i) +{ + char buf[256]; + + snprintf(buf, sizeof(buf), fmt, i); + yyerror(p, buf); +} + +static void +yywarn(parser_state *p, const char *s) +{ + char* c; + size_t n; + + if (! p->capture_errors) { +#ifndef MRB_DISABLE_STDIO + if (p->filename) { + fprintf(stderr, "%s:%d:%d: %s\n", p->filename, p->lineno, p->column, s); + } + else { + fprintf(stderr, "line %d:%d: %s\n", p->lineno, p->column, s); + } +#endif + } + else if (p->nwarn < sizeof(p->warn_buffer) / sizeof(p->warn_buffer[0])) { + n = strlen(s); + c = (char *)parser_palloc(p, n + 1); + memcpy(c, s, n + 1); + p->warn_buffer[p->nwarn].message = c; + p->warn_buffer[p->nwarn].lineno = p->lineno; + p->warn_buffer[p->nwarn].column = p->column; + } + p->nwarn++; +} + +static void +yywarning(parser_state *p, const char *s) +{ + yywarn(p, s); +} + +static void +yywarning_s(parser_state *p, const char *fmt, const char *s) +{ + char buf[256]; + + snprintf(buf, sizeof(buf), fmt, s); + yywarning(p, buf); +} + +static void +backref_error(parser_state *p, node *n) +{ + int c; + + c = (int)(intptr_t)n->car; + + if (c == NODE_NTH_REF) { + yyerror_i(p, "can't set variable $%" MRB_PRId, (mrb_int)(intptr_t)n->cdr); + } + else if (c == NODE_BACK_REF) { + yyerror_i(p, "can't set variable $%c", (int)(intptr_t)n->cdr); + } + else { + mrb_bug(p->mrb, "Internal error in backref_error() : n=>car == %S", mrb_fixnum_value(c)); + } +} + +static void +void_expr_error(parser_state *p, node *n) +{ + int c; + + if (n == NULL) return; + c = (int)(intptr_t)n->car; + switch (c) { + case NODE_BREAK: + case NODE_RETURN: + case NODE_NEXT: + case NODE_REDO: + case NODE_RETRY: + yyerror(p, "void value expression"); + break; + case NODE_AND: + case NODE_OR: + void_expr_error(p, n->cdr->car); + void_expr_error(p, n->cdr->cdr); + break; + case NODE_BEGIN: + if (n->cdr) { + while (n->cdr) { + n = n->cdr; + } + void_expr_error(p, n->car); + } + break; + default: + break; + } +} + +static void pushback(parser_state *p, int c); +static mrb_bool peeks(parser_state *p, const char *s); +static mrb_bool skips(parser_state *p, const char *s); + +static inline int +nextc(parser_state *p) +{ + int c; + + if (p->pb) { + node *tmp; + + c = (int)(intptr_t)p->pb->car; + tmp = p->pb; + p->pb = p->pb->cdr; + cons_free(tmp); + } + else { +#ifndef MRB_DISABLE_STDIO + if (p->f) { + if (feof(p->f)) goto eof; + c = fgetc(p->f); + if (c == EOF) goto eof; + } + else +#endif + if (!p->s || p->s >= p->send) { + goto eof; + } + else { + c = (unsigned char)*p->s++; + } + } + if (c >= 0) { + p->column++; + } + if (c == '\r') { + c = nextc(p); + if (c != '\n') { + pushback(p, c); + return '\r'; + } + return c; + } + return c; + + eof: + if (!p->cxt) return -1; + else { + if (p->cxt->partial_hook(p) < 0) + return -1; /* end of program(s) */ + return -2; /* end of a file in the program files */ + } +} + +static void +pushback(parser_state *p, int c) +{ + if (c >= 0) { + p->column--; + } + p->pb = cons((node*)(intptr_t)c, p->pb); +} + +static void +skip(parser_state *p, char term) +{ + int c; + + for (;;) { + c = nextc(p); + if (c < 0) break; + if (c == term) break; + } +} + +static int +peekc_n(parser_state *p, int n) +{ + node *list = 0; + int c0; + + do { + c0 = nextc(p); + if (c0 == -1) return c0; /* do not skip partial EOF */ + if (c0 >= 0) --p->column; + list = push(list, (node*)(intptr_t)c0); + } while(n--); + if (p->pb) { + p->pb = append((node*)list, p->pb); + } + else { + p->pb = list; + } + return c0; +} + +static mrb_bool +peek_n(parser_state *p, int c, int n) +{ + return peekc_n(p, n) == c && c >= 0; +} +#define peek(p,c) peek_n((p), (c), 0) + +static mrb_bool +peeks(parser_state *p, const char *s) +{ + size_t len = strlen(s); + +#ifndef MRB_DISABLE_STDIO + if (p->f) { + int n = 0; + while (*s) { + if (!peek_n(p, *s++, n++)) return FALSE; + } + return TRUE; + } + else +#endif + if (p->s && p->s + len <= p->send) { + if (memcmp(p->s, s, len) == 0) return TRUE; + } + return FALSE; +} + +static mrb_bool +skips(parser_state *p, const char *s) +{ + int c; + + for (;;) { + /* skip until first char */ + for (;;) { + c = nextc(p); + if (c < 0) return FALSE; + if (c == '\n') { + p->lineno++; + p->column = 0; + } + if (c == *s) break; + } + s++; + if (peeks(p, s)) { + size_t len = strlen(s); + + while (len--) { + if (nextc(p) == '\n') { + p->lineno++; + p->column = 0; + } + } + return TRUE; + } + else{ + s--; + } + } + return FALSE; +} + + +static int +newtok(parser_state *p) +{ + if (p->tokbuf != p->buf) { + mrb_free(p->mrb, p->tokbuf); + p->tokbuf = p->buf; + p->tsiz = MRB_PARSER_TOKBUF_SIZE; + } + p->tidx = 0; + return p->column - 1; +} + +static void +tokadd(parser_state *p, int32_t c) +{ + char utf8[4]; + int i, len; + + /* mrb_assert(-0x10FFFF <= c && c <= 0xFF); */ + if (c >= 0) { + /* Single byte from source or non-Unicode escape */ + utf8[0] = (char)c; + len = 1; + } + else { + /* Unicode character */ + c = -c; + if (c < 0x80) { + utf8[0] = (char)c; + len = 1; + } + else if (c < 0x800) { + utf8[0] = (char)(0xC0 | (c >> 6)); + utf8[1] = (char)(0x80 | (c & 0x3F)); + len = 2; + } + else if (c < 0x10000) { + utf8[0] = (char)(0xE0 | (c >> 12) ); + utf8[1] = (char)(0x80 | ((c >> 6) & 0x3F)); + utf8[2] = (char)(0x80 | ( c & 0x3F)); + len = 3; + } + else { + utf8[0] = (char)(0xF0 | (c >> 18) ); + utf8[1] = (char)(0x80 | ((c >> 12) & 0x3F)); + utf8[2] = (char)(0x80 | ((c >> 6) & 0x3F)); + utf8[3] = (char)(0x80 | ( c & 0x3F)); + len = 4; + } + } + if (p->tidx+len >= p->tsiz) { + if (p->tsiz >= MRB_PARSER_TOKBUF_MAX) { + p->tidx += len; + return; + } + p->tsiz *= 2; + if (p->tokbuf == p->buf) { + p->tokbuf = (char*)mrb_malloc(p->mrb, p->tsiz); + memcpy(p->tokbuf, p->buf, MRB_PARSER_TOKBUF_SIZE); + } + else { + p->tokbuf = (char*)mrb_realloc(p->mrb, p->tokbuf, p->tsiz); + } + } + for (i = 0; i < len; i++) { + p->tokbuf[p->tidx++] = utf8[i]; + } +} + +static int +toklast(parser_state *p) +{ + return p->tokbuf[p->tidx-1]; +} + +static void +tokfix(parser_state *p) +{ + if (p->tidx >= MRB_PARSER_TOKBUF_MAX) { + p->tidx = MRB_PARSER_TOKBUF_MAX-1; + yyerror(p, "string too long (truncated)"); + } + p->tokbuf[p->tidx] = '\0'; +} + +static const char* +tok(parser_state *p) +{ + return p->tokbuf; +} + +static int +toklen(parser_state *p) +{ + return p->tidx; +} + +#define IS_ARG() (p->lstate == EXPR_ARG || p->lstate == EXPR_CMDARG) +#define IS_END() (p->lstate == EXPR_END || p->lstate == EXPR_ENDARG || p->lstate == EXPR_ENDFN) +#define IS_BEG() (p->lstate == EXPR_BEG || p->lstate == EXPR_MID || p->lstate == EXPR_VALUE || p->lstate == EXPR_CLASS) +#define IS_SPCARG(c) (IS_ARG() && space_seen && !ISSPACE(c)) +#define IS_LABEL_POSSIBLE() ((p->lstate == EXPR_BEG && !cmd_state) || IS_ARG()) +#define IS_LABEL_SUFFIX(n) (peek_n(p, ':',(n)) && !peek_n(p, ':', (n)+1)) + +static int32_t +scan_oct(const int *start, int len, int *retlen) +{ + const int *s = start; + int32_t retval = 0; + + /* mrb_assert(len <= 3) */ + while (len-- && *s >= '0' && *s <= '7') { + retval <<= 3; + retval |= *s++ - '0'; + } + *retlen = (int)(s - start); + + return retval; +} + +static int32_t +scan_hex(parser_state *p, const int *start, int len, int *retlen) +{ + static const char hexdigit[] = "0123456789abcdef0123456789ABCDEF"; + const int *s = start; + uint32_t retval = 0; + char *tmp; + + /* mrb_assert(len <= 8) */ + while (len-- && *s && (tmp = (char*)strchr(hexdigit, *s))) { + retval <<= 4; + retval |= (tmp - hexdigit) & 15; + s++; + } + *retlen = (int)(s - start); + + return (int32_t)retval; +} + +static int32_t +read_escape_unicode(parser_state *p, int limit) +{ + int buf[9]; + int i; + int32_t hex; + + /* Look for opening brace */ + i = 0; + buf[0] = nextc(p); + if (buf[0] < 0) { + eof: + yyerror(p, "invalid escape character syntax"); + return -1; + } + if (ISXDIGIT(buf[0])) { + /* \uxxxx form */ + for (i=1; i 0x10FFFF || (hex & 0xFFFFF800) == 0xD800) { + yyerror(p, "invalid Unicode code point"); + return -1; + } + return hex; +} + +/* Return negative to indicate Unicode code point */ +static int32_t +read_escape(parser_state *p) +{ + int32_t c; + + switch (c = nextc(p)) { + case '\\':/* Backslash */ + return c; + + case 'n':/* newline */ + return '\n'; + + case 't':/* horizontal tab */ + return '\t'; + + case 'r':/* carriage-return */ + return '\r'; + + case 'f':/* form-feed */ + return '\f'; + + case 'v':/* vertical tab */ + return '\13'; + + case 'a':/* alarm(bell) */ + return '\007'; + + case 'e':/* escape */ + return 033; + + case '0': case '1': case '2': case '3': /* octal constant */ + case '4': case '5': case '6': case '7': + { + int buf[3]; + int i; + + buf[0] = c; + for (i=1; i<3; i++) { + buf[i] = nextc(p); + if (buf[i] < 0) goto eof; + if (buf[i] < '0' || '7' < buf[i]) { + pushback(p, buf[i]); + break; + } + } + c = scan_oct(buf, i, &i); + } + return c; + + case 'x': /* hex constant */ + { + int buf[2]; + int i; + + for (i=0; i<2; i++) { + buf[i] = nextc(p); + if (buf[i] < 0) goto eof; + if (!ISXDIGIT(buf[i])) { + pushback(p, buf[i]); + break; + } + } + if (i == 0) { + yyerror(p, "invalid hex escape"); + return -1; + } + return scan_hex(p, buf, i, &i); + } + + case 'u': /* Unicode */ + if (peek(p, '{')) { + /* \u{xxxxxxxx} form */ + nextc(p); + c = read_escape_unicode(p, 8); + if (c < 0) return 0; + if (nextc(p) != '}') goto eof; + } + else { + c = read_escape_unicode(p, 4); + if (c < 0) return 0; + } + return -c; + + case 'b':/* backspace */ + return '\010'; + + case 's':/* space */ + return ' '; + + case 'M': + if ((c = nextc(p)) != '-') { + yyerror(p, "Invalid escape character syntax"); + pushback(p, c); + return '\0'; + } + if ((c = nextc(p)) == '\\') { + return read_escape(p) | 0x80; + } + else if (c < 0) goto eof; + else { + return ((c & 0xff) | 0x80); + } + + case 'C': + if ((c = nextc(p)) != '-') { + yyerror(p, "Invalid escape character syntax"); + pushback(p, c); + return '\0'; + } + case 'c': + if ((c = nextc(p))== '\\') { + c = read_escape(p); + } + else if (c == '?') + return 0177; + else if (c < 0) goto eof; + return c & 0x9f; + + eof: + case -1: + case -2: /* end of a file */ + yyerror(p, "Invalid escape character syntax"); + return '\0'; + + default: + return c; + } +} + +static int +parse_string(parser_state *p) +{ + int c; + string_type type = (string_type)(intptr_t)p->lex_strterm->car; + int nest_level = intn(p->lex_strterm->cdr->car); + int beg = intn(p->lex_strterm->cdr->cdr->car); + int end = intn(p->lex_strterm->cdr->cdr->cdr); + parser_heredoc_info *hinf = (type & STR_FUNC_HEREDOC) ? parsing_heredoc_inf(p) : NULL; + int cmd_state = p->cmd_start; + + if (beg == 0) beg = -3; /* should never happen */ + if (end == 0) end = -3; + newtok(p); + while ((c = nextc(p)) != end || nest_level != 0) { + if (hinf && (c == '\n' || c < 0)) { + mrb_bool line_head; + tokadd(p, '\n'); + tokfix(p); + p->lineno++; + p->column = 0; + line_head = hinf->line_head; + hinf->line_head = TRUE; + if (line_head) { + /* check whether end of heredoc */ + const char *s = tok(p); + int len = toklen(p); + if (hinf->allow_indent) { + while (ISSPACE(*s) && len > 0) { + ++s; + --len; + } + } + if ((len-1 == hinf->term_len) && (strncmp(s, hinf->term, len-1) == 0)) { + if (c < 0) { + p->parsing_heredoc = NULL; + } + else { + return tHEREDOC_END; + } + } + } + if (c < 0) { + char buf[256]; + snprintf(buf, sizeof(buf), "can't find heredoc delimiter \"%s\" anywhere before EOF", hinf->term); + yyerror(p, buf); + return 0; + } + pylval.nd = new_str(p, tok(p), toklen(p)); + return tHD_STRING_MID; + } + if (c < 0) { + yyerror(p, "unterminated string meets end of file"); + return 0; + } + else if (c == beg) { + nest_level++; + p->lex_strterm->cdr->car = (node*)(intptr_t)nest_level; + } + else if (c == end) { + nest_level--; + p->lex_strterm->cdr->car = (node*)(intptr_t)nest_level; + } + else if (c == '\\') { + c = nextc(p); + if (type & STR_FUNC_EXPAND) { + if (c == end || c == beg) { + tokadd(p, c); + } + else if (c == '\n') { + p->lineno++; + p->column = 0; + if (type & STR_FUNC_ARRAY) { + tokadd(p, '\n'); + } + } + else if (type & STR_FUNC_REGEXP) { + tokadd(p, '\\'); + tokadd(p, c); + } + else if (c == 'u' && peek(p, '{')) { + /* \u{xxxx xxxx xxxx} form */ + nextc(p); + while (1) { + do c = nextc(p); while (ISSPACE(c)); + if (c == '}') break; + pushback(p, c); + c = read_escape_unicode(p, 8); + if (c < 0) break; + tokadd(p, -c); + } + if (hinf) + hinf->line_head = FALSE; + } + else { + pushback(p, c); + tokadd(p, read_escape(p)); + if (hinf) + hinf->line_head = FALSE; + } + } + else { + if (c != beg && c != end) { + if (c == '\n') { + p->lineno++; + p->column = 0; + } + if (!(c == '\\' || ((type & STR_FUNC_ARRAY) && ISSPACE(c)))) { + tokadd(p, '\\'); + } + } + tokadd(p, c); + } + continue; + } + else if ((c == '#') && (type & STR_FUNC_EXPAND)) { + c = nextc(p); + if (c == '{') { + tokfix(p); + p->lstate = EXPR_BEG; + p->cmd_start = TRUE; + pylval.nd = new_str(p, tok(p), toklen(p)); + if (hinf) { + hinf->line_head = FALSE; + return tHD_STRING_PART; + } + return tSTRING_PART; + } + tokadd(p, '#'); + pushback(p, c); + continue; + } + if ((type & STR_FUNC_ARRAY) && ISSPACE(c)) { + if (toklen(p) == 0) { + do { + if (c == '\n') { + p->lineno++; + p->column = 0; + heredoc_treat_nextline(p); + if (p->parsing_heredoc != NULL) { + return tHD_LITERAL_DELIM; + } + } + c = nextc(p); + } while (ISSPACE(c)); + pushback(p, c); + return tLITERAL_DELIM; + } + else { + pushback(p, c); + tokfix(p); + pylval.nd = new_str(p, tok(p), toklen(p)); + return tSTRING_MID; + } + } + if (c == '\n') { + p->lineno++; + p->column = 0; + } + tokadd(p, c); + } + + tokfix(p); + p->lstate = EXPR_END; + end_strterm(p); + + if (type & STR_FUNC_XQUOTE) { + pylval.nd = new_xstr(p, tok(p), toklen(p)); + return tXSTRING; + } + + if (type & STR_FUNC_REGEXP) { + int f = 0; + int re_opt; + char *s = strndup(tok(p), toklen(p)); + char flags[3]; + char *flag = flags; + char enc = '\0'; + char *encp; + char *dup; + + newtok(p); + while (re_opt = nextc(p), re_opt >= 0 && ISALPHA(re_opt)) { + switch (re_opt) { + case 'i': f |= 1; break; + case 'x': f |= 2; break; + case 'm': f |= 4; break; + case 'u': f |= 16; break; + case 'n': f |= 32; break; + default: tokadd(p, re_opt); break; + } + } + pushback(p, re_opt); + if (toklen(p)) { + char msg[128]; + tokfix(p); + snprintf(msg, sizeof(msg), "unknown regexp option%s - %s", + toklen(p) > 1 ? "s" : "", tok(p)); + yyerror(p, msg); + } + if (f != 0) { + if (f & 1) *flag++ = 'i'; + if (f & 2) *flag++ = 'x'; + if (f & 4) *flag++ = 'm'; + if (f & 16) enc = 'u'; + if (f & 32) enc = 'n'; + } + if (flag > flags) { + dup = strndup(flags, (size_t)(flag - flags)); + } + else { + dup = NULL; + } + if (enc) { + encp = strndup(&enc, 1); + } + else { + encp = NULL; + } + pylval.nd = new_regx(p, s, dup, encp); + + return tREGEXP; + } + pylval.nd = new_str(p, tok(p), toklen(p)); + if (IS_LABEL_POSSIBLE()) { + if (IS_LABEL_SUFFIX(0)) { + p->lstate = EXPR_BEG; + nextc(p); + return tLABEL_END; + } + } + + return tSTRING; +} + + +static int +heredoc_identifier(parser_state *p) +{ + int c; + int type = str_heredoc; + mrb_bool indent = FALSE; + mrb_bool quote = FALSE; + node *newnode; + parser_heredoc_info *info; + + c = nextc(p); + if (ISSPACE(c) || c == '=') { + pushback(p, c); + return 0; + } + if (c == '-') { + indent = TRUE; + c = nextc(p); + } + if (c == '\'' || c == '"') { + int term = c; + if (c == '\'') + quote = TRUE; + newtok(p); + while ((c = nextc(p)) >= 0 && c != term) { + if (c == '\n') { + c = -1; + break; + } + tokadd(p, c); + } + if (c < 0) { + yyerror(p, "unterminated here document identifier"); + return 0; + } + } + else { + if (c < 0) { + return 0; /* missing here document identifier */ + } + if (! identchar(c)) { + pushback(p, c); + if (indent) pushback(p, '-'); + return 0; + } + newtok(p); + do { + tokadd(p, c); + } while ((c = nextc(p)) >= 0 && identchar(c)); + pushback(p, c); + } + tokfix(p); + newnode = new_heredoc(p); + info = (parser_heredoc_info*)newnode->cdr; + info->term = strndup(tok(p), toklen(p)); + info->term_len = toklen(p); + if (! quote) + type |= STR_FUNC_EXPAND; + info->type = (string_type)type; + info->allow_indent = indent; + info->line_head = TRUE; + info->doc = NULL; + p->heredocs_from_nextline = push(p->heredocs_from_nextline, newnode); + p->lstate = EXPR_END; + + pylval.nd = newnode; + return tHEREDOC_BEG; +} + +static int +arg_ambiguous(parser_state *p) +{ + yywarning(p, "ambiguous first argument; put parentheses or even spaces"); + return 1; +} + +#include "lex.def" + +static int +parser_yylex(parser_state *p) +{ + int32_t c; + int space_seen = 0; + int cmd_state; + enum mrb_lex_state_enum last_state; + int token_column; + + if (p->lex_strterm) { + if (is_strterm_type(p, STR_FUNC_HEREDOC)) { + if (p->parsing_heredoc != NULL) + return parse_string(p); + } + else + return parse_string(p); + } + cmd_state = p->cmd_start; + p->cmd_start = FALSE; + retry: + last_state = p->lstate; + switch (c = nextc(p)) { + case '\004': /* ^D */ + case '\032': /* ^Z */ + case '\0': /* NUL */ + case -1: /* end of script. */ + if (p->heredocs_from_nextline) + goto maybe_heredoc; + return 0; + + /* white spaces */ + case ' ': case '\t': case '\f': case '\r': + case '\13': /* '\v' */ + space_seen = 1; + goto retry; + + case '#': /* it's a comment */ + skip(p, '\n'); + /* fall through */ + case -2: /* end of a file */ + case '\n': + maybe_heredoc: + heredoc_treat_nextline(p); + switch (p->lstate) { + case EXPR_BEG: + case EXPR_FNAME: + case EXPR_DOT: + case EXPR_CLASS: + case EXPR_VALUE: + p->lineno++; + p->column = 0; + if (p->parsing_heredoc != NULL) { + if (p->lex_strterm) { + return parse_string(p); + } + } + goto retry; + default: + break; + } + if (p->parsing_heredoc != NULL) { + return '\n'; + } + while ((c = nextc(p))) { + switch (c) { + case ' ': case '\t': case '\f': case '\r': + case '\13': /* '\v' */ + space_seen = 1; + break; + case '.': + if ((c = nextc(p)) != '.') { + pushback(p, c); + pushback(p, '.'); + goto retry; + } + case -1: /* EOF */ + case -2: /* end of a file */ + goto normal_newline; + default: + pushback(p, c); + goto normal_newline; + } + } + normal_newline: + p->cmd_start = TRUE; + p->lstate = EXPR_BEG; + return '\n'; + + case '*': + if ((c = nextc(p)) == '*') { + if ((c = nextc(p)) == '=') { + pylval.id = intern("**",2); + p->lstate = EXPR_BEG; + return tOP_ASGN; + } + pushback(p, c); + c = tPOW; + } + else { + if (c == '=') { + pylval.id = intern_c('*'); + p->lstate = EXPR_BEG; + return tOP_ASGN; + } + pushback(p, c); + if (IS_SPCARG(c)) { + yywarning(p, "'*' interpreted as argument prefix"); + c = tSTAR; + } + else if (IS_BEG()) { + c = tSTAR; + } + else { + c = '*'; + } + } + if (p->lstate == EXPR_FNAME || p->lstate == EXPR_DOT) { + p->lstate = EXPR_ARG; + } + else { + p->lstate = EXPR_BEG; + } + return c; + + case '!': + c = nextc(p); + if (p->lstate == EXPR_FNAME || p->lstate == EXPR_DOT) { + p->lstate = EXPR_ARG; + if (c == '@') { + return '!'; + } + } + else { + p->lstate = EXPR_BEG; + } + if (c == '=') { + return tNEQ; + } + if (c == '~') { + return tNMATCH; + } + pushback(p, c); + return '!'; + + case '=': + if (p->column == 1) { + static const char begin[] = "begin"; + static const char end[] = "\n=end"; + if (peeks(p, begin)) { + c = peekc_n(p, sizeof(begin)-1); + if (c < 0 || ISSPACE(c)) { + do { + if (!skips(p, end)) { + yyerror(p, "embedded document meets end of file"); + return 0; + } + c = nextc(p); + } while (!(c < 0 || ISSPACE(c))); + if (c != '\n') skip(p, '\n'); + p->lineno++; + p->column = 0; + goto retry; + } + } + } + if (p->lstate == EXPR_FNAME || p->lstate == EXPR_DOT) { + p->lstate = EXPR_ARG; + } + else { + p->lstate = EXPR_BEG; + } + if ((c = nextc(p)) == '=') { + if ((c = nextc(p)) == '=') { + return tEQQ; + } + pushback(p, c); + return tEQ; + } + if (c == '~') { + return tMATCH; + } + else if (c == '>') { + return tASSOC; + } + pushback(p, c); + return '='; + + case '<': + c = nextc(p); + if (c == '<' && + p->lstate != EXPR_DOT && + p->lstate != EXPR_CLASS && + !IS_END() && + (!IS_ARG() || space_seen)) { + int token = heredoc_identifier(p); + if (token) + return token; + } + if (p->lstate == EXPR_FNAME || p->lstate == EXPR_DOT) { + p->lstate = EXPR_ARG; + } + else { + p->lstate = EXPR_BEG; + if (p->lstate == EXPR_CLASS) { + p->cmd_start = TRUE; + } + } + if (c == '=') { + if ((c = nextc(p)) == '>') { + return tCMP; + } + pushback(p, c); + return tLEQ; + } + if (c == '<') { + if ((c = nextc(p)) == '=') { + pylval.id = intern("<<",2); + p->lstate = EXPR_BEG; + return tOP_ASGN; + } + pushback(p, c); + return tLSHFT; + } + pushback(p, c); + return '<'; + + case '>': + if (p->lstate == EXPR_FNAME || p->lstate == EXPR_DOT) { + p->lstate = EXPR_ARG; + } + else { + p->lstate = EXPR_BEG; + } + if ((c = nextc(p)) == '=') { + return tGEQ; + } + if (c == '>') { + if ((c = nextc(p)) == '=') { + pylval.id = intern(">>",2); + p->lstate = EXPR_BEG; + return tOP_ASGN; + } + pushback(p, c); + return tRSHFT; + } + pushback(p, c); + return '>'; + + case '"': + p->lex_strterm = new_strterm(p, str_dquote, '"', 0); + return tSTRING_BEG; + + case '\'': + p->lex_strterm = new_strterm(p, str_squote, '\'', 0); + return parse_string(p); + + case '`': + if (p->lstate == EXPR_FNAME) { + p->lstate = EXPR_ENDFN; + return '`'; + } + if (p->lstate == EXPR_DOT) { + if (cmd_state) + p->lstate = EXPR_CMDARG; + else + p->lstate = EXPR_ARG; + return '`'; + } + p->lex_strterm = new_strterm(p, str_xquote, '`', 0); + return tXSTRING_BEG; + + case '?': + if (IS_END()) { + p->lstate = EXPR_VALUE; + return '?'; + } + c = nextc(p); + if (c < 0) { + yyerror(p, "incomplete character syntax"); + return 0; + } + if (ISSPACE(c)) { + if (!IS_ARG()) { + int c2; + switch (c) { + case ' ': + c2 = 's'; + break; + case '\n': + c2 = 'n'; + break; + case '\t': + c2 = 't'; + break; + case '\v': + c2 = 'v'; + break; + case '\r': + c2 = 'r'; + break; + case '\f': + c2 = 'f'; + break; + default: + c2 = 0; + break; + } + if (c2) { + char buf[256]; + snprintf(buf, sizeof(buf), "invalid character syntax; use ?\\%c", c2); + yyerror(p, buf); + } + } + ternary: + pushback(p, c); + p->lstate = EXPR_VALUE; + return '?'; + } + newtok(p); + /* need support UTF-8 if configured */ + if ((isalnum(c) || c == '_')) { + int c2 = nextc(p); + pushback(p, c2); + if ((isalnum(c2) || c2 == '_')) { + goto ternary; + } + } + if (c == '\\') { + c = read_escape(p); + tokadd(p, c); + } + else { + tokadd(p, c); + } + tokfix(p); + pylval.nd = new_str(p, tok(p), toklen(p)); + p->lstate = EXPR_END; + return tCHAR; + + case '&': + if ((c = nextc(p)) == '&') { + p->lstate = EXPR_BEG; + if ((c = nextc(p)) == '=') { + pylval.id = intern("&&",2); + p->lstate = EXPR_BEG; + return tOP_ASGN; + } + pushback(p, c); + return tANDOP; + } + else if (c == '.') { + p->lstate = EXPR_DOT; + return tANDDOT; + } + else if (c == '=') { + pylval.id = intern_c('&'); + p->lstate = EXPR_BEG; + return tOP_ASGN; + } + pushback(p, c); + if (IS_SPCARG(c)) { + yywarning(p, "'&' interpreted as argument prefix"); + c = tAMPER; + } + else if (IS_BEG()) { + c = tAMPER; + } + else { + c = '&'; + } + if (p->lstate == EXPR_FNAME || p->lstate == EXPR_DOT) { + p->lstate = EXPR_ARG; + } + else { + p->lstate = EXPR_BEG; + } + return c; + + case '|': + if ((c = nextc(p)) == '|') { + p->lstate = EXPR_BEG; + if ((c = nextc(p)) == '=') { + pylval.id = intern("||",2); + p->lstate = EXPR_BEG; + return tOP_ASGN; + } + pushback(p, c); + return tOROP; + } + if (c == '=') { + pylval.id = intern_c('|'); + p->lstate = EXPR_BEG; + return tOP_ASGN; + } + if (p->lstate == EXPR_FNAME || p->lstate == EXPR_DOT) { + p->lstate = EXPR_ARG; + } + else { + p->lstate = EXPR_BEG; + } + pushback(p, c); + return '|'; + + case '+': + c = nextc(p); + if (p->lstate == EXPR_FNAME || p->lstate == EXPR_DOT) { + p->lstate = EXPR_ARG; + if (c == '@') { + return tUPLUS; + } + pushback(p, c); + return '+'; + } + if (c == '=') { + pylval.id = intern_c('+'); + p->lstate = EXPR_BEG; + return tOP_ASGN; + } + if (IS_BEG() || (IS_SPCARG(c) && arg_ambiguous(p))) { + p->lstate = EXPR_BEG; + pushback(p, c); + if (c >= 0 && ISDIGIT(c)) { + c = '+'; + goto start_num; + } + return tUPLUS; + } + p->lstate = EXPR_BEG; + pushback(p, c); + return '+'; + + case '-': + c = nextc(p); + if (p->lstate == EXPR_FNAME || p->lstate == EXPR_DOT) { + p->lstate = EXPR_ARG; + if (c == '@') { + return tUMINUS; + } + pushback(p, c); + return '-'; + } + if (c == '=') { + pylval.id = intern_c('-'); + p->lstate = EXPR_BEG; + return tOP_ASGN; + } + if (c == '>') { + p->lstate = EXPR_ENDFN; + return tLAMBDA; + } + if (IS_BEG() || (IS_SPCARG(c) && arg_ambiguous(p))) { + p->lstate = EXPR_BEG; + pushback(p, c); + if (c >= 0 && ISDIGIT(c)) { + return tUMINUS_NUM; + } + return tUMINUS; + } + p->lstate = EXPR_BEG; + pushback(p, c); + return '-'; + + case '.': + p->lstate = EXPR_BEG; + if ((c = nextc(p)) == '.') { + if ((c = nextc(p)) == '.') { + return tDOT3; + } + pushback(p, c); + return tDOT2; + } + pushback(p, c); + if (c >= 0 && ISDIGIT(c)) { + yyerror(p, "no . floating literal anymore; put 0 before dot"); + } + p->lstate = EXPR_DOT; + return '.'; + + start_num: + case '0': case '1': case '2': case '3': case '4': + case '5': case '6': case '7': case '8': case '9': + { + int is_float, seen_point, seen_e, nondigit; + + is_float = seen_point = seen_e = nondigit = 0; + p->lstate = EXPR_END; + newtok(p); + if (c == '-' || c == '+') { + tokadd(p, c); + c = nextc(p); + } + if (c == '0') { +#define no_digits() do {yyerror(p,"numeric literal without digits"); return 0;} while (0) + int start = toklen(p); + c = nextc(p); + if (c == 'x' || c == 'X') { + /* hexadecimal */ + c = nextc(p); + if (c >= 0 && ISXDIGIT(c)) { + do { + if (c == '_') { + if (nondigit) break; + nondigit = c; + continue; + } + if (!ISXDIGIT(c)) break; + nondigit = 0; + tokadd(p, tolower(c)); + } while ((c = nextc(p)) >= 0); + } + pushback(p, c); + tokfix(p); + if (toklen(p) == start) { + no_digits(); + } + else if (nondigit) goto trailing_uc; + pylval.nd = new_int(p, tok(p), 16); + return tINTEGER; + } + if (c == 'b' || c == 'B') { + /* binary */ + c = nextc(p); + if (c == '0' || c == '1') { + do { + if (c == '_') { + if (nondigit) break; + nondigit = c; + continue; + } + if (c != '0' && c != '1') break; + nondigit = 0; + tokadd(p, c); + } while ((c = nextc(p)) >= 0); + } + pushback(p, c); + tokfix(p); + if (toklen(p) == start) { + no_digits(); + } + else if (nondigit) goto trailing_uc; + pylval.nd = new_int(p, tok(p), 2); + return tINTEGER; + } + if (c == 'd' || c == 'D') { + /* decimal */ + c = nextc(p); + if (c >= 0 && ISDIGIT(c)) { + do { + if (c == '_') { + if (nondigit) break; + nondigit = c; + continue; + } + if (!ISDIGIT(c)) break; + nondigit = 0; + tokadd(p, c); + } while ((c = nextc(p)) >= 0); + } + pushback(p, c); + tokfix(p); + if (toklen(p) == start) { + no_digits(); + } + else if (nondigit) goto trailing_uc; + pylval.nd = new_int(p, tok(p), 10); + return tINTEGER; + } + if (c == '_') { + /* 0_0 */ + goto octal_number; + } + if (c == 'o' || c == 'O') { + /* prefixed octal */ + c = nextc(p); + if (c < 0 || c == '_' || !ISDIGIT(c)) { + no_digits(); + } + } + if (c >= '0' && c <= '7') { + /* octal */ + octal_number: + do { + if (c == '_') { + if (nondigit) break; + nondigit = c; + continue; + } + if (c < '0' || c > '9') break; + if (c > '7') goto invalid_octal; + nondigit = 0; + tokadd(p, c); + } while ((c = nextc(p)) >= 0); + + if (toklen(p) > start) { + pushback(p, c); + tokfix(p); + if (nondigit) goto trailing_uc; + pylval.nd = new_int(p, tok(p), 8); + return tINTEGER; + } + if (nondigit) { + pushback(p, c); + goto trailing_uc; + } + } + if (c > '7' && c <= '9') { + invalid_octal: + yyerror(p, "Invalid octal digit"); + } + else if (c == '.' || c == 'e' || c == 'E') { + tokadd(p, '0'); + } + else { + pushback(p, c); + pylval.nd = new_int(p, "0", 10); + return tINTEGER; + } + } + + for (;;) { + switch (c) { + case '0': case '1': case '2': case '3': case '4': + case '5': case '6': case '7': case '8': case '9': + nondigit = 0; + tokadd(p, c); + break; + + case '.': + if (nondigit) goto trailing_uc; + if (seen_point || seen_e) { + goto decode_num; + } + else { + int c0 = nextc(p); + if (c0 < 0 || !ISDIGIT(c0)) { + pushback(p, c0); + goto decode_num; + } + c = c0; + } + tokadd(p, '.'); + tokadd(p, c); + is_float++; + seen_point++; + nondigit = 0; + break; + + case 'e': + case 'E': + if (nondigit) { + pushback(p, c); + c = nondigit; + goto decode_num; + } + if (seen_e) { + goto decode_num; + } + tokadd(p, c); + seen_e++; + is_float++; + nondigit = c; + c = nextc(p); + if (c != '-' && c != '+') continue; + tokadd(p, c); + nondigit = c; + break; + + case '_': /* '_' in number just ignored */ + if (nondigit) goto decode_num; + nondigit = c; + break; + + default: + goto decode_num; + } + c = nextc(p); + } + + decode_num: + pushback(p, c); + if (nondigit) { + trailing_uc: + yyerror_i(p, "trailing '%c' in number", nondigit); + } + tokfix(p); + if (is_float) { + double d; + char *endp; + + errno = 0; + d = mrb_float_read(tok(p), &endp); + if (d == 0 && endp == tok(p)) { + yywarning_s(p, "corrupted float value %s", tok(p)); + } + else if (errno == ERANGE) { + yywarning_s(p, "float %s out of range", tok(p)); + errno = 0; + } + pylval.nd = new_float(p, tok(p)); + return tFLOAT; + } + pylval.nd = new_int(p, tok(p), 10); + return tINTEGER; + } + + case ')': + case ']': + p->paren_nest--; + /* fall through */ + case '}': + COND_LEXPOP(); + CMDARG_LEXPOP(); + if (c == ')') + p->lstate = EXPR_ENDFN; + else + p->lstate = EXPR_ENDARG; + return c; + + case ':': + c = nextc(p); + if (c == ':') { + if (IS_BEG() || p->lstate == EXPR_CLASS || IS_SPCARG(-1)) { + p->lstate = EXPR_BEG; + return tCOLON3; + } + p->lstate = EXPR_DOT; + return tCOLON2; + } + if (IS_END() || ISSPACE(c)) { + pushback(p, c); + p->lstate = EXPR_BEG; + return ':'; + } + pushback(p, c); + p->lstate = EXPR_FNAME; + return tSYMBEG; + + case '/': + if (IS_BEG()) { + p->lex_strterm = new_strterm(p, str_regexp, '/', 0); + return tREGEXP_BEG; + } + if ((c = nextc(p)) == '=') { + pylval.id = intern_c('/'); + p->lstate = EXPR_BEG; + return tOP_ASGN; + } + pushback(p, c); + if (IS_SPCARG(c)) { + p->lex_strterm = new_strterm(p, str_regexp, '/', 0); + return tREGEXP_BEG; + } + if (p->lstate == EXPR_FNAME || p->lstate == EXPR_DOT) { + p->lstate = EXPR_ARG; + } + else { + p->lstate = EXPR_BEG; + } + return '/'; + + case '^': + if ((c = nextc(p)) == '=') { + pylval.id = intern_c('^'); + p->lstate = EXPR_BEG; + return tOP_ASGN; + } + if (p->lstate == EXPR_FNAME || p->lstate == EXPR_DOT) { + p->lstate = EXPR_ARG; + } + else { + p->lstate = EXPR_BEG; + } + pushback(p, c); + return '^'; + + case ';': + p->lstate = EXPR_BEG; + return ';'; + + case ',': + p->lstate = EXPR_BEG; + return ','; + + case '~': + if (p->lstate == EXPR_FNAME || p->lstate == EXPR_DOT) { + if ((c = nextc(p)) != '@') { + pushback(p, c); + } + p->lstate = EXPR_ARG; + } + else { + p->lstate = EXPR_BEG; + } + return '~'; + + case '(': + if (IS_BEG()) { + c = tLPAREN; + } + else if (IS_SPCARG(-1)) { + c = tLPAREN_ARG; + } + p->paren_nest++; + COND_PUSH(0); + CMDARG_PUSH(0); + p->lstate = EXPR_BEG; + return c; + + case '[': + p->paren_nest++; + if (p->lstate == EXPR_FNAME || p->lstate == EXPR_DOT) { + p->lstate = EXPR_ARG; + if ((c = nextc(p)) == ']') { + if ((c = nextc(p)) == '=') { + return tASET; + } + pushback(p, c); + return tAREF; + } + pushback(p, c); + return '['; + } + else if (IS_BEG()) { + c = tLBRACK; + } + else if (IS_ARG() && space_seen) { + c = tLBRACK; + } + p->lstate = EXPR_BEG; + COND_PUSH(0); + CMDARG_PUSH(0); + return c; + + case '{': + if (p->lpar_beg && p->lpar_beg == p->paren_nest) { + p->lstate = EXPR_BEG; + p->lpar_beg = 0; + p->paren_nest--; + COND_PUSH(0); + CMDARG_PUSH(0); + return tLAMBEG; + } + if (IS_ARG() || p->lstate == EXPR_END || p->lstate == EXPR_ENDFN) + c = '{'; /* block (primary) */ + else if (p->lstate == EXPR_ENDARG) + c = tLBRACE_ARG; /* block (expr) */ + else + c = tLBRACE; /* hash */ + COND_PUSH(0); + CMDARG_PUSH(0); + p->lstate = EXPR_BEG; + return c; + + case '\\': + c = nextc(p); + if (c == '\n') { + p->lineno++; + p->column = 0; + space_seen = 1; + goto retry; /* skip \\n */ + } + pushback(p, c); + return '\\'; + + case '%': + if (IS_BEG()) { + int term; + int paren; + + c = nextc(p); + quotation: + if (c < 0 || !ISALNUM(c)) { + term = c; + c = 'Q'; + } + else { + term = nextc(p); + if (isalnum(term)) { + yyerror(p, "unknown type of %string"); + return 0; + } + } + if (c < 0 || term < 0) { + yyerror(p, "unterminated quoted string meets end of file"); + return 0; + } + paren = term; + if (term == '(') term = ')'; + else if (term == '[') term = ']'; + else if (term == '{') term = '}'; + else if (term == '<') term = '>'; + else paren = 0; + + switch (c) { + case 'Q': + p->lex_strterm = new_strterm(p, str_dquote, term, paren); + return tSTRING_BEG; + + case 'q': + p->lex_strterm = new_strterm(p, str_squote, term, paren); + return parse_string(p); + + case 'W': + p->lex_strterm = new_strterm(p, str_dword, term, paren); + return tWORDS_BEG; + + case 'w': + p->lex_strterm = new_strterm(p, str_sword, term, paren); + return tWORDS_BEG; + + case 'x': + p->lex_strterm = new_strterm(p, str_xquote, term, paren); + return tXSTRING_BEG; + + case 'r': + p->lex_strterm = new_strterm(p, str_regexp, term, paren); + return tREGEXP_BEG; + + case 's': + p->lex_strterm = new_strterm(p, str_ssym, term, paren); + return tSYMBEG; + + case 'I': + p->lex_strterm = new_strterm(p, str_dsymbols, term, paren); + return tSYMBOLS_BEG; + + case 'i': + p->lex_strterm = new_strterm(p, str_ssymbols, term, paren); + return tSYMBOLS_BEG; + + default: + yyerror(p, "unknown type of %string"); + return 0; + } + } + if ((c = nextc(p)) == '=') { + pylval.id = intern_c('%'); + p->lstate = EXPR_BEG; + return tOP_ASGN; + } + if (IS_SPCARG(c)) { + goto quotation; + } + if (p->lstate == EXPR_FNAME || p->lstate == EXPR_DOT) { + p->lstate = EXPR_ARG; + } + else { + p->lstate = EXPR_BEG; + } + pushback(p, c); + return '%'; + + case '$': + p->lstate = EXPR_END; + token_column = newtok(p); + c = nextc(p); + if (c < 0) { + yyerror(p, "incomplete global variable syntax"); + return 0; + } + switch (c) { + case '_': /* $_: last read line string */ + c = nextc(p); + if (c >= 0 && identchar(c)) { /* if there is more after _ it is a variable */ + tokadd(p, '$'); + tokadd(p, c); + break; + } + pushback(p, c); + c = '_'; + /* fall through */ + case '~': /* $~: match-data */ + case '*': /* $*: argv */ + case '$': /* $$: pid */ + case '?': /* $?: last status */ + case '!': /* $!: error string */ + case '@': /* $@: error position */ + case '/': /* $/: input record separator */ + case '\\': /* $\: output record separator */ + case ';': /* $;: field separator */ + case ',': /* $,: output field separator */ + case '.': /* $.: last read line number */ + case '=': /* $=: ignorecase */ + case ':': /* $:: load path */ + case '<': /* $<: reading filename */ + case '>': /* $>: default output handle */ + case '\"': /* $": already loaded files */ + tokadd(p, '$'); + tokadd(p, c); + tokfix(p); + pylval.id = intern_cstr(tok(p)); + return tGVAR; + + case '-': + tokadd(p, '$'); + tokadd(p, c); + c = nextc(p); + pushback(p, c); + gvar: + tokfix(p); + pylval.id = intern_cstr(tok(p)); + return tGVAR; + + case '&': /* $&: last match */ + case '`': /* $`: string before last match */ + case '\'': /* $': string after last match */ + case '+': /* $+: string matches last pattern */ + if (last_state == EXPR_FNAME) { + tokadd(p, '$'); + tokadd(p, c); + goto gvar; + } + pylval.nd = new_back_ref(p, c); + return tBACK_REF; + + case '1': case '2': case '3': + case '4': case '5': case '6': + case '7': case '8': case '9': + do { + tokadd(p, c); + c = nextc(p); + } while (c >= 0 && isdigit(c)); + pushback(p, c); + if (last_state == EXPR_FNAME) goto gvar; + tokfix(p); + { + unsigned long n = strtoul(tok(p), NULL, 10); + if (n > INT_MAX) { + yyerror_i(p, "capture group index must be <= %d", INT_MAX); + return 0; + } + pylval.nd = new_nth_ref(p, (int)n); + } + return tNTH_REF; + + default: + if (!identchar(c)) { + pushback(p, c); + return '$'; + } + /* fall through */ + case '0': + tokadd(p, '$'); + } + break; + + case '@': + c = nextc(p); + token_column = newtok(p); + tokadd(p, '@'); + if (c == '@') { + tokadd(p, '@'); + c = nextc(p); + } + if (c < 0) { + if (p->tidx == 1) { + yyerror(p, "incomplete instance variable syntax"); + } + else { + yyerror(p, "incomplete class variable syntax"); + } + return 0; + } + else if (isdigit(c)) { + if (p->tidx == 1) { + yyerror_i(p, "'@%c' is not allowed as an instance variable name", c); + } + else { + yyerror_i(p, "'@@%c' is not allowed as a class variable name", c); + } + return 0; + } + if (!identchar(c)) { + pushback(p, c); + return '@'; + } + break; + + case '_': + token_column = newtok(p); + break; + + default: + if (!identchar(c)) { + yyerror_i(p, "Invalid char '\\x%02X' in expression", c); + goto retry; + } + + token_column = newtok(p); + break; + } + + do { + tokadd(p, c); + c = nextc(p); + if (c < 0) break; + } while (identchar(c)); + if (token_column == 0 && toklen(p) == 7 && (c < 0 || c == '\n') && + strncmp(tok(p), "__END__", toklen(p)) == 0) + return -1; + + switch (tok(p)[0]) { + case '@': case '$': + pushback(p, c); + break; + default: + if ((c == '!' || c == '?') && !peek(p, '=')) { + tokadd(p, c); + } + else { + pushback(p, c); + } + } + tokfix(p); + { + int result = 0; + + switch (tok(p)[0]) { + case '$': + p->lstate = EXPR_END; + result = tGVAR; + break; + case '@': + p->lstate = EXPR_END; + if (tok(p)[1] == '@') + result = tCVAR; + else + result = tIVAR; + break; + + default: + if (toklast(p) == '!' || toklast(p) == '?') { + result = tFID; + } + else { + if (p->lstate == EXPR_FNAME) { + if ((c = nextc(p)) == '=' && !peek(p, '~') && !peek(p, '>') && + (!peek(p, '=') || (peek_n(p, '>', 1)))) { + result = tIDENTIFIER; + tokadd(p, c); + tokfix(p); + } + else { + pushback(p, c); + } + } + if (result == 0 && ISUPPER(tok(p)[0])) { + result = tCONSTANT; + } + else { + result = tIDENTIFIER; + } + } + + if (IS_LABEL_POSSIBLE()) { + if (IS_LABEL_SUFFIX(0)) { + p->lstate = EXPR_BEG; + nextc(p); + tokfix(p); + pylval.id = intern_cstr(tok(p)); + return tLABEL; + } + } + if (p->lstate != EXPR_DOT) { + const struct kwtable *kw; + + /* See if it is a reserved word. */ + kw = mrb_reserved_word(tok(p), toklen(p)); + if (kw) { + enum mrb_lex_state_enum state = p->lstate; + pylval.num = p->lineno; + p->lstate = kw->state; + if (state == EXPR_FNAME) { + pylval.id = intern_cstr(kw->name); + return kw->id[0]; + } + if (p->lstate == EXPR_BEG) { + p->cmd_start = TRUE; + } + if (kw->id[0] == keyword_do) { + if (p->lpar_beg && p->lpar_beg == p->paren_nest) { + p->lpar_beg = 0; + p->paren_nest--; + return keyword_do_LAMBDA; + } + if (COND_P()) return keyword_do_cond; + if (CMDARG_P() && state != EXPR_CMDARG) + return keyword_do_block; + if (state == EXPR_ENDARG || state == EXPR_BEG) + return keyword_do_block; + return keyword_do; + } + if (state == EXPR_BEG || state == EXPR_VALUE) + return kw->id[0]; + else { + if (kw->id[0] != kw->id[1]) + p->lstate = EXPR_BEG; + return kw->id[1]; + } + } + } + + if (IS_BEG() || p->lstate == EXPR_DOT || IS_ARG()) { + if (cmd_state) { + p->lstate = EXPR_CMDARG; + } + else { + p->lstate = EXPR_ARG; + } + } + else if (p->lstate == EXPR_FNAME) { + p->lstate = EXPR_ENDFN; + } + else { + p->lstate = EXPR_END; + } + } + { + mrb_sym ident = intern_cstr(tok(p)); + + pylval.id = ident; +#if 0 + if (last_state != EXPR_DOT && islower(tok(p)[0]) && lvar_defined(ident)) { + p->lstate = EXPR_END; + } +#endif + } + return result; + } +} + +static int +yylex(void *lval, parser_state *p) +{ + p->ylval = lval; + return parser_yylex(p); +} + +static void +parser_init_cxt(parser_state *p, mrbc_context *cxt) +{ + if (!cxt) return; + if (cxt->filename) mrb_parser_set_filename(p, cxt->filename); + if (cxt->lineno) p->lineno = cxt->lineno; + if (cxt->syms) { + int i; + + p->locals = cons(0,0); + for (i=0; islen; i++) { + local_add_f(p, cxt->syms[i]); + } + } + p->capture_errors = cxt->capture_errors; + p->no_optimize = cxt->no_optimize; + if (cxt->partial_hook) { + p->cxt = cxt; + } +} + +static void +parser_update_cxt(parser_state *p, mrbc_context *cxt) +{ + node *n, *n0; + int i = 0; + + if (!cxt) return; + if ((int)(intptr_t)p->tree->car != NODE_SCOPE) return; + n0 = n = p->tree->cdr->car; + while (n) { + i++; + n = n->cdr; + } + cxt->syms = (mrb_sym *)mrb_realloc(p->mrb, cxt->syms, i*sizeof(mrb_sym)); + cxt->slen = i; + for (i=0, n=n0; n; i++,n=n->cdr) { + cxt->syms[i] = sym(n->car); + } +} + +void mrb_codedump_all(mrb_state*, struct RProc*); +void mrb_parser_dump(mrb_state *mrb, node *tree, int offset); + +MRB_API void +mrb_parser_parse(parser_state *p, mrbc_context *c) +{ + struct mrb_jmpbuf buf1; + p->jmp = &buf1; + + MRB_TRY(p->jmp) { + int n = 1; + + p->cmd_start = TRUE; + p->in_def = p->in_single = 0; + p->nerr = p->nwarn = 0; + p->lex_strterm = NULL; + + parser_init_cxt(p, c); + + if (p->mrb->jmp) { + n = yyparse(p); + } + else { + struct mrb_jmpbuf buf2; + + p->mrb->jmp = &buf2; + MRB_TRY(p->mrb->jmp) { + n = yyparse(p); + } + MRB_CATCH(p->mrb->jmp) { + p->nerr++; + } + MRB_END_EXC(p->mrb->jmp); + p->mrb->jmp = 0; + } + if (n != 0 || p->nerr > 0) { + p->tree = 0; + return; + } + if (!p->tree) { + p->tree = new_nil(p); + } + parser_update_cxt(p, c); + if (c && c->dump_result) { + mrb_parser_dump(p->mrb, p->tree, 0); + } + } + MRB_CATCH(p->jmp) { + yyerror(p, "memory allocation error"); + p->nerr++; + p->tree = 0; + return; + } + MRB_END_EXC(p->jmp); +} + +MRB_API parser_state* +mrb_parser_new(mrb_state *mrb) +{ + mrb_pool *pool; + parser_state *p; + static const parser_state parser_state_zero = { 0 }; + + pool = mrb_pool_open(mrb); + if (!pool) return NULL; + p = (parser_state *)mrb_pool_alloc(pool, sizeof(parser_state)); + if (!p) return NULL; + + *p = parser_state_zero; + p->mrb = mrb; + p->pool = pool; + + p->s = p->send = NULL; +#ifndef MRB_DISABLE_STDIO + p->f = NULL; +#endif + + p->cmd_start = TRUE; + p->in_def = p->in_single = 0; + + p->capture_errors = FALSE; + p->lineno = 1; + p->column = 0; +#if defined(PARSER_TEST) || defined(PARSER_DEBUG) + yydebug = 1; +#endif + p->tsiz = MRB_PARSER_TOKBUF_SIZE; + p->tokbuf = p->buf; + + p->lex_strterm = NULL; + p->all_heredocs = p->parsing_heredoc = NULL; + p->lex_strterm_before_heredoc = NULL; + + p->current_filename_index = -1; + p->filename_table = NULL; + p->filename_table_length = 0; + + return p; +} + +MRB_API void +mrb_parser_free(parser_state *p) { + if (p->tokbuf != p->buf) { + mrb_free(p->mrb, p->tokbuf); + } + mrb_pool_close(p->pool); +} + +MRB_API mrbc_context* +mrbc_context_new(mrb_state *mrb) +{ + return (mrbc_context *)mrb_calloc(mrb, 1, sizeof(mrbc_context)); +} + +MRB_API void +mrbc_context_free(mrb_state *mrb, mrbc_context *cxt) +{ + mrb_free(mrb, cxt->filename); + mrb_free(mrb, cxt->syms); + mrb_free(mrb, cxt); +} + +MRB_API const char* +mrbc_filename(mrb_state *mrb, mrbc_context *c, const char *s) +{ + if (s) { + size_t len = strlen(s); + char *p = (char *)mrb_malloc(mrb, len + 1); + + memcpy(p, s, len + 1); + if (c->filename) { + mrb_free(mrb, c->filename); + } + c->filename = p; + } + return c->filename; +} + +MRB_API void +mrbc_partial_hook(mrb_state *mrb, mrbc_context *c, int (*func)(struct mrb_parser_state*), void *data) +{ + c->partial_hook = func; + c->partial_data = data; +} + +MRB_API void +mrb_parser_set_filename(struct mrb_parser_state *p, const char *f) +{ + mrb_sym sym; + size_t i; + mrb_sym* new_table; + + sym = mrb_intern_cstr(p->mrb, f); + p->filename = mrb_sym2name_len(p->mrb, sym, NULL); + p->lineno = (p->filename_table_length > 0)? 0 : 1; + + for (i = 0; i < p->filename_table_length; ++i) { + if (p->filename_table[i] == sym) { + p->current_filename_index = (int)i; + return; + } + } + + p->current_filename_index = (int)p->filename_table_length++; + + new_table = (mrb_sym*)parser_palloc(p, sizeof(mrb_sym) * p->filename_table_length); + if (p->filename_table) { + memmove(new_table, p->filename_table, sizeof(mrb_sym) * p->filename_table_length); + } + p->filename_table = new_table; + p->filename_table[p->filename_table_length - 1] = sym; +} + +MRB_API char const* +mrb_parser_get_filename(struct mrb_parser_state* p, uint16_t idx) { + if (idx >= p->filename_table_length) { return NULL; } + else { + return mrb_sym2name_len(p->mrb, p->filename_table[idx], NULL); + } +} + +#ifndef MRB_DISABLE_STDIO +MRB_API parser_state* +mrb_parse_file(mrb_state *mrb, FILE *f, mrbc_context *c) +{ + parser_state *p; + + p = mrb_parser_new(mrb); + if (!p) return NULL; + p->s = p->send = NULL; + p->f = f; + + mrb_parser_parse(p, c); + return p; +} +#endif + +MRB_API parser_state* +mrb_parse_nstring(mrb_state *mrb, const char *s, size_t len, mrbc_context *c) +{ + parser_state *p; + + p = mrb_parser_new(mrb); + if (!p) return NULL; + p->s = s; + p->send = s + len; + + mrb_parser_parse(p, c); + return p; +} + +MRB_API parser_state* +mrb_parse_string(mrb_state *mrb, const char *s, mrbc_context *c) +{ + return mrb_parse_nstring(mrb, s, strlen(s), c); +} + +MRB_API mrb_value +mrb_load_exec(mrb_state *mrb, struct mrb_parser_state *p, mrbc_context *c) +{ + struct RClass *target = mrb->object_class; + struct RProc *proc; + mrb_value v; + unsigned int keep = 0; + + if (!p) { + return mrb_undef_value(); + } + if (!p->tree || p->nerr) { + if (c) c->parser_nerr = p->nerr; + if (p->capture_errors) { + char buf[256]; + int n; + + n = snprintf(buf, sizeof(buf), "line %d: %s\n", + p->error_buffer[0].lineno, p->error_buffer[0].message); + mrb->exc = mrb_obj_ptr(mrb_exc_new(mrb, E_SYNTAX_ERROR, buf, n)); + mrb_parser_free(p); + return mrb_undef_value(); + } + else { + if (mrb->exc == NULL) { + mrb->exc = mrb_obj_ptr(mrb_exc_new_str_lit(mrb, E_SYNTAX_ERROR, "syntax error")); + } + mrb_parser_free(p); + return mrb_undef_value(); + } + } + proc = mrb_generate_code(mrb, p); + mrb_parser_free(p); + if (proc == NULL) { + if (mrb->exc == NULL) { + mrb->exc = mrb_obj_ptr(mrb_exc_new_str_lit(mrb, E_SCRIPT_ERROR, "codegen error")); + } + return mrb_undef_value(); + } + if (c) { + if (c->dump_result) mrb_codedump_all(mrb, proc); + if (c->no_exec) return mrb_obj_value(proc); + if (c->target_class) { + target = c->target_class; + } + if (c->keep_lv) { + keep = c->slen + 1; + } + else { + c->keep_lv = TRUE; + } + } + proc->target_class = target; + if (mrb->c->ci) { + mrb->c->ci->target_class = target; + } + v = mrb_top_run(mrb, proc, mrb_top_self(mrb), keep); + if (mrb->exc) return mrb_nil_value(); + return v; +} + +#ifndef MRB_DISABLE_STDIO +MRB_API mrb_value +mrb_load_file_cxt(mrb_state *mrb, FILE *f, mrbc_context *c) +{ + return mrb_load_exec(mrb, mrb_parse_file(mrb, f, c), c); +} + +MRB_API mrb_value +mrb_load_file(mrb_state *mrb, FILE *f) +{ + return mrb_load_file_cxt(mrb, f, NULL); +} +#endif + +MRB_API mrb_value +mrb_load_nstring_cxt(mrb_state *mrb, const char *s, size_t len, mrbc_context *c) +{ + return mrb_load_exec(mrb, mrb_parse_nstring(mrb, s, len, c), c); +} + +MRB_API mrb_value +mrb_load_nstring(mrb_state *mrb, const char *s, size_t len) +{ + return mrb_load_nstring_cxt(mrb, s, len, NULL); +} + +MRB_API mrb_value +mrb_load_string_cxt(mrb_state *mrb, const char *s, mrbc_context *c) +{ + return mrb_load_nstring_cxt(mrb, s, strlen(s), c); +} + +MRB_API mrb_value +mrb_load_string(mrb_state *mrb, const char *s) +{ + return mrb_load_string_cxt(mrb, s, NULL); +} + +#ifndef MRB_DISABLE_STDIO + +static void +dump_prefix(node *tree, int offset) +{ + printf("%05d ", tree->lineno); + while (offset--) { + putc(' ', stdout); + putc(' ', stdout); + } +} + +static void +dump_recur(mrb_state *mrb, node *tree, int offset) +{ + while (tree) { + mrb_parser_dump(mrb, tree->car, offset); + tree = tree->cdr; + } +} + +#endif + +void +mrb_parser_dump(mrb_state *mrb, node *tree, int offset) +{ +#ifndef MRB_DISABLE_STDIO + int nodetype; + + if (!tree) return; + again: + dump_prefix(tree, offset); + nodetype = (int)(intptr_t)tree->car; + tree = tree->cdr; + switch (nodetype) { + case NODE_BEGIN: + printf("NODE_BEGIN:\n"); + dump_recur(mrb, tree, offset+1); + break; + + case NODE_RESCUE: + printf("NODE_RESCUE:\n"); + if (tree->car) { + dump_prefix(tree, offset+1); + printf("body:\n"); + mrb_parser_dump(mrb, tree->car, offset+2); + } + tree = tree->cdr; + if (tree->car) { + node *n2 = tree->car; + + dump_prefix(n2, offset+1); + printf("rescue:\n"); + while (n2) { + node *n3 = n2->car; + if (n3->car) { + dump_prefix(n2, offset+2); + printf("handle classes:\n"); + dump_recur(mrb, n3->car, offset+3); + } + if (n3->cdr->car) { + dump_prefix(n3, offset+2); + printf("exc_var:\n"); + mrb_parser_dump(mrb, n3->cdr->car, offset+3); + } + if (n3->cdr->cdr->car) { + dump_prefix(n3, offset+2); + printf("rescue body:\n"); + mrb_parser_dump(mrb, n3->cdr->cdr->car, offset+3); + } + n2 = n2->cdr; + } + } + tree = tree->cdr; + if (tree->car) { + dump_prefix(tree, offset+1); + printf("else:\n"); + mrb_parser_dump(mrb, tree->car, offset+2); + } + break; + + case NODE_ENSURE: + printf("NODE_ENSURE:\n"); + dump_prefix(tree, offset+1); + printf("body:\n"); + mrb_parser_dump(mrb, tree->car, offset+2); + dump_prefix(tree, offset+1); + printf("ensure:\n"); + mrb_parser_dump(mrb, tree->cdr->cdr, offset+2); + break; + + case NODE_LAMBDA: + printf("NODE_BLOCK:\n"); + goto block; + + case NODE_BLOCK: + block: + printf("NODE_BLOCK:\n"); + tree = tree->cdr; + if (tree->car) { + node *n = tree->car; + + if (n->car) { + dump_prefix(n, offset+1); + printf("mandatory args:\n"); + dump_recur(mrb, n->car, offset+2); + } + n = n->cdr; + if (n->car) { + dump_prefix(n, offset+1); + printf("optional args:\n"); + { + node *n2 = n->car; + + while (n2) { + dump_prefix(n2, offset+2); + printf("%s=", mrb_sym2name(mrb, sym(n2->car->car))); + mrb_parser_dump(mrb, n2->car->cdr, 0); + n2 = n2->cdr; + } + } + } + n = n->cdr; + if (n->car) { + dump_prefix(n, offset+1); + printf("rest=*%s\n", mrb_sym2name(mrb, sym(n->car))); + } + n = n->cdr; + if (n->car) { + dump_prefix(n, offset+1); + printf("post mandatory args:\n"); + dump_recur(mrb, n->car, offset+2); + } + if (n->cdr) { + dump_prefix(n, offset+1); + printf("blk=&%s\n", mrb_sym2name(mrb, sym(n->cdr))); + } + } + dump_prefix(tree, offset+1); + printf("body:\n"); + mrb_parser_dump(mrb, tree->cdr->car, offset+2); + break; + + case NODE_IF: + printf("NODE_IF:\n"); + dump_prefix(tree, offset+1); + printf("cond:\n"); + mrb_parser_dump(mrb, tree->car, offset+2); + dump_prefix(tree, offset+1); + printf("then:\n"); + mrb_parser_dump(mrb, tree->cdr->car, offset+2); + if (tree->cdr->cdr->car) { + dump_prefix(tree, offset+1); + printf("else:\n"); + mrb_parser_dump(mrb, tree->cdr->cdr->car, offset+2); + } + break; + + case NODE_AND: + printf("NODE_AND:\n"); + mrb_parser_dump(mrb, tree->car, offset+1); + mrb_parser_dump(mrb, tree->cdr, offset+1); + break; + + case NODE_OR: + printf("NODE_OR:\n"); + mrb_parser_dump(mrb, tree->car, offset+1); + mrb_parser_dump(mrb, tree->cdr, offset+1); + break; + + case NODE_CASE: + printf("NODE_CASE:\n"); + if (tree->car) { + mrb_parser_dump(mrb, tree->car, offset+1); + } + tree = tree->cdr; + while (tree) { + dump_prefix(tree, offset+1); + printf("case:\n"); + dump_recur(mrb, tree->car->car, offset+2); + dump_prefix(tree, offset+1); + printf("body:\n"); + mrb_parser_dump(mrb, tree->car->cdr, offset+2); + tree = tree->cdr; + } + break; + + case NODE_WHILE: + printf("NODE_WHILE:\n"); + dump_prefix(tree, offset+1); + printf("cond:\n"); + mrb_parser_dump(mrb, tree->car, offset+2); + dump_prefix(tree, offset+1); + printf("body:\n"); + mrb_parser_dump(mrb, tree->cdr, offset+2); + break; + + case NODE_UNTIL: + printf("NODE_UNTIL:\n"); + dump_prefix(tree, offset+1); + printf("cond:\n"); + mrb_parser_dump(mrb, tree->car, offset+2); + dump_prefix(tree, offset+1); + printf("body:\n"); + mrb_parser_dump(mrb, tree->cdr, offset+2); + break; + + case NODE_FOR: + printf("NODE_FOR:\n"); + dump_prefix(tree, offset+1); + printf("var:\n"); + { + node *n2 = tree->car; + + if (n2->car) { + dump_prefix(n2, offset+2); + printf("pre:\n"); + dump_recur(mrb, n2->car, offset+3); + } + n2 = n2->cdr; + if (n2) { + if (n2->car) { + dump_prefix(n2, offset+2); + printf("rest:\n"); + mrb_parser_dump(mrb, n2->car, offset+3); + } + n2 = n2->cdr; + if (n2) { + if (n2->car) { + dump_prefix(n2, offset+2); + printf("post:\n"); + dump_recur(mrb, n2->car, offset+3); + } + } + } + } + tree = tree->cdr; + dump_prefix(tree, offset+1); + printf("in:\n"); + mrb_parser_dump(mrb, tree->car, offset+2); + tree = tree->cdr; + dump_prefix(tree, offset+1); + printf("do:\n"); + mrb_parser_dump(mrb, tree->car, offset+2); + break; + + case NODE_SCOPE: + printf("NODE_SCOPE:\n"); + { + node *n2 = tree->car; + mrb_bool first_lval = TRUE; + + if (n2 && (n2->car || n2->cdr)) { + dump_prefix(n2, offset+1); + printf("local variables:\n"); + dump_prefix(n2, offset+2); + while (n2) { + if (n2->car) { + if (!first_lval) printf(", "); + printf("%s", mrb_sym2name(mrb, sym(n2->car))); + first_lval = FALSE; + } + n2 = n2->cdr; + } + printf("\n"); + } + } + tree = tree->cdr; + offset++; + goto again; + + case NODE_FCALL: + case NODE_CALL: + case NODE_SCALL: + switch (nodetype) { + case NODE_FCALL: + printf("NODE_FCALL:\n"); break; + case NODE_CALL: + printf("NODE_CALL(.):\n"); break; + case NODE_SCALL: + printf("NODE_SCALL(&.):\n"); break; + default: + break; + } + mrb_parser_dump(mrb, tree->car, offset+1); + dump_prefix(tree, offset+1); + printf("method='%s' (%d)\n", + mrb_sym2name(mrb, sym(tree->cdr->car)), + (int)(intptr_t)tree->cdr->car); + tree = tree->cdr->cdr->car; + if (tree) { + dump_prefix(tree, offset+1); + printf("args:\n"); + dump_recur(mrb, tree->car, offset+2); + if (tree->cdr) { + dump_prefix(tree, offset+1); + printf("block:\n"); + mrb_parser_dump(mrb, tree->cdr, offset+2); + } + } + break; + + case NODE_DOT2: + printf("NODE_DOT2:\n"); + mrb_parser_dump(mrb, tree->car, offset+1); + mrb_parser_dump(mrb, tree->cdr, offset+1); + break; + + case NODE_DOT3: + printf("NODE_DOT3:\n"); + mrb_parser_dump(mrb, tree->car, offset+1); + mrb_parser_dump(mrb, tree->cdr, offset+1); + break; + + case NODE_COLON2: + printf("NODE_COLON2:\n"); + mrb_parser_dump(mrb, tree->car, offset+1); + dump_prefix(tree, offset+1); + printf("::%s\n", mrb_sym2name(mrb, sym(tree->cdr))); + break; + + case NODE_COLON3: + printf("NODE_COLON3: ::%s\n", mrb_sym2name(mrb, sym(tree))); + break; + + case NODE_ARRAY: + printf("NODE_ARRAY:\n"); + dump_recur(mrb, tree, offset+1); + break; + + case NODE_HASH: + printf("NODE_HASH:\n"); + while (tree) { + dump_prefix(tree, offset+1); + printf("key:\n"); + mrb_parser_dump(mrb, tree->car->car, offset+2); + dump_prefix(tree, offset+1); + printf("value:\n"); + mrb_parser_dump(mrb, tree->car->cdr, offset+2); + tree = tree->cdr; + } + break; + + case NODE_SPLAT: + printf("NODE_SPLAT:\n"); + mrb_parser_dump(mrb, tree, offset+1); + break; + + case NODE_ASGN: + printf("NODE_ASGN:\n"); + dump_prefix(tree, offset+1); + printf("lhs:\n"); + mrb_parser_dump(mrb, tree->car, offset+2); + dump_prefix(tree, offset+1); + printf("rhs:\n"); + mrb_parser_dump(mrb, tree->cdr, offset+2); + break; + + case NODE_MASGN: + printf("NODE_MASGN:\n"); + dump_prefix(tree, offset+1); + printf("mlhs:\n"); + { + node *n2 = tree->car; + + if (n2->car) { + dump_prefix(tree, offset+2); + printf("pre:\n"); + dump_recur(mrb, n2->car, offset+3); + } + n2 = n2->cdr; + if (n2) { + if (n2->car) { + dump_prefix(n2, offset+2); + printf("rest:\n"); + if (n2->car == (node*)-1) { + dump_prefix(n2, offset+2); + printf("(empty)\n"); + } + else { + mrb_parser_dump(mrb, n2->car, offset+3); + } + } + n2 = n2->cdr; + if (n2) { + if (n2->car) { + dump_prefix(n2, offset+2); + printf("post:\n"); + dump_recur(mrb, n2->car, offset+3); + } + } + } + } + dump_prefix(tree, offset+1); + printf("rhs:\n"); + mrb_parser_dump(mrb, tree->cdr, offset+2); + break; + + case NODE_OP_ASGN: + printf("NODE_OP_ASGN:\n"); + dump_prefix(tree, offset+1); + printf("lhs:\n"); + mrb_parser_dump(mrb, tree->car, offset+2); + tree = tree->cdr; + dump_prefix(tree, offset+1); + printf("op='%s' (%d)\n", mrb_sym2name(mrb, sym(tree->car)), (int)(intptr_t)tree->car); + tree = tree->cdr; + mrb_parser_dump(mrb, tree->car, offset+1); + break; + + case NODE_SUPER: + printf("NODE_SUPER:\n"); + if (tree) { + dump_prefix(tree, offset+1); + printf("args:\n"); + dump_recur(mrb, tree->car, offset+2); + if (tree->cdr) { + dump_prefix(tree, offset+1); + printf("block:\n"); + mrb_parser_dump(mrb, tree->cdr, offset+2); + } + } + break; + + case NODE_ZSUPER: + printf("NODE_ZSUPER\n"); + break; + + case NODE_RETURN: + printf("NODE_RETURN:\n"); + mrb_parser_dump(mrb, tree, offset+1); + break; + + case NODE_YIELD: + printf("NODE_YIELD:\n"); + dump_recur(mrb, tree, offset+1); + break; + + case NODE_BREAK: + printf("NODE_BREAK:\n"); + mrb_parser_dump(mrb, tree, offset+1); + break; + + case NODE_NEXT: + printf("NODE_NEXT:\n"); + mrb_parser_dump(mrb, tree, offset+1); + break; + + case NODE_REDO: + printf("NODE_REDO\n"); + break; + + case NODE_RETRY: + printf("NODE_RETRY\n"); + break; + + case NODE_LVAR: + printf("NODE_LVAR %s\n", mrb_sym2name(mrb, sym(tree))); + break; + + case NODE_GVAR: + printf("NODE_GVAR %s\n", mrb_sym2name(mrb, sym(tree))); + break; + + case NODE_IVAR: + printf("NODE_IVAR %s\n", mrb_sym2name(mrb, sym(tree))); + break; + + case NODE_CVAR: + printf("NODE_CVAR %s\n", mrb_sym2name(mrb, sym(tree))); + break; + + case NODE_CONST: + printf("NODE_CONST %s\n", mrb_sym2name(mrb, sym(tree))); + break; + + case NODE_MATCH: + printf("NODE_MATCH:\n"); + dump_prefix(tree, offset + 1); + printf("lhs:\n"); + mrb_parser_dump(mrb, tree->car, offset + 2); + dump_prefix(tree, offset + 1); + printf("rhs:\n"); + mrb_parser_dump(mrb, tree->cdr, offset + 2); + break; + + case NODE_BACK_REF: + printf("NODE_BACK_REF: $%c\n", (int)(intptr_t)tree); + break; + + case NODE_NTH_REF: + printf("NODE_NTH_REF: $%" MRB_PRId "\n", (mrb_int)(intptr_t)tree); + break; + + case NODE_ARG: + printf("NODE_ARG %s\n", mrb_sym2name(mrb, sym(tree))); + break; + + case NODE_BLOCK_ARG: + printf("NODE_BLOCK_ARG:\n"); + mrb_parser_dump(mrb, tree, offset+1); + break; + + case NODE_INT: + printf("NODE_INT %s base %d\n", (char*)tree->car, (int)(intptr_t)tree->cdr->car); + break; + + case NODE_FLOAT: + printf("NODE_FLOAT %s\n", (char*)tree); + break; + + case NODE_NEGATE: + printf("NODE_NEGATE\n"); + mrb_parser_dump(mrb, tree, offset+1); + break; + + case NODE_STR: + printf("NODE_STR \"%s\" len %d\n", (char*)tree->car, (int)(intptr_t)tree->cdr); + break; + + case NODE_DSTR: + printf("NODE_DSTR\n"); + dump_recur(mrb, tree, offset+1); + break; + + case NODE_XSTR: + printf("NODE_XSTR \"%s\" len %d\n", (char*)tree->car, (int)(intptr_t)tree->cdr); + break; + + case NODE_DXSTR: + printf("NODE_DXSTR\n"); + dump_recur(mrb, tree, offset+1); + break; + + case NODE_REGX: + printf("NODE_REGX /%s/%s\n", (char*)tree->car, (char*)tree->cdr); + break; + + case NODE_DREGX: + printf("NODE_DREGX\n"); + dump_recur(mrb, tree->car, offset+1); + dump_prefix(tree, offset); + printf("tail: %s\n", (char*)tree->cdr->cdr->car); + if (tree->cdr->cdr->cdr->car) { + dump_prefix(tree, offset); + printf("opt: %s\n", (char*)tree->cdr->cdr->cdr->car); + } + if (tree->cdr->cdr->cdr->cdr) { + dump_prefix(tree, offset); + printf("enc: %s\n", (char*)tree->cdr->cdr->cdr->cdr); + } + break; + + case NODE_SYM: + printf("NODE_SYM :%s (%d)\n", mrb_sym2name(mrb, sym(tree)), + (int)(intptr_t)tree); + break; + + case NODE_SELF: + printf("NODE_SELF\n"); + break; + + case NODE_NIL: + printf("NODE_NIL\n"); + break; + + case NODE_TRUE: + printf("NODE_TRUE\n"); + break; + + case NODE_FALSE: + printf("NODE_FALSE\n"); + break; + + case NODE_ALIAS: + printf("NODE_ALIAS %s %s:\n", + mrb_sym2name(mrb, sym(tree->car)), + mrb_sym2name(mrb, sym(tree->cdr))); + break; + + case NODE_UNDEF: + printf("NODE_UNDEF"); + { + node *t = tree; + while (t) { + printf(" %s", mrb_sym2name(mrb, sym(t->car))); + t = t->cdr; + } + } + printf(":\n"); + break; + + case NODE_CLASS: + printf("NODE_CLASS:\n"); + if (tree->car->car == (node*)0) { + dump_prefix(tree, offset+1); + printf(":%s\n", mrb_sym2name(mrb, sym(tree->car->cdr))); + } + else if (tree->car->car == (node*)1) { + dump_prefix(tree, offset+1); + printf("::%s\n", mrb_sym2name(mrb, sym(tree->car->cdr))); + } + else { + mrb_parser_dump(mrb, tree->car->car, offset+1); + dump_prefix(tree, offset+1); + printf("::%s\n", mrb_sym2name(mrb, sym(tree->car->cdr))); + } + if (tree->cdr->car) { + dump_prefix(tree, offset+1); + printf("super:\n"); + mrb_parser_dump(mrb, tree->cdr->car, offset+2); + } + dump_prefix(tree, offset+1); + printf("body:\n"); + mrb_parser_dump(mrb, tree->cdr->cdr->car->cdr, offset+2); + break; + + case NODE_MODULE: + printf("NODE_MODULE:\n"); + if (tree->car->car == (node*)0) { + dump_prefix(tree, offset+1); + printf(":%s\n", mrb_sym2name(mrb, sym(tree->car->cdr))); + } + else if (tree->car->car == (node*)1) { + dump_prefix(tree, offset+1); + printf("::%s\n", mrb_sym2name(mrb, sym(tree->car->cdr))); + } + else { + mrb_parser_dump(mrb, tree->car->car, offset+1); + dump_prefix(tree, offset+1); + printf("::%s\n", mrb_sym2name(mrb, sym(tree->car->cdr))); + } + dump_prefix(tree, offset+1); + printf("body:\n"); + mrb_parser_dump(mrb, tree->cdr->car->cdr, offset+2); + break; + + case NODE_SCLASS: + printf("NODE_SCLASS:\n"); + mrb_parser_dump(mrb, tree->car, offset+1); + dump_prefix(tree, offset+1); + printf("body:\n"); + mrb_parser_dump(mrb, tree->cdr->car->cdr, offset+2); + break; + + case NODE_DEF: + printf("NODE_DEF:\n"); + dump_prefix(tree, offset+1); + printf("%s\n", mrb_sym2name(mrb, sym(tree->car))); + tree = tree->cdr; + { + node *n2 = tree->car; + mrb_bool first_lval = TRUE; + + if (n2 && (n2->car || n2->cdr)) { + dump_prefix(n2, offset+1); + printf("local variables:\n"); + dump_prefix(n2, offset+2); + while (n2) { + if (n2->car) { + if (!first_lval) printf(", "); + printf("%s", mrb_sym2name(mrb, sym(n2->car))); + first_lval = FALSE; + } + n2 = n2->cdr; + } + printf("\n"); + } + } + tree = tree->cdr; + if (tree->car) { + node *n = tree->car; + + if (n->car) { + dump_prefix(n, offset+1); + printf("mandatory args:\n"); + dump_recur(mrb, n->car, offset+2); + } + n = n->cdr; + if (n->car) { + dump_prefix(n, offset+1); + printf("optional args:\n"); + { + node *n2 = n->car; + + while (n2) { + dump_prefix(n2, offset+2); + printf("%s=", mrb_sym2name(mrb, sym(n2->car->car))); + mrb_parser_dump(mrb, n2->car->cdr, 0); + n2 = n2->cdr; + } + } + } + n = n->cdr; + if (n->car) { + dump_prefix(n, offset+1); + printf("rest=*%s\n", mrb_sym2name(mrb, sym(n->car))); + } + n = n->cdr; + if (n->car) { + dump_prefix(n, offset+1); + printf("post mandatory args:\n"); + dump_recur(mrb, n->car, offset+2); + } + if (n->cdr) { + dump_prefix(n, offset+1); + printf("blk=&%s\n", mrb_sym2name(mrb, sym(n->cdr))); + } + } + mrb_parser_dump(mrb, tree->cdr->car, offset+1); + break; + + case NODE_SDEF: + printf("NODE_SDEF:\n"); + mrb_parser_dump(mrb, tree->car, offset+1); + tree = tree->cdr; + dump_prefix(tree, offset+1); + printf(":%s\n", mrb_sym2name(mrb, sym(tree->car))); + tree = tree->cdr->cdr; + if (tree->car) { + node *n = tree->car; + + if (n->car) { + dump_prefix(n, offset+1); + printf("mandatory args:\n"); + dump_recur(mrb, n->car, offset+2); + } + n = n->cdr; + if (n->car) { + dump_prefix(n, offset+1); + printf("optional args:\n"); + { + node *n2 = n->car; + + while (n2) { + dump_prefix(n2, offset+2); + printf("%s=", mrb_sym2name(mrb, sym(n2->car->car))); + mrb_parser_dump(mrb, n2->car->cdr, 0); + n2 = n2->cdr; + } + } + } + n = n->cdr; + if (n->car) { + dump_prefix(n, offset+1); + printf("rest=*%s\n", mrb_sym2name(mrb, sym(n->car))); + } + n = n->cdr; + if (n->car) { + dump_prefix(n, offset+1); + printf("post mandatory args:\n"); + dump_recur(mrb, n->car, offset+2); + } + n = n->cdr; + if (n) { + dump_prefix(n, offset+1); + printf("blk=&%s\n", mrb_sym2name(mrb, sym(n))); + } + } + tree = tree->cdr; + mrb_parser_dump(mrb, tree->car, offset+1); + break; + + case NODE_POSTEXE: + printf("NODE_POSTEXE:\n"); + mrb_parser_dump(mrb, tree, offset+1); + break; + + case NODE_HEREDOC: + printf("NODE_HEREDOC (<<%s):\n", ((parser_heredoc_info*)tree)->term); + dump_recur(mrb, ((parser_heredoc_info*)tree)->doc, offset+1); + break; + + default: + printf("node type: %d (0x%x)\n", nodetype, (unsigned)nodetype); + break; + } +#endif +} diff --git a/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-compiler/mrbgem.rake b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-compiler/mrbgem.rake new file mode 100644 index 00000000..3bf6d6ae --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-compiler/mrbgem.rake @@ -0,0 +1,40 @@ +MRuby::Gem::Specification.new 'mruby-compiler' do |spec| + spec.license = 'MIT' + spec.author = 'mruby developers' + spec.summary = 'mruby compiler library' + + current_dir = spec.dir + current_build_dir = spec.build_dir + + lex_def = "#{current_dir}/core/lex.def" + core_objs = Dir.glob("#{current_dir}/core/*.c").map { |f| + next nil if build.cxx_exception_enabled? and f =~ /(codegen).c$/ + objfile(f.pathmap("#{current_build_dir}/core/%n")) + }.compact + + if build.cxx_exception_enabled? + core_objs << + build.compile_as_cxx("#{current_build_dir}/core/y.tab.c", "#{current_build_dir}/core/y.tab.cxx", + objfile("#{current_build_dir}/y.tab"), ["#{current_dir}/core"]) << + build.compile_as_cxx("#{current_dir}/core/codegen.c", "#{current_build_dir}/core/codegen.cxx") + else + core_objs << objfile("#{current_build_dir}/core/y.tab") + file objfile("#{current_build_dir}/core/y.tab") => "#{current_build_dir}/core/y.tab.c" do |t| + cc.run t.name, t.prerequisites.first, [], ["#{current_dir}/core"] + end + end + file objfile("#{current_build_dir}/core/y.tab") => lex_def + + # Parser + file "#{current_build_dir}/core/y.tab.c" => ["#{current_dir}/core/parse.y"] do |t| + yacc.run t.name, t.prerequisites.first + end + + # Lexical analyzer + file lex_def => "#{current_dir}/core/keywords" do |t| + gperf.run t.name, t.prerequisites.first + end + + file libfile("#{build.build_dir}/lib/libmruby_core") => core_objs + build.libmruby << core_objs +end diff --git a/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-enum-ext/mrbgem.rake b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-enum-ext/mrbgem.rake new file mode 100644 index 00000000..d5816b80 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-enum-ext/mrbgem.rake @@ -0,0 +1,5 @@ +MRuby::Gem::Specification.new('mruby-enum-ext') do |spec| + spec.license = 'MIT' + spec.author = 'mruby developers' + spec.summary = 'Enumerable module extension' +end diff --git a/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-enum-ext/mrblib/enum.rb b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-enum-ext/mrblib/enum.rb new file mode 100644 index 00000000..7741e515 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-enum-ext/mrblib/enum.rb @@ -0,0 +1,711 @@ +## +# Enumerable +# +module Enumerable + ## + # call-seq: + # enum.drop(n) -> array + # + # Drops first n elements from enum, and returns rest elements + # in an array. + # + # a = [1, 2, 3, 4, 5, 0] + # a.drop(3) #=> [4, 5, 0] + + def drop(n) + raise TypeError, "no implicit conversion of #{n.class} into Integer" unless n.respond_to?(:to_int) + raise ArgumentError, "attempt to drop negative size" if n < 0 + + n = n.to_int + ary = [] + self.each {|*val| n == 0 ? ary << val.__svalue : n -= 1 } + ary + end + + ## + # call-seq: + # enum.drop_while {|arr| block } -> array + # enum.drop_while -> an_enumerator + # + # Drops elements up to, but not including, the first element for + # which the block returns +nil+ or +false+ and returns an array + # containing the remaining elements. + # + # If no block is given, an enumerator is returned instead. + # + # a = [1, 2, 3, 4, 5, 0] + # a.drop_while {|i| i < 3 } #=> [3, 4, 5, 0] + + def drop_while(&block) + return to_enum :drop_while unless block + + ary, state = [], false + self.each do |*val| + state = true if !state and !block.call(*val) + ary << val.__svalue if state + end + ary + end + + ## + # call-seq: + # enum.take(n) -> array + # + # Returns first n elements from enum. + # + # a = [1, 2, 3, 4, 5, 0] + # a.take(3) #=> [1, 2, 3] + + def take(n) + raise TypeError, "no implicit conversion of #{n.class} into Integer" unless n.respond_to?(:to_int) + i = n.to_int + raise ArgumentError, "attempt to take negative size" if i < 0 + ary = [] + return ary if i == 0 + self.each do |*val| + ary << val.__svalue + i -= 1 + break if i == 0 + end + ary + end + + ## + # call-seq: + # enum.take_while {|arr| block } -> array + # enum.take_while -> an_enumerator + # + # Passes elements to the block until the block returns +nil+ or +false+, + # then stops iterating and returns an array of all prior elements. + # + # If no block is given, an enumerator is returned instead. + # + # a = [1, 2, 3, 4, 5, 0] + # a.take_while {|i| i < 3 } #=> [1, 2] + # + def take_while(&block) + return to_enum :take_while unless block + + ary = [] + self.each do |*val| + return ary unless block.call(*val) + ary << val.__svalue + end + ary + end + + ## + # Iterates the given block for each array of consecutive + # elements. + # + # @return [nil] + # + # @example + # (1..10).each_cons(3) {|a| p a} + # # outputs below + # [1, 2, 3] + # [2, 3, 4] + # [3, 4, 5] + # [4, 5, 6] + # [5, 6, 7] + # [6, 7, 8] + # [7, 8, 9] + # [8, 9, 10] + + def each_cons(n, &block) + raise TypeError, "no implicit conversion of #{n.class} into Integer" unless n.respond_to?(:to_int) + raise ArgumentError, "invalid size" if n <= 0 + + return to_enum(:each_cons,n) unless block + ary = [] + n = n.to_int + self.each do |*val| + ary.shift if ary.size == n + ary << val.__svalue + block.call(ary.dup) if ary.size == n + end + nil + end + + ## + # Iterates the given block for each slice of elements. + # + # @return [nil] + # + # @example + # (1..10).each_slice(3) {|a| p a} + # # outputs below + # [1, 2, 3] + # [4, 5, 6] + # [7, 8, 9] + # [10] + + def each_slice(n, &block) + raise TypeError, "no implicit conversion of #{n.class} into Integer" unless n.respond_to?(:to_int) + raise ArgumentError, "invalid slice size" if n <= 0 + + return to_enum(:each_slice,n) unless block + ary = [] + n = n.to_int + self.each do |*val| + ary << val.__svalue + if ary.size == n + block.call(ary) + ary = [] + end + end + block.call(ary) unless ary.empty? + nil + end + + ## + # call-seq: + # enum.group_by {| obj | block } -> a_hash + # enum.group_by -> an_enumerator + # + # Returns a hash, which keys are evaluated result from the + # block, and values are arrays of elements in enum + # corresponding to the key. + # + # (1..6).group_by {|i| i%3} #=> {0=>[3, 6], 1=>[1, 4], 2=>[2, 5]} + # + def group_by(&block) + return to_enum :group_by unless block + + h = {} + self.each do |*val| + key = block.call(*val) + sv = val.__svalue + h.key?(key) ? (h[key] << sv) : (h[key] = [sv]) + end + h + end + + ## + # call-seq: + # enum.sort_by { |obj| block } -> array + # enum.sort_by -> an_enumerator + # + # Sorts enum using a set of keys generated by mapping the + # values in enum through the given block. + # + # If no block is given, an enumerator is returned instead. + + def sort_by(&block) + return to_enum :sort_by unless block + + ary = [] + orig = [] + self.each_with_index{|e, i| + orig.push(e) + ary.push([block.call(e), i]) + } + if ary.size > 1 + __sort_sub__(ary, 0, ary.size - 1) do |a,b| + a <=> b + end + end + ary.collect{|e,i| orig[i]} + end + + NONE = Object.new + ## + # call-seq: + # enum.first -> obj or nil + # enum.first(n) -> an_array + # + # Returns the first element, or the first +n+ elements, of the enumerable. + # If the enumerable is empty, the first form returns nil, and the + # second form returns an empty array. + def first(*args) + case args.length + when 0 + self.each do |*val| + return val.__svalue + end + return nil + when 1 + n = args[0] + raise TypeError, "no implicit conversion of #{n.class} into Integer" unless n.respond_to?(:to_int) + i = n.to_int + raise ArgumentError, "attempt to take negative size" if i < 0 + ary = [] + return ary if i == 0 + self.each do |*val| + ary << val.__svalue + i -= 1 + break if i == 0 + end + ary + else + raise ArgumentError, "wrong number of arguments (given #{args.length}, expected 0..1)" + end + end + + ## + # call-seq: + # enum.count -> int + # enum.count(item) -> int + # enum.count { |obj| block } -> int + # + # Returns the number of items in +enum+ through enumeration. + # If an argument is given, the number of items in +enum+ that + # are equal to +item+ are counted. If a block is given, it + # counts the number of elements yielding a true value. + def count(v=NONE, &block) + count = 0 + if block + self.each do |*val| + count += 1 if block.call(*val) + end + else + if v == NONE + self.each { count += 1 } + else + self.each do |*val| + count += 1 if val.__svalue == v + end + end + end + count + end + + ## + # call-seq: + # enum.flat_map { |obj| block } -> array + # enum.collect_concat { |obj| block } -> array + # enum.flat_map -> an_enumerator + # enum.collect_concat -> an_enumerator + # + # Returns a new array with the concatenated results of running + # block once for every element in enum. + # + # If no block is given, an enumerator is returned instead. + # + # [1, 2, 3, 4].flat_map { |e| [e, -e] } #=> [1, -1, 2, -2, 3, -3, 4, -4] + # [[1, 2], [3, 4]].flat_map { |e| e + [100] } #=> [1, 2, 100, 3, 4, 100] + def flat_map(&block) + return to_enum :flat_map unless block + + ary = [] + self.each do |*e| + e2 = block.call(*e) + if e2.respond_to? :each + e2.each {|e3| ary.push(e3) } + else + ary.push(e2) + end + end + ary + end + alias collect_concat flat_map + + ## + # call-seq: + # enum.max_by {|obj| block } -> obj + # enum.max_by -> an_enumerator + # + # Returns the object in enum that gives the maximum + # value from the given block. + # + # If no block is given, an enumerator is returned instead. + # + # %w[albatross dog horse].max_by {|x| x.length } #=> "albatross" + + def max_by(&block) + return to_enum :max_by unless block + + first = true + max = nil + max_cmp = nil + + self.each do |*val| + if first + max = val.__svalue + max_cmp = block.call(*val) + first = false + else + if (cmp = block.call(*val)) > max_cmp + max = val.__svalue + max_cmp = cmp + end + end + end + max + end + + ## + # call-seq: + # enum.min_by {|obj| block } -> obj + # enum.min_by -> an_enumerator + # + # Returns the object in enum that gives the minimum + # value from the given block. + # + # If no block is given, an enumerator is returned instead. + # + # %w[albatross dog horse].min_by {|x| x.length } #=> "dog" + + def min_by(&block) + return to_enum :min_by unless block + + first = true + min = nil + min_cmp = nil + + self.each do |*val| + if first + min = val.__svalue + min_cmp = block.call(*val) + first = false + else + if (cmp = block.call(*val)) < min_cmp + min = val.__svalue + min_cmp = cmp + end + end + end + min + end + + ## + # call-seq: + # enum.minmax -> [min, max] + # enum.minmax { |a, b| block } -> [min, max] + # + # Returns two elements array which contains the minimum and the + # maximum value in the enumerable. The first form assumes all + # objects implement Comparable; the second uses the + # block to return a <=> b. + # + # a = %w(albatross dog horse) + # a.minmax #=> ["albatross", "horse"] + # a.minmax { |a, b| a.length <=> b.length } #=> ["dog", "albatross"] + + def minmax(&block) + max = nil + min = nil + first = true + + self.each do |*val| + if first + val = val.__svalue + max = val + min = val + first = false + else + val = val.__svalue + if block + max = val if block.call(val, max) > 0 + min = val if block.call(val, min) < 0 + else + max = val if (val <=> max) > 0 + min = val if (val <=> min) < 0 + end + end + end + [min, max] + end + + ## + # call-seq: + # enum.minmax_by { |obj| block } -> [min, max] + # enum.minmax_by -> an_enumerator + # + # Returns a two element array containing the objects in + # enum that correspond to the minimum and maximum values respectively + # from the given block. + # + # If no block is given, an enumerator is returned instead. + # + # %w(albatross dog horse).minmax_by { |x| x.length } #=> ["dog", "albatross"] + + def minmax_by(&block) + return to_enum :minmax_by unless block + + max = nil + max_cmp = nil + min = nil + min_cmp = nil + first = true + + self.each do |*val| + if first + max = min = val.__svalue + max_cmp = min_cmp = block.call(*val) + first = false + else + if (cmp = block.call(*val)) > max_cmp + max = val.__svalue + max_cmp = cmp + end + if (cmp = block.call(*val)) < min_cmp + min = val.__svalue + min_cmp = cmp + end + end + end + [min, max] + end + + ## + # call-seq: + # enum.none? [{ |obj| block }] -> true or false + # + # Passes each element of the collection to the given block. The method + # returns true if the block never returns true + # for all elements. If the block is not given, none? will return + # true only if none of the collection members is true. + # + # %w(ant bear cat).none? { |word| word.length == 5 } #=> true + # %w(ant bear cat).none? { |word| word.length >= 4 } #=> false + # [].none? #=> true + # [nil, false].none? #=> true + # [nil, true].none? #=> false + + def none?(&block) + if block + self.each do |*val| + return false if block.call(*val) + end + else + self.each do |*val| + return false if val.__svalue + end + end + true + end + + ## + # call-seq: + # enum.one? [{ |obj| block }] -> true or false + # + # Passes each element of the collection to the given block. The method + # returns true if the block returns true + # exactly once. If the block is not given, one? will return + # true only if exactly one of the collection members is + # true. + # + # %w(ant bear cat).one? { |word| word.length == 4 } #=> true + # %w(ant bear cat).one? { |word| word.length > 4 } #=> false + # %w(ant bear cat).one? { |word| word.length < 4 } #=> false + # [nil, true, 99].one? #=> false + # [nil, true, false].one? #=> true + # + + def one?(&block) + count = 0 + if block + self.each do |*val| + count += 1 if block.call(*val) + return false if count > 1 + end + else + self.each do |*val| + count += 1 if val.__svalue + return false if count > 1 + end + end + + count == 1 ? true : false + end + + ## + # call-seq: + # enum.each_with_object(obj) { |(*args), memo_obj| ... } -> obj + # enum.each_with_object(obj) -> an_enumerator + # + # Iterates the given block for each element with an arbitrary + # object given, and returns the initially given object. + # + # If no block is given, returns an enumerator. + # + # (1..10).each_with_object([]) { |i, a| a << i*2 } + # #=> [2, 4, 6, 8, 10, 12, 14, 16, 18, 20] + # + + def each_with_object(obj=nil, &block) + raise ArgumentError, "wrong number of arguments (0 for 1)" if obj.nil? + + return to_enum(:each_with_object, obj) unless block + + self.each {|*val| block.call(val.__svalue, obj) } + obj + end + + ## + # call-seq: + # enum.reverse_each { |item| block } -> enum + # enum.reverse_each -> an_enumerator + # + # Builds a temporary array and traverses that array in reverse order. + # + # If no block is given, an enumerator is returned instead. + # + # (1..3).reverse_each { |v| p v } + # + # produces: + # + # 3 + # 2 + # 1 + # + + def reverse_each(&block) + return to_enum :reverse_each unless block + + ary = self.to_a + i = ary.size - 1 + while i>=0 + block.call(ary[i]) + i -= 1 + end + self + end + + ## + # call-seq: + # enum.cycle(n=nil) { |obj| block } -> nil + # enum.cycle(n=nil) -> an_enumerator + # + # Calls block for each element of enum repeatedly _n_ + # times or forever if none or +nil+ is given. If a non-positive + # number is given or the collection is empty, does nothing. Returns + # +nil+ if the loop has finished without getting interrupted. + # + # Enumerable#cycle saves elements in an internal array so changes + # to enum after the first pass have no effect. + # + # If no block is given, an enumerator is returned instead. + # + # a = ["a", "b", "c"] + # a.cycle { |x| puts x } # print, a, b, c, a, b, c,.. forever. + # a.cycle(2) { |x| puts x } # print, a, b, c, a, b, c. + # + + def cycle(nv = nil, &block) + return to_enum(:cycle, nv) unless block + + n = nil + + if nv.nil? + n = -1 + else + unless nv.respond_to?(:to_int) + raise TypeError, "no implicit conversion of #{nv.class} into Integer" + end + n = nv.to_int + unless n.kind_of?(Integer) + raise TypeError, "no implicit conversion of #{nv.class} into Integer" + end + return nil if n <= 0 + end + + ary = [] + each do |*i| + ary.push(i) + yield(*i) + end + return nil if ary.empty? + + while n < 0 || 0 < (n -= 1) + ary.each do |i| + yield(*i) + end + end + + nil + end + + ## + # call-seq: + # enum.find_index(value) -> int or nil + # enum.find_index { |obj| block } -> int or nil + # enum.find_index -> an_enumerator + # + # Compares each entry in enum with value or passes + # to block. Returns the index for the first for which the + # evaluated value is non-false. If no object matches, returns + # nil + # + # If neither block nor argument is given, an enumerator is returned instead. + # + # (1..10).find_index { |i| i % 5 == 0 and i % 7 == 0 } #=> nil + # (1..100).find_index { |i| i % 5 == 0 and i % 7 == 0 } #=> 34 + # (1..100).find_index(50) #=> 49 + # + + def find_index(val=NONE, &block) + return to_enum(:find_index, val) if !block && val == NONE + + idx = 0 + if block + self.each do |*e| + return idx if block.call(*e) + idx += 1 + end + else + self.each do |*e| + return idx if e.__svalue == val + idx += 1 + end + end + nil + end + + ## + # call-seq: + # enum.zip(arg, ...) -> an_array_of_array + # + # Takes one element from enum and merges corresponding + # elements from each args. This generates a sequence of + # n-element arrays, where n is one more than the + # count of arguments. The length of the resulting sequence will be + # enum#size. If the size of any argument is less than + # enum#size, nil values are supplied. + # + + def zip(*arg) + ary = [] + arg = arg.map{|a|a.to_a} + i = 0 + self.each do |*val| + a = [] + a.push(val.__svalue) + idx = 0 + while idx < arg.size + a.push(arg[idx][i]) + idx += 1 + end + ary.push(a) + i += 1 + end + ary + end + + ## + # call-seq: + # enum.to_h -> hash + # + # Returns the result of interpreting enum as a list of + # [key, value] pairs. + # + # %i[hello world].each_with_index.to_h + # # => {:hello => 0, :world => 1} + # + + def to_h + h = {} + self.each do |*v| + v = v.__svalue + raise TypeError, "wrong element type #{v.class} (expected Array)" unless v.is_a? Array + raise ArgumentError, "element has wrong array length (expected 2, was #{v.size})" if v.size != 2 + h[v[0]] = v[1] + end + h + end + + def nil.to_h + {} + end +end diff --git a/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-enum-ext/test/enum.rb b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-enum-ext/test/enum.rb new file mode 100644 index 00000000..e772f85b --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-enum-ext/test/enum.rb @@ -0,0 +1,171 @@ +## +# Enumerable(Ext) Test + +assert("Enumerable#drop") do + a = [1, 2, 3, 4, 5, 0] + + assert_equal [4, 5, 0], a.drop(3) + assert_equal [], a.drop(6) +end + +assert("Enumerable#drop_while") do + a = [1, 2, 3, 4, 5, 0] + assert_equal [3, 4, 5, 0], a.drop_while {|i| i < 3 } +end + +assert("Enumerable#take") do + a = [1, 2, 3, 4, 5, 0] + assert_equal [1, 2, 3], a.take(3) +end + +assert("Enumerable#take_while") do + a = [1, 2, 3, 4, 5, 0] + assert_equal [1, 2], a.take_while {|i| i < 3} +end + +assert("Enumerable#each_cons") do + a = [] + b = (1..5).each_cons(3){|e| a << e} + assert_equal [[1, 2, 3], [2, 3, 4], [3, 4, 5]], a + assert_equal nil, b +end + +assert("Enumerable#each_slice") do + a = [] + b = (1..10).each_slice(3){|e| a << e} + assert_equal [[1, 2, 3], [4, 5, 6], [7, 8, 9], [10]], a + assert_equal nil, b +end + +assert("Enumerable#group_by") do + r = (1..6).group_by {|i| i % 3 } + assert_equal [3, 6], r[0] + assert_equal [1, 4], r[1] + assert_equal [2, 5], r[2] +end + +assert("Enumerable#sort_by") do + assert_equal ["car", "train", "bicycle"], %w{car bicycle train}.sort_by {|e| e.length} +end + +assert("Enumerable#first") do + a = Object.new + a.extend Enumerable + def a.each + yield 1 + yield 2 + yield 3 + end + assert_equal 1, a.first + assert_equal [1, 2], a.first(2) + assert_equal [1, 2, 3], a.first(10) + a = Object.new + a.extend Enumerable + def a.each + end + assert_nil a.first +end + +assert("Enumerable#count") do + a = [1, 2, 4, 2] + assert_equal 4, a.count + assert_equal 2, a.count(2) + assert_equal 3, a.count{|x| x % 2 == 0} +end + +assert("Enumerable#flat_map") do + assert_equal [1, 2, 3, 4], [1, 2, 3, 4].flat_map { |e| e } + assert_equal [1, -1, 2, -2, 3, -3, 4, -4], [1, 2, 3, 4].flat_map { |e| [e, -e] } + assert_equal [1, 2, 100, 3, 4, 100], [[1, 2], [3, 4]].flat_map { |e| e + [100] } +end + +assert("Enumerable#max_by") do + assert_equal "albatross", %w[albatross dog horse].max_by { |x| x.length } +end + +assert("Enumerable#min_by") do + assert_equal "dog", %w[albatross dog horse].min_by { |x| x.length } +end + +assert("Enumerable#minmax") do + a = %w(albatross dog horse) + assert_equal ["albatross", "horse"], a.minmax + assert_equal ["dog", "albatross"], a.minmax { |a, b| a.length <=> b.length } +end + +assert("Enumerable#minmax_by") do + assert_equal ["dog", "albatross"], %w(albatross dog horse).minmax_by { |x| x.length } +end + +assert("Enumerable#none?") do + assert_true %w(ant bear cat).none? { |word| word.length == 5 } + assert_false %w(ant bear cat).none? { |word| word.length >= 4 } + assert_true [].none? + assert_true [nil, false].none? + assert_false [nil, true].none? +end + +assert("Enumerable#one?") do + assert_true %w(ant bear cat).one? { |word| word.length == 4 } + assert_false %w(ant bear cat).one? { |word| word.length > 4 } + assert_false %w(ant bear cat).one? { |word| word.length < 4 } + assert_false [nil, true, 99].one? + assert_true [nil, true, false].one? +end + +assert("Enumerable#each_with_object") do + assert_true [2, 4, 6, 8, 10, 12, 14, 16, 18, 20], (1..10).each_with_object([]) { |i, a| a << i*2 } + assert_raise(ArgumentError) { (1..10).each_with_object() { |i, a| a << i*2 } } +end + +assert("Enumerable#reverse_each") do + r = (1..3) + a = [] + assert_equal (1..3), r.reverse_each { |v| a << v } + assert_equal [3, 2, 1], a +end + +assert("Enumerable#cycle") do + a = [] + ["a", "b", "c"].cycle(2) { |v| a << v } + assert_equal ["a", "b", "c", "a", "b", "c"], a + assert_raise(TypeError) { ["a", "b", "c"].cycle("a") { |v| a << v } } + + empty = Class.new do + include Enumerable + def each + end + end + assert_nil empty.new.cycle { break :nope } +end + +assert("Enumerable#find_index") do + assert_nil (1..10).find_index { |i| i % 5 == 0 and i % 7 == 0 } + assert_equal 34, (1..100).find_index { |i| i % 5 == 0 and i % 7 == 0 } + assert_equal 49 ,(1..100).find_index(50) +end + +assert("Enumerable#zip") do + a = [ 4, 5, 6 ] + b = [ 7, 8, 9 ] + assert_equal [[4, 7], [5, 8], [6, 9]], a.zip(b) + assert_equal [[1, 4, 7], [2, 5, 8], [3, 6, 9]], [1, 2, 3].zip(a, b) + assert_equal [[1, 4, 7], [2, 5, 8]], [1, 2].zip(a, b) + assert_equal [[4, 1, 8], [5, 2, nil], [6, nil, nil]], a.zip([1, 2], [8]) +end + +assert("Enumerable#to_h") do + c = Class.new { + include Enumerable + def each + yield [1,2] + yield [3,4] + end + } + h0 = {1=>2, 3=>4} + h = c.new.to_h + assert_equal Hash, h.class + assert_equal h0, h + # mruby-enum-ext also provides nil.to_h + assert_equal Hash.new, nil.to_h +end diff --git a/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-enum-lazy/mrbgem.rake b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-enum-lazy/mrbgem.rake new file mode 100644 index 00000000..682134c4 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-enum-lazy/mrbgem.rake @@ -0,0 +1,7 @@ +MRuby::Gem::Specification.new('mruby-enum-lazy') do |spec| + spec.license = 'MIT' + spec.author = 'mruby developers' + spec.summary = 'Enumerator::Lazy class' + spec.add_dependency('mruby-enumerator', :core => 'mruby-enumerator') + spec.add_dependency('mruby-enum-ext', :core => 'mruby-enum-ext') +end diff --git a/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-enum-lazy/mrblib/lazy.rb b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-enum-lazy/mrblib/lazy.rb new file mode 100644 index 00000000..c98681ed --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-enum-lazy/mrblib/lazy.rb @@ -0,0 +1,163 @@ +module Enumerable + + # = Enumerable#lazy implementation + # + # Enumerable#lazy returns an instance of Enumerator::Lazy. + # You can use it just like as normal Enumerable object, + # except these methods act as 'lazy': + # + # - map collect + # - select find_all + # - reject + # - grep + # - drop + # - drop_while + # - take_while + # - flat_map collect_concat + # - zip + def lazy + Enumerator::Lazy.new(self) + end +end + +class Enumerator + # == Acknowledgements + # + # Based on https://github.com/yhara/enumerable-lazy + # Inspired by https://github.com/antimon2/enumerable_lz + # http://jp.rubyist.net/magazine/?0034-Enumerable_lz (ja) + class Lazy < Enumerator + def initialize(obj, &block) + super(){|yielder| + begin + obj.each{|x| + if block + block.call(yielder, x) + else + yielder << x + end + } + rescue StopIteration + end + } + end + + def to_enum(meth=:each, *args, &block) + unless self.respond_to?(meth) + raise NoMethodError, "undefined method #{meth}" + end + lz = Lazy.new(self, &block) + lz.obj = self + lz.meth = meth + lz.args = args + lz + end + alias enum_for to_enum + + def map(&block) + Lazy.new(self){|yielder, val| + yielder << block.call(val) + } + end + alias collect map + + def select(&block) + Lazy.new(self){|yielder, val| + if block.call(val) + yielder << val + end + } + end + alias find_all select + + def reject(&block) + Lazy.new(self){|yielder, val| + unless block.call(val) + yielder << val + end + } + end + + def grep(pattern) + Lazy.new(self){|yielder, val| + if pattern === val + yielder << val + end + } + end + + def drop(n) + dropped = 0 + Lazy.new(self){|yielder, val| + if dropped < n + dropped += 1 + else + yielder << val + end + } + end + + def drop_while(&block) + dropping = true + Lazy.new(self){|yielder, val| + if dropping + if not block.call(val) + yielder << val + dropping = false + end + else + yielder << val + end + } + end + + def take(n) + if n == 0 + return Lazy.new(self){raise StopIteration} + end + taken = 0 + Lazy.new(self){|yielder, val| + yielder << val + taken += 1 + if taken >= n + raise StopIteration + end + } + end + + def take_while(&block) + Lazy.new(self){|yielder, val| + if block.call(val) + yielder << val + else + raise StopIteration + end + } + end + + def flat_map(&block) + Lazy.new(self){|yielder, val| + ary = block.call(val) + # TODO: check ary is an Array + ary.each{|x| + yielder << x + } + } + end + alias collect_concat flat_map + + def zip(*args, &block) + enums = [self] + args + Lazy.new(self){|yielder, val| + ary = enums.map{|e| e.next} + if block + yielder << block.call(ary) + else + yielder << ary + end + } + end + + alias force to_a + end +end diff --git a/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-enum-lazy/test/lazy.rb b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-enum-lazy/test/lazy.rb new file mode 100644 index 00000000..940d070e --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-enum-lazy/test/lazy.rb @@ -0,0 +1,53 @@ +assert("Enumerator::Lazy") do + a = [1, 2] + assert_equal Enumerator::Lazy, a.lazy.class +end + +assert("Enumerator::Lazy laziness") do + a = Object.new + def a.each + return to_enum :each unless block_given? + self.b << 10 + yield 1 + self.b << 20 + yield 2 + self.b << 30 + yield 3 + self.b << 40 + yield 4 + self.b << 50 + yield 5 + end + def a.b(b=nil) + @b = b if b + @b + end + + a.b([]) + assert_equal [1,2], a.each.lazy.take(2).force + assert_equal [10,20], a.b + + a.b([]) + assert_equal [2,4], a.each.lazy.select{|x|x%2==0}.take(2).force + assert_equal [10,20,30,40], a.b + + a.b([]) + assert_equal [1], a.each.lazy.take_while{|x|x<2}.take(1).force + assert_equal [10], a.b + + a.b([]) + assert_equal [1], a.each.lazy.take_while{|x|x<2}.take(4).force + assert_equal [10,20], a.b +end + +assert("Enumrator::Lazy#to_enum") do + lazy_enum = (0..Float::INFINITY).lazy.to_enum(:each_slice, 2) + assert_kind_of Enumerator::Lazy, lazy_enum + assert_equal [0*1, 2*3, 4*5, 6*7], lazy_enum.map { |a| a.first * a.last }.first(4) +end + +assert("Enumerator::Lazy#zip with cycle") do + e1 = [1, 2, 3].cycle + e2 = [:a, :b].cycle + assert_equal [[1,:a],[2,:b],[3,:a]], e1.lazy.zip(e2).first(3) +end diff --git a/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-enumerator/mrbgem.rake b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-enumerator/mrbgem.rake new file mode 100644 index 00000000..8757a15e --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-enumerator/mrbgem.rake @@ -0,0 +1,7 @@ +MRuby::Gem::Specification.new('mruby-enumerator') do |spec| + spec.license = 'MIT' + spec.author = 'mruby developers' + spec.add_dependency('mruby-fiber', :core => 'mruby-fiber') + spec.add_dependency 'mruby-enum-ext', :core => 'mruby-enum-ext' + spec.summary = 'Enumerator class' +end diff --git a/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-enumerator/mrblib/enumerator.rb b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-enumerator/mrblib/enumerator.rb new file mode 100644 index 00000000..1e77af36 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-enumerator/mrblib/enumerator.rb @@ -0,0 +1,645 @@ +## +# enumerator.rb Enumerator class +# See Copyright Notice in mruby.h + +## +# A class which allows both internal and external iteration. +# +# An Enumerator can be created by the following methods. +# - {Kernel#to_enum} +# - {Kernel#enum_for} +# - {Enumerator#initialize Enumerator.new} +# +# Most methods have two forms: a block form where the contents +# are evaluated for each item in the enumeration, and a non-block form +# which returns a new Enumerator wrapping the iteration. +# +# enumerator = %w(one two three).each +# puts enumerator.class # => Enumerator +# +# enumerator.each_with_object("foo") do |item, obj| +# puts "#{obj}: #{item}" +# end +# +# # foo: one +# # foo: two +# # foo: three +# +# enum_with_obj = enumerator.each_with_object("foo") +# puts enum_with_obj.class # => Enumerator +# +# enum_with_obj.each do |item, obj| +# puts "#{obj}: #{item}" +# end +# +# # foo: one +# # foo: two +# # foo: three +# +# This allows you to chain Enumerators together. For example, you +# can map a list's elements to strings containing the index +# and the element as a string via: +# +# puts %w[foo bar baz].map.with_index { |w, i| "#{i}:#{w}" } +# # => ["0:foo", "1:bar", "2:baz"] +# +# An Enumerator can also be used as an external iterator. +# For example, Enumerator#next returns the next value of the iterator +# or raises StopIteration if the Enumerator is at the end. +# +# e = [1,2,3].each # returns an enumerator object. +# puts e.next # => 1 +# puts e.next # => 2 +# puts e.next # => 3 +# puts e.next # raises StopIteration +# +# You can use this to implement an internal iterator as follows: +# +# def ext_each(e) +# while true +# begin +# vs = e.next_values +# rescue StopIteration +# return $!.result +# end +# y = yield(*vs) +# e.feed y +# end +# end +# +# o = Object.new +# +# def o.each +# puts yield +# puts yield(1) +# puts yield(1, 2) +# 3 +# end +# +# # use o.each as an internal iterator directly. +# puts o.each {|*x| puts x; [:b, *x] } +# # => [], [:b], [1], [:b, 1], [1, 2], [:b, 1, 2], 3 +# +# # convert o.each to an external iterator for +# # implementing an internal iterator. +# puts ext_each(o.to_enum) {|*x| puts x; [:b, *x] } +# # => [], [:b], [1], [:b, 1], [1, 2], [:b, 1, 2], 3 +# +class Enumerator + include Enumerable + + ## + # @overload initialize(size = nil, &block) + # @overload initialize(obj, method = :each, *args) + # + # Creates a new Enumerator object, which can be used as an + # Enumerable. + # + # In the first form, iteration is defined by the given block, in + # which a "yielder" object, given as block parameter, can be used to + # yield a value by calling the +yield+ method (aliased as +<<+): + # + # fib = Enumerator.new do |y| + # a = b = 1 + # loop do + # y << a + # a, b = b, a + b + # end + # end + # + # p fib.take(10) # => [1, 1, 2, 3, 5, 8, 13, 21, 34, 55] + # + def initialize(obj=nil, meth=:each, *args, &block) + if block + obj = Generator.new(&block) + else + raise ArgumentError unless obj + end + if @obj and !self.respond_to?(meth) + raise NoMethodError, "undefined method #{meth}" + end + + @obj = obj + @meth = meth + @args = args.dup + @fib = nil + @dst = nil + @lookahead = nil + @feedvalue = nil + @stop_exc = false + end + attr_accessor :obj, :meth, :args, :fib + private :obj, :meth, :args, :fib + + def initialize_copy(obj) + raise TypeError, "can't copy type #{obj.class}" unless obj.kind_of? Enumerator + raise TypeError, "can't copy execution context" if obj.fib + @obj = obj.obj + @meth = obj.meth + @args = obj.args + @fib = nil + @lookahead = nil + @feedvalue = nil + self + end + + ## + # call-seq: + # e.with_index(offset = 0) {|(*args), idx| ... } + # e.with_index(offset = 0) + # + # Iterates the given block for each element with an index, which + # starts from +offset+. If no block is given, returns a new Enumerator + # that includes the index, starting from +offset+ + # + # +offset+:: the starting index to use + # + def with_index(offset=0, &block) + return to_enum :with_index, offset unless block + + offset = if offset.nil? + 0 + elsif offset.respond_to?(:to_int) + offset.to_int + else + raise TypeError, "no implicit conversion of #{offset.class} into Integer" + end + + n = offset - 1 + enumerator_block_call do |*i| + n += 1 + block.call i.__svalue, n + end + end + + ## + # call-seq: + # e.each_with_index {|(*args), idx| ... } + # e.each_with_index + # + # Same as Enumerator#with_index(0), i.e. there is no starting offset. + # + # If no block is given, a new Enumerator is returned that includes the index. + # + def each_with_index(&block) + with_index(0, &block) + end + + ## + # call-seq: + # e.each_with_object(obj) {|(*args), obj| ... } + # e.each_with_object(obj) + # e.with_object(obj) {|(*args), obj| ... } + # e.with_object(obj) + # + # Iterates the given block for each element with an arbitrary object, +obj+, + # and returns +obj+ + # + # If no block is given, returns a new Enumerator. + # + # @example + # to_three = Enumerator.new do |y| + # 3.times do |x| + # y << x + # end + # end + # + # to_three_with_string = to_three.with_object("foo") + # to_three_with_string.each do |x,string| + # puts "#{string}: #{x}" + # end + # + # # => foo:0 + # # => foo:1 + # # => foo:2 + # + def with_object(object, &block) + return to_enum(:with_object, object) unless block + + enumerator_block_call do |i| + block.call [i,object] + end + object + end + + def inspect + return "#<#{self.class}: uninitialized>" unless @obj + + if @args && @args.size > 0 + args = @args.join(", ") + "#<#{self.class}: #{@obj}:#{@meth}(#{args})>" + else + "#<#{self.class}: #{@obj}:#{@meth}>" + end + end + + ## + # call-seq: + # enum.each { |elm| block } -> obj + # enum.each -> enum + # enum.each(*appending_args) { |elm| block } -> obj + # enum.each(*appending_args) -> an_enumerator + # + # Iterates over the block according to how this Enumerator was constructed. + # If no block and no arguments are given, returns self. + # + # === Examples + # + # "Hello, world!".scan(/\w+/) #=> ["Hello", "world"] + # "Hello, world!".to_enum(:scan, /\w+/).to_a #=> ["Hello", "world"] + # "Hello, world!".to_enum(:scan).each(/\w+/).to_a #=> ["Hello", "world"] + # + # obj = Object.new + # + # def obj.each_arg(a, b=:b, *rest) + # yield a + # yield b + # yield rest + # :method_returned + # end + # + # enum = obj.to_enum :each_arg, :a, :x + # + # enum.each.to_a #=> [:a, :x, []] + # enum.each.equal?(enum) #=> true + # enum.each { |elm| elm } #=> :method_returned + # + # enum.each(:y, :z).to_a #=> [:a, :x, [:y, :z]] + # enum.each(:y, :z).equal?(enum) #=> false + # enum.each(:y, :z) { |elm| elm } #=> :method_returned + # + def each(*argv, &block) + obj = self + if 0 < argv.length + obj = self.dup + args = obj.args + if !args.empty? + args = args.dup + args.concat argv + else + args = argv.dup + end + obj.args = args + end + return obj unless block + enumerator_block_call(&block) + end + + def enumerator_block_call(&block) + @obj.__send__ @meth, *@args, &block + end + private :enumerator_block_call + + ## + # call-seq: + # e.next -> object + # + # Returns the next object in the enumerator, and move the internal position + # forward. When the position reached at the end, StopIteration is raised. + # + # === Example + # + # a = [1,2,3] + # e = a.to_enum + # p e.next #=> 1 + # p e.next #=> 2 + # p e.next #=> 3 + # p e.next #raises StopIteration + # + # Note that enumeration sequence by +next+ does not affect other non-external + # enumeration methods, unless the underlying iteration methods itself has + # side-effect + # + def next + next_values.__svalue + end + + ## + # call-seq: + # e.next_values -> array + # + # Returns the next object as an array in the enumerator, and move the + # internal position forward. When the position reached at the end, + # StopIteration is raised. + # + # This method can be used to distinguish yield and yield + # nil. + # + # === Example + # + # o = Object.new + # def o.each + # yield + # yield 1 + # yield 1, 2 + # yield nil + # yield [1, 2] + # end + # e = o.to_enum + # p e.next_values + # p e.next_values + # p e.next_values + # p e.next_values + # p e.next_values + # e = o.to_enum + # p e.next + # p e.next + # p e.next + # p e.next + # p e.next + # + # ## yield args next_values next + # # yield [] nil + # # yield 1 [1] 1 + # # yield 1, 2 [1, 2] [1, 2] + # # yield nil [nil] nil + # # yield [1, 2] [[1, 2]] [1, 2] + # + # Note that +next_values+ does not affect other non-external enumeration + # methods unless underlying iteration method itself has side-effect + # + def next_values + if @lookahead + vs = @lookahead + @lookahead = nil + return vs + end + raise @stop_exc if @stop_exc + + curr = Fiber.current + + if !@fib || !@fib.alive? + @dst = curr + @fib = Fiber.new do + result = each do |*args| + feedvalue = nil + Fiber.yield args + if @feedvalue + feedvalue = @feedvalue + @feedvalue = nil + end + feedvalue + end + @stop_exc = StopIteration.new "iteration reached an end" + @stop_exc.result = result + Fiber.yield nil + end + @lookahead = nil + end + + vs = @fib.resume curr + if @stop_exc + @fib = nil + @dst = nil + @lookahead = nil + @feedvalue = nil + raise @stop_exc + end + vs + end + + ## + # call-seq: + # e.peek -> object + # + # Returns the next object in the enumerator, but doesn't move the internal + # position forward. If the position is already at the end, StopIteration + # is raised. + # + # === Example + # + # a = [1,2,3] + # e = a.to_enum + # p e.next #=> 1 + # p e.peek #=> 2 + # p e.peek #=> 2 + # p e.peek #=> 2 + # p e.next #=> 2 + # p e.next #=> 3 + # p e.next #raises StopIteration + # + def peek + peek_values.__svalue + end + + ## + # call-seq: + # e.peek_values -> array + # + # Returns the next object as an array, similar to Enumerator#next_values, but + # doesn't move the internal position forward. If the position is already at + # the end, StopIteration is raised. + # + # === Example + # + # o = Object.new + # def o.each + # yield + # yield 1 + # yield 1, 2 + # end + # e = o.to_enum + # p e.peek_values #=> [] + # e.next + # p e.peek_values #=> [1] + # p e.peek_values #=> [1] + # e.next + # p e.peek_values #=> [1, 2] + # e.next + # p e.peek_values # raises StopIteration + # + def peek_values + if @lookahead.nil? + @lookahead = next_values + end + @lookahead.dup + end + + ## + # call-seq: + # e.rewind -> e + # + # Rewinds the enumeration sequence to the beginning. + # + # If the enclosed object responds to a "rewind" method, it is called. + # + def rewind + @obj.rewind if @obj.respond_to? :rewind + @fib = nil + @dst = nil + @lookahead = nil + @feedvalue = nil + @stop_exc = false + self + end + + ## + # call-seq: + # e.feed obj -> nil + # + # Sets the value to be returned by the next yield inside +e+. + # + # If the value is not set, the yield returns nil. + # + # This value is cleared after being yielded. + # + # # Array#map passes the array's elements to "yield" and collects the + # # results of "yield" as an array. + # # Following example shows that "next" returns the passed elements and + # # values passed to "feed" are collected as an array which can be + # # obtained by StopIteration#result. + # e = [1,2,3].map + # p e.next #=> 1 + # e.feed "a" + # p e.next #=> 2 + # e.feed "b" + # p e.next #=> 3 + # e.feed "c" + # begin + # e.next + # rescue StopIteration + # p $!.result #=> ["a", "b", "c"] + # end + # + # o = Object.new + # def o.each + # x = yield # (2) blocks + # p x # (5) => "foo" + # x = yield # (6) blocks + # p x # (8) => nil + # x = yield # (9) blocks + # p x # not reached w/o another e.next + # end + # + # e = o.to_enum + # e.next # (1) + # e.feed "foo" # (3) + # e.next # (4) + # e.next # (7) + # # (10) + # + def feed(value) + raise TypeError, "feed value already set" if @feedvalue + @feedvalue = value + nil + end + + # just for internal + class Generator + include Enumerable + def initialize(&block) + raise TypeError, "wrong argument type #{self.class} (expected Proc)" unless block.kind_of? Proc + + @proc = block + end + + def each(*args, &block) + args.unshift Yielder.new(&block) + @proc.call(*args) + end + end + + # just for internal + class Yielder + def initialize(&block) + raise LocalJumpError, "no block given" unless block + + @proc = block + end + + def yield(*args) + @proc.call(*args) + end + + def << *args + self.yield(*args) + self + end + end +end + +module Kernel + ## + # call-seq: + # obj.to_enum(method = :each, *args) -> enum + # obj.enum_for(method = :each, *args) -> enum + # obj.to_enum(method = :each, *args) {|*args| block} -> enum + # obj.enum_for(method = :each, *args){|*args| block} -> enum + # + # Creates a new Enumerator which will enumerate by calling +method+ on + # +obj+, passing +args+ if any. + # + # If a block is given, it will be used to calculate the size of + # the enumerator without the need to iterate it (see Enumerator#size). + # + # === Examples + # + # str = "xyz" + # + # enum = str.enum_for(:each_byte) + # enum.each { |b| puts b } + # # => 120 + # # => 121 + # # => 122 + # + # # protect an array from being modified by some_method + # a = [1, 2, 3] + # some_method(a.to_enum) + # + # It is typical to call to_enum when defining methods for + # a generic Enumerable, in case no block is passed. + # + # Here is such an example, with parameter passing and a sizing block: + # + # module Enumerable + # # a generic method to repeat the values of any enumerable + # def repeat(n) + # raise ArgumentError, "#{n} is negative!" if n < 0 + # unless block_given? + # return to_enum(__method__, n) do # __method__ is :repeat here + # sz = size # Call size and multiply by n... + # sz * n if sz # but return nil if size itself is nil + # end + # end + # each do |*val| + # n.times { yield *val } + # end + # end + # end + # + # %i[hello world].repeat(2) { |w| puts w } + # # => Prints 'hello', 'hello', 'world', 'world' + # enum = (1..14).repeat(3) + # # => returns an Enumerator when called without a block + # enum.first(4) # => [1, 1, 1, 2] + # + def to_enum(meth=:each, *args) + Enumerator.new self, meth, *args + end + alias enum_for to_enum +end + +module Enumerable + # use Enumerator to use infinite sequence + def zip(*arg) + ary = [] + arg = arg.map{|a|a.each} + i = 0 + self.each do |*val| + a = [] + a.push(val.__svalue) + idx = 0 + while idx < arg.size + begin + a.push(arg[idx].next) + rescue StopIteration + a.push(nil) + end + idx += 1 + end + ary.push(a) + i += 1 + end + ary + end +end diff --git a/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-enumerator/test/enumerator.rb b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-enumerator/test/enumerator.rb new file mode 100644 index 00000000..763cd36e --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-enumerator/test/enumerator.rb @@ -0,0 +1,546 @@ +@obj = Object.new +class << @obj + include Enumerable + def foo *a + a.each { |x| yield x } + end +end + +assert 'Enumerator' do + assert_equal Class, Enumerator.class +end + +assert 'Enumerator' do + assert_equal Object, Enumerator.superclass +end + +assert 'Enumerator.new' do + assert_equal [0,1,2], 3.times.map{|i| i}.sort + assert_equal [:x,:y,:z], [:x,:y,:z].each.map{|i| i}.sort + assert_equal [[:x,1],[:y,2]], {x:1, y:2}.each.map{|i| i}.sort + assert_equal [1,2,3], @obj.to_enum(:foo, 1,2,3).to_a + assert_equal [1,2,3], Enumerator.new(@obj, :foo, 1,2,3).to_a + assert_equal [1,2,3], Enumerator.new { |y| i = 0; loop { y << (i += 1) } }.take(3) + assert_raise(ArgumentError) { Enumerator.new } + enum = @obj.to_enum + assert_raise(NoMethodError) { enum.each {} } + + # examples + fib = Enumerator.new do |y| + a = b = 1 + loop do + y << a + a, b = b, a + b + end + end + assert_equal fib.take(10), [1,1,2,3,5,8,13,21,34,55] +end + +assert 'Enumerator#initialize_copy' do + assert_equal [1, 2, 3], @obj.to_enum(:foo, 1, 2, 3).dup.to_a + e = @obj.to_enum :foo, 1, 2, 3 + assert_nothing_raised { assert_equal(1, e.next) } + assert_raise(TypeError) { e.dup } + + e = Enumerator.new { |y| i = 0; loop { y << (i += 1) } }.dup + assert_nothing_raised { assert_equal(1, e.next) } + assert_raise(TypeError) { e.dup } +end + +assert 'Enumerator#with_index' do + assert_equal([[1,0],[2,1],[3,2]], @obj.to_enum(:foo, 1, 2, 3).with_index.to_a) + assert_equal([[1,5],[2,6],[3,7]], @obj.to_enum(:foo, 1, 2, 3).with_index(5).to_a) + a = [] + @obj.to_enum(:foo, 1, 2, 3).with_index(10).with_index(20) { |*i| a << i } + assert_equal [[[1, 10], 20], [[2, 11], 21], [[3, 12], 22]], a +end + +assert 'Enumerator#with_index nonnum offset' do + s = Object.new + def s.to_int; 1 end + assert_equal([[1,1],[2,2],[3,3]], @obj.to_enum(:foo, 1, 2, 3).with_index(s).to_a) +end + +assert 'Enumerator#with_index string offset' do + assert_raise(TypeError){ @obj.to_enum(:foo, 1, 2, 3).with_index('1').to_a } +end + +assert 'Enumerator#each_with_index' do + assert_equal([[1,0],[2,1],[3,2]], @obj.to_enum(:foo, 1, 2, 3).each_with_index.to_a) + a = [] + @obj.to_enum(:foo, 1, 2, 3).each_with_index {|*i| a << i} + assert_equal([[1, 0], [2, 1], [3, 2]], a) +end + +assert 'Enumerator#with_object' do + obj = [0, 1] + ret = (1..10).each.with_object(obj) {|i, memo| + memo[0] += i + memo[1] *= i + } + assert_true(obj.equal?(ret)) + assert_equal([55, 3628800], ret) +end + +assert 'Enumerator#with_object arguments' do + to_three = Enumerator.new do |y| + 3.times do |x| + y << x + end + end + + a = [] + to_three_with_string = to_three.with_object("foo") + to_three_with_string.each do |x,string| + a << "#{string}:#{x}" + end + assert_equal ["foo:0","foo:1","foo:2"], a +end + +assert 'Enumerator#inspect' do + e = (0..10).each + assert_equal("#", e.inspect) + e = Enumerator.new("FooObject", :foo, 1) + assert_equal("#", e.inspect) + e = Enumerator.new("FooObject", :foo, 1, 2, 3) + assert_equal("#", e.inspect) +end + +assert 'Enumerator#each' do + o = Object.new + def o.each(ary) + ary << 1 + yield + end + ary = [] + e = o.to_enum.each(ary) + e.next + assert_equal([1], ary) +end + +assert 'Enumerator#each arguments' do + obj = Object.new + + def obj.each_arg(a, b=:b, *rest) + yield a + yield b + yield rest + :method_returned + end + + enum = obj.to_enum :each_arg, :a, :x + + assert_equal [:a, :x, []], enum.each.to_a + assert_true enum.each.equal?(enum) + assert_equal :method_returned, enum.each { |elm| elm } + + assert_equal [:a, :x, [:y, :z]], enum.each(:y, :z).to_a + assert_false enum.each(:y, :z).equal?(enum) + assert_equal :method_returned, enum.each(:y, :z) { |elm| elm } +end + +assert 'Enumerator#next' do + e = 3.times + 3.times { |i| + assert_equal i, e.next + } + assert_raise(StopIteration) { e.next } +end + +assert 'Enumerator#next_values' do + o = Object.new + def o.each + yield + yield 1 + yield 1, 2 + end + e = o.to_enum + assert_equal nil, e.next + assert_equal 1, e.next + assert_equal [1,2], e.next + e = o.to_enum + assert_equal [], e.next_values + assert_equal [1], e.next_values + assert_equal [1,2], e.next_values +end + +assert 'Enumerator#peek' do + a = [1] + e = a.each + assert_equal 1, e.peek + assert_equal 1, e.peek + assert_equal 1, e.next + assert_raise(StopIteration) { e.peek } + assert_raise(StopIteration) { e.peek } +end + +assert 'Enumerator#peek modify' do + o = Object.new + def o.each + yield 1,2 + end + e = o.to_enum + a = e.peek + a << 3 + assert_equal([1,2], e.peek) +end + +assert 'Enumerator#peek_values' do + o = Object.new + def o.each + yield + yield 1 + yield 1, 2 + end + e = o.to_enum + assert_equal nil, e.peek + assert_equal nil, e.next + assert_equal 1, e.peek + assert_equal 1, e.next + assert_equal [1,2], e.peek + assert_equal [1,2], e.next + e = o.to_enum + assert_equal [], e.peek_values + assert_equal [], e.next_values + assert_equal [1], e.peek_values + assert_equal [1], e.next_values + assert_equal [1,2], e.peek_values + assert_equal [1,2], e.next_values + e = o.to_enum + assert_equal [], e.peek_values + assert_equal nil, e.next + assert_equal [1], e.peek_values + assert_equal 1, e.next + assert_equal [1,2], e.peek_values + assert_equal [1,2], e.next + e = o.to_enum + assert_equal nil, e.peek + assert_equal [], e.next_values + assert_equal 1, e.peek + assert_equal [1], e.next_values + assert_equal [1,2], e.peek + assert_equal [1,2], e.next_values +end + +assert 'Enumerator#peek_values modify' do + o = Object.new + def o.each + yield 1,2 + end + e = o.to_enum + a = e.peek_values + a << 3 + assert_equal [1,2], e.peek +end + +assert 'Enumerator#feed' do + o = Object.new + def o.each(ary) + ary << yield + ary << yield + ary << yield + end + ary = [] + e = o.to_enum :each, ary + e.next + e.feed 1 + e.next + e.feed 2 + e.next + e.feed 3 + assert_raise(StopIteration) { e.next } + assert_equal [1,2,3], ary +end + +assert 'Enumerator#feed mixed' do + o = Object.new + def o.each(ary) + ary << yield + ary << yield + ary << yield + end + ary = [] + e = o.to_enum :each, ary + e.next + e.feed 1 + e.next + e.next + e.feed 3 + assert_raise(StopIteration) { e.next } + assert_equal [1,nil,3], ary +end + +assert 'Enumerator#feed twice' do + o = Object.new + def o.each(ary) + ary << yield + ary << yield + ary << yield + end + ary = [] + e = o.to_enum :each, ary + e.feed 1 + assert_raise(TypeError) { e.feed 2 } +end + +assert 'Enumerator#feed before first next' do + o = Object.new + def o.each(ary) + ary << yield + ary << yield + ary << yield + end + ary = [] + e = o.to_enum :each, ary + e.feed 1 + e.next + e.next + assert_equal [1], ary +end + +assert 'Enumerator#feed yielder' do + x = nil + e = Enumerator.new {|y| x = y.yield; 10 } + e.next + e.feed 100 + assert_raise(StopIteration) { e.next } + assert_equal 100, x +end + +assert 'Enumerator#rewind' do + e = @obj.to_enum(:foo, 1, 2, 3) + assert_equal 1, e.next + assert_equal 2, e.next + e.rewind + assert_equal 1, e.next + assert_equal 2, e.next + assert_equal 3, e.next + assert_raise(StopIteration) { e.next } +end + +assert 'Enumerator#rewind clear feed' do + o = Object.new + def o.each(ary) + ary << yield + ary << yield + ary << yield + end + ary = [] + e = o.to_enum(:each, ary) + e.next + e.feed 1 + e.next + e.feed 2 + e.rewind + e.next + e.next + assert_equal([1,nil], ary) +end + +assert 'Enumerator#rewind clear' do + o = Object.new + def o.each(ary) + ary << yield + ary << yield + ary << yield + end + ary = [] + e = o.to_enum :each, ary + e.next + e.feed 1 + e.next + e.feed 2 + e.rewind + e.next + e.next + assert_equal [1,nil], ary +end + +assert 'Enumerator::Generator' do + # note: Enumerator::Generator is a class just for internal + g = Enumerator::Generator.new {|y| y << 1 << 2 << 3; :foo } + g2 = g.dup + a = [] + assert_equal(:foo, g.each {|x| a << x }) + assert_equal([1, 2, 3], a) + a = [] + assert_equal(:foo, g2.each {|x| a << x }) + assert_equal([1, 2, 3], a) +end + +assert 'Enumerator::Generator args' do + g = Enumerator::Generator.new {|y, x| y << 1 << 2 << 3; x } + a = [] + assert_equal(:bar, g.each(:bar) {|x| a << x }) + assert_equal([1, 2, 3], a) +end + +assert 'Enumerator::Yielder' do + # note: Enumerator::Yielder is a class just for internal + a = [] + y = Enumerator::Yielder.new {|x| a << x } + assert_equal(y, y << 1 << 2 << 3) + assert_equal([1, 2, 3], a) + + a = [] + y = Enumerator::Yielder.new {|x| a << x } + assert_equal([1], y.yield(1)) + assert_equal([1, 2], y.yield(2)) + assert_equal([1, 2, 3], y.yield(3)) + + assert_raise(LocalJumpError) { Enumerator::Yielder.new } +end + +assert 'next after StopIteration' do + a = [1] + e = a.each + assert_equal(1, e.next) + assert_raise(StopIteration) { e.next } + assert_raise(StopIteration) { e.next } + e.rewind + assert_equal(1, e.next) + assert_raise(StopIteration) { e.next } + assert_raise(StopIteration) { e.next } +end + +assert 'gc' do + assert_nothing_raised do + 1.times do + foo = [1,2,3].to_enum + GC.start + end + GC.start + end +end + +assert 'nested iteration' do + def (o = Object.new).each + yield :ok1 + yield [:ok2, :x].each.next + end + e = o.to_enum + assert_equal :ok1, e.next + assert_equal :ok2, e.next + assert_raise(StopIteration) { e.next } +end + +assert 'Kernel#to_enum' do + assert_equal Enumerator, [].to_enum.class + assert_raise(ArgumentError){ nil.to_enum } +end + +assert 'modifying existing methods' do + assert_equal Enumerator, loop.class + e = 3.times + i = 0 + loop_ret = loop { + assert_equal i, e.next + i += 1 + } +end + +assert 'Integral#times' do + a = 3 + b = a.times + c = [] + b.with_object(c) do |i, obj| + obj << i + end + assert_equal 3, a + assert_equal Enumerator, b.class + assert_equal [0,1,2], c +end + +assert 'Enumerable#each_with_index' do + assert_equal [['a',0],['b',1],['c',2]], ['a','b','c'].each_with_index.to_a +end + +assert 'Enumerable#map' do + a = [1,2,3] + b = a.map + c = b.with_index do |i, index| + [i*i, index*index] + end + assert_equal [1,2,3], a + assert_equal [[1,0],[4,1],[9,4]], c +end + +assert 'Enumerable#find_all' do + assert_equal [[3,4]], [[1,2],[3,4],[5,6]].find_all.each{ |i| i[1] == 4 } +end + +assert 'Array#each_index' do + a = [1,2,3] + b = a.each_index + c = [] + b.with_index do |index1,index2| + c << [index1+2,index2+5] + end + assert_equal [1,2,3], a + assert_equal [[2,5],[3,6],[4,7]], c +end + +assert 'Array#map!' do + a = [1,2,3] + b = a.map! + b.with_index do |i, index| + [i*i, index*index] + end + assert_equal [[1,0],[4,1],[9,4]], a +end + +assert 'Hash#each' do + a = {a:1,b:2} + b = a.each + c = [] + b.each do |k,v| + c << [k,v] + end + assert_equal [[:a,1], [:b,2]], c.sort +end + +assert 'Hash#each_key' do + assert_equal [:a,:b], {a:1,b:2}.each_key.to_a.sort +end + +assert 'Hash#each_value' do + assert_equal [1,2], {a:1,b:2}.each_value.to_a.sort +end + +assert 'Hash#select' do + h = {1=>2,3=>4,5=>6} + hret = h.select.with_index {|a,b| a[1] == 4} + assert_equal({3=>4}, hret) + assert_equal({1=>2,3=>4,5=>6}, h) +end + +assert 'Hash#select!' do + h = {1=>2,3=>4,5=>6} + hret = h.select!.with_index {|a,b| a[1] == 4} + assert_equal h, hret + assert_equal({3=>4}, h) +end + +assert 'Hash#reject' do + h = {1=>2,3=>4,5=>6} + hret = h.reject.with_index {|a,b| a[1] == 4} + assert_equal({1=>2,5=>6}, hret) + assert_equal({1=>2,3=>4,5=>6}, h) +end + +assert 'Hash#reject!' do + h = {1=>2,3=>4,5=>6} + hret = h.reject!.with_index {|a,b| a[1] == 4} + assert_equal h, hret + assert_equal({1=>2,5=>6}, h) +end + +assert 'Range#each' do + a = (1..5) + b = a.each + c = [] + b.each do |i| + c << i + end + assert_equal [1,2,3,4,5], c +end diff --git a/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-error/mrbgem.rake b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-error/mrbgem.rake new file mode 100644 index 00000000..30a4259a --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-error/mrbgem.rake @@ -0,0 +1,10 @@ +MRuby::Gem::Specification.new('mruby-error') do |spec| + spec.license = 'MIT' + spec.author = 'mruby developers' + spec.summary = 'extensional error handling' + + if build.cxx_exception_enabled? + @objs << build.compile_as_cxx("#{spec.dir}/src/exception.c", "#{spec.build_dir}/src/exception.cxx") + @objs.delete_if { |v| v == objfile("#{spec.build_dir}/src/exception") } + end +end diff --git a/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-error/src/exception.c b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-error/src/exception.c new file mode 100644 index 00000000..170abb69 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-error/src/exception.c @@ -0,0 +1,100 @@ +#include +#include +#include + +MRB_API mrb_value +mrb_protect(mrb_state *mrb, mrb_func_t body, mrb_value data, mrb_bool *state) +{ + struct mrb_jmpbuf *prev_jmp = mrb->jmp; + struct mrb_jmpbuf c_jmp; + mrb_value result = mrb_nil_value(); + + if (state) { *state = FALSE; } + + MRB_TRY(&c_jmp) { + mrb->jmp = &c_jmp; + result = body(mrb, data); + mrb->jmp = prev_jmp; + } MRB_CATCH(&c_jmp) { + mrb->jmp = prev_jmp; + result = mrb_obj_value(mrb->exc); + mrb->exc = NULL; + if (state) { *state = TRUE; } + } MRB_END_EXC(&c_jmp); + + mrb_gc_protect(mrb, result); + return result; +} + +MRB_API mrb_value +mrb_ensure(mrb_state *mrb, mrb_func_t body, mrb_value b_data, mrb_func_t ensure, mrb_value e_data) +{ + struct mrb_jmpbuf *prev_jmp = mrb->jmp; + struct mrb_jmpbuf c_jmp; + mrb_value result; + + MRB_TRY(&c_jmp) { + mrb->jmp = &c_jmp; + result = body(mrb, b_data); + mrb->jmp = prev_jmp; + } MRB_CATCH(&c_jmp) { + mrb->jmp = prev_jmp; + ensure(mrb, e_data); + MRB_THROW(mrb->jmp); /* rethrow catched exceptions */ + } MRB_END_EXC(&c_jmp); + + ensure(mrb, e_data); + mrb_gc_protect(mrb, result); + return result; +} + +MRB_API mrb_value +mrb_rescue(mrb_state *mrb, mrb_func_t body, mrb_value b_data, + mrb_func_t rescue, mrb_value r_data) +{ + return mrb_rescue_exceptions(mrb, body, b_data, rescue, r_data, 1, &mrb->eStandardError_class); +} + +MRB_API mrb_value +mrb_rescue_exceptions(mrb_state *mrb, mrb_func_t body, mrb_value b_data, mrb_func_t rescue, mrb_value r_data, + mrb_int len, struct RClass **classes) +{ + struct mrb_jmpbuf *prev_jmp = mrb->jmp; + struct mrb_jmpbuf c_jmp; + mrb_value result; + mrb_bool error_matched = FALSE; + mrb_int i; + + MRB_TRY(&c_jmp) { + mrb->jmp = &c_jmp; + result = body(mrb, b_data); + mrb->jmp = prev_jmp; + } MRB_CATCH(&c_jmp) { + mrb->jmp = prev_jmp; + + for (i = 0; i < len; ++i) { + if (mrb_obj_is_kind_of(mrb, mrb_obj_value(mrb->exc), classes[i])) { + error_matched = TRUE; + break; + } + } + + if (!error_matched) { MRB_THROW(mrb->jmp); } + + mrb->exc = NULL; + result = rescue(mrb, r_data); + } MRB_END_EXC(&c_jmp); + + mrb_gc_protect(mrb, result); + return result; +} + +void +mrb_mruby_error_gem_init(mrb_state *mrb) +{ +} + +void +mrb_mruby_error_gem_final(mrb_state *mrb) +{ +} diff --git a/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-error/test/exception.c b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-error/test/exception.c new file mode 100644 index 00000000..4de0e960 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-error/test/exception.c @@ -0,0 +1,59 @@ +#include +#include +#include + +static mrb_value +protect_cb(mrb_state *mrb, mrb_value b) +{ + return mrb_yield_argv(mrb, b, 0, NULL); +} + +static mrb_value +run_protect(mrb_state *mrb, mrb_value self) +{ + mrb_value b; + mrb_value ret[2]; + mrb_bool state; + mrb_get_args(mrb, "&", &b); + ret[0] = mrb_protect(mrb, protect_cb, b, &state); + ret[1] = mrb_bool_value(state); + return mrb_ary_new_from_values(mrb, 2, ret); +} + +static mrb_value +run_ensure(mrb_state *mrb, mrb_value self) +{ + mrb_value b, e; + mrb_get_args(mrb, "oo", &b, &e); + return mrb_ensure(mrb, protect_cb, b, protect_cb, e); +} + +static mrb_value +run_rescue(mrb_state *mrb, mrb_value self) +{ + mrb_value b, r; + mrb_get_args(mrb, "oo", &b, &r); + return mrb_rescue(mrb, protect_cb, b, protect_cb, r); +} + +static mrb_value +run_rescue_exceptions(mrb_state *mrb, mrb_value self) +{ + mrb_value b, r; + struct RClass *cls[1]; + mrb_get_args(mrb, "oo", &b, &r); + cls[0] = E_TYPE_ERROR; + return mrb_rescue_exceptions(mrb, protect_cb, b, protect_cb, r, 1, cls); +} + +void +mrb_mruby_error_gem_test(mrb_state *mrb) +{ + struct RClass *cls; + + cls = mrb_define_class(mrb, "ExceptionTest", mrb->object_class); + mrb_define_module_function(mrb, cls, "mrb_protect", run_protect, MRB_ARGS_NONE() | MRB_ARGS_BLOCK()); + mrb_define_module_function(mrb, cls, "mrb_ensure", run_ensure, MRB_ARGS_REQ(2)); + mrb_define_module_function(mrb, cls, "mrb_rescue", run_rescue, MRB_ARGS_REQ(2)); + mrb_define_module_function(mrb, cls, "mrb_rescue_exceptions", run_rescue_exceptions, MRB_ARGS_REQ(2)); +} diff --git a/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-error/test/exception.rb b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-error/test/exception.rb new file mode 100644 index 00000000..90846504 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-error/test/exception.rb @@ -0,0 +1,55 @@ +assert 'mrb_protect' do + # no failure in protect returns [result, false] + assert_equal ['test', false] do + ExceptionTest.mrb_protect { 'test' } + end + # failure in protect returns [exception, true] + result = ExceptionTest.mrb_protect { raise 'test' } + assert_kind_of RuntimeError, result[0] + assert_true result[1] +end + +assert 'mrb_ensure' do + a = false + assert_equal 'test' do + ExceptionTest.mrb_ensure Proc.new { 'test' }, Proc.new { a = true } + end + assert_true a + + a = false + assert_raise RuntimeError do + ExceptionTest.mrb_ensure Proc.new { raise 'test' }, Proc.new { a = true } + end + assert_true a +end + +assert 'mrb_rescue' do + assert_equal 'test' do + ExceptionTest.mrb_rescue Proc.new { 'test' }, Proc.new {} + end + + class CustomExp < Exception + end + + assert_raise CustomExp do + ExceptionTest.mrb_rescue Proc.new { raise CustomExp.new 'test' }, Proc.new { 'rescue' } + end + + assert_equal 'rescue' do + ExceptionTest.mrb_rescue Proc.new { raise 'test' }, Proc.new { 'rescue' } + end +end + +assert 'mrb_rescue_exceptions' do + assert_equal 'test' do + ExceptionTest.mrb_rescue_exceptions Proc.new { 'test' }, Proc.new {} + end + + assert_raise RangeError do + ExceptionTest.mrb_rescue_exceptions Proc.new { raise RangeError.new 'test' }, Proc.new { 'rescue' } + end + + assert_equal 'rescue' do + ExceptionTest.mrb_rescue_exceptions Proc.new { raise TypeError.new 'test' }, Proc.new { 'rescue' } + end +end diff --git a/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-eval/mrbgem.rake b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-eval/mrbgem.rake new file mode 100644 index 00000000..cb8835b3 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-eval/mrbgem.rake @@ -0,0 +1,7 @@ +MRuby::Gem::Specification.new('mruby-eval') do |spec| + spec.license = 'MIT' + spec.author = 'mruby developers' + spec.summary = 'standard Kernel#eval method' + + add_dependency 'mruby-compiler', :core => 'mruby-compiler' +end diff --git a/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-eval/src/eval.c b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-eval/src/eval.c new file mode 100644 index 00000000..5c0ea82f --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-eval/src/eval.c @@ -0,0 +1,346 @@ +#include +#include +#include +#include +#include +#include +#include + +mrb_value mrb_exec_irep(mrb_state *mrb, mrb_value self, struct RProc *p); +mrb_value mrb_obj_instance_eval(mrb_state *mrb, mrb_value self); + +static struct mrb_irep * +get_closure_irep(mrb_state *mrb, int level) +{ + struct mrb_context *c = mrb->c; + struct REnv *e = c->ci[-1].proc->env; + struct RProc *proc; + + if (level == 0) { + proc = c->ci[-1].proc; + if (MRB_PROC_CFUNC_P(proc)) { + return NULL; + } + return proc->body.irep; + } + + while (--level) { + e = (struct REnv*)e->c; + if (!e) return NULL; + } + + if (!e) return NULL; + if (!MRB_ENV_STACK_SHARED_P(e)) return NULL; + c = e->cxt.c; + proc = c->cibase[e->cioff].proc; + + if (!proc || MRB_PROC_CFUNC_P(proc)) { + return NULL; + } + return proc->body.irep; +} + +/* search for irep lev above the bottom */ +static mrb_irep* +search_irep(mrb_irep *top, int bnest, int lev, mrb_irep *bottom) +{ + int i; + + for (i=0; irlen; i++) { + mrb_irep* tmp = top->reps[i]; + + if (tmp == bottom) return top; + tmp = search_irep(tmp, bnest-1, lev, bottom); + if (tmp) { + if (bnest == lev) return top; + return tmp; + } + } + return NULL; +} + +static inline mrb_code +search_variable(mrb_state *mrb, mrb_sym vsym, int bnest) +{ + mrb_irep *virep; + int level; + int pos; + + for (level = 0; (virep = get_closure_irep(mrb, level)); level++) { + if (!virep || virep->lv == NULL) { + continue; + } + for (pos = 0; pos < virep->nlocals - 1; pos++) { + if (vsym == virep->lv[pos].name) { + return (MKARG_B(pos + 1) | MKARG_C(level + bnest)); + } + } + } + + return 0; +} + +static int +irep_argc(mrb_irep *irep) +{ + mrb_code c; + + c = irep->iseq[0]; + if (GET_OPCODE(c) == OP_ENTER) { + mrb_aspec ax = GETARG_Ax(c); + /* extra 1 means a slot for block */ + return MRB_ASPEC_REQ(ax)+MRB_ASPEC_OPT(ax)+MRB_ASPEC_REST(ax)+MRB_ASPEC_POST(ax)+1; + } + return 0; +} + +static mrb_bool +potential_upvar_p(struct mrb_locals *lv, uint16_t v, int argc, uint16_t nlocals) +{ + if (v >= nlocals) return FALSE; + /* skip arguments */ + if (v < argc+1) return FALSE; + return TRUE; +} + +static void +patch_irep(mrb_state *mrb, mrb_irep *irep, int bnest, mrb_irep *top) +{ + int i; + mrb_code c; + int argc = irep_argc(irep); + + for (i = 0; i < irep->ilen; i++) { + c = irep->iseq[i]; + switch(GET_OPCODE(c)){ + case OP_EPUSH: + patch_irep(mrb, irep->reps[GETARG_Bx(c)], bnest + 1, top); + break; + + case OP_LAMBDA: + { + int arg_c = GETARG_c(c); + if (arg_c & OP_L_CAPTURE) { + patch_irep(mrb, irep->reps[GETARG_b(c)], bnest + 1, top); + } + } + break; + + case OP_SEND: + if (GETARG_C(c) != 0) { + break; + } + { + mrb_code arg = search_variable(mrb, irep->syms[GETARG_B(c)], bnest); + if (arg != 0) { + /* must replace */ + irep->iseq[i] = MKOPCODE(OP_GETUPVAR) | MKARG_A(GETARG_A(c)) | arg; + } + } + break; + + case OP_MOVE: + /* src part */ + if (potential_upvar_p(irep->lv, GETARG_B(c), argc, irep->nlocals)) { + mrb_code arg = search_variable(mrb, irep->lv[GETARG_B(c) - 1].name, bnest); + if (arg != 0) { + /* must replace */ + irep->iseq[i] = MKOPCODE(OP_GETUPVAR) | MKARG_A(GETARG_A(c)) | arg; + } + } + /* dst part */ + if (potential_upvar_p(irep->lv, GETARG_A(c), argc, irep->nlocals)) { + mrb_code arg = search_variable(mrb, irep->lv[GETARG_A(c) - 1].name, bnest); + if (arg != 0) { + /* must replace */ + irep->iseq[i] = MKOPCODE(OP_SETUPVAR) | MKARG_A(GETARG_B(c)) | arg; + } + } + break; + + case OP_GETUPVAR: + { + int lev = GETARG_C(c)+1; + mrb_irep *tmp = search_irep(top, bnest, lev, irep); + if (potential_upvar_p(tmp->lv, GETARG_B(c), irep_argc(tmp), tmp->nlocals)) { + mrb_code arg = search_variable(mrb, tmp->lv[GETARG_B(c)-1].name, bnest); + if (arg != 0) { + /* must replace */ + irep->iseq[i] = MKOPCODE(OP_GETUPVAR) | MKARG_A(GETARG_A(c)) | arg; + } + } + } + break; + + case OP_SETUPVAR: + { + int lev = GETARG_C(c)+1; + mrb_irep *tmp = search_irep(top, bnest, lev, irep); + if (potential_upvar_p(tmp->lv, GETARG_B(c), irep_argc(tmp), tmp->nlocals)) { + mrb_code arg = search_variable(mrb, tmp->lv[GETARG_B(c)-1].name, bnest); + if (arg != 0) { + /* must replace */ + irep->iseq[i] = MKOPCODE(OP_SETUPVAR) | MKARG_A(GETARG_A(c)) | arg; + } + } + } + break; + + case OP_STOP: + if (mrb->c->ci->acc >= 0) { + irep->iseq[i] = MKOP_AB(OP_RETURN, irep->nlocals, OP_R_NORMAL); + } + break; + } + } +} + +void mrb_codedump_all(mrb_state*, struct RProc*); + +static struct RProc* +create_proc_from_string(mrb_state *mrb, char *s, int len, mrb_value binding, const char *file, mrb_int line) +{ + mrbc_context *cxt; + struct mrb_parser_state *p; + struct RProc *proc; + struct REnv *e; + struct mrb_context *c = mrb->c; + + if (!mrb_nil_p(binding)) { + mrb_raise(mrb, E_ARGUMENT_ERROR, "Binding of eval must be nil."); + } + + cxt = mrbc_context_new(mrb); + cxt->lineno = line; + + mrbc_filename(mrb, cxt, file ? file : "(eval)"); + cxt->capture_errors = TRUE; + cxt->no_optimize = TRUE; + + p = mrb_parse_nstring(mrb, s, len, cxt); + + /* only occur when memory ran out */ + if (!p) { + mrb_raise(mrb, E_RUNTIME_ERROR, "Failed to create parser state."); + } + + if (0 < p->nerr) { + /* parse error */ + mrb_value str; + + if (file) { + str = mrb_format(mrb, " file %S line %S: %S", + mrb_str_new_cstr(mrb, file), + mrb_fixnum_value(p->error_buffer[0].lineno), + mrb_str_new_cstr(mrb, p->error_buffer[0].message)); + } + else { + str = mrb_format(mrb, " line %S: %S", + mrb_fixnum_value(p->error_buffer[0].lineno), + mrb_str_new_cstr(mrb, p->error_buffer[0].message)); + } + mrb_parser_free(p); + mrbc_context_free(mrb, cxt); + mrb_exc_raise(mrb, mrb_exc_new_str(mrb, E_SYNTAX_ERROR, str)); + } + + proc = mrb_generate_code(mrb, p); + if (proc == NULL) { + /* codegen error */ + mrb_parser_free(p); + mrbc_context_free(mrb, cxt); + mrb_raise(mrb, E_SCRIPT_ERROR, "codegen error"); + } + if (c->ci[-1].proc->target_class) { + proc->target_class = c->ci[-1].proc->target_class; + } + e = c->ci[-1].proc->env; + if (!e) e = c->ci[-1].env; + e = (struct REnv*)mrb_obj_alloc(mrb, MRB_TT_ENV, (struct RClass*)e); + e->cxt.c = c; + e->cioff = c->ci - c->cibase; + e->stack = c->ci->stackent; + MRB_SET_ENV_STACK_LEN(e, c->ci->proc->body.irep->nlocals); + c->ci->target_class = proc->target_class; + c->ci->env = 0; + proc->env = e; + patch_irep(mrb, proc->body.irep, 0, proc->body.irep); + /* mrb_codedump_all(mrb, proc); */ + + mrb_parser_free(p); + mrbc_context_free(mrb, cxt); + + return proc; +} + +static mrb_value +exec_irep(mrb_state *mrb, mrb_value self, struct RProc *proc) +{ + if (mrb->c->ci->acc < 0) { + mrb_value ret = mrb_top_run(mrb, proc, mrb->c->stack[0], 0); + if (mrb->exc) { + mrb_exc_raise(mrb, mrb_obj_value(mrb->exc)); + } + return ret; + } + return mrb_exec_irep(mrb, self, proc); +} + +static mrb_value +f_eval(mrb_state *mrb, mrb_value self) +{ + char *s; + mrb_int len; + mrb_value binding = mrb_nil_value(); + char *file = NULL; + mrb_int line = 1; + struct RProc *proc; + + mrb_get_args(mrb, "s|ozi", &s, &len, &binding, &file, &line); + + proc = create_proc_from_string(mrb, s, len, binding, file, line); + mrb_assert(!MRB_PROC_CFUNC_P(proc)); + return exec_irep(mrb, self, proc); +} + +static mrb_value +f_instance_eval(mrb_state *mrb, mrb_value self) +{ + mrb_value b; + mrb_int argc; mrb_value *argv; + + mrb_get_args(mrb, "*!&", &argv, &argc, &b); + + if (mrb_nil_p(b)) { + char *s; + mrb_int len; + char *file = NULL; + mrb_int line = 1; + mrb_value cv; + struct RProc *proc; + + mrb_get_args(mrb, "s|zi", &s, &len, &file, &line); + cv = mrb_singleton_class(mrb, self); + proc = create_proc_from_string(mrb, s, len, mrb_nil_value(), file, line); + proc->target_class = mrb_class_ptr(cv); + mrb->c->ci->env = NULL; + mrb_assert(!MRB_PROC_CFUNC_P(proc)); + return exec_irep(mrb, self, proc); + } + else { + mrb_get_args(mrb, "&", &b); + return mrb_obj_instance_eval(mrb, self); + } +} + +void +mrb_mruby_eval_gem_init(mrb_state* mrb) +{ + mrb_define_module_function(mrb, mrb->kernel_module, "eval", f_eval, MRB_ARGS_ARG(1, 3)); + mrb_define_method(mrb, mrb->kernel_module, "instance_eval", f_instance_eval, MRB_ARGS_ARG(1, 2)); +} + +void +mrb_mruby_eval_gem_final(mrb_state* mrb) +{ +} diff --git a/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-eval/test/eval.rb b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-eval/test/eval.rb new file mode 100644 index 00000000..66ca1fcd --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-eval/test/eval.rb @@ -0,0 +1,101 @@ +assert('Kernel.eval', '15.3.1.2.3') do + assert_equal(10) { Kernel.eval '1 * 10' } + assert_equal('aaa') { Kernel.eval "'a' * 3" } + assert_equal(10) { + a = 10 + Kernel.eval "a" + } + assert_equal(20) { + a = 10 + Kernel.eval "a = 20" + a + } + assert_equal(15) { + c = 5 + lambda { + a = 10 + Kernel.eval "c = a + c" + }.call + c + } + assert_equal(5) { + c = 5 + lambda { + Kernel.eval 'lambda { c }.call' + }.call + } + assert_equal(15) { + c = 5 + lambda { + a = 10 + Kernel.eval 'lambda { c = a + c }.call' + }.call + c + } + assert_equal(2) { + a = 10 + Kernel.eval 'def f(a); b=a.send(:+, 1); end' + f(1) + } +end + +assert('Kernel#eval', '15.3.1.3.12') do + assert_equal(10) { eval '1 * 10' } +end + +assert('rest arguments of eval') do + assert_raise(ArgumentError) { Kernel.eval('0', 0, 'test', 0) } + assert_equal ['test', 'test.rb', 10] do + Kernel.eval('[\'test\', __FILE__, __LINE__]', nil, 'test.rb', 10) + end +end + +assert 'eval syntax error' do + assert_raise(SyntaxError) do + eval 'p "test' + end +end + +assert('String instance_eval') do + obj = Object.new + obj.instance_variable_set :@test, 'test' + assert_raise(ArgumentError) { obj.instance_eval(0) { } } + assert_raise(ArgumentError) { obj.instance_eval('0', 'test', 0, 'test') } + assert_equal(['test.rb', 10]) { obj.instance_eval('[__FILE__, __LINE__]', 'test.rb', 10)} + assert_equal('test') { obj.instance_eval('@test') } + assert_equal('test') { obj.instance_eval { @test } } + o = Object.new + assert_equal ['', o, o], o.instance_eval("[''].each { |s| break [s, o, self] }") +end + +assert('Kernel.#eval(string) context') do + class TestEvalConstScope + EVAL_CONST_CLASS = 'class' + def const_string + eval 'EVAL_CONST_CLASS' + end + end + obj = TestEvalConstScope.new + assert_raise(NameError) { eval 'EVAL_CONST_CLASS' } + assert_equal('class') { obj.const_string } +end + +assert('Object#instance_eval with begin-rescue-ensure execution order') do + class HellRaiser + def raise_hell + order = [:enter_raise_hell] + begin + order.push :begin + self.instance_eval("raise 'error'") + rescue + order.push :rescue + ensure + order.push :ensure + end + order + end + end + + hell_raiser = HellRaiser.new + assert_equal([:enter_raise_hell, :begin, :rescue, :ensure], hell_raiser.raise_hell) +end diff --git a/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-exit/mrbgem.rake b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-exit/mrbgem.rake new file mode 100644 index 00000000..d193528d --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-exit/mrbgem.rake @@ -0,0 +1,5 @@ +MRuby::Gem::Specification.new('mruby-exit') do |spec| + spec.license = 'MIT' + spec.author = 'mruby developers' + spec.summary = 'Kernel#exit method' +end diff --git a/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-exit/src/mruby-exit.c b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-exit/src/mruby-exit.c new file mode 100644 index 00000000..3e147f80 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-exit/src/mruby-exit.c @@ -0,0 +1,24 @@ +#include +#include + +static mrb_value +f_exit(mrb_state *mrb, mrb_value self) +{ + mrb_int i = EXIT_SUCCESS; + + mrb_get_args(mrb, "|i", &i); + exit(i); + /* not reached */ + return mrb_nil_value(); +} + +void +mrb_mruby_exit_gem_init(mrb_state* mrb) +{ + mrb_define_method(mrb, mrb->kernel_module, "exit", f_exit, MRB_ARGS_OPT(1)); +} + +void +mrb_mruby_exit_gem_final(mrb_state* mrb) +{ +} diff --git a/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-fiber/mrbgem.rake b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-fiber/mrbgem.rake new file mode 100644 index 00000000..815cd3c4 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-fiber/mrbgem.rake @@ -0,0 +1,5 @@ +MRuby::Gem::Specification.new('mruby-fiber') do |spec| + spec.license = 'MIT' + spec.author = 'mruby developers' + spec.summary = 'Fiber class' +end diff --git a/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-fiber/src/fiber.c b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-fiber/src/fiber.c new file mode 100644 index 00000000..9de175f3 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-fiber/src/fiber.c @@ -0,0 +1,420 @@ +#include +#include +#include +#include + +#define fiber_ptr(o) ((struct RFiber*)mrb_ptr(o)) + +#define FIBER_STACK_INIT_SIZE 64 +#define FIBER_CI_INIT_SIZE 8 +#define CI_ACC_RESUMED -3 + +/* + * call-seq: + * Fiber.new{...} -> obj + * + * Creates a fiber, whose execution is suspend until it is explicitly + * resumed using Fiber#resume method. + * The code running inside the fiber can give up control by calling + * Fiber.yield in which case it yields control back to caller + * (the caller of the Fiber#resume). + * + * Upon yielding or termination the Fiber returns the value of the last + * executed expression + * + * For instance: + * + * fiber = Fiber.new do + * Fiber.yield 1 + * 2 + * end + * + * puts fiber.resume + * puts fiber.resume + * puts fiber.resume + * + * produces + * + * 1 + * 2 + * resuming dead fiber (FiberError) + * + * The Fiber#resume method accepts an arbitrary number of + * parameters, if it is the first call to resume then they + * will be passed as block arguments. Otherwise they will be the return + * value of the call to Fiber.yield + * + * Example: + * + * fiber = Fiber.new do |first| + * second = Fiber.yield first + 2 + * end + * + * puts fiber.resume 10 + * puts fiber.resume 14 + * puts fiber.resume 18 + * + * produces + * + * 12 + * 14 + * resuming dead fiber (FiberError) + * + */ +static mrb_value +fiber_init(mrb_state *mrb, mrb_value self) +{ + static const struct mrb_context mrb_context_zero = { 0 }; + struct RFiber *f = fiber_ptr(self); + struct mrb_context *c; + struct RProc *p; + mrb_callinfo *ci; + mrb_value blk; + size_t slen; + + mrb_get_args(mrb, "&", &blk); + + if (f->cxt) { + mrb_raise(mrb, E_RUNTIME_ERROR, "cannot initialize twice"); + } + if (mrb_nil_p(blk)) { + mrb_raise(mrb, E_ARGUMENT_ERROR, "tried to create Fiber object without a block"); + } + p = mrb_proc_ptr(blk); + if (MRB_PROC_CFUNC_P(p)) { + mrb_raise(mrb, E_FIBER_ERROR, "tried to create Fiber from C defined method"); + } + + c = (struct mrb_context*)mrb_malloc(mrb, sizeof(struct mrb_context)); + *c = mrb_context_zero; + f->cxt = c; + + /* initialize VM stack */ + slen = FIBER_STACK_INIT_SIZE; + if (p->body.irep->nregs > slen) { + slen += p->body.irep->nregs; + } + c->stbase = (mrb_value *)mrb_malloc(mrb, slen*sizeof(mrb_value)); + c->stend = c->stbase + slen; + c->stack = c->stbase; + +#ifdef MRB_NAN_BOXING + { + mrb_value *p = c->stbase; + mrb_value *pend = c->stend; + + while (p < pend) { + SET_NIL_VALUE(*p); + p++; + } + } +#else + memset(c->stbase, 0, slen * sizeof(mrb_value)); +#endif + + /* copy receiver from a block */ + c->stack[0] = mrb->c->stack[0]; + + /* initialize callinfo stack */ + c->cibase = (mrb_callinfo *)mrb_calloc(mrb, FIBER_CI_INIT_SIZE, sizeof(mrb_callinfo)); + c->ciend = c->cibase + FIBER_CI_INIT_SIZE; + c->ci = c->cibase; + c->ci->stackent = c->stack; + + /* adjust return callinfo */ + ci = c->ci; + ci->target_class = p->target_class; + ci->proc = p; + mrb_field_write_barrier(mrb, (struct RBasic*)mrb_obj_ptr(self), (struct RBasic*)p); + ci->pc = p->body.irep->iseq; + ci->nregs = p->body.irep->nregs; + ci[1] = ci[0]; + c->ci++; /* push dummy callinfo */ + + c->fib = f; + c->status = MRB_FIBER_CREATED; + + return self; +} + +static struct mrb_context* +fiber_check(mrb_state *mrb, mrb_value fib) +{ + struct RFiber *f = fiber_ptr(fib); + + mrb_assert(f->tt == MRB_TT_FIBER); + if (!f->cxt) { + mrb_raise(mrb, E_FIBER_ERROR, "uninitialized Fiber"); + } + return f->cxt; +} + +static mrb_value +fiber_result(mrb_state *mrb, const mrb_value *a, mrb_int len) +{ + if (len == 0) return mrb_nil_value(); + if (len == 1) return a[0]; + return mrb_ary_new_from_values(mrb, len, a); +} + +/* mark return from context modifying method */ +#define MARK_CONTEXT_MODIFY(c) (c)->ci->target_class = NULL + +static void +fiber_check_cfunc(mrb_state *mrb, struct mrb_context *c) +{ + mrb_callinfo *ci; + + for (ci = c->ci; ci >= c->cibase; ci--) { + if (ci->acc < 0) { + mrb_raise(mrb, E_FIBER_ERROR, "can't cross C function boundary"); + } + } +} + +static void +fiber_switch_context(mrb_state *mrb, struct mrb_context *c) +{ + if (mrb->c->fib) { + mrb_write_barrier(mrb, (struct RBasic*)mrb->c->fib); + } + c->status = MRB_FIBER_RUNNING; + mrb->c = c; +} + +static mrb_value +fiber_switch(mrb_state *mrb, mrb_value self, mrb_int len, const mrb_value *a, mrb_bool resume, mrb_bool vmexec) +{ + struct mrb_context *c = fiber_check(mrb, self); + struct mrb_context *old_c = mrb->c; + mrb_value value; + + fiber_check_cfunc(mrb, c); + if (resume && c->status == MRB_FIBER_TRANSFERRED) { + mrb_raise(mrb, E_FIBER_ERROR, "resuming transferred fiber"); + } + if (c->status == MRB_FIBER_RUNNING || c->status == MRB_FIBER_RESUMED) { + mrb_raise(mrb, E_FIBER_ERROR, "double resume (fib)"); + } + if (c->status == MRB_FIBER_TERMINATED) { + mrb_raise(mrb, E_FIBER_ERROR, "resuming dead fiber"); + } + mrb->c->status = resume ? MRB_FIBER_RESUMED : MRB_FIBER_TRANSFERRED; + c->prev = resume ? mrb->c : (c->prev ? c->prev : mrb->root_c); + if (c->status == MRB_FIBER_CREATED) { + mrb_value *b, *e; + + if (len >= c->stend - c->stack) { + mrb_raise(mrb, E_FIBER_ERROR, "too many arguments to fiber"); + } + b = c->stack+1; + e = b + len; + while (bcibase->argc = len; + value = c->stack[0] = c->ci->proc->env->stack[0]; + } + else { + value = fiber_result(mrb, a, len); + } + fiber_switch_context(mrb, c); + + if (vmexec) { + c->vmexec = TRUE; + value = mrb_vm_exec(mrb, c->ci[-1].proc, c->ci->pc); + mrb->c = old_c; + } + else { + MARK_CONTEXT_MODIFY(c); + } + return value; +} + +/* + * call-seq: + * fiber.resume(args, ...) -> obj + * + * Resumes the fiber from the point at which the last Fiber.yield + * was called, or starts running it if it is the first call to + * resume. Arguments passed to resume will be the value of + * the Fiber.yield expression or will be passed as block + * parameters to the fiber's block if this is the first resume. + * + * Alternatively, when resume is called it evaluates to the arguments passed + * to the next Fiber.yield statement inside the fiber's block + * or to the block value if it runs to completion without any + * Fiber.yield + */ +static mrb_value +fiber_resume(mrb_state *mrb, mrb_value self) +{ + mrb_value *a; + mrb_int len; + mrb_bool vmexec = FALSE; + + mrb_get_args(mrb, "*!", &a, &len); + if (mrb->c->ci->acc < 0) { + vmexec = TRUE; + } + return fiber_switch(mrb, self, len, a, TRUE, vmexec); +} + +/* resume thread with given arguments */ +MRB_API mrb_value +mrb_fiber_resume(mrb_state *mrb, mrb_value fib, mrb_int len, const mrb_value *a) +{ + return fiber_switch(mrb, fib, len, a, TRUE, TRUE); +} + +/* + * call-seq: + * fiber.alive? -> true or false + * + * Returns true if the fiber can still be resumed. After finishing + * execution of the fiber block this method will always return false. + */ +static mrb_value +fiber_alive_p(mrb_state *mrb, mrb_value self) +{ + struct mrb_context *c = fiber_check(mrb, self); + return mrb_bool_value(c->status != MRB_FIBER_TERMINATED); +} + +static mrb_value +fiber_eq(mrb_state *mrb, mrb_value self) +{ + mrb_value other; + mrb_get_args(mrb, "o", &other); + + if (mrb_type(other) != MRB_TT_FIBER) { + return mrb_false_value(); + } + return mrb_bool_value(fiber_ptr(self) == fiber_ptr(other)); +} + +/* + * call-seq: + * fiber.transfer(args, ...) -> obj + * + * Transfers control to receiver fiber of the method call. + * Unlike resume the receiver wouldn't be pushed to call + * stack of fibers. Instead it will switch to the call stack of + * transferring fiber. + * When resuming a fiber that was transferred to another fiber it would + * cause double resume error. Though when the fiber is re-transferred + * and Fiber.yield is called, the fiber would be resumable. + */ +static mrb_value +fiber_transfer(mrb_state *mrb, mrb_value self) +{ + struct mrb_context *c = fiber_check(mrb, self); + mrb_value* a; + mrb_int len; + + fiber_check_cfunc(mrb, mrb->c); + mrb_get_args(mrb, "*!", &a, &len); + + if (c == mrb->root_c) { + mrb->c->status = MRB_FIBER_TRANSFERRED; + fiber_switch_context(mrb, c); + MARK_CONTEXT_MODIFY(c); + return fiber_result(mrb, a, len); + } + + if (c == mrb->c) { + return fiber_result(mrb, a, len); + } + + return fiber_switch(mrb, self, len, a, FALSE, FALSE); +} + +/* yield values to the caller fiber */ +/* mrb_fiber_yield() must be called as `return mrb_fiber_yield(...)` */ +MRB_API mrb_value +mrb_fiber_yield(mrb_state *mrb, mrb_int len, const mrb_value *a) +{ + struct mrb_context *c = mrb->c; + + if (!c->prev) { + mrb_raise(mrb, E_FIBER_ERROR, "can't yield from root fiber"); + } + + fiber_check_cfunc(mrb, c); + c->prev->status = MRB_FIBER_RUNNING; + c->status = MRB_FIBER_SUSPENDED; + fiber_switch_context(mrb, c->prev); + c->prev = NULL; + if (c->vmexec) { + c->vmexec = FALSE; + mrb->c->ci->acc = CI_ACC_RESUMED; + } + MARK_CONTEXT_MODIFY(mrb->c); + return fiber_result(mrb, a, len); +} + +/* + * call-seq: + * Fiber.yield(args, ...) -> obj + * + * Yields control back to the context that resumed the fiber, passing + * along any arguments that were passed to it. The fiber will resume + * processing at this point when resume is called next. + * Any arguments passed to the next resume will be the + * + * mruby limitation: Fiber resume/yield cannot cross C function boundary. + * thus you cannot yield from #initialize which is called by mrb_funcall(). + */ +static mrb_value +fiber_yield(mrb_state *mrb, mrb_value self) +{ + mrb_value *a; + mrb_int len; + + mrb_get_args(mrb, "*!", &a, &len); + return mrb_fiber_yield(mrb, len, a); +} + +/* + * call-seq: + * Fiber.current() -> fiber + * + * Returns the current fiber. If you are not running in the context of + * a fiber this method will return the root fiber. + */ +static mrb_value +fiber_current(mrb_state *mrb, mrb_value self) +{ + if (!mrb->c->fib) { + struct RFiber *f = (struct RFiber*)mrb_obj_alloc(mrb, MRB_TT_FIBER, mrb_class_ptr(self)); + + f->cxt = mrb->c; + mrb->c->fib = f; + } + return mrb_obj_value(mrb->c->fib); +} + +void +mrb_mruby_fiber_gem_init(mrb_state* mrb) +{ + struct RClass *c; + + c = mrb_define_class(mrb, "Fiber", mrb->object_class); + MRB_SET_INSTANCE_TT(c, MRB_TT_FIBER); + + mrb_define_method(mrb, c, "initialize", fiber_init, MRB_ARGS_NONE()); + mrb_define_method(mrb, c, "resume", fiber_resume, MRB_ARGS_ANY()); + mrb_define_method(mrb, c, "transfer", fiber_transfer, MRB_ARGS_ANY()); + mrb_define_method(mrb, c, "alive?", fiber_alive_p, MRB_ARGS_NONE()); + mrb_define_method(mrb, c, "==", fiber_eq, MRB_ARGS_REQ(1)); + + mrb_define_class_method(mrb, c, "yield", fiber_yield, MRB_ARGS_ANY()); + mrb_define_class_method(mrb, c, "current", fiber_current, MRB_ARGS_NONE()); + + mrb_define_class(mrb, "FiberError", mrb->eStandardError_class); +} + +void +mrb_mruby_fiber_gem_final(mrb_state* mrb) +{ +} diff --git a/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-fiber/test/fiber.rb b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-fiber/test/fiber.rb new file mode 100644 index 00000000..d063a0a6 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-fiber/test/fiber.rb @@ -0,0 +1,208 @@ +assert('Fiber.new') do + f = Fiber.new{} + assert_kind_of Fiber, f +end + +assert('Fiber#resume') do + f = Fiber.new{|x| x } + assert_equal 2, f.resume(2) +end + +assert('Fiber#transfer') do + f2 = nil + f1 = Fiber.new do |v| + Fiber.yield v + f2.transfer + end + f2 = Fiber.new do + f1.transfer(1) + f1.transfer(1) + Fiber.yield 2 + end + assert_equal 1, f2.resume + assert_raise(FiberError) { f2.resume } + assert_equal 2, f2.transfer + assert_raise(FiberError) { f1.resume } + f1.transfer + f2.resume + assert_false f1.alive? + assert_false f2.alive? +end + +assert('Fiber#alive?') do + f = Fiber.new{ Fiber.yield } + f.resume + assert_true f.alive? + f.resume + assert_false f.alive? +end + +assert('Fiber#==') do + root = Fiber.current + assert_equal root, root + assert_equal root, Fiber.current + assert_false root != Fiber.current + f = Fiber.new { + assert_false root == Fiber.current + } + f.resume + assert_false f == root + assert_true f != root +end + +assert('Fiber.yield') do + f = Fiber.new{|x| Fiber.yield x } + assert_equal 3, f.resume(3) + assert_true f.alive? +end + +assert('FiberError') do + assert_equal StandardError, FiberError.superclass +end + +assert('Fiber iteration') do + f1 = Fiber.new{ + [1,2,3].each{|x| Fiber.yield(x)} + } + f2 = Fiber.new{ + [9,8,7].each{|x| Fiber.yield(x)} + } + a = [] + 3.times { + a << f1.resume + a << f2.resume + } + assert_equal [1,9,2,8,3,7], a +end + +assert('Fiber with splat in the block argument list') { + Fiber.new{|*x|x}.resume(1) == [1] +} + +assert('Fiber raises on resume when dead') do + assert_raise(FiberError) do + f = Fiber.new{} + f.resume + assert_false f.alive? + f.resume + end +end + +assert('Yield raises when called on root fiber') do + assert_raise(FiberError) { Fiber.yield } +end + +assert('Double resume of Fiber') do + f1 = Fiber.new {} + f2 = Fiber.new { + f1.resume + assert_raise(FiberError) { f2.resume } + Fiber.yield 0 + } + assert_equal 0, f2.resume + f2.resume + assert_false f1.alive? + assert_false f2.alive? +end + +assert('Recursive resume of Fiber') do + f1, f2 = nil, nil + f1 = Fiber.new { assert_raise(FiberError) { f2.resume } } + f2 = Fiber.new { + f1.resume + Fiber.yield 0 + } + f3 = Fiber.new { + f2.resume + } + assert_equal 0, f3.resume + f2.resume + assert_false f1.alive? + assert_false f2.alive? + assert_false f3.alive? +end + +assert('Root fiber resume') do + root = Fiber.current + assert_raise(FiberError) { root.resume } + f = Fiber.new { + assert_raise(FiberError) { root.resume } + } + f.resume + assert_false f.alive? +end + +assert('Fiber without block') do + assert_raise(ArgumentError) { Fiber.new } +end + + +assert('Transfer to self.') do + result = [] + f = Fiber.new { result << :start; f.transfer; result << :end } + f.transfer + assert_equal [:start, :end], result + + result = [] + f = Fiber.new { result << :start; f.transfer; result << :end } + f.resume + assert_equal [:start, :end], result +end + +assert('Resume transferred fiber') do + f = Fiber.new { + assert_raise(FiberError) { f.resume } + } + f.transfer +end + +assert('Root fiber transfer.') do + result = nil + root = Fiber.current + f = Fiber.new { + result = :ok + root.transfer + } + f.resume + assert_true f.alive? + assert_equal :ok, result +end + +assert('Break nested fiber with root fiber transfer') do + root = Fiber.current + + result = nil + f2 = nil + f1 = Fiber.new { + Fiber.yield f2.resume + result = :f1 + } + f2 = Fiber.new { + result = :to_root + root.transfer :from_f2 + result = :f2 + } + assert_equal :from_f2, f1.resume + assert_equal :to_root, result + assert_equal :f2, f2.transfer + assert_equal :f2, result + assert_false f2.alive? + assert_equal :f1, f1.resume + assert_equal :f1, result + assert_false f1.alive? +end + +assert('CRuby Fiber#transfer test.') do + ary = [] + f2 = nil + f1 = Fiber.new{ + ary << f2.transfer(:foo) + :ok + } + f2 = Fiber.new{ + ary << f1.transfer(:baz) + :ng + } + assert_equal :ok, f1.transfer + assert_equal [:baz], ary +end diff --git a/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-hash-ext/mrbgem.rake b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-hash-ext/mrbgem.rake new file mode 100644 index 00000000..103410ab --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-hash-ext/mrbgem.rake @@ -0,0 +1,8 @@ +MRuby::Gem::Specification.new('mruby-hash-ext') do |spec| + spec.license = 'MIT' + spec.author = 'mruby developers' + spec.summary = 'Hash class extension' + spec.add_dependency 'mruby-enum-ext', core: 'mruby-enum-ext' + spec.add_dependency 'mruby-array-ext', core: 'mruby-array-ext' + spec.add_test_dependency 'mruby-enumerator', core: 'mruby-enumerator' +end diff --git a/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-hash-ext/mrblib/hash.rb b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-hash-ext/mrblib/hash.rb new file mode 100644 index 00000000..73d1fbe6 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-hash-ext/mrblib/hash.rb @@ -0,0 +1,477 @@ +class Hash + + # ISO does not define Hash#each_pair, so each_pair is defined in gem. + alias each_pair each + + ## + # call-seq: + # Hash[ key, value, ... ] -> new_hash + # Hash[ [ [key, value], ... ] ] -> new_hash + # Hash[ object ] -> new_hash + # + # Creates a new hash populated with the given objects. + # + # Similar to the literal `{ _key_ => _value_, ... }`. In the first + # form, keys and values occur in pairs, so there must be an even number of + # arguments. + # + # The second and third form take a single argument which is either an array + # of key-value pairs or an object convertible to a hash. + # + # Hash["a", 100, "b", 200] #=> {"a"=>100, "b"=>200} + # Hash[ [ ["a", 100], ["b", 200] ] ] #=> {"a"=>100, "b"=>200} + # Hash["a" => 100, "b" => 200] #=> {"a"=>100, "b"=>200} + # + + def self.[](*object) + length = object.length + if length == 1 + o = object[0] + if o.respond_to?(:to_hash) + h = self.new + object[0].to_hash.each { |k, v| h[k] = v } + return h + elsif o.respond_to?(:to_a) + h = self.new + o.to_a.each do |i| + raise ArgumentError, "wrong element type #{i.class} (expected array)" unless i.respond_to?(:to_a) + k, v = nil + case i.size + when 2 + k = i[0] + v = i[1] + when 1 + k = i[0] + else + raise ArgumentError, "invalid number of elements (#{i.size} for 1..2)" + end + h[k] = v + end + return h + end + end + unless length % 2 == 0 + raise ArgumentError, 'odd number of arguments for Hash' + end + h = self.new + 0.step(length - 2, 2) do |i| + h[object[i]] = object[i + 1] + end + h + end + + ## + # call-seq: + # Hash.try_convert(obj) -> hash or nil + # + # Try to convert obj into a hash, using to_hash method. + # Returns converted hash or nil if obj cannot be converted + # for any reason. + # + # Hash.try_convert({1=>2}) # => {1=>2} + # Hash.try_convert("1=>2") # => nil + # + def self.try_convert(obj) + if obj.respond_to?(:to_hash) + obj.to_hash + else + nil + end + end + + ## + # call-seq: + # hsh.merge!(other_hash) -> hsh + # hsh.merge!(other_hash){|key, oldval, newval| block} -> hsh + # + # Adds the contents of _other_hash_ to _hsh_. If no block is specified, + # entries with duplicate keys are overwritten with the values from + # _other_hash_, otherwise the value of each duplicate key is determined by + # calling the block with the key, its value in _hsh_ and its value in + # _other_hash_. + # + # h1 = { "a" => 100, "b" => 200 } + # h2 = { "b" => 254, "c" => 300 } + # h1.merge!(h2) #=> {"a"=>100, "b"=>254, "c"=>300} + # + # h1 = { "a" => 100, "b" => 200 } + # h2 = { "b" => 254, "c" => 300 } + # h1.merge!(h2) { |key, v1, v2| v1 } + # #=> {"a"=>100, "b"=>200, "c"=>300} + # + + def merge!(other, &block) + raise TypeError, "can't convert argument into Hash" unless other.respond_to?(:to_hash) + if block + other.each_key{|k| + self[k] = (self.has_key?(k))? block.call(k, self[k], other[k]): other[k] + } + else + other.each_key{|k| self[k] = other[k]} + end + self + end + + alias update merge! + + ## + # call-seq: + # hsh.compact -> new_hsh + # + # Returns a new hash with the nil values/key pairs removed + # + # h = { a: 1, b: false, c: nil } + # h.compact #=> { a: 1, b: false } + # h #=> { a: 1, b: false, c: nil } + # + def compact + result = self.dup + result.compact! + result + end + + ## + # call-seq: + # hsh.fetch(key [, default] ) -> obj + # hsh.fetch(key) {| key | block } -> obj + # + # Returns a value from the hash for the given key. If the key can't be + # found, there are several options: With no other arguments, it will + # raise an KeyError exception; if default is + # given, then that will be returned; if the optional code block is + # specified, then that will be run and its result returned. + # + # h = { "a" => 100, "b" => 200 } + # h.fetch("a") #=> 100 + # h.fetch("z", "go fish") #=> "go fish" + # h.fetch("z") { |el| "go fish, #{el}"} #=> "go fish, z" + # + # The following example shows that an exception is raised if the key + # is not found and a default value is not supplied. + # + # h = { "a" => 100, "b" => 200 } + # h.fetch("z") + # + # produces: + # + # prog.rb:2:in 'fetch': key not found (KeyError) + # from prog.rb:2 + # + + def fetch(key, none=NONE, &block) + unless self.key?(key) + if block + block.call(key) + elsif none != NONE + none + else + raise KeyError, "Key not found: #{key}" + end + else + self[key] + end + end + + ## + # call-seq: + # hsh.delete_if {| key, value | block } -> hsh + # hsh.delete_if -> an_enumerator + # + # Deletes every key-value pair from hsh for which block + # evaluates to true. + # + # If no block is given, an enumerator is returned instead. + # + # h = { "a" => 100, "b" => 200, "c" => 300 } + # h.delete_if {|key, value| key >= "b" } #=> {"a"=>100} + # + + def delete_if(&block) + return to_enum :delete_if unless block + + self.each do |k, v| + self.delete(k) if block.call(k, v) + end + self + end + + ## + # call-seq: + # hash.flatten -> an_array + # hash.flatten(level) -> an_array + # + # Returns a new array that is a one-dimensional flattening of this + # hash. That is, for every key or value that is an array, extract + # its elements into the new array. Unlike Array#flatten, this + # method does not flatten recursively by default. The optional + # level argument determines the level of recursion to flatten. + # + # a = {1=> "one", 2 => [2,"two"], 3 => "three"} + # a.flatten # => [1, "one", 2, [2, "two"], 3, "three"] + # a.flatten(2) # => [1, "one", 2, 2, "two", 3, "three"] + # + + def flatten(level=1) + self.to_a.flatten(level) + end + + ## + # call-seq: + # hsh.invert -> new_hash + # + # Returns a new hash created by using hsh's values as keys, and + # the keys as values. + # + # h = { "n" => 100, "m" => 100, "y" => 300, "d" => 200, "a" => 0 } + # h.invert #=> {0=>"a", 100=>"m", 200=>"d", 300=>"y"} + # + + def invert + h = self.class.new + self.each {|k, v| h[v] = k } + h + end + + ## + # call-seq: + # hsh.keep_if {| key, value | block } -> hsh + # hsh.keep_if -> an_enumerator + # + # Deletes every key-value pair from hsh for which block + # evaluates to false. + # + # If no block is given, an enumerator is returned instead. + # + + def keep_if(&block) + return to_enum :keep_if unless block + + keys = [] + self.each do |k, v| + unless block.call([k, v]) + self.delete(k) + end + end + self + end + + ## + # call-seq: + # hsh.key(value) -> key + # + # Returns the key of an occurrence of a given value. If the value is + # not found, returns nil. + # + # h = { "a" => 100, "b" => 200, "c" => 300, "d" => 300 } + # h.key(200) #=> "b" + # h.key(300) #=> "c" + # h.key(999) #=> nil + # + + def key(val) + self.each do |k, v| + return k if v == val + end + nil + end + + ## + # call-seq: + # hsh.to_h -> hsh or new_hash + # + # Returns +self+. If called on a subclass of Hash, converts + # the receiver to a Hash object. + # + def to_h + self + end + + ## + # call-seq: + # hash < other -> true or false + # + # Returns true if hash is subset of + # other. + # + # h1 = {a:1, b:2} + # h2 = {a:1, b:2, c:3} + # h1 < h2 #=> true + # h2 < h1 #=> false + # h1 < h1 #=> false + # + def <(hash) + begin + hash = hash.to_hash + rescue NoMethodError + raise TypeError, "can't convert #{hash.class} to Hash" + end + size < hash.size and all? {|key, val| + hash.key?(key) and hash[key] == val + } + end + + ## + # call-seq: + # hash <= other -> true or false + # + # Returns true if hash is subset of + # other or equals to other. + # + # h1 = {a:1, b:2} + # h2 = {a:1, b:2, c:3} + # h1 <= h2 #=> true + # h2 <= h1 #=> false + # h1 <= h1 #=> true + # + def <=(hash) + begin + hash = hash.to_hash + rescue NoMethodError + raise TypeError, "can't convert #{hash.class} to Hash" + end + size <= hash.size and all? {|key, val| + hash.key?(key) and hash[key] == val + } + end + + ## + # call-seq: + # hash > other -> true or false + # + # Returns true if other is subset of + # hash. + # + # h1 = {a:1, b:2} + # h2 = {a:1, b:2, c:3} + # h1 > h2 #=> false + # h2 > h1 #=> true + # h1 > h1 #=> false + # + def >(hash) + begin + hash = hash.to_hash + rescue NoMethodError + raise TypeError, "can't convert #{hash.class} to Hash" + end + size > hash.size and hash.all? {|key, val| + key?(key) and self[key] == val + } + end + + ## + # call-seq: + # hash >= other -> true or false + # + # Returns true if other is subset of + # hash or equals to hash. + # + # h1 = {a:1, b:2} + # h2 = {a:1, b:2, c:3} + # h1 >= h2 #=> false + # h2 >= h1 #=> true + # h1 >= h1 #=> true + # + def >=(hash) + begin + hash = hash.to_hash + rescue NoMethodError + raise TypeError, "can't convert #{hash.class} to Hash" + end + size >= hash.size and hash.all? {|key, val| + key?(key) and self[key] == val + } + end + + ## + # call-seq: + # hsh.dig(key,...) -> object + # + # Extracts the nested value specified by the sequence of key + # objects by calling +dig+ at each step, returning +nil+ if any + # intermediate step is +nil+. + # + def dig(idx,*args) + n = self[idx] + if args.size > 0 + n&.dig(*args) + else + n + end + end + + ## + # call-seq: + # hsh.transform_keys {|key| block } -> new_hash + # hsh.transform_keys -> an_enumerator + # + # Returns a new hash, with the keys computed from running the block + # once for each key in the hash, and the values unchanged. + # + # If no block is given, an enumerator is returned instead. + # + def transform_keys(&block) + return to_enum :transform_keys unless block + hash = {} + self.keys.each do |k| + new_key = block.call(k) + hash[new_key] = self[k] + end + hash + end + ## + # call-seq: + # hsh.transform_keys! {|key| block } -> hsh + # hsh.transform_keys! -> an_enumerator + # + # Invokes the given block once for each key in hsh, replacing it + # with the new key returned by the block, and then returns hsh. + # + # If no block is given, an enumerator is returned instead. + # + def transform_keys!(&block) + return to_enum :transform_keys! unless block + self.keys.each do |k| + value = self[k] + new_key = block.call(k) + self.__delete(k) + self[new_key] = value + end + self + end + ## + # call-seq: + # hsh.transform_values {|value| block } -> new_hash + # hsh.transform_values -> an_enumerator + # + # Returns a new hash with the results of running the block once for + # every value. + # This method does not change the keys. + # + # If no block is given, an enumerator is returned instead. + # + def transform_values(&b) + return to_enum :transform_values unless block_given? + hash = {} + self.keys.each do |k| + hash[k] = yield(self[k]) + end + hash + end + ## + # call-seq: + # hsh.transform_values! {|key| block } -> hsh + # hsh.transform_values! -> an_enumerator + # + # Invokes the given block once for each value in the hash, replacing + # with the new value returned by the block, and then returns hsh. + # + # If no block is given, an enumerator is returned instead. + # + def transform_values!(&b) + return to_enum :transform_values! unless block_given? + self.keys.each do |k| + self[k] = yield(self[k]) + end + self + end +end diff --git a/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-hash-ext/src/hash-ext.c b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-hash-ext/src/hash-ext.c new file mode 100644 index 00000000..952f2eb6 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-hash-ext/src/hash-ext.c @@ -0,0 +1,88 @@ +/* +** hash.c - Hash class +** +** See Copyright Notice in mruby.h +*/ + +#include +#include +#include + +/* + * call-seq: + * hsh.values_at(key, ...) -> array + * + * Return an array containing the values associated with the given keys. + * Also see Hash.select. + * + * h = { "cat" => "feline", "dog" => "canine", "cow" => "bovine" } + * h.values_at("cow", "cat") #=> ["bovine", "feline"] + */ + +static mrb_value +hash_values_at(mrb_state *mrb, mrb_value hash) +{ + mrb_value *argv, result; + mrb_int argc, i; + int ai; + + mrb_get_args(mrb, "*", &argv, &argc); + result = mrb_ary_new_capa(mrb, argc); + ai = mrb_gc_arena_save(mrb); + for (i = 0; i < argc; i++) { + mrb_ary_push(mrb, result, mrb_hash_get(mrb, hash, argv[i])); + mrb_gc_arena_restore(mrb, ai); + } + return result; +} + +/* + * call-seq: + * hsh.compact! -> hsh + * + * Removes all nil values from the hash. Returns the hash. + * + * h = { a: 1, b: false, c: nil } + * h.compact! #=> { a: 1, b: false } + */ +static mrb_value +hash_compact_bang(mrb_state *mrb, mrb_value hash) +{ + khiter_t k; + khash_t(ht) *h = RHASH_TBL(hash); + mrb_int n = -1; + + if (!h) return mrb_nil_value(); + for (k = kh_begin(h); k != kh_end(h); k++) { + if (kh_exist(h, k)) { + mrb_value val = kh_value(h, k).v; + khiter_t k2; + + if (mrb_nil_p(val)) { + kh_del(ht, mrb, h, k); + n = kh_value(h, k).n; + for (k2 = kh_begin(h); k2 != kh_end(h); k2++) { + if (!kh_exist(h, k2)) continue; + if (kh_value(h, k2).n > n) kh_value(h, k2).n--; + } + } + } + } + if (n < 0) return mrb_nil_value(); + return hash; +} + +void +mrb_mruby_hash_ext_gem_init(mrb_state *mrb) +{ + struct RClass *h; + + h = mrb->hash_class; + mrb_define_method(mrb, h, "values_at", hash_values_at, MRB_ARGS_ANY()); + mrb_define_method(mrb, h, "compact!", hash_compact_bang, MRB_ARGS_NONE()); +} + +void +mrb_mruby_hash_ext_gem_final(mrb_state *mrb) +{ +} diff --git a/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-hash-ext/test/hash.rb b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-hash-ext/test/hash.rb new file mode 100644 index 00000000..ca4e346f --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-hash-ext/test/hash.rb @@ -0,0 +1,294 @@ +## +# Hash(Ext) Test + +assert('Hash.[] Hash') do + a = Hash['a_key' => 'a_value'] + + assert_equal({'a_key' => 'a_value'}, a) +end + +assert('Hash.[] [ [ ["b_key", "b_value" ] ] ]') do + a = Hash[ [ ['b_key', 'b_value'] ] ] + + assert_equal({'b_key' => 'b_value'}, a) + + a = Hash[ [ ] ] + + assert_equal({}, a) + + assert_raise(ArgumentError) do + Hash[ [ ['b_key', 'b_value', 'b_over'] ] ] + end + + assert_raise(ArgumentError) do + Hash[ [ [] ] ] + end +end + +assert('Hash.[] "c_key", "c_value"') do + a = Hash['c_key', 'c_value', 'd_key', 1] + + assert_equal({'c_key' => 'c_value', 'd_key' => 1}, a) + + a = Hash[] + + assert_equal({}, a) + + assert_raise(ArgumentError) do + Hash['d_key'] + end +end + +assert('Hash.[] for sub class') do + sub_hash_class = Class.new(Hash) + sub_hash = sub_hash_class[] + assert_equal(sub_hash_class, sub_hash.class) +end + +assert('Hash.try_convert') do + assert_nil Hash.try_convert(nil) + assert_nil Hash.try_convert("{1=>2}") + assert_equal({1=>2}, Hash.try_convert({1=>2})) +end + +assert('Hash#merge!') do + a = { 'abc_key' => 'abc_value', 'cba_key' => 'cba_value' } + b = { 'cba_key' => 'XXX', 'xyz_key' => 'xyz_value' } + + result_1 = a.merge! b + + a = { 'abc_key' => 'abc_value', 'cba_key' => 'cba_value' } + result_2 = a.merge!(b) do |key, original, new| + original + end + + assert_equal({'abc_key' => 'abc_value', 'cba_key' => 'XXX', + 'xyz_key' => 'xyz_value' }, result_1) + assert_equal({'abc_key' => 'abc_value', 'cba_key' => 'cba_value', + 'xyz_key' => 'xyz_value' }, result_2) + + assert_raise(TypeError) do + { 'abc_key' => 'abc_value' }.merge! "a" + end +end + +assert('Hash#values_at') do + h = { "cat" => "feline", "dog" => "canine", "cow" => "bovine" } + assert_equal ["bovine", "feline"], h.values_at("cow", "cat") + + keys = [] + (0...1000).each { |v| keys.push "#{v}" } + h = Hash.new { |hash,k| hash[k] = k } + assert_equal keys, h.values_at(*keys) +end + +assert('Hash#compact') do + h = { "cat" => "feline", "dog" => nil, "cow" => false } + + assert_equal({ "cat" => "feline", "cow" => false }, h.compact) + assert_equal({ "cat" => "feline", "dog" => nil, "cow" => false }, h) +end + +assert('Hash#compact!') do + h = { "cat" => "feline", "dog" => nil, "cow" => false } + + h.compact! + assert_equal({ "cat" => "feline", "cow" => false }, h) +end + +assert('Hash#fetch') do + h = { "cat" => "feline", "dog" => "canine", "cow" => "bovine" } + assert_equal "feline", h.fetch("cat") + assert_equal "mickey", h.fetch("mouse", "mickey") + assert_equal "minny", h.fetch("mouse"){"minny"} + assert_equal "mouse", h.fetch("mouse"){|k| k} + assert_raise(KeyError) do + h.fetch("gnu") + end +end + +assert("Hash#delete_if") do + base = { 1 => 'one', 2 => false, true => 'true', 'cat' => 99 } + h1 = { 1 => 'one', 2 => false, true => 'true' } + h2 = { 2 => false, 'cat' => 99 } + h3 = { 2 => false } + + h = base.dup + assert_equal(h, h.delete_if { false }) + assert_equal({}, h.delete_if { true }) + + h = base.dup + assert_equal(h1, h.delete_if {|k,v| k.instance_of?(String) }) + assert_equal(h1, h) + + h = base.dup + assert_equal(h2, h.delete_if {|k,v| v.instance_of?(String) }) + assert_equal(h2, h) + + h = base.dup + assert_equal(h3, h.delete_if {|k,v| v }) + assert_equal(h3, h) + + h = base.dup + n = 0 + h.delete_if {|*a| + n += 1 + assert_equal(2, a.size) + assert_equal(base[a[0]], a[1]) + h.shift + true + } + assert_equal(base.size, n) +end + +assert("Hash#flatten") do + a = {1=> "one", 2 => [2,"two"], 3 => [3, ["three"]]} + assert_equal [1, "one", 2, [2, "two"], 3, [3, ["three"]]], a.flatten + assert_equal [[1, "one"], [2, [2, "two"]], [3, [3, ["three"]]]], a.flatten(0) + assert_equal [1, "one", 2, [2, "two"], 3, [3, ["three"]]], a.flatten(1) + assert_equal [1, "one", 2, 2, "two", 3, 3, ["three"]], a.flatten(2) + assert_equal [1, "one", 2, 2, "two", 3, 3, "three"], a.flatten(3) +end + +assert("Hash#invert") do + h = { 1 => 'one', 2 => 'two', 3 => 'three', + true => 'true', nil => 'nil' }.invert + assert_equal 1, h['one'] + assert_equal true, h['true'] + assert_equal nil, h['nil'] + + h = { 'a' => 1, 'b' => 2, 'c' => 1 }.invert + assert_equal(2, h.length) + assert_include(%w[a c], h[1]) + assert_equal('b', h[2]) +end + +assert("Hash#invert with sub class") do + sub_hash_class = Class.new(Hash) + sub_hash = sub_hash_class.new + assert_equal(sub_hash_class, sub_hash.invert.class) +end + +assert("Hash#keep_if") do + h = { 1 => 2, 3 => 4, 5 => 6 } + assert_equal({3=>4,5=>6}, h.keep_if {|k, v| k + v >= 7 }) + h = { 1 => 2, 3 => 4, 5 => 6 } + assert_equal({ 1 => 2, 3=> 4, 5 =>6} , h.keep_if { true }) +end + +assert("Hash#key") do + h = { "a" => 100, "b" => 200, "c" => 300, "d" => 300, nil => 'nil', 'nil' => nil } + assert_equal "b", h.key(200) + assert_equal "c", h.key(300) + assert_nil h.key(999) + assert_nil h.key('nil') + assert_equal 'nil', h.key(nil) +end + +assert("Hash#to_h") do + h = { "a" => 100, "b" => 200 } + assert_equal Hash, h.to_h.class + assert_equal h, h.to_h +end + +assert('Hash#<') do + h1 = {a:1, b:2} + h2 = {a:1, b:2, c:3} + + assert_false(h1 < h1) + assert_true(h1 < h2) + assert_false(h2 < h1) + assert_false(h2 < h2) + + h1 = {a:1} + h2 = {a:2} + + assert_false(h1 < h1) + assert_false(h1 < h2) + assert_false(h2 < h1) + assert_false(h2 < h2) +end + +assert('Hash#<=') do + h1 = {a:1, b:2} + h2 = {a:1, b:2, c:3} + + assert_true(h1 <= h1) + assert_true(h1 <= h2) + assert_false(h2 <= h1) + assert_true(h2 <= h2) + + h1 = {a:1} + h2 = {a:2} + + assert_true(h1 <= h1) + assert_false(h1 <= h2) + assert_false(h2 <= h1) + assert_true(h2 <= h2) +end + +assert('Hash#>=') do + h1 = {a:1, b:2} + h2 = {a:1, b:2, c:3} + + assert_true(h1 >= h1) + assert_false(h1 >= h2) + assert_true(h2 >= h1) + assert_true(h2 >= h2) + + h1 = {a:1} + h2 = {a:2} + + assert_true(h1 >= h1) + assert_false(h1 >= h2) + assert_false(h2 >= h1) + assert_true(h2 >= h2) +end + +assert('Hash#>') do + h1 = {a:1, b:2} + h2 = {a:1, b:2, c:3} + + assert_false(h1 > h1) + assert_false(h1 > h2) + assert_true(h2 > h1) + assert_false(h2 > h2) + + h1 = {a:1} + h2 = {a:2} + + assert_false(h1 > h1) + assert_false(h1 > h2) + assert_false(h2 > h1) + assert_false(h2 > h2) +end + +assert("Hash#dig") do + h = {a:{b:{c:1}}} + assert_equal(1, h.dig(:a, :b, :c)) + assert_nil(h.dig(:d)) +end + +assert("Hash#transform_keys") do + h = {"1" => 100, "2" => 200} + assert_equal(h.transform_keys{|k| k+"!"}, + {"1!" => 100, "2!" => 200}) + assert_equal(h.transform_keys{|k|k.to_i}, + {1 => 100, 2 => 200}) + assert_equal(h.transform_keys.with_index{|k, i| "#{k}.#{i}"}, + {"1.0" => 100, "2.1" => 200}) + assert_equal(h.transform_keys!{|k|k.to_i}, h) + assert_equal(h, {1 => 100, 2 => 200}) +end + +assert("Hash#transform_values") do + h = {a: 1, b: 2, c: 3} + assert_equal(h.transform_values{|v| v * v + 1}, + {a: 2, b: 5, c: 10}) + assert_equal(h.transform_values{|v|v.to_s}, + {a: "1", b: "2", c: "3"}) + assert_equal(h.transform_values.with_index{|v, i| "#{v}.#{i}"}, + {a: "1.0", b: "2.1", c: "3.2"}) + assert_equal(h.transform_values!{|v|v.to_s}, h) + assert_equal(h, {a: "1", b: "2", c: "3"}) +end diff --git a/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-inline-struct/mrbgem.rake b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-inline-struct/mrbgem.rake new file mode 100644 index 00000000..91ad9f44 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-inline-struct/mrbgem.rake @@ -0,0 +1,5 @@ +MRuby::Gem::Specification.new('mruby-inline-struct') do |spec| + spec.license = 'MIT' + spec.author = 'mruby developers' + spec.summary = 'inline structure' +end diff --git a/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-inline-struct/test/inline.c b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-inline-struct/test/inline.c new file mode 100644 index 00000000..0baaab61 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-inline-struct/test/inline.c @@ -0,0 +1,83 @@ +#include +#include +#include +#include + +static mrb_value +istruct_test_initialize(mrb_state *mrb, mrb_value self) +{ + char *string = (char*)mrb_istruct_ptr(self); + mrb_int size = mrb_istruct_size(); + mrb_value object; + mrb_get_args(mrb, "o", &object); + + if (mrb_float_p(object)) + { + snprintf(string, size, "float(%.3f)", mrb_float(object)); + } + else if (mrb_fixnum_p(object)) + { + snprintf(string, size, "fixnum(%" MRB_PRId ")", mrb_fixnum(object)); + } + else if (mrb_string_p(object)) + { + snprintf(string, size, "string(%s)", mrb_string_value_cstr(mrb, &object)); + } + + string[size - 1] = 0; // force NULL at the end + return self; +} + +static mrb_value +istruct_test_to_s(mrb_state *mrb, mrb_value self) +{ + return mrb_str_new_cstr(mrb, (const char*)mrb_istruct_ptr(self)); +} + +static mrb_value +istruct_test_length(mrb_state *mrb, mrb_value self) +{ + return mrb_fixnum_value(mrb_istruct_size()); +} + +static mrb_value +istruct_test_test_receive(mrb_state *mrb, mrb_value self) +{ + mrb_value object; + mrb_get_args(mrb, "o", &object); + if (mrb_obj_class(mrb, object) != mrb_class_get(mrb, "InlineStructTest")) + { + mrb_raisef(mrb, E_TYPE_ERROR, "Expected InlineStructTest"); + } + return mrb_bool_value(((char*)mrb_istruct_ptr(object))[0] == 's'); +} + +static mrb_value +istruct_test_test_receive_direct(mrb_state *mrb, mrb_value self) +{ + char *ptr; + mrb_get_args(mrb, "I", &ptr); + return mrb_bool_value(ptr[0] == 's'); +} + +static mrb_value +istruct_test_mutate(mrb_state *mrb, mrb_value self) +{ + char *ptr = (char*)mrb_istruct_ptr(self); + memcpy(ptr, "mutate", 6); + return mrb_nil_value(); +} + +void mrb_mruby_inline_struct_gem_test(mrb_state *mrb) +{ + struct RClass *cls; + + cls = mrb_define_class(mrb, "InlineStructTest", mrb->object_class); + MRB_SET_INSTANCE_TT(cls, MRB_TT_ISTRUCT); + mrb_define_method(mrb, cls, "initialize", istruct_test_initialize, MRB_ARGS_REQ(1)); + mrb_define_method(mrb, cls, "to_s", istruct_test_to_s, MRB_ARGS_NONE()); + mrb_define_method(mrb, cls, "mutate", istruct_test_mutate, MRB_ARGS_NONE()); + mrb_define_class_method(mrb, cls, "length", istruct_test_length, MRB_ARGS_NONE()); + mrb_define_class_method(mrb, cls, "test_receive", istruct_test_test_receive, MRB_ARGS_REQ(1)); + mrb_define_class_method(mrb, cls, "test_receive_direct", istruct_test_test_receive_direct, MRB_ARGS_REQ(1)); +} diff --git a/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-inline-struct/test/inline.rb b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-inline-struct/test/inline.rb new file mode 100644 index 00000000..49585923 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-inline-struct/test/inline.rb @@ -0,0 +1,151 @@ +## +# InlineStruct Test + +class InlineStructTest + def extra_method + :ok + end + + def test_ivar_set + @var = :ivar + end + + def test_ivar_get + @vat + end +end + +assert('InlineStructTest#dup') do + obj = InlineStructTest.new(1) + assert_equal obj.to_s, 'fixnum(1)' + assert_equal obj.dup.to_s, 'fixnum(1)' +end + +assert('InlineStructTest#clone') do + obj = InlineStructTest.new(1) + assert_equal obj.to_s, 'fixnum(1)' + assert_equal obj.clone.to_s, 'fixnum(1)' +end + +assert('InlineStruct#object_id') do + obj1 = InlineStructTest.new(1) + obj2 = InlineStructTest.new(1) + assert_not_equal obj1, obj2 + assert_not_equal obj1.object_id, obj2.object_id + assert_not_equal obj1.object_id, obj1.dup.object_id + assert_not_equal obj1.object_id, obj1.clone.object_id +end + +assert('InlineStructTest#mutate (dup)') do + obj1 = InlineStructTest.new("foo") + assert_equal obj1.to_s, "string(foo)" + obj2 = obj1.dup + assert_equal obj2.to_s, "string(foo)" + obj1.mutate + assert_equal obj1.to_s, "mutate(foo)" + assert_equal obj2.to_s, "string(foo)" +end + +assert('InlineStructTest#mutate (clone)') do + obj1 = InlineStructTest.new("foo") + assert_equal obj1.to_s, "string(foo)" + obj2 = obj1.clone + assert_equal obj2.to_s, "string(foo)" + obj1.mutate + assert_equal obj1.to_s, "mutate(foo)" + assert_equal obj2.to_s, "string(foo)" +end + +assert('InlineStructTest#test_receive(string)') do + assert_equal InlineStructTest.test_receive(InlineStructTest.new('a')), true +end + +assert('InlineStructTest#test_receive(float)') do + assert_equal InlineStructTest.test_receive(InlineStructTest.new(1.25)), false +end + +assert('InlineStructTest#test_receive(invalid object)') do + assert_raise(TypeError) do + InlineStructTest.test_receive([]) + end +end + +assert('InlineStructTest#test_receive(string)') do + assert_equal InlineStructTest.test_receive_direct(InlineStructTest.new('a')), true +end + +assert('InlineStructTest#test_receive(float)') do + assert_equal InlineStructTest.test_receive_direct(InlineStructTest.new(1.25)), false +end + +assert('InlineStructTest#test_receive(invalid object)') do + assert_raise(TypeError) do + InlineStructTest.test_receive_direct([]) + end +end + +assert('InlineStructTest#extra_method') do + assert_equal InlineStructTest.new(1).extra_method, :ok +end + +assert('InlineStructTest instance variable') do + obj = InlineStructTest.new(1) + assert_raise(ArgumentError) do + obj.test_ivar_set + end + assert_equal obj.test_ivar_get, nil +end + +# 64-bit mode +if InlineStructTest.length == 24 + assert('InlineStructTest length [64 bit]') do + assert_equal InlineStructTest.length, 3 * 8 + end + + assert('InlineStructTest w/float [64 bit]') do + obj = InlineStructTest.new(1.25) + assert_equal obj.to_s, "float(1.250)" + end + + assert('InlineStructTest w/fixnum [64 bit]') do + obj = InlineStructTest.new(42) + assert_equal obj.to_s, "fixnum(42)" + end + + assert('InlineStructTest w/string [64 bit]') do + obj = InlineStructTest.new("hello") + assert_equal obj.to_s, "string(hello)" + end + + assert('InlineStructTest w/long string [64 bit]') do + obj = InlineStructTest.new("this won't fit in 3 * 8 bytes available for the structure") + assert_equal obj.to_s, "string(this won't fit i" + end +end + +# 32-bit mode +if InlineStructTest.length == 12 + assert('InlineStructTest length [32 bit]') do + assert_equal InlineStructTest.length, 3 * 4 + end + + assert('InlineStructTest w/float [32 bit]') do + obj = InlineStructTest.new(1.25) + assert_equal obj.to_s, "float(1.250" + end + + assert('InlineStructTest w/fixnum [32 bit]') do + obj = InlineStructTest.new(42) + assert_equal obj.to_s, "fixnum(42)" + end + + assert('InlineStructTest w/string [32 bit]') do + obj = InlineStructTest.new("hello") + assert_equal obj.to_s, "string(hell" + end + + assert('InlineStructTest w/long string [32 bit]') do + obj = InlineStructTest.new("this won't fit in 3 * 4 bytes available for the structure") + assert_equal obj.to_s, "string(this" + end +end diff --git a/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-kernel-ext/mrbgem.rake b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-kernel-ext/mrbgem.rake new file mode 100644 index 00000000..fcb3a83b --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-kernel-ext/mrbgem.rake @@ -0,0 +1,5 @@ +MRuby::Gem::Specification.new('mruby-kernel-ext') do |spec| + spec.license = 'MIT' + spec.author = 'mruby developers' + spec.summary = 'Kernel module extension' +end diff --git a/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-kernel-ext/src/kernel.c b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-kernel-ext/src/kernel.c new file mode 100644 index 00000000..7e6fa28b --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-kernel-ext/src/kernel.c @@ -0,0 +1,243 @@ +#include +#include +#include +#include +#include + +static mrb_value +mrb_f_caller(mrb_state *mrb, mrb_value self) +{ + mrb_value bt, v, length; + mrb_int bt_len, argc, lev, n; + + bt = mrb_get_backtrace(mrb); + bt_len = RARRAY_LEN(bt); + argc = mrb_get_args(mrb, "|oo", &v, &length); + + switch (argc) { + case 0: + lev = 1; + n = bt_len - lev; + break; + case 1: + if (mrb_type(v) == MRB_TT_RANGE) { + mrb_int beg, len; + if (mrb_range_beg_len(mrb, v, &beg, &len, bt_len, TRUE) == 1) { + lev = beg; + n = len; + } + else { + return mrb_nil_value(); + } + } + else { + v = mrb_to_int(mrb, v); + lev = mrb_fixnum(v); + if (lev < 0) { + mrb_raisef(mrb, E_ARGUMENT_ERROR, "negative level (%S)", v); + } + n = bt_len - lev; + } + break; + case 2: + lev = mrb_fixnum(mrb_to_int(mrb, v)); + n = mrb_fixnum(mrb_to_int(mrb, length)); + if (lev < 0) { + mrb_raisef(mrb, E_ARGUMENT_ERROR, "negative level (%S)", v); + } + if (n < 0) { + mrb_raisef(mrb, E_ARGUMENT_ERROR, "negative size (%S)", length); + } + break; + default: + lev = n = 0; + break; + } + + if (n == 0) { + return mrb_ary_new(mrb); + } + + return mrb_funcall(mrb, bt, "[]", 2, mrb_fixnum_value(lev), mrb_fixnum_value(n)); +} + +/* + * call-seq: + * __method__ -> symbol + * + * Returns the name at the definition of the current method as a + * Symbol. + * If called outside of a method, it returns nil. + * + */ +static mrb_value +mrb_f_method(mrb_state *mrb, mrb_value self) +{ + mrb_callinfo *ci = mrb->c->ci; + ci--; + if (ci->mid) + return mrb_symbol_value(ci->mid); + else + return mrb_nil_value(); +} + +/* + * call-seq: + * Integer(arg,base=0) -> integer + * + * Converts arg to a Fixnum. + * Numeric types are converted directly (with floating point numbers + * being truncated). base (0, or between 2 and 36) is a base for + * integer string representation. If arg is a String, + * when base is omitted or equals to zero, radix indicators + * (0, 0b, and 0x) are honored. + * In any case, strings should be strictly conformed to numeric + * representation. This behavior is different from that of + * String#to_i. Non string values will be converted using + * to_int, and to_i. Passing nil + * raises a TypeError. + * + * Integer(123.999) #=> 123 + * Integer("0x1a") #=> 26 + * Integer(Time.new) #=> 1204973019 + * Integer("0930", 10) #=> 930 + * Integer("111", 2) #=> 7 + * Integer(nil) #=> TypeError + */ +static mrb_value +mrb_f_integer(mrb_state *mrb, mrb_value self) +{ + mrb_value arg; + mrb_int base = 0; + + mrb_get_args(mrb, "o|i", &arg, &base); + return mrb_convert_to_integer(mrb, arg, base); +} + +/* + * call-seq: + * Float(arg) -> float + * + * Returns arg converted to a float. Numeric types are converted + * directly, the rest are converted using arg.to_f. + * + * Float(1) #=> 1.0 + * Float(123.456) #=> 123.456 + * Float("123.456") #=> 123.456 + * Float(nil) #=> TypeError + */ +static mrb_value +mrb_f_float(mrb_state *mrb, mrb_value self) +{ + mrb_value arg; + + mrb_get_args(mrb, "o", &arg); + return mrb_Float(mrb, arg); +} + +/* + * call-seq: + * String(arg) -> string + * + * Returns arg as an String. + * + * First tries to call its to_str method, then its to_s method. + * + * String(self) #=> "main" + * String(self.class) #=> "Object" + * String(123456) #=> "123456" + */ +static mrb_value +mrb_f_string(mrb_state *mrb, mrb_value self) +{ + mrb_value arg, tmp; + + mrb_get_args(mrb, "o", &arg); + tmp = mrb_check_convert_type(mrb, arg, MRB_TT_STRING, "String", "to_str"); + if (mrb_nil_p(tmp)) { + tmp = mrb_check_convert_type(mrb, arg, MRB_TT_STRING, "String", "to_s"); + } + return tmp; +} + +/* + * call-seq: + * Array(arg) -> array + * + * Returns +arg+ as an Array. + * + * First tries to call Array#to_ary on +arg+, then Array#to_a. + * + * Array(1..5) #=> [1, 2, 3, 4, 5] + * + */ +static mrb_value +mrb_f_array(mrb_state *mrb, mrb_value self) +{ + mrb_value arg, tmp; + + mrb_get_args(mrb, "o", &arg); + tmp = mrb_check_convert_type(mrb, arg, MRB_TT_ARRAY, "Array", "to_ary"); + if (mrb_nil_p(tmp)) { + tmp = mrb_check_convert_type(mrb, arg, MRB_TT_ARRAY, "Array", "to_a"); + } + if (mrb_nil_p(tmp)) { + return mrb_ary_new_from_values(mrb, 1, &arg); + } + + return tmp; +} + +/* + * call-seq: + * Hash(arg) -> hash + * + * Converts arg to a Hash by calling + * arg.to_hash. Returns an empty Hash when + * arg is nil or []. + * + * Hash([]) #=> {} + * Hash(nil) #=> {} + * Hash(key: :value) #=> {:key => :value} + * Hash([1, 2, 3]) #=> TypeError + * + */ +static mrb_value +mrb_f_hash(mrb_state *mrb, mrb_value self) +{ + mrb_value arg, tmp; + + mrb_get_args(mrb, "o", &arg); + if (mrb_nil_p(arg)) { + return mrb_hash_new(mrb); + } + tmp = mrb_check_convert_type(mrb, arg, MRB_TT_HASH, "Hash", "to_hash"); + if (mrb_nil_p(tmp)) { + if (mrb_array_p(arg) && RARRAY_LEN(arg) == 0) { + return mrb_hash_new(mrb); + } + mrb_raisef(mrb, E_TYPE_ERROR, "can't convert %S into Hash", + mrb_str_new_cstr(mrb, mrb_obj_classname(mrb, arg))); + } + return tmp; +} + +void +mrb_mruby_kernel_ext_gem_init(mrb_state *mrb) +{ + struct RClass *krn = mrb->kernel_module; + + mrb_define_module_function(mrb, krn, "fail", mrb_f_raise, MRB_ARGS_OPT(2)); + mrb_define_module_function(mrb, krn, "caller", mrb_f_caller, MRB_ARGS_OPT(2)); + mrb_define_method(mrb, krn, "__method__", mrb_f_method, MRB_ARGS_NONE()); + mrb_define_module_function(mrb, krn, "Integer", mrb_f_integer, MRB_ARGS_ANY()); + mrb_define_module_function(mrb, krn, "Float", mrb_f_float, MRB_ARGS_REQ(1)); + mrb_define_module_function(mrb, krn, "String", mrb_f_string, MRB_ARGS_REQ(1)); + mrb_define_module_function(mrb, krn, "Array", mrb_f_array, MRB_ARGS_REQ(1)); + mrb_define_module_function(mrb, krn, "Hash", mrb_f_hash, MRB_ARGS_REQ(1)); +} + +void +mrb_mruby_kernel_ext_gem_final(mrb_state *mrb) +{ +} diff --git a/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-kernel-ext/test/kernel.rb b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-kernel-ext/test/kernel.rb new file mode 100644 index 00000000..89cedaf2 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-kernel-ext/test/kernel.rb @@ -0,0 +1,86 @@ +assert('Kernel.fail, Kernel#fail') do + assert_raise(RuntimeError) { fail } + assert_raise(RuntimeError) { Kernel.fail } +end + +assert('Kernel.caller, Kernel#caller') do + skip "backtrace isn't available" if caller(0).empty? + + caller_lineno = __LINE__ + 3 + c = Class.new do + def foo(*args) + caller(*args) + end + + def bar(*args) + foo(*args) + end + + def baz(*args) + bar(*args) + end + end + assert_equal "kernel.rb:#{caller_lineno}:in foo", c.new.baz(0)[0][-19..-1] + assert_equal "bar", c.new.baz[0][-3..-1] + assert_equal "foo", c.new.baz(0)[0][-3..-1] + assert_equal "bar", c.new.baz(1)[0][-3..-1] + assert_equal "baz", c.new.baz(2)[0][-3..-1] + assert_equal ["foo", "bar"], c.new.baz(0, 2).map { |i| i[-3..-1] } + assert_equal ["bar", "baz"], c.new.baz(1..2).map { |i| i[-3..-1] } + assert_nil c.new.baz(10..20) + assert_raise(ArgumentError) { c.new.baz(-1) } + assert_raise(ArgumentError) { c.new.baz(-1, 1) } + assert_raise(ArgumentError) { c.new.baz(1, -1) } + assert_raise(TypeError) { c.new.baz(nil) } +end + +assert('Kernel#__method__') do + assert_equal(:m, Class.new {def m; __method__; end}.new.m) + assert_equal(:m, Class.new {define_method(:m) {__method__}}.new.m) + c = Class.new do + [:m1, :m2].each do |m| + define_method(m) do + __method__ + end + end + end + assert_equal(:m1, c.new.m1) + assert_equal(:m2, c.new.m2) +end + +assert('Kernel#Integer') do + assert_equal(123, Integer(123.999)) + assert_equal(26, Integer("0x1a")) + assert_equal(930, Integer("0930", 10)) + assert_equal(7, Integer("111", 2)) + assert_equal(0, Integer("0")) + assert_equal(0, Integer("00000")) + assert_raise(TypeError) { Integer(nil) } +end + +assert('Kernel#Float') do + assert_equal(1.0, Float(1)) + assert_equal(123.456, Float(123.456)) + assert_equal(123.456, Float("123.456")) + assert_raise(TypeError) { Float(nil) } +end + +assert('Kernel#String') do + assert_equal("main", String(self)) + assert_equal("Object", String(self.class)) + assert_equal("123456", String(123456)) +end + +assert('Kernel#Array') do + assert_equal([1], Kernel.Array(1)) + assert_equal([1, 2, 3, 4, 5], Kernel.Array([1, 2, 3, 4, 5])) + assert_equal([1, 2, 3, 4, 5], Kernel.Array(1..5)) + assert_equal([[:a, 1], [:b, 2], [:c, 3]], Kernel.Array({a:1, b:2, c:3})) +end + +assert('Kernel#Hash') do + assert_equal({}, Hash([])) + assert_equal({}, Hash(nil)) + assert_equal({:key => :value}, Hash(key: :value)) + assert_raise(TypeError) { Hash([1, 2, 3]) } +end diff --git a/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-math/mrbgem.rake b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-math/mrbgem.rake new file mode 100644 index 00000000..66eb5c8d --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-math/mrbgem.rake @@ -0,0 +1,5 @@ +MRuby::Gem::Specification.new('mruby-math') do |spec| + spec.license = 'MIT' + spec.author = 'mruby developers' + spec.summary = 'standard Math module' +end diff --git a/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-math/src/math.c b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-math/src/math.c new file mode 100644 index 00000000..7302b92d --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-math/src/math.c @@ -0,0 +1,783 @@ +/* +** math.c - Math module +** +** See Copyright Notice in mruby.h +*/ + +#include +#include + +#include + +static void +domain_error(mrb_state *mrb, const char *func) +{ + struct RClass *math = mrb_module_get(mrb, "Math"); + struct RClass *domainerror = mrb_class_get_under(mrb, math, "DomainError"); + mrb_value str = mrb_str_new_cstr(mrb, func); + mrb_raisef(mrb, domainerror, "Numerical argument is out of domain - %S", str); +} + +/* math functions not provided by Microsoft Visual C++ 2012 or older */ +#if defined _MSC_VER && _MSC_VER <= 1700 + +#include + +#define MATH_TOLERANCE 1E-12 + +double +asinh(double x) +{ + double xa, ya, y; + + /* Basic formula loses precision for x < 0, but asinh is an odd function */ + xa = fabs(x); + if (xa > 3.16227E+18) { + /* Prevent x*x from overflowing; basic formula reduces to log(2*x) */ + ya = log(xa) + 0.69314718055994530942; + } + else { + /* Basic formula for asinh */ + ya = log(xa + sqrt(xa*xa + 1.0)); + } + + y = _copysign(ya, x); + return y; +} + +double +acosh(double x) +{ + double y; + + if (x > 3.16227E+18) { + /* Prevent x*x from overflowing; basic formula reduces to log(2*x) */ + y = log(x) + 0.69314718055994530942; + } + else { + /* Basic formula for acosh */ + y = log(x + sqrt(x*x - 1.0)); + } + + return y; +} + +double +atanh(double x) +{ + double y; + + if (fabs(x) < 1E-2) { + /* The sums 1+x and 1-x lose precision for small x. Use the polynomial + instead. */ + double x2 = x * x; + y = x*(1.0 + x2*(1.0/3.0 + x2*(1.0/5.0 + x2*(1.0/7.0)))); + } + else { + /* Basic formula for atanh */ + y = 0.5 * (log(1.0+x) - log(1.0-x)); + } + + return y; +} + +double +cbrt(double x) +{ + double xa, ya, y; + + /* pow(x, y) is undefined for x < 0 and y not an integer, but cbrt is an + odd function */ + xa = fabs(x); + ya = pow(xa, 1.0/3.0); + y = _copysign(ya, x); + return y; +} + +/* Declaration of complementary Error function */ +double +erfc(double x); + +/* +** Implementations of error functions +** credits to http://www.digitalmars.com/archives/cplusplus/3634.html +*/ + +/* Implementation of Error function */ +double +erf(double x) +{ + static const double two_sqrtpi = 1.128379167095512574; + double sum = x; + double term = x; + double xsqr = x*x; + int j= 1; + if (fabs(x) > 2.2) { + return 1.0 - erfc(x); + } + do { + term *= xsqr/j; + sum -= term/(2*j+1); + ++j; + term *= xsqr/j; + sum += term/(2*j+1); + ++j; + } while (fabs(term/sum) > MATH_TOLERANCE); + return two_sqrtpi*sum; +} + +/* Implementation of complementary Error function */ +double +erfc(double x) +{ + static const double one_sqrtpi= 0.564189583547756287; + double a = 1; + double b = x; + double c = x; + double d = x*x+0.5; + double q1; + double q2 = b/d; + double n = 1.0; + double t; + if (fabs(x) < 2.2) { + return 1.0 - erf(x); + } + if (x < 0.0) { /*signbit(x)*/ + return 2.0 - erfc(-x); + } + do { + t = a*n+b*x; + a = b; + b = t; + t = c*n+d*x; + c = d; + d = t; + n += 0.5; + q1 = q2; + q2 = b/d; + } while (fabs(q1-q2)/q2 > MATH_TOLERANCE); + return one_sqrtpi*exp(-x*x)*q2; +} + +#endif + +#if (defined _MSC_VER && _MSC_VER < 1800) || defined __ANDROID__ || (defined __FreeBSD__ && __FreeBSD_version < 803000) + +double +log2(double x) +{ + return log10(x)/log10(2.0); +} + +#endif + +/* + TRIGONOMETRIC FUNCTIONS +*/ + +/* + * call-seq: + * Math.sin(x) -> float + * + * Computes the sine of x (expressed in radians). Returns + * -1..1. + */ +static mrb_value +math_sin(mrb_state *mrb, mrb_value obj) +{ + mrb_float x; + + mrb_get_args(mrb, "f", &x); + x = sin(x); + + return mrb_float_value(mrb, x); +} + +/* + * call-seq: + * Math.cos(x) -> float + * + * Computes the cosine of x (expressed in radians). Returns + * -1..1. + */ +static mrb_value +math_cos(mrb_state *mrb, mrb_value obj) +{ + mrb_float x; + + mrb_get_args(mrb, "f", &x); + x = cos(x); + + return mrb_float_value(mrb, x); +} + +/* + * call-seq: + * Math.tan(x) -> float + * + * Returns the tangent of x (expressed in radians). + */ +static mrb_value +math_tan(mrb_state *mrb, mrb_value obj) +{ + mrb_float x; + + mrb_get_args(mrb, "f", &x); + x = tan(x); + + return mrb_float_value(mrb, x); +} + +/* + INVERSE TRIGONOMETRIC FUNCTIONS +*/ + +/* + * call-seq: + * Math.asin(x) -> float + * + * Computes the arc sine of x. + * @return computed value between `-(PI/2)` and `(PI/2)`. + */ +static mrb_value +math_asin(mrb_state *mrb, mrb_value obj) +{ + mrb_float x; + + mrb_get_args(mrb, "f", &x); + if (x < -1.0 || x > 1.0) { + domain_error(mrb, "asin"); + } + x = asin(x); + + return mrb_float_value(mrb, x); +} + +/* + * call-seq: + * Math.acos(x) -> float + * + * Computes the arc cosine of x. Returns 0..PI. + */ +static mrb_value +math_acos(mrb_state *mrb, mrb_value obj) +{ + mrb_float x; + + mrb_get_args(mrb, "f", &x); + if (x < -1.0 || x > 1.0) { + domain_error(mrb, "acos"); + } + x = acos(x); + + return mrb_float_value(mrb, x); +} + +/* + * call-seq: + * Math.atan(x) -> float + * + * Computes the arc tangent of x. Returns `-(PI/2) .. (PI/2)`. + */ +static mrb_value +math_atan(mrb_state *mrb, mrb_value obj) +{ + mrb_float x; + + mrb_get_args(mrb, "f", &x); + x = atan(x); + + return mrb_float_value(mrb, x); +} + +/* + * call-seq: + * Math.atan2(y, x) -> float + * + * Computes the arc tangent given y and x. Returns + * -PI..PI. + * + * Math.atan2(-0.0, -1.0) #=> -3.141592653589793 + * Math.atan2(-1.0, -1.0) #=> -2.356194490192345 + * Math.atan2(-1.0, 0.0) #=> -1.5707963267948966 + * Math.atan2(-1.0, 1.0) #=> -0.7853981633974483 + * Math.atan2(-0.0, 1.0) #=> -0.0 + * Math.atan2(0.0, 1.0) #=> 0.0 + * Math.atan2(1.0, 1.0) #=> 0.7853981633974483 + * Math.atan2(1.0, 0.0) #=> 1.5707963267948966 + * Math.atan2(1.0, -1.0) #=> 2.356194490192345 + * Math.atan2(0.0, -1.0) #=> 3.141592653589793 + * + */ +static mrb_value +math_atan2(mrb_state *mrb, mrb_value obj) +{ + mrb_float x, y; + + mrb_get_args(mrb, "ff", &x, &y); + x = atan2(x, y); + + return mrb_float_value(mrb, x); +} + + + +/* + HYPERBOLIC TRIG FUNCTIONS +*/ +/* + * call-seq: + * Math.sinh(x) -> float + * + * Computes the hyperbolic sine of x (expressed in + * radians). + */ +static mrb_value +math_sinh(mrb_state *mrb, mrb_value obj) +{ + mrb_float x; + + mrb_get_args(mrb, "f", &x); + x = sinh(x); + + return mrb_float_value(mrb, x); +} + +/* + * call-seq: + * Math.cosh(x) -> float + * + * Computes the hyperbolic cosine of x (expressed in radians). + */ +static mrb_value +math_cosh(mrb_state *mrb, mrb_value obj) +{ + mrb_float x; + + mrb_get_args(mrb, "f", &x); + x = cosh(x); + + return mrb_float_value(mrb, x); +} + +/* + * call-seq: + * Math.tanh() -> float + * + * Computes the hyperbolic tangent of x (expressed in + * radians). + */ +static mrb_value +math_tanh(mrb_state *mrb, mrb_value obj) +{ + mrb_float x; + + mrb_get_args(mrb, "f", &x); + x = tanh(x); + + return mrb_float_value(mrb, x); +} + + +/* + INVERSE HYPERBOLIC TRIG FUNCTIONS +*/ + +/* + * call-seq: + * Math.asinh(x) -> float + * + * Computes the inverse hyperbolic sine of x. + */ +static mrb_value +math_asinh(mrb_state *mrb, mrb_value obj) +{ + mrb_float x; + + mrb_get_args(mrb, "f", &x); + + x = asinh(x); + + return mrb_float_value(mrb, x); +} + +/* + * call-seq: + * Math.acosh(x) -> float + * + * Computes the inverse hyperbolic cosine of x. + */ +static mrb_value +math_acosh(mrb_state *mrb, mrb_value obj) +{ + mrb_float x; + + mrb_get_args(mrb, "f", &x); + if (x < 1.0) { + domain_error(mrb, "acosh"); + } + x = acosh(x); + + return mrb_float_value(mrb, x); +} + +/* + * call-seq: + * Math.atanh(x) -> float + * + * Computes the inverse hyperbolic tangent of x. + */ +static mrb_value +math_atanh(mrb_state *mrb, mrb_value obj) +{ + mrb_float x; + + mrb_get_args(mrb, "f", &x); + if (x < -1.0 || x > 1.0) { + domain_error(mrb, "atanh"); + } + x = atanh(x); + + return mrb_float_value(mrb, x); +} + +/* + EXPONENTIALS AND LOGARITHMS +*/ + +/* + * call-seq: + * Math.exp(x) -> float + * + * Returns e**x. + * + * Math.exp(0) #=> 1.0 + * Math.exp(1) #=> 2.718281828459045 + * Math.exp(1.5) #=> 4.4816890703380645 + * + */ +static mrb_value +math_exp(mrb_state *mrb, mrb_value obj) +{ + mrb_float x; + + mrb_get_args(mrb, "f", &x); + x = exp(x); + + return mrb_float_value(mrb, x); +} + +/* + * call-seq: + * Math.log(numeric) -> float + * Math.log(num,base) -> float + * + * Returns the natural logarithm of numeric. + * If additional second argument is given, it will be the base + * of logarithm. + * + * Math.log(1) #=> 0.0 + * Math.log(Math::E) #=> 1.0 + * Math.log(Math::E**3) #=> 3.0 + * Math.log(12,3) #=> 2.2618595071429146 + * + */ +static mrb_value +math_log(mrb_state *mrb, mrb_value obj) +{ + mrb_float x, base; + int argc; + + argc = mrb_get_args(mrb, "f|f", &x, &base); + if (x < 0.0) { + domain_error(mrb, "log"); + } + x = log(x); + if (argc == 2) { + if (base < 0.0) { + domain_error(mrb, "log"); + } + x /= log(base); + } + return mrb_float_value(mrb, x); +} + +/* + * call-seq: + * Math.log2(numeric) -> float + * + * Returns the base 2 logarithm of numeric. + * + * Math.log2(1) #=> 0.0 + * Math.log2(2) #=> 1.0 + * Math.log2(32768) #=> 15.0 + * Math.log2(65536) #=> 16.0 + * + */ +static mrb_value +math_log2(mrb_state *mrb, mrb_value obj) +{ + mrb_float x; + + mrb_get_args(mrb, "f", &x); + if (x < 0.0) { + domain_error(mrb, "log2"); + } + x = log2(x); + + return mrb_float_value(mrb, x); +} + +/* + * call-seq: + * Math.log10(numeric) -> float + * + * Returns the base 10 logarithm of numeric. + * + * Math.log10(1) #=> 0.0 + * Math.log10(10) #=> 1.0 + * Math.log10(10**100) #=> 100.0 + * + */ +static mrb_value +math_log10(mrb_state *mrb, mrb_value obj) +{ + mrb_float x; + + mrb_get_args(mrb, "f", &x); + if (x < 0.0) { + domain_error(mrb, "log10"); + } + x = log10(x); + + return mrb_float_value(mrb, x); +} + +/* + * call-seq: + * Math.sqrt(numeric) -> float + * + * Returns the square root of numeric. + * + */ +static mrb_value +math_sqrt(mrb_state *mrb, mrb_value obj) +{ + mrb_float x; + + mrb_get_args(mrb, "f", &x); + if (x < 0.0) { + domain_error(mrb, "sqrt"); + } + x = sqrt(x); + + return mrb_float_value(mrb, x); +} + + +/* + * call-seq: + * Math.cbrt(numeric) -> float + * + * Returns the cube root of numeric. + * + * -9.upto(9) {|x| + * p [x, Math.cbrt(x), Math.cbrt(x)**3] + * } + * #=> + * [-9, -2.0800838230519, -9.0] + * [-8, -2.0, -8.0] + * [-7, -1.91293118277239, -7.0] + * [-6, -1.81712059283214, -6.0] + * [-5, -1.7099759466767, -5.0] + * [-4, -1.5874010519682, -4.0] + * [-3, -1.44224957030741, -3.0] + * [-2, -1.25992104989487, -2.0] + * [-1, -1.0, -1.0] + * [0, 0.0, 0.0] + * [1, 1.0, 1.0] + * [2, 1.25992104989487, 2.0] + * [3, 1.44224957030741, 3.0] + * [4, 1.5874010519682, 4.0] + * [5, 1.7099759466767, 5.0] + * [6, 1.81712059283214, 6.0] + * [7, 1.91293118277239, 7.0] + * [8, 2.0, 8.0] + * [9, 2.0800838230519, 9.0] + * + */ +static mrb_value +math_cbrt(mrb_state *mrb, mrb_value obj) +{ + mrb_float x; + + mrb_get_args(mrb, "f", &x); + x = cbrt(x); + + return mrb_float_value(mrb, x); +} + + +/* + * call-seq: + * Math.frexp(numeric) -> [ fraction, exponent ] + * + * Returns a two-element array containing the normalized fraction (a + * Float) and exponent (a Fixnum) of + * numeric. + * + * fraction, exponent = Math.frexp(1234) #=> [0.6025390625, 11] + * fraction * 2**exponent #=> 1234.0 + */ +static mrb_value +math_frexp(mrb_state *mrb, mrb_value obj) +{ + mrb_float x; + int exp; + + mrb_get_args(mrb, "f", &x); + x = frexp(x, &exp); + + return mrb_assoc_new(mrb, mrb_float_value(mrb, x), mrb_fixnum_value(exp)); +} + +/* + * call-seq: + * Math.ldexp(flt, int) -> float + * + * Returns the value of flt*(2**int). + * + * fraction, exponent = Math.frexp(1234) + * Math.ldexp(fraction, exponent) #=> 1234.0 + */ +static mrb_value +math_ldexp(mrb_state *mrb, mrb_value obj) +{ + mrb_float x; + mrb_int i; + + mrb_get_args(mrb, "fi", &x, &i); + x = ldexp(x, i); + + return mrb_float_value(mrb, x); +} + +/* + * call-seq: + * Math.hypot(x, y) -> float + * + * Returns sqrt(x**2 + y**2), the hypotenuse of a right-angled triangle + * with sides x and y. + * + * Math.hypot(3, 4) #=> 5.0 + */ +static mrb_value +math_hypot(mrb_state *mrb, mrb_value obj) +{ + mrb_float x, y; + + mrb_get_args(mrb, "ff", &x, &y); + x = hypot(x, y); + + return mrb_float_value(mrb, x); +} + +/* + * call-seq: + * Math.erf(x) -> float + * + * Calculates the error function of x. + */ +static mrb_value +math_erf(mrb_state *mrb, mrb_value obj) +{ + mrb_float x; + + mrb_get_args(mrb, "f", &x); + x = erf(x); + + return mrb_float_value(mrb, x); +} + + +/* + * call-seq: + * Math.erfc(x) -> float + * + * Calculates the complementary error function of x. + */ +static mrb_value +math_erfc(mrb_state *mrb, mrb_value obj) +{ + mrb_float x; + + mrb_get_args(mrb, "f", &x); + x = erfc(x); + + return mrb_float_value(mrb, x); +} + +/* ------------------------------------------------------------------------*/ +void +mrb_mruby_math_gem_init(mrb_state* mrb) +{ + struct RClass *mrb_math; + mrb_math = mrb_define_module(mrb, "Math"); + + mrb_define_class_under(mrb, mrb_math, "DomainError", mrb->eStandardError_class); + +#ifdef M_PI + mrb_define_const(mrb, mrb_math, "PI", mrb_float_value(mrb, M_PI)); +#else + mrb_define_const(mrb, mrb_math, "PI", mrb_float_value(mrb, atan(1.0)*4.0)); +#endif + +#ifdef M_E + mrb_define_const(mrb, mrb_math, "E", mrb_float_value(mrb, M_E)); +#else + mrb_define_const(mrb, mrb_math, "E", mrb_float_value(mrb, exp(1.0))); +#endif + +#ifdef MRB_USE_FLOAT + mrb_define_const(mrb, mrb_math, "TOLERANCE", mrb_float_value(mrb, 1e-5)); +#else + mrb_define_const(mrb, mrb_math, "TOLERANCE", mrb_float_value(mrb, 1e-12)); +#endif + + mrb_define_module_function(mrb, mrb_math, "sin", math_sin, MRB_ARGS_REQ(1)); + mrb_define_module_function(mrb, mrb_math, "cos", math_cos, MRB_ARGS_REQ(1)); + mrb_define_module_function(mrb, mrb_math, "tan", math_tan, MRB_ARGS_REQ(1)); + + mrb_define_module_function(mrb, mrb_math, "asin", math_asin, MRB_ARGS_REQ(1)); + mrb_define_module_function(mrb, mrb_math, "acos", math_acos, MRB_ARGS_REQ(1)); + mrb_define_module_function(mrb, mrb_math, "atan", math_atan, MRB_ARGS_REQ(1)); + mrb_define_module_function(mrb, mrb_math, "atan2", math_atan2, MRB_ARGS_REQ(2)); + + mrb_define_module_function(mrb, mrb_math, "sinh", math_sinh, MRB_ARGS_REQ(1)); + mrb_define_module_function(mrb, mrb_math, "cosh", math_cosh, MRB_ARGS_REQ(1)); + mrb_define_module_function(mrb, mrb_math, "tanh", math_tanh, MRB_ARGS_REQ(1)); + + mrb_define_module_function(mrb, mrb_math, "asinh", math_asinh, MRB_ARGS_REQ(1)); + mrb_define_module_function(mrb, mrb_math, "acosh", math_acosh, MRB_ARGS_REQ(1)); + mrb_define_module_function(mrb, mrb_math, "atanh", math_atanh, MRB_ARGS_REQ(1)); + + mrb_define_module_function(mrb, mrb_math, "exp", math_exp, MRB_ARGS_REQ(1)); + mrb_define_module_function(mrb, mrb_math, "log", math_log, MRB_ARGS_REQ(1)|MRB_ARGS_OPT(1)); + mrb_define_module_function(mrb, mrb_math, "log2", math_log2, MRB_ARGS_REQ(1)); + mrb_define_module_function(mrb, mrb_math, "log10", math_log10, MRB_ARGS_REQ(1)); + mrb_define_module_function(mrb, mrb_math, "sqrt", math_sqrt, MRB_ARGS_REQ(1)); + mrb_define_module_function(mrb, mrb_math, "cbrt", math_cbrt, MRB_ARGS_REQ(1)); + + mrb_define_module_function(mrb, mrb_math, "frexp", math_frexp, MRB_ARGS_REQ(1)); + mrb_define_module_function(mrb, mrb_math, "ldexp", math_ldexp, MRB_ARGS_REQ(2)); + + mrb_define_module_function(mrb, mrb_math, "hypot", math_hypot, MRB_ARGS_REQ(2)); + + mrb_define_module_function(mrb, mrb_math, "erf", math_erf, MRB_ARGS_REQ(1)); + mrb_define_module_function(mrb, mrb_math, "erfc", math_erfc, MRB_ARGS_REQ(1)); +} + +void +mrb_mruby_math_gem_final(mrb_state* mrb) +{ +} diff --git a/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-math/test/math.rb b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-math/test/math.rb new file mode 100644 index 00000000..e9ea07cc --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-math/test/math.rb @@ -0,0 +1,152 @@ +## +# Math Test + +## +# Performs fuzzy check for equality on methods returning floats +# on the basis of the Math::TOLERANCE constant. +def check_float(a, b) + tolerance = Math::TOLERANCE + a = a.to_f + b = b.to_f + if a.finite? and b.finite? + (a-b).abs < tolerance + else + true + end +end + +assert('Math.sin 0') do + check_float(Math.sin(0), 0) +end + +assert('Math.sin PI/2') do + check_float(Math.sin(Math::PI / 2), 1) +end + +assert('Math.cos 0') do + check_float(Math.cos(0), 1) +end + +assert('Math.cos PI/2') do + check_float(Math.cos(Math::PI / 2), 0) +end + +assert('Math.tan 0') do + check_float(Math.tan(0), 0) +end + +assert('Math.tan PI/4') do + check_float(Math.tan(Math::PI / 4), 1) +end + +assert('Fundamental trig identities') do + result = true + N = 13 + N.times do |i| + a = Math::PI / N * i + ca = Math::PI / 2 - a + s = Math.sin(a) + c = Math.cos(a) + t = Math.tan(a) + result &= check_float(s, Math.cos(ca)) + result &= check_float(t, 1 / Math.tan(ca)) + result &= check_float(s ** 2 + c ** 2, 1) + result &= check_float(t ** 2 + 1, (1/c) ** 2) + result &= check_float((1/t) ** 2 + 1, (1/s) ** 2) + end + result +end + +assert('Math.erf 0') do + check_float(Math.erf(0), 0) +end + +assert('Math.exp 0') do + check_float(Math.exp(0), 1.0) +end + +assert('Math.exp 1') do + check_float(Math.exp(1), 2.718281828459045) +end + +assert('Math.exp 1.5') do + check_float(Math.exp(1.5), 4.4816890703380645) +end + +assert('Math.log 1') do + check_float(Math.log(1), 0) +end + +assert('Math.log E') do + check_float(Math.log(Math::E), 1.0) +end + +assert('Math.log E**3') do + check_float(Math.log(Math::E**3), 3.0) +end + +assert('Math.log2 1') do + check_float(Math.log2(1), 0.0) +end + +assert('Math.log2 2') do + check_float(Math.log2(2), 1.0) +end + +assert('Math.log10 1') do + check_float(Math.log10(1), 0.0) +end + +assert('Math.log10 10') do + check_float(Math.log10(10), 1.0) +end + +assert('Math.log10 10**100') do + check_float(Math.log10(10**100), 100.0) +end + +assert('Math.sqrt') do + num = [0.0, 1.0, 2.0, 3.0, 4.0] + sqr = [0, 1, 4, 9, 16] + result = true + sqr.each_with_index do |v,i| + result &= check_float(Math.sqrt(v), num[i]) + end + result +end + +assert('Math.cbrt') do + num = [-2.0, -1.0, 0.0, 1.0, 2.0] + cub = [-8, -1, 0, 1, 8] + result = true + cub.each_with_index do |v,i| + result &= check_float(Math.cbrt(v), num[i]) + end + result +end + +assert('Math.hypot') do + check_float(Math.hypot(3, 4), 5.0) +end + +assert('Math.frexp 1234') do + n = 1234 + fraction, exponent = Math.frexp(n) + check_float(Math.ldexp(fraction, exponent), n) +end + +assert('Math.erf 1') do + check_float(Math.erf(1), 0.842700792949715) +end + +assert('Math.erfc 1') do + check_float(Math.erfc(1), 0.157299207050285) +end + +assert('Math.erf -1') do + check_float(Math.erf(-1), -0.8427007929497148) +end + +assert('Math.erfc -1') do + check_float(Math.erfc(-1), 1.8427007929497148) +end diff --git a/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-numeric-ext/mrbgem.rake b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-numeric-ext/mrbgem.rake new file mode 100644 index 00000000..6db7e589 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-numeric-ext/mrbgem.rake @@ -0,0 +1,5 @@ +MRuby::Gem::Specification.new('mruby-numeric-ext') do |spec| + spec.license = 'MIT' + spec.author = 'mruby developers' + spec.summary = 'Numeric class extension' +end diff --git a/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-numeric-ext/mrblib/numeric_ext.rb b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-numeric-ext/mrblib/numeric_ext.rb new file mode 100644 index 00000000..0bf3c6ab --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-numeric-ext/mrblib/numeric_ext.rb @@ -0,0 +1,17 @@ +module Integral + def div(other) + self.divmod(other)[0] + end + + def zero? + self == 0 + end + + def nonzero? + if self == 0 + nil + else + self + end + end +end diff --git a/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-numeric-ext/src/numeric_ext.c b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-numeric-ext/src/numeric_ext.c new file mode 100644 index 00000000..f71236a3 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-numeric-ext/src/numeric_ext.c @@ -0,0 +1,30 @@ +#include +#include + +static mrb_value +mrb_int_chr(mrb_state *mrb, mrb_value x) +{ + mrb_int chr; + char c; + + chr = mrb_fixnum(x); + if (chr >= (1 << CHAR_BIT)) { + mrb_raisef(mrb, E_RANGE_ERROR, "%S out of char range", x); + } + c = (char)chr; + + return mrb_str_new(mrb, &c, 1); +} + +void +mrb_mruby_numeric_ext_gem_init(mrb_state* mrb) +{ + struct RClass *i = mrb_class_get(mrb, "Integer"); + + mrb_define_method(mrb, i, "chr", mrb_int_chr, MRB_ARGS_NONE()); +} + +void +mrb_mruby_numeric_ext_gem_final(mrb_state* mrb) +{ +} diff --git a/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-numeric-ext/test/numeric.rb b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-numeric-ext/test/numeric.rb new file mode 100644 index 00000000..8bead248 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-numeric-ext/test/numeric.rb @@ -0,0 +1,28 @@ +## +# Numeric(Ext) Test + +assert('Integer#chr') do + assert_equal("A", 65.chr) + assert_equal("B", 0x42.chr) + + # multibyte encoding (not support yet) + assert_raise(RangeError) { 256.chr } +end + +assert('Integer#div') do + assert_equal 52, 365.div(7) +end + +assert('Float#div') do + assert_float 52, 365.2425.div(7) +end + +assert('Integer#zero?') do + assert_equal true, 0.zero? + assert_equal false, 1.zero? +end + +assert('Integer#nonzero?') do + assert_equal nil, 0.nonzero? + assert_equal 1000, 1000.nonzero? +end diff --git a/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-object-ext/mrbgem.rake b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-object-ext/mrbgem.rake new file mode 100644 index 00000000..6d14b4a5 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-object-ext/mrbgem.rake @@ -0,0 +1,5 @@ +MRuby::Gem::Specification.new('mruby-object-ext') do |spec| + spec.license = 'MIT' + spec.author = 'mruby developers' + spec.summary = 'Object class extension' +end diff --git a/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-object-ext/mrblib/object.rb b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-object-ext/mrblib/object.rb new file mode 100644 index 00000000..581156cb --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-object-ext/mrblib/object.rb @@ -0,0 +1,19 @@ +class Object + ## + # call-seq: + # obj.tap{|x|...} -> obj + # + # Yields x to the block, and then returns x. + # The primary purpose of this method is to "tap into" a method chain, + # in order to perform operations on intermediate results within the chain. + # + # (1..10) .tap {|x| puts "original: #{x.inspect}"} + # .to_a .tap {|x| puts "array: #{x.inspect}"} + # .select {|x| x%2==0} .tap {|x| puts "evens: #{x.inspect}"} + # .map { |x| x*x } .tap {|x| puts "squares: #{x.inspect}"} + # + def tap + yield self + self + end +end diff --git a/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-object-ext/src/object.c b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-object-ext/src/object.c new file mode 100644 index 00000000..35a07b58 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-object-ext/src/object.c @@ -0,0 +1,106 @@ +#include +#include +#include +#include + +/* + * call-seq: + * nil.to_a -> [] + * + * Always returns an empty array. + */ + +static mrb_value +nil_to_a(mrb_state *mrb, mrb_value obj) +{ + return mrb_ary_new(mrb); +} + +/* + * call-seq: + * nil.to_f -> 0.0 + * + * Always returns zero. + */ + +static mrb_value +nil_to_f(mrb_state *mrb, mrb_value obj) +{ + return mrb_float_value(mrb, 0.0); +} + +/* + * call-seq: + * nil.to_i -> 0 + * + * Always returns zero. + */ + +static mrb_value +nil_to_i(mrb_state *mrb, mrb_value obj) +{ + return mrb_fixnum_value(0); +} + +/* + * call-seq: + * obj.instance_exec(arg...) {|var...| block } -> obj + * + * Executes the given block within the context of the receiver + * (_obj_). In order to set the context, the variable +self+ is set + * to _obj_ while the code is executing, giving the code access to + * _obj_'s instance variables. Arguments are passed as block parameters. + * + * class KlassWithSecret + * def initialize + * @secret = 99 + * end + * end + * k = KlassWithSecret.new + * k.instance_exec(5) {|x| @secret+x } #=> 104 + */ + +static mrb_value +mrb_obj_instance_exec(mrb_state *mrb, mrb_value self) +{ + const mrb_value *argv; + mrb_int argc; + mrb_value blk; + struct RClass *c; + + mrb_get_args(mrb, "*&", &argv, &argc, &blk); + + if (mrb_nil_p(blk)) { + mrb_raise(mrb, E_ARGUMENT_ERROR, "no block given"); + } + + switch (mrb_type(self)) { + case MRB_TT_SYMBOL: + case MRB_TT_FIXNUM: + case MRB_TT_FLOAT: + c = NULL; + break; + default: + c = mrb_class_ptr(mrb_singleton_class(mrb, self)); + break; + } + mrb->c->ci->target_class = c; + return mrb_yield_cont(mrb, blk, self, argc, argv); +} + +void +mrb_mruby_object_ext_gem_init(mrb_state* mrb) +{ + struct RClass * n = mrb->nil_class; + + mrb_define_method(mrb, n, "to_a", nil_to_a, MRB_ARGS_NONE()); + mrb_define_method(mrb, n, "to_f", nil_to_f, MRB_ARGS_NONE()); + mrb_define_method(mrb, n, "to_i", nil_to_i, MRB_ARGS_NONE()); + + mrb_define_method(mrb, mrb->kernel_module, "instance_exec", mrb_obj_instance_exec, MRB_ARGS_ANY() | MRB_ARGS_BLOCK()); +} + +void +mrb_mruby_object_ext_gem_final(mrb_state* mrb) +{ +} diff --git a/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-object-ext/test/nil.rb b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-object-ext/test/nil.rb new file mode 100644 index 00000000..5cd1cf4e --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-object-ext/test/nil.rb @@ -0,0 +1,11 @@ +assert('NilClass#to_a') do + assert_equal [], nil.to_a +end + +assert('NilClass#to_f') do + assert_equal 0.0, nil.to_f +end + +assert('NilClass#to_i') do + assert_equal 0, nil.to_i +end diff --git a/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-object-ext/test/object.rb b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-object-ext/test/object.rb new file mode 100644 index 00000000..f0742f8c --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-object-ext/test/object.rb @@ -0,0 +1,53 @@ +assert('Object#instance_exec') do + class KlassWithSecret + def initialize + @secret = 99 + end + end + k = KlassWithSecret.new + assert_equal 104, k.instance_exec(5) {|x| @secret+x } +end + +assert('Object#tap') do + ret = [] + (1..10) .tap {|x| ret << "original: #{x.inspect}"} + .to_a .tap {|x| ret << "array: #{x.inspect}"} + .select {|x| x%2==0} .tap {|x| ret << "evens: #{x.inspect}"} + .map { |x| x*x } .tap {|x| ret << "squares: #{x.inspect}"} + + assert_equal [ + "original: 1..10", + "array: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]", + "evens: [2, 4, 6, 8, 10]", + "squares: [4, 16, 36, 64, 100]" + ], ret + assert_equal(:tap_ok, Class.new {def m; tap{return :tap_ok}; end}.new.m) +end + +assert('instance_exec on primitives with class and module definition') do + begin + class A + 1.instance_exec do + class B + end + end + end + + assert_kind_of Class, A::B + ensure + Object.remove_const :A + end + + begin + class A + 1.instance_exec do + module B + end + end + end + + assert_kind_of Module, A::B + ensure + Object.remove_const :A + end +end diff --git a/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-objectspace/mrbgem.rake b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-objectspace/mrbgem.rake new file mode 100644 index 00000000..fa35136a --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-objectspace/mrbgem.rake @@ -0,0 +1,5 @@ +MRuby::Gem::Specification.new('mruby-objectspace') do |spec| + spec.license = 'MIT' + spec.author = 'mruby developers' + spec.summary = 'ObjectSpace class' +end diff --git a/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-objectspace/src/mruby_objectspace.c b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-objectspace/src/mruby_objectspace.c new file mode 100644 index 00000000..3887091d --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-objectspace/src/mruby_objectspace.c @@ -0,0 +1,187 @@ +#include +#include +#include +#include + +struct os_count_struct { + mrb_int total; + mrb_int freed; + mrb_int counts[MRB_TT_MAXDEFINE+1]; +}; + +static int +os_count_object_type(mrb_state *mrb, struct RBasic *obj, void *data) +{ + struct os_count_struct *obj_count; + obj_count = (struct os_count_struct*)data; + + obj_count->total++; + + if (mrb_object_dead_p(mrb, obj)) { + obj_count->freed++; + } + else { + obj_count->counts[obj->tt]++; + } + return MRB_EACH_OBJ_OK; +} + +/* + * call-seq: + * ObjectSpace.count_objects([result_hash]) -> hash + * + * Counts objects for each type. + * + * It returns a hash, such as: + * { + * :TOTAL=>10000, + * :FREE=>3011, + * :T_OBJECT=>6, + * :T_CLASS=>404, + * # ... + * } + * + * If the optional argument +result_hash+ is given, + * it is overwritten and returned. This is intended to avoid probe effect. + * + */ + +static mrb_value +os_count_objects(mrb_state *mrb, mrb_value self) +{ + struct os_count_struct obj_count = { 0 }; + mrb_int i; + mrb_value hash; + + if (mrb_get_args(mrb, "|H", &hash) == 0) { + hash = mrb_hash_new(mrb); + } + + if (!mrb_test(mrb_hash_empty_p(mrb, hash))) { + mrb_hash_clear(mrb, hash); + } + + mrb_objspace_each_objects(mrb, os_count_object_type, &obj_count); + + mrb_hash_set(mrb, hash, mrb_symbol_value(mrb_intern_lit(mrb, "TOTAL")), mrb_fixnum_value(obj_count.total)); + mrb_hash_set(mrb, hash, mrb_symbol_value(mrb_intern_lit(mrb, "FREE")), mrb_fixnum_value(obj_count.freed)); + + for (i = MRB_TT_FALSE; i < MRB_TT_MAXDEFINE; i++) { + mrb_value type; + switch (i) { +#define COUNT_TYPE(t) case (MRB_T ## t): type = mrb_symbol_value(mrb_intern_lit(mrb, #t)); break; + COUNT_TYPE(T_FALSE); + COUNT_TYPE(T_FREE); + COUNT_TYPE(T_TRUE); + COUNT_TYPE(T_FIXNUM); + COUNT_TYPE(T_SYMBOL); + COUNT_TYPE(T_UNDEF); + COUNT_TYPE(T_FLOAT); + COUNT_TYPE(T_CPTR); + COUNT_TYPE(T_OBJECT); + COUNT_TYPE(T_CLASS); + COUNT_TYPE(T_MODULE); + COUNT_TYPE(T_ICLASS); + COUNT_TYPE(T_SCLASS); + COUNT_TYPE(T_PROC); + COUNT_TYPE(T_ARRAY); + COUNT_TYPE(T_HASH); + COUNT_TYPE(T_STRING); + COUNT_TYPE(T_RANGE); + COUNT_TYPE(T_EXCEPTION); + COUNT_TYPE(T_FILE); + COUNT_TYPE(T_ENV); + COUNT_TYPE(T_DATA); + COUNT_TYPE(T_FIBER); +#undef COUNT_TYPE + default: + type = mrb_fixnum_value(i); break; + } + if (obj_count.counts[i]) + mrb_hash_set(mrb, hash, type, mrb_fixnum_value(obj_count.counts[i])); + } + + return hash; +} + +struct os_each_object_data { + mrb_value block; + struct RClass *target_module; + mrb_int count; +}; + +static int +os_each_object_cb(mrb_state *mrb, struct RBasic *obj, void *ud) +{ + struct os_each_object_data *d = (struct os_each_object_data*)ud; + + /* filter dead objects */ + if (mrb_object_dead_p(mrb, obj)) { + return MRB_EACH_OBJ_OK; + } + + /* filter internal objects */ + switch (obj->tt) { + case MRB_TT_ENV: + case MRB_TT_ICLASS: + return MRB_EACH_OBJ_OK; + default: + break; + } + + /* filter half baked (or internal) objects */ + if (!obj->c) return MRB_EACH_OBJ_OK; + + /* filter class kind if target module defined */ + if (d->target_module && !mrb_obj_is_kind_of(mrb, mrb_obj_value(obj), d->target_module)) { + return MRB_EACH_OBJ_OK; + } + + mrb_yield(mrb, d->block, mrb_obj_value(obj)); + ++d->count; + return MRB_EACH_OBJ_OK; +} + +/* + * call-seq: + * ObjectSpace.each_object([module]) {|obj| ... } -> fixnum + * + * Calls the block once for each object in this Ruby process. + * Returns the number of objects found. + * If the optional argument +module+ is given, + * calls the block for only those classes or modules + * that match (or are a subclass of) +module+. + * + * If no block is given, ArgumentError is raised. + * + */ + +static mrb_value +os_each_object(mrb_state *mrb, mrb_value self) +{ + mrb_value cls = mrb_nil_value(); + struct os_each_object_data d; + mrb_get_args(mrb, "&|C", &d.block, &cls); + + if (mrb_nil_p(d.block)) { + mrb_raise(mrb, E_ARGUMENT_ERROR, "Expected block in ObjectSpace.each_object."); + } + + d.target_module = mrb_nil_p(cls) ? NULL : mrb_class_ptr(cls); + d.count = 0; + mrb_objspace_each_objects(mrb, os_each_object_cb, &d); + return mrb_fixnum_value(d.count); +} + +void +mrb_mruby_objectspace_gem_init(mrb_state *mrb) +{ + struct RClass *os = mrb_define_module(mrb, "ObjectSpace"); + mrb_define_class_method(mrb, os, "count_objects", os_count_objects, MRB_ARGS_OPT(1)); + mrb_define_class_method(mrb, os, "each_object", os_each_object, MRB_ARGS_OPT(1)); +} + +void +mrb_mruby_objectspace_gem_final(mrb_state *mrb) +{ +} diff --git a/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-objectspace/test/objectspace.rb b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-objectspace/test/objectspace.rb new file mode 100644 index 00000000..4731d53b --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-objectspace/test/objectspace.rb @@ -0,0 +1,60 @@ +assert('ObjectSpace.count_objects') do + h = {} + f = Fiber.new {} if Object.const_defined? :Fiber + ObjectSpace.count_objects(h) + assert_kind_of(Hash, h) + assert_true(h.keys.all? {|x| x.is_a?(Symbol) || x.is_a?(Integer) }) + assert_true(h.values.all? {|x| x.is_a?(Integer) }) + + assert_true(h.has_key?(:TOTAL)) + assert_true(h.has_key?(:FREE)) + assert_true(h.has_key?(:T_FIBER)) if Object.const_defined? :Fiber + + assert_equal(h[:TOTAL] * 2, h.values.reduce(:+)) + + h = ObjectSpace.count_objects + assert_kind_of(Hash, h) + assert_true(h.keys.all? {|x| x.is_a?(Symbol) || x.is_a?(Integer) }) + assert_true(h.values.all? {|x| x.is_a?(Integer) }) + + assert_raise(TypeError) { ObjectSpace.count_objects(1) } + + h0 = {:T_FOO=>1000} + h = ObjectSpace.count_objects(h0) + assert_false(h0.has_key?(:T_FOO)) + + GC.start + h_after = {} + h_before = ObjectSpace.count_objects + + objs = [] + 1000.times do + objs << {} + end + objs = nil + ObjectSpace.count_objects(h) + GC.start + ObjectSpace.count_objects(h_after) + + assert_equal(h[:T_HASH], h_before[:T_HASH] + 1000) + assert_equal(h_after[:T_HASH], h_before[:T_HASH]) +end + +assert('ObjectSpace.each_object') do + objs = [] + objs_count = ObjectSpace.each_object { |obj| + objs << obj + } + assert_equal objs.length, objs_count + + arys = [] + arys_count = ObjectSpace.each_object(Array) { |obj| + arys << obj + } + assert_equal arys.length, arys_count + assert_true arys.length < objs.length +end + +assert 'Check class pointer of ObjectSpace.each_object.' do + ObjectSpace.each_object { |obj| !obj } +end diff --git a/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-print/mrbgem.rake b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-print/mrbgem.rake new file mode 100644 index 00000000..2ea6e312 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-print/mrbgem.rake @@ -0,0 +1,5 @@ +MRuby::Gem::Specification.new('mruby-print') do |spec| + spec.license = 'MIT' + spec.author = 'mruby developers' + spec.summary = 'standard print/puts/p' +end diff --git a/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-print/mrblib/print.rb b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-print/mrblib/print.rb new file mode 100644 index 00000000..38a10661 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-print/mrblib/print.rb @@ -0,0 +1,64 @@ +## +# Kernel +# +# ISO 15.3.1 +module Kernel + ## + # Invoke method +print+ on STDOUT and passing +*args+ + # + # ISO 15.3.1.2.10 + def print(*args) + i = 0 + len = args.size + while i < len + __printstr__ args[i].to_s + i += 1 + end + end + + ## + # Invoke method +puts+ on STDOUT and passing +*args*+ + # + # ISO 15.3.1.2.11 + def puts(*args) + i = 0 + len = args.size + while i < len + s = args[i].to_s + __printstr__ s + __printstr__ "\n" if (s[-1] != "\n") + i += 1 + end + __printstr__ "\n" if len == 0 + nil + end + + ## + # Print human readable object description + # + # ISO 15.3.1.3.34 + def p(*args) + i = 0 + len = args.size + while i < len + __printstr__ args[i].inspect + __printstr__ "\n" + i += 1 + end + args[0] + end + + unless Kernel.respond_to?(:sprintf) + def printf(*args) + raise NotImplementedError.new('printf not available') + end + def sprintf(*args) + raise NotImplementedError.new('sprintf not available') + end + else + def printf(*args) + __printstr__(sprintf(*args)) + nil + end + end +end diff --git a/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-print/src/print.c b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-print/src/print.c new file mode 100644 index 00000000..d0c522d2 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-print/src/print.c @@ -0,0 +1,64 @@ +#include +#include +#include +#include +#include +#if defined(_WIN32) +# include +# include +#ifdef _MSC_VER +# define isatty(x) _isatty(x) +# define fileno(x) _fileno(x) +#endif +#endif + +static void +printstr(mrb_state *mrb, mrb_value obj) +{ + if (mrb_string_p(obj)) { +#if defined(_WIN32) + if (isatty(fileno(stdout))) { + DWORD written; + int mlen = RSTRING_LEN(obj); + char* utf8 = RSTRING_PTR(obj); + int wlen = MultiByteToWideChar(CP_UTF8, 0, utf8, mlen, NULL, 0); + wchar_t* utf16 = (wchar_t*)mrb_malloc(mrb, (wlen+1) * sizeof(wchar_t)); + if (utf16 == NULL) return; + if (MultiByteToWideChar(CP_UTF8, 0, utf8, mlen, utf16, wlen) > 0) { + utf16[wlen] = 0; + WriteConsoleW(GetStdHandle(STD_OUTPUT_HANDLE), + utf16, wlen, &written, NULL); + } + mrb_free(mrb, utf16); + } else +#endif + fwrite(RSTRING_PTR(obj), RSTRING_LEN(obj), 1, stdout); + fflush(stdout); + } +} + +/* 15.3.1.2.9 */ +/* 15.3.1.3.34 */ +mrb_value +mrb_printstr(mrb_state *mrb, mrb_value self) +{ + mrb_value argv; + + mrb_get_args(mrb, "o", &argv); + printstr(mrb, argv); + + return argv; +} + +void +mrb_mruby_print_gem_init(mrb_state* mrb) +{ + struct RClass *krn; + krn = mrb->kernel_module; + mrb_define_method(mrb, krn, "__printstr__", mrb_printstr, MRB_ARGS_REQ(1)); +} + +void +mrb_mruby_print_gem_final(mrb_state* mrb) +{ +} diff --git a/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-proc-ext/mrbgem.rake b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-proc-ext/mrbgem.rake new file mode 100644 index 00000000..e4d15a14 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-proc-ext/mrbgem.rake @@ -0,0 +1,5 @@ +MRuby::Gem::Specification.new('mruby-proc-ext') do |spec| + spec.license = 'MIT' + spec.author = 'mruby developers' + spec.summary = 'Proc class extension' +end diff --git a/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-proc-ext/mrblib/proc.rb b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-proc-ext/mrblib/proc.rb new file mode 100644 index 00000000..b7166393 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-proc-ext/mrblib/proc.rb @@ -0,0 +1,42 @@ +class Proc + + def ===(*args) + call(*args) + end + + def yield(*args) + call(*args) + end + + def to_proc + self + end + + def curry(arity=self.arity) + type = :proc + abs = lambda {|a| a < 0 ? -a - 1 : a} + arity = abs[arity] + if lambda? + type = :lambda + self_arity = self.arity + if (self_arity >= 0 && arity != self_arity) || + (self_arity < 0 && abs[self_arity] > arity) + raise ArgumentError, "wrong number of arguments (#{arity} for #{abs[self_arity]})" + end + end + + pproc = self + make_curry = proc do |given_args=[]| + send(type) do |*args| + new_args = given_args + args + if new_args.size >= arity + pproc[*new_args] + else + make_curry[new_args] + end + end + end + make_curry.call + end + +end diff --git a/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-proc-ext/src/proc.c b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-proc-ext/src/proc.c new file mode 100644 index 00000000..b13606f5 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-proc-ext/src/proc.c @@ -0,0 +1,173 @@ +#include +#include +#include +#include +#include +#include + +static mrb_value +mrb_proc_lambda(mrb_state *mrb, mrb_value self) +{ + struct RProc *p = mrb_proc_ptr(self); + return mrb_bool_value(MRB_PROC_STRICT_P(p)); +} + +static mrb_value +mrb_proc_source_location(mrb_state *mrb, mrb_value self) +{ + struct RProc *p = mrb_proc_ptr(self); + + if (MRB_PROC_CFUNC_P(p)) { + return mrb_nil_value(); + } + else { + mrb_irep *irep = p->body.irep; + int32_t line; + const char *filename; + + filename = mrb_debug_get_filename(irep, 0); + line = mrb_debug_get_line(irep, 0); + + return (!filename && line == -1)? mrb_nil_value() + : mrb_assoc_new(mrb, mrb_str_new_cstr(mrb, filename), mrb_fixnum_value(line)); + } +} + +static mrb_value +mrb_proc_inspect(mrb_state *mrb, mrb_value self) +{ + struct RProc *p = mrb_proc_ptr(self); + mrb_value str = mrb_str_new_lit(mrb, "#body.irep; + const char *filename; + int32_t line; + mrb_str_cat_lit(mrb, str, "@"); + + filename = mrb_debug_get_filename(irep, 0); + mrb_str_cat_cstr(mrb, str, filename ? filename : "-"); + mrb_str_cat_lit(mrb, str, ":"); + + line = mrb_debug_get_line(irep, 0); + if (line != -1) { + str = mrb_format(mrb, "%S:%S", str, mrb_fixnum_value(line)); + } + else { + mrb_str_cat_lit(mrb, str, "-"); + } + } + + if (MRB_PROC_STRICT_P(p)) { + mrb_str_cat_lit(mrb, str, " (lambda)"); + } + + mrb_str_cat_lit(mrb, str, ">"); + return str; +} + +static mrb_value +mrb_kernel_proc(mrb_state *mrb, mrb_value self) +{ + mrb_value blk; + + mrb_get_args(mrb, "&", &blk); + if (mrb_nil_p(blk)) { + mrb_raise(mrb, E_ARGUMENT_ERROR, "tried to create Proc object without a block"); + } + + return blk; +} + +/* + * call-seq: + * prc.parameters -> array + * + * Returns the parameter information of this proc. + * + * prc = lambda{|x, y=42, *other|} + * prc.parameters #=> [[:req, :x], [:opt, :y], [:rest, :other]] + */ + +static mrb_value +mrb_proc_parameters(mrb_state *mrb, mrb_value self) +{ + struct parameters_type { + int size; + const char *name; + } *p, parameters_list [] = { + {0, "req"}, + {0, "opt"}, + {0, "rest"}, + {0, "req"}, + {0, "block"}, + {0, NULL} + }; + const struct RProc *proc = mrb_proc_ptr(self); + const struct mrb_irep *irep = proc->body.irep; + mrb_aspec aspec; + mrb_value sname, parameters; + int i, j; + + if (MRB_PROC_CFUNC_P(proc)) { + // TODO cfunc aspec is not implemented yet + return mrb_ary_new(mrb); + } + if (!irep) { + return mrb_ary_new(mrb); + } + if (!irep->lv) { + return mrb_ary_new(mrb); + } + if (GET_OPCODE(*irep->iseq) != OP_ENTER) { + return mrb_ary_new(mrb); + } + + if (!MRB_PROC_STRICT_P(proc)) { + parameters_list[0].name = "opt"; + parameters_list[3].name = "opt"; + } + + aspec = GETARG_Ax(*irep->iseq); + parameters_list[0].size = MRB_ASPEC_REQ(aspec); + parameters_list[1].size = MRB_ASPEC_OPT(aspec); + parameters_list[2].size = MRB_ASPEC_REST(aspec); + parameters_list[3].size = MRB_ASPEC_POST(aspec); + parameters_list[4].size = MRB_ASPEC_BLOCK(aspec); + + parameters = mrb_ary_new_capa(mrb, irep->nlocals-1); + + for (i = 0, p = parameters_list; p->name; p++) { + if (p->size <= 0) continue; + sname = mrb_symbol_value(mrb_intern_cstr(mrb, p->name)); + for (j = 0; j < p->size; i++, j++) { + mrb_value a = mrb_ary_new(mrb); + mrb_ary_push(mrb, a, sname); + if (irep->lv[i].name) { + mrb_ary_push(mrb, a, mrb_symbol_value(irep->lv[i].name)); + } + mrb_ary_push(mrb, parameters, a); + } + } + return parameters; +} + +void +mrb_mruby_proc_ext_gem_init(mrb_state* mrb) +{ + struct RClass *p = mrb->proc_class; + mrb_define_method(mrb, p, "lambda?", mrb_proc_lambda, MRB_ARGS_NONE()); + mrb_define_method(mrb, p, "source_location", mrb_proc_source_location, MRB_ARGS_NONE()); + mrb_define_method(mrb, p, "to_s", mrb_proc_inspect, MRB_ARGS_NONE()); + mrb_define_method(mrb, p, "inspect", mrb_proc_inspect, MRB_ARGS_NONE()); + mrb_define_method(mrb, p, "parameters", mrb_proc_parameters, MRB_ARGS_NONE()); + + mrb_define_class_method(mrb, mrb->kernel_module, "proc", mrb_kernel_proc, MRB_ARGS_NONE()); + mrb_define_method(mrb, mrb->kernel_module, "proc", mrb_kernel_proc, MRB_ARGS_NONE()); +} + +void +mrb_mruby_proc_ext_gem_final(mrb_state* mrb) +{ +} diff --git a/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-proc-ext/test/proc.c b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-proc-ext/test/proc.c new file mode 100644 index 00000000..a77b68e9 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-proc-ext/test/proc.c @@ -0,0 +1,56 @@ +#include +#include +#include + +static mrb_value +return_func_name(mrb_state *mrb, mrb_value self) +{ + return mrb_cfunc_env_get(mrb, 0); +} + +static mrb_value +proc_new_cfunc_with_env(mrb_state *mrb, mrb_value self) +{ + mrb_sym n; + mrb_value n_val; + mrb_get_args(mrb, "n", &n); + n_val = mrb_symbol_value(n); + mrb_define_method_raw(mrb, mrb_class_ptr(self), n, + mrb_proc_new_cfunc_with_env(mrb, return_func_name, 1, &n_val)); + return self; +} + +static mrb_value +return_env(mrb_state *mrb, mrb_value self) +{ + mrb_int idx; + mrb_get_args(mrb, "i", &idx); + return mrb_cfunc_env_get(mrb, idx); +} + +static mrb_value +cfunc_env_get(mrb_state *mrb, mrb_value self) +{ + mrb_sym n; + mrb_value *argv; mrb_int argc; + mrb_get_args(mrb, "na", &n, &argv, &argc); + mrb_define_method_raw(mrb, mrb_class_ptr(self), n, + mrb_proc_new_cfunc_with_env(mrb, return_env, argc, argv)); + return self; +} + +static mrb_value +cfunc_without_env(mrb_state *mrb, mrb_value self) +{ + return mrb_cfunc_env_get(mrb, 0); +} + +void mrb_mruby_proc_ext_gem_test(mrb_state *mrb) +{ + struct RClass *cls; + + cls = mrb_define_class(mrb, "ProcExtTest", mrb->object_class); + mrb_define_module_function(mrb, cls, "mrb_proc_new_cfunc_with_env", proc_new_cfunc_with_env, MRB_ARGS_REQ(1)); + mrb_define_module_function(mrb, cls, "mrb_cfunc_env_get", cfunc_env_get, MRB_ARGS_REQ(2)); + mrb_define_module_function(mrb, cls, "cfunc_without_env", cfunc_without_env, MRB_ARGS_NONE()); +} diff --git a/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-proc-ext/test/proc.rb b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-proc-ext/test/proc.rb new file mode 100644 index 00000000..037d8d12 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-proc-ext/test/proc.rb @@ -0,0 +1,96 @@ +## +# Proc(Ext) Test + +assert('Proc#source_location') do + loc = Proc.new {}.source_location + next true if loc.nil? + assert_equal loc[0][-7, 7], 'proc.rb' + assert_equal loc[1], 5 +end + +assert('Proc#inspect') do + ins = Proc.new{}.inspect + assert_kind_of String, ins +end + +assert('Proc#lambda?') do + assert_true lambda{}.lambda? + assert_true !Proc.new{}.lambda? +end + +assert('Proc#===') do + proc = Proc.new {|a| a * 2} + assert_equal 20, (proc === 10) +end + +assert('Proc#yield') do + proc = Proc.new {|a| a * 2} + assert_equal 20, proc.yield(10) +end + +assert('Proc#curry') do + b = proc {|x, y, z| (x||0) + (y||0) + (z||0) } + assert_equal 6, b.curry[1][2][3] + assert_equal 6, b.curry[1, 2][3, 4] + assert_equal 6, b.curry(5)[1][2][3][4][5] + assert_equal 6, b.curry(5)[1, 2][3, 4][5] + assert_equal 1, b.curry(1)[1] + + b = lambda {|x, y, z| (x||0) + (y||0) + (z||0) } + assert_equal 6, b.curry[1][2][3] + assert_raise(ArgumentError) { b.curry[1, 2][3, 4] } + assert_raise(ArgumentError) { b.curry(5) } + assert_raise(ArgumentError) { b.curry(1) } + + assert_false(proc{}.curry.lambda?) + assert_true(lambda{}.curry.lambda?) +end + +assert('Proc#parameters') do + assert_equal([], Proc.new {}.parameters) + assert_equal([], Proc.new {||}.parameters) + assert_equal([[:opt, :a]], Proc.new {|a|}.parameters) + assert_equal([[:req, :a]], lambda {|a|}.parameters) + assert_equal([[:opt, :a]], lambda {|a=nil|}.parameters) + assert_equal([[:req, :a]], ->(a){}.parameters) + assert_equal([[:rest]], lambda { |*| }.parameters) + assert_equal([[:rest, :a]], Proc.new {|*a|}.parameters) + assert_equal([[:opt, :a], [:opt, :b], [:opt, :c], [:opt, :d], [:rest, :e], [:opt, :f], [:opt, :g], [:block, :h]], Proc.new {|a,b,c=:c,d=:d,*e,f,g,&h|}.parameters) + assert_equal([[:req, :a], [:req, :b], [:opt, :c], [:opt, :d], [:rest, :e], [:req, :f], [:req, :g], [:block, :h]], lambda {|a,b,c=:c,d=:d,*e,f,g,&h|}.parameters) +end + +assert('Proc#to_proc') do + proc = Proc.new {} + assert_equal proc, proc.to_proc +end + +assert('Kernel#proc') do + assert_true !proc{|a|}.lambda? + + assert_raise LocalJumpError do + proc{ break }.call + end +end + +assert('mrb_proc_new_cfunc_with_env') do + ProcExtTest.mrb_proc_new_cfunc_with_env(:test) + ProcExtTest.mrb_proc_new_cfunc_with_env(:mruby) + + t = ProcExtTest.new + + assert_equal :test, t.test + assert_equal :mruby, t.mruby +end + +assert('mrb_cfunc_env_get') do + ProcExtTest.mrb_cfunc_env_get :get_int, [0, 1, 2] + + t = ProcExtTest.new + + assert_raise(TypeError) { t.cfunc_without_env } + + assert_raise(IndexError) { t.get_int(-1) } + assert_raise(IndexError) { t.get_int(3) } + + assert_equal 1, t.get_int(1) +end diff --git a/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-random/mrbgem.rake b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-random/mrbgem.rake new file mode 100644 index 00000000..3a3fd2bd --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-random/mrbgem.rake @@ -0,0 +1,5 @@ +MRuby::Gem::Specification.new('mruby-random') do |spec| + spec.license = 'MIT' + spec.author = 'mruby developers' + spec.summary = 'Random class' +end diff --git a/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-random/src/mt19937ar.c b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-random/src/mt19937ar.c new file mode 100644 index 00000000..405bd5c2 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-random/src/mt19937ar.c @@ -0,0 +1,224 @@ +/* +** mt19937ar.c - MT Random functions +** +** Copyright (C) 1997 - 2016, Makoto Matsumoto and Takuji Nishimura, +** All rights reserved. +** +** Permission is hereby granted, free of charge, to any person obtaining +** a copy of this software and associated documentation files (the +** "Software"), to deal in the Software without restriction, including +** without limitation the rights to use, copy, modify, merge, publish, +** distribute, sublicense, and/or sell copies of the Software, and to +** permit persons to whom the Software is furnished to do so, subject to +** the following conditions: +** +** The above copyright notice and this permission notice shall be +** included in all copies or substantial portions of the Software. +** +** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +** SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +** +** [ MIT license: http://www.opensource.org/licenses/mit-license.php ] +** +** Any feedback is very welcome. +** http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/emt.html +** email: m-mat @ math.sci.hiroshima-u.ac.jp (remove space) +** +** This version is modified by mruby developers. If you see any problem, +** contact us first at https://github.com/mruby/mruby/issues +*/ + +#include +#include "mt19937ar.h" + +/* Period parameters */ +/* #define N 624 */ +#define M 397 +#define MATRIX_A 0x9908b0dfUL /* constant vector a */ +#define UPPER_MASK 0x80000000UL /* most significant w-r bits */ +#define LOWER_MASK 0x7fffffffUL /* least significant r bits */ + +#if 0 /* dead_code */ +static unsigned long mt[N]; /* the array for the state vector */ +static int mti=N+1; /* mti==N+1 means mt[N] is not initialized */ +#endif /* dead_code */ + +void mrb_random_init_genrand(mt_state *t, unsigned long s) +{ + t->mt[0]= s & 0xffffffffUL; + for (t->mti=1; t->mtimti++) { + t->mt[t->mti] = (1812433253UL * (t->mt[t->mti-1] ^ (t->mt[t->mti-1] >> 30)) + t->mti); + t->mt[t->mti] &= 0xffffffffUL; + } +} + +unsigned long mrb_random_genrand_int32(mt_state *t) +{ + unsigned long y; + static const unsigned long mag01[2]={0x0UL, MATRIX_A}; + /* mag01[x] = x * MATRIX_A for x=0,1 */ + + if (t->mti >= N) { /* generate N words at one time */ + int kk; + + if (t->mti == N+1) /* if init_genrand() has not been called, */ + mrb_random_init_genrand(t, 5489UL); /* a default initial seed is used */ + + for (kk=0;kkmt[kk]&UPPER_MASK)|(t->mt[kk+1]&LOWER_MASK); + t->mt[kk] = t->mt[kk+M] ^ (y >> 1) ^ mag01[y & 0x1UL]; + } + for (;kkmt[kk]&UPPER_MASK)|(t->mt[kk+1]&LOWER_MASK); + t->mt[kk] = t->mt[kk+(M-N)] ^ (y >> 1) ^ mag01[y & 0x1UL]; + } + y = (t->mt[N-1]&UPPER_MASK)|(t->mt[0]&LOWER_MASK); + t->mt[N-1] = t->mt[M-1] ^ (y >> 1) ^ mag01[y & 0x1UL]; + + t->mti = 0; + } + + y = t->mt[t->mti++]; + + /* Tempering */ + y ^= (y >> 11); + y ^= (y << 7) & 0x9d2c5680UL; + y ^= (y << 15) & 0xefc60000UL; + y ^= (y >> 18); + + t->gen.int_ = y; + + return y; +} + +double mrb_random_genrand_real1(mt_state *t) +{ + mrb_random_genrand_int32(t); + t->gen.double_ = t->gen.int_*(1.0/4294967295.0); + return t->gen.double_; + /* divided by 2^32-1 */ +} + +#if 0 /* dead_code */ +/* initializes mt[N] with a seed */ +void init_genrand(unsigned long s) +{ + mt[0]= s & 0xffffffffUL; + for (mti=1; mti> 30)) + mti); + /* See Knuth TAOCP Vol2. 3rd Ed. P.106 for multiplier. */ + /* In the previous versions, MSBs of the seed affect */ + /* only MSBs of the array mt[]. */ + /* 2002/01/09 modified by Makoto Matsumoto */ + mt[mti] &= 0xffffffffUL; + /* for >32 bit machines */ + } +} + +/* initialize by an array with array-length */ +/* init_key is the array for initializing keys */ +/* key_length is its length */ +/* slight change for C++, 2004/2/26 */ +void init_by_array(unsigned long init_key[], int key_length) +{ + int i, j, k; + init_genrand(19650218UL); + i=1; j=0; + k = (N>key_length ? N : key_length); + for (; k; k--) { + mt[i] = (mt[i] ^ ((mt[i-1] ^ (mt[i-1] >> 30)) * 1664525UL)) + + init_key[j] + j; /* non linear */ + mt[i] &= 0xffffffffUL; /* for WORDSIZE > 32 machines */ + i++; j++; + if (i>=N) { mt[0] = mt[N-1]; i=1; } + if (j>=key_length) j=0; + } + for (k=N-1; k; k--) { + mt[i] = (mt[i] ^ ((mt[i-1] ^ (mt[i-1] >> 30)) * 1566083941UL)) + - i; /* non linear */ + mt[i] &= 0xffffffffUL; /* for WORDSIZE > 32 machines */ + i++; + if (i>=N) { mt[0] = mt[N-1]; i=1; } + } + + mt[0] = 0x80000000UL; /* MSB is 1; assuring non-zero initial array */ +} + +/* generates a random number on [0,0xffffffff]-interval */ +unsigned long genrand_int32(void) +{ + unsigned long y; + static const unsigned long mag01[2]={0x0UL, MATRIX_A}; + /* mag01[x] = x * MATRIX_A for x=0,1 */ + + if (mti >= N) { /* generate N words at one time */ + int kk; + + if (mti == N+1) /* if init_genrand() has not been called, */ + init_genrand(5489UL); /* a default initial seed is used */ + + for (kk=0;kk> 1) ^ mag01[y & 0x1UL]; + } + for (;kk> 1) ^ mag01[y & 0x1UL]; + } + y = (mt[N-1]&UPPER_MASK)|(mt[0]&LOWER_MASK); + mt[N-1] = mt[M-1] ^ (y >> 1) ^ mag01[y & 0x1UL]; + + mti = 0; + } + + y = mt[mti++]; + + /* Tempering */ + y ^= (y >> 11); + y ^= (y << 7) & 0x9d2c5680UL; + y ^= (y << 15) & 0xefc60000UL; + y ^= (y >> 18); + + return y; +} + +/* generates a random number on [0,0x7fffffff]-interval */ +long genrand_int31(void) +{ + return (long)(genrand_int32()>>1); +} + +/* generates a random number on [0,1]-real-interval */ +double genrand_real1(void) +{ + return genrand_int32()*(1.0/4294967295.0); + /* divided by 2^32-1 */ +} + +/* generates a random number on [0,1)-real-interval */ +double genrand_real2(void) +{ + return genrand_int32()*(1.0/4294967296.0); + /* divided by 2^32 */ +} + +/* generates a random number on (0,1)-real-interval */ +double genrand_real3(void) +{ + return (((double)genrand_int32()) + 0.5)*(1.0/4294967296.0); + /* divided by 2^32 */ +} + +/* generates a random number on [0,1) with 53-bit resolution*/ +double genrand_res53(void) +{ + unsigned long a=genrand_int32()>>5, b=genrand_int32()>>6; + return(a*67108864.0+b)*(1.0/9007199254740992.0); +} +/* These real versions are due to Isaku Wada, 2002/01/09 added */ +#endif /* dead_code */ diff --git a/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-random/src/mt19937ar.h b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-random/src/mt19937ar.h new file mode 100644 index 00000000..7d382320 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-random/src/mt19937ar.h @@ -0,0 +1,80 @@ +/* +** mt19937ar.h - MT Random functions +** +** Copyright (C) 1997 - 2016, Makoto Matsumoto and Takuji Nishimura, +** All rights reserved. +** +** Permission is hereby granted, free of charge, to any person obtaining +** a copy of this software and associated documentation files (the +** "Software"), to deal in the Software without restriction, including +** without limitation the rights to use, copy, modify, merge, publish, +** distribute, sublicense, and/or sell copies of the Software, and to +** permit persons to whom the Software is furnished to do so, subject to +** the following conditions: +** +** The above copyright notice and this permission notice shall be +** included in all copies or substantial portions of the Software. +** +** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +** SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +** +** [ MIT license: http://www.opensource.org/licenses/mit-license.php ] +** +** Any feedback is very welcome. +** http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/emt.html +** email: m-mat @ math.sci.hiroshima-u.ac.jp (remove space) +** +** This version is modified by mruby developers. If you see any problem, +** contact us first at https://github.com/mruby/mruby/issues +*/ + +#define N 624 + +typedef struct { + unsigned long mt[N]; + int mti; + union { + unsigned long int_; + double double_; + } gen; + + mrb_int seed; + mrb_bool has_seed : 1; +} mt_state; + +void mrb_random_init_genrand(mt_state *, unsigned long); +unsigned long mrb_random_genrand_int32(mt_state *); +double mrb_random_genrand_real1(mt_state *t); + +/* initializes mt[N] with a seed */ +void init_genrand(unsigned long s); + +/* initialize by an array with array-length */ +/* init_key is the array for initializing keys */ +/* key_length is its length */ +/* slight change for C++, 2004/2/26 */ +void init_by_array(unsigned long init_key[], int key_length); + +/* generates a random number on [0,0xffffffff]-interval */ +unsigned long genrand_int32(void); + +/* generates a random number on [0,0x7fffffff]-interval */ +long genrand_int31(void); + +/* These real versions are due to Isaku Wada, 2002/01/09 added */ +/* generates a random number on [0,1]-real-interval */ +double genrand_real1(void); + +/* generates a random number on [0,1)-real-interval */ +double genrand_real2(void); + +/* generates a random number on (0,1)-real-interval */ +double genrand_real3(void); + +/* generates a random number on [0,1) with 53-bit resolution*/ +double genrand_res53(void); diff --git a/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-random/src/random.c b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-random/src/random.c new file mode 100644 index 00000000..b865244c --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-random/src/random.c @@ -0,0 +1,349 @@ +/* +** random.c - Random module +** +** See Copyright Notice in mruby.h +*/ + +#include +#include +#include +#include +#include +#include "mt19937ar.h" + +#include + +static char const MT_STATE_KEY[] = "$mrb_i_mt_state"; + +static const struct mrb_data_type mt_state_type = { + MT_STATE_KEY, mrb_free, +}; + +static mrb_value mrb_random_rand(mrb_state *mrb, mrb_value self); +static mrb_value mrb_random_srand(mrb_state *mrb, mrb_value self); + +static void +mt_srand(mt_state *t, unsigned long seed) +{ + mrb_random_init_genrand(t, seed); +} + +static unsigned long +mt_rand(mt_state *t) +{ + return mrb_random_genrand_int32(t); +} + +static double +mt_rand_real(mt_state *t) +{ + return mrb_random_genrand_real1(t); +} + +static mrb_value +mrb_random_mt_srand(mrb_state *mrb, mt_state *t, mrb_value seed) +{ + if (mrb_nil_p(seed)) { + seed = mrb_fixnum_value((mrb_int)(time(NULL) + mt_rand(t))); + if (mrb_fixnum(seed) < 0) { + seed = mrb_fixnum_value(0 - mrb_fixnum(seed)); + } + } + + mt_srand(t, (unsigned) mrb_fixnum(seed)); + + return seed; +} + +static mrb_value +mrb_random_mt_rand(mrb_state *mrb, mt_state *t, mrb_value max) +{ + mrb_value value; + + if (mrb_fixnum(max) == 0) { + value = mrb_float_value(mrb, mt_rand_real(t)); + } + else { + value = mrb_fixnum_value(mt_rand(t) % mrb_fixnum(max)); + } + + return value; +} + +static mrb_value +get_opt(mrb_state* mrb) +{ + mrb_value arg; + + arg = mrb_nil_value(); + mrb_get_args(mrb, "|o", &arg); + + if (!mrb_nil_p(arg)) { + arg = mrb_check_convert_type(mrb, arg, MRB_TT_FIXNUM, "Fixnum", "to_int"); + if (mrb_nil_p(arg)) { + mrb_raise(mrb, E_ARGUMENT_ERROR, "invalid argument type"); + } + if (mrb_fixnum(arg) < 0) { + arg = mrb_fixnum_value(0 - mrb_fixnum(arg)); + } + } + return arg; +} + +static mrb_value +get_random(mrb_state *mrb) { + return mrb_const_get(mrb, + mrb_obj_value(mrb_class_get(mrb, "Random")), + mrb_intern_lit(mrb, "DEFAULT")); +} + +static mt_state * +get_random_state(mrb_state *mrb) +{ + mrb_value random_val = get_random(mrb); + return DATA_GET_PTR(mrb, random_val, &mt_state_type, mt_state); +} + +static mrb_value +mrb_random_g_rand(mrb_state *mrb, mrb_value self) +{ + mrb_value random = get_random(mrb); + return mrb_random_rand(mrb, random); +} + +static mrb_value +mrb_random_g_srand(mrb_state *mrb, mrb_value self) +{ + mrb_value random = get_random(mrb); + return mrb_random_srand(mrb, random); +} + +static mrb_value +mrb_random_init(mrb_state *mrb, mrb_value self) +{ + mrb_value seed; + mt_state *t; + + seed = get_opt(mrb); + + /* avoid memory leaks */ + t = (mt_state*)DATA_PTR(self); + if (t) { + mrb_free(mrb, t); + } + mrb_data_init(self, NULL, &mt_state_type); + + t = (mt_state *)mrb_malloc(mrb, sizeof(mt_state)); + t->mti = N + 1; + + seed = mrb_random_mt_srand(mrb, t, seed); + if (mrb_nil_p(seed)) { + t->has_seed = FALSE; + } + else { + mrb_assert(mrb_fixnum_p(seed)); + t->has_seed = TRUE; + t->seed = mrb_fixnum(seed); + } + + mrb_data_init(self, t, &mt_state_type); + + return self; +} + +static void +mrb_random_rand_seed(mrb_state *mrb, mt_state *t) +{ + if (!t->has_seed) { + mrb_random_mt_srand(mrb, t, mrb_nil_value()); + } +} + +static mrb_value +mrb_random_rand(mrb_state *mrb, mrb_value self) +{ + mrb_value max; + mt_state *t = DATA_GET_PTR(mrb, self, &mt_state_type, mt_state); + + max = get_opt(mrb); + mrb_random_rand_seed(mrb, t); + return mrb_random_mt_rand(mrb, t, max); +} + +static mrb_value +mrb_random_srand(mrb_state *mrb, mrb_value self) +{ + mrb_value seed; + mrb_value old_seed; + mt_state *t = DATA_GET_PTR(mrb, self, &mt_state_type, mt_state); + + seed = get_opt(mrb); + seed = mrb_random_mt_srand(mrb, t, seed); + old_seed = t->has_seed? mrb_fixnum_value(t->seed) : mrb_nil_value(); + if (mrb_nil_p(seed)) { + t->has_seed = FALSE; + } + else { + mrb_assert(mrb_fixnum_p(seed)); + t->has_seed = TRUE; + t->seed = mrb_fixnum(seed); + } + + return old_seed; +} + +/* + * call-seq: + * ary.shuffle! -> ary + * + * Shuffles elements in self in place. + */ + +static mrb_value +mrb_ary_shuffle_bang(mrb_state *mrb, mrb_value ary) +{ + mrb_int i; + mt_state *random = NULL; + + if (RARRAY_LEN(ary) > 1) { + mrb_get_args(mrb, "|d", &random, &mt_state_type); + + if (random == NULL) { + random = get_random_state(mrb); + } + mrb_random_rand_seed(mrb, random); + + mrb_ary_modify(mrb, mrb_ary_ptr(ary)); + + for (i = RARRAY_LEN(ary) - 1; i > 0; i--) { + mrb_int j; + mrb_value *ptr = RARRAY_PTR(ary); + mrb_value tmp; + + + j = mrb_fixnum(mrb_random_mt_rand(mrb, random, mrb_fixnum_value(RARRAY_LEN(ary)))); + + tmp = ptr[i]; + ptr[i] = ptr[j]; + ptr[j] = tmp; + } + } + + return ary; +} + +/* + * call-seq: + * ary.shuffle -> new_ary + * + * Returns a new array with elements of self shuffled. + */ + +static mrb_value +mrb_ary_shuffle(mrb_state *mrb, mrb_value ary) +{ + mrb_value new_ary = mrb_ary_new_from_values(mrb, RARRAY_LEN(ary), RARRAY_PTR(ary)); + mrb_ary_shuffle_bang(mrb, new_ary); + + return new_ary; +} + +/* + * call-seq: + * ary.sample -> obj + * ary.sample(n) -> new_ary + * + * Choose a random element or +n+ random elements from the array. + * + * The elements are chosen by using random and unique indices into the array + * in order to ensure that an element doesn't repeat itself unless the array + * already contained duplicate elements. + * + * If the array is empty the first form returns +nil+ and the second form + * returns an empty array. + */ + +static mrb_value +mrb_ary_sample(mrb_state *mrb, mrb_value ary) +{ + mrb_int n = 0; + mrb_bool given; + mt_state *random = NULL; + mrb_int len; + + mrb_get_args(mrb, "|i?d", &n, &given, &random, &mt_state_type); + if (random == NULL) { + random = get_random_state(mrb); + } + mrb_random_rand_seed(mrb, random); + mt_rand(random); + len = RARRAY_LEN(ary); + if (!given) { /* pick one element */ + switch (len) { + case 0: + return mrb_nil_value(); + case 1: + return RARRAY_PTR(ary)[0]; + default: + return RARRAY_PTR(ary)[mt_rand(random) % len]; + } + } + else { + mrb_value result; + mrb_int i, j; + + if (n < 0) mrb_raise(mrb, E_ARGUMENT_ERROR, "negative sample number"); + if (n > len) n = len; + result = mrb_ary_new_capa(mrb, n); + for (i=0; iarray_class; + + mrb_define_method(mrb, mrb->kernel_module, "rand", mrb_random_g_rand, MRB_ARGS_OPT(1)); + mrb_define_method(mrb, mrb->kernel_module, "srand", mrb_random_g_srand, MRB_ARGS_OPT(1)); + + random = mrb_define_class(mrb, "Random", mrb->object_class); + MRB_SET_INSTANCE_TT(random, MRB_TT_DATA); + mrb_define_class_method(mrb, random, "rand", mrb_random_g_rand, MRB_ARGS_OPT(1)); + mrb_define_class_method(mrb, random, "srand", mrb_random_g_srand, MRB_ARGS_OPT(1)); + + mrb_define_method(mrb, random, "initialize", mrb_random_init, MRB_ARGS_OPT(1)); + mrb_define_method(mrb, random, "rand", mrb_random_rand, MRB_ARGS_OPT(1)); + mrb_define_method(mrb, random, "srand", mrb_random_srand, MRB_ARGS_OPT(1)); + + mrb_define_method(mrb, array, "shuffle", mrb_ary_shuffle, MRB_ARGS_OPT(1)); + mrb_define_method(mrb, array, "shuffle!", mrb_ary_shuffle_bang, MRB_ARGS_OPT(1)); + mrb_define_method(mrb, array, "sample", mrb_ary_sample, MRB_ARGS_OPT(2)); + + mrb_const_set(mrb, mrb_obj_value(random), mrb_intern_lit(mrb, "DEFAULT"), + mrb_obj_new(mrb, random, 0, NULL)); +} + +void mrb_mruby_random_gem_final(mrb_state *mrb) +{ +} diff --git a/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-random/src/random.h b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-random/src/random.h new file mode 100644 index 00000000..a4785ae5 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-random/src/random.h @@ -0,0 +1,12 @@ +/* +** random.h - Random module +** +** See Copyright Notice in mruby.h +*/ + +#ifndef MRUBY_RANDOM_H +#define MRUBY_RANDOM_H + +void mrb_mruby_random_gem_init(mrb_state *mrb); + +#endif diff --git a/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-random/test/random.rb b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-random/test/random.rb new file mode 100644 index 00000000..1c59be3a --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-random/test/random.rb @@ -0,0 +1,88 @@ +## +# Random Test + +assert("Random#srand") do + r1 = Random.new(123) + r2 = Random.new(123) + r1.rand == r2.rand +end + +assert("Kernel::srand") do + srand(234) + r1 = rand + srand(234) + r2 = rand + r1 == r2 +end + +assert("Random::srand") do + Random.srand(345) + r1 = rand + srand(345) + r2 = Random.rand + r1 == r2 +end + +assert("fixnum") do + rand(3).class == Fixnum +end + +assert("float") do + rand.class == Float +end + +assert("Array#shuffle") do + ary = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] + shuffled = ary.shuffle + + ary == [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] and shuffled != ary and 10.times { |x| ary.include? x } +end + +assert('Array#shuffle!') do + ary = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] + ary.shuffle! + + ary != [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] and 10.times { |x| ary.include? x } +end + +assert("Array#shuffle(random)") do + assert_raise(TypeError) do + # this will cause an exception due to the wrong argument + [1, 2].shuffle "Not a Random instance" + end + + # verify that the same seed causes the same results + ary1 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] + shuffle1 = ary1.shuffle Random.new 345 + ary2 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] + shuffle2 = ary2.shuffle Random.new 345 + + ary1 != shuffle1 and 10.times { |x| shuffle1.include? x } and shuffle1 == shuffle2 +end + +assert('Array#shuffle!(random)') do + assert_raise(TypeError) do + # this will cause an exception due to the wrong argument + [1, 2].shuffle! "Not a Random instance" + end + + # verify that the same seed causes the same results + ary1 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] + ary1.shuffle! Random.new 345 + ary2 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] + ary2.shuffle! Random.new 345 + + ary1 != [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] and 10.times { |x| ary1.include? x } and ary1 == ary2 +end + +assert('Array#sample checks input length after reading arguments') do + $ary = [1, 2, 3] + class ArrayChange + def to_i + $ary << 4 + 4 + end + end + + assert_equal [1, 2, 3, 4], $ary.sample(ArrayChange.new).sort +end diff --git a/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-range-ext/mrbgem.rake b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-range-ext/mrbgem.rake new file mode 100644 index 00000000..e6fa7df5 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-range-ext/mrbgem.rake @@ -0,0 +1,5 @@ +MRuby::Gem::Specification.new('mruby-range-ext') do |spec| + spec.license = 'MIT' + spec.author = 'mruby developers' + spec.summary = 'Range class extension' +end diff --git a/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-range-ext/mrblib/range.rb b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-range-ext/mrblib/range.rb new file mode 100644 index 00000000..e5d1fb07 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-range-ext/mrblib/range.rb @@ -0,0 +1,31 @@ +class Range + ## + # call-seq: + # rng.first -> obj + # rng.first(n) -> an_array + # + # Returns the first object in the range, or an array of the first +n+ + # elements. + # + # (10..20).first #=> 10 + # (10..20).first(3) #=> [10, 11, 12] + # + def first(*args) + return self.begin if args.empty? + + raise ArgumentError, "wrong number of arguments (given #{args.length}, expected 1)" unless args.length == 1 + nv = args[0] + raise TypeError, "no implicit conversion from nil to integer" if nv.nil? + raise TypeError, "no implicit conversion of #{nv.class} into Integer" unless nv.respond_to?(:to_int) + n = nv.to_int + raise TypeError, "no implicit conversion of #{nv.class} into Integer" unless n.kind_of?(Integer) + raise ArgumentError, "negative array size (or size too big)" unless 0 <= n + ary = [] + each do |i| + break if n <= 0 + ary.push(i) + n -= 1 + end + ary + end +end diff --git a/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-range-ext/src/range.c b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-range-ext/src/range.c new file mode 100644 index 00000000..aca71cc0 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-range-ext/src/range.c @@ -0,0 +1,176 @@ +#include +#include +#include + +static mrb_bool +r_le(mrb_state *mrb, mrb_value a, mrb_value b) +{ + mrb_value r = mrb_funcall(mrb, a, "<=>", 1, b); /* compare result */ + /* output :a < b => -1, a = b => 0, a > b => +1 */ + + if (mrb_fixnum_p(r)) { + mrb_int c = mrb_fixnum(r); + if (c == 0 || c == -1) return TRUE; + } + + return FALSE; +} + +static mrb_bool +r_lt(mrb_state *mrb, mrb_value a, mrb_value b) +{ + mrb_value r = mrb_funcall(mrb, a, "<=>", 1, b); + /* output :a < b => -1, a = b => 0, a > b => +1 */ + + return mrb_fixnum_p(r) && mrb_fixnum(r) == -1; +} + +/* + * call-seq: + * rng.cover?(obj) -> true or false + * + * Returns true if +obj+ is between the begin and end of + * the range. + * + * This tests begin <= obj <= end when #exclude_end? is +false+ + * and begin <= obj < end when #exclude_end? is +true+. + * + * ("a".."z").cover?("c") #=> true + * ("a".."z").cover?("5") #=> false + * ("a".."z").cover?("cc") #=> true + */ +static mrb_value +mrb_range_cover(mrb_state *mrb, mrb_value range) +{ + mrb_value val; + struct RRange *r = mrb_range_ptr(mrb, range); + mrb_value beg, end; + + mrb_get_args(mrb, "o", &val); + + beg = r->edges->beg; + end = r->edges->end; + + if (r_le(mrb, beg, val)) { + if (r->excl) { + if (r_lt(mrb, val, end)) + return mrb_true_value(); + } + else { + if (r_le(mrb, val, end)) + return mrb_true_value(); + } + } + + return mrb_false_value(); +} + +/* + * call-seq: + * rng.last -> obj + * rng.last(n) -> an_array + * + * Returns the last object in the range, + * or an array of the last +n+ elements. + * + * Note that with no arguments +last+ will return the object that defines + * the end of the range even if #exclude_end? is +true+. + * + * (10..20).last #=> 20 + * (10...20).last #=> 20 + * (10..20).last(3) #=> [18, 19, 20] + * (10...20).last(3) #=> [17, 18, 19] + */ +static mrb_value +mrb_range_last(mrb_state *mrb, mrb_value range) +{ + mrb_value num; + mrb_value array; + struct RRange *r = mrb_range_ptr(mrb, range); + + if (mrb_get_args(mrb, "|o", &num) == 0) { + return r->edges->end; + } + + array = mrb_funcall(mrb, range, "to_a", 0); + return mrb_funcall(mrb, array, "last", 1, mrb_to_int(mrb, num)); +} + +/* + * call-seq: + * rng.size -> num + * + * Returns the number of elements in the range. Both the begin and the end of + * the Range must be Numeric, otherwise nil is returned. + * + * (10..20).size #=> 11 + * ('a'..'z').size #=> nil + */ + +static mrb_value +mrb_range_size(mrb_state *mrb, mrb_value range) +{ + struct RRange *r = mrb_range_ptr(mrb, range); + mrb_value beg, end; + mrb_float beg_f, end_f; + mrb_bool num_p = TRUE; + mrb_bool excl; + + beg = r->edges->beg; + end = r->edges->end; + excl = r->excl; + if (mrb_fixnum_p(beg)) { + beg_f = (mrb_float)mrb_fixnum(beg); + } + else if (mrb_float_p(beg)) { + beg_f = mrb_float(beg); + } + else { + num_p = FALSE; + } + if (mrb_fixnum_p(end)) { + end_f = (mrb_float)mrb_fixnum(end); + } + else if (mrb_float_p(end)) { + end_f = mrb_float(end); + } + else { + num_p = FALSE; + } + if (num_p) { + mrb_float n = end_f - beg_f; + mrb_float err = (fabs(beg_f) + fabs(end_f) + fabs(end_f-beg_f)) * MRB_FLOAT_EPSILON; + + if (err>0.5) err=0.5; + if (excl) { + if (n<=0) return mrb_fixnum_value(0); + if (n<1) + n = 0; + else + n = floor(n - err); + } + else { + if (n<0) return mrb_fixnum_value(0); + n = floor(n + err); + } + if (isinf(n+1)) + return mrb_float_value(mrb, INFINITY); + return mrb_fixnum_value((mrb_int)n+1); + } + return mrb_nil_value(); +} + +void +mrb_mruby_range_ext_gem_init(mrb_state* mrb) +{ + struct RClass * s = mrb_class_get(mrb, "Range"); + + mrb_define_method(mrb, s, "cover?", mrb_range_cover, MRB_ARGS_REQ(1)); + mrb_define_method(mrb, s, "last", mrb_range_last, MRB_ARGS_OPT(1)); + mrb_define_method(mrb, s, "size", mrb_range_size, MRB_ARGS_NONE()); +} + +void +mrb_mruby_range_ext_gem_final(mrb_state* mrb) +{ +} diff --git a/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-range-ext/test/range.rb b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-range-ext/test/range.rb new file mode 100644 index 00000000..efcbdabe --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-range-ext/test/range.rb @@ -0,0 +1,32 @@ +## +# Range(Ext) Test + +assert('Range#cover?') do + assert_true ("a".."z").cover?("c") + assert_true !("a".."z").cover?("5") + assert_true ("a".."z").cover?("cc") +end + +assert('Range#first') do + assert_equal 10, (10..20).first + assert_equal [10, 11, 12], (10..20).first(3) + assert_equal [0, 1, 2], (0..Float::INFINITY).first(3) +end + +assert('Range#last') do + assert_equal 20, (10..20).last + assert_equal 20, (10...20).last + assert_equal [18, 19, 20], (10..20).last(3) + assert_equal [17, 18, 19], (10...20).last(3) +end + +assert('Range#size') do + assert_equal 42, (1..42).size + assert_equal 41, (1...42).size + assert_equal 6, (1...6.3).size + assert_equal 5, (1...6.0).size + assert_equal 5, (1.1...6).size + assert_equal 15, (1.0..15.9).size + assert_equal Float::INFINITY, (0..Float::INFINITY).size + assert_nil ('a'..'z').size +end diff --git a/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-sprintf/mrbgem.rake b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-sprintf/mrbgem.rake new file mode 100644 index 00000000..bc897243 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-sprintf/mrbgem.rake @@ -0,0 +1,5 @@ +MRuby::Gem::Specification.new('mruby-sprintf') do |spec| + spec.license = 'MIT' + spec.author = 'mruby developers' + spec.summary = 'standard Kernel#sprintf method' +end diff --git a/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-sprintf/mrblib/string.rb b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-sprintf/mrblib/string.rb new file mode 100644 index 00000000..d7e55536 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-sprintf/mrblib/string.rb @@ -0,0 +1,9 @@ +class String + def %(args) + if args.is_a? Array + sprintf(self, *args) + else + sprintf(self, args) + end + end +end diff --git a/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-sprintf/src/kernel.c b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-sprintf/src/kernel.c new file mode 100644 index 00000000..946b43a8 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-sprintf/src/kernel.c @@ -0,0 +1,30 @@ +/* +** kernel.c - Kernel module suppliment +** +** See Copyright Notice in mruby.h +*/ + +#include + +mrb_value mrb_f_sprintf(mrb_state *mrb, mrb_value obj); /* in sprintf.c */ + +void +mrb_mruby_sprintf_gem_init(mrb_state* mrb) +{ + struct RClass *krn; + + if (mrb->kernel_module == NULL) { + mrb->kernel_module = mrb_define_module(mrb, "Kernel"); /* Might be PARANOID. */ + } + krn = mrb->kernel_module; + + mrb_define_method(mrb, krn, "sprintf", mrb_f_sprintf, MRB_ARGS_ANY()); + mrb_define_method(mrb, krn, "format", mrb_f_sprintf, MRB_ARGS_ANY()); +} + +void +mrb_mruby_sprintf_gem_final(mrb_state* mrb) +{ + /* nothing to do. */ +} + diff --git a/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-sprintf/src/sprintf.c b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-sprintf/src/sprintf.c new file mode 100644 index 00000000..d2069924 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-sprintf/src/sprintf.c @@ -0,0 +1,1113 @@ +/* +** sprintf.c - Kernel.#sprintf +** +** See Copyright Notice in mruby.h +*/ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#define BIT_DIGITS(N) (((N)*146)/485 + 1) /* log2(10) =~ 146/485 */ +#define BITSPERDIG MRB_INT_BIT +#define EXTENDSIGN(n, l) (((~0U << (n)) >> (((n)*(l)) % BITSPERDIG)) & ~(~0U << (n))) + +mrb_value mrb_str_format(mrb_state *, int, const mrb_value *, mrb_value); +static void fmt_setup(char*,size_t,int,int,mrb_int,mrb_int); + +static char* +remove_sign_bits(char *str, int base) +{ + char *t; + + t = str; + if (base == 16) { + while (*t == 'f') { + t++; + } + } + else if (base == 8) { + *t |= EXTENDSIGN(3, strlen(t)); + while (*t == '7') { + t++; + } + } + else if (base == 2) { + while (*t == '1') { + t++; + } + } + + return t; +} + +static char +sign_bits(int base, const char *p) +{ + char c; + + switch (base) { + case 16: + if (*p == 'X') c = 'F'; + else c = 'f'; + break; + case 8: + c = '7'; break; + case 2: + c = '1'; break; + default: + c = '.'; break; + } + return c; +} + +static mrb_value +mrb_fix2binstr(mrb_state *mrb, mrb_value x, int base) +{ + char buf[66], *b = buf + sizeof buf; + mrb_int num = mrb_fixnum(x); + uint64_t val = (uint64_t)num; + char d; + + if (base != 2) { + mrb_raisef(mrb, E_ARGUMENT_ERROR, "invalid radix %S", mrb_fixnum_value(base)); + } + if (val == 0) { + return mrb_str_new_lit(mrb, "0"); + } + *--b = '\0'; + do { + *--b = mrb_digitmap[(int)(val % base)]; + } while (val /= base); + + if (num < 0) { + b = remove_sign_bits(b, base); + switch (base) { + case 16: d = 'f'; break; + case 8: d = '7'; break; + case 2: d = '1'; break; + default: d = 0; break; + } + + if (d && *b != d) { + *--b = d; + } + } + + return mrb_str_new_cstr(mrb, b); +} + +#define FNONE 0 +#define FSHARP 1 +#define FMINUS 2 +#define FPLUS 4 +#define FZERO 8 +#define FSPACE 16 +#define FWIDTH 32 +#define FPREC 64 +#define FPREC0 128 + +#define CHECK(l) do {\ +/* int cr = ENC_CODERANGE(result);*/\ + while ((l) >= bsiz - blen) {\ + bsiz*=2;\ + if (bsiz < 0) mrb_raise(mrb, E_ARGUMENT_ERROR, "too big specifier"); \ + }\ + mrb_str_resize(mrb, result, bsiz);\ +/* ENC_CODERANGE_SET(result, cr);*/\ + buf = RSTRING_PTR(result);\ +} while (0) + +#define PUSH(s, l) do { \ + CHECK(l);\ + memcpy(&buf[blen], s, l);\ + blen += (mrb_int)(l);\ +} while (0) + +#define FILL(c, l) do { \ + CHECK(l);\ + memset(&buf[blen], c, l);\ + blen += (l);\ +} while (0) + +static void +check_next_arg(mrb_state *mrb, int posarg, int nextarg) +{ + switch (posarg) { + case -1: + mrb_raisef(mrb, E_ARGUMENT_ERROR, "unnumbered(%S) mixed with numbered", mrb_fixnum_value(nextarg)); + break; + case -2: + mrb_raisef(mrb, E_ARGUMENT_ERROR, "unnumbered(%S) mixed with named", mrb_fixnum_value(nextarg)); + break; + default: + break; + } +} + +static void +check_pos_arg(mrb_state *mrb, int posarg, int n) +{ + if (posarg > 0) { + mrb_raisef(mrb, E_ARGUMENT_ERROR, "numbered(%S) after unnumbered(%S)", + mrb_fixnum_value(n), mrb_fixnum_value(posarg)); + } + if (posarg == -2) { + mrb_raisef(mrb, E_ARGUMENT_ERROR, "numbered(%S) after named", mrb_fixnum_value(n)); + } + if (n < 1) { + mrb_raisef(mrb, E_ARGUMENT_ERROR, "invalid index - %S$", mrb_fixnum_value(n)); + } +} + +static void +check_name_arg(mrb_state *mrb, int posarg, const char *name, int len) +{ + if (posarg > 0) { + mrb_raisef(mrb, E_ARGUMENT_ERROR, "named%S after unnumbered(%S)", + mrb_str_new(mrb, (name), (len)), mrb_fixnum_value(posarg)); + } + if (posarg == -1) { + mrb_raisef(mrb, E_ARGUMENT_ERROR, "named%S after numbered", mrb_str_new(mrb, (name), (len))); + } +} + +#define GETNEXTARG() (\ + check_next_arg(mrb, posarg, nextarg),\ + (posarg = nextarg++, GETNTHARG(posarg))) + +#define GETARG() (!mrb_undef_p(nextvalue) ? nextvalue : GETNEXTARG()) + +#define GETPOSARG(n) (\ + check_pos_arg(mrb, posarg, n),\ + (posarg = -1, GETNTHARG(n))) + +#define GETNTHARG(nth) \ + ((nth >= argc) ? (mrb_raise(mrb, E_ARGUMENT_ERROR, "too few arguments"), mrb_undef_value()) : argv[nth]) + +#define GETNAMEARG(id, name, len) (\ + check_name_arg(mrb, posarg, name, len),\ + (posarg = -2, mrb_hash_fetch(mrb, get_hash(mrb, &hash, argc, argv), id, mrb_undef_value()))) + +#define GETNUM(n, val) \ + for (; p < end && ISDIGIT(*p); p++) {\ + int next_n = 10 * n + (*p - '0'); \ + if (next_n / 10 != n) {\ + mrb_raise(mrb, E_ARGUMENT_ERROR, #val " too big"); \ + } \ + n = next_n; \ + } \ + if (p >= end) { \ + mrb_raise(mrb, E_ARGUMENT_ERROR, "malformed format string - %*[0-9]"); \ + } + +#define GETASTER(num) do { \ + mrb_value tmp_v; \ + t = p++; \ + n = 0; \ + GETNUM(n, val); \ + if (*p == '$') { \ + tmp_v = GETPOSARG(n); \ + } \ + else { \ + tmp_v = GETNEXTARG(); \ + p = t; \ + } \ + num = mrb_int(mrb, tmp_v); \ +} while (0) + +static mrb_value +get_hash(mrb_state *mrb, mrb_value *hash, int argc, const mrb_value *argv) +{ + mrb_value tmp; + + if (!mrb_undef_p(*hash)) return *hash; + if (argc != 2) { + mrb_raise(mrb, E_ARGUMENT_ERROR, "one hash required"); + } + tmp = mrb_check_convert_type(mrb, argv[1], MRB_TT_HASH, "Hash", "to_hash"); + if (mrb_nil_p(tmp)) { + mrb_raise(mrb, E_ARGUMENT_ERROR, "one hash required"); + } + return (*hash = tmp); +} + +/* + * call-seq: + * format(format_string [, arguments...] ) -> string + * sprintf(format_string [, arguments...] ) -> string + * + * Returns the string resulting from applying format_string to + * any additional arguments. Within the format string, any characters + * other than format sequences are copied to the result. + * + * The syntax of a format sequence is follows. + * + * %[flags][width][.precision]type + * + * A format + * sequence consists of a percent sign, followed by optional flags, + * width, and precision indicators, then terminated with a field type + * character. The field type controls how the corresponding + * sprintf argument is to be interpreted, while the flags + * modify that interpretation. + * + * The field type characters are: + * + * Field | Integer Format + * ------+-------------------------------------------------------------- + * b | Convert argument as a binary number. + * | Negative numbers will be displayed as a two's complement + * | prefixed with '..1'. + * B | Equivalent to 'b', but uses an uppercase 0B for prefix + * | in the alternative format by #. + * d | Convert argument as a decimal number. + * i | Identical to 'd'. + * o | Convert argument as an octal number. + * | Negative numbers will be displayed as a two's complement + * | prefixed with '..7'. + * u | Identical to 'd'. + * x | Convert argument as a hexadecimal number. + * | Negative numbers will be displayed as a two's complement + * | prefixed with '..f' (representing an infinite string of + * | leading 'ff's). + * X | Equivalent to 'x', but uses uppercase letters. + * + * Field | Float Format + * ------+-------------------------------------------------------------- + * e | Convert floating point argument into exponential notation + * | with one digit before the decimal point as [-]d.dddddde[+-]dd. + * | The precision specifies the number of digits after the decimal + * | point (defaulting to six). + * E | Equivalent to 'e', but uses an uppercase E to indicate + * | the exponent. + * f | Convert floating point argument as [-]ddd.dddddd, + * | where the precision specifies the number of digits after + * | the decimal point. + * g | Convert a floating point number using exponential form + * | if the exponent is less than -4 or greater than or + * | equal to the precision, or in dd.dddd form otherwise. + * | The precision specifies the number of significant digits. + * G | Equivalent to 'g', but use an uppercase 'E' in exponent form. + * a | Convert floating point argument as [-]0xh.hhhhp[+-]dd, + * | which is consisted from optional sign, "0x", fraction part + * | as hexadecimal, "p", and exponential part as decimal. + * A | Equivalent to 'a', but use uppercase 'X' and 'P'. + * + * Field | Other Format + * ------+-------------------------------------------------------------- + * c | Argument is the numeric code for a single character or + * | a single character string itself. + * p | The valuing of argument.inspect. + * s | Argument is a string to be substituted. If the format + * | sequence contains a precision, at most that many characters + * | will be copied. + * % | A percent sign itself will be displayed. No argument taken. + * + * The flags modifies the behavior of the formats. + * The flag characters are: + * + * Flag | Applies to | Meaning + * ---------+---------------+----------------------------------------- + * space | bBdiouxX | Leave a space at the start of + * | aAeEfgG | non-negative numbers. + * | (numeric fmt) | For 'o', 'x', 'X', 'b' and 'B', use + * | | a minus sign with absolute value for + * | | negative values. + * ---------+---------------+----------------------------------------- + * (digit)$ | all | Specifies the absolute argument number + * | | for this field. Absolute and relative + * | | argument numbers cannot be mixed in a + * | | sprintf string. + * ---------+---------------+----------------------------------------- + * # | bBoxX | Use an alternative format. + * | aAeEfgG | For the conversions 'o', increase the precision + * | | until the first digit will be '0' if + * | | it is not formatted as complements. + * | | For the conversions 'x', 'X', 'b' and 'B' + * | | on non-zero, prefix the result with "0x", + * | | "0X", "0b" and "0B", respectively. + * | | For 'a', 'A', 'e', 'E', 'f', 'g', and 'G', + * | | force a decimal point to be added, + * | | even if no digits follow. + * | | For 'g' and 'G', do not remove trailing zeros. + * ---------+---------------+----------------------------------------- + * + | bBdiouxX | Add a leading plus sign to non-negative + * | aAeEfgG | numbers. + * | (numeric fmt) | For 'o', 'x', 'X', 'b' and 'B', use + * | | a minus sign with absolute value for + * | | negative values. + * ---------+---------------+----------------------------------------- + * - | all | Left-justify the result of this conversion. + * ---------+---------------+----------------------------------------- + * 0 (zero) | bBdiouxX | Pad with zeros, not spaces. + * | aAeEfgG | For 'o', 'x', 'X', 'b' and 'B', radix-1 + * | (numeric fmt) | is used for negative numbers formatted as + * | | complements. + * ---------+---------------+----------------------------------------- + * * | all | Use the next argument as the field width. + * | | If negative, left-justify the result. If the + * | | asterisk is followed by a number and a dollar + * | | sign, use the indicated argument as the width. + * + * Examples of flags: + * + * # '+' and space flag specifies the sign of non-negative numbers. + * sprintf("%d", 123) #=> "123" + * sprintf("%+d", 123) #=> "+123" + * sprintf("% d", 123) #=> " 123" + * + * # '#' flag for 'o' increases number of digits to show '0'. + * # '+' and space flag changes format of negative numbers. + * sprintf("%o", 123) #=> "173" + * sprintf("%#o", 123) #=> "0173" + * sprintf("%+o", -123) #=> "-173" + * sprintf("%o", -123) #=> "..7605" + * sprintf("%#o", -123) #=> "..7605" + * + * # '#' flag for 'x' add a prefix '0x' for non-zero numbers. + * # '+' and space flag disables complements for negative numbers. + * sprintf("%x", 123) #=> "7b" + * sprintf("%#x", 123) #=> "0x7b" + * sprintf("%+x", -123) #=> "-7b" + * sprintf("%x", -123) #=> "..f85" + * sprintf("%#x", -123) #=> "0x..f85" + * sprintf("%#x", 0) #=> "0" + * + * # '#' for 'X' uses the prefix '0X'. + * sprintf("%X", 123) #=> "7B" + * sprintf("%#X", 123) #=> "0X7B" + * + * # '#' flag for 'b' add a prefix '0b' for non-zero numbers. + * # '+' and space flag disables complements for negative numbers. + * sprintf("%b", 123) #=> "1111011" + * sprintf("%#b", 123) #=> "0b1111011" + * sprintf("%+b", -123) #=> "-1111011" + * sprintf("%b", -123) #=> "..10000101" + * sprintf("%#b", -123) #=> "0b..10000101" + * sprintf("%#b", 0) #=> "0" + * + * # '#' for 'B' uses the prefix '0B'. + * sprintf("%B", 123) #=> "1111011" + * sprintf("%#B", 123) #=> "0B1111011" + * + * # '#' for 'e' forces to show the decimal point. + * sprintf("%.0e", 1) #=> "1e+00" + * sprintf("%#.0e", 1) #=> "1.e+00" + * + * # '#' for 'f' forces to show the decimal point. + * sprintf("%.0f", 1234) #=> "1234" + * sprintf("%#.0f", 1234) #=> "1234." + * + * # '#' for 'g' forces to show the decimal point. + * # It also disables stripping lowest zeros. + * sprintf("%g", 123.4) #=> "123.4" + * sprintf("%#g", 123.4) #=> "123.400" + * sprintf("%g", 123456) #=> "123456" + * sprintf("%#g", 123456) #=> "123456." + * + * The field width is an optional integer, followed optionally by a + * period and a precision. The width specifies the minimum number of + * characters that will be written to the result for this field. + * + * Examples of width: + * + * # padding is done by spaces, width=20 + * # 0 or radix-1. <------------------> + * sprintf("%20d", 123) #=> " 123" + * sprintf("%+20d", 123) #=> " +123" + * sprintf("%020d", 123) #=> "00000000000000000123" + * sprintf("%+020d", 123) #=> "+0000000000000000123" + * sprintf("% 020d", 123) #=> " 0000000000000000123" + * sprintf("%-20d", 123) #=> "123 " + * sprintf("%-+20d", 123) #=> "+123 " + * sprintf("%- 20d", 123) #=> " 123 " + * sprintf("%020x", -123) #=> "..ffffffffffffffff85" + * + * For + * numeric fields, the precision controls the number of decimal places + * displayed. For string fields, the precision determines the maximum + * number of characters to be copied from the string. (Thus, the format + * sequence %10.10s will always contribute exactly ten + * characters to the result.) + * + * Examples of precisions: + * + * # precision for 'd', 'o', 'x' and 'b' is + * # minimum number of digits <------> + * sprintf("%20.8d", 123) #=> " 00000123" + * sprintf("%20.8o", 123) #=> " 00000173" + * sprintf("%20.8x", 123) #=> " 0000007b" + * sprintf("%20.8b", 123) #=> " 01111011" + * sprintf("%20.8d", -123) #=> " -00000123" + * sprintf("%20.8o", -123) #=> " ..777605" + * sprintf("%20.8x", -123) #=> " ..ffff85" + * sprintf("%20.8b", -11) #=> " ..110101" + * + * # "0x" and "0b" for '#x' and '#b' is not counted for + * # precision but "0" for '#o' is counted. <------> + * sprintf("%#20.8d", 123) #=> " 00000123" + * sprintf("%#20.8o", 123) #=> " 00000173" + * sprintf("%#20.8x", 123) #=> " 0x0000007b" + * sprintf("%#20.8b", 123) #=> " 0b01111011" + * sprintf("%#20.8d", -123) #=> " -00000123" + * sprintf("%#20.8o", -123) #=> " ..777605" + * sprintf("%#20.8x", -123) #=> " 0x..ffff85" + * sprintf("%#20.8b", -11) #=> " 0b..110101" + * + * # precision for 'e' is number of + * # digits after the decimal point <------> + * sprintf("%20.8e", 1234.56789) #=> " 1.23456789e+03" + * + * # precision for 'f' is number of + * # digits after the decimal point <------> + * sprintf("%20.8f", 1234.56789) #=> " 1234.56789000" + * + * # precision for 'g' is number of + * # significant digits <-------> + * sprintf("%20.8g", 1234.56789) #=> " 1234.5679" + * + * # <-------> + * sprintf("%20.8g", 123456789) #=> " 1.2345679e+08" + * + * # precision for 's' is + * # maximum number of characters <------> + * sprintf("%20.8s", "string test") #=> " string t" + * + * Examples: + * + * sprintf("%d %04x", 123, 123) #=> "123 007b" + * sprintf("%08b '%4s'", 123, 123) #=> "01111011 ' 123'" + * sprintf("%1$*2$s %2$d %1$s", "hello", 8) #=> " hello 8 hello" + * sprintf("%1$*2$s %2$d", "hello", -8) #=> "hello -8" + * sprintf("%+g:% g:%-g", 1.23, 1.23, 1.23) #=> "+1.23: 1.23:1.23" + * sprintf("%u", -123) #=> "-123" + * + * For more complex formatting, Ruby supports a reference by name. + * %s style uses format style, but %{name} style doesn't. + * + * Exapmles: + * sprintf("%d : %f", { :foo => 1, :bar => 2 }) + * #=> 1 : 2.000000 + * sprintf("%{foo}f", { :foo => 1 }) + * # => "1f" + */ + +mrb_value +mrb_f_sprintf(mrb_state *mrb, mrb_value obj) +{ + mrb_int argc; + mrb_value *argv; + + mrb_get_args(mrb, "*", &argv, &argc); + + if (argc <= 0) { + mrb_raise(mrb, E_ARGUMENT_ERROR, "too few arguments"); + return mrb_nil_value(); + } + else { + return mrb_str_format(mrb, argc - 1, argv + 1, argv[0]); + } +} + +mrb_value +mrb_str_format(mrb_state *mrb, int argc, const mrb_value *argv, mrb_value fmt) +{ + const char *p, *end; + char *buf; + mrb_int blen; + mrb_int bsiz; + mrb_value result; + mrb_int n; + mrb_int width; + mrb_int prec; + int nextarg = 1; + int posarg = 0; + mrb_value nextvalue; + mrb_value str; + mrb_value hash = mrb_undef_value(); + +#define CHECK_FOR_WIDTH(f) \ + if ((f) & FWIDTH) { \ + mrb_raise(mrb, E_ARGUMENT_ERROR, "width given twice"); \ + } \ + if ((f) & FPREC0) { \ + mrb_raise(mrb, E_ARGUMENT_ERROR, "width after precision"); \ + } +#define CHECK_FOR_FLAGS(f) \ + if ((f) & FWIDTH) { \ + mrb_raise(mrb, E_ARGUMENT_ERROR, "flag after width"); \ + } \ + if ((f) & FPREC0) { \ + mrb_raise(mrb, E_ARGUMENT_ERROR, "flag after precision"); \ + } + + ++argc; + --argv; + fmt = mrb_str_to_str(mrb, fmt); + p = RSTRING_PTR(fmt); + end = p + RSTRING_LEN(fmt); + blen = 0; + bsiz = 120; + result = mrb_str_new_capa(mrb, bsiz); + buf = RSTRING_PTR(result); + memset(buf, 0, bsiz); + + for (; p < end; p++) { + const char *t; + mrb_sym id = 0; + int flags = FNONE; + + for (t = p; t < end && *t != '%'; t++) ; + if (t + 1 == end) ++t; + PUSH(p, t - p); + if (t >= end) + goto sprint_exit; /* end of fmt string */ + + p = t + 1; /* skip '%' */ + + width = prec = -1; + nextvalue = mrb_undef_value(); + +retry: + switch (*p) { + default: + mrb_raisef(mrb, E_ARGUMENT_ERROR, "malformed format string - \\%%S", mrb_str_new(mrb, p, 1)); + break; + + case ' ': + CHECK_FOR_FLAGS(flags); + flags |= FSPACE; + p++; + goto retry; + + case '#': + CHECK_FOR_FLAGS(flags); + flags |= FSHARP; + p++; + goto retry; + + case '+': + CHECK_FOR_FLAGS(flags); + flags |= FPLUS; + p++; + goto retry; + + case '-': + CHECK_FOR_FLAGS(flags); + flags |= FMINUS; + p++; + goto retry; + + case '0': + CHECK_FOR_FLAGS(flags); + flags |= FZERO; + p++; + goto retry; + + case '1': case '2': case '3': case '4': + case '5': case '6': case '7': case '8': case '9': + n = 0; + GETNUM(n, width); + if (*p == '$') { + if (!mrb_undef_p(nextvalue)) { + mrb_raisef(mrb, E_ARGUMENT_ERROR, "value given twice - %S$", mrb_fixnum_value(n)); + } + nextvalue = GETPOSARG(n); + p++; + goto retry; + } + CHECK_FOR_WIDTH(flags); + width = n; + flags |= FWIDTH; + goto retry; + + case '<': + case '{': { + const char *start = p; + char term = (*p == '<') ? '>' : '}'; + mrb_value symname; + + for (; p < end && *p != term; ) + p++; + if (id) { + mrb_raisef(mrb, E_ARGUMENT_ERROR, "name%S after <%S>", + mrb_str_new(mrb, start, p - start + 1), mrb_sym2str(mrb, id)); + } + symname = mrb_str_new(mrb, start + 1, p - start - 1); + id = mrb_intern_str(mrb, symname); + nextvalue = GETNAMEARG(mrb_symbol_value(id), start, (int)(p - start + 1)); + if (mrb_undef_p(nextvalue)) { + mrb_raisef(mrb, E_KEY_ERROR, "key%S not found", mrb_str_new(mrb, start, p - start + 1)); + } + if (term == '}') goto format_s; + p++; + goto retry; + } + + case '*': + CHECK_FOR_WIDTH(flags); + flags |= FWIDTH; + GETASTER(width); + if (width < 0) { + flags |= FMINUS; + width = -width; + } + p++; + goto retry; + + case '.': + if (flags & FPREC0) { + mrb_raise(mrb, E_ARGUMENT_ERROR, "precision given twice"); + } + flags |= FPREC|FPREC0; + + prec = 0; + p++; + if (*p == '*') { + GETASTER(prec); + if (prec < 0) { /* ignore negative precision */ + flags &= ~FPREC; + } + p++; + goto retry; + } + + GETNUM(prec, precision); + goto retry; + + case '\n': + case '\0': + p--; + /* fallthrough */ + case '%': + if (flags != FNONE) { + mrb_raise(mrb, E_ARGUMENT_ERROR, "invalid format character - %"); + } + PUSH("%", 1); + break; + + case 'c': { + mrb_value val = GETARG(); + mrb_value tmp; + char *c; + + tmp = mrb_check_string_type(mrb, val); + if (!mrb_nil_p(tmp)) { + if (RSTRING_LEN(tmp) != 1) { + mrb_raise(mrb, E_ARGUMENT_ERROR, "%c requires a character"); + } + } + else if (mrb_fixnum_p(val)) { + mrb_int n = mrb_fixnum(val); + + if (n < 0x80) { + char buf[1]; + + buf[0] = (char)n; + tmp = mrb_str_new(mrb, buf, 1); + } + else { + tmp = mrb_funcall(mrb, val, "chr", 0); + mrb_check_type(mrb, tmp, MRB_TT_STRING); + } + } + else { + mrb_raise(mrb, E_ARGUMENT_ERROR, "invalid character"); + } + c = RSTRING_PTR(tmp); + n = RSTRING_LEN(tmp); + if (!(flags & FWIDTH)) { + PUSH(c, n); + } + else if ((flags & FMINUS)) { + PUSH(c, n); + if (width>0) FILL(' ', width-1); + } + else { + if (width>0) FILL(' ', width-1); + PUSH(c, n); + } + } + break; + + case 's': + case 'p': + format_s: + { + mrb_value arg = GETARG(); + mrb_int len; + mrb_int slen; + + if (*p == 'p') arg = mrb_inspect(mrb, arg); + str = mrb_obj_as_string(mrb, arg); + len = RSTRING_LEN(str); + if (RSTRING(result)->flags & MRB_STR_EMBED) { + mrb_int tmp_n = len; + RSTRING(result)->flags &= ~MRB_STR_EMBED_LEN_MASK; + RSTRING(result)->flags |= tmp_n << MRB_STR_EMBED_LEN_SHIFT; + } + else { + RSTRING(result)->as.heap.len = blen; + } + if (flags&(FPREC|FWIDTH)) { + slen = RSTRING_LEN(str); + if (slen < 0) { + mrb_raise(mrb, E_ARGUMENT_ERROR, "invalid mbstring sequence"); + } + if ((flags&FPREC) && (prec < slen)) { + char *p = RSTRING_PTR(str) + prec; + slen = prec; + len = (mrb_int)(p - RSTRING_PTR(str)); + } + /* need to adjust multi-byte string pos */ + if ((flags&FWIDTH) && (width > slen)) { + width -= (int)slen; + if (!(flags&FMINUS)) { + FILL(' ', width); + } + PUSH(RSTRING_PTR(str), len); + if (flags&FMINUS) { + FILL(' ', width); + } + break; + } + } + PUSH(RSTRING_PTR(str), len); + } + break; + + case 'd': + case 'i': + case 'o': + case 'x': + case 'X': + case 'b': + case 'B': + case 'u': { + mrb_value val = GETARG(); + char nbuf[68], *s; + const char *prefix = NULL; + int sign = 0, dots = 0; + char sc = 0; + mrb_int v = 0; + int base; + mrb_int len; + + if (flags & FSHARP) { + switch (*p) { + case 'o': prefix = "0"; break; + case 'x': prefix = "0x"; break; + case 'X': prefix = "0X"; break; + case 'b': prefix = "0b"; break; + case 'B': prefix = "0B"; break; + default: break; + } + } + + bin_retry: + switch (mrb_type(val)) { + case MRB_TT_FLOAT: + val = mrb_flo_to_fixnum(mrb, val); + if (mrb_fixnum_p(val)) goto bin_retry; + break; + case MRB_TT_STRING: + val = mrb_str_to_inum(mrb, val, 0, TRUE); + goto bin_retry; + case MRB_TT_FIXNUM: + v = mrb_fixnum(val); + break; + default: + val = mrb_Integer(mrb, val); + goto bin_retry; + } + + switch (*p) { + case 'o': + base = 8; break; + case 'x': + case 'X': + base = 16; break; + case 'b': + case 'B': + base = 2; break; + case 'u': + case 'd': + case 'i': + sign = 1; + default: + base = 10; break; + } + + if (sign) { + if (v >= 0) { + if (flags & FPLUS) { + sc = '+'; + width--; + } + else if (flags & FSPACE) { + sc = ' '; + width--; + } + } + else { + sc = '-'; + width--; + } + mrb_assert(base == 10); + snprintf(nbuf, sizeof(nbuf), "%" MRB_PRId, v); + s = nbuf; + if (v < 0) s++; /* skip minus sign */ + } + else { + s = nbuf; + if (v < 0) { + dots = 1; + } + switch (base) { + case 2: + if (v < 0) { + val = mrb_fix2binstr(mrb, mrb_fixnum_value(v), base); + } + else { + val = mrb_fixnum_to_str(mrb, mrb_fixnum_value(v), base); + } + strncpy(++s, RSTRING_PTR(val), sizeof(nbuf)-1); + break; + case 8: + snprintf(++s, sizeof(nbuf)-1, "%" MRB_PRIo, v); + break; + case 16: + snprintf(++s, sizeof(nbuf)-1, "%" MRB_PRIx, v); + break; + } + if (v < 0) { + char d; + + s = remove_sign_bits(s, base); + switch (base) { + case 16: d = 'f'; break; + case 8: d = '7'; break; + case 2: d = '1'; break; + default: d = 0; break; + } + + if (d && *s != d) { + *--s = d; + } + } + } + { + size_t size; + size = strlen(s); + /* PARANOID: assert(size <= MRB_INT_MAX) */ + len = (mrb_int)size; + } + + if (*p == 'X') { + char *pp = s; + int c; + while ((c = (int)(unsigned char)*pp) != 0) { + *pp = toupper(c); + pp++; + } + } + + if (prefix && !prefix[1]) { /* octal */ + if (dots) { + prefix = NULL; + } + else if (len == 1 && *s == '0') { + len = 0; + if (flags & FPREC) prec--; + } + else if ((flags & FPREC) && (prec > len)) { + prefix = NULL; + } + } + else if (len == 1 && *s == '0') { + prefix = NULL; + } + + if (prefix) { + size_t size; + size = strlen(prefix); + /* PARANOID: assert(size <= MRB_INT_MAX). + * this check is absolutely paranoid. */ + width -= (mrb_int)size; + } + + if ((flags & (FZERO|FMINUS|FPREC)) == FZERO) { + prec = width; + width = 0; + } + else { + if (prec < len) { + if (!prefix && prec == 0 && len == 1 && *s == '0') len = 0; + prec = len; + } + width -= prec; + } + + if (!(flags&FMINUS) && width > 0) { + FILL(' ', width); + width = 0; + } + + if (sc) PUSH(&sc, 1); + + if (prefix) { + int plen = (int)strlen(prefix); + PUSH(prefix, plen); + } + if (dots) { + prec -= 2; + width -= 2; + PUSH("..", 2); + } + + if (prec > len) { + CHECK(prec - len); + if ((flags & (FMINUS|FPREC)) != FMINUS) { + char c = '0'; + FILL(c, prec - len); + } else if (v < 0) { + char c = sign_bits(base, p); + FILL(c, prec - len); + } + } + PUSH(s, len); + if (width > 0) { + FILL(' ', width); + } + } + break; + + case 'f': + case 'g': + case 'G': + case 'e': + case 'E': + case 'a': + case 'A': { + mrb_value val = GETARG(); + double fval; + int i, need = 6; + char fbuf[32]; + + fval = mrb_float(mrb_Float(mrb, val)); + if (!isfinite(fval)) { + const char *expr; + const int elen = 3; + char sign = '\0'; + + if (isnan(fval)) { + expr = "NaN"; + } + else { + expr = "Inf"; + } + need = elen; + if (!isnan(fval) && fval < 0.0) + sign = '-'; + else if (flags & (FPLUS|FSPACE)) + sign = (flags & FPLUS) ? '+' : ' '; + if (sign) + ++need; + if ((flags & FWIDTH) && need < width) + need = width; + + if (need < 0) { + mrb_raise(mrb, E_ARGUMENT_ERROR, "width too big"); + } + FILL(' ', need); + if (flags & FMINUS) { + if (sign) + buf[blen - need--] = sign; + memcpy(&buf[blen - need], expr, elen); + } + else { + if (sign) + buf[blen - elen - 1] = sign; + memcpy(&buf[blen - elen], expr, elen); + } + break; + } + + fmt_setup(fbuf, sizeof(fbuf), *p, flags, width, prec); + need = 0; + if (*p != 'e' && *p != 'E') { + i = INT_MIN; + frexp(fval, &i); + if (i > 0) + need = BIT_DIGITS(i); + } + need += (flags&FPREC) ? prec : 6; + if ((flags&FWIDTH) && need < width) + need = width; + need += 20; + if (need <= 0) { + mrb_raise(mrb, E_ARGUMENT_ERROR, + (width > prec ? "width too big" : "prec too big")); + } + + CHECK(need); + n = snprintf(&buf[blen], need, fbuf, fval); + if (n < 0) { + mrb_raise(mrb, E_RUNTIME_ERROR, "formatting error"); + } + blen += n; + } + break; + } + flags = FNONE; + } + + sprint_exit: +#if 0 + /* XXX - We cannot validate the number of arguments if (digit)$ style used. + */ + if (posarg >= 0 && nextarg < argc) { + const char *mesg = "too many arguments for format string"; + if (mrb_test(ruby_debug)) mrb_raise(mrb, E_ARGUMENT_ERROR, mesg); + if (mrb_test(ruby_verbose)) mrb_warn(mrb, "%S", mrb_str_new_cstr(mrb, mesg)); + } +#endif + mrb_str_resize(mrb, result, blen); + + return result; +} + +static void +fmt_setup(char *buf, size_t size, int c, int flags, mrb_int width, mrb_int prec) +{ + char *end = buf + size; + int n; + + *buf++ = '%'; + if (flags & FSHARP) *buf++ = '#'; + if (flags & FPLUS) *buf++ = '+'; + if (flags & FMINUS) *buf++ = '-'; + if (flags & FZERO) *buf++ = '0'; + if (flags & FSPACE) *buf++ = ' '; + + if (flags & FWIDTH) { + n = snprintf(buf, end - buf, "%d", (int)width); + buf += n; + } + + if (flags & FPREC) { + n = snprintf(buf, end - buf, ".%d", (int)prec); + buf += n; + } + + *buf++ = c; + *buf = '\0'; +} diff --git a/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-sprintf/test/sprintf.rb b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-sprintf/test/sprintf.rb new file mode 100644 index 00000000..e3b66ef9 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-sprintf/test/sprintf.rb @@ -0,0 +1,109 @@ +#assert('Kernel.sprintf') do +#end + +assert('String#%') do + assert_equal "one=1", "one=%d" % 1 + assert_equal "1 one 1.0", "%d %s %3.1f" % [ 1, "one", 1.01 ] + assert_equal "123 < 456", "%{num} < %s" % { num: 123, str: "456" } + assert_equal 15, ("%b" % (1<<14)).size +end + +assert('String#% with inf') do + inf = Float::INFINITY + + assert_equal "Inf", "%f" % inf + assert_equal "Inf", "%2f" % inf + assert_equal "Inf", "%3f" % inf + assert_equal " Inf", "%4f" % inf + assert_equal " Inf", "%5f" % inf + + assert_equal "+Inf", "%+f" % inf + assert_equal "+Inf", "%+2f" % inf + assert_equal "+Inf", "%+3f" % inf + assert_equal "+Inf", "%+4f" % inf + assert_equal " +Inf", "%+5f" % inf + + assert_equal "Inf", "%-f" % inf + assert_equal "Inf", "%-2f" % inf + assert_equal "Inf", "%-3f" % inf + assert_equal "Inf ", "%-4f" % inf + assert_equal "Inf ", "%-5f" % inf + + assert_equal " Inf", "% f" % inf + assert_equal " Inf", "% 2f" % inf + assert_equal " Inf", "% 3f" % inf + assert_equal " Inf", "% 4f" % inf + assert_equal " Inf", "% 5f" % inf +end + +assert('String#% with nan') do + nan = Float::NAN + + assert_equal "NaN", "%f" % nan + assert_equal "NaN", "%2f" % nan + assert_equal "NaN", "%3f" % nan + assert_equal " NaN", "%4f" % nan + assert_equal " NaN", "%5f" % nan + + assert_equal "+NaN", "%+f" % nan + assert_equal "+NaN", "%+2f" % nan + assert_equal "+NaN", "%+3f" % nan + assert_equal "+NaN", "%+4f" % nan + assert_equal " +NaN", "%+5f" % nan + + assert_equal "NaN", "%-f" % nan + assert_equal "NaN", "%-2f" % nan + assert_equal "NaN", "%-3f" % nan + assert_equal "NaN ", "%-4f" % nan + assert_equal "NaN ", "%-5f" % nan + + assert_equal " NaN", "% f" % nan + assert_equal " NaN", "% 2f" % nan + assert_equal " NaN", "% 3f" % nan + assert_equal " NaN", "% 4f" % nan + assert_equal " NaN", "% 5f" % nan +end + +assert("String#% with invalid chr") do + begin + class Fixnum + alias_method :chr_, :chr if method_defined?(:chr) + + def chr + nil + end + end + + assert_raise TypeError do + "%c" % 0x80 + end + ensure + class Fixnum + if method_defined?(:chr_) + alias_method :chr, :chr_ + remove_method :chr_ + end + end + end +end + +assert("String#% %b") do + assert_equal("..10115", "%0b5" % -5) +end + +assert("String#% %d") do + assert_equal(" 10", "%4d" % 10) + assert_equal("1000", "%4d" % 1000) + assert_equal("10000", "%4d" % 10000) +end + +assert("String#% invalid format") do + assert_raise ArgumentError do + "%?" % "" + end +end + +assert("String#% invalid format shared substring") do + fmt = ("x"*30+"%!")[0...-1] + assert_equal fmt, sprintf(fmt, "") +end diff --git a/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-string-ext/mrbgem.rake b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-string-ext/mrbgem.rake new file mode 100644 index 00000000..9812f2cc --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-string-ext/mrbgem.rake @@ -0,0 +1,6 @@ +MRuby::Gem::Specification.new('mruby-string-ext') do |spec| + spec.license = 'MIT' + spec.author = 'mruby developers' + spec.summary = 'String class extension' + spec.add_test_dependency 'mruby-enumerator', core: 'mruby-enumerator' +end diff --git a/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-string-ext/mrblib/string.rb b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-string-ext/mrblib/string.rb new file mode 100644 index 00000000..c3a7eb38 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-string-ext/mrblib/string.rb @@ -0,0 +1,355 @@ +class String + + ## + # call-seq: + # String.try_convert(obj) -> string or nil + # + # Try to convert obj into a String, using to_str method. + # Returns converted string or nil if obj cannot be converted + # for any reason. + # + # String.try_convert("str") #=> "str" + # String.try_convert(/re/) #=> nil + # + def self.try_convert(obj) + if obj.respond_to?(:to_str) + obj.to_str + else + nil + end + end + + ## + # call-seq: + # string.clear -> string + # + # Makes string empty. + # + # a = "abcde" + # a.clear #=> "" + # + def clear + self.replace("") + end + + ## + # call-seq: + # str.lstrip -> new_str + # + # Returns a copy of str with leading whitespace removed. See also + # String#rstrip and String#strip. + # + # " hello ".lstrip #=> "hello " + # "hello".lstrip #=> "hello" + # + def lstrip + a = 0 + z = self.size - 1 + a += 1 while a <= z and " \f\n\r\t\v".include?(self[a]) + (z >= 0) ? self[a..z] : "" + end + + ## + # call-seq: + # str.rstrip -> new_str + # + # Returns a copy of str with trailing whitespace removed. See also + # String#lstrip and String#strip. + # + # " hello ".rstrip #=> " hello" + # "hello".rstrip #=> "hello" + # + def rstrip + a = 0 + z = self.size - 1 + z -= 1 while a <= z and " \f\n\r\t\v\0".include?(self[z]) + (z >= 0) ? self[a..z] : "" + end + + ## + # call-seq: + # str.strip -> new_str + # + # Returns a copy of str with leading and trailing whitespace removed. + # + # " hello ".strip #=> "hello" + # "\tgoodbye\r\n".strip #=> "goodbye" + # + def strip + a = 0 + z = self.size - 1 + a += 1 while a <= z and " \f\n\r\t\v".include?(self[a]) + z -= 1 while a <= z and " \f\n\r\t\v\0".include?(self[z]) + (z >= 0) ? self[a..z] : "" + end + + ## + # call-seq: + # str.lstrip! -> self or nil + # + # Removes leading whitespace from str, returning nil if no + # change was made. See also String#rstrip! and + # String#strip!. + # + # " hello ".lstrip #=> "hello " + # "hello".lstrip! #=> nil + # + def lstrip! + raise RuntimeError, "can't modify frozen String" if frozen? + s = self.lstrip + (s == self) ? nil : self.replace(s) + end + + ## + # call-seq: + # str.rstrip! -> self or nil + # + # Removes trailing whitespace from str, returning nil if + # no change was made. See also String#lstrip! and + # String#strip!. + # + # " hello ".rstrip #=> " hello" + # "hello".rstrip! #=> nil + # + def rstrip! + raise RuntimeError, "can't modify frozen String" if frozen? + s = self.rstrip + (s == self) ? nil : self.replace(s) + end + + ## + # call-seq: + # str.strip! -> str or nil + # + # Removes leading and trailing whitespace from str. Returns + # nil if str was not altered. + # + def strip! + raise RuntimeError, "can't modify frozen String" if frozen? + s = self.strip + (s == self) ? nil : self.replace(s) + end + + ## + # call-seq: + # str.casecmp(other_str) -> -1, 0, +1 or nil + # + # Case-insensitive version of String#<=>. + # + # "abcdef".casecmp("abcde") #=> 1 + # "aBcDeF".casecmp("abcdef") #=> 0 + # "abcdef".casecmp("abcdefg") #=> -1 + # "abcdef".casecmp("ABCDEF") #=> 0 + # + def casecmp(str) + self.downcase <=> str.to_str.downcase + rescue NoMethodError + raise TypeError, "no implicit conversion of #{str.class} into String" + end + + def partition(sep) + raise TypeError, "type mismatch: #{sep.class} given" unless sep.is_a? String + n = index(sep) + unless n.nil? + m = n + sep.size + [ slice(0, n), sep, slice(m, size - m) ] + else + [ self, "", "" ] + end + end + + def rpartition(sep) + raise TypeError, "type mismatch: #{sep.class} given" unless sep.is_a? String + n = rindex(sep) + unless n.nil? + m = n + sep.size + [ slice(0, n), sep, slice(m, size - m) ] + else + [ "", "", self ] + end + end + + ## + # call-seq: + # str.slice!(fixnum) -> new_str or nil + # str.slice!(fixnum, fixnum) -> new_str or nil + # str.slice!(range) -> new_str or nil + # str.slice!(other_str) -> new_str or nil + # + # Deletes the specified portion from str, and returns the portion + # deleted. + # + # string = "this is a string" + # string.slice!(2) #=> "i" + # string.slice!(3..6) #=> " is " + # string.slice!("r") #=> "r" + # string #=> "thsa sting" + # + def slice!(arg1, arg2=nil) + raise RuntimeError, "can't modify frozen String" if frozen? + raise "wrong number of arguments (for 1..2)" if arg1.nil? && arg2.nil? + + if !arg1.nil? && !arg2.nil? + idx = arg1 + idx += self.size if arg1 < 0 + if idx >= 0 && idx <= self.size && arg2 > 0 + str = self[idx, arg2] + else + return nil + end + else + validated = false + if arg1.kind_of?(Range) + beg = arg1.begin + ed = arg1.end + beg += self.size if beg < 0 + ed += self.size if ed < 0 + ed -= 1 if arg1.exclude_end? + validated = true + elsif arg1.kind_of?(String) + validated = true + else + idx = arg1 + idx += self.size if arg1 < 0 + validated = true if idx >=0 && arg1 < self.size + end + if validated + str = self[arg1] + else + return nil + end + end + unless str.nil? || str == "" + if !arg1.nil? && !arg2.nil? + idx = arg1 >= 0 ? arg1 : self.size+arg1 + str2 = self[0...idx] + self[idx+arg2..-1].to_s + else + if arg1.kind_of?(Range) + idx = beg >= 0 ? beg : self.size+beg + idx2 = ed>= 0 ? ed : self.size+ed + str2 = self[0...idx] + self[idx2+1..-1].to_s + elsif arg1.kind_of?(String) + idx = self.index(arg1) + str2 = self[0...idx] + self[idx+arg1.size..-1] unless idx.nil? + else + idx = arg1 >= 0 ? arg1 : self.size+arg1 + str2 = self[0...idx] + self[idx+1..-1].to_s + end + end + self.replace(str2) unless str2.nil? + end + str + end + + ## + # call-seq: + # str.insert(index, other_str) -> str + # + # Inserts other_str before the character at the given + # index, modifying str. Negative indices count from the + # end of the string, and insert after the given character. + # The intent is insert aString so that it starts at the given + # index. + # + # "abcd".insert(0, 'X') #=> "Xabcd" + # "abcd".insert(3, 'X') #=> "abcXd" + # "abcd".insert(4, 'X') #=> "abcdX" + # "abcd".insert(-3, 'X') #=> "abXcd" + # "abcd".insert(-1, 'X') #=> "abcdX" + # + def insert(idx, str) + if idx == -1 + return self << str + elsif idx < 0 + idx += 1 + end + self[idx, 0] = str + self + end + + ## + # call-seq: + # str.ljust(integer, padstr=' ') -> new_str + # + # If integer is greater than the length of str, returns a new + # String of length integer with str left justified + # and padded with padstr; otherwise, returns str. + # + # "hello".ljust(4) #=> "hello" + # "hello".ljust(20) #=> "hello " + # "hello".ljust(20, '1234') #=> "hello123412341234123" + def ljust(idx, padstr = ' ') + raise ArgumentError, 'zero width padding' if padstr == '' + return self if idx <= self.size + pad_repetitions = (idx / padstr.length).ceil + padding = (padstr * pad_repetitions)[0...(idx - self.length)] + self + padding + end + + ## + # call-seq: + # str.rjust(integer, padstr=' ') -> new_str + # + # If integer is greater than the length of str, returns a new + # String of length integer with str right justified + # and padded with padstr; otherwise, returns str. + # + # "hello".rjust(4) #=> "hello" + # "hello".rjust(20) #=> " hello" + # "hello".rjust(20, '1234') #=> "123412341234123hello" + def rjust(idx, padstr = ' ') + raise ArgumentError, 'zero width padding' if padstr == '' + return self if idx <= self.size + pad_repetitions = (idx / padstr.length).ceil + padding = (padstr * pad_repetitions)[0...(idx - self.length)] + padding + self + end + + def chars(&block) + if block_given? + self.split('').each do |i| + block.call(i) + end + self + else + self.split('') + end + end + + def each_char(&block) + return to_enum :each_char unless block + + split('').each do |i| + block.call(i) + end + self + end + + def codepoints(&block) + len = self.size + + if block_given? + self.split('').each do|x| + block.call(x.ord) + end + self + else + self.split('').map{|x| x.ord} + end + end + alias each_codepoint codepoints + + ## + # call-seq: + # str.prepend(other_str) -> str + # + # Prepend---Prepend the given string to str. + # + # a = "world" + # a.prepend("hello ") #=> "hello world" + # a #=> "hello world" + def prepend(arg) + self[0, 0] = arg + self + end +end diff --git a/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-string-ext/src/string.c b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-string-ext/src/string.c new file mode 100644 index 00000000..6bc035d6 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-string-ext/src/string.c @@ -0,0 +1,685 @@ +#include +#include +#include +#include +#include +#include + +static mrb_value +mrb_str_getbyte(mrb_state *mrb, mrb_value str) +{ + mrb_int pos; + mrb_get_args(mrb, "i", &pos); + + if (pos < 0) + pos += RSTRING_LEN(str); + if (pos < 0 || RSTRING_LEN(str) <= pos) + return mrb_nil_value(); + + return mrb_fixnum_value((unsigned char)RSTRING_PTR(str)[pos]); +} + +static mrb_value +mrb_str_setbyte(mrb_state *mrb, mrb_value str) +{ + mrb_int pos, byte; + long len; + + mrb_get_args(mrb, "ii", &pos, &byte); + + len = RSTRING_LEN(str); + if (pos < -len || len <= pos) + mrb_raisef(mrb, E_INDEX_ERROR, "index %S is out of array", mrb_fixnum_value(pos)); + if (pos < 0) + pos += len; + + mrb_str_modify(mrb, mrb_str_ptr(str)); + byte &= 0xff; + RSTRING_PTR(str)[pos] = byte; + return mrb_fixnum_value((unsigned char)byte); +} + +static mrb_value +mrb_str_byteslice(mrb_state *mrb, mrb_value str) +{ + mrb_value a1; + mrb_int len; + int argc; + + argc = mrb_get_args(mrb, "o|i", &a1, &len); + if (argc == 2) { + return mrb_str_substr(mrb, str, mrb_fixnum(a1), len); + } + switch (mrb_type(a1)) { + case MRB_TT_RANGE: + { + mrb_int beg; + + len = RSTRING_LEN(str); + switch (mrb_range_beg_len(mrb, a1, &beg, &len, len, TRUE)) { + case 0: /* not range */ + break; + case 1: /* range */ + return mrb_str_substr(mrb, str, beg, len); + case 2: /* out of range */ + mrb_raisef(mrb, E_RANGE_ERROR, "%S out of range", a1); + break; + } + return mrb_nil_value(); + } + case MRB_TT_FLOAT: + a1 = mrb_fixnum_value((mrb_int)mrb_float(a1)); + /* fall through */ + case MRB_TT_FIXNUM: + return mrb_str_substr(mrb, str, mrb_fixnum(a1), 1); + default: + mrb_raise(mrb, E_TYPE_ERROR, "wrong type of argument"); + } + /* not reached */ + return mrb_nil_value(); +} + +/* + * call-seq: + * str.swapcase! -> str or nil + * + * Equivalent to String#swapcase, but modifies the receiver in + * place, returning str, or nil if no changes were made. + * Note: case conversion is effective only in ASCII region. + */ +static mrb_value +mrb_str_swapcase_bang(mrb_state *mrb, mrb_value str) +{ + char *p, *pend; + int modify = 0; + struct RString *s = mrb_str_ptr(str); + + mrb_str_modify(mrb, s); + p = RSTRING_PTR(str); + pend = p + RSTRING_LEN(str); + while (p < pend) { + if (ISUPPER(*p)) { + *p = TOLOWER(*p); + modify = 1; + } + else if (ISLOWER(*p)) { + *p = TOUPPER(*p); + modify = 1; + } + p++; + } + + if (modify) return str; + return mrb_nil_value(); +} + +/* + * call-seq: + * str.swapcase -> new_str + * + * Returns a copy of str with uppercase alphabetic characters converted + * to lowercase and lowercase characters converted to uppercase. + * Note: case conversion is effective only in ASCII region. + * + * "Hello".swapcase #=> "hELLO" + * "cYbEr_PuNk11".swapcase #=> "CyBeR_pUnK11" + */ +static mrb_value +mrb_str_swapcase(mrb_state *mrb, mrb_value self) +{ + mrb_value str; + + str = mrb_str_dup(mrb, self); + mrb_str_swapcase_bang(mrb, str); + return str; +} + +static mrb_value mrb_fixnum_chr(mrb_state *mrb, mrb_value num); + +/* + * call-seq: + * str << integer -> str + * str.concat(integer) -> str + * str << obj -> str + * str.concat(obj) -> str + * + * Append---Concatenates the given object to str. If the object is a + * Integer, it is considered as a codepoint, and is converted + * to a character before concatenation. + * + * a = "hello " + * a << "world" #=> "hello world" + * a.concat(33) #=> "hello world!" + */ +static mrb_value +mrb_str_concat_m(mrb_state *mrb, mrb_value self) +{ + mrb_value str; + + mrb_get_args(mrb, "o", &str); + if (mrb_fixnum_p(str)) + str = mrb_fixnum_chr(mrb, str); + else + str = mrb_string_type(mrb, str); + mrb_str_concat(mrb, self, str); + return self; +} + +/* + * call-seq: + * str.start_with?([prefixes]+) -> true or false + * + * Returns true if +str+ starts with one of the +prefixes+ given. + * + * "hello".start_with?("hell") #=> true + * + * # returns true if one of the prefixes matches. + * "hello".start_with?("heaven", "hell") #=> true + * "hello".start_with?("heaven", "paradise") #=> false + * "h".start_with?("heaven", "hell") #=> false + */ +static mrb_value +mrb_str_start_with(mrb_state *mrb, mrb_value self) +{ + mrb_value *argv, sub; + mrb_int argc, i; + mrb_get_args(mrb, "*", &argv, &argc); + + for (i = 0; i < argc; i++) { + size_t len_l, len_r; + int ai = mrb_gc_arena_save(mrb); + sub = mrb_string_type(mrb, argv[i]); + mrb_gc_arena_restore(mrb, ai); + len_l = RSTRING_LEN(self); + len_r = RSTRING_LEN(sub); + if (len_l >= len_r) { + if (memcmp(RSTRING_PTR(self), RSTRING_PTR(sub), len_r) == 0) { + return mrb_true_value(); + } + } + } + return mrb_false_value(); +} + +/* + * call-seq: + * str.end_with?([suffixes]+) -> true or false + * + * Returns true if +str+ ends with one of the +suffixes+ given. + */ +static mrb_value +mrb_str_end_with(mrb_state *mrb, mrb_value self) +{ + mrb_value *argv, sub; + mrb_int argc, i; + mrb_get_args(mrb, "*", &argv, &argc); + + for (i = 0; i < argc; i++) { + size_t len_l, len_r; + int ai = mrb_gc_arena_save(mrb); + sub = mrb_string_type(mrb, argv[i]); + mrb_gc_arena_restore(mrb, ai); + len_l = RSTRING_LEN(self); + len_r = RSTRING_LEN(sub); + if (len_l >= len_r) { + if (memcmp(RSTRING_PTR(self) + (len_l - len_r), + RSTRING_PTR(sub), + len_r) == 0) { + return mrb_true_value(); + } + } + } + return mrb_false_value(); +} + +static mrb_value +mrb_str_hex(mrb_state *mrb, mrb_value self) +{ + return mrb_str_to_inum(mrb, self, 16, FALSE); +} + +static mrb_value +mrb_str_oct(mrb_state *mrb, mrb_value self) +{ + return mrb_str_to_inum(mrb, self, 8, FALSE); +} + +/* + * call-seq: + * string.chr -> string + * + * Returns a one-character string at the beginning of the string. + * + * a = "abcde" + * a.chr #=> "a" + */ +static mrb_value +mrb_str_chr(mrb_state *mrb, mrb_value self) +{ + return mrb_str_substr(mrb, self, 0, 1); +} + +static mrb_value +mrb_fixnum_chr(mrb_state *mrb, mrb_value num) +{ + mrb_int cp = mrb_fixnum(num); +#ifdef MRB_UTF8_STRING + char utf8[4]; + mrb_int len; + + if (cp < 0 || 0x10FFFF < cp) { + mrb_raisef(mrb, E_RANGE_ERROR, "%S out of char range", num); + } + if (cp < 0x80) { + utf8[0] = (char)cp; + len = 1; + } + else if (cp < 0x800) { + utf8[0] = (char)(0xC0 | (cp >> 6)); + utf8[1] = (char)(0x80 | (cp & 0x3F)); + len = 2; + } + else if (cp < 0x10000) { + utf8[0] = (char)(0xE0 | (cp >> 12)); + utf8[1] = (char)(0x80 | ((cp >> 6) & 0x3F)); + utf8[2] = (char)(0x80 | ( cp & 0x3F)); + len = 3; + } + else { + utf8[0] = (char)(0xF0 | (cp >> 18)); + utf8[1] = (char)(0x80 | ((cp >> 12) & 0x3F)); + utf8[2] = (char)(0x80 | ((cp >> 6) & 0x3F)); + utf8[3] = (char)(0x80 | ( cp & 0x3F)); + len = 4; + } + return mrb_str_new(mrb, utf8, len); +#else + char c; + + if (cp < 0 || 0xff < cp) { + mrb_raisef(mrb, E_RANGE_ERROR, "%S out of char range", num); + } + c = (char)cp; + return mrb_str_new(mrb, &c, 1); +#endif +} + +/* + * call-seq: + * string.lines -> array of string + * + * Returns strings per line; + * + * a = "abc\ndef" + * a.lines #=> ["abc\n", "def"] + */ +static mrb_value +mrb_str_lines(mrb_state *mrb, mrb_value self) +{ + mrb_value result; + mrb_value blk; + int ai; + mrb_int len; + mrb_value arg; + char *b = RSTRING_PTR(self); + char *p = b, *t; + char *e = b + RSTRING_LEN(self); + + mrb_get_args(mrb, "&", &blk); + + result = mrb_ary_new(mrb); + ai = mrb_gc_arena_save(mrb); + if (!mrb_nil_p(blk)) { + while (p < e) { + t = p; + while (p < e && *p != '\n') p++; + if (*p == '\n') p++; + len = (mrb_int) (p - t); + arg = mrb_str_new(mrb, t, len); + mrb_yield_argv(mrb, blk, 1, &arg); + mrb_gc_arena_restore(mrb, ai); + if (b != RSTRING_PTR(self)) { + ptrdiff_t diff = p - b; + b = RSTRING_PTR(self); + p = b + diff; + } + e = b + RSTRING_LEN(self); + } + return self; + } + while (p < e) { + t = p; + while (p < e && *p != '\n') p++; + if (*p == '\n') p++; + len = (mrb_int) (p - t); + mrb_ary_push(mrb, result, mrb_str_new(mrb, t, len)); + mrb_gc_arena_restore(mrb, ai); + } + return result; +} + +/* + * call-seq: + * string.succ -> string + * + * Returns next sequence of the string; + * + * a = "abc" + * a.succ #=> "abd" + */ +static mrb_value +mrb_str_succ_bang(mrb_state *mrb, mrb_value self) +{ + mrb_value result; + unsigned char *p, *e, *b, *t; + const char *prepend; + struct RString *s = mrb_str_ptr(self); + mrb_int l; + + if (RSTRING_LEN(self) == 0) + return self; + + mrb_str_modify(mrb, s); + l = RSTRING_LEN(self); + b = p = (unsigned char*) RSTRING_PTR(self); + t = e = p + l; + *(e--) = 0; + + // find trailing ascii/number + while (e >= b) { + if (ISALNUM(*e)) + break; + e--; + } + if (e < b) { + e = p + l - 1; + result = mrb_str_new_lit(mrb, ""); + } + else { + // find leading letter of the ascii/number + b = e; + while (b > p) { + if (!ISALNUM(*b) || (ISALNUM(*b) && *b != '9' && *b != 'z' && *b != 'Z')) + break; + b--; + } + if (!ISALNUM(*b)) + b++; + result = mrb_str_new(mrb, (char*) p, b - p); + } + + while (e >= b) { + if (!ISALNUM(*e)) { + if (*e == 0xff) { + mrb_str_cat_lit(mrb, result, "\x01"); + (*e) = 0; + } + else + (*e)++; + break; + } + prepend = NULL; + if (*e == '9') { + if (e == b) prepend = "1"; + *e = '0'; + } + else if (*e == 'z') { + if (e == b) prepend = "a"; + *e = 'a'; + } + else if (*e == 'Z') { + if (e == b) prepend = "A"; + *e = 'A'; + } + else { + (*e)++; + break; + } + if (prepend) mrb_str_cat_cstr(mrb, result, prepend); + e--; + } + result = mrb_str_cat(mrb, result, (char*) b, t - b); + l = RSTRING_LEN(result); + mrb_str_resize(mrb, self, l); + memcpy(RSTRING_PTR(self), RSTRING_PTR(result), l); + return self; +} + +static mrb_value +mrb_str_succ(mrb_state *mrb, mrb_value self) +{ + mrb_value str; + + str = mrb_str_dup(mrb, self); + mrb_str_succ_bang(mrb, str); + return str; +} + +#ifdef MRB_UTF8_STRING +static const char utf8len_codepage_zero[256] = +{ + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,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,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,0,0,0,0,0,0,0,0,0,0,0,0, + 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, + 3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,0,0,0,0,0,0,0,0,0,0,0, +}; + +static mrb_int +utf8code(unsigned char* p) +{ + mrb_int len; + + if (p[0] < 0x80) + return p[0]; + + len = utf8len_codepage_zero[p[0]]; + if (len > 1 && (p[1] & 0xc0) == 0x80) { + if (len == 2) + return ((p[0] & 0x1f) << 6) + (p[1] & 0x3f); + if ((p[2] & 0xc0) == 0x80) { + if (len == 3) + return ((p[0] & 0x0f) << 12) + ((p[1] & 0x3f) << 6) + + (p[2] & 0x3f); + if ((p[3] & 0xc0) == 0x80) { + if (len == 4) + return ((p[0] & 0x07) << 18) + ((p[1] & 0x3f) << 12) + + ((p[2] & 0x3f) << 6) + (p[3] & 0x3f); + if ((p[4] & 0xc0) == 0x80) { + if (len == 5) + return ((p[0] & 0x03) << 24) + ((p[1] & 0x3f) << 18) + + ((p[2] & 0x3f) << 12) + ((p[3] & 0x3f) << 6) + + (p[4] & 0x3f); + if ((p[5] & 0xc0) == 0x80 && len == 6) + return ((p[0] & 0x01) << 30) + ((p[1] & 0x3f) << 24) + + ((p[2] & 0x3f) << 18) + ((p[3] & 0x3f) << 12) + + ((p[4] & 0x3f) << 6) + (p[5] & 0x3f); + } + } + } + } + return p[0]; +} + +static mrb_value +mrb_str_ord(mrb_state* mrb, mrb_value str) +{ + if (RSTRING_LEN(str) == 0) + mrb_raise(mrb, E_ARGUMENT_ERROR, "empty string"); + return mrb_fixnum_value(utf8code((unsigned char*) RSTRING_PTR(str))); +} +#else +static mrb_value +mrb_str_ord(mrb_state* mrb, mrb_value str) +{ + if (RSTRING_LEN(str) == 0) + mrb_raise(mrb, E_ARGUMENT_ERROR, "empty string"); + return mrb_fixnum_value((unsigned char)RSTRING_PTR(str)[0]); +} +#endif + +static mrb_bool +all_digits_p(const char *s, mrb_int len) +{ + while (len-- > 0) { + if (!ISDIGIT(*s)) return FALSE; + s++; + } + return TRUE; +} + +/* + * call-seq: + * str.upto(other_str, exclusive=false) {|s| block } -> str + * str.upto(other_str, exclusive=false) -> an_enumerator + * + * Iterates through successive values, starting at str and + * ending at other_str inclusive, passing each value in turn to + * the block. The String#succ method is used to generate + * each value. If optional second argument exclusive is omitted or is false, + * the last value will be included; otherwise it will be excluded. + * + * If no block is given, an enumerator is returned instead. + * + * "a8".upto("b6") {|s| print s, ' ' } + * for s in "a8".."b6" + * print s, ' ' + * end + * + * produces: + * + * a8 a9 b0 b1 b2 b3 b4 b5 b6 + * a8 a9 b0 b1 b2 b3 b4 b5 b6 + * + * If str and other_str contains only ascii numeric characters, + * both are recognized as decimal numbers. In addition, the width of + * string (e.g. leading zeros) is handled appropriately. + * + * "9".upto("11").to_a #=> ["9", "10", "11"] + * "25".upto("5").to_a #=> [] + * "07".upto("11").to_a #=> ["07", "08", "09", "10", "11"] + */ +static mrb_value +mrb_str_upto(mrb_state *mrb, mrb_value beg) +{ + mrb_value end; + mrb_value exclusive = mrb_false_value(); + mrb_value block = mrb_nil_value(); + mrb_value current, after_end; + mrb_int n; + mrb_bool excl; + + mrb_get_args(mrb, "o|o&", &end, &exclusive, &block); + + if (mrb_nil_p(block)) { + return mrb_funcall(mrb, beg, "to_enum", 3, mrb_symbol_value(mrb_intern_lit(mrb, "upto")), end, exclusive); + } + end = mrb_string_type(mrb, end); + excl = mrb_test(exclusive); + + /* single character */ + if (RSTRING_LEN(beg) == 1 && RSTRING_LEN(end) == 1 && + ISASCII(RSTRING_PTR(beg)[0]) && ISASCII(RSTRING_PTR(end)[0])) { + char c = RSTRING_PTR(beg)[0]; + char e = RSTRING_PTR(end)[0]; + int ai = mrb_gc_arena_save(mrb); + + if (c > e || (excl && c == e)) return beg; + for (;;) { + mrb_yield(mrb, block, mrb_str_new(mrb, &c, 1)); + mrb_gc_arena_restore(mrb, ai); + if (!excl && c == e) break; + c++; + if (excl && c == e) break; + } + return beg; + } + /* both edges are all digits */ + if (ISDIGIT(RSTRING_PTR(beg)[0]) && ISDIGIT(RSTRING_PTR(end)[0]) && + all_digits_p(RSTRING_PTR(beg), RSTRING_LEN(beg)) && + all_digits_p(RSTRING_PTR(end), RSTRING_LEN(end))) { + mrb_int min_width = RSTRING_LEN(beg); + mrb_int bi = mrb_int(mrb, mrb_str_to_inum(mrb, beg, 10, FALSE)); + mrb_int ei = mrb_int(mrb, mrb_str_to_inum(mrb, end, 10, FALSE)); + int ai = mrb_gc_arena_save(mrb); + + while (bi <= ei) { + mrb_value ns, str; + + if (excl && bi == ei) break; + ns = mrb_format(mrb, "%S", mrb_fixnum_value(bi)); + if (min_width > RSTRING_LEN(ns)) { + str = mrb_str_new(mrb, NULL, min_width); + memset(RSTRING_PTR(str), '0', min_width-RSTRING_LEN(ns)); + memcpy(RSTRING_PTR(str)+min_width-RSTRING_LEN(ns), + RSTRING_PTR(ns), RSTRING_LEN(ns)); + } + else { + str = ns; + } + mrb_yield(mrb, block, str); + mrb_gc_arena_restore(mrb, ai); + bi++; + } + + return beg; + } + /* normal case */ + n = mrb_int(mrb, mrb_funcall(mrb, beg, "<=>", 1, end)); + if (n > 0 || (excl && n == 0)) return beg; + + after_end = mrb_funcall(mrb, end, "succ", 0); + current = mrb_str_dup(mrb, beg); + while (!mrb_str_equal(mrb, current, after_end)) { + int ai = mrb_gc_arena_save(mrb); + mrb_value next = mrb_nil_value(); + if (excl || !mrb_str_equal(mrb, current, end)) + next = mrb_funcall(mrb, current, "succ", 0); + mrb_yield(mrb, block, current); + if (mrb_nil_p(next)) break; + current = mrb_str_to_str(mrb, next); + if (excl && mrb_str_equal(mrb, current, end)) break; + if (RSTRING_LEN(current) > RSTRING_LEN(end) || RSTRING_LEN(current) == 0) + break; + mrb_gc_arena_restore(mrb, ai); + } + + return beg; +} + +void +mrb_mruby_string_ext_gem_init(mrb_state* mrb) +{ + struct RClass * s = mrb->string_class; + + mrb_define_method(mrb, s, "dump", mrb_str_dump, MRB_ARGS_NONE()); + mrb_define_method(mrb, s, "getbyte", mrb_str_getbyte, MRB_ARGS_REQ(1)); + mrb_define_method(mrb, s, "setbyte", mrb_str_setbyte, MRB_ARGS_REQ(2)); + mrb_define_method(mrb, s, "byteslice", mrb_str_byteslice, MRB_ARGS_REQ(1)|MRB_ARGS_OPT(1)); + mrb_define_method(mrb, s, "swapcase!", mrb_str_swapcase_bang, MRB_ARGS_NONE()); + mrb_define_method(mrb, s, "swapcase", mrb_str_swapcase, MRB_ARGS_NONE()); + mrb_define_method(mrb, s, "concat", mrb_str_concat_m, MRB_ARGS_REQ(1)); + mrb_define_method(mrb, s, "<<", mrb_str_concat_m, MRB_ARGS_REQ(1)); + mrb_define_method(mrb, s, "start_with?", mrb_str_start_with, MRB_ARGS_REST()); + mrb_define_method(mrb, s, "end_with?", mrb_str_end_with, MRB_ARGS_REST()); + mrb_define_method(mrb, s, "hex", mrb_str_hex, MRB_ARGS_NONE()); + mrb_define_method(mrb, s, "oct", mrb_str_oct, MRB_ARGS_NONE()); + mrb_define_method(mrb, s, "chr", mrb_str_chr, MRB_ARGS_NONE()); + mrb_define_method(mrb, s, "lines", mrb_str_lines, MRB_ARGS_NONE()); + mrb_define_method(mrb, s, "succ", mrb_str_succ, MRB_ARGS_NONE()); + mrb_define_method(mrb, s, "succ!", mrb_str_succ_bang, MRB_ARGS_NONE()); + mrb_alias_method(mrb, s, mrb_intern_lit(mrb, "next"), mrb_intern_lit(mrb, "succ")); + mrb_alias_method(mrb, s, mrb_intern_lit(mrb, "next!"), mrb_intern_lit(mrb, "succ!")); + mrb_define_method(mrb, s, "ord", mrb_str_ord, MRB_ARGS_NONE()); + mrb_define_method(mrb, s, "upto", mrb_str_upto, MRB_ARGS_ANY()); + + mrb_define_method(mrb, mrb->fixnum_class, "chr", mrb_fixnum_chr, MRB_ARGS_NONE()); +} + +void +mrb_mruby_string_ext_gem_final(mrb_state* mrb) +{ +} diff --git a/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-string-ext/test/string.rb b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-string-ext/test/string.rb new file mode 100644 index 00000000..2a568c7d --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-string-ext/test/string.rb @@ -0,0 +1,667 @@ +## +# String(Ext) Test + +UTF8STRING = ("\343\201\202".size == 1) + +assert('String.try_convert') do + assert_nil String.try_convert(nil) + assert_nil String.try_convert(:foo) + assert_equal "", String.try_convert("") + assert_equal "1,2,3", String.try_convert("1,2,3") +end + +assert('String#getbyte') do + str1 = "hello" + bytes1 = [104, 101, 108, 108, 111] + assert_equal bytes1[0], str1.getbyte(0) + assert_equal bytes1[-1], str1.getbyte(-1) + assert_equal bytes1[6], str1.getbyte(6) + + str2 = "\xFF" + bytes2 = [0xFF] + assert_equal bytes2[0], str2.getbyte(0) +end + +assert('String#setbyte') do + str1 = "hello" + h = "H".getbyte(0) + str1.setbyte(0, h) + assert_equal(h, str1.getbyte(0)) + assert_equal("Hello", str1) +end + +assert("String#setbyte raises IndexError if arg conversion resizes String") do + $s = "01234\n" + class Tmp + def to_i + $s.chomp! '' + 95 + end + end + tmp = Tmp.new + assert_raise(IndexError) { $s.setbyte(5, tmp) } +end + +assert('String#byteslice') do + str1 = "hello" + assert_equal("e", str1.byteslice(1)) + assert_equal("o", str1.byteslice(-1)) + assert_equal("ell", str1.byteslice(1..3)) + assert_equal("el", str1.byteslice(1...3)) +end + +assert('String#dump') do + ("\1" * 100).dump # should not raise an exception - regress #1210 + "\0".inspect == "\"\\000\"" and + "foo".dump == "\"foo\"" +end + +assert('String#strip') do + s = " abc " + "".strip == "" and " \t\r\n\f\v".strip == "" and + "\0a\0".strip == "\0a" and + "abc".strip == "abc" and + " abc".strip == "abc" and + "abc ".strip == "abc" and + " abc ".strip == "abc" and + s == " abc " +end + +assert('String#lstrip') do + s = " abc " + s.lstrip + "".lstrip == "" and " \t\r\n\f\v".lstrip == "" and + "\0a\0".lstrip == "\0a\0" and + "abc".lstrip == "abc" and + " abc".lstrip == "abc" and + "abc ".lstrip == "abc " and + " abc ".lstrip == "abc " and + s == " abc " +end + +assert('String#rstrip') do + s = " abc " + s.rstrip + "".rstrip == "" and " \t\r\n\f\v".rstrip == "" and + "\0a\0".rstrip == "\0a" and + "abc".rstrip == "abc" and + " abc".rstrip == " abc" and + "abc ".rstrip == "abc" and + " abc ".rstrip == " abc" and + s == " abc " +end + +assert('String#strip!') do + s = " abc " + t = "abc" + s.strip! == "abc" and s == "abc" and t.strip! == nil +end + +assert('String#lstrip!') do + s = " abc " + t = "abc " + s.lstrip! == "abc " and s == "abc " and t.lstrip! == nil +end + +assert('String#rstrip!') do + s = " abc " + t = " abc" + s.rstrip! == " abc" and s == " abc" and t.rstrip! == nil +end + +assert('String#swapcase') do + assert_equal "hELLO", "Hello".swapcase + assert_equal "CyBeR_pUnK11", "cYbEr_PuNk11".swapcase +end + +assert('String#swapcase!') do + s = "Hello" + t = s.clone + t.swapcase! + assert_equal s.swapcase, t +end + +assert('String#concat') do + assert_equal "Hello World!", "Hello " << "World" << 33 + assert_equal "Hello World!", "Hello ".concat("World").concat(33) + + o = Object.new + def o.to_str + "to_str" + end + assert_equal "hi to_str", "hi " << o + + assert_raise(TypeError) { "".concat(Object.new) } +end + +assert('String#casecmp') do + assert_equal 1, "abcdef".casecmp("abcde") + assert_equal 0, "aBcDeF".casecmp("abcdef") + assert_equal(-1, "abcdef".casecmp("abcdefg")) + assert_equal 0, "abcdef".casecmp("ABCDEF") + o = Object.new + def o.to_str + "ABCDEF" + end + assert_equal 0, "abcdef".casecmp(o) +end + +assert('String#start_with?') do + assert_true "hello".start_with?("heaven", "hell") + assert_true !"hello".start_with?("heaven", "paradise") + assert_true !"h".start_with?("heaven", "hell") + assert_raise TypeError do "hello".start_with?(true) end +end + +assert('String#end_with?') do + assert_true "string".end_with?("ing", "mng") + assert_true !"string".end_with?("str", "tri") + assert_true !"ng".end_with?("ing", "mng") + assert_raise TypeError do "hello".end_with?(true) end +end + +assert('String#partition') do + assert_equal ["a", "x", "axa"], "axaxa".partition("x") + assert_equal ["aaaaa", "", ""], "aaaaa".partition("x") + assert_equal ["", "", "aaaaa"], "aaaaa".partition("") + assert_equal ["", "a", "aaaa"], "aaaaa".partition("a") + assert_equal ["aaaa", "b", ""], "aaaab".partition("b") + assert_equal ["", "b", "aaaa"], "baaaa".partition("b") + assert_equal ["", "", ""], "".partition("a") +end + +assert('String#rpartition') do + assert_equal ["axa", "x", "a"], "axaxa".rpartition("x") + assert_equal ["", "", "aaaaa"], "aaaaa".rpartition("x") + assert_equal ["aaaaa", "", ""], "aaaaa".rpartition("") + assert_equal ["aaaa", "a", ""], "aaaaa".rpartition("a") + assert_equal ["aaaa", "b", ""], "aaaab".rpartition("b") + assert_equal ["", "b", "aaaa"], "baaaa".rpartition("b") + assert_equal ["", "", ""], "".rpartition("a") +end + +assert('String#hex') do + assert_equal 16, "10".hex + assert_equal 255, "ff".hex + assert_equal 16, "0x10".hex + assert_equal (-16), "-0x10".hex + assert_equal 0, "xyz".hex + assert_equal 16, "10z".hex + assert_equal 16, "1_0".hex + assert_equal 0, "".hex +end + +assert('String#oct') do + assert_equal 8, "10".oct + assert_equal 7, "7".oct + assert_equal 0, "8".oct + assert_equal 0, "9".oct + assert_equal 0, "xyz".oct + assert_equal 8, "10z".oct + assert_equal 8, "1_0".oct + assert_equal 8, "010".oct + assert_equal (-8), "-10".oct +end + +assert('String#chr') do + assert_equal "a", "abcde".chr + # test Fixnum#chr as well + assert_equal "a", 97.chr +end + +assert('String#lines') do + assert_equal ["Hel\n", "lo\n", "World!"], "Hel\nlo\nWorld!".lines + assert_equal ["Hel\n", "lo\n", "World!\n"], "Hel\nlo\nWorld!\n".lines + assert_equal ["\n", "\n", "\n"], "\n\n\n".lines + assert_equal [], "".lines +end + +assert('String#clear') do + # embed string + s = "foo" + assert_equal("", s.clear) + assert_equal("", s) + + # not embed string and not shared string + s = "foo" * 100 + a = s + assert_equal("", s.clear) + assert_equal("", s) + assert_equal("", a) + + # shared string + s = "foo" * 100 + a = s[10, 90] # create shared string + assert_equal("", s.clear) # clear + assert_equal("", s) # s is cleared + assert_not_equal("", a) # a should not be affected +end + +assert('String#slice!') do + a = "AooBar" + b = a.dup + assert_equal "A", a.slice!(0) + assert_equal "AooBar", b + + a = "FooBar" + assert_equal "r", a.slice!(-1) + assert_equal "FooBa", a + + a = "FooBar" + assert_nil a.slice!(6) + assert_nil a.slice!(-7) + assert_equal "FooBar", a + + a = "FooBar" + assert_equal "Foo", a.slice!(0, 3) + assert_equal "Bar", a + + a = "FooBar" + assert_equal "Bar", a.slice!(-3, 3) + assert_equal "Foo", a + + a = "FooBar" + assert_equal "", a.slice!(6, 2) + assert_equal "FooBar", a + + a = "FooBar" + assert_nil a.slice!(-7,10) + assert_equal "FooBar", a + + a = "FooBar" + assert_equal "Foo", a.slice!(0..2) + assert_equal "Bar", a + + a = "FooBar" + assert_equal "Bar", a.slice!(-3..-1) + assert_equal "Foo", a + + a = "FooBar" + assert_equal "", a.slice!(6..2) + assert_equal "FooBar", a + + a = "FooBar" + assert_nil a.slice!(-10..-7) + assert_equal "FooBar", a + + a = "FooBar" + assert_equal "Foo", a.slice!("Foo") + assert_equal "Bar", a + + a = "FooBar" + assert_nil a.slice!("xyzzy") + assert_equal "FooBar", a + + assert_raise(ArgumentError) { "foo".slice! } +end + +assert('String#succ') do + assert_equal "", "".succ + assert_equal "1", "0".succ + assert_equal "10", "9".succ + assert_equal "01", "00".succ + assert_equal "a1", "a0".succ + assert_equal "A1", "A0".succ + assert_equal "10", "09".succ + assert_equal "b0", "a9".succ + assert_equal "B0", "A9".succ + + assert_equal "b", "a".succ + assert_equal "aa", "z".succ + assert_equal "ab", "aa".succ + assert_equal "Ab", "Aa".succ + assert_equal "0b", "0a".succ + assert_equal "ba", "az".succ + assert_equal "Ba", "Az".succ + assert_equal "1a", "0z".succ + + assert_equal "B", "A".succ + assert_equal "AA", "Z".succ + assert_equal "AB", "AA".succ + assert_equal "aB", "aA".succ + assert_equal "0B", "0A".succ + assert_equal "BA", "AZ".succ + assert_equal "bA", "aZ".succ + assert_equal "1A", "0Z".succ + + assert_equal ".", "-".succ + assert_equal "\x01\x00", "\xff".succ + assert_equal "-b", "-a".succ + assert_equal "-aa", "-z".succ + assert_equal "-a-b-", "-a-a-".succ + assert_equal "-b-", "-a-".succ + assert_equal "-aa-", "-z-".succ + assert_equal "ã‚b", "ã‚a".succ + assert_equal "ã‚ba", "ã‚az".succ + + a = ""; a.succ! + assert_equal "", a + a = "0"; a.succ! + assert_equal "1", a + a = "9"; a.succ! + assert_equal "10", a + a = "00"; a.succ! + assert_equal "01", a + a = "a0"; a.succ! + assert_equal "a1", a + a = "A0"; a.succ! + assert_equal "A1", a + a = "09"; a.succ! + assert_equal "10", a + a = "a9"; a.succ! + assert_equal "b0", a + a = "A9"; a.succ! + assert_equal "B0", a + + a = "a"; a.succ! + assert_equal "b", a + a = "z"; a.succ! + assert_equal "aa", a + a = "aa"; a.succ! + assert_equal "ab", a + a = "Aa"; a.succ! + assert_equal "Ab", a + a = "0a"; a.succ! + assert_equal "0b", a + a = "az"; a.succ! + assert_equal "ba", a + a = "Az"; a.succ! + assert_equal "Ba", a + a = "0z"; a.succ! + assert_equal "1a", a + + a = "A"; a.succ! + assert_equal "B", a + a = "Z"; a.succ! + assert_equal "AA", a + a = "AA"; a.succ! + assert_equal "AB", a + a = "aA"; a.succ! + assert_equal "aB", a + a = "0A"; a.succ! + assert_equal "0B", a + a = "AZ"; a.succ! + assert_equal "BA", a + a = "aZ"; a.succ! + assert_equal "bA", a + a = "0Z"; a.succ! + assert_equal "1A", a + + a = "-"; a.succ! + assert_equal ".", a + a = "\xff"; a.succ! + assert_equal "\x01\x00", a + a = "-a"; a.succ! + assert_equal "-b", a + a = "-z"; a.succ! + assert_equal "-aa", a + a = "-a-a-"; a.succ! + assert_equal "-a-b-", a + a = "-a-"; a.succ! + assert_equal "-b-", a + a = "-z-"; a.succ! + assert_equal "-aa-", a + a = "ã‚b"; a.succ! + assert_equal "ã‚c", a + a = "ã‚az"; a.succ! + assert_equal "ã‚ba", a +end + +assert('String#next') do + assert_equal "01", "00".next + + a = "00"; a.next! + assert_equal "01", a +end + +assert('String#insert') do + assert_equal "Xabcd", "abcd".insert(0, 'X') + assert_equal "abcXd", "abcd".insert(3, 'X') + assert_equal "abcdX", "abcd".insert(4, 'X') + assert_equal "abXcd", "abcd".insert(-3, 'X') + assert_equal "abcdX", "abcd".insert(-1, 'X') + assert_raise(IndexError) { "abcd".insert(5, 'X') } + assert_raise(IndexError) { "abcd".insert(-6, 'X') } + + a = "abcd" + a.insert(0, 'X') + assert_equal "Xabcd", a +end + +assert('String#prepend') do + a = "world" + assert_equal "hello world", a.prepend("hello ") + assert_equal "hello world", a +end + +assert('String#ljust') do + assert_equal "hello", "hello".ljust(4) + assert_equal "hello ", "hello".ljust(20) + assert_equal 20, "hello".ljust(20).length + assert_equal "hello123412341234123", "hello".ljust(20, '1234') + assert_equal "hello", "hello".ljust(-3) +end + +assert('String#rjust') do + assert_equal "hello", "hello".rjust(4) + assert_equal " hello", "hello".rjust(20) + assert_equal 20, "hello".rjust(20).length + assert_equal "123412341234123hello", "hello".rjust(20, '1234') + assert_equal "hello", "hello".rjust(-3) +end + +if UTF8STRING + assert('String#ljust with UTF8') do + assert_equal "helloã‚“ ", "helloã‚“".ljust(20) + assert_equal "helloó ", "helloó".ljust(34) + assert_equal 34, "helloó".ljust(34).length + assert_equal "helloã‚“ã‚“ã‚“ã‚“ã‚“ã‚“ã‚“ã‚“ã‚“ã‚“ã‚“ã‚“ã‚“ã‚“", "hello".ljust(19, 'ã‚“') + assert_equal "helloã‚“ã‚“ã‚“ã‚“ã‚“ã‚“ã‚“ã‚“ã‚“ã‚“ã‚“ã‚“ã‚“ã‚“ã‚“", "hello".ljust(20, 'ã‚“') + end + + assert('String#rjust with UTF8') do + assert_equal " helloã‚“", "helloã‚“".rjust(20) + assert_equal " helloó", "helloó".rjust(34) + # assert_equal 34, "helloó".rjust(34).length + assert_equal "ã‚“ã‚“ã‚“ã‚“ã‚“ã‚“ã‚“ã‚“ã‚“ã‚“ã‚“ã‚“ã‚“ã‚“hello", "hello".rjust(19, 'ã‚“') + assert_equal "ã‚“ã‚“ã‚“ã‚“ã‚“ã‚“ã‚“ã‚“ã‚“ã‚“ã‚“ã‚“ã‚“ã‚“ã‚“hello", "hello".rjust(20, 'ã‚“') + end + + assert('UTF8 byte counting') do + ret = ' ' + ret[-6..-1] = "helloó" + assert_equal 34, ret.length + end +end + +assert('String#ljust should not change string') do + a = "hello" + a.ljust(20) + assert_equal "hello", a +end + +assert('String#rjust should not change string') do + a = "hello" + a.rjust(20) + assert_equal "hello", a +end + +assert('String#ljust should raise on zero width padding') do + assert_raise(ArgumentError) { "foo".ljust(10, '') } +end + +assert('String#rjust should raise on zero width padding') do + assert_raise(ArgumentError) { "foo".rjust(10, '') } +end + +assert('String#upto') do + assert_equal %w(a8 a9 b0 b1 b2 b3 b4 b5 b6), "a8".upto("b6").to_a + assert_equal ["9", "10", "11"], "9".upto("11").to_a + assert_equal [], "25".upto("5").to_a + assert_equal ["07", "08", "09", "10", "11"], "07".upto("11").to_a + +if UTF8STRING + assert_equal ["ã‚", "ãƒ", "ã„", "ã…", "ã†", "ã‡", "ãˆ", "ã‰", "ãŠ"], "ã‚".upto("ãŠ").to_a +end + + assert_equal ["9", ":", ";", "<", "=", ">", "?", "@", "A"], "9".upto("A").to_a + + a = "aa" + start = "aa" + count = 0 + assert_equal("aa", a.upto("zz") {|s| + assert_equal(start, s) + start.succ! + count += 1 + }) + assert_equal(676, count) + + a = "a" + start = "a" + count = 0 + assert_equal("a", a.upto("a") {|s| + assert_equal(start, s) + start.succ! + count += 1 + }) + assert_equal(1, count) + + a = "a" + start = "a" + count = 0 + assert_equal("a", a.upto("b", true) {|s| + assert_equal(start, s) + start.succ! + count += 1 + }) + assert_equal(1, count) + + a = "0" + start = "0" + count = 0 + assert_equal("0", a.upto("0") {|s| + assert_equal(start, s) + start.succ! + count += 1 + }) + assert_equal(1, count) + + a = "0" + start = "0" + count = 0 + assert_equal("0", a.upto("-1") {|s| + assert_equal(start, s) + start.succ! + count += 1 + }) + assert_equal(0, count) + + a = "-1" + start = "-1" + count = 0 + assert_equal("-1", a.upto("-2") {|s| + assert_equal(start, s) + start.succ! + count += 1 + }) + assert_equal(2, count) + + assert_raise(TypeError) { "a".upto(:c) {} } +end + +assert('String#ord') do + got = "hello!".split('').map {|x| x.ord} + expect = [104, 101, 108, 108, 111, 33] + unless UTF8STRING + got << "\xff".ord + expect << 0xff + end + assert_equal expect, got +end + +assert('String#ord(UTF-8)') do + got = "ã“ã‚“ã«ã¡ã¯ä¸–ç•Œ!".split('').map {|x| x.ord} + expect = [0x3053,0x3093,0x306b,0x3061,0x306f,0x4e16,0x754c,0x21] + assert_equal expect, got +end if UTF8STRING + +assert('String#chr') do + assert_equal "h", "hello!".chr +end +assert('String#chr(UTF-8)') do + assert_equal "ã“", "ã“ã‚“ã«ã¡ã¯ä¸–ç•Œ!".chr +end if UTF8STRING + +assert('String#chars') do + expect = ["h", "e", "l", "l", "o", "!"] + assert_equal expect, "hello!".chars + s = "" + "hello!".chars do |x| + s += x + end + assert_equal "hello!", s +end + +assert('String#chars(UTF-8)') do + expect = ['ã“', 'ã‚“', 'ã«', 'ã¡', 'ã¯', '世', 'ç•Œ', '!'] + assert_equal expect, "ã“ã‚“ã«ã¡ã¯ä¸–ç•Œ!".chars + s = "" + "ã“ã‚“ã«ã¡ã¯ä¸–ç•Œ!".chars do |x| + s += x + end + assert_equal "ã“ã‚“ã«ã¡ã¯ä¸–ç•Œ!", s +end if UTF8STRING + +assert('String#each_char') do + s = "" + "hello!".each_char do |x| + s += x + end + assert_equal "hello!", s +end + +assert('String#each_char(UTF-8)') do + s = "" + "ã“ã‚“ã«ã¡ã¯ä¸–ç•Œ!".each_char do |x| + s += x + end + assert_equal "ã“ã‚“ã«ã¡ã¯ä¸–ç•Œ!", s +end if UTF8STRING + +assert('String#codepoints') do + expect = [104, 101, 108, 108, 111, 33] + assert_equal expect, "hello!".codepoints + cp = [] + "hello!".codepoints do |x| + cp << x + end + assert_equal expect, cp +end + +assert('String#codepoints(UTF-8)') do + expect = [12371, 12435, 12395, 12385, 12399, 19990, 30028, 33] + assert_equal expect, "ã“ã‚“ã«ã¡ã¯ä¸–ç•Œ!".codepoints + cp = [] + "ã“ã‚“ã«ã¡ã¯ä¸–ç•Œ!".codepoints do |x| + cp << x + end + assert_equal expect, cp +end if UTF8STRING + +assert('String#each_codepoint') do + expect = [104, 101, 108, 108, 111, 33] + cp = [] + "hello!".each_codepoint do |x| + cp << x + end + assert_equal expect, cp +end + +assert('String#each_codepoint(UTF-8)') do + expect = [12371, 12435, 12395, 12385, 12399, 19990, 30028, 33] + cp = [] + "ã“ã‚“ã«ã¡ã¯ä¸–ç•Œ!".each_codepoint do |x| + cp << x + end + assert_equal expect, cp +end if UTF8STRING diff --git a/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-struct/mrbgem.rake b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-struct/mrbgem.rake new file mode 100644 index 00000000..2826ad2a --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-struct/mrbgem.rake @@ -0,0 +1,5 @@ +MRuby::Gem::Specification.new('mruby-struct') do |spec| + spec.license = 'MIT' + spec.author = 'mruby developers' + spec.summary = 'standard Struct class' +end diff --git a/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-struct/mrblib/struct.rb b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-struct/mrblib/struct.rb new file mode 100644 index 00000000..7cf3dd3a --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-struct/mrblib/struct.rb @@ -0,0 +1,103 @@ +## +# Struct +# +# ISO 15.2.18 + +if Object.const_defined?(:Struct) + class Struct + + ## + # Calls the given block for each element of +self+ + # and pass the respective element. + # + # ISO 15.2.18.4.4 + def each(&block) + self.class.members.each{|field| + block.call(self[field]) + } + self + end + + ## + # Calls the given block for each element of +self+ + # and pass the name and value of the respectiev + # element. + # + # ISO 15.2.18.4.5 + def each_pair(&block) + self.class.members.each{|field| + block.call(field.to_sym, self[field]) + } + self + end + + ## + # Calls the given block for each element of +self+ + # and returns an array with all elements of which + # block is not false. + # + # ISO 15.2.18.4.7 + def select(&block) + ary = [] + self.class.members.each{|field| + val = self[field] + ary.push(val) if block.call(val) + } + ary + end + + def _inspect + name = self.class.to_s + if name[0] == "#" + str = "#" + end + + ## + # call-seq: + # struct.to_s -> string + # struct.inspect -> string + # + # Describe the contents of this struct in a string. + # + # 15.2.18.4.10(x) + # + def inspect + begin + self._inspect + rescue SystemStackError + "#" + end + end + + ## + # 15.2.18.4.11(x) + # + alias to_s inspect + end + + ## + # call-seq: + # hsh.dig(key,...) -> object + # + # Extracts the nested value specified by the sequence of key + # objects by calling +dig+ at each step, returning +nil+ if any + # intermediate step is +nil+. + # + def dig(idx,*args) + n = self[idx] + if args.size > 0 + n&.dig(*args) + else + n + end + end +end + diff --git a/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-struct/src/struct.c b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-struct/src/struct.c new file mode 100644 index 00000000..67762a94 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-struct/src/struct.c @@ -0,0 +1,714 @@ +/* +** struct.c - Struct class +** +** See Copyright Notice in mruby.h +*/ + +#include +#include +#include +#include +#include +#include +#include +#include + +#define RSTRUCT_LEN(st) RARRAY_LEN(st) +#define RSTRUCT_PTR(st) RARRAY_PTR(st) + +static struct RClass * +struct_class(mrb_state *mrb) +{ + return mrb_class_get(mrb, "Struct"); +} + +static inline mrb_value +struct_ivar_get(mrb_state *mrb, mrb_value c, mrb_sym id) +{ + struct RClass* kclass; + struct RClass* sclass = struct_class(mrb); + mrb_value ans; + + for (;;) { + ans = mrb_iv_get(mrb, c, id); + if (!mrb_nil_p(ans)) return ans; + kclass = RCLASS_SUPER(c); + if (kclass == 0 || kclass == sclass) + return mrb_nil_value(); + c = mrb_obj_value(kclass); + } +} + +static mrb_value +struct_s_members(mrb_state *mrb, struct RClass *klass) +{ + mrb_value members = struct_ivar_get(mrb, mrb_obj_value(klass), mrb_intern_lit(mrb, "__members__")); + + if (mrb_nil_p(members)) { + mrb_raise(mrb, E_TYPE_ERROR, "uninitialized struct"); + } + if (!mrb_array_p(members)) { + mrb_raise(mrb, E_TYPE_ERROR, "corrupted struct"); + } + return members; +} + +static mrb_value +struct_members(mrb_state *mrb, mrb_value s) +{ + mrb_value members = struct_s_members(mrb, mrb_obj_class(mrb, s)); + if (!mrb_array_p(s)) { + mrb_raise(mrb, E_TYPE_ERROR, "corrupted struct"); + } + if (RSTRUCT_LEN(s) != RARRAY_LEN(members)) { + if (RSTRUCT_LEN(s) == 0) { /* probably uninitialized */ + mrb_ary_resize(mrb, s, RARRAY_LEN(members)); + } + else { + mrb_raisef(mrb, E_TYPE_ERROR, + "struct size differs (%S required %S given)", + mrb_fixnum_value(RARRAY_LEN(members)), mrb_fixnum_value(RSTRUCT_LEN(s))); + } + } + return members; +} + +static mrb_value +mrb_struct_s_members_m(mrb_state *mrb, mrb_value klass) +{ + mrb_value members, ary; + + members = struct_s_members(mrb, mrb_class_ptr(klass)); + ary = mrb_ary_new_capa(mrb, RARRAY_LEN(members)); + mrb_ary_replace(mrb, ary, members); + return ary; +} + +static void +mrb_struct_modify(mrb_state *mrb, mrb_value strct) +{ + if (MRB_FROZEN_P(mrb_basic_ptr(strct))) { + mrb_raise(mrb, E_RUNTIME_ERROR, "can't modify frozen struct"); + } + + mrb_write_barrier(mrb, mrb_basic_ptr(strct)); +} + +/* 15.2.18.4.6 */ +/* + * call-seq: + * struct.members -> array + * + * Returns an array of strings representing the names of the instance + * variables. + * + * Customer = Struct.new(:name, :address, :zip) + * joe = Customer.new("Joe Smith", "123 Maple, Anytown NC", 12345) + * joe.members #=> [:name, :address, :zip] + */ + +static mrb_value +mrb_struct_members(mrb_state *mrb, mrb_value obj) +{ + return mrb_struct_s_members_m(mrb, mrb_obj_value(mrb_obj_class(mrb, obj))); +} + +static mrb_value struct_aref_sym(mrb_state *mrb, mrb_value obj, mrb_sym id); + +static mrb_value +mrb_struct_ref(mrb_state *mrb, mrb_value obj) +{ + return struct_aref_sym(mrb, obj, mrb->c->ci->mid); +} + +static mrb_sym +mrb_id_attrset(mrb_state *mrb, mrb_sym id) +{ + const char *name; + char *buf; + mrb_int len; + mrb_sym mid; + + name = mrb_sym2name_len(mrb, id, &len); + buf = (char *)mrb_malloc(mrb, (size_t)len+2); + memcpy(buf, name, (size_t)len); + buf[len] = '='; + buf[len+1] = '\0'; + + mid = mrb_intern(mrb, buf, len+1); + mrb_free(mrb, buf); + return mid; +} + +static mrb_value mrb_struct_aset_sym(mrb_state *mrb, mrb_value s, mrb_sym id, mrb_value val); + +static mrb_value +mrb_struct_set_m(mrb_state *mrb, mrb_value obj) +{ + mrb_value val; + + const char *name; + mrb_int slen; + mrb_sym mid; + + mrb_get_args(mrb, "o", &val); + + /* get base id */ + name = mrb_sym2name_len(mrb, mrb->c->ci->mid, &slen); + mid = mrb_intern(mrb, name, slen-1); /* omit last "=" */ + + return mrb_struct_aset_sym(mrb, obj, mid, val); +} + +static mrb_bool +is_local_id(mrb_state *mrb, const char *name) +{ + if (!name) return FALSE; + return !ISUPPER(name[0]); +} + +static mrb_bool +is_const_id(mrb_state *mrb, const char *name) +{ + if (!name) return FALSE; + return ISUPPER(name[0]); +} + +static void +make_struct_define_accessors(mrb_state *mrb, mrb_value members, struct RClass *c) +{ + const mrb_value *ptr_members = RARRAY_PTR(members); + mrb_int i; + mrb_int len = RARRAY_LEN(members); + int ai = mrb_gc_arena_save(mrb); + + for (i=0; ibasic.c->super = c->c; */ + make_struct_define_accessors(mrb, members, c); + return nstr; +} + +/* 15.2.18.3.1 */ +/* + * call-seq: + * Struct.new( [aString] [, aSym]+> ) -> StructClass + * StructClass.new(arg, ...) -> obj + * StructClass[arg, ...] -> obj + * + * Creates a new class, named by aString, containing accessor + * methods for the given symbols. If the name aString is + * omitted, an anonymous structure class will be created. Otherwise, + * the name of this struct will appear as a constant in class + * Struct, so it must be unique for all + * Structs in the system and should start with a capital + * letter. Assigning a structure class to a constant effectively gives + * the class the name of the constant. + * + * Struct::new returns a new Class object, + * which can then be used to create specific instances of the new + * structure. The number of actual parameters must be + * less than or equal to the number of attributes defined for this + * class; unset parameters default to nil. Passing too many + * parameters will raise an ArgumentError. + * + * The remaining methods listed in this section (class and instance) + * are defined for this generated class. + * + * # Create a structure with a name in Struct + * Struct.new("Customer", :name, :address) #=> Struct::Customer + * Struct::Customer.new("Dave", "123 Main") #=> # + * + * # Create a structure named by its constant + * Customer = Struct.new(:name, :address) #=> Customer + * Customer.new("Dave", "123 Main") #=> # + */ +static mrb_value +mrb_struct_s_def(mrb_state *mrb, mrb_value klass) +{ + mrb_value name, rest; + mrb_value *pargv; + mrb_int argcnt; + mrb_int i; + mrb_value b, st; + mrb_sym id; + mrb_value *argv; + mrb_int argc; + + name = mrb_nil_value(); + mrb_get_args(mrb, "*&", &argv, &argc, &b); + if (argc == 0) { /* special case to avoid crash */ + rest = mrb_ary_new(mrb); + } + else { + if (argc > 0) name = argv[0]; + pargv = &argv[1]; + argcnt = argc-1; + if (!mrb_nil_p(name) && mrb_symbol_p(name)) { + /* 1stArgument:symbol -> name=nil rest=argv[0]-[n] */ + name = mrb_nil_value(); + pargv = &argv[0]; + argcnt++; + } + rest = mrb_ary_new_from_values(mrb, argcnt, pargv); + for (i=0; i anObject + * struct[fixnum] -> anObject + * + * Attribute Reference---Returns the value of the instance variable + * named by symbol, or indexed (0..length-1) by + * fixnum. Will raise NameError if the named + * variable does not exist, or IndexError if the index is + * out of range. + * + * Customer = Struct.new(:name, :address, :zip) + * joe = Customer.new("Joe Smith", "123 Maple, Anytown NC", 12345) + * + * joe["name"] #=> "Joe Smith" + * joe[:name] #=> "Joe Smith" + * joe[0] #=> "Joe Smith" + */ +static mrb_value +mrb_struct_aref(mrb_state *mrb, mrb_value s) +{ + mrb_value idx; + + mrb_get_args(mrb, "o", &idx); + if (mrb_string_p(idx)) { + mrb_value sym = mrb_check_intern_str(mrb, idx); + + if (mrb_nil_p(sym)) { + mrb_name_error(mrb, mrb_intern_str(mrb, idx), "no member '%S' in struct", idx); + } + idx = sym; + } + if (mrb_symbol_p(idx)) { + return struct_aref_sym(mrb, s, mrb_symbol(idx)); + } + return struct_aref_int(mrb, s, mrb_int(mrb, idx)); +} + +static mrb_value +mrb_struct_aset_sym(mrb_state *mrb, mrb_value s, mrb_sym id, mrb_value val) +{ + mrb_value members, *ptr; + const mrb_value *ptr_members; + mrb_int i, len; + + members = struct_members(mrb, s); + len = RARRAY_LEN(members); + ptr = RSTRUCT_PTR(s); + ptr_members = RARRAY_PTR(members); + for (i=0; i obj + * struct[fixnum] = obj -> obj + * + * Attribute Assignment---Assigns to the instance variable named by + * symbol or fixnum the value obj and + * returns it. Will raise a NameError if the named + * variable does not exist, or an IndexError if the index + * is out of range. + * + * Customer = Struct.new(:name, :address, :zip) + * joe = Customer.new("Joe Smith", "123 Maple, Anytown NC", 12345) + * + * joe["name"] = "Luke" + * joe[:zip] = "90210" + * + * joe.name #=> "Luke" + * joe.zip #=> "90210" + */ + +static mrb_value +mrb_struct_aset(mrb_state *mrb, mrb_value s) +{ + mrb_int i; + mrb_value idx; + mrb_value val; + + mrb_get_args(mrb, "oo", &idx, &val); + + if (mrb_string_p(idx)) { + mrb_value sym = mrb_check_intern_str(mrb, idx); + + if (mrb_nil_p(sym)) { + mrb_name_error(mrb, mrb_intern_str(mrb, idx), "no member '%S' in struct", idx); + } + idx = sym; + } + if (mrb_symbol_p(idx)) { + return mrb_struct_aset_sym(mrb, s, mrb_symbol(idx), val); + } + + i = mrb_int(mrb, idx); + if (i < 0) i = RSTRUCT_LEN(s) + i; + if (i < 0) { + mrb_raisef(mrb, E_INDEX_ERROR, + "offset %S too small for struct(size:%S)", + mrb_fixnum_value(i), mrb_fixnum_value(RSTRUCT_LEN(s))); + } + if (RSTRUCT_LEN(s) <= i) { + mrb_raisef(mrb, E_INDEX_ERROR, + "offset %S too large for struct(size:%S)", + mrb_fixnum_value(i), mrb_fixnum_value(RSTRUCT_LEN(s))); + } + mrb_struct_modify(mrb, s); + return RSTRUCT_PTR(s)[i] = val; +} + +/* 15.2.18.4.1 */ +/* + * call-seq: + * struct == other_struct -> true or false + * + * Equality---Returns true if other_struct is + * equal to this one: they must be of the same class as generated by + * Struct::new, and the values of all instance variables + * must be equal (according to Object#==). + * + * Customer = Struct.new(:name, :address, :zip) + * joe = Customer.new("Joe Smith", "123 Maple, Anytown NC", 12345) + * joejr = Customer.new("Joe Smith", "123 Maple, Anytown NC", 12345) + * jane = Customer.new("Jane Doe", "456 Elm, Anytown NC", 12345) + * joe == joejr #=> true + * joe == jane #=> false + */ + +static mrb_value +mrb_struct_equal(mrb_state *mrb, mrb_value s) +{ + mrb_value s2; + mrb_value *ptr, *ptr2; + mrb_int i, len; + + mrb_get_args(mrb, "o", &s2); + if (mrb_obj_equal(mrb, s, s2)) { + return mrb_true_value(); + } + if (mrb_obj_class(mrb, s) != mrb_obj_class(mrb, s2)) { + return mrb_false_value(); + } + if (RSTRUCT_LEN(s) != RSTRUCT_LEN(s2)) { + mrb_bug(mrb, "inconsistent struct"); /* should never happen */ + } + ptr = RSTRUCT_PTR(s); + ptr2 = RSTRUCT_PTR(s2); + len = RSTRUCT_LEN(s); + for (i=0; i true or false + * + * Two structures are equal if they are the same object, or if all their + * fields are equal (using eql?). + */ +static mrb_value +mrb_struct_eql(mrb_state *mrb, mrb_value s) +{ + mrb_value s2; + mrb_value *ptr, *ptr2; + mrb_int i, len; + + mrb_get_args(mrb, "o", &s2); + if (mrb_obj_equal(mrb, s, s2)) { + return mrb_true_value(); + } + if (mrb_obj_class(mrb, s) != mrb_obj_class(mrb, s2)) { + return mrb_false_value(); + } + if (RSTRUCT_LEN(s) != RSTRUCT_LEN(s2)) { + mrb_bug(mrb, "inconsistent struct"); /* should never happen */ + } + ptr = RSTRUCT_PTR(s); + ptr2 = RSTRUCT_PTR(s2); + len = RSTRUCT_LEN(s); + for (i=0; i Fixnum + * struct.size -> Fixnum + * + * Returns number of struct members. + */ +static mrb_value +mrb_struct_len(mrb_state *mrb, mrb_value self) +{ + return mrb_fixnum_value(RSTRUCT_LEN(self)); +} + +/* + * call-seq: + * struct.to_a -> array + * struct.values -> array + * + * Create an array from struct values. + */ +static mrb_value +mrb_struct_to_a(mrb_state *mrb, mrb_value self) +{ + return mrb_ary_new_from_values(mrb, RSTRUCT_LEN(self), RSTRUCT_PTR(self)); +} + +/* + * call-seq: + * struct.to_h -> hash + * + * Create a hash from member names and struct values. + */ +static mrb_value +mrb_struct_to_h(mrb_state *mrb, mrb_value self) +{ + mrb_value members, ret; + mrb_int i; + + members = struct_members(mrb, self); + ret = mrb_hash_new_capa(mrb, RARRAY_LEN(members)); + + for (i = 0; i < RARRAY_LEN(members); ++i) { + mrb_hash_set(mrb, ret, RARRAY_PTR(members)[i], RSTRUCT_PTR(self)[i]); + } + + return ret; +} + +static mrb_value +mrb_struct_values_at(mrb_state *mrb, mrb_value self) +{ + mrb_int argc; + mrb_value *argv; + + mrb_get_args(mrb, "*", &argv, &argc); + + return mrb_get_values_at(mrb, self, RSTRUCT_LEN(self), argc, argv, struct_aref_int); +} + +/* + * A Struct is a convenient way to bundle a number of + * attributes together, using accessor methods, without having to write + * an explicit class. + * + * The Struct class is a generator of specific classes, + * each one of which is defined to hold a set of variables and their + * accessors. In these examples, we'll call the generated class + * "CustomerClass," and we'll show an example instance of that + * class as "CustomerInst." + * + * In the descriptions that follow, the parameter symbol refers + * to a symbol, which is either a quoted string or a + * Symbol (such as :name). + */ +void +mrb_mruby_struct_gem_init(mrb_state* mrb) +{ + struct RClass *st; + st = mrb_define_class(mrb, "Struct", mrb->object_class); + MRB_SET_INSTANCE_TT(st, MRB_TT_ARRAY); + + mrb_define_class_method(mrb, st, "new", mrb_struct_s_def, MRB_ARGS_ANY()); /* 15.2.18.3.1 */ + + mrb_define_method(mrb, st, "==", mrb_struct_equal, MRB_ARGS_REQ(1)); /* 15.2.18.4.1 */ + mrb_define_method(mrb, st, "[]", mrb_struct_aref, MRB_ARGS_REQ(1)); /* 15.2.18.4.2 */ + mrb_define_method(mrb, st, "[]=", mrb_struct_aset, MRB_ARGS_REQ(2)); /* 15.2.18.4.3 */ + mrb_define_method(mrb, st, "members", mrb_struct_members, MRB_ARGS_NONE()); /* 15.2.18.4.6 */ + mrb_define_method(mrb, st, "initialize", mrb_struct_initialize, MRB_ARGS_ANY()); /* 15.2.18.4.8 */ + mrb_define_method(mrb, st, "initialize_copy", mrb_struct_init_copy, MRB_ARGS_REQ(1)); /* 15.2.18.4.9 */ + mrb_define_method(mrb, st, "eql?", mrb_struct_eql, MRB_ARGS_REQ(1)); /* 15.2.18.4.12(x) */ + + mrb_define_method(mrb, st, "size", mrb_struct_len, MRB_ARGS_NONE()); + mrb_define_method(mrb, st, "length", mrb_struct_len, MRB_ARGS_NONE()); + mrb_define_method(mrb, st, "to_a", mrb_struct_to_a, MRB_ARGS_NONE()); + mrb_define_method(mrb, st, "values", mrb_struct_to_a, MRB_ARGS_NONE()); + mrb_define_method(mrb, st, "to_h", mrb_struct_to_h, MRB_ARGS_NONE()); + mrb_define_method(mrb, st, "values_at", mrb_struct_values_at, MRB_ARGS_ANY()); +} + +void +mrb_mruby_struct_gem_final(mrb_state* mrb) +{ +} diff --git a/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-struct/test/struct.rb b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-struct/test/struct.rb new file mode 100644 index 00000000..421fe4b5 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-struct/test/struct.rb @@ -0,0 +1,212 @@ +## +# Struct ISO Test + +assert('Struct', '15.2.18') do + assert_equal Class, Struct.class +end + +assert('Struct.new', '15.2.18.3.1') do + c = Struct.new(:m1, :m2) + assert_equal Struct, c.superclass + assert_equal [:m1, :m2], c.members +end + +# Check crash bug with Struc.new and no params. +assert('Struct.new', '15.2.18.3.1') do + c = Struct.new() + assert_equal Struct, c.superclass + assert_equal [], c.members +end + +assert('Struct#==', '15.2.18.4.1') do + c = Struct.new(:m1, :m2) + cc1 = c.new(1,2) + cc2 = c.new(1,2) + assert_true cc1 == cc2 + + Struct.new(:m1, :m2) { def foo; end } + assert_raise(NoMethodError) { Struct.new(:m1).new.foo } +end + +assert('Struct#[]', '15.2.18.4.2') do + c = Struct.new(:m1, :m2) + cc = c.new(1,2) + assert_equal 1, cc[:m1] + assert_equal 2, cc["m2"] + assert_equal 1, cc[0] + assert_equal 2, cc[-1] + assert_raise(TypeError) { cc[[]] } + assert_raise(IndexError) { cc[2] } + assert_raise(NameError) { cc['tama'] } +end + +assert('Struct#[]=', '15.2.18.4.3') do + c = Struct.new(:m1, :m2) + cc = c.new(1,2) + cc[:m1] = 3 + assert_equal 3, cc[:m1] + cc["m2"] = 3 + assert_equal 3, cc["m2"] + cc[0] = 4 + assert_equal 4, cc[0] + cc[-1] = 5 + assert_equal 5, cc[-1] + assert_raise(TypeError) { cc[[]] = 3 } + assert_raise(IndexError) { cc[2] = 7 } + assert_raise(NameError) { cc['pochi'] = 8 } +end + +assert('Struct#each', '15.2.18.4.4') do + c = Struct.new(:m1, :m2) + cc = c.new(1,2) + a = [] + cc.each{|x| + a << x + } + assert_equal [1, 2], a +end + +assert('Struct#each_pair', '15.2.18.4.5') do + c = Struct.new(:m1, :m2) + cc = c.new(1,2) + a = [] + cc.each_pair{|k,v| + a << [k,v] + } + assert_equal [[:m1, 1], [:m2, 2]], a +end + +assert('Struct#members', '15.2.18.4.6') do + c = Struct.new(:m1, :m2) + assert_equal [:m1, :m2], c.new(1,2).members +end + +assert('Struct#select', '15.2.18.4.7') do + c = Struct.new(:m1, :m2) + assert_equal([2]) { c.new(1,2).select{|v| v % 2 == 0} } +end + +assert('large struct') do + c = Struct.new(:m1, :m2, :m3, :m4, :m5, :m6, :m7, :m8, :m9, :m10, :m11, :m12, :m13) + cc = c.new(1,2,3,4,5,6,7,8,9,10,11,12,13) + assert_equal 1, cc.m1 + assert_equal 2, cc.m2 + assert_equal 3, cc.m3 + assert_equal 4, cc.m4 + assert_equal 5, cc.m5 + assert_equal 6, cc.m6 + assert_equal 7, cc.m7 + assert_equal 8, cc.m8 + assert_equal 9, cc.m9 + assert_equal 10, cc.m10 + assert_equal 13, cc.m13 + + cc.m13 = 'test' + assert_equal 'test', cc.m13 + + assert_raise(NoMethodError) { cc.m14 } +end + +assert('wrong struct arg count') do + c = Struct.new(:m1) + assert_raise ArgumentError do + cc = c.new(1,2,3) + end +end + +assert('struct dup') do + c = Struct.new(:m1, :m2, :m3, :m4, :m5) + cc = c.new(1,2,3,4,5) + assert_nothing_raised { + assert_equal(cc, cc.dup) + } +end + +assert('struct inspect') do + c = Struct.new(:m1, :m2, :m3, :m4, :m5) + cc = c.new(1,2,3,4,5) + assert_equal "#", cc.inspect +end + +assert('Struct#length, Struct#size') do + s = Struct.new(:f1, :f2).new(0, 1) + assert_equal 2, s.size + assert_equal 2, s.length +end + +assert('Struct#to_a, Struct#values') do + s = Struct.new(:mem1, :mem2).new('a', 'b') + assert_equal ['a', 'b'], s.to_a + assert_equal ['a', 'b'], s.values +end + +assert('Struct#to_h') do + s = Struct.new(:white, :red, :green).new('ruuko', 'yuzuki', 'hitoe') + assert_equal(:white => 'ruuko', :red => 'yuzuki', :green => 'hitoe') { s.to_h } +end + +assert('Struct#values_at') do + a = Struct.new(:blue, :purple).new('aki', 'io') + assert_equal ['aki'], a.values_at(0) + assert_equal ['io', 'aki'], a.values_at(1, 0) + assert_raise(IndexError) { a.values_at 2 } +end + +assert("Struct#dig") do + a = Struct.new(:blue, :purple).new('aki', Struct.new(:red).new(1)) + assert_equal 'aki', a.dig(:blue) + assert_equal 1, a.dig(:purple, :red) + assert_equal 1, a.dig(1, 0) +end + +assert("Struct.new removes existing constant") do + skip "redefining Struct with same name cause warnings" + begin + assert_not_equal Struct.new("Test", :a), Struct.new("Test", :a, :b) + ensure + Struct.remove_const :Test + end +end + +assert("Struct#initialize_copy requires struct to be the same type") do + begin + Struct.new("Test", :a) + a = Struct::Test.new("a") + Struct.remove_const :Test + Struct.new("Test", :a, :b) + assert_raise(TypeError) do + a.initialize_copy(Struct::Test.new("a", "b")) + end + ensure + Struct.remove_const :Test + end +end + +assert("Struct.new does not allow array") do + assert_raise(TypeError) do + Struct.new("Test", [:a]) + end +end + +assert("Struct.new generates subclass of Struct") do + begin + original_struct = Struct + Struct = String + assert_equal original_struct, original_struct.new.superclass + ensure + Struct = original_struct + end +end + +assert 'Struct#freeze' do + c = Struct.new :m + + o = c.new + o.m = :test + assert_equal :test, o.m + + o.freeze + assert_raise(RuntimeError) { o.m = :modify } + assert_raise(RuntimeError) { o[:m] = :modify } + assert_equal :test, o.m +end diff --git a/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-symbol-ext/mrbgem.rake b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-symbol-ext/mrbgem.rake new file mode 100644 index 00000000..4f3fa43b --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-symbol-ext/mrbgem.rake @@ -0,0 +1,5 @@ +MRuby::Gem::Specification.new('mruby-symbol-ext') do |spec| + spec.license = 'MIT' + spec.author = 'mruby developers' + spec.summary = 'Symbol class extension' +end diff --git a/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-symbol-ext/mrblib/symbol.rb b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-symbol-ext/mrblib/symbol.rb new file mode 100644 index 00000000..1e3d24b8 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-symbol-ext/mrblib/symbol.rb @@ -0,0 +1,65 @@ +class Symbol + include Comparable + + alias intern to_sym + + def to_proc + ->(obj,*args,&block) do + obj.__send__(self, *args, &block) + end + end + + ## + # call-seq: + # sym.capitalize -> symbol + # + # Same as sym.to_s.capitalize.intern. + + def capitalize + (self.to_s.capitalize! || self).to_sym + end + + ## + # call-seq: + # sym.downcase -> symbol + # + # Same as sym.to_s.downcase.intern. + + def downcase + (self.to_s.downcase! || self).to_sym + end + + ## + # call-seq: + # sym.upcase -> symbol + # + # Same as sym.to_s.upcase.intern. + + def upcase + (self.to_s.upcase! || self).to_sym + end + + ## + # call-seq: + # sym.casecmp(other) -> -1, 0, +1 or nil + # + # Case-insensitive version of Symbol#<=>. + + def casecmp(other) + return nil unless other.kind_of?(Symbol) + lhs = self.to_s; lhs.upcase! + rhs = other.to_s; rhs.upcase! + lhs <=> rhs + end + + # + # call-seq: + # sym.empty? -> true or false + # + # Returns that _sym_ is :"" or not. + + def empty? + self.length == 0 + end + +end diff --git a/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-symbol-ext/src/symbol.c b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-symbol-ext/src/symbol.c new file mode 100644 index 00000000..a992dbfc --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-symbol-ext/src/symbol.c @@ -0,0 +1,64 @@ +#include +#include +#include + +typedef struct symbol_name { + size_t len; + const char *name; +} symbol_name; + +/* + * call-seq: + * Symbol.all_symbols => array + * + * Returns an array of all the symbols currently in Ruby's symbol + * table. + * + * Symbol.all_symbols.size #=> 903 + * Symbol.all_symbols[1,20] #=> [:floor, :ARGV, :Binding, :symlink, + * :chown, :EOFError, :$;, :String, + * :LOCK_SH, :"setuid?", :$<, + * :default_proc, :compact, :extend, + * :Tms, :getwd, :$=, :ThreadGroup, + * :wait2, :$>] + */ +static mrb_value +mrb_sym_all_symbols(mrb_state *mrb, mrb_value self) +{ + mrb_sym i, lim; + mrb_value ary = mrb_ary_new_capa(mrb, mrb->symidx); + + for (i=1, lim=mrb->symidx+1; i integer + * + * Same as sym.to_s.length. + */ +static mrb_value +mrb_sym_length(mrb_state *mrb, mrb_value self) +{ + mrb_int len; + mrb_sym2name_len(mrb, mrb_symbol(self), &len); + return mrb_fixnum_value(len); +} + +void +mrb_mruby_symbol_ext_gem_init(mrb_state* mrb) +{ + struct RClass *s = mrb->symbol_class; + mrb_define_class_method(mrb, s, "all_symbols", mrb_sym_all_symbols, MRB_ARGS_NONE()); + mrb_define_method(mrb, s, "length", mrb_sym_length, MRB_ARGS_NONE()); + mrb_define_method(mrb, s, "size", mrb_sym_length, MRB_ARGS_NONE()); +} + +void +mrb_mruby_symbol_ext_gem_final(mrb_state* mrb) +{ +} diff --git a/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-symbol-ext/test/symbol.rb b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-symbol-ext/test/symbol.rb new file mode 100644 index 00000000..6070d141 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-symbol-ext/test/symbol.rb @@ -0,0 +1,48 @@ +## +# Symbol(Ext) Test + +assert('Symbol#to_proc') do + assert_equal 5, :abs.to_proc[-5] +end + +assert('Symbol.all_symbols') do + foo = [:__symbol_test_1, :__symbol_test_2, :__symbol_test_3].sort + symbols = Symbol.all_symbols.select{|sym|sym.to_s.include? '__symbol_test'}.sort + assert_equal foo, symbols +end + +assert("Symbol#length") do + assert_equal 5, :hello.size + assert_equal 5, :mruby.length +end + +assert("Symbol#capitalize") do + assert_equal :Hello, :hello.capitalize + assert_equal :Hello, :HELLO.capitalize + assert_equal :Hello, :Hello.capitalize +end + +assert("Symbol#downcase") do + assert_equal :hello, :hEllO.downcase + assert_equal :hello, :hello.downcase +end + +assert("Symbol#upcase") do + assert_equal :HELLO, :hEllO.upcase + assert_equal :HELLO, :HELLO.upcase +end + +assert("Symbol#casecmp") do + assert_equal 0, :HELLO.casecmp(:hEllO) + assert_equal 1, :HELLO.casecmp(:hEllN) + assert_equal(-1, :HELLO.casecmp(:hEllP)) + assert_nil :HELLO.casecmp("hEllO") +end + +assert("Symbol#empty?") do + assert_true :''.empty? +end + +assert('Symbol#intern') do + assert_equal :test, :test.intern +end diff --git a/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-test/README.md b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-test/README.md new file mode 100644 index 00000000..fa4b91e3 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-test/README.md @@ -0,0 +1,7 @@ +Running Tests +============= + +To run the tests, execute the following from the project's root directory. + + $ make test + diff --git a/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-test/driver.c b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-test/driver.c new file mode 100644 index 00000000..14e93ff3 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-test/driver.c @@ -0,0 +1,172 @@ +/* +** mrbtest - Test for Embeddable Ruby +** +** This program runs Ruby test programs in test/t directory +** against the current mruby implementation. +*/ + + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +void +mrb_init_mrbtest(mrb_state *); + +/* Print a short remark for the user */ +static void +print_hint(void) +{ + printf("mrbtest - Embeddable Ruby Test\n\n"); +} + +static int +check_error(mrb_state *mrb) +{ + /* Error check */ + /* $ko_test and $kill_test should be 0 */ + mrb_value ko_test = mrb_gv_get(mrb, mrb_intern_lit(mrb, "$ko_test")); + mrb_value kill_test = mrb_gv_get(mrb, mrb_intern_lit(mrb, "$kill_test")); + + return mrb_fixnum_p(ko_test) && mrb_fixnum(ko_test) == 0 && mrb_fixnum_p(kill_test) && mrb_fixnum(kill_test) == 0; +} + +static int +eval_test(mrb_state *mrb) +{ + /* evaluate the test */ + mrb_funcall(mrb, mrb_top_self(mrb), "report", 0); + /* did an exception occur? */ + if (mrb->exc) { + mrb_print_error(mrb); + mrb->exc = 0; + return EXIT_FAILURE; + } + else if (!check_error(mrb)) { + return EXIT_FAILURE; + } + return EXIT_SUCCESS; +} + +static void +t_printstr(mrb_state *mrb, mrb_value obj) +{ + char *s; + int len; + + if (mrb_string_p(obj)) { + s = RSTRING_PTR(obj); + len = RSTRING_LEN(obj); + fwrite(s, len, 1, stdout); + } +} + +mrb_value +mrb_t_printstr(mrb_state *mrb, mrb_value self) +{ + mrb_value argv; + + mrb_get_args(mrb, "o", &argv); + t_printstr(mrb, argv); + + return argv; +} + +void +mrb_init_test_driver(mrb_state *mrb, mrb_bool verbose) +{ + struct RClass *krn, *mrbtest; + + krn = mrb->kernel_module; + mrb_define_method(mrb, krn, "__t_printstr__", mrb_t_printstr, MRB_ARGS_REQ(1)); + + mrbtest = mrb_define_module(mrb, "Mrbtest"); + + mrb_define_const(mrb, mrbtest, "FIXNUM_MAX", mrb_fixnum_value(MRB_INT_MAX)); + mrb_define_const(mrb, mrbtest, "FIXNUM_MIN", mrb_fixnum_value(MRB_INT_MIN)); + mrb_define_const(mrb, mrbtest, "FIXNUM_BIT", mrb_fixnum_value(MRB_INT_BIT)); + +#ifdef MRB_USE_FLOAT + mrb_define_const(mrb, mrbtest, "FLOAT_TOLERANCE", mrb_float_value(mrb, 1e-6)); +#else + mrb_define_const(mrb, mrbtest, "FLOAT_TOLERANCE", mrb_float_value(mrb, 1e-12)); +#endif + + if (verbose) { + mrb_gv_set(mrb, mrb_intern_lit(mrb, "$mrbtest_verbose"), mrb_true_value()); + } +} + +void +mrb_t_pass_result(mrb_state *mrb_dst, mrb_state *mrb_src) +{ + mrb_value res_src; + + if (mrb_src->exc) { + mrb_print_error(mrb_src); + exit(EXIT_FAILURE); + } + +#define TEST_COUNT_PASS(name) \ + do { \ + res_src = mrb_gv_get(mrb_src, mrb_intern_lit(mrb_src, "$" #name)); \ + if (mrb_fixnum_p(res_src)) { \ + mrb_value res_dst = mrb_gv_get(mrb_dst, mrb_intern_lit(mrb_dst, "$" #name)); \ + mrb_gv_set(mrb_dst, mrb_intern_lit(mrb_dst, "$" #name), mrb_fixnum_value(mrb_fixnum(res_dst) + mrb_fixnum(res_src))); \ + } \ + } while (FALSE) \ + + TEST_COUNT_PASS(ok_test); + TEST_COUNT_PASS(ko_test); + TEST_COUNT_PASS(kill_test); + +#undef TEST_COUNT_PASS + + res_src = mrb_gv_get(mrb_src, mrb_intern_lit(mrb_src, "$asserts")); + + if (mrb_array_p(res_src)) { + mrb_int i; + mrb_value res_dst = mrb_gv_get(mrb_dst, mrb_intern_lit(mrb_dst, "$asserts")); + for (i = 0; i < RARRAY_LEN(res_src); ++i) { + mrb_value val_src = RARRAY_PTR(res_src)[i]; + mrb_ary_push(mrb_dst, res_dst, mrb_str_new(mrb_dst, RSTRING_PTR(val_src), RSTRING_LEN(val_src))); + } + } +} + +int +main(int argc, char **argv) +{ + mrb_state *mrb; + int ret; + mrb_bool verbose = FALSE; + + print_hint(); + + /* new interpreter instance */ + mrb = mrb_open(); + if (mrb == NULL) { + fprintf(stderr, "Invalid mrb_state, exiting test driver"); + return EXIT_FAILURE; + } + + if (argc == 2 && argv[1][0] == '-' && argv[1][1] == 'v') { + printf("verbose mode: enable\n\n"); + verbose = TRUE; + } + + mrb_init_test_driver(mrb, verbose); + mrb_init_mrbtest(mrb); + ret = eval_test(mrb); + mrb_close(mrb); + + return ret; +} diff --git a/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-test/init_mrbtest.c b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-test/init_mrbtest.c new file mode 100644 index 00000000..17ac1bde --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-test/init_mrbtest.c @@ -0,0 +1,38 @@ +#include +#include +#include +#include + +extern const uint8_t mrbtest_assert_irep[]; + +void mrbgemtest_init(mrb_state* mrb); +void mrb_init_test_driver(mrb_state* mrb, mrb_bool verbose); +void mrb_t_pass_result(mrb_state *mrb_dst, mrb_state *mrb_src); + +void +mrb_init_mrbtest(mrb_state *mrb) +{ + mrb_state *core_test; + + mrb_load_irep(mrb, mrbtest_assert_irep); + + core_test = mrb_open_core(mrb_default_allocf, NULL); + if (core_test == NULL) { + fprintf(stderr, "Invalid mrb_state, exiting %s", __FUNCTION__); + exit(EXIT_FAILURE); + } + mrb_init_test_driver(core_test, mrb_test(mrb_gv_get(mrb, mrb_intern_lit(mrb, "$mrbtest_verbose")))); + mrb_load_irep(core_test, mrbtest_assert_irep); + mrb_t_pass_result(mrb, core_test); + +#ifndef DISABLE_GEMS + mrbgemtest_init(mrb); +#endif + + if (mrb->exc) { + mrb_print_error(mrb); + exit(EXIT_FAILURE); + } + mrb_close(core_test); +} + diff --git a/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-test/mrbgem.rake b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-test/mrbgem.rake new file mode 100644 index 00000000..ae4c2f13 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-test/mrbgem.rake @@ -0,0 +1,187 @@ +MRuby::Gem::Specification.new('mruby-test') do |spec| + spec.license = 'MIT' + spec.author = 'mruby developers' + spec.summary = 'mruby test' + + build.bins << 'mrbtest' + spec.add_dependency('mruby-compiler', :core => 'mruby-compiler') + + spec.test_rbfiles = Dir.glob("#{MRUBY_ROOT}/test/t/*.rb") + + clib = "#{build_dir}/mrbtest.c" + mlib = clib.ext(exts.object) + exec = exefile("#{build.build_dir}/bin/mrbtest") + + libmruby = libfile("#{build.build_dir}/lib/libmruby") + libmruby_core = libfile("#{build.build_dir}/lib/libmruby_core") + + mrbtest_lib = libfile("#{build_dir}/mrbtest") + mrbtest_objs = [] + + driver_obj = objfile("#{build_dir}/driver") + driver = "#{spec.dir}/driver.c" + + assert_c = "#{build_dir}/assert.c" + assert_rb = "#{MRUBY_ROOT}/test/assert.rb" + assert_lib = assert_c.ext(exts.object) + mrbtest_objs << assert_lib + + file assert_lib => assert_c + file assert_c => assert_rb do |t| + open(t.name, 'w') do |f| + mrbc.run f, assert_rb, 'mrbtest_assert_irep' + end + end + + gem_table = build.gems.generate_gem_table build + + build.gems.each do |g| + test_rbobj = g.test_rbireps.ext(exts.object) + g.test_objs << test_rbobj + dep_list = build.gems.tsort_dependencies(g.test_dependencies, gem_table).select(&:generate_functions) + + file test_rbobj => g.test_rbireps + file g.test_rbireps => [g.test_rbfiles].flatten do |t| + FileUtils.mkdir_p File.dirname(t.name) + open(t.name, 'w') do |f| + g.print_gem_test_header(f) + test_preload = g.test_preload and [g.dir, MRUBY_ROOT].map {|dir| + File.expand_path(g.test_preload, dir) + }.find {|file| File.exist?(file) } + + f.puts %Q[/*] + f.puts %Q[ * This file contains a test code for #{g.name} gem.] + f.puts %Q[ *] + f.puts %Q[ * IMPORTANT:] + f.puts %Q[ * This file was generated!] + f.puts %Q[ * All manual changes will get lost.] + f.puts %Q[ */] + if test_preload.nil? + f.puts %Q[extern const uint8_t mrbtest_assert_irep[];] + else + g.build.mrbc.run f, test_preload, "gem_test_irep_#{g.funcname}_preload" + end + g.test_rbfiles.flatten.each_with_index do |rbfile, i| + g.build.mrbc.run f, rbfile, "gem_test_irep_#{g.funcname}_#{i}" + end + f.puts %Q[void mrb_#{g.funcname}_gem_test(mrb_state *mrb);] unless g.test_objs.empty? + dep_list.each do |d| + f.puts %Q[void GENERATED_TMP_mrb_#{d.funcname}_gem_init(mrb_state *mrb);] + f.puts %Q[void GENERATED_TMP_mrb_#{d.funcname}_gem_final(mrb_state *mrb);] + end + f.puts %Q[void mrb_init_test_driver(mrb_state *mrb, mrb_bool verbose);] + f.puts %Q[void mrb_t_pass_result(mrb_state *dst, mrb_state *src);] + f.puts %Q[void GENERATED_TMP_mrb_#{g.funcname}_gem_test(mrb_state *mrb) {] + unless g.test_rbfiles.empty? + f.puts %Q[ mrb_state *mrb2;] + unless g.test_args.empty? + f.puts %Q[ mrb_value test_args_hash;] + end + f.puts %Q[ int ai;] + g.test_rbfiles.count.times do |i| + f.puts %Q[ ai = mrb_gc_arena_save(mrb);] + f.puts %Q[ mrb2 = mrb_open_core(mrb_default_allocf, NULL);] + f.puts %Q[ if (mrb2 == NULL) {] + f.puts %Q[ fprintf(stderr, "Invalid mrb_state, exiting \%s", __FUNCTION__);] + f.puts %Q[ exit(EXIT_FAILURE);] + f.puts %Q[ }] + dep_list.each do |d| + f.puts %Q[ GENERATED_TMP_mrb_#{d.funcname}_gem_init(mrb2);] + f.puts %Q[ mrb_state_atexit(mrb2, GENERATED_TMP_mrb_#{d.funcname}_gem_final);] + end + f.puts %Q[ mrb_init_test_driver(mrb2, mrb_test(mrb_gv_get(mrb, mrb_intern_lit(mrb, "$mrbtest_verbose"))));] + if test_preload.nil? + f.puts %Q[ mrb_load_irep(mrb2, mrbtest_assert_irep);] + else + f.puts %Q[ mrb_load_irep(mrb2, gem_test_irep_#{g.funcname}_preload);] + end + f.puts %Q[ if (mrb2->exc) {] + f.puts %Q[ mrb_print_error(mrb2);] + f.puts %Q[ exit(EXIT_FAILURE);] + f.puts %Q[ }] + f.puts %Q[ mrb_const_set(mrb2, mrb_obj_value(mrb2->object_class), mrb_intern_lit(mrb2, "GEMNAME"), mrb_str_new(mrb2, "#{g.name}", #{g.name.length}));] + + unless g.test_args.empty? + f.puts %Q[ test_args_hash = mrb_hash_new_capa(mrb, #{g.test_args.length}); ] + g.test_args.each do |arg_name, arg_value| + escaped_arg_name = arg_name.gsub('\\', '\\\\\\\\').gsub('"', '\"') + escaped_arg_value = arg_value.gsub('\\', '\\\\\\\\').gsub('"', '\"') + f.puts %Q[ mrb_hash_set(mrb2, test_args_hash, mrb_str_new(mrb2, "#{escaped_arg_name.to_s}", #{escaped_arg_name.to_s.length}), mrb_str_new(mrb2, "#{escaped_arg_value.to_s}", #{escaped_arg_value.to_s.length})); ] + end + f.puts %Q[ mrb_const_set(mrb2, mrb_obj_value(mrb2->object_class), mrb_intern_lit(mrb2, "TEST_ARGS"), test_args_hash); ] + end + + f.puts %Q[ mrb_#{g.funcname}_gem_test(mrb2);] if g.custom_test_init? + + f.puts %Q[ mrb_load_irep(mrb2, gem_test_irep_#{g.funcname}_#{i});] + f.puts %Q[ ] + + f.puts %Q[ mrb_t_pass_result(mrb, mrb2);] + f.puts %Q[ mrb_close(mrb2);] + f.puts %Q[ mrb_gc_arena_restore(mrb, ai);] + end + end + f.puts %Q[}] + end + end + end + + build.gems.each do |v| + mrbtest_objs.concat v.test_objs + end + + file mrbtest_lib => mrbtest_objs do |t| + build.archiver.run t.name, t.prerequisites + end + + unless build.build_mrbtest_lib_only? + file exec => [driver_obj, mlib, mrbtest_lib, libmruby_core, libmruby] do |t| + gem_flags = build.gems.map { |g| g.linker.flags } + gem_flags_before_libraries = build.gems.map { |g| g.linker.flags_before_libraries } + gem_flags_after_libraries = build.gems.map { |g| g.linker.flags_after_libraries } + gem_libraries = build.gems.map { |g| g.linker.libraries } + gem_library_paths = build.gems.map { |g| g.linker.library_paths } + build.linker.run t.name, t.prerequisites, gem_libraries, gem_library_paths, gem_flags, gem_flags_before_libraries + end + end + + init = "#{spec.dir}/init_mrbtest.c" + + # store the last gem selection and make the re-build + # of the test gem depending on a change to the gem + # selection + active_gems = "#{build_dir}/active_gems.lst" + FileUtils.mkdir_p File.dirname(active_gems) + open(active_gems, 'w+') do |f| + build.gems.each do |g| + f.puts g.name + end + end + file clib => active_gems + + file mlib => clib + file clib => init do |t| + _pp "GEN", "*.rb", "#{clib.relative_path}" + FileUtils.mkdir_p File.dirname(clib) + open(clib, 'w') do |f| + f.puts %Q[/*] + f.puts %Q[ * This file contains a list of all] + f.puts %Q[ * test functions.] + f.puts %Q[ *] + f.puts %Q[ * IMPORTANT:] + f.puts %Q[ * This file was generated!] + f.puts %Q[ * All manual changes will get lost.] + f.puts %Q[ */] + f.puts %Q[] + f.puts IO.read(init) + build.gems.each do |g| + f.puts %Q[void GENERATED_TMP_mrb_#{g.funcname}_gem_test(mrb_state *mrb);] + end + f.puts %Q[void mrbgemtest_init(mrb_state* mrb) {] + build.gems.each do |g| + f.puts %Q[ GENERATED_TMP_mrb_#{g.funcname}_gem_test(mrb);] + end + f.puts %Q[}] + end + end +end diff --git a/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-time/mrbgem.rake b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-time/mrbgem.rake new file mode 100644 index 00000000..45b2ead7 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-time/mrbgem.rake @@ -0,0 +1,5 @@ +MRuby::Gem::Specification.new('mruby-time') do |spec| + spec.license = 'MIT' + spec.author = 'mruby developers' + spec.summary = 'standard Time class' +end diff --git a/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-time/mrblib/time.rb b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-time/mrblib/time.rb new file mode 100644 index 00000000..df0d8ca8 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-time/mrblib/time.rb @@ -0,0 +1,9 @@ +class Time + def sunday?; wday == 0 end + def monday?; wday == 1 end + def tuesday?; wday == 2 end + def wednesday?; wday == 3 end + def thursday?; wday == 4 end + def friday?; wday == 5 end + def saturday?; wday == 6 end +end diff --git a/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-time/src/time.c b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-time/src/time.c new file mode 100644 index 00000000..5e862483 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-time/src/time.c @@ -0,0 +1,869 @@ +/* +** time.c - Time class +** +** See Copyright Notice in mruby.h +*/ + +#include +#include +#include +#include +#include + +#ifndef DISABLE_STDIO +#include +#else +#include +#endif + +#define NDIV(x,y) (-(-((x)+1)/(y))-1) + +#if defined(_MSC_VER) && _MSC_VER < 1800 +double round(double x) { + return floor(x + 0.5); +} +#endif + +#if !defined(__MINGW64__) && defined(_WIN32) +# define llround(x) round(x) +#endif + +#if defined(__MINGW64__) || defined(__MINGW32__) +# include +#endif + +/** Time class configuration */ + +/* gettimeofday(2) */ +/* C99 does not have gettimeofday that is required to retrieve microseconds */ +/* uncomment following macro on platforms without gettimeofday(2) */ +/* #define NO_GETTIMEOFDAY */ + +/* gmtime(3) */ +/* C99 does not have reentrant gmtime_r() so it might cause troubles under */ +/* multi-threading environment. undef following macro on platforms that */ +/* does not have gmtime_r() and localtime_r(). */ +/* #define NO_GMTIME_R */ + +#ifdef _WIN32 +#if _MSC_VER +/* Win32 platform do not provide gmtime_r/localtime_r; emulate them using gmtime_s/localtime_s */ +#define gmtime_r(tp, tm) ((gmtime_s((tm), (tp)) == 0) ? (tm) : NULL) +#define localtime_r(tp, tm) ((localtime_s((tm), (tp)) == 0) ? (tm) : NULL) +#else +#define NO_GMTIME_R +#endif +#endif + +/* asctime(3) */ +/* mruby usually use its own implementation of struct tm to string conversion */ +/* except when DISABLE_STDIO is set. In that case, it uses asctime() or asctime_r(). */ +/* By default mruby tries to use asctime_r() which is reentrant. */ +/* Undef following macro on platforms that does not have asctime_r(). */ +/* #define NO_ASCTIME_R */ + +/* timegm(3) */ +/* mktime() creates tm structure for localtime; timegm() is for UTC time */ +/* define following macro to use probably faster timegm() on the platform */ +/* #define USE_SYSTEM_TIMEGM */ + +/** end of Time class configuration */ + +#ifndef NO_GETTIMEOFDAY +# ifdef _WIN32 +# define WIN32_LEAN_AND_MEAN /* don't include winsock.h */ +# include +# define gettimeofday my_gettimeofday + +# ifdef _MSC_VER +# define UI64(x) x##ui64 +# else +# define UI64(x) x##ull +# endif + +typedef long suseconds_t; + +# if (!defined __MINGW64__) && (!defined __MINGW32__) +struct timeval { + time_t tv_sec; + suseconds_t tv_usec; +}; +# endif + +static int +gettimeofday(struct timeval *tv, void *tz) +{ + if (tz) { + mrb_assert(0); /* timezone is not supported */ + } + if (tv) { + union { + FILETIME ft; + unsigned __int64 u64; + } t; + GetSystemTimeAsFileTime(&t.ft); /* 100 ns intervals since Windows epoch */ + t.u64 -= UI64(116444736000000000); /* Unix epoch bias */ + t.u64 /= 10; /* to microseconds */ + tv->tv_sec = (time_t)(t.u64 / (1000 * 1000)); + tv->tv_usec = t.u64 % (1000 * 1000); + } + return 0; +} +# else +# include +# endif +#endif +#ifdef NO_GMTIME_R +#define gmtime_r(t,r) gmtime(t) +#define localtime_r(t,r) localtime(t) +#endif + +#ifndef USE_SYSTEM_TIMEGM +#define timegm my_timgm + +static unsigned int +is_leapyear(unsigned int y) +{ + return (y % 4) == 0 && ((y % 100) != 0 || (y % 400) == 0); +} + +static time_t +timegm(struct tm *tm) +{ + static const unsigned int ndays[2][12] = { + {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}, + {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31} + }; + time_t r = 0; + int i; + unsigned int *nday = (unsigned int*) ndays[is_leapyear(tm->tm_year+1900)]; + + for (i = 70; i < tm->tm_year; ++i) + r += is_leapyear(i+1900) ? 366*24*60*60 : 365*24*60*60; + for (i = 0; i < tm->tm_mon; ++i) + r += nday[i] * 24 * 60 * 60; + r += (tm->tm_mday - 1) * 24 * 60 * 60; + r += tm->tm_hour * 60 * 60; + r += tm->tm_min * 60; + r += tm->tm_sec; + return r; +} +#endif + +/* Since we are limited to using ISO C99, this implementation is based +* on time_t. That means the resolution of time is only precise to the +* second level. Also, there are only 2 timezones, namely UTC and LOCAL. +*/ + +enum mrb_timezone { + MRB_TIMEZONE_NONE = 0, + MRB_TIMEZONE_UTC = 1, + MRB_TIMEZONE_LOCAL = 2, + MRB_TIMEZONE_LAST = 3 +}; + +typedef struct mrb_timezone_name { + const char name[8]; + size_t len; +} mrb_timezone_name; + +static const mrb_timezone_name timezone_names[] = { + { "none", sizeof("none") - 1 }, + { "UTC", sizeof("UTC") - 1 }, + { "LOCAL", sizeof("LOCAL") - 1 }, +}; + +#ifndef DISABLE_STDIO +static const char mon_names[12][4] = { + "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec", +}; + +static const char wday_names[7][4] = { + "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", +}; +#endif + +struct mrb_time { + time_t sec; + time_t usec; + enum mrb_timezone timezone; + struct tm datetime; +}; + +static const struct mrb_data_type mrb_time_type = { "Time", mrb_free }; + +/** Updates the datetime of a mrb_time based on it's timezone and +seconds setting. Returns self on success, NULL of failure. */ +static struct mrb_time* +time_update_datetime(mrb_state *mrb, struct mrb_time *self) +{ + struct tm *aid; + + if (self->timezone == MRB_TIMEZONE_UTC) { + aid = gmtime_r(&self->sec, &self->datetime); + } + else { + aid = localtime_r(&self->sec, &self->datetime); + } + if (!aid) { + mrb_raisef(mrb, E_ARGUMENT_ERROR, "%S out of Time range", mrb_float_value(mrb, (mrb_float)self->sec)); + /* not reached */ + return NULL; + } +#ifdef NO_GMTIME_R + self->datetime = *aid; /* copy data */ +#endif + + return self; +} + +static mrb_value +mrb_time_wrap(mrb_state *mrb, struct RClass *tc, struct mrb_time *tm) +{ + return mrb_obj_value(Data_Wrap_Struct(mrb, tc, &mrb_time_type, tm)); +} + +void mrb_check_num_exact(mrb_state *mrb, mrb_float num); + +/* Allocates a mrb_time object and initializes it. */ +static struct mrb_time* +time_alloc(mrb_state *mrb, double sec, double usec, enum mrb_timezone timezone) +{ + struct mrb_time *tm; + time_t tsec = 0; + + mrb_check_num_exact(mrb, (mrb_float)sec); + mrb_check_num_exact(mrb, (mrb_float)usec); + + if (sizeof(time_t) == 4 && (sec > (double)INT32_MAX || (double)INT32_MIN > sec)) { + goto out_of_range; + } + if (sizeof(time_t) == 8 && (sec > (double)INT64_MAX || (double)INT64_MIN > sec)) { + goto out_of_range; + } + tsec = (time_t)sec; + if ((sec > 0 && tsec < 0) || (sec < 0 && (double)tsec > sec)) { + out_of_range: + mrb_raisef(mrb, E_ARGUMENT_ERROR, "%S out of Time range", mrb_float_value(mrb, sec)); + } + tm = (struct mrb_time *)mrb_malloc(mrb, sizeof(struct mrb_time)); + tm->sec = tsec; + tm->usec = (time_t)llround((sec - tm->sec) * 1.0e6 + usec); + if (tm->usec < 0) { + long sec2 = (long)NDIV(usec,1000000); /* negative div */ + tm->usec -= sec2 * 1000000; + tm->sec += sec2; + } + else if (tm->usec >= 1000000) { + long sec2 = (long)(usec / 1000000); + tm->usec -= sec2 * 1000000; + tm->sec += sec2; + } + tm->timezone = timezone; + time_update_datetime(mrb, tm); + + return tm; +} + +static mrb_value +mrb_time_make(mrb_state *mrb, struct RClass *c, double sec, double usec, enum mrb_timezone timezone) +{ + return mrb_time_wrap(mrb, c, time_alloc(mrb, sec, usec, timezone)); +} + +static struct mrb_time* +current_mrb_time(mrb_state *mrb) +{ + struct mrb_time *tm; + + tm = (struct mrb_time *)mrb_malloc(mrb, sizeof(*tm)); +#if defined(TIME_UTC) + { + struct timespec ts; + if (timespec_get(&ts, TIME_UTC) == 0) { + mrb_free(mrb, tm); + mrb_raise(mrb, E_RUNTIME_ERROR, "timespec_get() failed for unknown reasons"); + } + tm->sec = ts.tv_sec; + tm->usec = ts.tv_nsec / 1000; + } +#elif defined(NO_GETTIMEOFDAY) + { + static time_t last_sec = 0, last_usec = 0; + + tm->sec = time(NULL); + if (tm->sec != last_sec) { + last_sec = tm->sec; + last_usec = 0; + } + else { + /* add 1 usec to differentiate two times */ + last_usec += 1; + } + tm->usec = last_usec; + } +#else + { + struct timeval tv; + + gettimeofday(&tv, NULL); + tm->sec = tv.tv_sec; + tm->usec = tv.tv_usec; + } +#endif + tm->timezone = MRB_TIMEZONE_LOCAL; + time_update_datetime(mrb, tm); + + return tm; +} + +/* Allocates a new Time object with given millis value. */ +static mrb_value +mrb_time_now(mrb_state *mrb, mrb_value self) +{ + return mrb_time_wrap(mrb, mrb_class_ptr(self), current_mrb_time(mrb)); +} + +/* 15.2.19.6.1 */ +/* Creates an instance of time at the given time in seconds, etc. */ +static mrb_value +mrb_time_at(mrb_state *mrb, mrb_value self) +{ + mrb_float f, f2 = 0; + + mrb_get_args(mrb, "f|f", &f, &f2); + return mrb_time_make(mrb, mrb_class_ptr(self), f, f2, MRB_TIMEZONE_LOCAL); +} + +static struct mrb_time* +time_mktime(mrb_state *mrb, mrb_int ayear, mrb_int amonth, mrb_int aday, + mrb_int ahour, mrb_int amin, mrb_int asec, mrb_int ausec, + enum mrb_timezone timezone) +{ + time_t nowsecs; + struct tm nowtime = { 0 }; + + nowtime.tm_year = (int)ayear - 1900; + nowtime.tm_mon = (int)amonth - 1; + nowtime.tm_mday = (int)aday; + nowtime.tm_hour = (int)ahour; + nowtime.tm_min = (int)amin; + nowtime.tm_sec = (int)asec; + nowtime.tm_isdst = -1; + + if (nowtime.tm_mon < 0 || nowtime.tm_mon > 11 + || nowtime.tm_mday < 1 || nowtime.tm_mday > 31 + || nowtime.tm_hour < 0 || nowtime.tm_hour > 24 + || (nowtime.tm_hour == 24 && (nowtime.tm_min > 0 || nowtime.tm_sec > 0)) + || nowtime.tm_min < 0 || nowtime.tm_min > 59 + || nowtime.tm_sec < 0 || nowtime.tm_sec > 60) + mrb_raise(mrb, E_RUNTIME_ERROR, "argument out of range"); + + if (timezone == MRB_TIMEZONE_UTC) { + nowsecs = timegm(&nowtime); + } + else { + nowsecs = mktime(&nowtime); + } + if (nowsecs == (time_t)-1) { + mrb_raise(mrb, E_ARGUMENT_ERROR, "Not a valid time."); + } + + return time_alloc(mrb, (double)nowsecs, ausec, timezone); +} + +/* 15.2.19.6.2 */ +/* Creates an instance of time at the given time in UTC. */ +static mrb_value +mrb_time_gm(mrb_state *mrb, mrb_value self) +{ + mrb_int ayear = 0, amonth = 1, aday = 1, ahour = 0, amin = 0, asec = 0, ausec = 0; + + mrb_get_args(mrb, "i|iiiiii", + &ayear, &amonth, &aday, &ahour, &amin, &asec, &ausec); + return mrb_time_wrap(mrb, mrb_class_ptr(self), + time_mktime(mrb, ayear, amonth, aday, ahour, amin, asec, ausec, MRB_TIMEZONE_UTC)); +} + + +/* 15.2.19.6.3 */ +/* Creates an instance of time at the given time in local time zone. */ +static mrb_value +mrb_time_local(mrb_state *mrb, mrb_value self) +{ + mrb_int ayear = 0, amonth = 1, aday = 1, ahour = 0, amin = 0, asec = 0, ausec = 0; + + mrb_get_args(mrb, "i|iiiiii", + &ayear, &amonth, &aday, &ahour, &amin, &asec, &ausec); + return mrb_time_wrap(mrb, mrb_class_ptr(self), + time_mktime(mrb, ayear, amonth, aday, ahour, amin, asec, ausec, MRB_TIMEZONE_LOCAL)); +} + +static struct mrb_time* +time_get_ptr(mrb_state *mrb, mrb_value time) +{ + struct mrb_time *tm; + + tm = DATA_GET_PTR(mrb, time, &mrb_time_type, struct mrb_time); + if (!tm) { + mrb_raise(mrb, E_ARGUMENT_ERROR, "uninitialized time"); + } + return tm; +} + +static mrb_value +mrb_time_eq(mrb_state *mrb, mrb_value self) +{ + mrb_value other; + struct mrb_time *tm1, *tm2; + mrb_bool eq_p; + + mrb_get_args(mrb, "o", &other); + tm1 = DATA_GET_PTR(mrb, self, &mrb_time_type, struct mrb_time); + tm2 = DATA_CHECK_GET_PTR(mrb, other, &mrb_time_type, struct mrb_time); + eq_p = tm1 && tm2 && tm1->sec == tm2->sec && tm1->usec == tm2->usec; + + return mrb_bool_value(eq_p); +} + +static mrb_value +mrb_time_cmp(mrb_state *mrb, mrb_value self) +{ + mrb_value other; + struct mrb_time *tm1, *tm2; + + mrb_get_args(mrb, "o", &other); + tm1 = DATA_GET_PTR(mrb, self, &mrb_time_type, struct mrb_time); + tm2 = DATA_CHECK_GET_PTR(mrb, other, &mrb_time_type, struct mrb_time); + if (!tm1 || !tm2) return mrb_nil_value(); + if (tm1->sec > tm2->sec) { + return mrb_fixnum_value(1); + } + else if (tm1->sec < tm2->sec) { + return mrb_fixnum_value(-1); + } + /* tm1->sec == tm2->sec */ + if (tm1->usec > tm2->usec) { + return mrb_fixnum_value(1); + } + else if (tm1->usec < tm2->usec) { + return mrb_fixnum_value(-1); + } + return mrb_fixnum_value(0); +} + +static mrb_value +mrb_time_plus(mrb_state *mrb, mrb_value self) +{ + mrb_float f; + struct mrb_time *tm; + + mrb_get_args(mrb, "f", &f); + tm = time_get_ptr(mrb, self); + return mrb_time_make(mrb, mrb_obj_class(mrb, self), (double)tm->sec+f, (double)tm->usec, tm->timezone); +} + +static mrb_value +mrb_time_minus(mrb_state *mrb, mrb_value self) +{ + mrb_float f; + mrb_value other; + struct mrb_time *tm, *tm2; + + mrb_get_args(mrb, "o", &other); + tm = time_get_ptr(mrb, self); + tm2 = DATA_CHECK_GET_PTR(mrb, other, &mrb_time_type, struct mrb_time); + if (tm2) { + f = (mrb_float)(tm->sec - tm2->sec) + + (mrb_float)(tm->usec - tm2->usec) / 1.0e6; + return mrb_float_value(mrb, f); + } + else { + mrb_get_args(mrb, "f", &f); + return mrb_time_make(mrb, mrb_obj_class(mrb, self), (double)tm->sec-f, (double)tm->usec, tm->timezone); + } +} + +/* 15.2.19.7.30 */ +/* Returns week day number of time. */ +static mrb_value +mrb_time_wday(mrb_state *mrb, mrb_value self) +{ + struct mrb_time *tm; + + tm = time_get_ptr(mrb, self); + return mrb_fixnum_value(tm->datetime.tm_wday); +} + +/* 15.2.19.7.31 */ +/* Returns year day number of time. */ +static mrb_value +mrb_time_yday(mrb_state *mrb, mrb_value self) +{ + struct mrb_time *tm; + + tm = time_get_ptr(mrb, self); + return mrb_fixnum_value(tm->datetime.tm_yday + 1); +} + +/* 15.2.19.7.32 */ +/* Returns year of time. */ +static mrb_value +mrb_time_year(mrb_state *mrb, mrb_value self) +{ + struct mrb_time *tm; + + tm = time_get_ptr(mrb, self); + return mrb_fixnum_value(tm->datetime.tm_year + 1900); +} + +/* 15.2.19.7.33 */ +/* Returns name of time's timezone. */ +static mrb_value +mrb_time_zone(mrb_state *mrb, mrb_value self) +{ + struct mrb_time *tm; + + tm = time_get_ptr(mrb, self); + if (tm->timezone <= MRB_TIMEZONE_NONE) return mrb_nil_value(); + if (tm->timezone >= MRB_TIMEZONE_LAST) return mrb_nil_value(); + return mrb_str_new_static(mrb, + timezone_names[tm->timezone].name, + timezone_names[tm->timezone].len); +} + +/* 15.2.19.7.4 */ +/* Returns a string that describes the time. */ +static mrb_value +mrb_time_asctime(mrb_state *mrb, mrb_value self) +{ + struct mrb_time *tm = time_get_ptr(mrb, self); + struct tm *d = &tm->datetime; + int len; + +#if defined(DISABLE_STDIO) + char *s; +# ifdef NO_ASCTIME_R + s = asctime(d); +# else + char buf[32]; + s = asctime_r(d, buf); +# endif + len = strlen(s)-1; /* truncate the last newline */ +#else + char buf[256]; + + len = snprintf(buf, sizeof(buf), "%s %s %02d %02d:%02d:%02d %s%d", + wday_names[d->tm_wday], mon_names[d->tm_mon], d->tm_mday, + d->tm_hour, d->tm_min, d->tm_sec, + tm->timezone == MRB_TIMEZONE_UTC ? "UTC " : "", + d->tm_year + 1900); +#endif + return mrb_str_new(mrb, buf, len); +} + +/* 15.2.19.7.6 */ +/* Returns the day in the month of the time. */ +static mrb_value +mrb_time_day(mrb_state *mrb, mrb_value self) +{ + struct mrb_time *tm; + + tm = time_get_ptr(mrb, self); + return mrb_fixnum_value(tm->datetime.tm_mday); +} + + +/* 15.2.19.7.7 */ +/* Returns true if daylight saving was applied for this time. */ +static mrb_value +mrb_time_dst_p(mrb_state *mrb, mrb_value self) +{ + struct mrb_time *tm; + + tm = time_get_ptr(mrb, self); + return mrb_bool_value(tm->datetime.tm_isdst); +} + +/* 15.2.19.7.8 */ +/* 15.2.19.7.10 */ +/* Returns the Time object of the UTC(GMT) timezone. */ +static mrb_value +mrb_time_getutc(mrb_state *mrb, mrb_value self) +{ + struct mrb_time *tm, *tm2; + + tm = time_get_ptr(mrb, self); + tm2 = (struct mrb_time *)mrb_malloc(mrb, sizeof(*tm)); + *tm2 = *tm; + tm2->timezone = MRB_TIMEZONE_UTC; + time_update_datetime(mrb, tm2); + return mrb_time_wrap(mrb, mrb_obj_class(mrb, self), tm2); +} + +/* 15.2.19.7.9 */ +/* Returns the Time object of the LOCAL timezone. */ +static mrb_value +mrb_time_getlocal(mrb_state *mrb, mrb_value self) +{ + struct mrb_time *tm, *tm2; + + tm = time_get_ptr(mrb, self); + tm2 = (struct mrb_time *)mrb_malloc(mrb, sizeof(*tm)); + *tm2 = *tm; + tm2->timezone = MRB_TIMEZONE_LOCAL; + time_update_datetime(mrb, tm2); + return mrb_time_wrap(mrb, mrb_obj_class(mrb, self), tm2); +} + +/* 15.2.19.7.15 */ +/* Returns hour of time. */ +static mrb_value +mrb_time_hour(mrb_state *mrb, mrb_value self) +{ + struct mrb_time *tm; + + tm = time_get_ptr(mrb, self); + return mrb_fixnum_value(tm->datetime.tm_hour); +} + +/* 15.2.19.7.16 */ +/* Initializes a time by setting the amount of milliseconds since the epoch.*/ +static mrb_value +mrb_time_initialize(mrb_state *mrb, mrb_value self) +{ + mrb_int ayear = 0, amonth = 1, aday = 1, ahour = 0, + amin = 0, asec = 0, ausec = 0; + int n; + struct mrb_time *tm; + + n = mrb_get_args(mrb, "|iiiiiii", + &ayear, &amonth, &aday, &ahour, &amin, &asec, &ausec); + tm = (struct mrb_time*)DATA_PTR(self); + if (tm) { + mrb_free(mrb, tm); + } + mrb_data_init(self, NULL, &mrb_time_type); + + if (n == 0) { + tm = current_mrb_time(mrb); + } + else { + tm = time_mktime(mrb, ayear, amonth, aday, ahour, amin, asec, ausec, MRB_TIMEZONE_LOCAL); + } + mrb_data_init(self, tm, &mrb_time_type); + return self; +} + +/* 15.2.19.7.17(x) */ +/* Initializes a copy of this time object. */ +static mrb_value +mrb_time_initialize_copy(mrb_state *mrb, mrb_value copy) +{ + mrb_value src; + struct mrb_time *t1, *t2; + + mrb_get_args(mrb, "o", &src); + if (mrb_obj_equal(mrb, copy, src)) return copy; + if (!mrb_obj_is_instance_of(mrb, src, mrb_obj_class(mrb, copy))) { + mrb_raise(mrb, E_TYPE_ERROR, "wrong argument class"); + } + t1 = (struct mrb_time *)DATA_PTR(copy); + t2 = (struct mrb_time *)DATA_PTR(src); + if (!t2) { + mrb_raise(mrb, E_ARGUMENT_ERROR, "uninitialized time"); + } + if (!t1) { + t1 = (struct mrb_time *)mrb_malloc(mrb, sizeof(struct mrb_time)); + mrb_data_init(copy, t1, &mrb_time_type); + } + *t1 = *t2; + return copy; +} + +/* 15.2.19.7.18 */ +/* Sets the timezone attribute of the Time object to LOCAL. */ +static mrb_value +mrb_time_localtime(mrb_state *mrb, mrb_value self) +{ + struct mrb_time *tm; + + tm = time_get_ptr(mrb, self); + tm->timezone = MRB_TIMEZONE_LOCAL; + time_update_datetime(mrb, tm); + return self; +} + +/* 15.2.19.7.19 */ +/* Returns day of month of time. */ +static mrb_value +mrb_time_mday(mrb_state *mrb, mrb_value self) +{ + struct mrb_time *tm; + + tm = time_get_ptr(mrb, self); + return mrb_fixnum_value(tm->datetime.tm_mday); +} + +/* 15.2.19.7.20 */ +/* Returns minutes of time. */ +static mrb_value +mrb_time_min(mrb_state *mrb, mrb_value self) +{ + struct mrb_time *tm; + + tm = time_get_ptr(mrb, self); + return mrb_fixnum_value(tm->datetime.tm_min); +} + +/* 15.2.19.7.21 and 15.2.19.7.22 */ +/* Returns month of time. */ +static mrb_value +mrb_time_mon(mrb_state *mrb, mrb_value self) +{ + struct mrb_time *tm; + + tm = time_get_ptr(mrb, self); + return mrb_fixnum_value(tm->datetime.tm_mon + 1); +} + +/* 15.2.19.7.23 */ +/* Returns seconds in minute of time. */ +static mrb_value +mrb_time_sec(mrb_state *mrb, mrb_value self) +{ + struct mrb_time *tm; + + tm = time_get_ptr(mrb, self); + return mrb_fixnum_value(tm->datetime.tm_sec); +} + + +/* 15.2.19.7.24 */ +/* Returns a Float with the time since the epoch in seconds. */ +static mrb_value +mrb_time_to_f(mrb_state *mrb, mrb_value self) +{ + struct mrb_time *tm; + + tm = time_get_ptr(mrb, self); + return mrb_float_value(mrb, (mrb_float)tm->sec + (mrb_float)tm->usec/1.0e6); +} + +/* 15.2.19.7.25 */ +/* Returns a Fixnum with the time since the epoch in seconds. */ +static mrb_value +mrb_time_to_i(mrb_state *mrb, mrb_value self) +{ + struct mrb_time *tm; + + tm = time_get_ptr(mrb, self); + if (tm->sec > MRB_INT_MAX || tm->sec < MRB_INT_MIN) { + return mrb_float_value(mrb, (mrb_float)tm->sec); + } + return mrb_fixnum_value((mrb_int)tm->sec); +} + +/* 15.2.19.7.26 */ +/* Returns a Float with the time since the epoch in microseconds. */ +static mrb_value +mrb_time_usec(mrb_state *mrb, mrb_value self) +{ + struct mrb_time *tm; + + tm = time_get_ptr(mrb, self); + if (tm->usec > MRB_INT_MAX || tm->usec < MRB_INT_MIN) { + return mrb_float_value(mrb, (mrb_float)tm->usec); + } + return mrb_fixnum_value((mrb_int)tm->usec); +} + +/* 15.2.19.7.27 */ +/* Sets the timezone attribute of the Time object to UTC. */ +static mrb_value +mrb_time_utc(mrb_state *mrb, mrb_value self) +{ + struct mrb_time *tm; + + tm = time_get_ptr(mrb, self); + tm->timezone = MRB_TIMEZONE_UTC; + time_update_datetime(mrb, tm); + return self; +} + +/* 15.2.19.7.28 */ +/* Returns true if this time is in the UTC timezone false if not. */ +static mrb_value +mrb_time_utc_p(mrb_state *mrb, mrb_value self) +{ + struct mrb_time *tm; + + tm = time_get_ptr(mrb, self); + return mrb_bool_value(tm->timezone == MRB_TIMEZONE_UTC); +} + + +void +mrb_mruby_time_gem_init(mrb_state* mrb) +{ + struct RClass *tc; + /* ISO 15.2.19.2 */ + tc = mrb_define_class(mrb, "Time", mrb->object_class); + MRB_SET_INSTANCE_TT(tc, MRB_TT_DATA); + mrb_include_module(mrb, tc, mrb_module_get(mrb, "Comparable")); + mrb_define_class_method(mrb, tc, "at", mrb_time_at, MRB_ARGS_ARG(1, 1)); /* 15.2.19.6.1 */ + mrb_define_class_method(mrb, tc, "gm", mrb_time_gm, MRB_ARGS_ARG(1,6)); /* 15.2.19.6.2 */ + mrb_define_class_method(mrb, tc, "local", mrb_time_local, MRB_ARGS_ARG(1,6)); /* 15.2.19.6.3 */ + mrb_define_class_method(mrb, tc, "mktime", mrb_time_local, MRB_ARGS_ARG(1,6));/* 15.2.19.6.4 */ + mrb_define_class_method(mrb, tc, "now", mrb_time_now, MRB_ARGS_NONE()); /* 15.2.19.6.5 */ + mrb_define_class_method(mrb, tc, "utc", mrb_time_gm, MRB_ARGS_ARG(1,6)); /* 15.2.19.6.6 */ + + mrb_define_method(mrb, tc, "==" , mrb_time_eq , MRB_ARGS_REQ(1)); + mrb_define_method(mrb, tc, "<=>" , mrb_time_cmp , MRB_ARGS_REQ(1)); /* 15.2.19.7.1 */ + mrb_define_method(mrb, tc, "+" , mrb_time_plus , MRB_ARGS_REQ(1)); /* 15.2.19.7.2 */ + mrb_define_method(mrb, tc, "-" , mrb_time_minus , MRB_ARGS_REQ(1)); /* 15.2.19.7.3 */ + mrb_define_method(mrb, tc, "to_s" , mrb_time_asctime, MRB_ARGS_NONE()); + mrb_define_method(mrb, tc, "inspect", mrb_time_asctime, MRB_ARGS_NONE()); + mrb_define_method(mrb, tc, "asctime", mrb_time_asctime, MRB_ARGS_NONE()); /* 15.2.19.7.4 */ + mrb_define_method(mrb, tc, "ctime" , mrb_time_asctime, MRB_ARGS_NONE()); /* 15.2.19.7.5 */ + mrb_define_method(mrb, tc, "day" , mrb_time_day , MRB_ARGS_NONE()); /* 15.2.19.7.6 */ + mrb_define_method(mrb, tc, "dst?" , mrb_time_dst_p , MRB_ARGS_NONE()); /* 15.2.19.7.7 */ + mrb_define_method(mrb, tc, "getgm" , mrb_time_getutc , MRB_ARGS_NONE()); /* 15.2.19.7.8 */ + mrb_define_method(mrb, tc, "getlocal",mrb_time_getlocal,MRB_ARGS_NONE()); /* 15.2.19.7.9 */ + mrb_define_method(mrb, tc, "getutc" , mrb_time_getutc , MRB_ARGS_NONE()); /* 15.2.19.7.10 */ + mrb_define_method(mrb, tc, "gmt?" , mrb_time_utc_p , MRB_ARGS_NONE()); /* 15.2.19.7.11 */ + mrb_define_method(mrb, tc, "gmtime" , mrb_time_utc , MRB_ARGS_NONE()); /* 15.2.19.7.13 */ + mrb_define_method(mrb, tc, "hour" , mrb_time_hour, MRB_ARGS_NONE()); /* 15.2.19.7.15 */ + mrb_define_method(mrb, tc, "localtime", mrb_time_localtime, MRB_ARGS_NONE()); /* 15.2.19.7.18 */ + mrb_define_method(mrb, tc, "mday" , mrb_time_mday, MRB_ARGS_NONE()); /* 15.2.19.7.19 */ + mrb_define_method(mrb, tc, "min" , mrb_time_min, MRB_ARGS_NONE()); /* 15.2.19.7.20 */ + + mrb_define_method(mrb, tc, "mon" , mrb_time_mon, MRB_ARGS_NONE()); /* 15.2.19.7.21 */ + mrb_define_method(mrb, tc, "month", mrb_time_mon, MRB_ARGS_NONE()); /* 15.2.19.7.22 */ + + mrb_define_method(mrb, tc, "sec" , mrb_time_sec, MRB_ARGS_NONE()); /* 15.2.19.7.23 */ + mrb_define_method(mrb, tc, "to_i", mrb_time_to_i, MRB_ARGS_NONE()); /* 15.2.19.7.25 */ + mrb_define_method(mrb, tc, "to_f", mrb_time_to_f, MRB_ARGS_NONE()); /* 15.2.19.7.24 */ + mrb_define_method(mrb, tc, "usec", mrb_time_usec, MRB_ARGS_NONE()); /* 15.2.19.7.26 */ + mrb_define_method(mrb, tc, "utc" , mrb_time_utc, MRB_ARGS_NONE()); /* 15.2.19.7.27 */ + mrb_define_method(mrb, tc, "utc?", mrb_time_utc_p,MRB_ARGS_NONE()); /* 15.2.19.7.28 */ + mrb_define_method(mrb, tc, "wday", mrb_time_wday, MRB_ARGS_NONE()); /* 15.2.19.7.30 */ + mrb_define_method(mrb, tc, "yday", mrb_time_yday, MRB_ARGS_NONE()); /* 15.2.19.7.31 */ + mrb_define_method(mrb, tc, "year", mrb_time_year, MRB_ARGS_NONE()); /* 15.2.19.7.32 */ + mrb_define_method(mrb, tc, "zone", mrb_time_zone, MRB_ARGS_NONE()); /* 15.2.19.7.33 */ + + mrb_define_method(mrb, tc, "initialize", mrb_time_initialize, MRB_ARGS_REQ(1)); /* 15.2.19.7.16 */ + mrb_define_method(mrb, tc, "initialize_copy", mrb_time_initialize_copy, MRB_ARGS_REQ(1)); /* 15.2.19.7.17 */ + + /* + methods not available: + gmt_offset(15.2.19.7.12) + gmtoff(15.2.19.7.14) + utc_offset(15.2.19.7.29) + */ +} + +void +mrb_mruby_time_gem_final(mrb_state* mrb) +{ +} diff --git a/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-time/test/time.rb b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-time/test/time.rb new file mode 100644 index 00000000..52b93117 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-time/test/time.rb @@ -0,0 +1,228 @@ +## +# Time ISO Test + +assert('Time.new', '15.2.3.3.3') do + Time.new.class == Time +end + +assert('Time', '15.2.19') do + Time.class == Class +end + +assert('Time.at', '15.2.19.6.1') do + assert_kind_of(Time, Time.at(1300000000.0)) + + assert_raise(FloatDomainError) { Time.at(Float::NAN) } + assert_raise(FloatDomainError) { Time.at(Float::INFINITY) } + assert_raise(FloatDomainError) { Time.at(-Float::INFINITY) } + assert_raise(FloatDomainError) { Time.at(0, Float::NAN) } + assert_raise(FloatDomainError) { Time.at(0, Float::INFINITY) } + assert_raise(FloatDomainError) { Time.at(0, -Float::INFINITY) } +end + +assert('Time.gm', '15.2.19.6.2') do + Time.gm(2012, 12, 23) +end + +assert('Time.local', '15.2.19.6.3') do + Time.local(2012, 12, 23) +end + +assert('Time.mktime', '15.2.19.6.4') do + Time.mktime(2012, 12, 23) +end + +assert('Time.now', '15.2.19.6.5') do + Time.now.class == Time +end + +assert('Time.utc', '15.2.19.6.6') do + Time.utc(2012, 12, 23) +end + +assert('Time#+', '15.2.19.7.1') do + t1 = Time.at(1300000000.0) + t2 = t1.+(60) + + assert_equal(t2.utc.asctime, "Sun Mar 13 07:07:40 UTC 2011") + + assert_raise(FloatDomainError) { Time.at(0) + Float::NAN } + assert_raise(FloatDomainError) { Time.at(0) + Float::INFINITY } + assert_raise(FloatDomainError) { Time.at(0) + -Float::INFINITY } +end + +assert('Time#-', '15.2.19.7.2') do + t1 = Time.at(1300000000.0) + t2 = t1.-(60) + + assert_equal(t2.utc.asctime, "Sun Mar 13 07:05:40 UTC 2011") + + assert_raise(FloatDomainError) { Time.at(0) - Float::NAN } + assert_raise(FloatDomainError) { Time.at(0) - Float::INFINITY } + assert_raise(FloatDomainError) { Time.at(0) - -Float::INFINITY } +end + +assert('Time#<=>', '15.2.19.7.3') do + t1 = Time.at(1300000000.0) + t2 = Time.at(1400000000.0) + t3 = Time.at(1500000000.0) + + t2.<=>(t1) == 1 and + t2.<=>(t2) == 0 and + t2.<=>(t3) == -1 and + t2.<=>(nil) == nil +end + +assert('Time#asctime', '15.2.19.7.4') do + Time.at(1300000000.0).utc.asctime == "Sun Mar 13 07:06:40 UTC 2011" +end + +assert('Time#ctime', '15.2.19.7.5') do + Time.at(1300000000.0).utc.ctime == "Sun Mar 13 07:06:40 UTC 2011" +end + +assert('Time#day', '15.2.19.7.6') do + Time.gm(2012, 12, 23).day == 23 +end + +assert('Time#dst?', '15.2.19.7.7') do + not Time.gm(2012, 12, 23).utc.dst? +end + +assert('Time#getgm', '15.2.19.7.8') do + Time.at(1300000000.0).getgm.asctime == "Sun Mar 13 07:06:40 UTC 2011" +end + +assert('Time#getlocal', '15.2.19.7.9') do + t1 = Time.at(1300000000.0) + t2 = Time.at(1300000000.0) + t3 = t1.getlocal + + t1 == t3 and t3 == t2.getlocal +end + +assert('Time#getutc', '15.2.19.7.10') do + Time.at(1300000000.0).getutc.asctime == "Sun Mar 13 07:06:40 UTC 2011" +end + +assert('Time#gmt?', '15.2.19.7.11') do + Time.at(1300000000.0).utc.gmt? +end + +# ATM not implemented +# assert('Time#gmt_offset', '15.2.19.7.12') do + +assert('Time#gmtime', '15.2.19.7.13') do + Time.at(1300000000.0).gmtime +end + +# ATM not implemented +# assert('Time#gmtoff', '15.2.19.7.14') do + +assert('Time#hour', '15.2.19.7.15') do + Time.gm(2012, 12, 23, 7, 6).hour == 7 +end + +# ATM doesn't really work +# assert('Time#initialize', '15.2.19.7.16') do + +assert('Time#initialize_copy', '15.2.19.7.17') do + time_tmp_2 = Time.at(7.0e6) + time_tmp_2.clone == time_tmp_2 +end + +assert('Time#localtime', '15.2.19.7.18') do + t1 = Time.at(1300000000.0) + t2 = Time.at(1300000000.0) + + t1.localtime + t1 == t2.getlocal +end + +assert('Time#mday', '15.2.19.7.19') do + Time.gm(2012, 12, 23).mday == 23 +end + +assert('Time#min', '15.2.19.7.20') do + Time.gm(2012, 12, 23, 7, 6).min == 6 +end + +assert('Time#mon', '15.2.19.7.21') do + Time.gm(2012, 12, 23).mon == 12 +end + +assert('Time#month', '15.2.19.7.22') do + Time.gm(2012, 12, 23).month == 12 +end + +assert('Times#sec', '15.2.19.7.23') do + Time.gm(2012, 12, 23, 7, 6, 40).sec == 40 +end + +assert('Time#to_f', '15.2.19.7.24') do + Time.at(1300000000.0).to_f == 1300000000.0 +end + +assert('Time#to_i', '15.2.19.7.25') do + Time.at(1300000000.0).to_i == 1300000000 +end + +assert('Time#usec', '15.2.19.7.26') do + Time.at(1300000000.0).usec == 0 +end + +assert('Time#utc', '15.2.19.7.27') do + Time.at(1300000000.0).utc +end + +assert('Time#utc?', '15.2.19.7.28') do + Time.at(1300000000.0).utc.utc? +end + +# ATM not implemented +# assert('Time#utc_offset', '15.2.19.7.29') do + +assert('Time#wday', '15.2.19.7.30') do + Time.gm(2012, 12, 23).wday == 0 +end + +assert('Time#yday', '15.2.19.7.31') do + Time.gm(2012, 12, 23).yday == 358 +end + +assert('Time#year', '15.2.19.7.32') do + Time.gm(2012, 12, 23).year == 2012 +end + +assert('Time#zone', '15.2.19.7.33') do + Time.at(1300000000.0).utc.zone == 'UTC' +end + +# Not ISO specified + +assert('Time#to_s') do + Time.at(1300000000.0).utc.to_s == "Sun Mar 13 07:06:40 UTC 2011" +end + +assert('Time#inspect') do + Time.at(1300000000.0).utc.inspect == "Sun Mar 13 07:06:40 UTC 2011" +end + +assert('day of week methods') do + t = Time.gm(2012, 12, 24) + assert_false t.sunday? + assert_true t.monday? + assert_false t.tuesday? + assert_false t.wednesday? + assert_false t.thursday? + assert_false t.friday? + assert_false t.saturday? +end + +assert('2000 times 500us make a second') do + t = Time.utc 2015 + 2000.times do + t += 0.0005 + end + t.usec == 0 +end diff --git a/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-toplevel-ext/mrbgem.rake b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-toplevel-ext/mrbgem.rake new file mode 100644 index 00000000..ce77e0bc --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-toplevel-ext/mrbgem.rake @@ -0,0 +1,5 @@ +MRuby::Gem::Specification.new('mruby-toplevel-ext') do |spec| + spec.license = 'MIT' + spec.author = 'mruby developers' + spec.summary = 'toplevel object (main) methods extension' +end diff --git a/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-toplevel-ext/mrblib/toplevel.rb b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-toplevel-ext/mrblib/toplevel.rb new file mode 100644 index 00000000..77456239 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-toplevel-ext/mrblib/toplevel.rb @@ -0,0 +1,11 @@ + +def self.include (*modules) + self.class.include(*modules) +end + +def self.private(*methods) +end +def self.protected(*methods) +end +def self.public(*methods) +end diff --git a/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-toplevel-ext/test/toplevel.rb b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-toplevel-ext/test/toplevel.rb new file mode 100644 index 00000000..aebdd8b4 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-toplevel-ext/test/toplevel.rb @@ -0,0 +1,24 @@ +## +# Toplevel Self(Ext) Test + +assert('Toplevel#include') do + module ToplevelTestModule1 + def method_foo + :foo + end + + CONST_BAR = :bar + end + + module ToplevelTestModule2 + CONST_BAR = :bar2 + end + + self.include ToplevelTestModule2, ToplevelTestModule1 + + assert_true self.class.included_modules.include?( ToplevelTestModule1 ) + assert_true self.class.included_modules.include?( ToplevelTestModule2 ) + assert_equal :foo, method_foo + assert_equal :bar2, CONST_BAR +end + diff --git a/web/server/h2o/libh2o/deps/mruby/mrblib/00class.rb b/web/server/h2o/libh2o/deps/mruby/mrblib/00class.rb new file mode 100644 index 00000000..1a2d833c --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/mrblib/00class.rb @@ -0,0 +1,28 @@ +class Module + # 15.2.2.4.12 + def attr_accessor(*names) + attr_reader(*names) + attr_writer(*names) + end + # 15.2.2.4.11 + def attr(name) + attr_reader(name) + end + + # 15.2.2.4.27 + def include(*args) + args.reverse.each do |m| + m.append_features(self) + m.included(self) + end + self + end + + def prepend(*args) + args.reverse.each do |m| + m.prepend_features(self) + m.prepended(self) + end + self + end +end diff --git a/web/server/h2o/libh2o/deps/mruby/mrblib/10error.rb b/web/server/h2o/libh2o/deps/mruby/mrblib/10error.rb new file mode 100644 index 00000000..22a8d1ad --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/mrblib/10error.rb @@ -0,0 +1,56 @@ +# ISO 15.2.24 +class ArgumentError < StandardError +end + +# ISO 15.2.25 says "LocalJumpError < StandardError" +class LocalJumpError < ScriptError +end + +# ISO 15.2.26 +class RangeError < StandardError +end + +class FloatDomainError < RangeError +end + +# ISO 15.2.26 +class RegexpError < StandardError +end + +# ISO 15.2.29 +class TypeError < StandardError +end + +# ISO 15.2.31 +class NameError < StandardError + attr_accessor :name + + def initialize(message=nil, name=nil) + @name = name + super(message) + end +end + +# ISO 15.2.32 +class NoMethodError < NameError + attr_reader :args + + def initialize(message=nil, name=nil, args=nil) + @args = args + super message, name + end +end + +# ISO 15.2.33 +class IndexError < StandardError +end + +class KeyError < IndexError +end + +class NotImplementedError < ScriptError +end + +class StopIteration < IndexError + attr_accessor :result +end diff --git a/web/server/h2o/libh2o/deps/mruby/mrblib/array.rb b/web/server/h2o/libh2o/deps/mruby/mrblib/array.rb new file mode 100644 index 00000000..a75ed622 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/mrblib/array.rb @@ -0,0 +1,243 @@ +# coding: utf-8 +## +# Array +# +# ISO 15.2.12 +class Array + + ## + # Calls the given block for each element of +self+ + # and pass the respective element. + # + # ISO 15.2.12.5.10 + def each(&block) + return to_enum :each unless block + + idx = 0 + while idx < length + block.call(self[idx]) + idx += 1 + end + self + end + + ## + # Calls the given block for each element of +self+ + # and pass the index of the respective element. + # + # ISO 15.2.12.5.11 + def each_index(&block) + return to_enum :each_index unless block + + idx = 0 + while idx < length + block.call(idx) + idx += 1 + end + self + end + + ## + # Calls the given block for each element of +self+ + # and pass the respective element. Each element will + # be replaced by the resulting values. + # + # ISO 15.2.12.5.7 + def collect!(&block) + return to_enum :collect! unless block + + idx = 0 + len = size + while idx < len + self[idx] = block.call self[idx] + idx += 1 + end + self + end + + ## + # Alias for collect! + # + # ISO 15.2.12.5.20 + alias map! collect! + + ## + # Private method for Array creation. + # + # ISO 15.2.12.5.15 + def initialize(size=0, obj=nil, &block) + raise TypeError, "expected Integer for 1st argument" unless size.kind_of? Integer + raise ArgumentError, "negative array size" if size < 0 + + self.clear + if size > 0 + self[size - 1] = nil # allocate + + idx = 0 + while idx < size + self[idx] = (block)? block.call(idx): obj + idx += 1 + end + end + + self + end + + def _inspect + return "[]" if self.size == 0 + "["+self.map{|x|x.inspect}.join(", ")+"]" + end + ## + # Return the contents of this array as a string. + # + # ISO 15.2.12.5.31 (x) + def inspect + begin + self._inspect + rescue SystemStackError + "[...]" + end + end + # ISO 15.2.12.5.32 (x) + alias to_s inspect + + ## + # Equality---Two arrays are equal if they contain the same number + # of elements and if each element is equal to (according to + # Object.==) the corresponding element in the other array. + # + # ISO 15.2.12.5.33 (x) + def ==(other) + other = self.__ary_eq(other) + return false if other == false + return true if other == true + len = self.size + i = 0 + while i < len + return false if self[i] != other[i] + i += 1 + end + return true + end + + ## + # Returns true if +self+ and _other_ are the same object, + # or are both arrays with the same content. + # + # ISO 15.2.12.5.34 (x) + def eql?(other) + other = self.__ary_eq(other) + return false if other == false + return true if other == true + len = self.size + i = 0 + while i < len + return false unless self[i].eql?(other[i]) + i += 1 + end + return true + end + + ## + # Comparison---Returns an integer (-1, 0, or +1) + # if this array is less than, equal to, or greater than other_ary. + # Each object in each array is compared (using <=>). If any value isn't + # equal, then that inequality is the return value. If all the + # values found are equal, then the return is based on a + # comparison of the array lengths. Thus, two arrays are + # "equal" according to Array#<=> if and only if they have + # the same length and the value of each element is equal to the + # value of the corresponding element in the other array. + # + # ISO 15.2.12.5.36 (x) + def <=>(other) + other = self.__ary_cmp(other) + return 0 if 0 == other + return nil if nil == other + + len = self.size + n = other.size + len = n if len > n + i = 0 + while i < len + n = (self[i] <=> other[i]) + return n if n.nil? || n != 0 + i += 1 + end + len = self.size - other.size + if len == 0 + 0 + elsif len > 0 + 1 + else + -1 + end + end + + ## + # Delete element with index +key+ + def delete(key, &block) + while i = self.index(key) + self.delete_at(i) + ret = key + end + return block.call if ret.nil? && block + ret + end + + # internal method to convert multi-value to single value + def __svalue + return self.first if self.size < 2 + self + end +end + +## +# Array is enumerable +class Array + # ISO 15.2.12.3 + include Enumerable + + ## + # Quick sort + # a : the array to sort + # left : the beginning of sort region + # right : the end of sort region + def __sort_sub__(a, left, right, &block) + if left < right + i = left + j = right + pivot = a[i + (j - i) / 2] + while true + while ((block)? block.call(a[i], pivot): (a[i] <=> pivot)) < 0 + i += 1 + end + while ((block)? block.call(pivot, a[j]): (pivot <=> a[j])) < 0 + j -= 1 + end + break if (i >= j) + tmp = a[i]; a[i] = a[j]; a[j] = tmp; + i += 1 + j -= 1 + end + __sort_sub__(a, left, i-1, &block) + __sort_sub__(a, j+1, right, &block) + end + end + # private :__sort_sub__ + + ## + # Sort all elements and replace +self+ with these + # elements. + def sort!(&block) + size = self.size + if size > 1 + __sort_sub__(self, 0, size - 1, &block) + end + self + end + + def sort(&block) + self.dup.sort!(&block) + end +end diff --git a/web/server/h2o/libh2o/deps/mruby/mrblib/compar.rb b/web/server/h2o/libh2o/deps/mruby/mrblib/compar.rb new file mode 100644 index 00000000..84b96259 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/mrblib/compar.rb @@ -0,0 +1,84 @@ +## +# Comparable +# +# ISO 15.3.3 +module Comparable + + ## + # Return true if +self+ is less + # than +other+. Otherwise return + # false. + # + # ISO 15.3.3.2.1 + def < other + cmp = self <=> other + if cmp.nil? + raise ArgumentError, "comparison of #{self.class} with #{other.class} failed" + end + cmp < 0 + end + + ## + # Return true if +self+ is less + # than or equal to +other+. + # Otherwise return false. + # + # ISO 15.3.3.2.2 + def <= other + cmp = self <=> other + if cmp.nil? + raise ArgumentError, "comparison of #{self.class} with #{other.class} failed" + end + cmp <= 0 + end + + ## + # Return true if +self+ is equal + # to +other+. Otherwise return + # false. + # + # ISO 15.3.3.2.3 + def == other + cmp = self <=> other + cmp == 0 + end + + ## + # Return true if +self+ is greater + # than +other+. Otherwise return + # false. + # + # ISO 15.3.3.2.4 + def > other + cmp = self <=> other + if cmp.nil? + raise ArgumentError, "comparison of #{self.class} with #{other.class} failed" + end + cmp > 0 + end + + ## + # Return true if +self+ is greater + # than or equal to +other+. + # Otherwise return false. + # + # ISO 15.3.3.2.5 + def >= other + cmp = self <=> other + if cmp.nil? + raise ArgumentError, "comparison of #{self.class} with #{other.class} failed" + end + cmp >= 0 + end + + ## + # Return true if +self+ is greater + # than or equal to +min+ and + # less than or equal to +max+. + # Otherwise return false. + # + # ISO 15.3.3.2.6 + def between?(min, max) + self >= min and self <= max + end +end diff --git a/web/server/h2o/libh2o/deps/mruby/mrblib/enum.rb b/web/server/h2o/libh2o/deps/mruby/mrblib/enum.rb new file mode 100644 index 00000000..12bd1d37 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/mrblib/enum.rb @@ -0,0 +1,348 @@ +## +# Enumerable +# +# The Enumerable mixin provides collection classes with +# several traversal and searching methods, and with the ability to +# sort. The class must provide a method `each`, which +# yields successive members of the collection. If +# {Enumerable#max}, {#min}, or +# {#sort} is used, the objects in the collection must also +# implement a meaningful `<=>` operator, as these methods +# rely on an ordering between members of the collection. +# +# @ISO 15.3.2 +module Enumerable + + ## + # Call the given block for each element + # which is yield by +each+. Return false + # if one block value is false. Otherwise + # return true. If no block is given and + # +self+ is false return false. + # + # ISO 15.3.2.2.1 + def all?(&block) + if block + self.each{|*val| return false unless block.call(*val)} + else + self.each{|*val| return false unless val.__svalue} + end + true + end + + ## + # Call the given block for each element + # which is yield by +each+. Return true + # if one block value is true. Otherwise + # return false. If no block is given and + # +self+ is true object return true. + # + # ISO 15.3.2.2.2 + def any?(&block) + if block + self.each{|*val| return true if block.call(*val)} + else + self.each{|*val| return true if val.__svalue} + end + false + end + + ## + # Call the given block for each element + # which is yield by +each+. Append all + # values of each block together and + # return this value. + # + # ISO 15.3.2.2.3 + def collect(&block) + return to_enum :collect unless block + + ary = [] + self.each{|*val| ary.push(block.call(*val))} + ary + end + + ## + # Call the given block for each element + # which is yield by +each+. Return + # +ifnone+ if no block value was true. + # Otherwise return the first block value + # which had was true. + # + # ISO 15.3.2.2.4 + def detect(ifnone=nil, &block) + ret = ifnone + self.each{|*val| + if block.call(*val) + ret = val.__svalue + break + end + } + ret + end + + ## + # Call the given block for each element + # which is yield by +each+. Pass an + # index to the block which starts at 0 + # and increase by 1 for each element. + # + # ISO 15.3.2.2.5 + def each_with_index(&block) + return to_enum :each_with_index unless block + + i = 0 + self.each{|*val| + block.call(val.__svalue, i) + i += 1 + } + self + end + + ## + # Return an array of all elements which + # are yield by +each+. + # + # ISO 15.3.2.2.6 + def entries + ary = [] + self.each{|*val| + # __svalue is an internal method + ary.push val.__svalue + } + ary + end + + ## + # Alias for find + # + # ISO 15.3.2.2.7 + alias find detect + + ## + # Call the given block for each element + # which is yield by +each+. Return an array + # which contains all elements whose block + # value was true. + # + # ISO 15.3.2.2.8 + def find_all(&block) + return to_enum :find_all unless block + + ary = [] + self.each{|*val| + ary.push(val.__svalue) if block.call(*val) + } + ary + end + + ## + # Call the given block for each element + # which is yield by +each+ and which return + # value was true when invoking === with + # +pattern+. Return an array with all + # elements or the respective block values. + # + # ISO 15.3.2.2.9 + def grep(pattern, &block) + ary = [] + self.each{|*val| + sv = val.__svalue + if pattern === sv + ary.push((block)? block.call(*val): sv) + end + } + ary + end + + ## + # Return true if at least one element which + # is yield by +each+ returns a true value + # by invoking == with +obj+. Otherwise return + # false. + # + # ISO 15.3.2.2.10 + def include?(obj) + self.each{|*val| + return true if val.__svalue == obj + } + false + end + + ## + # Call the given block for each element + # which is yield by +each+. Return value + # is the sum of all block values. Pass + # to each block the current sum and the + # current element. + # + # ISO 15.3.2.2.11 + def inject(*args, &block) + raise ArgumentError, "too many arguments" if args.size > 2 + if Symbol === args[-1] + sym = args[-1] + block = ->(x,y){x.__send__(sym,y)} + args.pop + end + if args.empty? + flag = true # no initial argument + result = nil + else + flag = false + result = args[0] + end + self.each{|*val| + val = val.__svalue + if flag + # push first element as initial + flag = false + result = val + else + result = block.call(result, val) + end + } + result + end + alias reduce inject + + ## + # Alias for collect + # + # ISO 15.3.2.2.12 + alias map collect + + ## + # Return the maximum value of all elements + # yield by +each+. If no block is given <=> + # will be invoked to define this value. If + # a block is given it will be used instead. + # + # ISO 15.3.2.2.13 + def max(&block) + flag = true # 1st element? + result = nil + self.each{|*val| + val = val.__svalue + if flag + # 1st element + result = val + flag = false + else + if block + result = val if block.call(val, result) > 0 + else + result = val if (val <=> result) > 0 + end + end + } + result + end + + ## + # Return the minimum value of all elements + # yield by +each+. If no block is given <=> + # will be invoked to define this value. If + # a block is given it will be used instead. + # + # ISO 15.3.2.2.14 + def min(&block) + flag = true # 1st element? + result = nil + self.each{|*val| + val = val.__svalue + if flag + # 1st element + result = val + flag = false + else + if block + result = val if block.call(val, result) < 0 + else + result = val if (val <=> result) < 0 + end + end + } + result + end + + ## + # Alias for include? + # + # ISO 15.3.2.2.15 + alias member? include? + + ## + # Call the given block for each element + # which is yield by +each+. Return an + # array which contains two arrays. The + # first array contains all elements + # whose block value was true. The second + # array contains all elements whose + # block value was false. + # + # ISO 15.3.2.2.16 + def partition(&block) + ary_T = [] + ary_F = [] + self.each{|*val| + if block.call(*val) + ary_T.push(val.__svalue) + else + ary_F.push(val.__svalue) + end + } + [ary_T, ary_F] + end + + ## + # Call the given block for each element + # which is yield by +each+. Return an + # array which contains only the elements + # whose block value was false. + # + # ISO 15.3.2.2.17 + def reject(&block) + ary = [] + self.each{|*val| + ary.push(val.__svalue) unless block.call(*val) + } + ary + end + + ## + # Alias for find_all. + # + # ISO 15.3.2.2.18 + alias select find_all + + ## + # Return a sorted array of all elements + # which are yield by +each+. If no block + # is given <=> will be invoked on each + # element to define the order. Otherwise + # the given block will be used for + # sorting. + # + # ISO 15.3.2.2.19 + def sort(&block) + self.map{|*val| val.__svalue}.sort + end + + ## + # Alias for entries. + # + # ISO 15.3.2.2.20 + alias to_a entries + + # redefine #hash 15.3.1.3.15 + def hash + h = 12347 + i = 0 + self.each do |e| + n = (e.hash & (0x7fffffff >> (i % 16))) << (i % 16) + h ^= n + i += 1 + end + h + end +end diff --git a/web/server/h2o/libh2o/deps/mruby/mrblib/hash.rb b/web/server/h2o/libh2o/deps/mruby/mrblib/hash.rb new file mode 100644 index 00000000..6b4803cc --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/mrblib/hash.rb @@ -0,0 +1,358 @@ +## +# Hash +# +# ISO 15.2.13 +class Hash + ## + # Equality---Two hashes are equal if they each contain the same number + # of keys and if each key-value pair is equal to (according to + # Object#==) the corresponding elements in the other + # hash. + # + # ISO 15.2.13.4.1 + def ==(hash) + return true if self.equal?(hash) + begin + hash = hash.to_hash + rescue NoMethodError + return false + end + return false if self.size != hash.size + self.each do |k,v| + return false unless hash.key?(k) + return false unless self[k] == hash[k] + end + return true + end + + ## + # Returns true if hash and other are + # both hashes with the same content compared by eql?. + # + # ISO 15.2.13.4.32 (x) + def eql?(hash) + return true if self.equal?(hash) + begin + hash = hash.to_hash + rescue NoMethodError + return false + end + return false if self.size != hash.size + self.each do |k,v| + return false unless hash.key?(k) + return false unless self[k].eql?(hash[k]) + end + return true + end + + ## + # Delete the element with the key +key+. + # Return the value of the element if +key+ + # was found. Return nil if nothing was + # found. If a block is given, call the + # block with the value of the element. + # + # ISO 15.2.13.4.8 + def delete(key, &block) + if block && !self.has_key?(key) + block.call(key) + else + self.__delete(key) + end + end + + ## + # Calls the given block for each element of +self+ + # and pass the key and value of each element. + # + # call-seq: + # hsh.each {| key, value | block } -> hsh + # hsh.each_pair {| key, value | block } -> hsh + # hsh.each -> an_enumerator + # hsh.each_pair -> an_enumerator + # + # + # If no block is given, an enumerator is returned instead. + # + # h = { "a" => 100, "b" => 200 } + # h.each {|key, value| puts "#{key} is #{value}" } + # + # produces: + # + # a is 100 + # b is 200 + # + # ISO 15.2.13.4.9 + def each(&block) + return to_enum :each unless block + + keys = self.keys + vals = self.values + len = self.size + i = 0 + while i < len + block.call [keys[i], vals[i]] + i += 1 + end + self + end + + ## + # Calls the given block for each element of +self+ + # and pass the key of each element. + # + # call-seq: + # hsh.each_key {| key | block } -> hsh + # hsh.each_key -> an_enumerator + # + # If no block is given, an enumerator is returned instead. + # + # h = { "a" => 100, "b" => 200 } + # h.each_key {|key| puts key } + # + # produces: + # + # a + # b + # + # ISO 15.2.13.4.10 + def each_key(&block) + return to_enum :each_key unless block + + self.keys.each{|k| block.call(k)} + self + end + + ## + # Calls the given block for each element of +self+ + # and pass the value of each element. + # + # call-seq: + # hsh.each_value {| value | block } -> hsh + # hsh.each_value -> an_enumerator + # + # If no block is given, an enumerator is returned instead. + # + # h = { "a" => 100, "b" => 200 } + # h.each_value {|value| puts value } + # + # produces: + # + # 100 + # 200 + # + # ISO 15.2.13.4.11 + def each_value(&block) + return to_enum :each_value unless block + + self.keys.each{|k| block.call(self[k])} + self + end + + ## + # Replaces the contents of hsh with the contents of other hash + # + # ISO 15.2.13.4.23 + def replace(hash) + raise TypeError, "can't convert argument into Hash" unless hash.respond_to?(:to_hash) + self.clear + hash = hash.to_hash + hash.each_key{|k| + self[k] = hash[k] + } + if hash.default_proc + self.default_proc = hash.default_proc + else + self.default = hash.default + end + self + end + # ISO 15.2.13.4.17 + alias initialize_copy replace + + ## + # Return a hash which contains the content of + # +self+ and +other+. If a block is given + # it will be called for each element with + # a duplicate key. The value of the block + # will be the final value of this element. + # + # ISO 15.2.13.4.22 + def merge(other, &block) + h = {} + raise TypeError, "can't convert argument into Hash" unless other.respond_to?(:to_hash) + other = other.to_hash + self.each_key{|k| h[k] = self[k]} + if block + other.each_key{|k| + h[k] = (self.has_key?(k))? block.call(k, self[k], other[k]): other[k] + } + else + other.each_key{|k| h[k] = other[k]} + end + h + end + + # internal method for Hash inspection + def _inspect + return "{}" if self.size == 0 + "{"+self.map {|k,v| + k._inspect + "=>" + v._inspect + }.join(", ")+"}" + end + ## + # Return the contents of this hash as a string. + # + # ISO 15.2.13.4.30 (x) + def inspect + begin + self._inspect + rescue SystemStackError + "{...}" + end + end + # ISO 15.2.13.4.31 (x) + alias to_s inspect + + ## + # call-seq: + # hsh.reject! {| key, value | block } -> hsh or nil + # hsh.reject! -> an_enumerator + # + # Equivalent to Hash#delete_if, but returns + # nil if no changes were made. + # + # 1.8/1.9 Hash#reject! returns Hash; ISO says nothing. + # + def reject!(&block) + return to_enum :reject! unless block + + keys = [] + self.each{|k,v| + if block.call([k, v]) + keys.push(k) + end + } + return nil if keys.size == 0 + keys.each{|k| + self.delete(k) + } + self + end + + ## + # call-seq: + # hsh.reject {|key, value| block} -> a_hash + # hsh.reject -> an_enumerator + # + # Returns a new hash consisting of entries for which the block returns false. + # + # If no block is given, an enumerator is returned instead. + # + # h = { "a" => 100, "b" => 200, "c" => 300 } + # h.reject {|k,v| k < "b"} #=> {"b" => 200, "c" => 300} + # h.reject {|k,v| v > 100} #=> {"a" => 100} + # + # 1.8/1.9 Hash#reject returns Hash; ISO says nothing. + # + def reject(&block) + return to_enum :reject unless block + + h = {} + self.each{|k,v| + unless block.call([k, v]) + h[k] = v + end + } + h + end + + ## + # call-seq: + # hsh.select! {| key, value | block } -> hsh or nil + # hsh.select! -> an_enumerator + # + # Equivalent to Hash#keep_if, but returns + # nil if no changes were made. + # + # 1.9 Hash#select! returns Hash; ISO says nothing. + # + def select!(&block) + return to_enum :select! unless block + + keys = [] + self.each{|k,v| + unless block.call([k, v]) + keys.push(k) + end + } + return nil if keys.size == 0 + keys.each{|k| + self.delete(k) + } + self + end + + ## + # call-seq: + # hsh.select {|key, value| block} -> a_hash + # hsh.select -> an_enumerator + # + # Returns a new hash consisting of entries for which the block returns true. + # + # If no block is given, an enumerator is returned instead. + # + # h = { "a" => 100, "b" => 200, "c" => 300 } + # h.select {|k,v| k > "a"} #=> {"b" => 200, "c" => 300} + # h.select {|k,v| v < 200} #=> {"a" => 100} + # + # 1.9 Hash#select returns Hash; ISO says nothing + # + def select(&block) + return to_enum :select unless block + + h = {} + self.each{|k,v| + if block.call([k, v]) + h[k] = v + end + } + h + end + + ## + # call-seq: + # hsh.rehash -> hsh + # + # Rebuilds the hash based on the current hash values for each key. If + # values of key objects have changed since they were inserted, this + # method will reindex hsh. + # + # h = {"AAA" => "b"} + # h.keys[0].chop! + # h #=> {"AA"=>"b"} + # h["AA"] #=> nil + # h.rehash #=> {"AA"=>"b"} + # h["AA"] #=> "b" + # + def rehash + h = {} + self.each{|k,v| + h[k] = v + } + self.replace(h) + end + + def __update(h) + h.each_key{|k| self[k] = h[k]} + self + end +end + +## +# Hash is enumerable +# +# ISO 15.2.13.3 +class Hash + include Enumerable +end diff --git a/web/server/h2o/libh2o/deps/mruby/mrblib/init_mrblib.c b/web/server/h2o/libh2o/deps/mruby/mrblib/init_mrblib.c new file mode 100644 index 00000000..4d4bcd25 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/mrblib/init_mrblib.c @@ -0,0 +1,11 @@ +#include +#include + +extern const uint8_t mrblib_irep[]; + +void +mrb_init_mrblib(mrb_state *mrb) +{ + mrb_load_irep(mrb, mrblib_irep); +} + diff --git a/web/server/h2o/libh2o/deps/mruby/mrblib/kernel.rb b/web/server/h2o/libh2o/deps/mruby/mrblib/kernel.rb new file mode 100644 index 00000000..550ae817 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/mrblib/kernel.rb @@ -0,0 +1,50 @@ +## +# Kernel +# +# ISO 15.3.1 +module Kernel + + # 15.3.1.2.1 Kernel.` + # provided by Kernel#` + # 15.3.1.3.5 + def `(s) + raise NotImplementedError.new("backquotes not implemented") + end + + ## + # 15.3.1.2.3 Kernel.eval + # 15.3.1.3.12 Kernel#eval + # NotImplemented by mruby core; use mruby-eval gem + + ## + # ISO 15.3.1.2.8 Kernel.loop + # provided by Kernel#loop + + ## + # Calls the given block repetitively. + # + # ISO 15.3.1.3.29 + def loop(&block) + return to_enum :loop unless block + + while true + yield + end + rescue StopIteration => e + e.result + end + + # 11.4.4 Step c) + def !~(y) + !(self =~ y) + end + + # internal method for inspect + def _inspect + self.inspect + end + + def to_enum(*a) + raise NotImplementedError.new("fiber required for enumerator") + end +end diff --git a/web/server/h2o/libh2o/deps/mruby/mrblib/mrblib.rake b/web/server/h2o/libh2o/deps/mruby/mrblib/mrblib.rake new file mode 100644 index 00000000..19fd00d6 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/mrblib/mrblib.rake @@ -0,0 +1,18 @@ +MRuby.each_target do + current_dir = File.dirname(__FILE__) + relative_from_root = File.dirname(__FILE__).relative_path_from(MRUBY_ROOT) + current_build_dir = "#{build_dir}/#{relative_from_root}" + + self.libmruby << objfile("#{current_build_dir}/mrblib") + + file objfile("#{current_build_dir}/mrblib") => "#{current_build_dir}/mrblib.c" + file "#{current_build_dir}/mrblib.c" => [mrbcfile, __FILE__] + Dir.glob("#{current_dir}/*.rb").sort do |t| + _, _, *rbfiles = t.prerequisites + FileUtils.mkdir_p File.dirname(t.name) + open(t.name, 'w') do |f| + _pp "GEN", "*.rb", "#{t.name.relative_path}" + f.puts File.read("#{current_dir}/init_mrblib.c") + mrbc.run f, rbfiles, 'mrblib_irep' + end + end +end diff --git a/web/server/h2o/libh2o/deps/mruby/mrblib/numeric.rb b/web/server/h2o/libh2o/deps/mruby/mrblib/numeric.rb new file mode 100644 index 00000000..89401a08 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/mrblib/numeric.rb @@ -0,0 +1,173 @@ +## +# Numeric +# +# ISO 15.2.7 +class Numeric + include Comparable + ## + # Returns the receiver simply. + # + # ISO 15.2.7.4.1 + def +@ + self + end + + ## + # Returns the receiver's value, negated. + # + # ISO 15.2.7.4.2 + def -@ + 0 - self + end + + ## + # Returns the absolute value of the receiver. + # + # ISO 15.2.7.4.3 + def abs + if self < 0 + -self + else + self + end + end +end + +## +# Integral +# +# mruby special - module to share methods between Floats and Integers +# to make them compatible +module Integral + ## + # Calls the given block once for each Integer + # from +self+ downto +num+. + # + # ISO 15.2.8.3.15 + def downto(num, &block) + return to_enum(:downto, num) unless block + + i = self.to_i + while i >= num + block.call(i) + i -= 1 + end + self + end + + ## + # Returns self + 1 + # + # ISO 15.2.8.3.19 + def next + self + 1 + end + # ISO 15.2.8.3.21 + alias succ next + + ## + # Calls the given block +self+ times. + # + # ISO 15.2.8.3.22 + def times &block + return to_enum :times unless block + + i = 0 + while i < self + block.call i + i += 1 + end + self + end + + ## + # Calls the given block once for each Integer + # from +self+ upto +num+. + # + # ISO 15.2.8.3.27 + def upto(num, &block) + return to_enum(:upto, num) unless block + + i = self.to_i + while i <= num + block.call(i) + i += 1 + end + self + end + + ## + # Calls the given block from +self+ to +num+ + # incremented by +step+ (default 1). + # + def step(num=nil, step=1, &block) + raise ArgumentError, "step can't be 0" if step == 0 + return to_enum(:step, num, step) unless block + + i = if num.kind_of? Float then self.to_f else self end + if num == nil + while true + block.call(i) + i+=step + end + return self + end + if step > 0 + while i <= num + block.call(i) + i += step + end + else + while i >= num + block.call(i) + i += step + end + end + self + end +end + +## +# Integer +# +# ISO 15.2.8 +class Integer + include Integral + ## + # Returns the receiver simply. + # + # ISO 15.2.8.3.14 + def ceil + self + end + + ## + # Returns the receiver simply. + # + # ISO 15.2.8.3.17 + def floor + self + end + + ## + # Returns the receiver simply. + # + # ISO 15.2.8.3.24 + alias round floor + + ## + # Returns the receiver simply. + # + # ISO 15.2.8.3.26 + alias truncate floor +end + +## +# Float +# +# ISO 15.2.9 +class Float + # mruby special - since mruby integers may be upgraded to floats, + # floats should be compatible to integers. + include Integral +end diff --git a/web/server/h2o/libh2o/deps/mruby/mrblib/range.rb b/web/server/h2o/libh2o/deps/mruby/mrblib/range.rb new file mode 100644 index 00000000..5bd2521e --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/mrblib/range.rb @@ -0,0 +1,67 @@ +## +# Range +# +# ISO 15.2.14 +class Range + + ## + # Calls the given block for each element of +self+ + # and pass the respective element. + # + # ISO 15.2.14.4.4 + def each(&block) + return to_enum :each unless block + + val = self.first + last = self.last + + if val.kind_of?(Fixnum) && last.kind_of?(Fixnum) # fixnums are special + lim = last + lim += 1 unless exclude_end? + i = val + while i < lim + block.call(i) + i += 1 + end + return self + end + + if val.kind_of?(String) && last.kind_of?(String) # fixnums are special + if val.respond_to? :upto + return val.upto(last, exclude_end?, &block) + else + str_each = true + end + end + + raise TypeError, "can't iterate" unless val.respond_to? :succ + + return self if (val <=> last) > 0 + + while (val <=> last) < 0 + block.call(val) + val = val.succ + if str_each + break if val.size > last.size + end + end + + block.call(val) if !exclude_end? && (val <=> last) == 0 + self + end + + # redefine #hash 15.3.1.3.15 + def hash + h = first.hash ^ last.hash + h += 1 if self.exclude_end? + h + end +end + +## +# Range is enumerable +# +# ISO 15.2.14.3 +class Range + include Enumerable +end diff --git a/web/server/h2o/libh2o/deps/mruby/mrblib/string.rb b/web/server/h2o/libh2o/deps/mruby/mrblib/string.rb new file mode 100644 index 00000000..4c6114ec --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/mrblib/string.rb @@ -0,0 +1,275 @@ +## +# String +# +# ISO 15.2.10 +class String + include Comparable + ## + # Calls the given block for each line + # and pass the respective line. + # + # ISO 15.2.10.5.15 + def each_line(rs = "\n", &block) + return to_enum(:each_line, rs, &block) unless block + return block.call(self) if rs.nil? + rs = rs.to_str + offset = 0 + rs_len = rs.length + this = dup + while pos = this.index(rs, offset) + block.call(this[offset, pos + rs_len - offset]) + offset = pos + rs_len + end + block.call(this[offset, this.size - offset]) if this.size > offset + self + end + + # private method for gsub/sub + def __sub_replace(pre, m, post) + s = "" + i = 0 + while j = index("\\", i) + break if j == length-1 + t = case self[j+1] + when "\\" + "\\" + when "`" + pre + when "&", "0" + m + when "'" + post + when "1", "2", "3", "4", "5", "6", "7", "8", "9" + "" + else + self[j, 2] + end + s += self[i, j-i] + t + i = j + 2 + end + s + self[i, length-i] + end + + ## + # Replace all matches of +pattern+ with +replacement+. + # Call block (if given) for each match and replace + # +pattern+ with the value of the block. Return the + # final value. + # + # ISO 15.2.10.5.18 + def gsub(*args, &block) + return to_enum(:gsub, *args) if args.length == 1 && !block + raise ArgumentError, "wrong number of arguments" unless (1..2).include?(args.length) + + pattern, replace = *args + plen = pattern.length + if args.length == 2 && block + block = nil + end + if !replace.nil? || !block + replace = replace.to_str + end + offset = 0 + result = [] + while found = index(pattern, offset) + result << self[offset, found - offset] + offset = found + plen + result << if block + block.call(pattern).to_s + else + replace.__sub_replace(self[0, found], pattern, self[offset..-1] || "") + end + if plen == 0 + result << self[offset, 1] + offset += 1 + end + end + result << self[offset..-1] if offset < length + result.join + end + + ## + # Replace all matches of +pattern+ with +replacement+. + # Call block (if given) for each match and replace + # +pattern+ with the value of the block. Modify + # +self+ with the final value. + # + # ISO 15.2.10.5.19 + def gsub!(*args, &block) + raise RuntimeError, "can't modify frozen String" if frozen? + return to_enum(:gsub!, *args) if args.length == 1 && !block + str = self.gsub(*args, &block) + return nil if str == self + self.replace(str) + end + + ## + # Calls the given block for each match of +pattern+ + # If no block is given return an array with all + # matches of +pattern+. + # + # ISO 15.2.10.5.32 + def scan(reg, &block) + ### *** TODO *** ### + unless Object.const_defined?(:Regexp) + raise NotImplementedError, "scan not available (yet)" + end + end + + ## + # Replace only the first match of +pattern+ with + # +replacement+. Call block (if given) for each + # match and replace +pattern+ with the value of the + # block. Return the final value. + # + # ISO 15.2.10.5.36 + def sub(*args, &block) + unless (1..2).include?(args.length) + raise ArgumentError, "wrong number of arguments (given #{args.length}, expected 2)" + end + + pattern, replace = *args + pattern = pattern.to_str + if args.length == 2 && block + block = nil + end + unless block + replace = replace.to_str + end + result = [] + this = dup + found = index(pattern) + return this unless found + result << this[0, found] + offset = found + pattern.length + result << if block + block.call(pattern).to_s + else + replace.__sub_replace(this[0, found], pattern, this[offset..-1] || "") + end + result << this[offset..-1] if offset < length + result.join + end + + ## + # Replace only the first match of +pattern+ with + # +replacement+. Call block (if given) for each + # match and replace +pattern+ with the value of the + # block. Modify +self+ with the final value. + # + # ISO 15.2.10.5.37 + def sub!(*args, &block) + raise RuntimeError, "can't modify frozen String" if frozen? + str = self.sub(*args, &block) + return nil if str == self + self.replace(str) + end + + ## + # Call the given block for each character of + # +self+. + def each_char(&block) + pos = 0 + while pos < self.size + block.call(self[pos]) + pos += 1 + end + self + end + + ## + # Call the given block for each byte of +self+. + def each_byte(&block) + bytes = self.bytes + pos = 0 + while pos < bytes.size + block.call(bytes[pos]) + pos += 1 + end + self + end + + ## + # Modify +self+ by replacing the content of +self+. + # The portion of the string affected is determined using the same criteria as +String#[]+. + def []=(*args) + anum = args.size + if anum == 2 + pos, value = args + case pos + when String + posnum = self.index(pos) + if posnum + b = self[0, posnum.to_i] + a = self[(posnum + pos.length)..-1] + self.replace([b, value, a].join('')) + else + raise IndexError, "string not matched" + end + when Range + head = pos.begin + tail = pos.end + tail += self.length if tail < 0 + unless pos.exclude_end? + tail += 1 + end + return self[head, tail-head]=value + else + pos += self.length if pos < 0 + if pos < 0 || pos > self.length + raise IndexError, "index #{args[0]} out of string" + end + b = self[0, pos.to_i] + a = self[pos + 1..-1] + self.replace([b, value, a].join('')) + end + return value + elsif anum == 3 + pos, len, value = args + pos += self.length if pos < 0 + if pos < 0 || pos > self.length + raise IndexError, "index #{args[0]} out of string" + end + if len < 0 + raise IndexError, "negative length #{len}" + end + b = self[0, pos.to_i] + a = self[pos + len..-1] + self.replace([b, value, a].join('')) + return value + else + raise ArgumentError, "wrong number of arguments (#{anum} for 2..3)" + end + end + + ## + # ISO 15.2.10.5.3 + def =~(re) + raise TypeError, "type mismatch: String given" if re.respond_to? :to_str + re =~ self + end + + ## + # ISO 15.2.10.5.27 + def match(re, &block) + if re.respond_to? :to_str + if Object.const_defined?(:Regexp) + r = Regexp.new(re) + r.match(self, &block) + else + raise NotImplementedError, "String#match needs Regexp class" + end + else + re.match(self, &block) + end + end +end + +## +# String is comparable +# +# ISO 15.2.10.3 +module Comparable; end +class String + include Comparable +end diff --git a/web/server/h2o/libh2o/deps/mruby/mruby-source.gemspec b/web/server/h2o/libh2o/deps/mruby/mruby-source.gemspec new file mode 100644 index 00000000..62d4c0d1 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/mruby-source.gemspec @@ -0,0 +1,18 @@ +# coding: utf-8 +lib = File.expand_path('../lib', __FILE__) +$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib) +require 'mruby/source' + +Gem::Specification.new do |spec| + spec.name = "mruby-source" + spec.version = MRuby::Source::MRUBY_VERSION + spec.authors = [ MRuby::Source::MRUBY_AUTHOR ] + + spec.summary = %q{MRuby source code wrapper.} + spec.description = %q{MRuby source code wrapper for use with Ruby libs.} + spec.homepage = "http://www.mruby.org/" + spec.license = "MIT" + + spec.files = `git ls-files -z`.split("\x0") + spec.require_paths = ["lib"] +end diff --git a/web/server/h2o/libh2o/deps/mruby/src/array.c b/web/server/h2o/libh2o/deps/mruby/src/array.c new file mode 100644 index 00000000..8f33defe --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/src/array.c @@ -0,0 +1,1249 @@ +/* +** array.c - Array class +** +** See Copyright Notice in mruby.h +*/ + +#include +#include +#include +#include +#include +#include "value_array.h" + +#define ARY_DEFAULT_LEN 4 +#define ARY_SHRINK_RATIO 5 /* must be larger than 2 */ +#define ARY_C_MAX_SIZE (SIZE_MAX / sizeof(mrb_value)) +#define ARY_MAX_SIZE ((mrb_int)((ARY_C_MAX_SIZE < (size_t)MRB_INT_MAX) ? ARY_C_MAX_SIZE : MRB_INT_MAX-1)) + +static struct RArray* +ary_new_capa(mrb_state *mrb, mrb_int capa) +{ + struct RArray *a; + size_t blen; + + if (capa > ARY_MAX_SIZE) { + mrb_raise(mrb, E_ARGUMENT_ERROR, "array size too big"); + } + blen = capa * sizeof(mrb_value); + + a = (struct RArray*)mrb_obj_alloc(mrb, MRB_TT_ARRAY, mrb->array_class); + if (capa <= MRB_ARY_EMBED_LEN_MAX) { + ARY_SET_EMBED_LEN(a, 0); + } + else { + a->as.heap.ptr = (mrb_value *)mrb_malloc(mrb, blen); + a->as.heap.aux.capa = capa; + a->as.heap.len = 0; + } + + return a; +} + +MRB_API mrb_value +mrb_ary_new_capa(mrb_state *mrb, mrb_int capa) +{ + struct RArray *a = ary_new_capa(mrb, capa); + return mrb_obj_value(a); +} + +MRB_API mrb_value +mrb_ary_new(mrb_state *mrb) +{ + return mrb_ary_new_capa(mrb, 0); +} + +/* + * to copy array, use this instead of memcpy because of portability + * * gcc on ARM may fail optimization of memcpy + * http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.faqs/ka3934.html + * * gcc on MIPS also fail + * http://gcc.gnu.org/bugzilla/show_bug.cgi?id=39755 + * * memcpy doesn't exist on freestanding environment + * + * If you optimize for binary size, use memcpy instead of this at your own risk + * of above portability issue. + * + * see also http://togetter.com/li/462898 + * + */ +static inline void +array_copy(mrb_value *dst, const mrb_value *src, mrb_int size) +{ + mrb_int i; + + for (i = 0; i < size; i++) { + dst[i] = src[i]; + } +} + +MRB_API mrb_value +mrb_ary_new_from_values(mrb_state *mrb, mrb_int size, const mrb_value *vals) +{ + struct RArray *a = ary_new_capa(mrb, size); + + array_copy(ARY_PTR(a), vals, size); + ARY_SET_LEN(a, size); + + return mrb_obj_value(a); +} + +MRB_API mrb_value +mrb_assoc_new(mrb_state *mrb, mrb_value car, mrb_value cdr) +{ + struct RArray *a; + + a = ary_new_capa(mrb, 2); + ARY_PTR(a)[0] = car; + ARY_PTR(a)[1] = cdr; + ARY_SET_LEN(a, 2); + return mrb_obj_value(a); +} + +static void +ary_fill_with_nil(mrb_value *ptr, mrb_int size) +{ + mrb_value nil = mrb_nil_value(); + + while (size--) { + *ptr++ = nil; + } +} + +static void +ary_modify_check(mrb_state *mrb, struct RArray *a) +{ + if (MRB_FROZEN_P(a)) { + mrb_raise(mrb, E_RUNTIME_ERROR, "can't modify frozen array"); + } +} + +static void +ary_modify(mrb_state *mrb, struct RArray *a) +{ + ary_modify_check(mrb, a); + + if (ARY_SHARED_P(a)) { + mrb_shared_array *shared = a->as.heap.aux.shared; + + if (shared->refcnt == 1 && a->as.heap.ptr == shared->ptr) { + a->as.heap.ptr = shared->ptr; + a->as.heap.aux.capa = a->as.heap.len; + mrb_free(mrb, shared); + } + else { + mrb_value *ptr, *p; + mrb_int len; + + p = a->as.heap.ptr; + len = a->as.heap.len * sizeof(mrb_value); + ptr = (mrb_value *)mrb_malloc(mrb, len); + if (p) { + array_copy(ptr, p, a->as.heap.len); + } + a->as.heap.ptr = ptr; + a->as.heap.aux.capa = a->as.heap.len; + mrb_ary_decref(mrb, shared); + } + ARY_UNSET_SHARED_FLAG(a); + } +} + +MRB_API void +mrb_ary_modify(mrb_state *mrb, struct RArray* a) +{ + mrb_write_barrier(mrb, (struct RBasic*)a); + ary_modify(mrb, a); +} + +static void +ary_make_shared(mrb_state *mrb, struct RArray *a) +{ + if (!ARY_SHARED_P(a) && !ARY_EMBED_P(a)) { + mrb_shared_array *shared = (mrb_shared_array *)mrb_malloc(mrb, sizeof(mrb_shared_array)); + mrb_value *ptr = a->as.heap.ptr; + mrb_int len = a->as.heap.len; + + shared->refcnt = 1; + if (a->as.heap.aux.capa > len) { + a->as.heap.ptr = shared->ptr = (mrb_value *)mrb_realloc(mrb, ptr, sizeof(mrb_value)*len+1); + } + else { + shared->ptr = ptr; + } + shared->len = len; + a->as.heap.aux.shared = shared; + ARY_SET_SHARED_FLAG(a); + } +} + +static void +ary_expand_capa(mrb_state *mrb, struct RArray *a, mrb_int len) +{ + mrb_int capa = ARY_CAPA(a); + + if (len > ARY_MAX_SIZE || len < 0) { + size_error: + mrb_raise(mrb, E_ARGUMENT_ERROR, "array size too big"); + } + + if (capa < ARY_DEFAULT_LEN) { + capa = ARY_DEFAULT_LEN; + } + while (capa < len) { + if (capa <= ARY_MAX_SIZE / 2) { + capa *= 2; + } + else { + capa = len; + } + } + if (capa < len || capa > ARY_MAX_SIZE) { + goto size_error; + } + + if (ARY_EMBED_P(a)) { + mrb_value *ptr = ARY_EMBED_PTR(a); + mrb_int len = ARY_EMBED_LEN(a); + mrb_value *expanded_ptr = (mrb_value *)mrb_malloc(mrb, sizeof(mrb_value)*capa); + + ARY_UNSET_EMBED_FLAG(a); + array_copy(expanded_ptr, ptr, len); + a->as.heap.len = len; + a->as.heap.aux.capa = capa; + a->as.heap.ptr = expanded_ptr; + } + else if (capa > a->as.heap.aux.capa) { + mrb_value *expanded_ptr = (mrb_value *)mrb_realloc(mrb, a->as.heap.ptr, sizeof(mrb_value)*capa); + + a->as.heap.aux.capa = capa; + a->as.heap.ptr = expanded_ptr; + } +} + +static void +ary_shrink_capa(mrb_state *mrb, struct RArray *a) +{ + + mrb_int capa; + + if (ARY_EMBED_P(a)) return; + + capa = a->as.heap.aux.capa; + if (capa < ARY_DEFAULT_LEN * 2) return; + if (capa <= a->as.heap.len * ARY_SHRINK_RATIO) return; + + do { + capa /= 2; + if (capa < ARY_DEFAULT_LEN) { + capa = ARY_DEFAULT_LEN; + break; + } + } while (capa > a->as.heap.len * ARY_SHRINK_RATIO); + + if (capa > a->as.heap.len && capa < a->as.heap.aux.capa) { + a->as.heap.aux.capa = capa; + a->as.heap.ptr = (mrb_value *)mrb_realloc(mrb, a->as.heap.ptr, sizeof(mrb_value)*capa); + } +} + +MRB_API mrb_value +mrb_ary_resize(mrb_state *mrb, mrb_value ary, mrb_int new_len) +{ + mrb_int old_len; + struct RArray *a = mrb_ary_ptr(ary); + + ary_modify(mrb, a); + old_len = RARRAY_LEN(ary); + if (old_len != new_len) { + ARY_SET_LEN(a, new_len); + if (new_len < old_len) { + ary_shrink_capa(mrb, a); + } + else { + ary_expand_capa(mrb, a, new_len); + ary_fill_with_nil(ARY_PTR(a) + old_len, new_len - old_len); + } + } + + return ary; +} + +static mrb_value +mrb_ary_s_create(mrb_state *mrb, mrb_value klass) +{ + mrb_value ary; + mrb_value *vals; + mrb_int len; + struct RArray *a; + + mrb_get_args(mrb, "*!", &vals, &len); + ary = mrb_ary_new_from_values(mrb, len, vals); + a = mrb_ary_ptr(ary); + a->c = mrb_class_ptr(klass); + + return ary; +} + +static void +ary_concat(mrb_state *mrb, struct RArray *a, struct RArray *a2) +{ + mrb_int len; + + if (ARY_LEN(a2) > ARY_MAX_SIZE - ARY_LEN(a)) { + mrb_raise(mrb, E_ARGUMENT_ERROR, "array size too big"); + } + len = ARY_LEN(a) + ARY_LEN(a2); + + ary_modify(mrb, a); + if (ARY_CAPA(a) < len) { + ary_expand_capa(mrb, a, len); + } + array_copy(ARY_PTR(a)+ARY_LEN(a), ARY_PTR(a2), ARY_LEN(a2)); + mrb_write_barrier(mrb, (struct RBasic*)a); + ARY_SET_LEN(a, len); +} + +MRB_API void +mrb_ary_concat(mrb_state *mrb, mrb_value self, mrb_value other) +{ + struct RArray *a2 = mrb_ary_ptr(other); + + ary_concat(mrb, mrb_ary_ptr(self), a2); +} + +static mrb_value +mrb_ary_concat_m(mrb_state *mrb, mrb_value self) +{ + mrb_value ary; + + mrb_get_args(mrb, "A", &ary); + mrb_ary_concat(mrb, self, ary); + return self; +} + +static mrb_value +mrb_ary_plus(mrb_state *mrb, mrb_value self) +{ + struct RArray *a1 = mrb_ary_ptr(self); + struct RArray *a2; + mrb_value *ptr; + mrb_int blen, len1; + + mrb_get_args(mrb, "a", &ptr, &blen); + if (ARY_MAX_SIZE - blen < ARY_LEN(a1)) { + mrb_raise(mrb, E_ARGUMENT_ERROR, "array size too big"); + } + len1 = ARY_LEN(a1); + a2 = ary_new_capa(mrb, len1 + blen); + array_copy(ARY_PTR(a2), ARY_PTR(a1), len1); + array_copy(ARY_PTR(a2) + len1, ptr, blen); + ARY_SET_LEN(a2, len1+blen); + + return mrb_obj_value(a2); +} + +static void +ary_replace(mrb_state *mrb, struct RArray *a, mrb_value *argv, mrb_int len) +{ + ary_modify(mrb, a); + if (ARY_CAPA(a) < len) + ary_expand_capa(mrb, a, len); + array_copy(ARY_PTR(a), argv, len); + mrb_write_barrier(mrb, (struct RBasic*)a); + ARY_SET_LEN(a, len); +} + +MRB_API void +mrb_ary_replace(mrb_state *mrb, mrb_value self, mrb_value other) +{ + struct RArray *a1 = mrb_ary_ptr(self); + struct RArray *a2 = mrb_ary_ptr(other); + + if (a1 != a2) { + ary_replace(mrb, a1, ARY_PTR(a2), ARY_LEN(a2)); + } +} + +static mrb_value +mrb_ary_replace_m(mrb_state *mrb, mrb_value self) +{ + mrb_value other; + + mrb_get_args(mrb, "A", &other); + mrb_ary_replace(mrb, self, other); + + return self; +} + +static mrb_value +mrb_ary_times(mrb_state *mrb, mrb_value self) +{ + struct RArray *a1 = mrb_ary_ptr(self); + struct RArray *a2; + mrb_value *ptr; + mrb_int times, len1; + + mrb_get_args(mrb, "i", ×); + if (times < 0) { + mrb_raise(mrb, E_ARGUMENT_ERROR, "negative argument"); + } + if (times == 0) return mrb_ary_new(mrb); + if (ARY_MAX_SIZE / times < ARY_LEN(a1)) { + mrb_raise(mrb, E_ARGUMENT_ERROR, "array size too big"); + } + len1 = ARY_LEN(a1); + a2 = ary_new_capa(mrb, len1 * times); + ARY_SET_LEN(a2, len1 * times); + ptr = ARY_PTR(a2); + while (times--) { + array_copy(ptr, ARY_PTR(a1), len1); + ptr += len1; + } + + return mrb_obj_value(a2); +} + +static mrb_value +mrb_ary_reverse_bang(mrb_state *mrb, mrb_value self) +{ + struct RArray *a = mrb_ary_ptr(self); + mrb_int len = ARY_LEN(a); + + if (len > 1) { + mrb_value *p1, *p2; + + ary_modify(mrb, a); + p1 = ARY_PTR(a); + p2 = p1 + len - 1; + + while (p1 < p2) { + mrb_value tmp = *p1; + *p1++ = *p2; + *p2-- = tmp; + } + } + return self; +} + +static mrb_value +mrb_ary_reverse(mrb_state *mrb, mrb_value self) +{ + struct RArray *a = mrb_ary_ptr(self), *b = ary_new_capa(mrb, ARY_LEN(a)); + mrb_int len = ARY_LEN(a); + + if (len > 0) { + mrb_value *p1, *p2, *e; + + p1 = ARY_PTR(a); + e = p1 + len; + p2 = ARY_PTR(b) + len - 1; + while (p1 < e) { + *p2-- = *p1++; + } + ARY_SET_LEN(b, len); + } + return mrb_obj_value(b); +} + +MRB_API void +mrb_ary_push(mrb_state *mrb, mrb_value ary, mrb_value elem) +{ + struct RArray *a = mrb_ary_ptr(ary); + mrb_int len = ARY_LEN(a); + + ary_modify(mrb, a); + if (len == ARY_CAPA(a)) + ary_expand_capa(mrb, a, len + 1); + ARY_PTR(a)[len] = elem; + ARY_SET_LEN(a, len+1); + mrb_field_write_barrier_value(mrb, (struct RBasic*)a, elem); +} + +static mrb_value +mrb_ary_push_m(mrb_state *mrb, mrb_value self) +{ + mrb_value *argv; + mrb_int len, len2, alen; + struct RArray *a; + + mrb_get_args(mrb, "*!", &argv, &alen); + a = mrb_ary_ptr(self); + ary_modify(mrb, a); + len = ARY_LEN(a); + len2 = len + alen; + if (ARY_CAPA(a) < len2) { + ary_expand_capa(mrb, a, len2); + } + array_copy(ARY_PTR(a)+len, argv, alen); + ARY_SET_LEN(a, len2); + mrb_write_barrier(mrb, (struct RBasic*)a); + + return self; +} + +MRB_API mrb_value +mrb_ary_pop(mrb_state *mrb, mrb_value ary) +{ + struct RArray *a = mrb_ary_ptr(ary); + mrb_int len = ARY_LEN(a); + + ary_modify_check(mrb, a); + if (len == 0) return mrb_nil_value(); + ARY_SET_LEN(a, len-1); + return ARY_PTR(a)[len-1]; +} + +#define ARY_SHIFT_SHARED_MIN 10 + +MRB_API mrb_value +mrb_ary_shift(mrb_state *mrb, mrb_value self) +{ + struct RArray *a = mrb_ary_ptr(self); + mrb_int len = ARY_LEN(a); + mrb_value val; + + ary_modify_check(mrb, a); + if (len == 0) return mrb_nil_value(); + if (ARY_SHARED_P(a)) { + L_SHIFT: + val = a->as.heap.ptr[0]; + a->as.heap.ptr++; + a->as.heap.len--; + return val; + } + if (len > ARY_SHIFT_SHARED_MIN) { + ary_make_shared(mrb, a); + goto L_SHIFT; + } + else { + mrb_value *ptr = ARY_PTR(a); + mrb_int size = len; + + val = *ptr; + while (--size) { + *ptr = *(ptr+1); + ++ptr; + } + ARY_SET_LEN(a, len-1); + } + return val; +} + +/* self = [1,2,3] + item = 0 + self.unshift item + p self #=> [0, 1, 2, 3] */ +MRB_API mrb_value +mrb_ary_unshift(mrb_state *mrb, mrb_value self, mrb_value item) +{ + struct RArray *a = mrb_ary_ptr(self); + mrb_int len = ARY_LEN(a); + + if (ARY_SHARED_P(a) + && a->as.heap.aux.shared->refcnt == 1 /* shared only referenced from this array */ + && a->as.heap.ptr - a->as.heap.aux.shared->ptr >= 1) /* there's room for unshifted item */ { + a->as.heap.ptr--; + a->as.heap.ptr[0] = item; + } + else { + mrb_value *ptr; + + ary_modify(mrb, a); + if (ARY_CAPA(a) < len + 1) + ary_expand_capa(mrb, a, len + 1); + ptr = ARY_PTR(a); + value_move(ptr + 1, ptr, len); + ptr[0] = item; + } + ARY_SET_LEN(a, len+1); + mrb_field_write_barrier_value(mrb, (struct RBasic*)a, item); + + return self; +} + +static mrb_value +mrb_ary_unshift_m(mrb_state *mrb, mrb_value self) +{ + struct RArray *a = mrb_ary_ptr(self); + mrb_value *vals, *ptr; + mrb_int alen, len; + + mrb_get_args(mrb, "*!", &vals, &alen); + if (alen == 0) { + ary_modify_check(mrb, a); + return self; + } + len = ARY_LEN(a); + if (alen > ARY_MAX_SIZE - len) { + mrb_raise(mrb, E_ARGUMENT_ERROR, "array size too big"); + } + if (ARY_SHARED_P(a) + && a->as.heap.aux.shared->refcnt == 1 /* shared only referenced from this array */ + && a->as.heap.ptr - a->as.heap.aux.shared->ptr >= alen) /* there's room for unshifted item */ { + ary_modify_check(mrb, a); + a->as.heap.ptr -= alen; + ptr = a->as.heap.ptr; + } + else { + ary_modify(mrb, a); + if (ARY_CAPA(a) < len + alen) + ary_expand_capa(mrb, a, len + alen); + ptr = ARY_PTR(a); + value_move(ptr + alen, ptr, len); + } + array_copy(ptr, vals, alen); + ARY_SET_LEN(a, len+alen); + while (alen--) { + mrb_field_write_barrier_value(mrb, (struct RBasic*)a, vals[alen]); + } + + return self; +} + +MRB_API mrb_value +mrb_ary_ref(mrb_state *mrb, mrb_value ary, mrb_int n) +{ + struct RArray *a = mrb_ary_ptr(ary); + mrb_int len = ARY_LEN(a); + + /* range check */ + if (n < 0) n += len; + if (n < 0 || len <= n) return mrb_nil_value(); + + return ARY_PTR(a)[n]; +} + +MRB_API void +mrb_ary_set(mrb_state *mrb, mrb_value ary, mrb_int n, mrb_value val) +{ + struct RArray *a = mrb_ary_ptr(ary); + mrb_int len = ARY_LEN(a); + + ary_modify(mrb, a); + /* range check */ + if (n < 0) { + n += len; + if (n < 0) { + mrb_raisef(mrb, E_INDEX_ERROR, "index %S out of array", mrb_fixnum_value(n - len)); + } + } + if (len <= n) { + if (ARY_CAPA(a) <= n) + ary_expand_capa(mrb, a, n + 1); + ary_fill_with_nil(ARY_PTR(a) + len, n + 1 - len); + ARY_SET_LEN(a, n+1); + } + + ARY_PTR(a)[n] = val; + mrb_field_write_barrier_value(mrb, (struct RBasic*)a, val); +} + +static struct RArray* +ary_dup(mrb_state *mrb, struct RArray *a) +{ + mrb_int len = ARY_LEN(a); + struct RArray *d = ary_new_capa(mrb, len); + + ary_replace(mrb, d, ARY_PTR(a), len); + return d; +} + +MRB_API mrb_value +mrb_ary_splice(mrb_state *mrb, mrb_value ary, mrb_int head, mrb_int len, mrb_value rpl) +{ + struct RArray *a = mrb_ary_ptr(ary); + mrb_int alen = ARY_LEN(a); + const mrb_value *argv; + mrb_int argc; + mrb_int tail; + + ary_modify(mrb, a); + + /* len check */ + if (len < 0) mrb_raisef(mrb, E_INDEX_ERROR, "negative length (%S)", mrb_fixnum_value(len)); + + /* range check */ + if (head < 0) { + head += alen; + if (head < 0) { + mrb_raise(mrb, E_INDEX_ERROR, "index is out of array"); + } + } + tail = head + len; + if (alen < len || alen < tail) { + len = alen - head; + } + + /* size check */ + if (mrb_array_p(rpl)) { + argc = RARRAY_LEN(rpl); + argv = RARRAY_PTR(rpl); + if (argv == ARY_PTR(a)) { + struct RArray *r; + + if (argc > 32767) { + mrb_raise(mrb, E_ARGUMENT_ERROR, "too big recursive splice"); + } + r = ary_dup(mrb, a); + argv = ARY_PTR(r); + } + } + else { + argc = 1; + argv = &rpl; + } + if (head >= alen) { + if (head > ARY_MAX_SIZE - argc) { + mrb_raisef(mrb, E_INDEX_ERROR, "index %S too big", mrb_fixnum_value(head)); + } + len = head + argc; + if (len > ARY_CAPA(a)) { + ary_expand_capa(mrb, a, head + argc); + } + ary_fill_with_nil(ARY_PTR(a) + alen, head - alen); + if (argc > 0) { + array_copy(ARY_PTR(a) + head, argv, argc); + } + ARY_SET_LEN(a, len); + } + else { + mrb_int newlen; + + if (alen - len > ARY_MAX_SIZE - argc) { + mrb_raisef(mrb, E_INDEX_ERROR, "index %S too big", mrb_fixnum_value(alen + argc - len)); + } + newlen = alen + argc - len; + if (newlen > ARY_CAPA(a)) { + ary_expand_capa(mrb, a, newlen); + } + + if (len != argc) { + mrb_value *ptr = ARY_PTR(a); + tail = head + len; + value_move(ptr + head + argc, ptr + tail, alen - tail); + ARY_SET_LEN(a, newlen); + } + if (argc > 0) { + value_move(ARY_PTR(a) + head, argv, argc); + } + } + mrb_write_barrier(mrb, (struct RBasic*)a); + return ary; +} + +void +mrb_ary_decref(mrb_state *mrb, mrb_shared_array *shared) +{ + shared->refcnt--; + if (shared->refcnt == 0) { + mrb_free(mrb, shared->ptr); + mrb_free(mrb, shared); + } +} + +static mrb_value +ary_subseq(mrb_state *mrb, struct RArray *a, mrb_int beg, mrb_int len) +{ + struct RArray *b; + + if (!ARY_SHARED_P(a) && len <= ARY_SHIFT_SHARED_MIN) { + return mrb_ary_new_from_values(mrb, len, ARY_PTR(a)+beg); + } + ary_make_shared(mrb, a); + b = (struct RArray*)mrb_obj_alloc(mrb, MRB_TT_ARRAY, mrb->array_class); + b->as.heap.ptr = a->as.heap.ptr + beg; + b->as.heap.len = len; + b->as.heap.aux.shared = a->as.heap.aux.shared; + b->as.heap.aux.shared->refcnt++; + ARY_SET_SHARED_FLAG(b); + + return mrb_obj_value(b); +} + +static mrb_int +aget_index(mrb_state *mrb, mrb_value index) +{ + if (mrb_fixnum_p(index)) { + return mrb_fixnum(index); + } + else if (mrb_float_p(index)) { + return (mrb_int)mrb_float(index); + } + else { + mrb_int i, argc; + mrb_value *argv; + + mrb_get_args(mrb, "i*!", &i, &argv, &argc); + return i; + } +} + +/* + * call-seq: + * ary[index] -> obj or nil + * ary[start, length] -> new_ary or nil + * ary[range] -> new_ary or nil + * ary.slice(index) -> obj or nil + * ary.slice(start, length) -> new_ary or nil + * ary.slice(range) -> new_ary or nil + * + * Element Reference --- Returns the element at +index+, or returns a + * subarray starting at the +start+ index and continuing for +length+ + * elements, or returns a subarray specified by +range+ of indices. + * + * Negative indices count backward from the end of the array (-1 is the last + * element). For +start+ and +range+ cases the starting index is just before + * an element. Additionally, an empty array is returned when the starting + * index for an element range is at the end of the array. + * + * Returns +nil+ if the index (or starting index) are out of range. + * + * a = [ "a", "b", "c", "d", "e" ] + * a[1] => "b" + * a[1,2] => ["b", "c"] + * a[1..-2] => ["b", "c", "d"] + * + */ + +static mrb_value +mrb_ary_aget(mrb_state *mrb, mrb_value self) +{ + struct RArray *a = mrb_ary_ptr(self); + mrb_int i, len, alen = ARY_LEN(a); + mrb_value index; + + if (mrb_get_args(mrb, "o|i", &index, &len) == 1) { + switch (mrb_type(index)) { + /* a[n..m] */ + case MRB_TT_RANGE: + if (mrb_range_beg_len(mrb, index, &i, &len, alen, TRUE) == 1) { + return ary_subseq(mrb, a, i, len); + } + else { + return mrb_nil_value(); + } + case MRB_TT_FIXNUM: + return mrb_ary_ref(mrb, self, mrb_fixnum(index)); + default: + return mrb_ary_ref(mrb, self, aget_index(mrb, index)); + } + } + + i = aget_index(mrb, index); + if (i < 0) i += alen; + if (i < 0 || alen < i) return mrb_nil_value(); + if (len < 0) return mrb_nil_value(); + if (alen == i) return mrb_ary_new(mrb); + if (len > alen - i) len = alen - i; + + return ary_subseq(mrb, a, i, len); +} + +/* + * call-seq: + * ary[index] = obj -> obj + * ary[start, length] = obj or other_ary or nil -> obj or other_ary or nil + * ary[range] = obj or other_ary or nil -> obj or other_ary or nil + * + * Element Assignment --- Sets the element at +index+, or replaces a subarray + * from the +start+ index for +length+ elements, or replaces a subarray + * specified by the +range+ of indices. + * + * If indices are greater than the current capacity of the array, the array + * grows automatically. Elements are inserted into the array at +start+ if + * +length+ is zero. + * + * Negative indices will count backward from the end of the array. For + * +start+ and +range+ cases the starting index is just before an element. + * + * An IndexError is raised if a negative index points past the beginning of + * the array. + * + * See also Array#push, and Array#unshift. + * + * a = Array.new + * a[4] = "4"; #=> [nil, nil, nil, nil, "4"] + * a[0, 3] = [ 'a', 'b', 'c' ] #=> ["a", "b", "c", nil, "4"] + * a[1..2] = [ 1, 2 ] #=> ["a", 1, 2, nil, "4"] + * a[0, 2] = "?" #=> ["?", 2, nil, "4"] + * a[0..2] = "A" #=> ["A", "4"] + * a[-1] = "Z" #=> ["A", "Z"] + * a[1..-1] = nil #=> ["A", nil] + * a[1..-1] = [] #=> ["A"] + * a[0, 0] = [ 1, 2 ] #=> [1, 2, "A"] + * a[3, 0] = "B" #=> [1, 2, "A", "B"] + */ + +static mrb_value +mrb_ary_aset(mrb_state *mrb, mrb_value self) +{ + mrb_value v1, v2, v3; + mrb_int i, len; + + mrb_ary_modify(mrb, mrb_ary_ptr(self)); + if (mrb_get_args(mrb, "oo|o", &v1, &v2, &v3) == 2) { + /* a[n..m] = v */ + switch (mrb_range_beg_len(mrb, v1, &i, &len, RARRAY_LEN(self), FALSE)) { + case 0: /* not range */ + mrb_ary_set(mrb, self, aget_index(mrb, v1), v2); + break; + case 1: /* range */ + mrb_ary_splice(mrb, self, i, len, v2); + break; + case 2: /* out of range */ + mrb_raisef(mrb, E_RANGE_ERROR, "%S out of range", v1); + break; + } + return v2; + } + + /* a[n,m] = v */ + mrb_ary_splice(mrb, self, aget_index(mrb, v1), aget_index(mrb, v2), v3); + return v3; +} + +static mrb_value +mrb_ary_delete_at(mrb_state *mrb, mrb_value self) +{ + struct RArray *a = mrb_ary_ptr(self); + mrb_int index; + mrb_value val; + mrb_value *ptr; + mrb_int len, alen = ARY_LEN(a); + + mrb_get_args(mrb, "i", &index); + if (index < 0) index += alen; + if (index < 0 || alen <= index) return mrb_nil_value(); + + ary_modify(mrb, a); + ptr = ARY_PTR(a); + val = ptr[index]; + + ptr += index; + len = alen - index; + while (--len) { + *ptr = *(ptr+1); + ++ptr; + } + ARY_SET_LEN(a, alen-1); + + ary_shrink_capa(mrb, a); + + return val; +} + +static mrb_value +mrb_ary_first(mrb_state *mrb, mrb_value self) +{ + struct RArray *a = mrb_ary_ptr(self); + mrb_int size, alen = ARY_LEN(a); + + if (mrb->c->ci->argc == 0) { + return (alen > 0)? ARY_PTR(a)[0]: mrb_nil_value(); + } + mrb_get_args(mrb, "|i", &size); + if (size < 0) { + mrb_raise(mrb, E_ARGUMENT_ERROR, "negative array size"); + } + + if (size > alen) size = alen; + if (ARY_SHARED_P(a)) { + return ary_subseq(mrb, a, 0, size); + } + return mrb_ary_new_from_values(mrb, size, ARY_PTR(a)); +} + +static mrb_value +mrb_ary_last(mrb_state *mrb, mrb_value self) +{ + struct RArray *a = mrb_ary_ptr(self); + mrb_int size, alen = ARY_LEN(a); + + if (mrb_get_args(mrb, "|i", &size) == 0) + return (alen > 0)? ARY_PTR(a)[alen - 1]: mrb_nil_value(); + + if (size < 0) { + mrb_raise(mrb, E_ARGUMENT_ERROR, "negative array size"); + } + if (size > alen) size = alen; + if (ARY_SHARED_P(a) || size > ARY_DEFAULT_LEN) { + return ary_subseq(mrb, a, alen - size, size); + } + return mrb_ary_new_from_values(mrb, size, ARY_PTR(a) + alen - size); +} + +static mrb_value +mrb_ary_index_m(mrb_state *mrb, mrb_value self) +{ + mrb_value obj; + mrb_int i; + + mrb_get_args(mrb, "o", &obj); + for (i = 0; i < RARRAY_LEN(self); i++) { + if (mrb_equal(mrb, RARRAY_PTR(self)[i], obj)) { + return mrb_fixnum_value(i); + } + } + return mrb_nil_value(); +} + +static mrb_value +mrb_ary_rindex_m(mrb_state *mrb, mrb_value self) +{ + mrb_value obj; + mrb_int i, len; + + mrb_get_args(mrb, "o", &obj); + for (i = RARRAY_LEN(self) - 1; i >= 0; i--) { + if (mrb_equal(mrb, RARRAY_PTR(self)[i], obj)) { + return mrb_fixnum_value(i); + } + if (i > (len = RARRAY_LEN(self))) { + i = len; + } + } + return mrb_nil_value(); +} + +MRB_API mrb_value +mrb_ary_splat(mrb_state *mrb, mrb_value v) +{ + mrb_value a, recv_class; + + if (mrb_array_p(v)) { + return v; + } + + if (!mrb_respond_to(mrb, v, mrb_intern_lit(mrb, "to_a"))) { + return mrb_ary_new_from_values(mrb, 1, &v); + } + + a = mrb_funcall(mrb, v, "to_a", 0); + if (mrb_array_p(a)) { + return a; + } + else if (mrb_nil_p(a)) { + return mrb_ary_new_from_values(mrb, 1, &v); + } + else { + recv_class = mrb_obj_value(mrb_obj_class(mrb, v)); + mrb_raisef(mrb, E_TYPE_ERROR, "can't convert %S to Array (%S#to_a gives %S)", + recv_class, + recv_class, + mrb_obj_value(mrb_obj_class(mrb, a)) + ); + /* not reached */ + return mrb_undef_value(); + } +} + +static mrb_value +mrb_ary_size(mrb_state *mrb, mrb_value self) +{ + struct RArray *a = mrb_ary_ptr(self); + + return mrb_fixnum_value(ARY_LEN(a)); +} + +MRB_API mrb_value +mrb_ary_clear(mrb_state *mrb, mrb_value self) +{ + struct RArray *a = mrb_ary_ptr(self); + + ary_modify(mrb, a); + if (ARY_SHARED_P(a)) { + mrb_ary_decref(mrb, a->as.heap.aux.shared); + ARY_UNSET_SHARED_FLAG(a); + } + else if (!ARY_EMBED_P(a)){ + mrb_free(mrb, a->as.heap.ptr); + } + ARY_SET_EMBED_LEN(a, 0); + + return self; +} + +static mrb_value +mrb_ary_empty_p(mrb_state *mrb, mrb_value self) +{ + struct RArray *a = mrb_ary_ptr(self); + + return mrb_bool_value(ARY_LEN(a) == 0); +} + +MRB_API mrb_value +mrb_check_array_type(mrb_state *mrb, mrb_value ary) +{ + return mrb_check_convert_type(mrb, ary, MRB_TT_ARRAY, "Array", "to_ary"); +} + +MRB_API mrb_value +mrb_ary_entry(mrb_value ary, mrb_int offset) +{ + if (offset < 0) { + offset += RARRAY_LEN(ary); + } + if (offset < 0 || RARRAY_LEN(ary) <= offset) { + return mrb_nil_value(); + } + return RARRAY_PTR(ary)[offset]; +} + +static mrb_value +join_ary(mrb_state *mrb, mrb_value ary, mrb_value sep, mrb_value list) +{ + mrb_int i; + mrb_value result, val, tmp; + + /* check recursive */ + for (i=0; i 0 && !mrb_nil_p(sep)) { + mrb_str_cat_str(mrb, result, sep); + } + + val = RARRAY_PTR(ary)[i]; + switch (mrb_type(val)) { + case MRB_TT_ARRAY: + ary_join: + val = join_ary(mrb, val, sep, list); + /* fall through */ + + case MRB_TT_STRING: + str_join: + mrb_str_cat_str(mrb, result, val); + break; + + default: + if (!mrb_immediate_p(val)) { + tmp = mrb_check_string_type(mrb, val); + if (!mrb_nil_p(tmp)) { + val = tmp; + goto str_join; + } + tmp = mrb_check_convert_type(mrb, val, MRB_TT_ARRAY, "Array", "to_ary"); + if (!mrb_nil_p(tmp)) { + val = tmp; + goto ary_join; + } + } + val = mrb_obj_as_string(mrb, val); + goto str_join; + } + } + + mrb_ary_pop(mrb, list); + + return result; +} + +MRB_API mrb_value +mrb_ary_join(mrb_state *mrb, mrb_value ary, mrb_value sep) +{ + if (!mrb_nil_p(sep)) { + sep = mrb_obj_as_string(mrb, sep); + } + return join_ary(mrb, ary, sep, mrb_ary_new(mrb)); +} + +/* + * call-seq: + * ary.join(sep="") -> str + * + * Returns a string created by converting each element of the array to + * a string, separated by sep. + * + * [ "a", "b", "c" ].join #=> "abc" + * [ "a", "b", "c" ].join("-") #=> "a-b-c" + */ + +static mrb_value +mrb_ary_join_m(mrb_state *mrb, mrb_value ary) +{ + mrb_value sep = mrb_nil_value(); + + mrb_get_args(mrb, "|S!", &sep); + return mrb_ary_join(mrb, ary, sep); +} + +static mrb_value +mrb_ary_eq(mrb_state *mrb, mrb_value ary1) +{ + mrb_value ary2; + + mrb_get_args(mrb, "o", &ary2); + if (mrb_obj_equal(mrb, ary1, ary2)) return mrb_true_value(); + if (!mrb_array_p(ary2)) { + return mrb_false_value(); + } + if (RARRAY_LEN(ary1) != RARRAY_LEN(ary2)) return mrb_false_value(); + + return ary2; +} + +static mrb_value +mrb_ary_cmp(mrb_state *mrb, mrb_value ary1) +{ + mrb_value ary2; + + mrb_get_args(mrb, "o", &ary2); + if (mrb_obj_equal(mrb, ary1, ary2)) return mrb_fixnum_value(0); + if (!mrb_array_p(ary2)) { + return mrb_nil_value(); + } + + return ary2; +} + +void +mrb_init_array(mrb_state *mrb) +{ + struct RClass *a; + + mrb->array_class = a = mrb_define_class(mrb, "Array", mrb->object_class); /* 15.2.12 */ + MRB_SET_INSTANCE_TT(a, MRB_TT_ARRAY); + + mrb_define_class_method(mrb, a, "[]", mrb_ary_s_create, MRB_ARGS_ANY()); /* 15.2.12.4.1 */ + + mrb_define_method(mrb, a, "+", mrb_ary_plus, MRB_ARGS_REQ(1)); /* 15.2.12.5.1 */ + mrb_define_method(mrb, a, "*", mrb_ary_times, MRB_ARGS_REQ(1)); /* 15.2.12.5.2 */ + mrb_define_method(mrb, a, "<<", mrb_ary_push_m, MRB_ARGS_REQ(1)); /* 15.2.12.5.3 */ + mrb_define_method(mrb, a, "[]", mrb_ary_aget, MRB_ARGS_ANY()); /* 15.2.12.5.4 */ + mrb_define_method(mrb, a, "[]=", mrb_ary_aset, MRB_ARGS_ANY()); /* 15.2.12.5.5 */ + mrb_define_method(mrb, a, "clear", mrb_ary_clear, MRB_ARGS_NONE()); /* 15.2.12.5.6 */ + mrb_define_method(mrb, a, "concat", mrb_ary_concat_m, MRB_ARGS_REQ(1)); /* 15.2.12.5.8 */ + mrb_define_method(mrb, a, "delete_at", mrb_ary_delete_at, MRB_ARGS_REQ(1)); /* 15.2.12.5.9 */ + mrb_define_method(mrb, a, "empty?", mrb_ary_empty_p, MRB_ARGS_NONE()); /* 15.2.12.5.12 */ + mrb_define_method(mrb, a, "first", mrb_ary_first, MRB_ARGS_OPT(1)); /* 15.2.12.5.13 */ + mrb_define_method(mrb, a, "index", mrb_ary_index_m, MRB_ARGS_REQ(1)); /* 15.2.12.5.14 */ + mrb_define_method(mrb, a, "initialize_copy", mrb_ary_replace_m, MRB_ARGS_REQ(1)); /* 15.2.12.5.16 */ + mrb_define_method(mrb, a, "join", mrb_ary_join_m, MRB_ARGS_ANY()); /* 15.2.12.5.17 */ + mrb_define_method(mrb, a, "last", mrb_ary_last, MRB_ARGS_ANY()); /* 15.2.12.5.18 */ + mrb_define_method(mrb, a, "length", mrb_ary_size, MRB_ARGS_NONE()); /* 15.2.12.5.19 */ + mrb_define_method(mrb, a, "pop", mrb_ary_pop, MRB_ARGS_NONE()); /* 15.2.12.5.21 */ + mrb_define_method(mrb, a, "push", mrb_ary_push_m, MRB_ARGS_ANY()); /* 15.2.12.5.22 */ + mrb_define_method(mrb, a, "append", mrb_ary_push_m, MRB_ARGS_ANY()); + mrb_define_method(mrb, a, "replace", mrb_ary_replace_m, MRB_ARGS_REQ(1)); /* 15.2.12.5.23 */ + mrb_define_method(mrb, a, "reverse", mrb_ary_reverse, MRB_ARGS_NONE()); /* 15.2.12.5.24 */ + mrb_define_method(mrb, a, "reverse!", mrb_ary_reverse_bang, MRB_ARGS_NONE()); /* 15.2.12.5.25 */ + mrb_define_method(mrb, a, "rindex", mrb_ary_rindex_m, MRB_ARGS_REQ(1)); /* 15.2.12.5.26 */ + mrb_define_method(mrb, a, "shift", mrb_ary_shift, MRB_ARGS_NONE()); /* 15.2.12.5.27 */ + mrb_define_method(mrb, a, "size", mrb_ary_size, MRB_ARGS_NONE()); /* 15.2.12.5.28 */ + mrb_define_method(mrb, a, "slice", mrb_ary_aget, MRB_ARGS_ANY()); /* 15.2.12.5.29 */ + mrb_define_method(mrb, a, "unshift", mrb_ary_unshift_m, MRB_ARGS_ANY()); /* 15.2.12.5.30 */ + mrb_define_method(mrb, a, "prepend", mrb_ary_unshift_m, MRB_ARGS_ANY()); + + mrb_define_method(mrb, a, "__ary_eq", mrb_ary_eq, MRB_ARGS_REQ(1)); + mrb_define_method(mrb, a, "__ary_cmp", mrb_ary_cmp, MRB_ARGS_REQ(1)); + mrb_define_method(mrb, a, "__ary_index", mrb_ary_index_m, MRB_ARGS_REQ(1)); /* kept for mruby-array-ext */ +} diff --git a/web/server/h2o/libh2o/deps/mruby/src/backtrace.c b/web/server/h2o/libh2o/deps/mruby/src/backtrace.c new file mode 100644 index 00000000..3e4e1a43 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/src/backtrace.c @@ -0,0 +1,281 @@ +/* +** backtrace.c - +** +** See Copyright Notice in mruby.h +*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +struct backtrace_location { + int lineno; + const char *filename; + mrb_sym method_id; +}; + +typedef void (*each_backtrace_func)(mrb_state*, struct backtrace_location*, void*); + +static const mrb_data_type bt_type = { "Backtrace", mrb_free }; + +static void +each_backtrace(mrb_state *mrb, ptrdiff_t ciidx, mrb_code *pc0, each_backtrace_func func, void *data) +{ + ptrdiff_t i, j; + + if (ciidx >= mrb->c->ciend - mrb->c->cibase) + ciidx = 10; /* ciidx is broken... */ + + for (i=ciidx, j=0; i >= 0; i--,j++) { + struct backtrace_location loc; + mrb_callinfo *ci; + mrb_irep *irep; + mrb_code *pc; + + ci = &mrb->c->cibase[i]; + + if (!ci->proc) continue; + if (MRB_PROC_CFUNC_P(ci->proc)) continue; + + irep = ci->proc->body.irep; + if (!irep) continue; + + if (mrb->c->cibase[i].err) { + pc = mrb->c->cibase[i].err; + } + else if (i+1 <= ciidx) { + pc = mrb->c->cibase[i+1].pc - 1; + } + else { + pc = pc0; + } + loc.filename = mrb_debug_get_filename(irep, pc - irep->iseq); + loc.lineno = mrb_debug_get_line(irep, pc - irep->iseq); + + if (loc.lineno == -1) continue; + + if (!loc.filename) { + loc.filename = "(unknown)"; + } + + loc.method_id = ci->mid; + func(mrb, &loc, data); + } +} + +#ifndef MRB_DISABLE_STDIO + +static void +print_backtrace(mrb_state *mrb, mrb_value backtrace) +{ + int i, n; + FILE *stream = stderr; + + if (!mrb_array_p(backtrace)) return; + + n = RARRAY_LEN(backtrace) - 1; + if (n == 0) return; + + fprintf(stream, "trace:\n"); + for (i=0; iflags; + + if (packed_bt_len(bt, n) == 0) return; + fprintf(stream, "trace:\n"); + for (i = 0; ifilename == NULL) continue; + fprintf(stream, "\t[%d] %s:%d", i, entry->filename, entry->lineno); + if (entry->method_id != 0) { + const char *method_name; + + method_name = mrb_sym2name(mrb, entry->method_id); + fprintf(stream, ":in %s", method_name); + mrb_gc_arena_restore(mrb, ai); + } + fprintf(stream, "\n"); + } +} + +/* mrb_print_backtrace + + function to retrieve backtrace information from the last exception. +*/ + +MRB_API void +mrb_print_backtrace(mrb_state *mrb) +{ + mrb_value backtrace; + + if (!mrb->exc) { + return; + } + + backtrace = mrb_obj_iv_get(mrb, mrb->exc, mrb_intern_lit(mrb, "backtrace")); + if (mrb_nil_p(backtrace)) return; + if (mrb_array_p(backtrace)) { + print_backtrace(mrb, backtrace); + } + else { + print_packed_backtrace(mrb, backtrace); + } +} +#else + +MRB_API void +mrb_print_backtrace(mrb_state *mrb) +{ +} + +#endif + +static void +count_backtrace_i(mrb_state *mrb, + struct backtrace_location *loc, + void *data) +{ + int *lenp = (int*)data; + + if (loc->filename == NULL) return; + (*lenp)++; +} + +static void +pack_backtrace_i(mrb_state *mrb, + struct backtrace_location *loc, + void *data) +{ + struct backtrace_location **pptr = (struct backtrace_location**)data; + struct backtrace_location *ptr = *pptr; + + if (loc->filename == NULL) return; + *ptr = *loc; + *pptr = ptr+1; +} + +static mrb_value +packed_backtrace(mrb_state *mrb) +{ + struct RData *backtrace; + ptrdiff_t ciidx = mrb->c->ci - mrb->c->cibase; + int len = 0; + int size; + void *ptr; + + each_backtrace(mrb, ciidx, mrb->c->ci->pc, count_backtrace_i, &len); + size = len * sizeof(struct backtrace_location); + ptr = mrb_malloc(mrb, size); + if (ptr) memset(ptr, 0, size); + backtrace = mrb_data_object_alloc(mrb, NULL, ptr, &bt_type); + backtrace->flags = (unsigned int)len; + each_backtrace(mrb, ciidx, mrb->c->ci->pc, pack_backtrace_i, &ptr); + return mrb_obj_value(backtrace); +} + +void +mrb_keep_backtrace(mrb_state *mrb, mrb_value exc) +{ + mrb_value backtrace; + int ai = mrb_gc_arena_save(mrb); + + backtrace = packed_backtrace(mrb); + mrb_iv_set(mrb, exc, mrb_intern_lit(mrb, "backtrace"), backtrace); + mrb_gc_arena_restore(mrb, ai); +} + +mrb_value +mrb_unpack_backtrace(mrb_state *mrb, mrb_value backtrace) +{ + struct backtrace_location *bt; + mrb_int n, i; + int ai; + + if (mrb_nil_p(backtrace)) { + empty_backtrace: + return mrb_ary_new_capa(mrb, 0); + } + if (mrb_array_p(backtrace)) return backtrace; + bt = (struct backtrace_location*)mrb_data_check_get_ptr(mrb, backtrace, &bt_type); + if (bt == NULL) goto empty_backtrace; + n = (mrb_int)RDATA(backtrace)->flags; + backtrace = mrb_ary_new_capa(mrb, n); + ai = mrb_gc_arena_save(mrb); + for (i = 0; i < n; i++) { + struct backtrace_location *entry = &bt[i]; + mrb_value btline; + + if (entry->filename == NULL) continue; + btline = mrb_format(mrb, "%S:%S", + mrb_str_new_cstr(mrb, entry->filename), + mrb_fixnum_value(entry->lineno)); + if (entry->method_id != 0) { + mrb_str_cat_lit(mrb, btline, ":in "); + mrb_str_cat_cstr(mrb, btline, mrb_sym2name(mrb, entry->method_id)); + } + mrb_ary_push(mrb, backtrace, btline); + mrb_gc_arena_restore(mrb, ai); + } + + return backtrace; +} + +MRB_API mrb_value +mrb_exc_backtrace(mrb_state *mrb, mrb_value exc) +{ + mrb_sym attr_name; + mrb_value backtrace; + + attr_name = mrb_intern_lit(mrb, "backtrace"); + backtrace = mrb_iv_get(mrb, exc, attr_name); + if (mrb_nil_p(backtrace) || mrb_array_p(backtrace)) { + return backtrace; + } + backtrace = mrb_unpack_backtrace(mrb, backtrace); + mrb_iv_set(mrb, exc, attr_name, backtrace); + return backtrace; +} + +MRB_API mrb_value +mrb_get_backtrace(mrb_state *mrb) +{ + return mrb_unpack_backtrace(mrb, packed_backtrace(mrb)); +} diff --git a/web/server/h2o/libh2o/deps/mruby/src/class.c b/web/server/h2o/libh2o/deps/mruby/src/class.c new file mode 100644 index 00000000..e3888001 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/src/class.c @@ -0,0 +1,2474 @@ +/* +** class.c - Class class +** +** See Copyright Notice in mruby.h +*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +KHASH_DEFINE(mt, mrb_sym, struct RProc*, TRUE, kh_int_hash_func, kh_int_hash_equal) + +void +mrb_gc_mark_mt(mrb_state *mrb, struct RClass *c) +{ + khiter_t k; + khash_t(mt) *h = c->mt; + + if (!h) return; + for (k = kh_begin(h); k != kh_end(h); k++) { + if (kh_exist(h, k)) { + struct RProc *m = kh_value(h, k); + if (m) { + mrb_gc_mark(mrb, (struct RBasic*)m); + } + } + } +} + +size_t +mrb_gc_mark_mt_size(mrb_state *mrb, struct RClass *c) +{ + khash_t(mt) *h = c->mt; + + if (!h) return 0; + return kh_size(h); +} + +void +mrb_gc_free_mt(mrb_state *mrb, struct RClass *c) +{ + kh_destroy(mt, mrb, c->mt); +} + +void +mrb_class_name_class(mrb_state *mrb, struct RClass *outer, struct RClass *c, mrb_sym id) +{ + mrb_value name; + mrb_sym nsym = mrb_intern_lit(mrb, "__classname__"); + + if (mrb_obj_iv_defined(mrb, (struct RObject*)c, nsym)) return; + if (outer == NULL || outer == mrb->object_class) { + name = mrb_symbol_value(id); + } + else { + name = mrb_class_path(mrb, outer); + if (mrb_nil_p(name)) { /* unnamed outer class */ + if (outer != mrb->object_class) { + mrb_obj_iv_set(mrb, (struct RObject*)c, mrb_intern_lit(mrb, "__outer__"), + mrb_obj_value(outer)); + } + return; + } + mrb_str_cat_cstr(mrb, name, "::"); + mrb_str_cat_cstr(mrb, name, mrb_sym2name(mrb, id)); + } + mrb_obj_iv_set(mrb, (struct RObject*)c, nsym, name); +} + +static void +setup_class(mrb_state *mrb, struct RClass *outer, struct RClass *c, mrb_sym id) +{ + mrb_class_name_class(mrb, outer, c, id); + mrb_obj_iv_set(mrb, (struct RObject*)outer, id, mrb_obj_value(c)); +} + +#define make_metaclass(mrb, c) prepare_singleton_class((mrb), (struct RBasic*)(c)) + +static void +prepare_singleton_class(mrb_state *mrb, struct RBasic *o) +{ + struct RClass *sc, *c; + + if (o->c->tt == MRB_TT_SCLASS) return; + sc = (struct RClass*)mrb_obj_alloc(mrb, MRB_TT_SCLASS, mrb->class_class); + sc->flags |= MRB_FLAG_IS_INHERITED; + sc->mt = kh_init(mt, mrb); + sc->iv = 0; + if (o->tt == MRB_TT_CLASS) { + c = (struct RClass*)o; + if (!c->super) { + sc->super = mrb->class_class; + } + else { + sc->super = c->super->c; + } + } + else if (o->tt == MRB_TT_SCLASS) { + c = (struct RClass*)o; + while (c->super->tt == MRB_TT_ICLASS) + c = c->super; + make_metaclass(mrb, c->super); + sc->super = c->super->c; + } + else { + sc->super = o->c; + prepare_singleton_class(mrb, (struct RBasic*)sc); + } + o->c = sc; + mrb_field_write_barrier(mrb, (struct RBasic*)o, (struct RBasic*)sc); + mrb_field_write_barrier(mrb, (struct RBasic*)sc, (struct RBasic*)o); + mrb_obj_iv_set(mrb, (struct RObject*)sc, mrb_intern_lit(mrb, "__attached__"), mrb_obj_value(o)); +} + +static struct RClass* +class_from_sym(mrb_state *mrb, struct RClass *klass, mrb_sym id) +{ + mrb_value c = mrb_const_get(mrb, mrb_obj_value(klass), id); + + mrb_check_type(mrb, c, MRB_TT_CLASS); + return mrb_class_ptr(c); +} + +static struct RClass* +module_from_sym(mrb_state *mrb, struct RClass *klass, mrb_sym id) +{ + mrb_value c = mrb_const_get(mrb, mrb_obj_value(klass), id); + + mrb_check_type(mrb, c, MRB_TT_MODULE); + return mrb_class_ptr(c); +} + +static mrb_bool +class_ptr_p(mrb_value obj) +{ + switch (mrb_type(obj)) { + case MRB_TT_CLASS: + case MRB_TT_SCLASS: + case MRB_TT_MODULE: + return TRUE; + default: + return FALSE; + } +} + +static void +check_if_class_or_module(mrb_state *mrb, mrb_value obj) +{ + if (!class_ptr_p(obj)) { + mrb_raisef(mrb, E_TYPE_ERROR, "%S is not a class/module", mrb_inspect(mrb, obj)); + } +} + +static struct RClass* +define_module(mrb_state *mrb, mrb_sym name, struct RClass *outer) +{ + struct RClass *m; + + if (mrb_const_defined_at(mrb, mrb_obj_value(outer), name)) { + return module_from_sym(mrb, outer, name); + } + m = mrb_module_new(mrb); + setup_class(mrb, outer, m, name); + + return m; +} + +MRB_API struct RClass* +mrb_define_module_id(mrb_state *mrb, mrb_sym name) +{ + return define_module(mrb, name, mrb->object_class); +} + +MRB_API struct RClass* +mrb_define_module(mrb_state *mrb, const char *name) +{ + return define_module(mrb, mrb_intern_cstr(mrb, name), mrb->object_class); +} + +MRB_API struct RClass* +mrb_vm_define_module(mrb_state *mrb, mrb_value outer, mrb_sym id) +{ + check_if_class_or_module(mrb, outer); + if (mrb_const_defined_at(mrb, outer, id)) { + mrb_value old = mrb_const_get(mrb, outer, id); + + if (mrb_type(old) != MRB_TT_MODULE) { + mrb_raisef(mrb, E_TYPE_ERROR, "%S is not a module", mrb_inspect(mrb, old)); + } + return mrb_class_ptr(old); + } + return define_module(mrb, id, mrb_class_ptr(outer)); +} + +MRB_API struct RClass* +mrb_define_module_under(mrb_state *mrb, struct RClass *outer, const char *name) +{ + mrb_sym id = mrb_intern_cstr(mrb, name); + struct RClass * c = define_module(mrb, id, outer); + + setup_class(mrb, outer, c, id); + return c; +} + +static struct RClass* +find_origin(struct RClass *c) +{ + MRB_CLASS_ORIGIN(c); + return c; +} + +static struct RClass* +define_class(mrb_state *mrb, mrb_sym name, struct RClass *super, struct RClass *outer) +{ + struct RClass * c; + + if (mrb_const_defined_at(mrb, mrb_obj_value(outer), name)) { + c = class_from_sym(mrb, outer, name); + MRB_CLASS_ORIGIN(c); + if (super && mrb_class_real(c->super) != super) { + mrb_raisef(mrb, E_TYPE_ERROR, "superclass mismatch for Class %S (%S not %S)", + mrb_sym2str(mrb, name), + mrb_obj_value(c->super), mrb_obj_value(super)); + } + return c; + } + + c = mrb_class_new(mrb, super); + setup_class(mrb, outer, c, name); + + return c; +} + +MRB_API struct RClass* +mrb_define_class_id(mrb_state *mrb, mrb_sym name, struct RClass *super) +{ + if (!super) { + mrb_warn(mrb, "no super class for '%S', Object assumed", mrb_sym2str(mrb, name)); + } + return define_class(mrb, name, super, mrb->object_class); +} + +MRB_API struct RClass* +mrb_define_class(mrb_state *mrb, const char *name, struct RClass *super) +{ + return mrb_define_class_id(mrb, mrb_intern_cstr(mrb, name), super); +} + +static mrb_value mrb_bob_init(mrb_state *mrb, mrb_value); +#ifdef MRB_METHOD_CACHE +static void mc_clear_all(mrb_state *mrb); +static void mc_clear_by_class(mrb_state *mrb, struct RClass*); +static void mc_clear_by_id(mrb_state *mrb, struct RClass*, mrb_sym); +#else +#define mc_clear_all(mrb) +#define mc_clear_by_class(mrb,c) +#define mc_clear_by_id(mrb,c,s) +#endif + +static void +mrb_class_inherited(mrb_state *mrb, struct RClass *super, struct RClass *klass) +{ + mrb_value s; + mrb_sym mid; + + if (!super) + super = mrb->object_class; + super->flags |= MRB_FLAG_IS_INHERITED; + s = mrb_obj_value(super); + mc_clear_by_class(mrb, klass); + mid = mrb_intern_lit(mrb, "inherited"); + if (!mrb_func_basic_p(mrb, s, mid, mrb_bob_init)) { + mrb_value c = mrb_obj_value(klass); + mrb_funcall_argv(mrb, s, mid, 1, &c); + } +} + +MRB_API struct RClass* +mrb_vm_define_class(mrb_state *mrb, mrb_value outer, mrb_value super, mrb_sym id) +{ + struct RClass *s; + struct RClass *c; + + if (!mrb_nil_p(super)) { + if (mrb_type(super) != MRB_TT_CLASS) { + mrb_raisef(mrb, E_TYPE_ERROR, "superclass must be a Class (%S given)", + mrb_inspect(mrb, super)); + } + s = mrb_class_ptr(super); + } + else { + s = 0; + } + check_if_class_or_module(mrb, outer); + if (mrb_const_defined_at(mrb, outer, id)) { + mrb_value old = mrb_const_get(mrb, outer, id); + + if (mrb_type(old) != MRB_TT_CLASS) { + mrb_raisef(mrb, E_TYPE_ERROR, "%S is not a class", mrb_inspect(mrb, old)); + } + c = mrb_class_ptr(old); + if (s) { + /* check super class */ + if (mrb_class_real(c->super) != s) { + mrb_raisef(mrb, E_TYPE_ERROR, "superclass mismatch for class %S", old); + } + } + return c; + } + c = define_class(mrb, id, s, mrb_class_ptr(outer)); + mrb_class_inherited(mrb, mrb_class_real(c->super), c); + + return c; +} + +MRB_API mrb_bool +mrb_class_defined(mrb_state *mrb, const char *name) +{ + mrb_value sym = mrb_check_intern_cstr(mrb, name); + if (mrb_nil_p(sym)) { + return FALSE; + } + return mrb_const_defined(mrb, mrb_obj_value(mrb->object_class), mrb_symbol(sym)); +} + +MRB_API mrb_bool +mrb_class_defined_under(mrb_state *mrb, struct RClass *outer, const char *name) +{ + mrb_value sym = mrb_check_intern_cstr(mrb, name); + if (mrb_nil_p(sym)) { + return FALSE; + } + return mrb_const_defined_at(mrb, mrb_obj_value(outer), mrb_symbol(sym)); +} + +MRB_API struct RClass* +mrb_class_get_under(mrb_state *mrb, struct RClass *outer, const char *name) +{ + return class_from_sym(mrb, outer, mrb_intern_cstr(mrb, name)); +} + +MRB_API struct RClass* +mrb_class_get(mrb_state *mrb, const char *name) +{ + return mrb_class_get_under(mrb, mrb->object_class, name); +} + +MRB_API struct RClass* +mrb_exc_get(mrb_state *mrb, const char *name) +{ + struct RClass *exc, *e; + mrb_value c = mrb_const_get(mrb, mrb_obj_value(mrb->object_class), + mrb_intern_cstr(mrb, name)); + + if (mrb_type(c) != MRB_TT_CLASS) { + mrb_raise(mrb, mrb->eException_class, "exception corrupted"); + } + exc = e = mrb_class_ptr(c); + + while (e) { + if (e == mrb->eException_class) + return exc; + e = e->super; + } + return mrb->eException_class; +} + +MRB_API struct RClass* +mrb_module_get_under(mrb_state *mrb, struct RClass *outer, const char *name) +{ + return module_from_sym(mrb, outer, mrb_intern_cstr(mrb, name)); +} + +MRB_API struct RClass* +mrb_module_get(mrb_state *mrb, const char *name) +{ + return mrb_module_get_under(mrb, mrb->object_class, name); +} + +/*! + * Defines a class under the namespace of \a outer. + * \param outer a class which contains the new class. + * \param id name of the new class + * \param super a class from which the new class will derive. + * NULL means \c Object class. + * \return the created class + * \throw TypeError if the constant name \a name is already taken but + * the constant is not a \c Class. + * \throw NameError if the class is already defined but the class can not + * be reopened because its superclass is not \a super. + * \post top-level constant named \a name refers the returned class. + * + * \note if a class named \a name is already defined and its superclass is + * \a super, the function just returns the defined class. + */ +MRB_API struct RClass* +mrb_define_class_under(mrb_state *mrb, struct RClass *outer, const char *name, struct RClass *super) +{ + mrb_sym id = mrb_intern_cstr(mrb, name); + struct RClass * c; + +#if 0 + if (!super) { + mrb_warn(mrb, "no super class for '%S::%S', Object assumed", + mrb_obj_value(outer), mrb_sym2str(mrb, id)); + } +#endif + c = define_class(mrb, id, super, outer); + setup_class(mrb, outer, c, id); + return c; +} + +MRB_API void +mrb_define_method_raw(mrb_state *mrb, struct RClass *c, mrb_sym mid, struct RProc *p) +{ + khash_t(mt) *h; + khiter_t k; + MRB_CLASS_ORIGIN(c); + h = c->mt; + + if (MRB_FROZEN_P(c)) { + if (c->tt == MRB_TT_MODULE) + mrb_raise(mrb, E_RUNTIME_ERROR, "can't modify frozen module"); + else + mrb_raise(mrb, E_RUNTIME_ERROR, "can't modify frozen class"); + } + if (!h) h = c->mt = kh_init(mt, mrb); + k = kh_put(mt, mrb, h, mid); + kh_value(h, k) = p; + if (p) { + p->c = NULL; + mrb_field_write_barrier(mrb, (struct RBasic *)c, (struct RBasic *)p); + } + mc_clear_by_id(mrb, c, mid); +} + +MRB_API void +mrb_define_method_id(mrb_state *mrb, struct RClass *c, mrb_sym mid, mrb_func_t func, mrb_aspec aspec) +{ + struct RProc *p; + int ai = mrb_gc_arena_save(mrb); + + p = mrb_proc_new_cfunc(mrb, func); + p->target_class = c; + mrb_define_method_raw(mrb, c, mid, p); + mrb_gc_arena_restore(mrb, ai); +} + +MRB_API void +mrb_define_method(mrb_state *mrb, struct RClass *c, const char *name, mrb_func_t func, mrb_aspec aspec) +{ + mrb_define_method_id(mrb, c, mrb_intern_cstr(mrb, name), func, aspec); +} + +/* a function to raise NotImplementedError with current method name */ +MRB_API void +mrb_notimplement(mrb_state *mrb) +{ + const char *str; + mrb_int len; + mrb_callinfo *ci = mrb->c->ci; + + if (ci->mid) { + str = mrb_sym2name_len(mrb, ci->mid, &len); + mrb_raisef(mrb, E_NOTIMP_ERROR, + "%S() function is unimplemented on this machine", + mrb_str_new_static(mrb, str, (size_t)len)); + } +} + +/* a function to be replacement of unimplemented method */ +MRB_API mrb_value +mrb_notimplement_m(mrb_state *mrb, mrb_value self) +{ + mrb_notimplement(mrb); + /* not reached */ + return mrb_nil_value(); +} + +static mrb_value +check_type(mrb_state *mrb, mrb_value val, enum mrb_vtype t, const char *c, const char *m) +{ + mrb_value tmp; + + tmp = mrb_check_convert_type(mrb, val, t, c, m); + if (mrb_nil_p(tmp)) { + mrb_raisef(mrb, E_TYPE_ERROR, "expected %S", mrb_str_new_cstr(mrb, c)); + } + return tmp; +} + +static mrb_value +to_str(mrb_state *mrb, mrb_value val) +{ + return check_type(mrb, val, MRB_TT_STRING, "String", "to_str"); +} + +static mrb_value +to_ary(mrb_state *mrb, mrb_value val) +{ + return check_type(mrb, val, MRB_TT_ARRAY, "Array", "to_ary"); +} + +static mrb_value +to_hash(mrb_state *mrb, mrb_value val) +{ + return check_type(mrb, val, MRB_TT_HASH, "Hash", "to_hash"); +} + +static mrb_sym +to_sym(mrb_state *mrb, mrb_value ss) +{ + if (mrb_type(ss) == MRB_TT_SYMBOL) { + return mrb_symbol(ss); + } + else if (mrb_string_p(ss)) { + return mrb_intern_str(mrb, to_str(mrb, ss)); + } + else { + mrb_value obj = mrb_funcall(mrb, ss, "inspect", 0); + mrb_raisef(mrb, E_TYPE_ERROR, "%S is not a symbol", obj); + /* not reached */ + return 0; + } +} + +/* + retrieve arguments from mrb_state. + + mrb_get_args(mrb, format, ...) + + returns number of arguments parsed. + + format specifiers: + + string mruby type C type note + ---------------------------------------------------------------------------------------------- + o: Object [mrb_value] + C: class/module [mrb_value] + S: String [mrb_value] when ! follows, the value may be nil + A: Array [mrb_value] when ! follows, the value may be nil + H: Hash [mrb_value] when ! follows, the value may be nil + s: String [char*,mrb_int] Receive two arguments; s! gives (NULL,0) for nil + z: String [char*] NUL terminated string; z! gives NULL for nil + a: Array [mrb_value*,mrb_int] Receive two arguments; a! gives (NULL,0) for nil + f: Float [mrb_float] + i: Integer [mrb_int] + b: Boolean [mrb_bool] + n: Symbol [mrb_sym] + d: Data [void*,mrb_data_type const] 2nd argument will be used to check data type so it won't be modified + I: Inline struct [void*] + &: Block [mrb_value] + *: rest argument [mrb_value*,mrb_int] The rest of the arguments as an array; *! avoid copy of the stack + |: optional Following arguments are optional + ?: optional given [mrb_bool] true if preceding argument (optional) is given + */ +MRB_API mrb_int +mrb_get_args(mrb_state *mrb, const char *format, ...) +{ + const char *fmt = format; + char c; + int i = 0; + va_list ap; + int argc = mrb->c->ci->argc; + int arg_i = 0; + mrb_value *array_argv; + mrb_bool opt = FALSE; + mrb_bool opt_skip = TRUE; + mrb_bool given = TRUE; + + va_start(ap, format); + if (argc < 0) { + struct RArray *a = mrb_ary_ptr(mrb->c->stack[1]); + + argc = ARY_LEN(a); + array_argv = ARY_PTR(a); + } + else { + array_argv = NULL; + } + +#define ARGV \ + (array_argv ? array_argv : (mrb->c->stack + 1)) + + while ((c = *fmt++)) { + switch (c) { + case '|': + opt = TRUE; + break; + case '*': + opt_skip = FALSE; + goto check_exit; + case '!': + break; + case '&': case '?': + if (opt) opt_skip = FALSE; + break; + default: + break; + } + } + + check_exit: + opt = FALSE; + i = 0; + while ((c = *format++)) { + switch (c) { + case '|': case '*': case '&': case '?': + break; + default: + if (argc <= i) { + if (opt) { + given = FALSE; + } + else { + mrb_raise(mrb, E_ARGUMENT_ERROR, "wrong number of arguments"); + } + } + break; + } + + switch (c) { + case 'o': + { + mrb_value *p; + + p = va_arg(ap, mrb_value*); + if (i < argc) { + *p = ARGV[arg_i++]; + i++; + } + } + break; + case 'C': + { + mrb_value *p; + + p = va_arg(ap, mrb_value*); + if (i < argc) { + mrb_value ss; + + ss = ARGV[arg_i++]; + if (!class_ptr_p(ss)) { + mrb_raisef(mrb, E_TYPE_ERROR, "%S is not class/module", ss); + } + *p = ss; + i++; + } + } + break; + case 'S': + { + mrb_value *p; + + p = va_arg(ap, mrb_value*); + if (*format == '!') { + format++; + if (i < argc && mrb_nil_p(ARGV[arg_i])) { + *p = ARGV[arg_i++]; + i++; + break; + } + } + if (i < argc) { + *p = to_str(mrb, ARGV[arg_i++]); + i++; + } + } + break; + case 'A': + { + mrb_value *p; + + p = va_arg(ap, mrb_value*); + if (*format == '!') { + format++; + if (i < argc && mrb_nil_p(ARGV[arg_i])) { + *p = ARGV[arg_i++]; + i++; + break; + } + } + if (i < argc) { + *p = to_ary(mrb, ARGV[arg_i++]); + i++; + } + } + break; + case 'H': + { + mrb_value *p; + + p = va_arg(ap, mrb_value*); + if (*format == '!') { + format++; + if (i < argc && mrb_nil_p(ARGV[arg_i])) { + *p = ARGV[arg_i++]; + i++; + break; + } + } + if (i < argc) { + *p = to_hash(mrb, ARGV[arg_i++]); + i++; + } + } + break; + case 's': + { + mrb_value ss; + char **ps = 0; + mrb_int *pl = 0; + + ps = va_arg(ap, char**); + pl = va_arg(ap, mrb_int*); + if (*format == '!') { + format++; + if (i < argc && mrb_nil_p(ARGV[arg_i])) { + *ps = NULL; + *pl = 0; + i++; arg_i++; + break; + } + } + if (i < argc) { + ss = to_str(mrb, ARGV[arg_i++]); + *ps = RSTRING_PTR(ss); + *pl = RSTRING_LEN(ss); + i++; + } + } + break; + case 'z': + { + mrb_value ss; + const char **ps; + + ps = va_arg(ap, const char**); + if (*format == '!') { + format++; + if (i < argc && mrb_nil_p(ARGV[arg_i])) { + *ps = NULL; + i++; arg_i++; + break; + } + } + if (i < argc) { + ss = to_str(mrb, ARGV[arg_i++]); + *ps = mrb_string_value_cstr(mrb, &ss); + i++; + } + } + break; + case 'a': + { + mrb_value aa; + struct RArray *a; + mrb_value **pb; + mrb_int *pl; + + pb = va_arg(ap, mrb_value**); + pl = va_arg(ap, mrb_int*); + if (*format == '!') { + format++; + if (i < argc && mrb_nil_p(ARGV[arg_i])) { + *pb = 0; + *pl = 0; + i++; arg_i++; + break; + } + } + if (i < argc) { + aa = to_ary(mrb, ARGV[arg_i++]); + a = mrb_ary_ptr(aa); + *pb = ARY_PTR(a); + *pl = ARY_LEN(a); + i++; + } + } + break; + case 'I': + { + void* *p; + mrb_value ss; + + p = va_arg(ap, void**); + if (i < argc) { + ss = ARGV[arg_i]; + if (mrb_type(ss) != MRB_TT_ISTRUCT) + { + mrb_raisef(mrb, E_TYPE_ERROR, "%S is not inline struct", ss); + } + *p = mrb_istruct_ptr(ss); + arg_i++; + i++; + } + } + break; + case 'f': + { + mrb_float *p; + + p = va_arg(ap, mrb_float*); + if (i < argc) { + *p = mrb_to_flo(mrb, ARGV[arg_i]); + arg_i++; + i++; + } + } + break; + case 'i': + { + mrb_int *p; + + p = va_arg(ap, mrb_int*); + if (i < argc) { + switch (mrb_type(ARGV[arg_i])) { + case MRB_TT_FIXNUM: + *p = mrb_fixnum(ARGV[arg_i]); + break; + case MRB_TT_FLOAT: + { + mrb_float f = mrb_float(ARGV[arg_i]); + + if (!FIXABLE_FLOAT(f)) { + mrb_raise(mrb, E_RANGE_ERROR, "float too big for int"); + } + *p = (mrb_int)f; + } + break; + case MRB_TT_STRING: + mrb_raise(mrb, E_TYPE_ERROR, "no implicit conversion of String into Integer"); + break; + default: + *p = mrb_fixnum(mrb_Integer(mrb, ARGV[arg_i])); + break; + } + arg_i++; + i++; + } + } + break; + case 'b': + { + mrb_bool *boolp = va_arg(ap, mrb_bool*); + + if (i < argc) { + mrb_value b = ARGV[arg_i++]; + *boolp = mrb_test(b); + i++; + } + } + break; + case 'n': + { + mrb_sym *symp; + + symp = va_arg(ap, mrb_sym*); + if (i < argc) { + mrb_value ss; + + ss = ARGV[arg_i++]; + *symp = to_sym(mrb, ss); + i++; + } + } + break; + case 'd': + { + void** datap; + struct mrb_data_type const* type; + + datap = va_arg(ap, void**); + type = va_arg(ap, struct mrb_data_type const*); + if (*format == '!') { + format++; + if (i < argc && mrb_nil_p(ARGV[arg_i])) { + *datap = 0; + i++; arg_i++; + break; + } + } + if (i < argc) { + *datap = mrb_data_get_ptr(mrb, ARGV[arg_i++], type); + ++i; + } + } + break; + + case '&': + { + mrb_value *p, *bp; + + p = va_arg(ap, mrb_value*); + if (mrb->c->ci->argc < 0) { + bp = mrb->c->stack + 2; + } + else { + bp = mrb->c->stack + mrb->c->ci->argc + 1; + } + *p = *bp; + } + break; + case '|': + if (opt_skip && i == argc) return argc; + opt = TRUE; + break; + case '?': + { + mrb_bool *p; + + p = va_arg(ap, mrb_bool*); + *p = given; + } + break; + + case '*': + { + mrb_value **var; + mrb_int *pl; + mrb_bool nocopy = array_argv ? TRUE : FALSE; + + if (*format == '!') { + format++; + nocopy = TRUE; + } + var = va_arg(ap, mrb_value**); + pl = va_arg(ap, mrb_int*); + if (argc > i) { + *pl = argc-i; + if (*pl > 0) { + if (nocopy) { + *var = ARGV+arg_i; + } + else { + mrb_value args = mrb_ary_new_from_values(mrb, *pl, ARGV+arg_i); + RARRAY(args)->c = NULL; + *var = RARRAY_PTR(args); + } + } + i = argc; + arg_i += *pl; + } + else { + *pl = 0; + *var = NULL; + } + } + break; + default: + mrb_raisef(mrb, E_ARGUMENT_ERROR, "invalid argument specifier %S", mrb_str_new(mrb, &c, 1)); + break; + } + } + +#undef ARGV + + if (!c && argc > i) { + mrb_raise(mrb, E_ARGUMENT_ERROR, "wrong number of arguments"); + } + va_end(ap); + return i; +} + +static struct RClass* +boot_defclass(mrb_state *mrb, struct RClass *super) +{ + struct RClass *c; + + c = (struct RClass*)mrb_obj_alloc(mrb, MRB_TT_CLASS, mrb->class_class); + if (super) { + c->super = super; + mrb_field_write_barrier(mrb, (struct RBasic*)c, (struct RBasic*)super); + } + else { + c->super = mrb->object_class; + } + c->mt = kh_init(mt, mrb); + return c; +} + +static void +boot_initmod(mrb_state *mrb, struct RClass *mod) +{ + if (!mod->mt) { + mod->mt = kh_init(mt, mrb); + } +} + +static struct RClass* +include_class_new(mrb_state *mrb, struct RClass *m, struct RClass *super) +{ + struct RClass *ic = (struct RClass*)mrb_obj_alloc(mrb, MRB_TT_ICLASS, mrb->class_class); + if (m->tt == MRB_TT_ICLASS) { + m = m->c; + } + MRB_CLASS_ORIGIN(m); + ic->iv = m->iv; + ic->mt = m->mt; + ic->super = super; + if (m->tt == MRB_TT_ICLASS) { + ic->c = m->c; + } + else { + ic->c = m; + } + return ic; +} + +static int +include_module_at(mrb_state *mrb, struct RClass *c, struct RClass *ins_pos, struct RClass *m, int search_super) +{ + struct RClass *p, *ic; + void *klass_mt = find_origin(c)->mt; + + while (m) { + int superclass_seen = 0; + + if (m->flags & MRB_FLAG_IS_PREPENDED) + goto skip; + + if (klass_mt && klass_mt == m->mt) + return -1; + + p = c->super; + while (p) { + if (p->tt == MRB_TT_ICLASS) { + if (p->mt == m->mt) { + if (!superclass_seen) { + ins_pos = p; /* move insert point */ + } + goto skip; + } + } else if (p->tt == MRB_TT_CLASS) { + if (!search_super) break; + superclass_seen = 1; + } + p = p->super; + } + + ic = include_class_new(mrb, m, ins_pos->super); + m->flags |= MRB_FLAG_IS_INHERITED; + ins_pos->super = ic; + mrb_field_write_barrier(mrb, (struct RBasic*)ins_pos, (struct RBasic*)ic); + mc_clear_by_class(mrb, ins_pos); + ins_pos = ic; + skip: + m = m->super; + } + mc_clear_all(mrb); + return 0; +} + +MRB_API void +mrb_include_module(mrb_state *mrb, struct RClass *c, struct RClass *m) +{ + int changed = include_module_at(mrb, c, find_origin(c), m, 1); + if (changed < 0) { + mrb_raise(mrb, E_ARGUMENT_ERROR, "cyclic include detected"); + } +} + +MRB_API void +mrb_prepend_module(mrb_state *mrb, struct RClass *c, struct RClass *m) +{ + struct RClass *origin; + int changed = 0; + + if (!(c->flags & MRB_FLAG_IS_PREPENDED)) { + origin = (struct RClass*)mrb_obj_alloc(mrb, MRB_TT_ICLASS, c); + origin->flags |= MRB_FLAG_IS_ORIGIN | MRB_FLAG_IS_INHERITED; + origin->super = c->super; + c->super = origin; + origin->mt = c->mt; + c->mt = kh_init(mt, mrb); + mrb_field_write_barrier(mrb, (struct RBasic*)c, (struct RBasic*)origin); + c->flags |= MRB_FLAG_IS_PREPENDED; + } + changed = include_module_at(mrb, c, c, m, 0); + if (changed < 0) { + mrb_raise(mrb, E_ARGUMENT_ERROR, "cyclic prepend detected"); + } +} + +static mrb_value +mrb_mod_prepend_features(mrb_state *mrb, mrb_value mod) +{ + mrb_value klass; + + mrb_check_type(mrb, mod, MRB_TT_MODULE); + mrb_get_args(mrb, "C", &klass); + mrb_prepend_module(mrb, mrb_class_ptr(klass), mrb_class_ptr(mod)); + return mod; +} + +static mrb_value +mrb_mod_append_features(mrb_state *mrb, mrb_value mod) +{ + mrb_value klass; + + mrb_check_type(mrb, mod, MRB_TT_MODULE); + mrb_get_args(mrb, "C", &klass); + mrb_include_module(mrb, mrb_class_ptr(klass), mrb_class_ptr(mod)); + return mod; +} + +/* 15.2.2.4.28 */ +/* + * call-seq: + * mod.include?(module) -> true or false + * + * Returns true if module is included in + * mod or one of mod's ancestors. + * + * module A + * end + * class B + * include A + * end + * class C < B + * end + * B.include?(A) #=> true + * C.include?(A) #=> true + * A.include?(A) #=> false + */ +static mrb_value +mrb_mod_include_p(mrb_state *mrb, mrb_value mod) +{ + mrb_value mod2; + struct RClass *c = mrb_class_ptr(mod); + + mrb_get_args(mrb, "C", &mod2); + mrb_check_type(mrb, mod2, MRB_TT_MODULE); + + while (c) { + if (c->tt == MRB_TT_ICLASS) { + if (c->c == mrb_class_ptr(mod2)) return mrb_true_value(); + } + c = c->super; + } + return mrb_false_value(); +} + +static mrb_value +mrb_mod_ancestors(mrb_state *mrb, mrb_value self) +{ + mrb_value result; + struct RClass *c = mrb_class_ptr(self); + result = mrb_ary_new(mrb); + while (c) { + if (c->tt == MRB_TT_ICLASS) { + mrb_ary_push(mrb, result, mrb_obj_value(c->c)); + } + else if (!(c->flags & MRB_FLAG_IS_PREPENDED)) { + mrb_ary_push(mrb, result, mrb_obj_value(c)); + } + c = c->super; + } + + return result; +} + +static mrb_value +mrb_mod_extend_object(mrb_state *mrb, mrb_value mod) +{ + mrb_value obj; + + mrb_check_type(mrb, mod, MRB_TT_MODULE); + mrb_get_args(mrb, "o", &obj); + mrb_include_module(mrb, mrb_class_ptr(mrb_singleton_class(mrb, obj)), mrb_class_ptr(mod)); + return mod; +} + +static mrb_value +mrb_mod_included_modules(mrb_state *mrb, mrb_value self) +{ + mrb_value result; + struct RClass *c = mrb_class_ptr(self); + struct RClass *origin = c; + + MRB_CLASS_ORIGIN(origin); + result = mrb_ary_new(mrb); + while (c) { + if (c != origin && c->tt == MRB_TT_ICLASS) { + if (c->c->tt == MRB_TT_MODULE) { + mrb_ary_push(mrb, result, mrb_obj_value(c->c)); + } + } + c = c->super; + } + + return result; +} + +static mrb_value +mrb_mod_initialize(mrb_state *mrb, mrb_value mod) +{ + mrb_value b; + struct RClass *m = mrb_class_ptr(mod); + boot_initmod(mrb, m); /* bootstrap a newly initialized module */ + mrb_get_args(mrb, "|&", &b); + if (!mrb_nil_p(b)) { + mrb_yield_with_class(mrb, b, 1, &mod, mod, m); + } + return mod; +} + +mrb_value mrb_class_instance_method_list(mrb_state*, mrb_bool, struct RClass*, int); + +/* 15.2.2.4.33 */ +/* + * call-seq: + * mod.instance_methods(include_super=true) -> array + * + * Returns an array containing the names of the public and protected instance + * methods in the receiver. For a module, these are the public and protected methods; + * for a class, they are the instance (not singleton) methods. With no + * argument, or with an argument that is false, the + * instance methods in mod are returned, otherwise the methods + * in mod and mod's superclasses are returned. + * + * module A + * def method1() end + * end + * class B + * def method2() end + * end + * class C < B + * def method3() end + * end + * + * A.instance_methods #=> [:method1] + * B.instance_methods(false) #=> [:method2] + * C.instance_methods(false) #=> [:method3] + * C.instance_methods(true).length #=> 43 + */ + +static mrb_value +mrb_mod_instance_methods(mrb_state *mrb, mrb_value mod) +{ + struct RClass *c = mrb_class_ptr(mod); + mrb_bool recur = TRUE; + mrb_get_args(mrb, "|b", &recur); + return mrb_class_instance_method_list(mrb, recur, c, 0); +} + +/* implementation of module_eval/class_eval */ +mrb_value mrb_mod_module_eval(mrb_state*, mrb_value); + +static mrb_value +mrb_mod_dummy_visibility(mrb_state *mrb, mrb_value mod) +{ + return mod; +} + +MRB_API mrb_value +mrb_singleton_class(mrb_state *mrb, mrb_value v) +{ + struct RBasic *obj; + + switch (mrb_type(v)) { + case MRB_TT_FALSE: + if (mrb_nil_p(v)) + return mrb_obj_value(mrb->nil_class); + return mrb_obj_value(mrb->false_class); + case MRB_TT_TRUE: + return mrb_obj_value(mrb->true_class); + case MRB_TT_CPTR: + return mrb_obj_value(mrb->object_class); + case MRB_TT_SYMBOL: + case MRB_TT_FIXNUM: + case MRB_TT_FLOAT: + mrb_raise(mrb, E_TYPE_ERROR, "can't define singleton"); + return mrb_nil_value(); /* not reached */ + default: + break; + } + obj = mrb_basic_ptr(v); + prepare_singleton_class(mrb, obj); + return mrb_obj_value(obj->c); +} + +MRB_API void +mrb_define_singleton_method(mrb_state *mrb, struct RObject *o, const char *name, mrb_func_t func, mrb_aspec aspec) +{ + prepare_singleton_class(mrb, (struct RBasic*)o); + mrb_define_method_id(mrb, o->c, mrb_intern_cstr(mrb, name), func, aspec); +} + +MRB_API void +mrb_define_class_method(mrb_state *mrb, struct RClass *c, const char *name, mrb_func_t func, mrb_aspec aspec) +{ + mrb_define_singleton_method(mrb, (struct RObject*)c, name, func, aspec); +} + +MRB_API void +mrb_define_module_function(mrb_state *mrb, struct RClass *c, const char *name, mrb_func_t func, mrb_aspec aspec) +{ + mrb_define_class_method(mrb, c, name, func, aspec); + mrb_define_method(mrb, c, name, func, aspec); +} + +#ifdef MRB_METHOD_CACHE +static void +mc_clear_all(mrb_state *mrb) +{ + struct mrb_cache_entry *mc = mrb->cache; + int i; + + for (i=0; icache; + int i; + + if (c->flags & MRB_FLAG_IS_INHERITED) { + mc_clear_all(mrb); + c->flags &= ~MRB_FLAG_IS_INHERITED; + return; + } + for (i=0; icache; + int i; + + if (c->flags & MRB_FLAG_IS_INHERITED) { + mc_clear_all(mrb); + c->flags &= ~MRB_FLAG_IS_INHERITED; + return; + } + for (i=0; icache[h]; + + if (mc->c == c && mc->mid == mid) { + return mc->m; + } +#endif + + while (c) { + khash_t(mt) *h = c->mt; + + if (h) { + k = kh_get(mt, mrb, h, mid); + if (k != kh_end(h)) { + m = kh_value(h, k); + if (!m) break; + *cp = c; +#ifdef MRB_METHOD_CACHE + mc->c = oc; + mc->mid = mid; + mc->m = m; +#endif + return m; + } + } + c = c->super; + } + return NULL; /* no method */ +} + +MRB_API struct RProc* +mrb_method_search(mrb_state *mrb, struct RClass* c, mrb_sym mid) +{ + struct RProc *m; + + m = mrb_method_search_vm(mrb, &c, mid); + if (!m) { + mrb_value inspect = mrb_funcall(mrb, mrb_obj_value(c), "inspect", 0); + if (mrb_string_p(inspect) && RSTRING_LEN(inspect) > 64) { + inspect = mrb_any_to_s(mrb, mrb_obj_value(c)); + } + mrb_name_error(mrb, mid, "undefined method '%S' for class %S", + mrb_sym2str(mrb, mid), inspect); + } + return m; +} + +static mrb_value +attr_reader(mrb_state *mrb, mrb_value obj) +{ + mrb_value name = mrb_proc_cfunc_env_get(mrb, 0); + return mrb_iv_get(mrb, obj, to_sym(mrb, name)); +} + +static mrb_value +mrb_mod_attr_reader(mrb_state *mrb, mrb_value mod) +{ + struct RClass *c = mrb_class_ptr(mod); + mrb_value *argv; + mrb_int argc, i; + int ai; + + mrb_get_args(mrb, "*", &argv, &argc); + ai = mrb_gc_arena_save(mrb); + for (i=0; i obj + * + * Creates a new object of class's class, then + * invokes that object's initialize method, + * passing it args. This is the method that ends + * up getting called whenever an object is constructed using + * `.new`. + * + */ + +MRB_API mrb_value +mrb_instance_new(mrb_state *mrb, mrb_value cv) +{ + mrb_value obj, blk; + mrb_value *argv; + mrb_int argc; + mrb_sym init; + + mrb_get_args(mrb, "*&", &argv, &argc, &blk); + obj = mrb_instance_alloc(mrb, cv); + init = mrb_intern_lit(mrb, "initialize"); + if (!mrb_func_basic_p(mrb, obj, init, mrb_bob_init)) { + mrb_funcall_with_block(mrb, obj, init, argc, argv, blk); + } + + return obj; +} + +MRB_API mrb_value +mrb_obj_new(mrb_state *mrb, struct RClass *c, mrb_int argc, const mrb_value *argv) +{ + mrb_value obj; + mrb_sym mid; + + obj = mrb_instance_alloc(mrb, mrb_obj_value(c)); + mid = mrb_intern_lit(mrb, "initialize"); + if (!mrb_func_basic_p(mrb, obj, mid, mrb_bob_init)) { + mrb_funcall_argv(mrb, obj, mid, argc, argv); + } + return obj; +} + +static mrb_value +mrb_class_initialize(mrb_state *mrb, mrb_value c) +{ + mrb_value a, b; + + mrb_get_args(mrb, "|C&", &a, &b); + if (!mrb_nil_p(b)) { + mrb_yield_with_class(mrb, b, 1, &c, c, mrb_class_ptr(c)); + } + return c; +} + +static mrb_value +mrb_class_new_class(mrb_state *mrb, mrb_value cv) +{ + mrb_int n; + mrb_value super, blk; + mrb_value new_class; + mrb_sym mid; + + n = mrb_get_args(mrb, "|C&", &super, &blk); + if (n == 0) { + super = mrb_obj_value(mrb->object_class); + } + new_class = mrb_obj_value(mrb_class_new(mrb, mrb_class_ptr(super))); + mid = mrb_intern_lit(mrb, "initialize"); + if (!mrb_func_basic_p(mrb, new_class, mid, mrb_bob_init)) { + mrb_funcall_with_block(mrb, new_class, mid, n, &super, blk); + } + mrb_class_inherited(mrb, mrb_class_ptr(super), mrb_class_ptr(new_class)); + return new_class; +} + +static mrb_value +mrb_class_superclass(mrb_state *mrb, mrb_value klass) +{ + struct RClass *c; + + c = mrb_class_ptr(klass); + c = find_origin(c)->super; + while (c && c->tt == MRB_TT_ICLASS) { + c = find_origin(c)->super; + } + if (!c) return mrb_nil_value(); + return mrb_obj_value(c); +} + +static mrb_value +mrb_bob_init(mrb_state *mrb, mrb_value cv) +{ + return mrb_nil_value(); +} + +static mrb_value +mrb_bob_not(mrb_state *mrb, mrb_value cv) +{ + return mrb_bool_value(!mrb_test(cv)); +} + +/* 15.3.1.3.1 */ +/* 15.3.1.3.10 */ +/* 15.3.1.3.11 */ +/* + * call-seq: + * obj == other -> true or false + * obj.equal?(other) -> true or false + * obj.eql?(other) -> true or false + * + * Equality---At the Object level, == returns + * true only if obj and other are the + * same object. Typically, this method is overridden in descendant + * classes to provide class-specific meaning. + * + * Unlike ==, the equal? method should never be + * overridden by subclasses: it is used to determine object identity + * (that is, a.equal?(b) iff a is the same + * object as b). + * + * The eql? method returns true if + * obj and anObject have the same value. Used by + * Hash to test members for equality. For objects of + * class Object, eql? is synonymous with + * ==. Subclasses normally continue this tradition, but + * there are exceptions. Numeric types, for example, + * perform type conversion across ==, but not across + * eql?, so: + * + * 1 == 1.0 #=> true + * 1.eql? 1.0 #=> false + */ +mrb_value +mrb_obj_equal_m(mrb_state *mrb, mrb_value self) +{ + mrb_value arg; + + mrb_get_args(mrb, "o", &arg); + return mrb_bool_value(mrb_obj_equal(mrb, self, arg)); +} + +static mrb_value +mrb_obj_not_equal_m(mrb_state *mrb, mrb_value self) +{ + mrb_value arg; + + mrb_get_args(mrb, "o", &arg); + return mrb_bool_value(!mrb_equal(mrb, self, arg)); +} + +MRB_API mrb_bool +mrb_obj_respond_to(mrb_state *mrb, struct RClass* c, mrb_sym mid) +{ + struct RProc *m; + + m = mrb_method_search_vm(mrb, &c, mid); + if (!m) { + return FALSE; + } + return TRUE; +} + +MRB_API mrb_bool +mrb_respond_to(mrb_state *mrb, mrb_value obj, mrb_sym mid) +{ + return mrb_obj_respond_to(mrb, mrb_class(mrb, obj), mid); +} + +MRB_API mrb_value +mrb_class_path(mrb_state *mrb, struct RClass *c) +{ + mrb_value path; + mrb_sym nsym = mrb_intern_lit(mrb, "__classname__"); + + path = mrb_obj_iv_get(mrb, (struct RObject*)c, nsym); + if (mrb_nil_p(path)) { + /* no name (yet) */ + return mrb_class_find_path(mrb, c); + } + else if (mrb_symbol_p(path)) { + /* topleve class/module */ + const char *str; + mrb_int len; + + str = mrb_sym2name_len(mrb, mrb_symbol(path), &len); + return mrb_str_new(mrb, str, len); + } + return mrb_str_dup(mrb, path); +} + +MRB_API struct RClass* +mrb_class_real(struct RClass* cl) +{ + if (cl == 0) + return NULL; + while ((cl->tt == MRB_TT_SCLASS) || (cl->tt == MRB_TT_ICLASS)) { + cl = cl->super; + } + return cl; +} + +MRB_API const char* +mrb_class_name(mrb_state *mrb, struct RClass* c) +{ + mrb_value path = mrb_class_path(mrb, c); + if (mrb_nil_p(path)) { + path = mrb_str_new_lit(mrb, "#"); + } + return RSTRING_PTR(path); +} + +MRB_API const char* +mrb_obj_classname(mrb_state *mrb, mrb_value obj) +{ + return mrb_class_name(mrb, mrb_obj_class(mrb, obj)); +} + +/*! + * Ensures a class can be derived from super. + * + * \param super a reference to an object. + * \exception TypeError if \a super is not a Class or \a super is a singleton class. + */ +static void +mrb_check_inheritable(mrb_state *mrb, struct RClass *super) +{ + if (super->tt != MRB_TT_CLASS) { + mrb_raisef(mrb, E_TYPE_ERROR, "superclass must be a Class (%S given)", mrb_obj_value(super)); + } + if (super->tt == MRB_TT_SCLASS) { + mrb_raise(mrb, E_TYPE_ERROR, "can't make subclass of singleton class"); + } + if (super == mrb->class_class) { + mrb_raise(mrb, E_TYPE_ERROR, "can't make subclass of Class"); + } +} + +/*! + * Creates a new class. + * \param super a class from which the new class derives. + * \exception TypeError \a super is not inheritable. + * \exception TypeError \a super is the Class class. + */ +MRB_API struct RClass* +mrb_class_new(mrb_state *mrb, struct RClass *super) +{ + struct RClass *c; + + if (super) { + mrb_check_inheritable(mrb, super); + } + c = boot_defclass(mrb, super); + if (super) { + MRB_SET_INSTANCE_TT(c, MRB_INSTANCE_TT(super)); + } + make_metaclass(mrb, c); + + return c; +} + +/*! + * Creates a new module. + */ +MRB_API struct RClass* +mrb_module_new(mrb_state *mrb) +{ + struct RClass *m = (struct RClass*)mrb_obj_alloc(mrb, MRB_TT_MODULE, mrb->module_class); + boot_initmod(mrb, m); + return m; +} + +/* + * call-seq: + * obj.class => class + * + * Returns the class of obj, now preferred over + * Object#type, as an object's type in Ruby is only + * loosely tied to that object's class. This method must always be + * called with an explicit receiver, as class is also a + * reserved word in Ruby. + * + * 1.class #=> Fixnum + * self.class #=> Object + */ + +MRB_API struct RClass* +mrb_obj_class(mrb_state *mrb, mrb_value obj) +{ + return mrb_class_real(mrb_class(mrb, obj)); +} + +MRB_API void +mrb_alias_method(mrb_state *mrb, struct RClass *c, mrb_sym a, mrb_sym b) +{ + struct RProc *m = mrb_method_search(mrb, c, b); + + mrb_define_method_raw(mrb, c, a, m); +} + +/*! + * Defines an alias of a method. + * \param klass the class which the original method belongs to + * \param name1 a new name for the method + * \param name2 the original name of the method + */ +MRB_API void +mrb_define_alias(mrb_state *mrb, struct RClass *klass, const char *name1, const char *name2) +{ + mrb_alias_method(mrb, klass, mrb_intern_cstr(mrb, name1), mrb_intern_cstr(mrb, name2)); +} + +/* + * call-seq: + * mod.to_s -> string + * + * Return a string representing this module or class. For basic + * classes and modules, this is the name. For singletons, we + * show information on the thing we're attached to as well. + */ + +static mrb_value +mrb_mod_to_s(mrb_state *mrb, mrb_value klass) +{ + mrb_value str; + + if (mrb_type(klass) == MRB_TT_SCLASS) { + mrb_value v = mrb_iv_get(mrb, klass, mrb_intern_lit(mrb, "__attached__")); + + str = mrb_str_new_lit(mrb, "#"); + } + else { + struct RClass *c; + mrb_value path; + + str = mrb_str_new_capa(mrb, 32); + c = mrb_class_ptr(klass); + path = mrb_class_path(mrb, c); + + if (mrb_nil_p(path)) { + switch (mrb_type(klass)) { + case MRB_TT_CLASS: + mrb_str_cat_lit(mrb, str, "#"); + } + else { + return path; + } + } +} + +static mrb_value +mrb_mod_alias(mrb_state *mrb, mrb_value mod) +{ + struct RClass *c = mrb_class_ptr(mod); + mrb_sym new_name, old_name; + + mrb_get_args(mrb, "nn", &new_name, &old_name); + mrb_alias_method(mrb, c, new_name, old_name); + return mrb_nil_value(); +} + +static void +undef_method(mrb_state *mrb, struct RClass *c, mrb_sym a) +{ + if (!mrb_obj_respond_to(mrb, c, a)) { + mrb_name_error(mrb, a, "undefined method '%S' for class '%S'", mrb_sym2str(mrb, a), mrb_obj_value(c)); + } + else { + mrb_define_method_raw(mrb, c, a, NULL); + } +} + +MRB_API void +mrb_undef_method(mrb_state *mrb, struct RClass *c, const char *name) +{ + undef_method(mrb, c, mrb_intern_cstr(mrb, name)); +} + +MRB_API void +mrb_undef_class_method(mrb_state *mrb, struct RClass *c, const char *name) +{ + mrb_undef_method(mrb, mrb_class_ptr(mrb_singleton_class(mrb, mrb_obj_value(c))), name); +} + +static mrb_value +mrb_mod_undef(mrb_state *mrb, mrb_value mod) +{ + struct RClass *c = mrb_class_ptr(mod); + mrb_int argc; + mrb_value *argv; + + mrb_get_args(mrb, "*", &argv, &argc); + while (argc--) { + undef_method(mrb, c, to_sym(mrb, *argv)); + argv++; + } + return mrb_nil_value(); +} + +static mrb_value +mod_define_method(mrb_state *mrb, mrb_value self) +{ + struct RClass *c = mrb_class_ptr(self); + struct RProc *p; + mrb_sym mid; + mrb_value proc = mrb_undef_value(); + mrb_value blk; + + mrb_get_args(mrb, "n|o&", &mid, &proc, &blk); + switch (mrb_type(proc)) { + case MRB_TT_PROC: + blk = proc; + break; + case MRB_TT_UNDEF: + /* ignored */ + break; + default: + mrb_raisef(mrb, E_TYPE_ERROR, "wrong argument type %S (expected Proc)", mrb_obj_value(mrb_obj_class(mrb, proc))); + break; + } + if (mrb_nil_p(blk)) { + mrb_raise(mrb, E_ARGUMENT_ERROR, "no block given"); + } + p = (struct RProc*)mrb_obj_alloc(mrb, MRB_TT_PROC, mrb->proc_class); + mrb_proc_copy(p, mrb_proc_ptr(blk)); + p->flags |= MRB_PROC_STRICT; + mrb_define_method_raw(mrb, c, mid, p); + return mrb_symbol_value(mid); +} + +static void +check_cv_name_str(mrb_state *mrb, mrb_value str) +{ + const char *s = RSTRING_PTR(str); + mrb_int len = RSTRING_LEN(str); + + if (len < 3 || !(s[0] == '@' && s[1] == '@')) { + mrb_name_error(mrb, mrb_intern_str(mrb, str), "'%S' is not allowed as a class variable name", str); + } +} + +static void +check_cv_name_sym(mrb_state *mrb, mrb_sym id) +{ + check_cv_name_str(mrb, mrb_sym2str(mrb, id)); +} + +/* 15.2.2.4.16 */ +/* + * call-seq: + * obj.class_variable_defined?(symbol) -> true or false + * + * Returns true if the given class variable is defined + * in obj. + * + * class Fred + * @@foo = 99 + * end + * Fred.class_variable_defined?(:@@foo) #=> true + * Fred.class_variable_defined?(:@@bar) #=> false + */ + +static mrb_value +mrb_mod_cvar_defined(mrb_state *mrb, mrb_value mod) +{ + mrb_sym id; + + mrb_get_args(mrb, "n", &id); + check_cv_name_sym(mrb, id); + return mrb_bool_value(mrb_cv_defined(mrb, mod, id)); +} + +/* 15.2.2.4.17 */ +/* + * call-seq: + * mod.class_variable_get(symbol) -> obj + * + * Returns the value of the given class variable (or throws a + * NameError exception). The @@ part of the + * variable name should be included for regular class variables + * + * class Fred + * @@foo = 99 + * end + * Fred.class_variable_get(:@@foo) #=> 99 + */ + +static mrb_value +mrb_mod_cvar_get(mrb_state *mrb, mrb_value mod) +{ + mrb_sym id; + + mrb_get_args(mrb, "n", &id); + check_cv_name_sym(mrb, id); + return mrb_cv_get(mrb, mod, id); +} + +/* 15.2.2.4.18 */ +/* + * call-seq: + * obj.class_variable_set(symbol, obj) -> obj + * + * Sets the class variable names by symbol to + * object. + * + * class Fred + * @@foo = 99 + * def foo + * @@foo + * end + * end + * Fred.class_variable_set(:@@foo, 101) #=> 101 + * Fred.new.foo #=> 101 + */ + +static mrb_value +mrb_mod_cvar_set(mrb_state *mrb, mrb_value mod) +{ + mrb_value value; + mrb_sym id; + + mrb_get_args(mrb, "no", &id, &value); + check_cv_name_sym(mrb, id); + mrb_cv_set(mrb, mod, id, value); + return value; +} + +/* 15.2.2.4.39 */ +/* + * call-seq: + * remove_class_variable(sym) -> obj + * + * Removes the definition of the sym, returning that + * constant's value. + * + * class Dummy + * @@var = 99 + * puts @@var + * p class_variables + * remove_class_variable(:@@var) + * p class_variables + * end + * + * produces: + * + * 99 + * [:@@var] + * [] + */ + +static mrb_value +mrb_mod_remove_cvar(mrb_state *mrb, mrb_value mod) +{ + mrb_value val; + mrb_sym id; + + mrb_get_args(mrb, "n", &id); + check_cv_name_sym(mrb, id); + + val = mrb_iv_remove(mrb, mod, id); + if (!mrb_undef_p(val)) return val; + + if (mrb_cv_defined(mrb, mod, id)) { + mrb_name_error(mrb, id, "cannot remove %S for %S", + mrb_sym2str(mrb, id), mod); + } + + mrb_name_error(mrb, id, "class variable %S not defined for %S", + mrb_sym2str(mrb, id), mod); + + /* not reached */ + return mrb_nil_value(); +} + +/* 15.2.2.4.34 */ +/* + * call-seq: + * mod.method_defined?(symbol) -> true or false + * + * Returns +true+ if the named method is defined by + * _mod_ (or its included modules and, if _mod_ is a class, + * its ancestors). Public and protected methods are matched. + * + * module A + * def method1() end + * end + * class B + * def method2() end + * end + * class C < B + * include A + * def method3() end + * end + * + * A.method_defined? :method1 #=> true + * C.method_defined? "method1" #=> true + * C.method_defined? "method2" #=> true + * C.method_defined? "method3" #=> true + * C.method_defined? "method4" #=> false + */ + +static mrb_value +mrb_mod_method_defined(mrb_state *mrb, mrb_value mod) +{ + mrb_sym id; + + mrb_get_args(mrb, "n", &id); + return mrb_bool_value(mrb_obj_respond_to(mrb, mrb_class_ptr(mod), id)); +} + +static void +remove_method(mrb_state *mrb, mrb_value mod, mrb_sym mid) +{ + struct RClass *c = mrb_class_ptr(mod); + khash_t(mt) *h = find_origin(c)->mt; + khiter_t k; + + if (h) { + k = kh_get(mt, mrb, h, mid); + if (k != kh_end(h)) { + kh_del(mt, mrb, h, k); + mrb_funcall(mrb, mod, "method_removed", 1, mrb_symbol_value(mid)); + return; + } + } + + mrb_name_error(mrb, mid, "method '%S' not defined in %S", + mrb_sym2str(mrb, mid), mod); +} + +/* 15.2.2.4.41 */ +/* + * call-seq: + * remove_method(symbol) -> self + * + * Removes the method identified by _symbol_ from the current + * class. For an example, see Module.undef_method. + */ + +static mrb_value +mrb_mod_remove_method(mrb_state *mrb, mrb_value mod) +{ + mrb_int argc; + mrb_value *argv; + + mrb_get_args(mrb, "*", &argv, &argc); + while (argc--) { + remove_method(mrb, mod, to_sym(mrb, *argv)); + argv++; + } + return mod; +} + + + +static void +check_const_name_str(mrb_state *mrb, mrb_value str) +{ + if (RSTRING_LEN(str) < 1 || !ISUPPER(*RSTRING_PTR(str))) { + mrb_name_error(mrb, mrb_intern_str(mrb, str), "wrong constant name %S", str); + } +} + +static void +check_const_name_sym(mrb_state *mrb, mrb_sym id) +{ + check_const_name_str(mrb, mrb_sym2str(mrb, id)); +} + +static mrb_value +const_defined(mrb_state *mrb, mrb_value mod, mrb_sym id, mrb_bool inherit) +{ + if (inherit) { + return mrb_bool_value(mrb_const_defined(mrb, mod, id)); + } + return mrb_bool_value(mrb_const_defined_at(mrb, mod, id)); +} + +static mrb_value +mrb_mod_const_defined(mrb_state *mrb, mrb_value mod) +{ + mrb_sym id; + mrb_bool inherit = TRUE; + + mrb_get_args(mrb, "n|b", &id, &inherit); + check_const_name_sym(mrb, id); + return const_defined(mrb, mod, id, inherit); +} + +static mrb_value +mrb_const_get_sym(mrb_state *mrb, mrb_value mod, mrb_sym id) +{ + check_const_name_sym(mrb, id); + return mrb_const_get(mrb, mod, id); +} + +static mrb_value +mrb_mod_const_get(mrb_state *mrb, mrb_value mod) +{ + mrb_value path; + mrb_sym id; + char *ptr; + mrb_int off, end, len; + + mrb_get_args(mrb, "o", &path); + + if (mrb_symbol_p(path)) { + /* const get with symbol */ + id = mrb_symbol(path); + return mrb_const_get_sym(mrb, mod, id); + } + + /* const get with class path string */ + path = mrb_string_type(mrb, path); + ptr = RSTRING_PTR(path); + len = RSTRING_LEN(path); + off = 0; + + while (off < len) { + end = mrb_str_index_lit(mrb, path, "::", off); + end = (end == -1) ? len : end; + id = mrb_intern(mrb, ptr+off, end-off); + mod = mrb_const_get_sym(mrb, mod, id); + off = (end == len) ? end : end+2; + } + + return mod; +} + +static mrb_value +mrb_mod_const_set(mrb_state *mrb, mrb_value mod) +{ + mrb_sym id; + mrb_value value; + + mrb_get_args(mrb, "no", &id, &value); + check_const_name_sym(mrb, id); + mrb_const_set(mrb, mod, id, value); + return value; +} + +static mrb_value +mrb_mod_remove_const(mrb_state *mrb, mrb_value mod) +{ + mrb_sym id; + mrb_value val; + + mrb_get_args(mrb, "n", &id); + check_const_name_sym(mrb, id); + val = mrb_iv_remove(mrb, mod, id); + if (mrb_undef_p(val)) { + mrb_name_error(mrb, id, "constant %S not defined", mrb_sym2str(mrb, id)); + } + return val; +} + +static mrb_value +mrb_mod_const_missing(mrb_state *mrb, mrb_value mod) +{ + mrb_sym sym; + + mrb_get_args(mrb, "n", &sym); + + if (mrb_class_real(mrb_class_ptr(mod)) != mrb->object_class) { + mrb_name_error(mrb, sym, "uninitialized constant %S::%S", + mod, + mrb_sym2str(mrb, sym)); + } + else { + mrb_name_error(mrb, sym, "uninitialized constant %S", + mrb_sym2str(mrb, sym)); + } + /* not reached */ + return mrb_nil_value(); +} + +static mrb_value +mrb_mod_s_constants(mrb_state *mrb, mrb_value mod) +{ + mrb_raise(mrb, E_NOTIMP_ERROR, "Module.constants not implemented"); + return mrb_nil_value(); /* not reached */ +} + +static mrb_value +mrb_mod_eqq(mrb_state *mrb, mrb_value mod) +{ + mrb_value obj; + mrb_bool eqq; + + mrb_get_args(mrb, "o", &obj); + eqq = mrb_obj_is_kind_of(mrb, obj, mrb_class_ptr(mod)); + + return mrb_bool_value(eqq); +} + +MRB_API mrb_value +mrb_mod_module_function(mrb_state *mrb, mrb_value mod) +{ + mrb_value *argv; + mrb_int argc, i; + mrb_sym mid; + struct RProc *method_rproc; + struct RClass *rclass; + int ai; + + mrb_check_type(mrb, mod, MRB_TT_MODULE); + + mrb_get_args(mrb, "*", &argv, &argc); + if (argc == 0) { + /* set MODFUNC SCOPE if implemented */ + return mod; + } + + /* set PRIVATE method visibility if implemented */ + /* mrb_mod_dummy_visibility(mrb, mod); */ + + for (i=0; ic, mid, method_rproc); + mrb_gc_arena_restore(mrb, ai); + } + + return mod; +} + +/* implementation of __id__ */ +mrb_value mrb_obj_id_m(mrb_state *mrb, mrb_value self); +/* implementation of instance_eval */ +mrb_value mrb_obj_instance_eval(mrb_state*, mrb_value); +/* implementation of Module.nesting */ +mrb_value mrb_mod_s_nesting(mrb_state*, mrb_value); + +void +mrb_init_class(mrb_state *mrb) +{ + struct RClass *bob; /* BasicObject */ + struct RClass *obj; /* Object */ + struct RClass *mod; /* Module */ + struct RClass *cls; /* Class */ + + /* boot class hierarchy */ + bob = boot_defclass(mrb, 0); + obj = boot_defclass(mrb, bob); mrb->object_class = obj; + mod = boot_defclass(mrb, obj); mrb->module_class = mod;/* obj -> mod */ + cls = boot_defclass(mrb, mod); mrb->class_class = cls; /* obj -> cls */ + /* fix-up loose ends */ + bob->c = obj->c = mod->c = cls->c = cls; + make_metaclass(mrb, bob); + make_metaclass(mrb, obj); + make_metaclass(mrb, mod); + make_metaclass(mrb, cls); + + /* name basic classes */ + mrb_define_const(mrb, bob, "BasicObject", mrb_obj_value(bob)); + mrb_define_const(mrb, obj, "BasicObject", mrb_obj_value(bob)); + mrb_define_const(mrb, obj, "Object", mrb_obj_value(obj)); + mrb_define_const(mrb, obj, "Module", mrb_obj_value(mod)); + mrb_define_const(mrb, obj, "Class", mrb_obj_value(cls)); + + /* name each classes */ + mrb_class_name_class(mrb, NULL, bob, mrb_intern_lit(mrb, "BasicObject")); + mrb_class_name_class(mrb, NULL, obj, mrb_intern_lit(mrb, "Object")); /* 15.2.1 */ + mrb_class_name_class(mrb, NULL, mod, mrb_intern_lit(mrb, "Module")); /* 15.2.2 */ + mrb_class_name_class(mrb, NULL, cls, mrb_intern_lit(mrb, "Class")); /* 15.2.3 */ + + mrb->proc_class = mrb_define_class(mrb, "Proc", mrb->object_class); /* 15.2.17 */ + MRB_SET_INSTANCE_TT(mrb->proc_class, MRB_TT_PROC); + + MRB_SET_INSTANCE_TT(cls, MRB_TT_CLASS); + mrb_define_method(mrb, bob, "initialize", mrb_bob_init, MRB_ARGS_NONE()); + mrb_define_method(mrb, bob, "!", mrb_bob_not, MRB_ARGS_NONE()); + mrb_define_method(mrb, bob, "==", mrb_obj_equal_m, MRB_ARGS_REQ(1)); /* 15.3.1.3.1 */ + mrb_define_method(mrb, bob, "!=", mrb_obj_not_equal_m, MRB_ARGS_REQ(1)); + mrb_define_method(mrb, bob, "__id__", mrb_obj_id_m, MRB_ARGS_NONE()); /* 15.3.1.3.3 */ + mrb_define_method(mrb, bob, "__send__", mrb_f_send, MRB_ARGS_ANY()); /* 15.3.1.3.4 */ + mrb_define_method(mrb, bob, "instance_eval", mrb_obj_instance_eval, MRB_ARGS_ANY()); /* 15.3.1.3.18 */ + + mrb_define_class_method(mrb, cls, "new", mrb_class_new_class, MRB_ARGS_OPT(1)); + mrb_define_method(mrb, cls, "superclass", mrb_class_superclass, MRB_ARGS_NONE()); /* 15.2.3.3.4 */ + mrb_define_method(mrb, cls, "new", mrb_instance_new, MRB_ARGS_ANY()); /* 15.2.3.3.3 */ + mrb_define_method(mrb, cls, "initialize", mrb_class_initialize, MRB_ARGS_OPT(1)); /* 15.2.3.3.1 */ + mrb_define_method(mrb, cls, "inherited", mrb_bob_init, MRB_ARGS_REQ(1)); + + MRB_SET_INSTANCE_TT(mod, MRB_TT_MODULE); + mrb_define_method(mrb, mod, "class_variable_defined?", mrb_mod_cvar_defined, MRB_ARGS_REQ(1)); /* 15.2.2.4.16 */ + mrb_define_method(mrb, mod, "class_variable_get", mrb_mod_cvar_get, MRB_ARGS_REQ(1)); /* 15.2.2.4.17 */ + mrb_define_method(mrb, mod, "class_variable_set", mrb_mod_cvar_set, MRB_ARGS_REQ(2)); /* 15.2.2.4.18 */ + mrb_define_method(mrb, mod, "extend_object", mrb_mod_extend_object, MRB_ARGS_REQ(1)); /* 15.2.2.4.25 */ + mrb_define_method(mrb, mod, "extended", mrb_bob_init, MRB_ARGS_REQ(1)); /* 15.2.2.4.26 */ + mrb_define_method(mrb, mod, "prepended", mrb_bob_init, MRB_ARGS_REQ(1)); + mrb_define_method(mrb, mod, "prepend_features", mrb_mod_prepend_features, MRB_ARGS_REQ(1)); + mrb_define_method(mrb, mod, "include?", mrb_mod_include_p, MRB_ARGS_REQ(1)); /* 15.2.2.4.28 */ + mrb_define_method(mrb, mod, "append_features", mrb_mod_append_features, MRB_ARGS_REQ(1)); /* 15.2.2.4.10 */ + mrb_define_method(mrb, mod, "class_eval", mrb_mod_module_eval, MRB_ARGS_ANY()); /* 15.2.2.4.15 */ + mrb_define_method(mrb, mod, "included", mrb_bob_init, MRB_ARGS_REQ(1)); /* 15.2.2.4.29 */ + mrb_define_method(mrb, mod, "included_modules", mrb_mod_included_modules, MRB_ARGS_NONE()); /* 15.2.2.4.30 */ + mrb_define_method(mrb, mod, "initialize", mrb_mod_initialize, MRB_ARGS_NONE()); /* 15.2.2.4.31 */ + mrb_define_method(mrb, mod, "instance_methods", mrb_mod_instance_methods, MRB_ARGS_ANY()); /* 15.2.2.4.33 */ + mrb_define_method(mrb, mod, "method_defined?", mrb_mod_method_defined, MRB_ARGS_REQ(1)); /* 15.2.2.4.34 */ + mrb_define_method(mrb, mod, "module_eval", mrb_mod_module_eval, MRB_ARGS_ANY()); /* 15.2.2.4.35 */ + mrb_define_method(mrb, mod, "module_function", mrb_mod_module_function, MRB_ARGS_ANY()); + mrb_define_method(mrb, mod, "private", mrb_mod_dummy_visibility, MRB_ARGS_ANY()); /* 15.2.2.4.36 */ + mrb_define_method(mrb, mod, "protected", mrb_mod_dummy_visibility, MRB_ARGS_ANY()); /* 15.2.2.4.37 */ + mrb_define_method(mrb, mod, "public", mrb_mod_dummy_visibility, MRB_ARGS_ANY()); /* 15.2.2.4.38 */ + mrb_define_method(mrb, mod, "remove_class_variable", mrb_mod_remove_cvar, MRB_ARGS_REQ(1)); /* 15.2.2.4.39 */ + mrb_define_method(mrb, mod, "remove_method", mrb_mod_remove_method, MRB_ARGS_ANY()); /* 15.2.2.4.41 */ + mrb_define_method(mrb, mod, "method_removed", mrb_bob_init, MRB_ARGS_REQ(1)); + mrb_define_method(mrb, mod, "attr_reader", mrb_mod_attr_reader, MRB_ARGS_ANY()); /* 15.2.2.4.13 */ + mrb_define_method(mrb, mod, "attr_writer", mrb_mod_attr_writer, MRB_ARGS_ANY()); /* 15.2.2.4.14 */ + mrb_define_method(mrb, mod, "to_s", mrb_mod_to_s, MRB_ARGS_NONE()); + mrb_define_method(mrb, mod, "inspect", mrb_mod_to_s, MRB_ARGS_NONE()); + mrb_define_method(mrb, mod, "alias_method", mrb_mod_alias, MRB_ARGS_ANY()); /* 15.2.2.4.8 */ + mrb_define_method(mrb, mod, "ancestors", mrb_mod_ancestors, MRB_ARGS_NONE()); /* 15.2.2.4.9 */ + mrb_define_method(mrb, mod, "undef_method", mrb_mod_undef, MRB_ARGS_ANY()); /* 15.2.2.4.41 */ + mrb_define_method(mrb, mod, "const_defined?", mrb_mod_const_defined, MRB_ARGS_ARG(1,1)); /* 15.2.2.4.20 */ + mrb_define_method(mrb, mod, "const_get", mrb_mod_const_get, MRB_ARGS_REQ(1)); /* 15.2.2.4.21 */ + mrb_define_method(mrb, mod, "const_set", mrb_mod_const_set, MRB_ARGS_REQ(2)); /* 15.2.2.4.23 */ + mrb_define_method(mrb, mod, "constants", mrb_mod_constants, MRB_ARGS_OPT(1)); /* 15.2.2.4.24 */ + mrb_define_method(mrb, mod, "remove_const", mrb_mod_remove_const, MRB_ARGS_REQ(1)); /* 15.2.2.4.40 */ + mrb_define_method(mrb, mod, "const_missing", mrb_mod_const_missing, MRB_ARGS_REQ(1)); + mrb_define_method(mrb, mod, "define_method", mod_define_method, MRB_ARGS_ARG(1,1)); + mrb_define_method(mrb, mod, "class_variables", mrb_mod_class_variables, MRB_ARGS_NONE()); /* 15.2.2.4.19 */ + mrb_define_method(mrb, mod, "===", mrb_mod_eqq, MRB_ARGS_REQ(1)); + mrb_define_class_method(mrb, mod, "constants", mrb_mod_s_constants, MRB_ARGS_ANY()); /* 15.2.2.3.1 */ + mrb_define_class_method(mrb, mod, "nesting", mrb_mod_s_nesting, MRB_ARGS_REQ(0)); /* 15.2.2.3.2 */ + + mrb_undef_method(mrb, cls, "append_features"); + mrb_undef_method(mrb, cls, "extend_object"); +} diff --git a/web/server/h2o/libh2o/deps/mruby/src/codedump.c b/web/server/h2o/libh2o/deps/mruby/src/codedump.c new file mode 100644 index 00000000..e3a33419 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/src/codedump.c @@ -0,0 +1,474 @@ +#include +#include +#include +#include +#include +#include + +#ifndef MRB_DISABLE_STDIO +static int +print_r(mrb_state *mrb, mrb_irep *irep, size_t n, int pre) +{ + size_t i; + + if (n == 0) return 0; + + for (i=0; i+1nlocals; i++) { + if (irep->lv[i].r == n) { + mrb_sym sym = irep->lv[i].name; + if (pre) printf(" "); + printf("R%d:%s", (int)n, mrb_sym2name(mrb, sym)); + return 1; + } + } + return 0; +} + +#define RA 1 +#define RB 2 +#define RAB 3 + +static void +print_lv(mrb_state *mrb, mrb_irep *irep, mrb_code c, int r) +{ + int pre = 0; + + if (!irep->lv + || ((!(r & RA) || GETARG_A(c) >= irep->nlocals) + && (!(r & RB) || GETARG_B(c) >= irep->nlocals))) { + printf("\n"); + return; + } + printf("\t; "); + if (r & RA) { + pre = print_r(mrb, irep, GETARG_A(c), 0); + } + if (r & RB) { + print_r(mrb, irep, GETARG_B(c), pre); + } + printf("\n"); +} +#endif + +static void +codedump(mrb_state *mrb, mrb_irep *irep) +{ +#ifndef MRB_DISABLE_STDIO + int i; + int ai; + mrb_code c; + const char *file = NULL, *next_file; + int32_t line; + + if (!irep) return; + printf("irep %p nregs=%d nlocals=%d pools=%d syms=%d reps=%d\n", (void*)irep, + irep->nregs, irep->nlocals, (int)irep->plen, (int)irep->slen, (int)irep->rlen); + + for (i = 0; i < (int)irep->ilen; i++) { + ai = mrb_gc_arena_save(mrb); + + next_file = mrb_debug_get_filename(irep, i); + if (next_file && file != next_file) { + printf("file: %s\n", next_file); + file = next_file; + } + line = mrb_debug_get_line(irep, i); + if (line < 0) { + printf(" "); + } + else { + printf("%5d ", line); + } + + printf("%03d ", i); + c = irep->iseq[i]; + switch (GET_OPCODE(c)) { + case OP_NOP: + printf("OP_NOP\n"); + break; + case OP_MOVE: + printf("OP_MOVE\tR%d\tR%d\t", GETARG_A(c), GETARG_B(c)); + print_lv(mrb, irep, c, RAB); + break; + case OP_LOADL: + { + mrb_value v = irep->pool[GETARG_Bx(c)]; + mrb_value s = mrb_inspect(mrb, v); + printf("OP_LOADL\tR%d\tL(%d)\t; %s", GETARG_A(c), GETARG_Bx(c), RSTRING_PTR(s)); + } + print_lv(mrb, irep, c, RA); + break; + case OP_LOADI: + printf("OP_LOADI\tR%d\t%d\t", GETARG_A(c), GETARG_sBx(c)); + print_lv(mrb, irep, c, RA); + break; + case OP_LOADSYM: + printf("OP_LOADSYM\tR%d\t:%s", GETARG_A(c), + mrb_sym2name(mrb, irep->syms[GETARG_Bx(c)])); + print_lv(mrb, irep, c, RA); + break; + case OP_LOADNIL: + printf("OP_LOADNIL\tR%d\t\t", GETARG_A(c)); + print_lv(mrb, irep, c, RA); + break; + case OP_LOADSELF: + printf("OP_LOADSELF\tR%d\t\t", GETARG_A(c)); + print_lv(mrb, irep, c, RA); + break; + case OP_LOADT: + printf("OP_LOADT\tR%d\t\t", GETARG_A(c)); + print_lv(mrb, irep, c, RA); + break; + case OP_LOADF: + printf("OP_LOADF\tR%d\t\t", GETARG_A(c)); + print_lv(mrb, irep, c, RA); + break; + case OP_GETGLOBAL: + printf("OP_GETGLOBAL\tR%d\t:%s", GETARG_A(c), + mrb_sym2name(mrb, irep->syms[GETARG_Bx(c)])); + print_lv(mrb, irep, c, RA); + break; + case OP_SETGLOBAL: + printf("OP_SETGLOBAL\t:%s\tR%d\t", + mrb_sym2name(mrb, irep->syms[GETARG_Bx(c)]), + GETARG_A(c)); + print_lv(mrb, irep, c, RA); + break; + case OP_GETCONST: + printf("OP_GETCONST\tR%d\t:%s", GETARG_A(c), + mrb_sym2name(mrb, irep->syms[GETARG_Bx(c)])); + print_lv(mrb, irep, c, RA); + break; + case OP_SETCONST: + printf("OP_SETCONST\t:%s\tR%d\t", + mrb_sym2name(mrb, irep->syms[GETARG_Bx(c)]), + GETARG_A(c)); + print_lv(mrb, irep, c, RA); + break; + case OP_GETMCNST: + printf("OP_GETMCNST\tR%d\tR%d::%s", GETARG_A(c), GETARG_A(c), + mrb_sym2name(mrb, irep->syms[GETARG_Bx(c)])); + print_lv(mrb, irep, c, RAB); + break; + case OP_SETMCNST: + printf("OP_SETMCNST\tR%d::%s\tR%d", GETARG_A(c)+1, + mrb_sym2name(mrb, irep->syms[GETARG_Bx(c)]), + GETARG_A(c)); + print_lv(mrb, irep, c, RA); + break; + case OP_GETIV: + printf("OP_GETIV\tR%d\t%s", GETARG_A(c), + mrb_sym2name(mrb, irep->syms[GETARG_Bx(c)])); + print_lv(mrb, irep, c, RA); + break; + case OP_SETIV: + printf("OP_SETIV\t%s\tR%d", + mrb_sym2name(mrb, irep->syms[GETARG_Bx(c)]), + GETARG_A(c)); + print_lv(mrb, irep, c, RA); + break; + case OP_GETUPVAR: + printf("OP_GETUPVAR\tR%d\t%d\t%d", + GETARG_A(c), GETARG_B(c), GETARG_C(c)); + print_lv(mrb, irep, c, RA); + break; + case OP_SETUPVAR: + printf("OP_SETUPVAR\tR%d\t%d\t%d", + GETARG_A(c), GETARG_B(c), GETARG_C(c)); + print_lv(mrb, irep, c, RA); + break; + case OP_GETCV: + printf("OP_GETCV\tR%d\t%s", GETARG_A(c), + mrb_sym2name(mrb, irep->syms[GETARG_Bx(c)])); + print_lv(mrb, irep, c, RA); + break; + case OP_SETCV: + printf("OP_SETCV\t%s\tR%d", + mrb_sym2name(mrb, irep->syms[GETARG_Bx(c)]), + GETARG_A(c)); + print_lv(mrb, irep, c, RA); + break; + case OP_JMP: + printf("OP_JMP\t%03d\n", i+GETARG_sBx(c)); + break; + case OP_JMPIF: + printf("OP_JMPIF\tR%d\t%03d\n", GETARG_A(c), i+GETARG_sBx(c)); + break; + case OP_JMPNOT: + printf("OP_JMPNOT\tR%d\t%03d\n", GETARG_A(c), i+GETARG_sBx(c)); + break; + case OP_SEND: + printf("OP_SEND\tR%d\t:%s\t%d\n", GETARG_A(c), + mrb_sym2name(mrb, irep->syms[GETARG_B(c)]), + GETARG_C(c)); + break; + case OP_SENDB: + printf("OP_SENDB\tR%d\t:%s\t%d\n", GETARG_A(c), + mrb_sym2name(mrb, irep->syms[GETARG_B(c)]), + GETARG_C(c)); + break; + case OP_TAILCALL: + printf("OP_TAILCALL\tR%d\t:%s\t%d\n", GETARG_A(c), + mrb_sym2name(mrb, irep->syms[GETARG_B(c)]), + GETARG_C(c)); + break; + case OP_SUPER: + printf("OP_SUPER\tR%d\t%d\n", GETARG_A(c), + GETARG_C(c)); + break; + case OP_ARGARY: + printf("OP_ARGARY\tR%d\t%d:%d:%d:%d", GETARG_A(c), + (GETARG_Bx(c)>>10)&0x3f, + (GETARG_Bx(c)>>9)&0x1, + (GETARG_Bx(c)>>4)&0x1f, + (GETARG_Bx(c)>>0)&0xf); + print_lv(mrb, irep, c, RA); + break; + + case OP_ENTER: + printf("OP_ENTER\t%d:%d:%d:%d:%d:%d:%d\n", + (GETARG_Ax(c)>>18)&0x1f, + (GETARG_Ax(c)>>13)&0x1f, + (GETARG_Ax(c)>>12)&0x1, + (GETARG_Ax(c)>>7)&0x1f, + (GETARG_Ax(c)>>2)&0x1f, + (GETARG_Ax(c)>>1)&0x1, + GETARG_Ax(c) & 0x1); + break; + case OP_RETURN: + printf("OP_RETURN\tR%d", GETARG_A(c)); + switch (GETARG_B(c)) { + case OP_R_NORMAL: + printf("\tnormal\t"); break; + case OP_R_RETURN: + printf("\treturn\t"); break; + case OP_R_BREAK: + printf("\tbreak\t"); break; + default: + printf("\tbroken\t"); break; + } + print_lv(mrb, irep, c, RA); + break; + case OP_BLKPUSH: + printf("OP_BLKPUSH\tR%d\t%d:%d:%d:%d", GETARG_A(c), + (GETARG_Bx(c)>>10)&0x3f, + (GETARG_Bx(c)>>9)&0x1, + (GETARG_Bx(c)>>4)&0x1f, + (GETARG_Bx(c)>>0)&0xf); + print_lv(mrb, irep, c, RA); + break; + + case OP_LAMBDA: + printf("OP_LAMBDA\tR%d\tI(%+d)\t", GETARG_A(c), GETARG_b(c)+1); + switch (GETARG_c(c)) { + case OP_L_METHOD: + printf("method"); break; + case OP_L_BLOCK: + printf("block"); break; + case OP_L_LAMBDA: + printf("lambda"); break; + } + print_lv(mrb, irep, c, RA); + break; + case OP_RANGE: + printf("OP_RANGE\tR%d\tR%d\t%d", GETARG_A(c), GETARG_B(c), GETARG_C(c)); + print_lv(mrb, irep, c, RAB); + break; + case OP_METHOD: + printf("OP_METHOD\tR%d\t:%s", GETARG_A(c), + mrb_sym2name(mrb, irep->syms[GETARG_B(c)])); + print_lv(mrb, irep, c, RA); + break; + + case OP_ADD: + printf("OP_ADD\tR%d\t:%s\t%d\n", GETARG_A(c), + mrb_sym2name(mrb, irep->syms[GETARG_B(c)]), + GETARG_C(c)); + break; + case OP_ADDI: + printf("OP_ADDI\tR%d\t:%s\t%d\n", GETARG_A(c), + mrb_sym2name(mrb, irep->syms[GETARG_B(c)]), + GETARG_C(c)); + break; + case OP_SUB: + printf("OP_SUB\tR%d\t:%s\t%d\n", GETARG_A(c), + mrb_sym2name(mrb, irep->syms[GETARG_B(c)]), + GETARG_C(c)); + break; + case OP_SUBI: + printf("OP_SUBI\tR%d\t:%s\t%d\n", GETARG_A(c), + mrb_sym2name(mrb, irep->syms[GETARG_B(c)]), + GETARG_C(c)); + break; + case OP_MUL: + printf("OP_MUL\tR%d\t:%s\t%d\n", GETARG_A(c), + mrb_sym2name(mrb, irep->syms[GETARG_B(c)]), + GETARG_C(c)); + break; + case OP_DIV: + printf("OP_DIV\tR%d\t:%s\t%d\n", GETARG_A(c), + mrb_sym2name(mrb, irep->syms[GETARG_B(c)]), + GETARG_C(c)); + break; + case OP_LT: + printf("OP_LT\tR%d\t:%s\t%d\n", GETARG_A(c), + mrb_sym2name(mrb, irep->syms[GETARG_B(c)]), + GETARG_C(c)); + break; + case OP_LE: + printf("OP_LE\tR%d\t:%s\t%d\n", GETARG_A(c), + mrb_sym2name(mrb, irep->syms[GETARG_B(c)]), + GETARG_C(c)); + break; + case OP_GT: + printf("OP_GT\tR%d\t:%s\t%d\n", GETARG_A(c), + mrb_sym2name(mrb, irep->syms[GETARG_B(c)]), + GETARG_C(c)); + break; + case OP_GE: + printf("OP_GE\tR%d\t:%s\t%d\n", GETARG_A(c), + mrb_sym2name(mrb, irep->syms[GETARG_B(c)]), + GETARG_C(c)); + break; + case OP_EQ: + printf("OP_EQ\t\tR%d\t:%s\t%d\n", GETARG_A(c), + mrb_sym2name(mrb, irep->syms[GETARG_B(c)]), + GETARG_C(c)); + break; + + case OP_STOP: + printf("OP_STOP\n"); + break; + + case OP_ARRAY: + printf("OP_ARRAY\tR%d\tR%d\t%d", GETARG_A(c), GETARG_B(c), GETARG_C(c)); + print_lv(mrb, irep, c, RAB); + break; + case OP_ARYCAT: + printf("OP_ARYCAT\tR%d\tR%d\t", GETARG_A(c), GETARG_B(c)); + print_lv(mrb, irep, c, RAB); + break; + case OP_ARYPUSH: + printf("OP_ARYPUSH\tR%d\tR%d\t", GETARG_A(c), GETARG_B(c)); + print_lv(mrb, irep, c, RAB); + break; + case OP_AREF: + printf("OP_AREF\tR%d\tR%d\t%d", GETARG_A(c), GETARG_B(c), GETARG_C(c)); + print_lv(mrb, irep, c, RAB); + break; + case OP_APOST: + printf("OP_APOST\tR%d\t%d\t%d", GETARG_A(c), GETARG_B(c), GETARG_C(c)); + print_lv(mrb, irep, c, RA); + break; + case OP_STRING: + { + mrb_value v = irep->pool[GETARG_Bx(c)]; + mrb_value s = mrb_str_dump(mrb, mrb_str_new(mrb, RSTRING_PTR(v), RSTRING_LEN(v))); + printf("OP_STRING\tR%d\tL(%d)\t; %s", GETARG_A(c), GETARG_Bx(c), RSTRING_PTR(s)); + } + print_lv(mrb, irep, c, RA); + break; + case OP_STRCAT: + printf("OP_STRCAT\tR%d\tR%d\t", GETARG_A(c), GETARG_B(c)); + print_lv(mrb, irep, c, RAB); + break; + case OP_HASH: + printf("OP_HASH\tR%d\tR%d\t%d", GETARG_A(c), GETARG_B(c), GETARG_C(c)); + print_lv(mrb, irep, c, RAB); + break; + + case OP_OCLASS: + printf("OP_OCLASS\tR%d\t\t", GETARG_A(c)); + print_lv(mrb, irep, c, RA); + break; + case OP_CLASS: + printf("OP_CLASS\tR%d\t:%s", GETARG_A(c), + mrb_sym2name(mrb, irep->syms[GETARG_B(c)])); + print_lv(mrb, irep, c, RA); + break; + case OP_MODULE: + printf("OP_MODULE\tR%d\t:%s", GETARG_A(c), + mrb_sym2name(mrb, irep->syms[GETARG_B(c)])); + print_lv(mrb, irep, c, RA); + break; + case OP_EXEC: + printf("OP_EXEC\tR%d\tI(%+d)", GETARG_A(c), GETARG_Bx(c)+1); + print_lv(mrb, irep, c, RA); + break; + case OP_SCLASS: + printf("OP_SCLASS\tR%d\tR%d\t", GETARG_A(c), GETARG_B(c)); + print_lv(mrb, irep, c, RAB); + break; + case OP_TCLASS: + printf("OP_TCLASS\tR%d\t\t", GETARG_A(c)); + print_lv(mrb, irep, c, RA); + break; + case OP_ERR: + { + mrb_value v = irep->pool[GETARG_Bx(c)]; + mrb_value s = mrb_str_dump(mrb, mrb_str_new(mrb, RSTRING_PTR(v), RSTRING_LEN(v))); + printf("OP_ERR\t%s\n", RSTRING_PTR(s)); + } + break; + case OP_EPUSH: + printf("OP_EPUSH\t:I(%+d)\n", GETARG_Bx(c)+1); + break; + case OP_ONERR: + printf("OP_ONERR\t%03d\n", i+GETARG_sBx(c)); + break; + case OP_RESCUE: + { + int a = GETARG_A(c); + int b = GETARG_B(c); + int cnt = GETARG_C(c); + + if (b == 0) { + printf("OP_RESCUE\tR%d\t\t%s", a, cnt ? "cont" : ""); + print_lv(mrb, irep, c, RA); + break; + } + else { + printf("OP_RESCUE\tR%d\tR%d\t%s", a, b, cnt ? "cont" : ""); + print_lv(mrb, irep, c, RAB); + break; + } + } + break; + case OP_RAISE: + printf("OP_RAISE\tR%d\t\t", GETARG_A(c)); + print_lv(mrb, irep, c, RA); + break; + case OP_POPERR: + printf("OP_POPERR\t%d\t\t\n", GETARG_A(c)); + break; + case OP_EPOP: + printf("OP_EPOP\t%d\n", GETARG_A(c)); + break; + + default: + printf("OP_unknown %d\t%d\t%d\t%d\n", GET_OPCODE(c), + GETARG_A(c), GETARG_B(c), GETARG_C(c)); + break; + } + mrb_gc_arena_restore(mrb, ai); + } + printf("\n"); +#endif +} + +static void +codedump_recur(mrb_state *mrb, mrb_irep *irep) +{ + int i; + + codedump(mrb, irep); + for (i=0; irlen; i++) { + codedump_recur(mrb, irep->reps[i]); + } +} + +void +mrb_codedump_all(mrb_state *mrb, struct RProc *proc) +{ + codedump_recur(mrb, proc->body.irep); +} diff --git a/web/server/h2o/libh2o/deps/mruby/src/compar.c b/web/server/h2o/libh2o/deps/mruby/src/compar.c new file mode 100644 index 00000000..0032fc85 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/src/compar.c @@ -0,0 +1,13 @@ +/* +** compar.c - Comparable module +** +** See Copyright Notice in mruby.h +*/ + +#include + +void +mrb_init_comparable(mrb_state *mrb) +{ + mrb_define_module(mrb, "Comparable"); /* 15.3.3 */ +} diff --git a/web/server/h2o/libh2o/deps/mruby/src/crc.c b/web/server/h2o/libh2o/deps/mruby/src/crc.c new file mode 100644 index 00000000..290b2ca0 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/src/crc.c @@ -0,0 +1,39 @@ +/* +** crc.c - calculate CRC +** +** See Copyright Notice in mruby.h +*/ + +#include +#include +#include + +/* Calculate CRC (CRC-16-CCITT) +** +** 0000_0000_0000_0000_0000_0000_0000_0000 +** ^|------- CRC -------|- work --| +** carry +*/ +#define CRC_16_CCITT 0x11021ul /* x^16+x^12+x^5+1 */ +#define CRC_XOR_PATTERN (CRC_16_CCITT << 8) +#define CRC_CARRY_BIT (0x01000000) + +uint16_t +calc_crc_16_ccitt(const uint8_t *src, size_t nbytes, uint16_t crc) +{ + size_t ibyte; + uint32_t ibit; + uint32_t crcwk = crc << 8; + + for (ibyte = 0; ibyte < nbytes; ibyte++) { + crcwk |= *src++; + for (ibit = 0; ibit < CHAR_BIT; ibit++) { + crcwk <<= 1; + if (crcwk & CRC_CARRY_BIT) { + crcwk ^= CRC_XOR_PATTERN; + } + } + } + return (uint16_t)(crcwk >> 8); +} + diff --git a/web/server/h2o/libh2o/deps/mruby/src/debug.c b/web/server/h2o/libh2o/deps/mruby/src/debug.c new file mode 100644 index 00000000..e55f11d4 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/src/debug.c @@ -0,0 +1,217 @@ +#include +#include +#include +#include + +static mrb_irep_debug_info_file* +get_file(mrb_irep_debug_info *info, uint32_t pc) +{ + mrb_irep_debug_info_file **ret; + int32_t count; + + if (pc >= info->pc_count) { return NULL; } + /* get upper bound */ + ret = info->files; + count = info->flen; + while (count > 0) { + int32_t step = count / 2; + mrb_irep_debug_info_file **it = ret + step; + if (!(pc < (*it)->start_pos)) { + ret = it + 1; + count -= step + 1; + } + else { count = step; } + } + + --ret; + + /* check returning file exists inside debug info */ + mrb_assert(info->files <= ret && ret < (info->files + info->flen)); + /* check pc is within the range of returning file */ + mrb_assert((*ret)->start_pos <= pc && + pc < (((ret + 1 - info->files) < info->flen) + ? (*(ret+1))->start_pos : info->pc_count)); + + return *ret; +} + +static mrb_debug_line_type +select_line_type(const uint16_t *lines, size_t lines_len) +{ + size_t line_count = 0; + int prev_line = -1; + size_t i; + for (i = 0; i < lines_len; ++i) { + if (lines[i] != prev_line) { + ++line_count; + } + } + return (sizeof(uint16_t) * lines_len) <= (sizeof(mrb_irep_debug_info_line) * line_count) + ? mrb_debug_line_ary : mrb_debug_line_flat_map; +} + +MRB_API char const* +mrb_debug_get_filename(mrb_irep *irep, ptrdiff_t pc) +{ + if (irep && pc >= 0 && pc < irep->ilen) { + mrb_irep_debug_info_file* f = NULL; + if (!irep->debug_info) { return irep->filename; } + else if ((f = get_file(irep->debug_info, (uint32_t)pc))) { + return f->filename; + } + } + return NULL; +} + +MRB_API int32_t +mrb_debug_get_line(mrb_irep *irep, ptrdiff_t pc) +{ + if (irep && pc >= 0 && pc < irep->ilen) { + mrb_irep_debug_info_file* f = NULL; + if (!irep->debug_info) { + return irep->lines? irep->lines[pc] : -1; + } + else if ((f = get_file(irep->debug_info, (uint32_t)pc))) { + switch (f->line_type) { + case mrb_debug_line_ary: + mrb_assert(f->start_pos <= pc && pc < (f->start_pos + f->line_entry_count)); + return f->lines.ary[pc - f->start_pos]; + + case mrb_debug_line_flat_map: { + /* get upper bound */ + mrb_irep_debug_info_line *ret = f->lines.flat_map; + uint32_t count = f->line_entry_count; + while (count > 0) { + int32_t step = count / 2; + mrb_irep_debug_info_line *it = ret + step; + if (!(pc < it->start_pos)) { + ret = it + 1; + count -= step + 1; + } + else { count = step; } + } + + --ret; + + /* check line entry pointer range */ + mrb_assert(f->lines.flat_map <= ret && ret < (f->lines.flat_map + f->line_entry_count)); + /* check pc range */ + mrb_assert(ret->start_pos <= pc && + pc < (((uint32_t)(ret + 1 - f->lines.flat_map) < f->line_entry_count) + ? (ret+1)->start_pos : irep->debug_info->pc_count)); + + return ret->line; + } + } + } + } + return -1; +} + +MRB_API mrb_irep_debug_info* +mrb_debug_info_alloc(mrb_state *mrb, mrb_irep *irep) +{ + static const mrb_irep_debug_info initial = { 0, 0, NULL }; + mrb_irep_debug_info *ret; + + mrb_assert(!irep->debug_info); + ret = (mrb_irep_debug_info *)mrb_malloc(mrb, sizeof(*ret)); + *ret = initial; + irep->debug_info = ret; + return ret; +} + +MRB_API mrb_irep_debug_info_file* +mrb_debug_info_append_file(mrb_state *mrb, mrb_irep *irep, + uint32_t start_pos, uint32_t end_pos) +{ + mrb_irep_debug_info *info; + mrb_irep_debug_info_file *ret; + uint32_t file_pc_count; + size_t fn_len; + mrb_int len; + uint32_t i; + + if (!irep->debug_info) { return NULL; } + + mrb_assert(irep->filename); + mrb_assert(irep->lines); + + info = irep->debug_info; + + if (info->flen > 0 && strcmp(irep->filename, info->files[info->flen - 1]->filename) == 0) { + return NULL; + } + + ret = (mrb_irep_debug_info_file *)mrb_malloc(mrb, sizeof(*ret)); + info->files = + (mrb_irep_debug_info_file**)( + info->files + ? mrb_realloc(mrb, info->files, sizeof(mrb_irep_debug_info_file*) * (info->flen + 1)) + : mrb_malloc(mrb, sizeof(mrb_irep_debug_info_file*))); + info->files[info->flen++] = ret; + + file_pc_count = end_pos - start_pos; + + ret->start_pos = start_pos; + info->pc_count = end_pos; + + fn_len = strlen(irep->filename); + ret->filename_sym = mrb_intern(mrb, irep->filename, fn_len); + len = 0; + ret->filename = mrb_sym2name_len(mrb, ret->filename_sym, &len); + + ret->line_type = select_line_type(irep->lines + start_pos, end_pos - start_pos); + ret->lines.ptr = NULL; + + switch (ret->line_type) { + case mrb_debug_line_ary: + ret->line_entry_count = file_pc_count; + ret->lines.ary = (uint16_t*)mrb_malloc(mrb, sizeof(uint16_t) * file_pc_count); + for (i = 0; i < file_pc_count; ++i) { + ret->lines.ary[i] = irep->lines[start_pos + i]; + } + break; + + case mrb_debug_line_flat_map: { + uint16_t prev_line = 0; + mrb_irep_debug_info_line m; + ret->lines.flat_map = (mrb_irep_debug_info_line*)mrb_malloc(mrb, sizeof(mrb_irep_debug_info_line) * 1); + ret->line_entry_count = 0; + for (i = 0; i < file_pc_count; ++i) { + if (irep->lines[start_pos + i] == prev_line) { continue; } + + ret->lines.flat_map = (mrb_irep_debug_info_line*)mrb_realloc( + mrb, ret->lines.flat_map, + sizeof(mrb_irep_debug_info_line) * (ret->line_entry_count + 1)); + m.start_pos = start_pos + i; + m.line = irep->lines[start_pos + i]; + ret->lines.flat_map[ret->line_entry_count] = m; + + /* update */ + ++ret->line_entry_count; + prev_line = irep->lines[start_pos + i]; + } + } break; + + default: mrb_assert(0); break; + } + + return ret; +} + +MRB_API void +mrb_debug_info_free(mrb_state *mrb, mrb_irep_debug_info *d) +{ + uint32_t i; + + if (!d) { return; } + + for (i = 0; i < d->flen; ++i) { + mrb_assert(d->files[i]); + mrb_free(mrb, d->files[i]->lines.ptr); + mrb_free(mrb, d->files[i]); + } + mrb_free(mrb, d->files); + mrb_free(mrb, d); +} diff --git a/web/server/h2o/libh2o/deps/mruby/src/dump.c b/web/server/h2o/libh2o/deps/mruby/src/dump.c new file mode 100644 index 00000000..d479a1a4 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/src/dump.c @@ -0,0 +1,1100 @@ +/* +** dump.c - mruby binary dumper (mrbc binary format) +** +** See Copyright Notice in mruby.h +*/ + +#include +#include +#include +#include +#include +#include +#include + +#define FLAG_BYTEORDER_NATIVE 2 +#define FLAG_BYTEORDER_NONATIVE 0 + +#ifdef MRB_USE_FLOAT +#define MRB_FLOAT_FMT "%.8e" +#else +#define MRB_FLOAT_FMT "%.16e" +#endif + +static size_t get_irep_record_size_1(mrb_state *mrb, mrb_irep *irep); + +#if UINT32_MAX > SIZE_MAX +# error This code cannot be built on your environment. +#endif + +static size_t +write_padding(uint8_t *buf) +{ + const size_t align = MRB_DUMP_ALIGNMENT; + size_t pad_len = -(intptr_t)buf & (align-1); + if (pad_len > 0) { + memset(buf, 0, pad_len); + } + return pad_len; +} + +static size_t +get_irep_header_size(mrb_state *mrb) +{ + size_t size = 0; + + size += sizeof(uint32_t) * 1; + size += sizeof(uint16_t) * 3; + + return size; +} + +static ptrdiff_t +write_irep_header(mrb_state *mrb, mrb_irep *irep, uint8_t *buf) +{ + uint8_t *cur = buf; + + cur += uint32_to_bin((uint32_t)get_irep_record_size_1(mrb, irep), cur); /* record size */ + cur += uint16_to_bin((uint16_t)irep->nlocals, cur); /* number of local variable */ + cur += uint16_to_bin((uint16_t)irep->nregs, cur); /* number of register variable */ + cur += uint16_to_bin((uint16_t)irep->rlen, cur); /* number of child irep */ + + return cur - buf; +} + + +static size_t +get_iseq_block_size(mrb_state *mrb, mrb_irep *irep) +{ + size_t size = 0; + + size += sizeof(uint32_t); /* ilen */ + size += sizeof(uint32_t); /* max padding */ + size += sizeof(uint32_t) * irep->ilen; /* iseq(n) */ + + return size; +} + +static ptrdiff_t +write_iseq_block(mrb_state *mrb, mrb_irep *irep, uint8_t *buf, uint8_t flags) +{ + uint8_t *cur = buf; + int iseq_no; + + cur += uint32_to_bin(irep->ilen, cur); /* number of opcode */ + cur += write_padding(cur); + switch (flags & DUMP_ENDIAN_NAT) { + case DUMP_ENDIAN_BIG: + if (bigendian_p()) goto native; + for (iseq_no = 0; iseq_no < irep->ilen; iseq_no++) { + cur += uint32_to_bin(irep->iseq[iseq_no], cur); /* opcode */ + } + break; + case DUMP_ENDIAN_LIL: + if (!bigendian_p()) goto native; + for (iseq_no = 0; iseq_no < irep->ilen; iseq_no++) { + cur += uint32l_to_bin(irep->iseq[iseq_no], cur); /* opcode */ + } + break; + + native: + case DUMP_ENDIAN_NAT: + memcpy(cur, irep->iseq, irep->ilen * sizeof(mrb_code)); + cur += irep->ilen * sizeof(mrb_code); + break; + } + + return cur - buf; +} + + +static size_t +get_pool_block_size(mrb_state *mrb, mrb_irep *irep) +{ + int pool_no; + size_t size = 0; + mrb_value str; + + size += sizeof(uint32_t); /* plen */ + size += irep->plen * (sizeof(uint8_t) + sizeof(uint16_t)); /* len(n) */ + + for (pool_no = 0; pool_no < irep->plen; pool_no++) { + int ai = mrb_gc_arena_save(mrb); + + switch (mrb_type(irep->pool[pool_no])) { + case MRB_TT_FIXNUM: + str = mrb_fixnum_to_str(mrb, irep->pool[pool_no], 10); + { + mrb_int len = RSTRING_LEN(str); + mrb_assert_int_fit(mrb_int, len, size_t, SIZE_MAX); + size += (size_t)len; + } + break; + + case MRB_TT_FLOAT: + str = mrb_float_to_str(mrb, irep->pool[pool_no], MRB_FLOAT_FMT); + { + mrb_int len = RSTRING_LEN(str); + mrb_assert_int_fit(mrb_int, len, size_t, SIZE_MAX); + size += (size_t)len; + } + break; + + case MRB_TT_STRING: + { + mrb_int len = RSTRING_LEN(irep->pool[pool_no]); + mrb_assert_int_fit(mrb_int, len, size_t, SIZE_MAX); + size += (size_t)len; + } + break; + + default: + break; + } + mrb_gc_arena_restore(mrb, ai); + } + + return size; +} + +static ptrdiff_t +write_pool_block(mrb_state *mrb, mrb_irep *irep, uint8_t *buf) +{ + int pool_no; + uint8_t *cur = buf; + uint16_t len; + mrb_value str; + const char *char_ptr; + + cur += uint32_to_bin(irep->plen, cur); /* number of pool */ + + for (pool_no = 0; pool_no < irep->plen; pool_no++) { + int ai = mrb_gc_arena_save(mrb); + + switch (mrb_type(irep->pool[pool_no])) { + case MRB_TT_FIXNUM: + cur += uint8_to_bin(IREP_TT_FIXNUM, cur); /* data type */ + str = mrb_fixnum_to_str(mrb, irep->pool[pool_no], 10); + break; + + case MRB_TT_FLOAT: + cur += uint8_to_bin(IREP_TT_FLOAT, cur); /* data type */ + str = mrb_float_to_str(mrb, irep->pool[pool_no], MRB_FLOAT_FMT); + break; + + case MRB_TT_STRING: + cur += uint8_to_bin(IREP_TT_STRING, cur); /* data type */ + str = irep->pool[pool_no]; + break; + + default: + continue; + } + + char_ptr = RSTRING_PTR(str); + { + mrb_int tlen = RSTRING_LEN(str); + mrb_assert_int_fit(mrb_int, tlen, uint16_t, UINT16_MAX); + len = (uint16_t)tlen; + } + + cur += uint16_to_bin(len, cur); /* data length */ + memcpy(cur, char_ptr, (size_t)len); + cur += len; + + mrb_gc_arena_restore(mrb, ai); + } + + return cur - buf; +} + + +static size_t +get_syms_block_size(mrb_state *mrb, mrb_irep *irep) +{ + size_t size = 0; + int sym_no; + mrb_int len; + + size += sizeof(uint32_t); /* slen */ + for (sym_no = 0; sym_no < irep->slen; sym_no++) { + size += sizeof(uint16_t); /* snl(n) */ + if (irep->syms[sym_no] != 0) { + mrb_sym2name_len(mrb, irep->syms[sym_no], &len); + size += len + 1; /* sn(n) + null char */ + } + } + + return size; +} + +static ptrdiff_t +write_syms_block(mrb_state *mrb, mrb_irep *irep, uint8_t *buf) +{ + int sym_no; + uint8_t *cur = buf; + const char *name; + + cur += uint32_to_bin(irep->slen, cur); /* number of symbol */ + + for (sym_no = 0; sym_no < irep->slen; sym_no++) { + if (irep->syms[sym_no] != 0) { + mrb_int len; + + name = mrb_sym2name_len(mrb, irep->syms[sym_no], &len); + + mrb_assert_int_fit(mrb_int, len, uint16_t, UINT16_MAX); + cur += uint16_to_bin((uint16_t)len, cur); /* length of symbol name */ + memcpy(cur, name, len); /* symbol name */ + cur += (uint16_t)len; + *cur++ = '\0'; + } + else { + cur += uint16_to_bin(MRB_DUMP_NULL_SYM_LEN, cur); /* length of symbol name */ + } + } + + return cur - buf; +} + +static size_t +get_irep_record_size_1(mrb_state *mrb, mrb_irep *irep) +{ + size_t size = 0; + + size += get_irep_header_size(mrb); + size += get_iseq_block_size(mrb, irep); + size += get_pool_block_size(mrb, irep); + size += get_syms_block_size(mrb, irep); + return size; +} + +static size_t +get_irep_record_size(mrb_state *mrb, mrb_irep *irep) +{ + size_t size = 0; + int irep_no; + + size = get_irep_record_size_1(mrb, irep); + for (irep_no = 0; irep_no < irep->rlen; irep_no++) { + size += get_irep_record_size(mrb, irep->reps[irep_no]); + } + return size; +} + +static int +write_irep_record(mrb_state *mrb, mrb_irep *irep, uint8_t *bin, size_t *irep_record_size, uint8_t flags) +{ + int i; + uint8_t *src = bin; + + if (irep == NULL) { + return MRB_DUMP_INVALID_IREP; + } + + *irep_record_size = get_irep_record_size_1(mrb, irep); + if (*irep_record_size == 0) { + return MRB_DUMP_GENERAL_FAILURE; + } + + bin += write_irep_header(mrb, irep, bin); + bin += write_iseq_block(mrb, irep, bin, flags); + bin += write_pool_block(mrb, irep, bin); + bin += write_syms_block(mrb, irep, bin); + + for (i = 0; i < irep->rlen; i++) { + int result; + size_t rsize; + + result = write_irep_record(mrb, irep->reps[i], bin, &rsize, flags); + if (result != MRB_DUMP_OK) { + return result; + } + bin += rsize; + } + *irep_record_size = bin - src; + return MRB_DUMP_OK; +} + +static uint32_t +write_footer(mrb_state *mrb, uint8_t *bin) +{ + struct rite_binary_footer footer; + + memcpy(footer.section_ident, RITE_BINARY_EOF, sizeof(footer.section_ident)); + uint32_to_bin(sizeof(struct rite_binary_footer), footer.section_size); + memcpy(bin, &footer, sizeof(struct rite_binary_footer)); + + return sizeof(struct rite_binary_footer); +} + + +static int +write_section_irep_header(mrb_state *mrb, size_t section_size, uint8_t *bin) +{ + struct rite_section_irep_header *header = (struct rite_section_irep_header*)bin; + + memcpy(header->section_ident, RITE_SECTION_IREP_IDENT, sizeof(header->section_ident)); + + mrb_assert_int_fit(size_t, section_size, uint32_t, UINT32_MAX); + uint32_to_bin((uint32_t)section_size, header->section_size); + memcpy(header->rite_version, RITE_VM_VER, sizeof(header->rite_version)); + + return MRB_DUMP_OK; +} + +static int +write_section_irep(mrb_state *mrb, mrb_irep *irep, uint8_t *bin, size_t *len_p, uint8_t flags) +{ + int result; + size_t rsize = 0; + uint8_t *cur = bin; + + if (mrb == NULL || bin == NULL) { + return MRB_DUMP_INVALID_ARGUMENT; + } + + cur += sizeof(struct rite_section_irep_header); + + result = write_irep_record(mrb, irep, cur, &rsize, flags); + if (result != MRB_DUMP_OK) { + return result; + } + *len_p = cur - bin + rsize; + write_section_irep_header(mrb, *len_p, bin); + + return MRB_DUMP_OK; +} + +static int +write_section_lineno_header(mrb_state *mrb, size_t section_size, uint8_t *bin) +{ + struct rite_section_lineno_header *header = (struct rite_section_lineno_header*)bin; + + memcpy(header->section_ident, RITE_SECTION_LINENO_IDENT, sizeof(header->section_ident)); + uint32_to_bin((uint32_t)section_size, header->section_size); + + return MRB_DUMP_OK; +} + +static size_t +get_lineno_record_size(mrb_state *mrb, mrb_irep *irep) +{ + size_t size = 0; + + size += sizeof(uint32_t); /* record size */ + size += sizeof(uint16_t); /* filename size */ + if (irep->filename) { + size += strlen(irep->filename); /* filename */ + } + size += sizeof(uint32_t); /* niseq */ + if (irep->lines) { + size += sizeof(uint16_t) * irep->ilen; /* lineno */ + } + + return size; +} + +static size_t +write_lineno_record_1(mrb_state *mrb, mrb_irep *irep, uint8_t* bin) +{ + uint8_t *cur = bin; + int iseq_no; + size_t filename_len; + ptrdiff_t diff; + + cur += sizeof(uint32_t); /* record size */ + + if (irep->filename) { + filename_len = strlen(irep->filename); + } + else { + filename_len = 0; + } + mrb_assert_int_fit(size_t, filename_len, uint16_t, UINT16_MAX); + cur += uint16_to_bin((uint16_t)filename_len, cur); /* filename size */ + + if (filename_len) { + memcpy(cur, irep->filename, filename_len); + cur += filename_len; /* filename */ + } + + if (irep->lines) { + mrb_assert_int_fit(size_t, irep->ilen, uint32_t, UINT32_MAX); + cur += uint32_to_bin((uint32_t)(irep->ilen), cur); /* niseq */ + for (iseq_no = 0; iseq_no < irep->ilen; iseq_no++) { + cur += uint16_to_bin(irep->lines[iseq_no], cur); /* opcode */ + } + } + else { + cur += uint32_to_bin(0, cur); /* niseq */ + } + + diff = cur - bin; + mrb_assert_int_fit(ptrdiff_t, diff, uint32_t, UINT32_MAX); + + uint32_to_bin((uint32_t)diff, bin); /* record size */ + + mrb_assert_int_fit(ptrdiff_t, diff, size_t, SIZE_MAX); + return (size_t)diff; +} + +static size_t +write_lineno_record(mrb_state *mrb, mrb_irep *irep, uint8_t* bin) +{ + size_t rlen, size = 0; + int i; + + rlen = write_lineno_record_1(mrb, irep, bin); + bin += rlen; + size += rlen; + for (i=0; irlen; i++) { + rlen = write_lineno_record(mrb, irep, bin); + bin += rlen; + size += rlen; + } + return size; +} + +static int +write_section_lineno(mrb_state *mrb, mrb_irep *irep, uint8_t *bin) +{ + size_t section_size = 0; + size_t rlen = 0; /* size of irep record */ + uint8_t *cur = bin; + + if (mrb == NULL || bin == NULL) { + return MRB_DUMP_INVALID_ARGUMENT; + } + + cur += sizeof(struct rite_section_lineno_header); + section_size += sizeof(struct rite_section_lineno_header); + + rlen = write_lineno_record(mrb, irep, cur); + section_size += rlen; + + write_section_lineno_header(mrb, section_size, bin); + + return MRB_DUMP_OK; +} + +static size_t +get_debug_record_size(mrb_state *mrb, mrb_irep *irep) +{ + size_t ret = 0; + uint16_t f_idx; + int i; + + ret += sizeof(uint32_t); /* record size */ + ret += sizeof(uint16_t); /* file count */ + + for (f_idx = 0; f_idx < irep->debug_info->flen; ++f_idx) { + mrb_irep_debug_info_file const* file = irep->debug_info->files[f_idx]; + + ret += sizeof(uint32_t); /* position */ + ret += sizeof(uint16_t); /* filename index */ + + /* lines */ + ret += sizeof(uint32_t); /* entry count */ + ret += sizeof(uint8_t); /* line type */ + switch (file->line_type) { + case mrb_debug_line_ary: + ret += sizeof(uint16_t) * (size_t)(file->line_entry_count); + break; + + case mrb_debug_line_flat_map: + ret += (sizeof(uint32_t) + sizeof(uint16_t)) * (size_t)(file->line_entry_count); + break; + + default: mrb_assert(0); break; + } + } + for (i=0; irlen; i++) { + ret += get_debug_record_size(mrb, irep->reps[i]); + } + + return ret; +} + +static int +find_filename_index(const mrb_sym *ary, int ary_len, mrb_sym s) +{ + int i; + + for (i = 0; i < ary_len; ++i) { + if (ary[i] == s) { return i; } + } + return -1; +} + +static size_t +get_filename_table_size(mrb_state *mrb, mrb_irep *irep, mrb_sym **fp, uint16_t *lp) +{ + mrb_sym *filenames = *fp; + size_t size = 0; + mrb_irep_debug_info *di = irep->debug_info; + int i; + + mrb_assert(lp); + for (i = 0; i < di->flen; ++i) { + mrb_irep_debug_info_file *file; + mrb_int filename_len; + + file = di->files[i]; + if (find_filename_index(filenames, *lp, file->filename_sym) == -1) { + /* register filename */ + *lp += 1; + *fp = filenames = (mrb_sym *)mrb_realloc(mrb, filenames, sizeof(mrb_sym) * (*lp)); + filenames[*lp - 1] = file->filename_sym; + + /* filename */ + mrb_sym2name_len(mrb, file->filename_sym, &filename_len); + size += sizeof(uint16_t) + (size_t)filename_len; + } + } + for (i=0; irlen; i++) { + size += get_filename_table_size(mrb, irep->reps[i], fp, lp); + } + return size; +} + +static size_t +write_debug_record_1(mrb_state *mrb, mrb_irep *irep, uint8_t *bin, mrb_sym const* filenames, uint16_t filenames_len) +{ + uint8_t *cur; + uint16_t f_idx; + ptrdiff_t ret; + + cur = bin + sizeof(uint32_t); /* skip record size */ + cur += uint16_to_bin(irep->debug_info->flen, cur); /* file count */ + + for (f_idx = 0; f_idx < irep->debug_info->flen; ++f_idx) { + int filename_idx; + const mrb_irep_debug_info_file *file = irep->debug_info->files[f_idx]; + + /* position */ + cur += uint32_to_bin(file->start_pos, cur); + + /* filename index */ + filename_idx = find_filename_index(filenames, filenames_len, + file->filename_sym); + mrb_assert_int_fit(int, filename_idx, uint16_t, UINT16_MAX); + cur += uint16_to_bin((uint16_t)filename_idx, cur); + + /* lines */ + cur += uint32_to_bin(file->line_entry_count, cur); + cur += uint8_to_bin(file->line_type, cur); + switch (file->line_type) { + case mrb_debug_line_ary: { + uint32_t l; + for (l = 0; l < file->line_entry_count; ++l) { + cur += uint16_to_bin(file->lines.ary[l], cur); + } + } break; + + case mrb_debug_line_flat_map: { + uint32_t line; + for (line = 0; line < file->line_entry_count; ++line) { + cur += uint32_to_bin(file->lines.flat_map[line].start_pos, cur); + cur += uint16_to_bin(file->lines.flat_map[line].line, cur); + } + } break; + + default: mrb_assert(0); break; + } + } + + ret = cur - bin; + mrb_assert_int_fit(ptrdiff_t, ret, uint32_t, UINT32_MAX); + uint32_to_bin((uint32_t)ret, bin); + + mrb_assert_int_fit(ptrdiff_t, ret, size_t, SIZE_MAX); + return (size_t)ret; +} + +static size_t +write_debug_record(mrb_state *mrb, mrb_irep *irep, uint8_t *bin, mrb_sym const* filenames, uint16_t filenames_len) +{ + size_t size, len; + int irep_no; + + size = len = write_debug_record_1(mrb, irep, bin, filenames, filenames_len); + bin += len; + for (irep_no = 0; irep_no < irep->rlen; irep_no++) { + len = write_debug_record(mrb, irep->reps[irep_no], bin, filenames, filenames_len); + bin += len; + size += len; + } + + mrb_assert(size == get_debug_record_size(mrb, irep)); + return size; +} + +static int +write_section_debug(mrb_state *mrb, mrb_irep *irep, uint8_t *cur, mrb_sym const *filenames, uint16_t filenames_len) +{ + size_t section_size = 0; + const uint8_t *bin = cur; + struct rite_section_debug_header *header; + size_t dlen; + uint16_t i; + char const *sym; mrb_int sym_len; + + if (mrb == NULL || cur == NULL) { + return MRB_DUMP_INVALID_ARGUMENT; + } + + header = (struct rite_section_debug_header *)bin; + cur += sizeof(struct rite_section_debug_header); + section_size += sizeof(struct rite_section_debug_header); + + /* filename table */ + cur += uint16_to_bin(filenames_len, cur); + section_size += sizeof(uint16_t); + for (i = 0; i < filenames_len; ++i) { + sym = mrb_sym2name_len(mrb, filenames[i], &sym_len); + mrb_assert(sym); + cur += uint16_to_bin(sym_len, cur); + memcpy(cur, sym, sym_len); + cur += sym_len; + section_size += sizeof(uint16_t) + sym_len; + } + + /* debug records */ + dlen = write_debug_record(mrb, irep, cur, filenames, filenames_len); + section_size += dlen; + + memcpy(header->section_ident, RITE_SECTION_DEBUG_IDENT, sizeof(header->section_ident)); + mrb_assert(section_size <= INT32_MAX); + uint32_to_bin((uint32_t)section_size, header->section_size); + + return MRB_DUMP_OK; +} + +static void +create_lv_sym_table(mrb_state *mrb, const mrb_irep *irep, mrb_sym **syms, uint32_t *syms_len) +{ + int i; + + if (*syms == NULL) { + *syms = (mrb_sym*)mrb_malloc(mrb, sizeof(mrb_sym) * 1); + } + + for (i = 0; i + 1 < irep->nlocals; ++i) { + mrb_sym const name = irep->lv[i].name; + if (name == 0) continue; + if (find_filename_index(*syms, *syms_len, name) != -1) continue; + + ++(*syms_len); + *syms = (mrb_sym*)mrb_realloc(mrb, *syms, sizeof(mrb_sym) * (*syms_len)); + (*syms)[*syms_len - 1] = name; + } + + for (i = 0; i < irep->rlen; ++i) { + create_lv_sym_table(mrb, irep->reps[i], syms, syms_len); + } +} + +static int +write_lv_sym_table(mrb_state *mrb, uint8_t **start, mrb_sym const *syms, uint32_t syms_len) +{ + uint8_t *cur = *start; + uint32_t i; + const char *str; + mrb_int str_len; + + cur += uint32_to_bin(syms_len, cur); + + for (i = 0; i < syms_len; ++i) { + str = mrb_sym2name_len(mrb, syms[i], &str_len); + cur += uint16_to_bin(str_len, cur); + memcpy(cur, str, str_len); + cur += str_len; + } + + *start = cur; + + return MRB_DUMP_OK; +} + +static int +write_lv_record(mrb_state *mrb, const mrb_irep *irep, uint8_t **start, mrb_sym const *syms, uint32_t syms_len) +{ + uint8_t *cur = *start; + int i; + + for (i = 0; i + 1 < irep->nlocals; ++i) { + if (irep->lv[i].name == 0) { + cur += uint16_to_bin(RITE_LV_NULL_MARK, cur); + cur += uint16_to_bin(0, cur); + } + else { + int const sym_idx = find_filename_index(syms, syms_len, irep->lv[i].name); + mrb_assert(sym_idx != -1); /* local variable name must be in syms */ + + cur += uint16_to_bin(sym_idx, cur); + cur += uint16_to_bin(irep->lv[i].r, cur); + } + } + + for (i = 0; i < irep->rlen; ++i) { + write_lv_record(mrb, irep->reps[i], &cur, syms, syms_len); + } + + *start = cur; + + return MRB_DUMP_OK; +} + +static size_t +get_lv_record_size(mrb_state *mrb, mrb_irep *irep) +{ + size_t ret = 0; + int i; + + ret += (sizeof(uint16_t) + sizeof(uint16_t)) * (irep->nlocals - 1); + + for (i = 0; i < irep->rlen; ++i) { + ret += get_lv_record_size(mrb, irep->reps[i]); + } + + return ret; +} + +static size_t +get_lv_section_size(mrb_state *mrb, mrb_irep *irep, mrb_sym const *syms, uint32_t syms_len) +{ + size_t ret = 0, i; + + ret += sizeof(uint32_t); /* syms_len */ + ret += sizeof(uint16_t) * syms_len; /* symbol name lengths */ + for (i = 0; i < syms_len; ++i) { + mrb_int str_len; + mrb_sym2name_len(mrb, syms[i], &str_len); + ret += str_len; + } + + ret += get_lv_record_size(mrb, irep); + + return ret; +} + +static int +write_section_lv(mrb_state *mrb, mrb_irep *irep, uint8_t *start, mrb_sym const *syms, uint32_t const syms_len) +{ + uint8_t *cur = start; + struct rite_section_lv_header *header; + ptrdiff_t diff; + int result = MRB_DUMP_OK; + + if (mrb == NULL || cur == NULL) { + return MRB_DUMP_INVALID_ARGUMENT; + } + + header = (struct rite_section_lv_header*)cur; + cur += sizeof(struct rite_section_lv_header); + + result = write_lv_sym_table(mrb, &cur, syms, syms_len); + if (result != MRB_DUMP_OK) { + goto lv_section_exit; + } + + result = write_lv_record(mrb, irep, &cur, syms, syms_len); + if (result != MRB_DUMP_OK) { + goto lv_section_exit; + } + + memcpy(header->section_ident, RITE_SECTION_LV_IDENT, sizeof(header->section_ident)); + + diff = cur - start; + mrb_assert_int_fit(ptrdiff_t, diff, size_t, SIZE_MAX); + uint32_to_bin((uint32_t)diff, header->section_size); + +lv_section_exit: + return result; +} + +static int +write_rite_binary_header(mrb_state *mrb, size_t binary_size, uint8_t *bin, uint8_t flags) +{ + struct rite_binary_header *header = (struct rite_binary_header *)bin; + uint16_t crc; + uint32_t offset; + + switch (flags & DUMP_ENDIAN_NAT) { + endian_big: + case DUMP_ENDIAN_BIG: + memcpy(header->binary_ident, RITE_BINARY_IDENT, sizeof(header->binary_ident)); + break; + endian_little: + case DUMP_ENDIAN_LIL: + memcpy(header->binary_ident, RITE_BINARY_IDENT_LIL, sizeof(header->binary_ident)); + break; + + case DUMP_ENDIAN_NAT: + if (bigendian_p()) goto endian_big; + goto endian_little; + break; + } + + memcpy(header->binary_version, RITE_BINARY_FORMAT_VER, sizeof(header->binary_version)); + memcpy(header->compiler_name, RITE_COMPILER_NAME, sizeof(header->compiler_name)); + memcpy(header->compiler_version, RITE_COMPILER_VERSION, sizeof(header->compiler_version)); + mrb_assert(binary_size <= UINT32_MAX); + uint32_to_bin((uint32_t)binary_size, header->binary_size); + + offset = (uint32_t)((&(header->binary_crc[0]) - bin) + sizeof(uint16_t)); + crc = calc_crc_16_ccitt(bin + offset, binary_size - offset, 0); + uint16_to_bin(crc, header->binary_crc); + + return MRB_DUMP_OK; +} + +static mrb_bool +is_debug_info_defined(mrb_irep *irep) +{ + int i; + + if (!irep->debug_info) return FALSE; + for (i=0; irlen; i++) { + if (!is_debug_info_defined(irep->reps[i])) return FALSE; + } + return TRUE; +} + +static mrb_bool +is_lv_defined(mrb_irep *irep) +{ + int i; + + if (irep->lv) { return TRUE; } + + for (i = 0; i < irep->rlen; ++i) { + if (is_lv_defined(irep->reps[i])) { return TRUE; } + } + + return FALSE; +} + +static uint8_t +dump_flags(uint8_t flags, uint8_t native) +{ + if (native == FLAG_BYTEORDER_NATIVE) { + if ((flags & DUMP_ENDIAN_NAT) == 0) { + return (flags & DUMP_DEBUG_INFO) | DUMP_ENDIAN_NAT; + } + return flags; + } + if ((flags & DUMP_ENDIAN_NAT) == 0) { + return (flags & DUMP_DEBUG_INFO) | DUMP_ENDIAN_BIG; + } + return flags; +} + +static int +dump_irep(mrb_state *mrb, mrb_irep *irep, uint8_t flags, uint8_t **bin, size_t *bin_size) +{ + int result = MRB_DUMP_GENERAL_FAILURE; + size_t malloc_size; + size_t section_irep_size; + size_t section_lineno_size = 0, section_lv_size = 0; + uint8_t *cur = NULL; + mrb_bool const debug_info_defined = is_debug_info_defined(irep), lv_defined = is_lv_defined(irep); + mrb_sym *lv_syms = NULL; uint32_t lv_syms_len = 0; + mrb_sym *filenames = NULL; uint16_t filenames_len = 0; + + if (mrb == NULL) { + *bin = NULL; + return MRB_DUMP_GENERAL_FAILURE; + } + + section_irep_size = sizeof(struct rite_section_irep_header); + section_irep_size += get_irep_record_size(mrb, irep); + + /* DEBUG section size */ + if (flags & DUMP_DEBUG_INFO) { + if (debug_info_defined) { + section_lineno_size += sizeof(struct rite_section_debug_header); + /* filename table */ + filenames = (mrb_sym*)mrb_malloc(mrb, sizeof(mrb_sym) + 1); + + /* filename table size */ + section_lineno_size += sizeof(uint16_t); + section_lineno_size += get_filename_table_size(mrb, irep, &filenames, &filenames_len); + + section_lineno_size += get_debug_record_size(mrb, irep); + } + else { + section_lineno_size += sizeof(struct rite_section_lineno_header); + section_lineno_size += get_lineno_record_size(mrb, irep); + } + } + + if (lv_defined) { + section_lv_size += sizeof(struct rite_section_lv_header); + create_lv_sym_table(mrb, irep, &lv_syms, &lv_syms_len); + section_lv_size += get_lv_section_size(mrb, irep, lv_syms, lv_syms_len); + } + + malloc_size = sizeof(struct rite_binary_header) + + section_irep_size + section_lineno_size + section_lv_size + + sizeof(struct rite_binary_footer); + cur = *bin = (uint8_t*)mrb_malloc(mrb, malloc_size); + cur += sizeof(struct rite_binary_header); + + result = write_section_irep(mrb, irep, cur, §ion_irep_size, flags); + if (result != MRB_DUMP_OK) { + goto error_exit; + } + cur += section_irep_size; + *bin_size = sizeof(struct rite_binary_header) + + section_irep_size + section_lineno_size + section_lv_size + + sizeof(struct rite_binary_footer); + + /* write DEBUG section */ + if (flags & DUMP_DEBUG_INFO) { + if (debug_info_defined) { + result = write_section_debug(mrb, irep, cur, filenames, filenames_len); + } + else { + result = write_section_lineno(mrb, irep, cur); + } + if (result != MRB_DUMP_OK) { + goto error_exit; + } + cur += section_lineno_size; + } + + if (lv_defined) { + result = write_section_lv(mrb, irep, cur, lv_syms, lv_syms_len); + if (result != MRB_DUMP_OK) { + goto error_exit; + } + cur += section_lv_size; + } + + write_footer(mrb, cur); + write_rite_binary_header(mrb, *bin_size, *bin, flags); + +error_exit: + if (result != MRB_DUMP_OK) { + mrb_free(mrb, *bin); + *bin = NULL; + } + mrb_free(mrb, lv_syms); + mrb_free(mrb, filenames); + return result; +} + +int +mrb_dump_irep(mrb_state *mrb, mrb_irep *irep, uint8_t flags, uint8_t **bin, size_t *bin_size) +{ + return dump_irep(mrb, irep, dump_flags(flags, FLAG_BYTEORDER_NONATIVE), bin, bin_size); +} + +#ifndef MRB_DISABLE_STDIO + +int +mrb_dump_irep_binary(mrb_state *mrb, mrb_irep *irep, uint8_t flags, FILE* fp) +{ + uint8_t *bin = NULL; + size_t bin_size = 0; + int result; + + if (fp == NULL) { + return MRB_DUMP_INVALID_ARGUMENT; + } + + result = dump_irep(mrb, irep, dump_flags(flags, FLAG_BYTEORDER_NONATIVE), &bin, &bin_size); + if (result == MRB_DUMP_OK) { + if (fwrite(bin, sizeof(bin[0]), bin_size, fp) != bin_size) { + result = MRB_DUMP_WRITE_FAULT; + } + } + + mrb_free(mrb, bin); + return result; +} + +static mrb_bool +dump_bigendian_p(uint8_t flags) +{ + switch (flags & DUMP_ENDIAN_NAT) { + case DUMP_ENDIAN_BIG: + return TRUE; + case DUMP_ENDIAN_LIL: + return FALSE; + default: + case DUMP_ENDIAN_NAT: + return bigendian_p(); + } +} + +int +mrb_dump_irep_cfunc(mrb_state *mrb, mrb_irep *irep, uint8_t flags, FILE *fp, const char *initname) +{ + uint8_t *bin = NULL; + size_t bin_size = 0, bin_idx = 0; + int result; + + if (fp == NULL || initname == NULL || initname[0] == '\0') { + return MRB_DUMP_INVALID_ARGUMENT; + } + flags = dump_flags(flags, FLAG_BYTEORDER_NATIVE); + result = dump_irep(mrb, irep, flags, &bin, &bin_size); + if (result == MRB_DUMP_OK) { + if (!dump_bigendian_p(flags)) { + if (fprintf(fp, "/* dumped in little endian order.\n" + " use `mrbc -E` option for big endian CPU. */\n") < 0) { + mrb_free(mrb, bin); + return MRB_DUMP_WRITE_FAULT; + } + } + else { + if (fprintf(fp, "/* dumped in big endian order.\n" + " use `mrbc -e` option for better performance on little endian CPU. */\n") < 0) { + mrb_free(mrb, bin); + return MRB_DUMP_WRITE_FAULT; + } + } + if (fprintf(fp, "#include \n") < 0) { /* for uint8_t under at least Darwin */ + mrb_free(mrb, bin); + return MRB_DUMP_WRITE_FAULT; + } + if (fprintf(fp, + "extern const uint8_t %s[];\n" + "const uint8_t\n" + "#if defined __GNUC__\n" + "__attribute__((aligned(%u)))\n" + "#elif defined _MSC_VER\n" + "__declspec(align(%u))\n" + "#endif\n" + "%s[] = {", + initname, + (uint16_t)MRB_DUMP_ALIGNMENT, (uint16_t)MRB_DUMP_ALIGNMENT, initname) < 0) { + mrb_free(mrb, bin); + return MRB_DUMP_WRITE_FAULT; + } + while (bin_idx < bin_size) { + if (bin_idx % 16 == 0) { + if (fputs("\n", fp) == EOF) { + mrb_free(mrb, bin); + return MRB_DUMP_WRITE_FAULT; + } + } + if (fprintf(fp, "0x%02x,", bin[bin_idx++]) < 0) { + mrb_free(mrb, bin); + return MRB_DUMP_WRITE_FAULT; + } + } + if (fputs("\n};\n", fp) == EOF) { + mrb_free(mrb, bin); + return MRB_DUMP_WRITE_FAULT; + } + } + + mrb_free(mrb, bin); + return result; +} + +#endif /* MRB_DISABLE_STDIO */ diff --git a/web/server/h2o/libh2o/deps/mruby/src/enum.c b/web/server/h2o/libh2o/deps/mruby/src/enum.c new file mode 100644 index 00000000..adb815bf --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/src/enum.c @@ -0,0 +1,14 @@ +/* +** enum.c - Enumerable module +** +** See Copyright Notice in mruby.h +*/ + +#include + +void +mrb_init_enumerable(mrb_state *mrb) +{ + mrb_define_module(mrb, "Enumerable"); /* 15.3.2 */ +} + diff --git a/web/server/h2o/libh2o/deps/mruby/src/error.c b/web/server/h2o/libh2o/deps/mruby/src/error.c new file mode 100644 index 00000000..2c4fd1a4 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/src/error.c @@ -0,0 +1,503 @@ +/* +** error.c - Exception class +** +** See Copyright Notice in mruby.h +*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +MRB_API mrb_value +mrb_exc_new(mrb_state *mrb, struct RClass *c, const char *ptr, size_t len) +{ + mrb_value arg = mrb_str_new(mrb, ptr, len); + return mrb_obj_new(mrb, c, 1, &arg); +} + +MRB_API mrb_value +mrb_exc_new_str(mrb_state *mrb, struct RClass* c, mrb_value str) +{ + str = mrb_str_to_str(mrb, str); + return mrb_obj_new(mrb, c, 1, &str); +} + +/* + * call-seq: + * Exception.new(msg = nil) -> exception + * + * Construct a new Exception object, optionally passing in + * a message. + */ + +static mrb_value +exc_initialize(mrb_state *mrb, mrb_value exc) +{ + mrb_value mesg; + mrb_int argc; + mrb_value *argv; + + if (mrb_get_args(mrb, "|o*!", &mesg, &argv, &argc) >= 1) { + mrb_iv_set(mrb, exc, mrb_intern_lit(mrb, "mesg"), mesg); + } + return exc; +} + +/* + * Document-method: exception + * + * call-seq: + * exc.exception(string) -> an_exception or exc + * + * With no argument, or if the argument is the same as the receiver, + * return the receiver. Otherwise, create a new + * exception object of the same class as the receiver, but with a + * message equal to string. + * + */ + +static mrb_value +exc_exception(mrb_state *mrb, mrb_value self) +{ + mrb_value exc; + mrb_value a; + int argc; + + argc = mrb_get_args(mrb, "|o", &a); + if (argc == 0) return self; + if (mrb_obj_equal(mrb, self, a)) return self; + exc = mrb_obj_clone(mrb, self); + mrb_iv_set(mrb, exc, mrb_intern_lit(mrb, "mesg"), a); + + return exc; +} + +/* + * call-seq: + * exception.to_s -> string + * + * Returns exception's message (or the name of the exception if + * no message is set). + */ + +static mrb_value +exc_to_s(mrb_state *mrb, mrb_value exc) +{ + mrb_value mesg = mrb_attr_get(mrb, exc, mrb_intern_lit(mrb, "mesg")); + struct RObject *p; + + if (!mrb_string_p(mesg)) { + return mrb_str_new_cstr(mrb, mrb_obj_classname(mrb, exc)); + } + p = mrb_obj_ptr(mesg); + if (!p->c) { + p->c = mrb->string_class; + } + return mesg; +} + +/* + * call-seq: + * exception.message -> string + * + * Returns the result of invoking exception.to_s. + * Normally this returns the exception's message or name. + */ + +static mrb_value +exc_message(mrb_state *mrb, mrb_value exc) +{ + return mrb_funcall(mrb, exc, "to_s", 0); +} + +/* + * call-seq: + * exception.inspect -> string + * + * Returns this exception's file name, line number, + * message and class name. + * If file name or line number is not set, + * returns message and class name. + */ + +static mrb_value +exc_inspect(mrb_state *mrb, mrb_value exc) +{ + mrb_value str, mesg, file, line; + mrb_bool append_mesg; + const char *cname; + + mesg = mrb_attr_get(mrb, exc, mrb_intern_lit(mrb, "mesg")); + file = mrb_attr_get(mrb, exc, mrb_intern_lit(mrb, "file")); + line = mrb_attr_get(mrb, exc, mrb_intern_lit(mrb, "line")); + + append_mesg = !mrb_nil_p(mesg); + if (append_mesg) { + mesg = mrb_obj_as_string(mrb, mesg); + append_mesg = RSTRING_LEN(mesg) > 0; + } + + cname = mrb_obj_classname(mrb, exc); + str = mrb_str_new_cstr(mrb, cname); + if (mrb_string_p(file) && mrb_fixnum_p(line)) { + if (append_mesg) { + str = mrb_format(mrb, "%S:%S: %S (%S)", file, line, mesg, str); + } + else { + str = mrb_format(mrb, "%S:%S: %S", file, line, str); + } + } + else if (append_mesg) { + str = mrb_format(mrb, "%S: %S", str, mesg); + } + return str; +} + +void mrb_keep_backtrace(mrb_state *mrb, mrb_value exc); + +static void +set_backtrace(mrb_state *mrb, mrb_value exc, mrb_value backtrace) +{ + if (!mrb_array_p(backtrace)) { + type_err: + mrb_raise(mrb, E_TYPE_ERROR, "backtrace must be Array of String"); + } + else { + const mrb_value *p = RARRAY_PTR(backtrace); + const mrb_value *pend = p + RARRAY_LEN(backtrace); + + while (p < pend) { + if (!mrb_string_p(*p)) goto type_err; + p++; + } + } + mrb_iv_set(mrb, exc, mrb_intern_lit(mrb, "backtrace"), backtrace); +} + +static mrb_value +exc_set_backtrace(mrb_state *mrb, mrb_value exc) +{ + mrb_value backtrace; + + mrb_get_args(mrb, "o", &backtrace); + set_backtrace(mrb, exc, backtrace); + return backtrace; +} + +static void +exc_debug_info(mrb_state *mrb, struct RObject *exc) +{ + mrb_callinfo *ci = mrb->c->ci; + mrb_code *pc = ci->pc; + + while (ci >= mrb->c->cibase) { + mrb_code *err = ci->err; + + if (!err && pc) err = pc - 1; + if (err && ci->proc && !MRB_PROC_CFUNC_P(ci->proc)) { + mrb_irep *irep = ci->proc->body.irep; + + int32_t const line = mrb_debug_get_line(irep, err - irep->iseq); + char const* file = mrb_debug_get_filename(irep, err - irep->iseq); + if (line != -1 && file) { + mrb_obj_iv_set(mrb, exc, mrb_intern_lit(mrb, "file"), mrb_str_new_cstr(mrb, file)); + mrb_obj_iv_set(mrb, exc, mrb_intern_lit(mrb, "line"), mrb_fixnum_value(line)); + return; + } + } + pc = ci->pc; + ci--; + } +} + +void +mrb_exc_set(mrb_state *mrb, mrb_value exc) +{ + if (mrb_nil_p(exc)) { + mrb->exc = 0; + } + else { + mrb->exc = mrb_obj_ptr(exc); + if (!mrb->gc.out_of_memory) { + exc_debug_info(mrb, mrb->exc); + mrb_keep_backtrace(mrb, exc); + } + } +} + +MRB_API mrb_noreturn void +mrb_exc_raise(mrb_state *mrb, mrb_value exc) +{ + if (!mrb_obj_is_kind_of(mrb, exc, mrb->eException_class)) { + mrb_raise(mrb, E_TYPE_ERROR, "exception object expected"); + } + mrb_exc_set(mrb, exc); + if (!mrb->jmp) { + mrb_p(mrb, exc); + abort(); + } + MRB_THROW(mrb->jmp); +} + +MRB_API mrb_noreturn void +mrb_raise(mrb_state *mrb, struct RClass *c, const char *msg) +{ + mrb_exc_raise(mrb, mrb_exc_new_str(mrb, c, mrb_str_new_cstr(mrb, msg))); +} + +MRB_API mrb_value +mrb_vformat(mrb_state *mrb, const char *format, va_list ap) +{ + const char *p = format; + const char *b = p; + ptrdiff_t size; + mrb_value ary = mrb_ary_new_capa(mrb, 4); + int ai = mrb_gc_arena_save(mrb); + + while (*p) { + const char c = *p++; + + if (c == '%') { + if (*p == 'S') { + mrb_value val; + + size = p - b - 1; + mrb_ary_push(mrb, ary, mrb_str_new(mrb, b, size)); + val = va_arg(ap, mrb_value); + mrb_ary_push(mrb, ary, mrb_obj_as_string(mrb, val)); + b = p + 1; + } + } + else if (c == '\\') { + if (*p) { + size = p - b - 1; + mrb_ary_push(mrb, ary, mrb_str_new(mrb, b, size)); + mrb_ary_push(mrb, ary, mrb_str_new(mrb, p, 1)); + b = ++p; + } + else { + break; + } + } + mrb_gc_arena_restore(mrb, ai); + } + if (b == format) { + return mrb_str_new_cstr(mrb, format); + } + else { + size = p - b; + if (size > 0) { + mrb_ary_push(mrb, ary, mrb_str_new(mrb, b, size)); + mrb_gc_arena_restore(mrb, ai); + } + return mrb_ary_join(mrb, ary, mrb_nil_value()); + } +} + +MRB_API mrb_value +mrb_format(mrb_state *mrb, const char *format, ...) +{ + va_list ap; + mrb_value str; + + va_start(ap, format); + str = mrb_vformat(mrb, format, ap); + va_end(ap); + + return str; +} + +static mrb_noreturn void +raise_va(mrb_state *mrb, struct RClass *c, const char *fmt, va_list ap, int argc, mrb_value *argv) +{ + mrb_value mesg; + + mesg = mrb_vformat(mrb, fmt, ap); + if (argv == NULL) { + argv = &mesg; + } + else { + argv[0] = mesg; + } + mrb_exc_raise(mrb, mrb_obj_new(mrb, c, argc+1, argv)); +} + +MRB_API mrb_noreturn void +mrb_raisef(mrb_state *mrb, struct RClass *c, const char *fmt, ...) +{ + va_list args; + + va_start(args, fmt); + raise_va(mrb, c, fmt, args, 0, NULL); + va_end(args); +} + +MRB_API mrb_noreturn void +mrb_name_error(mrb_state *mrb, mrb_sym id, const char *fmt, ...) +{ + mrb_value argv[2]; + va_list args; + + va_start(args, fmt); + argv[1] = mrb_symbol_value(id); + raise_va(mrb, E_NAME_ERROR, fmt, args, 1, argv); + va_end(args); +} + +MRB_API void +mrb_warn(mrb_state *mrb, const char *fmt, ...) +{ +#ifndef MRB_DISABLE_STDIO + va_list ap; + mrb_value str; + + va_start(ap, fmt); + str = mrb_vformat(mrb, fmt, ap); + fputs("warning: ", stderr); + fwrite(RSTRING_PTR(str), RSTRING_LEN(str), 1, stderr); + va_end(ap); +#endif +} + +MRB_API mrb_noreturn void +mrb_bug(mrb_state *mrb, const char *fmt, ...) +{ +#ifndef MRB_DISABLE_STDIO + va_list ap; + mrb_value str; + + va_start(ap, fmt); + str = mrb_vformat(mrb, fmt, ap); + fputs("bug: ", stderr); + fwrite(RSTRING_PTR(str), RSTRING_LEN(str), 1, stderr); + va_end(ap); +#endif + exit(EXIT_FAILURE); +} + +MRB_API mrb_value +mrb_make_exception(mrb_state *mrb, int argc, const mrb_value *argv) +{ + mrb_value mesg; + int n; + + mesg = mrb_nil_value(); + switch (argc) { + case 0: + break; + case 1: + if (mrb_nil_p(argv[0])) + break; + if (mrb_string_p(argv[0])) { + mesg = mrb_exc_new_str(mrb, E_RUNTIME_ERROR, argv[0]); + break; + } + n = 0; + goto exception_call; + + case 2: + case 3: + n = 1; +exception_call: + { + mrb_sym exc = mrb_intern_lit(mrb, "exception"); + if (mrb_respond_to(mrb, argv[0], exc)) { + mesg = mrb_funcall_argv(mrb, argv[0], exc, n, argv+1); + } + else { + /* undef */ + mrb_raise(mrb, E_TYPE_ERROR, "exception class/object expected"); + } + } + + break; + default: + mrb_raisef(mrb, E_ARGUMENT_ERROR, "wrong number of arguments (%S for 0..3)", mrb_fixnum_value(argc)); + break; + } + if (argc > 0) { + if (!mrb_obj_is_kind_of(mrb, mesg, mrb->eException_class)) + mrb_raise(mrb, mrb->eException_class, "exception object expected"); + if (argc > 2) + set_backtrace(mrb, mesg, argv[2]); + } + + return mesg; +} + +MRB_API void +mrb_sys_fail(mrb_state *mrb, const char *mesg) +{ + struct RClass *sce; + mrb_int no; + + no = (mrb_int)errno; + if (mrb_class_defined(mrb, "SystemCallError")) { + sce = mrb_class_get(mrb, "SystemCallError"); + if (mesg != NULL) { + mrb_funcall(mrb, mrb_obj_value(sce), "_sys_fail", 2, mrb_fixnum_value(no), mrb_str_new_cstr(mrb, mesg)); + } + else { + mrb_funcall(mrb, mrb_obj_value(sce), "_sys_fail", 1, mrb_fixnum_value(no)); + } + } + else { + mrb_raise(mrb, E_RUNTIME_ERROR, mesg); + } +} + +MRB_API mrb_noreturn void +mrb_no_method_error(mrb_state *mrb, mrb_sym id, mrb_value args, char const* fmt, ...) +{ + mrb_value exc; + mrb_value argv[3]; + va_list ap; + + va_start(ap, fmt); + argv[0] = mrb_vformat(mrb, fmt, ap); + argv[1] = mrb_symbol_value(id); + argv[2] = args; + va_end(ap); + exc = mrb_obj_new(mrb, E_NOMETHOD_ERROR, 3, argv); + mrb_exc_raise(mrb, exc); +} + +void +mrb_init_exception(mrb_state *mrb) +{ + struct RClass *exception, *script_error, *stack_error, *nomem_error; + + mrb->eException_class = exception = mrb_define_class(mrb, "Exception", mrb->object_class); /* 15.2.22 */ + MRB_SET_INSTANCE_TT(exception, MRB_TT_EXCEPTION); + mrb_define_class_method(mrb, exception, "exception", mrb_instance_new, MRB_ARGS_ANY()); + mrb_define_method(mrb, exception, "exception", exc_exception, MRB_ARGS_ANY()); + mrb_define_method(mrb, exception, "initialize", exc_initialize, MRB_ARGS_ANY()); + mrb_define_method(mrb, exception, "to_s", exc_to_s, MRB_ARGS_NONE()); + mrb_define_method(mrb, exception, "message", exc_message, MRB_ARGS_NONE()); + mrb_define_method(mrb, exception, "inspect", exc_inspect, MRB_ARGS_NONE()); + mrb_define_method(mrb, exception, "backtrace", mrb_exc_backtrace, MRB_ARGS_NONE()); + mrb_define_method(mrb, exception, "set_backtrace", exc_set_backtrace, MRB_ARGS_REQ(1)); + + mrb->eStandardError_class = mrb_define_class(mrb, "StandardError", mrb->eException_class); /* 15.2.23 */ + mrb_define_class(mrb, "RuntimeError", mrb->eStandardError_class); /* 15.2.28 */ + script_error = mrb_define_class(mrb, "ScriptError", mrb->eException_class); /* 15.2.37 */ + mrb_define_class(mrb, "SyntaxError", script_error); /* 15.2.38 */ + stack_error = mrb_define_class(mrb, "SystemStackError", exception); + mrb->stack_err = mrb_obj_ptr(mrb_exc_new_str_lit(mrb, stack_error, "stack level too deep")); + + nomem_error = mrb_define_class(mrb, "NoMemoryError", exception); + mrb->nomem_err = mrb_obj_ptr(mrb_exc_new_str_lit(mrb, nomem_error, "Out of memory")); +#ifdef MRB_GC_FIXED_ARENA + mrb->arena_err = mrb_obj_ptr(mrb_exc_new_str_lit(mrb, nomem_error, "arena overflow error")); +#endif +} diff --git a/web/server/h2o/libh2o/deps/mruby/src/error.h b/web/server/h2o/libh2o/deps/mruby/src/error.h new file mode 100644 index 00000000..eb755ec7 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/src/error.h @@ -0,0 +1,3 @@ +/* this header file is to be removed soon. + added for compatibility purpose (1.0.0) */ +#include diff --git a/web/server/h2o/libh2o/deps/mruby/src/etc.c b/web/server/h2o/libh2o/deps/mruby/src/etc.c new file mode 100644 index 00000000..9475ae30 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/src/etc.c @@ -0,0 +1,234 @@ +/* +** etc.c - +** +** See Copyright Notice in mruby.h +*/ + +#include +#include +#include +#include +#include +#include + +MRB_API struct RData* +mrb_data_object_alloc(mrb_state *mrb, struct RClass *klass, void *ptr, const mrb_data_type *type) +{ + struct RData *data; + + data = (struct RData*)mrb_obj_alloc(mrb, MRB_TT_DATA, klass); + data->data = ptr; + data->type = type; + + return data; +} + +MRB_API void +mrb_data_check_type(mrb_state *mrb, mrb_value obj, const mrb_data_type *type) +{ + if (mrb_type(obj) != MRB_TT_DATA) { + mrb_check_type(mrb, obj, MRB_TT_DATA); + } + if (DATA_TYPE(obj) != type) { + const mrb_data_type *t2 = DATA_TYPE(obj); + + if (t2) { + mrb_raisef(mrb, E_TYPE_ERROR, "wrong argument type %S (expected %S)", + mrb_str_new_cstr(mrb, t2->struct_name), mrb_str_new_cstr(mrb, type->struct_name)); + } + else { + struct RClass *c = mrb_class(mrb, obj); + + mrb_raisef(mrb, E_TYPE_ERROR, "uninitialized %S (expected %S)", + mrb_obj_value(c), mrb_str_new_cstr(mrb, type->struct_name)); + } + } +} + +MRB_API void* +mrb_data_check_get_ptr(mrb_state *mrb, mrb_value obj, const mrb_data_type *type) +{ + if (mrb_type(obj) != MRB_TT_DATA) { + return NULL; + } + if (DATA_TYPE(obj) != type) { + return NULL; + } + return DATA_PTR(obj); +} + +MRB_API void* +mrb_data_get_ptr(mrb_state *mrb, mrb_value obj, const mrb_data_type *type) +{ + mrb_data_check_type(mrb, obj, type); + return DATA_PTR(obj); +} + +MRB_API mrb_sym +mrb_obj_to_sym(mrb_state *mrb, mrb_value name) +{ + mrb_sym id; + + switch (mrb_type(name)) { + default: + name = mrb_check_string_type(mrb, name); + if (mrb_nil_p(name)) { + name = mrb_inspect(mrb, name); + mrb_raisef(mrb, E_TYPE_ERROR, "%S is not a symbol", name); + } + /* fall through */ + case MRB_TT_STRING: + name = mrb_str_intern(mrb, name); + /* fall through */ + case MRB_TT_SYMBOL: + id = mrb_symbol(name); + } + return id; +} + +MRB_API mrb_int +mrb_float_id(mrb_float f) +{ + const char *p = (const char*)&f; + int len = sizeof(f); + mrb_int id = 0; + + /* normalize -0.0 to 0.0 */ + if (f == 0) f = 0.0; + while (len--) { + id = id*65599 + *p; + p++; + } + id = id + (id>>5); + + return id; +} + +MRB_API mrb_int +mrb_obj_id(mrb_value obj) +{ + mrb_int tt = mrb_type(obj); + +#define MakeID2(p,t) (mrb_int)(((intptr_t)(p))^(t)) +#define MakeID(p) MakeID2(p,tt) + + switch (tt) { + case MRB_TT_FREE: + case MRB_TT_UNDEF: + return MakeID(0); /* not define */ + case MRB_TT_FALSE: + if (mrb_nil_p(obj)) + return MakeID(1); + return MakeID(0); + case MRB_TT_TRUE: + return MakeID(1); + case MRB_TT_SYMBOL: + return MakeID(mrb_symbol(obj)); + case MRB_TT_FIXNUM: + return MakeID2(mrb_float_id((mrb_float)mrb_fixnum(obj)), MRB_TT_FLOAT); + case MRB_TT_FLOAT: + return MakeID(mrb_float_id(mrb_float(obj))); + case MRB_TT_STRING: + case MRB_TT_OBJECT: + case MRB_TT_CLASS: + case MRB_TT_MODULE: + case MRB_TT_ICLASS: + case MRB_TT_SCLASS: + case MRB_TT_PROC: + case MRB_TT_ARRAY: + case MRB_TT_HASH: + case MRB_TT_RANGE: + case MRB_TT_EXCEPTION: + case MRB_TT_FILE: + case MRB_TT_DATA: + case MRB_TT_ISTRUCT: + default: + return MakeID(mrb_ptr(obj)); + } +} + +#ifdef MRB_WORD_BOXING +MRB_API mrb_value +mrb_word_boxing_float_value(mrb_state *mrb, mrb_float f) +{ + mrb_value v; + + v.value.p = mrb_obj_alloc(mrb, MRB_TT_FLOAT, mrb->float_class); + v.value.fp->f = f; + return v; +} + +MRB_API mrb_value +mrb_word_boxing_float_pool(mrb_state *mrb, mrb_float f) +{ + struct RFloat *nf = (struct RFloat *)mrb_malloc(mrb, sizeof(struct RFloat)); + nf->tt = MRB_TT_FLOAT; + nf->c = mrb->float_class; + nf->f = f; + return mrb_obj_value(nf); +} + +MRB_API mrb_value +mrb_word_boxing_cptr_value(mrb_state *mrb, void *p) +{ + mrb_value v; + + v.value.p = mrb_obj_alloc(mrb, MRB_TT_CPTR, mrb->object_class); + v.value.vp->p = p; + return v; +} +#endif /* MRB_WORD_BOXING */ + +MRB_API mrb_bool +mrb_regexp_p(mrb_state *mrb, mrb_value v) +{ + if (mrb->flags & MRB_STATE_NO_REGEXP) { + return FALSE; + } + if ((mrb->flags & MRB_STATE_REGEXP) || mrb_class_defined(mrb, REGEXP_CLASS)) { + mrb->flags |= MRB_STATE_REGEXP; + return mrb_obj_is_kind_of(mrb, v, mrb_class_get(mrb, REGEXP_CLASS)); + } + else { + mrb->flags |= MRB_STATE_REGEXP; + mrb->flags |= MRB_STATE_NO_REGEXP; + } + return FALSE; +} + +#if defined _MSC_VER && _MSC_VER < 1900 + +#ifndef va_copy +static void +mrb_msvc_va_copy(va_list *dest, va_list src) +{ + *dest = src; +} +#define va_copy(dest, src) mrb_msvc_va_copy(&(dest), src) +#endif + +MRB_API int +mrb_msvc_vsnprintf(char *s, size_t n, const char *format, va_list arg) +{ + int cnt; + va_list argcp; + va_copy(argcp, arg); + if (n == 0 || (cnt = _vsnprintf_s(s, n, _TRUNCATE, format, argcp)) < 0) { + cnt = _vscprintf(format, arg); + } + va_end(argcp); + return cnt; +} + +MRB_API int +mrb_msvc_snprintf(char *s, size_t n, const char *format, ...) +{ + va_list arg; + int ret; + va_start(arg, format); + ret = mrb_msvc_vsnprintf(s, n, format, arg); + va_end(arg); + return ret; +} + +#endif /* defined _MSC_VER && _MSC_VER < 1900 */ diff --git a/web/server/h2o/libh2o/deps/mruby/src/ext/.gitkeep b/web/server/h2o/libh2o/deps/mruby/src/ext/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/web/server/h2o/libh2o/deps/mruby/src/fmt_fp.c b/web/server/h2o/libh2o/deps/mruby/src/fmt_fp.c new file mode 100644 index 00000000..0a8b22b4 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/src/fmt_fp.c @@ -0,0 +1,372 @@ +/* + +Most code in this file originates from musl (src/stdio/vfprintf.c) +which, just like mruby itself, is licensed under the MIT license. + +Copyright (c) 2005-2014 Rich Felker, et al. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +*/ + +#include +#include +#include +#include +#include +#include + +#include +#include + +struct fmt_args { + mrb_state *mrb; + mrb_value str; +}; + +#define MAX(a,b) ((a)>(b) ? (a) : (b)) +#define MIN(a,b) ((a)<(b) ? (a) : (b)) + +/* Convenient bit representation for modifier flags, which all fall + * within 31 codepoints of the space character. */ + +#define ALT_FORM (1U<<('#'-' ')) +#define ZERO_PAD (1U<<('0'-' ')) +#define LEFT_ADJ (1U<<('-'-' ')) +#define PAD_POS (1U<<(' '-' ')) +#define MARK_POS (1U<<('+'-' ')) + +static void +out(struct fmt_args *f, const char *s, size_t l) +{ + mrb_str_cat(f->mrb, f->str, s, l); +} + +#define PAD_SIZE 256 +static void +pad(struct fmt_args *f, char c, ptrdiff_t w, ptrdiff_t l, uint8_t fl) +{ + char pad[PAD_SIZE]; + if (fl & (LEFT_ADJ | ZERO_PAD) || l >= w) return; + l = w - l; + memset(pad, c, l>PAD_SIZE ? PAD_SIZE : l); + for (; l >= PAD_SIZE; l -= PAD_SIZE) + out(f, pad, PAD_SIZE); + out(f, pad, l); +} + +static const char xdigits[16] = { + '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' +}; + +static char* +fmt_u(uint32_t x, char *s) +{ + for (; x; x /= 10) *--s = '0' + x % 10; + return s; +} + +/* Do not override this check. The floating point printing code below + * depends on the float.h constants being right. If they are wrong, it + * may overflow the stack. */ +#if LDBL_MANT_DIG == 53 +typedef char compiler_defines_long_double_incorrectly[9-(int)sizeof(long double)]; +#endif + +static int +fmt_fp(struct fmt_args *f, long double y, ptrdiff_t p, uint8_t fl, int t) +{ + uint32_t big[(LDBL_MANT_DIG+28)/29 + 1 // mantissa expansion + + (LDBL_MAX_EXP+LDBL_MANT_DIG+28+8)/9]; // exponent expansion + uint32_t *a, *d, *r, *z; + uint32_t i; + int e2=0, e, j; + ptrdiff_t l; + char buf[9+LDBL_MANT_DIG/4], *s; + const char *prefix="-0X+0X 0X-0x+0x 0x"; + ptrdiff_t pl; + char ebuf0[3*sizeof(int)], *ebuf=&ebuf0[3*sizeof(int)], *estr; + + pl=1; + if (signbit(y)) { + y=-y; + } else if (fl & MARK_POS) { + prefix+=3; + } else if (fl & PAD_POS) { + prefix+=6; + } else prefix++, pl=0; + + if (!isfinite(y)) { + const char *ss = (t&32)?"inf":"INF"; + if (y!=y) ss=(t&32)?"nan":"NAN"; + pad(f, ' ', 0, 3+pl, fl&~ZERO_PAD); + out(f, prefix, pl); + out(f, ss, 3); + pad(f, ' ', 0, 3+pl, fl^LEFT_ADJ); + return 3+(int)pl; + } + + y = frexp((double)y, &e2) * 2; + if (y) e2--; + + if ((t|32)=='a') { + long double round = 8.0; + ptrdiff_t re; + + if (t&32) prefix += 9; + pl += 2; + + if (p<0 || p>=LDBL_MANT_DIG/4-1) re=0; + else re=LDBL_MANT_DIG/4-1-p; + + if (re) { + while (re--) round*=16; + if (*prefix=='-') { + y=-y; + y-=round; + y+=round; + y=-y; + } + else { + y+=round; + y-=round; + } + } + + estr=fmt_u(e2<0 ? -e2 : e2, ebuf); + if (estr==ebuf) *--estr='0'; + *--estr = (e2<0 ? '-' : '+'); + *--estr = t+('p'-'a'); + + s=buf; + do { + int x=(int)y; + *s++=xdigits[x]|(t&32); + y=16*(y-x); + if (s-buf==1 && (y||p>0||(fl&ALT_FORM))) *s++='.'; + } while (y); + + if (p && s-buf-2 < p) + l = (p+2) + (ebuf-estr); + else + l = (s-buf) + (ebuf-estr); + + pad(f, ' ', 0, pl+l, fl); + out(f, prefix, pl); + pad(f, '0', 0, pl+l, fl^ZERO_PAD); + out(f, buf, s-buf); + pad(f, '0', l-(ebuf-estr)-(s-buf), 0, 0); + out(f, estr, ebuf-estr); + pad(f, ' ', 0, pl+l, fl^LEFT_ADJ); + return (int)pl+(int)l; + } + if (p<0) p=6; + + if (y) y *= 268435456.0, e2-=28; + + if (e2<0) a=r=z=big; + else a=r=z=big+sizeof(big)/sizeof(*big) - LDBL_MANT_DIG - 1; + + do { + *z = (uint32_t)y; + y = 1000000000*(y-*z++); + } while (y); + + while (e2>0) { + uint32_t carry=0; + int sh=MIN(29,e2); + for (d=z-1; d>=a; d--) { + uint64_t x = ((uint64_t)*d<a && !z[-1]) z--; + e2-=sh; + } + while (e2<0) { + uint32_t carry=0, *b; + int sh=MIN(9,-e2), need=1+((int)p+LDBL_MANT_DIG/3+8)/9; + for (d=a; d>sh) + carry; + carry = (1000000000>>sh) * rm; + } + if (!*a) a++; + if (carry) *z++ = carry; + /* Avoid (slow!) computation past requested precision */ + b = (t|32)=='f' ? r : a; + if (z-b > need) z = b+need; + e2+=sh; + } + + if (a=i; i*=10, e++); + else e=0; + + /* Perform rounding: j is precision after the radix (possibly neg) */ + j = (int)p - ((t|32)!='f')*e - ((t|32)=='g' && p); + if (j < 9*(z-r-1)) { + uint32_t x; + /* We avoid C's broken division of negative numbers */ + d = r + 1 + ((j+9*LDBL_MAX_EXP)/9 - LDBL_MAX_EXP); + j += 9*LDBL_MAX_EXP; + j %= 9; + for (i=10, j++; j<9; i*=10, j++); + x = *d % i; + /* Are there any significant digits past j? */ + if (x || d+1!=z) { + long double round = 2/LDBL_EPSILON; + long double small; + if (*d/i & 1) round += 2; + if (x 999999999) { + *d--=0; + if (d=i; i*=10, e++); + } + } + if (z>d+1) z=d+1; + } + for (; z>a && !z[-1]; z--); + + if ((t|32)=='g') { + if (!p) p++; + if (p>e && e>=-4) { + t--; + p-=e+1; + } + else { + t-=2; + p--; + } + if (!(fl&ALT_FORM)) { + /* Count trailing zeros in last place */ + if (z>a && z[-1]) for (i=10, j=0; z[-1]%i==0; i*=10, j++); + else j=9; + if ((t|32)=='f') + p = MIN(p,MAX(0,9*(z-r-1)-j)); + else + p = MIN(p,MAX(0,9*(z-r-1)+e-j)); + } + } + l = 1 + p + (p || (fl&ALT_FORM)); + if ((t|32)=='f') { + if (e>0) l+=e; + } + else { + estr=fmt_u(e<0 ? -e : e, ebuf); + while(ebuf-estr<2) *--estr='0'; + *--estr = (e<0 ? '-' : '+'); + *--estr = t; + l += ebuf-estr; + } + + pad(f, ' ', 0, pl+l, fl); + out(f, prefix, pl); + pad(f, '0', 0, pl+l, fl^ZERO_PAD); + + if ((t|32)=='f') { + if (a>r) a=r; + for (d=a; d<=r; d++) { + char *ss = fmt_u(*d, buf+9); + if (d!=a) while (ss>buf) *--ss='0'; + else if (ss==buf+9) *--ss='0'; + out(f, ss, buf+9-ss); + } + if (p || (fl&ALT_FORM)) out(f, ".", 1); + for (; d0; d++, p-=9) { + char *ss = fmt_u(*d, buf+9); + while (ss>buf) *--ss='0'; + out(f, ss, MIN(9,p)); + } + pad(f, '0', p+9, 9, 0); + } + else { + if (z<=a) z=a+1; + for (d=a; d=0; d++) { + char *ss = fmt_u(*d, buf+9); + if (ss==buf+9) *--ss='0'; + if (d!=a) while (ss>buf) *--ss='0'; + else { + out(f, ss++, 1); + if (p>0||(fl&ALT_FORM)) out(f, ".", 1); + } + out(f, ss, MIN(buf+9-ss, p)); + p -= (int)(buf+9-ss); + } + pad(f, '0', p+18, 18, 0); + out(f, estr, ebuf-estr); + } + + pad(f, ' ', 0, pl+l, fl^LEFT_ADJ); + + return (int)pl+(int)l; +} + +static int +fmt_core(struct fmt_args *f, const char *fmt, mrb_float flo) +{ + ptrdiff_t p; + + if (*fmt != '%') { + return -1; + } + ++fmt; + + if (*fmt == '.') { + ++fmt; + for (p = 0; ISDIGIT(*fmt); ++fmt) { + p = 10 * p + (*fmt - '0'); + } + } + else { + p = -1; + } + + switch (*fmt) { + case 'e': case 'f': case 'g': case 'a': + case 'E': case 'F': case 'G': case 'A': + return fmt_fp(f, flo, p, 0, *fmt); + default: + return -1; + } +} + +mrb_value +mrb_float_to_str(mrb_state *mrb, mrb_value flo, const char *fmt) +{ + struct fmt_args f; + + f.mrb = mrb; + f.str = mrb_str_new_capa(mrb, 24); + if (fmt_core(&f, fmt, mrb_float(flo)) < 0) { + mrb_raise(mrb, E_ARGUMENT_ERROR, "invalid format string"); + } + return f.str; +} diff --git a/web/server/h2o/libh2o/deps/mruby/src/gc.c b/web/server/h2o/libh2o/deps/mruby/src/gc.c new file mode 100644 index 00000000..d602bfb7 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/src/gc.c @@ -0,0 +1,1824 @@ +/* +** gc.c - garbage collector for mruby +** +** See Copyright Notice in mruby.h +*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* + = Tri-color Incremental Garbage Collection + + mruby's GC is Tri-color Incremental GC with Mark & Sweep. + Algorithm details are omitted. + Instead, the implementation part is described below. + + == Object's Color + + Each object can be painted in three colors: + + * White - Unmarked. + * Gray - Marked, But the child objects are unmarked. + * Black - Marked, the child objects are also marked. + + == Two White Types + + There're two white color types in a flip-flop fashion: White-A and White-B, + which respectively represent the Current White color (the newly allocated + objects in the current GC cycle) and the Sweep Target White color (the + dead objects to be swept). + + A and B will be switched just at the beginning of the next GC cycle. At + that time, all the dead objects have been swept, while the newly created + objects in the current GC cycle which finally remains White are now + regarded as dead objects. Instead of traversing all the White-A objects and + painting them as White-B, just switch the meaning of White-A and White-B as + this will be much cheaper. + + As a result, the objects we sweep in the current GC cycle are always + left from the previous GC cycle. This allows us to sweep objects + incrementally, without the disturbance of the newly created objects. + + == Execution Timing + + GC Execution Time and Each step interval are decided by live objects count. + List of Adjustment API: + + * gc_interval_ratio_set + * gc_step_ratio_set + + For details, see the comments for each function. + + == Write Barrier + + mruby implementer and C extension library writer must insert a write + barrier when updating a reference from a field of an object. + When updating a reference from a field of object A to object B, + two different types of write barrier are available: + + * mrb_field_write_barrier - target B object for a mark. + * mrb_write_barrier - target A object for a mark. + + == Generational Mode + + mruby's GC offers an Generational Mode while re-using the tri-color GC + infrastructure. It will treat the Black objects as Old objects after each + sweep phase, instead of painting them White. The key ideas are still the same + as traditional generational GC: + + * Minor GC - just traverse the Young objects (Gray objects) in the mark + phase, then only sweep the newly created objects, and leave + the Old objects live. + + * Major GC - same as a full regular GC cycle. + + The difference from "traditional" generational GC is, that the major GC + in mruby is triggered incrementally in a tri-color manner. + + + For details, see the comments for each function. + +*/ + +struct free_obj { + MRB_OBJECT_HEADER; + struct RBasic *next; +}; + +typedef struct { + union { + struct free_obj free; + struct RBasic basic; + struct RObject object; + struct RClass klass; + struct RString string; + struct RArray array; + struct RHash hash; + struct RRange range; + struct RData data; + struct RProc proc; + struct REnv env; + struct RException exc; + struct RBreak brk; +#ifdef MRB_WORD_BOXING + struct RFloat floatv; + struct RCptr cptr; +#endif + } as; +} RVALUE; + +#ifdef GC_PROFILE +#include +#include + +static double program_invoke_time = 0; +static double gc_time = 0; +static double gc_total_time = 0; + +static double +gettimeofday_time(void) +{ + struct timeval tv; + gettimeofday(&tv, NULL); + return tv.tv_sec + tv.tv_usec * 1e-6; +} + +#define GC_INVOKE_TIME_REPORT(with) do {\ + fprintf(stderr, "%s\n", with);\ + fprintf(stderr, "gc_invoke: %19.3f\n", gettimeofday_time() - program_invoke_time);\ + fprintf(stderr, "is_generational: %d\n", is_generational(gc));\ + fprintf(stderr, "is_major_gc: %d\n", is_major_gc(gc));\ +} while(0) + +#define GC_TIME_START do {\ + gc_time = gettimeofday_time();\ +} while(0) + +#define GC_TIME_STOP_AND_REPORT do {\ + gc_time = gettimeofday_time() - gc_time;\ + gc_total_time += gc_time;\ + fprintf(stderr, "gc_state: %d\n", gc->state);\ + fprintf(stderr, "live: %zu\n", gc->live);\ + fprintf(stderr, "majorgc_old_threshold: %zu\n", gc->majorgc_old_threshold);\ + fprintf(stderr, "gc_threshold: %zu\n", gc->threshold);\ + fprintf(stderr, "gc_time: %30.20f\n", gc_time);\ + fprintf(stderr, "gc_total_time: %30.20f\n\n", gc_total_time);\ +} while(0) +#else +#define GC_INVOKE_TIME_REPORT(s) +#define GC_TIME_START +#define GC_TIME_STOP_AND_REPORT +#endif + +#ifdef GC_DEBUG +#define DEBUG(x) (x) +#else +#define DEBUG(x) +#endif + +#ifndef MRB_HEAP_PAGE_SIZE +#define MRB_HEAP_PAGE_SIZE 1024 +#endif + +#define GC_STEP_SIZE 1024 + +/* white: 011, black: 100, gray: 000 */ +#define GC_GRAY 0 +#define GC_WHITE_A 1 +#define GC_WHITE_B (1 << 1) +#define GC_BLACK (1 << 2) +#define GC_WHITES (GC_WHITE_A | GC_WHITE_B) +#define GC_COLOR_MASK 7 + +#define paint_gray(o) ((o)->color = GC_GRAY) +#define paint_black(o) ((o)->color = GC_BLACK) +#define paint_white(o) ((o)->color = GC_WHITES) +#define paint_partial_white(s, o) ((o)->color = (s)->current_white_part) +#define is_gray(o) ((o)->color == GC_GRAY) +#define is_white(o) ((o)->color & GC_WHITES) +#define is_black(o) ((o)->color & GC_BLACK) +#define flip_white_part(s) ((s)->current_white_part = other_white_part(s)) +#define other_white_part(s) ((s)->current_white_part ^ GC_WHITES) +#define is_dead(s, o) (((o)->color & other_white_part(s) & GC_WHITES) || (o)->tt == MRB_TT_FREE) + +#define objects(p) ((RVALUE *)p->objects) + +MRB_API void* +mrb_realloc_simple(mrb_state *mrb, void *p, size_t len) +{ + void *p2; + + p2 = (mrb->allocf)(mrb, p, len, mrb->allocf_ud); + if (!p2 && len > 0 && mrb->gc.heaps) { + mrb_full_gc(mrb); + p2 = (mrb->allocf)(mrb, p, len, mrb->allocf_ud); + } + + return p2; +} + +MRB_API void* +mrb_realloc(mrb_state *mrb, void *p, size_t len) +{ + void *p2; + + p2 = mrb_realloc_simple(mrb, p, len); + if (len == 0) return p2; + if (p2 == NULL) { + if (mrb->gc.out_of_memory) { + mrb_exc_raise(mrb, mrb_obj_value(mrb->nomem_err)); + /* mrb_panic(mrb); */ + } + else { + mrb->gc.out_of_memory = TRUE; + mrb_exc_raise(mrb, mrb_obj_value(mrb->nomem_err)); + } + } + else { + mrb->gc.out_of_memory = FALSE; + } + + return p2; +} + +MRB_API void* +mrb_malloc(mrb_state *mrb, size_t len) +{ + return mrb_realloc(mrb, 0, len); +} + +MRB_API void* +mrb_malloc_simple(mrb_state *mrb, size_t len) +{ + return mrb_realloc_simple(mrb, 0, len); +} + +MRB_API void* +mrb_calloc(mrb_state *mrb, size_t nelem, size_t len) +{ + void *p; + + if (nelem > 0 && len > 0 && + nelem <= SIZE_MAX / len) { + size_t size; + size = nelem * len; + p = mrb_malloc(mrb, size); + + memset(p, 0, size); + } + else { + p = NULL; + } + + return p; +} + +MRB_API void +mrb_free(mrb_state *mrb, void *p) +{ + (mrb->allocf)(mrb, p, 0, mrb->allocf_ud); +} + +MRB_API mrb_bool +mrb_object_dead_p(mrb_state *mrb, struct RBasic *object) { + return is_dead(&mrb->gc, object); +} + +static void +link_heap_page(mrb_gc *gc, mrb_heap_page *page) +{ + page->next = gc->heaps; + if (gc->heaps) + gc->heaps->prev = page; + gc->heaps = page; +} + +static void +unlink_heap_page(mrb_gc *gc, mrb_heap_page *page) +{ + if (page->prev) + page->prev->next = page->next; + if (page->next) + page->next->prev = page->prev; + if (gc->heaps == page) + gc->heaps = page->next; + page->prev = NULL; + page->next = NULL; +} + +static void +link_free_heap_page(mrb_gc *gc, mrb_heap_page *page) +{ + page->free_next = gc->free_heaps; + if (gc->free_heaps) { + gc->free_heaps->free_prev = page; + } + gc->free_heaps = page; +} + +static void +unlink_free_heap_page(mrb_gc *gc, mrb_heap_page *page) +{ + if (page->free_prev) + page->free_prev->free_next = page->free_next; + if (page->free_next) + page->free_next->free_prev = page->free_prev; + if (gc->free_heaps == page) + gc->free_heaps = page->free_next; + page->free_prev = NULL; + page->free_next = NULL; +} + +static void +add_heap(mrb_state *mrb, mrb_gc *gc) +{ + mrb_heap_page *page = (mrb_heap_page *)mrb_calloc(mrb, 1, sizeof(mrb_heap_page) + MRB_HEAP_PAGE_SIZE * sizeof(RVALUE)); + RVALUE *p, *e; + struct RBasic *prev = NULL; + + for (p = objects(page), e=p+MRB_HEAP_PAGE_SIZE; pas.free.tt = MRB_TT_FREE; + p->as.free.next = prev; + prev = &p->as.basic; + } + page->freelist = prev; + + link_heap_page(gc, page); + link_free_heap_page(gc, page); +} + +#define DEFAULT_GC_INTERVAL_RATIO 200 +#define DEFAULT_GC_STEP_RATIO 200 +#define DEFAULT_MAJOR_GC_INC_RATIO 200 +#define is_generational(gc) ((gc)->generational) +#define is_major_gc(gc) (is_generational(gc) && (gc)->full) +#define is_minor_gc(gc) (is_generational(gc) && !(gc)->full) + +void +mrb_gc_init(mrb_state *mrb, mrb_gc *gc) +{ +#ifndef MRB_GC_FIXED_ARENA + gc->arena = (struct RBasic**)mrb_malloc(mrb, sizeof(struct RBasic*)*MRB_GC_ARENA_SIZE); + gc->arena_capa = MRB_GC_ARENA_SIZE; +#endif + + gc->current_white_part = GC_WHITE_A; + gc->heaps = NULL; + gc->free_heaps = NULL; + add_heap(mrb, gc); + gc->interval_ratio = DEFAULT_GC_INTERVAL_RATIO; + gc->step_ratio = DEFAULT_GC_STEP_RATIO; +#ifndef MRB_GC_TURN_OFF_GENERATIONAL + gc->generational = TRUE; + gc->full = TRUE; +#endif + +#ifdef GC_PROFILE + program_invoke_time = gettimeofday_time(); +#endif +} + +static void obj_free(mrb_state *mrb, struct RBasic *obj, int end); + +void +free_heap(mrb_state *mrb, mrb_gc *gc) +{ + mrb_heap_page *page = gc->heaps; + mrb_heap_page *tmp; + RVALUE *p, *e; + + while (page) { + tmp = page; + page = page->next; + for (p = objects(tmp), e=p+MRB_HEAP_PAGE_SIZE; pas.free.tt != MRB_TT_FREE) + obj_free(mrb, &p->as.basic, TRUE); + } + mrb_free(mrb, tmp); + } +} + +void +mrb_gc_destroy(mrb_state *mrb, mrb_gc *gc) +{ + free_heap(mrb, gc); +#ifndef MRB_GC_FIXED_ARENA + mrb_free(mrb, gc->arena); +#endif +} + +static void +gc_protect(mrb_state *mrb, mrb_gc *gc, struct RBasic *p) +{ +#ifdef MRB_GC_FIXED_ARENA + if (gc->arena_idx >= MRB_GC_ARENA_SIZE) { + /* arena overflow error */ + gc->arena_idx = MRB_GC_ARENA_SIZE - 4; /* force room in arena */ + mrb_exc_raise(mrb, mrb_obj_value(mrb->arena_err)); + } +#else + if (gc->arena_idx >= gc->arena_capa) { + /* extend arena */ + gc->arena_capa = (int)(gc->arena_capa * 1.5); + gc->arena = (struct RBasic**)mrb_realloc(mrb, gc->arena, sizeof(struct RBasic*)*gc->arena_capa); + } +#endif + gc->arena[gc->arena_idx++] = p; +} + +/* mrb_gc_protect() leaves the object in the arena */ +MRB_API void +mrb_gc_protect(mrb_state *mrb, mrb_value obj) +{ + if (mrb_immediate_p(obj)) return; + gc_protect(mrb, &mrb->gc, mrb_basic_ptr(obj)); +} + +#define GC_ROOT_NAME "_gc_root_" + +/* mrb_gc_register() keeps the object from GC. + + Register your object when it's exported to C world, + without reference from Ruby world, e.g. callback + arguments. Don't forget to remove the object using + mrb_gc_unregister, otherwise your object will leak. +*/ + +MRB_API void +mrb_gc_register(mrb_state *mrb, mrb_value obj) +{ + mrb_sym root = mrb_intern_lit(mrb, GC_ROOT_NAME); + mrb_value table = mrb_gv_get(mrb, root); + + if (mrb_nil_p(table) || mrb_type(table) != MRB_TT_ARRAY) { + table = mrb_ary_new(mrb); + mrb_gv_set(mrb, root, table); + } + mrb_ary_push(mrb, table, obj); +} + +/* mrb_gc_unregister() removes the object from GC root. */ +MRB_API void +mrb_gc_unregister(mrb_state *mrb, mrb_value obj) +{ + mrb_sym root = mrb_intern_lit(mrb, GC_ROOT_NAME); + mrb_value table = mrb_gv_get(mrb, root); + struct RArray *a; + mrb_int i; + + if (mrb_nil_p(table)) return; + if (mrb_type(table) != MRB_TT_ARRAY) { + mrb_gv_set(mrb, root, mrb_nil_value()); + return; + } + a = mrb_ary_ptr(table); + mrb_ary_modify(mrb, a); + for (i = 0; i < ARY_LEN(a); i++) { + if (mrb_obj_eq(mrb, ARY_PTR(a)[i], obj)) { + mrb_int len = ARY_LEN(a)-1; + mrb_value *ptr = ARY_PTR(a); + + ARY_SET_LEN(a, len); + memmove(&ptr[i], &ptr[i + 1], (len - i) * sizeof(mrb_value)); + break; + } + } +} + +MRB_API struct RBasic* +mrb_obj_alloc(mrb_state *mrb, enum mrb_vtype ttype, struct RClass *cls) +{ + struct RBasic *p; + static const RVALUE RVALUE_zero = { { { MRB_TT_FALSE } } }; + mrb_gc *gc = &mrb->gc; + + if (cls) { + enum mrb_vtype tt; + + switch (cls->tt) { + case MRB_TT_CLASS: + case MRB_TT_SCLASS: + case MRB_TT_MODULE: + case MRB_TT_ENV: + break; + default: + mrb_raise(mrb, E_TYPE_ERROR, "allocation failure"); + } + tt = MRB_INSTANCE_TT(cls); + if (tt != MRB_TT_FALSE && + ttype != MRB_TT_SCLASS && + ttype != MRB_TT_ICLASS && + ttype != MRB_TT_ENV && + ttype != tt) { + mrb_raisef(mrb, E_TYPE_ERROR, "allocation failure of %S", mrb_obj_value(cls)); + } + } + +#ifdef MRB_GC_STRESS + mrb_full_gc(mrb); +#endif + if (gc->threshold < gc->live) { + mrb_incremental_gc(mrb); + } + if (gc->free_heaps == NULL) { + add_heap(mrb, gc); + } + + p = gc->free_heaps->freelist; + gc->free_heaps->freelist = ((struct free_obj*)p)->next; + if (gc->free_heaps->freelist == NULL) { + unlink_free_heap_page(gc, gc->free_heaps); + } + + gc->live++; + gc_protect(mrb, gc, p); + *(RVALUE *)p = RVALUE_zero; + p->tt = ttype; + p->c = cls; + paint_partial_white(gc, p); + return p; +} + +static inline void +add_gray_list(mrb_state *mrb, mrb_gc *gc, struct RBasic *obj) +{ +#ifdef MRB_GC_STRESS + if (obj->tt > MRB_TT_MAXDEFINE) { + abort(); + } +#endif + paint_gray(obj); + obj->gcnext = gc->gray_list; + gc->gray_list = obj; +} + +static void +mark_context_stack(mrb_state *mrb, struct mrb_context *c) +{ + size_t i; + size_t e; + mrb_value nil; + int nregs; + + if (c->stack == NULL) return; + e = c->stack - c->stbase; + if (c->ci) { + nregs = c->ci->argc + 2; + if (c->ci->nregs > nregs) + nregs = c->ci->nregs; + e += nregs; + } + if (c->stbase + e > c->stend) e = c->stend - c->stbase; + for (i=0; istbase[i]; + + if (!mrb_immediate_p(v)) { + mrb_gc_mark(mrb, mrb_basic_ptr(v)); + } + } + e = c->stend - c->stbase; + nil = mrb_nil_value(); + for (; istbase[i] = nil; + } +} + +static void +mark_context(mrb_state *mrb, struct mrb_context *c) +{ + int i; + mrb_callinfo *ci; + + if (c->status == MRB_FIBER_TERMINATED) return; + + /* mark VM stack */ + mark_context_stack(mrb, c); + + /* mark call stack */ + if (c->cibase) { + for (ci = c->cibase; ci <= c->ci; ci++) { + mrb_gc_mark(mrb, (struct RBasic*)ci->env); + mrb_gc_mark(mrb, (struct RBasic*)ci->proc); + mrb_gc_mark(mrb, (struct RBasic*)ci->target_class); + } + } + /* mark ensure stack */ + for (i=0; iesize; i++) { + if (c->ensure[i] == NULL) break; + mrb_gc_mark(mrb, (struct RBasic*)c->ensure[i]); + } + /* mark fibers */ + mrb_gc_mark(mrb, (struct RBasic*)c->fib); + if (c->prev) { + mark_context(mrb, c->prev); + } +} + +static void +gc_mark_children(mrb_state *mrb, mrb_gc *gc, struct RBasic *obj) +{ + mrb_assert(is_gray(obj)); + paint_black(obj); + gc->gray_list = obj->gcnext; + mrb_gc_mark(mrb, (struct RBasic*)obj->c); + switch (obj->tt) { + case MRB_TT_ICLASS: + { + struct RClass *c = (struct RClass*)obj; + if (MRB_FLAG_TEST(c, MRB_FLAG_IS_ORIGIN)) + mrb_gc_mark_mt(mrb, c); + mrb_gc_mark(mrb, (struct RBasic*)((struct RClass*)obj)->super); + } + break; + + case MRB_TT_CLASS: + case MRB_TT_MODULE: + case MRB_TT_SCLASS: + { + struct RClass *c = (struct RClass*)obj; + + mrb_gc_mark_mt(mrb, c); + mrb_gc_mark(mrb, (struct RBasic*)c->super); + } + /* fall through */ + + case MRB_TT_OBJECT: + case MRB_TT_DATA: + case MRB_TT_EXCEPTION: + mrb_gc_mark_iv(mrb, (struct RObject*)obj); + break; + + case MRB_TT_PROC: + { + struct RProc *p = (struct RProc*)obj; + + mrb_gc_mark(mrb, (struct RBasic*)p->env); + mrb_gc_mark(mrb, (struct RBasic*)p->target_class); + if (!MRB_PROC_CFUNC_P(p) && p->body.irep) { + mrb_gc_mark(mrb, (struct RBasic*)p->body.irep->target_class); + } + } + break; + + case MRB_TT_ENV: + { + struct REnv *e = (struct REnv*)obj; + mrb_int i, len; + + if (MRB_ENV_STACK_SHARED_P(e)) { + if (e->cxt.c->fib) { + mrb_gc_mark(mrb, (struct RBasic*)e->cxt.c->fib); + } + break; + } + len = MRB_ENV_STACK_LEN(e); + for (i=0; istack[i]); + } + } + break; + + case MRB_TT_FIBER: + { + struct mrb_context *c = ((struct RFiber*)obj)->cxt; + + if (c) mark_context(mrb, c); + } + break; + + case MRB_TT_ARRAY: + { + struct RArray *a = (struct RArray*)obj; + size_t i, e; + + for (i=0,e=ARY_LEN(a); iedges) { + mrb_gc_mark_value(mrb, r->edges->beg); + mrb_gc_mark_value(mrb, r->edges->end); + } + } + break; + + default: + break; + } +} + +MRB_API void +mrb_gc_mark(mrb_state *mrb, struct RBasic *obj) +{ + if (obj == 0) return; + if (!is_white(obj)) return; + mrb_assert((obj)->tt != MRB_TT_FREE); + add_gray_list(mrb, &mrb->gc, obj); +} + +static void +obj_free(mrb_state *mrb, struct RBasic *obj, int end) +{ + DEBUG(fprintf(stderr, "obj_free(%p,tt=%d)\n",obj,obj->tt)); + switch (obj->tt) { + /* immediate - no mark */ + case MRB_TT_TRUE: + case MRB_TT_FIXNUM: + case MRB_TT_SYMBOL: + /* cannot happen */ + return; + + case MRB_TT_FLOAT: +#ifdef MRB_WORD_BOXING + break; +#else + return; +#endif + + case MRB_TT_OBJECT: + mrb_gc_free_iv(mrb, (struct RObject*)obj); + break; + + case MRB_TT_EXCEPTION: + mrb_gc_free_iv(mrb, (struct RObject*)obj); + break; + + case MRB_TT_CLASS: + case MRB_TT_MODULE: + case MRB_TT_SCLASS: + mrb_gc_free_mt(mrb, (struct RClass*)obj); + mrb_gc_free_iv(mrb, (struct RObject*)obj); + break; + case MRB_TT_ICLASS: + if (MRB_FLAG_TEST(obj, MRB_FLAG_IS_ORIGIN)) + mrb_gc_free_mt(mrb, (struct RClass*)obj); + break; + case MRB_TT_ENV: + { + struct REnv *e = (struct REnv*)obj; + + if (MRB_ENV_STACK_SHARED_P(e)) { + /* cannot be freed */ + return; + } + mrb_free(mrb, e->stack); + e->stack = NULL; + } + break; + + case MRB_TT_FIBER: + { + struct mrb_context *c = ((struct RFiber*)obj)->cxt; + + if (!end && c && c != mrb->root_c) { + mrb_callinfo *ci = c->ci; + mrb_callinfo *ce = c->cibase; + + while (ce <= ci) { + struct REnv *e = ci->env; + if (e && !is_dead(&mrb->gc, e) && + e->tt == MRB_TT_ENV && MRB_ENV_STACK_SHARED_P(e)) { + mrb_env_unshare(mrb, e); + } + ci--; + } + mrb_free_context(mrb, c); + } + } + break; + + case MRB_TT_ARRAY: + if (ARY_SHARED_P(obj)) + mrb_ary_decref(mrb, ((struct RArray*)obj)->as.heap.aux.shared); + else if (!ARY_EMBED_P(obj)) + mrb_free(mrb, ((struct RArray*)obj)->as.heap.ptr); + break; + + case MRB_TT_HASH: + mrb_gc_free_iv(mrb, (struct RObject*)obj); + mrb_gc_free_hash(mrb, (struct RHash*)obj); + break; + + case MRB_TT_STRING: + mrb_gc_free_str(mrb, (struct RString*)obj); + break; + + case MRB_TT_PROC: + { + struct RProc *p = (struct RProc*)obj; + + if (!MRB_PROC_CFUNC_P(p) && p->body.irep) { + mrb_irep_decref(mrb, p->body.irep); + } + } + break; + + case MRB_TT_RANGE: + mrb_free(mrb, ((struct RRange*)obj)->edges); + break; + + case MRB_TT_DATA: + { + struct RData *d = (struct RData*)obj; + if (d->type && d->type->dfree) { + d->type->dfree(mrb, d->data); + } + mrb_gc_free_iv(mrb, (struct RObject*)obj); + } + break; + + default: + break; + } + obj->tt = MRB_TT_FREE; +} + +static void +root_scan_phase(mrb_state *mrb, mrb_gc *gc) +{ + int i, e; + + if (!is_minor_gc(gc)) { + gc->gray_list = NULL; + gc->atomic_gray_list = NULL; + } + + mrb_gc_mark_gv(mrb); + /* mark arena */ + for (i=0,e=gc->arena_idx; iarena[i]); + } + /* mark class hierarchy */ + mrb_gc_mark(mrb, (struct RBasic*)mrb->object_class); + + /* mark built-in classes */ + mrb_gc_mark(mrb, (struct RBasic*)mrb->class_class); + mrb_gc_mark(mrb, (struct RBasic*)mrb->module_class); + mrb_gc_mark(mrb, (struct RBasic*)mrb->proc_class); + mrb_gc_mark(mrb, (struct RBasic*)mrb->string_class); + mrb_gc_mark(mrb, (struct RBasic*)mrb->array_class); + mrb_gc_mark(mrb, (struct RBasic*)mrb->hash_class); + mrb_gc_mark(mrb, (struct RBasic*)mrb->range_class); + + mrb_gc_mark(mrb, (struct RBasic*)mrb->float_class); + mrb_gc_mark(mrb, (struct RBasic*)mrb->fixnum_class); + mrb_gc_mark(mrb, (struct RBasic*)mrb->true_class); + mrb_gc_mark(mrb, (struct RBasic*)mrb->false_class); + mrb_gc_mark(mrb, (struct RBasic*)mrb->nil_class); + mrb_gc_mark(mrb, (struct RBasic*)mrb->symbol_class); + mrb_gc_mark(mrb, (struct RBasic*)mrb->kernel_module); + + mrb_gc_mark(mrb, (struct RBasic*)mrb->eException_class); + mrb_gc_mark(mrb, (struct RBasic*)mrb->eStandardError_class); + + /* mark top_self */ + mrb_gc_mark(mrb, (struct RBasic*)mrb->top_self); + /* mark exception */ + mrb_gc_mark(mrb, (struct RBasic*)mrb->exc); + /* mark pre-allocated exception */ + mrb_gc_mark(mrb, (struct RBasic*)mrb->nomem_err); + mrb_gc_mark(mrb, (struct RBasic*)mrb->stack_err); +#ifdef MRB_GC_FIXED_ARENA + mrb_gc_mark(mrb, (struct RBasic*)mrb->arena_err); +#endif + + mark_context(mrb, mrb->c); + if (mrb->root_c != mrb->c) { + mark_context(mrb, mrb->root_c); + } +} + +static size_t +gc_gray_mark(mrb_state *mrb, mrb_gc *gc, struct RBasic *obj) +{ + size_t children = 0; + + gc_mark_children(mrb, gc, obj); + + switch (obj->tt) { + case MRB_TT_ICLASS: + children++; + break; + + case MRB_TT_CLASS: + case MRB_TT_SCLASS: + case MRB_TT_MODULE: + { + struct RClass *c = (struct RClass*)obj; + + children += mrb_gc_mark_iv_size(mrb, (struct RObject*)obj); + children += mrb_gc_mark_mt_size(mrb, c); + children++; + } + break; + + case MRB_TT_OBJECT: + case MRB_TT_DATA: + case MRB_TT_EXCEPTION: + children += mrb_gc_mark_iv_size(mrb, (struct RObject*)obj); + break; + + case MRB_TT_ENV: + children += (int)obj->flags; + break; + + case MRB_TT_FIBER: + { + struct mrb_context *c = ((struct RFiber*)obj)->cxt; + size_t i; + mrb_callinfo *ci; + + if (!c) break; + /* mark stack */ + i = c->stack - c->stbase; + if (c->ci) i += c->ci->nregs; + if (c->stbase + i > c->stend) i = c->stend - c->stbase; + children += i; + + /* mark ensure stack */ + children += c->eidx; + + /* mark closure */ + if (c->cibase) { + for (i=0, ci = c->cibase; ci <= c->ci; i++, ci++) + ; + } + children += i; + } + break; + + case MRB_TT_ARRAY: + { + struct RArray *a = (struct RArray*)obj; + children += ARY_LEN(a); + } + break; + + case MRB_TT_HASH: + children += mrb_gc_mark_iv_size(mrb, (struct RObject*)obj); + children += mrb_gc_mark_hash_size(mrb, (struct RHash*)obj); + break; + + case MRB_TT_PROC: + case MRB_TT_RANGE: + children+=2; + break; + + default: + break; + } + return children; +} + + +static void +gc_mark_gray_list(mrb_state *mrb, mrb_gc *gc) { + while (gc->gray_list) { + if (is_gray(gc->gray_list)) + gc_mark_children(mrb, gc, gc->gray_list); + else + gc->gray_list = gc->gray_list->gcnext; + } +} + + +static size_t +incremental_marking_phase(mrb_state *mrb, mrb_gc *gc, size_t limit) +{ + size_t tried_marks = 0; + + while (gc->gray_list && tried_marks < limit) { + tried_marks += gc_gray_mark(mrb, gc, gc->gray_list); + } + + return tried_marks; +} + +static void +final_marking_phase(mrb_state *mrb, mrb_gc *gc) +{ + int i, e; + + /* mark arena */ + for (i=0,e=gc->arena_idx; iarena[i]); + } + mrb_gc_mark_gv(mrb); + mark_context(mrb, mrb->c); + mark_context(mrb, mrb->root_c); + mrb_gc_mark(mrb, (struct RBasic*)mrb->exc); + gc_mark_gray_list(mrb, gc); + mrb_assert(gc->gray_list == NULL); + gc->gray_list = gc->atomic_gray_list; + gc->atomic_gray_list = NULL; + gc_mark_gray_list(mrb, gc); + mrb_assert(gc->gray_list == NULL); +} + +static void +prepare_incremental_sweep(mrb_state *mrb, mrb_gc *gc) +{ + gc->state = MRB_GC_STATE_SWEEP; + gc->sweeps = gc->heaps; + gc->live_after_mark = gc->live; +} + +static size_t +incremental_sweep_phase(mrb_state *mrb, mrb_gc *gc, size_t limit) +{ + mrb_heap_page *page = gc->sweeps; + size_t tried_sweep = 0; + + while (page && (tried_sweep < limit)) { + RVALUE *p = objects(page); + RVALUE *e = p + MRB_HEAP_PAGE_SIZE; + size_t freed = 0; + mrb_bool dead_slot = TRUE; + mrb_bool full = (page->freelist == NULL); + + if (is_minor_gc(gc) && page->old) { + /* skip a slot which doesn't contain any young object */ + p = e; + dead_slot = FALSE; + } + while (pas.basic)) { + if (p->as.basic.tt != MRB_TT_FREE) { + obj_free(mrb, &p->as.basic, FALSE); + if (p->as.basic.tt == MRB_TT_FREE) { + p->as.free.next = page->freelist; + page->freelist = (struct RBasic*)p; + freed++; + } + else { + dead_slot = FALSE; + } + } + } + else { + if (!is_generational(gc)) + paint_partial_white(gc, &p->as.basic); /* next gc target */ + dead_slot = FALSE; + } + p++; + } + + /* free dead slot */ + if (dead_slot && freed < MRB_HEAP_PAGE_SIZE) { + mrb_heap_page *next = page->next; + + unlink_heap_page(gc, page); + unlink_free_heap_page(gc, page); + mrb_free(mrb, page); + page = next; + } + else { + if (full && freed > 0) { + link_free_heap_page(gc, page); + } + if (page->freelist == NULL && is_minor_gc(gc)) + page->old = TRUE; + else + page->old = FALSE; + page = page->next; + } + tried_sweep += MRB_HEAP_PAGE_SIZE; + gc->live -= freed; + gc->live_after_mark -= freed; + } + gc->sweeps = page; + return tried_sweep; +} + +static size_t +incremental_gc(mrb_state *mrb, mrb_gc *gc, size_t limit) +{ + switch (gc->state) { + case MRB_GC_STATE_ROOT: + root_scan_phase(mrb, gc); + gc->state = MRB_GC_STATE_MARK; + flip_white_part(gc); + return 0; + case MRB_GC_STATE_MARK: + if (gc->gray_list) { + return incremental_marking_phase(mrb, gc, limit); + } + else { + final_marking_phase(mrb, gc); + prepare_incremental_sweep(mrb, gc); + return 0; + } + case MRB_GC_STATE_SWEEP: { + size_t tried_sweep = 0; + tried_sweep = incremental_sweep_phase(mrb, gc, limit); + if (tried_sweep == 0) + gc->state = MRB_GC_STATE_ROOT; + return tried_sweep; + } + default: + /* unknown state */ + mrb_assert(0); + return 0; + } +} + +static void +incremental_gc_until(mrb_state *mrb, mrb_gc *gc, mrb_gc_state to_state) +{ + do { + incremental_gc(mrb, gc, SIZE_MAX); + } while (gc->state != to_state); +} + +static void +incremental_gc_step(mrb_state *mrb, mrb_gc *gc) +{ + size_t limit = 0, result = 0; + limit = (GC_STEP_SIZE/100) * gc->step_ratio; + while (result < limit) { + result += incremental_gc(mrb, gc, limit); + if (gc->state == MRB_GC_STATE_ROOT) + break; + } + + gc->threshold = gc->live + GC_STEP_SIZE; +} + +static void +clear_all_old(mrb_state *mrb, mrb_gc *gc) +{ + mrb_bool origin_mode = gc->generational; + + mrb_assert(is_generational(gc)); + if (is_major_gc(gc)) { + /* finish the half baked GC */ + incremental_gc_until(mrb, gc, MRB_GC_STATE_ROOT); + } + + /* Sweep the dead objects, then reset all the live objects + * (including all the old objects, of course) to white. */ + gc->generational = FALSE; + prepare_incremental_sweep(mrb, gc); + incremental_gc_until(mrb, gc, MRB_GC_STATE_ROOT); + gc->generational = origin_mode; + + /* The gray objects have already been painted as white */ + gc->atomic_gray_list = gc->gray_list = NULL; +} + +MRB_API void +mrb_incremental_gc(mrb_state *mrb) +{ + mrb_gc *gc = &mrb->gc; + + if (gc->disabled || gc->iterating) return; + + GC_INVOKE_TIME_REPORT("mrb_incremental_gc()"); + GC_TIME_START; + + if (is_minor_gc(gc)) { + incremental_gc_until(mrb, gc, MRB_GC_STATE_ROOT); + } + else { + incremental_gc_step(mrb, gc); + } + + if (gc->state == MRB_GC_STATE_ROOT) { + mrb_assert(gc->live >= gc->live_after_mark); + gc->threshold = (gc->live_after_mark/100) * gc->interval_ratio; + if (gc->threshold < GC_STEP_SIZE) { + gc->threshold = GC_STEP_SIZE; + } + + if (is_major_gc(gc)) { + gc->majorgc_old_threshold = gc->live_after_mark/100 * DEFAULT_MAJOR_GC_INC_RATIO; + gc->full = FALSE; + } + else if (is_minor_gc(gc)) { + if (gc->live > gc->majorgc_old_threshold) { + clear_all_old(mrb, gc); + gc->full = TRUE; + } + } + } + + GC_TIME_STOP_AND_REPORT; +} + +/* Perform a full gc cycle */ +MRB_API void +mrb_full_gc(mrb_state *mrb) +{ + mrb_gc *gc = &mrb->gc; + + if (gc->disabled || gc->iterating) return; + + GC_INVOKE_TIME_REPORT("mrb_full_gc()"); + GC_TIME_START; + + if (is_generational(gc)) { + /* clear all the old objects back to young */ + clear_all_old(mrb, gc); + gc->full = TRUE; + } + else if (gc->state != MRB_GC_STATE_ROOT) { + /* finish half baked GC cycle */ + incremental_gc_until(mrb, gc, MRB_GC_STATE_ROOT); + } + + incremental_gc_until(mrb, gc, MRB_GC_STATE_ROOT); + gc->threshold = (gc->live_after_mark/100) * gc->interval_ratio; + + if (is_generational(gc)) { + gc->majorgc_old_threshold = gc->live_after_mark/100 * DEFAULT_MAJOR_GC_INC_RATIO; + gc->full = FALSE; + } + + GC_TIME_STOP_AND_REPORT; +} + +MRB_API void +mrb_garbage_collect(mrb_state *mrb) +{ + mrb_full_gc(mrb); +} + +/* + * Field write barrier + * Paint obj(Black) -> value(White) to obj(Black) -> value(Gray). + */ + +MRB_API void +mrb_field_write_barrier(mrb_state *mrb, struct RBasic *obj, struct RBasic *value) +{ + mrb_gc *gc = &mrb->gc; + + if (!is_black(obj)) return; + if (!is_white(value)) return; + + mrb_assert(gc->state == MRB_GC_STATE_MARK || (!is_dead(gc, value) && !is_dead(gc, obj))); + mrb_assert(is_generational(gc) || gc->state != MRB_GC_STATE_ROOT); + + if (is_generational(gc) || gc->state == MRB_GC_STATE_MARK) { + add_gray_list(mrb, gc, value); + } + else { + mrb_assert(gc->state == MRB_GC_STATE_SWEEP); + paint_partial_white(gc, obj); /* for never write barriers */ + } +} + +/* + * Write barrier + * Paint obj(Black) to obj(Gray). + * + * The object that is painted gray will be traversed atomically in final + * mark phase. So you use this write barrier if it's frequency written spot. + * e.g. Set element on Array. + */ + +MRB_API void +mrb_write_barrier(mrb_state *mrb, struct RBasic *obj) +{ + mrb_gc *gc = &mrb->gc; + + if (!is_black(obj)) return; + + mrb_assert(!is_dead(gc, obj)); + mrb_assert(is_generational(gc) || gc->state != MRB_GC_STATE_ROOT); + paint_gray(obj); + obj->gcnext = gc->atomic_gray_list; + gc->atomic_gray_list = obj; +} + +/* + * call-seq: + * GC.start -> nil + * + * Initiates full garbage collection. + * + */ + +static mrb_value +gc_start(mrb_state *mrb, mrb_value obj) +{ + mrb_full_gc(mrb); + return mrb_nil_value(); +} + +/* + * call-seq: + * GC.enable -> true or false + * + * Enables garbage collection, returning true if garbage + * collection was previously disabled. + * + * GC.disable #=> false + * GC.enable #=> true + * GC.enable #=> false + * + */ + +static mrb_value +gc_enable(mrb_state *mrb, mrb_value obj) +{ + mrb_bool old = mrb->gc.disabled; + + mrb->gc.disabled = FALSE; + + return mrb_bool_value(old); +} + +/* + * call-seq: + * GC.disable -> true or false + * + * Disables garbage collection, returning true if garbage + * collection was already disabled. + * + * GC.disable #=> false + * GC.disable #=> true + * + */ + +static mrb_value +gc_disable(mrb_state *mrb, mrb_value obj) +{ + mrb_bool old = mrb->gc.disabled; + + mrb->gc.disabled = TRUE; + + return mrb_bool_value(old); +} + +/* + * call-seq: + * GC.interval_ratio -> fixnum + * + * Returns ratio of GC interval. Default value is 200(%). + * + */ + +static mrb_value +gc_interval_ratio_get(mrb_state *mrb, mrb_value obj) +{ + return mrb_fixnum_value(mrb->gc.interval_ratio); +} + +/* + * call-seq: + * GC.interval_ratio = fixnum -> nil + * + * Updates ratio of GC interval. Default value is 200(%). + * GC start as soon as after end all step of GC if you set 100(%). + * + */ + +static mrb_value +gc_interval_ratio_set(mrb_state *mrb, mrb_value obj) +{ + mrb_int ratio; + + mrb_get_args(mrb, "i", &ratio); + mrb->gc.interval_ratio = ratio; + return mrb_nil_value(); +} + +/* + * call-seq: + * GC.step_ratio -> fixnum + * + * Returns step span ratio of Incremental GC. Default value is 200(%). + * + */ + +static mrb_value +gc_step_ratio_get(mrb_state *mrb, mrb_value obj) +{ + return mrb_fixnum_value(mrb->gc.step_ratio); +} + +/* + * call-seq: + * GC.step_ratio = fixnum -> nil + * + * Updates step span ratio of Incremental GC. Default value is 200(%). + * 1 step of incrementalGC becomes long if a rate is big. + * + */ + +static mrb_value +gc_step_ratio_set(mrb_state *mrb, mrb_value obj) +{ + mrb_int ratio; + + mrb_get_args(mrb, "i", &ratio); + mrb->gc.step_ratio = ratio; + return mrb_nil_value(); +} + +static void +change_gen_gc_mode(mrb_state *mrb, mrb_gc *gc, mrb_bool enable) +{ + if (gc->disabled || gc->iterating) { + mrb_raise(mrb, E_RUNTIME_ERROR, "generational mode changed when GC disabled"); + return; + } + if (is_generational(gc) && !enable) { + clear_all_old(mrb, gc); + mrb_assert(gc->state == MRB_GC_STATE_ROOT); + gc->full = FALSE; + } + else if (!is_generational(gc) && enable) { + incremental_gc_until(mrb, gc, MRB_GC_STATE_ROOT); + gc->majorgc_old_threshold = gc->live_after_mark/100 * DEFAULT_MAJOR_GC_INC_RATIO; + gc->full = FALSE; + } + gc->generational = enable; +} + +/* + * call-seq: + * GC.generational_mode -> true or false + * + * Returns generational or normal gc mode. + * + */ + +static mrb_value +gc_generational_mode_get(mrb_state *mrb, mrb_value self) +{ + return mrb_bool_value(mrb->gc.generational); +} + +/* + * call-seq: + * GC.generational_mode = true or false -> true or false + * + * Changes to generational or normal gc mode. + * + */ + +static mrb_value +gc_generational_mode_set(mrb_state *mrb, mrb_value self) +{ + mrb_bool enable; + + mrb_get_args(mrb, "b", &enable); + if (mrb->gc.generational != enable) + change_gen_gc_mode(mrb, &mrb->gc, enable); + + return mrb_bool_value(enable); +} + + +static void +gc_each_objects(mrb_state *mrb, mrb_gc *gc, mrb_each_object_callback *callback, void *data) +{ + mrb_heap_page* page; + + mrb_full_gc(mrb); + page = gc->heaps; + while (page != NULL) { + RVALUE *p; + int i; + + p = objects(page); + for (i=0; i < MRB_HEAP_PAGE_SIZE; i++) { + if ((*callback)(mrb, &p[i].as.basic, data) == MRB_EACH_OBJ_BREAK) + return; + } + page = page->next; + } +} + +void +mrb_objspace_each_objects(mrb_state *mrb, mrb_each_object_callback *callback, void *data) +{ + mrb_bool iterating = mrb->gc.iterating; + + mrb->gc.iterating = TRUE; + if (iterating) { + gc_each_objects(mrb, &mrb->gc, callback, data); + } + else { + struct mrb_jmpbuf *prev_jmp = mrb->jmp; + struct mrb_jmpbuf c_jmp; + + MRB_TRY(&c_jmp) { + mrb->jmp = &c_jmp; + gc_each_objects(mrb, &mrb->gc, callback, data); + mrb->jmp = prev_jmp; + mrb->gc.iterating = iterating; + } MRB_CATCH(&c_jmp) { + mrb->gc.iterating = iterating; + mrb->jmp = prev_jmp; + MRB_THROW(prev_jmp); + } MRB_END_EXC(&c_jmp); + } +} + +#ifdef GC_TEST +#ifdef GC_DEBUG +static mrb_value gc_test(mrb_state *, mrb_value); +#endif +#endif + +void +mrb_init_gc(mrb_state *mrb) +{ + struct RClass *gc; + + gc = mrb_define_module(mrb, "GC"); + + mrb_define_class_method(mrb, gc, "start", gc_start, MRB_ARGS_NONE()); + mrb_define_class_method(mrb, gc, "enable", gc_enable, MRB_ARGS_NONE()); + mrb_define_class_method(mrb, gc, "disable", gc_disable, MRB_ARGS_NONE()); + mrb_define_class_method(mrb, gc, "interval_ratio", gc_interval_ratio_get, MRB_ARGS_NONE()); + mrb_define_class_method(mrb, gc, "interval_ratio=", gc_interval_ratio_set, MRB_ARGS_REQ(1)); + mrb_define_class_method(mrb, gc, "step_ratio", gc_step_ratio_get, MRB_ARGS_NONE()); + mrb_define_class_method(mrb, gc, "step_ratio=", gc_step_ratio_set, MRB_ARGS_REQ(1)); + mrb_define_class_method(mrb, gc, "generational_mode=", gc_generational_mode_set, MRB_ARGS_REQ(1)); + mrb_define_class_method(mrb, gc, "generational_mode", gc_generational_mode_get, MRB_ARGS_NONE()); +#ifdef GC_TEST +#ifdef GC_DEBUG + mrb_define_class_method(mrb, gc, "test", gc_test, MRB_ARGS_NONE()); +#endif +#endif +} + +#ifdef GC_TEST +#ifdef GC_DEBUG +void +test_mrb_field_write_barrier(void) +{ + mrb_state *mrb = mrb_open(); + struct RBasic *obj, *value; + mrb_gc *gc = &mrb->gc; + + puts("test_mrb_field_write_barrier"); + gc->generational = FALSE; + obj = mrb_basic_ptr(mrb_ary_new(mrb)); + value = mrb_basic_ptr(mrb_str_new_lit(mrb, "value")); + paint_black(obj); + paint_partial_white(gc, value); + + + puts(" in MRB_GC_STATE_MARK"); + gc->state = MRB_GC_STATE_MARK; + mrb_field_write_barrier(mrb, obj, value); + + mrb_assert(is_gray(value)); + + + puts(" in MRB_GC_STATE_SWEEP"); + paint_partial_white(gc, value); + gc->state = MRB_GC_STATE_SWEEP; + mrb_field_write_barrier(mrb, obj, value); + + mrb_assert(obj->color & gc->current_white_part); + mrb_assert(value->color & gc->current_white_part); + + + puts(" fail with black"); + gc->state = MRB_GC_STATE_MARK; + paint_white(obj); + paint_partial_white(gc, value); + mrb_field_write_barrier(mrb, obj, value); + + mrb_assert(obj->color & gc->current_white_part); + + + puts(" fail with gray"); + gc->state = MRB_GC_STATE_MARK; + paint_black(obj); + paint_gray(value); + mrb_field_write_barrier(mrb, obj, value); + + mrb_assert(is_gray(value)); + + + { + puts("test_mrb_field_write_barrier_value"); + obj = mrb_basic_ptr(mrb_ary_new(mrb)); + mrb_value value = mrb_str_new_lit(mrb, "value"); + paint_black(obj); + paint_partial_white(gc, mrb_basic_ptr(value)); + + gc->state = MRB_GC_STATE_MARK; + mrb_field_write_barrier_value(mrb, obj, value); + + mrb_assert(is_gray(mrb_basic_ptr(value))); + } + + mrb_close(mrb); +} + +void +test_mrb_write_barrier(void) +{ + mrb_state *mrb = mrb_open(); + struct RBasic *obj; + mrb_gc *gc = &mrb->gc; + + puts("test_mrb_write_barrier"); + obj = mrb_basic_ptr(mrb_ary_new(mrb)); + paint_black(obj); + + puts(" in MRB_GC_STATE_MARK"); + gc->state = MRB_GC_STATE_MARK; + mrb_write_barrier(mrb, obj); + + mrb_assert(is_gray(obj)); + mrb_assert(gc->atomic_gray_list == obj); + + + puts(" fail with gray"); + paint_gray(obj); + mrb_write_barrier(mrb, obj); + + mrb_assert(is_gray(obj)); + + mrb_close(mrb); +} + +void +test_add_gray_list(void) +{ + mrb_state *mrb = mrb_open(); + struct RBasic *obj1, *obj2; + mrb_gc *gc = &mrb->gc; + + puts("test_add_gray_list"); + change_gen_gc_mode(mrb, gc, FALSE); + mrb_assert(gc->gray_list == NULL); + obj1 = mrb_basic_ptr(mrb_str_new_lit(mrb, "test")); + add_gray_list(mrb, gc, obj1); + mrb_assert(gc->gray_list == obj1); + mrb_assert(is_gray(obj1)); + + obj2 = mrb_basic_ptr(mrb_str_new_lit(mrb, "test")); + add_gray_list(mrb, gc, obj2); + mrb_assert(gc->gray_list == obj2); + mrb_assert(gc->gray_list->gcnext == obj1); + mrb_assert(is_gray(obj2)); + + mrb_close(mrb); +} + +void +test_gc_gray_mark(void) +{ + mrb_state *mrb = mrb_open(); + mrb_value obj_v, value_v; + struct RBasic *obj; + size_t gray_num = 0; + mrb_gc *gc = &mrb->gc; + + puts("test_gc_gray_mark"); + + puts(" in MRB_TT_CLASS"); + obj = (struct RBasic*)mrb->object_class; + paint_gray(obj); + gray_num = gc_gray_mark(mrb, gc, obj); + mrb_assert(is_black(obj)); + mrb_assert(gray_num > 1); + + puts(" in MRB_TT_ARRAY"); + obj_v = mrb_ary_new(mrb); + value_v = mrb_str_new_lit(mrb, "test"); + paint_gray(mrb_basic_ptr(obj_v)); + paint_partial_white(gc, mrb_basic_ptr(value_v)); + mrb_ary_push(mrb, obj_v, value_v); + gray_num = gc_gray_mark(mrb, gc, mrb_basic_ptr(obj_v)); + mrb_assert(is_black(mrb_basic_ptr(obj_v))); + mrb_assert(is_gray(mrb_basic_ptr(value_v))); + mrb_assert(gray_num == 1); + + mrb_close(mrb); +} + +void +test_incremental_gc(void) +{ + mrb_state *mrb = mrb_open(); + size_t max = ~0, live = 0, total = 0, freed = 0; + RVALUE *free; + mrb_heap_page *page; + mrb_gc *gc = &mrb->gc; + + puts("test_incremental_gc"); + change_gen_gc_mode(mrb, gc, FALSE); + + puts(" in mrb_full_gc"); + mrb_full_gc(mrb); + + mrb_assert(gc->state == MRB_GC_STATE_ROOT); + puts(" in MRB_GC_STATE_ROOT"); + incremental_gc(mrb, gc, max); + mrb_assert(gc->state == MRB_GC_STATE_MARK); + puts(" in MRB_GC_STATE_MARK"); + incremental_gc_until(mrb, gc, MRB_GC_STATE_SWEEP); + mrb_assert(gc->state == MRB_GC_STATE_SWEEP); + + puts(" in MRB_GC_STATE_SWEEP"); + page = gc->heaps; + while (page) { + RVALUE *p = objects(page); + RVALUE *e = p + MRB_HEAP_PAGE_SIZE; + while (pas.basic)) { + live++; + } + if (is_gray(&p->as.basic) && !is_dead(gc, &p->as.basic)) { + printf("%p\n", &p->as.basic); + } + p++; + } + page = page->next; + total += MRB_HEAP_PAGE_SIZE; + } + + mrb_assert(gc->gray_list == NULL); + + incremental_gc(mrb, gc, max); + mrb_assert(gc->state == MRB_GC_STATE_SWEEP); + + incremental_gc(mrb, gc, max); + mrb_assert(gc->state == MRB_GC_STATE_ROOT); + + free = (RVALUE*)gc->heaps->freelist; + while (free) { + freed++; + free = (RVALUE*)free->as.free.next; + } + + mrb_assert(gc->live == live); + mrb_assert(gc->live == total-freed); + + puts("test_incremental_gc(gen)"); + incremental_gc_until(mrb, gc, MRB_GC_STATE_SWEEP); + change_gen_gc_mode(mrb, gc, TRUE); + + mrb_assert(gc->full == FALSE); + mrb_assert(gc->state == MRB_GC_STATE_ROOT); + + puts(" in minor"); + mrb_assert(is_minor_gc(gc)); + mrb_assert(gc->majorgc_old_threshold > 0); + gc->majorgc_old_threshold = 0; + mrb_incremental_gc(mrb); + mrb_assert(gc->full == TRUE); + mrb_assert(gc->state == MRB_GC_STATE_ROOT); + + puts(" in major"); + mrb_assert(is_major_gc(gc)); + do { + mrb_incremental_gc(mrb); + } while (gc->state != MRB_GC_STATE_ROOT); + mrb_assert(gc->full == FALSE); + + mrb_close(mrb); +} + +void +test_incremental_sweep_phase(void) +{ + mrb_state *mrb = mrb_open(); + mrb_gc *gc = &mrb->gc; + + puts("test_incremental_sweep_phase"); + + add_heap(mrb, gc); + gc->sweeps = gc->heaps; + + mrb_assert(gc->heaps->next->next == NULL); + mrb_assert(gc->free_heaps->next->next == NULL); + incremental_sweep_phase(mrb, gc, MRB_HEAP_PAGE_SIZE * 3); + + mrb_assert(gc->heaps->next == NULL); + mrb_assert(gc->heaps == gc->free_heaps); + + mrb_close(mrb); +} + +static mrb_value +gc_test(mrb_state *mrb, mrb_value self) +{ + test_mrb_field_write_barrier(); + test_mrb_write_barrier(); + test_add_gray_list(); + test_gc_gray_mark(); + test_incremental_gc(); + test_incremental_sweep_phase(); + return mrb_nil_value(); +} +#endif /* GC_DEBUG */ +#endif /* GC_TEST */ diff --git a/web/server/h2o/libh2o/deps/mruby/src/hash.c b/web/server/h2o/libh2o/deps/mruby/src/hash.c new file mode 100644 index 00000000..93d55018 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/src/hash.c @@ -0,0 +1,905 @@ +/* +** hash.c - Hash class +** +** See Copyright Notice in mruby.h +*/ + +#include +#include +#include +#include +#include +#include +#include + +/* a function to get hash value of a float number */ +mrb_int mrb_float_id(mrb_float f); + +static inline khint_t +mrb_hash_ht_hash_func(mrb_state *mrb, mrb_value key) +{ + enum mrb_vtype t = mrb_type(key); + mrb_value hv; + khint_t h; + + switch (t) { + case MRB_TT_STRING: + h = mrb_str_hash(mrb, key); + break; + + case MRB_TT_TRUE: + case MRB_TT_FALSE: + case MRB_TT_SYMBOL: + case MRB_TT_FIXNUM: + case MRB_TT_FLOAT: + h = (khint_t)mrb_obj_id(key); + break; + + default: + hv = mrb_funcall(mrb, key, "hash", 0); + h = (khint_t)t ^ mrb_fixnum(hv); + break; + } + return kh_int_hash_func(mrb, h); +} + +static inline khint_t +mrb_hash_ht_hash_equal(mrb_state *mrb, mrb_value a, mrb_value b) +{ + enum mrb_vtype t = mrb_type(a); + + switch (t) { + case MRB_TT_STRING: + return mrb_str_equal(mrb, a, b); + + case MRB_TT_SYMBOL: + if (mrb_type(b) != MRB_TT_SYMBOL) return FALSE; + return mrb_symbol(a) == mrb_symbol(b); + + case MRB_TT_FIXNUM: + switch (mrb_type(b)) { + case MRB_TT_FIXNUM: + return mrb_fixnum(a) == mrb_fixnum(b); + case MRB_TT_FLOAT: + return (mrb_float)mrb_fixnum(a) == mrb_float(b); + default: + return FALSE; + } + + case MRB_TT_FLOAT: + switch (mrb_type(b)) { + case MRB_TT_FIXNUM: + return mrb_float(a) == (mrb_float)mrb_fixnum(b); + case MRB_TT_FLOAT: + return mrb_float(a) == mrb_float(b); + default: + return FALSE; + } + + default: + return mrb_eql(mrb, a, b); + } +} + +KHASH_DEFINE (ht, mrb_value, mrb_hash_value, TRUE, mrb_hash_ht_hash_func, mrb_hash_ht_hash_equal) + +static void mrb_hash_modify(mrb_state *mrb, mrb_value hash); + +static inline mrb_value +mrb_hash_ht_key(mrb_state *mrb, mrb_value key) +{ + if (mrb_string_p(key) && !MRB_FROZEN_P(mrb_str_ptr(key))) { + key = mrb_str_dup(mrb, key); + MRB_SET_FROZEN_FLAG(mrb_str_ptr(key)); + } + return key; +} + +#define KEY(key) mrb_hash_ht_key(mrb, key) + +void +mrb_gc_mark_hash(mrb_state *mrb, struct RHash *hash) +{ + khiter_t k; + khash_t(ht) *h = hash->ht; + + if (!h) return; + for (k = kh_begin(h); k != kh_end(h); k++) { + if (kh_exist(h, k)) { + mrb_value key = kh_key(h, k); + mrb_value val = kh_value(h, k).v; + + mrb_gc_mark_value(mrb, key); + mrb_gc_mark_value(mrb, val); + } + } +} + +size_t +mrb_gc_mark_hash_size(mrb_state *mrb, struct RHash *hash) +{ + if (!hash->ht) return 0; + return kh_size(hash->ht)*2; +} + +void +mrb_gc_free_hash(mrb_state *mrb, struct RHash *hash) +{ + if (hash->ht) kh_destroy(ht, mrb, hash->ht); +} + + +MRB_API mrb_value +mrb_hash_new_capa(mrb_state *mrb, mrb_int capa) +{ + struct RHash *h; + + h = (struct RHash*)mrb_obj_alloc(mrb, MRB_TT_HASH, mrb->hash_class); + /* khash needs 1/4 empty space so it is not resized immediately */ + h->ht = kh_init_size(ht, mrb, capa*4/3); + h->iv = 0; + return mrb_obj_value(h); +} + +MRB_API mrb_value +mrb_hash_new(mrb_state *mrb) +{ + return mrb_hash_new_capa(mrb, 0); +} + +static mrb_value mrb_hash_default(mrb_state *mrb, mrb_value hash); +static mrb_value hash_default(mrb_state *mrb, mrb_value hash, mrb_value key); + +MRB_API mrb_value +mrb_hash_get(mrb_state *mrb, mrb_value hash, mrb_value key) +{ + khash_t(ht) *h = RHASH_TBL(hash); + khiter_t k; + mrb_sym mid; + + if (h) { + k = kh_get(ht, mrb, h, key); + if (k != kh_end(h)) + return kh_value(h, k).v; + } + + mid = mrb_intern_lit(mrb, "default"); + if (mrb_func_basic_p(mrb, hash, mid, mrb_hash_default)) { + return hash_default(mrb, hash, key); + } + /* xxx mrb_funcall_tailcall(mrb, hash, "default", 1, key); */ + return mrb_funcall_argv(mrb, hash, mid, 1, &key); +} + +MRB_API mrb_value +mrb_hash_fetch(mrb_state *mrb, mrb_value hash, mrb_value key, mrb_value def) +{ + khash_t(ht) *h = RHASH_TBL(hash); + khiter_t k; + + if (h) { + k = kh_get(ht, mrb, h, key); + if (k != kh_end(h)) + return kh_value(h, k).v; + } + + /* not found */ + return def; +} + +MRB_API void +mrb_hash_set(mrb_state *mrb, mrb_value hash, mrb_value key, mrb_value val) +{ + khash_t(ht) *h; + khiter_t k; + int r; + + mrb_hash_modify(mrb, hash); + h = RHASH_TBL(hash); + + if (!h) h = RHASH_TBL(hash) = kh_init(ht, mrb); + k = kh_put2(ht, mrb, h, key, &r); + kh_value(h, k).v = val; + + if (r != 0) { + /* expand */ + int ai = mrb_gc_arena_save(mrb); + key = kh_key(h, k) = KEY(key); + mrb_gc_arena_restore(mrb, ai); + kh_value(h, k).n = kh_size(h)-1; + } + + mrb_field_write_barrier_value(mrb, (struct RBasic*)RHASH(hash), key); + mrb_field_write_barrier_value(mrb, (struct RBasic*)RHASH(hash), val); + return; +} + +static mrb_value +mrb_hash_dup(mrb_state *mrb, mrb_value hash) +{ + struct RHash* ret; + khash_t(ht) *h, *ret_h; + khiter_t k, ret_k; + mrb_value ifnone, vret; + + h = RHASH_TBL(hash); + ret = (struct RHash*)mrb_obj_alloc(mrb, MRB_TT_HASH, mrb->hash_class); + ret->ht = kh_init(ht, mrb); + + if (h && kh_size(h) > 0) { + ret_h = ret->ht; + + for (k = kh_begin(h); k != kh_end(h); k++) { + if (kh_exist(h, k)) { + int ai = mrb_gc_arena_save(mrb); + ret_k = kh_put(ht, mrb, ret_h, KEY(kh_key(h, k))); + mrb_gc_arena_restore(mrb, ai); + kh_val(ret_h, ret_k).v = kh_val(h, k).v; + kh_val(ret_h, ret_k).n = kh_size(ret_h)-1; + } + } + } + + if (MRB_RHASH_DEFAULT_P(hash)) { + ret->flags |= MRB_HASH_DEFAULT; + } + if (MRB_RHASH_PROCDEFAULT_P(hash)) { + ret->flags |= MRB_HASH_PROC_DEFAULT; + } + vret = mrb_obj_value(ret); + ifnone = RHASH_IFNONE(hash); + if (!mrb_nil_p(ifnone)) { + mrb_iv_set(mrb, vret, mrb_intern_lit(mrb, "ifnone"), ifnone); + } + return vret; +} + +MRB_API mrb_value +mrb_check_hash_type(mrb_state *mrb, mrb_value hash) +{ + return mrb_check_convert_type(mrb, hash, MRB_TT_HASH, "Hash", "to_hash"); +} + +MRB_API khash_t(ht)* +mrb_hash_tbl(mrb_state *mrb, mrb_value hash) +{ + khash_t(ht) *h = RHASH_TBL(hash); + + if (!h) { + return RHASH_TBL(hash) = kh_init(ht, mrb); + } + return h; +} + +static void +mrb_hash_modify(mrb_state *mrb, mrb_value hash) +{ + if (MRB_FROZEN_P(mrb_hash_ptr(hash))) { + mrb_raise(mrb, E_RUNTIME_ERROR, "can't modify frozen hash"); + } + mrb_hash_tbl(mrb, hash); +} + +/* 15.2.13.4.16 */ +/* + * call-seq: + * Hash.new -> new_hash + * Hash.new(obj) -> new_hash + * Hash.new {|hash, key| block } -> new_hash + * + * Returns a new, empty hash. If this hash is subsequently accessed by + * a key that doesn't correspond to a hash entry, the value returned + * depends on the style of new used to create the hash. In + * the first form, the access returns nil. If + * obj is specified, this single object will be used for + * all default values. If a block is specified, it will be + * called with the hash object and the key, and should return the + * default value. It is the block's responsibility to store the value + * in the hash if required. + * + * h = Hash.new("Go Fish") + * h["a"] = 100 + * h["b"] = 200 + * h["a"] #=> 100 + * h["c"] #=> "Go Fish" + * # The following alters the single default object + * h["c"].upcase! #=> "GO FISH" + * h["d"] #=> "GO FISH" + * h.keys #=> ["a", "b"] + * + * # While this creates a new default object each time + * h = Hash.new { |hash, key| hash[key] = "Go Fish: #{key}" } + * h["c"] #=> "Go Fish: c" + * h["c"].upcase! #=> "GO FISH: C" + * h["d"] #=> "Go Fish: d" + * h.keys #=> ["c", "d"] + * + */ + +static mrb_value +mrb_hash_init(mrb_state *mrb, mrb_value hash) +{ + mrb_value block, ifnone; + mrb_bool ifnone_p; + + ifnone = mrb_nil_value(); + mrb_get_args(mrb, "&|o?", &block, &ifnone, &ifnone_p); + mrb_hash_modify(mrb, hash); + if (!mrb_nil_p(block)) { + if (ifnone_p) { + mrb_raise(mrb, E_ARGUMENT_ERROR, "wrong number of arguments"); + } + RHASH(hash)->flags |= MRB_HASH_PROC_DEFAULT; + ifnone = block; + } + if (!mrb_nil_p(ifnone)) { + RHASH(hash)->flags |= MRB_HASH_DEFAULT; + mrb_iv_set(mrb, hash, mrb_intern_lit(mrb, "ifnone"), ifnone); + } + return hash; +} + +/* 15.2.13.4.2 */ +/* + * call-seq: + * hsh[key] -> value + * + * Element Reference---Retrieves the value object corresponding + * to the key object. If not found, returns the default value (see + * Hash::new for details). + * + * h = { "a" => 100, "b" => 200 } + * h["a"] #=> 100 + * h["c"] #=> nil + * + */ +static mrb_value +mrb_hash_aget(mrb_state *mrb, mrb_value self) +{ + mrb_value key; + + mrb_get_args(mrb, "o", &key); + return mrb_hash_get(mrb, self, key); +} + +static mrb_value +hash_default(mrb_state *mrb, mrb_value hash, mrb_value key) +{ + if (MRB_RHASH_DEFAULT_P(hash)) { + if (MRB_RHASH_PROCDEFAULT_P(hash)) { + return mrb_funcall(mrb, RHASH_PROCDEFAULT(hash), "call", 2, hash, key); + } + else { + return RHASH_IFNONE(hash); + } + } + return mrb_nil_value(); +} + +/* 15.2.13.4.5 */ +/* + * call-seq: + * hsh.default(key=nil) -> obj + * + * Returns the default value, the value that would be returned by + * hsh[key] if key did not exist in hsh. + * See also Hash::new and Hash#default=. + * + * h = Hash.new #=> {} + * h.default #=> nil + * h.default(2) #=> nil + * + * h = Hash.new("cat") #=> {} + * h.default #=> "cat" + * h.default(2) #=> "cat" + * + * h = Hash.new {|h,k| h[k] = k.to_i*10} #=> {} + * h.default #=> nil + * h.default(2) #=> 20 + */ + +static mrb_value +mrb_hash_default(mrb_state *mrb, mrb_value hash) +{ + mrb_value key; + mrb_bool given; + + mrb_get_args(mrb, "|o?", &key, &given); + if (MRB_RHASH_DEFAULT_P(hash)) { + if (MRB_RHASH_PROCDEFAULT_P(hash)) { + if (!given) return mrb_nil_value(); + return mrb_funcall(mrb, RHASH_PROCDEFAULT(hash), "call", 2, hash, key); + } + else { + return RHASH_IFNONE(hash); + } + } + return mrb_nil_value(); +} + +/* 15.2.13.4.6 */ +/* + * call-seq: + * hsh.default = obj -> obj + * + * Sets the default value, the value returned for a key that does not + * exist in the hash. It is not possible to set the default to a + * Proc that will be executed on each key lookup. + * + * h = { "a" => 100, "b" => 200 } + * h.default = "Go fish" + * h["a"] #=> 100 + * h["z"] #=> "Go fish" + * # This doesn't do what you might hope... + * h.default = proc do |hash, key| + * hash[key] = key + key + * end + * h[2] #=> # + * h["cat"] #=> # + */ + +static mrb_value +mrb_hash_set_default(mrb_state *mrb, mrb_value hash) +{ + mrb_value ifnone; + + mrb_get_args(mrb, "o", &ifnone); + mrb_hash_modify(mrb, hash); + mrb_iv_set(mrb, hash, mrb_intern_lit(mrb, "ifnone"), ifnone); + RHASH(hash)->flags &= ~MRB_HASH_PROC_DEFAULT; + if (!mrb_nil_p(ifnone)) { + RHASH(hash)->flags |= MRB_HASH_DEFAULT; + } + else { + RHASH(hash)->flags &= ~MRB_HASH_DEFAULT; + } + return ifnone; +} + +/* 15.2.13.4.7 */ +/* + * call-seq: + * hsh.default_proc -> anObject + * + * If Hash::new was invoked with a block, return that + * block, otherwise return nil. + * + * h = Hash.new {|h,k| h[k] = k*k } #=> {} + * p = h.default_proc #=> # + * a = [] #=> [] + * p.call(a, 2) + * a #=> [nil, nil, 4] + */ + + +static mrb_value +mrb_hash_default_proc(mrb_state *mrb, mrb_value hash) +{ + if (MRB_RHASH_PROCDEFAULT_P(hash)) { + return RHASH_PROCDEFAULT(hash); + } + return mrb_nil_value(); +} + +/* + * call-seq: + * hsh.default_proc = proc_obj -> proc_obj + * + * Sets the default proc to be executed on each key lookup. + * + * h.default_proc = proc do |hash, key| + * hash[key] = key + key + * end + * h[2] #=> 4 + * h["cat"] #=> "catcat" + */ + +static mrb_value +mrb_hash_set_default_proc(mrb_state *mrb, mrb_value hash) +{ + mrb_value ifnone; + + mrb_get_args(mrb, "o", &ifnone); + mrb_hash_modify(mrb, hash); + mrb_iv_set(mrb, hash, mrb_intern_lit(mrb, "ifnone"), ifnone); + if (!mrb_nil_p(ifnone)) { + RHASH(hash)->flags |= MRB_HASH_PROC_DEFAULT; + RHASH(hash)->flags |= MRB_HASH_DEFAULT; + } + else { + RHASH(hash)->flags &= ~MRB_HASH_DEFAULT; + RHASH(hash)->flags &= ~MRB_HASH_PROC_DEFAULT; + } + + return ifnone; +} + +MRB_API mrb_value +mrb_hash_delete_key(mrb_state *mrb, mrb_value hash, mrb_value key) +{ + khash_t(ht) *h = RHASH_TBL(hash); + khiter_t k; + mrb_value delVal; + mrb_int n; + + if (h) { + k = kh_get(ht, mrb, h, key); + if (k != kh_end(h)) { + delVal = kh_value(h, k).v; + n = kh_value(h, k).n; + kh_del(ht, mrb, h, k); + for (k = kh_begin(h); k != kh_end(h); k++) { + if (!kh_exist(h, k)) continue; + if (kh_value(h, k).n > n) kh_value(h, k).n--; + } + return delVal; + } + } + + /* not found */ + return mrb_nil_value(); +} + +/* 15.2.13.4.8 */ +/* + * call-seq: + * hsh.delete(key) -> value + * hsh.delete(key) {| key | block } -> value + * + * Deletes and returns a key-value pair from hsh whose key is + * equal to key. If the key is not found, returns the + * default value. If the optional code block is given and the + * key is not found, pass in the key and return the result of + * block. + * + * h = { "a" => 100, "b" => 200 } + * h.delete("a") #=> 100 + * h.delete("z") #=> nil + * h.delete("z") { |el| "#{el} not found" } #=> "z not found" + * + */ +static mrb_value +mrb_hash_delete(mrb_state *mrb, mrb_value self) +{ + mrb_value key; + + mrb_get_args(mrb, "o", &key); + mrb_hash_modify(mrb, self); + return mrb_hash_delete_key(mrb, self, key); +} + +/* 15.2.13.4.24 */ +/* + * call-seq: + * hsh.shift -> anArray or obj + * + * Removes a key-value pair from hsh and returns it as the + * two-item array [ key, value ], or + * the hash's default value if the hash is empty. + * + * h = { 1 => "a", 2 => "b", 3 => "c" } + * h.shift #=> [1, "a"] + * h #=> {2=>"b", 3=>"c"} + */ + +static mrb_value +mrb_hash_shift(mrb_state *mrb, mrb_value hash) +{ + khash_t(ht) *h = RHASH_TBL(hash); + khiter_t k; + mrb_value delKey, delVal; + + mrb_hash_modify(mrb, hash); + if (h && kh_size(h) > 0) { + for (k = kh_begin(h); k != kh_end(h); k++) { + if (!kh_exist(h, k)) continue; + + delKey = kh_key(h, k); + mrb_gc_protect(mrb, delKey); + delVal = mrb_hash_delete_key(mrb, hash, delKey); + mrb_gc_protect(mrb, delVal); + + return mrb_assoc_new(mrb, delKey, delVal); + } + } + + if (MRB_RHASH_DEFAULT_P(hash)) { + if (MRB_RHASH_PROCDEFAULT_P(hash)) { + return mrb_funcall(mrb, RHASH_PROCDEFAULT(hash), "call", 2, hash, mrb_nil_value()); + } + else { + return RHASH_IFNONE(hash); + } + } + return mrb_nil_value(); +} + +/* 15.2.13.4.4 */ +/* + * call-seq: + * hsh.clear -> hsh + * + * Removes all key-value pairs from `hsh`. + * + * h = { "a" => 100, "b" => 200 } #=> {"a"=>100, "b"=>200} + * h.clear #=> {} + * + */ + +MRB_API mrb_value +mrb_hash_clear(mrb_state *mrb, mrb_value hash) +{ + khash_t(ht) *h = RHASH_TBL(hash); + + mrb_hash_modify(mrb, hash); + if (h) kh_clear(ht, mrb, h); + return hash; +} + +/* 15.2.13.4.3 */ +/* 15.2.13.4.26 */ +/* + * call-seq: + * hsh[key] = value -> value + * hsh.store(key, value) -> value + * + * Element Assignment---Associates the value given by + * value with the key given by key. + * key should not have its value changed while it is in + * use as a key (a String passed as a key will be + * duplicated and frozen). + * + * h = { "a" => 100, "b" => 200 } + * h["a"] = 9 + * h["c"] = 4 + * h #=> {"a"=>9, "b"=>200, "c"=>4} + * + */ +static mrb_value +mrb_hash_aset(mrb_state *mrb, mrb_value self) +{ + mrb_value key, val; + + mrb_get_args(mrb, "oo", &key, &val); + mrb_hash_set(mrb, self, key, val); + return val; +} + +/* 15.2.13.4.20 */ +/* 15.2.13.4.25 */ +/* + * call-seq: + * hsh.length -> fixnum + * hsh.size -> fixnum + * + * Returns the number of key-value pairs in the hash. + * + * h = { "d" => 100, "a" => 200, "v" => 300, "e" => 400 } + * h.length #=> 4 + * h.delete("a") #=> 200 + * h.length #=> 3 + */ +static mrb_value +mrb_hash_size_m(mrb_state *mrb, mrb_value self) +{ + khash_t(ht) *h = RHASH_TBL(self); + + if (!h) return mrb_fixnum_value(0); + return mrb_fixnum_value(kh_size(h)); +} + +/* 15.2.13.4.12 */ +/* + * call-seq: + * hsh.empty? -> true or false + * + * Returns true if hsh contains no key-value pairs. + * + * {}.empty? #=> true + * + */ +MRB_API mrb_value +mrb_hash_empty_p(mrb_state *mrb, mrb_value self) +{ + khash_t(ht) *h = RHASH_TBL(self); + + if (h) return mrb_bool_value(kh_size(h) == 0); + return mrb_true_value(); +} + +/* 15.2.13.4.29 (x)*/ +/* + * call-seq: + * hsh.to_hash => hsh + * + * Returns +self+. + */ + +static mrb_value +mrb_hash_to_hash(mrb_state *mrb, mrb_value hash) +{ + return hash; +} + +/* 15.2.13.4.19 */ +/* + * call-seq: + * hsh.keys -> array + * + * Returns a new array populated with the keys from this hash. See also + * Hash#values. + * + * h = { "a" => 100, "b" => 200, "c" => 300, "d" => 400 } + * h.keys #=> ["a", "b", "c", "d"] + * + */ + +MRB_API mrb_value +mrb_hash_keys(mrb_state *mrb, mrb_value hash) +{ + khash_t(ht) *h = RHASH_TBL(hash); + khiter_t k; + mrb_int end; + mrb_value ary; + mrb_value *p; + + if (!h || kh_size(h) == 0) return mrb_ary_new(mrb); + ary = mrb_ary_new_capa(mrb, kh_size(h)); + end = kh_size(h)-1; + mrb_ary_set(mrb, ary, end, mrb_nil_value()); + p = RARRAY_PTR(ary); + for (k = kh_begin(h); k != kh_end(h); k++) { + if (kh_exist(h, k)) { + mrb_value kv = kh_key(h, k); + mrb_hash_value hv = kh_value(h, k); + + if (hv.n <= end) { + p[hv.n] = kv; + } + else { + p[end] = kv; + } + } + } + return ary; +} + +/* 15.2.13.4.28 */ +/* + * call-seq: + * hsh.values -> array + * + * Returns a new array populated with the values from hsh. See + * also Hash#keys. + * + * h = { "a" => 100, "b" => 200, "c" => 300 } + * h.values #=> [100, 200, 300] + * + */ + +MRB_API mrb_value +mrb_hash_values(mrb_state *mrb, mrb_value hash) +{ + khash_t(ht) *h = RHASH_TBL(hash); + khiter_t k; + mrb_value ary; + + if (!h) return mrb_ary_new(mrb); + ary = mrb_ary_new_capa(mrb, kh_size(h)); + for (k = kh_begin(h); k != kh_end(h); k++) { + if (kh_exist(h, k)) { + mrb_hash_value hv = kh_value(h, k); + + mrb_ary_set(mrb, ary, hv.n, hv.v); + } + } + return ary; +} + +/* 15.2.13.4.13 */ +/* 15.2.13.4.15 */ +/* 15.2.13.4.18 */ +/* 15.2.13.4.21 */ +/* + * call-seq: + * hsh.has_key?(key) -> true or false + * hsh.include?(key) -> true or false + * hsh.key?(key) -> true or false + * hsh.member?(key) -> true or false + * + * Returns true if the given key is present in hsh. + * + * h = { "a" => 100, "b" => 200 } + * h.has_key?("a") #=> true + * h.has_key?("z") #=> false + * + */ + +static mrb_value +mrb_hash_has_key(mrb_state *mrb, mrb_value hash) +{ + mrb_value key; + khash_t(ht) *h; + khiter_t k; + + mrb_get_args(mrb, "o", &key); + + h = RHASH_TBL(hash); + if (h) { + k = kh_get(ht, mrb, h, key); + return mrb_bool_value(k != kh_end(h)); + } + return mrb_false_value(); +} + +/* 15.2.13.4.14 */ +/* 15.2.13.4.27 */ +/* + * call-seq: + * hsh.has_value?(value) -> true or false + * hsh.value?(value) -> true or false + * + * Returns true if the given value is present for some key + * in hsh. + * + * h = { "a" => 100, "b" => 200 } + * h.has_value?(100) #=> true + * h.has_value?(999) #=> false + */ + +static mrb_value +mrb_hash_has_value(mrb_state *mrb, mrb_value hash) +{ + mrb_value val; + khash_t(ht) *h; + khiter_t k; + + mrb_get_args(mrb, "o", &val); + h = RHASH_TBL(hash); + + if (h) { + for (k = kh_begin(h); k != kh_end(h); k++) { + if (!kh_exist(h, k)) continue; + + if (mrb_equal(mrb, kh_value(h, k).v, val)) { + return mrb_true_value(); + } + } + } + return mrb_false_value(); +} + +void +mrb_init_hash(mrb_state *mrb) +{ + struct RClass *h; + + mrb->hash_class = h = mrb_define_class(mrb, "Hash", mrb->object_class); /* 15.2.13 */ + MRB_SET_INSTANCE_TT(h, MRB_TT_HASH); + + mrb_define_method(mrb, h, "[]", mrb_hash_aget, MRB_ARGS_REQ(1)); /* 15.2.13.4.2 */ + mrb_define_method(mrb, h, "[]=", mrb_hash_aset, MRB_ARGS_REQ(2)); /* 15.2.13.4.3 */ + mrb_define_method(mrb, h, "clear", mrb_hash_clear, MRB_ARGS_NONE()); /* 15.2.13.4.4 */ + mrb_define_method(mrb, h, "default", mrb_hash_default, MRB_ARGS_ANY()); /* 15.2.13.4.5 */ + mrb_define_method(mrb, h, "default=", mrb_hash_set_default, MRB_ARGS_REQ(1)); /* 15.2.13.4.6 */ + mrb_define_method(mrb, h, "default_proc", mrb_hash_default_proc,MRB_ARGS_NONE()); /* 15.2.13.4.7 */ + mrb_define_method(mrb, h, "default_proc=", mrb_hash_set_default_proc,MRB_ARGS_REQ(1)); /* 15.2.13.4.7 */ + mrb_define_method(mrb, h, "__delete", mrb_hash_delete, MRB_ARGS_REQ(1)); /* core of 15.2.13.4.8 */ + mrb_define_method(mrb, h, "empty?", mrb_hash_empty_p, MRB_ARGS_NONE()); /* 15.2.13.4.12 */ + mrb_define_method(mrb, h, "has_key?", mrb_hash_has_key, MRB_ARGS_REQ(1)); /* 15.2.13.4.13 */ + mrb_define_method(mrb, h, "has_value?", mrb_hash_has_value, MRB_ARGS_REQ(1)); /* 15.2.13.4.14 */ + mrb_define_method(mrb, h, "include?", mrb_hash_has_key, MRB_ARGS_REQ(1)); /* 15.2.13.4.15 */ + mrb_define_method(mrb, h, "initialize", mrb_hash_init, MRB_ARGS_OPT(1)); /* 15.2.13.4.16 */ + mrb_define_method(mrb, h, "key?", mrb_hash_has_key, MRB_ARGS_REQ(1)); /* 15.2.13.4.18 */ + mrb_define_method(mrb, h, "keys", mrb_hash_keys, MRB_ARGS_NONE()); /* 15.2.13.4.19 */ + mrb_define_method(mrb, h, "length", mrb_hash_size_m, MRB_ARGS_NONE()); /* 15.2.13.4.20 */ + mrb_define_method(mrb, h, "member?", mrb_hash_has_key, MRB_ARGS_REQ(1)); /* 15.2.13.4.21 */ + mrb_define_method(mrb, h, "shift", mrb_hash_shift, MRB_ARGS_NONE()); /* 15.2.13.4.24 */ + mrb_define_method(mrb, h, "dup", mrb_hash_dup, MRB_ARGS_NONE()); + mrb_define_method(mrb, h, "size", mrb_hash_size_m, MRB_ARGS_NONE()); /* 15.2.13.4.25 */ + mrb_define_method(mrb, h, "store", mrb_hash_aset, MRB_ARGS_REQ(2)); /* 15.2.13.4.26 */ + mrb_define_method(mrb, h, "value?", mrb_hash_has_value, MRB_ARGS_REQ(1)); /* 15.2.13.4.27 */ + mrb_define_method(mrb, h, "values", mrb_hash_values, MRB_ARGS_NONE()); /* 15.2.13.4.28 */ + + mrb_define_method(mrb, h, "to_hash", mrb_hash_to_hash, MRB_ARGS_NONE()); /* 15.2.13.4.29 (x)*/ +} diff --git a/web/server/h2o/libh2o/deps/mruby/src/init.c b/web/server/h2o/libh2o/deps/mruby/src/init.c new file mode 100644 index 00000000..afd69975 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/src/init.c @@ -0,0 +1,51 @@ +/* +** init.c - initialize mruby core +** +** See Copyright Notice in mruby.h +*/ + +#include + +void mrb_init_symtbl(mrb_state*); +void mrb_init_class(mrb_state*); +void mrb_init_object(mrb_state*); +void mrb_init_kernel(mrb_state*); +void mrb_init_comparable(mrb_state*); +void mrb_init_enumerable(mrb_state*); +void mrb_init_symbol(mrb_state*); +void mrb_init_string(mrb_state*); +void mrb_init_exception(mrb_state*); +void mrb_init_proc(mrb_state*); +void mrb_init_array(mrb_state*); +void mrb_init_hash(mrb_state*); +void mrb_init_numeric(mrb_state*); +void mrb_init_range(mrb_state*); +void mrb_init_gc(mrb_state*); +void mrb_init_math(mrb_state*); +void mrb_init_version(mrb_state*); +void mrb_init_mrblib(mrb_state*); + +#define DONE mrb_gc_arena_restore(mrb, 0); +void +mrb_init_core(mrb_state *mrb) +{ + mrb_init_symtbl(mrb); DONE; + + mrb_init_class(mrb); DONE; + mrb_init_object(mrb); DONE; + mrb_init_kernel(mrb); DONE; + mrb_init_comparable(mrb); DONE; + mrb_init_enumerable(mrb); DONE; + + mrb_init_symbol(mrb); DONE; + mrb_init_string(mrb); DONE; + mrb_init_exception(mrb); DONE; + mrb_init_proc(mrb); DONE; + mrb_init_array(mrb); DONE; + mrb_init_hash(mrb); DONE; + mrb_init_numeric(mrb); DONE; + mrb_init_range(mrb); DONE; + mrb_init_gc(mrb); DONE; + mrb_init_version(mrb); DONE; + mrb_init_mrblib(mrb); DONE; +} diff --git a/web/server/h2o/libh2o/deps/mruby/src/kernel.c b/web/server/h2o/libh2o/deps/mruby/src/kernel.c new file mode 100644 index 00000000..4e95ab24 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/src/kernel.c @@ -0,0 +1,1238 @@ +/* +** kernel.c - Kernel module +** +** See Copyright Notice in mruby.h +*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +typedef enum { + NOEX_PUBLIC = 0x00, + NOEX_NOSUPER = 0x01, + NOEX_PRIVATE = 0x02, + NOEX_PROTECTED = 0x04, + NOEX_MASK = 0x06, + NOEX_BASIC = 0x08, + NOEX_UNDEF = NOEX_NOSUPER, + NOEX_MODFUNC = 0x12, + NOEX_SUPER = 0x20, + NOEX_VCALL = 0x40, + NOEX_RESPONDS = 0x80 +} mrb_method_flag_t; + +MRB_API mrb_bool +mrb_func_basic_p(mrb_state *mrb, mrb_value obj, mrb_sym mid, mrb_func_t func) +{ + struct RProc *me = mrb_method_search(mrb, mrb_class(mrb, obj), mid); + if (MRB_PROC_CFUNC_P(me) && (me->body.func == func)) + return TRUE; + return FALSE; +} + +static mrb_bool +mrb_obj_basic_to_s_p(mrb_state *mrb, mrb_value obj) +{ + return mrb_func_basic_p(mrb, obj, mrb_intern_lit(mrb, "to_s"), mrb_any_to_s); +} + +/* 15.3.1.3.17 */ +/* + * call-seq: + * obj.inspect -> string + * + * Returns a string containing a human-readable representation of + * obj. If not overridden and no instance variables, uses the + * to_s method to generate the string. + * obj. If not overridden, uses the to_s method to + * generate the string. + * + * [ 1, 2, 3..4, 'five' ].inspect #=> "[1, 2, 3..4, \"five\"]" + * Time.new.inspect #=> "2008-03-08 19:43:39 +0900" + */ +MRB_API mrb_value +mrb_obj_inspect(mrb_state *mrb, mrb_value obj) +{ + if ((mrb_type(obj) == MRB_TT_OBJECT) && mrb_obj_basic_to_s_p(mrb, obj)) { + return mrb_obj_iv_inspect(mrb, mrb_obj_ptr(obj)); + } + return mrb_any_to_s(mrb, obj); +} + +/* 15.3.1.3.2 */ +/* + * call-seq: + * obj === other -> true or false + * + * Case Equality---For class Object, effectively the same + * as calling #==, but typically overridden by descendants + * to provide meaningful semantics in case statements. + */ +static mrb_value +mrb_equal_m(mrb_state *mrb, mrb_value self) +{ + mrb_value arg; + + mrb_get_args(mrb, "o", &arg); + return mrb_bool_value(mrb_equal(mrb, self, arg)); +} + +/* 15.3.1.3.3 */ +/* 15.3.1.3.33 */ +/* + * Document-method: __id__ + * Document-method: object_id + * + * call-seq: + * obj.__id__ -> fixnum + * obj.object_id -> fixnum + * + * Returns an integer identifier for obj. The same number will + * be returned on all calls to id for a given object, and + * no two active objects will share an id. + * Object#object_id is a different concept from the + * :name notation, which returns the symbol id of + * name. Replaces the deprecated Object#id. + */ +mrb_value +mrb_obj_id_m(mrb_state *mrb, mrb_value self) +{ + return mrb_fixnum_value(mrb_obj_id(self)); +} + +/* 15.3.1.2.2 */ +/* 15.3.1.2.5 */ +/* 15.3.1.3.6 */ +/* 15.3.1.3.25 */ +/* + * call-seq: + * block_given? -> true or false + * iterator? -> true or false + * + * Returns true if yield would execute a + * block in the current context. The iterator? form + * is mildly deprecated. + * + * def try + * if block_given? + * yield + * else + * "no block" + * end + * end + * try #=> "no block" + * try { "hello" } #=> "hello" + * try do "hello" end #=> "hello" + */ +static mrb_value +mrb_f_block_given_p_m(mrb_state *mrb, mrb_value self) +{ + mrb_callinfo *ci = mrb->c->ci; + mrb_value *bp; + + bp = ci->stackent + 1; + ci--; + if (ci <= mrb->c->cibase) { + return mrb_false_value(); + } + /* block_given? called within block; check upper scope */ + if (ci->proc->env) { + struct REnv *e = ci->proc->env; + + while (e->c) { + e = (struct REnv*)e->c; + } + /* top-level does not have block slot (always false) */ + if (e->stack == mrb->c->stbase) + return mrb_false_value(); + if (e->stack && e->cioff < 0) { + /* use saved block arg position */ + bp = &e->stack[-e->cioff]; + ci = 0; /* no callinfo available */ + } + else { + ci = e->cxt.c->cibase + e->cioff; + bp = ci[1].stackent + 1; + } + } + if (ci && ci->argc > 0) { + bp += ci->argc; + } + if (mrb_nil_p(*bp)) + return mrb_false_value(); + return mrb_true_value(); +} + +/* 15.3.1.3.7 */ +/* + * call-seq: + * obj.class -> class + * + * Returns the class of obj. This method must always be + * called with an explicit receiver, as class is also a + * reserved word in Ruby. + * + * 1.class #=> Fixnum + * self.class #=> Object + */ +static mrb_value +mrb_obj_class_m(mrb_state *mrb, mrb_value self) +{ + return mrb_obj_value(mrb_obj_class(mrb, self)); +} + +static struct RClass* +mrb_singleton_class_clone(mrb_state *mrb, mrb_value obj) +{ + struct RClass *klass = mrb_basic_ptr(obj)->c; + + if (klass->tt != MRB_TT_SCLASS) + return klass; + else { + /* copy singleton(unnamed) class */ + struct RClass *clone = (struct RClass*)mrb_obj_alloc(mrb, klass->tt, mrb->class_class); + + switch (mrb_type(obj)) { + case MRB_TT_CLASS: + case MRB_TT_SCLASS: + break; + default: + clone->c = mrb_singleton_class_clone(mrb, mrb_obj_value(klass)); + break; + } + clone->super = klass->super; + if (klass->iv) { + mrb_iv_copy(mrb, mrb_obj_value(clone), mrb_obj_value(klass)); + mrb_obj_iv_set(mrb, (struct RObject*)clone, mrb_intern_lit(mrb, "__attached__"), obj); + } + if (klass->mt) { + clone->mt = kh_copy(mt, mrb, klass->mt); + } + else { + clone->mt = kh_init(mt, mrb); + } + clone->tt = MRB_TT_SCLASS; + return clone; + } +} + +static void +copy_class(mrb_state *mrb, mrb_value dst, mrb_value src) +{ + struct RClass *dc = mrb_class_ptr(dst); + struct RClass *sc = mrb_class_ptr(src); + /* if the origin is not the same as the class, then the origin and + the current class need to be copied */ + if (sc->flags & MRB_FLAG_IS_PREPENDED) { + struct RClass *c0 = sc->super; + struct RClass *c1 = dc; + + /* copy prepended iclasses */ + while (!(c0->flags & MRB_FLAG_IS_ORIGIN)) { + c1->super = mrb_class_ptr(mrb_obj_dup(mrb, mrb_obj_value(c0))); + c1 = c1->super; + c0 = c0->super; + } + c1->super = mrb_class_ptr(mrb_obj_dup(mrb, mrb_obj_value(c0))); + c1->super->flags |= MRB_FLAG_IS_ORIGIN; + } + if (sc->mt) { + dc->mt = kh_copy(mt, mrb, sc->mt); + } + else { + dc->mt = kh_init(mt, mrb); + } + dc->super = sc->super; + MRB_SET_INSTANCE_TT(dc, MRB_INSTANCE_TT(sc)); +} + +static void +init_copy(mrb_state *mrb, mrb_value dest, mrb_value obj) +{ + switch (mrb_type(obj)) { + case MRB_TT_CLASS: + case MRB_TT_MODULE: + copy_class(mrb, dest, obj); + /* fall through */ + case MRB_TT_OBJECT: + case MRB_TT_SCLASS: + case MRB_TT_HASH: + case MRB_TT_DATA: + case MRB_TT_EXCEPTION: + mrb_iv_copy(mrb, dest, obj); + break; + case MRB_TT_ISTRUCT: + mrb_istruct_copy(dest, obj); + break; + + default: + break; + } + mrb_funcall(mrb, dest, "initialize_copy", 1, obj); +} + +/* 15.3.1.3.8 */ +/* + * call-seq: + * obj.clone -> an_object + * + * Produces a shallow copy of obj---the instance variables of + * obj are copied, but not the objects they reference. Copies + * the frozen state of obj. See also the discussion + * under Object#dup. + * + * class Klass + * attr_accessor :str + * end + * s1 = Klass.new #=> # + * s1.str = "Hello" #=> "Hello" + * s2 = s1.clone #=> # + * s2.str[1,4] = "i" #=> "i" + * s1.inspect #=> "#" + * s2.inspect #=> "#" + * + * This method may have class-specific behavior. If so, that + * behavior will be documented under the #+initialize_copy+ method of + * the class. + * + * Some Class(True False Nil Symbol Fixnum Float) Object cannot clone. + */ +MRB_API mrb_value +mrb_obj_clone(mrb_state *mrb, mrb_value self) +{ + struct RObject *p; + mrb_value clone; + + if (mrb_immediate_p(self)) { + mrb_raisef(mrb, E_TYPE_ERROR, "can't clone %S", self); + } + if (mrb_type(self) == MRB_TT_SCLASS) { + mrb_raise(mrb, E_TYPE_ERROR, "can't clone singleton class"); + } + p = (struct RObject*)mrb_obj_alloc(mrb, mrb_type(self), mrb_obj_class(mrb, self)); + p->c = mrb_singleton_class_clone(mrb, self); + mrb_field_write_barrier(mrb, (struct RBasic*)p, (struct RBasic*)p->c); + clone = mrb_obj_value(p); + init_copy(mrb, clone, self); + + return clone; +} + +/* 15.3.1.3.9 */ +/* + * call-seq: + * obj.dup -> an_object + * + * Produces a shallow copy of obj---the instance variables of + * obj are copied, but not the objects they reference. + * dup copies the frozen state of obj. See also + * the discussion under Object#clone. In general, + * clone and dup may have different semantics + * in descendant classes. While clone is used to duplicate + * an object, including its internal state, dup typically + * uses the class of the descendant object to create the new instance. + * + * This method may have class-specific behavior. If so, that + * behavior will be documented under the #+initialize_copy+ method of + * the class. + */ + +MRB_API mrb_value +mrb_obj_dup(mrb_state *mrb, mrb_value obj) +{ + struct RBasic *p; + mrb_value dup; + + if (mrb_immediate_p(obj)) { + mrb_raisef(mrb, E_TYPE_ERROR, "can't dup %S", obj); + } + if (mrb_type(obj) == MRB_TT_SCLASS) { + mrb_raise(mrb, E_TYPE_ERROR, "can't dup singleton class"); + } + p = mrb_obj_alloc(mrb, mrb_type(obj), mrb_obj_class(mrb, obj)); + dup = mrb_obj_value(p); + init_copy(mrb, dup, obj); + + return dup; +} + +static mrb_value +mrb_obj_extend(mrb_state *mrb, mrb_int argc, mrb_value *argv, mrb_value obj) +{ + mrb_int i; + + if (argc == 0) { + mrb_raise(mrb, E_ARGUMENT_ERROR, "wrong number of arguments (at least 1)"); + } + for (i = 0; i < argc; i++) { + mrb_check_type(mrb, argv[i], MRB_TT_MODULE); + } + while (argc--) { + mrb_funcall(mrb, argv[argc], "extend_object", 1, obj); + mrb_funcall(mrb, argv[argc], "extended", 1, obj); + } + return obj; +} + +/* 15.3.1.3.13 */ +/* + * call-seq: + * obj.extend(module, ...) -> obj + * + * Adds to _obj_ the instance methods from each module given as a + * parameter. + * + * module Mod + * def hello + * "Hello from Mod.\n" + * end + * end + * + * class Klass + * def hello + * "Hello from Klass.\n" + * end + * end + * + * k = Klass.new + * k.hello #=> "Hello from Klass.\n" + * k.extend(Mod) #=> # + * k.hello #=> "Hello from Mod.\n" + */ +static mrb_value +mrb_obj_extend_m(mrb_state *mrb, mrb_value self) +{ + mrb_value *argv; + mrb_int argc; + + mrb_get_args(mrb, "*", &argv, &argc); + return mrb_obj_extend(mrb, argc, argv, self); +} + +static mrb_value +mrb_obj_freeze(mrb_state *mrb, mrb_value self) +{ + struct RBasic *b; + + switch (mrb_type(self)) { + case MRB_TT_FALSE: + case MRB_TT_TRUE: + case MRB_TT_FIXNUM: + case MRB_TT_SYMBOL: + case MRB_TT_FLOAT: + return self; + default: + break; + } + + b = mrb_basic_ptr(self); + if (!MRB_FROZEN_P(b)) { + MRB_SET_FROZEN_FLAG(b); + } + return self; +} + +static mrb_value +mrb_obj_frozen(mrb_state *mrb, mrb_value self) +{ + struct RBasic *b; + + switch (mrb_type(self)) { + case MRB_TT_FALSE: + case MRB_TT_TRUE: + case MRB_TT_FIXNUM: + case MRB_TT_SYMBOL: + case MRB_TT_FLOAT: + return mrb_true_value(); + default: + break; + } + + b = mrb_basic_ptr(self); + if (!MRB_FROZEN_P(b)) { + return mrb_false_value(); + } + return mrb_true_value(); +} + +/* 15.3.1.3.15 */ +/* + * call-seq: + * obj.hash -> fixnum + * + * Generates a Fixnum hash value for this object. This + * function must have the property that a.eql?(b) implies + * a.hash == b.hash. The hash value is used by class + * Hash. Any hash value that exceeds the capacity of a + * Fixnum will be truncated before being used. + */ +MRB_API mrb_value +mrb_obj_hash(mrb_state *mrb, mrb_value self) +{ + return mrb_fixnum_value(mrb_obj_id(self)); +} + +/* 15.3.1.3.16 */ +static mrb_value +mrb_obj_init_copy(mrb_state *mrb, mrb_value self) +{ + mrb_value orig; + + mrb_get_args(mrb, "o", &orig); + if (mrb_obj_equal(mrb, self, orig)) return self; + if ((mrb_type(self) != mrb_type(orig)) || (mrb_obj_class(mrb, self) != mrb_obj_class(mrb, orig))) { + mrb_raise(mrb, E_TYPE_ERROR, "initialize_copy should take same class object"); + } + return self; +} + + +MRB_API mrb_bool +mrb_obj_is_instance_of(mrb_state *mrb, mrb_value obj, struct RClass* c) +{ + if (mrb_obj_class(mrb, obj) == c) return TRUE; + return FALSE; +} + +/* 15.3.1.3.19 */ +/* + * call-seq: + * obj.instance_of?(class) -> true or false + * + * Returns true if obj is an instance of the given + * class. See also Object#kind_of?. + */ +static mrb_value +obj_is_instance_of(mrb_state *mrb, mrb_value self) +{ + mrb_value arg; + + mrb_get_args(mrb, "C", &arg); + + return mrb_bool_value(mrb_obj_is_instance_of(mrb, self, mrb_class_ptr(arg))); +} + +/* 15.3.1.3.20 */ +/* + * call-seq: + * obj.instance_variable_defined?(symbol) -> true or false + * + * Returns true if the given instance variable is + * defined in obj. + * + * class Fred + * def initialize(p1, p2) + * @a, @b = p1, p2 + * end + * end + * fred = Fred.new('cat', 99) + * fred.instance_variable_defined?(:@a) #=> true + * fred.instance_variable_defined?("@b") #=> true + * fred.instance_variable_defined?("@c") #=> false + */ +static mrb_value +mrb_obj_ivar_defined(mrb_state *mrb, mrb_value self) +{ + mrb_sym sym; + + mrb_get_args(mrb, "n", &sym); + mrb_iv_check(mrb, sym); + return mrb_bool_value(mrb_iv_defined(mrb, self, sym)); +} + +/* 15.3.1.3.21 */ +/* + * call-seq: + * obj.instance_variable_get(symbol) -> obj + * + * Returns the value of the given instance variable, or nil if the + * instance variable is not set. The @ part of the + * variable name should be included for regular instance + * variables. Throws a NameError exception if the + * supplied symbol is not valid as an instance variable name. + * + * class Fred + * def initialize(p1, p2) + * @a, @b = p1, p2 + * end + * end + * fred = Fred.new('cat', 99) + * fred.instance_variable_get(:@a) #=> "cat" + * fred.instance_variable_get("@b") #=> 99 + */ +static mrb_value +mrb_obj_ivar_get(mrb_state *mrb, mrb_value self) +{ + mrb_sym iv_name; + + mrb_get_args(mrb, "n", &iv_name); + mrb_iv_check(mrb, iv_name); + return mrb_iv_get(mrb, self, iv_name); +} + +/* 15.3.1.3.22 */ +/* + * call-seq: + * obj.instance_variable_set(symbol, obj) -> obj + * + * Sets the instance variable names by symbol to + * object, thereby frustrating the efforts of the class's + * author to attempt to provide proper encapsulation. The variable + * did not have to exist prior to this call. + * + * class Fred + * def initialize(p1, p2) + * @a, @b = p1, p2 + * end + * end + * fred = Fred.new('cat', 99) + * fred.instance_variable_set(:@a, 'dog') #=> "dog" + * fred.instance_variable_set(:@c, 'cat') #=> "cat" + * fred.inspect #=> "#" + */ +static mrb_value +mrb_obj_ivar_set(mrb_state *mrb, mrb_value self) +{ + mrb_sym iv_name; + mrb_value val; + + mrb_get_args(mrb, "no", &iv_name, &val); + mrb_iv_check(mrb, iv_name); + mrb_iv_set(mrb, self, iv_name, val); + return val; +} + +/* 15.3.1.3.24 */ +/* 15.3.1.3.26 */ +/* + * call-seq: + * obj.is_a?(class) -> true or false + * obj.kind_of?(class) -> true or false + * + * Returns true if class is the class of + * obj, or if class is one of the superclasses of + * obj or modules included in obj. + * + * module M; end + * class A + * include M + * end + * class B < A; end + * class C < B; end + * b = B.new + * b.instance_of? A #=> false + * b.instance_of? B #=> true + * b.instance_of? C #=> false + * b.instance_of? M #=> false + * b.kind_of? A #=> true + * b.kind_of? B #=> true + * b.kind_of? C #=> false + * b.kind_of? M #=> true + */ +static mrb_value +mrb_obj_is_kind_of_m(mrb_state *mrb, mrb_value self) +{ + mrb_value arg; + + mrb_get_args(mrb, "C", &arg); + + return mrb_bool_value(mrb_obj_is_kind_of(mrb, self, mrb_class_ptr(arg))); +} + +KHASH_DECLARE(st, mrb_sym, char, FALSE) +KHASH_DEFINE(st, mrb_sym, char, FALSE, kh_int_hash_func, kh_int_hash_equal) + +static void +method_entry_loop(mrb_state *mrb, struct RClass* klass, khash_t(st)* set) +{ + khint_t i; + + khash_t(mt) *h = klass->mt; + if (!h) return; + for (i=0;iflags & MRB_FLAG_IS_PREPENDED)) { + MRB_CLASS_ORIGIN(klass); + prepended = TRUE; + } + + oldklass = 0; + while (klass && (klass != oldklass)) { + method_entry_loop(mrb, klass, set); + if ((klass->tt == MRB_TT_ICLASS && !prepended) || + (klass->tt == MRB_TT_SCLASS)) { + } + else { + if (!recur) break; + } + oldklass = klass; + klass = klass->super; + } + + ary = mrb_ary_new(mrb); + for (i=0;itt == MRB_TT_SCLASS)) { + method_entry_loop(mrb, klass, set); + klass = klass->super; + } + if (recur) { + while (klass && ((klass->tt == MRB_TT_SCLASS) || (klass->tt == MRB_TT_ICLASS))) { + method_entry_loop(mrb, klass, set); + klass = klass->super; + } + } + + ary = mrb_ary_new(mrb); + for (i=0;i array + * + * Returns a list of the names of methods publicly accessible in + * obj. This will include all the methods accessible in + * obj's ancestors. + * + * class Klass + * def kMethod() + * end + * end + * k = Klass.new + * k.methods[0..9] #=> [:kMethod, :respond_to?, :nil?, :is_a?, + * # :class, :instance_variable_set, + * # :methods, :extend, :__send__, :instance_eval] + * k.methods.length #=> 42 + */ +static mrb_value +mrb_obj_methods_m(mrb_state *mrb, mrb_value self) +{ + mrb_bool recur = TRUE; + mrb_get_args(mrb, "|b", &recur); + return mrb_obj_methods(mrb, recur, self, (mrb_method_flag_t)0); /* everything but private */ +} + +/* 15.3.1.3.32 */ +/* + * call_seq: + * nil.nil? -> true + * .nil? -> false + * + * Only the object nil responds true to nil?. + */ +static mrb_value +mrb_false(mrb_state *mrb, mrb_value self) +{ + return mrb_false_value(); +} + +/* 15.3.1.3.36 */ +/* + * call-seq: + * obj.private_methods(all=true) -> array + * + * Returns the list of private methods accessible to obj. If + * the all parameter is set to false, only those methods + * in the receiver will be listed. + */ +static mrb_value +mrb_obj_private_methods(mrb_state *mrb, mrb_value self) +{ + mrb_bool recur = TRUE; + mrb_get_args(mrb, "|b", &recur); + return mrb_obj_methods(mrb, recur, self, NOEX_PRIVATE); /* private attribute not define */ +} + +/* 15.3.1.3.37 */ +/* + * call-seq: + * obj.protected_methods(all=true) -> array + * + * Returns the list of protected methods accessible to obj. If + * the all parameter is set to false, only those methods + * in the receiver will be listed. + */ +static mrb_value +mrb_obj_protected_methods(mrb_state *mrb, mrb_value self) +{ + mrb_bool recur = TRUE; + mrb_get_args(mrb, "|b", &recur); + return mrb_obj_methods(mrb, recur, self, NOEX_PROTECTED); /* protected attribute not define */ +} + +/* 15.3.1.3.38 */ +/* + * call-seq: + * obj.public_methods(all=true) -> array + * + * Returns the list of public methods accessible to obj. If + * the all parameter is set to false, only those methods + * in the receiver will be listed. + */ +static mrb_value +mrb_obj_public_methods(mrb_state *mrb, mrb_value self) +{ + mrb_bool recur = TRUE; + mrb_get_args(mrb, "|b", &recur); + return mrb_obj_methods(mrb, recur, self, NOEX_PUBLIC); /* public attribute not define */ +} + +/* 15.3.1.2.12 */ +/* 15.3.1.3.40 */ +/* + * call-seq: + * raise + * raise(string) + * raise(exception [, string]) + * + * With no arguments, raises a RuntimeError + * With a single +String+ argument, raises a + * +RuntimeError+ with the string as a message. Otherwise, + * the first parameter should be the name of an +Exception+ + * class (or an object that returns an +Exception+ object when sent + * an +exception+ message). The optional second parameter sets the + * message associated with the exception, and the third parameter is an + * array of callback information. Exceptions are caught by the + * +rescue+ clause of begin...end blocks. + * + * raise "Failed to create socket" + * raise ArgumentError, "No parameters", caller + */ +MRB_API mrb_value +mrb_f_raise(mrb_state *mrb, mrb_value self) +{ + mrb_value a[2], exc; + int argc; + + + argc = mrb_get_args(mrb, "|oo", &a[0], &a[1]); + switch (argc) { + case 0: + mrb_raise(mrb, E_RUNTIME_ERROR, ""); + break; + case 1: + if (mrb_string_p(a[0])) { + a[1] = a[0]; + argc = 2; + a[0] = mrb_obj_value(E_RUNTIME_ERROR); + } + /* fall through */ + default: + exc = mrb_make_exception(mrb, argc, a); + mrb_exc_raise(mrb, exc); + break; + } + return mrb_nil_value(); /* not reached */ +} + +/* 15.3.1.3.41 */ +/* + * call-seq: + * obj.remove_instance_variable(symbol) -> obj + * + * Removes the named instance variable from obj, returning that + * variable's value. + * + * class Dummy + * attr_reader :var + * def initialize + * @var = 99 + * end + * def remove + * remove_instance_variable(:@var) + * end + * end + * d = Dummy.new + * d.var #=> 99 + * d.remove #=> 99 + * d.var #=> nil + */ +static mrb_value +mrb_obj_remove_instance_variable(mrb_state *mrb, mrb_value self) +{ + mrb_sym sym; + mrb_value val; + + mrb_get_args(mrb, "n", &sym); + mrb_iv_check(mrb, sym); + val = mrb_iv_remove(mrb, self, sym); + if (mrb_undef_p(val)) { + mrb_name_error(mrb, sym, "instance variable %S not defined", mrb_sym2str(mrb, sym)); + } + return val; +} + +void +mrb_method_missing(mrb_state *mrb, mrb_sym name, mrb_value self, mrb_value args) +{ + mrb_sym inspect; + mrb_value repr; + + inspect = mrb_intern_lit(mrb, "inspect"); + if (mrb->c->ci > mrb->c->cibase && mrb->c->ci[-1].mid == inspect) { + /* method missing in inspect; avoid recursion */ + repr = mrb_any_to_s(mrb, self); + } + else if (mrb_respond_to(mrb, self, inspect) && mrb->c->ci - mrb->c->cibase < 16) { + repr = mrb_funcall_argv(mrb, self, inspect, 0, 0); + if (mrb_string_p(repr) && RSTRING_LEN(repr) > 64) { + repr = mrb_any_to_s(mrb, self); + } + } + else { + repr = mrb_any_to_s(mrb, self); + } + + mrb_no_method_error(mrb, name, args, "undefined method '%S' for %S", + mrb_sym2str(mrb, name), repr); +} + +/* 15.3.1.3.30 */ +/* + * call-seq: + * obj.method_missing(symbol [, *args] ) -> result + * + * Invoked by Ruby when obj is sent a message it cannot handle. + * symbol is the symbol for the method called, and args + * are any arguments that were passed to it. By default, the interpreter + * raises an error when this method is called. However, it is possible + * to override the method to provide more dynamic behavior. + * If it is decided that a particular method should not be handled, then + * super should be called, so that ancestors can pick up the + * missing method. + * The example below creates + * a class Roman, which responds to methods with names + * consisting of roman numerals, returning the corresponding integer + * values. + * + * class Roman + * def romanToInt(str) + * # ... + * end + * def method_missing(methId) + * str = methId.id2name + * romanToInt(str) + * end + * end + * + * r = Roman.new + * r.iv #=> 4 + * r.xxiii #=> 23 + * r.mm #=> 2000 + */ +#ifdef MRB_DEFAULT_METHOD_MISSING +static mrb_value +mrb_obj_missing(mrb_state *mrb, mrb_value mod) +{ + mrb_sym name; + mrb_value *a; + mrb_int alen; + + mrb_get_args(mrb, "n*!", &name, &a, &alen); + mrb_method_missing(mrb, name, mod, mrb_ary_new_from_values(mrb, alen, a)); + /* not reached */ + return mrb_nil_value(); +} +#endif + +static inline mrb_bool +basic_obj_respond_to(mrb_state *mrb, mrb_value obj, mrb_sym id, int pub) +{ + return mrb_respond_to(mrb, obj, id); +} +/* 15.3.1.3.43 */ +/* + * call-seq: + * obj.respond_to?(symbol, include_private=false) -> true or false + * + * Returns +true+ if _obj_ responds to the given + * method. Private methods are included in the search only if the + * optional second parameter evaluates to +true+. + * + * If the method is not implemented, + * as Process.fork on Windows, File.lchmod on GNU/Linux, etc., + * false is returned. + * + * If the method is not defined, respond_to_missing? + * method is called and the result is returned. + */ +static mrb_value +obj_respond_to(mrb_state *mrb, mrb_value self) +{ + mrb_value mid; + mrb_sym id, rtm_id; + mrb_bool priv = FALSE, respond_to_p = TRUE; + + mrb_get_args(mrb, "o|b", &mid, &priv); + + if (mrb_symbol_p(mid)) { + id = mrb_symbol(mid); + } + else { + mrb_value tmp; + if (mrb_string_p(mid)) { + tmp = mrb_check_intern_str(mrb, mid); + } + else { + tmp = mrb_check_string_type(mrb, mid); + if (mrb_nil_p(tmp)) { + tmp = mrb_inspect(mrb, mid); + mrb_raisef(mrb, E_TYPE_ERROR, "%S is not a symbol", tmp); + } + tmp = mrb_check_intern_str(mrb, tmp); + } + if (mrb_nil_p(tmp)) { + respond_to_p = FALSE; + } + else { + id = mrb_symbol(tmp); + } + } + + if (respond_to_p) { + respond_to_p = basic_obj_respond_to(mrb, self, id, !priv); + } + + if (!respond_to_p) { + rtm_id = mrb_intern_lit(mrb, "respond_to_missing?"); + if (basic_obj_respond_to(mrb, self, rtm_id, !priv)) { + mrb_value args[2], v; + args[0] = mid; + args[1] = mrb_bool_value(priv); + v = mrb_funcall_argv(mrb, self, rtm_id, 2, args); + return mrb_bool_value(mrb_bool(v)); + } + } + return mrb_bool_value(respond_to_p); +} + +/* 15.3.1.3.45 */ +/* + * call-seq: + * obj.singleton_methods(all=true) -> array + * + * Returns an array of the names of singleton methods for obj. + * If the optional all parameter is true, the list will include + * methods in modules included in obj. + * Only public and protected singleton methods are returned. + * + * module Other + * def three() end + * end + * + * class Single + * def Single.four() end + * end + * + * a = Single.new + * + * def a.one() + * end + * + * class << a + * include Other + * def two() + * end + * end + * + * Single.singleton_methods #=> [:four] + * a.singleton_methods(false) #=> [:two, :one] + * a.singleton_methods #=> [:two, :one, :three] + */ +static mrb_value +mrb_obj_singleton_methods_m(mrb_state *mrb, mrb_value self) +{ + mrb_bool recur = TRUE; + mrb_get_args(mrb, "|b", &recur); + return mrb_obj_singleton_methods(mrb, recur, self); +} + +static mrb_value +mod_define_singleton_method(mrb_state *mrb, mrb_value self) +{ + struct RProc *p; + mrb_sym mid; + mrb_value blk = mrb_nil_value(); + + mrb_get_args(mrb, "n&", &mid, &blk); + if (mrb_nil_p(blk)) { + mrb_raise(mrb, E_ARGUMENT_ERROR, "no block given"); + } + p = (struct RProc*)mrb_obj_alloc(mrb, MRB_TT_PROC, mrb->proc_class); + mrb_proc_copy(p, mrb_proc_ptr(blk)); + p->flags |= MRB_PROC_STRICT; + mrb_define_method_raw(mrb, mrb_class_ptr(mrb_singleton_class(mrb, self)), mid, p); + return mrb_symbol_value(mid); +} + +static mrb_value +mrb_obj_ceqq(mrb_state *mrb, mrb_value self) +{ + mrb_value v; + mrb_int i, len; + mrb_sym eqq = mrb_intern_lit(mrb, "==="); + mrb_value ary = mrb_ary_splat(mrb, self); + + mrb_get_args(mrb, "o", &v); + len = RARRAY_LEN(ary); + for (i=0; i array + * + * Returns the names of local variables in the current scope. + * + * [mruby limitation] + * If variable symbol information was stripped out from + * compiled binary files using `mruby-strip -l`, this + * method always returns an empty array. + */ +static mrb_value +mrb_local_variables(mrb_state *mrb, mrb_value self) +{ + struct RProc *proc; + mrb_irep *irep; + mrb_value vars; + size_t i; + + proc = mrb->c->ci[-1].proc; + + if (MRB_PROC_CFUNC_P(proc)) { + return mrb_ary_new(mrb); + } + vars = mrb_hash_new(mrb); + irep = proc->body.irep; + while (irep) { + if (!irep->lv) break; + for (i = 0; i + 1 < irep->nlocals; ++i) { + if (irep->lv[i].name) { + mrb_hash_set(mrb, vars, mrb_symbol_value(irep->lv[i].name), mrb_true_value()); + } + } + if (!proc->env) break; + irep = irep->outer; + } + + return mrb_hash_keys(mrb, vars); +} + +mrb_value mrb_obj_equal_m(mrb_state *mrb, mrb_value); +void +mrb_init_kernel(mrb_state *mrb) +{ + struct RClass *krn; + + mrb->kernel_module = krn = mrb_define_module(mrb, "Kernel"); /* 15.3.1 */ + mrb_define_class_method(mrb, krn, "block_given?", mrb_f_block_given_p_m, MRB_ARGS_NONE()); /* 15.3.1.2.2 */ + mrb_define_class_method(mrb, krn, "global_variables", mrb_f_global_variables, MRB_ARGS_NONE()); /* 15.3.1.2.4 */ + mrb_define_class_method(mrb, krn, "iterator?", mrb_f_block_given_p_m, MRB_ARGS_NONE()); /* 15.3.1.2.5 */ + mrb_define_class_method(mrb, krn, "local_variables", mrb_local_variables, MRB_ARGS_NONE()); /* 15.3.1.2.7 */ +; /* 15.3.1.2.11 */ + mrb_define_class_method(mrb, krn, "raise", mrb_f_raise, MRB_ARGS_OPT(2)); /* 15.3.1.2.12 */ + + mrb_define_method(mrb, krn, "singleton_class", mrb_singleton_class, MRB_ARGS_NONE()); + + mrb_define_method(mrb, krn, "===", mrb_equal_m, MRB_ARGS_REQ(1)); /* 15.3.1.3.2 */ + mrb_define_method(mrb, krn, "block_given?", mrb_f_block_given_p_m, MRB_ARGS_NONE()); /* 15.3.1.3.6 */ + mrb_define_method(mrb, krn, "class", mrb_obj_class_m, MRB_ARGS_NONE()); /* 15.3.1.3.7 */ + mrb_define_method(mrb, krn, "clone", mrb_obj_clone, MRB_ARGS_NONE()); /* 15.3.1.3.8 */ + mrb_define_method(mrb, krn, "dup", mrb_obj_dup, MRB_ARGS_NONE()); /* 15.3.1.3.9 */ + mrb_define_method(mrb, krn, "eql?", mrb_obj_equal_m, MRB_ARGS_REQ(1)); /* 15.3.1.3.10 */ + mrb_define_method(mrb, krn, "equal?", mrb_obj_equal_m, MRB_ARGS_REQ(1)); /* 15.3.1.3.11 */ + mrb_define_method(mrb, krn, "extend", mrb_obj_extend_m, MRB_ARGS_ANY()); /* 15.3.1.3.13 */ + mrb_define_method(mrb, krn, "freeze", mrb_obj_freeze, MRB_ARGS_NONE()); + mrb_define_method(mrb, krn, "frozen?", mrb_obj_frozen, MRB_ARGS_NONE()); + mrb_define_method(mrb, krn, "global_variables", mrb_f_global_variables, MRB_ARGS_NONE()); /* 15.3.1.3.14 */ + mrb_define_method(mrb, krn, "hash", mrb_obj_hash, MRB_ARGS_NONE()); /* 15.3.1.3.15 */ + mrb_define_method(mrb, krn, "initialize_copy", mrb_obj_init_copy, MRB_ARGS_REQ(1)); /* 15.3.1.3.16 */ + mrb_define_method(mrb, krn, "inspect", mrb_obj_inspect, MRB_ARGS_NONE()); /* 15.3.1.3.17 */ + mrb_define_method(mrb, krn, "instance_of?", obj_is_instance_of, MRB_ARGS_REQ(1)); /* 15.3.1.3.19 */ + mrb_define_method(mrb, krn, "instance_variable_defined?", mrb_obj_ivar_defined, MRB_ARGS_REQ(1)); /* 15.3.1.3.20 */ + mrb_define_method(mrb, krn, "instance_variable_get", mrb_obj_ivar_get, MRB_ARGS_REQ(1)); /* 15.3.1.3.21 */ + mrb_define_method(mrb, krn, "instance_variable_set", mrb_obj_ivar_set, MRB_ARGS_REQ(2)); /* 15.3.1.3.22 */ + mrb_define_method(mrb, krn, "instance_variables", mrb_obj_instance_variables, MRB_ARGS_NONE()); /* 15.3.1.3.23 */ + mrb_define_method(mrb, krn, "is_a?", mrb_obj_is_kind_of_m, MRB_ARGS_REQ(1)); /* 15.3.1.3.24 */ + mrb_define_method(mrb, krn, "iterator?", mrb_f_block_given_p_m, MRB_ARGS_NONE()); /* 15.3.1.3.25 */ + mrb_define_method(mrb, krn, "kind_of?", mrb_obj_is_kind_of_m, MRB_ARGS_REQ(1)); /* 15.3.1.3.26 */ + mrb_define_method(mrb, krn, "local_variables", mrb_local_variables, MRB_ARGS_NONE()); /* 15.3.1.3.28 */ +#ifdef MRB_DEFAULT_METHOD_MISSING + mrb_define_method(mrb, krn, "method_missing", mrb_obj_missing, MRB_ARGS_ANY()); /* 15.3.1.3.30 */ +#endif + mrb_define_method(mrb, krn, "methods", mrb_obj_methods_m, MRB_ARGS_OPT(1)); /* 15.3.1.3.31 */ + mrb_define_method(mrb, krn, "nil?", mrb_false, MRB_ARGS_NONE()); /* 15.3.1.3.32 */ + mrb_define_method(mrb, krn, "object_id", mrb_obj_id_m, MRB_ARGS_NONE()); /* 15.3.1.3.33 */ + mrb_define_method(mrb, krn, "private_methods", mrb_obj_private_methods, MRB_ARGS_OPT(1)); /* 15.3.1.3.36 */ + mrb_define_method(mrb, krn, "protected_methods", mrb_obj_protected_methods, MRB_ARGS_OPT(1)); /* 15.3.1.3.37 */ + mrb_define_method(mrb, krn, "public_methods", mrb_obj_public_methods, MRB_ARGS_OPT(1)); /* 15.3.1.3.38 */ + mrb_define_method(mrb, krn, "raise", mrb_f_raise, MRB_ARGS_ANY()); /* 15.3.1.3.40 */ + mrb_define_method(mrb, krn, "remove_instance_variable", mrb_obj_remove_instance_variable,MRB_ARGS_REQ(1)); /* 15.3.1.3.41 */ + mrb_define_method(mrb, krn, "respond_to?", obj_respond_to, MRB_ARGS_ANY()); /* 15.3.1.3.43 */ + mrb_define_method(mrb, krn, "send", mrb_f_send, MRB_ARGS_ANY()); /* 15.3.1.3.44 */ + mrb_define_method(mrb, krn, "singleton_methods", mrb_obj_singleton_methods_m, MRB_ARGS_OPT(1)); /* 15.3.1.3.45 */ + mrb_define_method(mrb, krn, "define_singleton_method", mod_define_singleton_method, MRB_ARGS_ANY()); + mrb_define_method(mrb, krn, "to_s", mrb_any_to_s, MRB_ARGS_NONE()); /* 15.3.1.3.46 */ + mrb_define_method(mrb, krn, "__case_eqq", mrb_obj_ceqq, MRB_ARGS_REQ(1)); /* internal */ + + mrb_include_module(mrb, mrb->object_class, mrb->kernel_module); + mrb_alias_method(mrb, mrb->module_class, mrb_intern_lit(mrb, "dup"), mrb_intern_lit(mrb, "clone")); +} diff --git a/web/server/h2o/libh2o/deps/mruby/src/load.c b/web/server/h2o/libh2o/deps/mruby/src/load.c new file mode 100644 index 00000000..8ae607ff --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/src/load.c @@ -0,0 +1,704 @@ +/* +** load.c - mruby binary loader +** +** See Copyright Notice in mruby.h +*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if SIZE_MAX < UINT32_MAX +# error size_t must be at least 32 bits wide +#endif + +#define FLAG_BYTEORDER_BIG 2 +#define FLAG_BYTEORDER_LIL 4 +#define FLAG_BYTEORDER_NATIVE 8 +#define FLAG_SRC_MALLOC 1 +#define FLAG_SRC_STATIC 0 + +#define SIZE_ERROR_MUL(nmemb, size) ((size_t)(nmemb) > SIZE_MAX / (size)) + +static size_t +skip_padding(const uint8_t *buf) +{ + const size_t align = MRB_DUMP_ALIGNMENT; + return -(intptr_t)buf & (align-1); +} + +static size_t +offset_crc_body(void) +{ + struct rite_binary_header header; + return ((uint8_t *)header.binary_crc - (uint8_t *)&header) + sizeof(header.binary_crc); +} + +static mrb_irep* +read_irep_record_1(mrb_state *mrb, const uint8_t *bin, size_t *len, uint8_t flags) +{ + int i; + const uint8_t *src = bin; + ptrdiff_t diff; + uint16_t tt, pool_data_len, snl; + int plen; + int ai = mrb_gc_arena_save(mrb); + mrb_irep *irep = mrb_add_irep(mrb); + + /* skip record size */ + src += sizeof(uint32_t); + + /* number of local variable */ + irep->nlocals = bin_to_uint16(src); + src += sizeof(uint16_t); + + /* number of register variable */ + irep->nregs = bin_to_uint16(src); + src += sizeof(uint16_t); + + /* number of child irep */ + irep->rlen = (size_t)bin_to_uint16(src); + src += sizeof(uint16_t); + + /* Binary Data Section */ + /* ISEQ BLOCK */ + irep->ilen = (size_t)bin_to_uint32(src); + src += sizeof(uint32_t); + src += skip_padding(src); + + if (irep->ilen > 0) { + if (SIZE_ERROR_MUL(irep->ilen, sizeof(mrb_code))) { + return NULL; + } + if ((flags & FLAG_SRC_MALLOC) == 0 && + (flags & FLAG_BYTEORDER_NATIVE)) { + irep->iseq = (mrb_code*)src; + src += sizeof(uint32_t) * irep->ilen; + irep->flags |= MRB_ISEQ_NO_FREE; + } + else { + irep->iseq = (mrb_code *)mrb_malloc(mrb, sizeof(mrb_code) * irep->ilen); + if (flags & FLAG_BYTEORDER_NATIVE) { + memcpy(irep->iseq, src, sizeof(uint32_t) * irep->ilen); + src += sizeof(uint32_t) * irep->ilen; + } + else if (flags & FLAG_BYTEORDER_BIG) { + for (i = 0; i < irep->ilen; i++) { + irep->iseq[i] = (mrb_code)bin_to_uint32(src); /* iseq */ + src += sizeof(uint32_t); + } + } + else { + for (i = 0; i < irep->ilen; i++) { + irep->iseq[i] = (mrb_code)bin_to_uint32l(src); /* iseq */ + src += sizeof(uint32_t); + } + } + } + } + + /* POOL BLOCK */ + plen = bin_to_uint32(src); /* number of pool */ + src += sizeof(uint32_t); + if (plen > 0) { + if (SIZE_ERROR_MUL(plen, sizeof(mrb_value))) { + return NULL; + } + irep->pool = (mrb_value*)mrb_malloc(mrb, sizeof(mrb_value) * plen); + + for (i = 0; i < plen; i++) { + mrb_value s; + + tt = *src++; /* pool TT */ + pool_data_len = bin_to_uint16(src); /* pool data length */ + src += sizeof(uint16_t); + if (flags & FLAG_SRC_MALLOC) { + s = mrb_str_new(mrb, (char *)src, pool_data_len); + } + else { + s = mrb_str_new_static(mrb, (char *)src, pool_data_len); + } + src += pool_data_len; + switch (tt) { /* pool data */ + case IREP_TT_FIXNUM: + irep->pool[i] = mrb_str_to_inum(mrb, s, 10, FALSE); + break; + + case IREP_TT_FLOAT: + irep->pool[i] = mrb_float_pool(mrb, mrb_str_to_dbl(mrb, s, FALSE)); + break; + + case IREP_TT_STRING: + irep->pool[i] = mrb_str_pool(mrb, s); + break; + + default: + /* should not happen */ + irep->pool[i] = mrb_nil_value(); + break; + } + irep->plen++; + mrb_gc_arena_restore(mrb, ai); + } + } + + /* SYMS BLOCK */ + irep->slen = (size_t)bin_to_uint32(src); /* syms length */ + src += sizeof(uint32_t); + if (irep->slen > 0) { + if (SIZE_ERROR_MUL(irep->slen, sizeof(mrb_sym))) { + return NULL; + } + irep->syms = (mrb_sym *)mrb_malloc(mrb, sizeof(mrb_sym) * irep->slen); + + for (i = 0; i < irep->slen; i++) { + snl = bin_to_uint16(src); /* symbol name length */ + src += sizeof(uint16_t); + + if (snl == MRB_DUMP_NULL_SYM_LEN) { + irep->syms[i] = 0; + continue; + } + + if (flags & FLAG_SRC_MALLOC) { + irep->syms[i] = mrb_intern(mrb, (char *)src, snl); + } + else { + irep->syms[i] = mrb_intern_static(mrb, (char *)src, snl); + } + src += snl + 1; + + mrb_gc_arena_restore(mrb, ai); + } + } + + irep->reps = (mrb_irep**)mrb_malloc(mrb, sizeof(mrb_irep*)*irep->rlen); + + diff = src - bin; + mrb_assert_int_fit(ptrdiff_t, diff, size_t, SIZE_MAX); + *len = (size_t)diff; + + return irep; +} + +static mrb_irep* +read_irep_record(mrb_state *mrb, const uint8_t *bin, size_t *len, uint8_t flags) +{ + mrb_irep *irep = read_irep_record_1(mrb, bin, len, flags); + int i; + + if (irep == NULL) { + return NULL; + } + + bin += *len; + for (i=0; irlen; i++) { + size_t rlen; + + irep->reps[i] = read_irep_record(mrb, bin, &rlen, flags); + if (irep->reps[i] == NULL) { + return NULL; + } + bin += rlen; + *len += rlen; + } + return irep; +} + +static mrb_irep* +read_section_irep(mrb_state *mrb, const uint8_t *bin, uint8_t flags) +{ + size_t len; + + bin += sizeof(struct rite_section_irep_header); + return read_irep_record(mrb, bin, &len, flags); +} + +static int +read_lineno_record_1(mrb_state *mrb, const uint8_t *bin, mrb_irep *irep, size_t *len) +{ + size_t i, fname_len, niseq; + char *fname; + uint16_t *lines; + + *len = 0; + bin += sizeof(uint32_t); /* record size */ + *len += sizeof(uint32_t); + fname_len = bin_to_uint16(bin); + bin += sizeof(uint16_t); + *len += sizeof(uint16_t); + fname = (char *)mrb_malloc(mrb, fname_len + 1); + memcpy(fname, bin, fname_len); + fname[fname_len] = '\0'; + bin += fname_len; + *len += fname_len; + + niseq = (size_t)bin_to_uint32(bin); + bin += sizeof(uint32_t); /* niseq */ + *len += sizeof(uint32_t); + + if (SIZE_ERROR_MUL(niseq, sizeof(uint16_t))) { + return MRB_DUMP_GENERAL_FAILURE; + } + lines = (uint16_t *)mrb_malloc(mrb, niseq * sizeof(uint16_t)); + for (i = 0; i < niseq; i++) { + lines[i] = bin_to_uint16(bin); + bin += sizeof(uint16_t); /* niseq */ + *len += sizeof(uint16_t); + } + + irep->filename = fname; + irep->lines = lines; + return MRB_DUMP_OK; +} + +static int +read_lineno_record(mrb_state *mrb, const uint8_t *bin, mrb_irep *irep, size_t *lenp) +{ + int result = read_lineno_record_1(mrb, bin, irep, lenp); + int i; + + if (result != MRB_DUMP_OK) return result; + for (i = 0; i < irep->rlen; i++) { + size_t len; + + result = read_lineno_record(mrb, bin, irep->reps[i], &len); + if (result != MRB_DUMP_OK) break; + bin += len; + *lenp += len; + } + return result; +} + +static int +read_section_lineno(mrb_state *mrb, const uint8_t *bin, mrb_irep *irep) +{ + size_t len; + + len = 0; + bin += sizeof(struct rite_section_lineno_header); + + /* Read Binary Data Section */ + return read_lineno_record(mrb, bin, irep, &len); +} + +static int +read_debug_record(mrb_state *mrb, const uint8_t *start, mrb_irep* irep, size_t *record_len, const mrb_sym *filenames, size_t filenames_len) +{ + const uint8_t *bin = start; + ptrdiff_t diff; + size_t record_size; + uint16_t f_idx; + int i; + + if (irep->debug_info) { return MRB_DUMP_INVALID_IREP; } + + irep->debug_info = (mrb_irep_debug_info*)mrb_malloc(mrb, sizeof(mrb_irep_debug_info)); + irep->debug_info->pc_count = (uint32_t)irep->ilen; + + record_size = (size_t)bin_to_uint32(bin); + bin += sizeof(uint32_t); + + irep->debug_info->flen = bin_to_uint16(bin); + irep->debug_info->files = (mrb_irep_debug_info_file**)mrb_malloc(mrb, sizeof(mrb_irep_debug_info*) * irep->debug_info->flen); + bin += sizeof(uint16_t); + + for (f_idx = 0; f_idx < irep->debug_info->flen; ++f_idx) { + mrb_irep_debug_info_file *file; + uint16_t filename_idx; + mrb_int len; + + file = (mrb_irep_debug_info_file *)mrb_malloc(mrb, sizeof(*file)); + irep->debug_info->files[f_idx] = file; + + file->start_pos = bin_to_uint32(bin); + bin += sizeof(uint32_t); + + /* filename */ + filename_idx = bin_to_uint16(bin); + bin += sizeof(uint16_t); + mrb_assert(filename_idx < filenames_len); + file->filename_sym = filenames[filename_idx]; + len = 0; + file->filename = mrb_sym2name_len(mrb, file->filename_sym, &len); + + file->line_entry_count = bin_to_uint32(bin); + bin += sizeof(uint32_t); + file->line_type = (mrb_debug_line_type)bin_to_uint8(bin); + bin += sizeof(uint8_t); + switch (file->line_type) { + case mrb_debug_line_ary: { + uint32_t l; + + file->lines.ary = (uint16_t *)mrb_malloc(mrb, sizeof(uint16_t) * (size_t)(file->line_entry_count)); + for (l = 0; l < file->line_entry_count; ++l) { + file->lines.ary[l] = bin_to_uint16(bin); + bin += sizeof(uint16_t); + } + } break; + + case mrb_debug_line_flat_map: { + uint32_t l; + + file->lines.flat_map = (mrb_irep_debug_info_line*)mrb_malloc( + mrb, sizeof(mrb_irep_debug_info_line) * (size_t)(file->line_entry_count)); + for (l = 0; l < file->line_entry_count; ++l) { + file->lines.flat_map[l].start_pos = bin_to_uint32(bin); + bin += sizeof(uint32_t); + file->lines.flat_map[l].line = bin_to_uint16(bin); + bin += sizeof(uint16_t); + } + } break; + + default: return MRB_DUMP_GENERAL_FAILURE; + } + } + + diff = bin - start; + mrb_assert_int_fit(ptrdiff_t, diff, size_t, SIZE_MAX); + + if (record_size != (size_t)diff) { + return MRB_DUMP_GENERAL_FAILURE; + } + + for (i = 0; i < irep->rlen; i++) { + size_t len; + int ret; + + ret = read_debug_record(mrb, bin, irep->reps[i], &len, filenames, filenames_len); + if (ret != MRB_DUMP_OK) return ret; + bin += len; + } + + diff = bin - start; + mrb_assert_int_fit(ptrdiff_t, diff, size_t, SIZE_MAX); + *record_len = (size_t)diff; + + return MRB_DUMP_OK; +} + +static int +read_section_debug(mrb_state *mrb, const uint8_t *start, mrb_irep *irep, uint8_t flags) +{ + const uint8_t *bin; + ptrdiff_t diff; + struct rite_section_debug_header *header; + uint16_t i; + size_t len = 0; + int result; + uint16_t filenames_len; + mrb_sym *filenames; + + bin = start; + header = (struct rite_section_debug_header *)bin; + bin += sizeof(struct rite_section_debug_header); + + filenames_len = bin_to_uint16(bin); + bin += sizeof(uint16_t); + filenames = (mrb_sym*)mrb_malloc(mrb, sizeof(mrb_sym) * (size_t)filenames_len); + for (i = 0; i < filenames_len; ++i) { + uint16_t f_len = bin_to_uint16(bin); + bin += sizeof(uint16_t); + if (flags & FLAG_SRC_MALLOC) { + filenames[i] = mrb_intern(mrb, (const char *)bin, (size_t)f_len); + } + else { + filenames[i] = mrb_intern_static(mrb, (const char *)bin, (size_t)f_len); + } + bin += f_len; + } + + result = read_debug_record(mrb, bin, irep, &len, filenames, filenames_len); + if (result != MRB_DUMP_OK) goto debug_exit; + + bin += len; + diff = bin - start; + mrb_assert_int_fit(ptrdiff_t, diff, size_t, SIZE_MAX); + if ((uint32_t)diff != bin_to_uint32(header->section_size)) { + result = MRB_DUMP_GENERAL_FAILURE; + } + +debug_exit: + mrb_free(mrb, filenames); + return result; +} + +static int +read_lv_record(mrb_state *mrb, const uint8_t *start, mrb_irep *irep, size_t *record_len, mrb_sym const *syms, uint32_t syms_len) +{ + const uint8_t *bin = start; + ptrdiff_t diff; + int i; + + irep->lv = (struct mrb_locals*)mrb_malloc(mrb, sizeof(struct mrb_locals) * (irep->nlocals - 1)); + + for (i = 0; i + 1< irep->nlocals; ++i) { + uint16_t const sym_idx = bin_to_uint16(bin); + bin += sizeof(uint16_t); + if (sym_idx == RITE_LV_NULL_MARK) { + irep->lv[i].name = 0; + irep->lv[i].r = 0; + } + else { + if (sym_idx >= syms_len) { + return MRB_DUMP_GENERAL_FAILURE; + } + irep->lv[i].name = syms[sym_idx]; + + irep->lv[i].r = bin_to_uint16(bin); + } + bin += sizeof(uint16_t); + } + + for (i = 0; i < irep->rlen; ++i) { + size_t len; + int ret; + + ret = read_lv_record(mrb, bin, irep->reps[i], &len, syms, syms_len); + if (ret != MRB_DUMP_OK) return ret; + bin += len; + } + + diff = bin - start; + mrb_assert_int_fit(ptrdiff_t, diff, size_t, SIZE_MAX); + *record_len = (size_t)diff; + + return MRB_DUMP_OK; +} + +static int +read_section_lv(mrb_state *mrb, const uint8_t *start, mrb_irep *irep, uint8_t flags) +{ + const uint8_t *bin; + ptrdiff_t diff; + struct rite_section_lv_header const *header; + uint32_t i; + size_t len = 0; + int result; + uint32_t syms_len; + mrb_sym *syms; + mrb_sym (*intern_func)(mrb_state*, const char*, size_t) = + (flags & FLAG_SRC_MALLOC)? mrb_intern : mrb_intern_static; + + bin = start; + header = (struct rite_section_lv_header const*)bin; + bin += sizeof(struct rite_section_lv_header); + + syms_len = bin_to_uint32(bin); + bin += sizeof(uint32_t); + syms = (mrb_sym*)mrb_malloc(mrb, sizeof(mrb_sym) * (size_t)syms_len); + for (i = 0; i < syms_len; ++i) { + uint16_t const str_len = bin_to_uint16(bin); + bin += sizeof(uint16_t); + + syms[i] = intern_func(mrb, (const char*)bin, str_len); + bin += str_len; + } + + result = read_lv_record(mrb, bin, irep, &len, syms, syms_len); + if (result != MRB_DUMP_OK) goto lv_exit; + + bin += len; + diff = bin - start; + mrb_assert_int_fit(ptrdiff_t, diff, size_t, SIZE_MAX); + if ((uint32_t)diff != bin_to_uint32(header->section_size)) { + result = MRB_DUMP_GENERAL_FAILURE; + } + +lv_exit: + mrb_free(mrb, syms); + return result; +} + +static int +read_binary_header(const uint8_t *bin, size_t *bin_size, uint16_t *crc, uint8_t *flags) +{ + const struct rite_binary_header *header = (const struct rite_binary_header *)bin; + + if (memcmp(header->binary_ident, RITE_BINARY_IDENT, sizeof(header->binary_ident)) == 0) { + if (bigendian_p()) + *flags |= FLAG_BYTEORDER_NATIVE; + else + *flags |= FLAG_BYTEORDER_BIG; + } + else if (memcmp(header->binary_ident, RITE_BINARY_IDENT_LIL, sizeof(header->binary_ident)) == 0) { + if (bigendian_p()) + *flags |= FLAG_BYTEORDER_LIL; + else + *flags |= FLAG_BYTEORDER_NATIVE; + } + else { + return MRB_DUMP_INVALID_FILE_HEADER; + } + + if (crc) { + *crc = bin_to_uint16(header->binary_crc); + } + *bin_size = (size_t)bin_to_uint32(header->binary_size); + + return MRB_DUMP_OK; +} + +static mrb_irep* +read_irep(mrb_state *mrb, const uint8_t *bin, uint8_t flags) +{ + int result; + mrb_irep *irep = NULL; + const struct rite_section_header *section_header; + uint16_t crc; + size_t bin_size = 0; + size_t n; + + if ((mrb == NULL) || (bin == NULL)) { + return NULL; + } + + result = read_binary_header(bin, &bin_size, &crc, &flags); + if (result != MRB_DUMP_OK) { + return NULL; + } + + n = offset_crc_body(); + if (crc != calc_crc_16_ccitt(bin + n, bin_size - n, 0)) { + return NULL; + } + + bin += sizeof(struct rite_binary_header); + do { + section_header = (const struct rite_section_header *)bin; + if (memcmp(section_header->section_ident, RITE_SECTION_IREP_IDENT, sizeof(section_header->section_ident)) == 0) { + irep = read_section_irep(mrb, bin, flags); + if (!irep) return NULL; + } + else if (memcmp(section_header->section_ident, RITE_SECTION_LINENO_IDENT, sizeof(section_header->section_ident)) == 0) { + if (!irep) return NULL; /* corrupted data */ + result = read_section_lineno(mrb, bin, irep); + if (result < MRB_DUMP_OK) { + return NULL; + } + } + else if (memcmp(section_header->section_ident, RITE_SECTION_DEBUG_IDENT, sizeof(section_header->section_ident)) == 0) { + if (!irep) return NULL; /* corrupted data */ + result = read_section_debug(mrb, bin, irep, flags); + if (result < MRB_DUMP_OK) { + return NULL; + } + } + else if (memcmp(section_header->section_ident, RITE_SECTION_LV_IDENT, sizeof(section_header->section_ident)) == 0) { + if (!irep) return NULL; + result = read_section_lv(mrb, bin, irep, flags); + if (result < MRB_DUMP_OK) { + return NULL; + } + } + bin += bin_to_uint32(section_header->section_size); + } while (memcmp(section_header->section_ident, RITE_BINARY_EOF, sizeof(section_header->section_ident)) != 0); + + return irep; +} + +mrb_irep* +mrb_read_irep(mrb_state *mrb, const uint8_t *bin) +{ +#ifdef MRB_USE_ETEXT_EDATA + uint8_t flags = mrb_ro_data_p((char*)bin) ? FLAG_SRC_STATIC : FLAG_SRC_MALLOC; +#else + uint8_t flags = FLAG_SRC_STATIC; +#endif + + return read_irep(mrb, bin, flags); +} + +void mrb_exc_set(mrb_state *mrb, mrb_value exc); + +static void +irep_error(mrb_state *mrb) +{ + mrb_exc_set(mrb, mrb_exc_new_str_lit(mrb, E_SCRIPT_ERROR, "irep load error")); +} + +void mrb_codedump_all(mrb_state*, struct RProc*); + +static mrb_value +load_irep(mrb_state *mrb, mrb_irep *irep, mrbc_context *c) +{ + struct RProc *proc; + + if (!irep) { + irep_error(mrb); + return mrb_nil_value(); + } + proc = mrb_proc_new(mrb, irep); + proc->c = NULL; + mrb_irep_decref(mrb, irep); + if (c && c->dump_result) mrb_codedump_all(mrb, proc); + if (c && c->no_exec) return mrb_obj_value(proc); + return mrb_top_run(mrb, proc, mrb_top_self(mrb), 0); +} + +MRB_API mrb_value +mrb_load_irep_cxt(mrb_state *mrb, const uint8_t *bin, mrbc_context *c) +{ + return load_irep(mrb, mrb_read_irep(mrb, bin), c); +} + +MRB_API mrb_value +mrb_load_irep(mrb_state *mrb, const uint8_t *bin) +{ + return mrb_load_irep_cxt(mrb, bin, NULL); +} + +#ifndef MRB_DISABLE_STDIO + +mrb_irep* +mrb_read_irep_file(mrb_state *mrb, FILE* fp) +{ + mrb_irep *irep = NULL; + uint8_t *buf; + const size_t header_size = sizeof(struct rite_binary_header); + size_t buf_size = 0; + uint8_t flags = 0; + int result; + + if ((mrb == NULL) || (fp == NULL)) { + return NULL; + } + + buf = (uint8_t*)mrb_malloc(mrb, header_size); + if (fread(buf, header_size, 1, fp) == 0) { + goto irep_exit; + } + result = read_binary_header(buf, &buf_size, NULL, &flags); + if (result != MRB_DUMP_OK || buf_size <= header_size) { + goto irep_exit; + } + + buf = (uint8_t*)mrb_realloc(mrb, buf, buf_size); + if (fread(buf+header_size, buf_size-header_size, 1, fp) == 0) { + goto irep_exit; + } + irep = read_irep(mrb, buf, FLAG_SRC_MALLOC); + +irep_exit: + mrb_free(mrb, buf); + return irep; +} + +MRB_API mrb_value +mrb_load_irep_file_cxt(mrb_state *mrb, FILE* fp, mrbc_context *c) +{ + return load_irep(mrb, mrb_read_irep_file(mrb, fp), c); +} + +MRB_API mrb_value +mrb_load_irep_file(mrb_state *mrb, FILE* fp) +{ + return mrb_load_irep_file_cxt(mrb, fp, NULL); +} +#endif /* MRB_DISABLE_STDIO */ diff --git a/web/server/h2o/libh2o/deps/mruby/src/mruby_core.rake b/web/server/h2o/libh2o/deps/mruby/src/mruby_core.rake new file mode 100644 index 00000000..4558493d --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/src/mruby_core.rake @@ -0,0 +1,19 @@ +MRuby.each_target do + current_dir = File.dirname(__FILE__).relative_path_from(Dir.pwd) + relative_from_root = File.dirname(__FILE__).relative_path_from(MRUBY_ROOT) + current_build_dir = "#{build_dir}/#{relative_from_root}" + + objs = Dir.glob("#{current_dir}/*.c").map { |f| + next nil if cxx_exception_enabled? and f =~ /(error|vm).c$/ + objfile(f.pathmap("#{current_build_dir}/%n")) + }.compact + + if cxx_exception_enabled? + objs += %w(vm error).map { |v| compile_as_cxx "#{current_dir}/#{v}.c", "#{current_build_dir}/#{v}.cxx" } + end + self.libmruby << objs + + file libfile("#{build_dir}/lib/libmruby_core") => objs do |t| + archiver.run t.name, t.prerequisites + end +end diff --git a/web/server/h2o/libh2o/deps/mruby/src/numeric.c b/web/server/h2o/libh2o/deps/mruby/src/numeric.c new file mode 100644 index 00000000..afb8415a --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/src/numeric.c @@ -0,0 +1,1355 @@ +/* +** numeric.c - Numeric, Integer, Float, Fixnum class +** +** See Copyright Notice in mruby.h +*/ + +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#ifdef MRB_USE_FLOAT +#define trunc(f) truncf(f) +#define floor(f) floorf(f) +#define ceil(f) ceilf(f) +#define fmod(x,y) fmodf(x,y) +#define MRB_FLO_TO_STR_FMT "%.7g" +#else +#define MRB_FLO_TO_STR_FMT "%.14g" +#endif + +MRB_API mrb_float +mrb_to_flo(mrb_state *mrb, mrb_value val) +{ + switch (mrb_type(val)) { + case MRB_TT_FIXNUM: + return (mrb_float)mrb_fixnum(val); + case MRB_TT_FLOAT: + break; + default: + mrb_raise(mrb, E_TYPE_ERROR, "non float value"); + } + return mrb_float(val); +} + +/* + * call-seq: + * + * num ** other -> num + * + * Raises num the other power. + * + * 2.0**3 #=> 8.0 + */ +static mrb_value +num_pow(mrb_state *mrb, mrb_value x) +{ + mrb_value y; + mrb_float d; + + mrb_get_args(mrb, "o", &y); + if (mrb_fixnum_p(x) && mrb_fixnum_p(y)) { + /* try ipow() */ + mrb_int base = mrb_fixnum(x); + mrb_int exp = mrb_fixnum(y); + mrb_int result = 1; + + if (exp < 0) goto float_pow; + for (;;) { + if (exp & 1) { + if (mrb_int_mul_overflow(result, base, &result)) { + goto float_pow; + } + } + exp >>= 1; + if (exp == 0) break; + if (mrb_int_mul_overflow(base, base, &base)) { + goto float_pow; + } + } + return mrb_fixnum_value(result); + } + float_pow: + d = pow(mrb_to_flo(mrb, x), mrb_to_flo(mrb, y)); + return mrb_float_value(mrb, d); +} + +/* 15.2.8.3.4 */ +/* 15.2.9.3.4 */ +/* + * call-seq: + * num / other -> num + * + * Performs division: the class of the resulting object depends on + * the class of num and on the magnitude of the + * result. + */ + +mrb_value +mrb_num_div(mrb_state *mrb, mrb_value x, mrb_value y) +{ + return mrb_float_value(mrb, mrb_to_flo(mrb, x) / mrb_to_flo(mrb, y)); +} + +/* 15.2.9.3.19(x) */ +/* + * call-seq: + * num.quo(numeric) -> real + * + * Returns most exact division. + */ + +static mrb_value +num_div(mrb_state *mrb, mrb_value x) +{ + mrb_float y; + + mrb_get_args(mrb, "f", &y); + return mrb_float_value(mrb, mrb_to_flo(mrb, x) / y); +} + +/******************************************************************** + * + * Document-class: Float + * + * Float objects represent inexact real numbers using + * the native architecture's double-precision floating point + * representation. + */ + +/* 15.2.9.3.16(x) */ +/* + * call-seq: + * flt.to_s -> string + * + * Returns a string containing a representation of self. As well as a + * fixed or exponential form of the number, the call may return + * "NaN", "Infinity", and + * "-Infinity". + */ + +static mrb_value +flo_to_s(mrb_state *mrb, mrb_value flt) +{ + if (isnan(mrb_float(flt))) { + return mrb_str_new_lit(mrb, "NaN"); + } + return mrb_float_to_str(mrb, flt, MRB_FLO_TO_STR_FMT); +} + +/* 15.2.9.3.2 */ +/* + * call-seq: + * float - other -> float + * + * Returns a new float which is the difference of float + * and other. + */ + +static mrb_value +flo_minus(mrb_state *mrb, mrb_value x) +{ + mrb_value y; + + mrb_get_args(mrb, "o", &y); + return mrb_float_value(mrb, mrb_float(x) - mrb_to_flo(mrb, y)); +} + +/* 15.2.9.3.3 */ +/* + * call-seq: + * float * other -> float + * + * Returns a new float which is the product of float + * and other. + */ + +static mrb_value +flo_mul(mrb_state *mrb, mrb_value x) +{ + mrb_value y; + + mrb_get_args(mrb, "o", &y); + return mrb_float_value(mrb, mrb_float(x) * mrb_to_flo(mrb, y)); +} + +static void +flodivmod(mrb_state *mrb, mrb_float x, mrb_float y, mrb_float *divp, mrb_float *modp) +{ + mrb_float div; + mrb_float mod; + + if (y == 0.0) { + if (x > 0.0) div = INFINITY; + else if (x < 0.0) div = -INFINITY; + else div = NAN; /* x == 0.0 */ + mod = NAN; + } + else { + mod = fmod(x, y); + if (isinf(x) && isfinite(y)) + div = x; + else + div = (x - mod) / y; + if (y*mod < 0) { + mod += y; + div -= 1.0; + } + } + + if (modp) *modp = mod; + if (divp) *divp = div; +} + +/* 15.2.9.3.5 */ +/* + * call-seq: + * flt % other -> float + * flt.modulo(other) -> float + * + * Return the modulo after division of flt by other. + * + * 6543.21.modulo(137) #=> 104.21 + * 6543.21.modulo(137.24) #=> 92.9299999999996 + */ + +static mrb_value +flo_mod(mrb_state *mrb, mrb_value x) +{ + mrb_value y; + mrb_float mod; + + mrb_get_args(mrb, "o", &y); + + flodivmod(mrb, mrb_float(x), mrb_to_flo(mrb, y), 0, &mod); + return mrb_float_value(mrb, mod); +} + +/* 15.2.8.3.16 */ +/* + * call-seq: + * num.eql?(numeric) -> true or false + * + * Returns true if num and numeric are the + * same type and have equal values. + * + * 1 == 1.0 #=> true + * 1.eql?(1.0) #=> false + * (1.0).eql?(1.0) #=> true + */ +static mrb_value +fix_eql(mrb_state *mrb, mrb_value x) +{ + mrb_value y; + + mrb_get_args(mrb, "o", &y); + if (!mrb_fixnum_p(y)) return mrb_false_value(); + return mrb_bool_value(mrb_fixnum(x) == mrb_fixnum(y)); +} + +static mrb_value +flo_eql(mrb_state *mrb, mrb_value x) +{ + mrb_value y; + + mrb_get_args(mrb, "o", &y); + if (!mrb_float_p(y)) return mrb_false_value(); + return mrb_bool_value(mrb_float(x) == (mrb_float)mrb_fixnum(y)); +} + +/* 15.2.9.3.7 */ +/* + * call-seq: + * flt == obj -> true or false + * + * Returns true only if obj has the same value + * as flt. Contrast this with Float#eql?, which + * requires obj to be a Float. + * + * 1.0 == 1 #=> true + * + */ + +static mrb_value +flo_eq(mrb_state *mrb, mrb_value x) +{ + mrb_value y; + mrb_get_args(mrb, "o", &y); + + switch (mrb_type(y)) { + case MRB_TT_FIXNUM: + return mrb_bool_value(mrb_float(x) == (mrb_float)mrb_fixnum(y)); + case MRB_TT_FLOAT: + return mrb_bool_value(mrb_float(x) == mrb_float(y)); + default: + return mrb_false_value(); + } +} + +static int64_t +value_int64(mrb_state *mrb, mrb_value x) +{ + switch (mrb_type(x)) { + case MRB_TT_FIXNUM: + return (int64_t)mrb_fixnum(x); + break; + case MRB_TT_FLOAT: + return (int64_t)mrb_float(x); + default: + mrb_raise(mrb, E_TYPE_ERROR, "cannot convert to Integer"); + break; + } + /* not reached */ + return 0; +} + +static mrb_value +int64_value(mrb_state *mrb, int64_t v) +{ + if (FIXABLE(v)) { + return mrb_fixnum_value((mrb_int)v); + } + return mrb_float_value(mrb, (mrb_float)v); +} + +static mrb_value +flo_rev(mrb_state *mrb, mrb_value x) +{ + int64_t v1; + mrb_get_args(mrb, ""); + v1 = (int64_t)mrb_float(x); + return int64_value(mrb, ~v1); +} + +static mrb_value +flo_and(mrb_state *mrb, mrb_value x) +{ + mrb_value y; + int64_t v1, v2; + mrb_get_args(mrb, "o", &y); + + v1 = (int64_t)mrb_float(x); + v2 = value_int64(mrb, y); + return int64_value(mrb, v1 & v2); +} + +static mrb_value +flo_or(mrb_state *mrb, mrb_value x) +{ + mrb_value y; + int64_t v1, v2; + mrb_get_args(mrb, "o", &y); + + v1 = (int64_t)mrb_float(x); + v2 = value_int64(mrb, y); + return int64_value(mrb, v1 | v2); +} + +static mrb_value +flo_xor(mrb_state *mrb, mrb_value x) +{ + mrb_value y; + int64_t v1, v2; + mrb_get_args(mrb, "o", &y); + + v1 = (int64_t)mrb_float(x); + v2 = value_int64(mrb, y); + return int64_value(mrb, v1 ^ v2); +} + +static mrb_value +flo_shift(mrb_state *mrb, mrb_value x, mrb_int width) +{ + mrb_float val; + + if (width == 0) { + return x; + } + val = mrb_float(x); + if (width < 0) { + while (width++) { + val /= 2; + } +#if defined(_ISOC99_SOURCE) + val = trunc(val); +#else + if (val > 0){ + val = floor(val); + } else { + val = ceil(val); + } +#endif + if (val == 0 && mrb_float(x) < 0) { + return mrb_fixnum_value(-1); + } + } + else { + while (width--) { + val *= 2; + } + } + if (FIXABLE_FLOAT(val)) { + return mrb_fixnum_value((mrb_int)val); + } + return mrb_float_value(mrb, val); +} + +static mrb_value +flo_lshift(mrb_state *mrb, mrb_value x) +{ + mrb_int width; + + mrb_get_args(mrb, "i", &width); + return flo_shift(mrb, x, -width); +} + +static mrb_value +flo_rshift(mrb_state *mrb, mrb_value x) +{ + mrb_int width; + + mrb_get_args(mrb, "i", &width); + return flo_shift(mrb, x, width); +} + +/* 15.2.9.3.13 */ +/* + * call-seq: + * flt.to_f -> self + * + * As flt is already a float, returns +self+. + */ + +static mrb_value +flo_to_f(mrb_state *mrb, mrb_value num) +{ + return num; +} + +/* 15.2.9.3.11 */ +/* + * call-seq: + * flt.infinite? -> nil, -1, +1 + * + * Returns nil, -1, or +1 depending on whether flt + * is finite, -infinity, or +infinity. + * + * (0.0).infinite? #=> nil + * (-1.0/0.0).infinite? #=> -1 + * (+1.0/0.0).infinite? #=> 1 + */ + +static mrb_value +flo_infinite_p(mrb_state *mrb, mrb_value num) +{ + mrb_float value = mrb_float(num); + + if (isinf(value)) { + return mrb_fixnum_value(value < 0 ? -1 : 1); + } + return mrb_nil_value(); +} + +/* 15.2.9.3.9 */ +/* + * call-seq: + * flt.finite? -> true or false + * + * Returns true if flt is a valid IEEE floating + * point number (it is not infinite, and nan? is + * false). + * + */ + +static mrb_value +flo_finite_p(mrb_state *mrb, mrb_value num) +{ + return mrb_bool_value(isfinite(mrb_float(num))); +} + +void +mrb_check_num_exact(mrb_state *mrb, mrb_float num) +{ + if (isinf(num)) { + mrb_raise(mrb, E_FLOATDOMAIN_ERROR, num < 0 ? "-Infinity" : "Infinity"); + } + if (isnan(num)) { + mrb_raise(mrb, E_FLOATDOMAIN_ERROR, "NaN"); + } +} + +/* 15.2.9.3.10 */ +/* + * call-seq: + * flt.floor -> integer + * + * Returns the largest integer less than or equal to flt. + * + * 1.2.floor #=> 1 + * 2.0.floor #=> 2 + * (-1.2).floor #=> -2 + * (-2.0).floor #=> -2 + */ + +static mrb_value +flo_floor(mrb_state *mrb, mrb_value num) +{ + mrb_float f = floor(mrb_float(num)); + + mrb_check_num_exact(mrb, f); + if (!FIXABLE_FLOAT(f)) { + return mrb_float_value(mrb, f); + } + return mrb_fixnum_value((mrb_int)f); +} + +/* 15.2.9.3.8 */ +/* + * call-seq: + * flt.ceil -> integer + * + * Returns the smallest Integer greater than or equal to + * flt. + * + * 1.2.ceil #=> 2 + * 2.0.ceil #=> 2 + * (-1.2).ceil #=> -1 + * (-2.0).ceil #=> -2 + */ + +static mrb_value +flo_ceil(mrb_state *mrb, mrb_value num) +{ + mrb_float f = ceil(mrb_float(num)); + + mrb_check_num_exact(mrb, f); + if (!FIXABLE_FLOAT(f)) { + return mrb_float_value(mrb, f); + } + return mrb_fixnum_value((mrb_int)f); +} + +/* 15.2.9.3.12 */ +/* + * call-seq: + * flt.round([ndigits]) -> integer or float + * + * Rounds flt to a given precision in decimal digits (default 0 digits). + * Precision may be negative. Returns a floating point number when ndigits + * is more than zero. + * + * 1.4.round #=> 1 + * 1.5.round #=> 2 + * 1.6.round #=> 2 + * (-1.5).round #=> -2 + * + * 1.234567.round(2) #=> 1.23 + * 1.234567.round(3) #=> 1.235 + * 1.234567.round(4) #=> 1.2346 + * 1.234567.round(5) #=> 1.23457 + * + * 34567.89.round(-5) #=> 0 + * 34567.89.round(-4) #=> 30000 + * 34567.89.round(-3) #=> 35000 + * 34567.89.round(-2) #=> 34600 + * 34567.89.round(-1) #=> 34570 + * 34567.89.round(0) #=> 34568 + * 34567.89.round(1) #=> 34567.9 + * 34567.89.round(2) #=> 34567.89 + * 34567.89.round(3) #=> 34567.89 + * + */ + +static mrb_value +flo_round(mrb_state *mrb, mrb_value num) +{ + double number, f; + mrb_int ndigits = 0; + mrb_int i; + + mrb_get_args(mrb, "|i", &ndigits); + number = mrb_float(num); + + if (0 < ndigits && (isinf(number) || isnan(number))) { + return num; + } + mrb_check_num_exact(mrb, number); + + f = 1.0; + i = ndigits >= 0 ? ndigits : -ndigits; + while (--i >= 0) + f = f*10.0; + + if (isinf(f)) { + if (ndigits < 0) number = 0; + } + else { + double d; + + if (ndigits < 0) number /= f; + else number *= f; + + /* home-made inline implementation of round(3) */ + if (number > 0.0) { + d = floor(number); + number = d + (number - d >= 0.5); + } + else if (number < 0.0) { + d = ceil(number); + number = d - (d - number >= 0.5); + } + + if (ndigits < 0) number *= f; + else number /= f; + } + + if (ndigits > 0) { + if (!isfinite(number)) return num; + return mrb_float_value(mrb, number); + } + return mrb_fixnum_value((mrb_int)number); +} + +/* 15.2.9.3.14 */ +/* 15.2.9.3.15 */ +/* + * call-seq: + * flt.to_i -> integer + * flt.to_int -> integer + * flt.truncate -> integer + * + * Returns flt truncated to an Integer. + */ + +static mrb_value +flo_truncate(mrb_state *mrb, mrb_value num) +{ + mrb_float f = mrb_float(num); + + if (f > 0.0) f = floor(f); + if (f < 0.0) f = ceil(f); + + mrb_check_num_exact(mrb, f); + if (!FIXABLE_FLOAT(f)) { + return mrb_float_value(mrb, f); + } + return mrb_fixnum_value((mrb_int)f); +} + +static mrb_value +flo_nan_p(mrb_state *mrb, mrb_value num) +{ + return mrb_bool_value(isnan(mrb_float(num))); +} + +/* + * Document-class: Integer + * + * Integer is the basis for the two concrete classes that + * hold whole numbers, Bignum and Fixnum. + * + */ + + +/* + * call-seq: + * int.to_i -> integer + * int.to_int -> integer + * + * As int is already an Integer, all these + * methods simply return the receiver. + */ + +static mrb_value +int_to_i(mrb_state *mrb, mrb_value num) +{ + return num; +} + +mrb_value +mrb_fixnum_mul(mrb_state *mrb, mrb_value x, mrb_value y) +{ + mrb_int a; + + a = mrb_fixnum(x); + if (mrb_fixnum_p(y)) { + mrb_int b, c; + + if (a == 0) return x; + b = mrb_fixnum(y); + if (mrb_int_mul_overflow(a, b, &c)) { + return mrb_float_value(mrb, (mrb_float)a * (mrb_float)b); + } + return mrb_fixnum_value(c); + } + return mrb_float_value(mrb, (mrb_float)a * mrb_to_flo(mrb, y)); +} + +/* 15.2.8.3.3 */ +/* + * call-seq: + * fix * numeric -> numeric_result + * + * Performs multiplication: the class of the resulting object depends on + * the class of numeric and on the magnitude of the + * result. + */ + +static mrb_value +fix_mul(mrb_state *mrb, mrb_value x) +{ + mrb_value y; + + mrb_get_args(mrb, "o", &y); + return mrb_fixnum_mul(mrb, x, y); +} + +static void +fixdivmod(mrb_state *mrb, mrb_int x, mrb_int y, mrb_int *divp, mrb_int *modp) +{ + mrb_int div, mod; + + /* TODO: add mrb_assert(y != 0) to make sure */ + + if (y < 0) { + if (x < 0) + div = -x / -y; + else + div = - (x / -y); + } + else { + if (x < 0) + div = - (-x / y); + else + div = x / y; + } + mod = x - div*y; + if ((mod < 0 && y > 0) || (mod > 0 && y < 0)) { + mod += y; + div -= 1; + } + if (divp) *divp = div; + if (modp) *modp = mod; +} + +/* 15.2.8.3.5 */ +/* + * call-seq: + * fix % other -> real + * fix.modulo(other) -> real + * + * Returns fix modulo other. + * See numeric.divmod for more information. + */ + +static mrb_value +fix_mod(mrb_state *mrb, mrb_value x) +{ + mrb_value y; + mrb_int a; + + mrb_get_args(mrb, "o", &y); + a = mrb_fixnum(x); + if (mrb_fixnum_p(y)) { + mrb_int b, mod; + + if ((b=mrb_fixnum(y)) == 0) { + return mrb_float_value(mrb, NAN); + } + fixdivmod(mrb, a, b, 0, &mod); + return mrb_fixnum_value(mod); + } + else { + mrb_float mod; + + flodivmod(mrb, (mrb_float)a, mrb_to_flo(mrb, y), 0, &mod); + return mrb_float_value(mrb, mod); + } +} + +/* + * call-seq: + * fix.divmod(numeric) -> array + * + * See Numeric#divmod. + */ +static mrb_value +fix_divmod(mrb_state *mrb, mrb_value x) +{ + mrb_value y; + + mrb_get_args(mrb, "o", &y); + + if (mrb_fixnum_p(y)) { + mrb_int div, mod; + + if (mrb_fixnum(y) == 0) { + return mrb_assoc_new(mrb, ((mrb_fixnum(x) == 0) ? + mrb_float_value(mrb, NAN): + mrb_float_value(mrb, INFINITY)), + mrb_float_value(mrb, NAN)); + } + fixdivmod(mrb, mrb_fixnum(x), mrb_fixnum(y), &div, &mod); + return mrb_assoc_new(mrb, mrb_fixnum_value(div), mrb_fixnum_value(mod)); + } + else { + mrb_float div, mod; + mrb_value a, b; + + flodivmod(mrb, (mrb_float)mrb_fixnum(x), mrb_to_flo(mrb, y), &div, &mod); + a = mrb_float_value(mrb, div); + b = mrb_float_value(mrb, mod); + return mrb_assoc_new(mrb, a, b); + } +} + +static mrb_value +flo_divmod(mrb_state *mrb, mrb_value x) +{ + mrb_value y; + mrb_float div, mod; + mrb_value a, b; + + mrb_get_args(mrb, "o", &y); + + flodivmod(mrb, mrb_float(x), mrb_to_flo(mrb, y), &div, &mod); + a = mrb_float_value(mrb, div); + b = mrb_float_value(mrb, mod); + return mrb_assoc_new(mrb, a, b); +} + +/* 15.2.8.3.7 */ +/* + * call-seq: + * fix == other -> true or false + * + * Return true if fix equals other + * numerically. + * + * 1 == 2 #=> false + * 1 == 1.0 #=> true + */ + +static mrb_value +fix_equal(mrb_state *mrb, mrb_value x) +{ + mrb_value y; + + mrb_get_args(mrb, "o", &y); + switch (mrb_type(y)) { + case MRB_TT_FIXNUM: + return mrb_bool_value(mrb_fixnum(x) == mrb_fixnum(y)); + case MRB_TT_FLOAT: + return mrb_bool_value((mrb_float)mrb_fixnum(x) == mrb_float(y)); + default: + return mrb_false_value(); + } +} + +/* 15.2.8.3.8 */ +/* + * call-seq: + * ~fix -> integer + * + * One's complement: returns a number where each bit is flipped. + * ex.0---00001 (1)-> 1---11110 (-2) + * ex.0---00010 (2)-> 1---11101 (-3) + * ex.0---00100 (4)-> 1---11011 (-5) + */ + +static mrb_value +fix_rev(mrb_state *mrb, mrb_value num) +{ + mrb_int val = mrb_fixnum(num); + + return mrb_fixnum_value(~val); +} + +static mrb_value flo_and(mrb_state *mrb, mrb_value x); +static mrb_value flo_or(mrb_state *mrb, mrb_value x); +static mrb_value flo_xor(mrb_state *mrb, mrb_value x); +#define bit_op(x,y,op1,op2) do {\ + if (mrb_fixnum_p(y)) return mrb_fixnum_value(mrb_fixnum(x) op2 mrb_fixnum(y));\ + return flo_ ## op1(mrb, mrb_float_value(mrb, mrb_fixnum(x)));\ +} while(0) + +/* 15.2.8.3.9 */ +/* + * call-seq: + * fix & integer -> integer_result + * + * Bitwise AND. + */ + +static mrb_value +fix_and(mrb_state *mrb, mrb_value x) +{ + mrb_value y; + + mrb_get_args(mrb, "o", &y); + bit_op(x, y, and, &); +} + +/* 15.2.8.3.10 */ +/* + * call-seq: + * fix | integer -> integer_result + * + * Bitwise OR. + */ + +static mrb_value +fix_or(mrb_state *mrb, mrb_value x) +{ + mrb_value y; + + mrb_get_args(mrb, "o", &y); + bit_op(x, y, or, |); +} + +/* 15.2.8.3.11 */ +/* + * call-seq: + * fix ^ integer -> integer_result + * + * Bitwise EXCLUSIVE OR. + */ + +static mrb_value +fix_xor(mrb_state *mrb, mrb_value x) +{ + mrb_value y; + + mrb_get_args(mrb, "o", &y); + bit_op(x, y, or, ^); +} + +#define NUMERIC_SHIFT_WIDTH_MAX (MRB_INT_BIT-1) + +static mrb_value +lshift(mrb_state *mrb, mrb_int val, mrb_int width) +{ + if (width < 0) { /* mrb_int overflow */ + return mrb_float_value(mrb, INFINITY); + } + if (val > 0) { + if ((width > NUMERIC_SHIFT_WIDTH_MAX) || + (val > (MRB_INT_MAX >> width))) { + goto bit_overflow; + } + return mrb_fixnum_value(val << width); + } + else { + if ((width > NUMERIC_SHIFT_WIDTH_MAX) || + (val < (MRB_INT_MIN >> width))) { + goto bit_overflow; + } + return mrb_fixnum_value(val * (1u << width)); + } + +bit_overflow: + { + mrb_float f = (mrb_float)val; + while (width--) { + f *= 2; + } + return mrb_float_value(mrb, f); + } +} + +static mrb_value +rshift(mrb_int val, mrb_int width) +{ + if (width < 0) { /* mrb_int overflow */ + return mrb_fixnum_value(0); + } + if (width >= NUMERIC_SHIFT_WIDTH_MAX) { + if (val < 0) { + return mrb_fixnum_value(-1); + } + return mrb_fixnum_value(0); + } + return mrb_fixnum_value(val >> width); +} + +/* 15.2.8.3.12 */ +/* + * call-seq: + * fix << count -> integer or float + * + * Shifts _fix_ left _count_ positions (right if _count_ is negative). + */ + +static mrb_value +fix_lshift(mrb_state *mrb, mrb_value x) +{ + mrb_int width, val; + + mrb_get_args(mrb, "i", &width); + if (width == 0) { + return x; + } + val = mrb_fixnum(x); + if (val == 0) return x; + if (width < 0) { + return rshift(val, -width); + } + return lshift(mrb, val, width); +} + +/* 15.2.8.3.13 */ +/* + * call-seq: + * fix >> count -> integer or float + * + * Shifts _fix_ right _count_ positions (left if _count_ is negative). + */ + +static mrb_value +fix_rshift(mrb_state *mrb, mrb_value x) +{ + mrb_int width, val; + + mrb_get_args(mrb, "i", &width); + if (width == 0) { + return x; + } + val = mrb_fixnum(x); + if (val == 0) return x; + if (width < 0) { + return lshift(mrb, val, -width); + } + return rshift(val, width); +} + +/* 15.2.8.3.23 */ +/* + * call-seq: + * fix.to_f -> float + * + * Converts fix to a Float. + * + */ + +static mrb_value +fix_to_f(mrb_state *mrb, mrb_value num) +{ + return mrb_float_value(mrb, (mrb_float)mrb_fixnum(num)); +} + +/* + * Document-class: FloatDomainError + * + * Raised when attempting to convert special float values + * (in particular infinite or NaN) + * to numerical classes which don't support them. + * + * Float::INFINITY.to_r + * + * raises the exception: + * + * FloatDomainError: Infinity + */ +/* ------------------------------------------------------------------------*/ +MRB_API mrb_value +mrb_flo_to_fixnum(mrb_state *mrb, mrb_value x) +{ + mrb_int z = 0; + + if (!mrb_float_p(x)) { + mrb_raise(mrb, E_TYPE_ERROR, "non float value"); + z = 0; /* not reached. just suppress warnings. */ + } + else { + mrb_float d = mrb_float(x); + + if (isinf(d)) { + mrb_raise(mrb, E_FLOATDOMAIN_ERROR, d < 0 ? "-Infinity" : "Infinity"); + } + if (isnan(d)) { + mrb_raise(mrb, E_FLOATDOMAIN_ERROR, "NaN"); + } + if (FIXABLE_FLOAT(d)) { + z = (mrb_int)d; + } + else { + mrb_raisef(mrb, E_ARGUMENT_ERROR, "number (%S) too big for integer", x); + } + } + return mrb_fixnum_value(z); +} + +mrb_value +mrb_fixnum_plus(mrb_state *mrb, mrb_value x, mrb_value y) +{ + mrb_int a; + + a = mrb_fixnum(x); + if (mrb_fixnum_p(y)) { + mrb_int b, c; + + if (a == 0) return y; + b = mrb_fixnum(y); + if (mrb_int_add_overflow(a, b, &c)) { + return mrb_float_value(mrb, (mrb_float)a + (mrb_float)b); + } + return mrb_fixnum_value(c); + } + return mrb_float_value(mrb, (mrb_float)a + mrb_to_flo(mrb, y)); +} + +/* 15.2.8.3.1 */ +/* + * call-seq: + * fix + numeric -> numeric_result + * + * Performs addition: the class of the resulting object depends on + * the class of numeric and on the magnitude of the + * result. + */ +static mrb_value +fix_plus(mrb_state *mrb, mrb_value self) +{ + mrb_value other; + + mrb_get_args(mrb, "o", &other); + return mrb_fixnum_plus(mrb, self, other); +} + +mrb_value +mrb_fixnum_minus(mrb_state *mrb, mrb_value x, mrb_value y) +{ + mrb_int a; + + a = mrb_fixnum(x); + if (mrb_fixnum_p(y)) { + mrb_int b, c; + + b = mrb_fixnum(y); + if (mrb_int_sub_overflow(a, b, &c)) { + return mrb_float_value(mrb, (mrb_float)a - (mrb_float)b); + } + return mrb_fixnum_value(c); + } + return mrb_float_value(mrb, (mrb_float)a - mrb_to_flo(mrb, y)); +} + +/* 15.2.8.3.2 */ +/* 15.2.8.3.16 */ +/* + * call-seq: + * fix - numeric -> numeric_result + * + * Performs subtraction: the class of the resulting object depends on + * the class of numeric and on the magnitude of the + * result. + */ +static mrb_value +fix_minus(mrb_state *mrb, mrb_value self) +{ + mrb_value other; + + mrb_get_args(mrb, "o", &other); + return mrb_fixnum_minus(mrb, self, other); +} + + +MRB_API mrb_value +mrb_fixnum_to_str(mrb_state *mrb, mrb_value x, int base) +{ + char buf[MRB_INT_BIT+1]; + char *b = buf + sizeof buf; + mrb_int val = mrb_fixnum(x); + + if (base < 2 || 36 < base) { + mrb_raisef(mrb, E_ARGUMENT_ERROR, "invalid radix %S", mrb_fixnum_value(base)); + } + + if (val == 0) { + *--b = '0'; + } + else if (val < 0) { + do { + *--b = mrb_digitmap[-(val % base)]; + } while (val /= base); + *--b = '-'; + } + else { + do { + *--b = mrb_digitmap[(int)(val % base)]; + } while (val /= base); + } + + return mrb_str_new(mrb, b, buf + sizeof(buf) - b); +} + +/* 15.2.8.3.25 */ +/* + * call-seq: + * fix.to_s(base=10) -> string + * + * Returns a string containing the representation of fix radix + * base (between 2 and 36). + * + * 12345.to_s #=> "12345" + * 12345.to_s(2) #=> "11000000111001" + * 12345.to_s(8) #=> "30071" + * 12345.to_s(10) #=> "12345" + * 12345.to_s(16) #=> "3039" + * 12345.to_s(36) #=> "9ix" + * + */ +static mrb_value +fix_to_s(mrb_state *mrb, mrb_value self) +{ + mrb_int base = 10; + + mrb_get_args(mrb, "|i", &base); + return mrb_fixnum_to_str(mrb, self, base); +} + +/* 15.2.9.3.6 */ +/* + * call-seq: + * self.f <=> other.f => -1, 0, +1 + * < => -1 + * = => 0 + * > => +1 + * Comparison---Returns -1, 0, or +1 depending on whether fix is + * less than, equal to, or greater than numeric. This is the + * basis for the tests in Comparable. + */ +static mrb_value +num_cmp(mrb_state *mrb, mrb_value self) +{ + mrb_value other; + mrb_float x, y; + + mrb_get_args(mrb, "o", &other); + + x = mrb_to_flo(mrb, self); + switch (mrb_type(other)) { + case MRB_TT_FIXNUM: + y = (mrb_float)mrb_fixnum(other); + break; + case MRB_TT_FLOAT: + y = mrb_float(other); + break; + default: + return mrb_nil_value(); + } + if (x > y) + return mrb_fixnum_value(1); + else { + if (x < y) + return mrb_fixnum_value(-1); + return mrb_fixnum_value(0); + } +} + +/* 15.2.9.3.1 */ +/* + * call-seq: + * float + other -> float + * + * Returns a new float which is the sum of float + * and other. + */ +static mrb_value +flo_plus(mrb_state *mrb, mrb_value x) +{ + mrb_value y; + + mrb_get_args(mrb, "o", &y); + return mrb_float_value(mrb, mrb_float(x) + mrb_to_flo(mrb, y)); +} + +/* ------------------------------------------------------------------------*/ +void +mrb_init_numeric(mrb_state *mrb) +{ + struct RClass *numeric, *integer, *fixnum, *fl; + + /* Numeric Class */ + numeric = mrb_define_class(mrb, "Numeric", mrb->object_class); /* 15.2.7 */ + + mrb_define_method(mrb, numeric, "**", num_pow, MRB_ARGS_REQ(1)); + mrb_define_method(mrb, numeric, "/", num_div, MRB_ARGS_REQ(1)); /* 15.2.8.3.4 */ + mrb_define_method(mrb, numeric, "quo", num_div, MRB_ARGS_REQ(1)); /* 15.2.7.4.5 (x) */ + mrb_define_method(mrb, numeric, "<=>", num_cmp, MRB_ARGS_REQ(1)); /* 15.2.9.3.6 */ + + /* Integer Class */ + integer = mrb_define_class(mrb, "Integer", numeric); /* 15.2.8 */ + MRB_SET_INSTANCE_TT(integer, MRB_TT_FIXNUM); + mrb_undef_class_method(mrb, integer, "new"); + mrb_define_method(mrb, integer, "to_i", int_to_i, MRB_ARGS_NONE()); /* 15.2.8.3.24 */ + mrb_define_method(mrb, integer, "to_int", int_to_i, MRB_ARGS_NONE()); + mrb_define_method(mrb, integer, "ceil", int_to_i, MRB_ARGS_REQ(1)); /* 15.2.8.3.8 (x) */ + mrb_define_method(mrb, integer, "floor", int_to_i, MRB_ARGS_REQ(1)); /* 15.2.8.3.10 (x) */ + mrb_define_method(mrb, integer, "round", int_to_i, MRB_ARGS_REQ(1)); /* 15.2.8.3.12 (x) */ + mrb_define_method(mrb, integer, "truncate", int_to_i, MRB_ARGS_REQ(1)); /* 15.2.8.3.15 (x) */ + + /* Fixnum Class */ + mrb->fixnum_class = fixnum = mrb_define_class(mrb, "Fixnum", integer); + mrb_define_method(mrb, fixnum, "+", fix_plus, MRB_ARGS_REQ(1)); /* 15.2.8.3.1 */ + mrb_define_method(mrb, fixnum, "-", fix_minus, MRB_ARGS_REQ(1)); /* 15.2.8.3.2 */ + mrb_define_method(mrb, fixnum, "*", fix_mul, MRB_ARGS_REQ(1)); /* 15.2.8.3.3 */ + mrb_define_method(mrb, fixnum, "%", fix_mod, MRB_ARGS_REQ(1)); /* 15.2.8.3.5 */ + mrb_define_method(mrb, fixnum, "==", fix_equal, MRB_ARGS_REQ(1)); /* 15.2.8.3.7 */ + mrb_define_method(mrb, fixnum, "~", fix_rev, MRB_ARGS_NONE()); /* 15.2.8.3.8 */ + mrb_define_method(mrb, fixnum, "&", fix_and, MRB_ARGS_REQ(1)); /* 15.2.8.3.9 */ + mrb_define_method(mrb, fixnum, "|", fix_or, MRB_ARGS_REQ(1)); /* 15.2.8.3.10 */ + mrb_define_method(mrb, fixnum, "^", fix_xor, MRB_ARGS_REQ(1)); /* 15.2.8.3.11 */ + mrb_define_method(mrb, fixnum, "<<", fix_lshift, MRB_ARGS_REQ(1)); /* 15.2.8.3.12 */ + mrb_define_method(mrb, fixnum, ">>", fix_rshift, MRB_ARGS_REQ(1)); /* 15.2.8.3.13 */ + mrb_define_method(mrb, fixnum, "eql?", fix_eql, MRB_ARGS_REQ(1)); /* 15.2.8.3.16 */ + mrb_define_method(mrb, fixnum, "to_f", fix_to_f, MRB_ARGS_NONE()); /* 15.2.8.3.23 */ + mrb_define_method(mrb, fixnum, "to_s", fix_to_s, MRB_ARGS_NONE()); /* 15.2.8.3.25 */ + mrb_define_method(mrb, fixnum, "inspect", fix_to_s, MRB_ARGS_NONE()); + mrb_define_method(mrb, fixnum, "divmod", fix_divmod, MRB_ARGS_REQ(1)); /* 15.2.8.3.30 (x) */ + + /* Float Class */ + mrb->float_class = fl = mrb_define_class(mrb, "Float", numeric); /* 15.2.9 */ + MRB_SET_INSTANCE_TT(fl, MRB_TT_FLOAT); + mrb_undef_class_method(mrb, fl, "new"); + mrb_define_method(mrb, fl, "+", flo_plus, MRB_ARGS_REQ(1)); /* 15.2.9.3.1 */ + mrb_define_method(mrb, fl, "-", flo_minus, MRB_ARGS_REQ(1)); /* 15.2.9.3.2 */ + mrb_define_method(mrb, fl, "*", flo_mul, MRB_ARGS_REQ(1)); /* 15.2.9.3.3 */ + mrb_define_method(mrb, fl, "%", flo_mod, MRB_ARGS_REQ(1)); /* 15.2.9.3.5 */ + mrb_define_method(mrb, fl, "==", flo_eq, MRB_ARGS_REQ(1)); /* 15.2.9.3.7 */ + mrb_define_method(mrb, fl, "~", flo_rev, MRB_ARGS_NONE()); + mrb_define_method(mrb, fl, "&", flo_and, MRB_ARGS_REQ(1)); + mrb_define_method(mrb, fl, "|", flo_or, MRB_ARGS_REQ(1)); + mrb_define_method(mrb, fl, "^", flo_xor, MRB_ARGS_REQ(1)); + mrb_define_method(mrb, fl, ">>", flo_lshift, MRB_ARGS_REQ(1)); + mrb_define_method(mrb, fl, "<<", flo_rshift, MRB_ARGS_REQ(1)); + mrb_define_method(mrb, fl, "ceil", flo_ceil, MRB_ARGS_NONE()); /* 15.2.9.3.8 */ + mrb_define_method(mrb, fl, "finite?", flo_finite_p, MRB_ARGS_NONE()); /* 15.2.9.3.9 */ + mrb_define_method(mrb, fl, "floor", flo_floor, MRB_ARGS_NONE()); /* 15.2.9.3.10 */ + mrb_define_method(mrb, fl, "infinite?", flo_infinite_p, MRB_ARGS_NONE()); /* 15.2.9.3.11 */ + mrb_define_method(mrb, fl, "round", flo_round, MRB_ARGS_OPT(1)); /* 15.2.9.3.12 */ + mrb_define_method(mrb, fl, "to_f", flo_to_f, MRB_ARGS_NONE()); /* 15.2.9.3.13 */ + mrb_define_method(mrb, fl, "to_i", flo_truncate, MRB_ARGS_NONE()); /* 15.2.9.3.14 */ + mrb_define_method(mrb, fl, "to_int", flo_truncate, MRB_ARGS_NONE()); + mrb_define_method(mrb, fl, "truncate", flo_truncate, MRB_ARGS_NONE()); /* 15.2.9.3.15 */ + mrb_define_method(mrb, fl, "divmod", flo_divmod, MRB_ARGS_REQ(1)); + mrb_define_method(mrb, fl, "eql?", flo_eql, MRB_ARGS_REQ(1)); /* 15.2.8.3.16 */ + + mrb_define_method(mrb, fl, "to_s", flo_to_s, MRB_ARGS_NONE()); /* 15.2.9.3.16(x) */ + mrb_define_method(mrb, fl, "inspect", flo_to_s, MRB_ARGS_NONE()); + mrb_define_method(mrb, fl, "nan?", flo_nan_p, MRB_ARGS_NONE()); + +#ifdef INFINITY + mrb_define_const(mrb, fl, "INFINITY", mrb_float_value(mrb, INFINITY)); +#endif +#ifdef NAN + mrb_define_const(mrb, fl, "NAN", mrb_float_value(mrb, NAN)); +#endif +} diff --git a/web/server/h2o/libh2o/deps/mruby/src/object.c b/web/server/h2o/libh2o/deps/mruby/src/object.c new file mode 100644 index 00000000..368e90b9 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/src/object.c @@ -0,0 +1,610 @@ +/* +** object.c - Object, NilClass, TrueClass, FalseClass class +** +** See Copyright Notice in mruby.h +*/ + +#include +#include +#include +#include +#include + +MRB_API mrb_bool +mrb_obj_eq(mrb_state *mrb, mrb_value v1, mrb_value v2) +{ + if (mrb_type(v1) != mrb_type(v2)) return FALSE; + switch (mrb_type(v1)) { + case MRB_TT_TRUE: + return TRUE; + + case MRB_TT_FALSE: + case MRB_TT_FIXNUM: + return (mrb_fixnum(v1) == mrb_fixnum(v2)); + case MRB_TT_SYMBOL: + return (mrb_symbol(v1) == mrb_symbol(v2)); + + case MRB_TT_FLOAT: + return (mrb_float(v1) == mrb_float(v2)); + + default: + return (mrb_ptr(v1) == mrb_ptr(v2)); + } +} + +MRB_API mrb_bool +mrb_obj_equal(mrb_state *mrb, mrb_value v1, mrb_value v2) +{ + /* temporary definition */ + return mrb_obj_eq(mrb, v1, v2); +} + +MRB_API mrb_bool +mrb_equal(mrb_state *mrb, mrb_value obj1, mrb_value obj2) +{ + mrb_value result; + + if (mrb_obj_eq(mrb, obj1, obj2)) return TRUE; + result = mrb_funcall(mrb, obj1, "==", 1, obj2); + if (mrb_test(result)) return TRUE; + return FALSE; +} + +/* + * Document-class: NilClass + * + * The class of the singleton object nil. + */ + +/* 15.2.4.3.4 */ +/* + * call_seq: + * nil.nil? -> true + * + * Only the object nil responds true to nil?. + */ + +static mrb_value +mrb_true(mrb_state *mrb, mrb_value obj) +{ + return mrb_true_value(); +} + +/* 15.2.4.3.5 */ +/* + * call-seq: + * nil.to_s -> "" + * + * Always returns the empty string. + */ + +static mrb_value +nil_to_s(mrb_state *mrb, mrb_value obj) +{ + return mrb_str_new(mrb, 0, 0); +} + +static mrb_value +nil_inspect(mrb_state *mrb, mrb_value obj) +{ + return mrb_str_new_lit(mrb, "nil"); +} + +/*********************************************************************** + * Document-class: TrueClass + * + * The global value true is the only instance of class + * TrueClass and represents a logically true value in + * boolean expressions. The class provides operators allowing + * true to be used in logical expressions. + */ + +/* 15.2.5.3.1 */ +/* + * call-seq: + * true & obj -> true or false + * + * And---Returns false if obj is + * nil or false, true otherwise. + */ + +static mrb_value +true_and(mrb_state *mrb, mrb_value obj) +{ + mrb_bool obj2; + + mrb_get_args(mrb, "b", &obj2); + + return mrb_bool_value(obj2); +} + +/* 15.2.5.3.2 */ +/* + * call-seq: + * true ^ obj -> !obj + * + * Exclusive Or---Returns true if obj is + * nil or false, false + * otherwise. + */ + +static mrb_value +true_xor(mrb_state *mrb, mrb_value obj) +{ + mrb_bool obj2; + + mrb_get_args(mrb, "b", &obj2); + return mrb_bool_value(!obj2); +} + +/* 15.2.5.3.3 */ +/* + * call-seq: + * true.to_s -> "true" + * + * The string representation of true is "true". + */ + +static mrb_value +true_to_s(mrb_state *mrb, mrb_value obj) +{ + return mrb_str_new_lit(mrb, "true"); +} + +/* 15.2.5.3.4 */ +/* + * call-seq: + * true | obj -> true + * + * Or---Returns true. As anObject is an argument to + * a method call, it is always evaluated; there is no short-circuit + * evaluation in this case. + * + * true | puts("or") + * true || puts("logical or") + * + * produces: + * + * or + */ + +static mrb_value +true_or(mrb_state *mrb, mrb_value obj) +{ + return mrb_true_value(); +} + +/* + * Document-class: FalseClass + * + * The global value false is the only instance of class + * FalseClass and represents a logically false value in + * boolean expressions. The class provides operators allowing + * false to participate correctly in logical expressions. + * + */ + +/* 15.2.4.3.1 */ +/* 15.2.6.3.1 */ +/* + * call-seq: + * false & obj -> false + * nil & obj -> false + * + * And---Returns false. obj is always + * evaluated as it is the argument to a method call---there is no + * short-circuit evaluation in this case. + */ + +static mrb_value +false_and(mrb_state *mrb, mrb_value obj) +{ + return mrb_false_value(); +} + +/* 15.2.4.3.2 */ +/* 15.2.6.3.2 */ +/* + * call-seq: + * false ^ obj -> true or false + * nil ^ obj -> true or false + * + * Exclusive Or---If obj is nil or + * false, returns false; otherwise, returns + * true. + * + */ + +static mrb_value +false_xor(mrb_state *mrb, mrb_value obj) +{ + mrb_bool obj2; + + mrb_get_args(mrb, "b", &obj2); + return mrb_bool_value(obj2); +} + +/* 15.2.4.3.3 */ +/* 15.2.6.3.4 */ +/* + * call-seq: + * false | obj -> true or false + * nil | obj -> true or false + * + * Or---Returns false if obj is + * nil or false; true otherwise. + */ + +static mrb_value +false_or(mrb_state *mrb, mrb_value obj) +{ + mrb_bool obj2; + + mrb_get_args(mrb, "b", &obj2); + return mrb_bool_value(obj2); +} + +/* 15.2.6.3.3 */ +/* + * call-seq: + * false.to_s -> "false" + * + * 'nuf said... + */ + +static mrb_value +false_to_s(mrb_state *mrb, mrb_value obj) +{ + return mrb_str_new_lit(mrb, "false"); +} + +void +mrb_init_object(mrb_state *mrb) +{ + struct RClass *n; + struct RClass *t; + struct RClass *f; + + mrb->nil_class = n = mrb_define_class(mrb, "NilClass", mrb->object_class); + MRB_SET_INSTANCE_TT(n, MRB_TT_TRUE); + mrb_undef_class_method(mrb, n, "new"); + mrb_define_method(mrb, n, "&", false_and, MRB_ARGS_REQ(1)); /* 15.2.4.3.1 */ + mrb_define_method(mrb, n, "^", false_xor, MRB_ARGS_REQ(1)); /* 15.2.4.3.2 */ + mrb_define_method(mrb, n, "|", false_or, MRB_ARGS_REQ(1)); /* 15.2.4.3.3 */ + mrb_define_method(mrb, n, "nil?", mrb_true, MRB_ARGS_NONE()); /* 15.2.4.3.4 */ + mrb_define_method(mrb, n, "to_s", nil_to_s, MRB_ARGS_NONE()); /* 15.2.4.3.5 */ + mrb_define_method(mrb, n, "inspect", nil_inspect, MRB_ARGS_NONE()); + + mrb->true_class = t = mrb_define_class(mrb, "TrueClass", mrb->object_class); + MRB_SET_INSTANCE_TT(t, MRB_TT_TRUE); + mrb_undef_class_method(mrb, t, "new"); + mrb_define_method(mrb, t, "&", true_and, MRB_ARGS_REQ(1)); /* 15.2.5.3.1 */ + mrb_define_method(mrb, t, "^", true_xor, MRB_ARGS_REQ(1)); /* 15.2.5.3.2 */ + mrb_define_method(mrb, t, "to_s", true_to_s, MRB_ARGS_NONE()); /* 15.2.5.3.3 */ + mrb_define_method(mrb, t, "|", true_or, MRB_ARGS_REQ(1)); /* 15.2.5.3.4 */ + mrb_define_method(mrb, t, "inspect", true_to_s, MRB_ARGS_NONE()); + + mrb->false_class = f = mrb_define_class(mrb, "FalseClass", mrb->object_class); + MRB_SET_INSTANCE_TT(f, MRB_TT_TRUE); + mrb_undef_class_method(mrb, f, "new"); + mrb_define_method(mrb, f, "&", false_and, MRB_ARGS_REQ(1)); /* 15.2.6.3.1 */ + mrb_define_method(mrb, f, "^", false_xor, MRB_ARGS_REQ(1)); /* 15.2.6.3.2 */ + mrb_define_method(mrb, f, "to_s", false_to_s, MRB_ARGS_NONE()); /* 15.2.6.3.3 */ + mrb_define_method(mrb, f, "|", false_or, MRB_ARGS_REQ(1)); /* 15.2.6.3.4 */ + mrb_define_method(mrb, f, "inspect", false_to_s, MRB_ARGS_NONE()); +} + +static mrb_value +inspect_type(mrb_state *mrb, mrb_value val) +{ + if (mrb_type(val) == MRB_TT_FALSE || mrb_type(val) == MRB_TT_TRUE) { + return mrb_inspect(mrb, val); + } + else { + return mrb_str_new_cstr(mrb, mrb_obj_classname(mrb, val)); + } +} + +static mrb_value +convert_type(mrb_state *mrb, mrb_value val, const char *tname, const char *method, mrb_bool raise) +{ + mrb_sym m = 0; + + m = mrb_intern_cstr(mrb, method); + if (!mrb_respond_to(mrb, val, m)) { + if (raise) { + mrb_raisef(mrb, E_TYPE_ERROR, "can't convert %S into %S", inspect_type(mrb, val), mrb_str_new_cstr(mrb, tname)); + } + return mrb_nil_value(); + } + return mrb_funcall_argv(mrb, val, m, 0, 0); +} + +MRB_API mrb_value +mrb_check_to_integer(mrb_state *mrb, mrb_value val, const char *method) +{ + mrb_value v; + + if (mrb_fixnum_p(val)) return val; + v = convert_type(mrb, val, "Integer", method, FALSE); + if (mrb_nil_p(v) || !mrb_fixnum_p(v)) { + return mrb_nil_value(); + } + return v; +} + +MRB_API mrb_value +mrb_convert_type(mrb_state *mrb, mrb_value val, enum mrb_vtype type, const char *tname, const char *method) +{ + mrb_value v; + + if (mrb_type(val) == type) return val; + v = convert_type(mrb, val, tname, method, TRUE); + if (mrb_type(v) != type) { + mrb_raisef(mrb, E_TYPE_ERROR, "%S cannot be converted to %S by #%S", val, + mrb_str_new_cstr(mrb, tname), mrb_str_new_cstr(mrb, method)); + } + return v; +} + +MRB_API mrb_value +mrb_check_convert_type(mrb_state *mrb, mrb_value val, enum mrb_vtype type, const char *tname, const char *method) +{ + mrb_value v; + + if (mrb_type(val) == type && type != MRB_TT_DATA && type != MRB_TT_ISTRUCT) return val; + v = convert_type(mrb, val, tname, method, FALSE); + if (mrb_nil_p(v) || mrb_type(v) != type) return mrb_nil_value(); + return v; +} + +static const struct types { + unsigned char type; + const char *name; +} builtin_types[] = { +/* {MRB_TT_NIL, "nil"}, */ + {MRB_TT_FALSE, "false"}, + {MRB_TT_TRUE, "true"}, + {MRB_TT_FIXNUM, "Fixnum"}, + {MRB_TT_SYMBOL, "Symbol"}, /* :symbol */ + {MRB_TT_MODULE, "Module"}, + {MRB_TT_OBJECT, "Object"}, + {MRB_TT_CLASS, "Class"}, + {MRB_TT_ICLASS, "iClass"}, /* internal use: mixed-in module holder */ + {MRB_TT_SCLASS, "SClass"}, + {MRB_TT_PROC, "Proc"}, + {MRB_TT_FLOAT, "Float"}, + {MRB_TT_ARRAY, "Array"}, + {MRB_TT_HASH, "Hash"}, + {MRB_TT_STRING, "String"}, + {MRB_TT_RANGE, "Range"}, +/* {MRB_TT_BIGNUM, "Bignum"}, */ + {MRB_TT_FILE, "File"}, + {MRB_TT_DATA, "Data"}, /* internal use: wrapped C pointers */ +/* {MRB_TT_VARMAP, "Varmap"}, */ /* internal use: dynamic variables */ +/* {MRB_TT_NODE, "Node"}, */ /* internal use: syntax tree node */ +/* {MRB_TT_UNDEF, "undef"}, */ /* internal use: #undef; should not happen */ + {MRB_TT_MAXDEFINE, 0} +}; + +MRB_API void +mrb_check_type(mrb_state *mrb, mrb_value x, enum mrb_vtype t) +{ + const struct types *type = builtin_types; + enum mrb_vtype xt; + + xt = mrb_type(x); + if ((xt != t) || (xt == MRB_TT_DATA) || (xt == MRB_TT_ISTRUCT)) { + while (type->type < MRB_TT_MAXDEFINE) { + if (type->type == t) { + const char *etype; + + if (mrb_nil_p(x)) { + etype = "nil"; + } + else if (mrb_fixnum_p(x)) { + etype = "Fixnum"; + } + else if (mrb_type(x) == MRB_TT_SYMBOL) { + etype = "Symbol"; + } + else if (mrb_immediate_p(x)) { + etype = RSTRING_PTR(mrb_obj_as_string(mrb, x)); + } + else { + etype = mrb_obj_classname(mrb, x); + } + mrb_raisef(mrb, E_TYPE_ERROR, "wrong argument type %S (expected %S)", + mrb_str_new_cstr(mrb, etype), mrb_str_new_cstr(mrb, type->name)); + } + type++; + } + mrb_raisef(mrb, E_TYPE_ERROR, "unknown type %S (%S given)", + mrb_fixnum_value(t), mrb_fixnum_value(mrb_type(x))); + } +} + +/* 15.3.1.3.46 */ +/* + * call-seq: + * obj.to_s => string + * + * Returns a string representing obj. The default + * to_s prints the object's class and an encoding of the + * object id. As a special case, the top-level object that is the + * initial execution context of Ruby programs returns "main." + */ + +MRB_API mrb_value +mrb_any_to_s(mrb_state *mrb, mrb_value obj) +{ + mrb_value str = mrb_str_new_capa(mrb, 20); + const char *cname = mrb_obj_classname(mrb, obj); + + mrb_str_cat_lit(mrb, str, "#<"); + mrb_str_cat_cstr(mrb, str, cname); + mrb_str_cat_lit(mrb, str, ":"); + mrb_str_concat(mrb, str, mrb_ptr_to_str(mrb, mrb_ptr(obj))); + mrb_str_cat_lit(mrb, str, ">"); + + return str; +} + +/* + * call-seq: + * obj.is_a?(class) => true or false + * obj.kind_of?(class) => true or false + * + * Returns true if class is the class of + * obj, or if class is one of the superclasses of + * obj or modules included in obj. + * + * module M; end + * class A + * include M + * end + * class B < A; end + * class C < B; end + * b = B.new + * b.instance_of? A #=> false + * b.instance_of? B #=> true + * b.instance_of? C #=> false + * b.instance_of? M #=> false + * b.kind_of? A #=> true + * b.kind_of? B #=> true + * b.kind_of? C #=> false + * b.kind_of? M #=> true + */ + +MRB_API mrb_bool +mrb_obj_is_kind_of(mrb_state *mrb, mrb_value obj, struct RClass *c) +{ + struct RClass *cl = mrb_class(mrb, obj); + + switch (c->tt) { + case MRB_TT_MODULE: + case MRB_TT_CLASS: + case MRB_TT_ICLASS: + case MRB_TT_SCLASS: + break; + + default: + mrb_raise(mrb, E_TYPE_ERROR, "class or module required"); + } + + MRB_CLASS_ORIGIN(c); + while (cl) { + if (cl == c || cl->mt == c->mt) + return TRUE; + cl = cl->super; + } + return FALSE; +} + +static mrb_value +mrb_to_integer(mrb_state *mrb, mrb_value val, const char *method) +{ + mrb_value v; + + if (mrb_fixnum_p(val)) return val; + v = convert_type(mrb, val, "Integer", method, TRUE); + if (!mrb_obj_is_kind_of(mrb, v, mrb->fixnum_class)) { + mrb_value type = inspect_type(mrb, val); + mrb_raisef(mrb, E_TYPE_ERROR, "can't convert %S to Integer (%S#%S gives %S)", + type, type, mrb_str_new_cstr(mrb, method), inspect_type(mrb, v)); + } + return v; +} + +MRB_API mrb_value +mrb_to_int(mrb_state *mrb, mrb_value val) +{ + return mrb_to_integer(mrb, val, "to_int"); +} + +MRB_API mrb_value +mrb_convert_to_integer(mrb_state *mrb, mrb_value val, int base) +{ + mrb_value tmp; + + if (mrb_nil_p(val)) { + if (base != 0) goto arg_error; + mrb_raise(mrb, E_TYPE_ERROR, "can't convert nil into Integer"); + } + switch (mrb_type(val)) { + case MRB_TT_FLOAT: + if (base != 0) goto arg_error; + else { + mrb_float f = mrb_float(val); + if (FIXABLE_FLOAT(f)) { + break; + } + } + return mrb_flo_to_fixnum(mrb, val); + + case MRB_TT_FIXNUM: + if (base != 0) goto arg_error; + return val; + + case MRB_TT_STRING: + string_conv: + return mrb_str_to_inum(mrb, val, base, TRUE); + + default: + break; + } + if (base != 0) { + tmp = mrb_check_string_type(mrb, val); + if (!mrb_nil_p(tmp)) { + val = tmp; + goto string_conv; + } +arg_error: + mrb_raise(mrb, E_ARGUMENT_ERROR, "base specified for non string value"); + } + tmp = convert_type(mrb, val, "Integer", "to_int", FALSE); + if (mrb_nil_p(tmp)) { + return mrb_to_integer(mrb, val, "to_i"); + } + return tmp; +} + +MRB_API mrb_value +mrb_Integer(mrb_state *mrb, mrb_value val) +{ + return mrb_convert_to_integer(mrb, val, 0); +} + +MRB_API mrb_value +mrb_Float(mrb_state *mrb, mrb_value val) +{ + if (mrb_nil_p(val)) { + mrb_raise(mrb, E_TYPE_ERROR, "can't convert nil into Float"); + } + switch (mrb_type(val)) { + case MRB_TT_FIXNUM: + return mrb_float_value(mrb, (mrb_float)mrb_fixnum(val)); + + case MRB_TT_FLOAT: + return val; + + case MRB_TT_STRING: + return mrb_float_value(mrb, mrb_str_to_dbl(mrb, val, TRUE)); + + default: + return mrb_convert_type(mrb, val, MRB_TT_FLOAT, "Float", "to_f"); + } +} + +MRB_API mrb_value +mrb_inspect(mrb_state *mrb, mrb_value obj) +{ + return mrb_obj_as_string(mrb, mrb_funcall(mrb, obj, "inspect", 0)); +} + +MRB_API mrb_bool +mrb_eql(mrb_state *mrb, mrb_value obj1, mrb_value obj2) +{ + if (mrb_obj_eq(mrb, obj1, obj2)) return TRUE; + return mrb_test(mrb_funcall(mrb, obj1, "eql?", 1, obj2)); +} diff --git a/web/server/h2o/libh2o/deps/mruby/src/opcode.h b/web/server/h2o/libh2o/deps/mruby/src/opcode.h new file mode 100644 index 00000000..fe4d17a2 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/src/opcode.h @@ -0,0 +1,2 @@ +/* this header file is to be removed soon. */ +#include diff --git a/web/server/h2o/libh2o/deps/mruby/src/pool.c b/web/server/h2o/libh2o/deps/mruby/src/pool.c new file mode 100644 index 00000000..db4546ab --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/src/pool.c @@ -0,0 +1,198 @@ +/* +** pool.c - memory pool +** +** See Copyright Notice in mruby.h +*/ + +#include +#include +#include +#include + +/* configuration section */ +/* allocated memory address should be multiple of POOL_ALIGNMENT */ +/* or undef it if alignment does not matter */ +#ifndef POOL_ALIGNMENT +#if INTPTR_MAX == INT64_MAX +#define POOL_ALIGNMENT 8 +#else +#define POOL_ALIGNMENT 4 +#endif +#endif +/* page size of memory pool */ +#ifndef POOL_PAGE_SIZE +#define POOL_PAGE_SIZE 16000 +#endif +/* end of configuration section */ + +struct mrb_pool_page { + struct mrb_pool_page *next; + size_t offset; + size_t len; + void *last; + char page[]; +}; + +struct mrb_pool { + mrb_state *mrb; + struct mrb_pool_page *pages; +}; + +#undef TEST_POOL +#ifdef TEST_POOL + +#define mrb_malloc_simple(m,s) malloc(s) +#define mrb_free(m,p) free(p) +#endif + +#ifdef POOL_ALIGNMENT +# define ALIGN_PADDING(x) ((SIZE_MAX - (x) + 1) & (POOL_ALIGNMENT - 1)) +#else +# define ALIGN_PADDING(x) (0) +#endif + +MRB_API mrb_pool* +mrb_pool_open(mrb_state *mrb) +{ + mrb_pool *pool = (mrb_pool *)mrb_malloc_simple(mrb, sizeof(mrb_pool)); + + if (pool) { + pool->mrb = mrb; + pool->pages = NULL; + } + + return pool; +} + +MRB_API void +mrb_pool_close(mrb_pool *pool) +{ + struct mrb_pool_page *page, *tmp; + + if (!pool) return; + page = pool->pages; + while (page) { + tmp = page; + page = page->next; + mrb_free(pool->mrb, tmp); + } + mrb_free(pool->mrb, pool); +} + +static struct mrb_pool_page* +page_alloc(mrb_pool *pool, size_t len) +{ + struct mrb_pool_page *page; + + if (len < POOL_PAGE_SIZE) + len = POOL_PAGE_SIZE; + page = (struct mrb_pool_page *)mrb_malloc_simple(pool->mrb, sizeof(struct mrb_pool_page)+len); + if (page) { + page->offset = 0; + page->len = len; + } + + return page; +} + +MRB_API void* +mrb_pool_alloc(mrb_pool *pool, size_t len) +{ + struct mrb_pool_page *page; + size_t n; + + if (!pool) return NULL; + len += ALIGN_PADDING(len); + page = pool->pages; + while (page) { + if (page->offset + len <= page->len) { + n = page->offset; + page->offset += len; + page->last = (char*)page->page+n; + return page->last; + } + page = page->next; + } + page = page_alloc(pool, len); + if (!page) return NULL; + page->offset = len; + page->next = pool->pages; + pool->pages = page; + + page->last = (void*)page->page; + return page->last; +} + +MRB_API mrb_bool +mrb_pool_can_realloc(mrb_pool *pool, void *p, size_t len) +{ + struct mrb_pool_page *page; + + if (!pool) return FALSE; + len += ALIGN_PADDING(len); + page = pool->pages; + while (page) { + if (page->last == p) { + size_t beg; + + beg = (char*)p - page->page; + if (beg + len > page->len) return FALSE; + return TRUE; + } + page = page->next; + } + return FALSE; +} + +MRB_API void* +mrb_pool_realloc(mrb_pool *pool, void *p, size_t oldlen, size_t newlen) +{ + struct mrb_pool_page *page; + void *np; + + if (!pool) return NULL; + oldlen += ALIGN_PADDING(oldlen); + newlen += ALIGN_PADDING(newlen); + page = pool->pages; + while (page) { + if (page->last == p) { + size_t beg; + + beg = (char*)p - page->page; + if (beg + oldlen != page->offset) break; + if (beg + newlen > page->len) { + page->offset = beg; + break; + } + page->offset = beg + newlen; + return p; + } + page = page->next; + } + np = mrb_pool_alloc(pool, newlen); + if (np == NULL) { + return NULL; + } + memcpy(np, p, oldlen); + return np; +} + +#ifdef TEST_POOL +int +main(void) +{ + int i, len = 250; + mrb_pool *pool; + void *p; + + pool = mrb_pool_open(NULL); + p = mrb_pool_alloc(pool, len); + for (i=1; i<20; i++) { + printf("%p (len=%d) %ud\n", p, len, mrb_pool_can_realloc(pool, p, len*2)); + p = mrb_pool_realloc(pool, p, len, len*2); + len *= 2; + } + mrb_pool_close(pool); + return 0; +} +#endif diff --git a/web/server/h2o/libh2o/deps/mruby/src/print.c b/web/server/h2o/libh2o/deps/mruby/src/print.c new file mode 100644 index 00000000..03b5eadf --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/src/print.c @@ -0,0 +1,47 @@ +/* +** print.c - Kernel.#p +** +** See Copyright Notice in mruby.h +*/ + +#include +#include +#include + +#ifndef MRB_DISABLE_STDIO +static void +printstr(mrb_value obj, FILE *stream) +{ + if (mrb_string_p(obj)) { + fwrite(RSTRING_PTR(obj), RSTRING_LEN(obj), 1, stream); + putc('\n', stream); + } +} +#else +# define printstr(obj, stream) (void)0 +#endif + +MRB_API void +mrb_p(mrb_state *mrb, mrb_value obj) +{ + printstr(mrb_inspect(mrb, obj), stdout); +} + +MRB_API void +mrb_print_error(mrb_state *mrb) +{ + mrb_print_backtrace(mrb); + printstr(mrb_funcall(mrb, mrb_obj_value(mrb->exc), "inspect", 0), stderr); +} + +MRB_API void +mrb_show_version(mrb_state *mrb) +{ + printstr(mrb_const_get(mrb, mrb_obj_value(mrb->object_class), mrb_intern_lit(mrb, "MRUBY_DESCRIPTION")), stdout); +} + +MRB_API void +mrb_show_copyright(mrb_state *mrb) +{ + printstr(mrb_const_get(mrb, mrb_obj_value(mrb->object_class), mrb_intern_lit(mrb, "MRUBY_COPYRIGHT")), stdout); +} diff --git a/web/server/h2o/libh2o/deps/mruby/src/proc.c b/web/server/h2o/libh2o/deps/mruby/src/proc.c new file mode 100644 index 00000000..10a2c4f3 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/src/proc.c @@ -0,0 +1,294 @@ +/* +** proc.c - Proc class +** +** See Copyright Notice in mruby.h +*/ + +#include +#include +#include +#include + +static mrb_code call_iseq[] = { + MKOP_A(OP_CALL, 0), +}; + +struct RProc* +mrb_proc_new(mrb_state *mrb, mrb_irep *irep) +{ + struct RProc *p; + mrb_callinfo *ci = mrb->c->ci; + + p = (struct RProc*)mrb_obj_alloc(mrb, MRB_TT_PROC, mrb->proc_class); + p->target_class = 0; + if (ci) { + if (ci->proc) + p->target_class = ci->proc->target_class; + if (!p->target_class) + p->target_class = ci->target_class; + } + p->body.irep = irep; + p->env = 0; + mrb_irep_incref(mrb, irep); + + return p; +} + +static struct REnv* +env_new(mrb_state *mrb, int nlocals) +{ + struct REnv *e; + + e = (struct REnv*)mrb_obj_alloc(mrb, MRB_TT_ENV, (struct RClass*)mrb->c->ci->proc->env); + MRB_SET_ENV_STACK_LEN(e, nlocals); + e->cxt.c = mrb->c; + e->cioff = mrb->c->ci - mrb->c->cibase; + e->stack = mrb->c->stack; + + return e; +} + +static void +closure_setup(mrb_state *mrb, struct RProc *p, int nlocals) +{ + struct REnv *e; + + if (!mrb->c->ci->env) { + e = env_new(mrb, nlocals); + mrb->c->ci->env = e; + } + else { + e = mrb->c->ci->env; + } + p->env = e; + mrb_field_write_barrier(mrb, (struct RBasic *)p, (struct RBasic *)p->env); +} + +struct RProc* +mrb_closure_new(mrb_state *mrb, mrb_irep *irep) +{ + struct RProc *p = mrb_proc_new(mrb, irep); + + closure_setup(mrb, p, mrb->c->ci->proc->body.irep->nlocals); + return p; +} + +MRB_API struct RProc* +mrb_proc_new_cfunc(mrb_state *mrb, mrb_func_t func) +{ + struct RProc *p; + + p = (struct RProc*)mrb_obj_alloc(mrb, MRB_TT_PROC, mrb->proc_class); + p->body.func = func; + p->flags |= MRB_PROC_CFUNC; + p->env = 0; + + return p; +} + +MRB_API struct RProc* +mrb_proc_new_cfunc_with_env(mrb_state *mrb, mrb_func_t func, mrb_int argc, const mrb_value *argv) +{ + struct RProc *p = mrb_proc_new_cfunc(mrb, func); + struct REnv *e; + int i; + + p->env = e = env_new(mrb, argc); + mrb_field_write_barrier(mrb, (struct RBasic *)p, (struct RBasic *)p->env); + MRB_ENV_UNSHARE_STACK(e); + e->stack = (mrb_value*)mrb_malloc(mrb, sizeof(mrb_value) * argc); + if (argv) { + for (i = 0; i < argc; ++i) { + e->stack[i] = argv[i]; + } + } + else { + for (i = 0; i < argc; ++i) { + SET_NIL_VALUE(e->stack[i]); + } + } + return p; +} + +MRB_API struct RProc* +mrb_closure_new_cfunc(mrb_state *mrb, mrb_func_t func, int nlocals) +{ + return mrb_proc_new_cfunc_with_env(mrb, func, nlocals, NULL); +} + +MRB_API mrb_value +mrb_proc_cfunc_env_get(mrb_state *mrb, mrb_int idx) +{ + struct RProc *p = mrb->c->ci->proc; + struct REnv *e = p->env; + + if (!MRB_PROC_CFUNC_P(p)) { + mrb_raise(mrb, E_TYPE_ERROR, "Can't get cfunc env from non-cfunc proc."); + } + if (!e) { + mrb_raise(mrb, E_TYPE_ERROR, "Can't get cfunc env from cfunc Proc without REnv."); + } + if (idx < 0 || MRB_ENV_STACK_LEN(e) <= idx) { + mrb_raisef(mrb, E_INDEX_ERROR, "Env index out of range: %S (expected: 0 <= index < %S)", + mrb_fixnum_value(idx), mrb_fixnum_value(MRB_ENV_STACK_LEN(e))); + } + + return e->stack[idx]; +} + +void +mrb_proc_copy(struct RProc *a, struct RProc *b) +{ + if (a->body.irep) { + /* already initialized proc */ + return; + } + a->flags = b->flags; + a->body = b->body; + if (!MRB_PROC_CFUNC_P(a) && a->body.irep) { + a->body.irep->refcnt++; + } + a->target_class = b->target_class; + a->env = b->env; +} + +static mrb_value +mrb_proc_s_new(mrb_state *mrb, mrb_value proc_class) +{ + mrb_value blk; + mrb_value proc; + struct RProc *p; + + mrb_get_args(mrb, "&", &blk); + if (mrb_nil_p(blk)) { + /* Calling Proc.new without a block is not implemented yet */ + mrb_raise(mrb, E_ARGUMENT_ERROR, "tried to create Proc object without a block"); + } + p = (struct RProc *)mrb_obj_alloc(mrb, MRB_TT_PROC, mrb_class_ptr(proc_class)); + mrb_proc_copy(p, mrb_proc_ptr(blk)); + proc = mrb_obj_value(p); + mrb_funcall_with_block(mrb, proc, mrb_intern_lit(mrb, "initialize"), 0, NULL, proc); + if (!MRB_PROC_STRICT_P(p) && + mrb->c->ci > mrb->c->cibase && p->env == mrb->c->ci[-1].env) { + p->flags |= MRB_PROC_ORPHAN; + } + return proc; +} + +static mrb_value +mrb_proc_init_copy(mrb_state *mrb, mrb_value self) +{ + mrb_value proc; + + mrb_get_args(mrb, "o", &proc); + if (mrb_type(proc) != MRB_TT_PROC) { + mrb_raise(mrb, E_ARGUMENT_ERROR, "not a proc"); + } + mrb_proc_copy(mrb_proc_ptr(self), mrb_proc_ptr(proc)); + return self; +} + +int +mrb_proc_cfunc_p(struct RProc *p) +{ + return MRB_PROC_CFUNC_P(p); +} + +mrb_value +mrb_proc_call_cfunc(mrb_state *mrb, struct RProc *p, mrb_value self) +{ + return (p->body.func)(mrb, self); +} + +/* 15.2.17.4.2 */ +static mrb_value +mrb_proc_arity(mrb_state *mrb, mrb_value self) +{ + struct RProc *p = mrb_proc_ptr(self); + struct mrb_irep *irep; + mrb_code *iseq; + mrb_aspec aspec; + int ma, op, ra, pa, arity; + + if (MRB_PROC_CFUNC_P(p)) { + /* TODO cfunc aspec not implemented yet */ + return mrb_fixnum_value(-1); + } + + irep = p->body.irep; + if (!irep) { + return mrb_fixnum_value(0); + } + + iseq = irep->iseq; + /* arity is depend on OP_ENTER */ + if (GET_OPCODE(*iseq) != OP_ENTER) { + return mrb_fixnum_value(0); + } + + aspec = GETARG_Ax(*iseq); + ma = MRB_ASPEC_REQ(aspec); + op = MRB_ASPEC_OPT(aspec); + ra = MRB_ASPEC_REST(aspec); + pa = MRB_ASPEC_POST(aspec); + arity = ra || (MRB_PROC_STRICT_P(p) && op) ? -(ma + pa + 1) : ma + pa; + + return mrb_fixnum_value(arity); +} + +/* 15.3.1.2.6 */ +/* 15.3.1.3.27 */ +/* + * call-seq: + * lambda { |...| block } -> a_proc + * + * Equivalent to Proc.new, except the resulting Proc objects + * check the number of parameters passed when called. + */ +static mrb_value +proc_lambda(mrb_state *mrb, mrb_value self) +{ + mrb_value blk; + struct RProc *p; + + mrb_get_args(mrb, "&", &blk); + if (mrb_nil_p(blk)) { + mrb_raise(mrb, E_ARGUMENT_ERROR, "tried to create Proc object without a block"); + } + if (mrb_type(blk) != MRB_TT_PROC) { + mrb_raise(mrb, E_ARGUMENT_ERROR, "not a proc"); + } + p = mrb_proc_ptr(blk); + if (!MRB_PROC_STRICT_P(p)) { + struct RProc *p2 = (struct RProc*)mrb_obj_alloc(mrb, MRB_TT_PROC, p->c); + mrb_proc_copy(p2, p); + p2->flags |= MRB_PROC_STRICT; + return mrb_obj_value(p2); + } + return blk; +} + +void +mrb_init_proc(mrb_state *mrb) +{ + struct RProc *m; + mrb_irep *call_irep = (mrb_irep *)mrb_malloc(mrb, sizeof(mrb_irep)); + static const mrb_irep mrb_irep_zero = { 0 }; + + *call_irep = mrb_irep_zero; + call_irep->flags = MRB_ISEQ_NO_FREE; + call_irep->iseq = call_iseq; + call_irep->ilen = 1; + call_irep->nregs = 2; /* receiver and block */ + + mrb_define_class_method(mrb, mrb->proc_class, "new", mrb_proc_s_new, MRB_ARGS_ANY()); + mrb_define_method(mrb, mrb->proc_class, "initialize_copy", mrb_proc_init_copy, MRB_ARGS_REQ(1)); + mrb_define_method(mrb, mrb->proc_class, "arity", mrb_proc_arity, MRB_ARGS_NONE()); + + m = mrb_proc_new(mrb, call_irep); + mrb_define_method_raw(mrb, mrb->proc_class, mrb_intern_lit(mrb, "call"), m); + mrb_define_method_raw(mrb, mrb->proc_class, mrb_intern_lit(mrb, "[]"), m); + + mrb_define_class_method(mrb, mrb->kernel_module, "lambda", proc_lambda, MRB_ARGS_NONE()); /* 15.3.1.2.6 */ + mrb_define_method(mrb, mrb->kernel_module, "lambda", proc_lambda, MRB_ARGS_NONE()); /* 15.3.1.3.27 */ +} diff --git a/web/server/h2o/libh2o/deps/mruby/src/range.c b/web/server/h2o/libh2o/deps/mruby/src/range.c new file mode 100644 index 00000000..eb9a9c61 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/src/range.c @@ -0,0 +1,442 @@ +/* +** range.c - Range class +** +** See Copyright Notice in mruby.h +*/ + +#include +#include +#include +#include +#include + +MRB_API struct RRange* +mrb_range_ptr(mrb_state *mrb, mrb_value v) +{ + struct RRange *r = (struct RRange*)mrb_ptr(v); + + if (r->edges == NULL) { + mrb_raise(mrb, E_ARGUMENT_ERROR, "uninitialized range"); + } + return r; +} + +static void +range_check(mrb_state *mrb, mrb_value a, mrb_value b) +{ + mrb_value ans; + enum mrb_vtype ta; + enum mrb_vtype tb; + + ta = mrb_type(a); + tb = mrb_type(b); + if ((ta == MRB_TT_FIXNUM || ta == MRB_TT_FLOAT) && + (tb == MRB_TT_FIXNUM || tb == MRB_TT_FLOAT)) { + return; + } + + ans = mrb_funcall(mrb, a, "<=>", 1, b); + if (mrb_nil_p(ans)) { + /* can not be compared */ + mrb_raise(mrb, E_ARGUMENT_ERROR, "bad value for range"); + } +} + +MRB_API mrb_value +mrb_range_new(mrb_state *mrb, mrb_value beg, mrb_value end, mrb_bool excl) +{ + struct RRange *r; + + range_check(mrb, beg, end); + r = (struct RRange*)mrb_obj_alloc(mrb, MRB_TT_RANGE, mrb->range_class); + r->edges = (mrb_range_edges *)mrb_malloc(mrb, sizeof(mrb_range_edges)); + r->edges->beg = beg; + r->edges->end = end; + r->excl = excl; + return mrb_range_value(r); +} + +/* + * call-seq: + * rng.first => obj + * rng.begin => obj + * + * Returns the first object in rng. + */ +mrb_value +mrb_range_beg(mrb_state *mrb, mrb_value range) +{ + struct RRange *r = mrb_range_ptr(mrb, range); + + return r->edges->beg; +} + +/* + * call-seq: + * rng.end => obj + * rng.last => obj + * + * Returns the object that defines the end of rng. + * + * (1..10).end #=> 10 + * (1...10).end #=> 10 + */ + +mrb_value +mrb_range_end(mrb_state *mrb, mrb_value range) +{ + struct RRange *r = mrb_range_ptr(mrb, range); + + return r->edges->end; +} + +/* + * call-seq: + * range.exclude_end? => true or false + * + * Returns true if range excludes its end value. + */ +mrb_value +mrb_range_excl(mrb_state *mrb, mrb_value range) +{ + struct RRange *r = mrb_range_ptr(mrb, range); + + return mrb_bool_value(r->excl); +} + +static void +range_init(mrb_state *mrb, mrb_value range, mrb_value beg, mrb_value end, mrb_bool exclude_end) +{ + struct RRange *r = mrb_range_raw_ptr(range); + + range_check(mrb, beg, end); + r->excl = exclude_end; + if (!r->edges) { + r->edges = (mrb_range_edges *)mrb_malloc(mrb, sizeof(mrb_range_edges)); + } + r->edges->beg = beg; + r->edges->end = end; +} +/* + * call-seq: + * Range.new(start, end, exclusive=false) => range + * + * Constructs a range using the given start and end. If the third + * parameter is omitted or is false, the range will include + * the end object; otherwise, it will be excluded. + */ + +mrb_value +mrb_range_initialize(mrb_state *mrb, mrb_value range) +{ + mrb_value beg, end; + mrb_bool exclusive; + int n; + + n = mrb_get_args(mrb, "oo|b", &beg, &end, &exclusive); + if (n != 3) { + exclusive = FALSE; + } + /* Ranges are immutable, so that they should be initialized only once. */ + if (mrb_range_raw_ptr(range)->edges) { + mrb_name_error(mrb, mrb_intern_lit(mrb, "initialize"), "`initialize' called twice"); + } + range_init(mrb, range, beg, end, exclusive); + return range; +} +/* + * call-seq: + * range == obj => true or false + * + * Returns true only if + * 1) obj is a Range, + * 2) obj has equivalent beginning and end items (by comparing them with ==), + * 3) obj has the same #exclude_end? setting as rng. + * + * (0..2) == (0..2) #=> true + * (0..2) == Range.new(0,2) #=> true + * (0..2) == (0...2) #=> false + * + */ + +mrb_value +mrb_range_eq(mrb_state *mrb, mrb_value range) +{ + struct RRange *rr; + struct RRange *ro; + mrb_value obj, v1, v2; + + mrb_get_args(mrb, "o", &obj); + + if (mrb_obj_equal(mrb, range, obj)) return mrb_true_value(); + if (!mrb_obj_is_instance_of(mrb, obj, mrb_obj_class(mrb, range))) { /* same class? */ + return mrb_false_value(); + } + + rr = mrb_range_ptr(mrb, range); + ro = mrb_range_ptr(mrb, obj); + v1 = mrb_funcall(mrb, rr->edges->beg, "==", 1, ro->edges->beg); + v2 = mrb_funcall(mrb, rr->edges->end, "==", 1, ro->edges->end); + if (!mrb_bool(v1) || !mrb_bool(v2) || rr->excl != ro->excl) { + return mrb_false_value(); + } + return mrb_true_value(); +} + +static mrb_bool +r_le(mrb_state *mrb, mrb_value a, mrb_value b) +{ + mrb_value r = mrb_funcall(mrb, a, "<=>", 1, b); /* compare result */ + /* output :a < b => -1, a = b => 0, a > b => +1 */ + + if (mrb_fixnum_p(r)) { + mrb_int c = mrb_fixnum(r); + if (c == 0 || c == -1) return TRUE; + } + + return FALSE; +} + +static mrb_bool +r_gt(mrb_state *mrb, mrb_value a, mrb_value b) +{ + mrb_value r = mrb_funcall(mrb, a, "<=>", 1, b); + /* output :a < b => -1, a = b => 0, a > b => +1 */ + + return mrb_fixnum_p(r) && mrb_fixnum(r) == 1; +} + +static mrb_bool +r_ge(mrb_state *mrb, mrb_value a, mrb_value b) +{ + mrb_value r = mrb_funcall(mrb, a, "<=>", 1, b); /* compare result */ + /* output :a < b => -1, a = b => 0, a > b => +1 */ + + if (mrb_fixnum_p(r)) { + mrb_int c = mrb_fixnum(r); + if (c == 0 || c == 1) return TRUE; + } + + return FALSE; +} + +/* + * call-seq: + * range === obj => true or false + * range.member?(val) => true or false + * range.include?(val) => true or false + * + */ +mrb_value +mrb_range_include(mrb_state *mrb, mrb_value range) +{ + mrb_value val; + struct RRange *r = mrb_range_ptr(mrb, range); + mrb_value beg, end; + mrb_bool include_p; + + mrb_get_args(mrb, "o", &val); + + beg = r->edges->beg; + end = r->edges->end; + include_p = r_le(mrb, beg, val) && /* beg <= val */ + (r->excl ? r_gt(mrb, end, val) /* end > val */ + : r_ge(mrb, end, val)); /* end >= val */ + + return mrb_bool_value(include_p); +} + +MRB_API mrb_int +mrb_range_beg_len(mrb_state *mrb, mrb_value range, mrb_int *begp, mrb_int *lenp, mrb_int len, mrb_bool trunc) +{ + mrb_int beg, end; + struct RRange *r; + + if (mrb_type(range) != MRB_TT_RANGE) return 0; + r = mrb_range_ptr(mrb, range); + + beg = mrb_int(mrb, r->edges->beg); + end = mrb_int(mrb, r->edges->end); + + if (beg < 0) { + beg += len; + if (beg < 0) return 2; + } + + if (trunc) { + if (beg > len) return 2; + if (end > len) end = len; + } + + if (end < 0) end += len; + if (!r->excl && (!trunc || end < len)) + end++; /* include end point */ + len = end - beg; + if (len < 0) len = 0; + + *begp = beg; + *lenp = len; + return 1; +} + +/* 15.2.14.4.12(x) */ +/* + * call-seq: + * rng.to_s -> string + * + * Convert this range object to a printable form. + */ + +static mrb_value +range_to_s(mrb_state *mrb, mrb_value range) +{ + mrb_value str, str2; + struct RRange *r = mrb_range_ptr(mrb, range); + + str = mrb_obj_as_string(mrb, r->edges->beg); + str2 = mrb_obj_as_string(mrb, r->edges->end); + str = mrb_str_dup(mrb, str); + mrb_str_cat(mrb, str, "...", r->excl ? 3 : 2); + mrb_str_cat_str(mrb, str, str2); + + return str; +} + +/* 15.2.14.4.13(x) */ +/* + * call-seq: + * rng.inspect -> string + * + * Convert this range object to a printable form (using + * inspect to convert the start and end + * objects). + */ + +static mrb_value +range_inspect(mrb_state *mrb, mrb_value range) +{ + mrb_value str, str2; + struct RRange *r = mrb_range_ptr(mrb, range); + + str = mrb_inspect(mrb, r->edges->beg); + str2 = mrb_inspect(mrb, r->edges->end); + str = mrb_str_dup(mrb, str); + mrb_str_cat(mrb, str, "...", r->excl ? 3 : 2); + mrb_str_cat_str(mrb, str, str2); + + return str; +} + +/* 15.2.14.4.14(x) */ +/* + * call-seq: + * rng.eql?(obj) -> true or false + * + * Returns true only if obj is a Range, has equivalent + * beginning and end items (by comparing them with #eql?), and has the same + * #exclude_end? setting as rng. + * + * (0..2).eql?(0..2) #=> true + * (0..2).eql?(Range.new(0,2)) #=> true + * (0..2).eql?(0...2) #=> false + * + */ + +static mrb_value +range_eql(mrb_state *mrb, mrb_value range) +{ + mrb_value obj; + struct RRange *r, *o; + + mrb_get_args(mrb, "o", &obj); + + if (mrb_obj_equal(mrb, range, obj)) return mrb_true_value(); + if (!mrb_obj_is_kind_of(mrb, obj, mrb->range_class)) { + return mrb_false_value(); + } + if (mrb_type(obj) != MRB_TT_RANGE) return mrb_false_value(); + + r = mrb_range_ptr(mrb, range); + o = mrb_range_ptr(mrb, obj); + if (!mrb_eql(mrb, r->edges->beg, o->edges->beg) || + !mrb_eql(mrb, r->edges->end, o->edges->end) || + (r->excl != o->excl)) { + return mrb_false_value(); + } + return mrb_true_value(); +} + +/* 15.2.14.4.15(x) */ +static mrb_value +range_initialize_copy(mrb_state *mrb, mrb_value copy) +{ + mrb_value src; + struct RRange *r; + + mrb_get_args(mrb, "o", &src); + + if (mrb_obj_equal(mrb, copy, src)) return copy; + if (!mrb_obj_is_instance_of(mrb, src, mrb_obj_class(mrb, copy))) { + mrb_raise(mrb, E_TYPE_ERROR, "wrong argument class"); + } + + r = mrb_range_ptr(mrb, src); + range_init(mrb, copy, r->edges->beg, r->edges->end, r->excl); + + return copy; +} + +mrb_value +mrb_get_values_at(mrb_state *mrb, mrb_value obj, mrb_int olen, mrb_int argc, const mrb_value *argv, mrb_value (*func)(mrb_state*, mrb_value, mrb_int)) +{ + mrb_int i, j, beg, len; + mrb_value result; + result = mrb_ary_new(mrb); + + for (i = 0; i < argc; ++i) { + if (mrb_fixnum_p(argv[i])) { + mrb_ary_push(mrb, result, func(mrb, obj, mrb_fixnum(argv[i]))); + } + else if (mrb_range_beg_len(mrb, argv[i], &beg, &len, olen, FALSE) == 1) { + mrb_int const end = olen < beg + len ? olen : beg + len; + for (j = beg; j < end; ++j) { + mrb_ary_push(mrb, result, func(mrb, obj, j)); + } + + for (; j < beg + len; ++j) { + mrb_ary_push(mrb, result, mrb_nil_value()); + } + } + else { + mrb_raisef(mrb, E_TYPE_ERROR, "invalid values selector: %S", argv[i]); + } + } + + return result; +} + +void +mrb_init_range(mrb_state *mrb) +{ + struct RClass *r; + + r = mrb_define_class(mrb, "Range", mrb->object_class); /* 15.2.14 */ + mrb->range_class = r; + MRB_SET_INSTANCE_TT(r, MRB_TT_RANGE); + + mrb_define_method(mrb, r, "begin", mrb_range_beg, MRB_ARGS_NONE()); /* 15.2.14.4.3 */ + mrb_define_method(mrb, r, "end", mrb_range_end, MRB_ARGS_NONE()); /* 15.2.14.4.5 */ + mrb_define_method(mrb, r, "==", mrb_range_eq, MRB_ARGS_REQ(1)); /* 15.2.14.4.1 */ + mrb_define_method(mrb, r, "===", mrb_range_include, MRB_ARGS_REQ(1)); /* 15.2.14.4.2 */ + mrb_define_method(mrb, r, "exclude_end?", mrb_range_excl, MRB_ARGS_NONE()); /* 15.2.14.4.6 */ + mrb_define_method(mrb, r, "first", mrb_range_beg, MRB_ARGS_NONE()); /* 15.2.14.4.7 */ + mrb_define_method(mrb, r, "include?", mrb_range_include, MRB_ARGS_REQ(1)); /* 15.2.14.4.8 */ + mrb_define_method(mrb, r, "initialize", mrb_range_initialize, MRB_ARGS_ANY()); /* 15.2.14.4.9 */ + mrb_define_method(mrb, r, "last", mrb_range_end, MRB_ARGS_NONE()); /* 15.2.14.4.10 */ + mrb_define_method(mrb, r, "member?", mrb_range_include, MRB_ARGS_REQ(1)); /* 15.2.14.4.11 */ + + mrb_define_method(mrb, r, "to_s", range_to_s, MRB_ARGS_NONE()); /* 15.2.14.4.12(x) */ + mrb_define_method(mrb, r, "inspect", range_inspect, MRB_ARGS_NONE()); /* 15.2.14.4.13(x) */ + mrb_define_method(mrb, r, "eql?", range_eql, MRB_ARGS_REQ(1)); /* 15.2.14.4.14(x) */ + mrb_define_method(mrb, r, "initialize_copy", range_initialize_copy, MRB_ARGS_REQ(1)); /* 15.2.14.4.15(x) */ +} diff --git a/web/server/h2o/libh2o/deps/mruby/src/state.c b/web/server/h2o/libh2o/deps/mruby/src/state.c new file mode 100644 index 00000000..039d67d5 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/src/state.c @@ -0,0 +1,303 @@ +/* +** state.c - mrb_state open/close functions +** +** See Copyright Notice in mruby.h +*/ + +#include +#include +#include +#include +#include +#include +#include + +void mrb_init_core(mrb_state*); +void mrb_init_mrbgems(mrb_state*); + +void mrb_gc_init(mrb_state*, mrb_gc *gc); +void mrb_gc_destroy(mrb_state*, mrb_gc *gc); + +static mrb_value +inspect_main(mrb_state *mrb, mrb_value mod) +{ + return mrb_str_new_lit(mrb, "main"); +} + +MRB_API mrb_state* +mrb_open_core(mrb_allocf f, void *ud) +{ + static const mrb_state mrb_state_zero = { 0 }; + static const struct mrb_context mrb_context_zero = { 0 }; + mrb_state *mrb; + + mrb = (mrb_state *)(f)(NULL, NULL, sizeof(mrb_state), ud); + if (mrb == NULL) return NULL; + + *mrb = mrb_state_zero; + mrb->allocf_ud = ud; + mrb->allocf = f; + mrb->atexit_stack_len = 0; + + mrb_gc_init(mrb, &mrb->gc); + mrb->c = (struct mrb_context*)mrb_malloc(mrb, sizeof(struct mrb_context)); + *mrb->c = mrb_context_zero; + mrb->root_c = mrb->c; + + mrb_init_core(mrb); + + return mrb; +} + +void* +mrb_default_allocf(mrb_state *mrb, void *p, size_t size, void *ud) +{ + if (size == 0) { + free(p); + return NULL; + } + else { + return realloc(p, size); + } +} + +struct alloca_header { + struct alloca_header *next; + char buf[]; +}; + +MRB_API void* +mrb_alloca(mrb_state *mrb, size_t size) +{ + struct alloca_header *p; + + p = (struct alloca_header*) mrb_malloc(mrb, sizeof(struct alloca_header)+size); + p->next = mrb->mems; + mrb->mems = p; + return (void*)p->buf; +} + +static void +mrb_alloca_free(mrb_state *mrb) +{ + struct alloca_header *p; + struct alloca_header *tmp; + + if (mrb == NULL) return; + p = mrb->mems; + + while (p) { + tmp = p; + p = p->next; + mrb_free(mrb, tmp); + } +} + +MRB_API mrb_state* +mrb_open(void) +{ + mrb_state *mrb = mrb_open_allocf(mrb_default_allocf, NULL); + + return mrb; +} + +MRB_API mrb_state* +mrb_open_allocf(mrb_allocf f, void *ud) +{ + mrb_state *mrb = mrb_open_core(f, ud); + + if (mrb == NULL) { + return NULL; + } + +#ifndef DISABLE_GEMS + mrb_init_mrbgems(mrb); + mrb_gc_arena_restore(mrb, 0); +#endif + return mrb; +} + +void mrb_free_symtbl(mrb_state *mrb); + +void +mrb_irep_incref(mrb_state *mrb, mrb_irep *irep) +{ + irep->refcnt++; +} + +void +mrb_irep_decref(mrb_state *mrb, mrb_irep *irep) +{ + irep->refcnt--; + if (irep->refcnt == 0) { + mrb_irep_free(mrb, irep); + } +} + +void +mrb_irep_free(mrb_state *mrb, mrb_irep *irep) +{ + int i; + + if (!(irep->flags & MRB_ISEQ_NO_FREE)) + mrb_free(mrb, irep->iseq); + if (irep->pool) for (i=0; iplen; i++) { + if (mrb_type(irep->pool[i]) == MRB_TT_STRING) { + mrb_gc_free_str(mrb, RSTRING(irep->pool[i])); + mrb_free(mrb, mrb_obj_ptr(irep->pool[i])); + } +#ifdef MRB_WORD_BOXING + else if (mrb_type(irep->pool[i]) == MRB_TT_FLOAT) { + mrb_free(mrb, mrb_obj_ptr(irep->pool[i])); + } +#endif + } + mrb_free(mrb, irep->pool); + mrb_free(mrb, irep->syms); + for (i=0; irlen; i++) { + mrb_irep_decref(mrb, irep->reps[i]); + } + if (irep->outer) + mrb_irep_decref(mrb, irep->outer); + mrb_free(mrb, irep->reps); + mrb_free(mrb, irep->lv); + if (irep->own_filename) { + mrb_free(mrb, (void *)irep->filename); + } + mrb_free(mrb, irep->lines); + mrb_debug_info_free(mrb, irep->debug_info); + mrb_free(mrb, irep); +} + +mrb_value +mrb_str_pool(mrb_state *mrb, mrb_value str) +{ + struct RString *s = mrb_str_ptr(str); + struct RString *ns; + char *ptr; + mrb_int len; + + ns = (struct RString *)mrb_malloc(mrb, sizeof(struct RString)); + ns->tt = MRB_TT_STRING; + ns->c = mrb->string_class; + + if (RSTR_NOFREE_P(s)) { + ns->flags = MRB_STR_NOFREE; + ns->as.heap.ptr = s->as.heap.ptr; + ns->as.heap.len = s->as.heap.len; + ns->as.heap.aux.capa = 0; + } + else { + ns->flags = 0; + if (RSTR_EMBED_P(s)) { + ptr = s->as.ary; + len = RSTR_EMBED_LEN(s); + } + else { + ptr = s->as.heap.ptr; + len = s->as.heap.len; + } + + if (len < RSTRING_EMBED_LEN_MAX) { + RSTR_SET_EMBED_FLAG(ns); + RSTR_SET_EMBED_LEN(ns, len); + if (ptr) { + memcpy(ns->as.ary, ptr, len); + } + ns->as.ary[len] = '\0'; + } + else { + ns->as.heap.ptr = (char *)mrb_malloc(mrb, (size_t)len+1); + ns->as.heap.len = len; + ns->as.heap.aux.capa = len; + if (ptr) { + memcpy(ns->as.heap.ptr, ptr, len); + } + ns->as.heap.ptr[len] = '\0'; + } + } + return mrb_obj_value(ns); +} + +void mrb_free_backtrace(mrb_state *mrb); + +MRB_API void +mrb_free_context(mrb_state *mrb, struct mrb_context *c) +{ + if (!c) return; + mrb_free(mrb, c->stbase); + mrb_free(mrb, c->cibase); + mrb_free(mrb, c->rescue); + mrb_free(mrb, c->ensure); + mrb_free(mrb, c); +} + +MRB_API void +mrb_close(mrb_state *mrb) +{ + if (!mrb) return; + if (mrb->atexit_stack_len > 0) { + mrb_int i; + for (i = mrb->atexit_stack_len; i > 0; --i) { + mrb->atexit_stack[i - 1](mrb); + } +#ifndef MRB_FIXED_STATE_ATEXIT_STACK + mrb_free(mrb, mrb->atexit_stack); +#endif + } + + /* free */ + mrb_gc_free_gv(mrb); + mrb_free_context(mrb, mrb->root_c); + mrb_free_symtbl(mrb); + mrb_alloca_free(mrb); + mrb_gc_destroy(mrb, &mrb->gc); + mrb_free(mrb, mrb); +} + +MRB_API mrb_irep* +mrb_add_irep(mrb_state *mrb) +{ + static const mrb_irep mrb_irep_zero = { 0 }; + mrb_irep *irep; + + irep = (mrb_irep *)mrb_malloc(mrb, sizeof(mrb_irep)); + *irep = mrb_irep_zero; + irep->refcnt = 1; + irep->own_filename = FALSE; + + return irep; +} + +MRB_API mrb_value +mrb_top_self(mrb_state *mrb) +{ + if (!mrb->top_self) { + mrb->top_self = (struct RObject*)mrb_obj_alloc(mrb, MRB_TT_OBJECT, mrb->object_class); + mrb_define_singleton_method(mrb, mrb->top_self, "inspect", inspect_main, MRB_ARGS_NONE()); + mrb_define_singleton_method(mrb, mrb->top_self, "to_s", inspect_main, MRB_ARGS_NONE()); + } + return mrb_obj_value(mrb->top_self); +} + +MRB_API void +mrb_state_atexit(mrb_state *mrb, mrb_atexit_func f) +{ +#ifdef MRB_FIXED_STATE_ATEXIT_STACK + if (mrb->atexit_stack_len + 1 > MRB_FIXED_STATE_ATEXIT_STACK_SIZE) { + mrb_raise(mrb, E_RUNTIME_ERROR, "exceeded fixed state atexit stack limit"); + } +#else + size_t stack_size; + + stack_size = sizeof(mrb_atexit_func) * (mrb->atexit_stack_len + 1); + if (mrb->atexit_stack_len == 0) { + mrb->atexit_stack = (mrb_atexit_func*)mrb_malloc(mrb, stack_size); + } + else { + mrb->atexit_stack = (mrb_atexit_func*)mrb_realloc(mrb, mrb->atexit_stack, stack_size); + } +#endif + + mrb->atexit_stack[mrb->atexit_stack_len++] = f; +} diff --git a/web/server/h2o/libh2o/deps/mruby/src/string.c b/web/server/h2o/libh2o/deps/mruby/src/string.c new file mode 100644 index 00000000..01d706fa --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/src/string.c @@ -0,0 +1,3013 @@ +/* +** string.c - String class +** +** See Copyright Notice in mruby.h +*/ + +#ifdef _MSC_VER +# define _CRT_NONSTDC_NO_DEPRECATE +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +typedef struct mrb_shared_string { + mrb_bool nofree : 1; + int refcnt; + char *ptr; + mrb_int len; +} mrb_shared_string; + +const char mrb_digitmap[] = "0123456789abcdefghijklmnopqrstuvwxyz"; + +#define mrb_obj_alloc_string(mrb) ((struct RString*)mrb_obj_alloc((mrb), MRB_TT_STRING, (mrb)->string_class)) + +static struct RString* +str_new_static(mrb_state *mrb, const char *p, size_t len) +{ + struct RString *s; + + if (len >= MRB_INT_MAX) { + mrb_raise(mrb, E_ARGUMENT_ERROR, "string size too big"); + } + s = mrb_obj_alloc_string(mrb); + s->as.heap.len = (mrb_int)len; + s->as.heap.aux.capa = 0; /* nofree */ + s->as.heap.ptr = (char *)p; + s->flags = MRB_STR_NOFREE; + + return s; +} + +static struct RString* +str_new(mrb_state *mrb, const char *p, size_t len) +{ + struct RString *s; + + if (p && mrb_ro_data_p(p)) { + return str_new_static(mrb, p, len); + } + s = mrb_obj_alloc_string(mrb); + if (len < RSTRING_EMBED_LEN_MAX) { + RSTR_SET_EMBED_FLAG(s); + RSTR_SET_EMBED_LEN(s, len); + if (p) { + memcpy(s->as.ary, p, len); + } + } + else { + if (len >= MRB_INT_MAX) { + mrb_raise(mrb, E_ARGUMENT_ERROR, "string size too big"); + } + s->as.heap.len = (mrb_int)len; + s->as.heap.aux.capa = (mrb_int)len; + s->as.heap.ptr = (char *)mrb_malloc(mrb, len+1); + if (p) { + memcpy(s->as.heap.ptr, p, len); + } + } + RSTR_PTR(s)[len] = '\0'; + return s; +} + +static inline void +str_with_class(mrb_state *mrb, struct RString *s, mrb_value obj) +{ + s->c = mrb_str_ptr(obj)->c; +} + +static mrb_value +mrb_str_new_empty(mrb_state *mrb, mrb_value str) +{ + struct RString *s = str_new(mrb, 0, 0); + + str_with_class(mrb, s, str); + return mrb_obj_value(s); +} + +MRB_API mrb_value +mrb_str_new_capa(mrb_state *mrb, size_t capa) +{ + struct RString *s; + + s = mrb_obj_alloc_string(mrb); + + if (capa >= MRB_INT_MAX) { + mrb_raise(mrb, E_ARGUMENT_ERROR, "string capacity size too big"); + } + s->as.heap.len = 0; + s->as.heap.aux.capa = (mrb_int)capa; + s->as.heap.ptr = (char *)mrb_malloc(mrb, capa+1); + RSTR_PTR(s)[0] = '\0'; + + return mrb_obj_value(s); +} + +#ifndef MRB_STR_BUF_MIN_SIZE +# define MRB_STR_BUF_MIN_SIZE 128 +#endif + +MRB_API mrb_value +mrb_str_buf_new(mrb_state *mrb, size_t capa) +{ + if (capa < MRB_STR_BUF_MIN_SIZE) { + capa = MRB_STR_BUF_MIN_SIZE; + } + return mrb_str_new_capa(mrb, capa); +} + +static void +resize_capa(mrb_state *mrb, struct RString *s, size_t capacity) +{ +#if SIZE_MAX > MRB_INT_MAX + mrb_assert(capacity < MRB_INT_MAX); +#endif + if (RSTR_EMBED_P(s)) { + if (RSTRING_EMBED_LEN_MAX < capacity) { + char *const tmp = (char *)mrb_malloc(mrb, capacity+1); + const mrb_int len = RSTR_EMBED_LEN(s); + memcpy(tmp, s->as.ary, len); + RSTR_UNSET_EMBED_FLAG(s); + s->as.heap.ptr = tmp; + s->as.heap.len = len; + s->as.heap.aux.capa = (mrb_int)capacity; + } + } + else { + s->as.heap.ptr = (char*)mrb_realloc(mrb, RSTR_PTR(s), capacity+1); + s->as.heap.aux.capa = (mrb_int)capacity; + } +} + +MRB_API mrb_value +mrb_str_new(mrb_state *mrb, const char *p, size_t len) +{ + return mrb_obj_value(str_new(mrb, p, len)); +} + +/* + * call-seq: (Caution! NULL string) + * String.new(str="") => new_str + * + * Returns a new string object containing a copy of str. + */ + +MRB_API mrb_value +mrb_str_new_cstr(mrb_state *mrb, const char *p) +{ + struct RString *s; + size_t len; + + if (p) { + len = strlen(p); + } + else { + len = 0; + } + + s = str_new(mrb, p, len); + + return mrb_obj_value(s); +} + +MRB_API mrb_value +mrb_str_new_static(mrb_state *mrb, const char *p, size_t len) +{ + struct RString *s = str_new_static(mrb, p, len); + return mrb_obj_value(s); +} + +static void +str_decref(mrb_state *mrb, mrb_shared_string *shared) +{ + shared->refcnt--; + if (shared->refcnt == 0) { + if (!shared->nofree) { + mrb_free(mrb, shared->ptr); + } + mrb_free(mrb, shared); + } +} + +void +mrb_gc_free_str(mrb_state *mrb, struct RString *str) +{ + if (RSTR_EMBED_P(str)) + /* no code */; + else if (RSTR_SHARED_P(str)) + str_decref(mrb, str->as.heap.aux.shared); + else if (!RSTR_NOFREE_P(str)) + mrb_free(mrb, str->as.heap.ptr); +} + +#ifdef MRB_UTF8_STRING +static const char utf8len_codepage[256] = +{ + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, + 3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,1,1,1,1,1,1,1,1,1,1,1, +}; + +static mrb_int +utf8len(const char* p, const char* e) +{ + mrb_int len; + mrb_int i; + + len = utf8len_codepage[(unsigned char)*p]; + if (p + len > e) return 1; + for (i = 1; i < len; ++i) + if ((p[i] & 0xc0) != 0x80) + return 1; + return len; +} + +static mrb_int +utf8_strlen(mrb_value str, mrb_int len) +{ + mrb_int total = 0; + char* p = RSTRING_PTR(str); + char* e = p; + if (RSTRING(str)->flags & MRB_STR_NO_UTF) { + return RSTRING_LEN(str); + } + e += len < 0 ? RSTRING_LEN(str) : len; + while (pflags |= MRB_STR_NO_UTF; + } + return total; +} + +#define RSTRING_CHAR_LEN(s) utf8_strlen(s, -1) + +/* map character index to byte offset index */ +static mrb_int +chars2bytes(mrb_value s, mrb_int off, mrb_int idx) +{ + mrb_int i, b, n; + const char *p = RSTRING_PTR(s) + off; + const char *e = RSTRING_END(s); + + for (b=i=0; p n) return -1; + else if (m == n) { + return memcmp(x0, y0, m) == 0 ? 0 : -1; + } + else if (m < 1) { + return 0; + } + else if (m == 1) { + const unsigned char *ys = (const unsigned char *)memchr(y, *x, n); + + if (ys) + return (mrb_int)(ys - y); + else + return -1; + } + return mrb_memsearch_qs((const unsigned char *)x0, m, (const unsigned char *)y0, n); +} + +static void +str_make_shared(mrb_state *mrb, struct RString *s) +{ + if (!RSTR_SHARED_P(s)) { + mrb_shared_string *shared = (mrb_shared_string *)mrb_malloc(mrb, sizeof(mrb_shared_string)); + + shared->refcnt = 1; + if (RSTR_EMBED_P(s)) { + const mrb_int len = RSTR_EMBED_LEN(s); + char *const tmp = (char *)mrb_malloc(mrb, len+1); + memcpy(tmp, s->as.ary, len); + tmp[len] = '\0'; + RSTR_UNSET_EMBED_FLAG(s); + s->as.heap.ptr = tmp; + s->as.heap.len = len; + shared->nofree = FALSE; + shared->ptr = s->as.heap.ptr; + } + else if (RSTR_NOFREE_P(s)) { + shared->nofree = TRUE; + shared->ptr = s->as.heap.ptr; + RSTR_UNSET_NOFREE_FLAG(s); + } + else { + shared->nofree = FALSE; + if (s->as.heap.aux.capa > s->as.heap.len) { + s->as.heap.ptr = shared->ptr = (char *)mrb_realloc(mrb, s->as.heap.ptr, s->as.heap.len+1); + } + else { + shared->ptr = s->as.heap.ptr; + } + } + shared->len = s->as.heap.len; + s->as.heap.aux.shared = shared; + RSTR_SET_SHARED_FLAG(s); + } +} + +static mrb_value +byte_subseq(mrb_state *mrb, mrb_value str, mrb_int beg, mrb_int len) +{ + struct RString *orig, *s; + mrb_shared_string *shared; + + orig = mrb_str_ptr(str); + if (RSTR_EMBED_P(orig) || RSTR_LEN(orig) == 0) { + s = str_new(mrb, orig->as.ary+beg, len); + } + else { + str_make_shared(mrb, orig); + shared = orig->as.heap.aux.shared; + s = mrb_obj_alloc_string(mrb); + s->as.heap.ptr = orig->as.heap.ptr + beg; + s->as.heap.len = len; + s->as.heap.aux.shared = shared; + RSTR_SET_SHARED_FLAG(s); + shared->refcnt++; + } + + return mrb_obj_value(s); +} +#ifdef MRB_UTF8_STRING +static inline mrb_value +str_subseq(mrb_state *mrb, mrb_value str, mrb_int beg, mrb_int len) +{ + beg = chars2bytes(str, 0, beg); + len = chars2bytes(str, beg, len); + + return byte_subseq(mrb, str, beg, len); +} +#else +#define str_subseq(mrb, str, beg, len) byte_subseq(mrb, str, beg, len) +#endif + +static mrb_value +str_substr(mrb_state *mrb, mrb_value str, mrb_int beg, mrb_int len) +{ + mrb_int clen = RSTRING_CHAR_LEN(str); + + if (len < 0) return mrb_nil_value(); + if (clen == 0) { + len = 0; + } + else if (beg < 0) { + beg = clen + beg; + } + if (beg > clen) return mrb_nil_value(); + if (beg < 0) { + beg += clen; + if (beg < 0) return mrb_nil_value(); + } + if (len > clen - beg) + len = clen - beg; + if (len <= 0) { + len = 0; + } + return str_subseq(mrb, str, beg, len); +} + +MRB_API mrb_int +mrb_str_index(mrb_state *mrb, mrb_value str, const char *sptr, mrb_int slen, mrb_int offset) +{ + mrb_int pos; + char *s; + mrb_int len; + + len = RSTRING_LEN(str); + if (offset < 0) { + offset += len; + if (offset < 0) return -1; + } + if (len - offset < slen) return -1; + s = RSTRING_PTR(str); + if (offset) { + s += offset; + } + if (slen == 0) return offset; + /* need proceed one character at a time */ + len = RSTRING_LEN(str) - offset; + pos = mrb_memsearch(sptr, slen, s, len); + if (pos < 0) return pos; + return pos + offset; +} + +static mrb_int +str_index_str(mrb_state *mrb, mrb_value str, mrb_value str2, mrb_int offset) +{ + const char *ptr; + mrb_int len; + + ptr = RSTRING_PTR(str2); + len = RSTRING_LEN(str2); + + return mrb_str_index(mrb, str, ptr, len, offset); +} + +static void +check_frozen(mrb_state *mrb, struct RString *s) +{ + if (MRB_FROZEN_P(s)) { + mrb_raise(mrb, E_RUNTIME_ERROR, "can't modify frozen string"); + } +} + +static mrb_value +str_replace(mrb_state *mrb, struct RString *s1, struct RString *s2) +{ + long len; + + check_frozen(mrb, s1); + if (s1 == s2) return mrb_obj_value(s1); + s1->flags &= ~MRB_STR_NO_UTF; + s1->flags |= s2->flags&MRB_STR_NO_UTF; + len = RSTR_LEN(s2); + if (RSTR_SHARED_P(s1)) { + str_decref(mrb, s1->as.heap.aux.shared); + } + else if (!RSTR_EMBED_P(s1) && !RSTR_NOFREE_P(s1)) { + mrb_free(mrb, s1->as.heap.ptr); + } + + RSTR_UNSET_NOFREE_FLAG(s1); + + if (RSTR_SHARED_P(s2)) { +L_SHARE: + RSTR_UNSET_EMBED_FLAG(s1); + s1->as.heap.ptr = s2->as.heap.ptr; + s1->as.heap.len = len; + s1->as.heap.aux.shared = s2->as.heap.aux.shared; + RSTR_SET_SHARED_FLAG(s1); + s1->as.heap.aux.shared->refcnt++; + } + else { + if (len <= RSTRING_EMBED_LEN_MAX) { + RSTR_UNSET_SHARED_FLAG(s1); + RSTR_SET_EMBED_FLAG(s1); + memcpy(s1->as.ary, RSTR_PTR(s2), len); + RSTR_SET_EMBED_LEN(s1, len); + } + else { + str_make_shared(mrb, s2); + goto L_SHARE; + } + } + + return mrb_obj_value(s1); +} + +static mrb_int +str_rindex(mrb_state *mrb, mrb_value str, mrb_value sub, mrb_int pos) +{ + char *s, *sbeg, *t; + struct RString *ps = mrb_str_ptr(str); + mrb_int len = RSTRING_LEN(sub); + + /* substring longer than string */ + if (RSTR_LEN(ps) < len) return -1; + if (RSTR_LEN(ps) - pos < len) { + pos = RSTR_LEN(ps) - len; + } + sbeg = RSTR_PTR(ps); + s = RSTR_PTR(ps) + pos; + t = RSTRING_PTR(sub); + if (len) { + while (sbeg <= s) { + if (memcmp(s, t, len) == 0) { + return (mrb_int)(s - RSTR_PTR(ps)); + } + s--; + } + return -1; + } + else { + return pos; + } +} + +MRB_API mrb_int +mrb_str_strlen(mrb_state *mrb, struct RString *s) +{ + mrb_int i, max = RSTR_LEN(s); + char *p = RSTR_PTR(s); + + if (!p) return 0; + for (i=0; i + +char* +mrb_utf8_from_locale(const char *str, int len) +{ + wchar_t* wcsp; + char* mbsp; + int mbssize, wcssize; + + if (len == 0) + return strdup(""); + if (len == -1) + len = (int)strlen(str); + wcssize = MultiByteToWideChar(GetACP(), 0, str, len, NULL, 0); + wcsp = (wchar_t*) malloc((wcssize + 1) * sizeof(wchar_t)); + if (!wcsp) + return NULL; + wcssize = MultiByteToWideChar(GetACP(), 0, str, len, wcsp, wcssize + 1); + wcsp[wcssize] = 0; + + mbssize = WideCharToMultiByte(CP_UTF8, 0, (LPCWSTR) wcsp, -1, NULL, 0, NULL, NULL); + mbsp = (char*) malloc((mbssize + 1)); + if (!mbsp) { + free(wcsp); + return NULL; + } + mbssize = WideCharToMultiByte(CP_UTF8, 0, (LPCWSTR) wcsp, -1, mbsp, mbssize, NULL, NULL); + mbsp[mbssize] = 0; + free(wcsp); + return mbsp; +} + +char* +mrb_locale_from_utf8(const char *utf8, int len) +{ + wchar_t* wcsp; + char* mbsp; + int mbssize, wcssize; + + if (len == 0) + return strdup(""); + if (len == -1) + len = (int)strlen(utf8); + wcssize = MultiByteToWideChar(CP_UTF8, 0, utf8, len, NULL, 0); + wcsp = (wchar_t*) malloc((wcssize + 1) * sizeof(wchar_t)); + if (!wcsp) + return NULL; + wcssize = MultiByteToWideChar(CP_UTF8, 0, utf8, len, wcsp, wcssize + 1); + wcsp[wcssize] = 0; + mbssize = WideCharToMultiByte(GetACP(), 0, (LPCWSTR) wcsp, -1, NULL, 0, NULL, NULL); + mbsp = (char*) malloc((mbssize + 1)); + if (!mbsp) { + free(wcsp); + return NULL; + } + mbssize = WideCharToMultiByte(GetACP(), 0, (LPCWSTR) wcsp, -1, mbsp, mbssize, NULL, NULL); + mbsp[mbssize] = 0; + free(wcsp); + return mbsp; +} +#endif + +MRB_API void +mrb_str_modify(mrb_state *mrb, struct RString *s) +{ + check_frozen(mrb, s); + s->flags &= ~MRB_STR_NO_UTF; + if (RSTR_SHARED_P(s)) { + mrb_shared_string *shared = s->as.heap.aux.shared; + + if (shared->nofree == 0 && shared->refcnt == 1 && s->as.heap.ptr == shared->ptr) { + s->as.heap.ptr = shared->ptr; + s->as.heap.aux.capa = shared->len; + RSTR_PTR(s)[s->as.heap.len] = '\0'; + mrb_free(mrb, shared); + } + else { + char *ptr, *p; + mrb_int len; + + p = RSTR_PTR(s); + len = s->as.heap.len; + if (len < RSTRING_EMBED_LEN_MAX) { + RSTR_SET_EMBED_FLAG(s); + RSTR_SET_EMBED_LEN(s, len); + ptr = RSTR_PTR(s); + } + else { + ptr = (char *)mrb_malloc(mrb, (size_t)len + 1); + s->as.heap.ptr = ptr; + s->as.heap.aux.capa = len; + } + if (p) { + memcpy(ptr, p, len); + } + ptr[len] = '\0'; + str_decref(mrb, shared); + } + RSTR_UNSET_SHARED_FLAG(s); + return; + } + if (RSTR_NOFREE_P(s)) { + char *p = s->as.heap.ptr; + mrb_int len = s->as.heap.len; + + RSTR_UNSET_NOFREE_FLAG(s); + if (len < RSTRING_EMBED_LEN_MAX) { + RSTR_SET_EMBED_FLAG(s); + RSTR_SET_EMBED_LEN(s, len); + } + else { + s->as.heap.ptr = (char *)mrb_malloc(mrb, (size_t)len+1); + s->as.heap.aux.capa = len; + } + if (p) { + memcpy(RSTR_PTR(s), p, len); + } + RSTR_PTR(s)[len] = '\0'; + return; + } +} + +MRB_API mrb_value +mrb_str_resize(mrb_state *mrb, mrb_value str, mrb_int len) +{ + mrb_int slen; + struct RString *s = mrb_str_ptr(str); + + mrb_str_modify(mrb, s); + slen = RSTR_LEN(s); + if (len != slen) { + if (slen < len || slen - len > 256) { + resize_capa(mrb, s, len); + } + RSTR_SET_LEN(s, len); + RSTR_PTR(s)[len] = '\0'; /* sentinel */ + } + return str; +} + +MRB_API char* +mrb_str_to_cstr(mrb_state *mrb, mrb_value str0) +{ + struct RString *s; + + if (!mrb_string_p(str0)) { + mrb_raise(mrb, E_TYPE_ERROR, "expected String"); + } + + s = str_new(mrb, RSTRING_PTR(str0), RSTRING_LEN(str0)); + if ((strlen(RSTR_PTR(s)) ^ RSTR_LEN(s)) != 0) { + mrb_raise(mrb, E_ARGUMENT_ERROR, "string contains null byte"); + } + return RSTR_PTR(s); +} + +/* + * call-seq: (Caution! String("abcd") change) + * String("abcdefg") = String("abcd") + String("efg") + * + * Returns a new string object containing a copy of str. + */ +MRB_API void +mrb_str_concat(mrb_state *mrb, mrb_value self, mrb_value other) +{ + if (!mrb_string_p(other)) { + other = mrb_str_to_str(mrb, other); + } + mrb_str_cat_str(mrb, self, other); +} + +/* + * call-seq: (Caution! String("abcd") remain) + * String("abcdefg") = String("abcd") + String("efg") + * + * Returns a new string object containing a copy of str. + */ +MRB_API mrb_value +mrb_str_plus(mrb_state *mrb, mrb_value a, mrb_value b) +{ + struct RString *s = mrb_str_ptr(a); + struct RString *s2 = mrb_str_ptr(b); + struct RString *t; + + t = str_new(mrb, 0, RSTR_LEN(s) + RSTR_LEN(s2)); + memcpy(RSTR_PTR(t), RSTR_PTR(s), RSTR_LEN(s)); + memcpy(RSTR_PTR(t) + RSTR_LEN(s), RSTR_PTR(s2), RSTR_LEN(s2)); + + return mrb_obj_value(t); +} + +/* 15.2.10.5.2 */ + +/* + * call-seq: (Caution! String("abcd") remain) for stack_argument + * String("abcdefg") = String("abcd") + String("efg") + * + * Returns a new string object containing a copy of str. + */ +static mrb_value +mrb_str_plus_m(mrb_state *mrb, mrb_value self) +{ + mrb_value str; + + mrb_get_args(mrb, "S", &str); + return mrb_str_plus(mrb, self, str); +} + +/* 15.2.10.5.26 */ +/* 15.2.10.5.33 */ +/* + * call-seq: + * "abcd".size => int + * + * Returns the length of string. + */ +static mrb_value +mrb_str_size(mrb_state *mrb, mrb_value self) +{ + mrb_int len = RSTRING_CHAR_LEN(self); + return mrb_fixnum_value(len); +} + +static mrb_value +mrb_str_bytesize(mrb_state *mrb, mrb_value self) +{ + mrb_int len = RSTRING_LEN(self); + return mrb_fixnum_value(len); +} + +/* 15.2.10.5.1 */ +/* + * call-seq: + * str * integer => new_str + * + * Copy---Returns a new String containing integer copies of + * the receiver. + * + * "Ho! " * 3 #=> "Ho! Ho! Ho! " + */ +static mrb_value +mrb_str_times(mrb_state *mrb, mrb_value self) +{ + mrb_int n,len,times; + struct RString *str2; + char *p; + + mrb_get_args(mrb, "i", ×); + if (times < 0) { + mrb_raise(mrb, E_ARGUMENT_ERROR, "negative argument"); + } + if (times && MRB_INT_MAX / times < RSTRING_LEN(self)) { + mrb_raise(mrb, E_ARGUMENT_ERROR, "argument too big"); + } + + len = RSTRING_LEN(self)*times; + str2 = str_new(mrb, 0, len); + str_with_class(mrb, str2, self); + p = RSTR_PTR(str2); + if (len > 0) { + n = RSTRING_LEN(self); + memcpy(p, RSTRING_PTR(self), n); + while (n <= len/2) { + memcpy(p + n, p, n); + n *= 2; + } + memcpy(p + n, p, len-n); + } + p[RSTR_LEN(str2)] = '\0'; + + return mrb_obj_value(str2); +} +/* -------------------------------------------------------------- */ + +#define lesser(a,b) (((a)>(b))?(b):(a)) + +/* ---------------------------*/ +/* + * call-seq: + * mrb_value str1 <=> mrb_value str2 => int + * > 1 + * = 0 + * < -1 + */ +MRB_API int +mrb_str_cmp(mrb_state *mrb, mrb_value str1, mrb_value str2) +{ + mrb_int len; + mrb_int retval; + struct RString *s1 = mrb_str_ptr(str1); + struct RString *s2 = mrb_str_ptr(str2); + + len = lesser(RSTR_LEN(s1), RSTR_LEN(s2)); + retval = memcmp(RSTR_PTR(s1), RSTR_PTR(s2), len); + if (retval == 0) { + if (RSTR_LEN(s1) == RSTR_LEN(s2)) return 0; + if (RSTR_LEN(s1) > RSTR_LEN(s2)) return 1; + return -1; + } + if (retval > 0) return 1; + return -1; +} + +/* 15.2.10.5.3 */ + +/* + * call-seq: + * str <=> other_str => -1, 0, +1 + * + * Comparison---Returns -1 if other_str is less than, 0 if + * other_str is equal to, and +1 if other_str is greater than + * str. If the strings are of different lengths, and the strings are + * equal when compared up to the shortest length, then the longer string is + * considered greater than the shorter one. If the variable $= is + * false, the comparison is based on comparing the binary values + * of each character in the string. In older versions of Ruby, setting + * $= allowed case-insensitive comparisons; this is now deprecated + * in favor of using String#casecmp. + * + * <=> is the basis for the methods <, + * <=, >, >=, and between?, + * included from module Comparable. The method + * String#== does not use Comparable#==. + * + * "abcdef" <=> "abcde" #=> 1 + * "abcdef" <=> "abcdef" #=> 0 + * "abcdef" <=> "abcdefg" #=> -1 + * "abcdef" <=> "ABCDEF" #=> 1 + */ +static mrb_value +mrb_str_cmp_m(mrb_state *mrb, mrb_value str1) +{ + mrb_value str2; + mrb_int result; + + mrb_get_args(mrb, "o", &str2); + if (!mrb_string_p(str2)) { + if (!mrb_respond_to(mrb, str2, mrb_intern_lit(mrb, "to_s"))) { + return mrb_nil_value(); + } + else if (!mrb_respond_to(mrb, str2, mrb_intern_lit(mrb, "<=>"))) { + return mrb_nil_value(); + } + else { + mrb_value tmp = mrb_funcall(mrb, str2, "<=>", 1, str1); + + if (!mrb_nil_p(tmp)) return mrb_nil_value(); + if (!mrb_fixnum_p(tmp)) { + return mrb_funcall(mrb, mrb_fixnum_value(0), "-", 1, tmp); + } + result = -mrb_fixnum(tmp); + } + } + else { + result = mrb_str_cmp(mrb, str1, str2); + } + return mrb_fixnum_value(result); +} + +static mrb_bool +str_eql(mrb_state *mrb, const mrb_value str1, const mrb_value str2) +{ + const mrb_int len = RSTRING_LEN(str1); + + if (len != RSTRING_LEN(str2)) return FALSE; + if (memcmp(RSTRING_PTR(str1), RSTRING_PTR(str2), (size_t)len) == 0) + return TRUE; + return FALSE; +} + +MRB_API mrb_bool +mrb_str_equal(mrb_state *mrb, mrb_value str1, mrb_value str2) +{ + if (mrb_immediate_p(str2)) return FALSE; + if (!mrb_string_p(str2)) { + if (mrb_nil_p(str2)) return FALSE; + if (!mrb_respond_to(mrb, str2, mrb_intern_lit(mrb, "to_str"))) { + return FALSE; + } + str2 = mrb_funcall(mrb, str2, "to_str", 0); + return mrb_equal(mrb, str2, str1); + } + return str_eql(mrb, str1, str2); +} + +/* 15.2.10.5.4 */ +/* + * call-seq: + * str == obj => true or false + * + * Equality--- + * If obj is not a String, returns false. + * Otherwise, returns false or true + * + * caution:if str <=> obj returns zero. + */ +static mrb_value +mrb_str_equal_m(mrb_state *mrb, mrb_value str1) +{ + mrb_value str2; + + mrb_get_args(mrb, "o", &str2); + + return mrb_bool_value(mrb_str_equal(mrb, str1, str2)); +} +/* ---------------------------------- */ +MRB_API mrb_value +mrb_str_to_str(mrb_state *mrb, mrb_value str) +{ + mrb_value s; + + if (!mrb_string_p(str)) { + s = mrb_check_convert_type(mrb, str, MRB_TT_STRING, "String", "to_str"); + if (mrb_nil_p(s)) { + s = mrb_convert_type(mrb, str, MRB_TT_STRING, "String", "to_s"); + } + return s; + } + return str; +} + +MRB_API const char* +mrb_string_value_ptr(mrb_state *mrb, mrb_value ptr) +{ + mrb_value str = mrb_str_to_str(mrb, ptr); + return RSTRING_PTR(str); +} + +MRB_API mrb_int +mrb_string_value_len(mrb_state *mrb, mrb_value ptr) +{ + mrb_value str = mrb_str_to_str(mrb, ptr); + return RSTRING_LEN(str); +} + +void +mrb_noregexp(mrb_state *mrb, mrb_value self) +{ + mrb_raise(mrb, E_NOTIMP_ERROR, "Regexp class not implemented"); +} + +void +mrb_regexp_check(mrb_state *mrb, mrb_value obj) +{ + if (mrb_regexp_p(mrb, obj)) { + mrb_noregexp(mrb, obj); + } +} + +MRB_API mrb_value +mrb_str_dup(mrb_state *mrb, mrb_value str) +{ + struct RString *s = mrb_str_ptr(str); + struct RString *dup = str_new(mrb, 0, 0); + + str_with_class(mrb, dup, str); + return str_replace(mrb, dup, s); +} + +static mrb_value +mrb_str_aref(mrb_state *mrb, mrb_value str, mrb_value indx) +{ + mrb_int idx; + + mrb_regexp_check(mrb, indx); + switch (mrb_type(indx)) { + case MRB_TT_FIXNUM: + idx = mrb_fixnum(indx); + +num_index: + str = str_substr(mrb, str, idx, 1); + if (!mrb_nil_p(str) && RSTRING_LEN(str) == 0) return mrb_nil_value(); + return str; + + case MRB_TT_STRING: + if (str_index_str(mrb, str, indx, 0) != -1) + return mrb_str_dup(mrb, indx); + return mrb_nil_value(); + + case MRB_TT_RANGE: + goto range_arg; + + default: + indx = mrb_Integer(mrb, indx); + if (mrb_nil_p(indx)) { + range_arg: + { + mrb_int beg, len; + + len = RSTRING_CHAR_LEN(str); + switch (mrb_range_beg_len(mrb, indx, &beg, &len, len, TRUE)) { + case 1: + return str_subseq(mrb, str, beg, len); + case 2: + return mrb_nil_value(); + default: + break; + } + } + mrb_raise(mrb, E_TYPE_ERROR, "can't convert to Fixnum"); + } + idx = mrb_fixnum(indx); + goto num_index; + } + return mrb_nil_value(); /* not reached */ +} + +/* 15.2.10.5.6 */ +/* 15.2.10.5.34 */ +/* + * call-seq: + * str[fixnum] => fixnum or nil + * str[fixnum, fixnum] => new_str or nil + * str[range] => new_str or nil + * str[regexp] => new_str or nil + * str[regexp, fixnum] => new_str or nil + * str[other_str] => new_str or nil + * str.slice(fixnum) => fixnum or nil + * str.slice(fixnum, fixnum) => new_str or nil + * str.slice(range) => new_str or nil + * str.slice(other_str) => new_str or nil + * + * Element Reference---If passed a single Fixnum, returns the code + * of the character at that position. If passed two Fixnum + * objects, returns a substring starting at the offset given by the first, and + * a length given by the second. If given a range, a substring containing + * characters at offsets given by the range is returned. In all three cases, if + * an offset is negative, it is counted from the end of str. Returns + * nil if the initial offset falls outside the string, the length + * is negative, or the beginning of the range is greater than the end. + * + * If a String is given, that string is returned if it occurs in + * str. In both cases, nil is returned if there is no + * match. + * + * a = "hello there" + * a[1] #=> 101(1.8.7) "e"(1.9.2) + * a[1.1] #=> "e"(1.9.2) + * a[1,3] #=> "ell" + * a[1..3] #=> "ell" + * a[-3,2] #=> "er" + * a[-4..-2] #=> "her" + * a[12..-1] #=> nil + * a[-2..-4] #=> "" + * a["lo"] #=> "lo" + * a["bye"] #=> nil + */ +static mrb_value +mrb_str_aref_m(mrb_state *mrb, mrb_value str) +{ + mrb_value a1, a2; + int argc; + + argc = mrb_get_args(mrb, "o|o", &a1, &a2); + if (argc == 2) { + mrb_int n1, n2; + + mrb_regexp_check(mrb, a1); + mrb_get_args(mrb, "ii", &n1, &n2); + return str_substr(mrb, str, n1, n2); + } + if (argc != 1) { + mrb_raisef(mrb, E_ARGUMENT_ERROR, "wrong number of arguments (%S for 1)", mrb_fixnum_value(argc)); + } + return mrb_str_aref(mrb, str, a1); +} + +/* 15.2.10.5.8 */ +/* + * call-seq: + * str.capitalize! => str or nil + * + * Modifies str by converting the first character to uppercase and the + * remainder to lowercase. Returns nil if no changes are made. + * + * a = "hello" + * a.capitalize! #=> "Hello" + * a #=> "Hello" + * a.capitalize! #=> nil + */ +static mrb_value +mrb_str_capitalize_bang(mrb_state *mrb, mrb_value str) +{ + char *p, *pend; + mrb_bool modify = FALSE; + struct RString *s = mrb_str_ptr(str); + + mrb_str_modify(mrb, s); + if (RSTR_LEN(s) == 0 || !RSTR_PTR(s)) return mrb_nil_value(); + p = RSTR_PTR(s); pend = RSTR_PTR(s) + RSTR_LEN(s); + if (ISLOWER(*p)) { + *p = TOUPPER(*p); + modify = TRUE; + } + while (++p < pend) { + if (ISUPPER(*p)) { + *p = TOLOWER(*p); + modify = TRUE; + } + } + if (modify) return str; + return mrb_nil_value(); +} + +/* 15.2.10.5.7 */ +/* + * call-seq: + * str.capitalize => new_str + * + * Returns a copy of str with the first character converted to uppercase + * and the remainder to lowercase. + * + * "hello".capitalize #=> "Hello" + * "HELLO".capitalize #=> "Hello" + * "123ABC".capitalize #=> "123abc" + */ +static mrb_value +mrb_str_capitalize(mrb_state *mrb, mrb_value self) +{ + mrb_value str; + + str = mrb_str_dup(mrb, self); + mrb_str_capitalize_bang(mrb, str); + return str; +} + +/* 15.2.10.5.10 */ +/* + * call-seq: + * str.chomp!(separator="\n") => str or nil + * + * Modifies str in place as described for String#chomp, + * returning str, or nil if no modifications were made. + */ +static mrb_value +mrb_str_chomp_bang(mrb_state *mrb, mrb_value str) +{ + mrb_value rs; + mrb_int newline; + char *p, *pp; + mrb_int rslen; + mrb_int len; + mrb_int argc; + struct RString *s = mrb_str_ptr(str); + + mrb_str_modify(mrb, s); + argc = mrb_get_args(mrb, "|S", &rs); + len = RSTR_LEN(s); + if (argc == 0) { + if (len == 0) return mrb_nil_value(); + smart_chomp: + if (RSTR_PTR(s)[len-1] == '\n') { + RSTR_SET_LEN(s, RSTR_LEN(s) - 1); + if (RSTR_LEN(s) > 0 && + RSTR_PTR(s)[RSTR_LEN(s)-1] == '\r') { + RSTR_SET_LEN(s, RSTR_LEN(s) - 1); + } + } + else if (RSTR_PTR(s)[len-1] == '\r') { + RSTR_SET_LEN(s, RSTR_LEN(s) - 1); + } + else { + return mrb_nil_value(); + } + RSTR_PTR(s)[RSTR_LEN(s)] = '\0'; + return str; + } + + if (len == 0 || mrb_nil_p(rs)) return mrb_nil_value(); + p = RSTR_PTR(s); + rslen = RSTRING_LEN(rs); + if (rslen == 0) { + while (len>0 && p[len-1] == '\n') { + len--; + if (len>0 && p[len-1] == '\r') + len--; + } + if (len < RSTR_LEN(s)) { + RSTR_SET_LEN(s, len); + p[len] = '\0'; + return str; + } + return mrb_nil_value(); + } + if (rslen > len) return mrb_nil_value(); + newline = RSTRING_PTR(rs)[rslen-1]; + if (rslen == 1 && newline == '\n') + newline = RSTRING_PTR(rs)[rslen-1]; + if (rslen == 1 && newline == '\n') + goto smart_chomp; + + pp = p + len - rslen; + if (p[len-1] == newline && + (rslen <= 1 || + memcmp(RSTRING_PTR(rs), pp, rslen) == 0)) { + RSTR_SET_LEN(s, len - rslen); + p[RSTR_LEN(s)] = '\0'; + return str; + } + return mrb_nil_value(); +} + +/* 15.2.10.5.9 */ +/* + * call-seq: + * str.chomp(separator="\n") => new_str + * + * Returns a new String with the given record separator removed + * from the end of str (if present). If $/ has not been + * changed from the default Ruby record separator, then chomp also + * removes carriage return characters (that is it will remove \n, + * \r, and \r\n). + * + * "hello".chomp #=> "hello" + * "hello\n".chomp #=> "hello" + * "hello\r\n".chomp #=> "hello" + * "hello\n\r".chomp #=> "hello\n" + * "hello\r".chomp #=> "hello" + * "hello \n there".chomp #=> "hello \n there" + * "hello".chomp("llo") #=> "he" + */ +static mrb_value +mrb_str_chomp(mrb_state *mrb, mrb_value self) +{ + mrb_value str; + + str = mrb_str_dup(mrb, self); + mrb_str_chomp_bang(mrb, str); + return str; +} + +/* 15.2.10.5.12 */ +/* + * call-seq: + * str.chop! => str or nil + * + * Processes str as for String#chop, returning str, + * or nil if str is the empty string. See also + * String#chomp!. + */ +static mrb_value +mrb_str_chop_bang(mrb_state *mrb, mrb_value str) +{ + struct RString *s = mrb_str_ptr(str); + + mrb_str_modify(mrb, s); + if (RSTR_LEN(s) > 0) { + mrb_int len; +#ifdef MRB_UTF8_STRING + const char* t = RSTR_PTR(s), *p = t; + const char* e = p + RSTR_LEN(s); + while (p=e) break; + p += clen; + } + len = p - t; +#else + len = RSTR_LEN(s) - 1; +#endif + if (RSTR_PTR(s)[len] == '\n') { + if (len > 0 && + RSTR_PTR(s)[len-1] == '\r') { + len--; + } + } + RSTR_SET_LEN(s, len); + RSTR_PTR(s)[len] = '\0'; + return str; + } + return mrb_nil_value(); +} + +/* 15.2.10.5.11 */ +/* + * call-seq: + * str.chop => new_str + * + * Returns a new String with the last character removed. If the + * string ends with \r\n, both characters are removed. Applying + * chop to an empty string returns an empty + * string. String#chomp is often a safer alternative, as it leaves + * the string unchanged if it doesn't end in a record separator. + * + * "string\r\n".chop #=> "string" + * "string\n\r".chop #=> "string\n" + * "string\n".chop #=> "string" + * "string".chop #=> "strin" + * "x".chop #=> "" + */ +static mrb_value +mrb_str_chop(mrb_state *mrb, mrb_value self) +{ + mrb_value str; + str = mrb_str_dup(mrb, self); + mrb_str_chop_bang(mrb, str); + return str; +} + +/* 15.2.10.5.14 */ +/* + * call-seq: + * str.downcase! => str or nil + * + * Downcases the contents of str, returning nil if no + * changes were made. + */ +static mrb_value +mrb_str_downcase_bang(mrb_state *mrb, mrb_value str) +{ + char *p, *pend; + mrb_bool modify = FALSE; + struct RString *s = mrb_str_ptr(str); + + mrb_str_modify(mrb, s); + p = RSTR_PTR(s); + pend = RSTR_PTR(s) + RSTR_LEN(s); + while (p < pend) { + if (ISUPPER(*p)) { + *p = TOLOWER(*p); + modify = TRUE; + } + p++; + } + + if (modify) return str; + return mrb_nil_value(); +} + +/* 15.2.10.5.13 */ +/* + * call-seq: + * str.downcase => new_str + * + * Returns a copy of str with all uppercase letters replaced with their + * lowercase counterparts. The operation is locale insensitive---only + * characters 'A' to 'Z' are affected. + * + * "hEllO".downcase #=> "hello" + */ +static mrb_value +mrb_str_downcase(mrb_state *mrb, mrb_value self) +{ + mrb_value str; + + str = mrb_str_dup(mrb, self); + mrb_str_downcase_bang(mrb, str); + return str; +} + +/* 15.2.10.5.16 */ +/* + * call-seq: + * str.empty? => true or false + * + * Returns true if str has a length of zero. + * + * "hello".empty? #=> false + * "".empty? #=> true + */ +static mrb_value +mrb_str_empty_p(mrb_state *mrb, mrb_value self) +{ + struct RString *s = mrb_str_ptr(self); + + return mrb_bool_value(RSTR_LEN(s) == 0); +} + +/* 15.2.10.5.17 */ +/* + * call-seq: + * str.eql?(other) => true or false + * + * Two strings are equal if the have the same length and content. + */ +static mrb_value +mrb_str_eql(mrb_state *mrb, mrb_value self) +{ + mrb_value str2; + mrb_bool eql_p; + + mrb_get_args(mrb, "o", &str2); + eql_p = (mrb_type(str2) == MRB_TT_STRING) && str_eql(mrb, self, str2); + + return mrb_bool_value(eql_p); +} + +MRB_API mrb_value +mrb_str_substr(mrb_state *mrb, mrb_value str, mrb_int beg, mrb_int len) +{ + return str_substr(mrb, str, beg, len); +} + +mrb_int +mrb_str_hash(mrb_state *mrb, mrb_value str) +{ + /* 1-8-7 */ + struct RString *s = mrb_str_ptr(str); + mrb_int len = RSTR_LEN(s); + char *p = RSTR_PTR(s); + uint64_t key = 0; + + while (len--) { + key = key*65599 + *p; + p++; + } + return (mrb_int)(key + (key>>5)); +} + +/* 15.2.10.5.20 */ +/* + * call-seq: + * str.hash => fixnum + * + * Return a hash based on the string's length and content. + */ +static mrb_value +mrb_str_hash_m(mrb_state *mrb, mrb_value self) +{ + mrb_int key = mrb_str_hash(mrb, self); + return mrb_fixnum_value(key); +} + +/* 15.2.10.5.21 */ +/* + * call-seq: + * str.include? other_str => true or false + * str.include? fixnum => true or false + * + * Returns true if str contains the given string or + * character. + * + * "hello".include? "lo" #=> true + * "hello".include? "ol" #=> false + * "hello".include? ?h #=> true + */ +static mrb_value +mrb_str_include(mrb_state *mrb, mrb_value self) +{ + mrb_value str2; + + mrb_get_args(mrb, "S", &str2); + if (str_index_str(mrb, self, str2, 0) < 0) + return mrb_bool_value(FALSE); + return mrb_bool_value(TRUE); +} + +/* 15.2.10.5.22 */ +/* + * call-seq: + * str.index(substring [, offset]) => fixnum or nil + * str.index(fixnum [, offset]) => fixnum or nil + * str.index(regexp [, offset]) => fixnum or nil + * + * Returns the index of the first occurrence of the given + * substring, + * character (fixnum), or pattern (regexp) in str. + * Returns + * nil if not found. + * If the second parameter is present, it + * specifies the position in the string to begin the search. + * + * "hello".index('e') #=> 1 + * "hello".index('lo') #=> 3 + * "hello".index('a') #=> nil + * "hello".index(101) #=> 1(101=0x65='e') + * "hello".index(/[aeiou]/, -3) #=> 4 + */ +static mrb_value +mrb_str_index_m(mrb_state *mrb, mrb_value str) +{ + mrb_value *argv; + mrb_int argc; + mrb_value sub; + mrb_int pos, clen; + + mrb_get_args(mrb, "*!", &argv, &argc); + if (argc == 2) { + mrb_get_args(mrb, "oi", &sub, &pos); + } + else { + pos = 0; + if (argc > 0) + sub = argv[0]; + else + sub = mrb_nil_value(); + } + mrb_regexp_check(mrb, sub); + clen = RSTRING_CHAR_LEN(str); + if (pos < 0) { + pos += clen; + if (pos < 0) { + return mrb_nil_value(); + } + } + if (pos > clen) return mrb_nil_value(); + pos = chars2bytes(str, 0, pos); + + switch (mrb_type(sub)) { + default: { + mrb_value tmp; + + tmp = mrb_check_string_type(mrb, sub); + if (mrb_nil_p(tmp)) { + mrb_raisef(mrb, E_TYPE_ERROR, "type mismatch: %S given", sub); + } + sub = tmp; + } + /* fall through */ + case MRB_TT_STRING: + pos = str_index_str(mrb, str, sub, pos); + break; + } + + if (pos == -1) return mrb_nil_value(); + pos = bytes2chars(RSTRING_PTR(str), pos); + BYTES_ALIGN_CHECK(pos); + return mrb_fixnum_value(pos); +} + +#define STR_REPLACE_SHARED_MIN 10 + +/* 15.2.10.5.24 */ +/* 15.2.10.5.28 */ +/* + * call-seq: + * str.replace(other_str) => str + * + * s = "hello" #=> "hello" + * s.replace "world" #=> "world" + */ +static mrb_value +mrb_str_replace(mrb_state *mrb, mrb_value str) +{ + mrb_value str2; + + mrb_get_args(mrb, "S", &str2); + return str_replace(mrb, mrb_str_ptr(str), mrb_str_ptr(str2)); +} + +/* 15.2.10.5.23 */ +/* + * call-seq: + * String.new(str="") => new_str + * + * Returns a new string object containing a copy of str. + */ +static mrb_value +mrb_str_init(mrb_state *mrb, mrb_value self) +{ + mrb_value str2; + + if (mrb_get_args(mrb, "|S", &str2) == 0) { + struct RString *s = str_new(mrb, 0, 0); + str2 = mrb_obj_value(s); + } + str_replace(mrb, mrb_str_ptr(self), mrb_str_ptr(str2)); + return self; +} + +/* 15.2.10.5.25 */ +/* 15.2.10.5.41 */ +/* + * call-seq: + * str.intern => symbol + * str.to_sym => symbol + * + * Returns the Symbol corresponding to str, creating the + * symbol if it did not previously exist. See Symbol#id2name. + * + * "Koala".intern #=> :Koala + * s = 'cat'.to_sym #=> :cat + * s == :cat #=> true + * s = '@cat'.to_sym #=> :@cat + * s == :@cat #=> true + * + * This can also be used to create symbols that cannot be represented using the + * :xxx notation. + * + * 'cat and dog'.to_sym #=> :"cat and dog" + */ +MRB_API mrb_value +mrb_str_intern(mrb_state *mrb, mrb_value self) +{ + return mrb_symbol_value(mrb_intern_str(mrb, self)); +} +/* ---------------------------------- */ +MRB_API mrb_value +mrb_obj_as_string(mrb_state *mrb, mrb_value obj) +{ + mrb_value str; + + if (mrb_string_p(obj)) { + return obj; + } + str = mrb_funcall(mrb, obj, "to_s", 0); + if (!mrb_string_p(str)) + return mrb_any_to_s(mrb, obj); + return str; +} + +MRB_API mrb_value +mrb_ptr_to_str(mrb_state *mrb, void *p) +{ + struct RString *p_str; + char *p1; + char *p2; + uintptr_t n = (uintptr_t)p; + + p_str = str_new(mrb, NULL, 2 + sizeof(uintptr_t) * CHAR_BIT / 4); + p1 = RSTR_PTR(p_str); + *p1++ = '0'; + *p1++ = 'x'; + p2 = p1; + + do { + *p2++ = mrb_digitmap[n % 16]; + n /= 16; + } while (n > 0); + *p2 = '\0'; + RSTR_SET_LEN(p_str, (mrb_int)(p2 - RSTR_PTR(p_str))); + + while (p1 < p2) { + const char c = *p1; + *p1++ = *--p2; + *p2 = c; + } + + return mrb_obj_value(p_str); +} + +MRB_API mrb_value +mrb_string_type(mrb_state *mrb, mrb_value str) +{ + return mrb_convert_type(mrb, str, MRB_TT_STRING, "String", "to_str"); +} + +MRB_API mrb_value +mrb_check_string_type(mrb_state *mrb, mrb_value str) +{ + return mrb_check_convert_type(mrb, str, MRB_TT_STRING, "String", "to_str"); +} + +/* 15.2.10.5.30 */ +/* + * call-seq: + * str.reverse! => str + * + * Reverses str in place. + */ +static mrb_value +mrb_str_reverse_bang(mrb_state *mrb, mrb_value str) +{ +#ifdef MRB_UTF8_STRING + mrb_int utf8_len = RSTRING_CHAR_LEN(str); + mrb_int len = RSTRING_LEN(str); + + if (utf8_len == len) goto bytes; + if (utf8_len > 1) { + char *buf; + char *p, *e, *r; + + mrb_str_modify(mrb, mrb_str_ptr(str)); + len = RSTRING_LEN(str); + buf = (char*)mrb_malloc(mrb, (size_t)len); + p = buf; + e = buf + len; + + memcpy(buf, RSTRING_PTR(str), len); + r = RSTRING_PTR(str) + len; + + while (p 1) { + p = RSTR_PTR(s); + e = p + RSTR_LEN(s) - 1; + while (p < e) { + c = *p; + *p++ = *e; + *e-- = c; + } + } + return str; + } +} + +/* ---------------------------------- */ +/* 15.2.10.5.29 */ +/* + * call-seq: + * str.reverse => new_str + * + * Returns a new string with the characters from str in reverse order. + * + * "stressed".reverse #=> "desserts" + */ +static mrb_value +mrb_str_reverse(mrb_state *mrb, mrb_value str) +{ + mrb_value str2 = mrb_str_dup(mrb, str); + mrb_str_reverse_bang(mrb, str2); + return str2; +} + +/* 15.2.10.5.31 */ +/* + * call-seq: + * str.rindex(substring [, fixnum]) => fixnum or nil + * str.rindex(fixnum [, fixnum]) => fixnum or nil + * str.rindex(regexp [, fixnum]) => fixnum or nil + * + * Returns the index of the last occurrence of the given substring, + * character (fixnum), or pattern (regexp) in str. Returns + * nil if not found. If the second parameter is present, it + * specifies the position in the string to end the search---characters beyond + * this point will not be considered. + * + * "hello".rindex('e') #=> 1 + * "hello".rindex('l') #=> 3 + * "hello".rindex('a') #=> nil + * "hello".rindex(101) #=> 1 + * "hello".rindex(/[aeiou]/, -2) #=> 1 + */ +static mrb_value +mrb_str_rindex(mrb_state *mrb, mrb_value str) +{ + mrb_value *argv; + mrb_int argc; + mrb_value sub; + mrb_int pos, len = RSTRING_CHAR_LEN(str); + + mrb_get_args(mrb, "*!", &argv, &argc); + if (argc == 2) { + mrb_get_args(mrb, "oi", &sub, &pos); + if (pos < 0) { + pos += len; + if (pos < 0) { + mrb_regexp_check(mrb, sub); + return mrb_nil_value(); + } + } + if (pos > len) pos = len; + } + else { + pos = len; + if (argc > 0) + sub = argv[0]; + else + sub = mrb_nil_value(); + } + pos = chars2bytes(str, 0, pos); + mrb_regexp_check(mrb, sub); + + switch (mrb_type(sub)) { + default: { + mrb_value tmp; + + tmp = mrb_check_string_type(mrb, sub); + if (mrb_nil_p(tmp)) { + mrb_raisef(mrb, E_TYPE_ERROR, "type mismatch: %S given", sub); + } + sub = tmp; + } + /* fall through */ + case MRB_TT_STRING: + pos = str_rindex(mrb, str, sub, pos); + if (pos >= 0) { + pos = bytes2chars(RSTRING_PTR(str), pos); + BYTES_ALIGN_CHECK(pos); + return mrb_fixnum_value(pos); + } + break; + + } /* end of switch (TYPE(sub)) */ + return mrb_nil_value(); +} + +/* 15.2.10.5.35 */ + +/* + * call-seq: + * str.split(pattern="\n", [limit]) => anArray + * + * Divides str into substrings based on a delimiter, returning an array + * of these substrings. + * + * If pattern is a String, then its contents are used as + * the delimiter when splitting str. If pattern is a single + * space, str is split on whitespace, with leading whitespace and runs + * of contiguous whitespace characters ignored. + * + * If pattern is a Regexp, str is divided where the + * pattern matches. Whenever the pattern matches a zero-length string, + * str is split into individual characters. + * + * If pattern is omitted, the value of $; is used. If + * $; is nil (which is the default), str is + * split on whitespace as if ' ' were specified. + * + * If the limit parameter is omitted, trailing null fields are + * suppressed. If limit is a positive number, at most that number of + * fields will be returned (if limit is 1, the entire + * string is returned as the only entry in an array). If negative, there is no + * limit to the number of fields returned, and trailing null fields are not + * suppressed. + * + * " now's the time".split #=> ["now's", "the", "time"] + * " now's the time".split(' ') #=> ["now's", "the", "time"] + * " now's the time".split(/ /) #=> ["", "now's", "", "the", "time"] + * "hello".split(//) #=> ["h", "e", "l", "l", "o"] + * "hello".split(//, 3) #=> ["h", "e", "llo"] + * + * "mellow yellow".split("ello") #=> ["m", "w y", "w"] + * "1,2,,3,4,,".split(',') #=> ["1", "2", "", "3", "4"] + * "1,2,,3,4,,".split(',', 4) #=> ["1", "2", "", "3,4,,"] + * "1,2,,3,4,,".split(',', -4) #=> ["1", "2", "", "3", "4", "", ""] + */ + +static mrb_value +mrb_str_split_m(mrb_state *mrb, mrb_value str) +{ + int argc; + mrb_value spat = mrb_nil_value(); + enum {awk, string, regexp} split_type = string; + mrb_int i = 0; + mrb_int beg; + mrb_int end; + mrb_int lim = 0; + mrb_bool lim_p; + mrb_value result, tmp; + + argc = mrb_get_args(mrb, "|oi", &spat, &lim); + lim_p = (lim > 0 && argc == 2); + if (argc == 2) { + if (lim == 1) { + if (RSTRING_LEN(str) == 0) + return mrb_ary_new_capa(mrb, 0); + return mrb_ary_new_from_values(mrb, 1, &str); + } + i = 1; + } + + if (argc == 0 || mrb_nil_p(spat)) { + split_type = awk; + } + else { + if (mrb_string_p(spat)) { + split_type = string; + if (RSTRING_LEN(spat) == 1 && RSTRING_PTR(spat)[0] == ' ') { + split_type = awk; + } + } + else { + mrb_noregexp(mrb, str); + } + } + + result = mrb_ary_new(mrb); + beg = 0; + if (split_type == awk) { + mrb_bool skip = TRUE; + mrb_int idx = 0; + mrb_int str_len = RSTRING_LEN(str); + unsigned int c; + int ai = mrb_gc_arena_save(mrb); + + idx = end = beg; + while (idx < str_len) { + c = (unsigned char)RSTRING_PTR(str)[idx++]; + if (skip) { + if (ISSPACE(c)) { + beg = idx; + } + else { + end = idx; + skip = FALSE; + if (lim_p && lim <= i) break; + } + } + else if (ISSPACE(c)) { + mrb_ary_push(mrb, result, byte_subseq(mrb, str, beg, end-beg)); + mrb_gc_arena_restore(mrb, ai); + skip = TRUE; + beg = idx; + if (lim_p) ++i; + } + else { + end = idx; + } + } + } + else if (split_type == string) { + mrb_int str_len = RSTRING_LEN(str); + mrb_int pat_len = RSTRING_LEN(spat); + mrb_int idx = 0; + int ai = mrb_gc_arena_save(mrb); + + while (idx < str_len) { + if (pat_len > 0) { + end = mrb_memsearch(RSTRING_PTR(spat), pat_len, RSTRING_PTR(str)+idx, str_len - idx); + if (end < 0) break; + } + else { + end = chars2bytes(str, idx, 1); + } + mrb_ary_push(mrb, result, byte_subseq(mrb, str, idx, end)); + mrb_gc_arena_restore(mrb, ai); + idx += end + pat_len; + if (lim_p && lim <= ++i) break; + } + beg = idx; + } + else { + mrb_noregexp(mrb, str); + } + if (RSTRING_LEN(str) > 0 && (lim_p || RSTRING_LEN(str) > beg || lim < 0)) { + if (RSTRING_LEN(str) == beg) { + tmp = mrb_str_new_empty(mrb, str); + } + else { + tmp = byte_subseq(mrb, str, beg, RSTRING_LEN(str)-beg); + } + mrb_ary_push(mrb, result, tmp); + } + if (!lim_p && lim == 0) { + mrb_int len; + while ((len = RARRAY_LEN(result)) > 0 && + (tmp = RARRAY_PTR(result)[len-1], RSTRING_LEN(tmp) == 0)) + mrb_ary_pop(mrb, result); + } + + return result; +} + +MRB_API mrb_value +mrb_str_len_to_inum(mrb_state *mrb, const char *str, size_t len, int base, int badcheck) +{ + const char *p = str; + const char *pend = str + len; + char sign = 1; + int c; + uint64_t n = 0; + mrb_int val; + +#define conv_digit(c) \ + (ISDIGIT(c) ? ((c) - '0') : \ + ISLOWER(c) ? ((c) - 'a' + 10) : \ + ISUPPER(c) ? ((c) - 'A' + 10) : \ + -1) + + if (!p) { + if (badcheck) goto bad; + return mrb_fixnum_value(0); + } + while (p=pend) { + if (badcheck) goto bad; + return mrb_fixnum_value(0); + } + if (*p == '0') { /* squeeze preceding 0s */ + p++; + while (p= base) { + break; + } + n *= base; + n += c; + if (n > (uint64_t)MRB_INT_MAX + (sign ? 0 : 1)) { + mrb_raisef(mrb, E_ARGUMENT_ERROR, "string (%S) too big for integer", + mrb_str_new(mrb, str, pend-str)); + } + } + val = (mrb_int)n; + if (badcheck) { + if (p == str) goto bad; /* no number */ + while (p integer + * + * Returns the result of interpreting leading characters in str as an + * integer base base (between 2 and 36). Extraneous characters past the + * end of a valid number are ignored. If there is not a valid number at the + * start of str, 0 is returned. This method never raises an + * exception. + * + * "12345".to_i #=> 12345 + * "99 red balloons".to_i #=> 99 + * "0a".to_i #=> 0 + * "0a".to_i(16) #=> 10 + * "hello".to_i #=> 0 + * "1100101".to_i(2) #=> 101 + * "1100101".to_i(8) #=> 294977 + * "1100101".to_i(10) #=> 1100101 + * "1100101".to_i(16) #=> 17826049 + */ +static mrb_value +mrb_str_to_i(mrb_state *mrb, mrb_value self) +{ + mrb_int base = 10; + + mrb_get_args(mrb, "|i", &base); + if (base < 0) { + mrb_raisef(mrb, E_ARGUMENT_ERROR, "illegal radix %S", mrb_fixnum_value(base)); + } + return mrb_str_to_inum(mrb, self, base, FALSE); +} + +MRB_API double +mrb_cstr_to_dbl(mrb_state *mrb, const char * p, mrb_bool badcheck) +{ + char *end; + char buf[DBL_DIG * 4 + 10]; + double d; + + enum {max_width = 20}; + + if (!p) return 0.0; + while (ISSPACE(*p)) p++; + + if (!badcheck && p[0] == '0' && (p[1] == 'x' || p[1] == 'X')) { + return 0.0; + } + d = mrb_float_read(p, &end); + if (p == end) { + if (badcheck) { +bad: + mrb_raisef(mrb, E_ARGUMENT_ERROR, "invalid string for float(%S)", mrb_str_new_cstr(mrb, p)); + /* not reached */ + } + return d; + } + if (*end) { + char *n = buf; + char *e = buf + sizeof(buf) - 1; + char prev = 0; + + while (p < end && n < e) prev = *n++ = *p++; + while (*p) { + if (*p == '_') { + /* remove underscores between digits */ + if (badcheck) { + if (n == buf || !ISDIGIT(prev)) goto bad; + ++p; + if (!ISDIGIT(*p)) goto bad; + } + else { + while (*++p == '_'); + continue; + } + } + prev = *p++; + if (n < e) *n++ = prev; + } + *n = '\0'; + p = buf; + + if (!badcheck && p[0] == '0' && (p[1] == 'x' || p[1] == 'X')) { + return 0.0; + } + + d = mrb_float_read(p, &end); + if (badcheck) { + if (!end || p == end) goto bad; + while (*end && ISSPACE(*end)) end++; + if (*end) goto bad; + } + } + return d; +} + +MRB_API double +mrb_str_to_dbl(mrb_state *mrb, mrb_value str, mrb_bool badcheck) +{ + char *s; + mrb_int len; + + str = mrb_str_to_str(mrb, str); + s = RSTRING_PTR(str); + len = RSTRING_LEN(str); + if (s) { + if (badcheck && memchr(s, '\0', len)) { + mrb_raise(mrb, E_ARGUMENT_ERROR, "string for Float contains null byte"); + } + if (s[len]) { /* no sentinel somehow */ + struct RString *temp_str = str_new(mrb, s, len); + s = RSTR_PTR(temp_str); + } + } + return mrb_cstr_to_dbl(mrb, s, badcheck); +} + +/* 15.2.10.5.39 */ +/* + * call-seq: + * str.to_f => float + * + * Returns the result of interpreting leading characters in str as a + * floating point number. Extraneous characters past the end of a valid number + * are ignored. If there is not a valid number at the start of str, + * 0.0 is returned. This method never raises an exception. + * + * "123.45e1".to_f #=> 1234.5 + * "45.67 degrees".to_f #=> 45.67 + * "thx1138".to_f #=> 0.0 + */ +static mrb_value +mrb_str_to_f(mrb_state *mrb, mrb_value self) +{ + return mrb_float_value(mrb, mrb_str_to_dbl(mrb, self, FALSE)); +} + +/* 15.2.10.5.40 */ +/* + * call-seq: + * str.to_s => str + * str.to_str => str + * + * Returns the receiver. + */ +static mrb_value +mrb_str_to_s(mrb_state *mrb, mrb_value self) +{ + if (mrb_obj_class(mrb, self) != mrb->string_class) { + return mrb_str_dup(mrb, self); + } + return self; +} + +/* 15.2.10.5.43 */ +/* + * call-seq: + * str.upcase! => str or nil + * + * Upcases the contents of str, returning nil if no changes + * were made. + */ +static mrb_value +mrb_str_upcase_bang(mrb_state *mrb, mrb_value str) +{ + struct RString *s = mrb_str_ptr(str); + char *p, *pend; + mrb_bool modify = FALSE; + + mrb_str_modify(mrb, s); + p = RSTRING_PTR(str); + pend = RSTRING_END(str); + while (p < pend) { + if (ISLOWER(*p)) { + *p = TOUPPER(*p); + modify = TRUE; + } + p++; + } + + if (modify) return str; + return mrb_nil_value(); +} + +/* 15.2.10.5.42 */ +/* + * call-seq: + * str.upcase => new_str + * + * Returns a copy of str with all lowercase letters replaced with their + * uppercase counterparts. The operation is locale insensitive---only + * characters 'a' to 'z' are affected. + * + * "hEllO".upcase #=> "HELLO" + */ +static mrb_value +mrb_str_upcase(mrb_state *mrb, mrb_value self) +{ + mrb_value str; + + str = mrb_str_dup(mrb, self); + mrb_str_upcase_bang(mrb, str); + return str; +} + +#define IS_EVSTR(p,e) ((p) < (e) && (*(p) == '$' || *(p) == '@' || *(p) == '{')) + +/* + * call-seq: + * str.dump -> new_str + * + * Produces a version of str with all nonprinting characters replaced by + * \nnn notation and all special characters escaped. + */ +mrb_value +mrb_str_dump(mrb_state *mrb, mrb_value str) +{ + mrb_int len; + const char *p, *pend; + char *q; + struct RString *result; + + len = 2; /* "" */ + p = RSTRING_PTR(str); pend = p + RSTRING_LEN(str); + while (p < pend) { + unsigned char c = *p++; + switch (c) { + case '"': case '\\': + case '\n': case '\r': + case '\t': case '\f': + case '\013': case '\010': case '\007': case '\033': + len += 2; + break; + + case '#': + len += IS_EVSTR(p, pend) ? 2 : 1; + break; + + default: + if (ISPRINT(c)) { + len++; + } + else { + len += 4; /* \NNN */ + } + break; + } + } + + result = str_new(mrb, 0, len); + str_with_class(mrb, result, str); + p = RSTRING_PTR(str); pend = p + RSTRING_LEN(str); + q = RSTR_PTR(result); + *q++ = '"'; + while (p < pend) { + unsigned char c = *p++; + + switch (c) { + case '"': + case '\\': + *q++ = '\\'; + *q++ = c; + break; + + case '\n': + *q++ = '\\'; + *q++ = 'n'; + break; + + case '\r': + *q++ = '\\'; + *q++ = 'r'; + break; + + case '\t': + *q++ = '\\'; + *q++ = 't'; + break; + + case '\f': + *q++ = '\\'; + *q++ = 'f'; + break; + + case '\013': + *q++ = '\\'; + *q++ = 'v'; + break; + + case '\010': + *q++ = '\\'; + *q++ = 'b'; + break; + + case '\007': + *q++ = '\\'; + *q++ = 'a'; + break; + + case '\033': + *q++ = '\\'; + *q++ = 'e'; + break; + + case '#': + if (IS_EVSTR(p, pend)) *q++ = '\\'; + *q++ = '#'; + break; + + default: + if (ISPRINT(c)) { + *q++ = c; + } + else { + *q++ = '\\'; + q[2] = '0' + c % 8; c /= 8; + q[1] = '0' + c % 8; c /= 8; + q[0] = '0' + c % 8; + q += 3; + } + } + } + *q = '"'; + return mrb_obj_value(result); +} + +MRB_API mrb_value +mrb_str_cat(mrb_state *mrb, mrb_value str, const char *ptr, size_t len) +{ + struct RString *s = mrb_str_ptr(str); + size_t capa; + size_t total; + ptrdiff_t off = -1; + + if (len == 0) return str; + mrb_str_modify(mrb, s); + if (ptr >= RSTR_PTR(s) && ptr <= RSTR_PTR(s) + (size_t)RSTR_LEN(s)) { + off = ptr - RSTR_PTR(s); + } + + capa = RSTR_CAPA(s); + total = RSTR_LEN(s)+len; + if (total >= MRB_INT_MAX) { + size_error: + mrb_raise(mrb, E_ARGUMENT_ERROR, "string size too big"); + } + if (capa <= total) { + if (capa == 0) capa = 1; + while (capa <= total) { + if (capa <= MRB_INT_MAX / 2) { + capa *= 2; + } + else { + capa = total+1; + } + } + if (capa <= total || capa > MRB_INT_MAX) { + goto size_error; + } + resize_capa(mrb, s, capa); + } + if (off != -1) { + ptr = RSTR_PTR(s) + off; + } + memcpy(RSTR_PTR(s) + RSTR_LEN(s), ptr, len); + mrb_assert_int_fit(size_t, total, mrb_int, MRB_INT_MAX); + RSTR_SET_LEN(s, total); + RSTR_PTR(s)[total] = '\0'; /* sentinel */ + return str; +} + +MRB_API mrb_value +mrb_str_cat_cstr(mrb_state *mrb, mrb_value str, const char *ptr) +{ + return mrb_str_cat(mrb, str, ptr, strlen(ptr)); +} + +MRB_API mrb_value +mrb_str_cat_str(mrb_state *mrb, mrb_value str, mrb_value str2) +{ + return mrb_str_cat(mrb, str, RSTRING_PTR(str2), RSTRING_LEN(str2)); +} + +MRB_API mrb_value +mrb_str_append(mrb_state *mrb, mrb_value str1, mrb_value str2) +{ + str2 = mrb_str_to_str(mrb, str2); + return mrb_str_cat_str(mrb, str1, str2); +} + +#define CHAR_ESC_LEN 13 /* sizeof(\x{ hex of 32bit unsigned int } \0) */ + +/* + * call-seq: + * str.inspect -> string + * + * Returns a printable version of _str_, surrounded by quote marks, + * with special characters escaped. + * + * str = "hello" + * str[3] = "\b" + * str.inspect #=> "\"hel\\bo\"" + */ +mrb_value +mrb_str_inspect(mrb_state *mrb, mrb_value str) +{ + const char *p, *pend; + char buf[CHAR_ESC_LEN + 1]; + mrb_value result = mrb_str_new_lit(mrb, "\""); + + p = RSTRING_PTR(str); pend = RSTRING_END(str); + for (;p < pend; p++) { + unsigned char c, cc; +#ifdef MRB_UTF8_STRING + mrb_int clen; + + clen = utf8len(p, pend); + if (clen > 1) { + mrb_int i; + + for (i=0; i array of fixnums + * + * Returns an array of bytes in _str_. + * + * str = "hello" + * str.bytes #=> [104, 101, 108, 108, 111] + */ +static mrb_value +mrb_str_bytes(mrb_state *mrb, mrb_value str) +{ + struct RString *s = mrb_str_ptr(str); + mrb_value a = mrb_ary_new_capa(mrb, RSTR_LEN(s)); + unsigned char *p = (unsigned char *)(RSTR_PTR(s)), *pend = p + RSTR_LEN(s); + + while (p < pend) { + mrb_ary_push(mrb, a, mrb_fixnum_value(p[0])); + p++; + } + return a; +} + +/* ---------------------------*/ +void +mrb_init_string(mrb_state *mrb) +{ + struct RClass *s; + + mrb_static_assert(RSTRING_EMBED_LEN_MAX < (1 << 5), "pointer size too big for embedded string"); + + mrb->string_class = s = mrb_define_class(mrb, "String", mrb->object_class); /* 15.2.10 */ + MRB_SET_INSTANCE_TT(s, MRB_TT_STRING); + + mrb_define_method(mrb, s, "bytesize", mrb_str_bytesize, MRB_ARGS_NONE()); + + mrb_define_method(mrb, s, "<=>", mrb_str_cmp_m, MRB_ARGS_REQ(1)); /* 15.2.10.5.1 */ + mrb_define_method(mrb, s, "==", mrb_str_equal_m, MRB_ARGS_REQ(1)); /* 15.2.10.5.2 */ + mrb_define_method(mrb, s, "+", mrb_str_plus_m, MRB_ARGS_REQ(1)); /* 15.2.10.5.4 */ + mrb_define_method(mrb, s, "*", mrb_str_times, MRB_ARGS_REQ(1)); /* 15.2.10.5.5 */ + mrb_define_method(mrb, s, "[]", mrb_str_aref_m, MRB_ARGS_ANY()); /* 15.2.10.5.6 */ + mrb_define_method(mrb, s, "capitalize", mrb_str_capitalize, MRB_ARGS_NONE()); /* 15.2.10.5.7 */ + mrb_define_method(mrb, s, "capitalize!", mrb_str_capitalize_bang, MRB_ARGS_NONE()); /* 15.2.10.5.8 */ + mrb_define_method(mrb, s, "chomp", mrb_str_chomp, MRB_ARGS_ANY()); /* 15.2.10.5.9 */ + mrb_define_method(mrb, s, "chomp!", mrb_str_chomp_bang, MRB_ARGS_ANY()); /* 15.2.10.5.10 */ + mrb_define_method(mrb, s, "chop", mrb_str_chop, MRB_ARGS_NONE()); /* 15.2.10.5.11 */ + mrb_define_method(mrb, s, "chop!", mrb_str_chop_bang, MRB_ARGS_NONE()); /* 15.2.10.5.12 */ + mrb_define_method(mrb, s, "downcase", mrb_str_downcase, MRB_ARGS_NONE()); /* 15.2.10.5.13 */ + mrb_define_method(mrb, s, "downcase!", mrb_str_downcase_bang, MRB_ARGS_NONE()); /* 15.2.10.5.14 */ + mrb_define_method(mrb, s, "empty?", mrb_str_empty_p, MRB_ARGS_NONE()); /* 15.2.10.5.16 */ + mrb_define_method(mrb, s, "eql?", mrb_str_eql, MRB_ARGS_REQ(1)); /* 15.2.10.5.17 */ + + mrb_define_method(mrb, s, "hash", mrb_str_hash_m, MRB_ARGS_NONE()); /* 15.2.10.5.20 */ + mrb_define_method(mrb, s, "include?", mrb_str_include, MRB_ARGS_REQ(1)); /* 15.2.10.5.21 */ + mrb_define_method(mrb, s, "index", mrb_str_index_m, MRB_ARGS_ANY()); /* 15.2.10.5.22 */ + mrb_define_method(mrb, s, "initialize", mrb_str_init, MRB_ARGS_REQ(1)); /* 15.2.10.5.23 */ + mrb_define_method(mrb, s, "initialize_copy", mrb_str_replace, MRB_ARGS_REQ(1)); /* 15.2.10.5.24 */ + mrb_define_method(mrb, s, "intern", mrb_str_intern, MRB_ARGS_NONE()); /* 15.2.10.5.25 */ + mrb_define_method(mrb, s, "length", mrb_str_size, MRB_ARGS_NONE()); /* 15.2.10.5.26 */ + mrb_define_method(mrb, s, "replace", mrb_str_replace, MRB_ARGS_REQ(1)); /* 15.2.10.5.28 */ + mrb_define_method(mrb, s, "reverse", mrb_str_reverse, MRB_ARGS_NONE()); /* 15.2.10.5.29 */ + mrb_define_method(mrb, s, "reverse!", mrb_str_reverse_bang, MRB_ARGS_NONE()); /* 15.2.10.5.30 */ + mrb_define_method(mrb, s, "rindex", mrb_str_rindex, MRB_ARGS_ANY()); /* 15.2.10.5.31 */ + mrb_define_method(mrb, s, "size", mrb_str_size, MRB_ARGS_NONE()); /* 15.2.10.5.33 */ + mrb_define_method(mrb, s, "slice", mrb_str_aref_m, MRB_ARGS_ANY()); /* 15.2.10.5.34 */ + mrb_define_method(mrb, s, "split", mrb_str_split_m, MRB_ARGS_ANY()); /* 15.2.10.5.35 */ + + mrb_define_method(mrb, s, "to_f", mrb_str_to_f, MRB_ARGS_NONE()); /* 15.2.10.5.38 */ + mrb_define_method(mrb, s, "to_i", mrb_str_to_i, MRB_ARGS_ANY()); /* 15.2.10.5.39 */ + mrb_define_method(mrb, s, "to_s", mrb_str_to_s, MRB_ARGS_NONE()); /* 15.2.10.5.40 */ + mrb_define_method(mrb, s, "to_str", mrb_str_to_s, MRB_ARGS_NONE()); + mrb_define_method(mrb, s, "to_sym", mrb_str_intern, MRB_ARGS_NONE()); /* 15.2.10.5.41 */ + mrb_define_method(mrb, s, "upcase", mrb_str_upcase, MRB_ARGS_NONE()); /* 15.2.10.5.42 */ + mrb_define_method(mrb, s, "upcase!", mrb_str_upcase_bang, MRB_ARGS_NONE()); /* 15.2.10.5.43 */ + mrb_define_method(mrb, s, "inspect", mrb_str_inspect, MRB_ARGS_NONE()); /* 15.2.10.5.46(x) */ + mrb_define_method(mrb, s, "bytes", mrb_str_bytes, MRB_ARGS_NONE()); +} + +/* + * Source code for the "strtod" library procedure. + * + * Copyright (c) 1988-1993 The Regents of the University of California. + * Copyright (c) 1994 Sun Microsystems, Inc. + * + * Permission to use, copy, modify, and distribute this + * software and its documentation for any purpose and without + * fee is hereby granted, provided that the above copyright + * notice appear in all copies. The University of California + * makes no representations about the suitability of this + * software for any purpose. It is provided "as is" without + * express or implied warranty. + * + * RCS: @(#) $Id: strtod.c 11708 2007-02-12 23:01:19Z shyouhei $ + */ + +#include +#include + +static const int maxExponent = 511; /* Largest possible base 10 exponent. Any + * exponent larger than this will already + * produce underflow or overflow, so there's + * no need to worry about additional digits. + */ +static const double powersOf10[] = {/* Table giving binary powers of 10. Entry */ + 10., /* is 10^2^i. Used to convert decimal */ + 100., /* exponents into floating-point numbers. */ + 1.0e4, + 1.0e8, + 1.0e16, + 1.0e32, + 1.0e64, + 1.0e128, + 1.0e256 +}; + +MRB_API double +mrb_float_read(const char *string, char **endPtr) +/* const char *string; A decimal ASCII floating-point number, + * optionally preceded by white space. + * Must have form "-I.FE-X", where I is the + * integer part of the mantissa, F is the + * fractional part of the mantissa, and X + * is the exponent. Either of the signs + * may be "+", "-", or omitted. Either I + * or F may be omitted, or both. The decimal + * point isn't necessary unless F is present. + * The "E" may actually be an "e". E and X + * may both be omitted (but not just one). + */ +/* char **endPtr; If non-NULL, store terminating character's + * address here. */ +{ + int sign, expSign = FALSE; + double fraction, dblExp; + const double *d; + register const char *p; + register int c; + int exp = 0; /* Exponent read from "EX" field. */ + int fracExp = 0; /* Exponent that derives from the fractional + * part. Under normal circumstatnces, it is + * the negative of the number of digits in F. + * However, if I is very long, the last digits + * of I get dropped (otherwise a long I with a + * large negative exponent could cause an + * unnecessary overflow on I alone). In this + * case, fracExp is incremented one for each + * dropped digit. */ + int mantSize; /* Number of digits in mantissa. */ + int decPt; /* Number of mantissa digits BEFORE decimal + * point. */ + const char *pExp; /* Temporarily holds location of exponent + * in string. */ + + /* + * Strip off leading blanks and check for a sign. + */ + + p = string; + while (isspace(*p)) { + p += 1; + } + if (*p == '-') { + sign = TRUE; + p += 1; + } + else { + if (*p == '+') { + p += 1; + } + sign = FALSE; + } + + /* + * Count the number of digits in the mantissa (including the decimal + * point), and also locate the decimal point. + */ + + decPt = -1; + for (mantSize = 0; ; mantSize += 1) + { + c = *p; + if (!isdigit(c)) { + if ((c != '.') || (decPt >= 0)) { + break; + } + decPt = mantSize; + } + p += 1; + } + + /* + * Now suck up the digits in the mantissa. Use two integers to + * collect 9 digits each (this is faster than using floating-point). + * If the mantissa has more than 18 digits, ignore the extras, since + * they can't affect the value anyway. + */ + + pExp = p; + p -= mantSize; + if (decPt < 0) { + decPt = mantSize; + } + else { + mantSize -= 1; /* One of the digits was the point. */ + } + if (mantSize > 18) { + if (decPt - 18 > 29999) { + fracExp = 29999; + } + else { + fracExp = decPt - 18; + } + mantSize = 18; + } + else { + fracExp = decPt - mantSize; + } + if (mantSize == 0) { + fraction = 0.0; + p = string; + goto done; + } + else { + int frac1, frac2; + frac1 = 0; + for ( ; mantSize > 9; mantSize -= 1) + { + c = *p; + p += 1; + if (c == '.') { + c = *p; + p += 1; + } + frac1 = 10*frac1 + (c - '0'); + } + frac2 = 0; + for (; mantSize > 0; mantSize -= 1) + { + c = *p; + p += 1; + if (c == '.') { + c = *p; + p += 1; + } + frac2 = 10*frac2 + (c - '0'); + } + fraction = (1.0e9 * frac1) + frac2; + } + + /* + * Skim off the exponent. + */ + + p = pExp; + if ((*p == 'E') || (*p == 'e')) { + p += 1; + if (*p == '-') { + expSign = TRUE; + p += 1; + } + else { + if (*p == '+') { + p += 1; + } + expSign = FALSE; + } + while (isdigit(*p)) { + exp = exp * 10 + (*p - '0'); + if (exp > 19999) { + exp = 19999; + } + p += 1; + } + } + if (expSign) { + exp = fracExp - exp; + } + else { + exp = fracExp + exp; + } + + /* + * Generate a floating-point number that represents the exponent. + * Do this by processing the exponent one bit at a time to combine + * many powers of 2 of 10. Then combine the exponent with the + * fraction. + */ + + if (exp < 0) { + expSign = TRUE; + exp = -exp; + } + else { + expSign = FALSE; + } + if (exp > maxExponent) { + exp = maxExponent; + errno = ERANGE; + } + dblExp = 1.0; + for (d = powersOf10; exp != 0; exp >>= 1, d += 1) { + if (exp & 01) { + dblExp *= *d; + } + } + if (expSign) { + fraction /= dblExp; + } + else { + fraction *= dblExp; + } + +done: + if (endPtr != NULL) { + *endPtr = (char *) p; + } + + if (sign) { + return -fraction; + } + return fraction; +} diff --git a/web/server/h2o/libh2o/deps/mruby/src/symbol.c b/web/server/h2o/libh2o/deps/mruby/src/symbol.c new file mode 100644 index 00000000..a3ab05c8 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/src/symbol.c @@ -0,0 +1,494 @@ +/* +** symbol.c - Symbol class +** +** See Copyright Notice in mruby.h +*/ + +#include +#include +#include +#include +#include +#include +#include + +/* ------------------------------------------------------ */ +typedef struct symbol_name { + mrb_bool lit : 1; + uint16_t len; + const char *name; +} symbol_name; + +static inline khint_t +sym_hash_func(mrb_state *mrb, mrb_sym s) +{ + khint_t h = 0; + size_t i, len = mrb->symtbl[s].len; + const char *p = mrb->symtbl[s].name; + + for (i=0; isymtbl[a].len == mrb->symtbl[b].len && memcmp(mrb->symtbl[a].name, mrb->symtbl[b].name, mrb->symtbl[a].len) == 0) + +KHASH_DECLARE(n2s, mrb_sym, mrb_sym, FALSE) +KHASH_DEFINE (n2s, mrb_sym, mrb_sym, FALSE, sym_hash_func, sym_hash_equal) +/* ------------------------------------------------------ */ + +static void +sym_validate_len(mrb_state *mrb, size_t len) +{ + if (len >= RITE_LV_NULL_MARK) { + mrb_raise(mrb, E_ARGUMENT_ERROR, "symbol length too long"); + } +} + +static mrb_sym +sym_intern(mrb_state *mrb, const char *name, size_t len, mrb_bool lit) +{ + khash_t(n2s) *h = mrb->name2sym; + symbol_name *sname = mrb->symtbl; /* symtbl[0] for working memory */ + khiter_t k; + mrb_sym sym; + char *p; + + sym_validate_len(mrb, len); + if (sname) { + sname->lit = lit; + sname->len = (uint16_t)len; + sname->name = name; + k = kh_get(n2s, mrb, h, 0); + if (k != kh_end(h)) + return kh_key(h, k); + } + + /* registering a new symbol */ + sym = ++mrb->symidx; + if (mrb->symcapa < sym) { + if (mrb->symcapa == 0) mrb->symcapa = 100; + else mrb->symcapa = (size_t)(mrb->symcapa * 1.2); + mrb->symtbl = (symbol_name*)mrb_realloc(mrb, mrb->symtbl, sizeof(symbol_name)*(mrb->symcapa+1)); + } + sname = &mrb->symtbl[sym]; + sname->len = (uint16_t)len; + if (lit || mrb_ro_data_p(name)) { + sname->name = name; + sname->lit = TRUE; + } + else { + p = (char *)mrb_malloc(mrb, len+1); + memcpy(p, name, len); + p[len] = 0; + sname->name = (const char*)p; + sname->lit = FALSE; + } + kh_put(n2s, mrb, h, sym); + + return sym; +} + +MRB_API mrb_sym +mrb_intern(mrb_state *mrb, const char *name, size_t len) +{ + return sym_intern(mrb, name, len, FALSE); +} + +MRB_API mrb_sym +mrb_intern_static(mrb_state *mrb, const char *name, size_t len) +{ + return sym_intern(mrb, name, len, TRUE); +} + +MRB_API mrb_sym +mrb_intern_cstr(mrb_state *mrb, const char *name) +{ + return mrb_intern(mrb, name, strlen(name)); +} + +MRB_API mrb_sym +mrb_intern_str(mrb_state *mrb, mrb_value str) +{ + return mrb_intern(mrb, RSTRING_PTR(str), RSTRING_LEN(str)); +} + +MRB_API mrb_value +mrb_check_intern(mrb_state *mrb, const char *name, size_t len) +{ + khash_t(n2s) *h = mrb->name2sym; + symbol_name *sname = mrb->symtbl; + khiter_t k; + + sym_validate_len(mrb, len); + sname->len = (uint16_t)len; + sname->name = name; + + k = kh_get(n2s, mrb, h, 0); + if (k != kh_end(h)) { + return mrb_symbol_value(kh_key(h, k)); + } + return mrb_nil_value(); +} + +MRB_API mrb_value +mrb_check_intern_cstr(mrb_state *mrb, const char *name) +{ + return mrb_check_intern(mrb, name, (mrb_int)strlen(name)); +} + +MRB_API mrb_value +mrb_check_intern_str(mrb_state *mrb, mrb_value str) +{ + return mrb_check_intern(mrb, RSTRING_PTR(str), RSTRING_LEN(str)); +} + +/* lenp must be a pointer to a size_t variable */ +MRB_API const char* +mrb_sym2name_len(mrb_state *mrb, mrb_sym sym, mrb_int *lenp) +{ + if (sym == 0 || mrb->symidx < sym) { + if (lenp) *lenp = 0; + return NULL; + } + + if (lenp) *lenp = mrb->symtbl[sym].len; + return mrb->symtbl[sym].name; +} + +void +mrb_free_symtbl(mrb_state *mrb) +{ + mrb_sym i, lim; + + for (i=1, lim=mrb->symidx+1; isymtbl[i].lit) { + mrb_free(mrb, (char*)mrb->symtbl[i].name); + } + } + mrb_free(mrb, mrb->symtbl); + kh_destroy(n2s, mrb, mrb->name2sym); +} + +void +mrb_init_symtbl(mrb_state *mrb) +{ + mrb->name2sym = kh_init(n2s, mrb); +} + +/********************************************************************** + * Document-class: Symbol + * + * Symbol objects represent names and some strings + * inside the Ruby + * interpreter. They are generated using the :name and + * :"string" literals + * syntax, and by the various to_sym methods. The same + * Symbol object will be created for a given name or string + * for the duration of a program's execution, regardless of the context + * or meaning of that name. Thus if Fred is a constant in + * one context, a method in another, and a class in a third, the + * Symbol :Fred will be the same object in + * all three contexts. + * + * module One + * class Fred + * end + * $f1 = :Fred + * end + * module Two + * Fred = 1 + * $f2 = :Fred + * end + * def Fred() + * end + * $f3 = :Fred + * $f1.object_id #=> 2514190 + * $f2.object_id #=> 2514190 + * $f3.object_id #=> 2514190 + * + */ + + +/* 15.2.11.3.1 */ +/* + * call-seq: + * sym == obj -> true or false + * + * Equality---If sym and obj are exactly the same + * symbol, returns true. + */ + +static mrb_value +sym_equal(mrb_state *mrb, mrb_value sym1) +{ + mrb_value sym2; + + mrb_get_args(mrb, "o", &sym2); + + return mrb_bool_value(mrb_obj_equal(mrb, sym1, sym2)); +} + +/* 15.2.11.3.2 */ +/* 15.2.11.3.3 */ +/* + * call-seq: + * sym.id2name -> string + * sym.to_s -> string + * + * Returns the name or string corresponding to sym. + * + * :fred.id2name #=> "fred" + */ +static mrb_value +mrb_sym_to_s(mrb_state *mrb, mrb_value sym) +{ + mrb_sym id = mrb_symbol(sym); + const char *p; + mrb_int len; + + p = mrb_sym2name_len(mrb, id, &len); + return mrb_str_new_static(mrb, p, len); +} + +/* 15.2.11.3.4 */ +/* + * call-seq: + * sym.to_sym -> sym + * sym.intern -> sym + * + * In general, to_sym returns the Symbol corresponding + * to an object. As sym is already a symbol, self is returned + * in this case. + */ + +static mrb_value +sym_to_sym(mrb_state *mrb, mrb_value sym) +{ + return sym; +} + +/* 15.2.11.3.5(x) */ +/* + * call-seq: + * sym.inspect -> string + * + * Returns the representation of sym as a symbol literal. + * + * :fred.inspect #=> ":fred" + */ + +#if __STDC__ +# define SIGN_EXTEND_CHAR(c) ((signed char)(c)) +#else /* not __STDC__ */ +/* As in Harbison and Steele. */ +# define SIGN_EXTEND_CHAR(c) ((((unsigned char)(c)) ^ 128) - 128) +#endif +#define is_identchar(c) (SIGN_EXTEND_CHAR(c)!=-1&&(ISALNUM(c) || (c) == '_')) + +static mrb_bool +is_special_global_name(const char* m) +{ + switch (*m) { + case '~': case '*': case '$': case '?': case '!': case '@': + case '/': case '\\': case ';': case ',': case '.': case '=': + case ':': case '<': case '>': case '\"': + case '&': case '`': case '\'': case '+': + case '0': + ++m; + break; + case '-': + ++m; + if (is_identchar(*m)) m += 1; + break; + default: + if (!ISDIGIT(*m)) return FALSE; + do ++m; while (ISDIGIT(*m)); + break; + } + return !*m; +} + +static mrb_bool +symname_p(const char *name) +{ + const char *m = name; + mrb_bool localid = FALSE; + + if (!m) return FALSE; + switch (*m) { + case '\0': + return FALSE; + + case '$': + if (is_special_global_name(++m)) return TRUE; + goto id; + + case '@': + if (*++m == '@') ++m; + goto id; + + case '<': + switch (*++m) { + case '<': ++m; break; + case '=': if (*++m == '>') ++m; break; + default: break; + } + break; + + case '>': + switch (*++m) { + case '>': case '=': ++m; break; + default: break; + } + break; + + case '=': + switch (*++m) { + case '~': ++m; break; + case '=': if (*++m == '=') ++m; break; + default: return FALSE; + } + break; + + case '*': + if (*++m == '*') ++m; + break; + case '!': + switch (*++m) { + case '=': case '~': ++m; + } + break; + case '+': case '-': + if (*++m == '@') ++m; + break; + case '|': + if (*++m == '|') ++m; + break; + case '&': + if (*++m == '&') ++m; + break; + + case '^': case '/': case '%': case '~': case '`': + ++m; + break; + + case '[': + if (*++m != ']') return FALSE; + if (*++m == '=') ++m; + break; + + default: + localid = !ISUPPER(*m); +id: + if (*m != '_' && !ISALPHA(*m)) return FALSE; + while (is_identchar(*m)) m += 1; + if (localid) { + switch (*m) { + case '!': case '?': case '=': ++m; + default: break; + } + } + break; + } + return *m ? FALSE : TRUE; +} + +static mrb_value +sym_inspect(mrb_state *mrb, mrb_value sym) +{ + mrb_value str; + const char *name; + mrb_int len; + mrb_sym id = mrb_symbol(sym); + char *sp; + + name = mrb_sym2name_len(mrb, id, &len); + str = mrb_str_new(mrb, 0, len+1); + sp = RSTRING_PTR(str); + RSTRING_PTR(str)[0] = ':'; + memcpy(sp+1, name, len); + mrb_assert_int_fit(mrb_int, len, size_t, SIZE_MAX); + if (!symname_p(name) || strlen(name) != (size_t)len) { + str = mrb_str_dump(mrb, str); + sp = RSTRING_PTR(str); + sp[0] = ':'; + sp[1] = '"'; + } + return str; +} + +MRB_API mrb_value +mrb_sym2str(mrb_state *mrb, mrb_sym sym) +{ + mrb_int len; + const char *name = mrb_sym2name_len(mrb, sym, &len); + + if (!name) return mrb_undef_value(); /* can't happen */ + return mrb_str_new_static(mrb, name, len); +} + +MRB_API const char* +mrb_sym2name(mrb_state *mrb, mrb_sym sym) +{ + mrb_int len; + const char *name = mrb_sym2name_len(mrb, sym, &len); + + if (!name) return NULL; + if (symname_p(name) && strlen(name) == (size_t)len) { + return name; + } + else { + mrb_value str = mrb_str_dump(mrb, mrb_str_new_static(mrb, name, len)); + return RSTRING_PTR(str); + } +} + +#define lesser(a,b) (((a)>(b))?(b):(a)) + +static mrb_value +sym_cmp(mrb_state *mrb, mrb_value s1) +{ + mrb_value s2; + mrb_sym sym1, sym2; + + mrb_get_args(mrb, "o", &s2); + if (mrb_type(s2) != MRB_TT_SYMBOL) return mrb_nil_value(); + sym1 = mrb_symbol(s1); + sym2 = mrb_symbol(s2); + if (sym1 == sym2) return mrb_fixnum_value(0); + else { + const char *p1, *p2; + int retval; + mrb_int len, len1, len2; + + p1 = mrb_sym2name_len(mrb, sym1, &len1); + p2 = mrb_sym2name_len(mrb, sym2, &len2); + len = lesser(len1, len2); + retval = memcmp(p1, p2, len); + if (retval == 0) { + if (len1 == len2) return mrb_fixnum_value(0); + if (len1 > len2) return mrb_fixnum_value(1); + return mrb_fixnum_value(-1); + } + if (retval > 0) return mrb_fixnum_value(1); + return mrb_fixnum_value(-1); + } +} + +void +mrb_init_symbol(mrb_state *mrb) +{ + struct RClass *sym; + + mrb->symbol_class = sym = mrb_define_class(mrb, "Symbol", mrb->object_class); /* 15.2.11 */ + MRB_SET_INSTANCE_TT(sym, MRB_TT_SYMBOL); + mrb_undef_class_method(mrb, sym, "new"); + + mrb_define_method(mrb, sym, "===", sym_equal, MRB_ARGS_REQ(1)); /* 15.2.11.3.1 */ + mrb_define_method(mrb, sym, "id2name", mrb_sym_to_s, MRB_ARGS_NONE()); /* 15.2.11.3.2 */ + mrb_define_method(mrb, sym, "to_s", mrb_sym_to_s, MRB_ARGS_NONE()); /* 15.2.11.3.3 */ + mrb_define_method(mrb, sym, "to_sym", sym_to_sym, MRB_ARGS_NONE()); /* 15.2.11.3.4 */ + mrb_define_method(mrb, sym, "inspect", sym_inspect, MRB_ARGS_NONE()); /* 15.2.11.3.5(x) */ + mrb_define_method(mrb, sym, "<=>", sym_cmp, MRB_ARGS_REQ(1)); +} diff --git a/web/server/h2o/libh2o/deps/mruby/src/value_array.h b/web/server/h2o/libh2o/deps/mruby/src/value_array.h new file mode 100644 index 00000000..bc5f28b0 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/src/value_array.h @@ -0,0 +1,27 @@ +#ifndef MRB_VALUE_ARRAY_H__ +#define MRB_VALUE_ARRAY_H__ + +#include + +static inline void +value_move(mrb_value *s1, const mrb_value *s2, size_t n) +{ + if (s1 > s2 && s1 < s2 + n) + { + s1 += n; + s2 += n; + while (n-- > 0) { + *--s1 = *--s2; + } + } + else if (s1 != s2) { + while (n-- > 0) { + *s1++ = *s2++; + } + } + else { + /* nothing to do. */ + } +} + +#endif /* MRB_VALUE_ARRAY_H__ */ diff --git a/web/server/h2o/libh2o/deps/mruby/src/variable.c b/web/server/h2o/libh2o/deps/mruby/src/variable.c new file mode 100644 index 00000000..50fc7068 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/src/variable.c @@ -0,0 +1,987 @@ +/* +** variable.c - mruby variables +** +** See Copyright Notice in mruby.h +*/ + +#include +#include +#include +#include +#include + +typedef int (iv_foreach_func)(mrb_state*,mrb_sym,mrb_value,void*); + +#include + +#ifndef MRB_IVHASH_INIT_SIZE +#define MRB_IVHASH_INIT_SIZE KHASH_MIN_SIZE +#endif + +KHASH_DECLARE(iv, mrb_sym, mrb_value, TRUE) +KHASH_DEFINE(iv, mrb_sym, mrb_value, TRUE, kh_int_hash_func, kh_int_hash_equal) + +/* Instance variable table structure */ +typedef struct iv_tbl { + khash_t(iv) h; +} iv_tbl; + +/* + * Creates the instance variable table. + * + * Parameters + * mrb + * Returns + * the instance variable table. + */ +static iv_tbl* +iv_new(mrb_state *mrb) +{ + return (iv_tbl*)kh_init_size(iv, mrb, MRB_IVHASH_INIT_SIZE); +} + +/* + * Set the value for the symbol in the instance variable table. + * + * Parameters + * mrb + * t the instance variable table to be set in. + * sym the symbol to be used as the key. + * val the value to be set. + */ +static void +iv_put(mrb_state *mrb, iv_tbl *t, mrb_sym sym, mrb_value val) +{ + khash_t(iv) *h = &t->h; + khiter_t k; + + k = kh_put(iv, mrb, h, sym); + kh_value(h, k) = val; +} + +/* + * Get a value for a symbol from the instance variable table. + * + * Parameters + * mrb + * t the variable table to be searched. + * sym the symbol to be used as the key. + * vp the value pointer. Receives the value if the specified symbol is + * contained in the instance variable table. + * Returns + * true if the specified symbol is contained in the instance variable table. + */ +static mrb_bool +iv_get(mrb_state *mrb, iv_tbl *t, mrb_sym sym, mrb_value *vp) +{ + khash_t(iv) *h = &t->h; + khiter_t k; + + k = kh_get(iv, mrb, h, sym); + if (k != kh_end(h)) { + if (vp) *vp = kh_value(h, k); + return TRUE; + } + return FALSE; +} + +/* + * Deletes the value for the symbol from the instance variable table. + * + * Parameters + * t the variable table to be searched. + * sym the symbol to be used as the key. + * vp the value pointer. Receive the deleted value if the symbol is + * contained in the instance variable table. + * Returns + * true if the specified symbol is contained in the instance variable table. + */ +static mrb_bool +iv_del(mrb_state *mrb, iv_tbl *t, mrb_sym sym, mrb_value *vp) +{ + if (t == NULL) return FALSE; + else { + khash_t(iv) *h = &t->h; + khiter_t k; + + k = kh_get(iv, mrb, h, sym); + if (k != kh_end(h)) { + mrb_value val = kh_value(h, k); + kh_del(iv, mrb, h, k); + if (vp) *vp = val; + return TRUE; + } + } + return FALSE; +} + +static mrb_bool +iv_foreach(mrb_state *mrb, iv_tbl *t, iv_foreach_func *func, void *p) +{ + if (t == NULL) { + return TRUE; + } + else { + khash_t(iv) *h = &t->h; + khiter_t k; + int n; + + for (k = kh_begin(h); k != kh_end(h); k++) { + if (kh_exist(h, k)) { + n = (*func)(mrb, kh_key(h, k), kh_value(h, k), p); + if (n > 0) return FALSE; + if (n < 0) { + kh_del(iv, mrb, h, k); + } + } + } + } + return TRUE; +} + +static size_t +iv_size(mrb_state *mrb, iv_tbl *t) +{ + if (t) { + return kh_size(&t->h); + } + return 0; +} + +static iv_tbl* +iv_copy(mrb_state *mrb, iv_tbl *t) +{ + return (iv_tbl*)kh_copy(iv, mrb, &t->h); +} + +static void +iv_free(mrb_state *mrb, iv_tbl *t) +{ + kh_destroy(iv, mrb, &t->h); +} + +static int +iv_mark_i(mrb_state *mrb, mrb_sym sym, mrb_value v, void *p) +{ + mrb_gc_mark_value(mrb, v); + return 0; +} + +static void +mark_tbl(mrb_state *mrb, iv_tbl *t) +{ + if (t) { + iv_foreach(mrb, t, iv_mark_i, 0); + } +} + +void +mrb_gc_mark_gv(mrb_state *mrb) +{ + mark_tbl(mrb, mrb->globals); +} + +void +mrb_gc_free_gv(mrb_state *mrb) +{ + if (mrb->globals) + iv_free(mrb, mrb->globals); +} + +void +mrb_gc_mark_iv(mrb_state *mrb, struct RObject *obj) +{ + mark_tbl(mrb, obj->iv); +} + +size_t +mrb_gc_mark_iv_size(mrb_state *mrb, struct RObject *obj) +{ + return iv_size(mrb, obj->iv); +} + +void +mrb_gc_free_iv(mrb_state *mrb, struct RObject *obj) +{ + if (obj->iv) { + iv_free(mrb, obj->iv); + } +} + +mrb_value +mrb_vm_special_get(mrb_state *mrb, mrb_sym i) +{ + return mrb_fixnum_value(0); +} + +void +mrb_vm_special_set(mrb_state *mrb, mrb_sym i, mrb_value v) +{ +} + +static mrb_bool +obj_iv_p(mrb_value obj) +{ + switch (mrb_type(obj)) { + case MRB_TT_OBJECT: + case MRB_TT_CLASS: + case MRB_TT_MODULE: + case MRB_TT_SCLASS: + case MRB_TT_HASH: + case MRB_TT_DATA: + case MRB_TT_EXCEPTION: + return TRUE; + default: + return FALSE; + } +} + +MRB_API mrb_value +mrb_obj_iv_get(mrb_state *mrb, struct RObject *obj, mrb_sym sym) +{ + mrb_value v; + + if (obj->iv && iv_get(mrb, obj->iv, sym, &v)) + return v; + return mrb_nil_value(); +} + +MRB_API mrb_value +mrb_iv_get(mrb_state *mrb, mrb_value obj, mrb_sym sym) +{ + if (obj_iv_p(obj)) { + return mrb_obj_iv_get(mrb, mrb_obj_ptr(obj), sym); + } + return mrb_nil_value(); +} + +MRB_API void +mrb_obj_iv_set(mrb_state *mrb, struct RObject *obj, mrb_sym sym, mrb_value v) +{ + iv_tbl *t = obj->iv; + + if (MRB_FROZEN_P(obj)) { + mrb_raisef(mrb, E_RUNTIME_ERROR, "can't modify frozen %S", mrb_obj_value(obj)); + } + if (!t) { + t = obj->iv = iv_new(mrb); + } + mrb_write_barrier(mrb, (struct RBasic*)obj); + iv_put(mrb, t, sym, v); +} + +MRB_API void +mrb_iv_set(mrb_state *mrb, mrb_value obj, mrb_sym sym, mrb_value v) +{ + if (obj_iv_p(obj)) { + mrb_obj_iv_set(mrb, mrb_obj_ptr(obj), sym, v); + } + else { + mrb_raise(mrb, E_ARGUMENT_ERROR, "cannot set instance variable"); + } +} + +MRB_API mrb_bool +mrb_obj_iv_defined(mrb_state *mrb, struct RObject *obj, mrb_sym sym) +{ + iv_tbl *t; + + t = obj->iv; + if (t) { + return iv_get(mrb, t, sym, NULL); + } + return FALSE; +} + +MRB_API mrb_bool +mrb_iv_defined(mrb_state *mrb, mrb_value obj, mrb_sym sym) +{ + if (!obj_iv_p(obj)) return FALSE; + return mrb_obj_iv_defined(mrb, mrb_obj_ptr(obj), sym); +} + +#define identchar(c) (ISALNUM(c) || (c) == '_' || !ISASCII(c)) + +MRB_API mrb_bool +mrb_iv_p(mrb_state *mrb, mrb_sym iv_name) +{ + const char *s; + mrb_int i, len; + + s = mrb_sym2name_len(mrb, iv_name, &len); + if (len < 2) return FALSE; + if (s[0] != '@') return FALSE; + if (s[1] == '@') return FALSE; + for (i=1; iiv) { + iv_free(mrb, d->iv); + d->iv = 0; + } + if (s->iv) { + mrb_write_barrier(mrb, (struct RBasic*)d); + d->iv = iv_copy(mrb, s->iv); + } +} + +static int +inspect_i(mrb_state *mrb, mrb_sym sym, mrb_value v, void *p) +{ + mrb_value str = *(mrb_value*)p; + const char *s; + mrb_int len; + mrb_value ins; + char *sp = RSTRING_PTR(str); + + /* need not to show internal data */ + if (sp[0] == '-') { /* first element */ + sp[0] = '#'; + mrb_str_cat_lit(mrb, str, " "); + } + else { + mrb_str_cat_lit(mrb, str, ", "); + } + s = mrb_sym2name_len(mrb, sym, &len); + mrb_str_cat(mrb, str, s, len); + mrb_str_cat_lit(mrb, str, "="); + if (mrb_type(v) == MRB_TT_OBJECT) { + ins = mrb_any_to_s(mrb, v); + } + else { + ins = mrb_inspect(mrb, v); + } + mrb_str_cat_str(mrb, str, ins); + return 0; +} + +mrb_value +mrb_obj_iv_inspect(mrb_state *mrb, struct RObject *obj) +{ + iv_tbl *t = obj->iv; + size_t len = iv_size(mrb, t); + + if (len > 0) { + const char *cn = mrb_obj_classname(mrb, mrb_obj_value(obj)); + mrb_value str = mrb_str_new_capa(mrb, 30); + + mrb_str_cat_lit(mrb, str, "-<"); + mrb_str_cat_cstr(mrb, str, cn); + mrb_str_cat_lit(mrb, str, ":"); + mrb_str_concat(mrb, str, mrb_ptr_to_str(mrb, obj)); + + iv_foreach(mrb, t, inspect_i, &str); + mrb_str_cat_lit(mrb, str, ">"); + return str; + } + return mrb_any_to_s(mrb, mrb_obj_value(obj)); +} + +MRB_API mrb_value +mrb_iv_remove(mrb_state *mrb, mrb_value obj, mrb_sym sym) +{ + if (obj_iv_p(obj)) { + iv_tbl *t = mrb_obj_ptr(obj)->iv; + mrb_value val; + + if (t && iv_del(mrb, t, sym, &val)) { + return val; + } + } + return mrb_undef_value(); +} + +mrb_value +mrb_vm_iv_get(mrb_state *mrb, mrb_sym sym) +{ + /* get self */ + return mrb_iv_get(mrb, mrb->c->stack[0], sym); +} + +void +mrb_vm_iv_set(mrb_state *mrb, mrb_sym sym, mrb_value v) +{ + /* get self */ + mrb_iv_set(mrb, mrb->c->stack[0], sym, v); +} + +static int +iv_i(mrb_state *mrb, mrb_sym sym, mrb_value v, void *p) +{ + mrb_value ary; + const char* s; + mrb_int len; + + ary = *(mrb_value*)p; + s = mrb_sym2name_len(mrb, sym, &len); + if (len > 1 && s[0] == '@' && s[1] != '@') { + mrb_ary_push(mrb, ary, mrb_symbol_value(sym)); + } + return 0; +} + +/* 15.3.1.3.23 */ +/* + * call-seq: + * obj.instance_variables -> array + * + * Returns an array of instance variable names for the receiver. Note + * that simply defining an accessor does not create the corresponding + * instance variable. + * + * class Fred + * attr_accessor :a1 + * def initialize + * @iv = 3 + * end + * end + * Fred.new.instance_variables #=> [:@iv] + */ +mrb_value +mrb_obj_instance_variables(mrb_state *mrb, mrb_value self) +{ + mrb_value ary; + + ary = mrb_ary_new(mrb); + if (obj_iv_p(self) && mrb_obj_ptr(self)->iv) { + iv_foreach(mrb, mrb_obj_ptr(self)->iv, iv_i, &ary); + } + return ary; +} + +static int +cv_i(mrb_state *mrb, mrb_sym sym, mrb_value v, void *p) +{ + mrb_value ary; + const char* s; + mrb_int len; + + ary = *(mrb_value*)p; + s = mrb_sym2name_len(mrb, sym, &len); + if (len > 2 && s[0] == '@' && s[1] == '@') { + mrb_ary_push(mrb, ary, mrb_symbol_value(sym)); + } + return 0; +} + +/* 15.2.2.4.19 */ +/* + * call-seq: + * mod.class_variables -> array + * + * Returns an array of the names of class variables in mod. + * + * class One + * @@var1 = 1 + * end + * class Two < One + * @@var2 = 2 + * end + * One.class_variables #=> [:@@var1] + * Two.class_variables #=> [:@@var2] + */ +mrb_value +mrb_mod_class_variables(mrb_state *mrb, mrb_value mod) +{ + mrb_value ary; + struct RClass *c; + + ary = mrb_ary_new(mrb); + c = mrb_class_ptr(mod); + while (c) { + if (c->iv) { + iv_foreach(mrb, c->iv, cv_i, &ary); + } + c = c->super; + } + return ary; +} + +MRB_API mrb_value +mrb_mod_cv_get(mrb_state *mrb, struct RClass *c, mrb_sym sym) +{ + struct RClass * cls = c; + mrb_value v; + int given = FALSE; + + while (c) { + if (c->iv && iv_get(mrb, c->iv, sym, &v)) { + given = TRUE; + } + c = c->super; + } + if (given) return v; + if (cls && cls->tt == MRB_TT_SCLASS) { + mrb_value klass; + + klass = mrb_obj_iv_get(mrb, (struct RObject *)cls, + mrb_intern_lit(mrb, "__attached__")); + c = mrb_class_ptr(klass); + if (c->tt == MRB_TT_CLASS || c->tt == MRB_TT_MODULE) { + given = FALSE; + while (c) { + if (c->iv && iv_get(mrb, c->iv, sym, &v)) { + given = TRUE; + } + c = c->super; + } + if (given) return v; + } + } + mrb_name_error(mrb, sym, "uninitialized class variable %S in %S", + mrb_sym2str(mrb, sym), mrb_obj_value(cls)); + /* not reached */ + return mrb_nil_value(); +} + +MRB_API mrb_value +mrb_cv_get(mrb_state *mrb, mrb_value mod, mrb_sym sym) +{ + return mrb_mod_cv_get(mrb, mrb_class_ptr(mod), sym); +} + +MRB_API void +mrb_mod_cv_set(mrb_state *mrb, struct RClass *c, mrb_sym sym, mrb_value v) +{ + struct RClass * cls = c; + + while (c) { + if (c->iv) { + iv_tbl *t = c->iv; + + if (iv_get(mrb, t, sym, NULL)) { + mrb_write_barrier(mrb, (struct RBasic*)c); + iv_put(mrb, t, sym, v); + return; + } + } + c = c->super; + } + + if (cls && cls->tt == MRB_TT_SCLASS) { + mrb_value klass; + + klass = mrb_obj_iv_get(mrb, (struct RObject*)cls, + mrb_intern_lit(mrb, "__attached__")); + switch (mrb_type(klass)) { + case MRB_TT_CLASS: + case MRB_TT_MODULE: + case MRB_TT_SCLASS: + c = mrb_class_ptr(klass); + break; + default: + c = cls; + break; + } + } + else{ + c = cls; + } + + if (!c->iv) { + c->iv = iv_new(mrb); + } + + mrb_write_barrier(mrb, (struct RBasic*)c); + iv_put(mrb, c->iv, sym, v); +} + +MRB_API void +mrb_cv_set(mrb_state *mrb, mrb_value mod, mrb_sym sym, mrb_value v) +{ + mrb_mod_cv_set(mrb, mrb_class_ptr(mod), sym, v); +} + +MRB_API mrb_bool +mrb_mod_cv_defined(mrb_state *mrb, struct RClass * c, mrb_sym sym) +{ + while (c) { + if (c->iv) { + iv_tbl *t = c->iv; + if (iv_get(mrb, t, sym, NULL)) return TRUE; + } + c = c->super; + } + + return FALSE; +} + +MRB_API mrb_bool +mrb_cv_defined(mrb_state *mrb, mrb_value mod, mrb_sym sym) +{ + return mrb_mod_cv_defined(mrb, mrb_class_ptr(mod), sym); +} + +mrb_value +mrb_vm_cv_get(mrb_state *mrb, mrb_sym sym) +{ + struct RClass *c = mrb->c->ci->proc->target_class; + + if (!c) c = mrb->c->ci->target_class; + + return mrb_mod_cv_get(mrb, c, sym); +} + +void +mrb_vm_cv_set(mrb_state *mrb, mrb_sym sym, mrb_value v) +{ + struct RClass *c = mrb->c->ci->proc->target_class; + + if (!c) c = mrb->c->ci->target_class; + mrb_mod_cv_set(mrb, c, sym, v); +} + +static void +mod_const_check(mrb_state *mrb, mrb_value mod) +{ + switch (mrb_type(mod)) { + case MRB_TT_CLASS: + case MRB_TT_MODULE: + case MRB_TT_SCLASS: + break; + default: + mrb_raise(mrb, E_TYPE_ERROR, "constant look-up for non class/module"); + break; + } +} + +static mrb_value +const_get(mrb_state *mrb, struct RClass *base, mrb_sym sym) +{ + struct RClass *c = base; + mrb_value v; + iv_tbl *t; + mrb_bool retry = FALSE; + mrb_value name; + +L_RETRY: + while (c) { + if (c->iv) { + t = c->iv; + if (iv_get(mrb, t, sym, &v)) + return v; + } + c = c->super; + } + if (!retry && base && base->tt == MRB_TT_MODULE) { + c = mrb->object_class; + retry = TRUE; + goto L_RETRY; + } + name = mrb_symbol_value(sym); + return mrb_funcall_argv(mrb, mrb_obj_value(base), mrb_intern_lit(mrb, "const_missing"), 1, &name); +} + +MRB_API mrb_value +mrb_const_get(mrb_state *mrb, mrb_value mod, mrb_sym sym) +{ + mod_const_check(mrb, mod); + return const_get(mrb, mrb_class_ptr(mod), sym); +} + +mrb_value +mrb_vm_const_get(mrb_state *mrb, mrb_sym sym) +{ + struct RClass *c = mrb->c->ci->proc->target_class; + struct RClass *c2; + mrb_value v; + mrb_irep *irep; + + if (!c) c = mrb->c->ci->target_class; + mrb_assert(c != NULL); + + if (c->iv && iv_get(mrb, c->iv, sym, &v)) { + return v; + } + c2 = c; + while (c2 && c2->tt == MRB_TT_SCLASS) { + mrb_value klass; + klass = mrb_obj_iv_get(mrb, (struct RObject *)c2, + mrb_intern_lit(mrb, "__attached__")); + c2 = mrb_class_ptr(klass); + } + if (c2->tt == MRB_TT_CLASS || c2->tt == MRB_TT_MODULE) c = c2; + mrb_assert(!MRB_PROC_CFUNC_P(mrb->c->ci->proc)); + irep = mrb->c->ci->proc->body.irep; + while (irep) { + if (irep->target_class) { + c2 = irep->target_class; + if (c2->iv && iv_get(mrb, c2->iv, sym, &v)) { + return v; + } + } + irep = irep->outer; + } + return const_get(mrb, c, sym); +} + +MRB_API void +mrb_const_set(mrb_state *mrb, mrb_value mod, mrb_sym sym, mrb_value v) +{ + mod_const_check(mrb, mod); + if (mrb_type(v) == MRB_TT_CLASS || mrb_type(v) == MRB_TT_MODULE) { + mrb_class_name_class(mrb, mrb_class_ptr(mod), mrb_class_ptr(v), sym); + } + mrb_iv_set(mrb, mod, sym, v); +} + +void +mrb_vm_const_set(mrb_state *mrb, mrb_sym sym, mrb_value v) +{ + struct RClass *c = mrb->c->ci->proc->target_class; + + if (!c) c = mrb->c->ci->target_class; + mrb_obj_iv_set(mrb, (struct RObject*)c, sym, v); +} + +MRB_API void +mrb_const_remove(mrb_state *mrb, mrb_value mod, mrb_sym sym) +{ + mod_const_check(mrb, mod); + mrb_iv_remove(mrb, mod, sym); +} + +MRB_API void +mrb_define_const(mrb_state *mrb, struct RClass *mod, const char *name, mrb_value v) +{ + mrb_obj_iv_set(mrb, (struct RObject*)mod, mrb_intern_cstr(mrb, name), v); +} + +MRB_API void +mrb_define_global_const(mrb_state *mrb, const char *name, mrb_value val) +{ + mrb_define_const(mrb, mrb->object_class, name, val); +} + +static int +const_i(mrb_state *mrb, mrb_sym sym, mrb_value v, void *p) +{ + mrb_value ary; + const char* s; + mrb_int len; + + ary = *(mrb_value*)p; + s = mrb_sym2name_len(mrb, sym, &len); + if (len >= 1 && ISUPPER(s[0])) { + mrb_ary_push(mrb, ary, mrb_symbol_value(sym)); + } + return 0; +} + +/* 15.2.2.4.24 */ +/* + * call-seq: + * mod.constants -> array + * + * Returns an array of all names of contants defined in the receiver. + */ +mrb_value +mrb_mod_constants(mrb_state *mrb, mrb_value mod) +{ + mrb_value ary; + mrb_bool inherit = TRUE; + struct RClass *c = mrb_class_ptr(mod); + + mrb_get_args(mrb, "|b", &inherit); + ary = mrb_ary_new(mrb); + while (c) { + if (c->iv) { + iv_foreach(mrb, c->iv, const_i, &ary); + } + if (!inherit) break; + c = c->super; + if (c == mrb->object_class) break; + } + return ary; +} + +MRB_API mrb_value +mrb_gv_get(mrb_state *mrb, mrb_sym sym) +{ + mrb_value v; + + if (!mrb->globals) { + return mrb_nil_value(); + } + if (iv_get(mrb, mrb->globals, sym, &v)) + return v; + return mrb_nil_value(); +} + +MRB_API void +mrb_gv_set(mrb_state *mrb, mrb_sym sym, mrb_value v) +{ + iv_tbl *t; + + if (!mrb->globals) { + t = mrb->globals = iv_new(mrb); + } + else { + t = mrb->globals; + } + iv_put(mrb, t, sym, v); +} + +MRB_API void +mrb_gv_remove(mrb_state *mrb, mrb_sym sym) +{ + if (!mrb->globals) { + return; + } + iv_del(mrb, mrb->globals, sym, NULL); +} + +static int +gv_i(mrb_state *mrb, mrb_sym sym, mrb_value v, void *p) +{ + mrb_value ary; + + ary = *(mrb_value*)p; + mrb_ary_push(mrb, ary, mrb_symbol_value(sym)); + return 0; +} + +/* 15.3.1.2.4 */ +/* 15.3.1.3.14 */ +/* + * call-seq: + * global_variables -> array + * + * Returns an array of the names of global variables. + * + * global_variables.grep /std/ #=> [:$stdin, :$stdout, :$stderr] + */ +mrb_value +mrb_f_global_variables(mrb_state *mrb, mrb_value self) +{ + iv_tbl *t = mrb->globals; + mrb_value ary = mrb_ary_new(mrb); + size_t i; + char buf[3]; + + if (t) { + iv_foreach(mrb, t, gv_i, &ary); + } + buf[0] = '$'; + buf[2] = 0; + for (i = 1; i <= 9; ++i) { + buf[1] = (char)(i + '0'); + mrb_ary_push(mrb, ary, mrb_symbol_value(mrb_intern(mrb, buf, 2))); + } + return ary; +} + +static mrb_bool +mrb_const_defined_0(mrb_state *mrb, mrb_value mod, mrb_sym id, mrb_bool exclude, mrb_bool recurse) +{ + struct RClass *klass = mrb_class_ptr(mod); + struct RClass *tmp; + mrb_bool mod_retry = 0; + + tmp = klass; +retry: + while (tmp) { + if (tmp->iv && iv_get(mrb, tmp->iv, id, NULL)) { + return TRUE; + } + if (!recurse && (klass != mrb->object_class)) break; + tmp = tmp->super; + } + if (!exclude && !mod_retry && (klass->tt == MRB_TT_MODULE)) { + mod_retry = 1; + tmp = mrb->object_class; + goto retry; + } + return FALSE; +} + +MRB_API mrb_bool +mrb_const_defined(mrb_state *mrb, mrb_value mod, mrb_sym id) +{ + return mrb_const_defined_0(mrb, mod, id, TRUE, TRUE); +} + +MRB_API mrb_bool +mrb_const_defined_at(mrb_state *mrb, mrb_value mod, mrb_sym id) +{ + return mrb_const_defined_0(mrb, mod, id, TRUE, FALSE); +} + +MRB_API mrb_value +mrb_attr_get(mrb_state *mrb, mrb_value obj, mrb_sym id) +{ + return mrb_iv_get(mrb, obj, id); +} + +struct csym_arg { + struct RClass *c; + mrb_sym sym; +}; + +static int +csym_i(mrb_state *mrb, mrb_sym sym, mrb_value v, void *p) +{ + struct csym_arg *a = (struct csym_arg*)p; + struct RClass *c = a->c; + + if (mrb_type(v) == c->tt && mrb_class_ptr(v) == c) { + a->sym = sym; + return 1; /* stop iteration */ + } + return 0; +} + +static mrb_sym +find_class_sym(mrb_state *mrb, struct RClass *outer, struct RClass *c) +{ + struct csym_arg arg; + + if (!outer) return 0; + arg.c = c; + arg.sym = 0; + iv_foreach(mrb, outer->iv, csym_i, &arg); + return arg.sym; +} + +mrb_value +mrb_class_find_path(mrb_state *mrb, struct RClass *c) +{ + mrb_value outer, path; + mrb_sym name; + const char *str; + mrb_int len; + mrb_sym osym = mrb_intern_lit(mrb, "__outer__"); + + outer = mrb_obj_iv_get(mrb, (struct RObject*)c, osym); + if (mrb_nil_p(outer)) return outer; + name = find_class_sym(mrb, mrb_class_ptr(outer), c); + if (name == 0) return mrb_nil_value(); + str = mrb_class_name(mrb, mrb_class_ptr(outer)); + path = mrb_str_new_capa(mrb, 40); + mrb_str_cat_cstr(mrb, path, str); + mrb_str_cat_cstr(mrb, path, "::"); + + str = mrb_sym2name_len(mrb, name, &len); + mrb_str_cat(mrb, path, str, len); + iv_del(mrb, c->iv, osym, NULL); + iv_put(mrb, c->iv, mrb_intern_lit(mrb, "__classname__"), path); + mrb_field_write_barrier_value(mrb, (struct RBasic*)c, path); + return path; +} diff --git a/web/server/h2o/libh2o/deps/mruby/src/version.c b/web/server/h2o/libh2o/deps/mruby/src/version.c new file mode 100644 index 00000000..350bc167 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/src/version.c @@ -0,0 +1,17 @@ +#include +#include + +void +mrb_init_version(mrb_state* mrb) +{ + mrb_value mruby_version = mrb_str_new_lit(mrb, MRUBY_VERSION); + + mrb_define_global_const(mrb, "RUBY_VERSION", mrb_str_new_lit(mrb, MRUBY_RUBY_VERSION)); + mrb_define_global_const(mrb, "RUBY_ENGINE", mrb_str_new_lit(mrb, MRUBY_RUBY_ENGINE)); + mrb_define_global_const(mrb, "RUBY_ENGINE_VERSION", mruby_version); + mrb_define_global_const(mrb, "MRUBY_VERSION", mruby_version); + mrb_define_global_const(mrb, "MRUBY_RELEASE_NO", mrb_fixnum_value(MRUBY_RELEASE_NO)); + mrb_define_global_const(mrb, "MRUBY_RELEASE_DATE", mrb_str_new_lit(mrb, MRUBY_RELEASE_DATE)); + mrb_define_global_const(mrb, "MRUBY_DESCRIPTION", mrb_str_new_lit(mrb, MRUBY_DESCRIPTION)); + mrb_define_global_const(mrb, "MRUBY_COPYRIGHT", mrb_str_new_lit(mrb, MRUBY_COPYRIGHT)); +} diff --git a/web/server/h2o/libh2o/deps/mruby/src/vm.c b/web/server/h2o/libh2o/deps/mruby/src/vm.c new file mode 100644 index 00000000..f413211e --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/src/vm.c @@ -0,0 +1,2909 @@ +/* +** vm.c - virtual machine for mruby +** +** See Copyright Notice in mruby.h +*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "value_array.h" +#include + +#ifdef MRB_DISABLE_STDIO +#if defined(__cplusplus) +extern "C" { +#endif +void abort(void); +#if defined(__cplusplus) +} /* extern "C" { */ +#endif +#endif + +#define STACK_INIT_SIZE 128 +#define CALLINFO_INIT_SIZE 32 + +#ifndef ENSURE_STACK_INIT_SIZE +#define ENSURE_STACK_INIT_SIZE 16 +#endif + +#ifndef RESCUE_STACK_INIT_SIZE +#define RESCUE_STACK_INIT_SIZE 16 +#endif + +/* Define amount of linear stack growth. */ +#ifndef MRB_STACK_GROWTH +#define MRB_STACK_GROWTH 128 +#endif + +/* Maximum mrb_funcall() depth. Should be set lower on memory constrained systems. */ +#ifndef MRB_FUNCALL_DEPTH_MAX +#define MRB_FUNCALL_DEPTH_MAX 512 +#endif + +/* Maximum stack depth. Should be set lower on memory constrained systems. +The value below allows about 60000 recursive calls in the simplest case. */ +#ifndef MRB_STACK_MAX +#define MRB_STACK_MAX (0x40000 - MRB_STACK_GROWTH) +#endif + +#ifdef VM_DEBUG +# define DEBUG(x) (x) +#else +# define DEBUG(x) +#endif + + +#ifndef MRB_GC_FIXED_ARENA +static void +mrb_gc_arena_shrink(mrb_state *mrb, int idx) +{ + mrb_gc *gc = &mrb->gc; + int capa = gc->arena_capa; + + if (idx < capa / 4) { + capa >>= 2; + if (capa < MRB_GC_ARENA_SIZE) { + capa = MRB_GC_ARENA_SIZE; + } + if (capa != gc->arena_capa) { + gc->arena = (struct RBasic**)mrb_realloc(mrb, gc->arena, sizeof(struct RBasic*)*capa); + gc->arena_capa = capa; + } + } +} +#else +#define mrb_gc_arena_shrink(mrb,idx) +#endif + +#define CALL_MAXARGS 127 + +void mrb_method_missing(mrb_state *mrb, mrb_sym name, mrb_value self, mrb_value args); + +static inline void +stack_clear(mrb_value *from, size_t count) +{ +#ifndef MRB_NAN_BOXING + const mrb_value mrb_value_zero = { { 0 } }; + + while (count-- > 0) { + *from++ = mrb_value_zero; + } +#else + while (count-- > 0) { + SET_NIL_VALUE(*from); + from++; + } +#endif +} + +static inline void +stack_copy(mrb_value *dst, const mrb_value *src, size_t size) +{ + while (size-- > 0) { + *dst++ = *src++; + } +} + +static void +stack_init(mrb_state *mrb) +{ + struct mrb_context *c = mrb->c; + + /* mrb_assert(mrb->stack == NULL); */ + c->stbase = (mrb_value *)mrb_calloc(mrb, STACK_INIT_SIZE, sizeof(mrb_value)); + c->stend = c->stbase + STACK_INIT_SIZE; + c->stack = c->stbase; + + /* mrb_assert(ci == NULL); */ + c->cibase = (mrb_callinfo *)mrb_calloc(mrb, CALLINFO_INIT_SIZE, sizeof(mrb_callinfo)); + c->ciend = c->cibase + CALLINFO_INIT_SIZE; + c->ci = c->cibase; + c->ci->target_class = mrb->object_class; + c->ci->stackent = c->stack; +} + +static inline void +envadjust(mrb_state *mrb, mrb_value *oldbase, mrb_value *newbase, size_t size) +{ + mrb_callinfo *ci = mrb->c->cibase; + + if (newbase == oldbase) return; + while (ci <= mrb->c->ci) { + struct REnv *e = ci->env; + mrb_value *st; + + if (e && MRB_ENV_STACK_SHARED_P(e) && + (st = e->stack) && oldbase <= st && st < oldbase+size) { + ptrdiff_t off = e->stack - oldbase; + + e->stack = newbase + off; + } + ci->stackent = newbase + (ci->stackent - oldbase); + ci++; + } +} + +/** def rec ; $deep =+ 1 ; if $deep > 1000 ; return 0 ; end ; rec ; end */ + +static void +stack_extend_alloc(mrb_state *mrb, int room) +{ + mrb_value *oldbase = mrb->c->stbase; + mrb_value *newstack; + size_t oldsize = mrb->c->stend - mrb->c->stbase; + size_t size = oldsize; + size_t off = mrb->c->stack - mrb->c->stbase; + + if (off > size) size = off; +#ifdef MRB_STACK_EXTEND_DOUBLING + if (room <= size) + size *= 2; + else + size += room; +#else + /* Use linear stack growth. + It is slightly slower than doubling the stack space, + but it saves memory on small devices. */ + if (room <= MRB_STACK_GROWTH) + size += MRB_STACK_GROWTH; + else + size += room; +#endif + + newstack = (mrb_value *)mrb_realloc(mrb, mrb->c->stbase, sizeof(mrb_value) * size); + if (newstack == NULL) { + mrb_exc_raise(mrb, mrb_obj_value(mrb->stack_err)); + } + stack_clear(&(newstack[oldsize]), size - oldsize); + envadjust(mrb, oldbase, newstack, size); + mrb->c->stbase = newstack; + mrb->c->stack = mrb->c->stbase + off; + mrb->c->stend = mrb->c->stbase + size; + + /* Raise an exception if the new stack size will be too large, + to prevent infinite recursion. However, do this only after resizing the stack, so mrb_raise has stack space to work with. */ + if (size > MRB_STACK_MAX) { + mrb_exc_raise(mrb, mrb_obj_value(mrb->stack_err)); + } +} + +static inline void +stack_extend(mrb_state *mrb, int room) +{ + if (mrb->c->stack + room >= mrb->c->stend) { + stack_extend_alloc(mrb, room); + } +} + +static inline struct REnv* +uvenv(mrb_state *mrb, int up) +{ + struct REnv *e = mrb->c->ci->proc->env; + + while (up--) { + if (!e) return NULL; + e = (struct REnv*)e->c; + } + return e; +} + +static inline mrb_bool +is_strict(mrb_state *mrb, struct REnv *e) +{ + ptrdiff_t cioff = e->cioff; + + if (MRB_ENV_STACK_SHARED_P(e) && e->cxt.c->cibase[cioff].proc && + MRB_PROC_STRICT_P(e->cxt.c->cibase[cioff].proc)) { + return TRUE; + } + return FALSE; +} + +static inline struct REnv* +top_env(mrb_state *mrb, struct RProc *proc) +{ + struct REnv *e = proc->env; + + if (is_strict(mrb, e)) return e; + while (e->c) { + e = (struct REnv*)e->c; + if (is_strict(mrb, e)) return e; + } + return e; +} + +#define CI_ACC_SKIP -1 +#define CI_ACC_DIRECT -2 +#define CI_ACC_RESUMED -3 + +static inline mrb_callinfo* +cipush(mrb_state *mrb) +{ + struct mrb_context *c = mrb->c; + static const mrb_callinfo ci_zero = { 0 }; + mrb_callinfo *ci = c->ci; + + int ridx = ci->ridx; + + if (ci + 1 == c->ciend) { + ptrdiff_t size = ci - c->cibase; + + c->cibase = (mrb_callinfo *)mrb_realloc(mrb, c->cibase, sizeof(mrb_callinfo)*size*2); + c->ci = c->cibase + size; + c->ciend = c->cibase + size * 2; + } + ci = ++c->ci; + *ci = ci_zero; + ci->epos = mrb->c->eidx; + ci->ridx = ridx; + + return ci; +} + +MRB_API void +mrb_env_unshare(mrb_state *mrb, struct REnv *e) +{ + if (e == NULL) return; + else { + size_t len = (size_t)MRB_ENV_STACK_LEN(e); + ptrdiff_t cioff = e->cioff; + mrb_value *p; + + if (!MRB_ENV_STACK_SHARED_P(e)) return; + if (e->cxt.c != mrb->c) return; + if (e->cioff == 0 && e->cxt.c == mrb->root_c) return; + MRB_ENV_UNSHARE_STACK(e); + if (!e->c) { + /* save block argument position (negated) */ + e->cioff = -e->cxt.c->cibase[cioff].argc-1; + if (e->cioff == 0) e->cioff = -2; /* blkarg position for vararg (1:args, 2:blk) */ + } + e->cxt.mid = e->cxt.c->cibase[cioff].mid; + p = (mrb_value *)mrb_malloc(mrb, sizeof(mrb_value)*len); + if (len > 0) { + stack_copy(p, e->stack, len); + } + e->stack = p; + mrb_write_barrier(mrb, (struct RBasic *)e); + } +} + +static inline void +cipop(mrb_state *mrb) +{ + struct mrb_context *c = mrb->c; + struct REnv *env = c->ci->env; + + c->ci--; + mrb_env_unshare(mrb, env); +} + +void mrb_exc_set(mrb_state *mrb, mrb_value exc); + +static void +ecall(mrb_state *mrb, int i) +{ + struct RProc *p; + mrb_callinfo *ci = mrb->c->ci; + mrb_value *self = mrb->c->stack; + struct RObject *exc; + ptrdiff_t cioff; + int ai = mrb_gc_arena_save(mrb); + + if (i<0) return; + if (ci - mrb->c->cibase > MRB_FUNCALL_DEPTH_MAX) { + mrb_exc_raise(mrb, mrb_obj_value(mrb->stack_err)); + } + p = mrb->c->ensure[i]; + if (!p) return; + mrb->c->ensure[i] = NULL; + cioff = ci - mrb->c->cibase; + ci = cipush(mrb); + ci->stackent = mrb->c->stack; + ci->mid = ci[-1].mid; + ci->acc = CI_ACC_SKIP; + ci->argc = 0; + ci->proc = p; + ci->nregs = p->body.irep->nregs; + ci->target_class = p->target_class; + mrb->c->stack = mrb->c->stack + ci[-1].nregs; + exc = mrb->exc; mrb->exc = 0; + if (exc) { + mrb_gc_protect(mrb, mrb_obj_value(exc)); + } + mrb_run(mrb, p, *self); + mrb->c->ci = mrb->c->cibase + cioff; + if (!mrb->exc) mrb->exc = exc; + mrb_gc_arena_restore(mrb, ai); +} + +#ifndef MRB_FUNCALL_ARGC_MAX +#define MRB_FUNCALL_ARGC_MAX 16 +#endif + +MRB_API mrb_value +mrb_funcall(mrb_state *mrb, mrb_value self, const char *name, mrb_int argc, ...) +{ + mrb_value argv[MRB_FUNCALL_ARGC_MAX]; + va_list ap; + mrb_int i; + mrb_sym mid = mrb_intern_cstr(mrb, name); + + if (argc > MRB_FUNCALL_ARGC_MAX) { + mrb_raise(mrb, E_ARGUMENT_ERROR, "Too long arguments. (limit=" MRB_STRINGIZE(MRB_FUNCALL_ARGC_MAX) ")"); + } + + va_start(ap, argc); + for (i = 0; i < argc; i++) { + argv[i] = va_arg(ap, mrb_value); + } + va_end(ap); + return mrb_funcall_argv(mrb, self, mid, argc, argv); +} + +MRB_API mrb_value +mrb_funcall_with_block(mrb_state *mrb, mrb_value self, mrb_sym mid, mrb_int argc, const mrb_value *argv, mrb_value blk) +{ + mrb_value val; + + if (!mrb->jmp) { + struct mrb_jmpbuf c_jmp; + ptrdiff_t nth_ci = mrb->c->ci - mrb->c->cibase; + + MRB_TRY(&c_jmp) { + mrb->jmp = &c_jmp; + /* recursive call */ + val = mrb_funcall_with_block(mrb, self, mid, argc, argv, blk); + mrb->jmp = 0; + } + MRB_CATCH(&c_jmp) { /* error */ + while (nth_ci < (mrb->c->ci - mrb->c->cibase)) { + mrb->c->stack = mrb->c->ci->stackent; + cipop(mrb); + } + mrb->jmp = 0; + val = mrb_obj_value(mrb->exc); + } + MRB_END_EXC(&c_jmp); + mrb->jmp = 0; + } + else { + struct RProc *p; + struct RClass *c; + mrb_callinfo *ci; + int n; + ptrdiff_t voff = -1; + + if (!mrb->c->stack) { + stack_init(mrb); + } + n = mrb->c->ci->nregs; + if (argc < 0) { + mrb_raisef(mrb, E_ARGUMENT_ERROR, "negative argc for funcall (%S)", mrb_fixnum_value(argc)); + } + c = mrb_class(mrb, self); + p = mrb_method_search_vm(mrb, &c, mid); + if (!p) { + mrb_sym missing = mrb_intern_lit(mrb, "method_missing"); + mrb_value args = mrb_ary_new_from_values(mrb, argc, argv); + p = mrb_method_search_vm(mrb, &c, missing); + if (!p) { + mrb_method_missing(mrb, mid, self, args); + } + mrb_ary_unshift(mrb, args, mrb_symbol_value(mid)); + stack_extend(mrb, n+2); + mrb->c->stack[n+1] = args; + argc = -1; + } + if (mrb->c->ci - mrb->c->cibase > MRB_FUNCALL_DEPTH_MAX) { + mrb_exc_raise(mrb, mrb_obj_value(mrb->stack_err)); + } + ci = cipush(mrb); + ci->mid = mid; + ci->proc = p; + ci->stackent = mrb->c->stack; + ci->argc = argc; + ci->target_class = c; + mrb->c->stack = mrb->c->stack + n; + if (mrb->c->stbase <= argv && argv < mrb->c->stend) { + voff = argv - mrb->c->stbase; + } + if (MRB_PROC_CFUNC_P(p)) { + ci->nregs = argc + 2; + stack_extend(mrb, ci->nregs); + } + else if (argc >= CALL_MAXARGS) { + mrb_value args = mrb_ary_new_from_values(mrb, argc, argv); + stack_extend(mrb, ci->nregs); + mrb->c->stack[1] = args; + ci->argc = -1; + argc = 1; + } + else { + if (argc < 0) argc = 1; + ci->nregs = p->body.irep->nregs + argc; + stack_extend(mrb, ci->nregs); + } + if (voff >= 0) { + argv = mrb->c->stbase + voff; + } + mrb->c->stack[0] = self; + if (ci->argc > 0) { + stack_copy(mrb->c->stack+1, argv, argc); + } + mrb->c->stack[argc+1] = blk; + + if (MRB_PROC_CFUNC_P(p)) { + int ai = mrb_gc_arena_save(mrb); + + ci->acc = CI_ACC_DIRECT; + val = p->body.func(mrb, self); + mrb->c->stack = mrb->c->ci->stackent; + cipop(mrb); + mrb_gc_arena_restore(mrb, ai); + } + else { + ci->acc = CI_ACC_SKIP; + val = mrb_run(mrb, p, self); + } + } + mrb_gc_protect(mrb, val); + return val; +} + +MRB_API mrb_value +mrb_funcall_argv(mrb_state *mrb, mrb_value self, mrb_sym mid, mrb_int argc, const mrb_value *argv) +{ + return mrb_funcall_with_block(mrb, self, mid, argc, argv, mrb_nil_value()); +} + +mrb_value +mrb_exec_irep(mrb_state *mrb, mrb_value self, struct RProc *p) +{ + mrb_callinfo *ci = mrb->c->ci; + + mrb->c->stack[0] = self; + ci->proc = p; + ci->target_class = p->target_class; + if (MRB_PROC_CFUNC_P(p)) { + return p->body.func(mrb, self); + } + ci->nregs = p->body.irep->nregs; + stack_extend(mrb, (ci->argc < 0 && ci->nregs < 3) ? 3 : ci->nregs); + + ci = cipush(mrb); + ci->nregs = 0; + ci->target_class = 0; + ci->pc = p->body.irep->iseq; + ci->stackent = mrb->c->stack; + ci->acc = 0; + + return self; +} + +/* 15.3.1.3.4 */ +/* 15.3.1.3.44 */ +/* + * call-seq: + * obj.send(symbol [, args...]) -> obj + * obj.__send__(symbol [, args...]) -> obj + * + * Invokes the method identified by _symbol_, passing it any + * arguments specified. You can use __send__ if the name + * +send+ clashes with an existing method in _obj_. + * + * class Klass + * def hello(*args) + * "Hello " + args.join(' ') + * end + * end + * k = Klass.new + * k.send :hello, "gentle", "readers" #=> "Hello gentle readers" + */ +MRB_API mrb_value +mrb_f_send(mrb_state *mrb, mrb_value self) +{ + mrb_sym name; + mrb_value block, *argv, *regs; + mrb_int argc, i, len; + struct RProc *p; + struct RClass *c; + mrb_callinfo *ci; + + mrb_get_args(mrb, "n*&", &name, &argv, &argc, &block); + ci = mrb->c->ci; + if (ci->acc < 0) { + funcall: + return mrb_funcall_with_block(mrb, self, name, argc, argv, block); + } + + c = mrb_class(mrb, self); + p = mrb_method_search_vm(mrb, &c, name); + + if (!p) { /* call method_mising */ + goto funcall; + } + + ci->mid = name; + ci->target_class = c; + regs = mrb->c->stack+1; + /* remove first symbol from arguments */ + if (ci->argc >= 0) { + for (i=0,len=ci->argc; iargc--; + } + else { /* variable length arguments */ + mrb_ary_shift(mrb, regs[0]); + } + + return mrb_exec_irep(mrb, self, p); +} + +static mrb_value +eval_under(mrb_state *mrb, mrb_value self, mrb_value blk, struct RClass *c) +{ + struct RProc *p; + mrb_callinfo *ci; + + if (mrb_nil_p(blk)) { + mrb_raise(mrb, E_ARGUMENT_ERROR, "no block given"); + } + ci = mrb->c->ci; + if (ci->acc == CI_ACC_DIRECT) { + ci->target_class = c; + return mrb_yield_cont(mrb, blk, self, 1, &self); + } + ci->target_class = c; + p = mrb_proc_ptr(blk); + ci->proc = p; + ci->argc = 1; + ci->mid = ci[-1].mid; + if (MRB_PROC_CFUNC_P(p)) { + stack_extend(mrb, 3); + mrb->c->stack[0] = self; + mrb->c->stack[1] = self; + mrb->c->stack[2] = mrb_nil_value(); + return p->body.func(mrb, self); + } + ci->nregs = p->body.irep->nregs; + stack_extend(mrb, (ci->nregs < 3) ? 3 : ci->nregs); + mrb->c->stack[0] = self; + mrb->c->stack[1] = self; + mrb->c->stack[2] = mrb_nil_value(); + ci = cipush(mrb); + ci->nregs = 0; + ci->target_class = 0; + ci->pc = p->body.irep->iseq; + ci->stackent = mrb->c->stack; + ci->acc = 0; + + return self; +} + +/* 15.2.2.4.35 */ +/* + * call-seq: + * mod.class_eval {| | block } -> obj + * mod.module_eval {| | block } -> obj + * + * Evaluates block in the context of _mod_. This can + * be used to add methods to a class. module_eval returns + * the result of evaluating its argument. + */ +mrb_value +mrb_mod_module_eval(mrb_state *mrb, mrb_value mod) +{ + mrb_value a, b; + + if (mrb_get_args(mrb, "|S&", &a, &b) == 1) { + mrb_raise(mrb, E_NOTIMP_ERROR, "module_eval/class_eval with string not implemented"); + } + return eval_under(mrb, mod, b, mrb_class_ptr(mod)); +} + +/* 15.3.1.3.18 */ +/* + * call-seq: + * obj.instance_eval {| | block } -> obj + * + * Evaluates the given block,within the context of the receiver (_obj_). + * In order to set the context, the variable +self+ is set to _obj_ while + * the code is executing, giving the code access to _obj_'s + * instance variables. In the version of instance_eval + * that takes a +String+, the optional second and third + * parameters supply a filename and starting line number that are used + * when reporting compilation errors. + * + * class KlassWithSecret + * def initialize + * @secret = 99 + * end + * end + * k = KlassWithSecret.new + * k.instance_eval { @secret } #=> 99 + */ +mrb_value +mrb_obj_instance_eval(mrb_state *mrb, mrb_value self) +{ + mrb_value a, b; + mrb_value cv; + struct RClass *c; + + if (mrb_get_args(mrb, "|S&", &a, &b) == 1) { + mrb_raise(mrb, E_NOTIMP_ERROR, "instance_eval with string not implemented"); + } + switch (mrb_type(self)) { + case MRB_TT_SYMBOL: + case MRB_TT_FIXNUM: + case MRB_TT_FLOAT: + c = 0; + break; + default: + cv = mrb_singleton_class(mrb, self); + c = mrb_class_ptr(cv); + break; + } + return eval_under(mrb, self, b, c); +} + +MRB_API mrb_value +mrb_yield_with_class(mrb_state *mrb, mrb_value b, mrb_int argc, const mrb_value *argv, mrb_value self, struct RClass *c) +{ + struct RProc *p; + mrb_sym mid = mrb->c->ci->mid; + mrb_callinfo *ci; + int n = mrb->c->ci->nregs; + mrb_value val; + + if (mrb_nil_p(b)) { + mrb_raise(mrb, E_ARGUMENT_ERROR, "no block given"); + } + if (mrb->c->ci - mrb->c->cibase > MRB_FUNCALL_DEPTH_MAX) { + mrb_exc_raise(mrb, mrb_obj_value(mrb->stack_err)); + } + p = mrb_proc_ptr(b); + ci = cipush(mrb); + ci->mid = mid; + ci->proc = p; + ci->stackent = mrb->c->stack; + ci->argc = argc; + ci->target_class = c; + ci->acc = CI_ACC_SKIP; + mrb->c->stack = mrb->c->stack + n; + ci->nregs = MRB_PROC_CFUNC_P(p) ? argc+2 : p->body.irep->nregs; + stack_extend(mrb, ci->nregs); + + mrb->c->stack[0] = self; + if (argc > 0) { + stack_copy(mrb->c->stack+1, argv, argc); + } + mrb->c->stack[argc+1] = mrb_nil_value(); + + if (MRB_PROC_CFUNC_P(p)) { + val = p->body.func(mrb, self); + mrb->c->stack = mrb->c->ci->stackent; + } + else { + ptrdiff_t cioff = mrb->c->ci - mrb->c->cibase; + val = mrb_run(mrb, p, self); + mrb->c->ci = mrb->c->cibase + cioff; + } + cipop(mrb); + return val; +} + +MRB_API mrb_value +mrb_yield_argv(mrb_state *mrb, mrb_value b, mrb_int argc, const mrb_value *argv) +{ + struct RProc *p = mrb_proc_ptr(b); + + return mrb_yield_with_class(mrb, b, argc, argv, p->env->stack[0], p->target_class); +} + +MRB_API mrb_value +mrb_yield(mrb_state *mrb, mrb_value b, mrb_value arg) +{ + struct RProc *p = mrb_proc_ptr(b); + + return mrb_yield_with_class(mrb, b, 1, &arg, p->env->stack[0], p->target_class); +} + +mrb_value +mrb_yield_cont(mrb_state *mrb, mrb_value b, mrb_value self, mrb_int argc, const mrb_value *argv) +{ + struct RProc *p; + mrb_callinfo *ci; + + if (mrb_nil_p(b)) { + mrb_raise(mrb, E_ARGUMENT_ERROR, "no block given"); + } + if (mrb_type(b) != MRB_TT_PROC) { + mrb_raise(mrb, E_TYPE_ERROR, "not a block"); + } + + p = mrb_proc_ptr(b); + ci = mrb->c->ci; + + stack_extend(mrb, 3); + mrb->c->stack[1] = mrb_ary_new_from_values(mrb, argc, argv); + mrb->c->stack[2] = mrb_nil_value(); + ci->argc = -1; + return mrb_exec_irep(mrb, self, p); +} + +mrb_value +mrb_mod_s_nesting(mrb_state *mrb, mrb_value mod) +{ + struct RProc *proc; + mrb_irep *irep; + mrb_value ary; + struct RClass *c; + + mrb_get_args(mrb, ""); + ary = mrb_ary_new(mrb); + proc = mrb->c->ci[-1].proc; /* callee proc */ + c = proc->target_class; + mrb_ary_push(mrb, ary, mrb_obj_value(c)); + mrb_assert(!MRB_PROC_CFUNC_P(proc)); + irep = proc->body.irep; + while (irep) { + if (irep->target_class && irep->target_class != c) { + c = irep->target_class; + mrb_ary_push(mrb, ary, mrb_obj_value(c)); + } + irep = irep->outer; + } + return ary; +} + +static struct RBreak* +break_new(mrb_state *mrb, struct RProc *p, mrb_value val) +{ + struct RBreak *brk; + + brk = (struct RBreak*)mrb_obj_alloc(mrb, MRB_TT_BREAK, NULL); + brk->iv = NULL; + brk->proc = p; + brk->val = val; + + return brk; +} + +typedef enum { + LOCALJUMP_ERROR_RETURN = 0, + LOCALJUMP_ERROR_BREAK = 1, + LOCALJUMP_ERROR_YIELD = 2 +} localjump_error_kind; + +static void +localjump_error(mrb_state *mrb, localjump_error_kind kind) +{ + char kind_str[3][7] = { "return", "break", "yield" }; + char kind_str_len[] = { 6, 5, 5 }; + static const char lead[] = "unexpected "; + mrb_value msg; + mrb_value exc; + + msg = mrb_str_new_capa(mrb, sizeof(lead) + 7); + mrb_str_cat(mrb, msg, lead, sizeof(lead) - 1); + mrb_str_cat(mrb, msg, kind_str[kind], kind_str_len[kind]); + exc = mrb_exc_new_str(mrb, E_LOCALJUMP_ERROR, msg); + mrb_exc_set(mrb, exc); +} + +static void +argnum_error(mrb_state *mrb, mrb_int num) +{ + mrb_value exc; + mrb_value str; + mrb_int argc = mrb->c->ci->argc; + + if (argc < 0) { + mrb_value args = mrb->c->stack[1]; + if (mrb_array_p(args)) { + argc = RARRAY_LEN(args); + } + } + if (mrb->c->ci->mid) { + str = mrb_format(mrb, "'%S': wrong number of arguments (%S for %S)", + mrb_sym2str(mrb, mrb->c->ci->mid), + mrb_fixnum_value(argc), mrb_fixnum_value(num)); + } + else { + str = mrb_format(mrb, "wrong number of arguments (%S for %S)", + mrb_fixnum_value(argc), mrb_fixnum_value(num)); + } + exc = mrb_exc_new_str(mrb, E_ARGUMENT_ERROR, str); + mrb_exc_set(mrb, exc); +} + +void +irep_uplink(mrb_state *mrb, mrb_irep *outer, mrb_irep *irep) +{ + if (irep->outer != outer) { + if (irep->outer) { + mrb_irep_decref(mrb, irep->outer); + } + irep->outer = outer; + mrb_irep_incref(mrb, outer); + } +} + +#define ERR_PC_SET(mrb, pc) mrb->c->ci->err = pc; +#define ERR_PC_CLR(mrb) mrb->c->ci->err = 0; +#ifdef MRB_ENABLE_DEBUG_HOOK +#define CODE_FETCH_HOOK(mrb, irep, pc, regs) if ((mrb)->code_fetch_hook) (mrb)->code_fetch_hook((mrb), (irep), (pc), (regs)); +#else +#define CODE_FETCH_HOOK(mrb, irep, pc, regs) +#endif + +#ifdef MRB_BYTECODE_DECODE_OPTION +#define BYTECODE_DECODER(x) ((mrb)->bytecode_decoder)?(mrb)->bytecode_decoder((mrb), (x)):(x) +#else +#define BYTECODE_DECODER(x) (x) +#endif + + +#if defined __GNUC__ || defined __clang__ || defined __INTEL_COMPILER +#define DIRECT_THREADED +#endif + +#ifndef DIRECT_THREADED + +#define INIT_DISPATCH for (;;) { i = BYTECODE_DECODER(*pc); CODE_FETCH_HOOK(mrb, irep, pc, regs); switch (GET_OPCODE(i)) { +#define CASE(op) case op: +#define NEXT pc++; break +#define JUMP break +#define END_DISPATCH }} + +#else + +#define INIT_DISPATCH JUMP; return mrb_nil_value(); +#define CASE(op) L_ ## op: +#define NEXT i=BYTECODE_DECODER(*++pc); CODE_FETCH_HOOK(mrb, irep, pc, regs); goto *optable[GET_OPCODE(i)] +#define JUMP i=BYTECODE_DECODER(*pc); CODE_FETCH_HOOK(mrb, irep, pc, regs); goto *optable[GET_OPCODE(i)] + +#define END_DISPATCH + +#endif + +MRB_API mrb_value +mrb_vm_run(mrb_state *mrb, struct RProc *proc, mrb_value self, unsigned int stack_keep) +{ + mrb_irep *irep = proc->body.irep; + mrb_value result; + struct mrb_context *c = mrb->c; + ptrdiff_t cioff = c->ci - c->cibase; + unsigned int nregs = irep->nregs; + + if (!c->stack) { + stack_init(mrb); + } + if (stack_keep > nregs) + nregs = stack_keep; + stack_extend(mrb, nregs); + stack_clear(c->stack + stack_keep, nregs - stack_keep); + c->stack[0] = self; + result = mrb_vm_exec(mrb, proc, irep->iseq); + if (c->ci - c->cibase > cioff) { + c->ci = c->cibase + cioff; + } + if (mrb->c != c) { + if (mrb->c->fib) { + mrb_write_barrier(mrb, (struct RBasic*)mrb->c->fib); + } + mrb->c = c; + } + return result; +} + +MRB_API mrb_value +mrb_vm_exec(mrb_state *mrb, struct RProc *proc, mrb_code *pc) +{ + /* mrb_assert(mrb_proc_cfunc_p(proc)) */ + mrb_irep *irep = proc->body.irep; + mrb_value *pool = irep->pool; + mrb_sym *syms = irep->syms; + mrb_code i; + int ai = mrb_gc_arena_save(mrb); + struct mrb_jmpbuf *prev_jmp = mrb->jmp; + struct mrb_jmpbuf c_jmp; + +#ifdef DIRECT_THREADED + static void *optable[] = { + &&L_OP_NOP, &&L_OP_MOVE, + &&L_OP_LOADL, &&L_OP_LOADI, &&L_OP_LOADSYM, &&L_OP_LOADNIL, + &&L_OP_LOADSELF, &&L_OP_LOADT, &&L_OP_LOADF, + &&L_OP_GETGLOBAL, &&L_OP_SETGLOBAL, &&L_OP_GETSPECIAL, &&L_OP_SETSPECIAL, + &&L_OP_GETIV, &&L_OP_SETIV, &&L_OP_GETCV, &&L_OP_SETCV, + &&L_OP_GETCONST, &&L_OP_SETCONST, &&L_OP_GETMCNST, &&L_OP_SETMCNST, + &&L_OP_GETUPVAR, &&L_OP_SETUPVAR, + &&L_OP_JMP, &&L_OP_JMPIF, &&L_OP_JMPNOT, + &&L_OP_ONERR, &&L_OP_RESCUE, &&L_OP_POPERR, &&L_OP_RAISE, &&L_OP_EPUSH, &&L_OP_EPOP, + &&L_OP_SEND, &&L_OP_SENDB, &&L_OP_FSEND, + &&L_OP_CALL, &&L_OP_SUPER, &&L_OP_ARGARY, &&L_OP_ENTER, + &&L_OP_KARG, &&L_OP_KDICT, &&L_OP_RETURN, &&L_OP_TAILCALL, &&L_OP_BLKPUSH, + &&L_OP_ADD, &&L_OP_ADDI, &&L_OP_SUB, &&L_OP_SUBI, &&L_OP_MUL, &&L_OP_DIV, + &&L_OP_EQ, &&L_OP_LT, &&L_OP_LE, &&L_OP_GT, &&L_OP_GE, + &&L_OP_ARRAY, &&L_OP_ARYCAT, &&L_OP_ARYPUSH, &&L_OP_AREF, &&L_OP_ASET, &&L_OP_APOST, + &&L_OP_STRING, &&L_OP_STRCAT, &&L_OP_HASH, + &&L_OP_LAMBDA, &&L_OP_RANGE, &&L_OP_OCLASS, + &&L_OP_CLASS, &&L_OP_MODULE, &&L_OP_EXEC, + &&L_OP_METHOD, &&L_OP_SCLASS, &&L_OP_TCLASS, + &&L_OP_DEBUG, &&L_OP_STOP, &&L_OP_ERR, + }; +#endif + + mrb_bool exc_catched = FALSE; +RETRY_TRY_BLOCK: + + MRB_TRY(&c_jmp) { + + if (exc_catched) { + exc_catched = FALSE; + if (mrb->exc && mrb->exc->tt == MRB_TT_BREAK) + goto L_BREAK; + goto L_RAISE; + } + mrb->jmp = &c_jmp; + mrb->c->ci->proc = proc; + mrb->c->ci->nregs = irep->nregs; + +#define regs (mrb->c->stack) + INIT_DISPATCH { + CASE(OP_NOP) { + /* do nothing */ + NEXT; + } + + CASE(OP_MOVE) { + /* A B R(A) := R(B) */ + int a = GETARG_A(i); + int b = GETARG_B(i); + regs[a] = regs[b]; + NEXT; + } + + CASE(OP_LOADL) { + /* A Bx R(A) := Pool(Bx) */ + int a = GETARG_A(i); + int bx = GETARG_Bx(i); +#ifdef MRB_WORD_BOXING + mrb_value val = pool[bx]; + if (mrb_float_p(val)) { + val = mrb_float_value(mrb, mrb_float(val)); + } + regs[a] = val; +#else + regs[a] = pool[bx]; +#endif + NEXT; + } + + CASE(OP_LOADI) { + /* A sBx R(A) := sBx */ + SET_INT_VALUE(regs[GETARG_A(i)], GETARG_sBx(i)); + NEXT; + } + + CASE(OP_LOADSYM) { + /* A Bx R(A) := Syms(Bx) */ + int a = GETARG_A(i); + int bx = GETARG_Bx(i); + SET_SYM_VALUE(regs[a], syms[bx]); + NEXT; + } + + CASE(OP_LOADSELF) { + /* A R(A) := self */ + int a = GETARG_A(i); + regs[a] = regs[0]; + NEXT; + } + + CASE(OP_LOADT) { + /* A R(A) := true */ + int a = GETARG_A(i); + SET_TRUE_VALUE(regs[a]); + NEXT; + } + + CASE(OP_LOADF) { + /* A R(A) := false */ + int a = GETARG_A(i); + SET_FALSE_VALUE(regs[a]); + NEXT; + } + + CASE(OP_GETGLOBAL) { + /* A Bx R(A) := getglobal(Syms(Bx)) */ + int a = GETARG_A(i); + int bx = GETARG_Bx(i); + mrb_value val = mrb_gv_get(mrb, syms[bx]); + regs[a] = val; + NEXT; + } + + CASE(OP_SETGLOBAL) { + /* A Bx setglobal(Syms(Bx), R(A)) */ + int a = GETARG_A(i); + int bx = GETARG_Bx(i); + mrb_gv_set(mrb, syms[bx], regs[a]); + NEXT; + } + + CASE(OP_GETSPECIAL) { + /* A Bx R(A) := Special[Bx] */ + int a = GETARG_A(i); + int bx = GETARG_Bx(i); + mrb_value val = mrb_vm_special_get(mrb, bx); + regs[a] = val; + NEXT; + } + + CASE(OP_SETSPECIAL) { + /* A Bx Special[Bx] := R(A) */ + int a = GETARG_A(i); + int bx = GETARG_Bx(i); + mrb_vm_special_set(mrb, bx, regs[a]); + NEXT; + } + + CASE(OP_GETIV) { + /* A Bx R(A) := ivget(Bx) */ + int a = GETARG_A(i); + int bx = GETARG_Bx(i); + mrb_value val = mrb_vm_iv_get(mrb, syms[bx]); + regs[a] = val; + NEXT; + } + + CASE(OP_SETIV) { + /* A Bx ivset(Syms(Bx),R(A)) */ + int a = GETARG_A(i); + int bx = GETARG_Bx(i); + mrb_vm_iv_set(mrb, syms[bx], regs[a]); + NEXT; + } + + CASE(OP_GETCV) { + /* A Bx R(A) := cvget(Syms(Bx)) */ + int a = GETARG_A(i); + int bx = GETARG_Bx(i); + mrb_value val; + ERR_PC_SET(mrb, pc); + val = mrb_vm_cv_get(mrb, syms[bx]); + ERR_PC_CLR(mrb); + regs[a] = val; + NEXT; + } + + CASE(OP_SETCV) { + /* A Bx cvset(Syms(Bx),R(A)) */ + int a = GETARG_A(i); + int bx = GETARG_Bx(i); + mrb_vm_cv_set(mrb, syms[bx], regs[a]); + NEXT; + } + + CASE(OP_GETCONST) { + /* A Bx R(A) := constget(Syms(Bx)) */ + mrb_value val; + int a = GETARG_A(i); + int bx = GETARG_Bx(i); + mrb_sym sym = syms[bx]; + + ERR_PC_SET(mrb, pc); + val = mrb_vm_const_get(mrb, sym); + ERR_PC_CLR(mrb); + regs[a] = val; + NEXT; + } + + CASE(OP_SETCONST) { + /* A Bx constset(Syms(Bx),R(A)) */ + int a = GETARG_A(i); + int bx = GETARG_Bx(i); + mrb_vm_const_set(mrb, syms[bx], regs[a]); + NEXT; + } + + CASE(OP_GETMCNST) { + /* A Bx R(A) := R(A)::Syms(Bx) */ + mrb_value val; + int a = GETARG_A(i); + int bx = GETARG_Bx(i); + + ERR_PC_SET(mrb, pc); + val = mrb_const_get(mrb, regs[a], syms[bx]); + ERR_PC_CLR(mrb); + regs[a] = val; + NEXT; + } + + CASE(OP_SETMCNST) { + /* A Bx R(A+1)::Syms(Bx) := R(A) */ + int a = GETARG_A(i); + int bx = GETARG_Bx(i); + mrb_const_set(mrb, regs[a+1], syms[bx], regs[a]); + NEXT; + } + + CASE(OP_GETUPVAR) { + /* A B C R(A) := uvget(B,C) */ + int a = GETARG_A(i); + int b = GETARG_B(i); + int c = GETARG_C(i); + mrb_value *regs_a = regs + a; + struct REnv *e = uvenv(mrb, c); + + if (!e) { + *regs_a = mrb_nil_value(); + } + else { + *regs_a = e->stack[b]; + } + NEXT; + } + + CASE(OP_SETUPVAR) { + /* A B C uvset(B,C,R(A)) */ + int a = GETARG_A(i); + int b = GETARG_B(i); + int c = GETARG_C(i); + + struct REnv *e = uvenv(mrb, c); + + if (e) { + mrb_value *regs_a = regs + a; + + if (b < MRB_ENV_STACK_LEN(e)) { + e->stack[b] = *regs_a; + mrb_write_barrier(mrb, (struct RBasic*)e); + } + } + NEXT; + } + + CASE(OP_JMP) { + /* sBx pc+=sBx */ + int sbx = GETARG_sBx(i); + pc += sbx; + JUMP; + } + + CASE(OP_JMPIF) { + /* A sBx if R(A) pc+=sBx */ + int a = GETARG_A(i); + int sbx = GETARG_sBx(i); + if (mrb_test(regs[a])) { + pc += sbx; + JUMP; + } + NEXT; + } + + CASE(OP_JMPNOT) { + /* A sBx if !R(A) pc+=sBx */ + int a = GETARG_A(i); + int sbx = GETARG_sBx(i); + if (!mrb_test(regs[a])) { + pc += sbx; + JUMP; + } + NEXT; + } + + CASE(OP_ONERR) { + /* sBx pc+=sBx on exception */ + int sbx = GETARG_sBx(i); + if (mrb->c->rsize <= mrb->c->ci->ridx) { + if (mrb->c->rsize == 0) mrb->c->rsize = RESCUE_STACK_INIT_SIZE; + else mrb->c->rsize *= 2; + mrb->c->rescue = (mrb_code **)mrb_realloc(mrb, mrb->c->rescue, sizeof(mrb_code*) * mrb->c->rsize); + } + mrb->c->rescue[mrb->c->ci->ridx++] = pc + sbx; + NEXT; + } + + CASE(OP_RESCUE) { + /* A B R(A) := exc; clear(exc); R(B) := matched (bool) */ + int a = GETARG_A(i); + int b = GETARG_B(i); + int c = GETARG_C(i); + mrb_value exc; + + if (c == 0) { + exc = mrb_obj_value(mrb->exc); + mrb->exc = 0; + } + else { /* continued; exc taken from R(A) */ + exc = regs[a]; + } + if (b != 0) { + mrb_value e = regs[b]; + struct RClass *ec; + + switch (mrb_type(e)) { + case MRB_TT_CLASS: + case MRB_TT_MODULE: + break; + default: + { + mrb_value exc; + + exc = mrb_exc_new_str_lit(mrb, E_TYPE_ERROR, + "class or module required for rescue clause"); + mrb_exc_set(mrb, exc); + goto L_RAISE; + } + } + ec = mrb_class_ptr(e); + regs[b] = mrb_bool_value(mrb_obj_is_kind_of(mrb, exc, ec)); + } + if (a != 0 && c == 0) { + regs[a] = exc; + } + NEXT; + } + + CASE(OP_POPERR) { + /* A A.times{rescue_pop()} */ + int a = GETARG_A(i); + + mrb->c->ci->ridx -= a; + NEXT; + } + + CASE(OP_RAISE) { + /* A raise(R(A)) */ + int a = GETARG_A(i); + + mrb_exc_set(mrb, regs[a]); + goto L_RAISE; + } + + CASE(OP_EPUSH) { + /* Bx ensure_push(SEQ[Bx]) */ + int bx = GETARG_Bx(i); + struct RProc *p; + + p = mrb_closure_new(mrb, irep->reps[bx]); + /* push ensure_stack */ + if (mrb->c->esize <= mrb->c->eidx+1) { + if (mrb->c->esize == 0) mrb->c->esize = ENSURE_STACK_INIT_SIZE; + else mrb->c->esize *= 2; + mrb->c->ensure = (struct RProc **)mrb_realloc(mrb, mrb->c->ensure, sizeof(struct RProc*) * mrb->c->esize); + } + mrb->c->ensure[mrb->c->eidx++] = p; + mrb->c->ensure[mrb->c->eidx] = NULL; + mrb_gc_arena_restore(mrb, ai); + NEXT; + } + + CASE(OP_EPOP) { + /* A A.times{ensure_pop().call} */ + int a = GETARG_A(i); + mrb_callinfo *ci = mrb->c->ci; + int n, epos = ci->epos; + + for (n=0; nc->eidx > epos; n++) { + ecall(mrb, --mrb->c->eidx); + mrb_gc_arena_restore(mrb, ai); + } + NEXT; + } + + CASE(OP_LOADNIL) { + /* A R(A) := nil */ + int a = GETARG_A(i); + + SET_NIL_VALUE(regs[a]); + NEXT; + } + + CASE(OP_SENDB) { + /* A B C R(A) := call(R(A),Syms(B),R(A+1),...,R(A+C),&R(A+C+1))*/ + /* fall through */ + }; + + L_SEND: + CASE(OP_SEND) { + /* A B C R(A) := call(R(A),Syms(B),R(A+1),...,R(A+C)) */ + int a = GETARG_A(i); + int n = GETARG_C(i); + int argc = (n == CALL_MAXARGS) ? -1 : n; + int bidx = (argc < 0) ? a+2 : a+n+1; + struct RProc *m; + struct RClass *c; + mrb_callinfo *ci = mrb->c->ci; + mrb_value recv, blk; + mrb_sym mid = syms[GETARG_B(i)]; + + mrb_assert(bidx < ci->nregs); + + recv = regs[a]; + if (GET_OPCODE(i) != OP_SENDB) { + SET_NIL_VALUE(regs[bidx]); + blk = regs[bidx]; + } + else { + blk = regs[bidx]; + if (!mrb_nil_p(blk) && mrb_type(blk) != MRB_TT_PROC) { + blk = mrb_convert_type(mrb, blk, MRB_TT_PROC, "Proc", "to_proc"); + /* The stack might have been reallocated during mrb_convert_type(), + see #3622 */ + regs[bidx] = blk; + } + } + c = mrb_class(mrb, recv); + m = mrb_method_search_vm(mrb, &c, mid); + if (!m) { + mrb_sym missing = mrb_intern_lit(mrb, "method_missing"); + m = mrb_method_search_vm(mrb, &c, missing); + if (!m) { + mrb_value args = (argc < 0) ? regs[a+1] : mrb_ary_new_from_values(mrb, n, regs+a+1); + ERR_PC_SET(mrb, pc); + mrb_method_missing(mrb, mid, recv, args); + } + if (argc >= 0) { + if (a+2 >= irep->nregs) { + stack_extend(mrb, a+3); + } + regs[a+1] = mrb_ary_new_from_values(mrb, n, regs+a+1); + regs[a+2] = blk; + argc = -1; + } + mrb_ary_unshift(mrb, regs[a+1], mrb_symbol_value(mid)); + mid = missing; + } + + /* push callinfo */ + ci = cipush(mrb); + ci->mid = mid; + ci->proc = m; + ci->stackent = mrb->c->stack; + ci->target_class = c; + ci->argc = argc; + + ci->pc = pc + 1; + ci->acc = a; + + /* prepare stack */ + mrb->c->stack += a; + + if (MRB_PROC_CFUNC_P(m)) { + ci->nregs = (argc < 0) ? 3 : n+2; + recv = m->body.func(mrb, recv); + mrb_gc_arena_restore(mrb, ai); + mrb_gc_arena_shrink(mrb, ai); + if (mrb->exc) goto L_RAISE; + ci = mrb->c->ci; + if (GET_OPCODE(i) == OP_SENDB) { + if (mrb_type(blk) == MRB_TT_PROC) { + struct RProc *p = mrb_proc_ptr(blk); + if (p && !MRB_PROC_STRICT_P(p) && p->env == ci[-1].env) { + p->flags |= MRB_PROC_ORPHAN; + } + } + } + if (!ci->target_class) { /* return from context modifying method (resume/yield) */ + if (ci->acc == CI_ACC_RESUMED) { + mrb->jmp = prev_jmp; + return recv; + } + else { + mrb_assert(!MRB_PROC_CFUNC_P(ci[-1].proc)); + proc = ci[-1].proc; + irep = proc->body.irep; + pool = irep->pool; + syms = irep->syms; + } + } + mrb->c->stack[0] = recv; + /* pop stackpos */ + mrb->c->stack = ci->stackent; + pc = ci->pc; + cipop(mrb); + JUMP; + } + else { + /* setup environment for calling method */ + proc = mrb->c->ci->proc = m; + irep = m->body.irep; + pool = irep->pool; + syms = irep->syms; + ci->nregs = irep->nregs; + stack_extend(mrb, (argc < 0 && ci->nregs < 3) ? 3 : ci->nregs); + pc = irep->iseq; + JUMP; + } + } + + CASE(OP_FSEND) { + /* A B C R(A) := fcall(R(A),Syms(B),R(A+1),... ,R(A+C-1)) */ + /* not implemented yet */ + NEXT; + } + + CASE(OP_CALL) { + /* A R(A) := self.call(frame.argc, frame.argv) */ + mrb_callinfo *ci; + mrb_value recv = mrb->c->stack[0]; + struct RProc *m = mrb_proc_ptr(recv); + + /* replace callinfo */ + ci = mrb->c->ci; + ci->target_class = m->target_class; + ci->proc = m; + if (m->env) { + mrb_sym mid; + + if (MRB_ENV_STACK_SHARED_P(m->env)) { + mid = m->env->cxt.c->cibase[m->env->cioff].mid; + } + else { + mid = m->env->cxt.mid; + } + if (mid) ci->mid = mid; + if (!m->env->stack) { + m->env->stack = mrb->c->stack; + } + } + + /* prepare stack */ + if (MRB_PROC_CFUNC_P(m)) { + recv = m->body.func(mrb, recv); + mrb_gc_arena_restore(mrb, ai); + mrb_gc_arena_shrink(mrb, ai); + if (mrb->exc) goto L_RAISE; + /* pop stackpos */ + ci = mrb->c->ci; + mrb->c->stack = ci->stackent; + regs[ci->acc] = recv; + pc = ci->pc; + cipop(mrb); + irep = mrb->c->ci->proc->body.irep; + pool = irep->pool; + syms = irep->syms; + JUMP; + } + else { + /* setup environment for calling method */ + proc = m; + irep = m->body.irep; + if (!irep) { + mrb->c->stack[0] = mrb_nil_value(); + goto L_RETURN; + } + pool = irep->pool; + syms = irep->syms; + ci->nregs = irep->nregs; + stack_extend(mrb, ci->nregs); + if (ci->argc < 0) { + if (irep->nregs > 3) { + stack_clear(regs+3, irep->nregs-3); + } + } + else if (ci->argc+2 < irep->nregs) { + stack_clear(regs+ci->argc+2, irep->nregs-ci->argc-2); + } + if (m->env) { + regs[0] = m->env->stack[0]; + } + pc = irep->iseq; + JUMP; + } + } + + CASE(OP_SUPER) { + /* A C R(A) := super(R(A+1),... ,R(A+C+1)) */ + int a = GETARG_A(i); + int n = GETARG_C(i); + int argc = (n == CALL_MAXARGS) ? -1 : n; + int bidx = (argc < 0) ? a+2 : a+n+1; + struct RProc *m; + struct RClass *c; + mrb_callinfo *ci = mrb->c->ci; + mrb_value recv, blk; + mrb_sym mid = ci->mid; + + mrb_assert(bidx < ci->nregs); + + if (mid == 0 || !ci->target_class) { + mrb_value exc = mrb_exc_new_str_lit(mrb, E_NOMETHOD_ERROR, "super called outside of method"); + mrb_exc_set(mrb, exc); + goto L_RAISE; + } + recv = regs[0]; + blk = regs[bidx]; + if (!mrb_nil_p(blk) && mrb_type(blk) != MRB_TT_PROC) { + blk = mrb_convert_type(mrb, blk, MRB_TT_PROC, "Proc", "to_proc"); + /* The stack or ci stack might have been reallocated during + mrb_convert_type(), see #3622 and #3784 */ + regs[bidx] = blk; + ci = mrb->c->ci; + } + c = ci->target_class->super; + m = mrb_method_search_vm(mrb, &c, mid); + if (!m) { + mrb_sym missing = mrb_intern_lit(mrb, "method_missing"); + m = mrb_method_search_vm(mrb, &c, missing); + if (!m) { + mrb_value args = (argc < 0) ? regs[a+1] : mrb_ary_new_from_values(mrb, n, regs+a+1); + ERR_PC_SET(mrb, pc); + mrb_method_missing(mrb, mid, recv, args); + } + mid = missing; + if (argc >= 0) { + if (a+2 >= ci->nregs) { + stack_extend(mrb, a+3); + } + regs[a+1] = mrb_ary_new_from_values(mrb, n, regs+a+1); + regs[a+2] = blk; + argc = -1; + } + mrb_ary_unshift(mrb, regs[a+1], mrb_symbol_value(ci->mid)); + } + + /* push callinfo */ + ci = cipush(mrb); + ci->mid = mid; + ci->proc = m; + ci->stackent = mrb->c->stack; + ci->target_class = c; + ci->pc = pc + 1; + ci->argc = argc; + + /* prepare stack */ + mrb->c->stack += a; + mrb->c->stack[0] = recv; + + if (MRB_PROC_CFUNC_P(m)) { + mrb_value v; + ci->nregs = (argc < 0) ? 3 : n+2; + v = m->body.func(mrb, recv); + mrb_gc_arena_restore(mrb, ai); + if (mrb->exc) goto L_RAISE; + ci = mrb->c->ci; + if (!ci->target_class) { /* return from context modifying method (resume/yield) */ + if (ci->acc == CI_ACC_RESUMED) { + mrb->jmp = prev_jmp; + return v; + } + else { + mrb_assert(!MRB_PROC_CFUNC_P(ci[-1].proc)); + proc = ci[-1].proc; + irep = proc->body.irep; + pool = irep->pool; + syms = irep->syms; + } + } + mrb->c->stack[0] = v; + /* pop stackpos */ + mrb->c->stack = ci->stackent; + pc = ci->pc; + cipop(mrb); + JUMP; + } + else { + /* fill callinfo */ + ci->acc = a; + + /* setup environment for calling method */ + ci->proc = m; + irep = m->body.irep; + pool = irep->pool; + syms = irep->syms; + ci->nregs = irep->nregs; + stack_extend(mrb, (argc < 0 && ci->nregs < 3) ? 3 : ci->nregs); + pc = irep->iseq; + JUMP; + } + } + + CASE(OP_ARGARY) { + /* A Bx R(A) := argument array (16=6:1:5:4) */ + int a = GETARG_A(i); + int bx = GETARG_Bx(i); + int m1 = (bx>>10)&0x3f; + int r = (bx>>9)&0x1; + int m2 = (bx>>4)&0x1f; + int lv = (bx>>0)&0xf; + mrb_value *stack; + + if (mrb->c->ci->mid == 0 || mrb->c->ci->target_class == NULL) { + mrb_value exc; + + L_NOSUPER: + exc = mrb_exc_new_str_lit(mrb, E_NOMETHOD_ERROR, "super called outside of method"); + mrb_exc_set(mrb, exc); + goto L_RAISE; + } + if (lv == 0) stack = regs + 1; + else { + struct REnv *e = uvenv(mrb, lv-1); + if (!e) goto L_NOSUPER; + if (MRB_ENV_STACK_LEN(e) <= m1+r+m2+1) + goto L_NOSUPER; + stack = e->stack + 1; + } + if (r == 0) { + regs[a] = mrb_ary_new_from_values(mrb, m1+m2, stack); + } + else { + mrb_value *pp = NULL; + struct RArray *rest; + int len = 0; + + if (mrb_array_p(stack[m1])) { + struct RArray *ary = mrb_ary_ptr(stack[m1]); + + pp = ARY_PTR(ary); + len = ARY_LEN(ary); + } + regs[a] = mrb_ary_new_capa(mrb, m1+len+m2); + rest = mrb_ary_ptr(regs[a]); + if (m1 > 0) { + stack_copy(ARY_PTR(rest), stack, m1); + } + if (len > 0) { + stack_copy(ARY_PTR(rest)+m1, pp, len); + } + if (m2 > 0) { + stack_copy(ARY_PTR(rest)+m1+len, stack+m1+1, m2); + } + ARY_SET_LEN(rest, m1+len+m2); + } + regs[a+1] = stack[m1+r+m2]; + mrb_gc_arena_restore(mrb, ai); + NEXT; + } + + CASE(OP_ENTER) { + /* Ax arg setup according to flags (23=5:5:1:5:5:1:1) */ + /* number of optional arguments times OP_JMP should follow */ + mrb_aspec ax = GETARG_Ax(i); + int m1 = MRB_ASPEC_REQ(ax); + int o = MRB_ASPEC_OPT(ax); + int r = MRB_ASPEC_REST(ax); + int m2 = MRB_ASPEC_POST(ax); + /* unused + int k = MRB_ASPEC_KEY(ax); + int kd = MRB_ASPEC_KDICT(ax); + int b = MRB_ASPEC_BLOCK(ax); + */ + int argc = mrb->c->ci->argc; + mrb_value *argv = regs+1; + mrb_value *argv0 = argv; + int len = m1 + o + r + m2; + mrb_value *blk = &argv[argc < 0 ? 1 : argc]; + + if (argc < 0) { + struct RArray *ary = mrb_ary_ptr(regs[1]); + argv = ARY_PTR(ary); + argc = ARY_LEN(ary); + mrb_gc_protect(mrb, regs[1]); + } + if (mrb->c->ci->proc && MRB_PROC_STRICT_P(mrb->c->ci->proc)) { + if (argc >= 0) { + if (argc < m1 + m2 || (r == 0 && argc > len)) { + argnum_error(mrb, m1+m2); + goto L_RAISE; + } + } + } + else if (len > 1 && argc == 1 && mrb_array_p(argv[0])) { + mrb_gc_protect(mrb, argv[0]); + argc = RARRAY_LEN(argv[0]); + argv = RARRAY_PTR(argv[0]); + } + if (argc < len) { + int mlen = m2; + if (argc < m1+m2) { + if (m1 < argc) + mlen = argc - m1; + else + mlen = 0; + } + regs[len+1] = *blk; /* move block */ + SET_NIL_VALUE(regs[argc+1]); + if (argv0 != argv) { + value_move(®s[1], argv, argc-mlen); /* m1 + o */ + } + if (argc < m1) { + stack_clear(®s[argc+1], m1-argc); + } + if (mlen) { + value_move(®s[len-m2+1], &argv[argc-mlen], mlen); + } + if (mlen < m2) { + stack_clear(®s[len-m2+mlen+1], m2-mlen); + } + if (r) { + regs[m1+o+1] = mrb_ary_new_capa(mrb, 0); + } + if (o == 0 || argc < m1+m2) pc++; + else + pc += argc - m1 - m2 + 1; + } + else { + int rnum = 0; + if (argv0 != argv) { + regs[len+1] = *blk; /* move block */ + value_move(®s[1], argv, m1+o); + } + if (r) { + rnum = argc-m1-o-m2; + regs[m1+o+1] = mrb_ary_new_from_values(mrb, rnum, argv+m1+o); + } + if (m2) { + if (argc-m2 > m1) { + value_move(®s[m1+o+r+1], &argv[m1+o+rnum], m2); + } + } + if (argv0 == argv) { + regs[len+1] = *blk; /* move block */ + } + pc += o + 1; + } + mrb->c->ci->argc = len; + /* clear local (but non-argument) variables */ + if (irep->nlocals-len-2 > 0) { + stack_clear(®s[len+2], irep->nlocals-len-2); + } + JUMP; + } + + CASE(OP_KARG) { + /* A B C R(A) := kdict[Syms(B)]; if C kdict.rm(Syms(B)) */ + /* if C == 2; raise unless kdict.empty? */ + /* OP_JMP should follow to skip init code */ + NEXT; + } + + CASE(OP_KDICT) { + /* A C R(A) := kdict */ + NEXT; + } + + L_RETURN: + i = MKOP_AB(OP_RETURN, GETARG_A(i), OP_R_NORMAL); + /* fall through */ + CASE(OP_RETURN) { + /* A B return R(A) (B=normal,in-block return/break) */ + mrb_callinfo *ci; + + ci = mrb->c->ci; + if (ci->mid) { + mrb_value blk; + + if (ci->argc < 0) { + blk = regs[2]; + } + else { + blk = regs[ci->argc+1]; + } + if (mrb_type(blk) == MRB_TT_PROC) { + struct RProc *p = mrb_proc_ptr(blk); + + if (!MRB_PROC_STRICT_P(p) && + ci > mrb->c->cibase && p->env == ci[-1].env) { + p->flags |= MRB_PROC_ORPHAN; + } + } + } + + if (mrb->exc) { + mrb_callinfo *ci0; + mrb_value *stk; + + L_RAISE: + ci0 = ci = mrb->c->ci; + if (ci == mrb->c->cibase) { + if (ci->ridx == 0) goto L_FTOP; + goto L_RESCUE; + } + stk = mrb->c->stack; + while (ci[0].ridx == ci[-1].ridx) { + cipop(mrb); + mrb->c->stack = ci->stackent; + if (ci->acc == CI_ACC_SKIP && prev_jmp) { + mrb->jmp = prev_jmp; + MRB_THROW(prev_jmp); + } + ci = mrb->c->ci; + if (ci == mrb->c->cibase) { + mrb->c->stack = stk; + if (ci->ridx == 0) { + L_FTOP: /* fiber top */ + if (mrb->c == mrb->root_c) { + mrb->c->stack = mrb->c->stbase; + goto L_STOP; + } + else { + struct mrb_context *c = mrb->c; + + if (c->fib) { + mrb_write_barrier(mrb, (struct RBasic*)c->fib); + } + mrb->c = c->prev; + c->prev = NULL; + goto L_RAISE; + } + } + break; + } + /* call ensure only when we skip this callinfo */ + if (ci[0].ridx == ci[-1].ridx) { + mrb_value *org_stbase = mrb->c->stbase; + while (mrb->c->eidx > ci->epos) { + ecall(mrb, --mrb->c->eidx); + ci = mrb->c->ci; + if (org_stbase != mrb->c->stbase) { + stk = mrb->c->stack; + } + } + } + } + L_RESCUE: + if (ci->ridx == 0) goto L_STOP; + proc = ci->proc; + irep = proc->body.irep; + pool = irep->pool; + syms = irep->syms; + if (ci != ci0) { + mrb->c->stack = ci[1].stackent; + } + stack_extend(mrb, irep->nregs); + pc = mrb->c->rescue[--ci->ridx]; + } + else { + int acc; + mrb_value v; + + v = regs[GETARG_A(i)]; + mrb_gc_protect(mrb, v); + switch (GETARG_B(i)) { + case OP_R_RETURN: + /* Fall through to OP_R_NORMAL otherwise */ + if (ci->acc >=0 && proc->env && !MRB_PROC_STRICT_P(proc)) { + struct REnv *e = top_env(mrb, proc); + mrb_callinfo *ce; + + if (!MRB_ENV_STACK_SHARED_P(e) || e->cxt.c != mrb->c) { + localjump_error(mrb, LOCALJUMP_ERROR_RETURN); + goto L_RAISE; + } + + ce = mrb->c->cibase + e->cioff; + while (ci > ce) { + mrb_env_unshare(mrb, ci->env); + if (ci->acc < 0) { + localjump_error(mrb, LOCALJUMP_ERROR_RETURN); + goto L_RAISE; + } + ci--; + } + mrb_env_unshare(mrb, ci->env); + if (ce == mrb->c->cibase) { + localjump_error(mrb, LOCALJUMP_ERROR_RETURN); + goto L_RAISE; + } + mrb->c->stack = mrb->c->ci->stackent; + mrb->c->ci = ce; + break; + } + case OP_R_NORMAL: + NORMAL_RETURN: + if (ci == mrb->c->cibase) { + if (!mrb->c->prev) { /* toplevel return */ + localjump_error(mrb, LOCALJUMP_ERROR_RETURN); + goto L_RAISE; + } + if (mrb->c->prev->ci == mrb->c->prev->cibase) { + mrb_value exc = mrb_exc_new_str_lit(mrb, E_FIBER_ERROR, "double resume"); + mrb_exc_set(mrb, exc); + goto L_RAISE; + } + while (mrb->c->eidx > 0) { + ecall(mrb, --mrb->c->eidx); + } + /* automatic yield at the end */ + mrb->c->status = MRB_FIBER_TERMINATED; + mrb->c = mrb->c->prev; + mrb->c->status = MRB_FIBER_RUNNING; + } + ci = mrb->c->ci; + break; + case OP_R_BREAK: + if (MRB_PROC_STRICT_P(proc)) goto NORMAL_RETURN; + if (MRB_PROC_ORPHAN_P(proc)) { + mrb_value exc; + + L_BREAK_ERROR: + exc = mrb_exc_new_str_lit(mrb, E_LOCALJUMP_ERROR, + "break from proc-closure"); + mrb_exc_set(mrb, exc); + goto L_RAISE; + } + if (!proc->env || !MRB_ENV_STACK_SHARED_P(proc->env)) { + goto L_BREAK_ERROR; + } + if (proc->env->cxt.c != mrb->c) { + goto L_BREAK_ERROR; + } + while (mrb->c->eidx > mrb->c->ci->epos) { + ecall(mrb, --mrb->c->eidx); + } + /* break from fiber block */ + if (mrb->c->ci == mrb->c->cibase && mrb->c->ci->pc) { + struct mrb_context *c = mrb->c; + + mrb->c = c->prev; + c->prev = NULL; + } + ci = mrb->c->ci; + if (ci->acc < 0) { + mrb_gc_arena_restore(mrb, ai); + mrb->c->vmexec = FALSE; + mrb->exc = (struct RObject*)break_new(mrb, proc, v); + mrb->jmp = prev_jmp; + MRB_THROW(prev_jmp); + } + if (FALSE) { + L_BREAK: + v = ((struct RBreak*)mrb->exc)->val; + proc = ((struct RBreak*)mrb->exc)->proc; + mrb->exc = NULL; + ci = mrb->c->ci; + } + mrb->c->stack = ci->stackent; + mrb->c->ci = mrb->c->cibase + proc->env->cioff + 1; + while (ci > mrb->c->ci) { + mrb_env_unshare(mrb, ci->env); + if (ci[-1].acc == CI_ACC_SKIP) { + mrb->c->ci = ci; + goto L_BREAK_ERROR; + } + ci--; + } + mrb_env_unshare(mrb, ci->env); + break; + default: + /* cannot happen */ + break; + } + while (mrb->c->eidx > mrb->c->ci->epos) { + ecall(mrb, --mrb->c->eidx); + } + if (mrb->c->vmexec && !mrb->c->ci->target_class) { + mrb_gc_arena_restore(mrb, ai); + mrb->c->vmexec = FALSE; + mrb->jmp = prev_jmp; + return v; + } + ci = mrb->c->ci; + acc = ci->acc; + mrb->c->stack = ci->stackent; + cipop(mrb); + if (acc == CI_ACC_SKIP || acc == CI_ACC_DIRECT) { + mrb_gc_arena_restore(mrb, ai); + mrb->jmp = prev_jmp; + return v; + } + pc = ci->pc; + DEBUG(fprintf(stderr, "from :%s\n", mrb_sym2name(mrb, ci->mid))); + proc = mrb->c->ci->proc; + irep = proc->body.irep; + pool = irep->pool; + syms = irep->syms; + + regs[acc] = v; + mrb_gc_arena_restore(mrb, ai); + } + JUMP; + } + + CASE(OP_TAILCALL) { + /* A B C return call(R(A),Syms(B),R(A+1),... ,R(A+C+1)) */ + int a = GETARG_A(i); + int n = GETARG_C(i); + struct RProc *m; + struct RClass *c; + mrb_callinfo *ci; + mrb_value recv; + mrb_sym mid = syms[GETARG_B(i)]; + + recv = regs[a]; + c = mrb_class(mrb, recv); + m = mrb_method_search_vm(mrb, &c, mid); + if (!m) { + mrb_value sym = mrb_symbol_value(mid); + mrb_sym missing = mrb_intern_lit(mrb, "method_missing"); + m = mrb_method_search_vm(mrb, &c, missing); + if (!m) { + mrb_value args; + + if (n == CALL_MAXARGS) { + args = regs[a+1]; + } + else { + args = mrb_ary_new_from_values(mrb, n, regs+a+1); + } + ERR_PC_SET(mrb, pc); + mrb_method_missing(mrb, mid, recv, args); + } + mid = missing; + if (n == CALL_MAXARGS) { + mrb_ary_unshift(mrb, regs[a+1], sym); + } + else { + value_move(regs+a+2, regs+a+1, ++n); + regs[a+1] = sym; + } + } + + /* replace callinfo */ + ci = mrb->c->ci; + ci->mid = mid; + ci->target_class = c; + if (n == CALL_MAXARGS) { + ci->argc = -1; + } + else { + ci->argc = n; + } + + /* move stack */ + value_move(mrb->c->stack, ®s[a], ci->argc+1); + + if (MRB_PROC_CFUNC_P(m)) { + mrb_value v = m->body.func(mrb, recv); + mrb->c->stack[0] = v; + mrb_gc_arena_restore(mrb, ai); + goto L_RETURN; + } + else { + /* setup environment for calling method */ + irep = m->body.irep; + pool = irep->pool; + syms = irep->syms; + if (ci->argc < 0) { + stack_extend(mrb, (irep->nregs < 3) ? 3 : irep->nregs); + } + else { + stack_extend(mrb, irep->nregs); + } + pc = irep->iseq; + } + JUMP; + } + + CASE(OP_BLKPUSH) { + /* A Bx R(A) := block (16=6:1:5:4) */ + int a = GETARG_A(i); + int bx = GETARG_Bx(i); + int m1 = (bx>>10)&0x3f; + int r = (bx>>9)&0x1; + int m2 = (bx>>4)&0x1f; + int lv = (bx>>0)&0xf; + mrb_value *stack; + + if (lv == 0) stack = regs + 1; + else { + struct REnv *e = uvenv(mrb, lv-1); + if (!e || e->cioff == 0 || + (!MRB_ENV_STACK_SHARED_P(e) && e->cxt.mid == 0) || + MRB_ENV_STACK_LEN(e) <= m1+r+m2+1) { + localjump_error(mrb, LOCALJUMP_ERROR_YIELD); + goto L_RAISE; + } + stack = e->stack + 1; + } + if (mrb_nil_p(stack[m1+r+m2])) { + localjump_error(mrb, LOCALJUMP_ERROR_YIELD); + goto L_RAISE; + } + regs[a] = stack[m1+r+m2]; + NEXT; + } + +#define TYPES2(a,b) ((((uint16_t)(a))<<8)|(((uint16_t)(b))&0xff)) +#define OP_MATH_BODY(op,v1,v2) do {\ + v1(regs[a]) = v1(regs[a]) op v2(regs[a+1]);\ +} while(0) + + CASE(OP_ADD) { + /* A B C R(A) := R(A)+R(A+1) (Syms[B]=:+,C=1)*/ + int a = GETARG_A(i); + + /* need to check if op is overridden */ + switch (TYPES2(mrb_type(regs[a]),mrb_type(regs[a+1]))) { + case TYPES2(MRB_TT_FIXNUM,MRB_TT_FIXNUM): + { + mrb_int x, y, z; + mrb_value *regs_a = regs + a; + + x = mrb_fixnum(regs_a[0]); + y = mrb_fixnum(regs_a[1]); + if (mrb_int_add_overflow(x, y, &z)) { + SET_FLOAT_VALUE(mrb, regs_a[0], (mrb_float)x + (mrb_float)y); + break; + } + SET_INT_VALUE(regs[a], z); + } + break; + case TYPES2(MRB_TT_FIXNUM,MRB_TT_FLOAT): + { + mrb_int x = mrb_fixnum(regs[a]); + mrb_float y = mrb_float(regs[a+1]); + SET_FLOAT_VALUE(mrb, regs[a], (mrb_float)x + y); + } + break; + case TYPES2(MRB_TT_FLOAT,MRB_TT_FIXNUM): +#ifdef MRB_WORD_BOXING + { + mrb_float x = mrb_float(regs[a]); + mrb_int y = mrb_fixnum(regs[a+1]); + SET_FLOAT_VALUE(mrb, regs[a], x + y); + } +#else + OP_MATH_BODY(+,mrb_float,mrb_fixnum); +#endif + break; + case TYPES2(MRB_TT_FLOAT,MRB_TT_FLOAT): +#ifdef MRB_WORD_BOXING + { + mrb_float x = mrb_float(regs[a]); + mrb_float y = mrb_float(regs[a+1]); + SET_FLOAT_VALUE(mrb, regs[a], x + y); + } +#else + OP_MATH_BODY(+,mrb_float,mrb_float); +#endif + break; + case TYPES2(MRB_TT_STRING,MRB_TT_STRING): + regs[a] = mrb_str_plus(mrb, regs[a], regs[a+1]); + break; + default: + goto L_SEND; + } + mrb_gc_arena_restore(mrb, ai); + NEXT; + } + + CASE(OP_SUB) { + /* A B C R(A) := R(A)-R(A+1) (Syms[B]=:-,C=1)*/ + int a = GETARG_A(i); + + /* need to check if op is overridden */ + switch (TYPES2(mrb_type(regs[a]),mrb_type(regs[a+1]))) { + case TYPES2(MRB_TT_FIXNUM,MRB_TT_FIXNUM): + { + mrb_int x, y, z; + + x = mrb_fixnum(regs[a]); + y = mrb_fixnum(regs[a+1]); + if (mrb_int_sub_overflow(x, y, &z)) { + SET_FLOAT_VALUE(mrb, regs[a], (mrb_float)x - (mrb_float)y); + break; + } + SET_INT_VALUE(regs[a], z); + } + break; + case TYPES2(MRB_TT_FIXNUM,MRB_TT_FLOAT): + { + mrb_int x = mrb_fixnum(regs[a]); + mrb_float y = mrb_float(regs[a+1]); + SET_FLOAT_VALUE(mrb, regs[a], (mrb_float)x - y); + } + break; + case TYPES2(MRB_TT_FLOAT,MRB_TT_FIXNUM): +#ifdef MRB_WORD_BOXING + { + mrb_float x = mrb_float(regs[a]); + mrb_int y = mrb_fixnum(regs[a+1]); + SET_FLOAT_VALUE(mrb, regs[a], x - y); + } +#else + OP_MATH_BODY(-,mrb_float,mrb_fixnum); +#endif + break; + case TYPES2(MRB_TT_FLOAT,MRB_TT_FLOAT): +#ifdef MRB_WORD_BOXING + { + mrb_float x = mrb_float(regs[a]); + mrb_float y = mrb_float(regs[a+1]); + SET_FLOAT_VALUE(mrb, regs[a], x - y); + } +#else + OP_MATH_BODY(-,mrb_float,mrb_float); +#endif + break; + default: + goto L_SEND; + } + NEXT; + } + + CASE(OP_MUL) { + /* A B C R(A) := R(A)*R(A+1) (Syms[B]=:*,C=1)*/ + int a = GETARG_A(i); + + /* need to check if op is overridden */ + switch (TYPES2(mrb_type(regs[a]),mrb_type(regs[a+1]))) { + case TYPES2(MRB_TT_FIXNUM,MRB_TT_FIXNUM): + { + mrb_int x, y, z; + + x = mrb_fixnum(regs[a]); + y = mrb_fixnum(regs[a+1]); + if (mrb_int_mul_overflow(x, y, &z)) { + SET_FLOAT_VALUE(mrb, regs[a], (mrb_float)x * (mrb_float)y); + break; + } + SET_INT_VALUE(regs[a], z); + } + break; + case TYPES2(MRB_TT_FIXNUM,MRB_TT_FLOAT): + { + mrb_int x = mrb_fixnum(regs[a]); + mrb_float y = mrb_float(regs[a+1]); + SET_FLOAT_VALUE(mrb, regs[a], (mrb_float)x * y); + } + break; + case TYPES2(MRB_TT_FLOAT,MRB_TT_FIXNUM): +#ifdef MRB_WORD_BOXING + { + mrb_float x = mrb_float(regs[a]); + mrb_int y = mrb_fixnum(regs[a+1]); + SET_FLOAT_VALUE(mrb, regs[a], x * y); + } +#else + OP_MATH_BODY(*,mrb_float,mrb_fixnum); +#endif + break; + case TYPES2(MRB_TT_FLOAT,MRB_TT_FLOAT): +#ifdef MRB_WORD_BOXING + { + mrb_float x = mrb_float(regs[a]); + mrb_float y = mrb_float(regs[a+1]); + SET_FLOAT_VALUE(mrb, regs[a], x * y); + } +#else + OP_MATH_BODY(*,mrb_float,mrb_float); +#endif + break; + default: + goto L_SEND; + } + NEXT; + } + + CASE(OP_DIV) { + /* A B C R(A) := R(A)/R(A+1) (Syms[B]=:/,C=1)*/ + int a = GETARG_A(i); + + /* need to check if op is overridden */ + switch (TYPES2(mrb_type(regs[a]),mrb_type(regs[a+1]))) { + case TYPES2(MRB_TT_FIXNUM,MRB_TT_FIXNUM): + { + mrb_int x = mrb_fixnum(regs[a]); + mrb_int y = mrb_fixnum(regs[a+1]); + double f; + if (y == 0) { + if (x > 0) f = INFINITY; + else if (x < 0) f = -INFINITY; + else /* if (x == 0) */ f = NAN; + } + else { + f = (mrb_float)x / (mrb_float)y; + } + SET_FLOAT_VALUE(mrb, regs[a], f); + } + break; + case TYPES2(MRB_TT_FIXNUM,MRB_TT_FLOAT): + { + mrb_int x = mrb_fixnum(regs[a]); + mrb_float y = mrb_float(regs[a+1]); + SET_FLOAT_VALUE(mrb, regs[a], (mrb_float)x / y); + } + break; + case TYPES2(MRB_TT_FLOAT,MRB_TT_FIXNUM): +#ifdef MRB_WORD_BOXING + { + mrb_float x = mrb_float(regs[a]); + mrb_int y = mrb_fixnum(regs[a+1]); + double f; + if (y == 0) { + f = INFINITY; + } + else { + f = x / y; + } + SET_FLOAT_VALUE(mrb, regs[a], f); + } +#else + OP_MATH_BODY(/,mrb_float,mrb_fixnum); +#endif + break; + case TYPES2(MRB_TT_FLOAT,MRB_TT_FLOAT): +#ifdef MRB_WORD_BOXING + { + mrb_float x = mrb_float(regs[a]); + mrb_float y = mrb_float(regs[a+1]); + SET_FLOAT_VALUE(mrb, regs[a], x / y); + } +#else + OP_MATH_BODY(/,mrb_float,mrb_float); +#endif + break; + default: + goto L_SEND; + } +#ifdef MRB_NAN_BOXING + if (isnan(mrb_float(regs[a]))) { + mrb_value v = mrb_float_value(mrb, mrb_float(regs[a])); + regs[a] = v; + } +#endif + NEXT; + } + + CASE(OP_ADDI) { + /* A B C R(A) := R(A)+C (Syms[B]=:+)*/ + int a = GETARG_A(i); + + /* need to check if + is overridden */ + switch (mrb_type(regs[a])) { + case MRB_TT_FIXNUM: + { + mrb_int x = mrb_fixnum(regs[a]); + mrb_int y = GETARG_C(i); + mrb_int z; + + if (mrb_int_add_overflow(x, y, &z)) { + SET_FLOAT_VALUE(mrb, regs[a], (mrb_float)x + (mrb_float)y); + break; + } + SET_INT_VALUE(regs[a], z); + } + break; + case MRB_TT_FLOAT: +#ifdef MRB_WORD_BOXING + { + mrb_float x = mrb_float(regs[a]); + SET_FLOAT_VALUE(mrb, regs[a], x + GETARG_C(i)); + } +#else + mrb_float(regs[a]) += GETARG_C(i); +#endif + break; + default: + SET_INT_VALUE(regs[a+1], GETARG_C(i)); + i = MKOP_ABC(OP_SEND, a, GETARG_B(i), 1); + goto L_SEND; + } + NEXT; + } + + CASE(OP_SUBI) { + /* A B C R(A) := R(A)-C (Syms[B]=:-)*/ + int a = GETARG_A(i); + mrb_value *regs_a = regs + a; + + /* need to check if + is overridden */ + switch (mrb_type(regs_a[0])) { + case MRB_TT_FIXNUM: + { + mrb_int x = mrb_fixnum(regs_a[0]); + mrb_int y = GETARG_C(i); + mrb_int z; + + if (mrb_int_sub_overflow(x, y, &z)) { + SET_FLOAT_VALUE(mrb, regs_a[0], (mrb_float)x - (mrb_float)y); + } + else { + SET_INT_VALUE(regs_a[0], z); + } + } + break; + case MRB_TT_FLOAT: +#ifdef MRB_WORD_BOXING + { + mrb_float x = mrb_float(regs[a]); + SET_FLOAT_VALUE(mrb, regs[a], x - GETARG_C(i)); + } +#else + mrb_float(regs_a[0]) -= GETARG_C(i); +#endif + break; + default: + SET_INT_VALUE(regs_a[1], GETARG_C(i)); + i = MKOP_ABC(OP_SEND, a, GETARG_B(i), 1); + goto L_SEND; + } + NEXT; + } + +#define OP_CMP_BODY(op,v1,v2) (v1(regs[a]) op v2(regs[a+1])) + +#define OP_CMP(op) do {\ + int result;\ + /* need to check if - is overridden */\ + switch (TYPES2(mrb_type(regs[a]),mrb_type(regs[a+1]))) {\ + case TYPES2(MRB_TT_FIXNUM,MRB_TT_FIXNUM):\ + result = OP_CMP_BODY(op,mrb_fixnum,mrb_fixnum);\ + break;\ + case TYPES2(MRB_TT_FIXNUM,MRB_TT_FLOAT):\ + result = OP_CMP_BODY(op,mrb_fixnum,mrb_float);\ + break;\ + case TYPES2(MRB_TT_FLOAT,MRB_TT_FIXNUM):\ + result = OP_CMP_BODY(op,mrb_float,mrb_fixnum);\ + break;\ + case TYPES2(MRB_TT_FLOAT,MRB_TT_FLOAT):\ + result = OP_CMP_BODY(op,mrb_float,mrb_float);\ + break;\ + default:\ + goto L_SEND;\ + }\ + if (result) {\ + SET_TRUE_VALUE(regs[a]);\ + }\ + else {\ + SET_FALSE_VALUE(regs[a]);\ + }\ +} while(0) + + CASE(OP_EQ) { + /* A B C R(A) := R(A)==R(A+1) (Syms[B]=:==,C=1)*/ + int a = GETARG_A(i); + if (mrb_obj_eq(mrb, regs[a], regs[a+1])) { + SET_TRUE_VALUE(regs[a]); + } + else { + OP_CMP(==); + } + NEXT; + } + + CASE(OP_LT) { + /* A B C R(A) := R(A)R(A+1) (Syms[B]=:>,C=1)*/ + int a = GETARG_A(i); + OP_CMP(>); + NEXT; + } + + CASE(OP_GE) { + /* A B C R(A) := R(A)>=R(A+1) (Syms[B]=:>=,C=1)*/ + int a = GETARG_A(i); + OP_CMP(>=); + NEXT; + } + + CASE(OP_ARRAY) { + /* A B C R(A) := ary_new(R(B),R(B+1)..R(B+C)) */ + int a = GETARG_A(i); + int b = GETARG_B(i); + int c = GETARG_C(i); + mrb_value v = mrb_ary_new_from_values(mrb, c, ®s[b]); + regs[a] = v; + mrb_gc_arena_restore(mrb, ai); + NEXT; + } + + CASE(OP_ARYCAT) { + /* A B mrb_ary_concat(R(A),R(B)) */ + int a = GETARG_A(i); + int b = GETARG_B(i); + mrb_value splat = mrb_ary_splat(mrb, regs[b]); + mrb_ary_concat(mrb, regs[a], splat); + mrb_gc_arena_restore(mrb, ai); + NEXT; + } + + CASE(OP_ARYPUSH) { + /* A B R(A).push(R(B)) */ + int a = GETARG_A(i); + int b = GETARG_B(i); + mrb_ary_push(mrb, regs[a], regs[b]); + NEXT; + } + + CASE(OP_AREF) { + /* A B C R(A) := R(B)[C] */ + int a = GETARG_A(i); + int b = GETARG_B(i); + int c = GETARG_C(i); + mrb_value v = regs[b]; + + if (!mrb_array_p(v)) { + if (c == 0) { + regs[a] = v; + } + else { + SET_NIL_VALUE(regs[a]); + } + } + else { + v = mrb_ary_ref(mrb, v, c); + regs[a] = v; + } + NEXT; + } + + CASE(OP_ASET) { + /* A B C R(B)[C] := R(A) */ + int a = GETARG_A(i); + int b = GETARG_B(i); + int c = GETARG_C(i); + mrb_ary_set(mrb, regs[b], c, regs[a]); + NEXT; + } + + CASE(OP_APOST) { + /* A B C *R(A),R(A+1)..R(A+C) := R(A) */ + int a = GETARG_A(i); + mrb_value v = regs[a]; + int pre = GETARG_B(i); + int post = GETARG_C(i); + struct RArray *ary; + int len, idx; + + if (!mrb_array_p(v)) { + v = mrb_ary_new_from_values(mrb, 1, ®s[a]); + } + ary = mrb_ary_ptr(v); + len = ARY_LEN(ary); + if (len > pre + post) { + v = mrb_ary_new_from_values(mrb, len - pre - post, ARY_PTR(ary)+pre); + regs[a++] = v; + while (post--) { + regs[a++] = ARY_PTR(ary)[len-post-1]; + } + } + else { + v = mrb_ary_new_capa(mrb, 0); + regs[a++] = v; + for (idx=0; idx+prereps[b]; + + irep_uplink(mrb, irep, nirep); + if (c & OP_L_CAPTURE) { + p = mrb_closure_new(mrb, nirep); + } + else { + p = mrb_proc_new(mrb, nirep); + } + if (c & OP_L_STRICT) p->flags |= MRB_PROC_STRICT; + regs[a] = mrb_obj_value(p); + mrb_gc_arena_restore(mrb, ai); + NEXT; + } + + CASE(OP_OCLASS) { + /* A R(A) := ::Object */ + regs[GETARG_A(i)] = mrb_obj_value(mrb->object_class); + NEXT; + } + + CASE(OP_CLASS) { + /* A B R(A) := newclass(R(A),Syms(B),R(A+1)) */ + struct RClass *c = 0, *baseclass; + int a = GETARG_A(i); + mrb_value base, super; + mrb_sym id = syms[GETARG_B(i)]; + + base = regs[a]; + super = regs[a+1]; + if (mrb_nil_p(base)) { + baseclass = mrb->c->ci->proc->target_class; + if (!baseclass) baseclass = mrb->c->ci->target_class; + + base = mrb_obj_value(baseclass); + } + c = mrb_vm_define_class(mrb, base, super, id); + regs[a] = mrb_obj_value(c); + mrb_gc_arena_restore(mrb, ai); + NEXT; + } + + CASE(OP_MODULE) { + /* A B R(A) := newmodule(R(A),Syms(B)) */ + struct RClass *c = 0, *baseclass; + int a = GETARG_A(i); + mrb_value base; + mrb_sym id = syms[GETARG_B(i)]; + + base = regs[a]; + if (mrb_nil_p(base)) { + baseclass = mrb->c->ci->proc->target_class; + if (!baseclass) baseclass = mrb->c->ci->target_class; + + base = mrb_obj_value(baseclass); + } + c = mrb_vm_define_module(mrb, base, id); + regs[a] = mrb_obj_value(c); + mrb_gc_arena_restore(mrb, ai); + NEXT; + } + + CASE(OP_EXEC) { + /* A Bx R(A) := blockexec(R(A),SEQ[Bx]) */ + int a = GETARG_A(i); + int bx = GETARG_Bx(i); + mrb_callinfo *ci; + mrb_value recv = regs[a]; + struct RProc *p; + mrb_irep *nirep = irep->reps[bx]; + + irep_uplink(mrb, irep, nirep); + nirep->target_class = mrb_class_ptr(recv); + /* prepare closure */ + p = mrb_closure_new(mrb, nirep); + p->c = NULL; + + /* prepare stack */ + ci = cipush(mrb); + ci->pc = pc + 1; + ci->acc = a; + ci->mid = 0; + ci->stackent = mrb->c->stack; + ci->argc = 0; + ci->target_class = mrb_class_ptr(recv); + + /* prepare stack */ + mrb->c->stack += a; + + /* setup closure */ + p->target_class = ci->target_class; + ci->proc = p; + + irep = p->body.irep; + pool = irep->pool; + syms = irep->syms; + ci->nregs = irep->nregs; + stack_extend(mrb, ci->nregs); + stack_clear(regs+1, ci->nregs-1); + pc = irep->iseq; + JUMP; + } + + CASE(OP_METHOD) { + /* A B R(A).newmethod(Syms(B),R(A+1)) */ + int a = GETARG_A(i); + struct RClass *c = mrb_class_ptr(regs[a]); + struct RProc *p = mrb_proc_ptr(regs[a+1]); + + mrb_define_method_raw(mrb, c, syms[GETARG_B(i)], p); + mrb_gc_arena_restore(mrb, ai); + NEXT; + } + + CASE(OP_SCLASS) { + /* A B R(A) := R(B).singleton_class */ + regs[GETARG_A(i)] = mrb_singleton_class(mrb, regs[GETARG_B(i)]); + mrb_gc_arena_restore(mrb, ai); + NEXT; + } + + CASE(OP_TCLASS) { + /* A R(A) := target_class */ + if (!mrb->c->ci->target_class) { + mrb_value exc = mrb_exc_new_str_lit(mrb, E_TYPE_ERROR, "no target class or module"); + mrb_exc_set(mrb, exc); + goto L_RAISE; + } + regs[GETARG_A(i)] = mrb_obj_value(mrb->c->ci->target_class); + NEXT; + } + + CASE(OP_RANGE) { + /* A B C R(A) := range_new(R(B),R(B+1),C) */ + int b = GETARG_B(i); + mrb_value val = mrb_range_new(mrb, regs[b], regs[b+1], GETARG_C(i)); + regs[GETARG_A(i)] = val; + mrb_gc_arena_restore(mrb, ai); + NEXT; + } + + CASE(OP_DEBUG) { + /* A B C debug print R(A),R(B),R(C) */ +#ifdef MRB_ENABLE_DEBUG_HOOK + mrb->debug_op_hook(mrb, irep, pc, regs); +#else +#ifndef MRB_DISABLE_STDIO + printf("OP_DEBUG %d %d %d\n", GETARG_A(i), GETARG_B(i), GETARG_C(i)); +#else + abort(); +#endif +#endif + NEXT; + } + + CASE(OP_STOP) { + /* stop VM */ + L_STOP: + { + int epos = mrb->c->ci->epos; + + while (mrb->c->eidx > epos) { + ecall(mrb, --mrb->c->eidx); + } + } + ERR_PC_CLR(mrb); + mrb->jmp = prev_jmp; + if (mrb->exc) { + return mrb_obj_value(mrb->exc); + } + return regs[irep->nlocals]; + } + + CASE(OP_ERR) { + /* Bx raise RuntimeError with message Lit(Bx) */ + mrb_value msg = mrb_str_dup(mrb, pool[GETARG_Bx(i)]); + mrb_value exc; + + if (GETARG_A(i) == 0) { + exc = mrb_exc_new_str(mrb, E_RUNTIME_ERROR, msg); + } + else { + exc = mrb_exc_new_str(mrb, E_LOCALJUMP_ERROR, msg); + } + ERR_PC_SET(mrb, pc); + mrb_exc_set(mrb, exc); + goto L_RAISE; + } + } + END_DISPATCH; +#undef regs + + } + MRB_CATCH(&c_jmp) { + exc_catched = TRUE; + goto RETRY_TRY_BLOCK; + } + MRB_END_EXC(&c_jmp); +} + +MRB_API mrb_value +mrb_run(mrb_state *mrb, struct RProc *proc, mrb_value self) +{ + if (mrb->c->ci->argc < 0) { + return mrb_vm_run(mrb, proc, self, 3); /* receiver, args and block) */ + } + else { + return mrb_vm_run(mrb, proc, self, mrb->c->ci->argc + 2); /* argc + 2 (receiver and block) */ + } +} + +MRB_API mrb_value +mrb_top_run(mrb_state *mrb, struct RProc *proc, mrb_value self, unsigned int stack_keep) +{ + mrb_callinfo *ci; + mrb_value v; + + if (!mrb->c->cibase) { + return mrb_vm_run(mrb, proc, self, stack_keep); + } + if (mrb->c->ci == mrb->c->cibase) { + mrb->c->ci->env = NULL; + return mrb_vm_run(mrb, proc, self, stack_keep); + } + ci = cipush(mrb); + ci->mid = 0; + ci->nregs = 1; /* protect the receiver */ + ci->acc = CI_ACC_SKIP; + ci->target_class = mrb->object_class; + v = mrb_vm_run(mrb, proc, self, stack_keep); + cipop(mrb); + + return v; +} + +#if defined(MRB_ENABLE_CXX_EXCEPTION) && defined(__cplusplus) +# if !defined(MRB_ENABLE_CXX_ABI) +} /* end of extern "C" */ +# endif +mrb_int mrb_jmpbuf::jmpbuf_id = 0; +# if !defined(MRB_ENABLE_CXX_ABI) +extern "C" { +# endif +#endif diff --git a/web/server/h2o/libh2o/deps/mruby/tasks/benchmark.rake b/web/server/h2o/libh2o/deps/mruby/tasks/benchmark.rake new file mode 100644 index 00000000..84e69ebe --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/tasks/benchmark.rake @@ -0,0 +1,91 @@ +module MRuby + BENCHMARK_REPEAT = 4 +end + +$dat_files = [] + +def bm_files + Dir.glob("#{MRUBY_ROOT}/benchmark/bm_*.rb") +end + +def build_config_name + if ENV['MRUBY_CONFIG'] + File.basename(ENV['MRUBY_CONFIG'], '.rb').gsub('build_config_', '') + else + "build" + end +end + +def plot_file + File.join(MRUBY_ROOT, 'benchmark', "#{build_config_name}.png") +end + +def plot + opts_file = "#{MRUBY_ROOT}/benchmark/plot.gpl" + opts = File.read(opts_file).each_line.to_a.map(&:strip).join(';') + + dat_files = $dat_files.group_by {|f| File.dirname(f).split(File::SEPARATOR)[-1]} + + opts += ";set output '#{plot_file}'" + + opts += ';plot ' + + opts += dat_files.keys.map do |data_file| + %Q['-' u 2:3:4:xtic(1) w hist title columnheader(1)] + end.join(',') + opts += ';' + + cmd = %Q{gnuplot -p -e "#{opts}"} + + IO.popen(cmd, 'w') do |p| + dat_files.each do |target_name, bm_files| + p.puts target_name.gsub('_', '-') + bm_files.each do |bm_file| + p.write File.read(bm_file) + end + p.puts "e" + end + end +end + + +MRuby.each_target do |target| + next if target.name == 'host' + mruby_bin = "#{target.build_dir}/bin/mruby" + + bm_files.each do |bm_file| + bm_name = File.basename bm_file, ".rb" + + dat_dir = File.join('benchmark', build_config_name, target.name) + dat_file = File.join(dat_dir, "#{bm_name}.dat") + $dat_files << dat_file + + directory dat_dir + + file dat_file => [bm_file, dat_dir, mruby_bin] do |task| + print bm_name + puts "..." + + data = (0...MRuby::BENCHMARK_REPEAT).map do |n| + str = %x{(time -f "%e %S %U" #{mruby_bin} #{bm_file}) 2>&1 >/dev/null} + str.split(' ').map(&:to_f) + end + + File.open(task.name, "w") do |f| + data = data.map {|_,r,s| (r + s) / 2.0} + min = data.min + max = data.max + avg = data.inject(&:+) / data.size + f.puts "#{bm_name.gsub('_', '-')} #{avg} #{min} #{max}" + end + end + end +end + +file plot_file => $dat_files do + plot +end + +task :benchmark => plot_file do + plot +end diff --git a/web/server/h2o/libh2o/deps/mruby/tasks/gitlab.rake b/web/server/h2o/libh2o/deps/mruby/tasks/gitlab.rake new file mode 100644 index 00000000..47117237 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/tasks/gitlab.rake @@ -0,0 +1,118 @@ +CI_VERSION = '0.7'.freeze +CI_BASE = 'ubuntu:16.10'.freeze +CI_COMPILERS = ['gcc-4.7', + 'gcc-4.8', + 'gcc-4.9', + 'gcc-5', + 'gcc-6', + 'clang-3.5', + 'clang-3.6', + 'clang-3.7', + 'clang-3.8', + 'clang-3.9'].freeze + +def ci_image_tag(compiler) + compiler.tr('+', 'c').delete('-').delete('.') +end + +def ci_docker_tag(compiler) + tag = ci_image_tag(compiler) + "registry.gitlab.com/dabroz/mruby:#{tag}_#{CI_VERSION}" +end + +def run_cmd(cmd) + puts cmd + raise 'error' unless system cmd +end + +desc 'recreate docker images for GitLab builds' +task :gitlab_dockers do + CI_COMPILERS.each do |compiler| + tag = ci_image_tag(compiler) + filename = "Dockerfile.#{tag}" + File.open(filename, 'wb') do |f| + f << "# #{compiler} - #{tag}\n" + f << "FROM #{CI_BASE}\n" + f << "RUN apt-get update && apt-get install -y git ruby2.3 ruby2.3-dev bison\n" + f << "RUN apt-get update && apt-get install -y binutils manpages\n" + f << "RUN apt-get update && apt-get install -y #{compiler}\n" + if compiler['gcc'] + f << "RUN apt-get update && apt-get install -y libx32#{compiler}-dev\n" + f << "RUN apt-get update && apt-get install --no-install-recommends -y #{compiler}-multilib\n" + end + f << "RUN dpkg --add-architecture i386\n" + f << "RUN apt-get update && apt-get install -y linux-libc-dev:i386\n" + if compiler['clang'] + f << "RUN apt-get update && apt-get install --no-install-recommends -y libc6-dev-i386\n" + f << "RUN apt-get update && apt-get install -y gcc gcc-multilib\n" + end + end + docker_tag = ci_docker_tag(compiler) + cmd1 = "docker build -t #{docker_tag} -f #{filename} ." + cmd2 = "docker push #{docker_tag}" + run_cmd cmd1 + run_cmd cmd2 + File.delete(filename) + end +end + +desc 'create build configurations and update .gitlab-ci.yml' +task :gitlab_config do + require 'yaml' + + configs = [] + [true, false].each do |mode_32| + ['', 'MRB_USE_FLOAT'].each do |float_conf| + ['', 'MRB_INT16', 'MRB_INT64'].each do |int_conf| + ['', 'MRB_NAN_BOXING', 'MRB_WORD_BOXING'].each do |boxing_conf| + ['', 'MRB_UTF8_STRING'].each do |utf8_conf| + next if (float_conf == 'MRB_USE_FLOAT') && (boxing_conf == 'MRB_NAN_BOXING') + next if (int_conf == 'MRB_INT64') && (boxing_conf == 'MRB_NAN_BOXING') + next if (int_conf == 'MRB_INT16') && (boxing_conf == 'MRB_WORD_BOXING') + next if (int_conf == 'MRB_INT64') && (boxing_conf == 'MRB_WORD_BOXING') && mode_32 + env = [float_conf, int_conf, boxing_conf, utf8_conf].map do |conf| + conf == '' ? nil : "-D#{conf}=1" + end.compact.join(' ') + bit = mode_32 ? '-m32 ' : '' + _info = '' + _info += mode_32 ? '32bit ' : '64bit ' + _info += float_conf['USE'] ? 'float ' : '' + _info += int_conf['16'] ? 'int16 ' : '' + _info += int_conf['64'] ? 'int64 ' : '' + _info += boxing_conf['NAN'] ? 'nan ' : '' + _info += boxing_conf['word'] ? 'word ' : '' + _info += utf8_conf['UTF8'] ? 'utf8 ' : '' + _info = _info.gsub(/ +/, ' ').strip.tr(' ', '_') + configs << { '_info' => _info, 'CFLAGS' => "#{bit}#{env}", 'LDFLAGS' => bit.strip.to_s } + end + end + end + end + end + path = './.gitlab-ci.yml' + data = YAML.load_file(path) + data.keys.select do |key| + key.start_with? 'Test' + end.each do |key| + data.delete(key) + end + CI_COMPILERS.each do |compiler| + configs.each do |config| + name = "Test #{compiler} #{config['_info']}" + hash = { + 'CC' => compiler, + 'CXX' => compiler.gsub('gcc', 'g++').gsub('clang', 'clang++'), + 'LD' => compiler + } + hash = hash.merge(config) + hash.delete('_info') + data[name] = { + 'stage' => 'test', + 'image' => ci_docker_tag(compiler), + 'variables' => hash, + 'script' => 'env; ./minirake --verbose all test' + } + end + end + File.open(path, 'w') { |f| YAML.dump(data, f) } +end diff --git a/web/server/h2o/libh2o/deps/mruby/tasks/libmruby.rake b/web/server/h2o/libh2o/deps/mruby/tasks/libmruby.rake new file mode 100644 index 00000000..540aa3eb --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/tasks/libmruby.rake @@ -0,0 +1,24 @@ +MRuby.each_target do + file libfile("#{build_dir}/lib/libmruby") => libmruby.flatten do |t| + archiver.run t.name, t.prerequisites + end + + file "#{build_dir}/lib/libmruby.flags.mak" => [__FILE__, libfile("#{build_dir}/lib/libmruby")] do |t| + open(t.name, 'w') do |f| + f.puts "MRUBY_CFLAGS = #{cc.all_flags}" + + gem_flags = gems.map { |g| g.linker.flags } + gem_library_paths = gems.map { |g| g.linker.library_paths } + f.puts "MRUBY_LDFLAGS = #{linker.all_flags(gem_library_paths, gem_flags)} #{linker.option_library_path % "#{build_dir}/lib"}" + + gem_flags_before_libraries = gems.map { |g| g.linker.flags_before_libraries } + f.puts "MRUBY_LDFLAGS_BEFORE_LIBS = #{[linker.flags_before_libraries, gem_flags_before_libraries].flatten.join(' ')}" + + gem_libraries = gems.map { |g| g.linker.libraries } + f.puts "MRUBY_LIBS = #{linker.option_library % 'mruby'} #{linker.library_flags(gem_libraries)}" + + f.puts "MRUBY_LIBMRUBY_PATH = #{libfile("#{build_dir}/lib/libmruby")}" + end + end + task :all => "#{build_dir}/lib/libmruby.flags.mak" +end diff --git a/web/server/h2o/libh2o/deps/mruby/tasks/mrbgems.rake b/web/server/h2o/libh2o/deps/mruby/tasks/mrbgems.rake new file mode 100644 index 00000000..65368c30 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/tasks/mrbgems.rake @@ -0,0 +1,96 @@ +MRuby.each_target do + if enable_gems? + # set up all gems + gems.each(&:setup) + gems.check self + + # loader all gems + self.libmruby << objfile("#{build_dir}/mrbgems/gem_init") + file objfile("#{build_dir}/mrbgems/gem_init") => ["#{build_dir}/mrbgems/gem_init.c", "#{build_dir}/LEGAL"] + file "#{build_dir}/mrbgems/gem_init.c" => [MRUBY_CONFIG, __FILE__] do |t| + FileUtils.mkdir_p "#{build_dir}/mrbgems" + open(t.name, 'w') do |f| + gem_func_gems = gems.select { |g| g.generate_functions } + gem_func_decls = gem_func_gems.each_with_object('') do |g, s| + s << "void GENERATED_TMP_mrb_#{g.funcname}_gem_init(mrb_state*);\n" \ + "void GENERATED_TMP_mrb_#{g.funcname}_gem_final(mrb_state*);\n" + end + gem_init_calls = gem_func_gems.each_with_object('') do |g, s| + s << " GENERATED_TMP_mrb_#{g.funcname}_gem_init(mrb);\n" + end + gem_final_calls = gem_func_gems.each_with_object('') do |g, s| + s << " GENERATED_TMP_mrb_#{g.funcname}_gem_final(mrb);\n" + end + f.puts %Q[/*] + f.puts %Q[ * This file contains a list of all] + f.puts %Q[ * initializing methods which are] + f.puts %Q[ * necessary to bootstrap all gems.] + f.puts %Q[ *] + f.puts %Q[ * IMPORTANT:] + f.puts %Q[ * This file was generated!] + f.puts %Q[ * All manual changes will get lost.] + f.puts %Q[ */] + f.puts %Q[] + f.puts %Q[#include ] + f.puts %Q[] + f.write gem_func_decls + f.puts %Q[] + f.puts %Q[static void] + f.puts %Q[mrb_final_mrbgems(mrb_state *mrb) {] + f.write gem_final_calls + f.puts %Q[}] + f.puts %Q[] + f.puts %Q[void] + f.puts %Q[mrb_init_mrbgems(mrb_state *mrb) {] + f.write gem_init_calls + f.puts %Q[ mrb_state_atexit(mrb, mrb_final_mrbgems);] unless gem_final_calls.empty? + f.puts %Q[}] + end + end + end + + # legal documents + file "#{build_dir}/LEGAL" => [MRUBY_CONFIG, __FILE__] do |t| + open(t.name, 'w+') do |f| + f.puts < @platform ? platform : @platform + end + } + if @platform === nil + raise(PlatformDirNotFound) + else + @platform = "android-#{@platform}" + end + end + end + if Integer(@platform.rpartition('-')[2]) < 21 + case arch + when /arm64-v8a/, /x86_64/, /mips64/ + raise NotImplementedError, "Platform (#{@platform}) has no implementation for architecture (#{arch})" + end + end + @platform + end + + def armeabi_v7a_mfpu + @armeabi_v7a_mfpu ||= (params[:mfpu] || 'vfpv3-d16').to_s + end + + def armeabi_v7a_mfloat_abi + @armeabi_v7a_mfloat_abi ||= (params[:mfloat_abi] || 'softfp').to_s + end + + def no_warn_mismatch + if %W(soft softfp).include? armeabi_v7a_mfloat_abi + '' + else + ',--no-warn-mismatch' + end + end + + def cc + case toolchain + when :gcc then bin_gcc('gcc') + when :clang then bin('clang') + end + end + + def ar + case toolchain + when :gcc then bin_gcc('ar') + when :clang then bin_gcc('ar') + end + end + + def ctarget + flags = [] + + case toolchain + when :gcc + case arch + when /armeabi-v7a/ then flags += %W(-march=armv7-a) + when /armeabi/ then flags += %W(-march=armv5te) + when /arm64-v8a/ then flags += %W(-march=armv8-a) + when /x86_64/ then flags += %W(-march=x86-64) + when /x86/ then flags += %W(-march=i686) + when /mips64/ then flags += %W(-march=mips64r6) + when /mips/ then flags += %W(-march=mips32) + end + when :clang + case arch + when /armeabi-v7a/ then flags += %W(-target armv7-none-linux-androideabi) + when /armeabi/ then flags += %W(-target armv5te-none-linux-androideabi) + when /arm64-v8a/ then flags += %W(-target aarch64-none-linux-android) + when /x86_64/ then flags += %W(-target x86_64-none-linux-android) + when /x86/ then flags += %W(-target i686-none-linux-android) + when /mips64/ then flags += %W(-target mips64el-none-linux-android) + when /mips/ then flags += %W(-target mipsel-none-linux-android) + end + end + + case arch + when /armeabi-v7a/ then flags += %W(-mfpu=#{armeabi_v7a_mfpu} -mfloat-abi=#{armeabi_v7a_mfloat_abi}) + when /armeabi/ then flags += %W(-mtune=xscale -msoft-float) + when /arm64-v8a/ then flags += %W() + when /x86_64/ then flags += %W() + when /x86/ then flags += %W() + when /mips64/ then flags += %W(-fmessage-length=0) + when /mips/ then flags += %W(-fmessage-length=0) + end + + flags + end + + def cflags + flags = [] + + flags += %W(-MMD -MP -D__android__ -DANDROID --sysroot="#{sysroot}") + flags += ctarget + case toolchain + when :gcc + when :clang + flags += %W(-gcc-toolchain "#{gcc_toolchain_path}" -Wno-invalid-command-line-argument -Wno-unused-command-line-argument) + end + flags += %W(-fpic -ffunction-sections -funwind-tables -fstack-protector-strong -no-canonical-prefixes) + + flags + end + + def ldflags + flags = [] + + flags += %W(--sysroot="#{sysroot}") + + flags + end + + def ldflags_before_libraries + flags = [] + + case toolchain + when :gcc + case arch + when /armeabi-v7a/ then flags += %W(-Wl#{no_warn_mismatch}) + end + when :clang + flags += %W(-gcc-toolchain "#{gcc_toolchain_path.to_s}") + case arch + when /armeabi-v7a/ then flags += %W(-target armv7-none-linux-androideabi -Wl,--fix-cortex-a8#{no_warn_mismatch}) + when /armeabi/ then flags += %W(-target armv5te-none-linux-androideabi) + when /arm64-v8a/ then flags += %W(-target aarch64-none-linux-android) + when /x86_64/ then flags += %W(-target x86_64-none-linux-android) + when /x86/ then flags += %W(-target i686-none-linux-android) + when /mips64/ then flags += %W(-target mips64el-none-linux-android) + when /mips/ then flags += %W(-target mipsel-none-linux-android) + end + end + flags += %W(-no-canonical-prefixes) + + flags + end +end + +MRuby::Toolchain.new(:android) do |conf, params| + android = MRuby::Toolchain::Android.new(params) + + toolchain android.toolchain + + [conf.cc, conf.cxx, conf.objc, conf.asm].each do |cc| + cc.command = android.cc + cc.flags = android.cflags + end + + conf.archiver.command = android.ar + conf.linker.command = android.cc + conf.linker.flags = android.ldflags + conf.linker.flags_before_libraries = android.ldflags_before_libraries +end diff --git a/web/server/h2o/libh2o/deps/mruby/tasks/toolchains/clang.rake b/web/server/h2o/libh2o/deps/mruby/tasks/toolchains/clang.rake new file mode 100644 index 00000000..c75fa030 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/tasks/toolchains/clang.rake @@ -0,0 +1,9 @@ +MRuby::Toolchain.new(:clang) do |conf, _params| + toolchain :gcc + + [conf.cc, conf.objc, conf.asm].each do |cc| + cc.command = ENV['CC'] || 'clang' + end + conf.cxx.command = ENV['CXX'] || 'clang++' + conf.linker.command = ENV['LD'] || 'clang' +end diff --git a/web/server/h2o/libh2o/deps/mruby/tasks/toolchains/gcc.rake b/web/server/h2o/libh2o/deps/mruby/tasks/toolchains/gcc.rake new file mode 100644 index 00000000..f370c0ab --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/tasks/toolchains/gcc.rake @@ -0,0 +1,58 @@ +MRuby::Toolchain.new(:gcc) do |conf, _params| + [conf.cc, conf.objc, conf.asm].each do |cc| + cc.command = ENV['CC'] || 'gcc' + cc.flags = [ENV['CFLAGS'] || %w(-g -std=gnu99 -O3 -Wall -Werror-implicit-function-declaration -Wdeclaration-after-statement -Wwrite-strings)] + cc.defines = %w(DISABLE_GEMS) + cc.option_include_path = '-I%s' + cc.option_define = '-D%s' + cc.compile_options = '%{flags} -MMD -o %{outfile} -c %{infile}' + cc.cxx_compile_flag = '-x c++ -std=c++03' + cc.cxx_exception_flag = '-fexceptions' + end + + [conf.cxx].each do |cxx| + cxx.command = ENV['CXX'] || 'g++' + cxx.flags = [ENV['CXXFLAGS'] || ENV['CFLAGS'] || %w(-g -O3 -Wall -Werror-implicit-function-declaration)] + cxx.defines = %w(DISABLE_GEMS) + cxx.option_include_path = '-I%s' + cxx.option_define = '-D%s' + cxx.compile_options = '%{flags} -MMD -o %{outfile} -c %{infile}' + cxx.cxx_compile_flag = '-x c++ -std=c++03' + cxx.cxx_exception_flag = '-fexceptions' + end + + conf.linker do |linker| + linker.command = ENV['LD'] || 'gcc' + linker.flags = [ENV['LDFLAGS'] || %w()] + linker.libraries = %w(m) + linker.library_paths = [] + linker.option_library = '-l%s' + linker.option_library_path = '-L%s' + linker.link_options = '%{flags} -o %{outfile} %{objs} %{flags_before_libraries} %{libs} %{flags_after_libraries}' + end + + [[conf.cc, 'c'], [conf.cxx, 'c++']].each do |cc, lang| + cc.instance_variable_set :@header_search_language, lang + def cc.header_search_paths + if @header_search_command != command + result = `echo | #{build.filename command} -x#{@header_search_language} -Wp,-v - -fsyntax-only 2>&1` + result = `echo | #{command} -x#{@header_search_language} -Wp,-v - -fsyntax-only 2>&1` if $?.exitstatus != 0 + return include_paths if $?.exitstatus != 0 + + @frameworks = [] + @header_search_paths = result.lines.map { |v| + framework = v.match(/^ (.*)(?: \(framework directory\))$/) + if framework + @frameworks << framework[1] + next nil + end + + v.match(/^ (.*)$/) + }.compact.map { |v| v[1] }.select { |v| File.directory? v } + @header_search_paths += include_paths + @header_search_command = command + end + @header_search_paths + end + end +end diff --git a/web/server/h2o/libh2o/deps/mruby/tasks/toolchains/openwrt.rake b/web/server/h2o/libh2o/deps/mruby/tasks/toolchains/openwrt.rake new file mode 100644 index 00000000..1637f6d9 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/tasks/toolchains/openwrt.rake @@ -0,0 +1,38 @@ +# usage of environmental variables to set the +# cross compiling toolchain proper +MRuby::Toolchain.new(:openwrt) do |conf| + [conf.cc, conf.objc, conf.asm].each do |cc| + cc.command = ENV['TARGET_CC'] + cc.flags = ENV['TARGET_CFLAGS'] + cc.include_paths = ["#{MRUBY_ROOT}/include"] + cc.defines = %w(DISABLE_GEMS) + cc.option_include_path = '-I%s' + cc.option_define = '-D%s' + cc.compile_options = '%{flags} -MMD -o %{outfile} -c %{infile}' + end + + [conf.cxx].each do |cxx| + cxx.command = ENV['TARGET_CXX'] + cxx.flags = ENV['TARGET_CXXFLAGS'] + cxx.include_paths = ["#{MRUBY_ROOT}/include"] + cxx.defines = %w(DISABLE_GEMS) + cxx.option_include_path = '-I%s' + cxx.option_define = '-D%s' + cxx.compile_options = '%{flags} -MMD -o %{outfile} -c %{infile}' + end + + conf.linker do |linker| + linker.command = ENV['TARGET_CC'] + linker.flags = ENV['TARGET_LDFLAGS'] + linker.libraries = %w(m) + linker.library_paths = [] + linker.option_library = '-l%s' + linker.option_library_path = '-L%s' + linker.link_options = '%{flags} -o %{outfile} %{objs} %{flags_before_libraries} %{libs} %{flags_after_libraries}' + end + + conf.archiver do |archiver| + archiver.command = ENV['TARGET_AR'] + archiver.archive_options = 'rs %{outfile} %{objs}' + end +end diff --git a/web/server/h2o/libh2o/deps/mruby/tasks/toolchains/visualcpp.rake b/web/server/h2o/libh2o/deps/mruby/tasks/toolchains/visualcpp.rake new file mode 100644 index 00000000..5bc24a73 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/tasks/toolchains/visualcpp.rake @@ -0,0 +1,68 @@ +MRuby::Toolchain.new(:visualcpp) do |conf, _params| + conf.cc do |cc| + cc.command = ENV['CC'] || 'cl.exe' + # C4013: implicit function declaration + cc.flags = [ENV['CFLAGS'] || %w(/c /nologo /W3 /we4013 /Zi /MD /O2 /D_CRT_SECURE_NO_WARNINGS)] + cc.defines = %w(DISABLE_GEMS MRB_STACK_EXTEND_DOUBLING) + cc.option_include_path = '/I%s' + cc.option_define = '/D%s' + cc.compile_options = "%{flags} /Fo%{outfile} %{infile}" + cc.cxx_compile_flag = '/TP' + cc.cxx_exception_flag = '/EHs' + end + + conf.cxx do |cxx| + cxx.command = ENV['CXX'] || 'cl.exe' + cxx.flags = [ENV['CXXFLAGS'] || ENV['CFLAGS'] || %w(/c /nologo /W3 /Zi /MD /O2 /EHs /D_CRT_SECURE_NO_WARNINGS)] + cxx.defines = %w(DISABLE_GEMS MRB_STACK_EXTEND_DOUBLING) + cxx.option_include_path = '/I%s' + cxx.option_define = '/D%s' + cxx.compile_options = "%{flags} /Fo%{outfile} %{infile}" + cxx.cxx_compile_flag = '/TP' + cxx.cxx_exception_flag = '/EHs' + end + + conf.linker do |linker| + linker.command = ENV['LD'] || 'link.exe' + linker.flags = [ENV['LDFLAGS'] || %w(/NOLOGO /DEBUG /INCREMENTAL:NO /OPT:ICF /OPT:REF)] + linker.libraries = %w() + linker.library_paths = %w() + linker.option_library = '%s.lib' + linker.option_library_path = '/LIBPATH:%s' + linker.link_options = "%{flags} /OUT:%{outfile} %{objs} %{flags_before_libraries} %{libs} %{flags_after_libraries}" + end + + conf.archiver do |archiver| + archiver.command = ENV['AR'] || 'lib.exe' + archiver.archive_options = '/nologo /OUT:%{outfile} %{objs}' + end + + conf.yacc do |yacc| + yacc.command = ENV['YACC'] || 'bison.exe' + yacc.compile_options = '-o %{outfile} %{infile}' + end + + conf.gperf do |gperf| + gperf.command = 'gperf.exe' + gperf.compile_options = '-L ANSI-C -C -p -j1 -i 1 -g -o -t -N mrb_reserved_word -k"1,3,$" %{infile} > %{outfile}' + end + + conf.exts do |exts| + exts.object = '.obj' + exts.executable = '.exe' + exts.library = '.lib' + end + + conf.file_separator = '\\' + + if require 'open3' + Open3.popen3 conf.cc.command do |_, _, e, _| + if /Version (\d{2})\.\d{2}\.\d{5}/ =~ e.gets && $1.to_i <= 17 + m = "# VS2010/2012 support will be dropped after the next release! #" + h = "#" * m.length + puts h, m, h + end + end + end + +end diff --git a/web/server/h2o/libh2o/deps/mruby/test/assert.rb b/web/server/h2o/libh2o/deps/mruby/test/assert.rb new file mode 100644 index 00000000..fb7ae9ab --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/test/assert.rb @@ -0,0 +1,248 @@ +$ok_test = 0 +$ko_test = 0 +$kill_test = 0 +$asserts = [] +$test_start = Time.now if Object.const_defined?(:Time) + +# Implementation of print due to the reason that there might be no print +def t_print(*args) + i = 0 + len = args.size + while i < len + str = args[i].to_s + __t_printstr__ str rescue print str + i += 1 + end +end + +## +# Create the assertion in a readable way +def assertion_string(err, str, iso=nil, e=nil, bt=nil) + msg = "#{err}#{str}" + msg += " [#{iso}]" if iso && iso != '' + msg += " => #{e.message}" if e + msg += " (mrbgems: #{GEMNAME})" if Object.const_defined?(:GEMNAME) + if $mrbtest_assert && $mrbtest_assert.size > 0 + $mrbtest_assert.each do |idx, assert_msg, diff| + msg += "\n - Assertion[#{idx}] Failed: #{assert_msg}\n#{diff}" + end + end + msg += "\nbacktrace:\n\t#{bt.join("\n\t")}" if bt + msg +end + +## +# Verify a code block. +# +# str : A remark which will be printed in case +# this assertion fails +# iso : The ISO reference code of the feature +# which will be tested by this +# assertion +def assert(str = 'Assertion failed', iso = '') + t_print(str, (iso != '' ? " [#{iso}]" : ''), ' : ') if $mrbtest_verbose + begin + $mrbtest_assert = [] + $mrbtest_assert_idx = 0 + yield + if($mrbtest_assert.size > 0) + $asserts.push(assertion_string('Fail: ', str, iso, nil)) + $ko_test += 1 + t_print('F') + else + $ok_test += 1 + t_print('.') + end + rescue Exception => e + bt = e.backtrace if $mrbtest_verbose + if e.class.to_s == 'MRubyTestSkip' + $asserts.push "Skip: #{str} #{iso} #{e.cause}" + t_print('?') + else + $asserts.push(assertion_string("#{e.class}: ", str, iso, e, bt)) + $kill_test += 1 + t_print('X') + end + ensure + $mrbtest_assert = nil + end + t_print("\n") if $mrbtest_verbose +end + +def assertion_diff(exp, act) + " Expected: #{exp.inspect}\n" + + " Actual: #{act.inspect}" +end + +def assert_true(ret, msg = nil, diff = nil) + if $mrbtest_assert + $mrbtest_assert_idx += 1 + unless ret + msg = "Expected #{ret.inspect} to be true" unless msg + diff = assertion_diff(true, ret) unless diff + $mrbtest_assert.push([$mrbtest_assert_idx, msg, diff]) + end + end + ret +end + +def assert_false(ret, msg = nil, diff = nil) + if $mrbtest_assert + $mrbtest_assert_idx += 1 + if ret + msg = "Expected #{ret.inspect} to be false" unless msg + diff = assertion_diff(false, ret) unless diff + + $mrbtest_assert.push([$mrbtest_assert_idx, msg, diff]) + end + end + !ret +end + +def assert_equal(arg1, arg2 = nil, arg3 = nil) + if block_given? + exp, act, msg = arg1, yield, arg2 + else + exp, act, msg = arg1, arg2, arg3 + end + + msg = "Expected to be equal" unless msg + diff = assertion_diff(exp, act) + assert_true(exp == act, msg, diff) +end + +def assert_not_equal(arg1, arg2 = nil, arg3 = nil) + if block_given? + exp, act, msg = arg1, yield, arg2 + else + exp, act, msg = arg1, arg2, arg3 + end + + msg = "Expected to be not equal" unless msg + diff = assertion_diff(exp, act) + assert_false(exp == act, msg, diff) +end + +def assert_nil(obj, msg = nil) + msg = "Expected #{obj.inspect} to be nil" unless msg + diff = assertion_diff(nil, obj) + assert_true(obj.nil?, msg, diff) +end + +def assert_include(collection, obj, msg = nil) + msg = "Expected #{collection.inspect} to include #{obj.inspect}" unless msg + diff = " Collection: #{collection.inspect}\n" + + " Object: #{obj.inspect}" + assert_true(collection.include?(obj), msg, diff) +end + +def assert_not_include(collection, obj, msg = nil) + msg = "Expected #{collection.inspect} to not include #{obj.inspect}" unless msg + diff = " Collection: #{collection.inspect}\n" + + " Object: #{obj.inspect}" + assert_false(collection.include?(obj), msg, diff) +end + +def assert_raise(*exc) + return true unless $mrbtest_assert + $mrbtest_assert_idx += 1 + + msg = (exc.last.is_a? String) ? exc.pop : nil + + begin + yield + msg ||= "Expected to raise #{exc} but nothing was raised." + diff = nil + $mrbtest_assert.push [$mrbtest_assert_idx, msg, diff] + false + rescue *exc + true + rescue Exception => e + msg ||= "Expected to raise #{exc}, not" + diff = " Class: <#{e.class}>\n" + + " Message: #{e.message}" + $mrbtest_assert.push [$mrbtest_assert_idx, msg, diff] + false + end +end + +def assert_nothing_raised(msg = nil) + return true unless $mrbtest_assert + $mrbtest_assert_idx += 1 + + begin + yield + true + rescue Exception => e + msg ||= "Expected not to raise #{exc.join(', ')} but it raised" + diff = " Class: <#{e.class}>\n" + + " Message: #{e.message}" + $mrbtest_assert.push [$mrbtest_assert_idx, msg, diff] + false + end +end + +## +# Fails unless +obj+ is a kind of +cls+. +def assert_kind_of(cls, obj, msg = nil) + msg = "Expected #{obj.inspect} to be a kind of #{cls}, not #{obj.class}" unless msg + diff = assertion_diff(cls, obj.class) + assert_true(obj.kind_of?(cls), msg, diff) +end + +## +# Fails unless +exp+ is equal to +act+ in terms of a Float +def assert_float(exp, act, msg = nil) + msg = "Float #{exp} expected to be equal to float #{act}" unless msg + diff = assertion_diff(exp, act) + assert_true check_float(exp, act), msg, diff +end + +## +# Report the test result and print all assertions +# which were reported broken. +def report() + t_print("\n") + + $asserts.each do |msg| + t_print "#{msg}\n" + end + + $total_test = $ok_test+$ko_test+$kill_test + t_print("Total: #{$total_test}\n") + + t_print(" OK: #{$ok_test}\n") + t_print(" KO: #{$ko_test}\n") + t_print("Crash: #{$kill_test}\n") + + if Object.const_defined?(:Time) + t_time = Time.now - $test_start + t_print(" Time: #{t_time.round(2)} seconds\n") + end +end + +## +# Performs fuzzy check for equality on methods returning floats +def check_float(a, b) + tolerance = Mrbtest::FLOAT_TOLERANCE + a = a.to_f + b = b.to_f + if a.finite? and b.finite? + (a-b).abs < tolerance + else + true + end +end + +## +# Skip the test +class MRubyTestSkip < NotImplementedError + attr_accessor :cause + def initialize(cause) + @cause = cause + end +end + +def skip(cause = "") + raise MRubyTestSkip.new(cause) +end diff --git a/web/server/h2o/libh2o/deps/mruby/test/bintest.rb b/web/server/h2o/libh2o/deps/mruby/test/bintest.rb new file mode 100644 index 00000000..12971a9d --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/test/bintest.rb @@ -0,0 +1,33 @@ +$:.unshift File.dirname(File.dirname(File.expand_path(__FILE__))) +require 'test/assert.rb' + +def cmd(s) + case RbConfig::CONFIG['host_os'] + when /mswin(?!ce)|mingw|bccwin/ + "bin\\#{s}.exe" + else + "bin/#{s}" + end +end + +def shellquote(s) + case RbConfig::CONFIG['host_os'] + when /mswin(?!ce)|mingw|bccwin/ + "\"#{s}\"" + else + "'#{s}'" + end +end + +ARGV.each do |gem| + case RbConfig::CONFIG['host_os'] + when /mswin(?!ce)|mingw|bccwin/ + gem = gem.gsub('\\', '/') + end + + Dir["#{gem}/bintest/**/*.rb"].each do |file| + load file + end +end + +load 'test/report.rb' diff --git a/web/server/h2o/libh2o/deps/mruby/test/report.rb b/web/server/h2o/libh2o/deps/mruby/test/report.rb new file mode 100644 index 00000000..fb77fd0a --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/test/report.rb @@ -0,0 +1,4 @@ +report +if $ko_test > 0 or $kill_test > 0 + raise "mrbtest failed (KO:#{$ko_test}, Crash:#{$kill_test})" +end diff --git a/web/server/h2o/libh2o/deps/mruby/test/t/argumenterror.rb b/web/server/h2o/libh2o/deps/mruby/test/t/argumenterror.rb new file mode 100644 index 00000000..abb53429 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/test/t/argumenterror.rb @@ -0,0 +1,16 @@ +## +# ArgumentError ISO Test + +assert('ArgumentError', '15.2.24') do + e2 = nil + a = [] + begin + # this will cause an exception due to the wrong arguments + a[] + rescue => e1 + e2 = e1 + end + + assert_equal(Class, ArgumentError.class) + assert_equal(ArgumentError, e2.class) +end diff --git a/web/server/h2o/libh2o/deps/mruby/test/t/array.rb b/web/server/h2o/libh2o/deps/mruby/test/t/array.rb new file mode 100644 index 00000000..7c11265a --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/test/t/array.rb @@ -0,0 +1,394 @@ +## +# Array ISO Test + +assert('Array', '15.2.12') do + assert_equal(Class, Array.class) +end + +assert('Array inclueded modules', '15.2.12.3') do + assert_true(Array.include?(Enumerable)) +end + +assert('Array.[]', '15.2.12.4.1') do + assert_equal([1, 2, 3], Array.[](1,2,3)) +end + +class SubArray < Array +end + +assert('SubArray.[]') do + a = SubArray[1, 2, 3] + assert_equal(SubArray, a.class) +end + +assert('Array#+', '15.2.12.5.1') do + assert_equal([1, 1], [1].+([1])) +end + +assert('Array#*', '15.2.12.5.2') do + assert_raise(ArgumentError) do + # this will cause an exception due to the wrong argument + [1].*(-1) + end + assert_equal([1, 1, 1], [1].*(3)) + assert_equal([], [1].*(0)) +end + +assert('Array#<<', '15.2.12.5.3') do + assert_equal([1, 1], [1].<<(1)) +end + +assert('Array#[]', '15.2.12.5.4') do + a = Array.new + assert_raise(ArgumentError) do + # this will cause an exception due to the wrong arguments + a.[]() + end + assert_raise(ArgumentError) do + # this will cause an exception due to the wrong arguments + a.[](1,2,3) + end + + assert_equal(2, [1,2,3].[](1)) + assert_equal(nil, [1,2,3].[](4)) + assert_equal(3, [1,2,3].[](-1)) + assert_equal(nil, [1,2,3].[](-4)) + + a = [ "a", "b", "c", "d", "e" ] + assert_equal("b", a[1.1]) + assert_equal(["b", "c"], a[1,2]) + assert_equal(["b", "c", "d"], a[1..-2]) +end + +assert('Array#[]=', '15.2.12.5.5') do + a = Array.new + assert_raise(ArgumentError) do + # this will cause an exception due to the wrong arguments + a.[]=() + end + assert_raise(ArgumentError) do + # this will cause an exception due to the wrong arguments + a.[]=(1,2,3,4) + end + assert_raise(IndexError) do + # this will cause an exception due to the wrong arguments + a = [1,2,3,4,5] + a[1, -1] = 10 + end + + assert_equal(4, [1,2,3].[]=(1,4)) + assert_equal(3, [1,2,3].[]=(1,2,3)) + + a = [1,2,3,4,5] + a[3..-1] = 6 + assert_equal([1,2,3,6], a) + + a = [1,2,3,4,5] + a[3..-1] = [] + assert_equal([1,2,3], a) + + a = [1,2,3,4,5] + a[2...4] = 6 + assert_equal([1,2,6,5], a) + + # passing self (#3274) + a = [1,2,3] + a[1,0] = a + assert_equal([1,1,2,3,2,3], a) + a = [1,2,3] + a[-1,0] = a + assert_equal([1,2,1,2,3,3], a) +end + +assert('Array#clear', '15.2.12.5.6') do + a = [1] + a.clear + assert_equal([], a) +end + +assert('Array#collect!', '15.2.12.5.7') do + a = [1,2,3] + a.collect! { |i| i + i } + assert_equal([2,4,6], a) +end + +assert('Array#concat', '15.2.12.5.8') do + assert_equal([1,2,3,4], [1, 2].concat([3, 4])) + + # passing self (#3302) + a = [1,2,3] + a.concat(a) + assert_equal([1,2,3,1,2,3], a) +end + +assert('Array#delete_at', '15.2.12.5.9') do + a = [1,2,3] + assert_equal(2, a.delete_at(1)) + assert_equal([1,3], a) + assert_equal(nil, a.delete_at(3)) + assert_equal([1,3], a) + assert_equal(nil, a.delete_at(-3)) + assert_equal([1,3], a) + assert_equal(3, a.delete_at(-1)) + assert_equal([1], a) +end + +assert('Array#each', '15.2.12.5.10') do + a = [1,2,3] + b = 0 + a.each {|i| b += i} + assert_equal(6, b) +end + +assert('Array#each_index', '15.2.12.5.11') do + a = [1] + b = nil + a.each_index {|i| b = i} + assert_equal(0, b) +end + +assert('Array#empty?', '15.2.12.5.12') do + a = [] + b = [b] + assert_true([].empty?) + assert_false([1].empty?) +end + +assert('Array#first', '15.2.12.5.13') do + assert_raise(ArgumentError) do + # this will cause an exception due to the wrong argument + [1,2,3].first(-1) + end + assert_raise(ArgumentError) do + # this will cause an exception due to the wrong argument + [1,2,3].first(1,2) + end + + assert_nil([].first) + + b = [1,2,3] + assert_equal(1, b.first) + assert_equal([], b.first(0)) + assert_equal([1], b.first(1)) + assert_equal([1,2,3], b.first(4)) +end + +assert('Array#index', '15.2.12.5.14') do + a = [1,2,3] + + assert_equal(1, a.index(2)) + assert_equal(nil, a.index(0)) +end + +assert('Array#initialize', '15.2.12.5.15') do + a = [].initialize(1) + b = [].initialize(2) + c = [].initialize(2, 1) + d = [].initialize(2) {|i| i} + + assert_equal([nil], a) + assert_equal([nil,nil], b) + assert_equal([1,1], c) + assert_equal([0,1], d) +end + +assert('Array#initialize_copy', '15.2.12.5.16') do + a = [1,2,3] + b = [].initialize_copy(a) + + assert_equal([1,2,3], b) +end + +assert('Array#join', '15.2.12.5.17') do + a = [1,2,3].join + b = [1,2,3].join(',') + + assert_equal('123', a) + assert_equal('1,2,3', b) +end + +assert('Array#last', '15.2.12.5.18') do + assert_raise(ArgumentError) do + # this will cause an exception due to the wrong argument + [1,2,3].last(-1) + end + + a = [1,2,3] + assert_equal(3, a.last) + assert_nil([].last) +end + +assert('Array#length', '15.2.12.5.19') do + a = [1,2,3] + + assert_equal(3, a.length) +end + +assert('Array#map!', '15.2.12.5.20') do + a = [1,2,3] + a.map! { |i| i + i } + assert_equal([2,4,6], a) +end + +assert('Array#pop', '15.2.12.5.21') do + a = [1,2,3] + b = a.pop + + assert_nil([].pop) + assert_equal([1,2], a) + assert_equal(3, b) + + assert_raise(RuntimeError) { [].freeze.pop } +end + +assert('Array#push', '15.2.12.5.22') do + a = [1,2,3] + b = a.push(4) + + assert_equal([1,2,3,4], a) + assert_equal([1,2,3,4], b) +end + +assert('Array#replace', '15.2.12.5.23') do + a = [1,2,3] + b = [].replace(a) + + assert_equal([1,2,3], b) +end + +assert('Array#reverse', '15.2.12.5.24') do + a = [1,2,3] + b = a.reverse + + assert_equal([1,2,3], a) + assert_equal([3,2,1], b) +end + +assert('Array#reverse!', '15.2.12.5.25') do + a = [1,2,3] + b = a.reverse! + + assert_equal([3,2,1], a) + assert_equal([3,2,1], b) +end + +assert('Array#rindex', '15.2.12.5.26') do + a = [1,2,3] + + assert_equal(1, a.rindex(2)) + assert_equal(nil, a.rindex(0)) +end + +assert('Array#shift', '15.2.12.5.27') do + a = [1,2,3] + b = a.shift + + assert_nil([].shift) + assert_equal([2,3], a) + assert_equal(1, b) + + assert_raise(RuntimeError) { [].freeze.shift } +end + +assert('Array#size', '15.2.12.5.28') do + a = [1,2,3] + + assert_equal(3, a.size) +end + +assert('Array#slice', '15.2.12.5.29') do + a = "12345".slice(1, 3) + b = a.slice(0) + + assert_equal("2:", "#{b}:") + assert_equal(2, [1,2,3].[](1)) +end + +assert('Array#unshift', '15.2.12.5.30') do + a = [2,3] + b = a.unshift(1) + c = [2,3] + d = c.unshift(0, 1) + + assert_equal([1,2,3], a) + assert_equal([1,2,3], b) + assert_equal([0,1,2,3], c) + assert_equal([0,1,2,3], d) +end + +assert('Array#to_s', '15.2.12.5.31 / 15.2.12.5.32') do + a = [2, 3, 4, 5] + r1 = a.to_s + r2 = a.inspect + + assert_equal(r2, r1) + assert_equal("[2, 3, 4, 5]", r1) +end + +assert('Array#==', '15.2.12.5.33') do + assert_false(["a", "c"] == ["a", "c", 7]) + assert_true(["a", "c", 7] == ["a", "c", 7]) + assert_false(["a", "c", 7] == ["a", "d", "f"]) +end + +assert('Array#eql?', '15.2.12.5.34') do + a1 = [ 1, 2, 3 ] + a2 = [ 1, 2, 3 ] + a3 = [ 1.0, 2.0, 3.0 ] + + assert_true(a1.eql? a2) + assert_false(a1.eql? a3) +end + +assert('Array#hash', '15.2.12.5.35') do + a = [ 1, 2, 3 ] + + #assert_true(a.hash.is_a? Integer) + assert_true(a.hash.is_a? Integral) # mruby special + assert_equal([1,2].hash, [1,2].hash) +end + +assert('Array#<=>', '15.2.12.5.36') do + r1 = [ "a", "a", "c" ] <=> [ "a", "b", "c" ] #=> -1 + r2 = [ 1, 2, 3, 4, 5, 6 ] <=> [ 1, 2 ] #=> +1 + r3 = [ "a", "b", "c" ] <=> [ "a", "b", "c" ] #=> 0 + + assert_equal(-1, r1) + assert_equal(+1, r2) + assert_equal(0, r3) +end + +# Not ISO specified + +assert("Array (Shared Array Corruption)") do + a = [ "a", "b", "c", "d", "e", "f" ] + b = a.slice(1, 3) + a.clear + b.clear +end + +assert("Array (Longish inline array)") do + ary = [[0, 0], [1, 1], [2, 2], [3, 3], [4, 4], [5, 5], [6, 6], [7, 7], [8, 8], [9, 9], [10, 10], [11, 11], [12, 12], [13, 13], [14, 14], [15, 15], [16, 16], [17, 17], [18, 18], [19, 19], [20, 20], [21, 21], [22, 22], [23, 23], [24, 24], [25, 25], [26, 26], [27, 27], [28, 28], [29, 29], [30, 30], [31, 31], [32, 32], [33, 33], [34, 34], [35, 35], [36, 36], [37, 37], [38, 38], [39, 39], [40, 40], [41, 41], [42, 42], [43, 43], [44, 44], [45, 45], [46, 46], [47, 47], [48, 48], [49, 49], [50, 50], [51, 51], [52, 52], [53, 53], [54, 54], [55, 55], [56, 56], [57, 57], [58, 58], [59, 59], [60, 60], [61, 61], [62, 62], [63, 63], [64, 64], [65, 65], [66, 66], [67, 67], [68, 68], [69, 69], [70, 70], [71, 71], [72, 72], [73, 73], [74, 74], [75, 75], [76, 76], [77, 77], [78, 78], [79, 79], [80, 80], [81, 81], [82, 82], [83, 83], [84, 84], [85, 85], [86, 86], [87, 87], [88, 88], [89, 89], [90, 90], [91, 91], [92, 92], [93, 93], [94, 94], [95, 95], [96, 96], [97, 97], [98, 98], [99, 99], [100, 100], [101, 101], [102, 102], [103, 103], [104, 104], [105, 105], [106, 106], [107, 107], [108, 108], [109, 109], [110, 110], [111, 111], [112, 112], [113, 113], [114, 114], [115, 115], [116, 116], [117, 117], [118, 118], [119, 119], [120, 120], [121, 121], [122, 122], [123, 123], [124, 124], [125, 125], [126, 126], [127, 127], [128, 128], [129, 129], [130, 130], [131, 131], [132, 132], [133, 133], [134, 134], [135, 135], [136, 136], [137, 137], [138, 138], [139, 139], [140, 140], [141, 141], [142, 142], [143, 143], [144, 144], [145, 145], [146, 146], [147, 147], [148, 148], [149, 149], [150, 150], [151, 151], [152, 152], [153, 153], [154, 154], [155, 155], [156, 156], [157, 157], [158, 158], [159, 159], [160, 160], [161, 161], [162, 162], [163, 163], [164, 164], [165, 165], [166, 166], [167, 167], [168, 168], [169, 169], [170, 170], [171, 171], [172, 172], [173, 173], [174, 174], [175, 175], [176, 176], [177, 177], [178, 178], [179, 179], [180, 180], [181, 181], [182, 182], [183, 183], [184, 184], [185, 185], [186, 186], [187, 187], [188, 188], [189, 189], [190, 190], [191, 191], [192, 192], [193, 193], [194, 194], [195, 195], [196, 196], [197, 197], [198, 198], [199, 199]] + h = Hash.new(0) + ary.each {|p| h[p.class] += 1} + assert_equal({Array=>200}, h) +end + +assert("Array#rindex") do + class Sneaky + def ==(*) + $a.clear + $a.replace([1]) + false + end + end + $a = [2, 3, 4, 5, 6, 7, 8, 9, 10, Sneaky.new] + assert_equal 0, $a.rindex(1) +end + +assert('Array#freeze') do + a = [].freeze + assert_raise(RuntimeError) do + a[0] = 1 + end +end diff --git a/web/server/h2o/libh2o/deps/mruby/test/t/basicobject.rb b/web/server/h2o/libh2o/deps/mruby/test/t/basicobject.rb new file mode 100644 index 00000000..f3317126 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/test/t/basicobject.rb @@ -0,0 +1,11 @@ +## +# BasicObject + +assert('BasicObject') do + assert_equal(Class, BasicObject.class) +end + +assert('BasicObject superclass') do + assert_nil(BasicObject.superclass) +end + diff --git a/web/server/h2o/libh2o/deps/mruby/test/t/bs_block.rb b/web/server/h2o/libh2o/deps/mruby/test/t/bs_block.rb new file mode 100644 index 00000000..04a4a15b --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/test/t/bs_block.rb @@ -0,0 +1,521 @@ +## +# Bootstrap tests for blocks + +assert('BS Block 1') do + assert_equal(1) do + 1.times{ + begin + a = 1 + ensure + foo = nil + end + } + end +end + +assert('BS Block 2') do + assert_equal 2, [1,2,3].find{|x| x == 2} +end + +assert('BS Block 3') do + class E + include Enumerable + def each(&block) + [1, 2, 3].each(&block) + end + end + assert_equal 2, E.new.find {|x| x == 2 } +end + +assert('BS Block 3') do + sum = 0 + for x in [1, 2, 3] + sum += x + end + assert_equal 6, sum +end + +assert('BS Block 4') do + sum = 0 + for x in (1..5) + sum += x + end + assert_equal 15, sum +end + +assert('BS Block 5') do + sum = 0 + for x in [] + sum += x + end + assert_equal 0, sum +end + +assert('BS Block 6') do + ans = [] + assert_equal(1) do + 1.times{ + for n in 1..3 + a = n + ans << a + end + } + end +end + +assert('BS Block 7') do + ans = [] + assert_equal((1..3)) do + for m in 1..3 + for n in 2..4 + a = [m, n] + ans << a + end + end + end +end + +assert('BS Block 8') do + assert_equal [1, 2, 3], (1..3).to_a +end + +assert('BS Block 9') do + assert_equal([4, 8, 12]) do + (1..3).map{|e| + e * 4 + } + end +end + +assert('BS Block 10') do + def m + yield + end + def n + yield + end + + assert_equal(100) do + m{ + n{ + 100 + } + } + end +end + +assert('BS Block 11') do + def m + yield 1 + end + + assert_equal(20) do + m{|ib| + m{|jb| + i = 20 + } + } + end +end + +assert('BS Block 12') do + def m + yield 1 + end + + assert_equal(2) do + m{|ib| + m{|jb| + ib = 20 + kb = 2 + } + } + end +end + +assert('BS Block 13') do + def iter1 + iter2{ + yield + } + end + + def iter2 + yield + end + + assert_equal(3) do + iter1{ + jb = 2 + iter1{ + jb = 3 + } + jb + } + end +end + +assert('BS Block 14') do + def iter1 + iter2{ + yield + } + end + + def iter2 + yield + end + + assert_equal(2) do + iter1{ + jb = 2 + iter1{ + jb + } + jb + } + end +end + +assert('BS Block 15') do + def m + yield 1 + end + assert_equal(2) do + m{|ib| + ib*2 + } + end +end + +assert('BS Block 16') do + def m + yield 12345, 67890 + end + assert_equal(92580) do + m{|ib,jb| + ib*2+jb + } + end +end + +assert('BS Block 17') do + def iter + yield 10 + end + + a = nil + assert_equal [10, nil] do + [iter{|a| + a + }, a] + end +end + +assert('BS Block 18') do + def iter + yield 10 + end + + assert_equal(21) do + iter{|a| + iter{|a| + a + 1 + } + a + } + end +end + +assert('BS Block 19') do + def iter + yield 10, 20, 30, 40 + end + + a = b = c = d = nil + assert_equal([10, 20, 30, 40, nil, nil, nil, nil]) do + iter{|a, b, c, d| + [a, b, c, d] + } + [a, b, c, d] + end +end + +assert('BS Block 20') do + def iter + yield 10, 20, 30, 40 + end + + a = b = nil + assert_equal([10, 20, 30, 40, nil, nil]) do + iter{|a, b, c, d| + [a, b, c, d] + } + [a, b] + end +end + +assert('BS Block 21') do + def iter + yield 1, 2 + end + + assert_equal([1, [2]]) do + iter{|a, *b| + [a, b] + } + end +end + +assert('BS Block 22') do + def iter + yield 1, 2 + end + + assert_equal([[1, 2]]) do + iter{|*a| + [a] + } + end +end + +assert('BS Block 23') do + def iter + yield 1, 2 + end + + assert_equal([1, 2, []]) do + iter{|a, b, *c| + [a, b, c] + } + end +end + +assert('BS Block 24') do + def m + yield + end + assert_equal(1) do + m{ + 1 + } + end +end + +assert('BS Block 25') do + def m + yield 123 + end + assert_equal(15129) do + m{|ib| + m{|jb| + ib*jb + } + } + end +end + +assert('BS Block 26') do + def m a + yield a + end + assert_equal(2) do + m(1){|ib| + m(2){|jb| + ib*jb + } + } + end +end + +assert('BS Block 27') do + sum = 0 + 3.times{|ib| + 2.times{|jb| + sum += ib + jb + }} + assert_equal sum, 9 +end + +assert('BS Block 28') do + assert_equal(10) do + 3.times{|bl| + break 10 + } + end +end + +assert('BS Block 29') do + def iter + yield 1,2,3 + end + + assert_equal([1, 2]) do + iter{|i, j| + [i, j] + } + end +end + +assert('BS Block 30') do + def iter + yield 1 + end + + assert_equal([1, nil]) do + iter{|i, j| + [i, j] + } + end +end + +assert('BS Block [ruby-dev:31147]') do + def m + yield + end + assert_nil m{|&b| b} +end + +assert('BS Block [ruby-dev:31160]') do + def m() + yield + end + assert_nil m {|(v,(*))|} +end + +assert('BS Block [issue #750]') do + def m(a, *b) + yield + end + args = [1, 2, 3] + assert_equal m(*args){ 1 }, 1 +end + +assert('BS Block 31') do + def m() + yield + end + assert_nil m {|((*))|} +end + +assert('BS Block [ruby-dev:31440]') do + def m + yield [0] + end + assert_equal m{|v, &b| v}, [0] +end + +assert('BS Block 32') do + r = false; 1.times{|&b| r = b} + assert_equal NilClass, r.class +end + +assert('BS Block [ruby-core:14395]') do + class Controller + def respond_to(&block) + responder = Responder.new + block.call(responder) + responder.respond + end + def test_for_bug + respond_to{|format| + format.js{ + "in test" + render{|obj| + obj + } + } + } + end + def render(&block) + "in render" + end + end + + class Responder + def method_missing(symbol, &block) + "enter method_missing" + @response = Proc.new{ + 'in method missing' + block.call + } + "leave method_missing" + end + def respond + @response.call + end + end + t = Controller.new + assert_true t.test_for_bug +end + +assert("BS Block 33") do + module TestReturnFromNestedBlock + def self.test + 1.times do + 1.times do + return :ok + end + end + :bad + end + end + assert_equal :ok, TestReturnFromNestedBlock.test +end + +assert("BS Block 34") do + module TestReturnFromNestedBlock_BSBlock34 + def self.test + 1.times do + while true + return :ok + end + end + :bad + end + end + assert_equal :ok, TestReturnFromNestedBlock_BSBlock34.test +end + +assert("BS Block 35") do + module TestReturnFromNestedBlock_BSBlock35 + def self.test + 1.times do + until false + return :ok + end + end + :bad + end + end + assert_equal :ok, TestReturnFromNestedBlock_BSBlock35.test +end + +assert('BS Block 36') do + def iter + yield 1, 2, 3, 4, 5 + end + + assert_equal([1, 2, [3, 4], 5]) do + iter{|a, b, *c, d| + [a, b, c, d] + } + end +end + +assert('BS Block 37') do + def iter + yield 1, 2, 3 + end + + assert_equal([1, 2, [], 3]) do + iter{|a, b, *c, d| + [a, b, c, d] + } + end +end + +assert('BS Block 38') do + def iter + yield 1,2,3,4,5,6 + end + + assert_equal [1,2,3,4,5], iter{|a,b,c=:c,d,e| [a,b,c,d,e]} +end diff --git a/web/server/h2o/libh2o/deps/mruby/test/t/bs_literal.rb b/web/server/h2o/libh2o/deps/mruby/test/t/bs_literal.rb new file mode 100644 index 00000000..c6c38140 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/test/t/bs_literal.rb @@ -0,0 +1,38 @@ +## +# Bootstrap test for literals + +assert('BS Literal 1') do + assert_true true +end + +assert('BS Literal 2') do + assert_equal TrueClass, true.class +end + +assert('BS Literal 3') do + assert_false false +end + +assert('BS Literal 4') do + assert_equal FalseClass, false.class +end + +assert('BS Literal 5') do + assert_equal 'nil', nil.inspect +end + +assert('BS Literal 6') do + assert_equal NilClass, nil.class +end + +assert('BS Literal 7') do + assert_equal Symbol, :sym.class +end + +assert('BS Literal 8') do + assert_equal 1234, 1234 +end + +assert('BS Literal 9') do + assert_equal Fixnum, 1234.class +end diff --git a/web/server/h2o/libh2o/deps/mruby/test/t/class.rb b/web/server/h2o/libh2o/deps/mruby/test/t/class.rb new file mode 100644 index 00000000..eb077fce --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/test/t/class.rb @@ -0,0 +1,451 @@ +## +# Class ISO Test + +assert('Class', '15.2.3') do + assert_equal(Class, Class.class) +end + +assert('Class#initialize', '15.2.3.3.1') do + c = Class.new do + def test + :test + end + end.new + + assert_equal(c.test, :test) +end + +assert('Class#initialize_copy', '15.2.3.3.2') do + class TestClass + attr_accessor :n + def initialize(n) + @n = n + end + def initialize_copy(obj) + @n = n + end + end + + c1 = TestClass.new('Foo') + c2 = c1.dup + c3 = TestClass.new('Bar') + + assert_equal(c1.n, c2.n) + assert_not_equal(c1.n, c3.n) +end + +assert('Class#new', '15.2.3.3.3') do + assert_raise(TypeError, 'Singleton should raise TypeError') do + "a".singleton_class.new + end + + class TestClass + def initialize args, &block + @result = if not args.nil? and block.nil? + # only arguments + :only_args + elsif not args.nil? and not block.nil? + # args and block is given + :args_and_block + else + # this should never happen + :broken + end + end + + def result; @result; end + end + + assert_equal(:only_args, TestClass.new(:arg).result) + # with block doesn't work yet +end + +assert('Class#superclass', '15.2.3.3.4') do + class SubClass < String; end + assert_equal(String, SubClass.superclass) +end + +# Not ISO specified + +assert('Class 1') do + class C1; end + assert_equal(Class, C1.class) +end + +assert('Class 2') do + class C2; end + assert_equal(C2, C2.new.class) +end + +assert('Class 3') do + class C3; end + assert_equal(Class, C3.new.class.class) +end + +assert('Class 4') do + class C4_A; end + class C4 < C4_A; end + assert_equal(Class, C4.class) +end + +assert('Class 5') do + class C5_A; end + class C5 < C5_A; end + assert_equal(C5, C5.new.class) +end + +assert('Class 6') do + class C6_A; end + class C6 < C6_A; end + assert_equal(Class, C6.new.class.class) +end + +assert('Class 7') do + class C7_A; end + class C7_B; end + + class C7 < C7_A; end + + assert_raise(TypeError) do + # Different superclass. + class C7 < C7_B; end + end +end + +assert('Class 8') do + class C8_A; end + + class C8; end # superclass is Object + + assert_raise(TypeError) do + # Different superclass. + class C8 < C8_A; end + end +end + +assert('Class 9') do + Class9Const = "a" + + assert_raise(TypeError) do + class Class9Const; end + end +end + +assert('Class Module 1') do + module M; end + assert_equal(Module, M.class) +end + +assert('Class Module 2') do + module M; end + class C; include M; end + assert_equal(C, C.new.class) +end + +# nested class +assert('Class Nested 1') do + class A; end + class A::B; end + assert_equal(A::B, A::B) +end + +assert('Class Nested 2') do + class A; end + class A::B; end + assert_equal(A::B, A::B.new.class) +end + +assert('Class Nested 3') do + class A; end + class A::B; end + assert_equal(Class, A::B.new.class.class) +end + +assert('Class Nested 4') do + class A; end + class A::B; end + class A::B::C; end + assert_equal(A::B::C, A::B::C) +end + +assert('Class Nested 5') do + class A; end + class A::B; end + class A::B::C; end + assert_equal(Class, A::B::C.class) +end + +assert('Class Nested 6') do + class A; end + class A::B; end + class A::B::C; end + assert_equal(A::B::C, A::B::C.new.class) +end + +assert('Class Nested 7') do + class A; end + class A::B; end + class A::B2 < A::B; end + assert_equal(A::B2, A::B2) +end + +assert('Class Nested 8') do + class A; end + class A::B; end + class A::B2 < A::B; end + assert_equal(Class, A::B2.class) +end + +assert('Class Colon 1') do + class A; end + A::C = 1 + assert_equal(1, A::C) +end + +assert('Class Colon 2') do + class A; class ::C; end end + assert_equal(C, C) +end + +assert('Class Colon 3') do + class A; class ::C; end end + assert_equal(Class, C.class) +end + +assert('Class Dup 1') do + class C; end + assert_equal(Class, C.dup.class) +end + +assert('Class Dup 2') do + module M; end + assert_equal(Module, M.dup.class) +end + +assert('Class.new') do + assert_equal(Class, Class.new.class) + a = [] + klass = Class.new do |c| + a << c + end + assert_equal([klass], a) +end + +assert('class to return the last value') do + m = class C; :m end + assert_equal(m, :m) +end + +assert('raise when superclass is not a class') do + module FirstModule; end + assert_raise(TypeError, 'should raise TypeError') do + class FirstClass < FirstModule; end + end + + class SecondClass; end + assert_raise(TypeError, 'should raise TypeError') do + class SecondClass < false; end + end + + class ThirdClass; end + assert_raise(TypeError, 'should raise TypeError') do + class ThirdClass < ThirdClass; end + end +end + +assert('Class#inherited') do + class Foo + @@subclass_name = nil + def self.inherited(subclass) + @@subclass_name = subclass + end + def self.subclass_name + @@subclass_name + end + end + + assert_equal(nil, Foo.subclass_name) + + class Bar < Foo + end + + assert_equal(Bar, Foo.subclass_name) + + class Baz < Bar + end + + assert_equal(Baz, Foo.subclass_name) +end + +assert('singleton tests') do + module FooMod + def run_foo_mod + 100 + end + end + + bar = String.new + + baz = class << bar + extend FooMod + def self.run_baz + 200 + end + end + + assert_false baz.singleton_methods.include? :run_foo_mod + assert_false baz.singleton_methods.include? :run_baz + + assert_raise(NoMethodError, 'should raise NoMethodError') do + baz.run_foo_mod + end + assert_raise(NoMethodError, 'should raise NoMethodError') do + baz.run_baz + end + + assert_raise(NoMethodError, 'should raise NoMethodError') do + bar.run_foo_mod + end + assert_raise(NoMethodError, 'should raise NoMethodError') do + bar.run_baz + end + + baz = class << bar + extend FooMod + def self.run_baz + 300 + end + self + end + + assert_true baz.singleton_methods.include? :run_baz + assert_true baz.singleton_methods.include? :run_foo_mod + assert_equal 100, baz.run_foo_mod + assert_equal 300, baz.run_baz + + assert_raise(NoMethodError, 'should raise NoMethodError') do + bar.run_foo_mod + end + assert_raise(NoMethodError, 'should raise NoMethodError') do + bar.run_baz + end + + fv = false + class << fv + def self.run_false + 5 + end + end + + nv = nil + class << nv + def self.run_nil + 6 + end + end + + tv = true + class << tv + def self.run_nil + 7 + end + end + + assert_raise(TypeError, 'should raise TypeError') do + num = 1.0 + class << num + def self.run_nil + 7 + end + end + end +end + +assert('clone Class') do + class Foo + def func + true + end + end + + Foo.clone.new.func +end + +assert('class variable and class << self style class method') do + class ClassVariableTest + @@class_variable = "value" + class << self + def class_variable + @@class_variable + end + end + end + + assert_equal("value", ClassVariableTest.class_variable) +end + +assert('class variable definition in singleton_class') do + class ClassVariableDefinitionInSingletonTest + class << self + @@class_variable = "value" + end + def class_variable + @@class_variable + end + end + + assert_equal("value", ClassVariableDefinitionInSingletonTest.new.class_variable) +end + +assert('class variable in module and class << self style class method') do + module ClassVariableInModuleTest + @@class_variable = "value" + class << self + def class_variable + @@class_variable + end + end + end + + assert_equal("value", ClassVariableInModuleTest.class_variable) +end + +assert('child class/module defined in singleton class get parent constant') do + actual = module GetParentConstantTest + EXPECT = "value" + class << self + class CHILD + class << self + EXPECT + end + end + end + end + assert_equal("value", actual) +end + +assert('overriding class variable with a module (#3235)') do + module ModuleWithCVar + @@class_variable = 1 + end + class CVarOverrideTest + @@class_variable = 2 + include ModuleWithCVar + + assert_equal(1, @@class_variable) + end +end + +assert('class with non-class/module outer raises TypeError') do + assert_raise(TypeError) { class 0::C1; end } + assert_raise(TypeError) { class []::C2; end } +end + +assert("remove_method doesn't segfault if the passed in argument isn't a symbol") do + klass = Class.new + assert_raise(TypeError) { klass.remove_method nil } + assert_raise(TypeError) { klass.remove_method 123 } + assert_raise(TypeError) { klass.remove_method 1.23 } + assert_raise(NameError) { klass.remove_method "hello" } + assert_raise(TypeError) { klass.remove_method Class.new } +end diff --git a/web/server/h2o/libh2o/deps/mruby/test/t/codegen.rb b/web/server/h2o/libh2o/deps/mruby/test/t/codegen.rb new file mode 100644 index 00000000..4c9e2c59 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/test/t/codegen.rb @@ -0,0 +1,197 @@ +## +# Codegen tests + +assert('peephole optimization does not eliminate move whose result is reused') do + assert_raise LocalJumpError do + def method + yield + end + method(&a &&= 0) + end +end + +assert('empty condition in ternary expression parses correctly') do + assert_equal(() ? 1 : 2, 2) +end + +assert('method call with exactly 127 arguments') do + def args_to_ary(*args) + args + end + + assert_equal [0]*127, args_to_ary( + 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,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,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,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,0, \ + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + ) +end + +assert('nested empty heredoc') do + _, a = nil, <0, 1=>1, 2=>2, 3=>3, 4=>4, 5=>5, 6=>6, 7=>7, 8=>8, 9=>9, + 10=>10, 11=>11, 12=>12, 13=>13, 14=>14, 15=>15, 16=>16, 17=>17, 18=>18, 19=>19, + 20=>20, 21=>21, 22=>22, 23=>23, 24=>24, 25=>25, 26=>26, 27=>27, 28=>28, 29=>29, + 30=>30, 31=>31, 32=>32, 33=>33, 34=>34, 35=>35, 36=>36, 37=>37, 38=>38, 39=>39, + 40=>40, 41=>41, 42=>42, 43=>43, 44=>44, 45=>45, 46=>46, 47=>47, 48=>48, 49=>49, + 50=>50, 51=>51, 52=>52, 53=>53, 54=>54, 55=>55, 56=>56, 57=>57, 58=>58, 59=>59, + 60=>60, 61=>61, 62=>62, 63=>63, 64=>64, 65=>65, 66=>66, 67=>67, 68=>68, 69=>69, + 70=>70, 71=>71, 72=>72, 73=>73, 74=>74, 75=>75, 76=>76, 77=>77, 78=>78, 79=>79, + 80=>80, 81=>81, 82=>82, 83=>83, 84=>84, 85=>85, 86=>86, 87=>87, 88=>88, 89=>89, + 90=>90, 91=>91, 92=>92, 93=>93, 94=>94, 95=>95, 96=>96, 97=>97, 98=>98, 99=>99, + 100=>100, 101=>101, 102=>102, 103=>103, 104=>104, 105=>105, 106=>106, 107=>107, 108=>108, 109=>109, + 110=>110, 111=>111, 112=>112, 113=>113, 114=>114, 115=>115, 116=>116, 117=>117, 118=>118, 119=>119, + 120=>120, 121=>121, 122=>122, 123=>123, 124=>124, 125=>125, 126=>126) + end + + # NODE_OP_ASGN + o = Object.new + class << o + attr_accessor :a + end + + o.a = 1 + assert_nothing_raised{ o.a += 1 } + o.a = 1 + assert_nothing_raised{ o.a <<= 1 } + o.a = 1 + assert_nothing_raised{ o.a &&= 1 } + + o = { k: 1 } + assert_nothing_raised{ o[:k] += 1 } + o = { k: 1 } + assert_nothing_raised{ o[:k] <<= 1 } + o = { k: 1 } + assert_nothing_raised{ o[:k] &&= 1 } + + o = { k: 1 } + assert_nothing_raised{ o[*[:k]] += 1 } + o = { k: 1 } + assert_nothing_raised{ o[*[:k]] <<= 1 } + o = { k: 1 } + assert_nothing_raised{ o[*[:k]] &&= 1 } + + # NODE_YIELD + def check_node_yield + yield + end + assert_nothing_raised do + check_node_yield{} + end + + # NODE_DXSTR + assert_raise(NotImplementedError){ `#{:dynamic}` } + + # NODE_XSTR + assert_raise(NotImplementedError){ `static` } + + # NODE_DREGX + class Regexp; end + assert_raise(NoMethodError){ /#{'dynamic'}tail/ } + assert_raise(NoMethodError){ /#{'dynamic'}tail/iu } + + # NODE_REGX + assert_raise(NoMethodError){ /static/ } + assert_raise(NoMethodError){ /static/iu } + Object.remove_const :Regexp + + # NODE_UNDEF + assert_nothing_raised do + class << Object.new + undef send + end + end + + # NODE_ALIAS + assert_nothing_raised do + class << Object.new + alias send2 send + end + end +end \ No newline at end of file diff --git a/web/server/h2o/libh2o/deps/mruby/test/t/comparable.rb b/web/server/h2o/libh2o/deps/mruby/test/t/comparable.rb new file mode 100644 index 00000000..2ee28de7 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/test/t/comparable.rb @@ -0,0 +1,80 @@ + +assert('Comparable#<', '15.3.3.2.1') do + class Foo + include Comparable + def <=>(x) + x + end + end + assert_false(Foo.new < 0) + assert_false(Foo.new < 1) + assert_true(Foo.new < -1) + assert_raise(ArgumentError){ Foo.new < nil } +end + +assert('Comparable#<=', '15.3.3.2.2') do + class Foo + include Comparable + def <=>(x) + x + end + end + assert_true(Foo.new <= 0) + assert_false(Foo.new <= 1) + assert_true(Foo.new <= -1) + assert_raise(ArgumentError){ Foo.new <= nil } +end + +assert('Comparable#==', '15.3.3.2.3') do + class Foo + include Comparable + def <=>(x) + 0 + end + end + + assert_true(Foo.new == Foo.new) +end + +assert('Comparable#>', '15.3.3.2.4') do + class Foo + include Comparable + def <=>(x) + x + end + end + assert_false(Foo.new > 0) + assert_true(Foo.new > 1) + assert_false(Foo.new > -1) + assert_raise(ArgumentError){ Foo.new > nil } +end + +assert('Comparable#>=', '15.3.3.2.5') do + class Foo + include Comparable + def <=>(x) + x + end + end + assert_true(Foo.new >= 0) + assert_true(Foo.new >= 1) + assert_false(Foo.new >= -1) + assert_raise(ArgumentError){ Foo.new >= nil } +end + +assert('Comparable#between?', '15.3.3.2.6') do + class Foo + include Comparable + def <=>(x) + x + end + end + + c = Foo.new + + assert_false(c.between?(-1, 1)) + assert_false(c.between?(-1, -1)) + assert_false(c.between?( 1, 1)) + assert_true(c.between?( 1, -1)) + assert_true(c.between?(0, 0)) +end diff --git a/web/server/h2o/libh2o/deps/mruby/test/t/ensure.rb b/web/server/h2o/libh2o/deps/mruby/test/t/ensure.rb new file mode 100644 index 00000000..bef39705 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/test/t/ensure.rb @@ -0,0 +1,54 @@ +## +# ensure Test + +assert('ensure - context - yield') do + class EnsureYieldBreak + attr_reader :ensure_context + def try + yield + ensure + @ensure_context = self + end + end + + yielder = EnsureYieldBreak.new + yielder.try do + end + assert_equal yielder, yielder.ensure_context +end + +assert('ensure - context - yield and break') do + class EnsureYieldBreak + attr_reader :ensure_context + def try + yield + ensure + @ensure_context = self + end + end + + yielder = EnsureYieldBreak.new + yielder.try do + break + end + assert_equal yielder, yielder.ensure_context +end + +assert('ensure - context - yield and return') do + class EnsureYieldBreak + attr_reader :ensure_context + def try + yield + ensure + @ensure_context = self + end + end + + yielder = EnsureYieldBreak.new + lambda do + yielder.try do + return + end + end.call + assert_equal yielder, yielder.ensure_context +end diff --git a/web/server/h2o/libh2o/deps/mruby/test/t/enumerable.rb b/web/server/h2o/libh2o/deps/mruby/test/t/enumerable.rb new file mode 100644 index 00000000..359c3451 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/test/t/enumerable.rb @@ -0,0 +1,134 @@ +## +# Enumerable ISO Test + +assert('Enumerable', '15.3.2') do + assert_equal(Module, Enumerable.class) +end + +assert('Enumerable#all?', '15.3.2.2.1') do + assert_true([1,2,3].all?) + assert_false([1,false,3].all?) + + a = [2,4,6] + all = a.all? do |e| + e % 2 == 0 + end + assert_true(all) + + a = [2,4,7] + all = a.all? do |e| + e % 2 == 0 + end + assert_false(all) +end + +assert('Enumerable#any?', '15.3.2.2.2') do + assert_true([false,true,false].any?) + assert_false([false,false,false].any?) + + a = [1,3,6] + any = a.any? do |e| + e % 2 == 0 + end + assert_true(any) + + a = [1,3,5] + any = a.any? do |e| + e % 2 == 0 + end + assert_false(any) +end + +assert('Enumerable#collect', '15.3.2.2.3') do + assert_true [1,2,3].collect { |i| i + i } == [2,4,6] +end + +assert('Enumerable#detect', '15.3.2.2.4') do + assert_equal 1, [1,2,3].detect() { true } + assert_equal 'a', [1,2,3].detect("a") { false } +end + +assert('Array#each_with_index', '15.3.2.2.5') do + a = nil + b = nil + + [1].each_with_index {|e,i| a = e; b = i} + + assert_equal(1, a) + assert_equal(0, b) +end + +assert('Enumerable#entries', '15.3.2.2.6') do + assert_equal([1], [1].entries) +end + +assert('Enumerable#find', '15.3.2.2.7') do + assert_equal 1, [1,2,3].find() { true } + assert_equal 'a', [1,2,3].find("a") { false } +end + +assert('Enumerable#find_all', '15.3.2.2.8') do + assert_true [1,2,3,4,5,6,7,8,9].find_all() {|i| i%2 == 0}, [2,4,6,8] +end + +assert('Enumerable#grep', '15.3.2.2.9') do + assert_equal [4,5,6], [1,2,3,4,5,6,7,8,9].grep(4..6) +end + +assert('Enumerable#include?', '15.3.2.2.10') do + assert_true [1,2,3,4,5,6,7,8,9].include?(5) + assert_false [1,2,3,4,5,6,7,8,9].include?(0) +end + +assert('Enumerable#inject', '15.3.2.2.11') do + assert_equal 21, [1,2,3,4,5,6].inject() {|s, n| s + n} + assert_equal 22, [1,2,3,4,5,6].inject(1) {|s, n| s + n} +end + +assert('Enumerable#map', '15.3.2.2.12') do + assert_equal [2,4,6], [1,2,3].map { |i| i + i } +end + +assert('Enumerable#max', '15.3.2.2.13') do + a = ['aaa', 'bb', 'c'] + assert_equal 'c', a.max + assert_equal 'aaa', a.max {|i1,i2| i1.length <=> i2.length} +end + +assert('Enumerable#min', '15.3.2.2.14') do + a = ['aaa', 'bb', 'c'] + assert_equal 'aaa', a.min + assert_equal 'c', a.min {|i1,i2| i1.length <=> i2.length} +end + +assert('Enumerable#member?', '15.3.2.2.15') do + assert_true [1,2,3,4,5,6,7,8,9].member?(5) + assert_false [1,2,3,4,5,6,7,8,9].member?(0) +end + +assert('Enumerable#partition', '15.3.2.2.16') do + partition = [0,1,2,3,4,5,6,7,8,9].partition do |i| + i % 2 == 0 + end + assert_equal [[0,2,4,6,8], [1,3,5,7,9]], partition +end + +assert('Enumerable#reject', '15.3.2.2.17') do + reject = [0,1,2,3,4,5,6,7,8,9].reject do |i| + i % 2 == 0 + end + assert_equal [1,3,5,7,9], reject +end + +assert('Enumerable#select', '15.3.2.2.18') do + assert_equal [2,4,6,8], [1,2,3,4,5,6,7,8,9].select() {|i| i%2 == 0} +end + +assert('Enumerable#sort', '15.3.2.2.19') do + assert_equal [1,2,3,4,6,7], [7,3,1,2,6,4].sort + assert_equal [7,6,4,3,2,1], [7,3,1,2,6,4].sort {|e1,e2|e2<=>e1} +end + +assert('Enumerable#to_a', '15.3.2.2.20') do + assert_equal [1], [1].to_a +end diff --git a/web/server/h2o/libh2o/deps/mruby/test/t/exception.rb b/web/server/h2o/libh2o/deps/mruby/test/t/exception.rb new file mode 100644 index 00000000..ce7b5841 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/test/t/exception.rb @@ -0,0 +1,422 @@ +## +# Exception ISO Test + +assert('Exception', '15.2.22') do + assert_equal Class, Exception.class +end + +assert('Exception.exception', '15.2.22.4.1') do + e = Exception.exception('a') + + assert_equal Exception, e.class +end + +assert('Exception#exception', '15.2.22.5.1') do + e = Exception.new + re = RuntimeError.new + assert_equal e, e.exception + assert_equal e, e.exception(e) + assert_equal re, re.exception(re) + changed_re = re.exception('message has changed') + assert_not_equal re, changed_re + assert_equal 'message has changed', changed_re.message +end + +assert('Exception#message', '15.2.22.5.2') do + e = Exception.exception('a') + + assert_equal 'a', e.message +end + +assert('Exception#to_s', '15.2.22.5.3') do + e = Exception.exception('a') + + assert_equal 'a', e.to_s +end + +assert('Exception.exception', '15.2.22.4.1') do + e = Exception.exception() + e.initialize('a') + + assert_equal 'a', e.message +end + +assert('NameError', '15.2.31') do + assert_raise(NameError) do + raise NameError.new + end + + e = NameError.new "msg", "name" + assert_equal "msg", e.message + assert_equal "name", e.name +end + +assert('ScriptError', '15.2.37') do + assert_raise(ScriptError) do + raise ScriptError.new + end +end + +assert('SyntaxError', '15.2.38') do + assert_raise(SyntaxError) do + raise SyntaxError.new + end +end + +# Not ISO specified + +assert('Exception 1') do +r=begin + 1+1 + ensure + 2+2 + end + assert_equal 2, r +end + +assert('Exception 2') do +r=begin + 1+1 + begin + 2+2 + ensure + 3+3 + end + ensure + 4+4 + end + assert_equal 4, r +end + +assert('Exception 3') do +r=begin + 1+1 + begin + 2+2 + ensure + 3+3 + end + ensure + 4+4 + begin + 5+5 + ensure + 6+6 + end + end + assert_equal 4, r +end + +assert('Exception 4') do + a = nil + 1.times{|e| + begin + rescue => err + end + a = err.class + } + assert_equal NilClass, a +end + +assert('Exception 5') do + $ans = [] + def m + $! + end + def m2 + 1.times{ + begin + return + ensure + $ans << m + end + } + end + m2 + assert_equal [nil], $ans +end + +assert('Exception 6') do + $i = 0 + def m + iter{ + begin + $i += 1 + begin + $i += 2 + break + ensure + + end + ensure + $i += 4 + end + $i = 0 + } + end + + def iter + yield + end + m + assert_equal 7, $i +end + +assert('Exception 7') do + $i = 0 + def m + begin + $i += 1 + begin + $i += 2 + return + ensure + $i += 3 + end + ensure + $i += 4 + end + p :end + end + m + assert_equal 10, $i +end + +assert('Exception 8') do +r=begin + 1 + rescue + 2 + else + 3 + end + assert_equal 3, r +end + +assert('Exception 9') do +r=begin + 1+1 + rescue + 2+2 + else + 3+3 + ensure + 4+4 + end + assert_equal 6, r +end + +assert('Exception 10') do +r=begin + 1+1 + begin + 2+2 + rescue + 3+3 + else + 4+4 + end + rescue + 5+5 + else + 6+6 + ensure + 7+7 + end + assert_equal 12, r +end + +assert('Exception 11') do + a = :ok + begin + begin + raise Exception + rescue + a = :ng + end + rescue Exception + end + assert_equal :ok, a +end + +assert('Exception 12') do + a = :ok + begin + raise Exception rescue a = :ng + rescue Exception + end + assert_equal :ok, a +end + +assert('Exception 13') do + a = :ng + begin + raise StandardError + rescue TypeError, ArgumentError + a = :ng + rescue + a = :ok + else + a = :ng + end + assert_equal :ok, a +end + +assert('Exception 14') do + def exception_test14; UnknownConstant; end + a = :ng + begin + send(:exception_test14) + rescue + a = :ok + end + + assert_equal :ok, a +end + +assert('Exception 15') do + a = begin + :ok + rescue + :ko + end + assert_equal :ok, a +end + +assert('Exception 16') do + begin + raise "foo" + false + rescue => e + assert_equal "foo", e.message + end +end + +assert('Exception 17') do +r=begin + raise "a" # RuntimeError + rescue ArgumentError + 1 + rescue StandardError + 2 + else + 3 + ensure + 4 + end + assert_equal 2, r +end + +assert('Exception 18') do +r=begin + 0 + rescue ArgumentError + 1 + rescue StandardError + 2 + else + 3 + ensure + 4 + end + assert_equal 3, r +end + +assert('Exception 19') do + class Class4Exception19 + def a + r = @e = false + begin + b + rescue TypeError + r = self.z + end + [ r, @e ] + end + + def b + begin + 1 * "b" + ensure + @e = self.zz + end + end + + def zz + true + end + def z + true + end + end + assert_equal [true, true], Class4Exception19.new.a +end + +assert('Exception#inspect without message') do + assert_equal "Exception", Exception.new.inspect +end + +assert('Exception#backtrace') do + assert_nothing_raised do + begin + raise "get backtrace" + rescue => e + e.backtrace + end + end +end + +assert('Raise in ensure') do + assert_raise(ArgumentError) do + begin + raise "" # RuntimeError + ensure + raise ArgumentError + end + end +end + +def backtrace_available? + begin + raise "XXX" + rescue => exception + not exception.backtrace.empty? + end +end + +assert('GC in rescue') do + skip "backtrace isn't available" unless backtrace_available? + + line = nil + begin + [1].each do + [2].each do + [3].each do + line = __LINE__; raise "XXX" + end + end + end + rescue => exception + GC.start + assert_equal("#{__FILE__}:#{line}:in call", + exception.backtrace.first) + end +end + +assert('Method call in rescue') do + skip "backtrace isn't available" unless backtrace_available? + + line = nil + begin + [1].each do + [2].each do + line = __LINE__; raise "XXX" + end + end + rescue => exception + [3].each do + end + assert_equal("#{__FILE__}:#{line}:in call", + exception.backtrace.first) + end +end diff --git a/web/server/h2o/libh2o/deps/mruby/test/t/false.rb b/web/server/h2o/libh2o/deps/mruby/test/t/false.rb new file mode 100644 index 00000000..3582f697 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/test/t/false.rb @@ -0,0 +1,31 @@ +## +# FalseClass ISO Test + +assert('FalseClass', '15.2.6') do + assert_equal Class, FalseClass.class +end + +assert('FalseClass false', '15.2.6.1') do + assert_false false + assert_equal FalseClass, false.class + assert_false FalseClass.method_defined? :new +end + +assert('FalseClass#&', '15.2.6.3.1') do + assert_false false.&(true) + assert_false false.&(false) +end + +assert('FalseClass#^', '15.2.6.3.2') do + assert_true false.^(true) + assert_false false.^(false) +end + +assert('FalseClass#to_s', '15.2.6.3.3') do + assert_equal 'false', false.to_s +end + +assert('FalseClass#|', '15.2.6.3.4') do + assert_true false.|(true) + assert_false false.|(false) +end diff --git a/web/server/h2o/libh2o/deps/mruby/test/t/float.rb b/web/server/h2o/libh2o/deps/mruby/test/t/float.rb new file mode 100644 index 00000000..7e8c9898 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/test/t/float.rb @@ -0,0 +1,205 @@ +## +# Float ISO Test + +assert('Float', '15.2.9') do + assert_equal Class, Float.class +end + +assert('Float#+', '15.2.9.3.1') do + a = 3.123456788 + 0.000000001 + b = 3.123456789 + 1 + + assert_float(3.123456789, a) + assert_float(4.123456789, b) + + assert_raise(TypeError){ 0.0+nil } + assert_raise(TypeError){ 1.0+nil } +end + +assert('Float#-', '15.2.9.3.2') do + a = 3.123456790 - 0.000000001 + b = 5.123456789 - 1 + + assert_float(3.123456789, a) + assert_float(4.123456789, b) +end + +assert('Float#*', '15.2.9.3.3') do + a = 3.125 * 3.125 + b = 3.125 * 1 + + assert_float(9.765625, a) + assert_float(3.125 , b) +end + +assert('Float#/', '15.2.9.3.4') do + a = 3.123456789 / 3.123456789 + b = 3.123456789 / 1 + + assert_float(1.0 , a) + assert_float(3.123456789, b) +end + +assert('Float#%', '15.2.9.3.5') do + a = 3.125 % 3.125 + b = 3.125 % 1 + + assert_float(0.0 , a) + assert_float(0.125, b) +end + +assert('Float#<=>', '15.2.9.3.6') do + a = 3.125 <=> 3.123 + b = 3.125 <=> 3.125 + c = 3.125 <=> 3.126 + a2 = 3.125 <=> 3 + c2 = 3.125 <=> 4 + + assert_equal( 1, a) + assert_equal( 0, b) + assert_equal(-1, c) + assert_equal( 1, a2) + assert_equal(-1, c2) +end + +assert('Float#==', '15.2.9.3.7') do + assert_true 3.1 == 3.1 + assert_false 3.1 == 3.2 +end + +assert('Float#ceil', '15.2.9.3.8') do + a = 3.123456789.ceil + b = 3.0.ceil + c = -3.123456789.ceil + d = -3.0.ceil + + assert_equal( 4, a) + assert_equal( 3, b) + assert_equal(-3, c) + assert_equal(-3, d) +end + +assert('Float#finite?', '15.2.9.3.9') do + assert_true 3.123456789.finite? + assert_false (1.0 / 0.0).finite? +end + +assert('Float#floor', '15.2.9.3.10') do + a = 3.123456789.floor + b = 3.0.floor + c = -3.123456789.floor + d = -3.0.floor + + assert_equal( 3, a) + assert_equal( 3, b) + assert_equal(-4, c) + assert_equal(-3, d) +end + +assert('Float#infinite?', '15.2.9.3.11') do + a = 3.123456789.infinite? + b = (1.0 / 0.0).infinite? + c = (-1.0 / 0.0).infinite? + + assert_nil a + assert_equal( 1, b) + assert_equal(-1, c) +end + +assert('Float#round', '15.2.9.3.12') do + a = 3.123456789.round + b = 3.5.round + c = 3.4999.round + d = (-3.123456789).round + e = (-3.5).round + f = 12345.67.round(-1) + g = 3.423456789.round(0) + h = 3.423456789.round(1) + i = 3.423456789.round(3) + + assert_equal( 3, a) + assert_equal( 4, b) + assert_equal( 3, c) + assert_equal( -3, d) + assert_equal( -4, e) + assert_equal(12350, f) + assert_equal( 3, g) + assert_float( 3.4, h) + assert_float(3.423, i) + + assert_equal(42.0, 42.0.round(307)) + assert_equal(1.0e307, 1.0e307.round(2)) + + inf = 1.0/0.0 + assert_raise(FloatDomainError){ inf.round } + assert_raise(FloatDomainError){ inf.round(-1) } + assert_equal(inf, inf.round(1)) + nan = 0.0/0.0 + assert_raise(FloatDomainError){ nan.round } + assert_raise(FloatDomainError){ nan.round(-1) } + assert_true(nan.round(1).nan?) +end + +assert('Float#to_f', '15.2.9.3.13') do + a = 3.123456789 + + assert_float(a, a.to_f) +end + +assert('Float#to_i', '15.2.9.3.14') do + assert_equal(3, 3.123456789.to_i) + assert_raise(FloatDomainError) { Float::INFINITY.to_i } + assert_raise(FloatDomainError) { (-Float::INFINITY).to_i } + assert_raise(FloatDomainError) { Float::NAN.to_i } +end + +assert('Float#truncate', '15.2.9.3.15') do + assert_equal( 3, 3.123456789.truncate) + assert_equal(-3, -3.1.truncate) +end + +assert('Float#divmod') do + def check_floats exp, act + assert_float exp[0], act[0] + assert_float exp[1], act[1] + end + + # Note: quotients are Float because mruby does not have Bignum. + check_floats [ 0, 0.0], 0.0.divmod(1) + check_floats [ 0, 1.1], 1.1.divmod(3) + check_floats [ 3, 0.2], 3.2.divmod(1) + check_floats [ 2, 6.3], 20.3.divmod(7) + check_floats [-1, 1.6], -3.4.divmod(5) + check_floats [-2, -0.5], 25.5.divmod(-13) + check_floats [ 1, -6.6], -13.6.divmod(-7) + check_floats [ 3, 0.2], 9.8.divmod(3.2) +end + +assert('Float#nan?') do + assert_true (0.0/0.0).nan? + assert_false 0.0.nan? + assert_false (1.0/0.0).nan? + assert_false (-1.0/0.0).nan? +end + +assert('Float#<<') do + # Left Shift by one + assert_equal 46, 23.0 << 1 + + # Left Shift by a negative is Right Shift + assert_equal 23, 46.0 << -1 +end + +assert('Float#>>') do + # Right Shift by one + assert_equal 23, 46.0 >> 1 + + # Right Shift by a negative is Left Shift + assert_equal 46, 23.0 >> -1 + + # Don't raise on large Right Shift + assert_equal 0, 23.0 >> 128 + + # Don't raise on large Right Shift + assert_equal(-1, -23.0 >> 128) +end diff --git a/web/server/h2o/libh2o/deps/mruby/test/t/gc.rb b/web/server/h2o/libh2o/deps/mruby/test/t/gc.rb new file mode 100644 index 00000000..4b800e94 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/test/t/gc.rb @@ -0,0 +1,45 @@ +# Not ISO specified + +assert('GC.enable') do + assert_false GC.disable + assert_true GC.enable + assert_false GC.enable +end + +assert('GC.disable') do + begin + assert_false GC.disable + assert_true GC.disable + ensure + GC.enable + end +end + +assert('GC.interval_ratio=') do + origin = GC.interval_ratio + begin + assert_equal 150, (GC.interval_ratio = 150) + ensure + GC.interval_ratio = origin + end +end + +assert('GC.step_ratio=') do + origin = GC.step_ratio + begin + assert_equal 150, (GC.step_ratio = 150) + ensure + GC.step_ratio = origin + end +end + +assert('GC.generational_mode=') do + origin = GC.generational_mode + begin + assert_false (GC.generational_mode = false) + assert_true (GC.generational_mode = true) + assert_true (GC.generational_mode = true) + ensure + GC.generational_mode = origin + end +end diff --git a/web/server/h2o/libh2o/deps/mruby/test/t/hash.rb b/web/server/h2o/libh2o/deps/mruby/test/t/hash.rb new file mode 100644 index 00000000..c63b8c00 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/test/t/hash.rb @@ -0,0 +1,375 @@ +## +# Hash ISO Test + +assert('Hash', '15.2.13') do + assert_equal Class, Hash.class +end + +assert('Hash#==', '15.2.13.4.1') do + assert_true({ 'abc' => 'abc' } == { 'abc' => 'abc' }) + assert_false({ 'abc' => 'abc' } == { 'cba' => 'cba' }) + assert_true({ :equal => 1 } == { :equal => 1.0 }) + assert_false({ :a => 1 } == true) +end + +assert('Hash#[]', '15.2.13.4.2') do + a = { 'abc' => 'abc' } + + assert_equal 'abc', a['abc'] + + # Hash#[] should call #default (#3272) + hash = {} + def hash.default(k); self[k] = 1; end + hash[:foo] += 1 + + assert_equal 2, hash[:foo] +end + +assert('Hash#[]=', '15.2.13.4.3') do + a = Hash.new + a['abc'] = 'abc' + + assert_equal 'abc', a['abc'] +end + +assert('Hash#clear', '15.2.13.4.4') do + a = { 'abc' => 'abc' } + a.clear + + assert_equal({ }, a) +end + +assert('Hash#dup') do + a = { 'a' => 1 } + b = a.dup + a['a'] = 2 + assert_equal({'a' => 1}, b) + + c = Hash.new { |h, k| h[k] = k.upcase } + d = c.dup + assert_equal("FOO", d["foo"]) +end + +assert('Hash#default', '15.2.13.4.5') do + a = Hash.new + b = Hash.new('abc') + c = Hash.new {|s,k| s[k] = k} + + assert_nil a.default + assert_equal 'abc', b.default + assert_nil c.default + assert_equal 'abc', c.default('abc') +end + +assert('Hash#default=', '15.2.13.4.6') do + a = { 'abc' => 'abc' } + a.default = 'cba' + + assert_equal 'abc', a['abc'] + assert_equal 'cba', a['notexist'] +end + +assert('Hash#default_proc', '15.2.13.4.7') do + a = Hash.new + b = Hash.new {|s,k| s[k] = k + k} + c = b[2] + d = b['cat'] + + assert_nil a.default_proc + assert_equal Proc, b.default_proc.class + assert_equal 4, c + assert_equal 'catcat', d +end + +assert('Hash#delete', '15.2.13.4.8') do + a = { 'abc' => 'abc' } + b = { 'abc' => 'abc' } + b_tmp_1 = false + b_tmp_2 = false + + a.delete('abc') + b.delete('abc') do |k| + b_tmp_1 = true + end + b.delete('abc') do |k| + b_tmp_2 = true + end + + assert_nil a.delete('cba') + assert_false a.has_key?('abc') + assert_false b_tmp_1 + assert_true b_tmp_2 +end + +assert('Hash#each', '15.2.13.4.9') do + a = { 'abc_key' => 'abc_value' } + key = nil + value = nil + + a.each do |k,v| + key = k + value = v + end + + assert_equal 'abc_key', key + assert_equal 'abc_value', value +end + +assert('Hash#each_key', '15.2.13.4.10') do + a = { 'abc_key' => 'abc_value' } + key = nil + + a.each_key do |k| + key = k + end + + assert_equal 'abc_key', key +end + +assert('Hash#each_value', '15.2.13.4.11') do + a = { 'abc_key' => 'abc_value' } + value = nil + + a.each_value do |v| + value = v + end + + assert_equal 'abc_value', value +end + +assert('Hash#empty?', '15.2.13.4.12') do + a = { 'abc_key' => 'abc_value' } + b = Hash.new + + assert_false a.empty? + assert_true b.empty? +end + +assert('Hash#has_key?', '15.2.13.4.13') do + a = { 'abc_key' => 'abc_value' } + b = Hash.new + + assert_true a.has_key?('abc_key') + assert_false b.has_key?('cba') +end + +assert('Hash#has_value?', '15.2.13.4.14') do + a = { 'abc_key' => 'abc_value' } + b = Hash.new + + assert_true a.has_value?('abc_value') + assert_false b.has_value?('cba') +end + +assert('Hash#include?', '15.2.13.4.15') do + a = { 'abc_key' => 'abc_value' } + b = Hash.new + + assert_true a.include?('abc_key') + assert_false b.include?('cba') +end + +assert('Hash#initialize', '15.2.13.4.16') do + # Testing initialize by new. + h = Hash.new + h2 = Hash.new(:not_found) + + assert_true h.is_a? Hash + assert_equal({ }, h) + assert_nil h["hello"] + assert_equal :not_found, h2["hello"] +end + +assert('Hash#initialize_copy', '15.2.13.4.17') do + a = { 'abc_key' => 'abc_value' } + b = Hash.new.initialize_copy(a) + + assert_equal({ 'abc_key' => 'abc_value' }, b) +end + +assert('Hash#key?', '15.2.13.4.18') do + a = { 'abc_key' => 'abc_value' } + b = Hash.new + + assert_true a.key?('abc_key') + assert_false b.key?('cba') +end + +assert('Hash#keys', '15.2.13.4.19') do + a = { 'abc_key' => 'abc_value' } + + assert_equal ['abc_key'], a.keys +end + +assert('Hash#length', '15.2.13.4.20') do + a = { 'abc_key' => 'abc_value' } + b = Hash.new + + assert_equal 1, a.length + assert_equal 0, b.length +end + +assert('Hash#member?', '15.2.13.4.21') do + a = { 'abc_key' => 'abc_value' } + b = Hash.new + + assert_true a.member?('abc_key') + assert_false b.member?('cba') +end + +assert('Hash#merge', '15.2.13.4.22') do + a = { 'abc_key' => 'abc_value', 'cba_key' => 'cba_value' } + b = { 'cba_key' => 'XXX', 'xyz_key' => 'xyz_value' } + + result_1 = a.merge b + result_2 = a.merge(b) do |key, original, new| + original + end + + assert_equal({'abc_key' => 'abc_value', 'cba_key' => 'XXX', + 'xyz_key' => 'xyz_value' }, result_1) + assert_equal({'abc_key' => 'abc_value', 'cba_key' => 'cba_value', + 'xyz_key' => 'xyz_value' }, result_2) + + assert_raise(TypeError) do + { 'abc_key' => 'abc_value' }.merge "a" + end +end + +assert('Hash#replace', '15.2.13.4.23') do + a = { 'abc_key' => 'abc_value' } + b = Hash.new.replace(a) + + assert_equal({ 'abc_key' => 'abc_value' }, b) + + a = Hash.new(42) + b = {} + b.replace(a) + assert_equal(42, b[1]) + + a = Hash.new{|h,x| x} + b.replace(a) + assert_equal(127, b[127]) + + assert_raise(TypeError) do + { 'abc_key' => 'abc_value' }.replace "a" + end +end + +assert('Hash#shift', '15.2.13.4.24') do + a = { 'abc_key' => 'abc_value', 'cba_key' => 'cba_value' } + b = a.shift + + assert_equal Array, b.class + assert_equal 2, b.size + assert_equal 1, a.size + + b = a.shift + + assert_equal Array, b.class + assert_equal 2, b.size + assert_equal 0, a.size +end + +assert('Hash#size', '15.2.13.4.25') do + a = { 'abc_key' => 'abc_value' } + b = Hash.new + + assert_equal 1, a.size + assert_equal 0, b.size +end + +assert('Hash#store', '15.2.13.4.26') do + a = Hash.new + a.store('abc', 'abc') + + assert_equal 'abc', a['abc'] +end + +assert('Hash#value?', '15.2.13.4.27') do + a = { 'abc_key' => 'abc_value' } + b = Hash.new + + assert_true a.value?('abc_value') + assert_false b.value?('cba') +end + +assert('Hash#values', '15.2.13.4.28') do + a = { 'abc_key' => 'abc_value' } + + assert_equal ['abc_value'], a.values +end + +# Not ISO specified + +assert('Hash#eql?') do + a = { 'a' => 1, 'b' => 2, 'c' => 3 } + b = { 'a' => 1, 'b' => 2, 'c' => 3 } + c = { 'a' => 1.0, 'b' => 2, 'c' => 3 } + assert_true(a.eql?(b)) + assert_false(a.eql?(c)) + assert_false(a.eql?(true)) +end + +assert('Hash#reject') do + h = {:one => 1, :two => 2, :three => 3, :four => 4} + ret = h.reject do |k,v| + v % 2 == 0 + end + assert_equal({:one => 1, :three => 3}, ret) + assert_equal({:one => 1, :two => 2, :three => 3, :four => 4}, h) +end + +assert('Hash#reject!') do + h = {:one => 1, :two => 2, :three => 3, :four => 4} + ret = h.reject! do |k,v| + v % 2 == 0 + end + assert_equal({:one => 1, :three => 3}, ret) + assert_equal({:one => 1, :three => 3}, h) +end + +assert('Hash#select') do + h = {:one => 1, :two => 2, :three => 3, :four => 4} + ret = h.select do |k,v| + v % 2 == 0 + end + assert_equal({:two => 2, :four => 4}, ret) + assert_equal({:one => 1, :two => 2, :three => 3, :four => 4}, h) +end + +assert('Hash#select!') do + h = {:one => 1, :two => 2, :three => 3, :four => 4} + ret = h.select! do |k,v| + v % 2 == 0 + end + assert_equal({:two => 2, :four => 4}, ret) + assert_equal({:two => 2, :four => 4}, h) +end + +# Not ISO specified + +assert('Hash#inspect') do + h = { "c" => 300, "a" => 100, "d" => 400, "c" => 300 } + ret = h.to_s + + assert_include ret, '"c"=>300' + assert_include ret, '"a"=>100' + assert_include ret, '"d"=>400' +end + +assert('Hash#rehash') do + h = {[:a] => "b"} + # hash key modified + h.keys[0][0] = :b + # h[[:b]] => nil + h.rehash + assert_equal("b", h[[:b]]) +end + +assert('Hash#freeze') do + h = {}.freeze + assert_raise(RuntimeError) do + h[:a] = 'b' + end +end diff --git a/web/server/h2o/libh2o/deps/mruby/test/t/indexerror.rb b/web/server/h2o/libh2o/deps/mruby/test/t/indexerror.rb new file mode 100644 index 00000000..a8dce23a --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/test/t/indexerror.rb @@ -0,0 +1,6 @@ +## +# IndexError ISO Test + +assert('IndexError', '15.2.33') do + assert_equal Class, IndexError.class +end diff --git a/web/server/h2o/libh2o/deps/mruby/test/t/integer.rb b/web/server/h2o/libh2o/deps/mruby/test/t/integer.rb new file mode 100644 index 00000000..d4ef8b51 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/test/t/integer.rb @@ -0,0 +1,268 @@ +## +# Integer ISO Test + +assert('Integer', '15.2.8') do + assert_equal Class, Integer.class +end + +assert('Integer#+', '15.2.8.3.1') do + a = 1+1 + b = 1+1.0 + + assert_equal 2, a + assert_equal 2.0, b + + assert_raise(TypeError){ 0+nil } + assert_raise(TypeError){ 1+nil } + + c = Mrbtest::FIXNUM_MAX + 1 + d = Mrbtest::FIXNUM_MAX.__send__(:+, 1) + e = Mrbtest::FIXNUM_MAX + 1.0 + assert_equal Float, c.class + assert_equal Float, d.class + assert_float e, c + assert_float e, d +end + +assert('Integer#-', '15.2.8.3.2') do + a = 2-1 + b = 2-1.0 + + assert_equal 1, a + assert_equal 1.0, b + + c = Mrbtest::FIXNUM_MIN - 1 + d = Mrbtest::FIXNUM_MIN.__send__(:-, 1) + e = Mrbtest::FIXNUM_MIN - 1.0 + assert_equal Float, c.class + assert_equal Float, d.class + assert_float e, c + assert_float e, d +end + +assert('Integer#*', '15.2.8.3.3') do + a = 1*1 + b = 1*1.0 + + assert_equal 1, a + assert_equal 1.0, b + + assert_raise(TypeError){ 0*nil } + assert_raise(TypeError){ 1*nil } + + c = Mrbtest::FIXNUM_MAX * 2 + d = Mrbtest::FIXNUM_MAX.__send__(:*, 2) + e = Mrbtest::FIXNUM_MAX * 2.0 + assert_equal Float, c.class + assert_equal Float, d.class + assert_float e, c + assert_float e, d +end + +assert('Integer#/', '15.2.8.3.4') do + a = 2/1 + b = 2/1.0 + + assert_equal 2, a + assert_equal 2.0, b +end + +assert('Integer#%', '15.2.8.3.5') do + a = 1%1 + b = 1%1.0 + c = 2%4 + d = 2%5 + e = 2%-5 + f = -2%5 + g = -2%-5 + h = 2%-2 + i = -2%2 + j = -2%-2 + + assert_equal 0, a + assert_equal 0.0, b + assert_equal 2, c + assert_equal 2, d + assert_equal(-3, e) + assert_equal 3, f + assert_equal(-2, g) + assert_equal 0, h + assert_equal 0, i + assert_equal 0, j +end + +assert('Integer#<=>', '15.2.9.3.6') do + a = 1<=>0 + b = 1<=>1 + c = 1<=>2 + + assert_equal 1, a + assert_equal 0, b + assert_equal(-1, c) +end + +assert('Integer#==', '15.2.8.3.7') do + a = 1==0 + b = 1==1 + + assert_false a + assert_true b +end + +assert('Integer#~', '15.2.8.3.8') do + # Complement + assert_equal(-1, ~0) + assert_equal(-3, ~2) +end + +assert('Integer#&', '15.2.8.3.9') do + # Bitwise AND + # 0101 (5) + # & 0011 (3) + # = 0001 (1) + assert_equal 1, 5 & 3 +end + +assert('Integer#|', '15.2.8.3.10') do + # Bitwise OR + # 0101 (5) + # | 0011 (3) + # = 0111 (7) + assert_equal 7, 5 | 3 +end + +assert('Integer#^', '15.2.8.3.11') do + # Bitwise XOR + # 0101 (5) + # ^ 0011 (3) + # = 0110 (6) + assert_equal 6, 5 ^ 3 +end + +assert('Integer#<<', '15.2.8.3.12') do + # Left Shift by one + # 00010111 (23) + # = 00101110 (46) + assert_equal 46, 23 << 1 + + # Left Shift by a negative is Right Shift + assert_equal 23, 46 << -1 + + # Left Shift by 31 is bitShift overflow to SignedInt + assert_equal 2147483648, 1 << 31 + + # -3 Left Shift by 30 is bitShift overflow to SignedInt + assert_equal(-3221225472, -3 << 30) +end + +assert('Integer#>>', '15.2.8.3.13') do + # Right Shift by one + # 00101110 (46) + # = 00010111 (23) + assert_equal 23, 46 >> 1 + + # Right Shift by a negative is Left Shift + assert_equal 46, 23 >> -1 + + # Don't raise on large Right Shift + assert_equal 0, 23 >> 128 +end + +assert('Integer#ceil', '15.2.8.3.14') do + assert_equal 10, 10.ceil +end + +assert('Integer#downto', '15.2.8.3.15') do + a = 0 + 3.downto(1) do |i| + a += i + end + assert_equal 6, a +end + +assert('Integer#eql?', '15.2.8.3.16') do + a = 1.eql?(1) + b = 1.eql?(2) + c = 1.eql?(nil) + + assert_true a + assert_false b + assert_false c +end + +assert('Integer#floor', '15.2.8.3.17') do + a = 1.floor + + assert_equal 1, a +end + +assert('Integer#next', '15.2.8.3.19') do + assert_equal 2, 1.next +end + +assert('Integer#round', '15.2.8.3.20') do + assert_equal 1, 1.round +end + +assert('Integer#succ', '15.2.8.3.21') do + assert_equal 2, 1.succ +end + +assert('Integer#times', '15.2.8.3.22') do + a = 0 + 3.times do + a += 1 + end + assert_equal 3, a +end + +assert('Integer#to_f', '15.2.8.3.23') do + assert_equal 1.0, 1.to_f +end + +assert('Integer#to_i', '15.2.8.3.24') do + assert_equal 1, 1.to_i +end + +assert('Integer#to_s', '15.2.8.3.25') do + assert_equal '1', 1.to_s + assert_equal("-1", -1.to_s) +end + +assert('Integer#truncate', '15.2.8.3.26') do + assert_equal 1, 1.truncate +end + +assert('Integer#upto', '15.2.8.3.27') do + a = 0 + 1.upto(3) do |i| + a += i + end + assert_equal 6, a +end + +assert('Integer#divmod', '15.2.8.3.30') do + assert_equal [ 0, 0], 0.divmod(1) + assert_equal [ 0, 1], 1.divmod(3) + assert_equal [ 3, 0], 3.divmod(1) + assert_equal [ 2, 6], 20.divmod(7) + assert_equal [-1, 2], -3.divmod(5) + assert_equal [-2, -1], 25.divmod(-13) + assert_equal [ 1, -6], -13.divmod(-7) +end + +# Not ISO specified + +assert('Integer#step') do + a = [] + b = [] + 1.step(3) do |i| + a << i + end + 1.step(6, 2) do |i| + b << i + end + + assert_equal [1, 2, 3], a + assert_equal [1, 3, 5], b +end diff --git a/web/server/h2o/libh2o/deps/mruby/test/t/iterations.rb b/web/server/h2o/libh2o/deps/mruby/test/t/iterations.rb new file mode 100644 index 00000000..f227a603 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/test/t/iterations.rb @@ -0,0 +1,61 @@ +assert('while expression', '11.5.2.3.2') do + idx = 10 + all = [] + res = while idx > 0 + all << idx + idx -= 1 + end + + assert_equal nil, res + assert_equal [10,9,8,7,6,5,4,3,2,1], all +end + +assert('until expression', '11.5.2.3.3') do + idx = 10 + all = [] + res = until idx == 0 + all << idx + idx -= 1 + end + + assert_equal nil, res + assert_equal [10,9,8,7,6,5,4,3,2,1], all +end + +assert('break expression', '11.5.2.4.3') do + assert_equal :result do + while true + break :result + end + end + + assert_equal :result do + until false + break :result + end + end +end + +assert('next expression', '11.5.2.4.4') do + assert_equal [8,6,4,2,0] do + all = [] + idx = 10 + while idx > 0 + idx -= 1 + next if (idx % 2) == 1 + all << idx + end + all + end + + assert_equal [8,6,4,2,0] do + all = [] + idx = 10 + until idx == 0 + idx -= 1 + next if (idx % 2) == 1 + all << idx + end + all + end +end \ No newline at end of file diff --git a/web/server/h2o/libh2o/deps/mruby/test/t/kernel.rb b/web/server/h2o/libh2o/deps/mruby/test/t/kernel.rb new file mode 100644 index 00000000..e9bd24dc --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/test/t/kernel.rb @@ -0,0 +1,643 @@ +## +# Kernel ISO Test + +assert('Kernel', '15.3.1') do + assert_equal Module, Kernel.class +end + +assert('Kernel.block_given?', '15.3.1.2.2') do + def bg_try(&b) + if Kernel.block_given? + yield + else + "no block" + end + end + + assert_false Kernel.block_given? + # test without block + assert_equal "no block", bg_try + # test with block + assert_equal "block" do + bg_try { "block" } + end + # test with block + assert_equal "block" do + bg_try do + "block" + end + end +end + +# Kernel.eval is provided by the mruby-gem mrbgem. '15.3.1.2.3' + +assert('Kernel.global_variables', '15.3.1.2.4') do + assert_equal Array, Kernel.global_variables.class +end + +assert('Kernel.iterator?', '15.3.1.2.5') do + assert_false Kernel.iterator? +end + +assert('Kernel.lambda', '15.3.1.2.6') do + l = Kernel.lambda do + true + end + + m = Kernel.lambda(&l) + + assert_true l.call + assert_equal Proc, l.class + assert_true m.call + assert_equal Proc, m.class +end + +# Not implemented at the moment +#assert('Kernel.local_variables', '15.3.1.2.7') do +# Kernel.local_variables.class == Array +#end + +assert('Kernel.loop', '15.3.1.2.8') do + i = 0 + + Kernel.loop do + i += 1 + break if i == 100 + end + + assert_equal 100, i +end + +assert('Kernel.p', '15.3.1.2.9') do + # TODO search for a way to test p to stdio + assert_true true +end + +assert('Kernel.print', '15.3.1.2.10') do + # TODO search for a way to test print to stdio + assert_true true +end + +assert('Kernel.puts', '15.3.1.2.11') do + # TODO search for a way to test puts to stdio + assert_true true +end + +assert('Kernel.raise', '15.3.1.2.12') do + assert_raise RuntimeError do + Kernel.raise + end + + assert_raise RuntimeError do + Kernel.raise RuntimeError.new + end +end + +assert('Kernel#__id__', '15.3.1.3.3') do + assert_equal Fixnum, __id__.class +end + +assert('Kernel#__send__', '15.3.1.3.4') do + # test with block + l = __send__(:lambda) do + true + end + + assert_true l.call + assert_equal Proc, l.class + # test with argument + assert_true __send__(:respond_to?, :nil?) + # test without argument and without block + assert_equal Array, __send__(:public_methods).class +end + +assert('Kernel#block_given?', '15.3.1.3.6') do + def bg_try(&b) + if block_given? + yield + else + "no block" + end + end + + assert_false block_given? + assert_equal "no block", bg_try + assert_equal "block" do + bg_try { "block" } + end + assert_equal "block" do + bg_try do + "block" + end + end +end + +assert('Kernel#class', '15.3.1.3.7') do + assert_equal Module, Kernel.class +end + +assert('Kernel#clone', '15.3.1.3.8') do + class KernelCloneTest + def initialize + @v = 0 + end + + def get + @v + end + + def set(v) + @v = v + end + end + + a = KernelCloneTest.new + a.set(1) + b = a.clone + + def a.test + end + a.set(2) + c = a.clone + + immutables = [ 1, :foo, true, false, nil ] + error_count = 0 + immutables.each do |i| + begin + i.clone + rescue TypeError + error_count += 1 + end + end + + assert_equal 2, a.get + assert_equal 1, b.get + assert_equal 2, c.get + assert_true a.respond_to?(:test) + assert_false b.respond_to?(:test) + assert_true c.respond_to?(:test) +end + +assert('Kernel#dup', '15.3.1.3.9') do + class KernelDupTest + def initialize + @v = 0 + end + + def get + @v + end + + def set(v) + @v = v + end + end + + a = KernelDupTest.new + a.set(1) + b = a.dup + + def a.test + end + a.set(2) + c = a.dup + + immutables = [ 1, :foo, true, false, nil ] + error_count = 0 + immutables.each do |i| + begin + i.dup + rescue TypeError + error_count += 1 + end + end + + assert_equal immutables.size, error_count + assert_equal 2, a.get + assert_equal 1, b.get + assert_equal 2, c.get + assert_true a.respond_to?(:test) + assert_false b.respond_to?(:test) + assert_false c.respond_to?(:test) +end + +assert('Kernel#dup class') do + assert_nothing_raised do + Array.dup.new(200) + Range.dup.new(2, 3) + String.dup.new("a"*50) + end +end + +# Kernel#eval is provided by mruby-eval mrbgem '15.3.1.3.12' + +assert('Kernel#extend', '15.3.1.3.13') do + class Test4ExtendClass + end + + module Test4ExtendModule + def test_method; end + end + + a = Test4ExtendClass.new + a.extend(Test4ExtendModule) + b = Test4ExtendClass.new + + assert_true a.respond_to?(:test_method) + assert_false b.respond_to?(:test_method) +end + +assert('Kernel#extend works on toplevel', '15.3.1.3.13') do + module Test4ExtendModule + def test_method; end + end + # This would crash... + extend(Test4ExtendModule) + + assert_true respond_to?(:test_method) +end + +assert('Kernel#freeze') do + obj = Object.new + assert_equal obj, obj.freeze + assert_equal 0, 0.freeze + assert_equal :a, :a.freeze +end + +assert('Kernel#global_variables', '15.3.1.3.14') do + assert_equal Array, global_variables.class +end + +assert('Kernel#hash', '15.3.1.3.15') do + assert_equal hash, hash +end + +assert('Kernel#inspect', '15.3.1.3.17') do + s = inspect + + assert_equal String, s.class + assert_equal "main", s +end + +assert('Kernel#instance_variable_defined?', '15.3.1.3.20') do + o = Object.new + o.instance_variable_set(:@a, 1) + + assert_true o.instance_variable_defined?("@a") + assert_false o.instance_variable_defined?("@b") + assert_true o.instance_variable_defined?("@a"[0,2]) + assert_true o.instance_variable_defined?("@abc"[0,2]) +end + +assert('Kernel#instance_variables', '15.3.1.3.23') do + o = Object.new + o.instance_eval do + @a = 11 + @b = 12 + end + ivars = o.instance_variables + + assert_equal Array, ivars.class, + assert_equal(2, ivars.size) + assert_true ivars.include?(:@a) + assert_true ivars.include?(:@b) +end + +assert('Kernel#is_a?', '15.3.1.3.24') do + assert_true is_a?(Kernel) + assert_false is_a?(Array) + + assert_raise TypeError do + 42.is_a?(42) + end +end + +assert('Kernel#iterator?', '15.3.1.3.25') do + assert_false iterator? +end + +assert('Kernel#kind_of?', '15.3.1.3.26') do + assert_true kind_of?(Kernel) + assert_false kind_of?(Array) +end + +assert('Kernel#lambda', '15.3.1.3.27') do + l = lambda do + true + end + + m = lambda(&l) + + assert_true l.call + assert_equal Proc, l.class + assert_true m.call + assert_equal Proc, m.class +end + +# Not implemented yet +#assert('Kernel#local_variables', '15.3.1.3.28') do +# local_variables.class == Array +#end + +assert('Kernel#loop', '15.3.1.3.29') do + i = 0 + + loop do + i += 1 + break if i == 100 + end + + assert_equal i, 100 +end + +assert('Kernel#method_missing', '15.3.1.3.30') do + class MMTestClass + def method_missing(sym) + "A call to #{sym}" + end + end + mm_test = MMTestClass.new + assert_equal 'A call to no_method_named_this', mm_test.no_method_named_this + + class SuperMMTestClass < MMTestClass + def no_super_method_named_this + super + end + end + super_mm_test = SuperMMTestClass.new + assert_equal 'A call to no_super_method_named_this', super_mm_test.no_super_method_named_this + + class NoSuperMethodTestClass + def no_super_method_named_this + super + end + end + no_super_test = NoSuperMethodTestClass.new + begin + no_super_test.no_super_method_named_this + rescue NoMethodError => e + assert_equal "undefined method 'no_super_method_named_this' for #{no_super_test}", e.message + end + + a = String.new + begin + a.no_method_named_this + rescue NoMethodError => e + assert_equal "undefined method 'no_method_named_this' for \"\"", e.message + end + + class ShortInspectClass + def inspect + 'An inspect string' + end + end + b = ShortInspectClass.new + begin + b.no_method_named_this + rescue NoMethodError => e + assert_equal "undefined method 'no_method_named_this' for An inspect string", e.message + end + + class LongInspectClass + def inspect + "A" * 70 + end + end + c = LongInspectClass.new + begin + c.no_method_named_this + rescue NoMethodError => e + assert_equal "undefined method 'no_method_named_this' for #{c}", e.message + end + + class NoInspectClass + undef inspect + end + d = NoInspectClass.new + begin + d.no_method_named_this + rescue NoMethodError => e + assert_equal "undefined method 'no_method_named_this' for #{d}", e.message + end +end + +assert('Kernel#methods', '15.3.1.3.31') do + assert_equal Array, methods.class +end + +assert('Kernel#nil?', '15.3.1.3.32') do + assert_false nil? +end + +assert('Kernel#object_id', '15.3.1.3.33') do + a = "" + b = "" + assert_not_equal a.object_id, b.object_id + + assert_kind_of Numeric, object_id + assert_kind_of Numeric, "".object_id + assert_kind_of Numeric, true.object_id + assert_kind_of Numeric, false.object_id + assert_kind_of Numeric, nil.object_id + assert_kind_of Numeric, :no.object_id + assert_kind_of Numeric, 1.object_id + assert_kind_of Numeric, 1.0.object_id +end + +# Kernel#p is defined in mruby-print mrbgem. '15.3.1.3.34' + +# Kernel#print is defined in mruby-print mrbgem. '15.3.1.3.35' + +assert('Kernel#private_methods', '15.3.1.3.36') do + assert_equal Array, private_methods.class +end + +assert('Kernel#protected_methods', '15.3.1.3.37') do + assert_equal Array, protected_methods.class +end + +assert('Kernel#public_methods', '15.3.1.3.38') do + assert_equal Array, public_methods.class + class Foo + def foo + end + end + assert_equal [:foo], Foo.new.public_methods(false) +end + +# Kernel#puts is defined in mruby-print mrbgem. '15.3.1.3.39' + +assert('Kernel#raise', '15.3.1.3.40') do + assert_raise RuntimeError do + raise + end + + assert_raise RuntimeError do + raise RuntimeError.new + end +end + +assert('Kernel#remove_instance_variable', '15.3.1.3.41') do + class Test4RemoveInstanceVar + attr_reader :var + def initialize + @var = 99 + end + def remove + remove_instance_variable(:@var) + end + end + + tri = Test4RemoveInstanceVar.new + assert_equal 99, tri.var + tri.remove + assert_equal nil, tri.var + assert_raise NameError do + tri.remove + end +end + +# Kernel#require is defined in mruby-require. '15.3.1.3.42' + +assert('Kernel#respond_to?', '15.3.1.3.43') do + class Test4RespondTo + def valid_method; end + + def test_method; end + undef test_method + end + + assert_raise TypeError do + Test4RespondTo.new.respond_to?(1) + end + + assert_raise ArgumentError do + Test4RespondTo.new.respond_to? + end + + assert_raise ArgumentError do + Test4RespondTo.new.respond_to? :a, true, :aa + end + + assert_true respond_to?(:nil?) + assert_true Test4RespondTo.new.respond_to?(:valid_method) + assert_true Test4RespondTo.new.respond_to?('valid_method') + assert_false Test4RespondTo.new.respond_to?(:test_method) +end + +assert('Kernel#send', '15.3.1.3.44') do + # test with block + l = send(:lambda) do + true + end + + assert_true l.call + assert_equal l.class, Proc + # test with argument + assert_true send(:respond_to?, :nil?) + # test without argument and without block + assert_equal send(:public_methods).class, Array +end + +assert('Kernel#singleton_methods', '15.3.1.3.45') do + assert_equal singleton_methods.class, Array +end + +assert('Kernel#to_s', '15.3.1.3.46') do + assert_equal to_s.class, String +end + +assert('Kernel#to_s on primitives') do + begin + Fixnum.alias_method :to_s_, :to_s + Fixnum.remove_method :to_s + + assert_nothing_raised do + # segfaults if mrb_cptr is used + 1.to_s + end + ensure + Fixnum.alias_method :to_s, :to_s_ + Fixnum.remove_method :to_s_ + end +end + +assert('Kernel.local_variables', '15.3.1.2.7') do + a, b = 0, 1 + a += b + + vars = Kernel.local_variables.sort + assert_equal [:a, :b, :vars], vars + + assert_equal [:a, :b, :c, :vars], Proc.new { |a, b| + c = 2 + Kernel.local_variables.sort + }.call(-1, -2) +end + +assert('Kernel#!=') do + str1 = "hello" + str2 = str1 + str3 = "world" + + assert_false (str1[1] != 'e') + assert_true (str1 != str3) + assert_false (str2 != str1) +end + +# operator "!~" is defined in ISO Ruby 11.4.4. +assert('Kernel#!~') do + x = "x" + def x.=~(other) + other == "x" + end + assert_false x !~ "x" + assert_true x !~ "z" + + y = "y" + def y.=~(other) + other == "y" + end + def y.!~(other) + other == "not y" + end + assert_false y !~ "y" + assert_false y !~ "z" + assert_true y !~ "not y" +end + +assert('Kernel#respond_to_missing?') do + class Test4RespondToMissing + def respond_to_missing?(method_name, include_private = false) + method_name == :a_method + end + end + + assert_true Test4RespondToMissing.new.respond_to?(:a_method) + assert_false Test4RespondToMissing.new.respond_to?(:no_method) +end + +assert('Kernel#global_variables') do + variables = global_variables + 1.upto(9) do |i| + assert_equal variables.include?(:"$#{i}"), true + end +end + +assert('Kernel#define_singleton_method') do + o = Object.new + ret = o.define_singleton_method(:test_method) do + :singleton_method_ok + end + assert_equal :test_method, ret + assert_equal :singleton_method_ok, o.test_method +end + +assert('stack extend') do + def recurse(count, stop) + return count if count > stop + recurse(count+1, stop) + end + + assert_equal 6, recurse(0, 5) +end diff --git a/web/server/h2o/libh2o/deps/mruby/test/t/lang.rb b/web/server/h2o/libh2o/deps/mruby/test/t/lang.rb new file mode 100755 index 00000000..57c37564 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/test/t/lang.rb @@ -0,0 +1,74 @@ +# The aim of these tests is to detect pitfall for optimized VM. + +# Test for or/and +# +# You may think instruction fusion(OP_EQ and OP_JMPIF) for avoiding +# generate intermediate boolean value. +# But and/or is pitfall for this fusioning. +# +# For example, the following mruby code: +# +# if i > 0 and i < 10 then +# +# compiles to the following byte code: +# +# 1 000 OP_LOADI R1 0 ; R1:i +# 2 001 OP_MOVE R2 R1 ; R1:i +# 2 002 OP_LOADI R3 0 +# 2 003 OP_GT R2 :> 1 +# 2 004 OP_JMPNOT R2 008 +# 2 005 OP_MOVE R2 R1 ; R1:i +# 2 006 OP_LOADI R3 10 +# 2 007 OP_LT R2 :< 1 +# 2 008 OP_JMPNOT R2 (The address of end of then part) +# +# When the instruction fusion the OP_GT and OP_JMPNOT you fell into the pitfalls. +# The deleted intermediate boolean value is used in OP_JMPNOT (address 008). + +assert('and', '11.2.3') do + a = 1 + if a > 0 and a < 10 then + b = 1 + else + b = 0 + end + assert_equal 1, b + + if a < 0 and a < 10 then + b = 1 + else + b = 0 + end + assert_equal 0, b + + if a < 0 and a > 10 then + b = 1 + else + b = 0 + end + assert_equal 0, b +end + +assert('or','11.2.4') do + a = 1 + if a > 0 or a < 10 then + b = 1 + else + b = 0 + end + assert_equal 1, b + + if a < 0 or a < 10 then + b = 1 + else + b = 0 + end + assert_equal 1, b + + if a < 0 or a > 10 then + b = 1 + else + b = 0 + end + assert_equal 0, b +end diff --git a/web/server/h2o/libh2o/deps/mruby/test/t/literals.rb b/web/server/h2o/libh2o/deps/mruby/test/t/literals.rb new file mode 100644 index 00000000..51a37c32 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/test/t/literals.rb @@ -0,0 +1,337 @@ +## +# Literals ISO Test + +assert('Literals Numerical', '8.7.6.2') do + # signed and unsigned integer + assert_equal 1, 1 + assert_equal(-1, -1) + assert_equal(+1, +1) + # signed and unsigned float + assert_equal 1.0, 1.0 + assert_equal(-1.0, -1.0) + # binary + assert_equal 128, 0b10000000 + assert_equal 128, 0B10000000 + # octal + assert_equal 8, 0o10 + assert_equal 8, 0O10 + assert_equal 8, 0_10 + # hex + assert_equal 255, 0xff + assert_equal 255, 0Xff + # decimal + assert_equal 999, 0d999 + assert_equal 999, 0D999 + # decimal seperator + assert_equal 10000000, 10_000_000 + assert_equal 10, 1_0 + # integer with exponent + assert_equal 10.0, 1e1 + assert_equal(0.1, 1e-1) + assert_equal 10.0, 1e+1 + # float with exponent + assert_equal 10.0, 1.0e1 + assert_equal(0.1, 1.0e-1) + assert_equal 10.0, 1.0e+1 +end + +assert('Literals Strings Single Quoted', '8.7.6.3.2') do + assert_equal 'abc', 'abc' + assert_equal '\'', '\'' + assert_equal '\\', '\\' +end + +assert('Literals Strings Double Quoted', '8.7.6.3.3') do + a = "abc" + + assert_equal "abc", "abc" + assert_equal "\"", "\"" + assert_equal "\\", "\\" + assert_equal "abc", "#{a}" +end + +assert('Literals Strings Quoted Non-Expanded', '8.7.6.3.4') do + a = %q{abc} + b = %q(abc) + c = %q[abc] + d = %q + e = %q/abc/ + f = %q/ab\/c/ + g = %q{#{a}} + + assert_equal 'abc', a + assert_equal 'abc', b + assert_equal 'abc', c + assert_equal 'abc', d + assert_equal 'abc', e + assert_equal 'ab/c', f + assert_equal '#{a}', g +end + +assert('Literals Strings Quoted Expanded', '8.7.6.3.5') do + a = %Q{abc} + b = %Q(abc) + c = %Q[abc] + d = %Q + e = %Q/abc/ + f = %Q/ab\/c/ + g = %Q{#{a}} + + assert_equal 'abc', a + assert_equal 'abc', b + assert_equal 'abc', c + assert_equal 'abc', d + assert_equal 'abc', e + assert_equal 'ab/c', f + assert_equal 'abc', g +end + +assert('Literals Strings Here documents', '8.7.6.3.6') do + a = <\"mm3\\n\"}y\nmm1\n", "mm2\n"], m + assert_equal ({:x=>"mm3\n"}), m2 + assert_equal [1, "nn1\n", 3, 4], n + assert_equal "a $ q\n $ c $ d", q1 + assert_equal "l $ mqq\nn $ o", q2 + assert_equal ["1", "www\n", "3", "4", "5"], w + assert_equal [1, "foo 222 333\n 444\n5\n bar\n6\n", 9], x + assert_equal "", z + +end + + +assert('Literals Array', '8.7.6.4') do + a = %W{abc#{1+2}def \}g} + b = %W(abc #{2+3} def \(g) + c = %W[#{3+4}] + d = %W< #{4+5} > + e = %W// + f = %W[[ab cd][ef]] + g = %W{ + ab + #{-1}1 + 2#{2} + } + h = %W(a\nb + test\ abc + c\ +d + x\y x\\y x\\\y) + + assert_equal ['abc3def', '}g'], a + assert_equal ['abc', '5', 'def', '(g'], b + assert_equal ['7'],c + assert_equal ['9'], d + assert_equal [], e + assert_equal ['[ab', 'cd][ef]'], f + assert_equal ['ab', '-11', '22'], g + assert_equal ["a\nb", 'test abc', "c\nd", "xy", "x\\y", "x\\y"], h + + a = %w{abc#{1+2}def \}g} + b = %w(abc #{2+3} def \(g) + c = %w[#{3+4}] + d = %w< #{4+5} > + e = %w// + f = %w[[ab cd][ef]] + g = %w{ + ab + #{-1}1 + 2#{2} + } + h = %w(a\nb + test\ abc + c\ +d + x\y x\\y x\\\y) + + assert_equal ['abc#{1+2}def', '}g'], a + assert_equal ['abc', '#{2+3}', 'def', '(g'], b + assert_equal ['#{3+4}'], c + assert_equal ['#{4+5}'], d + assert_equal [], e + assert_equal ['[ab', 'cd][ef]'], f + assert_equal ['ab', '#{-1}1', '2#{2}'], g + assert_equal ["a\\nb", "test abc", "c\nd", "x\\y", "x\\y", "x\\\\y"], h +end + + +assert('Literals Array of symbols') do + a = %I{abc#{1+2}def \}g} + b = %I(abc #{2+3} def \(g) + c = %I[#{3+4}] + d = %I< #{4+5} > + e = %I// + f = %I[[ab cd][ef]] + g = %I{ + ab + #{-1}1 + 2#{2} + } + + assert_equal [:'abc3def', :'}g'], a + assert_equal [:'abc', :'5', :'def', :'(g'], b + assert_equal [:'7'],c + assert_equal [:'9'], d + assert_equal [], e + assert_equal [:'[ab', :'cd][ef]'], f + assert_equal [:'ab', :'-11', :'22'], g + + a = %i{abc#{1+2}def \}g} + b = %i(abc #{2+3} def \(g) + c = %i[#{3+4}] + d = %i< #{4+5} > + e = %i// + f = %i[[ab cd][ef]] + g = %i{ + ab + #{-1}1 + 2#{2} + } + + assert_equal [:'abc#{1+2}def', :'}g'], a + assert_equal [:'abc', :'#{2+3}', :'def', :'(g'], b + assert_equal [:'#{3+4}'], c + assert_equal [:'#{4+5}'], d + assert_equal [] ,e + assert_equal [:'[ab', :'cd][ef]'], f + assert_equal [:'ab', :'#{-1}1', :'2#{2}'], g +end + +assert('Literals Symbol', '8.7.6.6') do + # do not compile error + :$asd + :@asd + :@@asd + :asd= + :asd! + :asd? + :+ + :+@ + :if + :BEGIN + + a = :"asd qwe" + b = :'foo bar' + c = :"a#{1+2}b" + d = %s(asd) + e = %s( foo \)) + f = %s[asd \[ +qwe] + g = %s/foo#{1+2}bar/ + h = %s{{foo bar}} + + assert_equal :'asd qwe', a + assert_equal :"foo bar", b + assert_equal :a3b, c + assert_equal :asd, d + assert_equal :' foo )', e + assert_equal :"asd [\nqwe", f + assert_equal :'foo#{1+2}bar', g + assert_equal :'{foo bar}', h +end + +# Not Implemented ATM assert('Literals Regular expression', '8.7.6.5') do diff --git a/web/server/h2o/libh2o/deps/mruby/test/t/localjumperror.rb b/web/server/h2o/libh2o/deps/mruby/test/t/localjumperror.rb new file mode 100644 index 00000000..1780cb51 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/test/t/localjumperror.rb @@ -0,0 +1,13 @@ +## +# LocalJumpError ISO Test + +assert('LocalJumpError', '15.2.25') do + assert_equal Class, LocalJumpError.class +# assert_raise LocalJumpError do +# # this will cause an exception due to the wrong location +# retry +# end +end + +# TODO 15.2.25.2.1 LocalJumpError#exit_value +# TODO 15.2.25.2.2 LocalJumpError#reason diff --git a/web/server/h2o/libh2o/deps/mruby/test/t/methods.rb b/web/server/h2o/libh2o/deps/mruby/test/t/methods.rb new file mode 100644 index 00000000..f9c25dc3 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/test/t/methods.rb @@ -0,0 +1,109 @@ +## +# Chapter 13.3 "Methods" ISO Test + +assert('The alias statement', '13.3.6 a) 4)') do + # check aliasing in all possible ways + + def alias_test_method_original; true; end + + alias alias_test_method_a alias_test_method_original + alias :alias_test_method_b :alias_test_method_original + + assert_true(alias_test_method_original) + assert_true(alias_test_method_a) + assert_true(alias_test_method_b) +end + +assert('The alias statement (overwrite original)', '13.3.6 a) 4)') do + # check that an aliased method can be overwritten + # without side effect + + def alias_test_method_original; true; end + + alias alias_test_method_a alias_test_method_original + alias :alias_test_method_b :alias_test_method_original + + assert_true(alias_test_method_original) + + def alias_test_method_original; false; end + + assert_false(alias_test_method_original) + assert_true(alias_test_method_a) + assert_true(alias_test_method_b) +end + +assert('The alias statement', '13.3.6 a) 5)') do + # check that alias is raising NameError if + # non-existing method should be undefined + + assert_raise(NameError) do + alias new_name_a non_existing_method + end + + assert_raise(NameError) do + alias :new_name_b :non_existing_method + end +end + +assert('The undef statement', '13.3.7 a) 4)') do + # check that undef is undefining method + # based on the method name + + def existing_method_a; true; end + def existing_method_b; true; end + def existing_method_c; true; end + def existing_method_d; true; end + def existing_method_e; true; end + def existing_method_f; true; end + + # check that methods are defined + + assert_true(existing_method_a, 'Method should be defined') + assert_true(existing_method_b, 'Method should be defined') + assert_true(existing_method_c, 'Method should be defined') + assert_true(existing_method_d, 'Method should be defined') + assert_true(existing_method_e, 'Method should be defined') + assert_true(existing_method_f, 'Method should be defined') + + # undefine in all possible ways and check that method + # is undefined + + undef existing_method_a + assert_raise(NoMethodError) do + existing_method_a + end + + undef :existing_method_b + assert_raise(NoMethodError) do + existing_method_b + end + + undef existing_method_c, existing_method_d + assert_raise(NoMethodError) do + existing_method_c + end + assert_raise(NoMethodError) do + existing_method_d + end + + undef :existing_method_e, :existing_method_f + assert_raise(NoMethodError) do + existing_method_e + end + assert_raise(NoMethodError) do + existing_method_f + end +end + +assert('The undef statement (method undefined)', '13.3.7 a) 5)') do + # check that undef is raising NameError if + # non-existing method should be undefined + + assert_raise(NameError) do + undef non_existing_method + end + + assert_raise(NameError) do + undef :non_existing_method + end +end diff --git a/web/server/h2o/libh2o/deps/mruby/test/t/module.rb b/web/server/h2o/libh2o/deps/mruby/test/t/module.rb new file mode 100644 index 00000000..5a46c24f --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/test/t/module.rb @@ -0,0 +1,914 @@ +## +# Module ISO Test + +def labeled_module(name, &block) + Module.new do + singleton_class.class_eval do + define_method(:to_s) { name } + alias_method :inspect, :to_s + end + class_eval(&block) if block + end +end + +def labeled_class(name, supklass = Object, &block) + Class.new(supklass) do + singleton_class.class_eval do + define_method(:to_s) { name } + alias_method :inspect, :to_s + end + class_eval(&block) if block + end +end + +assert('Module', '15.2.2') do + assert_equal Class, Module.class +end + +# TODO not implemented ATM assert('Module.constants', '15.2.2.3.1') do + +# TODO not implemented ATM assert('Module.nesting', '15.2.2.3.2') do + +assert('Module.nesting', '15.2.2.2.2') do + module Test4ModuleNesting + module Test4ModuleNesting2 + assert_equal [Test4ModuleNesting2, Test4ModuleNesting], + Module.nesting + end + end + module Test4ModuleNesting::Test4ModuleNesting2 + assert_equal [Test4ModuleNesting::Test4ModuleNesting2], Module.nesting + end +end + +assert('Module#ancestors', '15.2.2.4.9') do + class Test4ModuleAncestors + end + sc = Test4ModuleAncestors.singleton_class + r = String.ancestors + + assert_equal Array, r.class + assert_true r.include?(String) + assert_true r.include?(Object) +end + +assert('Module#append_features', '15.2.2.4.10') do + module Test4AppendFeatures + def self.append_features(mod) + Test4AppendFeatures2.const_set(:Const4AppendFeatures2, mod) + end + end + module Test4AppendFeatures2 + include Test4AppendFeatures + end + + assert_equal Test4AppendFeatures2, Test4AppendFeatures2.const_get(:Const4AppendFeatures2) +end + +assert('Module#attr NameError') do + %w[ + foo? + @foo + @@foo + $foo + ].each do |name| + module NameTest; end + + assert_raise(NameError) do + NameTest.module_eval { attr_reader name.to_sym } + end + + assert_raise(NameError) do + NameTest.module_eval { attr_writer name.to_sym } + end + + assert_raise(NameError) do + NameTest.module_eval { attr name.to_sym } + end + + assert_raise(NameError) do + NameTest.module_eval { attr_accessor name.to_sym } + end + end + +end + +assert('Module#attr', '15.2.2.4.11') do + class AttrTest + class << self + attr :cattr + def cattr_val=(val) + @cattr = val + end + end + attr :iattr + def iattr_val=(val) + @iattr = val + end + end + + test = AttrTest.new + assert_true AttrTest.respond_to?(:cattr) + assert_true test.respond_to?(:iattr) + + assert_false AttrTest.respond_to?(:cattr=) + assert_false test.respond_to?(:iattr=) + + test.iattr_val = 'test' + assert_equal 'test', test.iattr + + AttrTest.cattr_val = 'test' + assert_equal 'test', AttrTest.cattr +end + +assert('Module#attr_accessor', '15.2.2.4.12') do + class AttrTestAccessor + class << self + attr_accessor :cattr + end + attr_accessor :iattr, 'iattr2' + end + + attr_instance = AttrTestAccessor.new + assert_true AttrTestAccessor.respond_to?(:cattr=) + assert_true attr_instance.respond_to?(:iattr=) + assert_true attr_instance.respond_to?(:iattr2=) + assert_true AttrTestAccessor.respond_to?(:cattr) + assert_true attr_instance.respond_to?(:iattr) + assert_true attr_instance.respond_to?(:iattr2) + + attr_instance.iattr = 'test' + assert_equal 'test', attr_instance.iattr + + AttrTestAccessor.cattr = 'test' + assert_equal 'test', AttrTestAccessor.cattr +end + +assert('Module#attr_reader', '15.2.2.4.13') do + class AttrTestReader + class << self + attr_reader :cattr + def cattr_val=(val) + @cattr = val + end + end + attr_reader :iattr, 'iattr2' + def iattr_val=(val) + @iattr = val + end + end + + attr_instance = AttrTestReader.new + assert_true AttrTestReader.respond_to?(:cattr) + assert_true attr_instance.respond_to?(:iattr) + assert_true attr_instance.respond_to?(:iattr2) + + assert_false AttrTestReader.respond_to?(:cattr=) + assert_false attr_instance.respond_to?(:iattr=) + assert_false attr_instance.respond_to?(:iattr2=) + + attr_instance.iattr_val = 'test' + assert_equal 'test', attr_instance.iattr + + AttrTestReader.cattr_val = 'test' + assert_equal 'test', AttrTestReader.cattr +end + +assert('Module#attr_writer', '15.2.2.4.14') do + class AttrTestWriter + class << self + attr_writer :cattr + def cattr_val + @cattr + end + end + attr_writer :iattr, 'iattr2' + def iattr_val + @iattr + end + end + + attr_instance = AttrTestWriter.new + assert_true AttrTestWriter.respond_to?(:cattr=) + assert_true attr_instance.respond_to?(:iattr=) + assert_true attr_instance.respond_to?(:iattr2=) + + assert_false AttrTestWriter.respond_to?(:cattr) + assert_false attr_instance.respond_to?(:iattr) + assert_false attr_instance.respond_to?(:iattr2) + + attr_instance.iattr = 'test' + assert_equal 'test', attr_instance.iattr_val + + AttrTestWriter.cattr = 'test' + assert_equal 'test', AttrTestWriter.cattr_val +end + +assert('Module#class_eval', '15.2.2.4.15') do + class Test4ClassEval + @a = 11 + @b = 12 + end + Test4ClassEval.class_eval do + def method1 + end + end + r = Test4ClassEval.instance_methods + + assert_equal 11, Test4ClassEval.class_eval{ @a } + assert_equal 12, Test4ClassEval.class_eval{ @b } + assert_equal Array, r.class + assert_true r.include?(:method1) +end + +assert('Module#class_variable_defined?', '15.2.2.4.16') do + class Test4ClassVariableDefined + @@cv = 99 + end + + assert_true Test4ClassVariableDefined.class_variable_defined?(:@@cv) + assert_false Test4ClassVariableDefined.class_variable_defined?(:@@noexisting) +end + +assert('Module#class_variable_get', '15.2.2.4.17') do + class Test4ClassVariableGet + @@cv = 99 + end + + assert_equal 99, Test4ClassVariableGet.class_variable_get(:@@cv) +end + +assert('Module#class_variable_set', '15.2.2.4.18') do + class Test4ClassVariableSet + @@foo = 100 + def foo + @@foo + end + end + + assert_true Test4ClassVariableSet.class_variable_set(:@@cv, 99) + assert_true Test4ClassVariableSet.class_variable_set(:@@foo, 101) + assert_true Test4ClassVariableSet.class_variables.include? :@@cv + assert_equal 99, Test4ClassVariableSet.class_variable_get(:@@cv) + assert_equal 101, Test4ClassVariableSet.new.foo +end + +assert('Module#class_variables', '15.2.2.4.19') do + class Test4ClassVariables1 + @@var1 = 1 + end + class Test4ClassVariables2 < Test4ClassVariables1 + @@var2 = 2 + end + + assert_equal [:@@var1], Test4ClassVariables1.class_variables + assert_equal [:@@var2, :@@var1], Test4ClassVariables2.class_variables +end + +assert('Module#const_defined?', '15.2.2.4.20') do + module Test4ConstDefined + Const4Test4ConstDefined = true + end + + assert_true Test4ConstDefined.const_defined?(:Const4Test4ConstDefined) + assert_false Test4ConstDefined.const_defined?(:NotExisting) +end + +assert('Module#const_get', '15.2.2.4.21') do + module Test4ConstGet + Const4Test4ConstGet = 42 + end + + assert_equal 42, Test4ConstGet.const_get(:Const4Test4ConstGet) + assert_equal 42, Test4ConstGet.const_get("Const4Test4ConstGet") + assert_equal 42, Object.const_get("Test4ConstGet::Const4Test4ConstGet") + + assert_raise(TypeError){ Test4ConstGet.const_get(123) } + assert_raise(NameError){ Test4ConstGet.const_get(:I_DO_NOT_EXIST) } + assert_raise(NameError){ Test4ConstGet.const_get("I_DO_NOT_EXIST::ME_NEITHER") } +end + +assert('Module#const_missing', '15.2.2.4.22') do + module Test4ConstMissing + def self.const_missing(sym) + 42 # the answer to everything + end + end + + assert_equal 42, Test4ConstMissing.const_get(:ConstDoesntExist) +end + +assert('Module#const_set', '15.2.2.4.23') do + module Test4ConstSet + Const4Test4ConstSet = 42 + end + + assert_true Test4ConstSet.const_set(:Const4Test4ConstSet, 23) + assert_equal 23, Test4ConstSet.const_get(:Const4Test4ConstSet) +end + +assert('Module#constants', '15.2.2.4.24') do + $n = [] + module TestA + C = 1 + end + class TestB + include TestA + C2 = 1 + $n = constants.sort + end + + assert_equal [ :C ], TestA.constants + assert_equal [ :C, :C2 ], $n +end + +assert('Module#include', '15.2.2.4.27') do + module Test4Include + Const4Include = 42 + end + module Test4Include2 + @include_result = include Test4Include + class << self + attr_reader :include_result + end + end + + assert_equal 42, Test4Include2.const_get(:Const4Include) + assert_equal Test4Include2, Test4Include2.include_result +end + +assert('Module#include?', '15.2.2.4.28') do + module Test4IncludeP + end + class Test4IncludeP2 + include Test4IncludeP + end + class Test4IncludeP3 < Test4IncludeP2 + end + + assert_true Test4IncludeP2.include?(Test4IncludeP) + assert_true Test4IncludeP3.include?(Test4IncludeP) + assert_false Test4IncludeP.include?(Test4IncludeP) +end + +assert('Module#included', '15.2.2.4.29') do + module Test4Included + Const4Included = 42 + def self.included mod + Test4Included.const_set(:Const4Included2, mod) + end + end + module Test4Included2 + include Test4Included + end + + assert_equal 42, Test4Included2.const_get(:Const4Included) + assert_equal Test4Included2, Test4Included2.const_get(:Const4Included2) +end + +assert('Module#included_modules', '15.2.2.4.30') do + module Test4includedModules + end + module Test4includedModules2 + include Test4includedModules + end + r = Test4includedModules2.included_modules + + assert_equal Array, r.class + assert_true r.include?(Test4includedModules) +end + +assert('Module#initialize', '15.2.2.4.31') do + assert_kind_of Module, Module.new + mod = Module.new { def hello; "hello"; end } + assert_equal [:hello], mod.instance_methods + a = nil + mod = Module.new { |m| a = m } + assert_equal mod, a +end + +assert('Module#instance_methods', '15.2.2.4.33') do + module Test4InstanceMethodsA + def method1() end + end + class Test4InstanceMethodsB + def method2() end + end + class Test4InstanceMethodsC < Test4InstanceMethodsB + def method3() end + end + + r = Test4InstanceMethodsC.instance_methods(true) + + assert_equal [:method1], Test4InstanceMethodsA.instance_methods + assert_equal [:method2], Test4InstanceMethodsB.instance_methods(false) + assert_equal [:method3], Test4InstanceMethodsC.instance_methods(false) + assert_equal Array, r.class + assert_true r.include?(:method3) + assert_true r.include?(:method2) +end + +assert('Module#method_defined?', '15.2.2.4.34') do + module Test4MethodDefined + module A + def method1() end + end + + class B + def method2() end + end + + class C < B + include A + def method3() end + end + end + + assert_true Test4MethodDefined::A.method_defined? :method1 + assert_true Test4MethodDefined::C.method_defined? :method1 + assert_true Test4MethodDefined::C.method_defined? "method2" + assert_true Test4MethodDefined::C.method_defined? "method3" + assert_false Test4MethodDefined::C.method_defined? "method4" +end + + +assert('Module#module_eval', '15.2.2.4.35') do + module Test4ModuleEval + @a = 11 + @b = 12 + end + + assert_equal 11, Test4ModuleEval.module_eval{ @a } + assert_equal 12, Test4ModuleEval.module_eval{ @b } +end + +assert('Module#remove_class_variable', '15.2.2.4.39') do + class Test4RemoveClassVariable + @@cv = 99 + end + + assert_equal 99, Test4RemoveClassVariable.remove_class_variable(:@@cv) + assert_false Test4RemoveClassVariable.class_variables.include? :@@cv +end + +assert('Module#remove_const', '15.2.2.4.40') do + module Test4RemoveConst + ExistingConst = 23 + end + + result = Test4RemoveConst.module_eval { remove_const :ExistingConst } + + name_error = false + begin + Test4RemoveConst.module_eval { remove_const :NonExistingConst } + rescue NameError + name_error = true + end + + # Constant removed from Module + assert_false Test4RemoveConst.const_defined? :ExistingConst + # Return value of binding + assert_equal 23, result + # Name Error raised when Constant doesn't exist + assert_true name_error +end + +assert('Module#remove_method', '15.2.2.4.41') do + module Test4RemoveMethod + class Parent + def hello + end + end + + class Child < Parent + def hello + end + end + end + + assert_true Test4RemoveMethod::Child.class_eval{ remove_method :hello } + assert_true Test4RemoveMethod::Child.instance_methods.include? :hello + assert_false Test4RemoveMethod::Child.instance_methods(false).include? :hello +end + +assert('Module#undef_method', '15.2.2.4.42') do + module Test4UndefMethod + class Parent + def hello + end + end + + class Child < Parent + def hello + end + end + + class GrandChild < Child + end + end + Test4UndefMethod::Child.class_eval{ undef_method :hello } + + assert_true Test4UndefMethod::Parent.new.respond_to?(:hello) + assert_false Test4UndefMethod::Child.new.respond_to?(:hello) + assert_false Test4UndefMethod::GrandChild.new.respond_to?(:hello) + assert_false Test4UndefMethod::Child.instance_methods(false).include? :hello +end + +# Not ISO specified + +assert('Module#define_method') do + c = Class.new { + define_method(:m1) { :ok } + define_method(:m2, Proc.new { :ok }) + } + assert_equal c.new.m1, :ok + assert_equal c.new.m2, :ok + assert_raise(TypeError) do + Class.new { define_method(:n1, nil) } + end +end + +# @!group prepend + assert('Module#prepend') do + module M0 + def m1; [:M0] end + end + module M1 + def m1; [:M1, super, :M1] end + end + module M2 + def m1; [:M2, super, :M2] end + end + M3 = Module.new do + def m1; [:M3, super, :M3] end + end + module M4 + def m1; [:M4, super, :M4] end + end + + class P0 + include M0 + prepend M1 + def m1; [:C0, super, :C0] end + end + class P1 < P0 + prepend M2, M3 + include M4 + def m1; [:C1, super, :C1] end + end + + obj = P1.new + expected = [:M2,[:M3,[:C1,[:M4,[:M1,[:C0,[:M0],:C0],:M1],:M4],:C1],:M3],:M2] + assert_equal(expected, obj.m1) + end + + assert('Module#prepend result') do + module TestPrepended; end + module TestPrependResult + @prepend_result = prepend TestPrepended + class << self + attr_reader :prepend_result + end + end + + assert_equal TestPrependResult, TestPrependResult.prepend_result + end + + # mruby shouldn't be affected by this since there is + # no visibility control (yet) + assert('Module#prepend public') do + assert_nothing_raised('ruby/ruby #8846') do + Class.new.prepend(Module.new) + end + end + + assert('Module#prepend inheritance') do + bug6654 = '[ruby-core:45914]' + a = labeled_module('a') + b = labeled_module('b') { include a } + c = labeled_module('c') { prepend b } + + #assert bug6654 do + # the Module#< operator should be used here instead, but we don't have it + assert_include(c.ancestors, a) + assert_include(c.ancestors, b) + #end + + bug8357 = '[ruby-core:54736] [Bug #8357]' + b = labeled_module('b') { prepend a } + c = labeled_class('c') { include b } + + #assert bug8357 do + # the Module#< operator should be used here instead, but we don't have it + assert_include(c.ancestors, a) + assert_include(c.ancestors, b) + #end + + bug8357 = '[ruby-core:54742] [Bug #8357]' + assert_kind_of(b, c.new, bug8357) + end + + assert('Moduler#prepend + #instance_methods') do + bug6655 = '[ruby-core:45915]' + assert_equal(Object.instance_methods, Class.new {prepend Module.new}.instance_methods, bug6655) + end + + assert 'Module#prepend + #singleton_methods' do + o = Object.new + o.singleton_class.class_eval {prepend Module.new} + assert_equal([], o.singleton_methods) + end + + assert 'Module#prepend + #remove_method' do + c = Class.new do + prepend Module.new { def foo; end } + end + assert_raise(NameError) do + c.class_eval do + remove_method(:foo) + end + end + c.class_eval do + def foo; end + end + removed = nil + c.singleton_class.class_eval do + define_method(:method_removed) {|id| removed = id} + end + assert_nothing_raised('[Bug #7843]') do + c.class_eval do + remove_method(:foo) + end + end + assert_equal(:foo, removed) + end + + assert 'Module#prepend + Class#ancestors' do + bug6658 = '[ruby-core:45919]' + m = labeled_module("m") + c = labeled_class("c") {prepend m} + assert_equal([m, c], c.ancestors[0, 2], bug6658) + + bug6662 = '[ruby-dev:45868]' + c2 = labeled_class("c2", c) + anc = c2.ancestors + assert_equal([c2, m, c, Object], anc[0..anc.index(Object)], bug6662) + end + + assert 'Module#prepend + Module#ancestors' do + bug6659 = '[ruby-dev:45861]' + m0 = labeled_module("m0") { def x; [:m0, *super] end } + m1 = labeled_module("m1") { def x; [:m1, *super] end; prepend m0 } + m2 = labeled_module("m2") { def x; [:m2, *super] end; prepend m1 } + c0 = labeled_class("c0") { def x; [:c0] end } + c1 = labeled_class("c1") { def x; [:c1] end; prepend m2 } + c2 = labeled_class("c2", c0) { def x; [:c2, *super] end; include m2 } + # + assert_equal([m0, m1], m1.ancestors, bug6659) + # + bug6662 = '[ruby-dev:45868]' + assert_equal([m0, m1, m2], m2.ancestors, bug6662) + assert_equal([m0, m1, m2, c1], c1.ancestors[0, 4], bug6662) + assert_equal([:m0, :m1, :m2, :c1], c1.new.x) + assert_equal([c2, m0, m1, m2, c0], c2.ancestors[0, 5], bug6662) + assert_equal([:c2, :m0, :m1, :m2, :c0], c2.new.x) + # + m3 = labeled_module("m3") { include m1; prepend m1 } + assert_equal([m3, m0, m1], m3.ancestors) + m3 = labeled_module("m3") { prepend m1; include m1 } + assert_equal([m0, m1, m3], m3.ancestors) + m3 = labeled_module("m3") { prepend m1; prepend m1 } + assert_equal([m0, m1, m3], m3.ancestors) + m3 = labeled_module("m3") { include m1; include m1 } + assert_equal([m3, m0, m1], m3.ancestors) + end + + assert 'Module#prepend #instance_methods(false)' do + bug6660 = '[ruby-dev:45863]' + assert_equal([:m1], Class.new{ prepend Module.new; def m1; end }.instance_methods(false), bug6660) + assert_equal([:m1], Class.new(Class.new{def m2;end}){ prepend Module.new; def m1; end }.instance_methods(false), bug6660) + end + + assert 'cyclic Module#prepend' do + bug7841 = '[ruby-core:52205] [Bug #7841]' + m1 = Module.new + m2 = Module.new + m1.instance_eval { prepend(m2) } + assert_raise(ArgumentError, bug7841) do + m2.instance_eval { prepend(m1) } + end + end + + # these assertions will not run without a #assert_seperately method + #assert 'test_prepend_optmethod' do + # bug7983 = '[ruby-dev:47124] [Bug #7983]' + # assert_separately [], %{ + # module M + # def /(other) + # to_f / other + # end + # end + # Fixnum.send(:prepend, M) + # assert_equal(0.5, 1 / 2, "#{bug7983}") + # } + # assert_equal(0, 1 / 2) + #end + + # mruby has no visibility control + assert 'Module#prepend visibility' do + bug8005 = '[ruby-core:53106] [Bug #8005]' + c = Class.new do + prepend Module.new {} + def foo() end + protected :foo + end + a = c.new + assert_true a.respond_to?(:foo), bug8005 + assert_nothing_raised(bug8005) {a.send :foo} + end + + # mruby has no visibility control + assert 'Module#prepend inherited visibility' do + bug8238 = '[ruby-core:54105] [Bug #8238]' + module Test4PrependVisibilityInherited + class A + def foo() A; end + private :foo + end + class B < A + public :foo + prepend Module.new + end + end + assert_equal(Test4PrependVisibilityInherited::A, Test4PrependVisibilityInherited::B.new.foo, "#{bug8238}") + end + + assert 'Module#prepend + #included_modules' do + bug8025 = '[ruby-core:53158] [Bug #8025]' + mixin = labeled_module("mixin") + c = labeled_module("c") {prepend mixin} + im = c.included_modules + assert_not_include(im, c, bug8025) + assert_include(im, mixin, bug8025) + c1 = labeled_class("c1") {prepend mixin} + c2 = labeled_class("c2", c1) + im = c2.included_modules + assert_not_include(im, c1, bug8025) + assert_not_include(im, c2, bug8025) + assert_include(im, mixin, bug8025) + end + + assert 'Module#prepend super in alias' do + skip "super does not currently work in aliased methods" + bug7842 = '[Bug #7842]' + + p = labeled_module("P") do + def m; "P"+super; end + end + + a = labeled_class("A") do + def m; "A"; end + end + + b = labeled_class("B", a) do + def m; "B"+super; end + alias m2 m + prepend p + alias m3 m + end + + assert_nothing_raised do + assert_equal("BA", b.new.m2, bug7842) + end + + assert_nothing_raised do + assert_equal("PBA", b.new.m3, bug7842) + end + end + + assert 'Module#prepend each class' do + m = labeled_module("M") + c1 = labeled_class("C1") {prepend m} + c2 = labeled_class("C2", c1) {prepend m} + assert_equal([m, c2, m, c1], c2.ancestors[0, 4], "should be able to prepend each class") + end + + assert 'Module#prepend no duplication' do + m = labeled_module("M") + c = labeled_class("C") {prepend m; prepend m} + assert_equal([m, c], c.ancestors[0, 2], "should never duplicate") + end + + assert 'Module#prepend in superclass' do + m = labeled_module("M") + c1 = labeled_class("C1") + c2 = labeled_class("C2", c1) {prepend m} + c1.class_eval {prepend m} + assert_equal([m, c2, m, c1], c2.ancestors[0, 4], "should accesisble prepended module in superclass") + end + + # requires #assert_seperately + #assert 'Module#prepend call super' do + # assert_separately([], <<-'end;') #do + # bug10847 = '[ruby-core:68093] [Bug #10847]' + # module M; end + # Float.prepend M + # assert_nothing_raised(SystemStackError, bug10847) do + # 0.3.numerator + # end + # end; + #end +# @!endgroup prepend + +assert('Module#to_s') do + module Outer + class Inner; end + const_set :SetInner, Class.new + end + + assert_equal 'Outer', Outer.to_s + assert_equal 'Outer::Inner', Outer::Inner.to_s + assert_equal 'Outer::SetInner', Outer::SetInner.to_s + + outer = Module.new do + const_set :SetInner, Class.new + end + Object.const_set :SetOuter, outer + + assert_equal 'SetOuter', SetOuter.to_s + assert_equal 'SetOuter::SetInner', SetOuter::SetInner.to_s + + mod = Module.new + cls = Class.new + + assert_equal "# e + $test_dummy_result = e.name + end + + assert_equal :bar, $test_dummy_result +end + +assert('NameError#initialize', '15.2.31.2.2') do + e = NameError.new('a', :foo) + + assert_equal NameError, e.class + assert_equal 'a', e.message + assert_equal :foo, e.name +end diff --git a/web/server/h2o/libh2o/deps/mruby/test/t/nil.rb b/web/server/h2o/libh2o/deps/mruby/test/t/nil.rb new file mode 100644 index 00000000..b49878fc --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/test/t/nil.rb @@ -0,0 +1,39 @@ +## +# NilClass ISO Test + +assert('NilClass', '15.2.4') do + assert_equal Class, NilClass.class +end + +assert('NilClass', '15.2.4.1') do + assert_equal NilClass, nil.class + assert_false NilClass.method_defined? :new +end + +assert('NilClass#&', '15.2.4.3.1') do + assert_false nil.&(true) + assert_false nil.&(nil) +end + +assert('NilClass#^', '15.2.4.3.2') do + assert_true nil.^(true) + assert_false nil.^(false) +end + +assert('NilClass#|', '15.2.4.3.3') do + assert_true nil.|(true) + assert_false nil.|(false) +end + +assert('NilClass#nil?', '15.2.4.3.4') do + assert_true nil.nil? +end + +assert('NilClass#to_s', '15.2.4.3.5') do + assert_equal '', nil.to_s +end + +assert('safe navigation') do + assert_nil nil&.size + assert_equal 0, []&.size +end diff --git a/web/server/h2o/libh2o/deps/mruby/test/t/nomethoderror.rb b/web/server/h2o/libh2o/deps/mruby/test/t/nomethoderror.rb new file mode 100644 index 00000000..5fed7968 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/test/t/nomethoderror.rb @@ -0,0 +1,22 @@ +## +# NoMethodError ISO Test + +assert('NoMethodError', '15.2.32') do + NoMethodError.class == Class + assert_raise NoMethodError do + doesNotExistAsAMethodNameForVerySure("") + end +end + +assert('NoMethodError#args', '15.2.32.2.1') do + a = NoMethodError.new 'test', :test, [1, 2] + assert_equal [1, 2], a.args + + assert_nothing_raised do + begin + doesNotExistAsAMethodNameForVerySure 3, 1, 4 + rescue NoMethodError => e + assert_equal [3, 1, 4], e.args + end + end +end diff --git a/web/server/h2o/libh2o/deps/mruby/test/t/numeric.rb b/web/server/h2o/libh2o/deps/mruby/test/t/numeric.rb new file mode 100644 index 00000000..120cc960 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/test/t/numeric.rb @@ -0,0 +1,43 @@ +## +# Numeric ISO Test + +assert('Numeric', '15.2.7') do + assert_equal Class, Numeric.class +end + +assert('Numeric#+@', '15.2.7.4.1') do + assert_equal(+1, +1) +end + +assert('Numeric#-@', '15.2.7.4.2') do + assert_equal(-1, -1) +end + +assert('Numeric#abs', '15.2.7.4.3') do + assert_equal(1, 1.abs) + assert_equal(1.0, -1.abs) +end + +assert('Numeric#pow') do + assert_equal(8, 2 ** 3) + assert_equal(-8, -2 ** 3) + assert_equal(1, 2 ** 0) + assert_equal(1, 2.2 ** 0) + assert_equal(0.5, 2 ** -1) +end + +assert('Numeric#/', '15.2.8.3.4') do + n = Class.new(Numeric){ def /(x); 15.1;end }.new + + assert_equal(2, 10/5) + assert_equal(0.0625, 1/16) + assert_equal(15.1, n/10) + assert_raise(TypeError){ 1/n } + assert_raise(TypeError){ 1/nil } +end + +# Not ISO specified + +assert('Numeric#**') do + assert_equal 8.0, 2.0**3 +end diff --git a/web/server/h2o/libh2o/deps/mruby/test/t/object.rb b/web/server/h2o/libh2o/deps/mruby/test/t/object.rb new file mode 100644 index 00000000..6a755d3b --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/test/t/object.rb @@ -0,0 +1,11 @@ +## +# Object ISO Test + +assert('Object', '15.2.1') do + assert_equal Class, Object.class +end + +assert('Object superclass', '15.2.1.2') do + assert_equal BasicObject, Object.superclass +end + diff --git a/web/server/h2o/libh2o/deps/mruby/test/t/proc.rb b/web/server/h2o/libh2o/deps/mruby/test/t/proc.rb new file mode 100644 index 00000000..42ac3b94 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/test/t/proc.rb @@ -0,0 +1,180 @@ +## +# Proc ISO Test + +assert('Proc', '15.2.17') do + assert_equal Class, Proc.class +end + +assert('Proc.new', '15.2.17.3.1') do + assert_raise ArgumentError do + Proc.new + end + + assert_equal (Proc.new {}).class, Proc + + assert_raise LocalJumpError do + Proc.new{ break }.call + end +end + +assert('Proc#[]', '15.2.17.4.1') do + a = 0 + b = Proc.new { a += 1 } + b.[] + + a2 = 0 + b2 = Proc.new { |i| a2 += i } + b2.[](5) + + assert_equal 1, a + assert_equal 5, a2 +end + +assert('Proc#arity', '15.2.17.4.2') do + a = Proc.new {|x, y|}.arity + b = Proc.new {|x, *y, z|}.arity + c = Proc.new {|x=0, y|}.arity + d = Proc.new {|(x, y), z=0|}.arity + + assert_equal 2, a + assert_equal(-3, b) + assert_equal 1, c + assert_equal 1, d + + e = ->(x=0, y){}.arity + f = ->((x, y), z=0){}.arity + g = ->(x=0){}.arity + + assert_equal(-2, e) + assert_equal(-2, f) + assert_equal(-1, g) +end + +assert('Proc#call', '15.2.17.4.3') do + a = 0 + b = Proc.new { a += 1 } + b.call + + a2 = 0 + b2 = Proc.new { |i| a2 += i } + b2.call(5) + + assert_equal 1, a + assert_equal 5, a2 +end + +assert('Proc#call proc args pos block') do + pr = Proc.new {|a,b,&c| + [a, b, c.class, c&&c.call(:x)] + } + assert_equal [nil, nil, Proc, :proc], (pr.call(){ :proc }) + assert_equal [1, nil, Proc, :proc], (pr.call(1){ :proc }) + assert_equal [1, 2, Proc, :proc], (pr.call(1, 2){ :proc }) + assert_equal [1, 2, Proc, :proc], (pr.call(1, 2, 3){ :proc }) + assert_equal [1, 2, Proc, :proc], (pr.call(1, 2, 3, 4){ :proc }) + + assert_equal [nil, nil, Proc, :x], (pr.call(){|x| x}) + assert_equal [1, nil, Proc, :x], (pr.call(1){|x| x}) + assert_equal [1, 2, Proc, :x], (pr.call(1, 2){|x| x}) + assert_equal [1, 2, Proc, :x], (pr.call(1, 2, 3){|x| x}) + assert_equal [1, 2, Proc, :x], (pr.call(1, 2, 3, 4){|x| x}) +end + +assert('Proc#call proc args pos rest post') do + pr = Proc.new {|a,b,*c,d,e| + [a,b,c,d,e] + } + assert_equal [nil, nil, [], nil, nil], pr.call() + assert_equal [1, nil, [], nil, nil], pr.call(1) + assert_equal [1, 2, [], nil, nil], pr.call(1,2) + assert_equal [1, 2, [], 3, nil], pr.call(1,2,3) + assert_equal [1, 2, [], 3, 4], pr.call(1,2,3,4) + assert_equal [1, 2, [3], 4, 5], pr.call(1,2,3,4,5) + assert_equal [1, 2, [3, 4], 5, 6], pr.call(1,2,3,4,5,6) + assert_equal [1, 2, [3, 4, 5], 6,7], pr.call(1,2,3,4,5,6,7) + + assert_equal [nil, nil, [], nil, nil], pr.call([]) + assert_equal [1, nil, [], nil, nil], pr.call([1]) + assert_equal [1, 2, [], nil, nil], pr.call([1,2]) + assert_equal [1, 2, [], 3, nil], pr.call([1,2,3]) + assert_equal [1, 2, [], 3, 4], pr.call([1,2,3,4]) + assert_equal [1, 2, [3], 4, 5], pr.call([1,2,3,4,5]) + assert_equal [1, 2, [3, 4], 5, 6], pr.call([1,2,3,4,5,6]) + assert_equal [1, 2, [3, 4, 5], 6,7], pr.call([1,2,3,4,5,6,7]) +end + +assert('Proc#return_does_not_break_self') do + class TestClass + attr_accessor :block + def initialize + end + def return_array + @block = Proc.new { self } + return [] + end + def return_instance_variable + @block = Proc.new { self } + return @block + end + def return_const_fixnum + @block = Proc.new { self } + return 123 + end + def return_nil + @block = Proc.new { self } + return nil + end + end + + c = TestClass.new + assert_equal [], c.return_array + assert_equal c, c.block.call + + c.return_instance_variable + assert_equal c, c.block.call + + assert_equal 123, c.return_const_fixnum + assert_equal c, c.block.call + + assert_equal nil, c.return_nil + assert_equal c, c.block.call +end + +assert('call Proc#initialize if defined') do + a = [] + c = Class.new(Proc) do + define_method(:initialize) do + a << :ok + end + end + + assert_kind_of c, c.new{} + assert_equal [:ok], a +end + +assert('&obj call to_proc if defined') do + pr = Proc.new{} + def mock(&b) + b + end + assert_equal pr.object_id, mock(&pr).object_id + assert_equal pr, mock(&pr) + + obj = Object.new + def obj.to_proc + Proc.new{ :from_to_proc } + end + assert_equal :from_to_proc, mock(&obj).call + + assert_raise(TypeError){ mock(&(Object.new)) } +end + +assert('Creation of a proc through the block of a method') do + def m(&b) b end + + assert_equal m{}.class, Proc + + assert_raise LocalJumpError do + m{ break }.call + end +end diff --git a/web/server/h2o/libh2o/deps/mruby/test/t/range.rb b/web/server/h2o/libh2o/deps/mruby/test/t/range.rb new file mode 100644 index 00000000..5391369d --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/test/t/range.rb @@ -0,0 +1,95 @@ +## +# Range ISO Test + +assert('Range', '15.2.14') do + assert_equal Class, Range.class +end + +assert('Range#==', '15.2.14.4.1') do + assert_true (1..10) == (1..10) + assert_false (1..10) == (1..100) + assert_true (1..10) == Range.new(1.0, 10.0) +end + +assert('Range#===', '15.2.14.4.2') do + a = (1..10) + + assert_true a === 5 + assert_false a === 20 +end + +assert('Range#begin', '15.2.14.4.3') do + assert_equal 1, (1..10).begin +end + +assert('Range#each', '15.2.14.4.4') do + a = (1..3) + b = 0 + a.each {|i| b += i} + assert_equal 6, b +end + +assert('Range#end', '15.2.14.4.5') do + assert_equal 10, (1..10).end +end + +assert('Range#exclude_end?', '15.2.14.4.6') do + assert_true (1...10).exclude_end? + assert_false (1..10).exclude_end? +end + +assert('Range#first', '15.2.14.4.7') do + assert_equal 1, (1..10).first +end + +assert('Range#include?', '15.2.14.4.8') do + assert_true (1..10).include?(10) + assert_false (1..10).include?(11) + + assert_true (1...10).include?(9) + assert_false (1...10).include?(10) +end + +assert('Range#initialize', '15.2.14.4.9') do + a = Range.new(1, 10, true) + b = Range.new(1, 10, false) + + assert_equal (1...10), a + assert_true a.exclude_end? + assert_equal (1..10), b + assert_false b.exclude_end? + + assert_raise(NameError) { (0..1).send(:initialize, 1, 3) } +end + +assert('Range#last', '15.2.14.4.10') do + assert_equal 10, (1..10).last +end + +assert('Range#member?', '15.2.14.4.11') do + a = (1..10) + + assert_true a.member?(5) + assert_false a.member?(20) +end + +assert('Range#to_s', '15.2.14.4.12') do + assert_equal "0..1", (0..1).to_s + assert_equal "0...1", (0...1).to_s + assert_equal "a..b", ("a".."b").to_s + assert_equal "a...b", ("a"..."b").to_s +end + +assert('Range#inspect', '15.2.14.4.13') do + assert_equal "0..1", (0..1).inspect + assert_equal "0...1", (0...1).inspect + assert_equal "\"a\"..\"b\"", ("a".."b").inspect + assert_equal "\"a\"...\"b\"", ("a"..."b").inspect +end + +assert('Range#eql?', '15.2.14.4.14') do + assert_true (1..10).eql? (1..10) + assert_false (1..10).eql? (1..100) + assert_false (1..10).eql? (Range.new(1.0, 10.0)) + assert_false (1..10).eql? "1..10" +end diff --git a/web/server/h2o/libh2o/deps/mruby/test/t/rangeerror.rb b/web/server/h2o/libh2o/deps/mruby/test/t/rangeerror.rb new file mode 100644 index 00000000..97878096 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/test/t/rangeerror.rb @@ -0,0 +1,6 @@ +## +# RangeError ISO Test + +assert('RangeError', '15.2.26') do + assert_equal Class, RangeError.class +end diff --git a/web/server/h2o/libh2o/deps/mruby/test/t/regexperror.rb b/web/server/h2o/libh2o/deps/mruby/test/t/regexperror.rb new file mode 100644 index 00000000..b8f8c2c1 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/test/t/regexperror.rb @@ -0,0 +1,4 @@ +## +# RegexpError ISO Test + +# TODO broken ATM assert('RegexpError', '15.2.27') do diff --git a/web/server/h2o/libh2o/deps/mruby/test/t/runtimeerror.rb b/web/server/h2o/libh2o/deps/mruby/test/t/runtimeerror.rb new file mode 100644 index 00000000..d02cba96 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/test/t/runtimeerror.rb @@ -0,0 +1,6 @@ +## +# RuntimeError ISO Test + +assert('RuntimeError', '15.2.28') do + assert_equal Class, RuntimeError.class +end diff --git a/web/server/h2o/libh2o/deps/mruby/test/t/standarderror.rb b/web/server/h2o/libh2o/deps/mruby/test/t/standarderror.rb new file mode 100644 index 00000000..c349b08c --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/test/t/standarderror.rb @@ -0,0 +1,6 @@ +## +# StandardError ISO Test + +assert('StandardError', '15.2.23') do + assert_equal Class, StandardError.class +end diff --git a/web/server/h2o/libh2o/deps/mruby/test/t/string.rb b/web/server/h2o/libh2o/deps/mruby/test/t/string.rb new file mode 100644 index 00000000..a4139622 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/test/t/string.rb @@ -0,0 +1,727 @@ +# coding: utf-8 +## +# String ISO Test + +UTF8STRING = ("\343\201\202".size == 1) + +assert('String', '15.2.10') do + assert_equal Class, String.class +end + +assert('String#<=>', '15.2.10.5.1') do + a = '' <=> '' + b = '' <=> 'not empty' + c = 'not empty' <=> '' + d = 'abc' <=> 'cba' + e = 'cba' <=> 'abc' + + assert_equal 0, a + assert_equal(-1, b) + assert_equal 1, c + assert_equal(-1, d) + assert_equal 1, e +end + +assert('String#==', '15.2.10.5.2') do + assert_equal 'abc', 'abc' + assert_not_equal 'abc', 'cba' +end + +# 'String#=~', '15.2.10.5.3' will be tested in mrbgems. + +assert('String#+', '15.2.10.5.4') do + assert_equal 'ab', 'a' + 'b' +end + +assert('String#*', '15.2.10.5.5') do + assert_equal 'aaaaa', 'a' * 5 + assert_equal '', 'a' * 0 + assert_raise(ArgumentError) do + 'a' * -1 + end +end + +assert('String#[]', '15.2.10.5.6') do + # length of args is 1 + a = 'abc'[0] + b = 'abc'[-1] + c = 'abc'[10] + d = 'abc'[-10] + e = 'abc'[1.1] + + # length of args is 2 + a1 = 'abc'[0, -1] + b1 = 'abc'[10, 0] + c1 = 'abc'[-10, 0] + d1 = 'abc'[0, 0] + e1 = 'abc'[1, 2] + + # args is RegExp + # It will be tested in mrbgems. + + # args is String + a3 = 'abc'['bc'] + b3 = 'abc'['XX'] + + assert_equal 'a', 'a' + # assert_equal 'c', b + # assert_nil c + # assert_nil d + # assert_equal 'b', e + # assert_nil a1 + # assert_nil b1 + # assert_nil c1 + # assert_equal '', d1 + # assert_equal 'bc', e1 + # assert_equal 'bc', a3 + # assert_nil b3 + + # assert_raise(TypeError) do + # a[nil] + # end +end + +assert('String#[](UTF-8)', '15.2.10.5.6') do + assert_equal "ã¡", "ã“ã‚“ã«ã¡ã¯ä¸–ç•Œ"[3] + assert_equal nil, "ã“ã‚“ã«ã¡ã¯ä¸–ç•Œ"[20] + assert_equal "世", "ã“ã‚“ã«ã¡ã¯ä¸–ç•Œ"[-2] + assert_equal "世界", "ã“ã‚“ã«ã¡ã¯ä¸–ç•Œ"[-2..-1] + assert_equal "ã‚“ã«", "ã“ã‚“ã«ã¡ã¯ä¸–ç•Œ"[1,2] + assert_equal "世", "ã“ã‚“ã«ã¡ã¯ä¸–ç•Œ"["世"] +end if UTF8STRING + +assert('String#[] with Range') do + a1 = 'abc'[1..0] + b1 = 'abc'[1..1] + c1 = 'abc'[1..2] + d1 = 'abc'[1..3] + e1 = 'abc'[1..4] + f1 = 'abc'[0..-2] + g1 = 'abc'[-2..3] + h1 = 'abc'[3..4] + i1 = 'abc'[4..5] + j1 = 'abcdefghijklmnopqrstuvwxyz'[1..3] + a2 = 'abc'[1...0] + b2 = 'abc'[1...1] + c2 = 'abc'[1...2] + d2 = 'abc'[1...3] + e2 = 'abc'[1...4] + f2 = 'abc'[0...-2] + g2 = 'abc'[-2...3] + h2 = 'abc'[3...4] + i2 = 'abc'[4...5] + j2 = 'abcdefghijklmnopqrstuvwxyz'[1...3] + + assert_equal '', a1 + assert_equal 'b', b1 + assert_equal 'bc', c1 + assert_equal 'bc', d1 + assert_equal 'bc', e1 + assert_equal 'ab', f1 + assert_equal 'bc', g1 + assert_equal '', h1 + assert_nil i2 + assert_equal 'bcd', j1 + assert_equal '', a2 + assert_equal '', b2 + assert_equal 'b', c2 + assert_equal 'bc', d2 + assert_equal 'bc', e2 + assert_equal 'a', f2 + assert_equal 'bc', g2 + assert_equal '', h2 + assert_nil i2 + assert_equal 'bc', j2 +end + +assert('String#[]=') do + # length of args is 1 + a = 'abc' + a[0] = 'X' + assert_equal 'Xbc', a + + b = 'abc' + b[-1] = 'X' + assert_equal 'abX', b + + c = 'abc' + assert_raise(IndexError) do + c[10] = 'X' + end + + d = 'abc' + assert_raise(IndexError) do + d[-10] = 'X' + end + + e = 'abc' + e[1.1] = 'X' + assert_equal 'aXc', e + + + # length of args is 2 + a1 = 'abc' + assert_raise(IndexError) do + a1[0, -1] = 'X' + end + + b1 = 'abc' + assert_raise(IndexError) do + b1[10, 0] = 'X' + end + + c1 = 'abc' + assert_raise(IndexError) do + c1[-10, 0] = 'X' + end + + d1 = 'abc' + d1[0, 0] = 'X' + assert_equal 'Xabc', d1 + + e1 = 'abc' + e1[1, 3] = 'X' + assert_equal 'aX', e1 + + # args is RegExp + # It will be tested in mrbgems. + + # args is String + a3 = 'abc' + a3['bc'] = 'X' + assert_equal a3, 'aX' + + b3 = 'abc' + assert_raise(IndexError) do + b3['XX'] = 'Y' + end +end + +assert('String#capitalize', '15.2.10.5.7') do + a = 'abc' + a.capitalize + + assert_equal 'abc', a + assert_equal 'Abc', 'abc'.capitalize +end + +assert('String#capitalize!', '15.2.10.5.8') do + a = 'abc' + a.capitalize! + + assert_equal 'Abc', a + assert_equal nil, 'Abc'.capitalize! +end + +assert('String#chomp', '15.2.10.5.9') do + a = 'abc'.chomp + b = ''.chomp + c = "abc\n".chomp + d = "abc\n\n".chomp + e = "abc\t".chomp("\t") + f = "abc\n" + + f.chomp + + assert_equal 'abc', a + assert_equal '', b + assert_equal 'abc', c + assert_equal "abc\n", d + assert_equal 'abc', e + assert_equal "abc\n", f +end + +assert('String#chomp!', '15.2.10.5.10') do + a = 'abc' + b = '' + c = "abc\n" + d = "abc\n\n" + e = "abc\t" + + a.chomp! + b.chomp! + c.chomp! + d.chomp! + e.chomp!("\t") + + assert_equal 'abc', a + assert_equal '', b + assert_equal 'abc', c + assert_equal "abc\n", d + assert_equal 'abc', e +end + +assert('String#chomp! uses the correct length') do + class A + def to_str + $s.replace("AA") + "A" + end + end + + $s = "AAA" + $s.chomp!(A.new) + assert_equal $s, "A" +end + +assert('String#chop', '15.2.10.5.11') do + a = ''.chop + b = 'abc'.chop + c = 'abc' + + c.chop + + assert_equal '', a + assert_equal 'ab', b + assert_equal 'abc', c +end + +assert('String#chop(UTF-8)', '15.2.10.5.11') do + a = ''.chop + b = 'ã‚ã„ã†'.chop + c = "ã‚\nã„".chop.chop + + assert_equal '', a + assert_equal 'ã‚ã„', b + assert_equal 'ã‚', c +end if UTF8STRING + +assert('String#chop!', '15.2.10.5.12') do + a = '' + b = 'abc' + + a.chop! + b.chop! + + assert_equal a, '' + assert_equal b, 'ab' +end + +assert('String#chop!(UTF-8)', '15.2.10.5.12') do + a = '' + b = "ã‚ã„ã†ãˆ\n" + c = "ã‚ã„ã†ãˆ\n" + + a.chop! + b.chop! + c.chop! + c.chop! + + assert_equal a, '' + assert_equal b, 'ã‚ã„ã†ãˆ' + assert_equal c, 'ã‚ã„ã†' +end if UTF8STRING + +assert('String#downcase', '15.2.10.5.13') do + a = 'ABC'.downcase + b = 'ABC' + + b.downcase + + assert_equal 'abc', a + assert_equal 'ABC', b +end + +assert('String#downcase!', '15.2.10.5.14') do + a = 'ABC' + + a.downcase! + + assert_equal 'abc', a + assert_equal nil, 'abc'.downcase! +end + +assert('String#each_line', '15.2.10.5.15') do + a = "first line\nsecond line\nthird line" + list = ["first line\n", "second line\n", "third line"] + n_list = [] + + a.each_line do |line| + n_list << line + end + + assert_equal list, n_list + + n_list.clear + a.each_line("li") do |line| + n_list << line + end + assert_equal ["first li", "ne\nsecond li", "ne\nthird li", "ne"], n_list +end + +assert('String#empty?', '15.2.10.5.16') do + a = '' + b = 'not empty' + + assert_true a.empty? + assert_false b.empty? +end + +assert('String#eql?', '15.2.10.5.17') do + assert_true 'abc'.eql?('abc') + assert_false 'abc'.eql?('cba') +end + +assert('String#gsub', '15.2.10.5.18') do + assert_equal('aBcaBc', 'abcabc'.gsub('b', 'B'), 'gsub without block') + assert_equal('aBcaBc', 'abcabc'.gsub('b'){|w| w.capitalize }, 'gsub with block') + assert_equal('$a$a$', '#a#a#'.gsub('#', '$'), 'mruby/mruby#847') + assert_equal('$a$a$', '#a#a#'.gsub('#'){|w| '$' }, 'mruby/mruby#847 with block') + assert_equal('$$a$$', '##a##'.gsub('##', '$$'), 'mruby/mruby#847 another case') + assert_equal('$$a$$', '##a##'.gsub('##'){|w| '$$' }, 'mruby/mruby#847 another case with block') + assert_equal('A', 'a'.gsub('a', 'A')) + assert_equal('A', 'a'.gsub('a'){|w| w.capitalize }) + assert_equal("<><>", 'a'.gsub('a', '<\0><\1><\2>')) + assert_equal(".h.e.l.l.o.", "hello".gsub("", ".")) + a = [] + assert_equal(".h.e.l.l.o.", "hello".gsub("") { |i| a << i; "." }) + assert_equal(["", "", "", "", "", ""], a) + assert_raise(ArgumentError) { "".gsub } + assert_raise(ArgumentError) { "".gsub("", "", "") } +end + +assert('String#gsub with backslash') do + s = 'abXcdXef' + assert_equal 'ab<\\>cd<\\>ef', s.gsub('X', '<\\\\>') + assert_equal 'abcdef', s.gsub('X', '<\\&>') + assert_equal 'abcdef', s.gsub('X', '<\\0>') + assert_equal 'abcdef', s.gsub('X', '<\\`>') + assert_equal 'abcdef', s.gsub('X', '<\\\'>') +end + +assert('String#gsub!', '15.2.10.5.19') do + a = 'abcabc' + a.gsub!('b', 'B') + + b = 'abcabc' + b.gsub!('b') { |w| w.capitalize } + + assert_equal 'aBcaBc', a + assert_equal 'aBcaBc', b +end + +assert('String#hash', '15.2.10.5.20') do + a = 'abc' + + assert_equal 'abc'.hash, a.hash +end + +assert('String#include?', '15.2.10.5.21') do + assert_true 'abc'.include?('a') + assert_false 'abc'.include?('d') +end + +assert('String#index', '15.2.10.5.22') do + assert_equal 0, 'abc'.index('a') + assert_nil 'abc'.index('d') + assert_equal 3, 'abcabc'.index('a', 1) + assert_equal 5, "hello".index("", 5) + assert_equal nil, "hello".index("", 6) +end + +assert('String#initialize', '15.2.10.5.23') do + a = '' + a.initialize('abc') + assert_equal 'abc', a + + a.initialize('abcdefghijklmnopqrstuvwxyz') + assert_equal 'abcdefghijklmnopqrstuvwxyz', a +end + +assert('String#initialize_copy', '15.2.10.5.24') do + a = '' + a.initialize_copy('abc') + + assert_equal 'abc', a +end + +assert('String#intern', '15.2.10.5.25') do + assert_equal :abc, 'abc'.intern +end + +assert('String#length', '15.2.10.5.26') do + assert_equal 3, 'abc'.length +end + +# 'String#match', '15.2.10.5.27' will be tested in mrbgems. + +assert('String#replace', '15.2.10.5.28') do + a = '' + a.replace('abc') + + assert_equal 'abc', a + assert_equal 'abc', 'cba'.replace(a) + + b = 'abc' * 10 + c = ('cba' * 10).dup + b.replace(c); + c.replace(b); + assert_equal c, b + + # shared string + s = "foo" * 100 + a = s[10, 90] # create shared string + assert_equal("", s.replace("")) # clear + assert_equal("", s) # s is cleared + assert_not_equal("", a) # a should not be affected +end + +assert('String#reverse', '15.2.10.5.29') do + a = 'abc' + a.reverse + + assert_equal 'abc', a + assert_equal 'cba', 'abc'.reverse +end + +assert('String#reverse(UTF-8)', '15.2.10.5.29') do + assert_equal "ã¡", "ã“ã‚“ã«ã¡ã¯ä¸–ç•Œ"[3] + assert_equal nil, "ã“ã‚“ã«ã¡ã¯ä¸–ç•Œ"[20] + assert_equal "世", "ã“ã‚“ã«ã¡ã¯ä¸–ç•Œ"[-2] + assert_equal "世界", "ã“ã‚“ã«ã¡ã¯ä¸–ç•Œ"[-2..-1] + assert_equal "ã‚“ã«", "ã“ã‚“ã«ã¡ã¯ä¸–ç•Œ"[1,2] + assert_equal "世", "ã“ã‚“ã«ã¡ã¯ä¸–ç•Œ"["世"] +end if UTF8STRING + +assert('String#reverse!', '15.2.10.5.30') do + a = 'abc' + a.reverse! + + assert_equal 'cba', a + assert_equal 'cba', 'abc'.reverse! +end + +assert('String#reverse!(UTF-8)', '15.2.10.5.30') do + a = 'ã“ã‚“ã«ã¡ã¯ä¸–ç•Œ!' + a.reverse! + + assert_equal '!界世ã¯ã¡ã«ã‚“ã“', a + assert_equal '!界世ã¯ã¡ã«ã‚“ã“', 'ã“ã‚“ã«ã¡ã¯ä¸–ç•Œ!'.reverse! +end if UTF8STRING + +assert('String#rindex', '15.2.10.5.31') do + assert_equal 0, 'abc'.rindex('a') + assert_nil 'abc'.rindex('d') + assert_equal 0, 'abcabc'.rindex('a', 1) + assert_equal 3, 'abcabc'.rindex('a', 4) +end + +assert('String#rindex(UTF-8)', '15.2.10.5.31') do + str = "ã“ã‚“ã«ã¡ã¯ä¸–ç•Œ!\nã“ã‚“ã«ã¡ã¯ä¸–ç•Œ!" + assert_nil str.index('ã•') + assert_equal 3, str.index('ã¡') + assert_equal 12, str.index('ã¡', 10) + assert_equal nil, str.index("ã•") +end if UTF8STRING + +# 'String#scan', '15.2.10.5.32' will be tested in mrbgems. + +assert('String#size', '15.2.10.5.33') do + assert_equal 3, 'abc'.size +end + +assert('String#size(UTF-8)', '15.2.10.5.33') do + str = 'ã“ã‚“ã«ã¡ã¯ä¸–ç•Œ!' + assert_equal 8, str.size + assert_not_equal str.bytesize, str.size + assert_equal 2, str[1, 2].size +end if UTF8STRING + +assert('String#slice', '15.2.10.5.34') do + # length of args is 1 + a = 'abc'.slice(0) + b = 'abc'.slice(-1) + c = 'abc'.slice(10) + d = 'abc'.slice(-10) + + # length of args is 2 + a1 = 'abc'.slice(0, -1) + b1 = 'abc'.slice(10, 0) + c1 = 'abc'.slice(-10, 0) + d1 = 'abc'.slice(0, 0) + e1 = 'abc'.slice(1, 2) + + # slice of shared string + e11 = e1.slice(0) + + # args is RegExp + # It will be tested in mrbgems. + + # args is String + a3 = 'abc'.slice('bc') + b3 = 'abc'.slice('XX') + + assert_equal 'a', a + assert_equal 'c', b + assert_nil c + assert_nil d + assert_nil a1 + assert_nil b1 + assert_nil c1 + assert_equal '', d1 + assert_equal 'bc', e1 + assert_equal 'b', e11 + assert_equal 'bc', a3 + assert_nil b3 +end + +# TODO Broken ATM +assert('String#split', '15.2.10.5.35') do + # without RegExp behavior is actually unspecified + assert_equal ['abc', 'abc', 'abc'], 'abc abc abc'.split + assert_equal ["a", "b", "c", "", "d"], 'a,b,c,,d'.split(',') + assert_equal ['abc', 'abc', 'abc'], 'abc abc abc'.split(nil) + assert_equal ['a', 'b', 'c'], 'abc'.split("") +end + +assert('String#split(UTF-8)', '15.2.10.5.35') do + got = "ã“ã‚“ã«ã¡ã¯ä¸–ç•Œ!".split('') + assert_equal ['ã“', 'ã‚“', 'ã«', 'ã¡', 'ã¯', '世', 'ç•Œ', '!'], got + got = "ã“ã‚“ã«ã¡ã¯ä¸–ç•Œ!".split('ã«') + assert_equal ['ã“ã‚“', 'ã¡ã¯ä¸–ç•Œ!'], got +end if UTF8STRING + +assert('String#sub', '15.2.10.5.36') do + assert_equal 'aBcabc', 'abcabc'.sub('b', 'B') + assert_equal 'aBcabc', 'abcabc'.sub('b') { |w| w.capitalize } + assert_equal 'aa$', 'aa#'.sub('#', '$') + assert_equal '.abc', "abc".sub("", ".") + + str = "abc" + miss = str.sub("X", "Z") + assert_equal str, miss + assert_not_equal str.object_id, miss.object_id + + a = [] + assert_equal '.abc', "abc".sub("") { |i| a << i; "." } + assert_equal [""], a +end + +assert('String#sub with backslash') do + s = 'abXcdXef' + assert_equal 'ab<\\>cdXef', s.sub('X', '<\\\\>') + assert_equal 'abcdXef', s.sub('X', '<\\&>') + assert_equal 'abcdXef', s.sub('X', '<\\0>') + assert_equal 'abcdXef', s.sub('X', '<\\`>') + assert_equal 'abcdXef', s.sub('X', '<\\\'>') +end + +assert('String#sub!', '15.2.10.5.37') do + a = 'abcabc' + a.sub!('b', 'B') + + b = 'abcabc' + b.sub!('b') { |w| w.capitalize } + + assert_equal 'aBcabc', a + assert_equal 'aBcabc', b +end + +assert('String#to_f', '15.2.10.5.38') do + a = ''.to_f + b = '123456789'.to_f + c = '12345.6789'.to_f + d = '1e-2147483648'.to_f + e = '1e2147483648'.to_f + + assert_float(0.0, a) + assert_float(123456789.0, b) + assert_float(12345.6789, c) + assert_float(0, d) + assert_float(Float::INFINITY, e) +end + +assert('String#to_i', '15.2.10.5.39') do + a = ''.to_i + b = '32143'.to_i + c = 'a'.to_i(16) + d = '100'.to_i(2) + e = '1_000'.to_i + + assert_equal 0, a + assert_equal 32143, b + assert_equal 10, c + assert_equal 4, d + assert_equal 1_000, e +end + +assert('String#to_s', '15.2.10.5.40') do + assert_equal 'abc', 'abc'.to_s +end + +assert('String#to_sym', '15.2.10.5.41') do + assert_equal :abc, 'abc'.to_sym +end + +assert('String#upcase', '15.2.10.5.42') do + a = 'abc'.upcase + b = 'abc' + + b.upcase + + assert_equal 'ABC', a + assert_equal 'abc', b +end + +assert('String#upcase!', '15.2.10.5.43') do + a = 'abc' + + a.upcase! + + assert_equal 'ABC', a + assert_equal nil, 'ABC'.upcase! + + a = 'abcdefghijklmnopqrstuvwxyz' + b = a.dup + a.upcase! + b.upcase! + assert_equal 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', b +end + +assert('String#inspect', '15.2.10.5.46') do + # should not raise an exception - regress #1210 + assert_nothing_raised do + ("\1" * 100).inspect + end + + assert_equal "\"\\000\"", "\0".inspect +end + +# Not ISO specified + +assert('String interpolation (mrb_str_concat for shared strings)') do + a = "A" * 32 + assert_equal "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA:", "#{a}:" +end + +assert('Check the usage of a NUL character') do + "qqq\0ppp" +end + +assert('String#bytes') do + str1 = "hello" + bytes1 = [104, 101, 108, 108, 111] + + str2 = "\xFF" + bytes2 = [0xFF] + + assert_equal bytes1, str1.bytes + assert_equal bytes2, str2.bytes +end + +assert('String#each_byte') do + str1 = "hello" + bytes1 = [104, 101, 108, 108, 111] + bytes2 = [] + + str1.each_byte {|b| bytes2 << b } + + assert_equal bytes1, bytes2 +end + +assert('String#freeze') do + str = "hello" + str.freeze + + assert_raise(RuntimeError) { str.upcase! } +end diff --git a/web/server/h2o/libh2o/deps/mruby/test/t/superclass.rb b/web/server/h2o/libh2o/deps/mruby/test/t/superclass.rb new file mode 100644 index 00000000..10b6438d --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/test/t/superclass.rb @@ -0,0 +1,47 @@ +[ + # [:Object, :implementation_defined_value, '15.2.2.1'], + [:Module, :Object, '15.2.2.2'], + [:Class, :Module, '15.2.3.2'], + [:NilClass, :Object, '15.2.4.2'], + [:TrueClass, :Object, '15.2.5.2'], + [:FalseClass, :Object, '15.2.6.2'], + [:Numeric, :Object, '15.2.7.2'], + [:Integer, :Numeric, '15.2.8.2'], + [:Float, :Numeric, '15.2.9.2'], + [:String, :Object, '15.2.10.2'], + [:Symbol, :Object, '15.2.11.2'], + [:Array, :Object, '15.2.12.2'], + [:Hash, :Object, '15.2.13.2'], + [:Range, :Object, '15.2.14.2'], +# [:Regexp, :Object, '15.2.15.2'], #No Regexp in mruby core +# [:MatchData, :Object, '15.2.16.2'], + [:Proc, :Object, '15.2.17.2'], +# [:Struct, :Object, '15.2.18.2'], +# [:Time, :Object, '15.2.19.2'], +# [:IO, :Object, '15.2.20.2'], +# [:File, :IO, '15.2.21.2'], + [:Exception, :Object, '15.2.22.2'], + [:StandardError, :Exception, '15.2.23.2'], + [:ArgumentError, :StandardError, '15.2.24.2'], + # [:LocalJumpError, :StandardError, '15.2.25.2'], + [:LocalJumpError, :ScriptError, '15.2.25.2'], # mruby specific + [:RangeError, :StandardError, '12.2.26.2'], + [:RegexpError, :StandardError, '12.2.27.2'], + [:RuntimeError, :StandardError, '12.2.28.2'], + [:TypeError, :StandardError, '12.2.29.2'], +# [:ZeroDivisionError, :StandardError, '12.2.30.2'], # No ZeroDivisionError in mruby + [:NameError, :StandardError, '15.2.31.2'], + [:NoMethodError, :NameError, '15.2.32.2'], + [:IndexError, :StandardError, '15.2.33.2'], +# [:IOError, :StandardError, '12.2.34.2'], +# [:EOFError, :IOError, '12.2.35.2'], +# [:SystemCallError, :StandardError, '15.2.36.2'], + [:ScriptError, :Exception, '12.2.37.2'], + [:SyntaxError, :ScriptError, '12.2.38.2'], +# [:LoadError, :ScriptError, '12.2.39,2'], +].each do |cls, super_cls, iso| + assert "Direct superclass of #{cls}", iso do + skip "#{cls} isn't defined" unless Object.const_defined? cls + assert_equal Object.const_get(super_cls), Object.const_get(cls).superclass + end +end diff --git a/web/server/h2o/libh2o/deps/mruby/test/t/symbol.rb b/web/server/h2o/libh2o/deps/mruby/test/t/symbol.rb new file mode 100644 index 00000000..9059f45c --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/test/t/symbol.rb @@ -0,0 +1,30 @@ +## +# Symbol ISO Test + +assert('Symbol') do + assert_equal :"a", :a + assert_equal :"a#{1}", :a1 + assert_equal :'a', :a + assert_equal :'a#{1}', :"a\#{1}" +end + +assert('Symbol', '15.2.11') do + assert_equal Class, Symbol.class +end + +assert('Symbol#===', '15.2.11.3.1') do + assert_true :abc == :abc + assert_false :abc == :cba +end + +assert('Symbol#id2name', '15.2.11.3.2') do + assert_equal 'abc', :abc.id2name +end + +assert('Symbol#to_s', '15.2.11.3.3') do + assert_equal 'abc', :abc.to_s +end + +assert('Symbol#to_sym', '15.2.11.3.4') do + assert_equal :abc, :abc.to_sym +end diff --git a/web/server/h2o/libh2o/deps/mruby/test/t/syntax.rb b/web/server/h2o/libh2o/deps/mruby/test/t/syntax.rb new file mode 100644 index 00000000..29939455 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/test/t/syntax.rb @@ -0,0 +1,468 @@ +assert('__FILE__') do + file = __FILE__[-9, 9] + assert_equal 'syntax.rb', file +end + +assert('__LINE__') do + assert_equal 7, __LINE__ +end + +assert('super', '11.3.4') do + assert_raise NoMethodError do + super + end + + class SuperFoo + def foo + true + end + def bar(*a) + a + end + end + class SuperBar < SuperFoo + def foo + super + end + def bar(*a) + super(*a) + end + end + bar = SuperBar.new + + assert_true bar.foo + assert_equal [1,2,3], bar.bar(1,2,3) +end + +assert('yield', '11.3.5') do + assert_raise LocalJumpError do + yield + end + assert_raise LocalJumpError do + o = Object.new + def o.foo + yield + end + o.foo + end +end + +assert('redo in a for loop (#3275)') do + sum = 0 + for i in 1..10 + sum += i + i -= 1 + if i > 0 + redo + end + end + + assert_equal 220, sum +end + +assert('Abbreviated variable assignment', '11.4.2.3.2') do + a ||= 1 + b &&= 1 + c = 1 + c += 2 + + assert_equal 1, a + assert_nil b + assert_equal 3, c +end + +assert('case expression', '11.5.2.2.4') do + # case-expression-with-expression, one when-clause + x = 0 + case "a" + when "a" + x = 1 + end + assert_equal 1, x + + # case-expression-with-expression, multiple when-clauses + x = 0 + case "b" + when "a" + x = 1 + when "b" + x = 2 + end + assert_equal 2, x + + # no matching when-clause + x = 0 + case "c" + when "a" + x = 1 + when "b" + x = 2 + end + assert_equal 0, x + + # case-expression-with-expression, one when-clause and one else-clause + a = 0 + case "c" + when "a" + x = 1 + else + x = 3 + end + assert_equal 3, x + + # case-expression-without-expression, one when-clause + x = 0 + case + when true + x = 1 + end + assert_equal 1, x + + # case-expression-without-expression, multiple when-clauses + x = 0 + case + when 0 == 1 + x = 1 + when 1 == 1 + x = 2 + end + assert_equal 2, x + + # case-expression-without-expression, one when-clause and one else-clause + x = 0 + case + when 0 == 1 + x = 1 + else + x = 3 + end + assert_equal 3, x + + # multiple when-arguments + x = 0 + case 4 + when 1, 3, 5 + x = 1 + when 2, 4, 6 + x = 2 + end + assert_equal 2, x + + # when-argument with splatting argument + x = :integer + odds = [ 1, 3, 5, 7, 9 ] + evens = [ 2, 4, 6, 8 ] + case 5 + when *odds + x = :odd + when *evens + x = :even + end + assert_equal :odd, x + + true +end + +assert('Nested const reference') do + module Syntax4Const + CONST1 = "hello world" + class Const2 + def const1 + CONST1 + end + end + end + assert_equal "hello world", Syntax4Const::CONST1 + assert_equal "hello world", Syntax4Const::Const2.new.const1 +end + +assert('Abbreviated variable assignment as returns') do + module Syntax4AbbrVarAsgnAsReturns + class A + def b + @c ||= 1 + end + end + end + assert_equal 1, Syntax4AbbrVarAsgnAsReturns::A.new.b +end + +assert('Splat and multiple assignment') do + *a = *[1,2,3] + b, *c = *[7,8,9] + + assert_equal [1,2,3], a + assert_equal 7, b + assert_equal [8,9], c + + (a, b), c = [1,2],3 + assert_equal [1,2,3], [a,b,c] + (a, b), c = 1,2,3 + assert_equal [1,nil,2], [a,b,c] +end + +assert('Splat and multiple assignment from variable') do + a = [1, 2, 3] + b, *c = a + + assert_equal 1, b + assert_equal [2, 3], c +end + +assert('Splat and multiple assignment from variables') do + a = [1, 2, 3] + b = [4, 5, 6, 7] + c, d, *e, f, g = *a, *b + + assert_equal 1, c + assert_equal 2, d + assert_equal [3, 4, 5], e + assert_equal 6, f + assert_equal 7, g +end + +assert('Splat and multiple assignment in for') do + a = [1, 2, 3, 4, 5, 6, 7] + for b, c, *d, e, f in [a] do + end + + assert_equal 1, b + assert_equal 2, c + assert_equal [3, 4, 5], d + assert_equal 6, e + assert_equal 7, f +end + +assert('Splat without assignment') do + * = [0] + a, * = [1, 2] + assert_equal 1, a +end + +assert('multiple assignment (rest)') do + *a = 0 + assert_equal [0], a +end + +assert('multiple assignment (rest+post)') do + *a, b = 0, 1, 2 + *c, d = 3 + + assert_equal [0, 1], a + assert_equal 2, b + assert_equal [], c + assert_equal 3, d +end + +assert('multiple assignment (nosplat array rhs)') do + a, *b = [] + *c, d = [0] + e, *f, g = [1, 2] + + assert_nil a + assert_equal [], b + assert_equal [], c + assert_equal 0, d + assert_equal 1, e + assert_equal [], f + assert_equal 2, g +end + +assert('multiple assignment (empty array rhs #3236, #3239)') do + a,b,*c = []; assert_equal [nil, nil, []], [a, b, c] + a,b,*c = [1]; assert_equal [1, nil, []], [a, b, c] + a,b,*c = [nil]; assert_equal [nil,nil, []], [a, b, c] + a,b,*c = [[]]; assert_equal [[], nil, []], [a, b, c] +end + +assert('Return values of case statements') do + a = [] << case 1 + when 3 then 2 + when 2 then 2 + when 1 then 2 + end + + b = [] << case 1 + when 2 then 2 + else + end + + def fb + n = 0 + Proc.new do + n += 1 + case + when n % 15 == 0 + else n + end + end + end + + assert_equal [2], a + assert_equal [nil], b + assert_equal 1, fb.call +end + +assert('Return values of if and case statements') do + true_clause_value = + if true + 1 + else + case 2 + when 3 + end + 4 + end + + assert_equal 1, true_clause_value +end + +assert('Return values of no expression case statement') do + when_value = + case + when true + 1 + end + + assert_equal 1, when_value +end + +assert('splat object in assignment') do + o = Object.new + def o.to_a + nil + end + assert_equal [o], (a = *o) + + def o.to_a + 1 + end + assert_raise(TypeError) { a = *o } + + def o.to_a + [2] + end + assert_equal [2], (a = *o) +end + +assert('splat object in case statement') do + o = Object.new + def o.to_a + nil + end + a = case o + when *o + 1 + end + assert_equal 1, a +end + +assert('splat in case statement') do + values = [3,5,1,7,8] + testa = [1,2,7] + testb = [5,6] + resulta = [] + resultb = [] + resultc = [] + values.each do |value| + case value + when *testa + resulta << value + when *testb + resultb << value + else + resultc << value + end + end + + assert_equal [1,7], resulta + assert_equal [5], resultb + assert_equal [3,8], resultc +end + +assert('External command execution.') do + module Kernel + sym = '`'.to_sym + alias_method :old_cmd, sym + + results = [] + define_method(sym) do |str| + results.push str + str + end + + `test` # NOVAL NODE_XSTR + `test dynamic #{sym}` # NOVAL NODE_DXSTR + assert_equal ['test', 'test dynamic `'], results + + t = `test` # VAL NODE_XSTR + assert_equal 'test', t + assert_equal ['test', 'test dynamic `', 'test'], results + + t = `test dynamic #{sym}` # VAL NODE_DXSTR + assert_equal 'test dynamic `', t + assert_equal ['test', 'test dynamic `', 'test', 'test dynamic `'], results + + alias_method sym, :old_cmd + end + true +end + +assert('parenthesed do-block in cmdarg') do + class ParenDoBlockCmdArg + def test(block) + block.call + end + end + x = ParenDoBlockCmdArg.new + result = x.test (Proc.new do :ok; end) + assert_equal :ok, result +end + +assert('method definition in cmdarg') do + if false + bar def foo; self.each do end end + end + true +end + +assert('optional argument in the rhs default expressions') do + class OptArgInRHS + def foo + "method called" + end + def t(foo = foo) + foo + end + def t2(foo = foo()) + foo + end + end + o = OptArgInRHS.new + assert_nil(o.t) + assert_equal("method called", o.t2) +end + +assert('optional block argument in the rhs default expressions') do + assert_nil(Proc.new {|foo = foo| foo}.call) +end + +assert('multiline comments work correctly') do +=begin +this is a comment with nothing after begin and end +=end +=begin this is a comment +this is a comment with extra after =begin +=end +=begin +this is a comment that has =end with spaces after it +=end +=begin this is a comment +this is a comment that has extra after =begin and =end with spaces after it +=end + line = __LINE__ +=begin this is a comment +this is a comment that has extra after =begin and =end with tabs after it +=end xxxxxxxxxxxxxxxxxxxxxxxxxx + assert_equal(line + 4, __LINE__) +end diff --git a/web/server/h2o/libh2o/deps/mruby/test/t/true.rb b/web/server/h2o/libh2o/deps/mruby/test/t/true.rb new file mode 100644 index 00000000..74f605ef --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/test/t/true.rb @@ -0,0 +1,31 @@ +## +# TrueClass ISO Test + +assert('TrueClass', '15.2.5') do + assert_equal Class, TrueClass.class +end + +assert('TrueClass true', '15.2.5.1') do + assert_true true + assert_equal TrueClass, true.class + assert_false TrueClass.method_defined? :new +end + +assert('TrueClass#&', '15.2.5.3.1') do + assert_true true.&(true) + assert_false true.&(false) +end + +assert('TrueClass#^', '15.2.5.3.2') do + assert_false true.^(true) + assert_true true.^(false) +end + +assert('TrueClass#to_s', '15.2.5.3.3') do + assert_equal 'true', true.to_s +end + +assert('TrueClass#|', '15.2.5.3.4') do + assert_true true.|(true) + assert_true true.|(false) +end diff --git a/web/server/h2o/libh2o/deps/mruby/test/t/typeerror.rb b/web/server/h2o/libh2o/deps/mruby/test/t/typeerror.rb new file mode 100644 index 00000000..32536a74 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/test/t/typeerror.rb @@ -0,0 +1,6 @@ +## +# TypeError ISO Test + +assert('TypeError', '15.2.29') do + assert_equal Class, TypeError.class +end diff --git a/web/server/h2o/libh2o/deps/mruby/test/t/unicode.rb b/web/server/h2o/libh2o/deps/mruby/test/t/unicode.rb new file mode 100644 index 00000000..8622ae08 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/test/t/unicode.rb @@ -0,0 +1,39 @@ +# Test of the \u notation + +assert('bare \u notation test') do + # Mininum and maximum one byte characters + assert_equal("\x00", "\u0000") + assert_equal("\x7F", "\u007F") + + # Mininum and maximum two byte characters + assert_equal("\xC2\x80", "\u0080") + assert_equal("\xDF\xBF", "\u07FF") + + # Mininum and maximum three byte characters + assert_equal("\xE0\xA0\x80", "\u0800") + assert_equal("\xEF\xBF\xBF", "\uFFFF") + + # Four byte characters require the \U notation +end + +assert('braced \u notation test') do + # Mininum and maximum one byte characters + assert_equal("\x00", "\u{0000}") + assert_equal("\x7F", "\u{007F}") + + # Mininum and maximum two byte characters + assert_equal("\xC2\x80", "\u{0080}") + assert_equal("\xDF\xBF", "\u{07FF}") + + # Mininum and maximum three byte characters + assert_equal("\xE0\xA0\x80", "\u{0800}") + assert_equal("\xEF\xBF\xBF", "\u{FFFF}") + + # Mininum and maximum four byte characters + assert_equal("\xF0\x90\x80\x80", "\u{10000}") + assert_equal("\xF4\x8F\xBF\xBF", "\u{10FFFF}") +end + +assert('braced multiple \u notation test') do + assert_equal("ABC", "\u{41 42 43}") +end diff --git a/web/server/h2o/libh2o/deps/mruby/travis_config.rb b/web/server/h2o/libh2o/deps/mruby/travis_config.rb new file mode 100644 index 00000000..5904d688 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/travis_config.rb @@ -0,0 +1,53 @@ +MRuby::Build.new('debug') do |conf| + toolchain :gcc + enable_debug + + # include all core GEMs + conf.gembox 'full-core' + conf.cc.flags += %w(-Werror=declaration-after-statement) + conf.compilers.each do |c| + c.defines += %w(MRB_GC_STRESS MRB_GC_FIXED_ARENA MRB_METHOD_CACHE) + end + + build_mrbc_exec +end + +MRuby::Build.new('full-debug') do |conf| + toolchain :gcc + enable_debug + + # include all core GEMs + conf.gembox 'full-core' + conf.cc.defines = %w(MRB_ENABLE_DEBUG_HOOK) + + conf.enable_test +end + +MRuby::Build.new do |conf| + toolchain :gcc + + # include all core GEMs + conf.gembox 'full-core' + conf.cc.flags += %w(-Werror=declaration-after-statement) + conf.compilers.each do |c| + c.defines += %w(MRB_GC_FIXED_ARENA) + end + conf.enable_bintest + conf.enable_test +end + +MRuby::Build.new('cxx_abi') do |conf| + toolchain :gcc + + conf.gembox 'full-core' + conf.cc.flags += %w(-Werror=declaration-after-statement) + conf.compilers.each do |c| + c.defines += %w(MRB_GC_FIXED_ARENA) + end + conf.enable_bintest + conf.enable_test + + enable_cxx_abi + + build_mrbc_exec +end diff --git a/web/server/h2o/libh2o/deps/neverbleed/.clang-format b/web/server/h2o/libh2o/deps/neverbleed/.clang-format new file mode 100644 index 00000000..9640123c --- /dev/null +++ b/web/server/h2o/libh2o/deps/neverbleed/.clang-format @@ -0,0 +1,7 @@ +# requires clang-format >= 3.6 +BasedOnStyle: "LLVM" +IndentWidth: 4 +ColumnLimit: 132 +BreakBeforeBraces: Linux +AllowShortFunctionsOnASingleLine: None +SortIncludes: false diff --git a/web/server/h2o/libh2o/deps/neverbleed/.gitignore b/web/server/h2o/libh2o/deps/neverbleed/.gitignore new file mode 100644 index 00000000..bbf313b2 --- /dev/null +++ b/web/server/h2o/libh2o/deps/neverbleed/.gitignore @@ -0,0 +1,32 @@ +# Object files +*.o +*.ko +*.obj +*.elf + +# Precompiled Headers +*.gch +*.pch + +# Libraries +*.lib +*.a +*.la +*.lo + +# Shared objects (inc. Windows DLLs) +*.dll +*.so +*.so.* +*.dylib + +# Executables +*.exe +*.out +*.app +*.i*86 +*.x86_64 +*.hex + +# Debug files +*.dSYM/ diff --git a/web/server/h2o/libh2o/deps/neverbleed/LICENSE b/web/server/h2o/libh2o/deps/neverbleed/LICENSE new file mode 100644 index 00000000..2bd3423e --- /dev/null +++ b/web/server/h2o/libh2o/deps/neverbleed/LICENSE @@ -0,0 +1,22 @@ +The MIT License (MIT) + +Copyright (c) 2015 Kazuho Oku, DeNA Co., Ltd. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + diff --git a/web/server/h2o/libh2o/deps/neverbleed/README.md b/web/server/h2o/libh2o/deps/neverbleed/README.md new file mode 100644 index 00000000..8357055c --- /dev/null +++ b/web/server/h2o/libh2o/deps/neverbleed/README.md @@ -0,0 +1,70 @@ +Neverbleed +=============== + +Neverbleed is an [OpenSSL engine](https://www.openssl.org/docs/manmaster/crypto/engine.html) that runs RSA private key operations in an isolated process, thereby minimizing the risk of private key leak in case of vulnerability such as [Heartbleed](http://heartbleed.com/). + +The engine is known to work together with existing versions of OpenSSL or LibreSSL, with minimal changes to the server source code. + +FAQ +--- + +### Q. How much is the overhead? + +Virtually none. + +Generally speaking, private key operations are much more heavier than the overhead of inter-process communication. +On my Linux VM running on Core i7 @ 2.4GHz (MacBook Pro 15" Late 2013), OpenSSL 1.0.2 without privilege separation processes 319.56 full TLS handshakes per second, whereas OpenSSL with privilege separation processes 316.72 handshakes per second (note: RSA key length: 2,048 bits, selected cipher-suite: ECDHE-RSA-AES128-GCM-SHA256). + +### Q. Why does the library only protect the private keys? + +Because private keys are the only _long-term_ secret being used for encrypting and/or digitally-signing the communication. + +Depending on how OpenSSL is used, it might be beneficial to separate symmetric cipher operations or TLS operations as a whole. +But even in such case, it would still be a good idea to isolate private key operations from them considering the impact of private key leaks. +In other words, separating private key operations only to an isolated process in always a good thing to do. + +### Q. Is there any HTTP server that uses Neverbleed? + +Neverbleed is used by [H2O](https://h2o.examp1e.net/) HTTP2 server since version [1.5.0-beta4](https://github.com/h2o/h2o/releases/tag/v1.5.0-beta4). + +How-to +------ + +The library exposes two functions: `neverbleed_init` and `neverbleed_load_private_key_file`. + +The first function spawns an external process dedicated to private key operations, and the second function assigns a RSA private key stored in the specified file to an existing SSL context (`SSL_CTX`). + +By + +1. adding call to `neverbleed_init` +2. replacing call to `SSL_CTX_use_PrivateKey_file` with `neverbleed_load_private_key_file` + +the privilege separation engine will be used for all the incoming TLS connections. + +``` + neverbleed_t nb; + char errbuf[NEVERBLEED_ERRBUF_SIZE]; + + /* initialize the OpenSSL library and the neverbleed engine */ + SSL_load_error_strings(); + SSL_library_init(); + OpenSSL_add_all_algorithms(); + if (neverbleed_init(&nb, errbuf) != 0) { + fprintf(stderr, "neverbleed_init failed: %s\n", errbuf); + ... + } + + ... + + /* load certificate chain and private key */ + if (SSL_CTX_use_certificate_chain_file(ssl_ctx, certchain_fn) != 1) { + fprintf(stderr, "failed to load certificate chain file:%s\n", certchain_fn); + ... + } + if (neverbleed_load_private_key_file(&nb, ctx, privkey_fn, errbuf) != 1) { + fprintf(stderr, "failed to load private key from file:%s:%s\n", privkey_fn, errbuf); + ... + } +``` + +Also, `neverbleed_setuidgid` function can be used to drop the privileges of the daemon process once it completes loading all the private keys. diff --git a/web/server/h2o/libh2o/deps/neverbleed/neverbleed.c b/web/server/h2o/libh2o/deps/neverbleed/neverbleed.c new file mode 100644 index 00000000..7b36d6cb --- /dev/null +++ b/web/server/h2o/libh2o/deps/neverbleed/neverbleed.c @@ -0,0 +1,1521 @@ +/* + * Copyright (c) 2015 Kazuho Oku, DeNA Co., Ltd. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef __linux__ +#include +#endif +#include "neverbleed.h" + +#if (!defined(LIBRESSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER >= 0x1010000fL) +#define OPENSSL_1_1_API 1 +#else +#define OPENSSL_1_1_API 0 +#endif + +enum neverbleed_type { NEVERBLEED_TYPE_ERROR, NEVERBLEED_TYPE_RSA, NEVERBLEED_TYPE_ECDSA }; + +struct expbuf_t { + char *buf; + char *start; + char *end; + size_t capacity; +}; + +struct st_neverbleed_rsa_exdata_t { + neverbleed_t *nb; + size_t key_index; +}; + +struct st_neverbleed_thread_data_t { + pid_t self_pid; + int fd; +}; + +static void warnvf(const char *fmt, va_list args) +{ + char errbuf[256]; + + if (errno != 0) { + strerror_r(errno, errbuf, sizeof(errbuf)); + } else { + errbuf[0] = '\0'; + } + + fprintf(stderr, "[openssl-privsep] "); + vfprintf(stderr, fmt, args); + if (errbuf[0] != '\0') + fputs(errbuf, stderr); + fputc('\n', stderr); +} + +__attribute__((format(printf, 1, 2))) static void warnf(const char *fmt, ...) +{ + va_list args; + + va_start(args, fmt); + warnvf(fmt, args); + va_end(args); +} + +__attribute__((format(printf, 1, 2), noreturn)) static void dief(const char *fmt, ...) +{ + va_list args; + + va_start(args, fmt); + warnvf(fmt, args); + va_end(args); + + abort(); +} + +static char *dirname(const char *path) +{ + const char *last_slash = strrchr(path, '/'); + char *ret; + + if (last_slash == NULL) { + errno = 0; + dief("dirname: no slash in given path:%s", path); + } + if ((ret = malloc(last_slash + 1 - path)) == NULL) + dief("no memory"); + memcpy(ret, path, last_slash - path); + ret[last_slash - path] = '\0'; + return ret; +} + +static void set_cloexec(int fd) +{ + if (fcntl(fd, F_SETFD, O_CLOEXEC) == -1) + dief("failed to set O_CLOEXEC to fd %d", fd); +} + +static int read_nbytes(int fd, void *p, size_t sz) +{ + while (sz != 0) { + ssize_t r; + while ((r = read(fd, p, sz)) == -1 && errno == EINTR) + ; + if (r == -1) { + return -1; + } else if (r == 0) { + errno = 0; + return -1; + } + p = (char *)p + r; + sz -= r; + } + return 0; +} + +static size_t expbuf_size(struct expbuf_t *buf) +{ + return buf->end - buf->start; +} + +static void expbuf_dispose(struct expbuf_t *buf) +{ + if (buf->capacity != 0) + OPENSSL_cleanse(buf->buf, buf->capacity); + free(buf->buf); + memset(buf, 0, sizeof(*buf)); +} + +static void expbuf_reserve(struct expbuf_t *buf, size_t extra) +{ + char *n; + + if (extra <= buf->buf + buf->capacity - buf->end) + return; + + if (buf->capacity == 0) + buf->capacity = 4096; + while (buf->buf + buf->capacity - buf->end < extra) + buf->capacity *= 2; + if ((n = realloc(buf->buf, buf->capacity)) == NULL) + dief("realloc failed"); + buf->start += n - buf->buf; + buf->end += n - buf->buf; + buf->buf = n; +} + +static void expbuf_push_num(struct expbuf_t *buf, size_t v) +{ + expbuf_reserve(buf, sizeof(v)); + memcpy(buf->end, &v, sizeof(v)); + buf->end += sizeof(v); +} + +static void expbuf_push_str(struct expbuf_t *buf, const char *s) +{ + size_t l = strlen(s) + 1; + expbuf_reserve(buf, l); + memcpy(buf->end, s, l); + buf->end += l; +} + +static void expbuf_push_bytes(struct expbuf_t *buf, const void *p, size_t l) +{ + expbuf_push_num(buf, l); + expbuf_reserve(buf, l); + memcpy(buf->end, p, l); + buf->end += l; +} + +static int expbuf_shift_num(struct expbuf_t *buf, size_t *v) +{ + if (expbuf_size(buf) < sizeof(*v)) + return -1; + memcpy(v, buf->start, sizeof(*v)); + buf->start += sizeof(*v); + return 0; +} + +static char *expbuf_shift_str(struct expbuf_t *buf) +{ + char *nul = memchr(buf->start, '\0', expbuf_size(buf)), *ret; + if (nul == NULL) + return NULL; + ret = buf->start; + buf->start = nul + 1; + return ret; +} + +static void *expbuf_shift_bytes(struct expbuf_t *buf, size_t *l) +{ + void *ret; + if (expbuf_shift_num(buf, l) != 0) + return NULL; + if (expbuf_size(buf) < *l) + return NULL; + ret = buf->start; + buf->start += *l; + return ret; +} + +static int expbuf_write(struct expbuf_t *buf, int fd) +{ + struct iovec vecs[2] = {{NULL}}; + size_t bufsz = expbuf_size(buf); + int vecindex; + ssize_t r; + + vecs[0].iov_base = &bufsz; + vecs[0].iov_len = sizeof(bufsz); + vecs[1].iov_base = buf->start; + vecs[1].iov_len = bufsz; + + for (vecindex = 0; vecindex != sizeof(vecs) / sizeof(vecs[0]);) { + while ((r = writev(fd, vecs + vecindex, sizeof(vecs) / sizeof(vecs[0]) - vecindex)) == -1 && errno == EINTR) + ; + if (r == -1) + return -1; + assert(r != 0); + while (r != 0 && r >= vecs[vecindex].iov_len) { + r -= vecs[vecindex].iov_len; + ++vecindex; + } + if (r != 0) { + vecs[vecindex].iov_base = (char *)vecs[vecindex].iov_base + r; + vecs[vecindex].iov_len -= r; + } + } + + return 0; +} + +static int expbuf_read(struct expbuf_t *buf, int fd) +{ + size_t sz; + + if (read_nbytes(fd, &sz, sizeof(sz)) != 0) + return -1; + expbuf_reserve(buf, sz); + if (read_nbytes(fd, buf->end, sz) != 0) + return -1; + buf->end += sz; + return 0; +} + +#if !defined(NAME_MAX) || defined(__linux__) +/* readdir(3) is known to be thread-safe on Linux and should be thread-safe on a platform that does not have a predefined value for + NAME_MAX */ +#define FOREACH_DIRENT(dp, dent) \ + struct dirent *dent; \ + while ((dent = readdir(dp)) != NULL) +#else +#define FOREACH_DIRENT(dp, dent) \ + struct { \ + struct dirent d; \ + char s[NAME_MAX + 1]; \ + } dent_; \ + struct dirent *dentp, *dent = &dent_.d; \ + int ret; \ + while ((ret = readdir_r(dp, dent, &dentp)) == 0 && dentp != NULL) +#endif /* FOREACH_DIRENT */ + +static void unlink_dir(const char *path) +{ + DIR *dp; + char buf[PATH_MAX]; + + if ((dp = opendir(path)) != NULL) { + FOREACH_DIRENT(dp, entp) + { + if (strcmp(entp->d_name, ".") == 0 || strcmp(entp->d_name, "..") == 0) + continue; + snprintf(buf, sizeof(buf), "%s/%s", path, entp->d_name); + unlink_dir(buf); + } + closedir(dp); + } + unlink(path); + rmdir(path); +} + +void dispose_thread_data(void *_thdata) +{ + struct st_neverbleed_thread_data_t *thdata = _thdata; + assert(thdata->fd >= 0); + close(thdata->fd); + thdata->fd = -1; +} + +struct st_neverbleed_thread_data_t *get_thread_data(neverbleed_t *nb) +{ + struct st_neverbleed_thread_data_t *thdata; + pid_t self_pid = getpid(); + ssize_t r; + + if ((thdata = pthread_getspecific(nb->thread_key)) != NULL) { + if (thdata->self_pid == self_pid) + return thdata; + /* we have been forked! */ + close(thdata->fd); + } else { + if ((thdata = malloc(sizeof(*thdata))) == NULL) + dief("malloc failed"); + } + + thdata->self_pid = self_pid; +#ifdef SOCK_CLOEXEC + if ((thdata->fd = socket(PF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0)) == -1) + dief("socket(2) failed"); +#else + if ((thdata->fd = socket(PF_UNIX, SOCK_STREAM, 0)) == -1) + dief("socket(2) failed"); + set_cloexec(thdata->fd); +#endif + while (connect(thdata->fd, (void *)&nb->sun_, sizeof(nb->sun_)) != 0) + if (errno != EINTR) + dief("failed to connect to privsep daemon"); + while ((r = write(thdata->fd, nb->auth_token, sizeof(nb->auth_token))) == -1 && errno == EINTR) + ; + if (r != sizeof(nb->auth_token)) + dief("failed to send authentication token"); + pthread_setspecific(nb->thread_key, thdata); + + return thdata; +} + +static void get_privsep_data(const RSA *rsa, struct st_neverbleed_rsa_exdata_t **exdata, + struct st_neverbleed_thread_data_t **thdata) +{ + *exdata = RSA_get_ex_data(rsa, 0); + if (*exdata == NULL) { + errno = 0; + dief("invalid internal ref"); + } + *thdata = get_thread_data((*exdata)->nb); +} + +static const size_t default_reserved_size = 8192; + +struct key_slots { + size_t size; + size_t reserved_size; + /* bit array slots: + * 1-bit slot available + * 0-bit slot unavailable + */ + uint8_t *bita_avail; +}; + +static struct { + struct { + pthread_mutex_t lock; + RSA **keys; + struct key_slots rsa_slots; + EC_KEY **ecdsa_keys; + struct key_slots ecdsa_slots; + } keys; + neverbleed_t *nb; +} daemon_vars = {{PTHREAD_MUTEX_INITIALIZER}}; + +static RSA *daemon_get_rsa(size_t key_index) +{ + RSA *rsa; + + pthread_mutex_lock(&daemon_vars.keys.lock); + rsa = daemon_vars.keys.keys[key_index]; + if (rsa) + RSA_up_ref(rsa); + pthread_mutex_unlock(&daemon_vars.keys.lock); + + return rsa; +} + +/* + * Returns an available slot in bit array B + * or if not found, returns SIZE_MAX + */ +static size_t bita_ffirst(const uint8_t *b, const size_t tot, size_t bits) +{ + if (bits >= tot) + return SIZE_MAX; + + uint64_t w = *((uint64_t *) b); + /* __builtin_ffsll returns one plus the index of the least significant 1-bit, or zero if not found */ + uint32_t r = __builtin_ffsll(w); + if (r) + return bits + r - 1; /* adjust result */ + + return bita_ffirst(&b[8], tot, bits + 64); +} + +/* + * bit operation helpers for the bit-array in key_slots + */ +#define BITMASK(b) (1 << ((b) % CHAR_BIT)) +#define BITBYTE(b) ((b) / CHAR_BIT) +#define BITSET(a, b) ((a)[BITBYTE(b)] |= BITMASK(b)) +#define BITUNSET(a, b) ((a)[BITBYTE(b)] &= ~BITMASK(b)) +#define BITBYTES(nb) ((nb + CHAR_BIT - 1) / CHAR_BIT) +#define BITCHECK(a, b) ((a)[BITBYTE(b)] & BITMASK(b)) + +static void adjust_slots_reserved_size(int type, struct key_slots *slots) +{ +#define ROUND2WORD(n) (n + 64 - 1 - (n + 64 - 1) % 64) + if (!slots->reserved_size || (slots->size >= slots->reserved_size)) { + size_t size = slots->reserved_size ? ROUND2WORD((size_t)(slots->reserved_size * 0.50) + slots->reserved_size) + : default_reserved_size; +#undef ROUND2WORD + + switch (type) { + case NEVERBLEED_TYPE_RSA: + if ((daemon_vars.keys.keys = realloc(daemon_vars.keys.keys, sizeof(*daemon_vars.keys.keys) * size)) == NULL) + dief("no memory"); + break; + case NEVERBLEED_TYPE_ECDSA: + if ((daemon_vars.keys.ecdsa_keys = realloc(daemon_vars.keys.ecdsa_keys, sizeof(*daemon_vars.keys.ecdsa_keys) * size)) == NULL) + dief("no memory"); + break; + default: + dief("invalid type adjusting reserved"); + } + + uint8_t *b; + if ((b = realloc(slots->bita_avail, BITBYTES(size))) == NULL) + dief("no memory"); + + /* set all bits to 1 making all slots available */ + memset(&b[BITBYTES(slots->reserved_size)], 0xff, BITBYTES(size - slots->reserved_size)); + + slots->bita_avail = b; + slots->reserved_size = size; + } +} + +static size_t daemon_set_rsa(RSA *rsa) +{ + pthread_mutex_lock(&daemon_vars.keys.lock); + + adjust_slots_reserved_size(NEVERBLEED_TYPE_RSA, &daemon_vars.keys.rsa_slots); + + size_t index = bita_ffirst(daemon_vars.keys.rsa_slots.bita_avail, daemon_vars.keys.rsa_slots.reserved_size, 0); + + if (index == SIZE_MAX) + dief("no available slot for key"); + + /* set slot as unavailable */ + BITUNSET(daemon_vars.keys.rsa_slots.bita_avail, index); + + daemon_vars.keys.rsa_slots.size++; + daemon_vars.keys.keys[index] = rsa; + RSA_up_ref(rsa); + pthread_mutex_unlock(&daemon_vars.keys.lock); + + return index; +} + +static int priv_encdec_proxy(const char *cmd, int flen, const unsigned char *from, unsigned char *_to, RSA *rsa, int padding) +{ + struct st_neverbleed_rsa_exdata_t *exdata; + struct st_neverbleed_thread_data_t *thdata; + struct expbuf_t buf = {NULL}; + size_t ret; + unsigned char *to; + size_t tolen; + + get_privsep_data(rsa, &exdata, &thdata); + + expbuf_push_str(&buf, cmd); + expbuf_push_bytes(&buf, from, flen); + expbuf_push_num(&buf, exdata->key_index); + expbuf_push_num(&buf, padding); + if (expbuf_write(&buf, thdata->fd) != 0) + dief(errno != 0 ? "write error" : "connection closed by daemon"); + expbuf_dispose(&buf); + + if (expbuf_read(&buf, thdata->fd) != 0) + dief(errno != 0 ? "read error" : "connection closed by daemon"); + if (expbuf_shift_num(&buf, &ret) != 0 || (to = expbuf_shift_bytes(&buf, &tolen)) == NULL) { + errno = 0; + dief("failed to parse response"); + } + memcpy(_to, to, tolen); + expbuf_dispose(&buf); + + return (int)ret; +} + +static int priv_encdec_stub(const char *name, + int (*func)(int flen, const unsigned char *from, unsigned char *to, RSA *rsa, int padding), + struct expbuf_t *buf) +{ + unsigned char *from, to[4096]; + size_t flen; + size_t key_index, padding; + RSA *rsa; + int ret; + + if ((from = expbuf_shift_bytes(buf, &flen)) == NULL || expbuf_shift_num(buf, &key_index) != 0 || + expbuf_shift_num(buf, &padding) != 0) { + errno = 0; + warnf("%s: failed to parse request", name); + return -1; + } + if ((rsa = daemon_get_rsa(key_index)) == NULL) { + errno = 0; + warnf("%s: invalid key index:%zu\n", name, key_index); + return -1; + } + ret = func((int)flen, from, to, rsa, (int)padding); + expbuf_dispose(buf); + RSA_free(rsa); + + expbuf_push_num(buf, ret); + expbuf_push_bytes(buf, to, ret > 0 ? ret : 0); + + return 0; +} + +static int priv_enc_proxy(int flen, const unsigned char *from, unsigned char *to, RSA *rsa, int padding) +{ + return priv_encdec_proxy("priv_enc", flen, from, to, rsa, padding); +} + +static int priv_enc_stub(struct expbuf_t *buf) +{ + return priv_encdec_stub(__FUNCTION__, RSA_private_encrypt, buf); +} + +static int priv_dec_proxy(int flen, const unsigned char *from, unsigned char *to, RSA *rsa, int padding) +{ + return priv_encdec_proxy("priv_dec", flen, from, to, rsa, padding); +} + +static int priv_dec_stub(struct expbuf_t *buf) +{ + return priv_encdec_stub(__FUNCTION__, RSA_private_decrypt, buf); +} + +static int sign_proxy(int type, const unsigned char *m, unsigned int m_len, unsigned char *_sigret, unsigned *_siglen, + const RSA *rsa) +{ + struct st_neverbleed_rsa_exdata_t *exdata; + struct st_neverbleed_thread_data_t *thdata; + struct expbuf_t buf = {NULL}; + size_t ret, siglen; + unsigned char *sigret; + + get_privsep_data(rsa, &exdata, &thdata); + + expbuf_push_str(&buf, "sign"); + expbuf_push_num(&buf, type); + expbuf_push_bytes(&buf, m, m_len); + expbuf_push_num(&buf, exdata->key_index); + if (expbuf_write(&buf, thdata->fd) != 0) + dief(errno != 0 ? "write error" : "connection closed by daemon"); + expbuf_dispose(&buf); + + if (expbuf_read(&buf, thdata->fd) != 0) + dief(errno != 0 ? "read error" : "connection closed by daemon"); + if (expbuf_shift_num(&buf, &ret) != 0 || (sigret = expbuf_shift_bytes(&buf, &siglen)) == NULL) { + errno = 0; + dief("failed to parse response"); + } + memcpy(_sigret, sigret, siglen); + *_siglen = (unsigned)siglen; + expbuf_dispose(&buf); + + return (int)ret; +} + +static int sign_stub(struct expbuf_t *buf) +{ + unsigned char *m, sigret[4096]; + size_t type, m_len, key_index; + RSA *rsa; + unsigned siglen = 0; + int ret; + + if (expbuf_shift_num(buf, &type) != 0 || (m = expbuf_shift_bytes(buf, &m_len)) == NULL || + expbuf_shift_num(buf, &key_index) != 0) { + errno = 0; + warnf("%s: failed to parse request", __FUNCTION__); + return -1; + } + if ((rsa = daemon_get_rsa(key_index)) == NULL) { + errno = 0; + warnf("%s: invalid key index:%zu", __FUNCTION__, key_index); + return -1; + } + ret = RSA_sign((int)type, m, (unsigned)m_len, sigret, &siglen, rsa); + expbuf_dispose(buf); + RSA_free(rsa); + + expbuf_push_num(buf, ret); + expbuf_push_bytes(buf, sigret, ret == 1 ? siglen : 0); + + return 0; +} + +#if !OPENSSL_1_1_API + +static void RSA_get0_key(const RSA *rsa, const BIGNUM **n, const BIGNUM **e, const BIGNUM **d) +{ + if (n) { + *n = rsa->n; + } + + if (e) { + *e = rsa->e; + } + + if (d) { + *d = rsa->d; + } +} + +static int RSA_set0_key(RSA *rsa, BIGNUM *n, BIGNUM *e, BIGNUM *d) +{ + if (n == NULL || e == NULL) { + return 0; + } + + BN_free(rsa->n); + BN_free(rsa->e); + BN_free(rsa->d); + rsa->n = n; + rsa->e = e; + rsa->d = d; + + return 1; +} + +static void RSA_set_flags(RSA *r, int flags) +{ + r->flags |= flags; +} +#endif + +static EVP_PKEY *create_pkey(neverbleed_t *nb, size_t key_index, const char *ebuf, const char *nbuf) +{ + struct st_neverbleed_rsa_exdata_t *exdata; + RSA *rsa; + EVP_PKEY *pkey; + BIGNUM *e = NULL, *n = NULL; + + if ((exdata = malloc(sizeof(*exdata))) == NULL) { + fprintf(stderr, "no memory\n"); + abort(); + } + exdata->nb = nb; + exdata->key_index = key_index; + + rsa = RSA_new_method(nb->engine); + RSA_set_ex_data(rsa, 0, exdata); + if (BN_hex2bn(&e, ebuf) == 0) { + fprintf(stderr, "failed to parse e:%s\n", ebuf); + abort(); + } + if (BN_hex2bn(&n, nbuf) == 0) { + fprintf(stderr, "failed to parse n:%s\n", nbuf); + abort(); + } + RSA_set0_key(rsa, n, e, NULL); + RSA_set_flags(rsa, RSA_FLAG_EXT_PKEY); + + pkey = EVP_PKEY_new(); + EVP_PKEY_set1_RSA(pkey, rsa); + RSA_free(rsa); + + return pkey; +} + +#if OPENSSL_1_1_API + +static EC_KEY *daemon_get_ecdsa(size_t key_index) +{ + EC_KEY *ec_key; + + pthread_mutex_lock(&daemon_vars.keys.lock); + ec_key = daemon_vars.keys.ecdsa_keys[key_index]; + if (ec_key) + EC_KEY_up_ref(ec_key); + pthread_mutex_unlock(&daemon_vars.keys.lock); + + return ec_key; +} + +static size_t daemon_set_ecdsa(EC_KEY *ec_key) +{ + pthread_mutex_lock(&daemon_vars.keys.lock); + + adjust_slots_reserved_size(NEVERBLEED_TYPE_ECDSA, &daemon_vars.keys.ecdsa_slots); + + size_t index = bita_ffirst(daemon_vars.keys.ecdsa_slots.bita_avail, daemon_vars.keys.ecdsa_slots.reserved_size, 0); + + if (index == SIZE_MAX) + dief("no available slot for key"); + + /* set slot as unavailable */ + BITUNSET(daemon_vars.keys.ecdsa_slots.bita_avail, index); + + daemon_vars.keys.ecdsa_slots.size++; + daemon_vars.keys.ecdsa_keys[index] = ec_key; + EC_KEY_up_ref(ec_key); + pthread_mutex_unlock(&daemon_vars.keys.lock); + + return index; +} + +static int ecdsa_sign_stub(struct expbuf_t *buf) +{ + unsigned char *m, sigret[4096]; + size_t type, m_len, key_index; + EC_KEY *ec_key; + unsigned siglen = 0; + int ret; + + if (expbuf_shift_num(buf, &type) != 0 || (m = expbuf_shift_bytes(buf, &m_len)) == NULL || + expbuf_shift_num(buf, &key_index) != 0) { + errno = 0; + warnf("%s: failed to parse request", __FUNCTION__); + return -1; + } + if ((ec_key = daemon_get_ecdsa(key_index)) == NULL) { + errno = 0; + warnf("%s: invalid key index:%zu", __FUNCTION__, key_index); + return -1; + } + + ret = ECDSA_sign((int)type, m, (unsigned)m_len, sigret, &siglen, ec_key); + expbuf_dispose(buf); + + EC_KEY_free(ec_key); + + expbuf_push_num(buf, ret); + expbuf_push_bytes(buf, sigret, ret == 1 ? siglen : 0); + + return 0; +} + +static void ecdsa_get_privsep_data(const EC_KEY *ec_key, struct st_neverbleed_rsa_exdata_t **exdata, + struct st_neverbleed_thread_data_t **thdata) +{ + *exdata = EC_KEY_get_ex_data(ec_key, 0); + if (*exdata == NULL) { + errno = 0; + dief("invalid internal ref"); + } + *thdata = get_thread_data((*exdata)->nb); +} + +static int ecdsa_sign_proxy(int type, const unsigned char *m, int m_len, unsigned char *_sigret, unsigned int *_siglen, + const BIGNUM *kinv, const BIGNUM *rp, EC_KEY *ec_key) +{ + struct st_neverbleed_rsa_exdata_t *exdata; + struct st_neverbleed_thread_data_t *thdata; + struct expbuf_t buf = {}; + size_t ret, siglen; + unsigned char *sigret; + + ecdsa_get_privsep_data(ec_key, &exdata, &thdata); + + /* as far as I've tested so far, kinv and rp are always NULL. + Looks like setup_sign will precompute this, but it is only + called sign_sig, and it seems to be not used in TLS ECDSA */ + if (kinv != NULL || rp != NULL) { + errno = 0; + dief("unexpected non-NULL kinv and rp"); + } + + expbuf_push_str(&buf, "ecdsa_sign"); + expbuf_push_num(&buf, type); + expbuf_push_bytes(&buf, m, m_len); + expbuf_push_num(&buf, exdata->key_index); + if (expbuf_write(&buf, thdata->fd) != 0) + dief(errno != 0 ? "write error" : "connection closed by daemon"); + expbuf_dispose(&buf); + + if (expbuf_read(&buf, thdata->fd) != 0) + dief(errno != 0 ? "read error" : "connection closed by daemon"); + if (expbuf_shift_num(&buf, &ret) != 0 || (sigret = expbuf_shift_bytes(&buf, &siglen)) == NULL) { + errno = 0; + dief("failed to parse response"); + } + memcpy(_sigret, sigret, siglen); + *_siglen = (unsigned)siglen; + expbuf_dispose(&buf); + + return (int)ret; +} + +static EVP_PKEY *ecdsa_create_pkey(neverbleed_t *nb, size_t key_index, int curve_name, const char *ec_pubkeybuf) +{ + struct st_neverbleed_rsa_exdata_t *exdata; + EC_KEY *ec_key; + EC_GROUP *ec_group; + BIGNUM *ec_pubkeybn = NULL; + EC_POINT *ec_pubkey; + EVP_PKEY *pkey; + + if ((exdata = malloc(sizeof(*exdata))) == NULL) { + fprintf(stderr, "no memory\n"); + abort(); + } + exdata->nb = nb; + exdata->key_index = key_index; + + ec_key = EC_KEY_new_method(nb->engine); + EC_KEY_set_ex_data(ec_key, 0, exdata); + + ec_group = EC_GROUP_new_by_curve_name(curve_name); + if (!ec_group) { + fprintf(stderr, "could not create EC_GROUP\n"); + abort(); + } + + EC_KEY_set_group(ec_key, ec_group); + + if (BN_hex2bn(&ec_pubkeybn, ec_pubkeybuf) == 0) { + fprintf(stderr, "failed to parse ECDSA ephemeral public key:%s\n", ec_pubkeybuf); + abort(); + } + + if ((ec_pubkey = EC_POINT_bn2point(ec_group, ec_pubkeybn, NULL, NULL)) == NULL) { + fprintf(stderr, "failed to get ECDSA ephemeral public key from BIGNUM\n"); + abort(); + } + + EC_KEY_set_public_key(ec_key, ec_pubkey); + + pkey = EVP_PKEY_new(); + EVP_PKEY_set1_EC_KEY(pkey, ec_key); + + EC_POINT_free(ec_pubkey); + BN_free(ec_pubkeybn); + EC_GROUP_free(ec_group); + EC_KEY_free(ec_key); + + return pkey; +} + +static void priv_ecdsa_finish(EC_KEY *key) +{ + struct st_neverbleed_rsa_exdata_t *exdata; + struct st_neverbleed_thread_data_t *thdata; + + ecdsa_get_privsep_data(key, &exdata, &thdata); + + struct expbuf_t buf = {NULL}; + size_t ret; + + expbuf_push_str(&buf, "del_ecdsa_key"); + expbuf_push_num(&buf, exdata->key_index); + if (expbuf_write(&buf, thdata->fd) != 0) + dief(errno != 0 ? "write error" : "connection closed by daemon"); + expbuf_dispose(&buf); + + if (expbuf_read(&buf, thdata->fd) != 0) + dief(errno != 0 ? "read error" : "connection closed by daemon"); + if (expbuf_shift_num(&buf, &ret) != 0) { + errno = 0; + dief("failed to parse response"); + } + expbuf_dispose(&buf); +} + +static int del_ecdsa_key_stub(struct expbuf_t *buf) +{ + size_t key_index; + int ret = 0; + + if (expbuf_shift_num(buf, &key_index) != 0) { + errno = 0; + warnf("%s: failed to parse request", __FUNCTION__); + return -1; + } + + if (!daemon_vars.keys.ecdsa_keys || key_index >= daemon_vars.keys.ecdsa_slots.reserved_size) { + errno = 0; + warnf("%s: invalid key index %zu", __FUNCTION__, key_index); + goto respond; + } + + if (BITCHECK(daemon_vars.keys.ecdsa_slots.bita_avail, key_index)) { + warnf("%s: index not in use %zu", __FUNCTION__, key_index); + goto respond; + } + + pthread_mutex_lock(&daemon_vars.keys.lock); + /* set slot as available */ + BITSET(daemon_vars.keys.ecdsa_slots.bita_avail, key_index); + daemon_vars.keys.ecdsa_slots.size--; + EC_KEY_free(daemon_vars.keys.ecdsa_keys[key_index]); + daemon_vars.keys.ecdsa_keys[key_index] = NULL; + pthread_mutex_unlock(&daemon_vars.keys.lock); + + ret = 1; + +respond: + expbuf_dispose(buf); + expbuf_push_num(buf, ret); + return 0; +} + +#endif + +int neverbleed_load_private_key_file(neverbleed_t *nb, SSL_CTX *ctx, const char *fn, char *errbuf) +{ + struct st_neverbleed_thread_data_t *thdata = get_thread_data(nb); + struct expbuf_t buf = {NULL}; + int ret = 1; + size_t index, type; + EVP_PKEY *pkey; + + expbuf_push_str(&buf, "load_key"); + expbuf_push_str(&buf, fn); + if (expbuf_write(&buf, thdata->fd) != 0) + dief(errno != 0 ? "write error" : "connection closed by daemon"); + expbuf_dispose(&buf); + + if (expbuf_read(&buf, thdata->fd) != 0) + dief(errno != 0 ? "read error" : "connection closed by daemon"); + if (expbuf_shift_num(&buf, &type) != 0 || expbuf_shift_num(&buf, &index) != 0) { + errno = 0; + dief("failed to parse response"); + } + + switch (type) { + case NEVERBLEED_TYPE_RSA: { + char *estr, *nstr; + + if ((estr = expbuf_shift_str(&buf)) == NULL || (nstr = expbuf_shift_str(&buf)) == NULL) { + errno = 0; + dief("failed to parse response"); + } + pkey = create_pkey(nb, index, estr, nstr); + break; + } +#if OPENSSL_1_1_API + case NEVERBLEED_TYPE_ECDSA: { + char *ec_pubkeystr; + size_t curve_name; + + if (expbuf_shift_num(&buf, &curve_name) != 0 || (ec_pubkeystr = expbuf_shift_str(&buf)) == NULL) { + errno = 0; + dief("failed to parse response"); + } + pkey = ecdsa_create_pkey(nb, index, curve_name, ec_pubkeystr); + break; + } +#endif + default: { + char *errstr; + + if ((errstr = expbuf_shift_str(&buf)) == NULL) { + errno = 0; + dief("failed to parse response"); + } + + snprintf(errbuf, NEVERBLEED_ERRBUF_SIZE, "%s", errstr); + return -1; + } + } + + expbuf_dispose(&buf); + + /* success */ + if (SSL_CTX_use_PrivateKey(ctx, pkey) != 1) { + snprintf(errbuf, NEVERBLEED_ERRBUF_SIZE, "SSL_CTX_use_PrivateKey failed"); + ret = 0; + } + + EVP_PKEY_free(pkey); + return ret; +} + +static int load_key_stub(struct expbuf_t *buf) +{ + char *fn; + FILE *fp = NULL; + RSA *rsa = NULL; + size_t key_index = SIZE_MAX; + char *estr = NULL, *nstr = NULL, errbuf[NEVERBLEED_ERRBUF_SIZE] = ""; + size_t type = NEVERBLEED_TYPE_ERROR; + EVP_PKEY *pkey = NULL; + const EC_GROUP *ec_group; + BIGNUM *ec_pubkeybn = NULL; + char *ec_pubkeystr = NULL; + + if ((fn = expbuf_shift_str(buf)) == NULL) { + warnf("%s: failed to parse request", __FUNCTION__); + return -1; + } + + if ((fp = fopen(fn, "rt")) == NULL) { + strerror_r(errno, errbuf, sizeof(errbuf)); + goto Respond; + } + + if ((pkey = PEM_read_PrivateKey(fp, NULL, NULL, NULL)) == NULL) { + snprintf(errbuf, sizeof(errbuf), "failed to parse the private key"); + goto Respond; + } + + switch (EVP_PKEY_base_id(pkey)) { + case EVP_PKEY_RSA: { + const BIGNUM *e, *n; + + rsa = EVP_PKEY_get1_RSA(pkey); + type = NEVERBLEED_TYPE_RSA; + key_index = daemon_set_rsa(rsa); + RSA_get0_key(rsa, &n, &e, NULL); + estr = BN_bn2hex(e); + nstr = BN_bn2hex(n); + break; + } + case EVP_PKEY_EC: { +#if OPENSSL_1_1_API + const EC_POINT *ec_pubkey; + EC_KEY *ec_key; + + ec_key = EVP_PKEY_get0_EC_KEY(pkey); + type = NEVERBLEED_TYPE_ECDSA; + key_index = daemon_set_ecdsa(ec_key); + ec_group = EC_KEY_get0_group(ec_key); + ec_pubkey = EC_KEY_get0_public_key(ec_key); + ec_pubkeybn = BN_new(); + if (!EC_POINT_point2bn(ec_group, ec_pubkey, POINT_CONVERSION_COMPRESSED, ec_pubkeybn, NULL)) { + type = NEVERBLEED_TYPE_ERROR; + snprintf(errbuf, sizeof(errbuf), "failed to convert ECDSA public key to BIGNUM"); + goto Respond; + } + ec_pubkeystr = BN_bn2hex(ec_pubkeybn); + break; +#else + snprintf(errbuf, sizeof(errbuf), "ECDSA support requires OpenSSL >= 1.1.0"); + goto Respond; +#endif + } + default: + snprintf(errbuf, sizeof(errbuf), "unsupported private key: %d", EVP_PKEY_base_id(pkey)); + goto Respond; + } + +Respond: + expbuf_dispose(buf); + expbuf_push_num(buf, type); + expbuf_push_num(buf, key_index); + switch (type) { + case NEVERBLEED_TYPE_RSA: + expbuf_push_str(buf, estr != NULL ? estr : ""); + expbuf_push_str(buf, nstr != NULL ? nstr : ""); + break; + case NEVERBLEED_TYPE_ECDSA: + expbuf_push_num(buf, EC_GROUP_get_curve_name(ec_group)); + expbuf_push_str(buf, ec_pubkeystr); + break; + default: + expbuf_push_str(buf, errbuf); + } + if (rsa != NULL) + RSA_free(rsa); + if (pkey != NULL) + EVP_PKEY_free(pkey); + if (estr != NULL) + OPENSSL_free(estr); + if (nstr != NULL) + OPENSSL_free(nstr); + if (ec_pubkeystr != NULL) + OPENSSL_free(ec_pubkeystr); + if (ec_pubkeybn != NULL) + BN_free(ec_pubkeybn); + if (fp != NULL) + fclose(fp); + + return 0; +} + +int neverbleed_setuidgid(neverbleed_t *nb, const char *user, int change_socket_ownership) +{ + struct st_neverbleed_thread_data_t *thdata = get_thread_data(nb); + struct expbuf_t buf = {NULL}; + size_t ret; + + expbuf_push_str(&buf, "setuidgid"); + expbuf_push_str(&buf, user); + expbuf_push_num(&buf, change_socket_ownership); + if (expbuf_write(&buf, thdata->fd) != 0) + dief(errno != 0 ? "write error" : "connection closed by daemon"); + expbuf_dispose(&buf); + + if (expbuf_read(&buf, thdata->fd) != 0) + dief(errno != 0 ? "read error" : "connection closed by daemon"); + if (expbuf_shift_num(&buf, &ret) != 0) { + errno = 0; + dief("failed to parse response"); + } + expbuf_dispose(&buf); + + return (int)ret; +} + +static int setuidgid_stub(struct expbuf_t *buf) +{ + const char *user; + size_t change_socket_ownership; + struct passwd pwbuf, *pw; + char pwstrbuf[65536]; /* should be large enough */ + int ret = -1; + + if ((user = expbuf_shift_str(buf)) == NULL || expbuf_shift_num(buf, &change_socket_ownership) != 0) { + errno = 0; + warnf("%s: failed to parse request", __FUNCTION__); + return -1; + } + + errno = 0; + if (getpwnam_r(user, &pwbuf, pwstrbuf, sizeof(pwstrbuf), &pw) != 0) { + warnf("%s: getpwnam_r failed", __FUNCTION__); + goto Respond; + } + if (pw == NULL) { + warnf("%s: failed to obtain information of user:%s", __FUNCTION__, user); + goto Respond; + } + + if (change_socket_ownership) { + char *dir; + if (chown(daemon_vars.nb->sun_.sun_path, pw->pw_uid, pw->pw_gid) != 0) + dief("chown failed for:%s", daemon_vars.nb->sun_.sun_path); + dir = dirname(daemon_vars.nb->sun_.sun_path); + if (chown(dir, pw->pw_uid, pw->pw_gid) != 0) + dief("chown failed for:%s", dir); + free(dir); + } + + /* setuidgid */ + if (setgid(pw->pw_gid) != 0) { + warnf("%s: setgid(%d) failed", __FUNCTION__, (int)pw->pw_gid); + goto Respond; + } + if (initgroups(pw->pw_name, pw->pw_gid) != 0) { + warnf("%s: initgroups(%s, %d) failed", __FUNCTION__, pw->pw_name, (int)pw->pw_gid); + goto Respond; + } + if (setuid(pw->pw_uid) != 0) { + warnf("%s: setuid(%d) failed\n", __FUNCTION__, (int)pw->pw_uid); + goto Respond; + } + ret = 0; + +Respond: + expbuf_dispose(buf); + expbuf_push_num(buf, ret); + return 0; +} + +__attribute__((noreturn)) static void *daemon_close_notify_thread(void *_close_notify_fd) +{ + int close_notify_fd = (int)((char *)_close_notify_fd - (char *)NULL); + char b; + ssize_t r; + +Redo: + r = read(close_notify_fd, &b, 1); + if (r == -1 && errno == EINTR) + goto Redo; + if (r > 0) + goto Redo; + /* close or error */ + + /* unlink the temporary directory and socket file */ + unlink_dir(dirname(daemon_vars.nb->sun_.sun_path)); + + _exit(0); +} + +static int priv_rsa_finish(RSA *rsa) +{ + struct st_neverbleed_rsa_exdata_t *exdata; + struct st_neverbleed_thread_data_t *thdata; + + get_privsep_data(rsa, &exdata, &thdata); + + struct expbuf_t buf = {NULL}; + size_t ret; + + expbuf_push_str(&buf, "del_rsa_key"); + expbuf_push_num(&buf, exdata->key_index); + if (expbuf_write(&buf, thdata->fd) != 0) + dief(errno != 0 ? "write error" : "connection closed by daemon"); + expbuf_dispose(&buf); + + if (expbuf_read(&buf, thdata->fd) != 0) + dief(errno != 0 ? "read error" : "connection closed by daemon"); + if (expbuf_shift_num(&buf, &ret) != 0) { + errno = 0; + dief("failed to parse response"); + } + expbuf_dispose(&buf); + + return (int)ret; +} + +static int del_rsa_key_stub(struct expbuf_t *buf) +{ + size_t key_index; + + int ret = 0; + + if (expbuf_shift_num(buf, &key_index) != 0) { + errno = 0; + warnf("%s: failed to parse request", __FUNCTION__); + return -1; + } + + if (!daemon_vars.keys.keys || key_index >= daemon_vars.keys.rsa_slots.reserved_size) { + errno = 0; + warnf("%s: invalid key index %zu", __FUNCTION__, key_index); + goto respond; + } + + if (BITCHECK(daemon_vars.keys.rsa_slots.bita_avail, key_index)) { + warnf("%s: index not in use %zu", __FUNCTION__, key_index); + goto respond; + } + + pthread_mutex_lock(&daemon_vars.keys.lock); + /* set slot as available */ + BITSET(daemon_vars.keys.rsa_slots.bita_avail, key_index); + daemon_vars.keys.rsa_slots.size--; + RSA_free(daemon_vars.keys.keys[key_index]); + daemon_vars.keys.keys[key_index] = NULL; + pthread_mutex_unlock(&daemon_vars.keys.lock); + + ret = 1; + +respond: + expbuf_dispose(buf); + expbuf_push_num(buf, ret); + return 0; +} + +static void *daemon_conn_thread(void *_sock_fd) +{ + int sock_fd = (int)((char *)_sock_fd - (char *)NULL); + struct expbuf_t buf = {NULL}; + unsigned char auth_token[NEVERBLEED_AUTH_TOKEN_SIZE]; + + /* authenticate */ + if (read_nbytes(sock_fd, &auth_token, sizeof(auth_token)) != 0) { + warnf("failed to receive authencication token from client"); + goto Exit; + } + if (memcmp(auth_token, daemon_vars.nb->auth_token, NEVERBLEED_AUTH_TOKEN_SIZE) != 0) { + warnf("client authentication failed"); + goto Exit; + } + + while (1) { + char *cmd; + if (expbuf_read(&buf, sock_fd) != 0) { + if (errno != 0) + warnf("read error"); + break; + } + if ((cmd = expbuf_shift_str(&buf)) == NULL) { + errno = 0; + warnf("failed to parse request"); + break; + } + if (strcmp(cmd, "priv_enc") == 0) { + if (priv_enc_stub(&buf) != 0) + break; + } else if (strcmp(cmd, "priv_dec") == 0) { + if (priv_dec_stub(&buf) != 0) + break; + } else if (strcmp(cmd, "sign") == 0) { + if (sign_stub(&buf) != 0) + break; +#if OPENSSL_1_1_API + } else if (strcmp(cmd, "ecdsa_sign") == 0) { + if (ecdsa_sign_stub(&buf) != 0) + break; + } else if (strcmp(cmd, "del_ecdsa_key") == 0) { + if (del_ecdsa_key_stub(&buf) != 0) + break; +#endif + } else if (strcmp(cmd, "load_key") == 0) { + if (load_key_stub(&buf) != 0) + break; + } else if (strcmp(cmd, "del_rsa_key") == 0) { + if (del_rsa_key_stub(&buf) != 0) + break; + } else if (strcmp(cmd, "setuidgid") == 0) { + if (setuidgid_stub(&buf) != 0) + break; + } else { + warnf("unknown command:%s", cmd); + break; + } + if (expbuf_write(&buf, sock_fd) != 0) { + warnf(errno != 0 ? "write error" : "connection closed by client"); + break; + } + expbuf_dispose(&buf); + } + +Exit: + expbuf_dispose(&buf); + close(sock_fd); + + return NULL; +} + +__attribute__((noreturn)) static void daemon_main(int listen_fd, int close_notify_fd, const char *tempdir) +{ + pthread_t tid; + pthread_attr_t thattr; + int sock_fd; + + { /* close all descriptors (except STDIN, STDOUT, STRERR, listen_fd, close_notify_fd) */ + int fd = (int)sysconf(_SC_OPEN_MAX) - 1; + for (; fd > 2; --fd) { + if (fd == listen_fd || fd == close_notify_fd) + continue; + close(fd); + } + } + + pthread_attr_init(&thattr); + pthread_attr_setdetachstate(&thattr, 1); + + if (pthread_create(&tid, &thattr, daemon_close_notify_thread, (char *)NULL + close_notify_fd) != 0) + dief("pthread_create failed"); + + while (1) { + while ((sock_fd = accept(listen_fd, NULL, NULL)) == -1) + ; + if (pthread_create(&tid, &thattr, daemon_conn_thread, (char *)NULL + sock_fd) != 0) + dief("pthread_create failed"); + } +} + +#if !OPENSSL_1_1_API + +static RSA_METHOD static_rsa_method = { + "privsep RSA method", /* name */ + NULL, /* rsa_pub_enc */ + NULL, /* rsa_pub_dec */ + priv_enc_proxy, /* rsa_priv_enc */ + priv_dec_proxy, /* rsa_priv_dec */ + NULL, /* rsa_mod_exp */ + NULL, /* bn_mod_exp */ + NULL, /* init */ + priv_rsa_finish, /* finish */ + RSA_FLAG_SIGN_VER, /* flags */ + NULL, /* app data */ + sign_proxy, /* rsa_sign */ + NULL, /* rsa_verify */ + NULL /* rsa_keygen */ +}; + +#endif + +int neverbleed_init(neverbleed_t *nb, char *errbuf) +{ + int pipe_fds[2] = {-1, -1}, listen_fd = -1; + char *tempdir = NULL; +#if OPENSSL_1_1_API + const RSA_METHOD *default_method = RSA_PKCS1_OpenSSL(); + EC_KEY_METHOD *ecdsa_method; + const EC_KEY_METHOD *ecdsa_default_method; + RSA_METHOD *rsa_method = RSA_meth_new("privsep RSA method", 0); + + RSA_meth_set_priv_enc(rsa_method, priv_enc_proxy); + RSA_meth_set_priv_dec(rsa_method, priv_dec_proxy); + RSA_meth_set_sign(rsa_method, sign_proxy); + + RSA_meth_set_pub_enc(rsa_method, RSA_meth_get_pub_enc(default_method)); + RSA_meth_set_pub_dec(rsa_method, RSA_meth_get_pub_dec(default_method)); + RSA_meth_set_verify(rsa_method, RSA_meth_get_verify(default_method)); + + RSA_meth_set_finish(rsa_method, priv_rsa_finish); + + /* setup EC_KEY_METHOD for ECDSA */ + ecdsa_default_method = EC_KEY_get_default_method(); + ecdsa_method = EC_KEY_METHOD_new(ecdsa_default_method); + + EC_KEY_METHOD_set_keygen(ecdsa_method, NULL); + EC_KEY_METHOD_set_compute_key(ecdsa_method, NULL); + /* it seems sign_sig and sign_setup is not used in TLS ECDSA. */ + EC_KEY_METHOD_set_sign(ecdsa_method, ecdsa_sign_proxy, NULL, NULL); + EC_KEY_METHOD_set_init(ecdsa_method, NULL, priv_ecdsa_finish, NULL, NULL, NULL, NULL); +#else + const RSA_METHOD *default_method = RSA_PKCS1_SSLeay(); + RSA_METHOD *rsa_method = &static_rsa_method; + + rsa_method->rsa_pub_enc = default_method->rsa_pub_enc; + rsa_method->rsa_pub_dec = default_method->rsa_pub_dec; + rsa_method->rsa_verify = default_method->rsa_verify; +#endif + + /* setup the daemon */ + if (pipe(pipe_fds) != 0) { + snprintf(errbuf, NEVERBLEED_ERRBUF_SIZE, "pipe(2) failed:%s", strerror(errno)); + goto Fail; + } + set_cloexec(pipe_fds[1]); + if ((tempdir = strdup("/tmp/openssl-privsep.XXXXXX")) == NULL) { + snprintf(errbuf, NEVERBLEED_ERRBUF_SIZE, "no memory"); + goto Fail; + } + if (mkdtemp(tempdir) == NULL) { + snprintf(errbuf, NEVERBLEED_ERRBUF_SIZE, "failed to create temporary directory under /tmp:%s", strerror(errno)); + goto Fail; + } + memset(&nb->sun_, 0, sizeof(nb->sun_)); + nb->sun_.sun_family = AF_UNIX; + snprintf(nb->sun_.sun_path, sizeof(nb->sun_.sun_path), "%s/_", tempdir); + RAND_bytes(nb->auth_token, sizeof(nb->auth_token)); + if ((listen_fd = socket(PF_UNIX, SOCK_STREAM, 0)) == -1) { + snprintf(errbuf, NEVERBLEED_ERRBUF_SIZE, "socket(2) failed:%s", strerror(errno)); + goto Fail; + } + if (bind(listen_fd, (void *)&nb->sun_, sizeof(nb->sun_)) != 0) { + snprintf(errbuf, NEVERBLEED_ERRBUF_SIZE, "failed to bind to %s:%s", nb->sun_.sun_path, strerror(errno)); + goto Fail; + } + if (listen(listen_fd, SOMAXCONN) != 0) { + snprintf(errbuf, NEVERBLEED_ERRBUF_SIZE, "listen(2) failed:%s", strerror(errno)); + goto Fail; + } + nb->daemon_pid = fork(); + switch (nb->daemon_pid) { + case -1: + snprintf(errbuf, NEVERBLEED_ERRBUF_SIZE, "fork(2) failed:%s", strerror(errno)); + goto Fail; + case 0: + close(pipe_fds[1]); +#ifdef __linux__ + prctl(PR_SET_DUMPABLE, 0, 0, 0, 0); +#endif + daemon_vars.nb = nb; + daemon_main(listen_fd, pipe_fds[0], tempdir); + break; + default: + break; + } + close(listen_fd); + listen_fd = -1; + close(pipe_fds[0]); + pipe_fds[0] = -1; + + /* setup engine */ + if ((nb->engine = ENGINE_new()) == NULL || !ENGINE_set_id(nb->engine, "neverbleed") || + !ENGINE_set_name(nb->engine, "privilege separation software engine") || !ENGINE_set_RSA(nb->engine, rsa_method) +#if OPENSSL_1_1_API + || !ENGINE_set_EC(nb->engine, ecdsa_method) +#endif + ) { + snprintf(errbuf, NEVERBLEED_ERRBUF_SIZE, "failed to initialize the OpenSSL engine"); + goto Fail; + } + ENGINE_add(nb->engine); + + /* setup thread key */ + pthread_key_create(&nb->thread_key, dispose_thread_data); + + free(tempdir); + return 0; +Fail: + if (pipe_fds[0] != -1) + close(pipe_fds[0]); + if (pipe_fds[1] != -1) + close(pipe_fds[1]); + if (tempdir != NULL) { + unlink_dir(tempdir); + free(tempdir); + } + if (listen_fd != -1) + close(listen_fd); + if (nb->engine != NULL) { + ENGINE_free(nb->engine); + nb->engine = NULL; + } + return -1; +} diff --git a/web/server/h2o/libh2o/deps/neverbleed/neverbleed.h b/web/server/h2o/libh2o/deps/neverbleed/neverbleed.h new file mode 100644 index 00000000..4abfad47 --- /dev/null +++ b/web/server/h2o/libh2o/deps/neverbleed/neverbleed.h @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2015 Kazuho Oku, DeNA Co., Ltd. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ +#ifndef NEVERBLEED_H +#define NEVERBLEED_H + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define NEVERBLEED_ERRBUF_SIZE (256) +#define NEVERBLEED_AUTH_TOKEN_SIZE 32 + +typedef struct st_neverbleed_t { + ENGINE *engine; + pid_t daemon_pid; + struct sockaddr_un sun_; + pthread_key_t thread_key; + unsigned char auth_token[NEVERBLEED_AUTH_TOKEN_SIZE]; +} neverbleed_t; + +/** + * initializes the privilege separation engine (returns 0 if successful) + */ +int neverbleed_init(neverbleed_t *nb, char *errbuf); +/** + * loads a private key file (returns 1 if successful) + */ +int neverbleed_load_private_key_file(neverbleed_t *nb, SSL_CTX *ctx, const char *fn, char *errbuf); +/** + * setuidgid (also changes the file permissions so that `user` can connect to the daemon, if change_socket_ownership is non-zero) + */ +int neverbleed_setuidgid(neverbleed_t *nb, const char *user, int change_socket_ownership); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/web/server/h2o/libh2o/deps/neverbleed/test.c b/web/server/h2o/libh2o/deps/neverbleed/test.c new file mode 100644 index 00000000..494fc65f --- /dev/null +++ b/web/server/h2o/libh2o/deps/neverbleed/test.c @@ -0,0 +1,149 @@ +/* + * Copyright (c) 2015 Kazuho Oku, DeNA Co., Ltd. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include "neverbleed.h" + +static void setup_ecc_key(SSL_CTX *ssl_ctx) +{ + int nid = NID_X9_62_prime256v1; + EC_KEY *key = EC_KEY_new_by_curve_name(nid); + if (key == NULL) { + fprintf(stderr, "Failed to create curve \"%s\"\n", OBJ_nid2sn(nid)); + return; + } + SSL_CTX_set_tmp_ecdh(ssl_ctx, key); + EC_KEY_free(key); +} + +int dumb_https_server(unsigned short port, SSL_CTX *ctx) +{ + int listen_fd, reuse_flag; + struct sockaddr_in sin = {}; + + if ((listen_fd = socket(AF_INET, SOCK_STREAM, 0)) == -1) { + fprintf(stderr, "failed to create socket:%s\n", strerror(errno)); + return 111; + } + reuse_flag = 1; + setsockopt(listen_fd, SOL_SOCKET, SO_REUSEADDR, &reuse_flag, sizeof(reuse_flag)); + sin.sin_family = AF_INET; + sin.sin_addr.s_addr = htonl(0x7f000001); + sin.sin_port = htons(8888); + if (bind(listen_fd, (void *)&sin, sizeof(sin)) != 0) { + fprintf(stderr, "bind failed:%s\n", strerror(errno)); + return 111; + } + if (listen(listen_fd, SOMAXCONN) != 0) { + fprintf(stderr, "listen failed:%s\n", strerror(errno)); + return 111; + } + + while (1) { + int conn_fd; + SSL *ssl; + char buf[4096]; + /* accept connection */ + while ((conn_fd = accept(listen_fd, NULL, NULL)) == -1 && errno == EINTR) + ; + if (conn_fd == -1) { + fprintf(stderr, "accept(2) failed:%s\n", strerror(errno)); + return 111; + } + ssl = SSL_new(ctx); + SSL_set_fd(ssl, conn_fd); + if (SSL_accept(ssl) == 1) { + SSL_read(ssl, buf, sizeof(buf)); + const char *resp = + "HTTP/1.0 200 OK\r\nContent-Length: 6\r\nConnection: close\r\nContent-Type: text/plain\r\n\r\nhello\n"; + SSL_write(ssl, resp, strlen(resp)); + SSL_shutdown(ssl); + } else { + fprintf(stderr, "SSL_accept failed\n"); + } + SSL_free(ssl); + close(conn_fd); + } +} + +int main(int argc, char **argv) +{ + unsigned short port; + SSL_CTX *ctx; + neverbleed_t nb; + char errbuf[NEVERBLEED_ERRBUF_SIZE]; + int use_privsep; + + /* initialization */ + SSL_load_error_strings(); + SSL_library_init(); + OpenSSL_add_all_algorithms(); + if (neverbleed_init(&nb, errbuf) != 0) { + fprintf(stderr, "openssl_privsep_init: %s\n", errbuf); + return 111; + } + ctx = SSL_CTX_new(SSLv23_server_method()); + SSL_CTX_set_options(ctx, SSL_OP_ALL | SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 | SSL_OP_NO_COMPRESSION); + setup_ecc_key(ctx); + + /* parse args */ + if (argc != 5) { + fprintf(stderr, "Usage: %s \n", argv[0]); + return 111; + } + if (strcmp(argv[1], "internal") == 0) { + use_privsep = 0; + } else if (strcmp(argv[1], "privsep") == 0) { + use_privsep = 1; + } else { + fprintf(stderr, "unknown mode:%s\n", argv[1]); + return 111; + } + if (sscanf(argv[2], "%hu", &port) != 1) { + fprintf(stderr, "failed to parse port:%s\n", argv[2]); + return 111; + } + if (SSL_CTX_use_certificate_chain_file(ctx, argv[3]) != 1) { + fprintf(stderr, "failed to load certificate chain file:%s\n", argv[3]); + return 111; + } + if (use_privsep) { + if (neverbleed_load_private_key_file(&nb, ctx, argv[4], errbuf) != 1) { + fprintf(stderr, "failed to load private key from file:%s:%s\n", argv[4], errbuf); + return 111; + } + } else { + if (SSL_CTX_use_PrivateKey_file(ctx, argv[4], SSL_FILETYPE_PEM) != 1) { + fprintf(stderr, "failed to load private key from file:%s\n", argv[4]); + return 111; + } + } + + /* start the httpd */ + return dumb_https_server(port, ctx); +} diff --git a/web/server/h2o/libh2o/deps/picohttpparser/.clang-format b/web/server/h2o/libh2o/deps/picohttpparser/.clang-format new file mode 100644 index 00000000..9640123c --- /dev/null +++ b/web/server/h2o/libh2o/deps/picohttpparser/.clang-format @@ -0,0 +1,7 @@ +# requires clang-format >= 3.6 +BasedOnStyle: "LLVM" +IndentWidth: 4 +ColumnLimit: 132 +BreakBeforeBraces: Linux +AllowShortFunctionsOnASingleLine: None +SortIncludes: false diff --git a/web/server/h2o/libh2o/deps/picohttpparser/.gitattributes b/web/server/h2o/libh2o/deps/picohttpparser/.gitattributes new file mode 100644 index 00000000..03d9eec3 --- /dev/null +++ b/web/server/h2o/libh2o/deps/picohttpparser/.gitattributes @@ -0,0 +1 @@ +picohttpparser.* ident diff --git a/web/server/h2o/libh2o/deps/picohttpparser/.gitmodules b/web/server/h2o/libh2o/deps/picohttpparser/.gitmodules new file mode 100644 index 00000000..e1434dac --- /dev/null +++ b/web/server/h2o/libh2o/deps/picohttpparser/.gitmodules @@ -0,0 +1,3 @@ +[submodule "picotest"] + path = picotest + url = https://github.com/h2o/picotest.git diff --git a/web/server/h2o/libh2o/deps/picohttpparser/.travis.yml b/web/server/h2o/libh2o/deps/picohttpparser/.travis.yml new file mode 100644 index 00000000..78af54bc --- /dev/null +++ b/web/server/h2o/libh2o/deps/picohttpparser/.travis.yml @@ -0,0 +1,6 @@ +language: c +compiler: + - gcc + - clang +script: + - make test diff --git a/web/server/h2o/libh2o/deps/picohttpparser/Jamfile b/web/server/h2o/libh2o/deps/picohttpparser/Jamfile new file mode 100644 index 00000000..5acbe55d --- /dev/null +++ b/web/server/h2o/libh2o/deps/picohttpparser/Jamfile @@ -0,0 +1,7 @@ +project picohttpparser ; + +lib picohttpparser : picohttpparser.c ; + +unit-test test + : picohttpparser picotest/picotest.c test.c + : prove ; diff --git a/web/server/h2o/libh2o/deps/picohttpparser/Makefile b/web/server/h2o/libh2o/deps/picohttpparser/Makefile new file mode 100644 index 00000000..9e42298d --- /dev/null +++ b/web/server/h2o/libh2o/deps/picohttpparser/Makefile @@ -0,0 +1,40 @@ +# +# Copyright (c) 2009-2014 Kazuho Oku, Tokuhiro Matsuno, Daisuke Murase, +# Shigeo Mitsunari +# +# The software is licensed under either the MIT License (below) or the Perl +# license. +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to +# deal in the Software without restriction, including without limitation the +# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +# sell copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +# IN THE SOFTWARE. + +CC?=gcc +PROVE?=prove + +all: + +test: test-bin + $(PROVE) -v ./test-bin + +test-bin: picohttpparser.c picotest/picotest.c test.c + $(CC) -Wall $(CFLAGS) $(LDFLAGS) -o $@ $^ + +clean: + rm -f test-bin + +.PHONY: test diff --git a/web/server/h2o/libh2o/deps/picohttpparser/README.md b/web/server/h2o/libh2o/deps/picohttpparser/README.md new file mode 100644 index 00000000..cb32f58e --- /dev/null +++ b/web/server/h2o/libh2o/deps/picohttpparser/README.md @@ -0,0 +1,116 @@ +PicoHTTPParser +============= + +Copyright (c) 2009-2014 [Kazuho Oku](https://github.com/kazuho), [Tokuhiro Matsuno](https://github.com/tokuhirom), [Daisuke Murase](https://github.com/typester), [Shigeo Mitsunari](https://github.com/herumi) + +PicoHTTPParser is a tiny, primitive, fast HTTP request/response parser. + +Unlike most parsers, it is stateless and does not allocate memory by itself. +All it does is accept pointer to buffer and the output structure, and setups the pointers in the latter to point at the necessary portions of the buffer. + +The code is widely deployed within Perl applications through popular modules that use it, including [Plack](https://metacpan.org/pod/Plack), [Starman](https://metacpan.org/pod/Starman), [Starlet](https://metacpan.org/pod/Starlet), [Furl](https://metacpan.org/pod/Furl). It is also the HTTP/1 parser of [H2O](https://github.com/h2o/h2o). + +Check out [test.c] to find out how to use the parser. + +The software is dual-licensed under the Perl License or the MIT License. + +Usage +----- + +The library exposes four functions: `phr_parse_request`, `phr_parse_response`, `phr_parse_headers`, `phr_decode_chunked`. + +### phr_parse_request + +The example below reads an HTTP request from socket `sock` using `read(2)`, parses it using `phr_parse_request`, and prints the details. + +```c +char buf[4096], *method, *path; +int pret, minor_version; +struct phr_header headers[100]; +size_t buflen = 0, prevbuflen = 0, method_len, path_len, num_headers; +ssize_t rret; + +while (1) { + /* read the request */ + while ((rret = read(sock, buf + buflen, sizeof(buf) - buflen)) == -1 && errno == EINTR) + ; + if (rret <= 0) + return IOError; + prevbuflen = buflen; + buflen += rret; + /* parse the request */ + num_headers = sizeof(headers) / sizeof(headers[0]); + pret = phr_parse_request(buf, buflen, &method, &method_len, &path, &path_len, + &minor_version, headers, &num_headers, prevbuflen); + if (pret > 0) + break; /* successfully parsed the request */ + else if (pret == -1) + return ParseError; + /* request is incomplete, continue the loop */ + assert(pret == -2); + if (buflen == sizeof(buf)) + return RequestIsTooLongError; +} + +printf("request is %d bytes long\n", pret); +printf("method is %.*s\n", (int)method_len, method); +printf("path is %.*s\n", (int)path_len, path); +printf("HTTP version is 1.%d\n", minor_version); +printf("headers:\n"); +for (i = 0; i != num_headers; ++i) { + printf("%.*s: %.*s\n", (int)headers[i].name_len, headers[i].name, + (int)headers[i].value_len, headers[i].value); +} +``` + +### phr_parse_response, phr_parse_headers + +`phr_parse_response` and `phr_parse_headers` provide similar interfaces as `phr_parse_request`. `phr_parse_response` parses an HTTP response, and `phr_parse_headers` parses the headers only. + +### phr_decode_chunked + +The example below decodes incoming data in chunked-encoding. The data is decoded in-place. + +```c +struct phr_chunked_decoder decoder = {}; /* zero-clear */ +char *buf = malloc(4096); +size_t size = 0, capacity = 4096, rsize; +ssize_t rret, pret; + +/* set consume_trailer to 1 to discard the trailing header, or the application + * should call phr_parse_headers to parse the trailing header */ +decoder.consume_trailer = 1; + +do { + /* expand the buffer if necessary */ + if (size == capacity) { + capacity *= 2; + buf = realloc(buf, capacity); + assert(buf != NULL); + } + /* read */ + while ((rret = read(sock, buf + size, capacity - size)) == -1 && errno == EINTR) + ; + if (rret <= 0) + return IOError; + /* decode */ + rsize = rret; + pret = phr_decode_chunked(&decoder, buf + size, &rsize); + if (pret == -1) + return ParseError; + size += rsize; +} while (pret == -2); + +/* successfully decoded the chunked data */ +assert(pret >= 0); +printf("decoded data is at %p (%zu bytes)\n", buf, size); +``` + +Benchmark +--------- + +![benchmark results](http://i.gyazo.com/a85c18d3162dfb46b485bb41e0ad443a.png) + +The benchmark code is from [fukamachi/fast-http@6b91103](https://github.com/fukamachi/fast-http/tree/6b9110347c7a3407310c08979aefd65078518478). + +The internals of picohttpparser has been described to some extent in [my blog entry]( http://blog.kazuhooku.com/2014/11/the-internals-h2o-or-how-to-write-fast.html). diff --git a/web/server/h2o/libh2o/deps/picohttpparser/bench.c b/web/server/h2o/libh2o/deps/picohttpparser/bench.c new file mode 100644 index 00000000..8dec06c4 --- /dev/null +++ b/web/server/h2o/libh2o/deps/picohttpparser/bench.c @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2009-2014 Kazuho Oku, Tokuhiro Matsuno, Daisuke Murase, + * Shigeo Mitsunari + * + * The software is licensed under either the MIT License (below) or the Perl + * license. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include +#include +#include "picohttpparser.h" + +#define REQ \ + "GET /wp-content/uploads/2010/03/hello-kitty-darth-vader-pink.jpg HTTP/1.1\r\n" \ + "Host: www.kittyhell.com\r\n" \ + "User-Agent: Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.6; ja-JP-mac; rv:1.9.2.3) Gecko/20100401 Firefox/3.6.3 " \ + "Pathtraq/0.9\r\n" \ + "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n" \ + "Accept-Language: ja,en-us;q=0.7,en;q=0.3\r\n" \ + "Accept-Encoding: gzip,deflate\r\n" \ + "Accept-Charset: Shift_JIS,utf-8;q=0.7,*;q=0.7\r\n" \ + "Keep-Alive: 115\r\n" \ + "Connection: keep-alive\r\n" \ + "Cookie: wp_ozh_wsa_visits=2; wp_ozh_wsa_visit_lasttime=xxxxxxxxxx; " \ + "__utma=xxxxxxxxx.xxxxxxxxxx.xxxxxxxxxx.xxxxxxxxxx.xxxxxxxxxx.x; " \ + "__utmz=xxxxxxxxx.xxxxxxxxxx.x.x.utmccn=(referral)|utmcsr=reader.livedoor.com|utmcct=/reader/|utmcmd=referral\r\n" \ + "\r\n" + +int main(void) +{ + const char *method; + size_t method_len; + const char *path; + size_t path_len; + int minor_version; + struct phr_header headers[32]; + size_t num_headers; + int i, ret; + + for (i = 0; i < 10000000; i++) { + num_headers = sizeof(headers) / sizeof(headers[0]); + ret = phr_parse_request(REQ, sizeof(REQ) - 1, &method, &method_len, &path, &path_len, &minor_version, headers, &num_headers, + 0); + assert(ret == sizeof(REQ) - 1); + } + + return 0; +} diff --git a/web/server/h2o/libh2o/deps/picohttpparser/picohttpparser.c b/web/server/h2o/libh2o/deps/picohttpparser/picohttpparser.c new file mode 100644 index 00000000..a707070d --- /dev/null +++ b/web/server/h2o/libh2o/deps/picohttpparser/picohttpparser.c @@ -0,0 +1,620 @@ +/* + * Copyright (c) 2009-2014 Kazuho Oku, Tokuhiro Matsuno, Daisuke Murase, + * Shigeo Mitsunari + * + * The software is licensed under either the MIT License (below) or the Perl + * license. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include +#include +#include +#ifdef __SSE4_2__ +#ifdef _MSC_VER +#include +#else +#include +#endif +#endif +#include "picohttpparser.h" + +/* $Id$ */ + +#if __GNUC__ >= 3 +#define likely(x) __builtin_expect(!!(x), 1) +#define unlikely(x) __builtin_expect(!!(x), 0) +#else +#define likely(x) (x) +#define unlikely(x) (x) +#endif + +#ifdef _MSC_VER +#define ALIGNED(n) _declspec(align(n)) +#else +#define ALIGNED(n) __attribute__((aligned(n))) +#endif + +#define IS_PRINTABLE_ASCII(c) ((unsigned char)(c)-040u < 0137u) + +#define CHECK_EOF() \ + if (buf == buf_end) { \ + *ret = -2; \ + return NULL; \ + } + +#define EXPECT_CHAR_NO_CHECK(ch) \ + if (*buf++ != ch) { \ + *ret = -1; \ + return NULL; \ + } + +#define EXPECT_CHAR(ch) \ + CHECK_EOF(); \ + EXPECT_CHAR_NO_CHECK(ch); + +#define ADVANCE_TOKEN(tok, toklen) \ + do { \ + const char *tok_start = buf; \ + static const char ALIGNED(16) ranges2[] = "\000\040\177\177"; \ + int found2; \ + buf = findchar_fast(buf, buf_end, ranges2, sizeof(ranges2) - 1, &found2); \ + if (!found2) { \ + CHECK_EOF(); \ + } \ + while (1) { \ + if (*buf == ' ') { \ + break; \ + } else if (unlikely(!IS_PRINTABLE_ASCII(*buf))) { \ + if ((unsigned char)*buf < '\040' || *buf == '\177') { \ + *ret = -1; \ + return NULL; \ + } \ + } \ + ++buf; \ + CHECK_EOF(); \ + } \ + tok = tok_start; \ + toklen = buf - tok_start; \ + } while (0) + +static const char *token_char_map = "\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\0\0\0\0\0\0" + "\0\1\0\1\1\1\1\1\0\0\1\1\0\1\1\0\1\1\1\1\1\1\1\1\1\1\0\0\0\0\0\0" + "\0\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\0\0\0\1\1" + "\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\0\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\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\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\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\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"; + +static const char *findchar_fast(const char *buf, const char *buf_end, const char *ranges, size_t ranges_size, int *found) +{ + *found = 0; +#if __SSE4_2__ + if (likely(buf_end - buf >= 16)) { + __m128i ranges16 = _mm_loadu_si128((const __m128i *)ranges); + + size_t left = (buf_end - buf) & ~15; + do { + __m128i b16 = _mm_loadu_si128((const __m128i *)buf); + int r = _mm_cmpestri(ranges16, ranges_size, b16, 16, _SIDD_LEAST_SIGNIFICANT | _SIDD_CMP_RANGES | _SIDD_UBYTE_OPS); + if (unlikely(r != 16)) { + buf += r; + *found = 1; + break; + } + buf += 16; + left -= 16; + } while (likely(left != 0)); + } +#else + /* suppress unused parameter warning */ + (void)buf_end; + (void)ranges; + (void)ranges_size; +#endif + return buf; +} + +static const char *get_token_to_eol(const char *buf, const char *buf_end, const char **token, size_t *token_len, int *ret) +{ + const char *token_start = buf; + +#ifdef __SSE4_2__ + static const char ranges1[] = "\0\010" + /* allow HT */ + "\012\037" + /* allow SP and up to but not including DEL */ + "\177\177" + /* allow chars w. MSB set */ + ; + int found; + buf = findchar_fast(buf, buf_end, ranges1, sizeof(ranges1) - 1, &found); + if (found) + goto FOUND_CTL; +#else + /* find non-printable char within the next 8 bytes, this is the hottest code; manually inlined */ + while (likely(buf_end - buf >= 8)) { +#define DOIT() \ + do { \ + if (unlikely(!IS_PRINTABLE_ASCII(*buf))) \ + goto NonPrintable; \ + ++buf; \ + } while (0) + DOIT(); + DOIT(); + DOIT(); + DOIT(); + DOIT(); + DOIT(); + DOIT(); + DOIT(); +#undef DOIT + continue; + NonPrintable: + if ((likely((unsigned char)*buf < '\040') && likely(*buf != '\011')) || unlikely(*buf == '\177')) { + goto FOUND_CTL; + } + ++buf; + } +#endif + for (;; ++buf) { + CHECK_EOF(); + if (unlikely(!IS_PRINTABLE_ASCII(*buf))) { + if ((likely((unsigned char)*buf < '\040') && likely(*buf != '\011')) || unlikely(*buf == '\177')) { + goto FOUND_CTL; + } + } + } +FOUND_CTL: + if (likely(*buf == '\015')) { + ++buf; + EXPECT_CHAR('\012'); + *token_len = buf - 2 - token_start; + } else if (*buf == '\012') { + *token_len = buf - token_start; + ++buf; + } else { + *ret = -1; + return NULL; + } + *token = token_start; + + return buf; +} + +static const char *is_complete(const char *buf, const char *buf_end, size_t last_len, int *ret) +{ + int ret_cnt = 0; + buf = last_len < 3 ? buf : buf + last_len - 3; + + while (1) { + CHECK_EOF(); + if (*buf == '\015') { + ++buf; + CHECK_EOF(); + EXPECT_CHAR('\012'); + ++ret_cnt; + } else if (*buf == '\012') { + ++buf; + ++ret_cnt; + } else { + ++buf; + ret_cnt = 0; + } + if (ret_cnt == 2) { + return buf; + } + } + + *ret = -2; + return NULL; +} + +#define PARSE_INT(valp_, mul_) \ + if (*buf < '0' || '9' < *buf) { \ + buf++; \ + *ret = -1; \ + return NULL; \ + } \ + *(valp_) = (mul_) * (*buf++ - '0'); + +#define PARSE_INT_3(valp_) \ + do { \ + int res_ = 0; \ + PARSE_INT(&res_, 100) \ + *valp_ = res_; \ + PARSE_INT(&res_, 10) \ + *valp_ += res_; \ + PARSE_INT(&res_, 1) \ + *valp_ += res_; \ + } while (0) + +/* returned pointer is always within [buf, buf_end), or null */ +static const char *parse_http_version(const char *buf, const char *buf_end, int *minor_version, int *ret) +{ + /* we want at least [HTTP/1.] to try to parse */ + if (buf_end - buf < 9) { + *ret = -2; + return NULL; + } + EXPECT_CHAR_NO_CHECK('H'); + EXPECT_CHAR_NO_CHECK('T'); + EXPECT_CHAR_NO_CHECK('T'); + EXPECT_CHAR_NO_CHECK('P'); + EXPECT_CHAR_NO_CHECK('/'); + EXPECT_CHAR_NO_CHECK('1'); + EXPECT_CHAR_NO_CHECK('.'); + PARSE_INT(minor_version, 1); + return buf; +} + +static const char *parse_headers(const char *buf, const char *buf_end, struct phr_header *headers, size_t *num_headers, + size_t max_headers, int *ret) +{ + for (;; ++*num_headers) { + CHECK_EOF(); + if (*buf == '\015') { + ++buf; + EXPECT_CHAR('\012'); + break; + } else if (*buf == '\012') { + ++buf; + break; + } + if (*num_headers == max_headers) { + *ret = -1; + return NULL; + } + if (!(*num_headers != 0 && (*buf == ' ' || *buf == '\t'))) { + /* parsing name, but do not discard SP before colon, see + * http://www.mozilla.org/security/announce/2006/mfsa2006-33.html */ + headers[*num_headers].name = buf; + static const char ALIGNED(16) ranges1[] = "\x00 " /* control chars and up to SP */ + "\"\"" /* 0x22 */ + "()" /* 0x28,0x29 */ + ",," /* 0x2c */ + "//" /* 0x2f */ + ":@" /* 0x3a-0x40 */ + "[]" /* 0x5b-0x5d */ + "{\377"; /* 0x7b-0xff */ + int found; + buf = findchar_fast(buf, buf_end, ranges1, sizeof(ranges1) - 1, &found); + if (!found) { + CHECK_EOF(); + } + while (1) { + if (*buf == ':') { + break; + } else if (!token_char_map[(unsigned char)*buf]) { + *ret = -1; + return NULL; + } + ++buf; + CHECK_EOF(); + } + if ((headers[*num_headers].name_len = buf - headers[*num_headers].name) == 0) { + *ret = -1; + return NULL; + } + ++buf; + for (;; ++buf) { + CHECK_EOF(); + if (!(*buf == ' ' || *buf == '\t')) { + break; + } + } + } else { + headers[*num_headers].name = NULL; + headers[*num_headers].name_len = 0; + } + if ((buf = get_token_to_eol(buf, buf_end, &headers[*num_headers].value, &headers[*num_headers].value_len, ret)) == NULL) { + return NULL; + } + } + return buf; +} + +static const char *parse_request(const char *buf, const char *buf_end, const char **method, size_t *method_len, const char **path, + size_t *path_len, int *minor_version, struct phr_header *headers, size_t *num_headers, + size_t max_headers, int *ret) +{ + /* skip first empty line (some clients add CRLF after POST content) */ + CHECK_EOF(); + if (*buf == '\015') { + ++buf; + EXPECT_CHAR('\012'); + } else if (*buf == '\012') { + ++buf; + } + + /* parse request line */ + ADVANCE_TOKEN(*method, *method_len); + ++buf; + ADVANCE_TOKEN(*path, *path_len); + ++buf; + if ((buf = parse_http_version(buf, buf_end, minor_version, ret)) == NULL) { + return NULL; + } + if (*buf == '\015') { + ++buf; + EXPECT_CHAR('\012'); + } else if (*buf == '\012') { + ++buf; + } else { + *ret = -1; + return NULL; + } + + return parse_headers(buf, buf_end, headers, num_headers, max_headers, ret); +} + +int phr_parse_request(const char *buf_start, size_t len, const char **method, size_t *method_len, const char **path, + size_t *path_len, int *minor_version, struct phr_header *headers, size_t *num_headers, size_t last_len) +{ + const char *buf = buf_start, *buf_end = buf_start + len; + size_t max_headers = *num_headers; + int r; + + *method = NULL; + *method_len = 0; + *path = NULL; + *path_len = 0; + *minor_version = -1; + *num_headers = 0; + + /* if last_len != 0, check if the request is complete (a fast countermeasure + againt slowloris */ + if (last_len != 0 && is_complete(buf, buf_end, last_len, &r) == NULL) { + return r; + } + + if ((buf = parse_request(buf, buf_end, method, method_len, path, path_len, minor_version, headers, num_headers, max_headers, + &r)) == NULL) { + return r; + } + + return (int)(buf - buf_start); +} + +static const char *parse_response(const char *buf, const char *buf_end, int *minor_version, int *status, const char **msg, + size_t *msg_len, struct phr_header *headers, size_t *num_headers, size_t max_headers, int *ret) +{ + /* parse "HTTP/1.x" */ + if ((buf = parse_http_version(buf, buf_end, minor_version, ret)) == NULL) { + return NULL; + } + /* skip space */ + if (*buf++ != ' ') { + *ret = -1; + return NULL; + } + /* parse status code, we want at least [:digit:][:digit:][:digit:] to try to parse */ + if (buf_end - buf < 4) { + *ret = -2; + return NULL; + } + PARSE_INT_3(status); + + /* skip space */ + if (*buf++ != ' ') { + *ret = -1; + return NULL; + } + /* get message */ + if ((buf = get_token_to_eol(buf, buf_end, msg, msg_len, ret)) == NULL) { + return NULL; + } + + return parse_headers(buf, buf_end, headers, num_headers, max_headers, ret); +} + +int phr_parse_response(const char *buf_start, size_t len, int *minor_version, int *status, const char **msg, size_t *msg_len, + struct phr_header *headers, size_t *num_headers, size_t last_len) +{ + const char *buf = buf_start, *buf_end = buf + len; + size_t max_headers = *num_headers; + int r; + + *minor_version = -1; + *status = 0; + *msg = NULL; + *msg_len = 0; + *num_headers = 0; + + /* if last_len != 0, check if the response is complete (a fast countermeasure + against slowloris */ + if (last_len != 0 && is_complete(buf, buf_end, last_len, &r) == NULL) { + return r; + } + + if ((buf = parse_response(buf, buf_end, minor_version, status, msg, msg_len, headers, num_headers, max_headers, &r)) == NULL) { + return r; + } + + return (int)(buf - buf_start); +} + +int phr_parse_headers(const char *buf_start, size_t len, struct phr_header *headers, size_t *num_headers, size_t last_len) +{ + const char *buf = buf_start, *buf_end = buf + len; + size_t max_headers = *num_headers; + int r; + + *num_headers = 0; + + /* if last_len != 0, check if the response is complete (a fast countermeasure + against slowloris */ + if (last_len != 0 && is_complete(buf, buf_end, last_len, &r) == NULL) { + return r; + } + + if ((buf = parse_headers(buf, buf_end, headers, num_headers, max_headers, &r)) == NULL) { + return r; + } + + return (int)(buf - buf_start); +} + +enum { + CHUNKED_IN_CHUNK_SIZE, + CHUNKED_IN_CHUNK_EXT, + CHUNKED_IN_CHUNK_DATA, + CHUNKED_IN_CHUNK_CRLF, + CHUNKED_IN_TRAILERS_LINE_HEAD, + CHUNKED_IN_TRAILERS_LINE_MIDDLE +}; + +static int decode_hex(int ch) +{ + if ('0' <= ch && ch <= '9') { + return ch - '0'; + } else if ('A' <= ch && ch <= 'F') { + return ch - 'A' + 0xa; + } else if ('a' <= ch && ch <= 'f') { + return ch - 'a' + 0xa; + } else { + return -1; + } +} + +ssize_t phr_decode_chunked(struct phr_chunked_decoder *decoder, char *buf, size_t *_bufsz) +{ + size_t dst = 0, src = 0, bufsz = *_bufsz; + ssize_t ret = -2; /* incomplete */ + + while (1) { + switch (decoder->_state) { + case CHUNKED_IN_CHUNK_SIZE: + for (;; ++src) { + int v; + if (src == bufsz) + goto Exit; + if ((v = decode_hex(buf[src])) == -1) { + if (decoder->_hex_count == 0) { + ret = -1; + goto Exit; + } + break; + } + if (decoder->_hex_count == sizeof(size_t) * 2) { + ret = -1; + goto Exit; + } + decoder->bytes_left_in_chunk = decoder->bytes_left_in_chunk * 16 + v; + ++decoder->_hex_count; + } + decoder->_hex_count = 0; + decoder->_state = CHUNKED_IN_CHUNK_EXT; + /* fallthru */ + case CHUNKED_IN_CHUNK_EXT: + /* RFC 7230 A.2 "Line folding in chunk extensions is disallowed" */ + for (;; ++src) { + if (src == bufsz) + goto Exit; + if (buf[src] == '\012') + break; + } + ++src; + if (decoder->bytes_left_in_chunk == 0) { + if (decoder->consume_trailer) { + decoder->_state = CHUNKED_IN_TRAILERS_LINE_HEAD; + break; + } else { + goto Complete; + } + } + decoder->_state = CHUNKED_IN_CHUNK_DATA; + /* fallthru */ + case CHUNKED_IN_CHUNK_DATA: { + size_t avail = bufsz - src; + if (avail < decoder->bytes_left_in_chunk) { + if (dst != src) + memmove(buf + dst, buf + src, avail); + src += avail; + dst += avail; + decoder->bytes_left_in_chunk -= avail; + goto Exit; + } + if (dst != src) + memmove(buf + dst, buf + src, decoder->bytes_left_in_chunk); + src += decoder->bytes_left_in_chunk; + dst += decoder->bytes_left_in_chunk; + decoder->bytes_left_in_chunk = 0; + decoder->_state = CHUNKED_IN_CHUNK_CRLF; + } + /* fallthru */ + case CHUNKED_IN_CHUNK_CRLF: + for (;; ++src) { + if (src == bufsz) + goto Exit; + if (buf[src] != '\015') + break; + } + if (buf[src] != '\012') { + ret = -1; + goto Exit; + } + ++src; + decoder->_state = CHUNKED_IN_CHUNK_SIZE; + break; + case CHUNKED_IN_TRAILERS_LINE_HEAD: + for (;; ++src) { + if (src == bufsz) + goto Exit; + if (buf[src] != '\015') + break; + } + if (buf[src++] == '\012') + goto Complete; + decoder->_state = CHUNKED_IN_TRAILERS_LINE_MIDDLE; + /* fallthru */ + case CHUNKED_IN_TRAILERS_LINE_MIDDLE: + for (;; ++src) { + if (src == bufsz) + goto Exit; + if (buf[src] == '\012') + break; + } + ++src; + decoder->_state = CHUNKED_IN_TRAILERS_LINE_HEAD; + break; + default: + assert(!"decoder is corrupt"); + } + } + +Complete: + ret = bufsz - src; +Exit: + if (dst != src) + memmove(buf + dst, buf + src, bufsz - src); + *_bufsz = dst; + return ret; +} + +int phr_decode_chunked_is_in_data(struct phr_chunked_decoder *decoder) +{ + return decoder->_state == CHUNKED_IN_CHUNK_DATA; +} + +#undef CHECK_EOF +#undef EXPECT_CHAR +#undef ADVANCE_TOKEN diff --git a/web/server/h2o/libh2o/deps/picohttpparser/picohttpparser.h b/web/server/h2o/libh2o/deps/picohttpparser/picohttpparser.h new file mode 100644 index 00000000..67fd3ee7 --- /dev/null +++ b/web/server/h2o/libh2o/deps/picohttpparser/picohttpparser.h @@ -0,0 +1,89 @@ +/* + * Copyright (c) 2009-2014 Kazuho Oku, Tokuhiro Matsuno, Daisuke Murase, + * Shigeo Mitsunari + * + * The software is licensed under either the MIT License (below) or the Perl + * license. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#ifndef picohttpparser_h +#define picohttpparser_h + +#include + +#ifdef _MSC_VER +#define ssize_t intptr_t +#endif + +/* $Id$ */ + +#ifdef __cplusplus +extern "C" { +#endif + +/* contains name and value of a header (name == NULL if is a continuing line + * of a multiline header */ +struct phr_header { + const char *name; + size_t name_len; + const char *value; + size_t value_len; +}; + +/* returns number of bytes consumed if successful, -2 if request is partial, + * -1 if failed */ +int phr_parse_request(const char *buf, size_t len, const char **method, size_t *method_len, const char **path, size_t *path_len, + int *minor_version, struct phr_header *headers, size_t *num_headers, size_t last_len); + +/* ditto */ +int phr_parse_response(const char *_buf, size_t len, int *minor_version, int *status, const char **msg, size_t *msg_len, + struct phr_header *headers, size_t *num_headers, size_t last_len); + +/* ditto */ +int phr_parse_headers(const char *buf, size_t len, struct phr_header *headers, size_t *num_headers, size_t last_len); + +/* should be zero-filled before start */ +struct phr_chunked_decoder { + size_t bytes_left_in_chunk; /* number of bytes left in current chunk */ + char consume_trailer; /* if trailing headers should be consumed */ + char _hex_count; + char _state; +}; + +/* the function rewrites the buffer given as (buf, bufsz) removing the chunked- + * encoding headers. When the function returns without an error, bufsz is + * updated to the length of the decoded data available. Applications should + * repeatedly call the function while it returns -2 (incomplete) every time + * supplying newly arrived data. If the end of the chunked-encoded data is + * found, the function returns a non-negative number indicating the number of + * octets left undecoded at the tail of the supplied buffer. Returns -1 on + * error. + */ +ssize_t phr_decode_chunked(struct phr_chunked_decoder *decoder, char *buf, size_t *bufsz); + +/* returns if the chunked decoder is in middle of chunked data */ +int phr_decode_chunked_is_in_data(struct phr_chunked_decoder *decoder); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/web/server/h2o/libh2o/deps/picohttpparser/test.c b/web/server/h2o/libh2o/deps/picohttpparser/test.c new file mode 100644 index 00000000..8f808fdf --- /dev/null +++ b/web/server/h2o/libh2o/deps/picohttpparser/test.c @@ -0,0 +1,419 @@ +/* use `make test` to run the test */ +/* + * Copyright (c) 2009-2014 Kazuho Oku, Tokuhiro Matsuno, Daisuke Murase, + * Shigeo Mitsunari + * + * The software is licensed under either the MIT License (below) or the Perl + * license. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include +#include +#include +#include "picotest/picotest.h" +#include "picohttpparser.h" + +static int bufis(const char *s, size_t l, const char *t) +{ + return strlen(t) == l && memcmp(s, t, l) == 0; +} + +static void test_request(void) +{ + const char *method; + size_t method_len; + const char *path; + size_t path_len; + int minor_version; + struct phr_header headers[4]; + size_t num_headers; + +#define PARSE(s, last_len, exp, comment) \ + do { \ + note(comment); \ + num_headers = sizeof(headers) / sizeof(headers[0]); \ + ok(phr_parse_request(s, sizeof(s) - 1, &method, &method_len, &path, &path_len, &minor_version, headers, &num_headers, \ + last_len) == (exp == 0 ? strlen(s) : exp)); \ + } while (0) + + PARSE("GET / HTTP/1.0\r\n\r\n", 0, 0, "simple"); + ok(num_headers == 0); + ok(bufis(method, method_len, "GET")); + ok(bufis(path, path_len, "/")); + ok(minor_version == 0); + + PARSE("GET / HTTP/1.0\r\n\r", 0, -2, "partial"); + + PARSE("GET /hoge HTTP/1.1\r\nHost: example.com\r\nCookie: \r\n\r\n", 0, 0, "parse headers"); + ok(num_headers == 2); + ok(bufis(method, method_len, "GET")); + ok(bufis(path, path_len, "/hoge")); + ok(minor_version == 1); + ok(bufis(headers[0].name, headers[0].name_len, "Host")); + ok(bufis(headers[0].value, headers[0].value_len, "example.com")); + ok(bufis(headers[1].name, headers[1].name_len, "Cookie")); + ok(bufis(headers[1].value, headers[1].value_len, "")); + + PARSE("GET /hoge HTTP/1.1\r\nHost: example.com\r\nUser-Agent: \343\201\262\343/1.0\r\n\r\n", 0, 0, "multibyte included"); + ok(num_headers == 2); + ok(bufis(method, method_len, "GET")); + ok(bufis(path, path_len, "/hoge")); + ok(minor_version == 1); + ok(bufis(headers[0].name, headers[0].name_len, "Host")); + ok(bufis(headers[0].value, headers[0].value_len, "example.com")); + ok(bufis(headers[1].name, headers[1].name_len, "User-Agent")); + ok(bufis(headers[1].value, headers[1].value_len, "\343\201\262\343/1.0")); + + PARSE("GET / HTTP/1.0\r\nfoo: \r\nfoo: b\r\n \tc\r\n\r\n", 0, 0, "parse multiline"); + ok(num_headers == 3); + ok(bufis(method, method_len, "GET")); + ok(bufis(path, path_len, "/")); + ok(minor_version == 0); + ok(bufis(headers[0].name, headers[0].name_len, "foo")); + ok(bufis(headers[0].value, headers[0].value_len, "")); + ok(bufis(headers[1].name, headers[1].name_len, "foo")); + ok(bufis(headers[1].value, headers[1].value_len, "b")); + ok(headers[2].name == NULL); + ok(bufis(headers[2].value, headers[2].value_len, " \tc")); + + PARSE("GET / HTTP/1.0\r\nfoo : ab\r\n\r\n", 0, -1, "parse header name with trailing space"); + + PARSE("GET", 0, -2, "incomplete 1"); + ok(method == NULL); + PARSE("GET ", 0, -2, "incomplete 2"); + ok(bufis(method, method_len, "GET")); + PARSE("GET /", 0, -2, "incomplete 3"); + ok(path == NULL); + PARSE("GET / ", 0, -2, "incomplete 4"); + ok(bufis(path, path_len, "/")); + PARSE("GET / H", 0, -2, "incomplete 5"); + PARSE("GET / HTTP/1.", 0, -2, "incomplete 6"); + PARSE("GET / HTTP/1.0", 0, -2, "incomplete 7"); + ok(minor_version == -1); + PARSE("GET / HTTP/1.0\r", 0, -2, "incomplete 8"); + ok(minor_version == 0); + + PARSE("GET /hoge HTTP/1.0\r\n\r", strlen("GET /hoge HTTP/1.0\r\n\r") - 1, -2, "slowloris (incomplete)"); + PARSE("GET /hoge HTTP/1.0\r\n\r\n", strlen("GET /hoge HTTP/1.0\r\n\r\n") - 1, 0, "slowloris (complete)"); + + PARSE("GET / HTTP/1.0\r\n:a\r\n\r\n", 0, -1, "empty header name"); + PARSE("GET / HTTP/1.0\r\n :a\r\n\r\n", 0, -1, "header name (space only)"); + + PARSE("G\0T / HTTP/1.0\r\n\r\n", 0, -1, "NUL in method"); + PARSE("G\tT / HTTP/1.0\r\n\r\n", 0, -1, "tab in method"); + PARSE("GET /\x7fhello HTTP/1.0\r\n\r\n", 0, -1, "DEL in uri-path"); + PARSE("GET / HTTP/1.0\r\na\0b: c\r\n\r\n", 0, -1, "NUL in header name"); + PARSE("GET / HTTP/1.0\r\nab: c\0d\r\n\r\n", 0, -1, "NUL in header value"); + PARSE("GET / HTTP/1.0\r\na\033b: c\r\n\r\n", 0, -1, "CTL in header name"); + PARSE("GET / HTTP/1.0\r\nab: c\033\r\n\r\n", 0, -1, "CTL in header value"); + PARSE("GET / HTTP/1.0\r\n/: 1\r\n\r\n", 0, -1, "invalid char in header value"); + PARSE("GET /\xa0 HTTP/1.0\r\nh: c\xa2y\r\n\r\n", 0, 0, "accept MSB chars"); + ok(num_headers == 1); + ok(bufis(method, method_len, "GET")); + ok(bufis(path, path_len, "/\xa0")); + ok(minor_version == 0); + ok(bufis(headers[0].name, headers[0].name_len, "h")); + ok(bufis(headers[0].value, headers[0].value_len, "c\xa2y")); + + PARSE("GET / HTTP/1.0\r\n\x7c\x7e: 1\r\n\r\n", 0, 0, "accept |~ (though forbidden by SSE)"); + ok(num_headers == 1); + ok(bufis(headers[0].name, headers[0].name_len, "\x7c\x7e")); + ok(bufis(headers[0].value, headers[0].value_len, "1")); + + PARSE("GET / HTTP/1.0\r\n\x7b: 1\r\n\r\n", 0, -1, "disallow {"); + +#undef PARSE +} + +static void test_response(void) +{ + int minor_version; + int status; + const char *msg; + size_t msg_len; + struct phr_header headers[4]; + size_t num_headers; + +#define PARSE(s, last_len, exp, comment) \ + do { \ + note(comment); \ + num_headers = sizeof(headers) / sizeof(headers[0]); \ + ok(phr_parse_response(s, strlen(s), &minor_version, &status, &msg, &msg_len, headers, &num_headers, last_len) == \ + (exp == 0 ? strlen(s) : exp)); \ + } while (0) + + PARSE("HTTP/1.0 200 OK\r\n\r\n", 0, 0, "simple"); + ok(num_headers == 0); + ok(status == 200); + ok(minor_version == 0); + ok(bufis(msg, msg_len, "OK")); + + PARSE("HTTP/1.0 200 OK\r\n\r", 0, -2, "partial"); + + PARSE("HTTP/1.1 200 OK\r\nHost: example.com\r\nCookie: \r\n\r\n", 0, 0, "parse headers"); + ok(num_headers == 2); + ok(minor_version == 1); + ok(status == 200); + ok(bufis(msg, msg_len, "OK")); + ok(bufis(headers[0].name, headers[0].name_len, "Host")); + ok(bufis(headers[0].value, headers[0].value_len, "example.com")); + ok(bufis(headers[1].name, headers[1].name_len, "Cookie")); + ok(bufis(headers[1].value, headers[1].value_len, "")); + + PARSE("HTTP/1.0 200 OK\r\nfoo: \r\nfoo: b\r\n \tc\r\n\r\n", 0, 0, "parse multiline"); + ok(num_headers == 3); + ok(minor_version == 0); + ok(status == 200); + ok(bufis(msg, msg_len, "OK")); + ok(bufis(headers[0].name, headers[0].name_len, "foo")); + ok(bufis(headers[0].value, headers[0].value_len, "")); + ok(bufis(headers[1].name, headers[1].name_len, "foo")); + ok(bufis(headers[1].value, headers[1].value_len, "b")); + ok(headers[2].name == NULL); + ok(bufis(headers[2].value, headers[2].value_len, " \tc")); + + PARSE("HTTP/1.0 500 Internal Server Error\r\n\r\n", 0, 0, "internal server error"); + ok(num_headers == 0); + ok(minor_version == 0); + ok(status == 500); + ok(bufis(msg, msg_len, "Internal Server Error")); + ok(msg_len == sizeof("Internal Server Error") - 1); + + PARSE("H", 0, -2, "incomplete 1"); + PARSE("HTTP/1.", 0, -2, "incomplete 2"); + PARSE("HTTP/1.1", 0, -2, "incomplete 3"); + ok(minor_version == -1); + PARSE("HTTP/1.1 ", 0, -2, "incomplete 4"); + ok(minor_version == 1); + PARSE("HTTP/1.1 2", 0, -2, "incomplete 5"); + PARSE("HTTP/1.1 200", 0, -2, "incomplete 6"); + ok(status == 0); + PARSE("HTTP/1.1 200 ", 0, -2, "incomplete 7"); + ok(status == 200); + PARSE("HTTP/1.1 200 O", 0, -2, "incomplete 8"); + PARSE("HTTP/1.1 200 OK\r", 0, -2, "incomplete 9"); + ok(msg == NULL); + PARSE("HTTP/1.1 200 OK\r\n", 0, -2, "incomplete 10"); + ok(bufis(msg, msg_len, "OK")); + PARSE("HTTP/1.1 200 OK\n", 0, -2, "incomplete 11"); + ok(bufis(msg, msg_len, "OK")); + + PARSE("HTTP/1.1 200 OK\r\nA: 1\r", 0, -2, "incomplete 11"); + ok(num_headers == 0); + PARSE("HTTP/1.1 200 OK\r\nA: 1\r\n", 0, -2, "incomplete 12"); + ok(num_headers == 1); + ok(bufis(headers[0].name, headers[0].name_len, "A")); + ok(bufis(headers[0].value, headers[0].value_len, "1")); + + PARSE("HTTP/1.0 200 OK\r\n\r", strlen("HTTP/1.0 200 OK\r\n\r") - 1, -2, "slowloris (incomplete)"); + PARSE("HTTP/1.0 200 OK\r\n\r\n", strlen("HTTP/1.0 200 OK\r\n\r\n") - 1, 0, "slowloris (complete)"); + + PARSE("HTTP/1. 200 OK\r\n\r\n", 0, -1, "invalid http version"); + PARSE("HTTP/1.2z 200 OK\r\n\r\n", 0, -1, "invalid http version 2"); + PARSE("HTTP/1.1 OK\r\n\r\n", 0, -1, "no status code"); + +#undef PARSE +} + +static void test_headers(void) +{ + /* only test the interface; the core parser is tested by the tests above */ + + struct phr_header headers[4]; + size_t num_headers; + +#define PARSE(s, last_len, exp, comment) \ + do { \ + note(comment); \ + num_headers = sizeof(headers) / sizeof(headers[0]); \ + ok(phr_parse_headers(s, strlen(s), headers, &num_headers, last_len) == (exp == 0 ? strlen(s) : exp)); \ + } while (0) + + PARSE("Host: example.com\r\nCookie: \r\n\r\n", 0, 0, "simple"); + ok(num_headers == 2); + ok(bufis(headers[0].name, headers[0].name_len, "Host")); + ok(bufis(headers[0].value, headers[0].value_len, "example.com")); + ok(bufis(headers[1].name, headers[1].name_len, "Cookie")); + ok(bufis(headers[1].value, headers[1].value_len, "")); + + PARSE("Host: example.com\r\nCookie: \r\n\r\n", 1, 0, "slowloris"); + ok(num_headers == 2); + ok(bufis(headers[0].name, headers[0].name_len, "Host")); + ok(bufis(headers[0].value, headers[0].value_len, "example.com")); + ok(bufis(headers[1].name, headers[1].name_len, "Cookie")); + ok(bufis(headers[1].value, headers[1].value_len, "")); + + PARSE("Host: example.com\r\nCookie: \r\n\r", 0, -2, "partial"); + + PARSE("Host: e\7fample.com\r\nCookie: \r\n\r", 0, -1, "error"); + +#undef PARSE +} + +static void test_chunked_at_once(int line, int consume_trailer, const char *encoded, const char *decoded, ssize_t expected) +{ + struct phr_chunked_decoder dec = {0}; + char *buf; + size_t bufsz; + ssize_t ret; + + dec.consume_trailer = consume_trailer; + + note("testing at-once, source at line %d", line); + + buf = strdup(encoded); + bufsz = strlen(buf); + + ret = phr_decode_chunked(&dec, buf, &bufsz); + + ok(ret == expected); + ok(bufsz == strlen(decoded)); + ok(bufis(buf, bufsz, decoded)); + if (expected >= 0) { + if (ret == expected) + ok(bufis(buf + bufsz, ret, encoded + strlen(encoded) - ret)); + else + ok(0); + } + + free(buf); +} + +static void test_chunked_per_byte(int line, int consume_trailer, const char *encoded, const char *decoded, ssize_t expected) +{ + struct phr_chunked_decoder dec = {0}; + char *buf = malloc(strlen(encoded) + 1); + size_t bytes_to_consume = strlen(encoded) - (expected >= 0 ? expected : 0), bytes_ready = 0, bufsz, i; + ssize_t ret; + + dec.consume_trailer = consume_trailer; + + note("testing per-byte, source at line %d", line); + + for (i = 0; i < bytes_to_consume - 1; ++i) { + buf[bytes_ready] = encoded[i]; + bufsz = 1; + ret = phr_decode_chunked(&dec, buf + bytes_ready, &bufsz); + if (ret != -2) { + ok(0); + goto cleanup; + } + bytes_ready += bufsz; + } + strcpy(buf + bytes_ready, encoded + bytes_to_consume - 1); + bufsz = strlen(buf + bytes_ready); + ret = phr_decode_chunked(&dec, buf + bytes_ready, &bufsz); + ok(ret == expected); + bytes_ready += bufsz; + ok(bytes_ready == strlen(decoded)); + ok(bufis(buf, bytes_ready, decoded)); + if (expected >= 0) { + if (ret == expected) + ok(bufis(buf + bytes_ready, expected, encoded + bytes_to_consume)); + else + ok(0); + } + +cleanup: + free(buf); +} + +static void test_chunked_failure(int line, const char *encoded, ssize_t expected) +{ + struct phr_chunked_decoder dec = {0}; + char *buf = strdup(encoded); + size_t bufsz, i; + ssize_t ret; + + note("testing failure at-once, source at line %d", line); + bufsz = strlen(buf); + ret = phr_decode_chunked(&dec, buf, &bufsz); + ok(ret == expected); + + note("testing failure per-byte, source at line %d", line); + memset(&dec, 0, sizeof(dec)); + for (i = 0; encoded[i] != '\0'; ++i) { + buf[0] = encoded[i]; + bufsz = 1; + ret = phr_decode_chunked(&dec, buf, &bufsz); + if (ret == -1) { + ok(ret == expected); + goto cleanup; + } else if (ret == -2) { + /* continue */ + } else { + ok(0); + goto cleanup; + } + } + ok(ret == expected); + +cleanup: + free(buf); +} + +static void (*chunked_test_runners[])(int, int, const char *, const char *, ssize_t) = {test_chunked_at_once, test_chunked_per_byte, + NULL}; + +static void test_chunked(void) +{ + size_t i; + + for (i = 0; chunked_test_runners[i] != NULL; ++i) { + chunked_test_runners[i](__LINE__, 0, "b\r\nhello world\r\n0\r\n", "hello world", 0); + chunked_test_runners[i](__LINE__, 0, "6\r\nhello \r\n5\r\nworld\r\n0\r\n", "hello world", 0); + chunked_test_runners[i](__LINE__, 0, "6;comment=hi\r\nhello \r\n5\r\nworld\r\n0\r\n", "hello world", 0); + chunked_test_runners[i](__LINE__, 0, "6\r\nhello \r\n5\r\nworld\r\n0\r\na: b\r\nc: d\r\n\r\n", "hello world", + sizeof("a: b\r\nc: d\r\n\r\n") - 1); + chunked_test_runners[i](__LINE__, 0, "b\r\nhello world\r\n0\r\n", "hello world", 0); + } + + note("failures"); + test_chunked_failure(__LINE__, "z\r\nabcdefg", -1); + if (sizeof(size_t) == 8) { + test_chunked_failure(__LINE__, "6\r\nhello \r\nffffffffffffffff\r\nabcdefg", -2); + test_chunked_failure(__LINE__, "6\r\nhello \r\nfffffffffffffffff\r\nabcdefg", -1); + } +} + +static void test_chunked_consume_trailer(void) +{ + size_t i; + + for (i = 0; chunked_test_runners[i] != NULL; ++i) { + chunked_test_runners[i](__LINE__, 1, "b\r\nhello world\r\n0\r\n", "hello world", -2); + chunked_test_runners[i](__LINE__, 1, "6\r\nhello \r\n5\r\nworld\r\n0\r\n", "hello world", -2); + chunked_test_runners[i](__LINE__, 1, "6;comment=hi\r\nhello \r\n5\r\nworld\r\n0\r\n", "hello world", -2); + chunked_test_runners[i](__LINE__, 1, "b\r\nhello world\r\n0\r\n\r\n", "hello world", 0); + chunked_test_runners[i](__LINE__, 1, "b\nhello world\n0\n\n", "hello world", 0); + chunked_test_runners[i](__LINE__, 1, "6\r\nhello \r\n5\r\nworld\r\n0\r\na: b\r\nc: d\r\n\r\n", "hello world", 0); + } +} + +int main(int argc, char **argv) +{ + subtest("request", test_request); + subtest("response", test_response); + subtest("headers", test_headers); + subtest("chunked", test_chunked); + subtest("chunked-consume-trailer", test_chunked_consume_trailer); + return done_testing(); +} diff --git a/web/server/h2o/libh2o/deps/picotest/picotest.c b/web/server/h2o/libh2o/deps/picotest/picotest.c new file mode 100644 index 00000000..d1fe699d --- /dev/null +++ b/web/server/h2o/libh2o/deps/picotest/picotest.c @@ -0,0 +1,99 @@ +/* + * Copyright (c) 2014 DeNA Co., Ltd. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ +#include +#include +#include +#include "picotest.h" + +struct test_t { + int num_tests; + int failed; +}; +struct test_t main_tests, *cur_tests = &main_tests; +static int test_level = 0; + +static void indent(void) +{ + int i; + for (i = 0; i != test_level; ++i) + printf(" "); +} + +__attribute__((format (printf, 1, 2))) +void note(const char *fmt, ...) +{ + va_list arg; + + indent(); + printf("# "); + + va_start(arg, fmt); + vprintf(fmt, arg); + va_end(arg); + + printf("\n"); +} + +__attribute__((format (printf, 2, 3))) +void _ok(int cond, const char *fmt, ...) +{ + va_list arg; + + if (! cond) + cur_tests->failed = 1; + indent(); + + printf("%s %d - ", cond ? "ok" : "not ok", ++cur_tests->num_tests); + va_start(arg, fmt); + vprintf(fmt, arg); + va_end(arg); + + printf("\n"); +} + +int done_testing(void) +{ + indent(); + printf("1..%d\n", cur_tests->num_tests); + return cur_tests->failed; +} + +void subtest(const char *name, void (*cb)(void)) +{ + struct test_t test = {}, *parent_tests; + + parent_tests = cur_tests; + cur_tests = &test; + ++test_level; + + note("Subtest: %s", name); + + cb(); + + done_testing(); + + --test_level; + cur_tests = parent_tests; + if (test.failed) + cur_tests->failed = 1; + _ok(! test.failed, "%s", name); +} diff --git a/web/server/h2o/libh2o/deps/picotest/picotest.h b/web/server/h2o/libh2o/deps/picotest/picotest.h new file mode 100644 index 00000000..22ab02fb --- /dev/null +++ b/web/server/h2o/libh2o/deps/picotest/picotest.h @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2014 DeNA Co., Ltd. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ +#ifndef picotest_h +#define picotest_h + +#ifdef __cplusplus +extern "C" { +#endif + +void note(const char *fmt, ...) __attribute__((format (printf, 1, 2))); +void _ok(int cond, const char *fmt, ...) __attribute__((format (printf, 2, 3))); +#define ok(cond) _ok(cond, "%s %d", __FILE__, __LINE__) +int done_testing(void); +void subtest(const char *name, void (*cb)(void)); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/web/server/h2o/libh2o/deps/picotls/.clang-format b/web/server/h2o/libh2o/deps/picotls/.clang-format new file mode 100644 index 00000000..9640123c --- /dev/null +++ b/web/server/h2o/libh2o/deps/picotls/.clang-format @@ -0,0 +1,7 @@ +# requires clang-format >= 3.6 +BasedOnStyle: "LLVM" +IndentWidth: 4 +ColumnLimit: 132 +BreakBeforeBraces: Linux +AllowShortFunctionsOnASingleLine: None +SortIncludes: false diff --git a/web/server/h2o/libh2o/deps/picotls/.gitignore b/web/server/h2o/libh2o/deps/picotls/.gitignore new file mode 100644 index 00000000..4d46b407 --- /dev/null +++ b/web/server/h2o/libh2o/deps/picotls/.gitignore @@ -0,0 +1,24 @@ +*/Debug +Debug +*/Release +Release +*/x64 +x64 +*/.vs +.vs +*/Generated Files +*.sdf +*/*.sdf +*/*.user +*.ipch +*/*.ipch +*.db +*/*.db +*/*.lib +*/*.pdb +*/AppX +*/*.exe +*/*.dll +*/*.xbf +*/*.ilk +deps/picotest diff --git a/web/server/h2o/libh2o/deps/picotls/.gitmodules b/web/server/h2o/libh2o/deps/picotls/.gitmodules new file mode 100644 index 00000000..37df0c6d --- /dev/null +++ b/web/server/h2o/libh2o/deps/picotls/.gitmodules @@ -0,0 +1,3 @@ +[submodule "deps/picotest"] + path = deps/picotest + url = https://github.com/h2o/picotest.git diff --git a/web/server/h2o/libh2o/deps/picotls/.travis.yml b/web/server/h2o/libh2o/deps/picotls/.travis.yml new file mode 100644 index 00000000..6c822845 --- /dev/null +++ b/web/server/h2o/libh2o/deps/picotls/.travis.yml @@ -0,0 +1,17 @@ +# use trusty beta (ubuntu 14.04) +sudo: required +dist: trusty + +language: c + +compiler: + - gcc + - clang + +before_install: + - sudo apt-get install --yes cmake + +script: + - cmake . + - make all + - make check diff --git a/web/server/h2o/libh2o/deps/picotls/CMakeLists.txt b/web/server/h2o/libh2o/deps/picotls/CMakeLists.txt new file mode 100644 index 00000000..87d14724 --- /dev/null +++ b/web/server/h2o/libh2o/deps/picotls/CMakeLists.txt @@ -0,0 +1,51 @@ +CMAKE_MINIMUM_REQUIRED(VERSION 2.8.11) +CMAKE_POLICY(SET CMP0003 NEW) + +PROJECT(picotls) + +FIND_PACKAGE(PkgConfig REQUIRED) + +SET(CMAKE_C_FLAGS "-std=c99 -Wall -O2 -g ${CC_WARNING_FLAGS} ${CMAKE_C_FLAGS}") +INCLUDE_DIRECTORIES(${OPENSSL_INCLUDE_DIR} deps/cifra/src/ext deps/cifra/src deps/micro-ecc deps/picotest include) +SET(MINICRYPTO_LIBRARY_FILES + deps/micro-ecc/uECC.c + deps/cifra/src/aes.c + deps/cifra/src/blockwise.c + deps/cifra/src/chacha20.c + deps/cifra/src/chash.c + deps/cifra/src/curve25519.c + deps/cifra/src/drbg.c + deps/cifra/src/hmac.c + deps/cifra/src/gcm.c + deps/cifra/src/gf128.c + deps/cifra/src/modes.c + deps/cifra/src/poly1305.c + deps/cifra/src/sha256.c + deps/cifra/src/sha512.c) + +ADD_LIBRARY(picotls-core lib/picotls.c lib/pembase64.c) +ADD_LIBRARY(picotls-minicrypto ${MINICRYPTO_LIBRARY_FILES} lib/cifra.c lib/minicrypto-pem.c lib/uecc.c lib/asn1.c) +ADD_EXECUTABLE(test-minicrypto.t ${MINICRYPTO_LIBRARY_FILES} deps/picotest/picotest.c t/picotls.c t/minicrypto.c lib/asn1.c lib/pembase64.c) + +SET(TEST_EXES test-minicrypto.t) + +FIND_PACKAGE(OpenSSL) +IF (OPENSSL_FOUND AND NOT (OPENSSL_VERSION VERSION_LESS "1.0.1")) + MESSAGE(WARNING "Enabling OpenSSL support") + INCLUDE_DIRECTORIES(${OPENSSL_INCLUDE_DIR}) + ADD_LIBRARY(picotls-openssl lib/openssl.c) + ADD_EXECUTABLE(cli t/cli.c lib/pembase64.c) + TARGET_LINK_LIBRARIES(cli picotls-openssl picotls-core ${OPENSSL_LIBRARIES} ${CMAKE_DL_LIBS}) + ADD_EXECUTABLE(test-openssl.t ${MINICRYPTO_LIBRARY_FILES} lib/cifra.c lib/uecc.c lib/asn1.c lib/pembase64.c deps/picotest/picotest.c t/picotls.c t/openssl.c) + SET_TARGET_PROPERTIES(test-openssl.t PROPERTIES COMPILE_FLAGS "-DPTLS_MEMORY_DEBUG=1") + TARGET_LINK_LIBRARIES(test-openssl.t ${OPENSSL_LIBRARIES} ${CMAKE_DL_LIBS}) + SET(TEST_EXES ${TEST_EXES} test-openssl.t) +ELSE () + MESSAGE(WARNING "Disabling OpenSSL support (requires 1.0.1 or newer)") +ENDIF () + +ADD_CUSTOM_TARGET(check prove --exec '' -v ./*.t DEPENDS ${TEST_EXES}) + +IF ("${CMAKE_SYSTEM_NAME}" MATCHES "SunOS") + TARGET_LINK_LIBRARIES(cli "socket" "nsl") +ENDIF () diff --git a/web/server/h2o/libh2o/deps/picotls/README.md b/web/server/h2o/libh2o/deps/picotls/README.md new file mode 100644 index 00000000..12f58724 --- /dev/null +++ b/web/server/h2o/libh2o/deps/picotls/README.md @@ -0,0 +1,78 @@ +picotls +=== + +[![Build Status](https://travis-ci.org/h2o/picotls.svg?branch=master)](https://travis-ci.org/h2o/picotls) + +Picotls is a [TLS 1.3](https://tlswg.github.io/tls13-spec/) implementation written in C. + +At the moment, the library implements draft-22 of the specification, including support 0-RTT resumption using PSK or PSK-DHE. + +Primary goal of the project is to create a fast, tiny TLS 1.3 implementation that can be used with the HTTP/2 protocol stack and possibly the upcoming QUIC stack of the [H2O HTTP/2 server](https://h2o.examp1e.net). + +Picotls only implements the communination protocol; cryptographic operations are delegated to cryptographic engines. +At the moment, _minicrypto_ binding (uses [cifra](https://github.com/ctz/cifra/) and [micro-ecc](https://github.com/kmackay/micro-ecc)) and _openssl_ binding are provided. + +License and algorithms supported by the bindings are as follows: + +| Binding | License | Key Exchange | Certificate | AEAD cipher | +|:-----:|:-----:|:-----:|:-----:|:-----:| +| minicrypto | [CC0](https://github.com/ctz/cifra/) / [2-clause BSD](https://github.com/kmackay/micro-ecc) | secp256r1, x25519 | ECDSA (P256)1 | AES-128-GCM | +| OpenSSL | OpenSSL | secp256r1 | RSA, ECDSA (P256) | AES-128-GCM | + +Note 1: Minicrypto binding is capable of signing a handshake using the certificate's key, but cannot verify a signature sent by the peer. + +Building picotls +--- + +If you have cloned picotls from git then ensure that you have initialised the submodules: +``` +% git submodule init +% git submodule update +``` + +Build using cmake: +``` +% cmake . +% make +% make check +``` + +A dedicated documentation for using picotls with Visual Studio can be found in [WindowsPort.md](WindowsPort.md). + +Developer documentation +--- + +Developer documentation should be available on [the wiki](https://github.com/h2o/picotls/wiki). + +Using the cli command +--- + +Run the test server (at 127.0.0.1:8443): +``` +% ./cli -c /path/to/certificate.pem -k /path/to/private-key.pem 127.0.0.1 8443 +``` + +Connect to the test server: +``` +% ./cli 127.0.0.1 8443 +``` + +Using resumption: +``` +% ./cli -s session-file 127.0.0.1 8443 +``` +The session-file is read-write. +The cli server implements a single-entry session cache. +The cli server sends NewSessionTicket when it first sends application data after receiving ClientFinished. + +Using early-data: +``` +% ./cli -s session-file -e 127.0.0.1 8443 +``` +When `-e` option is used, client first waits for user input, and then sends CLIENT_HELLO along with the early-data. + +License +--- + +The software is provided under the MIT license. +Note that additional licences apply if you use the minicrypto binding (see above). diff --git a/web/server/h2o/libh2o/deps/picotls/WindowsPort.md b/web/server/h2o/libh2o/deps/picotls/WindowsPort.md new file mode 100644 index 00000000..b2989e3d --- /dev/null +++ b/web/server/h2o/libh2o/deps/picotls/WindowsPort.md @@ -0,0 +1,34 @@ +Compiling PicoTLS with Visual Studio 2017 + +The source contains a Visual Studio 2017 solution (picotls/picotlsvs/picotlsvs.sln) +which itself contains 5 projects: + +* Three libraries, picotls.lib and its dependencies cifra.lib and uecc.lib; + +* A test project, testopenssl.exe, which will run on a console and + execute the OpenSSL tests; + +* And, an example project, picotlsvs.exe, which will perform a TLS exchange + in memory, and demonstrate how to use PicoTLS in windows. + +The code has a dependency on OpenSSL. When building the 32 bit projects (WIN32) it +expects to find: + +* OpenSSL header files under $(OPENSSLDIR)\include + +* OpenSSL library libcrypto.lib under $(OPENSSLDIR) + +When building the 64 bits projects (X64), it expects to find: + +* OpenSSL header files under $(OPENSSL64DIR)\include + +* OpenSSL library libcrypto.lib under $(OPENSSL64DIR) + +You will need also to copy libcrypto.dll to the library that contains your +executable, or to otherwise register that library. Be sure to copy the 32 bit +library or 64 bit library, depending on which type of project you build. + +Only two configurations are tested: "X86 Debug" and "X86 Release". The X64 configurations +will compile, but are not tested yet. + +Feel free to provide feedback and contribute. diff --git a/web/server/h2o/libh2o/deps/picotls/deps/cifra/.travis.yml b/web/server/h2o/libh2o/deps/picotls/deps/cifra/.travis.yml new file mode 100644 index 00000000..44b1a26f --- /dev/null +++ b/web/server/h2o/libh2o/deps/picotls/deps/cifra/.travis.yml @@ -0,0 +1,29 @@ +language: c + +before_install: + - sudo pip install cpp-coveralls + +script: + - cd src + - make clean + - make test + +after_success: + - coveralls --exclude src/ext --gcov-options '\-lp' + +compiler: + - gcc + +env: + global: + - secure: "W9IUnUWNc03gIBGLPOxXCVJUOb3RY2fS4lgOo+wIsCSk0rsJAB6gruAZDoz1sMxCJyBhCv0dKV5WPkAxkZ0y55wiuUcCepgR0qis6S6rJxldPdEWc3RQaeU9LbVRKRBYUBqSsFlXr5pdOvl0CBDWmx8lhcRxAw8z+JVDrAGVsTQ=" + +addons: + coverity_scan: + project: + name: "ctz/cifra" + description: "Cifra is a collection of cryptographic primitives targeted at embedded use." + notification_email: jpixton@gmail.com + build_command_prepend: "cd src ; make clean" + build_command: "make" + branch_pattern: coverity-scan diff --git a/web/server/h2o/libh2o/deps/picotls/deps/cifra/COPYING b/web/server/h2o/libh2o/deps/picotls/deps/cifra/COPYING new file mode 100644 index 00000000..0e259d42 --- /dev/null +++ b/web/server/h2o/libh2o/deps/picotls/deps/cifra/COPYING @@ -0,0 +1,121 @@ +Creative Commons Legal Code + +CC0 1.0 Universal + + CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE + LEGAL SERVICES. DISTRIBUTION OF THIS DOCUMENT DOES NOT CREATE AN + ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS + INFORMATION ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES + REGARDING THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS + PROVIDED HEREUNDER, AND DISCLAIMS LIABILITY FOR DAMAGES RESULTING FROM + THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS PROVIDED + HEREUNDER. + +Statement of Purpose + +The laws of most jurisdictions throughout the world automatically confer +exclusive Copyright and Related Rights (defined below) upon the creator +and subsequent owner(s) (each and all, an "owner") of an original work of +authorship and/or a database (each, a "Work"). + +Certain owners wish to permanently relinquish those rights to a Work for +the purpose of contributing to a commons of creative, cultural and +scientific works ("Commons") that the public can reliably and without fear +of later claims of infringement build upon, modify, incorporate in other +works, reuse and redistribute as freely as possible in any form whatsoever +and for any purposes, including without limitation commercial purposes. +These owners may contribute to the Commons to promote the ideal of a free +culture and the further production of creative, cultural and scientific +works, or to gain reputation or greater distribution for their Work in +part through the use and efforts of others. + +For these and/or other purposes and motivations, and without any +expectation of additional consideration or compensation, the person +associating CC0 with a Work (the "Affirmer"), to the extent that he or she +is an owner of Copyright and Related Rights in the Work, voluntarily +elects to apply CC0 to the Work and publicly distribute the Work under its +terms, with knowledge of his or her Copyright and Related Rights in the +Work and the meaning and intended legal effect of CC0 on those rights. + +1. Copyright and Related Rights. A Work made available under CC0 may be +protected by copyright and related or neighboring rights ("Copyright and +Related Rights"). Copyright and Related Rights include, but are not +limited to, the following: + + i. the right to reproduce, adapt, distribute, perform, display, + communicate, and translate a Work; + ii. moral rights retained by the original author(s) and/or performer(s); +iii. publicity and privacy rights pertaining to a person's image or + likeness depicted in a Work; + iv. rights protecting against unfair competition in regards to a Work, + subject to the limitations in paragraph 4(a), below; + v. rights protecting the extraction, dissemination, use and reuse of data + in a Work; + vi. database rights (such as those arising under Directive 96/9/EC of the + European Parliament and of the Council of 11 March 1996 on the legal + protection of databases, and under any national implementation + thereof, including any amended or successor version of such + directive); and +vii. other similar, equivalent or corresponding rights throughout the + world based on applicable law or treaty, and any national + implementations thereof. + +2. Waiver. To the greatest extent permitted by, but not in contravention +of, applicable law, Affirmer hereby overtly, fully, permanently, +irrevocably and unconditionally waives, abandons, and surrenders all of +Affirmer's Copyright and Related Rights and associated claims and causes +of action, whether now known or unknown (including existing as well as +future claims and causes of action), in the Work (i) in all territories +worldwide, (ii) for the maximum duration provided by applicable law or +treaty (including future time extensions), (iii) in any current or future +medium and for any number of copies, and (iv) for any purpose whatsoever, +including without limitation commercial, advertising or promotional +purposes (the "Waiver"). Affirmer makes the Waiver for the benefit of each +member of the public at large and to the detriment of Affirmer's heirs and +successors, fully intending that such Waiver shall not be subject to +revocation, rescission, cancellation, termination, or any other legal or +equitable action to disrupt the quiet enjoyment of the Work by the public +as contemplated by Affirmer's express Statement of Purpose. + +3. Public License Fallback. Should any part of the Waiver for any reason +be judged legally invalid or ineffective under applicable law, then the +Waiver shall be preserved to the maximum extent permitted taking into +account Affirmer's express Statement of Purpose. In addition, to the +extent the Waiver is so judged Affirmer hereby grants to each affected +person a royalty-free, non transferable, non sublicensable, non exclusive, +irrevocable and unconditional license to exercise Affirmer's Copyright and +Related Rights in the Work (i) in all territories worldwide, (ii) for the +maximum duration provided by applicable law or treaty (including future +time extensions), (iii) in any current or future medium and for any number +of copies, and (iv) for any purpose whatsoever, including without +limitation commercial, advertising or promotional purposes (the +"License"). The License shall be deemed effective as of the date CC0 was +applied by Affirmer to the Work. Should any part of the License for any +reason be judged legally invalid or ineffective under applicable law, such +partial invalidity or ineffectiveness shall not invalidate the remainder +of the License, and in such case Affirmer hereby affirms that he or she +will not (i) exercise any of his or her remaining Copyright and Related +Rights in the Work or (ii) assert any associated claims and causes of +action with respect to the Work, in either case contrary to Affirmer's +express Statement of Purpose. + +4. Limitations and Disclaimers. + + a. No trademark or patent rights held by Affirmer are waived, abandoned, + surrendered, licensed or otherwise affected by this document. + b. Affirmer offers the Work as-is and makes no representations or + warranties of any kind concerning the Work, express, implied, + statutory or otherwise, including without limitation warranties of + title, merchantability, fitness for a particular purpose, non + infringement, or the absence of latent or other defects, accuracy, or + the present or absence of errors, whether or not discoverable, all to + the greatest extent permissible under applicable law. + c. Affirmer disclaims responsibility for clearing rights of other persons + that may apply to the Work or any use thereof, including without + limitation any person's Copyright and Related Rights in the Work. + Further, Affirmer disclaims responsibility for obtaining any necessary + consents, permissions or other rights required for any use of the + Work. + d. Affirmer understands and acknowledges that Creative Commons is not a + party to this document and has no duty or obligation with respect to + this CC0 or use of the Work. diff --git a/web/server/h2o/libh2o/deps/picotls/deps/cifra/README.md b/web/server/h2o/libh2o/deps/picotls/deps/cifra/README.md new file mode 100644 index 00000000..e972912e --- /dev/null +++ b/web/server/h2o/libh2o/deps/picotls/deps/cifra/README.md @@ -0,0 +1,246 @@ +# Cifra +Cifra is a collection of cryptographic primitives targeted at embedded use. + +[![Build Status](https://travis-ci.org/ctz/cifra.svg?branch=master)](https://travis-ci.org/ctz/cifra) + +[![Documentation](https://readthedocs.org/projects/pip/badge/)](https://cifra.readthedocs.org/en/latest/) + +[![Analysis Status](https://scan.coverity.com/projects/4324/badge.svg)](https://scan.coverity.com/projects/4324) + +[![Coverage Status](https://coveralls.io/repos/ctz/cifra/badge.svg?branch=coveralls-scan)](https://coveralls.io/r/ctz/cifra?branch=coveralls-scan) + +## Aims +In order of descending emphasis, cifra aims for: + +* **Clarity** and **simplicity**. +* Countermeasures for side channel leaks inherent in some + algorithms. +* Suitability for embedded use. Particularly: cifra uses an + absolute minimum of the standard C library and is reasonably + efficient with respect to code and data space. + +## Features +* **AES** in the **GCM**, **CCM**, **EAX** and **OCB** authenticated encryption modes. +* **NORX** authenticated encryption system. +* **SHA224**, **SHA256**, **SHA384** and **SHA512** hash functions (including **HMAC** and **PBKDF2**). +* **SHA3-224**, **SHA3-256**, **SHA3-384**, **SHA3-512** hash functions (FIPS 202 compatible). +* **ChaCha20** and **Salsa20** stream ciphers. +* **Poly1305** one time MAC. +* 100% code coverage by line, zero static analysis defects, valgrind-clean. + +Additionally cifra imports curve25519 from elsewhere (μNaCl, NaCl, tweetNaCl, +Adam Langley's curve25519-donna) for comparison between various implementations +on embedded targets. + +## Documentation +Available at [Read the Docs](https://cifra.readthedocs.org/en/latest/). + +## Testing +There is quite a lot of testing available: + +* **Host builds**: run `make test` in the `src` directory. This builds and + runs assorted test programs. +* **Emulated embedded builds**: run `make test` in the `src/arm` directory. This + expects to find `qemu-system-gnuarmeclipse` on the path. These tests assume + a Cortex-M3 target. +* **Cortex-M0 on-target tests**: run `make test.stm32f0` in the `src/arm` directory. + This expects to find `openocd` on the path, with an STM32F0xx attached via + stlinkv2. It uses ARM semihosting to report results. +* **Cortex-M3/4 on-target tests**: run `make test.stm32f1` or `make test.stm32f3` as above. + +Additionally all embedded targets expect to find the `arm-none-eabi` toolchain +to be on the path. + +## Measurements +All measurements performed at `-Os` (optimise for space), on the following MCUs: + +Core | Part number | Price (1s) | Max clock | Flash | SRAM +---------- | ------------- | ------------ | ---------- | ----- | ----- +Cortex-M0 | STM32F030F4P6 | 1.17EUR | 48MHz | 16KB | 4KB +Cortex-M3 | STM32F103C8T6 | 2.87EUR | 72MHz | 64KB | 20KB +Cortex-M4F | STM32F303K6T6 | 4.53EUR | 72MHz | 32KB | 12KB + +More measurements are available for AEAD modes on my blog post: +[Benchmarking Modern Authenticated Encryption on €1 devices](http://jbp.io/2015/06/01/modern-authenticated-encryption-for-1-euro/). + +## AES +This test does a key schedule, then encrypts one block. + +### 128-bit key +Core | Cycles (key schedule + block) | Cycles (key schedule) | Cycles (block) | Stack | Code size +---------- | ----------------------------- | --------------------- | -------------- | ----- | --------- +Cortex-M0 | 7156 | 2147 | 5009 | 312B | 1020B +Cortex-M3 | 4692 | 1591 | 3101 | 300B | 960B +Cortex-M4F | 4591 | 1571 | 3020 | 300B | 960B + +### 256-bit key +Core | Cycles (key schedule + block) | Cycles (key schedule) | Cycles (block) | Stack | Code size +---------- | ----------------------------- | --------------------- | -------------- | ----- | --------- +Cortex-M0 | 10611 | 3650 | 6961 | 396B | 1100B +Cortex-M3 | 6735 | 2450 | 4285 | 380B | 1048B +Cortex-M4F | 6588 | 2416 | 4172 | 380B | 1048B + +## AES128-GCM +This test encrypts and authenticates a 16 byte message, +with 16 bytes additionally authenticated data. It includes +the initial key schedule. + +Core | Cycles | Stack | Code size +---------- | ------ | ----- | --------- +Cortex-M0 | 57022 | 796B | 2600B +Cortex-M3 | 44306 | 812B | 2644B +Cortex-M4F | 43657 | 812B | 2644B + +## AES128-EAX +This test encrypts and authenticates a 16 byte message, +with 16 bytes additionally authenticated data. It includes +the initial key schedule. + +Core | Cycles | Stack | Code size +---------- | ------ | ----- | --------- +Cortex-M0 | 50564 | 932B | 2836B +Cortex-M3 | 32855 | 932B | 2780B +Cortex-M4F | 32159 | 932B | 2780B + +## AES128-CCM +This test encrypts and authenticates a 16 byte message, +with 16 bytes additionally authenticated data. It includes +the initial key schedule. + +Core | Cycles | Stack | Code size +---------- | ------ | ----- | --------- +Cortex-M0 | 37677 | 772B | 2280B +Cortex-M3 | 24462 | 780B | 2256B +Cortex-M4F | 23949 | 780B | 2256B + +## NORX32 +This test encrypts and authenticates a 16 byte message, +with 16 bytes additionally authenticated data. + +Core | Cycles | Stack | Code size +---------- | ------ | ----- | --------- +Cortex-M0 | 10692 | 320B | 1636B +Cortex-M3 | 6909 | 320B | 1820B +Cortex-M4F | 6855 | 320B | 1820B + +## ChaCha20 +This test encrypts a 64 byte message. + +Core | Cycles | Stack | Code size +---------- | ------ | ----- | --------- +Cortex-M0 | 5981 | 564B | 1416B +Cortex-M3 | 3487 | 544B | 1328B +Cortex-M4F | 3468 | 544B | 1328B + +(For comparison with AES, add an AES256 key schedule plus 4 blocks. +That's about 33K cycles.) + +## Salsa20 +This test encrypts a 64 byte message. + +Core | Cycles | Stack | Code size +---------- | ------ | ----- | --------- +Cortex-M0 | 6173 | 560B | 1412B +Cortex-M3 | 3320 | 552B | 1272B +Cortex-M4F | 3311 | 552B | 1272B + +## SHA256 +This test hashes the empty string (one compression function invocation). + +Core | Cycles | Stack | Code size +---------- | ------ | ----- | --------- +Cortex-M0 | 11561 | 312B | 1760B +Cortex-M3 | 6530 | 300B | 1708B +Cortex-M4F | 6278 | 300B | 1708B + +## SHA512 +This test hashes the empty string (one compression function invocation). + +Core | Cycles | Stack | Code size +---------- | ------ | ----- | --------- +Cortex-M0 | 38447 | 796B | 2888B +Cortex-M3 | 28771 | 836B | 2988B +Cortex-M4F | 28777 | 836B | 2980B + +## SHA3-256 +This test hashes the empty string (one sponge permutation). + +Core | Cycles | Stack | Code size +---------- | ------ | ----- | --------- +Cortex-M0 | 93648 | 848B | 2212B +Cortex-M3 | 74321 | 856B | 2164B +Cortex-M4F | 72215 | 856B | 2140B + +## SHA3-512 +This test hashes the empty string (one sponge permutation). + +Core | Cycles | Stack | Code size +---------- | ------ | ----- | --------- +Cortex-M0 | 92565 | 880B | 2212B +Cortex-M3 | 73509 | 888B | 2164B +Cortex-M4F | 71419 | 888B | 2140B + +## HMAC-SHA256 +This test computes a MAC with a 32 byte key over the +message "hello world". + +Core | Cycles | Stack | Code size +---------- | ------ | ----- | --------- +Cortex-M0 | 48924 | 1328B | 2200B +Cortex-M3 | 28333 | 1324B | 2132B +Cortex-M4F | 27337 | 1324B | 2132B + +## Poly1305-AES +This test computes a MAC with a 32 byte key over the +message "hello world". It includes the AES nonce +processing. + +Core | Cycles | Stack | Code size +---------- | ------ | ----- | --------- +Cortex-M0 | 15719 | 704B | 1920B +Cortex-M3 | 11328 | 696B | 1964B +Cortex-M4F | 10706 | 696B | 1932B + +## Curve25519 +This test is one point multiplication. + +This uses the implementation from [μNaCl](http://munacl.cryptojedi.org/curve25519-cortexm0.shtml) +by Düll, Haase, Hinterwälder, Hutter, Paar, Sánchez and Schwabe. + +Core | Cycles | Stack | Code size +---------- | ------- | ----- | --------- +Cortex-M0 | 4070271 | 464B | 5596B +Cortex-M3 | 3720363 | 448B | 5536B +Cortex-M4F | 3720105 | 448B | 5536B + +See [curve25519-shootout](curve25519-shootout.md) for comparitive measurements +for other curve25519 implementations. + +## C library requirements +Cifra requires `memcpy`, `memset`, and `abort`. + +## Future +* ~~Keccak hash function (aka SHA3)~~. +* ~~Poly1305 one-time MAC~~. +* Constant time curve25519 for Cortex-M4F using the FPU. +* Constant time curve25519 for Cortex-M3 (avoiding the variable-time multiplier). + +## Notable past bugs/advisories +* [Issue #2](https://github.com/ctz/cifra/issues/2): in all versions before commit + [d62aa26e](https://github.com/ctz/cifra/commit/d62aa26e2c3c49e5b8a4298644cff290406d9357) + (September 16th 2015) too much padding was added when hashing messages of certain + lengths. Specifically, messages whose length satisfied `len % 64 = 55` for + SHA1/SHA224/SHA256 or `len % 128 = 119` for SHA384/SHA512. SHA3 was not affected. + Better testing is now in place. +* [Issue #3](https://github.com/ctz/cifra/issues/3): in all versions before commit + [82d77cd8](https://github.com/ctz/cifra/commit/82d77cd8323f6d4473fcb68517752a778970138d) + (April 16th 2016) EAX would produce wrong tags for empty AADs or messages. The + underlying CMAC is now more resistant to this case. + +## License +[CC0](https://creativecommons.org/publicdomain/zero/1.0/). + +Please attribute the author. This is a request only, and not a license term. + +## Author +Joseph Birr-Pixton diff --git a/web/server/h2o/libh2o/deps/picotls/deps/cifra/curve25519-shootout.md b/web/server/h2o/libh2o/deps/picotls/deps/cifra/curve25519-shootout.md new file mode 100644 index 00000000..6f057589 --- /dev/null +++ b/web/server/h2o/libh2o/deps/picotls/deps/cifra/curve25519-shootout.md @@ -0,0 +1,16 @@ +## Curve25519 on Cortex-M0 shootout +Implementation | Optimisation | Cycles | Code size | Stack usage +-------------- | ------------ | --------- | --------- | ----------- +donna | `-Os` | 15748K | 7.4KB | 3148B +donna | `-O2` | 15218K | 7.9KB | 3148B +donna | `-O3` | 12907K | 16KB | 3380B +naclref | `-Os` | 47813K | 3.2KB | 4012B +naclref | `-O2` | 34309K | 3.5KB | 4036B +naclref | `-O3` | 35059K | 4.1KB | 4044B +tweetnacl | `-Os` | 75979K | 2.8KB | 2244B +tweetnacl | `-O2` | 68876K | 3.0KB | 2268B +tweetnacl | `-O3` | 69622K | 8.9KB | 2900B + +naclref at -O2 seems to give a good balance. If you can spare the flash, +donna is quite significantly quicker. + diff --git a/web/server/h2o/libh2o/deps/picotls/deps/cifra/doc/Makefile b/web/server/h2o/libh2o/deps/picotls/deps/cifra/doc/Makefile new file mode 100644 index 00000000..2b7f5c03 --- /dev/null +++ b/web/server/h2o/libh2o/deps/picotls/deps/cifra/doc/Makefile @@ -0,0 +1,3 @@ +default: all +all: + sphinx-build -b html . _build diff --git a/web/server/h2o/libh2o/deps/picotls/deps/cifra/doc/build.py b/web/server/h2o/libh2o/deps/picotls/deps/cifra/doc/build.py new file mode 100644 index 00000000..0b006825 --- /dev/null +++ b/web/server/h2o/libh2o/deps/picotls/deps/cifra/doc/build.py @@ -0,0 +1,274 @@ +""" +Extracts documentation from cifra headers. + +We want to embed documentation in headers for good +locality. But want to write rst for formatting by sphinx. +This is a problem. + +'Breathe' provides a bridge between doxygen and sphinx, +but doxygen's documentation markup is pretty awful. + +Therefore, we write rst directly in C headers, and then +extract it here. The rules are: a C block comment +starting exactly '/* .. ' is dedented, and then included +verbatim. The convention is that the documentation +preceeds the C declarations they apply to, and that struct +members are documented before the struct they are contained +within. eg: + +/* .. c:function:: int foo(int bar) + * Foos a bar, returning the foo coefficient. + */ +int foo(int bar); + +/* .. c:type:: thing + * Container for things. + * + * .. c:member:: int thing.foo + * Count of foos. + * + * .. c:member:: int thing.bar + * Count of bars. + */ +typedef struct +{ + int foo; + int bar; +} thing; + +As a special effect, the following tokens are replaced +in the comments: + + - $DECL: the immediately following function declaration +""" + +import glob +import re +import StringIO + +# We know which headers constitute the external interface. +EXTERNAL = """ +aes +cf_config +chash +hmac +modes +pbkdf2 +prp +salsa20 +sha1 +sha2 +sha3 +norx +poly1305 +chacha20poly1305 +drbg +""".split() + +# Basic idea of a C identifier +C_IDENTIFIER = '[a-zA-Z_][a-zA-Z0-9_]+' + +DECL_RE = re.compile(r'^\s*(.+?' + C_IDENTIFIER + '\(.+?\));', re.MULTILINE | re.DOTALL) +COMMENT_RE = re.compile(r'^\s*\/\* (\.\..*?) \*\/$', re.MULTILINE | re.DOTALL) +INTRO_RE = re.compile(r'^\s*\/\*\*(.*?)\*\/$', re.MULTILINE | re.DOTALL) +NEW_SECTION_RE = re.compile(r'^..+\n(==+|--+)$', re.MULTILINE) + +class section(object): + def __init__(self): + self.intro = [] + self.macros = [] + self.types = [] + self.functions = [] + self.values = [] + + def __repr__(self): + return repr(self.format()[:30]) + + def __str__(self): + return repr(self.format()[:30]) + + def format(self): + f = StringIO.StringIO() + + def emit(title, section): + if len(section) == 0: + return + + if title: + print >>f, title + print >>f, '*' * len(title) + print >>f + + for s in section: + print >>f, s.getvalue() + + emit(None, self.intro) + emit('Macros', self.macros) + emit('Types', self.types) + emit('Functions', self.functions) + emit('Values', self.values) + + return f.getvalue() + + def is_empty(self): + items = len(self.intro) + len(self.macros) + len(self.types) + \ + len(self.functions) + len(self.values) + return 0 == items + + def add_item(self, sec): + f = StringIO.StringIO() + sec.append(f) + return f + +def massage_decl(decl): + """ + Tart-up a C function declaration: remove storage qualifiers, + smush onto one line, escape asterisks. + """ + for storage in 'extern static inline'.split(): + decl = decl.replace(storage + ' ', '') + + fixed_lines = ' '.join(line.strip() for line in decl.splitlines()) + + return fixed_lines.replace('*', '\\*') + +def replace_decl(comment, comment_match, header): + if '$DECL' not in comment: + return comment + + start = comment_match.end(0) + 1 + decl_match = DECL_RE.match(header, start) + + if decl_match is None: + print 'Cause:', comment + print 'Trailer:', header[start:start+60] + raise IOError('$DECL present but cannot find following DECL') + + decl = decl_match.group(1) + decl = massage_decl(decl) + return comment.replace('$DECL', decl) + +def decomment(lines): + for i in range(len(lines)): + if lines[i].startswith(' *'): + lines[i] = lines[i][3:] + lines[i] = lines[i].strip() + +def drop_empty_prefix(lines): + while len(lines) and lines[0] == '': + lines.pop(0) + +def starts_new_section(lines): + txt = '\n'.join(lines) + r = NEW_SECTION_RE.search(txt) is not None + return r + +def process(header, rst): + """ + Converts a header into restructured text. + + header is a file-like opened to read the header. + rst is a file-like opened to write the rst results. + """ + + hh = header.read() + + # Collect definitions into sections + sec = None + all_sections = [] + intro, macros, types, functions, values = [], [], [], [], [] + + def add_section(): + if sec and not sec.is_empty(): + all_sections.append(sec) + return section() + + sec = add_section() + + offs = 0 + + while True: + intro_match = INTRO_RE.search(hh, offs) + comment_match = COMMENT_RE.search(hh, offs) + + if intro_match is None and comment_match is None: + break + + # process earliest occuring + if intro_match is not None and (comment_match is None or intro_match.start(0) < comment_match.start(0)): + txt = intro_match.group(1) + + lines = txt.splitlines() + decomment(lines) + drop_empty_prefix(lines) + + if starts_new_section(lines): + sec = add_section() + + outf = sec.add_item(sec.intro) + + for l in lines: + print >>outf, l + offs = intro_match.end(0) + 1 + continue + + if comment_match is not None and (intro_match is None or comment_match.start(0) < intro_match.start(0)): + txt = comment_match.group(1) + + # work out which section this goes into + outf = None + if '.. c:macro::' in txt: + outf = sec.add_item(sec.macros) + elif '.. c:type::' in txt: + outf = sec.add_item(sec.types) + elif '.. c:var::' in txt: + outf = sec.add_item(sec.values) + elif '.. c:function::' in txt: + outf = sec.add_item(sec.functions) + elif '.. c:member::' in txt: + if len(types) == 0: + raise IOError('c:member must come after a c:type') + outf = types[-1] + else: + raise IOError('Cannot categorise item: ' + txt) + + # expand $DECL + txt = replace_decl(txt, comment_match, hh) + + # decomment lines + lines = txt.splitlines() + decomment(lines) + + # domain lines are unindented + while lines and lines[0].startswith('.. '): + print >>outf, lines.pop(0) + print >>outf + + # empty prefix lines are stripped + drop_empty_prefix(lines) + + # other lines are indented + for line in lines: + if len(line): + line = ' ' + line + print >>outf, line + + offs = comment_match.end(0) + 1 + continue + + add_section() + + for sec in all_sections: + rst.write(sec.format()) + +def run(): + for fn in EXTERNAL: + print '** build', fn + header = '../src/' + fn + '.h' + rst = fn + '.rst' + with open(header, 'r') as fh: + with open(rst, 'w') as fr: + process(fh, fr) + +if __name__ == '__main__': + run() diff --git a/web/server/h2o/libh2o/deps/picotls/deps/cifra/doc/conf.py b/web/server/h2o/libh2o/deps/picotls/deps/cifra/doc/conf.py new file mode 100644 index 00000000..8354354c --- /dev/null +++ b/web/server/h2o/libh2o/deps/picotls/deps/cifra/doc/conf.py @@ -0,0 +1,263 @@ +# -*- coding: utf-8 -*- +# +# Cifra documentation build configuration file, created by +# sphinx-quickstart on Sat Feb 21 18:02:37 2015. +# +# This file is execfile()d with the current directory set to its +# containing dir. +# +# Note that not all possible configuration values are present in this +# autogenerated file. +# +# All configuration values have a default; values that are commented out +# serve to show the default. + +import sys +import os + +# If extensions (or modules to document with autodoc) are in another directory, +# add these directories to sys.path here. If the directory is relative to the +# documentation root, use os.path.abspath to make it absolute, like shown here. +sys.path.insert(0, os.path.abspath('.')) + +import build +build.run() + +# -- General configuration ------------------------------------------------ + +# If your documentation needs a minimal Sphinx version, state it here. +#needs_sphinx = '1.0' + +# Add any Sphinx extension module names here, as strings. They can be +# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom +# ones. +extensions = [ + 'sphinx.ext.mathjax', +] + +# Add any paths that contain templates here, relative to this directory. +templates_path = ['_templates'] + +# The suffix of source filenames. +source_suffix = '.rst' + +# The encoding of source files. +#source_encoding = 'utf-8-sig' + +# The master toctree document. +master_doc = 'index' + +# General information about the project. +project = u'Cifra' +copyright = u'2015, Joseph Birr-Pixton' + +# The version info for the project you're documenting, acts as replacement for +# |version| and |release|, also used in various other places throughout the +# built documents. +# +# The short X.Y version. +version = '0.1' +# The full version, including alpha/beta/rc tags. +release = '0.1' + +# The language for content autogenerated by Sphinx. Refer to documentation +# for a list of supported languages. +#language = None + +# There are two options for replacing |today|: either, you set today to some +# non-false value, then it is used: +#today = '' +# Else, today_fmt is used as the format for a strftime call. +#today_fmt = '%B %d, %Y' + +# List of patterns, relative to source directory, that match files and +# directories to ignore when looking for source files. +exclude_patterns = ['_build'] + +# The reST default role (used for this markup: `text`) to use for all +# documents. +#default_role = None + +# If true, '()' will be appended to :func: etc. cross-reference text. +#add_function_parentheses = True + +# If true, the current module name will be prepended to all description +# unit titles (such as .. function::). +#add_module_names = True + +# If true, sectionauthor and moduleauthor directives will be shown in the +# output. They are ignored by default. +#show_authors = False + +# The name of the Pygments (syntax highlighting) style to use. +pygments_style = 'sphinx' + +# A list of ignored prefixes for module index sorting. +#modindex_common_prefix = [] + +# If true, keep warnings as "system message" paragraphs in the built documents. +#keep_warnings = False + + +# -- Options for HTML output ---------------------------------------------- + +# The theme to use for HTML and HTML Help pages. See the documentation for +# a list of builtin themes. +html_theme = 'default' + +# Theme options are theme-specific and customize the look and feel of a theme +# further. For a list of options available for each theme, see the +# documentation. +#html_theme_options = {} + +# Add any paths that contain custom themes here, relative to this directory. +#html_theme_path = [] + +# The name for this set of Sphinx documents. If None, it defaults to +# " v documentation". +#html_title = None + +# A shorter title for the navigation bar. Default is the same as html_title. +#html_short_title = None + +# The name of an image file (relative to this directory) to place at the top +# of the sidebar. +#html_logo = None + +# The name of an image file (within the static path) to use as favicon of the +# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 +# pixels large. +#html_favicon = None + +# Add any paths that contain custom static files (such as style sheets) here, +# relative to this directory. They are copied after the builtin static files, +# so a file named "default.css" will overwrite the builtin "default.css". +html_static_path = ['_static'] + +# Add any extra paths that contain custom files (such as robots.txt or +# .htaccess) here, relative to this directory. These files are copied +# directly to the root of the documentation. +#html_extra_path = [] + +# If not '', a 'Last updated on:' timestamp is inserted at every page bottom, +# using the given strftime format. +#html_last_updated_fmt = '%b %d, %Y' + +# If true, SmartyPants will be used to convert quotes and dashes to +# typographically correct entities. +#html_use_smartypants = True + +# Custom sidebar templates, maps document names to template names. +#html_sidebars = {} + +# Additional templates that should be rendered to pages, maps page names to +# template names. +#html_additional_pages = {} + +# If false, no module index is generated. +#html_domain_indices = True + +# If false, no index is generated. +#html_use_index = True + +# If true, the index is split into individual pages for each letter. +#html_split_index = False + +# If true, links to the reST sources are added to the pages. +#html_show_sourcelink = True + +# If true, "Created using Sphinx" is shown in the HTML footer. Default is True. +#html_show_sphinx = True + +# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True. +#html_show_copyright = True + +# If true, an OpenSearch description file will be output, and all pages will +# contain a tag referring to it. The value of this option must be the +# base URL from which the finished HTML is served. +#html_use_opensearch = '' + +# This is the file name suffix for HTML files (e.g. ".xhtml"). +#html_file_suffix = None + +# Output file base name for HTML help builder. +htmlhelp_basename = 'Cifradoc' + + +# -- Options for LaTeX output --------------------------------------------- + +latex_elements = { +# The paper size ('letterpaper' or 'a4paper'). +#'papersize': 'letterpaper', + +# The font size ('10pt', '11pt' or '12pt'). +#'pointsize': '10pt', + +# Additional stuff for the LaTeX preamble. +#'preamble': '', +} + +# Grouping the document tree into LaTeX files. List of tuples +# (source start file, target name, title, +# author, documentclass [howto, manual, or own class]). +latex_documents = [ + ('index', 'Cifra.tex', u'Cifra Documentation', + u'Joseph Birr-Pixton', 'manual'), +] + +# The name of an image file (relative to this directory) to place at the top of +# the title page. +#latex_logo = None + +# For "manual" documents, if this is true, then toplevel headings are parts, +# not chapters. +#latex_use_parts = False + +# If true, show page references after internal links. +#latex_show_pagerefs = False + +# If true, show URL addresses after external links. +#latex_show_urls = False + +# Documents to append as an appendix to all manuals. +#latex_appendices = [] + +# If false, no module index is generated. +#latex_domain_indices = True + + +# -- Options for manual page output --------------------------------------- + +# One entry per manual page. List of tuples +# (source start file, name, description, authors, manual section). +man_pages = [ + ('index', 'cifra', u'Cifra Documentation', + [u'Joseph Birr-Pixton'], 1) +] + +# If true, show URL addresses after external links. +#man_show_urls = False + + +# -- Options for Texinfo output ------------------------------------------- + +# Grouping the document tree into Texinfo files. List of tuples +# (source start file, target name, title, author, +# dir menu entry, description, category) +texinfo_documents = [ + ('index', 'Cifra', u'Cifra Documentation', + u'Joseph Birr-Pixton', 'Cifra', 'One line description of project.', + 'Miscellaneous'), +] + +# Documents to append as an appendix to all manuals. +#texinfo_appendices = [] + +# If false, no module index is generated. +#texinfo_domain_indices = True + +# How to display URL addresses: 'footnote', 'no', or 'inline'. +#texinfo_show_urls = 'footnote' + +# If true, do not generate a @detailmenu in the "Top" node's menu. +#texinfo_no_detailmenu = False diff --git a/web/server/h2o/libh2o/deps/picotls/deps/cifra/doc/index.rst b/web/server/h2o/libh2o/deps/picotls/deps/cifra/doc/index.rst new file mode 100644 index 00000000..e853de4a --- /dev/null +++ b/web/server/h2o/libh2o/deps/picotls/deps/cifra/doc/index.rst @@ -0,0 +1,33 @@ +.. Cifra documentation master file, created by + sphinx-quickstart on Sat Feb 21 18:02:37 2015. + You can adapt this file completely to your liking, but it should at least + contain the root `toctree` directive. + +Welcome to Cifra's documentation! +================================= + +Contents: + +.. toctree:: + :maxdepth: 2 + + cf_config + prp + chash + aes + norx + salsa20 + modes + hmac + poly1305 + chacha20poly1305 + pbkdf2 + sha1 + sha2 + sha3 + drbg + +Index +----- +* :ref:`genindex` + diff --git a/web/server/h2o/libh2o/deps/picotls/deps/cifra/extra_vecs/.gitignore b/web/server/h2o/libh2o/deps/picotls/deps/cifra/extra_vecs/.gitignore new file mode 100644 index 00000000..2163875d --- /dev/null +++ b/web/server/h2o/libh2o/deps/picotls/deps/cifra/extra_vecs/.gitignore @@ -0,0 +1 @@ +openssl-hash diff --git a/web/server/h2o/libh2o/deps/picotls/deps/cifra/extra_vecs/Makefile b/web/server/h2o/libh2o/deps/picotls/deps/cifra/extra_vecs/Makefile new file mode 100644 index 00000000..065721c2 --- /dev/null +++ b/web/server/h2o/libh2o/deps/picotls/deps/cifra/extra_vecs/Makefile @@ -0,0 +1,13 @@ +CFLAGS += -std=gnu99 -O0 -g -Wall -Werror + +all: run + +openssl-hash: openssl-hash.c + $(CC) $(CFLAGS) -o $@ $^ -lcrypto + +run: openssl-hash + ./openssl-hash + python python-hash.py + +clean: + rm -rf *.o openssl-hash diff --git a/web/server/h2o/libh2o/deps/picotls/deps/cifra/extra_vecs/README.md b/web/server/h2o/libh2o/deps/picotls/deps/cifra/extra_vecs/README.md new file mode 100644 index 00000000..a7d38287 --- /dev/null +++ b/web/server/h2o/libh2o/deps/picotls/deps/cifra/extra_vecs/README.md @@ -0,0 +1,2 @@ +This directory contains assorted programs for generating test vectors +from other crypto libraries, like OpenSSL. diff --git a/web/server/h2o/libh2o/deps/picotls/deps/cifra/extra_vecs/openssl-hash.c b/web/server/h2o/libh2o/deps/picotls/deps/cifra/extra_vecs/openssl-hash.c new file mode 100644 index 00000000..9df68566 --- /dev/null +++ b/web/server/h2o/libh2o/deps/picotls/deps/cifra/extra_vecs/openssl-hash.c @@ -0,0 +1,60 @@ +#include +#include + +#include + +#define MAX_LENGTH 1024 + +static void printhex(const uint8_t *buf, size_t len) +{ + for (size_t i = 0; i < len; i++) + printf("%02x", buf[i]); +} + +/* This test produces a single hash value which depends on + * hashes with all preimage lengths up to max. + * + * It emits + * H(H(t(0)) || H(t(1)) || ... || H(t(max-1)))) + * where + * t(n) = (n % 256) ^ n + * (informally, t(n) is a n-length octet string of octets with value n mod 256) + */ +static void emit_length_test(const char *name, const EVP_MD *h, size_t max) +{ + EVP_MD_CTX outer, inner; + EVP_DigestInit(&outer, h); + uint8_t digest[EVP_MAX_MD_SIZE]; + unsigned int digestlen; + + for (size_t n = 0; n < max; n++) + { + EVP_DigestInit(&inner, h); + for (size_t i = 0; i < n; i++) + { + uint8_t byte = n & 0xff; + EVP_DigestUpdate(&inner, &byte, 1); + } + digestlen = sizeof digest; + EVP_DigestFinal(&inner, digest, &digestlen); + + EVP_DigestUpdate(&outer, digest, digestlen); + } + + digestlen = sizeof digest; + EVP_DigestFinal(&outer, digest, &digestlen); + + printf("%s(%zu) = ", name, max); + printhex(digest, (size_t) digestlen); + printf("\n"); +} + +int main(void) +{ + emit_length_test("SHA1", EVP_sha1(), MAX_LENGTH); + emit_length_test("SHA224", EVP_sha224(), MAX_LENGTH); + emit_length_test("SHA256", EVP_sha256(), MAX_LENGTH); + emit_length_test("SHA384", EVP_sha384(), MAX_LENGTH); + emit_length_test("SHA512", EVP_sha512(), MAX_LENGTH); + return 0; +} diff --git a/web/server/h2o/libh2o/deps/picotls/deps/cifra/extra_vecs/python-hash.py b/web/server/h2o/libh2o/deps/picotls/deps/cifra/extra_vecs/python-hash.py new file mode 100644 index 00000000..90aa248f --- /dev/null +++ b/web/server/h2o/libh2o/deps/picotls/deps/cifra/extra_vecs/python-hash.py @@ -0,0 +1,38 @@ +#!/usr/bin/python2 + +# +# see openssl-hash for details of what this is computing +# you'll need python-sha3 from https://github.com/bjornedstrom/python-sha3 +# + +import hashlib +import sha3 + +# check sha3 at least works; pysha3 *DOES NOT* (it is keccak, not sha3) +assert '3a985da74fe225b2045c172d6bd390bd855f086e3e9d525b46bfe24511431532' == hashlib.sha3_256('abc').hexdigest() + +def hh(x): + return ''.join(['\\x' + x[y:y+2] for y in range(0, len(x), 2)]) + +def len_test(name, H, max): + outer = H() + + for n in range(max): + inner = H() + inner.update(chr(n & 0xff) * n) + outer.update(inner.digest()) + + result = outer.hexdigest() + print '%s(%d) = %s or %s' % (name, max, result, hh(result)) + +if __name__ == '__main__': + MAX = 1024 + len_test('SHA1', hashlib.sha1, MAX) + len_test('SHA224', hashlib.sha224, MAX) + len_test('SHA256', hashlib.sha256, MAX) + len_test('SHA384', hashlib.sha384, MAX) + len_test('SHA512', hashlib.sha512, MAX) + len_test('SHA3-224', hashlib.sha3_224, MAX) + len_test('SHA3-256', hashlib.sha3_256, MAX) + len_test('SHA3-384', hashlib.sha3_384, MAX) + len_test('SHA3-512', hashlib.sha3_512, MAX) diff --git a/web/server/h2o/libh2o/deps/picotls/deps/cifra/shitlisp/.gitignore b/web/server/h2o/libh2o/deps/picotls/deps/cifra/shitlisp/.gitignore new file mode 100644 index 00000000..3bd32750 --- /dev/null +++ b/web/server/h2o/libh2o/deps/picotls/deps/cifra/shitlisp/.gitignore @@ -0,0 +1,5 @@ +*.o +*.so +*.gcov +*.gcno +*.gcda diff --git a/web/server/h2o/libh2o/deps/picotls/deps/cifra/shitlisp/Makefile b/web/server/h2o/libh2o/deps/picotls/deps/cifra/shitlisp/Makefile new file mode 100644 index 00000000..ccbda7eb --- /dev/null +++ b/web/server/h2o/libh2o/deps/picotls/deps/cifra/shitlisp/Makefile @@ -0,0 +1,17 @@ +CFLAGS += -g -O0 -std=gnu99 -fPIC -Wall -Wextra -Werror -Wno-unused-parameter +CPPFLAGS += -I../src -I../../bignum/out -I../../shitlisp/out + +all: cifra.so + +SOURCES = aes.o sha256.o sha512.o chash.o hmac.o pbkdf2.o modes.o eax.o \ + blockwise.o cmac.o salsa20.o chacha20.o curve25519.o + +cifra.so: $(addprefix ../src/, $(SOURCES)) sl-cifra.o + $(CC) $(CPPFLAGS) $(CFLAGS) -o $@ $^ -shared + +clean: + rm -f *.o *.pyc $(TARGETS) *.gcov *.gcda *.gcno + +test: $(wildcard test-*.sl) cifra.so + ../../shitlisp/out/shitlisp --mod=./cifra.so $(wildcard test-*.sl) + diff --git a/web/server/h2o/libh2o/deps/picotls/deps/cifra/shitlisp/sl-cifra.c b/web/server/h2o/libh2o/deps/picotls/deps/cifra/shitlisp/sl-cifra.c new file mode 100644 index 00000000..6d7b944f --- /dev/null +++ b/web/server/h2o/libh2o/deps/picotls/deps/cifra/shitlisp/sl-cifra.c @@ -0,0 +1,206 @@ +#include "handy.h" +#include "dstr.h" +#include "shitlisp.h" +#include "aes.h" +#include "sha2.h" +#include "hmac.h" +#include "pbkdf2.h" + +#include + +static sl_value * aes_block_fn(sl_value *self, sl_value *args, sl_symboltab *tab, + void (*blockfn)(const cf_aes_context *ctx, + const uint8_t *in, + uint8_t *out)) +{ + sl_iter it = sl_iter_start(args); + sl_value *key = sl_iter_convert(&it, sl_preprocess_eval, sl_assert_bytes, tab); + sl_value *block = sl_iter_convert(&it, sl_preprocess_eval, sl_assert_bytes, tab); + + sl_value *ret = NULL; + + if (!key || !block || + (key->u.bytes.len != 16 && key->u.bytes.len != 24 && key->u.bytes.len != 32) || + block->u.bytes.len != AES_BLOCKSZ) + { + ret = sl_get_nil(); + goto x_err; + } + + cf_aes_context ctx; + cf_aes_init(&ctx, key->u.bytes.buf, key->u.bytes.len); + uint8_t blockout[AES_BLOCKSZ]; + blockfn(&ctx, block->u.bytes.buf, blockout); + ret = sl_new_bytes(blockout, AES_BLOCKSZ); + cf_aes_finish(&ctx); + +x_err: + sl_decref(key); + sl_decref(block); + return ret; +} + +static sl_value * aes_block_encrypt(sl_value *self, sl_value *args, sl_symboltab *tab) +{ + return aes_block_fn(self, args, tab, cf_aes_encrypt); +} + +static sl_value * aes_block_decrypt(sl_value *self, sl_value *args, sl_symboltab *tab) +{ + return aes_block_fn(self, args, tab, cf_aes_decrypt); +} + +/* Hashing */ +static sl_value * hash_fn(sl_value *self, sl_value *args, sl_symboltab *tab, const cf_chash *h) +{ + sl_iter it = sl_iter_start(args); + sl_value *msg = sl_iter_convert(&it, sl_preprocess_eval, sl_assert_bytes, tab); + + if (!msg) + return sl_get_nil(); + + cf_chash_ctx ctx; + assert(h->ctxsz <= CF_CHASH_MAXCTX); + h->init(&ctx); + h->update(&ctx, msg->u.bytes.buf, msg->u.bytes.len); + sl_decref(msg); + + uint8_t result[CF_MAXHASH]; + assert(h->hashsz <= CF_MAXHASH); + h->digest(&ctx, result); + + return sl_new_bytes(result, h->hashsz); +} + +static sl_value * sha224(sl_value *self, sl_value *args, sl_symboltab *tab) +{ + return hash_fn(self, args, tab, &cf_sha224); +} + +static sl_value * sha256(sl_value *self, sl_value *args, sl_symboltab *tab) +{ + return hash_fn(self, args, tab, &cf_sha256); +} + +static sl_value * sha384(sl_value *self, sl_value *args, sl_symboltab *tab) +{ + return hash_fn(self, args, tab, &cf_sha384); +} + +static sl_value * sha512(sl_value *self, sl_value *args, sl_symboltab *tab) +{ + return hash_fn(self, args, tab, &cf_sha512); +} + +/* HMAC */ +static sl_value * hmac_fn(sl_value *self, sl_value *args, sl_symboltab *tab, const cf_chash *h) +{ + sl_iter it = sl_iter_start(args); + sl_value *key = sl_iter_convert(&it, sl_preprocess_eval, sl_assert_bytes, tab); + sl_value *msg = sl_iter_convert(&it, sl_preprocess_eval, sl_assert_bytes, tab); + + if (!key || !msg) + { + sl_decref(key); + sl_decref(msg); + return sl_get_nil(); + } + + uint8_t result[CF_MAXHASH]; + cf_hmac(key->u.bytes.buf, key->u.bytes.len, + msg->u.bytes.buf, msg->u.bytes.len, + result, + h); + + sl_decref(key); + sl_decref(msg); + return sl_new_bytes(result, h->hashsz); +} + +static sl_value * hmac_sha224(sl_value *self, sl_value *args, sl_symboltab *tab) +{ return hmac_fn(self, args, tab, &cf_sha224); } + +static sl_value * hmac_sha256(sl_value *self, sl_value *args, sl_symboltab *tab) +{ return hmac_fn(self, args, tab, &cf_sha256); } + +static sl_value * hmac_sha384(sl_value *self, sl_value *args, sl_symboltab *tab) +{ return hmac_fn(self, args, tab, &cf_sha384); } + +static sl_value * hmac_sha512(sl_value *self, sl_value *args, sl_symboltab *tab) +{ return hmac_fn(self, args, tab, &cf_sha512); } + + +/* PBKDF2 */ +static sl_value * do_pbkdf2(const cf_chash *h, sl_value *pw, sl_value *salt, + uint32_t iterations, uint32_t outlen) +{ + dstr out; + dstr_init(&out); + if (dstr_expand(&out, outlen)) + return NULL; + + cf_pbkdf2_hmac(pw->u.bytes.buf, pw->u.bytes.len, + salt->u.bytes.buf, salt->u.bytes.len, + iterations, + (uint8_t *) out.start, outlen, + h); + + sl_value *ret = sl_new_bytes((uint8_t *) out.start, outlen); + dstr_free(&out); + return ret; +} + +static sl_value * pbkdf2_fn(sl_value *self, sl_value *args, sl_symboltab *tab, const cf_chash *h) +{ + sl_iter it = sl_iter_start(args); + sl_value *pw = sl_iter_convert(&it, sl_preprocess_eval, sl_assert_bytes, tab); + sl_value *salt = sl_iter_convert(&it, sl_preprocess_eval, sl_assert_bytes, tab); + sl_value *iterations = sl_iter_convert(&it, sl_preprocess_eval, sl_assert_integer, tab); + sl_value *outlen = sl_iter_convert(&it, sl_preprocess_eval, sl_assert_integer, tab); + + sl_value *ret; + + if (!pw || !salt || !iterations || !outlen) + ret = sl_get_nil(); + else + { + assert(bignum_len_words(&iterations->u.integer.bn) == 1); + assert(bignum_len_words(&outlen->u.integer.bn) == 1); + ret = do_pbkdf2(h, pw, salt, + iterations->u.integer.bn.v[0], + outlen->u.integer.bn.v[0]); + } + + sl_decref(pw); + sl_decref(salt); + sl_decref(iterations); + sl_decref(outlen); + return ret; +} + +static sl_value * pbkdf2_sha224(sl_value *self, sl_value *args, sl_symboltab *tab) +{ + return pbkdf2_fn(self, args, tab, &cf_sha224); +} + +static sl_value * pbkdf2_sha256(sl_value *self, sl_value *args, sl_symboltab *tab) +{ + return pbkdf2_fn(self, args, tab, &cf_sha256); +} + +int SL_MODULE_ENTRY(sl_symboltab *tab) +{ + ER(sl_symboltab_add_name_native(tab, "aes-encrypt", aes_block_encrypt)); + ER(sl_symboltab_add_name_native(tab, "aes-decrypt", aes_block_decrypt)); + ER(sl_symboltab_add_name_native(tab, "sha224", sha224)); + ER(sl_symboltab_add_name_native(tab, "sha256", sha256)); + ER(sl_symboltab_add_name_native(tab, "sha384", sha384)); + ER(sl_symboltab_add_name_native(tab, "sha512", sha512)); + ER(sl_symboltab_add_name_native(tab, "hmac-sha224", hmac_sha224)); + ER(sl_symboltab_add_name_native(tab, "hmac-sha256", hmac_sha256)); + ER(sl_symboltab_add_name_native(tab, "hmac-sha384", hmac_sha384)); + ER(sl_symboltab_add_name_native(tab, "hmac-sha512", hmac_sha512)); + ER(sl_symboltab_add_name_native(tab, "pbkdf2-sha224", pbkdf2_sha224)); + ER(sl_symboltab_add_name_native(tab, "pbkdf2-sha256", pbkdf2_sha256)); + return 0; +} diff --git a/web/server/h2o/libh2o/deps/picotls/deps/cifra/shitlisp/test-aes.sl b/web/server/h2o/libh2o/deps/picotls/deps/cifra/shitlisp/test-aes.sl new file mode 100644 index 00000000..5535c5de --- /dev/null +++ b/web/server/h2o/libh2o/deps/picotls/deps/cifra/shitlisp/test-aes.sl @@ -0,0 +1,91 @@ +(def check-aes (key pt ct) + (+ + (assert (= + ct + (aes-encrypt key pt))) + (assert (= + pt + (aes-decrypt key ct))) + ) +) + +(check-aes + [000102030405060708090a0b0c0d0e0f] + [00112233445566778899aabbccddeeff] + [69c4e0d86a7b0430d8cdb78070b4c55a] +) +(check-aes + [000102030405060708090a0b0c0d0e0f1011121314151617] + [00112233445566778899aabbccddeeff] + [dda97ca4864cdfe06eaf70a0ec0d7191] +) +(check-aes + [000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f] + [00112233445566778899aabbccddeeff] + [8ea2b7ca516745bfeafc49904b496089] +) + +(check-aes + [2b7e151628aed2a6abf7158809cf4f3c] + [6bc1bee22e409f96e93d7e117393172a] + [3ad77bb40d7a3660a89ecaf32466ef97] +) +(check-aes + [2b7e151628aed2a6abf7158809cf4f3c] + [ae2d8a571e03ac9c9eb76fac45af8e51] + [f5d3d58503b9699de785895a96fdbaaf] +) +(check-aes + [2b7e151628aed2a6abf7158809cf4f3c] + [30c81c46a35ce411e5fbc1191a0a52ef] + [43b1cd7f598ece23881b00e3ed030688] +) +(check-aes + [2b7e151628aed2a6abf7158809cf4f3c] + [f69f2445df4f9b17ad2b417be66c3710] + [7b0c785e27e8ad3f8223207104725dd4] +) + +(check-aes + [8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b] + [6bc1bee22e409f96e93d7e117393172a] + [bd334f1d6e45f25ff712a214571fa5cc] +) +(check-aes + [8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b] + [ae2d8a571e03ac9c9eb76fac45af8e51] + [974104846d0ad3ad7734ecb3ecee4eef] +) +(check-aes + [8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b] + [30c81c46a35ce411e5fbc1191a0a52ef] + [ef7afd2270e2e60adce0ba2face6444e] +) +(check-aes + [8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b] + [f69f2445df4f9b17ad2b417be66c3710] + [9a4b41ba738d6c72fb16691603c18e0e] +) + +(check-aes + [603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4] + [6bc1bee22e409f96e93d7e117393172a] + [f3eed1bdb5d2a03c064b5a7e3db181f8] +) +(check-aes + [603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4] + [ae2d8a571e03ac9c9eb76fac45af8e51] + [591ccb10d410ed26dc5ba74a31362870] +) +(check-aes + [603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4] + [30c81c46a35ce411e5fbc1191a0a52ef] + [b6ed21b99ca6f4f9f153e7b1beafed1d] +) +(check-aes + [603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4] + [f69f2445df4f9b17ad2b417be66c3710] + [23304b7a39f9f3ff067d8d8f9e24ecc7] +) + +(puts success) diff --git a/web/server/h2o/libh2o/deps/picotls/deps/cifra/shitlisp/test-pbkdf2.sl b/web/server/h2o/libh2o/deps/picotls/deps/cifra/shitlisp/test-pbkdf2.sl new file mode 100644 index 00000000..b87f3970 --- /dev/null +++ b/web/server/h2o/libh2o/deps/picotls/deps/cifra/shitlisp/test-pbkdf2.sl @@ -0,0 +1,36 @@ +(assert (= + (pbkdf2-sha256 (bytes "password") (bytes "salt") 1 32) + [120fb6cffcf8b32c43e7225256c4f837a86548c92ccc35480805987cb70be17b]) +) + +(assert (= + (pbkdf2-sha256 (bytes "password") (bytes "salt") 2 32) + [ae4d0c95af6b46d32d0adff928f06dd02a303f8ef3c251dfd6e2d85a95474c43]) +) + +(assert (= + (pbkdf2-sha256 (bytes "password") (bytes "salt") 4096 32) + [c5e478d59288c841aa530db6845c4c8d962893a001ce4e11a4963873aa98134a]) +) + +(assert (= + (pbkdf2-sha256 (bytes "passwordPASSWORDpassword") (bytes "saltSALTsaltSALTsaltSALTsaltSALTsalt") 4096 40) + [348c89dbcbd32b2f32d814b8116e84cf2b17347ebc1800181c4e2a1fb8dd53e1c635518c7dac47e9]) +) + +(assert (= + (pbkdf2-sha256 [] (bytes "salt") 1024 32) + [9e83f279c040f2a11aa4a02b24c418f2d3cb39560c9627fa4f47e3bcc2897c3d]) +) + +(assert (= + (pbkdf2-sha256 (bytes "password") [] 1024 32) + [ea5808411eb0c7e830deab55096cee582761e22a9bc034e3ece925225b07bf46]) +) + +(assert (= + (pbkdf2-sha256 [7061737300776f7264] [7361006c74] 4096 16) + [89b69d0516f829893c696226650a8687]) +) + +(puts success) diff --git a/web/server/h2o/libh2o/deps/picotls/deps/cifra/shitlisp/test-sha224.sl b/web/server/h2o/libh2o/deps/picotls/deps/cifra/shitlisp/test-sha224.sl new file mode 100644 index 00000000..5de9e151 --- /dev/null +++ b/web/server/h2o/libh2o/deps/picotls/deps/cifra/shitlisp/test-sha224.sl @@ -0,0 +1,41 @@ +(assert (= + (sha224 (bytes "abc")) + [23097d22 3405d822 8642a477 bda255b3 2aadbce4 bda0b3f7 e36c9da7]) +) + +(assert (= + (sha224 []) + [d14a028c 2a3a2bc9 476102bb 288234c4 15a2b01f 828ea62a c5b3e42f]) +) + +(assert (= + (hmac-sha224 (* [0b] 20) (bytes "Hi There")) + [896fb1128abbdf196832107cd49df33f47b4b1169912ba4f53684b22]) +) + +(assert (= + (hmac-sha224 (bytes "Jefe") (bytes "what do ya want for nothing?")) + [a30e01098bc6dbbf45690f3a7e9e6d0f8bbea2a39e6148008fd05e44]) +) + +(assert (= + (hmac-sha224 (* [aa] 20) (* [dd] 50)) + [7fb3cb3588c6c1f6ffa9694d7d6ad2649365b0c1f65d69d1ec8333ea]) +) + +(assert (= + (hmac-sha224 [0102030405060708090a0b0c0d0e0f10111213141516171819] (* [cd] 50)) + [6c11506874013cac6a2abc1bb382627cec6a90d86efc012de7afec5a]) +) + +(assert (= + (hmac-sha224 (* [aa] 131) (bytes "Test Using Larger Than Block-Size Key - Hash Key First")) + [95e9a0db962095adaebe9b2d6f0dbce2d499f112f2d2b7273fa6870e]) +) + +(assert (= + (hmac-sha224 (* [aa] 131) (bytes "This is a test using a larger than block-size key and a larger than block-size data. The key needs to be hashed before being used by the HMAC algorithm.")) + [3a854166ac5d9f023f54d517d0b39dbd946770db9c2b95c9f6f565d1]) +) + +(puts success) diff --git a/web/server/h2o/libh2o/deps/picotls/deps/cifra/shitlisp/test-sha256.sl b/web/server/h2o/libh2o/deps/picotls/deps/cifra/shitlisp/test-sha256.sl new file mode 100644 index 00000000..83c04573 --- /dev/null +++ b/web/server/h2o/libh2o/deps/picotls/deps/cifra/shitlisp/test-sha256.sl @@ -0,0 +1,62 @@ +(assert (= + (sha256 (bytes "abc")) + [ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad]) +) + +(assert (= + (sha256 (bytes "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq")) + [248d6a61d20638b8e5c026930c3e6039a33ce45964ff2167f6ecedd419db06c1]) +) + +(assert (= + (sha256 (* (bytes "a") 1000000)) + [cdc76e5c9914fb9281a1c7e284d73e67f1809a48a497200e046d39ccc7112cd0]) +) + +(assert (= + (sha256 (bytes "The quick brown fox jumps over the lazy dog")) + [d7a8fbb307d7809469ca9abcb0082e4f8d5651e46d3cdb762d02d0bf37c9e592]) +) + +(assert (= + (sha256 (bytes "The quick brown fox jumps over the lazy cog")) + [e4c4d8f3bf76b692de791a173e05321150f7a345b46484fe427f6acc7ecc81be]) +) + +(assert (= + (sha256 []) + [e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855]) +) + +(assert (= + (hmac-sha256 (* [0b] 20) (bytes "Hi There")) + [b0344c61d8db38535ca8afceaf0bf12b881dc200c9833da726e9376c2e32cff7]) +) + +(assert (= + (hmac-sha256 (bytes "Jefe") (bytes "what do ya want for nothing?")) + [5bdcc146bf60754e6a042426089575c75a003f089d2739839dec58b964ec3843]) +) + +(assert (= + (hmac-sha256 (* [aa] 20) (* [dd] 50)) + [773ea91e36800e46854db8ebd09181a72959098b3ef8c122d9635514ced565fe]) +) + +(assert (= + (hmac-sha256 [0102030405060708090a0b0c0d0e0f10111213141516171819] (* [cd] 50)) + [82558a389a443c0ea4cc819899f2083a85f0faa3e578f8077a2e3ff46729665b]) +) + +(assert (= + (hmac-sha256 (* [aa] 131) (bytes "Test Using Larger Than Block-Size Key - Hash Key First")) + [60e431591ee0b67f0d8a26aacbf5b77f8e0bc6213728c5140546040f0ee37f54]) +) + +(assert (= + (hmac-sha256 (* [aa] 131) (bytes "This is a test using a larger than block-size key and a larger than block-size data. The key needs to be hashed before being used by the HMAC algorithm.")) + [9b09ffa71b942fcb27635fbcd5b0e944bfdc63644f0713938a7f51535c3a35e2]) +) + + +(puts success) diff --git a/web/server/h2o/libh2o/deps/picotls/deps/cifra/shitlisp/test-sha384.sl b/web/server/h2o/libh2o/deps/picotls/deps/cifra/shitlisp/test-sha384.sl new file mode 100644 index 00000000..33a00ee6 --- /dev/null +++ b/web/server/h2o/libh2o/deps/picotls/deps/cifra/shitlisp/test-sha384.sl @@ -0,0 +1,67 @@ +(assert (= + (sha384 (bytes "abc")) + [cb00753f45a35e8b b5a03d699ac65007 272c32ab0eded163 1a8b605a43ff5bed 8086072ba1e7cc23 58baeca134c825a7]) +) + +(assert (= + (sha384 (bytes "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq")) + [3391fdddfc8dc739 3707a65b1b470939 7cf8b1d162af05ab fe8f450de5f36bc6 b0455a8520bc4e6f 5fe95b1fe3c8452b]) +) + +(assert (= + (sha384 (bytes "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu")) + [09330c33f71147e8 3d192fc782cd1b47 53111b173b3b05d2 2fa08086e3b0f712 fcc7c71a557e2db9 66c3e9fa91746039]) +) + +(assert (= + (sha384 (* (bytes "a") 1000000)) + [9d0e1809716474cb 086e834e310a4a1c ed149e9c00f24852 7972cec5704c2a5b 07b8b3dc38ecc4eb ae97ddd87f3d8985]) +) + +(assert (= + (sha384 (bytes "The quick brown fox jumps over the lazy dog")) + [ca737f1014a48f4c0b6dd43cb177b0afd9e5169367544c494011e3317dbf9a509cb1e5dc1e85a941bbee3d7f2afbc9b1]) +) + +(assert (= + (sha384 (bytes "The quick brown fox jumps over the lazy cog")) + [098cea620b0978caa5f0befba6ddcf22764bea977e1c70b3483edfdf1de25f4b40d6cea3cadf00f809d422feb1f0161b]) +) + +(assert (= + (sha384 []) + [38b060a751ac9638 4cd9327eb1b1e36a 21fdb71114be0743 4c0cc7bf63f6e1da 274edebfe76f65fb d51ad2f14898b95b]) +) + +(assert (= + (hmac-sha384 (* [0b] 20) (bytes "Hi There")) + [afd03944d84895626b0825f4ab46907f15f9dadbe4101ec682aa034c7cebc59cfaea9ea9076ede7f4af152e8b2fa9cb6]) +) + +(assert (= + (hmac-sha384 (bytes "Jefe") (bytes "what do ya want for nothing?")) + [af45d2e376484031617f78d2b58a6b1b9c7ef464f5a01b47e42ec3736322445e8e2240ca5e69e2c78b3239ecfab21649]) +) + +(assert (= + (hmac-sha384 (* [aa] 20) (* [dd] 50)) + [88062608d3e6ad8a0aa2ace014c8a86f0aa635d947ac9febe83ef4e55966144b2a5ab39dc13814b94e3ab6e101a34f27]) +) + +(assert (= + (hmac-sha384 [0102030405060708090a0b0c0d0e0f10111213141516171819] (* [cd] 50)) + [3e8a69b7783c25851933ab6290af6ca77a9981480850009cc5577c6e1f573b4e6801dd23c4a7d679ccf8a386c674cffb]) +) + +(assert (= + (hmac-sha384 (* [aa] 131) (bytes "Test Using Larger Than Block-Size Key - Hash Key First")) + [4ece084485813e9088d2c63a041bc5b44f9ef1012a2b588f3cd11f05033ac4c60c2ef6ab4030fe8296248df163f44952]) +) + +(assert (= + (hmac-sha384 (* [aa] 131) (bytes "This is a test using a larger than block-size key and a larger than block-size data. The key needs to be hashed before being used by the HMAC algorithm.")) + [6617178e941f020d351e2f254e8fd32c602420feb0b8fb9adccebb82461e99c5a678cc31e799176d3860e6110c46523e]) +) + + +(puts success) diff --git a/web/server/h2o/libh2o/deps/picotls/deps/cifra/shitlisp/test-sha512.sl b/web/server/h2o/libh2o/deps/picotls/deps/cifra/shitlisp/test-sha512.sl new file mode 100644 index 00000000..42010199 --- /dev/null +++ b/web/server/h2o/libh2o/deps/picotls/deps/cifra/shitlisp/test-sha512.sl @@ -0,0 +1,67 @@ +(assert (= + (sha512 (bytes "abc")) + [ddaf35a193617aba cc417349ae204131 12e6fa4e89a97ea2 0a9eeee64b55d39a 2192992a274fc1a8 36ba3c23a3feebbd 454d4423643ce80e 2a9ac94fa54ca49f]) +) + +(assert (= + (sha512 (bytes "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq")) + [204a8fc6dda82f0a 0ced7beb8e08a416 57c16ef468b228a8 279be331a703c335 96fd15c13b1b07f9 aa1d3bea57789ca0 31ad85c7a71dd703 54ec631238ca3445]) +) + +(assert (= + (sha512 (bytes "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu")) + [8e959b75dae313da 8cf4f72814fc143f 8f7779c6eb9f7fa1 7299aeadb6889018 501d289e4900f7e4 331b99dec4b5433a c7d329eeb6dd2654 5e96e55b874be909]) +) + +(assert (= + (sha512 (* (bytes "a") 1000000)) + [e718483d0ce76964 4e2e42c7bc15b463 8e1f98b13b204428 5632a803afa973eb de0ff244877ea60a 4cb0432ce577c31b eb009c5c2c49aa2e 4eadb217ad8cc09b]) +) + +(assert (= + (sha512 (bytes "The quick brown fox jumps over the lazy dog")) + [07e547d9586f6a73f73fbac0435ed76951218fb7d0c8d788a309d785436bbb642e93a252a954f23912547d1e8a3b5ed6e1bfd7097821233fa0538f3db854fee6]) +) + +(assert (= + (sha512 (bytes "The quick brown fox jumps over the lazy cog")) + [3eeee1d0 e11733ef 152a6c29 503b3ae2 0c4f1f3c da4cb26f 1bc1a41f 91c7fe4a b3bd8649 4049e201 c4bd5155 f31ecb7a 3c860684 3c4cc8df cab7da11 c8ae5045]) +) + +(assert (= + (sha512 []) + [cf83e1357eefb8bd f1542850d66d8007 d620e4050b5715dc 83f4a921d36ce9ce 47d0d13c5d85f2b0 ff8318d2877eec2f 63b931bd47417a81 a538327af927da3e]) +) + +(assert (= + (hmac-sha512 (* [0b] 20) (bytes "Hi There")) + [87aa7cdea5ef619d4ff0b4241a1d6cb02379f4e2ce4ec2787ad0b30545e17cdedaa833b7d6b8a702038b274eaea3f4e4be9d914eeb61f1702e696c203a126854]) +) + +(assert (= + (hmac-sha512 (bytes "Jefe") (bytes "what do ya want for nothing?")) + [164b7a7bfcf819e2e395fbe73b56e0a387bd64222e831fd610270cd7ea2505549758bf75c05a994a6d034f65f8f0e6fdcaeab1a34d4a6b4b636e070a38bce737]) +) + +(assert (= + (hmac-sha512 (* [aa] 20) (* [dd] 50)) + [fa73b0089d56a284efb0f0756c890be9b1b5dbdd8ee81a3655f83e33b2279d39bf3e848279a722c806b485a47e67c807b946a337bee8942674278859e13292fb]) +) + +(assert (= + (hmac-sha512 [0102030405060708090a0b0c0d0e0f10111213141516171819] (* [cd] 50)) + [b0ba465637458c6990e5a8c5f61d4af7e576d97ff94b872de76f8050361ee3dba91ca5c11aa25eb4d679275cc5788063a5f19741120c4f2de2adebeb10a298dd]) +) + +(assert (= + (hmac-sha512 (* [aa] 131) (bytes "Test Using Larger Than Block-Size Key - Hash Key First")) + [80b24263c7c1a3ebb71493c1dd7be8b49b46d1f41b4aeec1121b013783f8f3526b56d037e05f2598bd0fd2215d6a1e5295e64f73f63f0aec8b915a985d786598]) +) + +(assert (= + (hmac-sha512 (* [aa] 131) (bytes "This is a test using a larger than block-size key and a larger than block-size data. The key needs to be hashed before being used by the HMAC algorithm.")) + [e37b6a775dc87dbaa4dfa9f96e5e3ffddebd71f8867289865df5a32d20cdc944b6022cac3c4982b10d5eeb55c3e4de15134676fb6de0446065c97440fa8c6a58]) +) + + +(puts success) diff --git a/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/.gitignore b/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/.gitignore new file mode 100644 index 00000000..abc5da36 --- /dev/null +++ b/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/.gitignore @@ -0,0 +1,15 @@ +*.o +*.gcov +*.gcno +*.gcda +testaes +testmodes +testsha1 +testsha2 +testsha3 +testsalsa20 +testcurve25519 +testpoly1305 +testnorx +testchacha20poly1305 +testdrbg diff --git a/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/Makefile b/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/Makefile new file mode 100644 index 00000000..451548d6 --- /dev/null +++ b/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/Makefile @@ -0,0 +1,54 @@ +CFLAGS += -g -O0 -std=gnu99 -fPIC -Wall -Wextra -Werror \ + -Wno-unused-parameter -Wno-missing-field-initializers +CPPFLAGS += -I./ext + +ifdef WITH_ASAN + LDFLAGS += -fsanitize=address + CFLAGS += -fsanitize=address +endif + +ifdef WITH_COVERAGE + LDFLAGS += -coverage + CFLAGS += -coverage +endif + +ifdef WITH_VALGRIND + VALGRIND := valgrind --leak-check=full --show-reachable=yes --track-origins=yes + TEST_OPT := --no-exec +endif + +TARGETS = testaes testmodes testsha1 testsha2 testsha3 testsalsa20 \ + testcurve25519 testpoly1305 testnorx testchacha20poly1305 \ + testdrbg +all: $(TARGETS) + +SOURCES = aes.o sha256.o sha512.o chash.o hmac.o pbkdf2.o modes.o eax.o \ + gf128.o blockwise.o cmac.o salsa20.o chacha20.o curve25519.o \ + gcm.o cbcmac.o ccm.o sha3.o sha1.o poly1305.o \ + norx.o chacha20poly1305.o drbg.o ocb.o + +testaes: $(SOURCES) testaes.o +testmodes: $(SOURCES) testmodes.o +testsha1: $(SOURCES) testsha1.o +testsha2: $(SOURCES) testsha2.o +testsha3: $(SOURCES) testsha3.o +testsalsa20: $(SOURCES) testsalsa20.o +testcurve25519: $(SOURCES) testcurve25519.o +testpoly1305: $(SOURCES) testpoly1305.o +testnorx: $(SOURCES) testnorx.o +testchacha20poly1305: $(SOURCES) testchacha20poly1305.o +testdrbg: $(SOURCES) testdrbg.o + +clean: + rm -f *.o *.pyc $(TARGETS) *.gcov *.gcda *.gcno + +test: $(TARGETS) + for x in $(TARGETS) ; do \ + echo "Running $$x" ; \ + $(VALGRIND) ./$$x $(TEST_OPT) ; \ + done + +cover: test + gcov *.c + echo 'Lines with missing coverage:' + grep '#####' *.gcov | grep -vE '(cutest|testutil).h.gcov' diff --git a/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/aes.c b/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/aes.c new file mode 100644 index 00000000..545588e5 --- /dev/null +++ b/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/aes.c @@ -0,0 +1,419 @@ +/* + * cifra - embedded cryptography library + * Written in 2014 by Joseph Birr-Pixton + * + * To the extent possible under law, the author(s) have dedicated all + * copyright and related and neighboring rights to this software to the + * public domain worldwide. This software is distributed without any + * warranty. + * + * You should have received a copy of the CC0 Public Domain Dedication + * along with this software. If not, see + * . + */ + +#include +#include + +#include "cf_config.h" +#include "aes.h" +#include "handy.h" +#include "bitops.h" +#include "tassert.h" + +static const uint8_t S[256] = +{ + 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, + 0xd7, 0xab, 0x76, 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, + 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0, 0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, + 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15, 0x04, 0xc7, 0x23, 0xc3, + 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75, 0x09, + 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, + 0x2f, 0x84, 0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, + 0x39, 0x4a, 0x4c, 0x58, 0xcf, 0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, + 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8, 0x51, 0xa3, 0x40, 0x8f, 0x92, + 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2, 0xcd, 0x0c, + 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, + 0x73, 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, + 0xde, 0x5e, 0x0b, 0xdb, 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, + 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79, 0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, + 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08, 0xba, 0x78, 0x25, + 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a, + 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, + 0xc1, 0x1d, 0x9e, 0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, + 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf, 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, + 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16 +}; + +static const uint8_t Rcon[11] = +{ + 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36 +}; + +#ifdef INLINE_FUNCS +static inline uint32_t word4(uint8_t b0, uint8_t b1, uint8_t b2, uint8_t b3) +{ + return b0 << 24 | b1 << 16 | b2 << 8 | b3; +} + +static inline uint8_t byte(uint32_t w, unsigned x) +{ + /* nb. bytes are numbered 0 (leftmost, top) + * to 3 (rightmost). */ + x = 3 - x; + return (w >> (x * 8)) & 0xff; +} + +static uint32_t round_constant(uint32_t i) +{ + return Rcon[i] << 24; +} + +static uint32_t rot_word(uint32_t w) +{ + /* Takes + * word [a0,a1,a2,a3] + * returns + * word [a1,a2,a3,a0] + * + */ + return rotl32(w, 8); +} +#endif + +#define word4(a, b, c, d) (((uint32_t)(a) << 24) | ((uint32_t)(b) << 16) | ((uint32_t)(c) << 8) | (d)) +#define byte(w, x) ((w >> ((3 - (x)) << 3)) & 0xff) +#define round_constant(i) ((uint32_t)(Rcon[i]) << 24) +#define rot_word(w) rotl32((w), 8) + +static uint32_t sub_word(uint32_t w, const uint8_t *sbox) +{ + uint8_t a = byte(w, 0), + b = byte(w, 1), + c = byte(w, 2), + d = byte(w, 3); +#if CF_CACHE_SIDE_CHANNEL_PROTECTION + select_u8x4(&a, &b, &c, &d, sbox, 256); +#else + a = sbox[a]; + b = sbox[b]; + c = sbox[c]; + d = sbox[d]; +#endif + return word4(a, b, c, d); +} + +static void aes_schedule(cf_aes_context *ctx, const uint8_t *key, size_t nkey) +{ + size_t i, + nb = AES_BLOCKSZ / 4, + nk = nkey / 4, + n = nb * (ctx->rounds + 1); + uint32_t *w = ctx->ks; + + /* First words are just the key. */ + for (i = 0; i < nk; i++) + { + w[i] = read32_be(key + i * 4); + } + + uint32_t i_div_nk = 1; + uint32_t i_mod_nk = 0; + + for (; i < n; i++, i_mod_nk++) + { + uint32_t temp = w[i - 1]; + + if (i_mod_nk == nk) + { + i_div_nk++; + i_mod_nk = 0; + } + + if (i_mod_nk == 0) + temp = sub_word(rot_word(temp), S) ^ round_constant(i_div_nk); + else if (nk > 6 && i_mod_nk == 4) + temp = sub_word(temp, S); + + w[i] = w[i - nk] ^ temp; + } +} + +void cf_aes_init(cf_aes_context *ctx, const uint8_t *key, size_t nkey) +{ + memset(ctx, 0, sizeof *ctx); + + switch (nkey) + { +#if CF_AES_MAXROUNDS >= AES128_ROUNDS + case 16: + ctx->rounds = AES128_ROUNDS; + aes_schedule(ctx, key, nkey); + break; +#endif + +#if CF_AES_MAXROUNDS >= AES192_ROUNDS + case 24: + ctx->rounds = AES192_ROUNDS; + aes_schedule(ctx, key, nkey); + break; +#endif + +#if CF_AES_MAXROUNDS >= AES256_ROUNDS + case 32: + ctx->rounds = AES256_ROUNDS; + aes_schedule(ctx, key, nkey); + break; +#endif + + default: + abort(); + } +} + +static void add_round_key(uint32_t state[4], const uint32_t rk[4]) +{ + state[0] ^= rk[0]; + state[1] ^= rk[1]; + state[2] ^= rk[2]; + state[3] ^= rk[3]; +} + +static void sub_block(uint32_t state[4]) +{ + state[0] = sub_word(state[0], S); + state[1] = sub_word(state[1], S); + state[2] = sub_word(state[2], S); + state[3] = sub_word(state[3], S); +} + +static void shift_rows(uint32_t state[4]) +{ + uint32_t u, v, x, y; + + u = word4(byte(state[0], 0), + byte(state[1], 1), + byte(state[2], 2), + byte(state[3], 3)); + + v = word4(byte(state[1], 0), + byte(state[2], 1), + byte(state[3], 2), + byte(state[0], 3)); + + x = word4(byte(state[2], 0), + byte(state[3], 1), + byte(state[0], 2), + byte(state[1], 3)); + + y = word4(byte(state[3], 0), + byte(state[0], 1), + byte(state[1], 2), + byte(state[2], 3)); + + state[0] = u; + state[1] = v; + state[2] = x; + state[3] = y; +} + +static uint32_t gf_poly_mul2(uint32_t x) +{ + return + ((x & 0x7f7f7f7f) << 1) ^ + (((x & 0x80808080) >> 7) * 0x1b); +} + +static uint32_t mix_column(uint32_t x) +{ + uint32_t x2 = gf_poly_mul2(x); + return x2 ^ rotr32(x ^ x2, 24) ^ rotr32(x, 16) ^ rotr32(x, 8); +} + +static void mix_columns(uint32_t state[4]) +{ + state[0] = mix_column(state[0]); + state[1] = mix_column(state[1]); + state[2] = mix_column(state[2]); + state[3] = mix_column(state[3]); +} + +void cf_aes_encrypt(const cf_aes_context *ctx, + const uint8_t in[AES_BLOCKSZ], + uint8_t out[AES_BLOCKSZ]) +{ + assert(ctx->rounds == AES128_ROUNDS || + ctx->rounds == AES192_ROUNDS || + ctx->rounds == AES256_ROUNDS); + + uint32_t state[4] = { + read32_be(in + 0), + read32_be(in + 4), + read32_be(in + 8), + read32_be(in + 12) + }; + + const uint32_t *round_keys = ctx->ks; + add_round_key(state, round_keys); + round_keys += 4; + + uint32_t round; + for (round = 1; round < ctx->rounds; round++) + { + sub_block(state); + shift_rows(state); + mix_columns(state); + add_round_key(state, round_keys); + round_keys += 4; + } + + sub_block(state); + shift_rows(state); + add_round_key(state, round_keys); + + write32_be(state[0], out + 0); + write32_be(state[1], out + 4); + write32_be(state[2], out + 8); + write32_be(state[3], out + 12); +} + +#if CF_AES_ENCRYPT_ONLY == 0 +static const uint8_t S_inv[256] = +{ + 0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, 0xbf, 0x40, 0xa3, 0x9e, 0x81, + 0xf3, 0xd7, 0xfb, 0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87, 0x34, 0x8e, + 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb, 0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, + 0x3d, 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e, 0x08, 0x2e, 0xa1, 0x66, + 0x28, 0xd9, 0x24, 0xb2, 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25, 0x72, + 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, + 0xb6, 0x92, 0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda, 0x5e, 0x15, 0x46, + 0x57, 0xa7, 0x8d, 0x9d, 0x84, 0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a, + 0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06, 0xd0, 0x2c, 0x1e, 0x8f, 0xca, + 0x3f, 0x0f, 0x02, 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b, 0x3a, 0x91, + 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea, 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, + 0x73, 0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85, 0xe2, 0xf9, 0x37, 0xe8, + 0x1c, 0x75, 0xdf, 0x6e, 0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89, 0x6f, + 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b, 0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, + 0x79, 0x20, 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4, 0x1f, 0xdd, 0xa8, + 0x33, 0x88, 0x07, 0xc7, 0x31, 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f, + 0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d, 0x2d, 0xe5, 0x7a, 0x9f, 0x93, + 0xc9, 0x9c, 0xef, 0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0, 0xc8, 0xeb, + 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61, 0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, + 0x26, 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d +}; + +static void inv_sub_block(uint32_t state[4]) +{ + state[0] = sub_word(state[0], S_inv); + state[1] = sub_word(state[1], S_inv); + state[2] = sub_word(state[2], S_inv); + state[3] = sub_word(state[3], S_inv); +} + +static void inv_shift_rows(uint32_t state[4]) +{ + uint32_t u, v, x, y; + + u = word4(byte(state[0], 0), + byte(state[3], 1), + byte(state[2], 2), + byte(state[1], 3)); + + v = word4(byte(state[1], 0), + byte(state[0], 1), + byte(state[3], 2), + byte(state[2], 3)); + + x = word4(byte(state[2], 0), + byte(state[1], 1), + byte(state[0], 2), + byte(state[3], 3)); + + y = word4(byte(state[3], 0), + byte(state[2], 1), + byte(state[1], 2), + byte(state[0], 3)); + + state[0] = u; + state[1] = v; + state[2] = x; + state[3] = y; +} + +static uint32_t inv_mix_column(uint32_t x) +{ + uint32_t x2 = gf_poly_mul2(x), + x4 = gf_poly_mul2(x2), + x9 = x ^ gf_poly_mul2(x4), + x11 = x2 ^ x9, + x13 = x4 ^ x9; + + return x ^ x2 ^ x13 ^ rotr32(x11, 24) ^ rotr32(x13, 16) ^ rotr32(x9, 8); +} + +static void inv_mix_columns(uint32_t state[4]) +{ + state[0] = inv_mix_column(state[0]); + state[1] = inv_mix_column(state[1]); + state[2] = inv_mix_column(state[2]); + state[3] = inv_mix_column(state[3]); +} + +void cf_aes_decrypt(const cf_aes_context *ctx, + const uint8_t in[AES_BLOCKSZ], + uint8_t out[AES_BLOCKSZ]) +{ + assert(ctx->rounds == AES128_ROUNDS || + ctx->rounds == AES192_ROUNDS || + ctx->rounds == AES256_ROUNDS); + + uint32_t state[4] = { + read32_be(in + 0), + read32_be(in + 4), + read32_be(in + 8), + read32_be(in + 12) + }; + + const uint32_t *round_keys = &ctx->ks[ctx->rounds << 2]; + add_round_key(state, round_keys); + round_keys -= 4; + + uint32_t round; + for (round = ctx->rounds - 1; round != 0; round--) + { + inv_shift_rows(state); + inv_sub_block(state); + add_round_key(state, round_keys); + inv_mix_columns(state); + round_keys -= 4; + } + + inv_shift_rows(state); + inv_sub_block(state); + add_round_key(state, round_keys); + + write32_be(state[0], out + 0); + write32_be(state[1], out + 4); + write32_be(state[2], out + 8); + write32_be(state[3], out + 12); +} +#else +void cf_aes_decrypt(const cf_aes_context *ctx, + const uint8_t in[AES_BLOCKSZ], + uint8_t out[AES_BLOCKSZ]) +{ + abort(); +} +#endif + +void cf_aes_finish(cf_aes_context *ctx) +{ + mem_clean(ctx, sizeof *ctx); +} + +const cf_prp cf_aes = { + .blocksz = AES_BLOCKSZ, + .encrypt = (cf_prp_block) cf_aes_encrypt, + .decrypt = (cf_prp_block) cf_aes_decrypt +}; + diff --git a/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/aes.h b/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/aes.h new file mode 100644 index 00000000..2ee7f467 --- /dev/null +++ b/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/aes.h @@ -0,0 +1,152 @@ +/* + * cifra - embedded cryptography library + * Written in 2014 by Joseph Birr-Pixton + * + * To the extent possible under law, the author(s) have dedicated all + * copyright and related and neighboring rights to this software to the + * public domain worldwide. This software is distributed without any + * warranty. + * + * You should have received a copy of the CC0 Public Domain Dedication + * along with this software. If not, see + * . + */ + +/** + * The AES block cipher + * ==================== + * + * This is a small, simple implementation of AES. Key expansion is done + * first, filling in a :c:type:`cf_aes_context`. Then encryption and + * decryption can be performed as desired. + * + * Usually you don't want to use AES directly; you should use it via + * a :doc:`block cipher mode `. + */ + +#ifndef AES_H +#define AES_H + +#include +#include + +#include "prp.h" + +/* .. c:macro:: AES_BLOCKSZ + * AES has a 128-bit block size. This quantity is in bytes. + */ +#define AES_BLOCKSZ 16 + +/* --- Size configuration --- */ + +/* .. c:macro:: AES128_ROUNDS + * .. c:macro:: AES192_ROUNDS + * .. c:macro:: AES256_ROUNDS + * + * Round counts for different key sizes. + */ +#define AES128_ROUNDS 10 +#define AES192_ROUNDS 12 +#define AES256_ROUNDS 14 + +/* .. c:macro:: CF_AES_MAXROUNDS + * + * You can reduce the maximum number of rounds this implementation + * supports. This reduces the storage needed by :c:type:`cf_aes_context`. + * + * The default is :c:macro:`AES256_ROUNDS` and is good for all key + * sizes. + */ +#ifndef CF_AES_MAXROUNDS +# define CF_AES_MAXROUNDS AES256_ROUNDS +#endif + +/* .. c:macro:: CF_AES_ENCRYPT_ONLY + * + * Define this to 1 if you don't need to decrypt anything. + * This saves space. :c:func:`cf_aes_decrypt` calls `abort(3)`. + */ +#ifndef CF_AES_ENCRYPT_ONLY +# define CF_AES_ENCRYPT_ONLY 0 +#endif + +/* .. c:type:: cf_aes_context + * This type represents an expanded AES key. Create one + * using :c:func:`cf_aes_init`, make use of one using + * :c:func:`cf_aes_encrypt` or :c:func:`cf_aes_decrypt`. + * + * The contents of this structure are equivalent to the + * original key material. You should clean the + * contents of this structure with :c:func:`cf_aes_finish` + * when you're done. + * + * .. c:member:: cf_aes_context.rounds + * + * Number of rounds to use, set by :c:func:`cf_aes_init`. + * + * This depends on the original key size, and will be + * :c:macro:`AES128_ROUNDS`, :c:macro:`AES192_ROUNDS` or + * :c:macro:`AES256_ROUNDS`. + * + * .. c:member:: cf_aes_context.ks + * + * Expanded key material. Filled in by :c:func:`cf_aes_init`. + */ +typedef struct +{ + uint32_t rounds; + uint32_t ks[AES_BLOCKSZ / 4 * (CF_AES_MAXROUNDS + 1)]; +} cf_aes_context; + +/* .. c:function:: $DECL + * This function does AES key expansion. It destroys + * existing contents of :c:data:`ctx`. + * + * :param ctx: expanded key context, filled in by this function. + * :param key: pointer to key material, of :c:data:`nkey` bytes. + * :param nkey: length of key material. Must be `16`, `24` or `32`. + */ +extern void cf_aes_init(cf_aes_context *ctx, + const uint8_t *key, + size_t nkey); + +/* .. c:function:: $DECL + * Encrypts the given block, from :c:data:`in` to :c:data:`out`. + * These may alias. + * + * Fails at runtime if :c:data:`ctx` is invalid. + * + * :param ctx: expanded key context + * :param in: input block (read) + * :param out: output block (written) + */ +extern void cf_aes_encrypt(const cf_aes_context *ctx, + const uint8_t in[AES_BLOCKSZ], + uint8_t out[AES_BLOCKSZ]); + +/* .. c:function:: $DECL + * Decrypts the given block, from :c:data:`in` to :c:data:`out`. + * These may alias. + * + * Fails at runtime if :c:data:`ctx` is invalid. + * + * :param ctx: expanded key context + * :param in: input block (read) + * :param out: output block (written) + */ +extern void cf_aes_decrypt(const cf_aes_context *ctx, + const uint8_t in[AES_BLOCKSZ], + uint8_t out[AES_BLOCKSZ]); + +/* .. c:function:: $DECL + * Erase scheduled key material. + * + * Call this when you're done to erase the round keys. */ +extern void cf_aes_finish(cf_aes_context *ctx); + +/* .. c:var:: const cf_prp cf_aes + * Abstract interface to AES. See :c:type:`cf_prp` for + * more information. */ +extern const cf_prp cf_aes; + +#endif diff --git a/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/arm/.gitignore b/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/arm/.gitignore new file mode 100644 index 00000000..5841cb8e --- /dev/null +++ b/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/arm/.gitignore @@ -0,0 +1,3 @@ +*.log +*.elf +*.bin diff --git a/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/arm/Makefile b/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/arm/Makefile new file mode 100644 index 00000000..7be9a53a --- /dev/null +++ b/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/arm/Makefile @@ -0,0 +1,184 @@ +FUNCS = do_nothing stack_8w stack_64w \ + hashtest_sha256 hashtest_sha512 \ + hashtest_sha3_256 hashtest_sha3_512 \ + aes128block_test aes128sched_test \ + aes256block_test aes256sched_test \ + aes128gcm_test aes128eax_test \ + aes128ccm_test \ + salsa20_test chacha20_test \ + poly1305_test hmacsha256_test \ + curve25519_test \ + norx_test + +AEADS = aeadperf_aes128gcm \ + aeadperf_aes128ccm \ + aeadperf_aes128eax \ + aeadperf_aes256gcm \ + aeadperf_aes256ccm \ + aeadperf_aes256eax \ + aeadperf_norx \ + aeadperf_chacha20poly1305 +TESTS = testcurve25519 testaes testmodes testsalsa20 testsha1 testsha2 \ + testsha3 testpoly1305 testnorx testchacha20poly1305 testdrbg +ARCHS = stm32f0 stm32f1 stm32f3 efm32 qemucm3 + +all: $(patsubst %,%.stm32f0.bin,$(FUNCS) $(AEADS) $(TESTS)) \ + $(patsubst %,%.stm32f1.bin,$(FUNCS) $(AEADS) $(TESTS)) \ + $(patsubst %,%.stm32f3.bin,$(FUNCS) $(AEADS) $(TESTS)) \ + $(patsubst %,%.efm32.bin,$(FUNCS) $(AEADS) $(TESTS)) \ + $(patsubst %,%.qemucm3.bin,$(FUNCS) $(AEADS) $(TESTS)) + +%.stm32f0.elf: + arm-none-eabi-gcc $(CFLAGS) $(CFLAGS_$*) $(LDFLAGS) -T linkscript.stm32f0.ld -mcpu=cortex-m0 -DCORTEX_M0 -o $@ $^ -DTEST=$* -lgcc + +%.stm32f1.elf: + arm-none-eabi-gcc $(CFLAGS) $(CFLAGS_$*) $(LDFLAGS) -T linkscript.stm32f1.ld -mcpu=cortex-m3 -DCORTEX_M3 -o $@ $^ -DTEST=$* -lgcc + +%.stm32f3.elf: + arm-none-eabi-gcc $(CFLAGS) $(CFLAGS_$*) $(LDFLAGS) -T linkscript.stm32f3.ld -mcpu=cortex-m4 -DCORTEX_M4 -o $@ $^ -DTEST=$* -lgcc + +%.efm32.elf: + arm-none-eabi-gcc $(CFLAGS) $(CFLAGS_$*) $(LDFLAGS) -T linkscript.efm32.ld -mcpu=cortex-m0 -DCORTEX_M0 -o $@ $^ -DTEST=$* -lgcc + +%.qemucm3.elf: + arm-none-eabi-gcc $(CFLAGS) $(CFLAGS_$*) $(LDFLAGS) -T linkscript.qemucm3.ld -mcpu=cortex-m3 -DCORTEX_M3 -o $@ $^ -DTEST=$* -lgcc + +%.bin: %.elf + arm-none-eabi-objcopy -O binary $< $@ +.PRECIOUS: %.bin + +AES_OPTIONS = -DCF_AES_ENCRYPT_ONLY=1 -DCF_SIDE_CHANNEL_PROTECTION=0 +AES128_OPTIONS = -DCF_AES_MAXROUNDS=AES128_ROUNDS +AES256_OPTIONS = -DCF_AES_MAXROUNDS=AES256_ROUNDS + +AEADPERF_BRACKET = -DBRACKET_MODE=1 -DBRACKET_START=0 -DBRACKET_END=256 -DBRACKET_STEP=4 + +CFLAGS_aes128block_test = $(AES_OPTIONS) $(AES128_OPTIONS) +CFLAGS_aes128sched_test = $(AES_OPTIONS) $(AES128_OPTIONS) +CFLAGS_aes128gcm_test = $(AES_OPTIONS) $(AES128_OPTIONS) +CFLAGS_aes128eax_test = $(AES_OPTIONS) $(AES128_OPTIONS) +CFLAGS_aes128ccm_test = $(AES_OPTIONS) $(AES128_OPTIONS) +CFLAGS_poly1305_test = $(AES_OPTIONS) $(AES128_OPTIONS) + +CFLAGS_aeadperf_aes128gcm = $(AES_OPTIONS) $(AES128_OPTIONS) $(AEADPERF_BRACKET) +CFLAGS_aeadperf_aes128eax = $(AES_OPTIONS) $(AES128_OPTIONS) $(AEADPERF_BRACKET) +CFLAGS_aeadperf_aes128ccm = $(AES_OPTIONS) $(AES128_OPTIONS) $(AEADPERF_BRACKET) +CFLAGS_aeadperf_aes256gcm = $(AES_OPTIONS) $(AES256_OPTIONS) $(AEADPERF_BRACKET) +CFLAGS_aeadperf_aes256eax = $(AES_OPTIONS) $(AES256_OPTIONS) $(AEADPERF_BRACKET) +CFLAGS_aeadperf_aes256ccm = $(AES_OPTIONS) $(AES256_OPTIONS) $(AEADPERF_BRACKET) +CFLAGS_aeadperf_norx = $(AEADPERF_BRACKET) +CFLAGS_aeadperf_chacha20poly1305 = $(AEADPERF_BRACKET) + +CFLAGS_aes256block_test = $(AES_OPTIONS) $(AES256_OPTIONS) +CFLAGS_aes256sched_test = $(AES_OPTIONS) $(AES256_OPTIONS) + +CFLAGS_testaes = -DCF_SIDE_CHANNEL_PROTECTION=0 + +CFLAGS = -I./ext -I../ext -I.. -Os -ffunction-sections -g \ + -Wall -Werror -std=gnu99 -mthumb +LDFLAGS = -nostartfiles -nostdlib -Wl,-gc-sections +CURVESRCS = unacl/cortex_m0_mpy121666.s unacl/cortex_m0_reduce25519.s unacl/mul.s unacl/sqr.s +SRCS = boot.c memcpy.s memset.s semihost.c semihost.s \ + ../sha1.c ../sha256.c ../sha512.c ../sha3.c ../blockwise.c ../chash.c \ + ../curve25519.c ../poly1305.c \ + ../aes.c ../eax.c ../gcm.c ../cbcmac.c ../ccm.c \ + ../modes.c ../cmac.c ../gf128.c \ + ../hmac.c ../pbkdf2.c ../salsa20.c ../chacha20.c \ + ../norx.c ../chacha20poly1305.c ../drbg.c + +$(patsubst %,%.stm32f0.elf, $(FUNCS) $(AEADS)): $(SRCS) main.c $(CURVESRCS) +$(patsubst %,%.stm32f1.elf, $(FUNCS) $(AEADS)): $(SRCS) main.c $(CURVESRCS) +$(patsubst %,%.stm32f3.elf, $(FUNCS) $(AEADS)): $(SRCS) main.c $(CURVESRCS) +$(patsubst %,%.efm32.elf, $(FUNCS) $(AEADS)): $(SRCS) main.c $(CURVESRCS) +$(patsubst %,%.qemucm3.elf, $(FUNCS) $(AEADS)): $(SRCS) main.c $(CURVESRCS) + +$(patsubst %,testcurve25519.%.elf, $(ARCHS)): $(SRCS) $(CURVESRCS) ../testcurve25519.c +$(patsubst %,testaes.%.elf, $(ARCHS)): $(SRCS) ../testaes.c +$(patsubst %,testmodes.%.elf, $(ARCHS)): $(SRCS) ../testmodes.c +$(patsubst %,testsalsa20.%.elf, $(ARCHS)): $(SRCS) ../testsalsa20.c +$(patsubst %,testsha1.%.elf, $(ARCHS)): $(SRCS) ../testsha1.c +$(patsubst %,testsha2.%.elf, $(ARCHS)): $(SRCS) ../testsha2.c +$(patsubst %,testsha3.%.elf, $(ARCHS)): $(SRCS) ../testsha3.c +$(patsubst %,testpoly1305.%.elf, $(ARCHS)): $(SRCS) ../testpoly1305.c +$(patsubst %,testnorx.%.elf, $(ARCHS)): $(SRCS) ../testnorx.c +$(patsubst %,testchacha20poly1305.%.elf, $(ARCHS)): $(SRCS) ../testchacha20poly1305.c +$(patsubst %,testdrbg.%.elf, $(ARCHS)): $(SRCS) ../testdrbg.c + +run.%.qemucm3: %.qemucm3.bin + arm-none-eabi-readelf -l $(patsubst %.bin,%.elf,$^) > $@.log + qemu-system-gnuarmeclipse -verbose -verbose -M STM32-P103 -kernel $^ -semihosting -nographic -monitor null -serial null 2>> $@.log + cat $@.log + +run.%.efm32: %.efm32.elf + arm-none-eabi-readelf -l $^ > $@.log + echo '-----' >> $@.log + openocd -f openocd.efm32.cfg >> $@.log & + arm-none-eabi-gdb --quiet --batch-silent \ + $^ \ + -ex 'target remote :3333' \ + -ex 'monitor reset halt' \ + -ex 'load' \ + -ex 'monitor arm semihosting enable' \ + -ex 'monitor reset run' \ + -ex 'monitor wait_halt 720000' \ + -ex 'monitor shutdown' + +run.%.stm32f0: %.stm32f0.elf + arm-none-eabi-readelf -l $^ > $@.log + echo '-----' >> $@.log + openocd -f openocd.stm32f0.cfg >> $@.log & + arm-none-eabi-gdb --quiet --batch-silent \ + $^ \ + -ex 'target remote :3333' \ + -ex 'monitor reset halt' \ + -ex 'load' \ + -ex 'monitor arm semihosting enable' \ + -ex 'monitor reset run' \ + -ex 'monitor wait_halt 720000' \ + -ex 'monitor shutdown' + +run.%.stm32f1: %.stm32f1.elf + arm-none-eabi-readelf -l $^ > $@.log + echo '-----' >> $@.log + openocd -f openocd.stm32f1.cfg >> $@.log & + arm-none-eabi-gdb --quiet --batch-silent \ + $^ \ + -ex 'target remote :3333' \ + -ex 'monitor reset halt' \ + -ex 'load' \ + -ex 'monitor arm semihosting enable' \ + -ex 'monitor reset run' \ + -ex 'monitor wait_halt 720000' \ + -ex 'monitor shutdown' + +run.%.stm32f3: %.stm32f3.elf + arm-none-eabi-readelf -l $^ > $@.log + echo '-----' >> $@.log + openocd -f openocd.stm32f3.cfg >> $@.log & + arm-none-eabi-gdb --quiet --batch-silent \ + $^ \ + -ex 'target remote :3333' \ + -ex 'monitor reset halt' \ + -ex 'load' \ + -ex 'monitor arm semihosting enable' \ + -ex 'monitor reset run' \ + -ex 'monitor wait_halt 720000' \ + -ex 'monitor shutdown' + +test: $(patsubst %,run.%.qemucm3,$(FUNCS) $(TESTS)) +.PHONY: test + +perf.stm32f0: $(patsubst %,run.%.stm32f0,$(FUNCS)) +.PHONY: perf.stm32f0 + +test.stm32f0: $(patsubst %,run.%.stm32f0,$(FUNCS) $(TESTS)) +.PHONY: test.stm32f0 + +test.stm32f1: $(patsubst %,run.%.stm32f1,$(FUNCS) $(TESTS)) +.PHONY: test.stm32f1 + +test.stm32f3: $(patsubst %,run.%.stm32f3,$(FUNCS) $(TESTS)) +.PHONY: test.stm32f3 + +clean: + rm -rf *.log *.elf *.bin diff --git a/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/arm/analyse.py b/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/arm/analyse.py new file mode 100644 index 00000000..d2c456fe --- /dev/null +++ b/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/arm/analyse.py @@ -0,0 +1,207 @@ +import subprocess +import sys +import re + +function_intro_re = re.compile(r'^(?P[0-9a-fA-F]{8}) <(?P[a-zA-Z0-9\._]+)>:$') +insn_re = re.compile(r'^\s+(?P[0-9a-fA-F]+):\s+(?P[0-9a-fA-F ]+)\s+\t(?P.*)$') + +class Instruction: + def __init__(self, addr, insn, op): + self.addr = long(addr, 16) + self.insn = insn + + args = op.split('\t', 1) + + self.op = args[0].strip() + if len(args) == 2: + comment = args[1].strip().split(';', 1) + else: + comment = args + + self.args = comment[0].strip() + + if len(comment) == 2: + self.comment = comment[1].strip() + else: + self.comment = '' + + def __repr__(self): + return '' % (self.__dict__) + + +def literal_branch_target(t): + return ' <' in t + +class Function: + def __init__(self, addr, name): + self.name = name + self.addr = long(addr, 16) + self.insns = [] + self.calls = [] + + def __repr__(self): + return '<%s %d instructions>' % (self.name, len(self.insns)) + + def add_insn(self, insn): + self.insns.append(Instruction(**insn)) + + def contains_addr(self, addr): + if self.insns: + return addr >= self.addr and addr <= self.insns[-1].addr + else: + return addr == self.addr + + def dump(self): + print self.name + ':' + for insn in self.insns: + print ' ', '%04x' % insn.addr + ':', insn.op, insn.args, '\t;', insn.comment + + def get_literal_word(self, addr): + for insn in self.insns: + if insn.addr == addr and insn.op == '.word': + w = int(insn.args, 16) + if w & 0x80000000: + w = -(w ^ 0xffffffff) + 1 + return w + return None + + def analyse(self, prog): + self.stack_guess = None + regs = {} + + for insn in self.insns: + # stack adjustment with literal + if insn.op == 'sub' and insn.args.startswith('sp, ') and self.stack_guess is None: + sz = int(insn.args.split('#', 1)[1]) + self.stack_guess = sz + + # literal pool loads + if insn.op == 'ldr' and ', [pc, #' in insn.args: + reg, offset = insn.args.split(', [pc, #') + offset = int(offset.replace(']', '')) + word = self.get_literal_word(insn.addr + offset + 2) + if word is not None: + regs[reg] = word + + if insn.op == 'add' and insn.args.startswith('sp, r') and self.stack_guess is None: + reg = insn.args.split(', ')[1] + if reg in regs: + self.stack_guess = regs[reg] + + # static branches + if insn.op[0] == 'b' and literal_branch_target(insn.args): + target = long(insn.args.split(' <', 1)[0], 16) + + targetf = prog.function_at_addr(target) + + if targetf and targetf != self: + self.calls.append(targetf) + + if self.stack_guess is None: + self.stack_guess = 0 + + def stack_usage(self, hints, warns, prog, depth = 0): + hinted_calls = [] + if self.stack_guess: + print ' ' * depth, 'stack:', self.name, self.stack_guess, 'bytes' + + our_hints = [h for h in hints if h and h[0] == self.name] + if our_hints: + hints = [h[1:] for h in our_hints] + hinted_calls = [prog.function_by_name(h[0]) for h in hints if h] + else: + if self.name in warns: + print ' WARN: no calls hints for fn-ptr caller', self.name + + if self.calls + hinted_calls: + call_usage = max([f.stack_usage(hints, warns, prog, depth + 1) for f in self.calls + hinted_calls]) + else: + call_usage = 0 + return self.stack_guess + call_usage + +class Program: + def __init__(self): + self.functions = [] + + # sequence of tuples naming a call sequence known to occur + # this allows working out calls through pointers + self.call_hints = [] + + # function names to warn on if we don't have callees + self.call_warns = set() + + def read_elf(self, elf): + current_fn = None + + for x in subprocess.Popen(['arm-none-eabi-objdump', '-d', elf], + stdout = subprocess.PIPE).stdout: + x = x.rstrip('\n') + m = function_intro_re.match(x) + if m: + fn = Function(**m.groupdict()) + current_fn = fn + self.functions.append(fn) + + m = insn_re.match(x) + if m: + assert current_fn + current_fn.add_insn(m.groupdict()) + + def analyse(self): + for f in self.functions: + f.analyse(self) + + def function_by_name(self, name): + fns = [fn for fn in self.functions if fn.name == name] + if len(fns) == 0: + return None + elif len(fns) == 1: + return fns[0] + else: + print 'warn: more than one function named', name + return None + + def function_at_addr(self, addr): + for f in self.functions: + if f.addr == addr: + return f + return None + + def add_call_hint(self, *seq): + self.call_hints.append(seq) + + def add_call_warn(self, fn): + self.call_warns.add(fn) + + def measure_stack(self, name): + fn = self.function_by_name(name) + if fn is None: + return 0 + + return fn.stack_usage(self.call_hints, self.call_warns, self) + +_, exe, fn = sys.argv + +p = Program() +p.read_elf(exe) + +p.analyse() + +# calls which indirect through fn ptrs +p.add_call_warn('cf_blockwise_accumulate') +p.add_call_warn('cf_blockwise_accumulate_final') + +# hints to resolve those +p.add_call_hint('cf_sha224_update', 'cf_blockwise_accumulate', 'cf_blockwise_accumulate_final', 'sha256_update_block') +p.add_call_hint('cf_sha256_update', 'cf_blockwise_accumulate', 'cf_blockwise_accumulate_final', 'sha256_update_block') +p.add_call_hint('cf_sha384_update', 'cf_blockwise_accumulate', 'cf_blockwise_accumulate_final', 'sha512_update_block') +p.add_call_hint('cf_sha512_update', 'cf_blockwise_accumulate', 'cf_blockwise_accumulate_final', 'sha512_update_block') +p.add_call_hint('cf_norx32_encrypt', 'input', 'cf_blockwise_accumulate', 'cf_blockwise_accumulate_final', 'input_block') +p.add_call_hint('cf_norx32_decrypt', 'input', 'cf_blockwise_accumulate', 'cf_blockwise_accumulate_final', 'input_block') +p.add_call_hint('cf_cbcmac_stream_update', 'cf_blockwise_accumulate', 'cf_blockwise_accumulate_final', 'cbcmac_process') +p.add_call_hint('cf_cmac_stream_update', 'cf_blockwise_accumulate', 'cf_blockwise_accumulate_final', 'cmac_process_final_pad') +p.add_call_hint('cf_cmac_stream_update', 'cf_blockwise_accumulate_final', 'cmac_process') +p.add_call_hint('cf_cmac_stream_update', 'cf_blockwise_accumulate_final', 'cmac_process_final_nopad') + + +print 'stack', fn, '=', p.measure_stack(fn) diff --git a/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/arm/boot.c b/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/arm/boot.c new file mode 100644 index 00000000..d2a8e407 --- /dev/null +++ b/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/arm/boot.c @@ -0,0 +1,144 @@ +#include +#include +#include + +extern int main(void); + +/* --- Defined by link script --- */ +extern uint32_t __etext; /* End of text/start of data. */ +extern uint32_t __data_start__, __data_end__; /* Data addresses in RAM */ +extern uint32_t __bss_start__, __bss_end__; /* BSS addresses in RAM */ +extern uint32_t __StackTop; /* End of stack in RAM */ + +#define ATTR_SECTION(sec) __attribute__ ((section (sec))) + +/* --- Interrupt vector table. --- */ +void Reset_Handler(void); +void SysTick_Handler(void); +void infinite_loop(void); +void do_nothing(void); + +typedef void (*vector_fn)(void); + +typedef struct { + uint32_t *stack_top; + vector_fn reset, nmi, hard_fault, mmu_fault, bus_fault, usage_fault; + vector_fn reserved0[4]; + vector_fn svc, debug_monitor; + vector_fn reserved1; + vector_fn pendsv, systick; + vector_fn irq[128]; +} vectors_t; + +#define COPY2(v) v, v +#define COPY4(v) COPY2(v), COPY2(v) +#define COPY8(v) COPY4(v), COPY4(v) +#define COPY16(v) COPY8(v), COPY8(v) +#define COPY32(v) COPY16(v), COPY16(v) +#define COPY64(v) COPY32(v), COPY32(v) +#define COPY128(v) COPY64(v), COPY64(v) + +vectors_t vectors ATTR_SECTION(".isr_vector") = { + .stack_top = &__StackTop, + .reset = Reset_Handler, + .nmi = do_nothing, + .hard_fault = infinite_loop, + .mmu_fault = infinite_loop, + .bus_fault = infinite_loop, + .usage_fault = infinite_loop, + .svc = do_nothing, + .debug_monitor = do_nothing, + .pendsv = do_nothing, + .systick = SysTick_Handler, + .irq = { COPY128(do_nothing) } +}; + +/* --- ISRs --- */ +void Reset_Handler(void) +{ + /* Copy data segment contents from flash to RAM. */ + uint32_t data_bytes = (&__data_end__ - &__data_start__) * 4; + memcpy(&__etext, &__data_start__, data_bytes); + + /* Zero BSS. */ + uint32_t bss_bytes = (&__bss_end__ - &__bss_start__) * 4; + memset(&__bss_start__, 0, bss_bytes); + + main(); + while (1) + ; +} + +void __assert_func(const char *file, int line, const char *func, const char *expr) +{ + while (1) + ; +} + +void infinite_loop(void) +{ + while (1) + ; +} + +void do_nothing(void) +{ +} + +uint32_t ticks = 0; + +void SysTick_Handler(void) +{ + ticks++; +} + +uint32_t get_ticks(void) +{ + return ticks; +} + +void reset_ticks(void) +{ + ticks = 0; +} + +void *memmove(void *vtarg, const void *vsrc, size_t len) +{ + if (vsrc > vtarg) + return memcpy(vtarg, vsrc, len); + else if (vsrc == vtarg) + return vtarg; + + uint8_t *targ = vtarg; + const uint8_t *src = vsrc; + + for (size_t i = len; i != 0; i++) + targ[i - 1] = src[i - 1]; + return vtarg; +} + +int memcmp(const void *va, const void *vb, size_t len) +{ + const uint8_t *a = va, *b = vb; + + for (size_t i = 0; i < len; i++) + { + if (a[i] != b[i]) + return a[i] < b[i] ? -1 : 1; + } + + return 0; +} + +size_t strlen(const char *c) +{ + size_t r = 0; + while (*c++) r++; + return r; +} + +void abort(void) +{ + while (1) + ; +} diff --git a/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/arm/curve25519-results.txt b/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/arm/curve25519-results.txt new file mode 100644 index 00000000..968e40e5 --- /dev/null +++ b/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/arm/curve25519-results.txt @@ -0,0 +1,22 @@ +STM32F0 +donna-before-opt: 12907000c +donna-after-opt: 17294000c +donna-reset-opt: 12947000c +~20k + +donna -O2 -Os: 15268000c +donna -O2 -Os noasm: 20453000c +donna -Os: 15748000c +7.4k + +donna -O3: 12907000c 16KB 3380b +donna -Os: 15748000c 7.4KB 3148b +donna -O2: 15218000c 7.9KB 3148b + +tweetnacl -O2: 68876000c 3.0KB 2268b +tweetnacl -Os: 75979000c 2.8KB 2244b +tweetnacl -O3: 69622000c 8.9KB 2900b + +naclref -Os: 47813000c 3.2KB 4012b +naclref -O3: 35059000c 4.1KB 4044b +naclref -O2: 34309000c 3.5KB 4036b diff --git a/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/arm/ext/cutest.h b/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/arm/ext/cutest.h new file mode 100644 index 00000000..fa3c5d84 --- /dev/null +++ b/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/arm/ext/cutest.h @@ -0,0 +1,55 @@ +/* cutest, for embedded targets. */ + +#ifndef CUTEST_H +#define CUTEST_H + +/* Main interface. */ +#define TEST_LIST const struct test__ test_list__[] +#define TEST_CHECK(cond) test_check__((cond), __FILE__, __LINE__, #cond) +/* no TEST_CHECK_ -- we don't have a good enough printf */ + +/* Implementation */ +#include "../semihost.h" + +struct test__ +{ + const char *name; + void (*func)(void); +}; + +extern const struct test__ test_list__[]; + +static void test_check__(int cond, const char *file, int line, const char *expr) +{ + if (cond) + return; /* pass */ + + emit("Failed!\n"); + emit("File: "); emit(file); emit("\n"); + emit("Line: "); emit_uint32(line); emit("\n"); + emit("Expr: "); emit(expr); emit("\n"); + quit_failure(); +} + +static void run_test__(const struct test__ *t) +{ + emit(" "); emit(t->name); emit(": "); + t->func(); + emit("OK\n"); +} + +int main(void) +{ + emit("Running tests:\n"); + + for (const struct test__ *t = test_list__; + t->name; + t++) + { + run_test__(t); + } + emit("Success\n"); + quit_success(); +} + +#endif diff --git a/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/arm/linkscript.efm32.ld b/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/arm/linkscript.efm32.ld new file mode 100644 index 00000000..8b9a6bfd --- /dev/null +++ b/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/arm/linkscript.efm32.ld @@ -0,0 +1,8 @@ +MEMORY +{ + FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 64K + RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 8K +} + +INCLUDE linkscript.std.ld + diff --git a/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/arm/linkscript.lm3s6965evb.ld b/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/arm/linkscript.lm3s6965evb.ld new file mode 100644 index 00000000..14fdac4e --- /dev/null +++ b/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/arm/linkscript.lm3s6965evb.ld @@ -0,0 +1,7 @@ +MEMORY +{ + FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 256K + RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 64K +} + +INCLUDE linkscript.std.ld diff --git a/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/arm/linkscript.qemucm3.ld b/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/arm/linkscript.qemucm3.ld new file mode 100644 index 00000000..28264674 --- /dev/null +++ b/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/arm/linkscript.qemucm3.ld @@ -0,0 +1,8 @@ +MEMORY +{ + FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 128K + RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 20K +} + +INCLUDE linkscript.std.ld + diff --git a/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/arm/linkscript.std.ld b/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/arm/linkscript.std.ld new file mode 100644 index 00000000..c08d7bea --- /dev/null +++ b/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/arm/linkscript.std.ld @@ -0,0 +1,172 @@ + +/* Linker script to place sections and symbol values. Should be used together + * with other linker script that defines memory regions FLASH and RAM. + * It references following symbols, which must be defined in code: + * Reset_Handler : Entry of reset handler + * + * It defines following symbols, which code can use without definition: + * __exidx_start + * __exidx_end + * __copy_table_start__ + * __copy_table_end__ + * __zero_table_start__ + * __zero_table_end__ + * __etext + * __data_start__ + * __preinit_array_start + * __preinit_array_end + * __init_array_start + * __init_array_end + * __fini_array_start + * __fini_array_end + * __data_end__ + * __bss_start__ + * __bss_end__ + * __end__ + * end + * __HeapLimit + * __StackLimit + * __StackTop + * __stack + */ +ENTRY(Reset_Handler) + +SECTIONS +{ + .text : + { + KEEP(*(.isr_vector)) + *(.text*) + + KEEP(*(.init)) + KEEP(*(.fini)) + + /* .ctors */ + *crtbegin.o(.ctors) + *crtbegin?.o(.ctors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors) + *(SORT(.ctors.*)) + *(.ctors) + + /* .dtors */ + *crtbegin.o(.dtors) + *crtbegin?.o(.dtors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors) + *(SORT(.dtors.*)) + *(.dtors) + + *(.rodata*) + + KEEP(*(.eh_frame*)) + } > FLASH + + .ARM.extab : + { + *(.ARM.extab* .gnu.linkonce.armextab.*) + } > FLASH + + __exidx_start = .; + .ARM.exidx : + { + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + } > FLASH + __exidx_end = .; + + /* To copy multiple ROM to RAM sections, + * uncomment .copy.table section and, + * define __STARTUP_COPY_MULTIPLE in startup_ARMCMx.S */ + + .copy.table : + { + . = ALIGN(4); + __copy_table_start__ = .; + LONG (__etext) + LONG (__data_start__) + LONG (__data_end__ - __data_start__) + __copy_table_end__ = .; + } > FLASH + + + /* To clear multiple BSS sections, + * uncomment .zero.table section and, + * define __STARTUP_CLEAR_BSS_MULTIPLE in startup_ARMCMx.S */ + .zero.table : + { + . = ALIGN(4); + __zero_table_start__ = .; + LONG (__bss_start__) + LONG (__bss_end__ - __bss_start__) + __zero_table_end__ = .; + } > FLASH + + __etext = .; + + .data : AT (__etext) + { + __data_start__ = .; + *(vtable) + *(.data*) + + . = ALIGN(4); + /* preinit data */ + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP(*(.preinit_array)) + PROVIDE_HIDDEN (__preinit_array_end = .); + + . = ALIGN(4); + /* init data */ + PROVIDE_HIDDEN (__init_array_start = .); + KEEP(*(SORT(.init_array.*))) + KEEP(*(.init_array)) + PROVIDE_HIDDEN (__init_array_end = .); + + + . = ALIGN(4); + /* finit data */ + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP(*(SORT(.fini_array.*))) + KEEP(*(.fini_array)) + PROVIDE_HIDDEN (__fini_array_end = .); + + KEEP(*(.jcr*)) + . = ALIGN(4); + /* All data end */ + __data_end__ = .; + + } > RAM + + .bss : + { + . = ALIGN(4); + __bss_start__ = .; + *(.bss*) + *(COMMON) + . = ALIGN(4); + __bss_end__ = .; + } > RAM + + .heap (COPY): + { + __end__ = .; + PROVIDE(end = .); + *(.heap*) + __HeapLimit = .; + } > RAM + + /* .stack_dummy section doesn't contains any symbols. It is only + * used for linker to calculate size of stack sections, and assign + * values to stack symbols later */ + .stack_dummy (COPY): + { + *(.stack*) + } > RAM + + /* Set stack top to end of RAM, and stack limit move down by + * size of stack_dummy section */ + __StackTop = ORIGIN(RAM) + LENGTH(RAM); + __StackLimit = __StackTop - SIZEOF(.stack_dummy); + PROVIDE(__stack = __StackTop); + + /* Check if data + heap + stack exceeds RAM limit */ + ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed with stack") +} diff --git a/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/arm/linkscript.stm32f0.ld b/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/arm/linkscript.stm32f0.ld new file mode 100644 index 00000000..c7a3bd85 --- /dev/null +++ b/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/arm/linkscript.stm32f0.ld @@ -0,0 +1,8 @@ +MEMORY +{ + FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 128K + RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 16K +} + +INCLUDE linkscript.std.ld + diff --git a/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/arm/linkscript.stm32f1.ld b/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/arm/linkscript.stm32f1.ld new file mode 100644 index 00000000..d13f58de --- /dev/null +++ b/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/arm/linkscript.stm32f1.ld @@ -0,0 +1,8 @@ +MEMORY +{ + FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 64K + RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 8K +} + +INCLUDE linkscript.std.ld + diff --git a/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/arm/linkscript.stm32f3.ld b/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/arm/linkscript.stm32f3.ld new file mode 100644 index 00000000..92eee46e --- /dev/null +++ b/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/arm/linkscript.stm32f3.ld @@ -0,0 +1,8 @@ +MEMORY +{ + FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 64K + RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 12K +} + +INCLUDE linkscript.std.ld + diff --git a/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/arm/main.c b/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/arm/main.c new file mode 100644 index 00000000..5b7cbf22 --- /dev/null +++ b/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/arm/main.c @@ -0,0 +1,447 @@ +#ifndef TEST +# error You must select a function to test. +#endif + +#include "semihost.h" +#include "aes.h" +#include "hmac.h" +#include "sha2.h" +#include "sha3.h" +#include "modes.h" +#include "salsa20.h" +#include "curve25519.h" +#include "poly1305.h" +#include "norx.h" +#include "chacha20poly1305.h" + +#include + +typedef void (*measure_fn)(void); +static uint32_t bracket; /* bracket mode parameter */ + +static void do_nothing(void) +{ +} + +static void stack_64w(void) +{ + volatile uint32_t words[64]; + words[0] = 0; + words[63] = 0; + (void) words[63]; +} + +static void stack_8w(void) +{ + volatile uint32_t words[8]; + words[0] = 0; + words[7] = 0; + (void) words[7]; +} + +static void hashtest_sha256(void) +{ + uint8_t hash[CF_SHA256_HASHSZ]; + cf_sha256_context ctx; + cf_sha256_init(&ctx); + cf_sha256_update(&ctx, "", 0); + cf_sha256_digest_final(&ctx, hash); +} + +static void hashtest_sha512(void) +{ + uint8_t hash[CF_SHA512_HASHSZ]; + cf_sha512_context ctx; + cf_sha512_init(&ctx); + cf_sha512_update(&ctx, "", 0); + cf_sha512_digest_final(&ctx, hash); +} + +static void hashtest_sha3_256(void) +{ + uint8_t hash[CF_SHA3_256_HASHSZ]; + cf_sha3_context ctx; + cf_sha3_256_init(&ctx); + cf_sha3_256_update(&ctx, "", 0); + cf_sha3_256_digest_final(&ctx, hash); +} + +static void hashtest_sha3_512(void) +{ + uint8_t hash[CF_SHA3_512_HASHSZ]; + cf_sha3_context ctx; + cf_sha3_512_init(&ctx); + cf_sha3_512_update(&ctx, "", 0); + cf_sha3_512_digest_final(&ctx, hash); +} + +static void aes128block_test(void) +{ + uint8_t key[16] = { 0 }, block[16] = { 0 }; + cf_aes_context ctx; + cf_aes_init(&ctx, key, sizeof key); + cf_aes_encrypt(&ctx, block, block); +} + +static void aes128sched_test(void) +{ + uint8_t key[16] = { 0 }; + cf_aes_context ctx; + cf_aes_init(&ctx, key, sizeof key); +} + +static void aes256block_test(void) +{ + uint8_t key[32] = { 0 }, block[16] = { 0 }; + cf_aes_context ctx; + cf_aes_init(&ctx, key, sizeof key); + cf_aes_encrypt(&ctx, block, block); +} + +static void aes256sched_test(void) +{ + uint8_t key[32] = { 0 }; + cf_aes_context ctx; + cf_aes_init(&ctx, key, sizeof key); +} + +static void aes128gcm_test(void) +{ + uint8_t key[16] = { 0 }; + cf_aes_context ctx; + cf_aes_init(&ctx, key, sizeof key); + + uint8_t msg[16] = { 0 }; + uint8_t aad[16] = { 0 }; + uint8_t nonce[12] = { 0 }; + uint8_t cipher[16] = { 0 }; + uint8_t tag[16] = { 0 }; + + cf_gcm_encrypt(&cf_aes, &ctx, + msg, sizeof msg, + aad, sizeof aad, + nonce, sizeof nonce, + cipher, + tag, sizeof tag); +} + +static void aes128eax_test(void) +{ + uint8_t key[16] = { 0 }; + cf_aes_context ctx; + cf_aes_init(&ctx, key, sizeof key); + + uint8_t msg[16] = { 0 }; + uint8_t aad[16] = { 0 }; + uint8_t nonce[12] = { 0 }; + uint8_t cipher[16] = { 0 }; + uint8_t tag[16] = { 0 }; + + cf_eax_encrypt(&cf_aes, &ctx, + msg, sizeof msg, + aad, sizeof aad, + nonce, sizeof nonce, + cipher, + tag, sizeof tag); +} + +static void aes128ccm_test(void) +{ + uint8_t key[16] = { 0 }; + cf_aes_context ctx; + cf_aes_init(&ctx, key, sizeof key); + + uint8_t msg[16] = { 0 }; + uint8_t aad[16] = { 0 }; + uint8_t nonce[11] = { 0 }; + uint8_t cipher[16] = { 0 }; + uint8_t tag[16] = { 0 }; + + cf_ccm_encrypt(&cf_aes, &ctx, + msg, sizeof msg, 4, + aad, sizeof aad, + nonce, sizeof nonce, + cipher, + tag, sizeof tag); +} + +static void salsa20_test(void) +{ + uint8_t key[32] = { 0 }; + uint8_t nonce[8] = { 0 }; + uint8_t msg[64] = { 0 }; + uint8_t cipher[64] = { 0 }; + + cf_salsa20_ctx ctx; + cf_salsa20_init(&ctx, key, sizeof key, nonce); + cf_salsa20_cipher(&ctx, msg, cipher, sizeof msg); +} + +static void chacha20_test(void) +{ + uint8_t key[32] = { 0 }; + uint8_t nonce[8] = { 0 }; + uint8_t msg[64] = { 0 }; + uint8_t cipher[64] = { 0 }; + + cf_chacha20_ctx ctx; + cf_chacha20_init(&ctx, key, sizeof key, nonce); + cf_chacha20_cipher(&ctx, msg, cipher, sizeof msg); +} + +static void curve25519_test(void) +{ + uint8_t secret[32] = { 1 }; + uint8_t pubkey[32]; + cf_curve25519_mul_base(pubkey, secret); +} + +static const uint8_t *mac_message = (const uint8_t *) "hello world"; +static const size_t mac_message_len = 11; + +static void poly1305_test(void) +{ + uint8_t key[32] = { 0 }, + nonce[16] = { 0 }, + encnonce[16], + mac[16]; + + cf_aes_context aes; + cf_aes_init(&aes, key, 16); + cf_aes_encrypt(&aes, nonce, encnonce); + + cf_poly1305 poly; + cf_poly1305_init(&poly, key + 16, encnonce); + cf_poly1305_update(&poly, mac_message, mac_message_len); + cf_poly1305_finish(&poly, mac); +} + +static void hmacsha256_test(void) +{ + uint8_t key[32] = { 0 }, + mac[32] = { 0 }; + + cf_hmac_ctx ctx; + cf_hmac_init(&ctx, &cf_sha256, key, sizeof key); + cf_hmac_update(&ctx, mac_message, mac_message_len); + cf_hmac_finish(&ctx, mac); +} + +static void norx_test(void) +{ + uint8_t key[16] = { 0 }; + uint8_t msg[16] = { 0 }; + uint8_t aad[16] = { 0 }; + uint8_t nonce[8] = { 0 }; + uint8_t cipher[16] = { 0 }; + uint8_t tag[16] = { 0 }; + + cf_norx32_encrypt(key, + nonce, + aad, sizeof aad, + msg, sizeof msg, + NULL, 0, + cipher, + tag); +} + +#ifndef BRACKET_MODE +# define AEADPERF_LEN 1 +#else +# define AEADPERF_LEN BRACKET_END +#endif + +static uint8_t aead_msg[AEADPERF_LEN] = { 0 }; +static uint8_t aead_cipher[AEADPERF_LEN] = { 0 }; +static uint8_t aead_aad[16] = { 0 }; +static uint8_t aead_key[32] = { 0 }; +static uint8_t aead_nonce[16] = { 0 }; +static uint8_t aead_tag[16] = { 0 }; + +static void aeadperf_norx(void) +{ + cf_norx32_encrypt(aead_key, aead_nonce, + aead_aad, sizeof aead_aad, + aead_msg, bracket, + NULL, 0, + aead_cipher, aead_tag); +} + +static void aeadperf_chacha20poly1305(void) +{ + cf_chacha20poly1305_encrypt(aead_key, aead_nonce, + aead_aad, sizeof aead_aad, + aead_msg, bracket, + aead_cipher, aead_tag); +} +static void aeadperf_aes128gcm(void) +{ + cf_aes_context ctx; + cf_aes_init(&ctx, aead_key, 16); + + cf_gcm_encrypt(&cf_aes, &ctx, + aead_msg, bracket, + aead_aad, sizeof aead_aad, + aead_nonce, 12, + aead_cipher, + aead_tag, 16); +} + +static void aeadperf_aes128ccm(void) +{ + cf_aes_context ctx; + cf_aes_init(&ctx, aead_key, 16); + + cf_ccm_encrypt(&cf_aes, &ctx, + aead_msg, bracket, + 4, + aead_aad, sizeof aead_aad, + aead_nonce, 11, + aead_cipher, + aead_tag, 16); +} + +static void aeadperf_aes128eax(void) +{ + cf_aes_context ctx; + cf_aes_init(&ctx, aead_key, 16); + + cf_eax_encrypt(&cf_aes, &ctx, + aead_msg, bracket, + aead_aad, sizeof aead_aad, + aead_nonce, 12, + aead_cipher, + aead_tag, 16); +} + +static void aeadperf_aes256gcm(void) +{ + cf_aes_context ctx; + cf_aes_init(&ctx, aead_key, 32); + + cf_gcm_encrypt(&cf_aes, &ctx, + aead_msg, bracket, + aead_aad, sizeof aead_aad, + aead_nonce, 12, + aead_cipher, + aead_tag, 16); +} + +static void aeadperf_aes256ccm(void) +{ + cf_aes_context ctx; + cf_aes_init(&ctx, aead_key, 32); + + cf_ccm_encrypt(&cf_aes, &ctx, + aead_msg, bracket, + 4, + aead_aad, sizeof aead_aad, + aead_nonce, 11, + aead_cipher, + aead_tag, 16); +} + +static void aeadperf_aes256eax(void) +{ + cf_aes_context ctx; + cf_aes_init(&ctx, aead_key, 32); + + cf_eax_encrypt(&cf_aes, &ctx, + aead_msg, bracket, + aead_aad, sizeof aead_aad, + aead_nonce, 12, + aead_cipher, + aead_tag, 16); +} + +/* Provided by linkscript */ +extern uint32_t __HeapLimit; + +#define STACK_MAGIC 0x57ac34df + +static __attribute__((noinline)) void clear_stack(void) +{ + uint32_t *stack_start = &__HeapLimit; + uint32_t ss = 0, *stack_stop = &ss; + size_t words = stack_stop - stack_start; + for (size_t i = 0; i < words; i++) + stack_start[i] = STACK_MAGIC; +} + +static __attribute__((noinline)) uint32_t measure_stack(void) +{ + uint32_t *stack_start = &__HeapLimit; + uint32_t ss, *stack_stop = &ss; + size_t words = stack_stop - stack_start; + for (size_t i = 0; i < words; i++) + if (stack_start[i] != STACK_MAGIC) + return words - i + 4; /* we used 4 words for ourselves, roughly */ + + return 0; +} + +static void measure(measure_fn fn) +{ + clear_stack(); + uint32_t start_cycles = reset_cycles(); + fn(); + uint32_t end_cycles = get_cycles(); + uint32_t stack_words = measure_stack(); + + emit("cycles = "); + emit_uint32(end_cycles - start_cycles); + emit("\n"); + emit("stack = "); + emit_uint32(stack_words << 2); + emit("\n"); +} + +#define STRING_(x) #x +#define STRING(x) STRING_(x) + +int main(void) +{ + emit(STRING(TEST) "\n"); +#ifdef BRACKET_MODE + for (bracket = BRACKET_START; bracket <= BRACKET_END; bracket += BRACKET_STEP) + { + emit("bracket = "); + emit_uint32(bracket); + emit("\n"); + measure(TEST); + } +#else + measure(TEST); +#endif + quit_success(); + + (void) bracket; + (void) do_nothing; + (void) stack_8w; + (void) stack_64w; + (void) hashtest_sha256; + (void) hashtest_sha512; + (void) hashtest_sha3_256; + (void) hashtest_sha3_512; + (void) aes128block_test; + (void) aes128sched_test; + (void) aes256block_test; + (void) aes256sched_test; + (void) aes128gcm_test; + (void) aes128eax_test; + (void) aes128ccm_test; + (void) salsa20_test; + (void) chacha20_test; + (void) curve25519_test; + (void) poly1305_test; + (void) hmacsha256_test; + (void) norx_test; + (void) aeadperf_norx; + (void) aeadperf_chacha20poly1305; + (void) aeadperf_aes128gcm; + (void) aeadperf_aes128ccm; + (void) aeadperf_aes128eax; + (void) aeadperf_aes256gcm; + (void) aeadperf_aes256ccm; + (void) aeadperf_aes256eax; +} diff --git a/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/arm/memcpy.s b/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/arm/memcpy.s new file mode 100644 index 00000000..63406fe5 --- /dev/null +++ b/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/arm/memcpy.s @@ -0,0 +1,49 @@ + .text + .syntax unified + .global memcpy + .func memcpy + .thumb_func + +memcpy: + /* on entry + * r0 = targ + * r1 = src + * r2 = len (bytes) + * on exit + * r0 = targ (unchanged) + */ + push {r0, r4, lr} + + /* If targ or src are unaligned, drop to byte + * processing. */ + mov r3, r0 + movs r4, #3 + orrs r3, r1 + ands r3, r4 + bne L_bytewise + + /* Process words */ +L_wordwise: + cmp r2, #4 + blo L_bytewise + ldr r4, [r1] + adds r1, #4 + str r4, [r0] + adds r0, #4 + subs r2, #4 + b L_wordwise + + /* Process bytes */ +L_bytewise: + cmp r2, #0 + beq L_fin + ldrb r4, [r1] + adds r1, #1 + strb r4, [r0] + adds r0, #1 + subs r2, #1 + b L_bytewise + +L_fin: + pop {r0, r4, pc} + .endfunc diff --git a/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/arm/memset.s b/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/arm/memset.s new file mode 100644 index 00000000..a5019667 --- /dev/null +++ b/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/arm/memset.s @@ -0,0 +1,50 @@ + .text + .syntax unified + .global memset + .func memset + .thumb_func + +memset: + /* on entry + * r0 = targ + * r1 = value + * r2 = len (bytes) + * on exit + * r0 = targ (unchanged) + */ + push {r0, r4, lr} + + /* If targ is unaligned, drop to byte + * processing. */ + movs r3, #3 + ands r3, r0 + bne L_bytewise + + /* Process words */ + /* Build r4 by repeating r1. */ + uxtb r4, r1 + lsls r3, r4, #8 + orrs r4, r3 + lsls r3, r4, #16 + orrs r4, r3 + +L_wordwise: + cmp r2, #4 + blo L_bytewise + str r4, [r0] + adds r0, #4 + subs r2, #4 + b L_wordwise + + /* Process bytes */ +L_bytewise: + cmp r2, #0 + beq L_fin + strb r1, [r0] + adds r0, #1 + subs r2, #1 + b L_bytewise + +L_fin: + pop {r0, r4, pc} + .endfunc diff --git a/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/arm/merge.py b/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/arm/merge.py new file mode 100644 index 00000000..71d50895 --- /dev/null +++ b/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/arm/merge.py @@ -0,0 +1,26 @@ +import sys + +def extract_results(results): + index = 0 + while index < len(results): + if results[index].startswith('## '): + end = results.index('\n', index) + yield results[index:end] + index += 1 + +def merge(readme, res): + title, table = res[0], res[1:] + assert title in readme, 'Section ' + title + ' missing from README.md' + secindex = readme.index(title) + hdrindex = [i for i in range(secindex, len(readme)) if readme[i].startswith('---------- | ')][0] + start = hdrindex - 1 + end = readme.index('\n', start) + table = [t.rstrip() + '\n' for t in table] + return readme[:start] + table + readme[end:] + +results = sys.stdin.readlines() +readme = open('../../README.md').readlines() + +for res in extract_results(results): + readme = merge(readme, res) +print ''.join(readme).rstrip() diff --git a/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/arm/openocd.efm32.cfg b/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/arm/openocd.efm32.cfg new file mode 100644 index 00000000..85af4733 --- /dev/null +++ b/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/arm/openocd.efm32.cfg @@ -0,0 +1,3 @@ +source [find interface/jlink.cfg] +transport select swd +source [find target/efm32.cfg] diff --git a/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/arm/openocd.stm32f0.cfg b/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/arm/openocd.stm32f0.cfg new file mode 100644 index 00000000..e9356f75 --- /dev/null +++ b/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/arm/openocd.stm32f0.cfg @@ -0,0 +1,3 @@ +source [find interface/stlink-v2.cfg] +transport select hla_swd +source [find target/stm32f0x.cfg] diff --git a/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/arm/openocd.stm32f1.cfg b/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/arm/openocd.stm32f1.cfg new file mode 100644 index 00000000..1108ea07 --- /dev/null +++ b/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/arm/openocd.stm32f1.cfg @@ -0,0 +1,3 @@ +source [find interface/stlink-v2.cfg] +transport select hla_swd +source [find target/stm32f1x.cfg] diff --git a/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/arm/openocd.stm32f3.cfg b/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/arm/openocd.stm32f3.cfg new file mode 100644 index 00000000..de023b84 --- /dev/null +++ b/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/arm/openocd.stm32f3.cfg @@ -0,0 +1,3 @@ +source [find interface/stlink-v2.cfg] +transport select hla_swd +source [find target/stm32f3x.cfg] diff --git a/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/arm/report.py b/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/arm/report.py new file mode 100644 index 00000000..718ab24e --- /dev/null +++ b/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/arm/report.py @@ -0,0 +1,276 @@ +""" +Interprets logs from test runs. Outputs ASCII +tables containing results, json data, etc. +""" + +import json +import sys + +archs = 'stm32f0 stm32f1 stm32f3'.split() +tests = """ +aes128block_test +aes256block_test +aes128sched_test +aes256sched_test +hashtest_sha256 +hashtest_sha512 +hashtest_sha3_256 +hashtest_sha3_512 +aes128gcm_test +aes128eax_test +aes128ccm_test +norx_test +salsa20_test +chacha20_test +poly1305_test +hmacsha256_test +curve25519_test +aeadperf_norx +aeadperf_aes128gcm +aeadperf_aes128eax +aeadperf_aes128ccm +aeadperf_aes256gcm +aeadperf_aes256eax +aeadperf_aes256ccm +aeadperf_chacha20poly1305 +do_nothing +""".split() + +arch_names = dict( + stm32f0 = 'Cortex-M0', + stm32f1 = 'Cortex-M3', + stm32f3 = 'Cortex-M4F' + ) + +base_test = 'do_nothing' + +def extract(arch, test): + fn = 'run.%s.%s.log' % (test, arch) + + code_size = 0 + data_size = 0 + cycle_count = None + stack_usage = None + brackets = None + current_bracket = None + + try: + lines = open(fn).readlines() + except IOError: + return None + + for l in lines: + if 'LOAD' in l: + parts = l.split() + assert len(parts) >= 8 + assert 'LOAD' == parts[0] + if parts[6] == 'RWE': + code_size += long(parts[5], 16) + if parts[6] == 'RW': + data_size += long(parts[5], 16) + + if l.startswith('bracket = '): + bracket = long(l.split(' = ')[1].strip(), 16) + current_bracket = bracket + if brackets is None: + brackets = {} + brackets[current_bracket] = dict() + + if l.startswith('cycles = '): + cycle_count = long(l.split(' = ')[1].strip(), 16) + if current_bracket is not None: + brackets[current_bracket]['cycle_count'] = cycle_count + + if l.startswith('stack = '): + stack_usage = long(l.split(' = ')[1].strip(), 16) + if current_bracket is not None: + brackets[current_bracket]['stack_usage'] = stack_usage + + return dict( + code_size = code_size, + data_size = data_size, + cycle_count = cycle_count, + stack_usage = stack_usage, + brackets = brackets + ) + +def print_table(rows): + header, rows = rows[0], rows[1:] + assert not [True for r in rows if len(r) != len(header)] + widths = [] + for i, h in enumerate(header): + widths.append(max([len(h)] + [len(r[i]) for r in rows])) + + def print_row(row): + print ' | '.join(c + (' ' * (widths[i] - len(c))) for i, c in enumerate(row)) + + print_row(header) + print_row(['-' * w for w in widths]) + for r in rows: + print_row(r) + +results = {} + +for arch in archs: + for test in tests: + inf = extract(arch, test) + if inf: + results.setdefault(arch, {})[test] = inf + +for arch in results.keys(): + if base_test not in results[arch]: + print 'need', base_test, 'results to report for', arch + continue + + base_result = results[arch][base_test] + + for test in results[arch].keys(): + if test == base_test: + continue + + results[arch][test]['code_size'] -= base_result['code_size'] + +def tabulate_aes(arch, block_result, sched_result, table = None): + if table is None: + table = [] + table.append(( + 'Core', + 'Cycles (key schedule + block)', + 'Cycles (key schedule)', + 'Cycles (block)', + 'Stack', + 'Code size' + )) + + table.append( + ( + arch_names[arch], + '%d' % block_result['cycle_count'], + '%d' % sched_result['cycle_count'], + '%d' % (block_result['cycle_count'] - sched_result['cycle_count']), + '%dB' % block_result['stack_usage'], + '%dB' % block_result['code_size'] + )) + + return table + +def print_std(result): + print """* **Cycles**: %(cycle_count)d +* **Stack**: %(stack_usage)dB +* **Code size**: %(code_size)dB +""" % result + +def tabulate_std(arch, result, table = None): + if table is None: + table = [] + table.append(('Core', 'Cycles', 'Stack', 'Code size')) + + table.append( + ( + arch_names[arch], + '%d' % result['cycle_count'], + '%dB' % result['stack_usage'], + '%dB' % result['code_size'] + )) + + return table + +def tabulate(mktab): + table = None + for arch in archs: + if arch not in results: + continue + table = mktab(arch, table) + print_table(table) + +def convert_brackets(metric, tests): + for arch in archs: + arch_result = {} + + # collect results for each test + for t in tests: + if arch not in results or t not in results[arch]: + print 'missing', arch, t + continue + data = results[arch][t]['brackets'] + arch_result[t] = [[b, data[b][metric]] for b in sorted(data.keys())] + + # convert into list of [bracket, test-1, test-2, ...] lists + out = [] + if len(arch_result) == 0: + continue + first_row = arch_result.values()[0] + + for i in range(len(first_row)): + row = [ first_row[i][0] ] + + for k in sorted(arch_result.keys()): + if len(arch_result[k]) != len(first_row): + print 'warn:', 'test', k, 'did not complete?' + rr = arch_result[k][i] + row.append(rr[1]) + + out.append(row) + + print json.dumps(out) + +convert_brackets('cycle_count', + [ + 'aeadperf_norx', + 'aeadperf_aes128gcm', + 'aeadperf_aes128eax', + 'aeadperf_aes128ccm', + 'aeadperf_aes256gcm', + 'aeadperf_aes256eax', + 'aeadperf_aes256ccm', + 'aeadperf_chacha20poly1305' + ]) +convert_brackets('stack_usage', + [ + 'aeadperf_norx', + 'aeadperf_aes128gcm', + 'aeadperf_aes128eax', + 'aeadperf_aes128ccm', + 'aeadperf_aes256gcm', + 'aeadperf_aes256eax', + 'aeadperf_aes256ccm', + 'aeadperf_chacha20poly1305' + ]) + +# screwed if we need other block ciphers +print '###', '128-bit key' +tabulate(lambda arch, table: tabulate_aes(arch, results[arch]['aes128block_test'], results[arch]['aes128sched_test'], table)) +print + +print '###', '256-bit key' +tabulate(lambda arch, table: tabulate_aes(arch, results[arch]['aes256block_test'], results[arch]['aes256sched_test'], table)) +print + +def do_table(title, test): + print '##', title + tabulate(lambda arch, table: tabulate_std(arch, results[arch][test], table)) + print + +do_table('AES128-GCM', 'aes128gcm_test') +do_table('AES128-EAX', 'aes128eax_test') +do_table('AES128-CCM', 'aes128ccm_test') +do_table('NORX32', 'norx_test') +do_table('ChaCha20', 'chacha20_test') +do_table('Salsa20', 'salsa20_test') +do_table('SHA256', 'hashtest_sha256') +do_table('SHA512', 'hashtest_sha512') +do_table('SHA3-256', 'hashtest_sha3_256') +do_table('SHA3-512', 'hashtest_sha3_512') +do_table('HMAC-SHA256', 'hmacsha256_test') +do_table('Poly1305-AES', 'poly1305_test') +do_table('Curve25519', 'curve25519_test') + +if '--aead' in sys.argv: + do_table('AEAD-Shootout: NORX', 'aeadperf_norx') + do_table('AEAD-Shootout: AES-128-GCM', 'aeadperf_aes128gcm') + do_table('AEAD-Shootout: AES-128-EAX', 'aeadperf_aes128eax') + do_table('AEAD-Shootout: AES-128-CCM', 'aeadperf_aes128ccm') + do_table('AEAD-Shootout: AES-256-GCM', 'aeadperf_aes256gcm') + do_table('AEAD-Shootout: AES-256-EAX', 'aeadperf_aes256eax') + do_table('AEAD-Shootout: AES-256-CCM', 'aeadperf_aes256ccm') + do_table('AEAD-Shootout: ChaCha20-Poly1305', 'aeadperf_chacha20poly1305') diff --git a/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/arm/semihost.c b/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/arm/semihost.c new file mode 100644 index 00000000..cbe5aa2e --- /dev/null +++ b/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/arm/semihost.c @@ -0,0 +1,170 @@ +#include +#include +#include +#include + +#include "semihost.h" + +#define OP_WRITE0 0x04 +#define OP_EXIT 0x18 +#define OP_EXIT_ARG_FAILURE 0x0 +#define OP_EXIT_ARG_SUCCESS 0x20026 + +extern uint32_t semihost(uint32_t, volatile void *); + +__attribute__((noreturn)) +void quit_success(void) +{ + semihost(OP_EXIT, (void *) OP_EXIT_ARG_SUCCESS); + while (1) + ; +} + +__attribute__((noreturn)) +void quit_failure(void) +{ + semihost(OP_EXIT, (void *) OP_EXIT_ARG_FAILURE); + while (1) + ; +} + +void emit(const char *buf) +{ + semihost(OP_WRITE0, (volatile void *) buf); +} + +static void emit_extent(const char *start, const char *end) +{ + char buf[32+1]; + size_t bufmax = sizeof(buf) - 1; + buf[32] = 0; + + size_t bytes = end - start + 1; + + while (bytes >= bufmax) + { + memcpy(buf, start, bufmax); + emit(buf); + bytes -= bufmax; + start += bufmax; + } + + if (bytes == 0) + return; + + memcpy(buf, start, bytes); + buf[bytes] = 0; + emit(buf); +} + +void emitf(const char *fmt, ...) +{ + const char *start = fmt, *end = fmt; + + va_list args; + va_start(args, fmt); + + while (*fmt) + { + switch (*fmt) + { + case '%': + emit_extent(start, end); + + switch (fmt[1]) + { + case '%': + emit("%"); + break; + + case 'u': + emit_uint32(va_arg(args, uint32_t)); + break; + + case 's': + emit(va_arg(args, const char *)); + break; + } + start = end = fmt + 2; + break; + + default: + end = fmt; + break; + } + + fmt++; + } + + va_end(args); + emit_extent(start, end); +} + +static const char *hex_chars = "0123456789abcdef"; + +void emit_hex(const void *ptr, size_t len) +{ + const uint8_t *bb = ptr; + char byte[3]; + + byte[2] = 0; + + for (size_t i = 0; i < len; i++) + { + byte[0] = hex_chars[(bb[i] >> 4) & 0xf]; + byte[1] = hex_chars[bb[i] & 0xf]; + emit(byte); + } +} + +void emit_uint32(uint32_t x) +{ + char buf[sizeof "0x11223344"]; + buf[0] = '0'; + buf[1] = 'x'; + buf[2] = hex_chars[(x >> 28) & 0xf]; + buf[3] = hex_chars[(x >> 24) & 0xf]; + buf[4] = hex_chars[(x >> 20) & 0xf]; + buf[5] = hex_chars[(x >> 16) & 0xf]; + buf[6] = hex_chars[(x >> 12) & 0xf]; + buf[7] = hex_chars[(x >> 8) & 0xf]; + buf[8] = hex_chars[(x >> 4) & 0xf]; + buf[9] = hex_chars[x & 0xf]; + buf[10] = 0; + + emit(buf); +} + +typedef struct +{ + volatile uint32_t ctrl; + volatile uint32_t reload; + volatile uint32_t current; +} systick; + +#define SysTick ((systick *)0xe000e010) + +#define STCTRL_SYSCLOCK 0x04 +#define STCTRL_TICKINT 0x02 +#define STCTRL_ENABLE 0x01 + +#define STCTRL_MAX 0xffffff +#define STCTRL_SHIFT 24 + +extern uint32_t get_ticks(void); +extern void reset_ticks(void); + +uint32_t reset_cycles(void) +{ + SysTick->reload = STCTRL_MAX; + SysTick->ctrl = STCTRL_SYSCLOCK | STCTRL_TICKINT | STCTRL_ENABLE; + SysTick->current = 0; + reset_ticks(); + return get_ticks(); +} + +uint32_t get_cycles(void) +{ + return (get_ticks() << STCTRL_SHIFT) + (STCTRL_MAX - SysTick->current); +} + diff --git a/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/arm/semihost.h b/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/arm/semihost.h new file mode 100644 index 00000000..cf6f01a5 --- /dev/null +++ b/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/arm/semihost.h @@ -0,0 +1,40 @@ +#ifndef SEMIHOST_H +#define SEMIHOST_H + +#include +#include + +/* Exits emulator with success (or merely hangs). */ +__attribute__((noreturn)) +void quit_success(void); + +/* Exits emulator with failure (or merely hangs). */ +__attribute__((noreturn)) +void quit_failure(void); + +/* Writes zero terminated string to debug output */ +void emit(const char *buf); + +/* Writes a formatting string to debug output. + * + * Supported: + * %u - uint32_t argument, same as emit_uint32 + * %s - const char * argument, same as emit + */ +void emitf(const char *fmt, ...); + +/* Writes hex dump of len bytes at ptr to debug output. */ +void emit_hex(const void *ptr, size_t len); + +/* Writes value v in hex to debug output, in format: + * 0xHHHHHHHH (equivalent to printf 0x%08x). */ +void emit_uint32(uint32_t v); + +/* Reset cycle counter to 0. Returns the current value + * (just after resetting it). */ +uint32_t reset_cycles(void); + +/* Return the value of the cycle counter. */ +uint32_t get_cycles(void); + +#endif diff --git a/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/arm/semihost.s b/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/arm/semihost.s new file mode 100644 index 00000000..0fddf045 --- /dev/null +++ b/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/arm/semihost.s @@ -0,0 +1,15 @@ + .text + .syntax unified + .global semihost + .func semihost + .thumb_func + +semihost: + /* on entry + * r0 = op + * r1 = arg */ + push {r7, lr} + bkpt 0xab + pop {r7, pc} + + .endfunc diff --git a/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/arm/unacl/cortex_m0_mpy121666.s b/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/arm/unacl/cortex_m0_mpy121666.s new file mode 100644 index 00000000..49e3b5d0 --- /dev/null +++ b/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/arm/unacl/cortex_m0_mpy121666.s @@ -0,0 +1,199 @@ +// Implementation of multiplication of an fe25519 bit value with the curve constant 121666. +// +// B. Haase, Endress + Hauser Conducta GmbH & Ko. KG +// public domain. +// +// gnu assembler format. +// +// Generated and tested with C++ functions in the test subdirectory. +// +// ATTENTION: +// Not yet tested on target hardware. + + + .cpu cortex-m0 + .fpu softvfp + .eabi_attribute 20, 1 + .eabi_attribute 21, 1 + .eabi_attribute 23, 3 + .eabi_attribute 24, 1 + .eabi_attribute 25, 1 + .eabi_attribute 26, 1 + .eabi_attribute 30, 2 + .eabi_attribute 34, 0 + .eabi_attribute 18, 4 + .code 16 + + .file "cortex_m0_reduce25519.s" + + .text + .align 2 + + .global fe25519_mpyWith121666_asm + .code 16 + .thumb_func + .type fe25519_mpyWith121666_asm, %function + +fe25519_mpyWith121666_asm: + push {r4,r5,r6,r7,r14} + ldr r7,__label_for_immediate_56130 + ldr r2,[r1,#28] + lsl r5,r2,#16 + lsr r6,r2,#16 + lsr r3,r2,#16 + uxth r2,r2 + mul r2,r7 + mul r3,r7 + add r5,r2 + mov r2,#0 + adc r6,r2 + lsl r2,r3,#16 + lsr r3,r3,#16 + add r5,r2 + adc r6,r3 + lsl r2,r5,#1 + lsr r2,r2,#1 + str r2,[r0,#28] + lsr r5,r5,#31 + lsl r6,r6,#1 + orr r5,r6 + mov r6,#19 + mul r5,r6 + mov r6,#0 + ldr r2,[r1,#0] + lsl r3,r2,#16 + lsr r4,r2,#16 + add r5,r3 + adc r6,r4 + lsr r3,r2,#16 + uxth r2,r2 + mul r2,r7 + mul r3,r7 + add r5,r2 + mov r2,#0 + adc r6,r2 + lsl r2,r3,#16 + lsr r3,r3,#16 + add r5,r2 + adc r6,r3 + str r5,[r0,#0] + mov r5,#0 + ldr r2,[r1,#4] + lsl r3,r2,#16 + lsr r4,r2,#16 + add r6,r3 + adc r5,r4 + lsr r3,r2,#16 + uxth r2,r2 + mul r2,r7 + mul r3,r7 + add r6,r2 + mov r2,#0 + adc r5,r2 + lsl r2,r3,#16 + lsr r3,r3,#16 + add r6,r2 + adc r5,r3 + str r6,[r0,#4] + mov r6,#0 + ldr r2,[r1,#8] + lsl r3,r2,#16 + lsr r4,r2,#16 + add r5,r3 + adc r6,r4 + lsr r3,r2,#16 + uxth r2,r2 + mul r2,r7 + mul r3,r7 + add r5,r2 + mov r2,#0 + adc r6,r2 + lsl r2,r3,#16 + lsr r3,r3,#16 + add r5,r2 + adc r6,r3 + str r5,[r0,#8] + mov r5,#0 + ldr r2,[r1,#12] + lsl r3,r2,#16 + lsr r4,r2,#16 + add r6,r3 + adc r5,r4 + lsr r3,r2,#16 + uxth r2,r2 + mul r2,r7 + mul r3,r7 + add r6,r2 + mov r2,#0 + adc r5,r2 + lsl r2,r3,#16 + lsr r3,r3,#16 + add r6,r2 + adc r5,r3 + str r6,[r0,#12] + mov r6,#0 + ldr r2,[r1,#16] + lsl r3,r2,#16 + lsr r4,r2,#16 + add r5,r3 + adc r6,r4 + lsr r3,r2,#16 + uxth r2,r2 + mul r2,r7 + mul r3,r7 + add r5,r2 + mov r2,#0 + adc r6,r2 + lsl r2,r3,#16 + lsr r3,r3,#16 + add r5,r2 + adc r6,r3 + str r5,[r0,#16] + mov r5,#0 + ldr r2,[r1,#20] + lsl r3,r2,#16 + lsr r4,r2,#16 + add r6,r3 + adc r5,r4 + lsr r3,r2,#16 + uxth r2,r2 + mul r2,r7 + mul r3,r7 + add r6,r2 + mov r2,#0 + adc r5,r2 + lsl r2,r3,#16 + lsr r3,r3,#16 + add r6,r2 + adc r5,r3 + str r6,[r0,#20] + mov r6,#0 + ldr r2,[r1,#24] + lsl r3,r2,#16 + lsr r4,r2,#16 + add r5,r3 + adc r6,r4 + lsr r3,r2,#16 + uxth r2,r2 + mul r2,r7 + mul r3,r7 + add r5,r2 + mov r2,#0 + adc r6,r2 + lsl r2,r3,#16 + lsr r3,r3,#16 + add r5,r2 + adc r6,r3 + str r5,[r0,#24] + mov r5,#0 + ldr r2,[r0,#28] + add r6,r2 + str r6,[r0,#28] + pop {r4,r5,r6,r7,r15} + + .align 2 +__label_for_immediate_56130: + .word 56130 + + .size fe25519_mpyWith121666_asm, .-fe25519_mpyWith121666_asm + diff --git a/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/arm/unacl/cortex_m0_reduce25519.s b/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/arm/unacl/cortex_m0_reduce25519.s new file mode 100644 index 00000000..4c09f5ea --- /dev/null +++ b/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/arm/unacl/cortex_m0_reduce25519.s @@ -0,0 +1,176 @@ +// Implementation of a partial reduction modulo 2^255 - 38. +// +// B. Haase, Endress + Hauser Conducta GmbH & Ko. KG +// public domain. +// +// gnu assembler format. +// +// Generated and tested with C++ functions in the test subdirectory and on the target. +// + + .cpu cortex-m0 + .fpu softvfp + .eabi_attribute 20, 1 + .eabi_attribute 21, 1 + .eabi_attribute 23, 3 + .eabi_attribute 24, 1 + .eabi_attribute 25, 1 + .eabi_attribute 26, 1 + .eabi_attribute 30, 2 + .eabi_attribute 34, 0 + .eabi_attribute 18, 4 + .code 16 + + .file "cortex_m0_reduce25519.s" + + .text + .align 2 + + .global fe25519_reduceTo256Bits_asm + .code 16 + .thumb_func + .type fe25519_reduceTo256Bits_asm, %function + +fe25519_reduceTo256Bits_asm: + push {r4,r5,r6,r7,r14} + ldr r2,[r1,#60] + lsr r3,r2,#16 + uxth r2,r2 + mov r7,#38 + mul r2,r7 + mul r3,r7 + ldr r4,[r1,#28] + lsr r5,r3,#16 + lsl r3,r3,#16 + mov r6,#0 + add r4,r2 + adc r5,r6 + add r4,r3 + adc r5,r6 + lsl r2,r4,#1 + lsr r2,r2,#1 + str r2,[r0,#28] + lsr r4,r4,#31 + lsl r5,r5,#1 + orr r4,r5 + mov r2,#19 + mul r2,r4 + ldr r4,[r1,#0] + add r2,r4 + mov r3,#0 + adc r3,r6 + ldr r4,[r1,#32] + lsr r5,r4,#16 + uxth r4,r4 + mul r5,r7 + mul r4,r7 + add r2,r4 + adc r3,r6 + lsl r4,r5,#16 + lsr r5,r5,#16 + add r2,r4 + adc r3,r5 + str r2,[r0,#0] + ldr r4,[r1,#4] + add r3,r4 + mov r2,#0 + adc r2,r6 + ldr r4,[r1,#36] + lsr r5,r4,#16 + uxth r4,r4 + mul r5,r7 + mul r4,r7 + add r3,r4 + adc r2,r6 + lsl r4,r5,#16 + lsr r5,r5,#16 + add r3,r4 + adc r2,r5 + str r3,[r0,#4] + ldr r4,[r1,#8] + add r2,r4 + mov r3,#0 + adc r3,r6 + ldr r4,[r1,#40] + lsr r5,r4,#16 + uxth r4,r4 + mul r5,r7 + mul r4,r7 + add r2,r4 + adc r3,r6 + lsl r4,r5,#16 + lsr r5,r5,#16 + add r2,r4 + adc r3,r5 + str r2,[r0,#8] + ldr r4,[r1,#12] + add r3,r4 + mov r2,#0 + adc r2,r6 + ldr r4,[r1,#44] + lsr r5,r4,#16 + uxth r4,r4 + mul r5,r7 + mul r4,r7 + add r3,r4 + adc r2,r6 + lsl r4,r5,#16 + lsr r5,r5,#16 + add r3,r4 + adc r2,r5 + str r3,[r0,#12] + ldr r4,[r1,#16] + add r2,r4 + mov r3,#0 + adc r3,r6 + ldr r4,[r1,#48] + lsr r5,r4,#16 + uxth r4,r4 + mul r5,r7 + mul r4,r7 + add r2,r4 + adc r3,r6 + lsl r4,r5,#16 + lsr r5,r5,#16 + add r2,r4 + adc r3,r5 + str r2,[r0,#16] + ldr r4,[r1,#20] + add r3,r4 + mov r2,#0 + adc r2,r6 + ldr r4,[r1,#52] + lsr r5,r4,#16 + uxth r4,r4 + mul r5,r7 + mul r4,r7 + add r3,r4 + adc r2,r6 + lsl r4,r5,#16 + lsr r5,r5,#16 + add r3,r4 + adc r2,r5 + str r3,[r0,#20] + ldr r4,[r1,#24] + add r2,r4 + mov r3,#0 + adc r3,r6 + ldr r4,[r1,#56] + lsr r5,r4,#16 + uxth r4,r4 + mul r5,r7 + mul r4,r7 + add r2,r4 + adc r3,r6 + lsl r4,r5,#16 + lsr r5,r5,#16 + add r2,r4 + adc r3,r5 + str r2,[r0,#24] + ldr r4,[r0,#28] + add r4,r3 + str r4,[r0,#28] + pop {r4,r5,r6,r7,r15} + + .size fe25519_reduceTo256Bits_asm, .-fe25519_reduceTo256Bits_asm + diff --git a/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/arm/unacl/mul.s b/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/arm/unacl/mul.s new file mode 100644 index 00000000..155674c6 --- /dev/null +++ b/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/arm/unacl/mul.s @@ -0,0 +1,1109 @@ + .align 2 + .global multiply256x256_asm + .type multiply256x256_asm, %function +multiply256x256_asm: + push {r4-r7,lr} + mov r3, r8 + mov r4, r9 + mov r5, r10 + mov r6, r11 + push {r0-r6} + mov r12, r0 + mov r10, r2 + mov r11, r1 + mov r0,r2 + ldm r0!, {r4,r5,r6,r7} + ldm r1!, {r2,r3,r6,r7} + push {r0,r1} + /////////BEGIN LOW PART ////////////////////// + /////////MUL128///////////// + //MUL64 + mov r6, r5 + mov r1, r2 + sub r5, r4 + sbc r0, r0 + eor r5, r0 + sub r5, r0 + sub r1, r3 + sbc r7, r7 + eor r1, r7 + sub r1, r7 + eor r7, r0 + mov r9, r1 + mov r8, r5 + lsr r1,r4,#16 + uxth r4,r4 + mov r0,r4 + uxth r5,r2 + lsr r2,#16 + mul r0,r5//00 + mul r5,r1//10 + mul r4,r2//01 + mul r1,r2//11 + lsl r2,r4,#16 + lsr r4,r4,#16 + add r0,r2 + adc r1,r4 + lsl r2,r5,#16 + lsr r4,r5,#16 + add r0,r2 + adc r1,r4 + lsr r4, r6,#16 + uxth r6, r6 + uxth r5, r3 + lsr r3, r3, #16 + mov r2, r6 + mul r2, r5 + mul r5, r4 + mul r6, r3 + mul r3, r4 + lsl r4,r5,#16 + lsr r5,r5,#16 + add r2,r4 + adc r3,r5 + lsl r4,r6,#16 + lsr r5,r6,#16 + add r2,r4 + adc r3,r5 + eor r6, r6 + add r2, r1 + adc r3, r6 + mov r1, r9 + mov r5, r8 + mov r8, r0 + lsr r0, r1,#16 + uxth r1,r1 + mov r4,r1 + lsr r6,r5,#16 + uxth r5,r5 + mul r1,r5 + mul r4,r6 + mul r5,r0 + mul r0,r6 + lsl r6,r4,#16 + lsr r4,#16 + add r1,r6 + adc r0,r4 + lsl r6,r5,#16 + lsr r5,#16 + add r1,r6 + adc r0,r5 + eor r1,r7 + eor r0,r7 + eor r4, r4 + asr r7, r7, #1 + adc r1, r2 + adc r2, r0 + adc r7, r4 + mov r0, r8 + add r1, r0 + adc r2, r3 + adc r3, r7 + ////////////////////////// + mov r4, r12 + stm r4!, {r0,r1} + push {r4} + push {r0,r1} + mov r1, r10 + mov r10, r2 + ldm r1, {r0, r1, r4, r5} + mov r2, r4 + mov r7, r5 + sub r2, r0 + sbc r7, r1 + sbc r6, r6 + eor r2, r6 + eor r7, r6 + sub r2, r6 + sbc r7, r6 + push {r2, r7} + mov r2, r11 + mov r11, r3 + ldm r2, {r0, r1, r2, r3} + sub r0, r2 + sbc r1, r3 + sbc r7, r7 + eor r0, r7 + eor r1, r7 + sub r0, r7 + sbc r1, r7 + eor r7, r6 + mov r12, r7 + push {r0, r1} + //MUL64 + mov r6, r5 + mov r1, r2 + sub r5, r4 + sbc r0, r0 + eor r5, r0 + sub r5, r0 + sub r1, r3 + sbc r7, r7 + eor r1, r7 + sub r1, r7 + eor r7, r0 + mov r9, r1 + mov r8, r5 + lsr r1,r4,#16 + uxth r4,r4 + mov r0,r4 + uxth r5,r2 + lsr r2,#16 + mul r0,r5//00 + mul r5,r1//10 + mul r4,r2//01 + mul r1,r2//11 + lsl r2,r4,#16 + lsr r4,r4,#16 + add r0,r2 + adc r1,r4 + lsl r2,r5,#16 + lsr r4,r5,#16 + add r0,r2 + adc r1,r4 + lsr r4, r6,#16 + uxth r6, r6 + uxth r5, r3 + lsr r3, r3, #16 + mov r2, r6 + mul r2, r5 + mul r5, r4 + mul r6, r3 + mul r3, r4 + lsl r4,r5,#16 + lsr r5,r5,#16 + add r2,r4 + adc r3,r5 + lsl r4,r6,#16 + lsr r5,r6,#16 + add r2,r4 + adc r3,r5 + eor r6, r6 + add r2, r1 + adc r3, r6 + mov r1, r9 + mov r5, r8 + mov r8, r0 + lsr r0, r1,#16 + uxth r1,r1 + mov r4,r1 + lsr r6,r5,#16 + uxth r5,r5 + mul r1,r5 + mul r4,r6 + mul r5,r0 + mul r0,r6 + lsl r6,r4,#16 + lsr r4,#16 + add r1,r6 + adc r0,r4 + lsl r6,r5,#16 + lsr r5,#16 + add r1,r6 + adc r0,r5 + eor r1,r7 + eor r0,r7 + eor r4, r4 + asr r7, r7, #1 + adc r1, r2 + adc r2, r0 + adc r7, r4 + mov r0, r8 + add r1, r0 + adc r2, r3 + adc r3, r7 + mov r4, r10 + mov r5, r11 + eor r6, r6 + add r0, r4 + adc r1, r5 + adc r2, r6 + adc r3, r6 + mov r10, r2 + mov r11, r3 + pop {r2-r5} + push {r0, r1} + mov r6, r5 + mov r1, r2 + sub r5, r4 + sbc r0, r0 + eor r5, r0 + sub r5, r0 + sub r1, r3 + sbc r7, r7 + eor r1, r7 + sub r1, r7 + eor r7, r0 + mov r9, r1 + mov r8, r5 + lsr r1,r4,#16 + uxth r4,r4 + mov r0,r4 + uxth r5,r2 + lsr r2,#16 + mul r0,r5//00 + mul r5,r1//10 + mul r4,r2//01 + mul r1,r2//11 + lsl r2,r4,#16 + lsr r4,r4,#16 + add r0,r2 + adc r1,r4 + lsl r2,r5,#16 + lsr r4,r5,#16 + add r0,r2 + adc r1,r4 + lsr r4, r6,#16 + uxth r6, r6 + uxth r5, r3 + lsr r3, r3, #16 + mov r2, r6 + mul r2, r5 + mul r5, r4 + mul r6, r3 + mul r3, r4 + lsl r4,r5,#16 + lsr r5,r5,#16 + add r2,r4 + adc r3,r5 + lsl r4,r6,#16 + lsr r5,r6,#16 + add r2,r4 + adc r3,r5 + eor r6, r6 + add r2, r1 + adc r3, r6 + mov r1, r9 + mov r5, r8 + mov r8, r0 + lsr r0, r1,#16 + uxth r1,r1 + mov r4,r1 + lsr r6,r5,#16 + uxth r5,r5 + mul r1,r5 + mul r4,r6 + mul r5,r0 + mul r0,r6 + lsl r6,r4,#16 + lsr r4,#16 + add r1,r6 + adc r0,r4 + lsl r6,r5,#16 + lsr r5,#16 + add r1,r6 + adc r0,r5 + eor r1,r7 + eor r0,r7 + eor r4, r4 + asr r7, r7, #1 + adc r1, r2 + adc r2, r0 + adc r7, r4 + mov r0, r8 + add r1, r0 + adc r2, r3 + adc r3, r7 + pop {r4, r5} + mov r6, r12 + mov r7, r12 + eor r0, r6 + eor r1, r6 + eor r2, r6 + eor r3, r6 + asr r6, r6, #1 + adc r0, r4 + adc r1, r5 + adc r4, r2 + adc r5, r3 + eor r2, r2 + adc r6,r2 + adc r7,r2 + pop {r2, r3} + mov r8, r2 + mov r9, r3 + add r2, r0 + adc r3, r1 + mov r0, r10 + mov r1, r11 + adc r4, r0 + adc r5, r1 + adc r6, r0 + adc r7, r1 + ////////END LOW PART///////////////////// + pop {r0} + stm r0!, {r2,r3} + pop {r1,r2} + push {r0} + push {r4-r7} + mov r10, r1 + mov r11, r2 + ldm r1!, {r4, r5} + ldm r2, {r2, r3} + /////////BEGIN HIGH PART//////////////// + /////////MUL128///////////// + //MUL64 + mov r6, r5 + mov r1, r2 + sub r5, r4 + sbc r0, r0 + eor r5, r0 + sub r5, r0 + sub r1, r3 + sbc r7, r7 + eor r1, r7 + sub r1, r7 + eor r7, r0 + mov r9, r1 + mov r8, r5 + lsr r1,r4,#16 + uxth r4,r4 + mov r0,r4 + uxth r5,r2 + lsr r2,#16 + mul r0,r5//00 + mul r5,r1//10 + mul r4,r2//01 + mul r1,r2//11 + lsl r2,r4,#16 + lsr r4,r4,#16 + add r0,r2 + adc r1,r4 + lsl r2,r5,#16 + lsr r4,r5,#16 + add r0,r2 + adc r1,r4 + lsr r4, r6,#16 + uxth r6, r6 + uxth r5, r3 + lsr r3, r3, #16 + mov r2, r6 + mul r2, r5 + mul r5, r4 + mul r6, r3 + mul r3, r4 + lsl r4,r5,#16 + lsr r5,r5,#16 + add r2,r4 + adc r3,r5 + lsl r4,r6,#16 + lsr r5,r6,#16 + add r2,r4 + adc r3,r5 + eor r6, r6 + add r2, r1 + adc r3, r6 + mov r1, r9 + mov r5, r8 + mov r8, r0 + lsr r0, r1,#16 + uxth r1,r1 + mov r4,r1 + lsr r6,r5,#16 + uxth r5,r5 + mul r1,r5 + mul r4,r6 + mul r5,r0 + mul r0,r6 + lsl r6,r4,#16 + lsr r4,#16 + add r1,r6 + adc r0,r4 + lsl r6,r5,#16 + lsr r5,#16 + add r1,r6 + adc r0,r5 + eor r1,r7 + eor r0,r7 + eor r4, r4 + asr r7, r7, #1 + adc r1, r2 + adc r2, r0 + adc r7, r4 + mov r0, r8 + add r1, r0 + adc r2, r3 + adc r3, r7 + push {r0,r1} + mov r1, r10 + mov r10, r2 + ldm r1, {r0, r1, r4, r5} + mov r2, r4 + mov r7, r5 + sub r2, r0 + sbc r7, r1 + sbc r6, r6 + eor r2, r6 + eor r7, r6 + sub r2, r6 + sbc r7, r6 + push {r2, r7} + mov r2, r11 + mov r11, r3 + ldm r2, {r0, r1, r2, r3} + sub r0, r2 + sbc r1, r3 + sbc r7, r7 + eor r0, r7 + eor r1, r7 + sub r0, r7 + sbc r1, r7 + eor r7, r6 + mov r12, r7 + push {r0, r1} + //MUL64 + mov r6, r5 + mov r1, r2 + sub r5, r4 + sbc r0, r0 + eor r5, r0 + sub r5, r0 + sub r1, r3 + sbc r7, r7 + eor r1, r7 + sub r1, r7 + eor r7, r0 + mov r9, r1 + mov r8, r5 + lsr r1,r4,#16 + uxth r4,r4 + mov r0,r4 + uxth r5,r2 + lsr r2,#16 + mul r0,r5//00 + mul r5,r1//10 + mul r4,r2//01 + mul r1,r2//11 + lsl r2,r4,#16 + lsr r4,r4,#16 + add r0,r2 + adc r1,r4 + lsl r2,r5,#16 + lsr r4,r5,#16 + add r0,r2 + adc r1,r4 + lsr r4, r6,#16 + uxth r6, r6 + uxth r5, r3 + lsr r3, r3, #16 + mov r2, r6 + mul r2, r5 + mul r5, r4 + mul r6, r3 + mul r3, r4 + lsl r4,r5,#16 + lsr r5,r5,#16 + add r2,r4 + adc r3,r5 + lsl r4,r6,#16 + lsr r5,r6,#16 + add r2,r4 + adc r3,r5 + eor r6, r6 + add r2, r1 + adc r3, r6 + mov r1, r9 + mov r5, r8 + mov r8, r0 + lsr r0, r1,#16 + uxth r1,r1 + mov r4,r1 + lsr r6,r5,#16 + uxth r5,r5 + mul r1,r5 + mul r4,r6 + mul r5,r0 + mul r0,r6 + lsl r6,r4,#16 + lsr r4,#16 + add r1,r6 + adc r0,r4 + lsl r6,r5,#16 + lsr r5,#16 + add r1,r6 + adc r0,r5 + eor r1,r7 + eor r0,r7 + eor r4, r4 + asr r7, r7, #1 + adc r1, r2 + adc r2, r0 + adc r7, r4 + mov r0, r8 + add r1, r0 + adc r2, r3 + adc r3, r7 + mov r4, r10 + mov r5, r11 + eor r6, r6 + add r0, r4 + adc r1, r5 + adc r2, r6 + adc r3, r6 + mov r10, r2 + mov r11, r3 + pop {r2-r5} + push {r0, r1} + mov r6, r5 + mov r1, r2 + sub r5, r4 + sbc r0, r0 + eor r5, r0 + sub r5, r0 + sub r1, r3 + sbc r7, r7 + eor r1, r7 + sub r1, r7 + eor r7, r0 + mov r9, r1 + mov r8, r5 + lsr r1,r4,#16 + uxth r4,r4 + mov r0,r4 + uxth r5,r2 + lsr r2,#16 + mul r0,r5//00 + mul r5,r1//10 + mul r4,r2//01 + mul r1,r2//11 + lsl r2,r4,#16 + lsr r4,r4,#16 + add r0,r2 + adc r1,r4 + lsl r2,r5,#16 + lsr r4,r5,#16 + add r0,r2 + adc r1,r4 + lsr r4, r6,#16 + uxth r6, r6 + uxth r5, r3 + lsr r3, r3, #16 + mov r2, r6 + mul r2, r5 + mul r5, r4 + mul r6, r3 + mul r3, r4 + lsl r4,r5,#16 + lsr r5,r5,#16 + add r2,r4 + adc r3,r5 + lsl r4,r6,#16 + lsr r5,r6,#16 + add r2,r4 + adc r3,r5 + eor r6, r6 + add r2, r1 + adc r3, r6 + mov r1, r9 + mov r5, r8 + mov r8, r0 + lsr r0, r1,#16 + uxth r1,r1 + mov r4,r1 + lsr r6,r5,#16 + uxth r5,r5 + mul r1,r5 + mul r4,r6 + mul r5,r0 + mul r0,r6 + lsl r6,r4,#16 + lsr r4,#16 + add r1,r6 + adc r0,r4 + lsl r6,r5,#16 + lsr r5,#16 + add r1,r6 + adc r0,r5 + eor r1,r7 + eor r0,r7 + eor r4, r4 + asr r7, r7, #1 + adc r1, r2 + adc r2, r0 + adc r7, r4 + mov r0, r8 + add r1, r0 + adc r2, r3 + adc r3, r7 + pop {r4, r5} + mov r6, r12 + mov r7, r12 + eor r0, r6 + eor r1, r6 + eor r2, r6 + eor r3, r6 + asr r6, r6, #1 + adc r0, r4 + adc r1, r5 + adc r4, r2 + adc r5, r3 + eor r2, r2 + adc r6,r2 //0,1 + adc r7,r2 + pop {r2, r3} + mov r8, r2 + mov r9, r3 + add r2, r0 + adc r3, r1 + mov r0, r10 + mov r1, r11 + adc r4, r0 + adc r5, r1 + adc r6, r0 + adc r7, r1 + ////////END HIGH PART///////////////////// + mov r0, r8 + mov r1, r9 + mov r8, r6 + mov r9, r7 + pop {r6, r7} + add r0, r6 + adc r1, r7 + pop {r6, r7} + adc r2, r6 + adc r3, r7 + pop {r7} + stm r7!, {r0-r3} + mov r10, r7 + eor r0,r0 + mov r6, r8 + mov r7, r9 + adc r4, r0 + adc r5, r0 + adc r6, r0 + adc r7, r0 + pop {r0,r1,r2} + mov r12, r2 + push {r0, r4-r7} + ldm r1, {r0-r7} + sub r0, r4 + sbc r1, r5 + sbc r2, r6 + sbc r3, r7 + eor r4, r4 + sbc r4, r4 + eor r0, r4 + eor r1, r4 + eor r2, r4 + eor r3, r4 + sub r0, r4 + sbc r1, r4 + sbc r2, r4 + sbc r3, r4 + mov r6, r12 + mov r12, r4 //carry + mov r5, r10 + stm r5!, {r0-r3} + mov r11, r5 + mov r8, r0 + mov r9, r1 + ldm r6, {r0-r7} + sub r4, r0 + sbc r5, r1 + sbc r6, r2 + sbc r7, r3 + eor r0, r0 + sbc r0, r0 + eor r4, r0 + eor r5, r0 + eor r6, r0 + eor r7, r0 + sub r4, r0 + sbc r5, r0 + sbc r6, r0 + sbc r7, r0 + mov r1, r12 + eor r0, r1 + mov r1, r11 + stm r1!, {r4-r7} + push {r0} + mov r2, r8 + mov r3, r9 + /////////BEGIN MIDDLE PART//////////////// + /////////MUL128///////////// + //MUL64 + mov r6, r5 + mov r1, r2 + sub r5, r4 + sbc r0, r0 + eor r5, r0 + sub r5, r0 + sub r1, r3 + sbc r7, r7 + eor r1, r7 + sub r1, r7 + eor r7, r0 + mov r9, r1 + mov r8, r5 + lsr r1,r4,#16 + uxth r4,r4 + mov r0,r4 + uxth r5,r2 + lsr r2,#16 + mul r0,r5//00 + mul r5,r1//10 + mul r4,r2//01 + mul r1,r2//11 + lsl r2,r4,#16 + lsr r4,r4,#16 + add r0,r2 + adc r1,r4 + lsl r2,r5,#16 + lsr r4,r5,#16 + add r0,r2 + adc r1,r4 + lsr r4, r6,#16 + uxth r6, r6 + uxth r5, r3 + lsr r3, r3, #16 + mov r2, r6 + mul r2, r5 + mul r5, r4 + mul r6, r3 + mul r3, r4 + lsl r4,r5,#16 + lsr r5,r5,#16 + add r2,r4 + adc r3,r5 + lsl r4,r6,#16 + lsr r5,r6,#16 + add r2,r4 + adc r3,r5 + eor r6, r6 + add r2, r1 + adc r3, r6 + mov r1, r9 + mov r5, r8 + mov r8, r0 + lsr r0, r1,#16 + uxth r1,r1 + mov r4,r1 + lsr r6,r5,#16 + uxth r5,r5 + mul r1,r5 + mul r4,r6 + mul r5,r0 + mul r0,r6 + lsl r6,r4,#16 + lsr r4,#16 + add r1,r6 + adc r0,r4 + lsl r6,r5,#16 + lsr r5,#16 + add r1,r6 + adc r0,r5 + eor r1,r7 + eor r0,r7 + eor r4, r4 + asr r7, r7, #1 + adc r1, r2 + adc r2, r0 + adc r7, r4 + mov r0, r8 + add r1, r0 + adc r2, r3 + adc r3, r7 + push {r0,r1} + mov r1, r10 + mov r10, r2 + ldm r1, {r0, r1, r4, r5} + mov r2, r4 + mov r7, r5 + sub r2, r0 + sbc r7, r1 + sbc r6, r6 + eor r2, r6 + eor r7, r6 + sub r2, r6 + sbc r7, r6 + push {r2, r7} + mov r2, r11 + mov r11, r3 + ldm r2, {r0, r1, r2, r3} + sub r0, r2 + sbc r1, r3 + sbc r7, r7 + eor r0, r7 + eor r1, r7 + sub r0, r7 + sbc r1, r7 + eor r7, r6 + mov r12, r7 + push {r0, r1} + //MUL64 + mov r6, r5 + mov r1, r2 + sub r5, r4 + sbc r0, r0 + eor r5, r0 + sub r5, r0 + sub r1, r3 + sbc r7, r7 + eor r1, r7 + sub r1, r7 + eor r7, r0 + mov r9, r1 + mov r8, r5 + lsr r1,r4,#16 + uxth r4,r4 + mov r0,r4 + uxth r5,r2 + lsr r2,#16 + mul r0,r5//00 + mul r5,r1//10 + mul r4,r2//01 + mul r1,r2//11 + lsl r2,r4,#16 + lsr r4,r4,#16 + add r0,r2 + adc r1,r4 + lsl r2,r5,#16 + lsr r4,r5,#16 + add r0,r2 + adc r1,r4 + lsr r4, r6,#16 + uxth r6, r6 + uxth r5, r3 + lsr r3, r3, #16 + mov r2, r6 + mul r2, r5 + mul r5, r4 + mul r6, r3 + mul r3, r4 + lsl r4,r5,#16 + lsr r5,r5,#16 + add r2,r4 + adc r3,r5 + lsl r4,r6,#16 + lsr r5,r6,#16 + add r2,r4 + adc r3,r5 + eor r6, r6 + add r2, r1 + adc r3, r6 + mov r1, r9 + mov r5, r8 + mov r8, r0 + lsr r0, r1,#16 + uxth r1,r1 + mov r4,r1 + lsr r6,r5,#16 + uxth r5,r5 + mul r1,r5 + mul r4,r6 + mul r5,r0 + mul r0,r6 + lsl r6,r4,#16 + lsr r4,#16 + add r1,r6 + adc r0,r4 + lsl r6,r5,#16 + lsr r5,#16 + add r1,r6 + adc r0,r5 + eor r1,r7 + eor r0,r7 + eor r4, r4 + asr r7, r7, #1 + adc r1, r2 + adc r2, r0 + adc r7, r4 + mov r0, r8 + add r1, r0 + adc r2, r3 + adc r3, r7 + mov r4, r10 + mov r5, r11 + eor r6, r6 + add r0, r4 + adc r1, r5 + adc r2, r6 + adc r3, r6 + mov r10, r2 + mov r11, r3 + pop {r2-r5} + push {r0, r1} + mov r6, r5 + mov r1, r2 + sub r5, r4 + sbc r0, r0 + eor r5, r0 + sub r5, r0 + sub r1, r3 + sbc r7, r7 + eor r1, r7 + sub r1, r7 + eor r7, r0 + mov r9, r1 + mov r8, r5 + lsr r1,r4,#16 + uxth r4,r4 + mov r0,r4 + uxth r5,r2 + lsr r2,#16 + mul r0,r5//00 + mul r5,r1//10 + mul r4,r2//01 + mul r1,r2//11 + lsl r2,r4,#16 + lsr r4,r4,#16 + add r0,r2 + adc r1,r4 + lsl r2,r5,#16 + lsr r4,r5,#16 + add r0,r2 + adc r1,r4 + lsr r4, r6,#16 + uxth r6, r6 + uxth r5, r3 + lsr r3, r3, #16 + mov r2, r6 + mul r2, r5 + mul r5, r4 + mul r6, r3 + mul r3, r4 + lsl r4,r5,#16 + lsr r5,r5,#16 + add r2,r4 + adc r3,r5 + lsl r4,r6,#16 + lsr r5,r6,#16 + add r2,r4 + adc r3,r5 + eor r6, r6 + add r2, r1 + adc r3, r6 + mov r1, r9 + mov r5, r8 + mov r8, r0 + lsr r0, r1,#16 + uxth r1,r1 + mov r4,r1 + lsr r6,r5,#16 + uxth r5,r5 + mul r1,r5 + mul r4,r6 + mul r5,r0 + mul r0,r6 + lsl r6,r4,#16 + lsr r4,#16 + add r1,r6 + adc r0,r4 + lsl r6,r5,#16 + lsr r5,#16 + add r1,r6 + adc r0,r5 + eor r1,r7 + eor r0,r7 + eor r4, r4 + asr r7, r7, #1 + adc r1, r2 + adc r2, r0 + adc r7, r4 + mov r0, r8 + add r1, r0 + adc r2, r3 + adc r3, r7 + pop {r4, r5} + mov r6, r12 + mov r7, r12 + eor r0, r6 + eor r1, r6 + eor r2, r6 + eor r3, r6 + asr r6, r6, #1 + adc r0, r4 + adc r1, r5 + adc r4, r2 + adc r5, r3 + eor r2, r2 + adc r6,r2 //0,1 + adc r7,r2 + pop {r2, r3} + mov r8, r2 + mov r9, r3 + add r2, r0 + adc r3, r1 + mov r0, r10 + mov r1, r11 + adc r4, r0 + adc r5, r1 + adc r6, r0 + adc r7, r1 + //////////END MIDDLE PART//////////////// + pop {r0,r1} //r0,r1 + mov r12, r0 //negative + eor r2, r0 + eor r3, r0 + eor r4, r0 + eor r5, r0 + eor r6, r0 + eor r7, r0 + push {r4-r7} + ldm r1!, {r4-r7} + mov r11, r1 //reference + mov r1, r9 + eor r1, r0 + mov r10, r4 + mov r4, r8 + asr r0, #1 + eor r0, r4 + mov r4, r10 + adc r0, r4 + adc r1, r5 + adc r2, r6 + adc r3, r7 + eor r4, r4 + adc r4, r4 + mov r10, r4 //carry + mov r4, r11 + ldm r4, {r4-r7} + add r0, r4 + adc r1, r5 + adc r2, r6 + adc r3, r7 + mov r9, r4 + mov r4, r11 + stm r4!, {r0-r3} + mov r11, r4 + pop {r0-r3} + mov r4, r9 + adc r4, r0 + adc r5, r1 + adc r6, r2 + adc r7, r3 + mov r1, #0 + adc r1, r1 + mov r0, r10 + mov r10, r1 //carry + asr r0, #1 + pop {r0-r3} + adc r4, r0 + adc r5, r1 + adc r6, r2 + adc r7, r3 + mov r8, r0 + mov r0, r11 + stm r0!, {r4-r7} + mov r11, r0 + mov r0, r8 + mov r6, r12 + mov r5, r10 + eor r4, r4 + adc r5, r6 + adc r6, r4 + add r0, r5 + adc r1, r6 + adc r2, r6 + adc r3, r6 + mov r7, r11 + stm r7!, {r0-r3} + pop {r3-r6} + mov r8, r3 + mov r9, r4 + mov r10, r5 + mov r11, r6 + pop {r4-r7,pc} + bx lr +.size multiply256x256_asm, .-multiply256x256_asm + diff --git a/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/arm/unacl/scalarmult.c b/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/arm/unacl/scalarmult.c new file mode 100644 index 00000000..488aac78 --- /dev/null +++ b/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/arm/unacl/scalarmult.c @@ -0,0 +1,761 @@ +/* ======================= + ============================ C/C++ HEADER FILE ============================= + ======================= + + Collection of all required submodules from naclM0 required for curve25519 + scalar multiplication (not including randomization, etc.) alone. + + Library naclM0 largely bases on work avrNacl of M. Hutter and P. Schwabe. + + Will compile to the two functions + + int + crypto_scalarmult_base_curve25519( + unsigned char* q, + const unsigned char* n + ); + + int + crypto_scalarmult_curve25519 ( + unsigned char* r, + const unsigned char* s, + const unsigned char* p + ); + + Requires inttypes.h header and the four external assembly functions + + extern void + fe25519_reduceTo256Bits_asm ( + fe25519 *res, + const UN_512bitValue *in + ); + + extern void + fe25519_mpyWith121666_asm ( + fe25519* out, + const fe25519* in + ); + + extern void + multiply256x256_asm ( + UN_512bitValue* result, + const UN_256bitValue* x, + const UN_256bitValue* y + ); + + extern void + square256_asm ( + UN_512bitValue* result, + const UN_256bitValue* x + ); + + \file scalarmult.c + + \Author B. Haase, Endress + Hauser Conducta GmbH & Co. KG + + License: CC Common Creative license Attribution 4.0 International (CC BY 4.0) + http://creativecommons.org/licenses/by/4.0/ + ============================================================================*/ + +#include + +// comment out this line if implementing conditional swaps by data moves +//#define DH_SWAP_BY_POINTERS + +// Define the symbol to 0 in order to only use ladder steps +//#define DH_REPLACE_LAST_THREE_LADDERSTEPS_WITH_DOUBLINGS 1 + +typedef uint8_t uint8; +typedef uint16_t uint16; +typedef uint32_t uint32; +typedef uint64_t uint64; +typedef uintptr_t uintptr; + +typedef int8_t int8; +typedef int16_t int16; +typedef int32_t int32; +typedef int64_t int64; +typedef intptr_t intptr; + +// Note that it's important to define the unit8 as first union member, so that +// an array of uint8 may be used as initializer. +typedef union UN_256bitValue_ +{ + uint8 as_uint8[32]; + uint16 as_uint16[16]; + uint32 as_uint32[8]; + uint64 as_uint64[4]; +} UN_256bitValue; + +// Note that it's important to define the unit8 as first union member, so that +// an array of uint8 may be used as initializer. +typedef union UN_512bitValue_ +{ + uint8 as_uint8[64]; + uint16 as_uint16[32]; + uint32 as_uint32[16]; + uint64 as_uint64[8]; + UN_256bitValue as_256_bitValue[2]; +} UN_512bitValue; + +typedef UN_256bitValue fe25519; + +// **************************************************** +// Assembly functions. +// **************************************************** + +extern void +fe25519_reduceTo256Bits_asm( + fe25519 *res, + const UN_512bitValue *in +); + +#define fe25519_mpyWith121666 fe25519_mpyWith121666_asm +extern void +fe25519_mpyWith121666_asm ( + fe25519* out, + const fe25519* in +); + +#define multiply256x256 multiply256x256_asm +extern void +multiply256x256( + UN_512bitValue* result, + const UN_256bitValue* x, + const UN_256bitValue* y +); + +#define square256 square256_asm +extern void +square256( + UN_512bitValue* result, + const UN_256bitValue* x +); + +// **************************************************** +// C functions for fe25519 +// **************************************************** + +static void +fe25519_cpy( + fe25519* dest, + const fe25519* source +) +{ + uint32 ctr; + + for (ctr = 0; ctr < 8; ctr++) + { + dest->as_uint32[ctr] = source->as_uint32[ctr]; + } +} + +static void +fe25519_unpack( + volatile fe25519* out, + const unsigned char in[32] +) +{ + uint8 ctr; + + for (ctr = 0; ctr < 32; ctr++) + { + out->as_uint8[ctr] = in[ctr]; + } + out->as_uint8[31] &= 0x7f; // make sure that the last bit is cleared. +} + +static void +fe25519_sub( + fe25519* out, + const fe25519* baseValue, + const fe25519* valueToSubstract +) +{ + uint16 ctr; + int64 accu = 0; + + // First subtract the most significant word, so that we may + // reduce the result "on the fly". + accu = baseValue->as_uint32[7]; + accu -= valueToSubstract->as_uint32[7]; + + // We always set bit #31, and compensate this by subtracting 1 from the reduction + // value. + out->as_uint32[7] = ((uint32)accu) | 0x80000000ul; + + accu = 19 * ((int32)(accu >> 31) - 1); + // ^ "-1" is the compensation for the "| 0x80000000ul" above. + // This choice makes sure, that the result will be positive! + + for (ctr = 0; ctr < 7; ctr += 1) + { + accu += baseValue->as_uint32[ctr]; + accu -= valueToSubstract->as_uint32[ctr]; + + out->as_uint32[ctr] = (uint32)accu; + accu >>= 32; + } + accu += out->as_uint32[7]; + out->as_uint32[7] = (uint32)accu; +} + +static void +fe25519_add( + fe25519* out, + const fe25519* baseValue, + const fe25519* valueToAdd +) +{ + uint16 ctr = 0; + uint64 accu = 0; + + // We first add the most significant word, so that we may reduce + // "on the fly". + accu = baseValue->as_uint32[7]; + accu += valueToAdd->as_uint32[7]; + out->as_uint32[7] = ((uint32)accu) & 0x7ffffffful; + + accu = ((uint32)(accu >> 31)) * 19; + + for (ctr = 0; ctr < 7; ctr += 1) + { + accu += baseValue->as_uint32[ctr]; + accu += valueToAdd->as_uint32[ctr]; + + out->as_uint32[ctr] = (uint32)accu; + accu >>= 32; + } + accu += out->as_uint32[7]; + out->as_uint32[7] = (uint32)accu; +} + +static void +fe25519_mul( + fe25519* result, + const fe25519* in1, + const fe25519* in2 +) +{ + UN_512bitValue tmp; + + multiply256x256(&tmp, in1, in2); + fe25519_reduceTo256Bits_asm(result,&tmp); +} + +static void +fe25519_square( + fe25519* result, + const fe25519* in +) +{ + UN_512bitValue tmp; + + square256(&tmp, in); + fe25519_reduceTo256Bits_asm(result,&tmp); +} + +static void +fe25519_reduceCompletely( + volatile fe25519* inout +) +{ + uint32 numberOfTimesToSubstractPrime; + uint32 initialGuessForNumberOfTimesToSubstractPrime = inout->as_uint32[7] >> + 31; + uint64 accu; + uint8 ctr; + + // add one additional 19 to the estimated number of reductions. + // Do the calculation without writing back the results to memory. + // + // The initial guess of required numbers of reductions is based + // on bit #32 of the most significant word. + // This initial guess may be wrong, since we might have a value + // v in the range + // 2^255 - 19 <= v < 2^255 + // . After adding 19 to the value, we will be having the correct + // Number of required subtractions. + accu = initialGuessForNumberOfTimesToSubstractPrime * 19 + 19; + + for (ctr = 0; ctr < 7; ctr++) + { + accu += inout->as_uint32[ctr]; + accu >>= 32; + } + accu += inout->as_uint32[7]; + + numberOfTimesToSubstractPrime = (uint32)(accu >> 31); + + // Do the reduction. + accu = numberOfTimesToSubstractPrime * 19; + + for (ctr = 0; ctr < 7; ctr++) + { + accu += inout->as_uint32[ctr]; + inout->as_uint32[ctr] = (uint32)accu; + accu >>= 32; + } + accu += inout->as_uint32[7]; + inout->as_uint32[7] = accu & 0x7ffffffful; +} + +/// We are already using a packed radix 16 representation for fe25519. The real use for this function +/// is for architectures that use more bits for storing a fe25519 in a representation where multiplication +/// may be calculated more efficiently. +/// Here we simply copy the data. +static void +fe25519_pack( + unsigned char out[32], + volatile fe25519* in +) +{ + uint8 ctr; + + fe25519_reduceCompletely(in); + + for (ctr = 0; ctr < 32; ctr++) + { + out[ctr] = in->as_uint8[ctr]; + } +} + +// Note, that r and x are allowed to overlap! +static void +fe25519_invert_useProvidedScratchBuffers( + fe25519* r, + const fe25519* x, + fe25519* t0, + fe25519* t1, + fe25519* t2 +) +{ + fe25519 *z11 = r; // store z11 in r (in order to save one temporary). + fe25519 *z2_10_0 = t1; + fe25519 *z2_50_0 = t2; + fe25519 *z2_100_0 = z2_10_0; + + uint8 i; + + { + fe25519 *z2 = z2_50_0; + + /* 2 */ fe25519_square(z2, x); + /* 4 */ fe25519_square(t0, z2); + /* 8 */ fe25519_square(t0, t0); + /* 9 */ fe25519_mul(z2_10_0, t0, x); + /* 11 */ fe25519_mul(z11, z2_10_0, z2); + + // z2 is dead. + } + + /* 22 */ fe25519_square(t0, z11); + /* 2^5 - 2^0 = 31 */ fe25519_mul(z2_10_0, t0, z2_10_0); + + /* 2^6 - 2^1 */ fe25519_square(t0, z2_10_0); + /* 2^7 - 2^2 */ fe25519_square(t0, t0); + /* 2^8 - 2^3 */ fe25519_square(t0, t0); + /* 2^9 - 2^4 */ fe25519_square(t0, t0); + /* 2^10 - 2^5 */ fe25519_square(t0, t0); + /* 2^10 - 2^0 */ fe25519_mul(z2_10_0, t0, z2_10_0); + + /* 2^11 - 2^1 */ fe25519_square(t0, z2_10_0); + + /* 2^20 - 2^10 */ for (i = 1; i < 10; i ++) + { + fe25519_square(t0, t0); + } + /* 2^20 - 2^0 */ fe25519_mul(z2_50_0, t0, z2_10_0); + + /* 2^21 - 2^1 */ fe25519_square(t0, z2_50_0); + + /* 2^40 - 2^20 */ for (i = 1; i < 20; i ++) + { + fe25519_square(t0, t0); + } + /* 2^40 - 2^0 */ fe25519_mul(t0, t0, z2_50_0); + + /* 2^41 - 2^1 */ fe25519_square(t0, t0); + + /* 2^50 - 2^10 */ for (i = 1; i < 10; i ++) + { + fe25519_square(t0, t0); + } + /* 2^50 - 2^0 */ fe25519_mul(z2_50_0, t0, z2_10_0); + + /* 2^51 - 2^1 */ fe25519_square(t0, z2_50_0); + + /* 2^100 - 2^50 */ for (i = 1; i < 50; i ++) + { + fe25519_square(t0, t0); + } + /* 2^100 - 2^0 */ fe25519_mul(z2_100_0, t0, z2_50_0); + + /* 2^101 - 2^1 */ fe25519_square(t0, z2_100_0); + + /* 2^200 - 2^100 */ for (i = 1; i < 100; i ++) + { + fe25519_square(t0, t0); + } + /* 2^200 - 2^0 */ fe25519_mul(t0, t0, z2_100_0); + + /* 2^250 - 2^50 */ for (i = 0; i < 50; i ++) + { + fe25519_square(t0, t0); + } + /* 2^250 - 2^0 */ fe25519_mul(t0, t0, z2_50_0); + + /* 2^255 - 2^5 */ for (i = 0; i < 5; i ++) + { + fe25519_square(t0, t0); + } + /* 2^255 - 21 */ fe25519_mul(r, t0, z11); +} + +static void +fe25519_setzero( + fe25519* out +) +{ + uint8 ctr; + + for (ctr = 0; ctr < 8; ctr++) + { + out->as_uint32[ctr] = 0; + } +} + +static void +fe25519_setone( + fe25519* out +) +{ + uint8 ctr; + + out->as_uint32[0] = 1; + + for (ctr = 1; ctr < 8; ctr++) + { + out->as_uint32[ctr] = 0; + } +} + +/* +static void +swapPointersConditionally (void **p1, void **p2, uint8 condition) +{ + // Secure version of this code: + // + // if (condition) + // { + // void *temp; + // temp = *p2; + // *p2 = *p1; + // *p1 = temp; + // } + + uintptr mask = condition; + uintptr val1 = (uintptr) *p1; + uintptr val2 = (uintptr) *p2; + uintptr temp = val2 ^ val1; + + mask = (uintptr)( - (intptr) mask ); + temp ^= mask & (temp ^ val1); + val1 ^= mask & (val1 ^ val2); + val2 ^= mask & (val2 ^ temp); + + *p1 = (void *) val1; + *p2 = (void *) val2; +} +*/ + +static void +fe25519_cswap( + fe25519* in1, + fe25519* in2, + int condition +) +{ + int32 mask = condition; + uint32 ctr; + + mask = -mask; + + for (ctr = 0; ctr < 8; ctr++) + { + uint32 val1 = in1->as_uint32[ctr]; + uint32 val2 = in2->as_uint32[ctr]; + uint32 temp = val1; + + val1 ^= mask & (val2 ^ val1); + val2 ^= mask & (val2 ^ temp); + + + in1->as_uint32[ctr] = val1; + in2->as_uint32[ctr] = val2; + } +} + +// **************************************************** +// Scalarmultiplication implementation. +// **************************************************** + +typedef struct _ST_curve25519ladderstepWorkingState +{ + // The base point in affine coordinates + fe25519 x0; + + // The two working points p, q, in projective coordinates. Possibly randomized. + fe25519 xp; + fe25519 zp; + fe25519 xq; + fe25519 zq; + + volatile UN_256bitValue s; + + int nextScalarBitToProcess; + uint8 previousProcessedBit; + +#ifdef DH_SWAP_BY_POINTERS + fe25519 *pXp; + fe25519 *pZp; + fe25519 *pXq; + fe25519 *pZq; +#endif + +} ST_curve25519ladderstepWorkingState; + +static void +curve25519_ladderstep( + ST_curve25519ladderstepWorkingState* pState +) +{ + // Implements the "ladd-1987-m-3" differential-addition-and-doubling formulas + // Source: 1987 Montgomery "Speeding the Pollard and elliptic curve methods of factorization", page 261, + // fifth and sixth displays, plus common-subexpression elimination. + // + // Notation from the explicit formulas database: + // (X2,Z2) corresponds to (xp,zp), + // (X3,Z3) corresponds to (xq,zq) + // Result (X4,Z4) (X5,Z5) expected in (xp,zp) and (xq,zq) + // + // A = X2+Z2; AA = A^2; B = X2-Z2; BB = B^2; E = AA-BB; C = X3+Z3; D = X3-Z3; + // DA = D*A; CB = C*B; t0 = DA+CB; t1 = t0^2; X5 = Z1*t1; t2 = DA-CB; + // t3 = t2^2; Z5 = X1*t3; X4 = AA*BB; t4 = a24*E; t5 = BB+t4; Z4 = E*t5 ; + // + // Re-Ordered for using less temporaries. + + fe25519 t1, t2; + + #ifdef DH_SWAP_BY_POINTERS + fe25519 *b1=pState->pXp; fe25519 *b2=pState->pZp; + fe25519 *b3=pState->pXq; fe25519 *b4=pState->pZq; + #else + fe25519 *b1=&pState->xp; fe25519 *b2=&pState->zp; + fe25519 *b3=&pState->xq; fe25519 *b4=&pState->zq; + #endif + + fe25519 *b5= &t1; fe25519 *b6=&t2; + + fe25519_add(b5,b1,b2); // A = X2+Z2 + fe25519_sub(b6,b1,b2); // B = X2-Z2 + fe25519_add(b1,b3,b4); // C = X3+Z3 + fe25519_sub(b2,b3,b4); // D = X3-Z3 + fe25519_mul(b3,b2,b5); // DA= D*A + fe25519_mul(b2,b1,b6); // CB= C*B + fe25519_add(b1,b2,b3); // T0= DA+CB + fe25519_sub(b4,b3,b2); // T2= DA-CB + fe25519_square(b3,b1); // X5==T1= T0^2 + fe25519_square(b1,b4); // T3= t2^2 + fe25519_mul(b4,b1,&pState->x0); // Z5=X1*t3 + fe25519_square(b1,b5); // AA=A^2 + fe25519_square(b5,b6); // BB=B^2 + fe25519_sub(b2,b1,b5); // E=AA-BB + fe25519_mul(b1,b5,b1); // X4= AA*BB + fe25519_mpyWith121666 (b6,b2); // T4 = a24*E + fe25519_add(b6,b6,b5); // T5 = BB + t4 + fe25519_mul(b2,b6,b2); // Z4 = E*t5 +} + +static void +curve25519_cswap( + ST_curve25519ladderstepWorkingState* state, + uint8 b +) +{ + #ifdef DH_SWAP_BY_POINTERS + swapPointersConditionally ((void **) &state->pXp,(void **) &state->pXq,b); + swapPointersConditionally ((void **) &state->pZp,(void **) &state->pZq,b); + #else + fe25519_cswap (&state->xp, &state->xq,b); + fe25519_cswap (&state->zp, &state->zq,b); + #endif +} + +#if DH_REPLACE_LAST_THREE_LADDERSTEPS_WITH_DOUBLINGS + +static void +curve25519_doublePointP (ST_curve25519ladderstepWorkingState* pState) +{ + // Implement the doubling formula "dbl-1987-m-3" + // from 1987 Montgomery "Speeding the Pollard and elliptic curve methods of factorization", + // page 261, sixth display, plus common-subexpression elimination. + // + // Three operand code: + // A = X1+Z1 + // AA = A^2 + // B = X1-Z1 + // BB = B^2 + // C = AA-BB + // X3 = AA*BB + // t0 = a24*C + // t1 = BB+t0 + // Z3 = C*t1 + + // Double the point input in the state variable "P". Use the State variable "Q" as temporary + // for storing A, AA and B, BB. Use the same temporary variable for A and AA respectively and + // B, BB respectively. + #ifdef DH_SWAP_BY_POINTERS + fe25519 *pA = pState->pXq; + fe25519 *pB = pState->pZq; + fe25519 *pX = pState->pXp; + fe25519 *pZ = pState->pZp; + #else + fe25519 *pA = &pState->xq; + fe25519 *pB = &pState->zq; + fe25519 *pX = &pState->xp; + fe25519 *pZ = &pState->zp; + #endif + + // A = X1+Z1 + fe25519_add(pA, pX, pZ); + // AA = A^2 + fe25519_square (pA,pA); + // B = X1-Z1 + fe25519_sub(pB, pX, pZ); + // BB = B^2 + fe25519_square (pB,pB); + // X3 = AA*BB + fe25519_mul (pX,pA,pB); + // C = AA-BB + fe25519_sub (pZ,pA,pB); + // t0 = a24*C + fe25519_mpyWith121666 (pA,pZ); + // t1 = BB+t0 + fe25519_add (pB,pA,pB); + // Z3 = C*t1 + fe25519_mul (pZ,pZ,pB); +} + +#endif // #ifdef DH_REPLACE_LAST_THREE_LADDERSTEPS_WITH_DOUBLINGS + +int +crypto_scalarmult_curve25519( + unsigned char* r, + const unsigned char* s, + const unsigned char* p +) +{ + ST_curve25519ladderstepWorkingState state; + unsigned char i; + + + // Prepare the scalar within the working state buffer. + for (i = 0; i < 32; i++) + { + state.s.as_uint8 [i] = s[i]; + } +#if DH_REPLACE_LAST_THREE_LADDERSTEPS_WITH_DOUBLINGS + // Due to explicit final doubling for the last three bits instead of a full ladderstep, + // the following line is no longer necessary. +#else + state.s.as_uint8 [0] &= 248; +#endif + state.s.as_uint8 [31] &= 127; + state.s.as_uint8 [31] |= 64; + + // Copy the affine x-axis of the base point to the state. + fe25519_unpack (&state.x0, p); + + // Prepare the working points within the working state struct. + + fe25519_setone (&state.zq); + fe25519_cpy (&state.xq, &state.x0); + + fe25519_setone(&state.xp); + fe25519_setzero(&state.zp); + + state.nextScalarBitToProcess = 254; + +#ifdef DH_SWAP_BY_POINTERS + // we need to initially assign the pointers correctly. + state.pXp = &state.xp; + state.pZp = &state.zp; + state.pXq = &state.xq; + state.pZq = &state.zq; +#endif + + state.previousProcessedBit = 0; + +#if DH_REPLACE_LAST_THREE_LADDERSTEPS_WITH_DOUBLINGS + // Process all the bits except for the last three where we explicitly double the result. + while (state.nextScalarBitToProcess >= 3) +#else + // Process all the bits except for the last three where we explicitly double the result. + while (state.nextScalarBitToProcess >= 0) +#endif + { + uint8 byteNo = state.nextScalarBitToProcess >> 3; + uint8 bitNo = state.nextScalarBitToProcess & 7; + uint8 bit; + uint8 swap; + + bit = 1 & (state.s.as_uint8 [byteNo] >> bitNo); + swap = bit ^ state.previousProcessedBit; + state.previousProcessedBit = bit; + curve25519_cswap(&state, swap); + curve25519_ladderstep(&state); + state.nextScalarBitToProcess --; + } + + curve25519_cswap(&state,state.previousProcessedBit); + +#if DH_REPLACE_LAST_THREE_LADDERSTEPS_WITH_DOUBLINGS + curve25519_doublePointP (&state); + curve25519_doublePointP (&state); + curve25519_doublePointP (&state); +#endif + +#ifdef DH_SWAP_BY_POINTERS + // optimize for stack usage. + fe25519_invert_useProvidedScratchBuffers (state.pZp, state.pZp, state.pXq,state.pZq,&state.x0); + fe25519_mul(state.pXp, state.pXp, state.pZp); + fe25519_reduceCompletely(state.pXp); + + fe25519_pack (r, state.pXp); +#else + // optimize for stack usage. + fe25519_invert_useProvidedScratchBuffers (&state.zp, &state.zp, &state.xq, &state.zq, &state.x0); + fe25519_mul(&state.xp, &state.xp, &state.zp); + fe25519_reduceCompletely(&state.xp); + + fe25519_pack (r, &state.xp); +#endif + + return 0; +} + +int +crypto_scalarmult_curve25519_base( + unsigned char* q, + const unsigned char* n +) +{ + static const uint8 base[32] = + { + 9, 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, 0, 0, 0, 0, 0 + }; + + return crypto_scalarmult_curve25519(q, n, base); +} diff --git a/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/arm/unacl/sqr.s b/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/arm/unacl/sqr.s new file mode 100644 index 00000000..3b190c92 --- /dev/null +++ b/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/arm/unacl/sqr.s @@ -0,0 +1,777 @@ + .align 2 + .global square256_asm + .type square256_asm, %function +square256_asm: + push {r4-r7,lr} + mov r2, r8 + mov r3, r9 + mov r4, r10 + mov r5, r11 + push {r0-r5} + + mov r12, r0 + mov r4, r1 + ldm r4!, {r0-r3} + push {r4} + /////////BEGIN LOW PART ////////////////////// + ///SQR 128, in r0-r3 + mov r8, r2 + mov r9, r3 + eor r4, r4 + sub r2, r0 + sbc r3, r1 + sbc r4, r4 + eor r2, r4 + eor r3, r4 + sub r2, r4 + sbc r3, r4 + mov r10, r2 + mov r11, r3 + //SQR64, in: r0, r1, out: r0-r3, used: r0-r6 + mov r2, r0 + eor r3, r3 + sub r2, r1 + sbc r3, r3 + eor r2, r3 + sub r2, r3 + lsr r3, r0, #16 + uxth r0, r0 + mov r4, r0 + mul r4, r3 + mul r0, r0 + mul r3, r3 + lsr r5, r4, #16 + lsl r4, #16 + add r0, r4 + adc r3, r5 + add r0, r4 + adc r3, r5 + lsr r4, r1, #16 + uxth r1, r1 + mov r5, r1 + mul r5, r4 + mul r1, r1 + mul r4, r4 + eor r6, r6 + add r1, r3 + adc r4, r6 + lsr r3, r5, #16 + lsl r5, r5, #16 + add r1, r5 + adc r4, r3 + add r1, r5 + adc r3, r4 + lsr r4, r2, #16 + uxth r2, r2 + mov r5, r2 + mul r5, r4 + mul r2, r2 + mul r4, r4 + lsr r6, r5, #16 + lsl r5, #16 + add r2, r5 + adc r4, r6 + add r5, r2 + adc r6, r4 + eor r7, r7 + mov r2, r1 + sub r1, r5 + sbc r2, r6 + sbc r7, r7 + add r1, r0 + adc r2, r3 + adc r7, r3 + mov r3, r12 + stm r3!, {r0-r1} + push {r3} + + mov r12, r0 + mov r0, r8 + mov r8, r1 + mov r1, r9 + mov r9, r2 + //SQR64, in: r0, r1, out: r0-r3, used: r0-r6 + mov r2, r0 + eor r3, r3 + sub r2, r1 + sbc r3, r3 + eor r2, r3 + sub r2, r3 + lsr r3, r0, #16 + uxth r0, r0 + mov r4, r0 + mul r4, r3 + mul r0, r0 + mul r3, r3 + lsr r5, r4, #16 + lsl r4, #16 + add r0, r4 + adc r3, r5 + add r0, r4 + adc r3, r5 + lsr r4, r1, #16 + uxth r1, r1 + mov r5, r1 + mul r5, r4 + mul r1, r1 + mul r4, r4 + eor r6, r6 + add r1, r3 + adc r4, r6 + lsr r3, r5, #16 + lsl r5, r5, #16 + add r1, r5 + adc r4, r3 + add r1, r5 + adc r3, r4 + lsr r4, r2, #16 + uxth r2, r2 + mov r5, r2 + mul r5, r4 + mul r2, r2 + mul r4, r4 + lsr r6, r5, #16 + lsl r5, #16 + add r2, r5 + adc r4, r6 + add r5, r2 + adc r6, r4 + eor r4, r4 + mov r2, r1 + sub r1, r5 + sbc r2, r6 + sbc r4, r4 + add r1, r0 + adc r2, r3 + adc r3, r4 + eor r4, r4 + mov r6, r9 + add r0, r6 + adc r7, r1 + adc r2, r4 + adc r3, r4 + mov r1, r11 + mov r11, r0 + mov r0, r10 + mov r9, r2 + mov r10,r3 + //SQR64, in: r0, r1, out: r0-r3, used: r0-r6 + mov r2, r0 + eor r3, r3 + sub r2, r1 + sbc r3, r3 + eor r2, r3 + sub r2, r3 + lsr r3, r0, #16 + uxth r0, r0 + mov r4, r0 + mul r4, r3 + mul r0, r0 + mul r3, r3 + lsr r5, r4, #16 + lsl r4, #16 + add r0, r4 + adc r3, r5 + add r0, r4 + adc r3, r5 + lsr r4, r1, #16 + uxth r1, r1 + mov r5, r1 + mul r5, r4 + mul r1, r1 + mul r4, r4 + eor r6, r6 + add r1, r3 + adc r4, r6 + lsr r3, r5, #16 + lsl r5, r5, #16 + add r1, r5 + adc r4, r3 + add r1, r5 + adc r3, r4 + lsr r4, r2, #16 + uxth r2, r2 + mov r5, r2 + mul r5, r4 + mul r2, r2 + mul r4, r4 + lsr r6, r5, #16 + lsl r5, #16 + add r2, r5 + adc r4, r6 + add r5, r2 + adc r6, r4 + eor r4, r4 + mov r2, r1 + sub r1, r5 + sbc r2, r6 + sbc r4, r4 + add r1, r0 + adc r2, r3 + adc r3, r4 + mov r6, r11 + mov r4, r11 + mov r5, r7 + sub r6, r0 + sbc r7, r1 + sbc r4, r2 + sbc r5, r3 + eor r1, r1 + sbc r1, r1 + mov r2, r12 + mov r3, r8 + add r2, r6 + adc r3, r7 + mov r6, r9 + mov r7, r10 + adc r4, r6 + adc r5, r7 + adc r6, r1 + adc r7, r1 + //results r12, r8, r2-r7 + /////////END LOW PART //////////////////////// + pop {r0,r1} + stm r0!, {r2, r3} + push {r0, r4-r7} + ldm r1, {r0-r3} + /////////BEGIN HIGH PART ////////////////////// + ///SQR 128, in r0-r3 + mov r8, r2 + mov r9, r3 + eor r4, r4 + sub r2, r0 + sbc r3, r1 + sbc r4, r4 + eor r2, r4 + eor r3, r4 + sub r2, r4 + sbc r3, r4 + mov r10, r2 + mov r11, r3 + //SQR64, in: r0, r1, out: r0-r3, used: r0-r6 + mov r2, r0 + eor r3, r3 + sub r2, r1 + sbc r3, r3 + eor r2, r3 + sub r2, r3 + lsr r3, r0, #16 + uxth r0, r0 + mov r4, r0 + mul r4, r3 + mul r0, r0 + mul r3, r3 + lsr r5, r4, #16 + lsl r4, #16 + add r0, r4 + adc r3, r5 + add r0, r4 + adc r3, r5 + lsr r4, r1, #16 + uxth r1, r1 + mov r5, r1 + mul r5, r4 + mul r1, r1 + mul r4, r4 + eor r6, r6 + add r1, r3 + adc r4, r6 + lsr r3, r5, #16 + lsl r5, r5, #16 + add r1, r5 + adc r4, r3 + add r1, r5 + adc r3, r4 + lsr r4, r2, #16 + uxth r2, r2 + mov r5, r2 + mul r5, r4 + mul r2, r2 + mul r4, r4 + lsr r6, r5, #16 + lsl r5, #16 + add r2, r5 + adc r4, r6 + add r5, r2 + adc r6, r4 + eor r7, r7 + mov r2, r1 + sub r1, r5 + sbc r2, r6 + sbc r7, r7 + add r1, r0 + adc r2, r3 + adc r7, r3 + mov r12, r0 + mov r0, r8 + mov r8, r1 + mov r1, r9 + mov r9, r2 + //SQR64, in: r0, r1, out: r0-r3, used: r0-r6 + mov r2, r0 + eor r3, r3 + sub r2, r1 + sbc r3, r3 + eor r2, r3 + sub r2, r3 + lsr r3, r0, #16 + uxth r0, r0 + mov r4, r0 + mul r4, r3 + mul r0, r0 + mul r3, r3 + lsr r5, r4, #16 + lsl r4, #16 + add r0, r4 + adc r3, r5 + add r0, r4 + adc r3, r5 + lsr r4, r1, #16 + uxth r1, r1 + mov r5, r1 + mul r5, r4 + mul r1, r1 + mul r4, r4 + eor r6, r6 + add r1, r3 + adc r4, r6 + lsr r3, r5, #16 + lsl r5, r5, #16 + add r1, r5 + adc r4, r3 + add r1, r5 + adc r3, r4 + lsr r4, r2, #16 + uxth r2, r2 + mov r5, r2 + mul r5, r4 + mul r2, r2 + mul r4, r4 + lsr r6, r5, #16 + lsl r5, #16 + add r2, r5 + adc r4, r6 + add r5, r2 + adc r6, r4 + eor r4, r4 + mov r2, r1 + sub r1, r5 + sbc r2, r6 + sbc r4, r4 + add r1, r0 + adc r2, r3 + adc r3, r4 + eor r4, r4 + mov r6, r9 + add r0, r6 + adc r7, r1 + adc r2, r4 + adc r3, r4 + mov r1, r11 + mov r11, r0 + mov r0, r10 + mov r9, r2 + mov r10,r3 + //SQR64, in: r0, r1, out: r0-r3, used: r0-r6 + mov r2, r0 + eor r3, r3 + sub r2, r1 + sbc r3, r3 + eor r2, r3 + sub r2, r3 + lsr r3, r0, #16 + uxth r0, r0 + mov r4, r0 + mul r4, r3 + mul r0, r0 + mul r3, r3 + lsr r5, r4, #16 + lsl r4, #16 + add r0, r4 + adc r3, r5 + add r0, r4 + adc r3, r5 + lsr r4, r1, #16 + uxth r1, r1 + mov r5, r1 + mul r5, r4 + mul r1, r1 + mul r4, r4 + eor r6, r6 + add r1, r3 + adc r4, r6 + lsr r3, r5, #16 + lsl r5, r5, #16 + add r1, r5 + adc r4, r3 + add r1, r5 + adc r3, r4 + lsr r4, r2, #16 + uxth r2, r2 + mov r5, r2 + mul r5, r4 + mul r2, r2 + mul r4, r4 + lsr r6, r5, #16 + lsl r5, #16 + add r2, r5 + adc r4, r6 + add r5, r2 + adc r6, r4 + eor r4, r4 + mov r2, r1 + sub r1, r5 + sbc r2, r6 + sbc r4, r4 + add r1, r0 + adc r2, r3 + adc r3, r4 + mov r6, r11 + mov r4, r11 + mov r5, r7 + sub r6, r0 + sbc r7, r1 + sbc r4, r2 + sbc r5, r3 + eor r1, r1 + sbc r1, r1 + mov r2, r12 + mov r3, r8 + add r2, r6 + adc r3, r7 + mov r6, r9 + mov r7, r10 + adc r4, r6 + adc r5, r7 + adc r6, r1 + adc r7, r1 + //results r12, r8, r2-r7 + /////////END HIGH PART //////////////////////// + mov r0, r12 + mov r1, r8 + mov r8, r4 + mov r9, r5 + mov r10, r6 + mov r11, r7 + pop {r4} + mov r12, r4//str + pop {r4-r7} + add r0, r4 + adc r1, r5 + adc r2, r6 + adc r3, r7 + mov r4, r12 + stm r4!, {r0-r3}//low part + mov r4, r8 + mov r5, r9 + mov r6, r10 + mov r7, r11 + eor r0, r0 + adc r4, r0 + adc r5, r0 + adc r6, r0 + adc r7, r0 + pop {r0, r1} //r0->out, r1, in + push {r0,r4-r7} + ldm r1, {r0-r7} + sub r0, r4 + sbc r1, r5 + sbc r2, r6 + sbc r3, r7 + sbc r4, r4 + eor r0, r4 + eor r1, r4 + eor r2, r4 + eor r3, r4 + sub r0, r4 + sbc r1, r4 + sbc r2, r4 + sbc r3, r4 + //////////BEGIN MIDDLE PART//////////////// + ///SQR 128, in r0-r3 + mov r8, r2 + mov r9, r3 + eor r4, r4 + sub r2, r0 + sbc r3, r1 + sbc r4, r4 + eor r2, r4 + eor r3, r4 + sub r2, r4 + sbc r3, r4 + mov r10, r2 + mov r11, r3 + //SQR64, in: r0, r1, out: r0-r3, used: r0-r6 + mov r2, r0 + eor r3, r3 + sub r2, r1 + sbc r3, r3 + eor r2, r3 + sub r2, r3 + lsr r3, r0, #16 + uxth r0, r0 + mov r4, r0 + mul r4, r3 + mul r0, r0 + mul r3, r3 + lsr r5, r4, #16 + lsl r4, #16 + add r0, r4 + adc r3, r5 + add r0, r4 + adc r3, r5 + lsr r4, r1, #16 + uxth r1, r1 + mov r5, r1 + mul r5, r4 + mul r1, r1 + mul r4, r4 + eor r6, r6 + add r1, r3 + adc r4, r6 + lsr r3, r5, #16 + lsl r5, r5, #16 + add r1, r5 + adc r4, r3 + add r1, r5 + adc r3, r4 + lsr r4, r2, #16 + uxth r2, r2 + mov r5, r2 + mul r5, r4 + mul r2, r2 + mul r4, r4 + lsr r6, r5, #16 + lsl r5, #16 + add r2, r5 + adc r4, r6 + add r5, r2 + adc r6, r4 + eor r7, r7 + mov r2, r1 + sub r1, r5 + sbc r2, r6 + sbc r7, r7 + add r1, r0 + adc r2, r3 + adc r7, r3 + mov r12, r0 + mov r0, r8 + mov r8, r1 + mov r1, r9 + mov r9, r2 + //SQR64, in: r0, r1, out: r0-r3, used: r0-r6 + mov r2, r0 + eor r3, r3 + sub r2, r1 + sbc r3, r3 + eor r2, r3 + sub r2, r3 + lsr r3, r0, #16 + uxth r0, r0 + mov r4, r0 + mul r4, r3 + mul r0, r0 + mul r3, r3 + lsr r5, r4, #16 + lsl r4, #16 + add r0, r4 + adc r3, r5 + add r0, r4 + adc r3, r5 + lsr r4, r1, #16 + uxth r1, r1 + mov r5, r1 + mul r5, r4 + mul r1, r1 + mul r4, r4 + eor r6, r6 + add r1, r3 + adc r4, r6 + lsr r3, r5, #16 + lsl r5, r5, #16 + add r1, r5 + adc r4, r3 + add r1, r5 + adc r3, r4 + lsr r4, r2, #16 + uxth r2, r2 + mov r5, r2 + mul r5, r4 + mul r2, r2 + mul r4, r4 + lsr r6, r5, #16 + lsl r5, #16 + add r2, r5 + adc r4, r6 + add r5, r2 + adc r6, r4 + eor r4, r4 + mov r2, r1 + sub r1, r5 + sbc r2, r6 + sbc r4, r4 + add r1, r0 + adc r2, r3 + adc r3, r4 + eor r4, r4 + mov r6, r9 + add r0, r6 + adc r7, r1 + adc r2, r4 + adc r3, r4 + mov r1, r11 + mov r11, r0 + mov r0, r10 + mov r9, r2 + mov r10,r3 + //SQR64, in: r0, r1, out: r0-r3, used: r0-r6 + mov r2, r0 + eor r3, r3 + sub r2, r1 + sbc r3, r3 + eor r2, r3 + sub r2, r3 + lsr r3, r0, #16 + uxth r0, r0 + mov r4, r0 + mul r4, r3 + mul r0, r0 + mul r3, r3 + lsr r5, r4, #16 + lsl r4, #16 + add r0, r4 + adc r3, r5 + add r0, r4 + adc r3, r5 + lsr r4, r1, #16 + uxth r1, r1 + mov r5, r1 + mul r5, r4 + mul r1, r1 + mul r4, r4 + eor r6, r6 + add r1, r3 + adc r4, r6 + lsr r3, r5, #16 + lsl r5, r5, #16 + add r1, r5 + adc r4, r3 + add r1, r5 + adc r3, r4 + lsr r4, r2, #16 + uxth r2, r2 + mov r5, r2 + mul r5, r4 + mul r2, r2 + mul r4, r4 + lsr r6, r5, #16 + lsl r5, #16 + add r2, r5 + adc r4, r6 + add r5, r2 + adc r6, r4 + eor r4, r4 + mov r2, r1 + sub r1, r5 + sbc r2, r6 + sbc r4, r4 + add r1, r0 + adc r2, r3 + adc r3, r4 + mov r6, r11 + mov r4, r11 + mov r5, r7 + sub r6, r0 + sbc r7, r1 + sbc r4, r2 + sbc r5, r3 + eor r1, r1 + sbc r1, r1 + mov r2, r12 + mov r3, r8 + add r2, r6 + adc r3, r7 + mov r6, r9 + mov r7, r10 + adc r4, r6 + adc r5, r7 + adc r6, r1 + adc r7, r1 + //results r12, r8, r2-r7 + //////////END MIDDLE PART////////////////// + mvn r2, r2 + mvn r3, r3 + mvn r4, r4 + mvn r5, r5 + mvn r6, r6 + mvn r7, r7 + pop {r1} + push {r4-r7} + mov r4, #1 + asr r4, #1 + ldm r1!, {r4-r7} + mov r0, r12 + mov r12, r1 ////////ref + mov r1, r8 + mvn r0, r0 + mvn r1, r1 + adc r0, r4 + adc r1, r5 + adc r2, r6 + adc r3, r7 + eor r4, r4 + adc r4, r4 + mov r8, r4 //carry A --ini + mov r4, r12 + ldm r4, {r4-r7} + add r0, r4 + adc r1, r5 + adc r2, r6 + adc r3, r7 + mov r9, r4 + mov r4, r12 + stm r4!, {r0-r3} + mov r12, r4 + mov r4, r9 + pop {r0-r3} + adc r4, r0 + adc r5, r1 + adc r6, r2 + adc r7, r3 + eor r0, r0 + adc r0, r0 + mov r9, r0 //carry B --ini + mov r0, r8 + asr r0, #1 //carry A --end + pop {r0-r3} + adc r4, r0 + adc r5, r1 + adc r6, r2 + adc r7, r3 + mov r8, r0 + mov r0, r12 + stm r0!, {r4-r7} + mov r11, r0 + mov r0, r8 + eor r4, r4 + mov r5, r9 + adc r5, r4 //carry B --end + mvn r6, r4 + add r5, r6 + adc r6, r4 + add r0, r5 + adc r1, r6 + adc r2, r6 + adc r3, r6 + mov r7, r11 + stm r7!, {r0-r3} + + pop {r3-r6} + mov r8, r3 + mov r9, r4 + mov r10, r5 + mov r11, r6 + pop {r4-r7,pc} + bx lr + .size square256_asm, .-square256_asm diff --git a/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/bitops.h b/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/bitops.h new file mode 100644 index 00000000..f2ca3084 --- /dev/null +++ b/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/bitops.h @@ -0,0 +1,310 @@ +/* + * cifra - embedded cryptography library + * Written in 2014 by Joseph Birr-Pixton + * + * To the extent possible under law, the author(s) have dedicated all + * copyright and related and neighboring rights to this software to the + * public domain worldwide. This software is distributed without any + * warranty. + * + * You should have received a copy of the CC0 Public Domain Dedication + * along with this software. If not, see + * . + */ + +#ifndef BITOPS_H +#define BITOPS_H + +#include +#include + +#ifdef _WINDOWS +#include +#endif + +/* Assorted bitwise and common operations used in ciphers. */ + +/** Circularly rotate right x by n bits. + * 0 > n > 32. */ +static inline uint32_t rotr32(uint32_t x, unsigned n) +{ + return (x >> n) | (x << (32 - n)); +} + +/** Circularly rotate left x by n bits. + * 0 > n > 32. */ +static inline uint32_t rotl32(uint32_t x, unsigned n) +{ + return (x << n) | (x >> (32 - n)); +} + +/** Circularly rotate right x by n bits. + * 0 > n > 64. */ +static inline uint64_t rotr64(uint64_t x, unsigned n) +{ + return (x >> n) | (x << (64 - n)); +} + +/** Circularly rotate left x by n bits. + * 0 > n > 64. */ +static inline uint64_t rotl64(uint64_t x, unsigned n) +{ + return (x << n) | (x >> (64 - n)); +} + +/** Read 4 bytes from buf, as a 32-bit big endian quantity. */ +static inline uint32_t read32_be(const uint8_t buf[4]) +{ + return (buf[0] << 24) | + (buf[1] << 16) | + (buf[2] << 8) | + (buf[3]); +} + +/** Read 4 bytes from buf, as a 32-bit little endian quantity. */ +static inline uint32_t read32_le(const uint8_t buf[4]) +{ + return (buf[3] << 24) | + (buf[2] << 16) | + (buf[1] << 8) | + (buf[0]); +} + +/** Read 8 bytes from buf, as a 64-bit big endian quantity. */ +static inline uint64_t read64_be(const uint8_t buf[8]) +{ + uint32_t hi = read32_be(buf), + lo = read32_be(buf + 4); + return ((uint64_t)hi) << 32 | + lo; +} + +/** Read 8 bytes from buf, as a 64-bit little endian quantity. */ +static inline uint64_t read64_le(const uint8_t buf[8]) +{ + uint32_t hi = read32_le(buf + 4), + lo = read32_le(buf); + return ((uint64_t)hi) << 32 | + lo; +} + +/** Encode v as a 32-bit big endian quantity into buf. */ +static inline void write32_be(uint32_t v, uint8_t buf[4]) +{ + *buf++ = (v >> 24) & 0xff; + *buf++ = (v >> 16) & 0xff; + *buf++ = (v >> 8) & 0xff; + *buf = v & 0xff; +} + +/** Encode v as a 32-bit little endian quantity into buf. */ +static inline void write32_le(uint32_t v, uint8_t buf[4]) +{ + *buf++ = v & 0xff; + *buf++ = (v >> 8) & 0xff; + *buf++ = (v >> 16) & 0xff; + *buf = (v >> 24) & 0xff; +} + +/** Encode v as a 64-bit big endian quantity into buf. */ +static inline void write64_be(uint64_t v, uint8_t buf[8]) +{ + *buf++ = (v >> 56) & 0xff; + *buf++ = (v >> 48) & 0xff; + *buf++ = (v >> 40) & 0xff; + *buf++ = (v >> 32) & 0xff; + *buf++ = (v >> 24) & 0xff; + *buf++ = (v >> 16) & 0xff; + *buf++ = (v >> 8) & 0xff; + *buf = v & 0xff; +} + +/** Encode v as a 64-bit little endian quantity into buf. */ +static inline void write64_le(uint64_t v, uint8_t buf[8]) +{ + *buf++ = v & 0xff; + *buf++ = (v >> 8) & 0xff; + *buf++ = (v >> 16) & 0xff; + *buf++ = (v >> 24) & 0xff; + *buf++ = (v >> 32) & 0xff; + *buf++ = (v >> 40) & 0xff; + *buf++ = (v >> 48) & 0xff; + *buf = (v >> 56) & 0xff; +} + +/** out = in ^ b8. + * out and in may alias. */ +static inline void xor_b8(uint8_t *out, const uint8_t *in, uint8_t b8, size_t len) +{ + size_t i; + for (i = 0; i < len; i++) + out[i] = in[i] ^ b8; +} + +/** out = x ^ y. + * out, x and y may alias. */ +static inline void xor_bb(uint8_t *out, const uint8_t *x, const uint8_t *y, size_t len) +{ + size_t i; + for (i = 0; i < len; i++) + out[i] = x[i] ^ y[i]; +} + +/* out ^= x + * out and x may alias. */ +static inline void xor_words(uint32_t *out, const uint32_t *x, size_t nwords) +{ + size_t i; + for (i = 0; i < nwords; i++) + out[i] ^= x[i]; +} + +/** Produce 0xffffffff if x == y, zero otherwise, without branching. */ +static inline uint32_t mask_u32(uint32_t x, uint32_t y) +{ + uint32_t diff = x ^ y; + uint32_t diff_is_zero = ~diff & (diff - 1); + return (uint32_t)(-(int32_t)(diff_is_zero >> 31)); +} + +/** Product 0xff if x == y, zero otherwise, without branching. */ +static inline uint8_t mask_u8(uint32_t x, uint32_t y) +{ + uint32_t diff = x ^ y; + uint8_t diff_is_zero = ~diff & (diff - 1); + return - (diff_is_zero >> 7); +} + +/** Select the ith entry from the given table of n values, in a side channel-silent + * way. */ +static inline uint32_t select_u32(uint32_t i, volatile const uint32_t *tab, uint32_t n) +{ + uint32_t r = 0, ii; + + for (ii = 0; ii < n; ii++) + { + uint32_t mask = mask_u32(i, ii); + r = (r & ~mask) | (tab[ii] & mask); + } + + return r; +} + +/** Select the ith entry from the given table of n values, in a side channel-silent + * way. */ +static inline uint8_t select_u8(uint32_t i, volatile const uint8_t *tab, uint32_t n) +{ + uint8_t r = 0; + uint32_t ii; + + for (ii = 0; ii < n; ii++) + { + uint8_t mask = mask_u8(i, ii); + r = (r & ~mask) | (tab[ii] & mask); + } + + return r; +} + +/** Select the ath, bth, cth and dth entries from the given table of n values, + * placing the results into a, b, c and d. */ +static inline void select_u8x4(uint8_t *a, uint8_t *b, uint8_t *c, uint8_t *d, + volatile const uint8_t *tab, uint32_t n) +{ + uint8_t ra = 0, + rb = 0, + rc = 0, + rd = 0; + uint8_t mask; + uint32_t i; + + for (i = 0; i < n; i++) + { + uint8_t item = tab[i]; + + mask = mask_u8(*a, i); ra = (ra & ~mask) | (item & mask); + mask = mask_u8(*b, i); rb = (rb & ~mask) | (item & mask); + mask = mask_u8(*c, i); rc = (rc & ~mask) | (item & mask); + mask = mask_u8(*d, i); rd = (rd & ~mask) | (item & mask); + } + + *a = ra; + *b = rb; + *c = rc; + *d = rd; +} + +/** out ^= if0 or if1, depending on the value of bit. */ +static inline void select_xor128(uint32_t out[4], + const uint32_t if0[4], + const uint32_t if1[4], + uint8_t bit) +{ + uint32_t mask1 = mask_u32(bit, 1); + uint32_t mask0 = ~mask1; + + out[0] ^= (if0[0] & mask0) | (if1[0] & mask1); + out[1] ^= (if0[1] & mask0) | (if1[1] & mask1); + out[2] ^= (if0[2] & mask0) | (if1[2] & mask1); + out[3] ^= (if0[3] & mask0) | (if1[3] & mask1); +} + +/** Increments the integer stored at v (of non-zero length len) + * with the least significant byte first. */ +static inline void incr_le(uint8_t *v, size_t len) +{ + size_t i = 0; + while (1) + { + if (++v[i] != 0) + return; + i++; + if (i == len) + return; + } +} + +/** Increments the integer stored at v (of non-zero length len) + * with the most significant byte last. */ +static inline void incr_be(uint8_t *v, size_t len) +{ + len--; + while (1) + { + if (++v[len] != 0) + return; + if (len == 0) + return; + len--; + } +} + +/** Copies len bytes from in to out, with in shifted left by offset bits + * to the right. */ +static inline void copy_bytes_unaligned(uint8_t *out, const uint8_t *in, size_t len, uint8_t offset) +{ + uint8_t byte_off = offset / 8; + uint8_t bit_off = offset & 7; + uint8_t rmask = (1 << bit_off) - 1; + uint8_t lmask = ~rmask; + size_t i; + + for (i = 0; i < len; i++) + { + out[i] = (in[i + byte_off] << bit_off) & lmask; + out[i] |= (in[i + byte_off + 1] >> (8 - bit_off)) & rmask; + } +} + +static inline uint32_t count_trailing_zeroes(uint32_t x) +{ +#ifdef _WINDOWS + uint32_t r = 0; + _BitScanReverse(&r, x); + return (31 - r); +#else + return (uint32_t) __builtin_ctzl(x); +#endif +} + +#endif diff --git a/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/blockwise.c b/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/blockwise.c new file mode 100644 index 00000000..182c8c51 --- /dev/null +++ b/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/blockwise.c @@ -0,0 +1,195 @@ +/* + * cifra - embedded cryptography library + * Written in 2014 by Joseph Birr-Pixton + * + * To the extent possible under law, the author(s) have dedicated all + * copyright and related and neighboring rights to this software to the + * public domain worldwide. This software is distributed without any + * warranty. + * + * You should have received a copy of the CC0 Public Domain Dedication + * along with this software. If not, see + * . + */ + +#include "blockwise.h" +#include "bitops.h" +#include "handy.h" +#include "tassert.h" + +#include + +void cf_blockwise_accumulate(uint8_t *partial, size_t *npartial, size_t nblock, + const void *inp, size_t nbytes, + cf_blockwise_in_fn process, + void *ctx) +{ + cf_blockwise_accumulate_final(partial, npartial, nblock, + inp, nbytes, + process, process, ctx); +} + +void cf_blockwise_accumulate_final(uint8_t *partial, size_t *npartial, size_t nblock, + const void *inp, size_t nbytes, + cf_blockwise_in_fn process, + cf_blockwise_in_fn process_final, + void *ctx) +{ + const uint8_t *bufin = inp; + assert(partial && *npartial < nblock); + assert(inp || !nbytes); + assert(process && ctx); + + /* If we have partial data, copy in to buffer. */ + if (*npartial && nbytes) + { + size_t space = nblock - *npartial; + size_t taken = MIN(space, nbytes); + + memcpy(partial + *npartial, bufin, taken); + + bufin += taken; + nbytes -= taken; + *npartial += taken; + + /* If that gives us a full block, process it. */ + if (*npartial == nblock) + { + if (nbytes == 0) + process_final(ctx, partial); + else + process(ctx, partial); + *npartial = 0; + } + } + + /* now nbytes < nblock or *npartial == 0. */ + + /* If we have a full block of data, process it directly. */ + while (nbytes >= nblock) + { + /* Partial buffer must be empty, or we're ignoring extant data */ + assert(*npartial == 0); + + if (nbytes == nblock) + process_final(ctx, bufin); + else + process(ctx, bufin); + bufin += nblock; + nbytes -= nblock; + } + + /* Finally, if we have remaining data, buffer it. */ + while (nbytes) + { + size_t space = nblock - *npartial; + size_t taken = MIN(space, nbytes); + + memcpy(partial + *npartial, bufin, taken); + + bufin += taken; + nbytes -= taken; + *npartial += taken; + + /* If we started with *npartial, we must have copied it + * in first. */ + assert(*npartial < nblock); + } +} + +void cf_blockwise_xor(uint8_t *partial, size_t *npartial, size_t nblock, + const void *inp, void *outp, size_t nbytes, + cf_blockwise_out_fn process, void *ctx) +{ + const uint8_t *inb = inp; + uint8_t *outb = outp; + + assert(partial && *npartial < nblock); + assert(inp || !nbytes); + assert(process && ctx); + + while (nbytes) + { + /* If we're out of material, and need more, produce a block. */ + if (*npartial == 0) + { + process(ctx, partial); + *npartial = nblock; + } + + size_t offset = nblock - *npartial; + size_t taken = MIN(*npartial, nbytes); + xor_bb(outb, inb, partial + offset, taken); + *npartial -= taken; + nbytes -= taken; + outb += taken; + inb += taken; + } +} + +void cf_blockwise_acc_byte(uint8_t *partial, size_t *npartial, + size_t nblock, + uint8_t byte, size_t nbytes, + cf_blockwise_in_fn process, + void *ctx) +{ + /* only memset the whole of the block once */ + int filled = 0; + + while (nbytes) + { + size_t start = *npartial; + size_t count = MIN(nbytes, nblock - start); + + if (!filled) + memset(partial + start, byte, count); + + if (start == 0 && count == nblock) + filled = 1; + + if (start + count == nblock) + { + process(ctx, partial); + *npartial = 0; + } else { + *npartial += count; + } + + nbytes -= count; + } +} + +void cf_blockwise_acc_pad(uint8_t *partial, size_t *npartial, + size_t nblock, + uint8_t fbyte, uint8_t mbyte, uint8_t lbyte, + size_t nbytes, + cf_blockwise_in_fn process, + void *ctx) +{ + + switch (nbytes) + { + case 0: break; + case 1: fbyte ^= lbyte; + cf_blockwise_accumulate(partial, npartial, nblock, &fbyte, 1, process, ctx); + break; + case 2: + cf_blockwise_accumulate(partial, npartial, nblock, &fbyte, 1, process, ctx); + cf_blockwise_accumulate(partial, npartial, nblock, &lbyte, 1, process, ctx); + break; + default: + cf_blockwise_accumulate(partial, npartial, nblock, &fbyte, 1, process, ctx); + + /* If the middle and last bytes differ, then process the last byte separately. + * Otherwise, just extend the middle block size. */ + if (lbyte != mbyte) + { + cf_blockwise_acc_byte(partial, npartial, nblock, mbyte, nbytes - 2, process, ctx); + cf_blockwise_accumulate(partial, npartial, nblock, &lbyte, 1, process, ctx); + } else { + cf_blockwise_acc_byte(partial, npartial, nblock, mbyte, nbytes - 1, process, ctx); + } + + break; + } +} diff --git a/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/blockwise.h b/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/blockwise.h new file mode 100644 index 00000000..a20ff959 --- /dev/null +++ b/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/blockwise.h @@ -0,0 +1,147 @@ +/* + * cifra - embedded cryptography library + * Written in 2014 by Joseph Birr-Pixton + * + * To the extent possible under law, the author(s) have dedicated all + * copyright and related and neighboring rights to this software to the + * public domain worldwide. This software is distributed without any + * warranty. + * + * You should have received a copy of the CC0 Public Domain Dedication + * along with this software. If not, see + * . + */ + +#ifndef BLOCKWISE_H +#define BLOCKWISE_H + +#include +#include + +/* Processing function for cf_blockwise_accumulate. */ +typedef void (*cf_blockwise_in_fn)(void *ctx, const uint8_t *data); + +/* Processing function for cf_blockwise_xor. */ +typedef void (*cf_blockwise_out_fn)(void *ctx, uint8_t *data); + +/* This function manages the common abstraction of accumulating input in + * a buffer, and processing it when a full block is available. + * + * partial is the buffer (maintained by the caller) + * on entry, npartial is the currently valid count of used bytes on + * the front of partial. + * on exit, npartial is updated to reflect the status of partial. + * nblock is the blocksize to accumulate -- partial must be at least + * this long! + * input is the new data to process, of length nbytes. + * process is the processing function, passed ctx and a pointer + * to the data to process (always exactly nblock bytes long!) + * which may not neccessarily be the same as partial. + */ +void cf_blockwise_accumulate(uint8_t *partial, size_t *npartial, + size_t nblock, + const void *input, size_t nbytes, + cf_blockwise_in_fn process, + void *ctx); + +/* This function manages the common abstraction of accumulating input in + * a buffer, and processing it when a full block is available. + * This version supports calling a different processing function for + * the last block. + * + * partial is the buffer (maintained by the caller) + * on entry, npartial is the currently valid count of used bytes on + * the front of partial. + * on exit, npartial is updated to reflect the status of partial. + * nblock is the blocksize to accumulate -- partial must be at least + * this long! + * input is the new data to process, of length nbytes. + * process is the processing function, passed ctx and a pointer + * to the data to process (always exactly nblock bytes long!) + * which may not neccessarily be the same as partial. + * process_final is called last (but may not be called at all if + * all input is buffered). + */ +void cf_blockwise_accumulate_final(uint8_t *partial, size_t *npartial, + size_t nblock, + const void *input, size_t nbytes, + cf_blockwise_in_fn process, + cf_blockwise_in_fn process_final, + void *ctx); + +/* This function manages XORing an input stream with a keystream + * to produce an output stream. The keystream is produced in blocks + * (ala a block cipher in counter mode). + * + * partial is the keystream buffer (maintained by the caller) + * on entry, *npartial is the currently valid count of bytes in partial: + * unused bytes are at the *end*. So *npartial = 4 means the last four + * bytes of partial are usable as keystream. + * on exit, npartial is updated to reflect the new state of partial. + * nblock is the blocksize to accumulate -- partial must be at least + * this long! + * input is the new data to process, of length nbytes. + * output is where to write input xored with the keystream -- also length + * nbytes. + * process is the processing function, passed ctx and partial which it + * should fill with fresh key stream. + */ +void cf_blockwise_xor(uint8_t *partial, size_t *npartial, + size_t nblock, + const void *input, void *output, size_t nbytes, + cf_blockwise_out_fn newblock, + void *ctx); + +/* This function processes a single byte a number of times. It's useful + * for padding, and more efficient than calling cf_blockwise_accumulate + * a bunch of times. + * + * partial is the buffer (maintained by the caller) + * on entry, npartial is the currently valid count of used bytes on + * the front of partial. + * on exit, npartial is updated to reflect the status of partial. + * nblock is the blocksize to accumulate -- partial must be at least + * this long! + * process is the processing function, passed ctx and a pointer + * to the data to process (always exactly nblock bytes long!) + * which may not neccessarily be the same as partial. + * byte is the byte to process, nbytes times. + */ +void cf_blockwise_acc_byte(uint8_t *partial, size_t *npartial, + size_t nblock, + uint8_t byte, size_t nbytes, + cf_blockwise_in_fn process, + void *ctx); + +/* This function attempts to process patterns of bytes common in + * block cipher padding. + * + * This takes three bytes: + * - a first byte, fbyte, + * - a middle byte, mbyte, + * - a last byte, lbyte. + * + * If nbytes is zero, nothing happens. + * If nbytes is one, the byte fbyte ^ lbyte is processed. + * If nbytes is two, the fbyte then lbyte are processed. + * If nbytes is three or more, fbyte, then one or more mbytes, then fbyte + * is processed. + * + * partial is the buffer (maintained by the caller) + * on entry, npartial is the currently valid count of used bytes on + * the front of partial. + * on exit, npartial is updated to reflect the status of partial. + * nblock is the blocksize to accumulate -- partial must be at least + * this long! + * process is the processing function, passed ctx and a pointer + * to the data to process (always exactly nblock bytes long!) + * which may not neccessarily be the same as partial. + */ +void cf_blockwise_acc_pad(uint8_t *partial, size_t *npartial, + size_t nblock, + uint8_t fbyte, uint8_t mbyte, uint8_t lbyte, + size_t nbytes, + cf_blockwise_in_fn process, + void *ctx); + +#endif diff --git a/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/cbcmac.c b/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/cbcmac.c new file mode 100644 index 00000000..f0dfe875 --- /dev/null +++ b/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/cbcmac.c @@ -0,0 +1,79 @@ +/* + * cifra - embedded cryptography library + * Written in 2014 by Joseph Birr-Pixton + * + * To the extent possible under law, the author(s) have dedicated all + * copyright and related and neighboring rights to this software to the + * public domain worldwide. This software is distributed without any + * warranty. + * + * You should have received a copy of the CC0 Public Domain Dedication + * along with this software. If not, see + * . + */ + +#include "handy.h" +#include "prp.h" +#include "modes.h" +#include "bitops.h" +#include "blockwise.h" +#include "gf128.h" +#include "tassert.h" + +#include + +void cf_cbcmac_stream_init(cf_cbcmac_stream *ctx, const cf_prp *prp, void *prpctx) +{ + memset(ctx, 0, sizeof *ctx); + ctx->prp = prp; + ctx->prpctx = prpctx; + cf_cbcmac_stream_reset(ctx); +} + +void cf_cbcmac_stream_reset(cf_cbcmac_stream *ctx) +{ + uint8_t iv_zero[CF_MAXBLOCK] = { 0 }; + cf_cbc_init(&ctx->cbc, ctx->prp, ctx->prpctx, iv_zero); + mem_clean(ctx->buffer, sizeof ctx->buffer); + ctx->used = 0; +} + +static void cbcmac_process(void *vctx, const uint8_t *block) +{ + cf_cbcmac_stream *ctx = vctx; + uint8_t output[CF_MAXBLOCK]; + cf_cbc_encrypt(&ctx->cbc, block, output, 1); +} + +void cf_cbcmac_stream_update(cf_cbcmac_stream *ctx, const uint8_t *data, size_t len) +{ + cf_blockwise_accumulate(ctx->buffer, &ctx->used, ctx->prp->blocksz, + data, len, + cbcmac_process, + ctx); +} + +void cf_cbcmac_stream_finish_block_zero(cf_cbcmac_stream *ctx) +{ + if (ctx->used == 0) + return; + + memset(ctx->buffer + ctx->used, 0, ctx->prp->blocksz - ctx->used); + cbcmac_process(ctx, ctx->buffer); + ctx->used = 0; +} + +void cf_cbcmac_stream_nopad_final(cf_cbcmac_stream *ctx, uint8_t out[CF_MAXBLOCK]) +{ + assert(ctx->used == 0); + memcpy(out, ctx->cbc.block, ctx->prp->blocksz); +} + +void cf_cbcmac_stream_pad_final(cf_cbcmac_stream *ctx, uint8_t out[CF_MAXBLOCK]) +{ + uint8_t npad = ctx->prp->blocksz - ctx->used; + cf_blockwise_acc_byte(ctx->buffer, &ctx->used, ctx->prp->blocksz, + npad, npad, + cbcmac_process, ctx); + cf_cbcmac_stream_nopad_final(ctx, out); +} diff --git a/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/ccm.c b/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/ccm.c new file mode 100644 index 00000000..7ef87fc1 --- /dev/null +++ b/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/ccm.c @@ -0,0 +1,193 @@ +/* + * cifra - embedded cryptography library + * Written in 2014 by Joseph Birr-Pixton + * + * To the extent possible under law, the author(s) have dedicated all + * copyright and related and neighboring rights to this software to the + * public domain worldwide. This software is distributed without any + * warranty. + * + * You should have received a copy of the CC0 Public Domain Dedication + * along with this software. If not, see + * . + */ + +#include "handy.h" +#include "prp.h" +#include "modes.h" +#include "tassert.h" + +#include + +#define CCM_ADATA_PRESENT 0x40 + +static void write_be(uint8_t *out, size_t value, size_t bytes) +{ + while (bytes) + { + out[bytes - 1] = value & 0xff; + value >>= 8; + bytes--; + } + + assert(value == 0); /* or we couldn't encode the value. */ +} + +static void zero_pad(cf_cbcmac_stream *cm) +{ + cf_cbcmac_stream_finish_block_zero(cm); +} + +/* nb. block is general workspace. */ +static void add_aad(cf_cbcmac_stream *cm, uint8_t block[CF_MAXBLOCK], + const uint8_t *header, size_t nheader) +{ + assert(nheader <= 0xffffffff); /* we don't support 64 bit lengths. */ + + /* Add length using stupidly complicated rules. */ + if (nheader < 0xff00) + { + write_be(block, nheader, 2); + cf_cbcmac_stream_update(cm, block, 2); + } else { + write_be(block, 0xfffe, 2); + write_be(block + 2, nheader, 4); + cf_cbcmac_stream_update(cm, block, 6); + } + + cf_cbcmac_stream_update(cm, header, nheader); + zero_pad(cm); +} + +static void add_block0(cf_cbcmac_stream *cm, + uint8_t block[CF_MAXBLOCK], size_t nblock, + const uint8_t *nonce, size_t nnonce, + size_t L, size_t nplain, + size_t nheader, size_t ntag) +{ + /* Construct first block B_0. */ + block[0] = ((nheader == 0) ? 0x00 : CCM_ADATA_PRESENT) | + ((ntag - 2) / 2) << 3 | + (L - 1); + memcpy(block + 1, nonce, nnonce); + write_be(block + 1 + nnonce, nplain, L); + + cf_cbcmac_stream_update(cm, block, nblock); +} + +static void build_ctr_nonce(uint8_t ctr_nonce[CF_MAXBLOCK], + size_t L, + const uint8_t *nonce, size_t nnonce) +{ + ctr_nonce[0] = (L - 1); + memcpy(ctr_nonce + 1, nonce, nnonce); + memset(ctr_nonce + 1 + nnonce, 0, L); +} + +void cf_ccm_encrypt(const cf_prp *prp, void *prpctx, + const uint8_t *plain, size_t nplain, size_t L, + const uint8_t *header, size_t nheader, + const uint8_t *nonce, size_t nnonce, + uint8_t *cipher, + uint8_t *tag, size_t ntag) +{ + uint8_t block[CF_MAXBLOCK]; + + assert(ntag >= 4 && ntag <= 16 && ntag % 2 == 0); + assert(L >= 2 && L <= 8); + assert(nnonce == prp->blocksz - L - 1); + + cf_cbcmac_stream cm; + cf_cbcmac_stream_init(&cm, prp, prpctx); + + /* Add first block. */ + add_block0(&cm, block, prp->blocksz, + nonce, nnonce, + L, nplain, nheader, ntag); + + /* Add AAD with length prefix, if present. */ + if (nheader) + add_aad(&cm, block, header, nheader); + + /* Add message. */ + cf_cbcmac_stream_update(&cm, plain, nplain); + zero_pad(&cm); + + /* Finish tag. */ + cf_cbcmac_stream_nopad_final(&cm, block); + + /* Start encryption. */ + /* Construct A_0 */ + uint8_t ctr_nonce[CF_MAXBLOCK]; + build_ctr_nonce(ctr_nonce, L, nonce, nnonce); + + cf_ctr ctr; + cf_ctr_init(&ctr, prp, prpctx, ctr_nonce); + cf_ctr_custom_counter(&ctr, prp->blocksz - L, L); + + /* Encrypt tag first. */ + cf_ctr_cipher(&ctr, block, block, prp->blocksz); + memcpy(tag, block, ntag); + + /* Then encrypt message. */ + cf_ctr_cipher(&ctr, plain, cipher, nplain); +} + +int cf_ccm_decrypt(const cf_prp *prp, void *prpctx, + const uint8_t *cipher, size_t ncipher, size_t L, + const uint8_t *header, size_t nheader, + const uint8_t *nonce, size_t nnonce, + const uint8_t *tag, size_t ntag, + uint8_t *plain) +{ + uint8_t block[CF_MAXBLOCK]; + + assert(ntag >= 4 && ntag <= 16 && ntag % 2 == 0); + assert(L >= 2 && L <= 8); + assert(nnonce == prp->blocksz - L - 1); + + uint8_t ctr_nonce[CF_MAXBLOCK]; + build_ctr_nonce(ctr_nonce, L, nonce, nnonce); + + cf_ctr ctr; + cf_ctr_init(&ctr, prp, prpctx, ctr_nonce); + cf_ctr_custom_counter(&ctr, prp->blocksz - L, L); + + /* Decrypt tag. */ + uint8_t plain_tag[CF_MAXBLOCK]; + cf_ctr_cipher(&ctr, tag, plain_tag, ntag); + cf_ctr_discard_block(&ctr); + + /* Decrypt message. */ + cf_ctr_cipher(&ctr, cipher, plain, ncipher); + + cf_cbcmac_stream cm; + cf_cbcmac_stream_init(&cm, prp, prpctx); + + /* Add first block. */ + add_block0(&cm, block, prp->blocksz, + nonce, nnonce, + L, ncipher, nheader, ntag); + + if (nheader) + add_aad(&cm, block, header, nheader); + + cf_cbcmac_stream_update(&cm, plain, ncipher); + zero_pad(&cm); + + /* Finish tag. */ + cf_cbcmac_stream_nopad_final(&cm, block); + + int err = 0; + + if (!mem_eq(block, plain_tag, ntag)) + { + err = 1; + mem_clean(plain, ncipher); + } + + mem_clean(block, sizeof block); + mem_clean(plain_tag, sizeof plain_tag); + return err; +} + diff --git a/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/cf_config.h b/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/cf_config.h new file mode 100644 index 00000000..ceb7e8da --- /dev/null +++ b/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/cf_config.h @@ -0,0 +1,59 @@ +/* + * cifra - embedded cryptography library + * Written in 2014 by Joseph Birr-Pixton + * + * To the extent possible under law, the author(s) have dedicated all + * copyright and related and neighboring rights to this software to the + * public domain worldwide. This software is distributed without any + * warranty. + * + * You should have received a copy of the CC0 Public Domain Dedication + * along with this software. If not, see + * . + */ + +#ifndef CF_CONFIG_H +#define CF_CONFIG_H + +/** + * Library configuration + * ===================== + */ + +/* .. c:macro:: CF_SIDE_CHANNEL_PROTECTION + * Define this as 1 if you need all available side channel protections. + * **This option may alter the ABI**. + * + * This has a non-trivial performance penalty. Where a + * side-channel free option is cheap or free (like checking + * a MAC) this is always done in a side-channel free way. + * + * The default is **on** for all available protections. + */ +#ifndef CF_SIDE_CHANNEL_PROTECTION +# define CF_SIDE_CHANNEL_PROTECTION 1 +#endif + +/* .. c:macro:: CF_TIME_SIDE_CHANNEL_PROTECTION + * Define this as 1 if you need timing/branch prediction side channel + * protection. + * + * You probably want this. The default is on. */ +#ifndef CF_TIME_SIDE_CHANNEL_PROTECTION +# define CF_TIME_SIDE_CHANNEL_PROTECTION CF_SIDE_CHANNEL_PROTECTION +#endif + +/* .. c:macro:: CF_CACHE_SIDE_CHANNEL_PROTECTION + * Define this as 1 if you need cache side channel protection. + * + * If you have a microcontroller with no cache, you can turn this off + * without negative effects. + * + * The default is on. This will have some performance impact, + * especially on AES. + */ +#ifndef CF_CACHE_SIDE_CHANNEL_PROTECTION +# define CF_CACHE_SIDE_CHANNEL_PROTECTION CF_SIDE_CHANNEL_PROTECTION +#endif + +#endif diff --git a/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/chacha20.c b/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/chacha20.c new file mode 100644 index 00000000..7a3bf382 --- /dev/null +++ b/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/chacha20.c @@ -0,0 +1,161 @@ +/* + * cifra - embedded cryptography library + * Written in 2014 by Joseph Birr-Pixton + * + * To the extent possible under law, the author(s) have dedicated all + * copyright and related and neighboring rights to this software to the + * public domain worldwide. This software is distributed without any + * warranty. + * + * You should have received a copy of the CC0 Public Domain Dedication + * along with this software. If not, see + * . + */ + +#include "bitops.h" +#include "salsa20.h" +#include "blockwise.h" +#include "tassert.h" + +#include +#include + +void cf_chacha20_core(const uint8_t key0[16], + const uint8_t key1[16], + const uint8_t nonce[16], + const uint8_t constant[16], + uint8_t out[64]) +{ + uint32_t z0, z1, z2, z3, z4, z5, z6, z7, + z8, z9, za, zb, zc, zd, ze, zf; + + uint32_t x0 = z0 = read32_le(constant + 0), + x1 = z1 = read32_le(constant + 4), + x2 = z2 = read32_le(constant + 8), + x3 = z3 = read32_le(constant + 12), + x4 = z4 = read32_le(key0 + 0), + x5 = z5 = read32_le(key0 + 4), + x6 = z6 = read32_le(key0 + 8), + x7 = z7 = read32_le(key0 + 12), + x8 = z8 = read32_le(key1 + 0), + x9 = z9 = read32_le(key1 + 4), + xa = za = read32_le(key1 + 8), + xb = zb = read32_le(key1 + 12), + xc = zc = read32_le(nonce + 0), + xd = zd = read32_le(nonce + 4), + xe = ze = read32_le(nonce + 8), + xf = zf = read32_le(nonce + 12); + +#define QUARTER(a, b, c, d) \ + a += b; d = rotl32(d ^ a, 16); \ + c += d; b = rotl32(b ^ c, 12); \ + a += b; d = rotl32(d ^ a, 8); \ + c += d; b = rotl32(b ^ c, 7); + + int i; + for (i = 0; i < 10; i++) + { + QUARTER(z0, z4, z8, zc); + QUARTER(z1, z5, z9, zd); + QUARTER(z2, z6, za, ze); + QUARTER(z3, z7, zb, zf); + QUARTER(z0, z5, za, zf); + QUARTER(z1, z6, zb, zc); + QUARTER(z2, z7, z8, zd); + QUARTER(z3, z4, z9, ze); + } + + x0 += z0; + x1 += z1; + x2 += z2; + x3 += z3; + x4 += z4; + x5 += z5; + x6 += z6; + x7 += z7; + x8 += z8; + x9 += z9; + xa += za; + xb += zb; + xc += zc; + xd += zd; + xe += ze; + xf += zf; + + write32_le(x0, out + 0); + write32_le(x1, out + 4); + write32_le(x2, out + 8); + write32_le(x3, out + 12); + write32_le(x4, out + 16); + write32_le(x5, out + 20); + write32_le(x6, out + 24); + write32_le(x7, out + 28); + write32_le(x8, out + 32); + write32_le(x9, out + 36); + write32_le(xa, out + 40); + write32_le(xb, out + 44); + write32_le(xc, out + 48); + write32_le(xd, out + 52); + write32_le(xe, out + 56); + write32_le(xf, out + 60); +} + +static const uint8_t *chacha20_tau = (const uint8_t *) "expand 16-byte k"; +static const uint8_t *chacha20_sigma = (const uint8_t *) "expand 32-byte k"; + +static void set_key(cf_chacha20_ctx *ctx, const uint8_t *key, size_t nkey) +{ + switch (nkey) + { + case 16: + memcpy(ctx->key0, key, 16); + memcpy(ctx->key1, key, 16); + ctx->constant = chacha20_tau; + break; + case 32: + memcpy(ctx->key0, key, 16); + memcpy(ctx->key1, key + 16, 16); + ctx->constant = chacha20_sigma; + break; + default: + abort(); + } +} + +void cf_chacha20_init(cf_chacha20_ctx *ctx, const uint8_t *key, size_t nkey, const uint8_t nonce[8]) +{ + set_key(ctx, key, nkey); + memset(ctx->nonce, 0, sizeof ctx->nonce); + memcpy(ctx->nonce + 8, nonce, 8); + ctx->nblock = 0; + ctx->ncounter = 8; +} + +void cf_chacha20_init_custom(cf_chacha20_ctx *ctx, const uint8_t *key, size_t nkey, + const uint8_t nonce[16], size_t ncounter) +{ + assert(ncounter > 0); + set_key(ctx, key, nkey); + memcpy(ctx->nonce, nonce, sizeof ctx->nonce); + ctx->nblock = 0; + ctx->ncounter = ncounter; +} + +static void cf_chacha20_next_block(void *vctx, uint8_t *out) +{ + cf_chacha20_ctx *ctx = vctx; + cf_chacha20_core(ctx->key0, + ctx->key1, + ctx->nonce, + ctx->constant, + out); + incr_le(ctx->nonce, ctx->ncounter); +} + +void cf_chacha20_cipher(cf_chacha20_ctx *ctx, const uint8_t *input, uint8_t *output, size_t bytes) +{ + cf_blockwise_xor(ctx->block, &ctx->nblock, 64, + input, output, bytes, + cf_chacha20_next_block, + ctx); +} diff --git a/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/chacha20poly1305.c b/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/chacha20poly1305.c new file mode 100644 index 00000000..0aef7254 --- /dev/null +++ b/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/chacha20poly1305.c @@ -0,0 +1,148 @@ +/* + * cifra - embedded cryptography library + * Written in 2014 by Joseph Birr-Pixton + * + * To the extent possible under law, the author(s) have dedicated all + * copyright and related and neighboring rights to this software to the + * public domain worldwide. This software is distributed without any + * warranty. + * + * You should have received a copy of the CC0 Public Domain Dedication + * along with this software. If not, see + * . + */ + +#include "chacha20poly1305.h" +#include "salsa20.h" +#include "poly1305.h" +#include "bitops.h" +#include "handy.h" + +#define ENCRYPT 1 +#define DECRYPT 0 + +#define SUCCESS 0 +#define FAILURE 1 + +static int process(const uint8_t key[32], + const uint8_t nonce[12], + const uint8_t *header, size_t nheader, + const uint8_t *input, size_t nbytes, + uint8_t *output, + int mode, + uint8_t tag[16]) +{ + /* First, generate the Poly1305 key by running ChaCha20 with the + * given key and a zero counter. The first half of the + * 64-byte output is the key. */ + uint8_t fullnonce[16] = { 0 }; + memcpy(fullnonce + 4, nonce, 12); + + uint8_t polykey[32] = { 0 }; + cf_chacha20_ctx chacha; + cf_chacha20_init_custom(&chacha, key, 32, fullnonce, 4); + cf_chacha20_cipher(&chacha, polykey, polykey, sizeof polykey); + + /* Now initialise Poly1305. */ + cf_poly1305 poly; + cf_poly1305_init(&poly, polykey, polykey + 16); + mem_clean(polykey, sizeof polykey); + + /* Discard next 32 bytes of chacha20 key stream. */ + cf_chacha20_cipher(&chacha, polykey, polykey, sizeof polykey); + mem_clean(polykey, sizeof polykey); + + /* The input to Poly1305 is: + * AAD || pad(AAD) || cipher || pad(cipher) || len_64(aad) || len_64(cipher) */ + uint8_t padbuf[16] = { 0 }; + +#define PADLEN(x) (16 - ((x) & 0xf)) + + /* AAD || pad(AAD) */ + cf_poly1305_update(&poly, header, nheader); + cf_poly1305_update(&poly, padbuf, PADLEN(nheader)); + + /* || cipher */ + if (mode == ENCRYPT) + { + /* If we're encrypting, we compute the ciphertext + * before inputting it into the MAC. */ + cf_chacha20_cipher(&chacha, input, output, nbytes); + cf_poly1305_update(&poly, output, nbytes); + } else { + /* Otherwise: decryption -- input the ciphertext. + * Delay actual decryption until we checked the MAC. */ + cf_poly1305_update(&poly, input, nbytes); + } + + /* || pad(cipher) */ + cf_poly1305_update(&poly, padbuf, PADLEN(nbytes)); + + /* || len_64(aad) || len_64(cipher) */ + write64_le(nheader, padbuf); + write64_le(nbytes, padbuf + 8); + cf_poly1305_update(&poly, padbuf, sizeof padbuf); + + /* MAC computation is now complete. */ + + if (mode == ENCRYPT) + { + cf_poly1305_finish(&poly, tag); + mem_clean(&chacha, sizeof chacha); + return SUCCESS; + } + + /* Decrypt mode: calculate tag, and check it. + * If it's correct, proceed with decryption. */ + uint8_t checktag[16]; + cf_poly1305_finish(&poly, checktag); + + if (mem_eq(checktag, tag, sizeof checktag)) + { + cf_chacha20_cipher(&chacha, input, output, nbytes); + mem_clean(&chacha, sizeof chacha); + mem_clean(checktag, sizeof checktag); + return SUCCESS; + } else { + mem_clean(output, nbytes); + mem_clean(&chacha, sizeof chacha); + mem_clean(checktag, sizeof checktag); + return FAILURE; + } +} + +void cf_chacha20poly1305_encrypt(const uint8_t key[32], + const uint8_t nonce[12], + const uint8_t *header, size_t nheader, + const uint8_t *plaintext, size_t nbytes, + uint8_t *ciphertext, + uint8_t tag[16]) +{ + process(key, + nonce, + header, nheader, + plaintext, nbytes, + ciphertext, + ENCRYPT, + tag); +} + +int cf_chacha20poly1305_decrypt(const uint8_t key[32], + const uint8_t nonce[12], + const uint8_t *header, size_t nheader, + const uint8_t *ciphertext, size_t nbytes, + const uint8_t tag[16], + uint8_t *plaintext) +{ + uint8_t ourtag[16]; + memcpy(ourtag, tag, sizeof ourtag); + + return process(key, + nonce, + header, nheader, + ciphertext, nbytes, + plaintext, + DECRYPT, + ourtag); +} + diff --git a/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/chacha20poly1305.h b/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/chacha20poly1305.h new file mode 100644 index 00000000..1d44156c --- /dev/null +++ b/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/chacha20poly1305.h @@ -0,0 +1,73 @@ +/* + * cifra - embedded cryptography library + * Written in 2014 by Joseph Birr-Pixton + * + * To the extent possible under law, the author(s) have dedicated all + * copyright and related and neighboring rights to this software to the + * public domain worldwide. This software is distributed without any + * warranty. + * + * You should have received a copy of the CC0 Public Domain Dedication + * along with this software. If not, see + * . + */ + +#ifndef CHACHA20POLY1305_H +#define CHACHA20POLY1305_H + +#include +#include + +/** + * The ChaCha20-Poly1305 AEAD construction + * ======================================= + * This is a composition of the ChaCha20 stream cipher and + * the Poly1305 polynomial MAC to form an AEAD. + * It's specified for use in TLS in the form of RFC7539. + * + * It uses a 256-bit key and a 96-bit nonce. + * + * This is a one-shot interface. + */ + +/* .. c:function:: $DECL + * ChaCha20-Poly1305 authenticated encryption. + * + * :param key: key material. + * :param nonce: per-message nonce. + * :param header: header buffer. + * :param nheader: number of header bytes. + * :param plaintext: plaintext bytes to be encrypted. + * :param nbytes: number of plaintext/ciphertext bytes. + * :param ciphertext: ciphertext output buffer, nbytes in length. + * :param tag: authentication tag output buffer. + */ +void cf_chacha20poly1305_encrypt(const uint8_t key[32], + const uint8_t nonce[12], + const uint8_t *header, size_t nheader, + const uint8_t *plaintext, size_t nbytes, + uint8_t *ciphertext, + uint8_t tag[16]); + +/* .. c:function:: $DECL + * ChaCha20-Poly1305 authenticated decryption. + * + * :return: 0 on success, non-zero on error. Plaintext is zeroed on error. + * + * :param key: key material. + * :param nonce: per-message nonce. + * :param header: header buffer. + * :param nheader: number of header bytes. + * :param ciphertext: ciphertext bytes to be decrypted. + * :param nbytes: number of plaintext/ciphertext bytes. + * :param plaintext: plaintext output buffer, nbytes in length. + * :param tag: authentication tag output buffer. + */ +int cf_chacha20poly1305_decrypt(const uint8_t key[32], + const uint8_t nonce[12], + const uint8_t *header, size_t nheader, + const uint8_t *ciphertext, size_t nbytes, + const uint8_t tag[16], + uint8_t *plaintext); + +#endif diff --git a/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/chash.c b/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/chash.c new file mode 100644 index 00000000..4ee5d76e --- /dev/null +++ b/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/chash.c @@ -0,0 +1,28 @@ +/* + * cifra - embedded cryptography library + * Written in 2014 by Joseph Birr-Pixton + * + * To the extent possible under law, the author(s) have dedicated all + * copyright and related and neighboring rights to this software to the + * public domain worldwide. This software is distributed without any + * warranty. + * + * You should have received a copy of the CC0 Public Domain Dedication + * along with this software. If not, see + * . + */ + +#include "chash.h" +#include "handy.h" +#include "tassert.h" + +void cf_hash(const cf_chash *h, const void *m, size_t nm, uint8_t *out) +{ + cf_chash_ctx ctx; + assert(h); + h->init(&ctx); + h->update(&ctx, m, nm); + h->digest(&ctx, out); + mem_clean(&ctx, sizeof ctx); +} + diff --git a/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/chash.h b/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/chash.h new file mode 100644 index 00000000..8f2e2012 --- /dev/null +++ b/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/chash.h @@ -0,0 +1,137 @@ +/* + * cifra - embedded cryptography library + * Written in 2014 by Joseph Birr-Pixton + * + * To the extent possible under law, the author(s) have dedicated all + * copyright and related and neighboring rights to this software to the + * public domain worldwide. This software is distributed without any + * warranty. + * + * You should have received a copy of the CC0 Public Domain Dedication + * along with this software. If not, see + * . + */ + +#ifndef CHASH_H +#define CHASH_H + +#include +#include + +/** + * General hash function description + * ================================= + * This allows us to make use of hash functions without depending + * on a specific one. This is useful in implementing, for example, + * :doc:`HMAC `. + */ + +/* .. c:type:: cf_chash_init + * Hashing initialisation function type. + * + * Functions of this type should initialise the context in preparation + * for hashing a message with `cf_chash_update` functions. + * + * :rtype: void + * :param ctx: hash function-specific context structure. + */ +typedef void (*cf_chash_init)(void *ctx); + +/* .. c:type:: cf_chash_update + * Hashing data processing function type. + * + * Functions of this type hash `count` bytes of data at `data`, + * updating the contents of `ctx`. + * + * :rtype: void + * :param ctx: hash function-specific context structure. + * :param data: input data to hash. + * :param count: number of bytes to hash. + */ +typedef void (*cf_chash_update)(void *ctx, const void *data, size_t count); + +/* .. c:type:: cf_chash_digest + * Hashing completion function type. + * + * Functions of this type complete a hashing operation, + * writing :c:member:`cf_chash.hashsz` bytes to `hash`. + * + * This function does not change `ctx` -- any padding which needs doing + * must be done seperately (in a copy of `ctx`, say). + * + * This means you can interlave `_update` and `_digest` calls to + * learn `H(A)` and `H(A || B)` without hashing `A` twice. + * + * :rtype: void + * :param ctx: hash function-specific context structure. + * :param hash: location to write hash result. + */ +typedef void (*cf_chash_digest)(const void *ctx, uint8_t *hash); + +/* .. c:type:: cf_chash + * This type describes an incremental hash function in an abstract way. + * + * .. c:member:: cf_chash.hashsz + * The hash function's output, in bytes. + * + * .. c:member:: cf_chash.blocksz + * The hash function's internal block size, in bytes. + * + * .. c:member:: cf_chash.init + * Context initialisation function. + * + * .. c:member:: cf_chash:update + * Data processing function. + * + * .. c:member:: cf_chash:digest + * Completion function. + * + */ +typedef struct +{ + size_t hashsz; + size_t blocksz; + + cf_chash_init init; + cf_chash_update update; + cf_chash_digest digest; +} cf_chash; + +/* .. c:macro:: CF_CHASH_MAXCTX + * The maximum size of a :c:type:`cf_chash_ctx`. This allows + * use to put a structure in automatic storage that can + * store working data for any supported hash function. */ +#define CF_CHASH_MAXCTX 360 + +/* .. c:macro:: CF_CHASH_MAXBLK + * Maximum hash function block size (in bytes). */ +#define CF_CHASH_MAXBLK 128 + +/* .. c:macro:: CF_MAXHASH + * Maximum hash function output (in bytes). */ +#define CF_MAXHASH 64 + +/* .. c:type:: cf_chash_ctx + * A type usable with any `cf_chash` as a context. */ +typedef union +{ + uint8_t ctx[CF_CHASH_MAXCTX]; + uint16_t u16; + uint32_t u32; + uint64_t u64; +} cf_chash_ctx; + +/* .. c:function:: $DECL + * One shot hashing: `out = h(m)`. + * + * Using the hash function `h`, `nm` bytes at `m` are hashed and `h->hashsz` bytes + * of result is written to the buffer `out`. + * + * :param h: hash function description. + * :param m: message buffer. + * :param nm: message length. + * :param out: hash result buffer (written). + */ +void cf_hash(const cf_chash *h, const void *m, size_t nm, uint8_t *out); + +#endif diff --git a/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/cmac.c b/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/cmac.c new file mode 100644 index 00000000..51f5843f --- /dev/null +++ b/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/cmac.c @@ -0,0 +1,150 @@ +/* + * cifra - embedded cryptography library + * Written in 2014 by Joseph Birr-Pixton + * + * To the extent possible under law, the author(s) have dedicated all + * copyright and related and neighboring rights to this software to the + * public domain worldwide. This software is distributed without any + * warranty. + * + * You should have received a copy of the CC0 Public Domain Dedication + * along with this software. If not, see + * . + */ + +#include "handy.h" +#include "prp.h" +#include "modes.h" +#include "bitops.h" +#include "blockwise.h" +#include "gf128.h" +#include "tassert.h" + +#include + +void cf_cmac_init(cf_cmac *ctx, const cf_prp *prp, void *prpctx) +{ + uint8_t L[CF_MAXBLOCK]; + assert(prp->blocksz == 16); + + mem_clean(ctx, sizeof *ctx); + + /* L = E_K(0^n) */ + mem_clean(L, prp->blocksz); + prp->encrypt(prpctx, L, L); + + /* B = 2L */ + cf_gf128 gf; + cf_gf128_frombytes_be(L, gf); + cf_gf128_double(gf, gf); + cf_gf128_tobytes_be(gf, ctx->B); + + /* P = 4L */ + cf_gf128_double(gf, gf); + cf_gf128_tobytes_be(gf, ctx->P); + + ctx->prp = prp; + ctx->prpctx = prpctx; +} + +void cf_cmac_sign(cf_cmac *ctx, const uint8_t *data, size_t len, uint8_t out[CF_MAXBLOCK]) +{ + cf_cmac_stream stream; + stream.cmac = *ctx; + cf_cmac_stream_reset(&stream); + cf_cmac_stream_update(&stream, data, len, 1); + cf_cmac_stream_final(&stream, out); +} + +void cf_cmac_stream_init(cf_cmac_stream *ctx, const cf_prp *prp, void *prpctx) +{ + cf_cmac_init(&ctx->cmac, prp, prpctx); + cf_cmac_stream_reset(ctx); +} + +void cf_cmac_stream_reset(cf_cmac_stream *ctx) +{ + uint8_t iv_zero[CF_MAXBLOCK] = { 0 }; + cf_cbc_init(&ctx->cbc, ctx->cmac.prp, ctx->cmac.prpctx, iv_zero); + mem_clean(ctx->buffer, sizeof ctx->buffer); + ctx->used = 0; + ctx->processed = 0; + ctx->finalised = 0; +} + +static void cmac_process(void *vctx, const uint8_t *block) +{ + cf_cmac_stream *ctx = vctx; + uint8_t output[CF_MAXBLOCK]; + cf_cbc_encrypt(&ctx->cbc, block, output, 1); + ctx->processed += ctx->cmac.prp->blocksz; +} + +static void cmac_process_final(cf_cmac_stream *ctx, const uint8_t *block, + const uint8_t *xor) +{ + uint8_t input[CF_MAXBLOCK]; + uint8_t output[CF_MAXBLOCK]; + xor_bb(input, block, xor, ctx->cmac.prp->blocksz); + cf_cbc_encrypt(&ctx->cbc, input, output, 1); + ctx->processed += ctx->cmac.prp->blocksz; + /* signature is in ctx->cbc.block. */ +} + +static void cmac_process_final_nopad(void *vctx, const uint8_t *block) +{ + cf_cmac_stream *ctx = vctx; + cmac_process_final(ctx, block, ctx->cmac.B); + ctx->finalised = 1; +} + +static void cmac_process_final_pad(void *vctx, const uint8_t *block) +{ + cf_cmac_stream *ctx = vctx; + cmac_process_final(ctx, block, ctx->cmac.P); + ctx->finalised = 1; +} + +void cf_cmac_stream_update(cf_cmac_stream *ctx, const uint8_t *data, size_t len, int isfinal) +{ + size_t blocksz = ctx->cmac.prp->blocksz; + cf_blockwise_in_fn final_fn = cmac_process; + int needpad = 0; + + if (isfinal) + { + int whole_number_of_blocks = ((len + ctx->used) & 0xf) == 0; + int empty_message = len == 0 && ctx->used == 0 && ctx->processed == 0; + + assert(!ctx->finalised); /* finalised before? */ + assert(len != 0 || empty_message); /* we can't be told we're done after the fact. */ + + /* If we have a whole number of blocks, and at least 1 block, we XOR in B. + * Otherwise, we need to pad and XOR in P. */ + if (whole_number_of_blocks && !empty_message) + final_fn = cmac_process_final_nopad; + else + needpad = 1; + } + + /* Input data */ + cf_blockwise_accumulate_final(ctx->buffer, &ctx->used, blocksz, + data, len, + cmac_process, + final_fn, ctx); + + /* Input padding */ + if (needpad) + { + cf_blockwise_acc_pad(ctx->buffer, &ctx->used, blocksz, + 0x80, 0x00, 0x00, blocksz - ctx->used, + cmac_process_final_pad, ctx); + } +} + +void cf_cmac_stream_final(cf_cmac_stream *ctx, uint8_t out[CF_MAXBLOCK]) +{ + assert(ctx->finalised); + memcpy(out, ctx->cbc.block, ctx->cmac.prp->blocksz); +} + diff --git a/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/curve25519.c b/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/curve25519.c new file mode 100644 index 00000000..6c4b9c15 --- /dev/null +++ b/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/curve25519.c @@ -0,0 +1,29 @@ +/* + * cifra - embedded cryptography library + * Written in 2014 by Joseph Birr-Pixton + * + * To the extent possible under law, the author(s) have dedicated all + * copyright and related and neighboring rights to this software to the + * public domain worldwide. This software is distributed without any + * warranty. + * + * You should have received a copy of the CC0 Public Domain Dedication + * along with this software. If not, see + * . + */ + +#if defined(CORTEX_M0) || defined(CORTEX_M3) || defined(CORTEX_M4) +#include "arm/unacl/scalarmult.c" + +void cf_curve25519_mul(uint8_t out[32], const uint8_t scalar[32], const uint8_t point[32]) +{ + crypto_scalarmult_curve25519(out, scalar, point); +} + +void cf_curve25519_mul_base(uint8_t out[32], const uint8_t scalar[32]) +{ + crypto_scalarmult_curve25519_base(out, scalar); +} +#else +#include "curve25519.tweetnacl.c" +#endif diff --git a/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/curve25519.donna.c b/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/curve25519.donna.c new file mode 100644 index 00000000..3c597d37 --- /dev/null +++ b/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/curve25519.donna.c @@ -0,0 +1,867 @@ +/* Copyright 2008, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * curve25519-donna: Curve25519 elliptic curve, public key function + * + * http://code.google.com/p/curve25519-donna/ + * + * Adam Langley + * + * Derived from public domain C code by Daniel J. Bernstein + * + * More information about curve25519 can be found here + * http://cr.yp.to/ecdh.html + * + * djb's sample implementation of curve25519 is written in a special assembly + * language called qhasm and uses the floating point registers. + * + * This is, almost, a clean room reimplementation from the curve25519 paper. It + * uses many of the tricks described therein. Only the crecip function is taken + * from the sample implementation. */ + +#include "curve25519.h" + +#include +#include + +#ifdef _MSC_VER +#define inline __inline +#endif + +typedef uint8_t u8; +typedef int32_t s32; +typedef int64_t limb; + +/* Field element representation: + * + * Field elements are written as an array of signed, 64-bit limbs, least + * significant first. The value of the field element is: + * x[0] + 2^26·x[1] + x^51·x[2] + 2^102·x[3] + ... + * + * i.e. the limbs are 26, 25, 26, 25, ... bits wide. */ + +/* Sum two numbers: output += in */ +static void fsum(limb *output, const limb *in) { + unsigned i; + for (i = 0; i < 10; i += 2) { + output[0+i] = output[0+i] + in[0+i]; + output[1+i] = output[1+i] + in[1+i]; + } +} + +/* Find the difference of two numbers: output = in - output + * (note the order of the arguments!). */ +static void fdifference(limb *output, const limb *in) { + unsigned i; + for (i = 0; i < 10; ++i) { + output[i] = in[i] - output[i]; + } +} + +/* Multiply a number by a scalar: output = in * scalar */ +static void fscalar_product(limb *output, const limb *in, const limb scalar) { + unsigned i; + for (i = 0; i < 10; ++i) { + output[i] = in[i] * scalar; + } +} + +/* Multiply two numbers: output = in2 * in + * + * output must be distinct to both inputs. The inputs are reduced coefficient + * form, the output is not. + * + * output[x] <= 14 * the largest product of the input limbs. */ +static void fproduct(limb *output, const limb *in2, const limb *in) { + output[0] = ((limb) ((s32) in2[0])) * ((s32) in[0]); + output[1] = ((limb) ((s32) in2[0])) * ((s32) in[1]) + + ((limb) ((s32) in2[1])) * ((s32) in[0]); + output[2] = 2 * ((limb) ((s32) in2[1])) * ((s32) in[1]) + + ((limb) ((s32) in2[0])) * ((s32) in[2]) + + ((limb) ((s32) in2[2])) * ((s32) in[0]); + output[3] = ((limb) ((s32) in2[1])) * ((s32) in[2]) + + ((limb) ((s32) in2[2])) * ((s32) in[1]) + + ((limb) ((s32) in2[0])) * ((s32) in[3]) + + ((limb) ((s32) in2[3])) * ((s32) in[0]); + output[4] = ((limb) ((s32) in2[2])) * ((s32) in[2]) + + 2 * (((limb) ((s32) in2[1])) * ((s32) in[3]) + + ((limb) ((s32) in2[3])) * ((s32) in[1])) + + ((limb) ((s32) in2[0])) * ((s32) in[4]) + + ((limb) ((s32) in2[4])) * ((s32) in[0]); + output[5] = ((limb) ((s32) in2[2])) * ((s32) in[3]) + + ((limb) ((s32) in2[3])) * ((s32) in[2]) + + ((limb) ((s32) in2[1])) * ((s32) in[4]) + + ((limb) ((s32) in2[4])) * ((s32) in[1]) + + ((limb) ((s32) in2[0])) * ((s32) in[5]) + + ((limb) ((s32) in2[5])) * ((s32) in[0]); + output[6] = 2 * (((limb) ((s32) in2[3])) * ((s32) in[3]) + + ((limb) ((s32) in2[1])) * ((s32) in[5]) + + ((limb) ((s32) in2[5])) * ((s32) in[1])) + + ((limb) ((s32) in2[2])) * ((s32) in[4]) + + ((limb) ((s32) in2[4])) * ((s32) in[2]) + + ((limb) ((s32) in2[0])) * ((s32) in[6]) + + ((limb) ((s32) in2[6])) * ((s32) in[0]); + output[7] = ((limb) ((s32) in2[3])) * ((s32) in[4]) + + ((limb) ((s32) in2[4])) * ((s32) in[3]) + + ((limb) ((s32) in2[2])) * ((s32) in[5]) + + ((limb) ((s32) in2[5])) * ((s32) in[2]) + + ((limb) ((s32) in2[1])) * ((s32) in[6]) + + ((limb) ((s32) in2[6])) * ((s32) in[1]) + + ((limb) ((s32) in2[0])) * ((s32) in[7]) + + ((limb) ((s32) in2[7])) * ((s32) in[0]); + output[8] = ((limb) ((s32) in2[4])) * ((s32) in[4]) + + 2 * (((limb) ((s32) in2[3])) * ((s32) in[5]) + + ((limb) ((s32) in2[5])) * ((s32) in[3]) + + ((limb) ((s32) in2[1])) * ((s32) in[7]) + + ((limb) ((s32) in2[7])) * ((s32) in[1])) + + ((limb) ((s32) in2[2])) * ((s32) in[6]) + + ((limb) ((s32) in2[6])) * ((s32) in[2]) + + ((limb) ((s32) in2[0])) * ((s32) in[8]) + + ((limb) ((s32) in2[8])) * ((s32) in[0]); + output[9] = ((limb) ((s32) in2[4])) * ((s32) in[5]) + + ((limb) ((s32) in2[5])) * ((s32) in[4]) + + ((limb) ((s32) in2[3])) * ((s32) in[6]) + + ((limb) ((s32) in2[6])) * ((s32) in[3]) + + ((limb) ((s32) in2[2])) * ((s32) in[7]) + + ((limb) ((s32) in2[7])) * ((s32) in[2]) + + ((limb) ((s32) in2[1])) * ((s32) in[8]) + + ((limb) ((s32) in2[8])) * ((s32) in[1]) + + ((limb) ((s32) in2[0])) * ((s32) in[9]) + + ((limb) ((s32) in2[9])) * ((s32) in[0]); + output[10] = 2 * (((limb) ((s32) in2[5])) * ((s32) in[5]) + + ((limb) ((s32) in2[3])) * ((s32) in[7]) + + ((limb) ((s32) in2[7])) * ((s32) in[3]) + + ((limb) ((s32) in2[1])) * ((s32) in[9]) + + ((limb) ((s32) in2[9])) * ((s32) in[1])) + + ((limb) ((s32) in2[4])) * ((s32) in[6]) + + ((limb) ((s32) in2[6])) * ((s32) in[4]) + + ((limb) ((s32) in2[2])) * ((s32) in[8]) + + ((limb) ((s32) in2[8])) * ((s32) in[2]); + output[11] = ((limb) ((s32) in2[5])) * ((s32) in[6]) + + ((limb) ((s32) in2[6])) * ((s32) in[5]) + + ((limb) ((s32) in2[4])) * ((s32) in[7]) + + ((limb) ((s32) in2[7])) * ((s32) in[4]) + + ((limb) ((s32) in2[3])) * ((s32) in[8]) + + ((limb) ((s32) in2[8])) * ((s32) in[3]) + + ((limb) ((s32) in2[2])) * ((s32) in[9]) + + ((limb) ((s32) in2[9])) * ((s32) in[2]); + output[12] = ((limb) ((s32) in2[6])) * ((s32) in[6]) + + 2 * (((limb) ((s32) in2[5])) * ((s32) in[7]) + + ((limb) ((s32) in2[7])) * ((s32) in[5]) + + ((limb) ((s32) in2[3])) * ((s32) in[9]) + + ((limb) ((s32) in2[9])) * ((s32) in[3])) + + ((limb) ((s32) in2[4])) * ((s32) in[8]) + + ((limb) ((s32) in2[8])) * ((s32) in[4]); + output[13] = ((limb) ((s32) in2[6])) * ((s32) in[7]) + + ((limb) ((s32) in2[7])) * ((s32) in[6]) + + ((limb) ((s32) in2[5])) * ((s32) in[8]) + + ((limb) ((s32) in2[8])) * ((s32) in[5]) + + ((limb) ((s32) in2[4])) * ((s32) in[9]) + + ((limb) ((s32) in2[9])) * ((s32) in[4]); + output[14] = 2 * (((limb) ((s32) in2[7])) * ((s32) in[7]) + + ((limb) ((s32) in2[5])) * ((s32) in[9]) + + ((limb) ((s32) in2[9])) * ((s32) in[5])) + + ((limb) ((s32) in2[6])) * ((s32) in[8]) + + ((limb) ((s32) in2[8])) * ((s32) in[6]); + output[15] = ((limb) ((s32) in2[7])) * ((s32) in[8]) + + ((limb) ((s32) in2[8])) * ((s32) in[7]) + + ((limb) ((s32) in2[6])) * ((s32) in[9]) + + ((limb) ((s32) in2[9])) * ((s32) in[6]); + output[16] = ((limb) ((s32) in2[8])) * ((s32) in[8]) + + 2 * (((limb) ((s32) in2[7])) * ((s32) in[9]) + + ((limb) ((s32) in2[9])) * ((s32) in[7])); + output[17] = ((limb) ((s32) in2[8])) * ((s32) in[9]) + + ((limb) ((s32) in2[9])) * ((s32) in[8]); + output[18] = 2 * ((limb) ((s32) in2[9])) * ((s32) in[9]); +} + +/* Reduce a long form to a short form by taking the input mod 2^255 - 19. + * + * On entry: |output[i]| < 14*2^54 + * On exit: |output[0..8]| < 280*2^54 */ +static void freduce_degree(limb *output) { + /* Each of these shifts and adds ends up multiplying the value by 19. + * + * For output[0..8], the absolute entry value is < 14*2^54 and we add, at + * most, 19*14*2^54 thus, on exit, |output[0..8]| < 280*2^54. */ + output[8] += output[18] << 4; + output[8] += output[18] << 1; + output[8] += output[18]; + output[7] += output[17] << 4; + output[7] += output[17] << 1; + output[7] += output[17]; + output[6] += output[16] << 4; + output[6] += output[16] << 1; + output[6] += output[16]; + output[5] += output[15] << 4; + output[5] += output[15] << 1; + output[5] += output[15]; + output[4] += output[14] << 4; + output[4] += output[14] << 1; + output[4] += output[14]; + output[3] += output[13] << 4; + output[3] += output[13] << 1; + output[3] += output[13]; + output[2] += output[12] << 4; + output[2] += output[12] << 1; + output[2] += output[12]; + output[1] += output[11] << 4; + output[1] += output[11] << 1; + output[1] += output[11]; + output[0] += output[10] << 4; + output[0] += output[10] << 1; + output[0] += output[10]; +} + +#if (-1 & 3) != 3 +#error "This code only works on a two's complement system" +#endif + +/* return v / 2^26, using only shifts and adds. + * + * On entry: v can take any value. */ +static inline limb +div_by_2_26(const limb v) +{ + /* High word of v; no shift needed. */ + const uint32_t highword = (uint32_t) (((uint64_t) v) >> 32); + /* Set to all 1s if v was negative; else set to 0s. */ + const int32_t sign = ((int32_t) highword) >> 31; + /* Set to 0x3ffffff if v was negative; else set to 0. */ + const int32_t roundoff = ((uint32_t) sign) >> 6; + /* Should return v / (1<<26) */ + return (v + roundoff) >> 26; +} + +/* return v / (2^25), using only shifts and adds. + * + * On entry: v can take any value. */ +static inline limb +div_by_2_25(const limb v) +{ + /* High word of v; no shift needed*/ + const uint32_t highword = (uint32_t) (((uint64_t) v) >> 32); + /* Set to all 1s if v was negative; else set to 0s. */ + const int32_t sign = ((int32_t) highword) >> 31; + /* Set to 0x1ffffff if v was negative; else set to 0. */ + const int32_t roundoff = ((uint32_t) sign) >> 7; + /* Should return v / (1<<25) */ + return (v + roundoff) >> 25; +} + +/* Reduce all coefficients of the short form input so that |x| < 2^26. + * + * On entry: |output[i]| < 280*2^54 */ +static void freduce_coefficients(limb *output) { + unsigned i; + + output[10] = 0; + + for (i = 0; i < 10; i += 2) { + limb over = div_by_2_26(output[i]); + /* The entry condition (that |output[i]| < 280*2^54) means that over is, at + * most, 280*2^28 in the first iteration of this loop. This is added to the + * next limb and we can approximate the resulting bound of that limb by + * 281*2^54. */ + output[i] -= over << 26; + output[i+1] += over; + + /* For the first iteration, |output[i+1]| < 281*2^54, thus |over| < + * 281*2^29. When this is added to the next limb, the resulting bound can + * be approximated as 281*2^54. + * + * For subsequent iterations of the loop, 281*2^54 remains a conservative + * bound and no overflow occurs. */ + over = div_by_2_25(output[i+1]); + output[i+1] -= over << 25; + output[i+2] += over; + } + /* Now |output[10]| < 281*2^29 and all other coefficients are reduced. */ + output[0] += output[10] << 4; + output[0] += output[10] << 1; + output[0] += output[10]; + + output[10] = 0; + + /* Now output[1..9] are reduced, and |output[0]| < 2^26 + 19*281*2^29 + * So |over| will be no more than 2^16. */ + { + limb over = div_by_2_26(output[0]); + output[0] -= over << 26; + output[1] += over; + } + + /* Now output[0,2..9] are reduced, and |output[1]| < 2^25 + 2^16 < 2^26. The + * bound on |output[1]| is sufficient to meet our needs. */ +} + +/* A helpful wrapper around fproduct: output = in * in2. + * + * On entry: |in[i]| < 2^27 and |in2[i]| < 2^27. + * + * output must be distinct to both inputs. The output is reduced degree + * (indeed, one need only provide storage for 10 limbs) and |output[i]| < 2^26. */ +static void +fmul(limb *output, const limb *in, const limb *in2) { + limb t[19]; + fproduct(t, in, in2); + /* |t[i]| < 14*2^54 */ + freduce_degree(t); + freduce_coefficients(t); + /* |t[i]| < 2^26 */ + memcpy(output, t, sizeof(limb) * 10); +} + +/* Square a number: output = in**2 + * + * output must be distinct from the input. The inputs are reduced coefficient + * form, the output is not. + * + * output[x] <= 14 * the largest product of the input limbs. */ +static void fsquare_inner(limb *output, const limb *in) { + output[0] = ((limb) ((s32) in[0])) * ((s32) in[0]); + output[1] = 2 * ((limb) ((s32) in[0])) * ((s32) in[1]); + output[2] = 2 * (((limb) ((s32) in[1])) * ((s32) in[1]) + + ((limb) ((s32) in[0])) * ((s32) in[2])); + output[3] = 2 * (((limb) ((s32) in[1])) * ((s32) in[2]) + + ((limb) ((s32) in[0])) * ((s32) in[3])); + output[4] = ((limb) ((s32) in[2])) * ((s32) in[2]) + + 4 * ((limb) ((s32) in[1])) * ((s32) in[3]) + + 2 * ((limb) ((s32) in[0])) * ((s32) in[4]); + output[5] = 2 * (((limb) ((s32) in[2])) * ((s32) in[3]) + + ((limb) ((s32) in[1])) * ((s32) in[4]) + + ((limb) ((s32) in[0])) * ((s32) in[5])); + output[6] = 2 * (((limb) ((s32) in[3])) * ((s32) in[3]) + + ((limb) ((s32) in[2])) * ((s32) in[4]) + + ((limb) ((s32) in[0])) * ((s32) in[6]) + + 2 * ((limb) ((s32) in[1])) * ((s32) in[5])); + output[7] = 2 * (((limb) ((s32) in[3])) * ((s32) in[4]) + + ((limb) ((s32) in[2])) * ((s32) in[5]) + + ((limb) ((s32) in[1])) * ((s32) in[6]) + + ((limb) ((s32) in[0])) * ((s32) in[7])); + output[8] = ((limb) ((s32) in[4])) * ((s32) in[4]) + + 2 * (((limb) ((s32) in[2])) * ((s32) in[6]) + + ((limb) ((s32) in[0])) * ((s32) in[8]) + + 2 * (((limb) ((s32) in[1])) * ((s32) in[7]) + + ((limb) ((s32) in[3])) * ((s32) in[5]))); + output[9] = 2 * (((limb) ((s32) in[4])) * ((s32) in[5]) + + ((limb) ((s32) in[3])) * ((s32) in[6]) + + ((limb) ((s32) in[2])) * ((s32) in[7]) + + ((limb) ((s32) in[1])) * ((s32) in[8]) + + ((limb) ((s32) in[0])) * ((s32) in[9])); + output[10] = 2 * (((limb) ((s32) in[5])) * ((s32) in[5]) + + ((limb) ((s32) in[4])) * ((s32) in[6]) + + ((limb) ((s32) in[2])) * ((s32) in[8]) + + 2 * (((limb) ((s32) in[3])) * ((s32) in[7]) + + ((limb) ((s32) in[1])) * ((s32) in[9]))); + output[11] = 2 * (((limb) ((s32) in[5])) * ((s32) in[6]) + + ((limb) ((s32) in[4])) * ((s32) in[7]) + + ((limb) ((s32) in[3])) * ((s32) in[8]) + + ((limb) ((s32) in[2])) * ((s32) in[9])); + output[12] = ((limb) ((s32) in[6])) * ((s32) in[6]) + + 2 * (((limb) ((s32) in[4])) * ((s32) in[8]) + + 2 * (((limb) ((s32) in[5])) * ((s32) in[7]) + + ((limb) ((s32) in[3])) * ((s32) in[9]))); + output[13] = 2 * (((limb) ((s32) in[6])) * ((s32) in[7]) + + ((limb) ((s32) in[5])) * ((s32) in[8]) + + ((limb) ((s32) in[4])) * ((s32) in[9])); + output[14] = 2 * (((limb) ((s32) in[7])) * ((s32) in[7]) + + ((limb) ((s32) in[6])) * ((s32) in[8]) + + 2 * ((limb) ((s32) in[5])) * ((s32) in[9])); + output[15] = 2 * (((limb) ((s32) in[7])) * ((s32) in[8]) + + ((limb) ((s32) in[6])) * ((s32) in[9])); + output[16] = ((limb) ((s32) in[8])) * ((s32) in[8]) + + 4 * ((limb) ((s32) in[7])) * ((s32) in[9]); + output[17] = 2 * ((limb) ((s32) in[8])) * ((s32) in[9]); + output[18] = 2 * ((limb) ((s32) in[9])) * ((s32) in[9]); +} + +/* fsquare sets output = in^2. + * + * On entry: The |in| argument is in reduced coefficients form and |in[i]| < + * 2^27. + * + * On exit: The |output| argument is in reduced coefficients form (indeed, one + * need only provide storage for 10 limbs) and |out[i]| < 2^26. */ +static void +fsquare(limb *output, const limb *in) { + limb t[19]; + fsquare_inner(t, in); + /* |t[i]| < 14*2^54 because the largest product of two limbs will be < + * 2^(27+27) and fsquare_inner adds together, at most, 14 of those + * products. */ + freduce_degree(t); + freduce_coefficients(t); + /* |t[i]| < 2^26 */ + memcpy(output, t, sizeof(limb) * 10); +} + +/* Take a little-endian, 32-byte number and expand it into polynomial form */ +static void +fexpand(limb *output, const u8 *input) { +#define F(n,start,shift,mask) \ + output[n] = ((((limb) input[start + 0]) | \ + ((limb) input[start + 1]) << 8 | \ + ((limb) input[start + 2]) << 16 | \ + ((limb) input[start + 3]) << 24) >> shift) & mask; + F(0, 0, 0, 0x3ffffff); + F(1, 3, 2, 0x1ffffff); + F(2, 6, 3, 0x3ffffff); + F(3, 9, 5, 0x1ffffff); + F(4, 12, 6, 0x3ffffff); + F(5, 16, 0, 0x1ffffff); + F(6, 19, 1, 0x3ffffff); + F(7, 22, 3, 0x1ffffff); + F(8, 25, 4, 0x3ffffff); + F(9, 28, 6, 0x1ffffff); +#undef F +} + +#if (-32 >> 1) != -16 +#error "This code only works when >> does sign-extension on negative numbers" +#endif + +/* s32_eq returns 0xffffffff iff a == b and zero otherwise. */ +static s32 s32_eq(s32 a, s32 b) { + a = ~(a ^ b); + a &= a << 16; + a &= a << 8; + a &= a << 4; + a &= a << 2; + a &= a << 1; + return a >> 31; +} + +/* s32_gte returns 0xffffffff if a >= b and zero otherwise, where a and b are + * both non-negative. */ +static s32 s32_gte(s32 a, s32 b) { + a -= b; + /* a >= 0 iff a >= b. */ + return ~(a >> 31); +} + +/* Take a fully reduced polynomial form number and contract it into a + * little-endian, 32-byte array. + * + * On entry: |input_limbs[i]| < 2^26 */ +static void +fcontract(u8 *output, limb *input_limbs) { + int i; + int j; + s32 input[10]; + s32 mask; + + /* |input_limbs[i]| < 2^26, so it's valid to convert to an s32. */ + for (i = 0; i < 10; i++) { + input[i] = input_limbs[i]; + } + + for (j = 0; j < 2; ++j) { + for (i = 0; i < 9; ++i) { + if ((i & 1) == 1) { + /* This calculation is a time-invariant way to make input[i] + * non-negative by borrowing from the next-larger limb. */ + const s32 mask = input[i] >> 31; + const s32 carry = -((input[i] & mask) >> 25); + input[i] = input[i] + (carry << 25); + input[i+1] = input[i+1] - carry; + } else { + const s32 mask = input[i] >> 31; + const s32 carry = -((input[i] & mask) >> 26); + input[i] = input[i] + (carry << 26); + input[i+1] = input[i+1] - carry; + } + } + + /* There's no greater limb for input[9] to borrow from, but we can multiply + * by 19 and borrow from input[0], which is valid mod 2^255-19. */ + { + const s32 mask = input[9] >> 31; + const s32 carry = -((input[9] & mask) >> 25); + input[9] = input[9] + (carry << 25); + input[0] = input[0] - (carry * 19); + } + + /* After the first iteration, input[1..9] are non-negative and fit within + * 25 or 26 bits, depending on position. However, input[0] may be + * negative. */ + } + + /* The first borrow-propagation pass above ended with every limb + except (possibly) input[0] non-negative. + + If input[0] was negative after the first pass, then it was because of a + carry from input[9]. On entry, input[9] < 2^26 so the carry was, at most, + one, since (2**26-1) >> 25 = 1. Thus input[0] >= -19. + + In the second pass, each limb is decreased by at most one. Thus the second + borrow-propagation pass could only have wrapped around to decrease + input[0] again if the first pass left input[0] negative *and* input[1] + through input[9] were all zero. In that case, input[1] is now 2^25 - 1, + and this last borrow-propagation step will leave input[1] non-negative. */ + { + const s32 mask = input[0] >> 31; + const s32 carry = -((input[0] & mask) >> 26); + input[0] = input[0] + (carry << 26); + input[1] = input[1] - carry; + } + + /* All input[i] are now non-negative. However, there might be values between + * 2^25 and 2^26 in a limb which is, nominally, 25 bits wide. */ + for (j = 0; j < 2; j++) { + for (i = 0; i < 9; i++) { + if ((i & 1) == 1) { + const s32 carry = input[i] >> 25; + input[i] &= 0x1ffffff; + input[i+1] += carry; + } else { + const s32 carry = input[i] >> 26; + input[i] &= 0x3ffffff; + input[i+1] += carry; + } + } + + { + const s32 carry = input[9] >> 25; + input[9] &= 0x1ffffff; + input[0] += 19*carry; + } + } + + /* If the first carry-chain pass, just above, ended up with a carry from + * input[9], and that caused input[0] to be out-of-bounds, then input[0] was + * < 2^26 + 2*19, because the carry was, at most, two. + * + * If the second pass carried from input[9] again then input[0] is < 2*19 and + * the input[9] -> input[0] carry didn't push input[0] out of bounds. */ + + /* It still remains the case that input might be between 2^255-19 and 2^255. + * In this case, input[1..9] must take their maximum value and input[0] must + * be >= (2^255-19) & 0x3ffffff, which is 0x3ffffed. */ + mask = s32_gte(input[0], 0x3ffffed); + for (i = 1; i < 10; i++) { + if ((i & 1) == 1) { + mask &= s32_eq(input[i], 0x1ffffff); + } else { + mask &= s32_eq(input[i], 0x3ffffff); + } + } + + /* mask is either 0xffffffff (if input >= 2^255-19) and zero otherwise. Thus + * this conditionally subtracts 2^255-19. */ + input[0] -= mask & 0x3ffffed; + + for (i = 1; i < 10; i++) { + if ((i & 1) == 1) { + input[i] -= mask & 0x1ffffff; + } else { + input[i] -= mask & 0x3ffffff; + } + } + + input[1] <<= 2; + input[2] <<= 3; + input[3] <<= 5; + input[4] <<= 6; + input[6] <<= 1; + input[7] <<= 3; + input[8] <<= 4; + input[9] <<= 6; +#define F(i, s) \ + output[s+0] |= input[i] & 0xff; \ + output[s+1] = (input[i] >> 8) & 0xff; \ + output[s+2] = (input[i] >> 16) & 0xff; \ + output[s+3] = (input[i] >> 24) & 0xff; + output[0] = 0; + output[16] = 0; + F(0,0); + F(1,3); + F(2,6); + F(3,9); + F(4,12); + F(5,16); + F(6,19); + F(7,22); + F(8,25); + F(9,28); +#undef F +} + +/* Input: Q, Q', Q-Q' + * Output: 2Q, Q+Q' + * + * x2 z3: long form + * x3 z3: long form + * x z: short form, destroyed + * xprime zprime: short form, destroyed + * qmqp: short form, preserved + * + * On entry and exit, the absolute value of the limbs of all inputs and outputs + * are < 2^26. */ +static void fmonty(limb *x2, limb *z2, /* output 2Q */ + limb *x3, limb *z3, /* output Q + Q' */ + limb *x, limb *z, /* input Q */ + limb *xprime, limb *zprime, /* input Q' */ + const limb *qmqp /* input Q - Q' */) { + limb origx[10], origxprime[10], zzz[19], xx[19], zz[19], xxprime[19], + zzprime[19], zzzprime[19], xxxprime[19]; + + memcpy(origx, x, 10 * sizeof(limb)); + fsum(x, z); + /* |x[i]| < 2^27 */ + fdifference(z, origx); /* does x - z */ + /* |z[i]| < 2^27 */ + + memcpy(origxprime, xprime, sizeof(limb) * 10); + fsum(xprime, zprime); + /* |xprime[i]| < 2^27 */ + fdifference(zprime, origxprime); + /* |zprime[i]| < 2^27 */ + fproduct(xxprime, xprime, z); + /* |xxprime[i]| < 14*2^54: the largest product of two limbs will be < + * 2^(27+27) and fproduct adds together, at most, 14 of those products. + * (Approximating that to 2^58 doesn't work out.) */ + fproduct(zzprime, x, zprime); + /* |zzprime[i]| < 14*2^54 */ + freduce_degree(xxprime); + freduce_coefficients(xxprime); + /* |xxprime[i]| < 2^26 */ + freduce_degree(zzprime); + freduce_coefficients(zzprime); + /* |zzprime[i]| < 2^26 */ + memcpy(origxprime, xxprime, sizeof(limb) * 10); + fsum(xxprime, zzprime); + /* |xxprime[i]| < 2^27 */ + fdifference(zzprime, origxprime); + /* |zzprime[i]| < 2^27 */ + fsquare(xxxprime, xxprime); + /* |xxxprime[i]| < 2^26 */ + fsquare(zzzprime, zzprime); + /* |zzzprime[i]| < 2^26 */ + fproduct(zzprime, zzzprime, qmqp); + /* |zzprime[i]| < 14*2^52 */ + freduce_degree(zzprime); + freduce_coefficients(zzprime); + /* |zzprime[i]| < 2^26 */ + memcpy(x3, xxxprime, sizeof(limb) * 10); + memcpy(z3, zzprime, sizeof(limb) * 10); + + fsquare(xx, x); + /* |xx[i]| < 2^26 */ + fsquare(zz, z); + /* |zz[i]| < 2^26 */ + fproduct(x2, xx, zz); + /* |x2[i]| < 14*2^52 */ + freduce_degree(x2); + freduce_coefficients(x2); + /* |x2[i]| < 2^26 */ + fdifference(zz, xx); // does zz = xx - zz + /* |zz[i]| < 2^27 */ + memset(zzz + 10, 0, sizeof(limb) * 9); + fscalar_product(zzz, zz, 121665); + /* |zzz[i]| < 2^(27+17) */ + /* No need to call freduce_degree here: + fscalar_product doesn't increase the degree of its input. */ + freduce_coefficients(zzz); + /* |zzz[i]| < 2^26 */ + fsum(zzz, xx); + /* |zzz[i]| < 2^27 */ + fproduct(z2, zz, zzz); + /* |z2[i]| < 14*2^(26+27) */ + freduce_degree(z2); + freduce_coefficients(z2); + /* |z2|i| < 2^26 */ +} + +/* Conditionally swap two reduced-form limb arrays if 'iswap' is 1, but leave + * them unchanged if 'iswap' is 0. Runs in data-invariant time to avoid + * side-channel attacks. + * + * NOTE that this function requires that 'iswap' be 1 or 0; other values give + * wrong results. Also, the two limb arrays must be in reduced-coefficient, + * reduced-degree form: the values in a[10..19] or b[10..19] aren't swapped, + * and all all values in a[0..9],b[0..9] must have magnitude less than + * INT32_MAX. */ +static void +swap_conditional(limb a[19], limb b[19], limb iswap) { + unsigned i; + const s32 swap = (s32) -iswap; + + for (i = 0; i < 10; ++i) { + const s32 x = swap & ( ((s32)a[i]) ^ ((s32)b[i]) ); + a[i] = ((s32)a[i]) ^ x; + b[i] = ((s32)b[i]) ^ x; + } +} + +/* Calculates nQ where Q is the x-coordinate of a point on the curve + * + * resultx/resultz: the x coordinate of the resulting curve point (short form) + * n: a little endian, 32-byte number + * q: a point of the curve (short form) */ +static void +cmult(limb *resultx, limb *resultz, const u8 *n, const limb *q) { + limb a[19] = {0}, b[19] = {1}, c[19] = {1}, d[19] = {0}; + limb *nqpqx = a, *nqpqz = b, *nqx = c, *nqz = d, *t; + limb e[19] = {0}, f[19] = {1}, g[19] = {0}, h[19] = {1}; + limb *nqpqx2 = e, *nqpqz2 = f, *nqx2 = g, *nqz2 = h; + + unsigned i, j; + + memcpy(nqpqx, q, sizeof(limb) * 10); + + for (i = 0; i < 32; ++i) { + u8 byte = n[31 - i]; + for (j = 0; j < 8; ++j) { + const limb bit = byte >> 7; + + swap_conditional(nqx, nqpqx, bit); + swap_conditional(nqz, nqpqz, bit); + fmonty(nqx2, nqz2, + nqpqx2, nqpqz2, + nqx, nqz, + nqpqx, nqpqz, + q); + swap_conditional(nqx2, nqpqx2, bit); + swap_conditional(nqz2, nqpqz2, bit); + + t = nqx; + nqx = nqx2; + nqx2 = t; + t = nqz; + nqz = nqz2; + nqz2 = t; + t = nqpqx; + nqpqx = nqpqx2; + nqpqx2 = t; + t = nqpqz; + nqpqz = nqpqz2; + nqpqz2 = t; + + byte <<= 1; + } + } + + memcpy(resultx, nqx, sizeof(limb) * 10); + memcpy(resultz, nqz, sizeof(limb) * 10); +} + +// ----------------------------------------------------------------------------- +// Shamelessly copied from djb's code +// ----------------------------------------------------------------------------- +static void +crecip(limb *out, const limb *z) { + limb z2[10]; + limb z9[10]; + limb z11[10]; + limb z2_5_0[10]; + limb z2_10_0[10]; + limb z2_20_0[10]; + limb z2_50_0[10]; + limb z2_100_0[10]; + limb t0[10]; + limb t1[10]; + int i; + + /* 2 */ fsquare(z2,z); + /* 4 */ fsquare(t1,z2); + /* 8 */ fsquare(t0,t1); + /* 9 */ fmul(z9,t0,z); + /* 11 */ fmul(z11,z9,z2); + /* 22 */ fsquare(t0,z11); + /* 2^5 - 2^0 = 31 */ fmul(z2_5_0,t0,z9); + + /* 2^6 - 2^1 */ fsquare(t0,z2_5_0); + /* 2^7 - 2^2 */ fsquare(t1,t0); + /* 2^8 - 2^3 */ fsquare(t0,t1); + /* 2^9 - 2^4 */ fsquare(t1,t0); + /* 2^10 - 2^5 */ fsquare(t0,t1); + /* 2^10 - 2^0 */ fmul(z2_10_0,t0,z2_5_0); + + /* 2^11 - 2^1 */ fsquare(t0,z2_10_0); + /* 2^12 - 2^2 */ fsquare(t1,t0); + /* 2^20 - 2^10 */ for (i = 2;i < 10;i += 2) { fsquare(t0,t1); fsquare(t1,t0); } + /* 2^20 - 2^0 */ fmul(z2_20_0,t1,z2_10_0); + + /* 2^21 - 2^1 */ fsquare(t0,z2_20_0); + /* 2^22 - 2^2 */ fsquare(t1,t0); + /* 2^40 - 2^20 */ for (i = 2;i < 20;i += 2) { fsquare(t0,t1); fsquare(t1,t0); } + /* 2^40 - 2^0 */ fmul(t0,t1,z2_20_0); + + /* 2^41 - 2^1 */ fsquare(t1,t0); + /* 2^42 - 2^2 */ fsquare(t0,t1); + /* 2^50 - 2^10 */ for (i = 2;i < 10;i += 2) { fsquare(t1,t0); fsquare(t0,t1); } + /* 2^50 - 2^0 */ fmul(z2_50_0,t0,z2_10_0); + + /* 2^51 - 2^1 */ fsquare(t0,z2_50_0); + /* 2^52 - 2^2 */ fsquare(t1,t0); + /* 2^100 - 2^50 */ for (i = 2;i < 50;i += 2) { fsquare(t0,t1); fsquare(t1,t0); } + /* 2^100 - 2^0 */ fmul(z2_100_0,t1,z2_50_0); + + /* 2^101 - 2^1 */ fsquare(t1,z2_100_0); + /* 2^102 - 2^2 */ fsquare(t0,t1); + /* 2^200 - 2^100 */ for (i = 2;i < 100;i += 2) { fsquare(t1,t0); fsquare(t0,t1); } + /* 2^200 - 2^0 */ fmul(t1,t0,z2_100_0); + + /* 2^201 - 2^1 */ fsquare(t0,t1); + /* 2^202 - 2^2 */ fsquare(t1,t0); + /* 2^250 - 2^50 */ for (i = 2;i < 50;i += 2) { fsquare(t0,t1); fsquare(t1,t0); } + /* 2^250 - 2^0 */ fmul(t0,t1,z2_50_0); + + /* 2^251 - 2^1 */ fsquare(t1,t0); + /* 2^252 - 2^2 */ fsquare(t0,t1); + /* 2^253 - 2^3 */ fsquare(t1,t0); + /* 2^254 - 2^4 */ fsquare(t0,t1); + /* 2^255 - 2^5 */ fsquare(t1,t0); + /* 2^255 - 21 */ fmul(out,t1,z11); +} + +void cf_curve25519_mul(u8 out[32], const u8 scalar[32], const u8 point[32]) +{ + limb bp[10], x[10], z[11], zmone[10]; + uint8_t e[32]; + int i; + + for (i = 0; i < 32; ++i) e[i] = scalar[i]; + e[0] &= 248; + e[31] &= 127; + e[31] |= 64; + + fexpand(bp, point); + cmult(x, z, e, bp); + crecip(zmone, z); + fmul(z, x, zmone); + fcontract(out, z); +} + +void cf_curve25519_mul_base(u8 out[32], const u8 scalar[32]) +{ + uint8_t base[32] = { 9 }; + cf_curve25519_mul(out, scalar, base); +} diff --git a/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/curve25519.h b/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/curve25519.h new file mode 100644 index 00000000..9b0b7f54 --- /dev/null +++ b/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/curve25519.h @@ -0,0 +1,42 @@ +/* + * cifra - embedded cryptography library + * Written in 2014 by Joseph Birr-Pixton + * + * To the extent possible under law, the author(s) have dedicated all + * copyright and related and neighboring rights to this software to the + * public domain worldwide. This software is distributed without any + * warranty. + * + * You should have received a copy of the CC0 Public Domain Dedication + * along with this software. If not, see + * . + */ + +#ifndef CURVE25519_H +#define CURVE25519_H + +#include +#include + +/** + * Curve25519 + * ========== + * This is `curve25519 `_ with switchable + * implementations underneath. + * + * By default tweetnacl is used on hosts, and the implementation + * from μNaCl for Cortex-M0, M3 and M4. + */ + +/* .. c:function:: $DECL + * Multiplies `point` by `scalar`, putting the resulting point into `out`. */ +void cf_curve25519_mul(uint8_t out[32], + const uint8_t scalar[32], + const uint8_t point[32]); + +/* .. c:function:: $DECL + * Multiplies `scalar` by the curve25519 base point, putting the resulting + * point into `out`. */ +void cf_curve25519_mul_base(uint8_t out[32], const uint8_t scalar[32]); + +#endif diff --git a/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/curve25519.naclref.c b/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/curve25519.naclref.c new file mode 100644 index 00000000..9f331d1d --- /dev/null +++ b/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/curve25519.naclref.c @@ -0,0 +1,273 @@ +/* +version 20081011 +Matthew Dempsky +Public domain. +Derived from public domain code by D. J. Bernstein. +*/ +#include "curve25519.h" + +static void add(unsigned int out[32],const unsigned int a[32],const unsigned int b[32]) +{ + unsigned int j; + unsigned int u; + u = 0; + for (j = 0;j < 31;++j) { u += a[j] + b[j]; out[j] = u & 255; u >>= 8; } + u += a[31] + b[31]; out[31] = u; +} + +static void sub(unsigned int out[32],const unsigned int a[32],const unsigned int b[32]) +{ + unsigned int j; + unsigned int u; + u = 218; + for (j = 0;j < 31;++j) { + u += a[j] + 65280 - b[j]; + out[j] = u & 255; + u >>= 8; + } + u += a[31] - b[31]; + out[31] = u; +} + +static void squeeze(unsigned int a[32]) +{ + unsigned int j; + unsigned int u; + u = 0; + for (j = 0;j < 31;++j) { u += a[j]; a[j] = u & 255; u >>= 8; } + u += a[31]; a[31] = u & 127; + u = 19 * (u >> 7); + for (j = 0;j < 31;++j) { u += a[j]; a[j] = u & 255; u >>= 8; } + u += a[31]; a[31] = u; +} + +static const unsigned int minusp[32] = { + 19, 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, 0, 0, 0, 0, 128 +} ; + +static void freeze(unsigned int a[32]) +{ + unsigned int aorig[32]; + unsigned int j; + unsigned int negative; + + for (j = 0;j < 32;++j) aorig[j] = a[j]; + add(a,a,minusp); + negative = -((a[31] >> 7) & 1); + for (j = 0;j < 32;++j) a[j] ^= negative & (aorig[j] ^ a[j]); +} + +static void mult(unsigned int out[32],const unsigned int a[32],const unsigned int b[32]) +{ + unsigned int i; + unsigned int j; + unsigned int u; + + for (i = 0;i < 32;++i) { + u = 0; + for (j = 0;j <= i;++j) u += a[j] * b[i - j]; + for (j = i + 1;j < 32;++j) u += 38 * a[j] * b[i + 32 - j]; + out[i] = u; + } + squeeze(out); +} + +static void mult121665(unsigned int out[32],const unsigned int a[32]) +{ + unsigned int j; + unsigned int u; + + u = 0; + for (j = 0;j < 31;++j) { u += 121665 * a[j]; out[j] = u & 255; u >>= 8; } + u += 121665 * a[31]; out[31] = u & 127; + u = 19 * (u >> 7); + for (j = 0;j < 31;++j) { u += out[j]; out[j] = u & 255; u >>= 8; } + u += out[j]; out[j] = u; +} + +static void square(unsigned int out[32],const unsigned int a[32]) +{ + unsigned int i; + unsigned int j; + unsigned int u; + + for (i = 0;i < 32;++i) { + u = 0; + for (j = 0;j < i - j;++j) u += a[j] * a[i - j]; + for (j = i + 1;j < i + 32 - j;++j) u += 38 * a[j] * a[i + 32 - j]; + u *= 2; + if ((i & 1) == 0) { + u += a[i / 2] * a[i / 2]; + u += 38 * a[i / 2 + 16] * a[i / 2 + 16]; + } + out[i] = u; + } + squeeze(out); +} + +static void select(unsigned int p[64],unsigned int q[64],const unsigned int r[64],const unsigned int s[64],unsigned int b) +{ + unsigned int j; + unsigned int t; + unsigned int bminus1; + + bminus1 = b - 1; + for (j = 0;j < 64;++j) { + t = bminus1 & (r[j] ^ s[j]); + p[j] = s[j] ^ t; + q[j] = r[j] ^ t; + } +} + +static void mainloop(unsigned int work[64],const unsigned char e[32]) +{ + unsigned int xzm1[64]; + unsigned int xzm[64]; + unsigned int xzmb[64]; + unsigned int xzm1b[64]; + unsigned int xznb[64]; + unsigned int xzn1b[64]; + unsigned int a0[64]; + unsigned int a1[64]; + unsigned int b0[64]; + unsigned int b1[64]; + unsigned int c1[64]; + unsigned int r[32]; + unsigned int s[32]; + unsigned int t[32]; + unsigned int u[32]; + unsigned int j; + unsigned int b; + int pos; + + for (j = 0;j < 32;++j) xzm1[j] = work[j]; + xzm1[32] = 1; + for (j = 33;j < 64;++j) xzm1[j] = 0; + + xzm[0] = 1; + for (j = 1;j < 64;++j) xzm[j] = 0; + + for (pos = 254;pos >= 0;--pos) { + b = e[pos / 8] >> (pos & 7); + b &= 1; + select(xzmb,xzm1b,xzm,xzm1,b); + add(a0,xzmb,xzmb + 32); + sub(a0 + 32,xzmb,xzmb + 32); + add(a1,xzm1b,xzm1b + 32); + sub(a1 + 32,xzm1b,xzm1b + 32); + square(b0,a0); + square(b0 + 32,a0 + 32); + mult(b1,a1,a0 + 32); + mult(b1 + 32,a1 + 32,a0); + add(c1,b1,b1 + 32); + sub(c1 + 32,b1,b1 + 32); + square(r,c1 + 32); + sub(s,b0,b0 + 32); + mult121665(t,s); + add(u,t,b0); + mult(xznb,b0,b0 + 32); + mult(xznb + 32,s,u); + square(xzn1b,c1); + mult(xzn1b + 32,r,work); + select(xzm,xzm1,xznb,xzn1b,b); + } + + for (j = 0;j < 64;++j) work[j] = xzm[j]; +} + +static void recip(unsigned int out[32],const unsigned int z[32]) +{ + unsigned int z2[32]; + unsigned int z9[32]; + unsigned int z11[32]; + unsigned int z2_5_0[32]; + unsigned int z2_10_0[32]; + unsigned int z2_20_0[32]; + unsigned int z2_50_0[32]; + unsigned int z2_100_0[32]; + unsigned int t0[32]; + unsigned int t1[32]; + int i; + + /* 2 */ square(z2,z); + /* 4 */ square(t1,z2); + /* 8 */ square(t0,t1); + /* 9 */ mult(z9,t0,z); + /* 11 */ mult(z11,z9,z2); + /* 22 */ square(t0,z11); + /* 2^5 - 2^0 = 31 */ mult(z2_5_0,t0,z9); + + /* 2^6 - 2^1 */ square(t0,z2_5_0); + /* 2^7 - 2^2 */ square(t1,t0); + /* 2^8 - 2^3 */ square(t0,t1); + /* 2^9 - 2^4 */ square(t1,t0); + /* 2^10 - 2^5 */ square(t0,t1); + /* 2^10 - 2^0 */ mult(z2_10_0,t0,z2_5_0); + + /* 2^11 - 2^1 */ square(t0,z2_10_0); + /* 2^12 - 2^2 */ square(t1,t0); + /* 2^20 - 2^10 */ for (i = 2;i < 10;i += 2) { square(t0,t1); square(t1,t0); } + /* 2^20 - 2^0 */ mult(z2_20_0,t1,z2_10_0); + + /* 2^21 - 2^1 */ square(t0,z2_20_0); + /* 2^22 - 2^2 */ square(t1,t0); + /* 2^40 - 2^20 */ for (i = 2;i < 20;i += 2) { square(t0,t1); square(t1,t0); } + /* 2^40 - 2^0 */ mult(t0,t1,z2_20_0); + + /* 2^41 - 2^1 */ square(t1,t0); + /* 2^42 - 2^2 */ square(t0,t1); + /* 2^50 - 2^10 */ for (i = 2;i < 10;i += 2) { square(t1,t0); square(t0,t1); } + /* 2^50 - 2^0 */ mult(z2_50_0,t0,z2_10_0); + + /* 2^51 - 2^1 */ square(t0,z2_50_0); + /* 2^52 - 2^2 */ square(t1,t0); + /* 2^100 - 2^50 */ for (i = 2;i < 50;i += 2) { square(t0,t1); square(t1,t0); } + /* 2^100 - 2^0 */ mult(z2_100_0,t1,z2_50_0); + + /* 2^101 - 2^1 */ square(t1,z2_100_0); + /* 2^102 - 2^2 */ square(t0,t1); + /* 2^200 - 2^100 */ for (i = 2;i < 100;i += 2) { square(t1,t0); square(t0,t1); } + /* 2^200 - 2^0 */ mult(t1,t0,z2_100_0); + + /* 2^201 - 2^1 */ square(t0,t1); + /* 2^202 - 2^2 */ square(t1,t0); + /* 2^250 - 2^50 */ for (i = 2;i < 50;i += 2) { square(t0,t1); square(t1,t0); } + /* 2^250 - 2^0 */ mult(t0,t1,z2_50_0); + + /* 2^251 - 2^1 */ square(t1,t0); + /* 2^252 - 2^2 */ square(t0,t1); + /* 2^253 - 2^3 */ square(t1,t0); + /* 2^254 - 2^4 */ square(t0,t1); + /* 2^255 - 2^5 */ square(t1,t0); + /* 2^255 - 21 */ mult(out,t1,z11); +} + +static void crypto_scalarmult(unsigned char *q, + const unsigned char *n, + const unsigned char *p) +{ + unsigned int work[96]; + unsigned char e[32]; + unsigned int i; + for (i = 0;i < 32;++i) e[i] = n[i]; + e[0] &= 248; + e[31] &= 127; + e[31] |= 64; + for (i = 0;i < 32;++i) work[i] = p[i]; + mainloop(work,e); + recip(work + 32,work + 32); + mult(work + 64,work,work + 32); + freeze(work + 64); + for (i = 0;i < 32;++i) q[i] = work[64 + i]; +} + +void cf_curve25519_mul(uint8_t out[32], const uint8_t scalar[32], const uint8_t point[32]) +{ + crypto_scalarmult(out, scalar, point); +} + +void cf_curve25519_mul_base(uint8_t out[32], const uint8_t scalar[32]) +{ + uint8_t base_point[32] = { 9 }; + cf_curve25519_mul(out, scalar, base_point); +} diff --git a/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/curve25519.tweetnacl.c b/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/curve25519.tweetnacl.c new file mode 100644 index 00000000..c98c1078 --- /dev/null +++ b/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/curve25519.tweetnacl.c @@ -0,0 +1,235 @@ +/* This is based on tweetnacl. Some typedefs have been + * replaced with their stdint equivalents. + * + * Original code was public domain. */ + +#include +#include + +#include "handy.h" + +typedef int64_t gf[16]; + +static const uint8_t _0[16], + _9[32] = {9}; +static const gf gf0, + gf1 = {1}, + _121665 = {0xDB41, 1}, + D = {0x78a3, 0x1359, 0x4dca, 0x75eb, + 0xd8ab, 0x4141, 0x0a4d, 0x0070, + 0xe898, 0x7779, 0x4079, 0x8cc7, + 0xfe73, 0x2b6f, 0x6cee, 0x5203}, + D2 = {0xf159, 0x26b2, 0x9b94, 0xebd6, + 0xb156, 0x8283, 0x149a, 0x00e0, + 0xd130, 0xeef3, 0x80f2, 0x198e, + 0xfce7, 0x56df, 0xd9dc, 0x2406}, + X = {0xd51a, 0x8f25, 0x2d60, 0xc956, + 0xa7b2, 0x9525, 0xc760, 0x692c, + 0xdc5c, 0xfdd6, 0xe231, 0xc0a4, + 0x53fe, 0xcd6e, 0x36d3, 0x2169}, + Y = {0x6658, 0x6666, 0x6666, 0x6666, + 0x6666, 0x6666, 0x6666, 0x6666, + 0x6666, 0x6666, 0x6666, 0x6666, + 0x6666, 0x6666, 0x6666, 0x6666}, + I = {0xa0b0, 0x4a0e, 0x1b27, 0xc4ee, + 0xe478, 0xad2f, 0x1806, 0x2f43, + 0xd7a7, 0x3dfb, 0x0099, 0x2b4d, + 0xdf0b, 0x4fc1, 0x2480, 0x2b83}; + +static void set25519(gf r, const gf a) +{ + size_t i; + for (i = 0; i < 16; i++) + r[i] = a[i]; +} + +static void car25519(gf o) +{ + int64_t c; + size_t i; + + for (i = 0; i < 16; i++) + { + o[i] += (1LL << 16); + c = o[i] >> 16; + o[(i + 1) * (i < 15)] += c - 1 + 37 * (c - 1) * (i == 15); + o[i] -= c << 16; + } +} + +static void sel25519(gf p, gf q, int64_t b) +{ + int64_t tmp, mask = ~(b-1); + size_t i; + for (i = 0; i < 16; i++) + { + tmp = mask & (p[i] ^ q[i]); + p[i] ^= tmp; + q[i] ^= tmp; + } +} + +static void pack25519(uint8_t out[32], const gf n) +{ + size_t i, j; + int b; + gf m, t; + set25519(t, n); + car25519(t); + car25519(t); + car25519(t); + + for(j = 0; j < 2; j++) + { + m[0] = t[0] - 0xffed; + for (i = 1; i < 15; i++) + { + m[i] = t[i] - 0xffff - ((m[i - 1] >> 16) & 1); + m[i - 1] &= 0xffff; + } + m[15] = t[15] - 0x7fff - ((m[14] >> 16) & 1); + b = (m[15] >> 16) & 1; + m[14] &= 0xffff; + sel25519(t, m, 1 - b); + } + + for (i = 0; i < 16; i++) + { + out[2 * i] = t[i] & 0xff; + out[2 * i + 1] = (uint8_t) (t[i] >> 8); + } +} + + + +static void unpack25519(gf o, const uint8_t *n) +{ + size_t i; + for (i = 0; i < 16; i++) + o[i] = n[2 * i] + ((int64_t) n[2 * i + 1] << 8); + o[15] &= 0x7fff; +} + +static void add(gf o, const gf a, const gf b) +{ + size_t i; + for (i = 0; i < 16; i++) + o[i] = a[i] + b[i]; +} + +static void sub(gf o, const gf a, const gf b) +{ + size_t i; + for (i = 0; i < 16; i++) + o[i] = a[i] - b[i]; +} + +static void mul(gf o, const gf a, const gf b) +{ + int64_t t[31]; + size_t i, j; + + for (i = 0; i < 31; i++) + t[i] = 0; + + for (i = 0; i < 16; i++) + for (j = 0; j < 16; j++) + t[i + j] += a[i] * b[j]; + + for (i = 0; i < 15; i++) + t[i] += 38 * t[i + 16]; + + for (i = 0; i < 16; i++) + o[i] = t[i]; + + car25519(o); + car25519(o); +} + +static void sqr(gf o, const gf a) +{ + mul(o, a, a); +} + +static void inv25519(gf o, const gf i) +{ + gf c; + int a; + for (a = 0; a < 16; a++) + c[a] = i[a]; + + for (a = 253; a >= 0; a--) + { + sqr(c, c); + if(a != 2 && a != 4) + mul(c, c, i); + } + + for (a = 0; a < 16; a++) + o[a] = c[a]; +} + + +void cf_curve25519_mul(uint8_t *q, const uint8_t *n, const uint8_t *p) +{ + uint8_t z[32]; + gf x; + gf a, b, c, d, e, f; + + { + size_t i; + for (i = 0; i < 31; i++) + z[i] = n[i]; + z[31] = (n[31] & 127) | 64; + z[0] &= 248; + + unpack25519(x, p); + + for(i = 0; i < 16; i++) + { + b[i] = x[i]; + d[i] = a[i] = c[i] = 0; + } + } + + a[0] = d[0] = 1; + + {int i; + for (i = 254; i >= 0; i--) + { + int64_t r = (z[i >> 3] >> (i & 7)) & 1; + sel25519(a, b, r); + sel25519(c, d, r); + add(e, a, c); + sub(a, a, c); + add(c, b, d); + sub(b, b, d); + sqr(d, e); + sqr(f, a); + mul(a, c, a); + mul(c, b, e); + add(e, a, c); + sub(a, a, c); + sqr(b, a); + sub(c, d, f); + mul(a, c, _121665); + add(a, a, d); + mul(c, c, a); + mul(a, d, f); + mul(d, b, x); + sqr(b, e); + sel25519(a, b, r); + sel25519(c, d, r); + } + } + + inv25519(c, c); + mul(a, a, c); + pack25519(q, a); +} + +void cf_curve25519_mul_base(uint8_t *q, const uint8_t *n) +{ + cf_curve25519_mul(q, n, _9); +} + diff --git a/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/drbg.c b/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/drbg.c new file mode 100644 index 00000000..ae790678 --- /dev/null +++ b/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/drbg.c @@ -0,0 +1,434 @@ +/* + * cifra - embedded cryptography library + * Written in 2016 by Joseph Birr-Pixton + * + * To the extent possible under law, the author(s) have dedicated all + * copyright and related and neighboring rights to this software to the + * public domain worldwide. This software is distributed without any + * warranty. + * + * You should have received a copy of the CC0 Public Domain Dedication + * along with this software. If not, see + * . + */ + +#include "drbg.h" +#include "handy.h" +#include "bitops.h" +#include "sha2.h" +#include "tassert.h" + +#include + +#define MAX_DRBG_GENERATE 0x10000ul + +static void hash_df(const cf_chash *H, + const void *in1, size_t nin1, + const void *in2, size_t nin2, + const void *in3, size_t nin3, + const void *in4, size_t nin4, + uint8_t *out, size_t nout) +{ + uint8_t counter = 1; + uint32_t bits_to_return = nout * 8; + uint8_t cbuf[4]; + uint8_t block[CF_MAXHASH]; + + write32_be(bits_to_return, cbuf); + + while (nout) + { + /* Make a block. This is the hash of: + * counter || bits_to_return || in1 || in2 || in3 | in4 + */ + cf_chash_ctx ctx; + H->init(&ctx); + H->update(&ctx, &counter, sizeof counter); + H->update(&ctx, cbuf, sizeof cbuf); + H->update(&ctx, in1, nin1); + H->update(&ctx, in2, nin2); + H->update(&ctx, in3, nin3); + H->update(&ctx, in4, nin4); + H->digest(&ctx, block); + + size_t take = MIN(H->hashsz, nout); + memcpy(out, block, take); + out += take; + nout -= take; + + counter += 1; + } +} + +void cf_hash_drbg_sha256_init(cf_hash_drbg_sha256 *ctx, + const void *entropy, size_t nentropy, + const void *nonce, size_t nnonce, + const void *persn, size_t npersn) +{ + mem_clean(ctx, sizeof *ctx); + + /* 1. seed_material = entropy_input || nonce || personalization_string + * 2. seed = Hash_df(seed_material, seedlen) + * 3. V = seed */ + hash_df(&cf_sha256, + entropy, nentropy, + nonce, nnonce, + persn, npersn, + NULL, 0, + ctx->V, sizeof ctx->V); + + /* 4. C = Hash_df(0x00 || V, seedlen) */ + uint8_t zero = 0; + hash_df(&cf_sha256, + &zero, sizeof zero, + ctx->V, sizeof ctx->V, + NULL, 0, + NULL, 0, + ctx->C, sizeof ctx->C); + + /* 5. reseed_counter = 1 */ + ctx->reseed_counter = 1; +} + +/* Add out += in, mod 2^nout. + * Runs in time dependent on nout and nin, but not the contents of out or in. + */ +static void add(uint8_t *out, size_t nout, const uint8_t *in, size_t nin) +{ + assert(nout >= nin); + + uint16_t carry = 0; + int oi, ii; + + for (oi = nout - 1, ii = nin - 1; + oi >= 0; + ii--, oi--) + { + carry += out[oi]; + if (ii >= 0) + carry += in[ii]; + out[oi] = carry & 0xff; + carry >>= 8; + } +} + +static void hash_process_addnl(const cf_chash *H, + const void *input, size_t ninput, + uint8_t *V, size_t nV) +{ + if (!ninput) + return; + + /* 2.1. w = Hash(0x02 || V || additional_input) */ + uint8_t two = 2; + uint8_t w[CF_MAXHASH]; + cf_chash_ctx ctx; + H->init(&ctx); + H->update(&ctx, &two, sizeof two); + H->update(&ctx, V, nV); + H->update(&ctx, input, ninput); + H->digest(&ctx, w); + + /* 2.2. V = (V + w) mod 2 ^ seedlen */ + add(V, nV, w, H->hashsz); +} + +static void hash_generate(const cf_chash *H, + uint8_t *data, size_t ndata, /* initialised with V */ + void *out, size_t nout) +{ + cf_chash_ctx ctx; + uint8_t w[CF_MAXHASH]; + uint8_t *bout = out; + uint8_t one = 1; + + while (nout) + { + /* 4.1. w = Hash(data) */ + H->init(&ctx); + H->update(&ctx, data, ndata); + H->digest(&ctx, w); + + /* 4.2. W = W || w */ + size_t take = MIN(H->hashsz, nout); + memcpy(bout, w, take); + bout += take; + nout -= take; + + /* 4.3. data = (data + 1) mod 2 ^ seedlen */ + add(data, ndata, &one, sizeof one); + } +} + +static void hash_step(const cf_chash *H, + uint8_t *V, size_t nV, + const uint8_t *C, size_t nC, + uint32_t *reseed_counter) +{ + /* 4. h = Hash(0x03 || V) */ + uint8_t h[CF_MAXHASH]; + uint8_t three = 3; + cf_chash_ctx ctx; + + H->init(&ctx); + H->update(&ctx, &three, sizeof three); + H->update(&ctx, V, nV); + H->digest(&ctx, h); + + /* 5. V = (V + h + C + reseed_counter) mod 2 ^ seedlen */ + uint8_t reseed_counter_buf[4]; + write32_be(*reseed_counter, reseed_counter_buf); + + add(V, nV, h, H->hashsz); + add(V, nV, C, nC); + add(V, nV, reseed_counter_buf, sizeof reseed_counter_buf); + + /* 6. reseed_counter = reseed_counter + 1 */ + *reseed_counter = *reseed_counter + 1; +} + +/* This is Hash_DRBG_Generate_algorithm. + * nout is a maximum of MAX_DRBG_GENERATE */ +static void hash_gen_request(cf_hash_drbg_sha256 *ctx, + const void *addnl, size_t naddnl, + void *out, size_t nout) +{ + uint8_t data[440/8]; /* a temporary copy of V, which gets incremented by generate */ + + assert(!cf_hash_drbg_sha256_needs_reseed(ctx)); + + hash_process_addnl(&cf_sha256, addnl, naddnl, ctx->V, sizeof ctx->V); + assert(sizeof data == sizeof ctx->V); + memcpy(data, ctx->V, sizeof ctx->V); + hash_generate(&cf_sha256, data, sizeof data, out, nout); + hash_step(&cf_sha256, ctx->V, sizeof ctx->V, ctx->C, sizeof ctx->C, &ctx->reseed_counter); +} + +void cf_hash_drbg_sha256_gen_additional(cf_hash_drbg_sha256 *ctx, + const void *addnl, size_t naddnl, + void *out, size_t nout) +{ + uint8_t *bout = out; + + /* Generate output in requests of MAX_DRBG_GENERATE in size. */ + while (nout != 0) + { + size_t take = MIN(MAX_DRBG_GENERATE, nout); + hash_gen_request(ctx, addnl, naddnl, bout, take); + bout += take; + nout -= take; + + /* Add additional data only once. */ + addnl = NULL; + naddnl = 0; + } +} + +void cf_hash_drbg_sha256_gen(cf_hash_drbg_sha256 *ctx, + void *out, size_t nout) +{ + cf_hash_drbg_sha256_gen_additional(ctx, + NULL, 0, + out, nout); +} + +void cf_hash_drbg_sha256_reseed(cf_hash_drbg_sha256 *ctx, + const void *entropy, size_t nentropy, + const void *addnl, size_t naddnl) +{ + /* 1. seed_material = 0x01 || V || entropy_input || additional_input + * 2. seed = Hash_df(seed_material, seedlen) + * 3. V = seed */ + uint8_t one = 1; + /* stash V in C, because it cannot alias output */ + memcpy(ctx->C, ctx->V, sizeof ctx->C); + hash_df(&cf_sha256, + &one, sizeof one, + ctx->C, sizeof ctx->C, + entropy, nentropy, + addnl, naddnl, + ctx->V, sizeof ctx->V); + + /* 4. C = Hash_df(0x00 || V, seedlen) */ + uint8_t zero = 0; + hash_df(&cf_sha256, + &zero, sizeof zero, + ctx->V, sizeof ctx->V, + NULL, 0, + NULL, 0, + ctx->C, sizeof ctx->C); + + /* 5. reseed_counter = 1 */ + ctx->reseed_counter = 1; +} + +uint32_t cf_hash_drbg_sha256_needs_reseed(const cf_hash_drbg_sha256 *ctx) +{ + /* we need reseeding after 2 ^ 32 - 1 requests. */ + return ctx->reseed_counter == 0; +} + +/* --- HMAC_DRBG --- */ + +/* provided_data is in1 || in2 || in3. + * K is already scheduled in ctx->hmac. */ +static void hmac_drbg_update(cf_hmac_drbg *ctx, + const void *in1, size_t nin1, + const void *in2, size_t nin2, + const void *in3, size_t nin3) +{ + cf_hmac_ctx local; + const cf_chash *H = ctx->hmac.hash; + uint8_t new_key[CF_MAXHASH]; + uint8_t zero = 0; + + /* 1. K = HMAC(K, V || 0x00 || provided_data) */ + local = ctx->hmac; + cf_hmac_update(&local, ctx->V, H->hashsz); + cf_hmac_update(&local, &zero, sizeof zero); + cf_hmac_update(&local, in1, nin1); + cf_hmac_update(&local, in2, nin2); + cf_hmac_update(&local, in3, nin3); + cf_hmac_finish(&local, new_key); + cf_hmac_init(&ctx->hmac, H, new_key, H->hashsz); + mem_clean(new_key, sizeof new_key); + + /* 2. V = HMAC(K, V) */ + local = ctx->hmac; + cf_hmac_update(&local, ctx->V, H->hashsz); + cf_hmac_finish(&local, ctx->V); + + /* 3. if (provided_data = null) then return K and V */ + if (nin1 == 0 && nin2 == 0 && nin3 == 0) + return; + + /* 4. K = HMAC(K, V || 0x01 || provided_data) */ + uint8_t one = 1; + local = ctx->hmac; + cf_hmac_update(&local, ctx->V, H->hashsz); + cf_hmac_update(&local, &one, sizeof one); + cf_hmac_update(&local, in1, nin1); + cf_hmac_update(&local, in2, nin2); + cf_hmac_update(&local, in3, nin3); + cf_hmac_finish(&local, new_key); + cf_hmac_init(&ctx->hmac, H, new_key, H->hashsz); + mem_clean(new_key, sizeof new_key); + + /* 5. V = HMAC(K, V) */ + local = ctx->hmac; + cf_hmac_update(&local, ctx->V, H->hashsz); + cf_hmac_finish(&local, ctx->V); +} + +void cf_hmac_drbg_init(cf_hmac_drbg *ctx, + const cf_chash *hash, + const void *entropy, size_t nentropy, + const void *nonce, size_t nnonce, + const void *persn, size_t npersn) +{ + mem_clean(ctx, sizeof *ctx); + + assert(hash->hashsz <= CF_MAXHASH); + + /* 2. Key = 0x00 00 ... 00 + * 3. V = 0x01 01 ... 01 */ + uint8_t initial_key[CF_MAXHASH]; + memset(initial_key, 0x00, hash->hashsz); + memset(ctx->V, 0x01, hash->hashsz); + cf_hmac_init(&ctx->hmac, hash, initial_key, hash->hashsz); + + /* 1. seed_material = entropy_input || nonce || personalization_string + * 4. (Key, V) = HMAC_DRBG_Update(seed_material, Key, V) */ + hmac_drbg_update(ctx, entropy, nentropy, nonce, nnonce, persn, npersn); + + /* 5. reseed_counter = 1 */ + ctx->reseed_counter = 1; +} + +uint32_t cf_hmac_drbg_needs_reseed(const cf_hmac_drbg *ctx) +{ + return ctx->reseed_counter == 0; +} + +static void hmac_drbg_generate(cf_hmac_drbg *ctx, + const void *addnl, size_t naddnl, + void *out, size_t nout) +{ + /* 1. If reseed_counter > reseed_interval, then return an indication + * that a reseed is required */ + assert(!cf_hmac_drbg_needs_reseed(ctx)); + + /* 2. If additional_input != null, then + * (Key, V) = HMAC_DRBG_Update(additional_input, Key, V) + */ + if (naddnl) + hmac_drbg_update(ctx, addnl, naddnl, NULL, 0, NULL, 0); + + /* 3. temp = Null + * 4. While (len(temp) < requested_number_of_bits) do: + * 4.1. V = HMAC(Key, V) + * 4.2. temp = temp || V + * 5. returned_bits = leftmost(temp, requested_number_of_bits) + * + * We write the contents of temp directly into the caller's + * out buffer. + */ + uint8_t *bout = out; + cf_hmac_ctx local; + + while (nout) + { + local = ctx->hmac; + cf_hmac_update(&local, ctx->V, ctx->hmac.hash->hashsz); + cf_hmac_finish(&local, ctx->V); + + size_t take = MIN(ctx->hmac.hash->hashsz, nout); + memcpy(bout, ctx->V, take); + bout += take; + nout -= take; + } + + /* 6. (Key, V) = HMAC_DRBG_Update(additional_input, Key, V) */ + hmac_drbg_update(ctx, addnl, naddnl, NULL, 0, NULL, 0); + + /* 7. reseed_counter = reseed_counter + 1 */ + ctx->reseed_counter++; +} + +void cf_hmac_drbg_gen_additional(cf_hmac_drbg *ctx, + const void *addnl, size_t naddnl, + void *out, size_t nout) +{ + uint8_t *bout = out; + + while (nout != 0) + { + size_t take = MIN(MAX_DRBG_GENERATE, nout); + hmac_drbg_generate(ctx, addnl, naddnl, bout, take); + bout += take; + nout -= take; + + /* Add additional data only once. */ + addnl = NULL; + naddnl = 0; + } +} + +void cf_hmac_drbg_gen(cf_hmac_drbg *ctx, void *out, size_t nout) +{ + cf_hmac_drbg_gen_additional(ctx, + NULL, 0, + out, nout); +} + +void cf_hmac_drbg_reseed(cf_hmac_drbg *ctx, + const void *entropy, size_t nentropy, + const void *addnl, size_t naddnl) +{ + /* 1. seed_material = entropy_input || additional_input + * 2. (Key, V) = HMAC_DRBG_Update(seed_material, Key, V) */ + hmac_drbg_update(ctx, entropy, nentropy, addnl, naddnl, NULL, 0); + + /* 3. reseed_counter = 1 */ + ctx->reseed_counter = 1; +} diff --git a/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/drbg.h b/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/drbg.h new file mode 100644 index 00000000..18a10704 --- /dev/null +++ b/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/drbg.h @@ -0,0 +1,191 @@ +/* + * cifra - embedded cryptography library + * Written in 2016 by Joseph Birr-Pixton + * + * To the extent possible under law, the author(s) have dedicated all + * copyright and related and neighboring rights to this software to the + * public domain worldwide. This software is distributed without any + * warranty. + * + * You should have received a copy of the CC0 Public Domain Dedication + * along with this software. If not, see + * . + */ + +#ifndef DRBG_H +#define DRBG_H + +#include +#include + +#include "chash.h" +#include "hmac.h" + +/** + * Hash_DRBG + * ========= + * This is Hash_DRBG from SP800-90A rev 1, with SHA256 as + * the underlying hash function. + * + * This generator enforces a `reseed_interval` of 2^32-1: + * use :c:func:`cf_hash_drbg_sha256_needs_reseed` to check + * whether you need to reseed before use, and reseed using + * :c:func:`cf_hash_drbg_sha256_reseed`. If you try to use + * the generator when it thinks it needs reseeding, it will + * call `abort`. + * + * Internally it enforces a `max_number_of_bits_per_request` + * of 2^19 bits. It sorts out chunking up multiple requests + * for you though, so feel free to ask for more than 2^16 bytes + * at a time. If you provide additional input when doing that, + * it is added only once, on the first subrequest. + * + * It does not enforce any `max_length` or + * `max_personalization_string_length`. + */ + +/* .. c:type:: cf_hash_drbg_sha256 + * Hash_DRBG with SHA256 context. + * + * .. c:member:: cf_hash_drbg_sha256.V + * Current internal state. + * + * .. c:member:: cf_hash_drbg_sha256.C + * Current update offset. + * + * .. c:member:: cf_hash_drbg_sha256.reseed_counter + * Current number of times entropy has been extracted from + * generator. + */ +typedef struct +{ + uint8_t V[440/8]; + uint8_t C[440/8]; + uint32_t reseed_counter; +} cf_hash_drbg_sha256; + +/* .. c:function:: $DECL + * Initialises the generator state `ctx`, using the provided `entropy`, + * `nonce` and personalisation string `persn`. + */ +extern void cf_hash_drbg_sha256_init(cf_hash_drbg_sha256 *ctx, + const void *entropy, size_t nentropy, + const void *nonce, size_t nnonce, + const void *persn, size_t npersn); + +/* .. c:function:: $DECL + * Returns non-zero if the generator needs reseeding. If + * this function returns non-zero, the next :c:func:`cf_hash_drbg_sha256_gen` + * or :c:func:`cf_hash_drbg_sha256_gen_additional` call will call `abort`. + */ +extern uint32_t cf_hash_drbg_sha256_needs_reseed(const cf_hash_drbg_sha256 *ctx); + +/* .. c:function:: $DECL + * Reseeds the generator with the given `entropy` and additional data `addnl`. + */ +extern void cf_hash_drbg_sha256_reseed(cf_hash_drbg_sha256 *ctx, + const void *entropy, size_t nentropy, + const void *addnl, size_t naddnl); + +/* .. c:function:: $DECL + * Generates pseudo-random output, writing `nout` bytes at `out`. + * This function aborts if the generator needs seeding. + */ +extern void cf_hash_drbg_sha256_gen(cf_hash_drbg_sha256 *ctx, + void *out, size_t nout); + +/* .. c:function:: $DECL + * Generates pseudo-random output, writing `nout` bytes at `out`. + * At the same time, `addnl` is input to the generator as further + * entropy. + * This function aborts if the generator needs seeding. + */ +extern void cf_hash_drbg_sha256_gen_additional(cf_hash_drbg_sha256 *ctx, + const void *addnl, size_t naddnl, + void *out, size_t nout); + +/** + * HMAC_DRBG + * ========= + * This is HMAC_DRBG from SP800-90a r1 with any hash function. + * + * This generator enforces a `reseed_interval` of 2^32-1: + * use :c:func:`cf_hmac_drbg_needs_reseed` to check whether + * you need to reseed before use, and reseed using + * :c:func:`cf_hmac_drbg_reseed`. If you try to use the + * generator when it thinks it needs reseeding, it will + * call `abort`. + * + * Internally it enforces a `max_number_of_bits_per_request` + * of 2^19 bits. It sorts out chunking up multiple requests + * for you though, so feel free to ask for more than 2^16 bytes + * at a time. If you provide additional input when doing that, + * it is added only once, on the first subrequest. + * + * It does not enforce any `max_length` or + * `max_personalization_string_length`. + */ + +/* .. c:type:: cf_hmac_drbg + * HMAC_DRBG context. + * + * .. c:member:: cf_hmac_drbg.V + * Current internal state. + * + * .. c:member:: cf_hmac_drbg.hmac + * Current HMAC context, with key scheduled in it. + * + * .. c:member:: cf_hmac_drbg.reseed_counter + * Current number of times entropy has been extracted from + * generator. + */ +typedef struct +{ + uint8_t V[CF_MAXHASH]; + cf_hmac_ctx hmac; /* pristine context with key scheduled */ + uint32_t reseed_counter; +} cf_hmac_drbg; + +/* .. c:function:: $DECL + * Initialises the generator state `ctx`, using the provided `entropy`, + * `nonce` and personalisation string `persn`. + */ +extern void cf_hmac_drbg_init(cf_hmac_drbg *ctx, + const cf_chash *hash, + const void *entropy, size_t nentropy, + const void *nonce, size_t nnonce, + const void *persn, size_t npersn); + +/* .. c:function:: $DECL + * Returns non-zero if the generator needs reseeding. If + * this function returns non-zero, the next :c:func:`cf_hmac_drbg_gen` + * or :c:func:`cf_hmac_drbg_gen_additional` call will call `abort`. + */ +extern uint32_t cf_hmac_drbg_needs_reseed(const cf_hmac_drbg *ctx); + +/* .. c:function:: $DECL + * Reseeds the generator with the given `entropy` and additional data + * `addnl`. + */ +extern void cf_hmac_drbg_reseed(cf_hmac_drbg *ctx, + const void *entropy, size_t nentropy, + const void *addnl, size_t naddnl); + +/* .. c:function:: $DECL + * Generates pseudo-random output, writing `nout` bytes at `out`. + * This function aborts if the generator needs seeding. + */ +extern void cf_hmac_drbg_gen(cf_hmac_drbg *ctx, + void *out, size_t nout); + +/* .. c:function:: $DECL + * Generates pseudo-random output, writing `nout` bytes at `out`. + * At the same time, `addnl` is input to the generator as further + * entropy. + * This function aborts if the generator needs seeding. + */ +extern void cf_hmac_drbg_gen_additional(cf_hmac_drbg *ctx, + const void *addnl, size_t naddnl, + void *out, size_t nout); + +#endif diff --git a/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/eax.c b/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/eax.c new file mode 100644 index 00000000..80ba46f4 --- /dev/null +++ b/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/eax.c @@ -0,0 +1,116 @@ +/* + * cifra - embedded cryptography library + * Written in 2014 by Joseph Birr-Pixton + * + * To the extent possible under law, the author(s) have dedicated all + * copyright and related and neighboring rights to this software to the + * public domain worldwide. This software is distributed without any + * warranty. + * + * You should have received a copy of the CC0 Public Domain Dedication + * along with this software. If not, see + * . + */ + +#include "handy.h" +#include "prp.h" +#include "modes.h" +#include "tassert.h" + +#include + +static void cmac_compute_n(cf_cmac_stream *ctx, + uint8_t t, + const uint8_t *input, size_t ninput, + uint8_t out[CF_MAXBLOCK]) +{ + size_t blocksz = ctx->cmac.prp->blocksz; + assert(blocksz > 0); + + uint8_t firstblock[CF_MAXBLOCK]; + memset(firstblock, 0, blocksz); + firstblock[blocksz - 1] = t; + + cf_cmac_stream_reset(ctx); + if (ninput) + { + cf_cmac_stream_update(ctx, firstblock, blocksz, 0); + cf_cmac_stream_update(ctx, input, ninput, 1); + } else { + cf_cmac_stream_update(ctx, firstblock, blocksz, 1); + } + + cf_cmac_stream_final(ctx, out); +} + +void cf_eax_encrypt(const cf_prp *prp, void *prpctx, + const uint8_t *plain, size_t nplain, + const uint8_t *header, size_t nheader, + const uint8_t *nonce, size_t nnonce, + uint8_t *cipher, /* the same size as nplain */ + uint8_t *tag, size_t ntag) +{ + uint8_t NN[CF_MAXBLOCK], + HH[CF_MAXBLOCK], + CC[CF_MAXBLOCK]; + + cf_cmac_stream cmac; + cf_cmac_stream_init(&cmac, prp, prpctx); + + /* NN = OMAC_K^0(N) */ + cmac_compute_n(&cmac, 0, nonce, nnonce, NN); + + /* HH = OMAC_K^1(H) */ + cmac_compute_n(&cmac, 1, header, nheader, HH); + + /* C = CTR_K^NN(M) */ + cf_ctr ctr; + cf_ctr_init(&ctr, prp, prpctx, NN); + cf_ctr_cipher(&ctr, plain, cipher, nplain); + + /* CC = OMAC_K^2(C) */ + cmac_compute_n(&cmac, 2, cipher, nplain, CC); + + /* Tag = NN ^ CC ^ HH + * T = Tag [ first tau bits ] */ + assert(ntag <= prp->blocksz); + for (size_t i = 0; i < ntag; i++) + tag[i] = NN[i] ^ CC[i] ^ HH[i]; +} + +int cf_eax_decrypt(const cf_prp *prp, void *prpctx, + const uint8_t *cipher, size_t ncipher, + const uint8_t *header, size_t nheader, + const uint8_t *nonce, size_t nnonce, + const uint8_t *tag, size_t ntag, + uint8_t *plain) /* the same size as ncipher */ +{ + uint8_t NN[CF_MAXBLOCK], + HH[CF_MAXBLOCK], + CC[CF_MAXBLOCK]; + + cf_cmac_stream cmac; + cf_cmac_stream_init(&cmac, prp, prpctx); + + /* NN = OMAC_K^0(N) */ + cmac_compute_n(&cmac, 0, nonce, nnonce, NN); + + /* HH = OMAC_K^1(H) */ + cmac_compute_n(&cmac, 1, header, nheader, HH); + + /* CC = OMAC_K^2(C) */ + cmac_compute_n(&cmac, 2, cipher, ncipher, CC); + + uint8_t tt[CF_MAXBLOCK]; + assert(ntag && ntag <= prp->blocksz); + for (size_t i = 0; i < ntag; i++) + tt[i] = NN[i] ^ CC[i] ^ HH[i]; + + if (!mem_eq(tt, tag, ntag)) + return 1; + + cf_ctr ctr; + cf_ctr_init(&ctr, prp, prpctx, NN); + cf_ctr_cipher(&ctr, cipher, plain, ncipher); + return 0; +} diff --git a/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/ext/cutest.h b/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/ext/cutest.h new file mode 100644 index 00000000..c9af425e --- /dev/null +++ b/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/ext/cutest.h @@ -0,0 +1,620 @@ +/* + * CUTest -- C/C++ Unit Test facility + * + * + * Copyright (c) 2013-2014 Martin Mitas + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1 of the License, or + * (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef CUTEST_H__ +#define CUTEST_H__ + + +/************************ + *** Public interface *** + ************************/ + +/* By default, provides the main program entry point (function + * main()). However, if the test suite is composed of multiple source files + * which include , then this brings a problem of multiple main() + * definitions. To avoid this problem, #define macro TEST_NO_MAIN in all + * compilation units but one. + */ + +/* Macro to specify list of unit tests in the suite. + * The unit test implementation MUST provide list of unit tests it implements + * with this macro: + * + * TEST_LIST = { + * { "test1_name", test1_func_ptr }, + * { "test2_name", test2_func_ptr }, + * ... + * { 0 } + * }; + * + * The list specifies names of each tests (must be unique) and pointer to + * a function implementing it. The function does not take any arguments + * and have no return values, i.e. the test functions should have this + * prototype: + * + * void test_func(void); + */ +#define TEST_LIST const struct test__ test_list__[] + + +/* Macros for testing whether an unit test succeeds or fails. These macros + * can be used arbitrarily in functions implementing the unit tests. + * + * If any condition fails throughout execution of a test, the test fails. + * + * TEST_CHECK takes only one argument (the condition), TEST_CHECK_ allows + * also to specify an error message to print out if the condition fails. + * (It expects printf-like format string and its parameters). The macros + * return non-zero (condition passes) or 0 (condition fails). + * + * That can be useful when more conditions should be checked only if some + * preceding condition passes, as illustrated here: + * + * SomeStruct* ptr = allocate_some_struct(); + * if(TEST_CHECK(ptr != NULL)) { + * TEST_CHECK(ptr->member1 < 100); + * TEST_CHECK(ptr->member2 > 200); + * } + */ +#define TEST_CHECK_(cond,...) test_check__((cond), __FILE__, __LINE__, __VA_ARGS__) +#define TEST_CHECK(cond) test_check__((cond), __FILE__, __LINE__, "%s", #cond) + + +/********************** + *** Implementation *** + **********************/ + +/* The unit test files should not rely on anything below. */ + +#include +#include +#include +#include + +#if defined(unix) || defined(__unix__) || defined(__unix) || defined(__APPLE__) + #define CUTEST_UNIX__ 1 + #include + #include + #include + #include + #include +#endif + +#if defined(_WIN32) || defined(__WIN32__) || defined(__WINDOWS__) + #define CUTEST_WIN__ 1 + #include + #include +#endif + +#ifdef __cplusplus + #include +#endif + + +/* Note our global private identifiers end with '__' to minimize risk of clash + * with the unit tests implementation. */ + + +#ifdef __cplusplus + extern "C" { +#endif + + +struct test__ { + const char* name; + void (*func)(void); +}; + +extern const struct test__ test_list__[]; +extern int test_verbose_level__; +extern const struct test__* test_current_unit__; +extern int test_current_already_logged__; +extern int test_current_failures__; +extern int test_colorize__; + + +#define CUTEST_COLOR_DEFAULT__ 0 +#define CUTEST_COLOR_GREEN__ 1 +#define CUTEST_COLOR_RED__ 2 +#define CUTEST_COLOR_DEFAULT_INTENSIVE__ 3 +#define CUTEST_COLOR_GREEN_INTENSIVE__ 4 +#define CUTEST_COLOR_RED_INTENSIVE__ 5 + +size_t +test_print_in_color(int color, const char* fmt, ...) +{ + va_list args; + char buffer[256]; + size_t n; + + va_start(args, fmt); + vsnprintf(buffer, sizeof(buffer), fmt, args); + va_end(args); + buffer[sizeof(buffer)-1] = '\0'; + + if(!test_colorize__) { + return printf("%s", buffer); + } + +#if defined CUTEST_UNIX__ + const char* col_str; + switch(color) { + case CUTEST_COLOR_GREEN__: col_str = "\e[0;32m"; break; + case CUTEST_COLOR_RED__: col_str = "\e[0;31m"; break; + case CUTEST_COLOR_GREEN_INTENSIVE__: col_str = "\e[1;32m"; break; + case CUTEST_COLOR_RED_INTENSIVE__: col_str = "\e[1;30m"; break; + case CUTEST_COLOR_DEFAULT_INTENSIVE__: col_str = "\e[1m"; break; + default: col_str = "\e[0m"; break; + } + printf("%s", col_str); + n = printf("%s", buffer); + printf("\e[0m"); + return n; +#elif defined CUTEST_WIN__ + HANDLE h; + CONSOLE_SCREEN_BUFFER_INFO info; + WORD attr; + + h = GetStdHandle(STD_OUTPUT_HANDLE); + GetConsoleScreenBufferInfo(h, &info); + + switch(color) { + case CUTEST_COLOR_GREEN__: attr = FOREGROUND_GREEN; break; + case CUTEST_COLOR_RED__: attr = FOREGROUND_RED; break; + case CUTEST_COLOR_GREEN_INTENSIVE__: attr = FOREGROUND_GREEN | FOREGROUND_INTENSITY; break; + case CUTEST_COLOR_RED_INTENSIVE__: attr = FOREGROUND_RED | FOREGROUND_INTENSITY; break; + case CUTEST_COLOR_DEFAULT_INTENSIVE__: attr = FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_INTENSITY; break; + default: attr = 0; break; + } + if(attr != 0) + SetConsoleTextAttribute(h, attr); + n = printf("%s", buffer); + SetConsoleTextAttribute(h, info.wAttributes); + return n; +#else + n = printf("%s", buffer); + return n; +#endif +} + +int +test_check__(int cond, const char* file, int line, const char* fmt, ...) +{ + const char *result_str; + int result_color; + int verbose_level; + + if(cond) { + result_str = "ok"; + result_color = CUTEST_COLOR_GREEN__; + verbose_level = 3; + } else { + if(!test_current_already_logged__ && test_current_unit__ != NULL) { + printf("[ "); + test_print_in_color(CUTEST_COLOR_RED_INTENSIVE__, "FAILED"); + printf(" ]\n"); + } + result_str = "failed"; + result_color = CUTEST_COLOR_RED__; + verbose_level = 2; + test_current_failures__++; + test_current_already_logged__++; + } + + if(test_verbose_level__ >= verbose_level) { + size_t n = 0; + va_list args; + + printf(" "); + + if(file != NULL) + n += printf("%s:%d: Check ", file, line); + + va_start(args, fmt); + n += vprintf(fmt, args); + va_end(args); + + printf("... "); + test_print_in_color(result_color, result_str); + printf("\n"); + test_current_already_logged__++; + } + + return (cond != 0); +} + + +#ifndef TEST_NO_MAIN + +static char* test_argv0__ = NULL; +static int test_count__ = 0; +static int test_no_exec__ = 0; +static int test_no_summary__ = 0; +static int test_skip_mode__ = 0; + +static int test_stat_failed_units__ = 0; +static int test_stat_run_units__ = 0; + +const struct test__* test_current_unit__ = NULL; +int test_current_already_logged__ = 0; +int test_verbose_level__ = 2; +int test_current_failures__ = 0; +int test_colorize__ = 0; + + +static void +test_list_names__(void) +{ + const struct test__* test; + + printf("Unit tests:\n"); + for(test = &test_list__[0]; test->func != NULL; test++) + printf(" %s\n", test->name); +} + +static const struct test__* +test_by_name__(const char* name) +{ + const struct test__* test; + + for(test = &test_list__[0]; test->func != NULL; test++) { + if(strcmp(test->name, name) == 0) + return test; + } + + return NULL; +} + +static int +test_do_run__(const struct test__* test) +{ + test_current_unit__ = test; + test_current_failures__ = 0; + test_current_already_logged__ = 0; + + if(test_verbose_level__ >= 3) { + test_print_in_color(CUTEST_COLOR_DEFAULT_INTENSIVE__, "Test %s:\n", test->name); + test_current_already_logged__++; + } else if(test_verbose_level__ >= 1) { + size_t n; + char spaces[32]; + + n = test_print_in_color(CUTEST_COLOR_DEFAULT_INTENSIVE__, "Test %s... ", test->name); + memset(spaces, ' ', sizeof(spaces)); + if(n < sizeof(spaces)) + printf("%.*s", (int) (sizeof(spaces) - n), spaces); + } else { + test_current_already_logged__ = 1; + } + +#ifdef __cplusplus + try { +#endif + + test->func(); + +#ifdef __cplusplus + } catch(std::exception& e) { + const char* what = e.what(); + if(what != NULL) + test_check__(0, NULL, 0, "Threw std::exception: %s", what); + else + test_check__(0, NULL, 0, "Threw std::exception"); + } catch(...) { + test_check__(0, NULL, 0, "Threw an exception"); + } +#endif + + if(test_verbose_level__ >= 3) { + switch(test_current_failures__) { + case 0: test_print_in_color(CUTEST_COLOR_GREEN_INTENSIVE__, " All conditions have passed.\n\n"); break; + case 1: test_print_in_color(CUTEST_COLOR_RED_INTENSIVE__, " One condition has FAILED.\n\n"); break; + default: test_print_in_color(CUTEST_COLOR_RED_INTENSIVE__, " %d conditions have FAILED.\n\n", test_current_failures__); break; + } + } else if(test_verbose_level__ >= 1 && test_current_failures__ == 0) { + printf("[ "); + test_print_in_color(CUTEST_COLOR_GREEN_INTENSIVE__, "OK"); + printf(" ]\n"); + } + + test_current_unit__ = NULL; + return (test_current_failures__ == 0) ? 0 : -1; +} + +static void +test_error__(const char* fmt, ...) +{ + va_list args; + + if(!test_current_already_logged__ && test_current_unit__ != NULL) { + printf("[ "); + test_print_in_color(CUTEST_COLOR_RED_INTENSIVE__, "FAILED"); + printf(" ]\n"); + } + + if(test_verbose_level__ < 2) + return; + + test_print_in_color(CUTEST_COLOR_RED_INTENSIVE__, " Error: "); + va_start(args, fmt); + vprintf(fmt, args); + va_end(args); + printf("\n"); +} + +static void +test_run__(const struct test__* test) +{ + int failed = 1; + + test_current_unit__ = test; + test_current_already_logged__ = 0; + + if(!test_no_exec__) { + +#if defined(CUTEST_UNIX__) + + pid_t pid; + int exit_code; + + pid = fork(); + if(pid == (pid_t)-1) { + test_error__("Cannot fork. %s [%d]", strerror(errno), errno); + failed = 1; + } else if(pid == 0) { + failed = (test_do_run__(test) != 0); + exit(failed ? 1 : 0); + } else { + waitpid(pid, &exit_code, 0); + if(WIFEXITED(exit_code)) { + switch(WEXITSTATUS(exit_code)) { + case 0: failed = 0; break; /* test has passed. */ + case 1: /* noop */ break; /* "normal" failure. */ + default: test_error__("Unexpected exit code [%d]", WEXITSTATUS(exit_code)); + } + } else if(WIFSIGNALED(exit_code)) { + char tmp[32]; + const char* signame; + switch(WTERMSIG(exit_code)) { + case SIGINT: signame = "SIGINT"; break; + case SIGHUP: signame = "SIGHUP"; break; + case SIGQUIT: signame = "SIGQUIT"; break; + case SIGABRT: signame = "SIGABRT"; break; + case SIGKILL: signame = "SIGKILL"; break; + case SIGSEGV: signame = "SIGSEGV"; break; + case SIGILL: signame = "SIGILL"; break; + case SIGTERM: signame = "SIGTERM"; break; + default: sprintf(tmp, "signal %d", WTERMSIG(exit_code)); signame = tmp; break; + } + test_error__("Test interrupted by %s", signame); + } else { + test_error__("Test ended in an unexpected way [%d]", exit_code); + } + } + +#elif defined(CUTEST_WIN__) + + char buffer[512] = {0}; + STARTUPINFOA startupInfo = {0}; + PROCESS_INFORMATION processInfo; + DWORD exitCode; + + _snprintf(buffer, sizeof(buffer)-1, + "%s --no-exec --no-summary --verbose=%d --color=%s -- \"%s\"", + test_argv0__, test_verbose_level__, + test_colorize__ ? "always" : "never", test->name); + startupInfo.cb = sizeof(STARTUPINFO); + if(CreateProcessA(NULL, buffer, NULL, NULL, FALSE, 0, NULL, NULL, &startupInfo, &processInfo)) { + WaitForSingleObject(processInfo.hProcess, INFINITE); + GetExitCodeProcess(processInfo.hProcess, &exitCode); + CloseHandle(processInfo.hThread); + CloseHandle(processInfo.hProcess); + failed = (exitCode != 0); + } else { + test_error__("Cannot create unit test subprocess [%ld].", GetLastError()); + failed = 1; + } + +#else + + failed = (test_do_run__(test) != 0); + +#endif + + } else { + failed = (test_do_run__(test) != 0); + } + + test_current_unit__ = NULL; + + test_stat_run_units__++; + if(failed) + test_stat_failed_units__++; +} + +#if defined(CUTEST_WIN__) +static LONG CALLBACK +test_exception_filter__(EXCEPTION_POINTERS *ptrs) +{ + test_error__("Unhandled SEH exception %08lx at %p.", + ptrs->ExceptionRecord->ExceptionCode, + ptrs->ExceptionRecord->ExceptionAddress); + fflush(stdout); + fflush(stderr); + return EXCEPTION_EXECUTE_HANDLER; +} +#endif + +static void +test_help__(void) +{ + printf("Usage: %s [options] [test...]\n", test_argv0__); + printf("Run the specified unit tests; or if the option '--skip' is used, run all\n"); + printf("tests in the suite but those listed. By default, if no tests are specified\n"); + printf("on the command line, all unit tests in the suite are run.\n"); + printf("\n"); + printf("Options:\n"); + printf(" -s, --skip Execute all unit tests but the listed ones\n"); + printf(" --no-exec Do not execute unit tests as child processes\n"); + printf(" --no-summary Suppress printing of test results summary\n"); + printf(" -l, --list List unit tests in the suite and exit\n"); + printf(" -v, --verbose Enable more verbose output\n"); + printf(" --verbose=LEVEL Set verbose level to LEVEL (small integer)\n"); + printf(" --color=WHEN Enable colorized output (WHEN is one of 'auto', 'always', 'never')\n"); + printf(" -h, --help Display this help and exit\n"); + printf("\n"); + test_list_names__(); +} + +int +main(int argc, char** argv) +{ + const struct test__** tests = NULL; + int i, j, n = 0; + int seen_double_dash = 0; + + test_argv0__ = argv[0]; + +#if defined CUTEST_UNIX__ + test_colorize__ = isatty(fileno(stdout)); +#elif defined CUTEST_WIN__ + test_colorize__ = _isatty(_fileno(stdout)); +#else + test_colorize__ = 0; +#endif + + /* Parse options */ + for(i = 1; i < argc; i++) { + if(seen_double_dash || argv[i][0] != '-') { + tests = (const struct test__**) realloc(tests, (n+1) * sizeof(const struct test__*)); + if(tests == NULL) { + fprintf(stderr, "Out of memory.\n"); + exit(2); + } + tests[n] = test_by_name__(argv[i]); + if(tests[n] == NULL) { + fprintf(stderr, "%s: Unrecognized unit test '%s'\n", argv[0], argv[i]); + fprintf(stderr, "Try '%s --list' for list of unit tests.\n", argv[0]); + exit(2); + } + n++; + } else if(strcmp(argv[i], "--") == 0) { + seen_double_dash = 1; + } else if(strcmp(argv[i], "--help") == 0 || strcmp(argv[i], "-h") == 0) { + test_help__(); + exit(0); + } else if(strcmp(argv[i], "--verbose") == 0 || strcmp(argv[i], "-v") == 0) { + test_verbose_level__++; + } else if(strncmp(argv[i], "--verbose=", 10) == 0) { + test_verbose_level__ = atoi(argv[i] + 10); + } else if(strcmp(argv[i], "--color=auto") == 0) { + /* noop (set from above) */ + } else if(strcmp(argv[i], "--color=always") == 0 || strcmp(argv[i], "--color") == 0) { + test_colorize__ = 1; + } else if(strcmp(argv[i], "--color=never") == 0) { + test_colorize__ = 0; + } else if(strcmp(argv[i], "--skip") == 0 || strcmp(argv[i], "-s") == 0) { + test_skip_mode__ = 1; + } else if(strcmp(argv[i], "--no-exec") == 0) { + test_no_exec__ = 1; + } else if(strcmp(argv[i], "--no-summary") == 0) { + test_no_summary__ = 1; + } else if(strcmp(argv[i], "--list") == 0 || strcmp(argv[i], "-l") == 0) { + test_list_names__(); + exit(0); + } else { + fprintf(stderr, "%s: Unrecognized option '%s'\n", argv[0], argv[i]); + fprintf(stderr, "Try '%s --help' for more information.\n", argv[0]); + exit(2); + } + } + +#if defined(CUTEST_WIN__) + SetUnhandledExceptionFilter(test_exception_filter__); +#endif + + /* Count all test units */ + test_count__ = 0; + for(i = 0; test_list__[i].func != NULL; i++) + test_count__++; + + /* Run the tests */ + if(n == 0) { + /* Run all tests */ + for(i = 0; test_list__[i].func != NULL; i++) + test_run__(&test_list__[i]); + } else if(!test_skip_mode__) { + /* Run the listed tests */ + for(i = 0; i < n; i++) + test_run__(tests[i]); + } else { + /* Run all tests except those listed */ + int is_skipped; + + for(i = 0; test_list__[i].func != NULL; i++) { + is_skipped = 0; + for(j = 0; j < n; j++) { + if(tests[j] == &test_list__[i]) { + is_skipped = 1; + break; + } + } + if(!is_skipped) + test_run__(&test_list__[i]); + } + } + + /* Write a summary */ + if(!test_no_summary__ && test_verbose_level__ >= 1) { + test_print_in_color(CUTEST_COLOR_DEFAULT_INTENSIVE__, "\nSummary:\n"); + + if(test_verbose_level__ >= 3) { + printf(" Count of all unit tests: %4d\n", test_count__); + printf(" Count of run unit tests: %4d\n", test_stat_run_units__); + printf(" Count of failed unit tests: %4d\n", test_stat_failed_units__); + printf(" Count of skipped unit tests: %4d\n", test_count__ - test_stat_run_units__); + } + + if(test_stat_failed_units__ == 0) { + test_print_in_color(CUTEST_COLOR_GREEN_INTENSIVE__, + " SUCCESS: All unit tests have passed.\n"); + } else { + test_print_in_color(CUTEST_COLOR_RED_INTENSIVE__, + " FAILED: %d of %d unit tests have failed.\n", + test_stat_failed_units__, test_stat_run_units__); + } + } + + if(tests != NULL) + free(tests); + + return (test_stat_failed_units__ == 0) ? 0 : 1; +} + + +#endif /* #ifndef TEST_NO_MAIN */ + +#ifdef __cplusplus + } /* extern "C" */ +#endif + + +#endif /* #ifndef CUTEST_H__ */ diff --git a/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/ext/handy.h b/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/ext/handy.h new file mode 100644 index 00000000..936e70f4 --- /dev/null +++ b/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/ext/handy.h @@ -0,0 +1,66 @@ +#ifndef HANDY_H +#define HANDY_H + +#include +#include +#include + +/* + * Handy CPP defines and C inline functions. + */ + +/* Evaluates to the number of items in array-type variable arr. */ +#define ARRAYCOUNT(arr) (sizeof arr / sizeof arr[0]) + +#ifndef MIN +# define MIN(x, y) ((x) < (y) ? (x) : (y)) +#endif + +/** Stringify its argument. */ +#define STRINGIFY(x) STRINGIFY_(x) +#define STRINGIFY_(x) #x + +/* Error handling macros. + * + * These expect a zero = success, non-zero = error convention. + */ + +/** Error: return. + * + * If the expression fails, return the error from this function. */ +#define ER(expr) do { typeof (expr) err_ = (expr); if (err_) return err_; } while (0) + +/** Error: goto. + * + * If the expression fails, goto x_err. Assumes defn of label + * x_err and 'error_type err'. */ +#define EG(expr) do { err = (expr); if (err) goto x_err; } while (0) + +/** Like memset(ptr, 0, len), but not allowed to be removed by + * compilers. */ +static inline void mem_clean(volatile void *v, size_t len) +{ + if (len) + { + memset((void *) v, 0, len); + (void) *((volatile uint8_t *) v); + } +} + +/** Returns 1 if len bytes at va equal len bytes at vb, 0 if they do not. + * Does not leak length of common prefix through timing. */ +static inline unsigned mem_eq(const void *va, const void *vb, size_t len) +{ + const volatile uint8_t *a = va; + const volatile uint8_t *b = vb; + uint8_t diff = 0; + + while (len--) + { + diff |= *a++ ^ *b++; + } + + return !diff; +} + +#endif diff --git a/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/gcm.c b/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/gcm.c new file mode 100644 index 00000000..5b374732 --- /dev/null +++ b/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/gcm.c @@ -0,0 +1,249 @@ +/* + * cifra - embedded cryptography library + * Written in 2014 by Joseph Birr-Pixton + * + * To the extent possible under law, the author(s) have dedicated all + * copyright and related and neighboring rights to this software to the + * public domain worldwide. This software is distributed without any + * warranty. + * + * You should have received a copy of the CC0 Public Domain Dedication + * along with this software. If not, see + * . + */ + +#include "handy.h" +#include "prp.h" +#include "modes.h" +#include "blockwise.h" +#include "bitops.h" +#include "gf128.h" +#include "tassert.h" + +#include + +#define STATE_INVALID 0 +#define STATE_AAD 1 +#define STATE_CIPHER 2 + +static void ghash_init(ghash_ctx *ctx, uint8_t H[16]) +{ + memset(ctx, 0, sizeof *ctx); + cf_gf128_frombytes_be(H, ctx->H); + ctx->state = STATE_AAD; +} + +static void ghash_block(void *vctx, const uint8_t *data) +{ + ghash_ctx *ctx = vctx; + cf_gf128 gfdata; + cf_gf128_frombytes_be(data, gfdata); + cf_gf128_add(gfdata, ctx->Y, ctx->Y); + cf_gf128_mul(ctx->Y, ctx->H, ctx->Y); +} + +static void ghash_add(ghash_ctx *ctx, const uint8_t *buf, size_t n) +{ + cf_blockwise_accumulate(ctx->buffer, &ctx->buffer_used, + sizeof ctx->buffer, + buf, n, + ghash_block, + ctx); +} + +static void ghash_add_pad(ghash_ctx *ctx) +{ + if (ctx->buffer_used == 0) + return; + + memset(ctx->buffer + ctx->buffer_used, 0, sizeof(ctx->buffer) - ctx->buffer_used); + ghash_block(ctx, ctx->buffer); + ctx->buffer_used = 0; +} + +static void ghash_add_aad(ghash_ctx *ctx, const uint8_t *buf, size_t n) +{ + assert(ctx->state == STATE_AAD); + ctx->len_aad += n; + ghash_add(ctx, buf, n); +} + +static void ghash_add_cipher(ghash_ctx *ctx, const uint8_t *buf, size_t n) +{ + if (ctx->state == STATE_AAD) + { + ghash_add_pad(ctx); + ctx->state = STATE_CIPHER; + } + + assert(ctx->state == STATE_CIPHER); + ctx->len_cipher += n; + ghash_add(ctx, buf, n); +} + +static void ghash_final(ghash_ctx *ctx, uint8_t out[16]) +{ + uint8_t lenbuf[8]; + + if (ctx->state == STATE_AAD || ctx->state == STATE_CIPHER) + { + ghash_add_pad(ctx); + ctx->state = STATE_INVALID; + } + + /* Add len(A) || len(C) */ + write64_be(ctx->len_aad * 8, lenbuf); + ghash_add(ctx, lenbuf, sizeof lenbuf); + + write64_be(ctx->len_cipher * 8, lenbuf); + ghash_add(ctx, lenbuf, sizeof lenbuf); + + assert(ctx->buffer_used == 0); + cf_gf128_tobytes_be(ctx->Y, out); +} + +void cf_gcm_encrypt_init(const cf_prp *prp, void *prpctx, cf_gcm_ctx *gcmctx, + const uint8_t *header, size_t nheader, + const uint8_t *nonce, size_t nnonce) +{ + uint8_t H[16] = { 0 }; + + /* H = E_K(0^128) */ + prp->encrypt(prpctx, H, H); + + /* Produce CTR nonce, Y_0: + * + * if len(IV) == 96 + * Y_0 = IV || 0^31 || 1 + * otherwise + * Y_0 = GHASH(H, {}, IV) + */ + + if (nnonce == 12) + { + memcpy(gcmctx->Y0, nonce, nnonce); + gcmctx->Y0[12] = gcmctx->Y0[13] = gcmctx->Y0[14] = 0x00; + gcmctx->Y0[15] = 0x01; + } else { + ghash_init(&gcmctx->gh, H); + ghash_add_cipher(&gcmctx->gh, nonce, nnonce); + ghash_final(&gcmctx->gh, gcmctx->Y0); + } + + /* Hash AAD */ + ghash_init(&gcmctx->gh, H); + ghash_add_aad(&gcmctx->gh, header, nheader); + + /* Produce ciphertext */ + memset(gcmctx->e_Y0, 0, sizeof(gcmctx->e_Y0)); + cf_ctr_init(&gcmctx->ctr, prp, prpctx, gcmctx->Y0); + cf_ctr_custom_counter(&gcmctx->ctr, 12, 4); /* counter is 2^32 */ + cf_ctr_cipher(&gcmctx->ctr, gcmctx->e_Y0, gcmctx->e_Y0, sizeof gcmctx->e_Y0); /* first block is tag offset */ + + mem_clean(H, sizeof H); +} + +void cf_gcm_encrypt_update(cf_gcm_ctx *gcmctx, const uint8_t *plain, size_t nplain, uint8_t *cipher) +{ + cf_ctr_cipher(&gcmctx->ctr, plain, cipher, nplain); + ghash_add_cipher(&gcmctx->gh, cipher, nplain); +} + +void cf_gcm_encrypt_final(cf_gcm_ctx *gcmctx, uint8_t *tag, size_t ntag) +{ + /* Post-process ghash output */ + uint8_t full_tag[16] = { 0 }; + ghash_final(&gcmctx->gh, full_tag); + + assert(ntag > 1 && ntag <= 16); + xor_bb(tag, full_tag, gcmctx->e_Y0, ntag); + + mem_clean(full_tag, sizeof full_tag); + mem_clean(gcmctx, sizeof *gcmctx); +} + +void cf_gcm_encrypt(const cf_prp *prp, void *prpctx, + const uint8_t *plain, size_t nplain, + const uint8_t *header, size_t nheader, + const uint8_t *nonce, size_t nnonce, + uint8_t *cipher, /* the same size as nplain */ + uint8_t *tag, size_t ntag) +{ + cf_gcm_ctx gcmctx; + + cf_gcm_encrypt_init(prp, prpctx, &gcmctx, header, nheader, nonce, nnonce); + cf_gcm_encrypt_update(&gcmctx, plain, nplain, cipher); + cf_gcm_encrypt_final(&gcmctx, tag, ntag); +} + +int cf_gcm_decrypt(const cf_prp *prp, void *prpctx, + const uint8_t *cipher, size_t ncipher, + const uint8_t *header, size_t nheader, + const uint8_t *nonce, size_t nnonce, + const uint8_t *tag, size_t ntag, + uint8_t *plain) +{ + uint8_t H[16] = { 0 }; + uint8_t Y0[16]; + + /* H = E_K(0^128) */ + prp->encrypt(prpctx, H, H); + + /* Produce CTR nonce, Y_0: + * + * if len(IV) == 96 + * Y_0 = IV || 0^31 || 1 + * otherwise + * Y_0 = GHASH(H, {}, IV) + */ + + if (nnonce == 12) + { + memcpy(Y0, nonce, nnonce); + Y0[12] = Y0[13] = Y0[14] = 0x00; + Y0[15] = 0x01; + } else { + ghash_ctx gh; + ghash_init(&gh, H); + ghash_add_cipher(&gh, nonce, nnonce); + ghash_final(&gh, Y0); + } + + /* Hash AAD. */ + ghash_ctx gh; + ghash_init(&gh, H); + ghash_add_aad(&gh, header, nheader); + + /* Start counter mode, to obtain offset on tag. */ + uint8_t e_Y0[16] = { 0 }; + cf_ctr ctr; + cf_ctr_init(&ctr, prp, prpctx, Y0); + cf_ctr_custom_counter(&ctr, 12, 4); + cf_ctr_cipher(&ctr, e_Y0, e_Y0, sizeof e_Y0); + + /* Hash ciphertext. */ + ghash_add_cipher(&gh, cipher, ncipher); + + /* Produce tag. */ + uint8_t full_tag[16]; + ghash_final(&gh, full_tag); + assert(ntag > 1 && ntag <= 16); + xor_bb(full_tag, full_tag, e_Y0, ntag); + + int err = 1; + if (!mem_eq(full_tag, tag, ntag)) + goto x_err; + + /* Complete decryption. */ + cf_ctr_cipher(&ctr, cipher, plain, ncipher); + err = 0; + +x_err: + mem_clean(H, sizeof H); + mem_clean(Y0, sizeof Y0); + mem_clean(e_Y0, sizeof e_Y0); + mem_clean(full_tag, sizeof full_tag); + mem_clean(&gh, sizeof gh); + mem_clean(&ctr, sizeof ctr); + return err; +} diff --git a/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/gf128.c b/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/gf128.c new file mode 100644 index 00000000..f7ea834b --- /dev/null +++ b/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/gf128.c @@ -0,0 +1,114 @@ +/* + * cifra - embedded cryptography library + * Written in 2014 by Joseph Birr-Pixton + * + * To the extent possible under law, the author(s) have dedicated all + * copyright and related and neighboring rights to this software to the + * public domain worldwide. This software is distributed without any + * warranty. + * + * You should have received a copy of the CC0 Public Domain Dedication + * along with this software. If not, see + * . + */ + +#include "cf_config.h" +#include "gf128.h" +#include "bitops.h" + +#include + +void cf_gf128_tobytes_be(const cf_gf128 in, uint8_t out[16]) +{ + write32_be(in[0], out + 0); + write32_be(in[1], out + 4); + write32_be(in[2], out + 8); + write32_be(in[3], out + 12); +} + +void cf_gf128_frombytes_be(const uint8_t in[16], cf_gf128 out) +{ + out[0] = read32_be(in + 0); + out[1] = read32_be(in + 4); + out[2] = read32_be(in + 8); + out[3] = read32_be(in + 12); +} + +/* out = 2 * in. Arguments may alias. */ +void cf_gf128_double(const cf_gf128 in, cf_gf128 out) +{ + uint8_t table[2] = { 0x00, 0x87 }; + uint32_t borrow = 0; + uint32_t inword; + + inword = in[3]; out[3] = (inword << 1) | borrow; borrow = inword >> 31; + inword = in[2]; out[2] = (inword << 1) | borrow; borrow = inword >> 31; + inword = in[1]; out[1] = (inword << 1) | borrow; borrow = inword >> 31; + inword = in[0]; out[0] = (inword << 1) | borrow; borrow = inword >> 31; + +#if CF_CACHE_SIDE_CHANNEL_PROTECTION + out[3] ^= select_u8(borrow, table, 2); +#else + out[3] ^= table[borrow]; +#endif +} + +/* out = 2 * in. Arguments may alias. */ +void cf_gf128_double_le(const cf_gf128 in, cf_gf128 out) +{ + uint8_t table[2] = { 0x00, 0xe1 }; + uint32_t borrow = 0; + uint32_t inword; + + inword = in[0]; out[0] = (inword >> 1) | (borrow << 31); borrow = inword & 1; + inword = in[1]; out[1] = (inword >> 1) | (borrow << 31); borrow = inword & 1; + inword = in[2]; out[2] = (inword >> 1) | (borrow << 31); borrow = inword & 1; + inword = in[3]; out[3] = (inword >> 1) | (borrow << 31); borrow = inword & 1; + +#if CF_CACHE_SIDE_CHANNEL_PROTECTION + out[0] ^= select_u8(borrow, table, 2) << 24; +#else + out[0] ^= table[borrow] << 24; +#endif +} + +/* out = x + y. Arguments may alias. */ +void cf_gf128_add(const cf_gf128 x, const cf_gf128 y, cf_gf128 out) +{ + out[0] = x[0] ^ y[0]; + out[1] = x[1] ^ y[1]; + out[2] = x[2] ^ y[2]; + out[3] = x[3] ^ y[3]; +} + +/* out = xy. Arguments may alias. */ +void cf_gf128_mul(const cf_gf128 x, const cf_gf128 y, cf_gf128 out) +{ +#if CF_TIME_SIDE_CHANNEL_PROTECTION + cf_gf128 zero = { 0 }; +#endif + + /* Z_0 = 0^128 + * V_0 = Y */ + cf_gf128 Z, V; + memset(Z, 0, sizeof Z); + memcpy(V, y, sizeof V); + + int i; + for (i = 0; i < 128; i++) + { + uint32_t word = x[i >> 5]; + uint8_t bit = (word >> (31 - (i & 31))) & 1; + +#if CF_TIME_SIDE_CHANNEL_PROTECTION + select_xor128(Z, zero, V, bit); +#else + if (bit) + xor_words(Z, V, 4); +#endif + + cf_gf128_double_le(V, V); + } + + memcpy(out, Z, sizeof Z); +} diff --git a/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/gf128.h b/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/gf128.h new file mode 100644 index 00000000..75608623 --- /dev/null +++ b/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/gf128.h @@ -0,0 +1,55 @@ +/* + * cifra - embedded cryptography library + * Written in 2014 by Joseph Birr-Pixton + * + * To the extent possible under law, the author(s) have dedicated all + * copyright and related and neighboring rights to this software to the + * public domain worldwide. This software is distributed without any + * warranty. + * + * You should have received a copy of the CC0 Public Domain Dedication + * along with this software. If not, see + * . + */ + +#ifndef GF128_H +#define GF128_H + +#include +#include + +/** + * @brief Operations in GF(2^128). + * + * These implementations are constant time, but relatively slow. + */ + +typedef uint32_t cf_gf128[4]; + +/* Unpack from big-endian bytes into out. */ +void cf_gf128_frombytes_be(const uint8_t in[16], cf_gf128 out); + +/* Pack in big-endian order into out. */ +void cf_gf128_tobytes_be(const cf_gf128 in, uint8_t out[16]); + +/* out = 2 * in. Arguments may not alias. */ +void cf_gf128_double(const cf_gf128 in, cf_gf128 out); + +/* out = 2 * in. Arguments may not alias. + * This differs from cf_gf128_double because it interprets the + * block in little endian: the lsb is the msb of the + * first element, the msb is the lsb of the last element. + * + * GCM uses this convention. */ +void cf_gf128_double_le(const cf_gf128 in, cf_gf128 out); + +/* out = x + y. Arguments may alias. */ +void cf_gf128_add(const cf_gf128 x, const cf_gf128 y, cf_gf128 out); + +/* out = xy. Arguments may alias. + * + * This uses cf_gf128_double_le internally, and is suitable for + * GCM. */ +void cf_gf128_mul(const cf_gf128 x, const cf_gf128 y, cf_gf128 out); + +#endif diff --git a/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/hmac.c b/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/hmac.c new file mode 100644 index 00000000..98646d7e --- /dev/null +++ b/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/hmac.c @@ -0,0 +1,106 @@ +/* + * cifra - embedded cryptography library + * Written in 2014 by Joseph Birr-Pixton + * + * To the extent possible under law, the author(s) have dedicated all + * copyright and related and neighboring rights to this software to the + * public domain worldwide. This software is distributed without any + * warranty. + * + * You should have received a copy of the CC0 Public Domain Dedication + * along with this software. If not, see + * . + */ + +#include "hmac.h" +#include "chash.h" +#include "bitops.h" +#include "handy.h" +#include "tassert.h" + +#include + +void cf_hmac_init(cf_hmac_ctx *ctx, + const cf_chash *hash, + const uint8_t *key, size_t nkey) +{ + assert(ctx); + assert(hash); + + mem_clean(ctx, sizeof *ctx); + ctx->hash = hash; + + /* Prepare key: */ + uint8_t k[CF_CHASH_MAXBLK]; + + /* Shorten long keys. */ + if (nkey > hash->blocksz) + { + /* Standard doesn't cover case where blocksz < hashsz. + * FIPS186-1 seems to want to append a negative number of zero bytes. + * In any case, we only have a k buffer of CF_CHASH_MAXBLK! */ + assert(hash->hashsz <= hash->blocksz); + + cf_hash(hash, key, nkey, k); + key = k; + nkey = hash->hashsz; + } + + /* Right zero-pad short keys. */ + if (k != key) + memcpy(k, key, nkey); + if (hash->blocksz > nkey) + memset(k + nkey, 0, hash->blocksz - nkey); + + /* Start inner hash computation */ + uint8_t blk[CF_CHASH_MAXBLK]; + + xor_b8(blk, k, 0x36, hash->blocksz); + hash->init(&ctx->inner); + hash->update(&ctx->inner, blk, hash->blocksz); + + /* And outer. */ + xor_b8(blk, k, 0x5c, hash->blocksz); + hash->init(&ctx->outer); + hash->update(&ctx->outer, blk, hash->blocksz); + + mem_clean(blk, sizeof blk); + mem_clean(k, sizeof k); +} + +void cf_hmac_update(cf_hmac_ctx *ctx, const void *data, size_t ndata) +{ + assert(ctx && ctx->hash); + + ctx->hash->update(&ctx->inner, data, ndata); +} + +void cf_hmac_finish(cf_hmac_ctx *ctx, uint8_t *out) +{ + assert(ctx && ctx->hash); + assert(out); + + uint8_t innerh[CF_MAXHASH]; + ctx->hash->digest(&ctx->inner, innerh); + + ctx->hash->update(&ctx->outer, innerh, ctx->hash->hashsz); + ctx->hash->digest(&ctx->outer, out); + + mem_clean(ctx, sizeof *ctx); +} + +void cf_hmac(const uint8_t *key, size_t nkey, + const uint8_t *msg, size_t nmsg, + uint8_t *out, + const cf_chash *hash) +{ + cf_hmac_ctx ctx; + + assert(out); + assert(hash); + + cf_hmac_init(&ctx, hash, key, nkey); + cf_hmac_update(&ctx, msg, nmsg); + cf_hmac_finish(&ctx, out); +} + diff --git a/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/hmac.h b/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/hmac.h new file mode 100644 index 00000000..2f9ea7b0 --- /dev/null +++ b/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/hmac.h @@ -0,0 +1,78 @@ +/* + * cifra - embedded cryptography library + * Written in 2014 by Joseph Birr-Pixton + * + * To the extent possible under law, the author(s) have dedicated all + * copyright and related and neighboring rights to this software to the + * public domain worldwide. This software is distributed without any + * warranty. + * + * You should have received a copy of the CC0 Public Domain Dedication + * along with this software. If not, see + * . + */ + +#ifndef HMAC_H +#define HMAC_H + +#include +#include + +#include "chash.h" + +/** + * HMAC + * ==== + * This is a one-shot and incremental interface to computing + * HMAC with any hash function. + * + * (Note: HMAC with SHA3 is possible, but is probably not a + * sensible thing to want.) + */ + +/* .. c:type:: cf_hmac_ctx + * HMAC incremental interface context. + * + * .. c:member:: cf_hmac_ctx.hash + * Hash function description. + * + * .. c:member:: cf_hmac_ctx.inner + * Inner hash computation. + * + * .. c:member:: cf_hmac_ctx.outer + * Outer hash computation. + */ +typedef struct +{ + const cf_chash *hash; + cf_chash_ctx inner; + cf_chash_ctx outer; +} cf_hmac_ctx; + +/* .. c:function:: $DECL + * Set up ctx for computing a HMAC using the given hash and key. */ +void cf_hmac_init(cf_hmac_ctx *ctx, + const cf_chash *hash, + const uint8_t *key, size_t nkey); + +/* .. c:function:: $DECL + * Input data. */ +void cf_hmac_update(cf_hmac_ctx *ctx, + const void *data, size_t ndata); + +/* .. c:function:: $DECL + * Finish and compute HMAC. + * `ctx->hash->hashsz` bytes are written to `out`. */ +void cf_hmac_finish(cf_hmac_ctx *ctx, uint8_t *out); + +/* .. c:function:: $DECL + * One shot interface: compute `HMAC_hash(key, msg)`, writing the + * answer (which is `hash->hashsz` long) to `out`. + * + * This function does not fail. */ +void cf_hmac(const uint8_t *key, size_t nkey, + const uint8_t *msg, size_t nmsg, + uint8_t *out, + const cf_chash *hash); + +#endif diff --git a/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/modes.c b/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/modes.c new file mode 100644 index 00000000..1e44af1d --- /dev/null +++ b/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/modes.c @@ -0,0 +1,99 @@ +/* + * cifra - embedded cryptography library + * Written in 2014 by Joseph Birr-Pixton + * + * To the extent possible under law, the author(s) have dedicated all + * copyright and related and neighboring rights to this software to the + * public domain worldwide. This software is distributed without any + * warranty. + * + * You should have received a copy of the CC0 Public Domain Dedication + * along with this software. If not, see + * . + */ + +#include "prp.h" +#include "modes.h" +#include "bitops.h" +#include "blockwise.h" + +#include +#include "tassert.h" + +/* CBC */ +void cf_cbc_init(cf_cbc *ctx, const cf_prp *prp, void *prpctx, const uint8_t iv[CF_MAXBLOCK]) +{ + ctx->prp = prp; + ctx->prpctx = prpctx; + memcpy(ctx->block, iv, prp->blocksz); +} + +void cf_cbc_encrypt(cf_cbc *ctx, const uint8_t *input, uint8_t *output, size_t blocks) +{ + uint8_t buf[CF_MAXBLOCK]; + size_t nblk = ctx->prp->blocksz; + + while (blocks--) + { + xor_bb(buf, input, ctx->block, nblk); + ctx->prp->encrypt(ctx->prpctx, buf, ctx->block); + memcpy(output, ctx->block, nblk); + input += nblk; + output += nblk; + } +} + +void cf_cbc_decrypt(cf_cbc *ctx, const uint8_t *input, uint8_t *output, size_t blocks) +{ + uint8_t buf[CF_MAXBLOCK]; + size_t nblk = ctx->prp->blocksz; + + while (blocks--) + { + ctx->prp->decrypt(ctx->prpctx, input, buf); + xor_bb(output, buf, ctx->block, nblk); + memcpy(ctx->block, input, nblk); + input += nblk; + output += nblk; + } +} + +/* CTR */ +void cf_ctr_init(cf_ctr *ctx, const cf_prp *prp, void *prpctx, const uint8_t nonce[CF_MAXBLOCK]) +{ + memset(ctx, 0, sizeof *ctx); + ctx->counter_offset = 0; + ctx->counter_width = prp->blocksz; + ctx->prp = prp; + ctx->prpctx = prpctx; + ctx->nkeymat = 0; + memcpy(ctx->nonce, nonce, prp->blocksz); +} + +void cf_ctr_custom_counter(cf_ctr *ctx, size_t offset, size_t width) +{ + assert(ctx->prp->blocksz <= offset + width); + ctx->counter_offset = offset; + ctx->counter_width = width; +} + +static void ctr_next_block(void *vctx, uint8_t *out) +{ + cf_ctr *ctx = vctx; + ctx->prp->encrypt(ctx->prpctx, ctx->nonce, out); + incr_be(ctx->nonce + ctx->counter_offset, ctx->counter_width); +} + +void cf_ctr_cipher(cf_ctr *ctx, const uint8_t *input, uint8_t *output, size_t bytes) +{ + cf_blockwise_xor(ctx->keymat, &ctx->nkeymat, + ctx->prp->blocksz, + input, output, bytes, + ctr_next_block, + ctx); +} + +void cf_ctr_discard_block(cf_ctr *ctx) +{ + ctx->nkeymat = 0; +} diff --git a/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/modes.h b/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/modes.h new file mode 100644 index 00000000..20940a34 --- /dev/null +++ b/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/modes.h @@ -0,0 +1,587 @@ +/* + * cifra - embedded cryptography library + * Written in 2014 by Joseph Birr-Pixton + * + * To the extent possible under law, the author(s) have dedicated all + * copyright and related and neighboring rights to this software to the + * public domain worldwide. This software is distributed without any + * warranty. + * + * You should have received a copy of the CC0 Public Domain Dedication + * along with this software. If not, see + * . + */ + +#ifndef MODES_H +#define MODES_H + +#include +#include + +#include "gf128.h" +#include "prp.h" + +/** + * Block cipher modes + * ================== + */ + +/** + * CBC mode + * -------- + * This implementation allows encryption or decryption of whole + * blocks in CBC mode. It does not offer a byte-wise incremental + * interface, or do any padding. + * + * This mode provides no useful integrity and should not be used + * directly. + */ + +/* .. c:type:: cf_cbc + * This structure binds together the things needed to encrypt/decrypt whole + * blocks in CBC mode. + * + * .. c:member:: cf_cbc.prp + * How to encrypt or decrypt blocks. This could be, for example, :c:data:`cf_aes`. + * + * .. c:member:: cf_cbc.prpctx + * Private data for prp functions. For a `prp` of `cf_aes`, this would be a + * pointer to a :c:type:`cf_aes_context` instance. + * + * .. c:member:: cf_cbc.block + * The IV or last ciphertext block. + */ +typedef struct +{ + const cf_prp *prp; + void *prpctx; + uint8_t block[CF_MAXBLOCK]; +} cf_cbc; + +/* .. c:function:: $DECL + * Initialise CBC encryption/decryption context using selected prp, prp context and IV. */ +void cf_cbc_init(cf_cbc *ctx, const cf_prp *prp, void *prpctx, const uint8_t iv[CF_MAXBLOCK]); + +/* .. c:function:: $DECL + * Encrypt blocks in CBC mode. input and output + * must point to blocks * ctx->prp->blocksz bytes of storage (and may alias). */ +void cf_cbc_encrypt(cf_cbc *ctx, const uint8_t *input, uint8_t *output, size_t blocks); + +/* .. c:function:: $DECL + * Decrypt blocks in CBC mode. input and output + * must point to blocks * ctx->prp->blocksz bytes of storage (and may alias). */ +void cf_cbc_decrypt(cf_cbc *ctx, const uint8_t *input, uint8_t *output, size_t blocks); + +/** + * Counter mode + * ------------ + * This implementation allows incremental encryption/decryption of + * messages. Encryption and decryption are the same operation. + * + * The counter is always big-endian, but has configurable location + * and size within the nonce block. The counter wraps, so you + * should make sure the length of a message with a given nonce + * doesn't cause nonce reuse. + * + * This mode provides no integrity and should not be used directly. + */ + +/* .. c:type:: cf_ctr + * + * .. c:member:: cf_ctr.prp + * How to encrypt or decrypt blocks. This could be, for example, :c:data:`cf_aes`. + * + * .. c:member:: cf_ctr.prpctx + * Private data for prp functions. For a `prp` of `cf_aes`, this would be a + * pointer to a :c:type:`cf_aes_context` instance. + * + * .. c:member:: cf_ctr.nonce + * The next block to encrypt to get another block of key stream. + * + * .. c:member:: cf_ctr.keymat + * The current block of key stream. + * + * .. c:member:: cf_ctr.nkeymat + * The number of bytes at the end of :c:member:`keymat` that are so-far unused. + * If this is zero, all the bytes are used up and/or of undefined value. + * + * .. c:member:: cf_ctr.counter_offset + * The offset (in bytes) of the counter block within the nonce. + * + * .. c:member:: cf_ctr.counter_width + * The width (in bytes) of the counter block in the nonce. + */ +typedef struct +{ + const cf_prp *prp; + void *prpctx; + uint8_t nonce[CF_MAXBLOCK]; + uint8_t keymat[CF_MAXBLOCK]; + size_t nkeymat; + size_t counter_offset; + size_t counter_width; +} cf_ctr; + +/* .. c:function:: $DECL + * Initialise CTR encryption/decryption context using selected prp and nonce. + * (nb, this only increments the whole nonce as a big endian block) */ +void cf_ctr_init(cf_ctr *ctx, const cf_prp *prp, void *prpctx, const uint8_t nonce[CF_MAXBLOCK]); + +/* .. c:function:: $DECL + * Set the location and width of the nonce counter. + * + * eg. offset = 12, width = 4 means the counter is mod 2^32 and placed + * at the end of the nonce. */ +void cf_ctr_custom_counter(cf_ctr *ctx, size_t offset, size_t width); + +/* .. c:function:: $DECL + * Encrypt or decrypt bytes in CTR mode. + * input and output may alias and must point to specified number of bytes. */ +void cf_ctr_cipher(cf_ctr *ctx, const uint8_t *input, uint8_t *output, size_t bytes); + +/* .. c:function:: $DECL + * Discards the rest of this block of key stream. */ +void cf_ctr_discard_block(cf_ctr *ctx); + +/** + * CBC-MAC + * ------- + * This is a incremental interface to computing a CBC-MAC tag over a message. + * + * It optionally pads the message with PKCS#5/PKCS#7 padding -- if you don't + * do this, messages must be an exact number of blocks long. + * + * You shouldn't use this directly because it isn't secure for variable-length + * messages. Use CMAC instead. + */ + +/* .. c:type:: cf_cbcmac_stream + * Stream interface to CBC-MAC signing. + * + * .. c:member:: cf_cbcmac.prp + * How to encrypt or decrypt blocks. This could be, for example, :c:data:`cf_aes`. + * + * .. c:member:: cf_cbcmac.prpctx + * Private data for prp functions. For a `prp` of `cf_aes`, this would be a + * pointer to a :c:type:`cf_aes_context` instance. + * + * .. c:member:: cf_cbcmac.cbc + * CBC data. + * + * .. c:member:: cf_cbcmac.buffer + * Buffer for data which can't be processed until we have a full block. + * + * .. c:member:: cf_cbcmac.used + * How many bytes at the front of :c:member:`buffer` are valid. + */ +typedef struct +{ + const cf_prp *prp; + void *prpctx; + cf_cbc cbc; + uint8_t buffer[CF_MAXBLOCK]; + size_t used; +} cf_cbcmac_stream; + +/* .. c:function:: $DECL + * Initialise CBC-MAC signing context using selected prp. */ +void cf_cbcmac_stream_init(cf_cbcmac_stream *ctx, const cf_prp *prp, void *prpctx); + +/* .. c:function:: $DECL + * Reset the streaming signing context, to sign a new message. */ +void cf_cbcmac_stream_reset(cf_cbcmac_stream *ctx); + +/* .. c:function:: $DECL + * Process ndata bytes at data. */ +void cf_cbcmac_stream_update(cf_cbcmac_stream *ctx, const uint8_t *data, size_t ndata); + +/* .. c:function:: $DECL + * Finish the current block of data by adding zeroes. Does nothing if there + * are no bytes awaiting processing. */ +void cf_cbcmac_stream_finish_block_zero(cf_cbcmac_stream *ctx); + +/* .. c:function:: $DECL + * Output the MAC to ctx->prp->blocksz bytes at out. + * ctx->used must be zero: the inputed message must be an exact number of + * blocks. */ +void cf_cbcmac_stream_nopad_final(cf_cbcmac_stream *ctx, uint8_t out[CF_MAXBLOCK]); + +/* .. c:function:: $DECL + * Output the MAC to ctx->prp->blocksz bytes at out. + * + * The message is padded with PKCS#5 padding. */ +void cf_cbcmac_stream_pad_final(cf_cbcmac_stream *ctx, uint8_t out[CF_MAXBLOCK]); + +/** + * CMAC + * ---- + * This is both a one-shot and incremental interface to + * computing a CMAC tag over a message. + * + * The one-shot interface separates out the per-key computation, + * so if you need to compute lots of MACs with one key you don't + * pay that cost more than once. + * + * CMAC is a good choice for a symmetric MAC. + */ + +/* .. c:type:: cf_cmac + * One-shot interface to CMAC signing. + * + * .. c:member:: cf_cmac.prp + * How to encrypt or decrypt blocks. This could be, for example, :c:data:`cf_aes`. + * + * .. c:member:: cf_cmac.prpctx + * Private data for prp functions. For a `prp` of `cf_aes`, this would be a + * pointer to a :c:type:`cf_aes_context` instance. + * + * .. c:member:: cf_cmac.B + * The XOR offset for the last message block if it is a complete block + * (also known as K\ :sub:`1`). + * + * .. c:member:: cf_cmac.P + * The XOR offset for the last message block if it is a partial block + * (also known as K\ :sub:`2`). + */ +typedef struct +{ + const cf_prp *prp; + void *prpctx; + uint8_t B[CF_MAXBLOCK]; + uint8_t P[CF_MAXBLOCK]; +} cf_cmac; + +/* .. c:function:: $DECL + * Initialise CMAC signing context using selected prp. */ +void cf_cmac_init(cf_cmac *ctx, const cf_prp *prp, void *prpctx); + +/* .. c:function:: $DECL + * CMAC sign the given data. The MAC is written to ctx->prp->blocksz + * bytes at out. This is a one-shot function. */ +void cf_cmac_sign(cf_cmac *ctx, const uint8_t *data, size_t bytes, + uint8_t out[CF_MAXBLOCK]); + +/* .. c:type:: cf_cmac_stream + * Stream interface to CMAC signing. + * + * Input data in arbitrary chunks using :c:func:`cf_cmac_stream_update`. + * The last bit of data must be signalled with the `isfinal` flag to + * that function, and the data cannot be zero length unless the whole + * message is empty. + * + * .. c:member:: cf_cmac_stream.cmac + * CMAC one-shot data. + * + * .. c:member:: cf_cmac_stream.cbc + * CBC block encryption data. + * + * .. c:member:: cf_cmac_stream.buffer + * Buffer for data which can't be processed until we have a full block. + * + * .. c:member:: cf_cmac_stream.used + * How many bytes at the front of :c:member:`buffer` are valid. + * + * .. c:member:: cf_cmac_stream.processed + * How many bytes in total we've processed. This is used to correctly + * process empty messages. + * + * .. c:member:: cf_cmac_stream.finalised + * A flag set when the final chunk of the message has been processed. + * Only when this flag is set can you get the MAC out. + */ +typedef struct +{ + cf_cmac cmac; + cf_cbc cbc; + uint8_t buffer[CF_MAXBLOCK]; + size_t used; + size_t processed; + int finalised; +} cf_cmac_stream; + +/* .. c:function:: $DECL + * Initialise CMAC streaming signing context using selected prp. */ +void cf_cmac_stream_init(cf_cmac_stream *ctx, const cf_prp *prp, void *prpctx); + +/* .. c:function:: $DECL + * Reset the streaming signing context, to sign a new message. */ +void cf_cmac_stream_reset(cf_cmac_stream *ctx); + +/* .. c:function:: $DECL + * Process ndata bytes at data. isfinal is non-zero if this is the last piece + * of data. */ +void cf_cmac_stream_update(cf_cmac_stream *ctx, const uint8_t *data, size_t ndata, + int isfinal); + +/* .. c:function:: $DECL + * Output the MAC to ctx->cmac->prp->blocksz bytes at out. + * cf_cmac_stream_update with isfinal non-zero must have been called + * since the last _init/_reset. */ +void cf_cmac_stream_final(cf_cmac_stream *ctx, uint8_t out[CF_MAXBLOCK]); + +/** + * EAX + * --- + * + * The EAX authenticated encryption mode. This is a one-shot + * interface. + * + * EAX is a pretty respectable and fast AEAD mode. + */ + +/* .. c:function:: $DECL + * EAX authenticated encryption. + * + * This function does not fail. + * + * :param prp/prpctx: describe the block cipher to use. + * :param plain: message plaintext. + * :param nplain: length of message. May be zero. + * :param header: additionally authenticated data (AAD). + * :param nheader: length of AAD. May be zero. + * :param nonce: nonce. This must not repeat for a given key. + * :param nnonce: length of nonce. The nonce can be any length. + * :param cipher: ciphertext output. `nplain` bytes are written here. + * :param tag: authentication tag. `ntag` bytes are written here. + * :param ntag: authentication tag length. This must be non-zero and no greater than `prp->blocksz`. + */ +void cf_eax_encrypt(const cf_prp *prp, void *prpctx, + const uint8_t *plain, size_t nplain, + const uint8_t *header, size_t nheader, + const uint8_t *nonce, size_t nnonce, + uint8_t *cipher, + uint8_t *tag, size_t ntag); + +/* .. c:function:: $DECL + * EAX authenticated decryption. + * + * :return: 0 on success, non-zero on error. Nothing is written to plain on error. + * + * :param prp/prpctx: describe the block cipher to use. + * :param cipher: message ciphertext. + * :param ncipher: message length. + * :param header: additionally authenticated data (AAD). + * :param nheader: length of AAD. + * :param nonce: nonce. + * :param nnonce: length of nonce. + * :param tag: authentication tag. `ntag` bytes are read from here. + * :param ntag: authentication tag length. + * :param plain: plaintext output. `ncipher` bytes are written here. + */ +int cf_eax_decrypt(const cf_prp *prp, void *prpctx, + const uint8_t *cipher, size_t ncipher, + const uint8_t *header, size_t nheader, + const uint8_t *nonce, size_t nnonce, + const uint8_t *tag, size_t ntag, + uint8_t *plain); + +/** + * GCM + * --- + * The GCM ('Galois counter mode') authenticated encryption mode. + * This is a one-shot interface. + * + * GCM is a reasonably respectable AEAD mode. It's somewhat more + * complex than EAX, and side channel-free implementations can + * be quite slow. + */ + +/* .. c:function:: $DECL + * GCM authenticated encryption. + * + * This function does not fail. + * + * :param prp/prpctx: describe the block cipher to use. + * :param plain: message plaintext. + * :param nplain: length of message. May be zero. + * :param header: additionally authenticated data (AAD). + * :param nheader: length of AAD. May be zero. + * :param nonce: nonce. This must not repeat for a given key. + * :param nnonce: length of nonce. The nonce can be any length, but 12 bytes is strongly recommended. + * :param cipher: ciphertext output. `nplain` bytes are written here. + * :param tag: authentication tag. `ntag` bytes are written here. + * :param ntag: authentication tag length. This must be non-zero and no greater than `prp->blocksz`. + * + * This function does not fail. + */ +void cf_gcm_encrypt(const cf_prp *prp, void *prpctx, + const uint8_t *plain, size_t nplain, + const uint8_t *header, size_t nheader, + const uint8_t *nonce, size_t nnonce, + uint8_t *cipher, + uint8_t *tag, size_t ntag); + +/* Incremental GHASH computation. */ +typedef struct +{ + cf_gf128 H; + cf_gf128 Y; + uint8_t buffer[16]; + size_t buffer_used; + uint64_t len_aad; + uint64_t len_cipher; + unsigned state; +} ghash_ctx; + +typedef struct +{ + cf_ctr ctr; + ghash_ctx gh; + uint8_t Y0[16]; + uint8_t e_Y0[16]; +} cf_gcm_ctx; + +void cf_gcm_encrypt_init(const cf_prp *prp, void *prpctx, cf_gcm_ctx *gcmctx, + const uint8_t *header, size_t nheader, + const uint8_t *nonce, size_t nnonce); +void cf_gcm_encrypt_update(cf_gcm_ctx *gcmctx, const uint8_t *plain, size_t nplain, uint8_t *cipher); +void cf_gcm_encrypt_final(cf_gcm_ctx *gcmctx, uint8_t *tag, size_t ntag); + +/* .. c:function:: $DECL + * GCM authenticated decryption. + * + * :return: 0 on success, non-zero on error. Nothing is written to plain on error. + * + * :param prp: describe the block cipher to use. + * :param prpctx: describe the block cipher to use. + * :param cipher: message ciphertext. + * :param ncipher: message length. + * :param header: additionally authenticated data (AAD). + * :param nheader: length of AAD. + * :param nonce: nonce. + * :param nnonce: length of nonce. + * :param tag: authentication tag. `ntag` bytes are read from here. + * :param ntag: authentication tag length. + * :param plain: plaintext output. `ncipher` bytes are written here. + */ +int cf_gcm_decrypt(const cf_prp *prp, void *prpctx, + const uint8_t *cipher, size_t ncipher, + const uint8_t *header, size_t nheader, + const uint8_t *nonce, size_t nnonce, + const uint8_t *tag, size_t ntag, + uint8_t *plain); + +/** + * CCM + * --- + * + * The CCM ('Counter with CBC-MAC') authenticated encryption mode. + * CCM is a widely used AEAD mode (in IPSec, WPA2, Bluetooth, etc.) + * + * It works (at a high level) by just gluing together CTR and CBC-MAC + * modes (in MAC-then-encrypt mode) and then fixing the problems inherent + * with CBC-MAC in over-complicated ways. + * + * This is a one-shot interface, which is good because the underlying + * mechanism isn't actually online: you need to know the message length + * before you start, or do everything in two passes. + */ + +/* .. c:function:: $DECL + * CCM authenticated encryption. + * + * This function does not fail. + * + * :param prp/prpctx: describe the block cipher to use. + * :param plain: message plaintext. + * :param nplain: length of message. May be zero. Must meet the constraints placed on it by `L`. + * :param L: length of the message length encoding. This must be in the interval `[2,8]` and gives a maximum message size of 2\ :sup:`8L` bytes. + * :param header: additionally authenticated data (AAD). + * :param nheader: length of AAD. May be zero. + * :param nonce: nonce. This must not repeat for a given key. + * :param nnonce: length of nonce. Must be exactly `15 - L` bytes for a 128-bit block cipher. + * :param cipher: ciphertext output. `nplain` bytes are written here. + * :param tag: authentication tag. `ntag` bytes are written here. + * :param ntag: authentication tag length. This must be 4, 6, 8, 10, 12, 14 or 16. + */ +void cf_ccm_encrypt(const cf_prp *prp, void *prpctx, + const uint8_t *plain, size_t nplain, size_t L, + const uint8_t *header, size_t nheader, + const uint8_t *nonce, size_t nnonce, + uint8_t *cipher, + uint8_t *tag, size_t ntag); + +/* .. c:function:: $DECL + * CCM authenticated decryption. + * + * :return: 0 on success, non-zero on error. Plain is cleared on error. + * + * :param prp: describe the block cipher to use. + * :param prpctx: describe the block cipher to use. + * :param cipher: message ciphertext. + * :param ncipher: length of message. + * :param L: length of the message length encoding. See :c:func:`cf_ccm_encrypt`. + * :param header: additionally authenticated data (AAD). + * :param nheader: length of AAD. + * :param nonce: nonce. + * :param nnonce: length of nonce. + * :param tag: authentication tag. `ntag` bytes are read from here. + * :param ntag: authentication tag length. This must be 4, 6, 8, 10, 12, 14 or 16. + * :param plain: plaintext output. `ncipher` bytes are written here. + */ +int cf_ccm_decrypt(const cf_prp *prp, void *prpctx, + const uint8_t *cipher, size_t ncipher, size_t L, + const uint8_t *header, size_t nheader, + const uint8_t *nonce, size_t nnonce, + const uint8_t *tag, size_t ntag, + uint8_t *plain); + +/** + * OCB + * --- + * + * OCB is an authenticated encryption mode by Phil Rogaway. + * + * This is version 3, as standardised in RFC7253. It's defined + * only for block ciphers with a 128-bit block size. + * + * This is a one-shot interface. + */ + +/* .. c:function:: $DECL + * OCB authenticated encryption. + * + * This function does not fail. + * + * :param prp/prpctx: describe the block cipher to use. + * :param plain: message plaintext. + * :param nplain: length of message. May be zero. + * :param header: additionally authenticated data (AAD). + * :param nheader: length of AAD. May be zero. + * :param nonce: nonce. This must not repeat for a given key. + * :param nnonce: length of nonce. Must be 15 or fewer bytes. + * :param cipher: ciphertext output. `nplain` bytes are written here. + * :param tag: authentication tag. `ntag` bytes are written here. + * :param ntag: authentication tag length. Must be 16 or fewer bytes. + */ +void cf_ocb_encrypt(const cf_prp *prp, void *prpctx, + const uint8_t *plain, size_t nplain, + const uint8_t *header, size_t nheader, + const uint8_t *nonce, size_t nnonce, + uint8_t *cipher, + uint8_t *tag, size_t ntag); + +/* .. c:function:: $DECL + * OCB authenticated decryption. + * + * :return: 0 on success, non-zero on error. `plain` is cleared on error. + * + * :param prp: describe the block cipher to use. + * :param prpctx: describe the block cipher to use. + * :param cipher: message ciphertext. + * :param ncipher: length of message. + * :param header: additionally authenticated data (AAD). + * :param nheader: length of AAD. + * :param nonce: nonce. + * :param nnonce: length of nonce. + * :param tag: authentication tag. `ntag` bytes are read from here. + * :param ntag: authentication tag length. + * :param plain: plaintext output. `ncipher` bytes are written here. + */ +int cf_ocb_decrypt(const cf_prp *prp, void *prpctx, + const uint8_t *cipher, size_t ncipher, + const uint8_t *header, size_t nheader, + const uint8_t *nonce, size_t nnonce, + const uint8_t *tag, size_t ntag, + uint8_t *plain); +#endif diff --git a/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/norx.c b/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/norx.c new file mode 100644 index 00000000..8f0aba6b --- /dev/null +++ b/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/norx.c @@ -0,0 +1,410 @@ +/* + * cifra - embedded cryptography library + * Written in 2014 by Joseph Birr-Pixton + * + * To the extent possible under law, the author(s) have dedicated all + * copyright and related and neighboring rights to this software to the + * public domain worldwide. This software is distributed without any + * warranty. + * + * You should have received a copy of the CC0 Public Domain Dedication + * along with this software. If not, see + * . + */ + + +#include "norx.h" +#include "bitops.h" +#include "handy.h" +#include "blockwise.h" +#include "tassert.h" + +#include + +typedef struct +{ + uint32_t s[16]; +} norx32_ctx; + +/* Domain separation constants */ +#define DOMAIN_HEADER 0x01 +#define DOMAIN_PAYLOAD 0x02 +#define DOMAIN_TRAILER 0x04 +#define DOMAIN_TAG 0x08 + +#define WORD_BYTES 4 +#define WORD_BITS 32 +#define ROUNDS 4 +#define DEGREE 1 +#define TAG_BITS 128 +#define RATE_BYTES 48 +#define RATE_WORDS 12 + +static void permute(norx32_ctx *ctx) +{ +#ifdef CORTEX_M0 + /* Register usage: A-D r2, r3, r4, r5. + * Temps: r6 */ + +#define in(xx) "%[" #xx "]" + + /* Load numbered slots of S into r2-r5 */ +#define LOAD(u, v, w, x) \ + " ldr r2, [%[S], " in(u) "]\n" \ + " ldr r3, [%[S], " in(v) "]\n" \ + " ldr r4, [%[S], " in(w) "]\n" \ + " ldr r5, [%[S], " in(x) "]\n" + + /* Store r2-r5 into numbered slots of S */ +#define STORE(u, v, w, x) \ + " str r2, [%[S], " in(u) "]\n" \ + " str r3, [%[S], " in(v) "]\n" \ + " str r4, [%[S], " in(w) "]\n" \ + " str r5, [%[S], " in(x) "]\n" + + /* This is H() plus the xor and rotate in one step of G. + * rx is the register containing x (read/write) + * ry is the register containing y (read) + * rw is the register containing d (read/write) + * rot is the rotation constant r_n */ +#define P(rx, ry, rw, rot) \ + " mov r6, " #rx "\n" \ + " and " #rx ", " #ry "\n" \ + " lsl " #rx ", #1\n" \ + " eor " #rx ", r6\n" \ + " eor " #rx ", " #ry "\n" \ + " mov r6, #" #rot "\n" \ + " eor " #rw ", " #rx "\n" \ + " ror " #rw ", r6\n" + + /* The function G. s is the state array, a-d are indices + * into it. */ +#define G(s, a, b, c, d) \ + __asm__ ( \ + LOAD(A, B, C, D) \ + P(r2, r3, r5, 8) \ + P(r4, r5, r3, 11) \ + P(r2, r3, r5, 16) \ + P(r4, r5, r3, 31) \ + STORE(A, B, C, D) \ + : \ + : [S] "r" (s), \ + [A] "i" (a << 2), \ + [B] "i" (b << 2), \ + [C] "i" (c << 2), \ + [D] "i" (d << 2) \ + : "memory", "cc", "r2", "r3", "r4", "r5", "r6"); +#else + + /* This is one quarter of G; the function H plus xor/rotate. */ +#define P(u, v, w, rr) \ + (u) = ((u) ^ (v)) ^ (((u) & (v)) << 1); \ + (w) = rotr32((u) ^ (w), rr); + +#define G(s, a, b, c, d) \ + P(s[a], s[b], s[d], 8) \ + P(s[c], s[d], s[b], 11) \ + P(s[a], s[b], s[d], 16) \ + P(s[c], s[d], s[b], 31) +#endif + + for (int i = 0; i < ROUNDS; i++) + { + /* columns */ + G(ctx->s, 0, 4, 8, 12); + G(ctx->s, 1, 5, 9, 13); + G(ctx->s, 2, 6, 10, 14); + G(ctx->s, 3, 7, 11, 15); + + /* diagonals */ + G(ctx->s, 0, 5, 10, 15); + G(ctx->s, 1, 6, 11, 12); + G(ctx->s, 2, 7, 8, 13); + G(ctx->s, 3, 4, 9, 14); + } + +#undef G +#undef P +} + +static void init(norx32_ctx *ctx, + const uint8_t key[16], + const uint8_t nonce[8]) +{ + /* 1. Basic setup */ + ctx->s[0] = read32_le(nonce + 0); + ctx->s[1] = read32_le(nonce + 4); + ctx->s[2] = 0xb707322f; + ctx->s[3] = 0xa0c7c90d; + + ctx->s[4] = read32_le(key + 0); + ctx->s[5] = read32_le(key + 4); + ctx->s[6] = read32_le(key + 8); + ctx->s[7] = read32_le(key + 12); + + ctx->s[8] = 0xa3d8d930; + ctx->s[9] = 0x3fa8b72c; + ctx->s[10] = 0xed84eb49; + ctx->s[11] = 0xedca4787; + + ctx->s[12] = 0x335463eb; + ctx->s[13] = 0xf994220b; + ctx->s[14] = 0xbe0bf5c9; + ctx->s[15] = 0xd7c49104; + + /* 2. Parameter integration + * w = 32 + * l = 4 + * p = 1 + * t = 128 + */ + ctx->s[12] ^= WORD_BITS; + ctx->s[13] ^= ROUNDS; + ctx->s[14] ^= DEGREE; + ctx->s[15] ^= TAG_BITS; + + permute(ctx); +} + +/* Input domain separation constant for next step, and final permutation of + * preceeding step. */ +static void switch_domain(norx32_ctx *ctx, uint32_t constant) +{ + ctx->s[15] ^= constant; + permute(ctx); +} + +typedef struct +{ + norx32_ctx *ctx; + uint32_t type; +} blockctx; + +static void input_block_final(void *vctx, const uint8_t *data) +{ + blockctx *bctx = vctx; + norx32_ctx *ctx = bctx->ctx; + + /* just xor-in data. */ + for (int i = 0; i < RATE_WORDS; i++) + { + ctx->s[i] ^= read32_le(data); + data += WORD_BYTES; + } +} + +static void input_block(void *vctx, const uint8_t *data) +{ + /* Process block, then prepare for the next one. */ + blockctx *bctx = vctx; + input_block_final(vctx, data); + switch_domain(bctx->ctx, bctx->type); +} + +static void input(norx32_ctx *ctx, uint32_t type, + const uint8_t *buf, size_t nbuf) +{ + uint8_t partial[RATE_BYTES]; + size_t npartial = 0; + blockctx bctx = { ctx, type }; + + /* Process input. */ + cf_blockwise_accumulate(partial, &npartial, sizeof partial, + buf, nbuf, + input_block, + &bctx); + + /* Now pad partial. This contains the trailing portion of buf. */ + memset(partial + npartial, 0, sizeof(partial) - npartial); + partial[npartial] = 0x01; + partial[sizeof(partial) - 1] ^= 0x80; + + input_block_final(&bctx, partial); +} + +static void do_header(norx32_ctx *ctx, const uint8_t *buf, size_t nbuf) +{ + if (nbuf) + { + switch_domain(ctx, DOMAIN_HEADER); + input(ctx, DOMAIN_HEADER, buf, nbuf); + } +} + +static void do_trailer(norx32_ctx *ctx, const uint8_t *buf, size_t nbuf) +{ + if (nbuf) + { + switch_domain(ctx, DOMAIN_TRAILER); + input(ctx, DOMAIN_TRAILER, buf, nbuf); + } +} + +static void body_block_encrypt(norx32_ctx *ctx, + const uint8_t plain[RATE_BYTES], + uint8_t cipher[RATE_BYTES]) +{ + for (int i = 0; i < RATE_WORDS; i++) + { + ctx->s[i] ^= read32_le(plain); + write32_le(ctx->s[i], cipher); + plain += WORD_BYTES; + cipher += WORD_BYTES; + } +} + +static void encrypt_body(norx32_ctx *ctx, + const uint8_t *plain, uint8_t *cipher, size_t nbytes) +{ + if (nbytes == 0) + return; + + /* Process full blocks: easy */ + while (nbytes >= RATE_BYTES) + { + switch_domain(ctx, DOMAIN_PAYLOAD); + body_block_encrypt(ctx, plain, cipher); + plain += RATE_BYTES; + cipher += RATE_BYTES; + nbytes -= RATE_BYTES; + } + + /* Final padded block. */ + uint8_t partial[RATE_BYTES]; + memset(partial, 0, sizeof partial); + memcpy(partial, plain, nbytes); + partial[nbytes] ^= 0x01; + partial[sizeof(partial) - 1] ^= 0x80; + + switch_domain(ctx, DOMAIN_PAYLOAD); + body_block_encrypt(ctx, partial, partial); + + memcpy(cipher, partial, nbytes); +} + +static void body_block_decrypt(norx32_ctx *ctx, + const uint8_t cipher[RATE_BYTES], + uint8_t plain[RATE_BYTES], + size_t start, size_t end) +{ + for (size_t i = start; i < end; i++) + { + uint32_t ct = read32_le(cipher); + write32_le(ctx->s[i] ^ ct, plain); + ctx->s[i] = ct; + plain += WORD_BYTES; + cipher += WORD_BYTES; + } +} + +static void undo_padding(norx32_ctx *ctx, size_t bytes) +{ + assert(bytes < RATE_BYTES); + ctx->s[bytes / WORD_BYTES] ^= 0x01 << ((bytes % WORD_BYTES) * 8); + ctx->s[RATE_WORDS - 1] ^= 0x80000000; +} + +static void decrypt_body(norx32_ctx *ctx, + const uint8_t *cipher, uint8_t *plain, size_t nbytes) +{ + if (nbytes == 0) + return; + + /* Process full blocks. */ + while (nbytes >= RATE_BYTES) + { + switch_domain(ctx, DOMAIN_PAYLOAD); + body_block_decrypt(ctx, cipher, plain, 0, RATE_WORDS); + plain += RATE_BYTES; + cipher += RATE_BYTES; + nbytes -= RATE_BYTES; + } + + /* Then partial blocks. */ + size_t offset = 0; + switch_domain(ctx, DOMAIN_PAYLOAD); + + undo_padding(ctx, nbytes); + + /* In units of whole words. */ + while (nbytes >= WORD_BYTES) + { + body_block_decrypt(ctx, cipher, plain, offset, offset + 1); + plain += WORD_BYTES; + cipher += WORD_BYTES; + nbytes -= WORD_BYTES; + offset += 1; + } + + /* And then, finally, bytewise. */ + uint8_t tmp[WORD_BYTES]; + write32_le(ctx->s[offset], tmp); + + for (size_t i = 0; i < nbytes; i++) + { + uint8_t c = cipher[i]; + plain[i] = tmp[i] ^ c; + tmp[i] = c; + } + + ctx->s[offset] = read32_le(tmp); +} + +static void get_tag(norx32_ctx *ctx, uint8_t tag[16]) +{ + switch_domain(ctx, DOMAIN_TAG); + permute(ctx); + write32_le(ctx->s[0], tag + 0); + write32_le(ctx->s[1], tag + 4); + write32_le(ctx->s[2], tag + 8); + write32_le(ctx->s[3], tag + 12); +} + +void cf_norx32_encrypt(const uint8_t key[16], + const uint8_t nonce[8], + const uint8_t *header, size_t nheader, + const uint8_t *plaintext, size_t nbytes, + const uint8_t *trailer, size_t ntrailer, + uint8_t *ciphertext, + uint8_t tag[16]) +{ + norx32_ctx ctx; + + init(&ctx, key, nonce); + do_header(&ctx, header, nheader); + encrypt_body(&ctx, plaintext, ciphertext, nbytes); + do_trailer(&ctx, trailer, ntrailer); + get_tag(&ctx, tag); + + mem_clean(&ctx, sizeof ctx); +} + +int cf_norx32_decrypt(const uint8_t key[16], + const uint8_t nonce[8], + const uint8_t *header, size_t nheader, + const uint8_t *ciphertext, size_t nbytes, + const uint8_t *trailer, size_t ntrailer, + const uint8_t tag[16], + uint8_t *plaintext) +{ + norx32_ctx ctx; + uint8_t ourtag[16]; + + init(&ctx, key, nonce); + do_header(&ctx, header, nheader); + decrypt_body(&ctx, ciphertext, plaintext, nbytes); + do_trailer(&ctx, trailer, ntrailer); + get_tag(&ctx, ourtag); + + int err = 0; + + if (!mem_eq(ourtag, tag, sizeof ourtag)) + { + err = 1; + mem_clean(plaintext, nbytes); + mem_clean(ourtag, sizeof ourtag); + } + + mem_clean(&ctx, sizeof ctx); + return err; +} diff --git a/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/norx.h b/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/norx.h new file mode 100644 index 00000000..aee7bfe1 --- /dev/null +++ b/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/norx.h @@ -0,0 +1,84 @@ +/* + * cifra - embedded cryptography library + * Written in 2014 by Joseph Birr-Pixton + * + * To the extent possible under law, the author(s) have dedicated all + * copyright and related and neighboring rights to this software to the + * public domain worldwide. This software is distributed without any + * warranty. + * + * You should have received a copy of the CC0 Public Domain Dedication + * along with this software. If not, see + * . + */ + +#ifndef NORX_H +#define NORX_H + +#include +#include + +/** + * The NORX AEAD cipher + * ==================== + * This is an implementation of NORX32-4-1 with a one-shot + * interface. NORX is a CAESAR candidate with a core similar + * to ChaCha20 and a sponge structure like Keccak. + * + * This is NORX v2.0. It is not compatible with earlier + * versions. + * + * NORX32 uses a 128-bit key. Each encryption requires a + * 64-bit nonce. An encryption processes one sequence of + * additional data ('header'), followed by encryption of + * the plaintext, followed by processing a second sequence + * of additional data ('trailer'). It outputs a 128-bit + * tag. + */ + +/* .. c:function:: $DECL + * NORX32-4-1 one-shot encryption interface. + * + * :param key: key material. + * :param nonce: per-message nonce. + * :param header: header buffer. + * :param nheader: number of header bytes. + * :param plaintext: plaintext bytes to be encrypted. + * :param nbytes: number of plaintext/ciphertext bytes. + * :param trailer: trailer buffer. + * :param ntrailer: number of trailer bytes. + * :param ciphertext: ciphertext output buffer, nbytes in length. + * :param tag: authentication tag output buffer. + */ +void cf_norx32_encrypt(const uint8_t key[16], + const uint8_t nonce[8], + const uint8_t *header, size_t nheader, + const uint8_t *plaintext, size_t nbytes, + const uint8_t *trailer, size_t ntrailer, + uint8_t *ciphertext, + uint8_t tag[16]); +/* .. c:function:: $DECL + * NORX32-4-1 one-shot decryption interface. + * + * :return: 0 on success, non-zero on error. Plaintext is zeroed on error. + * + * :param key: key material. + * :param nonce: per-message nonce. + * :param header: header buffer. + * :param nheader: number of header bytes. + * :param ciphertext: ciphertext bytes to be decrypted. + * :param nbytes: number of plaintext/ciphertext bytes. + * :param trailer: trailer buffer. + * :param ntrailer: number of trailer bytes. + * :param plaintext: plaintext output buffer, nbytes in length. + * :param tag: authentication tag output buffer. + */ +int cf_norx32_decrypt(const uint8_t key[16], + const uint8_t nonce[8], + const uint8_t *header, size_t nheader, + const uint8_t *ciphertext, size_t nbytes, + const uint8_t *trailer, size_t ntrailer, + const uint8_t tag[16], + uint8_t *plaintext); + +#endif diff --git a/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/ocb.c b/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/ocb.c new file mode 100644 index 00000000..3d244d4e --- /dev/null +++ b/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/ocb.c @@ -0,0 +1,404 @@ +/* + * cifra - embedded cryptography library + * Written in 2016 by Joseph Birr-Pixton + * + * To the extent possible under law, the author(s) have dedicated all + * copyright and related and neighboring rights to this software to the + * public domain worldwide. This software is distributed without any + * warranty. + * + * You should have received a copy of the CC0 Public Domain Dedication + * along with this software. If not, see + * . + */ + +#include "handy.h" +#include "prp.h" +#include "modes.h" +#include "blockwise.h" +#include "bitops.h" +#include "gf128.h" +#include "tassert.h" + +#include + +/* How many L_n values to compute at schedule time. */ +#define MAX_L 4 + +/* We and RFC7253 assume 128-bit blocks. */ +#define BLOCK 16 + +typedef struct +{ + const cf_prp *prp; + void *prpctx; /* Our PRP */ + uint8_t *out; /* Output pointer for block processing */ + cf_gf128 L_star; /* Zero block ciphertext */ + cf_gf128 L_dollar; /* L_$ is double of L_* */ + cf_gf128 L[MAX_L]; /* L[0] is double of L_$, L[1] is double of L[0], etc. */ + cf_gf128 offset; /* Offset_i */ + cf_gf128 checksum; /* Checksum_i */ + uint32_t i; /* Block index, 1-based */ +} ocb; + +typedef struct +{ + ocb *o; /* OCB context (contains PRP, etc.) */ + cf_gf128 sum; /* Current Sum_i */ + cf_gf128 offset; /* Current Offset_i */ + uint32_t i; /* Block index, 1-based */ +} ocb_hash; + +static void ocb_init(ocb *o, const cf_prp *prp, void *prpctx, + const uint8_t *nonce, size_t nnonce, + size_t ntag) +{ + o->prp = prp; + o->prpctx = prpctx; + + assert(o->prp->blocksz == BLOCK); + + /* L_* = ENCIPHER(K, zeros(128)) */ + uint8_t L_star_bytes[BLOCK] = { 0 }; + prp->encrypt(prpctx, L_star_bytes, L_star_bytes); + cf_gf128_frombytes_be(L_star_bytes, o->L_star); + + /* L_$ = double(L_*) */ + cf_gf128_double(o->L_star, o->L_dollar); + + /* L_0 = double(L_$) etc. */ + cf_gf128_double(o->L_dollar, o->L[0]); + + for (int i = 1; i < MAX_L; i++) + cf_gf128_double(o->L[i - 1], o->L[i]); + + /* Compute nonce-dependent and per-encryption vars */ + assert(nnonce > 0 && nnonce < BLOCK); + uint8_t full_nonce[BLOCK] = { 0 }; + full_nonce[0] = ((ntag * 8) & 0x7f) << 1; + full_nonce[BLOCK - 1 - nnonce] |= 0x01; + memcpy(full_nonce + BLOCK - nnonce, nonce, nnonce); + uint8_t bottom = full_nonce[BLOCK - 1] & 0x3f; + + /* Make Ktop */ + full_nonce[BLOCK - 1] &= 0xc0; + uint8_t Ktop[BLOCK + 8]; + prp->encrypt(prpctx, full_nonce, Ktop); + + /* Stretch Ktop */ + for (int i = 0; i < 8; i++) + Ktop[i + BLOCK] = Ktop[i] ^ Ktop[i + 1]; + + /* Outputs */ + uint8_t offset[BLOCK]; + copy_bytes_unaligned(offset, Ktop, BLOCK, bottom); + cf_gf128_frombytes_be(offset, o->offset); + memset(o->checksum, 0, sizeof o->checksum); +} + +static void ocb_start_cipher(ocb *o, uint8_t *output) +{ + o->i = 1; + o->out = output; +} + +static void ocb_add_Ln(ocb *o, uint32_t n, cf_gf128 out) +{ + /* Do we have a precomputed L term? */ + if (n < MAX_L) + { + cf_gf128_add(o->L[n], out, out); + return; + } + + /* Compute more terms of L. */ + cf_gf128 accum; + memcpy(accum, o->L[MAX_L - 1], sizeof accum); + + for (uint32_t i = MAX_L - 1; i < n; i++) + { + cf_gf128 next; + cf_gf128_double(accum, next); + memcpy(accum, next, sizeof accum); + } + + cf_gf128_add(accum, out, out); +} + +static void ocb_hash_init(ocb_hash *h) +{ + memset(h->offset, 0, sizeof h->offset); + memset(h->sum, 0, sizeof h->sum); + h->i = 1; +} + +static void ocb_hash_sum(ocb *o, const uint8_t *block, + cf_gf128 sum, const cf_gf128 offset) +{ + uint8_t offset_bytes[BLOCK]; + cf_gf128_tobytes_be(offset, offset_bytes); + + uint8_t block_tmp[BLOCK]; + xor_bb(block_tmp, block, offset_bytes, sizeof block_tmp); + o->prp->encrypt(o->prpctx, block_tmp, block_tmp); + + cf_gf128 tmp; + cf_gf128_frombytes_be(block_tmp, tmp); + cf_gf128_add(sum, tmp, sum); +} + +static void ocb_hash_block(void *vctx, const uint8_t *block) +{ + ocb_hash *h = vctx; + + /* Offset_i = Offset_{i - 1} xor L{ntz(i)} */ + ocb_add_Ln(h->o, count_trailing_zeroes(h->i), h->offset); + + /* Sum_i = Sum_{i - 1} xor ENCIPHER(K, A_i xor Offset_i) */ + ocb_hash_sum(h->o, block, h->sum, h->offset); + + h->i++; +} + +static void ocb_process_header(ocb *o, const uint8_t *header, size_t nheader, + uint8_t out[BLOCK]) +{ + ocb_hash ctx = { o }; + ocb_hash_init(&ctx); + + uint8_t partial[BLOCK]; + size_t npartial = 0; + + cf_blockwise_accumulate(partial, &npartial, + o->prp->blocksz, + header, nheader, + ocb_hash_block, + &ctx); + + if (npartial) + { + /* Offset_* = Offset_m xor L_* */ + cf_gf128_add(ctx.offset, o->L_star, ctx.offset); + + /* CipherInput = (A_* || 1 || zeros(127 - bitlen(A_*))) xor Offset_* */ + memset(partial + npartial, 0, sizeof(partial) - npartial); + partial[npartial] = 0x80; + + /* Sum = Sum_m xor ENCIPHER(K, CipherInput) */ + ocb_hash_sum(ctx.o, partial, ctx.sum, ctx.offset); + } + + cf_gf128_tobytes_be(ctx.sum, out); + mem_clean(&ctx, sizeof ctx); +} + +static void ocb_encrypt_block(void *vctx, const uint8_t *block) +{ + ocb *o = vctx; + + /* Offset_i = Offset_{i - 1} xor L{ntz(i)} */ + ocb_add_Ln(o, count_trailing_zeroes(o->i), o->offset); + + /* C_i = Offset_i xor ENCIPHER(K, P_i xor Offset_i) */ + uint8_t offset_bytes[BLOCK]; + cf_gf128_tobytes_be(o->offset, offset_bytes); + + uint8_t block_tmp[BLOCK]; + xor_bb(block_tmp, block, offset_bytes, sizeof block_tmp); + o->prp->encrypt(o->prpctx, block_tmp, block_tmp); + xor_bb(o->out, block_tmp, offset_bytes, sizeof block_tmp); + o->out += sizeof block_tmp; + + /* Checksum_i = Checksum_{i - 1} xor P_i */ + cf_gf128 P; + cf_gf128_frombytes_be(block, P); + cf_gf128_add(o->checksum, P, o->checksum); + + o->i++; +} + +void cf_ocb_encrypt(const cf_prp *prp, void *prpctx, + const uint8_t *plain, size_t nplain, + const uint8_t *header, size_t nheader, + const uint8_t *nonce, size_t nnonce, + uint8_t *cipher, /* the same size as nplain */ + uint8_t *tag, size_t ntag) +{ + ocb o; + ocb_init(&o, prp, prpctx, nonce, nnonce, ntag); + + /* Process blocks. The blockwise machinery takes care of + * splitting the input into 128-bit blocks, and calling + * a function on each one. */ + uint8_t partial[BLOCK]; + size_t npartial = 0; + + ocb_start_cipher(&o, cipher); + cf_blockwise_accumulate(partial, &npartial, + prp->blocksz, + plain, nplain, + ocb_encrypt_block, + &o); + + /* Move along plain and cipher. */ + plain += (o.out - cipher); + cipher = o.out; + + /* If we have remaining data to pad and process, + * it's in partial. */ + if (npartial) + { + /* Offset_* = Offset_m xor L_* */ + cf_gf128_add(o.offset, o.L_star, o.offset); + + /* Pad = ENCIPHER(K, Offset_*) */ + uint8_t pad[BLOCK]; + cf_gf128_tobytes_be(o.offset, pad); + o.prp->encrypt(o.prpctx, pad, pad); + + /* C_* = P_* xor Pad[1..bitlen(P_*)] */ + xor_bb(cipher, partial, pad, npartial); + mem_clean(pad, sizeof pad); + + /* Checksum_* = Checksum_m xor (P_* || 1 || zeros(127 - bitlen(P_*))) */ + memset(partial + npartial, 0, sizeof(partial) - npartial); + partial[npartial] = 0x80; + + cf_gf128 last_block; + cf_gf128_frombytes_be(partial, last_block); + cf_gf128_add(o.checksum, last_block, o.checksum); + mem_clean(last_block, sizeof last_block); + } + + /* Compute: Tag = ENCIPHER(K, Checksum_m xor Offset_m xor L_$) xor HASH(K, A) */ + cf_gf128 full_tag; + for (size_t i = 0; i < 4; i++) + full_tag[i] = o.checksum[i] ^ o.offset[i] ^ o.L_dollar[i]; + + /* Convert tag to bytes for encryption */ + uint8_t tag_bytes[BLOCK]; + cf_gf128_tobytes_be(full_tag, tag_bytes); + + /* ENCIPHER(...) */ + o.prp->encrypt(o.prpctx, tag_bytes, tag_bytes); + + /* Compute HASH(K, A). */ + uint8_t hash_a[BLOCK]; + ocb_process_header(&o, header, nheader, hash_a); + + /* ... xor HASH(K, A) */ + xor_bb(tag_bytes, tag_bytes, hash_a, sizeof tag_bytes); + + /* Copy out tag to caller. */ + memcpy(tag, tag_bytes, ntag); + + mem_clean(&o, sizeof o); +} + +static void ocb_decrypt_block(void *vctx, const uint8_t *block) +{ + ocb *o = vctx; + + /* Offset_i = Offset_{i - 1} xor L{ntz(i)} */ + ocb_add_Ln(o, count_trailing_zeroes(o->i), o->offset); + + /* P_i = Offset_i xor DECIPHER(K, C_i xor Offset_i) */ + uint8_t offset_bytes[BLOCK]; + cf_gf128_tobytes_be(o->offset, offset_bytes); + + uint8_t block_tmp[BLOCK]; + xor_bb(block_tmp, block, offset_bytes, sizeof block_tmp); + o->prp->decrypt(o->prpctx, block_tmp, block_tmp); + xor_bb(o->out, block_tmp, offset_bytes, sizeof block_tmp); + + /* Checksum_i = Checksum_{i - 1} xor P_i */ + cf_gf128 P; + cf_gf128_frombytes_be(o->out, P); + o->out += sizeof block_tmp; + cf_gf128_add(o->checksum, P, o->checksum); + + o->i++; +} + +int cf_ocb_decrypt(const cf_prp *prp, void *prpctx, + const uint8_t *cipher, size_t ncipher, + const uint8_t *header, size_t nheader, + const uint8_t *nonce, size_t nnonce, + const uint8_t *tag, size_t ntag, + uint8_t *plain) +{ + ocb o; + ocb_init(&o, prp, prpctx, nonce, nnonce, ntag); + + /* Do blockwise decryption */ + uint8_t partial[BLOCK]; + size_t npartial = 0; + + ocb_start_cipher(&o, plain); + cf_blockwise_accumulate(partial, &npartial, + prp->blocksz, + cipher, ncipher, + ocb_decrypt_block, + &o); + + if (npartial) + { + /* Offset_* = Offset_m xor L_* */ + cf_gf128_add(o.offset, o.L_star, o.offset); + + /* Pad = ENCIPHER(K, Offset_*) */ + uint8_t pad[BLOCK]; + cf_gf128_tobytes_be(o.offset, pad); + o.prp->encrypt(o.prpctx, pad, pad); + + /* P_* = C_* xor Pad[1..bitlen(C_*)] */ + xor_bb(partial, partial, pad, npartial); + mem_clean(pad, sizeof pad); + + memcpy(o.out, partial, npartial); + + /* Checksum_* = Checksum_m xor (P_* || 1 || zeros(127 - bitlen(P_*))) */ + memset(partial + npartial, 0, sizeof(partial) - npartial); + partial[npartial] = 0x80; + + cf_gf128 last_block; + cf_gf128_frombytes_be(partial, last_block); + cf_gf128_add(o.checksum, last_block, o.checksum); + mem_clean(last_block, sizeof last_block); + } + + /* Compute: Tag = ENCIPHER(K, Checksum_m xor Offset_m xor L_$) xor HASH(K, A) */ + cf_gf128 full_tag; + for (size_t i = 0; i < 4; i++) + full_tag[i] = o.checksum[i] ^ o.offset[i] ^ o.L_dollar[i]; + + /* Convert tag to bytes for encryption */ + uint8_t tag_bytes[BLOCK]; + cf_gf128_tobytes_be(full_tag, tag_bytes); + + /* ENCIPHER(...) */ + o.prp->encrypt(o.prpctx, tag_bytes, tag_bytes); + + /* Compute HASH(K, A). */ + uint8_t hash_a[BLOCK]; + ocb_process_header(&o, header, nheader, hash_a); + + /* ... xor HASH(K, A) */ + xor_bb(tag_bytes, tag_bytes, hash_a, sizeof tag_bytes); + + /* Check against caller's tag. */ + int err; + + if (mem_eq(tag, tag_bytes, ntag)) + { + err = 0; + } else { + err = 1; + mem_clean(plain, ncipher); + } + + mem_clean(&o, sizeof o); + mem_clean(tag_bytes, sizeof tag_bytes); + mem_clean(full_tag, sizeof full_tag); + return err; +} diff --git a/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/pbkdf2.c b/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/pbkdf2.c new file mode 100644 index 00000000..fce6a22f --- /dev/null +++ b/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/pbkdf2.c @@ -0,0 +1,84 @@ +/* + * cifra - embedded cryptography library + * Written in 2014 by Joseph Birr-Pixton + * + * To the extent possible under law, the author(s) have dedicated all + * copyright and related and neighboring rights to this software to the + * public domain worldwide. This software is distributed without any + * warranty. + * + * You should have received a copy of the CC0 Public Domain Dedication + * along with this software. If not, see + * . + */ + +#include "pbkdf2.h" +#include "hmac.h" +#include "bitops.h" +#include "handy.h" +#include "tassert.h" + +#include + +static void F(const cf_hmac_ctx *startctx, + uint32_t counter, + const uint8_t *salt, size_t nsalt, + uint32_t iterations, + uint8_t *out) +{ + uint8_t U[CF_MAXHASH]; + size_t hashsz = startctx->hash->hashsz; + + uint8_t countbuf[4]; + write32_be(counter, countbuf); + + /* First iteration: + * U_1 = PRF(P, S || INT_32_BE(i)) + */ + cf_hmac_ctx ctx = *startctx; + cf_hmac_update(&ctx, salt, nsalt); + cf_hmac_update(&ctx, countbuf, sizeof countbuf); + cf_hmac_finish(&ctx, U); + memcpy(out, U, hashsz); + + /* Subsequent iterations: + * U_c = PRF(P, U_{c-1}) + */ + for (uint32_t i = 1; i < iterations; i++) + { + ctx = *startctx; + cf_hmac_update(&ctx, U, hashsz); + cf_hmac_finish(&ctx, U); + xor_bb(out, out, U, hashsz); + } +} + +void cf_pbkdf2_hmac(const uint8_t *pw, size_t npw, + const uint8_t *salt, size_t nsalt, + uint32_t iterations, + uint8_t *out, size_t nout, + const cf_chash *hash) +{ + uint32_t counter = 1; + uint8_t block[CF_MAXHASH]; + + assert(iterations); + assert(out && nout); + assert(hash); + + /* Starting point for inner loop. */ + cf_hmac_ctx ctx; + cf_hmac_init(&ctx, hash, pw, npw); + + while (nout) + { + F(&ctx, counter, salt, nsalt, iterations, block); + + size_t taken = MIN(nout, hash->hashsz); + memcpy(out, block, taken); + out += taken; + nout -= taken; + counter++; + } +} + diff --git a/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/pbkdf2.h b/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/pbkdf2.h new file mode 100644 index 00000000..2f304840 --- /dev/null +++ b/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/pbkdf2.h @@ -0,0 +1,47 @@ +/* + * cifra - embedded cryptography library + * Written in 2014 by Joseph Birr-Pixton + * + * To the extent possible under law, the author(s) have dedicated all + * copyright and related and neighboring rights to this software to the + * public domain worldwide. This software is distributed without any + * warranty. + * + * You should have received a copy of the CC0 Public Domain Dedication + * along with this software. If not, see + * . + */ + +#ifndef PBKDF2_H +#define PBKDF2_H + +#include +#include + +#include "chash.h" + +/** + * PBKDF2-HMAC + * =========== + * This is PBKDF2 as described by PKCS#5/RFC2898 with HMAC as the PRF. + */ + +/* .. c:function:: $DECL + * This computes PBKDF2-HMAC with the given hash functon. + * + * :param pw: password input buffer. + * :param npw: password length. + * :param salt: salt input buffer. + * :param nsalt: salt length. + * :param iterations: non-zero iteration count. Tune this for performance/security tradeoff. + * :param out: key material output buffer. `nout` bytes are written here. + * :param nout: key material length. + * :param hash: hash function description. + */ +void cf_pbkdf2_hmac(const uint8_t *pw, size_t npw, + const uint8_t *salt, size_t nsalt, + uint32_t iterations, + uint8_t *out, size_t nout, + const cf_chash *hash); + +#endif diff --git a/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/poly1305.c b/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/poly1305.c new file mode 100644 index 00000000..6c3f13de --- /dev/null +++ b/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/poly1305.c @@ -0,0 +1,221 @@ +/* + * cifra - embedded cryptography library + * Written in 2014 by Joseph Birr-Pixton + * + * To the extent possible under law, the author(s) have dedicated all + * copyright and related and neighboring rights to this software to the + * public domain worldwide. This software is distributed without any + * warranty. + * + * You should have received a copy of the CC0 Public Domain Dedication + * along with this software. If not, see + * . + */ + +#include "poly1305.h" +#include "bitops.h" +#include "handy.h" +#include "blockwise.h" + +#include +#include + +void cf_poly1305_init(cf_poly1305 *ctx, + const uint8_t r[16], + const uint8_t s[16]) +{ + memset(ctx, 0, sizeof *ctx); + + ctx->r[0] = r[0]; + ctx->r[1] = r[1]; + ctx->r[2] = r[2]; + ctx->r[3] = r[3] & 0x0f; + ctx->r[4] = r[4] & 0xfc; + ctx->r[5] = r[5]; + ctx->r[6] = r[6]; + ctx->r[7] = r[7] & 0x0f; + ctx->r[8] = r[8] & 0xfc; + ctx->r[9] = r[9]; + ctx->r[10] = r[10]; + ctx->r[11] = r[11] & 0x0f; + ctx->r[12] = r[12] & 0xfc; + ctx->r[13] = r[13]; + ctx->r[14] = r[14]; + ctx->r[15] = r[15] & 0x0f; + ctx->r[16] = 0; + + memcpy(ctx->s, s, 16); +} + +static void poly1305_add(uint32_t h[17], + const uint32_t x[17]) +{ + uint32_t carry = 0; + int i; + + for (i = 0; i < 17; i++) + { + carry += h[i] + x[i]; + h[i] = carry & 0xff; + carry >>= 8; + } +} + +/* Minimal reduction/carry chain. */ +static void poly1305_min_reduce(uint32_t x[17]) +{ + uint32_t carry = 0; + int i; + for (i = 0; i < 16; i++) + { + carry += x[i]; + x[i] = carry & 0xff; + carry >>= 8; + } + + /* 2 ** 130 - 5 = 0x3fffffffffffffffffffffffffffffffb + * ^ + * So 2 bits of carry are put into top word. + * Remaining bits get multiplied by 5 and carried back + * into bottom */ + carry += x[16]; + x[16] = carry & 0x03; + carry = 5 * (carry >> 2); + + for (i = 0; i < 16; i++) + { + carry += x[i]; + x[i] = carry & 0xff; + carry >>= 8; + } + + x[16] += carry; +} + +/* This is - 2 ** 130 - 5 in twos complement. */ +static const uint32_t negative_1305[17] = { + 0x05, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0xfc +}; + +static void poly1305_full_reduce(uint32_t x[17]) +{ + uint32_t xsub[17]; + size_t i; + + for (i = 0; i < 17; i++) + xsub[i] = x[i]; + + poly1305_add(xsub, negative_1305); + + /* If x - (2 ** 130 - 5) is negative, then + * x didn't need reduction: we discard the results. + * Do this in a side-channel silent way. */ + uint32_t negative_mask = mask_u32(xsub[16] & 0x80, 0x80); + uint32_t positive_mask = negative_mask ^ 0xffffffff; + + for (i = 0; i < 17; i++) + x[i] = (x[i] & negative_mask) | (xsub[i] & positive_mask); +} + +static void poly1305_mul(uint32_t x[17], + const uint32_t y[17]) +{ + uint32_t r[17]; + int i; + + for (i = 0; i < 17; i++) + { + uint32_t accum = 0; + int j; + + for (j = 0; j <= i; j++) + accum += x[j] * y[i - j]; + + /* Add in carries. These get shifted 130 bits + * to the right, with a combination of byte indexing + * and shifting (136 bits right, then 6 bits left). + * + * nb. 5 << 6 is made up of two parts: + * 5: reduction of 2 ** 130 leaves a multiple 5 + * shift 6 places left + * 17 * 8: byte indexing shift (136 bits) + * 130: desired shift + */ + for (j = i + 1; j < 17; j++) + accum += (5 << 6) * x[j] * y[i + 17 - j]; + + r[i] = accum; + } + + poly1305_min_reduce(r); + + for (i = 0; i < 17; i++) + x[i] = r[i]; +} + +static void poly1305_block(cf_poly1305 *ctx, + const uint32_t c[17]) +{ + poly1305_add(ctx->h, c); + poly1305_mul(ctx->h, ctx->r); +} + +static void poly1305_whole_block(void *vctx, + const uint8_t *buf) +{ + cf_poly1305 *ctx = vctx; + uint32_t c[17]; + int i; + + for (i = 0; i < 16; i++) + c[i] = buf[i]; + + c[16] = 1; + poly1305_block(ctx, c); +} + +static void poly1305_last_block(cf_poly1305 *ctx) +{ + uint32_t c[17] = { 0 }; + size_t i; + + for (i = 0; i < ctx->npartial; i++) + c[i] = ctx->partial[i]; + + c[ctx->npartial] = 1; + poly1305_block(ctx, c); +} + +void cf_poly1305_update(cf_poly1305 *ctx, + const uint8_t *buf, + size_t nbytes) +{ + cf_blockwise_accumulate(ctx->partial, &ctx->npartial, + sizeof ctx->partial, + buf, nbytes, + poly1305_whole_block, + ctx); +} + +void cf_poly1305_finish(cf_poly1305 *ctx, + uint8_t out[16]) +{ + if (ctx->npartial) + poly1305_last_block(ctx); + + uint32_t s[17]; + size_t i; + for (i = 0; i < 16; i++) + s[i] = ctx->s[i]; + s[16] = 0; + + poly1305_full_reduce(ctx->h); + poly1305_add(ctx->h, s); + + for (i = 0; i < 16; i++) + out[i] = ctx->h[i]; + + mem_clean(ctx, sizeof *ctx); +} + diff --git a/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/poly1305.h b/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/poly1305.h new file mode 100644 index 00000000..b318e284 --- /dev/null +++ b/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/poly1305.h @@ -0,0 +1,91 @@ +/* + * cifra - embedded cryptography library + * Written in 2014 by Joseph Birr-Pixton + * + * To the extent possible under law, the author(s) have dedicated all + * copyright and related and neighboring rights to this software to the + * public domain worldwide. This software is distributed without any + * warranty. + * + * You should have received a copy of the CC0 Public Domain Dedication + * along with this software. If not, see + * . + */ + +#ifndef POLY1305_H +#define POLY1305_H + +#include +#include + +/** + * Poly1305 + * ======== + * This is an incremental interface to computing the poly1305 + * single shot MAC. + * + * Note: construct Poly1305-AES with this by taking a 16 byte + * nonce and encrypting it, and then using the result as an + * input to this function. + */ + +/* .. c:type:: cf_poly1305 + * Poly1305 incremental interface context. + * + * .. c:member:: cf_poly1305.h + * Current accumulator. + * + * .. c:member:: cf_poly1305.r + * Block multiplier. + * + * .. c:member:: cf_poly1305.s + * Final XOR offset. + * + * .. c:member:: cf_poly1305.partial + * Unprocessed input. + * + * .. c:member:: cf_poly1305.npartial + * Number of bytes of unprocessed input. + * + */ +typedef struct +{ + uint32_t h[17]; + uint32_t r[17]; + uint8_t s[16]; + uint8_t partial[16]; + size_t npartial; +} cf_poly1305; + +/* .. c:function:: $DECL + * Sets up `ctx` ready to compute a new MAC. + * + * In Poly1305-AES, `r` is the second half of the 32-byte key. + * `s` is a nonce encrypted under the first half of the key. + * + * :param ctx: context (written) + * :param r: MAC key. + * :param s: preprocessed nonce. + * + */ +void cf_poly1305_init(cf_poly1305 *ctx, + const uint8_t r[16], + const uint8_t s[16]); + +/* .. c:function:: $DECL + * Processes `nbytes` at `data`. Copies the data if there isn't enough to make + * a full block. + */ +void cf_poly1305_update(cf_poly1305 *ctx, + const uint8_t *data, + size_t nbytes); + +/* .. c:function:: $DECL + * Finishes the operation, writing 16 bytes to `out`. + * + * This destroys `ctx`. + */ +void cf_poly1305_finish(cf_poly1305 *ctx, + uint8_t out[16]); + +#endif diff --git a/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/poly1305.py b/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/poly1305.py new file mode 100644 index 00000000..41a1b9d8 --- /dev/null +++ b/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/poly1305.py @@ -0,0 +1,127 @@ +rs = (0xee,0xa6,0xa7,0x25,0x1c,0x1e,0x72,0x91 +,0x6d,0x11,0xc2,0xcb,0x21,0x4d,0x3c,0x25 +,0x25,0x39,0x12,0x1d,0x8e,0x23,0x4e,0x65 +,0x2d,0x65,0x1f,0xa4,0xc8,0xcf,0xf8,0x80) + +msg = (0x8e,0x99,0x3b,0x9f,0x48,0x68,0x12,0x73 + ,0xc2,0x96,0x50,0xba,0x32,0xfc,0x76,0xce + ,0x48,0x33,0x2e,0xa7,0x16,0x4d,0x96,0xa4 + ,0x47,0x6f,0xb8,0xc5,0x31,0xa1,0x18,0x6a + ,0xc0,0xdf,0xc1,0x7c,0x98,0xdc,0xe8,0x7b + ,0x4d,0xa7,0xf0,0x11,0xec,0x48,0xc9,0x72 + ,0x71,0xd2,0xc2,0x0f,0x9b,0x92,0x8f,0xe2 + ,0x27,0x0d,0x6f,0xb8,0x63,0xd5,0x17,0x38 + ,0xb4,0x8e,0xee,0xe3,0x14,0xa7,0xcc,0x8a + ,0xb9,0x32,0x16,0x45,0x48,0xe5,0x26,0xae + ,0x90,0x22,0x43,0x68,0x51,0x7a,0xcf,0xea + ,0xbd,0x6b,0xb3,0x73,0x2b,0xc0,0xe9,0xda + ,0x99,0x83,0x2b,0x61,0xca,0x01,0xb6,0xde + ,0x56,0x24,0x4a,0x9e,0x88,0xd5,0xf9,0xb3 + ,0x79,0x73,0xf6,0x22,0xa4,0x3d,0x14,0xa6 + ,0x59,0x9b,0x1f,0x65,0x4c,0xb4,0x5a,0x74 + ,0xe3,0x55,0xa5) + +tag = (0xf3,0xff,0xc7,0x70,0x3f,0x94,0x00,0xe5 +,0x2a,0x7d,0xfb,0x4b,0x3d,0x33,0x05,0xd9) + +print len(msg) + +WORD = 0xffffffff + +def add(x, y): + u = 0 + r = [0] * 17 + for i in range(17): + u += (x[i] + y[i]) & WORD + r[i] = u & 0xff + u >>= 8 + return r + +def reduce(x): + r = list(x) + u = 0 + + for i in range(16): + u += r[i] + r[i] = u & 0xff + u >>= 8 + u += r[16] + r[16] = u & 3 + u = 5 * (u >> 2) + + for i in range(16): + u += r[i] + r[i] = u & 0xff + u >>= 8 + u += r[16] + r[16] = u + + return r + +def modmul(x, y): + r = [0] * 17 + for i in range(17): + u = 0 + for j in range(i + 1): + u += (x[j] * y[i - j]) & WORD + for j in range(i + 1, 17): + u += (320 * x[j] * y[i + 17 - j]) & WORD + r[i] = u + return reduce(r) + +def dump(why, v): + print '%s = %s' % (why, ' '.join('%08x' % x for x in v)) + +def freeze(x): + # -2^130 - 5 in twos complement + negative_130_5 = (5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 252) + + r = add(x, negative_130_5) + dump('minusp', r) + negative = bool(x[16] >> 7) + if negative: + return r + else: + return x + +def poly1305(msg, rs): + r, s = list(rs[:16]), list(rs[16:]) + + r[3] &= 15 + r[4] &= 252 + r[7] &= 15 + r[8] &= 252 + r[11] &= 15 + r[12] &= 252 + r[15] &= 15 + r.append(0) + + h = [0] * 17 + dump('r-init', r) + dump('h-init', h) + + block = 0 + + for offs in range(0, len(msg), 16): + print '--- block %d ---' % block + block += 1 + c = list(msg[offs:offs+16]) + c.append(1) + while len(c) != 17: c.append(0) + dump('c', c) + + h = add(h, c) + dump('after-add', h) + h = modmul(h, r) + dump('after-mul', h) + + dump('end-block', h) + h = freeze(h) + dump('h', h) + s.append(0) + h = add(h, s) + dump('final', h) + return h[:16] + +r = poly1305(msg, rs) +print repr([hex(x) for x in r]) diff --git a/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/prp.h b/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/prp.h new file mode 100644 index 00000000..1aa72588 --- /dev/null +++ b/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/prp.h @@ -0,0 +1,64 @@ +/* + * cifra - embedded cryptography library + * Written in 2014 by Joseph Birr-Pixton + * + * To the extent possible under law, the author(s) have dedicated all + * copyright and related and neighboring rights to this software to the + * public domain worldwide. This software is distributed without any + * warranty. + * + * You should have received a copy of the CC0 Public Domain Dedication + * along with this software. If not, see + * . + */ + +#ifndef PRP_H +#define PRP_H + +#include +#include + +/** + * General block cipher description + * ================================ + * This allows us to implement block cipher modes which can work + * with different block ciphers. + */ + +/* .. c:type:: cf_prp_block + * Block processing function type. + * + * The `in` and `out` blocks may alias. + * + * :rtype: void + * :param ctx: block cipher-specific context object. + * :param in: input block. + * :param out: output block. + */ +typedef void (*cf_prp_block)(void *ctx, const uint8_t *in, uint8_t *out); + +/* .. c:type:: cf_prp + * Describes an PRP in a general way. + * + * .. c:member:: cf_prp.blocksz + * Block size in bytes. Must be no more than :c:macro:`CF_MAXBLOCK`. + * + * .. c:member:: cf_prp.encrypt + * Block encryption function. + * + * .. c:member:: cf_prp.decrypt + * Block decryption function. + */ +typedef struct +{ + size_t blocksz; + cf_prp_block encrypt; + cf_prp_block decrypt; +} cf_prp; + +/* .. c:macro:: CF_MAXBLOCK + * The maximum block cipher blocksize we support, in bytes. + */ +#define CF_MAXBLOCK 16 + +#endif diff --git a/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/salsa20.c b/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/salsa20.c new file mode 100644 index 00000000..34bd1562 --- /dev/null +++ b/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/salsa20.c @@ -0,0 +1,164 @@ +/* + * cifra - embedded cryptography library + * Written in 2014 by Joseph Birr-Pixton + * + * To the extent possible under law, the author(s) have dedicated all + * copyright and related and neighboring rights to this software to the + * public domain worldwide. This software is distributed without any + * warranty. + * + * You should have received a copy of the CC0 Public Domain Dedication + * along with this software. If not, see + * . + */ + +#include "salsa20.h" +#include "bitops.h" +#include "blockwise.h" + +#include +#include + +void cf_salsa20_core(const uint8_t key0[16], + const uint8_t key1[16], + const uint8_t nonce[16], + const uint8_t constant[16], + uint8_t out[64]) +{ + /* unpack sequence is: + * + * c0 + * key0 + * c1 + * nonce + * c2 + * key1 + * c3 + * + * where c0, c1, c2, c3 = constant + */ + + uint32_t z0, z1, z2, z3, z4, z5, z6, z7, + z8, z9, za, zb, zc, zd, ze, zf; + + uint32_t x0 = z0 = read32_le(constant + 0), + x1 = z1 = read32_le(key0 + 0), + x2 = z2 = read32_le(key0 + 4), + x3 = z3 = read32_le(key0 + 8), + x4 = z4 = read32_le(key0 + 12), + x5 = z5 = read32_le(constant + 4), + x6 = z6 = read32_le(nonce + 0), + x7 = z7 = read32_le(nonce + 4), + x8 = z8 = read32_le(nonce + 8), + x9 = z9 = read32_le(nonce + 12), + xa = za = read32_le(constant + 8), + xb = zb = read32_le(key1 + 0), + xc = zc = read32_le(key1 + 4), + xd = zd = read32_le(key1 + 8), + xe = ze = read32_le(key1 + 12), + xf = zf = read32_le(constant + 12); + +#define QUARTER(v0, v1, v2, v3) \ + v1 ^= rotl32(v0 + v3, 7); \ + v2 ^= rotl32(v1 + v0, 9); \ + v3 ^= rotl32(v2 + v1, 13);\ + v0 ^= rotl32(v3 + v2, 18) + +#define ROW \ + QUARTER(z0, z1, z2, z3); \ + QUARTER(z5, z6, z7, z4); \ + QUARTER(za, zb, z8, z9); \ + QUARTER(zf, zc, zd, ze) + +#define COLUMN\ + QUARTER(z0, z4, z8, zc); \ + QUARTER(z5, z9, zd, z1); \ + QUARTER(za, ze, z2, z6); \ + QUARTER(zf, z3, z7, zb) + + for (int i = 0; i < 10; i++) + { + COLUMN; + ROW; + } + + x0 += z0; + x1 += z1; + x2 += z2; + x3 += z3; + x4 += z4; + x5 += z5; + x6 += z6; + x7 += z7; + x8 += z8; + x9 += z9; + xa += za; + xb += zb; + xc += zc; + xd += zd; + xe += ze; + xf += zf; + + write32_le(x0, out + 0); + write32_le(x1, out + 4); + write32_le(x2, out + 8); + write32_le(x3, out + 12); + write32_le(x4, out + 16); + write32_le(x5, out + 20); + write32_le(x6, out + 24); + write32_le(x7, out + 28); + write32_le(x8, out + 32); + write32_le(x9, out + 36); + write32_le(xa, out + 40); + write32_le(xb, out + 44); + write32_le(xc, out + 48); + write32_le(xd, out + 52); + write32_le(xe, out + 56); + write32_le(xf, out + 60); +} + +static const uint8_t *salsa20_tau = (const uint8_t *) "expand 16-byte k"; +static const uint8_t *salsa20_sigma = (const uint8_t *) "expand 32-byte k"; + +void cf_salsa20_init(cf_salsa20_ctx *ctx, const uint8_t *key, size_t nkey, const uint8_t nonce[8]) +{ + switch (nkey) + { + case 16: + memcpy(ctx->key0, key, 16); + memcpy(ctx->key1, key, 16); + ctx->constant = salsa20_tau; + break; + case 32: + memcpy(ctx->key0, key, 16); + memcpy(ctx->key1, key + 16, 16); + ctx->constant = salsa20_sigma; + break; + default: + abort(); + } + + memset(ctx->nonce, 0, sizeof ctx->nonce); + memcpy(ctx->nonce + 8, nonce, 8); + ctx->nblock = 0; + ctx->ncounter = 8; +} + +static void cf_salsa20_next_block(void *vctx, uint8_t *out) +{ + cf_salsa20_ctx *ctx = vctx; + cf_salsa20_core(ctx->key0, + ctx->key1, + ctx->nonce, + ctx->constant, + out); + incr_le(ctx->nonce, ctx->ncounter); +} + +void cf_salsa20_cipher(cf_salsa20_ctx *ctx, const uint8_t *input, uint8_t *output, size_t bytes) +{ + cf_blockwise_xor(ctx->block, &ctx->nblock, 64, + input, output, bytes, + cf_salsa20_next_block, + ctx); +} diff --git a/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/salsa20.h b/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/salsa20.h new file mode 100644 index 00000000..462d0190 --- /dev/null +++ b/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/salsa20.h @@ -0,0 +1,140 @@ +/* + * cifra - embedded cryptography library + * Written in 2014 by Joseph Birr-Pixton + * + * To the extent possible under law, the author(s) have dedicated all + * copyright and related and neighboring rights to this software to the + * public domain worldwide. This software is distributed without any + * warranty. + * + * You should have received a copy of the CC0 Public Domain Dedication + * along with this software. If not, see + * . + */ + +#ifndef SALSA20_H +#define SALSA20_H + +#include +#include + +/** + * The Salsa20/Chacha20 stream ciphers + * =================================== + * + * These are similar stream ciphers by djb. + * + * A reduced round variant of Salsa20 (Salsa20/12) + * was selected as a finalist of the eSTREAM stream + * cipher competition. This implementation does + * the full 20 rounds. + * + * ChaCha20 is fundamentally like Salsa20, but + * has a tweaked round function to improve security + * margin without damaging performance. + */ + +/* Salsa20 core transform. */ +void cf_salsa20_core(const uint8_t key0[16], + const uint8_t key1[16], + const uint8_t nonce[16], + const uint8_t constant[16], + uint8_t out[64]); + +/* Chacha20 core transform. */ +void cf_chacha20_core(const uint8_t key0[16], + const uint8_t key1[16], + const uint8_t nonce[16], + const uint8_t constant[16], + uint8_t out[64]); + +/* .. c:type:: cf_salsa20_ctx + * Incremental interface to Salsa20. + * + * .. c:member:: cf_salsa20_ctx.key0 + * Half of key material. + * + * .. c:member:: cf_salsa20_ctx.key1 + * Half of key material. + * + * .. c:member:: cf_salsa20_ctx.nonce + * Nonce and counter block. + * + * .. c:member:: cf_salsa20_ctx.constant + * Per-key-length constants. + * + * .. c:member:: cf_salsa20_ctx.block + * Buffer for unused key stream material. + * + * .. c:member:: cf_salsa20_ctx.nblock + * Number of bytes at end of `block` that can be used as key stream. + * + */ +typedef struct +{ + uint8_t key0[16], key1[16]; + uint8_t nonce[16]; + const uint8_t *constant; + uint8_t block[64]; + size_t nblock; + size_t ncounter; +} cf_salsa20_ctx, cf_chacha20_ctx; + +/* .. c:type:: cf_chacha20_ctx + * Incremental interface to Chacha20. This structure + * is identical to :c:type:`cf_salsa20_ctx`. + */ + +/* .. c:function:: $DECL + * Salsa20 initialisation function. + * + * :param ctx: salsa20 context. + * :param key: key material. + * :param nkey: length of key in bytes, either 16 or 32. + * :param nonce: per-message nonce. + */ +void cf_salsa20_init(cf_salsa20_ctx *ctx, const uint8_t *key, size_t nkey, const uint8_t nonce[8]); + +/* .. c:function:: $DECL + * Chacha20 initialisation function. + * + * :param ctx: chacha20 context (written). + * :param key: key material. + * :param nkey: length of key in bytes, either 16 or 32. + * :param nonce: per-message nonce. + */ +void cf_chacha20_init(cf_chacha20_ctx *ctx, const uint8_t *key, size_t nkey, const uint8_t nonce[8]); + +/* .. c:function:: $DECL + * Chacha20 initialisation function. This version gives full control over the whole + * initial nonce value, and the size of the counter. The counter is always at the front + * of the nonce. + * + * :param ctx: chacha20 context (written). + * :param key: key material. + * :param nkey: length of key in bytes, either 16 or 32. + * :param nonce: per-message nonce. `ncounter` bytes at the start are the block counter. + * :param ncounter: length, in bytes, of the counter portion of the nonce. + */ +void cf_chacha20_init_custom(cf_chacha20_ctx *ctx, const uint8_t *key, size_t nkey, + const uint8_t nonce[16], size_t ncounter); + +/* .. c:function:: $DECL + * Salsa20 encryption/decryption function. + * + * :param ctx: salsa20 context. + * :param input: input data buffer (read), `count` bytes long. + * :param output: output data buffer (written), `count` bytes long. + */ +void cf_salsa20_cipher(cf_salsa20_ctx *ctx, const uint8_t *input, uint8_t *output, size_t count); + +/* .. c:function:: $DECL + * Chacha20 encryption/decryption function. + * + * :param ctx: chacha20 context. + * :param input: input data buffer (read), `count` bytes long. + * :param output: output data buffer (written), `count` bytes long. + */ +void cf_chacha20_cipher(cf_chacha20_ctx *ctx, const uint8_t *input, uint8_t *output, size_t count); + +#endif diff --git a/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/sha1.c b/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/sha1.c new file mode 100644 index 00000000..8b7d02fe --- /dev/null +++ b/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/sha1.c @@ -0,0 +1,150 @@ +/* + * cifra - embedded cryptography library + * Written in 2014 by Joseph Birr-Pixton + * + * To the extent possible under law, the author(s) have dedicated all + * copyright and related and neighboring rights to this software to the + * public domain worldwide. This software is distributed without any + * warranty. + * + * You should have received a copy of the CC0 Public Domain Dedication + * along with this software. If not, see + * . + */ + +#include + +#include "sha1.h" +#include "blockwise.h" +#include "bitops.h" +#include "handy.h" +#include "tassert.h" + +void cf_sha1_init(cf_sha1_context *ctx) +{ + memset(ctx, 0, sizeof *ctx); + ctx->H[0] = 0x67452301; + ctx->H[1] = 0xefcdab89; + ctx->H[2] = 0x98badcfe; + ctx->H[3] = 0x10325476; + ctx->H[4] = 0xc3d2e1f0; +} + +static void sha1_update_block(void *vctx, const uint8_t *inp) +{ + cf_sha1_context *ctx = vctx; + + /* This is a 16-word window into the whole W array. */ + uint32_t W[16]; + + uint32_t a = ctx->H[0], + b = ctx->H[1], + c = ctx->H[2], + d = ctx->H[3], + e = ctx->H[4], + Wt; + + for (size_t t = 0; t < 80; t++) + { + /* For W[0..16] we process the input into W. + * For W[16..79] we compute the next W value: + * + * W[t] = (W[t - 3] ^ W[t - 8] ^ W[t - 14] ^ W[t - 16]) <<< 1 + * + * But all W indices are reduced mod 16 into our window. + */ + if (t < 16) + { + W[t] = Wt = read32_be(inp); + inp += 4; + } else { + Wt = W[(t - 3) % 16] ^ W[(t - 8) % 16] ^ W[(t - 14) % 16] ^ W[(t - 16) % 16]; + Wt = rotl32(Wt, 1); + W[t % 16] = Wt; + } + + uint32_t f, k; + + if (t <= 19) + { + f = (b & c) | (~b & d); + k = 0x5a827999; + } else if (t <= 39) { + f = b ^ c ^ d; + k = 0x6ed9eba1; + } else if (t <= 59) { + f = (b & c) | (b & d) | (c & d); + k = 0x8f1bbcdc; + } else { + f = b ^ c ^ d; + k = 0xca62c1d6; + } + + uint32_t temp = rotl32(a, 5) + f + e + k + Wt; + e = d; + d = c; + c = rotl32(b, 30); + b = a; + a = temp; + } + + ctx->H[0] += a; + ctx->H[1] += b; + ctx->H[2] += c; + ctx->H[3] += d; + ctx->H[4] += e; + + ctx->blocks++; +} + +void cf_sha1_update(cf_sha1_context *ctx, const void *data, size_t nbytes) +{ + cf_blockwise_accumulate(ctx->partial, &ctx->npartial, sizeof ctx->partial, + data, nbytes, + sha1_update_block, ctx); +} + +void cf_sha1_digest(const cf_sha1_context *ctx, uint8_t hash[CF_SHA1_HASHSZ]) +{ + cf_sha1_context ours = *ctx; + cf_sha1_digest_final(&ours, hash); +} + +void cf_sha1_digest_final(cf_sha1_context *ctx, uint8_t hash[CF_SHA1_HASHSZ]) +{ + uint64_t digested_bytes = ctx->blocks; + digested_bytes = digested_bytes * CF_SHA1_BLOCKSZ + ctx->npartial; + uint64_t digested_bits = digested_bytes * 8; + + size_t padbytes = CF_SHA1_BLOCKSZ - ((digested_bytes + 8) % CF_SHA1_BLOCKSZ); + + /* Hash 0x80 00 ... block first. */ + cf_blockwise_acc_pad(ctx->partial, &ctx->npartial, sizeof ctx->partial, + 0x80, 0x00, 0x00, padbytes, + sha1_update_block, ctx); + + /* Now hash length. */ + uint8_t buf[8]; + write64_be(digested_bits, buf); + cf_sha1_update(ctx, buf, 8); + + /* We ought to have got our padding calculation right! */ + assert(ctx->npartial == 0); + + write32_be(ctx->H[0], hash + 0); + write32_be(ctx->H[1], hash + 4); + write32_be(ctx->H[2], hash + 8); + write32_be(ctx->H[3], hash + 12); + write32_be(ctx->H[4], hash + 16); + + memset(ctx, 0, sizeof *ctx); +} + +const cf_chash cf_sha1 = { + .hashsz = CF_SHA1_HASHSZ, + .blocksz = CF_SHA1_BLOCKSZ, + .init = (cf_chash_init) cf_sha1_init, + .update = (cf_chash_update) cf_sha1_update, + .digest = (cf_chash_digest) cf_sha1_digest +}; + diff --git a/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/sha1.h b/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/sha1.h new file mode 100644 index 00000000..4ca0e91c --- /dev/null +++ b/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/sha1.h @@ -0,0 +1,91 @@ +/* + * cifra - embedded cryptography library + * Written in 2014 by Joseph Birr-Pixton + * + * To the extent possible under law, the author(s) have dedicated all + * copyright and related and neighboring rights to this software to the + * public domain worldwide. This software is distributed without any + * warranty. + * + * You should have received a copy of the CC0 Public Domain Dedication + * along with this software. If not, see + * . + */ + +#ifndef SHA1_H +#define SHA1_H + +#include +#include + +#include "chash.h" + +/** + * SHA1 + * ==== + * + * You shouldn't use this for anything new. + */ + +/* .. c:macro:: CF_SHA1_HASHSZ + * The output size of SHA1: 20 bytes. */ +#define CF_SHA1_HASHSZ 20 + +/* .. c:macro:: CF_SHA1_BLOCKSZ + * The block size of SHA1: 64 bytes. */ +#define CF_SHA1_BLOCKSZ 64 + +/* .. c:type:: cf_sha1_context + * Incremental SHA1 hashing context. + * + * .. c:member:: cf_sha1_context.H + * Intermediate values. + * + * .. c:member:: cf_sha1_context.partial + * Unprocessed input. + * + * .. c:member:: cf_sha1_context.npartial + * Number of bytes of unprocessed input. + * + * .. c:member:: cf_sha1_context.blocks + * Number of full blocks processed. + */ +typedef struct +{ + uint32_t H[5]; /* State. */ + uint8_t partial[CF_SHA1_BLOCKSZ]; /* Partial block of input. */ + uint32_t blocks; /* Number of full blocks processed into H. */ + size_t npartial; /* Number of bytes in prefix of partial. */ +} cf_sha1_context; + +/* .. c:function:: $DECL + * Sets up `ctx` ready to hash a new message. + */ +extern void cf_sha1_init(cf_sha1_context *ctx); + +/* .. c:function:: $DECL + * Hashes `nbytes` at `data`. Copies the data if there isn't enough to make + * a full block. + */ +extern void cf_sha1_update(cf_sha1_context *ctx, const void *data, size_t nbytes); + +/* .. c:function:: $DECL + * Finishes the hash operation, writing `CF_SHA1_HASHSZ` bytes to `hash`. + * + * This leaves `ctx` unchanged. + */ +extern void cf_sha1_digest(const cf_sha1_context *ctx, uint8_t hash[CF_SHA1_HASHSZ]); + +/* .. c:function:: $DECL + * Finishes the hash operation, writing `CF_SHA1_HASHSZ` bytes to `hash`. + * + * This destroys `ctx`, but uses less stack than :c:func:`cf_sha1_digest`. + */ +extern void cf_sha1_digest_final(cf_sha1_context *ctx, uint8_t hash[CF_SHA1_HASHSZ]); + +/* .. c:var:: cf_sha1 + * Abstract interface to SHA1. See :c:type:`cf_chash` for more information. + */ +extern const cf_chash cf_sha1; + +#endif diff --git a/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/sha2.h b/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/sha2.h new file mode 100644 index 00000000..c4ed24b5 --- /dev/null +++ b/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/sha2.h @@ -0,0 +1,235 @@ +/* + * cifra - embedded cryptography library + * Written in 2014 by Joseph Birr-Pixton + * + * To the extent possible under law, the author(s) have dedicated all + * copyright and related and neighboring rights to this software to the + * public domain worldwide. This software is distributed without any + * warranty. + * + * You should have received a copy of the CC0 Public Domain Dedication + * along with this software. If not, see + * . + */ + +#ifndef SHA2_H +#define SHA2_H + +#include +#include + +#include "chash.h" + +/** + * SHA224/SHA256 + * ============= + */ + +/* .. c:macro:: CF_SHA224_HASHSZ + * The output size of SHA224: 28 bytes. */ +#define CF_SHA224_HASHSZ 28 + +/* .. c:macro:: CF_SHA224_BLOCKSZ + * The block size of SHA224: 64 bytes. */ +#define CF_SHA224_BLOCKSZ 64 + +/* .. c:macro:: CF_SHA256_HASHSZ + * The output size of SHA256: 32 bytes. */ +#define CF_SHA256_HASHSZ 32 + +/* .. c:macro:: CF_SHA256_BLOCKSZ + * The block size of SHA256: 64 bytes. */ +#define CF_SHA256_BLOCKSZ 64 + +/* .. c:type:: cf_sha256_context + * Incremental SHA256 hashing context. + * + * .. c:member:: cf_sha256_context.H + * Intermediate values. + * + * .. c:member:: cf_sha256_context.partial + * Unprocessed input. + * + * .. c:member:: cf_sha256_context.npartial + * Number of bytes of unprocessed input. + * + * .. c:member:: cf_sha256_context.blocks + * Number of full blocks processed. + */ +typedef struct +{ + uint32_t H[8]; /* State. */ + uint8_t partial[CF_SHA256_BLOCKSZ]; /* Partial block of input. */ + uint32_t blocks; /* Number of full blocks processed into H. */ + size_t npartial; /* Number of bytes in prefix of partial. */ +} cf_sha256_context; + +/* .. c:function:: $DECL + * Sets up `ctx` ready to hash a new message. + */ +extern void cf_sha256_init(cf_sha256_context *ctx); + +/* .. c:function:: $DECL + * Hashes `nbytes` at `data`. Copies the data if there isn't enough to make + * a full block. + */ +extern void cf_sha256_update(cf_sha256_context *ctx, const void *data, size_t nbytes); + +/* .. c:function:: $DECL + * Finishes the hash operation, writing `CF_SHA256_HASHSZ` bytes to `hash`. + * + * This leaves `ctx` unchanged. + */ +extern void cf_sha256_digest(const cf_sha256_context *ctx, uint8_t hash[CF_SHA256_HASHSZ]); + +/* .. c:function:: $DECL + * Finishes the hash operation, writing `CF_SHA256_HASHSZ` bytes to `hash`. + * + * This destroys `ctx`, but uses less stack than :c:func:`cf_sha256_digest`. + */ +extern void cf_sha256_digest_final(cf_sha256_context *ctx, uint8_t hash[CF_SHA256_HASHSZ]); + +/* .. c:function:: $DECL + * Sets up `ctx` ready to hash a new message. + * + * nb. SHA224 uses SHA256's underlying types. + */ +extern void cf_sha224_init(cf_sha256_context *ctx); + +/* .. c:function:: $DECL + * Hashes `nbytes` at `data`. Copies the data if there isn't enough to make + * a full block. + */ +extern void cf_sha224_update(cf_sha256_context *ctx, const void *data, size_t nbytes); + +/* .. c:function:: $DECL + * Finishes the hash operation, writing `CF_SHA224_HASHSZ` bytes to `hash`. + * + * This leaves `ctx` unchanged. + */ +extern void cf_sha224_digest(const cf_sha256_context *ctx, uint8_t hash[CF_SHA224_HASHSZ]); + +/* .. c:function:: $DECL + * Finishes the hash operation, writing `CF_SHA224_HASHSZ` bytes to `hash`. + * + * This destroys `ctx`, but uses less stack than :c:func:`cf_sha224_digest`. + */ +extern void cf_sha224_digest_final(cf_sha256_context *ctx, uint8_t hash[CF_SHA224_HASHSZ]); + +/* .. c:var:: cf_sha224 + * Abstract interface to SHA224. See :c:type:`cf_chash` for more information. + */ +extern const cf_chash cf_sha224; + +/* .. c:var:: cf_sha256 + * Abstract interface to SHA256. See :c:type:`cf_chash` for more information. + */ +extern const cf_chash cf_sha256; + +/** + * SHA384/SHA512 + * ============= + */ + +/* .. c:macro:: CF_SHA384_HASHSZ + * The output size of SHA384: 48 bytes. */ +#define CF_SHA384_HASHSZ 48 + +/* .. c:macro:: CF_SHA384_BLOCKSZ + * The block size of SHA384: 128 bytes. */ +#define CF_SHA384_BLOCKSZ 128 + +/* .. c:macro:: CF_SHA512_HASHSZ + * The output size of SHA512: 64 bytes. */ +#define CF_SHA512_HASHSZ 64 + +/* .. c:macro:: CF_SHA512_BLOCKSZ + * The block size of SHA512: 128 bytes. */ +#define CF_SHA512_BLOCKSZ 128 + +/* .. c:type:: cf_sha512_context + * Incremental SHA512 hashing context. + * + * .. c:member:: cf_sha512_context.H + * Intermediate values. + * + * .. c:member:: cf_sha512_context.partial + * Unprocessed input. + * + * .. c:member:: cf_sha512_context.npartial + * Number of bytes of unprocessed input. + * + * .. c:member:: cf_sha512_context.blocks + * Number of full blocks processed. + */ +typedef struct +{ + uint64_t H[8]; + uint8_t partial[CF_SHA512_BLOCKSZ]; + uint32_t blocks; + size_t npartial; +} cf_sha512_context; + +/* .. c:function:: $DECL + * Sets up `ctx` ready to hash a new message. + */ +extern void cf_sha512_init(cf_sha512_context *ctx); + +/* .. c:function:: $DECL + * Hashes `nbytes` at `data`. Copies the data if there isn't enough to make + * a full block. + */ +extern void cf_sha512_update(cf_sha512_context *ctx, const void *data, size_t nbytes); + +/* .. c:function:: $DECL + * Finishes the hash operation, writing `CF_SHA512_HASHSZ` bytes to `hash`. + * + * This leaves `ctx` unchanged. + */ +extern void cf_sha512_digest(const cf_sha512_context *ctx, uint8_t hash[CF_SHA512_HASHSZ]); + +/* .. c:function:: $DECL + * Finishes the hash operation, writing `CF_SHA512_HASHSZ` bytes to `hash`. + * + * This destroys `ctx`, but uses less stack than :c:func:`cf_sha512_digest`. + */ +extern void cf_sha512_digest_final(cf_sha512_context *ctx, uint8_t hash[CF_SHA512_HASHSZ]); + +/* .. c:function:: $DECL + * Sets up `ctx` ready to hash a new message. + * + * nb. SHA384 uses SHA512's underlying types. + */ +extern void cf_sha384_init(cf_sha512_context *ctx); + +/* .. c:function:: $DECL + * Hashes `nbytes` at `data`. Copies the data if there isn't enough to make + * a full block. + */ +extern void cf_sha384_update(cf_sha512_context *ctx, const void *data, size_t nbytes); + +/* .. c:function:: $DECL + * Finishes the hash operation, writing `CF_SHA384_HASHSZ` bytes to `hash`. + * + * This leaves `ctx` unchanged. + */ +extern void cf_sha384_digest(const cf_sha512_context *ctx, uint8_t hash[CF_SHA384_HASHSZ]); + +/* .. c:function:: $DECL + * Finishes the hash operation, writing `CF_SHA384_HASHSZ` bytes to `hash`. + * + * This destroys `ctx`, but uses less stack than :c:func:`cf_sha384_digest`. + */ +extern void cf_sha384_digest_final(cf_sha512_context *ctx, uint8_t hash[CF_SHA384_HASHSZ]); + +/* .. c:var:: cf_sha384 + * Abstract interface to SHA384. See :c:type:`cf_chash` for more information. + */ +extern const cf_chash cf_sha384; + +/* .. c:var:: cf_sha512 + * Abstract interface to SHA512. See :c:type:`cf_chash` for more information. + */ +extern const cf_chash cf_sha512; + +#endif diff --git a/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/sha256.c b/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/sha256.c new file mode 100644 index 00000000..8ecef168 --- /dev/null +++ b/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/sha256.c @@ -0,0 +1,232 @@ +/* + * cifra - embedded cryptography library + * Written in 2014 by Joseph Birr-Pixton + * + * To the extent possible under law, the author(s) have dedicated all + * copyright and related and neighboring rights to this software to the + * public domain worldwide. This software is distributed without any + * warranty. + * + * You should have received a copy of the CC0 Public Domain Dedication + * along with this software. If not, see + * . + */ + +#include + +#include "sha2.h" +#include "blockwise.h" +#include "bitops.h" +#include "handy.h" +#include "tassert.h" + +static const uint32_t K[64] = { + 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, + 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5, + 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, + 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, + 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, + 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, + 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, + 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967, + 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, + 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, + 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, + 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070, + 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, + 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3, + 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, + 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2 +}; + +# define CH(x, y, z) (((x) & (y)) ^ (~(x) & (z))) +# define MAJ(x, y, z) (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z))) +# define BSIG0(x) (rotr32((x), 2) ^ rotr32((x), 13) ^ rotr32((x), 22)) +# define BSIG1(x) (rotr32((x), 6) ^ rotr32((x), 11) ^ rotr32((x), 25)) +# define SSIG0(x) (rotr32((x), 7) ^ rotr32((x), 18) ^ ((x) >> 3)) +# define SSIG1(x) (rotr32((x), 17) ^ rotr32((x), 19) ^ ((x) >> 10)) + +void cf_sha256_init(cf_sha256_context *ctx) +{ + memset(ctx, 0, sizeof *ctx); + ctx->H[0] = 0x6a09e667; + ctx->H[1] = 0xbb67ae85; + ctx->H[2] = 0x3c6ef372; + ctx->H[3] = 0xa54ff53a; + ctx->H[4] = 0x510e527f; + ctx->H[5] = 0x9b05688c; + ctx->H[6] = 0x1f83d9ab; + ctx->H[7] = 0x5be0cd19; +} + +void cf_sha224_init(cf_sha256_context *ctx) +{ + memset(ctx, 0, sizeof *ctx); + ctx->H[0] = 0xc1059ed8; + ctx->H[1] = 0x367cd507; + ctx->H[2] = 0x3070dd17; + ctx->H[3] = 0xf70e5939; + ctx->H[4] = 0xffc00b31; + ctx->H[5] = 0x68581511; + ctx->H[6] = 0x64f98fa7; + ctx->H[7] = 0xbefa4fa4; +} + +static void sha256_update_block(void *vctx, const uint8_t *inp) +{ + cf_sha256_context *ctx = vctx; + + /* This is a 16-word window into the whole W array. */ + uint32_t W[16]; + + uint32_t a = ctx->H[0], + b = ctx->H[1], + c = ctx->H[2], + d = ctx->H[3], + e = ctx->H[4], + f = ctx->H[5], + g = ctx->H[6], + h = ctx->H[7], + Wt; + + size_t t; + for (t = 0; t < 64; t++) + { + /* For W[0..16] we process the input into W. + * For W[16..64] we compute the next W value: + * + * W[t] = SSIG1(W[t - 2]) + W[t - 7] + SSIG0(W[t - 15]) + W[t - 16]; + * + * But all W indices are reduced mod 16 into our window. + */ + if (t < 16) + { + W[t] = Wt = read32_be(inp); + inp += 4; + } else { + Wt = SSIG1(W[(t - 2) % 16]) + + W[(t - 7) % 16] + + SSIG0(W[(t - 15) % 16]) + + W[(t - 16) % 16]; + W[t % 16] = Wt; + } + + uint32_t T1 = h + BSIG1(e) + CH(e, f, g) + K[t] + Wt; + uint32_t T2 = BSIG0(a) + MAJ(a, b, c); + h = g; + g = f; + f = e; + e = d + T1; + d = c; + c = b; + b = a; + a = T1 + T2; + } + + ctx->H[0] += a; + ctx->H[1] += b; + ctx->H[2] += c; + ctx->H[3] += d; + ctx->H[4] += e; + ctx->H[5] += f; + ctx->H[6] += g; + ctx->H[7] += h; + + ctx->blocks++; +} + +void cf_sha256_update(cf_sha256_context *ctx, const void *data, size_t nbytes) +{ + cf_blockwise_accumulate(ctx->partial, &ctx->npartial, sizeof ctx->partial, + data, nbytes, + sha256_update_block, ctx); +} + +void cf_sha224_update(cf_sha256_context *ctx, const void *data, size_t nbytes) +{ + cf_sha256_update(ctx, data, nbytes); +} + +void cf_sha256_digest(const cf_sha256_context *ctx, uint8_t hash[CF_SHA256_HASHSZ]) +{ + /* We copy the context, so the finalisation doesn't effect the caller's + * context. This means the caller can do: + * + * x = init() + * x.update('hello') + * h1 = x.digest() + * x.update(' world') + * h2 = x.digest() + * + * to get h1 = H('hello') and h2 = H('hello world') + * + * This wouldn't work if we applied MD-padding to *ctx. + */ + + cf_sha256_context ours = *ctx; + cf_sha256_digest_final(&ours, hash); +} + +void cf_sha256_digest_final(cf_sha256_context *ctx, uint8_t hash[CF_SHA256_HASHSZ]) +{ + uint64_t digested_bytes = ctx->blocks; + digested_bytes = digested_bytes * CF_SHA256_BLOCKSZ + ctx->npartial; + uint64_t digested_bits = digested_bytes * 8; + + size_t padbytes = CF_SHA256_BLOCKSZ - ((digested_bytes + 8) % CF_SHA256_BLOCKSZ); + + /* Hash 0x80 00 ... block first. */ + cf_blockwise_acc_pad(ctx->partial, &ctx->npartial, sizeof ctx->partial, + 0x80, 0x00, 0x00, padbytes, + sha256_update_block, ctx); + + /* Now hash length. */ + uint8_t buf[8]; + write64_be(digested_bits, buf); + cf_sha256_update(ctx, buf, 8); + + /* We ought to have got our padding calculation right! */ + assert(ctx->npartial == 0); + + write32_be(ctx->H[0], hash + 0); + write32_be(ctx->H[1], hash + 4); + write32_be(ctx->H[2], hash + 8); + write32_be(ctx->H[3], hash + 12); + write32_be(ctx->H[4], hash + 16); + write32_be(ctx->H[5], hash + 20); + write32_be(ctx->H[6], hash + 24); + write32_be(ctx->H[7], hash + 28); + + memset(ctx, 0, sizeof *ctx); +} + +void cf_sha224_digest(const cf_sha256_context *ctx, uint8_t hash[CF_SHA224_HASHSZ]) +{ + uint8_t full[CF_SHA256_HASHSZ]; + cf_sha256_digest(ctx, full); + memcpy(hash, full, CF_SHA224_HASHSZ); +} + +void cf_sha224_digest_final(cf_sha256_context *ctx, uint8_t hash[CF_SHA224_HASHSZ]) +{ + uint8_t full[CF_SHA256_HASHSZ]; + cf_sha256_digest_final(ctx, full); + memcpy(hash, full, CF_SHA224_HASHSZ); +} + +const cf_chash cf_sha224 = { + .hashsz = CF_SHA224_HASHSZ, + .blocksz = CF_SHA256_BLOCKSZ, + .init = (cf_chash_init) cf_sha224_init, + .update = (cf_chash_update) cf_sha224_update, + .digest = (cf_chash_digest) cf_sha224_digest +}; + +const cf_chash cf_sha256 = { + .hashsz = CF_SHA256_HASHSZ, + .blocksz = CF_SHA256_BLOCKSZ, + .init = (cf_chash_init) cf_sha256_init, + .update = (cf_chash_update) cf_sha256_update, + .digest = (cf_chash_digest) cf_sha256_digest +}; + diff --git a/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/sha3.c b/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/sha3.c new file mode 100644 index 00000000..f130747d --- /dev/null +++ b/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/sha3.c @@ -0,0 +1,444 @@ +/* + * cifra - embedded cryptography library + * Written in 2014 by Joseph Birr-Pixton + * + * To the extent possible under law, the author(s) have dedicated all + * copyright and related and neighboring rights to this software to the + * public domain worldwide. This software is distributed without any + * warranty. + * + * You should have received a copy of the CC0 Public Domain Dedication + * along with this software. If not, see + * . + */ + +#include + +#include "sha3.h" +#include "blockwise.h" +#include "handy.h" +#include "bitops.h" +#include "tassert.h" + +/* The round constants, pre-interleaved. See bitinter.py */ +static const cf_sha3_bi round_constants[24] = { + { 0x00000001, 0x00000000 }, { 0x00000000, 0x00000089 }, + { 0x00000000, 0x8000008b }, { 0x00000000, 0x80008080 }, + { 0x00000001, 0x0000008b }, { 0x00000001, 0x00008000 }, + { 0x00000001, 0x80008088 }, { 0x00000001, 0x80000082 }, + { 0x00000000, 0x0000000b }, { 0x00000000, 0x0000000a }, + { 0x00000001, 0x00008082 }, { 0x00000000, 0x00008003 }, + { 0x00000001, 0x0000808b }, { 0x00000001, 0x8000000b }, + { 0x00000001, 0x8000008a }, { 0x00000001, 0x80000081 }, + { 0x00000000, 0x80000081 }, { 0x00000000, 0x80000008 }, + { 0x00000000, 0x00000083 }, { 0x00000000, 0x80008003 }, + { 0x00000001, 0x80008088 }, { 0x00000000, 0x80000088 }, + { 0x00000001, 0x00008000 }, { 0x00000000, 0x80008082 } +}; + +static const uint8_t rotation_constants[5][5] = { + { 0, 1, 62, 28, 27, }, + { 36, 44, 6, 55, 20, }, + { 3, 10, 43, 25, 39, }, + { 41, 45, 15, 21, 8, }, + { 18, 2, 61, 56, 14, } +}; + +/* --- Bit interleaving and uninterleaving --- */ +/* See bitinter.py for models of these bit twiddles. The originals + * come from "Hacker's Delight" by Henry Warren, where they are named + * shuffle2 and unshuffle. + * See: + * http://www.hackersdelight.org/hdcodetxt/shuffle.c.txt + * + * The overriding aim is to change bit ordering: + * AaBbCcDd -> ABCDabcd + * and back. Once they're in the shuffled form, we can extract + * odd/even bits by taking the half words from each pair. + */ + +static inline uint32_t shuffle_out(uint32_t x) +{ + uint32_t t; + t = (x ^ (x >> 1)) & 0x22222222; x = x ^ t ^ (t << 1); + t = (x ^ (x >> 2)) & 0x0c0c0c0c; x = x ^ t ^ (t << 2); + t = (x ^ (x >> 4)) & 0x00f000f0; x = x ^ t ^ (t << 4); + t = (x ^ (x >> 8)) & 0x0000ff00; x = x ^ t ^ (t << 8); + return x; +} + +/* Convert ABCDabcd -> AaBbCcDd. */ +static inline uint32_t shuffle_in(uint32_t x) +{ + uint32_t t; + t = (x ^ (x >> 8)) & 0x0000ff00; x = x ^ t ^ (t << 8); + t = (x ^ (x >> 4)) & 0x00f000f0; x = x ^ t ^ (t << 4); + t = (x ^ (x >> 2)) & 0x0c0c0c0c; x = x ^ t ^ (t << 2); + t = (x ^ (x >> 1)) & 0x22222222; x = x ^ t ^ (t << 1); + return x; +} + +static inline void read64_bi(cf_sha3_bi *out, const uint8_t data[8]) +{ + uint32_t lo = read32_le(data + 0), + hi = read32_le(data + 4); + + lo = shuffle_out(lo); + hi = shuffle_out(hi); + + out->odd = (lo & 0x0000ffff) | (hi << 16); + out->evn = (lo >> 16) | (hi & 0xffff0000); +} + +static inline void write64_bi(const cf_sha3_bi *bi, uint8_t data[8]) +{ + uint32_t lo = (bi->odd & 0x0000ffff) | (bi->evn << 16), + hi = (bi->odd >> 16) | (bi->evn & 0xffff0000); + + lo = shuffle_in(lo); + hi = shuffle_in(hi); + + write32_le(lo, data + 0); + write32_le(hi, data + 4); +} + +static inline void rotl_bi_1(cf_sha3_bi *out, const cf_sha3_bi *in) +{ + /* in bit-interleaved representation, a rotation of 1 + * is a swap plus a single rotation of the odd word. */ + out->odd = rotl32(in->evn, 1); + out->evn = in->odd; +} + +static inline void rotl_bi_n(cf_sha3_bi *out, const cf_sha3_bi *in, uint8_t rot) +{ + uint8_t half = rot >> 1; + + /* nb. rot is a constant, so this isn't a branch leak. */ + if (rot & 1) + { + out->odd = rotl32(in->evn, half + 1); + out->evn = rotl32(in->odd, half); + } else { + out->evn = rotl32(in->evn, half); + out->odd = rotl32(in->odd, half); + } +} + +/* --- */ + +static void sha3_init(cf_sha3_context *ctx, uint16_t rate_bits, uint16_t capacity_bits) +{ + mem_clean(ctx, sizeof *ctx); + ctx->rate = rate_bits / 8; + ctx->capacity = capacity_bits / 8; +} + +static void absorb(cf_sha3_context *ctx, const uint8_t *data, uint16_t sz) +{ + uint16_t lanes = sz / 8; + + for (uint16_t x = 0, y = 0, i = 0; i < lanes; i++) + { + cf_sha3_bi bi; + read64_bi(&bi, data); + ctx->A[x][y].odd ^= bi.odd; + ctx->A[x][y].evn ^= bi.evn; + data += 8; + + x++; + if (x == 5) + { + y++; + x = 0; + } + } +} + +/* Integers [-1,20] mod 5. To avoid a divmod. Indices + * are constants; not data-dependant. */ +static const uint8_t mod5_table[] = { + 4, + 0, + 1, 2, 3, 4, 0, 1, 2, 3, 4, 0, + 1, 2, 3, 4, 0, 1, 2, 3, 4, 0 +}; + +#define MOD5(x) (mod5_table[(x) + 1]) + +static void theta(cf_sha3_context *ctx) +{ + cf_sha3_bi C[5], D[5]; + + for (int x = 0; x < 5; x++) + { + C[x].odd = ctx->A[x][0].odd ^ ctx->A[x][1].odd ^ ctx->A[x][2].odd ^ ctx->A[x][3].odd ^ ctx->A[x][4].odd; + C[x].evn = ctx->A[x][0].evn ^ ctx->A[x][1].evn ^ ctx->A[x][2].evn ^ ctx->A[x][3].evn ^ ctx->A[x][4].evn; + } + + for (int x = 0; x < 5; x++) + { + cf_sha3_bi r; + rotl_bi_1(&r, &C[MOD5(x + 1)]); + D[x].odd = C[MOD5(x - 1)].odd ^ r.odd; + D[x].evn = C[MOD5(x - 1)].evn ^ r.evn; + + for (int y = 0; y < 5; y++) + { + ctx->A[x][y].odd ^= D[x].odd; + ctx->A[x][y].evn ^= D[x].evn; + } + } +} + +static void rho_pi_chi(cf_sha3_context *ctx) +{ + cf_sha3_bi B[5][5] = { { { 0 } } }; + + for (int x = 0; x < 5; x++) + for (int y = 0; y < 5; y++) + rotl_bi_n(&B[y][MOD5(2 * x + 3 * y)], &ctx->A[x][y], rotation_constants[y][x]); + + for (int x = 0; x < 5; x++) + { + unsigned x1 = MOD5(x + 1); + unsigned x2 = MOD5(x + 2); + + for (int y = 0; y < 5; y++) + { + ctx->A[x][y].odd = B[x][y].odd ^ ((~ B[x1][y].odd) & B[x2][y].odd); + ctx->A[x][y].evn = B[x][y].evn ^ ((~ B[x1][y].evn) & B[x2][y].evn); + } + } +} + +static void permute(cf_sha3_context *ctx) +{ + for (int r = 0; r < 24; r++) + { + theta(ctx); + rho_pi_chi(ctx); + + /* iota */ + ctx->A[0][0].odd ^= round_constants[r].odd; + ctx->A[0][0].evn ^= round_constants[r].evn; + } +} + +static void extract(cf_sha3_context *ctx, uint8_t *out, size_t nbytes) +{ + uint16_t lanes = (nbytes + 7) / 8; + + for (uint16_t x = 0, y = 0, i = 0; i < lanes; i++) + { + if (nbytes >= 8) + { + write64_bi(&ctx->A[x][y], out); + out += 8; + nbytes -= 8; + } else { + uint8_t buf[8]; + write64_bi(&ctx->A[x][y], buf); + memcpy(out, buf, nbytes); + out += nbytes; + nbytes = 0; + } + + x++; + if (x == 5) + { + y++; + x = 0; + } + } +} + +static void squeeze(cf_sha3_context *ctx, uint8_t *out, size_t nbytes) +{ + while (nbytes) + { + size_t take = MIN(nbytes, ctx->rate); + extract(ctx, out, take); + out += take; + nbytes -= take; + + assert(nbytes == 0); +#if 0 + /* Note: if we ever have |H| >= rate, we need to permute + * after each rate-length block. + * + * This cannot currently happen. */ + if (nbytes) + permute(ctx); +#endif + } +} + +static void sha3_block(void *vctx, const uint8_t *data) +{ + cf_sha3_context *ctx = vctx; + + absorb(ctx, data, ctx->rate); + permute(ctx); +} + +static void sha3_update(cf_sha3_context *ctx, const void *data, size_t nbytes) +{ + cf_blockwise_accumulate(ctx->partial, &ctx->npartial, ctx->rate, + data, nbytes, + sha3_block, ctx); +} + +/* Padding and domain separation constants. + * + * FIPS 202 specifies that 0b01 is appended to hash function + * input, and 0b1111 is appended to SHAKE input. + * + * This is done in internal (little endian) bit ordering, and + * we convolve it with the leftmost (first) padding bit, so: + * + * Hash: 0b110 + * SHAKE: 0b11111 + */ + +#define DOMAIN_HASH_PAD 0x06 +#define DOMAIN_SHAKE_PAD 0x1f + +static void pad(cf_sha3_context *ctx, uint8_t domain, size_t npad) +{ + assert(npad >= 1); + + cf_blockwise_acc_pad(ctx->partial, &ctx->npartial, ctx->rate, + domain, 0x00, 0x80, + npad, + sha3_block, ctx); +} + +static void pad_and_squeeze(cf_sha3_context *ctx, uint8_t *out, size_t nout) +{ + pad(ctx, DOMAIN_HASH_PAD, ctx->rate - ctx->npartial); + assert(ctx->npartial == 0); + + squeeze(ctx, out, nout); + mem_clean(ctx, sizeof *ctx); +} + +/* SHA3-224 */ +void cf_sha3_224_init(cf_sha3_context *ctx) +{ + sha3_init(ctx, 1152, 448); +} + +void cf_sha3_224_update(cf_sha3_context *ctx, const void *data, size_t nbytes) +{ + sha3_update(ctx, data, nbytes); +} + +void cf_sha3_224_digest(const cf_sha3_context *ctx, uint8_t hash[CF_SHA3_224_HASHSZ]) +{ + cf_sha3_context ours = *ctx; + cf_sha3_224_digest_final(&ours, hash); +} + +void cf_sha3_224_digest_final(cf_sha3_context *ctx, uint8_t hash[CF_SHA3_224_HASHSZ]) +{ + pad_and_squeeze(ctx, hash, CF_SHA3_224_HASHSZ); +} + +const cf_chash cf_sha3_224 = { + .hashsz = CF_SHA3_224_HASHSZ, + .blocksz = CF_SHA3_224_BLOCKSZ, + .init = (cf_chash_init) cf_sha3_224_init, + .update = (cf_chash_update) cf_sha3_224_update, + .digest = (cf_chash_digest) cf_sha3_224_digest +}; + +/* SHA3-256 */ +void cf_sha3_256_init(cf_sha3_context *ctx) +{ + sha3_init(ctx, 1088, 512); +} + +void cf_sha3_256_update(cf_sha3_context *ctx, const void *data, size_t nbytes) +{ + sha3_update(ctx, data, nbytes); +} + +void cf_sha3_256_digest(const cf_sha3_context *ctx, uint8_t hash[CF_SHA3_256_HASHSZ]) +{ + cf_sha3_context ours = *ctx; + cf_sha3_256_digest_final(&ours, hash); +} + +void cf_sha3_256_digest_final(cf_sha3_context *ctx, uint8_t hash[CF_SHA3_256_HASHSZ]) +{ + pad_and_squeeze(ctx, hash, CF_SHA3_256_HASHSZ); +} + +const cf_chash cf_sha3_256 = { + .hashsz = CF_SHA3_256_HASHSZ, + .blocksz = CF_SHA3_256_BLOCKSZ, + .init = (cf_chash_init) cf_sha3_256_init, + .update = (cf_chash_update) cf_sha3_256_update, + .digest = (cf_chash_digest) cf_sha3_256_digest +}; + +/* SHA3-384 */ +void cf_sha3_384_init(cf_sha3_context *ctx) +{ + sha3_init(ctx, 832, 768); +} + +void cf_sha3_384_update(cf_sha3_context *ctx, const void *data, size_t nbytes) +{ + sha3_update(ctx, data, nbytes); +} + +void cf_sha3_384_digest(const cf_sha3_context *ctx, uint8_t hash[CF_SHA3_384_HASHSZ]) +{ + cf_sha3_context ours = *ctx; + cf_sha3_384_digest_final(&ours, hash); +} + +void cf_sha3_384_digest_final(cf_sha3_context *ctx, uint8_t hash[CF_SHA3_384_HASHSZ]) +{ + pad_and_squeeze(ctx, hash, CF_SHA3_384_HASHSZ); +} + +const cf_chash cf_sha3_384 = { + .hashsz = CF_SHA3_384_HASHSZ, + .blocksz = CF_SHA3_384_BLOCKSZ, + .init = (cf_chash_init) cf_sha3_384_init, + .update = (cf_chash_update) cf_sha3_384_update, + .digest = (cf_chash_digest) cf_sha3_384_digest +}; + +/* SHA3-512 */ +void cf_sha3_512_init(cf_sha3_context *ctx) +{ + sha3_init(ctx, 576, 1024); +} + +void cf_sha3_512_update(cf_sha3_context *ctx, const void *data, size_t nbytes) +{ + sha3_update(ctx, data, nbytes); +} + +void cf_sha3_512_digest(const cf_sha3_context *ctx, uint8_t hash[CF_SHA3_512_HASHSZ]) +{ + cf_sha3_context ours = *ctx; + cf_sha3_512_digest_final(&ours, hash); +} + +void cf_sha3_512_digest_final(cf_sha3_context *ctx, uint8_t hash[CF_SHA3_512_HASHSZ]) +{ + pad_and_squeeze(ctx, hash, CF_SHA3_512_HASHSZ); +} + +const cf_chash cf_sha3_512 = { + .hashsz = CF_SHA3_512_HASHSZ, + .blocksz = CF_SHA3_512_BLOCKSZ, + .init = (cf_chash_init) cf_sha3_512_init, + .update = (cf_chash_update) cf_sha3_512_update, + .digest = (cf_chash_digest) cf_sha3_512_digest +}; diff --git a/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/sha3.h b/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/sha3.h new file mode 100644 index 00000000..44895dc3 --- /dev/null +++ b/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/sha3.h @@ -0,0 +1,180 @@ +/* + * cifra - embedded cryptography library + * Written in 2014 by Joseph Birr-Pixton + * + * To the extent possible under law, the author(s) have dedicated all + * copyright and related and neighboring rights to this software to the + * public domain worldwide. This software is distributed without any + * warranty. + * + * You should have received a copy of the CC0 Public Domain Dedication + * along with this software. If not, see + * . + */ + +#ifndef SHA3_H +#define SHA3_H + +#include +#include + +#include "chash.h" + +/** + * SHA3/Keccak + * =========== + * This implementation is compatible with FIPS 202, + * rather than the original Keccak submission. + * + */ + +/* .. c:macro:: CF_SHA3_224_HASHSZ + * The output size of SHA3-224: 28 bytes. */ +#define CF_SHA3_224_HASHSZ 28 + +/* .. c:macro:: CF_SHA3_256_HASHSZ + * The output size of SHA3-256: 32 bytes. */ +#define CF_SHA3_256_HASHSZ 32 + +/* .. c:macro:: CF_SHA3_384_HASHSZ + * The output size of SHA3-384: 48 bytes. */ +#define CF_SHA3_384_HASHSZ 48 + +/* .. c:macro:: CF_SHA3_512_HASHSZ + * The output size of SHA3-512: 64 bytes. */ +#define CF_SHA3_512_HASHSZ 64 + +/* .. c:macro:: CF_SHA3_224_BLOCKSZ + * The block size of SHA3-224. */ +#define CF_SHA3_224_BLOCKSZ 144 + +/* .. c:macro:: CF_SHA3_256_BLOCKSZ + * The block size of SHA3-256. */ +#define CF_SHA3_256_BLOCKSZ 136 + +/* .. c:macro:: CF_SHA3_384_BLOCKSZ + * The block size of SHA3-384. */ +#define CF_SHA3_384_BLOCKSZ 104 + +/* .. c:macro:: CF_SHA3_512_BLOCKSZ + * The block size of SHA3-512. */ +#define CF_SHA3_512_BLOCKSZ 72 + +/* We use bit-interleaved internal representation. This + * stores a 64 bit quantity in two 32 bit words: one word + * contains odd bits, the other even. This means 64-bit rotations + * are cheaper to compute. */ +typedef struct +{ + uint32_t odd, evn; +} cf_sha3_bi; + +/* .. c:type:: cf_sha3_context + * Incremental SHA3 hashing context. + * + * .. c:member:: cf_sha3_context.A + * Intermediate state. + * + * .. c:member:: cf_sha3_context.partial + * Unprocessed input. + * + * .. c:member:: cf_sha3_context.npartial + * Number of bytes of unprocessed input. + * + * .. c:member:: cf_sha3_context.rate + * Sponge absorption rate. + * + * .. c:member:: cf_sha3_context.rate + * Sponge capacity. + */ +typedef struct +{ + /* State is a 5x5 block of 64-bit values, for Keccak-f[1600]. */ + cf_sha3_bi A[5][5]; + uint8_t partial[CF_SHA3_224_BLOCKSZ]; + size_t npartial; + uint16_t rate, capacity; /* rate and capacity, in bytes. */ +} cf_sha3_context; + + +/* -- _init functions -- */ + +/* .. c:function:: $DECL */ +extern void cf_sha3_224_init(cf_sha3_context *ctx); + +/* .. c:function:: $DECL */ +extern void cf_sha3_256_init(cf_sha3_context *ctx); + +/* .. c:function:: $DECL */ +extern void cf_sha3_384_init(cf_sha3_context *ctx); + +/* .. c:function:: $DECL + * Sets up `ctx` ready to hash a new message. + */ +extern void cf_sha3_512_init(cf_sha3_context *ctx); + +/* -- _update functions -- */ + +/* .. c:function:: $DECL */ +extern void cf_sha3_224_update(cf_sha3_context *ctx, const void *data, size_t nbytes); + +/* .. c:function:: $DECL */ +extern void cf_sha3_256_update(cf_sha3_context *ctx, const void *data, size_t nbytes); + +/* .. c:function:: $DECL */ +extern void cf_sha3_384_update(cf_sha3_context *ctx, const void *data, size_t nbytes); + +/* .. c:function:: $DECL + * Hashes `nbytes` at `data`. Copies the data for processing later if there + * isn't enough to make a full block. + */ +extern void cf_sha3_512_update(cf_sha3_context *ctx, const void *data, size_t nbytes); + +/* -- _digest functions -- */ + +/* .. c:function:: $DECL */ +extern void cf_sha3_224_digest(const cf_sha3_context *ctx, uint8_t hash[CF_SHA3_224_HASHSZ]); + +/* .. c:function:: $DECL */ +extern void cf_sha3_256_digest(const cf_sha3_context *ctx, uint8_t hash[CF_SHA3_256_HASHSZ]); + +/* .. c:function:: $DECL */ +extern void cf_sha3_384_digest(const cf_sha3_context *ctx, uint8_t hash[CF_SHA3_384_HASHSZ]); + +/* .. c:function:: $DECL + * Finishes the hashing operation, writing result to `hash`. + * + * This leaves `ctx` unchanged. + */ +extern void cf_sha3_512_digest(const cf_sha3_context *ctx, uint8_t hash[CF_SHA3_512_HASHSZ]); + +/* -- _digest_final functions -- */ + +/* .. c:function:: $DECL */ +extern void cf_sha3_224_digest_final(cf_sha3_context *ctx, uint8_t hash[CF_SHA3_224_HASHSZ]); + +/* .. c:function:: $DECL */ +extern void cf_sha3_256_digest_final(cf_sha3_context *ctx, uint8_t hash[CF_SHA3_256_HASHSZ]); + +/* .. c:function:: $DECL */ +extern void cf_sha3_384_digest_final(cf_sha3_context *ctx, uint8_t hash[CF_SHA3_384_HASHSZ]); + +/* .. c:function:: $DECL + * Finishes the hashing operation, writing result to `hash`. + * + * This destroys the contents of `ctx`. + */ +extern void cf_sha3_512_digest_final(cf_sha3_context *ctx, uint8_t hash[CF_SHA3_512_HASHSZ]); + +/* .. c:var:: cf_sha3_224 + * .. c:var:: cf_sha3_256 + * .. c:var:: cf_sha3_384 + * .. c:var:: cf_sha3_512 + * Abstract interface to SHA3 functions. See :c:type:`cf_chash` for more information. + */ +extern const cf_chash cf_sha3_224; +extern const cf_chash cf_sha3_256; +extern const cf_chash cf_sha3_384; +extern const cf_chash cf_sha3_512; + +#endif diff --git a/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/sha512.c b/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/sha512.c new file mode 100644 index 00000000..2d1c8964 --- /dev/null +++ b/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/sha512.c @@ -0,0 +1,248 @@ +/* + * cifra - embedded cryptography library + * Written in 2014 by Joseph Birr-Pixton + * + * To the extent possible under law, the author(s) have dedicated all + * copyright and related and neighboring rights to this software to the + * public domain worldwide. This software is distributed without any + * warranty. + * + * You should have received a copy of the CC0 Public Domain Dedication + * along with this software. If not, see + * . + */ + +#include + +#include "sha2.h" +#include "blockwise.h" +#include "bitops.h" +#include "handy.h" +#include "tassert.h" + +static const uint64_t K[80] = { + UINT64_C(0x428a2f98d728ae22), UINT64_C(0x7137449123ef65cd), + UINT64_C(0xb5c0fbcfec4d3b2f), UINT64_C(0xe9b5dba58189dbbc), + UINT64_C(0x3956c25bf348b538), UINT64_C(0x59f111f1b605d019), + UINT64_C(0x923f82a4af194f9b), UINT64_C(0xab1c5ed5da6d8118), + UINT64_C(0xd807aa98a3030242), UINT64_C(0x12835b0145706fbe), + UINT64_C(0x243185be4ee4b28c), UINT64_C(0x550c7dc3d5ffb4e2), + UINT64_C(0x72be5d74f27b896f), UINT64_C(0x80deb1fe3b1696b1), + UINT64_C(0x9bdc06a725c71235), UINT64_C(0xc19bf174cf692694), + UINT64_C(0xe49b69c19ef14ad2), UINT64_C(0xefbe4786384f25e3), + UINT64_C(0x0fc19dc68b8cd5b5), UINT64_C(0x240ca1cc77ac9c65), + UINT64_C(0x2de92c6f592b0275), UINT64_C(0x4a7484aa6ea6e483), + UINT64_C(0x5cb0a9dcbd41fbd4), UINT64_C(0x76f988da831153b5), + UINT64_C(0x983e5152ee66dfab), UINT64_C(0xa831c66d2db43210), + UINT64_C(0xb00327c898fb213f), UINT64_C(0xbf597fc7beef0ee4), + UINT64_C(0xc6e00bf33da88fc2), UINT64_C(0xd5a79147930aa725), + UINT64_C(0x06ca6351e003826f), UINT64_C(0x142929670a0e6e70), + UINT64_C(0x27b70a8546d22ffc), UINT64_C(0x2e1b21385c26c926), + UINT64_C(0x4d2c6dfc5ac42aed), UINT64_C(0x53380d139d95b3df), + UINT64_C(0x650a73548baf63de), UINT64_C(0x766a0abb3c77b2a8), + UINT64_C(0x81c2c92e47edaee6), UINT64_C(0x92722c851482353b), + UINT64_C(0xa2bfe8a14cf10364), UINT64_C(0xa81a664bbc423001), + UINT64_C(0xc24b8b70d0f89791), UINT64_C(0xc76c51a30654be30), + UINT64_C(0xd192e819d6ef5218), UINT64_C(0xd69906245565a910), + UINT64_C(0xf40e35855771202a), UINT64_C(0x106aa07032bbd1b8), + UINT64_C(0x19a4c116b8d2d0c8), UINT64_C(0x1e376c085141ab53), + UINT64_C(0x2748774cdf8eeb99), UINT64_C(0x34b0bcb5e19b48a8), + UINT64_C(0x391c0cb3c5c95a63), UINT64_C(0x4ed8aa4ae3418acb), + UINT64_C(0x5b9cca4f7763e373), UINT64_C(0x682e6ff3d6b2b8a3), + UINT64_C(0x748f82ee5defb2fc), UINT64_C(0x78a5636f43172f60), + UINT64_C(0x84c87814a1f0ab72), UINT64_C(0x8cc702081a6439ec), + UINT64_C(0x90befffa23631e28), UINT64_C(0xa4506cebde82bde9), + UINT64_C(0xbef9a3f7b2c67915), UINT64_C(0xc67178f2e372532b), + UINT64_C(0xca273eceea26619c), UINT64_C(0xd186b8c721c0c207), + UINT64_C(0xeada7dd6cde0eb1e), UINT64_C(0xf57d4f7fee6ed178), + UINT64_C(0x06f067aa72176fba), UINT64_C(0x0a637dc5a2c898a6), + UINT64_C(0x113f9804bef90dae), UINT64_C(0x1b710b35131c471b), + UINT64_C(0x28db77f523047d84), UINT64_C(0x32caab7b40c72493), + UINT64_C(0x3c9ebe0a15c9bebc), UINT64_C(0x431d67c49c100d4c), + UINT64_C(0x4cc5d4becb3e42b6), UINT64_C(0x597f299cfc657e2a), + UINT64_C(0x5fcb6fab3ad6faec), UINT64_C(0x6c44198c4a475817) +}; + +# define CH(x, y, z) (((x) & (y)) ^ (~(x) & (z))) +# define MAJ(x, y, z) (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z))) +# define BSIG0(x) (rotr64((x), 28) ^ rotr64((x), 34) ^ rotr64((x), 39)) +# define BSIG1(x) (rotr64((x), 14) ^ rotr64((x), 18) ^ rotr64((x), 41)) +# define SSIG0(x) (rotr64((x), 1) ^ rotr64((x), 8) ^ ((x) >> 7)) +# define SSIG1(x) (rotr64((x), 19) ^ rotr64((x), 61) ^ ((x) >> 6)) + +void cf_sha512_init(cf_sha512_context *ctx) +{ + memset(ctx, 0, sizeof *ctx); + ctx->H[0] = UINT64_C(0x6a09e667f3bcc908); + ctx->H[1] = UINT64_C(0xbb67ae8584caa73b); + ctx->H[2] = UINT64_C(0x3c6ef372fe94f82b); + ctx->H[3] = UINT64_C(0xa54ff53a5f1d36f1); + ctx->H[4] = UINT64_C(0x510e527fade682d1); + ctx->H[5] = UINT64_C(0x9b05688c2b3e6c1f); + ctx->H[6] = UINT64_C(0x1f83d9abfb41bd6b); + ctx->H[7] = UINT64_C(0x5be0cd19137e2179); +} + +void cf_sha384_init(cf_sha512_context *ctx) +{ + memset(ctx, 0, sizeof *ctx); + ctx->H[0] = UINT64_C(0xcbbb9d5dc1059ed8); + ctx->H[1] = UINT64_C(0x629a292a367cd507); + ctx->H[2] = UINT64_C(0x9159015a3070dd17); + ctx->H[3] = UINT64_C(0x152fecd8f70e5939); + ctx->H[4] = UINT64_C(0x67332667ffc00b31); + ctx->H[5] = UINT64_C(0x8eb44a8768581511); + ctx->H[6] = UINT64_C(0xdb0c2e0d64f98fa7); + ctx->H[7] = UINT64_C(0x47b5481dbefa4fa4); +} + +static void sha512_update_block(void *vctx, const uint8_t *inp) +{ + cf_sha512_context *ctx = vctx; + + uint64_t W[16]; + + uint64_t a = ctx->H[0], + b = ctx->H[1], + c = ctx->H[2], + d = ctx->H[3], + e = ctx->H[4], + f = ctx->H[5], + g = ctx->H[6], + h = ctx->H[7], + Wt; + + for (size_t t = 0; t < 80; t++) + { + if (t < 16) + { + W[t] = Wt = read64_be(inp); + inp += 8; + } else { + Wt = SSIG1(W[(t - 2) % 16]) + + W[(t - 7) % 16] + + SSIG0(W[(t - 15) % 16]) + + W[(t - 16) % 16]; + W[t % 16] = Wt; + } + + uint64_t T1 = h + BSIG1(e) + CH(e, f, g) + K[t] + Wt; + uint64_t T2 = BSIG0(a) + MAJ(a, b, c); + h = g; + g = f; + f = e; + e = d + T1; + d = c; + c = b; + b = a; + a = T1 + T2; + } + + ctx->H[0] += a; + ctx->H[1] += b; + ctx->H[2] += c; + ctx->H[3] += d; + ctx->H[4] += e; + ctx->H[5] += f; + ctx->H[6] += g; + ctx->H[7] += h; + + ctx->blocks++; +} + +void cf_sha512_update(cf_sha512_context *ctx, const void *data, size_t nbytes) +{ + cf_blockwise_accumulate(ctx->partial, &ctx->npartial, sizeof ctx->partial, + data, nbytes, + sha512_update_block, ctx); +} + +void cf_sha384_update(cf_sha512_context *ctx, const void *data, size_t nbytes) +{ + cf_sha512_update(ctx, data, nbytes); +} + +void cf_sha512_digest(const cf_sha512_context *ctx, uint8_t hash[CF_SHA512_HASHSZ]) +{ + /* We copy the context, so the finalisation doesn't effect the caller's + * context. This means the caller can do: + * + * x = init() + * x.update('hello') + * h1 = x.digest() + * x.update(' world') + * h2 = x.digest() + * + * to get h1 = H('hello') and h2 = H('hello world') + * + * This wouldn't work if we applied MD-padding to *ctx. + */ + + cf_sha512_context ours = *ctx; + cf_sha512_digest_final(&ours, hash); +} + +void cf_sha512_digest_final(cf_sha512_context *ctx, uint8_t hash[CF_SHA512_HASHSZ]) +{ + uint64_t digested_bytes = ctx->blocks; + digested_bytes = digested_bytes * CF_SHA512_BLOCKSZ + ctx->npartial; + uint64_t digested_bits = digested_bytes * 8; + + size_t padbytes = CF_SHA512_BLOCKSZ - ((digested_bytes + 16) % CF_SHA512_BLOCKSZ); + + /* Hash 0x80 00 ... block first. */ + cf_blockwise_acc_pad(ctx->partial, &ctx->npartial, sizeof ctx->partial, + 0x80, 0x00, 0x00, padbytes, + sha512_update_block, ctx); + + /* Now hash length (this is 128 bits long). */ + uint8_t buf[8]; + write64_be(0, buf); + cf_sha512_update(ctx, buf, 8); + write64_be(digested_bits, buf); + cf_sha512_update(ctx, buf, 8); + + /* We ought to have got our padding calculation right! */ + assert(ctx->npartial == 0); + + write64_be(ctx->H[0], hash + 0); + write64_be(ctx->H[1], hash + 8); + write64_be(ctx->H[2], hash + 16); + write64_be(ctx->H[3], hash + 24); + write64_be(ctx->H[4], hash + 32); + write64_be(ctx->H[5], hash + 40); + write64_be(ctx->H[6], hash + 48); + write64_be(ctx->H[7], hash + 56); + memset(ctx, 0, sizeof *ctx); +} + +void cf_sha384_digest(const cf_sha512_context *ctx, uint8_t hash[CF_SHA384_HASHSZ]) +{ + uint8_t full[CF_SHA512_HASHSZ]; + cf_sha512_digest(ctx, full); + memcpy(hash, full, CF_SHA384_HASHSZ); +} + +void cf_sha384_digest_final(cf_sha512_context *ctx, uint8_t hash[CF_SHA384_HASHSZ]) +{ + uint8_t full[CF_SHA512_HASHSZ]; + cf_sha512_digest_final(ctx, full); + memcpy(hash, full, CF_SHA384_HASHSZ); +} + +const cf_chash cf_sha384 = { + .hashsz = CF_SHA384_HASHSZ, + .blocksz = CF_SHA384_BLOCKSZ, + .init = (cf_chash_init) cf_sha384_init, + .update = (cf_chash_update) cf_sha384_update, + .digest = (cf_chash_digest) cf_sha384_digest +}; + +const cf_chash cf_sha512 = { + .hashsz = CF_SHA512_HASHSZ, + .blocksz = CF_SHA512_BLOCKSZ, + .init = (cf_chash_init) cf_sha512_init, + .update = (cf_chash_update) cf_sha512_update, + .digest = (cf_chash_digest) cf_sha512_digest +}; + diff --git a/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/tassert.h b/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/tassert.h new file mode 100644 index 00000000..58ebb4c8 --- /dev/null +++ b/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/tassert.h @@ -0,0 +1,32 @@ +/* + * cifra - embedded cryptography library + * Written in 2014 by Joseph Birr-Pixton + * + * To the extent possible under law, the author(s) have dedicated all + * copyright and related and neighboring rights to this software to the + * public domain worldwide. This software is distributed without any + * warranty. + * + * You should have received a copy of the CC0 Public Domain Dedication + * along with this software. If not, see + * . + */ + +#ifndef TASSERT_H +#define TASSERT_H + +/* Tiny assert + * ----------- + * + * This is an assert(3) definition which doesn't include any + * strings, but just branches to abort(3) on failure. + */ + +#ifndef FULL_FAT_ASSERT +# include +# define assert(expr) do { if (!(expr)) abort(); } while (0) +#else +# include +#endif + +#endif diff --git a/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/testaes.c b/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/testaes.c new file mode 100644 index 00000000..12543bbf --- /dev/null +++ b/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/testaes.c @@ -0,0 +1,258 @@ +/* + * cifra - embedded cryptography library + * Written in 2014 by Joseph Birr-Pixton + * + * To the extent possible under law, the author(s) have dedicated all + * copyright and related and neighboring rights to this software to the + * public domain worldwide. This software is distributed without any + * warranty. + * + * You should have received a copy of the CC0 Public Domain Dedication + * along with this software. If not, see + * . + */ + +#include "aes.h" +#include "modes.h" +#include "bitops.h" +#include "gf128.h" + +#include "handy.h" +#include "cutest.h" +#include "testutil.h" + +static void test_memclean(void) +{ + uint8_t buf[32], buf2[32]; + memset(buf, 0xff, sizeof buf); + mem_clean(buf + 1, sizeof buf - 2); + TEST_CHECK(buf[0] == 0xff); + TEST_CHECK(buf[1] == 0x00); + TEST_CHECK(buf[16] == 0x00); + TEST_CHECK(buf[30] == 0x00); + TEST_CHECK(buf[31] == 0xff); + + memcpy(buf2, buf, sizeof buf); + TEST_CHECK(buf2[0] == 0xff); + TEST_CHECK(buf2[1] == 0x00); + TEST_CHECK(buf2[16] == 0x00); + TEST_CHECK(buf2[30] == 0x00); + TEST_CHECK(buf2[31] == 0xff); + + memset(buf2, 0xee, sizeof buf); + TEST_CHECK(buf2[0] == 0xee); + TEST_CHECK(buf2[1] == 0xee); + TEST_CHECK(buf2[2] == 0xee); + TEST_CHECK(buf2[3] == 0xee); + TEST_CHECK(buf2[30] == 0xee); + TEST_CHECK(buf2[31] == 0xee); +} + +static void test_bitops_select(void) +{ + uint8_t tab8[8]; + uint32_t tab32[32]; + + for (size_t i = 0; i < 8; i++) + tab8[i] = 1 << i; + for (size_t i = 0; i < 32; i++) + tab32[i] = 1 << i; + + for (size_t i = 0; i < 8; i++) + { + TEST_CHECK(select_u8(i, tab8, 8) == tab8[i]); + } + + for (size_t i = 0; i < 32; i++) + { + TEST_CHECK(select_u32(i, tab32, 32) == tab32[i]); + } +} + +static void test_bitops_incr(void) +{ + uint8_t buf[4]; + +#define CHECK_BE(start, add, end) \ + { \ + write32_be((start), buf); \ + for (size_t i = 0; i < (add); i++) \ + incr_be(buf, sizeof buf); \ + TEST_CHECK(read32_be(buf) == (end)); \ + } + +#define CHECK_LE(start, add, end) \ + { \ + write32_le((start), buf); \ + for (size_t i = 0; i < (add); i++) \ + incr_le(buf, sizeof buf); \ + TEST_CHECK(read32_le(buf) == (end)); \ + } + + CHECK_BE(0, 1, 1); + CHECK_BE(0, 256, 256); + CHECK_BE(256, 256, 512); + CHECK_BE(0xffffffff, 1, 0); + + CHECK_LE(0, 1, 1); + CHECK_LE(0, 256, 256); + CHECK_LE(0x7fffffff, 1, 0x80000000); + CHECK_LE(0xffffffff, 1, 0); + +#undef CHECK_BE +#undef CHECK_LE +} + +static void test_bitops_unaligned(void) +{ + uint8_t in[4], out[4]; + +#define CHECK(outw, len, offs) \ + { \ + memset(out, 0, sizeof out); \ + copy_bytes_unaligned(out, in, len, offs); \ + TEST_CHECK(read32_be(out) == (outw)); \ + } + + write32_be(0x11223344, in); + + CHECK(0x11223344, 4, 0); + CHECK(0x22446600, 3, 1); + CHECK(0x4488cd00, 3, 2); + CHECK(0x89119a00, 3, 3); + CHECK(0x12233400, 3, 4); + CHECK(0x24466800, 3, 5); + CHECK(0x488cd100, 3, 6); + CHECK(0x9119a200, 3, 7); + CHECK(0x22334400, 3, 8); + CHECK(0x44660000, 2, 9); + CHECK(0x33440000, 2, 16); + +#undef CHECK +} + +static void test_expand(const uint8_t *key, size_t nkey, + const uint32_t *answer, size_t roundkeys) +{ + cf_aes_context ctx; + + cf_aes_init(&ctx, key, nkey); + + for (size_t i = 0; i < roundkeys; i++) + { + TEST_CHECK(ctx.ks[i] == answer[i]); + } +} + +static void test_expand_128(void) +{ + /* This is FIPS-197 appendix A.1. */ + const uint8_t key[] = { + 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, + 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c + }; + + const uint32_t answer[] = { + 0x2b7e1516, 0x28aed2a6, 0xabf71588, 0x09cf4f3c, 0xa0fafe17, 0x88542cb1, + 0x23a33939, 0x2a6c7605, 0xf2c295f2, 0x7a96b943, 0x5935807a, 0x7359f67f, + 0x3d80477d, 0x4716fe3e, 0x1e237e44, 0x6d7a883b, 0xef44a541, 0xa8525b7f, + 0xb671253b, 0xdb0bad00, 0xd4d1c6f8, 0x7c839d87, 0xcaf2b8bc, 0x11f915bc, + 0x6d88a37a, 0x110b3efd, 0xdbf98641, 0xca0093fd, 0x4e54f70e, 0x5f5fc9f3, + 0x84a64fb2, 0x4ea6dc4f, 0xead27321, 0xb58dbad2, 0x312bf560, 0x7f8d292f, + 0xac7766f3, 0x19fadc21, 0x28d12941, 0x575c006e, 0xd014f9a8, 0xc9ee2589, + 0xe13f0cc8, 0xb6630ca6 + }; + + test_expand(key, sizeof key, answer, ARRAYCOUNT(answer)); +} + +static void test_expand_192(void) +{ + /* This is FIPS-197 appendix A.2. */ + const uint8_t key[] = { + 0x8e, 0x73, 0xb0, 0xf7, 0xda, 0x0e, 0x64, 0x52, 0xc8, 0x10, 0xf3, 0x2b, + 0x80, 0x90, 0x79, 0xe5, 0x62, 0xf8, 0xea, 0xd2, 0x52, 0x2c, 0x6b, 0x7b + }; + + const uint32_t answer[] = { + 0x8e73b0f7, 0xda0e6452, 0xc810f32b, 0x809079e5, 0x62f8ead2, 0x522c6b7b, + 0xfe0c91f7, 0x2402f5a5, 0xec12068e, 0x6c827f6b, 0x0e7a95b9, 0x5c56fec2, + 0x4db7b4bd, 0x69b54118, 0x85a74796, 0xe92538fd, 0xe75fad44, 0xbb095386, + 0x485af057, 0x21efb14f, 0xa448f6d9, 0x4d6dce24, 0xaa326360, 0x113b30e6, + 0xa25e7ed5, 0x83b1cf9a, 0x27f93943, 0x6a94f767, 0xc0a69407, 0xd19da4e1, + 0xec1786eb, 0x6fa64971, 0x485f7032, 0x22cb8755, 0xe26d1352, 0x33f0b7b3, + 0x40beeb28, 0x2f18a259, 0x6747d26b, 0x458c553e, 0xa7e1466c, 0x9411f1df, + 0x821f750a, 0xad07d753, 0xca400538, 0x8fcc5006, 0x282d166a, 0xbc3ce7b5, + 0xe98ba06f, 0x448c773c, 0x8ecc7204, 0x01002202 + }; + + test_expand(key, sizeof key, answer, ARRAYCOUNT(answer)); +} + +static void test_expand_256(void) +{ + /* And this is A.3. */ + const uint8_t key[] = { + 0x60, 0x3d, 0xeb, 0x10, 0x15, 0xca, 0x71, 0xbe, 0x2b, 0x73, 0xae, 0xf0, + 0x85, 0x7d, 0x77, 0x81, 0x1f, 0x35, 0x2c, 0x07, 0x3b, 0x61, 0x08, 0xd7, + 0x2d, 0x98, 0x10, 0xa3, 0x09, 0x14, 0xdf, 0xf4 + }; + + const uint32_t answer[] = { + 0x603deb10, 0x15ca71be, 0x2b73aef0, 0x857d7781, 0x1f352c07, 0x3b6108d7, + 0x2d9810a3, 0x0914dff4, 0x9ba35411, 0x8e6925af, 0xa51a8b5f, 0x2067fcde, + 0xa8b09c1a, 0x93d194cd, 0xbe49846e, 0xb75d5b9a, 0xd59aecb8, 0x5bf3c917, + 0xfee94248, 0xde8ebe96, 0xb5a9328a, 0x2678a647, 0x98312229, 0x2f6c79b3, + 0x812c81ad, 0xdadf48ba, 0x24360af2, 0xfab8b464, 0x98c5bfc9, 0xbebd198e, + 0x268c3ba7, 0x09e04214, 0x68007bac, 0xb2df3316, 0x96e939e4, 0x6c518d80, + 0xc814e204, 0x76a9fb8a, 0x5025c02d, 0x59c58239, 0xde136967, 0x6ccc5a71, + 0xfa256395, 0x9674ee15, 0x5886ca5d, 0x2e2f31d7, 0x7e0af1fa, 0x27cf73c3, + 0x749c47ab, 0x18501dda, 0xe2757e4f, 0x7401905a, 0xcafaaae3, 0xe4d59b34, + 0x9adf6ace, 0xbd10190d, 0xfe4890d1, 0xe6188d0b, 0x046df344, 0x706c631e + }; + + test_expand(key, sizeof key, answer, ARRAYCOUNT(answer)); +} + +static void vector(const char *input, const char *output, + const char *key) +{ + uint8_t keybuf[32], inbuf[16], outbuf[16], tmp[16]; + size_t nkey = sizeof keybuf; + cf_aes_context ctx; + + nkey = unhex(keybuf, 32, key); + unhex(inbuf, 16, input); + unhex(outbuf, 16, output); + + cf_aes_init(&ctx, keybuf, nkey); + cf_aes_encrypt(&ctx, inbuf, tmp); + TEST_CHECK(memcmp(tmp, outbuf, 16) == 0); + + cf_aes_decrypt(&ctx, outbuf, tmp); + TEST_CHECK(memcmp(tmp, inbuf, 16) == 0); + cf_aes_finish(&ctx); +} + +static void test_vectors(void) +{ + vector("00112233445566778899aabbccddeeff", "69c4e0d86a7b0430d8cdb78070b4c55a", + "000102030405060708090a0b0c0d0e0f"); + vector("00112233445566778899aabbccddeeff", "dda97ca4864cdfe06eaf70a0ec0d7191", + "000102030405060708090a0b0c0d0e0f1011121314151617"); + vector("00112233445566778899aabbccddeeff", "8ea2b7ca516745bfeafc49904b496089", + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f"); +} + +TEST_LIST = { + { "handy-memclean", test_memclean }, + { "bitops-select", test_bitops_select }, + { "bitops-incr", test_bitops_incr }, + { "bitops-unaligned", test_bitops_unaligned }, + { "key-expansion-128", test_expand_128 }, + { "key-expansion-192", test_expand_192 }, + { "key-expansion-256", test_expand_256 }, + { "vectors", test_vectors }, + { 0 } +}; + diff --git a/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/testchacha20poly1305.c b/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/testchacha20poly1305.c new file mode 100644 index 00000000..f1b53e65 --- /dev/null +++ b/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/testchacha20poly1305.c @@ -0,0 +1,91 @@ +/* + * cifra - embedded cryptography library + * Written in 2014 by Joseph Birr-Pixton + * + * To the extent possible under law, the author(s) have dedicated all + * copyright and related and neighboring rights to this software to the + * public domain worldwide. This software is distributed without any + * warranty. + * + * You should have received a copy of the CC0 Public Domain Dedication + * along with this software. If not, see + * . + */ + +#include "chacha20poly1305.h" +#include "handy.h" +#include "cutest.h" +#include "testutil.h" + +static void vector(const char *keystr, + const char *noncestr, + const char *headerstr, + const char *plainstr, + const char *cipherstr, + const char *tagstr) +{ + /* inputs */ + uint8_t K[32], N[12], H[12], A[16]; + uint8_t C[265], P[265]; + + unhex(K, sizeof K, keystr); + unhex(N, sizeof N, noncestr); + size_t headerlen = unhex(H, sizeof H, headerstr); + size_t plainlen = unhex(P, sizeof P, plainstr); + size_t cipherlen = unhex(C, sizeof C, cipherstr); + unhex(A, sizeof A, tagstr); + + assert(cipherlen == plainlen); + + /* working data */ + uint8_t out[265], ourtag[16]; + + /* check encryption works. */ + cf_chacha20poly1305_encrypt(K, N, + H, headerlen, + P, plainlen, + out, ourtag); + + TEST_CHECK(memcmp(out, C, cipherlen) == 0); + TEST_CHECK(memcmp(ourtag, A, sizeof A) == 0); + + /* proper decryption */ + TEST_CHECK(0 == cf_chacha20poly1305_decrypt(K, N, + H, headerlen, + C, cipherlen, + A, out)); + TEST_CHECK(0 == memcmp(out, P, plainlen)); + + /* failure decryption */ + C[0] ^= 0xff; + + TEST_CHECK(1 == cf_chacha20poly1305_decrypt(K, N, + H, headerlen, + C, cipherlen, + A, out)); +} + +static void test_vectors(void) +{ + /* Test vector from section 2.8.2. */ + vector("808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f", + "070000004041424344454647", + "50515253c0c1c2c3c4c5c6c7", + "4c616469657320616e642047656e746c656d656e206f662074686520636c617373206f66202739393a204966204920636f756c64206f6666657220796f75206f6e6c79206f6e652074697020666f7220746865206675747572652c2073756e73637265656e20776f756c642062652069742e", + "d31a8d34648e60db7b86afbc53ef7ec2a4aded51296e08fea9e2b5a736ee62d63dbea45e8ca9671282fafb69da92728b1a71de0a9e060b2905d6a5b67ecd3b3692ddbd7f2d778b8c9803aee328091b58fab324e4fad675945585808b4831d7bc3ff4def08e4b7a9de576d26586cec64b6116", + "1ae10b594f09e26a7e902ecbd0600691"); + + /* Test vector from A.5. */ + vector("1c9240a5eb55d38af333888604f6b5f0473917c1402b80099dca5cbc207075c0", + "000000000102030405060708", + "f33388860000000000004e91", + "496e7465726e65742d4472616674732061726520647261667420646f63756d656e74732076616c696420666f722061206d6178696d756d206f6620736978206d6f6e74687320616e64206d617920626520757064617465642c207265706c616365642c206f72206f62736f6c65746564206279206f7468657220646f63756d656e747320617420616e792074696d652e20497420697320696e617070726f70726961746520746f2075736520496e7465726e65742d447261667473206173207265666572656e6365206d6174657269616c206f7220746f2063697465207468656d206f74686572207468616e206173202fe2809c776f726b20696e2070726f67726573732e2fe2809d", + "64a0861575861af460f062c79be643bd5e805cfd345cf389f108670ac76c8cb24c6cfc18755d43eea09ee94e382d26b0bdb7b73c321b0100d4f03b7f355894cf332f830e710b97ce98c8a84abd0b948114ad176e008d33bd60f982b1ff37c8559797a06ef4f0ef61c186324e2b3506383606907b6a7c02b0f9f6157b53c867e4b9166c767b804d46a59b5216cde7a4e99040c5a40433225ee282a1b0a06c523eaf4534d7f83fa1155b0047718cbc546a0d072b04b3564eea1b422273f548271a0bb2316053fa76991955ebd63159434ecebb4e466dae5a1073a6727627097a1049e617d91d361094fa68f0ff77987130305beaba2eda04df997b714d6c6f2c29a6ad5cb4022b02709b", + "eead9d67890cbb22392336fea1851f38"); +} + +TEST_LIST = { + { "vectors", test_vectors }, + { 0 } +}; + diff --git a/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/testcurve25519.c b/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/testcurve25519.c new file mode 100644 index 00000000..a0ab8db5 --- /dev/null +++ b/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/testcurve25519.c @@ -0,0 +1,56 @@ +/* + * cifra - embedded cryptography library + * Written in 2014 by Joseph Birr-Pixton + * + * To the extent possible under law, the author(s) have dedicated all + * copyright and related and neighboring rights to this software to the + * public domain worldwide. This software is distributed without any + * warranty. + * + * You should have received a copy of the CC0 Public Domain Dedication + * along with this software. If not, see + * . + */ + +#include "curve25519.h" +#include "handy.h" +#include "cutest.h" +#include "testutil.h" + +static void test_base_mul(void) +{ + uint8_t secret[32]; + uint8_t public[32]; + uint8_t expect[32]; + + unhex(secret, 32, "77076d0a7318a57d3c16c17251b26645df4c2f87ebc0992ab177fba51db92c2a"); + unhex(expect, 32, "8520f0098930a754748b7ddcb43ef75a0dbf3a0d26381af4eba4a98eaa9b4e6a"); + cf_curve25519_mul_base(public, secret); + TEST_CHECK(memcmp(expect, public, 32) == 0); + + unhex(secret, 32, "5dab087e624a8a4b79e17f8b83800ee66f3bb1292618b6fd1c2f8b27ff88e0eb"); + unhex(expect, 32, "de9edb7d7b7dc1b4d35b61c2ece435373f8343c85b78674dadfc7e146f882b4f"); + cf_curve25519_mul_base(public, secret); + TEST_CHECK(memcmp(expect, public, 32) == 0); +} + +static void test_mul(void) +{ + uint8_t scalar[32]; + uint8_t public[32]; + uint8_t shared[32]; + uint8_t expect[32]; + + unhex(scalar, 32, "77076d0a7318a57d3c16c17251b26645df4c2f87ebc0992ab177fba51db92c2a"); + unhex(public, 32, "de9edb7d7b7dc1b4d35b61c2ece435373f8343c85b78674dadfc7e146f882b4f"); + unhex(expect, 32, "4a5d9d5ba4ce2de1728e3bf480350f25e07e21c947d19e3376f09b3c1e161742"); + cf_curve25519_mul(shared, scalar, public); + TEST_CHECK(memcmp(expect, shared, 32) == 0); +} + +TEST_LIST = { + { "base-mul", test_base_mul }, + { "mul", test_mul }, + { 0 } +}; + diff --git a/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/testdrbg.c b/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/testdrbg.c new file mode 100644 index 00000000..253c8c0a --- /dev/null +++ b/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/testdrbg.c @@ -0,0 +1,206 @@ +/* + * cifra - embedded cryptography library + * Written in 2016 by Joseph Birr-Pixton + * + * To the extent possible under law, the author(s) have dedicated all + * copyright and related and neighboring rights to this software to the + * public domain worldwide. This software is distributed without any + * warranty. + * + * You should have received a copy of the CC0 Public Domain Dedication + * along with this software. If not, see + * . + */ + +#include "drbg.h" +#include "sha1.h" +#include "sha2.h" + +#include "handy.h" +#include "cutest.h" +#include "testutil.h" + +static void test_hashdrbg_sha256_vector(void) +{ + uint8_t entropy[32], nonce[16], persn[32], reseed[32], got[128], expect[128]; + + /* This is the first KAT from NIST's CAVP example + * file for SHA-256 with all inputs used; line 4360. */ + unhex(entropy, sizeof entropy, "b87bb4de5c148d964fc0cb612d69295671780b4270fe32bf389b6f49488efe13"); + unhex(nonce, sizeof nonce, "27eb37a0c695c4ee3c9b70b7f6b33492"); + unhex(persn, sizeof persn, "52321406ac8a9c266b1f8d811bb871269e5824b59a0234f01d358193523bbb7c"); + unhex(reseed, sizeof reseed, "7638267f534c4e6ee22cc6ca6ed824fd5d3d387c00b89dd791eb5ac9766385b8"); + + unhex(expect, sizeof expect, "de01c061651bab3cef2fc4ea89a56b6e86e74b2e9fd11ed671c97c813778a06a2c1f41b41e754a5257750c6bde9601da9d67d8d9564f4a8538b92516a2dacc496dee257b85393f2a01ad59aa3257f1b6da9566e3706d2d6d4a26e511b0c64d7dc223acb24827178afa43ca8d5a66f983d6929dc61564c4c14fc32d85765a23f7"); + + cf_hash_drbg_sha256 ctx; + cf_hash_drbg_sha256_init(&ctx, entropy, sizeof entropy, nonce, sizeof nonce, persn, sizeof persn); + cf_hash_drbg_sha256_reseed(&ctx, reseed, sizeof reseed, NULL, 0); + cf_hash_drbg_sha256_gen(&ctx, got, sizeof got); + cf_hash_drbg_sha256_gen(&ctx, got, sizeof got); + TEST_CHECK(memcmp(got, expect, sizeof got) == 0); + + /* This is line 5064 from Hash_DRBG.rsp */ + unhex(entropy, sizeof entropy, "63363377e41e86468deb0ab4a8ed683f6a134e47e014c700454e81e95358a569"); + unhex(nonce, sizeof nonce, "808aa38f2a72a62359915a9f8a04ca68"); + /* no persn */ + unhex(reseed, sizeof reseed, "e62b8a8ee8f141b6980566e3bfe3c04903dad4ac2cdf9f2280010a6739bc83d3"); + unhex(expect, sizeof expect, "04eec63bb231df2c630a1afbe724949d005a587851e1aa795e477347c8b056621c18bddcdd8d99fc5fc2b92053d8cfacfb0bb8831205fad1ddd6c071318a6018f03b73f5ede4d4d071f9de03fd7aea105d9299b8af99aa075bdb4db9aa28c18d174b56ee2a014d098896ff2282c955a81969e069fa8ce007a180183a07dfae17"); + + cf_hash_drbg_sha256_init(&ctx, entropy, sizeof entropy, nonce, sizeof nonce, NULL, 0); + cf_hash_drbg_sha256_reseed(&ctx, reseed, sizeof reseed, NULL, 0); + cf_hash_drbg_sha256_gen(&ctx, got, sizeof got); + cf_hash_drbg_sha256_gen(&ctx, got, sizeof got); + TEST_CHECK(memcmp(got, expect, sizeof got) == 0); +} + +static void test_hashdrbg_sha256_vector_addnl(void) +{ + uint8_t entropy[32], nonce[16], reseed[32], got[128], expect[128], addnl[32]; + + /* Hash_DRBG.rsp, line 5230. No personlisation string, but with additional data. */ + unhex(entropy, sizeof entropy, "9cfb7ad03be487a3b42be06e9ae44f283c2b1458cec801da2ae6532fcb56cc4c"); + unhex(nonce, sizeof nonce, "a20765538e8db31295747ec922c13a69"); + unhex(reseed, sizeof reseed, "96bc8014f90ebdf690db0e171b59cc46c75e2e9b8e1dc699c65c03ceb2f4d7dc"); + unhex(expect, sizeof expect, "71c1154a2a7a3552413970bf698aa02f14f8ea95e861f801f463be27868b1b14b1b4babd9eba5915a6414ab1104c8979b1918f3094925aeab0d07d2037e613b63cbd4f79d9f95c84b47ed9b77230a57515c211f48f4af6f5edb2c308b33905db308cf88f552c8912c49b34e66c026e67b302ca65b187928a1aba9a49edbfe190"); + + cf_hash_drbg_sha256 ctx; + cf_hash_drbg_sha256_init(&ctx, entropy, sizeof entropy, nonce, sizeof nonce, NULL, 0); + unhex(addnl, sizeof addnl, "6fea0894052dab3c44d503950c7c72bd7b87de87cb81d3bb51c32a62f742286d"); + cf_hash_drbg_sha256_reseed(&ctx, reseed, sizeof reseed, addnl, sizeof addnl); + unhex(addnl, sizeof addnl, "d3467c78563b74c13db7af36c2a964820f2a9b1b167474906508fdac9b2049a6"); + cf_hash_drbg_sha256_gen_additional(&ctx, addnl, sizeof addnl, got, sizeof got); + unhex(addnl, sizeof addnl, "5840a11cc9ebf77b963854726a826370ffdb2fc2b3d8479e1df5dcfa3dddd10b"); + cf_hash_drbg_sha256_gen_additional(&ctx, addnl, sizeof addnl, got, sizeof got); + TEST_CHECK(memcmp(got, expect, sizeof got) == 0); +} + +static void test_hmacdrbg_sha1_vector(void) +{ + uint8_t entropy[16], nonce[8], reseed[16], got[80], expect[80]; + + /* HMAC_DRBG.rsp, line 8. */ + unhex(entropy, sizeof entropy, "79349bbf7cdda5799557866621c91383"); + unhex(nonce, sizeof nonce, "1146733abf8c35c8"); + unhex(reseed, sizeof reseed, "c7215b5b96c48e9b338c74e3e99dfedf"); + unhex(expect, sizeof expect, "c6a16ab8d420706f0f34ab7fec5adca9d8ca3a133e159ca6ac43c6f8a2be22834a4c0a0affb10d7194f1c1a5cf7322ec1ae0964ed4bf122746e087fdb5b3e91b3493d5bb98faed49e85f130fc8a459b7"); + + cf_hmac_drbg ctx; + cf_hmac_drbg_init(&ctx, &cf_sha1, entropy, sizeof entropy, nonce, sizeof nonce, NULL, 0); + cf_hmac_drbg_reseed(&ctx, reseed, sizeof reseed, NULL, 0); + cf_hmac_drbg_gen(&ctx, got, sizeof got); + cf_hmac_drbg_gen(&ctx, got, sizeof got); + TEST_CHECK(memcmp(got, expect, sizeof got) == 0); +} + +static void test_hmacdrbg_sha1_vector_addnl(void) +{ + uint8_t entropy[16], nonce[8], reseed[16], got[80], expect[80], addnl[16]; + + /* HMAC_DRBG.rsp, line 174. */ + unhex(entropy, sizeof entropy, "7d7052a776fd2fb3d7191f733304ee8b"); + unhex(nonce, sizeof nonce, "be4a0ceedca80207"); + unhex(reseed, sizeof reseed, "49047e879d610955eed916e4060e00c9"); + unhex(expect, sizeof expect, "a736343844fc92511391db0addd9064dbee24c8976aa259a9e3b6368aa6de4c9bf3a0effcda9cb0e9dc33652ab58ecb7650ed80467f76a849fb1cfc1ed0a09f7155086064db324b1e124f3fc9e614fcb"); + + cf_hmac_drbg ctx; + cf_hmac_drbg_init(&ctx, &cf_sha1, entropy, sizeof entropy, nonce, sizeof nonce, NULL, 0); + unhex(addnl, sizeof addnl, "fd8bb33aab2f6cdfbc541811861d518d"); + cf_hmac_drbg_reseed(&ctx, reseed, sizeof reseed, addnl, sizeof addnl); + unhex(addnl, sizeof addnl, "99afe347540461ddf6abeb491e0715b4"); + cf_hmac_drbg_gen_additional(&ctx, addnl, sizeof addnl, got, sizeof got); + unhex(addnl, sizeof addnl, "02f773482dd7ae66f76e381598a64ef0"); + cf_hmac_drbg_gen_additional(&ctx, addnl, sizeof addnl, got, sizeof got); + TEST_CHECK(memcmp(got, expect, sizeof got) == 0); +} + +static void test_hmacdrbg_sha256_vector(void) +{ + uint8_t entropy[32], nonce[16], reseed[32], got[128], expect[128]; + + /* HMAC_DRBG.rsp, line 5064. */ + unhex(entropy, sizeof entropy, "06032cd5eed33f39265f49ecb142c511da9aff2af71203bffaf34a9ca5bd9c0d"); + unhex(nonce, sizeof nonce, "0e66f71edc43e42a45ad3c6fc6cdc4df"); + unhex(reseed, sizeof reseed, "01920a4e669ed3a85ae8a33b35a74ad7fb2a6bb4cf395ce00334a9c9a5a5d552"); + unhex(expect, sizeof expect, "76fc79fe9b50beccc991a11b5635783a83536add03c157fb30645e611c2898bb2b1bc215000209208cd506cb28da2a51bdb03826aaf2bd2335d576d519160842e7158ad0949d1a9ec3e66ea1b1a064b005de914eac2e9d4f2d72a8616a80225422918250ff66a41bd2f864a6a38cc5b6499dc43f7f2bd09e1e0f8f5885935124"); + + cf_hmac_drbg ctx; + cf_hmac_drbg_init(&ctx, &cf_sha256, entropy, sizeof entropy, nonce, sizeof nonce, NULL, 0); + cf_hmac_drbg_reseed(&ctx, reseed, sizeof reseed, NULL, 0); + cf_hmac_drbg_gen(&ctx, got, sizeof got); + cf_hmac_drbg_gen(&ctx, got, sizeof got); + TEST_CHECK(memcmp(got, expect, sizeof got) == 0); +} + +static void test_hmacdrbg_sha256_vector_addnl(void) +{ + uint8_t entropy[32], nonce[16], reseed[32], got[128], expect[128], addnl[32]; + + /* HMAC_DRBG.rsp, line 5230. */ + unhex(entropy, sizeof entropy, "05ac9fc4c62a02e3f90840da5616218c6de5743d66b8e0fbf833759c5928b53d"); + unhex(nonce, sizeof nonce, "2b89a17904922ed8f017a63044848545"); + unhex(reseed, sizeof reseed, "2791126b8b52ee1fd9392a0a13e0083bed4186dc649b739607ac70ec8dcecf9b"); + unhex(expect, sizeof expect, "02ddff5173da2fcffa10215b030d660d61179e61ecc22609b1151a75f1cbcbb4363c3a89299b4b63aca5e581e73c860491010aa35de3337cc6c09ebec8c91a6287586f3a74d9694b462d2720ea2e11bbd02af33adefb4a16e6b370fa0effd57d607547bdcfbb7831f54de7073ad2a7da987a0016a82fa958779a168674b56524"); + + cf_hmac_drbg ctx; + cf_hmac_drbg_init(&ctx, &cf_sha256, entropy, sizeof entropy, nonce, sizeof nonce, NULL, 0); + unhex(addnl, sizeof addnl, "43bac13bae715092cf7eb280a2e10a962faf7233c41412f69bc74a35a584e54c"); + cf_hmac_drbg_reseed(&ctx, reseed, sizeof reseed, addnl, sizeof addnl); + unhex(addnl, sizeof addnl, "3f2fed4b68d506ecefa21f3f5bb907beb0f17dbc30f6ffbba5e5861408c53a1e"); + cf_hmac_drbg_gen_additional(&ctx, addnl, sizeof addnl, got, sizeof got); + unhex(addnl, sizeof addnl, "529030df50f410985fde068df82b935ec23d839cb4b269414c0ede6cffea5b68"); + cf_hmac_drbg_gen_additional(&ctx, addnl, sizeof addnl, got, sizeof got); + TEST_CHECK(memcmp(got, expect, sizeof got) == 0); +} + +static void test_hmacdrbg_sha512_vector(void) +{ + uint8_t entropy[32], nonce[16], reseed[32], got[256], expect[256]; + + /* HMAC_DRBG.rsp, line 10120. */ + unhex(entropy, sizeof entropy, "48c121b18733af15c27e1dd9ba66a9a81a5579cdba0f5b657ec53c2b9e90bbf6"); + unhex(nonce, sizeof nonce, "bbb7c777428068fad9970891f879b1af"); + unhex(reseed, sizeof reseed, "e0ffefdadb9ccf990504d568bdb4d862cbe17ccce6e22dfcab8b4804fd21421a"); + unhex(expect, sizeof expect, "05da6aac7d980da038f65f392841476d37fe70fbd3e369d1f80196e66e54b8fadb1d60e1a0f3d4dc173769d75fc3410549d7a843270a54a068b4fe767d7d9a59604510a875ad1e9731c8afd0fd50b825e2c50d062576175106a9981be37e02ec7c5cd0a69aa0ca65bddaee1b0de532e10cfa1f5bf6a026e47379736a099d6750ab121dbe3622b841baf8bdcbe875c85ba4b586b8b5b57b0fecbec08c12ff2a9453c47c6e32a52103d972c62ab9affb8e728a31fcefbbccc556c0f0a35f4b10ace2d96b906e36cbb72233201e536d3e13b045187b417d2449cad1edd192e061f12d22147b0a176ea8d9c4c35404395b6502ef333a813b6586037479e0fa3c6a23"); + + cf_hmac_drbg ctx; + cf_hmac_drbg_init(&ctx, &cf_sha512, entropy, sizeof entropy, nonce, sizeof nonce, NULL, 0); + cf_hmac_drbg_reseed(&ctx, reseed, sizeof reseed, NULL, 0); + cf_hmac_drbg_gen(&ctx, got, sizeof got); + cf_hmac_drbg_gen(&ctx, got, sizeof got); + TEST_CHECK(memcmp(got, expect, sizeof got) == 0); +} + +static void test_hmacdrbg_sha512_vector_addnl(void) +{ + uint8_t entropy[32], nonce[16], reseed[32], got[256], expect[256], addnl[32]; + + /* HMAC_DRBG.rsp, line 10286. */ + unhex(entropy, sizeof entropy, "4686a959e17dfb96c294b09c0f7a60efb386416cfb4c8972bcc55e44a151607a"); + unhex(nonce, sizeof nonce, "5226543b4c89321bbfb0f11f18ee3462"); + unhex(reseed, sizeof reseed, "5ef50daaf29929047870235c17762f5df5d9ab1af656e0e215fcc6fd9fc0d85d"); + unhex(expect, sizeof expect, "b60d8803531b2b8583d17bdf3ac7c01f3c65cf9b069862b2d39b9024b34c172b712db0704acb078a1ab1aec0390dbaee2dec9be7b234e63da481fd469a92c77bc7bb2cfca586855520e0f9e9d47dcb9bdf2a2fdfa9f2b4342ef0ea582616b55477717cfd516d46d6383257743656f7cf8b38402ba795a8c9d35a4aa88bec623313dad6ead689d152b54074f183b2fee556f554db343626cea853718f18d386bc8bebb0c07b3c5e96ceb391ffceece88864dbd3be83a613562c5c417a24807d5f9332974f045e79a9ade36994af6cf9bbeeb71d0025fcb4ad50f121cbc2df7cd12ff5a50cddfd9a4bbc6d942d743c8b8fbebe00eeccea3d14e07ff8454fa715da"); + + cf_hmac_drbg ctx; + cf_hmac_drbg_init(&ctx, &cf_sha512, entropy, sizeof entropy, nonce, sizeof nonce, NULL, 0); + unhex(addnl, sizeof addnl, "d2383c3e528492269e6c3b3aaa2b54fbf48731f5aa52150ce7fc644679a5e7c6"); + cf_hmac_drbg_reseed(&ctx, reseed, sizeof reseed, addnl, sizeof addnl); + unhex(addnl, sizeof addnl, "c841e7a2d9d13bdb8644cd7f5d91d241a369e12dc6c9c2be50d1ed29484bff98"); + cf_hmac_drbg_gen_additional(&ctx, addnl, sizeof addnl, got, sizeof got); + unhex(addnl, sizeof addnl, "9054cf9216af66a788d3bf6757b8987e42d4e49b325e728dc645d5e107048245"); + cf_hmac_drbg_gen_additional(&ctx, addnl, sizeof addnl, got, sizeof got); + TEST_CHECK(memcmp(got, expect, sizeof got) == 0); +} + +TEST_LIST = { + { "hashdrbg-sha256", test_hashdrbg_sha256_vector }, + { "hashdrbg-sha256-addnl", test_hashdrbg_sha256_vector_addnl }, + { "hmacdrbg-sha1", test_hmacdrbg_sha1_vector }, + { "hmacdrbg-sha1-addnl", test_hmacdrbg_sha1_vector_addnl }, + { "hmacdrbg-sha256", test_hmacdrbg_sha256_vector }, + { "hmacdrbg-sha256-addnl", test_hmacdrbg_sha256_vector_addnl }, + { "hmacdrbg-sha512", test_hmacdrbg_sha512_vector }, + { "hmacdrbg-sha512-addnl", test_hmacdrbg_sha512_vector_addnl }, + { 0 } +}; + diff --git a/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/testmodes.c b/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/testmodes.c new file mode 100644 index 00000000..ed96dde8 --- /dev/null +++ b/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/testmodes.c @@ -0,0 +1,890 @@ +/* + * cifra - embedded cryptography library + * Written in 2014 by Joseph Birr-Pixton + * + * To the extent possible under law, the author(s) have dedicated all + * copyright and related and neighboring rights to this software to the + * public domain worldwide. This software is distributed without any + * warranty. + * + * You should have received a copy of the CC0 Public Domain Dedication + * along with this software. If not, see + * . + */ + +#include "aes.h" +#include "modes.h" +#include "bitops.h" +#include "gf128.h" + +#include "handy.h" +#include "cutest.h" +#include "testutil.h" + +/* Some tests are too big for microcontrollers. */ +#if defined(CORTEX_M0) || defined(CORTEX_M3) || defined(CORTEX_M4) +# define MCU_TARGET 1 +#else +# define MCU_TARGET 0 +#endif + +static void test_cbc(void) +{ + uint8_t out[16]; + + const void *iv = "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"; + const void *key = "\x2b\x7e\x15\x16\x28\xae\xd2\xa6\xab\xf7\x15\x88\x09\xcf\x4f\x3c"; + const void *inp = "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96\xe9\x3d\x7e\x11\x73\x93\x17\x2a"; + const void *expect = "\x76\x49\xab\xac\x81\x19\xb2\x46\xce\xe9\x8e\x9b\x12\xe9\x19\x7d"; + + cf_aes_context aes; + cf_aes_init(&aes, key, 16); + + cf_cbc cbc; + cf_cbc_init(&cbc, &cf_aes, &aes, iv); + cf_cbc_encrypt(&cbc, inp, out, 1); + TEST_CHECK(memcmp(out, expect, 16) == 0); + + uint8_t decrypt[16]; + cf_cbc_init(&cbc, &cf_aes, &aes, iv); + cf_cbc_decrypt(&cbc, out, decrypt, 1); + TEST_CHECK(memcmp(decrypt, inp, 16) == 0); +} + +static void cbcmac_vector(const void *tag_expect, size_t ntag, + const void *key, size_t nkey, + const void *msg, size_t nmsg) +{ + uint8_t tag[16]; + + cf_aes_context aes; + cf_aes_init(&aes, key, nkey); + + cf_cbcmac_stream cm; + cf_cbcmac_stream_init(&cm, &cf_aes, &aes); + cf_cbcmac_stream_update(&cm, msg, nmsg); + cf_cbcmac_stream_pad_final(&cm, tag); + + TEST_CHECK(sizeof tag == ntag); + TEST_CHECK(memcmp(tag, tag_expect, sizeof tag) == 0); +} + +static void test_cbcmac(void) +{ + cbcmac_vector("\xf0\xf1\x89\x75\xa0\x85\x9d\x13\xa4\x9d\x3d\xbf\xc6\xcd\x65\xd9", 16, "\x04\xf7\xf7\x78\x62\x1d\x1e\x2c\x86\x47\x82\x2a\x50\xd9\x8a\x83", 16, "\x83\x1b\xe7\x4b\x9b\xe6\x85\xc8\x38\xe2\x2a\x25\xa3\x11\xcb\x14\x79\x62\x35\xf5\x28\x98\xd0", 23); + cbcmac_vector("\x0d\x6a\x13\x8f\x75\xb7\x56\x94\xd5\x15\xc5\x55\x5e\xee\xdd\x92", 16, "\xff\x84\x5a\xfc\x51\xf2\x06\x35\xa4\x8f\x6c\xec\x9f\x78\x1f\x2e", 16, "\xc5\x85\x3e\x6b\x3f\x7e\xf5\x10\x93\x6e\x30\xd5\x54\x13\x5f\x0d\x55\x43\x92\x8c\x53\xfc\x2f\x81\xa3", 25); + cbcmac_vector("\x96\x81\x3d\xb1\x7e\xac\x06\xb9\x79\x42\xa7\x3a\x7c\x5a\x0a\xad", 16, "\x10\x77\x16\x47\x23\x2e\xda\x40\x23\xd7\xc5\xc9\xbb\x51\x2e\x93", 16, "\x06\x53\x5f\x70\xd9\x6c\x80\x50\x85\x6b\x02\x4f\x67\xae\x87\xde\xc8\xd2\x9d\xab\xb7\x1f\x55\x93\x51\x00\x0a\x3c\x8f\xfc\x63\x60", 32); + cbcmac_vector("\x20\xdd\xa5\xb1\xc1\x14\x00\x90\x97\x41\xef\x3b\xc6\xac\xe8\xec", 16, "\x5b\x39\xdb\x4b\xa4\x53\x1f\x97\xf9\xca\x4b\xdd\xed\x9b\x28\x53", 16, "\x49\x91\xb3\x35\x40\xda\x4d\x8a\xdf\xe9\x37\x4b\xb4\xe1\xc5", 15); + cbcmac_vector("\xc0\x2f\x8f\x0a\xba\x13\x4b\x6b\x16\x69\xfb\x58\x2f\xc1\xc8\x76", 16, "\xd0\x22\xc7\xe7\x85\xd2\xfc\xa4\xd6\x7f\xaa\x18\xb1\xa9\xfd\x9d\x7a\x47\x37\x09\x33\x43\x06\x32", 24, "\x2b\xa2\x8e\xa5\x62\xdd\x9c\x5e\x80\xcc\xaf\x80\x16\x77", 14); + cbcmac_vector("\x05\x79\x4b\x5f\xc8\xf2\xee\x87\x74\xcd\x88\x9f\x7c\x29\xeb\xa0", 16, "\xe4\x51\xdb\x26\x8e\x2a\x26\xd1\xbf\x78\x3e\xab\x5d\xc6\xf9\x3f\xb2\xc5\xe2\x5c\xe8\x61\x28\x3c", 24, "\xea\x14\xfa\xaa\x95\x48\x12\xcb", 8); + cbcmac_vector("\x6a\x14\x4b\xaa\x39\xf6\x19\x71\x62\x65\xd3\x4e\x53\xb4\xc6\x7c", 16, "\xff\x46\x38\x0f\x62\xa9\x37\x7f\xb2\x41\x88\x44\x39\x2a\x97\xf5\xb9\x9a\xc0\x37\xf9\xc6\x75\x3f", 24, "\x64\x04\x53\x4c\xa8\x0a\x60\xf6\x5e\x22\xb6\xc4\xd7\xf3\xa9\x33\xf9\x3e", 18); + cbcmac_vector("\xf7\x1d\x16\x5c\xba\xac\x0f\xf0\x1a\x12\x75\xf8\x5b\x6a\x8e\x15", 16, "\x67\xce\x47\x6c\x11\x0e\xa1\xbc\xf0\x81\x30\x2b\x5f\xe2\x3b\xbc\x34\xc5\x4d\x46\x01\xed\x49\x04", 24, "\x94\xb1\x25\x63\x49\x49\x46\x7e\x7a\xa0\x0e\xa1\x10\x25\x21\x9a\xc9\x1f\x0d\xed\xa1\x10\x30\x7e\x08\x84\xee\x09\xe8\x31\x53\x81", 32); + cbcmac_vector("\x22\xfb\x7e\x4c\x77\x12\x7c\xed\x2c\xaa\xf9\x8d\x9f\x35\x15\x60", 16, "\x1c\x50\xc0\x79\x7c\xd6\x7f\x89\x26\xd1\xc9\xb9\x85\xf9\xee\xaf\x18\x3f\x07\x0b\x3a\xd2\x5f\x7e\xfa\x08\x95\xfe\x98\xe3\x43\x91", 32, "\x7d\x1e\x7e\x19\x9a\xd4\xf4\x3f\xcf\xff\x55\xf7\xc9\x81\xe6\x13\xc0\x22\xab\x7f\x83\x92\x21\x72\x65\x79\x78\xcd\xf0\x8b\x36", 31); + cbcmac_vector("\x40\xc1\xef\xf3\xf4\x71\x54\x58\x77\x3c\xd3\x07\x96\xdf\xfd\x54", 16, "\x3c\x1e\xae\xa7\x4a\xf6\xee\x43\x9b\xd7\xa3\x76\x38\xd6\x08\x21\x60\xe6\x1b\x23\x2b\xf8\xa4\x5d\x05\xd5\xf4\x89\x04\x3e\x2d\x19", 32, "\xd2\xa3\x38\x1a\x82\xd6\xb6\xc2\x52\x93\x43\x1d\xdc\x1d\x73\xb5\x14\x82\x40\xfe\x00\xc3\x24\x52\x8d\x69\xc6\x11\x4e\x4c\xa9\x40\xcd\xfb\x29\x17", 36); + cbcmac_vector("\x69\x7c\x65\x95\xa2\x1f\xa2\xfa\x3a\xd3\x60\x68\x7a\xed\x68\x37", 16, "\xc2\xda\x01\xb4\x12\xa5\xcd\x1c\x75\xb5\x08\x5f\xd2\xee\x79\xc3\x47\xd9\xf9\x12\x86\x3d\x81\xd0\x42\x89\x75\x96\x58\x70\x47\x05", 32, "\x65\x22\x9b\x77\x15\xe5\x02\x54\x04\x90\xfb\xe2\xbf\x5a\x8e\xb0\xbf\x64\xff\x7f\xb7\xab\x7f\x18\x69\x7b", 26); + cbcmac_vector("\xf5\x2d\x65\x16\x84\x43\x0d\xe8\x1f\x29\x51\x06\xec\xf0\xa5\xd2", 16, "\x76\xff\xb3\x38\x5b\xca\x7c\x93\xc0\x12\xd7\xbc\xb3\xa3\xd0\xf2\x87\xa7\x0a\x91\x36\x76\xa7\x8d\x28\x47\x05\x8e\x75\xae\x5e\x3c", 32, "\x12\x90\x91\x65\x32\x37\xd0\x35\xf6\x40\x42\xa7\x4f\x61\xa9\x9c\x8f\xd6\x84\x9a\x86\x0e\x57\xe7\xe4", 25); +} + +static void test_ctr(void) +{ + uint8_t out[16]; + + const void *nonce = "\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff"; + const void *key = "\x2b\x7e\x15\x16\x28\xae\xd2\xa6\xab\xf7\x15\x88\x09\xcf\x4f\x3c"; + const void *inp = "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96\xe9\x3d\x7e\x11\x73\x93\x17\x2a"; + const void *expect = "\x87\x4d\x61\x91\xb6\x20\xe3\x26\x1b\xef\x68\x64\x99\x0d\xb6\xce"; + + cf_aes_context aes; + cf_aes_init(&aes, key, 16); + + cf_ctr ctr; + cf_ctr_init(&ctr, &cf_aes, &aes, nonce); + cf_ctr_cipher(&ctr, inp, out, 16); /* one piece */ + TEST_CHECK(memcmp(expect, out, 16) == 0); + + cf_ctr_init(&ctr, &cf_aes, &aes, nonce); + cf_ctr_cipher(&ctr, inp, out, 1); /* incremental (2 blocks) */ + cf_ctr_cipher(&ctr, inp, out, 16); + cf_ctr_cipher(&ctr, inp, out, 16); + + cf_ctr_init(&ctr, &cf_aes, &aes, nonce); + cf_ctr_cipher(&ctr, inp, out, 1); /* incremental */ + cf_ctr_cipher(&ctr, ((uint8_t *)inp) + 1, out + 1, 15); + TEST_CHECK(memcmp(expect, out, 16) == 0); + + uint8_t decrypt[16]; + cf_ctr_init(&ctr, &cf_aes, &aes, nonce); + cf_ctr_cipher(&ctr, out, decrypt, 16); + TEST_CHECK(memcmp(decrypt, inp, 16) == 0); + + /* Test we use the right number of blocks up. */ + uint8_t test_nonce[16], test_inp[16]; + memset(test_nonce, 0xff, 16); + memset(test_inp, 0x00, 16); + cf_ctr_init(&ctr, &cf_aes, &aes, test_nonce); + + /* Exercise cf_blockwise_xor code paths. */ + for (int i = 0; i < 1024; i++) + { + cf_ctr_cipher(&ctr, test_inp, out, i % 16); + } + + /* expected counter value is 1024 * 7.5 / 16 - 1: + * 479 = 0x1df + */ + + memset(test_nonce, 0, sizeof test_nonce); + test_nonce[15] = 0xdf; + test_nonce[14] = 0x01; + + TEST_CHECK(memcmp(test_nonce, ctr.nonce, 16) == 0); +} + +static void check_eax(const void *key, size_t nkey, + const void *msg, size_t nmsg, + const void *nonce, size_t nnonce, + const void *header, size_t nheader, + const void *expect_cipher, + const void *expect_tag, size_t ntag) +{ + uint8_t cipher[32]; + uint8_t tag[16]; + + assert(nmsg <= sizeof cipher); + assert(ntag <= ntag); + + cf_aes_context aes; + cf_aes_init(&aes, key, nkey); + + cf_eax_encrypt(&cf_aes, &aes, + msg, nmsg, + header, nheader, + nonce, nnonce, + cipher, + tag, ntag); + + TEST_CHECK(memcmp(expect_cipher, cipher, nmsg) == 0); + TEST_CHECK(memcmp(expect_tag, tag, ntag) == 0); + + int rc; + uint8_t tmp[sizeof cipher]; + rc = cf_eax_decrypt(&cf_aes, &aes, + cipher, nmsg, + header, nheader, + nonce, nnonce, + tag, ntag, + tmp); + TEST_CHECK(rc == 0); + TEST_CHECK(memcmp(tmp, msg, nmsg) == 0); + + tag[0] ^= 0xff; + rc = cf_eax_decrypt(&cf_aes, &aes, + cipher, nmsg, + header, nheader, + nonce, nnonce, + tag, ntag, + tmp); + TEST_CHECK(rc == 1); +} + +static void test_eax(void) +{ + /* Test vectors from paper. */ + check_eax("\x23\x39\x52\xDE\xE4\xD5\xED\x5F\x9B\x9C\x6D\x6F\xF8\x0F\xF4\x78", 16, + "", 0, + "\x62\xEC\x67\xF9\xC3\xA4\xA4\x07\xFC\xB2\xA8\xC4\x90\x31\xA8\xB3", 16, + "\x6B\xFB\x91\x4F\xD0\x7E\xAE\x6B", 8, + "", + "\xE0\x37\x83\x0E\x83\x89\xF2\x7B\x02\x5A\x2D\x65\x27\xE7\x9D\x01", 16); + + check_eax("\x91\x94\x5D\x3F\x4D\xCB\xEE\x0B\xF4\x5E\xF5\x22\x55\xF0\x95\xA4", 16, + "\xF7\xFB", 2, + "\xBE\xCA\xF0\x43\xB0\xA2\x3D\x84\x31\x94\xBA\x97\x2C\x66\xDE\xBD", 16, + "\xFA\x3B\xFD\x48\x06\xEB\x53\xFA", 8, + "\x19\xDD", + "\x5C\x4C\x93\x31\x04\x9D\x0B\xDA\xB0\x27\x74\x08\xF6\x79\x67\xE5", 16); + + check_eax("\x01\xF7\x4A\xD6\x40\x77\xF2\xE7\x04\xC0\xF6\x0A\xDA\x3D\xD5\x23", 16, + "\x1A\x47\xCB\x49\x33", 5, + "\x70\xC3\xDB\x4F\x0D\x26\x36\x84\x00\xA1\x0E\xD0\x5D\x2B\xFF\x5E", 16, + "\x23\x4A\x34\x63\xC1\x26\x4A\xC6", 8, + "\xD8\x51\xD5\xBA\xE0", + "\x3A\x59\xF2\x38\xA2\x3E\x39\x19\x9D\xC9\x26\x66\x26\xC4\x0F\x80", 16); + + check_eax("\xD0\x7C\xF6\xCB\xB7\xF3\x13\xBD\xDE\x66\xB7\x27\xAF\xD3\xC5\xE8", 16, + "\x48\x1C\x9E\x39\xB1", 5, + "\x84\x08\xDF\xFF\x3C\x1A\x2B\x12\x92\xDC\x19\x9E\x46\xB7\xD6\x17", 16, + "\x33\xCC\xE2\xEA\xBF\xF5\xA7\x9D", 8, + "\x63\x2A\x9D\x13\x1A", + "\xD4\xC1\x68\xA4\x22\x5D\x8E\x1F\xF7\x55\x93\x99\x74\xA7\xBE\xDE", 16); + + check_eax("\x35\xB6\xD0\x58\x00\x05\xBB\xC1\x2B\x05\x87\x12\x45\x57\xD2\xC2", 16, + "\x40\xD0\xC0\x7D\xA5\xE4", 6, + "\xFD\xB6\xB0\x66\x76\xEE\xDC\x5C\x61\xD7\x42\x76\xE1\xF8\xE8\x16", 16, + "\xAE\xB9\x6E\xAE\xBE\x29\x70\xE9", 8, + "\x07\x1D\xFE\x16\xC6\x75", + "\xCB\x06\x77\xE5\x36\xF7\x3A\xFE\x6A\x14\xB7\x4E\xE4\x98\x44\xDD", 16); + + check_eax("\xBD\x8E\x6E\x11\x47\x5E\x60\xB2\x68\x78\x4C\x38\xC6\x2F\xEB\x22", 16, + "\x4D\xE3\xB3\x5C\x3F\xC0\x39\x24\x5B\xD1\xFB\x7D", 12, + "\x6E\xAC\x5C\x93\x07\x2D\x8E\x85\x13\xF7\x50\x93\x5E\x46\xDA\x1B", 16, + "\xD4\x48\x2D\x1C\xA7\x8D\xCE\x0F", 8, + "\x83\x5B\xB4\xF1\x5D\x74\x3E\x35\x0E\x72\x84\x14", + "\xAB\xB8\x64\x4F\xD6\xCC\xB8\x69\x47\xC5\xE1\x05\x90\x21\x0A\x4F", 16); + + check_eax("\x7C\x77\xD6\xE8\x13\xBE\xD5\xAC\x98\xBA\xA4\x17\x47\x7A\x2E\x7D", 16, + "\x8B\x0A\x79\x30\x6C\x9C\xE7\xED\x99\xDA\xE4\xF8\x7F\x8D\xD6\x16\x36", 17, + "\x1A\x8C\x98\xDC\xD7\x3D\x38\x39\x3B\x2B\xF1\x56\x9D\xEE\xFC\x19", 16, + "\x65\xD2\x01\x79\x90\xD6\x25\x28", 8, + "\x02\x08\x3E\x39\x79\xDA\x01\x48\x12\xF5\x9F\x11\xD5\x26\x30\xDA\x30", + "\x13\x73\x27\xD1\x06\x49\xB0\xAA\x6E\x1C\x18\x1D\xB6\x17\xD7\xF2", 16); + + check_eax("\x5F\xFF\x20\xCA\xFA\xB1\x19\xCA\x2F\xC7\x35\x49\xE2\x0F\x5B\x0D", 16, + "\x1B\xDA\x12\x2B\xCE\x8A\x8D\xBA\xF1\x87\x7D\x96\x2B\x85\x92\xDD\x2D\x56", 18, + "\xDD\xE5\x9B\x97\xD7\x22\x15\x6D\x4D\x9A\xFF\x2B\xC7\x55\x98\x26", 16, + "\x54\xB9\xF0\x4E\x6A\x09\x18\x9A", 8, + "\x2E\xC4\x7B\x2C\x49\x54\xA4\x89\xAF\xC7\xBA\x48\x97\xED\xCD\xAE\x8C\xC3", + "\x3B\x60\x45\x05\x99\xBD\x02\xC9\x63\x82\x90\x2A\xEF\x7F\x83\x2A", 16); + + check_eax("\xA4\xA4\x78\x2B\xCF\xFD\x3E\xC5\xE7\xEF\x6D\x8C\x34\xA5\x61\x23", 16, + "\x6C\xF3\x67\x20\x87\x2B\x85\x13\xF6\xEA\xB1\xA8\xA4\x44\x38\xD5\xEF\x11", 18, + "\xB7\x81\xFC\xF2\xF7\x5F\xA5\xA8\xDE\x97\xA9\xCA\x48\xE5\x22\xEC", 16, + "\x89\x9A\x17\x58\x97\x56\x1D\x7E", 8, + "\x0D\xE1\x8F\xD0\xFD\xD9\x1E\x7A\xF1\x9F\x1D\x8E\xE8\x73\x39\x38\xB1\xE8", + "\xE7\xF6\xD2\x23\x16\x18\x10\x2F\xDB\x7F\xE5\x5F\xF1\x99\x17\x00", 16); + + check_eax("\x83\x95\xFC\xF1\xE9\x5B\xEB\xD6\x97\xBD\x01\x0B\xC7\x66\xAA\xC3", 16, + "\xCA\x40\xD7\x44\x6E\x54\x5F\xFA\xED\x3B\xD1\x2A\x74\x0A\x65\x9F\xFB\xBB\x3C\xEA\xB7", 21, + "\x22\xE7\xAD\xD9\x3C\xFC\x63\x93\xC5\x7E\xC0\xB3\xC1\x7D\x6B\x44", 16, + "\x12\x67\x35\xFC\xC3\x20\xD2\x5A", 8, + "\xCB\x89\x20\xF8\x7A\x6C\x75\xCF\xF3\x96\x27\xB5\x6E\x3E\xD1\x97\xC5\x52\xD2\x95\xA7", + "\xCF\xC4\x6A\xFC\x25\x3B\x46\x52\xB1\xAF\x37\x95\xB1\x24\xAB\x6E", 16); + + /* Test vector from bug #3 */ + check_eax("\x58\x94\x17\xB0\x32\x4B\x1B\x71\xD7\xA6\x75\x18\x52\x86\x7A\xE8", 16, + "\x00\x00\x1C\x40\x00\x00\x00\x48\x00\x00\x00\x73", 12, + "\x00\x01\x00\x00\xF6\x83", 6, + "", 0, + "\xD5\xD8\x99\x79\xAE\x79\xEB\xEE\x4E\x38\x5F\xA5", + "\x0E\xFB\x21\xFA\xD7\x14\xA2\x5B\x44\x14\x5F\x79\x22\x1A\x2C\x9A", 16); + +} + +static void check_cmac(const void *key, size_t nkey, + const void *msg, size_t nmsg, + const void *wanttag, size_t ntag) +{ + uint8_t gottag[16]; + + TEST_CHECK(cf_aes.blocksz == ntag); + + cf_aes_context aes; + cf_aes_init(&aes, key, nkey); + + cf_cmac cmac; + cf_cmac_init(&cmac, &cf_aes, &aes); + cf_cmac_sign(&cmac, msg, nmsg, gottag); + + TEST_CHECK(memcmp(gottag, wanttag, cf_aes.blocksz) == 0); +} + +static void test_cmac(void) +{ + /* These from SP800-38B */ + check_cmac("\x2b\x7e\x15\x16\x28\xae\xd2\xa6\xab\xf7\x15\x88\x09\xcf\x4f\x3c", 16, + "", 0, + "\xbb\x1d\x69\x29\xe9\x59\x37\x28\x7f\xa3\x7d\x12\x9b\x75\x67\x46", 16); + check_cmac("\x2b\x7e\x15\x16\x28\xae\xd2\xa6\xab\xf7\x15\x88\x09\xcf\x4f\x3c", 16, + "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96\xe9\x3d\x7e\x11\x73\x93\x17\x2a", 16, + "\x07\x0a\x16\xb4\x6b\x4d\x41\x44\xf7\x9b\xdd\x9d\xd0\x4a\x28\x7c", 16); + check_cmac("\x2b\x7e\x15\x16\x28\xae\xd2\xa6\xab\xf7\x15\x88\x09\xcf\x4f\x3c", 16, + "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96\xe9\x3d\x7e\x11\x73\x93\x17\x2a\xae\x2d\x8a\x57\x1e\x03\xac\x9c\x9e\xb7\x6f\xac\x45\xaf\x8e\x51\x30\xc8\x1c\x46\xa3\x5c\xe4\x11", 40, + "\xdf\xa6\x67\x47\xde\x9a\xe6\x30\x30\xca\x32\x61\x14\x97\xc8\x27", 16); + check_cmac("\x2b\x7e\x15\x16\x28\xae\xd2\xa6\xab\xf7\x15\x88\x09\xcf\x4f\x3c", 16, + "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96\xe9\x3d\x7e\x11\x73\x93\x17\x2a\xae\x2d\x8a\x57\x1e\x03\xac\x9c\x9e\xb7\x6f\xac\x45\xaf\x8e\x51\x30\xc8\x1c\x46\xa3\x5c\xe4\x11\xe5\xfb\xc1\x19\x1a\x0a\x52\xef\xf6\x9f\x24\x45\xdf\x4f\x9b\x17\xad\x2b\x41\x7b\xe6\x6c\x37\x10", 64, + "\x51\xf0\xbe\xbf\x7e\x3b\x9d\x92\xfc\x49\x74\x17\x79\x36\x3c\xfe", 16); + + check_cmac("\x8e\x73\xb0\xf7\xda\x0e\x64\x52\xc8\x10\xf3\x2b\x80\x90\x79\xe5\x62\xf8\xea\xd2\x52\x2c\x6b\x7b", 24, + "", 0, + "\xd1\x7d\xdf\x46\xad\xaa\xcd\xe5\x31\xca\xc4\x83\xde\x7a\x93\x67", 16); + check_cmac("\x8e\x73\xb0\xf7\xda\x0e\x64\x52\xc8\x10\xf3\x2b\x80\x90\x79\xe5\x62\xf8\xea\xd2\x52\x2c\x6b\x7b", 24, + "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96\xe9\x3d\x7e\x11\x73\x93\x17\x2a", 16, + "\x9e\x99\xa7\xbf\x31\xe7\x10\x90\x06\x62\xf6\x5e\x61\x7c\x51\x84", 16); + check_cmac("\x8e\x73\xb0\xf7\xda\x0e\x64\x52\xc8\x10\xf3\x2b\x80\x90\x79\xe5\x62\xf8\xea\xd2\x52\x2c\x6b\x7b", 24, + "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96\xe9\x3d\x7e\x11\x73\x93\x17\x2a\xae\x2d\x8a\x57\x1e\x03\xac\x9c\x9e\xb7\x6f\xac\x45\xaf\x8e\x51\x30\xc8\x1c\x46\xa3\x5c\xe4\x11", 40, + "\x8a\x1d\xe5\xbe\x2e\xb3\x1a\xad\x08\x9a\x82\xe6\xee\x90\x8b\x0e", 16); + check_cmac("\x8e\x73\xb0\xf7\xda\x0e\x64\x52\xc8\x10\xf3\x2b\x80\x90\x79\xe5\x62\xf8\xea\xd2\x52\x2c\x6b\x7b", 24, + "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96\xe9\x3d\x7e\x11\x73\x93\x17\x2a\xae\x2d\x8a\x57\x1e\x03\xac\x9c\x9e\xb7\x6f\xac\x45\xaf\x8e\x51\x30\xc8\x1c\x46\xa3\x5c\xe4\x11\xe5\xfb\xc1\x19\x1a\x0a\x52\xef\xf6\x9f\x24\x45\xdf\x4f\x9b\x17\xad\x2b\x41\x7b\xe6\x6c\x37\x10", 64, + "\xa1\xd5\xdf\x0e\xed\x79\x0f\x79\x4d\x77\x58\x96\x59\xf3\x9a\x11", 16); + + check_cmac("\x60\x3d\xeb\x10\x15\xca\x71\xbe\x2b\x73\xae\xf0\x85\x7d\x77\x81\x1f\x35\x2c\x07\x3b\x61\x08\xd7\x2d\x98\x10\xa3\x09\x14\xdf\xf4", 32, + "", 0, + "\x02\x89\x62\xf6\x1b\x7b\xf8\x9e\xfc\x6b\x55\x1f\x46\x67\xd9\x83", 16); + check_cmac("\x60\x3d\xeb\x10\x15\xca\x71\xbe\x2b\x73\xae\xf0\x85\x7d\x77\x81\x1f\x35\x2c\x07\x3b\x61\x08\xd7\x2d\x98\x10\xa3\x09\x14\xdf\xf4", 32, + "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96\xe9\x3d\x7e\x11\x73\x93\x17\x2a", 16, + "\x28\xa7\x02\x3f\x45\x2e\x8f\x82\xbd\x4b\xf2\x8d\x8c\x37\xc3\x5c", 16); + check_cmac("\x60\x3d\xeb\x10\x15\xca\x71\xbe\x2b\x73\xae\xf0\x85\x7d\x77\x81\x1f\x35\x2c\x07\x3b\x61\x08\xd7\x2d\x98\x10\xa3\x09\x14\xdf\xf4", 32, + "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96\xe9\x3d\x7e\x11\x73\x93\x17\x2a\xae\x2d\x8a\x57\x1e\x03\xac\x9c\x9e\xb7\x6f\xac\x45\xaf\x8e\x51\x30\xc8\x1c\x46\xa3\x5c\xe4\x11", 40, + "\xaa\xf3\xd8\xf1\xde\x56\x40\xc2\x32\xf5\xb1\x69\xb9\xc9\x11\xe6", 16); + check_cmac("\x60\x3d\xeb\x10\x15\xca\x71\xbe\x2b\x73\xae\xf0\x85\x7d\x77\x81\x1f\x35\x2c\x07\x3b\x61\x08\xd7\x2d\x98\x10\xa3\x09\x14\xdf\xf4", 32, + "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96\xe9\x3d\x7e\x11\x73\x93\x17\x2a\xae\x2d\x8a\x57\x1e\x03\xac\x9c\x9e\xb7\x6f\xac\x45\xaf\x8e\x51\x30\xc8\x1c\x46\xa3\x5c\xe4\x11\xe5\xfb\xc1\x19\x1a\x0a\x52\xef\xf6\x9f\x24\x45\xdf\x4f\x9b\x17\xad\x2b\x41\x7b\xe6\x6c\x37\x10", 64, + "\xe1\x99\x21\x90\x54\x9f\x6e\xd5\x69\x6a\x2c\x05\x6c\x31\x54\x10", 16); +} + +static void test_gf128_mul(void) +{ + uint8_t bout[16]; + + const void *bx = "\x03\x88\xda\xce\x60\xb6\xa3\x92\xf3\x28\xc2\xb9\x71\xb2\xfe\x78"; + const void *by = "\x66\xe9\x4b\xd4\xef\x8a\x2c\x3b\x88\x4c\xfa\x59\xca\x34\x2b\x2e"; + const void *bexpect = "\x5e\x2e\xc7\x46\x91\x70\x62\x88\x2c\x85\xb0\x68\x53\x53\xde\xb7"; + + cf_gf128 x, y, out; + cf_gf128_frombytes_be(bx, x); + cf_gf128_frombytes_be(by, y); + cf_gf128_mul(x, y, out); + cf_gf128_tobytes_be(out, bout); + TEST_CHECK(memcmp(bexpect, bout, 16) == 0); +} + +static void check_gcm(const void *key, size_t nkey, + const void *plain, size_t nplain, + const void *aad, size_t naad, + const void *iv, size_t niv, + const void *cipher_expect, size_t ncipher, + const void *tag_expect, size_t ntag) +{ + uint8_t plain_decrypt[64], + cipher[64], + tag[16]; + + assert(ncipher == nplain); + + cf_aes_context ctx; + cf_aes_init(&ctx, key, nkey); + + cf_gcm_encrypt(&cf_aes, &ctx, + plain, nplain, + aad, naad, + iv, niv, + cipher, + tag, ntag); + + TEST_CHECK(memcmp(tag, tag_expect, ntag) == 0); + TEST_CHECK(memcmp(cipher, cipher_expect, ncipher) == 0); + + int err = cf_gcm_decrypt(&cf_aes, &ctx, + cipher, ncipher, + aad, naad, + iv, niv, + tag, ntag, + plain_decrypt); + TEST_CHECK(err == 0); + TEST_CHECK(memcmp(plain_decrypt, plain, ncipher) == 0); + + tag[0] ^= 0xff; + err = cf_gcm_decrypt(&cf_aes, &ctx, + cipher, ncipher, + aad, naad, + iv, niv, + tag, ntag, + plain_decrypt); + TEST_CHECK(err == 1); +} + +static void test_gcm(void) +{ + check_gcm("\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 16, + "", 0, + "", 0, + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 12, + "", 0, + "\x58\xe2\xfc\xce\xfa\x7e\x30\x61\x36\x7f\x1d\x57\xa4\xe7\x45\x5a", 16); + check_gcm("\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 16, + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 16, + "", 0, + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 12, + "\x03\x88\xda\xce\x60\xb6\xa3\x92\xf3\x28\xc2\xb9\x71\xb2\xfe\x78", 16, + "\xab\x6e\x47\xd4\x2c\xec\x13\xbd\xf5\x3a\x67\xb2\x12\x57\xbd\xdf", 16); + check_gcm("\xfe\xff\xe9\x92\x86\x65\x73\x1c\x6d\x6a\x8f\x94\x67\x30\x83\x08", 16, + "\xd9\x31\x32\x25\xf8\x84\x06\xe5\xa5\x59\x09\xc5\xaf\xf5\x26\x9a" + "\x86\xa7\xa9\x53\x15\x34\xf7\xda\x2e\x4c\x30\x3d\x8a\x31\x8a\x72" + "\x1c\x3c\x0c\x95\x95\x68\x09\x53\x2f\xcf\x0e\x24\x49\xa6\xb5\x25" + "\xb1\x6a\xed\xf5\xaa\x0d\xe6\x57\xba\x63\x7b\x39\x1a\xaf\xd2\x55", 64, + "", 0, + "\xca\xfe\xba\xbe\xfa\xce\xdb\xad\xde\xca\xf8\x88", 12, + "\x42\x83\x1e\xc2\x21\x77\x74\x24\x4b\x72\x21\xb7\x84\xd0\xd4\x9c" + "\xe3\xaa\x21\x2f\x2c\x02\xa4\xe0\x35\xc1\x7e\x23\x29\xac\xa1\x2e" + "\x21\xd5\x14\xb2\x54\x66\x93\x1c\x7d\x8f\x6a\x5a\xac\x84\xaa\x05" + "\x1b\xa3\x0b\x39\x6a\x0a\xac\x97\x3d\x58\xe0\x91\x47\x3f\x59\x85", 64, + "\x4d\x5c\x2a\xf3\x27\xcd\x64\xa6\x2c\xf3\x5a\xbd\x2b\xa6\xfa\xb4", 16); + check_gcm("\xfe\xff\xe9\x92\x86\x65\x73\x1c\x6d\x6a\x8f\x94\x67\x30\x83\x08", 16, + "\xd9\x31\x32\x25\xf8\x84\x06\xe5\xa5\x59\x09\xc5\xaf\xf5\x26\x9a" + "\x86\xa7\xa9\x53\x15\x34\xf7\xda\x2e\x4c\x30\x3d\x8a\x31\x8a\x72" + "\x1c\x3c\x0c\x95\x95\x68\x09\x53\x2f\xcf\x0e\x24\x49\xa6\xb5\x25" + "\xb1\x6a\xed\xf5\xaa\x0d\xe6\x57\xba\x63\x7b\x39", 60, + "\xfe\xed\xfa\xce\xde\xad\xbe\xef\xfe\xed\xfa\xce\xde\xad\xbe\xef" + "\xab\xad\xda\xd2", 20, + "\xca\xfe\xba\xbe\xfa\xce\xdb\xad\xde\xca\xf8\x88", 12, + "\x42\x83\x1e\xc2\x21\x77\x74\x24\x4b\x72\x21\xb7\x84\xd0\xd4\x9c" + "\xe3\xaa\x21\x2f\x2c\x02\xa4\xe0\x35\xc1\x7e\x23\x29\xac\xa1\x2e" + "\x21\xd5\x14\xb2\x54\x66\x93\x1c\x7d\x8f\x6a\x5a\xac\x84\xaa\x05" + "\x1b\xa3\x0b\x39\x6a\x0a\xac\x97\x3d\x58\xe0\x91", 60, + "\x5b\xc9\x4f\xbc\x32\x21\xa5\xdb\x94\xfa\xe9\x5a\xe7\x12\x1a\x47", 16); + check_gcm("\xfe\xff\xe9\x92\x86\x65\x73\x1c\x6d\x6a\x8f\x94\x67\x30\x83\x08", 16, + "\xd9\x31\x32\x25\xf8\x84\x06\xe5\xa5\x59\x09\xc5\xaf\xf5\x26\x9a" + "\x86\xa7\xa9\x53\x15\x34\xf7\xda\x2e\x4c\x30\x3d\x8a\x31\x8a\x72" + "\x1c\x3c\x0c\x95\x95\x68\x09\x53\x2f\xcf\x0e\x24\x49\xa6\xb5\x25" + "\xb1\x6a\xed\xf5\xaa\x0d\xe6\x57\xba\x63\x7b\x39", 60, + "\xfe\xed\xfa\xce\xde\xad\xbe\xef\xfe\xed\xfa\xce\xde\xad\xbe\xef" + "\xab\xad\xda\xd2", 20, + "\xca\xfe\xba\xbe\xfa\xce\xdb\xad", 8, + "\x61\x35\x3b\x4c\x28\x06\x93\x4a\x77\x7f\xf5\x1f\xa2\x2a\x47\x55" + "\x69\x9b\x2a\x71\x4f\xcd\xc6\xf8\x37\x66\xe5\xf9\x7b\x6c\x74\x23" + "\x73\x80\x69\x00\xe4\x9f\x24\xb2\x2b\x09\x75\x44\xd4\x89\x6b\x42" + "\x49\x89\xb5\xe1\xeb\xac\x0f\x07\xc2\x3f\x45\x98", 60, + "\x36\x12\xd2\xe7\x9e\x3b\x07\x85\x56\x1b\xe1\x4a\xac\xa2\xfc\xcb", 16); + check_gcm("\xfe\xff\xe9\x92\x86\x65\x73\x1c\x6d\x6a\x8f\x94\x67\x30\x83\x08", 16, + "\xd9\x31\x32\x25\xf8\x84\x06\xe5\xa5\x59\x09\xc5\xaf\xf5\x26\x9a" + "\x86\xa7\xa9\x53\x15\x34\xf7\xda\x2e\x4c\x30\x3d\x8a\x31\x8a\x72" + "\x1c\x3c\x0c\x95\x95\x68\x09\x53\x2f\xcf\x0e\x24\x49\xa6\xb5\x25" + "\xb1\x6a\xed\xf5\xaa\x0d\xe6\x57\xba\x63\x7b\x39", 60, + "\xfe\xed\xfa\xce\xde\xad\xbe\xef\xfe\xed\xfa\xce\xde\xad\xbe\xef" + "\xab\xad\xda\xd2", 20, + "\x93\x13\x22\x5d\xf8\x84\x06\xe5\x55\x90\x9c\x5a\xff\x52\x69\xaa" + "\x6a\x7a\x95\x38\x53\x4f\x7d\xa1\xe4\xc3\x03\xd2\xa3\x18\xa7\x28" + "\xc3\xc0\xc9\x51\x56\x80\x95\x39\xfc\xf0\xe2\x42\x9a\x6b\x52\x54" + "\x16\xae\xdb\xf5\xa0\xde\x6a\x57\xa6\x37\xb3\x9b", 60, + "\x8c\xe2\x49\x98\x62\x56\x15\xb6\x03\xa0\x33\xac\xa1\x3f\xb8\x94" + "\xbe\x91\x12\xa5\xc3\xa2\x11\xa8\xba\x26\x2a\x3c\xca\x7e\x2c\xa7" + "\x01\xe4\xa9\xa4\xfb\xa4\x3c\x90\xcc\xdc\xb2\x81\xd4\x8c\x7c\x6f" + "\xd6\x28\x75\xd2\xac\xa4\x17\x03\x4c\x34\xae\xe5", 60, + "\x61\x9c\xc5\xae\xff\xfe\x0b\xfa\x46\x2a\xf4\x3c\x16\x99\xd0\x50", 16); + + check_gcm("\xfe\xff\xe9\x92\x86\x65\x73\x1c\x6d\x6a\x8f\x94\x67\x30\x83\x08", 16, + "\xd9\x31\x32\x25\xf8\x84\x06\xe5\xa5\x59\x09\xc5\xaf\xf5\x26\x9a" + "\x86\xa7\xa9\x53\x15\x34\xf7\xda\x2e\x4c\x30\x3d\x8a\x31\x8a\x72" + "\x1c\x3c\x0c\x95\x95\x68\x09\x53\x2f\xcf\x0e\x24\x49\xa6\xb5\x25" + "\xb1\x6a\xed\xf5\xaa\x0d\xe6\x57\xba\x63\x7b\x39", 60, + "\xfe\xed\xfa\xce\xde\xad\xbe\xef\xfe\xed\xfa\xce\xde\xad\xbe\xef" + "\xab\xad\xda\xd2", 20, + "\x93\x13\x22\x5d\xf8\x84\x06\xe5\x55\x90\x9c\x5a\xff\x52\x69\xaa" + "\x6a\x7a\x95\x38\x53\x4f\x7d\xa1\xe4\xc3\x03\xd2\xa3\x18\xa7\x28" + "\xc3\xc0\xc9\x51\x56\x80\x95\x39\xfc\xf0\xe2\x42\x9a\x6b\x52\x54" + "\x16\xae\xdb\xf5\xa0\xde\x6a\x57\xa6\x37\xb3\x9b", 60, + "\x8c\xe2\x49\x98\x62\x56\x15\xb6\x03\xa0\x33\xac\xa1\x3f\xb8\x94" + "\xbe\x91\x12\xa5\xc3\xa2\x11\xa8\xba\x26\x2a\x3c\xca\x7e\x2c\xa7" + "\x01\xe4\xa9\xa4\xfb\xa4\x3c\x90\xcc\xdc\xb2\x81\xd4\x8c\x7c\x6f" + "\xd6\x28\x75\xd2\xac\xa4\x17\x03\x4c\x34\xae\xe5", 60, + "\x61\x9c\xc5\xae\xff\xfe\x0b\xfa\x46\x2a\xf4\x3c\x16\x99\xd0\x50", 16); + check_gcm("\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 24, + "", 0, + "", 0, + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 12, + "", 0, + "\xcd\x33\xb2\x8a\xc7\x73\xf7\x4b\xa0\x0e\xd1\xf3\x12\x57\x24\x35", 16); + check_gcm("\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 24, + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 16, + "", 0, + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 12, + "\x98\xe7\x24\x7c\x07\xf0\xfe\x41\x1c\x26\x7e\x43\x84\xb0\xf6\x00", 16, + "\x2f\xf5\x8d\x80\x03\x39\x27\xab\x8e\xf4\xd4\x58\x75\x14\xf0\xfb", 16); + check_gcm("\xfe\xff\xe9\x92\x86\x65\x73\x1c\x6d\x6a\x8f\x94\x67\x30\x83\x08" + "\xfe\xff\xe9\x92\x86\x65\x73\x1c", 24, + "\xd9\x31\x32\x25\xf8\x84\x06\xe5\xa5\x59\x09\xc5\xaf\xf5\x26\x9a" + "\x86\xa7\xa9\x53\x15\x34\xf7\xda\x2e\x4c\x30\x3d\x8a\x31\x8a\x72" + "\x1c\x3c\x0c\x95\x95\x68\x09\x53\x2f\xcf\x0e\x24\x49\xa6\xb5\x25" + "\xb1\x6a\xed\xf5\xaa\x0d\xe6\x57\xba\x63\x7b\x39\x1a\xaf\xd2\x55", 64, + "", 0, + "\xca\xfe\xba\xbe\xfa\xce\xdb\xad\xde\xca\xf8\x88", 12, + "\x39\x80\xca\x0b\x3c\x00\xe8\x41\xeb\x06\xfa\xc4\x87\x2a\x27\x57" + "\x85\x9e\x1c\xea\xa6\xef\xd9\x84\x62\x85\x93\xb4\x0c\xa1\xe1\x9c" + "\x7d\x77\x3d\x00\xc1\x44\xc5\x25\xac\x61\x9d\x18\xc8\x4a\x3f\x47" + "\x18\xe2\x44\x8b\x2f\xe3\x24\xd9\xcc\xda\x27\x10\xac\xad\xe2\x56", 64, + "\x99\x24\xa7\xc8\x58\x73\x36\xbf\xb1\x18\x02\x4d\xb8\x67\x4a\x14", 16); +} + +static void check_ccm(const void *key, size_t nkey, + const void *header, size_t nheader, + const void *plain, size_t nplain, + const void *nonce, size_t nnonce, + const void *expect_cipher, size_t ncipher, + const void *expect_tag, size_t ntag) +{ + uint8_t cipher[32], tag[16], decrypted[32]; + + assert(ncipher == nplain); + + cf_aes_context ctx; + cf_aes_init(&ctx, key, nkey); + + cf_ccm_encrypt(&cf_aes, &ctx, + plain, nplain, 15 - nnonce, + header, nheader, + nonce, nnonce, + cipher, + tag, ntag); + + TEST_CHECK(memcmp(tag, expect_tag, ntag) == 0); + TEST_CHECK(memcmp(cipher, expect_cipher, ncipher) == 0); + + int err; + err = cf_ccm_decrypt(&cf_aes, &ctx, + expect_cipher, ncipher, 15 - nnonce, + header, nheader, + nonce, nnonce, + tag, ntag, + decrypted); + TEST_CHECK(err == 0); + TEST_CHECK(memcmp(decrypted, plain, nplain) == 0); + + tag[0] ^= 0xff; + + err = cf_ccm_decrypt(&cf_aes, &ctx, + expect_cipher, ncipher, 15 - nnonce, + header, nheader, + nonce, nnonce, + tag, ntag, + decrypted); + TEST_CHECK(err == 1); +} + +#if !MCU_TARGET +static void fill(uint8_t *buf, size_t len, uint8_t b) +{ + for (size_t i = 0; i < len; i++) + buf[i] = b++; +} + +static void test_ccm_long(void) +{ + /* This is example 4 from SP800-38C, to test the long AAD code path. */ + uint8_t header[0x10000]; + uint8_t key[16]; + uint8_t tag[14]; + uint8_t nonce[13]; + uint8_t plain[32], cipher[32]; + + fill(header, sizeof header, 0x00); + fill(key, sizeof key, 0x40); + fill(nonce, sizeof nonce, 0x10); + fill(plain, sizeof plain, 0x20); + + const void *expect_tag = "\xb4\xac\x6b\xec\x93\xe8\x59\x8e\x7f\x0d\xad\xbc\xea\x5b"; + const void *expect_cipher = "\x69\x91\x5d\xad\x1e\x84\xc6\x37\x6a\x68\xc2\x96\x7e\x4d\xab\x61\x5a\xe0\xfd\x1f\xae\xc4\x4c\xc4\x84\x82\x85\x29\x46\x3c\xcf\x72"; + + cf_aes_context ctx; + cf_aes_init(&ctx, key, sizeof key); + + cf_ccm_encrypt(&cf_aes, &ctx, + plain, sizeof plain, 15 - sizeof nonce, + header, sizeof header, + nonce, sizeof nonce, + cipher, + tag, sizeof tag); + + TEST_CHECK(memcmp(expect_tag, tag, sizeof tag) == 0); + TEST_CHECK(memcmp(expect_cipher, cipher, sizeof cipher) == 0); +} +#endif + +static void test_ccm(void) +{ + check_ccm("\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf", 16, + "\x00\x01\x02\x03\x04\x05\x06\x07", 8, + "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e", 23, + "\x00\x00\x00\x03\x02\x01\x00\xa0\xa1\xa2\xa3\xa4\xa5", 13, + "\x58\x8c\x97\x9a\x61\xc6\x63\xd2\xf0\x66\xd0\xc2\xc0\xf9\x89\x80\x6d\x5f\x6b\x61\xda\xc3\x84", 23, + "\x17\xe8\xd1\x2c\xfd\xf9\x26\xe0", 8); + + check_ccm("\x40\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f", 16, + "\x00\x01\x02\x03\x04\x05\x06\x07", 8, + "\x20\x21\x22\x23", 4, + "\x10\x11\x12\x13\x14\x15\x16", 7, + "\x71\x62\x01\x5b", 4, + "\x4d\xac\x25\x5d", 4); + + check_ccm("\x40\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f", 16, + "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13", 20, + "\x20\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f\x30\x31\x32\x33\x34\x35\x36\x37", 24, + "\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b", 12, + "\xe3\xb2\x01\xa9\xf5\xb7\x1a\x7a\x9b\x1c\xea\xec\xcd\x97\xe7\x0b\x61\x76\xaa\xd9\xa4\x42\x8a\xa5", 24, + "\x48\x43\x92\xfb\xc1\xb0\x99\x51", 8); +} + +static void check_ocb(const void *key, size_t nkey, + const void *header, size_t nheader, + const void *plain, size_t nplain, + const void *nonce, size_t nnonce, + const void *expect_cipher, size_t ncipher, + const void *expect_tag, size_t ntag) +{ + uint8_t cipher[40], tag[16]; + + assert(ncipher == nplain); + assert(ncipher <= sizeof cipher); + assert(ntag <= sizeof tag); + + cf_aes_context ctx; + cf_aes_init(&ctx, key, nkey); + + cf_ocb_encrypt(&cf_aes, &ctx, + plain, nplain, + header, nheader, + nonce, nnonce, + cipher, + tag, ntag); + + TEST_CHECK(memcmp(tag, expect_tag, ntag) == 0); + TEST_CHECK(memcmp(cipher, expect_cipher, ncipher) == 0); + + uint8_t decrypted[40]; + int err; + err = cf_ocb_decrypt(&cf_aes, &ctx, + expect_cipher, ncipher, + header, nheader, + nonce, nnonce, + tag, ntag, + decrypted); + TEST_CHECK(err == 0); + TEST_CHECK(memcmp(decrypted, plain, nplain) == 0); + + tag[0] ^= 0xff; + + err = cf_ocb_decrypt(&cf_aes, &ctx, + expect_cipher, ncipher, + header, nheader, + nonce, nnonce, + tag, ntag, + decrypted); + TEST_CHECK(err == 1); +} + +static void test_ocb(void) +{ + check_ocb("\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F", 16, + "", 0, + "", 0, + "\xBB\xAA\x99\x88\x77\x66\x55\x44\x33\x22\x11\x00", 12, + "", 0, + "\x78\x54\x07\xBF\xFF\xC8\xAD\x9E\xDC\xC5\x52\x0A\xC9\x11\x1E\xE6", 16); + + check_ocb("\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F", 16, + "\x00\x01\x02\x03\x04\x05\x06\x07", 8, + "\x00\x01\x02\x03\x04\x05\x06\x07", 8, + "\xBB\xAA\x99\x88\x77\x66\x55\x44\x33\x22\x11\x01", 12, + "\x68\x20\xB3\x65\x7B\x6F\x61\x5A", 8, + "\x57\x25\xBD\xA0\xD3\xB4\xEB\x3A\x25\x7C\x9A\xF1\xF8\xF0\x30\x09", 16); + + check_ocb("\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F", 16, + "\x00\x01\x02\x03\x04\x05\x06\x07", 8, + "", 0, + "\xBB\xAA\x99\x88\x77\x66\x55\x44\x33\x22\x11\x02", 12, + "", 0, + "\x81\x01\x7F\x82\x03\xF0\x81\x27\x71\x52\xFA\xDE\x69\x4A\x0A\x00", 16); + + check_ocb("\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F", 16, + "", 0, + "\x00\x01\x02\x03\x04\x05\x06\x07", 8, + "\xBB\xAA\x99\x88\x77\x66\x55\x44\x33\x22\x11\x03", 12, + "\x45\xDD\x69\xF8\xF5\xAA\xE7\x24", 8, + "\x14\x05\x4C\xD1\xF3\x5D\x82\x76\x0B\x2C\xD0\x0D\x2F\x99\xBF\xA9", 16); + + check_ocb("\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F", 16, + "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F", 16, + "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F", 16, + "\xBB\xAA\x99\x88\x77\x66\x55\x44\x33\x22\x11\x04", 12, + "\x57\x1D\x53\x5B\x60\xB2\x77\x18\x8B\xE5\x14\x71\x70\xA9\xA2\x2C", 16, + "\x3A\xD7\xA4\xFF\x38\x35\xB8\xC5\x70\x1C\x1C\xCE\xC8\xFC\x33\x58", 16); + + check_ocb("\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F", 16, + "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F", 16, + "", 0, + "\xBB\xAA\x99\x88\x77\x66\x55\x44\x33\x22\x11\x05", 12, + "", 0, + "\x8C\xF7\x61\xB6\x90\x2E\xF7\x64\x46\x2A\xD8\x64\x98\xCA\x6B\x97", 16); + + check_ocb("\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F", 16, + "", 0, + "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F", 16, + "\xBB\xAA\x99\x88\x77\x66\x55\x44\x33\x22\x11\x06", 12, + "\x5C\xE8\x8E\xC2\xE0\x69\x27\x06\xA9\x15\xC0\x0A\xEB\x8B\x23\x96", 16, + "\xF4\x0E\x1C\x74\x3F\x52\x43\x6B\xDF\x06\xD8\xFA\x1E\xCA\x34\x3D", 16); + + check_ocb("\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F", 16, + "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F\x10\x11\x12\x13\x14\x15\x16\x17", 24, + "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F\x10\x11\x12\x13\x14\x15\x16\x17", 24, + "\xBB\xAA\x99\x88\x77\x66\x55\x44\x33\x22\x11\x07", 12, + "\x1C\xA2\x20\x73\x08\xC8\x7C\x01\x07\x56\x10\x4D\x88\x40\xCE\x19\x52\xF0\x96\x73\xA4\x48\xA1\x22", 24, + "\xC9\x2C\x62\x24\x10\x51\xF5\x73\x56\xD7\xF3\xC9\x0B\xB0\xE0\x7F", 16); + + check_ocb("\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F", 16, + "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F\x10\x11\x12\x13\x14\x15\x16\x17", 24, + "", 0, + "\xBB\xAA\x99\x88\x77\x66\x55\x44\x33\x22\x11\x08", 12, + "", 0, + "\x6D\xC2\x25\xA0\x71\xFC\x1B\x9F\x7C\x69\xF9\x3B\x0F\x1E\x10\xDE", 16); + + check_ocb("\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F", 16, + "", 0, + "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F\x10\x11\x12\x13\x14\x15\x16\x17", 24, + "\xBB\xAA\x99\x88\x77\x66\x55\x44\x33\x22\x11\x09", 12, + "\x22\x1B\xD0\xDE\x7F\xA6\xFE\x99\x3E\xCC\xD7\x69\x46\x0A\x0A\xF2\xD6\xCD\xED\x0C\x39\x5B\x1C\x3C", 24, + "\xE7\x25\xF3\x24\x94\xB9\xF9\x14\xD8\x5C\x0B\x1E\xB3\x83\x57\xFF", 16); + + check_ocb("\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F", 16, + "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F", 32, + "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F", 32, + "\xBB\xAA\x99\x88\x77\x66\x55\x44\x33\x22\x11\x0A", 12, + "\xBD\x6F\x6C\x49\x62\x01\xC6\x92\x96\xC1\x1E\xFD\x13\x8A\x46\x7A\xBD\x3C\x70\x79\x24\xB9\x64\xDE\xAF\xFC\x40\x31\x9A\xF5\xA4\x85", 32, + "\x40\xFB\xBA\x18\x6C\x55\x53\xC6\x8A\xD9\xF5\x92\xA7\x9A\x42\x40", 16); + + check_ocb("\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F", 16, + "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F", 32, + "", 0, + "\xBB\xAA\x99\x88\x77\x66\x55\x44\x33\x22\x11\x0B", 12, + "", 0, + "\xFE\x80\x69\x0B\xEE\x8A\x48\x5D\x11\xF3\x29\x65\xBC\x9D\x2A\x32", 16); + + check_ocb("\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F", 16, + "", 0, + "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F", 32, + "\xBB\xAA\x99\x88\x77\x66\x55\x44\x33\x22\x11\x0C", 12, + "\x29\x42\xBF\xC7\x73\xBD\xA2\x3C\xAB\xC6\xAC\xFD\x9B\xFD\x58\x35\xBD\x30\x0F\x09\x73\x79\x2E\xF4\x60\x40\xC5\x3F\x14\x32\xBC\xDF", 32, + "\xB5\xE1\xDD\xE3\xBC\x18\xA5\xF8\x40\xB5\x2E\x65\x34\x44\xD5\xDF", 16); + + check_ocb("\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F", 16, + "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F\x20\x21\x22\x23\x24\x25\x26\x27", 40, + "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F\x20\x21\x22\x23\x24\x25\x26\x27", 40, + "\xBB\xAA\x99\x88\x77\x66\x55\x44\x33\x22\x11\x0D", 12, + "\xD5\xCA\x91\x74\x84\x10\xC1\x75\x1F\xF8\xA2\xF6\x18\x25\x5B\x68\xA0\xA1\x2E\x09\x3F\xF4\x54\x60\x6E\x59\xF9\xC1\xD0\xDD\xC5\x4B\x65\xE8\x62\x8E\x56\x8B\xAD\x7A", 40, + "\xED\x07\xBA\x06\xA4\xA6\x94\x83\xA7\x03\x54\x90\xC5\x76\x9E\x60", 16); + + check_ocb("\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F", 16, + "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F\x20\x21\x22\x23\x24\x25\x26\x27", 40, + "", 0, + "\xBB\xAA\x99\x88\x77\x66\x55\x44\x33\x22\x11\x0E", 12, + "", 0, + "\xC5\xCD\x9D\x18\x50\xC1\x41\xE3\x58\x64\x99\x94\xEE\x70\x1B\x68", 16); + + check_ocb("\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F", 16, + "", 0, + "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F\x20\x21\x22\x23\x24\x25\x26\x27", 40, + "\xBB\xAA\x99\x88\x77\x66\x55\x44\x33\x22\x11\x0F", 12, + "\x44\x12\x92\x34\x93\xC5\x7D\x5D\xE0\xD7\x00\xF7\x53\xCC\xE0\xD1\xD2\xD9\x50\x60\x12\x2E\x9F\x15\xA5\xDD\xBF\xC5\x78\x7E\x50\xB5\xCC\x55\xEE\x50\x7B\xCB\x08\x4E", 40, + "\x47\x9A\xD3\x63\xAC\x36\x6B\x95\xA9\x8C\xA5\xF3\x00\x0B\x14\x79", 16); + + check_ocb("\x0F\x0E\x0D\x0C\x0B\x0A\x09\x08\x07\x06\x05\x04\x03\x02\x01\x00", 16, + "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F\x20\x21\x22\x23\x24\x25\x26\x27", 40, + "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F\x20\x21\x22\x23\x24\x25\x26\x27", 40, + "\xBB\xAA\x99\x88\x77\x66\x55\x44\x33\x22\x11\x0D", 12, + "\x17\x92\xA4\xE3\x1E\x07\x55\xFB\x03\xE3\x1B\x22\x11\x6E\x6C\x2D\xDF\x9E\xFD\x6E\x33\xD5\x36\xF1\xA0\x12\x4B\x0A\x55\xBA\xE8\x84\xED\x93\x48\x15\x29\xC7\x6B\x6A", 40, + "\xD0\xC5\x15\xF4\xD1\xCD\xD4\xFD\xAC\x4F\x02\xAA", 12); +} + +#if !MCU_TARGET +static void check_ocb_long(size_t nkey, const void *expect_tag, size_t ntag) +{ + uint8_t C[22400]; + uint8_t K[32]; + uint8_t S[128] = { 0 }; + uint8_t N[12] = { 0 }; + size_t nC = 0; + + memset(K, 0, sizeof K); + K[nkey - 1] = ntag * 8; + + cf_aes_context aes; + cf_aes_init(&aes, K, nkey); + + for (size_t i = 0; i < 128; i++) + { + /* N = num2str(3i+1, 96) */ + memset(N, 0, sizeof N); + write32_be(3 * i + 1, N + 8); + + /* C = C || OCB-ENCRYPT(K, N, S, S) + * nb. OCB-ENCRYPT(Key, Nonce, AAD, Plain) */ + cf_ocb_encrypt(&cf_aes, &aes, + S, i, /* plain */ + S, i, /* aad */ + N, sizeof N, /* nonce */ + C + nC, /* cipher out */ + C + nC + i, /* tag out */ + ntag); + nC += i + ntag; + + /* N = num2str(3i+2,96) */ + write32_be(3 * i + 2, N + 8); + + /* C = C || OCB-ENCRYPT(K, N, , S) */ + cf_ocb_encrypt(&cf_aes, &aes, + S, i, + NULL, 0, + N, sizeof N, + C + nC, + C + nC + i, + ntag); + nC += i + ntag; + + /* N = num2str(3i+3,96) */ + write32_be(3 * i + 3, N + 8); + + /* C = C || OCB-ENCRYPT(K, N, S, ) */ + cf_ocb_encrypt(&cf_aes, &aes, + NULL, 0, + S, i, + N, sizeof N, + NULL, + C + nC, + ntag); + nC += ntag; + } + + /* N = num2str(385, 96) */ + write32_be(385, N + 8); + + /* Output : OCB-ENCRYPT(K, N, C, ) */ + uint8_t result[16]; + cf_ocb_encrypt(&cf_aes, &aes, + NULL, 0, + C, nC, + N, sizeof N, + NULL, + result, ntag); + + TEST_CHECK(memcmp(result, expect_tag, ntag) == 0); +} + +static void test_ocb_long(void) +{ + check_ocb_long(16, "\x67\xE9\x44\xD2\x32\x56\xC5\xE0\xB6\xC6\x1F\xA2\x2F\xDF\x1E\xA2", 16); + check_ocb_long(24, "\xF6\x73\xF2\xC3\xE7\x17\x4A\xAE\x7B\xAE\x98\x6C\xA9\xF2\x9E\x17", 16); + check_ocb_long(32, "\xD9\x0E\xB8\xE9\xC9\x77\xC8\x8B\x79\xDD\x79\x3D\x7F\xFA\x16\x1C", 16); + check_ocb_long(16, "\x77\xA3\xD8\xE7\x35\x89\x15\x8D\x25\xD0\x12\x09", 12); + check_ocb_long(24, "\x05\xD5\x6E\xAD\x27\x52\xC8\x6B\xE6\x93\x2C\x5E", 12); + check_ocb_long(32, "\x54\x58\x35\x9A\xC2\x3B\x0C\xBA\x9E\x63\x30\xDD", 12); + check_ocb_long(16, "\x19\x2C\x9B\x7B\xD9\x0B\xA0\x6A", 8); + check_ocb_long(24, "\x00\x66\xBC\x6E\x0E\xF3\x4E\x24", 8); + check_ocb_long(32, "\x7D\x4E\xA5\xD4\x45\x50\x1C\xBE", 8); +} +#endif + +TEST_LIST = { + { "cbc", test_cbc }, + { "cbcmac", test_cbcmac }, + { "ctr", test_ctr }, + { "eax", test_eax }, + { "cmac", test_cmac }, + { "gf128-mul", test_gf128_mul }, + { "gcm", test_gcm }, + { "ccm", test_ccm }, + { "ocb", test_ocb }, + /* These remaining tests are too big for microcontroller targets. */ +#if !MCU_TARGET + { "ccm-long", test_ccm_long }, + { "ocb-long", test_ocb_long }, +#endif + { 0 } +}; + diff --git a/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/testnorx.c b/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/testnorx.c new file mode 100644 index 00000000..b18393f5 --- /dev/null +++ b/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/testnorx.c @@ -0,0 +1,118 @@ +/* + * cifra - embedded cryptography library + * Written in 2014 by Joseph Birr-Pixton + * + * To the extent possible under law, the author(s) have dedicated all + * copyright and related and neighboring rights to this software to the + * public domain worldwide. This software is distributed without any + * warranty. + * + * You should have received a copy of the CC0 Public Domain Dedication + * along with this software. If not, see + * . + */ + +#include "norx.h" +#include "handy.h" +#include "cutest.h" +#include "testutil.h" + +static void test_vector(void) +{ + uint8_t K[16], N[8], A[128], M[128], Z[128], C[128], T[16]; + + /* This is from the v2.0 paper, section A.2. */ + + unhex(K, sizeof K, "000102030405060708090a0b0c0d0e0f"); + unhex(N, sizeof N, "f0e0d0c0b0a09080"); + + for (unsigned i = 0; i < 128; i++) + { + A[i] = M[i] = Z[i] = i; + } + + cf_norx32_encrypt(K, N, + A, sizeof A, + M, sizeof M, + Z, sizeof Z, + C, T); + + uint8_t expect_C[128], expect_T[16]; + + unhex(expect_C, sizeof expect_C, "f4afc8e66d2d80de0a7f719c899624c9ad896ec7c61739d5376d0648c7bcb204e57db05c6f83b3ff4315e8a4ef2f2c855f21ea4c51ac6de575773ba548f36e636a13b979d953bb91298ea4a6e2aa27402991e0da541997825407b2f12441de3ae6c5dbfe41b12f1480d234832765111e4c09deef9fe3971618d2217c4b77921e"); + unhex(expect_T, sizeof expect_T, "7810131eea2eab1e5da05d23d4e3cb99"); + + TEST_CHECK(memcmp(C, expect_C, sizeof C) == 0); + TEST_CHECK(memcmp(T, expect_T, sizeof T) == 0); + + uint8_t M2[128]; + TEST_CHECK(0 == + cf_norx32_decrypt(K, N, + A, sizeof A, + C, sizeof C, + Z, sizeof Z, + T, + M2)); + + TEST_CHECK(memcmp(M, M2, sizeof M) == 0); + T[0] ^= 0xff; + + TEST_CHECK(cf_norx32_decrypt(K, N, + A, sizeof A, + C, sizeof C, + Z, sizeof Z, + T, + M2)); +} + +#include "testnorx.katdata.inc" + +static void test_kat(void) +{ + uint8_t K[16], N[16], H[256], W[256]; + const uint8_t *kats = kat_data; + +#define FILL(arr, c) \ + do { \ + for (size_t i = 0; i < sizeof arr; i++) \ + arr[i] = (i * c + 123) & 0xff; \ + } while (0) + FILL(N, 181); + FILL(K, 191); + FILL(H, 193); + FILL(W, 197); +#undef FILL + + for (size_t i = 0; i < sizeof W; i++) + { + uint8_t C[256]; + uint8_t A[16]; + + cf_norx32_encrypt(K, N, + H, i, + W, i, + NULL, 0, + C, A); + + TEST_CHECK(memcmp(kats, C, i) == 0); + kats += i; + TEST_CHECK(memcmp(kats, A, sizeof A) == 0); + kats += sizeof A; + + uint8_t M[256] = { 0 }; + TEST_CHECK(0 == cf_norx32_decrypt(K, N, + H, i, + C, i, + NULL, 0, + A, M)); + + TEST_CHECK(0 == memcmp(M, W, i)); + } +} + +TEST_LIST = { + { "vector", test_vector }, + { "kat", test_kat }, + { 0 } +}; + diff --git a/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/testnorx.katdata.inc b/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/testnorx.katdata.inc new file mode 100644 index 00000000..13dd7461 --- /dev/null +++ b/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/testnorx.katdata.inc @@ -0,0 +1,4961 @@ +static const uint8_t kat_data[] = { + 0xAF, 0x7C, 0xEF, 0x63, 0x5D, 0xEE, 0x94, 0x74, + 0x9B, 0xC2, 0x03, 0x9E, 0xC0, 0x49, 0xE0, 0x81, + + 0x69, 0x63, 0x57, 0x72, 0xEC, 0x0B, 0x66, 0xF2, + 0xE4, 0xB0, 0x1D, 0x30, 0x34, 0x29, 0x84, 0xE9, + 0xA8, + + 0x02, 0x46, 0x13, 0xCC, 0x6B, 0x19, 0x96, 0xB3, + 0x7E, 0x1C, 0xA6, 0x79, 0x00, 0x28, 0x19, 0x09, + 0x9F, 0x86, + + 0x99, 0xAC, 0xEA, 0x8C, 0x2B, 0x70, 0x02, 0xBA, + 0x86, 0xE9, 0xEB, 0x22, 0xEC, 0x23, 0xAF, 0x9A, + 0x95, 0xD0, 0xE5, + + 0xFE, 0xFB, 0xA0, 0xBA, 0x20, 0x28, 0x50, 0xDC, + 0xE5, 0xD6, 0x70, 0x26, 0x7A, 0x9E, 0x2A, 0xC3, + 0x3F, 0xCB, 0xD7, 0x0C, + + 0xB9, 0x67, 0x98, 0x4F, 0xDF, 0x1B, 0x19, 0x66, + 0x9C, 0xDE, 0xAE, 0x96, 0x76, 0xDB, 0xDE, 0x55, + 0x95, 0x50, 0xD9, 0xC2, 0xBA, + + 0x62, 0x28, 0x9A, 0x03, 0xF3, 0xF2, 0xFB, 0x0E, + 0xCF, 0xD4, 0x11, 0x74, 0x1D, 0x8E, 0x8B, 0xCD, + 0x92, 0x52, 0x96, 0x5B, 0x64, 0x99, + + 0x2F, 0xCE, 0xB4, 0x86, 0x4C, 0x0A, 0x47, 0xEB, + 0x98, 0x2A, 0xD2, 0xA1, 0x59, 0x9A, 0x5A, 0xB9, + 0x0C, 0xA7, 0x7D, 0xB0, 0xA6, 0xFF, 0x05, + + 0xE0, 0x22, 0x71, 0xE2, 0xCD, 0xF8, 0x3C, 0x12, + 0x8B, 0x4E, 0x28, 0x14, 0x6F, 0x0E, 0x18, 0xAE, + 0x23, 0xDF, 0xD0, 0x59, 0x70, 0x9E, 0x54, 0x49, + + 0xF6, 0xB6, 0x9E, 0x08, 0xB8, 0x27, 0x54, 0x94, + 0xD1, 0x0B, 0x93, 0x25, 0xEF, 0xD5, 0xE2, 0x19, + 0xEF, 0xEA, 0x0C, 0xFC, 0x01, 0x75, 0xC2, 0x90, + 0x00, + + 0x54, 0xBE, 0x7D, 0xFB, 0xF5, 0xCC, 0x52, 0xC6, + 0x9A, 0x0F, 0x65, 0xBD, 0xF1, 0x53, 0x5D, 0x01, + 0x07, 0xCC, 0xAB, 0xB9, 0xA5, 0x53, 0xFD, 0xE7, + 0xE4, 0x74, + + 0xD7, 0x6E, 0x5B, 0x87, 0xD0, 0xC1, 0x68, 0x92, + 0xD0, 0x80, 0x7D, 0x36, 0x8D, 0xE7, 0x36, 0xC5, + 0x97, 0xE7, 0x46, 0xDA, 0xC9, 0x19, 0xD9, 0x98, + 0xD9, 0xBD, 0x7B, + + 0x7E, 0xEB, 0x69, 0xAB, 0x77, 0x97, 0xDA, 0xE8, + 0x47, 0xA4, 0x6E, 0x4A, 0x1D, 0xC9, 0x00, 0xF3, + 0x4B, 0x2E, 0xCD, 0x56, 0xDF, 0xE1, 0xAF, 0x9E, + 0xE8, 0xAD, 0x94, 0x48, + + 0xDF, 0xAB, 0x2B, 0xE7, 0x84, 0x9C, 0xBB, 0x96, + 0x3F, 0x02, 0x99, 0x65, 0x42, 0x1A, 0x0D, 0x33, + 0x97, 0xA8, 0x23, 0x7C, 0x59, 0x4E, 0xCC, 0x64, + 0x54, 0x11, 0x6F, 0x09, 0x80, + + 0xB5, 0x4B, 0x1A, 0x8C, 0x05, 0x62, 0x60, 0x7A, + 0xCC, 0xA8, 0x63, 0x7F, 0xCC, 0xC6, 0x13, 0x70, + 0xF8, 0xC6, 0x09, 0x5C, 0x45, 0x93, 0x3E, 0x7C, + 0x9E, 0x27, 0x23, 0x42, 0xAE, 0x52, + + 0x56, 0x3E, 0x38, 0xC7, 0x66, 0xCE, 0xB5, 0x8F, + 0x77, 0xA1, 0x20, 0xE2, 0x69, 0x08, 0x92, 0x1E, + 0x32, 0x01, 0x75, 0xD2, 0x05, 0x92, 0x1B, 0x60, + 0x60, 0x9F, 0xD2, 0xA3, 0x89, 0x49, 0x6E, + + 0x01, 0x91, 0x5D, 0xDC, 0xC7, 0xB1, 0x4F, 0x6D, + 0x73, 0x4D, 0x3B, 0x68, 0xA0, 0xA5, 0x1D, 0xA5, + 0x22, 0x3C, 0xFE, 0xDC, 0x86, 0xB1, 0x64, 0x54, + 0x92, 0xE1, 0x0F, 0x32, 0xD5, 0xA6, 0x4B, 0xAC, + + 0x13, 0xF8, 0xFC, 0xDB, 0x41, 0x62, 0x9F, 0x6E, + 0xE6, 0x9B, 0xAB, 0xE5, 0x27, 0x3B, 0x8C, 0x15, + 0x8C, 0xC8, 0x03, 0x38, 0xE3, 0x7E, 0x83, 0xDA, + 0xA2, 0x5B, 0xA8, 0x44, 0xE2, 0x41, 0x47, 0x53, + 0x2A, + + 0xD2, 0x73, 0x87, 0xC2, 0xF0, 0x28, 0x2A, 0x0F, + 0xE6, 0x37, 0xC9, 0xAF, 0xF3, 0x02, 0xAC, 0xEA, + 0x37, 0xB6, 0x8C, 0xA6, 0x37, 0x5F, 0x79, 0x89, + 0xCD, 0x90, 0x6B, 0xCC, 0xF6, 0x7C, 0xEC, 0xD9, + 0x75, 0xE6, + + 0x0B, 0x76, 0x2F, 0xAC, 0x9F, 0x20, 0xA1, 0x56, + 0x5F, 0xF9, 0x67, 0xB8, 0xDC, 0xAC, 0x48, 0xA0, + 0x00, 0xD3, 0xFE, 0x87, 0xAE, 0x13, 0x07, 0x26, + 0xD9, 0xC2, 0x6D, 0xF9, 0xEC, 0xB4, 0xA2, 0x41, + 0x17, 0xB6, 0x4C, + + 0xA2, 0xE6, 0x67, 0xBC, 0x65, 0x03, 0x88, 0xDC, + 0xAD, 0x8B, 0x3C, 0x28, 0x83, 0x5F, 0xE3, 0x47, + 0x95, 0xDA, 0xF9, 0x6A, 0x09, 0xE9, 0xF9, 0xD5, + 0x58, 0xE4, 0xC3, 0x64, 0x3E, 0xE2, 0x82, 0x22, + 0xC3, 0xF7, 0x50, 0x40, + + 0x73, 0xA2, 0xA1, 0xB7, 0xC4, 0xCC, 0x5F, 0xA6, + 0x86, 0x7A, 0xFB, 0xF9, 0x2D, 0xB0, 0x92, 0x90, + 0xDB, 0xD1, 0xD0, 0xD4, 0x7E, 0x83, 0xD8, 0xF7, + 0x39, 0x38, 0xFA, 0xD4, 0x24, 0x56, 0x96, 0x1D, + 0xF5, 0xB9, 0x35, 0x7A, 0x7B, + + 0xCB, 0xA1, 0x1C, 0x70, 0x7E, 0x42, 0xF7, 0x32, + 0x68, 0x56, 0x27, 0xC7, 0xFD, 0x13, 0xCE, 0xC2, + 0xD3, 0xEE, 0x3E, 0x33, 0xF3, 0xC3, 0xB4, 0x87, + 0x31, 0x6E, 0xDA, 0xA1, 0x09, 0x77, 0x9E, 0xBE, + 0x43, 0x8D, 0x11, 0xF9, 0x0B, 0x5B, + + 0x31, 0xD7, 0x0C, 0xE3, 0xD3, 0x37, 0xCA, 0xF9, + 0x9E, 0x7E, 0x57, 0xF1, 0x45, 0x02, 0x7D, 0xDC, + 0xA9, 0xBF, 0x73, 0x6B, 0x04, 0x16, 0x44, 0x6D, + 0x62, 0x65, 0x2E, 0x5D, 0xBE, 0x75, 0xD0, 0xA2, + 0x88, 0xF2, 0x60, 0xFE, 0x7B, 0xED, 0x74, + + 0x42, 0xD4, 0xAD, 0xFF, 0xDB, 0x5D, 0xBF, 0x2F, + 0xA9, 0xE1, 0x7B, 0x60, 0xB8, 0xE8, 0x4D, 0x6F, + 0xF9, 0x70, 0xE4, 0x26, 0x40, 0xFA, 0x19, 0x36, + 0x07, 0x5C, 0xEA, 0x0F, 0x47, 0x89, 0xE0, 0x91, + 0xD2, 0xF7, 0x75, 0xB7, 0x27, 0x3A, 0xCC, 0xEB, + + 0xCB, 0x20, 0xDD, 0xCD, 0x30, 0x13, 0xD8, 0x84, + 0xD8, 0x57, 0xAA, 0xFA, 0x74, 0xDA, 0x46, 0x49, + 0x35, 0x60, 0x93, 0x20, 0xAB, 0x32, 0x19, 0x02, + 0x3C, 0x8F, 0x9F, 0x1E, 0xAD, 0x4B, 0x8F, 0x5A, + 0xE5, 0x1F, 0xEA, 0x8B, 0x5C, 0x53, 0x81, 0x68, + 0x0D, + + 0xF9, 0x00, 0x75, 0x76, 0x0E, 0x8B, 0x33, 0xAF, + 0x83, 0xD4, 0xB4, 0x0D, 0xF1, 0x48, 0xD5, 0x02, + 0x08, 0x6F, 0xEC, 0x1B, 0xB0, 0x40, 0x82, 0xF2, + 0xF4, 0x52, 0xCB, 0x43, 0xE6, 0x0F, 0x1F, 0xBE, + 0x15, 0xCE, 0x9D, 0xB8, 0xED, 0x3F, 0x7B, 0xD0, + 0x94, 0xFF, + + 0x6C, 0x78, 0x7D, 0x34, 0x07, 0xA5, 0xB2, 0xA9, + 0xF8, 0x8F, 0xB6, 0x4E, 0x0D, 0x31, 0x23, 0xD2, + 0x71, 0xB5, 0x7D, 0x10, 0xBA, 0xA7, 0x35, 0x1F, + 0xDE, 0x10, 0xE7, 0x21, 0x56, 0x50, 0xB1, 0xAD, + 0x76, 0x03, 0x7C, 0x8C, 0x88, 0x12, 0x09, 0x46, + 0xF4, 0x5F, 0x57, + + 0xFC, 0xAC, 0x41, 0xB1, 0x66, 0xBD, 0xFE, 0x96, + 0x4D, 0xDA, 0x18, 0x9C, 0xDA, 0xA8, 0xC7, 0x6A, + 0x94, 0x5D, 0x2B, 0x44, 0xB0, 0xF6, 0x89, 0x58, + 0x9C, 0x30, 0xD3, 0xC8, 0x48, 0x2F, 0xE8, 0x9F, + 0xB5, 0x33, 0x4C, 0x2A, 0x89, 0x15, 0x71, 0xDF, + 0xDB, 0xA0, 0x4B, 0x00, + + 0x1F, 0x85, 0x54, 0x96, 0x15, 0x04, 0x80, 0x09, + 0xDB, 0x13, 0xA7, 0x52, 0x03, 0x5F, 0x8C, 0x6E, + 0x66, 0x9D, 0x65, 0x64, 0xB0, 0x73, 0xC0, 0x61, + 0xCD, 0xF1, 0xEF, 0xE6, 0x01, 0x5B, 0x3B, 0x85, + 0xB8, 0x9E, 0x54, 0xC8, 0x47, 0x9C, 0x8A, 0x9C, + 0x27, 0x43, 0x4D, 0xB3, 0x33, + + 0x96, 0xEA, 0xF6, 0x72, 0xED, 0x28, 0x75, 0x42, + 0x06, 0x81, 0xEA, 0x29, 0xDF, 0xE4, 0x06, 0x51, + 0xD2, 0x3F, 0x42, 0xF5, 0x9C, 0xDD, 0x4C, 0xCD, + 0xA3, 0xEC, 0x46, 0x65, 0xD8, 0xA2, 0x5D, 0x05, + 0x6D, 0x5B, 0x46, 0x18, 0x44, 0xB0, 0x34, 0x02, + 0x7A, 0xEF, 0x24, 0x2A, 0x73, 0x69, + + 0x41, 0xC9, 0xA4, 0x8C, 0xE0, 0x92, 0xB4, 0xAB, + 0xCB, 0xFA, 0x94, 0xDF, 0xF5, 0x29, 0xFA, 0x23, + 0x43, 0x0F, 0xF0, 0x96, 0x01, 0x58, 0xAC, 0x6E, + 0x16, 0x5B, 0x59, 0xAA, 0x46, 0x10, 0xA5, 0x27, + 0xF3, 0xD0, 0x6D, 0x7B, 0xA8, 0x44, 0x2E, 0x9D, + 0xF9, 0x62, 0x87, 0xA4, 0xA2, 0xDC, 0x69, + + 0xA6, 0xBB, 0x70, 0x33, 0x8E, 0x2E, 0xBD, 0xF7, + 0x24, 0xAF, 0x04, 0xAF, 0x33, 0x3C, 0x58, 0x6A, + 0xB0, 0x83, 0xC6, 0x4B, 0xE6, 0xB6, 0x90, 0xDA, + 0x29, 0xFC, 0x34, 0xDE, 0x50, 0x4E, 0x4F, 0x77, + 0xD6, 0x31, 0x41, 0x80, 0x52, 0x06, 0x39, 0x11, + 0x83, 0xA9, 0x34, 0x69, 0x87, 0xAC, 0x54, 0x28, + + 0x5E, 0x8D, 0x7B, 0xAE, 0xCD, 0x3B, 0x76, 0xBC, + 0xD6, 0x0A, 0x5D, 0x7A, 0x91, 0x4C, 0x51, 0x5D, + 0x54, 0xA6, 0x9D, 0xB8, 0xAD, 0xE9, 0xA3, 0xCB, + 0x80, 0xAD, 0xE8, 0x72, 0x99, 0xFE, 0x31, 0xFA, + 0x9F, 0x5E, 0xB4, 0x7A, 0x8A, 0x33, 0x19, 0x42, + 0xF4, 0x7E, 0xB1, 0x68, 0x28, 0x72, 0xFD, 0xCB, + 0x39, + + 0x4E, 0x1D, 0xFC, 0x0C, 0x9C, 0x55, 0x80, 0x6A, + 0x05, 0x1B, 0x55, 0x77, 0x9D, 0x42, 0x98, 0x4A, + 0x70, 0x70, 0x1E, 0x06, 0x48, 0xD3, 0x76, 0x72, + 0x6A, 0x14, 0x71, 0xA2, 0xF9, 0xB1, 0xB2, 0xE9, + 0x17, 0x08, 0x95, 0x20, 0x2A, 0x00, 0xDF, 0x29, + 0x3B, 0xFA, 0x3C, 0xD2, 0x63, 0xAF, 0x24, 0xF9, + 0x08, 0x09, + + 0xCB, 0x1E, 0x1E, 0x95, 0xE6, 0x40, 0xDF, 0x3F, + 0x0C, 0x7B, 0x5B, 0x76, 0xFD, 0x13, 0xC4, 0x95, + 0xBE, 0xCC, 0x66, 0xD9, 0x1D, 0x4F, 0xBD, 0x29, + 0xBB, 0x3F, 0x5C, 0x3B, 0xA4, 0x0E, 0x4E, 0x76, + 0xD4, 0x42, 0x6F, 0x64, 0xCA, 0x26, 0xAB, 0x7B, + 0xA6, 0x9C, 0x54, 0x7B, 0x2A, 0x71, 0xBA, 0xC2, + 0xF0, 0xF2, 0x6F, + + 0x63, 0xF4, 0x8B, 0x62, 0x4F, 0xE7, 0x46, 0xCC, + 0x4F, 0x60, 0x20, 0x8B, 0x00, 0x57, 0xD0, 0xA7, + 0xDF, 0x6F, 0x08, 0x5C, 0x6F, 0x00, 0x78, 0xA8, + 0x5A, 0x77, 0x71, 0x65, 0x6E, 0x01, 0x71, 0x8D, + 0x2B, 0x15, 0x90, 0x7E, 0x59, 0xA4, 0xF6, 0x23, + 0xF3, 0x12, 0xBC, 0x3C, 0xFD, 0x21, 0x7D, 0x2E, + 0x7E, 0x4F, 0x83, 0xD7, + + 0x76, 0xC1, 0x46, 0xC5, 0x86, 0x11, 0xE9, 0x28, + 0x6A, 0x97, 0x26, 0xC7, 0x89, 0xA7, 0xCD, 0x01, + 0x40, 0x53, 0xD6, 0x42, 0xB3, 0xF1, 0x48, 0x51, + 0x11, 0xC6, 0x9E, 0xDF, 0x91, 0x5C, 0xD9, 0x4C, + 0xB9, 0x68, 0x63, 0x6D, 0xBC, 0xCE, 0x6F, 0x5E, + 0xE3, 0xFC, 0xAB, 0xCE, 0x24, 0x94, 0x5C, 0x43, + 0x51, 0xB6, 0xE7, 0x99, 0x45, + + 0xC9, 0xC7, 0xCD, 0x1F, 0x2E, 0x48, 0x25, 0xC3, + 0x1C, 0xF8, 0x85, 0x32, 0x15, 0x56, 0x82, 0x17, + 0xF4, 0xDC, 0x5F, 0xAE, 0xEF, 0x94, 0xDD, 0xFA, + 0xEA, 0xEE, 0xFC, 0x9B, 0x8C, 0xE1, 0x2E, 0xCF, + 0xE3, 0x40, 0x03, 0xF7, 0xBD, 0x7B, 0x12, 0x56, + 0x42, 0xCA, 0x1A, 0x68, 0xEF, 0xC3, 0xEF, 0xAC, + 0xEB, 0xA8, 0xD8, 0x91, 0x8C, 0x42, + + 0x78, 0xF9, 0x51, 0x9E, 0x84, 0x32, 0xFC, 0xBA, + 0x46, 0xA0, 0xF1, 0x04, 0x77, 0xF6, 0x93, 0xAD, + 0xB3, 0x95, 0xA3, 0x69, 0xA4, 0xAD, 0x45, 0x89, + 0x39, 0xFC, 0x08, 0x35, 0x45, 0xA9, 0xDC, 0x26, + 0x55, 0xA2, 0x8E, 0x3E, 0xF5, 0xE3, 0x86, 0xD1, + 0x1A, 0x37, 0x4C, 0x96, 0x16, 0x68, 0x06, 0x01, + 0xF0, 0x0D, 0x02, 0x4F, 0x17, 0x34, 0x9C, + + 0xD8, 0xFF, 0x53, 0x2C, 0xEE, 0xA5, 0xEB, 0x21, + 0xD8, 0x4C, 0x89, 0xCF, 0x7F, 0x15, 0x59, 0x5D, + 0xDD, 0x45, 0x01, 0x6A, 0x71, 0x0B, 0x47, 0x2C, + 0x72, 0x08, 0xC4, 0x5D, 0x71, 0x6A, 0x59, 0xDB, + 0x46, 0x0E, 0xDF, 0xD7, 0x2B, 0xDA, 0xE1, 0x69, + 0x0A, 0xE7, 0xD7, 0x5F, 0x18, 0x49, 0xC6, 0xA2, + 0xA7, 0x1A, 0x2E, 0x94, 0xCD, 0x45, 0xD9, 0x5A, + + 0x51, 0x54, 0x80, 0x8F, 0x07, 0xDA, 0xCC, 0x7B, + 0xB8, 0xE1, 0xE0, 0xEE, 0xF2, 0x7D, 0x8D, 0x2D, + 0xF0, 0x50, 0x5A, 0xB6, 0xF5, 0xBC, 0x62, 0xBC, + 0xA6, 0x75, 0xB7, 0x80, 0xBA, 0x6E, 0x1D, 0x7C, + 0xD5, 0xC7, 0x42, 0x31, 0xA3, 0x98, 0x08, 0xFE, + 0x13, 0xA2, 0xA6, 0x74, 0x4D, 0xF3, 0x20, 0x9E, + 0xEB, 0x83, 0x64, 0x27, 0xE4, 0x9C, 0x3C, 0x1F, + 0xC2, + + 0xF1, 0x24, 0xBC, 0xD3, 0x95, 0x66, 0x65, 0x69, + 0xA7, 0x6E, 0x61, 0x08, 0x9C, 0xBF, 0xC3, 0x9B, + 0x9B, 0x09, 0x05, 0x0B, 0x94, 0xB4, 0x64, 0xB2, + 0x0E, 0x0F, 0x19, 0x0C, 0x6D, 0x92, 0xF5, 0xC3, + 0xB8, 0x9B, 0xBF, 0x59, 0x00, 0x6D, 0x8D, 0x48, + 0xE0, 0xB1, 0x06, 0xC2, 0x3E, 0x33, 0x26, 0x24, + 0x6F, 0x53, 0xBE, 0x86, 0xD7, 0xEA, 0xCD, 0x18, + 0x18, 0x24, + + 0xE8, 0xE1, 0xC4, 0x50, 0xEF, 0xB6, 0xF0, 0xCA, + 0x78, 0xEF, 0x9C, 0x51, 0x61, 0x58, 0x18, 0xB7, + 0x90, 0x09, 0x48, 0x73, 0xA1, 0x13, 0x6D, 0x16, + 0x8D, 0x97, 0x84, 0x92, 0x25, 0x44, 0xBF, 0xF5, + 0x3C, 0x9D, 0xCE, 0x68, 0x7E, 0x4B, 0x0A, 0x49, + 0xE1, 0xAE, 0xA7, 0xB3, 0xC8, 0xE0, 0x7B, 0x54, + 0xF9, 0xAB, 0x22, 0x0A, 0x19, 0x4F, 0x86, 0x1F, + 0xB7, 0x0F, 0x3A, + + 0x23, 0xD4, 0x95, 0xC7, 0xF9, 0xB7, 0x17, 0x4B, + 0xE8, 0x10, 0xF9, 0xB4, 0xCA, 0x9F, 0xBA, 0xBE, + 0x66, 0xAA, 0x83, 0x98, 0x7D, 0x2B, 0xF4, 0x84, + 0x18, 0x13, 0xCE, 0xBE, 0x10, 0x7D, 0x1B, 0x76, + 0x89, 0xBC, 0x9C, 0xF4, 0xE6, 0x71, 0x62, 0xA7, + 0x39, 0x89, 0xEF, 0x0D, 0xE9, 0x63, 0xD9, 0xB1, + 0x96, 0x63, 0xAC, 0xBC, 0xC7, 0x85, 0x77, 0xE3, + 0xD4, 0x40, 0x41, 0x5C, + + 0x0F, 0x8F, 0x47, 0xF8, 0xEA, 0x17, 0x30, 0x7E, + 0x67, 0xE2, 0x69, 0xF5, 0x20, 0xD9, 0xE0, 0x87, + 0xAB, 0xF6, 0x70, 0xBE, 0xF1, 0x26, 0x25, 0x01, + 0x14, 0x69, 0xE8, 0x8E, 0xA9, 0x8E, 0xB2, 0xAE, + 0xA5, 0x2C, 0x5F, 0x9D, 0x0C, 0x50, 0xC6, 0x95, + 0xC1, 0xDE, 0xEC, 0x7D, 0xEA, 0x87, 0xCA, 0x02, + 0xD7, 0x3F, 0x5E, 0x8A, 0xB3, 0x3A, 0xDA, 0x6A, + 0x33, 0xAD, 0x06, 0xD4, 0x6D, + + 0xAB, 0x89, 0xF3, 0x78, 0x67, 0x63, 0xD5, 0xFC, + 0xF2, 0x19, 0xD5, 0x91, 0x5C, 0x10, 0x86, 0x9F, + 0xD2, 0xDC, 0x46, 0xD9, 0xC7, 0xAA, 0x4E, 0x44, + 0xFF, 0x79, 0x5B, 0x8A, 0xE3, 0x47, 0x92, 0x20, + 0xA8, 0xA3, 0x5C, 0x95, 0xEF, 0xD2, 0x21, 0x49, + 0x8C, 0x66, 0x0D, 0xCD, 0xD2, 0x1D, 0x11, 0x22, + 0x31, 0x62, 0x47, 0xC9, 0xD4, 0xC1, 0xBC, 0xB3, + 0x80, 0x84, 0xB4, 0x71, 0xC1, 0xAB, + + 0x85, 0x76, 0x7F, 0x0D, 0x73, 0xE2, 0x6C, 0xB5, + 0x98, 0x1F, 0x7E, 0x09, 0xFC, 0x2D, 0xD6, 0xA4, + 0xE7, 0x57, 0xDC, 0x14, 0xCB, 0xD9, 0x7D, 0x46, + 0xC9, 0x6E, 0xE7, 0x61, 0x0A, 0x5F, 0x3D, 0xAB, + 0x4D, 0x39, 0x77, 0x96, 0xF5, 0xB0, 0x0C, 0x53, + 0x21, 0xBB, 0xA2, 0xAC, 0xA9, 0xC6, 0x91, 0xB9, + 0xF8, 0x03, 0xE2, 0xDD, 0xEE, 0x3B, 0xB7, 0xEB, + 0xD8, 0xB7, 0xCE, 0xAC, 0x02, 0xA1, 0xA8, + + 0xAA, 0xBE, 0xDD, 0x59, 0x61, 0xF8, 0xD1, 0x11, + 0x7A, 0xC2, 0x81, 0x7E, 0x61, 0x58, 0xAF, 0xA2, + 0x67, 0xC1, 0xA2, 0x8F, 0xE1, 0xC7, 0x0D, 0x27, + 0x2B, 0x4A, 0x9A, 0x6A, 0x77, 0x68, 0xFD, 0x68, + 0x18, 0xF1, 0xDB, 0x55, 0xBA, 0xEC, 0x2A, 0x37, + 0x7F, 0xD2, 0x68, 0xA7, 0xEF, 0x31, 0x77, 0x97, + 0xDE, 0x6B, 0x56, 0xB1, 0x5E, 0xBE, 0xBD, 0x51, + 0x07, 0x3E, 0xD6, 0xD9, 0x01, 0x64, 0xB8, 0x65, + + 0x52, 0x67, 0x5D, 0x5E, 0x11, 0xDA, 0x06, 0xC2, + 0xA6, 0x8E, 0x41, 0xE4, 0x30, 0x59, 0x2F, 0x73, + 0x40, 0x03, 0x88, 0x85, 0xE6, 0x91, 0x29, 0xCB, + 0xA6, 0x68, 0x56, 0xCF, 0x05, 0xE4, 0xD7, 0xA2, + 0x46, 0xC6, 0xC1, 0x06, 0x50, 0x0E, 0x1F, 0xAA, + 0xC2, 0xB2, 0x6E, 0x2F, 0xB9, 0x1A, 0x9F, 0xC3, + 0xC0, 0xD8, 0xD7, 0xF6, 0xCD, 0xD8, 0x92, 0xFB, + 0x6A, 0x4F, 0xFA, 0x2D, 0x0E, 0x13, 0x01, 0xD8, + 0x9A, + + 0x6B, 0xA5, 0xF2, 0x8D, 0x73, 0x10, 0x6F, 0x06, + 0x2B, 0x8B, 0x10, 0x56, 0xF6, 0x5F, 0xC0, 0x94, + 0x1C, 0x70, 0xB3, 0xBE, 0xEE, 0x00, 0x4D, 0x50, + 0x94, 0x88, 0xC5, 0x51, 0x01, 0x8B, 0xE8, 0xA5, + 0xF8, 0x89, 0x0F, 0x97, 0x7F, 0x0C, 0x67, 0x6F, + 0xC7, 0x1F, 0x91, 0x20, 0xD7, 0x32, 0x9C, 0x63, + 0xFF, 0xE7, 0xB8, 0x63, 0x0F, 0xE1, 0xCE, 0xC7, + 0xEA, 0x82, 0x1D, 0x57, 0xEC, 0xB9, 0xF9, 0x05, + 0x8D, 0x94, + + 0xFE, 0x5B, 0xB2, 0x66, 0xD8, 0xDF, 0x19, 0x49, + 0x59, 0x8E, 0xBC, 0xC5, 0xC7, 0xD1, 0x6F, 0x0A, + 0x8A, 0x5B, 0x0C, 0xF4, 0xC2, 0x35, 0x62, 0x61, + 0x89, 0x2E, 0x43, 0x70, 0x7D, 0x5A, 0xE7, 0xF1, + 0x63, 0x92, 0xDD, 0xD4, 0xBD, 0x61, 0x93, 0x8C, + 0x21, 0x13, 0x96, 0xBA, 0xDB, 0x7A, 0x1B, 0x81, + 0x43, 0x6B, 0x3F, 0x2C, 0x2E, 0x6B, 0xB2, 0x49, + 0x2E, 0x28, 0xB2, 0x79, 0x52, 0x66, 0x89, 0x48, + 0xE7, 0x97, 0x44, + + 0x4C, 0xAD, 0x82, 0xE3, 0x09, 0xEA, 0x08, 0x73, + 0xF4, 0x16, 0x4D, 0x67, 0x33, 0x17, 0xB0, 0x47, + 0x16, 0xA2, 0xAF, 0x99, 0xFE, 0x5A, 0x45, 0x70, + 0x5C, 0xB2, 0xF2, 0x7A, 0x64, 0xC9, 0x65, 0xE3, + 0x07, 0xAD, 0x8D, 0x77, 0x3F, 0x10, 0x9E, 0xCE, + 0xC5, 0x63, 0xA2, 0x67, 0xE3, 0xFE, 0x48, 0xAC, + 0x9A, 0x8F, 0x9E, 0xB9, 0x63, 0xB2, 0x2B, 0x59, + 0xF1, 0x53, 0x18, 0x95, 0xA8, 0x12, 0x28, 0xAF, + 0xCF, 0x97, 0x9A, 0xC9, + + 0x5C, 0x23, 0xC9, 0xB0, 0x2F, 0x8E, 0x8B, 0x75, + 0xBC, 0xD3, 0x76, 0x22, 0xD0, 0x83, 0x85, 0x0A, + 0xA8, 0xC1, 0xF6, 0x06, 0xD5, 0x80, 0x59, 0xEB, + 0xF5, 0xD2, 0xBF, 0x35, 0x76, 0x64, 0xF6, 0x40, + 0x2B, 0xC4, 0x59, 0xA4, 0x8A, 0x21, 0x78, 0x77, + 0xBD, 0x4C, 0x2D, 0x11, 0x24, 0x31, 0x33, 0xF4, + 0x8D, 0x89, 0x61, 0xA4, 0xD9, 0x74, 0xEC, 0xEA, + 0xC9, 0x90, 0x9C, 0x79, 0x5D, 0x4B, 0x9E, 0x92, + 0xB5, 0x0D, 0x94, 0xE4, 0xCE, + + 0xAC, 0xE3, 0xD3, 0xD0, 0x7C, 0x51, 0x6F, 0xD7, + 0x73, 0xC9, 0x82, 0x6B, 0x9A, 0x6C, 0x8D, 0x56, + 0xB4, 0x17, 0xB7, 0xD8, 0xAD, 0x80, 0xA7, 0xFC, + 0xCA, 0xD5, 0x5B, 0x8E, 0x3A, 0xE3, 0x4B, 0x6B, + 0xFD, 0x75, 0x1B, 0xD1, 0xE5, 0xBA, 0x64, 0xD8, + 0xC4, 0x29, 0x83, 0xF8, 0x18, 0x98, 0xA2, 0x96, + 0x10, 0xB2, 0x3E, 0x60, 0x04, 0xE9, 0x9A, 0x68, + 0x2D, 0xFD, 0x41, 0x6A, 0xB7, 0xB4, 0xB8, 0x81, + 0x08, 0x54, 0x7A, 0xBF, 0xD1, 0x91, + + 0xA9, 0xB0, 0xF9, 0x25, 0x66, 0xC3, 0xF5, 0x4D, + 0x9A, 0x9A, 0x18, 0x15, 0x8E, 0x06, 0x8E, 0xC3, + 0x75, 0x7B, 0x99, 0xE2, 0x07, 0x49, 0x41, 0x19, + 0xA1, 0x7E, 0x3E, 0x13, 0xED, 0x3E, 0xB9, 0x66, + 0x89, 0x37, 0x37, 0xE3, 0xBC, 0xC4, 0xA7, 0xA5, + 0xB4, 0x5A, 0x57, 0x1B, 0xF7, 0xAD, 0x54, 0x13, + 0xF5, 0x4F, 0x80, 0x3F, 0xF9, 0x02, 0x89, 0xCA, + 0xFE, 0x2F, 0xE3, 0xC5, 0x63, 0xB6, 0x4D, 0x72, + 0x95, 0x25, 0x51, 0xFE, 0xD7, 0x4C, 0x7B, + + 0xB9, 0x14, 0xD1, 0xAD, 0x98, 0x4B, 0x37, 0x28, + 0x4B, 0x73, 0xFE, 0x28, 0x3F, 0x0B, 0x83, 0xC4, + 0xB6, 0xED, 0x8D, 0x4E, 0x25, 0x12, 0xB5, 0x41, + 0xB3, 0xAC, 0x2C, 0x2A, 0x8B, 0x5C, 0x3D, 0xE6, + 0x69, 0xE1, 0x99, 0x18, 0x31, 0x78, 0xCB, 0xAC, + 0xA8, 0xE7, 0x7F, 0x44, 0xFF, 0x87, 0xBB, 0x92, + 0xBD, 0x98, 0xEF, 0xD3, 0x86, 0x1B, 0xD3, 0xB5, + 0xB2, 0x78, 0x56, 0x1D, 0x7A, 0x0C, 0x4D, 0xC7, + 0x15, 0xA1, 0x68, 0x10, 0x85, 0x19, 0x39, 0x9A, + + 0x4B, 0x01, 0x86, 0x3D, 0x0D, 0xB2, 0x31, 0x1F, + 0xA1, 0xCA, 0x12, 0x0C, 0x59, 0x69, 0xEC, 0x14, + 0x62, 0xC9, 0x17, 0xC2, 0x61, 0xF1, 0x60, 0x2B, + 0x8C, 0x46, 0x80, 0x62, 0x9E, 0x7E, 0xE4, 0x21, + 0xC3, 0x3F, 0xF7, 0x4C, 0x31, 0xCE, 0x8B, 0x4C, + 0x87, 0x48, 0xD9, 0x60, 0x39, 0xFD, 0xFC, 0x12, + 0x15, 0x2F, 0x35, 0x74, 0x79, 0xEB, 0x87, 0x20, + 0x72, 0x23, 0xE6, 0x66, 0x5A, 0xD4, 0xFB, 0x72, + 0xA9, 0x6B, 0xDB, 0xB4, 0x30, 0xFD, 0x80, 0xF5, + 0xBB, + + 0xBC, 0xD6, 0x2A, 0xC2, 0x2E, 0x81, 0x71, 0xF7, + 0xF9, 0x29, 0x5B, 0xBB, 0x8C, 0x84, 0xB3, 0xB2, + 0x47, 0xF4, 0xBB, 0x9C, 0x82, 0xC0, 0x35, 0xA2, + 0xEA, 0xA7, 0x4E, 0xA5, 0x5E, 0xD5, 0x0D, 0xDF, + 0x89, 0x3E, 0xC1, 0x3F, 0x8B, 0x82, 0xE5, 0xEB, + 0x4D, 0x87, 0xD9, 0x73, 0xAC, 0x06, 0x8A, 0xB4, + 0xF3, 0x2C, 0x83, 0xCB, 0x08, 0xB5, 0xB2, 0x74, + 0x16, 0xD0, 0x97, 0x87, 0x53, 0x6C, 0x73, 0x7B, + 0x20, 0x0D, 0x18, 0x7F, 0x3A, 0xD6, 0x3D, 0xF0, + 0x9E, 0x00, + + 0xE9, 0x20, 0xCF, 0x62, 0x26, 0x4F, 0xA8, 0xA2, + 0x8C, 0xCC, 0x32, 0xDE, 0x6B, 0xA5, 0x44, 0xB7, + 0xD0, 0x25, 0x48, 0x4B, 0xB7, 0x10, 0x61, 0x3B, + 0x93, 0xFB, 0xFB, 0x57, 0x02, 0xBC, 0x02, 0xD2, + 0x8E, 0x33, 0x08, 0xBF, 0xA2, 0x02, 0xB4, 0xDF, + 0x86, 0x33, 0xCD, 0xCD, 0x7C, 0x3B, 0x8D, 0xDB, + 0x90, 0x3A, 0xF3, 0x55, 0x82, 0x73, 0x5F, 0x27, + 0x8D, 0xED, 0x06, 0x08, 0x18, 0x27, 0xAF, 0xF8, + 0x7B, 0x01, 0x4E, 0xB0, 0xF2, 0xE8, 0xD9, 0x73, + 0x43, 0x59, 0xB0, + + 0x92, 0x47, 0x3D, 0x62, 0x6D, 0x82, 0xB4, 0x89, + 0x35, 0xCB, 0x4A, 0x66, 0x24, 0xF1, 0x14, 0x40, + 0xA6, 0xAD, 0xE1, 0xD4, 0xC8, 0xFB, 0x08, 0x90, + 0xFC, 0x33, 0xA8, 0x2E, 0xCF, 0x38, 0x4C, 0x45, + 0xF8, 0x8D, 0x4B, 0x11, 0xF8, 0x7F, 0xD8, 0x4F, + 0x22, 0x2D, 0x7B, 0x38, 0x8C, 0x8F, 0xDF, 0x8B, + 0xF1, 0x4B, 0xCF, 0x46, 0xE5, 0xCC, 0x8D, 0x0A, + 0x7A, 0x0E, 0xF8, 0xDE, 0xCE, 0x10, 0xCA, 0xCD, + 0xA8, 0x30, 0x0A, 0x63, 0x0E, 0xA0, 0x32, 0x54, + 0x5C, 0x77, 0x49, 0xDC, + + 0xED, 0xA1, 0x20, 0xA9, 0x5E, 0x2A, 0xBC, 0xBC, + 0x1A, 0x8D, 0x48, 0x71, 0x4E, 0x3A, 0xFA, 0xEA, + 0x8F, 0x78, 0x3F, 0xA6, 0x61, 0x28, 0xC3, 0xC9, + 0x01, 0xCF, 0xD4, 0x2E, 0x36, 0x40, 0x90, 0xA8, + 0xCA, 0x45, 0x40, 0xFE, 0x9E, 0xB6, 0x40, 0x28, + 0xFB, 0x28, 0x3E, 0x07, 0xFC, 0xA1, 0x1A, 0x8D, + 0xA8, 0x5B, 0xB1, 0x1A, 0xE3, 0x18, 0xDC, 0xB3, + 0x19, 0x14, 0xF9, 0xB9, 0x9C, 0xF2, 0x15, 0xE2, + 0x70, 0xD5, 0x74, 0xFF, 0x1E, 0xED, 0x92, 0x0C, + 0xC9, 0xE7, 0x57, 0x55, 0x8B, + + 0xD5, 0x15, 0x63, 0x0A, 0x41, 0xF9, 0x2B, 0x15, + 0x55, 0x1E, 0x63, 0x96, 0xC3, 0xF0, 0x21, 0x90, + 0xFB, 0xB9, 0xC7, 0xFE, 0xEE, 0x15, 0x2C, 0x28, + 0xBB, 0x2C, 0x9D, 0x6F, 0x8E, 0xAB, 0x73, 0xD3, + 0x03, 0x39, 0xE9, 0xB4, 0xEC, 0xED, 0x48, 0x1F, + 0xDA, 0x87, 0x29, 0xA1, 0x4B, 0xD7, 0xC8, 0xCD, + 0xDB, 0xF0, 0xCF, 0x82, 0x54, 0x27, 0xBF, 0x20, + 0xF4, 0xD4, 0x52, 0xED, 0x64, 0xA2, 0x4A, 0x6D, + 0xC8, 0x78, 0x1E, 0x83, 0x03, 0xBA, 0x22, 0x9C, + 0xFC, 0xB1, 0xE0, 0x67, 0xC7, 0x23, + + 0x62, 0xB2, 0xA4, 0xD4, 0xCD, 0xAE, 0xD3, 0xF1, + 0xFB, 0x71, 0x5C, 0xDD, 0xD6, 0x51, 0x91, 0x9D, + 0x48, 0xBD, 0x3C, 0xF9, 0x0C, 0x05, 0xEB, 0xF8, + 0x55, 0x48, 0x03, 0xE6, 0x9C, 0x13, 0x9E, 0xB8, + 0x6B, 0xB5, 0x09, 0xB3, 0x89, 0x04, 0x96, 0xFD, + 0x1C, 0xE8, 0x0F, 0xC9, 0x19, 0x85, 0xE4, 0xCC, + 0xBB, 0xDB, 0xC3, 0x15, 0x69, 0xD9, 0xA1, 0x91, + 0x9B, 0x16, 0xE0, 0xD0, 0x74, 0x3F, 0xF4, 0x2D, + 0x33, 0x74, 0x02, 0x1D, 0xE3, 0xDB, 0xF8, 0xD3, + 0x33, 0xD9, 0x2F, 0x77, 0x94, 0x6B, 0x20, + + 0x86, 0x99, 0xFC, 0xEF, 0x12, 0x8E, 0x6E, 0x84, + 0x7A, 0x25, 0xD3, 0xB6, 0x37, 0xEE, 0x42, 0x0D, + 0x88, 0xE2, 0x53, 0xD7, 0x59, 0x4A, 0x73, 0x67, + 0xA6, 0x20, 0xA3, 0x91, 0x7C, 0x1F, 0xCA, 0x18, + 0xC9, 0xEF, 0xD1, 0xD0, 0xE0, 0xC7, 0x23, 0x14, + 0x03, 0x05, 0x7F, 0x84, 0xCD, 0xDB, 0xDB, 0x2D, + 0x31, 0x33, 0xBE, 0xD5, 0x1A, 0xDC, 0xC2, 0xBE, + 0x6C, 0x9B, 0x35, 0xFB, 0xAD, 0xC1, 0xDE, 0xDC, + 0xDC, 0xB9, 0xDE, 0xF5, 0x38, 0xCF, 0x06, 0x95, + 0x53, 0x24, 0x47, 0x9F, 0xB8, 0x41, 0x84, 0x9B, + + 0x13, 0x83, 0x54, 0x9F, 0x66, 0xE7, 0x40, 0x2D, + 0xD9, 0xB5, 0xB9, 0xAC, 0xB0, 0x08, 0x06, 0x54, + 0x50, 0x34, 0x07, 0x8A, 0x2E, 0x0B, 0xF2, 0x06, + 0x85, 0xF2, 0x8C, 0xC1, 0x24, 0x2D, 0x9F, 0x66, + 0x9A, 0x94, 0x93, 0x0E, 0xFA, 0x5E, 0xCC, 0x1D, + 0x74, 0xAE, 0x8F, 0xAA, 0x51, 0x0E, 0x7F, 0xD4, + 0x61, 0xA2, 0x29, 0xAB, 0xE9, 0x70, 0x8F, 0x99, + 0xFF, 0x11, 0x38, 0x84, 0x63, 0x6D, 0x91, 0xB8, + 0xF8, 0x08, 0x01, 0x08, 0x65, 0x39, 0xCF, 0x42, + 0x34, 0x29, 0x36, 0xDE, 0x29, 0xE9, 0x44, 0xFE, + 0x7E, + + 0x13, 0x26, 0xF8, 0xB2, 0xD9, 0x68, 0xE5, 0x81, + 0x20, 0xE6, 0xA3, 0xC8, 0x34, 0x43, 0x4D, 0xCE, + 0xA7, 0x87, 0x10, 0x98, 0x35, 0x91, 0x70, 0xF0, + 0x1D, 0xA4, 0xFB, 0x73, 0x00, 0x8E, 0x15, 0x49, + 0x14, 0xF8, 0xE8, 0x11, 0xA6, 0xBD, 0xEE, 0x7D, + 0x51, 0x49, 0x52, 0x5F, 0x0D, 0x63, 0x8D, 0x52, + 0x40, 0x4D, 0xF5, 0x40, 0x15, 0x04, 0x7C, 0xE2, + 0x23, 0xCE, 0x1F, 0x37, 0x15, 0x2C, 0xDF, 0x92, + 0xDC, 0xF7, 0xAB, 0xA5, 0x2B, 0xE8, 0x8C, 0xF9, + 0xF1, 0xBC, 0x42, 0x79, 0xE0, 0x6B, 0xBF, 0xEA, + 0x74, 0xBA, + + 0xB4, 0x5B, 0x74, 0xCE, 0x30, 0x5A, 0x8C, 0x7B, + 0xCE, 0x65, 0x3E, 0x64, 0xEE, 0x0D, 0xC8, 0x91, + 0x2E, 0x57, 0x6B, 0xE6, 0xD1, 0x95, 0xCC, 0x64, + 0xB6, 0x0E, 0x67, 0xD2, 0xB3, 0x52, 0x78, 0x18, + 0x1E, 0xE6, 0x49, 0x32, 0x61, 0x68, 0x94, 0x19, + 0x98, 0x54, 0xDB, 0x92, 0x8B, 0x9B, 0x4E, 0x75, + 0x93, 0x72, 0x59, 0x63, 0x8D, 0x3F, 0x2F, 0x9C, + 0x4D, 0xC6, 0x94, 0x60, 0xDD, 0xD9, 0xB3, 0xB4, + 0x04, 0xC0, 0xBC, 0x49, 0x94, 0x01, 0x61, 0x1B, + 0xF0, 0xB6, 0x94, 0xCF, 0x21, 0xE6, 0x96, 0x77, + 0xDF, 0xB9, 0x13, + + 0xB2, 0xEB, 0xE5, 0x13, 0x22, 0xCD, 0x5F, 0x6C, + 0x28, 0xB3, 0xCD, 0x37, 0x6A, 0xCC, 0xC8, 0x59, + 0xBC, 0x0A, 0x44, 0xC0, 0x53, 0xB7, 0xD9, 0x1F, + 0x6A, 0xD2, 0x7D, 0x34, 0xB8, 0x9F, 0xBF, 0xA7, + 0xF2, 0x87, 0x09, 0xF7, 0xE0, 0xDE, 0x43, 0x66, + 0xD8, 0xAF, 0x04, 0x03, 0x2A, 0x48, 0xBC, 0x70, + 0x49, 0x34, 0x05, 0x03, 0x85, 0xFC, 0x30, 0x78, + 0xE5, 0x2A, 0x30, 0x65, 0x95, 0x62, 0xD6, 0x0B, + 0x5C, 0xD6, 0x97, 0x4C, 0x65, 0x0A, 0x94, 0xB5, + 0x2E, 0xF7, 0x86, 0x30, 0x63, 0x4F, 0xA8, 0x72, + 0xAD, 0xF4, 0x19, 0xFB, + + 0x9B, 0x61, 0xE9, 0xE9, 0x8D, 0xB0, 0x02, 0x06, + 0x4D, 0x1C, 0x28, 0x5C, 0x65, 0x7E, 0x89, 0x02, + 0x47, 0x76, 0x1A, 0x1E, 0xEC, 0x64, 0xBA, 0x8D, + 0x59, 0xF0, 0xC5, 0xCE, 0x89, 0xCF, 0x11, 0x5E, + 0x3A, 0xBF, 0x8A, 0x32, 0x63, 0xFB, 0xD8, 0xC7, + 0x56, 0xA8, 0x6F, 0xF3, 0x2B, 0xC8, 0x5B, 0x8F, + 0xEC, 0x2C, 0x91, 0x35, 0x60, 0xE4, 0x84, 0x09, + 0x2F, 0x36, 0x8E, 0x4F, 0xFB, 0x06, 0xBD, 0x53, + 0xC4, 0x8A, 0x6B, 0x3B, 0xFA, 0x04, 0x50, 0x15, + 0x17, 0x63, 0x46, 0x9C, 0x54, 0xF6, 0xB6, 0xA9, + 0xEA, 0xE5, 0x60, 0x5E, 0x75, + + 0xC6, 0x4D, 0xA8, 0x7B, 0xC5, 0xC5, 0xDA, 0x2B, + 0xBB, 0x19, 0xA2, 0x36, 0xBE, 0x76, 0xA7, 0x34, + 0x92, 0xD4, 0xE2, 0xA5, 0xF3, 0xF1, 0xF8, 0xBE, + 0xA0, 0xA3, 0xB8, 0xE2, 0x3C, 0x39, 0x34, 0x84, + 0xE5, 0xF7, 0x48, 0xF3, 0xD1, 0x4F, 0x4E, 0xC2, + 0x4E, 0xB3, 0xC2, 0xBB, 0xE0, 0x1E, 0xAA, 0xBF, + 0x42, 0x62, 0x90, 0x4D, 0x62, 0xF5, 0x79, 0xE5, + 0x50, 0x25, 0x03, 0x37, 0x90, 0xAA, 0xF7, 0xFC, + 0xEB, 0xC0, 0x32, 0xDA, 0x1C, 0xD7, 0x1E, 0xA5, + 0x1C, 0x49, 0xF4, 0xE4, 0x94, 0x2D, 0x88, 0xA8, + 0x24, 0x7C, 0x0D, 0x1F, 0xB1, 0xA7, + + 0xE5, 0x1F, 0xCF, 0xE1, 0x7A, 0x7C, 0xF5, 0x66, + 0x6E, 0x92, 0x41, 0x68, 0x89, 0x5C, 0xD7, 0xB4, + 0x24, 0x06, 0xEE, 0x3D, 0x0D, 0xC7, 0xDF, 0xA9, + 0x48, 0x39, 0xCB, 0x8E, 0x79, 0xE9, 0xA8, 0x3D, + 0xB9, 0xFC, 0x97, 0xF1, 0x03, 0x06, 0xEB, 0xFB, + 0x14, 0x97, 0x96, 0xA1, 0xFB, 0x25, 0x12, 0x6D, + 0xA9, 0x2B, 0x0C, 0xC1, 0x27, 0x87, 0x4D, 0x17, + 0xDE, 0xEA, 0xD3, 0xEE, 0x3A, 0xA9, 0xD5, 0x80, + 0x52, 0x0E, 0xBB, 0x15, 0xA8, 0x16, 0x58, 0x25, + 0x7A, 0x6C, 0x55, 0x30, 0x80, 0xCE, 0x9B, 0x1E, + 0x97, 0x21, 0xD7, 0xEE, 0x5D, 0x4C, 0xE6, + + 0xEE, 0x3C, 0x03, 0x94, 0x28, 0xD8, 0xED, 0x96, + 0x2E, 0x67, 0x08, 0xEE, 0xDB, 0x31, 0xD9, 0x42, + 0x10, 0x51, 0x99, 0x56, 0x68, 0x60, 0xA6, 0x79, + 0x19, 0x7A, 0x54, 0xC3, 0xBD, 0x2A, 0x2D, 0x69, + 0xF1, 0xE2, 0xEF, 0xA7, 0x26, 0x3D, 0x9A, 0x6F, + 0x26, 0x8D, 0xE3, 0x0E, 0x3B, 0xFB, 0xCC, 0xFF, + 0x65, 0x09, 0xAD, 0x24, 0xEE, 0xA8, 0xD8, 0x55, + 0x83, 0xF5, 0xEA, 0x61, 0x07, 0x6F, 0x90, 0x54, + 0x3C, 0x1A, 0x8E, 0xB0, 0x89, 0x79, 0x8A, 0xA7, + 0x35, 0x05, 0x7B, 0xAF, 0xF0, 0xBC, 0x94, 0xB1, + 0x59, 0xF2, 0xB8, 0xAA, 0xC9, 0x92, 0x9B, 0x4A, + + 0xF6, 0xF8, 0x0F, 0x47, 0xEF, 0xEB, 0x09, 0xB2, + 0xB3, 0xC6, 0x0E, 0xE1, 0xA5, 0xA2, 0x62, 0x6D, + 0x44, 0x25, 0xEE, 0xEE, 0x35, 0xD0, 0x18, 0xBE, + 0x07, 0xC3, 0xAD, 0x9E, 0x8E, 0x93, 0xBB, 0x78, + 0xD7, 0x8F, 0x47, 0x6A, 0x27, 0x4C, 0x39, 0x18, + 0xD1, 0xC5, 0xA9, 0x9F, 0x31, 0x7F, 0x47, 0x6A, + 0x95, 0x35, 0x74, 0x6B, 0x1C, 0xD5, 0x33, 0x51, + 0x68, 0x58, 0x67, 0x89, 0xA8, 0x43, 0x9B, 0xE5, + 0xB4, 0x94, 0x5E, 0x62, 0xD5, 0x1C, 0xCB, 0x31, + 0x1E, 0x5C, 0xA8, 0x10, 0xA4, 0xC0, 0x62, 0xDE, + 0x19, 0xCC, 0x17, 0x09, 0x4A, 0x5B, 0x88, 0xC3, + 0xE4, + + 0xFB, 0xD9, 0x1D, 0x95, 0x93, 0x0F, 0xBA, 0xDB, + 0x70, 0x42, 0x47, 0x89, 0xB4, 0xF2, 0xCB, 0xF9, + 0x65, 0x5F, 0x8D, 0xC7, 0x44, 0x51, 0x39, 0x7F, + 0xCC, 0xD2, 0x8A, 0xA7, 0x14, 0xFE, 0xFC, 0x4A, + 0x36, 0x50, 0x6E, 0x18, 0xF9, 0xAF, 0x0E, 0xB5, + 0xEC, 0x1B, 0xCB, 0x66, 0xE0, 0x1A, 0x41, 0xC2, + 0xA8, 0x5F, 0x62, 0x35, 0xE5, 0x9C, 0xCB, 0x35, + 0x40, 0x51, 0x54, 0x25, 0xA6, 0xAB, 0x3D, 0x87, + 0x13, 0x58, 0x6C, 0x39, 0xEA, 0x09, 0xDE, 0xF4, + 0xD9, 0x8D, 0x55, 0xF3, 0xBF, 0x18, 0xDC, 0xD5, + 0x9E, 0xD2, 0xCE, 0x9D, 0x38, 0x99, 0x16, 0xB3, + 0x67, 0xAB, + + 0xFF, 0x15, 0x86, 0xD2, 0x9C, 0x6E, 0xBB, 0xC6, + 0x3F, 0xB4, 0x57, 0x9D, 0x0C, 0x84, 0xCF, 0xE3, + 0xAB, 0x55, 0xA6, 0x11, 0x6A, 0xBB, 0xB8, 0x3A, + 0x4C, 0x18, 0x53, 0x53, 0x54, 0xAE, 0x1F, 0x48, + 0x81, 0x98, 0x10, 0x13, 0x95, 0xE5, 0xF7, 0xC9, + 0x7A, 0xE5, 0x08, 0x3D, 0xD2, 0xE3, 0xE0, 0x63, + 0x08, 0x2C, 0x53, 0x35, 0x4A, 0xFA, 0xB1, 0x33, + 0x8C, 0xE7, 0x4B, 0xE7, 0x56, 0x9C, 0x97, 0x26, + 0xC8, 0xD7, 0x8F, 0x37, 0xF0, 0x8C, 0x69, 0x30, + 0x6C, 0x6B, 0xE9, 0x50, 0x03, 0xDC, 0xF3, 0x06, + 0x02, 0x6B, 0x73, 0x97, 0xF3, 0xC8, 0x51, 0x90, + 0x56, 0xEE, 0x6B, + + 0xD1, 0x92, 0x49, 0xBE, 0x13, 0xB9, 0x0D, 0xC3, + 0x94, 0x48, 0xF7, 0xAE, 0x8D, 0xB3, 0xCD, 0x40, + 0xBB, 0x01, 0x2F, 0x5E, 0x65, 0xBF, 0x15, 0xE7, + 0xC9, 0x23, 0xD8, 0x8A, 0x31, 0x92, 0xD4, 0x89, + 0x03, 0x92, 0x64, 0x77, 0xC4, 0x02, 0xA1, 0xC8, + 0x06, 0xA5, 0x46, 0xD8, 0x83, 0x19, 0x9B, 0x49, + 0x2C, 0x77, 0x14, 0x1C, 0x37, 0xEC, 0xBC, 0x16, + 0x16, 0x90, 0x38, 0x5D, 0x7B, 0x62, 0xC7, 0x5E, + 0xB9, 0x90, 0x4C, 0x86, 0xB1, 0x04, 0x3F, 0x9B, + 0x97, 0xFF, 0x96, 0x96, 0xF8, 0x8C, 0xED, 0x30, + 0x29, 0x97, 0xCE, 0x39, 0x08, 0xEA, 0xCE, 0xEC, + 0xE4, 0xD5, 0x97, 0x80, + + 0xED, 0x40, 0x76, 0x4D, 0x2A, 0x83, 0x9E, 0xB9, + 0x0E, 0xA6, 0x9B, 0xFF, 0x43, 0xD3, 0x57, 0x22, + 0xA1, 0xE5, 0x19, 0x44, 0x8A, 0x2C, 0x2B, 0xA5, + 0xE0, 0x58, 0x00, 0xEA, 0xDE, 0xD7, 0x77, 0x95, + 0x98, 0x02, 0x43, 0xC8, 0xAC, 0x9E, 0x10, 0x49, + 0xDD, 0xFC, 0x0D, 0x6B, 0x69, 0x0C, 0x5F, 0xA6, + 0xBC, 0x11, 0xCB, 0xB0, 0x40, 0x8C, 0xFD, 0xFD, + 0x28, 0xEF, 0xEB, 0xAC, 0x73, 0xCD, 0x15, 0x74, + 0x49, 0x08, 0x5F, 0xE5, 0xCA, 0x39, 0x3E, 0x07, + 0xAB, 0xF0, 0xE8, 0xC3, 0x6F, 0xEC, 0x41, 0x50, + 0x29, 0x5A, 0xF8, 0xD8, 0x95, 0x68, 0x77, 0xA9, + 0x31, 0x9A, 0x5E, 0xB7, 0xFD, + + 0x4E, 0xB1, 0x03, 0x95, 0xE6, 0x22, 0x49, 0x89, + 0xDE, 0x26, 0x73, 0x65, 0x0B, 0xE2, 0x85, 0xA1, + 0xC5, 0x15, 0x5B, 0x5F, 0x8D, 0xC8, 0xB3, 0x15, + 0xCB, 0x39, 0xD8, 0xD8, 0x12, 0xEF, 0x83, 0x89, + 0x02, 0x81, 0x5A, 0x36, 0xB4, 0xAF, 0xE0, 0xA4, + 0xE3, 0x1E, 0x72, 0xB6, 0x80, 0x1A, 0xCA, 0xB9, + 0xF8, 0x64, 0x80, 0x62, 0x55, 0xA3, 0x50, 0x6F, + 0xD0, 0x4C, 0x37, 0xFC, 0xFE, 0x8D, 0xC6, 0xFE, + 0xD9, 0x6A, 0x6A, 0x1E, 0x44, 0x35, 0xCF, 0x6A, + 0x1F, 0xDC, 0x86, 0x22, 0x74, 0x5D, 0xC9, 0x6A, + 0xFA, 0x32, 0x12, 0xB3, 0x12, 0x8A, 0x9D, 0x29, + 0x6A, 0xB0, 0x10, 0x73, 0xF3, 0xAF, + + 0xAF, 0x25, 0xCA, 0x2F, 0xCC, 0xAC, 0xEB, 0x64, + 0x67, 0xCA, 0x4A, 0xC6, 0xE6, 0x6C, 0x98, 0xC8, + 0xB9, 0x12, 0xCF, 0xCD, 0x56, 0xC1, 0x01, 0x32, + 0x36, 0xEB, 0xE5, 0x58, 0xAC, 0xEC, 0x2D, 0xA6, + 0xF9, 0x95, 0x84, 0xD9, 0x21, 0x13, 0x81, 0xE7, + 0x8B, 0x46, 0x34, 0x3E, 0x29, 0xD7, 0x02, 0xAE, + 0xC7, 0x45, 0x38, 0xC1, 0x69, 0x70, 0xE9, 0x38, + 0x2C, 0x9D, 0x0F, 0xE1, 0x32, 0x48, 0x74, 0x65, + 0x8A, 0x20, 0x50, 0x2A, 0x5C, 0xF9, 0x6F, 0xD7, + 0xAC, 0x8A, 0xFB, 0x63, 0x24, 0x09, 0x6F, 0x9F, + 0xC0, 0x19, 0xA9, 0x84, 0x53, 0x2E, 0x4F, 0x25, + 0x22, 0x19, 0x99, 0x6D, 0x63, 0xD6, 0x2F, + + 0x06, 0x07, 0xEB, 0x05, 0xA8, 0x83, 0xC7, 0xFC, + 0x5B, 0x09, 0xBF, 0x80, 0xC9, 0x86, 0x1C, 0x98, + 0xDD, 0x25, 0xE9, 0xDB, 0x66, 0xC5, 0x49, 0x4F, + 0xF0, 0x12, 0xD6, 0x73, 0x04, 0xD7, 0x1B, 0xC6, + 0xFF, 0xEB, 0xB7, 0x34, 0x09, 0x74, 0x96, 0xB4, + 0xDD, 0xB2, 0x52, 0x3E, 0xB2, 0xDC, 0x9D, 0x4D, + 0x12, 0x77, 0x7C, 0x5B, 0xB1, 0x2D, 0x18, 0x35, + 0xD0, 0xCF, 0x22, 0x40, 0x2B, 0xEF, 0x91, 0x28, + 0xDC, 0x4A, 0xF8, 0xB3, 0xAE, 0x22, 0x7B, 0x9D, + 0x1C, 0x92, 0x19, 0xD2, 0x3E, 0x7D, 0xAF, 0xD5, + 0x31, 0x95, 0xB0, 0x9A, 0x52, 0xD2, 0xFE, 0x3F, + 0x23, 0x37, 0x22, 0xF5, 0xC6, 0xC4, 0x41, 0xCC, + + 0x67, 0x3B, 0x8B, 0xB9, 0x68, 0x4C, 0x7A, 0x96, + 0xA1, 0xB1, 0x89, 0x79, 0x49, 0x24, 0xC4, 0x12, + 0x42, 0x1A, 0x78, 0x6F, 0xE2, 0x7F, 0xB4, 0x92, + 0xCD, 0xC0, 0xAD, 0xF5, 0x2D, 0x87, 0x6D, 0x22, + 0x18, 0xFC, 0xCE, 0x69, 0xAA, 0xD8, 0x01, 0x2D, + 0x49, 0x64, 0x3C, 0x24, 0xEE, 0xFF, 0xCA, 0x32, + 0x34, 0xF5, 0x09, 0x5E, 0x90, 0x50, 0x35, 0xEB, + 0xB8, 0x2D, 0x16, 0x10, 0xAD, 0x38, 0x30, 0x3D, + 0x97, 0x07, 0xD0, 0x99, 0xCF, 0xF0, 0xA8, 0xBB, + 0x21, 0xB0, 0x54, 0xCB, 0x56, 0xC6, 0x72, 0x96, + 0x22, 0x58, 0x9A, 0x10, 0xAE, 0xA5, 0xD5, 0x52, + 0x0F, 0xB6, 0x3C, 0xF3, 0x16, 0x59, 0x3F, 0x46, + 0x56, + + 0xC3, 0xFC, 0x2F, 0xDE, 0xBC, 0xC5, 0xF4, 0xB3, + 0x17, 0x21, 0x88, 0xF7, 0xAB, 0x80, 0x06, 0x7A, + 0x36, 0x20, 0x97, 0x8A, 0x71, 0x16, 0xB9, 0x38, + 0xCF, 0x0E, 0x91, 0xC2, 0x4E, 0x38, 0x99, 0xC8, + 0x5B, 0xAA, 0xC0, 0xFC, 0xD4, 0x48, 0x85, 0x3F, + 0x41, 0xF0, 0x0A, 0x17, 0x2E, 0x32, 0xD3, 0xD4, + 0xF4, 0x43, 0xDE, 0x00, 0x0D, 0xE0, 0xA5, 0x81, + 0x2B, 0xB9, 0xF3, 0x9D, 0xE4, 0xA9, 0x29, 0xF1, + 0x25, 0x1F, 0x44, 0x7C, 0xBC, 0x84, 0xEA, 0xA1, + 0x39, 0xA3, 0x2F, 0x16, 0x7B, 0xEB, 0x47, 0xF6, + 0x33, 0x53, 0xD4, 0x4D, 0xFE, 0x63, 0x72, 0x4E, + 0x32, 0x72, 0x87, 0x1A, 0xA8, 0x94, 0x56, 0x7B, + 0xC0, 0x6E, + + 0xB9, 0x69, 0x4D, 0x32, 0x87, 0xD6, 0xC6, 0x8B, + 0xEC, 0xA1, 0xDF, 0xF8, 0x58, 0xB4, 0xCD, 0xCE, + 0x1E, 0xC5, 0x37, 0x4E, 0x9B, 0x77, 0x8F, 0x8A, + 0xEB, 0x89, 0x03, 0x4A, 0xA0, 0x0F, 0x51, 0x3C, + 0x6C, 0x1B, 0x14, 0x7D, 0x0D, 0x1D, 0xBF, 0xA1, + 0x8D, 0x59, 0x48, 0xA7, 0x95, 0x24, 0xED, 0x09, + 0x8D, 0xDF, 0x89, 0xCA, 0x80, 0xB7, 0x2D, 0x0D, + 0x71, 0xC7, 0x73, 0xFA, 0xB0, 0xFE, 0x70, 0xCE, + 0xEA, 0xA2, 0x53, 0x23, 0x07, 0x41, 0x5B, 0x75, + 0x44, 0x93, 0x0A, 0x36, 0xB3, 0x5A, 0x6C, 0xBD, + 0xDA, 0x66, 0x43, 0x55, 0x3C, 0x87, 0xC2, 0x8E, + 0x51, 0xA3, 0x28, 0xFB, 0xFB, 0x5F, 0x8E, 0x82, + 0xA9, 0x60, 0x5D, + + 0x7E, 0x26, 0x4B, 0x2B, 0x10, 0x93, 0x82, 0xAC, + 0x0B, 0x01, 0x88, 0x29, 0x90, 0x43, 0xA7, 0xAE, + 0xC5, 0xDE, 0xC6, 0xAB, 0x67, 0x49, 0x45, 0x6B, + 0x30, 0x5F, 0x87, 0x59, 0x4D, 0xB2, 0xE0, 0x8B, + 0xEC, 0x9F, 0x9D, 0xB6, 0x5E, 0x1A, 0xA8, 0xE8, + 0xB2, 0xF5, 0xC4, 0xDB, 0xC1, 0x39, 0xC6, 0xF4, + 0x85, 0xE8, 0x59, 0x19, 0xE8, 0xE8, 0xAA, 0xE6, + 0xA7, 0xE1, 0x66, 0x1B, 0x9A, 0xE3, 0x7C, 0xCE, + 0x5A, 0x7A, 0x3B, 0x32, 0x38, 0x89, 0x60, 0x6B, + 0xB8, 0xD9, 0xA1, 0xE2, 0x33, 0x62, 0xDA, 0xED, + 0xC0, 0xAF, 0x10, 0x23, 0xCA, 0xD5, 0x18, 0x5F, + 0x4F, 0xAC, 0x07, 0x02, 0x5D, 0x62, 0x4B, 0xCF, + 0x89, 0x5D, 0xB6, 0x8F, + + 0x4F, 0xB9, 0xC8, 0xBB, 0x61, 0x38, 0x62, 0xC0, + 0x7E, 0xDA, 0xBB, 0x97, 0x1F, 0x14, 0x93, 0x3D, + 0x56, 0x14, 0x06, 0xA0, 0xDA, 0xA6, 0x2F, 0x8D, + 0x61, 0xC6, 0xD3, 0x70, 0x2A, 0xF2, 0xEF, 0xD6, + 0x97, 0x81, 0x1B, 0x18, 0xCB, 0x5D, 0x3F, 0xC0, + 0xAB, 0xF1, 0xE8, 0x16, 0x59, 0xA3, 0x9E, 0xDC, + 0x59, 0x0D, 0x5D, 0x1C, 0x51, 0x81, 0xF6, 0x1A, + 0x12, 0x0C, 0xF7, 0xE3, 0xF0, 0x6E, 0x8D, 0x89, + 0x8D, 0xED, 0x1F, 0xE7, 0x4E, 0xE9, 0xB0, 0x9A, + 0x04, 0xB2, 0x9F, 0xB5, 0x05, 0xBB, 0xE2, 0x70, + 0x4F, 0x9F, 0x86, 0x03, 0x86, 0x9C, 0xE9, 0x63, + 0x8B, 0xA5, 0x8B, 0xFC, 0xD3, 0xF4, 0x24, 0xE1, + 0xE2, 0x46, 0xEB, 0x77, 0x2C, + + 0xD3, 0xE2, 0xB1, 0xBF, 0xE6, 0x28, 0xA2, 0x19, + 0x09, 0x7C, 0xE5, 0xDE, 0x6C, 0x07, 0x79, 0x55, + 0x36, 0xD2, 0x39, 0x8B, 0x1C, 0x1E, 0xBB, 0x67, + 0xF6, 0xE9, 0xA5, 0xD6, 0xCE, 0x83, 0x47, 0xFC, + 0x2D, 0x5D, 0xF3, 0x9D, 0xA8, 0x98, 0x78, 0x2B, + 0x2A, 0x4B, 0x1C, 0xC8, 0x7F, 0x45, 0x3F, 0x58, + 0x01, 0x35, 0xE4, 0x5C, 0xF8, 0xEE, 0x27, 0xC6, + 0x53, 0x88, 0x4B, 0x96, 0xDA, 0xBF, 0x57, 0x37, + 0x45, 0x2F, 0x4B, 0xDC, 0x57, 0x74, 0xD9, 0x69, + 0x15, 0x94, 0x60, 0x45, 0x72, 0xFA, 0x52, 0x05, + 0x2B, 0xA5, 0xF2, 0x85, 0x6F, 0x3C, 0xF6, 0xF1, + 0xF8, 0x4A, 0xAF, 0xF4, 0xC3, 0x0D, 0x6A, 0x8C, + 0xF3, 0xBC, 0x6A, 0x07, 0x02, 0x15, + + 0xBE, 0x63, 0x59, 0xA9, 0x6D, 0x8D, 0x63, 0xB4, + 0x80, 0xB1, 0xEA, 0xCD, 0x8B, 0xB3, 0x98, 0x8A, + 0x63, 0xF3, 0x0C, 0xD6, 0x93, 0xC0, 0x9E, 0x88, + 0x33, 0x19, 0x0F, 0xC0, 0xF0, 0xFE, 0xCC, 0x33, + 0xC7, 0xC5, 0xF0, 0xD6, 0x73, 0x6D, 0x57, 0xA4, + 0x4C, 0x49, 0x20, 0x10, 0x99, 0x68, 0x73, 0x99, + 0x38, 0xE9, 0x25, 0x11, 0x8B, 0xE1, 0xC8, 0x90, + 0x13, 0x6A, 0x96, 0x0F, 0x82, 0x23, 0xFD, 0x5E, + 0x71, 0x8D, 0x6E, 0xA4, 0x37, 0x7C, 0x35, 0xC6, + 0x37, 0xD3, 0xC8, 0xBE, 0x4B, 0x59, 0x94, 0xE2, + 0x5C, 0x70, 0xEB, 0x62, 0xC5, 0xF1, 0x7E, 0x63, + 0x02, 0xCE, 0xE4, 0x07, 0x38, 0x2E, 0x8F, 0x63, + 0x8D, 0xAC, 0xBB, 0x93, 0xAB, 0x8D, 0x71, + + 0x52, 0xBD, 0xA1, 0x06, 0x3C, 0x94, 0x40, 0x14, + 0x24, 0x66, 0x94, 0x84, 0x7F, 0x92, 0x07, 0x8C, + 0x02, 0xB4, 0x9A, 0x9D, 0x77, 0x91, 0xDC, 0xEC, + 0x69, 0xC6, 0x9F, 0xD5, 0x89, 0xDE, 0x3A, 0x55, + 0xF1, 0x8C, 0x2D, 0xAD, 0xBE, 0x56, 0x1B, 0x88, + 0x4D, 0xE1, 0x88, 0x8A, 0xEF, 0xFB, 0x2B, 0x1A, + 0xE0, 0xEF, 0xF3, 0x79, 0xED, 0x25, 0x23, 0xF3, + 0xAA, 0x1B, 0xE1, 0xF6, 0xB3, 0x0E, 0xC4, 0xA7, + 0x02, 0xBB, 0xCC, 0x25, 0x08, 0x67, 0x75, 0x23, + 0xE6, 0x0D, 0x5E, 0x4E, 0xE9, 0x00, 0xB3, 0xA8, + 0x7F, 0xB3, 0x42, 0x08, 0x7B, 0x36, 0xC8, 0x4A, + 0x67, 0xCA, 0xC3, 0x8E, 0xEC, 0x62, 0xB3, 0xA1, + 0x2E, 0x8A, 0xB6, 0x60, 0xE0, 0xD6, 0x38, 0xA9, + + 0x9E, 0x06, 0x4A, 0xB5, 0x71, 0xD7, 0x33, 0x84, + 0x95, 0x9C, 0x5F, 0xF8, 0x12, 0x0D, 0x46, 0xFA, + 0xE5, 0x67, 0x31, 0xE2, 0x71, 0xDC, 0xB6, 0xB4, + 0xE1, 0x3B, 0x16, 0x28, 0xE5, 0x04, 0x20, 0x90, + 0xC1, 0x70, 0xB3, 0x1C, 0x93, 0xF6, 0x6E, 0xC8, + 0x42, 0x8A, 0xAC, 0x85, 0x67, 0xB5, 0xAE, 0x74, + 0x78, 0xFA, 0x32, 0x4B, 0x0D, 0x74, 0x3B, 0x38, + 0xF9, 0x31, 0x01, 0xDA, 0x65, 0xE1, 0xBA, 0x5B, + 0x47, 0xE5, 0xCE, 0x58, 0xC6, 0x16, 0x6D, 0xC2, + 0x56, 0xB7, 0x9B, 0x43, 0x0B, 0x81, 0x65, 0xDD, + 0xF5, 0xB9, 0x44, 0x93, 0x06, 0xD6, 0x07, 0x8B, + 0xDF, 0xE7, 0x1F, 0x14, 0xD6, 0x04, 0x4F, 0xFD, + 0x47, 0x67, 0xEB, 0xBF, 0x23, 0xEB, 0xA7, 0xEE, + 0xB0, + + 0x31, 0xCF, 0x75, 0x5F, 0xFF, 0xBD, 0xB1, 0xE7, + 0x04, 0xBF, 0x32, 0x3F, 0x80, 0x8C, 0x1A, 0xCF, + 0x78, 0xF2, 0x95, 0x2B, 0x4B, 0xEF, 0x30, 0xDF, + 0xE4, 0x49, 0x04, 0xF3, 0x82, 0x11, 0x30, 0x6B, + 0x30, 0x3C, 0xAA, 0x9B, 0x1F, 0xDB, 0xFA, 0xDA, + 0xC3, 0x79, 0x88, 0x1F, 0x4C, 0x06, 0x7E, 0xE5, + 0x89, 0x04, 0x78, 0x7C, 0x0B, 0xA0, 0x2D, 0x50, + 0x88, 0xD4, 0xA8, 0x3C, 0x4D, 0x9F, 0x85, 0x9E, + 0x6A, 0x0C, 0xC6, 0x75, 0xE5, 0x02, 0x19, 0x64, + 0xA6, 0x64, 0x21, 0x76, 0x2F, 0x2E, 0xBC, 0xDA, + 0xF0, 0xDD, 0x19, 0xCE, 0xB1, 0xB6, 0x35, 0x3F, + 0x6B, 0x3F, 0xCF, 0xFD, 0x71, 0x2E, 0x0C, 0x4B, + 0x8B, 0x4D, 0x26, 0xDA, 0x06, 0x46, 0xE3, 0x68, + 0xBA, 0x22, + + 0xA3, 0x90, 0x81, 0xE3, 0xBA, 0x9C, 0x12, 0x57, + 0xE3, 0x53, 0x6E, 0x90, 0x2F, 0xD4, 0x6B, 0x23, + 0x58, 0xCD, 0x1C, 0xBD, 0x6F, 0x8B, 0x16, 0x0C, + 0x40, 0x41, 0x47, 0x86, 0xA4, 0xA2, 0x90, 0x6C, + 0x81, 0x8B, 0x51, 0x53, 0xC8, 0x9A, 0xF4, 0x4F, + 0x04, 0xB0, 0xF3, 0xE2, 0xDE, 0x73, 0x17, 0x3B, + 0xB3, 0xDB, 0x61, 0xFB, 0xBD, 0xC8, 0xBB, 0x13, + 0x8A, 0xE9, 0xB0, 0x5D, 0x38, 0x5F, 0x3F, 0x7A, + 0xDC, 0xB2, 0x25, 0xB7, 0x0B, 0xBD, 0xC6, 0xD6, + 0x8F, 0x15, 0xD5, 0x17, 0x2E, 0x84, 0xD0, 0xA6, + 0xA8, 0x72, 0xEA, 0x2D, 0x2C, 0xE9, 0x31, 0x8D, + 0x22, 0x6B, 0x0F, 0xD8, 0x36, 0x70, 0x3C, 0x11, + 0xBE, 0x32, 0x2D, 0xB1, 0x14, 0xCD, 0x90, 0x18, + 0x99, 0xCA, 0x01, + + 0xA9, 0x3C, 0xC6, 0x55, 0x5C, 0xA3, 0x2C, 0x02, + 0x51, 0xB8, 0x98, 0xF0, 0xDE, 0xF3, 0x51, 0x7A, + 0x1F, 0x6C, 0xA1, 0xCD, 0x15, 0xCB, 0x3B, 0x3A, + 0x7E, 0xD5, 0x3E, 0xF0, 0xD5, 0xE4, 0x6F, 0x30, + 0x3C, 0x1F, 0x92, 0x65, 0xEE, 0x40, 0xAC, 0x8F, + 0x8A, 0xA5, 0x5D, 0x26, 0x38, 0xCE, 0x02, 0xDE, + 0xA4, 0xF6, 0xC1, 0xB5, 0x53, 0x7B, 0x37, 0x40, + 0x38, 0xC6, 0x31, 0x9B, 0x3F, 0x72, 0x0D, 0x91, + 0x46, 0xD9, 0xE3, 0x17, 0xAD, 0x07, 0x1D, 0xDE, + 0x69, 0xF9, 0xBD, 0x72, 0x1E, 0x4E, 0x68, 0x4E, + 0x16, 0x48, 0xAD, 0xEA, 0x9C, 0x18, 0x70, 0xDF, + 0x7E, 0x38, 0x4F, 0x68, 0xC5, 0xE2, 0xA1, 0x09, + 0x5E, 0x5F, 0x42, 0x75, 0x66, 0x20, 0xE6, 0xE3, + 0x1F, 0xAC, 0x76, 0x6D, + + 0xCE, 0x61, 0xD7, 0xE9, 0x85, 0xCF, 0xEF, 0xDC, + 0x2D, 0x75, 0x04, 0x60, 0x76, 0xF1, 0x4E, 0xE9, + 0x72, 0xD3, 0x2E, 0x6A, 0x5A, 0x81, 0xB0, 0xAF, + 0x29, 0x05, 0xAF, 0x9C, 0xEF, 0xF1, 0xF3, 0x96, + 0x97, 0x10, 0xCA, 0x15, 0xA9, 0x73, 0x44, 0xFC, + 0x61, 0x0D, 0x2E, 0xE5, 0x1A, 0x3B, 0x24, 0x5E, + 0x04, 0xAE, 0x5B, 0xCA, 0x40, 0xEC, 0x4B, 0x92, + 0xD8, 0x7C, 0x3F, 0x0B, 0x69, 0x9B, 0x3C, 0xC4, + 0x9E, 0x80, 0x3C, 0x2B, 0xB1, 0x39, 0xFB, 0xC6, + 0x8A, 0x65, 0x98, 0x1A, 0x53, 0xE1, 0x31, 0x90, + 0xE6, 0x26, 0x43, 0x73, 0x07, 0xAD, 0x80, 0xD9, + 0x4C, 0xC0, 0x0E, 0x5F, 0xE7, 0x6D, 0x0B, 0xEB, + 0xD1, 0x16, 0x0A, 0x57, 0xFB, 0x49, 0xF5, 0xA0, + 0x96, 0x6E, 0x9A, 0xB0, 0x82, + + 0xC7, 0x84, 0x16, 0x76, 0x54, 0xAE, 0x96, 0x80, + 0x66, 0x9E, 0xCF, 0xB2, 0x49, 0x57, 0x8B, 0x32, + 0xDA, 0x1C, 0xCD, 0xD1, 0xA7, 0x44, 0x52, 0x19, + 0x5A, 0x77, 0x8D, 0x9D, 0x89, 0xC4, 0x84, 0xD0, + 0x2D, 0xFB, 0x8D, 0xB5, 0xCD, 0x63, 0x48, 0x6E, + 0x18, 0x49, 0x1B, 0xFA, 0x48, 0xD5, 0x32, 0xBB, + 0x85, 0x0A, 0x90, 0xBC, 0x6C, 0xAF, 0x5D, 0x6F, + 0xAC, 0x34, 0xF9, 0xC6, 0x59, 0x85, 0xE8, 0xC2, + 0xA2, 0xA4, 0x9F, 0x77, 0xE4, 0x00, 0xEE, 0x94, + 0xD9, 0x57, 0xEC, 0x31, 0x7E, 0x0F, 0xB1, 0xD2, + 0xD5, 0xA5, 0x1A, 0xBE, 0x0C, 0xC2, 0x85, 0x7B, + 0x5E, 0xCD, 0xD0, 0xB6, 0x1E, 0x04, 0x86, 0xEF, + 0x84, 0x74, 0x6B, 0x97, 0x5D, 0x6B, 0x5C, 0x63, + 0x81, 0x50, 0x6F, 0x4F, 0x8E, 0x1B, + + 0xC7, 0x9C, 0x57, 0x9D, 0xE5, 0x46, 0x4F, 0xC1, + 0x4A, 0x03, 0x63, 0x2E, 0x35, 0x1B, 0x35, 0x9D, + 0xD3, 0xA7, 0xB5, 0xDC, 0xCD, 0x58, 0xEB, 0x25, + 0x52, 0x9E, 0xC0, 0xB3, 0x19, 0x85, 0x11, 0x65, + 0x14, 0x8A, 0x27, 0x0F, 0xDD, 0xB5, 0x06, 0xCE, + 0x9A, 0x1A, 0xD8, 0xB5, 0x07, 0x63, 0x24, 0x5F, + 0xD2, 0xBC, 0x79, 0xB8, 0x62, 0x45, 0x10, 0xBC, + 0x65, 0x00, 0x22, 0x94, 0x83, 0x60, 0x62, 0xF3, + 0x13, 0xE1, 0xD0, 0x5D, 0x47, 0xD8, 0xCB, 0x2C, + 0x59, 0x60, 0x9D, 0x8F, 0x9A, 0x49, 0x7F, 0x60, + 0x71, 0x85, 0xA5, 0x53, 0xCE, 0x55, 0x72, 0x30, + 0x89, 0xD6, 0x74, 0x5B, 0xEE, 0xAF, 0x48, 0x60, + 0x1C, 0x0A, 0xD0, 0x56, 0x54, 0xC5, 0x40, 0x1B, + 0x1F, 0x94, 0xAE, 0x5E, 0x45, 0x60, 0x59, + + 0xD1, 0x73, 0xAA, 0xD6, 0x76, 0x3F, 0x35, 0xDE, + 0x77, 0x82, 0x96, 0xFF, 0x1B, 0x34, 0xAD, 0x16, + 0x77, 0x73, 0xD7, 0x8A, 0x96, 0x19, 0xA0, 0xBA, + 0x22, 0x71, 0x36, 0x9D, 0xAC, 0x41, 0x14, 0xAB, + 0xA8, 0x77, 0x34, 0x7A, 0x70, 0x2A, 0xF6, 0xF6, + 0xEA, 0xFD, 0x6D, 0xDB, 0xAD, 0x65, 0x14, 0x3A, + 0xEA, 0x0E, 0x2C, 0xC4, 0xC1, 0x13, 0x7D, 0x59, + 0x8D, 0xE8, 0x61, 0x29, 0x50, 0x61, 0xC3, 0xC9, + 0x76, 0x20, 0x7C, 0xEF, 0x09, 0xA8, 0xC3, 0x8E, + 0x11, 0xD2, 0x3F, 0x32, 0x09, 0x61, 0x91, 0xF8, + 0x60, 0xF6, 0x83, 0x93, 0x08, 0x94, 0xBF, 0x5D, + 0x6E, 0xDE, 0xA1, 0x04, 0xEE, 0xB2, 0xE3, 0x10, + 0x1D, 0x22, 0xF0, 0xF8, 0x4E, 0x5C, 0xF5, 0x9B, + 0x86, 0x44, 0x57, 0x28, 0xB7, 0x8C, 0x81, 0x14, + + 0x31, 0xDF, 0xA5, 0xD5, 0xF6, 0x17, 0x19, 0x50, + 0xA3, 0x0F, 0x26, 0x1C, 0xD4, 0x98, 0xCA, 0xB0, + 0xDB, 0x0C, 0x2F, 0x8C, 0xCE, 0xCC, 0x56, 0x35, + 0x57, 0xC2, 0x9D, 0xEF, 0x64, 0x82, 0xE4, 0x8A, + 0xFA, 0xFE, 0x07, 0xF1, 0xB7, 0x10, 0xDF, 0x56, + 0x7B, 0x64, 0x88, 0x9C, 0x25, 0xF1, 0x6D, 0x6C, + 0x5F, 0xD3, 0xC8, 0xC4, 0x7E, 0xD5, 0x26, 0xB8, + 0xC3, 0xDD, 0xAD, 0x85, 0x3E, 0xA0, 0x5C, 0x33, + 0x25, 0x9A, 0xD9, 0x52, 0xB7, 0x8C, 0x22, 0x3F, + 0x96, 0xD4, 0x51, 0x7C, 0x9F, 0xAD, 0x01, 0x81, + 0xBE, 0x95, 0x90, 0x38, 0x90, 0xDD, 0x81, 0x43, + 0xB0, 0x66, 0x0D, 0x4E, 0x9E, 0xF6, 0x0C, 0x13, + 0x47, 0xA5, 0xA0, 0x1F, 0x94, 0xFB, 0x86, 0x42, + 0x8B, 0x9B, 0x22, 0x25, 0xF2, 0xB8, 0x83, 0x3C, + 0x87, + + 0x06, 0xFA, 0x95, 0x25, 0x62, 0x35, 0x4D, 0x06, + 0x3F, 0xD2, 0xAE, 0x4E, 0x86, 0x32, 0x08, 0x54, + 0x78, 0x35, 0xAD, 0x84, 0xE1, 0x6D, 0xB1, 0x5E, + 0xD0, 0x91, 0x42, 0x02, 0x39, 0x1F, 0x0D, 0x4C, + 0xE5, 0x4B, 0xDB, 0x9D, 0x1A, 0xE5, 0x05, 0x97, + 0x90, 0x0F, 0xB4, 0xCD, 0xC5, 0xF7, 0xDA, 0x81, + 0xC7, 0x22, 0x25, 0xB8, 0xAA, 0xC5, 0xA6, 0x6C, + 0xCD, 0x21, 0xC3, 0xCA, 0xFA, 0xDB, 0x0C, 0xDC, + 0x35, 0x7B, 0x49, 0x2E, 0xC9, 0xD4, 0xDC, 0x2C, + 0xF5, 0x2A, 0x3E, 0xBA, 0x93, 0x52, 0x88, 0x73, + 0x4B, 0x3A, 0x1E, 0x5B, 0x37, 0xE4, 0x54, 0x8E, + 0xE7, 0x3C, 0x78, 0x37, 0xBA, 0x31, 0x09, 0x3A, + 0xE0, 0x36, 0xFF, 0x6C, 0x7D, 0xA9, 0x68, 0x0F, + 0x33, 0xCD, 0x1B, 0x7E, 0xD0, 0x12, 0x98, 0xC7, + 0xC6, 0x9E, + + 0x59, 0xBC, 0xD3, 0x93, 0xD5, 0x73, 0x5C, 0x4F, + 0xCD, 0x32, 0x8C, 0xA7, 0xEC, 0xB1, 0x92, 0x82, + 0xFF, 0x08, 0x94, 0xED, 0xCE, 0x65, 0x7E, 0xDD, + 0x28, 0x65, 0xEA, 0xDB, 0x3B, 0x77, 0x87, 0x41, + 0x5A, 0xE7, 0xE4, 0x4F, 0x5D, 0xC6, 0x8E, 0xB7, + 0xD5, 0x83, 0x5A, 0xA4, 0x1B, 0xE5, 0x40, 0x50, + 0xA1, 0x0E, 0xB3, 0x8F, 0xE3, 0x31, 0x87, 0xD8, + 0xBF, 0xD9, 0xBE, 0x07, 0x68, 0x9F, 0xAF, 0xD5, + 0x5A, 0xB3, 0xEB, 0x4B, 0x59, 0x0E, 0xDA, 0x36, + 0xE8, 0xCE, 0x29, 0x5A, 0x9D, 0x68, 0xF7, 0x40, + 0xAD, 0xD4, 0x4C, 0xEC, 0xD3, 0xB1, 0xF8, 0x13, + 0x5B, 0x4B, 0x9A, 0xE9, 0x7A, 0x19, 0x37, 0x21, + 0x35, 0x2F, 0x01, 0xE3, 0xF0, 0x7E, 0xF4, 0x80, + 0x3E, 0xBF, 0xB0, 0xDB, 0xB8, 0x5B, 0x46, 0xBF, + 0x81, 0xB2, 0x6D, + + 0xE6, 0x27, 0x7B, 0xD7, 0x3A, 0x57, 0x4A, 0x57, + 0x1F, 0x16, 0x60, 0x67, 0xE3, 0xCB, 0x95, 0x54, + 0x52, 0x0F, 0xD3, 0xF8, 0x2E, 0x4E, 0xFE, 0xAC, + 0x98, 0x99, 0x14, 0x6E, 0x24, 0x91, 0x5A, 0x2C, + 0xA1, 0xDE, 0x40, 0xBB, 0x2E, 0x59, 0x23, 0x98, + 0xCE, 0x15, 0x9A, 0xDC, 0x0D, 0x1B, 0xB2, 0xC4, + 0x6C, 0xC3, 0x23, 0xBE, 0xCB, 0xF3, 0xF6, 0x67, + 0xCF, 0x10, 0x5B, 0x90, 0xEE, 0xAC, 0x62, 0x54, + 0xCA, 0x9C, 0xD4, 0xD4, 0x83, 0x41, 0x1B, 0x46, + 0xD8, 0x42, 0x0B, 0x01, 0x7B, 0xC2, 0x1B, 0xD0, + 0x6A, 0x55, 0x1D, 0x2F, 0x2D, 0xF3, 0x63, 0xCD, + 0xAC, 0xCB, 0x30, 0xF0, 0x95, 0x7C, 0x9E, 0x37, + 0xA8, 0x37, 0x42, 0xA5, 0xAC, 0xCC, 0xA2, 0xFD, + 0x6E, 0x90, 0x0B, 0x64, 0x50, 0x38, 0x72, 0x7A, + 0x0B, 0x7E, 0x50, 0xFF, + + 0xAF, 0xB6, 0xBB, 0x4A, 0x9E, 0x62, 0xFB, 0xD7, + 0xDA, 0x69, 0xA1, 0x60, 0x20, 0x32, 0xE6, 0x56, + 0xA1, 0x6F, 0x37, 0xCA, 0x2D, 0x23, 0xBC, 0x39, + 0xED, 0xEF, 0xB7, 0xEE, 0x47, 0x4E, 0xCB, 0x46, + 0xD3, 0xCA, 0x19, 0xF6, 0x58, 0x4C, 0x31, 0x2B, + 0x65, 0xD6, 0xBC, 0x74, 0x21, 0x05, 0xD7, 0x99, + 0x96, 0x8F, 0x47, 0xE4, 0xD8, 0x4B, 0xD1, 0x60, + 0x27, 0x2E, 0x9B, 0xBF, 0x22, 0xC4, 0xAC, 0x37, + 0xDB, 0x41, 0x61, 0xF6, 0xA7, 0x25, 0x4B, 0xC6, + 0x75, 0x97, 0x0B, 0x17, 0xCB, 0x49, 0x60, 0x5A, + 0x3E, 0xB6, 0xD7, 0x88, 0x8D, 0x02, 0x89, 0xB3, + 0xB0, 0xCC, 0x03, 0xE4, 0x6F, 0x87, 0x44, 0xFF, + 0x01, 0x6D, 0xC0, 0xC9, 0xC5, 0x78, 0x34, 0xD2, + 0x33, 0x91, 0x0D, 0x51, 0x7A, 0xD9, 0x4D, 0x68, + 0x91, 0x47, 0xAB, 0xF9, 0xA1, + + 0x7B, 0x15, 0x4A, 0xEF, 0x0F, 0xD6, 0x75, 0xB7, + 0x1B, 0x32, 0x8B, 0x31, 0xC1, 0xCD, 0x3A, 0xF8, + 0x7F, 0x2F, 0xA5, 0xBD, 0x7C, 0x5C, 0x43, 0x82, + 0x4A, 0x01, 0x3B, 0x50, 0x59, 0x74, 0xB5, 0x61, + 0x40, 0x3B, 0xC0, 0xF3, 0xA1, 0x3E, 0x75, 0x36, + 0x85, 0x74, 0xC3, 0xB3, 0x55, 0xB6, 0xAB, 0xFC, + 0xE9, 0x36, 0x9E, 0x01, 0x1E, 0xCB, 0xEA, 0x1B, + 0xB2, 0x02, 0xD8, 0x42, 0x75, 0xD7, 0x36, 0x5E, + 0x45, 0x17, 0x0E, 0xDF, 0x33, 0xEF, 0x97, 0xCE, + 0xC5, 0x1D, 0x41, 0x4A, 0x06, 0xD3, 0xA1, 0x2F, + 0x5C, 0xD6, 0x7F, 0xE1, 0x45, 0xF7, 0x69, 0xC5, + 0xFA, 0xE6, 0x88, 0x3A, 0xCB, 0x96, 0xC0, 0xA4, + 0xB7, 0x50, 0x9C, 0x67, 0xA2, 0x12, 0x85, 0xC3, + 0x0D, 0xD3, 0x0A, 0xE2, 0x58, 0xD7, 0x94, 0x42, + 0xFD, 0x3D, 0x54, 0xA7, 0x08, 0x85, + + 0x56, 0x28, 0xAF, 0x54, 0xEA, 0x3E, 0xF7, 0xCF, + 0xB9, 0x44, 0xE1, 0xB6, 0x1D, 0x0D, 0xE5, 0x3F, + 0xDF, 0x47, 0x9D, 0xE4, 0x94, 0xA0, 0xBF, 0x0E, + 0xE1, 0xC1, 0x13, 0x73, 0x0F, 0x23, 0xB1, 0xBE, + 0xC1, 0x19, 0xD5, 0x4E, 0x0D, 0x19, 0xA0, 0xD5, + 0x20, 0xDD, 0xEA, 0xA9, 0x05, 0x27, 0xF7, 0x8C, + 0x3C, 0xB3, 0x18, 0x07, 0xDC, 0x11, 0xE8, 0x60, + 0xC2, 0x61, 0x67, 0xAD, 0x0B, 0x6C, 0xA9, 0xD9, + 0x3D, 0x65, 0xE9, 0x31, 0x68, 0xFB, 0x3F, 0xDF, + 0x4B, 0x0C, 0x3B, 0xC6, 0x51, 0xE4, 0x77, 0x73, + 0x9D, 0xB5, 0x5C, 0x37, 0x3B, 0xDD, 0xAD, 0xF2, + 0xA8, 0x22, 0x98, 0x4D, 0x5F, 0x4B, 0xE6, 0xE1, + 0x0A, 0x46, 0x60, 0x0F, 0xDE, 0x02, 0xF9, 0xE6, + 0xFC, 0x3E, 0x22, 0x5D, 0x42, 0x66, 0x50, 0x60, + 0x67, 0x8C, 0x16, 0x28, 0xC4, 0x87, 0x02, + + 0x7E, 0xF5, 0xA3, 0x08, 0x91, 0x76, 0x3F, 0x65, + 0x90, 0xBF, 0xA2, 0xD7, 0x38, 0x6B, 0x41, 0x4E, + 0xC7, 0xD5, 0xBE, 0xEC, 0x60, 0xC5, 0x80, 0x3B, + 0xD6, 0x7A, 0x45, 0x4A, 0x44, 0x0F, 0xA1, 0x28, + 0xB5, 0x5C, 0x58, 0xB4, 0x2F, 0x56, 0xD3, 0xB9, + 0x43, 0x49, 0x09, 0x5E, 0xA6, 0x50, 0xFE, 0xCF, + 0x6A, 0x1D, 0x26, 0xC5, 0x4E, 0x96, 0x1A, 0xD0, + 0xBA, 0x3F, 0x8D, 0x8D, 0xB1, 0x9E, 0x13, 0x66, + 0xCB, 0x9C, 0xEC, 0x57, 0x34, 0x59, 0x7C, 0x8F, + 0xE7, 0xE4, 0x8A, 0x52, 0x77, 0x31, 0x0A, 0x7C, + 0xB2, 0xD4, 0x80, 0x89, 0xCA, 0x09, 0xAD, 0x93, + 0xBC, 0x96, 0x60, 0xBE, 0xB7, 0x92, 0xD5, 0xDA, + 0xBB, 0x2C, 0x3B, 0xF6, 0x80, 0xA1, 0xFA, 0xB7, + 0x06, 0xA9, 0x5D, 0x74, 0x16, 0x5F, 0x4D, 0xBD, + 0xDF, 0x2B, 0x45, 0xA4, 0x14, 0xBA, 0x65, 0xBF, + + 0xDB, 0xE7, 0xA9, 0x45, 0xFF, 0x17, 0xA2, 0xCE, + 0xC3, 0x98, 0x34, 0xD0, 0x2F, 0xC2, 0xC1, 0xAE, + 0x0A, 0xC0, 0x0B, 0xFF, 0x6A, 0x0D, 0xA1, 0xAB, + 0xDA, 0x0B, 0x58, 0xA0, 0x85, 0xFC, 0xF1, 0xC7, + 0x53, 0x09, 0x22, 0x4E, 0xBC, 0x0D, 0x32, 0x83, + 0x2D, 0xF9, 0x06, 0x38, 0x18, 0x55, 0xC3, 0x6D, + 0x79, 0x46, 0x9D, 0x10, 0x5F, 0x14, 0xFB, 0x02, + 0x1D, 0xAD, 0x3A, 0xB2, 0x16, 0x48, 0xB5, 0xAD, + 0xB7, 0x24, 0x59, 0x93, 0x09, 0xA3, 0xDE, 0x52, + 0xE4, 0x4E, 0x63, 0xB8, 0xF4, 0x2E, 0x04, 0x90, + 0x10, 0x70, 0xE6, 0x2D, 0xE9, 0x27, 0xEC, 0x20, + 0x28, 0xF9, 0xBB, 0xF0, 0x1B, 0xF6, 0xB1, 0xA9, + 0x74, 0x60, 0x93, 0xF9, 0x39, 0x5D, 0x45, 0x29, + 0x43, 0x7B, 0x06, 0x50, 0x4B, 0x81, 0x79, 0xC1, + 0xF4, 0xBB, 0x71, 0x60, 0xE6, 0x1F, 0x93, 0xB2, + 0x33, + + 0xA8, 0xE6, 0xE9, 0xEB, 0x5A, 0xE1, 0xDE, 0x41, + 0xE9, 0x3E, 0x93, 0x29, 0xA3, 0x8C, 0x26, 0x4C, + 0x89, 0x01, 0x48, 0x46, 0x39, 0xB7, 0x49, 0x8D, + 0xAD, 0xDB, 0x76, 0x22, 0x74, 0x1C, 0x49, 0x79, + 0x61, 0x36, 0x56, 0x16, 0x10, 0x20, 0x68, 0x5E, + 0xBF, 0x1A, 0x25, 0x87, 0x7F, 0xC6, 0xB8, 0x17, + 0xB6, 0x4F, 0x89, 0xDD, 0x6A, 0x72, 0xD8, 0xF7, + 0xDF, 0x27, 0x50, 0xBF, 0x93, 0x26, 0xFE, 0x7A, + 0xD3, 0x55, 0x54, 0xC7, 0x23, 0x18, 0xFC, 0x88, + 0x47, 0x1A, 0x58, 0x51, 0x49, 0xE7, 0xC0, 0xAB, + 0xF8, 0xC8, 0x54, 0x38, 0xE0, 0x75, 0x6B, 0x47, + 0x1D, 0x5F, 0xC2, 0x60, 0x59, 0x72, 0x92, 0x57, + 0x5C, 0x2E, 0x0D, 0xAC, 0x94, 0x9A, 0x86, 0x74, + 0xF0, 0x42, 0x98, 0x11, 0x41, 0xE8, 0x3A, 0x3F, + 0xBA, 0xE4, 0xB4, 0xB6, 0x0E, 0x85, 0x11, 0xBC, + 0xB3, 0x23, + + 0x3C, 0xD8, 0x11, 0xEC, 0xC7, 0xBB, 0xA6, 0x7C, + 0x7F, 0x06, 0x4F, 0x7E, 0xBF, 0x3F, 0xA1, 0x96, + 0x65, 0x75, 0xC4, 0xDC, 0x2C, 0x2D, 0x89, 0x6D, + 0x75, 0xCB, 0xDD, 0xB2, 0xF9, 0x4F, 0x1B, 0x4C, + 0xE7, 0xCA, 0x02, 0xA5, 0x64, 0x6A, 0xEE, 0xEF, + 0x0B, 0xDF, 0xE8, 0x79, 0x2C, 0xBA, 0x0F, 0x46, + 0x17, 0xA0, 0x45, 0x14, 0x0C, 0x99, 0x2E, 0x66, + 0x09, 0xFC, 0x17, 0xD5, 0x03, 0xA3, 0x50, 0x98, + 0x82, 0xD6, 0x1B, 0x53, 0xBE, 0x27, 0x4D, 0xB3, + 0xBD, 0xC0, 0x43, 0x81, 0x75, 0x7D, 0xCF, 0x11, + 0xC7, 0x70, 0x50, 0x01, 0x0C, 0x08, 0x2E, 0xE3, + 0x81, 0xC7, 0x04, 0x43, 0xDE, 0x6F, 0x59, 0xB7, + 0x9E, 0x82, 0x33, 0x74, 0x6D, 0xF9, 0x0A, 0xE5, + 0x69, 0x99, 0xFC, 0x54, 0x73, 0xD8, 0xC8, 0x5A, + 0x65, 0x43, 0x45, 0xE0, 0x1B, 0xF4, 0xFA, 0x80, + 0xA0, 0x86, 0x7F, + + 0xB3, 0x36, 0xBC, 0x71, 0x8B, 0x9A, 0x93, 0x81, + 0x95, 0xD8, 0x5E, 0xF8, 0xDA, 0x56, 0x9E, 0xDB, + 0xF2, 0xBE, 0xFE, 0xB0, 0x57, 0xA6, 0x85, 0x48, + 0x59, 0x72, 0xEF, 0xB4, 0xF2, 0xFD, 0x5E, 0x98, + 0x9C, 0x74, 0x84, 0x52, 0xED, 0x88, 0xFA, 0x97, + 0x5C, 0x91, 0x4E, 0x34, 0x92, 0xD3, 0xC4, 0x4C, + 0x1B, 0x2F, 0x5F, 0xC8, 0x9B, 0xF1, 0xF6, 0x60, + 0x8F, 0xA5, 0x3E, 0xEC, 0x15, 0x2F, 0xCA, 0xC6, + 0xFF, 0xB9, 0xDD, 0x3E, 0x05, 0x6F, 0xAE, 0xE2, + 0x67, 0xD7, 0xF5, 0xE6, 0x93, 0x74, 0x07, 0x54, + 0x86, 0x62, 0xA3, 0x14, 0x4B, 0x8F, 0x00, 0xEA, + 0x70, 0x29, 0x15, 0xA5, 0x05, 0x9A, 0xFE, 0xFE, + 0xF5, 0x74, 0xE7, 0x29, 0xA1, 0x2C, 0x37, 0xEF, + 0x08, 0x81, 0xE0, 0x63, 0x4C, 0x0B, 0x4C, 0xD8, + 0xAF, 0x3A, 0x13, 0x11, 0x16, 0x03, 0x5C, 0x73, + 0x74, 0x6D, 0xDB, 0xD2, + + 0x84, 0x6D, 0xEF, 0xF2, 0x61, 0x96, 0xD3, 0x49, + 0x3A, 0x6E, 0x30, 0x46, 0xB9, 0x56, 0x8A, 0x81, + 0xC0, 0xCB, 0xDF, 0x5B, 0xCD, 0x5A, 0xAE, 0xF1, + 0xA1, 0x10, 0xE7, 0x03, 0x9A, 0xAE, 0x61, 0x16, + 0x2F, 0xD0, 0x0C, 0x26, 0x7A, 0x96, 0x8E, 0x3A, + 0x97, 0x8A, 0x0A, 0xC9, 0x90, 0x7F, 0x1E, 0x98, + 0xF2, 0x17, 0x74, 0xE7, 0xD1, 0xB2, 0x7F, 0x0F, + 0xE6, 0x19, 0x80, 0x2F, 0x83, 0x22, 0x63, 0xDD, + 0x73, 0x01, 0xEB, 0xC7, 0x72, 0xC7, 0x87, 0xBA, + 0x76, 0xF2, 0x53, 0xD2, 0xDD, 0x23, 0x91, 0x4F, + 0x67, 0x6F, 0x69, 0x74, 0xB4, 0xD8, 0x24, 0x20, + 0xD8, 0x29, 0x91, 0x78, 0xD6, 0xA2, 0xE0, 0x42, + 0x4C, 0xAE, 0x3A, 0xFB, 0xAB, 0x01, 0x70, 0xCF, + 0x57, 0xE7, 0xD0, 0x17, 0xF0, 0x4E, 0x9D, 0x52, + 0x4C, 0x37, 0x25, 0xA3, 0x23, 0x16, 0x82, 0x89, + 0x40, 0x64, 0xA4, 0x0C, 0x5A, + + 0x69, 0xB0, 0x3E, 0x4F, 0x95, 0x66, 0xFD, 0x32, + 0x6D, 0x68, 0xF4, 0xDD, 0x78, 0x1D, 0x54, 0x43, + 0xD1, 0xB2, 0x50, 0x71, 0x1C, 0x48, 0xDB, 0x8E, + 0xE0, 0x58, 0x1A, 0x89, 0xE0, 0x37, 0x64, 0x76, + 0x69, 0x85, 0xB9, 0x34, 0x82, 0xA5, 0x57, 0xAE, + 0x2A, 0x03, 0x00, 0x9B, 0x97, 0xCF, 0xE1, 0x59, + 0x94, 0x74, 0x07, 0x63, 0xD9, 0x6B, 0xBC, 0x1B, + 0x03, 0xD9, 0xE4, 0x40, 0xA5, 0xCB, 0x63, 0xF4, + 0xA1, 0xBA, 0x2F, 0xCE, 0x1A, 0x8F, 0xB7, 0x5A, + 0xB9, 0xFE, 0xEF, 0x8C, 0xA6, 0x74, 0x97, 0xC0, + 0xD6, 0x80, 0xB7, 0x2F, 0x03, 0xD8, 0x9B, 0x6E, + 0x36, 0x5D, 0xCC, 0x92, 0x21, 0x6E, 0xB8, 0x02, + 0xFA, 0xF9, 0xEA, 0x24, 0xA0, 0x3F, 0xDA, 0x2A, + 0xD9, 0x43, 0x1C, 0x07, 0xF2, 0x0A, 0x2C, 0x75, + 0x3D, 0x42, 0xDB, 0xEA, 0x33, 0xAB, 0x9D, 0x95, + 0xBE, 0x53, 0xF6, 0xAC, 0x56, 0xEB, + + 0x80, 0x25, 0xA8, 0x28, 0x34, 0x43, 0x8F, 0xDB, + 0xE4, 0xB8, 0x7A, 0x84, 0xE3, 0x12, 0x2E, 0xD3, + 0x28, 0x14, 0xFE, 0x42, 0x90, 0x95, 0x26, 0x2B, + 0xA1, 0x19, 0x69, 0x23, 0xCF, 0x9D, 0x91, 0xF4, + 0xD4, 0xF3, 0x3A, 0xCF, 0xA0, 0x61, 0x3E, 0x91, + 0xBF, 0xEE, 0x5B, 0xF8, 0x4E, 0xBE, 0xA0, 0x0A, + 0xAB, 0xBC, 0xE4, 0x6A, 0x11, 0x45, 0x20, 0xEA, + 0x3B, 0x29, 0xB7, 0xCA, 0x79, 0x75, 0x06, 0x48, + 0x4B, 0x7E, 0x11, 0xC5, 0xA8, 0x6A, 0x51, 0x9B, + 0x32, 0xBA, 0x3A, 0xA4, 0x06, 0x69, 0xC6, 0xD7, + 0x8F, 0xDE, 0x67, 0x52, 0x63, 0xFC, 0x71, 0x99, + 0x62, 0x10, 0x4B, 0x58, 0x77, 0xAB, 0x16, 0xBC, + 0x5D, 0xDF, 0x25, 0x45, 0xB3, 0x37, 0x03, 0x12, + 0x42, 0xAE, 0x77, 0xBD, 0xD5, 0x59, 0x37, 0x62, + 0x28, 0x8C, 0x0F, 0x70, 0x3B, 0x0B, 0x08, 0x2B, + 0x13, 0xAE, 0x21, 0x58, 0x20, 0x38, 0xDC, + + 0xCE, 0xFA, 0x4C, 0xBD, 0xCA, 0xBC, 0x3A, 0xC0, + 0x4B, 0x91, 0x3F, 0x33, 0x19, 0x46, 0x05, 0x16, + 0x80, 0xC0, 0xE2, 0x63, 0xB0, 0xE0, 0xD5, 0x2B, + 0xCE, 0xBA, 0x01, 0x36, 0x5B, 0xCD, 0x68, 0x17, + 0xCF, 0xEC, 0x0A, 0x31, 0x45, 0x36, 0x1B, 0x28, + 0xB1, 0x85, 0x90, 0x55, 0xB5, 0x27, 0x90, 0xE1, + 0x09, 0x4E, 0x8E, 0x27, 0x91, 0xD7, 0x15, 0x70, + 0x85, 0x89, 0x20, 0x0D, 0xD3, 0xF1, 0x70, 0x74, + 0xAA, 0x29, 0x0A, 0xA2, 0xA3, 0x96, 0x4B, 0x6E, + 0xBB, 0x04, 0x99, 0x4D, 0xC9, 0xD8, 0xFB, 0xA3, + 0xD0, 0xEF, 0x9D, 0x2A, 0x77, 0xC9, 0x0E, 0x85, + 0x33, 0x68, 0xFC, 0x30, 0xA1, 0x48, 0x55, 0x75, + 0x55, 0x21, 0xC8, 0x1F, 0x01, 0xF2, 0xA5, 0x2B, + 0x7D, 0xD7, 0x5E, 0x8C, 0x76, 0x06, 0x18, 0xBD, + 0x74, 0x4A, 0x5F, 0xE4, 0xE9, 0xD7, 0xCB, 0xEB, + 0x37, 0x95, 0x4F, 0x06, 0x26, 0xD2, 0xF1, 0xD4, + + 0x37, 0x0D, 0xA6, 0xE9, 0x34, 0x06, 0x17, 0x74, + 0x20, 0x52, 0x8E, 0x5B, 0xC2, 0x71, 0x8D, 0x6E, + 0x3C, 0xAA, 0xAA, 0xF9, 0x7F, 0x82, 0x09, 0x74, + 0x29, 0xCF, 0x79, 0xC1, 0xF7, 0x42, 0xB8, 0xA9, + 0x36, 0xA5, 0xFF, 0x77, 0x15, 0x09, 0x0B, 0x04, + 0x7E, 0xF4, 0xE1, 0xB1, 0x88, 0x89, 0x7A, 0x88, + 0x98, 0xD3, 0xA7, 0x95, 0x23, 0x69, 0x88, 0xD3, + 0x8F, 0x61, 0x1E, 0xBF, 0x99, 0xAD, 0xB4, 0x56, + 0xDF, 0x37, 0x12, 0x78, 0xDA, 0xF7, 0xDA, 0x42, + 0x8A, 0x43, 0xBD, 0x1A, 0xB2, 0x0A, 0xDA, 0x71, + 0xD6, 0x16, 0xDB, 0x15, 0xCA, 0xEA, 0x74, 0xA2, + 0x11, 0x0D, 0xAE, 0xE5, 0x2B, 0x64, 0x01, 0x61, + 0x91, 0x38, 0x16, 0xF4, 0x6E, 0xB9, 0x01, 0xDF, + 0xFD, 0xCD, 0x56, 0x79, 0xA7, 0x42, 0x7D, 0x8C, + 0xF4, 0x10, 0x4B, 0x00, 0xBA, 0x05, 0x77, 0x35, + 0x29, 0x74, 0x45, 0xDF, 0xCF, 0x2A, 0x6E, 0xBF, + 0x60, + + 0x49, 0x06, 0x7D, 0xD6, 0xE2, 0xC8, 0x54, 0x45, + 0x41, 0x97, 0x98, 0x29, 0xB5, 0x49, 0x3C, 0xE2, + 0x29, 0xC1, 0x87, 0xAC, 0x4A, 0x88, 0x31, 0x54, + 0x12, 0xDF, 0x6F, 0x7C, 0x88, 0xD4, 0x5A, 0x69, + 0xEF, 0x89, 0xB7, 0x26, 0xBD, 0x5D, 0x14, 0x45, + 0x5B, 0xAA, 0xC0, 0x31, 0x77, 0x20, 0x56, 0x22, + 0x32, 0x43, 0x0B, 0x0F, 0x29, 0x9F, 0x2C, 0xA5, + 0x42, 0xFC, 0x25, 0x1C, 0x9C, 0x1B, 0xE7, 0xBE, + 0x65, 0x8F, 0xBD, 0xA8, 0x07, 0xCC, 0x54, 0xFF, + 0xD2, 0x3B, 0xC0, 0x52, 0x9F, 0x21, 0xDE, 0xA4, + 0xA0, 0x8F, 0xB9, 0x05, 0x51, 0x8B, 0x4D, 0x6C, + 0x87, 0x4A, 0xD3, 0x82, 0xD4, 0x0D, 0xE2, 0x11, + 0xAC, 0x48, 0x81, 0x6D, 0xF9, 0xFD, 0xEC, 0x8D, + 0x15, 0x38, 0x8E, 0x6B, 0xE4, 0x5B, 0x04, 0x42, + 0xD5, 0x34, 0xFB, 0xE1, 0xBC, 0x0D, 0xDB, 0xB7, + 0xA9, 0xF7, 0xE6, 0x42, 0x5C, 0xBF, 0x89, 0x57, + 0x63, 0xF6, + + 0x90, 0x0A, 0xF6, 0x05, 0x11, 0x92, 0x82, 0x59, + 0xA1, 0x31, 0x54, 0xE8, 0x93, 0x6C, 0xE5, 0x4B, + 0xE8, 0x6C, 0x14, 0x80, 0xFB, 0x5F, 0xB5, 0x52, + 0xAA, 0x4A, 0x04, 0x64, 0xC5, 0xC5, 0x03, 0x2C, + 0x2D, 0xB1, 0x6F, 0xDC, 0xA0, 0x74, 0xFF, 0xDE, + 0xE5, 0x0D, 0x50, 0xE0, 0xBE, 0x35, 0xBA, 0x42, + 0x5E, 0x56, 0x64, 0x4F, 0xA0, 0x19, 0xD0, 0xAC, + 0xC6, 0x79, 0x09, 0x61, 0x1C, 0x72, 0xE2, 0x38, + 0x66, 0x7E, 0x96, 0x61, 0xC7, 0x69, 0x41, 0xEF, + 0x5A, 0x41, 0x89, 0xB2, 0xC6, 0xA9, 0xF3, 0xCB, + 0x8C, 0xAE, 0x1E, 0xBE, 0xDE, 0xF2, 0x4B, 0x20, + 0x67, 0xFF, 0x89, 0xAD, 0x95, 0x0A, 0x4D, 0x2C, + 0xEC, 0x62, 0x45, 0x53, 0x5C, 0xD8, 0x8F, 0x41, + 0x1B, 0x5E, 0xC6, 0x8E, 0xF6, 0x79, 0xB1, 0x3E, + 0xD5, 0x95, 0x46, 0x4E, 0x85, 0xA2, 0x32, 0x79, + 0x06, 0xE5, 0xBE, 0xD0, 0xEB, 0x77, 0xE0, 0x87, + 0x87, 0x75, 0xDD, + + 0xAC, 0x14, 0x1B, 0x69, 0xEE, 0x01, 0x0E, 0xE8, + 0x55, 0x78, 0x58, 0x91, 0xBE, 0xB4, 0x31, 0xCD, + 0x3D, 0xBE, 0x2F, 0x30, 0x81, 0x9D, 0x5F, 0x3A, + 0x65, 0x49, 0x1E, 0x24, 0x75, 0x38, 0xEA, 0x0F, + 0x45, 0x88, 0x6F, 0x66, 0x98, 0x56, 0x84, 0x41, + 0xB0, 0x7B, 0x08, 0x92, 0xE1, 0xAC, 0x8E, 0xFD, + 0x51, 0x96, 0xAD, 0x8B, 0x2D, 0x8C, 0xB8, 0xFA, + 0xB8, 0xA6, 0x63, 0x34, 0xF3, 0xC1, 0xCB, 0x51, + 0xC2, 0xAB, 0x04, 0x9B, 0x53, 0x28, 0xF9, 0x13, + 0xF0, 0x11, 0x54, 0xFF, 0xB0, 0x47, 0x18, 0x29, + 0xC5, 0x97, 0x43, 0x5E, 0x7C, 0xAA, 0x6F, 0x38, + 0x99, 0x04, 0x5C, 0x79, 0xF0, 0x08, 0xA2, 0x69, + 0xD3, 0xFF, 0x62, 0xC6, 0xDB, 0xA8, 0x2B, 0xF5, + 0xDB, 0xD2, 0x8A, 0xDD, 0x4F, 0xC3, 0xD2, 0x00, + 0xE5, 0xDE, 0x75, 0xD7, 0xC4, 0x8B, 0x76, 0xC8, + 0xDB, 0x55, 0xCB, 0xE6, 0x1B, 0xAB, 0xD2, 0x4E, + 0x3B, 0x93, 0x08, 0x43, + + 0x10, 0x07, 0x49, 0x6C, 0x11, 0x44, 0xEE, 0xFA, + 0x41, 0x19, 0xFA, 0xD1, 0x7D, 0xEC, 0xD2, 0x8F, + 0xA2, 0xBC, 0xB5, 0x38, 0x85, 0xD5, 0x4B, 0x79, + 0xFB, 0x77, 0x69, 0x42, 0x65, 0xEC, 0x29, 0x04, + 0x24, 0xCF, 0x51, 0xE1, 0xC2, 0x23, 0x06, 0x88, + 0x47, 0xAE, 0x7D, 0xA1, 0x08, 0x9A, 0x82, 0x2C, + 0xD6, 0xB4, 0x4D, 0x84, 0x96, 0x19, 0x17, 0x5A, + 0x0F, 0x22, 0x29, 0xDE, 0x0F, 0x8F, 0x71, 0xAE, + 0x12, 0x65, 0x87, 0xC5, 0xB4, 0xAD, 0x58, 0xDB, + 0xCA, 0x66, 0xE6, 0xB8, 0xE4, 0x3A, 0x80, 0x2B, + 0x18, 0x88, 0xD6, 0x21, 0xDC, 0x2B, 0xC8, 0x52, + 0x4B, 0x48, 0x90, 0x37, 0x72, 0x02, 0xCD, 0x01, + 0xEC, 0xE8, 0x03, 0xD4, 0x28, 0x8D, 0xD1, 0x94, + 0xBC, 0x1E, 0xAE, 0xA2, 0x79, 0x12, 0xB0, 0x5D, + 0x34, 0x32, 0x53, 0x1B, 0xC9, 0xA8, 0x6A, 0x1D, + 0x48, 0x30, 0x08, 0xB4, 0xC5, 0x54, 0x0A, 0x1E, + 0x24, 0x9E, 0x8D, 0x58, 0xF2, + + 0x1C, 0x73, 0x21, 0xCA, 0xB9, 0x20, 0x75, 0xEF, + 0xF4, 0x2B, 0xA5, 0xE5, 0x66, 0x62, 0xF3, 0x31, + 0x61, 0x92, 0x8B, 0x34, 0x44, 0x67, 0xC5, 0xAD, + 0xC1, 0x56, 0xC3, 0xB7, 0x23, 0xC6, 0x2B, 0xB1, + 0x34, 0x5F, 0xEF, 0xF7, 0x70, 0x21, 0x5E, 0x35, + 0x36, 0x28, 0xCC, 0xD2, 0x61, 0x58, 0xA3, 0xF6, + 0xB0, 0xD7, 0xA2, 0xBC, 0xF3, 0x02, 0x4E, 0x76, + 0x55, 0x1D, 0x48, 0x45, 0x90, 0x4C, 0xEF, 0x6C, + 0xAC, 0x58, 0x7B, 0xF2, 0x7C, 0x3E, 0x3F, 0xD6, + 0xFB, 0x57, 0x74, 0x3B, 0x91, 0xBE, 0xCE, 0x05, + 0x58, 0x9E, 0x26, 0xE6, 0x8A, 0x96, 0x8B, 0x00, + 0xC3, 0x28, 0x4A, 0xE8, 0x5C, 0xDA, 0x46, 0xF2, + 0x55, 0x14, 0x7C, 0x86, 0x58, 0xE0, 0x78, 0x16, + 0x0B, 0xA6, 0x45, 0xB2, 0xBD, 0x09, 0x83, 0x16, + 0xFE, 0x8F, 0x0D, 0xE6, 0x46, 0xE4, 0x85, 0x80, + 0x95, 0xE5, 0xC7, 0xEC, 0x5A, 0xE2, 0xE8, 0x1F, + 0xCC, 0x33, 0x25, 0x2A, 0x71, 0xB4, + + 0xDF, 0x62, 0x81, 0xFF, 0x5B, 0x88, 0x34, 0xB3, + 0xA9, 0x4A, 0xA6, 0xD9, 0x08, 0x48, 0x65, 0x7D, + 0xFC, 0x07, 0x56, 0xD8, 0xF5, 0xBA, 0x69, 0xD2, + 0xF8, 0x68, 0xAD, 0xDB, 0x14, 0x6F, 0x3F, 0x27, + 0x0B, 0x1D, 0x14, 0x53, 0x2C, 0xC2, 0x9E, 0x7E, + 0x1A, 0x97, 0xA2, 0xE3, 0x0B, 0x9E, 0x78, 0x3C, + 0x79, 0x4B, 0xD9, 0xCC, 0xDD, 0x19, 0x0D, 0x26, + 0x77, 0x65, 0xE6, 0x89, 0x19, 0xAB, 0x58, 0xA3, + 0x91, 0x50, 0x82, 0xA0, 0xB1, 0xB3, 0x7E, 0xD7, + 0x4B, 0xE2, 0xA2, 0xF7, 0x1E, 0x37, 0x33, 0x18, + 0xF6, 0x09, 0x60, 0x6B, 0x00, 0x46, 0xEF, 0xB1, + 0x06, 0x60, 0x1B, 0x0A, 0x4C, 0x0E, 0xE3, 0xFA, + 0xEA, 0xD7, 0x9D, 0xDC, 0x6B, 0x4C, 0x9E, 0x9C, + 0x61, 0x22, 0xAB, 0x19, 0x6E, 0x62, 0xA7, 0x25, + 0x26, 0xC3, 0xDB, 0x9B, 0xE0, 0x6E, 0xD4, 0x2D, + 0xDC, 0x71, 0x2A, 0x13, 0x7C, 0x77, 0xE8, 0xAA, + 0x1D, 0xED, 0x37, 0xB5, 0x6A, 0xB8, 0x3E, + + 0x02, 0xDC, 0x62, 0xA2, 0x98, 0x84, 0x22, 0x1E, + 0xB7, 0x25, 0x9A, 0xED, 0xDD, 0x60, 0x96, 0x44, + 0xEB, 0x1B, 0xC6, 0x9A, 0xEE, 0x76, 0x1B, 0x67, + 0xF4, 0x66, 0xE8, 0x63, 0x55, 0x3F, 0x6F, 0xB9, + 0x35, 0xAE, 0xB4, 0x3D, 0xD4, 0xDC, 0x4B, 0xD9, + 0x42, 0x1F, 0x7A, 0x36, 0x4D, 0x2C, 0x01, 0x2A, + 0x74, 0x5B, 0x67, 0xF9, 0xE1, 0x66, 0x69, 0xEF, + 0x89, 0x17, 0x96, 0xFF, 0x3F, 0xC6, 0x6C, 0xAB, + 0xFA, 0xE8, 0x82, 0x6D, 0x65, 0x48, 0xD2, 0x8D, + 0x0D, 0xCB, 0x0F, 0x5B, 0x2E, 0xCF, 0x17, 0xEA, + 0x60, 0x96, 0x76, 0x64, 0x33, 0x9A, 0xDE, 0x11, + 0xB4, 0x2A, 0xC4, 0x2D, 0x35, 0x2B, 0xF8, 0x36, + 0x80, 0xC4, 0x4E, 0xFE, 0x14, 0xFD, 0xB2, 0x57, + 0x0A, 0x46, 0x29, 0x37, 0x50, 0x7B, 0x26, 0x29, + 0x2B, 0xAE, 0x3D, 0xB9, 0xF8, 0x38, 0x31, 0x4C, + 0x13, 0x67, 0xD5, 0xF2, 0x40, 0x92, 0x09, 0xF1, + 0x5C, 0xE1, 0xF3, 0xE7, 0xE3, 0x6B, 0x25, 0x88, + + 0x70, 0x64, 0x4F, 0x22, 0x92, 0xCC, 0xBA, 0x70, + 0x10, 0xB5, 0xF9, 0x5D, 0xF6, 0xBD, 0x95, 0x7A, + 0x9E, 0xA1, 0xC3, 0x00, 0x77, 0x6A, 0x12, 0x94, + 0x43, 0xC9, 0x0C, 0xBB, 0xE2, 0xCD, 0xBE, 0xB7, + 0xF4, 0x11, 0xB0, 0x86, 0x11, 0xBB, 0x98, 0x31, + 0xBE, 0xC0, 0x82, 0xF9, 0x84, 0xF7, 0x99, 0xA6, + 0x1A, 0x44, 0x66, 0x28, 0x93, 0x32, 0xD9, 0x91, + 0x16, 0x8F, 0x53, 0x0D, 0x21, 0xF4, 0xFC, 0x69, + 0x5F, 0xDD, 0xFE, 0xF5, 0x59, 0x9A, 0x96, 0x4F, + 0x1C, 0x2A, 0xFD, 0xE4, 0x88, 0x66, 0x2A, 0x78, + 0x33, 0x60, 0xF3, 0x10, 0x55, 0xED, 0x68, 0xE6, + 0x34, 0x67, 0x62, 0x04, 0xBF, 0x39, 0x17, 0x3D, + 0x1B, 0x22, 0x8A, 0x77, 0x45, 0x90, 0x7C, 0x5C, + 0xCF, 0x4E, 0xE2, 0xB0, 0x88, 0xB8, 0x2B, 0x4A, + 0x4F, 0xCC, 0x14, 0xDC, 0xD3, 0x6A, 0x77, 0xA7, + 0xA7, 0x52, 0x0A, 0x4A, 0xCC, 0x3C, 0x30, 0xF0, + 0x9B, 0x10, 0x1A, 0xAA, 0xC8, 0x5A, 0xFE, 0x6F, + 0xA6, + + 0xC1, 0x62, 0xCF, 0x2C, 0xBA, 0xC0, 0xC0, 0x84, + 0x67, 0x4E, 0x96, 0xA2, 0xFF, 0x81, 0xE6, 0x74, + 0xFA, 0x22, 0xCE, 0x6B, 0xC4, 0x9C, 0x1D, 0x03, + 0xC0, 0xB1, 0x8B, 0x10, 0x33, 0xC3, 0x1F, 0x61, + 0x2D, 0x67, 0x09, 0x2F, 0x04, 0x51, 0x49, 0xCE, + 0x9F, 0x94, 0x14, 0xAB, 0x0A, 0x7F, 0x39, 0xD9, + 0xA5, 0x4F, 0x4E, 0x5A, 0x3C, 0xCB, 0xB8, 0x74, + 0x51, 0x28, 0x3B, 0xBE, 0x1B, 0x5E, 0x94, 0xFC, + 0xD1, 0xB2, 0x0A, 0x46, 0x20, 0xB3, 0x7E, 0x6E, + 0xD3, 0x9F, 0x76, 0x3F, 0x4A, 0xFF, 0x0B, 0xB7, + 0x52, 0xE2, 0xA4, 0xDF, 0x2E, 0x0C, 0x72, 0xE2, + 0xC7, 0x91, 0x2D, 0x5F, 0xB3, 0x38, 0x4F, 0x03, + 0x5C, 0x19, 0x2F, 0xBD, 0xDC, 0x84, 0xB5, 0xF9, + 0xFF, 0x8C, 0x19, 0x6F, 0x57, 0x4A, 0xD7, 0xA6, + 0xC5, 0x93, 0x2E, 0xEA, 0x35, 0xD7, 0xF8, 0xD4, + 0x08, 0xCA, 0x21, 0x06, 0x21, 0x12, 0x9B, 0xE2, + 0xF5, 0x38, 0x2C, 0xD4, 0x02, 0xD9, 0x56, 0xDE, + 0x5D, 0xB5, + + 0x1F, 0x86, 0xAE, 0xE4, 0xE4, 0xB2, 0x42, 0x60, + 0x9B, 0xBF, 0x1E, 0xA5, 0x16, 0x65, 0xA0, 0xDD, + 0xB3, 0xC6, 0xCA, 0xD7, 0xB8, 0xAE, 0x14, 0xCD, + 0xDF, 0xE9, 0xFF, 0x63, 0x38, 0x87, 0xE8, 0x2F, + 0xAE, 0xC7, 0xC7, 0x43, 0x46, 0x24, 0x54, 0xC0, + 0x41, 0xA6, 0x27, 0x73, 0x4E, 0x63, 0x0D, 0x0F, + 0x2D, 0xAA, 0xD6, 0x62, 0xFE, 0x8E, 0xE4, 0x3F, + 0xA2, 0xC3, 0x98, 0x5B, 0x93, 0x5B, 0x11, 0xEA, + 0xC9, 0x6D, 0xED, 0x9E, 0x71, 0x9D, 0xD9, 0x5E, + 0xA7, 0xB3, 0x4C, 0xB9, 0xBF, 0x2C, 0xE0, 0x90, + 0x3C, 0x19, 0x82, 0xE5, 0x94, 0xB9, 0xD7, 0x67, + 0x3F, 0xA7, 0x78, 0xAE, 0x10, 0x8B, 0x59, 0x69, + 0xD3, 0x73, 0x33, 0x2C, 0xD5, 0x74, 0x76, 0x56, + 0xA5, 0x16, 0xF0, 0x78, 0xB9, 0x4E, 0xFA, 0x0B, + 0x71, 0x77, 0x99, 0xAD, 0xBC, 0xD5, 0x86, 0xE0, + 0xFD, 0x36, 0xF6, 0x35, 0x97, 0x05, 0xEF, 0xB6, + 0xFF, 0x83, 0xA7, 0x0F, 0x65, 0xE8, 0x98, 0x8F, + 0x42, 0xB0, 0x8B, + + 0x90, 0x2A, 0x6C, 0xF6, 0x1D, 0xD4, 0x36, 0xDD, + 0xC3, 0x87, 0x2D, 0xE1, 0x68, 0xED, 0x8F, 0x21, + 0x0E, 0x53, 0xF5, 0x03, 0xE9, 0xA0, 0xD5, 0x3A, + 0xF9, 0xEF, 0x15, 0xCC, 0x0E, 0xE3, 0xD6, 0x27, + 0xB3, 0x30, 0x8B, 0x60, 0x0A, 0x43, 0x2F, 0xA4, + 0x41, 0x0E, 0xE9, 0x8F, 0xFD, 0x6E, 0x7C, 0x8A, + 0xEA, 0xCB, 0x7F, 0x1E, 0xEF, 0x15, 0x97, 0x59, + 0x4A, 0x67, 0x25, 0xFD, 0x72, 0xB6, 0x0D, 0x3A, + 0xC0, 0xCE, 0xD4, 0xA7, 0xF6, 0x61, 0x6B, 0x60, + 0x8C, 0x55, 0xB3, 0xB7, 0xA9, 0xB0, 0x7E, 0xD8, + 0x95, 0xBB, 0xAA, 0xFD, 0x3B, 0x72, 0x40, 0x72, + 0x28, 0xA4, 0x73, 0x19, 0x75, 0x37, 0x39, 0x07, + 0xBD, 0xB8, 0xB6, 0x51, 0x48, 0xC2, 0xB5, 0xFF, + 0xE8, 0xBC, 0x0C, 0x65, 0xD0, 0x8E, 0xB2, 0x32, + 0xA5, 0xCE, 0xE7, 0xB9, 0x3C, 0xC2, 0x56, 0xBF, + 0x4D, 0x7B, 0x8E, 0xA4, 0xCE, 0x2D, 0x7B, 0x32, + 0x48, 0xA9, 0xE3, 0x3A, 0x34, 0x18, 0xB0, 0x6A, + 0x68, 0x88, 0xED, 0x55, + + 0xB6, 0xDF, 0x47, 0x88, 0x2F, 0x70, 0x18, 0x3C, + 0xB9, 0x72, 0x04, 0x1E, 0x75, 0x5F, 0x45, 0xCA, + 0xA4, 0xB0, 0xAC, 0x11, 0x1B, 0x65, 0x4B, 0xAE, + 0xCA, 0x4D, 0xA1, 0xA9, 0x2C, 0xDF, 0x76, 0x14, + 0x94, 0x2A, 0xFC, 0x04, 0xC2, 0xE8, 0xAE, 0x94, + 0x15, 0x11, 0x07, 0x7A, 0x72, 0x25, 0xB6, 0x6D, + 0x70, 0x03, 0xC9, 0xAC, 0xE0, 0xAB, 0xD0, 0xC1, + 0x90, 0x4E, 0x08, 0xF4, 0x9F, 0x13, 0xB4, 0x7B, + 0xB5, 0x56, 0x37, 0x20, 0x83, 0x0C, 0x71, 0xA6, + 0x93, 0xF5, 0x00, 0x2F, 0xC9, 0xD5, 0x6A, 0x5C, + 0xB7, 0xA7, 0x9E, 0xB2, 0x1B, 0x62, 0x49, 0x9B, + 0xA0, 0x2A, 0x54, 0xC5, 0xE4, 0x5C, 0xCF, 0x5A, + 0x63, 0x9D, 0xA2, 0x85, 0x8D, 0xFA, 0xEE, 0x2B, + 0x1A, 0x41, 0x35, 0x97, 0x67, 0x36, 0x53, 0x25, + 0x52, 0x57, 0x8C, 0x8E, 0x53, 0x27, 0x89, 0xBC, + 0x2D, 0x3F, 0x91, 0xC4, 0x36, 0xB1, 0xEF, 0x54, + 0x1A, 0xCB, 0xDA, 0xC9, 0x78, 0x54, 0x78, 0xBA, + 0xDD, 0xA9, 0x23, 0x9D, 0xB4, + + 0xB0, 0xA8, 0x6B, 0x05, 0x72, 0x86, 0xDA, 0xD2, + 0x21, 0xDC, 0xC6, 0x3C, 0x0B, 0x47, 0x2E, 0xAA, + 0x4A, 0x4F, 0x19, 0x7B, 0xAC, 0xEF, 0x6F, 0xA6, + 0xD4, 0x9D, 0x45, 0xEF, 0xB4, 0x14, 0x83, 0x49, + 0xA6, 0x20, 0x55, 0x18, 0xA0, 0x64, 0x49, 0xD0, + 0xBB, 0x1C, 0xA5, 0x49, 0x56, 0x13, 0x8E, 0xD6, + 0x9A, 0x22, 0x3E, 0x1A, 0x28, 0x24, 0x6E, 0x55, + 0xAF, 0xA3, 0xDD, 0x02, 0x1B, 0xBC, 0x1E, 0xF2, + 0xA7, 0x8A, 0x5C, 0xBD, 0x6A, 0xE8, 0x26, 0x21, + 0x81, 0x5D, 0x6C, 0xDF, 0x44, 0xF8, 0xB4, 0xA7, + 0x42, 0x9D, 0x73, 0x9A, 0xC4, 0x7A, 0x4B, 0xF2, + 0x98, 0xFC, 0xB7, 0xE8, 0xEA, 0x8C, 0x0A, 0xC2, + 0xD5, 0xC3, 0x51, 0xCF, 0x3F, 0x71, 0xB5, 0xE4, + 0xC3, 0x5B, 0x30, 0xA6, 0xE4, 0x80, 0xFA, 0x46, + 0xB4, 0xBC, 0x13, 0x01, 0xA0, 0xA5, 0xF8, 0xEF, + 0x6D, 0xA8, 0xD3, 0xCB, 0x92, 0xD7, 0xBF, 0x46, + 0x73, 0xC4, 0xE0, 0x12, 0xC3, 0x57, 0xC1, 0x20, + 0x5E, 0xF2, 0xF2, 0x7A, 0x18, 0x54, + + 0xD5, 0x8C, 0x8D, 0x9B, 0x33, 0xB8, 0x9B, 0xC3, + 0x15, 0x50, 0xC9, 0xC7, 0x25, 0x8B, 0x36, 0xA6, + 0x5C, 0x3E, 0x87, 0x59, 0x3F, 0x6B, 0x0A, 0xD8, + 0x22, 0x39, 0x48, 0x8A, 0xE4, 0x50, 0x23, 0x8F, + 0x3A, 0x6E, 0xE1, 0x60, 0xA3, 0xDE, 0xB3, 0xFA, + 0xEA, 0xD4, 0x8B, 0x25, 0x17, 0xB1, 0x4E, 0xBA, + 0x0E, 0x97, 0x22, 0x37, 0xEE, 0xFE, 0x5D, 0x42, + 0xB5, 0xE5, 0xC1, 0x96, 0x34, 0xA6, 0x0E, 0x11, + 0xAA, 0x41, 0xD4, 0xF5, 0xDA, 0x40, 0x22, 0x2B, + 0xF9, 0x9E, 0x9C, 0x55, 0x6C, 0xB9, 0x73, 0xDF, + 0x94, 0x71, 0x8B, 0x90, 0x91, 0x67, 0xF4, 0xFE, + 0x01, 0x90, 0x64, 0xB8, 0xB8, 0x31, 0x85, 0xAE, + 0x82, 0x1B, 0x65, 0xD4, 0xC8, 0x61, 0x9D, 0x1D, + 0x9A, 0x94, 0x40, 0xD9, 0x7C, 0xE2, 0xE9, 0x09, + 0xE9, 0x2B, 0xD0, 0xEB, 0xBE, 0x57, 0xAD, 0x29, + 0xCB, 0xA5, 0xD4, 0x46, 0xBA, 0xB6, 0x86, 0xB8, + 0xD1, 0x2F, 0x0B, 0xFC, 0xCA, 0x43, 0xBA, 0x60, + 0xA2, 0x0F, 0xA6, 0xC6, 0x2F, 0x05, 0x0A, + + 0xA1, 0x11, 0x6A, 0x04, 0xA8, 0x55, 0xB1, 0x04, + 0xA8, 0x6F, 0x55, 0x85, 0xE9, 0xF1, 0x0D, 0x6F, + 0xDD, 0x04, 0x10, 0x3C, 0xB3, 0xAD, 0xD2, 0x9E, + 0xE7, 0x1E, 0x08, 0xBF, 0x65, 0x0A, 0xB0, 0xB4, + 0x95, 0x6D, 0xC6, 0x3E, 0xD8, 0x71, 0x46, 0x3E, + 0x1B, 0x1E, 0x82, 0x8D, 0x16, 0xF8, 0x98, 0xF1, + 0xEC, 0x0B, 0x0C, 0xFB, 0x73, 0xDB, 0x28, 0x1E, + 0xC1, 0xD0, 0xC2, 0xB1, 0xB0, 0x48, 0x02, 0xD9, + 0x69, 0xC5, 0x72, 0x6D, 0xB2, 0xD2, 0xCE, 0x15, + 0x8C, 0x77, 0xAD, 0x48, 0x7C, 0x4D, 0xEA, 0x87, + 0x5E, 0x13, 0x6D, 0x61, 0xFE, 0xFC, 0x75, 0xAA, + 0x76, 0x55, 0x2E, 0x87, 0x26, 0x92, 0x9D, 0x43, + 0x61, 0x7D, 0x1F, 0xFD, 0xE0, 0xCA, 0xC0, 0x87, + 0xAF, 0xAF, 0xC4, 0x92, 0x37, 0xED, 0xBB, 0x4F, + 0x38, 0x03, 0xE0, 0x1E, 0x1D, 0xB1, 0x4A, 0xBA, + 0x9A, 0xA0, 0x14, 0x84, 0x90, 0x90, 0x70, 0x62, + 0xA2, 0x55, 0x1D, 0x49, 0xD1, 0x51, 0xF1, 0x9B, + 0x1E, 0xD6, 0x8C, 0x02, 0xA4, 0xE2, 0x2D, 0x0E, + + 0xB9, 0xED, 0x83, 0x89, 0xD5, 0x73, 0x97, 0x72, + 0x3A, 0xF3, 0x32, 0x9A, 0xC4, 0xE0, 0x80, 0x5B, + 0xA3, 0x2E, 0x18, 0x82, 0xD9, 0x6D, 0xDC, 0xA3, + 0x4F, 0x00, 0x24, 0x67, 0x52, 0xDC, 0xD9, 0x07, + 0x1E, 0x62, 0x1A, 0xC8, 0xA8, 0xC0, 0xEF, 0x68, + 0x5E, 0xED, 0x2A, 0x23, 0xA2, 0x91, 0xC4, 0x49, + 0x69, 0xF4, 0xC1, 0x84, 0x60, 0x84, 0xAB, 0x34, + 0x91, 0x73, 0x76, 0x4A, 0x70, 0x98, 0xD5, 0x42, + 0xA0, 0x8C, 0x69, 0x1A, 0x6B, 0xC5, 0x90, 0x86, + 0x4E, 0xF3, 0x4C, 0xA0, 0xBA, 0x47, 0x4F, 0x41, + 0x0E, 0x83, 0x30, 0xF7, 0x5B, 0x47, 0x4C, 0x2D, + 0x78, 0xB9, 0x49, 0x51, 0x54, 0xF4, 0x01, 0x23, + 0x77, 0x6D, 0x2D, 0x05, 0x1F, 0xA9, 0xA5, 0x65, + 0x83, 0x92, 0xF3, 0xCE, 0x19, 0x2A, 0x9A, 0xF2, + 0xC6, 0x9C, 0x08, 0x8D, 0xF9, 0x31, 0xCA, 0xD0, + 0xF0, 0x56, 0xB9, 0xD2, 0xDE, 0x09, 0x6E, 0x7B, + 0xF1, 0x33, 0x45, 0xAD, 0x5D, 0x20, 0xC9, 0x6B, + 0x12, 0x91, 0xCC, 0xA0, 0x44, 0xF3, 0xB2, 0x9C, + 0x29, + + 0x28, 0x3B, 0xFC, 0xF7, 0x0B, 0xE0, 0x62, 0x2F, + 0xB3, 0x2E, 0x10, 0xD3, 0x78, 0x0C, 0x33, 0x6D, + 0xD7, 0xA8, 0xB2, 0xF7, 0x1C, 0x6C, 0xBA, 0xD0, + 0x67, 0x5F, 0xB5, 0xD3, 0x71, 0x09, 0xD7, 0x34, + 0xCE, 0xFB, 0xF0, 0xEE, 0x7D, 0x5C, 0xCE, 0x03, + 0x20, 0x85, 0xEA, 0xD6, 0x01, 0xF9, 0x4A, 0x3C, + 0x83, 0xC8, 0x59, 0xA3, 0x42, 0x90, 0xB3, 0x14, + 0x04, 0x86, 0xB1, 0x1A, 0xDB, 0x7C, 0x35, 0x56, + 0x96, 0x15, 0xE4, 0x17, 0x27, 0xB0, 0x47, 0xF2, + 0x75, 0x4E, 0xBD, 0x4D, 0x6D, 0x40, 0xDB, 0x03, + 0xBE, 0x34, 0x23, 0x9C, 0x80, 0xF3, 0x34, 0xF2, + 0x89, 0x43, 0xE2, 0x39, 0x4B, 0x9B, 0xD9, 0x1A, + 0xAB, 0x48, 0x4A, 0x97, 0x66, 0x87, 0xF8, 0x37, + 0x70, 0xCC, 0x05, 0x24, 0x48, 0x9F, 0xEF, 0x19, + 0x9C, 0xB4, 0x5F, 0x76, 0x28, 0xED, 0x59, 0x12, + 0x50, 0x5B, 0x69, 0x44, 0xA9, 0xBE, 0x40, 0xEE, + 0x2C, 0x97, 0xA3, 0x4A, 0x05, 0xCC, 0x57, 0xB8, + 0xC9, 0x26, 0x85, 0xE4, 0xB1, 0x58, 0xF2, 0x4D, + 0x9B, 0xA9, + + 0x36, 0xEF, 0xE2, 0x4F, 0xAE, 0x4C, 0xB1, 0xB3, + 0xB8, 0x22, 0x91, 0xB6, 0xC5, 0x31, 0x60, 0xFF, + 0x7B, 0x00, 0x71, 0x12, 0xAA, 0x5A, 0xD2, 0x10, + 0x5E, 0x0F, 0x4C, 0xB0, 0xDB, 0x09, 0x11, 0xC7, + 0x28, 0x6C, 0x88, 0x96, 0x97, 0xC6, 0xB7, 0x56, + 0x77, 0x20, 0xAB, 0xE4, 0x03, 0xFA, 0x7A, 0xCF, + 0x8E, 0xB7, 0x73, 0xEB, 0xD6, 0x80, 0xD8, 0xAE, + 0x6F, 0xCC, 0x22, 0x90, 0x49, 0x7B, 0x21, 0x57, + 0xAF, 0x39, 0x8E, 0x25, 0x98, 0x54, 0x2C, 0x7A, + 0xFC, 0xF1, 0xAE, 0xA0, 0xD7, 0x69, 0x95, 0x04, + 0x6A, 0x93, 0xDA, 0x41, 0x8F, 0xE3, 0x53, 0x7D, + 0x8C, 0xC4, 0xE6, 0x14, 0xD6, 0xF5, 0x23, 0x10, + 0xFF, 0xF4, 0x3D, 0x87, 0x8E, 0x44, 0x7B, 0xBD, + 0xDF, 0x5B, 0x81, 0x1E, 0x88, 0x9C, 0x8E, 0x3C, + 0xB3, 0xA1, 0x8D, 0xC9, 0x1F, 0xE2, 0x51, 0xFB, + 0x31, 0xBA, 0x07, 0x2D, 0xF8, 0xFA, 0x54, 0x88, + 0x64, 0x00, 0xA0, 0x73, 0x2A, 0xD7, 0x9B, 0x85, + 0xBB, 0xED, 0x0A, 0x2E, 0xA1, 0x98, 0x3D, 0x87, + 0xFA, 0x0A, 0x43, + + 0xAE, 0x78, 0x23, 0x96, 0x97, 0xE1, 0x6D, 0x02, + 0x31, 0xA9, 0x56, 0xBA, 0xDC, 0xA4, 0xDB, 0xD5, + 0x5F, 0x37, 0x26, 0xF8, 0xED, 0x78, 0x79, 0xAA, + 0x7B, 0xCC, 0xC3, 0x67, 0x38, 0x86, 0xB6, 0x58, + 0x7D, 0x2A, 0x5E, 0x77, 0xF8, 0xDB, 0x3A, 0xB0, + 0xB3, 0x83, 0x3A, 0xEF, 0xB5, 0xB0, 0x46, 0xA7, + 0x85, 0x98, 0xA8, 0x71, 0x1C, 0x2C, 0xB6, 0x06, + 0x3F, 0xEC, 0x59, 0x78, 0x15, 0xAD, 0x17, 0x65, + 0x94, 0x37, 0xC1, 0x21, 0xC9, 0x1A, 0x16, 0xEA, + 0x1A, 0xFE, 0x3D, 0x35, 0xF4, 0xBA, 0x5D, 0xA0, + 0x21, 0x9C, 0x89, 0x39, 0x69, 0xAB, 0x8E, 0x4B, + 0x8A, 0x9C, 0x38, 0xFD, 0x53, 0x37, 0xB4, 0x59, + 0xBE, 0xB0, 0x56, 0xD7, 0x6C, 0xF8, 0xB8, 0xF1, + 0x03, 0x26, 0xF5, 0x07, 0x98, 0xDB, 0xDF, 0xF3, + 0x9D, 0x02, 0x65, 0x78, 0x7C, 0xD7, 0x71, 0x06, + 0x93, 0xFF, 0xFA, 0xBE, 0xEF, 0x24, 0x24, 0x21, + 0x32, 0xD8, 0xC2, 0xFD, 0xB9, 0x08, 0xBC, 0x06, + 0xD6, 0xC1, 0xEE, 0x5D, 0xFE, 0xA1, 0x8D, 0x12, + 0x9A, 0x36, 0x5B, 0xB7, + + 0x61, 0x61, 0x14, 0x68, 0xE4, 0x54, 0x04, 0x1F, + 0xB4, 0x42, 0x87, 0x44, 0x7B, 0x01, 0xC6, 0xD6, + 0xF9, 0xBC, 0xE5, 0x1D, 0x25, 0x6E, 0xFB, 0xC9, + 0x2A, 0x50, 0x31, 0xB7, 0x8B, 0x11, 0x50, 0x39, + 0x2C, 0xE9, 0x37, 0xD1, 0x43, 0xD5, 0xD2, 0x9D, + 0x9D, 0x9E, 0x58, 0x1C, 0x14, 0x90, 0x8C, 0x0B, + 0xF0, 0x2D, 0xBE, 0xEB, 0xF4, 0x24, 0xA9, 0xFF, + 0x07, 0x5C, 0x8F, 0x49, 0x26, 0xEF, 0xC4, 0x74, + 0x8E, 0x32, 0x03, 0xCA, 0xBF, 0xB9, 0x8D, 0x3C, + 0x69, 0xE4, 0x3D, 0x35, 0x85, 0xC3, 0xAE, 0x35, + 0x33, 0x95, 0xD4, 0xE8, 0xAC, 0xBE, 0xE2, 0x2E, + 0xD2, 0x75, 0x3A, 0x42, 0x00, 0xBF, 0xC2, 0x61, + 0xF1, 0x0C, 0x5D, 0xFB, 0xC9, 0x59, 0xB1, 0xAC, + 0x37, 0x83, 0x7E, 0x52, 0xB0, 0x32, 0x38, 0x9E, + 0xD5, 0xCD, 0xE4, 0x77, 0x47, 0x08, 0x9B, 0x41, + 0x2A, 0x5D, 0xA7, 0x5E, 0xAA, 0xF2, 0xD3, 0x4F, + 0x76, 0x20, 0xB3, 0xD5, 0x55, 0xEE, 0x41, 0x00, + 0x8C, 0x7C, 0x38, 0x67, 0xF4, 0x38, 0x21, 0xB8, + 0x3F, 0x1E, 0x57, 0x46, 0x45, + + 0x66, 0xF1, 0x58, 0xCA, 0xD3, 0x81, 0x9F, 0x85, + 0x1D, 0x6F, 0xA2, 0xB5, 0xCB, 0x77, 0x12, 0x4C, + 0x41, 0xF2, 0x93, 0xED, 0x56, 0x04, 0xC7, 0xB1, + 0xA0, 0x9B, 0x6D, 0x51, 0x9C, 0xC8, 0xE9, 0xF3, + 0x9C, 0xE1, 0xC2, 0x91, 0x6A, 0x31, 0x05, 0x2A, + 0xB1, 0xEE, 0x19, 0xCD, 0x01, 0x30, 0x2F, 0x80, + 0x37, 0x03, 0xCD, 0xB1, 0x7D, 0xB8, 0xC0, 0x06, + 0x83, 0x00, 0xC7, 0x12, 0x85, 0x43, 0x8D, 0x67, + 0x12, 0xD8, 0xC8, 0x15, 0x62, 0x80, 0xA1, 0xE1, + 0x60, 0x42, 0x04, 0x74, 0x34, 0xBA, 0xBC, 0x67, + 0xF0, 0x04, 0xA7, 0x54, 0x3C, 0x6C, 0x0B, 0x10, + 0x2E, 0x02, 0x4D, 0x4F, 0x4A, 0x45, 0x97, 0x8E, + 0xF6, 0x50, 0x65, 0x44, 0xD0, 0x8B, 0x72, 0x33, + 0xCE, 0xD9, 0xDE, 0x7A, 0xE9, 0x98, 0x6F, 0x0C, + 0xE7, 0x79, 0xA8, 0x11, 0x73, 0x83, 0xF2, 0x93, + 0x5B, 0xE7, 0x3E, 0x4B, 0x81, 0xCE, 0xFB, 0x4E, + 0x27, 0x73, 0x7E, 0x66, 0xFA, 0x55, 0x1F, 0xCE, + 0xE8, 0xC3, 0x38, 0x7D, 0x04, 0xC6, 0xC3, 0x30, + 0x47, 0x8B, 0x02, 0x9D, 0x81, 0x49, + + 0x0A, 0x2A, 0x5B, 0x2B, 0x5E, 0xA4, 0x2B, 0x40, + 0x5E, 0x95, 0x70, 0x40, 0x23, 0x66, 0xD1, 0x1A, + 0x27, 0x79, 0x3F, 0x3C, 0xA9, 0x86, 0xF2, 0x75, + 0x2A, 0x52, 0x2E, 0xFE, 0x4E, 0x8E, 0x7E, 0x20, + 0x79, 0x19, 0x98, 0xDD, 0x01, 0x3F, 0x19, 0x68, + 0x23, 0x0A, 0xF0, 0x18, 0xA7, 0x13, 0x33, 0xF3, + 0x9E, 0x04, 0xA7, 0xA9, 0x01, 0xFA, 0xAC, 0xF3, + 0x81, 0x3D, 0xC6, 0x57, 0x35, 0x8C, 0xFE, 0x5D, + 0xCB, 0xE6, 0xF3, 0xA6, 0xCF, 0x18, 0x96, 0x70, + 0xCF, 0xAD, 0x05, 0xC6, 0x75, 0x05, 0x02, 0x50, + 0xA6, 0xAA, 0x88, 0xBC, 0x57, 0xA9, 0x14, 0x1A, + 0xF9, 0x1A, 0xD3, 0x40, 0xC7, 0x48, 0xFF, 0xE0, + 0x2D, 0xC6, 0xA8, 0x94, 0xBA, 0x3F, 0xFA, 0x76, + 0x44, 0xBA, 0xE8, 0x3E, 0xCC, 0x0D, 0x16, 0x8A, + 0x72, 0x91, 0xD8, 0xB1, 0x29, 0xC7, 0x3C, 0x67, + 0x1E, 0xA2, 0x3A, 0x9C, 0x9F, 0x5B, 0xCD, 0x41, + 0x8C, 0xCB, 0xFF, 0xFE, 0x70, 0x6F, 0xDA, 0xDF, + 0x10, 0x4B, 0xFF, 0x9A, 0xBF, 0x3E, 0xFF, 0x98, + 0x4E, 0x62, 0x15, 0x96, 0x97, 0xE1, 0x4E, + + 0x18, 0xDD, 0xC6, 0xD7, 0x31, 0x4C, 0x44, 0xF5, + 0x63, 0x56, 0x9C, 0xDF, 0xDC, 0x2D, 0x25, 0x5A, + 0xBF, 0x0C, 0x40, 0x69, 0x86, 0xDA, 0xA8, 0x76, + 0x86, 0x9C, 0x74, 0x9F, 0xDD, 0x04, 0x01, 0x9E, + 0x0B, 0x70, 0xEF, 0xE1, 0xF6, 0x26, 0x58, 0x5F, + 0x10, 0x2F, 0x9D, 0xC7, 0xAC, 0x4C, 0x19, 0x85, + 0xC8, 0x3E, 0xE8, 0xFF, 0xC4, 0x6C, 0x17, 0xB0, + 0xB9, 0x2E, 0x00, 0xD6, 0xEA, 0xF0, 0xFA, 0x40, + 0x93, 0x8D, 0x6F, 0xFD, 0x0B, 0xF5, 0x59, 0xEC, + 0xEA, 0x64, 0x26, 0x9D, 0x5F, 0xB2, 0x26, 0x1E, + 0x4C, 0xC8, 0x65, 0xAD, 0xD4, 0xC1, 0xAD, 0x63, + 0x29, 0x6C, 0x11, 0xCB, 0xE6, 0xDC, 0xF8, 0x2E, + 0x18, 0xA7, 0x50, 0xF0, 0x8F, 0x0E, 0x9B, 0x95, + 0xCC, 0x74, 0x3D, 0xB1, 0x9C, 0xD3, 0x50, 0x08, + 0x18, 0x5E, 0x27, 0x15, 0xD3, 0xF3, 0x5A, 0xC0, + 0x63, 0xEC, 0xB1, 0x4C, 0x77, 0x77, 0x9B, 0xE9, + 0x7B, 0x57, 0x0C, 0x31, 0xAA, 0xB5, 0xCE, 0x6C, + 0x4F, 0x46, 0x16, 0x0D, 0x55, 0xB9, 0x36, 0xF1, + 0xFA, 0x36, 0xE8, 0x89, 0xB0, 0x7B, 0xBB, 0x84, + + 0xF3, 0x24, 0x87, 0xDA, 0x52, 0xDC, 0x22, 0x0A, + 0xE1, 0x8E, 0x6A, 0x1A, 0xA6, 0x6C, 0x16, 0x48, + 0xFD, 0x70, 0xF9, 0x3E, 0x45, 0xF7, 0xE3, 0x6A, + 0xAC, 0x92, 0x5A, 0x82, 0xD1, 0xC3, 0x8C, 0x7E, + 0x76, 0x69, 0x3E, 0x34, 0x66, 0x25, 0x46, 0xD0, + 0x17, 0xEE, 0x25, 0xD2, 0xB2, 0x2A, 0xCE, 0xB8, + 0x6A, 0x56, 0x2C, 0x37, 0xB0, 0x51, 0x62, 0x1A, + 0x04, 0xB9, 0x68, 0xAA, 0x9B, 0x30, 0xEE, 0x17, + 0x57, 0xFC, 0x98, 0xCF, 0x7E, 0x4B, 0xAB, 0x25, + 0xA0, 0x91, 0x6E, 0x68, 0x23, 0x55, 0xF0, 0xC7, + 0x20, 0xA7, 0x3B, 0xE1, 0x03, 0xB3, 0x94, 0x2C, + 0x5D, 0xC1, 0x50, 0x32, 0x61, 0xB8, 0x63, 0x69, + 0x61, 0x74, 0x61, 0xCA, 0xC1, 0x49, 0x25, 0x63, + 0x9B, 0xA1, 0x5A, 0x09, 0x23, 0x44, 0x05, 0x97, + 0xCA, 0x73, 0xA6, 0x57, 0x92, 0xA5, 0x22, 0x18, + 0x82, 0x55, 0x0E, 0xFF, 0xE7, 0x53, 0xA9, 0x71, + 0x25, 0xC6, 0x2D, 0x02, 0x07, 0xD4, 0x51, 0x12, + 0x18, 0x03, 0x71, 0x4F, 0x10, 0x23, 0x17, 0xF0, + 0x76, 0xB3, 0x3B, 0x57, 0x8D, 0x88, 0xDA, 0x6F, + 0x5F, + + 0xCB, 0xF5, 0x44, 0xA5, 0x45, 0x49, 0x7D, 0x58, + 0xA6, 0x10, 0x4B, 0x4E, 0x81, 0xF2, 0x15, 0x21, + 0x03, 0xFB, 0xD2, 0x34, 0xE2, 0xF8, 0x99, 0x09, + 0x5D, 0x59, 0x24, 0xFF, 0xB9, 0x0D, 0xBC, 0xF6, + 0x2B, 0x11, 0x55, 0x4D, 0x50, 0x7C, 0xCD, 0x18, + 0x94, 0x92, 0xF3, 0x5C, 0x95, 0x7A, 0x64, 0xF7, + 0x35, 0x27, 0x56, 0x79, 0xD6, 0xD8, 0x81, 0xE0, + 0xF3, 0x3F, 0x80, 0x8F, 0x97, 0x1B, 0xD8, 0x15, + 0x70, 0x15, 0x2D, 0xC0, 0x2E, 0x7E, 0x79, 0xF8, + 0x1F, 0x88, 0xB7, 0xB7, 0xFF, 0x53, 0x67, 0xE8, + 0xC1, 0x59, 0x89, 0x66, 0xFD, 0x66, 0x4E, 0x88, + 0xA0, 0xCD, 0xC6, 0xD0, 0x34, 0x0C, 0x31, 0xE3, + 0xD4, 0x5F, 0x32, 0x32, 0xAC, 0xCC, 0xE1, 0x24, + 0x8C, 0x4E, 0xC9, 0x39, 0xC3, 0x7A, 0x6B, 0xAB, + 0xAE, 0x6C, 0x01, 0x79, 0x6D, 0xB4, 0xAF, 0x49, + 0x12, 0x10, 0xB3, 0xC5, 0x20, 0xB9, 0x63, 0x99, + 0x79, 0xC1, 0x22, 0xE4, 0x74, 0x15, 0x42, 0x61, + 0x98, 0x4E, 0xDC, 0x13, 0xD0, 0xE1, 0xD8, 0x24, + 0x0A, 0xC5, 0xB4, 0x54, 0xDC, 0x3C, 0x00, 0xDE, + 0xFB, 0xEB, + + 0x01, 0x0B, 0xD7, 0x6A, 0x19, 0xF8, 0xD2, 0x4A, + 0xD6, 0xC8, 0xFA, 0x05, 0x69, 0x4A, 0x18, 0x97, + 0x35, 0x61, 0x8B, 0xB9, 0x8B, 0x7B, 0x0C, 0xD9, + 0xF4, 0xF4, 0xC4, 0x2F, 0x1F, 0xA9, 0x98, 0x16, + 0xB7, 0xD6, 0x1F, 0x4A, 0x59, 0x42, 0x37, 0x60, + 0x37, 0x20, 0x37, 0x5C, 0x16, 0x6E, 0x63, 0x49, + 0x25, 0x1A, 0x86, 0x42, 0x00, 0xC3, 0x4A, 0x33, + 0xC7, 0x7D, 0x06, 0x14, 0xC9, 0x98, 0x19, 0x9A, + 0xD3, 0x17, 0xB4, 0x61, 0x4F, 0x52, 0x09, 0x13, + 0x54, 0xFE, 0xE4, 0x47, 0xA4, 0xFF, 0xA5, 0x20, + 0x62, 0x52, 0xB1, 0xDD, 0x42, 0xF2, 0x1C, 0xE9, + 0x0E, 0x2D, 0xEA, 0x19, 0x51, 0xF5, 0x3E, 0x7D, + 0x27, 0xFF, 0x1D, 0x43, 0x96, 0x16, 0x9B, 0xBD, + 0x9D, 0x29, 0x0E, 0x19, 0x4B, 0x6E, 0x98, 0xF4, + 0xA3, 0x51, 0x3C, 0x14, 0x64, 0xBF, 0x93, 0xAA, + 0x3C, 0x86, 0xF8, 0xB5, 0x3A, 0x2C, 0x12, 0x10, + 0x52, 0xD6, 0xE9, 0xB6, 0x36, 0x91, 0x5B, 0x36, + 0x22, 0x9B, 0xD1, 0x00, 0xEC, 0xC6, 0x13, 0x13, + 0x1D, 0x83, 0xF4, 0xF9, 0xBE, 0xC0, 0x3E, 0x71, + 0x0B, 0x64, 0xDF, + + 0xF2, 0xB0, 0xFC, 0xD2, 0x54, 0x85, 0x18, 0xD4, + 0x31, 0x7A, 0x3E, 0xD5, 0xDD, 0x8D, 0x3C, 0xCC, + 0x4E, 0x92, 0x14, 0xE4, 0x21, 0x39, 0xF3, 0x73, + 0x66, 0x71, 0x77, 0x29, 0x37, 0x49, 0x6C, 0x72, + 0xFB, 0x51, 0x17, 0x6C, 0x9E, 0x4A, 0x7C, 0x8C, + 0xBF, 0x96, 0x13, 0x8F, 0xAE, 0x7E, 0x88, 0x15, + 0xE9, 0x5E, 0x1A, 0xC4, 0xA7, 0x42, 0xFA, 0x60, + 0xD5, 0xFB, 0xCF, 0x90, 0x56, 0x97, 0xBB, 0xAD, + 0xF2, 0x2C, 0x6B, 0x07, 0xA5, 0xE6, 0x99, 0x92, + 0x75, 0x55, 0x69, 0xE8, 0xA3, 0xD9, 0x05, 0xC4, + 0x95, 0xED, 0xD0, 0x8E, 0x18, 0x60, 0x86, 0x86, + 0xEB, 0xC3, 0x20, 0xA8, 0xB9, 0x2E, 0xB8, 0x38, + 0xEB, 0xCE, 0x48, 0x2E, 0x4B, 0x42, 0xD6, 0xFB, + 0xDF, 0x97, 0xC4, 0xCD, 0x8C, 0xFD, 0x98, 0x0E, + 0xAC, 0xC2, 0xC4, 0xDA, 0x07, 0xFF, 0x8D, 0x72, + 0xF3, 0x15, 0x6F, 0x69, 0x3A, 0x61, 0x5F, 0xE0, + 0xAE, 0x1B, 0xCB, 0x16, 0x91, 0xEF, 0x54, 0x92, + 0xFC, 0xCD, 0xAF, 0xF4, 0x45, 0x4F, 0x2A, 0xCD, + 0xF8, 0xE4, 0x3F, 0x99, 0x2C, 0x61, 0xEC, 0x23, + 0xE3, 0x8B, 0xAB, 0x8F, + + 0x7C, 0x3F, 0x27, 0xDE, 0xAF, 0xE9, 0x72, 0x9C, + 0x04, 0xDA, 0xB4, 0xBB, 0xE6, 0x6F, 0x56, 0xF1, + 0xE8, 0x7E, 0xB5, 0xDA, 0x14, 0x2D, 0xFA, 0x29, + 0x80, 0x87, 0x53, 0x78, 0x65, 0xF7, 0x98, 0x64, + 0xB7, 0x11, 0x1A, 0x08, 0x4F, 0x36, 0x7E, 0xF8, + 0x4F, 0x0C, 0x70, 0xFE, 0xAF, 0xF1, 0x72, 0xC9, + 0xB8, 0x39, 0x57, 0xCB, 0x10, 0x61, 0x95, 0x49, + 0xEA, 0xB4, 0x2B, 0xA0, 0x77, 0x76, 0x30, 0x5D, + 0x9A, 0xB5, 0xCB, 0xF4, 0x5F, 0xC7, 0xA6, 0xD8, + 0x3A, 0x9E, 0xA8, 0xA1, 0x9F, 0xAB, 0xCC, 0x2C, + 0x2D, 0x8C, 0xCF, 0x3D, 0x7C, 0x11, 0xC6, 0xE9, + 0xD5, 0x15, 0xA2, 0xB8, 0xCE, 0x11, 0x45, 0x52, + 0x94, 0x0D, 0xE3, 0xF4, 0x47, 0x4A, 0xC6, 0x2E, + 0x7A, 0xBF, 0xBB, 0x4D, 0x2A, 0x89, 0xE5, 0x49, + 0x51, 0xDE, 0x25, 0x36, 0x58, 0x52, 0x3F, 0xA3, + 0xAD, 0xFE, 0xE3, 0xA3, 0x31, 0x90, 0xDA, 0xA3, + 0x1D, 0x48, 0xD6, 0xE8, 0xF2, 0x9E, 0x4C, 0xEC, + 0xCA, 0xC7, 0x46, 0x3C, 0xD5, 0x89, 0x01, 0xA7, + 0x33, 0xD3, 0x50, 0x7E, 0x31, 0x1C, 0x8E, 0xFF, + 0xF0, 0xB4, 0x42, 0x70, 0xA5, + + 0xDB, 0xFD, 0x65, 0xEB, 0x8C, 0xA7, 0x97, 0xE5, + 0xC7, 0xF4, 0x2E, 0xD4, 0x19, 0xCD, 0xA6, 0x0F, + 0x56, 0x39, 0xE3, 0x55, 0xF6, 0xFA, 0x43, 0xAC, + 0x3C, 0x0A, 0x1E, 0x00, 0xBF, 0x36, 0x1B, 0x95, + 0x71, 0x7E, 0x73, 0xBF, 0x93, 0x76, 0xF6, 0x2D, + 0xCB, 0x35, 0xBE, 0x43, 0x33, 0x2B, 0x89, 0x2D, + 0x85, 0x8A, 0xCE, 0x2F, 0xE7, 0x9C, 0x39, 0xD7, + 0x01, 0x69, 0x2E, 0xB3, 0xE7, 0xED, 0xEF, 0x41, + 0x06, 0xE7, 0xFC, 0x1F, 0x4B, 0x42, 0x71, 0xB2, + 0x59, 0x55, 0xEB, 0xBD, 0x18, 0x12, 0x63, 0x7F, + 0xEE, 0x10, 0x35, 0x84, 0x4E, 0x58, 0x9C, 0x75, + 0x86, 0xAB, 0x7F, 0x54, 0x8C, 0x90, 0x79, 0xAD, + 0xE7, 0xA6, 0x40, 0xCA, 0xB3, 0x6D, 0x8A, 0x14, + 0x8A, 0xE5, 0x13, 0x8C, 0x6E, 0xE9, 0x99, 0x56, + 0x11, 0xFC, 0xD4, 0x3B, 0xF5, 0xCB, 0x65, 0x33, + 0xEF, 0x98, 0x63, 0x7F, 0x91, 0x22, 0xD1, 0x2E, + 0xF4, 0xE0, 0xB3, 0xE8, 0xA6, 0x9E, 0xF9, 0x10, + 0xC6, 0xF1, 0x21, 0x95, 0x8C, 0x34, 0x2D, 0x7C, + 0x54, 0x92, 0x8D, 0x8F, 0xB6, 0x03, 0x34, 0xF7, + 0xF7, 0xD8, 0x5A, 0xBA, 0x57, 0x50, + + 0x41, 0x62, 0x0B, 0xC6, 0xC6, 0x43, 0xE4, 0x2D, + 0x36, 0x29, 0x87, 0x1D, 0x0D, 0xAC, 0xDB, 0xF0, + 0x00, 0x89, 0xBD, 0xE6, 0x48, 0x04, 0x24, 0x0C, + 0x28, 0x54, 0x88, 0x94, 0x3E, 0x1F, 0x2F, 0x5D, + 0x1C, 0xC1, 0x18, 0x38, 0xA6, 0xA5, 0xCA, 0xC3, + 0xAF, 0x5C, 0xDF, 0xAD, 0x8B, 0x4F, 0x53, 0x9E, + 0x6B, 0x99, 0xAB, 0x09, 0x2F, 0xD8, 0x11, 0xF9, + 0xC9, 0xAB, 0x73, 0x0A, 0xE6, 0x50, 0x6F, 0xBD, + 0xA5, 0xD1, 0x16, 0xFE, 0xC3, 0x11, 0xDE, 0x11, + 0x72, 0xC4, 0x71, 0x80, 0x40, 0x02, 0x14, 0x1F, + 0xC1, 0x6C, 0xE3, 0x28, 0xF8, 0xD8, 0x99, 0x06, + 0x1B, 0x90, 0x55, 0xFB, 0x67, 0x1D, 0x37, 0xA8, + 0xF9, 0xC7, 0xB2, 0xAD, 0x0F, 0x6C, 0xF4, 0x0F, + 0x1B, 0x42, 0xBD, 0x57, 0x51, 0x56, 0xA5, 0x83, + 0x7A, 0x15, 0x1C, 0x1A, 0xCF, 0x8C, 0xA4, 0x1B, + 0xF2, 0xFB, 0xDF, 0xC1, 0xCE, 0xD1, 0xF3, 0x29, + 0x7B, 0xA6, 0xA7, 0xE8, 0xA8, 0xB4, 0xCF, 0xEC, + 0x4E, 0xD7, 0x92, 0x82, 0x3A, 0x27, 0x05, 0xEF, + 0x88, 0x1B, 0x9C, 0x04, 0xAD, 0xF9, 0x51, 0x94, + 0xA6, 0xC1, 0xF8, 0x16, 0x3F, 0x5F, 0xF2, + + 0xFC, 0xF4, 0xBD, 0x0F, 0xE9, 0x09, 0xA4, 0xCE, + 0x31, 0x2D, 0x53, 0xD4, 0x15, 0xE5, 0x62, 0xF6, + 0x72, 0x63, 0x22, 0x53, 0x93, 0x2E, 0xCB, 0x30, + 0x01, 0x5C, 0x1C, 0xBA, 0x04, 0xA6, 0x95, 0x46, + 0x4E, 0x03, 0xEC, 0x36, 0xA2, 0xBE, 0x86, 0xD7, + 0x6E, 0x92, 0x2C, 0xEF, 0x64, 0x45, 0x94, 0x22, + 0xF8, 0x11, 0x43, 0x2D, 0x81, 0x04, 0xE6, 0x7B, + 0xEC, 0xE3, 0xF9, 0x9A, 0x43, 0xEF, 0xA7, 0xC9, + 0x5F, 0x39, 0x56, 0x6D, 0x3A, 0xBC, 0x26, 0xCD, + 0x77, 0x6F, 0x38, 0x30, 0x0A, 0x78, 0xD3, 0x98, + 0x71, 0xE1, 0x2C, 0xEA, 0xC2, 0xD8, 0x69, 0x18, + 0x74, 0xFE, 0x91, 0x1C, 0xAF, 0x5D, 0x8D, 0xDB, + 0x59, 0xDA, 0x52, 0xCD, 0xE4, 0x0D, 0x76, 0x41, + 0x9E, 0x6C, 0xD3, 0x85, 0x96, 0x3C, 0x8E, 0x66, + 0xDF, 0xED, 0x26, 0x03, 0x84, 0x88, 0x9D, 0x25, + 0x39, 0x35, 0xAD, 0xB5, 0x8B, 0xBB, 0xC5, 0x64, + 0xCE, 0xC5, 0xD7, 0x88, 0x5C, 0x2D, 0x46, 0x47, + 0x80, 0x11, 0x43, 0x85, 0xF1, 0xEB, 0x90, 0x71, + 0xA4, 0xB7, 0x5A, 0x3B, 0xB4, 0x51, 0x68, 0x76, + 0x63, 0x4D, 0x8F, 0x9F, 0x65, 0x6F, 0x9D, 0x03, + + 0x80, 0x5F, 0x0F, 0xB1, 0x39, 0x5B, 0xF6, 0x33, + 0xF7, 0x1C, 0xE6, 0x3C, 0x31, 0xC4, 0x31, 0x1A, + 0x14, 0x67, 0x38, 0x6C, 0x79, 0x59, 0x05, 0xF2, + 0x1F, 0xBA, 0xF2, 0xAE, 0x0C, 0xFF, 0xC5, 0x22, + 0x89, 0xB9, 0x2C, 0x88, 0xD1, 0x10, 0x24, 0xD1, + 0xBA, 0xD4, 0xD7, 0x41, 0x45, 0xAF, 0x57, 0xFC, + 0xF6, 0x97, 0x81, 0x4D, 0xA5, 0xF9, 0xC2, 0x25, + 0xFC, 0x3B, 0xBD, 0x0E, 0x96, 0xC2, 0x8B, 0xE3, + 0x93, 0x67, 0x65, 0xC4, 0x1D, 0x2A, 0x86, 0xCC, + 0x8A, 0x87, 0x4C, 0x35, 0xF7, 0x55, 0x51, 0xD6, + 0x8A, 0x8A, 0xE8, 0xE8, 0x69, 0xEF, 0x1A, 0xED, + 0xCB, 0x09, 0x4C, 0xE1, 0x4F, 0x36, 0xA6, 0xBD, + 0x68, 0x6B, 0x87, 0xC1, 0x39, 0x5E, 0x63, 0x61, + 0xA7, 0x19, 0x60, 0x3E, 0x1A, 0x2A, 0xF0, 0x43, + 0xA4, 0xE5, 0xE3, 0xEF, 0x76, 0x20, 0xA1, 0x7D, + 0x61, 0xFB, 0xC0, 0x8D, 0xED, 0xB0, 0x78, 0xDB, + 0xEC, 0x53, 0x44, 0x4A, 0x94, 0x42, 0x39, 0x83, + 0x41, 0x49, 0xBC, 0xA5, 0x17, 0x6C, 0xB4, 0x89, + 0x8D, 0xAB, 0x32, 0x40, 0x05, 0x69, 0x44, 0xF8, + 0x9A, 0x8B, 0x60, 0xD5, 0x47, 0x31, 0xD5, 0x17, + 0x1A, + + 0x99, 0xC8, 0x1F, 0x50, 0x51, 0xE0, 0xCA, 0x64, + 0x60, 0x38, 0x24, 0x34, 0x8B, 0x37, 0x13, 0x87, + 0x05, 0xE5, 0x3D, 0x7E, 0x8F, 0x8D, 0xF7, 0xD5, + 0x92, 0x06, 0xA4, 0x32, 0xD9, 0x64, 0xD8, 0xFC, + 0x1B, 0x5E, 0x46, 0xE4, 0x97, 0x14, 0x80, 0x2D, + 0xE2, 0x7B, 0x2E, 0xC4, 0xC2, 0x50, 0x0C, 0xDC, + 0xC1, 0xE6, 0x6A, 0x5F, 0x37, 0x02, 0x36, 0x24, + 0x98, 0x51, 0xB5, 0x92, 0x4E, 0x95, 0x80, 0x3E, + 0x93, 0x21, 0x03, 0xFB, 0x41, 0x20, 0x85, 0x55, + 0x39, 0xFC, 0xFC, 0x9E, 0xE6, 0x5B, 0x21, 0x29, + 0xC6, 0xCD, 0x63, 0x6B, 0xB8, 0x66, 0xB3, 0xB2, + 0x77, 0xE6, 0xA3, 0x3A, 0x40, 0x6C, 0xD0, 0x7C, + 0xEA, 0x36, 0x5F, 0x3E, 0xA2, 0x47, 0x64, 0xD9, + 0xF5, 0x94, 0x09, 0xE6, 0xC4, 0x90, 0x0E, 0xF6, + 0x5E, 0xE5, 0x9E, 0x54, 0xFC, 0x32, 0x51, 0x0F, + 0xED, 0x6A, 0xEE, 0x50, 0x29, 0x47, 0x0C, 0xEF, + 0xCD, 0x3D, 0x83, 0x2F, 0xA4, 0x62, 0x93, 0x0A, + 0x28, 0xEF, 0xD9, 0xAD, 0x6F, 0xAE, 0x79, 0x1B, + 0x7E, 0xB8, 0xEC, 0x21, 0x53, 0x13, 0x21, 0xDF, + 0x01, 0x81, 0x4C, 0x30, 0x07, 0x58, 0x6E, 0x80, + 0x1A, 0xED, + + 0x78, 0x66, 0x40, 0x07, 0x32, 0x18, 0x83, 0x4D, + 0x35, 0x65, 0x2D, 0xD2, 0x93, 0x09, 0xEF, 0xF7, + 0x5F, 0xD6, 0xB0, 0x99, 0xD9, 0xD0, 0xC5, 0xD7, + 0xF7, 0xC3, 0xDF, 0xD2, 0x01, 0xB2, 0x80, 0x7F, + 0xC5, 0xC8, 0x9A, 0xB3, 0x1B, 0x1D, 0x4A, 0x3E, + 0x05, 0xD4, 0x5B, 0xB5, 0xC5, 0x61, 0x7A, 0x16, + 0x49, 0x0E, 0xB3, 0x17, 0x30, 0x81, 0x10, 0xA0, + 0xC7, 0xE7, 0x3E, 0x1D, 0xAC, 0x2B, 0x36, 0x02, + 0xB2, 0x82, 0x7D, 0xAD, 0xD4, 0x24, 0x34, 0xC6, + 0x90, 0x19, 0x7E, 0xE0, 0xAD, 0xE2, 0xB2, 0xDE, + 0x59, 0xB8, 0xB5, 0x98, 0xC5, 0xEE, 0xA4, 0x14, + 0x8E, 0x4E, 0xEB, 0x9C, 0xA3, 0x27, 0x35, 0xF5, + 0x03, 0x8F, 0x3F, 0x24, 0xED, 0x7D, 0xA1, 0x86, + 0xFE, 0xD3, 0xD7, 0x45, 0xC8, 0x48, 0xDC, 0xA1, + 0x2E, 0xF9, 0xDF, 0xB3, 0x15, 0xD9, 0x16, 0x8E, + 0xEA, 0x52, 0xDE, 0x70, 0x71, 0xA9, 0x6A, 0x48, + 0x75, 0xBD, 0x6C, 0x8C, 0xF4, 0x51, 0x93, 0x35, + 0x7F, 0xD8, 0x59, 0xDB, 0xEE, 0x97, 0xB3, 0x15, + 0xC2, 0x66, 0x95, 0xB9, 0x09, 0x7F, 0x22, 0x4A, + 0x0D, 0xBF, 0xCE, 0x05, 0x11, 0x14, 0x72, 0x83, + 0x89, 0x77, 0x48, + + 0x36, 0x9A, 0x46, 0xA7, 0xD8, 0x92, 0xA3, 0x4A, + 0xBE, 0x55, 0xDA, 0xBE, 0xB4, 0x8D, 0x58, 0x09, + 0x0F, 0xEB, 0x49, 0x0C, 0xFE, 0xDA, 0x5E, 0xB3, + 0xCF, 0xB5, 0xDF, 0x65, 0x4B, 0x37, 0xF4, 0xFF, + 0x0F, 0x68, 0x8C, 0xBE, 0x3C, 0x36, 0x62, 0x54, + 0xF1, 0xC5, 0x76, 0x64, 0x6E, 0x7F, 0xCC, 0x91, + 0x61, 0x77, 0xB5, 0xD1, 0x5F, 0x56, 0x35, 0xAA, + 0xFB, 0x72, 0x8E, 0x21, 0xFF, 0x33, 0xD5, 0x36, + 0xFE, 0xF6, 0x85, 0x63, 0x58, 0x02, 0x6A, 0x35, + 0x0C, 0x3F, 0x42, 0xE2, 0xF7, 0xE7, 0x36, 0xC1, + 0x11, 0x49, 0x75, 0x99, 0x6D, 0x39, 0x68, 0x7F, + 0x17, 0x54, 0x29, 0x5A, 0x88, 0xAF, 0x48, 0xFC, + 0xF7, 0xC9, 0xD1, 0x39, 0xA2, 0xBD, 0x1D, 0xBF, + 0xAA, 0xA2, 0x37, 0x9D, 0x71, 0x7D, 0xEC, 0xF5, + 0x7C, 0xEC, 0x1C, 0x21, 0xBC, 0x73, 0x4D, 0x69, + 0xA5, 0x0C, 0xA1, 0x6E, 0xDA, 0x84, 0x52, 0xB9, + 0xED, 0xE6, 0x3C, 0xAC, 0x0D, 0xEA, 0x78, 0x40, + 0x4A, 0x24, 0x6C, 0xC5, 0xA9, 0xB9, 0x6C, 0x9A, + 0x57, 0xC4, 0xA3, 0xC2, 0x66, 0x8F, 0x4D, 0x9E, + 0x85, 0x14, 0x26, 0xB2, 0x9B, 0xB5, 0xEF, 0x22, + 0xE1, 0xA1, 0x50, 0x41, + + 0x96, 0x16, 0x23, 0x5B, 0x30, 0x81, 0xD1, 0x9A, + 0x66, 0x84, 0x92, 0xD1, 0xC4, 0x59, 0xE1, 0x24, + 0xFF, 0x2D, 0xA8, 0x6B, 0x83, 0x72, 0x38, 0xCD, + 0x7D, 0x4F, 0x5A, 0x85, 0x8A, 0x2E, 0xE9, 0x6B, + 0x48, 0x02, 0x54, 0xE4, 0x3B, 0x9F, 0x76, 0x13, + 0x9F, 0x9F, 0xF3, 0xE0, 0xF0, 0x48, 0x67, 0x9D, + 0x9F, 0x86, 0xCF, 0x7E, 0x7C, 0x1C, 0x0F, 0x61, + 0x64, 0xDA, 0x67, 0xBE, 0x68, 0x02, 0x08, 0x43, + 0x02, 0xF8, 0x68, 0x4C, 0x73, 0x4B, 0xCF, 0xFB, + 0xE8, 0xC7, 0x61, 0xCC, 0x62, 0x18, 0x39, 0xE4, + 0x04, 0x44, 0x36, 0x1E, 0xB7, 0xFB, 0xCC, 0x0A, + 0x05, 0xE7, 0x50, 0x28, 0x7F, 0xD0, 0x4F, 0xCF, + 0x81, 0xC2, 0x61, 0x72, 0x1C, 0x21, 0x76, 0x46, + 0x13, 0x05, 0x38, 0x5D, 0xEA, 0x2B, 0xF3, 0x5D, + 0xD9, 0x02, 0x3D, 0xBA, 0x4D, 0x79, 0x19, 0xB5, + 0xAC, 0xE3, 0xC7, 0x87, 0x0E, 0xA5, 0x40, 0xE5, + 0x68, 0x7A, 0x4A, 0xA1, 0x54, 0x1B, 0x10, 0xA0, + 0x9D, 0x00, 0x74, 0xB6, 0x86, 0x6D, 0x45, 0x77, + 0xBB, 0x7B, 0x4C, 0x8C, 0xD1, 0xCA, 0xC0, 0xA8, + 0xC1, 0x17, 0x17, 0x39, 0xD6, 0xC8, 0x8D, 0x75, + 0x63, 0x03, 0xB7, 0xCC, 0xA8, + + 0x18, 0xB2, 0xD0, 0xF4, 0xB4, 0xCD, 0x4D, 0xB5, + 0x3F, 0x45, 0x8E, 0x05, 0x57, 0x1A, 0x9E, 0xFB, + 0xA7, 0x46, 0xB9, 0x97, 0xC6, 0x72, 0x46, 0x48, + 0x84, 0xB2, 0xB3, 0x28, 0xBC, 0xF8, 0x3A, 0x70, + 0x4A, 0x1A, 0x26, 0x9D, 0x71, 0x31, 0xEC, 0xB2, + 0xA2, 0x26, 0x8A, 0x74, 0x03, 0x7D, 0x12, 0x07, + 0x09, 0x7B, 0xD9, 0x89, 0x3B, 0x76, 0xD6, 0xC5, + 0xB9, 0x25, 0x93, 0xFD, 0x15, 0xDA, 0x26, 0x9E, + 0x0D, 0x74, 0xAE, 0xCE, 0x81, 0xC1, 0x3E, 0x1F, + 0x4C, 0x86, 0x3C, 0x99, 0x0A, 0xC5, 0x28, 0x90, + 0x74, 0x39, 0x03, 0x07, 0x1F, 0x6A, 0xB5, 0xF1, + 0x64, 0xB4, 0xEC, 0xEE, 0x04, 0xEB, 0x46, 0xCA, + 0xCC, 0x2B, 0x3C, 0x6A, 0x9B, 0x06, 0x0A, 0xD9, + 0x76, 0xB6, 0xBB, 0x8B, 0xBD, 0x57, 0x7A, 0x31, + 0x87, 0x1D, 0x37, 0x2B, 0xAC, 0x43, 0xA5, 0x0F, + 0x0F, 0xC4, 0x25, 0x17, 0x65, 0xDF, 0xD3, 0x98, + 0x7F, 0x31, 0x89, 0xAF, 0xE2, 0x1D, 0xED, 0x3B, + 0x29, 0x5F, 0x35, 0x68, 0xEC, 0xC2, 0x77, 0x4A, + 0x9C, 0x5A, 0xAE, 0x52, 0x13, 0x8C, 0x98, 0x47, + 0x03, 0x1B, 0x20, 0x1A, 0x22, 0x4D, 0x87, 0x9D, + 0x40, 0x86, 0x48, 0xF8, 0x60, 0xFB, + + 0x63, 0x82, 0x97, 0xF6, 0x37, 0x44, 0x0E, 0x4B, + 0x54, 0x92, 0xA1, 0xFB, 0x06, 0x95, 0x89, 0x79, + 0x8F, 0x50, 0x5F, 0xD3, 0x46, 0x7A, 0xEB, 0xEC, + 0x98, 0x38, 0x40, 0x0E, 0xCC, 0x6C, 0x35, 0xBF, + 0x50, 0xD1, 0x6A, 0x3E, 0x08, 0x2E, 0x50, 0x8E, + 0xC2, 0xEB, 0xF3, 0xD8, 0x5A, 0xE8, 0xE3, 0xF4, + 0xC0, 0x37, 0x88, 0x04, 0x32, 0xAF, 0x17, 0xFC, + 0xEE, 0x42, 0x88, 0x84, 0xE7, 0xAD, 0x0F, 0xA7, + 0x51, 0xAB, 0x6A, 0xD5, 0x4B, 0xCF, 0xDB, 0xC2, + 0x09, 0xEF, 0x5D, 0x6B, 0x7F, 0x12, 0x79, 0x13, + 0xB0, 0xE8, 0xDE, 0x80, 0x72, 0x71, 0xD8, 0xDB, + 0x4E, 0x08, 0xF0, 0xA8, 0x7A, 0x68, 0xF8, 0x82, + 0xD5, 0xFD, 0xD3, 0x4A, 0x58, 0x2A, 0x99, 0x65, + 0xC2, 0x2C, 0x97, 0x59, 0x13, 0xA8, 0x96, 0x52, + 0xC3, 0xA9, 0x17, 0x47, 0xBA, 0x9C, 0xD9, 0xBB, + 0xBE, 0xAF, 0x91, 0x6F, 0xE0, 0xE3, 0x52, 0x9B, + 0xA5, 0x49, 0x7B, 0xEF, 0x5F, 0x2B, 0x03, 0xD7, + 0x4C, 0x46, 0xC0, 0xE8, 0x3F, 0xE5, 0x68, 0x7D, + 0xC9, 0xCC, 0x63, 0xA8, 0x85, 0x78, 0xFD, 0x0F, + 0x6A, 0x09, 0xBE, 0x1B, 0x1B, 0x62, 0x7A, 0x43, + 0x57, 0xF3, 0x7B, 0xC7, 0xD4, 0x9F, 0xF0, + + 0x48, 0xA5, 0xCC, 0x95, 0x4E, 0xDD, 0xE7, 0xF9, + 0x53, 0x3C, 0x37, 0xAC, 0xAA, 0x4D, 0xD7, 0x46, + 0x53, 0xD8, 0xC5, 0x51, 0x27, 0xFE, 0x09, 0x24, + 0x56, 0x0D, 0x9D, 0x57, 0x3B, 0x07, 0xB6, 0xA1, + 0x0E, 0x75, 0xF3, 0xC4, 0x80, 0x06, 0x49, 0x0B, + 0xFB, 0x36, 0x3A, 0x98, 0xB0, 0x98, 0xB8, 0xD1, + 0x4A, 0x9F, 0x7A, 0x3D, 0x06, 0x32, 0xDE, 0x00, + 0x8C, 0xF5, 0x5C, 0x65, 0xE8, 0xCB, 0x15, 0xF7, + 0x77, 0xE6, 0x93, 0x1F, 0x56, 0x21, 0x48, 0x7B, + 0xFF, 0xD1, 0x7E, 0xA2, 0xB1, 0xDB, 0x36, 0xC1, + 0x3D, 0x23, 0x9F, 0x8B, 0x2B, 0x23, 0x90, 0x58, + 0x9A, 0x60, 0xF2, 0x8D, 0x61, 0xAD, 0x69, 0x5C, + 0xC4, 0xA5, 0xB3, 0x68, 0xF0, 0x98, 0xD1, 0xB2, + 0xEA, 0x03, 0xE7, 0x02, 0x19, 0x81, 0x26, 0x5D, + 0x20, 0x4E, 0x61, 0xF1, 0xEC, 0xE6, 0x6C, 0xEF, + 0x0E, 0x55, 0x6F, 0x6D, 0x11, 0x84, 0x1A, 0x5B, + 0x7E, 0x82, 0x66, 0x88, 0x44, 0x63, 0x99, 0xB1, + 0x5B, 0xC5, 0xFB, 0x47, 0xFF, 0x9C, 0x39, 0xD6, + 0xC2, 0x96, 0xEC, 0xE3, 0xA7, 0xAA, 0xF7, 0xC2, + 0x93, 0xB2, 0x0D, 0x7B, 0x2A, 0xF8, 0xBA, 0x22, + 0x2E, 0xA5, 0x7C, 0x88, 0x41, 0x7E, 0x8A, 0xFA, + + 0x0F, 0x63, 0x92, 0x0D, 0x42, 0x3E, 0x56, 0x78, + 0x82, 0x58, 0xB7, 0x5A, 0xB4, 0xFF, 0x25, 0x5E, + 0xCD, 0x05, 0x8A, 0x3B, 0x00, 0xE7, 0xF0, 0x70, + 0xFE, 0x38, 0xC4, 0x17, 0x4D, 0x0A, 0x26, 0x71, + 0x3F, 0x64, 0x1F, 0x85, 0xE2, 0xF6, 0xED, 0x07, + 0x79, 0xDF, 0x7D, 0x03, 0x45, 0x0E, 0x26, 0xB1, + 0xC8, 0xD7, 0x7C, 0xE0, 0xF6, 0x3E, 0x6C, 0xDC, + 0xB2, 0x58, 0xFD, 0x56, 0x47, 0x69, 0xE1, 0x41, + 0xEB, 0x88, 0xEB, 0xE9, 0x8E, 0x73, 0x68, 0x4A, + 0xB4, 0xC3, 0x35, 0xA0, 0x2F, 0x8D, 0x07, 0x1E, + 0xE9, 0x7E, 0x63, 0x4D, 0x73, 0xEE, 0x79, 0x6A, + 0xA6, 0x84, 0x4A, 0x22, 0xE7, 0x88, 0xBC, 0x59, + 0x83, 0x41, 0xCD, 0x16, 0x73, 0x7C, 0xE3, 0xC0, + 0xEF, 0x23, 0x8C, 0x7A, 0x24, 0x16, 0x3F, 0x77, + 0x72, 0x10, 0xCF, 0x32, 0x1F, 0x2E, 0x37, 0xED, + 0x1B, 0x90, 0xD4, 0x4C, 0x71, 0x4D, 0x81, 0xBD, + 0x36, 0x6B, 0x6A, 0x2E, 0x07, 0xAD, 0x32, 0x35, + 0x76, 0x67, 0x66, 0xE1, 0x76, 0x95, 0x2F, 0x0A, + 0xF3, 0xF7, 0xC3, 0x25, 0x3D, 0xDF, 0xA1, 0x89, + 0xC2, 0xC1, 0x15, 0x7C, 0xD6, 0xA0, 0x07, 0x14, + 0x7D, 0x81, 0x83, 0x3B, 0x96, 0xBA, 0x39, 0x57, + 0x01, + + 0x41, 0xC2, 0x86, 0x92, 0x97, 0xA5, 0x85, 0x6B, + 0xA6, 0xEC, 0x46, 0xB2, 0xA1, 0xF7, 0x9F, 0x4C, + 0x95, 0xA8, 0xEE, 0xE0, 0xB8, 0x83, 0x46, 0x6A, + 0xAD, 0x9C, 0xD1, 0x91, 0x42, 0xD8, 0x18, 0xC1, + 0xA9, 0x54, 0x1A, 0xCA, 0xA6, 0x66, 0xF7, 0xE2, + 0x9F, 0x82, 0x73, 0xE9, 0x17, 0x32, 0x23, 0x35, + 0x3E, 0x18, 0x5C, 0xAE, 0x59, 0xB7, 0x6A, 0x04, + 0x97, 0xD1, 0x1F, 0xB2, 0x58, 0xC9, 0x37, 0xFD, + 0xE0, 0xC5, 0xA4, 0x6C, 0x9A, 0x00, 0x9B, 0x4C, + 0x06, 0x32, 0xF4, 0xA3, 0x94, 0xBF, 0xA8, 0x49, + 0xFE, 0xC2, 0x45, 0xA8, 0xB5, 0x32, 0x86, 0x5F, + 0xBA, 0xFD, 0xD1, 0x60, 0x4D, 0xF1, 0x43, 0xE1, + 0x55, 0x75, 0xD8, 0xD6, 0x1F, 0xD5, 0x7F, 0x35, + 0x67, 0x39, 0x74, 0x9C, 0x3B, 0x50, 0xBE, 0xC0, + 0x67, 0xA1, 0x90, 0x0F, 0x90, 0x27, 0xAD, 0xB9, + 0x97, 0x0C, 0xBC, 0x2A, 0xEF, 0x4D, 0x8F, 0x69, + 0x08, 0x50, 0xBD, 0x69, 0xE9, 0x2B, 0xB3, 0x37, + 0xB5, 0x90, 0x81, 0x73, 0x63, 0x64, 0xE6, 0x6A, + 0xF0, 0xEF, 0xB1, 0xEC, 0x9C, 0x8B, 0x23, 0xE3, + 0xBA, 0xDD, 0x10, 0x1A, 0x0E, 0x6A, 0x76, 0x4C, + 0x58, 0xAF, 0x8C, 0x10, 0xDD, 0xFE, 0xCB, 0x82, + 0x53, 0x9A, + + 0xB5, 0x42, 0x48, 0x28, 0x65, 0x88, 0xE8, 0xB7, + 0xB6, 0xCD, 0xAB, 0x9B, 0x31, 0xFE, 0xEC, 0xD7, + 0xBF, 0x43, 0x1B, 0x30, 0x75, 0x57, 0x96, 0x3E, + 0x34, 0x5C, 0xAA, 0x37, 0x83, 0x1C, 0xA3, 0x08, + 0x88, 0x31, 0xA0, 0x96, 0x40, 0x50, 0x7D, 0x5C, + 0x26, 0x66, 0x8D, 0x71, 0x95, 0xE0, 0xB8, 0x83, + 0x90, 0x8D, 0x9B, 0xBF, 0x85, 0x67, 0x08, 0x88, + 0x9F, 0x96, 0xC4, 0x31, 0xEC, 0xED, 0x6E, 0x9A, + 0x7E, 0x62, 0x20, 0x9A, 0xD2, 0xC6, 0xEA, 0x6B, + 0x65, 0xB2, 0xC5, 0xBB, 0xD3, 0x82, 0xC0, 0x0D, + 0xF6, 0x37, 0x3F, 0xAB, 0x88, 0xFA, 0x7E, 0xFC, + 0x4D, 0xE4, 0x83, 0x32, 0x8F, 0x3A, 0xFF, 0xAC, + 0x12, 0x81, 0xFC, 0x49, 0x0E, 0xA6, 0x37, 0xA0, + 0xFC, 0x40, 0x47, 0x4B, 0x14, 0x42, 0xC0, 0x0B, + 0xE5, 0x2D, 0x26, 0x5C, 0x2B, 0x4D, 0x0C, 0xBE, + 0xC1, 0x63, 0x67, 0x75, 0xB4, 0x1D, 0xB3, 0x9D, + 0xAA, 0xD6, 0x7C, 0xC3, 0x53, 0xD5, 0x0F, 0xE7, + 0x7F, 0xFA, 0xC0, 0xB5, 0x93, 0xBE, 0x18, 0x40, + 0x3B, 0x71, 0x32, 0xF1, 0x0F, 0x78, 0x53, 0xA1, + 0x01, 0xC6, 0xF6, 0x60, 0xEA, 0x50, 0x3A, 0x62, + 0x30, 0xBD, 0x1E, 0xE1, 0x88, 0x7C, 0x30, 0x9F, + 0xE4, 0x8E, 0x3F, + + 0x2A, 0x34, 0xC2, 0x7C, 0xAA, 0x2B, 0xA1, 0xC0, + 0x1A, 0xF5, 0xA8, 0xBC, 0xB8, 0x1E, 0x17, 0x9D, + 0xE3, 0x4E, 0x65, 0xB4, 0x4E, 0x9A, 0xB7, 0x6C, + 0xDD, 0x1E, 0x86, 0xA0, 0x68, 0x4D, 0x83, 0xB7, + 0x06, 0xD3, 0x5E, 0xAC, 0xB0, 0x9F, 0x00, 0x00, + 0x62, 0xD2, 0xCD, 0x67, 0x0C, 0x2D, 0xA9, 0x25, + 0xC1, 0x6E, 0xA8, 0xB0, 0x0E, 0xCF, 0xD9, 0x1D, + 0x5D, 0x5A, 0x04, 0xD9, 0xEA, 0x3F, 0x57, 0xE1, + 0x25, 0x19, 0xF4, 0x9D, 0x3C, 0x7D, 0xE0, 0x65, + 0x98, 0xF2, 0xD1, 0x92, 0xCA, 0x8E, 0x97, 0x6B, + 0x61, 0x58, 0x2B, 0xB4, 0x2A, 0xB4, 0x7A, 0x2A, + 0xEC, 0x93, 0xC4, 0xCB, 0x54, 0x58, 0x96, 0xD1, + 0x9E, 0x90, 0xA2, 0x2E, 0xD8, 0x62, 0x89, 0x97, + 0x2B, 0x43, 0x29, 0x6C, 0xC8, 0x78, 0x5E, 0xB8, + 0x25, 0x9E, 0x23, 0x92, 0x6F, 0x32, 0xAF, 0x4B, + 0x13, 0x6E, 0x1F, 0xB5, 0x8B, 0x8F, 0x46, 0x80, + 0x40, 0xD6, 0x34, 0xD4, 0x0D, 0x23, 0xA6, 0x46, + 0x86, 0x22, 0x51, 0xCF, 0xF5, 0xB6, 0x7E, 0x0B, + 0xD3, 0xE8, 0xD5, 0xAE, 0x47, 0x2C, 0xD9, 0xDA, + 0x61, 0x81, 0x32, 0x0A, 0xAC, 0x32, 0x83, 0x0F, + 0x5D, 0x06, 0x15, 0x19, 0x2D, 0x4E, 0x13, 0x7A, + 0xEC, 0x91, 0xEC, 0xC8, + + 0xB0, 0x44, 0xEA, 0xAC, 0x35, 0x51, 0x2D, 0x29, + 0x50, 0x73, 0x14, 0xC6, 0x5A, 0x7B, 0x9F, 0xD2, + 0x75, 0xE5, 0xE0, 0xE7, 0x66, 0x8A, 0xCB, 0x54, + 0x1D, 0xC4, 0x8A, 0x25, 0x0C, 0x7D, 0xA1, 0xA1, + 0xBA, 0x4E, 0x24, 0xB6, 0xD1, 0xF8, 0x8A, 0x9E, + 0x49, 0xD7, 0xCA, 0x7C, 0x7D, 0x83, 0xDE, 0x3E, + 0xED, 0x6E, 0x26, 0x34, 0x57, 0x6F, 0x00, 0x55, + 0xB9, 0x44, 0x54, 0x82, 0x9B, 0x9A, 0x32, 0xDA, + 0xBB, 0x59, 0x48, 0x80, 0x08, 0x96, 0x2D, 0x34, + 0x68, 0x40, 0x27, 0xB9, 0x00, 0x80, 0xC6, 0x6F, + 0x42, 0x72, 0x3C, 0x9B, 0xD1, 0xA0, 0x01, 0xCC, + 0xD2, 0x0F, 0x33, 0x00, 0x15, 0x6A, 0x65, 0x9B, + 0xED, 0x91, 0xDF, 0x56, 0xE2, 0x81, 0x54, 0x06, + 0xA0, 0xFE, 0x0E, 0xE6, 0x54, 0x16, 0xC5, 0xA6, + 0x89, 0x54, 0x87, 0x7E, 0x49, 0x47, 0x6C, 0x29, + 0x0F, 0x1C, 0x9E, 0xF7, 0x62, 0x23, 0xEB, 0x17, + 0xC2, 0x7B, 0x0D, 0x8B, 0xA0, 0xEF, 0xCE, 0x03, + 0xDE, 0x8D, 0x58, 0x0C, 0x7B, 0x6A, 0xD7, 0x66, + 0x52, 0x6E, 0x93, 0x0C, 0x13, 0xDF, 0x65, 0x28, + 0x66, 0x38, 0xA9, 0x67, 0xE9, 0x22, 0x96, 0x71, + 0xD2, 0xB9, 0xA3, 0xE8, 0x61, 0x49, 0x20, 0x7C, + 0xD5, 0x5B, 0x49, 0xCF, 0x57, + + 0x4B, 0xA0, 0x49, 0xB0, 0xEE, 0xB4, 0xED, 0x67, + 0x08, 0x08, 0x9D, 0xBB, 0x9F, 0xD8, 0x79, 0xE8, + 0x42, 0x71, 0x81, 0xDA, 0x5E, 0x8D, 0x90, 0x1B, + 0x4C, 0x9E, 0x71, 0xCF, 0x46, 0xEB, 0xE7, 0x14, + 0x96, 0x98, 0xA5, 0xDB, 0xFA, 0x35, 0x99, 0x4C, + 0x40, 0x21, 0x5D, 0xF8, 0xB5, 0xC5, 0xAE, 0xE5, + 0x29, 0x68, 0x5F, 0x4A, 0xE9, 0x1D, 0x15, 0x55, + 0xF1, 0x4F, 0x74, 0xD4, 0x15, 0xB3, 0x7D, 0x9F, + 0x37, 0xC8, 0xC8, 0xAF, 0xF1, 0xF0, 0x8D, 0xC4, + 0xF8, 0x36, 0xF0, 0x7A, 0xB9, 0xE6, 0xB8, 0xA9, + 0x66, 0x10, 0xDF, 0xFE, 0x16, 0x7C, 0x8E, 0xDE, + 0x57, 0x0C, 0x75, 0xBF, 0x67, 0x8C, 0x39, 0x49, + 0xF1, 0x66, 0x1D, 0xF2, 0x0D, 0x6D, 0xBB, 0xB4, + 0xC3, 0xC7, 0xD7, 0xE1, 0xB3, 0xEB, 0xE2, 0x0C, + 0x69, 0x4E, 0xC3, 0x60, 0x5B, 0x2B, 0xD5, 0x71, + 0x1D, 0x33, 0xF6, 0x9D, 0xBC, 0xAE, 0x0C, 0x7E, + 0x3B, 0x75, 0x16, 0x73, 0x1D, 0xD5, 0xFA, 0x71, + 0x04, 0xA1, 0x76, 0xA8, 0xCF, 0xB2, 0xD1, 0x8D, + 0x00, 0x83, 0x47, 0x14, 0x28, 0x13, 0x22, 0xF6, + 0x2C, 0xF1, 0xCF, 0xC1, 0xB9, 0x8F, 0x18, 0x42, + 0x88, 0x28, 0x9B, 0x0D, 0xFF, 0xEA, 0x2D, 0xD3, + 0xF8, 0xC5, 0x26, 0x49, 0x67, 0xB4, + + 0x5A, 0xE7, 0x15, 0x4E, 0x9B, 0xC6, 0x57, 0xBD, + 0x13, 0x39, 0xD7, 0xDA, 0x9A, 0xBA, 0x06, 0xDA, + 0x73, 0xEC, 0x64, 0xBF, 0xF4, 0x29, 0xEB, 0x4D, + 0x6B, 0x9A, 0xA2, 0x0F, 0x77, 0x6F, 0xBC, 0x2B, + 0xC5, 0x3F, 0xE8, 0xF0, 0x5A, 0x46, 0x88, 0x3C, + 0x4F, 0xC0, 0x44, 0xE7, 0xAC, 0x89, 0xED, 0xF6, + 0xF3, 0xF2, 0xE1, 0xB7, 0x24, 0x75, 0xAB, 0x72, + 0xC1, 0x06, 0x0E, 0x5D, 0x02, 0x5E, 0x57, 0xA6, + 0xA3, 0x4E, 0x4A, 0xFE, 0x46, 0xF0, 0xB4, 0xDD, + 0x2F, 0xAB, 0xD6, 0xED, 0x49, 0x68, 0x6B, 0xE3, + 0x5D, 0xFF, 0x11, 0x67, 0xA0, 0x38, 0xD1, 0xB6, + 0x6E, 0x98, 0x61, 0x88, 0xA5, 0x60, 0x3E, 0x74, + 0xFB, 0xF6, 0x47, 0x5D, 0xB4, 0xB0, 0x1F, 0xB0, + 0xD0, 0xE8, 0x7B, 0xB7, 0xD4, 0x7D, 0xA1, 0xAF, + 0xD5, 0xD8, 0x5B, 0x83, 0xDF, 0x82, 0x29, 0xA8, + 0xB1, 0x50, 0x2A, 0x06, 0xA6, 0xC0, 0x4C, 0xC0, + 0x96, 0xA4, 0xDB, 0x95, 0x61, 0x19, 0x4E, 0x1E, + 0xB8, 0x79, 0x45, 0x48, 0xCA, 0x22, 0xFD, 0x20, + 0x9E, 0x0E, 0xE1, 0xD7, 0x28, 0x00, 0x16, 0x50, + 0x42, 0xE4, 0x72, 0xB0, 0x61, 0x41, 0xA4, 0x93, + 0x9D, 0xB9, 0x0D, 0x7F, 0x2F, 0xBB, 0xD3, 0x89, + 0xA1, 0xBB, 0xCF, 0xE6, 0xE0, 0x09, 0x52, + + 0x0B, 0x8D, 0x85, 0x02, 0x46, 0xFB, 0x2D, 0x5A, + 0x4A, 0xB7, 0xC1, 0x3A, 0x8C, 0x4D, 0xA0, 0xBD, + 0x43, 0x52, 0xE1, 0x83, 0xA5, 0x6C, 0x78, 0x10, + 0xC1, 0xF1, 0xDF, 0x77, 0x66, 0x2C, 0x30, 0x82, + 0x12, 0x06, 0xBD, 0x79, 0x0A, 0xBD, 0x80, 0x92, + 0xF2, 0xCF, 0xB3, 0x50, 0xF7, 0x3A, 0x80, 0xE2, + 0xE5, 0xB6, 0xC8, 0x65, 0xFF, 0xB9, 0x75, 0x84, + 0x89, 0xB3, 0x63, 0x75, 0xA8, 0xA1, 0x45, 0x3E, + 0x46, 0x97, 0x4A, 0x09, 0xFF, 0xAC, 0x5B, 0xF9, + 0x25, 0x79, 0x49, 0x70, 0xA8, 0x87, 0x95, 0x8D, + 0x59, 0x2F, 0x27, 0x85, 0x02, 0x78, 0x30, 0x9F, + 0x72, 0xDB, 0x11, 0x88, 0x85, 0x09, 0xD4, 0x4B, + 0x71, 0x39, 0xF4, 0x68, 0xFB, 0x40, 0x63, 0x71, + 0xAA, 0xFC, 0x6C, 0xE3, 0x2A, 0xF1, 0x45, 0xF4, + 0xE8, 0x0E, 0x8E, 0xF4, 0xA3, 0xC9, 0x37, 0xA0, + 0xEF, 0xDE, 0x9C, 0x92, 0x42, 0x36, 0x95, 0x30, + 0x0A, 0x9A, 0x06, 0xB8, 0xEB, 0x5C, 0xE2, 0x85, + 0x40, 0x7C, 0x2A, 0xBD, 0xC6, 0x63, 0xCE, 0xBB, + 0x20, 0xC0, 0x1F, 0xE1, 0x5B, 0xDD, 0xD9, 0x62, + 0x2D, 0x30, 0x79, 0xBB, 0x49, 0x65, 0x2A, 0x12, + 0x82, 0x7A, 0x8D, 0x2F, 0xFC, 0xF7, 0xB4, 0x17, + 0x1B, 0x69, 0x5B, 0x90, 0x6D, 0x07, 0x0D, 0x5B, + + 0x99, 0x09, 0x0A, 0xFD, 0xC2, 0x22, 0x9F, 0x2B, + 0x4E, 0xD3, 0x2E, 0x38, 0x10, 0x2F, 0x9D, 0xD4, + 0x5E, 0xFC, 0x93, 0x77, 0x7B, 0x8D, 0xD3, 0xB9, + 0x5E, 0x1C, 0x17, 0x29, 0x4D, 0x0A, 0xA9, 0x5D, + 0x3E, 0xA9, 0x59, 0xD9, 0xBA, 0xF9, 0x5B, 0x21, + 0xF8, 0x59, 0xA8, 0xD5, 0x5C, 0x7E, 0x01, 0xDA, + 0xE5, 0x4F, 0x81, 0x1C, 0xD7, 0x63, 0x16, 0xA4, + 0x2D, 0xE6, 0xFA, 0xAA, 0x18, 0x8C, 0x87, 0xF7, + 0xF2, 0x7C, 0x38, 0x0C, 0x08, 0xD6, 0xA4, 0x1E, + 0x61, 0x19, 0xE7, 0xE9, 0x5B, 0x7C, 0x8F, 0x1A, + 0xB6, 0x4B, 0x7E, 0x78, 0x12, 0x22, 0xF4, 0xCA, + 0x59, 0xAE, 0x69, 0xC7, 0x22, 0x1D, 0xF6, 0xBB, + 0xFC, 0xEF, 0x70, 0x47, 0x0E, 0x5F, 0x85, 0x75, + 0x26, 0xA9, 0x07, 0xFA, 0x6C, 0x59, 0x67, 0x14, + 0x0B, 0x86, 0xCD, 0xA4, 0x84, 0xD9, 0xB1, 0xCF, + 0xC4, 0x26, 0x40, 0x55, 0x3E, 0xFA, 0x5F, 0x08, + 0x0A, 0x89, 0x56, 0x6F, 0x3A, 0xFF, 0xE4, 0x46, + 0x63, 0x93, 0xB9, 0xDE, 0x2C, 0x57, 0x26, 0x96, + 0x38, 0x03, 0x01, 0x80, 0x02, 0x44, 0xBA, 0x96, + 0x20, 0x7C, 0x7C, 0x76, 0x1C, 0x0C, 0x0D, 0x72, + 0x56, 0x28, 0xFD, 0x9F, 0xCB, 0xD5, 0xEE, 0x92, + 0x61, 0x5C, 0x6F, 0x0A, 0x70, 0xBA, 0xD3, 0xFB, + 0xD5, + + 0x79, 0xFE, 0xFA, 0xEB, 0xF2, 0x35, 0xB1, 0x0C, + 0x46, 0x53, 0x2E, 0x26, 0xCE, 0x1A, 0x6E, 0x36, + 0xD0, 0xD1, 0x4C, 0x2B, 0x55, 0x02, 0x8C, 0x39, + 0xA4, 0xC4, 0x14, 0x9B, 0x05, 0x83, 0x80, 0x8A, + 0xE6, 0x05, 0x7E, 0x0A, 0xE9, 0x1A, 0xBC, 0xBD, + 0xAE, 0xDE, 0xCF, 0x33, 0xC4, 0xAB, 0x10, 0x66, + 0x52, 0x56, 0x4D, 0xEA, 0xBD, 0xE2, 0xDA, 0xC8, + 0x77, 0x1D, 0x26, 0x8C, 0xD5, 0x9A, 0x01, 0xFD, + 0xFB, 0x49, 0x89, 0xB8, 0xE1, 0xD0, 0x48, 0x49, + 0x44, 0x23, 0xE2, 0xEF, 0x11, 0x74, 0x67, 0x5E, + 0x14, 0x01, 0x15, 0xEC, 0x39, 0x9B, 0x0A, 0x69, + 0x7C, 0x87, 0xC2, 0xE9, 0x58, 0x05, 0xDE, 0x15, + 0xA2, 0x71, 0x50, 0x73, 0x12, 0x5E, 0x5B, 0x87, + 0x6E, 0xAE, 0xD3, 0x8F, 0x95, 0xE9, 0x77, 0xEF, + 0x2F, 0xD3, 0x63, 0x5B, 0x40, 0xBB, 0xDD, 0xF0, + 0x01, 0x08, 0x7A, 0x5C, 0x92, 0xB6, 0x37, 0xC9, + 0xEB, 0x84, 0x07, 0x65, 0x92, 0xFC, 0xC6, 0xB3, + 0x68, 0x37, 0xED, 0x62, 0xD1, 0x70, 0xD4, 0xBD, + 0x28, 0xD3, 0x46, 0x94, 0x63, 0xD9, 0x56, 0xBE, + 0x93, 0xEC, 0x8A, 0x01, 0xB5, 0xBD, 0xC6, 0x9B, + 0x75, 0x08, 0x06, 0x08, 0xF1, 0xFB, 0x3F, 0xB0, + 0x3E, 0x18, 0x35, 0xF3, 0xFA, 0x85, 0x1A, 0xA7, + 0x9A, 0x8E, + + 0x17, 0x73, 0x8A, 0x98, 0x3B, 0x5B, 0xAD, 0x53, + 0x01, 0x84, 0x65, 0x88, 0xB4, 0x47, 0x4D, 0xC8, + 0x8C, 0x13, 0x47, 0x75, 0xB5, 0x03, 0x43, 0x64, + 0xE5, 0x8D, 0x56, 0xC1, 0xC0, 0x85, 0xE8, 0x25, + 0xE7, 0x2F, 0xC1, 0x98, 0x58, 0xE7, 0x2D, 0xD7, + 0x4D, 0x2B, 0xE0, 0x2D, 0x87, 0x67, 0x72, 0x7E, + 0xA1, 0xAE, 0xF3, 0x86, 0x88, 0xE4, 0x69, 0x23, + 0x30, 0x27, 0xA3, 0x48, 0xDC, 0xA0, 0x67, 0xCC, + 0x54, 0x31, 0xB2, 0xB7, 0x24, 0x23, 0xB9, 0x4A, + 0x5A, 0x07, 0x65, 0x4C, 0x2D, 0x5A, 0x9A, 0x4E, + 0xB4, 0xA6, 0x70, 0xFF, 0x69, 0x3E, 0xD2, 0xC9, + 0x55, 0x2E, 0x4F, 0xC4, 0x2F, 0x1F, 0x89, 0x98, + 0x76, 0x45, 0x5F, 0xBD, 0x3A, 0x8C, 0xB6, 0x55, + 0x93, 0xB0, 0xA7, 0x4E, 0x75, 0xBD, 0x7D, 0x25, + 0x08, 0x8C, 0xAD, 0x13, 0x33, 0x24, 0x57, 0xA9, + 0x1C, 0x44, 0x71, 0x86, 0x7E, 0xC4, 0xC4, 0x1C, + 0x5B, 0x1E, 0x83, 0x37, 0x1B, 0x37, 0x98, 0x9A, + 0xB4, 0xDC, 0xA1, 0xC2, 0x1A, 0x69, 0x89, 0xE1, + 0xD9, 0x67, 0x41, 0x58, 0x72, 0x6A, 0xF8, 0x22, + 0x69, 0xEA, 0x53, 0xF5, 0x3C, 0x5E, 0x53, 0x5D, + 0x98, 0x9A, 0x2A, 0xDA, 0xF6, 0x30, 0xA0, 0xBA, + 0xCE, 0xF8, 0xB7, 0x4D, 0xE2, 0xBF, 0x05, 0xAA, + 0xF7, 0x44, 0x84, + + 0x97, 0xDD, 0xB6, 0xB9, 0xD3, 0xA3, 0x8A, 0x20, + 0x05, 0x15, 0xD1, 0x14, 0x69, 0x33, 0x98, 0xFF, + 0x77, 0xDA, 0x47, 0x11, 0xC3, 0x59, 0x19, 0xFB, + 0x86, 0xEE, 0x3A, 0xB9, 0x4F, 0x61, 0x07, 0x6C, + 0x7B, 0x01, 0x89, 0x87, 0x1E, 0xA0, 0xBB, 0x34, + 0x60, 0x89, 0xAA, 0xE9, 0xE5, 0x03, 0xE4, 0xF7, + 0xA7, 0x16, 0xD0, 0xA9, 0x08, 0x3F, 0xA1, 0x25, + 0x57, 0xB4, 0xAD, 0x52, 0x80, 0x53, 0xB3, 0x3B, + 0x58, 0x58, 0x96, 0x37, 0x25, 0xEB, 0x08, 0xD9, + 0x63, 0xFA, 0x1F, 0xC8, 0x92, 0xF0, 0x50, 0x0D, + 0xAE, 0xFB, 0x16, 0x2E, 0xA7, 0xB1, 0x1E, 0x71, + 0x46, 0xCE, 0xE6, 0xA9, 0x4B, 0x67, 0xAC, 0xD8, + 0xC7, 0x01, 0x18, 0xA0, 0x83, 0xD5, 0xBA, 0xA9, + 0x94, 0xCD, 0x2C, 0x8C, 0x90, 0x86, 0xE9, 0x80, + 0x3E, 0x94, 0x0B, 0x0C, 0xDD, 0xF0, 0xB8, 0xFE, + 0x29, 0x9D, 0x9F, 0xAB, 0x16, 0xE6, 0x08, 0x12, + 0x67, 0x29, 0x45, 0x57, 0x4D, 0xB9, 0x08, 0xF3, + 0x44, 0x4E, 0x5C, 0x9C, 0x92, 0x69, 0xF6, 0x41, + 0x90, 0x17, 0x92, 0xF5, 0x1B, 0x8B, 0xBB, 0x89, + 0x2E, 0x3A, 0x7F, 0xAF, 0x82, 0x59, 0xA4, 0x94, + 0x53, 0x40, 0xF5, 0x6A, 0x2A, 0xF5, 0xA8, 0x4F, + 0x48, 0x2D, 0x01, 0x61, 0x6A, 0x98, 0xFD, 0xF8, + 0xBC, 0x46, 0xFC, 0x6F, + + 0x2F, 0x20, 0x5D, 0x1C, 0xAC, 0x77, 0x49, 0x4E, + 0x6A, 0x21, 0x43, 0x6D, 0x67, 0x9C, 0xF6, 0x87, + 0xC9, 0xAF, 0x8B, 0x58, 0xF0, 0xCB, 0x8B, 0x9C, + 0x41, 0x7D, 0x77, 0x66, 0xFF, 0x9D, 0x6D, 0xA5, + 0x23, 0xAC, 0x7E, 0x35, 0x18, 0xC1, 0x8E, 0x96, + 0x5F, 0x9B, 0xD8, 0xDF, 0xEA, 0xA1, 0x1A, 0x4E, + 0xE5, 0x43, 0x6E, 0x05, 0xE7, 0xBF, 0x0B, 0x81, + 0xD5, 0x73, 0x6C, 0x37, 0x43, 0x82, 0xF4, 0x40, + 0x8F, 0x6E, 0xA2, 0x7B, 0xEC, 0x28, 0x7B, 0xD5, + 0xA1, 0xCB, 0x38, 0xF1, 0x62, 0x5F, 0xCC, 0xCF, + 0xB5, 0x87, 0x38, 0x03, 0x5D, 0x1E, 0xC9, 0x01, + 0x4C, 0xE1, 0x97, 0xD7, 0xC5, 0x92, 0xE2, 0xEB, + 0x5B, 0x49, 0xC3, 0xB9, 0xB9, 0x9D, 0x16, 0x8D, + 0x54, 0x57, 0xB7, 0x08, 0xA9, 0xF2, 0x1E, 0x2B, + 0x6B, 0x8C, 0x0C, 0x1E, 0xD6, 0x8D, 0x0E, 0xA6, + 0x51, 0xB5, 0xC7, 0x02, 0xC1, 0x34, 0x92, 0x95, + 0x8A, 0xEA, 0xF3, 0xCD, 0x37, 0x54, 0x09, 0x74, + 0x47, 0x04, 0x93, 0x73, 0xD9, 0x91, 0x31, 0x33, + 0x91, 0x4E, 0xF5, 0x08, 0x0A, 0x8A, 0x50, 0x15, + 0x9F, 0x08, 0x36, 0xC5, 0x74, 0xEF, 0x2B, 0xD2, + 0x1E, 0x05, 0xD1, 0xB7, 0x2E, 0x57, 0x3B, 0x25, + 0x0F, 0x91, 0x65, 0x48, 0xEB, 0x2F, 0xF3, 0xDB, + 0xF8, 0xE2, 0x7B, 0xAF, 0x93, + + 0xB0, 0xC5, 0x54, 0xAD, 0x36, 0x9B, 0x5C, 0x03, + 0x86, 0x9C, 0x35, 0x73, 0xD5, 0xF9, 0x0F, 0x5F, + 0xEF, 0x3A, 0xFF, 0x73, 0x9E, 0xC4, 0xDB, 0x64, + 0x4F, 0x3E, 0xEF, 0xD2, 0x32, 0x5A, 0x7F, 0xA5, + 0xBF, 0x2C, 0x81, 0x00, 0xBB, 0xFA, 0x5F, 0x98, + 0x86, 0x71, 0x26, 0x39, 0x8F, 0xB7, 0x84, 0x38, + 0x9D, 0xE4, 0xF7, 0x99, 0x21, 0xB9, 0x0D, 0xF7, + 0x6F, 0x7F, 0xB8, 0x68, 0x8F, 0x7E, 0x7E, 0x4F, + 0xA7, 0x15, 0x2A, 0x82, 0xFC, 0x60, 0xCF, 0x70, + 0xE9, 0x86, 0xBD, 0x24, 0xA1, 0xBA, 0x30, 0xB2, + 0x70, 0x66, 0xBC, 0x6F, 0x1C, 0x39, 0x94, 0xB5, + 0x81, 0x3C, 0x54, 0x98, 0x3C, 0x82, 0xE3, 0xF8, + 0x6D, 0x3C, 0x1B, 0x5A, 0x7A, 0x81, 0x7A, 0x29, + 0xEF, 0x48, 0x3B, 0x35, 0x3F, 0x73, 0xF0, 0x05, + 0x12, 0xB6, 0xC9, 0x2D, 0xDA, 0xCB, 0x81, 0xBD, + 0xEE, 0x8F, 0x8E, 0xE7, 0x06, 0x8D, 0xD2, 0x76, + 0x39, 0x60, 0xF2, 0x57, 0xD6, 0xE5, 0xFC, 0x81, + 0x14, 0x49, 0xB4, 0x6B, 0x06, 0x6E, 0x33, 0xDC, + 0x2C, 0x2F, 0x4E, 0x15, 0xC8, 0xC2, 0x41, 0x95, + 0xA8, 0x65, 0x59, 0xCA, 0x97, 0xD8, 0xA0, 0x4A, + 0x1F, 0xCA, 0x35, 0xC5, 0x21, 0xBD, 0x51, 0x29, + 0x2B, 0x0A, 0x1B, 0x37, 0x4C, 0xF7, 0xAA, 0x88, + 0xDF, 0x44, 0x88, 0x05, 0x2F, 0x4B, + + 0x50, 0xDC, 0xA7, 0x8B, 0xED, 0x47, 0x10, 0x06, + 0x63, 0xCB, 0x7D, 0x5B, 0xE6, 0xB0, 0xED, 0x90, + 0x55, 0xF0, 0x38, 0x3C, 0x80, 0x34, 0x2B, 0x62, + 0x92, 0xC5, 0x61, 0x0D, 0xEC, 0x0E, 0xD3, 0xEA, + 0xD6, 0x81, 0xB8, 0x4D, 0xC6, 0x3E, 0xC5, 0x19, + 0x70, 0x31, 0x0F, 0x2C, 0x65, 0x07, 0x0F, 0x43, + 0x2F, 0xA0, 0x63, 0xD7, 0xFB, 0x9B, 0xD1, 0xA9, + 0x60, 0x3C, 0xFE, 0x4E, 0x09, 0xAF, 0xC7, 0x04, + 0x4A, 0xE6, 0x75, 0x18, 0xF6, 0x53, 0x87, 0x91, + 0xD6, 0x33, 0x15, 0x9C, 0x32, 0xA0, 0x52, 0x82, + 0xC7, 0xF9, 0x17, 0x9C, 0x58, 0x2C, 0xBC, 0x75, + 0x88, 0x1B, 0x7D, 0x71, 0xC3, 0xCC, 0xFE, 0x60, + 0x08, 0xDD, 0xB0, 0x5F, 0x45, 0x49, 0x08, 0x91, + 0xF6, 0x42, 0x97, 0x85, 0xBB, 0xF7, 0x04, 0xAB, + 0xFF, 0xB6, 0xB6, 0x37, 0xA3, 0xA8, 0x1D, 0x41, + 0x52, 0x9F, 0x47, 0xC2, 0xD4, 0xE1, 0x32, 0x22, + 0x26, 0xF5, 0x26, 0x0A, 0x03, 0xD5, 0xDD, 0x37, + 0x95, 0xBB, 0xC0, 0xEF, 0x4C, 0x61, 0xC9, 0x87, + 0x43, 0x88, 0x22, 0xE9, 0x5F, 0x30, 0x0A, 0x64, + 0x73, 0xF3, 0x2F, 0xD2, 0x4D, 0xE8, 0x91, 0x1C, + 0x68, 0xBE, 0x35, 0xC3, 0xF4, 0xC4, 0xD3, 0xD2, + 0x01, 0xB2, 0x19, 0x28, 0x30, 0x86, 0xD9, 0xFC, + 0x16, 0x4A, 0x0E, 0xCC, 0xCA, 0xD6, 0xF6, + + 0x74, 0xAF, 0x14, 0xA0, 0x6E, 0x50, 0x25, 0x74, + 0x8F, 0xC7, 0x16, 0x03, 0x56, 0x10, 0x01, 0x76, + 0x5B, 0x63, 0xD0, 0xEF, 0x4E, 0xA7, 0x59, 0x27, + 0x43, 0x0C, 0x3F, 0x8C, 0xFD, 0xB6, 0x09, 0x17, + 0x81, 0xD7, 0xEC, 0x94, 0x50, 0x4B, 0xC8, 0x22, + 0x3F, 0x82, 0x11, 0xA1, 0x58, 0x8C, 0x23, 0xBB, + 0x8B, 0xFB, 0x4F, 0x34, 0x31, 0x98, 0x63, 0x1B, + 0xC4, 0x8E, 0xCF, 0x12, 0x57, 0x68, 0x14, 0x2B, + 0x23, 0xA9, 0x9D, 0x17, 0x84, 0x2A, 0x53, 0xE7, + 0x67, 0x5A, 0xC1, 0x6E, 0x65, 0x25, 0x70, 0x25, + 0x76, 0x70, 0x30, 0x24, 0x85, 0xF8, 0x1F, 0x9D, + 0xFD, 0x8D, 0x84, 0xAD, 0x33, 0x07, 0xFD, 0x21, + 0x01, 0x13, 0xC0, 0x14, 0x20, 0xF2, 0xDC, 0x81, + 0x21, 0xEF, 0x3A, 0xCB, 0x32, 0x23, 0xB2, 0x76, + 0x3B, 0xA4, 0x30, 0xB6, 0x8F, 0x90, 0xE3, 0x20, + 0x4C, 0x81, 0x6A, 0xF4, 0x2C, 0xC3, 0x4C, 0x86, + 0x08, 0x86, 0x1E, 0x31, 0x48, 0x55, 0x7E, 0xF2, + 0xA7, 0xF5, 0xC6, 0x22, 0x19, 0x87, 0xE5, 0x6E, + 0xA6, 0xC5, 0x31, 0xF6, 0x1D, 0xA4, 0xD8, 0x75, + 0x90, 0x1C, 0x57, 0x01, 0xF5, 0xE8, 0x53, 0x3E, + 0x0A, 0x16, 0xDD, 0x40, 0x58, 0x0C, 0xE0, 0x8F, + 0xBF, 0x57, 0xFA, 0x1D, 0x37, 0x15, 0xC6, 0x63, + 0xC1, 0x57, 0x0C, 0x6D, 0x83, 0x6C, 0xA4, 0x0E, + + 0x6A, 0x33, 0x55, 0x52, 0x04, 0x3E, 0x41, 0x83, + 0x22, 0xED, 0x2A, 0xAC, 0x33, 0xEF, 0xA6, 0xA9, + 0x8E, 0x21, 0x9D, 0x2B, 0xFB, 0x20, 0x80, 0x22, + 0x0F, 0x7A, 0xB4, 0x67, 0xFF, 0x76, 0xFA, 0x1D, + 0x1B, 0x26, 0xF9, 0xD4, 0x3A, 0x66, 0x99, 0x4C, + 0xFD, 0x45, 0x61, 0x96, 0x02, 0x3F, 0xD3, 0x13, + 0xE4, 0x44, 0x30, 0x30, 0x6B, 0x76, 0x77, 0xEA, + 0x66, 0x69, 0x1B, 0x82, 0xE6, 0xA2, 0x50, 0x69, + 0xFD, 0x5D, 0xAD, 0x59, 0x82, 0x94, 0xA1, 0xF3, + 0x78, 0x5B, 0x00, 0x7B, 0x6E, 0xE9, 0xA2, 0xB9, + 0xB4, 0x56, 0xF9, 0xD5, 0x5C, 0x42, 0x89, 0xA5, + 0x7E, 0x86, 0xFE, 0x61, 0x6C, 0xF1, 0x0A, 0xFC, + 0xC9, 0x7D, 0x9C, 0xF0, 0xE7, 0x7F, 0xFE, 0xCD, + 0x85, 0xEC, 0x68, 0x68, 0xC5, 0x6F, 0x06, 0x35, + 0x4B, 0xA6, 0x15, 0xF8, 0x38, 0xF5, 0x1B, 0x56, + 0x20, 0x75, 0xCE, 0xA4, 0xCB, 0x5F, 0x60, 0x96, + 0xE7, 0xEF, 0x71, 0x1B, 0x1D, 0xF5, 0xD1, 0x96, + 0xA1, 0x9C, 0x64, 0xFA, 0x2F, 0x88, 0x9C, 0x87, + 0x53, 0xC5, 0x08, 0xE5, 0x93, 0xD0, 0x6E, 0xDB, + 0xA1, 0x84, 0x1C, 0x49, 0x79, 0x38, 0x48, 0xDD, + 0x6B, 0xD0, 0x80, 0x52, 0x51, 0x4A, 0x96, 0x9C, + 0x4A, 0x48, 0xB3, 0x9B, 0x86, 0x2F, 0xDC, 0x32, + 0x34, 0x27, 0x04, 0xAB, 0x37, 0xB2, 0x50, 0x6C, + 0xB8, + + 0x86, 0x42, 0xAF, 0x92, 0x97, 0x70, 0x4B, 0x6A, + 0xC3, 0x85, 0x01, 0xE0, 0xFE, 0x10, 0x0A, 0x58, + 0xD8, 0xF8, 0x1F, 0x0C, 0xA0, 0xF3, 0x41, 0x40, + 0x1F, 0x90, 0x54, 0x07, 0x52, 0x34, 0x2C, 0xC8, + 0x20, 0x3A, 0xA5, 0x1D, 0x12, 0x59, 0xC5, 0xCA, + 0x3F, 0x60, 0x7E, 0x9F, 0xB0, 0xB3, 0x66, 0x99, + 0x67, 0xD6, 0x0B, 0x05, 0x54, 0xB5, 0xE3, 0x7E, + 0xC6, 0x97, 0xF3, 0xD5, 0xC0, 0x73, 0xE9, 0xE2, + 0x70, 0x20, 0x78, 0x15, 0x74, 0x2F, 0x19, 0xCC, + 0x0F, 0xA9, 0xCC, 0xE1, 0xAE, 0x60, 0x6A, 0x05, + 0x97, 0xE4, 0x5A, 0x6F, 0xF9, 0xB6, 0x40, 0x31, + 0xE1, 0x41, 0xF2, 0x72, 0x3E, 0xB2, 0xEB, 0x78, + 0x33, 0x7E, 0x0A, 0xB4, 0x39, 0xE3, 0xEE, 0x99, + 0x17, 0x6C, 0x2F, 0x2F, 0xA8, 0x3C, 0x2C, 0xFC, + 0x70, 0x53, 0x53, 0x14, 0x82, 0x62, 0xCA, 0x55, + 0x23, 0x20, 0xFF, 0x7F, 0xC5, 0xE9, 0x28, 0xB9, + 0xA2, 0x15, 0x82, 0x6B, 0xED, 0x1C, 0xBB, 0xD6, + 0x74, 0x8E, 0xE5, 0x2F, 0x54, 0x97, 0x05, 0xAB, + 0x88, 0xF8, 0x6E, 0x5E, 0x45, 0x52, 0x61, 0x3B, + 0xCD, 0x9F, 0x3E, 0xE0, 0x43, 0x30, 0x37, 0x73, + 0x50, 0xE3, 0x21, 0x29, 0xAA, 0x48, 0x7B, 0xDE, + 0x50, 0x2B, 0xBC, 0x34, 0xBF, 0xB3, 0x0F, 0xF7, + 0xCB, 0x78, 0x4B, 0xDE, 0x7B, 0x1D, 0xAC, 0xFC, + 0xEB, 0x03, + + 0x76, 0xD3, 0x4B, 0xE8, 0x19, 0x32, 0xEE, 0xA7, + 0xD5, 0x21, 0xE4, 0xFF, 0x60, 0x32, 0xED, 0xE4, + 0x6D, 0xC3, 0xE2, 0xA4, 0xD2, 0xEC, 0x0B, 0x41, + 0x8E, 0xF2, 0xE3, 0x83, 0x84, 0x18, 0xE5, 0xF4, + 0xBA, 0xE7, 0x17, 0xED, 0xF7, 0xF6, 0xC8, 0x6C, + 0xA9, 0xC7, 0xF7, 0x23, 0x9E, 0x0F, 0xEC, 0x4C, + 0x51, 0x20, 0xB8, 0xEF, 0x02, 0xCC, 0xFF, 0xBB, + 0xDE, 0x1C, 0x47, 0x8A, 0xAB, 0x2D, 0xDF, 0xF6, + 0x86, 0x0B, 0xC8, 0xFB, 0xDE, 0x24, 0x64, 0x1F, + 0x99, 0x4F, 0x44, 0xC9, 0x78, 0x45, 0xD2, 0x2A, + 0x7A, 0x3B, 0x1C, 0xC5, 0xD8, 0x87, 0x29, 0xEB, + 0x5E, 0x02, 0x12, 0x93, 0xF7, 0xED, 0x21, 0xFF, + 0x50, 0xDB, 0xD9, 0xD4, 0x0B, 0x1C, 0xC9, 0x1D, + 0xF2, 0x1F, 0x9C, 0x93, 0x2F, 0xDA, 0x90, 0xB0, + 0xF9, 0x25, 0x4F, 0x25, 0xE7, 0x64, 0xB4, 0xD6, + 0x78, 0xB3, 0x68, 0xD8, 0x46, 0xCF, 0xE4, 0xC7, + 0x15, 0x28, 0xC2, 0x34, 0x6E, 0xB2, 0x4F, 0x12, + 0xD2, 0x89, 0xDE, 0x77, 0xDA, 0x58, 0x40, 0x62, + 0x8B, 0x55, 0xF7, 0x80, 0x82, 0x3C, 0xC3, 0xAC, + 0x7C, 0xF4, 0x2E, 0xDD, 0xC4, 0x70, 0x52, 0x63, + 0x17, 0x7F, 0x44, 0xF7, 0x65, 0x59, 0x3D, 0x91, + 0x95, 0x18, 0xB0, 0xA4, 0xA0, 0xAF, 0x52, 0x3A, + 0xD3, 0xC0, 0xDD, 0x0C, 0x00, 0xC1, 0xD7, 0xA6, + 0x1D, 0x5E, 0x35, + + 0xC5, 0x4F, 0x57, 0x22, 0xF0, 0xE2, 0x42, 0xEE, + 0x03, 0x5C, 0xDE, 0x88, 0x0A, 0x6E, 0xEB, 0xA4, + 0x41, 0xEF, 0x55, 0x9D, 0x37, 0x21, 0xAE, 0x2A, + 0xA9, 0x9D, 0x92, 0xDC, 0xCF, 0x5F, 0xD3, 0x28, + 0x23, 0x5D, 0x22, 0xDB, 0x89, 0x31, 0x4D, 0x60, + 0x08, 0x92, 0x78, 0x3A, 0x5D, 0xAE, 0x91, 0x1A, + 0x93, 0xCD, 0x4D, 0x62, 0x40, 0xA2, 0x18, 0x1A, + 0x6B, 0xCE, 0x34, 0x0D, 0x3B, 0x09, 0xC6, 0xE6, + 0x3F, 0x1B, 0x88, 0x19, 0x14, 0x29, 0xAD, 0x75, + 0x06, 0x1B, 0xD9, 0xE2, 0xEC, 0xE7, 0x1B, 0xC9, + 0x7A, 0xD3, 0x18, 0x86, 0xE7, 0x36, 0xAD, 0x21, + 0x7D, 0xA2, 0xDC, 0x1C, 0x97, 0xBA, 0xB2, 0xCB, + 0x59, 0x19, 0x7D, 0x20, 0xC5, 0x68, 0xB8, 0xBD, + 0x51, 0x49, 0x5B, 0x45, 0xAB, 0x47, 0x33, 0x63, + 0xA2, 0xEC, 0x4C, 0x2D, 0x69, 0x91, 0x27, 0x86, + 0x72, 0x28, 0xDB, 0x96, 0x55, 0x5D, 0x1A, 0x2F, + 0x7E, 0x5D, 0xC6, 0x0A, 0x69, 0xAB, 0x8C, 0x8B, + 0x36, 0x87, 0xB4, 0x1A, 0x15, 0xE4, 0x68, 0x21, + 0xDB, 0x65, 0x87, 0xBA, 0x24, 0xBD, 0x1F, 0xFA, + 0x5C, 0x4B, 0x48, 0x21, 0x83, 0xD8, 0x04, 0x50, + 0x31, 0x83, 0xF7, 0x21, 0xC5, 0xA8, 0xA9, 0x8A, + 0x5E, 0xC6, 0x1C, 0x40, 0x8E, 0x29, 0xB3, 0xF2, + 0xA8, 0x86, 0xED, 0x60, 0xCA, 0xF8, 0x24, 0x7F, + 0x09, 0xAE, 0x36, 0x3F, + + 0x6D, 0x99, 0x39, 0x36, 0xA1, 0x3E, 0x29, 0x65, + 0x55, 0xA1, 0x90, 0x10, 0xB5, 0x49, 0x64, 0xE3, + 0x09, 0xB2, 0xDB, 0x65, 0xF1, 0x5E, 0x05, 0x1E, + 0x0E, 0x6A, 0x8C, 0x38, 0xDF, 0xE1, 0xB8, 0x87, + 0x15, 0x2C, 0xCB, 0x4D, 0xD7, 0x44, 0xDB, 0x3B, + 0x80, 0xA2, 0xEA, 0x9A, 0x7A, 0xA8, 0x39, 0xE2, + 0x33, 0xFC, 0x40, 0xCD, 0x92, 0xB8, 0x62, 0x1D, + 0x9E, 0xC7, 0x65, 0x65, 0x3C, 0x24, 0x6A, 0x77, + 0x11, 0xA5, 0xEE, 0x86, 0x19, 0x5E, 0xCF, 0x01, + 0xF7, 0x74, 0x64, 0xAA, 0xDF, 0xD3, 0x0B, 0x54, + 0xF8, 0xEB, 0x9F, 0xE5, 0x3B, 0x9B, 0x3A, 0xCB, + 0x36, 0x65, 0xA6, 0xD3, 0x8B, 0x5D, 0xD3, 0x55, + 0xC4, 0xD6, 0x26, 0x46, 0x5D, 0x66, 0x4E, 0xEB, + 0x7F, 0xB3, 0x1F, 0x36, 0x12, 0x92, 0x50, 0xF4, + 0xE3, 0x2B, 0x90, 0x32, 0xFF, 0x56, 0x90, 0x81, + 0xC3, 0x52, 0x7A, 0x26, 0x67, 0xA5, 0x4E, 0xC1, + 0x3B, 0xB9, 0x44, 0x4B, 0x6F, 0x96, 0xD7, 0xD4, + 0xE9, 0x67, 0x10, 0x36, 0xD8, 0xAB, 0xC3, 0x0C, + 0x17, 0xCF, 0xC1, 0x38, 0xC9, 0xD6, 0x7B, 0xB9, + 0xFC, 0xF9, 0x1D, 0x49, 0x87, 0x84, 0xCF, 0x86, + 0x72, 0xFD, 0x95, 0x15, 0xBF, 0x27, 0x1F, 0xAB, + 0x64, 0x81, 0xCF, 0x99, 0x96, 0x2E, 0x15, 0x57, + 0xA5, 0xD7, 0x7D, 0x0E, 0xB9, 0xDC, 0x6A, 0x44, + 0xFC, 0x80, 0x80, 0x66, 0x2E, + + 0x9C, 0x95, 0xB5, 0x62, 0xE3, 0x90, 0x98, 0xF3, + 0x02, 0x26, 0x65, 0x18, 0x99, 0x4B, 0xCC, 0x67, + 0x42, 0xCF, 0x7B, 0x21, 0xC4, 0xB7, 0x97, 0x99, + 0x50, 0xBD, 0x05, 0x49, 0xB4, 0xA3, 0x9E, 0xCA, + 0x85, 0xD1, 0xD0, 0x65, 0xF3, 0x69, 0x8E, 0x21, + 0x49, 0xCA, 0x23, 0x89, 0x8F, 0x9A, 0x03, 0x7B, + 0xB0, 0x55, 0xE4, 0x21, 0x7D, 0x00, 0xC1, 0xFA, + 0xBC, 0x24, 0x65, 0x5C, 0x83, 0x67, 0x5B, 0x97, + 0x01, 0xCB, 0x00, 0x82, 0xF2, 0xA1, 0x3E, 0xE8, + 0xCC, 0xCE, 0x00, 0x5A, 0x79, 0xB5, 0xF7, 0x13, + 0xD8, 0x9D, 0x57, 0x8F, 0x98, 0x49, 0x80, 0x72, + 0xC4, 0xA5, 0x7C, 0x03, 0x91, 0x77, 0x1F, 0x82, + 0x07, 0x42, 0x88, 0x36, 0x00, 0x9B, 0x09, 0x87, + 0x90, 0xE6, 0x6C, 0x53, 0xF6, 0x3A, 0x5F, 0x6E, + 0x71, 0xA3, 0xDB, 0x58, 0x49, 0x69, 0xCC, 0x9B, + 0x69, 0x85, 0x43, 0xFF, 0x1E, 0xEA, 0x53, 0x3C, + 0xF5, 0xD9, 0x7C, 0x63, 0xF6, 0x85, 0xEB, 0xE0, + 0xE9, 0x20, 0x6F, 0xB1, 0x5F, 0xFE, 0xEA, 0xF1, + 0x30, 0x1F, 0x7E, 0x61, 0x10, 0x74, 0x29, 0x06, + 0xB4, 0x9F, 0xAC, 0xA5, 0x3E, 0xC1, 0xAF, 0xF8, + 0x6A, 0x3F, 0x7E, 0xDE, 0x75, 0x67, 0xB7, 0x79, + 0xAB, 0x96, 0x82, 0xD9, 0x52, 0x08, 0xC9, 0xEA, + 0x1F, 0x69, 0xBF, 0xF6, 0xEA, 0xE2, 0x6F, 0x7B, + 0xB7, 0x2F, 0xED, 0xA8, 0x50, 0xD4, + + 0x5E, 0xAA, 0x52, 0xBD, 0xD4, 0x77, 0xAF, 0x8B, + 0x18, 0x01, 0xE0, 0xF7, 0xC4, 0xE7, 0x4B, 0x86, + 0xAB, 0x7D, 0x11, 0xE6, 0x70, 0x98, 0x34, 0x7C, + 0x53, 0x63, 0x75, 0xFE, 0xE8, 0xB4, 0x7A, 0x95, + 0x59, 0x0A, 0x4D, 0x78, 0x65, 0x7E, 0x93, 0xEE, + 0xD0, 0x84, 0x3D, 0xE0, 0xB6, 0xA2, 0x2D, 0x8A, + 0x36, 0x68, 0x04, 0xB4, 0x84, 0x38, 0x14, 0x1E, + 0x7A, 0x61, 0x6B, 0x60, 0xA0, 0x4A, 0xE1, 0x7D, + 0x4B, 0xB8, 0x8F, 0x31, 0x49, 0x66, 0xE2, 0x3E, + 0x73, 0xE5, 0xE1, 0x73, 0xB9, 0x9A, 0x4D, 0xAD, + 0xD5, 0xED, 0x42, 0x53, 0x41, 0x42, 0x21, 0x2E, + 0xC3, 0x36, 0x8B, 0x0A, 0x40, 0xB5, 0xB4, 0x0C, + 0xB3, 0xF0, 0x53, 0x34, 0xD7, 0xE5, 0xE0, 0x70, + 0xB1, 0xEA, 0x86, 0x5E, 0x9A, 0x39, 0x30, 0x95, + 0x84, 0xC7, 0x57, 0x93, 0xC9, 0x7A, 0xF6, 0x10, + 0x3D, 0x3F, 0x68, 0x33, 0xC3, 0x4F, 0x45, 0x36, + 0xB0, 0xA4, 0xDF, 0x58, 0xE8, 0xB7, 0x4A, 0x42, + 0x8C, 0x6D, 0x04, 0xCF, 0x24, 0xA5, 0x69, 0x95, + 0xDE, 0x04, 0xC3, 0xA8, 0xDD, 0xE3, 0x78, 0x44, + 0xA0, 0x9F, 0x11, 0x9B, 0xB4, 0xA2, 0x27, 0x7A, + 0x15, 0xA3, 0x9D, 0x27, 0x80, 0x35, 0xB4, 0x9F, + 0x33, 0xBE, 0x27, 0x3A, 0xE1, 0x1F, 0x67, 0x97, + 0x1D, 0x1A, 0x7D, 0x11, 0x59, 0xEF, 0x01, 0x5E, + 0x8E, 0xD9, 0xA8, 0x16, 0x94, 0x54, 0xD9, + + 0x49, 0x52, 0x78, 0x3A, 0x42, 0x33, 0x66, 0xEF, + 0x71, 0xB1, 0xF3, 0x8B, 0x98, 0xB2, 0x65, 0x8A, + 0x8A, 0x5D, 0xE8, 0x6B, 0x9B, 0xFB, 0xEF, 0x15, + 0x86, 0x3C, 0x68, 0x1D, 0x3A, 0x5C, 0xA7, 0xD8, + 0x3B, 0x33, 0x95, 0xF0, 0x9C, 0xB8, 0xA6, 0x92, + 0x11, 0x79, 0xB2, 0xD9, 0x3C, 0x18, 0x7F, 0xBB, + 0xF9, 0xAA, 0x43, 0x01, 0xD1, 0x7D, 0xC7, 0xB7, + 0x0D, 0x49, 0x44, 0x0D, 0x36, 0x0B, 0xD9, 0xC6, + 0x54, 0x79, 0x0A, 0x63, 0x79, 0x86, 0xBD, 0x0B, + 0xC4, 0x03, 0xF5, 0xFC, 0x1E, 0x37, 0xE5, 0x24, + 0x30, 0x5A, 0x35, 0x1D, 0x13, 0xE8, 0x35, 0x9E, + 0x42, 0x0F, 0xDA, 0xB1, 0x80, 0xD1, 0xE6, 0xE5, + 0x7A, 0xD5, 0xFE, 0x66, 0x8B, 0x38, 0xD7, 0x5E, + 0xD8, 0xE0, 0x67, 0xC0, 0xE0, 0x06, 0x10, 0xE6, + 0x18, 0xC7, 0x7A, 0xF4, 0xCF, 0xFD, 0xB2, 0xB4, + 0x1C, 0xF5, 0x46, 0x7D, 0xDF, 0x7C, 0x83, 0xA5, + 0xAB, 0xC3, 0x7C, 0xE1, 0x3F, 0x0A, 0xA3, 0xAA, + 0x37, 0x9F, 0x86, 0x8F, 0xAD, 0x26, 0xB8, 0x84, + 0xF4, 0x91, 0xF7, 0x19, 0x0A, 0x7B, 0x1B, 0x46, + 0x63, 0x43, 0x08, 0x41, 0x07, 0x0D, 0x19, 0xF1, + 0xFF, 0x8D, 0x23, 0xF1, 0xE8, 0x42, 0x54, 0x4C, + 0xBC, 0x89, 0x34, 0xA3, 0x90, 0xDC, 0x8A, 0x9F, + 0xA0, 0xFD, 0xC9, 0x65, 0xAB, 0x6B, 0x29, 0x71, + 0x6C, 0xA9, 0xF4, 0x77, 0x50, 0xA5, 0xEA, 0xBB, + + 0x9C, 0xB1, 0xAA, 0x0D, 0xDB, 0xC1, 0x1A, 0x9C, + 0x5C, 0x98, 0x93, 0xD8, 0x01, 0xC7, 0xFE, 0x24, + 0xBC, 0x60, 0x5F, 0x0D, 0xA4, 0x50, 0xC2, 0x9D, + 0x11, 0x34, 0xDE, 0x31, 0xE9, 0xD2, 0x45, 0x49, + 0x6F, 0xC2, 0x91, 0x8C, 0x75, 0x1D, 0xB8, 0xD8, + 0x27, 0xA1, 0x5F, 0xF2, 0x66, 0xBA, 0xD2, 0x5C, + 0xD6, 0xBB, 0x5B, 0x45, 0x57, 0x08, 0xF3, 0x0A, + 0x5C, 0x58, 0xAA, 0x0B, 0x79, 0x12, 0x2F, 0x2D, + 0x42, 0x37, 0xCD, 0x5C, 0xB3, 0xF1, 0x8F, 0x34, + 0xE2, 0x61, 0xC3, 0x45, 0xFC, 0xFF, 0x96, 0x53, + 0x0B, 0x1A, 0x71, 0xB5, 0x5F, 0xA2, 0x12, 0x26, + 0x78, 0xCC, 0xBD, 0x5A, 0x84, 0x35, 0xAE, 0xF2, + 0xA3, 0xC3, 0x42, 0x5F, 0x51, 0x22, 0x77, 0x91, + 0x08, 0xDF, 0x1C, 0x68, 0xAE, 0x0F, 0x51, 0x79, + 0x4E, 0x75, 0xED, 0x8D, 0x55, 0x2A, 0x54, 0x88, + 0x97, 0xF8, 0x90, 0x24, 0x14, 0xE3, 0x07, 0x4D, + 0xCD, 0x26, 0x06, 0xA7, 0x35, 0xCF, 0x6A, 0x38, + 0xB7, 0x98, 0x2F, 0xA8, 0xAE, 0x6C, 0x3D, 0xB5, + 0x1E, 0x37, 0xD1, 0xE9, 0xD4, 0x53, 0x67, 0x4B, + 0xA4, 0xAE, 0xFA, 0x51, 0x01, 0x40, 0x8B, 0xD1, + 0x09, 0x74, 0x4C, 0x7F, 0xB2, 0xFA, 0xF9, 0xA8, + 0x27, 0xAF, 0xC8, 0x24, 0x2C, 0x31, 0xA1, 0xF6, + 0xF8, 0x81, 0xAC, 0xB4, 0x02, 0x83, 0x6F, 0x49, + 0xCF, 0xEC, 0xDF, 0x71, 0x5E, 0x2F, 0x33, 0x07, + 0xBA, + + 0x55, 0xA8, 0x19, 0x38, 0x4C, 0x45, 0x5C, 0xF7, + 0x03, 0x9A, 0x21, 0x1B, 0xFF, 0xA8, 0xF7, 0x76, + 0x3E, 0xF2, 0x8E, 0xF1, 0xCD, 0x69, 0xDB, 0x0F, + 0xF6, 0x1C, 0x6A, 0x92, 0x71, 0xEF, 0x4A, 0x3E, + 0xCE, 0xF9, 0xEA, 0xAB, 0x76, 0x6B, 0x1E, 0xB5, + 0x02, 0x61, 0xA7, 0x02, 0x76, 0xBA, 0x6B, 0x1D, + 0xE5, 0xF0, 0x12, 0xDF, 0x1D, 0x61, 0x82, 0x90, + 0x91, 0xDA, 0x96, 0x60, 0x89, 0x88, 0x83, 0xCD, + 0xBF, 0xAC, 0xA8, 0x86, 0xC4, 0x7F, 0xA5, 0xA3, + 0x3E, 0x50, 0xC4, 0x8B, 0x30, 0xD8, 0x98, 0x89, + 0x0E, 0x10, 0xA3, 0x77, 0x64, 0xBF, 0x44, 0xE8, + 0x7B, 0xF4, 0x56, 0xA2, 0x87, 0x06, 0xF6, 0xF0, + 0x98, 0x77, 0x92, 0x5D, 0xED, 0x6A, 0x29, 0x33, + 0x22, 0x31, 0xD5, 0x3A, 0xD4, 0xDB, 0x11, 0x34, + 0x7D, 0xA0, 0xFC, 0x96, 0x54, 0x61, 0x16, 0x2C, + 0x48, 0x6C, 0x55, 0x2B, 0xE0, 0x8C, 0xE3, 0x7F, + 0x05, 0x32, 0xFB, 0xCE, 0xD4, 0x2F, 0x47, 0x54, + 0xE5, 0x9D, 0x6B, 0x68, 0x85, 0xF0, 0xD6, 0xCD, + 0xEA, 0xB6, 0x48, 0x59, 0xA8, 0xE6, 0x0B, 0x80, + 0x21, 0x2A, 0x62, 0x74, 0x1E, 0xD9, 0x11, 0x9A, + 0x16, 0x8A, 0xB0, 0xC5, 0x2C, 0xF2, 0x77, 0x80, + 0x0D, 0x74, 0x24, 0xE9, 0x29, 0x65, 0x47, 0x1F, + 0xEE, 0xF0, 0xA4, 0x26, 0xAF, 0xC5, 0x4B, 0x83, + 0x67, 0x23, 0x7C, 0x2E, 0x54, 0x29, 0x88, 0xD0, + 0x6A, 0xCB, + + 0x35, 0x07, 0x1D, 0x30, 0xAA, 0x5F, 0xC8, 0x44, + 0xDA, 0x6D, 0xB6, 0xCB, 0x0B, 0xD6, 0x54, 0x54, + 0x48, 0x98, 0x07, 0xE6, 0xB0, 0x33, 0x48, 0xCF, + 0xB7, 0xAF, 0x58, 0xF6, 0x2A, 0x09, 0xD2, 0x7A, + 0xB5, 0xB4, 0x93, 0x6C, 0xC3, 0x83, 0xFB, 0x17, + 0xE5, 0xBF, 0xDD, 0xE3, 0x10, 0x37, 0x69, 0xF9, + 0x90, 0xEE, 0x65, 0x1E, 0x8F, 0x82, 0x14, 0xC5, + 0x38, 0xF3, 0x96, 0x22, 0x63, 0x81, 0xD4, 0x7A, + 0x23, 0x2E, 0x9A, 0xFD, 0xD4, 0xBB, 0xE1, 0x56, + 0xDD, 0xB6, 0xD0, 0x77, 0x0C, 0x88, 0x50, 0x18, + 0xE3, 0x25, 0xBC, 0x33, 0x36, 0xB0, 0xD9, 0x65, + 0xD2, 0xC2, 0xAA, 0x26, 0xB4, 0x52, 0xEF, 0x8B, + 0x19, 0x74, 0x14, 0x69, 0xB9, 0x60, 0x0B, 0x59, + 0x2C, 0xC7, 0x74, 0x0F, 0x6B, 0xF7, 0x5C, 0x4F, + 0xC7, 0xC8, 0xED, 0xFF, 0x1F, 0x02, 0x46, 0x46, + 0x93, 0x38, 0x6F, 0x34, 0x2A, 0x0C, 0xEC, 0x3E, + 0x3F, 0xAA, 0xA0, 0xEB, 0x43, 0x24, 0x84, 0x55, + 0xAF, 0x43, 0x08, 0x0B, 0xDD, 0x0D, 0x9D, 0x01, + 0x5C, 0x47, 0x27, 0x47, 0x3A, 0x0D, 0xA8, 0x27, + 0xAE, 0x04, 0x25, 0x27, 0x5D, 0xF6, 0x19, 0x6B, + 0x2E, 0x5A, 0x1B, 0x70, 0xBD, 0xB3, 0x44, 0x23, + 0x59, 0x4F, 0xE4, 0xA0, 0x02, 0x78, 0x22, 0xA6, + 0x25, 0xA8, 0x55, 0x59, 0xB5, 0xA0, 0x60, 0x47, + 0x57, 0x1F, 0x62, 0xC2, 0x16, 0x38, 0x7D, 0x86, + 0xB9, 0x0F, 0x8A, + + 0xDD, 0x6E, 0xDE, 0x6B, 0x5B, 0x0B, 0xEA, 0xD1, + 0xB1, 0xB9, 0xD8, 0xA3, 0xCE, 0xE3, 0x95, 0x79, + 0x16, 0x68, 0x90, 0x54, 0x7A, 0xC4, 0x4E, 0x77, + 0x95, 0xD6, 0xBE, 0xAF, 0x0E, 0xE0, 0x88, 0xDA, + 0x28, 0xF2, 0xEA, 0x52, 0x77, 0xFE, 0x7F, 0xAA, + 0x3D, 0xD4, 0xCA, 0x1B, 0xBC, 0xAC, 0xC5, 0x0D, + 0xE2, 0x50, 0x70, 0x57, 0x12, 0x14, 0x54, 0x97, + 0x22, 0x3E, 0x43, 0x82, 0x0F, 0xA1, 0xA8, 0x93, + 0x4A, 0xD3, 0x7E, 0xE1, 0x1E, 0xBE, 0xD5, 0x3E, + 0x36, 0x61, 0xB1, 0x0A, 0x85, 0x6F, 0x3B, 0xF4, + 0x60, 0x39, 0xEE, 0xE5, 0x81, 0x88, 0xC2, 0x6E, + 0x24, 0xAC, 0xBD, 0x0C, 0x25, 0xE7, 0xAB, 0xB0, + 0xC8, 0xA1, 0x8F, 0x09, 0xE3, 0xCA, 0x77, 0xE3, + 0x50, 0x80, 0x6A, 0x42, 0x94, 0x2C, 0x43, 0x85, + 0x71, 0xB8, 0x4A, 0xCC, 0xBA, 0x0C, 0x5D, 0xBF, + 0x2C, 0xF8, 0x36, 0x5D, 0x79, 0xFB, 0x3C, 0x11, + 0x15, 0x7C, 0x47, 0xDD, 0xC7, 0x26, 0x71, 0x44, + 0xAF, 0x17, 0xAE, 0x74, 0xF1, 0xC5, 0xE0, 0x00, + 0x5C, 0xF0, 0x96, 0x38, 0x86, 0x1A, 0x7F, 0xA1, + 0xBC, 0x0E, 0x32, 0xCA, 0x54, 0xBF, 0x5F, 0xEA, + 0x76, 0x31, 0x1B, 0x1B, 0x70, 0xE5, 0xB9, 0xA8, + 0x18, 0x58, 0xF4, 0x31, 0x92, 0xDD, 0x25, 0xB6, + 0xF5, 0xC1, 0x6B, 0x0D, 0xFC, 0x97, 0x29, 0xD1, + 0x6F, 0xE2, 0xCD, 0xC6, 0x41, 0x24, 0x28, 0x68, + 0x42, 0x23, 0x34, 0xF5, + + 0xC7, 0xD2, 0x23, 0x12, 0x22, 0x4E, 0x47, 0x8E, + 0xB9, 0x0E, 0x31, 0x80, 0xA3, 0xB3, 0x72, 0xE1, + 0xB4, 0xE6, 0x43, 0x4C, 0x9C, 0xDE, 0xBD, 0x34, + 0x79, 0xD8, 0x2D, 0x82, 0xA2, 0x79, 0x64, 0x54, + 0x13, 0x9C, 0xFC, 0x21, 0x3A, 0x7C, 0xFC, 0x84, + 0x87, 0xB6, 0x94, 0xD8, 0x8E, 0x6A, 0xBD, 0xA7, + 0xC5, 0x2E, 0xC6, 0x88, 0x46, 0xF9, 0xA3, 0xFE, + 0x66, 0x6D, 0x10, 0xB3, 0x07, 0x27, 0xDE, 0xDC, + 0x84, 0xEC, 0xFB, 0x15, 0xC7, 0x6C, 0x9E, 0x3E, + 0x03, 0x41, 0x29, 0x8F, 0x06, 0xDB, 0xF1, 0x5E, + 0x21, 0xB7, 0x5E, 0x42, 0x9C, 0x7D, 0x21, 0xC8, + 0x78, 0x5E, 0x6E, 0x19, 0x77, 0x21, 0x41, 0xF6, + 0x5D, 0x2F, 0x6A, 0xC1, 0xCB, 0xB8, 0x62, 0x4B, + 0xDD, 0xD4, 0xBE, 0x2E, 0xAD, 0x05, 0x6E, 0x4F, + 0x96, 0x4C, 0x02, 0x5D, 0x75, 0xE7, 0x0E, 0x50, + 0xA5, 0x45, 0xB3, 0x47, 0xAC, 0xAE, 0xED, 0x0C, + 0x94, 0x6A, 0x5E, 0x4A, 0x66, 0xE9, 0x2A, 0x2A, + 0x5B, 0x00, 0xA7, 0xEC, 0xDE, 0xE7, 0xE8, 0xAA, + 0x01, 0x51, 0x4F, 0x2B, 0x67, 0x95, 0x2E, 0xA7, + 0xE3, 0x05, 0x9D, 0x45, 0x40, 0x68, 0x7F, 0xBB, + 0x98, 0xCB, 0x54, 0x8C, 0xEB, 0x29, 0xAD, 0xE2, + 0xA6, 0x8C, 0xBB, 0x33, 0xCD, 0xB2, 0x79, 0x6E, + 0x37, 0x01, 0xEB, 0xF6, 0x19, 0x70, 0x08, 0x08, + 0x17, 0x4F, 0x8E, 0x45, 0x2A, 0x8A, 0x97, 0x91, + 0x8D, 0x4F, 0x53, 0x4B, 0x3F, + + 0xCA, 0x0D, 0x28, 0x4B, 0x0A, 0x4D, 0xD4, 0x03, + 0xDA, 0xAA, 0x7E, 0x33, 0x7D, 0x98, 0x9D, 0xE0, + 0x5B, 0x29, 0x94, 0x19, 0xA4, 0xD8, 0xC7, 0xF8, + 0x11, 0xF0, 0xD9, 0x18, 0x9A, 0x17, 0x1A, 0x14, + 0xE1, 0x4E, 0x4F, 0x09, 0x45, 0x7D, 0x17, 0xE9, + 0xB7, 0xA2, 0x6B, 0x0A, 0xE6, 0x17, 0x57, 0x05, + 0x24, 0xDC, 0xC6, 0x75, 0xAE, 0xBC, 0xAE, 0x32, + 0x1B, 0x60, 0x5A, 0x5D, 0x77, 0xB4, 0x42, 0x48, + 0x99, 0xE7, 0xB5, 0xEB, 0xE5, 0x7A, 0x10, 0x93, + 0x5D, 0x81, 0xCA, 0x01, 0x2F, 0x41, 0xD4, 0x0F, + 0xDE, 0xBE, 0xC4, 0x59, 0xC3, 0xDB, 0xDE, 0xF3, + 0x14, 0xFC, 0xC5, 0x8B, 0x22, 0xCC, 0x6A, 0x3F, + 0x0C, 0xCC, 0x53, 0x3D, 0x39, 0x0C, 0x83, 0xED, + 0x51, 0x54, 0x4A, 0xD9, 0x2D, 0x0C, 0x5E, 0x1D, + 0x0B, 0x82, 0x73, 0x0C, 0x41, 0xCD, 0x8D, 0xD0, + 0xD9, 0xD3, 0x7C, 0x8D, 0x3D, 0xFA, 0xA9, 0x51, + 0xE5, 0x13, 0x8B, 0x81, 0x32, 0x62, 0xAB, 0xB6, + 0xB1, 0xF2, 0x1C, 0x5C, 0xE6, 0x9A, 0xB0, 0x83, + 0x40, 0x92, 0xB8, 0x85, 0x22, 0x7E, 0x53, 0x9A, + 0x0F, 0x87, 0xDD, 0xBA, 0x20, 0x83, 0xE4, 0x93, + 0xDE, 0x35, 0x8E, 0xBD, 0x2F, 0xA3, 0x04, 0xF2, + 0x87, 0x62, 0x9E, 0xD9, 0x72, 0xBC, 0xC7, 0x0C, + 0x8F, 0x6F, 0x48, 0x93, 0x0D, 0x48, 0x9B, 0x21, + 0xA7, 0xD4, 0x12, 0x0C, 0x06, 0x61, 0x9D, 0xC2, + 0x45, 0x51, 0x17, 0x6D, 0xD2, 0x95, + + 0x15, 0x94, 0x79, 0xF5, 0xEB, 0x7F, 0xDD, 0x18, + 0x2E, 0x9C, 0x4B, 0xA0, 0xD2, 0x3D, 0xEF, 0x37, + 0x82, 0xDB, 0xDC, 0xFB, 0x8D, 0x07, 0x87, 0x30, + 0x89, 0x79, 0x31, 0xB1, 0x27, 0xAF, 0x6B, 0x9B, + 0x0C, 0xAB, 0xA3, 0x72, 0xA4, 0xE3, 0x96, 0x7B, + 0x61, 0x4F, 0xB4, 0x0D, 0xD1, 0x64, 0x9D, 0xD5, + 0x3D, 0x0F, 0x24, 0x3C, 0xFF, 0x39, 0xA3, 0x08, + 0x7E, 0xD0, 0x4A, 0x14, 0xF2, 0x16, 0x08, 0x12, + 0x58, 0x6F, 0xE4, 0xC3, 0xEE, 0x77, 0xDA, 0xF0, + 0x21, 0x0E, 0x8A, 0xFB, 0x19, 0x46, 0x08, 0xCF, + 0x47, 0x93, 0x76, 0xE8, 0x15, 0x7F, 0x07, 0xC7, + 0x44, 0x4A, 0x35, 0xA9, 0x65, 0x58, 0xF6, 0x21, + 0xCA, 0x2E, 0xAD, 0xE1, 0x21, 0xE2, 0x25, 0x8F, + 0x87, 0xA4, 0xFD, 0xE1, 0xEF, 0xE9, 0x25, 0x70, + 0x7E, 0x41, 0x4D, 0x5A, 0x20, 0xC6, 0x0C, 0xD4, + 0xE5, 0x49, 0xF3, 0xB9, 0xDB, 0xE5, 0xCE, 0x21, + 0x1D, 0xE5, 0xA9, 0x73, 0x5E, 0x91, 0xFA, 0x86, + 0x5A, 0x25, 0x52, 0x27, 0xF5, 0x4C, 0x92, 0xC1, + 0x14, 0x52, 0x0E, 0x78, 0x6E, 0xCD, 0x8F, 0x0F, + 0xD5, 0x40, 0x42, 0x01, 0xD1, 0x6A, 0xD2, 0xCE, + 0xD8, 0xC0, 0x6A, 0x3E, 0x82, 0xF0, 0x41, 0x0D, + 0x44, 0x24, 0xE2, 0x43, 0xA3, 0xE8, 0x68, 0x12, + 0x46, 0x2E, 0x7A, 0x72, 0x04, 0xE0, 0xE6, 0x38, + 0x4D, 0x62, 0x7F, 0x02, 0x59, 0x17, 0x8F, 0xB9, + 0x75, 0x74, 0x25, 0x7F, 0x95, 0xBF, 0x9C, + + 0xC5, 0x38, 0x2D, 0xA3, 0x3D, 0xF8, 0x27, 0x28, + 0x56, 0x3E, 0x35, 0x24, 0x8D, 0x8F, 0x56, 0xBD, + 0xA9, 0x6D, 0x58, 0x99, 0x12, 0xC7, 0xAB, 0x4A, + 0xE0, 0xF7, 0xDE, 0x1E, 0xF0, 0x40, 0x89, 0x0C, + 0xE4, 0x7B, 0xF8, 0x7B, 0x8C, 0x1B, 0x6F, 0xC1, + 0xD4, 0x6E, 0xEF, 0x45, 0x2E, 0x7E, 0x03, 0x0F, + 0x3B, 0x0F, 0x48, 0x28, 0x8D, 0x8C, 0xAF, 0x9E, + 0xB3, 0x55, 0x6B, 0xA7, 0xAA, 0x03, 0x94, 0x21, + 0xED, 0x7A, 0x92, 0x81, 0x12, 0x37, 0xAF, 0x4B, + 0xE1, 0x34, 0x62, 0xC6, 0x7D, 0x5E, 0xA8, 0xD6, + 0x9A, 0xB8, 0x12, 0xF0, 0xB8, 0x7E, 0x92, 0x88, + 0xDB, 0x67, 0x97, 0x56, 0x88, 0xA4, 0x22, 0x18, + 0xFC, 0xC3, 0xCD, 0x1B, 0x12, 0x09, 0xC9, 0xD6, + 0x71, 0xE1, 0x76, 0xED, 0x95, 0x61, 0x96, 0xF9, + 0xB1, 0xFA, 0x16, 0x9F, 0xDC, 0x3A, 0x3C, 0x9A, + 0xFB, 0x25, 0x0A, 0x0C, 0x8B, 0xFB, 0xD1, 0x7E, + 0x13, 0x27, 0x5B, 0x24, 0x95, 0xC4, 0x6B, 0xAC, + 0x32, 0xB5, 0x1D, 0xC9, 0x96, 0x67, 0x84, 0x43, + 0x5C, 0xAD, 0xD2, 0xF2, 0x15, 0xDA, 0x83, 0x84, + 0x71, 0xB2, 0x14, 0x04, 0x20, 0xDD, 0x04, 0x78, + 0x6E, 0xCD, 0x7F, 0x73, 0xD1, 0xAD, 0xBE, 0xD4, + 0x4F, 0xED, 0xF8, 0xE9, 0xEA, 0x07, 0xBD, 0xB7, + 0xDD, 0x0F, 0xFB, 0xF5, 0x88, 0x6A, 0x3E, 0x8A, + 0xCD, 0x79, 0xBA, 0xDE, 0x98, 0xB3, 0x74, 0x3D, + 0x0F, 0x92, 0x40, 0x10, 0xE4, 0x26, 0x85, 0x2D, + + 0x0E, 0x46, 0xBD, 0x8B, 0xDC, 0xE8, 0x28, 0x6A, + 0x31, 0x78, 0xE6, 0xDE, 0x37, 0xC0, 0x68, 0x2D, + 0xE0, 0x38, 0xD0, 0x2F, 0x28, 0xBB, 0xA2, 0xF4, + 0x8F, 0x82, 0x35, 0xDF, 0x0F, 0xB9, 0x31, 0x98, + 0xF6, 0x03, 0x66, 0x80, 0xCF, 0xDA, 0xF0, 0x0B, + 0x4C, 0x62, 0x2F, 0x6E, 0x7A, 0x1B, 0x80, 0x98, + 0x7A, 0xDB, 0x1F, 0x2B, 0xC2, 0x2F, 0x96, 0x80, + 0x58, 0x98, 0x21, 0xFC, 0xBB, 0x1A, 0x13, 0xAF, + 0x56, 0xA5, 0x4A, 0x89, 0xDB, 0xF0, 0x28, 0x97, + 0x43, 0xB6, 0x45, 0xBF, 0x58, 0x76, 0x78, 0x8A, + 0x83, 0xF8, 0x6E, 0xC1, 0x90, 0x99, 0x59, 0x0A, + 0xF2, 0x1E, 0x95, 0x8A, 0x13, 0x58, 0xC0, 0xC7, + 0x8F, 0x27, 0xD9, 0x53, 0xEC, 0xD0, 0x24, 0xFC, + 0x83, 0x60, 0x74, 0x24, 0x2D, 0xD5, 0xE5, 0x51, + 0x27, 0x0E, 0x62, 0x17, 0xD4, 0xAA, 0xF1, 0x30, + 0x6F, 0x35, 0x4C, 0xE0, 0x91, 0x2D, 0xDA, 0x11, + 0x68, 0xDF, 0x6F, 0xEA, 0x29, 0xC0, 0xB4, 0x75, + 0x04, 0x4E, 0xB7, 0x49, 0x47, 0x19, 0xA1, 0x7F, + 0x99, 0x0B, 0x45, 0x95, 0x3F, 0x6A, 0x97, 0x8B, + 0xA8, 0x27, 0x1C, 0xBF, 0x07, 0x7D, 0x30, 0xD9, + 0x97, 0xD7, 0xA5, 0x2D, 0x22, 0x23, 0xF7, 0x1D, + 0xFD, 0x4A, 0xE9, 0xA8, 0xFD, 0x10, 0xE4, 0xEF, + 0x0F, 0xBB, 0x54, 0x2B, 0xFC, 0x74, 0xDE, 0x55, + 0xF7, 0x51, 0xBF, 0x8B, 0x73, 0x38, 0xF8, 0x5E, + 0xFF, 0x8C, 0x96, 0xFF, 0xFA, 0x82, 0x67, 0xC7, + 0xA6, + + 0x78, 0xC3, 0xA1, 0xCB, 0x49, 0x80, 0x93, 0x83, + 0x6D, 0x3D, 0x8C, 0xB6, 0x38, 0x79, 0x45, 0xCF, + 0x65, 0x32, 0x71, 0xE6, 0x00, 0x24, 0x23, 0x45, + 0x47, 0x37, 0x84, 0x54, 0x1B, 0x7E, 0x25, 0x5B, + 0x86, 0xA5, 0x55, 0x07, 0xB4, 0x0B, 0xCD, 0x23, + 0x6B, 0xF3, 0x33, 0xCB, 0xCA, 0x7C, 0xBC, 0x7F, + 0x43, 0x50, 0x02, 0xA2, 0x45, 0x1C, 0xD3, 0x32, + 0x7C, 0x28, 0x6D, 0xA1, 0x24, 0x2A, 0x58, 0x29, + 0xC1, 0xB2, 0x6C, 0x71, 0x1A, 0xA4, 0xA9, 0xB3, + 0x27, 0xAB, 0xBC, 0xC6, 0x9F, 0x9D, 0x92, 0xB6, + 0x70, 0x99, 0xA6, 0x9B, 0xAD, 0x8A, 0x59, 0xC9, + 0x08, 0xE0, 0xFB, 0x92, 0xB0, 0x0B, 0x03, 0x75, + 0xBA, 0xC0, 0x88, 0x56, 0xF2, 0x8B, 0xCD, 0x22, + 0xB8, 0x2B, 0xEA, 0xD8, 0x79, 0xD1, 0xA5, 0xF4, + 0x98, 0xEF, 0x71, 0xE9, 0xFE, 0xBC, 0x0F, 0xEA, + 0x5B, 0x8D, 0x96, 0xF6, 0xB7, 0x03, 0xEF, 0xA6, + 0x61, 0x05, 0x8F, 0xB3, 0x0D, 0xB0, 0xCA, 0xC1, + 0xCF, 0x25, 0xB2, 0x87, 0x98, 0x13, 0xB8, 0xEC, + 0xA8, 0x54, 0xF6, 0xF5, 0x5F, 0xB2, 0x11, 0x52, + 0x14, 0xD7, 0x9E, 0x36, 0x93, 0x62, 0x3B, 0x24, + 0x92, 0x9C, 0x63, 0xB7, 0x2D, 0x18, 0xAA, 0x10, + 0x89, 0x84, 0x29, 0x16, 0xF0, 0xDF, 0x7C, 0x31, + 0x0C, 0x3E, 0x25, 0xB3, 0x72, 0x50, 0xE3, 0x51, + 0xDC, 0x12, 0x58, 0xA7, 0xED, 0x38, 0x43, 0x92, + 0x1B, 0xA5, 0x54, 0xE1, 0xC6, 0x56, 0x30, 0x65, + 0x0A, 0xA5, + + 0x02, 0xF5, 0xEC, 0x03, 0x39, 0xF9, 0x74, 0xC8, + 0xAC, 0xC7, 0xF7, 0xE5, 0x62, 0x30, 0xB3, 0x0E, + 0xBA, 0x02, 0xD6, 0x48, 0x76, 0x84, 0xDC, 0x9F, + 0xF0, 0x79, 0x39, 0x06, 0xA9, 0x82, 0x53, 0x00, + 0xAB, 0x09, 0x0C, 0x16, 0xDE, 0xC1, 0x05, 0xC8, + 0x2C, 0x92, 0x02, 0x61, 0xEA, 0x87, 0x8C, 0xFC, + 0x8A, 0x0B, 0x9F, 0x04, 0x9F, 0x51, 0x5F, 0x7B, + 0x4F, 0xAC, 0xF1, 0x4F, 0x9A, 0x29, 0x61, 0x42, + 0x8C, 0xD7, 0x23, 0x49, 0x63, 0xEB, 0xFD, 0x2C, + 0xDC, 0x76, 0xF1, 0xF0, 0xC8, 0xA2, 0x97, 0x5C, + 0x20, 0x23, 0x7C, 0x9F, 0x5D, 0xDE, 0x59, 0x87, + 0x3A, 0x33, 0xE6, 0x77, 0x83, 0xE8, 0xF7, 0xA8, + 0x31, 0x7E, 0xFA, 0x02, 0x79, 0x96, 0x13, 0xCB, + 0x08, 0xB3, 0x0E, 0x18, 0x2E, 0x2C, 0x48, 0x1B, + 0x8D, 0xF7, 0x40, 0x0F, 0xD0, 0x95, 0x29, 0x99, + 0xA9, 0x8C, 0xF5, 0xBA, 0xC3, 0xE7, 0x1E, 0x3F, + 0x34, 0x13, 0x02, 0x24, 0xF0, 0x4E, 0xC6, 0xCD, + 0xEE, 0xA1, 0xF0, 0x0F, 0xAE, 0xB8, 0x31, 0x0F, + 0x5F, 0x34, 0x4F, 0xAC, 0x17, 0x52, 0x26, 0x84, + 0xA0, 0x65, 0x88, 0x2E, 0xA2, 0x75, 0xC0, 0x18, + 0x6A, 0x2C, 0xDD, 0x0F, 0xF9, 0x0E, 0xFA, 0x56, + 0xBB, 0x71, 0xAD, 0x69, 0xCB, 0x96, 0x31, 0xCF, + 0x66, 0x1C, 0x87, 0x71, 0x77, 0x11, 0x39, 0xB7, + 0xE9, 0x25, 0x7A, 0x88, 0x8A, 0x0C, 0xE9, 0xCD, + 0x0F, 0xB9, 0x82, 0x18, 0x66, 0x2A, 0xD1, 0x91, + 0xD9, 0x4F, 0x8D, + + 0xE9, 0xF8, 0x7F, 0xAE, 0x1B, 0x66, 0x68, 0x95, + 0x73, 0xE2, 0x74, 0x01, 0xE1, 0x7D, 0x2A, 0x45, + 0xC0, 0x88, 0x27, 0xB0, 0x1A, 0x6F, 0xD0, 0x5E, + 0xA6, 0x05, 0x9D, 0x18, 0xB8, 0xA2, 0x86, 0x0E, + 0xB3, 0xF7, 0x79, 0xC3, 0x41, 0xBE, 0x1D, 0x34, + 0x69, 0x19, 0x07, 0x2F, 0x81, 0x48, 0xFC, 0xC1, + 0x35, 0xA4, 0x98, 0xFF, 0xAA, 0xA7, 0xF9, 0xC7, + 0x32, 0x63, 0xBB, 0x56, 0xA7, 0xBE, 0x31, 0x88, + 0xA1, 0x35, 0x57, 0x17, 0x1B, 0x00, 0x5A, 0x0C, + 0xAF, 0x48, 0xE8, 0xA6, 0x63, 0x5F, 0x6B, 0xB9, + 0x4D, 0x44, 0x0E, 0xCB, 0xA2, 0xDB, 0x7E, 0xBD, + 0xC1, 0x99, 0x7A, 0x02, 0xAE, 0xDF, 0x01, 0xA6, + 0x19, 0x8A, 0xA0, 0x91, 0xA8, 0x4E, 0x34, 0xF6, + 0x4A, 0x53, 0xD3, 0x44, 0xF6, 0x3C, 0x5A, 0x2D, + 0x16, 0xAD, 0x5F, 0x09, 0x0B, 0xE2, 0xE8, 0xD0, + 0xFE, 0x09, 0x6F, 0x7A, 0xDB, 0x86, 0x57, 0xA9, + 0x7B, 0x06, 0x7D, 0xC5, 0x99, 0x4C, 0xA5, 0xE2, + 0xEA, 0x18, 0x0A, 0xFD, 0xB6, 0xF2, 0x03, 0xEA, + 0xEC, 0xAF, 0x7B, 0xA1, 0x9C, 0x31, 0xDF, 0x17, + 0x74, 0x6D, 0x01, 0x9E, 0xBF, 0x76, 0x63, 0x2D, + 0x5B, 0xA0, 0xF6, 0xD1, 0xC2, 0x01, 0x40, 0xDF, + 0xE1, 0x81, 0xD6, 0xCB, 0x67, 0xC7, 0x96, 0x6C, + 0xE6, 0x34, 0x9E, 0xA5, 0x23, 0xCA, 0x9B, 0x06, + 0x96, 0x45, 0xFA, 0xB8, 0x96, 0x3A, 0x66, 0x32, + 0x5F, 0xF1, 0x92, 0xA1, 0x64, 0xF8, 0x2B, 0x90, + 0x65, 0x5D, 0xD7, 0xF8, + + 0x8F, 0xEC, 0x60, 0x90, 0x57, 0x5B, 0x8B, 0x0F, + 0xF5, 0xF9, 0xF1, 0xA6, 0x11, 0x9A, 0xE5, 0x47, + 0x50, 0x3A, 0x7D, 0x92, 0x1C, 0x2D, 0xBE, 0x3F, + 0x0B, 0x75, 0x18, 0x78, 0xD1, 0x29, 0xBA, 0x37, + 0x3F, 0xD6, 0x89, 0xE6, 0x14, 0x54, 0x58, 0x70, + 0x0F, 0x17, 0x62, 0x4E, 0xE3, 0x8E, 0xC0, 0x18, + 0x7B, 0x5C, 0xCB, 0x31, 0x95, 0x16, 0x9E, 0xEC, + 0x0B, 0x7B, 0xF4, 0x1D, 0xC6, 0x30, 0xB4, 0xBD, + 0xAA, 0x29, 0x33, 0x94, 0xCC, 0x30, 0x98, 0x44, + 0x20, 0x4E, 0xF3, 0x50, 0x9C, 0x75, 0x5C, 0xB0, + 0xB9, 0x1F, 0x60, 0xDF, 0xFA, 0x57, 0xAF, 0xC1, + 0x69, 0x50, 0xFD, 0x09, 0x9B, 0x62, 0xEB, 0xE5, + 0x9C, 0x09, 0xAB, 0x83, 0x34, 0xDE, 0x9F, 0x48, + 0xF7, 0x2B, 0x21, 0xB7, 0xC5, 0x90, 0x15, 0xFF, + 0x9D, 0x5F, 0xD7, 0x5A, 0x4F, 0x6D, 0xB7, 0x8C, + 0xD5, 0x74, 0x17, 0xEB, 0xD2, 0xF5, 0xE2, 0xCF, + 0x6E, 0xE0, 0xE3, 0xCD, 0xD7, 0x11, 0xD7, 0xA6, + 0x89, 0xF4, 0xDE, 0xEF, 0xEB, 0x77, 0xCD, 0xA3, + 0x2C, 0x1F, 0xDF, 0xED, 0x93, 0xA6, 0x51, 0xC8, + 0xD4, 0x45, 0x72, 0x11, 0x7F, 0xC8, 0x68, 0x86, + 0x4B, 0x6E, 0x13, 0x92, 0x2B, 0xDA, 0x6F, 0xE4, + 0x86, 0xBB, 0xF4, 0x71, 0x8E, 0xA4, 0x2A, 0x55, + 0x3C, 0xC6, 0x37, 0x67, 0x96, 0xFF, 0x40, 0xF9, + 0x1E, 0xDD, 0x95, 0x5A, 0x89, 0x0C, 0x07, 0x59, + 0x90, 0x4F, 0xCF, 0x83, 0xE8, 0x0B, 0x93, 0x73, + 0xAA, 0x8A, 0x15, 0x0A, 0x21, + + 0x8F, 0xB7, 0xC6, 0xB8, 0x22, 0xAE, 0x29, 0x71, + 0x39, 0xA5, 0x99, 0xC3, 0x6F, 0xBD, 0x8D, 0xF2, + 0x74, 0x24, 0x7E, 0xFF, 0x4B, 0x35, 0x63, 0xF4, + 0xD2, 0xA8, 0x55, 0xCD, 0x1A, 0x1A, 0x40, 0x64, + 0x45, 0x61, 0xD8, 0x26, 0xA0, 0x23, 0x3E, 0xDC, + 0x57, 0x05, 0xB8, 0xC4, 0xC0, 0x0C, 0xF4, 0x2E, + 0x3F, 0xBE, 0x36, 0xFB, 0x84, 0xDF, 0x5A, 0x19, + 0x87, 0x78, 0x6B, 0x31, 0x2D, 0xB5, 0x03, 0x98, + 0x92, 0x3C, 0x5F, 0xD7, 0x5F, 0x06, 0x2A, 0x00, + 0x5C, 0x7C, 0xF1, 0x4F, 0x70, 0x36, 0xBB, 0xE0, + 0xDC, 0x5B, 0x9A, 0x10, 0x87, 0x13, 0x05, 0x58, + 0xB2, 0x9C, 0xEB, 0xFE, 0xCF, 0x82, 0x03, 0x18, + 0x6A, 0x37, 0x8D, 0x11, 0xD9, 0x15, 0x1E, 0x27, + 0x54, 0x8E, 0x7A, 0x30, 0x13, 0xD8, 0x1A, 0xBB, + 0x6C, 0xAD, 0xC4, 0xFD, 0x61, 0x2E, 0x03, 0xEB, + 0x2C, 0x2D, 0x01, 0x4A, 0x3A, 0xCA, 0xDF, 0x23, + 0x8E, 0x39, 0x81, 0x6D, 0x62, 0xEE, 0x12, 0x89, + 0xC6, 0xA3, 0x1D, 0x38, 0xA9, 0xDE, 0x5D, 0x1C, + 0x3F, 0xAE, 0x79, 0xAC, 0x2A, 0x5B, 0xCD, 0x94, + 0x9F, 0xE3, 0xB8, 0x93, 0x21, 0x4E, 0x0E, 0xB4, + 0x78, 0xE6, 0xC2, 0x69, 0x7D, 0x58, 0x26, 0xDD, + 0xE1, 0xC0, 0xAB, 0xF9, 0x9F, 0xDE, 0xB0, 0xB5, + 0x24, 0x78, 0x4C, 0x5A, 0x42, 0x91, 0x8E, 0x03, + 0x95, 0xAA, 0x08, 0xD4, 0x56, 0x6D, 0x64, 0x41, + 0xC7, 0xC9, 0x2E, 0xEC, 0xE7, 0x1A, 0xEB, 0xE8, + 0x24, 0x8D, 0xE3, 0x31, 0xA5, 0x11, + + 0x05, 0x2F, 0xC0, 0x7D, 0xD7, 0xC5, 0x12, 0xF3, + 0x37, 0x94, 0x79, 0xEF, 0x44, 0xEE, 0xB0, 0xD0, + 0xED, 0x39, 0xCB, 0x5E, 0x64, 0xE9, 0x83, 0xD2, + 0x76, 0xF0, 0x65, 0x47, 0x25, 0x1D, 0x0D, 0x6B, + 0x16, 0x23, 0x98, 0xE5, 0x1D, 0xF2, 0xB1, 0x68, + 0x0D, 0xBA, 0xFE, 0x9D, 0x1A, 0x1D, 0xBA, 0x5F, + 0x92, 0x6F, 0x17, 0x76, 0xF5, 0xB3, 0xBA, 0x5A, + 0x71, 0x0C, 0x72, 0xFA, 0x32, 0xCC, 0x7B, 0x17, + 0x52, 0xB7, 0xF9, 0x86, 0x70, 0xF7, 0x39, 0x22, + 0xA1, 0xF6, 0xB3, 0xAA, 0xE9, 0xC5, 0x8B, 0x69, + 0xE4, 0x48, 0xD2, 0xAA, 0x8E, 0xAF, 0x7C, 0xE5, + 0x77, 0xE1, 0x33, 0xEC, 0x30, 0x20, 0xB8, 0xCD, + 0x3E, 0xD6, 0xB6, 0xD0, 0x64, 0x86, 0x39, 0x01, + 0x0D, 0x4F, 0xAB, 0xF7, 0x7B, 0xBE, 0x97, 0x21, + 0xCD, 0x96, 0x69, 0x16, 0x73, 0x61, 0x7D, 0x84, + 0x21, 0x3A, 0xA0, 0x07, 0xDE, 0xCA, 0x17, 0x0E, + 0x82, 0xA4, 0x8B, 0x2D, 0xE4, 0x99, 0x11, 0x3C, + 0x3C, 0x5B, 0x16, 0xB8, 0x00, 0xEE, 0xD1, 0xDF, + 0x68, 0x30, 0x0E, 0x12, 0x5E, 0x12, 0x4F, 0x1B, + 0xBE, 0xC2, 0x9B, 0x99, 0x64, 0xDB, 0xCE, 0x29, + 0xE5, 0x8E, 0x66, 0x96, 0x65, 0x37, 0x6E, 0xE2, + 0xE9, 0x05, 0x34, 0x56, 0x8D, 0xDF, 0x24, 0x34, + 0x09, 0x77, 0xB0, 0x76, 0xDD, 0x1E, 0x76, 0x5D, + 0x67, 0x7D, 0xCC, 0xCF, 0xB2, 0x7E, 0x15, 0x5E, + 0xE0, 0x4E, 0x80, 0x4B, 0xE0, 0xD2, 0x5A, 0xD4, + 0x1F, 0x5F, 0x6E, 0x65, 0x9C, 0x07, 0xBD, + + 0x08, 0x49, 0x9F, 0x83, 0x46, 0x0F, 0x0E, 0x04, + 0x94, 0x6C, 0x3F, 0x75, 0x4D, 0x98, 0xE5, 0x5D, + 0x12, 0xCB, 0xF6, 0x53, 0x0D, 0xFD, 0x30, 0x75, + 0x92, 0x02, 0xA9, 0x69, 0xD3, 0x71, 0xBC, 0x28, + 0xBC, 0x18, 0x88, 0x48, 0x27, 0x0B, 0x3B, 0x5C, + 0x2C, 0xFF, 0x7C, 0xFA, 0xB1, 0x02, 0x00, 0x79, + 0x6D, 0x8A, 0x39, 0x3F, 0xF2, 0x11, 0xA8, 0xA3, + 0x95, 0x68, 0xCA, 0x97, 0x1E, 0xD9, 0x80, 0xD8, + 0x9D, 0x4C, 0x62, 0x3E, 0xA5, 0xD0, 0x61, 0xE3, + 0x0D, 0x3D, 0xBA, 0xE7, 0x0E, 0x7F, 0x23, 0xBF, + 0x3D, 0x04, 0xB4, 0x1F, 0x20, 0x49, 0x5A, 0x40, + 0x50, 0x59, 0x2C, 0x09, 0x05, 0x5B, 0x8D, 0x07, + 0xA9, 0x79, 0x75, 0x13, 0xFF, 0xB5, 0x33, 0x58, + 0x41, 0x5D, 0x1D, 0xF1, 0x39, 0x54, 0x3A, 0x41, + 0x09, 0xDB, 0x5F, 0xC7, 0x5F, 0x7A, 0xE6, 0x27, + 0xA4, 0xFF, 0x20, 0xE8, 0x5F, 0x25, 0x89, 0xCB, + 0x77, 0x8D, 0xD7, 0x79, 0x16, 0x50, 0x68, 0xE0, + 0x24, 0xEC, 0x87, 0x60, 0xC2, 0x75, 0x87, 0xB8, + 0xAD, 0x66, 0x64, 0xF1, 0x6B, 0x01, 0x7E, 0xB0, + 0xE3, 0x79, 0x7E, 0x84, 0x29, 0x51, 0x47, 0x24, + 0xB9, 0x5D, 0xC6, 0x13, 0xEC, 0x0D, 0x5E, 0x8B, + 0x3E, 0x68, 0x97, 0x74, 0xB5, 0x1C, 0xE6, 0x9E, + 0x74, 0xD1, 0x9A, 0xE6, 0x1A, 0x6C, 0xFD, 0xBB, + 0x27, 0xC1, 0x73, 0xB1, 0x4E, 0xAC, 0x97, 0x1B, + 0x8B, 0xB2, 0x0A, 0x6A, 0x67, 0xA0, 0xA9, 0xDD, + 0x88, 0xF0, 0x55, 0x58, 0x10, 0x79, 0x9C, 0xC5, + + 0xAF, 0x48, 0x98, 0xFF, 0xF1, 0xC9, 0x67, 0xB3, + 0x74, 0xA9, 0xAC, 0xF5, 0x17, 0x7D, 0x95, 0x53, + 0x6A, 0xDD, 0xD6, 0x44, 0x3B, 0x09, 0x32, 0x78, + 0x2E, 0xEC, 0x19, 0x33, 0xD8, 0x4C, 0xFD, 0xE6, + 0xCE, 0x4A, 0x08, 0x78, 0xB5, 0xE8, 0x90, 0x1B, + 0x32, 0x04, 0x51, 0xC1, 0x4A, 0x1A, 0x69, 0xA2, + 0x0A, 0x76, 0x86, 0x73, 0x4B, 0x4C, 0xF7, 0x62, + 0xF7, 0xD0, 0x2E, 0x91, 0x8B, 0x7C, 0xFA, 0x8F, + 0xC9, 0xBE, 0x49, 0x9B, 0x1C, 0x58, 0xF8, 0x14, + 0xD1, 0x07, 0x4A, 0x4D, 0xE4, 0xB3, 0x83, 0x0A, + 0xD3, 0xF9, 0xDD, 0xC1, 0x2F, 0x84, 0x15, 0x02, + 0xA8, 0xB7, 0xB8, 0x45, 0x05, 0x99, 0x71, 0xEE, + 0xC6, 0x3B, 0xC4, 0xC3, 0x6F, 0x10, 0x63, 0x17, + 0x11, 0xD0, 0x1F, 0x1C, 0x63, 0xB9, 0x3F, 0x3D, + 0x68, 0x0A, 0x39, 0x25, 0x95, 0xB9, 0x81, 0xA7, + 0x04, 0x64, 0x6B, 0x2E, 0x52, 0xD0, 0x56, 0x04, + 0x99, 0x4F, 0x1B, 0x8E, 0xB0, 0x29, 0xA5, 0x3C, + 0x17, 0x46, 0xEC, 0x36, 0xC2, 0xD0, 0xAD, 0x92, + 0xB7, 0x58, 0x70, 0x33, 0xA9, 0xA3, 0xD8, 0xB7, + 0xF1, 0x04, 0xA7, 0xFA, 0x9D, 0x2C, 0x6B, 0x5A, + 0x52, 0x89, 0xAC, 0xD0, 0x12, 0x44, 0x8F, 0x7E, + 0x97, 0xA1, 0x82, 0x82, 0xB2, 0xEA, 0x47, 0x60, + 0x9B, 0x22, 0x32, 0x74, 0x77, 0x62, 0xE3, 0x46, + 0xF5, 0x55, 0x79, 0xEF, 0x9D, 0xB0, 0x2A, 0xC8, + 0x10, 0x2E, 0x7B, 0x3F, 0x00, 0xE8, 0x04, 0xA0, + 0x7E, 0x7F, 0x34, 0xB2, 0x35, 0x0E, 0x3A, 0x2F, + 0x65, + + 0x0C, 0x94, 0x90, 0x76, 0x67, 0xAB, 0xE0, 0x58, + 0x2E, 0x22, 0xF4, 0x48, 0xE7, 0x3E, 0x44, 0xB6, + 0x6D, 0xD4, 0xBD, 0x46, 0xEB, 0x9E, 0x01, 0xF9, + 0xB3, 0x06, 0x6F, 0xBA, 0xEE, 0x06, 0x1F, 0xB9, + 0x22, 0xE3, 0x49, 0x27, 0x80, 0x86, 0xB5, 0x38, + 0x47, 0x77, 0x14, 0x68, 0x0B, 0xF2, 0x6C, 0x9A, + 0xF1, 0x1F, 0x20, 0xED, 0x86, 0xF9, 0xEE, 0x04, + 0x92, 0xBC, 0xAB, 0xB8, 0x6B, 0x4A, 0x9D, 0x63, + 0xEB, 0x1B, 0x69, 0x18, 0x3D, 0x81, 0x4D, 0x16, + 0x68, 0x63, 0xF1, 0x96, 0x96, 0x0B, 0x51, 0x66, + 0x93, 0xFE, 0x49, 0xEA, 0xF6, 0x55, 0x8A, 0x2A, + 0xD7, 0x2E, 0xD0, 0x2D, 0xBF, 0x85, 0xD5, 0x97, + 0x9D, 0x8D, 0x2D, 0xD3, 0xB3, 0x62, 0x61, 0xB6, + 0x3B, 0x7B, 0xD1, 0x17, 0xB3, 0xB4, 0x94, 0x2D, + 0xEC, 0x76, 0xD1, 0x39, 0x75, 0x39, 0xFA, 0xAA, + 0x5B, 0x47, 0x0D, 0x9F, 0xBC, 0xEC, 0x12, 0x4F, + 0x76, 0x7C, 0xCB, 0xAD, 0x19, 0x80, 0xCF, 0x65, + 0x7F, 0x1E, 0x64, 0x2D, 0xE7, 0xF1, 0x4B, 0x22, + 0x9D, 0xEE, 0x46, 0x48, 0xBA, 0x54, 0x32, 0x5D, + 0x33, 0xE0, 0x81, 0xF6, 0x9C, 0x2F, 0x1C, 0xBC, + 0x17, 0xCA, 0x34, 0x0C, 0x9A, 0xEF, 0x27, 0x8E, + 0x19, 0xD8, 0x8C, 0xC4, 0xED, 0x0C, 0x88, 0xBA, + 0x60, 0x8B, 0xCF, 0x84, 0xB8, 0xF0, 0x25, 0x8C, + 0x9E, 0xEA, 0x00, 0xE0, 0xB6, 0xC1, 0xAA, 0x02, + 0x51, 0xD9, 0xFF, 0xDA, 0x87, 0x9D, 0x62, 0xB1, + 0xD1, 0x52, 0x7D, 0xE8, 0xB1, 0xC2, 0x45, 0x7D, + 0x4D, 0xF8, + + 0x20, 0xC9, 0xAD, 0x20, 0xED, 0x26, 0x96, 0x8F, + 0xF9, 0xEA, 0xD1, 0x3C, 0x54, 0xA2, 0x45, 0xAF, + 0x13, 0x85, 0x90, 0x43, 0xC3, 0xFD, 0x90, 0xBA, + 0x19, 0xAF, 0xB3, 0x6F, 0x3E, 0xD7, 0x01, 0xB3, + 0xCD, 0x1F, 0xAC, 0x35, 0x48, 0x29, 0x7E, 0xE3, + 0x7B, 0x5F, 0x2A, 0x48, 0x86, 0x27, 0x43, 0xAA, + 0x9C, 0x30, 0x6A, 0x4B, 0x13, 0x77, 0x2D, 0xE5, + 0xB4, 0xB2, 0x66, 0x82, 0xC0, 0x4E, 0xDE, 0x81, + 0x18, 0x9E, 0x4A, 0xC4, 0x0A, 0x20, 0x2E, 0x70, + 0xED, 0x7D, 0x48, 0x28, 0xF8, 0xE4, 0x68, 0x01, + 0xEF, 0x54, 0x43, 0x42, 0x3A, 0xA8, 0x65, 0xC6, + 0xF5, 0x94, 0x19, 0x8A, 0x23, 0x75, 0xBD, 0x08, + 0xAE, 0xA4, 0x78, 0x42, 0xD1, 0xF4, 0xF0, 0xA3, + 0x5A, 0x21, 0x74, 0x1B, 0x90, 0xD8, 0x05, 0x99, + 0xA7, 0x22, 0x7C, 0x79, 0xE9, 0x7D, 0xFF, 0xB2, + 0x1F, 0x04, 0x37, 0xAE, 0xFA, 0xD5, 0x93, 0x97, + 0x32, 0x7E, 0xFD, 0xBB, 0xAC, 0x6E, 0x96, 0xA5, + 0x4F, 0xB4, 0x89, 0x21, 0xB1, 0x3F, 0xB2, 0x3D, + 0xFA, 0x08, 0xCE, 0xED, 0x70, 0x23, 0xAF, 0x75, + 0x22, 0xDE, 0x2E, 0x12, 0x37, 0xE4, 0xB9, 0x92, + 0xA2, 0xB0, 0x4D, 0x56, 0xDE, 0x5E, 0xD3, 0x7F, + 0xBF, 0xBD, 0x5E, 0x6F, 0x4A, 0xBA, 0xC3, 0x27, + 0x22, 0x19, 0xA3, 0x4E, 0x90, 0x2E, 0x72, 0x2E, + 0xEB, 0x6B, 0x48, 0xD5, 0xC6, 0x00, 0x94, 0x56, + 0x29, 0x74, 0x13, 0x0B, 0x85, 0xCF, 0xE5, 0x51, + 0x83, 0xB5, 0x20, 0x49, 0xF0, 0xC6, 0x08, 0xEE, + 0x18, 0x26, 0x19, + + 0x74, 0x41, 0x6D, 0x4E, 0x6C, 0x5E, 0x82, 0xB9, + 0xA6, 0x6E, 0x53, 0x6C, 0xEF, 0x7E, 0x43, 0x36, + 0x6A, 0xAA, 0x94, 0x99, 0xAA, 0x92, 0x44, 0xE6, + 0x41, 0x1D, 0x09, 0xE6, 0x5D, 0xF5, 0x8D, 0xCF, + 0x34, 0xE3, 0xAC, 0x10, 0x0B, 0x5D, 0xC1, 0x59, + 0xB7, 0x60, 0x6C, 0xCB, 0x75, 0x67, 0x85, 0x40, + 0xB8, 0x06, 0x54, 0xE0, 0xB7, 0xB9, 0x4E, 0x4A, + 0x52, 0xD0, 0x39, 0x9F, 0x2C, 0x01, 0xFE, 0xB2, + 0x09, 0x73, 0xA1, 0x6C, 0xD6, 0x0E, 0xB4, 0x8F, + 0x40, 0xA2, 0x15, 0x12, 0x88, 0x3D, 0x65, 0x49, + 0x0C, 0xE1, 0xF5, 0x95, 0xF4, 0xC0, 0xF2, 0x63, + 0x5F, 0xF6, 0x1B, 0xF2, 0x30, 0xC8, 0x5B, 0xE9, + 0xC0, 0x84, 0x0C, 0x6E, 0xDF, 0xC4, 0x19, 0xB9, + 0xCE, 0xA6, 0x49, 0xA5, 0x64, 0xE9, 0x66, 0xC3, + 0x6C, 0xE5, 0x93, 0x76, 0xAC, 0x59, 0x65, 0x0E, + 0xE6, 0xF5, 0x80, 0xCE, 0x1C, 0x72, 0x9A, 0x53, + 0xB0, 0xC7, 0xB6, 0x11, 0x65, 0xDE, 0xEC, 0x89, + 0x18, 0xD8, 0x05, 0x6E, 0x41, 0xD2, 0x31, 0xBD, + 0xDB, 0xE5, 0xEF, 0xF5, 0x76, 0x5C, 0xBD, 0x03, + 0x6D, 0x04, 0x00, 0x16, 0x64, 0x19, 0xFE, 0x4B, + 0x73, 0x9C, 0xDB, 0x31, 0x13, 0x50, 0xD6, 0xCB, + 0xE4, 0xFC, 0x73, 0x89, 0x0F, 0x50, 0x31, 0xBF, + 0x0E, 0xAB, 0xD8, 0xF2, 0x9C, 0xB8, 0x04, 0x88, + 0xAD, 0xE3, 0x9F, 0xDA, 0x0D, 0xE3, 0x5B, 0x34, + 0x94, 0xCB, 0x50, 0x61, 0xA4, 0x01, 0x03, 0xFA, + 0x4D, 0x85, 0xE4, 0x29, 0xFC, 0x11, 0x77, 0x97, + 0x75, 0x6D, 0xF3, 0xC1, + + 0x16, 0x34, 0x6D, 0x2E, 0x36, 0x03, 0xC4, 0x4E, + 0xC5, 0xB4, 0xF8, 0xFA, 0x20, 0x49, 0x81, 0x68, + 0x7E, 0xC8, 0xC2, 0x13, 0x18, 0x84, 0x0C, 0x84, + 0xE8, 0xBF, 0xD9, 0x0D, 0x1B, 0x9F, 0xF0, 0x1F, + 0x8D, 0x41, 0x56, 0x5F, 0xBB, 0x1A, 0x21, 0x5F, + 0x0B, 0x7E, 0x79, 0xFC, 0x7C, 0x72, 0xD5, 0x80, + 0x64, 0x8A, 0xFD, 0xC5, 0xF9, 0xDC, 0x61, 0x27, + 0x75, 0x65, 0x0A, 0x2C, 0x2A, 0x4C, 0xE9, 0x7A, + 0x3A, 0xFA, 0x1E, 0xE6, 0x2A, 0x31, 0xFD, 0xD1, + 0xA0, 0xD8, 0xBF, 0xAB, 0x40, 0x61, 0x87, 0x9F, + 0xA8, 0x65, 0x18, 0x7C, 0x87, 0xEE, 0xA2, 0x93, + 0xC2, 0xE4, 0xED, 0xEF, 0x5C, 0x3D, 0x09, 0xC8, + 0xD7, 0x75, 0x76, 0xF2, 0x1A, 0x9E, 0x19, 0xB8, + 0x44, 0xE8, 0xBE, 0x4F, 0x71, 0xD2, 0xEF, 0x0A, + 0x83, 0x1C, 0xFC, 0xA5, 0x6F, 0x43, 0x0A, 0x1D, + 0xDA, 0xD7, 0x4D, 0x14, 0xE3, 0x5C, 0x32, 0x74, + 0x45, 0x19, 0xC4, 0xF4, 0x3D, 0x5A, 0x6E, 0xEC, + 0x5E, 0x54, 0xF1, 0xB3, 0xF1, 0x4B, 0x05, 0x52, + 0x92, 0x41, 0x49, 0x27, 0x18, 0x40, 0x38, 0x4E, + 0x0A, 0x7D, 0xD1, 0x31, 0x0A, 0xC8, 0x82, 0x60, + 0x5A, 0xBE, 0x4A, 0x5A, 0xAE, 0xBE, 0x86, 0x7D, + 0x2B, 0x27, 0x07, 0x2C, 0xFA, 0x65, 0xB0, 0x73, + 0x50, 0x68, 0x58, 0x36, 0x50, 0x74, 0x61, 0x57, + 0xAB, 0xF4, 0xE8, 0xCD, 0xEE, 0xBB, 0x29, 0x68, + 0x0E, 0x6C, 0x38, 0x0E, 0x0C, 0xDC, 0x79, 0x12, + 0xC7, 0xF4, 0x25, 0x74, 0x66, 0xD6, 0xC1, 0xF6, + 0xF0, 0xF6, 0x1D, 0x27, 0xA1, + + 0xFA, 0x0C, 0xB5, 0xEE, 0x97, 0x04, 0x06, 0xF8, + 0x04, 0xE8, 0xBF, 0x1C, 0x3D, 0x19, 0x5A, 0x1C, + 0x04, 0xBC, 0x6F, 0x76, 0x50, 0x3D, 0x0C, 0xE7, + 0xCE, 0xE5, 0xDE, 0x6F, 0xA1, 0xE6, 0xA3, 0xE4, + 0x3C, 0xC6, 0x17, 0xBF, 0xDC, 0xDF, 0x56, 0xFC, + 0x63, 0xE9, 0x9F, 0x57, 0x0C, 0xF0, 0xA8, 0x19, + 0x1B, 0x8A, 0x33, 0xA3, 0xBF, 0xA8, 0xCD, 0xC4, + 0x24, 0x71, 0xA2, 0x4D, 0x2D, 0xF4, 0x3E, 0xB7, + 0xF9, 0xAD, 0x3B, 0xA9, 0xDF, 0xCF, 0x81, 0xBD, + 0x9A, 0x5A, 0x45, 0xC0, 0x94, 0xA2, 0xAF, 0x9A, + 0x86, 0xF6, 0xBF, 0x3B, 0x99, 0xDB, 0x1E, 0x41, + 0xFD, 0xA5, 0x57, 0xB3, 0x2E, 0x7B, 0x73, 0x4F, + 0x6A, 0xBF, 0xAD, 0x5F, 0x87, 0xFC, 0xA7, 0xEC, + 0xC9, 0xD6, 0x70, 0xDA, 0xED, 0x75, 0x84, 0x50, + 0x61, 0x7C, 0x73, 0x18, 0x8D, 0x7B, 0xF2, 0x47, + 0x85, 0x75, 0x0A, 0x19, 0xBF, 0xFE, 0x3B, 0x81, + 0x81, 0x15, 0x57, 0xD8, 0xE7, 0x13, 0xD6, 0xF6, + 0x0D, 0x49, 0xB9, 0x71, 0x23, 0x51, 0x3F, 0x6A, + 0x50, 0x70, 0xB6, 0x42, 0x18, 0xE9, 0xD9, 0xF5, + 0xEF, 0x60, 0x15, 0xE3, 0x73, 0xCD, 0x49, 0x09, + 0x4A, 0x87, 0x05, 0x5D, 0x45, 0xE1, 0x40, 0xAC, + 0x6E, 0xA0, 0xD0, 0x1C, 0xD4, 0xFE, 0x76, 0xE4, + 0xD8, 0x4E, 0x3E, 0x93, 0xC9, 0xC8, 0xC7, 0x4A, + 0x49, 0x8E, 0x79, 0x46, 0x5D, 0xB0, 0xEB, 0xDC, + 0x46, 0x88, 0x25, 0x5B, 0xE4, 0xE2, 0x0E, 0x0C, + 0xC9, 0xD3, 0xA2, 0x79, 0x1A, 0xF2, 0x94, 0xF2, + 0xC2, 0xE2, 0x98, 0x6E, 0x99, 0x87, + + 0xDE, 0xEE, 0x45, 0x68, 0x9D, 0xC8, 0x03, 0xC0, + 0x02, 0x41, 0x3D, 0x9F, 0x33, 0x70, 0x73, 0x62, + 0x96, 0x25, 0x02, 0xF4, 0x74, 0x5D, 0xE2, 0xF1, + 0x67, 0xF2, 0xFD, 0xE1, 0x65, 0x47, 0x33, 0x6D, + 0xF4, 0x86, 0x11, 0x7C, 0xD0, 0x48, 0x02, 0x7C, + 0xA7, 0x26, 0x85, 0x27, 0xBE, 0x13, 0x96, 0x85, + 0x40, 0x1F, 0x6A, 0xB0, 0x0D, 0x8E, 0xD2, 0x02, + 0xD7, 0x03, 0xFD, 0x45, 0xC8, 0x08, 0xED, 0x3E, + 0x32, 0x04, 0x30, 0x48, 0x63, 0xA3, 0x65, 0x8C, + 0x11, 0x9D, 0x7B, 0x65, 0xE9, 0x02, 0x37, 0xF3, + 0x9D, 0x0B, 0x5E, 0xAD, 0x9D, 0xFF, 0x7D, 0x56, + 0x3D, 0x50, 0x74, 0x37, 0xAD, 0x39, 0x06, 0x85, + 0x10, 0xC5, 0x69, 0x37, 0x57, 0x3C, 0x4F, 0xE8, + 0x4A, 0xAC, 0x1D, 0x06, 0xDA, 0x62, 0xB3, 0x3E, + 0x0B, 0xB0, 0xE4, 0x1F, 0x3F, 0x2F, 0x29, 0x88, + 0x14, 0xC1, 0xAE, 0xD1, 0x62, 0x89, 0xB7, 0xC5, + 0x51, 0x72, 0xFE, 0xE3, 0xDF, 0x56, 0x9E, 0xDB, + 0x37, 0xE4, 0x64, 0xAC, 0x99, 0x08, 0xF7, 0x87, + 0xFA, 0xCE, 0x5B, 0xF3, 0xCD, 0x21, 0xF6, 0x8A, + 0xED, 0xA3, 0x7B, 0xEC, 0x3F, 0x30, 0x14, 0x3D, + 0x00, 0xD4, 0x40, 0xBE, 0x35, 0x36, 0x89, 0xCF, + 0x29, 0xDA, 0x13, 0xE8, 0x69, 0x0D, 0xDE, 0xE8, + 0x05, 0x22, 0x0D, 0x02, 0x18, 0xDB, 0x12, 0xAC, + 0x01, 0x12, 0xD0, 0xEF, 0xD2, 0x82, 0x21, 0xC9, + 0xF7, 0x52, 0x94, 0x98, 0x0E, 0xE7, 0xCB, 0x9C, + 0x3F, 0xD1, 0x0D, 0xA6, 0x0C, 0x53, 0x60, 0x8B, + 0x13, 0x3F, 0x77, 0xD5, 0xDC, 0xC5, 0xE2, + + 0x7D, 0x3B, 0xAE, 0x67, 0x64, 0x19, 0xC8, 0x66, + 0xF1, 0x0F, 0x31, 0xAD, 0x43, 0x35, 0xD4, 0x44, + 0x2C, 0xA5, 0x5D, 0x76, 0x78, 0x70, 0x4C, 0x2F, + 0x71, 0x11, 0xB9, 0xF3, 0x69, 0x16, 0xFA, 0x09, + 0x42, 0xE7, 0x6C, 0x09, 0x2E, 0xDA, 0xEB, 0x9A, + 0x53, 0x82, 0x1D, 0x31, 0x3E, 0x3E, 0xD8, 0x48, + 0xEA, 0x86, 0xE8, 0x76, 0x8E, 0xC6, 0xA7, 0xEA, + 0xBB, 0x58, 0x7D, 0xB7, 0x39, 0x76, 0xEC, 0xE6, + 0x35, 0x19, 0xAA, 0xFA, 0x6E, 0x98, 0x2C, 0x38, + 0xC2, 0xA2, 0x0E, 0x36, 0xA9, 0x4F, 0x88, 0xDA, + 0x6E, 0x3D, 0x1C, 0xFB, 0x25, 0xF5, 0x96, 0x1E, + 0x18, 0xBE, 0xEB, 0x0A, 0x48, 0xB8, 0x5A, 0x42, + 0xD3, 0x77, 0xEB, 0xD1, 0x06, 0x93, 0x4D, 0x56, + 0xB0, 0x60, 0xAA, 0x72, 0x8B, 0xC4, 0x29, 0x2E, + 0xE5, 0x36, 0x53, 0x46, 0xA3, 0x4F, 0x27, 0xED, + 0xED, 0x0A, 0x19, 0xCC, 0xF1, 0x1C, 0xBB, 0x0C, + 0x43, 0x2C, 0x6E, 0x40, 0xCF, 0x0F, 0x58, 0x23, + 0xC0, 0xE1, 0x5F, 0x2A, 0x63, 0x06, 0xD0, 0x91, + 0x97, 0x9C, 0x16, 0x0E, 0x0A, 0xE6, 0xAF, 0x1D, + 0x7C, 0x07, 0xD6, 0xC4, 0x64, 0x01, 0xB9, 0xE4, + 0x6D, 0x75, 0x92, 0x4F, 0x35, 0x1B, 0x4C, 0x37, + 0xCE, 0x05, 0x88, 0x06, 0x08, 0x1C, 0xD6, 0x75, + 0xE2, 0x07, 0x2E, 0x54, 0x58, 0xA1, 0x00, 0x39, + 0xA4, 0x80, 0xBF, 0xB2, 0x1F, 0xC4, 0x69, 0xC1, + 0x3D, 0x4B, 0xFE, 0x7F, 0x20, 0x1F, 0x49, 0x8B, + 0x08, 0xC6, 0x33, 0x86, 0xEB, 0x7B, 0x3E, 0x16, + 0xDE, 0xE3, 0x34, 0xD8, 0x66, 0x04, 0x55, 0xBA, + + 0xBE, 0x42, 0xC4, 0xEA, 0xAB, 0x31, 0xF5, 0x2E, + 0xF3, 0xF6, 0xBC, 0x86, 0xB6, 0xA4, 0x48, 0x74, + 0x15, 0xE9, 0xA7, 0x65, 0xE6, 0xDA, 0xF0, 0x94, + 0x5F, 0x1F, 0xC4, 0xCA, 0xD3, 0xFE, 0x66, 0x78, + 0x03, 0xE3, 0xBE, 0x9D, 0xE8, 0xAC, 0x45, 0x29, + 0xFA, 0x59, 0xE0, 0xBA, 0xD0, 0xAC, 0x62, 0x9A, + 0xA6, 0x6F, 0x6C, 0x5B, 0x0E, 0x86, 0xC8, 0x3E, + 0xD6, 0xE2, 0x84, 0x31, 0x79, 0xD1, 0xAF, 0xCB, + 0x78, 0x1D, 0xF5, 0x1D, 0x76, 0x72, 0xCC, 0xAA, + 0x7A, 0x22, 0x35, 0xBD, 0x3A, 0x26, 0x7B, 0x2B, + 0x08, 0xD8, 0x27, 0x26, 0x07, 0xA2, 0xAA, 0x6E, + 0x30, 0x8C, 0x38, 0x70, 0x40, 0x3C, 0x61, 0x9F, + 0x5C, 0x57, 0x72, 0x9B, 0x5B, 0x4C, 0x20, 0xB0, + 0x84, 0x1A, 0x85, 0x0C, 0xF3, 0x3E, 0x5B, 0x67, + 0x3D, 0xF2, 0xB4, 0x4F, 0xB1, 0xE6, 0x3D, 0xDC, + 0xF1, 0x3C, 0x49, 0x9A, 0x38, 0x95, 0x47, 0xF2, + 0xCA, 0x43, 0xB7, 0x0A, 0x80, 0x06, 0x9F, 0x06, + 0x4D, 0x02, 0x98, 0x44, 0xB0, 0x8B, 0x73, 0xC6, + 0x26, 0x5B, 0x14, 0xA1, 0xF6, 0x64, 0x37, 0xDE, + 0xF2, 0x22, 0x1A, 0x59, 0x85, 0xAE, 0xFD, 0x5A, + 0xE5, 0x71, 0xC8, 0xCF, 0x6C, 0xFA, 0x64, 0x27, + 0xFF, 0x55, 0x45, 0x88, 0xA4, 0x5A, 0x50, 0x82, + 0x47, 0x61, 0x4C, 0xE5, 0x43, 0x9A, 0xA9, 0x5A, + 0xCC, 0xA3, 0xCA, 0x1B, 0xA0, 0x28, 0x65, 0x6E, + 0xA4, 0xCE, 0xE2, 0x17, 0x41, 0x07, 0x50, 0x31, + 0x76, 0xCB, 0x61, 0x14, 0xE3, 0x50, 0x68, 0x2B, + 0xF2, 0x96, 0x6B, 0xCF, 0xFE, 0xF7, 0x91, 0xD6, + 0x6F, + + 0x55, 0x68, 0x17, 0x44, 0xA4, 0xAE, 0x0A, 0xBE, + 0xB6, 0xF4, 0x72, 0xAA, 0x55, 0x65, 0x33, 0x22, + 0xC5, 0x86, 0x02, 0xC5, 0xB6, 0x13, 0x9B, 0x68, + 0x1E, 0xE8, 0xFD, 0x2D, 0xEB, 0x9E, 0xF2, 0x72, + 0xA3, 0xA7, 0x38, 0xC1, 0xDB, 0xDB, 0x72, 0x03, + 0xE9, 0x7E, 0x5B, 0x55, 0x12, 0x0A, 0x8B, 0x87, + 0x89, 0xA5, 0xB7, 0x93, 0xFA, 0x8E, 0x80, 0xAA, + 0xB5, 0xDC, 0xA4, 0x78, 0xD7, 0x76, 0x21, 0x7B, + 0xF0, 0x1B, 0x41, 0x89, 0x9F, 0x9C, 0x41, 0xE6, + 0xDE, 0x3A, 0xF6, 0x16, 0x66, 0xDF, 0xF1, 0xC9, + 0x59, 0x75, 0x18, 0xBE, 0xC5, 0xE3, 0x55, 0xA7, + 0x39, 0xF5, 0x04, 0xBA, 0x3A, 0x11, 0x53, 0x36, + 0x69, 0x58, 0x49, 0xC3, 0xB1, 0x4E, 0x65, 0x88, + 0xDA, 0x46, 0xB8, 0x79, 0x58, 0x32, 0x18, 0xBA, + 0x3E, 0x3C, 0x5C, 0x02, 0x34, 0xFD, 0xD1, 0x2F, + 0x32, 0xCA, 0x4D, 0x1A, 0x68, 0x3B, 0x73, 0xC6, + 0xD0, 0xA8, 0x71, 0x24, 0xA8, 0xD5, 0x82, 0x83, + 0x26, 0x99, 0xCA, 0x8E, 0xC9, 0x55, 0xF2, 0x92, + 0xD1, 0x95, 0x4E, 0xA7, 0x5F, 0x16, 0x56, 0xD7, + 0xEA, 0xCF, 0xD3, 0xC7, 0xD7, 0xEA, 0x79, 0xF4, + 0x12, 0xC4, 0x7E, 0x5B, 0xB3, 0x1D, 0xAE, 0x0A, + 0xFD, 0xE1, 0x9F, 0x27, 0xCC, 0x95, 0xC6, 0x03, + 0xFD, 0x2F, 0xD3, 0xC5, 0x4E, 0xEF, 0x42, 0x10, + 0xF4, 0x6B, 0x24, 0x78, 0x53, 0xC5, 0xE1, 0xB6, + 0xB7, 0x80, 0xBD, 0xEB, 0x65, 0x5B, 0xA8, 0xE5, + 0x8E, 0xE5, 0x7F, 0x1E, 0x5B, 0x93, 0xA4, 0xDD, + 0xD5, 0xAB, 0xF2, 0x4A, 0x75, 0xE0, 0xAC, 0xC1, + 0x0C, 0x2D, + + 0x3A, 0x63, 0xF3, 0x06, 0x48, 0xB8, 0x7A, 0x18, + 0x11, 0x6F, 0x96, 0x89, 0x2C, 0x01, 0x1F, 0x47, + 0x73, 0xF4, 0x9E, 0x28, 0x77, 0xE8, 0xCD, 0x57, + 0x36, 0x53, 0xB4, 0x33, 0x62, 0x83, 0x51, 0x7A, + 0x4A, 0x4D, 0xC3, 0xF7, 0x58, 0x19, 0x73, 0xB5, + 0xFF, 0x36, 0x3E, 0x63, 0xB0, 0xD1, 0x12, 0x07, + 0xB9, 0x17, 0xF1, 0xC6, 0x78, 0x79, 0xA1, 0x2D, + 0x4F, 0x00, 0xAF, 0xCD, 0xA3, 0x73, 0x09, 0xDD, + 0x9C, 0x3D, 0x8E, 0x6B, 0x2B, 0xA5, 0xF5, 0x91, + 0x1C, 0x2B, 0xFE, 0xB8, 0xE5, 0x6E, 0xA5, 0x9D, + 0x5D, 0x5C, 0x6A, 0xF2, 0xA1, 0x7E, 0x82, 0xB0, + 0x47, 0xB5, 0x53, 0xE4, 0x49, 0x00, 0x5B, 0x60, + 0x5C, 0x94, 0x6E, 0xD1, 0xDE, 0x27, 0x7C, 0xC2, + 0xA2, 0xFF, 0xB4, 0xAF, 0x5F, 0x52, 0x0F, 0x5B, + 0x3B, 0xA5, 0x48, 0x93, 0x90, 0x97, 0x30, 0x10, + 0x30, 0x96, 0x84, 0x68, 0x8D, 0xB4, 0x47, 0x9E, + 0x77, 0x23, 0x2A, 0x96, 0xA9, 0x29, 0x2E, 0xBC, + 0x40, 0x59, 0x92, 0xE4, 0x55, 0xD7, 0x30, 0x2E, + 0x62, 0x15, 0xA6, 0xEA, 0x77, 0x5D, 0x2C, 0x1C, + 0x10, 0xF5, 0x8A, 0x43, 0x2B, 0x72, 0xC3, 0xD0, + 0x9E, 0xB9, 0x80, 0x4C, 0x8D, 0xCD, 0x5B, 0xB5, + 0xAD, 0xF6, 0x44, 0xDD, 0x9D, 0x37, 0x8E, 0x28, + 0xF1, 0xB5, 0xCE, 0xF2, 0xDD, 0x35, 0x6F, 0x63, + 0xB3, 0x32, 0xAC, 0x13, 0x4B, 0xC9, 0x67, 0x58, + 0x63, 0x2F, 0xB4, 0x23, 0x0C, 0xA3, 0x4F, 0xF8, + 0xB6, 0x52, 0xE7, 0xD1, 0xA7, 0x0D, 0x0D, 0x5B, + 0x66, 0x1D, 0x77, 0x82, 0xCA, 0xE5, 0x11, 0x62, + 0xF4, 0xA9, 0x95, + + 0xE7, 0x1E, 0xF9, 0x44, 0xCD, 0x9F, 0xB5, 0xC5, + 0x80, 0xDC, 0x78, 0xA9, 0x4E, 0xAB, 0xD3, 0x1D, + 0xA9, 0xC6, 0xCC, 0x67, 0x49, 0xC2, 0x9C, 0x99, + 0x60, 0x86, 0xBA, 0x95, 0xDD, 0x10, 0x02, 0x37, + 0xE8, 0x2B, 0xF9, 0x2B, 0xB3, 0x97, 0x44, 0xDA, + 0xEF, 0x65, 0xB6, 0xB2, 0x0D, 0xA4, 0xAB, 0xFE, + 0xD7, 0x19, 0x07, 0xBD, 0x5B, 0xCC, 0x56, 0x78, + 0x90, 0xBA, 0x9C, 0x85, 0x7B, 0xD7, 0xDE, 0xD2, + 0x07, 0x29, 0xB2, 0x82, 0xF1, 0x37, 0x7A, 0x87, + 0xB9, 0x04, 0xF6, 0xE2, 0xC9, 0xF7, 0xDD, 0x1D, + 0xA4, 0x25, 0xB0, 0x18, 0x49, 0x72, 0x6F, 0x02, + 0xB1, 0x49, 0xB9, 0x15, 0xA6, 0x00, 0x87, 0x23, + 0x88, 0xED, 0xB7, 0xD5, 0xA2, 0x12, 0xC2, 0xA6, + 0xF3, 0x8A, 0x8C, 0x50, 0xE2, 0xC9, 0xBC, 0x62, + 0x50, 0xF8, 0x2C, 0xB1, 0x11, 0x00, 0x36, 0x79, + 0x13, 0x75, 0xFB, 0x87, 0xDA, 0x49, 0x59, 0x42, + 0x57, 0xDD, 0x7C, 0xE4, 0xFA, 0xD1, 0x5B, 0xF9, + 0xB5, 0xB8, 0x56, 0xB0, 0x98, 0xF9, 0x63, 0xB1, + 0x1B, 0xEC, 0xF7, 0x05, 0x4C, 0xBC, 0x32, 0x1C, + 0x59, 0xC8, 0x75, 0x7E, 0xBC, 0xAD, 0xCF, 0x32, + 0x1A, 0x3D, 0xAE, 0x1F, 0x27, 0x01, 0x85, 0x60, + 0xCB, 0xDE, 0xAB, 0x39, 0xFD, 0x1E, 0x45, 0x82, + 0x36, 0xC1, 0xC3, 0x69, 0xA7, 0xE4, 0x5B, 0x16, + 0x36, 0x5A, 0xD5, 0x20, 0x5E, 0x4D, 0x1C, 0xBA, + 0x6E, 0x28, 0x30, 0x66, 0xDA, 0x6C, 0x66, 0x42, + 0xD4, 0x9A, 0x98, 0x31, 0xF8, 0x11, 0x8A, 0xB5, + 0xF9, 0x9E, 0x96, 0xE9, 0x42, 0x0D, 0xDF, 0x28, + 0x2D, 0x03, 0xC6, 0xFF, + + 0x05, 0x1F, 0xCE, 0x41, 0xE4, 0x8C, 0x74, 0x81, + 0x36, 0x78, 0x17, 0x9E, 0x28, 0xCC, 0xA0, 0xA8, + 0x03, 0x13, 0xEB, 0x8D, 0xD9, 0xF5, 0x75, 0x8C, + 0x58, 0x0B, 0xA5, 0x3F, 0xB5, 0x5D, 0x48, 0x94, + 0xA9, 0x7D, 0x61, 0x34, 0x5F, 0x07, 0xA2, 0x84, + 0x6A, 0xF9, 0x6C, 0xCB, 0x4C, 0x5D, 0x2D, 0xB2, + 0x05, 0x0B, 0x03, 0x61, 0x4A, 0x68, 0xB3, 0xA2, + 0x08, 0x33, 0x68, 0xB0, 0xD9, 0x95, 0x63, 0x98, + 0xBA, 0xF9, 0x70, 0x81, 0xDC, 0x34, 0xD2, 0xA3, + 0x5C, 0x5E, 0x85, 0x22, 0x8D, 0xEB, 0xEE, 0x81, + 0xEC, 0xEE, 0x43, 0xAC, 0x70, 0x93, 0x2C, 0xBC, + 0x66, 0x33, 0x37, 0xD9, 0xE1, 0x71, 0x2F, 0xD0, + 0x5A, 0xB8, 0x32, 0x8C, 0xE7, 0x98, 0x13, 0x8C, + 0x61, 0x94, 0x6C, 0xAA, 0x38, 0xCF, 0xAD, 0xF6, + 0xBE, 0x40, 0xA9, 0x6F, 0x02, 0xFA, 0x16, 0x5C, + 0x70, 0x2E, 0x55, 0xCC, 0x5F, 0x5A, 0xF7, 0x07, + 0x95, 0xB0, 0x18, 0xB7, 0xF0, 0x4A, 0xFA, 0xCD, + 0xB4, 0xA8, 0x92, 0x3F, 0x71, 0xED, 0x8F, 0x54, + 0xC0, 0x35, 0x1F, 0x2E, 0xC7, 0xF2, 0xBE, 0x4B, + 0x96, 0x4F, 0x05, 0xB7, 0x3E, 0x9E, 0x40, 0xA9, + 0x2A, 0xC7, 0x1C, 0x2D, 0x91, 0x5A, 0xBB, 0x31, + 0xB1, 0x4F, 0xE1, 0x3F, 0x34, 0x27, 0x4D, 0xAD, + 0x19, 0x34, 0xC5, 0x4F, 0x2C, 0x32, 0x24, 0x3E, + 0x9E, 0x50, 0x1F, 0xC2, 0x57, 0x63, 0xFF, 0x45, + 0xBE, 0x73, 0x72, 0xED, 0xE6, 0x01, 0x35, 0x33, + 0xCD, 0x14, 0xC2, 0xF4, 0xFB, 0xEF, 0x47, 0x55, + 0x3F, 0x4B, 0xD0, 0x05, 0xF0, 0x38, 0x2A, 0x37, + 0xAF, 0x02, 0xD9, 0x25, 0xDD, + + 0x20, 0xCE, 0x9F, 0xBC, 0x8E, 0x72, 0x30, 0xBB, + 0xE1, 0xC8, 0x3C, 0x08, 0x89, 0x34, 0x73, 0x4C, + 0x8D, 0x0C, 0x00, 0x1E, 0xA4, 0xD4, 0xDA, 0x55, + 0x18, 0x8C, 0xF0, 0xA4, 0x2F, 0xE9, 0x06, 0x30, + 0xDE, 0x73, 0xDA, 0x14, 0xA8, 0x82, 0xC3, 0x94, + 0xAE, 0x12, 0xC5, 0x55, 0x5B, 0x15, 0x42, 0x75, + 0x7A, 0xC3, 0x79, 0x05, 0x09, 0x63, 0x9A, 0xC4, + 0xD4, 0xCA, 0x1D, 0x08, 0x75, 0x68, 0x78, 0x07, + 0x7D, 0xD2, 0x37, 0xEB, 0x8B, 0x25, 0xAC, 0xF4, + 0x90, 0x5F, 0x4A, 0x2D, 0xE4, 0x4F, 0x08, 0x3B, + 0x3D, 0xF3, 0x9F, 0xA4, 0x8E, 0xEE, 0xE6, 0x47, + 0x4F, 0x3A, 0x6D, 0xBC, 0xB7, 0xA9, 0x4C, 0x1D, + 0x82, 0x4E, 0x7A, 0x29, 0xC9, 0x01, 0xFF, 0xC6, + 0x6F, 0x63, 0x4C, 0xE3, 0x0A, 0x10, 0x3F, 0x07, + 0xB4, 0x3F, 0x71, 0x55, 0x8D, 0xE3, 0xEF, 0xFC, + 0x76, 0xF6, 0x0A, 0xC3, 0xE9, 0xA9, 0x28, 0x03, + 0xB0, 0xDF, 0x15, 0x0E, 0xD0, 0x68, 0x17, 0x7D, + 0xC7, 0xC2, 0x51, 0x1A, 0x0D, 0x24, 0x21, 0x21, + 0x45, 0xFF, 0xEA, 0x17, 0xFB, 0xBF, 0x59, 0x63, + 0x03, 0x4F, 0x62, 0xEF, 0x1C, 0xDA, 0xF5, 0x00, + 0x8F, 0x9D, 0x2B, 0x81, 0x62, 0x9F, 0xED, 0xA6, + 0x6D, 0xA0, 0x57, 0x16, 0x08, 0x9E, 0x07, 0xB9, + 0xF3, 0x8B, 0x78, 0xA8, 0x6E, 0x15, 0x53, 0x26, + 0xE5, 0x7A, 0xE4, 0xBA, 0x09, 0xC6, 0x25, 0x41, + 0x1A, 0x24, 0x9B, 0xE0, 0x16, 0x62, 0xCF, 0x67, + 0xB6, 0xA1, 0xEF, 0x8B, 0x4D, 0xCC, 0xC3, 0xB6, + 0xB6, 0x89, 0x6C, 0x79, 0x02, 0x56, 0x79, 0x87, + 0xF4, 0xA7, 0x4B, 0x1D, 0xBC, 0xC0, + + 0x34, 0xF6, 0x75, 0xEA, 0x0F, 0x48, 0x36, 0xB3, + 0x59, 0x85, 0x62, 0x0F, 0xEF, 0x08, 0xA8, 0xEB, + 0x6F, 0x83, 0x96, 0x3D, 0xDA, 0x81, 0x49, 0xF3, + 0x9D, 0xBD, 0x99, 0x93, 0x3B, 0x86, 0xF3, 0x9F, + 0xEF, 0x0F, 0x16, 0x0F, 0xBD, 0x58, 0x11, 0x93, + 0x1E, 0xF2, 0xAB, 0x31, 0xB0, 0x2E, 0x8B, 0x3D, + 0x57, 0x97, 0x6F, 0x54, 0xA2, 0x75, 0x04, 0xBE, + 0x9E, 0xF2, 0x57, 0x23, 0xC7, 0x3C, 0x4A, 0x4B, + 0xF0, 0xBC, 0x61, 0x53, 0x88, 0xC5, 0x91, 0x34, + 0x58, 0xEE, 0x16, 0xA3, 0xB7, 0x68, 0xDE, 0x60, + 0x99, 0x50, 0xF6, 0x3B, 0x14, 0x55, 0xC0, 0xE7, + 0xEE, 0x34, 0xA4, 0x29, 0xED, 0xD5, 0x5E, 0x6A, + 0xD2, 0xAD, 0x09, 0xCD, 0x21, 0x63, 0x7D, 0xAD, + 0xCC, 0xB1, 0x15, 0xD4, 0x4A, 0x12, 0x7A, 0xD2, + 0xB5, 0xE3, 0x79, 0x7A, 0x88, 0xFE, 0x57, 0x77, + 0xB9, 0xE6, 0x08, 0xE4, 0xA4, 0x62, 0x7A, 0xED, + 0xBF, 0x4F, 0xC2, 0xD8, 0x66, 0x4A, 0x3D, 0xA8, + 0xEC, 0xC6, 0x1C, 0xE7, 0xAF, 0xC4, 0x2B, 0x3B, + 0xB5, 0x5D, 0xF0, 0x33, 0xBA, 0xF2, 0x61, 0x99, + 0x92, 0xCF, 0x34, 0x19, 0x99, 0x43, 0xF5, 0x9F, + 0xF6, 0x64, 0x5A, 0x40, 0x87, 0x53, 0x2D, 0x16, + 0x75, 0x68, 0x31, 0xAA, 0x61, 0xCF, 0x1F, 0xC3, + 0x32, 0x5B, 0x78, 0xFB, 0x8D, 0x67, 0x1F, 0x16, + 0x80, 0x3A, 0x7E, 0x05, 0x45, 0x7A, 0x5E, 0x43, + 0x0A, 0x2E, 0xE1, 0x22, 0xA8, 0x96, 0x79, 0xD5, + 0xC4, 0x2E, 0xE0, 0x1F, 0x43, 0x1B, 0x8D, 0xDC, + 0xBA, 0xCF, 0x7D, 0xF2, 0xD1, 0x70, 0xF6, 0x65, + 0x44, 0xCE, 0x2B, 0x08, 0x0D, 0x43, 0xC4, + + 0xF1, 0x1E, 0x0E, 0xFC, 0x7A, 0x10, 0x39, 0x3A, + 0x1E, 0xAD, 0x9E, 0x81, 0xC9, 0x04, 0xDB, 0x02, + 0x15, 0xC4, 0x9F, 0x6F, 0xD8, 0xF4, 0xCE, 0x77, + 0x00, 0x46, 0xB9, 0x0C, 0xD1, 0x4B, 0x1D, 0x6C, + 0x44, 0xFA, 0x19, 0x09, 0xB6, 0xEB, 0x34, 0x4A, + 0xC2, 0xDF, 0xF3, 0xF2, 0xE7, 0x3A, 0xE3, 0x6C, + 0xD4, 0xAF, 0x22, 0xFF, 0x40, 0xBC, 0x5C, 0x4A, + 0xBA, 0x7E, 0x54, 0xB1, 0xDB, 0xDF, 0x02, 0x2D, + 0xC2, 0xAD, 0x7B, 0x3E, 0x4C, 0x8E, 0x42, 0x97, + 0xDA, 0x00, 0xAA, 0x9F, 0x6A, 0x33, 0xB1, 0xFF, + 0xBB, 0x5E, 0x5F, 0x10, 0xE6, 0xA0, 0xF3, 0x25, + 0x8B, 0xAC, 0x36, 0xCF, 0xB6, 0x4A, 0x4D, 0x12, + 0x77, 0xDA, 0x17, 0xC5, 0xD5, 0xD2, 0xCB, 0xA1, + 0x95, 0xBB, 0xF1, 0xC9, 0xD8, 0xD3, 0xC1, 0xCC, + 0x67, 0xCE, 0xAB, 0x2B, 0x6A, 0x69, 0x41, 0x7C, + 0x7A, 0x47, 0x25, 0xE8, 0x39, 0xDC, 0x29, 0x31, + 0x36, 0x20, 0xA0, 0x58, 0x2A, 0x1A, 0xF0, 0x22, + 0xB9, 0x04, 0x10, 0xDA, 0x42, 0x2A, 0x6E, 0x1F, + 0x78, 0x01, 0x7C, 0x05, 0xE3, 0x1B, 0xA1, 0xC3, + 0x1A, 0x26, 0xA6, 0xF6, 0xBF, 0x54, 0xE9, 0x45, + 0x7F, 0x87, 0x08, 0xB8, 0xAF, 0xF0, 0xF0, 0xB4, + 0x96, 0xA4, 0xE3, 0xC0, 0x6A, 0x0B, 0xF9, 0x49, + 0x89, 0x1B, 0x9E, 0x69, 0x42, 0xD8, 0x21, 0x57, + 0x20, 0xC3, 0x95, 0xE5, 0xC6, 0x98, 0x06, 0x5E, + 0x69, 0x1F, 0x14, 0x8E, 0x9F, 0xF8, 0x58, 0x7C, + 0xEE, 0x13, 0xC7, 0x96, 0xC1, 0xE7, 0x71, 0x88, + 0x96, 0x54, 0xF9, 0xA7, 0xD6, 0x56, 0x7B, 0x8C, + 0xA5, 0x44, 0x42, 0xD3, 0x6B, 0x2E, 0x2E, 0x03, + + 0x7D, 0x39, 0xA9, 0xFF, 0x6A, 0x3D, 0x14, 0x95, + 0x1C, 0xB6, 0xD8, 0x13, 0x4E, 0x41, 0xF5, 0xD5, + 0x3F, 0x0F, 0xEC, 0x55, 0x1E, 0xAC, 0x95, 0x79, + 0x28, 0x5D, 0xBD, 0xBE, 0xC4, 0x7D, 0x31, 0x1F, + 0x64, 0x11, 0x9D, 0x0B, 0x8F, 0x06, 0xAB, 0x23, + 0x2D, 0x8D, 0xC4, 0x10, 0xE7, 0x20, 0x95, 0x60, + 0x76, 0xFC, 0xFA, 0xE3, 0x64, 0xC3, 0x67, 0x32, + 0xFA, 0x3D, 0x5D, 0x8F, 0xEA, 0xE3, 0x4F, 0x95, + 0x0A, 0x37, 0x4A, 0x30, 0x98, 0x93, 0x76, 0x20, + 0x7F, 0xB7, 0xA9, 0xE0, 0x6C, 0x42, 0xE7, 0xF8, + 0x57, 0xC8, 0xBE, 0xD3, 0x7A, 0x1E, 0xBE, 0xF8, + 0x30, 0x8C, 0x29, 0x95, 0x71, 0x29, 0xFD, 0x79, + 0x0E, 0x1D, 0xDD, 0x4B, 0x41, 0xE9, 0x5F, 0x7E, + 0xF5, 0x4C, 0x7F, 0xA2, 0x10, 0x06, 0x57, 0x86, + 0xAB, 0x10, 0xBF, 0x5A, 0xFE, 0xA2, 0x5F, 0xE8, + 0x70, 0x8F, 0xCC, 0x00, 0xD9, 0x86, 0x86, 0x2C, + 0x31, 0x2E, 0xF9, 0xAD, 0x56, 0x0C, 0xE9, 0xB9, + 0x42, 0x39, 0x3B, 0x0D, 0x47, 0x60, 0x6F, 0xF9, + 0xFB, 0xE8, 0xBE, 0xFC, 0x7D, 0x0B, 0xA3, 0xEC, + 0x09, 0x6E, 0x0E, 0x0B, 0x6D, 0xEC, 0x60, 0x17, + 0xE9, 0x34, 0x65, 0x6F, 0xA4, 0x84, 0x61, 0x13, + 0xB2, 0xA6, 0xD3, 0x56, 0x06, 0xD9, 0xAE, 0x9A, + 0x57, 0x78, 0x93, 0xF2, 0x86, 0xA5, 0x39, 0x27, + 0x20, 0x36, 0x7A, 0xE7, 0xDE, 0x63, 0x02, 0x90, + 0x52, 0x3B, 0x7D, 0x32, 0x24, 0xFA, 0x77, 0x3A, + 0xFF, 0x6D, 0x6D, 0x38, 0xB1, 0xDC, 0x78, 0x06, + 0x5A, 0xCE, 0x72, 0xE9, 0x72, 0x22, 0x72, 0x60, + 0x90, 0x25, 0x72, 0x00, 0x28, 0xA2, 0xC0, 0x4A, + 0x31, + + 0xFE, 0xCE, 0x1F, 0x8E, 0xEF, 0xB9, 0x81, 0xD1, + 0x1D, 0x7F, 0x88, 0x64, 0xF5, 0x96, 0xE5, 0xD0, + 0xCD, 0x3E, 0xBE, 0x2D, 0x39, 0x22, 0x61, 0xBA, + 0xC9, 0x91, 0xA1, 0xF6, 0x6E, 0x5F, 0x7E, 0x2A, + 0x90, 0xD0, 0x26, 0xB7, 0x6D, 0x1B, 0xAE, 0xE2, + 0x54, 0xDE, 0x79, 0xF8, 0x39, 0x1E, 0xA0, 0xFC, + 0x65, 0xE1, 0x45, 0x22, 0x7A, 0x1A, 0x06, 0x0A, + 0xBB, 0x59, 0x41, 0xF5, 0xCF, 0xC0, 0x4C, 0x76, + 0xB7, 0x98, 0xF8, 0x2F, 0x32, 0xE6, 0x5B, 0xC3, + 0x70, 0xF3, 0xF5, 0x18, 0xC5, 0x0B, 0xAF, 0x82, + 0x4A, 0x17, 0xEF, 0xA5, 0x96, 0xE2, 0x20, 0xBA, + 0xE5, 0x23, 0x55, 0xD2, 0x85, 0xA3, 0x1C, 0x1E, + 0x46, 0xDA, 0xCF, 0xD3, 0xAC, 0x56, 0xF6, 0x94, + 0xFE, 0x14, 0xBB, 0x15, 0xD6, 0xA0, 0xF3, 0x5B, + 0x5C, 0x62, 0xA3, 0xEC, 0xF8, 0x23, 0x75, 0x62, + 0x5D, 0xB9, 0x47, 0x46, 0x25, 0xF1, 0x9E, 0x88, + 0xC0, 0xF7, 0x5A, 0xC2, 0xA7, 0x97, 0xEA, 0xB1, + 0x35, 0x70, 0x02, 0x33, 0x29, 0xA9, 0xF9, 0x36, + 0xC8, 0xF0, 0x70, 0xCB, 0xD0, 0xD4, 0x07, 0x26, + 0xD6, 0x9C, 0x62, 0x37, 0xEB, 0xDD, 0xE1, 0x71, + 0x10, 0x49, 0x52, 0x86, 0x71, 0xC1, 0xB7, 0x78, + 0xE4, 0x85, 0xC2, 0x34, 0x3E, 0x83, 0xF2, 0xBE, + 0x31, 0x51, 0x65, 0xF4, 0x42, 0xE4, 0x66, 0x85, + 0xE8, 0xEF, 0xDD, 0xD9, 0xE0, 0x41, 0x3E, 0x25, + 0xF2, 0x9D, 0xCA, 0x48, 0xF3, 0x55, 0x99, 0x83, + 0xD6, 0xF3, 0x96, 0x37, 0xF5, 0x18, 0x90, 0x2E, + 0xA4, 0xA7, 0xE1, 0x08, 0x89, 0xFA, 0x54, 0x22, + 0xE8, 0x1D, 0x8E, 0xFE, 0x94, 0xED, 0x86, 0xF2, + 0x21, 0xE4, + + 0xE1, 0x07, 0xBB, 0xC9, 0x51, 0x1C, 0xA7, 0x07, + 0xE9, 0x61, 0x25, 0xB4, 0x69, 0x8D, 0x72, 0xF1, + 0xF0, 0x12, 0xBB, 0x01, 0xD0, 0xCA, 0x4F, 0x29, + 0x42, 0x6B, 0x97, 0x7E, 0xC1, 0x8B, 0x1D, 0x9B, + 0x64, 0xD9, 0x21, 0x24, 0xF3, 0xE0, 0xEA, 0x72, + 0xD3, 0x5E, 0xEB, 0x71, 0x27, 0xEE, 0xEF, 0x09, + 0x3A, 0xDF, 0x73, 0x2E, 0xBE, 0x30, 0x57, 0xCD, + 0xEB, 0x49, 0x28, 0x83, 0x58, 0xB6, 0xBB, 0x91, + 0x90, 0xAC, 0x38, 0xBF, 0xC5, 0x6A, 0x6F, 0x6E, + 0x2F, 0xFF, 0x98, 0xD2, 0xFF, 0xE1, 0xB6, 0x5C, + 0x10, 0x3F, 0xBB, 0xA5, 0xDB, 0xC8, 0x56, 0x64, + 0x0D, 0xD6, 0xBE, 0xD2, 0x76, 0xF0, 0x33, 0xA0, + 0x37, 0xD1, 0xC6, 0xF1, 0x32, 0x96, 0x84, 0x17, + 0xE9, 0x4D, 0x37, 0x1B, 0x76, 0x60, 0x5F, 0xAA, + 0xD0, 0x70, 0xEF, 0xA7, 0x83, 0x48, 0xC6, 0xAE, + 0xB0, 0xCF, 0x6B, 0x72, 0x2D, 0x43, 0x7A, 0x7C, + 0x18, 0x25, 0x6B, 0xC7, 0x16, 0x60, 0x5C, 0x5D, + 0xF9, 0x1E, 0xE4, 0x0B, 0xAD, 0x7B, 0x06, 0x23, + 0xCA, 0xB8, 0x46, 0x05, 0xFC, 0x47, 0xBF, 0xCC, + 0xF7, 0x78, 0x9A, 0xB6, 0xDE, 0x12, 0xA0, 0x5D, + 0x1C, 0x1B, 0xF5, 0x36, 0x77, 0x9E, 0x8F, 0x95, + 0x7E, 0x3F, 0x5F, 0x82, 0xE7, 0xF5, 0x3D, 0xF6, + 0xEF, 0x13, 0x95, 0xB5, 0xEE, 0x3B, 0x1F, 0x0E, + 0x20, 0x02, 0xEA, 0x85, 0xFB, 0x09, 0x84, 0xCE, + 0x93, 0x8D, 0x48, 0x67, 0xCC, 0xA0, 0x98, 0x2E, + 0xFF, 0xD4, 0x5D, 0x45, 0x81, 0x0D, 0x43, 0xA5, + 0xD5, 0xC9, 0xD1, 0x4D, 0x5B, 0x3A, 0x9F, 0x4D, + 0x85, 0x8E, 0x95, 0x6A, 0xD7, 0x98, 0x85, 0x95, + 0x6F, 0x3E, 0x1E, + + 0x8F, 0x79, 0x64, 0x19, 0x20, 0xB6, 0x73, 0xAD, + 0x05, 0xF9, 0x92, 0xB5, 0x64, 0xFD, 0x00, 0x8A, + 0xD1, 0x35, 0x86, 0xF9, 0x1B, 0x1C, 0x6C, 0x48, + 0x2A, 0x54, 0x07, 0xCD, 0x59, 0xD7, 0xC2, 0x1B, + 0xA5, 0xF6, 0x25, 0x80, 0xF2, 0xC7, 0x4D, 0xE6, + 0xC8, 0xB1, 0x6B, 0x02, 0x90, 0x19, 0x82, 0xCD, + 0xEB, 0x35, 0xC5, 0xB9, 0x9C, 0xE6, 0x18, 0xBF, + 0xD5, 0xFA, 0x16, 0x72, 0x5E, 0x41, 0x1B, 0x85, + 0xB3, 0xA6, 0x96, 0xA8, 0x3C, 0x84, 0x7A, 0xB9, + 0xCE, 0xA5, 0x18, 0xA8, 0xE5, 0x78, 0x9C, 0x1D, + 0x2D, 0x5F, 0x8C, 0x7C, 0x09, 0xF9, 0xE5, 0xFB, + 0xDD, 0x56, 0xD9, 0x95, 0x60, 0xB1, 0x12, 0xD6, + 0x86, 0x6C, 0x3B, 0xE8, 0x2C, 0x22, 0xE3, 0xAB, + 0xEF, 0xC5, 0x8E, 0x0A, 0x3F, 0x6E, 0x3A, 0x1B, + 0x5D, 0x39, 0x96, 0x1B, 0xC3, 0x8B, 0x59, 0x1C, + 0xC3, 0xE4, 0x10, 0xD7, 0x29, 0x43, 0x14, 0xEB, + 0x63, 0x88, 0x53, 0x6E, 0x44, 0x8F, 0xAD, 0x5A, + 0xDD, 0xF4, 0x8A, 0xD0, 0x20, 0x21, 0x02, 0x6B, + 0x81, 0x05, 0xB1, 0xC4, 0xD2, 0xA1, 0x48, 0x70, + 0xF7, 0x66, 0xE3, 0xBE, 0x15, 0xB5, 0xF5, 0x43, + 0x66, 0x12, 0x94, 0x56, 0x88, 0x31, 0xE6, 0xAC, + 0xC4, 0x54, 0x48, 0x9F, 0x51, 0x09, 0x3D, 0x95, + 0xA4, 0x83, 0x62, 0xD8, 0x47, 0x3D, 0xEB, 0xC4, + 0x5B, 0x6D, 0x38, 0x98, 0x93, 0x89, 0xF0, 0x1C, + 0x40, 0x00, 0x02, 0xE6, 0xCA, 0xDB, 0x95, 0xE6, + 0x8E, 0x44, 0xE0, 0x5F, 0xC9, 0x62, 0x55, 0x3F, + 0xC8, 0x48, 0x5D, 0x12, 0xE7, 0x01, 0x87, 0x5C, + 0x07, 0xF3, 0x0E, 0x0F, 0xD7, 0x89, 0x04, 0x3F, + 0x2A, 0x10, 0x70, 0xCC, + + 0x3C, 0xB9, 0x3D, 0x28, 0x90, 0xEB, 0x21, 0x7D, + 0x9E, 0xCC, 0x4D, 0xA5, 0x84, 0xF6, 0x96, 0x93, + 0x5D, 0x12, 0x84, 0x9E, 0x71, 0x56, 0x5C, 0xD4, + 0x71, 0xB9, 0x9F, 0xDF, 0x2B, 0x51, 0x43, 0xC5, + 0x1E, 0x98, 0xBE, 0x8D, 0xB8, 0xFE, 0x3A, 0x9C, + 0x22, 0x25, 0xF2, 0x0F, 0x7F, 0x52, 0xB3, 0x9A, + 0xB6, 0xD8, 0x31, 0xE9, 0xC3, 0x9A, 0x86, 0x89, + 0xB6, 0x1B, 0x63, 0x3F, 0xC0, 0x37, 0x7D, 0xFF, + 0x80, 0xC3, 0x28, 0x0D, 0xF1, 0x09, 0xB1, 0xD1, + 0x38, 0xA8, 0x99, 0xD9, 0x81, 0x32, 0x62, 0x16, + 0xDE, 0x2D, 0x16, 0x07, 0x78, 0x5D, 0xCB, 0xB8, + 0x3E, 0xB8, 0x01, 0x5A, 0xB5, 0x21, 0x6E, 0xA1, + 0x7B, 0xD8, 0x64, 0x00, 0xFC, 0x6B, 0xDF, 0xA4, + 0x4D, 0x07, 0x81, 0xEE, 0x76, 0x69, 0x43, 0x9F, + 0x90, 0x09, 0x24, 0x26, 0x72, 0xC5, 0x2F, 0xF5, + 0x50, 0x31, 0xC9, 0xB9, 0x3B, 0xAE, 0xDE, 0x1F, + 0x6B, 0xCC, 0xFA, 0xC6, 0xCB, 0xBC, 0xEC, 0x75, + 0x91, 0x3A, 0x0C, 0x5D, 0x13, 0xB9, 0x3E, 0x16, + 0x3C, 0xE4, 0xAC, 0x56, 0x60, 0x0C, 0x92, 0x2D, + 0x05, 0xD6, 0x1A, 0x01, 0xC4, 0x94, 0xAD, 0x19, + 0xEE, 0x3C, 0x79, 0x5D, 0x5C, 0x49, 0x8A, 0x67, + 0xAF, 0x19, 0x1B, 0xBA, 0x2C, 0x30, 0xA2, 0x47, + 0xF2, 0x35, 0x00, 0x15, 0xF0, 0x7B, 0xC1, 0xA2, + 0xB3, 0x9C, 0x49, 0x83, 0x81, 0x26, 0x71, 0x7E, + 0xF0, 0x34, 0x01, 0x02, 0xC0, 0xDE, 0x44, 0xFA, + 0xFA, 0x5F, 0x84, 0xBA, 0x23, 0x16, 0x39, 0x29, + 0x77, 0xD7, 0x5D, 0x17, 0xBA, 0x9A, 0x39, 0x93, + 0xBE, 0xBB, 0x01, 0x67, 0xD6, 0x23, 0x2B, 0x7F, + 0x9E, 0x29, 0x61, 0xCC, 0x4D, + + 0xCE, 0x24, 0x29, 0x8D, 0x54, 0x03, 0x84, 0x07, + 0xF8, 0x5A, 0x69, 0x9A, 0x3E, 0x01, 0xF5, 0x63, + 0xFC, 0x16, 0xB6, 0xF0, 0x20, 0x39, 0x81, 0x10, + 0xCD, 0x82, 0xD5, 0x5D, 0xAE, 0xED, 0xA6, 0x86, + 0xA5, 0xFF, 0xF8, 0x85, 0x6E, 0x0A, 0x36, 0x2F, + 0x6B, 0xF6, 0x62, 0xAB, 0x12, 0xE6, 0x41, 0x2B, + 0x3D, 0x4D, 0xDB, 0x80, 0x26, 0xC9, 0xAD, 0xE4, + 0x93, 0x05, 0x0C, 0x28, 0x23, 0xFF, 0x9B, 0xBF, + 0x85, 0x43, 0x82, 0xCD, 0x6E, 0x5F, 0xD4, 0x08, + 0x31, 0xFA, 0x52, 0x78, 0x99, 0x15, 0xD0, 0xD5, + 0xBD, 0x7C, 0xD4, 0x91, 0xCB, 0x0F, 0x53, 0xE7, + 0x5D, 0x53, 0xE8, 0xDA, 0xAB, 0x32, 0xDF, 0xD8, + 0xCF, 0xF5, 0x95, 0xF1, 0x41, 0xCF, 0x37, 0x2B, + 0xF0, 0x51, 0x93, 0x33, 0xAA, 0xFF, 0x36, 0x07, + 0x3C, 0xF9, 0x40, 0x18, 0x05, 0xA6, 0x1B, 0xEF, + 0x9E, 0x5E, 0x71, 0x77, 0x75, 0xD2, 0x23, 0xD6, + 0x0F, 0x5A, 0x84, 0x73, 0x6C, 0x23, 0x17, 0x18, + 0x78, 0x84, 0x41, 0xEC, 0x76, 0xD5, 0x66, 0xDE, + 0xF3, 0x22, 0x6E, 0x03, 0xD0, 0xF0, 0xFE, 0x67, + 0x8C, 0x4B, 0x4F, 0x43, 0xC8, 0x94, 0xBE, 0x8D, + 0x3C, 0x34, 0xA9, 0x1E, 0xC2, 0x27, 0x64, 0x90, + 0x13, 0x85, 0xA7, 0xC1, 0xC9, 0xF3, 0x6E, 0x50, + 0x0B, 0xD5, 0xD1, 0x38, 0xB0, 0x53, 0x0D, 0xDC, + 0x5A, 0xE8, 0x6B, 0x30, 0x91, 0xA2, 0x73, 0xDA, + 0x5C, 0xB3, 0x77, 0x36, 0xBC, 0xE1, 0xBF, 0xE0, + 0x85, 0x3B, 0xAC, 0x73, 0x13, 0xD1, 0x72, 0x0D, + 0x36, 0x47, 0xAE, 0x77, 0xA9, 0x91, 0x3B, 0x65, + 0x3F, 0x20, 0xED, 0x65, 0x02, 0x98, 0xAE, 0x1B, + 0x6B, 0x22, 0x17, 0x9F, 0x10, 0x64, + + 0x43, 0xA6, 0xF3, 0x60, 0x88, 0x3A, 0x74, 0x66, + 0xA5, 0x48, 0xB2, 0x8F, 0x82, 0x94, 0xCC, 0xFD, + 0xCB, 0x15, 0x13, 0x60, 0x9B, 0xE4, 0x97, 0x96, + 0x2E, 0x36, 0xF9, 0xB3, 0x7B, 0xEC, 0xF1, 0xC3, + 0x54, 0xF0, 0xBB, 0xA0, 0xA8, 0x4A, 0x28, 0xB7, + 0x3A, 0x2E, 0xEC, 0x36, 0x5D, 0x0F, 0x26, 0xDE, + 0x3A, 0x24, 0x53, 0x13, 0x3F, 0xEA, 0x7C, 0x03, + 0xEB, 0x83, 0x53, 0x76, 0x8E, 0x83, 0xBC, 0x15, + 0x77, 0x04, 0xCC, 0xEF, 0x16, 0x7A, 0x40, 0xBA, + 0x14, 0xAB, 0x79, 0xB3, 0x2C, 0x18, 0xCE, 0xEC, + 0xC0, 0xF0, 0x66, 0x61, 0x99, 0xF7, 0x31, 0x3C, + 0x69, 0x66, 0xB5, 0xC0, 0xF4, 0x22, 0x4E, 0xCC, + 0x8A, 0xE9, 0xAC, 0x94, 0xC7, 0xC4, 0xC0, 0x88, + 0xCB, 0xF3, 0x4C, 0x49, 0xD1, 0x87, 0x55, 0xB8, + 0x15, 0x34, 0x47, 0x4B, 0xF0, 0x5B, 0xB3, 0xBB, + 0x77, 0x15, 0xED, 0x3F, 0xF8, 0x4F, 0xD3, 0x9D, + 0xFE, 0x8C, 0xD5, 0x4C, 0xE1, 0x2B, 0x74, 0x6F, + 0xA3, 0xBF, 0x03, 0x8A, 0xDF, 0xC2, 0xBF, 0xC5, + 0x27, 0x0F, 0xAF, 0x53, 0x42, 0x9A, 0x69, 0x39, + 0x33, 0xC7, 0x73, 0x67, 0x2E, 0xCE, 0x88, 0xD6, + 0xCF, 0xBB, 0x7C, 0xCB, 0x0D, 0x84, 0x0E, 0xB9, + 0x54, 0xFD, 0x51, 0x9F, 0xE3, 0x62, 0x87, 0xC7, + 0x5F, 0x08, 0xFE, 0x4C, 0x2E, 0xEA, 0x7F, 0xF2, + 0xC6, 0xB8, 0xEB, 0xDC, 0x35, 0x02, 0x1A, 0x6C, + 0xEB, 0xC0, 0x73, 0x82, 0x34, 0x52, 0xBE, 0x55, + 0x14, 0xB9, 0x36, 0x3D, 0xC8, 0x88, 0x03, 0x51, + 0x35, 0x7D, 0x89, 0x1B, 0x36, 0xA9, 0xD4, 0x03, + 0xA0, 0x86, 0x66, 0x90, 0x10, 0xC0, 0xBD, 0x39, + 0x5D, 0xB5, 0x4A, 0x67, 0x49, 0x2A, 0xBC, + + 0x05, 0x95, 0xB2, 0x93, 0x14, 0x73, 0xB3, 0x70, + 0x89, 0xE4, 0xCC, 0x29, 0x8C, 0x60, 0x49, 0x46, + 0xBD, 0xC5, 0x33, 0x19, 0x32, 0xEE, 0xC7, 0xFA, + 0x6B, 0x93, 0x8B, 0x09, 0x75, 0x6D, 0xC6, 0x81, + 0xFA, 0xE9, 0xB1, 0x91, 0xBE, 0x74, 0xDF, 0x09, + 0xB6, 0xDB, 0x98, 0x67, 0x26, 0x7E, 0x8C, 0x0F, + 0x27, 0x5D, 0x38, 0x22, 0xCE, 0x70, 0x60, 0x7A, + 0xA1, 0xA5, 0x2F, 0xCC, 0x71, 0x18, 0x0C, 0x17, + 0x3D, 0x2A, 0xDD, 0xEC, 0xFA, 0xCB, 0x5B, 0x0E, + 0xD4, 0x4C, 0x3D, 0xED, 0x8A, 0xDE, 0xA5, 0x3D, + 0x1E, 0x35, 0xE4, 0xAB, 0xAF, 0x14, 0x5F, 0xF0, + 0x3F, 0xA0, 0x11, 0x5A, 0xC5, 0x64, 0x40, 0xEC, + 0x11, 0x90, 0x70, 0xDE, 0x01, 0x7F, 0xAD, 0xAE, + 0xE1, 0x30, 0x94, 0x6E, 0x1E, 0xE3, 0x22, 0xCD, + 0xC3, 0x91, 0x25, 0x77, 0x25, 0x9A, 0x62, 0xFA, + 0x43, 0xAC, 0x32, 0x8E, 0xE7, 0xB7, 0xF2, 0xD0, + 0x54, 0xD4, 0xC4, 0x6C, 0xB3, 0x88, 0xDD, 0xDA, + 0x82, 0xD6, 0xA4, 0x33, 0xC1, 0xAA, 0x42, 0xD1, + 0x26, 0x0C, 0xE7, 0xEC, 0x81, 0x87, 0x50, 0x56, + 0x00, 0xC0, 0xAC, 0xEE, 0x96, 0xBC, 0x67, 0xEB, + 0x03, 0x58, 0x38, 0x67, 0x71, 0x1B, 0xD8, 0x59, + 0xA2, 0xC5, 0x77, 0xA4, 0xD5, 0x39, 0x95, 0x13, + 0x60, 0x3C, 0x4F, 0x28, 0xD4, 0xB2, 0x9E, 0x15, + 0x3D, 0xB5, 0x24, 0x37, 0x32, 0xCC, 0x2C, 0x22, + 0xD3, 0x02, 0xAF, 0x60, 0x7F, 0x8E, 0x56, 0x59, + 0xC7, 0x52, 0x1A, 0xF7, 0x43, 0x70, 0x6E, 0xE6, + 0xFF, 0x2C, 0x94, 0x22, 0x85, 0x28, 0xEF, 0x24, + 0x83, 0x7F, 0x80, 0xAF, 0x4E, 0x7F, 0x37, 0x21, + 0x78, 0x9B, 0x31, 0x2E, 0x3A, 0xC0, 0xCE, 0x49, + + 0x1C, 0x1A, 0x99, 0x58, 0xBA, 0x52, 0xC5, 0x41, + 0xFB, 0x0A, 0x17, 0xAF, 0x23, 0x3B, 0xBF, 0x3D, + 0x5B, 0x70, 0x45, 0xB9, 0xC2, 0xF4, 0xD5, 0xB2, + 0xF9, 0x5E, 0x82, 0xC0, 0x19, 0x99, 0x3F, 0xCB, + 0x22, 0xEC, 0x10, 0xF3, 0x26, 0xBA, 0xC7, 0xD4, + 0x9B, 0x2D, 0xFF, 0x3C, 0x39, 0xE4, 0xFB, 0x4D, + 0xC5, 0x5A, 0x01, 0x43, 0xBC, 0x83, 0x9F, 0x17, + 0x4E, 0xDC, 0xFE, 0x4B, 0x2E, 0x3C, 0x67, 0xA9, + 0x2A, 0xDB, 0xC4, 0x28, 0xB6, 0xD7, 0xB1, 0x24, + 0xDB, 0x10, 0xE6, 0x27, 0xF9, 0x29, 0xFC, 0x63, + 0x57, 0x72, 0xB6, 0xA0, 0x8C, 0x25, 0x7F, 0x67, + 0x94, 0x70, 0xBB, 0xBF, 0x2F, 0x60, 0xF4, 0xF3, + 0x98, 0x85, 0xBD, 0xE6, 0x50, 0xDC, 0xA6, 0x0E, + 0x96, 0xE7, 0x9F, 0x3C, 0x4F, 0xAE, 0xC7, 0x95, + 0xDB, 0x67, 0xEC, 0x20, 0x54, 0x2B, 0x34, 0xFA, + 0x04, 0x98, 0x77, 0xEE, 0xAD, 0xE4, 0x65, 0x94, + 0x94, 0xD6, 0x6D, 0xE0, 0x81, 0x15, 0x1F, 0x10, + 0x0F, 0x34, 0xEE, 0x64, 0x47, 0xD4, 0x15, 0x07, + 0xF4, 0x38, 0xC5, 0xEE, 0x06, 0x6F, 0x8A, 0xE6, + 0x7A, 0x18, 0x2E, 0x2E, 0xAB, 0xE7, 0xD9, 0x5C, + 0xD6, 0x58, 0xE4, 0x22, 0x21, 0xFB, 0xE0, 0x34, + 0x46, 0xE1, 0xBE, 0x89, 0x17, 0xC7, 0x8A, 0xD7, + 0x22, 0xE6, 0xE4, 0xDF, 0xA8, 0xCE, 0xFF, 0x2D, + 0xC4, 0x63, 0xF8, 0x83, 0x70, 0x3B, 0x4F, 0xB6, + 0x62, 0xA0, 0x50, 0x46, 0x30, 0xB1, 0x3E, 0xE8, + 0x2E, 0xBE, 0xFC, 0xAA, 0x5C, 0xF5, 0x68, 0xB3, + 0x47, 0xBF, 0x65, 0x3E, 0x64, 0x72, 0x6F, 0x90, + 0x89, 0x88, 0x2F, 0x82, 0x35, 0xE9, 0xF6, 0xD1, + 0xFA, 0xEE, 0x25, 0xDC, 0xA0, 0x04, 0xD7, 0x0B, + 0x1E, + + 0xED, 0x32, 0x54, 0xE8, 0x2D, 0x03, 0x35, 0xD5, + 0x55, 0x62, 0x1F, 0xD2, 0x2A, 0xE5, 0x69, 0x47, + 0xD6, 0xD8, 0x92, 0xBC, 0x3D, 0xF1, 0xAB, 0x57, + 0xFE, 0x03, 0x12, 0xCE, 0xAD, 0xF8, 0x1D, 0x37, + 0xB2, 0x40, 0x72, 0xD0, 0xC8, 0x38, 0xE2, 0xD1, + 0xA4, 0x0F, 0xA0, 0x7F, 0x19, 0x72, 0xAF, 0x84, + 0x53, 0x8B, 0x71, 0x66, 0xBF, 0x56, 0x19, 0x3A, + 0xEA, 0x27, 0xFD, 0xF5, 0xB6, 0x43, 0xD4, 0xB8, + 0x8B, 0x27, 0xE8, 0x82, 0x0B, 0x24, 0x3C, 0xD7, + 0xFF, 0x31, 0xF3, 0x6D, 0x15, 0x5D, 0xBD, 0x1D, + 0x93, 0x0F, 0x98, 0x4E, 0x16, 0x00, 0x94, 0xEE, + 0xE6, 0x27, 0xBA, 0x19, 0xC2, 0xCE, 0x73, 0x63, + 0x0C, 0x71, 0xEC, 0x27, 0x70, 0x69, 0x2E, 0x96, + 0xA3, 0x20, 0x98, 0xCF, 0x2B, 0xDF, 0x50, 0x07, + 0xC8, 0x10, 0xCD, 0xA0, 0x6B, 0x9E, 0xBF, 0xEC, + 0xD3, 0x6E, 0x94, 0x70, 0x6B, 0x3F, 0xE1, 0x73, + 0x10, 0xDB, 0x9E, 0x98, 0x5B, 0x5B, 0x97, 0xB9, + 0x07, 0xF4, 0xD6, 0x55, 0xEC, 0x52, 0x86, 0x0E, + 0x14, 0xD5, 0xF9, 0x5F, 0xA9, 0xFB, 0xE1, 0x96, + 0x6E, 0xB1, 0xA8, 0xB0, 0xD3, 0xB1, 0x44, 0x08, + 0xF8, 0xBC, 0x97, 0xC8, 0xF7, 0xE8, 0xD5, 0xC9, + 0xD7, 0x9F, 0x2C, 0xCA, 0xC6, 0x35, 0x26, 0x4F, + 0x2F, 0x83, 0xC0, 0x88, 0x91, 0x8D, 0x9A, 0xD7, + 0xFC, 0x8A, 0x2A, 0x9C, 0x06, 0x8C, 0xFA, 0xC3, + 0xF3, 0xD0, 0x0A, 0x21, 0xE3, 0x4E, 0xDF, 0x6A, + 0xB4, 0x00, 0x9F, 0xF4, 0xB6, 0x6E, 0x41, 0xF2, + 0x1A, 0x5E, 0xC8, 0x8B, 0x36, 0xC2, 0x81, 0xDA, + 0x0C, 0x74, 0x20, 0xC5, 0x41, 0x60, 0xD1, 0x2A, + 0xEB, 0xAA, 0x51, 0xCB, 0x38, 0x10, 0x94, 0x8B, + 0xA2, 0x89, + + 0x90, 0xBB, 0xE5, 0x2E, 0xDE, 0xBA, 0xB1, 0x0F, + 0x5C, 0xB8, 0x39, 0x67, 0xF9, 0x10, 0x1A, 0x72, + 0x33, 0xA4, 0x9B, 0x47, 0x5C, 0xC3, 0x97, 0x66, + 0xA9, 0x31, 0xC6, 0xD6, 0xD1, 0x64, 0x51, 0x19, + 0x3A, 0xAC, 0xBF, 0x99, 0x1B, 0x1C, 0xEC, 0x32, + 0x4F, 0x69, 0xC7, 0x6D, 0xBD, 0x4A, 0xEE, 0x29, + 0x75, 0x66, 0x42, 0xF7, 0x40, 0x58, 0xE5, 0x05, + 0x84, 0x18, 0x8A, 0x82, 0xE8, 0x8E, 0x13, 0x19, + 0x89, 0x6F, 0xC1, 0xDD, 0x43, 0x0C, 0xC5, 0x63, + 0xE2, 0xC4, 0xCC, 0x33, 0x61, 0xF4, 0xE6, 0x6B, + 0x9B, 0x39, 0x5E, 0xA1, 0x8E, 0x80, 0x8C, 0x13, + 0x1B, 0xE5, 0xD4, 0x4D, 0x7A, 0xDD, 0xF4, 0x52, + 0x51, 0x0C, 0x0B, 0x1F, 0x23, 0x52, 0xC8, 0x52, + 0xF8, 0xD4, 0x88, 0x3E, 0xAE, 0xB8, 0x98, 0xF8, + 0x76, 0xB3, 0xAD, 0x6B, 0x20, 0xD4, 0x83, 0x87, + 0x68, 0x45, 0x5C, 0xA8, 0xB3, 0xA0, 0xA4, 0xB9, + 0xE7, 0x16, 0x06, 0x48, 0xEF, 0x45, 0x33, 0x29, + 0xAB, 0x75, 0xE6, 0x9D, 0x83, 0x74, 0xF9, 0xF7, + 0x22, 0xA0, 0xC5, 0xFF, 0x9E, 0x35, 0x6A, 0x46, + 0x7B, 0x80, 0x21, 0xE7, 0x47, 0xD8, 0x4C, 0x37, + 0xB1, 0x96, 0x05, 0xBD, 0xE2, 0x1B, 0xDF, 0xE9, + 0x34, 0x4B, 0xBF, 0x03, 0x72, 0xB8, 0x47, 0x6E, + 0xE4, 0xB8, 0xDB, 0x63, 0xD6, 0xC2, 0x62, 0x8E, + 0xA8, 0x28, 0x1F, 0xC3, 0x1C, 0x35, 0x1F, 0x2C, + 0xCD, 0x24, 0xAF, 0x6A, 0x38, 0x1D, 0xA1, 0xC8, + 0x07, 0xA7, 0xB7, 0x04, 0x5A, 0xC6, 0x08, 0x4E, + 0x29, 0xBB, 0xA2, 0x19, 0xFE, 0x54, 0x2F, 0xD8, + 0xF3, 0xB3, 0x3E, 0x60, 0xFF, 0x27, 0xB1, 0x88, + 0x2F, 0x2C, 0xB7, 0x66, 0x09, 0x97, 0xE5, 0x09, + 0x77, 0x5F, 0x53, + + 0xD3, 0xA5, 0x23, 0x44, 0x45, 0xCA, 0x7B, 0xF1, + 0x84, 0xF2, 0x59, 0x2F, 0x75, 0xC6, 0xC3, 0x49, + 0xEC, 0x4C, 0xA2, 0x4A, 0xF9, 0xD1, 0xBB, 0x1D, + 0xBB, 0x30, 0x2E, 0x18, 0xDD, 0xFF, 0xC8, 0x77, + 0x2D, 0x8F, 0x09, 0x6F, 0x65, 0x5A, 0x64, 0x6B, + 0xEB, 0x8A, 0xDF, 0xA2, 0x50, 0xBA, 0x5A, 0x54, + 0x79, 0xE5, 0x14, 0x69, 0x42, 0x34, 0xE8, 0xA0, + 0x62, 0xA5, 0x3A, 0x7A, 0x49, 0xB1, 0x8B, 0xA3, + 0xD8, 0x73, 0x57, 0x70, 0xE3, 0x93, 0x04, 0xE4, + 0x59, 0x86, 0x8A, 0x7B, 0xBE, 0x65, 0x48, 0x16, + 0xB5, 0xE6, 0xAF, 0xC3, 0xBD, 0xFF, 0x3C, 0xDF, + 0xF6, 0xCB, 0x60, 0xE4, 0xBA, 0x77, 0xF4, 0x4B, + 0x95, 0x79, 0xCE, 0xD6, 0x36, 0xBD, 0xBF, 0x36, + 0x42, 0x53, 0x15, 0xA3, 0x77, 0xB3, 0x9F, 0x68, + 0x98, 0x6E, 0xB5, 0x01, 0x16, 0xA2, 0x26, 0x79, + 0xB0, 0x1A, 0x65, 0x45, 0x30, 0xBB, 0x00, 0x4F, + 0xE4, 0x7A, 0xD0, 0x31, 0xE5, 0x77, 0xD4, 0xC6, + 0x6A, 0x72, 0xC5, 0xF2, 0xC1, 0xFC, 0x60, 0x74, + 0x99, 0xD5, 0x25, 0xF2, 0x7B, 0x6D, 0xFE, 0x32, + 0x1C, 0x90, 0xD0, 0xF9, 0xF0, 0xAE, 0x93, 0x20, + 0xB4, 0xA0, 0xF7, 0xA5, 0x75, 0xE4, 0x83, 0x94, + 0x80, 0x8C, 0x1E, 0x18, 0xD7, 0x1C, 0xA4, 0x5F, + 0x0A, 0x08, 0xD2, 0xB1, 0x27, 0xC4, 0x0D, 0xA4, + 0xBE, 0xE0, 0x36, 0x69, 0x19, 0x14, 0x9A, 0x58, + 0x9C, 0xD5, 0x36, 0xE5, 0x46, 0xE1, 0x94, 0x66, + 0xC3, 0x77, 0x78, 0x52, 0xF9, 0x2B, 0xDA, 0x95, + 0xDC, 0xED, 0x6A, 0x6E, 0x58, 0xE9, 0x16, 0x34, + 0x2A, 0x6B, 0xD5, 0x4E, 0xF2, 0x7E, 0xB8, 0x96, + 0xEB, 0x9B, 0x4D, 0xD3, 0xFD, 0xB4, 0x33, 0x0D, + 0x13, 0x26, 0x42, 0x3E, + + 0xF6, 0x0F, 0x59, 0xEC, 0xB0, 0xE1, 0x3D, 0x20, + 0xB8, 0xD7, 0x3D, 0xF9, 0x59, 0xCF, 0xEF, 0xA9, + 0xD7, 0xB2, 0x47, 0xBC, 0x87, 0x54, 0xD3, 0x7E, + 0xF9, 0x2C, 0xDF, 0xB6, 0x0F, 0x86, 0x13, 0x02, + 0x1C, 0xFA, 0xC0, 0x26, 0xDB, 0x49, 0x3B, 0x36, + 0x60, 0xA2, 0x64, 0xD8, 0x91, 0xB1, 0x7C, 0x35, + 0xEA, 0x2F, 0x5E, 0xF6, 0x99, 0xE2, 0x0B, 0x74, + 0x1F, 0x76, 0xF6, 0x8F, 0x7E, 0x58, 0x63, 0x3E, + 0xB6, 0xA2, 0xF3, 0x0A, 0xD4, 0xA5, 0x19, 0xB7, + 0x45, 0x08, 0xDB, 0x52, 0x17, 0x1D, 0xB1, 0x00, + 0x23, 0x0B, 0xD4, 0xC0, 0x86, 0x52, 0x49, 0xA8, + 0x33, 0xAB, 0x0A, 0xD1, 0x51, 0x9C, 0x5D, 0x4B, + 0x23, 0xF1, 0x93, 0x17, 0x6A, 0x48, 0xA6, 0x2F, + 0x9D, 0x0D, 0x9A, 0x09, 0xBD, 0x19, 0xA0, 0x39, + 0x60, 0xDE, 0xD1, 0xE4, 0x42, 0xD8, 0x34, 0xC0, + 0x1D, 0xD3, 0x88, 0x29, 0xA8, 0x48, 0x75, 0x5C, + 0xDF, 0x1D, 0xD4, 0x09, 0x53, 0x5E, 0x5D, 0x0A, + 0x9A, 0x2D, 0x95, 0x83, 0xF6, 0x85, 0x2F, 0xAD, + 0x8C, 0xFF, 0x55, 0xD8, 0x19, 0x56, 0xEE, 0x38, + 0xD2, 0x25, 0x30, 0x27, 0x21, 0xB5, 0x10, 0xED, + 0x24, 0xFB, 0x0E, 0x22, 0x55, 0xA2, 0xC3, 0x31, + 0xDC, 0x1E, 0xA0, 0xC7, 0x4B, 0x1B, 0xC0, 0x14, + 0x95, 0x25, 0x8F, 0x37, 0x3C, 0x75, 0x61, 0x44, + 0x0B, 0x09, 0x81, 0x8C, 0x32, 0xE5, 0x59, 0x3D, + 0xE3, 0xD5, 0x45, 0xDF, 0x11, 0xFF, 0x61, 0x9E, + 0x01, 0x10, 0x5E, 0x91, 0x70, 0x18, 0x1D, 0x76, + 0xC9, 0x74, 0x3C, 0xDD, 0x30, 0xB2, 0x01, 0xF5, + 0xCD, 0xCD, 0x9F, 0xFC, 0xE3, 0x7A, 0xB9, 0xD1, + 0x7F, 0xA4, 0x3C, 0x2E, 0x2C, 0x28, 0x25, 0xCC, + 0x6C, 0x56, 0x3A, 0x80, 0xF9, + + 0x7E, 0x13, 0xEF, 0xE6, 0x6B, 0x69, 0x25, 0xE0, + 0x81, 0xE9, 0x64, 0x4E, 0xE9, 0xFC, 0x00, 0x0C, + 0xDD, 0x81, 0x66, 0xB1, 0xC9, 0x12, 0xC4, 0x98, + 0x5F, 0x71, 0x2F, 0xFC, 0xFB, 0x24, 0x9E, 0x49, + 0x5E, 0xFB, 0x20, 0xB9, 0x56, 0x06, 0x23, 0xD3, + 0xD5, 0x80, 0x51, 0x25, 0xE6, 0x33, 0x55, 0xC0, + 0x48, 0x28, 0x32, 0xDB, 0xBB, 0x48, 0x6D, 0xF6, + 0x30, 0xA7, 0x4D, 0xC6, 0x54, 0x7A, 0x63, 0x5E, + 0x54, 0x7A, 0xE4, 0xEB, 0x71, 0x03, 0xA7, 0x65, + 0x1F, 0x36, 0x25, 0x32, 0xD0, 0x3F, 0xA1, 0x07, + 0xAB, 0xE0, 0x17, 0x57, 0x18, 0x06, 0xCB, 0x2B, + 0x78, 0x9F, 0xC3, 0xBD, 0x57, 0x13, 0x4B, 0x0A, + 0x52, 0xFC, 0x87, 0x39, 0xFF, 0xE6, 0xE8, 0x89, + 0x1D, 0x65, 0x61, 0x36, 0x6B, 0x93, 0xB8, 0xA9, + 0x71, 0x4B, 0xB3, 0xD4, 0x87, 0xBF, 0xAF, 0x89, + 0xB7, 0x57, 0x8F, 0x11, 0x3D, 0x36, 0xF2, 0x13, + 0x89, 0x92, 0x7C, 0xD6, 0xFE, 0x18, 0x9F, 0x4A, + 0x7F, 0xBE, 0x34, 0x1F, 0xAF, 0xCB, 0xFB, 0xCA, + 0x74, 0x7B, 0x4D, 0x93, 0x71, 0x45, 0xE4, 0xA0, + 0x4E, 0xE7, 0x4B, 0x9E, 0xFE, 0x45, 0x13, 0xDB, + 0xE9, 0x26, 0xD8, 0x75, 0xA5, 0xB6, 0x8A, 0x5E, + 0xF7, 0x7A, 0xE1, 0xA6, 0x78, 0xEB, 0xBA, 0xBA, + 0xC6, 0xB2, 0xC2, 0xCF, 0x04, 0x8A, 0x72, 0x6C, + 0xA2, 0x53, 0xDE, 0xC8, 0x91, 0xDB, 0x05, 0x46, + 0xA4, 0x86, 0x0C, 0xB8, 0xD0, 0x0F, 0x15, 0x10, + 0xD4, 0xC3, 0xA1, 0x53, 0xEA, 0x9F, 0x9A, 0x20, + 0x5A, 0xB3, 0xE8, 0x7A, 0x47, 0xC8, 0xCF, 0x87, + 0xA3, 0x7D, 0x54, 0x5C, 0xF1, 0x84, 0xE2, 0x5E, + 0x8A, 0x98, 0x8E, 0x7F, 0xAE, 0x18, 0x2F, 0x97, + 0xB3, 0x5D, 0x84, 0xFF, 0xEC, 0xAB, + + 0x81, 0x65, 0x82, 0x11, 0xCB, 0x36, 0xCA, 0xE9, + 0x04, 0x0E, 0x35, 0x85, 0xBE, 0xB3, 0x99, 0xDF, + 0xCF, 0xD5, 0x77, 0x38, 0xD4, 0xDC, 0xFE, 0x0D, + 0x01, 0xD3, 0x06, 0x2E, 0x83, 0x2E, 0x3A, 0x8C, + 0x90, 0x84, 0x17, 0x74, 0x28, 0x79, 0xFB, 0x3C, + 0x4B, 0x6D, 0x22, 0x43, 0xD6, 0x54, 0x6C, 0x6D, + 0x04, 0x36, 0xD7, 0x75, 0x95, 0xA0, 0xA8, 0xD1, + 0x42, 0xAC, 0x4B, 0x97, 0xAD, 0x69, 0x3F, 0xBA, + 0x2C, 0x0B, 0xC2, 0xCD, 0x3D, 0x70, 0x31, 0xEE, + 0xE6, 0x9E, 0x81, 0x28, 0x42, 0xAF, 0x67, 0x5D, + 0x3C, 0xFE, 0xDA, 0xF8, 0x89, 0x2F, 0xF8, 0xA0, + 0x19, 0x4E, 0x77, 0x87, 0x45, 0xBC, 0x0D, 0xB6, + 0xC0, 0x16, 0xE3, 0x4D, 0x46, 0x03, 0x89, 0x70, + 0xB0, 0xF3, 0xD3, 0x6F, 0x9A, 0x30, 0xD7, 0x51, + 0x05, 0xAE, 0xCC, 0x3A, 0xC5, 0x68, 0x56, 0x93, + 0x7B, 0x0F, 0x37, 0x96, 0x0E, 0x91, 0xD5, 0x7D, + 0xF9, 0xA6, 0xEB, 0x2C, 0x4E, 0xF6, 0x19, 0x0A, + 0xBA, 0x0F, 0x84, 0xA9, 0xD1, 0xFC, 0xD4, 0x72, + 0x0B, 0xCD, 0x79, 0xDE, 0x05, 0x49, 0x62, 0x4A, + 0x89, 0xEE, 0xB5, 0x6D, 0x5C, 0x28, 0xA7, 0xC7, + 0x96, 0x99, 0xF1, 0x0D, 0x35, 0xE2, 0xB3, 0x0E, + 0x20, 0xDB, 0x0A, 0xAD, 0x32, 0x72, 0x42, 0x40, + 0x60, 0x68, 0x39, 0xE1, 0xD9, 0x2E, 0x74, 0x90, + 0x59, 0xC7, 0xF1, 0xAE, 0x35, 0xC4, 0x0D, 0x8B, + 0xCE, 0xB1, 0xDC, 0x60, 0xD7, 0x03, 0x5A, 0x03, + 0xCD, 0x6F, 0xED, 0xC8, 0x8A, 0xF2, 0x5A, 0xE5, + 0x88, 0xBB, 0x24, 0xA5, 0x6C, 0x8E, 0x95, 0x84, + 0xF3, 0x02, 0x78, 0x5E, 0x7C, 0x8E, 0xDF, 0xCF, + 0xB1, 0x48, 0x5F, 0x16, 0x73, 0x38, 0x46, 0x69, + 0x3E, 0x41, 0x82, 0xBE, 0x29, 0xEC, 0xAF, + + 0x35, 0x6C, 0x92, 0x8B, 0x5B, 0xA9, 0xD1, 0x04, + 0x67, 0x82, 0x3C, 0x7E, 0x26, 0xA3, 0x0B, 0x58, + 0xD2, 0xC7, 0xC2, 0x3E, 0xC3, 0xDF, 0x79, 0x69, + 0xA6, 0x73, 0x38, 0xDC, 0x01, 0x60, 0x17, 0x37, + 0xD7, 0x46, 0xF4, 0xE6, 0x62, 0x72, 0xC7, 0x09, + 0xDB, 0x6F, 0x45, 0xDE, 0x59, 0x85, 0x48, 0xA1, + 0xA4, 0xF7, 0x6D, 0x83, 0x52, 0xC0, 0x64, 0xE3, + 0x4B, 0xFB, 0xCD, 0xAB, 0x62, 0x10, 0xF7, 0x40, + 0x07, 0xAA, 0x51, 0x83, 0xCF, 0xD8, 0xFD, 0xC1, + 0x35, 0x27, 0x0A, 0xCE, 0x21, 0x5E, 0x85, 0xF8, + 0x10, 0x0C, 0xAD, 0xCE, 0xD3, 0xB2, 0xF0, 0xCB, + 0x03, 0x4A, 0xE1, 0x8E, 0x8E, 0xF1, 0x05, 0xE3, + 0x1E, 0xBD, 0x35, 0xB3, 0x41, 0xEA, 0x39, 0x93, + 0xAD, 0xE2, 0xBC, 0xFD, 0x68, 0xCF, 0xAF, 0xDE, + 0x3F, 0xB3, 0xDD, 0xB3, 0x1A, 0x4C, 0x81, 0x6D, + 0x3E, 0x7E, 0x76, 0xA3, 0xB8, 0x26, 0x9D, 0xA4, + 0xD9, 0xAC, 0x88, 0x71, 0xEC, 0xE9, 0x4F, 0xA5, + 0xBF, 0x53, 0xB6, 0xFF, 0x52, 0xDA, 0xCB, 0x9B, + 0x2B, 0x67, 0xAF, 0x50, 0xEE, 0xCF, 0xA5, 0xD0, + 0x35, 0xAA, 0xB5, 0xE9, 0x34, 0x8E, 0x62, 0xD6, + 0x11, 0x94, 0xD0, 0xA7, 0xEF, 0xB9, 0xA2, 0x19, + 0x22, 0x17, 0xE4, 0x20, 0x35, 0xB6, 0x60, 0x8F, + 0x26, 0xAA, 0x3C, 0x41, 0xC8, 0xFC, 0xBC, 0xEE, + 0x5E, 0x42, 0xF6, 0x9B, 0x79, 0xBA, 0xAA, 0x4D, + 0x59, 0x18, 0xC9, 0x00, 0x9F, 0x28, 0x17, 0x3A, + 0x1F, 0xFC, 0x3B, 0x4C, 0xD5, 0xBF, 0x1B, 0x72, + 0x88, 0x5D, 0x22, 0x57, 0x7A, 0x47, 0x8A, 0x2C, + 0x19, 0x97, 0x80, 0x9A, 0x1C, 0x8A, 0x70, 0xA7, + 0xDA, 0xEB, 0xAE, 0x21, 0x81, 0x93, 0x63, 0xE9, + 0xDE, 0x12, 0xB2, 0xA6, 0xC3, 0x57, 0xD0, 0xD7, + + 0x04, 0xCD, 0xA5, 0x8D, 0x82, 0x25, 0xCC, 0xAE, + 0xDB, 0x8A, 0xBB, 0xCE, 0x96, 0x7D, 0x69, 0x62, + 0x5F, 0x34, 0x39, 0x4C, 0x82, 0xD3, 0xC6, 0x1E, + 0x27, 0x44, 0xDF, 0x66, 0xF0, 0x66, 0xF1, 0xA4, + 0x3E, 0xC8, 0x72, 0x58, 0x7C, 0x78, 0x50, 0x1B, + 0xAE, 0x6D, 0x22, 0x40, 0x27, 0x70, 0x6C, 0x12, + 0x1D, 0x44, 0x70, 0x1B, 0xC6, 0xD5, 0x76, 0x76, + 0xDD, 0xC4, 0x63, 0xE9, 0x17, 0xFF, 0xE4, 0x93, + 0x67, 0x24, 0xE0, 0x2C, 0x51, 0x3E, 0xCA, 0x62, + 0xC7, 0x0B, 0x47, 0x84, 0xDF, 0x98, 0x94, 0x85, + 0x40, 0xF0, 0xAA, 0xFC, 0x74, 0xCC, 0x15, 0x7E, + 0x9B, 0x14, 0x2D, 0x78, 0x38, 0x88, 0x12, 0x4D, + 0xB3, 0xE4, 0x64, 0xEB, 0x38, 0x3C, 0x0F, 0xC7, + 0x08, 0x26, 0x06, 0x9D, 0xD4, 0xCD, 0xCD, 0xCA, + 0x10, 0xA1, 0x9B, 0xCD, 0x03, 0x92, 0x75, 0x32, + 0xA5, 0x0F, 0xAA, 0xA4, 0xB0, 0xFE, 0x6B, 0xB3, + 0x47, 0xFD, 0x58, 0x9F, 0x69, 0x6D, 0xD5, 0x93, + 0xE7, 0x46, 0x92, 0xF5, 0x6B, 0xA7, 0x07, 0xBC, + 0x5E, 0xE1, 0x9D, 0x7D, 0xF6, 0xB5, 0x01, 0x64, + 0x6D, 0xDE, 0x24, 0x8F, 0xEF, 0x17, 0x4F, 0x74, + 0x3A, 0x13, 0x2B, 0x67, 0x05, 0x3C, 0x3B, 0xE2, + 0x17, 0x01, 0xD7, 0xAC, 0x2C, 0xD2, 0xEE, 0x89, + 0xE7, 0x50, 0xAB, 0x0B, 0x3A, 0x03, 0x6A, 0x05, + 0x2B, 0xAF, 0x7A, 0x71, 0x6D, 0x59, 0x13, 0x22, + 0xD4, 0x7F, 0xE0, 0xD4, 0xD5, 0xE6, 0x37, 0x4E, + 0x81, 0x04, 0xB1, 0x5C, 0xE4, 0x81, 0xE4, 0xE0, + 0x1D, 0x11, 0xF6, 0x3E, 0xE7, 0xB8, 0x7E, 0xDB, + 0xB3, 0x72, 0xE9, 0x63, 0x6B, 0xB7, 0xAA, 0x20, + 0x94, 0x14, 0x8E, 0x1C, 0x6D, 0xD3, 0xF4, 0xE6, + 0x3F, 0x14, 0xDD, 0x3F, 0xA3, 0x8A, 0x5B, 0xC3, + 0x0A, + + 0x10, 0x5A, 0xA3, 0x65, 0x9B, 0x9C, 0x5D, 0xBD, + 0x92, 0x5A, 0x84, 0x1B, 0x18, 0xA6, 0x4A, 0x43, + 0x69, 0xA2, 0xD2, 0x67, 0x8C, 0xC5, 0x90, 0xD6, + 0x33, 0xD7, 0xE5, 0x12, 0xEF, 0xCB, 0x68, 0x24, + 0xB9, 0x66, 0xF6, 0x69, 0xA5, 0x2D, 0x43, 0xDD, + 0xFC, 0x2C, 0x08, 0x3E, 0x71, 0xF3, 0x33, 0xF1, + 0xED, 0xBA, 0x0E, 0x8B, 0xE6, 0xF3, 0xA7, 0x90, + 0x61, 0xD9, 0x3B, 0xC6, 0xB6, 0x89, 0xEF, 0xE3, + 0x9C, 0x55, 0xCC, 0x92, 0xE0, 0xB7, 0xA8, 0xA2, + 0xBE, 0x6E, 0x3B, 0xF4, 0xC2, 0x47, 0x21, 0x0E, + 0x1B, 0xD8, 0x76, 0x19, 0x99, 0xCE, 0x97, 0x02, + 0x25, 0x37, 0x28, 0xC0, 0x8E, 0x13, 0x6E, 0xB7, + 0x1B, 0x6B, 0x7C, 0x40, 0x3E, 0x78, 0xD1, 0xD1, + 0x55, 0x84, 0xA7, 0x1E, 0x82, 0x5C, 0x5D, 0x8E, + 0x14, 0x2E, 0xF4, 0x5B, 0x76, 0xC7, 0xCB, 0x82, + 0x74, 0xB3, 0x6F, 0xF5, 0xFD, 0xDE, 0x74, 0xD5, + 0xBD, 0xFB, 0x37, 0xA9, 0x54, 0x90, 0x97, 0x08, + 0x5C, 0xA7, 0x13, 0x07, 0xC4, 0x8C, 0x0C, 0x51, + 0x5D, 0x22, 0x71, 0xFE, 0x25, 0x77, 0x13, 0x23, + 0x3C, 0x57, 0x04, 0xEC, 0xE5, 0xD4, 0x41, 0x4E, + 0xE7, 0xFA, 0x1B, 0x4A, 0x31, 0xE1, 0xC6, 0x35, + 0x99, 0x0D, 0x8B, 0xAC, 0x37, 0xAB, 0x38, 0x8C, + 0xEC, 0x59, 0x44, 0x8A, 0x5A, 0xD9, 0x7A, 0x99, + 0x95, 0x33, 0x7E, 0x65, 0xEF, 0x78, 0x63, 0xE2, + 0x6D, 0xFE, 0x7D, 0xAC, 0xA5, 0x05, 0x13, 0xB7, + 0x8E, 0xF2, 0x9B, 0x76, 0x7E, 0x6C, 0x54, 0x86, + 0xA2, 0xAA, 0x2F, 0x3B, 0x38, 0x46, 0x1D, 0x4E, + 0xDB, 0x36, 0x42, 0x88, 0x0D, 0x0C, 0x7B, 0xAF, + 0xAC, 0x58, 0x0B, 0x24, 0x99, 0xCB, 0x5E, 0x9D, + 0x6D, 0xDC, 0xE8, 0xE1, 0xDC, 0xD5, 0xC3, 0x31, + 0xBE, 0xD5, + + 0xB0, 0xD1, 0xFC, 0x60, 0x3A, 0x61, 0x99, 0x7C, + 0xDD, 0x25, 0x09, 0x27, 0x2F, 0x4F, 0xEA, 0x8D, + 0x71, 0x0C, 0xE3, 0x47, 0x8A, 0xBC, 0xB6, 0xBD, + 0x8B, 0x6E, 0xFC, 0x63, 0x4A, 0x49, 0x59, 0xA4, + 0x4D, 0x2C, 0x8B, 0xDB, 0x9C, 0xFA, 0x23, 0xAE, + 0xDF, 0xBA, 0x3A, 0x1A, 0x21, 0xED, 0x74, 0x3F, + 0x20, 0xC1, 0x66, 0xCF, 0xBB, 0x21, 0x96, 0x57, + 0xD4, 0x9A, 0xFF, 0xCD, 0xB6, 0x21, 0xE4, 0xA6, + 0xC1, 0x38, 0xDA, 0x54, 0x20, 0x9B, 0x21, 0xC9, + 0x22, 0x5D, 0x1E, 0xCD, 0x48, 0x8C, 0x85, 0xE2, + 0xCA, 0x4D, 0xE3, 0xE3, 0x82, 0x9F, 0x3A, 0xB9, + 0xC1, 0xB9, 0x01, 0x50, 0x1F, 0x13, 0xB0, 0xDF, + 0x12, 0x2D, 0x09, 0x85, 0xA2, 0xD7, 0x0D, 0x9D, + 0x01, 0x92, 0xC9, 0xEC, 0xE5, 0x50, 0x58, 0xF0, + 0xF8, 0x58, 0x7F, 0xD1, 0xCF, 0xFD, 0x77, 0xBD, + 0x73, 0x6B, 0x9B, 0x9D, 0x35, 0x25, 0x1D, 0x52, + 0x6B, 0xF0, 0x8E, 0x78, 0xF2, 0xCF, 0x52, 0x11, + 0x17, 0xF3, 0xB2, 0x20, 0x80, 0x22, 0x90, 0x7B, + 0xBD, 0x1B, 0x32, 0x1D, 0x17, 0xF8, 0xB0, 0xB0, + 0xBC, 0x82, 0xC1, 0x20, 0x8E, 0x79, 0x17, 0x18, + 0x6B, 0x8D, 0xD3, 0x57, 0xBE, 0xB6, 0xB0, 0x48, + 0x23, 0x5D, 0x70, 0x50, 0xA7, 0x2C, 0x55, 0xC4, + 0x39, 0x88, 0x5C, 0x7C, 0xA5, 0x74, 0x43, 0xA4, + 0x8E, 0x02, 0x4C, 0x8E, 0x7E, 0x05, 0x73, 0x6B, + 0x89, 0x44, 0xAA, 0x84, 0xF4, 0xD4, 0x0F, 0xB9, + 0xB1, 0x8B, 0x0D, 0xD5, 0x38, 0x32, 0xBD, 0x84, + 0x49, 0xB6, 0x3E, 0xD9, 0x65, 0xAB, 0x96, 0x2A, + 0x6A, 0x47, 0xD5, 0x0E, 0x21, 0x4F, 0xF7, 0xF9, + 0xE4, 0xE9, 0x46, 0xA1, 0x09, 0x7A, 0x7B, 0x0E, + 0x10, 0x3D, 0x3D, 0xE8, 0xB1, 0xBB, 0x07, 0x1A, + 0x54, 0xBA, 0xC2, + + 0x3C, 0xDD, 0x72, 0x30, 0xB1, 0xD2, 0x79, 0x40, + 0x8E, 0x03, 0x65, 0x7D, 0x82, 0x70, 0x77, 0xEB, + 0x77, 0x9B, 0x6C, 0x46, 0x20, 0x27, 0x40, 0xCF, + 0xAA, 0xF3, 0x2D, 0xBC, 0xF8, 0xE0, 0xA4, 0x04, + 0xAE, 0x72, 0xE7, 0x95, 0x38, 0xA2, 0xAA, 0x45, + 0x7F, 0xDB, 0x72, 0x58, 0x0C, 0x30, 0x70, 0x4E, + 0x8A, 0xE2, 0xDD, 0x2D, 0xA8, 0x03, 0x9A, 0xEB, + 0x99, 0x96, 0x8E, 0x9E, 0xC1, 0x65, 0x8C, 0xB9, + 0xD1, 0xE1, 0xED, 0xEC, 0x3C, 0x3F, 0xA8, 0xAB, + 0x54, 0x81, 0x2C, 0x16, 0x77, 0x3B, 0x6A, 0xB9, + 0x09, 0x51, 0xF0, 0x98, 0x38, 0xF3, 0x69, 0xC6, + 0x07, 0xB6, 0x98, 0x2C, 0x00, 0xDA, 0xFF, 0xD4, + 0x4B, 0x51, 0x00, 0xF4, 0xF4, 0xC6, 0x59, 0xFF, + 0x4D, 0x2F, 0xF0, 0x55, 0x91, 0x33, 0x58, 0xAC, + 0x0B, 0xA7, 0x43, 0x4B, 0x11, 0xDA, 0x6F, 0x3A, + 0x7A, 0xF1, 0xE5, 0xE4, 0x58, 0xB0, 0xA3, 0x5D, + 0x89, 0xDD, 0x6B, 0x84, 0x28, 0x04, 0x1E, 0x0B, + 0xD5, 0x3F, 0x5E, 0x87, 0x47, 0xE5, 0xCC, 0xCC, + 0xF8, 0x46, 0xD0, 0x41, 0xD4, 0x89, 0xC6, 0x31, + 0x4B, 0x9B, 0xF6, 0x64, 0xCB, 0xDE, 0x11, 0x36, + 0x7F, 0x1C, 0xC4, 0x4A, 0x10, 0xA0, 0xF0, 0xE2, + 0xA8, 0x9D, 0x80, 0x22, 0xAF, 0xFA, 0x1D, 0xCB, + 0x99, 0x08, 0x56, 0x12, 0x0C, 0xE8, 0x23, 0xF9, + 0x13, 0x68, 0x7C, 0x89, 0x5A, 0xAC, 0x00, 0x25, + 0x0A, 0xEF, 0xDD, 0xF1, 0xF4, 0xDC, 0xC1, 0x92, + 0x71, 0x12, 0xF2, 0xBF, 0x7F, 0xA9, 0x30, 0x5C, + 0x75, 0x43, 0x4F, 0x19, 0x7C, 0xD6, 0x39, 0xF2, + 0xDC, 0xAB, 0xE7, 0x36, 0x75, 0x26, 0x2C, 0xC5, + 0x4D, 0xBF, 0xD0, 0x4A, 0x20, 0x26, 0x50, 0x9A, + 0x31, 0x41, 0x29, 0xD0, 0x73, 0x53, 0x7A, 0x81, + 0xF4, 0x5D, 0xDB, 0x8E, + + 0x21, 0x55, 0x95, 0x56, 0x2A, 0xFA, 0x88, 0x2E, + 0xC9, 0x9B, 0x1E, 0xE9, 0xA4, 0x4C, 0x1A, 0xC7, + 0xFB, 0xF6, 0xA5, 0xE8, 0x5A, 0xFB, 0xF6, 0x53, + 0x4C, 0xCD, 0x0F, 0xE7, 0x0A, 0x97, 0x73, 0x95, + 0x7C, 0x0E, 0x11, 0x82, 0x07, 0x8F, 0x77, 0x2B, + 0xDE, 0x4D, 0x95, 0xDB, 0x27, 0x6D, 0x70, 0x89, + 0xC8, 0x5C, 0x1B, 0xC8, 0xEE, 0xEE, 0x8E, 0x75, + 0xDB, 0x1B, 0x5E, 0xF2, 0x1D, 0x6D, 0xD8, 0x8C, + 0x81, 0x3B, 0x58, 0x71, 0xBA, 0x12, 0x70, 0x12, + 0x6E, 0x8D, 0x13, 0x2E, 0x4B, 0x4A, 0x81, 0x93, + 0xA9, 0xAD, 0xA6, 0xB2, 0xB2, 0x4D, 0xE2, 0x26, + 0x2E, 0xC7, 0x31, 0xD1, 0xFB, 0x02, 0xAB, 0xE9, + 0x76, 0xBF, 0x84, 0xEF, 0xE2, 0x02, 0xDA, 0xDE, + 0x93, 0x08, 0x3F, 0x02, 0x37, 0x04, 0xC3, 0x37, + 0xB0, 0x5B, 0x7F, 0x04, 0x37, 0xC0, 0xA3, 0x67, + 0x3F, 0xFA, 0x31, 0x43, 0x10, 0x27, 0xA1, 0x36, + 0x3D, 0x56, 0xF9, 0x70, 0xDF, 0x6B, 0x51, 0x61, + 0x76, 0xD2, 0x22, 0xCC, 0x19, 0x66, 0x30, 0x63, + 0xBC, 0x25, 0x7A, 0x7E, 0x8B, 0x7B, 0x9D, 0xD7, + 0x49, 0x99, 0x67, 0x8C, 0x19, 0x2F, 0x51, 0x0F, + 0x01, 0xD7, 0x35, 0xF0, 0xA2, 0x20, 0x38, 0x03, + 0x9F, 0xCB, 0x42, 0x65, 0xC3, 0x6A, 0x0E, 0xA8, + 0xF6, 0x4F, 0xBF, 0x73, 0x3A, 0x1A, 0xDF, 0x48, + 0x03, 0x72, 0xF5, 0xB9, 0x94, 0x56, 0xD4, 0x46, + 0x93, 0xDD, 0x6B, 0xB3, 0xF9, 0x6B, 0xDF, 0xEC, + 0x88, 0x34, 0x6D, 0x39, 0x51, 0xEE, 0xFD, 0xA6, + 0x4B, 0xC7, 0x2B, 0xAE, 0xC6, 0x2A, 0x14, 0x15, + 0xDF, 0xB3, 0x7E, 0x02, 0x1C, 0x8D, 0xA8, 0xD4, + 0xDB, 0x19, 0xCF, 0x19, 0xEA, 0x8A, 0x14, 0xBC, + 0x67, 0xB1, 0x62, 0x35, 0x69, 0x84, 0x21, 0x08, + 0xF8, 0x5D, 0x44, 0x10, 0xD9, + + 0x0E, 0xE7, 0x88, 0x5B, 0x12, 0x67, 0xA8, 0x08, + 0x53, 0xD1, 0x65, 0x84, 0xE8, 0x9C, 0x12, 0xE3, + 0xBA, 0x44, 0x83, 0xA1, 0x1E, 0x73, 0xDE, 0x63, + 0x6C, 0xCC, 0xF7, 0xA4, 0x6B, 0xD0, 0x6B, 0xBF, + 0x3D, 0xAE, 0x4D, 0xF2, 0xB7, 0xF7, 0xC4, 0x30, + 0x2F, 0xB0, 0xEE, 0x09, 0x10, 0x20, 0xE1, 0x77, + 0x7B, 0xD4, 0xD1, 0x6B, 0x7F, 0x88, 0xA6, 0xE6, + 0x51, 0xD5, 0x4E, 0x9F, 0xFD, 0xFB, 0x1F, 0x4A, + 0x7C, 0xA7, 0x99, 0x32, 0x3F, 0x7C, 0xEA, 0xD9, + 0x36, 0xD4, 0x2C, 0xE1, 0xE0, 0x84, 0x2E, 0xFE, + 0x2A, 0x57, 0xA5, 0x56, 0xBD, 0xD3, 0x16, 0x8F, + 0x5A, 0x5A, 0x02, 0x20, 0xF1, 0x1B, 0xF0, 0x96, + 0x22, 0xBF, 0x1B, 0x24, 0xA4, 0xD2, 0x5A, 0x35, + 0x9E, 0xBA, 0x71, 0xB4, 0x5D, 0x13, 0x19, 0x8D, + 0x64, 0x4C, 0x5B, 0x22, 0xAA, 0x0E, 0x87, 0x1E, + 0xF6, 0x62, 0x8A, 0x94, 0xA6, 0x36, 0x03, 0xEA, + 0x6F, 0xB4, 0xFC, 0xA5, 0xC9, 0x98, 0x73, 0x54, + 0x38, 0x97, 0x6D, 0xC8, 0x08, 0x01, 0xCA, 0xD8, + 0x88, 0xE7, 0xAA, 0x9E, 0xCE, 0x3B, 0xA7, 0xBA, + 0x69, 0x50, 0xAB, 0x78, 0x9C, 0x83, 0x20, 0x23, + 0x31, 0x1C, 0xCC, 0x01, 0x52, 0xDF, 0x6F, 0xC2, + 0x56, 0x09, 0x57, 0xFF, 0xDE, 0x27, 0xD4, 0x17, + 0x4E, 0x6B, 0xD5, 0x60, 0x3A, 0x9F, 0xC8, 0xA4, + 0x1A, 0xAB, 0x82, 0x9A, 0x05, 0x15, 0xC8, 0x66, + 0x89, 0x40, 0x2A, 0x90, 0xF8, 0xEB, 0xD1, 0x2F, + 0x6E, 0x68, 0x13, 0xAD, 0x66, 0x39, 0x6C, 0xB1, + 0x7C, 0xEE, 0x33, 0xB7, 0xA6, 0x88, 0x69, 0xE1, + 0x32, 0x34, 0xA4, 0x87, 0xB1, 0x0C, 0xF3, 0x59, + 0xBE, 0x88, 0x72, 0x77, 0x76, 0x61, 0x45, 0x6F, + 0xF7, 0x75, 0x12, 0xB6, 0x03, 0x17, 0xE9, 0x2E, + 0x15, 0x93, 0xDA, 0xA9, 0xAE, 0x12, + + 0x4E, 0xB8, 0x67, 0xB1, 0x3C, 0x12, 0xCD, 0x1E, + 0x2D, 0xA3, 0x9C, 0xE5, 0xA6, 0x4A, 0x08, 0x0E, + 0x0D, 0x1C, 0x9B, 0xE7, 0xE5, 0x6D, 0x0A, 0x75, + 0xE0, 0xE4, 0x33, 0x3B, 0x43, 0x3D, 0x2C, 0x39, + 0x96, 0x43, 0x8F, 0xF6, 0xA4, 0xAA, 0x5E, 0x32, + 0xFE, 0x00, 0xCD, 0xD6, 0x9D, 0x75, 0x6F, 0x3A, + 0x20, 0x4E, 0x05, 0xB5, 0x7C, 0xE8, 0xDA, 0xE1, + 0x32, 0x10, 0xC0, 0x85, 0x8D, 0x34, 0x35, 0x12, + 0x41, 0x50, 0xBF, 0x58, 0xB8, 0xFF, 0x4E, 0x6B, + 0x04, 0x40, 0x76, 0xAD, 0xCC, 0x31, 0xDB, 0xF4, + 0x12, 0x7F, 0x30, 0x4E, 0x28, 0x28, 0x73, 0x67, + 0xED, 0x35, 0x38, 0x18, 0xD9, 0x9D, 0xEA, 0x68, + 0xFA, 0x65, 0x28, 0x7B, 0x99, 0x3A, 0x89, 0x7D, + 0x52, 0xE1, 0x59, 0x4C, 0x68, 0xC9, 0xDA, 0xFC, + 0x3D, 0x39, 0xE0, 0x81, 0xDB, 0x22, 0xBD, 0xBF, + 0xF3, 0xDA, 0x45, 0x1D, 0x3A, 0x8D, 0xF3, 0x97, + 0x9E, 0xDA, 0x2A, 0xD5, 0x4E, 0x2C, 0x23, 0x74, + 0x3A, 0xC9, 0x73, 0x4D, 0x24, 0x7E, 0x1A, 0x9B, + 0xF9, 0xD7, 0x21, 0x4D, 0x9A, 0x28, 0x21, 0x44, + 0xD4, 0xE8, 0x93, 0xC5, 0x4F, 0x9A, 0xF9, 0x66, + 0x09, 0xA5, 0x46, 0x31, 0x59, 0xB3, 0xCC, 0xF3, + 0xD4, 0x58, 0x9E, 0x8E, 0xB5, 0x35, 0x47, 0x5C, + 0x23, 0xC9, 0xFC, 0xE8, 0x64, 0x5D, 0x47, 0x6C, + 0x43, 0xAC, 0x47, 0x30, 0xAE, 0x40, 0x7A, 0x9E, + 0x1F, 0xF9, 0x74, 0x55, 0x10, 0x6F, 0x2A, 0xEB, + 0x50, 0x63, 0x51, 0xDD, 0x8E, 0x38, 0x6F, 0x27, + 0x1F, 0x21, 0x3C, 0xDC, 0x65, 0x63, 0xE4, 0xE8, + 0xD8, 0x63, 0x20, 0x67, 0x96, 0x22, 0xFD, 0xC3, + 0xA0, 0xDB, 0x90, 0x64, 0x56, 0xE6, 0xB0, 0xFE, + 0xB3, 0x7C, 0x74, 0x2C, 0x01, 0xD5, 0xCC, 0xD4, + 0x3C, 0x1B, 0xBA, 0x79, 0x68, 0x33, 0x7C, + + 0x3E, 0x82, 0xD7, 0x53, 0xF6, 0x16, 0xE3, 0x10, + 0x01, 0x36, 0xA8, 0xEF, 0x33, 0xCA, 0x26, 0xC9, + 0x21, 0xBF, 0xCA, 0x3B, 0x7D, 0x89, 0xC2, 0x59, + 0x1D, 0x57, 0x2B, 0x02, 0x05, 0xEA, 0x49, 0x99, + 0x31, 0x95, 0xFF, 0x0A, 0x45, 0x56, 0x1D, 0xB9, + 0xD3, 0x01, 0x44, 0xC4, 0x8C, 0x88, 0xAD, 0xC9, + 0x83, 0x6A, 0x35, 0x83, 0x81, 0xBC, 0x59, 0x0A, + 0xB0, 0x2A, 0x82, 0xE5, 0x89, 0x54, 0xA0, 0xAC, + 0x69, 0x1A, 0x63, 0x5B, 0x2C, 0x8A, 0x61, 0xAE, + 0x72, 0xD9, 0xDB, 0xF0, 0x6C, 0xAA, 0x8F, 0x61, + 0x46, 0x0C, 0x0A, 0x5D, 0xE6, 0x15, 0x92, 0x65, + 0x83, 0xCF, 0x80, 0xB6, 0x78, 0x9E, 0x87, 0x9B, + 0x13, 0xD5, 0x94, 0xD2, 0x1E, 0x7A, 0x28, 0x8B, + 0x14, 0x76, 0x0C, 0x7E, 0x41, 0xAE, 0x5B, 0x36, + 0x40, 0xD9, 0x30, 0x31, 0xFD, 0x73, 0x81, 0xCC, + 0x83, 0x22, 0x03, 0xFF, 0xB6, 0xCC, 0xFA, 0xD7, + 0x3A, 0x1C, 0xB4, 0xA8, 0x48, 0x47, 0xD9, 0xA9, + 0x54, 0xCE, 0x26, 0x92, 0x84, 0x19, 0x6D, 0x57, + 0x1B, 0x24, 0x3B, 0x5F, 0xBD, 0xBB, 0x7F, 0x18, + 0x97, 0xE2, 0x79, 0x81, 0x7B, 0x19, 0xB6, 0x9C, + 0x4F, 0xE6, 0xD5, 0x01, 0x8B, 0x41, 0xE5, 0x21, + 0x18, 0x76, 0x2A, 0x16, 0xC2, 0xEF, 0x20, 0xAC, + 0xB0, 0x0E, 0x58, 0x8C, 0x6D, 0xE7, 0x02, 0x35, + 0x15, 0x94, 0xDB, 0xC6, 0x58, 0xE3, 0xF0, 0x0F, + 0xBF, 0x6A, 0x63, 0xE0, 0x4A, 0x51, 0x32, 0x90, + 0x40, 0x84, 0xB6, 0x05, 0x92, 0xB1, 0x6B, 0xF8, + 0xCD, 0xCD, 0x7F, 0xF1, 0x43, 0x72, 0xBB, 0x8B, + 0x1E, 0xAF, 0xE5, 0x78, 0x75, 0x72, 0xE5, 0x72, + 0x14, 0x2D, 0x5B, 0x83, 0xD2, 0x40, 0x55, 0xFC, + 0x8C, 0x9B, 0xFB, 0xAE, 0xCC, 0x51, 0xBE, 0x56, + 0x9D, 0x4C, 0xC1, 0xFC, 0xF1, 0xC3, 0xC3, 0xAD, + + 0xA9, 0x2F, 0xB7, 0xB1, 0x24, 0x2E, 0xD1, 0x6E, + 0xAF, 0x5B, 0xC5, 0xF2, 0xF8, 0x5E, 0x43, 0x83, + 0xB4, 0x3D, 0x57, 0xD6, 0x16, 0x8D, 0x56, 0x31, + 0xE5, 0xEB, 0x44, 0x01, 0x9F, 0xCA, 0x6E, 0x77, + 0xC2, 0xAC, 0xAD, 0x84, 0x1E, 0x4B, 0x38, 0xCC, + 0x48, 0x36, 0xD6, 0x8E, 0xCA, 0xAD, 0x67, 0x3E, + 0x20, 0xD2, 0x3A, 0x84, 0xA2, 0x79, 0x60, 0xBD, + 0xA2, 0x1B, 0x7E, 0x41, 0x57, 0x2D, 0x52, 0x41, + 0x41, 0x1C, 0x32, 0x5F, 0xE4, 0x1B, 0x21, 0x55, + 0xA9, 0xAE, 0xFE, 0xB1, 0x80, 0xB2, 0x85, 0x0E, + 0x5A, 0xA8, 0x06, 0x4C, 0x73, 0x96, 0xC7, 0xDF, + 0x39, 0x6D, 0x5A, 0x69, 0x7F, 0x3C, 0xC1, 0x71, + 0xEF, 0xEC, 0x84, 0x23, 0x5F, 0x92, 0xD9, 0x07, + 0x2D, 0x73, 0x4A, 0xAB, 0x55, 0x46, 0xE8, 0xCC, + 0x46, 0x2C, 0x09, 0x7B, 0x65, 0xD7, 0xCF, 0x1A, + 0x3B, 0x27, 0xD3, 0x8C, 0x3B, 0x8A, 0xDC, 0xDB, + 0x36, 0x95, 0x06, 0x8D, 0x5B, 0x44, 0xBA, 0xBF, + 0x7E, 0x50, 0xAF, 0xC3, 0x63, 0x66, 0xB9, 0xD3, + 0xB0, 0xC4, 0x2C, 0x03, 0xBF, 0x7E, 0x70, 0xCF, + 0x93, 0xEB, 0x3D, 0xDC, 0x74, 0x16, 0x49, 0x0A, + 0x02, 0x98, 0x4F, 0x81, 0x6C, 0x29, 0x53, 0x39, + 0x25, 0xBA, 0xD4, 0x59, 0xF2, 0xB9, 0x92, 0xE6, + 0x83, 0x41, 0xE2, 0x7B, 0xE1, 0x6E, 0xA0, 0x8F, + 0xC4, 0xE8, 0x35, 0x76, 0x5A, 0x3A, 0xA4, 0x35, + 0x83, 0x85, 0x77, 0xA9, 0x63, 0x00, 0xA1, 0x29, + 0xD5, 0x43, 0x05, 0x59, 0xA3, 0x52, 0x3E, 0xE4, + 0xDA, 0xC1, 0x72, 0x36, 0x8F, 0x5E, 0xA0, 0x8B, + 0x88, 0x3D, 0xE9, 0x19, 0x11, 0x89, 0x3F, 0x0E, + 0xF1, 0x04, 0xA9, 0x4C, 0x87, 0xFF, 0x08, 0x89, + 0xF9, 0x13, 0xEB, 0xE7, 0x28, 0x41, 0x0B, 0x58, + 0xA4, 0xA9, 0x19, 0xC7, 0x4F, 0x34, 0xFD, 0x54, + 0x0A, + + 0x79, 0x14, 0x36, 0xA5, 0x6B, 0x3F, 0x22, 0xFA, + 0x12, 0x4B, 0x4F, 0xC4, 0x97, 0xD7, 0xC7, 0x61, + 0x94, 0x53, 0x53, 0xD3, 0xF5, 0x07, 0x64, 0x7D, + 0xE0, 0x11, 0x63, 0xC5, 0xE7, 0x4A, 0x88, 0xEC, + 0x6C, 0x0D, 0xA5, 0x05, 0x13, 0xE4, 0xC6, 0x94, + 0x3D, 0xEE, 0x87, 0xB1, 0x77, 0xCE, 0xB6, 0x7E, + 0xC9, 0x99, 0xB5, 0xAA, 0xB2, 0xC8, 0x0F, 0x5F, + 0xE9, 0x92, 0x9F, 0x1E, 0x49, 0x6D, 0xC8, 0xD7, + 0x6D, 0x1E, 0xD7, 0x63, 0x6D, 0xDD, 0x64, 0xCB, + 0xFF, 0x45, 0xB0, 0xF6, 0x89, 0xC5, 0xF3, 0xFB, + 0x82, 0xB9, 0x5B, 0xF1, 0x42, 0x4A, 0x8C, 0x9E, + 0xCD, 0x9D, 0xEF, 0x9D, 0x36, 0x79, 0x04, 0x7D, + 0x16, 0x6D, 0xC6, 0x66, 0xAA, 0xFE, 0x1D, 0xAB, + 0x4D, 0xDF, 0xF8, 0xE8, 0xC3, 0x12, 0xB3, 0xAD, + 0x49, 0xD1, 0x85, 0x7D, 0x2C, 0x76, 0xD9, 0x66, + 0x85, 0xA0, 0x81, 0x29, 0x2B, 0x13, 0x47, 0x1E, + 0x98, 0x77, 0x79, 0x3F, 0x23, 0xD2, 0xFC, 0xA5, + 0xA5, 0x64, 0xDF, 0xBB, 0x3E, 0xA8, 0x85, 0x98, + 0xB1, 0x34, 0x2B, 0xB7, 0xA0, 0xD1, 0x7A, 0x47, + 0x42, 0xFE, 0x98, 0x80, 0xBB, 0x21, 0x19, 0x4F, + 0xE0, 0x58, 0x2D, 0xD9, 0xE2, 0x0F, 0x46, 0x13, + 0xC7, 0x4A, 0x11, 0xDD, 0x49, 0xEC, 0x32, 0x0C, + 0x1C, 0x3C, 0x96, 0x75, 0x3C, 0xB4, 0x73, 0x07, + 0x3E, 0xBC, 0xA4, 0xB8, 0x17, 0x05, 0x38, 0x92, + 0x6B, 0x56, 0xF3, 0x28, 0xE3, 0x71, 0x73, 0x2A, + 0x30, 0x4C, 0xF5, 0xCF, 0x2A, 0xC5, 0x1B, 0x24, + 0x4E, 0xA0, 0x2C, 0x9A, 0xCA, 0x98, 0x8C, 0xCA, + 0x16, 0xD3, 0xA6, 0x77, 0xC7, 0x83, 0x3C, 0x25, + 0x96, 0x0D, 0x15, 0xBE, 0x33, 0x7E, 0xCA, 0x3A, + 0xC0, 0x37, 0x7C, 0x91, 0x04, 0xF0, 0x4D, 0x8D, + 0xAE, 0xBF, 0x6B, 0x99, 0x57, 0x63, 0x90, 0x10, + 0x41, 0xF1, + + 0x83, 0xD6, 0xF5, 0x41, 0x9F, 0x3B, 0x2C, 0x9B, + 0xAB, 0xAF, 0x1B, 0xAE, 0x69, 0xB4, 0xAA, 0x5B, + 0xF9, 0x5F, 0x0F, 0xC7, 0xD4, 0x7F, 0x90, 0xAF, + 0xB2, 0xBA, 0xAB, 0x86, 0x92, 0x8E, 0x66, 0x46, + 0xD5, 0x73, 0x08, 0xB7, 0x3E, 0x46, 0x86, 0xC0, + 0x1C, 0x72, 0xB1, 0xDF, 0x7A, 0x3A, 0xC4, 0xEF, + 0x85, 0x36, 0x21, 0x3C, 0x29, 0xB9, 0x68, 0xFD, + 0x48, 0xBD, 0x1A, 0x5C, 0x83, 0xA3, 0x02, 0xFD, + 0x67, 0xBF, 0xC3, 0xD1, 0x68, 0xE1, 0xB8, 0x91, + 0x57, 0xA5, 0x7B, 0xE8, 0x4B, 0x82, 0x7C, 0x76, + 0xEB, 0x1C, 0x38, 0x4C, 0x1E, 0x54, 0xE8, 0x66, + 0x47, 0x47, 0x8A, 0x41, 0xD7, 0x38, 0xCC, 0x8E, + 0xD8, 0x58, 0x20, 0x26, 0x79, 0x7B, 0x5A, 0xCF, + 0xD0, 0x0E, 0x6C, 0xE4, 0x91, 0x01, 0xE4, 0x95, + 0xF8, 0x6D, 0x7F, 0xFD, 0x38, 0x04, 0x41, 0x23, + 0x72, 0xC7, 0x32, 0xD9, 0x65, 0x4F, 0xCF, 0x3D, + 0xE8, 0xA3, 0xA7, 0x9C, 0xEF, 0x05, 0xDE, 0x12, + 0x70, 0x96, 0x04, 0x2C, 0x75, 0x06, 0xBE, 0xEC, + 0xA0, 0x37, 0x43, 0xF7, 0x39, 0x7E, 0x90, 0x39, + 0xAB, 0xFF, 0x97, 0x27, 0x05, 0xBC, 0x9D, 0xB9, + 0xDB, 0x8C, 0xFB, 0x10, 0x55, 0xC1, 0x63, 0xAA, + 0x59, 0xD3, 0x09, 0xC7, 0x49, 0xDB, 0x18, 0x2B, + 0x4A, 0xAE, 0x2B, 0x0E, 0xE0, 0x45, 0x3E, 0x96, + 0xF8, 0x82, 0x0F, 0xC4, 0xB7, 0x17, 0x3A, 0x0B, + 0x1D, 0x43, 0x81, 0x33, 0xA5, 0xDD, 0x26, 0x12, + 0xBF, 0xD9, 0x56, 0x13, 0xD8, 0xBB, 0xBE, 0xA8, + 0xAE, 0xCE, 0xF0, 0x99, 0x95, 0x66, 0xA0, 0xB5, + 0xD1, 0x94, 0xA3, 0xF8, 0x42, 0x3F, 0x3B, 0x0F, + 0x56, 0x9A, 0xBF, 0xAE, 0xEE, 0xC1, 0xA8, 0x25, + 0xFA, 0xF5, 0x0D, 0xAE, 0x4F, 0x40, 0x2B, 0xB2, + 0xEF, 0xB1, 0x61, 0xCF, 0x41, 0x6D, 0x96, 0x4D, + 0x8E, 0x0B, 0xFE, + + 0x24, 0xE7, 0xE5, 0x6C, 0xA2, 0x9D, 0xFB, 0xD1, + 0x90, 0xAA, 0xF0, 0xE7, 0xA6, 0x08, 0x5C, 0x80, + 0x69, 0xEE, 0x83, 0xE9, 0x8B, 0x70, 0x0B, 0x97, + 0xFB, 0xF0, 0xE5, 0x43, 0x81, 0x6D, 0xDC, 0xE9, + 0x4C, 0x14, 0xFA, 0xEA, 0x1F, 0x39, 0x31, 0x2A, + 0x60, 0x87, 0x10, 0x95, 0x19, 0x3A, 0x97, 0x09, + 0xF6, 0x7A, 0xDF, 0xF1, 0xAE, 0xB5, 0x43, 0x0D, + 0x6C, 0x1E, 0x2C, 0xC9, 0x2A, 0xF3, 0x76, 0xDA, + 0x6A, 0xEB, 0xE4, 0x92, 0x74, 0x82, 0xF1, 0x4C, + 0x64, 0x28, 0x01, 0xB0, 0xE1, 0xDF, 0x9A, 0x6B, + 0x89, 0x02, 0xE0, 0x43, 0xC6, 0x77, 0x18, 0xE8, + 0xC4, 0xC9, 0x98, 0xF2, 0x8F, 0xE0, 0xB4, 0x38, + 0x50, 0x81, 0xC7, 0xF4, 0x3F, 0xE2, 0xD9, 0xCB, + 0x5E, 0xE9, 0x5B, 0xC5, 0x98, 0xD2, 0xEB, 0xC6, + 0x13, 0x3E, 0xC1, 0x13, 0xFD, 0x54, 0x48, 0xA0, + 0x09, 0x64, 0x71, 0xE5, 0xCA, 0xC0, 0x75, 0x2D, + 0xF7, 0x89, 0x5B, 0x00, 0x05, 0xE1, 0x4B, 0xA8, + 0xDA, 0x12, 0x6A, 0x4E, 0xCE, 0xAB, 0x3A, 0xDF, + 0x4A, 0x90, 0xF4, 0xCA, 0x6C, 0x40, 0x00, 0xF9, + 0x9F, 0x92, 0xF7, 0x94, 0x53, 0x77, 0x55, 0x7F, + 0xA8, 0xA5, 0xBC, 0xC2, 0xC2, 0x45, 0xBB, 0x07, + 0x13, 0x4D, 0x9E, 0x0D, 0xCF, 0x49, 0xF1, 0x5A, + 0x69, 0xDF, 0x2D, 0x53, 0x54, 0xB7, 0x7A, 0xD4, + 0x2F, 0x1B, 0x99, 0x78, 0x84, 0x81, 0x04, 0xC4, + 0x5C, 0x26, 0x35, 0x01, 0xED, 0x75, 0xBC, 0x54, + 0x71, 0xA3, 0x96, 0x9E, 0xD4, 0x41, 0xCB, 0x05, + 0xB3, 0x08, 0x98, 0xAD, 0x93, 0x15, 0xF7, 0xC2, + 0xF4, 0xCB, 0xE6, 0xB7, 0xEB, 0x3F, 0xF7, 0x62, + 0x45, 0x40, 0xE3, 0x97, 0x58, 0xC4, 0x49, 0xED, + 0xBA, 0x92, 0xA3, 0x94, 0x1F, 0xCD, 0x66, 0x9C, + 0xA6, 0x85, 0x1F, 0xBF, 0xA1, 0xAA, 0x03, 0x1B, + 0xB2, 0x70, 0x9D, 0xE3, + + 0x0B, 0x45, 0xA1, 0x98, 0x47, 0xD8, 0xB2, 0x5D, + 0x41, 0xA7, 0x35, 0xE4, 0x41, 0x4B, 0x45, 0x6A, + 0x9A, 0x91, 0xA5, 0x66, 0xDA, 0x63, 0xE7, 0xB8, + 0x4E, 0x88, 0x0A, 0x80, 0x2E, 0xEC, 0x08, 0x74, + 0x8E, 0xEB, 0xDA, 0xC4, 0x6D, 0xB5, 0xDA, 0x27, + 0xEC, 0x67, 0xAC, 0x7D, 0x63, 0x7A, 0xF4, 0x9B, + 0xB6, 0x43, 0xE5, 0x87, 0xA7, 0x52, 0x34, 0xFD, + 0x15, 0x99, 0xC7, 0x13, 0x3E, 0xC6, 0x4F, 0x38, + 0xA3, 0x8B, 0xD1, 0xB4, 0x5E, 0x0E, 0xC0, 0xA8, + 0x9B, 0x34, 0x47, 0xC3, 0x61, 0x82, 0x0D, 0xBF, + 0x78, 0x2F, 0x90, 0x7B, 0x07, 0x5A, 0x2B, 0xA2, + 0xB6, 0x9D, 0xB0, 0x15, 0x0A, 0x32, 0xA1, 0x70, + 0x4E, 0x8D, 0x98, 0xC4, 0xB7, 0xE0, 0xD0, 0xBE, + 0x1D, 0xB4, 0xA3, 0xC9, 0x6A, 0xA4, 0xE6, 0x4F, + 0x12, 0xC2, 0x35, 0xD7, 0xA6, 0x69, 0x67, 0x18, + 0x2C, 0xB0, 0xCF, 0x39, 0x78, 0xDB, 0xB7, 0x66, + 0x50, 0xFD, 0xB7, 0x3F, 0x77, 0x7F, 0x4E, 0x3C, + 0xF8, 0xBD, 0xC5, 0xD2, 0xCA, 0xCB, 0xCB, 0x10, + 0x94, 0x9F, 0x3E, 0xA0, 0x5B, 0xBA, 0x74, 0xB9, + 0x84, 0xFE, 0xB1, 0x91, 0x93, 0x5D, 0x8B, 0x23, + 0x86, 0x8F, 0xCB, 0xF0, 0x0E, 0x27, 0xA8, 0x6A, + 0x57, 0xF3, 0x7A, 0xEE, 0x94, 0x5F, 0x29, 0x3F, + 0xF8, 0xD3, 0xD1, 0x30, 0xCD, 0x8B, 0x31, 0xFC, + 0x6E, 0xC6, 0x31, 0xB7, 0x76, 0x26, 0x12, 0x7A, + 0xB9, 0xB0, 0x29, 0x4D, 0xAF, 0x10, 0xFC, 0xCC, + 0xD1, 0xD6, 0x9C, 0x19, 0x81, 0x15, 0xC4, 0x19, + 0xDD, 0x5D, 0x56, 0x65, 0x6C, 0xE0, 0x39, 0x25, + 0x5C, 0xE5, 0xE2, 0x6E, 0x5D, 0x48, 0x44, 0xF8, + 0x53, 0x4A, 0x36, 0x48, 0xDB, 0x0D, 0x89, 0xF7, + 0x1B, 0xF5, 0xD0, 0x8E, 0xA2, 0xD8, 0xD7, 0x9E, + 0xCE, 0x35, 0xA0, 0x10, 0xE5, 0xBC, 0x22, 0xF9, + 0xC3, 0x35, 0xEC, 0x35, 0x6C, + + 0x59, 0x77, 0x61, 0xB9, 0xD2, 0xA0, 0x7C, 0xD6, + 0x95, 0x93, 0x17, 0x1B, 0x25, 0x09, 0x47, 0xF1, + 0x1B, 0x73, 0x28, 0xA8, 0xA1, 0xF6, 0x0F, 0x7F, + 0x4B, 0x86, 0xED, 0xC5, 0xBD, 0x15, 0x92, 0x75, + 0x23, 0x3E, 0x38, 0x30, 0xE0, 0x64, 0x80, 0x7B, + 0x10, 0xD5, 0x54, 0x08, 0x6E, 0x3D, 0x78, 0xFE, + 0x40, 0x0C, 0xFD, 0x86, 0xC1, 0xD1, 0xD4, 0xE7, + 0xF0, 0xD2, 0xFF, 0x52, 0xA4, 0x8F, 0xA8, 0x0A, + 0x9C, 0x6E, 0x49, 0x70, 0xC6, 0x7D, 0x7C, 0xDD, + 0xCE, 0x75, 0x09, 0xE3, 0xBF, 0x5A, 0x4A, 0x30, + 0xFD, 0xC0, 0x2B, 0x8F, 0x23, 0x39, 0x6B, 0x41, + 0x17, 0x51, 0x1F, 0x16, 0xAC, 0x33, 0x69, 0x42, + 0xD2, 0xE2, 0x32, 0x91, 0x81, 0xCB, 0x7C, 0x04, + 0xC8, 0xD9, 0x77, 0x1A, 0x59, 0xC7, 0x37, 0x5C, + 0x5B, 0xC3, 0x9F, 0x22, 0xE5, 0xDA, 0xD8, 0x59, + 0x3C, 0x01, 0xE6, 0xCC, 0x46, 0x5C, 0x90, 0xE0, + 0x3F, 0x4D, 0x77, 0xAD, 0x96, 0x2A, 0x5D, 0x37, + 0x0F, 0x59, 0x10, 0xF0, 0x23, 0xF0, 0xA9, 0x75, + 0xED, 0xDE, 0xFB, 0x74, 0x06, 0x2B, 0xBF, 0x20, + 0xED, 0xEA, 0xCD, 0x49, 0x8A, 0x41, 0x09, 0x6C, + 0x0F, 0x0E, 0x79, 0xF7, 0x61, 0x18, 0xBF, 0x77, + 0x09, 0xB9, 0x05, 0xEF, 0x89, 0xEE, 0x79, 0xD9, + 0x20, 0xAF, 0xE3, 0x3F, 0x0E, 0xCE, 0x3E, 0x94, + 0x0C, 0x3B, 0xC1, 0xA0, 0x88, 0xA8, 0x8D, 0xDB, + 0x4D, 0x70, 0xC6, 0x19, 0x2A, 0xCE, 0xE1, 0x9D, + 0x9E, 0x60, 0xBD, 0x93, 0x2D, 0xF1, 0xC6, 0x50, + 0x1B, 0xA7, 0x21, 0x7B, 0x11, 0x86, 0xCD, 0xF9, + 0x17, 0xAE, 0x4B, 0x88, 0x7B, 0xAF, 0xD1, 0xCA, + 0x80, 0xF7, 0xA1, 0x7F, 0x0A, 0x4D, 0xF8, 0x35, + 0x6E, 0xB1, 0x61, 0xEC, 0xAB, 0xD7, 0x60, 0x2D, + 0xB8, 0xB7, 0x59, 0x77, 0x90, 0xED, 0xC5, 0x24, + 0xCA, 0x02, 0xF2, 0x35, 0xD8, 0xB4, + + 0xE5, 0x07, 0x55, 0x53, 0x6C, 0x5E, 0xD2, 0x9F, + 0xE4, 0x23, 0xA5, 0x58, 0x45, 0x18, 0x2B, 0x0B, + 0x17, 0x00, 0xE8, 0xD7, 0x89, 0x06, 0xE6, 0x75, + 0x56, 0x25, 0xC0, 0x92, 0x79, 0xCD, 0xA2, 0xC0, + 0xBD, 0x8E, 0x52, 0x0D, 0xF3, 0xA2, 0xA1, 0x66, + 0x0F, 0x94, 0x23, 0xE7, 0x2D, 0x14, 0xB6, 0x82, + 0xB0, 0x9A, 0xE1, 0xE8, 0xF3, 0x15, 0x92, 0xFB, + 0xDE, 0x8D, 0xA2, 0x1A, 0xB3, 0xB2, 0xF7, 0xC0, + 0xAB, 0xA9, 0x79, 0x70, 0xBE, 0xE8, 0x14, 0x65, + 0x79, 0x10, 0x1C, 0x7C, 0x29, 0x2C, 0x16, 0x33, + 0xBB, 0xEF, 0x91, 0x5A, 0xC0, 0xA5, 0x7D, 0x97, + 0x79, 0x42, 0xB9, 0xA3, 0x7E, 0x9E, 0x87, 0xBB, + 0xDC, 0x65, 0x12, 0xDC, 0xD9, 0x2D, 0x73, 0x8A, + 0x73, 0x38, 0xF1, 0xA5, 0x60, 0x7E, 0xD1, 0xF3, + 0x97, 0xAB, 0xCF, 0xFF, 0x5C, 0x5E, 0xE1, 0xAC, + 0x1A, 0x41, 0xC2, 0x6D, 0xB1, 0x24, 0xAF, 0x19, + 0x55, 0x61, 0x4D, 0xDA, 0xD4, 0xE7, 0x10, 0x78, + 0x14, 0x2B, 0xA4, 0x88, 0x9D, 0x2F, 0x96, 0xF8, + 0x03, 0xF6, 0xB5, 0x13, 0x2B, 0xEA, 0x52, 0x24, + 0xB2, 0xA1, 0x46, 0xEC, 0x57, 0x59, 0x19, 0x17, + 0x83, 0x05, 0x20, 0x44, 0x4C, 0xEC, 0xC7, 0xE0, + 0xB1, 0x84, 0x00, 0x62, 0xE5, 0xE5, 0xAA, 0x0B, + 0xE6, 0x0E, 0x44, 0x5D, 0x55, 0x1D, 0x15, 0xDC, + 0xCE, 0x53, 0x2C, 0xF9, 0x7B, 0xDE, 0x95, 0x05, + 0xAF, 0x88, 0x59, 0xF1, 0xC2, 0x59, 0x3A, 0xFC, + 0x2E, 0x43, 0x37, 0x2F, 0xB8, 0x83, 0xD5, 0x42, + 0xE3, 0xA2, 0xFC, 0xA1, 0x62, 0xC6, 0x99, 0x9C, + 0x4C, 0x7A, 0x72, 0xD6, 0xF5, 0xF8, 0x3E, 0xE1, + 0xD0, 0x21, 0xE1, 0x74, 0x69, 0xB4, 0xE5, 0xB5, + 0x26, 0x2C, 0x37, 0x73, 0x90, 0xD3, 0x1D, 0x5B, + 0x08, 0xF4, 0x64, 0xE4, 0x9F, 0xA1, 0x95, 0xAE, + 0xCA, 0xB5, 0x6A, 0xD4, 0x50, 0x12, 0xDC, + + 0xED, 0xE8, 0x53, 0x43, 0xCA, 0x1B, 0xB7, 0x40, + 0x82, 0x4A, 0x01, 0x55, 0xD6, 0x0F, 0x9F, 0xFE, + 0x2F, 0x1B, 0x94, 0x9F, 0x49, 0xFA, 0x86, 0x45, + 0x3C, 0x63, 0x14, 0x2E, 0xAF, 0x66, 0x78, 0x97, + 0xA3, 0x40, 0x11, 0x32, 0x52, 0x3F, 0x22, 0x26, + 0xCA, 0xCC, 0x61, 0x3F, 0x31, 0x5E, 0x67, 0x5D, + 0x71, 0x7D, 0x5F, 0x69, 0xBF, 0xDC, 0x93, 0x1E, + 0xA8, 0x5F, 0xA2, 0x56, 0x91, 0xEC, 0xCE, 0x61, + 0x67, 0xF3, 0xDC, 0xE8, 0xF4, 0xF7, 0x46, 0xE9, + 0xE3, 0xB8, 0x21, 0x2A, 0x6E, 0xB9, 0xDD, 0x69, + 0x14, 0xFF, 0x1C, 0xC1, 0xF4, 0x27, 0x6B, 0x6E, + 0x2D, 0xC0, 0x75, 0x56, 0xF9, 0x75, 0x21, 0x3D, + 0x39, 0xE0, 0x67, 0x3C, 0xCC, 0x4D, 0x95, 0xDD, + 0xFE, 0x99, 0x1C, 0x77, 0xA6, 0xF2, 0x62, 0x23, + 0x79, 0x49, 0xAB, 0x65, 0x34, 0x2F, 0x71, 0x6F, + 0xCD, 0xA3, 0xBF, 0xF3, 0xAE, 0x08, 0xF8, 0xF3, + 0x18, 0x67, 0x51, 0x33, 0xD7, 0x3B, 0xF1, 0xD0, + 0x37, 0xA9, 0x07, 0x52, 0x77, 0xF0, 0x75, 0x0C, + 0xC6, 0x4A, 0xDC, 0x6B, 0x4C, 0xBF, 0x80, 0xEC, + 0x42, 0x89, 0x19, 0x22, 0xE1, 0x90, 0x2F, 0xC9, + 0x5E, 0x5D, 0xC8, 0xCF, 0xD3, 0x9F, 0x37, 0xAF, + 0x60, 0xAE, 0x34, 0x5F, 0xD8, 0x3F, 0xA9, 0x55, + 0x0E, 0x5C, 0xC9, 0xA8, 0xA2, 0x0E, 0xE3, 0xC2, + 0xAC, 0x9E, 0x87, 0x38, 0xBB, 0x53, 0x86, 0x82, + 0xDF, 0x05, 0xE4, 0x23, 0xF3, 0x77, 0xDA, 0x7A, + 0x1E, 0x9C, 0x88, 0x53, 0xB9, 0x14, 0x56, 0x49, + 0x2F, 0x6A, 0xE8, 0x3A, 0xF1, 0x5C, 0x72, 0xAF, + 0x2A, 0x19, 0x0A, 0xBB, 0x2B, 0xFD, 0x91, 0x59, + 0x43, 0x12, 0x9C, 0xC3, 0x0B, 0x7A, 0x7F, 0x85, + 0x1C, 0x98, 0x34, 0xF6, 0xDE, 0x59, 0x3F, 0x7C, + 0x49, 0x37, 0x75, 0x6B, 0xC1, 0xE1, 0xD7, 0x70, + 0xB9, 0xFB, 0xCA, 0xD8, 0x41, 0x6B, 0x8C, 0x01, + + 0xB9, 0xC3, 0x0F, 0x35, 0xEB, 0x2F, 0x12, 0x4E, + 0xE4, 0x78, 0x2D, 0x24, 0x77, 0xA4, 0x89, 0x1F, + 0x64, 0xAD, 0xE7, 0x2B, 0x49, 0xE0, 0xDC, 0x05, + 0x7D, 0x6C, 0xEC, 0x4E, 0x9E, 0xAE, 0x2E, 0xDF, + 0xE6, 0xF2, 0x3F, 0xC6, 0xD5, 0xAA, 0xFC, 0x23, + 0xAB, 0xCB, 0x96, 0x49, 0xC4, 0xEB, 0xAF, 0x18, + 0x14, 0x27, 0xFB, 0xE7, 0x1C, 0x34, 0xF7, 0x22, + 0x69, 0xA3, 0xD2, 0xFD, 0x9E, 0x9F, 0x29, 0xA9, + 0x50, 0x34, 0x3C, 0x4F, 0xDD, 0xE5, 0xAB, 0xE6, + 0xAC, 0x99, 0x80, 0x50, 0x7A, 0x4F, 0x79, 0xD2, + 0xC2, 0xC6, 0x31, 0x8F, 0xF6, 0xD6, 0xAA, 0x57, + 0x00, 0xA2, 0x4B, 0x61, 0xBA, 0xD6, 0x28, 0xD3, + 0xFA, 0x93, 0xE4, 0x65, 0x53, 0x81, 0xD3, 0x01, + 0xF1, 0xDA, 0x7A, 0x12, 0x85, 0x17, 0x5A, 0x7E, + 0x35, 0x21, 0x6C, 0xF0, 0x18, 0x34, 0xA4, 0xF4, + 0xDD, 0x24, 0xEB, 0x86, 0xDC, 0xD0, 0xF7, 0xAB, + 0x41, 0xB5, 0x59, 0x3F, 0x22, 0x7B, 0xCF, 0xDB, + 0x61, 0x4D, 0x61, 0x58, 0x55, 0xA5, 0x23, 0xCE, + 0x69, 0x2D, 0x5C, 0x24, 0x73, 0xA2, 0x80, 0x3F, + 0x67, 0xB7, 0x66, 0xD8, 0x30, 0x87, 0xFE, 0x74, + 0x23, 0x35, 0xFD, 0xD8, 0xA7, 0xD4, 0xAC, 0x02, + 0x40, 0xF6, 0xCA, 0x9B, 0xB3, 0xB4, 0x73, 0xEA, + 0x67, 0x39, 0xB4, 0x1B, 0xB4, 0x45, 0xFB, 0xB2, + 0xF9, 0xDB, 0x8E, 0x90, 0x29, 0x62, 0x9D, 0x9D, + 0x73, 0x30, 0x6C, 0x51, 0x56, 0xA6, 0x9B, 0x9A, + 0xE9, 0x33, 0xCA, 0xC8, 0xED, 0xE4, 0x58, 0x91, + 0x82, 0x17, 0x10, 0x0F, 0x2D, 0xF7, 0x82, 0xCD, + 0x25, 0x61, 0x45, 0xCD, 0xDD, 0x66, 0xF1, 0x8A, + 0xDC, 0x08, 0xF8, 0x53, 0xF6, 0x07, 0x8E, 0x3A, + 0x6F, 0x0B, 0xF0, 0x9D, 0x8F, 0xFE, 0xDD, 0xCF, + 0x94, 0xDD, 0xB2, 0x1F, 0x1A, 0xFF, 0x08, 0x22, + 0x3D, 0xEE, 0x45, 0x6B, 0xD2, 0x5A, 0xF3, 0x15, + 0x93, + + 0xCC, 0x0E, 0xCA, 0xDF, 0xEF, 0xC6, 0xC6, 0x35, + 0x66, 0x95, 0xFF, 0xCE, 0x3F, 0x13, 0x97, 0xEA, + 0xEC, 0xB9, 0xEB, 0x1F, 0x82, 0x4E, 0x6A, 0xFF, + 0xB0, 0x0A, 0x75, 0xAB, 0xBC, 0x6B, 0xF1, 0xC4, + 0xEE, 0xB8, 0x8C, 0xAE, 0x52, 0xED, 0x7C, 0x9E, + 0xF3, 0xE2, 0x74, 0xAD, 0x95, 0x65, 0x8F, 0x2D, + 0x1A, 0x93, 0xF5, 0x35, 0x5D, 0x5E, 0x7F, 0x5A, + 0x22, 0x9F, 0x48, 0x81, 0x25, 0xDE, 0xB1, 0xC3, + 0x0A, 0xD6, 0x7E, 0x9E, 0x77, 0xF0, 0x1F, 0x77, + 0xE0, 0x85, 0xBB, 0xFA, 0xC5, 0x87, 0xC7, 0x17, + 0x0A, 0x7B, 0x3D, 0x85, 0xD4, 0xA9, 0xCA, 0x98, + 0xCC, 0x08, 0xD5, 0x40, 0x58, 0x6A, 0x0D, 0xFE, + 0xBC, 0x4D, 0xBE, 0x46, 0x9E, 0xC0, 0x84, 0xF4, + 0x63, 0xE7, 0xEA, 0xFD, 0x7B, 0x73, 0x1D, 0xDB, + 0xE2, 0xD7, 0x51, 0x6D, 0xB2, 0x4F, 0x79, 0x37, + 0x9E, 0x37, 0x39, 0xE9, 0xD7, 0xCB, 0x7F, 0x56, + 0x5E, 0x68, 0xCC, 0x73, 0x7B, 0xBA, 0x3D, 0x76, + 0x0A, 0x41, 0x0B, 0x83, 0xC5, 0xAA, 0xCF, 0x7E, + 0xDA, 0x40, 0xB6, 0xCB, 0xC1, 0x76, 0xE5, 0x21, + 0xC3, 0xC8, 0xDB, 0x01, 0x2A, 0x87, 0xFF, 0x9E, + 0xC7, 0x58, 0xD5, 0xC8, 0x22, 0x37, 0x3F, 0x1F, + 0x49, 0xF0, 0x9F, 0x7C, 0x60, 0x91, 0x8C, 0xC5, + 0x51, 0xE3, 0x5F, 0x7A, 0x98, 0x0B, 0x3E, 0xE1, + 0xAA, 0xC8, 0xE4, 0x3C, 0xC5, 0x98, 0xC0, 0xE5, + 0x00, 0x5C, 0xEB, 0x57, 0xAF, 0xF2, 0x67, 0x30, + 0x11, 0xB0, 0xD8, 0x82, 0x8A, 0x5A, 0x97, 0xC8, + 0xFC, 0x09, 0xD7, 0x74, 0x98, 0xC9, 0x8D, 0xB5, + 0x1A, 0x96, 0x79, 0x47, 0xDE, 0x9B, 0x7C, 0xF3, + 0x86, 0x80, 0x87, 0x2C, 0x2F, 0xC6, 0xA6, 0x17, + 0x85, 0xF3, 0xD1, 0xEE, 0x33, 0x68, 0x7A, 0xCC, + 0x54, 0x4A, 0x08, 0x18, 0x8F, 0x20, 0x08, 0x33, + 0x43, 0x25, 0x05, 0x9B, 0x21, 0xB2, 0x49, 0xA5, + 0x33, 0xC0, + + 0x62, 0xD2, 0x23, 0x2D, 0x6D, 0xC4, 0x02, 0x15, + 0x9C, 0xC7, 0x37, 0x08, 0xEA, 0x73, 0x56, 0xB4, + 0x77, 0xEE, 0x14, 0xEC, 0x2B, 0x86, 0x51, 0xA0, + 0x63, 0x54, 0x00, 0xD4, 0xDE, 0x91, 0xE9, 0x94, + 0x3F, 0x32, 0xE6, 0x44, 0x49, 0xF7, 0xBD, 0x4C, + 0xFA, 0x07, 0xFB, 0xCB, 0x86, 0xFC, 0xBA, 0x1B, + 0x66, 0x52, 0xE3, 0x2C, 0x52, 0x5C, 0x07, 0xD7, + 0xFF, 0x08, 0x93, 0x73, 0x30, 0x4E, 0xB8, 0x97, + 0x8E, 0xB5, 0xEB, 0x24, 0xF7, 0x26, 0xB5, 0x21, + 0xEA, 0x1A, 0x62, 0x1B, 0xAC, 0x12, 0x83, 0xB1, + 0xB2, 0xAB, 0x1C, 0x1C, 0x69, 0x7D, 0x5C, 0x9D, + 0x4E, 0x20, 0x13, 0x52, 0x6B, 0x88, 0xB6, 0xBE, + 0x0E, 0x8D, 0x23, 0xD4, 0x14, 0xF5, 0x99, 0xEB, + 0x2E, 0xC8, 0x4D, 0x38, 0x57, 0x47, 0x70, 0x18, + 0x65, 0xB5, 0xB8, 0xB4, 0x29, 0x99, 0xA2, 0x4B, + 0xAA, 0x5A, 0xEC, 0x8B, 0xCA, 0x9F, 0xE9, 0x6D, + 0x8B, 0x0D, 0xEC, 0x0A, 0xCB, 0xD8, 0xF7, 0x0C, + 0x7B, 0x22, 0xB0, 0xE8, 0x3C, 0x4F, 0x0C, 0xEC, + 0x7E, 0x2D, 0x8F, 0x93, 0x2C, 0xC0, 0xA8, 0x40, + 0x48, 0xAA, 0xAF, 0x83, 0x08, 0xBF, 0xBF, 0x5C, + 0xBE, 0xB8, 0xAD, 0xC0, 0xCC, 0xDC, 0x7D, 0x00, + 0x2B, 0x2B, 0xC7, 0x74, 0xB0, 0x77, 0x95, 0x5F, + 0xE9, 0xA1, 0x65, 0x45, 0xB0, 0xBB, 0xEF, 0xD8, + 0xFA, 0x1D, 0x1F, 0x66, 0xEF, 0x3B, 0x68, 0x7B, + 0x67, 0x9F, 0xFF, 0xA4, 0xB5, 0x24, 0x69, 0xAB, + 0x84, 0xE3, 0x75, 0x69, 0x56, 0x72, 0x19, 0x0D, + 0x47, 0xA3, 0xF8, 0xAE, 0xA1, 0x4E, 0xB0, 0x4C, + 0xAA, 0x0F, 0xF9, 0x08, 0xEA, 0x8F, 0x69, 0xFC, + 0x60, 0xF4, 0x91, 0xFF, 0x08, 0xD5, 0xD4, 0xB4, + 0xD2, 0x4B, 0xBD, 0x4E, 0x3F, 0x53, 0x34, 0x06, + 0x4A, 0x26, 0x57, 0x0F, 0xF2, 0xDE, 0x9D, 0x02, + 0xA4, 0xE0, 0x0D, 0xD7, 0x2C, 0x5F, 0x5F, 0x05, + 0x4F, 0x60, 0x38, + + 0x0D, 0xEC, 0xE4, 0x86, 0xF5, 0x6D, 0xC1, 0x52, + 0x88, 0x55, 0xB9, 0x1D, 0x2D, 0xD7, 0x0A, 0xB4, + 0x5C, 0xB2, 0xDE, 0xF6, 0xBD, 0x91, 0x5D, 0x8D, + 0x0D, 0xB0, 0xD8, 0x54, 0x56, 0x62, 0xF1, 0x94, + 0xB5, 0xEE, 0x73, 0x23, 0xF2, 0x25, 0xF5, 0x7E, + 0x6A, 0xBF, 0x8A, 0xAA, 0x1C, 0x66, 0xCB, 0xA0, + 0xD6, 0xB2, 0xFC, 0x94, 0x6E, 0x26, 0x49, 0xF8, + 0xDE, 0xC0, 0xD8, 0x04, 0x93, 0x80, 0x16, 0x52, + 0xA6, 0xDE, 0x3F, 0x87, 0x4E, 0x2F, 0x93, 0xBD, + 0xAA, 0x8D, 0xA8, 0x86, 0x27, 0xAC, 0x6D, 0xA0, + 0x13, 0x81, 0xF6, 0xE7, 0x7D, 0xBC, 0xF1, 0x09, + 0x38, 0x09, 0x93, 0xC5, 0x94, 0x84, 0x0F, 0x4E, + 0x28, 0xCA, 0x29, 0x4D, 0xED, 0xDC, 0x91, 0xDC, + 0xEC, 0x16, 0xF7, 0x86, 0x4C, 0x0B, 0x2C, 0xDA, + 0xCE, 0x2B, 0x1B, 0xB4, 0xFC, 0x6F, 0xA5, 0x7C, + 0xE2, 0xC0, 0xAD, 0xC7, 0xA7, 0xE1, 0x28, 0x03, + 0xD5, 0xB3, 0x30, 0x51, 0xA2, 0x24, 0x2F, 0x9E, + 0x16, 0x48, 0x54, 0x6B, 0x36, 0x60, 0x22, 0x58, + 0x00, 0xFF, 0x40, 0x59, 0x17, 0x36, 0x1C, 0x2C, + 0x58, 0x0F, 0xC0, 0x5D, 0x41, 0x47, 0x7F, 0xE3, + 0xB1, 0x5F, 0x0A, 0x88, 0xBC, 0xBA, 0x83, 0xBF, + 0x3D, 0x0B, 0xDF, 0xFC, 0xD3, 0x55, 0xDF, 0x72, + 0x0D, 0x8A, 0xAF, 0x4D, 0xF4, 0x0C, 0x0F, 0x8C, + 0xE9, 0xEE, 0xA5, 0xA7, 0xFF, 0x87, 0x81, 0x2E, + 0x38, 0x04, 0x76, 0xAE, 0xA2, 0xE6, 0x84, 0x73, + 0xFF, 0xEC, 0xEE, 0xA3, 0x40, 0xA8, 0x67, 0x8C, + 0xD6, 0x68, 0x70, 0xA0, 0x6B, 0x3F, 0x0D, 0x45, + 0xE0, 0xA0, 0x29, 0x38, 0xF8, 0xD5, 0x58, 0x59, + 0xBD, 0x9B, 0x2B, 0xD3, 0x8B, 0x45, 0x3D, 0xDB, + 0x79, 0x0F, 0x25, 0xE7, 0xF9, 0xC7, 0x30, 0xC8, + 0x92, 0xC1, 0x99, 0xBE, 0xEC, 0xAF, 0x68, 0xDF, + 0x9F, 0xEC, 0x4C, 0x8C, 0xD8, 0x7A, 0xEF, 0x07, + 0x6E, 0x14, 0xF4, 0x41, + + 0x93, 0x45, 0x33, 0x61, 0xF0, 0xF2, 0x27, 0x76, + 0x4C, 0x53, 0x60, 0xAE, 0x83, 0xB0, 0x90, 0x70, + 0xDB, 0xAE, 0x2F, 0x1A, 0xCF, 0xF2, 0xC6, 0x50, + 0x36, 0x1B, 0x2E, 0x75, 0xF2, 0x4F, 0x1B, 0x9B, + 0x81, 0x2F, 0x49, 0x96, 0xED, 0x05, 0x69, 0x07, + 0x0C, 0x6B, 0x5A, 0x35, 0x11, 0x6B, 0x29, 0xC6, + 0x07, 0xF5, 0x68, 0xAF, 0x26, 0xE1, 0xEB, 0x71, + 0x53, 0x4A, 0xC0, 0x5A, 0x1B, 0xDD, 0x49, 0x28, + 0x90, 0xE3, 0xDB, 0x1F, 0x86, 0xB1, 0xAB, 0x4A, + 0x64, 0x39, 0x8F, 0x83, 0xA7, 0x37, 0x1B, 0xC9, + 0xB6, 0xEA, 0x5E, 0xA8, 0x25, 0x87, 0x78, 0x52, + 0xA0, 0xE5, 0xA3, 0x26, 0x74, 0x66, 0xCC, 0x0A, + 0x92, 0x7D, 0x9B, 0x4B, 0xAD, 0x79, 0x7F, 0x87, + 0x9E, 0x0A, 0xF9, 0xDE, 0xB0, 0x31, 0x2B, 0xDC, + 0xC8, 0x29, 0xD0, 0xAC, 0x3C, 0xD8, 0x60, 0x19, + 0xA5, 0xF6, 0x50, 0xC1, 0xBA, 0x0F, 0xE4, 0x4A, + 0x07, 0xE8, 0xA5, 0xB7, 0x6C, 0x88, 0xF1, 0xBE, + 0xAF, 0x2F, 0x40, 0x9B, 0xB3, 0x98, 0x28, 0x43, + 0x25, 0xBB, 0x23, 0x1C, 0xF3, 0x98, 0x19, 0x9E, + 0x9E, 0x3D, 0xC0, 0xFF, 0x05, 0xA8, 0x35, 0xCD, + 0x47, 0xB7, 0xB3, 0xEF, 0xC9, 0x38, 0x36, 0xE7, + 0xF9, 0x6F, 0x5B, 0x6E, 0x79, 0xCB, 0x08, 0x49, + 0x6F, 0x4C, 0x17, 0xC2, 0x91, 0x7E, 0x8B, 0x86, + 0x57, 0x30, 0x8F, 0x92, 0x94, 0x34, 0x10, 0x1B, + 0xE5, 0x8F, 0xCC, 0xAF, 0xD0, 0x87, 0xDA, 0x9A, + 0xF2, 0x09, 0x99, 0x6C, 0x8E, 0x50, 0x91, 0x7D, + 0x7C, 0x4D, 0x3E, 0x24, 0xFF, 0xD4, 0xC1, 0xAA, + 0xA7, 0x80, 0x89, 0xB5, 0x8E, 0x50, 0x7D, 0x49, + 0xD4, 0xA0, 0xA1, 0xFD, 0x34, 0xCA, 0xB8, 0xCB, + 0x64, 0x76, 0x07, 0x91, 0x39, 0x7D, 0xAE, 0xE2, + 0xD9, 0x5A, 0xCB, 0xB7, 0xAD, 0x9E, 0x8C, 0xE8, + 0x0A, 0xE8, 0xE9, 0xCC, 0x49, 0x97, 0xC3, 0xE9, + 0x96, 0x1A, 0xCE, 0xFF, 0x16, + + 0x3D, 0x76, 0xF1, 0x1D, 0x88, 0x56, 0x8E, 0x23, + 0x96, 0xE0, 0x55, 0xE9, 0xF3, 0x36, 0xCE, 0xEA, + 0x3C, 0x72, 0x34, 0x12, 0xA4, 0x19, 0x29, 0x74, + 0x26, 0xCA, 0xF9, 0xDB, 0xA4, 0x2F, 0x2E, 0xBD, + 0xD1, 0x64, 0x97, 0xE2, 0x7E, 0x30, 0x59, 0xDB, + 0xBB, 0x7D, 0x42, 0xD2, 0xC1, 0x84, 0x18, 0x1F, + 0x67, 0x61, 0x5D, 0x40, 0xE5, 0xD8, 0x83, 0x36, + 0x98, 0xAB, 0x2F, 0xE8, 0x24, 0x13, 0xC7, 0x61, + 0x0A, 0x71, 0x59, 0x9E, 0x51, 0xE1, 0xBB, 0xCE, + 0xEA, 0xE7, 0xFC, 0x7E, 0x92, 0xE0, 0x1F, 0xA5, + 0xE3, 0x89, 0x80, 0xBC, 0xA8, 0xCB, 0xDB, 0xFD, + 0x49, 0x8D, 0x7F, 0x01, 0x15, 0xA5, 0x35, 0x89, + 0x46, 0xB5, 0xBC, 0x8E, 0x96, 0x80, 0x11, 0xCA, + 0x6C, 0x56, 0x94, 0x1C, 0x0C, 0xEC, 0x56, 0x78, + 0xC9, 0x7E, 0x4A, 0x44, 0xE7, 0xDF, 0x03, 0xA9, + 0x32, 0xF5, 0xA2, 0x4C, 0x80, 0xBB, 0x31, 0x9E, + 0x00, 0x5D, 0xCD, 0xB2, 0x33, 0x41, 0xCA, 0xA4, + 0x8A, 0xB3, 0x52, 0x59, 0xD9, 0x19, 0xD4, 0x98, + 0x78, 0xFE, 0xB1, 0x02, 0x6D, 0x52, 0x6F, 0x23, + 0xC8, 0xF7, 0xA8, 0xC2, 0xB4, 0x90, 0x69, 0x68, + 0x5A, 0xA5, 0xDB, 0x26, 0x93, 0xF0, 0x78, 0x25, + 0xC3, 0x94, 0x1F, 0x0A, 0x0B, 0x0F, 0xA8, 0xC2, + 0xCB, 0x7B, 0x0D, 0xC9, 0x53, 0x1D, 0x5A, 0xB4, + 0x30, 0xF2, 0xDD, 0x15, 0x8D, 0xDE, 0x49, 0x82, + 0x94, 0x9B, 0x6E, 0x2D, 0x2D, 0xD7, 0x21, 0x38, + 0x98, 0x61, 0xEB, 0xF3, 0xDE, 0xB1, 0xCE, 0x54, + 0xB9, 0x7F, 0x9C, 0x4B, 0xF0, 0x8B, 0xD1, 0xBF, + 0x6A, 0xA4, 0x57, 0x28, 0x86, 0xE2, 0xB2, 0x74, + 0x31, 0x51, 0x9E, 0x30, 0xF5, 0x98, 0x3E, 0x9D, + 0x98, 0x21, 0x7C, 0xAD, 0x68, 0x44, 0x91, 0x5C, + 0x11, 0x5A, 0x42, 0x0C, 0x84, 0x69, 0x62, 0xD0, + 0x98, 0x3D, 0x89, 0x4D, 0xBC, 0x65, 0x38, 0x03, + 0x44, 0x76, 0xFF, 0x20, 0x3D, 0x28, + + 0xD4, 0xAE, 0xDA, 0xA8, 0x24, 0x19, 0x06, 0xFB, + 0xE9, 0xAD, 0x9F, 0x3C, 0x1D, 0xD6, 0x92, 0x5E, + 0x83, 0x58, 0x54, 0xBB, 0xCB, 0x7D, 0x8E, 0x24, + 0x0F, 0x0A, 0x43, 0xF5, 0x6D, 0x89, 0x99, 0x4A, + 0xB7, 0xDF, 0x8A, 0x84, 0x00, 0x1A, 0xF5, 0x6E, + 0x1C, 0xC2, 0xFA, 0x20, 0xE7, 0xC2, 0x41, 0x60, + 0x7C, 0xCE, 0x90, 0x8E, 0x16, 0x64, 0x94, 0xDA, + 0xE2, 0x3A, 0x8D, 0xDF, 0x21, 0x61, 0x17, 0x3C, + 0x72, 0xE3, 0x66, 0x35, 0x0B, 0xF6, 0x30, 0x5C, + 0x82, 0x5C, 0x48, 0xA1, 0xE8, 0x21, 0x9C, 0x92, + 0xA1, 0x0F, 0xBF, 0x89, 0xC8, 0x7A, 0xEE, 0x18, + 0x87, 0x5B, 0x51, 0xF3, 0xF7, 0x0A, 0xA3, 0xB4, + 0x2E, 0xDA, 0x4E, 0xAA, 0xAD, 0x6E, 0x70, 0x04, + 0xF8, 0x47, 0x1E, 0x5F, 0x43, 0x69, 0x0B, 0x26, + 0x4C, 0xBC, 0xDB, 0x46, 0x77, 0x87, 0xA1, 0x9A, + 0x04, 0xEF, 0x74, 0x99, 0xEA, 0x29, 0x71, 0x55, + 0x9C, 0x2E, 0x47, 0xE3, 0x4A, 0x15, 0xA4, 0xF6, + 0xED, 0x5D, 0xBE, 0x4F, 0x94, 0x3F, 0xFD, 0xD3, + 0x6E, 0x0E, 0xD9, 0x26, 0x68, 0x9F, 0xC2, 0x8C, + 0xA5, 0xA8, 0xF0, 0xFB, 0x53, 0x5F, 0x18, 0xCA, + 0xDB, 0xBD, 0x98, 0x96, 0x28, 0xFC, 0xE9, 0x2E, + 0x81, 0xE1, 0x0E, 0x3A, 0x77, 0x18, 0x25, 0x9D, + 0xB7, 0x67, 0x8C, 0x35, 0x68, 0x4A, 0x88, 0x18, + 0x45, 0x6C, 0xE5, 0xCC, 0x22, 0xD2, 0x77, 0x9A, + 0x68, 0x0E, 0xC5, 0xA6, 0x1D, 0xAD, 0xDB, 0xB5, + 0xFF, 0xEA, 0x7C, 0x7D, 0x19, 0x1B, 0x9D, 0xB9, + 0xD0, 0xA7, 0xAB, 0x4D, 0x4A, 0x7D, 0x1A, 0xA5, + 0x09, 0x54, 0x84, 0x5C, 0x14, 0x4E, 0xA6, 0x14, + 0x6B, 0x22, 0x46, 0x7E, 0x5E, 0xB9, 0x33, 0x97, + 0xB5, 0x63, 0x5C, 0xCE, 0xF4, 0xD0, 0xD8, 0x8C, + 0xCC, 0xE7, 0x67, 0x01, 0x1B, 0x56, 0x68, 0x54, + 0x56, 0x4C, 0x19, 0x1D, 0x05, 0xF8, 0x55, 0xD6, + 0x45, 0xC0, 0xAD, 0xD6, 0xEE, 0xD9, 0x03, + + 0x7F, 0x07, 0xFA, 0x8C, 0x77, 0xF1, 0xDA, 0x4E, + 0x4B, 0x65, 0x55, 0xA4, 0x12, 0xE8, 0x7F, 0x04, + 0x0A, 0xEC, 0x57, 0xFF, 0x30, 0xD1, 0xE2, 0x08, + 0x71, 0xEC, 0x5F, 0x72, 0x88, 0x37, 0xC1, 0x33, + 0x79, 0xC8, 0x49, 0x47, 0x11, 0xC9, 0x8C, 0xD3, + 0x3B, 0x4F, 0x2C, 0x5A, 0xDD, 0x8C, 0x00, 0x8B, + 0xF6, 0xC4, 0x07, 0x7E, 0x2C, 0xFA, 0x3A, 0xBF, + 0x84, 0xBA, 0x13, 0x31, 0x20, 0x69, 0xAF, 0xBD, + 0x61, 0xB0, 0xFF, 0x28, 0x40, 0x1B, 0x5F, 0x1D, + 0x87, 0x99, 0x23, 0x95, 0x77, 0x88, 0x3F, 0xBB, + 0xFA, 0x55, 0xB5, 0xB2, 0xF7, 0xF3, 0xA6, 0x0B, + 0x57, 0x71, 0xF5, 0x7A, 0xE7, 0x23, 0x61, 0x54, + 0x13, 0xCB, 0x71, 0x97, 0xDE, 0xFF, 0x0E, 0x23, + 0x5C, 0xD4, 0xCC, 0xB1, 0xB8, 0x2F, 0xA1, 0xA5, + 0x15, 0xEB, 0xB4, 0x47, 0xA7, 0x7C, 0xEA, 0xD1, + 0x23, 0xE7, 0xFE, 0x9D, 0x56, 0xC5, 0x73, 0x9D, + 0xE8, 0x90, 0x4E, 0x00, 0xE5, 0x7F, 0x6E, 0x36, + 0x6D, 0xEA, 0x8C, 0xBA, 0xC6, 0x9C, 0xA0, 0x27, + 0x13, 0x90, 0x35, 0xE7, 0xD5, 0x27, 0x56, 0x50, + 0x70, 0x64, 0x03, 0xD2, 0x43, 0xDC, 0x1F, 0x60, + 0x4B, 0x5D, 0x48, 0xF1, 0x82, 0xE6, 0x9A, 0xDE, + 0xC7, 0xDB, 0x2F, 0x0D, 0xD9, 0xF4, 0xAD, 0xD0, + 0xB9, 0xDC, 0x01, 0x09, 0x74, 0x4F, 0x29, 0x71, + 0x61, 0x6D, 0xE2, 0xAC, 0xE3, 0x60, 0x9C, 0x4D, + 0x9A, 0x26, 0xC9, 0x3D, 0x11, 0x04, 0x83, 0x9F, + 0x39, 0x39, 0x0E, 0x44, 0xB2, 0xD3, 0x7A, 0x0D, + 0xD7, 0x0B, 0xDB, 0x14, 0x4A, 0x46, 0xA7, 0xB5, + 0x34, 0x2C, 0x22, 0x98, 0xBA, 0x6A, 0xBA, 0x4A, + 0xDA, 0x30, 0x8C, 0xE7, 0xDF, 0xD8, 0x73, 0x83, + 0x8C, 0xB6, 0x7A, 0x73, 0x74, 0xE5, 0x04, 0x32, + 0x66, 0x24, 0xC9, 0x45, 0xDA, 0x86, 0xE2, 0xCD, + 0xF9, 0xDB, 0x2F, 0x1D, 0xBA, 0x2C, 0xC0, 0x91, + 0x06, 0xF7, 0x44, 0xE8, 0x30, 0x34, 0x94, 0x91, + + 0xD5, 0x3B, 0xA6, 0x5A, 0x56, 0xB4, 0xDD, 0xBC, + 0xD8, 0xE7, 0x85, 0x2B, 0x3E, 0xFC, 0xBC, 0xD1, + 0xB9, 0x68, 0x09, 0xC3, 0xA5, 0xC1, 0x1D, 0x5C, + 0x4C, 0x11, 0xAC, 0x4A, 0xA3, 0x96, 0xAB, 0xD2, + 0xFD, 0x33, 0xD7, 0x69, 0xD1, 0x95, 0x50, 0xE6, + 0x4D, 0x3A, 0xE9, 0x9D, 0x67, 0x68, 0x16, 0x01, + 0xE7, 0x8A, 0xE3, 0x90, 0xC8, 0x4D, 0xD4, 0xDF, + 0xB0, 0xA1, 0x90, 0x14, 0xC2, 0x32, 0x9A, 0xC2, + 0x86, 0xA2, 0x53, 0x72, 0x1A, 0x9A, 0xFE, 0x8E, + 0xB1, 0x4C, 0xCD, 0x9F, 0xFF, 0x3F, 0xA6, 0x6A, + 0x8E, 0xEB, 0x5E, 0x7C, 0x9D, 0xF3, 0x4B, 0x3B, + 0x09, 0xC7, 0x68, 0x71, 0xD5, 0xBA, 0x32, 0x2D, + 0xBA, 0x15, 0xE3, 0x63, 0xD7, 0x5A, 0x87, 0x5E, + 0x9E, 0xAF, 0xB0, 0x9C, 0xF9, 0x35, 0xA3, 0x67, + 0x1B, 0xD5, 0xC7, 0x9C, 0xB5, 0x63, 0x0E, 0x16, + 0x9B, 0x2D, 0x25, 0x1E, 0x22, 0x96, 0x0A, 0x96, + 0xBE, 0xEF, 0x65, 0xAA, 0xFE, 0x28, 0xB9, 0x55, + 0xD0, 0xDC, 0xB2, 0x5C, 0x21, 0x9B, 0x31, 0xF7, + 0xDE, 0xD9, 0xA6, 0x86, 0x3D, 0xD8, 0x5F, 0xB4, + 0xC5, 0x7A, 0x4D, 0xAB, 0xE5, 0xBC, 0x10, 0xB7, + 0x26, 0x15, 0x08, 0x64, 0x58, 0xB0, 0x4F, 0x77, + 0xCE, 0xDC, 0xBD, 0x1D, 0xD5, 0x21, 0x9A, 0x9A, + 0x93, 0x72, 0x2D, 0x4D, 0x82, 0x36, 0x29, 0xCA, + 0xAB, 0x80, 0xD2, 0x02, 0x1D, 0x6C, 0x49, 0x30, + 0x56, 0x20, 0x8D, 0xFA, 0xA1, 0x58, 0x3F, 0xA6, + 0xCB, 0xF0, 0x41, 0xFB, 0xDD, 0xD0, 0x6D, 0x80, + 0x75, 0xE1, 0x36, 0xAC, 0xF8, 0xAE, 0xDB, 0x37, + 0xB0, 0xDE, 0x4B, 0x89, 0xFB, 0xC1, 0x1B, 0x23, + 0x05, 0xBC, 0x02, 0x87, 0x42, 0x9A, 0x77, 0x23, + 0x99, 0xB4, 0x56, 0x7E, 0x7C, 0xD7, 0x61, 0x18, + 0xD2, 0x4F, 0x19, 0xE6, 0x05, 0x4D, 0x72, 0xC8, + 0xB7, 0xA9, 0x9F, 0xF9, 0x9F, 0xE9, 0x54, 0x34, + 0x54, 0x45, 0x7C, 0xA4, 0xCC, 0x3B, 0xFF, 0x2B, + 0x58, + + 0xB7, 0x93, 0x32, 0xE4, 0xCA, 0xD7, 0xB5, 0x4F, + 0x11, 0xB0, 0x5B, 0x38, 0xB8, 0xC0, 0x90, 0xA8, + 0x0E, 0x4B, 0x34, 0x6C, 0xCC, 0x81, 0x82, 0xC5, + 0x41, 0x91, 0x0D, 0x1A, 0x47, 0x0E, 0xE6, 0x39, + 0x7F, 0xDD, 0xF9, 0xBE, 0xF1, 0xB0, 0xDC, 0x76, + 0xB8, 0x2C, 0x2B, 0xAD, 0xA9, 0xE5, 0xCA, 0x70, + 0x8D, 0xF1, 0xCA, 0x60, 0x5C, 0x85, 0x2E, 0x73, + 0xE7, 0xF8, 0x0A, 0x33, 0xB3, 0x32, 0xC0, 0xCD, + 0x64, 0x4C, 0x9C, 0x65, 0x55, 0x2A, 0x60, 0x42, + 0xF3, 0xBA, 0xF5, 0xC2, 0x28, 0xFC, 0xFE, 0x32, + 0x96, 0xBF, 0x6F, 0x7E, 0x09, 0x82, 0xA5, 0xD0, + 0xE4, 0x11, 0x66, 0x67, 0x66, 0xDB, 0x8A, 0x3D, + 0x08, 0x40, 0xC4, 0x40, 0x66, 0xF8, 0x1F, 0x86, + 0x39, 0xDB, 0xB6, 0x12, 0x11, 0x4E, 0xE4, 0x52, + 0xA5, 0x18, 0x4A, 0x3F, 0x04, 0x01, 0x3D, 0x8D, + 0x15, 0xEE, 0x28, 0xBD, 0xED, 0x32, 0x11, 0xB8, + 0xE9, 0x5E, 0x2A, 0xB7, 0xD3, 0x3C, 0xDD, 0xC6, + 0x42, 0xE0, 0x15, 0x20, 0x0B, 0x13, 0x7E, 0x21, + 0xFE, 0x7B, 0x5F, 0x46, 0x70, 0xF6, 0x64, 0x73, + 0x71, 0x1A, 0x29, 0xD9, 0x07, 0xE0, 0xA9, 0x65, + 0x5B, 0x90, 0x17, 0x5E, 0xE6, 0xFC, 0x29, 0xA2, + 0x5B, 0xB0, 0x00, 0x54, 0x6C, 0x15, 0xA1, 0x44, + 0x66, 0x0F, 0x87, 0xCF, 0x66, 0x04, 0x6F, 0x3F, + 0x04, 0xE5, 0xFA, 0x2D, 0x0C, 0x70, 0x43, 0xF0, + 0x08, 0x01, 0x62, 0x21, 0x81, 0x65, 0x9F, 0x61, + 0xC6, 0x5A, 0x80, 0x64, 0x9D, 0x8E, 0xD7, 0x52, + 0xCF, 0xDC, 0x04, 0x50, 0x0A, 0x98, 0x5A, 0xF2, + 0x9F, 0x6A, 0xAF, 0xDA, 0x96, 0x35, 0x34, 0xF9, + 0xAB, 0x1E, 0x17, 0xC3, 0x18, 0x90, 0xFB, 0x07, + 0x5E, 0xA0, 0x02, 0x4C, 0x0C, 0xE1, 0xE9, 0x06, + 0x7F, 0x1F, 0xC1, 0xA2, 0x77, 0x63, 0xF0, 0x96, + 0xEE, 0x87, 0xC8, 0x28, 0x79, 0x17, 0x33, 0x2D, + 0x16, 0x43, 0x9A, 0x79, 0x32, 0xA9, 0x3D, 0x1F, + 0x35, 0x3D, + + 0xD1, 0x6C, 0xFF, 0x29, 0x4F, 0xC3, 0x29, 0xC5, + 0xC9, 0x5B, 0xDC, 0x81, 0xD1, 0xB3, 0x55, 0xA8, + 0x5E, 0xE2, 0xC9, 0xE3, 0xFC, 0x16, 0x30, 0x02, + 0xAB, 0x43, 0x26, 0x7E, 0xD1, 0xCD, 0x2B, 0x06, + 0xE8, 0x4E, 0xDA, 0xA3, 0xD3, 0xD3, 0x87, 0x05, + 0xB3, 0x05, 0x8C, 0xCF, 0xAE, 0xEF, 0x15, 0x33, + 0xCE, 0x72, 0x64, 0x52, 0x88, 0x78, 0x20, 0x1B, + 0xF1, 0x7E, 0xC9, 0x46, 0x13, 0xCF, 0xD9, 0xF2, + 0x4B, 0x1C, 0xA6, 0x96, 0xAF, 0x02, 0xAD, 0x6F, + 0xDB, 0xAD, 0x6F, 0x04, 0x55, 0xA2, 0x2C, 0x9C, + 0x56, 0xB6, 0x07, 0x8A, 0x87, 0x3F, 0xD6, 0x06, + 0x90, 0x4C, 0x6D, 0x5E, 0xE5, 0x16, 0x21, 0x46, + 0x00, 0x88, 0x77, 0x58, 0x0E, 0x9E, 0x89, 0xFE, + 0x3F, 0x20, 0x6A, 0x17, 0x64, 0x9C, 0x63, 0x71, + 0x3C, 0xDB, 0x36, 0xE3, 0x8A, 0xA6, 0x7A, 0xD5, + 0x1A, 0x27, 0x75, 0x4C, 0xD9, 0xF3, 0xF0, 0x02, + 0x2B, 0x3D, 0xE5, 0xF1, 0xDE, 0x98, 0x98, 0x62, + 0x18, 0x17, 0xAE, 0xD2, 0x80, 0xA7, 0xA3, 0x82, + 0xBF, 0x30, 0xC8, 0xC9, 0x68, 0x6A, 0x2F, 0x40, + 0x8A, 0x2F, 0x8A, 0x39, 0xB4, 0x60, 0x6F, 0xE1, + 0x0F, 0x19, 0xB1, 0x4C, 0x82, 0x9A, 0x11, 0xB4, + 0x98, 0x74, 0xE7, 0xAF, 0xD4, 0x21, 0x5E, 0xD8, + 0x30, 0xA1, 0x53, 0xF3, 0xD2, 0xDE, 0x02, 0x9F, + 0xA6, 0xA8, 0x4D, 0x03, 0x2A, 0x45, 0xE3, 0x49, + 0x98, 0xE2, 0xF7, 0x71, 0x9F, 0xBC, 0x93, 0xDE, + 0xF6, 0x7E, 0x12, 0xC1, 0x37, 0xB0, 0x93, 0x4E, + 0x89, 0x16, 0x39, 0x2B, 0xF6, 0x28, 0x30, 0x75, + 0xC0, 0x43, 0xA9, 0x3D, 0x1F, 0xD3, 0xFD, 0x56, + 0xF7, 0x65, 0xFC, 0x08, 0x3C, 0x9B, 0x1C, 0x33, + 0x57, 0x0B, 0xAB, 0x4B, 0xFE, 0xD4, 0x50, 0xFC, + 0x9D, 0x42, 0xF7, 0x8D, 0xB4, 0x50, 0xF5, 0xA9, + 0x54, 0x00, 0x74, 0x93, 0x59, 0x6B, 0x6F, 0x95, + 0x31, 0xEE, 0xF5, 0xC4, 0x4A, 0x9C, 0x33, 0x27, + 0x6E, 0x1D, 0x4A, + + 0xB5, 0xEE, 0x2C, 0xC7, 0x88, 0xD2, 0x63, 0x3E, + 0xF6, 0x8E, 0xC1, 0xA3, 0xD2, 0x39, 0x8E, 0xF6, + 0xD3, 0x44, 0x7C, 0xA6, 0x27, 0x6E, 0x67, 0x66, + 0x0F, 0x68, 0xF9, 0xE2, 0xE4, 0xA2, 0x9B, 0x59, + 0x6D, 0x26, 0xE2, 0x4B, 0xF1, 0x82, 0x5C, 0x67, + 0xE9, 0x55, 0xEE, 0xB6, 0xA0, 0xE3, 0x32, 0xEE, + 0x2A, 0x33, 0x2F, 0x6A, 0x2B, 0xBC, 0xE8, 0xB9, + 0x45, 0xCD, 0x0F, 0xF0, 0x84, 0xB6, 0x5D, 0xC5, + 0xAC, 0xD7, 0x45, 0x4B, 0x5A, 0xE4, 0xD5, 0x07, + 0x6D, 0x30, 0x0A, 0x9E, 0x73, 0x0E, 0x7D, 0x5F, + 0x8A, 0x2C, 0x7A, 0xE4, 0xD0, 0x1B, 0xE7, 0x02, + 0x93, 0x2E, 0xCE, 0x3C, 0xA1, 0xB1, 0x48, 0x5A, + 0xD6, 0xC0, 0x38, 0x0F, 0x13, 0xC7, 0x8B, 0x0F, + 0x4D, 0x90, 0xFC, 0x22, 0xC5, 0x74, 0xC6, 0xE0, + 0xFE, 0x1B, 0x2D, 0xEA, 0x3E, 0xDB, 0xC1, 0xCA, + 0x7F, 0x0D, 0xA0, 0xBB, 0x62, 0x0B, 0x51, 0x46, + 0xD4, 0xAB, 0x21, 0xE9, 0x6A, 0x13, 0x55, 0xEC, + 0x00, 0x16, 0xF5, 0xA3, 0xE8, 0x59, 0x90, 0xFB, + 0x56, 0xA5, 0x4B, 0x7F, 0x3F, 0xAA, 0x2E, 0x27, + 0x6F, 0xEC, 0x7B, 0xD1, 0xFA, 0x79, 0x36, 0x95, + 0x17, 0x84, 0xE0, 0xF1, 0xFB, 0xCA, 0xE2, 0x71, + 0x18, 0xAF, 0x49, 0x4D, 0x02, 0x51, 0xAB, 0x0C, + 0x56, 0x0A, 0xAF, 0x96, 0x0A, 0xD3, 0x57, 0x93, + 0xA1, 0x8E, 0xD1, 0x32, 0xD4, 0x1D, 0x62, 0xE1, + 0x1F, 0x4D, 0x00, 0xD4, 0x0B, 0x6F, 0xAE, 0x69, + 0x67, 0xAA, 0x2D, 0x75, 0x17, 0x0E, 0xE8, 0x72, + 0x91, 0x11, 0x05, 0xBB, 0x94, 0xBE, 0x0B, 0x2C, + 0x05, 0xF3, 0x09, 0x98, 0xAA, 0xA3, 0x77, 0xB9, + 0xAF, 0x75, 0x29, 0x57, 0xA0, 0x7F, 0x70, 0x53, + 0x4E, 0xEB, 0xD5, 0x15, 0x50, 0x60, 0x1D, 0x7B, + 0x3F, 0x3F, 0x65, 0x4E, 0xE0, 0x4A, 0x47, 0xEF, + 0xBA, 0x68, 0x01, 0xEB, 0xA5, 0x09, 0x4C, 0xE4, + 0xF6, 0xAA, 0xE0, 0x00, 0x43, 0x5B, 0x2E, 0x09, + 0xFE, 0xD0, 0x4E, 0xE8, + + 0x06, 0x49, 0x5B, 0x9A, 0xCF, 0x47, 0x2B, 0x04, + 0xBE, 0x1B, 0x98, 0x6A, 0xB5, 0x21, 0x6D, 0x0E, + 0x18, 0x9B, 0x87, 0xA4, 0x97, 0x13, 0xF5, 0x7E, + 0x94, 0x92, 0xB3, 0x69, 0xA1, 0xD5, 0x25, 0x46, + 0x26, 0x8E, 0x6B, 0x47, 0x0A, 0x77, 0x48, 0x51, + 0xB9, 0xAF, 0x64, 0x37, 0x70, 0x64, 0xBD, 0x98, + 0x16, 0x1A, 0x46, 0xAA, 0xFA, 0x0C, 0xB2, 0x3C, + 0x6F, 0x23, 0xA5, 0x6C, 0x81, 0x0B, 0x49, 0x7C, + 0x75, 0xE6, 0x0B, 0x47, 0x49, 0xDB, 0x70, 0xC5, + 0x26, 0x75, 0x20, 0x3E, 0xE2, 0x28, 0xD9, 0x1A, + 0xE2, 0x96, 0x9D, 0xAE, 0x29, 0x53, 0x9A, 0xE2, + 0xFE, 0xC9, 0xF5, 0x3B, 0x02, 0x40, 0x13, 0xF1, + 0x10, 0x27, 0x1A, 0x67, 0x97, 0x9C, 0xF6, 0xC5, + 0xBA, 0xE6, 0x3D, 0xA4, 0xA8, 0x67, 0xCF, 0xB6, + 0x35, 0xC7, 0x6B, 0xC6, 0x9C, 0x85, 0x25, 0x14, + 0x20, 0xC6, 0x48, 0x23, 0x26, 0x29, 0xE9, 0xBE, + 0x79, 0x89, 0xFA, 0x26, 0x2E, 0xB9, 0xC3, 0x54, + 0x28, 0x8B, 0xE2, 0xEF, 0xBC, 0xB2, 0x19, 0xC3, + 0x40, 0x85, 0x8A, 0x59, 0x06, 0x96, 0xDF, 0x39, + 0x03, 0x6E, 0xA0, 0xF8, 0x20, 0xD9, 0x3B, 0x72, + 0x80, 0xCC, 0x15, 0xBF, 0xB6, 0x2B, 0x15, 0x8A, + 0xC2, 0x71, 0x60, 0xEE, 0x51, 0x80, 0xCB, 0x61, + 0x7A, 0xDB, 0x17, 0x18, 0x80, 0xE5, 0x2F, 0xB9, + 0xB9, 0x36, 0xE3, 0xED, 0x7B, 0x7C, 0x23, 0xF7, + 0xBB, 0xBE, 0x61, 0xF1, 0xAF, 0x38, 0x5E, 0xAC, + 0x6E, 0x8F, 0x5A, 0x46, 0xB9, 0xD6, 0x4D, 0x51, + 0x5A, 0x7F, 0x3C, 0x34, 0xE5, 0x5E, 0x28, 0xB4, + 0x00, 0xD5, 0x76, 0xF6, 0x04, 0x94, 0x00, 0x36, + 0x23, 0xD1, 0x87, 0xA7, 0x0D, 0x55, 0xF4, 0x8A, + 0x89, 0x3A, 0x32, 0x9D, 0x08, 0xEB, 0xB6, 0x6F, + 0xED, 0xF0, 0xF8, 0x8F, 0x25, 0x3B, 0xAC, 0x6E, + 0xF5, 0x2B, 0x37, 0x4E, 0x4C, 0x28, 0x19, 0x69, + 0x66, 0x04, 0x40, 0x09, 0xE4, 0x1F, 0x82, 0x6F, + 0x5E, 0x40, 0x4C, 0x16, 0x4B, + + 0xBF, 0x12, 0xC4, 0xD2, 0xDD, 0xF1, 0x90, 0x50, + 0x38, 0x11, 0x8E, 0x5D, 0x20, 0x49, 0x64, 0xEB, + 0x08, 0xE0, 0x5F, 0xFF, 0x81, 0xC1, 0x23, 0x7F, + 0xA0, 0xBB, 0xB4, 0x28, 0x61, 0xA2, 0x99, 0xEB, + 0x44, 0x5A, 0x26, 0xF3, 0xF1, 0x76, 0x41, 0xF7, + 0x92, 0xFD, 0x6A, 0xB1, 0x72, 0x92, 0xBF, 0x62, + 0x92, 0x57, 0x46, 0x45, 0x0B, 0x5E, 0xA3, 0x33, + 0x64, 0x79, 0xE9, 0x3B, 0x50, 0x54, 0x62, 0xC1, + 0xB8, 0x5E, 0x45, 0x5A, 0x5F, 0xB4, 0xBB, 0x5F, + 0x6A, 0x01, 0x8D, 0x1B, 0x79, 0x76, 0x34, 0x08, + 0xF9, 0x42, 0xE4, 0xD6, 0x42, 0xDD, 0x16, 0x80, + 0xD4, 0x7D, 0x7D, 0xC4, 0x09, 0xAC, 0x96, 0xF8, + 0xB5, 0x8A, 0xF7, 0xBF, 0x92, 0xDB, 0x5D, 0xB7, + 0x15, 0x91, 0x6F, 0x96, 0xB5, 0x4C, 0x3E, 0x27, + 0xD8, 0xE2, 0xE1, 0x6F, 0x9D, 0x9B, 0xBB, 0x99, + 0x5D, 0xB5, 0x33, 0x55, 0xB3, 0x12, 0xFF, 0x64, + 0xBF, 0xB7, 0x58, 0xA0, 0x40, 0x9B, 0x6E, 0x35, + 0x26, 0x88, 0x13, 0x0B, 0x82, 0xA7, 0x2F, 0x10, + 0x70, 0x2B, 0xAF, 0x24, 0x1F, 0xAA, 0x62, 0xD2, + 0xBA, 0x0F, 0x3A, 0x29, 0x88, 0x48, 0xCB, 0xC9, + 0x60, 0x20, 0x73, 0x07, 0x46, 0x4D, 0x62, 0x2B, + 0x52, 0x2D, 0x39, 0xCB, 0x79, 0x63, 0x29, 0x54, + 0xA7, 0x4E, 0x3A, 0xD7, 0xD4, 0x51, 0x2D, 0xDD, + 0xBF, 0x6C, 0x16, 0x4E, 0xA7, 0x49, 0xEA, 0xE2, + 0x78, 0xBA, 0x84, 0x89, 0x7D, 0x5F, 0xA8, 0xFD, + 0x89, 0x2F, 0xA0, 0xE0, 0x1E, 0xE5, 0x51, 0x8D, + 0xE9, 0xE1, 0x73, 0x79, 0xE5, 0x28, 0x62, 0xFB, + 0x15, 0xD3, 0x44, 0xAF, 0xED, 0xCE, 0x1F, 0xB6, + 0x2D, 0x26, 0x5D, 0xDA, 0xED, 0x01, 0x30, 0x4D, + 0x72, 0x4F, 0x23, 0xF0, 0x5A, 0x1E, 0xC9, 0xAF, + 0xCF, 0x75, 0xA3, 0x15, 0xAE, 0x29, 0xF6, 0xD7, + 0xE4, 0xA9, 0x95, 0xF4, 0x39, 0x3E, 0xF6, 0x99, + 0xB5, 0xB3, 0x60, 0xDE, 0x7C, 0x26, 0xDD, 0xF0, + 0xD3, 0x04, 0x0A, 0xFC, 0xE9, 0xAE, + + 0xB0, 0x1B, 0x1C, 0xC2, 0xC4, 0x72, 0x71, 0xBF, + 0x61, 0x44, 0xD2, 0x9C, 0x4B, 0x14, 0x90, 0x14, + 0xC5, 0x89, 0x3D, 0xC7, 0x32, 0x07, 0xA7, 0xF5, + 0x64, 0xC1, 0xDD, 0x7D, 0x42, 0x2C, 0x3D, 0xDE, + 0x61, 0xDD, 0x78, 0x94, 0xB6, 0xB5, 0xF8, 0x47, + 0xEE, 0x5C, 0x2A, 0xA3, 0x32, 0xB5, 0x63, 0x3E, + 0x8C, 0xE6, 0x2F, 0x56, 0x1A, 0x24, 0xAA, 0xBD, + 0xA6, 0xAF, 0x30, 0x90, 0x7D, 0xF2, 0x73, 0x86, + 0x4D, 0x93, 0x74, 0xF1, 0xD8, 0x9B, 0x70, 0xDC, + 0xA5, 0xCC, 0xA8, 0xF9, 0x27, 0xBA, 0xA0, 0x3D, + 0x4D, 0x11, 0x19, 0xA5, 0x23, 0xE0, 0xC1, 0xC2, + 0xF7, 0x18, 0xDA, 0xCA, 0x23, 0x7E, 0x91, 0x56, + 0x72, 0xF7, 0xCE, 0xB4, 0xBF, 0x31, 0x2A, 0x61, + 0x9B, 0x7D, 0x82, 0xDF, 0xF2, 0xC7, 0x04, 0x74, + 0xD4, 0x2F, 0x14, 0x02, 0x4C, 0xC9, 0x12, 0x6D, + 0xF9, 0x67, 0x9C, 0xC5, 0x97, 0x3B, 0x9C, 0x54, + 0xA4, 0x45, 0xDA, 0xA5, 0xE8, 0xDB, 0xF7, 0x95, + 0x62, 0x0E, 0xE3, 0x25, 0x95, 0xC6, 0x68, 0xA1, + 0xBD, 0xC7, 0x78, 0xBD, 0x7E, 0xF8, 0x98, 0xDE, + 0xDA, 0x30, 0x75, 0xB6, 0xD0, 0xE1, 0x67, 0x42, + 0x6D, 0xE0, 0x26, 0x34, 0x7B, 0x47, 0x81, 0x03, + 0x96, 0x3C, 0x55, 0x8A, 0x6E, 0x73, 0x51, 0x88, + 0x1B, 0x05, 0x52, 0xDC, 0x8A, 0xA4, 0x07, 0x50, + 0x3C, 0x98, 0xC3, 0xFC, 0x58, 0xFA, 0xC8, 0x94, + 0x7D, 0x75, 0xE3, 0x4B, 0x6C, 0xCC, 0xB7, 0x9D, + 0x6F, 0xEA, 0x79, 0x4F, 0x5C, 0x77, 0xD3, 0x1B, + 0xC5, 0xB7, 0x97, 0xD7, 0xD4, 0xE9, 0x72, 0xD5, + 0x7E, 0xA3, 0xB5, 0xE9, 0xAC, 0xA0, 0x5D, 0xF8, + 0x38, 0xAC, 0x50, 0xA2, 0x47, 0x51, 0x96, 0x15, + 0x73, 0x74, 0x1B, 0x4E, 0xF2, 0x80, 0x59, 0xC6, + 0x58, 0x40, 0x3F, 0xB3, 0xE5, 0x4C, 0x62, 0x1F, + 0x65, 0xD9, 0x16, 0xBF, 0xD5, 0x45, 0x4A, 0x39, + 0xCA, 0x5A, 0x8F, 0xD2, 0x77, 0x5D, 0x96, 0x25, + 0x2E, 0xD4, 0xC3, 0x01, 0x25, 0xFB, 0x78 +}; diff --git a/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/testpoly1305.c b/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/testpoly1305.c new file mode 100644 index 00000000..3ecf1ca8 --- /dev/null +++ b/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/testpoly1305.c @@ -0,0 +1,102 @@ +/* + * cifra - embedded cryptography library + * Written in 2014 by Joseph Birr-Pixton + * + * To the extent possible under law, the author(s) have dedicated all + * copyright and related and neighboring rights to this software to the + * public domain worldwide. This software is distributed without any + * warranty. + * + * You should have received a copy of the CC0 Public Domain Dedication + * along with this software. If not, see + * . + */ + + +#include "poly1305.h" + +#include "testutil.h" +#include "handy.h" +#include "cutest.h" + +static void check(const char *rstr, const char *sstr, + const char *msgstr, const char *tagstr) +{ + uint8_t r[16], s[16], tag[16]; + uint8_t msg[132], out[16]; + + unhex(r, sizeof r, rstr); + unhex(s, sizeof s, sstr); + size_t nmsg = unhex(msg, sizeof msg, msgstr); + unhex(tag, sizeof tag, tagstr); + + cf_poly1305 ctx; + cf_poly1305_init(&ctx, r, s); + cf_poly1305_update(&ctx, msg, nmsg); + cf_poly1305_finish(&ctx, out); + + TEST_CHECK(memcmp(out, tag, 16) == 0); +} + +static void test_poly1305(void) +{ + check("eea6a7251c1e72916d11c2cb214d3c25", + "2539121d8e234e652d651fa4c8cff880", + "8e993b9f48681273c29650ba32fc76ce48332ea7164d96a4476fb8c531a1186ac0dfc17c98dce87b4da7f011ec48c97271d2c20f9b928fe2270d6fb863d51738b48eeee314a7cc8ab932164548e526ae90224368517acfeabd6bb3732bc0e9da99832b61ca01b6de56244a9e88d5f9b37973f622a43d14a6599b1f654cb45a74e355a5", + "f3ffc7703f9400e52a7dfb4b3d3305d9"); + + check("851fc40c3467ac0be05cc20404f3f700", + "580b3b0f9447bb1e69d095b5928b6dbc", + "f3f6", + "f4c633c3044fc145f84f335cb81953de"); + + check("a0f3080000f46400d0c7e9076c834403", + "dd3fab2251f11ac759f0887129cc2ee7", + "", + "dd3fab2251f11ac759f0887129cc2ee7"); + + check("48443d0bb0d21109c89a100b5ce2c208", + "83149c69b561dd88298a1798b10716ef", + "663cea190ffb83d89593f3f476b6bc24d7e679107ea26adb8caf6652d0656136", + "0ee1c16bb73f0f4fd19881753c01cdbe"); + + check("12976a08c4426d0ce8a82407c4f48207", + "80f8c20aa71202d1e29179cbcb555a57", + "ab0812724a7f1e342742cbed374d94d136c6b8795d45b3819830f2c04491faf0990c62e48b8018b2c3e4a0fa3134cb67fa83e158c994d961c4cb21095c1bf9", + "5154ad0d2cb26e01274fc51148491f1b"); + + /* extras from RFC7539 */ + check("02000000000000000000000000000000", + "00000000000000000000000000000000", + "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", + "03000000000000000000000000000000"); + check("02000000000000000000000000000000", + "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", + "02000000000000000000000000000000", + "03000000000000000000000000000000"); + check("01000000000000000000000000000000", + "00000000000000000000000000000000", + "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF11000000000000000000000000000000", + "05000000000000000000000000000000"); + check("01000000000000000000000000000000", + "00000000000000000000000000000000", + "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE01010101010101010101010101010101", + "00000000000000000000000000000000"); + check("02000000000000000000000000000000", + "00000000000000000000000000000000", + "FDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", + "FAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"); + check("01000000000000000400000000000000", + "00000000000000000000000000000000", + "E33594D7505E43B900000000000000003394D7505E4379CD01000000000000000000000000000000000000000000000001000000000000000000000000000000", + "14000000000000005500000000000000"); + check("01000000000000000400000000000000", + "00000000000000000000000000000000", + "E33594D7505E43B900000000000000003394D7505E4379CD010000000000000000000000000000000000000000000000", + "13000000000000000000000000000000"); +} + +TEST_LIST = { + { "poly1305", test_poly1305 }, + { 0 } +}; diff --git a/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/testsalsa20.c b/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/testsalsa20.c new file mode 100644 index 00000000..9d50b939 --- /dev/null +++ b/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/testsalsa20.c @@ -0,0 +1,210 @@ +/* + * cifra - embedded cryptography library + * Written in 2014 by Joseph Birr-Pixton + * + * To the extent possible under law, the author(s) have dedicated all + * copyright and related and neighboring rights to this software to the + * public domain worldwide. This software is distributed without any + * warranty. + * + * You should have received a copy of the CC0 Public Domain Dedication + * along with this software. If not, see + * . + */ + +#include "salsa20.h" + +#include "testutil.h" +#include "handy.h" +#include "cutest.h" + +static void test_salsa20_core(void) +{ + uint8_t k0[16], k1[16], nonce[16], sigma[16], out[64], expect[64]; + + /* From section 8. */ + memset(k0, 0, sizeof k0); + memset(k1, 0, sizeof k1); + memset(nonce, 0, sizeof nonce); + memset(sigma, 0, sizeof sigma); + + cf_salsa20_core(k0, k1, nonce, sigma, out); + + unhex(expect, 64, "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"); + TEST_CHECK(memcmp(expect, out, 64) == 0); + + /* + d39f0d73 + 4c3752b70375de25bfbbea8831edb330 + 016ab2db + afc7a6305610b3cf1ff0203f0f535da1 + 74933071 + ee37cc244fc9eb4f03519c2fcb1af4f3 + 58766836 + */ + unhex(k0, 16, "4c3752b70375de25bfbbea8831edb330"); + unhex(k1, 16, "ee37cc244fc9eb4f03519c2fcb1af4f3"); + unhex(nonce, 16, "afc7a6305610b3cf1ff0203f0f535da1"); + unhex(sigma, 16, "d39f0d73016ab2db7493307158766836"); + + cf_salsa20_core(k0, k1, nonce, sigma, out); + + unhex(expect, 64, "6d2ab2a89cf0f8eea8c4becb1a6eaa9a1d1d961a961eebf9bea3fb30459033397628989db4391b5e6b2aec231b6f7272dbece8876f9b6e1218e85f9eb31330ca"); + TEST_CHECK(memcmp(expect, out, 64) == 0); + + /* + 58766836 + 4fc9eb4f03519c2fcb1af4f3bfbbea88 + d39f0d73 + 4c3752b70375de255610b3cf31edb330 + 016ab2db + afc7a630ee37cc241ff0203f0f535da1 + 74933071 + */ + unhex(k0, 16, "4fc9eb4f03519c2fcb1af4f3bfbbea88"); + unhex(k1, 16, "afc7a630ee37cc241ff0203f0f535da1"); + unhex(nonce, 16, "4c3752b70375de255610b3cf31edb330"); + unhex(sigma, 16, "58766836d39f0d73016ab2db74933071"); + + cf_salsa20_core(k0, k1, nonce, sigma, out); + + unhex(expect, 64, "b31330cadbece8876f9b6e1218e85f9e1a6eaa9a6d2ab2a89cf0f8eea8c4becb459033391d1d961a961eebf9bea3fb301b6f72727628989db4391b5e6b2aec23"); + TEST_CHECK(memcmp(expect, out, 64) == 0); + + /* From section 9. */ + for (size_t i = 0; i < 16; i++) + { + k0[i] = 1 + i; + k1[i] = 201 + i; + nonce[i] = 101 + i; + } + + cf_salsa20_core(k0, k1, nonce, (const uint8_t *) "expand 32-byte k", out); + + unhex(expect, 64, "45254427290f6bc1ff8b7a06aae9d9625990b66a1533c841ef31de22d772287e68c507e1c5991f02664e4cb054f5f6b8b1a0858206489577c0c384ecea67f64a"); + TEST_CHECK(memcmp(expect, out, 64) == 0); + + cf_salsa20_core(k0, k0, nonce, (const uint8_t *) "expand 16-byte k", out); + + unhex(expect, 64, "27ad2ef81ec852113043feef25120df7f1c83d900a3732b9062ff6fd8f56bbe186556ef6a1a32bebe75eab3391d6701d0ee80510978cb78dab097ab568b6b1c1"); + TEST_CHECK(memcmp(expect, out, 64) == 0); +} + +static void test_salsa20(void) +{ + cf_salsa20_ctx ctx; + uint8_t key[32], nonce[8], cipher[64], expect[64]; + + unhex(key, 32, "0102030405060708090a0b0c0d0e0f10c9cacbcccdcecfd0d1d2d3d4d5d6d7d8"); + memset(nonce, 0, 8); + + cf_salsa20_init(&ctx, key, sizeof key, nonce); + unhex(ctx.nonce, 16, "65666768696a6b6c6d6e6f7071727374"); + memset(cipher, 0, 64); + cf_salsa20_cipher(&ctx, cipher, cipher, 64); + + unhex(expect, 64, "45254427290f6bc1ff8b7a06aae9d9625990b66a1533c841ef31de22d772287e68c507e1c5991f02664e4cb054f5f6b8b1a0858206489577c0c384ecea67f64a"); + TEST_CHECK(memcmp(expect, cipher, 64) == 0); + + cf_salsa20_init(&ctx, key, 16, nonce); + unhex(ctx.nonce, 16, "65666768696a6b6c6d6e6f7071727374"); + memset(cipher, 0, 64); + cf_salsa20_cipher(&ctx, cipher, cipher, 64); + + unhex(expect, 64, "27ad2ef81ec852113043feef25120df7f1c83d900a3732b9062ff6fd8f56bbe186556ef6a1a32bebe75eab3391d6701d0ee80510978cb78dab097ab568b6b1c1"); + TEST_CHECK(memcmp(expect, cipher, 64) == 0); +} + +static void test_chacha20_core(void) +{ + uint8_t k0[16], k1[16], nonce[16], out[64], expect[64]; + + /* From draft-agl-tls-chacha20poly1305-04 section 7. */ + + memset(k0, 0, sizeof k0); + memset(k1, 0, sizeof k1); + memset(nonce, 0, sizeof nonce); + + cf_chacha20_core(k0, k1, nonce, (const uint8_t *) "expand 32-byte k", out); + + unhex(expect, 60, "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7da41597c5157488d7724e03fb8d84a376a43b8f41518a11cc387b669"); + TEST_CHECK(memcmp(expect, out, 60) == 0); + + k1[15] = 0x01; + cf_chacha20_core(k0, k1, nonce, (const uint8_t *) "expand 32-byte k", out); + + unhex(expect, 60, "4540f05a9f1fb296d7736e7b208e3c96eb4fe1834688d2604f450952ed432d41bbe2a0b6ea7566d2a5d1e7e20d42af2c53d792b1c43fea817e9ad275"); + TEST_CHECK(memcmp(expect, out, 60) == 0); + + memset(k1, 0, sizeof k1); + nonce[15] = 0x01; + + cf_chacha20_core(k0, k1, nonce, (const uint8_t *) "expand 32-byte k", out); + + unhex(expect, 60, "de9cba7bf3d69ef5e786dc63973f653a0b49e015adbff7134fcb7df137821031e85a050278a7084527214f73efc7fa5b5277062eb7a0433e445f41e3"); + TEST_CHECK(memcmp(expect, out, 60) == 0); + + memset(nonce, 0, sizeof nonce); + nonce[8] = 0x01; + + cf_chacha20_core(k0, k1, nonce, (const uint8_t *) "expand 32-byte k", out); + + unhex(expect, 64, "ef3fdfd6c61578fbf5cf35bd3dd33b8009631634d21e42ac33960bd138e50d32111e4caf237ee53ca8ad6426194a88545ddc497a0b466e7d6bbdb0041b2f586b"); + TEST_CHECK(memcmp(expect, out, 64) == 0); + + unhex(k0, 16, "000102030405060708090a0b0c0d0e0f"); + unhex(k1, 16, "101112131415161718191a1b1c1d1e1f"); + unhex(nonce, 16, "00000000000000000001020304050607"); + + cf_chacha20_core(k0, k1, nonce, (const uint8_t *) "expand 32-byte k", out); + + unhex(expect, 64, "f798a189f195e66982105ffb640bb7757f579da31602fc93ec01ac56f85ac3c134a4547b733b46413042c9440049176905d3be59ea1c53f15916155c2be8241a"); + TEST_CHECK(memcmp(expect, out, 64) == 0); + + nonce[0]++; + cf_chacha20_core(k0, k1, nonce, (const uint8_t *) "expand 32-byte k", out); + + unhex(expect, 64, "38008b9a26bc35941e2444177c8ade6689de95264986d95889fb60e84629c9bd9a5acb1cc118be563eb9b3a4a472f82e09a7e778492b562ef7130e88dfe031c7"); + TEST_CHECK(memcmp(expect, out, 64) == 0); + + nonce[0]++; + cf_chacha20_core(k0, k1, nonce, (const uint8_t *) "expand 32-byte k", out); + + unhex(expect, 64, "9db9d4f7c7a899151b9a475032b63fc385245fe054e3dd5a97a5f576fe064025d3ce042c566ab2c507b138db853e3d6959660996546cc9c4a6eafdc777c040d7"); + TEST_CHECK(memcmp(expect, out, 64) == 0); + + nonce[0]++; + cf_chacha20_core(k0, k1, nonce, (const uint8_t *) "expand 32-byte k", out); + + unhex(expect, 64, "0eaf46f76dad3979e5c5360c3317166a1c894c94a371876a94df7628fe4eaaf2ccb27d5aaae0ad7ad0f9d4b6ad3b54098746d4524d38407a6deb3ab78fab78c9"); + TEST_CHECK(memcmp(expect, out, 64) == 0); +} + +static void test_chacha20(void) +{ + uint8_t key[32], nonce[8], block[256], expect[256]; + + unhex(key, 32, "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f"); + unhex(nonce, 8, "0001020304050607"); + unhex(expect, 256, "f798a189f195e66982105ffb640bb7757f579da31602fc93ec01ac56f85ac3c134a4547b733b46413042c9440049176905d3be59ea1c53f15916155c2be8241a38008b9a26bc35941e2444177c8ade6689de95264986d95889fb60e84629c9bd9a5acb1cc118be563eb9b3a4a472f82e09a7e778492b562ef7130e88dfe031c79db9d4f7c7a899151b9a475032b63fc385245fe054e3dd5a97a5f576fe064025d3ce042c566ab2c507b138db853e3d6959660996546cc9c4a6eafdc777c040d70eaf46f76dad3979e5c5360c3317166a1c894c94a371876a94df7628fe4eaaf2ccb27d5aaae0ad7ad0f9d4b6ad3b54098746d4524d38407a6deb3ab78fab78c9"); + memset(block, 0, 256); + + cf_chacha20_ctx ctx; + cf_chacha20_init(&ctx, key, sizeof key, nonce); + cf_chacha20_cipher(&ctx, block, block, sizeof block); + + TEST_CHECK(memcmp(expect, block, sizeof expect) == 0); + + /* Check 128-bit mode works. */ + cf_chacha20_init(&ctx, key, 16, nonce); + cf_chacha20_cipher(&ctx, block, block, sizeof block); +} + +TEST_LIST = { + { "salsa20-core", test_salsa20_core }, + { "chacha20-core", test_chacha20_core }, + { "salsa20", test_salsa20 }, + { "chacha20", test_chacha20 }, + { 0 } +}; + diff --git a/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/testsha.h b/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/testsha.h new file mode 100644 index 00000000..70075f01 --- /dev/null +++ b/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/testsha.h @@ -0,0 +1,213 @@ +/* + * cifra - embedded cryptography library + * Written in 2014 by Joseph Birr-Pixton + * + * To the extent possible under law, the author(s) have dedicated all + * copyright and related and neighboring rights to this software to the + * public domain worldwide. This software is distributed without any + * warranty. + * + * You should have received a copy of the CC0 Public Domain Dedication + * along with this software. If not, see + * . + */ + +#ifndef TESTSHA_H +#define TESTSHA_H + +#include "hmac.h" + +/* Common functions for testing hash functions. + * You shouldn't use this file. */ + +static void vector(const cf_chash *hash, + const void *vmsg, size_t nmsg, + const char *expect, size_t nexpect) +{ + uint8_t digest[CF_MAXHASH]; + const uint8_t *msg = vmsg; + size_t orig_nmsg = nmsg; + + cf_chash_ctx ctx; + hash->init(&ctx); + + /* Input in carefully chosen chunk sizes to exercise blockwise code. */ + if (nmsg) + { + hash->update(&ctx, msg, 1); + nmsg--; + msg++; + } + + hash->update(&ctx, msg, nmsg); + hash->digest(&ctx, digest); + TEST_CHECK(nexpect == hash->hashsz); + TEST_CHECK(memcmp(digest, expect, nexpect) == 0); + + /* Now try with other arrangements. */ + msg = vmsg; + nmsg = orig_nmsg; + + hash->init(&ctx); + if (nmsg >= hash->blocksz) + { + hash->update(&ctx, msg, hash->blocksz - 1); + nmsg -= hash->blocksz - 1; + msg += hash->blocksz - 1; + } + + hash->update(&ctx, msg, nmsg); + hash->digest(&ctx, digest); + TEST_CHECK(memcmp(digest, expect, nexpect) == 0); +} + +/* These are shared between RFC2202 and RFC4231. */ +static inline void hmac_test(const cf_chash *hash, + const void *hi_there, + const void *jefe, + const void *aa_dd, + const void *counter_key) +{ + uint8_t sig[CF_MAXHASH]; + uint8_t key[25], message[50]; + + /* Key: 0x0b * 20 + * Message: "Hi There" + */ + memset(key, 0x0b, 20); + memcpy(message, "Hi There", 8); + cf_hmac(key, 20, message, 8, sig, hash); + + TEST_CHECK(memcmp(sig, hi_there, hash->hashsz) == 0); + + /* Key: "Jefe" + * Message: "what do ya want for nothing?" + */ + memcpy(key, "Jefe", 4); + memcpy(message, "what do ya want for nothing?", 28); + cf_hmac(key, 4, message, 28, sig, hash); + TEST_CHECK(memcmp(sig, jefe, hash->hashsz) == 0); + + /* Key: 0xaa * 20 + * Message: 0xdd * 50 + */ + memset(key, 0xaa, 20); + memset(message, 0xdd, 50); + cf_hmac(key, 20, message, 50, sig, hash); + TEST_CHECK(memcmp(sig, aa_dd, hash->hashsz) == 0); + + /* Key: 0x01..0x19 + * Message: 0xcd * 50 + */ + for (uint8_t i = 1; i < 26; i++) + key[i - 1] = i; + memset(message, 0xcd, 50); + cf_hmac(key, 25, message, 50, sig, hash); + TEST_CHECK(memcmp(sig, counter_key, hash->hashsz) == 0); +} + +/* These are specific to RFC4231. */ +static inline void hmac_test_sha2(const cf_chash *hash, + const char *long_key, + const char *long_message) +{ + uint8_t sig[CF_MAXHASH]; + uint8_t key[131], message[152]; + + /* Key: 0xaa * 131 + * Message: "Test Using Larger Than Block-Size Key - Hash Key First" + */ + memset(key, 0xaa, 131); + memcpy(message, "Test Using Larger Than Block-Size Key - Hash Key First", 54); + cf_hmac(key, 131, message, 54, sig, hash); + TEST_CHECK(memcmp(sig, long_key, hash->hashsz) == 0); + + /* Key: 0xaa * 131 + * Message: "This is a test using a larger than block-size key and a larger than block-size data. The key needs to be hashed before being used by the HMAC algorithm." + */ + memset(key, 0xaa, 131); + memcpy(message, "This is a test using a larger than block-size key and a larger than block-size data. The key needs to be hashed before being used by the HMAC algorithm.", 152); + cf_hmac(key, 131, message, 152, sig, hash); + TEST_CHECK(memcmp(sig, long_message, hash->hashsz) == 0); +} + +/* This is as hmac_test_sha2, except the sizes are specific to + * a 512-bit block. This is from RFC2202. */ +static inline void hmac_test_sha1(const cf_chash *hash, + const char *long_key, + const char *long_message) +{ + uint8_t sig[CF_MAXHASH]; + uint8_t key[80], message[73]; + + /* Key: 0xaa * 80 + * Message: "Test Using Larger Than Block-Size Key - Hash Key First" + */ + memset(key, 0xaa, 80); + memcpy(message, "Test Using Larger Than Block-Size Key - Hash Key First", 54); + cf_hmac(key, 80, message, 54, sig, hash); + TEST_CHECK(memcmp(sig, long_key, hash->hashsz) == 0); + + /* Key: 0xaa * 80 + * Message: "Test Using Larger Than Block-Size Key and Larger Than One Block-Size Data" + */ + memset(key, 0xaa, 80); + memcpy(message, "Test Using Larger Than Block-Size Key and Larger Than One Block-Size Data", 73); + cf_hmac(key, 80, message, 73, sig, hash); + TEST_CHECK(memcmp(sig, long_message, hash->hashsz) == 0); +} + +typedef void (*final_fn)(void *ctx, uint8_t *out); + +/* Check incremental interface works, and final function likewise. */ +static void vector_abc_final(const cf_chash *hash, const void *vfinal_fn, + const void *expect, size_t nexpect) +{ + uint8_t digest[CF_MAXHASH]; + + final_fn final = vfinal_fn; + cf_chash_ctx ctx; + hash->init(&ctx); + hash->update(&ctx, "a", 1); + hash->digest(&ctx, digest); + hash->update(&ctx, "b", 1); + hash->digest(&ctx, digest); + hash->update(&ctx, "c", 1); + final(&ctx, digest); + + TEST_CHECK(hash->hashsz == nexpect); + TEST_CHECK(memcmp(expect, digest, nexpect) == 0); +} + +/* Check length-checking vectors work (generated by programs in ../extra_vecs) */ +static inline void vector_length(const cf_chash *h, + size_t max, + const void *expect, size_t nexpect) +{ + cf_chash_ctx outer, inner; + uint8_t digest[CF_MAXHASH]; + + h->init(&outer); + + for (size_t n = 0; n < max; n++) + { + h->init(&inner); + + for (size_t i = 0; i < n; i++) + { + uint8_t byte = (uint8_t) n & 0xff; + h->update(&inner, &byte, 1); + } + + h->digest(&inner, digest); + + h->update(&outer, digest, h->hashsz); + } + + h->digest(&outer, digest); + + TEST_CHECK(h->hashsz == nexpect); + TEST_CHECK(memcmp(expect, digest, nexpect) == 0); +} + +#endif diff --git a/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/testsha1.c b/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/testsha1.c new file mode 100644 index 00000000..c7adc8a4 --- /dev/null +++ b/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/testsha1.c @@ -0,0 +1,55 @@ +/* + * cifra - embedded cryptography library + * Written in 2014 by Joseph Birr-Pixton + * + * To the extent possible under law, the author(s) have dedicated all + * copyright and related and neighboring rights to this software to the + * public domain worldwide. This software is distributed without any + * warranty. + * + * You should have received a copy of the CC0 Public Domain Dedication + * along with this software. If not, see + * . + */ + +#include "sha1.h" +#include "hmac.h" +#include "handy.h" +#include "cutest.h" +#include "testutil.h" + +#include "testsha.h" + +static void test_sha1(void) +{ + const cf_chash *h = &cf_sha1; + vector(h, "", 0, "\xda\x39\xa3\xee\x5e\x6b\x4b\x0d\x32\x55\xbf\xef\x95\x60\x18\x90\xaf\xd8\x07\x09", 20); + vector(h, "abc", 3, "\xa9\x99\x3e\x36\x47\x06\x81\x6a\xba\x3e\x25\x71\x78\x50\xc2\x6c\x9c\xd0\xd8\x9d", 20); + vector(h, "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", 56, + "\x84\x98\x3e\x44\x1c\x3b\xd2\x6e\xba\xae\x4a\xa1\xf9\x51\x29\xe5\xe5\x46\x70\xf1", 20); + vector(h, "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu", 112, + "\xa4\x9b\x24\x46\xa0\x2c\x64\x5b\xf4\x19\xf9\x95\xb6\x70\x91\x25\x3a\x04\xa2\x59", 20); + + vector_abc_final(h, cf_sha1_digest_final, "\xa9\x99\x3e\x36\x47\x06\x81\x6a\xba\x3e\x25\x71\x78\x50\xc2\x6c\x9c\xd0\xd8\x9d", 20); + + vector_length(h, 1024, "\x15\x53\x65\xcf\x77\xee\xd4\x8f\x46\xe2\x55\xc7\xdd\xdf\xfd\x0a\xf6\x99\x88\xbe", 20); +} + +static void test_hmac_sha1(void) +{ + hmac_test(&cf_sha1, + "\xb6\x17\x31\x86\x55\x05\x72\x64\xe2\x8b\xc0\xb6\xfb\x37\x8c\x8e\xf1\x46\xbe\x00", + "\xef\xfc\xdf\x6a\xe5\xeb\x2f\xa2\xd2\x74\x16\xd5\xf1\x84\xdf\x9c\x25\x9a\x7c\x79", + "\x12\x5d\x73\x42\xb9\xac\x11\xcd\x91\xa3\x9a\xf4\x8a\xa1\x7b\x4f\x63\xf1\x75\xd3", + "\x4c\x90\x07\xf4\x02\x62\x50\xc6\xbc\x84\x14\xf9\xbf\x50\xc8\x6c\x2d\x72\x35\xda"); + hmac_test_sha1(&cf_sha1, + "\xaa\x4a\xe5\xe1\x52\x72\xd0\x0e\x95\x70\x56\x37\xce\x8a\x3b\x55\xed\x40\x21\x12", + "\xe8\xe9\x9d\x0f\x45\x23\x7d\x78\x6d\x6b\xba\xa7\x96\x5c\x78\x08\xbb\xff\x1a\x91"); +} + +TEST_LIST = { + { "sha1", test_sha1}, + { "hmac-sha1", test_hmac_sha1}, + { 0 } +}; + diff --git a/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/testsha2.c b/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/testsha2.c new file mode 100644 index 00000000..fc0ab6c8 --- /dev/null +++ b/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/testsha2.c @@ -0,0 +1,224 @@ +/* + * cifra - embedded cryptography library + * Written in 2014 by Joseph Birr-Pixton + * + * To the extent possible under law, the author(s) have dedicated all + * copyright and related and neighboring rights to this software to the + * public domain worldwide. This software is distributed without any + * warranty. + * + * You should have received a copy of the CC0 Public Domain Dedication + * along with this software. If not, see + * . + */ + +#include "sha2.h" +#include "hmac.h" +#include "pbkdf2.h" +#include "handy.h" +#include "cutest.h" +#include "testutil.h" + +#include "testsha.h" + +#undef REALLY_SLOW_TEST + +static void test_sha224(void) +{ + const cf_chash *h = &cf_sha224; + vector(h, "", 0, "\xd1\x4a\x02\x8c\x2a\x3a\x2b\xc9\x47\x61\x02\xbb\x28\x82\x34\xc4\x15\xa2\xb0\x1f\x82\x8e\xa6\x2a\xc5\xb3\xe4\x2f", 28); + vector(h, "abc", 3, "\x23\x09\x7d\x22\x34\x05\xd8\x22\x86\x42\xa4\x77\xbd\xa2\x55\xb3\x2a\xad\xbc\xe4\xbd\xa0\xb3\xf7\xe3\x6c\x9d\xa7", 28); + vector(h, "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", 56, + "\x75\x38\x8b\x16\x51\x27\x76\xcc\x5d\xba\x5d\xa1\xfd\x89\x01\x50\xb0\xc6\x45\x5c\xb4\xf5\x8b\x19\x52\x52\x25\x25", 28); + vector(h, "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu", 112, + "\xc9\x7c\xa9\xa5\x59\x85\x0c\xe9\x7a\x04\xa9\x6d\xef\x6d\x99\xa9\xe0\xe0\xe2\xab\x14\xe6\xb8\xdf\x26\x5f\xc0\xb3", 28); + + /* Check that incremental interface produces correct results. */ + vector_abc_final(h, cf_sha224_digest_final, "\x23\x09\x7d\x22\x34\x05\xd8\x22\x86\x42\xa4\x77\xbd\xa2\x55\xb3\x2a\xad\xbc\xe4\xbd\xa0\xb3\xf7\xe3\x6c\x9d\xa7", 28); + + vector_length(h, 1024, "\x08\x2c\x80\x5b\x6f\x85\xde\x0e\xdf\xa8\x51\xa0\x1f\xe6\x4f\x64\x85\x16\x48\xae\xfc\xc1\xd4\x52\x4e\xf8\x36\xe7", 28); +} + +static void test_hmac_sha224(void) +{ + hmac_test(&cf_sha224, + "\x89\x6f\xb1\x12\x8a\xbb\xdf\x19\x68\x32\x10\x7c\xd4\x9d\xf3\x3f\x47\xb4\xb1\x16\x99\x12\xba\x4f\x53\x68\x4b\x22", + "\xa3\x0e\x01\x09\x8b\xc6\xdb\xbf\x45\x69\x0f\x3a\x7e\x9e\x6d\x0f\x8b\xbe\xa2\xa3\x9e\x61\x48\x00\x8f\xd0\x5e\x44", + "\x7f\xb3\xcb\x35\x88\xc6\xc1\xf6\xff\xa9\x69\x4d\x7d\x6a\xd2\x64\x93\x65\xb0\xc1\xf6\x5d\x69\xd1\xec\x83\x33\xea", + "\x6c\x11\x50\x68\x74\x01\x3c\xac\x6a\x2a\xbc\x1b\xb3\x82\x62\x7c\xec\x6a\x90\xd8\x6e\xfc\x01\x2d\xe7\xaf\xec\x5a"); + hmac_test_sha2(&cf_sha224, + "\x95\xe9\xa0\xdb\x96\x20\x95\xad\xae\xbe\x9b\x2d\x6f\x0d\xbc\xe2\xd4\x99\xf1\x12\xf2\xd2\xb7\x27\x3f\xa6\x87\x0e", + "\x3a\x85\x41\x66\xac\x5d\x9f\x02\x3f\x54\xd5\x17\xd0\xb3\x9d\xbd\x94\x67\x70\xdb\x9c\x2b\x95\xc9\xf6\xf5\x65\xd1"); +} + +static void test_sha256(void) +{ + const cf_chash *h = &cf_sha256; + vector(h, "", 0, "\xe3\xb0\xc4\x42\x98\xfc\x1c\x14\x9a\xfb\xf4\xc8\x99\x6f\xb9\x24\x27\xae\x41\xe4\x64\x9b\x93\x4c\xa4\x95\x99\x1b\x78\x52\xb8\x55", 32); + vector(h, "abc", 3, "\xba\x78\x16\xbf\x8f\x01\xcf\xea\x41\x41\x40\xde\x5d\xae\x22\x23\xb0\x03\x61\xa3\x96\x17\x7a\x9c\xb4\x10\xff\x61\xf2\x00\x15\xad", 32); + vector(h, "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", 56, + "\x24\x8d\x6a\x61\xd2\x06\x38\xb8\xe5\xc0\x26\x93\x0c\x3e\x60\x39\xa3\x3c\xe4\x59\x64\xff\x21\x67\xf6\xec\xed\xd4\x19\xdb\x06\xc1", 32); + vector(h, "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu", 112, + "\xcf\x5b\x16\xa7\x78\xaf\x83\x80\x03\x6c\xe5\x9e\x7b\x04\x92\x37\x0b\x24\x9b\x11\xe8\xf0\x7a\x51\xaf\xac\x45\x03\x7a\xfe\xe9\xd1", 32); + + vector_abc_final(h, cf_sha256_digest_final, "\xba\x78\x16\xbf\x8f\x01\xcf\xea\x41\x41\x40\xde\x5d\xae\x22\x23\xb0\x03\x61\xa3\x96\x17\x7a\x9c\xb4\x10\xff\x61\xf2\x00\x15\xad", 32); + + vector_length(h, 1024, "\x55\x7b\xfd\xd5\xef\xda\xfd\x63\x06\x5e\xb7\x98\x87\xde\x86\xdb\x54\xc3\xfe\xdf\x7b\xcc\xcb\x97\x08\xfa\x87\xf0\x11\x87\x61\xdc", 32); +} + +static void test_hmac_sha256(void) +{ + hmac_test(&cf_sha256, + "\xb0\x34\x4c\x61\xd8\xdb\x38\x53\x5c\xa8\xaf\xce\xaf\x0b\xf1\x2b\x88\x1d\xc2\x00\xc9\x83\x3d\xa7\x26\xe9\x37\x6c\x2e\x32\xcf\xf7", + "\x5b\xdc\xc1\x46\xbf\x60\x75\x4e\x6a\x04\x24\x26\x08\x95\x75\xc7\x5a\x00\x3f\x08\x9d\x27\x39\x83\x9d\xec\x58\xb9\x64\xec\x38\x43", + "\x77\x3e\xa9\x1e\x36\x80\x0e\x46\x85\x4d\xb8\xeb\xd0\x91\x81\xa7\x29\x59\x09\x8b\x3e\xf8\xc1\x22\xd9\x63\x55\x14\xce\xd5\x65\xfe", + "\x82\x55\x8a\x38\x9a\x44\x3c\x0e\xa4\xcc\x81\x98\x99\xf2\x08\x3a\x85\xf0\xfa\xa3\xe5\x78\xf8\x07\x7a\x2e\x3f\xf4\x67\x29\x66\x5b"); + hmac_test_sha2(&cf_sha256, + "\x60\xe4\x31\x59\x1e\xe0\xb6\x7f\x0d\x8a\x26\xaa\xcb\xf5\xb7\x7f\x8e\x0b\xc6\x21\x37\x28\xc5\x14\x05\x46\x04\x0f\x0e\xe3\x7f\x54", + "\x9b\x09\xff\xa7\x1b\x94\x2f\xcb\x27\x63\x5f\xbc\xd5\xb0\xe9\x44\xbf\xdc\x63\x64\x4f\x07\x13\x93\x8a\x7f\x51\x53\x5c\x3a\x35\xe2"); +} + +static void test_sha384(void) +{ + const cf_chash *h = &cf_sha384; + vector(h, "", 0, "\x38\xb0\x60\xa7\x51\xac\x96\x38\x4c\xd9\x32\x7e\xb1\xb1\xe3\x6a\x21\xfd\xb7\x11\x14\xbe\x07\x43\x4c\x0c\xc7\xbf\x63\xf6\xe1\xda\x27\x4e\xde\xbf\xe7\x6f\x65\xfb\xd5\x1a\xd2\xf1\x48\x98\xb9\x5b", 48); + vector(h, "abc", 3, "\xcb\x00\x75\x3f\x45\xa3\x5e\x8b\xb5\xa0\x3d\x69\x9a\xc6\x50\x07\x27\x2c\x32\xab\x0e\xde\xd1\x63\x1a\x8b\x60\x5a\x43\xff\x5b\xed\x80\x86\x07\x2b\xa1\xe7\xcc\x23\x58\xba\xec\xa1\x34\xc8\x25\xa7", 48); + vector(h, "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", 56, + "\x33\x91\xfd\xdd\xfc\x8d\xc7\x39\x37\x07\xa6\x5b\x1b\x47\x09\x39\x7c\xf8\xb1\xd1\x62\xaf\x05\xab\xfe\x8f\x45\x0d\xe5\xf3\x6b\xc6\xb0\x45\x5a\x85\x20\xbc\x4e\x6f\x5f\xe9\x5b\x1f\xe3\xc8\x45\x2b", 48); + vector(h, "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu", 112, + "\x09\x33\x0c\x33\xf7\x11\x47\xe8\x3d\x19\x2f\xc7\x82\xcd\x1b\x47\x53\x11\x1b\x17\x3b\x3b\x05\xd2\x2f\xa0\x80\x86\xe3\xb0\xf7\x12\xfc\xc7\xc7\x1a\x55\x7e\x2d\xb9\x66\xc3\xe9\xfa\x91\x74\x60\x39", 48); + + vector_abc_final(h, cf_sha384_digest_final, "\xcb\x00\x75\x3f\x45\xa3\x5e\x8b\xb5\xa0\x3d\x69\x9a\xc6\x50\x07\x27\x2c\x32\xab\x0e\xde\xd1\x63\x1a\x8b\x60\x5a\x43\xff\x5b\xed\x80\x86\x07\x2b\xa1\xe7\xcc\x23\x58\xba\xec\xa1\x34\xc8\x25\xa7", 48); + + vector_length(h, 1024, "\xae\xe7\xf1\x43\xef\x69\x7b\xa2\xe1\xfd\x39\x9f\xd7\xe6\x28\x9c\x19\xaf\x3c\xc1\xbd\xda\xbd\x3f\x07\xae\xc2\xea\x40\x55\x37\x27\x5f\x41\x49\x50\x3f\xcc\xaf\xa0\xc5\x95\xf7\x62\x9b\xff\x50\x32", 48); +} + +static void test_hmac_sha384(void) +{ + hmac_test(&cf_sha384, + "\xaf\xd0\x39\x44\xd8\x48\x95\x62\x6b\x08\x25\xf4\xab\x46\x90\x7f\x15\xf9\xda\xdb\xe4\x10\x1e\xc6\x82\xaa\x03\x4c\x7c\xeb\xc5\x9c\xfa\xea\x9e\xa9\x07\x6e\xde\x7f\x4a\xf1\x52\xe8\xb2\xfa\x9c\xb6", + "\xaf\x45\xd2\xe3\x76\x48\x40\x31\x61\x7f\x78\xd2\xb5\x8a\x6b\x1b\x9c\x7e\xf4\x64\xf5\xa0\x1b\x47\xe4\x2e\xc3\x73\x63\x22\x44\x5e\x8e\x22\x40\xca\x5e\x69\xe2\xc7\x8b\x32\x39\xec\xfa\xb2\x16\x49", + "\x88\x06\x26\x08\xd3\xe6\xad\x8a\x0a\xa2\xac\xe0\x14\xc8\xa8\x6f\x0a\xa6\x35\xd9\x47\xac\x9f\xeb\xe8\x3e\xf4\xe5\x59\x66\x14\x4b\x2a\x5a\xb3\x9d\xc1\x38\x14\xb9\x4e\x3a\xb6\xe1\x01\xa3\x4f\x27", + "\x3e\x8a\x69\xb7\x78\x3c\x25\x85\x19\x33\xab\x62\x90\xaf\x6c\xa7\x7a\x99\x81\x48\x08\x50\x00\x9c\xc5\x57\x7c\x6e\x1f\x57\x3b\x4e\x68\x01\xdd\x23\xc4\xa7\xd6\x79\xcc\xf8\xa3\x86\xc6\x74\xcf\xfb"); + hmac_test_sha2(&cf_sha384, + "\x4e\xce\x08\x44\x85\x81\x3e\x90\x88\xd2\xc6\x3a\x04\x1b\xc5\xb4\x4f\x9e\xf1\x01\x2a\x2b\x58\x8f\x3c\xd1\x1f\x05\x03\x3a\xc4\xc6\x0c\x2e\xf6\xab\x40\x30\xfe\x82\x96\x24\x8d\xf1\x63\xf4\x49\x52", + "\x66\x17\x17\x8e\x94\x1f\x02\x0d\x35\x1e\x2f\x25\x4e\x8f\xd3\x2c\x60\x24\x20\xfe\xb0\xb8\xfb\x9a\xdc\xce\xbb\x82\x46\x1e\x99\xc5\xa6\x78\xcc\x31\xe7\x99\x17\x6d\x38\x60\xe6\x11\x0c\x46\x52\x3e"); +} + +static void test_sha512(void) +{ + const cf_chash *h = &cf_sha512; + vector(h, "", 0, "\xcf\x83\xe1\x35\x7e\xef\xb8\xbd\xf1\x54\x28\x50\xd6\x6d\x80\x07\xd6\x20\xe4\x05\x0b\x57\x15\xdc\x83\xf4\xa9\x21\xd3\x6c\xe9\xce\x47\xd0\xd1\x3c\x5d\x85\xf2\xb0\xff\x83\x18\xd2\x87\x7e\xec\x2f\x63\xb9\x31\xbd\x47\x41\x7a\x81\xa5\x38\x32\x7a\xf9\x27\xda\x3e", 64); + vector(h, "abc", 3, "\xdd\xaf\x35\xa1\x93\x61\x7a\xba\xcc\x41\x73\x49\xae\x20\x41\x31\x12\xe6\xfa\x4e\x89\xa9\x7e\xa2\x0a\x9e\xee\xe6\x4b\x55\xd3\x9a\x21\x92\x99\x2a\x27\x4f\xc1\xa8\x36\xba\x3c\x23\xa3\xfe\xeb\xbd\x45\x4d\x44\x23\x64\x3c\xe8\x0e\x2a\x9a\xc9\x4f\xa5\x4c\xa4\x9f", 64); + vector(h, "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", 56, + "\x20\x4a\x8f\xc6\xdd\xa8\x2f\x0a\x0c\xed\x7b\xeb\x8e\x08\xa4\x16\x57\xc1\x6e\xf4\x68\xb2\x28\xa8\x27\x9b\xe3\x31\xa7\x03\xc3\x35\x96\xfd\x15\xc1\x3b\x1b\x07\xf9\xaa\x1d\x3b\xea\x57\x78\x9c\xa0\x31\xad\x85\xc7\xa7\x1d\xd7\x03\x54\xec\x63\x12\x38\xca\x34\x45", 64); + vector(h, "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu", 112, + "\x8e\x95\x9b\x75\xda\xe3\x13\xda\x8c\xf4\xf7\x28\x14\xfc\x14\x3f\x8f\x77\x79\xc6\xeb\x9f\x7f\xa1\x72\x99\xae\xad\xb6\x88\x90\x18\x50\x1d\x28\x9e\x49\x00\xf7\xe4\x33\x1b\x99\xde\xc4\xb5\x43\x3a\xc7\xd3\x29\xee\xb6\xdd\x26\x54\x5e\x96\xe5\x5b\x87\x4b\xe9\x09", 64); + + vector_abc_final(h, cf_sha512_digest_final, "\xdd\xaf\x35\xa1\x93\x61\x7a\xba\xcc\x41\x73\x49\xae\x20\x41\x31\x12\xe6\xfa\x4e\x89\xa9\x7e\xa2\x0a\x9e\xee\xe6\x4b\x55\xd3\x9a\x21\x92\x99\x2a\x27\x4f\xc1\xa8\x36\xba\x3c\x23\xa3\xfe\xeb\xbd\x45\x4d\x44\x23\x64\x3c\xe8\x0e\x2a\x9a\xc9\x4f\xa5\x4c\xa4\x9f", 64); + + vector_length(h, 1024, "\x61\x20\x81\x2e\xd5\x0c\xc3\x11\x67\x04\x3f\x1f\x06\x9d\xcd\x4a\xd8\x83\x23\xd9\x96\x53\xd9\x67\x38\x2c\xc3\x44\x25\x69\x53\x1c\xd0\x3d\xe4\x79\x0a\x71\xde\x88\x45\x44\x66\x80\xb8\xc5\x90\xb3\x07\xc8\xae\x52\x57\x67\xf9\x28\xf8\xda\x9e\x9e\x80\xc9\x35\x5e", 64); +} + +static void test_hmac_sha512(void) +{ + hmac_test(&cf_sha512, + "\x87\xaa\x7c\xde\xa5\xef\x61\x9d\x4f\xf0\xb4\x24\x1a\x1d\x6c\xb0\x23\x79\xf4\xe2\xce\x4e\xc2\x78\x7a\xd0\xb3\x05\x45\xe1\x7c\xde\xda\xa8\x33\xb7\xd6\xb8\xa7\x02\x03\x8b\x27\x4e\xae\xa3\xf4\xe4\xbe\x9d\x91\x4e\xeb\x61\xf1\x70\x2e\x69\x6c\x20\x3a\x12\x68\x54", + "\x16\x4b\x7a\x7b\xfc\xf8\x19\xe2\xe3\x95\xfb\xe7\x3b\x56\xe0\xa3\x87\xbd\x64\x22\x2e\x83\x1f\xd6\x10\x27\x0c\xd7\xea\x25\x05\x54\x97\x58\xbf\x75\xc0\x5a\x99\x4a\x6d\x03\x4f\x65\xf8\xf0\xe6\xfd\xca\xea\xb1\xa3\x4d\x4a\x6b\x4b\x63\x6e\x07\x0a\x38\xbc\xe7\x37", + "\xfa\x73\xb0\x08\x9d\x56\xa2\x84\xef\xb0\xf0\x75\x6c\x89\x0b\xe9\xb1\xb5\xdb\xdd\x8e\xe8\x1a\x36\x55\xf8\x3e\x33\xb2\x27\x9d\x39\xbf\x3e\x84\x82\x79\xa7\x22\xc8\x06\xb4\x85\xa4\x7e\x67\xc8\x07\xb9\x46\xa3\x37\xbe\xe8\x94\x26\x74\x27\x88\x59\xe1\x32\x92\xfb", + "\xb0\xba\x46\x56\x37\x45\x8c\x69\x90\xe5\xa8\xc5\xf6\x1d\x4a\xf7\xe5\x76\xd9\x7f\xf9\x4b\x87\x2d\xe7\x6f\x80\x50\x36\x1e\xe3\xdb\xa9\x1c\xa5\xc1\x1a\xa2\x5e\xb4\xd6\x79\x27\x5c\xc5\x78\x80\x63\xa5\xf1\x97\x41\x12\x0c\x4f\x2d\xe2\xad\xeb\xeb\x10\xa2\x98\xdd"); + hmac_test_sha2(&cf_sha512, + "\x80\xb2\x42\x63\xc7\xc1\xa3\xeb\xb7\x14\x93\xc1\xdd\x7b\xe8\xb4\x9b\x46\xd1\xf4\x1b\x4a\xee\xc1\x12\x1b\x01\x37\x83\xf8\xf3\x52\x6b\x56\xd0\x37\xe0\x5f\x25\x98\xbd\x0f\xd2\x21\x5d\x6a\x1e\x52\x95\xe6\x4f\x73\xf6\x3f\x0a\xec\x8b\x91\x5a\x98\x5d\x78\x65\x98", + "\xe3\x7b\x6a\x77\x5d\xc8\x7d\xba\xa4\xdf\xa9\xf9\x6e\x5e\x3f\xfd\xde\xbd\x71\xf8\x86\x72\x89\x86\x5d\xf5\xa3\x2d\x20\xcd\xc9\x44\xb6\x02\x2c\xac\x3c\x49\x82\xb1\x0d\x5e\xeb\x55\xc3\xe4\xde\x15\x13\x46\x76\xfb\x6d\xe0\x44\x60\x65\xc9\x74\x40\xfa\x8c\x6a\x58"); +} + +#ifdef REALLY_SLOW_TEST +static void test_sha256_long(void) +{ + uint8_t digest[32]; + cf_sha256_context ctx; + cf_sha256_init(&ctx); + + for (size_t i = 0; i < 0x1000000; i++) + cf_sha256_update(&ctx, "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmno", 64); + cf_sha256_digest_final(&ctx, digest); + + uint8_t expect[32]; + unhex(expect, sizeof expect, "\x50\xe7\x2a\x0e\x26\x44\x2f\xe2\x55\x2d\xc3\x93\x8a\xc5\x86\x58\x22\x8c\x0c\xbf\xb1\xd2\xca\x87\x2a\xe4\x35\x26\x6f\xcd\x05\x5e", 32); + TEST_CHECK(memcmp(expect, digest, sizeof digest) == 0); +} +#endif + +static void check_pkbdf2_sha256(const void *pw, size_t npw, + const void *salt, size_t nsalt, + uint32_t iters, + const void *expect, size_t nexpect) +{ + uint8_t output[64]; + + cf_pbkdf2_hmac((const void *) pw, npw, + (const void *) salt, nsalt, + iters, + output, nexpect, + &cf_sha256); + + TEST_CHECK(memcmp(expect, output, nexpect) == 0); +} + +static void test_pbkdf2_sha256(void) +{ + check_pkbdf2_sha256("password", 8, + "salt", 4, + 1, + "\x12\x0f\xb6\xcf\xfc\xf8\xb3\x2c\x43\xe7\x22\x52\x56\xc4\xf8\x37\xa8\x65\x48\xc9\x2c\xcc\x35\x48\x08\x05\x98\x7c\xb7\x0b\xe1\x7b", 32); + + check_pkbdf2_sha256("password", 8, + "salt", 4, + 2, + "\xae\x4d\x0c\x95\xaf\x6b\x46\xd3\x2d\x0a\xdf\xf9\x28\xf0\x6d\xd0\x2a\x30\x3f\x8e\xf3\xc2\x51\xdf\xd6\xe2\xd8\x5a\x95\x47\x4c\x43", 32); + + check_pkbdf2_sha256("password", 8, + "salt", 4, + 4096, + "\xc5\xe4\x78\xd5\x92\x88\xc8\x41\xaa\x53\x0d\xb6\x84\x5c\x4c\x8d\x96\x28\x93\xa0\x01\xce\x4e\x11\xa4\x96\x38\x73\xaa\x98\x13\x4a", 32); + + check_pkbdf2_sha256("passwordPASSWORDpassword", 24, + "saltSALTsaltSALTsaltSALTsaltSALTsalt", 36, + 4096, + "\x34\x8c\x89\xdb\xcb\xd3\x2b\x2f\x32\xd8\x14\xb8\x11\x6e\x84\xcf\x2b\x17\x34\x7e\xbc\x18\x00\x18\x1c\x4e\x2a\x1f\xb8\xdd\x53\xe1\xc6\x35\x51\x8c\x7d\xac\x47\xe9", 40); + + check_pkbdf2_sha256("", 0, + "salt", 4, + 1024, + "\x9e\x83\xf2\x79\xc0\x40\xf2\xa1\x1a\xa4\xa0\x2b\x24\xc4\x18\xf2\xd3\xcb\x39\x56\x0c\x96\x27\xfa\x4f\x47\xe3\xbc\xc2\x89\x7c\x3d", 32); + + check_pkbdf2_sha256("password", 8, + "", 0, + 1024, + "\xea\x58\x08\x41\x1e\xb0\xc7\xe8\x30\xde\xab\x55\x09\x6c\xee\x58\x27\x61\xe2\x2a\x9b\xc0\x34\xe3\xec\xe9\x25\x22\x5b\x07\xbf\x46", 32); + + check_pkbdf2_sha256("\x70\x61\x73\x73\x00\x77\x6f\x72\x64", 9, + "\x73\x61\x00\x6c\x74", 5, + 4096, + "\x89\xb6\x9d\x05\x16\xf8\x29\x89\x3c\x69\x62\x26\x65\x0a\x86\x87", 16); +} + +TEST_LIST = { + { "sha224", test_sha224}, + { "sha256", test_sha256 }, + { "sha384", test_sha384 }, + { "sha512", test_sha512 }, + + { "hmac-sha224", test_hmac_sha224 }, + { "hmac-sha256", test_hmac_sha256 }, + { "hmac-sha384", test_hmac_sha384 }, + { "hmac-sha512", test_hmac_sha512 }, + + { "pbkdf2-sha256", test_pbkdf2_sha256 }, + +#ifdef REALLY_SLOW_TEST + { "sha256-long", test_sha256_long }, +#endif + { 0 } +}; + diff --git a/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/testsha3.c b/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/testsha3.c new file mode 100644 index 00000000..92ab9cf0 --- /dev/null +++ b/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/testsha3.c @@ -0,0 +1,104 @@ +/* + * cifra - embedded cryptography library + * Written in 2014 by Joseph Birr-Pixton + * + * To the extent possible under law, the author(s) have dedicated all + * copyright and related and neighboring rights to this software to the + * public domain worldwide. This software is distributed without any + * warranty. + * + * You should have received a copy of the CC0 Public Domain Dedication + * along with this software. If not, see + * . + */ + +#include "sha3.h" +#include "handy.h" +#include "cutest.h" +#include "testutil.h" +#include "testsha.h" + +static void test_sha3_224(void) +{ + const cf_chash *H = &cf_sha3_224; + vector(H, "", 0, + "\x6b\x4e\x03\x42\x36\x67\xdb\xb7\x3b\x6e\x15\x45\x4f\x0e\xb1\xab\xd4\x59\x7f\x9a\x1b\x07\x8e\x3f\x5b\x5a\x6b\xc7", 28); + vector(H, "abc", 3, + "\xe6\x42\x82\x4c\x3f\x8c\xf2\x4a\xd0\x92\x34\xee\x7d\x3c\x76\x6f\xc9\xa3\xa5\x16\x8d\x0c\x94\xad\x73\xb4\x6f\xdf", 28); + vector(H, "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", 56, + "\x8a\x24\x10\x8b\x15\x4a\xda\x21\xc9\xfd\x55\x74\x49\x44\x79\xba\x5c\x7e\x7a\xb7\x6e\xf2\x64\xea\xd0\xfc\xce\x33", 28); + vector(H, "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu", 112, + "\x54\x3e\x68\x68\xe1\x66\x6c\x1a\x64\x36\x30\xdf\x77\x36\x7a\xe5\xa6\x2a\x85\x07\x0a\x51\xc1\x4c\xbf\x66\x5c\xbc", 28); + + /* Artificial exercise for len(msg) = rate_bytes - 1 codepath */ + vector(H, "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", 143, + "\x73\xb1\xb2\x2b\x54\xf5\x15\xf6\x26\xa6\xab\xdd\xe6\xaf\x25\xcd\x48\x01\xdc\x6e\x9d\xc7\xfa\x3f\x77\xe1\xc1\x22", 28); + + vector_abc_final(H, cf_sha3_224_digest_final, + "\xe6\x42\x82\x4c\x3f\x8c\xf2\x4a\xd0\x92\x34\xee\x7d\x3c\x76\x6f\xc9\xa3\xa5\x16\x8d\x0c\x94\xad\x73\xb4\x6f\xdf", 28); + + vector_length(H, 1024, "\xf2\x54\xf3\x67\x6d\xc6\xc0\x0f\x2f\xee\x50\x59\x07\x62\x8b\x0d\x5b\x9e\xdf\xf8\xe8\xc2\x9e\x9b\xa7\xd6\x05\xdd", 28); +} + +static void test_sha3_256(void) +{ + const cf_chash *H = &cf_sha3_256; + vector(H, "", 0, + "\xa7\xff\xc6\xf8\xbf\x1e\xd7\x66\x51\xc1\x47\x56\xa0\x61\xd6\x62\xf5\x80\xff\x4d\xe4\x3b\x49\xfa\x82\xd8\x0a\x4b\x80\xf8\x43\x4a", 32); + vector(H, "abc", 3, + "\x3a\x98\x5d\xa7\x4f\xe2\x25\xb2\x04\x5c\x17\x2d\x6b\xd3\x90\xbd\x85\x5f\x08\x6e\x3e\x9d\x52\x5b\x46\xbf\xe2\x45\x11\x43\x15\x32", 32); + vector(H, "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", 56, + "\x41\xc0\xdb\xa2\xa9\xd6\x24\x08\x49\x10\x03\x76\xa8\x23\x5e\x2c\x82\xe1\xb9\x99\x8a\x99\x9e\x21\xdb\x32\xdd\x97\x49\x6d\x33\x76", 32); + vector(H, "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu", 112, + "\x91\x6f\x60\x61\xfe\x87\x97\x41\xca\x64\x69\xb4\x39\x71\xdf\xdb\x28\xb1\xa3\x2d\xc3\x6c\xb3\x25\x4e\x81\x2b\xe2\x7a\xad\x1d\x18", 32); + + vector_abc_final(H, cf_sha3_256_digest_final, + "\x3a\x98\x5d\xa7\x4f\xe2\x25\xb2\x04\x5c\x17\x2d\x6b\xd3\x90\xbd\x85\x5f\x08\x6e\x3e\x9d\x52\x5b\x46\xbf\xe2\x45\x11\x43\x15\x32", 32); + + vector_length(H, 1024, "\xf7\xed\xf7\x2b\x34\x8c\xb4\xab\x5e\xe7\x4f\x6c\xae\xaf\x11\xad\xe2\x2f\x04\x65\x84\x8e\x5c\xaa\x14\x38\x7f\xd4\xeb\xdb\x9d\x70", 32); +} + +static void test_sha3_384(void) +{ + const cf_chash *H = &cf_sha3_384; + vector(H, "", 0, + "\x0c\x63\xa7\x5b\x84\x5e\x4f\x7d\x01\x10\x7d\x85\x2e\x4c\x24\x85\xc5\x1a\x50\xaa\xaa\x94\xfc\x61\x99\x5e\x71\xbb\xee\x98\x3a\x2a\xc3\x71\x38\x31\x26\x4a\xdb\x47\xfb\x6b\xd1\xe0\x58\xd5\xf0\x04", 48); + vector(H, "abc", 3, + "\xec\x01\x49\x82\x88\x51\x6f\xc9\x26\x45\x9f\x58\xe2\xc6\xad\x8d\xf9\xb4\x73\xcb\x0f\xc0\x8c\x25\x96\xda\x7c\xf0\xe4\x9b\xe4\xb2\x98\xd8\x8c\xea\x92\x7a\xc7\xf5\x39\xf1\xed\xf2\x28\x37\x6d\x25", 48); + vector(H, "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", 56, + "\x99\x1c\x66\x57\x55\xeb\x3a\x4b\x6b\xbd\xfb\x75\xc7\x8a\x49\x2e\x8c\x56\xa2\x2c\x5c\x4d\x7e\x42\x9b\xfd\xbc\x32\xb9\xd4\xad\x5a\xa0\x4a\x1f\x07\x6e\x62\xfe\xa1\x9e\xef\x51\xac\xd0\x65\x7c\x22", 48); + vector(H, "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu", 112, + "\x79\x40\x7d\x3b\x59\x16\xb5\x9c\x3e\x30\xb0\x98\x22\x97\x47\x91\xc3\x13\xfb\x9e\xcc\x84\x9e\x40\x6f\x23\x59\x2d\x04\xf6\x25\xdc\x8c\x70\x9b\x98\xb4\x3b\x38\x52\xb3\x37\x21\x61\x79\xaa\x7f\xc7", 48); + + vector_abc_final(H, cf_sha3_384_digest_final, + "\xec\x01\x49\x82\x88\x51\x6f\xc9\x26\x45\x9f\x58\xe2\xc6\xad\x8d\xf9\xb4\x73\xcb\x0f\xc0\x8c\x25\x96\xda\x7c\xf0\xe4\x9b\xe4\xb2\x98\xd8\x8c\xea\x92\x7a\xc7\xf5\x39\xf1\xed\xf2\x28\x37\x6d\x25", 48); + + vector_length(H, 1024, "\xc2\x16\x48\x6a\x00\x32\xb1\xe1\x98\xf8\x72\x52\x01\x87\xba\xd4\xcf\x39\x13\x9c\x54\x21\x6d\x78\x86\x93\x88\xf9\x75\x03\xc1\x11\xcc\x7f\x5a\xc3\x21\x00\x3f\xc8\xa1\xf7\xfa\x10\x75\x60\xdb\xb1", 48); +} + +static void test_sha3_512(void) +{ + const cf_chash *H = &cf_sha3_512; + vector(H, "", 0, + "\xa6\x9f\x73\xcc\xa2\x3a\x9a\xc5\xc8\xb5\x67\xdc\x18\x5a\x75\x6e\x97\xc9\x82\x16\x4f\xe2\x58\x59\xe0\xd1\xdc\xc1\x47\x5c\x80\xa6\x15\xb2\x12\x3a\xf1\xf5\xf9\x4c\x11\xe3\xe9\x40\x2c\x3a\xc5\x58\xf5\x00\x19\x9d\x95\xb6\xd3\xe3\x01\x75\x85\x86\x28\x1d\xcd\x26", 64); + vector(H, "abc", 3, + "\xb7\x51\x85\x0b\x1a\x57\x16\x8a\x56\x93\xcd\x92\x4b\x6b\x09\x6e\x08\xf6\x21\x82\x74\x44\xf7\x0d\x88\x4f\x5d\x02\x40\xd2\x71\x2e\x10\xe1\x16\xe9\x19\x2a\xf3\xc9\x1a\x7e\xc5\x76\x47\xe3\x93\x40\x57\x34\x0b\x4c\xf4\x08\xd5\xa5\x65\x92\xf8\x27\x4e\xec\x53\xf0", 64); + vector(H, "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", 56, + "\x04\xa3\x71\xe8\x4e\xcf\xb5\xb8\xb7\x7c\xb4\x86\x10\xfc\xa8\x18\x2d\xd4\x57\xce\x6f\x32\x6a\x0f\xd3\xd7\xec\x2f\x1e\x91\x63\x6d\xee\x69\x1f\xbe\x0c\x98\x53\x02\xba\x1b\x0d\x8d\xc7\x8c\x08\x63\x46\xb5\x33\xb4\x9c\x03\x0d\x99\xa2\x7d\xaf\x11\x39\xd6\xe7\x5e", 64); + vector(H, "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu", 112, + "\xaf\xeb\xb2\xef\x54\x2e\x65\x79\xc5\x0c\xad\x06\xd2\xe5\x78\xf9\xf8\xdd\x68\x81\xd7\xdc\x82\x4d\x26\x36\x0f\xee\xbf\x18\xa4\xfa\x73\xe3\x26\x11\x22\x94\x8e\xfc\xfd\x49\x2e\x74\xe8\x2e\x21\x89\xed\x0f\xb4\x40\xd1\x87\xf3\x82\x27\x0c\xb4\x55\xf2\x1d\xd1\x85", 64); + + vector_abc_final(H, cf_sha3_512_digest_final, + "\xb7\x51\x85\x0b\x1a\x57\x16\x8a\x56\x93\xcd\x92\x4b\x6b\x09\x6e\x08\xf6\x21\x82\x74\x44\xf7\x0d\x88\x4f\x5d\x02\x40\xd2\x71\x2e\x10\xe1\x16\xe9\x19\x2a\xf3\xc9\x1a\x7e\xc5\x76\x47\xe3\x93\x40\x57\x34\x0b\x4c\xf4\x08\xd5\xa5\x65\x92\xf8\x27\x4e\xec\x53\xf0", 64); + + vector_length(H, 1024, "\x3a\x98\x11\x17\xbc\x2f\xa3\x3b\x00\x51\x71\xf8\x80\x86\x33\x7f\x4f\x6c\xe9\xd1\x5c\xb7\x38\xc0\x9b\xe2\x8a\xb6\xd5\x38\xba\xbf\x7b\xc5\x4e\xbf\x3d\xdb\x53\x4a\x9c\x3c\x10\x85\xe7\x18\x3d\x46\xa5\x8c\xbc\xb0\x15\xb0\xdf\x50\x7a\xad\x0e\xdf\xf3\x54\x8e\xfd", 64); +} + +TEST_LIST = { + { "sha3-224", test_sha3_224 }, + { "sha3-256", test_sha3_256 }, + { "sha3-384", test_sha3_384 }, + { "sha3-512", test_sha3_512 }, + { 0 } +}; + diff --git a/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/testutil.h b/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/testutil.h new file mode 100644 index 00000000..b9a52b33 --- /dev/null +++ b/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/testutil.h @@ -0,0 +1,61 @@ +/* + * cifra - embedded cryptography library + * Written in 2014 by Joseph Birr-Pixton + * + * To the extent possible under law, the author(s) have dedicated all + * copyright and related and neighboring rights to this software to the + * public domain worldwide. This software is distributed without any + * warranty. + * + * You should have received a copy of the CC0 Public Domain Dedication + * along with this software. If not, see + * . + */ + +#ifndef TESTUTIL_H +#define TESTUTIL_H + +#include +#include +#include + +static inline uint8_t unhex_chr(char a) +{ + if (a >= '0' && a <= '9') + return a - '0'; + else if (a >= 'a' && a <= 'f') + return a - 'a' + 10; + else if (a >= 'A' && a <= 'F') + return a - 'A' + 10; + return 0; +} + +static inline size_t unhex(uint8_t *buf, size_t len, const char *str) +{ + size_t used = 0; + + assert(strlen(str) % 2 == 0); + assert(strlen(str) / 2 <= len); + + while (*str) + { + assert(len); + *buf = unhex_chr(str[0]) << 4 | unhex_chr(str[1]); + buf++; + used++; + str += 2; + len--; + } + + return used; +} + +static inline void dump(const char *label, const uint8_t *buf, size_t len) +{ + printf("%s: ", label); + for (size_t i = 0; i < len; i++) + printf("%02x", buf[i]); + printf("\n"); +} + +#endif diff --git a/web/server/h2o/libh2o/deps/picotls/deps/micro-ecc/.gitignore b/web/server/h2o/libh2o/deps/picotls/deps/micro-ecc/.gitignore new file mode 100644 index 00000000..cd812eb9 --- /dev/null +++ b/web/server/h2o/libh2o/deps/picotls/deps/micro-ecc/.gitignore @@ -0,0 +1,8 @@ +__build__/ +__pycache__ +*.pyc +*.pyo +*.pyd +*.pyz +*.egg-info/ +.DS_Store \ No newline at end of file diff --git a/web/server/h2o/libh2o/deps/picotls/deps/micro-ecc/LICENSE.txt b/web/server/h2o/libh2o/deps/picotls/deps/micro-ecc/LICENSE.txt new file mode 100644 index 00000000..ab099ae5 --- /dev/null +++ b/web/server/h2o/libh2o/deps/picotls/deps/micro-ecc/LICENSE.txt @@ -0,0 +1,21 @@ +Copyright (c) 2014, Kenneth MacKay +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/web/server/h2o/libh2o/deps/picotls/deps/micro-ecc/README.md b/web/server/h2o/libh2o/deps/picotls/deps/micro-ecc/README.md new file mode 100644 index 00000000..01926e3f --- /dev/null +++ b/web/server/h2o/libh2o/deps/picotls/deps/micro-ecc/README.md @@ -0,0 +1,41 @@ +micro-ecc +========== + +A small and fast ECDH and ECDSA implementation for 8-bit, 32-bit, and 64-bit processors. + +The static version of micro-ecc (ie, where the curve was selected at compile-time) can be found in the "static" branch. + +Features +-------- + + * Resistant to known side-channel attacks. + * Written in C, with optional GCC inline assembly for AVR, ARM and Thumb platforms. + * Supports 8, 32, and 64-bit architectures. + * Small code size. + * No dynamic memory allocation. + * Support for 5 standard curves: secp160r1, secp192r1, secp224r1, secp256r1, and secp256k1. + * BSD 2-clause license. + +Usage Notes +----------- +### Point Representation ### +Compressed points are represented in the standard format as defined in http://www.secg.org/collateral/sec1_final.pdf; uncompressed points are represented in standard format, but without the `0x04` prefix. All functions except `uECC_compress()` only accept uncompressed points; use `uECC_compress()` and `uECC_decompress()` to convert between compressed and uncompressed point representations. + +Private keys are represented in the standard format. + +### Using the Code ### + +I recommend just copying (or symlink) the uECC files into your project. Then just `#include "uECC.h"` to use the micro-ecc functions. + +For use with Arduino, you can just create a symlink to the `uECC` directory in your Arduino `libraries` directory. You can then use uECC just like any other Arduino library (uECC should show up in the **Sketch**=>**Import Library** submenu). + +See uECC.h for documentation for each function. + +### Compilation Notes ### + + * Should compile with any C/C++ compiler that supports stdint.h (this includes Visual Studio 2013). + * If you want to change the defaults for any of the uECC compile-time options (such as `uECC_OPTIMIZATION_LEVEL`), you must change them in your Makefile or similar so that uECC.c is compiled with the desired values (ie, compile uECC.c with `-DuECC_OPTIMIZATION_LEVEL=3` or whatever). + * When compiling for a Thumb-1 platform, you must use the `-fomit-frame-pointer` GCC option (this is enabled by default when compiling with `-O1` or higher). + * When compiling for an ARM/Thumb-2 platform with `uECC_OPTIMIZATION_LEVEL` >= 3, you must use the `-fomit-frame-pointer` GCC option (this is enabled by default when compiling with `-O1` or higher). + * When compiling for AVR, you must have optimizations enabled (compile with `-O1` or higher). + * When building for Windows, you will need to link in the `advapi32.lib` system library. diff --git a/web/server/h2o/libh2o/deps/picotls/deps/micro-ecc/asm_arm.inc b/web/server/h2o/libh2o/deps/picotls/deps/micro-ecc/asm_arm.inc new file mode 100644 index 00000000..688fdc75 --- /dev/null +++ b/web/server/h2o/libh2o/deps/picotls/deps/micro-ecc/asm_arm.inc @@ -0,0 +1,820 @@ +/* Copyright 2015, Kenneth MacKay. Licensed under the BSD 2-clause license. */ + +#ifndef _UECC_ASM_ARM_H_ +#define _UECC_ASM_ARM_H_ + +#if (uECC_SUPPORTS_secp256r1 || uECC_SUPPORTS_secp256k1) + #define uECC_MIN_WORDS 8 +#endif +#if uECC_SUPPORTS_secp224r1 + #undef uECC_MIN_WORDS + #define uECC_MIN_WORDS 7 +#endif +#if uECC_SUPPORTS_secp192r1 + #undef uECC_MIN_WORDS + #define uECC_MIN_WORDS 6 +#endif +#if uECC_SUPPORTS_secp160r1 + #undef uECC_MIN_WORDS + #define uECC_MIN_WORDS 5 +#endif + +#if (uECC_PLATFORM == uECC_arm_thumb) + #define REG_RW "+l" + #define REG_WRITE "=l" +#else + #define REG_RW "+r" + #define REG_WRITE "=r" +#endif + +#if (uECC_PLATFORM == uECC_arm_thumb || uECC_PLATFORM == uECC_arm_thumb2) + #define REG_RW_LO "+l" + #define REG_WRITE_LO "=l" +#else + #define REG_RW_LO "+r" + #define REG_WRITE_LO "=r" +#endif + +#if (uECC_PLATFORM == uECC_arm_thumb2) + #define RESUME_SYNTAX +#else + #define RESUME_SYNTAX ".syntax divided \n\t" +#endif + +#if (uECC_OPTIMIZATION_LEVEL >= 2) + +uECC_VLI_API uECC_word_t uECC_vli_add(uECC_word_t *result, + const uECC_word_t *left, + const uECC_word_t *right, + wordcount_t num_words) { +#if (uECC_MAX_WORDS != uECC_MIN_WORDS) + #if (uECC_PLATFORM == uECC_arm_thumb) || (uECC_PLATFORM == uECC_arm_thumb2) + uint32_t jump = (uECC_MAX_WORDS - num_words) * 4 * 2 + 1; + #else /* ARM */ + uint32_t jump = (uECC_MAX_WORDS - num_words) * 4 * 4; + #endif +#endif + uint32_t carry; + uint32_t left_word; + uint32_t right_word; + + __asm__ volatile ( + ".syntax unified \n\t" + "movs %[carry], #0 \n\t" + #if (uECC_MAX_WORDS != uECC_MIN_WORDS) + "adr %[left], 1f \n\t" + ".align 4 \n\t" + "adds %[jump], %[left] \n\t" + #endif + + "ldmia %[lptr]!, {%[left]} \n\t" + "ldmia %[rptr]!, {%[right]} \n\t" + "adds %[left], %[right] \n\t" + "stmia %[dptr]!, {%[left]} \n\t" + + #if (uECC_MAX_WORDS != uECC_MIN_WORDS) + "bx %[jump] \n\t" + #endif + "1: \n\t" + REPEAT(DEC(uECC_MAX_WORDS), + "ldmia %[lptr]!, {%[left]} \n\t" + "ldmia %[rptr]!, {%[right]} \n\t" + "adcs %[left], %[right] \n\t" + "stmia %[dptr]!, {%[left]} \n\t") + + "adcs %[carry], %[carry] \n\t" + RESUME_SYNTAX + : [dptr] REG_RW_LO (result), [lptr] REG_RW_LO (left), [rptr] REG_RW_LO (right), + #if (uECC_MAX_WORDS != uECC_MIN_WORDS) + [jump] REG_RW_LO (jump), + #endif + [carry] REG_WRITE_LO (carry), [left] REG_WRITE_LO (left_word), + [right] REG_WRITE_LO (right_word) + : + : "cc", "memory" + ); + return carry; +} +#define asm_add 1 + +uECC_VLI_API uECC_word_t uECC_vli_sub(uECC_word_t *result, + const uECC_word_t *left, + const uECC_word_t *right, + wordcount_t num_words) { +#if (uECC_MAX_WORDS != uECC_MIN_WORDS) + #if (uECC_PLATFORM == uECC_arm_thumb) || (uECC_PLATFORM == uECC_arm_thumb2) + uint32_t jump = (uECC_MAX_WORDS - num_words) * 4 * 2 + 1; + #else /* ARM */ + uint32_t jump = (uECC_MAX_WORDS - num_words) * 4 * 4; + #endif +#endif + uint32_t carry; + uint32_t left_word; + uint32_t right_word; + + __asm__ volatile ( + ".syntax unified \n\t" + "movs %[carry], #0 \n\t" + #if (uECC_MAX_WORDS != uECC_MIN_WORDS) + "adr %[left], 1f \n\t" + ".align 4 \n\t" + "adds %[jump], %[left] \n\t" + #endif + + "ldmia %[lptr]!, {%[left]} \n\t" + "ldmia %[rptr]!, {%[right]} \n\t" + "subs %[left], %[right] \n\t" + "stmia %[dptr]!, {%[left]} \n\t" + + #if (uECC_MAX_WORDS != uECC_MIN_WORDS) + "bx %[jump] \n\t" + #endif + "1: \n\t" + REPEAT(DEC(uECC_MAX_WORDS), + "ldmia %[lptr]!, {%[left]} \n\t" + "ldmia %[rptr]!, {%[right]} \n\t" + "sbcs %[left], %[right] \n\t" + "stmia %[dptr]!, {%[left]} \n\t") + + "adcs %[carry], %[carry] \n\t" + RESUME_SYNTAX + : [dptr] REG_RW_LO (result), [lptr] REG_RW_LO (left), [rptr] REG_RW_LO (right), + #if (uECC_MAX_WORDS != uECC_MIN_WORDS) + [jump] REG_RW_LO (jump), + #endif + [carry] REG_WRITE_LO (carry), [left] REG_WRITE_LO (left_word), + [right] REG_WRITE_LO (right_word) + : + : "cc", "memory" + ); + return !carry; /* Note that on ARM, carry flag set means "no borrow" when subtracting + (for some reason...) */ +} +#define asm_sub 1 + +#endif /* (uECC_OPTIMIZATION_LEVEL >= 2) */ + +#if (uECC_OPTIMIZATION_LEVEL >= 3) + +#if (uECC_PLATFORM != uECC_arm_thumb) + +#if uECC_ARM_USE_UMAAL + #include "asm_arm_mult_square_umaal.inc" +#else + #include "asm_arm_mult_square.inc" +#endif + +#if (uECC_OPTIMIZATION_LEVEL == 3) + +uECC_VLI_API void uECC_vli_mult(uint32_t *result, + const uint32_t *left, + const uint32_t *right, + wordcount_t num_words) { + register uint32_t *r0 __asm__("r0") = result; + register const uint32_t *r1 __asm__("r1") = left; + register const uint32_t *r2 __asm__("r2") = right; + register uint32_t r3 __asm__("r3") = num_words; + + __asm__ volatile ( + ".syntax unified \n\t" +#if (uECC_MIN_WORDS == 5) + FAST_MULT_ASM_5 + #if (uECC_MAX_WORDS > 5) + FAST_MULT_ASM_5_TO_6 + #endif + #if (uECC_MAX_WORDS > 6) + FAST_MULT_ASM_6_TO_7 + #endif + #if (uECC_MAX_WORDS > 7) + FAST_MULT_ASM_7_TO_8 + #endif +#elif (uECC_MIN_WORDS == 6) + FAST_MULT_ASM_6 + #if (uECC_MAX_WORDS > 6) + FAST_MULT_ASM_6_TO_7 + #endif + #if (uECC_MAX_WORDS > 7) + FAST_MULT_ASM_7_TO_8 + #endif +#elif (uECC_MIN_WORDS == 7) + FAST_MULT_ASM_7 + #if (uECC_MAX_WORDS > 7) + FAST_MULT_ASM_7_TO_8 + #endif +#elif (uECC_MIN_WORDS == 8) + FAST_MULT_ASM_8 +#endif + "1: \n\t" + RESUME_SYNTAX + : "+r" (r0), "+r" (r1), "+r" (r2) + : "r" (r3) + : "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "r14", "cc", "memory" + ); +} +#define asm_mult 1 + +#if uECC_SQUARE_FUNC +uECC_VLI_API void uECC_vli_square(uECC_word_t *result, + const uECC_word_t *left, + wordcount_t num_words) { + register uint32_t *r0 __asm__("r0") = result; + register const uint32_t *r1 __asm__("r1") = left; + register uint32_t r2 __asm__("r2") = num_words; + + __asm__ volatile ( + ".syntax unified \n\t" +#if (uECC_MIN_WORDS == 5) + FAST_SQUARE_ASM_5 + #if (uECC_MAX_WORDS > 5) + FAST_SQUARE_ASM_5_TO_6 + #endif + #if (uECC_MAX_WORDS > 6) + FAST_SQUARE_ASM_6_TO_7 + #endif + #if (uECC_MAX_WORDS > 7) + FAST_SQUARE_ASM_7_TO_8 + #endif +#elif (uECC_MIN_WORDS == 6) + FAST_SQUARE_ASM_6 + #if (uECC_MAX_WORDS > 6) + FAST_SQUARE_ASM_6_TO_7 + #endif + #if (uECC_MAX_WORDS > 7) + FAST_SQUARE_ASM_7_TO_8 + #endif +#elif (uECC_MIN_WORDS == 7) + FAST_SQUARE_ASM_7 + #if (uECC_MAX_WORDS > 7) + FAST_SQUARE_ASM_7_TO_8 + #endif +#elif (uECC_MIN_WORDS == 8) + FAST_SQUARE_ASM_8 +#endif + + "1: \n\t" + RESUME_SYNTAX + : "+r" (r0), "+r" (r1) + : "r" (r2) + : "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "r14", "cc", "memory" + ); +} +#define asm_square 1 +#endif /* uECC_SQUARE_FUNC */ + +#else /* (uECC_OPTIMIZATION_LEVEL > 3) */ + +uECC_VLI_API void uECC_vli_mult(uint32_t *result, + const uint32_t *left, + const uint32_t *right, + wordcount_t num_words) { + register uint32_t *r0 __asm__("r0") = result; + register const uint32_t *r1 __asm__("r1") = left; + register const uint32_t *r2 __asm__("r2") = right; + register uint32_t r3 __asm__("r3") = num_words; + +#if uECC_SUPPORTS_secp160r1 + if (num_words == 5) { + __asm__ volatile ( + ".syntax unified \n\t" + FAST_MULT_ASM_5 + RESUME_SYNTAX + : "+r" (r0), "+r" (r1), "+r" (r2) + : "r" (r3) + : "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "r14", "cc", "memory" + ); + return; + } +#endif +#if uECC_SUPPORTS_secp192r1 + if (num_words == 6) { + __asm__ volatile ( + ".syntax unified \n\t" + FAST_MULT_ASM_6 + RESUME_SYNTAX + : "+r" (r0), "+r" (r1), "+r" (r2) + : "r" (r3) + : "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "r14", "cc", "memory" + ); + return; + } +#endif +#if uECC_SUPPORTS_secp224r1 + if (num_words == 7) { + __asm__ volatile ( + ".syntax unified \n\t" + FAST_MULT_ASM_7 + RESUME_SYNTAX + : "+r" (r0), "+r" (r1), "+r" (r2) + : "r" (r3) + : "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "r14", "cc", "memory" + ); + return; + } +#endif +#if (uECC_SUPPORTS_secp256r1 || uECC_SUPPORTS_secp256k1) + if (num_words == 8) { + __asm__ volatile ( + ".syntax unified \n\t" + FAST_MULT_ASM_8 + RESUME_SYNTAX + : "+r" (r0), "+r" (r1), "+r" (r2) + : "r" (r3) + : "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "r14", "cc", "memory" + ); + return; + } +#endif +} +#define asm_mult 1 + +#if uECC_SQUARE_FUNC +uECC_VLI_API void uECC_vli_square(uECC_word_t *result, + const uECC_word_t *left, + wordcount_t num_words) { + register uint32_t *r0 __asm__("r0") = result; + register const uint32_t *r1 __asm__("r1") = left; + register uint32_t r2 __asm__("r2") = num_words; + +#if uECC_SUPPORTS_secp160r1 + if (num_words == 5) { + __asm__ volatile ( + ".syntax unified \n\t" + FAST_SQUARE_ASM_5 + RESUME_SYNTAX + : "+r" (r0), "+r" (r1) + : "r" (r2) + : "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "r14", "cc", "memory" + ); + return; + } +#endif +#if uECC_SUPPORTS_secp192r1 + if (num_words == 6) { + __asm__ volatile ( + ".syntax unified \n\t" + FAST_SQUARE_ASM_6 + RESUME_SYNTAX + : "+r" (r0), "+r" (r1) + : "r" (r2) + : "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "r14", "cc", "memory" + ); + return; + } +#endif +#if uECC_SUPPORTS_secp224r1 + if (num_words == 7) { + __asm__ volatile ( + ".syntax unified \n\t" + FAST_SQUARE_ASM_7 + RESUME_SYNTAX + : "+r" (r0), "+r" (r1) + : "r" (r2) + : "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "r14", "cc", "memory" + ); + return; + } +#endif +#if (uECC_SUPPORTS_secp256r1 || uECC_SUPPORTS_secp256k1) + if (num_words == 8) { + __asm__ volatile ( + ".syntax unified \n\t" + FAST_SQUARE_ASM_8 + RESUME_SYNTAX + : "+r" (r0), "+r" (r1) + : "r" (r2) + : "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "r14", "cc", "memory" + ); + return; + } +#endif +} +#define asm_square 1 +#endif /* uECC_SQUARE_FUNC */ + +#endif /* (uECC_OPTIMIZATION_LEVEL > 3) */ + +#endif /* uECC_PLATFORM != uECC_arm_thumb */ + +#endif /* (uECC_OPTIMIZATION_LEVEL >= 3) */ + +/* ---- "Small" implementations ---- */ + +#if !asm_add +uECC_VLI_API uECC_word_t uECC_vli_add(uECC_word_t *result, + const uECC_word_t *left, + const uECC_word_t *right, + wordcount_t num_words) { + uint32_t carry = 0; + uint32_t left_word; + uint32_t right_word; + + __asm__ volatile ( + ".syntax unified \n\t" + "1: \n\t" + "ldmia %[lptr]!, {%[left]} \n\t" /* Load left word. */ + "ldmia %[rptr]!, {%[right]} \n\t" /* Load right word. */ + "lsrs %[carry], #1 \n\t" /* Set up carry flag (carry = 0 after this). */ + "adcs %[left], %[left], %[right] \n\t" /* Add with carry. */ + "adcs %[carry], %[carry], %[carry] \n\t" /* Store carry bit. */ + "stmia %[dptr]!, {%[left]} \n\t" /* Store result word. */ + "subs %[ctr], #1 \n\t" /* Decrement counter. */ + "bne 1b \n\t" /* Loop until counter == 0. */ + RESUME_SYNTAX + : [dptr] REG_RW (result), [lptr] REG_RW (left), [rptr] REG_RW (right), + [ctr] REG_RW (num_words), [carry] REG_RW (carry), + [left] REG_WRITE (left_word), [right] REG_WRITE (right_word) + : + : "cc", "memory" + ); + return carry; +} +#define asm_add 1 +#endif + +#if !asm_sub +uECC_VLI_API uECC_word_t uECC_vli_sub(uECC_word_t *result, + const uECC_word_t *left, + const uECC_word_t *right, + wordcount_t num_words) { + uint32_t carry = 1; /* carry = 1 initially (means don't borrow) */ + uint32_t left_word; + uint32_t right_word; + + __asm__ volatile ( + ".syntax unified \n\t" + "1: \n\t" + "ldmia %[lptr]!, {%[left]} \n\t" /* Load left word. */ + "ldmia %[rptr]!, {%[right]} \n\t" /* Load right word. */ + "lsrs %[carry], #1 \n\t" /* Set up carry flag (carry = 0 after this). */ + "sbcs %[left], %[left], %[right] \n\t" /* Subtract with borrow. */ + "adcs %[carry], %[carry], %[carry] \n\t" /* Store carry bit. */ + "stmia %[dptr]!, {%[left]} \n\t" /* Store result word. */ + "subs %[ctr], #1 \n\t" /* Decrement counter. */ + "bne 1b \n\t" /* Loop until counter == 0. */ + RESUME_SYNTAX + : [dptr] REG_RW (result), [lptr] REG_RW (left), [rptr] REG_RW (right), + [ctr] REG_RW (num_words), [carry] REG_RW (carry), + [left] REG_WRITE (left_word), [right] REG_WRITE (right_word) + : + : "cc", "memory" + ); + return !carry; +} +#define asm_sub 1 +#endif + +#if !asm_mult +uECC_VLI_API void uECC_vli_mult(uECC_word_t *result, + const uECC_word_t *left, + const uECC_word_t *right, + wordcount_t num_words) { +#if (uECC_PLATFORM != uECC_arm_thumb) + uint32_t c0 = 0; + uint32_t c1 = 0; + uint32_t c2 = 0; + uint32_t k = 0; + uint32_t i; + uint32_t t0, t1; + + __asm__ volatile ( + ".syntax unified \n\t" + + "1: \n\t" /* outer loop (k < num_words) */ + "movs %[i], #0 \n\t" /* i = 0 */ + "b 3f \n\t" + + "2: \n\t" /* outer loop (k >= num_words) */ + "movs %[i], %[k] \n\t" /* i = k */ + "subs %[i], %[last_word] \n\t" /* i = k - (num_words - 1) (times 4) */ + + "3: \n\t" /* inner loop */ + "subs %[t0], %[k], %[i] \n\t" /* t0 = k-i */ + + "ldr %[t1], [%[right], %[t0]] \n\t" /* t1 = right[k - i] */ + "ldr %[t0], [%[left], %[i]] \n\t" /* t0 = left[i] */ + + "umull %[t0], %[t1], %[t0], %[t1] \n\t" /* (t0, t1) = left[i] * right[k - i] */ + + "adds %[c0], %[c0], %[t0] \n\t" /* add low word to c0 */ + "adcs %[c1], %[c1], %[t1] \n\t" /* add high word to c1, including carry */ + "adcs %[c2], %[c2], #0 \n\t" /* add carry to c2 */ + + "adds %[i], #4 \n\t" /* i += 4 */ + "cmp %[i], %[last_word] \n\t" /* i > (num_words - 1) (times 4)? */ + "bgt 4f \n\t" /* if so, exit the loop */ + "cmp %[i], %[k] \n\t" /* i <= k? */ + "ble 3b \n\t" /* if so, continue looping */ + + "4: \n\t" /* end inner loop */ + + "str %[c0], [%[result], %[k]] \n\t" /* result[k] = c0 */ + "mov %[c0], %[c1] \n\t" /* c0 = c1 */ + "mov %[c1], %[c2] \n\t" /* c1 = c2 */ + "movs %[c2], #0 \n\t" /* c2 = 0 */ + "adds %[k], #4 \n\t" /* k += 4 */ + "cmp %[k], %[last_word] \n\t" /* k <= (num_words - 1) (times 4) ? */ + "ble 1b \n\t" /* if so, loop back, start with i = 0 */ + "cmp %[k], %[last_word], lsl #1 \n\t" /* k <= (num_words * 2 - 2) (times 4) ? */ + "ble 2b \n\t" /* if so, loop back, start with i = (k + 1) - num_words */ + /* end outer loop */ + + "str %[c0], [%[result], %[k]] \n\t" /* result[num_words * 2 - 1] = c0 */ + RESUME_SYNTAX + : [c0] "+r" (c0), [c1] "+r" (c1), [c2] "+r" (c2), + [k] "+r" (k), [i] "=&r" (i), [t0] "=&r" (t0), [t1] "=&r" (t1) + : [result] "r" (result), [left] "r" (left), [right] "r" (right), + [last_word] "r" ((num_words - 1) * 4) + : "cc", "memory" + ); + +#else /* Thumb-1 */ + uint32_t r4, r5, r6, r7; + + __asm__ volatile ( + ".syntax unified \n\t" + "subs %[r3], #1 \n\t" /* r3 = num_words - 1 */ + "lsls %[r3], #2 \n\t" /* r3 = (num_words - 1) * 4 */ + "mov r8, %[r3] \n\t" /* r8 = (num_words - 1) * 4 */ + "lsls %[r3], #1 \n\t" /* r3 = (num_words - 1) * 8 */ + "mov r9, %[r3] \n\t" /* r9 = (num_words - 1) * 8 */ + "movs %[r3], #0 \n\t" /* c0 = 0 */ + "movs %[r4], #0 \n\t" /* c1 = 0 */ + "movs %[r5], #0 \n\t" /* c2 = 0 */ + "movs %[r6], #0 \n\t" /* k = 0 */ + + "push {%[r0]} \n\t" /* keep result on the stack */ + + "1: \n\t" /* outer loop (k < num_words) */ + "movs %[r7], #0 \n\t" /* r7 = i = 0 */ + "b 3f \n\t" + + "2: \n\t" /* outer loop (k >= num_words) */ + "movs %[r7], %[r6] \n\t" /* r7 = k */ + "mov %[r0], r8 \n\t" /* r0 = (num_words - 1) * 4 */ + "subs %[r7], %[r0] \n\t" /* r7 = i = k - (num_words - 1) (times 4) */ + + "3: \n\t" /* inner loop */ + "mov r10, %[r3] \n\t" + "mov r11, %[r4] \n\t" + "mov r12, %[r5] \n\t" + "mov r14, %[r6] \n\t" + "subs %[r0], %[r6], %[r7] \n\t" /* r0 = k - i */ + + "ldr %[r4], [%[r2], %[r0]] \n\t" /* r4 = right[k - i] */ + "ldr %[r0], [%[r1], %[r7]] \n\t" /* r0 = left[i] */ + + "lsrs %[r3], %[r0], #16 \n\t" /* r3 = a1 */ + "uxth %[r0], %[r0] \n\t" /* r0 = a0 */ + + "lsrs %[r5], %[r4], #16 \n\t" /* r5 = b1 */ + "uxth %[r4], %[r4] \n\t" /* r4 = b0 */ + + "movs %[r6], %[r3] \n\t" /* r6 = a1 */ + "muls %[r6], %[r5], %[r6] \n\t" /* r6 = a1 * b1 */ + "muls %[r3], %[r4], %[r3] \n\t" /* r3 = b0 * a1 */ + "muls %[r5], %[r0], %[r5] \n\t" /* r5 = a0 * b1 */ + "muls %[r0], %[r4], %[r0] \n\t" /* r0 = a0 * b0 */ + + /* Add middle terms */ + "lsls %[r4], %[r3], #16 \n\t" + "lsrs %[r3], %[r3], #16 \n\t" + "adds %[r0], %[r4] \n\t" + "adcs %[r6], %[r3] \n\t" + + "lsls %[r4], %[r5], #16 \n\t" + "lsrs %[r5], %[r5], #16 \n\t" + "adds %[r0], %[r4] \n\t" + "adcs %[r6], %[r5] \n\t" + + "mov %[r3], r10\n\t" + "mov %[r4], r11\n\t" + "mov %[r5], r12\n\t" + "adds %[r3], %[r0] \n\t" /* add low word to c0 */ + "adcs %[r4], %[r6] \n\t" /* add high word to c1, including carry */ + "movs %[r0], #0 \n\t" /* r0 = 0 (does not affect carry bit) */ + "adcs %[r5], %[r0] \n\t" /* add carry to c2 */ + + "mov %[r6], r14\n\t" /* r6 = k */ + + "adds %[r7], #4 \n\t" /* i += 4 */ + "cmp %[r7], r8 \n\t" /* i > (num_words - 1) (times 4)? */ + "bgt 4f \n\t" /* if so, exit the loop */ + "cmp %[r7], %[r6] \n\t" /* i <= k? */ + "ble 3b \n\t" /* if so, continue looping */ + + "4: \n\t" /* end inner loop */ + + "ldr %[r0], [sp, #0] \n\t" /* r0 = result */ + + "str %[r3], [%[r0], %[r6]] \n\t" /* result[k] = c0 */ + "mov %[r3], %[r4] \n\t" /* c0 = c1 */ + "mov %[r4], %[r5] \n\t" /* c1 = c2 */ + "movs %[r5], #0 \n\t" /* c2 = 0 */ + "adds %[r6], #4 \n\t" /* k += 4 */ + "cmp %[r6], r8 \n\t" /* k <= (num_words - 1) (times 4) ? */ + "ble 1b \n\t" /* if so, loop back, start with i = 0 */ + "cmp %[r6], r9 \n\t" /* k <= (num_words * 2 - 2) (times 4) ? */ + "ble 2b \n\t" /* if so, loop back, with i = (k + 1) - num_words */ + /* end outer loop */ + + "str %[r3], [%[r0], %[r6]] \n\t" /* result[num_words * 2 - 1] = c0 */ + "pop {%[r0]} \n\t" /* pop result off the stack */ + + ".syntax divided \n\t" + : [r3] "+l" (num_words), [r4] "=&l" (r4), + [r5] "=&l" (r5), [r6] "=&l" (r6), [r7] "=&l" (r7) + : [r0] "l" (result), [r1] "l" (left), [r2] "l" (right) + : "r8", "r9", "r10", "r11", "r12", "r14", "cc", "memory" + ); +#endif +} +#define asm_mult 1 +#endif + +#if uECC_SQUARE_FUNC +#if !asm_square +uECC_VLI_API void uECC_vli_square(uECC_word_t *result, + const uECC_word_t *left, + wordcount_t num_words) { +#if (uECC_PLATFORM != uECC_arm_thumb) + uint32_t c0 = 0; + uint32_t c1 = 0; + uint32_t c2 = 0; + uint32_t k = 0; + uint32_t i, tt; + uint32_t t0, t1; + + __asm__ volatile ( + ".syntax unified \n\t" + + "1: \n\t" /* outer loop (k < num_words) */ + "movs %[i], #0 \n\t" /* i = 0 */ + "b 3f \n\t" + + "2: \n\t" /* outer loop (k >= num_words) */ + "movs %[i], %[k] \n\t" /* i = k */ + "subs %[i], %[last_word] \n\t" /* i = k - (num_words - 1) (times 4) */ + + "3: \n\t" /* inner loop */ + "subs %[tt], %[k], %[i] \n\t" /* tt = k-i */ + + "ldr %[t1], [%[left], %[tt]] \n\t" /* t1 = left[k - i] */ + "ldr %[t0], [%[left], %[i]] \n\t" /* t0 = left[i] */ + + "umull %[t0], %[t1], %[t0], %[t1] \n\t" /* (t0, t1) = left[i] * right[k - i] */ + + "cmp %[i], %[tt] \n\t" /* (i < k - i) ? */ + "bge 4f \n\t" /* if i >= k - i, skip */ + "adds %[c0], %[c0], %[t0] \n\t" /* add low word to c0 */ + "adcs %[c1], %[c1], %[t1] \n\t" /* add high word to c1, including carry */ + "adcs %[c2], %[c2], #0 \n\t" /* add carry to c2 */ + + "4: \n\t" + "adds %[c0], %[c0], %[t0] \n\t" /* add low word to c0 */ + "adcs %[c1], %[c1], %[t1] \n\t" /* add high word to c1, including carry */ + "adcs %[c2], %[c2], #0 \n\t" /* add carry to c2 */ + + "adds %[i], #4 \n\t" /* i += 4 */ + "cmp %[i], %[k] \n\t" /* i >= k? */ + "bge 5f \n\t" /* if so, exit the loop */ + "subs %[tt], %[k], %[i] \n\t" /* tt = k - i */ + "cmp %[i], %[tt] \n\t" /* i <= k - i? */ + "ble 3b \n\t" /* if so, continue looping */ + + "5: \n\t" /* end inner loop */ + + "str %[c0], [%[result], %[k]] \n\t" /* result[k] = c0 */ + "mov %[c0], %[c1] \n\t" /* c0 = c1 */ + "mov %[c1], %[c2] \n\t" /* c1 = c2 */ + "movs %[c2], #0 \n\t" /* c2 = 0 */ + "adds %[k], #4 \n\t" /* k += 4 */ + "cmp %[k], %[last_word] \n\t" /* k <= (num_words - 1) (times 4) ? */ + "ble 1b \n\t" /* if so, loop back, start with i = 0 */ + "cmp %[k], %[last_word], lsl #1 \n\t" /* k <= (num_words * 2 - 2) (times 4) ? */ + "ble 2b \n\t" /* if so, loop back, start with i = (k + 1) - num_words */ + /* end outer loop */ + + "str %[c0], [%[result], %[k]] \n\t" /* result[num_words * 2 - 1] = c0 */ + RESUME_SYNTAX + : [c0] "+r" (c0), [c1] "+r" (c1), [c2] "+r" (c2), + [k] "+r" (k), [i] "=&r" (i), [tt] "=&r" (tt), [t0] "=&r" (t0), [t1] "=&r" (t1) + : [result] "r" (result), [left] "r" (left), [last_word] "r" ((num_words - 1) * 4) + : "cc", "memory" + ); + +#else + uint32_t r3, r4, r5, r6, r7; + + __asm__ volatile ( + ".syntax unified \n\t" + "subs %[r2], #1 \n\t" /* r2 = num_words - 1 */ + "lsls %[r2], #2 \n\t" /* r2 = (num_words - 1) * 4 */ + "mov r8, %[r2] \n\t" /* r8 = (num_words - 1) * 4 */ + "lsls %[r2], #1 \n\t" /* r2 = (num_words - 1) * 8 */ + "mov r9, %[r2] \n\t" /* r9 = (num_words - 1) * 8 */ + "movs %[r2], #0 \n\t" /* c0 = 0 */ + "movs %[r3], #0 \n\t" /* c1 = 0 */ + "movs %[r4], #0 \n\t" /* c2 = 0 */ + "movs %[r5], #0 \n\t" /* k = 0 */ + + "push {%[r0]} \n\t" /* keep result on the stack */ + + "1: \n\t" /* outer loop (k < num_words) */ + "movs %[r6], #0 \n\t" /* r6 = i = 0 */ + "b 3f \n\t" + + "2: \n\t" /* outer loop (k >= num_words) */ + "movs %[r6], %[r5] \n\t" /* r6 = k */ + "mov %[r0], r8 \n\t" /* r0 = (num_words - 1) * 4 */ + "subs %[r6], %[r0] \n\t" /* r6 = i = k - (num_words - 1) (times 4) */ + + "3: \n\t" /* inner loop */ + "mov r10, %[r2] \n\t" + "mov r11, %[r3] \n\t" + "mov r12, %[r4] \n\t" + "mov r14, %[r5] \n\t" + "subs %[r7], %[r5], %[r6] \n\t" /* r7 = k - i */ + + "ldr %[r3], [%[r1], %[r7]] \n\t" /* r3 = left[k - i] */ + "ldr %[r0], [%[r1], %[r6]] \n\t" /* r0 = left[i] */ + + "lsrs %[r2], %[r0], #16 \n\t" /* r2 = a1 */ + "uxth %[r0], %[r0] \n\t" /* r0 = a0 */ + + "lsrs %[r4], %[r3], #16 \n\t" /* r4 = b1 */ + "uxth %[r3], %[r3] \n\t" /* r3 = b0 */ + + "movs %[r5], %[r2] \n\t" /* r5 = a1 */ + "muls %[r5], %[r4], %[r5] \n\t" /* r5 = a1 * b1 */ + "muls %[r2], %[r3], %[r2] \n\t" /* r2 = b0 * a1 */ + "muls %[r4], %[r0], %[r4] \n\t" /* r4 = a0 * b1 */ + "muls %[r0], %[r3], %[r0] \n\t" /* r0 = a0 * b0 */ + + /* Add middle terms */ + "lsls %[r3], %[r2], #16 \n\t" + "lsrs %[r2], %[r2], #16 \n\t" + "adds %[r0], %[r3] \n\t" + "adcs %[r5], %[r2] \n\t" + + "lsls %[r3], %[r4], #16 \n\t" + "lsrs %[r4], %[r4], #16 \n\t" + "adds %[r0], %[r3] \n\t" + "adcs %[r5], %[r4] \n\t" + + /* Add to acc, doubling if necessary */ + "mov %[r2], r10\n\t" + "mov %[r3], r11\n\t" + "mov %[r4], r12\n\t" + + "cmp %[r6], %[r7] \n\t" /* (i < k - i) ? */ + "bge 4f \n\t" /* if i >= k - i, skip */ + "movs %[r7], #0 \n\t" /* r7 = 0 */ + "adds %[r2], %[r0] \n\t" /* add low word to c0 */ + "adcs %[r3], %[r5] \n\t" /* add high word to c1, including carry */ + "adcs %[r4], %[r7] \n\t" /* add carry to c2 */ + "4: \n\t" + "movs %[r7], #0 \n\t" /* r7 = 0 */ + "adds %[r2], %[r0] \n\t" /* add low word to c0 */ + "adcs %[r3], %[r5] \n\t" /* add high word to c1, including carry */ + "adcs %[r4], %[r7] \n\t" /* add carry to c2 */ + + "mov %[r5], r14\n\t" /* r5 = k */ + + "adds %[r6], #4 \n\t" /* i += 4 */ + "cmp %[r6], %[r5] \n\t" /* i >= k? */ + "bge 5f \n\t" /* if so, exit the loop */ + "subs %[r7], %[r5], %[r6] \n\t" /* r7 = k - i */ + "cmp %[r6], %[r7] \n\t" /* i <= k - i? */ + "ble 3b \n\t" /* if so, continue looping */ + + "5: \n\t" /* end inner loop */ + + "ldr %[r0], [sp, #0] \n\t" /* r0 = result */ + + "str %[r2], [%[r0], %[r5]] \n\t" /* result[k] = c0 */ + "mov %[r2], %[r3] \n\t" /* c0 = c1 */ + "mov %[r3], %[r4] \n\t" /* c1 = c2 */ + "movs %[r4], #0 \n\t" /* c2 = 0 */ + "adds %[r5], #4 \n\t" /* k += 4 */ + "cmp %[r5], r8 \n\t" /* k <= (num_words - 1) (times 4) ? */ + "ble 1b \n\t" /* if so, loop back, start with i = 0 */ + "cmp %[r5], r9 \n\t" /* k <= (num_words * 2 - 2) (times 4) ? */ + "ble 2b \n\t" /* if so, loop back, with i = (k + 1) - num_words */ + /* end outer loop */ + + "str %[r2], [%[r0], %[r5]] \n\t" /* result[num_words * 2 - 1] = c0 */ + "pop {%[r0]} \n\t" /* pop result off the stack */ + + ".syntax divided \n\t" + : [r2] "+l" (num_words), [r3] "=&l" (r3), [r4] "=&l" (r4), + [r5] "=&l" (r5), [r6] "=&l" (r6), [r7] "=&l" (r7) + : [r0] "l" (result), [r1] "l" (left) + : "r8", "r9", "r10", "r11", "r12", "r14", "cc", "memory" + ); +#endif +} +#define asm_square 1 +#endif +#endif /* uECC_SQUARE_FUNC */ + +#endif /* _UECC_ASM_ARM_H_ */ diff --git a/web/server/h2o/libh2o/deps/picotls/deps/micro-ecc/asm_arm_mult_square.inc b/web/server/h2o/libh2o/deps/picotls/deps/micro-ecc/asm_arm_mult_square.inc new file mode 100644 index 00000000..8907fc18 --- /dev/null +++ b/web/server/h2o/libh2o/deps/picotls/deps/micro-ecc/asm_arm_mult_square.inc @@ -0,0 +1,2311 @@ +/* Copyright 2015, Kenneth MacKay. Licensed under the BSD 2-clause license. */ + +#ifndef _UECC_ASM_ARM_MULT_SQUARE_H_ +#define _UECC_ASM_ARM_MULT_SQUARE_H_ + +#define FAST_MULT_ASM_5 \ + "push {r3} \n\t" \ + "add r0, 12 \n\t" \ + "add r2, 12 \n\t" \ + "ldmia r1!, {r3,r4} \n\t" \ + "ldmia r2!, {r6,r7} \n\t" \ + \ + "umull r11, r12, r3, r6 \n\t" \ + "stmia r0!, {r11} \n\t" \ + \ + "mov r10, #0 \n\t" \ + "umull r11, r9, r3, r7 \n\t" \ + "adds r12, r12, r11 \n\t" \ + "adc r9, r9, #0 \n\t" \ + "umull r11, r14, r4, r6 \n\t" \ + "adds r12, r12, r11 \n\t" \ + "adcs r9, r9, r14 \n\t" \ + "adc r10, r10, #0 \n\t" \ + "stmia r0!, {r12} \n\t" \ + \ + "umull r12, r14, r4, r7 \n\t" \ + "adds r9, r9, r12 \n\t" \ + "adc r10, r10, r14 \n\t" \ + "stmia r0!, {r9, r10} \n\t" \ + \ + "sub r0, 28 \n\t" \ + "sub r2, 20 \n\t" \ + "ldmia r2!, {r6,r7,r8} \n\t" \ + "ldmia r1!, {r5} \n\t" \ + \ + "umull r11, r12, r3, r6 \n\t" \ + "stmia r0!, {r11} \n\t" \ + \ + "mov r10, #0 \n\t" \ + "umull r11, r9, r3, r7 \n\t" \ + "adds r12, r12, r11 \n\t" \ + "adc r9, r9, #0 \n\t" \ + "umull r11, r14, r4, r6 \n\t" \ + "adds r12, r12, r11 \n\t" \ + "adcs r9, r9, r14 \n\t" \ + "adc r10, r10, #0 \n\t" \ + "stmia r0!, {r12} \n\t" \ + \ + "mov r11, #0 \n\t" \ + "umull r12, r14, r3, r8 \n\t" \ + "adds r9, r9, r12 \n\t" \ + "adcs r10, r10, r14 \n\t" \ + "adc r11, r11, #0 \n\t" \ + "umull r12, r14, r4, r7 \n\t" \ + "adds r9, r9, r12 \n\t" \ + "adcs r10, r10, r14 \n\t" \ + "adc r11, r11, #0 \n\t" \ + "umull r12, r14, r5, r6 \n\t" \ + "adds r9, r9, r12 \n\t" \ + "adcs r10, r10, r14 \n\t" \ + "adc r11, r11, #0 \n\t" \ + "stmia r0!, {r9} \n\t" \ + \ + "ldmia r1!, {r3} \n\t" \ + "mov r12, #0 \n\t" \ + "umull r14, r9, r4, r8 \n\t" \ + "adds r10, r10, r14 \n\t" \ + "adcs r11, r11, r9 \n\t" \ + "adc r12, r12, #0 \n\t" \ + "umull r14, r9, r5, r7 \n\t" \ + "adds r10, r10, r14 \n\t" \ + "adcs r11, r11, r9 \n\t" \ + "adc r12, r12, #0 \n\t" \ + "umull r14, r9, r3, r6 \n\t" \ + "adds r10, r10, r14 \n\t" \ + "adcs r11, r11, r9 \n\t" \ + "adc r12, r12, #0 \n\t" \ + "ldr r14, [r0] \n\t" \ + "adds r10, r10, r14 \n\t" \ + "adcs r11, r11, #0 \n\t" \ + "adc r12, r12, #0 \n\t" \ + "stmia r0!, {r10} \n\t" \ + \ + "ldmia r1!, {r4} \n\t" \ + "mov r14, #0 \n\t" \ + "umull r9, r10, r5, r8 \n\t" \ + "adds r11, r11, r9 \n\t" \ + "adcs r12, r12, r10 \n\t" \ + "adc r14, r14, #0 \n\t" \ + "umull r9, r10, r3, r7 \n\t" \ + "adds r11, r11, r9 \n\t" \ + "adcs r12, r12, r10 \n\t" \ + "adc r14, r14, #0 \n\t" \ + "umull r9, r10, r4, r6 \n\t" \ + "adds r11, r11, r9 \n\t" \ + "adcs r12, r12, r10 \n\t" \ + "adc r14, r14, #0 \n\t" \ + "ldr r9, [r0] \n\t" \ + "adds r11, r11, r9 \n\t" \ + "adcs r12, r12, #0 \n\t" \ + "adc r14, r14, #0 \n\t" \ + "stmia r0!, {r11} \n\t" \ + \ + "ldmia r2!, {r6} \n\t" \ + "mov r9, #0 \n\t" \ + "umull r10, r11, r5, r6 \n\t" \ + "adds r12, r12, r10 \n\t" \ + "adcs r14, r14, r11 \n\t" \ + "adc r9, r9, #0 \n\t" \ + "umull r10, r11, r3, r8 \n\t" \ + "adds r12, r12, r10 \n\t" \ + "adcs r14, r14, r11 \n\t" \ + "adc r9, r9, #0 \n\t" \ + "umull r10, r11, r4, r7 \n\t" \ + "adds r12, r12, r10 \n\t" \ + "adcs r14, r14, r11 \n\t" \ + "adc r9, r9, #0 \n\t" \ + "ldr r10, [r0] \n\t" \ + "adds r12, r12, r10 \n\t" \ + "adcs r14, r14, #0 \n\t" \ + "adc r9, r9, #0 \n\t" \ + "stmia r0!, {r12} \n\t" \ + \ + "ldmia r2!, {r7} \n\t" \ + "mov r10, #0 \n\t" \ + "umull r11, r12, r5, r7 \n\t" \ + "adds r14, r14, r11 \n\t" \ + "adcs r9, r9, r12 \n\t" \ + "adc r10, r10, #0 \n\t" \ + "umull r11, r12, r3, r6 \n\t" \ + "adds r14, r14, r11 \n\t" \ + "adcs r9, r9, r12 \n\t" \ + "adc r10, r10, #0 \n\t" \ + "umull r11, r12, r4, r8 \n\t" \ + "adds r14, r14, r11 \n\t" \ + "adcs r9, r9, r12 \n\t" \ + "adc r10, r10, #0 \n\t" \ + "ldr r11, [r0] \n\t" \ + "adds r14, r14, r11 \n\t" \ + "adcs r9, r9, #0 \n\t" \ + "adc r10, r10, #0 \n\t" \ + "stmia r0!, {r14} \n\t" \ + \ + "mov r11, #0 \n\t" \ + "umull r12, r14, r3, r7 \n\t" \ + "adds r9, r9, r12 \n\t" \ + "adcs r10, r10, r14 \n\t" \ + "adc r11, r11, #0 \n\t" \ + "umull r12, r14, r4, r6 \n\t" \ + "adds r9, r9, r12 \n\t" \ + "adcs r10, r10, r14 \n\t" \ + "adc r11, r11, #0 \n\t" \ + "stmia r0!, {r9} \n\t" \ + \ + "umull r14, r9, r4, r7 \n\t" \ + "adds r10, r10, r14 \n\t" \ + "adc r11, r11, r9 \n\t" \ + "stmia r0!, {r10, r11} \n\t" \ + "pop {r3} \n\t" + +#define FAST_MULT_ASM_5_TO_6 \ + "cmp r3, #5 \n\t" \ + "beq 1f \n\t" \ + \ + /* r4 = left high, r5 = right high */ \ + "ldr r4, [r1] \n\t" \ + "ldr r5, [r2] \n\t" \ + \ + "sub r0, #20 \n\t" \ + "sub r1, #20 \n\t" \ + "sub r2, #20 \n\t" \ + \ + "ldr r6, [r0] \n\t" \ + "ldr r7, [r1], #4 \n\t" \ + "ldr r8, [r2], #4 \n\t" \ + "mov r14, #0 \n\t" \ + "umull r9, r10, r4, r8 \n\t" \ + "umull r11, r12, r5, r7 \n\t" \ + "adds r9, r9, r6 \n\t" \ + "adc r10, r10, #0 \n\t" \ + "adds r9, r9, r11 \n\t" \ + "adcs r10, r10, r12 \n\t" \ + "adc r14, r14, #0 \n\t" \ + "str r9, [r0], #4 \n\t" \ + \ + "ldr r6, [r0] \n\t" \ + "adds r10, r10, r6 \n\t" \ + "adcs r14, r14, #0 \n\t" \ + "ldr r7, [r1], #4 \n\t" \ + "ldr r8, [r2], #4 \n\t" \ + "mov r9, #0 \n\t" \ + "umull r11, r12, r4, r8 \n\t" \ + "adds r10, r10, r11 \n\t" \ + "adcs r14, r14, r12 \n\t" \ + "adc r9, r9, #0 \n\t" \ + "umull r11, r12, r5, r7 \n\t" \ + "adds r10, r10, r11 \n\t" \ + "adcs r14, r14, r12 \n\t" \ + "adc r9, r9, #0 \n\t" \ + "str r10, [r0], #4 \n\t" \ + \ + "ldr r6, [r0] \n\t" \ + "adds r14, r14, r6 \n\t" \ + "adcs r9, r9, #0 \n\t" \ + "ldr r7, [r1], #4 \n\t" \ + "ldr r8, [r2], #4 \n\t" \ + "mov r10, #0 \n\t" \ + "umull r11, r12, r4, r8 \n\t" \ + "adds r14, r14, r11 \n\t" \ + "adcs r9, r9, r12 \n\t" \ + "adc r10, r10, #0 \n\t" \ + "umull r11, r12, r5, r7 \n\t" \ + "adds r14, r14, r11 \n\t" \ + "adcs r9, r9, r12 \n\t" \ + "adc r10, r10, #0 \n\t" \ + "str r14, [r0], #4 \n\t" \ + \ + "ldr r6, [r0] \n\t" \ + "adds r9, r9, r6 \n\t" \ + "adcs r10, r10, #0 \n\t" \ + "ldr r7, [r1], #4 \n\t" \ + "ldr r8, [r2], #4 \n\t" \ + "mov r14, #0 \n\t" \ + "umull r11, r12, r4, r8 \n\t" \ + "adds r9, r9, r11 \n\t" \ + "adcs r10, r10, r12 \n\t" \ + "adc r14, r14, #0 \n\t" \ + "umull r11, r12, r5, r7 \n\t" \ + "adds r9, r9, r11 \n\t" \ + "adcs r10, r10, r12 \n\t" \ + "adc r14, r14, #0 \n\t" \ + "str r9, [r0], #4 \n\t" \ + \ + "ldr r6, [r0] \n\t" \ + "adds r10, r10, r6 \n\t" \ + "adcs r14, r14, #0 \n\t" \ + /* skip past already-loaded (r4, r5) */ \ + "ldr r7, [r1], #8 \n\t" \ + "ldr r8, [r2], #8 \n\t" \ + "mov r9, #0 \n\t" \ + "umull r11, r12, r4, r8 \n\t" \ + "adds r10, r10, r11 \n\t" \ + "adcs r14, r14, r12 \n\t" \ + "adc r9, r9, #0 \n\t" \ + "umull r11, r12, r5, r7 \n\t" \ + "adds r10, r10, r11 \n\t" \ + "adcs r14, r14, r12 \n\t" \ + "adc r9, r9, #0 \n\t" \ + "str r10, [r0], #4 \n\t" \ + \ + "umull r11, r12, r4, r5 \n\t" \ + "adds r11, r11, r14 \n\t" \ + "adc r12, r12, r9 \n\t" \ + "stmia r0!, {r11, r12} \n\t" + +#define FAST_MULT_ASM_6 \ + "push {r3} \n\t" \ + "add r0, 12 \n\t" \ + "add r2, 12 \n\t" \ + "ldmia r1!, {r3,r4,r5} \n\t" \ + "ldmia r2!, {r6,r7,r8} \n\t" \ + \ + "umull r11, r12, r3, r6 \n\t" \ + "stmia r0!, {r11} \n\t" \ + \ + "mov r10, #0 \n\t" \ + "umull r11, r9, r3, r7 \n\t" \ + "adds r12, r12, r11 \n\t" \ + "adc r9, r9, #0 \n\t" \ + "umull r11, r14, r4, r6 \n\t" \ + "adds r12, r12, r11 \n\t" \ + "adcs r9, r9, r14 \n\t" \ + "adc r10, r10, #0 \n\t" \ + "stmia r0!, {r12} \n\t" \ + \ + "mov r11, #0 \n\t" \ + "umull r12, r14, r3, r8 \n\t" \ + "adds r9, r9, r12 \n\t" \ + "adcs r10, r10, r14 \n\t" \ + "adc r11, r11, #0 \n\t" \ + "umull r12, r14, r4, r7 \n\t" \ + "adds r9, r9, r12 \n\t" \ + "adcs r10, r10, r14 \n\t" \ + "adc r11, r11, #0 \n\t" \ + "umull r12, r14, r5, r6 \n\t" \ + "adds r9, r9, r12 \n\t" \ + "adcs r10, r10, r14 \n\t" \ + "adc r11, r11, #0 \n\t" \ + "stmia r0!, {r9} \n\t" \ + \ + "mov r12, #0 \n\t" \ + "umull r14, r9, r4, r8 \n\t" \ + "adds r10, r10, r14 \n\t" \ + "adcs r11, r11, r9 \n\t" \ + "adc r12, r12, #0 \n\t" \ + "umull r14, r9, r5, r7 \n\t" \ + "adds r10, r10, r14 \n\t" \ + "adcs r11, r11, r9 \n\t" \ + "adc r12, r12, #0 \n\t" \ + "stmia r0!, {r10} \n\t" \ + \ + "umull r9, r10, r5, r8 \n\t" \ + "adds r11, r11, r9 \n\t" \ + "adc r12, r12, r10 \n\t" \ + "stmia r0!, {r11, r12} \n\t" \ + \ + "sub r0, 36 \n\t" \ + "sub r2, 24 \n\t" \ + "ldmia r2!, {r6,r7,r8} \n\t" \ + \ + "umull r11, r12, r3, r6 \n\t" \ + "stmia r0!, {r11} \n\t" \ + \ + "mov r10, #0 \n\t" \ + "umull r11, r9, r3, r7 \n\t" \ + "adds r12, r12, r11 \n\t" \ + "adc r9, r9, #0 \n\t" \ + "umull r11, r14, r4, r6 \n\t" \ + "adds r12, r12, r11 \n\t" \ + "adcs r9, r9, r14 \n\t" \ + "adc r10, r10, #0 \n\t" \ + "stmia r0!, {r12} \n\t" \ + \ + "mov r11, #0 \n\t" \ + "umull r12, r14, r3, r8 \n\t" \ + "adds r9, r9, r12 \n\t" \ + "adcs r10, r10, r14 \n\t" \ + "adc r11, r11, #0 \n\t" \ + "umull r12, r14, r4, r7 \n\t" \ + "adds r9, r9, r12 \n\t" \ + "adcs r10, r10, r14 \n\t" \ + "adc r11, r11, #0 \n\t" \ + "umull r12, r14, r5, r6 \n\t" \ + "adds r9, r9, r12 \n\t" \ + "adcs r10, r10, r14 \n\t" \ + "adc r11, r11, #0 \n\t" \ + "stmia r0!, {r9} \n\t" \ + \ + "ldmia r1!, {r3} \n\t" \ + "mov r12, #0 \n\t" \ + "umull r14, r9, r4, r8 \n\t" \ + "adds r10, r10, r14 \n\t" \ + "adcs r11, r11, r9 \n\t" \ + "adc r12, r12, #0 \n\t" \ + "umull r14, r9, r5, r7 \n\t" \ + "adds r10, r10, r14 \n\t" \ + "adcs r11, r11, r9 \n\t" \ + "adc r12, r12, #0 \n\t" \ + "umull r14, r9, r3, r6 \n\t" \ + "adds r10, r10, r14 \n\t" \ + "adcs r11, r11, r9 \n\t" \ + "adc r12, r12, #0 \n\t" \ + "ldr r14, [r0] \n\t" \ + "adds r10, r10, r14 \n\t" \ + "adcs r11, r11, #0 \n\t" \ + "adc r12, r12, #0 \n\t" \ + "stmia r0!, {r10} \n\t" \ + \ + "ldmia r1!, {r4} \n\t" \ + "mov r14, #0 \n\t" \ + "umull r9, r10, r5, r8 \n\t" \ + "adds r11, r11, r9 \n\t" \ + "adcs r12, r12, r10 \n\t" \ + "adc r14, r14, #0 \n\t" \ + "umull r9, r10, r3, r7 \n\t" \ + "adds r11, r11, r9 \n\t" \ + "adcs r12, r12, r10 \n\t" \ + "adc r14, r14, #0 \n\t" \ + "umull r9, r10, r4, r6 \n\t" \ + "adds r11, r11, r9 \n\t" \ + "adcs r12, r12, r10 \n\t" \ + "adc r14, r14, #0 \n\t" \ + "ldr r9, [r0] \n\t" \ + "adds r11, r11, r9 \n\t" \ + "adcs r12, r12, #0 \n\t" \ + "adc r14, r14, #0 \n\t" \ + "stmia r0!, {r11} \n\t" \ + \ + "ldmia r1!, {r5} \n\t" \ + "mov r9, #0 \n\t" \ + "umull r10, r11, r3, r8 \n\t" \ + "adds r12, r12, r10 \n\t" \ + "adcs r14, r14, r11 \n\t" \ + "adc r9, r9, #0 \n\t" \ + "umull r10, r11, r4, r7 \n\t" \ + "adds r12, r12, r10 \n\t" \ + "adcs r14, r14, r11 \n\t" \ + "adc r9, r9, #0 \n\t" \ + "umull r10, r11, r5, r6 \n\t" \ + "adds r12, r12, r10 \n\t" \ + "adcs r14, r14, r11 \n\t" \ + "adc r9, r9, #0 \n\t" \ + "ldr r10, [r0] \n\t" \ + "adds r12, r12, r10 \n\t" \ + "adcs r14, r14, #0 \n\t" \ + "adc r9, r9, #0 \n\t" \ + "stmia r0!, {r12} \n\t" \ + \ + "ldmia r2!, {r6} \n\t" \ + "mov r10, #0 \n\t" \ + "umull r11, r12, r3, r6 \n\t" \ + "adds r14, r14, r11 \n\t" \ + "adcs r9, r9, r12 \n\t" \ + "adc r10, r10, #0 \n\t" \ + "umull r11, r12, r4, r8 \n\t" \ + "adds r14, r14, r11 \n\t" \ + "adcs r9, r9, r12 \n\t" \ + "adc r10, r10, #0 \n\t" \ + "umull r11, r12, r5, r7 \n\t" \ + "adds r14, r14, r11 \n\t" \ + "adcs r9, r9, r12 \n\t" \ + "adc r10, r10, #0 \n\t" \ + "ldr r11, [r0] \n\t" \ + "adds r14, r14, r11 \n\t" \ + "adcs r9, r9, #0 \n\t" \ + "adc r10, r10, #0 \n\t" \ + "stmia r0!, {r14} \n\t" \ + \ + "ldmia r2!, {r7} \n\t" \ + "mov r11, #0 \n\t" \ + "umull r12, r14, r3, r7 \n\t" \ + "adds r9, r9, r12 \n\t" \ + "adcs r10, r10, r14 \n\t" \ + "adc r11, r11, #0 \n\t" \ + "umull r12, r14, r4, r6 \n\t" \ + "adds r9, r9, r12 \n\t" \ + "adcs r10, r10, r14 \n\t" \ + "adc r11, r11, #0 \n\t" \ + "umull r12, r14, r5, r8 \n\t" \ + "adds r9, r9, r12 \n\t" \ + "adcs r10, r10, r14 \n\t" \ + "adc r11, r11, #0 \n\t" \ + "ldr r12, [r0] \n\t" \ + "adds r9, r9, r12 \n\t" \ + "adcs r10, r10, #0 \n\t" \ + "adc r11, r11, #0 \n\t" \ + "stmia r0!, {r9} \n\t" \ + \ + "ldmia r2!, {r8} \n\t" \ + "mov r12, #0 \n\t" \ + "umull r14, r9, r3, r8 \n\t" \ + "adds r10, r10, r14 \n\t" \ + "adcs r11, r11, r9 \n\t" \ + "adc r12, r12, #0 \n\t" \ + "umull r14, r9, r4, r7 \n\t" \ + "adds r10, r10, r14 \n\t" \ + "adcs r11, r11, r9 \n\t" \ + "adc r12, r12, #0 \n\t" \ + "umull r14, r9, r5, r6 \n\t" \ + "adds r10, r10, r14 \n\t" \ + "adcs r11, r11, r9 \n\t" \ + "adc r12, r12, #0 \n\t" \ + "ldr r14, [r0] \n\t" \ + "adds r10, r10, r14 \n\t" \ + "adcs r11, r11, #0 \n\t" \ + "adc r12, r12, #0 \n\t" \ + "stmia r0!, {r10} \n\t" \ + \ + "mov r14, #0 \n\t" \ + "umull r9, r10, r4, r8 \n\t" \ + "adds r11, r11, r9 \n\t" \ + "adcs r12, r12, r10 \n\t" \ + "adc r14, r14, #0 \n\t" \ + "umull r9, r10, r5, r7 \n\t" \ + "adds r11, r11, r9 \n\t" \ + "adcs r12, r12, r10 \n\t" \ + "adc r14, r14, #0 \n\t" \ + "stmia r0!, {r11} \n\t" \ + \ + "umull r10, r11, r5, r8 \n\t" \ + "adds r12, r12, r10 \n\t" \ + "adc r14, r14, r11 \n\t" \ + "stmia r0!, {r12, r14} \n\t" \ + "pop {r3} \n\t" + +#define FAST_MULT_ASM_6_TO_7 \ + "cmp r3, #6 \n\t" \ + "beq 1f \n\t" \ + \ + /* r4 = left high, r5 = right high */ \ + "ldr r4, [r1] \n\t" \ + "ldr r5, [r2] \n\t" \ + \ + "sub r0, #24 \n\t" \ + "sub r1, #24 \n\t" \ + "sub r2, #24 \n\t" \ + \ + "ldr r6, [r0] \n\t" \ + "ldr r7, [r1], #4 \n\t" \ + "ldr r8, [r2], #4 \n\t" \ + "mov r14, #0 \n\t" \ + "umull r9, r10, r4, r8 \n\t" \ + "umull r11, r12, r5, r7 \n\t" \ + "adds r9, r9, r6 \n\t" \ + "adc r10, r10, #0 \n\t" \ + "adds r9, r9, r11 \n\t" \ + "adcs r10, r10, r12 \n\t" \ + "adc r14, r14, #0 \n\t" \ + "str r9, [r0], #4 \n\t" \ + \ + "ldr r6, [r0] \n\t" \ + "adds r10, r10, r6 \n\t" \ + "adcs r14, r14, #0 \n\t" \ + "ldr r7, [r1], #4 \n\t" \ + "ldr r8, [r2], #4 \n\t" \ + "mov r9, #0 \n\t" \ + "umull r11, r12, r4, r8 \n\t" \ + "adds r10, r10, r11 \n\t" \ + "adcs r14, r14, r12 \n\t" \ + "adc r9, r9, #0 \n\t" \ + "umull r11, r12, r5, r7 \n\t" \ + "adds r10, r10, r11 \n\t" \ + "adcs r14, r14, r12 \n\t" \ + "adc r9, r9, #0 \n\t" \ + "str r10, [r0], #4 \n\t" \ + \ + "ldr r6, [r0] \n\t" \ + "adds r14, r14, r6 \n\t" \ + "adcs r9, r9, #0 \n\t" \ + "ldr r7, [r1], #4 \n\t" \ + "ldr r8, [r2], #4 \n\t" \ + "mov r10, #0 \n\t" \ + "umull r11, r12, r4, r8 \n\t" \ + "adds r14, r14, r11 \n\t" \ + "adcs r9, r9, r12 \n\t" \ + "adc r10, r10, #0 \n\t" \ + "umull r11, r12, r5, r7 \n\t" \ + "adds r14, r14, r11 \n\t" \ + "adcs r9, r9, r12 \n\t" \ + "adc r10, r10, #0 \n\t" \ + "str r14, [r0], #4 \n\t" \ + \ + "ldr r6, [r0] \n\t" \ + "adds r9, r9, r6 \n\t" \ + "adcs r10, r10, #0 \n\t" \ + "ldr r7, [r1], #4 \n\t" \ + "ldr r8, [r2], #4 \n\t" \ + "mov r14, #0 \n\t" \ + "umull r11, r12, r4, r8 \n\t" \ + "adds r9, r9, r11 \n\t" \ + "adcs r10, r10, r12 \n\t" \ + "adc r14, r14, #0 \n\t" \ + "umull r11, r12, r5, r7 \n\t" \ + "adds r9, r9, r11 \n\t" \ + "adcs r10, r10, r12 \n\t" \ + "adc r14, r14, #0 \n\t" \ + "str r9, [r0], #4 \n\t" \ + \ + "ldr r6, [r0] \n\t" \ + "adds r10, r10, r6 \n\t" \ + "adcs r14, r14, #0 \n\t" \ + "ldr r7, [r1], #4 \n\t" \ + "ldr r8, [r2], #4 \n\t" \ + "mov r9, #0 \n\t" \ + "umull r11, r12, r4, r8 \n\t" \ + "adds r10, r10, r11 \n\t" \ + "adcs r14, r14, r12 \n\t" \ + "adc r9, r9, #0 \n\t" \ + "umull r11, r12, r5, r7 \n\t" \ + "adds r10, r10, r11 \n\t" \ + "adcs r14, r14, r12 \n\t" \ + "adc r9, r9, #0 \n\t" \ + "str r10, [r0], #4 \n\t" \ + \ + "ldr r6, [r0] \n\t" \ + "adds r14, r14, r6 \n\t" \ + "adcs r9, r9, #0 \n\t" \ + /* skip past already-loaded (r4, r5) */ \ + "ldr r7, [r1], #8 \n\t" \ + "ldr r8, [r2], #8 \n\t" \ + "mov r10, #0 \n\t" \ + "umull r11, r12, r4, r8 \n\t" \ + "adds r14, r14, r11 \n\t" \ + "adcs r9, r9, r12 \n\t" \ + "adc r10, r10, #0 \n\t" \ + "umull r11, r12, r5, r7 \n\t" \ + "adds r14, r14, r11 \n\t" \ + "adcs r9, r9, r12 \n\t" \ + "adc r10, r10, #0 \n\t" \ + "str r14, [r0], #4 \n\t" \ + \ + "umull r11, r12, r4, r5 \n\t" \ + "adds r11, r11, r9 \n\t" \ + "adc r12, r12, r10 \n\t" \ + "stmia r0!, {r11, r12} \n\t" + +#define FAST_MULT_ASM_7 \ + "push {r3} \n\t" \ + "add r0, 24 \n\t" \ + "add r2, 24 \n\t" \ + "ldmia r1!, {r3} \n\t" \ + "ldmia r2!, {r6} \n\t" \ + \ + "umull r9, r10, r3, r6 \n\t" \ + "stmia r0!, {r9, r10} \n\t" \ + \ + "sub r0, 20 \n\t" \ + "sub r2, 16 \n\t" \ + "ldmia r2!, {r6, r7, r8} \n\t" \ + "ldmia r1!, {r4, r5} \n\t" \ + \ + "umull r9, r10, r3, r6 \n\t" \ + "stmia r0!, {r9} \n\t" \ + \ + "mov r14, #0 \n\t" \ + "umull r9, r12, r3, r7 \n\t" \ + "adds r10, r10, r9 \n\t" \ + "adc r12, r12, #0 \n\t" \ + "umull r9, r11, r4, r6 \n\t" \ + "adds r10, r10, r9 \n\t" \ + "adcs r12, r12, r11 \n\t" \ + "adc r14, r14, #0 \n\t" \ + "stmia r0!, {r10} \n\t" \ + \ + "mov r9, #0 \n\t" \ + "umull r10, r11, r3, r8 \n\t" \ + "adds r12, r12, r10 \n\t" \ + "adcs r14, r14, r11 \n\t" \ + "adc r9, r9, #0 \n\t" \ + "umull r10, r11, r4, r7 \n\t" \ + "adds r12, r12, r10 \n\t" \ + "adcs r14, r14, r11 \n\t" \ + "adc r9, r9, #0 \n\t" \ + "umull r10, r11, r5, r6 \n\t" \ + "adds r12, r12, r10 \n\t" \ + "adcs r14, r14, r11 \n\t" \ + "adc r9, r9, #0 \n\t" \ + "stmia r0!, {r12} \n\t" \ + \ + "ldmia r1!, {r3} \n\t" \ + "mov r10, #0 \n\t" \ + "umull r11, r12, r4, r8 \n\t" \ + "adds r14, r14, r11 \n\t" \ + "adcs r9, r9, r12 \n\t" \ + "adc r10, r10, #0 \n\t" \ + "umull r11, r12, r5, r7 \n\t" \ + "adds r14, r14, r11 \n\t" \ + "adcs r9, r9, r12 \n\t" \ + "adc r10, r10, #0 \n\t" \ + "umull r11, r12, r3, r6 \n\t" \ + "adds r14, r14, r11 \n\t" \ + "adcs r9, r9, r12 \n\t" \ + "adc r10, r10, #0 \n\t" \ + "ldr r11, [r0] \n\t" \ + "adds r14, r14, r11 \n\t" \ + "adcs r9, r9, #0 \n\t" \ + "adc r10, r10, #0 \n\t" \ + "stmia r0!, {r14} \n\t" \ + \ + "ldmia r2!, {r6} \n\t" \ + "mov r11, #0 \n\t" \ + "umull r12, r14, r4, r6 \n\t" \ + "adds r9, r9, r12 \n\t" \ + "adcs r10, r10, r14 \n\t" \ + "adc r11, r11, #0 \n\t" \ + "umull r12, r14, r5, r8 \n\t" \ + "adds r9, r9, r12 \n\t" \ + "adcs r10, r10, r14 \n\t" \ + "adc r11, r11, #0 \n\t" \ + "umull r12, r14, r3, r7 \n\t" \ + "adds r9, r9, r12 \n\t" \ + "adcs r10, r10, r14 \n\t" \ + "adc r11, r11, #0 \n\t" \ + "ldr r12, [r0] \n\t" \ + "adds r9, r9, r12 \n\t" \ + "adcs r10, r10, #0 \n\t" \ + "adc r11, r11, #0 \n\t" \ + "stmia r0!, {r9} \n\t" \ + \ + "mov r12, #0 \n\t" \ + "umull r14, r9, r5, r6 \n\t" \ + "adds r10, r10, r14 \n\t" \ + "adcs r11, r11, r9 \n\t" \ + "adc r12, r12, #0 \n\t" \ + "umull r14, r9, r3, r8 \n\t" \ + "adds r10, r10, r14 \n\t" \ + "adcs r11, r11, r9 \n\t" \ + "adc r12, r12, #0 \n\t" \ + "stmia r0!, {r10} \n\t" \ + \ + "umull r9, r10, r3, r6 \n\t" \ + "adds r11, r11, r9 \n\t" \ + "adc r12, r12, r10 \n\t" \ + "stmia r0!, {r11, r12} \n\t" \ + \ + "sub r0, 44 \n\t" \ + "sub r1, 16 \n\t" \ + "sub r2, 28 \n\t" \ + "ldmia r1!, {r3,r4,r5} \n\t" \ + "ldmia r2!, {r6,r7,r8} \n\t" \ + \ + "umull r9, r10, r3, r6 \n\t" \ + "stmia r0!, {r9} \n\t" \ + \ + "mov r14, #0 \n\t" \ + "umull r9, r12, r3, r7 \n\t" \ + "adds r10, r10, r9 \n\t" \ + "adc r12, r12, #0 \n\t" \ + "umull r9, r11, r4, r6 \n\t" \ + "adds r10, r10, r9 \n\t" \ + "adcs r12, r12, r11 \n\t" \ + "adc r14, r14, #0 \n\t" \ + "stmia r0!, {r10} \n\t" \ + \ + "mov r9, #0 \n\t" \ + "umull r10, r11, r3, r8 \n\t" \ + "adds r12, r12, r10 \n\t" \ + "adcs r14, r14, r11 \n\t" \ + "adc r9, r9, #0 \n\t" \ + "umull r10, r11, r4, r7 \n\t" \ + "adds r12, r12, r10 \n\t" \ + "adcs r14, r14, r11 \n\t" \ + "adc r9, r9, #0 \n\t" \ + "umull r10, r11, r5, r6 \n\t" \ + "adds r12, r12, r10 \n\t" \ + "adcs r14, r14, r11 \n\t" \ + "adc r9, r9, #0 \n\t" \ + "stmia r0!, {r12} \n\t" \ + \ + "ldmia r1!, {r3} \n\t" \ + "mov r10, #0 \n\t" \ + "umull r11, r12, r4, r8 \n\t" \ + "adds r14, r14, r11 \n\t" \ + "adcs r9, r9, r12 \n\t" \ + "adc r10, r10, #0 \n\t" \ + "umull r11, r12, r5, r7 \n\t" \ + "adds r14, r14, r11 \n\t" \ + "adcs r9, r9, r12 \n\t" \ + "adc r10, r10, #0 \n\t" \ + "umull r11, r12, r3, r6 \n\t" \ + "adds r14, r14, r11 \n\t" \ + "adcs r9, r9, r12 \n\t" \ + "adc r10, r10, #0 \n\t" \ + "ldr r11, [r0] \n\t" \ + "adds r14, r14, r11 \n\t" \ + "adcs r9, r9, #0 \n\t" \ + "adc r10, r10, #0 \n\t" \ + "stmia r0!, {r14} \n\t" \ + \ + "ldmia r1!, {r4} \n\t" \ + "mov r11, #0 \n\t" \ + "umull r12, r14, r5, r8 \n\t" \ + "adds r9, r9, r12 \n\t" \ + "adcs r10, r10, r14 \n\t" \ + "adc r11, r11, #0 \n\t" \ + "umull r12, r14, r3, r7 \n\t" \ + "adds r9, r9, r12 \n\t" \ + "adcs r10, r10, r14 \n\t" \ + "adc r11, r11, #0 \n\t" \ + "umull r12, r14, r4, r6 \n\t" \ + "adds r9, r9, r12 \n\t" \ + "adcs r10, r10, r14 \n\t" \ + "adc r11, r11, #0 \n\t" \ + "ldr r12, [r0] \n\t" \ + "adds r9, r9, r12 \n\t" \ + "adcs r10, r10, #0 \n\t" \ + "adc r11, r11, #0 \n\t" \ + "stmia r0!, {r9} \n\t" \ + \ + "ldmia r1!, {r5} \n\t" \ + "mov r12, #0 \n\t" \ + "umull r14, r9, r3, r8 \n\t" \ + "adds r10, r10, r14 \n\t" \ + "adcs r11, r11, r9 \n\t" \ + "adc r12, r12, #0 \n\t" \ + "umull r14, r9, r4, r7 \n\t" \ + "adds r10, r10, r14 \n\t" \ + "adcs r11, r11, r9 \n\t" \ + "adc r12, r12, #0 \n\t" \ + "umull r14, r9, r5, r6 \n\t" \ + "adds r10, r10, r14 \n\t" \ + "adcs r11, r11, r9 \n\t" \ + "adc r12, r12, #0 \n\t" \ + "ldr r14, [r0] \n\t" \ + "adds r10, r10, r14 \n\t" \ + "adcs r11, r11, #0 \n\t" \ + "adc r12, r12, #0 \n\t" \ + "stmia r0!, {r10} \n\t" \ + \ + "ldmia r1!, {r3} \n\t" \ + "mov r14, #0 \n\t" \ + "umull r9, r10, r4, r8 \n\t" \ + "adds r11, r11, r9 \n\t" \ + "adcs r12, r12, r10 \n\t" \ + "adc r14, r14, #0 \n\t" \ + "umull r9, r10, r5, r7 \n\t" \ + "adds r11, r11, r9 \n\t" \ + "adcs r12, r12, r10 \n\t" \ + "adc r14, r14, #0 \n\t" \ + "umull r9, r10, r3, r6 \n\t" \ + "adds r11, r11, r9 \n\t" \ + "adcs r12, r12, r10 \n\t" \ + "adc r14, r14, #0 \n\t" \ + "ldr r9, [r0] \n\t" \ + "adds r11, r11, r9 \n\t" \ + "adcs r12, r12, #0 \n\t" \ + "adc r14, r14, #0 \n\t" \ + "stmia r0!, {r11} \n\t" \ + \ + "ldmia r2!, {r6} \n\t" \ + "mov r9, #0 \n\t" \ + "umull r10, r11, r4, r6 \n\t" \ + "adds r12, r12, r10 \n\t" \ + "adcs r14, r14, r11 \n\t" \ + "adc r9, r9, #0 \n\t" \ + "umull r10, r11, r5, r8 \n\t" \ + "adds r12, r12, r10 \n\t" \ + "adcs r14, r14, r11 \n\t" \ + "adc r9, r9, #0 \n\t" \ + "umull r10, r11, r3, r7 \n\t" \ + "adds r12, r12, r10 \n\t" \ + "adcs r14, r14, r11 \n\t" \ + "adc r9, r9, #0 \n\t" \ + "ldr r10, [r0] \n\t" \ + "adds r12, r12, r10 \n\t" \ + "adcs r14, r14, #0 \n\t" \ + "adc r9, r9, #0 \n\t" \ + "stmia r0!, {r12} \n\t" \ + \ + "ldmia r2!, {r7} \n\t" \ + "mov r10, #0 \n\t" \ + "umull r11, r12, r4, r7 \n\t" \ + "adds r14, r14, r11 \n\t" \ + "adcs r9, r9, r12 \n\t" \ + "adc r10, r10, #0 \n\t" \ + "umull r11, r12, r5, r6 \n\t" \ + "adds r14, r14, r11 \n\t" \ + "adcs r9, r9, r12 \n\t" \ + "adc r10, r10, #0 \n\t" \ + "umull r11, r12, r3, r8 \n\t" \ + "adds r14, r14, r11 \n\t" \ + "adcs r9, r9, r12 \n\t" \ + "adc r10, r10, #0 \n\t" \ + "ldr r11, [r0] \n\t" \ + "adds r14, r14, r11 \n\t" \ + "adcs r9, r9, #0 \n\t" \ + "adc r10, r10, #0 \n\t" \ + "stmia r0!, {r14} \n\t" \ + \ + "ldmia r2!, {r8} \n\t" \ + "mov r11, #0 \n\t" \ + "umull r12, r14, r4, r8 \n\t" \ + "adds r9, r9, r12 \n\t" \ + "adcs r10, r10, r14 \n\t" \ + "adc r11, r11, #0 \n\t" \ + "umull r12, r14, r5, r7 \n\t" \ + "adds r9, r9, r12 \n\t" \ + "adcs r10, r10, r14 \n\t" \ + "adc r11, r11, #0 \n\t" \ + "umull r12, r14, r3, r6 \n\t" \ + "adds r9, r9, r12 \n\t" \ + "adcs r10, r10, r14 \n\t" \ + "adc r11, r11, #0 \n\t" \ + "ldr r12, [r0] \n\t" \ + "adds r9, r9, r12 \n\t" \ + "adcs r10, r10, #0 \n\t" \ + "adc r11, r11, #0 \n\t" \ + "stmia r0!, {r9} \n\t" \ + \ + "ldmia r2!, {r6} \n\t" \ + "mov r12, #0 \n\t" \ + "umull r14, r9, r4, r6 \n\t" \ + "adds r10, r10, r14 \n\t" \ + "adcs r11, r11, r9 \n\t" \ + "adc r12, r12, #0 \n\t" \ + "umull r14, r9, r5, r8 \n\t" \ + "adds r10, r10, r14 \n\t" \ + "adcs r11, r11, r9 \n\t" \ + "adc r12, r12, #0 \n\t" \ + "umull r14, r9, r3, r7 \n\t" \ + "adds r10, r10, r14 \n\t" \ + "adcs r11, r11, r9 \n\t" \ + "adc r12, r12, #0 \n\t" \ + "ldr r14, [r0] \n\t" \ + "adds r10, r10, r14 \n\t" \ + "adcs r11, r11, #0 \n\t" \ + "adc r12, r12, #0 \n\t" \ + "stmia r0!, {r10} \n\t" \ + \ + "mov r14, #0 \n\t" \ + "umull r9, r10, r5, r6 \n\t" \ + "adds r11, r11, r9 \n\t" \ + "adcs r12, r12, r10 \n\t" \ + "adc r14, r14, #0 \n\t" \ + "umull r9, r10, r3, r8 \n\t" \ + "adds r11, r11, r9 \n\t" \ + "adcs r12, r12, r10 \n\t" \ + "adc r14, r14, #0 \n\t" \ + "stmia r0!, {r11} \n\t" \ + \ + "umull r10, r11, r3, r6 \n\t" \ + "adds r12, r12, r10 \n\t" \ + "adc r14, r14, r11 \n\t" \ + "stmia r0!, {r12, r14} \n\t" \ + "pop {r3} \n\t" + +#define FAST_MULT_ASM_7_TO_8 \ + "cmp r3, #7 \n\t" \ + "beq 1f \n\t" \ + \ + /* r4 = left high, r5 = right high */ \ + "ldr r4, [r1] \n\t" \ + "ldr r5, [r2] \n\t" \ + \ + "sub r0, #28 \n\t" \ + "sub r1, #28 \n\t" \ + "sub r2, #28 \n\t" \ + \ + "ldr r6, [r0] \n\t" \ + "ldr r7, [r1], #4 \n\t" \ + "ldr r8, [r2], #4 \n\t" \ + "mov r14, #0 \n\t" \ + "umull r9, r10, r4, r8 \n\t" \ + "umull r11, r12, r5, r7 \n\t" \ + "adds r9, r9, r6 \n\t" \ + "adc r10, r10, #0 \n\t" \ + "adds r9, r9, r11 \n\t" \ + "adcs r10, r10, r12 \n\t" \ + "adc r14, r14, #0 \n\t" \ + "str r9, [r0], #4 \n\t" \ + \ + "ldr r6, [r0] \n\t" \ + "adds r10, r10, r6 \n\t" \ + "adcs r14, r14, #0 \n\t" \ + "ldr r7, [r1], #4 \n\t" \ + "ldr r8, [r2], #4 \n\t" \ + "mov r9, #0 \n\t" \ + "umull r11, r12, r4, r8 \n\t" \ + "adds r10, r10, r11 \n\t" \ + "adcs r14, r14, r12 \n\t" \ + "adc r9, r9, #0 \n\t" \ + "umull r11, r12, r5, r7 \n\t" \ + "adds r10, r10, r11 \n\t" \ + "adcs r14, r14, r12 \n\t" \ + "adc r9, r9, #0 \n\t" \ + "str r10, [r0], #4 \n\t" \ + \ + "ldr r6, [r0] \n\t" \ + "adds r14, r14, r6 \n\t" \ + "adcs r9, r9, #0 \n\t" \ + "ldr r7, [r1], #4 \n\t" \ + "ldr r8, [r2], #4 \n\t" \ + "mov r10, #0 \n\t" \ + "umull r11, r12, r4, r8 \n\t" \ + "adds r14, r14, r11 \n\t" \ + "adcs r9, r9, r12 \n\t" \ + "adc r10, r10, #0 \n\t" \ + "umull r11, r12, r5, r7 \n\t" \ + "adds r14, r14, r11 \n\t" \ + "adcs r9, r9, r12 \n\t" \ + "adc r10, r10, #0 \n\t" \ + "str r14, [r0], #4 \n\t" \ + \ + "ldr r6, [r0] \n\t" \ + "adds r9, r9, r6 \n\t" \ + "adcs r10, r10, #0 \n\t" \ + "ldr r7, [r1], #4 \n\t" \ + "ldr r8, [r2], #4 \n\t" \ + "mov r14, #0 \n\t" \ + "umull r11, r12, r4, r8 \n\t" \ + "adds r9, r9, r11 \n\t" \ + "adcs r10, r10, r12 \n\t" \ + "adc r14, r14, #0 \n\t" \ + "umull r11, r12, r5, r7 \n\t" \ + "adds r9, r9, r11 \n\t" \ + "adcs r10, r10, r12 \n\t" \ + "adc r14, r14, #0 \n\t" \ + "str r9, [r0], #4 \n\t" \ + \ + "ldr r6, [r0] \n\t" \ + "adds r10, r10, r6 \n\t" \ + "adcs r14, r14, #0 \n\t" \ + "ldr r7, [r1], #4 \n\t" \ + "ldr r8, [r2], #4 \n\t" \ + "mov r9, #0 \n\t" \ + "umull r11, r12, r4, r8 \n\t" \ + "adds r10, r10, r11 \n\t" \ + "adcs r14, r14, r12 \n\t" \ + "adc r9, r9, #0 \n\t" \ + "umull r11, r12, r5, r7 \n\t" \ + "adds r10, r10, r11 \n\t" \ + "adcs r14, r14, r12 \n\t" \ + "adc r9, r9, #0 \n\t" \ + "str r10, [r0], #4 \n\t" \ + \ + "ldr r6, [r0] \n\t" \ + "adds r14, r14, r6 \n\t" \ + "adcs r9, r9, #0 \n\t" \ + "ldr r7, [r1], #4 \n\t" \ + "ldr r8, [r2], #4 \n\t" \ + "mov r10, #0 \n\t" \ + "umull r11, r12, r4, r8 \n\t" \ + "adds r14, r14, r11 \n\t" \ + "adcs r9, r9, r12 \n\t" \ + "adc r10, r10, #0 \n\t" \ + "umull r11, r12, r5, r7 \n\t" \ + "adds r14, r14, r11 \n\t" \ + "adcs r9, r9, r12 \n\t" \ + "adc r10, r10, #0 \n\t" \ + "str r14, [r0], #4 \n\t" \ + \ + "ldr r6, [r0] \n\t" \ + "adds r9, r9, r6 \n\t" \ + "adcs r10, r10, #0 \n\t" \ + /* skip past already-loaded (r4, r5) */ \ + "ldr r7, [r1], #8 \n\t" \ + "ldr r8, [r2], #8 \n\t" \ + "mov r14, #0 \n\t" \ + "umull r11, r12, r4, r8 \n\t" \ + "adds r9, r9, r11 \n\t" \ + "adcs r10, r10, r12 \n\t" \ + "adc r14, r14, #0 \n\t" \ + "umull r11, r12, r5, r7 \n\t" \ + "adds r9, r9, r11 \n\t" \ + "adcs r10, r10, r12 \n\t" \ + "adc r14, r14, #0 \n\t" \ + "str r9, [r0], #4 \n\t" \ + \ + "umull r11, r12, r4, r5 \n\t" \ + "adds r11, r11, r10 \n\t" \ + "adc r12, r12, r14 \n\t" \ + "stmia r0!, {r11, r12} \n\t" + +#define FAST_MULT_ASM_8 \ + "push {r3} \n\t" \ + "add r0, 24 \n\t" \ + "add r2, 24 \n\t" \ + "ldmia r1!, {r3,r4} \n\t" \ + "ldmia r2!, {r6,r7} \n\t" \ + \ + "umull r11, r12, r3, r6 \n\t" \ + "stmia r0!, {r11} \n\t" \ + \ + "mov r10, #0 \n\t" \ + "umull r11, r9, r3, r7 \n\t" \ + "adds r12, r12, r11 \n\t" \ + "adc r9, r9, #0 \n\t" \ + "umull r11, r14, r4, r6 \n\t" \ + "adds r12, r12, r11 \n\t" \ + "adcs r9, r9, r14 \n\t" \ + "adc r10, r10, #0 \n\t" \ + "stmia r0!, {r12} \n\t" \ + \ + "umull r12, r14, r4, r7 \n\t" \ + "adds r9, r9, r12 \n\t" \ + "adc r10, r10, r14 \n\t" \ + "stmia r0!, {r9, r10} \n\t" \ + \ + "sub r0, 28 \n\t" \ + "sub r2, 20 \n\t" \ + "ldmia r2!, {r6,r7,r8} \n\t" \ + "ldmia r1!, {r5} \n\t" \ + \ + "umull r11, r12, r3, r6 \n\t" \ + "stmia r0!, {r11} \n\t" \ + \ + "mov r10, #0 \n\t" \ + "umull r11, r9, r3, r7 \n\t" \ + "adds r12, r12, r11 \n\t" \ + "adc r9, r9, #0 \n\t" \ + "umull r11, r14, r4, r6 \n\t" \ + "adds r12, r12, r11 \n\t" \ + "adcs r9, r9, r14 \n\t" \ + "adc r10, r10, #0 \n\t" \ + "stmia r0!, {r12} \n\t" \ + \ + "mov r11, #0 \n\t" \ + "umull r12, r14, r3, r8 \n\t" \ + "adds r9, r9, r12 \n\t" \ + "adcs r10, r10, r14 \n\t" \ + "adc r11, r11, #0 \n\t" \ + "umull r12, r14, r4, r7 \n\t" \ + "adds r9, r9, r12 \n\t" \ + "adcs r10, r10, r14 \n\t" \ + "adc r11, r11, #0 \n\t" \ + "umull r12, r14, r5, r6 \n\t" \ + "adds r9, r9, r12 \n\t" \ + "adcs r10, r10, r14 \n\t" \ + "adc r11, r11, #0 \n\t" \ + "stmia r0!, {r9} \n\t" \ + \ + "ldmia r1!, {r3} \n\t" \ + "mov r12, #0 \n\t" \ + "umull r14, r9, r4, r8 \n\t" \ + "adds r10, r10, r14 \n\t" \ + "adcs r11, r11, r9 \n\t" \ + "adc r12, r12, #0 \n\t" \ + "umull r14, r9, r5, r7 \n\t" \ + "adds r10, r10, r14 \n\t" \ + "adcs r11, r11, r9 \n\t" \ + "adc r12, r12, #0 \n\t" \ + "umull r14, r9, r3, r6 \n\t" \ + "adds r10, r10, r14 \n\t" \ + "adcs r11, r11, r9 \n\t" \ + "adc r12, r12, #0 \n\t" \ + "ldr r14, [r0] \n\t" \ + "adds r10, r10, r14 \n\t" \ + "adcs r11, r11, #0 \n\t" \ + "adc r12, r12, #0 \n\t" \ + "stmia r0!, {r10} \n\t" \ + \ + "ldmia r1!, {r4} \n\t" \ + "mov r14, #0 \n\t" \ + "umull r9, r10, r5, r8 \n\t" \ + "adds r11, r11, r9 \n\t" \ + "adcs r12, r12, r10 \n\t" \ + "adc r14, r14, #0 \n\t" \ + "umull r9, r10, r3, r7 \n\t" \ + "adds r11, r11, r9 \n\t" \ + "adcs r12, r12, r10 \n\t" \ + "adc r14, r14, #0 \n\t" \ + "umull r9, r10, r4, r6 \n\t" \ + "adds r11, r11, r9 \n\t" \ + "adcs r12, r12, r10 \n\t" \ + "adc r14, r14, #0 \n\t" \ + "ldr r9, [r0] \n\t" \ + "adds r11, r11, r9 \n\t" \ + "adcs r12, r12, #0 \n\t" \ + "adc r14, r14, #0 \n\t" \ + "stmia r0!, {r11} \n\t" \ + \ + "ldmia r2!, {r6} \n\t" \ + "mov r9, #0 \n\t" \ + "umull r10, r11, r5, r6 \n\t" \ + "adds r12, r12, r10 \n\t" \ + "adcs r14, r14, r11 \n\t" \ + "adc r9, r9, #0 \n\t" \ + "umull r10, r11, r3, r8 \n\t" \ + "adds r12, r12, r10 \n\t" \ + "adcs r14, r14, r11 \n\t" \ + "adc r9, r9, #0 \n\t" \ + "umull r10, r11, r4, r7 \n\t" \ + "adds r12, r12, r10 \n\t" \ + "adcs r14, r14, r11 \n\t" \ + "adc r9, r9, #0 \n\t" \ + "ldr r10, [r0] \n\t" \ + "adds r12, r12, r10 \n\t" \ + "adcs r14, r14, #0 \n\t" \ + "adc r9, r9, #0 \n\t" \ + "stmia r0!, {r12} \n\t" \ + \ + "ldmia r2!, {r7} \n\t" \ + "mov r10, #0 \n\t" \ + "umull r11, r12, r5, r7 \n\t" \ + "adds r14, r14, r11 \n\t" \ + "adcs r9, r9, r12 \n\t" \ + "adc r10, r10, #0 \n\t" \ + "umull r11, r12, r3, r6 \n\t" \ + "adds r14, r14, r11 \n\t" \ + "adcs r9, r9, r12 \n\t" \ + "adc r10, r10, #0 \n\t" \ + "umull r11, r12, r4, r8 \n\t" \ + "adds r14, r14, r11 \n\t" \ + "adcs r9, r9, r12 \n\t" \ + "adc r10, r10, #0 \n\t" \ + "ldr r11, [r0] \n\t" \ + "adds r14, r14, r11 \n\t" \ + "adcs r9, r9, #0 \n\t" \ + "adc r10, r10, #0 \n\t" \ + "stmia r0!, {r14} \n\t" \ + \ + "mov r11, #0 \n\t" \ + "umull r12, r14, r3, r7 \n\t" \ + "adds r9, r9, r12 \n\t" \ + "adcs r10, r10, r14 \n\t" \ + "adc r11, r11, #0 \n\t" \ + "umull r12, r14, r4, r6 \n\t" \ + "adds r9, r9, r12 \n\t" \ + "adcs r10, r10, r14 \n\t" \ + "adc r11, r11, #0 \n\t" \ + "stmia r0!, {r9} \n\t" \ + \ + "umull r14, r9, r4, r7 \n\t" \ + "adds r10, r10, r14 \n\t" \ + "adc r11, r11, r9 \n\t" \ + "stmia r0!, {r10, r11} \n\t" \ + \ + "sub r0, 52 \n\t" \ + "sub r1, 20 \n\t" \ + "sub r2, 32 \n\t" \ + "ldmia r1!, {r3,r4,r5} \n\t" \ + "ldmia r2!, {r6,r7,r8} \n\t" \ + \ + "umull r11, r12, r3, r6 \n\t" \ + "stmia r0!, {r11} \n\t" \ + \ + "mov r10, #0 \n\t" \ + "umull r11, r9, r3, r7 \n\t" \ + "adds r12, r12, r11 \n\t" \ + "adc r9, r9, #0 \n\t" \ + "umull r11, r14, r4, r6 \n\t" \ + "adds r12, r12, r11 \n\t" \ + "adcs r9, r9, r14 \n\t" \ + "adc r10, r10, #0 \n\t" \ + "stmia r0!, {r12} \n\t" \ + \ + "mov r11, #0 \n\t" \ + "umull r12, r14, r3, r8 \n\t" \ + "adds r9, r9, r12 \n\t" \ + "adcs r10, r10, r14 \n\t" \ + "adc r11, r11, #0 \n\t" \ + "umull r12, r14, r4, r7 \n\t" \ + "adds r9, r9, r12 \n\t" \ + "adcs r10, r10, r14 \n\t" \ + "adc r11, r11, #0 \n\t" \ + "umull r12, r14, r5, r6 \n\t" \ + "adds r9, r9, r12 \n\t" \ + "adcs r10, r10, r14 \n\t" \ + "adc r11, r11, #0 \n\t" \ + "stmia r0!, {r9} \n\t" \ + \ + "ldmia r1!, {r3} \n\t" \ + "mov r12, #0 \n\t" \ + "umull r14, r9, r4, r8 \n\t" \ + "adds r10, r10, r14 \n\t" \ + "adcs r11, r11, r9 \n\t" \ + "adc r12, r12, #0 \n\t" \ + "umull r14, r9, r5, r7 \n\t" \ + "adds r10, r10, r14 \n\t" \ + "adcs r11, r11, r9 \n\t" \ + "adc r12, r12, #0 \n\t" \ + "umull r14, r9, r3, r6 \n\t" \ + "adds r10, r10, r14 \n\t" \ + "adcs r11, r11, r9 \n\t" \ + "adc r12, r12, #0 \n\t" \ + "ldr r14, [r0] \n\t" \ + "adds r10, r10, r14 \n\t" \ + "adcs r11, r11, #0 \n\t" \ + "adc r12, r12, #0 \n\t" \ + "stmia r0!, {r10} \n\t" \ + \ + "ldmia r1!, {r4} \n\t" \ + "mov r14, #0 \n\t" \ + "umull r9, r10, r5, r8 \n\t" \ + "adds r11, r11, r9 \n\t" \ + "adcs r12, r12, r10 \n\t" \ + "adc r14, r14, #0 \n\t" \ + "umull r9, r10, r3, r7 \n\t" \ + "adds r11, r11, r9 \n\t" \ + "adcs r12, r12, r10 \n\t" \ + "adc r14, r14, #0 \n\t" \ + "umull r9, r10, r4, r6 \n\t" \ + "adds r11, r11, r9 \n\t" \ + "adcs r12, r12, r10 \n\t" \ + "adc r14, r14, #0 \n\t" \ + "ldr r9, [r0] \n\t" \ + "adds r11, r11, r9 \n\t" \ + "adcs r12, r12, #0 \n\t" \ + "adc r14, r14, #0 \n\t" \ + "stmia r0!, {r11} \n\t" \ + \ + "ldmia r1!, {r5} \n\t" \ + "mov r9, #0 \n\t" \ + "umull r10, r11, r3, r8 \n\t" \ + "adds r12, r12, r10 \n\t" \ + "adcs r14, r14, r11 \n\t" \ + "adc r9, r9, #0 \n\t" \ + "umull r10, r11, r4, r7 \n\t" \ + "adds r12, r12, r10 \n\t" \ + "adcs r14, r14, r11 \n\t" \ + "adc r9, r9, #0 \n\t" \ + "umull r10, r11, r5, r6 \n\t" \ + "adds r12, r12, r10 \n\t" \ + "adcs r14, r14, r11 \n\t" \ + "adc r9, r9, #0 \n\t" \ + "ldr r10, [r0] \n\t" \ + "adds r12, r12, r10 \n\t" \ + "adcs r14, r14, #0 \n\t" \ + "adc r9, r9, #0 \n\t" \ + "stmia r0!, {r12} \n\t" \ + \ + "ldmia r1!, {r3} \n\t" \ + "mov r10, #0 \n\t" \ + "umull r11, r12, r4, r8 \n\t" \ + "adds r14, r14, r11 \n\t" \ + "adcs r9, r9, r12 \n\t" \ + "adc r10, r10, #0 \n\t" \ + "umull r11, r12, r5, r7 \n\t" \ + "adds r14, r14, r11 \n\t" \ + "adcs r9, r9, r12 \n\t" \ + "adc r10, r10, #0 \n\t" \ + "umull r11, r12, r3, r6 \n\t" \ + "adds r14, r14, r11 \n\t" \ + "adcs r9, r9, r12 \n\t" \ + "adc r10, r10, #0 \n\t" \ + "ldr r11, [r0] \n\t" \ + "adds r14, r14, r11 \n\t" \ + "adcs r9, r9, #0 \n\t" \ + "adc r10, r10, #0 \n\t" \ + "stmia r0!, {r14} \n\t" \ + \ + "ldmia r1!, {r4} \n\t" \ + "mov r11, #0 \n\t" \ + "umull r12, r14, r5, r8 \n\t" \ + "adds r9, r9, r12 \n\t" \ + "adcs r10, r10, r14 \n\t" \ + "adc r11, r11, #0 \n\t" \ + "umull r12, r14, r3, r7 \n\t" \ + "adds r9, r9, r12 \n\t" \ + "adcs r10, r10, r14 \n\t" \ + "adc r11, r11, #0 \n\t" \ + "umull r12, r14, r4, r6 \n\t" \ + "adds r9, r9, r12 \n\t" \ + "adcs r10, r10, r14 \n\t" \ + "adc r11, r11, #0 \n\t" \ + "ldr r12, [r0] \n\t" \ + "adds r9, r9, r12 \n\t" \ + "adcs r10, r10, #0 \n\t" \ + "adc r11, r11, #0 \n\t" \ + "stmia r0!, {r9} \n\t" \ + \ + "ldmia r2!, {r6} \n\t" \ + "mov r12, #0 \n\t" \ + "umull r14, r9, r5, r6 \n\t" \ + "adds r10, r10, r14 \n\t" \ + "adcs r11, r11, r9 \n\t" \ + "adc r12, r12, #0 \n\t" \ + "umull r14, r9, r3, r8 \n\t" \ + "adds r10, r10, r14 \n\t" \ + "adcs r11, r11, r9 \n\t" \ + "adc r12, r12, #0 \n\t" \ + "umull r14, r9, r4, r7 \n\t" \ + "adds r10, r10, r14 \n\t" \ + "adcs r11, r11, r9 \n\t" \ + "adc r12, r12, #0 \n\t" \ + "ldr r14, [r0] \n\t" \ + "adds r10, r10, r14 \n\t" \ + "adcs r11, r11, #0 \n\t" \ + "adc r12, r12, #0 \n\t" \ + "stmia r0!, {r10} \n\t" \ + \ + "ldmia r2!, {r7} \n\t" \ + "mov r14, #0 \n\t" \ + "umull r9, r10, r5, r7 \n\t" \ + "adds r11, r11, r9 \n\t" \ + "adcs r12, r12, r10 \n\t" \ + "adc r14, r14, #0 \n\t" \ + "umull r9, r10, r3, r6 \n\t" \ + "adds r11, r11, r9 \n\t" \ + "adcs r12, r12, r10 \n\t" \ + "adc r14, r14, #0 \n\t" \ + "umull r9, r10, r4, r8 \n\t" \ + "adds r11, r11, r9 \n\t" \ + "adcs r12, r12, r10 \n\t" \ + "adc r14, r14, #0 \n\t" \ + "ldr r9, [r0] \n\t" \ + "adds r11, r11, r9 \n\t" \ + "adcs r12, r12, #0 \n\t" \ + "adc r14, r14, #0 \n\t" \ + "stmia r0!, {r11} \n\t" \ + \ + "ldmia r2!, {r8} \n\t" \ + "mov r9, #0 \n\t" \ + "umull r10, r11, r5, r8 \n\t" \ + "adds r12, r12, r10 \n\t" \ + "adcs r14, r14, r11 \n\t" \ + "adc r9, r9, #0 \n\t" \ + "umull r10, r11, r3, r7 \n\t" \ + "adds r12, r12, r10 \n\t" \ + "adcs r14, r14, r11 \n\t" \ + "adc r9, r9, #0 \n\t" \ + "umull r10, r11, r4, r6 \n\t" \ + "adds r12, r12, r10 \n\t" \ + "adcs r14, r14, r11 \n\t" \ + "adc r9, r9, #0 \n\t" \ + "ldr r10, [r0] \n\t" \ + "adds r12, r12, r10 \n\t" \ + "adcs r14, r14, #0 \n\t" \ + "adc r9, r9, #0 \n\t" \ + "stmia r0!, {r12} \n\t" \ + \ + "ldmia r2!, {r6} \n\t" \ + "mov r10, #0 \n\t" \ + "umull r11, r12, r5, r6 \n\t" \ + "adds r14, r14, r11 \n\t" \ + "adcs r9, r9, r12 \n\t" \ + "adc r10, r10, #0 \n\t" \ + "umull r11, r12, r3, r8 \n\t" \ + "adds r14, r14, r11 \n\t" \ + "adcs r9, r9, r12 \n\t" \ + "adc r10, r10, #0 \n\t" \ + "umull r11, r12, r4, r7 \n\t" \ + "adds r14, r14, r11 \n\t" \ + "adcs r9, r9, r12 \n\t" \ + "adc r10, r10, #0 \n\t" \ + "ldr r11, [r0] \n\t" \ + "adds r14, r14, r11 \n\t" \ + "adcs r9, r9, #0 \n\t" \ + "adc r10, r10, #0 \n\t" \ + "stmia r0!, {r14} \n\t" \ + \ + "ldmia r2!, {r7} \n\t" \ + "mov r11, #0 \n\t" \ + "umull r12, r14, r5, r7 \n\t" \ + "adds r9, r9, r12 \n\t" \ + "adcs r10, r10, r14 \n\t" \ + "adc r11, r11, #0 \n\t" \ + "umull r12, r14, r3, r6 \n\t" \ + "adds r9, r9, r12 \n\t" \ + "adcs r10, r10, r14 \n\t" \ + "adc r11, r11, #0 \n\t" \ + "umull r12, r14, r4, r8 \n\t" \ + "adds r9, r9, r12 \n\t" \ + "adcs r10, r10, r14 \n\t" \ + "adc r11, r11, #0 \n\t" \ + "ldr r12, [r0] \n\t" \ + "adds r9, r9, r12 \n\t" \ + "adcs r10, r10, #0 \n\t" \ + "adc r11, r11, #0 \n\t" \ + "stmia r0!, {r9} \n\t" \ + \ + "mov r12, #0 \n\t" \ + "umull r14, r9, r3, r7 \n\t" \ + "adds r10, r10, r14 \n\t" \ + "adcs r11, r11, r9 \n\t" \ + "adc r12, r12, #0 \n\t" \ + "umull r14, r9, r4, r6 \n\t" \ + "adds r10, r10, r14 \n\t" \ + "adcs r11, r11, r9 \n\t" \ + "adc r12, r12, #0 \n\t" \ + "stmia r0!, {r10} \n\t" \ + \ + "umull r9, r10, r4, r7 \n\t" \ + "adds r11, r11, r9 \n\t" \ + "adc r12, r12, r10 \n\t" \ + "stmia r0!, {r11, r12} \n\t" \ + "pop {r3} \n\t" + +#define FAST_SQUARE_ASM_5 \ + "push {r2} \n\t" \ + "ldmia r1!, {r2,r3,r4,r5,r6} \n\t" \ + "push {r1} \n\t" \ + \ + "umull r11, r12, r2, r2 \n\t" \ + "stmia r0!, {r11} \n\t" \ + \ + "mov r9, #0 \n\t" \ + "umull r10, r11, r2, r3 \n\t" \ + "adds r12, r12, r10 \n\t" \ + "adcs r8, r11, #0 \n\t" \ + "adc r9, r9, #0 \n\t" \ + "adds r12, r12, r10 \n\t" \ + "adcs r8, r8, r11 \n\t" \ + "adc r9, r9, #0 \n\t" \ + "stmia r0!, {r12} \n\t" \ + \ + "mov r10, #0 \n\t" \ + "umull r11, r12, r2, r4 \n\t" \ + "adds r11, r11, r11 \n\t" \ + "adcs r12, r12, r12 \n\t" \ + "adc r10, r10, #0 \n\t" \ + "adds r8, r8, r11 \n\t" \ + "adcs r9, r9, r12 \n\t" \ + "adc r10, r10, #0 \n\t" \ + "umull r11, r12, r3, r3 \n\t" \ + "adds r8, r8, r11 \n\t" \ + "adcs r9, r9, r12 \n\t" \ + "adc r10, r10, #0 \n\t" \ + "stmia r0!, {r8} \n\t" \ + \ + "mov r12, #0 \n\t" \ + "umull r8, r11, r2, r5 \n\t" \ + "umull r1, r14, r3, r4 \n\t" \ + "adds r8, r8, r1 \n\t" \ + "adcs r11, r11, r14 \n\t" \ + "adc r12, r12, #0 \n\t" \ + "adds r8, r8, r8 \n\t" \ + "adcs r11, r11, r11 \n\t" \ + "adc r12, r12, r12 \n\t" \ + "adds r8, r8, r9 \n\t" \ + "adcs r11, r11, r10 \n\t" \ + "adc r12, r12, #0 \n\t" \ + "stmia r0!, {r8} \n\t" \ + \ + "mov r10, #0 \n\t" \ + "umull r8, r9, r2, r6 \n\t" \ + "umull r1, r14, r3, r5 \n\t" \ + "adds r8, r8, r1 \n\t" \ + "adcs r9, r9, r14 \n\t" \ + "adc r10, r10, #0 \n\t" \ + "adds r8, r8, r8 \n\t" \ + "adcs r9, r9, r9 \n\t" \ + "adc r10, r10, r10 \n\t" \ + "umull r1, r14, r4, r4 \n\t" \ + "adds r8, r8, r1 \n\t" \ + "adcs r9, r9, r14 \n\t" \ + "adc r10, r10, #0 \n\t" \ + "adds r8, r8, r11 \n\t" \ + "adcs r9, r9, r12 \n\t" \ + "adc r10, r10, #0 \n\t" \ + "stmia r0!, {r8} \n\t" \ + \ + "mov r12, #0 \n\t" \ + "umull r8, r11, r3, r6 \n\t" \ + "umull r1, r14, r4, r5 \n\t" \ + "adds r8, r8, r1 \n\t" \ + "adcs r11, r11, r14 \n\t" \ + "adc r12, r12, #0 \n\t" \ + "adds r8, r8, r8 \n\t" \ + "adcs r11, r11, r11 \n\t" \ + "adc r12, r12, r12 \n\t" \ + "adds r8, r8, r9 \n\t" \ + "adcs r11, r11, r10 \n\t" \ + "adc r12, r12, #0 \n\t" \ + "stmia r0!, {r8} \n\t" \ + \ + "mov r8, #0 \n\t" \ + "umull r1, r10, r4, r6 \n\t" \ + "adds r1, r1, r1 \n\t" \ + "adcs r10, r10, r10 \n\t" \ + "adc r8, r8, #0 \n\t" \ + "adds r11, r11, r1 \n\t" \ + "adcs r12, r12, r10 \n\t" \ + "adc r8, r8, #0 \n\t" \ + "umull r1, r10, r5, r5 \n\t" \ + "adds r11, r11, r1 \n\t" \ + "adcs r12, r12, r10 \n\t" \ + "adc r8, r8, #0 \n\t" \ + "stmia r0!, {r11} \n\t" \ + \ + "mov r11, #0 \n\t" \ + "umull r1, r10, r5, r6 \n\t" \ + "adds r1, r1, r1 \n\t" \ + "adcs r10, r10, r10 \n\t" \ + "adc r11, r11, #0 \n\t" \ + "adds r12, r12, r1 \n\t" \ + "adcs r8, r8, r10 \n\t" \ + "adc r11, r11, #0 \n\t" \ + "stmia r0!, {r12} \n\t" \ + \ + "umull r1, r10, r6, r6 \n\t" \ + "adds r8, r8, r1 \n\t" \ + "adcs r11, r11, r10 \n\t" \ + "stmia r0!, {r8, r11} \n\t" \ + "pop {r1, r2} \n\t" + +#define FAST_SQUARE_ASM_5_TO_6 \ + "cmp r2, #5 \n\t" \ + "beq 1f \n\t" \ + \ + "sub r0, #20 \n\t" \ + "sub r1, #20 \n\t" \ + \ + /* Do off-center multiplication */ \ + "ldmia r1!, {r6,r7,r8,r9,r10,r11} \n\t" \ + "umull r3, r4, r6, r11 \n\t" \ + "umull r6, r5, r7, r11 \n\t" \ + "adds r4, r4, r6 \n\t" \ + "umull r7, r6, r8, r11 \n\t" \ + "adcs r5, r5, r7 \n\t" \ + "umull r8, r7, r9, r11 \n\t" \ + "adcs r6, r6, r8 \n\t" \ + "umull r9, r8, r10, r11 \n\t" \ + "adcs r7, r7, r9 \n\t" \ + "adcs r8, r8, #0 \n\t" \ + \ + /* Multiply by 2 */ \ + "mov r9, #0 \n\t" \ + "adds r3, r3, r3 \n\t" \ + "adcs r4, r4, r4 \n\t" \ + "adcs r5, r5, r5 \n\t" \ + "adcs r6, r6, r6 \n\t" \ + "adcs r7, r7, r7 \n\t" \ + "adcs r8, r8, r8 \n\t" \ + "adcs r9, r9, #0 \n\t" \ + \ + /* Add into previous */ \ + "ldr r14, [r0], #4 \n\t" \ + "adds r3, r3, r14 \n\t" \ + "ldr r14, [r0], #4 \n\t" \ + "adcs r4, r4, r14 \n\t" \ + "ldr r14, [r0], #4 \n\t" \ + "adcs r5, r5, r14 \n\t" \ + "ldr r14, [r0], #4 \n\t" \ + "adcs r6, r6, r14 \n\t" \ + "ldr r14, [r0], #4 \n\t" \ + "adcs r7, r7, r14 \n\t" \ + "adcs r8, r8, #0 \n\t" \ + "adcs r9, r9, #0 \n\t" \ + "sub r0, #20 \n\t" \ + \ + /* Perform center multiplication */ \ + "umlal r8, r9, r11, r11 \n\t" \ + "stmia r0!, {r3,r4,r5,r6,r7,r8,r9} \n\t" + +#define FAST_SQUARE_ASM_6 \ + "push {r2} \n\t" \ + "ldmia r1!, {r2,r3,r4,r5,r6,r7} \n\t" \ + "push {r1} \n\t" \ + \ + "umull r11, r12, r2, r2 \n\t" \ + "stmia r0!, {r11} \n\t" \ + \ + "mov r9, #0 \n\t" \ + "umull r10, r11, r2, r3 \n\t" \ + "adds r12, r12, r10 \n\t" \ + "adcs r8, r11, #0 \n\t" \ + "adc r9, r9, #0 \n\t" \ + "adds r12, r12, r10 \n\t" \ + "adcs r8, r8, r11 \n\t" \ + "adc r9, r9, #0 \n\t" \ + "stmia r0!, {r12} \n\t" \ + \ + "mov r10, #0 \n\t" \ + "umull r11, r12, r2, r4 \n\t" \ + "adds r11, r11, r11 \n\t" \ + "adcs r12, r12, r12 \n\t" \ + "adc r10, r10, #0 \n\t" \ + "adds r8, r8, r11 \n\t" \ + "adcs r9, r9, r12 \n\t" \ + "adc r10, r10, #0 \n\t" \ + "umull r11, r12, r3, r3 \n\t" \ + "adds r8, r8, r11 \n\t" \ + "adcs r9, r9, r12 \n\t" \ + "adc r10, r10, #0 \n\t" \ + "stmia r0!, {r8} \n\t" \ + \ + "mov r12, #0 \n\t" \ + "umull r8, r11, r2, r5 \n\t" \ + "umull r1, r14, r3, r4 \n\t" \ + "adds r8, r8, r1 \n\t" \ + "adcs r11, r11, r14 \n\t" \ + "adc r12, r12, #0 \n\t" \ + "adds r8, r8, r8 \n\t" \ + "adcs r11, r11, r11 \n\t" \ + "adc r12, r12, r12 \n\t" \ + "adds r8, r8, r9 \n\t" \ + "adcs r11, r11, r10 \n\t" \ + "adc r12, r12, #0 \n\t" \ + "stmia r0!, {r8} \n\t" \ + \ + "mov r10, #0 \n\t" \ + "umull r8, r9, r2, r6 \n\t" \ + "umull r1, r14, r3, r5 \n\t" \ + "adds r8, r8, r1 \n\t" \ + "adcs r9, r9, r14 \n\t" \ + "adc r10, r10, #0 \n\t" \ + "adds r8, r8, r8 \n\t" \ + "adcs r9, r9, r9 \n\t" \ + "adc r10, r10, r10 \n\t" \ + "umull r1, r14, r4, r4 \n\t" \ + "adds r8, r8, r1 \n\t" \ + "adcs r9, r9, r14 \n\t" \ + "adc r10, r10, #0 \n\t" \ + "adds r8, r8, r11 \n\t" \ + "adcs r9, r9, r12 \n\t" \ + "adc r10, r10, #0 \n\t" \ + "stmia r0!, {r8} \n\t" \ + \ + "mov r12, #0 \n\t" \ + "umull r8, r11, r2, r7 \n\t" \ + "umull r1, r14, r3, r6 \n\t" \ + "adds r8, r8, r1 \n\t" \ + "adcs r11, r11, r14 \n\t" \ + "adc r12, r12, #0 \n\t" \ + "umull r1, r14, r4, r5 \n\t" \ + "adds r8, r8, r1 \n\t" \ + "adcs r11, r11, r14 \n\t" \ + "adc r12, r12, #0 \n\t" \ + "adds r8, r8, r8 \n\t" \ + "adcs r11, r11, r11 \n\t" \ + "adc r12, r12, r12 \n\t" \ + "adds r8, r8, r9 \n\t" \ + "adcs r11, r11, r10 \n\t" \ + "adc r12, r12, #0 \n\t" \ + "stmia r0!, {r8} \n\t" \ + \ + "mov r10, #0 \n\t" \ + "umull r8, r9, r3, r7 \n\t" \ + "umull r1, r14, r4, r6 \n\t" \ + "adds r8, r8, r1 \n\t" \ + "adcs r9, r9, r14 \n\t" \ + "adc r10, r10, #0 \n\t" \ + "adds r8, r8, r8 \n\t" \ + "adcs r9, r9, r9 \n\t" \ + "adc r10, r10, r10 \n\t" \ + "umull r1, r14, r5, r5 \n\t" \ + "adds r8, r8, r1 \n\t" \ + "adcs r9, r9, r14 \n\t" \ + "adc r10, r10, #0 \n\t" \ + "adds r8, r8, r11 \n\t" \ + "adcs r9, r9, r12 \n\t" \ + "adc r10, r10, #0 \n\t" \ + "stmia r0!, {r8} \n\t" \ + \ + "mov r12, #0 \n\t" \ + "umull r8, r11, r4, r7 \n\t" \ + "umull r1, r14, r5, r6 \n\t" \ + "adds r8, r8, r1 \n\t" \ + "adcs r11, r11, r14 \n\t" \ + "adc r12, r12, #0 \n\t" \ + "adds r8, r8, r8 \n\t" \ + "adcs r11, r11, r11 \n\t" \ + "adc r12, r12, r12 \n\t" \ + "adds r8, r8, r9 \n\t" \ + "adcs r11, r11, r10 \n\t" \ + "adc r12, r12, #0 \n\t" \ + "stmia r0!, {r8} \n\t" \ + \ + "mov r8, #0 \n\t" \ + "umull r1, r10, r5, r7 \n\t" \ + "adds r1, r1, r1 \n\t" \ + "adcs r10, r10, r10 \n\t" \ + "adc r8, r8, #0 \n\t" \ + "adds r11, r11, r1 \n\t" \ + "adcs r12, r12, r10 \n\t" \ + "adc r8, r8, #0 \n\t" \ + "umull r1, r10, r6, r6 \n\t" \ + "adds r11, r11, r1 \n\t" \ + "adcs r12, r12, r10 \n\t" \ + "adc r8, r8, #0 \n\t" \ + "stmia r0!, {r11} \n\t" \ + \ + "mov r11, #0 \n\t" \ + "umull r1, r10, r6, r7 \n\t" \ + "adds r1, r1, r1 \n\t" \ + "adcs r10, r10, r10 \n\t" \ + "adc r11, r11, #0 \n\t" \ + "adds r12, r12, r1 \n\t" \ + "adcs r8, r8, r10 \n\t" \ + "adc r11, r11, #0 \n\t" \ + "stmia r0!, {r12} \n\t" \ + \ + "umull r1, r10, r7, r7 \n\t" \ + "adds r8, r8, r1 \n\t" \ + "adcs r11, r11, r10 \n\t" \ + "stmia r0!, {r8, r11} \n\t" \ + "pop {r1, r2} \n\t" + +#define FAST_SQUARE_ASM_6_TO_7 \ + "cmp r2, #6 \n\t" \ + "beq 1f \n\t" \ + \ + "sub r0, #24 \n\t" \ + "sub r1, #24 \n\t" \ + \ + /* Do off-center multiplication */ \ + "ldmia r1!, {r6,r7,r8,r9,r10,r11,r12} \n\t" \ + "umull r3, r4, r6, r12 \n\t" \ + "umull r6, r5, r7, r12 \n\t" \ + "adds r4, r4, r6 \n\t" \ + "umull r7, r6, r8, r12 \n\t" \ + "adcs r5, r5, r7 \n\t" \ + "umull r8, r7, r9, r12 \n\t" \ + "adcs r6, r6, r8 \n\t" \ + "umull r9, r8, r10, r12 \n\t" \ + "adcs r7, r7, r9 \n\t" \ + "umull r10, r9, r11, r12 \n\t" \ + "adcs r8, r8, r10 \n\t" \ + "adcs r9, r9, #0 \n\t" \ + \ + /* Multiply by 2 */ \ + "mov r10, #0 \n\t" \ + "adds r3, r3, r3 \n\t" \ + "adcs r4, r4, r4 \n\t" \ + "adcs r5, r5, r5 \n\t" \ + "adcs r6, r6, r6 \n\t" \ + "adcs r7, r7, r7 \n\t" \ + "adcs r8, r8, r8 \n\t" \ + "adcs r9, r9, r9 \n\t" \ + "adcs r10, r10, #0 \n\t" \ + \ + /* Add into previous */ \ + "ldr r14, [r0], #4 \n\t" \ + "adds r3, r3, r14 \n\t" \ + "ldr r14, [r0], #4 \n\t" \ + "adcs r4, r4, r14 \n\t" \ + "ldr r14, [r0], #4 \n\t" \ + "adcs r5, r5, r14 \n\t" \ + "ldr r14, [r0], #4 \n\t" \ + "adcs r6, r6, r14 \n\t" \ + "ldr r14, [r0], #4 \n\t" \ + "adcs r7, r7, r14 \n\t" \ + "ldr r14, [r0], #4 \n\t" \ + "adcs r8, r8, r14 \n\t" \ + "adcs r9, r9, #0 \n\t" \ + "adcs r10, r10, #0 \n\t" \ + "sub r0, #24 \n\t" \ + \ + /* Perform center multiplication */ \ + "umlal r9, r10, r12, r12 \n\t" \ + "stmia r0!, {r3,r4,r5,r6,r7,r8,r9,r10} \n\t" + +#define FAST_SQUARE_ASM_7 \ + "push {r2} \n\t" \ + "ldmia r1!, {r2, r3, r4, r5, r6, r7, r8} \n\t" \ + "push {r1} \n\t" \ + "sub r1, 4 \n\t" \ + \ + "add r0, 24 \n\t" \ + "umull r9, r10, r2, r8 \n\t" \ + "stmia r0!, {r9, r10} \n\t" \ + "sub r0, 32 \n\t" \ + \ + "umull r11, r12, r2, r2 \n\t" \ + "stmia r0!, {r11} \n\t" \ + \ + "mov r9, #0 \n\t" \ + "umull r10, r11, r2, r3 \n\t" \ + "adds r12, r12, r10 \n\t" \ + "adcs r8, r11, #0 \n\t" \ + "adc r9, r9, #0 \n\t" \ + "adds r12, r12, r10 \n\t" \ + "adcs r8, r8, r11 \n\t" \ + "adc r9, r9, #0 \n\t" \ + "stmia r0!, {r12} \n\t" \ + \ + "mov r10, #0 \n\t" \ + "umull r11, r12, r2, r4 \n\t" \ + "adds r11, r11, r11 \n\t" \ + "adcs r12, r12, r12 \n\t" \ + "adc r10, r10, #0 \n\t" \ + "adds r8, r8, r11 \n\t" \ + "adcs r9, r9, r12 \n\t" \ + "adc r10, r10, #0 \n\t" \ + "umull r11, r12, r3, r3 \n\t" \ + "adds r8, r8, r11 \n\t" \ + "adcs r9, r9, r12 \n\t" \ + "adc r10, r10, #0 \n\t" \ + "stmia r0!, {r8} \n\t" \ + \ + "mov r12, #0 \n\t" \ + "umull r8, r11, r2, r5 \n\t" \ + "mov r14, r11 \n\t" \ + "umlal r8, r11, r3, r4 \n\t" \ + "cmp r14, r11 \n\t" \ + "it hi \n\t" \ + "adchi r12, r12, #0 \n\t" \ + "adds r8, r8, r8 \n\t" \ + "adcs r11, r11, r11 \n\t" \ + "adc r12, r12, r12 \n\t" \ + "adds r8, r8, r9 \n\t" \ + "adcs r11, r11, r10 \n\t" \ + "adc r12, r12, #0 \n\t" \ + "stmia r0!, {r8} \n\t" \ + \ + "mov r10, #0 \n\t" \ + "umull r8, r9, r2, r6 \n\t" \ + "mov r14, r9 \n\t" \ + "umlal r8, r9, r3, r5 \n\t" \ + "cmp r14, r9 \n\t" \ + "it hi \n\t" \ + "adchi r10, r10, #0 \n\t" \ + "adds r8, r8, r8 \n\t" \ + "adcs r9, r9, r9 \n\t" \ + "adc r10, r10, r10 \n\t" \ + "mov r14, r9 \n\t" \ + "umlal r8, r9, r4, r4 \n\t" \ + "cmp r14, r9 \n\t" \ + "it hi \n\t" \ + "adchi r10, r10, #0 \n\t" \ + "adds r8, r8, r11 \n\t" \ + "adcs r9, r9, r12 \n\t" \ + "adc r10, r10, #0 \n\t" \ + "stmia r0!, {r8} \n\t" \ + \ + "mov r12, #0 \n\t" \ + "umull r8, r11, r2, r7 \n\t" \ + "mov r14, r11 \n\t" \ + "umlal r8, r11, r3, r6 \n\t" \ + "cmp r14, r11 \n\t" \ + "it hi \n\t" \ + "adchi r12, r12, #0 \n\t" \ + "mov r14, r11 \n\t" \ + "umlal r8, r11, r4, r5 \n\t" \ + "cmp r14, r11 \n\t" \ + "it hi \n\t" \ + "adchi r12, r12, #0 \n\t" \ + "adds r8, r8, r8 \n\t" \ + "adcs r11, r11, r11 \n\t" \ + "adc r12, r12, r12 \n\t" \ + "adds r8, r8, r9 \n\t" \ + "adcs r11, r11, r10 \n\t" \ + "adc r12, r12, #0 \n\t" \ + "stmia r0!, {r8} \n\t" \ + \ + "ldmia r1!, {r2} \n\t" \ + "mov r10, #0 \n\t" \ + "umull r8, r9, r3, r7 \n\t" \ + "mov r14, r9 \n\t" \ + "umlal r8, r9, r4, r6 \n\t" \ + "cmp r14, r9 \n\t" \ + "it hi \n\t" \ + "adchi r10, r10, #0 \n\t" \ + "ldr r14, [r0] \n\t" \ + "adds r8, r8, r14 \n\t" \ + "adcs r9, r9, #0 \n\t" \ + "adc r10, r10, #0 \n\t" \ + "adds r8, r8, r8 \n\t" \ + "adcs r9, r9, r9 \n\t" \ + "adc r10, r10, r10 \n\t" \ + "mov r14, r9 \n\t" \ + "umlal r8, r9, r5, r5 \n\t" \ + "cmp r14, r9 \n\t" \ + "it hi \n\t" \ + "adchi r10, r10, #0 \n\t" \ + "adds r8, r8, r11 \n\t" \ + "adcs r9, r9, r12 \n\t" \ + "adc r10, r10, #0 \n\t" \ + "stmia r0!, {r8} \n\t" \ + \ + "mov r12, #0 \n\t" \ + "umull r8, r11, r3, r2 \n\t" \ + "mov r14, r11 \n\t" \ + "umlal r8, r11, r4, r7 \n\t" \ + "cmp r14, r11 \n\t" \ + "it hi \n\t" \ + "adchi r12, r12, #0 \n\t" \ + "mov r14, r11 \n\t" \ + "umlal r8, r11, r5, r6 \n\t" \ + "cmp r14, r11 \n\t" \ + "it hi \n\t" \ + "adchi r12, r12, #0 \n\t" \ + "ldr r14, [r0] \n\t" \ + "adds r8, r8, r14 \n\t" \ + "adcs r11, r11, #0 \n\t" \ + "adc r12, r12, #0 \n\t" \ + "adds r8, r8, r8 \n\t" \ + "adcs r11, r11, r11 \n\t" \ + "adc r12, r12, r12 \n\t" \ + "adds r8, r8, r9 \n\t" \ + "adcs r11, r11, r10 \n\t" \ + "adc r12, r12, #0 \n\t" \ + "stmia r0!, {r8} \n\t" \ + \ + "mov r10, #0 \n\t" \ + "umull r8, r9, r4, r2 \n\t" \ + "mov r14, r9 \n\t" \ + "umlal r8, r9, r5, r7 \n\t" \ + "cmp r14, r9 \n\t" \ + "it hi \n\t" \ + "adchi r10, r10, #0 \n\t" \ + "adds r8, r8, r8 \n\t" \ + "adcs r9, r9, r9 \n\t" \ + "adc r10, r10, r10 \n\t" \ + "mov r14, r9 \n\t" \ + "umlal r8, r9, r6, r6 \n\t" \ + "cmp r14, r9 \n\t" \ + "it hi \n\t" \ + "adchi r10, r10, #0 \n\t" \ + "adds r8, r8, r11 \n\t" \ + "adcs r9, r9, r12 \n\t" \ + "adc r10, r10, #0 \n\t" \ + "stmia r0!, {r8} \n\t" \ + \ + "mov r12, #0 \n\t" \ + "umull r8, r11, r5, r2 \n\t" \ + "mov r14, r11 \n\t" \ + "umlal r8, r11, r6, r7 \n\t" \ + "cmp r14, r11 \n\t" \ + "it hi \n\t" \ + "adchi r12, r12, #0 \n\t" \ + "adds r8, r8, r8 \n\t" \ + "adcs r11, r11, r11 \n\t" \ + "adc r12, r12, r12 \n\t" \ + "adds r8, r8, r9 \n\t" \ + "adcs r11, r11, r10 \n\t" \ + "adc r12, r12, #0 \n\t" \ + "stmia r0!, {r8} \n\t" \ + \ + "mov r8, #0 \n\t" \ + "umull r1, r10, r6, r2 \n\t" \ + "adds r1, r1, r1 \n\t" \ + "adcs r10, r10, r10 \n\t" \ + "adc r8, r8, #0 \n\t" \ + "adds r11, r11, r1 \n\t" \ + "adcs r12, r12, r10 \n\t" \ + "adc r8, r8, #0 \n\t" \ + "umull r1, r10, r7, r7 \n\t" \ + "adds r11, r11, r1 \n\t" \ + "adcs r12, r12, r10 \n\t" \ + "adc r8, r8, #0 \n\t" \ + "stmia r0!, {r11} \n\t" \ + \ + "mov r11, #0 \n\t" \ + "umull r1, r10, r7, r2 \n\t" \ + "adds r1, r1, r1 \n\t" \ + "adcs r10, r10, r10 \n\t" \ + "adc r11, r11, #0 \n\t" \ + "adds r12, r12, r1 \n\t" \ + "adcs r8, r8, r10 \n\t" \ + "adc r11, r11, #0 \n\t" \ + "stmia r0!, {r12} \n\t" \ + \ + "umull r1, r10, r2, r2 \n\t" \ + "adds r8, r8, r1 \n\t" \ + "adcs r11, r11, r10 \n\t" \ + "stmia r0!, {r8, r11} \n\t" \ + "pop {r1, r2} \n\t" + +#define FAST_SQUARE_ASM_7_TO_8 \ + "cmp r2, #7 \n\t" \ + "beq 1f \n\t" \ + \ + "sub r0, #28 \n\t" \ + "sub r1, #28 \n\t" \ + \ + /* Do off-center multiplication */ \ + "ldmia r1!, {r6,r7,r8,r9,r10,r11,r12,r14} \n\t" \ + "umull r3, r4, r6, r14 \n\t" \ + "umull r6, r5, r7, r14 \n\t" \ + "adds r4, r4, r6 \n\t" \ + "umull r7, r6, r8, r14 \n\t" \ + "adcs r5, r5, r7 \n\t" \ + "umull r8, r7, r9, r14 \n\t" \ + "adcs r6, r6, r8 \n\t" \ + "umull r9, r8, r10, r14 \n\t" \ + "adcs r7, r7, r9 \n\t" \ + "umull r10, r9, r11, r14 \n\t" \ + "adcs r8, r8, r10 \n\t" \ + "umull r11, r10, r12, r14 \n\t" \ + "adcs r9, r9, r11 \n\t" \ + "adcs r10, r10, #0 \n\t" \ + \ + /* Multiply by 2 */ \ + "mov r11, #0 \n\t" \ + "adds r3, r3, r3 \n\t" \ + "adcs r4, r4, r4 \n\t" \ + "adcs r5, r5, r5 \n\t" \ + "adcs r6, r6, r6 \n\t" \ + "adcs r7, r7, r7 \n\t" \ + "adcs r8, r8, r8 \n\t" \ + "adcs r9, r9, r9 \n\t" \ + "adcs r10, r10, r10 \n\t" \ + "adcs r11, r11, #0 \n\t" \ + \ + /* Add into previous */ \ + "ldr r12, [r0], #4 \n\t" \ + "adds r3, r3, r12 \n\t" \ + "ldr r12, [r0], #4 \n\t" \ + "adcs r4, r4, r12 \n\t" \ + "ldr r12, [r0], #4 \n\t" \ + "adcs r5, r5, r12 \n\t" \ + "ldr r12, [r0], #4 \n\t" \ + "adcs r6, r6, r12 \n\t" \ + "ldr r12, [r0], #4 \n\t" \ + "adcs r7, r7, r12 \n\t" \ + "ldr r12, [r0], #4 \n\t" \ + "adcs r8, r8, r12 \n\t" \ + "ldr r12, [r0], #4 \n\t" \ + "adcs r9, r9, r12 \n\t" \ + "adcs r10, r10, #0 \n\t" \ + "adcs r11, r11, #0 \n\t" \ + "sub r0, #28 \n\t" \ + \ + /* Perform center multiplication */ \ + "umlal r10, r11, r14, r14 \n\t" \ + "stmia r0!, {r3,r4,r5,r6,r7,r8,r9,r10,r11} \n\t" + +#define FAST_SQUARE_ASM_8 \ + "push {r2} \n\t" \ + "ldmia r1!, {r2,r3,r4,r5,r6,r7,r8,r9} \n\t" \ + "push {r1} \n\t" \ + "sub r1, 8 \n\t" \ + \ + "add r0, 24 \n\t" \ + "umull r10, r11, r2, r8 \n\t" \ + "umull r12, r14, r2, r9 \n\t" \ + "umull r8, r9, r3, r9 \n\t" \ + "adds r11, r11, r12 \n\t" \ + "adcs r12, r14, r8 \n\t" \ + "adcs r14, r9, #0 \n\t" \ + "stmia r0!, {r10, r11, r12, r14} \n\t" \ + "sub r0, 40 \n\t" \ + \ + "umull r11, r12, r2, r2 \n\t" \ + "stmia r0!, {r11} \n\t" \ + \ + "mov r9, #0 \n\t" \ + "umull r10, r11, r2, r3 \n\t" \ + "adds r12, r12, r10 \n\t" \ + "adcs r8, r11, #0 \n\t" \ + "adc r9, r9, #0 \n\t" \ + "adds r12, r12, r10 \n\t" \ + "adcs r8, r8, r11 \n\t" \ + "adc r9, r9, #0 \n\t" \ + "stmia r0!, {r12} \n\t" \ + \ + "mov r10, #0 \n\t" \ + "umull r11, r12, r2, r4 \n\t" \ + "adds r11, r11, r11 \n\t" \ + "adcs r12, r12, r12 \n\t" \ + "adc r10, r10, #0 \n\t" \ + "adds r8, r8, r11 \n\t" \ + "adcs r9, r9, r12 \n\t" \ + "adc r10, r10, #0 \n\t" \ + "umull r11, r12, r3, r3 \n\t" \ + "adds r8, r8, r11 \n\t" \ + "adcs r9, r9, r12 \n\t" \ + "adc r10, r10, #0 \n\t" \ + "stmia r0!, {r8} \n\t" \ + \ + "mov r12, #0 \n\t" \ + "umull r8, r11, r2, r5 \n\t" \ + "mov r14, r11 \n\t" \ + "umlal r8, r11, r3, r4 \n\t" \ + "cmp r14, r11 \n\t" \ + "it hi \n\t" \ + "adchi r12, r12, #0 \n\t" \ + "adds r8, r8, r8 \n\t" \ + "adcs r11, r11, r11 \n\t" \ + "adc r12, r12, r12 \n\t" \ + "adds r8, r8, r9 \n\t" \ + "adcs r11, r11, r10 \n\t" \ + "adc r12, r12, #0 \n\t" \ + "stmia r0!, {r8} \n\t" \ + \ + "mov r10, #0 \n\t" \ + "umull r8, r9, r2, r6 \n\t" \ + "mov r14, r9 \n\t" \ + "umlal r8, r9, r3, r5 \n\t" \ + "cmp r14, r9 \n\t" \ + "it hi \n\t" \ + "adchi r10, r10, #0 \n\t" \ + "adds r8, r8, r8 \n\t" \ + "adcs r9, r9, r9 \n\t" \ + "adc r10, r10, r10 \n\t" \ + "mov r14, r9 \n\t" \ + "umlal r8, r9, r4, r4 \n\t" \ + "cmp r14, r9 \n\t" \ + "it hi \n\t" \ + "adchi r10, r10, #0 \n\t" \ + "adds r8, r8, r11 \n\t" \ + "adcs r9, r9, r12 \n\t" \ + "adc r10, r10, #0 \n\t" \ + "stmia r0!, {r8} \n\t" \ + \ + "mov r12, #0 \n\t" \ + "umull r8, r11, r2, r7 \n\t" \ + "mov r14, r11 \n\t" \ + "umlal r8, r11, r3, r6 \n\t" \ + "cmp r14, r11 \n\t" \ + "it hi \n\t" \ + "adchi r12, r12, #0 \n\t" \ + "mov r14, r11 \n\t" \ + "umlal r8, r11, r4, r5 \n\t" \ + "cmp r14, r11 \n\t" \ + "it hi \n\t" \ + "adchi r12, r12, #0 \n\t" \ + "adds r8, r8, r8 \n\t" \ + "adcs r11, r11, r11 \n\t" \ + "adc r12, r12, r12 \n\t" \ + "adds r8, r8, r9 \n\t" \ + "adcs r11, r11, r10 \n\t" \ + "adc r12, r12, #0 \n\t" \ + "stmia r0!, {r8} \n\t" \ + \ + "ldmia r1!, {r2} \n\t" \ + "mov r10, #0 \n\t" \ + "umull r8, r9, r3, r7 \n\t" \ + "mov r14, r9 \n\t" \ + "umlal r8, r9, r4, r6 \n\t" \ + "cmp r14, r9 \n\t" \ + "it hi \n\t" \ + "adchi r10, r10, #0 \n\t" \ + "ldr r14, [r0] \n\t" \ + "adds r8, r8, r14 \n\t" \ + "adcs r9, r9, #0 \n\t" \ + "adc r10, r10, #0 \n\t" \ + "adds r8, r8, r8 \n\t" \ + "adcs r9, r9, r9 \n\t" \ + "adc r10, r10, r10 \n\t" \ + "mov r14, r9 \n\t" \ + "umlal r8, r9, r5, r5 \n\t" \ + "cmp r14, r9 \n\t" \ + "it hi \n\t" \ + "adchi r10, r10, #0 \n\t" \ + "adds r8, r8, r11 \n\t" \ + "adcs r9, r9, r12 \n\t" \ + "adc r10, r10, #0 \n\t" \ + "stmia r0!, {r8} \n\t" \ + \ + "mov r12, #0 \n\t" \ + "umull r8, r11, r3, r2 \n\t" \ + "mov r14, r11 \n\t" \ + "umlal r8, r11, r4, r7 \n\t" \ + "cmp r14, r11 \n\t" \ + "it hi \n\t" \ + "adchi r12, r12, #0 \n\t" \ + "mov r14, r11 \n\t" \ + "umlal r8, r11, r5, r6 \n\t" \ + "cmp r14, r11 \n\t" \ + "it hi \n\t" \ + "adchi r12, r12, #0 \n\t" \ + "ldr r14, [r0] \n\t" \ + "adds r8, r8, r14 \n\t" \ + "adcs r11, r11, #0 \n\t" \ + "adc r12, r12, #0 \n\t" \ + "adds r8, r8, r8 \n\t" \ + "adcs r11, r11, r11 \n\t" \ + "adc r12, r12, r12 \n\t" \ + "adds r8, r8, r9 \n\t" \ + "adcs r11, r11, r10 \n\t" \ + "adc r12, r12, #0 \n\t" \ + "stmia r0!, {r8} \n\t" \ + \ + "ldmia r1!, {r3} \n\t" \ + "mov r10, #0 \n\t" \ + "umull r8, r9, r4, r2 \n\t" \ + "mov r14, r9 \n\t" \ + "umlal r8, r9, r5, r7 \n\t" \ + "cmp r14, r9 \n\t" \ + "it hi \n\t" \ + "adchi r10, r10, #0 \n\t" \ + "ldr r14, [r0] \n\t" \ + "adds r8, r8, r14 \n\t" \ + "adcs r9, r9, #0 \n\t" \ + "adc r10, r10, #0 \n\t" \ + "adds r8, r8, r8 \n\t" \ + "adcs r9, r9, r9 \n\t" \ + "adc r10, r10, r10 \n\t" \ + "mov r14, r9 \n\t" \ + "umlal r8, r9, r6, r6 \n\t" \ + "cmp r14, r9 \n\t" \ + "it hi \n\t" \ + "adchi r10, r10, #0 \n\t" \ + "adds r8, r8, r11 \n\t" \ + "adcs r9, r9, r12 \n\t" \ + "adc r10, r10, #0 \n\t" \ + "stmia r0!, {r8} \n\t" \ + \ + "mov r12, #0 \n\t" \ + "umull r8, r11, r4, r3 \n\t" \ + "mov r14, r11 \n\t" \ + "umlal r8, r11, r5, r2 \n\t" \ + "cmp r14, r11 \n\t" \ + "it hi \n\t" \ + "adchi r12, r12, #0 \n\t" \ + "mov r14, r11 \n\t" \ + "umlal r8, r11, r6, r7 \n\t" \ + "cmp r14, r11 \n\t" \ + "it hi \n\t" \ + "adchi r12, r12, #0 \n\t" \ + "ldr r14, [r0] \n\t" \ + "adds r8, r8, r14 \n\t" \ + "adcs r11, r11, #0 \n\t" \ + "adc r12, r12, #0 \n\t" \ + "adds r8, r8, r8 \n\t" \ + "adcs r11, r11, r11 \n\t" \ + "adc r12, r12, r12 \n\t" \ + "adds r8, r8, r9 \n\t" \ + "adcs r11, r11, r10 \n\t" \ + "adc r12, r12, #0 \n\t" \ + "stmia r0!, {r8} \n\t" \ + \ + "mov r10, #0 \n\t" \ + "umull r8, r9, r5, r3 \n\t" \ + "mov r14, r9 \n\t" \ + "umlal r8, r9, r6, r2 \n\t" \ + "cmp r14, r9 \n\t" \ + "it hi \n\t" \ + "adchi r10, r10, #0 \n\t" \ + "adds r8, r8, r8 \n\t" \ + "adcs r9, r9, r9 \n\t" \ + "adc r10, r10, r10 \n\t" \ + "mov r14, r9 \n\t" \ + "umlal r8, r9, r7, r7 \n\t" \ + "cmp r14, r9 \n\t" \ + "it hi \n\t" \ + "adchi r10, r10, #0 \n\t" \ + "adds r8, r8, r11 \n\t" \ + "adcs r9, r9, r12 \n\t" \ + "adc r10, r10, #0 \n\t" \ + "stmia r0!, {r8} \n\t" \ + \ + "mov r12, #0 \n\t" \ + "umull r8, r11, r6, r3 \n\t" \ + "mov r14, r11 \n\t" \ + "umlal r8, r11, r7, r2 \n\t" \ + "cmp r14, r11 \n\t" \ + "it hi \n\t" \ + "adchi r12, r12, #0 \n\t" \ + "adds r8, r8, r8 \n\t" \ + "adcs r11, r11, r11 \n\t" \ + "adc r12, r12, r12 \n\t" \ + "adds r8, r8, r9 \n\t" \ + "adcs r11, r11, r10 \n\t" \ + "adc r12, r12, #0 \n\t" \ + "stmia r0!, {r8} \n\t" \ + \ + "mov r8, #0 \n\t" \ + "umull r1, r10, r7, r3 \n\t" \ + "adds r1, r1, r1 \n\t" \ + "adcs r10, r10, r10 \n\t" \ + "adc r8, r8, #0 \n\t" \ + "adds r11, r11, r1 \n\t" \ + "adcs r12, r12, r10 \n\t" \ + "adc r8, r8, #0 \n\t" \ + "umull r1, r10, r2, r2 \n\t" \ + "adds r11, r11, r1 \n\t" \ + "adcs r12, r12, r10 \n\t" \ + "adc r8, r8, #0 \n\t" \ + "stmia r0!, {r11} \n\t" \ + \ + "mov r11, #0 \n\t" \ + "umull r1, r10, r2, r3 \n\t" \ + "adds r1, r1, r1 \n\t" \ + "adcs r10, r10, r10 \n\t" \ + "adc r11, r11, #0 \n\t" \ + "adds r12, r12, r1 \n\t" \ + "adcs r8, r8, r10 \n\t" \ + "adc r11, r11, #0 \n\t" \ + "stmia r0!, {r12} \n\t" \ + \ + "umull r1, r10, r3, r3 \n\t" \ + "adds r8, r8, r1 \n\t" \ + "adcs r11, r11, r10 \n\t" \ + "stmia r0!, {r8, r11} \n\t" \ + "pop {r1, r2} \n\t" + +#endif /* _UECC_ASM_ARM_MULT_SQUARE_H_ */ diff --git a/web/server/h2o/libh2o/deps/picotls/deps/micro-ecc/asm_arm_mult_square_umaal.inc b/web/server/h2o/libh2o/deps/picotls/deps/micro-ecc/asm_arm_mult_square_umaal.inc new file mode 100644 index 00000000..c554d20e --- /dev/null +++ b/web/server/h2o/libh2o/deps/picotls/deps/micro-ecc/asm_arm_mult_square_umaal.inc @@ -0,0 +1,1202 @@ +/* Copyright 2015, Kenneth MacKay. Licensed under the BSD 2-clause license. */ + +#ifndef _UECC_ASM_ARM_MULT_SQUARE_H_ +#define _UECC_ASM_ARM_MULT_SQUARE_H_ + +#define FAST_MULT_ASM_5 \ + "push {r3} \n\t" \ + "ldmia r2!, {r3, r4, r5, r6, r7} \n\t" \ + "push {r2} \n\t" \ + \ + "ldr r2, [r1], #4 \n\t" \ + "umull r8, r9, r3, r2 \n\t" \ + "str r8, [r0], #4 \n\t" \ + "mov r10, #0 \n\t" \ + "umaal r9, r10, r4, r2 \n\t" \ + "mov r11, #0 \n\t" \ + "umaal r10, r11, r5, r2 \n\t" \ + "mov r12, #0 \n\t" \ + "umaal r11, r12, r6, r2 \n\t" \ + "mov r14, #0 \n\t" \ + "umaal r12, r14, r7, r2 \n\t" \ + \ + "ldr r2, [r1], #4 \n\t" \ + "mov r8, #0 \n\t" \ + "umaal r8, r9, r3, r2 \n\t" \ + "str r8, [r0], #4 \n\t" \ + "umaal r9, r10, r4, r2 \n\t" \ + "umaal r10, r11, r5, r2 \n\t" \ + "umaal r11, r12, r6, r2 \n\t" \ + "umaal r12, r14, r7, r2 \n\t" \ + \ + "ldr r2, [r1], #4 \n\t" \ + "mov r8, #0 \n\t" \ + "umaal r8, r9, r3, r2 \n\t" \ + "str r8, [r0], #4 \n\t" \ + "umaal r9, r10, r4, r2 \n\t" \ + "umaal r10, r11, r5, r2 \n\t" \ + "umaal r11, r12, r6, r2 \n\t" \ + "umaal r12, r14, r7, r2 \n\t" \ + \ + "ldr r2, [r1], #4 \n\t" \ + "mov r8, #0 \n\t" \ + "umaal r8, r9, r3, r2 \n\t" \ + "str r8, [r0], #4 \n\t" \ + "umaal r9, r10, r4, r2 \n\t" \ + "umaal r10, r11, r5, r2 \n\t" \ + "umaal r11, r12, r6, r2 \n\t" \ + "umaal r12, r14, r7, r2 \n\t" \ + \ + "ldr r2, [r1], #4 \n\t" \ + "mov r8, #0 \n\t" \ + "umaal r8, r9, r3, r2 \n\t" \ + "str r8, [r0], #4 \n\t" \ + "umaal r9, r10, r4, r2 \n\t" \ + "umaal r10, r11, r5, r2 \n\t" \ + "umaal r11, r12, r6, r2 \n\t" \ + "umaal r12, r14, r7, r2 \n\t" \ + \ + "str r9, [r0], #4 \n\t" \ + "str r10, [r0], #4 \n\t" \ + "str r11, [r0], #4 \n\t" \ + "str r12, [r0], #4 \n\t" \ + "str r14, [r0], #4 \n\t" \ + \ + "pop {r2, r3} \n\t" + +#define FAST_MULT_ASM_5_TO_6 \ + "cmp r3, #5 \n\t" \ + "beq 1f \n\t" \ + \ + /* r4 = left high */ \ + "ldr r4, [r1] \n\t" \ + \ + "sub r0, #20 \n\t" \ + "sub r1, #20 \n\t" \ + "sub r2, #20 \n\t" \ + \ + /* Do right side */ \ + "ldr r14, [r2], #4 \n\t" \ + "mov r5, #0 \n\t" \ + "ldr r6, [r0], #4 \n\t" \ + "umaal r5, r6, r4, r14 \n\t" \ + "ldr r14, [r2], #4 \n\t" \ + "ldr r7, [r0], #4 \n\t" \ + "umaal r6, r7, r4, r14 \n\t" \ + "ldr r14, [r2], #4 \n\t" \ + "ldr r8, [r0], #4 \n\t" \ + "umaal r7, r8, r4, r14 \n\t" \ + "ldr r14, [r2], #4 \n\t" \ + "ldr r9, [r0], #4 \n\t" \ + "umaal r8, r9, r4, r14 \n\t" \ + "ldr r14, [r2], #4 \n\t" \ + "ldr r10, [r0], #4 \n\t" \ + "umaal r9, r10, r4, r14 \n\t" \ + "sub r0, #20 \n\t" \ + \ + /* r4 = right high */ \ + "ldr r4, [r2], #4 \n\t" \ + \ + /* Do left side */ \ + "ldr r14, [r1], #4 \n\t" \ + "mov r12, #0 \n\t" \ + "umaal r12, r5, r4, r14 \n\t" \ + "str r12, [r0], #4 \n\t" \ + "ldr r14, [r1], #4 \n\t" \ + "umaal r5, r6, r4, r14 \n\t" \ + "str r5, [r0], #4 \n\t" \ + "ldr r14, [r1], #4 \n\t" \ + "umaal r6, r7, r4, r14 \n\t" \ + "str r6, [r0], #4 \n\t" \ + "ldr r14, [r1], #4 \n\t" \ + "umaal r7, r8, r4, r14 \n\t" \ + "str r7, [r0], #4 \n\t" \ + "ldr r14, [r1], #4 \n\t" \ + "umaal r8, r9, r4, r14 \n\t" \ + "str r8, [r0], #4 \n\t" \ + \ + "ldr r14, [r1], #4 \n\t" \ + "umaal r9, r10, r4, r14 \n\t" \ + "stmia r0!, {r9, r10} \n\t" + +#define FAST_MULT_ASM_6 \ + "ldmia r2!, {r4, r5, r6} \n\t" \ + \ + "ldr r14, [r1], #4 \n\t" \ + "umull r8, r9, r4, r14 \n\t" \ + "str r8, [r0], #4 \n\t" \ + "mov r10, #0 \n\t" \ + "umaal r9, r10, r5, r14 \n\t" \ + "mov r11, #0 \n\t" \ + "umaal r10, r11, r6, r14 \n\t" \ + \ + "ldr r14, [r1], #4 \n\t" \ + "mov r8, #0 \n\t" \ + "umaal r8, r9, r4, r14 \n\t" \ + "str r8, [r0], #4 \n\t" \ + "umaal r9, r10, r5, r14 \n\t" \ + "umaal r10, r11, r6, r14 \n\t" \ + \ + "ldr r14, [r1], #4 \n\t" \ + "mov r8, #0 \n\t" \ + "umaal r8, r9, r4, r14 \n\t" \ + "str r8, [r0], #4 \n\t" \ + "umaal r9, r10, r5, r14 \n\t" \ + "umaal r10, r11, r6, r14 \n\t" \ + \ + "ldr r14, [r1], #4 \n\t" \ + "mov r8, #0 \n\t" \ + "umaal r8, r9, r4, r14 \n\t" \ + "str r8, [r0], #4 \n\t" \ + "umaal r9, r10, r5, r14 \n\t" \ + "umaal r10, r11, r6, r14 \n\t" \ + \ + "ldr r14, [r1], #4 \n\t" \ + "mov r8, #0 \n\t" \ + "umaal r8, r9, r4, r14 \n\t" \ + "str r8, [r0], #4 \n\t" \ + "umaal r9, r10, r5, r14 \n\t" \ + "umaal r10, r11, r6, r14 \n\t" \ + \ + "ldr r14, [r1], #4 \n\t" \ + "mov r8, #0 \n\t" \ + "umaal r8, r9, r4, r14 \n\t" \ + "str r8, [r0], #4 \n\t" \ + "umaal r9, r10, r5, r14 \n\t" \ + "umaal r10, r11, r6, r14 \n\t" \ + \ + "str r9, [r0], #4 \n\t" \ + "str r10, [r0], #4 \n\t" \ + "str r11, [r0], #4 \n\t" \ + \ + "sub r0, #24 \n\t" \ + "sub r1, #24 \n\t" \ + "ldmia r2!, {r4, r5, r6} \n\t" \ + \ + "ldr r14, [r1], #4 \n\t" \ + "ldr r8, [r0] \n\t" \ + "mov r9, #0 \n\t" \ + "umaal r8, r9, r4, r14 \n\t" \ + "str r8, [r0], #4 \n\t" \ + "mov r10, #0 \n\t" \ + "umaal r9, r10, r5, r14 \n\t" \ + "mov r11, #0 \n\t" \ + "umaal r10, r11, r6, r14 \n\t" \ + \ + "ldr r14, [r1], #4 \n\t" \ + "ldr r8, [r0] \n\t" \ + "umaal r8, r9, r4, r14 \n\t" \ + "str r8, [r0], #4 \n\t" \ + "umaal r9, r10, r5, r14 \n\t" \ + "umaal r10, r11, r6, r14 \n\t" \ + \ + "ldr r14, [r1], #4 \n\t" \ + "ldr r8, [r0] \n\t" \ + "umaal r8, r9, r4, r14 \n\t" \ + "str r8, [r0], #4 \n\t" \ + "umaal r9, r10, r5, r14 \n\t" \ + "umaal r10, r11, r6, r14 \n\t" \ + \ + "ldr r14, [r1], #4 \n\t" \ + "ldr r8, [r0] \n\t" \ + "umaal r8, r9, r4, r14 \n\t" \ + "str r8, [r0], #4 \n\t" \ + "umaal r9, r10, r5, r14 \n\t" \ + "umaal r10, r11, r6, r14 \n\t" \ + \ + "ldr r14, [r1], #4 \n\t" \ + "ldr r8, [r0] \n\t" \ + "umaal r8, r9, r4, r14 \n\t" \ + "str r8, [r0], #4 \n\t" \ + "umaal r9, r10, r5, r14 \n\t" \ + "umaal r10, r11, r6, r14 \n\t" \ + \ + "ldr r14, [r1], #4 \n\t" \ + "ldr r8, [r0] \n\t" \ + "umaal r8, r9, r4, r14 \n\t" \ + "str r8, [r0], #4 \n\t" \ + "umaal r9, r10, r5, r14 \n\t" \ + "umaal r10, r11, r6, r14 \n\t" \ + \ + "str r9, [r0], #4 \n\t" \ + "str r10, [r0], #4 \n\t" \ + "str r11, [r0], #4 \n\t" + +#define FAST_MULT_ASM_6_TO_7 \ + "cmp r3, #6 \n\t" \ + "beq 1f \n\t" \ + \ + /* r4 = left high */ \ + "ldr r4, [r1] \n\t" \ + \ + "sub r0, #24 \n\t" \ + "sub r1, #24 \n\t" \ + "sub r2, #24 \n\t" \ + \ + /* Do right side */ \ + "ldr r14, [r2], #4 \n\t" \ + "mov r5, #0 \n\t" \ + "ldr r6, [r0], #4 \n\t" \ + "umaal r5, r6, r4, r14 \n\t" \ + "ldr r14, [r2], #4 \n\t" \ + "ldr r7, [r0], #4 \n\t" \ + "umaal r6, r7, r4, r14 \n\t" \ + "ldr r14, [r2], #4 \n\t" \ + "ldr r8, [r0], #4 \n\t" \ + "umaal r7, r8, r4, r14 \n\t" \ + "ldr r14, [r2], #4 \n\t" \ + "ldr r9, [r0], #4 \n\t" \ + "umaal r8, r9, r4, r14 \n\t" \ + "ldr r14, [r2], #4 \n\t" \ + "ldr r10, [r0], #4 \n\t" \ + "umaal r9, r10, r4, r14 \n\t" \ + "ldr r14, [r2], #4 \n\t" \ + "ldr r11, [r0], #4 \n\t" \ + "umaal r10, r11, r4, r14 \n\t" \ + "sub r0, #24 \n\t" \ + \ + /* r4 = right high */ \ + "ldr r4, [r2], #4 \n\t" \ + \ + /* Do left side */ \ + "ldr r14, [r1], #4 \n\t" \ + "mov r12, #0 \n\t" \ + "umaal r12, r5, r4, r14 \n\t" \ + "str r12, [r0], #4 \n\t" \ + "ldr r14, [r1], #4 \n\t" \ + "umaal r5, r6, r4, r14 \n\t" \ + "str r5, [r0], #4 \n\t" \ + "ldr r14, [r1], #4 \n\t" \ + "umaal r6, r7, r4, r14 \n\t" \ + "str r6, [r0], #4 \n\t" \ + "ldr r14, [r1], #4 \n\t" \ + "umaal r7, r8, r4, r14 \n\t" \ + "str r7, [r0], #4 \n\t" \ + "ldr r14, [r1], #4 \n\t" \ + "umaal r8, r9, r4, r14 \n\t" \ + "str r8, [r0], #4 \n\t" \ + "ldr r14, [r1], #4 \n\t" \ + "umaal r9, r10, r4, r14 \n\t" \ + "str r9, [r0], #4 \n\t" \ + \ + "ldr r14, [r1], #4 \n\t" \ + "umaal r10, r11, r4, r14 \n\t" \ + "stmia r0!, {r10, r11} \n\t" + +#define FAST_MULT_ASM_7 \ + "ldmia r2!, {r4, r5, r6, r7} \n\t" \ + \ + "ldr r14, [r1], #4 \n\t" \ + "umull r8, r9, r4, r14 \n\t" \ + "str r8, [r0], #4 \n\t" \ + "mov r10, #0 \n\t" \ + "umaal r9, r10, r5, r14 \n\t" \ + "mov r11, #0 \n\t" \ + "umaal r10, r11, r6, r14 \n\t" \ + "mov r12, #0 \n\t" \ + "umaal r11, r12, r7, r14 \n\t" \ + \ + "ldr r14, [r1], #4 \n\t" \ + "mov r8, #0 \n\t" \ + "umaal r8, r9, r4, r14 \n\t" \ + "str r8, [r0], #4 \n\t" \ + "umaal r9, r10, r5, r14 \n\t" \ + "umaal r10, r11, r6, r14 \n\t" \ + "umaal r11, r12, r7, r14 \n\t" \ + \ + "ldr r14, [r1], #4 \n\t" \ + "mov r8, #0 \n\t" \ + "umaal r8, r9, r4, r14 \n\t" \ + "str r8, [r0], #4 \n\t" \ + "umaal r9, r10, r5, r14 \n\t" \ + "umaal r10, r11, r6, r14 \n\t" \ + "umaal r11, r12, r7, r14 \n\t" \ + \ + "ldr r14, [r1], #4 \n\t" \ + "mov r8, #0 \n\t" \ + "umaal r8, r9, r4, r14 \n\t" \ + "str r8, [r0], #4 \n\t" \ + "umaal r9, r10, r5, r14 \n\t" \ + "umaal r10, r11, r6, r14 \n\t" \ + "umaal r11, r12, r7, r14 \n\t" \ + \ + "ldr r14, [r1], #4 \n\t" \ + "mov r8, #0 \n\t" \ + "umaal r8, r9, r4, r14 \n\t" \ + "str r8, [r0], #4 \n\t" \ + "umaal r9, r10, r5, r14 \n\t" \ + "umaal r10, r11, r6, r14 \n\t" \ + "umaal r11, r12, r7, r14 \n\t" \ + \ + "ldr r14, [r1], #4 \n\t" \ + "mov r8, #0 \n\t" \ + "umaal r8, r9, r4, r14 \n\t" \ + "str r8, [r0], #4 \n\t" \ + "umaal r9, r10, r5, r14 \n\t" \ + "umaal r10, r11, r6, r14 \n\t" \ + "umaal r11, r12, r7, r14 \n\t" \ + \ + "ldr r14, [r1], #4 \n\t" \ + "mov r8, #0 \n\t" \ + "umaal r8, r9, r4, r14 \n\t" \ + "str r8, [r0], #4 \n\t" \ + "umaal r9, r10, r5, r14 \n\t" \ + "umaal r10, r11, r6, r14 \n\t" \ + "umaal r11, r12, r7, r14 \n\t" \ + \ + "str r9, [r0], #4 \n\t" \ + "str r10, [r0], #4 \n\t" \ + "str r11, [r0], #4 \n\t" \ + "str r12, [r0], #4 \n\t" \ + \ + "sub r0, #28 \n\t" \ + "sub r1, #28 \n\t" \ + "ldmia r2!, {r4, r5, r6} \n\t" \ + \ + "ldr r14, [r1], #4 \n\t" \ + "ldr r8, [r0] \n\t" \ + "mov r9, #0 \n\t" \ + "umaal r8, r9, r4, r14 \n\t" \ + "str r8, [r0], #4 \n\t" \ + "mov r10, #0 \n\t" \ + "umaal r9, r10, r5, r14 \n\t" \ + "mov r11, #0 \n\t" \ + "umaal r10, r11, r6, r14 \n\t" \ + \ + "ldr r14, [r1], #4 \n\t" \ + "ldr r8, [r0] \n\t" \ + "umaal r8, r9, r4, r14 \n\t" \ + "str r8, [r0], #4 \n\t" \ + "umaal r9, r10, r5, r14 \n\t" \ + "umaal r10, r11, r6, r14 \n\t" \ + \ + "ldr r14, [r1], #4 \n\t" \ + "ldr r8, [r0] \n\t" \ + "umaal r8, r9, r4, r14 \n\t" \ + "str r8, [r0], #4 \n\t" \ + "umaal r9, r10, r5, r14 \n\t" \ + "umaal r10, r11, r6, r14 \n\t" \ + \ + "ldr r14, [r1], #4 \n\t" \ + "ldr r8, [r0] \n\t" \ + "umaal r8, r9, r4, r14 \n\t" \ + "str r8, [r0], #4 \n\t" \ + "umaal r9, r10, r5, r14 \n\t" \ + "umaal r10, r11, r6, r14 \n\t" \ + \ + "ldr r14, [r1], #4 \n\t" \ + "ldr r8, [r0] \n\t" \ + "umaal r8, r9, r4, r14 \n\t" \ + "str r8, [r0], #4 \n\t" \ + "umaal r9, r10, r5, r14 \n\t" \ + "umaal r10, r11, r6, r14 \n\t" \ + \ + "ldr r14, [r1], #4 \n\t" \ + "ldr r8, [r0] \n\t" \ + "umaal r8, r9, r4, r14 \n\t" \ + "str r8, [r0], #4 \n\t" \ + "umaal r9, r10, r5, r14 \n\t" \ + "umaal r10, r11, r6, r14 \n\t" \ + \ + "ldr r14, [r1], #4 \n\t" \ + "ldr r8, [r0] \n\t" \ + "umaal r8, r9, r4, r14 \n\t" \ + "str r8, [r0], #4 \n\t" \ + "umaal r9, r10, r5, r14 \n\t" \ + "umaal r10, r11, r6, r14 \n\t" \ + \ + "str r9, [r0], #4 \n\t" \ + "str r10, [r0], #4 \n\t" \ + "str r11, [r0], #4 \n\t" + +#define FAST_MULT_ASM_7_TO_8 \ + "cmp r3, #7 \n\t" \ + "beq 1f \n\t" \ + "push {r3} \n\t" \ + \ + /* r4 = left high */ \ + "ldr r4, [r1] \n\t" \ + \ + "sub r0, #28 \n\t" \ + "sub r1, #28 \n\t" \ + "sub r2, #28 \n\t" \ + \ + /* Do right side */ \ + "ldr r14, [r2], #4 \n\t" \ + "mov r5, #0 \n\t" \ + "ldr r6, [r0], #4 \n\t" \ + "umaal r5, r6, r4, r14 \n\t" \ + "ldr r14, [r2], #4 \n\t" \ + "ldr r7, [r0], #4 \n\t" \ + "umaal r6, r7, r4, r14 \n\t" \ + "ldr r14, [r2], #4 \n\t" \ + "ldr r8, [r0], #4 \n\t" \ + "umaal r7, r8, r4, r14 \n\t" \ + "ldr r14, [r2], #4 \n\t" \ + "ldr r9, [r0], #4 \n\t" \ + "umaal r8, r9, r4, r14 \n\t" \ + "ldr r14, [r2], #4 \n\t" \ + "ldr r10, [r0], #4 \n\t" \ + "umaal r9, r10, r4, r14 \n\t" \ + "ldr r14, [r2], #4 \n\t" \ + "ldr r11, [r0], #4 \n\t" \ + "umaal r10, r11, r4, r14 \n\t" \ + "ldr r14, [r2], #4 \n\t" \ + "ldr r12, [r0], #4 \n\t" \ + "umaal r11, r12, r4, r14 \n\t" \ + "sub r0, #28 \n\t" \ + \ + /* r4 = right high */ \ + "ldr r4, [r2], #4 \n\t" \ + \ + /* Do left side */ \ + "ldr r14, [r1], #4 \n\t" \ + "mov r3, #0 \n\t" \ + "umaal r3, r5, r4, r14 \n\t" \ + "str r3, [r0], #4 \n\t" \ + "ldr r14, [r1], #4 \n\t" \ + "umaal r5, r6, r4, r14 \n\t" \ + "str r5, [r0], #4 \n\t" \ + "ldr r14, [r1], #4 \n\t" \ + "umaal r6, r7, r4, r14 \n\t" \ + "str r6, [r0], #4 \n\t" \ + "ldr r14, [r1], #4 \n\t" \ + "umaal r7, r8, r4, r14 \n\t" \ + "str r7, [r0], #4 \n\t" \ + "ldr r14, [r1], #4 \n\t" \ + "umaal r8, r9, r4, r14 \n\t" \ + "str r8, [r0], #4 \n\t" \ + "ldr r14, [r1], #4 \n\t" \ + "umaal r9, r10, r4, r14 \n\t" \ + "str r9, [r0], #4 \n\t" \ + "ldr r14, [r1], #4 \n\t" \ + "umaal r10, r11, r4, r14 \n\t" \ + "str r10, [r0], #4 \n\t" \ + \ + "ldr r14, [r1], #4 \n\t" \ + "umaal r11, r12, r4, r14 \n\t" \ + "stmia r0!, {r11, r12} \n\t" \ + "pop {r3} \n\t" + +#define FAST_MULT_ASM_8 \ + "ldmia r2!, {r4, r5, r6, r7} \n\t" \ + \ + "ldr r14, [r1], #4 \n\t" \ + "umull r8, r9, r4, r14 \n\t" \ + "str r8, [r0], #4 \n\t" \ + "mov r10, #0 \n\t" \ + "umaal r9, r10, r5, r14 \n\t" \ + "mov r11, #0 \n\t" \ + "umaal r10, r11, r6, r14 \n\t" \ + "mov r12, #0 \n\t" \ + "umaal r11, r12, r7, r14 \n\t" \ + \ + "ldr r14, [r1], #4 \n\t" \ + "mov r8, #0 \n\t" \ + "umaal r8, r9, r4, r14 \n\t" \ + "str r8, [r0], #4 \n\t" \ + "umaal r9, r10, r5, r14 \n\t" \ + "umaal r10, r11, r6, r14 \n\t" \ + "umaal r11, r12, r7, r14 \n\t" \ + \ + "ldr r14, [r1], #4 \n\t" \ + "mov r8, #0 \n\t" \ + "umaal r8, r9, r4, r14 \n\t" \ + "str r8, [r0], #4 \n\t" \ + "umaal r9, r10, r5, r14 \n\t" \ + "umaal r10, r11, r6, r14 \n\t" \ + "umaal r11, r12, r7, r14 \n\t" \ + \ + "ldr r14, [r1], #4 \n\t" \ + "mov r8, #0 \n\t" \ + "umaal r8, r9, r4, r14 \n\t" \ + "str r8, [r0], #4 \n\t" \ + "umaal r9, r10, r5, r14 \n\t" \ + "umaal r10, r11, r6, r14 \n\t" \ + "umaal r11, r12, r7, r14 \n\t" \ + \ + "ldr r14, [r1], #4 \n\t" \ + "mov r8, #0 \n\t" \ + "umaal r8, r9, r4, r14 \n\t" \ + "str r8, [r0], #4 \n\t" \ + "umaal r9, r10, r5, r14 \n\t" \ + "umaal r10, r11, r6, r14 \n\t" \ + "umaal r11, r12, r7, r14 \n\t" \ + \ + "ldr r14, [r1], #4 \n\t" \ + "mov r8, #0 \n\t" \ + "umaal r8, r9, r4, r14 \n\t" \ + "str r8, [r0], #4 \n\t" \ + "umaal r9, r10, r5, r14 \n\t" \ + "umaal r10, r11, r6, r14 \n\t" \ + "umaal r11, r12, r7, r14 \n\t" \ + \ + "ldr r14, [r1], #4 \n\t" \ + "mov r8, #0 \n\t" \ + "umaal r8, r9, r4, r14 \n\t" \ + "str r8, [r0], #4 \n\t" \ + "umaal r9, r10, r5, r14 \n\t" \ + "umaal r10, r11, r6, r14 \n\t" \ + "umaal r11, r12, r7, r14 \n\t" \ + \ + "ldr r14, [r1], #4 \n\t" \ + "mov r8, #0 \n\t" \ + "umaal r8, r9, r4, r14 \n\t" \ + "str r8, [r0], #4 \n\t" \ + "umaal r9, r10, r5, r14 \n\t" \ + "umaal r10, r11, r6, r14 \n\t" \ + "umaal r11, r12, r7, r14 \n\t" \ + \ + "str r9, [r0], #4 \n\t" \ + "str r10, [r0], #4 \n\t" \ + "str r11, [r0], #4 \n\t" \ + "str r12, [r0], #4 \n\t" \ + \ + "sub r0, #32 \n\t" \ + "sub r1, #32 \n\t" \ + "ldmia r2!, {r4, r5, r6, r7} \n\t" \ + \ + "ldr r14, [r1], #4 \n\t" \ + "ldr r8, [r0] \n\t" \ + "mov r9, #0 \n\t" \ + "umaal r8, r9, r4, r14 \n\t" \ + "str r8, [r0], #4 \n\t" \ + "mov r10, #0 \n\t" \ + "umaal r9, r10, r5, r14 \n\t" \ + "mov r11, #0 \n\t" \ + "umaal r10, r11, r6, r14 \n\t" \ + "mov r12, #0 \n\t" \ + "umaal r11, r12, r7, r14 \n\t" \ + \ + "ldr r14, [r1], #4 \n\t" \ + "ldr r8, [r0] \n\t" \ + "umaal r8, r9, r4, r14 \n\t" \ + "str r8, [r0], #4 \n\t" \ + "umaal r9, r10, r5, r14 \n\t" \ + "umaal r10, r11, r6, r14 \n\t" \ + "umaal r11, r12, r7, r14 \n\t" \ + \ + "ldr r14, [r1], #4 \n\t" \ + "ldr r8, [r0] \n\t" \ + "umaal r8, r9, r4, r14 \n\t" \ + "str r8, [r0], #4 \n\t" \ + "umaal r9, r10, r5, r14 \n\t" \ + "umaal r10, r11, r6, r14 \n\t" \ + "umaal r11, r12, r7, r14 \n\t" \ + \ + "ldr r14, [r1], #4 \n\t" \ + "ldr r8, [r0] \n\t" \ + "umaal r8, r9, r4, r14 \n\t" \ + "str r8, [r0], #4 \n\t" \ + "umaal r9, r10, r5, r14 \n\t" \ + "umaal r10, r11, r6, r14 \n\t" \ + "umaal r11, r12, r7, r14 \n\t" \ + \ + "ldr r14, [r1], #4 \n\t" \ + "ldr r8, [r0] \n\t" \ + "umaal r8, r9, r4, r14 \n\t" \ + "str r8, [r0], #4 \n\t" \ + "umaal r9, r10, r5, r14 \n\t" \ + "umaal r10, r11, r6, r14 \n\t" \ + "umaal r11, r12, r7, r14 \n\t" \ + \ + "ldr r14, [r1], #4 \n\t" \ + "ldr r8, [r0] \n\t" \ + "umaal r8, r9, r4, r14 \n\t" \ + "str r8, [r0], #4 \n\t" \ + "umaal r9, r10, r5, r14 \n\t" \ + "umaal r10, r11, r6, r14 \n\t" \ + "umaal r11, r12, r7, r14 \n\t" \ + \ + "ldr r14, [r1], #4 \n\t" \ + "ldr r8, [r0] \n\t" \ + "umaal r8, r9, r4, r14 \n\t" \ + "str r8, [r0], #4 \n\t" \ + "umaal r9, r10, r5, r14 \n\t" \ + "umaal r10, r11, r6, r14 \n\t" \ + "umaal r11, r12, r7, r14 \n\t" \ + \ + "ldr r14, [r1], #4 \n\t" \ + "ldr r8, [r0] \n\t" \ + "umaal r8, r9, r4, r14 \n\t" \ + "str r8, [r0], #4 \n\t" \ + "umaal r9, r10, r5, r14 \n\t" \ + "umaal r10, r11, r6, r14 \n\t" \ + "umaal r11, r12, r7, r14 \n\t" \ + \ + "str r9, [r0], #4 \n\t" \ + "str r10, [r0], #4 \n\t" \ + "str r11, [r0], #4 \n\t" \ + "str r12, [r0], #4 \n\t" + +#define FAST_SQUARE_ASM_5 \ + "ldmia r1!, {r9,r10,r11,r12,r14} \n\t" \ + "push {r1, r2} \n\t" \ + \ + "umull r1, r2, r10, r9 \n\t" \ + "mov r3, #0 \n\t" \ + "umaal r2, r3, r11, r9 \n\t" \ + "mov r4, #0 \n\t" \ + "umaal r3, r4, r12, r9 \n\t" \ + "mov r5, #0 \n\t" \ + "umaal r4, r5, r14, r9 \n\t" \ + \ + "mov r6, #0 \n\t" \ + "umaal r6, r3, r11, r10 \n\t" \ + "umaal r3, r4, r12, r10 \n\t" \ + "adds r1, r1, r1 \n\t" \ + "adcs r2, r2, r2 \n\t" \ + "adcs r6, r6, r6 \n\t" \ + "adcs r3, r3, r3 \n\t" \ + \ + "umull r7, r8, r9, r9 \n\t" \ + /* Store carry in r9 */ \ + "mov r9, #0 \n\t" \ + "adc r9, r9, #0 \n\t" \ + "adds r8, r8, r1 \n\t" \ + "stmia r0!, {r7,r8} \n\t" \ + \ + "umull r7, r8, r10, r10 \n\t" \ + "adcs r7, r7, r2 \n\t" \ + "adcs r8, r8, r6 \n\t" \ + "stmia r0!, {r7,r8} \n\t" \ + \ + "umaal r4, r5, r14, r10 \n\t" \ + /* Store carry in r10 */ \ + "mov r10, #0 \n\t" \ + "adc r10, r10, #0 \n\t" \ + \ + "mov r1, #0 \n\t" \ + "umaal r1, r4, r12, r11 \n\t" \ + "umaal r4, r5, r14, r11 \n\t" \ + \ + "mov r2, #0 \n\t" \ + "umaal r2, r5, r14, r12 \n\t" \ + /* Load carry from r9 */ \ + "lsrs r9, #1 \n\t" \ + "adcs r1, r1, r1 \n\t" \ + "adcs r4, r4, r4 \n\t" \ + "adcs r2, r2, r2 \n\t" \ + "adcs r5, r5, r5 \n\t" \ + /* r9 is 0 now */ \ + "adc r9, r9, #0 \n\t" \ + \ + /* Use carry from r10 */ \ + "umaal r3, r10, r11, r11 \n\t" \ + "adds r10, r10, r1 \n\t" \ + "stmia r0!, {r3,r10} \n\t" \ + \ + "umull r6, r10, r12, r12 \n\t" \ + "adcs r6, r6, r4 \n\t" \ + "adcs r10, r10, r2 \n\t" \ + "stmia r0!, {r6,r10} \n\t" \ + \ + "umull r6, r10, r14, r14 \n\t" \ + "adcs r6, r6, r5 \n\t" \ + "adcs r10, r10, r9 \n\t" \ + "stmia r0!, {r6,r10} \n\t" \ + "pop {r1, r2} \n\t" + +#define FAST_SQUARE_ASM_5_TO_6 \ + "cmp r2, #5 \n\t" \ + "beq 1f \n\t" \ + \ + "sub r0, #20 \n\t" \ + "sub r1, #20 \n\t" \ + \ + /* Do off-center multiplication */ \ + "ldmia r1!, {r5,r6,r7,r8,r9,r14} \n\t" \ + "umull r3, r4, r5, r14 \n\t" \ + "mov r5, #0 \n\t" \ + "umaal r4, r5, r6, r14 \n\t" \ + "mov r6, #0 \n\t" \ + "umaal r5, r6, r7, r14 \n\t" \ + "mov r7, #0 \n\t" \ + "umaal r6, r7, r8, r14 \n\t" \ + "mov r8, #0 \n\t" \ + "umaal r7, r8, r9, r14 \n\t" \ + \ + /* Multiply by 2 */ \ + "mov r9, #0 \n\t" \ + "adds r3, r3, r3 \n\t" \ + "adcs r4, r4, r4 \n\t" \ + "adcs r5, r5, r5 \n\t" \ + "adcs r6, r6, r6 \n\t" \ + "adcs r7, r7, r7 \n\t" \ + "adcs r8, r8, r8 \n\t" \ + "adcs r9, r9, #0 \n\t" \ + \ + /* Add into previous */ \ + "ldr r12, [r0], #4 \n\t" \ + "adds r3, r3, r12 \n\t" \ + "ldr r12, [r0], #4 \n\t" \ + "adcs r4, r4, r12 \n\t" \ + "ldr r12, [r0], #4 \n\t" \ + "adcs r5, r5, r12 \n\t" \ + "ldr r12, [r0], #4 \n\t" \ + "adcs r6, r6, r12 \n\t" \ + "ldr r12, [r0], #4 \n\t" \ + "adcs r7, r7, r12 \n\t" \ + "adcs r8, r8, #0 \n\t" \ + "adcs r9, r9, #0 \n\t" \ + "sub r0, #20 \n\t" \ + \ + /* Perform center multiplication */ \ + "umlal r8, r9, r14, r14 \n\t" \ + "stmia r0!, {r3,r4,r5,r6,r7,r8,r9} \n\t" + +#define FAST_SQUARE_ASM_6 \ + "ldmia r1!, {r8,r9,r10,r11,r12,r14} \n\t" \ + "push {r1, r2} \n\t" \ + \ + "umull r1, r2, r9, r8 \n\t" \ + "mov r3, #0 \n\t" \ + "umaal r2, r3, r10, r8 \n\t" \ + "mov r4, #0 \n\t" \ + "umaal r3, r4, r11, r8 \n\t" \ + "mov r5, #0 \n\t" \ + "umaal r4, r5, r12, r8 \n\t" \ + "mov r6, #0 \n\t" \ + "umaal r5, r6, r14, r8 \n\t" \ + \ + "mov r7, #0 \n\t" \ + "umaal r7, r3, r10, r9 \n\t" \ + "umaal r3, r4, r11, r9 \n\t" \ + "umaal r4, r5, r12, r9 \n\t" \ + "push {r4, r5} \n\t" \ + "adds r1, r1, r1 \n\t" \ + "adcs r2, r2, r2 \n\t" \ + "adcs r7, r7, r7 \n\t" \ + "adcs r3, r3, r3 \n\t" \ + \ + "umull r4, r5, r8, r8 \n\t" \ + /* Store carry in r8 */ \ + "mov r8, #0 \n\t" \ + "adc r8, r8, #0 \n\t" \ + "adds r5, r5, r1 \n\t" \ + "stmia r0!, {r4,r5} \n\t" \ + \ + "umull r4, r5, r9, r9 \n\t" \ + "adcs r4, r4, r2 \n\t" \ + "adcs r5, r5, r7 \n\t" \ + "stmia r0!, {r4,r5} \n\t" \ + \ + "pop {r4, r5} \n\t" \ + "umaal r5, r6, r14, r9 \n\t" \ + /* Store carry in r9 */ \ + "mov r9, #0 \n\t" \ + "adc r9, r9, #0 \n\t" \ + \ + "mov r1, #0 \n\t" \ + "umaal r1, r4, r11, r10 \n\t" \ + "umaal r4, r5, r12, r10 \n\t" \ + "umaal r5, r6, r14, r10 \n\t" \ + \ + "mov r2, #0 \n\t" \ + "umaal r2, r5, r12, r11 \n\t" \ + "umaal r5, r6, r14, r11 \n\t" \ + \ + "mov r7, #0 \n\t" \ + "umaal r7, r6, r14, r12 \n\t" \ + \ + /* Load carry from r8 */ \ + "lsrs r8, #1 \n\t" \ + "adcs r1, r1, r1 \n\t" \ + "adcs r4, r4, r4 \n\t" \ + "adcs r2, r2, r2 \n\t" \ + "adcs r5, r5, r5 \n\t" \ + "adcs r7, r7, r7 \n\t" \ + "adcs r6, r6, r6 \n\t" \ + "adc r8, r8, #0 \n\t" \ + \ + /* Use carry from r9 */ \ + "umaal r3, r9, r10, r10 \n\t" \ + "adds r9, r9, r1 \n\t" \ + "stmia r0!, {r3,r9} \n\t" \ + \ + "umull r9, r10, r11, r11 \n\t" \ + "adcs r9, r9, r4 \n\t" \ + "adcs r10, r10, r2 \n\t" \ + "stmia r0!, {r9,r10} \n\t" \ + \ + "umull r9, r10, r12, r12 \n\t" \ + "adcs r9, r9, r5 \n\t" \ + "adcs r10, r10, r7 \n\t" \ + "stmia r0!, {r9,r10} \n\t" \ + \ + "umull r9, r10, r14, r14 \n\t" \ + "adcs r9, r9, r6 \n\t" \ + "adcs r10, r10, r8 \n\t" \ + "stmia r0!, {r9,r10} \n\t" \ + "pop {r1, r2} \n\t" + +#define FAST_SQUARE_ASM_6_TO_7 \ + "cmp r2, #6 \n\t" \ + "beq 1f \n\t" \ + \ + "sub r0, #24 \n\t" \ + "sub r1, #24 \n\t" \ + \ + /* Do off-center multiplication */ \ + "ldmia r1!, {r5,r6,r7,r8,r9,r10,r14} \n\t" \ + "umull r3, r4, r5, r14 \n\t" \ + "mov r5, #0 \n\t" \ + "umaal r4, r5, r6, r14 \n\t" \ + "mov r6, #0 \n\t" \ + "umaal r5, r6, r7, r14 \n\t" \ + "mov r7, #0 \n\t" \ + "umaal r6, r7, r8, r14 \n\t" \ + "mov r8, #0 \n\t" \ + "umaal r7, r8, r9, r14 \n\t" \ + "mov r9, #0 \n\t" \ + "umaal r8, r9, r10, r14 \n\t" \ + \ + /* Multiply by 2 */ \ + "mov r10, #0 \n\t" \ + "adds r3, r3, r3 \n\t" \ + "adcs r4, r4, r4 \n\t" \ + "adcs r5, r5, r5 \n\t" \ + "adcs r6, r6, r6 \n\t" \ + "adcs r7, r7, r7 \n\t" \ + "adcs r8, r8, r8 \n\t" \ + "adcs r9, r9, r9 \n\t" \ + "adcs r10, r10, #0 \n\t" \ + \ + /* Add into previous */ \ + "ldr r12, [r0], #4 \n\t" \ + "adds r3, r3, r12 \n\t" \ + "ldr r12, [r0], #4 \n\t" \ + "adcs r4, r4, r12 \n\t" \ + "ldr r12, [r0], #4 \n\t" \ + "adcs r5, r5, r12 \n\t" \ + "ldr r12, [r0], #4 \n\t" \ + "adcs r6, r6, r12 \n\t" \ + "ldr r12, [r0], #4 \n\t" \ + "adcs r7, r7, r12 \n\t" \ + "ldr r12, [r0], #4 \n\t" \ + "adcs r8, r8, r12 \n\t" \ + "adcs r9, r9, #0 \n\t" \ + "adcs r10, r10, #0 \n\t" \ + "sub r0, #24 \n\t" \ + \ + /* Perform center multiplication */ \ + "umlal r9, r10, r14, r14 \n\t" \ + "stmia r0!, {r3,r4,r5,r6,r7,r8,r9,r10} \n\t" + +#define FAST_SQUARE_ASM_7 \ + "ldmia r1!, {r9,r10,r11,r12} \n\t" \ + "push {r2} \n\t" \ + \ + "umull r14, r2, r10, r9 \n\t" \ + "mov r3, #0 \n\t" \ + "umaal r2, r3, r11, r9 \n\t" \ + "mov r4, #0 \n\t" \ + "umaal r3, r4, r12, r9 \n\t" \ + \ + "mov r5, #0 \n\t" \ + "umaal r5, r3, r11, r10 \n\t" \ + "adds r14, r14, r14 \n\t" \ + "adcs r2, r2, r2 \n\t" \ + "adcs r5, r5, r5 \n\t" \ + /* Store carry in r7 */ \ + "mov r7, #0 \n\t" \ + "adc r7, r7, #0 \n\t" \ + \ + "umull r6, r8, r9, r9 \n\t" \ + "adds r8, r8, r14 \n\t" \ + "stmia r0!, {r6,r8} \n\t" \ + \ + "umull r6, r8, r10, r10 \n\t" \ + "adcs r6, r6, r2 \n\t" \ + "adcs r8, r8, r5 \n\t" \ + "stmia r0!, {r6,r8} \n\t" \ + /* Store carry in r8 */ \ + "mov r8, #0 \n\t" \ + "adc r8, r8, #0 \n\t" \ + \ + "ldmia r1!, {r2, r6, r14} \n\t" \ + "push {r1} \n\t" \ + "umaal r3, r4, r2, r9 \n\t" \ + "mov r5, #0 \n\t" \ + "umaal r4, r5, r6, r9 \n\t" \ + "mov r1, #0 \n\t" \ + "umaal r5, r1, r14, r9 \n\t" \ + \ + "mov r9, #0 \n\t" \ + "umaal r3, r9, r12, r10 \n\t" \ + "umaal r9, r4, r2, r10 \n\t" \ + "umaal r4, r5, r6, r10 \n\t" \ + "umaal r5, r1, r14, r10 \n\t" \ + \ + "mov r10, #0 \n\t" \ + "umaal r10, r9, r12, r11 \n\t" \ + "umaal r9, r4, r2, r11 \n\t" \ + "umaal r4, r5, r6, r11 \n\t" \ + "umaal r5, r1, r14, r11 \n\t" \ + \ + /* Load carry from r7 */ \ + "lsrs r7, #1 \n\t" \ + "adcs r3, r3, r3 \n\t" \ + "adcs r10, r10, r10 \n\t" \ + "adcs r9, r9, r9 \n\t" \ + /* Store carry back in r7 */ \ + "adc r7, r7, #0 \n\t" \ + \ + /* Use carry from r8 */ \ + "umaal r3, r8, r11, r11 \n\t" \ + "adds r8, r8, r10 \n\t" \ + "stmia r0!, {r3,r8} \n\t" \ + /* Store carry back in r8 */ \ + "mov r8, #0 \n\t" \ + "adc r8, r8, #0 \n\t" \ + \ + "mov r3, #0 \n\t" \ + "umaal r3, r4, r2, r12 \n\t" \ + "umaal r4, r5, r6, r12 \n\t" \ + "umaal r5, r1, r14, r12 \n\t" \ + \ + "mov r10, #0 \n\t" \ + "umaal r10, r5, r6, r2 \n\t" \ + "umaal r5, r1, r14, r2 \n\t" \ + \ + "mov r11, #0 \n\t" \ + "umaal r11, r1, r14, r6 \n\t" \ + \ + /* Load carry from r7 */ \ + "lsrs r7, #1 \n\t" \ + "adcs r3, r3, r3 \n\t" \ + "adcs r4, r4, r4 \n\t" \ + "adcs r10, r10, r10 \n\t" \ + "adcs r5, r5, r5 \n\t" \ + "adcs r11, r11, r11 \n\t" \ + "adcs r1, r1, r1 \n\t" \ + "adc r7, r7, #0 \n\t" \ + \ + /* Use carry from r8 */ \ + "umaal r8, r9, r12, r12 \n\t" \ + "adds r9, r9, r3 \n\t" \ + "stmia r0!, {r8,r9} \n\t" \ + \ + "umull r8, r9, r2, r2 \n\t" \ + "adcs r8, r8, r4 \n\t" \ + "adcs r9, r9, r10 \n\t" \ + "stmia r0!, {r8,r9} \n\t" \ + \ + "umull r8, r9, r6, r6 \n\t" \ + "adcs r8, r8, r5 \n\t" \ + "adcs r9, r9, r11 \n\t" \ + "stmia r0!, {r8,r9} \n\t" \ + \ + "umull r8, r9, r14, r14 \n\t" \ + "adcs r8, r8, r1 \n\t" \ + "adcs r9, r9, r7 \n\t" \ + "stmia r0!, {r8,r9} \n\t" \ + "pop {r1, r2} \n\t" + +#define FAST_SQUARE_ASM_7_TO_8 \ + "cmp r2, #7 \n\t" \ + "beq 1f \n\t" \ + \ + "sub r0, #28 \n\t" \ + "sub r1, #28 \n\t" \ + \ + /* Do off-center multiplication */ \ + "ldmia r1!, {r5,r6,r7,r8,r9,r10,r11,r14} \n\t" \ + "umull r3, r4, r5, r14 \n\t" \ + "mov r5, #0 \n\t" \ + "umaal r4, r5, r6, r14 \n\t" \ + "mov r6, #0 \n\t" \ + "umaal r5, r6, r7, r14 \n\t" \ + "mov r7, #0 \n\t" \ + "umaal r6, r7, r8, r14 \n\t" \ + "mov r8, #0 \n\t" \ + "umaal r7, r8, r9, r14 \n\t" \ + "mov r9, #0 \n\t" \ + "umaal r8, r9, r10, r14 \n\t" \ + "mov r10, #0 \n\t" \ + "umaal r9, r10, r11, r14 \n\t" \ + \ + /* Multiply by 2 */ \ + "mov r11, #0 \n\t" \ + "adds r3, r3, r3 \n\t" \ + "adcs r4, r4, r4 \n\t" \ + "adcs r5, r5, r5 \n\t" \ + "adcs r6, r6, r6 \n\t" \ + "adcs r7, r7, r7 \n\t" \ + "adcs r8, r8, r8 \n\t" \ + "adcs r9, r9, r9 \n\t" \ + "adcs r10, r10, r10 \n\t" \ + "adcs r11, r11, #0 \n\t" \ + \ + /* Add into previous */ \ + "ldr r12, [r0], #4 \n\t" \ + "adds r3, r3, r12 \n\t" \ + "ldr r12, [r0], #4 \n\t" \ + "adcs r4, r4, r12 \n\t" \ + "ldr r12, [r0], #4 \n\t" \ + "adcs r5, r5, r12 \n\t" \ + "ldr r12, [r0], #4 \n\t" \ + "adcs r6, r6, r12 \n\t" \ + "ldr r12, [r0], #4 \n\t" \ + "adcs r7, r7, r12 \n\t" \ + "ldr r12, [r0], #4 \n\t" \ + "adcs r8, r8, r12 \n\t" \ + "ldr r12, [r0], #4 \n\t" \ + "adcs r9, r9, r12 \n\t" \ + "adcs r10, r10, #0 \n\t" \ + "adcs r11, r11, #0 \n\t" \ + "sub r0, #28 \n\t" \ + \ + /* Perform center multiplication */ \ + "umlal r10, r11, r14, r14 \n\t" \ + "stmia r0!, {r3,r4,r5,r6,r7,r8,r9,r10,r11} \n\t" + +#define FAST_SQUARE_ASM_8 \ + "ldmia r1!, {r10,r11,r12,r14} \n\t" \ + "push {r2} \n\t" \ + \ + "umull r2, r3, r11, r10 \n\t" \ + "mov r4, #0 \n\t" \ + "umaal r3, r4, r12, r10 \n\t" \ + "mov r5, #0 \n\t" \ + "umaal r4, r5, r14, r10 \n\t" \ + \ + "mov r6, #0 \n\t" \ + "umaal r6, r4, r12, r11 \n\t" \ + "adds r2, r2, r2 \n\t" \ + "adcs r3, r3, r3 \n\t" \ + "adcs r6, r6, r6 \n\t" \ + /* Store carry in r7 */ \ + "mov r7, #0 \n\t" \ + "adc r7, r7, #0 \n\t" \ + \ + "umull r8, r9, r10, r10 \n\t" \ + "adds r9, r9, r2 \n\t" \ + "stmia r0!, {r8,r9} \n\t" \ + \ + "umull r8, r9, r11, r11 \n\t" \ + "adcs r8, r8, r3 \n\t" \ + "adcs r9, r9, r6 \n\t" \ + "stmia r0!, {r8,r9} \n\t" \ + /* Store carry in r8 */ \ + "mov r8, #0 \n\t" \ + "adc r8, r8, #0 \n\t" \ + \ + "ldmia r1!, {r2, r3} \n\t" \ + "push {r1} \n\t" \ + "umaal r4, r5, r2, r10 \n\t" \ + "mov r6, #0 \n\t" \ + "umaal r5, r6, r3, r10 \n\t" \ + \ + "mov r9, #0 \n\t" \ + "umaal r9, r4, r14, r11 \n\t" \ + "umaal r4, r5, r2, r11 \n\t" \ + \ + "mov r1, #0 \n\t" \ + "umaal r1, r4, r14, r12 \n\t" \ + \ + /* Load carry from r7 */ \ + "lsrs r7, #1 \n\t" \ + "adcs r9, r9, r9 \n\t" \ + "adcs r1, r1, r1 \n\t" \ + /* Store carry back in r7 */ \ + "adc r7, r7, #0 \n\t" \ + \ + /* Use carry from r8 */ \ + "umaal r8, r9, r12, r12 \n\t" \ + "adds r9, r9, r1 \n\t" \ + "stmia r0!, {r8,r9} \n\t" \ + /* Store carry back in r8 */ \ + "mov r8, #0 \n\t" \ + "adc r8, r8, #0 \n\t" \ + \ + "pop {r1} \n\t" \ + /* TODO could fix up r1 value on stack here */ \ + /* and leave the value on the stack (rather */ \ + /* than popping) if supporting curves > 256 bits */ \ + "ldr r9, [r1], #4 \n\t" \ + "ldr r1, [r1] \n\t" \ + \ + "push {r7} \n\t" \ + "umaal r5, r6, r9, r10 \n\t" \ + "mov r7, #0 \n\t" \ + "umaal r6, r7, r1, r10 \n\t" \ + /* Carry now stored in r10 */ \ + "pop {r10} \n\t" \ + \ + "umaal r4, r5, r3, r11 \n\t" \ + "umaal r5, r6, r9, r11 \n\t" \ + "umaal r6, r7, r1, r11 \n\t" \ + \ + "mov r11, #0 \n\t" \ + "umaal r11, r4, r2, r12 \n\t" \ + "umaal r4, r5, r3, r12 \n\t" \ + "umaal r5, r6, r9, r12 \n\t" \ + "umaal r6, r7, r1, r12 \n\t" \ + \ + "mov r12, #0 \n\t" \ + "umaal r12, r4, r2, r14 \n\t" \ + "umaal r4, r5, r3, r14 \n\t" \ + "umaal r5, r6, r9, r14 \n\t" \ + "umaal r6, r7, r1, r14 \n\t" \ + \ + /* Load carry from r10 */ \ + "lsrs r10, #1 \n\t" \ + "adcs r11, r11, r11 \n\t" \ + "adcs r12, r12, r12 \n\t" \ + "adc r10, r10, #0 \n\t" \ + \ + /* Use carry from r8 */ \ + "umaal r8, r11, r14, r14 \n\t" \ + "adds r11, r11, r12 \n\t" \ + "stmia r0!, {r8,r11} \n\t" \ + /* Store carry back in r8 */ \ + "mov r8, #0 \n\t" \ + "adc r8, r8, #0 \n\t" \ + \ + "mov r11, #0 \n\t" \ + "umaal r11, r5, r3, r2 \n\t" \ + "umaal r5, r6, r9, r2 \n\t" \ + "umaal r6, r7, r1, r2 \n\t" \ + \ + "mov r12, #0 \n\t" \ + "umaal r12, r6, r9, r3 \n\t" \ + "umaal r6, r7, r1, r3 \n\t" \ + \ + "mov r14, #0 \n\t" \ + "umaal r14, r7, r1, r9 \n\t" \ + \ + /* Load carry from r10 */ \ + "lsrs r10, #1 \n\t" \ + "adcs r4, r4, r4 \n\t" \ + "adcs r11, r11, r11 \n\t" \ + "adcs r5, r5, r5 \n\t" \ + "adcs r12, r12, r12 \n\t" \ + "adcs r6, r6, r6 \n\t" \ + "adcs r14, r14, r14 \n\t" \ + "adcs r7, r7, r7 \n\t" \ + "adc r10, r10, #0 \n\t" \ + \ + /* Use carry from r8 */ \ + "umaal r4, r8, r2, r2 \n\t" \ + "adds r8, r8, r11 \n\t" \ + "stmia r0!, {r4,r8} \n\t" \ + \ + "umull r4, r8, r3, r3 \n\t" \ + "adcs r4, r4, r5 \n\t" \ + "adcs r8, r8, r12 \n\t" \ + "stmia r0!, {r4,r8} \n\t" \ + \ + "umull r4, r8, r9, r9 \n\t" \ + "adcs r4, r4, r6 \n\t" \ + "adcs r8, r8, r14 \n\t" \ + "stmia r0!, {r4,r8} \n\t" \ + \ + "umull r4, r8, r1, r1 \n\t" \ + "adcs r4, r4, r7 \n\t" \ + "adcs r8, r8, r10 \n\t" \ + "stmia r0!, {r4,r8} \n\t" \ + /* TODO pop {r1, r2} if supporting curves > 256 bits */ \ + "pop {r2} \n\t" + +#endif /* _UECC_ASM_ARM_MULT_SQUARE_H_ */ diff --git a/web/server/h2o/libh2o/deps/picotls/deps/micro-ecc/asm_avr.inc b/web/server/h2o/libh2o/deps/picotls/deps/micro-ecc/asm_avr.inc new file mode 100644 index 00000000..c9880403 --- /dev/null +++ b/web/server/h2o/libh2o/deps/picotls/deps/micro-ecc/asm_avr.inc @@ -0,0 +1,1089 @@ +/* Copyright 2015, Kenneth MacKay. Licensed under the BSD 2-clause license. */ + +#ifndef _UECC_ASM_AVR_H_ +#define _UECC_ASM_AVR_H_ + +#if (uECC_SUPPORTS_secp256r1 || uECC_SUPPORTS_secp256k1) + #define uECC_MIN_WORDS 32 +#endif +#if uECC_SUPPORTS_secp224r1 + #undef uECC_MIN_WORDS + #define uECC_MIN_WORDS 28 +#endif +#if uECC_SUPPORTS_secp192r1 + #undef uECC_MIN_WORDS + #define uECC_MIN_WORDS 24 +#endif +#if uECC_SUPPORTS_secp160r1 + #undef uECC_MIN_WORDS + #define uECC_MIN_WORDS 20 +#endif + +#if __AVR_HAVE_EIJMP_EICALL__ + #define IJMP "eijmp \n\t" +#else + #define IJMP "ijmp \n\t" +#endif + +#if (uECC_OPTIMIZATION_LEVEL >= 2) + +uECC_VLI_API void uECC_vli_clear(uECC_word_t *vli, wordcount_t num_words) { + volatile uECC_word_t *v = vli; + __asm__ volatile ( + #if (uECC_MAX_WORDS != uECC_MIN_WORDS) + "ldi r30, pm_lo8(1f) \n\t" + "ldi r31, pm_hi8(1f) \n\t" + "sub r30, %[num] \n\t" + "sbc r31, __zero_reg__ \n\t" + IJMP + #endif + + REPEAT(uECC_MAX_WORDS, "st x+, __zero_reg__ \n\t") + "1: \n\t" + : "+x" (v) + : [num] "r" (num_words) + : + #if (uECC_MAX_WORDS != uECC_MIN_WORDS) + "r30", "r31", "cc" + #endif + ); +} +#define asm_clear 1 + +uECC_VLI_API void uECC_vli_set(uECC_word_t *dest, const uECC_word_t *src, wordcount_t num_words) { + volatile uECC_word_t *d = dest; + __asm__ volatile ( + #if (uECC_MAX_WORDS != uECC_MIN_WORDS) + "ldi r30, pm_lo8(1f) \n\t" + "ldi r31, pm_hi8(1f) \n\t" + "sub r30, %[num] \n\t" + "sbc r31, __zero_reg__ \n\t" + IJMP + #endif + + REPEAT(uECC_MAX_WORDS, + "ld r0, y+ \n\t" + "st x+, r0 \n\t") + "1: \n\t" + : "+x" (d), "+y" (src) + : [num] "r" ((uint8_t)(num_words * 2)) + : "r0", + #if (uECC_MAX_WORDS != uECC_MIN_WORDS) + "r30", "r31", "cc" + #endif + ); +} +#define asm_set 1 + +uECC_VLI_API void uECC_vli_rshift1(uECC_word_t *vli, wordcount_t num_words) { + volatile uECC_word_t *v = vli; + __asm__ volatile ( + #if (uECC_MAX_WORDS != uECC_MIN_WORDS) + "ldi r30, pm_lo8(1f) \n\t" + "ldi r31, pm_hi8(1f) \n\t" + "sub r30, %[jump] \n\t" + "sbc r31, __zero_reg__ \n\t" + #endif + + "add r26, %[num] \n\t" + "adc r27, __zero_reg__ \n\t" + "ld r0, -x \n\t" + "lsr r0 \n\t" + "st x, r0 \n\t" + #if (uECC_MAX_WORDS != uECC_MIN_WORDS) + IJMP + #endif + + REPEAT(DEC(uECC_MAX_WORDS), + "ld r0, -x \n\t" + "ror r0 \n\t" + "st x, r0 \n\t") + "1: \n\t" + : "+x" (v) + #if (uECC_MAX_WORDS != uECC_MIN_WORDS) + : [num] "r" (num_words), [jump] "r" ((uint8_t)(3 * (num_words - 1))) + : "r0", "r30", "r31", "cc" + #else + : [num] "r" (num_words) + : "r0", "cc" + #endif + ); +} +#define asm_rshift1 1 + +#define ADD_RJPM_TABLE(N) \ + "movw r30, %A[result] \n\t" \ + "rjmp add_%=_" #N " \n\t" + +#define ADD_RJPM_DEST(N) \ + "add_%=_" #N ":" \ + "ld %[clb], x+ \n\t" \ + "ld %[rb], y+ \n\t" \ + "adc %[clb], %[rb] \n\t" \ + "st z+, %[clb] \n\t" + +uECC_VLI_API uECC_word_t uECC_vli_add(uECC_word_t *result, + const uECC_word_t *left, + const uECC_word_t *right, + wordcount_t num_words) { + volatile uECC_word_t *r = result; + uint8_t carry; + uint8_t right_byte; + + __asm__ volatile ( + #if (uECC_MAX_WORDS != uECC_MIN_WORDS) + "ldi r30, pm_lo8(add_%=_" STR(uECC_MAX_WORDS) ") \n\t" + "ldi r31, pm_hi8(add_%=_" STR(uECC_MAX_WORDS) ") \n\t" + "sub r30, %[num] \n\t" + "sbc r31, __zero_reg__ \n\t" + #endif + + "clc \n\t" + #if (uECC_MAX_WORDS != uECC_MIN_WORDS) + IJMP + REPEATM(uECC_MAX_WORDS, ADD_RJPM_TABLE) + #endif + + REPEATM(uECC_MAX_WORDS, ADD_RJPM_DEST) + + "mov %[clb], __zero_reg__ \n\t" + "adc %[clb], %[clb] \n\t" /* Store carry bit. */ + + : "+x" (left), "+y" (right), + [clb] "=&r" (carry), [rb] "=&r" (right_byte) + : [result] "r" (r), [num] "r" ((uint8_t)(num_words * 2)) + : "r30", "r31", "cc" + ); + return carry; +} +#define asm_add 1 + +#define SUB_RJPM_TABLE(N) \ + "movw r30, %A[result] \n\t" \ + "rjmp sub_%=_" #N " \n\t" + +#define SUB_RJPM_DEST(N) \ + "sub_%=_" #N ":" \ + "ld %[clb], x+ \n\t" \ + "ld %[rb], y+ \n\t" \ + "sbc %[clb], %[rb] \n\t" \ + "st z+, %[clb] \n\t" + +uECC_VLI_API uECC_word_t uECC_vli_sub(uECC_word_t *result, + const uECC_word_t *left, + const uECC_word_t *right, + wordcount_t num_words) { + volatile uECC_word_t *r = result; + uint8_t carry; + uint8_t right_byte; + + __asm__ volatile ( + #if (uECC_MAX_WORDS != uECC_MIN_WORDS) + "ldi r30, pm_lo8(sub_%=_" STR(uECC_MAX_WORDS) ") \n\t" + "ldi r31, pm_hi8(sub_%=_" STR(uECC_MAX_WORDS) ") \n\t" + "sub r30, %[num] \n\t" + "sbc r31, __zero_reg__ \n\t" + #endif + + "clc \n\t" + #if (uECC_MAX_WORDS != uECC_MIN_WORDS) + IJMP + REPEATM(uECC_MAX_WORDS, SUB_RJPM_TABLE) + #endif + + REPEATM(uECC_MAX_WORDS, SUB_RJPM_DEST) + + "mov %[clb], __zero_reg__ \n\t" + "adc %[clb], %[clb] \n\t" /* Store carry bit. */ + + : "+x" (left), "+y" (right), + [clb] "=&r" (carry), [rb] "=&r" (right_byte) + : [result] "r" (r), [num] "r" ((uint8_t)(num_words * 2)) + : "r30", "r31", "cc" + ); + return carry; +} +#define asm_sub 1 + +#if (uECC_OPTIMIZATION_LEVEL >= 3) + +#include "asm_avr_mult_square.inc" + +__attribute((noinline)) +uECC_VLI_API void uECC_vli_mult(uECC_word_t *result, + const uECC_word_t *left, + const uECC_word_t *right, + wordcount_t num_words) { + /* num_words should already be in r18. */ + register wordcount_t r18 __asm__("r18") = num_words; + + __asm__ volatile ( + "push r18 \n\t" +#if (uECC_MIN_WORDS == 20) + FAST_MULT_ASM_20 + "pop r18 \n\t" + #if (uECC_MAX_WORDS > 20) + FAST_MULT_ASM_20_TO_24 + #endif + #if (uECC_MAX_WORDS > 24) + FAST_MULT_ASM_24_TO_28 + #endif + #if (uECC_MAX_WORDS > 28) + FAST_MULT_ASM_28_TO_32 + #endif +#elif (uECC_MIN_WORDS == 24) + FAST_MULT_ASM_24 + "pop r18 \n\t" + #if (uECC_MAX_WORDS > 24) + FAST_MULT_ASM_24_TO_28 + #endif + #if (uECC_MAX_WORDS > 28) + FAST_MULT_ASM_28_TO_32 + #endif +#elif (uECC_MIN_WORDS == 28) + FAST_MULT_ASM_28 + "pop r18 \n\t" + #if (uECC_MAX_WORDS > 28) + FAST_MULT_ASM_28_TO_32 + #endif +#elif (uECC_MIN_WORDS == 32) + FAST_MULT_ASM_32 + "pop r18 \n\t" +#endif + "2: \n\t" + "eor r1, r1 \n\t" + : "+x" (left), "+y" (right), "+z" (result) + : "r" (r18) + : "r0", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", + "r11", "r12", "r13", "r14", "r15", "r16", "r17", "r19", "r20", + "r21", "r22", "r23", "r24", "r25", "cc" + ); +} +#define asm_mult 1 + +#if uECC_SQUARE_FUNC +__attribute((noinline)) +uECC_VLI_API void uECC_vli_square(uECC_word_t *result, + const uECC_word_t *left, + wordcount_t num_words) { + /* num_words should already be in r20. */ + register wordcount_t r20 __asm__("r20") = num_words; + + __asm__ volatile ( + "push r20 \n\t" +#if (uECC_MIN_WORDS == 20) + FAST_SQUARE_ASM_20 + "pop r20 \n\t" + #if (uECC_MAX_WORDS > 20) + FAST_SQUARE_ASM_20_TO_24 + #endif + #if (uECC_MAX_WORDS > 24) + FAST_SQUARE_ASM_24_TO_28 + #endif + #if (uECC_MAX_WORDS > 28) + FAST_SQUARE_ASM_28_TO_32 + #endif +#elif (uECC_MIN_WORDS == 24) + FAST_SQUARE_ASM_24 + "pop r20 \n\t" + #if (uECC_MAX_WORDS > 24) + FAST_SQUARE_ASM_24_TO_28 + #endif + #if (uECC_MAX_WORDS > 28) + FAST_SQUARE_ASM_28_TO_32 + #endif +#elif (uECC_MIN_WORDS == 28) + FAST_SQUARE_ASM_28 + "pop r20 \n\t" + #if (uECC_MAX_WORDS > 28) + FAST_SQUARE_ASM_28_TO_32 + #endif +#elif (uECC_MIN_WORDS == 32) + FAST_SQUARE_ASM_32 + "pop r20 \n\t" +#endif + "2: \n\t" + "eor r1, r1 \n\t" + : "+x" (left), "+z" (result) + : "r" (r20) + : "r0", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", + "r11", "r12", "r13", "r14", "r15", "r16", "r17", "r18", "r19", + "r21", "r22", "r23", "r24", "r25", "r28", "r29", "cc" + ); +} +#define asm_square 1 +#endif /* uECC_SQUARE_FUNC */ + +#endif /* (uECC_OPTIMIZATION_LEVEL >= 3) */ + +#if uECC_SUPPORTS_secp160r1 +static const struct uECC_Curve_t curve_secp160r1; +static void vli_mmod_fast_secp160r1(uECC_word_t *result, uECC_word_t *product) { + uint8_t carry = 0; + __asm__ volatile ( + "in r30, __SP_L__ \n\t" + "in r31, __SP_H__ \n\t" + "sbiw r30, 24 \n\t" + "in r0, __SREG__ \n\t" + "cli \n\t" + "out __SP_H__, r31 \n\t" + "out __SREG__, r0 \n\t" + "out __SP_L__, r30 \n\t" + + "adiw r30, 25 \n\t" /* we are shifting by 31 bits, so shift over 4 bytes + (+ 1 since z initially points below the stack) */ + "adiw r26, 40 \n\t" /* end of product */ + "ld r18, -x \n\t" /* Load word. */ + "lsr r18 \n\t" /* Shift. */ + "st -z, r18 \n\t" /* Store the first result word. */ + + /* Now we just do the remaining words with the carry bit (using ROR) */ + REPEAT(19, + "ld r18, -x \n\t" + "ror r18 \n\t" + "st -z, r18 \n\t") + + "eor r18, r18 \n\t" /* r18 = 0 */ + "ror r18 \n\t" /* get last bit */ + "st -z, r18 \n\t" /* store it */ + + "sbiw r30, 3 \n\t" /* move z back to point at tmp */ + /* now we add right */ + "ld r18, x+ \n\t" + "st z+, r18 \n\t" /* the first 3 bytes do not need to be added */ + "ld r18, x+ \n\t" + "st z+, r18 \n\t" + "ld r18, x+ \n\t" + "st z+, r18 \n\t" + + "ld r18, x+ \n\t" + "ld r19, z \n\t" + "add r18, r19 \n\t" + "st z+, r18 \n\t" + + /* Now we just do the remaining words with the carry bit (using ADC) */ + REPEAT(16, + "ld r18, x+ \n\t" + "ld r19, z \n\t" + "adc r18, r19 \n\t" + "st z+, r18 \n\t") + + /* Propagate over the remaining bytes of result */ + "ld r18, z \n\t" + "adc r18, r1 \n\t" + "st z+, r18 \n\t" + + "ld r18, z \n\t" + "adc r18, r1 \n\t" + "st z+, r18 \n\t" + + "ld r18, z \n\t" + "adc r18, r1 \n\t" + "st z+, r18 \n\t" + + "ld r18, z \n\t" + "adc r18, r1 \n\t" + "st z+, r18 \n\t" + + "sbiw r30, 24 \n\t" /* move z back to point at tmp */ + "sbiw r26, 40 \n\t" /* move x back to point at product */ + + /* add low bytes of tmp to product, storing in result */ + "ld r18, z+ \n\t" + "ld r19, x+ \n\t" + "add r18, r19 \n\t" + "st y+, r18 \n\t" + REPEAT(19, + "ld r18, z+ \n\t" + "ld r19, x+ \n\t" + "adc r18, r19 \n\t" + "st y+, r18 \n\t") + "adc %[carry], __zero_reg__ \n\t" /* Store carry bit (carry flag is cleared). */ + /* at this point x is at the end of product, y is at the end of result, + z is 20 bytes into tmp */ + "sbiw r28, 20 \n\t" /* move y back to point at result */ + "adiw r30, 4 \n\t" /* move z to point to the end of tmp */ + + /* do omega_mult again with the 4 relevant bytes */ + /* z points to the end of tmp, x points to the end of product */ + "ld r18, -z \n\t" /* Load word. */ + "lsr r18 \n\t" /* Shift. */ + "st -x, r18 \n\t" /* Store the first result word. */ + + "ld r18, -z \n\t" + "ror r18 \n\t" + "st -x, r18 \n\t" + "ld r18, -z \n\t" + "ror r18 \n\t" + "st -x, r18 \n\t" + "ld r18, -z \n\t" + "ror r18 \n\t" + "st -x, r18 \n\t" + + "eor r18, r18 \n\t" /* r18 = 0 */ + "ror r18 \n\t" /* get last bit */ + "st -x, r18 \n\t" /* store it */ + + "sbiw r26, 3 \n\t" /* move x back to point at beginning */ + /* now we add a copy of the 4 bytes */ + "ld r18, z+ \n\t" + "st x+, r18 \n\t" /* the first 3 bytes do not need to be added */ + "ld r18, z+ \n\t" + "st x+, r18 \n\t" + "ld r18, z+ \n\t" + "st x+, r18 \n\t" + + "ld r18, z+ \n\t" + "ld r19, x \n\t" + "add r18, r19 \n\t" + "st x+, r18 \n\t" + + /* Propagate over the remaining bytes */ + "ld r18, x \n\t" + "adc r18, r1 \n\t" + "st x+, r18 \n\t" + + "ld r18, x \n\t" + "adc r18, r1 \n\t" + "st x+, r18 \n\t" + + "ld r18, x \n\t" + "adc r18, r1 \n\t" + "st x+, r18 \n\t" + + "ld r18, x \n\t" + "adc r18, r1 \n\t" + "st x+, r18 \n\t" + + /* now z points to the end of tmp, x points to the end of product + (y still points at result) */ + "sbiw r26, 8 \n\t" /* move x back to point at beginning of actual data */ + /* add into result */ + "ld r18, x+ \n\t" + "ld r19, y \n\t" + "add r18, r19 \n\t" + "st y+, r18 \n\t" + REPEAT(7, + "ld r18, x+ \n\t" + "ld r19, y \n\t" + "adc r18, r19 \n\t" + "st y+, r18 \n\t") + + /* Done adding, now propagate carry bit */ + REPEAT(12, + "ld r18, y \n\t" + "adc r18, __zero_reg__ \n\t" + "st y+, r18 \n\t") + + "adc %[carry], __zero_reg__ \n\t" /* Store carry bit (carry flag is cleared). */ + "sbiw r28, 20 \n\t" /* move y back to point at result */ + + "sbiw r30, 1 \n\t" /* fix stack pointer */ + "in r0, __SREG__ \n\t" + "cli \n\t" + "out __SP_H__, r31 \n\t" + "out __SREG__, r0 \n\t" + "out __SP_L__, r30 \n\t" + + : "+x" (product), [carry] "+r" (carry) + : "y" (result) + : "r0", "r18", "r19", "r30", "r31", "cc" + ); + + if (carry > 0) { + --carry; + uECC_vli_sub(result, result, curve_secp160r1.p, 20); + } + if (carry > 0) { + uECC_vli_sub(result, result, curve_secp160r1.p, 20); + } + if (uECC_vli_cmp_unsafe(result, curve_secp160r1.p, 20) > 0) { + uECC_vli_sub(result, result, curve_secp160r1.p, 20); + } +} +#define asm_mmod_fast_secp160r1 1 +#endif /* uECC_SUPPORTS_secp160r1 */ + +#if uECC_SUPPORTS_secp256k1 +static const struct uECC_Curve_t curve_secp256k1; +static void vli_mmod_fast_secp256k1(uECC_word_t *result, uECC_word_t *product) { + uint8_t carry = 0; + __asm__ volatile ( + "in r30, __SP_L__ \n\t" + "in r31, __SP_H__ \n\t" + "sbiw r30, 37 \n\t" + "in r0, __SREG__ \n\t" + "cli \n\t" + "out __SP_H__, r31 \n\t" + "out __SREG__, r0 \n\t" + "out __SP_L__, r30 \n\t" + + "adiw r30, 1 \n\t" /* add 1 since z initially points below the stack */ + "adiw r26, 32 \n\t" /* product + uECC_WORDS */ + "ldi r25, 0x03 \n\t" + "ldi r24, 0xD1 \n\t" + "ld r18, x+ \n\t" + "ld r19, x+ \n\t" + "ld r20, x+ \n\t" + "ld r21, x+ \n\t" + + "mul r24, r18 \n\t" + "st z+, r0 \n\t" + "mov r22, r1 \n\t" + "ldi r23, 0 \n\t" + + "mul r24, r19 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" /* can't overflow */ + "mul r25, r18 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" /* can't overflow */ + "st z+, r22 \n\t" + "ldi r22, 0 \n\t" + + "mul r24, r20 \n\t" + "add r23, r0 \n\t" + "adc r22, r1 \n\t" + "mul r25, r19 \n\t" + "add r23, r0 \n\t" + "adc r22, r1 \n\t" + "st z+, r23 \n\t" + "ldi r23, 0 \n\t" + + "mul r24, r21 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "mul r25, r20 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "st z+, r22 \n\t" + "ldi r22, 0 \n\t" + + /* now we start adding the 2^32 part as well */ + "add r23, r18 \n\t" // 28 + "adc r22, r22 \n\t" + "ld r18, x+ \n\t" + "mul r24, r18 \n\t" + "add r23, r0 \n\t" + "adc r22, r1 \n\t" + "mul r25, r21 \n\t" + "add r23, r0 \n\t" + "adc r22, r1 \n\t" + "st z+, r23 \n\t" + "ldi r23, 0 \n\t" + + "add r22, r19 \n\t" // 27 + "adc r23, r23 \n\t" + "ld r19, x+ \n\t" + "mul r24, r19 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "mul r25, r18 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "st z+, r22 \n\t" + "ldi r22, 0 \n\t" + + REPEAT(6, // 26 - 3 + "add r23, r20 \n\t" + "adc r22, r22 \n\t" + "ld r20, x+ \n\t" + "mul r24, r20 \n\t" + "add r23, r0 \n\t" + "adc r22, r1 \n\t" + "mul r25, r19 \n\t" + "add r23, r0 \n\t" + "adc r22, r1 \n\t" + "st z+, r23 \n\t" + "ldi r23, 0 \n\t" + + "add r22, r21 \n\t" + "adc r23, r23 \n\t" + "ld r21, x+ \n\t" + "mul r24, r21 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "mul r25, r20 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "st z+, r22 \n\t" + "ldi r22, 0 \n\t" + + "add r23, r18 \n\t" + "adc r22, r22 \n\t" + "ld r18, x+ \n\t" + "mul r24, r18 \n\t" + "add r23, r0 \n\t" + "adc r22, r1 \n\t" + "mul r25, r21 \n\t" + "add r23, r0 \n\t" + "adc r22, r1 \n\t" + "st z+, r23 \n\t" + "ldi r23, 0 \n\t" + + "add r22, r19 \n\t" + "adc r23, r23 \n\t" + "ld r19, x+ \n\t" + "mul r24, r19 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "mul r25, r18 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "st z+, r22 \n\t" + "ldi r22, 0 \n\t") + + "add r23, r20 \n\t" // 2 + "adc r22, r22 \n\t" + "ld r20, x+ \n\t" + "mul r24, r20 \n\t" + "add r23, r0 \n\t" + "adc r22, r1 \n\t" + "mul r25, r19 \n\t" + "add r23, r0 \n\t" + "adc r22, r1 \n\t" + "st z+, r23 \n\t" + "ldi r23, 0 \n\t" + + "add r22, r21 \n\t" // 1 + "adc r23, r23 \n\t" + "ld r21, x+ \n\t" + "mul r24, r21 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "mul r25, r20 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "st z+, r22 \n\t" + "ldi r22, 0 \n\t" + + /* Now finish the carries etc */ + "add r23, r18 \n\t" + "adc r22, r22 \n\t" + "mul r25, r21 \n\t" + "add r23, r0 \n\t" + "adc r22, r1 \n\t" + "st z+, r23 \n\t" + "ldi r23, 0 \n\t" + + "add r22, r19 \n\t" + "adc r23, r23 \n\t" + "st z+, r22 \n\t" + "ldi r22, 0 \n\t" + + "add r23, r20 \n\t" + "adc r22, r22 \n\t" + "st z+, r23 \n\t" + "ldi r23, 0 \n\t" + + "add r22, r21 \n\t" + "adc r23, r23 \n\t" + "st z+, r22 \n\t" + "st z+, r23 \n\t" + "eor r1, r1 \n\t" /* make r1 be 0 again */ + + "sbiw r30, 37 \n\t" /* move z back to point at tmp */ + "subi r26, 64 \n\t" /* move x back to point at product */ + "sbc r27, __zero_reg__ \n\t" + + /* add low bytes of tmp to product, storing in result */ + "ld r18, z+ \n\t" + "ld r19, x+ \n\t" + "add r18, r19 \n\t" + "st y+, r18 \n\t" + REPEAT(31, + "ld r18, z+ \n\t" + "ld r19, x+ \n\t" + "adc r18, r19 \n\t" + "st y+, r18 \n\t") + + "adc %[carry], __zero_reg__ \n\t" /* Store carry bit (carry flag is cleared). */ + /* at this point x is at the end of product, y is at the end of result, + z is 32 bytes into tmp */ + "sbiw r28, 32 \n\t" /* move y back to point at result */ + + /* do omega_mult again with the 5 relevant bytes */ + /* z points to tmp + uECC_WORDS, x points to the end of product */ + "sbiw r26, 32 \n\t" /* shift x back to point into the product buffer + (we can overwrite it now) */ + "ld r18, z+ \n\t" + "ld r19, z+ \n\t" + "ld r20, z+ \n\t" + "ld r21, z+ \n\t" + + "mul r24, r18 \n\t" + "st x+, r0 \n\t" + "mov r22, r1 \n\t" + "ldi r23, 0 \n\t" + + "mul r24, r19 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" /* can't overflow */ + "mul r25, r18 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" /* can't overflow */ + "st x+, r22 \n\t" + "ldi r22, 0 \n\t" + + "mul r24, r20 \n\t" + "add r23, r0 \n\t" + "adc r22, r1 \n\t" + "mul r25, r19 \n\t" + "add r23, r0 \n\t" + "adc r22, r1 \n\t" + "st x+, r23 \n\t" + "ldi r23, 0 \n\t" + + "mul r24, r21 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "mul r25, r20 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "st x+, r22 \n\t" + "ldi r22, 0 \n\t" + + "add r23, r18 \n\t" + "adc r22, r22 \n\t" + "ld r18, z+ \n\t" + "mul r24, r18 \n\t" + "add r23, r0 \n\t" + "adc r22, r1 \n\t" + "mul r25, r21 \n\t" + "add r23, r0 \n\t" + "adc r22, r1 \n\t" + "st x+, r23 \n\t" + "ldi r23, 0 \n\t" + + /* Now finish the carries etc */ + "add r22, r19 \n\t" + "adc r23, r23 \n\t" + "mul r25, r18 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "st x+, r22 \n\t" + "ldi r22, 0 \n\t" + + "add r23, r20 \n\t" + "adc r22, r22 \n\t" + "st x+, r23 \n\t" + "ldi r23, 0 \n\t" + + "add r22, r21 \n\t" + "adc r23, r23 \n\t" + "st x+, r22 \n\t" + "ldi r22, 0 \n\t" + + "add r23, r18 \n\t" + "adc r22, r22 \n\t" + "st x+, r23 \n\t" + "st x+, r22 \n\t" + "eor r1, r1 \n\t" /* make r1 be 0 again */ + + /* now z points to the end of tmp, x points to the end of product + (y still points at result) */ + "sbiw r26, 10 \n\t" /* move x back to point at beginning of actual data */ + /* add into result */ + "ld r18, x+ \n\t" + "ld r19, y \n\t" + "add r18, r19 \n\t" + "st y+, r18 \n\t" + REPEAT(9, + "ld r18, x+ \n\t" + "ld r19, y \n\t" + "adc r18, r19 \n\t" + "st y+, r18 \n\t") + + /* Done adding, now propagate carry bit */ + REPEAT(22, + "ld r18, y \n\t" + "adc r18, __zero_reg__ \n\t" + "st y+, r18 \n\t") + + "adc %[carry], __zero_reg__ \n\t" /* Store carry bit (carry flag is cleared). */ + "sbiw r28, 32 \n\t" /* move y back to point at result */ + + "sbiw r30, 1 \n\t" /* fix stack pointer */ + "in r0, __SREG__ \n\t" + "cli \n\t" + "out __SP_H__, r31 \n\t" + "out __SREG__, r0 \n\t" + "out __SP_L__, r30 \n\t" + + : "+x" (product), [carry] "+r" (carry) + : "y" (result) + : "r0", "r18", "r19", "r20", "r21", "r22", "r23", "r24", "r25", "r30", "r31", "cc" + ); + + if (carry > 0) { + --carry; + uECC_vli_sub(result, result, curve_secp256k1.p, 32); + } + if (carry > 0) { + uECC_vli_sub(result, result, curve_secp256k1.p, 32); + } + if (uECC_vli_cmp_unsafe(result, curve_secp256k1.p, 32) > 0) { + uECC_vli_sub(result, result, curve_secp256k1.p, 32); + } +} +#define asm_mmod_fast_secp256k1 1 +#endif /* uECC_SUPPORTS_secp256k1 */ + +#endif /* (uECC_OPTIMIZATION_LEVEL >= 2) */ + +/* ---- "Small" implementations ---- */ + +#if !asm_add +uECC_VLI_API uECC_word_t uECC_vli_add(uECC_word_t *result, + const uECC_word_t *left, + const uECC_word_t *right, + wordcount_t num_words) { + volatile uECC_word_t *r = result; + uint8_t carry = 0; + uint8_t left_byte; + uint8_t right_byte; + + __asm__ volatile ( + "clc \n\t" + + "1: \n\t" + "ld %[left], x+ \n\t" /* Load left byte. */ + "ld %[right], y+ \n\t" /* Load right byte. */ + "adc %[left], %[right] \n\t" /* Add. */ + "st z+, %[left] \n\t" /* Store the result. */ + "dec %[i] \n\t" + "brne 1b \n\t" + + "adc %[carry], %[carry] \n\t" /* Store carry bit. */ + + : "+z" (r), "+x" (left), "+y" (right), [i] "+r" (num_words), + [carry] "+r" (carry), [left] "=&r" (left_byte), [right] "=&r" (right_byte) + : + : "cc" + ); + return carry; +} +#define asm_add 1 +#endif + +#if !asm_sub +uECC_VLI_API uECC_word_t uECC_vli_sub(uECC_word_t *result, + const uECC_word_t *left, + const uECC_word_t *right, + wordcount_t num_words) { + volatile uECC_word_t *r = result; + uint8_t borrow = 0; + uint8_t left_byte; + uint8_t right_byte; + + __asm__ volatile ( + "clc \n\t" + + "1: \n\t" + "ld %[left], x+ \n\t" /* Load left byte. */ + "ld %[right], y+ \n\t" /* Load right byte. */ + "sbc %[left], %[right] \n\t" /* Subtract. */ + "st z+, %[left] \n\t" /* Store the result. */ + "dec %[i] \n\t" + "brne 1b \n\t" + + "adc %[borrow], %[borrow] \n\t" /* Store carry bit in borrow. */ + + : "+z" (r), "+x" (left), "+y" (right), [i] "+r" (i), + [borrow] "+r" (borrow), [left] "=&r" (left_byte), [right] "=&r" (right_byte) + : + : "cc" + ); + return borrow; +} +#define asm_sub 1 +#endif + +#if !asm_mult +__attribute((noinline)) +uECC_VLI_API void uECC_vli_mult(uECC_word_t *result, + const uECC_word_t *left, + const uECC_word_t *right, + wordcount_t num_words) { + volatile uECC_word_t *r = result; + uint8_t r0 = 0; + uint8_t r1 = 0; + uint8_t r2 = 0; + uint8_t zero = 0; + uint8_t k, i; + + __asm__ volatile ( + "ldi %[k], 1 \n\t" /* k = 1; k < num_words; ++k */ + + "1: \n\t" + "ldi %[i], 0 \n\t" /* i = 0; i < k; ++i */ + + "add r28, %[k] \n\t" /* pre-add right ptr */ + "adc r29, %[zero] \n\t" + + "2: \n\t" + "ld r0, x+ \n\t" + "ld r1, -y \n\t" + "mul r0, r1 \n\t" + + "add %[r0], r0 \n\t" + "adc %[r1], r1 \n\t" + "adc %[r2], %[zero] \n\t" + + "inc %[i] \n\t" + "cp %[i], %[k] \n\t" + "brlo 2b \n\t" /* loop if i < k */ + + "sub r26, %[k] \n\t" /* fix up left ptr */ + "sbc r27, %[zero] \n\t" + + "st z+, %[r0] \n\t" /* Store the result. */ + "mov %[r0], %[r1] \n\t" + "mov %[r1], %[r2] \n\t" + "mov %[r2], %[zero] \n\t" + + "inc %[k] \n\t" + "cp %[k], %[num] \n\t" + "brlo 1b \n\t" /* loop if k < num_words */ + + /* second half */ + "mov %[k], %[num] \n\t" /* k = num_words; k > 0; --k */ + "add r28, %[num] \n\t" /* move right ptr to point at the end of right */ + "adc r29, %[zero] \n\t" + + "1: \n\t" + "ldi %[i], 0 \n\t" /* i = 0; i < k; ++i */ + + "2: \n\t" + "ld r0, x+ \n\t" + "ld r1, -y \n\t" + "mul r0, r1 \n\t" + + "add %[r0], r0 \n\t" + "adc %[r1], r1 \n\t" + "adc %[r2], %[zero] \n\t" + + "inc %[i] \n\t" + "cp %[i], %[k] \n\t" + "brlo 2b \n\t" /* loop if i < k */ + + "add r28, %[k] \n\t" /* fix up right ptr */ + "adc r29, %[zero] \n\t" + + "st z+, %[r0] \n\t" /* Store the result. */ + "mov %[r0], %[r1] \n\t" + "mov %[r1], %[r2] \n\t" + "mov %[r2], %[zero] \n\t" + + "dec %[k] \n\t" + "sub r26, %[k] \n\t" /* fix up left ptr (after k is decremented, so next time + we start 1 higher) */ + "sbc r27, %[zero] \n\t" + + "cp %[k], %[zero] \n\t" + "brne 1b \n\t" /* loop if k > 0 */ + + "st z+, %[r0] \n\t" /* Store last result byte. */ + "eor r1, r1 \n\t" /* fix r1 to be 0 again */ + + : "+z" (result), "+x" (left), "+y" (right), + [r0] "+r" (r0), [r1] "+r" (r1), [r2] "+r" (r2), + [zero] "+r" (zero), [num] "+r" (num_words), + [k] "=&r" (k), [i] "=&r" (i) + : + : "r0", "cc" + ); +} +#define asm_mult 1 +#endif + +#if (uECC_SQUARE_FUNC && !asm_square) +uECC_VLI_API void uECC_vli_square(uECC_word_t *result, + const uECC_word_t *left, + wordcount_t num_words) { + volatile uECC_word_t *r = result; + uint8_t r0 = 0; + uint8_t r1 = 0; + uint8_t r2 = 0; + uint8_t zero = 0; + uint8_t k; + + __asm__ volatile ( + "ldi %[k], 1 \n\t" /* k = 1; k < num_words * 2; ++k */ + + "1: \n\t" + + "movw r26, %[orig] \n\t" /* copy orig ptr to 'left' ptr */ + "movw r30, %[orig] \n\t" /* copy orig ptr to 'right' ptr */ + "cp %[k], %[num] \n\t" + "brlo 2f \n\t" + "breq 2f \n\t" + + /* when k > num_words, we start from (k - num_words) on the 'left' ptr */ + "add r26, %[k] \n\t" + "adc r27, %[zero] \n\t" + "sub r26, %[num] \n\t" + "sbc r27, %[zero] \n\t" + "add r30, %[num] \n\t" /* move right ptr to point at the end */ + "adc r31, %[zero] \n\t" + "rjmp 3f \n\t" + + "2: \n\t" /* when k <= num_words, we add k to the 'right' ptr */ + "add r30, %[k] \n\t" /* pre-add 'right' ptr */ + "adc r31, %[zero] \n\t" + + "3: \n\t" + "ld r0, x+ \n\t" + "cp r26, r30 \n\t" /* if left == right here, then we are done after this mult + (and we don't need to double) */ + "breq 4f \n\t" + "ld r1, -z \n\t" + "mul r0, r1 \n\t" + + /* add twice since it costs the same as doubling */ + "add %[r0], r0 \n\t" + "adc %[r1], r1 \n\t" + "adc %[r2], %[zero] \n\t" + "add %[r0], r0 \n\t" + "adc %[r1], r1 \n\t" + "adc %[r2], %[zero] \n\t" + + "cpse r26, r30 \n\t" /* if left == right here, then we are done */ + "rjmp 3b \n\t" + "rjmp 5f \n\t" /* skip code for non-doubled mult */ + + "4: \n\t" + "ld r1, -z \n\t" + "mul r0, r1 \n\t" + "add %[r0], r0 \n\t" + "adc %[r1], r1 \n\t" + "adc %[r2], %[zero] \n\t" + + "5: \n\t" + "movw r30, %[result] \n\t" /* make z point to result */ + "st z+, %[r0] \n\t" /* Store the result. */ + "movw %[result], r30 \n\t" /* update result ptr*/ + "mov %[r0], %[r1] \n\t" + "mov %[r1], %[r2] \n\t" + "mov %[r2], %[zero] \n\t" + + "inc %[k] \n\t" + "cp %[k], %[max] \n\t" + "brlo 1b \n\t" /* loop if k < num_words * 2 */ + + "movw r30, %[result] \n\t" /* make z point to result */ + "st z+, %[r0] \n\t" /* Store last result byte. */ + "eor r1, r1 \n\t" /* fix r1 to be 0 again */ + + : [result] "+r" (r), + [r0] "+r" (r0), [r1] "+r" (r1), [r2] "+r" (r2), [zero] "+r" (zero), + [k] "=&a" (k) + : [orig] "r" (left), [max] "r" ((uint8_t)(2 * num_words)), + [num] "r" (num_words) + : "r0", "r26", "r27", "r30", "r31", "cc" + ); +} +#define asm_square 1 +#endif /* uECC_SQUARE_FUNC && !asm_square */ + +#endif /* _UECC_ASM_AVR_H_ */ diff --git a/web/server/h2o/libh2o/deps/picotls/deps/micro-ecc/asm_avr_mult_square.inc b/web/server/h2o/libh2o/deps/picotls/deps/micro-ecc/asm_avr_mult_square.inc new file mode 100644 index 00000000..7ae08bce --- /dev/null +++ b/web/server/h2o/libh2o/deps/picotls/deps/micro-ecc/asm_avr_mult_square.inc @@ -0,0 +1,26311 @@ +/* Copyright 2015, Kenneth MacKay. Licensed under the BSD 2-clause license. */ + +#ifndef _UECC_ASM_AVR_MULT_SQUARE_H_ +#define _UECC_ASM_AVR_MULT_SQUARE_H_ + +#define FAST_MULT_ASM_20 \ + "adiw r30, 10 \n\t" \ + "adiw r28, 10 \n\t" \ + "ld r2, x+ \n\t" \ + "ld r3, x+ \n\t" \ + "ld r4, x+ \n\t" \ + "ld r5, x+ \n\t" \ + "ld r6, x+ \n\t" \ + "ld r7, x+ \n\t" \ + "ld r8, x+ \n\t" \ + "ld r9, x+ \n\t" \ + "ld r10, x+ \n\t" \ + "ld r11, x+ \n\t" \ + "ld r12, y+ \n\t" \ + "ld r13, y+ \n\t" \ + "ld r14, y+ \n\t" \ + "ld r15, y+ \n\t" \ + "ld r16, y+ \n\t" \ + "ld r17, y+ \n\t" \ + "ld r18, y+ \n\t" \ + "ld r19, y+ \n\t" \ + "ld r20, y+ \n\t" \ + "ld r21, y+ \n\t" \ + "ldi r25, 0 \n\t" \ + \ + "ldi r23, 0 \n\t" \ + "mul r2, r12 \n\t" \ + "st z+, r0 \n\t" \ + "mov r22, r1 \n\t" \ + \ + "ldi r24, 0 \n\t" \ + "mul r2, r13 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "mul r3, r12 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ldi r22, 0 \n\t" \ + "mul r2, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r3, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r4, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r23, 0 \n\t" \ + "mul r2, r15 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r3, r14 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r4, r13 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r5, r12 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "st z+, r24 \n\t" \ + \ + "ldi r24, 0 \n\t" \ + "mul r2, r16 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r3, r15 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r4, r14 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r5, r13 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r6, r12 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ldi r22, 0 \n\t" \ + "mul r2, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r3, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r4, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r5, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r6, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r7, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r23, 0 \n\t" \ + "mul r2, r18 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r3, r17 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r4, r16 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r5, r15 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r6, r14 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r7, r13 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r8, r12 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "st z+, r24 \n\t" \ + \ + "ldi r24, 0 \n\t" \ + "mul r2, r19 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r3, r18 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r4, r17 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r5, r16 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r6, r15 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r7, r14 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r8, r13 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r9, r12 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ldi r22, 0 \n\t" \ + "mul r2, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r3, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r4, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r5, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r6, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r7, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r8, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r9, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r10, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r23, 0 \n\t" \ + "mul r2, r21 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r3, r20 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r4, r19 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r5, r18 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r6, r17 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r7, r16 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r8, r15 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r9, r14 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r10, r13 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r11, r12 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "st z+, r24 \n\t" \ + \ + "ldi r24, 0 \n\t" \ + "mul r3, r21 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r4, r20 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r5, r19 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r6, r18 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r7, r17 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r8, r16 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r9, r15 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r10, r14 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r11, r13 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ldi r22, 0 \n\t" \ + "mul r4, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r5, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r6, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r7, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r8, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r9, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r10, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r11, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r23, 0 \n\t" \ + "mul r5, r21 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r6, r20 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r7, r19 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r8, r18 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r9, r17 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r10, r16 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r11, r15 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "st z+, r24 \n\t" \ + \ + "ldi r24, 0 \n\t" \ + "mul r6, r21 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r7, r20 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r8, r19 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r9, r18 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r10, r17 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r11, r16 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ldi r22, 0 \n\t" \ + "mul r7, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r8, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r9, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r10, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r11, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r23, 0 \n\t" \ + "mul r8, r21 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r9, r20 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r10, r19 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r11, r18 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "st z+, r24 \n\t" \ + \ + "ldi r24, 0 \n\t" \ + "mul r9, r21 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r10, r20 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r11, r19 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ldi r22, 0 \n\t" \ + "mul r10, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r11, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "mul r11, r21 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "st z+, r24 \n\t" \ + "st z+, r22 \n\t" \ + \ + "sbiw r30, 30 \n\t" \ + "sbiw r28, 20 \n\t" \ + "ld r12, y+ \n\t" \ + "ld r13, y+ \n\t" \ + "ld r14, y+ \n\t" \ + "ld r15, y+ \n\t" \ + "ld r16, y+ \n\t" \ + "ld r17, y+ \n\t" \ + "ld r18, y+ \n\t" \ + "ld r19, y+ \n\t" \ + "ld r20, y+ \n\t" \ + "ld r21, y+ \n\t" \ + \ + "ldi r23, 0 \n\t" \ + "mul r2, r12 \n\t" \ + "st z+, r0 \n\t" \ + "mov r22, r1 \n\t" \ + \ + "ldi r24, 0 \n\t" \ + "mul r2, r13 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "mul r3, r12 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ldi r22, 0 \n\t" \ + "mul r2, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r3, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r4, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r23, 0 \n\t" \ + "mul r2, r15 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r3, r14 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r4, r13 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r5, r12 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "st z+, r24 \n\t" \ + \ + "ldi r24, 0 \n\t" \ + "mul r2, r16 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r3, r15 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r4, r14 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r5, r13 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r6, r12 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ldi r22, 0 \n\t" \ + "mul r2, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r3, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r4, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r5, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r6, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r7, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r23, 0 \n\t" \ + "mul r2, r18 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r3, r17 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r4, r16 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r5, r15 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r6, r14 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r7, r13 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r8, r12 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "st z+, r24 \n\t" \ + \ + "ldi r24, 0 \n\t" \ + "mul r2, r19 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r3, r18 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r4, r17 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r5, r16 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r6, r15 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r7, r14 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r8, r13 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r9, r12 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ldi r22, 0 \n\t" \ + "mul r2, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r3, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r4, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r5, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r6, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r7, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r8, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r9, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r10, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r23, 0 \n\t" \ + "mul r2, r21 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r3, r20 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r4, r19 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r5, r18 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r6, r17 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r7, r16 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r8, r15 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r9, r14 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r10, r13 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r11, r12 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "st z+, r24 \n\t" \ + \ + "ld r2, x+ \n\t" \ + "ldi r24, 0 \n\t" \ + "mul r3, r21 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r4, r20 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r5, r19 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r6, r18 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r7, r17 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r8, r16 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r9, r15 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r10, r14 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r11, r13 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r2, r12 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r25 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ld r3, x+ \n\t" \ + "ldi r22, 0 \n\t" \ + "mul r4, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r5, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r6, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r7, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r8, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r9, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r10, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r11, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r2, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r3, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r25 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ld r4, x+ \n\t" \ + "ldi r23, 0 \n\t" \ + "mul r5, r21 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r6, r20 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r7, r19 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r8, r18 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r9, r17 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r10, r16 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r11, r15 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r2, r14 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r3, r13 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r4, r12 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r25 \n\t" \ + "adc r23, r25 \n\t" \ + "st z+, r24 \n\t" \ + \ + "ld r5, x+ \n\t" \ + "ldi r24, 0 \n\t" \ + "mul r6, r21 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r7, r20 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r8, r19 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r9, r18 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r10, r17 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r11, r16 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r2, r15 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r3, r14 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r4, r13 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r5, r12 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r25 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ld r6, x+ \n\t" \ + "ldi r22, 0 \n\t" \ + "mul r7, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r8, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r9, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r10, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r11, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r2, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r3, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r4, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r5, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r6, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r25 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ld r7, x+ \n\t" \ + "ldi r23, 0 \n\t" \ + "mul r8, r21 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r9, r20 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r10, r19 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r11, r18 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r2, r17 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r3, r16 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r4, r15 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r5, r14 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r6, r13 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r7, r12 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r25 \n\t" \ + "adc r23, r25 \n\t" \ + "st z+, r24 \n\t" \ + \ + "ld r8, x+ \n\t" \ + "ldi r24, 0 \n\t" \ + "mul r9, r21 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r10, r20 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r11, r19 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r2, r18 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r3, r17 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r4, r16 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r5, r15 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r6, r14 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r7, r13 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r8, r12 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r25 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ld r9, x+ \n\t" \ + "ldi r22, 0 \n\t" \ + "mul r10, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r11, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r2, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r3, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r4, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r5, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r6, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r7, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r8, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r9, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r25 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ld r10, x+ \n\t" \ + "ldi r23, 0 \n\t" \ + "mul r11, r21 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r2, r20 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r3, r19 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r4, r18 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r5, r17 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r6, r16 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r7, r15 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r8, r14 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r9, r13 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r10, r12 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r25 \n\t" \ + "adc r23, r25 \n\t" \ + "st z+, r24 \n\t" \ + \ + "ld r11, x+ \n\t" \ + "ldi r24, 0 \n\t" \ + "mul r2, r21 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r3, r20 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r4, r19 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r5, r18 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r6, r17 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r7, r16 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r8, r15 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r9, r14 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r10, r13 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r11, r12 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r25 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ld r12, y+ \n\t" \ + "ldi r22, 0 \n\t" \ + "mul r2, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r3, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r4, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r5, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r6, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r7, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r8, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r9, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r10, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r11, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r25 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ld r13, y+ \n\t" \ + "ldi r23, 0 \n\t" \ + "mul r2, r13 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r3, r12 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r4, r21 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r5, r20 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r6, r19 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r7, r18 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r8, r17 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r9, r16 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r10, r15 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r11, r14 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r25 \n\t" \ + "adc r23, r25 \n\t" \ + "st z+, r24 \n\t" \ + \ + "ld r14, y+ \n\t" \ + "ldi r24, 0 \n\t" \ + "mul r2, r14 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r3, r13 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r4, r12 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r5, r21 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r6, r20 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r7, r19 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r8, r18 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r9, r17 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r10, r16 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r11, r15 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r25 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ld r15, y+ \n\t" \ + "ldi r22, 0 \n\t" \ + "mul r2, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r3, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r4, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r5, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r6, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r7, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r8, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r9, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r10, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r11, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r25 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ld r16, y+ \n\t" \ + "ldi r23, 0 \n\t" \ + "mul r2, r16 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r3, r15 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r4, r14 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r5, r13 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r6, r12 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r7, r21 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r8, r20 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r9, r19 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r10, r18 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r11, r17 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r25 \n\t" \ + "adc r23, r25 \n\t" \ + "st z+, r24 \n\t" \ + \ + "ld r17, y+ \n\t" \ + "ldi r24, 0 \n\t" \ + "mul r2, r17 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r3, r16 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r4, r15 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r5, r14 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r6, r13 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r7, r12 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r8, r21 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r9, r20 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r10, r19 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r11, r18 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r25 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ld r18, y+ \n\t" \ + "ldi r22, 0 \n\t" \ + "mul r2, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r3, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r4, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r5, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r6, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r7, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r8, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r9, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r10, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r11, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r25 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ld r19, y+ \n\t" \ + "ldi r23, 0 \n\t" \ + "mul r2, r19 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r3, r18 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r4, r17 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r5, r16 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r6, r15 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r7, r14 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r8, r13 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r9, r12 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r10, r21 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r11, r20 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r25 \n\t" \ + "adc r23, r25 \n\t" \ + "st z+, r24 \n\t" \ + \ + "ld r20, y+ \n\t" \ + "ldi r24, 0 \n\t" \ + "mul r2, r20 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r3, r19 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r4, r18 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r5, r17 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r6, r16 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r7, r15 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r8, r14 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r9, r13 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r10, r12 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r11, r21 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r25 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ld r21, y+ \n\t" \ + "ldi r22, 0 \n\t" \ + "mul r2, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r3, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r4, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r5, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r6, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r7, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r8, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r9, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r10, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r11, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r25 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r23, 0 \n\t" \ + "mul r3, r21 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r4, r20 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r5, r19 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r6, r18 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r7, r17 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r8, r16 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r9, r15 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r10, r14 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r11, r13 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "st z+, r24 \n\t" \ + \ + "ldi r24, 0 \n\t" \ + "mul r4, r21 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r5, r20 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r6, r19 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r7, r18 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r8, r17 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r9, r16 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r10, r15 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r11, r14 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ldi r22, 0 \n\t" \ + "mul r5, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r6, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r7, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r8, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r9, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r10, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r11, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r23, 0 \n\t" \ + "mul r6, r21 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r7, r20 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r8, r19 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r9, r18 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r10, r17 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r11, r16 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "st z+, r24 \n\t" \ + \ + "ldi r24, 0 \n\t" \ + "mul r7, r21 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r8, r20 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r9, r19 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r10, r18 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r11, r17 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ldi r22, 0 \n\t" \ + "mul r8, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r9, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r10, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r11, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r23, 0 \n\t" \ + "mul r9, r21 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r10, r20 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r11, r19 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "st z+, r24 \n\t" \ + \ + "ldi r24, 0 \n\t" \ + "mul r10, r21 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r11, r20 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "mul r11, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "st z+, r23 \n\t" \ + "st z+, r24 \n\t" + +#define FAST_MULT_ASM_20_TO_24 \ + "cpi r18, 20 \n\t" \ + "brne 1f \n\t" \ + "jmp 2f \n\t" \ + "1: \n\t" \ + "ld r2, x+ \n\t" \ + "ld r6, y+ \n\t" \ + "ld r3, x+ \n\t" \ + "ld r7, y+ \n\t" \ + "ld r4, x+ \n\t" \ + "ld r8, y+ \n\t" \ + "ld r5, x+ \n\t" \ + "ld r9, y+ \n\t" \ + "sbiw r26, 24 \n\t" \ + "sbiw r28, 24 \n\t" \ + "sbiw r30, 20 \n\t" \ + "ld r10, x+ \n\t" \ + "ld r14, y+ \n\t" \ + "ld r11, x+ \n\t" \ + "ld r15, y+ \n\t" \ + "ld r12, x+ \n\t" \ + "ld r16, y+ \n\t" \ + "ld r13, x+ \n\t" \ + "ld r17, y+ \n\t" \ + \ + "mul r2, r14 \n\t" \ + "mov r19, r0 \n\t" \ + "mov r20, r1 \n\t" \ + "ldi r21, 0 \n\t" \ + "ld r0, z \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r6, r10 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "st z+, r19 \n\t" \ + \ + "ldi r19, 0 \n\t" \ + "ld r0, z \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r2, r15 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r6, r11 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r3, r14 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r7, r10 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "st z+, r20 \n\t" \ + \ + "ldi r20, 0 \n\t" \ + "ld r0, z \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r2, r16 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r6, r12 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r3, r15 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r7, r11 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r4, r14 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r8, r10 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "st z+, r21 \n\t" \ + \ + "ldi r21, 0 \n\t" \ + "ld r0, z \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r2, r17 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r6, r13 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r3, r16 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r7, r12 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r4, r15 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r8, r11 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r5, r14 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r9, r10 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "st z+, r19 \n\t" \ + \ + "ldi r19, 0 \n\t" \ + "ld r0, z \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r25 \n\t" \ + "ld r10, x+ \n\t" \ + "ld r14, y+ \n\t" \ + "mul r2, r14 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r6, r10 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r3, r17 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r7, r13 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r4, r16 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r8, r12 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r5, r15 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r9, r11 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "st z+, r20 \n\t" \ + \ + "ldi r20, 0 \n\t" \ + "ld r0, z \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r25 \n\t" \ + "ld r11, x+ \n\t" \ + "ld r15, y+ \n\t" \ + "mul r2, r15 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r6, r11 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r3, r14 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r7, r10 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r4, r17 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r8, r13 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r5, r16 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r9, r12 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "st z+, r21 \n\t" \ + \ + "ldi r21, 0 \n\t" \ + "ld r0, z \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r25 \n\t" \ + "ld r12, x+ \n\t" \ + "ld r16, y+ \n\t" \ + "mul r2, r16 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r6, r12 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r3, r15 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r7, r11 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r4, r14 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r8, r10 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r5, r17 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r9, r13 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "st z+, r19 \n\t" \ + \ + "ldi r19, 0 \n\t" \ + "ld r0, z \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r25 \n\t" \ + "ld r13, x+ \n\t" \ + "ld r17, y+ \n\t" \ + "mul r2, r17 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r6, r13 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r3, r16 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r7, r12 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r4, r15 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r8, r11 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r5, r14 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r9, r10 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "st z+, r20 \n\t" \ + \ + "ldi r20, 0 \n\t" \ + "ld r0, z \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r25 \n\t" \ + "ld r10, x+ \n\t" \ + "ld r14, y+ \n\t" \ + "mul r2, r14 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r6, r10 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r3, r17 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r7, r13 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r4, r16 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r8, r12 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r5, r15 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r9, r11 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "st z+, r21 \n\t" \ + \ + "ldi r21, 0 \n\t" \ + "ld r0, z \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r25 \n\t" \ + "ld r11, x+ \n\t" \ + "ld r15, y+ \n\t" \ + "mul r2, r15 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r6, r11 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r3, r14 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r7, r10 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r4, r17 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r8, r13 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r5, r16 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r9, r12 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "st z+, r19 \n\t" \ + \ + "ldi r19, 0 \n\t" \ + "ld r0, z \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r25 \n\t" \ + "ld r12, x+ \n\t" \ + "ld r16, y+ \n\t" \ + "mul r2, r16 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r6, r12 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r3, r15 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r7, r11 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r4, r14 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r8, r10 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r5, r17 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r9, r13 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "st z+, r20 \n\t" \ + \ + "ldi r20, 0 \n\t" \ + "ld r0, z \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r25 \n\t" \ + "ld r13, x+ \n\t" \ + "ld r17, y+ \n\t" \ + "mul r2, r17 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r6, r13 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r3, r16 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r7, r12 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r4, r15 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r8, r11 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r5, r14 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r9, r10 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "st z+, r21 \n\t" \ + \ + "ldi r21, 0 \n\t" \ + "ld r0, z \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r25 \n\t" \ + "ld r10, x+ \n\t" \ + "ld r14, y+ \n\t" \ + "mul r2, r14 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r6, r10 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r3, r17 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r7, r13 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r4, r16 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r8, r12 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r5, r15 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r9, r11 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "st z+, r19 \n\t" \ + \ + "ldi r19, 0 \n\t" \ + "ld r0, z \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r25 \n\t" \ + "ld r11, x+ \n\t" \ + "ld r15, y+ \n\t" \ + "mul r2, r15 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r6, r11 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r3, r14 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r7, r10 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r4, r17 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r8, r13 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r5, r16 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r9, r12 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "st z+, r20 \n\t" \ + \ + "ldi r20, 0 \n\t" \ + "ld r0, z \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r25 \n\t" \ + "ld r12, x+ \n\t" \ + "ld r16, y+ \n\t" \ + "mul r2, r16 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r6, r12 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r3, r15 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r7, r11 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r4, r14 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r8, r10 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r5, r17 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r9, r13 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "st z+, r21 \n\t" \ + \ + "ldi r21, 0 \n\t" \ + "ld r0, z \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r25 \n\t" \ + "ld r13, x+ \n\t" \ + "ld r17, y+ \n\t" \ + "mul r2, r17 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r6, r13 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r3, r16 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r7, r12 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r4, r15 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r8, r11 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r5, r14 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r9, r10 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "st z+, r19 \n\t" \ + \ + "ldi r19, 0 \n\t" \ + "ld r0, z \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r25 \n\t" \ + "ld r10, x+ \n\t" \ + "ld r14, y+ \n\t" \ + "mul r2, r14 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r6, r10 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r3, r17 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r7, r13 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r4, r16 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r8, r12 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r5, r15 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r9, r11 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "st z+, r20 \n\t" \ + \ + "ldi r20, 0 \n\t" \ + "ld r0, z \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r25 \n\t" \ + "ld r11, x+ \n\t" \ + "ld r15, y+ \n\t" \ + "mul r2, r15 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r6, r11 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r3, r14 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r7, r10 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r4, r17 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r8, r13 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r5, r16 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r9, r12 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "st z+, r21 \n\t" \ + \ + "ldi r21, 0 \n\t" \ + "ld r0, z \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r25 \n\t" \ + "ld r12, x+ \n\t" \ + "ld r16, y+ \n\t" \ + "mul r2, r16 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r6, r12 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r3, r15 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r7, r11 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r4, r14 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r8, r10 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r5, r17 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r9, r13 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "st z+, r19 \n\t" \ + \ + "ldi r19, 0 \n\t" \ + "ld r0, z \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r25 \n\t" \ + "ld r13, x+ \n\t" \ + "ld r17, y+ \n\t" \ + "mul r2, r17 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r6, r13 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r3, r16 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r7, r12 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r4, r15 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r8, r11 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r5, r14 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r9, r10 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "st z+, r20 \n\t" \ + \ + "ldi r20, 0 \n\t" \ + "mul r11, r9 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r12, r8 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r13, r7 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r2, r6 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r3, r17 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r4, r16 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r5, r15 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "st z+, r21 \n\t" \ + \ + "ldi r21, 0 \n\t" \ + "mul r12, r9 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r13, r8 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r2, r7 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r3, r6 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r4, r17 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r5, r16 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "st z+, r19 \n\t" \ + \ + "ldi r19, 0 \n\t" \ + "mul r13, r9 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r2, r8 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r3, r7 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r4, r6 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r5, r17 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "st z+, r20 \n\t" \ + \ + "ldi r20, 0 \n\t" \ + "mul r2, r9 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r3, r8 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r4, r7 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r5, r6 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "st z+, r21 \n\t" \ + \ + "ldi r21, 0 \n\t" \ + "mul r3, r9 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r4, r8 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r5, r7 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "st z+, r19 \n\t" \ + \ + "ldi r19, 0 \n\t" \ + "mul r4, r9 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r5, r8 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "st z+, r20 \n\t" \ + \ + "mul r5, r9 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "st z+, r21 \n\t" \ + "st z+, r19 \n\t" \ + "adiw r26, 4 \n\t" \ + "adiw r28, 4 \n\t" + +#define FAST_MULT_ASM_24 \ + "adiw r30, 20 \n\t" \ + "adiw r28, 20 \n\t" \ + "ld r2, x+ \n\t" \ + "ld r3, x+ \n\t" \ + "ld r4, x+ \n\t" \ + "ld r5, x+ \n\t" \ + "ld r12, y+ \n\t" \ + "ld r13, y+ \n\t" \ + "ld r14, y+ \n\t" \ + "ld r15, y+ \n\t" \ + "ldi r25, 0 \n\t" \ + \ + "ldi r23, 0 \n\t" \ + "mul r2, r12 \n\t" \ + "st z+, r0 \n\t" \ + "mov r22, r1 \n\t" \ + \ + "ldi r24, 0 \n\t" \ + "mul r2, r13 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "mul r3, r12 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ldi r22, 0 \n\t" \ + "mul r2, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r3, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r4, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r23, 0 \n\t" \ + "mul r2, r15 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r3, r14 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r4, r13 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r5, r12 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "st z+, r24 \n\t" \ + \ + "ldi r24, 0 \n\t" \ + "mul r3, r15 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r4, r14 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r5, r13 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ldi r22, 0 \n\t" \ + "mul r4, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r5, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "mul r5, r15 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "st z+, r24 \n\t" \ + "st z+, r22 \n\t" \ + \ + "sbiw r30, 18 \n\t" \ + "sbiw r28, 14 \n\t" \ + "ld r12, y+ \n\t" \ + "ld r13, y+ \n\t" \ + "ld r14, y+ \n\t" \ + "ld r15, y+ \n\t" \ + "ld r16, y+ \n\t" \ + "ld r17, y+ \n\t" \ + "ld r18, y+ \n\t" \ + "ld r19, y+ \n\t" \ + "ld r20, y+ \n\t" \ + "ld r21, y+ \n\t" \ + "ld r6, x+ \n\t" \ + "ld r7, x+ \n\t" \ + "ld r8, x+ \n\t" \ + "ld r9, x+ \n\t" \ + "ld r10, x+ \n\t" \ + "ld r11, x+ \n\t" \ + \ + "ldi r23, 0 \n\t" \ + "mul r2, r12 \n\t" \ + "st z+, r0 \n\t" \ + "mov r22, r1 \n\t" \ + \ + "ldi r24, 0 \n\t" \ + "mul r2, r13 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "mul r3, r12 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ldi r22, 0 \n\t" \ + "mul r2, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r3, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r4, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r23, 0 \n\t" \ + "mul r2, r15 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r3, r14 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r4, r13 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r5, r12 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "st z+, r24 \n\t" \ + \ + "ldi r24, 0 \n\t" \ + "mul r2, r16 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r3, r15 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r4, r14 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r5, r13 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r6, r12 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ldi r22, 0 \n\t" \ + "mul r2, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r3, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r4, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r5, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r6, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r7, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r23, 0 \n\t" \ + "mul r2, r18 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r3, r17 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r4, r16 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r5, r15 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r6, r14 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r7, r13 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r8, r12 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "st z+, r24 \n\t" \ + \ + "ldi r24, 0 \n\t" \ + "mul r2, r19 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r3, r18 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r4, r17 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r5, r16 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r6, r15 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r7, r14 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r8, r13 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r9, r12 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ldi r22, 0 \n\t" \ + "mul r2, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r3, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r4, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r5, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r6, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r7, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r8, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r9, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r10, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r23, 0 \n\t" \ + "mul r2, r21 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r3, r20 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r4, r19 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r5, r18 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r6, r17 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r7, r16 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r8, r15 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r9, r14 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r10, r13 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r11, r12 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "st z+, r24 \n\t" \ + \ + "ld r2, x+ \n\t" \ + "ldi r24, 0 \n\t" \ + "mul r3, r21 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r4, r20 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r5, r19 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r6, r18 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r7, r17 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r8, r16 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r9, r15 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r10, r14 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r11, r13 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r2, r12 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r25 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ld r3, x+ \n\t" \ + "ldi r22, 0 \n\t" \ + "mul r4, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r5, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r6, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r7, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r8, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r9, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r10, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r11, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r2, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r3, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r25 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ld r4, x+ \n\t" \ + "ldi r23, 0 \n\t" \ + "mul r5, r21 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r6, r20 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r7, r19 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r8, r18 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r9, r17 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r10, r16 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r11, r15 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r2, r14 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r3, r13 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r4, r12 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r25 \n\t" \ + "adc r23, r25 \n\t" \ + "st z+, r24 \n\t" \ + \ + "ld r5, x+ \n\t" \ + "ldi r24, 0 \n\t" \ + "mul r6, r21 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r7, r20 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r8, r19 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r9, r18 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r10, r17 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r11, r16 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r2, r15 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r3, r14 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r4, r13 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r5, r12 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r25 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ld r12, y+ \n\t" \ + "ldi r22, 0 \n\t" \ + "mul r6, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r7, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r8, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r9, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r10, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r11, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r2, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r3, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r4, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r5, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r25 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ld r13, y+ \n\t" \ + "ldi r23, 0 \n\t" \ + "mul r6, r13 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r7, r12 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r8, r21 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r9, r20 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r10, r19 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r11, r18 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r2, r17 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r3, r16 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r4, r15 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r5, r14 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r25 \n\t" \ + "adc r23, r25 \n\t" \ + "st z+, r24 \n\t" \ + \ + "ld r14, y+ \n\t" \ + "ldi r24, 0 \n\t" \ + "mul r6, r14 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r7, r13 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r8, r12 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r9, r21 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r10, r20 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r11, r19 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r2, r18 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r3, r17 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r4, r16 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r5, r15 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r25 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ld r15, y+ \n\t" \ + "ldi r22, 0 \n\t" \ + "mul r6, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r7, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r8, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r9, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r10, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r11, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r2, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r3, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r4, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r5, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r25 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r23, 0 \n\t" \ + "mul r7, r15 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r8, r14 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r9, r13 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r10, r12 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r11, r21 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r2, r20 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r3, r19 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r4, r18 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r5, r17 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "st z+, r24 \n\t" \ + \ + "ldi r24, 0 \n\t" \ + "mul r8, r15 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r9, r14 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r10, r13 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r11, r12 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r2, r21 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r3, r20 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r4, r19 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r5, r18 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ldi r22, 0 \n\t" \ + "mul r9, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r10, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r11, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r2, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r3, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r4, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r5, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r23, 0 \n\t" \ + "mul r10, r15 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r11, r14 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r2, r13 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r3, r12 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r4, r21 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r5, r20 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "st z+, r24 \n\t" \ + \ + "ldi r24, 0 \n\t" \ + "mul r11, r15 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r2, r14 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r3, r13 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r4, r12 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r5, r21 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ldi r22, 0 \n\t" \ + "mul r2, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r3, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r4, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r5, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r23, 0 \n\t" \ + "mul r3, r15 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r4, r14 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r5, r13 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "st z+, r24 \n\t" \ + \ + "ldi r24, 0 \n\t" \ + "mul r4, r15 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r5, r14 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "mul r5, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "st z+, r23 \n\t" \ + "st z+, r24 \n\t" \ + \ + "sbiw r30, 38 \n\t" \ + "sbiw r28, 24 \n\t" \ + "sbiw r26, 14 \n\t" \ + "ld r2, x+ \n\t" \ + "ld r12, y+ \n\t" \ + "ld r3, x+ \n\t" \ + "ld r13, y+ \n\t" \ + "ld r4, x+ \n\t" \ + "ld r14, y+ \n\t" \ + "ld r5, x+ \n\t" \ + "ld r15, y+ \n\t" \ + "ld r6, x+ \n\t" \ + "ld r16, y+ \n\t" \ + "ld r7, x+ \n\t" \ + "ld r17, y+ \n\t" \ + "ld r8, x+ \n\t" \ + "ld r18, y+ \n\t" \ + "ld r9, x+ \n\t" \ + "ld r19, y+ \n\t" \ + "ld r10, x+ \n\t" \ + "ld r20, y+ \n\t" \ + "ld r11, x+ \n\t" \ + "ld r21, y+ \n\t" \ + \ + "ldi r23, 0 \n\t" \ + "mul r2, r12 \n\t" \ + "st z+, r0 \n\t" \ + "mov r22, r1 \n\t" \ + \ + "ldi r24, 0 \n\t" \ + "mul r2, r13 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "mul r3, r12 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ldi r22, 0 \n\t" \ + "mul r2, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r3, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r4, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r23, 0 \n\t" \ + "mul r2, r15 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r3, r14 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r4, r13 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r5, r12 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "st z+, r24 \n\t" \ + \ + "ldi r24, 0 \n\t" \ + "mul r2, r16 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r3, r15 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r4, r14 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r5, r13 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r6, r12 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ldi r22, 0 \n\t" \ + "mul r2, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r3, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r4, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r5, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r6, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r7, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r23, 0 \n\t" \ + "mul r2, r18 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r3, r17 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r4, r16 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r5, r15 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r6, r14 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r7, r13 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r8, r12 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "st z+, r24 \n\t" \ + \ + "ldi r24, 0 \n\t" \ + "mul r2, r19 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r3, r18 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r4, r17 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r5, r16 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r6, r15 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r7, r14 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r8, r13 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r9, r12 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ldi r22, 0 \n\t" \ + "mul r2, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r3, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r4, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r5, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r6, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r7, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r8, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r9, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r10, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r23, 0 \n\t" \ + "mul r2, r21 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r3, r20 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r4, r19 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r5, r18 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r6, r17 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r7, r16 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r8, r15 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r9, r14 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r10, r13 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r11, r12 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "st z+, r24 \n\t" \ + \ + "ld r2, x+ \n\t" \ + "ldi r24, 0 \n\t" \ + "mul r3, r21 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r4, r20 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r5, r19 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r6, r18 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r7, r17 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r8, r16 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r9, r15 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r10, r14 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r11, r13 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r2, r12 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r25 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ld r3, x+ \n\t" \ + "ldi r22, 0 \n\t" \ + "mul r4, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r5, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r6, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r7, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r8, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r9, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r10, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r11, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r2, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r3, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r25 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ld r4, x+ \n\t" \ + "ldi r23, 0 \n\t" \ + "mul r5, r21 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r6, r20 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r7, r19 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r8, r18 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r9, r17 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r10, r16 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r11, r15 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r2, r14 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r3, r13 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r4, r12 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r25 \n\t" \ + "adc r23, r25 \n\t" \ + "st z+, r24 \n\t" \ + \ + "ld r5, x+ \n\t" \ + "ldi r24, 0 \n\t" \ + "mul r6, r21 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r7, r20 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r8, r19 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r9, r18 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r10, r17 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r11, r16 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r2, r15 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r3, r14 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r4, r13 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r5, r12 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r25 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ld r6, x+ \n\t" \ + "ldi r22, 0 \n\t" \ + "mul r7, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r8, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r9, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r10, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r11, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r2, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r3, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r4, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r5, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r6, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r25 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ld r7, x+ \n\t" \ + "ldi r23, 0 \n\t" \ + "mul r8, r21 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r9, r20 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r10, r19 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r11, r18 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r2, r17 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r3, r16 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r4, r15 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r5, r14 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r6, r13 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r7, r12 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r25 \n\t" \ + "adc r23, r25 \n\t" \ + "st z+, r24 \n\t" \ + \ + "ld r8, x+ \n\t" \ + "ldi r24, 0 \n\t" \ + "mul r9, r21 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r10, r20 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r11, r19 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r2, r18 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r3, r17 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r4, r16 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r5, r15 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r6, r14 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r7, r13 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r8, r12 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r25 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ld r9, x+ \n\t" \ + "ldi r22, 0 \n\t" \ + "mul r10, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r11, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r2, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r3, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r4, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r5, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r6, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r7, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r8, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r9, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r25 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ld r10, x+ \n\t" \ + "ldi r23, 0 \n\t" \ + "mul r11, r21 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r2, r20 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r3, r19 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r4, r18 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r5, r17 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r6, r16 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r7, r15 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r8, r14 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r9, r13 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r10, r12 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r25 \n\t" \ + "adc r23, r25 \n\t" \ + "st z+, r24 \n\t" \ + \ + "ld r11, x+ \n\t" \ + "ldi r24, 0 \n\t" \ + "mul r2, r21 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r3, r20 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r4, r19 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r5, r18 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r6, r17 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r7, r16 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r8, r15 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r9, r14 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r10, r13 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r11, r12 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r25 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ld r2, x+ \n\t" \ + "ldi r22, 0 \n\t" \ + "mul r3, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r4, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r5, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r6, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r7, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r8, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r9, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r10, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r11, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r2, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r25 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ld r3, x+ \n\t" \ + "ldi r23, 0 \n\t" \ + "mul r4, r21 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r5, r20 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r6, r19 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r7, r18 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r8, r17 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r9, r16 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r10, r15 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r11, r14 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r2, r13 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r3, r12 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r25 \n\t" \ + "adc r23, r25 \n\t" \ + "st z+, r24 \n\t" \ + \ + "ld r4, x+ \n\t" \ + "ldi r24, 0 \n\t" \ + "mul r5, r21 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r6, r20 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r7, r19 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r8, r18 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r9, r17 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r10, r16 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r11, r15 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r2, r14 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r3, r13 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r4, r12 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r25 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ld r5, x+ \n\t" \ + "ldi r22, 0 \n\t" \ + "mul r6, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r7, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r8, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r9, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r10, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r11, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r2, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r3, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r4, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r5, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r25 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ld r12, y+ \n\t" \ + "ldi r23, 0 \n\t" \ + "mul r6, r12 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r7, r21 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r8, r20 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r9, r19 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r10, r18 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r11, r17 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r2, r16 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r3, r15 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r4, r14 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r5, r13 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r25 \n\t" \ + "adc r23, r25 \n\t" \ + "st z+, r24 \n\t" \ + \ + "ld r13, y+ \n\t" \ + "ldi r24, 0 \n\t" \ + "mul r6, r13 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r7, r12 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r8, r21 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r9, r20 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r10, r19 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r11, r18 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r2, r17 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r3, r16 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r4, r15 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r5, r14 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r25 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ld r14, y+ \n\t" \ + "ldi r22, 0 \n\t" \ + "mul r6, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r7, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r8, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r9, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r10, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r11, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r2, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r3, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r4, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r5, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r25 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ld r15, y+ \n\t" \ + "ldi r23, 0 \n\t" \ + "mul r6, r15 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r7, r14 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r8, r13 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r9, r12 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r10, r21 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r11, r20 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r2, r19 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r3, r18 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r4, r17 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r5, r16 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r25 \n\t" \ + "adc r23, r25 \n\t" \ + "st z+, r24 \n\t" \ + \ + "ld r16, y+ \n\t" \ + "ldi r24, 0 \n\t" \ + "mul r6, r16 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r7, r15 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r8, r14 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r9, r13 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r10, r12 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r11, r21 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r2, r20 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r3, r19 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r4, r18 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r5, r17 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r25 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ld r17, y+ \n\t" \ + "ldi r22, 0 \n\t" \ + "mul r6, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r7, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r8, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r9, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r10, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r11, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r2, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r3, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r4, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r5, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r25 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ld r18, y+ \n\t" \ + "ldi r23, 0 \n\t" \ + "mul r6, r18 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r7, r17 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r8, r16 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r9, r15 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r10, r14 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r11, r13 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r2, r12 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r3, r21 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r4, r20 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r5, r19 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r25 \n\t" \ + "adc r23, r25 \n\t" \ + "st z+, r24 \n\t" \ + \ + "ld r19, y+ \n\t" \ + "ldi r24, 0 \n\t" \ + "mul r6, r19 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r7, r18 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r8, r17 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r9, r16 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r10, r15 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r11, r14 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r2, r13 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r3, r12 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r4, r21 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r5, r20 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r25 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ld r20, y+ \n\t" \ + "ldi r22, 0 \n\t" \ + "mul r6, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r7, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r8, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r9, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r10, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r11, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r2, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r3, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r4, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r5, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r25 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ld r21, y+ \n\t" \ + "ldi r23, 0 \n\t" \ + "mul r6, r21 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r7, r20 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r8, r19 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r9, r18 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r10, r17 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r11, r16 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r2, r15 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r3, r14 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r4, r13 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r5, r12 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r25 \n\t" \ + "adc r23, r25 \n\t" \ + "st z+, r24 \n\t" \ + \ + "ld r12, y+ \n\t" \ + "ldi r24, 0 \n\t" \ + "mul r6, r12 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r7, r21 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r8, r20 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r9, r19 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r10, r18 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r11, r17 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r2, r16 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r3, r15 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r4, r14 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r5, r13 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r25 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ld r13, y+ \n\t" \ + "ldi r22, 0 \n\t" \ + "mul r6, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r7, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r8, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r9, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r10, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r11, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r2, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r3, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r4, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r5, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r25 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ld r14, y+ \n\t" \ + "ldi r23, 0 \n\t" \ + "mul r6, r14 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r7, r13 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r8, r12 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r9, r21 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r10, r20 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r11, r19 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r2, r18 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r3, r17 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r4, r16 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r5, r15 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r25 \n\t" \ + "adc r23, r25 \n\t" \ + "st z+, r24 \n\t" \ + \ + "ld r15, y+ \n\t" \ + "ldi r24, 0 \n\t" \ + "mul r6, r15 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r7, r14 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r8, r13 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r9, r12 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r10, r21 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r11, r20 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r2, r19 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r3, r18 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r4, r17 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r5, r16 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r25 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ldi r22, 0 \n\t" \ + "mul r7, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r8, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r9, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r10, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r11, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r2, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r3, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r4, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r5, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r23, 0 \n\t" \ + "mul r8, r15 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r9, r14 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r10, r13 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r11, r12 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r2, r21 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r3, r20 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r4, r19 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r5, r18 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "st z+, r24 \n\t" \ + \ + "ldi r24, 0 \n\t" \ + "mul r9, r15 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r10, r14 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r11, r13 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r2, r12 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r3, r21 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r4, r20 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r5, r19 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ldi r22, 0 \n\t" \ + "mul r10, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r11, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r2, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r3, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r4, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r5, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r23, 0 \n\t" \ + "mul r11, r15 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r2, r14 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r3, r13 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r4, r12 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r5, r21 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "st z+, r24 \n\t" \ + \ + "ldi r24, 0 \n\t" \ + "mul r2, r15 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r3, r14 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r4, r13 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r5, r12 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ldi r22, 0 \n\t" \ + "mul r3, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r4, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r5, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r23, 0 \n\t" \ + "mul r4, r15 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r5, r14 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "st z+, r24 \n\t" \ + \ + "mul r5, r15 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "st z+, r22 \n\t" \ + "st z+, r23 \n\t" + +#define FAST_MULT_ASM_24_TO_28 \ + "cpi r18, 24 \n\t" \ + "brne 1f \n\t" \ + "jmp 2f \n\t" \ + "1: \n\t" \ + "ld r2, x+ \n\t" \ + "ld r6, y+ \n\t" \ + "ld r3, x+ \n\t" \ + "ld r7, y+ \n\t" \ + "ld r4, x+ \n\t" \ + "ld r8, y+ \n\t" \ + "ld r5, x+ \n\t" \ + "ld r9, y+ \n\t" \ + "sbiw r26, 28 \n\t" \ + "sbiw r28, 28 \n\t" \ + "sbiw r30, 24 \n\t" \ + "ld r10, x+ \n\t" \ + "ld r14, y+ \n\t" \ + "ld r11, x+ \n\t" \ + "ld r15, y+ \n\t" \ + "ld r12, x+ \n\t" \ + "ld r16, y+ \n\t" \ + "ld r13, x+ \n\t" \ + "ld r17, y+ \n\t" \ + \ + "mul r2, r14 \n\t" \ + "mov r19, r0 \n\t" \ + "mov r20, r1 \n\t" \ + "ldi r21, 0 \n\t" \ + "ld r0, z \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r6, r10 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "st z+, r19 \n\t" \ + \ + "ldi r19, 0 \n\t" \ + "ld r0, z \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r2, r15 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r6, r11 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r3, r14 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r7, r10 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "st z+, r20 \n\t" \ + \ + "ldi r20, 0 \n\t" \ + "ld r0, z \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r2, r16 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r6, r12 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r3, r15 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r7, r11 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r4, r14 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r8, r10 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "st z+, r21 \n\t" \ + \ + "ldi r21, 0 \n\t" \ + "ld r0, z \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r2, r17 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r6, r13 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r3, r16 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r7, r12 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r4, r15 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r8, r11 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r5, r14 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r9, r10 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "st z+, r19 \n\t" \ + \ + "ldi r19, 0 \n\t" \ + "ld r0, z \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r25 \n\t" \ + "ld r10, x+ \n\t" \ + "ld r14, y+ \n\t" \ + "mul r2, r14 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r6, r10 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r3, r17 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r7, r13 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r4, r16 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r8, r12 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r5, r15 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r9, r11 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "st z+, r20 \n\t" \ + \ + "ldi r20, 0 \n\t" \ + "ld r0, z \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r25 \n\t" \ + "ld r11, x+ \n\t" \ + "ld r15, y+ \n\t" \ + "mul r2, r15 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r6, r11 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r3, r14 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r7, r10 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r4, r17 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r8, r13 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r5, r16 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r9, r12 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "st z+, r21 \n\t" \ + \ + "ldi r21, 0 \n\t" \ + "ld r0, z \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r25 \n\t" \ + "ld r12, x+ \n\t" \ + "ld r16, y+ \n\t" \ + "mul r2, r16 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r6, r12 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r3, r15 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r7, r11 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r4, r14 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r8, r10 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r5, r17 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r9, r13 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "st z+, r19 \n\t" \ + \ + "ldi r19, 0 \n\t" \ + "ld r0, z \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r25 \n\t" \ + "ld r13, x+ \n\t" \ + "ld r17, y+ \n\t" \ + "mul r2, r17 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r6, r13 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r3, r16 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r7, r12 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r4, r15 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r8, r11 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r5, r14 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r9, r10 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "st z+, r20 \n\t" \ + \ + "ldi r20, 0 \n\t" \ + "ld r0, z \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r25 \n\t" \ + "ld r10, x+ \n\t" \ + "ld r14, y+ \n\t" \ + "mul r2, r14 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r6, r10 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r3, r17 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r7, r13 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r4, r16 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r8, r12 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r5, r15 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r9, r11 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "st z+, r21 \n\t" \ + \ + "ldi r21, 0 \n\t" \ + "ld r0, z \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r25 \n\t" \ + "ld r11, x+ \n\t" \ + "ld r15, y+ \n\t" \ + "mul r2, r15 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r6, r11 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r3, r14 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r7, r10 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r4, r17 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r8, r13 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r5, r16 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r9, r12 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "st z+, r19 \n\t" \ + \ + "ldi r19, 0 \n\t" \ + "ld r0, z \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r25 \n\t" \ + "ld r12, x+ \n\t" \ + "ld r16, y+ \n\t" \ + "mul r2, r16 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r6, r12 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r3, r15 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r7, r11 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r4, r14 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r8, r10 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r5, r17 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r9, r13 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "st z+, r20 \n\t" \ + \ + "ldi r20, 0 \n\t" \ + "ld r0, z \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r25 \n\t" \ + "ld r13, x+ \n\t" \ + "ld r17, y+ \n\t" \ + "mul r2, r17 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r6, r13 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r3, r16 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r7, r12 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r4, r15 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r8, r11 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r5, r14 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r9, r10 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "st z+, r21 \n\t" \ + \ + "ldi r21, 0 \n\t" \ + "ld r0, z \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r25 \n\t" \ + "ld r10, x+ \n\t" \ + "ld r14, y+ \n\t" \ + "mul r2, r14 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r6, r10 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r3, r17 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r7, r13 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r4, r16 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r8, r12 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r5, r15 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r9, r11 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "st z+, r19 \n\t" \ + \ + "ldi r19, 0 \n\t" \ + "ld r0, z \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r25 \n\t" \ + "ld r11, x+ \n\t" \ + "ld r15, y+ \n\t" \ + "mul r2, r15 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r6, r11 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r3, r14 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r7, r10 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r4, r17 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r8, r13 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r5, r16 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r9, r12 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "st z+, r20 \n\t" \ + \ + "ldi r20, 0 \n\t" \ + "ld r0, z \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r25 \n\t" \ + "ld r12, x+ \n\t" \ + "ld r16, y+ \n\t" \ + "mul r2, r16 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r6, r12 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r3, r15 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r7, r11 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r4, r14 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r8, r10 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r5, r17 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r9, r13 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "st z+, r21 \n\t" \ + \ + "ldi r21, 0 \n\t" \ + "ld r0, z \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r25 \n\t" \ + "ld r13, x+ \n\t" \ + "ld r17, y+ \n\t" \ + "mul r2, r17 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r6, r13 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r3, r16 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r7, r12 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r4, r15 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r8, r11 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r5, r14 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r9, r10 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "st z+, r19 \n\t" \ + \ + "ldi r19, 0 \n\t" \ + "ld r0, z \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r25 \n\t" \ + "ld r10, x+ \n\t" \ + "ld r14, y+ \n\t" \ + "mul r2, r14 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r6, r10 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r3, r17 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r7, r13 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r4, r16 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r8, r12 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r5, r15 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r9, r11 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "st z+, r20 \n\t" \ + \ + "ldi r20, 0 \n\t" \ + "ld r0, z \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r25 \n\t" \ + "ld r11, x+ \n\t" \ + "ld r15, y+ \n\t" \ + "mul r2, r15 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r6, r11 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r3, r14 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r7, r10 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r4, r17 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r8, r13 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r5, r16 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r9, r12 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "st z+, r21 \n\t" \ + \ + "ldi r21, 0 \n\t" \ + "ld r0, z \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r25 \n\t" \ + "ld r12, x+ \n\t" \ + "ld r16, y+ \n\t" \ + "mul r2, r16 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r6, r12 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r3, r15 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r7, r11 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r4, r14 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r8, r10 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r5, r17 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r9, r13 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "st z+, r19 \n\t" \ + \ + "ldi r19, 0 \n\t" \ + "ld r0, z \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r25 \n\t" \ + "ld r13, x+ \n\t" \ + "ld r17, y+ \n\t" \ + "mul r2, r17 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r6, r13 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r3, r16 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r7, r12 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r4, r15 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r8, r11 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r5, r14 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r9, r10 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "st z+, r20 \n\t" \ + \ + "ldi r20, 0 \n\t" \ + "ld r0, z \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r25 \n\t" \ + "ld r10, x+ \n\t" \ + "ld r14, y+ \n\t" \ + "mul r2, r14 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r6, r10 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r3, r17 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r7, r13 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r4, r16 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r8, r12 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r5, r15 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r9, r11 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "st z+, r21 \n\t" \ + \ + "ldi r21, 0 \n\t" \ + "ld r0, z \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r25 \n\t" \ + "ld r11, x+ \n\t" \ + "ld r15, y+ \n\t" \ + "mul r2, r15 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r6, r11 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r3, r14 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r7, r10 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r4, r17 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r8, r13 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r5, r16 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r9, r12 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "st z+, r19 \n\t" \ + \ + "ldi r19, 0 \n\t" \ + "ld r0, z \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r25 \n\t" \ + "ld r12, x+ \n\t" \ + "ld r16, y+ \n\t" \ + "mul r2, r16 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r6, r12 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r3, r15 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r7, r11 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r4, r14 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r8, r10 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r5, r17 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r9, r13 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "st z+, r20 \n\t" \ + \ + "ldi r20, 0 \n\t" \ + "ld r0, z \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r25 \n\t" \ + "ld r13, x+ \n\t" \ + "ld r17, y+ \n\t" \ + "mul r2, r17 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r6, r13 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r3, r16 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r7, r12 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r4, r15 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r8, r11 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r5, r14 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r9, r10 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "st z+, r21 \n\t" \ + \ + "ldi r21, 0 \n\t" \ + "mul r11, r9 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r12, r8 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r13, r7 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r2, r6 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r3, r17 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r4, r16 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r5, r15 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "st z+, r19 \n\t" \ + \ + "ldi r19, 0 \n\t" \ + "mul r12, r9 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r13, r8 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r2, r7 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r3, r6 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r4, r17 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r5, r16 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "st z+, r20 \n\t" \ + \ + "ldi r20, 0 \n\t" \ + "mul r13, r9 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r2, r8 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r3, r7 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r4, r6 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r5, r17 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "st z+, r21 \n\t" \ + \ + "ldi r21, 0 \n\t" \ + "mul r2, r9 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r3, r8 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r4, r7 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r5, r6 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "st z+, r19 \n\t" \ + \ + "ldi r19, 0 \n\t" \ + "mul r3, r9 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r4, r8 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r5, r7 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "st z+, r20 \n\t" \ + \ + "ldi r20, 0 \n\t" \ + "mul r4, r9 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r5, r8 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "st z+, r21 \n\t" \ + \ + "mul r5, r9 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "st z+, r19 \n\t" \ + "st z+, r20 \n\t" \ + "adiw r26, 4 \n\t" \ + "adiw r28, 4 \n\t" + +#define FAST_MULT_ASM_28 \ + "adiw r30, 20 \n\t" \ + "adiw r28, 20 \n\t" \ + "ld r2, x+ \n\t" \ + "ld r3, x+ \n\t" \ + "ld r4, x+ \n\t" \ + "ld r5, x+ \n\t" \ + "ld r6, x+ \n\t" \ + "ld r7, x+ \n\t" \ + "ld r8, x+ \n\t" \ + "ld r9, x+ \n\t" \ + "ld r12, y+ \n\t" \ + "ld r13, y+ \n\t" \ + "ld r14, y+ \n\t" \ + "ld r15, y+ \n\t" \ + "ld r16, y+ \n\t" \ + "ld r17, y+ \n\t" \ + "ld r18, y+ \n\t" \ + "ld r19, y+ \n\t" \ + "ldi r25, 0 \n\t" \ + \ + "ldi r23, 0 \n\t" \ + "mul r2, r12 \n\t" \ + "st z+, r0 \n\t" \ + "mov r22, r1 \n\t" \ + \ + "ldi r24, 0 \n\t" \ + "mul r2, r13 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "mul r3, r12 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ldi r22, 0 \n\t" \ + "mul r2, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r3, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r4, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r23, 0 \n\t" \ + "mul r2, r15 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r3, r14 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r4, r13 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r5, r12 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "st z+, r24 \n\t" \ + \ + "ldi r24, 0 \n\t" \ + "mul r2, r16 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r3, r15 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r4, r14 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r5, r13 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r6, r12 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ldi r22, 0 \n\t" \ + "mul r2, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r3, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r4, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r5, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r6, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r7, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r23, 0 \n\t" \ + "mul r2, r18 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r3, r17 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r4, r16 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r5, r15 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r6, r14 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r7, r13 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r8, r12 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "st z+, r24 \n\t" \ + \ + "ldi r24, 0 \n\t" \ + "mul r2, r19 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r3, r18 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r4, r17 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r5, r16 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r6, r15 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r7, r14 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r8, r13 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r9, r12 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ldi r22, 0 \n\t" \ + "mul r3, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r4, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r5, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r6, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r7, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r8, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r9, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r23, 0 \n\t" \ + "mul r4, r19 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r5, r18 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r6, r17 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r7, r16 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r8, r15 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r9, r14 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "st z+, r24 \n\t" \ + \ + "ldi r24, 0 \n\t" \ + "mul r5, r19 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r6, r18 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r7, r17 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r8, r16 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r9, r15 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ldi r22, 0 \n\t" \ + "mul r6, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r7, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r8, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r9, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r23, 0 \n\t" \ + "mul r7, r19 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r8, r18 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r9, r17 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "st z+, r24 \n\t" \ + \ + "ldi r24, 0 \n\t" \ + "mul r8, r19 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r9, r18 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "mul r9, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "st z+, r23 \n\t" \ + "st z+, r24 \n\t" \ + \ + "sbiw r30, 26 \n\t" \ + "sbiw r28, 18 \n\t" \ + "ld r12, y+ \n\t" \ + "ld r13, y+ \n\t" \ + "ld r14, y+ \n\t" \ + "ld r15, y+ \n\t" \ + "ld r16, y+ \n\t" \ + "ld r17, y+ \n\t" \ + "ld r18, y+ \n\t" \ + "ld r19, y+ \n\t" \ + "ld r20, y+ \n\t" \ + "ld r21, y+ \n\t" \ + "ld r10, x+ \n\t" \ + "ld r11, x+ \n\t" \ + \ + "ldi r23, 0 \n\t" \ + "mul r2, r12 \n\t" \ + "st z+, r0 \n\t" \ + "mov r22, r1 \n\t" \ + \ + "ldi r24, 0 \n\t" \ + "mul r2, r13 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "mul r3, r12 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ldi r22, 0 \n\t" \ + "mul r2, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r3, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r4, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r23, 0 \n\t" \ + "mul r2, r15 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r3, r14 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r4, r13 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r5, r12 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "st z+, r24 \n\t" \ + \ + "ldi r24, 0 \n\t" \ + "mul r2, r16 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r3, r15 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r4, r14 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r5, r13 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r6, r12 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ldi r22, 0 \n\t" \ + "mul r2, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r3, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r4, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r5, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r6, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r7, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r23, 0 \n\t" \ + "mul r2, r18 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r3, r17 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r4, r16 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r5, r15 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r6, r14 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r7, r13 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r8, r12 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "st z+, r24 \n\t" \ + \ + "ldi r24, 0 \n\t" \ + "mul r2, r19 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r3, r18 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r4, r17 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r5, r16 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r6, r15 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r7, r14 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r8, r13 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r9, r12 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ldi r22, 0 \n\t" \ + "mul r2, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r3, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r4, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r5, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r6, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r7, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r8, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r9, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r10, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r23, 0 \n\t" \ + "mul r2, r21 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r3, r20 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r4, r19 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r5, r18 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r6, r17 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r7, r16 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r8, r15 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r9, r14 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r10, r13 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r11, r12 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "st z+, r24 \n\t" \ + \ + "ld r2, x+ \n\t" \ + "ldi r24, 0 \n\t" \ + "mul r3, r21 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r4, r20 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r5, r19 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r6, r18 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r7, r17 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r8, r16 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r9, r15 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r10, r14 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r11, r13 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r2, r12 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r25 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ld r3, x+ \n\t" \ + "ldi r22, 0 \n\t" \ + "mul r4, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r5, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r6, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r7, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r8, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r9, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r10, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r11, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r2, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r3, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r25 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ld r4, x+ \n\t" \ + "ldi r23, 0 \n\t" \ + "mul r5, r21 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r6, r20 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r7, r19 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r8, r18 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r9, r17 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r10, r16 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r11, r15 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r2, r14 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r3, r13 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r4, r12 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r25 \n\t" \ + "adc r23, r25 \n\t" \ + "st z+, r24 \n\t" \ + \ + "ld r5, x+ \n\t" \ + "ldi r24, 0 \n\t" \ + "mul r6, r21 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r7, r20 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r8, r19 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r9, r18 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r10, r17 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r11, r16 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r2, r15 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r3, r14 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r4, r13 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r5, r12 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r25 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ld r6, x+ \n\t" \ + "ldi r22, 0 \n\t" \ + "mul r7, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r8, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r9, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r10, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r11, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r2, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r3, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r4, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r5, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r6, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r25 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ld r7, x+ \n\t" \ + "ldi r23, 0 \n\t" \ + "mul r8, r21 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r9, r20 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r10, r19 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r11, r18 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r2, r17 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r3, r16 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r4, r15 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r5, r14 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r6, r13 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r7, r12 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r25 \n\t" \ + "adc r23, r25 \n\t" \ + "st z+, r24 \n\t" \ + \ + "ld r8, x+ \n\t" \ + "ldi r24, 0 \n\t" \ + "mul r9, r21 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r10, r20 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r11, r19 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r2, r18 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r3, r17 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r4, r16 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r5, r15 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r6, r14 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r7, r13 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r8, r12 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r25 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ld r9, x+ \n\t" \ + "ldi r22, 0 \n\t" \ + "mul r10, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r11, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r2, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r3, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r4, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r5, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r6, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r7, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r8, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r9, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r25 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ld r12, y+ \n\t" \ + "ldi r23, 0 \n\t" \ + "mul r10, r12 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r11, r21 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r2, r20 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r3, r19 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r4, r18 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r5, r17 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r6, r16 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r7, r15 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r8, r14 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r9, r13 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r25 \n\t" \ + "adc r23, r25 \n\t" \ + "st z+, r24 \n\t" \ + \ + "ld r13, y+ \n\t" \ + "ldi r24, 0 \n\t" \ + "mul r10, r13 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r11, r12 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r2, r21 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r3, r20 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r4, r19 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r5, r18 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r6, r17 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r7, r16 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r8, r15 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r9, r14 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r25 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ld r14, y+ \n\t" \ + "ldi r22, 0 \n\t" \ + "mul r10, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r11, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r2, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r3, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r4, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r5, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r6, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r7, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r8, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r9, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r25 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ld r15, y+ \n\t" \ + "ldi r23, 0 \n\t" \ + "mul r10, r15 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r11, r14 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r2, r13 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r3, r12 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r4, r21 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r5, r20 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r6, r19 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r7, r18 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r8, r17 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r9, r16 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r25 \n\t" \ + "adc r23, r25 \n\t" \ + "st z+, r24 \n\t" \ + \ + "ld r16, y+ \n\t" \ + "ldi r24, 0 \n\t" \ + "mul r10, r16 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r11, r15 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r2, r14 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r3, r13 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r4, r12 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r5, r21 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r6, r20 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r7, r19 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r8, r18 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r9, r17 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r25 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ld r17, y+ \n\t" \ + "ldi r22, 0 \n\t" \ + "mul r10, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r11, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r2, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r3, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r4, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r5, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r6, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r7, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r8, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r9, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r25 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ld r18, y+ \n\t" \ + "ldi r23, 0 \n\t" \ + "mul r10, r18 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r11, r17 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r2, r16 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r3, r15 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r4, r14 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r5, r13 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r6, r12 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r7, r21 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r8, r20 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r9, r19 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r25 \n\t" \ + "adc r23, r25 \n\t" \ + "st z+, r24 \n\t" \ + \ + "ld r19, y+ \n\t" \ + "ldi r24, 0 \n\t" \ + "mul r10, r19 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r11, r18 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r2, r17 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r3, r16 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r4, r15 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r5, r14 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r6, r13 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r7, r12 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r8, r21 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r9, r20 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r25 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ldi r22, 0 \n\t" \ + "mul r11, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r2, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r3, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r4, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r5, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r6, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r7, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r8, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r9, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r23, 0 \n\t" \ + "mul r2, r19 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r3, r18 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r4, r17 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r5, r16 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r6, r15 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r7, r14 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r8, r13 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r9, r12 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "st z+, r24 \n\t" \ + \ + "ldi r24, 0 \n\t" \ + "mul r3, r19 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r4, r18 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r5, r17 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r6, r16 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r7, r15 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r8, r14 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r9, r13 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ldi r22, 0 \n\t" \ + "mul r4, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r5, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r6, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r7, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r8, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r9, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r23, 0 \n\t" \ + "mul r5, r19 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r6, r18 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r7, r17 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r8, r16 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r9, r15 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "st z+, r24 \n\t" \ + \ + "ldi r24, 0 \n\t" \ + "mul r6, r19 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r7, r18 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r8, r17 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r9, r16 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ldi r22, 0 \n\t" \ + "mul r7, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r8, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r9, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r23, 0 \n\t" \ + "mul r8, r19 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r9, r18 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "st z+, r24 \n\t" \ + \ + "mul r9, r19 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "st z+, r22 \n\t" \ + "st z+, r23 \n\t" \ + \ + "sbiw r30, 46 \n\t" \ + "sbiw r28, 28 \n\t" \ + "sbiw r26, 18 \n\t" \ + "ld r2, x+ \n\t" \ + "ld r12, y+ \n\t" \ + "ld r3, x+ \n\t" \ + "ld r13, y+ \n\t" \ + "ld r4, x+ \n\t" \ + "ld r14, y+ \n\t" \ + "ld r5, x+ \n\t" \ + "ld r15, y+ \n\t" \ + "ld r6, x+ \n\t" \ + "ld r16, y+ \n\t" \ + "ld r7, x+ \n\t" \ + "ld r17, y+ \n\t" \ + "ld r8, x+ \n\t" \ + "ld r18, y+ \n\t" \ + "ld r9, x+ \n\t" \ + "ld r19, y+ \n\t" \ + "ld r10, x+ \n\t" \ + "ld r20, y+ \n\t" \ + "ld r11, x+ \n\t" \ + "ld r21, y+ \n\t" \ + \ + "ldi r23, 0 \n\t" \ + "mul r2, r12 \n\t" \ + "st z+, r0 \n\t" \ + "mov r22, r1 \n\t" \ + \ + "ldi r24, 0 \n\t" \ + "mul r2, r13 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "mul r3, r12 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ldi r22, 0 \n\t" \ + "mul r2, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r3, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r4, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r23, 0 \n\t" \ + "mul r2, r15 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r3, r14 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r4, r13 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r5, r12 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "st z+, r24 \n\t" \ + \ + "ldi r24, 0 \n\t" \ + "mul r2, r16 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r3, r15 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r4, r14 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r5, r13 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r6, r12 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ldi r22, 0 \n\t" \ + "mul r2, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r3, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r4, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r5, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r6, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r7, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r23, 0 \n\t" \ + "mul r2, r18 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r3, r17 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r4, r16 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r5, r15 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r6, r14 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r7, r13 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r8, r12 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "st z+, r24 \n\t" \ + \ + "ldi r24, 0 \n\t" \ + "mul r2, r19 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r3, r18 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r4, r17 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r5, r16 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r6, r15 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r7, r14 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r8, r13 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r9, r12 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ldi r22, 0 \n\t" \ + "mul r2, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r3, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r4, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r5, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r6, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r7, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r8, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r9, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r10, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r23, 0 \n\t" \ + "mul r2, r21 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r3, r20 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r4, r19 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r5, r18 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r6, r17 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r7, r16 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r8, r15 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r9, r14 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r10, r13 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r11, r12 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "st z+, r24 \n\t" \ + \ + "ld r2, x+ \n\t" \ + "ldi r24, 0 \n\t" \ + "mul r3, r21 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r4, r20 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r5, r19 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r6, r18 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r7, r17 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r8, r16 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r9, r15 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r10, r14 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r11, r13 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r2, r12 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r25 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ld r3, x+ \n\t" \ + "ldi r22, 0 \n\t" \ + "mul r4, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r5, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r6, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r7, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r8, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r9, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r10, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r11, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r2, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r3, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r25 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ld r4, x+ \n\t" \ + "ldi r23, 0 \n\t" \ + "mul r5, r21 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r6, r20 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r7, r19 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r8, r18 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r9, r17 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r10, r16 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r11, r15 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r2, r14 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r3, r13 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r4, r12 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r25 \n\t" \ + "adc r23, r25 \n\t" \ + "st z+, r24 \n\t" \ + \ + "ld r5, x+ \n\t" \ + "ldi r24, 0 \n\t" \ + "mul r6, r21 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r7, r20 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r8, r19 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r9, r18 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r10, r17 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r11, r16 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r2, r15 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r3, r14 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r4, r13 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r5, r12 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r25 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ld r6, x+ \n\t" \ + "ldi r22, 0 \n\t" \ + "mul r7, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r8, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r9, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r10, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r11, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r2, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r3, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r4, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r5, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r6, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r25 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ld r7, x+ \n\t" \ + "ldi r23, 0 \n\t" \ + "mul r8, r21 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r9, r20 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r10, r19 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r11, r18 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r2, r17 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r3, r16 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r4, r15 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r5, r14 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r6, r13 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r7, r12 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r25 \n\t" \ + "adc r23, r25 \n\t" \ + "st z+, r24 \n\t" \ + \ + "ld r8, x+ \n\t" \ + "ldi r24, 0 \n\t" \ + "mul r9, r21 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r10, r20 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r11, r19 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r2, r18 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r3, r17 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r4, r16 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r5, r15 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r6, r14 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r7, r13 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r8, r12 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r25 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ld r9, x+ \n\t" \ + "ldi r22, 0 \n\t" \ + "mul r10, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r11, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r2, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r3, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r4, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r5, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r6, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r7, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r8, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r9, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r25 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ld r10, x+ \n\t" \ + "ldi r23, 0 \n\t" \ + "mul r11, r21 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r2, r20 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r3, r19 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r4, r18 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r5, r17 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r6, r16 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r7, r15 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r8, r14 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r9, r13 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r10, r12 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r25 \n\t" \ + "adc r23, r25 \n\t" \ + "st z+, r24 \n\t" \ + \ + "ld r11, x+ \n\t" \ + "ldi r24, 0 \n\t" \ + "mul r2, r21 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r3, r20 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r4, r19 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r5, r18 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r6, r17 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r7, r16 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r8, r15 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r9, r14 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r10, r13 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r11, r12 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r25 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ld r2, x+ \n\t" \ + "ldi r22, 0 \n\t" \ + "mul r3, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r4, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r5, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r6, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r7, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r8, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r9, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r10, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r11, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r2, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r25 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ld r3, x+ \n\t" \ + "ldi r23, 0 \n\t" \ + "mul r4, r21 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r5, r20 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r6, r19 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r7, r18 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r8, r17 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r9, r16 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r10, r15 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r11, r14 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r2, r13 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r3, r12 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r25 \n\t" \ + "adc r23, r25 \n\t" \ + "st z+, r24 \n\t" \ + \ + "ld r4, x+ \n\t" \ + "ldi r24, 0 \n\t" \ + "mul r5, r21 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r6, r20 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r7, r19 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r8, r18 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r9, r17 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r10, r16 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r11, r15 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r2, r14 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r3, r13 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r4, r12 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r25 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ld r5, x+ \n\t" \ + "ldi r22, 0 \n\t" \ + "mul r6, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r7, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r8, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r9, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r10, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r11, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r2, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r3, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r4, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r5, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r25 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ld r6, x+ \n\t" \ + "ldi r23, 0 \n\t" \ + "mul r7, r21 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r8, r20 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r9, r19 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r10, r18 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r11, r17 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r2, r16 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r3, r15 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r4, r14 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r5, r13 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r6, r12 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r25 \n\t" \ + "adc r23, r25 \n\t" \ + "st z+, r24 \n\t" \ + \ + "ld r7, x+ \n\t" \ + "ldi r24, 0 \n\t" \ + "mul r8, r21 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r9, r20 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r10, r19 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r11, r18 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r2, r17 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r3, r16 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r4, r15 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r5, r14 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r6, r13 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r7, r12 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r25 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ld r8, x+ \n\t" \ + "ldi r22, 0 \n\t" \ + "mul r9, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r10, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r11, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r2, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r3, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r4, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r5, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r6, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r7, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r8, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r25 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ld r9, x+ \n\t" \ + "ldi r23, 0 \n\t" \ + "mul r10, r21 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r11, r20 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r2, r19 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r3, r18 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r4, r17 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r5, r16 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r6, r15 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r7, r14 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r8, r13 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r9, r12 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r25 \n\t" \ + "adc r23, r25 \n\t" \ + "st z+, r24 \n\t" \ + \ + "ld r12, y+ \n\t" \ + "ldi r24, 0 \n\t" \ + "mul r10, r12 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r11, r21 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r2, r20 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r3, r19 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r4, r18 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r5, r17 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r6, r16 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r7, r15 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r8, r14 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r9, r13 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r25 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ld r13, y+ \n\t" \ + "ldi r22, 0 \n\t" \ + "mul r10, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r11, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r2, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r3, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r4, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r5, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r6, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r7, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r8, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r9, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r25 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ld r14, y+ \n\t" \ + "ldi r23, 0 \n\t" \ + "mul r10, r14 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r11, r13 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r2, r12 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r3, r21 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r4, r20 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r5, r19 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r6, r18 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r7, r17 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r8, r16 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r9, r15 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r25 \n\t" \ + "adc r23, r25 \n\t" \ + "st z+, r24 \n\t" \ + \ + "ld r15, y+ \n\t" \ + "ldi r24, 0 \n\t" \ + "mul r10, r15 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r11, r14 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r2, r13 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r3, r12 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r4, r21 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r5, r20 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r6, r19 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r7, r18 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r8, r17 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r9, r16 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r25 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ld r16, y+ \n\t" \ + "ldi r22, 0 \n\t" \ + "mul r10, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r11, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r2, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r3, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r4, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r5, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r6, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r7, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r8, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r9, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r25 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ld r17, y+ \n\t" \ + "ldi r23, 0 \n\t" \ + "mul r10, r17 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r11, r16 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r2, r15 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r3, r14 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r4, r13 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r5, r12 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r6, r21 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r7, r20 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r8, r19 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r9, r18 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r25 \n\t" \ + "adc r23, r25 \n\t" \ + "st z+, r24 \n\t" \ + \ + "ld r18, y+ \n\t" \ + "ldi r24, 0 \n\t" \ + "mul r10, r18 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r11, r17 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r2, r16 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r3, r15 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r4, r14 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r5, r13 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r6, r12 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r7, r21 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r8, r20 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r9, r19 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r25 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ld r19, y+ \n\t" \ + "ldi r22, 0 \n\t" \ + "mul r10, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r11, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r2, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r3, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r4, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r5, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r6, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r7, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r8, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r9, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r25 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ld r20, y+ \n\t" \ + "ldi r23, 0 \n\t" \ + "mul r10, r20 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r11, r19 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r2, r18 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r3, r17 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r4, r16 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r5, r15 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r6, r14 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r7, r13 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r8, r12 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r9, r21 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r25 \n\t" \ + "adc r23, r25 \n\t" \ + "st z+, r24 \n\t" \ + \ + "ld r21, y+ \n\t" \ + "ldi r24, 0 \n\t" \ + "mul r10, r21 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r11, r20 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r2, r19 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r3, r18 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r4, r17 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r5, r16 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r6, r15 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r7, r14 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r8, r13 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r9, r12 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r25 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ld r12, y+ \n\t" \ + "ldi r22, 0 \n\t" \ + "mul r10, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r11, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r2, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r3, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r4, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r5, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r6, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r7, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r8, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r9, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r25 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ld r13, y+ \n\t" \ + "ldi r23, 0 \n\t" \ + "mul r10, r13 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r11, r12 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r2, r21 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r3, r20 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r4, r19 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r5, r18 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r6, r17 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r7, r16 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r8, r15 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r9, r14 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r25 \n\t" \ + "adc r23, r25 \n\t" \ + "st z+, r24 \n\t" \ + \ + "ld r14, y+ \n\t" \ + "ldi r24, 0 \n\t" \ + "mul r10, r14 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r11, r13 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r2, r12 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r3, r21 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r4, r20 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r5, r19 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r6, r18 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r7, r17 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r8, r16 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r9, r15 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r25 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ld r15, y+ \n\t" \ + "ldi r22, 0 \n\t" \ + "mul r10, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r11, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r2, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r3, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r4, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r5, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r6, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r7, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r8, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r9, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r25 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ld r16, y+ \n\t" \ + "ldi r23, 0 \n\t" \ + "mul r10, r16 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r11, r15 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r2, r14 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r3, r13 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r4, r12 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r5, r21 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r6, r20 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r7, r19 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r8, r18 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r9, r17 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r25 \n\t" \ + "adc r23, r25 \n\t" \ + "st z+, r24 \n\t" \ + \ + "ld r17, y+ \n\t" \ + "ldi r24, 0 \n\t" \ + "mul r10, r17 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r11, r16 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r2, r15 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r3, r14 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r4, r13 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r5, r12 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r6, r21 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r7, r20 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r8, r19 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r9, r18 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r25 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ld r18, y+ \n\t" \ + "ldi r22, 0 \n\t" \ + "mul r10, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r11, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r2, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r3, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r4, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r5, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r6, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r7, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r8, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r9, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r25 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ld r19, y+ \n\t" \ + "ldi r23, 0 \n\t" \ + "mul r10, r19 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r11, r18 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r2, r17 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r3, r16 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r4, r15 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r5, r14 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r6, r13 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r7, r12 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r8, r21 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r9, r20 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r25 \n\t" \ + "adc r23, r25 \n\t" \ + "st z+, r24 \n\t" \ + \ + "ldi r24, 0 \n\t" \ + "mul r11, r19 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r2, r18 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r3, r17 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r4, r16 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r5, r15 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r6, r14 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r7, r13 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r8, r12 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r9, r21 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ldi r22, 0 \n\t" \ + "mul r2, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r3, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r4, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r5, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r6, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r7, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r8, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r9, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r23, 0 \n\t" \ + "mul r3, r19 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r4, r18 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r5, r17 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r6, r16 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r7, r15 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r8, r14 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r9, r13 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "st z+, r24 \n\t" \ + \ + "ldi r24, 0 \n\t" \ + "mul r4, r19 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r5, r18 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r6, r17 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r7, r16 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r8, r15 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r9, r14 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ldi r22, 0 \n\t" \ + "mul r5, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r6, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r7, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r8, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r9, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r23, 0 \n\t" \ + "mul r6, r19 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r7, r18 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r8, r17 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r9, r16 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "st z+, r24 \n\t" \ + \ + "ldi r24, 0 \n\t" \ + "mul r7, r19 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r8, r18 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r9, r17 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ldi r22, 0 \n\t" \ + "mul r8, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r9, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "mul r9, r19 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "st z+, r24 \n\t" \ + "st z+, r22 \n\t" + +#define FAST_MULT_ASM_28_TO_32 \ + "cpi r18, 28 \n\t" \ + "brne 1f \n\t" \ + "jmp 2f \n\t" \ + "1: \n\t" \ + "ld r2, x+ \n\t" \ + "ld r6, y+ \n\t" \ + "ld r3, x+ \n\t" \ + "ld r7, y+ \n\t" \ + "ld r4, x+ \n\t" \ + "ld r8, y+ \n\t" \ + "ld r5, x+ \n\t" \ + "ld r9, y+ \n\t" \ + "sbiw r26, 32 \n\t" \ + "sbiw r28, 32 \n\t" \ + "sbiw r30, 28 \n\t" \ + "ld r10, x+ \n\t" \ + "ld r14, y+ \n\t" \ + "ld r11, x+ \n\t" \ + "ld r15, y+ \n\t" \ + "ld r12, x+ \n\t" \ + "ld r16, y+ \n\t" \ + "ld r13, x+ \n\t" \ + "ld r17, y+ \n\t" \ + \ + "mul r2, r14 \n\t" \ + "mov r19, r0 \n\t" \ + "mov r20, r1 \n\t" \ + "ldi r21, 0 \n\t" \ + "ld r0, z \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r6, r10 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "st z+, r19 \n\t" \ + \ + "ldi r19, 0 \n\t" \ + "ld r0, z \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r2, r15 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r6, r11 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r3, r14 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r7, r10 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "st z+, r20 \n\t" \ + \ + "ldi r20, 0 \n\t" \ + "ld r0, z \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r2, r16 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r6, r12 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r3, r15 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r7, r11 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r4, r14 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r8, r10 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "st z+, r21 \n\t" \ + \ + "ldi r21, 0 \n\t" \ + "ld r0, z \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r2, r17 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r6, r13 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r3, r16 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r7, r12 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r4, r15 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r8, r11 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r5, r14 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r9, r10 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "st z+, r19 \n\t" \ + \ + "ldi r19, 0 \n\t" \ + "ld r0, z \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r25 \n\t" \ + "ld r10, x+ \n\t" \ + "ld r14, y+ \n\t" \ + "mul r2, r14 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r6, r10 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r3, r17 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r7, r13 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r4, r16 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r8, r12 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r5, r15 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r9, r11 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "st z+, r20 \n\t" \ + \ + "ldi r20, 0 \n\t" \ + "ld r0, z \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r25 \n\t" \ + "ld r11, x+ \n\t" \ + "ld r15, y+ \n\t" \ + "mul r2, r15 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r6, r11 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r3, r14 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r7, r10 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r4, r17 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r8, r13 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r5, r16 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r9, r12 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "st z+, r21 \n\t" \ + \ + "ldi r21, 0 \n\t" \ + "ld r0, z \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r25 \n\t" \ + "ld r12, x+ \n\t" \ + "ld r16, y+ \n\t" \ + "mul r2, r16 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r6, r12 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r3, r15 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r7, r11 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r4, r14 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r8, r10 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r5, r17 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r9, r13 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "st z+, r19 \n\t" \ + \ + "ldi r19, 0 \n\t" \ + "ld r0, z \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r25 \n\t" \ + "ld r13, x+ \n\t" \ + "ld r17, y+ \n\t" \ + "mul r2, r17 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r6, r13 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r3, r16 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r7, r12 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r4, r15 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r8, r11 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r5, r14 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r9, r10 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "st z+, r20 \n\t" \ + \ + "ldi r20, 0 \n\t" \ + "ld r0, z \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r25 \n\t" \ + "ld r10, x+ \n\t" \ + "ld r14, y+ \n\t" \ + "mul r2, r14 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r6, r10 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r3, r17 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r7, r13 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r4, r16 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r8, r12 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r5, r15 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r9, r11 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "st z+, r21 \n\t" \ + \ + "ldi r21, 0 \n\t" \ + "ld r0, z \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r25 \n\t" \ + "ld r11, x+ \n\t" \ + "ld r15, y+ \n\t" \ + "mul r2, r15 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r6, r11 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r3, r14 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r7, r10 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r4, r17 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r8, r13 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r5, r16 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r9, r12 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "st z+, r19 \n\t" \ + \ + "ldi r19, 0 \n\t" \ + "ld r0, z \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r25 \n\t" \ + "ld r12, x+ \n\t" \ + "ld r16, y+ \n\t" \ + "mul r2, r16 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r6, r12 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r3, r15 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r7, r11 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r4, r14 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r8, r10 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r5, r17 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r9, r13 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "st z+, r20 \n\t" \ + \ + "ldi r20, 0 \n\t" \ + "ld r0, z \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r25 \n\t" \ + "ld r13, x+ \n\t" \ + "ld r17, y+ \n\t" \ + "mul r2, r17 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r6, r13 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r3, r16 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r7, r12 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r4, r15 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r8, r11 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r5, r14 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r9, r10 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "st z+, r21 \n\t" \ + \ + "ldi r21, 0 \n\t" \ + "ld r0, z \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r25 \n\t" \ + "ld r10, x+ \n\t" \ + "ld r14, y+ \n\t" \ + "mul r2, r14 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r6, r10 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r3, r17 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r7, r13 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r4, r16 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r8, r12 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r5, r15 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r9, r11 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "st z+, r19 \n\t" \ + \ + "ldi r19, 0 \n\t" \ + "ld r0, z \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r25 \n\t" \ + "ld r11, x+ \n\t" \ + "ld r15, y+ \n\t" \ + "mul r2, r15 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r6, r11 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r3, r14 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r7, r10 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r4, r17 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r8, r13 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r5, r16 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r9, r12 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "st z+, r20 \n\t" \ + \ + "ldi r20, 0 \n\t" \ + "ld r0, z \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r25 \n\t" \ + "ld r12, x+ \n\t" \ + "ld r16, y+ \n\t" \ + "mul r2, r16 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r6, r12 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r3, r15 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r7, r11 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r4, r14 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r8, r10 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r5, r17 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r9, r13 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "st z+, r21 \n\t" \ + \ + "ldi r21, 0 \n\t" \ + "ld r0, z \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r25 \n\t" \ + "ld r13, x+ \n\t" \ + "ld r17, y+ \n\t" \ + "mul r2, r17 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r6, r13 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r3, r16 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r7, r12 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r4, r15 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r8, r11 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r5, r14 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r9, r10 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "st z+, r19 \n\t" \ + \ + "ldi r19, 0 \n\t" \ + "ld r0, z \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r25 \n\t" \ + "ld r10, x+ \n\t" \ + "ld r14, y+ \n\t" \ + "mul r2, r14 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r6, r10 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r3, r17 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r7, r13 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r4, r16 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r8, r12 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r5, r15 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r9, r11 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "st z+, r20 \n\t" \ + \ + "ldi r20, 0 \n\t" \ + "ld r0, z \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r25 \n\t" \ + "ld r11, x+ \n\t" \ + "ld r15, y+ \n\t" \ + "mul r2, r15 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r6, r11 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r3, r14 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r7, r10 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r4, r17 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r8, r13 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r5, r16 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r9, r12 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "st z+, r21 \n\t" \ + \ + "ldi r21, 0 \n\t" \ + "ld r0, z \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r25 \n\t" \ + "ld r12, x+ \n\t" \ + "ld r16, y+ \n\t" \ + "mul r2, r16 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r6, r12 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r3, r15 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r7, r11 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r4, r14 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r8, r10 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r5, r17 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r9, r13 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "st z+, r19 \n\t" \ + \ + "ldi r19, 0 \n\t" \ + "ld r0, z \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r25 \n\t" \ + "ld r13, x+ \n\t" \ + "ld r17, y+ \n\t" \ + "mul r2, r17 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r6, r13 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r3, r16 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r7, r12 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r4, r15 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r8, r11 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r5, r14 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r9, r10 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "st z+, r20 \n\t" \ + \ + "ldi r20, 0 \n\t" \ + "ld r0, z \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r25 \n\t" \ + "ld r10, x+ \n\t" \ + "ld r14, y+ \n\t" \ + "mul r2, r14 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r6, r10 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r3, r17 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r7, r13 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r4, r16 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r8, r12 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r5, r15 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r9, r11 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "st z+, r21 \n\t" \ + \ + "ldi r21, 0 \n\t" \ + "ld r0, z \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r25 \n\t" \ + "ld r11, x+ \n\t" \ + "ld r15, y+ \n\t" \ + "mul r2, r15 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r6, r11 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r3, r14 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r7, r10 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r4, r17 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r8, r13 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r5, r16 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r9, r12 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "st z+, r19 \n\t" \ + \ + "ldi r19, 0 \n\t" \ + "ld r0, z \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r25 \n\t" \ + "ld r12, x+ \n\t" \ + "ld r16, y+ \n\t" \ + "mul r2, r16 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r6, r12 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r3, r15 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r7, r11 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r4, r14 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r8, r10 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r5, r17 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r9, r13 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "st z+, r20 \n\t" \ + \ + "ldi r20, 0 \n\t" \ + "ld r0, z \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r25 \n\t" \ + "ld r13, x+ \n\t" \ + "ld r17, y+ \n\t" \ + "mul r2, r17 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r6, r13 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r3, r16 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r7, r12 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r4, r15 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r8, r11 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r5, r14 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r9, r10 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "st z+, r21 \n\t" \ + \ + "ldi r21, 0 \n\t" \ + "ld r0, z \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r25 \n\t" \ + "ld r10, x+ \n\t" \ + "ld r14, y+ \n\t" \ + "mul r2, r14 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r6, r10 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r3, r17 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r7, r13 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r4, r16 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r8, r12 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r5, r15 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r9, r11 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "st z+, r19 \n\t" \ + \ + "ldi r19, 0 \n\t" \ + "ld r0, z \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r25 \n\t" \ + "ld r11, x+ \n\t" \ + "ld r15, y+ \n\t" \ + "mul r2, r15 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r6, r11 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r3, r14 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r7, r10 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r4, r17 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r8, r13 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r5, r16 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r9, r12 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "st z+, r20 \n\t" \ + \ + "ldi r20, 0 \n\t" \ + "ld r0, z \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r25 \n\t" \ + "ld r12, x+ \n\t" \ + "ld r16, y+ \n\t" \ + "mul r2, r16 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r6, r12 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r3, r15 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r7, r11 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r4, r14 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r8, r10 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r5, r17 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r9, r13 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "st z+, r21 \n\t" \ + \ + "ldi r21, 0 \n\t" \ + "ld r0, z \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r25 \n\t" \ + "ld r13, x+ \n\t" \ + "ld r17, y+ \n\t" \ + "mul r2, r17 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r6, r13 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r3, r16 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r7, r12 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r4, r15 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r8, r11 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r5, r14 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r9, r10 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "st z+, r19 \n\t" \ + \ + "ldi r19, 0 \n\t" \ + "mul r11, r9 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r12, r8 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r13, r7 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r2, r6 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r3, r17 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r4, r16 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r5, r15 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "st z+, r20 \n\t" \ + \ + "ldi r20, 0 \n\t" \ + "mul r12, r9 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r13, r8 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r2, r7 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r3, r6 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r4, r17 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r5, r16 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "st z+, r21 \n\t" \ + \ + "ldi r21, 0 \n\t" \ + "mul r13, r9 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r2, r8 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r3, r7 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r4, r6 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r5, r17 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "st z+, r19 \n\t" \ + \ + "ldi r19, 0 \n\t" \ + "mul r2, r9 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r3, r8 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r4, r7 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r5, r6 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "st z+, r20 \n\t" \ + \ + "ldi r20, 0 \n\t" \ + "mul r3, r9 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r4, r8 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r5, r7 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "st z+, r21 \n\t" \ + \ + "ldi r21, 0 \n\t" \ + "mul r4, r9 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r5, r8 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "st z+, r19 \n\t" \ + \ + "mul r5, r9 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "st z+, r20 \n\t" \ + "st z+, r21 \n\t" + /* Not necessary to move ptrs since we don't support sizes > 32 */ + +#define FAST_MULT_ASM_32 \ + "adiw r30, 30 \n\t" \ + "adiw r28, 30 \n\t" \ + "ld r2, x+ \n\t" \ + "ld r3, x+ \n\t" \ + "ld r12, y+ \n\t" \ + "ld r13, y+ \n\t" \ + "ldi r25, 0 \n\t" \ + \ + "ldi r23, 0 \n\t" \ + "mul r2, r12 \n\t" \ + "st z+, r0 \n\t" \ + "mov r22, r1 \n\t" \ + \ + "ldi r24, 0 \n\t" \ + "mul r2, r13 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "mul r3, r12 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "mul r3, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "st z+, r23 \n\t" \ + "st z+, r24 \n\t" \ + \ + "sbiw r30, 14 \n\t" \ + "sbiw r28, 12 \n\t" \ + "ld r12, y+ \n\t" \ + "ld r13, y+ \n\t" \ + "ld r14, y+ \n\t" \ + "ld r15, y+ \n\t" \ + "ld r16, y+ \n\t" \ + "ld r17, y+ \n\t" \ + "ld r18, y+ \n\t" \ + "ld r19, y+ \n\t" \ + "ld r20, y+ \n\t" \ + "ld r21, y+ \n\t" \ + "ld r4, x+ \n\t" \ + "ld r5, x+ \n\t" \ + "ld r6, x+ \n\t" \ + "ld r7, x+ \n\t" \ + "ld r8, x+ \n\t" \ + "ld r9, x+ \n\t" \ + "ld r10, x+ \n\t" \ + "ld r11, x+ \n\t" \ + \ + "ldi r23, 0 \n\t" \ + "mul r2, r12 \n\t" \ + "st z+, r0 \n\t" \ + "mov r22, r1 \n\t" \ + \ + "ldi r24, 0 \n\t" \ + "mul r2, r13 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "mul r3, r12 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ldi r22, 0 \n\t" \ + "mul r2, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r3, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r4, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r23, 0 \n\t" \ + "mul r2, r15 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r3, r14 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r4, r13 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r5, r12 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "st z+, r24 \n\t" \ + \ + "ldi r24, 0 \n\t" \ + "mul r2, r16 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r3, r15 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r4, r14 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r5, r13 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r6, r12 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ldi r22, 0 \n\t" \ + "mul r2, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r3, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r4, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r5, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r6, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r7, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r23, 0 \n\t" \ + "mul r2, r18 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r3, r17 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r4, r16 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r5, r15 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r6, r14 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r7, r13 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r8, r12 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "st z+, r24 \n\t" \ + \ + "ldi r24, 0 \n\t" \ + "mul r2, r19 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r3, r18 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r4, r17 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r5, r16 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r6, r15 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r7, r14 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r8, r13 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r9, r12 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ldi r22, 0 \n\t" \ + "mul r2, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r3, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r4, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r5, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r6, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r7, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r8, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r9, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r10, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r23, 0 \n\t" \ + "mul r2, r21 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r3, r20 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r4, r19 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r5, r18 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r6, r17 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r7, r16 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r8, r15 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r9, r14 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r10, r13 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r11, r12 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "st z+, r24 \n\t" \ + \ + "ld r2, x+ \n\t" \ + "ldi r24, 0 \n\t" \ + "mul r3, r21 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r4, r20 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r5, r19 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r6, r18 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r7, r17 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r8, r16 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r9, r15 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r10, r14 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r11, r13 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r2, r12 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r25 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ld r3, x+ \n\t" \ + "ldi r22, 0 \n\t" \ + "mul r4, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r5, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r6, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r7, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r8, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r9, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r10, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r11, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r2, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r3, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r25 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ld r12, y+ \n\t" \ + "ldi r23, 0 \n\t" \ + "mul r4, r12 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r5, r21 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r6, r20 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r7, r19 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r8, r18 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r9, r17 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r10, r16 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r11, r15 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r2, r14 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r3, r13 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r25 \n\t" \ + "adc r23, r25 \n\t" \ + "st z+, r24 \n\t" \ + \ + "ld r13, y+ \n\t" \ + "ldi r24, 0 \n\t" \ + "mul r4, r13 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r5, r12 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r6, r21 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r7, r20 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r8, r19 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r9, r18 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r10, r17 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r11, r16 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r2, r15 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r3, r14 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r25 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ldi r22, 0 \n\t" \ + "mul r5, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r6, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r7, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r8, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r9, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r10, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r11, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r2, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r3, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r23, 0 \n\t" \ + "mul r6, r13 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r7, r12 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r8, r21 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r9, r20 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r10, r19 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r11, r18 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r2, r17 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r3, r16 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "st z+, r24 \n\t" \ + \ + "ldi r24, 0 \n\t" \ + "mul r7, r13 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r8, r12 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r9, r21 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r10, r20 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r11, r19 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r2, r18 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r3, r17 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ldi r22, 0 \n\t" \ + "mul r8, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r9, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r10, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r11, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r2, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r3, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r23, 0 \n\t" \ + "mul r9, r13 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r10, r12 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r11, r21 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r2, r20 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r3, r19 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "st z+, r24 \n\t" \ + \ + "ldi r24, 0 \n\t" \ + "mul r10, r13 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r11, r12 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r2, r21 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r3, r20 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ldi r22, 0 \n\t" \ + "mul r11, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r2, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r3, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r23, 0 \n\t" \ + "mul r2, r13 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r3, r12 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "st z+, r24 \n\t" \ + \ + "mul r3, r13 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "st z+, r22 \n\t" \ + "st z+, r23 \n\t" \ + \ + "sbiw r30, 34 \n\t" \ + "sbiw r28, 22 \n\t" \ + "sbiw r26, 12 \n\t" \ + "ld r2, x+ \n\t" \ + "ld r12, y+ \n\t" \ + "ld r3, x+ \n\t" \ + "ld r13, y+ \n\t" \ + "ld r4, x+ \n\t" \ + "ld r14, y+ \n\t" \ + "ld r5, x+ \n\t" \ + "ld r15, y+ \n\t" \ + "ld r6, x+ \n\t" \ + "ld r16, y+ \n\t" \ + "ld r7, x+ \n\t" \ + "ld r17, y+ \n\t" \ + "ld r8, x+ \n\t" \ + "ld r18, y+ \n\t" \ + "ld r9, x+ \n\t" \ + "ld r19, y+ \n\t" \ + "ld r10, x+ \n\t" \ + "ld r20, y+ \n\t" \ + "ld r11, x+ \n\t" \ + "ld r21, y+ \n\t" \ + \ + "ldi r23, 0 \n\t" \ + "mul r2, r12 \n\t" \ + "st z+, r0 \n\t" \ + "mov r22, r1 \n\t" \ + \ + "ldi r24, 0 \n\t" \ + "mul r2, r13 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "mul r3, r12 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ldi r22, 0 \n\t" \ + "mul r2, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r3, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r4, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r23, 0 \n\t" \ + "mul r2, r15 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r3, r14 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r4, r13 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r5, r12 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "st z+, r24 \n\t" \ + \ + "ldi r24, 0 \n\t" \ + "mul r2, r16 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r3, r15 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r4, r14 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r5, r13 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r6, r12 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ldi r22, 0 \n\t" \ + "mul r2, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r3, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r4, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r5, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r6, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r7, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r23, 0 \n\t" \ + "mul r2, r18 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r3, r17 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r4, r16 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r5, r15 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r6, r14 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r7, r13 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r8, r12 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "st z+, r24 \n\t" \ + \ + "ldi r24, 0 \n\t" \ + "mul r2, r19 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r3, r18 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r4, r17 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r5, r16 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r6, r15 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r7, r14 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r8, r13 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r9, r12 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ldi r22, 0 \n\t" \ + "mul r2, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r3, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r4, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r5, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r6, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r7, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r8, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r9, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r10, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r23, 0 \n\t" \ + "mul r2, r21 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r3, r20 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r4, r19 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r5, r18 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r6, r17 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r7, r16 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r8, r15 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r9, r14 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r10, r13 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r11, r12 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "st z+, r24 \n\t" \ + \ + "ld r2, x+ \n\t" \ + "ldi r24, 0 \n\t" \ + "mul r3, r21 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r4, r20 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r5, r19 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r6, r18 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r7, r17 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r8, r16 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r9, r15 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r10, r14 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r11, r13 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r2, r12 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r25 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ld r3, x+ \n\t" \ + "ldi r22, 0 \n\t" \ + "mul r4, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r5, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r6, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r7, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r8, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r9, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r10, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r11, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r2, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r3, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r25 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ld r4, x+ \n\t" \ + "ldi r23, 0 \n\t" \ + "mul r5, r21 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r6, r20 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r7, r19 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r8, r18 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r9, r17 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r10, r16 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r11, r15 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r2, r14 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r3, r13 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r4, r12 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r25 \n\t" \ + "adc r23, r25 \n\t" \ + "st z+, r24 \n\t" \ + \ + "ld r5, x+ \n\t" \ + "ldi r24, 0 \n\t" \ + "mul r6, r21 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r7, r20 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r8, r19 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r9, r18 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r10, r17 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r11, r16 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r2, r15 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r3, r14 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r4, r13 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r5, r12 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r25 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ld r6, x+ \n\t" \ + "ldi r22, 0 \n\t" \ + "mul r7, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r8, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r9, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r10, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r11, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r2, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r3, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r4, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r5, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r6, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r25 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ld r7, x+ \n\t" \ + "ldi r23, 0 \n\t" \ + "mul r8, r21 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r9, r20 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r10, r19 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r11, r18 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r2, r17 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r3, r16 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r4, r15 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r5, r14 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r6, r13 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r7, r12 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r25 \n\t" \ + "adc r23, r25 \n\t" \ + "st z+, r24 \n\t" \ + \ + "ld r8, x+ \n\t" \ + "ldi r24, 0 \n\t" \ + "mul r9, r21 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r10, r20 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r11, r19 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r2, r18 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r3, r17 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r4, r16 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r5, r15 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r6, r14 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r7, r13 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r8, r12 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r25 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ld r9, x+ \n\t" \ + "ldi r22, 0 \n\t" \ + "mul r10, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r11, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r2, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r3, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r4, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r5, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r6, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r7, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r8, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r9, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r25 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ld r10, x+ \n\t" \ + "ldi r23, 0 \n\t" \ + "mul r11, r21 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r2, r20 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r3, r19 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r4, r18 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r5, r17 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r6, r16 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r7, r15 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r8, r14 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r9, r13 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r10, r12 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r25 \n\t" \ + "adc r23, r25 \n\t" \ + "st z+, r24 \n\t" \ + \ + "ld r11, x+ \n\t" \ + "ldi r24, 0 \n\t" \ + "mul r2, r21 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r3, r20 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r4, r19 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r5, r18 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r6, r17 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r7, r16 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r8, r15 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r9, r14 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r10, r13 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r11, r12 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r25 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ld r2, x+ \n\t" \ + "ldi r22, 0 \n\t" \ + "mul r3, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r4, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r5, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r6, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r7, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r8, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r9, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r10, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r11, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r2, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r25 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ld r3, x+ \n\t" \ + "ldi r23, 0 \n\t" \ + "mul r4, r21 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r5, r20 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r6, r19 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r7, r18 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r8, r17 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r9, r16 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r10, r15 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r11, r14 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r2, r13 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r3, r12 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r25 \n\t" \ + "adc r23, r25 \n\t" \ + "st z+, r24 \n\t" \ + \ + "ld r12, y+ \n\t" \ + "ldi r24, 0 \n\t" \ + "mul r4, r12 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r5, r21 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r6, r20 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r7, r19 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r8, r18 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r9, r17 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r10, r16 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r11, r15 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r2, r14 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r3, r13 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r25 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ld r13, y+ \n\t" \ + "ldi r22, 0 \n\t" \ + "mul r4, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r5, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r6, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r7, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r8, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r9, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r10, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r11, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r2, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r3, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r25 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ld r14, y+ \n\t" \ + "ldi r23, 0 \n\t" \ + "mul r4, r14 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r5, r13 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r6, r12 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r7, r21 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r8, r20 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r9, r19 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r10, r18 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r11, r17 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r2, r16 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r3, r15 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r25 \n\t" \ + "adc r23, r25 \n\t" \ + "st z+, r24 \n\t" \ + \ + "ld r15, y+ \n\t" \ + "ldi r24, 0 \n\t" \ + "mul r4, r15 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r5, r14 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r6, r13 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r7, r12 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r8, r21 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r9, r20 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r10, r19 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r11, r18 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r2, r17 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r3, r16 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r25 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ld r16, y+ \n\t" \ + "ldi r22, 0 \n\t" \ + "mul r4, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r5, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r6, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r7, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r8, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r9, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r10, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r11, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r2, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r3, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r25 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ld r17, y+ \n\t" \ + "ldi r23, 0 \n\t" \ + "mul r4, r17 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r5, r16 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r6, r15 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r7, r14 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r8, r13 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r9, r12 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r10, r21 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r11, r20 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r2, r19 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r3, r18 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r25 \n\t" \ + "adc r23, r25 \n\t" \ + "st z+, r24 \n\t" \ + \ + "ld r18, y+ \n\t" \ + "ldi r24, 0 \n\t" \ + "mul r4, r18 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r5, r17 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r6, r16 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r7, r15 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r8, r14 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r9, r13 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r10, r12 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r11, r21 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r2, r20 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r3, r19 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r25 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ld r19, y+ \n\t" \ + "ldi r22, 0 \n\t" \ + "mul r4, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r5, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r6, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r7, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r8, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r9, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r10, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r11, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r2, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r3, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r25 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ld r20, y+ \n\t" \ + "ldi r23, 0 \n\t" \ + "mul r4, r20 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r5, r19 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r6, r18 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r7, r17 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r8, r16 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r9, r15 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r10, r14 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r11, r13 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r2, r12 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r3, r21 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r25 \n\t" \ + "adc r23, r25 \n\t" \ + "st z+, r24 \n\t" \ + \ + "ld r21, y+ \n\t" \ + "ldi r24, 0 \n\t" \ + "mul r4, r21 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r5, r20 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r6, r19 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r7, r18 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r8, r17 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r9, r16 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r10, r15 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r11, r14 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r2, r13 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r3, r12 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r25 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ld r12, y+ \n\t" \ + "ldi r22, 0 \n\t" \ + "mul r4, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r5, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r6, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r7, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r8, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r9, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r10, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r11, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r2, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r3, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r25 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ld r13, y+ \n\t" \ + "ldi r23, 0 \n\t" \ + "mul r4, r13 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r5, r12 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r6, r21 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r7, r20 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r8, r19 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r9, r18 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r10, r17 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r11, r16 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r2, r15 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r3, r14 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r25 \n\t" \ + "adc r23, r25 \n\t" \ + "st z+, r24 \n\t" \ + \ + "ldi r24, 0 \n\t" \ + "mul r5, r13 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r6, r12 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r7, r21 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r8, r20 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r9, r19 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r10, r18 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r11, r17 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r2, r16 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r3, r15 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ldi r22, 0 \n\t" \ + "mul r6, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r7, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r8, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r9, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r10, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r11, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r2, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r3, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r23, 0 \n\t" \ + "mul r7, r13 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r8, r12 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r9, r21 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r10, r20 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r11, r19 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r2, r18 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r3, r17 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "st z+, r24 \n\t" \ + \ + "ldi r24, 0 \n\t" \ + "mul r8, r13 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r9, r12 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r10, r21 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r11, r20 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r2, r19 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r3, r18 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ldi r22, 0 \n\t" \ + "mul r9, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r10, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r11, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r2, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r3, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r23, 0 \n\t" \ + "mul r10, r13 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r11, r12 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r2, r21 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r3, r20 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "st z+, r24 \n\t" \ + \ + "ldi r24, 0 \n\t" \ + "mul r11, r13 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r2, r12 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r3, r21 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ldi r22, 0 \n\t" \ + "mul r2, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r3, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "mul r3, r13 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "st z+, r24 \n\t" \ + "st z+, r22 \n\t" \ + \ + "sbiw r30, 54 \n\t" \ + "sbiw r28, 32 \n\t" \ + "sbiw r26, 22 \n\t" \ + "ld r2, x+ \n\t" \ + "ld r12, y+ \n\t" \ + "ld r3, x+ \n\t" \ + "ld r13, y+ \n\t" \ + "ld r4, x+ \n\t" \ + "ld r14, y+ \n\t" \ + "ld r5, x+ \n\t" \ + "ld r15, y+ \n\t" \ + "ld r6, x+ \n\t" \ + "ld r16, y+ \n\t" \ + "ld r7, x+ \n\t" \ + "ld r17, y+ \n\t" \ + "ld r8, x+ \n\t" \ + "ld r18, y+ \n\t" \ + "ld r9, x+ \n\t" \ + "ld r19, y+ \n\t" \ + "ld r10, x+ \n\t" \ + "ld r20, y+ \n\t" \ + "ld r11, x+ \n\t" \ + "ld r21, y+ \n\t" \ + \ + "ldi r23, 0 \n\t" \ + "mul r2, r12 \n\t" \ + "st z+, r0 \n\t" \ + "mov r22, r1 \n\t" \ + \ + "ldi r24, 0 \n\t" \ + "mul r2, r13 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "mul r3, r12 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ldi r22, 0 \n\t" \ + "mul r2, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r3, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r4, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r23, 0 \n\t" \ + "mul r2, r15 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r3, r14 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r4, r13 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r5, r12 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "st z+, r24 \n\t" \ + \ + "ldi r24, 0 \n\t" \ + "mul r2, r16 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r3, r15 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r4, r14 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r5, r13 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r6, r12 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ldi r22, 0 \n\t" \ + "mul r2, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r3, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r4, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r5, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r6, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r7, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r23, 0 \n\t" \ + "mul r2, r18 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r3, r17 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r4, r16 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r5, r15 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r6, r14 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r7, r13 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r8, r12 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "st z+, r24 \n\t" \ + \ + "ldi r24, 0 \n\t" \ + "mul r2, r19 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r3, r18 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r4, r17 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r5, r16 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r6, r15 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r7, r14 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r8, r13 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r9, r12 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ldi r22, 0 \n\t" \ + "mul r2, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r3, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r4, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r5, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r6, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r7, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r8, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r9, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r10, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r23, 0 \n\t" \ + "mul r2, r21 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r3, r20 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r4, r19 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r5, r18 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r6, r17 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r7, r16 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r8, r15 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r9, r14 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r10, r13 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r11, r12 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "st z+, r24 \n\t" \ + \ + "ld r2, x+ \n\t" \ + "ldi r24, 0 \n\t" \ + "mul r3, r21 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r4, r20 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r5, r19 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r6, r18 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r7, r17 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r8, r16 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r9, r15 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r10, r14 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r11, r13 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r2, r12 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r25 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ld r3, x+ \n\t" \ + "ldi r22, 0 \n\t" \ + "mul r4, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r5, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r6, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r7, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r8, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r9, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r10, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r11, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r2, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r3, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r25 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ld r4, x+ \n\t" \ + "ldi r23, 0 \n\t" \ + "mul r5, r21 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r6, r20 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r7, r19 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r8, r18 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r9, r17 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r10, r16 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r11, r15 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r2, r14 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r3, r13 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r4, r12 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r25 \n\t" \ + "adc r23, r25 \n\t" \ + "st z+, r24 \n\t" \ + \ + "ld r5, x+ \n\t" \ + "ldi r24, 0 \n\t" \ + "mul r6, r21 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r7, r20 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r8, r19 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r9, r18 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r10, r17 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r11, r16 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r2, r15 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r3, r14 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r4, r13 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r5, r12 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r25 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ld r6, x+ \n\t" \ + "ldi r22, 0 \n\t" \ + "mul r7, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r8, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r9, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r10, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r11, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r2, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r3, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r4, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r5, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r6, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r25 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ld r7, x+ \n\t" \ + "ldi r23, 0 \n\t" \ + "mul r8, r21 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r9, r20 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r10, r19 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r11, r18 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r2, r17 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r3, r16 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r4, r15 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r5, r14 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r6, r13 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r7, r12 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r25 \n\t" \ + "adc r23, r25 \n\t" \ + "st z+, r24 \n\t" \ + \ + "ld r8, x+ \n\t" \ + "ldi r24, 0 \n\t" \ + "mul r9, r21 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r10, r20 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r11, r19 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r2, r18 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r3, r17 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r4, r16 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r5, r15 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r6, r14 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r7, r13 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r8, r12 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r25 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ld r9, x+ \n\t" \ + "ldi r22, 0 \n\t" \ + "mul r10, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r11, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r2, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r3, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r4, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r5, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r6, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r7, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r8, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r9, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r25 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ld r10, x+ \n\t" \ + "ldi r23, 0 \n\t" \ + "mul r11, r21 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r2, r20 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r3, r19 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r4, r18 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r5, r17 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r6, r16 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r7, r15 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r8, r14 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r9, r13 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r10, r12 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r25 \n\t" \ + "adc r23, r25 \n\t" \ + "st z+, r24 \n\t" \ + \ + "ld r11, x+ \n\t" \ + "ldi r24, 0 \n\t" \ + "mul r2, r21 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r3, r20 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r4, r19 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r5, r18 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r6, r17 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r7, r16 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r8, r15 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r9, r14 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r10, r13 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r11, r12 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r25 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ld r2, x+ \n\t" \ + "ldi r22, 0 \n\t" \ + "mul r3, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r4, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r5, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r6, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r7, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r8, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r9, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r10, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r11, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r2, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r25 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ld r3, x+ \n\t" \ + "ldi r23, 0 \n\t" \ + "mul r4, r21 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r5, r20 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r6, r19 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r7, r18 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r8, r17 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r9, r16 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r10, r15 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r11, r14 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r2, r13 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r3, r12 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r25 \n\t" \ + "adc r23, r25 \n\t" \ + "st z+, r24 \n\t" \ + \ + "ld r4, x+ \n\t" \ + "ldi r24, 0 \n\t" \ + "mul r5, r21 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r6, r20 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r7, r19 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r8, r18 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r9, r17 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r10, r16 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r11, r15 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r2, r14 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r3, r13 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r4, r12 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r25 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ld r5, x+ \n\t" \ + "ldi r22, 0 \n\t" \ + "mul r6, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r7, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r8, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r9, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r10, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r11, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r2, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r3, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r4, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r5, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r25 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ld r6, x+ \n\t" \ + "ldi r23, 0 \n\t" \ + "mul r7, r21 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r8, r20 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r9, r19 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r10, r18 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r11, r17 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r2, r16 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r3, r15 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r4, r14 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r5, r13 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r6, r12 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r25 \n\t" \ + "adc r23, r25 \n\t" \ + "st z+, r24 \n\t" \ + \ + "ld r7, x+ \n\t" \ + "ldi r24, 0 \n\t" \ + "mul r8, r21 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r9, r20 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r10, r19 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r11, r18 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r2, r17 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r3, r16 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r4, r15 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r5, r14 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r6, r13 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r7, r12 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r25 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ld r8, x+ \n\t" \ + "ldi r22, 0 \n\t" \ + "mul r9, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r10, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r11, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r2, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r3, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r4, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r5, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r6, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r7, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r8, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r25 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ld r9, x+ \n\t" \ + "ldi r23, 0 \n\t" \ + "mul r10, r21 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r11, r20 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r2, r19 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r3, r18 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r4, r17 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r5, r16 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r6, r15 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r7, r14 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r8, r13 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r9, r12 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r25 \n\t" \ + "adc r23, r25 \n\t" \ + "st z+, r24 \n\t" \ + \ + "ld r10, x+ \n\t" \ + "ldi r24, 0 \n\t" \ + "mul r11, r21 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r2, r20 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r3, r19 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r4, r18 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r5, r17 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r6, r16 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r7, r15 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r8, r14 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r9, r13 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r10, r12 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r25 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ld r11, x+ \n\t" \ + "ldi r22, 0 \n\t" \ + "mul r2, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r3, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r4, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r5, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r6, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r7, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r8, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r9, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r10, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r11, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r25 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ld r2, x+ \n\t" \ + "ldi r23, 0 \n\t" \ + "mul r3, r21 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r4, r20 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r5, r19 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r6, r18 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r7, r17 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r8, r16 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r9, r15 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r10, r14 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r11, r13 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r2, r12 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r25 \n\t" \ + "adc r23, r25 \n\t" \ + "st z+, r24 \n\t" \ + \ + "ld r3, x+ \n\t" \ + "ldi r24, 0 \n\t" \ + "mul r4, r21 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r5, r20 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r6, r19 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r7, r18 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r8, r17 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r9, r16 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r10, r15 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r11, r14 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r2, r13 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r3, r12 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r25 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ld r12, y+ \n\t" \ + "ldi r22, 0 \n\t" \ + "mul r4, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r5, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r6, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r7, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r8, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r9, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r10, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r11, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r2, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r3, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r25 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ld r13, y+ \n\t" \ + "ldi r23, 0 \n\t" \ + "mul r4, r13 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r5, r12 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r6, r21 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r7, r20 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r8, r19 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r9, r18 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r10, r17 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r11, r16 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r2, r15 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r3, r14 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r25 \n\t" \ + "adc r23, r25 \n\t" \ + "st z+, r24 \n\t" \ + \ + "ld r14, y+ \n\t" \ + "ldi r24, 0 \n\t" \ + "mul r4, r14 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r5, r13 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r6, r12 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r7, r21 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r8, r20 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r9, r19 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r10, r18 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r11, r17 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r2, r16 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r3, r15 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r25 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ld r15, y+ \n\t" \ + "ldi r22, 0 \n\t" \ + "mul r4, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r5, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r6, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r7, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r8, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r9, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r10, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r11, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r2, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r3, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r25 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ld r16, y+ \n\t" \ + "ldi r23, 0 \n\t" \ + "mul r4, r16 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r5, r15 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r6, r14 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r7, r13 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r8, r12 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r9, r21 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r10, r20 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r11, r19 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r2, r18 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r3, r17 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r25 \n\t" \ + "adc r23, r25 \n\t" \ + "st z+, r24 \n\t" \ + \ + "ld r17, y+ \n\t" \ + "ldi r24, 0 \n\t" \ + "mul r4, r17 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r5, r16 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r6, r15 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r7, r14 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r8, r13 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r9, r12 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r10, r21 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r11, r20 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r2, r19 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r3, r18 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r25 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ld r18, y+ \n\t" \ + "ldi r22, 0 \n\t" \ + "mul r4, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r5, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r6, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r7, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r8, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r9, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r10, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r11, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r2, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r3, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r25 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ld r19, y+ \n\t" \ + "ldi r23, 0 \n\t" \ + "mul r4, r19 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r5, r18 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r6, r17 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r7, r16 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r8, r15 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r9, r14 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r10, r13 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r11, r12 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r2, r21 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r3, r20 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r25 \n\t" \ + "adc r23, r25 \n\t" \ + "st z+, r24 \n\t" \ + \ + "ld r20, y+ \n\t" \ + "ldi r24, 0 \n\t" \ + "mul r4, r20 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r5, r19 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r6, r18 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r7, r17 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r8, r16 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r9, r15 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r10, r14 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r11, r13 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r2, r12 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r3, r21 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r25 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ld r21, y+ \n\t" \ + "ldi r22, 0 \n\t" \ + "mul r4, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r5, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r6, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r7, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r8, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r9, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r10, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r11, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r2, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r3, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r25 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ld r12, y+ \n\t" \ + "ldi r23, 0 \n\t" \ + "mul r4, r12 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r5, r21 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r6, r20 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r7, r19 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r8, r18 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r9, r17 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r10, r16 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r11, r15 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r2, r14 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r3, r13 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r25 \n\t" \ + "adc r23, r25 \n\t" \ + "st z+, r24 \n\t" \ + \ + "ld r13, y+ \n\t" \ + "ldi r24, 0 \n\t" \ + "mul r4, r13 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r5, r12 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r6, r21 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r7, r20 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r8, r19 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r9, r18 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r10, r17 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r11, r16 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r2, r15 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r3, r14 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r25 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ld r14, y+ \n\t" \ + "ldi r22, 0 \n\t" \ + "mul r4, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r5, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r6, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r7, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r8, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r9, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r10, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r11, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r2, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r3, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r25 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ld r15, y+ \n\t" \ + "ldi r23, 0 \n\t" \ + "mul r4, r15 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r5, r14 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r6, r13 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r7, r12 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r8, r21 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r9, r20 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r10, r19 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r11, r18 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r2, r17 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r3, r16 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r25 \n\t" \ + "adc r23, r25 \n\t" \ + "st z+, r24 \n\t" \ + \ + "ld r16, y+ \n\t" \ + "ldi r24, 0 \n\t" \ + "mul r4, r16 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r5, r15 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r6, r14 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r7, r13 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r8, r12 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r9, r21 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r10, r20 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r11, r19 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r2, r18 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r3, r17 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r25 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ld r17, y+ \n\t" \ + "ldi r22, 0 \n\t" \ + "mul r4, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r5, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r6, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r7, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r8, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r9, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r10, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r11, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r2, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r3, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r25 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ld r18, y+ \n\t" \ + "ldi r23, 0 \n\t" \ + "mul r4, r18 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r5, r17 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r6, r16 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r7, r15 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r8, r14 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r9, r13 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r10, r12 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r11, r21 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r2, r20 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r3, r19 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r25 \n\t" \ + "adc r23, r25 \n\t" \ + "st z+, r24 \n\t" \ + \ + "ld r19, y+ \n\t" \ + "ldi r24, 0 \n\t" \ + "mul r4, r19 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r5, r18 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r6, r17 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r7, r16 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r8, r15 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r9, r14 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r10, r13 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r11, r12 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r2, r21 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r3, r20 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r25 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ld r20, y+ \n\t" \ + "ldi r22, 0 \n\t" \ + "mul r4, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r5, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r6, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r7, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r8, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r9, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r10, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r11, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r2, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r3, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r25 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ld r21, y+ \n\t" \ + "ldi r23, 0 \n\t" \ + "mul r4, r21 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r5, r20 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r6, r19 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r7, r18 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r8, r17 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r9, r16 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r10, r15 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r11, r14 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r2, r13 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r3, r12 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r25 \n\t" \ + "adc r23, r25 \n\t" \ + "st z+, r24 \n\t" \ + \ + "ld r12, y+ \n\t" \ + "ldi r24, 0 \n\t" \ + "mul r4, r12 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r5, r21 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r6, r20 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r7, r19 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r8, r18 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r9, r17 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r10, r16 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r11, r15 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r2, r14 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r3, r13 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r25 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ld r13, y+ \n\t" \ + "ldi r22, 0 \n\t" \ + "mul r4, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r5, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r6, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r7, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r8, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r9, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r10, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r11, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r2, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r3, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r25 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r23, 0 \n\t" \ + "mul r5, r13 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r6, r12 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r7, r21 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r8, r20 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r9, r19 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r10, r18 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r11, r17 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r2, r16 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r3, r15 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "st z+, r24 \n\t" \ + \ + "ldi r24, 0 \n\t" \ + "mul r6, r13 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r7, r12 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r8, r21 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r9, r20 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r10, r19 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r11, r18 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r2, r17 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r3, r16 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ldi r22, 0 \n\t" \ + "mul r7, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r8, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r9, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r10, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r11, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r2, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r3, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r23, 0 \n\t" \ + "mul r8, r13 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r9, r12 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r10, r21 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r11, r20 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r2, r19 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r3, r18 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "st z+, r24 \n\t" \ + \ + "ldi r24, 0 \n\t" \ + "mul r9, r13 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r10, r12 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r11, r21 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r2, r20 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r3, r19 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ldi r22, 0 \n\t" \ + "mul r10, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r11, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r2, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r3, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r23, 0 \n\t" \ + "mul r11, r13 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r2, r12 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r3, r21 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "st z+, r24 \n\t" \ + \ + "ldi r24, 0 \n\t" \ + "mul r2, r13 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r3, r12 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "mul r3, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "st z+, r23 \n\t" \ + "st z+, r24 \n\t" + +#define FAST_SQUARE_ASM_20 \ + "ld r2, x+ \n\t" \ + "ld r3, x+ \n\t" \ + "ld r4, x+ \n\t" \ + "ld r5, x+ \n\t" \ + "ld r6, x+ \n\t" \ + "ld r7, x+ \n\t" \ + "ld r8, x+ \n\t" \ + "ld r9, x+ \n\t" \ + "ld r10, x+ \n\t" \ + "ld r11, x+ \n\t" \ + "ld r12, x+ \n\t" \ + "ld r13, x+ \n\t" \ + "ld r14, x+ \n\t" \ + "ld r15, x+ \n\t" \ + "ld r16, x+ \n\t" \ + "ld r17, x+ \n\t" \ + "ld r18, x+ \n\t" \ + "ld r19, x+ \n\t" \ + "ld r20, x+ \n\t" \ + "ld r21, x+ \n\t" \ + "push r26 \n\t" \ + "push r27 \n\t" \ + "ldi r25, 0 \n\t" \ + \ + "ldi r23, 0 \n\t" \ + "mul r2, r2 \n\t" \ + "st z+, r0 \n\t" \ + "mov r22, r1 \n\t" \ + \ + "ldi r24, 0 \n\t" \ + "mul r2, r3 \n\t" \ + "lsl r0 \n\t" \ + "rol r1 \n\t" \ + "adc r24, r25 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ldi r22, 0 \n\t" \ + "mul r2, r4 \n\t" \ + "lsl r0 \n\t" \ + "rol r1 \n\t" \ + "adc r22, r25 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r3, r3 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r26, 0 \n\t" \ + "mul r2, r5 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r27, r1 \n\t" \ + "mul r3, r4 \n\t" \ + "add r23, r0 \n\t" \ + "adc r27, r1 \n\t" \ + "adc r26, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r27 \n\t" \ + "rol r26 \n\t" \ + "add r23, r24 \n\t" \ + "adc r27, r22 \n\t" \ + "adc r26, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r22, 0 \n\t" \ + "mul r2, r6 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r24, r1 \n\t" \ + "mul r3, r5 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r24 \n\t" \ + "rol r22 \n\t" \ + "mul r4, r4 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "add r23, r27 \n\t" \ + "adc r24, r26 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r26, 0 \n\t" \ + "mul r2, r7 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r27, r1 \n\t" \ + "mul r3, r6 \n\t" \ + "add r23, r0 \n\t" \ + "adc r27, r1 \n\t" \ + "adc r26, r25 \n\t" \ + "mul r4, r5 \n\t" \ + "add r23, r0 \n\t" \ + "adc r27, r1 \n\t" \ + "adc r26, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r27 \n\t" \ + "rol r26 \n\t" \ + "add r23, r24 \n\t" \ + "adc r27, r22 \n\t" \ + "adc r26, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r22, 0 \n\t" \ + "mul r2, r8 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r24, r1 \n\t" \ + "mul r3, r7 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r4, r6 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r24 \n\t" \ + "rol r22 \n\t" \ + "mul r5, r5 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "add r23, r27 \n\t" \ + "adc r24, r26 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r26, 0 \n\t" \ + "mul r2, r9 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r27, r1 \n\t" \ + "mul r3, r8 \n\t" \ + "add r23, r0 \n\t" \ + "adc r27, r1 \n\t" \ + "adc r26, r25 \n\t" \ + "mul r4, r7 \n\t" \ + "add r23, r0 \n\t" \ + "adc r27, r1 \n\t" \ + "adc r26, r25 \n\t" \ + "mul r5, r6 \n\t" \ + "add r23, r0 \n\t" \ + "adc r27, r1 \n\t" \ + "adc r26, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r27 \n\t" \ + "rol r26 \n\t" \ + "add r23, r24 \n\t" \ + "adc r27, r22 \n\t" \ + "adc r26, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r22, 0 \n\t" \ + "mul r2, r10 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r24, r1 \n\t" \ + "mul r3, r9 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r4, r8 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r5, r7 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r24 \n\t" \ + "rol r22 \n\t" \ + "mul r6, r6 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "add r23, r27 \n\t" \ + "adc r24, r26 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r26, 0 \n\t" \ + "mul r2, r11 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r27, r1 \n\t" \ + "mul r3, r10 \n\t" \ + "add r23, r0 \n\t" \ + "adc r27, r1 \n\t" \ + "adc r26, r25 \n\t" \ + "mul r4, r9 \n\t" \ + "add r23, r0 \n\t" \ + "adc r27, r1 \n\t" \ + "adc r26, r25 \n\t" \ + "mul r5, r8 \n\t" \ + "add r23, r0 \n\t" \ + "adc r27, r1 \n\t" \ + "adc r26, r25 \n\t" \ + "mul r6, r7 \n\t" \ + "add r23, r0 \n\t" \ + "adc r27, r1 \n\t" \ + "adc r26, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r27 \n\t" \ + "rol r26 \n\t" \ + "add r23, r24 \n\t" \ + "adc r27, r22 \n\t" \ + "adc r26, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r22, 0 \n\t" \ + "mul r2, r12 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r24, r1 \n\t" \ + "mul r3, r11 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r4, r10 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r5, r9 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r6, r8 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r24 \n\t" \ + "rol r22 \n\t" \ + "mul r7, r7 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "add r23, r27 \n\t" \ + "adc r24, r26 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r26, 0 \n\t" \ + "mul r2, r13 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r27, r1 \n\t" \ + "mul r3, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r27, r1 \n\t" \ + "adc r26, r25 \n\t" \ + "mul r4, r11 \n\t" \ + "add r23, r0 \n\t" \ + "adc r27, r1 \n\t" \ + "adc r26, r25 \n\t" \ + "mul r5, r10 \n\t" \ + "add r23, r0 \n\t" \ + "adc r27, r1 \n\t" \ + "adc r26, r25 \n\t" \ + "mul r6, r9 \n\t" \ + "add r23, r0 \n\t" \ + "adc r27, r1 \n\t" \ + "adc r26, r25 \n\t" \ + "mul r7, r8 \n\t" \ + "add r23, r0 \n\t" \ + "adc r27, r1 \n\t" \ + "adc r26, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r27 \n\t" \ + "rol r26 \n\t" \ + "add r23, r24 \n\t" \ + "adc r27, r22 \n\t" \ + "adc r26, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r22, 0 \n\t" \ + "mul r2, r14 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r24, r1 \n\t" \ + "mul r3, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r4, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r5, r11 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r6, r10 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r7, r9 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r24 \n\t" \ + "rol r22 \n\t" \ + "mul r8, r8 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "add r23, r27 \n\t" \ + "adc r24, r26 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r26, 0 \n\t" \ + "mul r2, r15 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r27, r1 \n\t" \ + "mul r3, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r27, r1 \n\t" \ + "adc r26, r25 \n\t" \ + "mul r4, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r27, r1 \n\t" \ + "adc r26, r25 \n\t" \ + "mul r5, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r27, r1 \n\t" \ + "adc r26, r25 \n\t" \ + "mul r6, r11 \n\t" \ + "add r23, r0 \n\t" \ + "adc r27, r1 \n\t" \ + "adc r26, r25 \n\t" \ + "mul r7, r10 \n\t" \ + "add r23, r0 \n\t" \ + "adc r27, r1 \n\t" \ + "adc r26, r25 \n\t" \ + "mul r8, r9 \n\t" \ + "add r23, r0 \n\t" \ + "adc r27, r1 \n\t" \ + "adc r26, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r27 \n\t" \ + "rol r26 \n\t" \ + "add r23, r24 \n\t" \ + "adc r27, r22 \n\t" \ + "adc r26, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r22, 0 \n\t" \ + "mul r2, r16 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r24, r1 \n\t" \ + "mul r3, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r4, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r5, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r6, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r7, r11 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r8, r10 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r24 \n\t" \ + "rol r22 \n\t" \ + "mul r9, r9 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "add r23, r27 \n\t" \ + "adc r24, r26 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r26, 0 \n\t" \ + "mul r2, r17 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r27, r1 \n\t" \ + "mul r3, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r27, r1 \n\t" \ + "adc r26, r25 \n\t" \ + "mul r4, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r27, r1 \n\t" \ + "adc r26, r25 \n\t" \ + "mul r5, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r27, r1 \n\t" \ + "adc r26, r25 \n\t" \ + "mul r6, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r27, r1 \n\t" \ + "adc r26, r25 \n\t" \ + "mul r7, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r27, r1 \n\t" \ + "adc r26, r25 \n\t" \ + "mul r8, r11 \n\t" \ + "add r23, r0 \n\t" \ + "adc r27, r1 \n\t" \ + "adc r26, r25 \n\t" \ + "mul r9, r10 \n\t" \ + "add r23, r0 \n\t" \ + "adc r27, r1 \n\t" \ + "adc r26, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r27 \n\t" \ + "rol r26 \n\t" \ + "add r23, r24 \n\t" \ + "adc r27, r22 \n\t" \ + "adc r26, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r22, 0 \n\t" \ + "mul r2, r18 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r24, r1 \n\t" \ + "mul r3, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r4, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r5, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r6, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r7, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r8, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r9, r11 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r24 \n\t" \ + "rol r22 \n\t" \ + "mul r10, r10 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "add r23, r27 \n\t" \ + "adc r24, r26 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r26, 0 \n\t" \ + "mul r2, r19 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r27, r1 \n\t" \ + "mul r3, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r27, r1 \n\t" \ + "adc r26, r25 \n\t" \ + "mul r4, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r27, r1 \n\t" \ + "adc r26, r25 \n\t" \ + "mul r5, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r27, r1 \n\t" \ + "adc r26, r25 \n\t" \ + "mul r6, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r27, r1 \n\t" \ + "adc r26, r25 \n\t" \ + "mul r7, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r27, r1 \n\t" \ + "adc r26, r25 \n\t" \ + "mul r8, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r27, r1 \n\t" \ + "adc r26, r25 \n\t" \ + "mul r9, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r27, r1 \n\t" \ + "adc r26, r25 \n\t" \ + "mul r10, r11 \n\t" \ + "add r23, r0 \n\t" \ + "adc r27, r1 \n\t" \ + "adc r26, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r27 \n\t" \ + "rol r26 \n\t" \ + "add r23, r24 \n\t" \ + "adc r27, r22 \n\t" \ + "adc r26, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r22, 0 \n\t" \ + "mul r2, r20 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r24, r1 \n\t" \ + "mul r3, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r4, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r5, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r6, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r7, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r8, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r9, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r10, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r24 \n\t" \ + "rol r22 \n\t" \ + "mul r11, r11 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "add r23, r27 \n\t" \ + "adc r24, r26 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r26, 0 \n\t" \ + "mul r2, r21 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r27, r1 \n\t" \ + "mul r3, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r27, r1 \n\t" \ + "adc r26, r25 \n\t" \ + "mul r4, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r27, r1 \n\t" \ + "adc r26, r25 \n\t" \ + "mul r5, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r27, r1 \n\t" \ + "adc r26, r25 \n\t" \ + "mul r6, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r27, r1 \n\t" \ + "adc r26, r25 \n\t" \ + "mul r7, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r27, r1 \n\t" \ + "adc r26, r25 \n\t" \ + "mul r8, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r27, r1 \n\t" \ + "adc r26, r25 \n\t" \ + "mul r9, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r27, r1 \n\t" \ + "adc r26, r25 \n\t" \ + "mul r10, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r27, r1 \n\t" \ + "adc r26, r25 \n\t" \ + "mul r11, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r27, r1 \n\t" \ + "adc r26, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r27 \n\t" \ + "rol r26 \n\t" \ + "add r23, r24 \n\t" \ + "adc r27, r22 \n\t" \ + "adc r26, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r22, 0 \n\t" \ + "mul r3, r21 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r24, r1 \n\t" \ + "mul r4, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r5, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r6, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r7, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r8, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r9, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r10, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r11, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r24 \n\t" \ + "rol r22 \n\t" \ + "mul r12, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "add r23, r27 \n\t" \ + "adc r24, r26 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r26, 0 \n\t" \ + "mul r4, r21 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r27, r1 \n\t" \ + "mul r5, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r27, r1 \n\t" \ + "adc r26, r25 \n\t" \ + "mul r6, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r27, r1 \n\t" \ + "adc r26, r25 \n\t" \ + "mul r7, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r27, r1 \n\t" \ + "adc r26, r25 \n\t" \ + "mul r8, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r27, r1 \n\t" \ + "adc r26, r25 \n\t" \ + "mul r9, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r27, r1 \n\t" \ + "adc r26, r25 \n\t" \ + "mul r10, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r27, r1 \n\t" \ + "adc r26, r25 \n\t" \ + "mul r11, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r27, r1 \n\t" \ + "adc r26, r25 \n\t" \ + "mul r12, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r27, r1 \n\t" \ + "adc r26, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r27 \n\t" \ + "rol r26 \n\t" \ + "add r23, r24 \n\t" \ + "adc r27, r22 \n\t" \ + "adc r26, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r22, 0 \n\t" \ + "mul r5, r21 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r24, r1 \n\t" \ + "mul r6, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r7, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r8, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r9, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r10, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r11, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r12, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r24 \n\t" \ + "rol r22 \n\t" \ + "mul r13, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "add r23, r27 \n\t" \ + "adc r24, r26 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r26, 0 \n\t" \ + "mul r6, r21 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r27, r1 \n\t" \ + "mul r7, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r27, r1 \n\t" \ + "adc r26, r25 \n\t" \ + "mul r8, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r27, r1 \n\t" \ + "adc r26, r25 \n\t" \ + "mul r9, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r27, r1 \n\t" \ + "adc r26, r25 \n\t" \ + "mul r10, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r27, r1 \n\t" \ + "adc r26, r25 \n\t" \ + "mul r11, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r27, r1 \n\t" \ + "adc r26, r25 \n\t" \ + "mul r12, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r27, r1 \n\t" \ + "adc r26, r25 \n\t" \ + "mul r13, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r27, r1 \n\t" \ + "adc r26, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r27 \n\t" \ + "rol r26 \n\t" \ + "add r23, r24 \n\t" \ + "adc r27, r22 \n\t" \ + "adc r26, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r22, 0 \n\t" \ + "mul r7, r21 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r24, r1 \n\t" \ + "mul r8, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r9, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r10, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r11, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r12, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r13, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r24 \n\t" \ + "rol r22 \n\t" \ + "mul r14, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "add r23, r27 \n\t" \ + "adc r24, r26 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r26, 0 \n\t" \ + "mul r8, r21 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r27, r1 \n\t" \ + "mul r9, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r27, r1 \n\t" \ + "adc r26, r25 \n\t" \ + "mul r10, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r27, r1 \n\t" \ + "adc r26, r25 \n\t" \ + "mul r11, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r27, r1 \n\t" \ + "adc r26, r25 \n\t" \ + "mul r12, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r27, r1 \n\t" \ + "adc r26, r25 \n\t" \ + "mul r13, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r27, r1 \n\t" \ + "adc r26, r25 \n\t" \ + "mul r14, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r27, r1 \n\t" \ + "adc r26, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r27 \n\t" \ + "rol r26 \n\t" \ + "add r23, r24 \n\t" \ + "adc r27, r22 \n\t" \ + "adc r26, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r22, 0 \n\t" \ + "mul r9, r21 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r24, r1 \n\t" \ + "mul r10, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r11, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r12, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r13, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r14, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r24 \n\t" \ + "rol r22 \n\t" \ + "mul r15, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "add r23, r27 \n\t" \ + "adc r24, r26 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r26, 0 \n\t" \ + "mul r10, r21 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r27, r1 \n\t" \ + "mul r11, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r27, r1 \n\t" \ + "adc r26, r25 \n\t" \ + "mul r12, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r27, r1 \n\t" \ + "adc r26, r25 \n\t" \ + "mul r13, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r27, r1 \n\t" \ + "adc r26, r25 \n\t" \ + "mul r14, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r27, r1 \n\t" \ + "adc r26, r25 \n\t" \ + "mul r15, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r27, r1 \n\t" \ + "adc r26, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r27 \n\t" \ + "rol r26 \n\t" \ + "add r23, r24 \n\t" \ + "adc r27, r22 \n\t" \ + "adc r26, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r22, 0 \n\t" \ + "mul r11, r21 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r24, r1 \n\t" \ + "mul r12, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r13, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r14, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r15, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r24 \n\t" \ + "rol r22 \n\t" \ + "mul r16, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "add r23, r27 \n\t" \ + "adc r24, r26 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r26, 0 \n\t" \ + "mul r12, r21 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r27, r1 \n\t" \ + "mul r13, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r27, r1 \n\t" \ + "adc r26, r25 \n\t" \ + "mul r14, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r27, r1 \n\t" \ + "adc r26, r25 \n\t" \ + "mul r15, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r27, r1 \n\t" \ + "adc r26, r25 \n\t" \ + "mul r16, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r27, r1 \n\t" \ + "adc r26, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r27 \n\t" \ + "rol r26 \n\t" \ + "add r23, r24 \n\t" \ + "adc r27, r22 \n\t" \ + "adc r26, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r22, 0 \n\t" \ + "mul r13, r21 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r24, r1 \n\t" \ + "mul r14, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r15, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r16, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r24 \n\t" \ + "rol r22 \n\t" \ + "mul r17, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "add r23, r27 \n\t" \ + "adc r24, r26 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r26, 0 \n\t" \ + "mul r14, r21 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r27, r1 \n\t" \ + "mul r15, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r27, r1 \n\t" \ + "adc r26, r25 \n\t" \ + "mul r16, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r27, r1 \n\t" \ + "adc r26, r25 \n\t" \ + "mul r17, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r27, r1 \n\t" \ + "adc r26, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r27 \n\t" \ + "rol r26 \n\t" \ + "add r23, r24 \n\t" \ + "adc r27, r22 \n\t" \ + "adc r26, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r22, 0 \n\t" \ + "mul r15, r21 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r24, r1 \n\t" \ + "mul r16, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r17, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r24 \n\t" \ + "rol r22 \n\t" \ + "mul r18, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "add r23, r27 \n\t" \ + "adc r24, r26 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r26, 0 \n\t" \ + "mul r16, r21 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r27, r1 \n\t" \ + "mul r17, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r27, r1 \n\t" \ + "adc r26, r25 \n\t" \ + "mul r18, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r27, r1 \n\t" \ + "adc r26, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r27 \n\t" \ + "rol r26 \n\t" \ + "add r23, r24 \n\t" \ + "adc r27, r22 \n\t" \ + "adc r26, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r22, 0 \n\t" \ + "mul r17, r21 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r24, r1 \n\t" \ + "mul r18, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r24 \n\t" \ + "rol r22 \n\t" \ + "mul r19, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "add r23, r27 \n\t" \ + "adc r24, r26 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r26, 0 \n\t" \ + "mul r18, r21 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r27, r1 \n\t" \ + "mul r19, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r27, r1 \n\t" \ + "adc r26, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r27 \n\t" \ + "rol r26 \n\t" \ + "add r23, r24 \n\t" \ + "adc r27, r22 \n\t" \ + "adc r26, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r23, 0 \n\t" \ + "mul r19, r21 \n\t" \ + "lsl r0 \n\t" \ + "rol r1 \n\t" \ + "adc r23, r25 \n\t" \ + "add r27, r0 \n\t" \ + "adc r26, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r20, r20 \n\t" \ + "add r27, r0 \n\t" \ + "adc r26, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "st z+, r27 \n\t" \ + \ + "ldi r27, 0 \n\t" \ + "mul r20, r21 \n\t" \ + "lsl r0 \n\t" \ + "rol r1 \n\t" \ + "adc r27, r25 \n\t" \ + "add r26, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r27, r25 \n\t" \ + "st z+, r26 \n\t" \ + \ + "mul r21, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r27, r1 \n\t" \ + "st z+, r23 \n\t" \ + "st z+, r27 \n\t" \ + "pop r27 \n\t" \ + "pop r26 \n\t" + +#define FAST_SQUARE_ASM_20_TO_24 \ + "cpi r20, 20 \n\t" \ + "brne 1f \n\t" \ + "jmp 2f \n\t" \ + "1: \n\t" \ + "ld r2, x+ \n\t" \ + "ld r3, x+ \n\t" \ + "ld r4, x+ \n\t" \ + "ld r5, x+ \n\t" \ + "sbiw r26, 24 \n\t" \ + "sbiw r30, 20 \n\t" \ + "ld r6, x+ \n\t" \ + "ld r7, x+ \n\t" \ + "ld r8, x+ \n\t" \ + "ld r9, x+ \n\t" \ + \ + "mul r2, r6 \n\t" \ + "mov r10, r0 \n\t" \ + "mov r11, r1 \n\t" \ + "mov r12, r25 \n\t" \ + "mov r13, r25 \n\t" \ + "mul r2, r7 \n\t" \ + "add r11, r0 \n\t" \ + "adc r12, r1 \n\t" \ + "adc r13, r25 \n\t" \ + "mul r3, r6 \n\t" \ + "add r11, r0 \n\t" \ + "adc r12, r1 \n\t" \ + "adc r13, r25 \n\t" \ + \ + "mov r14, r25 \n\t" \ + "mul r2, r8 \n\t" \ + "add r12, r0 \n\t" \ + "adc r13, r1 \n\t" \ + "adc r14, r25 \n\t" \ + "mul r3, r7 \n\t" \ + "add r12, r0 \n\t" \ + "adc r13, r1 \n\t" \ + "adc r14, r25 \n\t" \ + "mul r4, r6 \n\t" \ + "add r12, r0 \n\t" \ + "adc r13, r1 \n\t" \ + "adc r14, r25 \n\t" \ + \ + "mov r15, r25 \n\t" \ + "mul r2, r9 \n\t" \ + "add r13, r0 \n\t" \ + "adc r14, r1 \n\t" \ + "adc r15, r25 \n\t" \ + "mul r3, r8 \n\t" \ + "add r13, r0 \n\t" \ + "adc r14, r1 \n\t" \ + "adc r15, r25 \n\t" \ + "mul r4, r7 \n\t" \ + "add r13, r0 \n\t" \ + "adc r14, r1 \n\t" \ + "adc r15, r25 \n\t" \ + "mul r5, r6 \n\t" \ + "add r13, r0 \n\t" \ + "adc r14, r1 \n\t" \ + "adc r15, r25 \n\t" \ + \ + "ld r6, x+ \n\t" \ + "mov r16, r25 \n\t" \ + "mul r2, r6 \n\t" \ + "add r14, r0 \n\t" \ + "adc r15, r1 \n\t" \ + "adc r16, r25 \n\t" \ + "mul r3, r9 \n\t" \ + "add r14, r0 \n\t" \ + "adc r15, r1 \n\t" \ + "adc r16, r25 \n\t" \ + "mul r4, r8 \n\t" \ + "add r14, r0 \n\t" \ + "adc r15, r1 \n\t" \ + "adc r16, r25 \n\t" \ + "mul r5, r7 \n\t" \ + "add r14, r0 \n\t" \ + "adc r15, r1 \n\t" \ + "adc r16, r25 \n\t" \ + \ + "ld r7, x+ \n\t" \ + "mov r17, r25 \n\t" \ + "mul r2, r7 \n\t" \ + "add r15, r0 \n\t" \ + "adc r16, r1 \n\t" \ + "adc r17, r25 \n\t" \ + "mul r3, r6 \n\t" \ + "add r15, r0 \n\t" \ + "adc r16, r1 \n\t" \ + "adc r17, r25 \n\t" \ + "mul r4, r9 \n\t" \ + "add r15, r0 \n\t" \ + "adc r16, r1 \n\t" \ + "adc r17, r25 \n\t" \ + "mul r5, r8 \n\t" \ + "add r15, r0 \n\t" \ + "adc r16, r1 \n\t" \ + "adc r17, r25 \n\t" \ + \ + "ld r8, x+ \n\t" \ + "mov r18, r25 \n\t" \ + "mul r2, r8 \n\t" \ + "add r16, r0 \n\t" \ + "adc r17, r1 \n\t" \ + "adc r18, r25 \n\t" \ + "mul r3, r7 \n\t" \ + "add r16, r0 \n\t" \ + "adc r17, r1 \n\t" \ + "adc r18, r25 \n\t" \ + "mul r4, r6 \n\t" \ + "add r16, r0 \n\t" \ + "adc r17, r1 \n\t" \ + "adc r18, r25 \n\t" \ + "mul r5, r9 \n\t" \ + "add r16, r0 \n\t" \ + "adc r17, r1 \n\t" \ + "adc r18, r25 \n\t" \ + \ + "ld r9, x+ \n\t" \ + "mov r19, r25 \n\t" \ + "mul r2, r9 \n\t" \ + "add r17, r0 \n\t" \ + "adc r18, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r3, r8 \n\t" \ + "add r17, r0 \n\t" \ + "adc r18, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r4, r7 \n\t" \ + "add r17, r0 \n\t" \ + "adc r18, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r5, r6 \n\t" \ + "add r17, r0 \n\t" \ + "adc r18, r1 \n\t" \ + "adc r19, r25 \n\t" \ + \ + "ld r6, x+ \n\t" \ + "mov r21, r25 \n\t" \ + "mul r2, r6 \n\t" \ + "add r18, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r3, r9 \n\t" \ + "add r18, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r4, r8 \n\t" \ + "add r18, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r5, r7 \n\t" \ + "add r18, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r21, r25 \n\t" \ + \ + "ld r7, x+ \n\t" \ + "mov r22, r25 \n\t" \ + "mul r2, r7 \n\t" \ + "add r19, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r3, r6 \n\t" \ + "add r19, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r4, r9 \n\t" \ + "add r19, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r5, r8 \n\t" \ + "add r19, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r22, r25 \n\t" \ + \ + "ld r8, x+ \n\t" \ + "mov r23, r25 \n\t" \ + "mul r2, r8 \n\t" \ + "add r21, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r3, r7 \n\t" \ + "add r21, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r4, r6 \n\t" \ + "add r21, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r5, r9 \n\t" \ + "add r21, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + \ + "ld r9, x+ \n\t" \ + "mov r24, r25 \n\t" \ + "mul r2, r9 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r3, r8 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r4, r7 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r5, r6 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + \ + "ld r6, x+ \n\t" \ + "mov r28, r25 \n\t" \ + "mul r2, r6 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r28, r25 \n\t" \ + "mul r3, r9 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r28, r25 \n\t" \ + "mul r4, r8 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r28, r25 \n\t" \ + "mul r5, r7 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r28, r25 \n\t" \ + \ + "ld r7, x+ \n\t" \ + "mov r29, r25 \n\t" \ + "mul r2, r7 \n\t" \ + "add r24, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r3, r6 \n\t" \ + "add r24, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r4, r9 \n\t" \ + "add r24, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r5, r8 \n\t" \ + "add r24, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + \ + "lsl r10 \n\t" \ + "rol r11 \n\t" \ + "rol r12 \n\t" \ + "rol r13 \n\t" \ + "rol r14 \n\t" \ + "rol r15 \n\t" \ + "rol r16 \n\t" \ + "rol r17 \n\t" \ + "rol r18 \n\t" \ + "rol r19 \n\t" \ + "rol r21 \n\t" \ + "rol r22 \n\t" \ + "rol r23 \n\t" \ + "rol r24 \n\t" \ + "rol r28 \n\t" \ + "rol r29 \n\t" \ + "ld r0, z \n\t" \ + "add r10, r0 \n\t" \ + "st z+, r10 \n\t" \ + "ld r0, z \n\t" \ + "adc r11, r0 \n\t" \ + "st z+, r11 \n\t" \ + "ld r0, z \n\t" \ + "adc r12, r0 \n\t" \ + "st z+, r12 \n\t" \ + "ld r0, z \n\t" \ + "adc r13, r0 \n\t" \ + "st z+, r13 \n\t" \ + "ld r0, z \n\t" \ + "adc r14, r0 \n\t" \ + "st z+, r14 \n\t" \ + "ld r0, z \n\t" \ + "adc r15, r0 \n\t" \ + "st z+, r15 \n\t" \ + "ld r0, z \n\t" \ + "adc r16, r0 \n\t" \ + "st z+, r16 \n\t" \ + "ld r0, z \n\t" \ + "adc r17, r0 \n\t" \ + "st z+, r17 \n\t" \ + "ld r0, z \n\t" \ + "adc r18, r0 \n\t" \ + "st z+, r18 \n\t" \ + "ld r0, z \n\t" \ + "adc r19, r0 \n\t" \ + "st z+, r19 \n\t" \ + "ld r0, z \n\t" \ + "adc r21, r0 \n\t" \ + "st z+, r21 \n\t" \ + "ld r0, z \n\t" \ + "adc r22, r0 \n\t" \ + "st z+, r22 \n\t" \ + "ld r0, z \n\t" \ + "adc r23, r0 \n\t" \ + "st z+, r23 \n\t" \ + "ld r0, z \n\t" \ + "adc r24, r0 \n\t" \ + "st z+, r24 \n\t" \ + "adc r28, r25 \n\t" \ + "adc r29, r25 \n\t" \ + "bst r28, 0 \n\t" \ + "lsr r29 \n\t" \ + "ror r28 \n\t" \ + \ + "ld r8, x+ \n\t" \ + "mov r10, r25 \n\t" \ + "mul r2, r8 \n\t" \ + "add r28, r0 \n\t" \ + "adc r29, r1 \n\t" \ + "adc r10, r25 \n\t" \ + "mul r3, r7 \n\t" \ + "add r28, r0 \n\t" \ + "adc r29, r1 \n\t" \ + "adc r10, r25 \n\t" \ + "mul r4, r6 \n\t" \ + "add r28, r0 \n\t" \ + "adc r29, r1 \n\t" \ + "adc r10, r25 \n\t" \ + "mul r5, r9 \n\t" \ + "add r28, r0 \n\t" \ + "adc r29, r1 \n\t" \ + "adc r10, r25 \n\t" \ + \ + "ld r9, x+ \n\t" \ + "mov r11, r25 \n\t" \ + "mul r2, r9 \n\t" \ + "add r29, r0 \n\t" \ + "adc r10, r1 \n\t" \ + "adc r11, r25 \n\t" \ + "mul r3, r8 \n\t" \ + "add r29, r0 \n\t" \ + "adc r10, r1 \n\t" \ + "adc r11, r25 \n\t" \ + "mul r4, r7 \n\t" \ + "add r29, r0 \n\t" \ + "adc r10, r1 \n\t" \ + "adc r11, r25 \n\t" \ + "mul r5, r6 \n\t" \ + "add r29, r0 \n\t" \ + "adc r10, r1 \n\t" \ + "adc r11, r25 \n\t" \ + \ + "ld r6, x+ \n\t" \ + "mov r12, r25 \n\t" \ + "mul r2, r6 \n\t" \ + "add r10, r0 \n\t" \ + "adc r11, r1 \n\t" \ + "adc r12, r25 \n\t" \ + "mul r3, r9 \n\t" \ + "add r10, r0 \n\t" \ + "adc r11, r1 \n\t" \ + "adc r12, r25 \n\t" \ + "mul r4, r8 \n\t" \ + "add r10, r0 \n\t" \ + "adc r11, r1 \n\t" \ + "adc r12, r25 \n\t" \ + "mul r5, r7 \n\t" \ + "add r10, r0 \n\t" \ + "adc r11, r1 \n\t" \ + "adc r12, r25 \n\t" \ + \ + "ld r7, x+ \n\t" \ + "mov r13, r25 \n\t" \ + "mul r2, r7 \n\t" \ + "add r11, r0 \n\t" \ + "adc r12, r1 \n\t" \ + "adc r13, r25 \n\t" \ + "mul r3, r6 \n\t" \ + "add r11, r0 \n\t" \ + "adc r12, r1 \n\t" \ + "adc r13, r25 \n\t" \ + "mul r4, r9 \n\t" \ + "add r11, r0 \n\t" \ + "adc r12, r1 \n\t" \ + "adc r13, r25 \n\t" \ + "mul r5, r8 \n\t" \ + "add r11, r0 \n\t" \ + "adc r12, r1 \n\t" \ + "adc r13, r25 \n\t" \ + \ + "ld r8, x+ \n\t" \ + "mov r14, r25 \n\t" \ + "mul r2, r8 \n\t" \ + "add r12, r0 \n\t" \ + "adc r13, r1 \n\t" \ + "adc r14, r25 \n\t" \ + "mul r3, r7 \n\t" \ + "add r12, r0 \n\t" \ + "adc r13, r1 \n\t" \ + "adc r14, r25 \n\t" \ + "mul r4, r6 \n\t" \ + "add r12, r0 \n\t" \ + "adc r13, r1 \n\t" \ + "adc r14, r25 \n\t" \ + "mul r5, r9 \n\t" \ + "add r12, r0 \n\t" \ + "adc r13, r1 \n\t" \ + "adc r14, r25 \n\t" \ + \ + "ld r9, x+ \n\t" \ + "mov r15, r25 \n\t" \ + "mul r2, r9 \n\t" \ + "add r13, r0 \n\t" \ + "adc r14, r1 \n\t" \ + "adc r15, r25 \n\t" \ + "mul r3, r8 \n\t" \ + "add r13, r0 \n\t" \ + "adc r14, r1 \n\t" \ + "adc r15, r25 \n\t" \ + "mul r4, r7 \n\t" \ + "add r13, r0 \n\t" \ + "adc r14, r1 \n\t" \ + "adc r15, r25 \n\t" \ + "mul r5, r6 \n\t" \ + "add r13, r0 \n\t" \ + "adc r14, r1 \n\t" \ + "adc r15, r25 \n\t" \ + \ + "lsl r28 \n\t" \ + "bld r28, 0 \n\t" \ + "rol r29 \n\t" \ + "rol r10 \n\t" \ + "rol r11 \n\t" \ + "rol r12 \n\t" \ + "rol r13 \n\t" \ + "rol r14 \n\t" \ + "rol r15 \n\t" \ + "ld r0, z \n\t" \ + "add r28, r0 \n\t" \ + "st z+, r28 \n\t" \ + "ld r0, z \n\t" \ + "adc r29, r0 \n\t" \ + "st z+, r29 \n\t" \ + "ld r0, z \n\t" \ + "adc r10, r0 \n\t" \ + "st z+, r10 \n\t" \ + "ld r0, z \n\t" \ + "adc r11, r0 \n\t" \ + "st z+, r11 \n\t" \ + "ld r0, z \n\t" \ + "adc r12, r0 \n\t" \ + "st z+, r12 \n\t" \ + "ld r0, z \n\t" \ + "adc r13, r0 \n\t" \ + "st z+, r13 \n\t" \ + "adc r14, r25 \n\t" \ + "adc r15, r25 \n\t" \ + \ + "mul r2, r2 \n\t" \ + "mov r16, r0 \n\t" \ + "mov r17, r1 \n\t" \ + "mul r3, r3 \n\t" \ + "mov r18, r0 \n\t" \ + "mov r19, r1 \n\t" \ + "mul r4, r4 \n\t" \ + "mov r21, r0 \n\t" \ + "mov r22, r1 \n\t" \ + "mul r5, r5 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r24, r1 \n\t" \ + "add r16, r14 \n\t" \ + "adc r17, r15 \n\t" \ + "adc r18, r25 \n\t" \ + "adc r19, r25 \n\t" \ + \ + "mul r7, r5 \n\t" \ + "mov r14, r0 \n\t" \ + "mov r15, r1 \n\t" \ + "mov r28, r25 \n\t" \ + "mul r8, r4 \n\t" \ + "add r14, r0 \n\t" \ + "adc r15, r1 \n\t" \ + "adc r28, r25 \n\t" \ + "mul r9, r3 \n\t" \ + "add r14, r0 \n\t" \ + "adc r15, r1 \n\t" \ + "adc r28, r25 \n\t" \ + "mov r29, r25 \n\t" \ + "mul r8, r5 \n\t" \ + "add r15, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r9, r4 \n\t" \ + "add r15, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r2, r3 \n\t" \ + "add r15, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mov r10, r25 \n\t" \ + "mul r9, r5 \n\t" \ + "add r28, r0 \n\t" \ + "adc r29, r1 \n\t" \ + "adc r10, r25 \n\t" \ + "mul r2, r4 \n\t" \ + "add r28, r0 \n\t" \ + "adc r29, r1 \n\t" \ + "adc r10, r25 \n\t" \ + "mov r11, r25 \n\t" \ + "mul r2, r5 \n\t" \ + "add r29, r0 \n\t" \ + "adc r10, r1 \n\t" \ + "adc r11, r25 \n\t" \ + "mul r3, r4 \n\t" \ + "add r29, r0 \n\t" \ + "adc r10, r1 \n\t" \ + "adc r11, r25 \n\t" \ + "mov r12, r25 \n\t" \ + "mul r3, r5 \n\t" \ + "add r10, r0 \n\t" \ + "adc r11, r1 \n\t" \ + "adc r12, r25 \n\t" \ + "mul r4, r5 \n\t" \ + "add r11, r0 \n\t" \ + "adc r12, r1 \n\t" \ + \ + "lsl r14 \n\t" \ + "rol r15 \n\t" \ + "rol r28 \n\t" \ + "rol r29 \n\t" \ + "rol r10 \n\t" \ + "rol r11 \n\t" \ + "rol r12 \n\t" \ + "adc r24, r25 \n\t" \ + "add r16, r14 \n\t" \ + "adc r17, r15 \n\t" \ + "adc r18, r28 \n\t" \ + "adc r19, r29 \n\t" \ + "adc r21, r10 \n\t" \ + "adc r22, r11 \n\t" \ + "adc r23, r12 \n\t" \ + "adc r24, r25 \n\t" \ + \ + "st z+, r16 \n\t" \ + "st z+, r17 \n\t" \ + "st z+, r18 \n\t" \ + "st z+, r19 \n\t" \ + "st z+, r21 \n\t" \ + "st z+, r22 \n\t" \ + "st z+, r23 \n\t" \ + "st z+, r24 \n\t" \ + "adiw r26, 4 \n\t" + +#define FAST_SQUARE_ASM_24 \ + "ldi r25, 0 \n\t" \ + "movw r28, r26 \n\t" \ + "ld r2, x+ \n\t" \ + "ld r3, x+ \n\t" \ + "adiw r28, 20 \n\t" \ + "ld r12, y+ \n\t" \ + "ld r13, y+ \n\t" \ + "adiw r30, 20 \n\t" \ + \ + "ldi r23, 0 \n\t" \ + "mul 2, 12 \n\t" \ + "st z+, r0 \n\t" \ + "mov r22, r1 \n\t" \ + \ + "ldi r24, 0 \n\t" \ + "mul r2, r13 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ld r12, y+ \n\t" \ + "ldi r22, 0 \n\t" \ + "mul r2, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r3, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ld r13, y+ \n\t" \ + "ldi r23, 0 \n\t" \ + "mul r2, r13 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r3, r12 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "st z+, r24 \n\t" \ + \ + "ld r2, x+ \n\t" \ + "ldi r24, 0 \n\t" \ + "mul r3, r13 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r2, r12 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ld r3, x+ \n\t" \ + "ldi r22, 0 \n\t" \ + "mul r2, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "mul r3, r13 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "st z+, r24 \n\t" \ + "st z+, r22 \n\t" \ + \ + "sbiw r26, 4 \n\t" \ + "sbiw r30, 28 \n\t" \ + "ld r2, x+ \n\t" \ + "ld r3, x+ \n\t" \ + "ld r4, x+ \n\t" \ + "ld r5, x+ \n\t" \ + "ld r6, x+ \n\t" \ + "ld r7, x+ \n\t" \ + "ld r8, x+ \n\t" \ + "ld r9, x+ \n\t" \ + "ld r10, x+ \n\t" \ + "ld r11, x+ \n\t" \ + "ld r12, x+ \n\t" \ + "ld r13, x+ \n\t" \ + "ld r14, x+ \n\t" \ + "ld r15, x+ \n\t" \ + "ld r16, x+ \n\t" \ + "ld r17, x+ \n\t" \ + "ld r18, x+ \n\t" \ + "ld r19, x+ \n\t" \ + "ld r20, x+ \n\t" \ + "ld r21, x+ \n\t" \ + \ + "ldi r23, 0 \n\t" \ + "mul r2, r2 \n\t" \ + "st z+, r0 \n\t" \ + "mov r22, r1 \n\t" \ + \ + "ldi r24, 0 \n\t" \ + "mul r2, r3 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ldi r22, 0 \n\t" \ + "mul r2, r4 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r3, r3 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r29, 0 \n\t" \ + "mul r2, r5 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r28, r1 \n\t" \ + "mul r3, r4 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r28 \n\t" \ + "rol r29 \n\t" \ + "add r23, r24 \n\t" \ + "adc r28, r22 \n\t" \ + "adc r29, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r22, 0 \n\t" \ + "mul r2, r6 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r24, r1 \n\t" \ + "mul r3, r5 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r24 \n\t" \ + "rol r22 \n\t" \ + "mul r4, r4 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "add r23, r28 \n\t" \ + "adc r24, r29 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r29, 0 \n\t" \ + "mul r2, r7 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r28, r1 \n\t" \ + "mul r3, r6 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r4, r5 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r28 \n\t" \ + "rol r29 \n\t" \ + "add r23, r24 \n\t" \ + "adc r28, r22 \n\t" \ + "adc r29, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r22, 0 \n\t" \ + "mul r2, r8 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r24, r1 \n\t" \ + "mul r3, r7 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r4, r6 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r24 \n\t" \ + "rol r22 \n\t" \ + "mul r5, r5 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "add r23, r28 \n\t" \ + "adc r24, r29 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r29, 0 \n\t" \ + "mul r2, r9 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r28, r1 \n\t" \ + "mul r3, r8 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r4, r7 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r5, r6 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r28 \n\t" \ + "rol r29 \n\t" \ + "add r23, r24 \n\t" \ + "adc r28, r22 \n\t" \ + "adc r29, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r22, 0 \n\t" \ + "mul r2, r10 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r24, r1 \n\t" \ + "mul r3, r9 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r4, r8 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r5, r7 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r24 \n\t" \ + "rol r22 \n\t" \ + "mul r6, r6 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "add r23, r28 \n\t" \ + "adc r24, r29 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r29, 0 \n\t" \ + "mul r2, r11 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r28, r1 \n\t" \ + "mul r3, r10 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r4, r9 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r5, r8 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r6, r7 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r28 \n\t" \ + "rol r29 \n\t" \ + "add r23, r24 \n\t" \ + "adc r28, r22 \n\t" \ + "adc r29, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r22, 0 \n\t" \ + "mul r2, r12 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r24, r1 \n\t" \ + "mul r3, r11 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r4, r10 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r5, r9 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r6, r8 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r24 \n\t" \ + "rol r22 \n\t" \ + "mul r7, r7 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "add r23, r28 \n\t" \ + "adc r24, r29 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r29, 0 \n\t" \ + "mul r2, r13 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r28, r1 \n\t" \ + "mul r3, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r4, r11 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r5, r10 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r6, r9 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r7, r8 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r28 \n\t" \ + "rol r29 \n\t" \ + "add r23, r24 \n\t" \ + "adc r28, r22 \n\t" \ + "adc r29, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r22, 0 \n\t" \ + "mul r2, r14 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r24, r1 \n\t" \ + "mul r3, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r4, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r5, r11 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r6, r10 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r7, r9 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r24 \n\t" \ + "rol r22 \n\t" \ + "mul r8, r8 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "add r23, r28 \n\t" \ + "adc r24, r29 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r29, 0 \n\t" \ + "mul r2, r15 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r28, r1 \n\t" \ + "mul r3, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r4, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r5, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r6, r11 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r7, r10 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r8, r9 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r28 \n\t" \ + "rol r29 \n\t" \ + "add r23, r24 \n\t" \ + "adc r28, r22 \n\t" \ + "adc r29, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r22, 0 \n\t" \ + "mul r2, r16 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r24, r1 \n\t" \ + "mul r3, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r4, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r5, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r6, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r7, r11 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r8, r10 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r24 \n\t" \ + "rol r22 \n\t" \ + "mul r9, r9 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "add r23, r28 \n\t" \ + "adc r24, r29 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r29, 0 \n\t" \ + "mul r2, r17 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r28, r1 \n\t" \ + "mul r3, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r4, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r5, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r6, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r7, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r8, r11 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r9, r10 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r28 \n\t" \ + "rol r29 \n\t" \ + "add r23, r24 \n\t" \ + "adc r28, r22 \n\t" \ + "adc r29, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r22, 0 \n\t" \ + "mul r2, r18 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r24, r1 \n\t" \ + "mul r3, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r4, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r5, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r6, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r7, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r8, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r9, r11 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r24 \n\t" \ + "rol r22 \n\t" \ + "mul r10, r10 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "add r23, r28 \n\t" \ + "adc r24, r29 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r29, 0 \n\t" \ + "mul r2, r19 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r28, r1 \n\t" \ + "mul r3, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r4, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r5, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r6, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r7, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r8, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r9, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r10, r11 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r28 \n\t" \ + "rol r29 \n\t" \ + "add r23, r24 \n\t" \ + "adc r28, r22 \n\t" \ + "adc r29, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r22, 0 \n\t" \ + "mul r2, r20 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r24, r1 \n\t" \ + "mul r3, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r4, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r5, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r6, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r7, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r8, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r9, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r10, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r24 \n\t" \ + "rol r22 \n\t" \ + "mul r11, r11 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "add r23, r28 \n\t" \ + "adc r24, r29 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r29, 0 \n\t" \ + "mul r2, r21 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r28, r1 \n\t" \ + "mul r3, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r4, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r5, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r6, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r7, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r8, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r9, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r10, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r11, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r28 \n\t" \ + "rol r29 \n\t" \ + "add r23, r24 \n\t" \ + "adc r28, r22 \n\t" \ + "adc r29, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ld r2, x+ \n\t" \ + "ldi r22, 0 \n\t" \ + "mul r3, r21 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r24, r1 \n\t" \ + "mul r4, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r5, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r6, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r7, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r8, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r9, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r10, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r11, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r25 \n\t" \ + "adc r22, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r24 \n\t" \ + "rol r22 \n\t" \ + "mul r12, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "add r23, r28 \n\t" \ + "adc r24, r29 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r29, 0 \n\t" \ + "mul r3, r2 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r28, r1 \n\t" \ + "mul r4, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r5, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r6, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r7, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r8, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r9, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r10, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r11, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r12, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r25 \n\t" \ + "adc r29, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r28 \n\t" \ + "rol r29 \n\t" \ + "add r23, r24 \n\t" \ + "adc r28, r22 \n\t" \ + "adc r29, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ld r3, x+ \n\t" \ + "ldi r22, 0 \n\t" \ + "mul r4, r2 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r24, r1 \n\t" \ + "mul r5, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r6, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r7, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r8, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r9, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r10, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r11, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r12, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r25 \n\t" \ + "adc r22, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r24 \n\t" \ + "rol r22 \n\t" \ + "mul r13, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "add r23, r28 \n\t" \ + "adc r24, r29 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r29, 0 \n\t" \ + "mul r4, r3 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r28, r1 \n\t" \ + "mul r5, r2 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r6, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r7, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r8, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r9, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r10, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r11, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r12, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r13, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r25 \n\t" \ + "adc r29, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r28 \n\t" \ + "rol r29 \n\t" \ + "add r23, r24 \n\t" \ + "adc r28, r22 \n\t" \ + "adc r29, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ld r4, x+ \n\t" \ + "ldi r22, 0 \n\t" \ + "mul r5, r3 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r24, r1 \n\t" \ + "mul r6, r2 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r7, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r8, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r9, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r10, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r11, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r12, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r13, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r25 \n\t" \ + "adc r22, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r24 \n\t" \ + "rol r22 \n\t" \ + "mul r14, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "add r23, r28 \n\t" \ + "adc r24, r29 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r29, 0 \n\t" \ + "mul r5, r4 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r28, r1 \n\t" \ + "mul r6, r3 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r7, r2 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r8, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r9, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r10, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r11, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r12, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r13, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r14, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r25 \n\t" \ + "adc r29, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r28 \n\t" \ + "rol r29 \n\t" \ + "add r23, r24 \n\t" \ + "adc r28, r22 \n\t" \ + "adc r29, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ld r5, x+ \n\t" \ + "ldi r22, 0 \n\t" \ + "mul r6, r4 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r24, r1 \n\t" \ + "mul r7, r3 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r8, r2 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r9, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r10, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r11, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r12, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r13, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r14, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r25 \n\t" \ + "adc r22, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r24 \n\t" \ + "rol r22 \n\t" \ + "mul r15, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "add r23, r28 \n\t" \ + "adc r24, r29 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r29, 0 \n\t" \ + "mul r6, r5 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r28, r1 \n\t" \ + "mul r7, r4 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r8, r3 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r9, r2 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r10, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r11, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r12, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r13, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r14, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r15, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r25 \n\t" \ + "adc r29, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r28 \n\t" \ + "rol r29 \n\t" \ + "add r23, r24 \n\t" \ + "adc r28, r22 \n\t" \ + "adc r29, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r22, 0 \n\t" \ + "mul r7, r5 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r24, r1 \n\t" \ + "mul r8, r4 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r9, r3 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r10, r2 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r11, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r12, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r13, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r14, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r15, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r24 \n\t" \ + "rol r22 \n\t" \ + "mul r16, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "add r23, r28 \n\t" \ + "adc r24, r29 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r29, 0 \n\t" \ + "mul r8, r5 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r28, r1 \n\t" \ + "mul r9, r4 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r10, r3 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r11, r2 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r12, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r13, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r14, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r15, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r16, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r28 \n\t" \ + "rol r29 \n\t" \ + "add r23, r24 \n\t" \ + "adc r28, r22 \n\t" \ + "adc r29, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r22, 0 \n\t" \ + "mul r9, r5 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r24, r1 \n\t" \ + "mul r10, r4 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r11, r3 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r12, r2 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r13, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r14, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r15, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r16, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r24 \n\t" \ + "rol r22 \n\t" \ + "mul r17, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "add r23, r28 \n\t" \ + "adc r24, r29 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r29, 0 \n\t" \ + "mul r10, r5 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r28, r1 \n\t" \ + "mul r11, r4 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r12, r3 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r13, r2 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r14, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r15, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r16, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r17, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r28 \n\t" \ + "rol r29 \n\t" \ + "add r23, r24 \n\t" \ + "adc r28, r22 \n\t" \ + "adc r29, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r22, 0 \n\t" \ + "mul r11, r5 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r24, r1 \n\t" \ + "mul r12, r4 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r13, r3 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r14, r2 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r15, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r16, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r17, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r24 \n\t" \ + "rol r22 \n\t" \ + "mul r18, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "add r23, r28 \n\t" \ + "adc r24, r29 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r29, 0 \n\t" \ + "mul r12, r5 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r28, r1 \n\t" \ + "mul r13, r4 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r14, r3 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r15, r2 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r16, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r17, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r18, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r28 \n\t" \ + "rol r29 \n\t" \ + "add r23, r24 \n\t" \ + "adc r28, r22 \n\t" \ + "adc r29, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r22, 0 \n\t" \ + "mul r13, r5 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r24, r1 \n\t" \ + "mul r14, r4 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r15, r3 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r16, r2 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r17, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r18, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r24 \n\t" \ + "rol r22 \n\t" \ + "mul r19, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "add r23, r28 \n\t" \ + "adc r24, r29 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r29, 0 \n\t" \ + "mul r14, r5 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r28, r1 \n\t" \ + "mul r15, r4 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r16, r3 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r17, r2 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r18, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r19, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r28 \n\t" \ + "rol r29 \n\t" \ + "add r23, r24 \n\t" \ + "adc r28, r22 \n\t" \ + "adc r29, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r22, 0 \n\t" \ + "mul r15, r5 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r24, r1 \n\t" \ + "mul r16, r4 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r17, r3 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r18, r2 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r19, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r24 \n\t" \ + "rol r22 \n\t" \ + "mul r20, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "add r23, r28 \n\t" \ + "adc r24, r29 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r29, 0 \n\t" \ + "mul r16, r5 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r28, r1 \n\t" \ + "mul r17, r4 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r18, r3 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r19, r2 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r20, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r28 \n\t" \ + "rol r29 \n\t" \ + "add r23, r24 \n\t" \ + "adc r28, r22 \n\t" \ + "adc r29, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r22, 0 \n\t" \ + "mul r17, r5 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r24, r1 \n\t" \ + "mul r18, r4 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r19, r3 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r20, r2 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r24 \n\t" \ + "rol r22 \n\t" \ + "mul r21, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "add r23, r28 \n\t" \ + "adc r24, r29 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r29, 0 \n\t" \ + "mul r18, r5 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r28, r1 \n\t" \ + "mul r19, r4 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r20, r3 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r21, r2 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r28 \n\t" \ + "rol r29 \n\t" \ + "add r23, r24 \n\t" \ + "adc r28, r22 \n\t" \ + "adc r29, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r22, 0 \n\t" \ + "mul r19, r5 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r24, r1 \n\t" \ + "mul r20, r4 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r21, r3 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r24 \n\t" \ + "rol r22 \n\t" \ + "mul r2, r2 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "add r23, r28 \n\t" \ + "adc r24, r29 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r29, 0 \n\t" \ + "mul r20, r5 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r28, r1 \n\t" \ + "mul r21, r4 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r2, r3 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r28 \n\t" \ + "rol r29 \n\t" \ + "add r23, r24 \n\t" \ + "adc r28, r22 \n\t" \ + "adc r29, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r22, 0 \n\t" \ + "mul r21, r5 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r24, r1 \n\t" \ + "mul r2, r4 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r24 \n\t" \ + "rol r22 \n\t" \ + "mul r3, r3 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "add r23, r28 \n\t" \ + "adc r24, r29 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r29, 0 \n\t" \ + "mul r2, r5 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r28, r1 \n\t" \ + "mul r3, r4 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r28 \n\t" \ + "rol r29 \n\t" \ + "add r23, r24 \n\t" \ + "adc r28, r22 \n\t" \ + "adc r29, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r23, 0 \n\t" \ + "mul r3, r5 \n\t" \ + "add r28, r0 \n\t" \ + "adc r29, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "add r28, r0 \n\t" \ + "adc r29, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r4, r4 \n\t" \ + "add r28, r0 \n\t" \ + "adc r29, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "st z+, r28 \n\t" \ + \ + "ldi r28, 0 \n\t" \ + "mul r4, r5 \n\t" \ + "add r29, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r28, r25 \n\t" \ + "add r29, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r28, r25 \n\t" \ + "st z+, r29 \n\t" \ + \ + "mul r5, r5 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "st z+, r23 \n\t" \ + "st z+, r28 \n\t" + +#define FAST_SQUARE_ASM_24_TO_28 \ + "cpi r20, 24 \n\t" \ + "brne 1f \n\t" \ + "jmp 2f \n\t" \ + "1: \n\t" \ + "ld r2, x+ \n\t" \ + "ld r3, x+ \n\t" \ + "ld r4, x+ \n\t" \ + "ld r5, x+ \n\t" \ + "sbiw r26, 28 \n\t" \ + "sbiw r30, 24 \n\t" \ + "ld r6, x+ \n\t" \ + "ld r7, x+ \n\t" \ + "ld r8, x+ \n\t" \ + "ld r9, x+ \n\t" \ + \ + "mul r2, r6 \n\t" \ + "mov r10, r0 \n\t" \ + "mov r11, r1 \n\t" \ + "mov r12, r25 \n\t" \ + "mov r13, r25 \n\t" \ + "mul r2, r7 \n\t" \ + "add r11, r0 \n\t" \ + "adc r12, r1 \n\t" \ + "adc r13, r25 \n\t" \ + "mul r3, r6 \n\t" \ + "add r11, r0 \n\t" \ + "adc r12, r1 \n\t" \ + "adc r13, r25 \n\t" \ + \ + "mov r14, r25 \n\t" \ + "mul r2, r8 \n\t" \ + "add r12, r0 \n\t" \ + "adc r13, r1 \n\t" \ + "adc r14, r25 \n\t" \ + "mul r3, r7 \n\t" \ + "add r12, r0 \n\t" \ + "adc r13, r1 \n\t" \ + "adc r14, r25 \n\t" \ + "mul r4, r6 \n\t" \ + "add r12, r0 \n\t" \ + "adc r13, r1 \n\t" \ + "adc r14, r25 \n\t" \ + \ + "mov r15, r25 \n\t" \ + "mul r2, r9 \n\t" \ + "add r13, r0 \n\t" \ + "adc r14, r1 \n\t" \ + "adc r15, r25 \n\t" \ + "mul r3, r8 \n\t" \ + "add r13, r0 \n\t" \ + "adc r14, r1 \n\t" \ + "adc r15, r25 \n\t" \ + "mul r4, r7 \n\t" \ + "add r13, r0 \n\t" \ + "adc r14, r1 \n\t" \ + "adc r15, r25 \n\t" \ + "mul r5, r6 \n\t" \ + "add r13, r0 \n\t" \ + "adc r14, r1 \n\t" \ + "adc r15, r25 \n\t" \ + \ + "ld r6, x+ \n\t" \ + "mov r16, r25 \n\t" \ + "mul r2, r6 \n\t" \ + "add r14, r0 \n\t" \ + "adc r15, r1 \n\t" \ + "adc r16, r25 \n\t" \ + "mul r3, r9 \n\t" \ + "add r14, r0 \n\t" \ + "adc r15, r1 \n\t" \ + "adc r16, r25 \n\t" \ + "mul r4, r8 \n\t" \ + "add r14, r0 \n\t" \ + "adc r15, r1 \n\t" \ + "adc r16, r25 \n\t" \ + "mul r5, r7 \n\t" \ + "add r14, r0 \n\t" \ + "adc r15, r1 \n\t" \ + "adc r16, r25 \n\t" \ + \ + "ld r7, x+ \n\t" \ + "mov r17, r25 \n\t" \ + "mul r2, r7 \n\t" \ + "add r15, r0 \n\t" \ + "adc r16, r1 \n\t" \ + "adc r17, r25 \n\t" \ + "mul r3, r6 \n\t" \ + "add r15, r0 \n\t" \ + "adc r16, r1 \n\t" \ + "adc r17, r25 \n\t" \ + "mul r4, r9 \n\t" \ + "add r15, r0 \n\t" \ + "adc r16, r1 \n\t" \ + "adc r17, r25 \n\t" \ + "mul r5, r8 \n\t" \ + "add r15, r0 \n\t" \ + "adc r16, r1 \n\t" \ + "adc r17, r25 \n\t" \ + \ + "ld r8, x+ \n\t" \ + "mov r18, r25 \n\t" \ + "mul r2, r8 \n\t" \ + "add r16, r0 \n\t" \ + "adc r17, r1 \n\t" \ + "adc r18, r25 \n\t" \ + "mul r3, r7 \n\t" \ + "add r16, r0 \n\t" \ + "adc r17, r1 \n\t" \ + "adc r18, r25 \n\t" \ + "mul r4, r6 \n\t" \ + "add r16, r0 \n\t" \ + "adc r17, r1 \n\t" \ + "adc r18, r25 \n\t" \ + "mul r5, r9 \n\t" \ + "add r16, r0 \n\t" \ + "adc r17, r1 \n\t" \ + "adc r18, r25 \n\t" \ + \ + "ld r9, x+ \n\t" \ + "mov r19, r25 \n\t" \ + "mul r2, r9 \n\t" \ + "add r17, r0 \n\t" \ + "adc r18, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r3, r8 \n\t" \ + "add r17, r0 \n\t" \ + "adc r18, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r4, r7 \n\t" \ + "add r17, r0 \n\t" \ + "adc r18, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r5, r6 \n\t" \ + "add r17, r0 \n\t" \ + "adc r18, r1 \n\t" \ + "adc r19, r25 \n\t" \ + \ + "ld r6, x+ \n\t" \ + "mov r21, r25 \n\t" \ + "mul r2, r6 \n\t" \ + "add r18, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r3, r9 \n\t" \ + "add r18, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r4, r8 \n\t" \ + "add r18, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r5, r7 \n\t" \ + "add r18, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r21, r25 \n\t" \ + \ + "ld r7, x+ \n\t" \ + "mov r22, r25 \n\t" \ + "mul r2, r7 \n\t" \ + "add r19, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r3, r6 \n\t" \ + "add r19, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r4, r9 \n\t" \ + "add r19, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r5, r8 \n\t" \ + "add r19, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r22, r25 \n\t" \ + \ + "ld r8, x+ \n\t" \ + "mov r23, r25 \n\t" \ + "mul r2, r8 \n\t" \ + "add r21, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r3, r7 \n\t" \ + "add r21, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r4, r6 \n\t" \ + "add r21, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r5, r9 \n\t" \ + "add r21, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + \ + "ld r9, x+ \n\t" \ + "mov r24, r25 \n\t" \ + "mul r2, r9 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r3, r8 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r4, r7 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r5, r6 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + \ + "ld r6, x+ \n\t" \ + "mov r28, r25 \n\t" \ + "mul r2, r6 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r28, r25 \n\t" \ + "mul r3, r9 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r28, r25 \n\t" \ + "mul r4, r8 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r28, r25 \n\t" \ + "mul r5, r7 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r28, r25 \n\t" \ + \ + "ld r7, x+ \n\t" \ + "mov r29, r25 \n\t" \ + "mul r2, r7 \n\t" \ + "add r24, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r3, r6 \n\t" \ + "add r24, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r4, r9 \n\t" \ + "add r24, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r5, r8 \n\t" \ + "add r24, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + \ + "lsl r10 \n\t" \ + "rol r11 \n\t" \ + "rol r12 \n\t" \ + "rol r13 \n\t" \ + "rol r14 \n\t" \ + "rol r15 \n\t" \ + "rol r16 \n\t" \ + "rol r17 \n\t" \ + "rol r18 \n\t" \ + "rol r19 \n\t" \ + "rol r21 \n\t" \ + "rol r22 \n\t" \ + "rol r23 \n\t" \ + "rol r24 \n\t" \ + "rol r28 \n\t" \ + "rol r29 \n\t" \ + "ld r0, z \n\t" \ + "add r10, r0 \n\t" \ + "st z+, r10 \n\t" \ + "ld r0, z \n\t" \ + "adc r11, r0 \n\t" \ + "st z+, r11 \n\t" \ + "ld r0, z \n\t" \ + "adc r12, r0 \n\t" \ + "st z+, r12 \n\t" \ + "ld r0, z \n\t" \ + "adc r13, r0 \n\t" \ + "st z+, r13 \n\t" \ + "ld r0, z \n\t" \ + "adc r14, r0 \n\t" \ + "st z+, r14 \n\t" \ + "ld r0, z \n\t" \ + "adc r15, r0 \n\t" \ + "st z+, r15 \n\t" \ + "ld r0, z \n\t" \ + "adc r16, r0 \n\t" \ + "st z+, r16 \n\t" \ + "ld r0, z \n\t" \ + "adc r17, r0 \n\t" \ + "st z+, r17 \n\t" \ + "ld r0, z \n\t" \ + "adc r18, r0 \n\t" \ + "st z+, r18 \n\t" \ + "ld r0, z \n\t" \ + "adc r19, r0 \n\t" \ + "st z+, r19 \n\t" \ + "ld r0, z \n\t" \ + "adc r21, r0 \n\t" \ + "st z+, r21 \n\t" \ + "ld r0, z \n\t" \ + "adc r22, r0 \n\t" \ + "st z+, r22 \n\t" \ + "ld r0, z \n\t" \ + "adc r23, r0 \n\t" \ + "st z+, r23 \n\t" \ + "ld r0, z \n\t" \ + "adc r24, r0 \n\t" \ + "st z+, r24 \n\t" \ + "adc r28, r25 \n\t" \ + "adc r29, r25 \n\t" \ + "bst r28, 0 \n\t" \ + "lsr r29 \n\t" \ + "ror r28 \n\t" \ + \ + "ld r8, x+ \n\t" \ + "mov r10, r25 \n\t" \ + "mul r2, r8 \n\t" \ + "add r28, r0 \n\t" \ + "adc r29, r1 \n\t" \ + "adc r10, r25 \n\t" \ + "mul r3, r7 \n\t" \ + "add r28, r0 \n\t" \ + "adc r29, r1 \n\t" \ + "adc r10, r25 \n\t" \ + "mul r4, r6 \n\t" \ + "add r28, r0 \n\t" \ + "adc r29, r1 \n\t" \ + "adc r10, r25 \n\t" \ + "mul r5, r9 \n\t" \ + "add r28, r0 \n\t" \ + "adc r29, r1 \n\t" \ + "adc r10, r25 \n\t" \ + \ + "ld r9, x+ \n\t" \ + "mov r11, r25 \n\t" \ + "mul r2, r9 \n\t" \ + "add r29, r0 \n\t" \ + "adc r10, r1 \n\t" \ + "adc r11, r25 \n\t" \ + "mul r3, r8 \n\t" \ + "add r29, r0 \n\t" \ + "adc r10, r1 \n\t" \ + "adc r11, r25 \n\t" \ + "mul r4, r7 \n\t" \ + "add r29, r0 \n\t" \ + "adc r10, r1 \n\t" \ + "adc r11, r25 \n\t" \ + "mul r5, r6 \n\t" \ + "add r29, r0 \n\t" \ + "adc r10, r1 \n\t" \ + "adc r11, r25 \n\t" \ + \ + "ld r6, x+ \n\t" \ + "mov r12, r25 \n\t" \ + "mul r2, r6 \n\t" \ + "add r10, r0 \n\t" \ + "adc r11, r1 \n\t" \ + "adc r12, r25 \n\t" \ + "mul r3, r9 \n\t" \ + "add r10, r0 \n\t" \ + "adc r11, r1 \n\t" \ + "adc r12, r25 \n\t" \ + "mul r4, r8 \n\t" \ + "add r10, r0 \n\t" \ + "adc r11, r1 \n\t" \ + "adc r12, r25 \n\t" \ + "mul r5, r7 \n\t" \ + "add r10, r0 \n\t" \ + "adc r11, r1 \n\t" \ + "adc r12, r25 \n\t" \ + \ + "ld r7, x+ \n\t" \ + "mov r13, r25 \n\t" \ + "mul r2, r7 \n\t" \ + "add r11, r0 \n\t" \ + "adc r12, r1 \n\t" \ + "adc r13, r25 \n\t" \ + "mul r3, r6 \n\t" \ + "add r11, r0 \n\t" \ + "adc r12, r1 \n\t" \ + "adc r13, r25 \n\t" \ + "mul r4, r9 \n\t" \ + "add r11, r0 \n\t" \ + "adc r12, r1 \n\t" \ + "adc r13, r25 \n\t" \ + "mul r5, r8 \n\t" \ + "add r11, r0 \n\t" \ + "adc r12, r1 \n\t" \ + "adc r13, r25 \n\t" \ + \ + "ld r8, x+ \n\t" \ + "mov r14, r25 \n\t" \ + "mul r2, r8 \n\t" \ + "add r12, r0 \n\t" \ + "adc r13, r1 \n\t" \ + "adc r14, r25 \n\t" \ + "mul r3, r7 \n\t" \ + "add r12, r0 \n\t" \ + "adc r13, r1 \n\t" \ + "adc r14, r25 \n\t" \ + "mul r4, r6 \n\t" \ + "add r12, r0 \n\t" \ + "adc r13, r1 \n\t" \ + "adc r14, r25 \n\t" \ + "mul r5, r9 \n\t" \ + "add r12, r0 \n\t" \ + "adc r13, r1 \n\t" \ + "adc r14, r25 \n\t" \ + \ + "ld r9, x+ \n\t" \ + "mov r15, r25 \n\t" \ + "mul r2, r9 \n\t" \ + "add r13, r0 \n\t" \ + "adc r14, r1 \n\t" \ + "adc r15, r25 \n\t" \ + "mul r3, r8 \n\t" \ + "add r13, r0 \n\t" \ + "adc r14, r1 \n\t" \ + "adc r15, r25 \n\t" \ + "mul r4, r7 \n\t" \ + "add r13, r0 \n\t" \ + "adc r14, r1 \n\t" \ + "adc r15, r25 \n\t" \ + "mul r5, r6 \n\t" \ + "add r13, r0 \n\t" \ + "adc r14, r1 \n\t" \ + "adc r15, r25 \n\t" \ + \ + "ld r6, x+ \n\t" \ + "mov r16, r25 \n\t" \ + "mul r2, r6 \n\t" \ + "add r14, r0 \n\t" \ + "adc r15, r1 \n\t" \ + "adc r16, r25 \n\t" \ + "mul r3, r9 \n\t" \ + "add r14, r0 \n\t" \ + "adc r15, r1 \n\t" \ + "adc r16, r25 \n\t" \ + "mul r4, r8 \n\t" \ + "add r14, r0 \n\t" \ + "adc r15, r1 \n\t" \ + "adc r16, r25 \n\t" \ + "mul r5, r7 \n\t" \ + "add r14, r0 \n\t" \ + "adc r15, r1 \n\t" \ + "adc r16, r25 \n\t" \ + \ + "ld r7, x+ \n\t" \ + "mov r17, r25 \n\t" \ + "mul r2, r7 \n\t" \ + "add r15, r0 \n\t" \ + "adc r16, r1 \n\t" \ + "adc r17, r25 \n\t" \ + "mul r3, r6 \n\t" \ + "add r15, r0 \n\t" \ + "adc r16, r1 \n\t" \ + "adc r17, r25 \n\t" \ + "mul r4, r9 \n\t" \ + "add r15, r0 \n\t" \ + "adc r16, r1 \n\t" \ + "adc r17, r25 \n\t" \ + "mul r5, r8 \n\t" \ + "add r15, r0 \n\t" \ + "adc r16, r1 \n\t" \ + "adc r17, r25 \n\t" \ + \ + "ld r8, x+ \n\t" \ + "mov r18, r25 \n\t" \ + "mul r2, r8 \n\t" \ + "add r16, r0 \n\t" \ + "adc r17, r1 \n\t" \ + "adc r18, r25 \n\t" \ + "mul r3, r7 \n\t" \ + "add r16, r0 \n\t" \ + "adc r17, r1 \n\t" \ + "adc r18, r25 \n\t" \ + "mul r4, r6 \n\t" \ + "add r16, r0 \n\t" \ + "adc r17, r1 \n\t" \ + "adc r18, r25 \n\t" \ + "mul r5, r9 \n\t" \ + "add r16, r0 \n\t" \ + "adc r17, r1 \n\t" \ + "adc r18, r25 \n\t" \ + \ + "ld r9, x+ \n\t" \ + "mov r19, r25 \n\t" \ + "mul r2, r9 \n\t" \ + "add r17, r0 \n\t" \ + "adc r18, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r3, r8 \n\t" \ + "add r17, r0 \n\t" \ + "adc r18, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r4, r7 \n\t" \ + "add r17, r0 \n\t" \ + "adc r18, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r5, r6 \n\t" \ + "add r17, r0 \n\t" \ + "adc r18, r1 \n\t" \ + "adc r19, r25 \n\t" \ + \ + "lsl r28 \n\t" \ + "bld r28, 0 \n\t" \ + "rol r29 \n\t" \ + "rol r10 \n\t" \ + "rol r11 \n\t" \ + "rol r12 \n\t" \ + "rol r13 \n\t" \ + "rol r14 \n\t" \ + "rol r15 \n\t" \ + "rol r16 \n\t" \ + "rol r17 \n\t" \ + "rol r18 \n\t" \ + "rol r19 \n\t" \ + "ld r0, z \n\t" \ + "add r28, r0 \n\t" \ + "st z+, r28 \n\t" \ + "ld r0, z \n\t" \ + "adc r29, r0 \n\t" \ + "st z+, r29 \n\t" \ + "ld r0, z \n\t" \ + "adc r10, r0 \n\t" \ + "st z+, r10 \n\t" \ + "ld r0, z \n\t" \ + "adc r11, r0 \n\t" \ + "st z+, r11 \n\t" \ + "ld r0, z \n\t" \ + "adc r12, r0 \n\t" \ + "st z+, r12 \n\t" \ + "ld r0, z \n\t" \ + "adc r13, r0 \n\t" \ + "st z+, r13 \n\t" \ + "ld r0, z \n\t" \ + "adc r14, r0 \n\t" \ + "st z+, r14 \n\t" \ + "ld r0, z \n\t" \ + "adc r15, r0 \n\t" \ + "st z+, r15 \n\t" \ + "ld r0, z \n\t" \ + "adc r16, r0 \n\t" \ + "st z+, r16 \n\t" \ + "ld r0, z \n\t" \ + "adc r17, r0 \n\t" \ + "st z+, r17 \n\t" \ + "adc r18, r25 \n\t" \ + "adc r19, r25 \n\t" \ + \ + "mul r2, r2 \n\t" \ + "mov r21, r0 \n\t" \ + "mov r22, r1 \n\t" \ + "mul r3, r3 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r24, r1 \n\t" \ + "mul r4, r4 \n\t" \ + "mov r28, r0 \n\t" \ + "mov r29, r1 \n\t" \ + "mul r5, r5 \n\t" \ + "mov r10, r0 \n\t" \ + "mov r11, r1 \n\t" \ + "add r21, r18 \n\t" \ + "adc r22, r19 \n\t" \ + "adc r23, r25 \n\t" \ + "adc r24, r25 \n\t" \ + \ + "mul r7, r5 \n\t" \ + "mov r18, r0 \n\t" \ + "mov r19, r1 \n\t" \ + "mov r12, r25 \n\t" \ + "mul r8, r4 \n\t" \ + "add r18, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r12, r25 \n\t" \ + "mul r9, r3 \n\t" \ + "add r18, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r12, r25 \n\t" \ + "mov r13, r25 \n\t" \ + "mul r8, r5 \n\t" \ + "add r19, r0 \n\t" \ + "adc r12, r1 \n\t" \ + "adc r13, r25 \n\t" \ + "mul r9, r4 \n\t" \ + "add r19, r0 \n\t" \ + "adc r12, r1 \n\t" \ + "adc r13, r25 \n\t" \ + "mul r2, r3 \n\t" \ + "add r19, r0 \n\t" \ + "adc r12, r1 \n\t" \ + "adc r13, r25 \n\t" \ + "mov r14, r25 \n\t" \ + "mul r9, r5 \n\t" \ + "add r12, r0 \n\t" \ + "adc r13, r1 \n\t" \ + "adc r14, r25 \n\t" \ + "mul r2, r4 \n\t" \ + "add r12, r0 \n\t" \ + "adc r13, r1 \n\t" \ + "adc r14, r25 \n\t" \ + "mov r15, r25 \n\t" \ + "mul r2, r5 \n\t" \ + "add r13, r0 \n\t" \ + "adc r14, r1 \n\t" \ + "adc r15, r25 \n\t" \ + "mul r3, r4 \n\t" \ + "add r13, r0 \n\t" \ + "adc r14, r1 \n\t" \ + "adc r15, r25 \n\t" \ + "mov r16, r25 \n\t" \ + "mul r3, r5 \n\t" \ + "add r14, r0 \n\t" \ + "adc r15, r1 \n\t" \ + "adc r16, r25 \n\t" \ + "mul r4, r5 \n\t" \ + "add r15, r0 \n\t" \ + "adc r16, r1 \n\t" \ + \ + "lsl r18 \n\t" \ + "rol r19 \n\t" \ + "rol r12 \n\t" \ + "rol r13 \n\t" \ + "rol r14 \n\t" \ + "rol r15 \n\t" \ + "rol r16 \n\t" \ + "adc r11, r25 \n\t" \ + "add r21, r18 \n\t" \ + "adc r22, r19 \n\t" \ + "adc r23, r12 \n\t" \ + "adc r24, r13 \n\t" \ + "adc r28, r14 \n\t" \ + "adc r29, r15 \n\t" \ + "adc r10, r16 \n\t" \ + "adc r11, r25 \n\t" \ + \ + "st z+, r21 \n\t" \ + "st z+, r22 \n\t" \ + "st z+, r23 \n\t" \ + "st z+, r24 \n\t" \ + "st z+, r28 \n\t" \ + "st z+, r29 \n\t" \ + "st z+, r10 \n\t" \ + "st z+, r11 \n\t" \ + "adiw r26, 4 \n\t" + +#define FAST_SQUARE_ASM_28 \ + "ldi r25, 0 \n\t" \ + "movw r28, r26 \n\t" \ + "ld r2, x+ \n\t" \ + "ld r3, x+ \n\t" \ + "ld r4, x+ \n\t" \ + "ld r5, x+ \n\t" \ + "adiw r28, 20 \n\t" \ + "ld r12, y+ \n\t" \ + "ld r13, y+ \n\t" \ + "ld r14, y+ \n\t" \ + "ld r15, y+ \n\t" \ + "adiw r30, 20 \n\t" \ + \ + "ldi r23, 0 \n\t" \ + "mul 2, 12 \n\t" \ + "st z+, r0 \n\t" \ + "mov r22, r1 \n\t" \ + \ + "ldi r24, 0 \n\t" \ + "mul r2, r13 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ldi r22, 0 \n\t" \ + "mul r2, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r3, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r23, 0 \n\t" \ + "mul r2, r15 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r3, r14 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "st z+, r24 \n\t" \ + \ + "ld r12, y+ \n\t" \ + "ldi r24, 0 \n\t" \ + "mul r2, r12 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r3, r15 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r4, r14 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ld r13, y+ \n\t" \ + "ldi r22, 0 \n\t" \ + "mul r2, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r3, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r4, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ld r14, y+ \n\t" \ + "ldi r23, 0 \n\t" \ + "mul r2, r14 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r3, r13 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r4, r12 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r5, r15 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "st z+, r24 \n\t" \ + \ + "ld r15, y+ \n\t" \ + "ldi r24, 0 \n\t" \ + "mul r2, r15 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r3, r14 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r4, r13 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r5, r12 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ld r2, x+ \n\t" \ + "ldi r22, 0 \n\t" \ + "mul r3, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r4, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r5, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r2, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ld r3, x+ \n\t" \ + "ldi r23, 0 \n\t" \ + "mul r4, r15 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r5, r14 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r2, r13 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "st z+, r24 \n\t" \ + \ + "ld r4, x+ \n\t" \ + "ldi r24, 0 \n\t" \ + "mul r5, r15 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r2, r14 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r3, r13 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ld r5, x+ \n\t" \ + "ldi r22, 0 \n\t" \ + "mul r2, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r3, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r23, 0 \n\t" \ + "mul r3, r15 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r4, r14 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "st z+, r24 \n\t" \ + \ + "ldi r24, 0 \n\t" \ + "mul r4, r15 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "mul r5, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "st z+, r23 \n\t" \ + "st z+, r24 \n\t" \ + \ + "sbiw r26, 8 \n\t" \ + "sbiw r30, 36 \n\t" \ + "ld r2, x+ \n\t" \ + "ld r3, x+ \n\t" \ + "ld r4, x+ \n\t" \ + "ld r5, x+ \n\t" \ + "ld r6, x+ \n\t" \ + "ld r7, x+ \n\t" \ + "ld r8, x+ \n\t" \ + "ld r9, x+ \n\t" \ + "ld r10, x+ \n\t" \ + "ld r11, x+ \n\t" \ + "ld r12, x+ \n\t" \ + "ld r13, x+ \n\t" \ + "ld r14, x+ \n\t" \ + "ld r15, x+ \n\t" \ + "ld r16, x+ \n\t" \ + "ld r17, x+ \n\t" \ + "ld r18, x+ \n\t" \ + "ld r19, x+ \n\t" \ + "ld r20, x+ \n\t" \ + "ld r21, x+ \n\t" \ + \ + "ldi r23, 0 \n\t" \ + "mul r2, r2 \n\t" \ + "st z+, r0 \n\t" \ + "mov r22, r1 \n\t" \ + \ + "ldi r24, 0 \n\t" \ + "mul r2, r3 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ldi r22, 0 \n\t" \ + "mul r2, r4 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r3, r3 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r29, 0 \n\t" \ + "mul r2, r5 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r28, r1 \n\t" \ + "mul r3, r4 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r28 \n\t" \ + "rol r29 \n\t" \ + "add r23, r24 \n\t" \ + "adc r28, r22 \n\t" \ + "adc r29, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r22, 0 \n\t" \ + "mul r2, r6 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r24, r1 \n\t" \ + "mul r3, r5 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r24 \n\t" \ + "rol r22 \n\t" \ + "mul r4, r4 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "add r23, r28 \n\t" \ + "adc r24, r29 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r29, 0 \n\t" \ + "mul r2, r7 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r28, r1 \n\t" \ + "mul r3, r6 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r4, r5 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r28 \n\t" \ + "rol r29 \n\t" \ + "add r23, r24 \n\t" \ + "adc r28, r22 \n\t" \ + "adc r29, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r22, 0 \n\t" \ + "mul r2, r8 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r24, r1 \n\t" \ + "mul r3, r7 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r4, r6 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r24 \n\t" \ + "rol r22 \n\t" \ + "mul r5, r5 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "add r23, r28 \n\t" \ + "adc r24, r29 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r29, 0 \n\t" \ + "mul r2, r9 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r28, r1 \n\t" \ + "mul r3, r8 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r4, r7 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r5, r6 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r28 \n\t" \ + "rol r29 \n\t" \ + "add r23, r24 \n\t" \ + "adc r28, r22 \n\t" \ + "adc r29, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r22, 0 \n\t" \ + "mul r2, r10 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r24, r1 \n\t" \ + "mul r3, r9 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r4, r8 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r5, r7 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r24 \n\t" \ + "rol r22 \n\t" \ + "mul r6, r6 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "add r23, r28 \n\t" \ + "adc r24, r29 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r29, 0 \n\t" \ + "mul r2, r11 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r28, r1 \n\t" \ + "mul r3, r10 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r4, r9 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r5, r8 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r6, r7 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r28 \n\t" \ + "rol r29 \n\t" \ + "add r23, r24 \n\t" \ + "adc r28, r22 \n\t" \ + "adc r29, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r22, 0 \n\t" \ + "mul r2, r12 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r24, r1 \n\t" \ + "mul r3, r11 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r4, r10 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r5, r9 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r6, r8 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r24 \n\t" \ + "rol r22 \n\t" \ + "mul r7, r7 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "add r23, r28 \n\t" \ + "adc r24, r29 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r29, 0 \n\t" \ + "mul r2, r13 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r28, r1 \n\t" \ + "mul r3, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r4, r11 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r5, r10 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r6, r9 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r7, r8 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r28 \n\t" \ + "rol r29 \n\t" \ + "add r23, r24 \n\t" \ + "adc r28, r22 \n\t" \ + "adc r29, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r22, 0 \n\t" \ + "mul r2, r14 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r24, r1 \n\t" \ + "mul r3, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r4, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r5, r11 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r6, r10 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r7, r9 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r24 \n\t" \ + "rol r22 \n\t" \ + "mul r8, r8 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "add r23, r28 \n\t" \ + "adc r24, r29 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r29, 0 \n\t" \ + "mul r2, r15 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r28, r1 \n\t" \ + "mul r3, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r4, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r5, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r6, r11 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r7, r10 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r8, r9 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r28 \n\t" \ + "rol r29 \n\t" \ + "add r23, r24 \n\t" \ + "adc r28, r22 \n\t" \ + "adc r29, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r22, 0 \n\t" \ + "mul r2, r16 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r24, r1 \n\t" \ + "mul r3, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r4, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r5, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r6, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r7, r11 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r8, r10 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r24 \n\t" \ + "rol r22 \n\t" \ + "mul r9, r9 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "add r23, r28 \n\t" \ + "adc r24, r29 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r29, 0 \n\t" \ + "mul r2, r17 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r28, r1 \n\t" \ + "mul r3, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r4, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r5, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r6, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r7, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r8, r11 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r9, r10 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r28 \n\t" \ + "rol r29 \n\t" \ + "add r23, r24 \n\t" \ + "adc r28, r22 \n\t" \ + "adc r29, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r22, 0 \n\t" \ + "mul r2, r18 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r24, r1 \n\t" \ + "mul r3, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r4, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r5, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r6, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r7, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r8, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r9, r11 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r24 \n\t" \ + "rol r22 \n\t" \ + "mul r10, r10 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "add r23, r28 \n\t" \ + "adc r24, r29 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r29, 0 \n\t" \ + "mul r2, r19 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r28, r1 \n\t" \ + "mul r3, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r4, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r5, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r6, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r7, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r8, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r9, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r10, r11 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r28 \n\t" \ + "rol r29 \n\t" \ + "add r23, r24 \n\t" \ + "adc r28, r22 \n\t" \ + "adc r29, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r22, 0 \n\t" \ + "mul r2, r20 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r24, r1 \n\t" \ + "mul r3, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r4, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r5, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r6, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r7, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r8, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r9, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r10, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r24 \n\t" \ + "rol r22 \n\t" \ + "mul r11, r11 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "add r23, r28 \n\t" \ + "adc r24, r29 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r29, 0 \n\t" \ + "mul r2, r21 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r28, r1 \n\t" \ + "mul r3, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r4, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r5, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r6, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r7, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r8, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r9, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r10, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r11, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r28 \n\t" \ + "rol r29 \n\t" \ + "add r23, r24 \n\t" \ + "adc r28, r22 \n\t" \ + "adc r29, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ld r2, x+ \n\t" \ + "ldi r22, 0 \n\t" \ + "mul r3, r21 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r24, r1 \n\t" \ + "mul r4, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r5, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r6, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r7, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r8, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r9, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r10, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r11, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r25 \n\t" \ + "adc r22, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r24 \n\t" \ + "rol r22 \n\t" \ + "mul r12, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "add r23, r28 \n\t" \ + "adc r24, r29 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r29, 0 \n\t" \ + "mul r3, r2 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r28, r1 \n\t" \ + "mul r4, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r5, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r6, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r7, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r8, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r9, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r10, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r11, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r12, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r25 \n\t" \ + "adc r29, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r28 \n\t" \ + "rol r29 \n\t" \ + "add r23, r24 \n\t" \ + "adc r28, r22 \n\t" \ + "adc r29, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ld r3, x+ \n\t" \ + "ldi r22, 0 \n\t" \ + "mul r4, r2 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r24, r1 \n\t" \ + "mul r5, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r6, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r7, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r8, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r9, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r10, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r11, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r12, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r25 \n\t" \ + "adc r22, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r24 \n\t" \ + "rol r22 \n\t" \ + "mul r13, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "add r23, r28 \n\t" \ + "adc r24, r29 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r29, 0 \n\t" \ + "mul r4, r3 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r28, r1 \n\t" \ + "mul r5, r2 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r6, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r7, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r8, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r9, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r10, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r11, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r12, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r13, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r25 \n\t" \ + "adc r29, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r28 \n\t" \ + "rol r29 \n\t" \ + "add r23, r24 \n\t" \ + "adc r28, r22 \n\t" \ + "adc r29, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ld r4, x+ \n\t" \ + "ldi r22, 0 \n\t" \ + "mul r5, r3 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r24, r1 \n\t" \ + "mul r6, r2 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r7, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r8, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r9, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r10, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r11, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r12, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r13, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r25 \n\t" \ + "adc r22, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r24 \n\t" \ + "rol r22 \n\t" \ + "mul r14, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "add r23, r28 \n\t" \ + "adc r24, r29 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r29, 0 \n\t" \ + "mul r5, r4 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r28, r1 \n\t" \ + "mul r6, r3 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r7, r2 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r8, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r9, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r10, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r11, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r12, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r13, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r14, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r25 \n\t" \ + "adc r29, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r28 \n\t" \ + "rol r29 \n\t" \ + "add r23, r24 \n\t" \ + "adc r28, r22 \n\t" \ + "adc r29, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ld r5, x+ \n\t" \ + "ldi r22, 0 \n\t" \ + "mul r6, r4 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r24, r1 \n\t" \ + "mul r7, r3 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r8, r2 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r9, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r10, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r11, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r12, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r13, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r14, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r25 \n\t" \ + "adc r22, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r24 \n\t" \ + "rol r22 \n\t" \ + "mul r15, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "add r23, r28 \n\t" \ + "adc r24, r29 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r29, 0 \n\t" \ + "mul r6, r5 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r28, r1 \n\t" \ + "mul r7, r4 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r8, r3 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r9, r2 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r10, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r11, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r12, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r13, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r14, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r15, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r25 \n\t" \ + "adc r29, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r28 \n\t" \ + "rol r29 \n\t" \ + "add r23, r24 \n\t" \ + "adc r28, r22 \n\t" \ + "adc r29, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ld r6, x+ \n\t" \ + "ldi r22, 0 \n\t" \ + "mul r7, r5 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r24, r1 \n\t" \ + "mul r8, r4 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r9, r3 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r10, r2 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r11, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r12, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r13, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r14, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r15, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r25 \n\t" \ + "adc r22, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r24 \n\t" \ + "rol r22 \n\t" \ + "mul r16, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "add r23, r28 \n\t" \ + "adc r24, r29 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r29, 0 \n\t" \ + "mul r7, r6 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r28, r1 \n\t" \ + "mul r8, r5 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r9, r4 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r10, r3 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r11, r2 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r12, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r13, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r14, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r15, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r16, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r25 \n\t" \ + "adc r29, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r28 \n\t" \ + "rol r29 \n\t" \ + "add r23, r24 \n\t" \ + "adc r28, r22 \n\t" \ + "adc r29, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ld r7, x+ \n\t" \ + "ldi r22, 0 \n\t" \ + "mul r8, r6 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r24, r1 \n\t" \ + "mul r9, r5 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r10, r4 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r11, r3 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r12, r2 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r13, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r14, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r15, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r16, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r25 \n\t" \ + "adc r22, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r24 \n\t" \ + "rol r22 \n\t" \ + "mul r17, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "add r23, r28 \n\t" \ + "adc r24, r29 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r29, 0 \n\t" \ + "mul r8, r7 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r28, r1 \n\t" \ + "mul r9, r6 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r10, r5 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r11, r4 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r12, r3 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r13, r2 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r14, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r15, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r16, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r17, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r25 \n\t" \ + "adc r29, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r28 \n\t" \ + "rol r29 \n\t" \ + "add r23, r24 \n\t" \ + "adc r28, r22 \n\t" \ + "adc r29, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ld r8, x+ \n\t" \ + "ldi r22, 0 \n\t" \ + "mul r9, r7 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r24, r1 \n\t" \ + "mul r10, r6 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r11, r5 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r12, r4 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r13, r3 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r14, r2 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r15, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r16, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r17, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r25 \n\t" \ + "adc r22, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r24 \n\t" \ + "rol r22 \n\t" \ + "mul r18, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "add r23, r28 \n\t" \ + "adc r24, r29 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r29, 0 \n\t" \ + "mul r9, r8 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r28, r1 \n\t" \ + "mul r10, r7 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r11, r6 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r12, r5 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r13, r4 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r14, r3 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r15, r2 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r16, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r17, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r18, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r25 \n\t" \ + "adc r29, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r28 \n\t" \ + "rol r29 \n\t" \ + "add r23, r24 \n\t" \ + "adc r28, r22 \n\t" \ + "adc r29, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ld r9, x+ \n\t" \ + "ldi r22, 0 \n\t" \ + "mul r10, r8 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r24, r1 \n\t" \ + "mul r11, r7 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r12, r6 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r13, r5 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r14, r4 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r15, r3 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r16, r2 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r17, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r18, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r25 \n\t" \ + "adc r22, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r24 \n\t" \ + "rol r22 \n\t" \ + "mul r19, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "add r23, r28 \n\t" \ + "adc r24, r29 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r29, 0 \n\t" \ + "mul r10, r9 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r28, r1 \n\t" \ + "mul r11, r8 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r12, r7 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r13, r6 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r14, r5 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r15, r4 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r16, r3 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r17, r2 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r18, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r19, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r25 \n\t" \ + "adc r29, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r28 \n\t" \ + "rol r29 \n\t" \ + "add r23, r24 \n\t" \ + "adc r28, r22 \n\t" \ + "adc r29, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r22, 0 \n\t" \ + "mul r11, r9 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r24, r1 \n\t" \ + "mul r12, r8 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r13, r7 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r14, r6 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r15, r5 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r16, r4 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r17, r3 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r18, r2 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r19, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r24 \n\t" \ + "rol r22 \n\t" \ + "mul r20, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "add r23, r28 \n\t" \ + "adc r24, r29 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r29, 0 \n\t" \ + "mul r12, r9 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r28, r1 \n\t" \ + "mul r13, r8 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r14, r7 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r15, r6 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r16, r5 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r17, r4 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r18, r3 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r19, r2 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r20, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r28 \n\t" \ + "rol r29 \n\t" \ + "add r23, r24 \n\t" \ + "adc r28, r22 \n\t" \ + "adc r29, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r22, 0 \n\t" \ + "mul r13, r9 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r24, r1 \n\t" \ + "mul r14, r8 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r15, r7 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r16, r6 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r17, r5 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r18, r4 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r19, r3 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r20, r2 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r24 \n\t" \ + "rol r22 \n\t" \ + "mul r21, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "add r23, r28 \n\t" \ + "adc r24, r29 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r29, 0 \n\t" \ + "mul r14, r9 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r28, r1 \n\t" \ + "mul r15, r8 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r16, r7 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r17, r6 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r18, r5 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r19, r4 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r20, r3 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r21, r2 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r28 \n\t" \ + "rol r29 \n\t" \ + "add r23, r24 \n\t" \ + "adc r28, r22 \n\t" \ + "adc r29, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r22, 0 \n\t" \ + "mul r15, r9 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r24, r1 \n\t" \ + "mul r16, r8 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r17, r7 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r18, r6 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r19, r5 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r20, r4 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r21, r3 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r24 \n\t" \ + "rol r22 \n\t" \ + "mul r2, r2 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "add r23, r28 \n\t" \ + "adc r24, r29 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r29, 0 \n\t" \ + "mul r16, r9 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r28, r1 \n\t" \ + "mul r17, r8 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r18, r7 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r19, r6 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r20, r5 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r21, r4 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r2, r3 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r28 \n\t" \ + "rol r29 \n\t" \ + "add r23, r24 \n\t" \ + "adc r28, r22 \n\t" \ + "adc r29, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r22, 0 \n\t" \ + "mul r17, r9 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r24, r1 \n\t" \ + "mul r18, r8 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r19, r7 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r20, r6 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r21, r5 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r2, r4 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r24 \n\t" \ + "rol r22 \n\t" \ + "mul r3, r3 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "add r23, r28 \n\t" \ + "adc r24, r29 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r29, 0 \n\t" \ + "mul r18, r9 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r28, r1 \n\t" \ + "mul r19, r8 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r20, r7 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r21, r6 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r2, r5 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r3, r4 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r28 \n\t" \ + "rol r29 \n\t" \ + "add r23, r24 \n\t" \ + "adc r28, r22 \n\t" \ + "adc r29, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r22, 0 \n\t" \ + "mul r19, r9 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r24, r1 \n\t" \ + "mul r20, r8 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r21, r7 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r2, r6 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r3, r5 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r24 \n\t" \ + "rol r22 \n\t" \ + "mul r4, r4 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "add r23, r28 \n\t" \ + "adc r24, r29 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r29, 0 \n\t" \ + "mul r20, r9 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r28, r1 \n\t" \ + "mul r21, r8 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r2, r7 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r3, r6 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r4, r5 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r28 \n\t" \ + "rol r29 \n\t" \ + "add r23, r24 \n\t" \ + "adc r28, r22 \n\t" \ + "adc r29, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r22, 0 \n\t" \ + "mul r21, r9 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r24, r1 \n\t" \ + "mul r2, r8 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r3, r7 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r4, r6 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r24 \n\t" \ + "rol r22 \n\t" \ + "mul r5, r5 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "add r23, r28 \n\t" \ + "adc r24, r29 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r29, 0 \n\t" \ + "mul r2, r9 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r28, r1 \n\t" \ + "mul r3, r8 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r4, r7 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r5, r6 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r28 \n\t" \ + "rol r29 \n\t" \ + "add r23, r24 \n\t" \ + "adc r28, r22 \n\t" \ + "adc r29, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r22, 0 \n\t" \ + "mul r3, r9 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r24, r1 \n\t" \ + "mul r4, r8 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r5, r7 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r24 \n\t" \ + "rol r22 \n\t" \ + "mul r6, r6 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "add r23, r28 \n\t" \ + "adc r24, r29 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r29, 0 \n\t" \ + "mul r4, r9 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r28, r1 \n\t" \ + "mul r5, r8 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r6, r7 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r28 \n\t" \ + "rol r29 \n\t" \ + "add r23, r24 \n\t" \ + "adc r28, r22 \n\t" \ + "adc r29, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r22, 0 \n\t" \ + "mul r5, r9 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r24, r1 \n\t" \ + "mul r6, r8 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r24 \n\t" \ + "rol r22 \n\t" \ + "mul r7, r7 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "add r23, r28 \n\t" \ + "adc r24, r29 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r29, 0 \n\t" \ + "mul r6, r9 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r28, r1 \n\t" \ + "mul r7, r8 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r28 \n\t" \ + "rol r29 \n\t" \ + "add r23, r24 \n\t" \ + "adc r28, r22 \n\t" \ + "adc r29, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r23, 0 \n\t" \ + "mul r7, r9 \n\t" \ + "add r28, r0 \n\t" \ + "adc r29, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "add r28, r0 \n\t" \ + "adc r29, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r8, r8 \n\t" \ + "add r28, r0 \n\t" \ + "adc r29, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "st z+, r28 \n\t" \ + \ + "ldi r28, 0 \n\t" \ + "mul r8, r9 \n\t" \ + "add r29, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r28, r25 \n\t" \ + "add r29, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r28, r25 \n\t" \ + "st z+, r29 \n\t" \ + \ + "mul r9, r9 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "st z+, r23 \n\t" \ + "st z+, r28 \n\t" + +#define FAST_SQUARE_ASM_28_TO_32 \ + "cpi r20, 28 \n\t" \ + "brne 1f \n\t" \ + "jmp 2f \n\t" \ + "1: \n\t" \ + "ld r2, x+ \n\t" \ + "ld r3, x+ \n\t" \ + "ld r4, x+ \n\t" \ + "ld r5, x+ \n\t" \ + "sbiw r26, 32 \n\t" \ + "sbiw r30, 28 \n\t" \ + "ld r6, x+ \n\t" \ + "ld r7, x+ \n\t" \ + "ld r8, x+ \n\t" \ + "ld r9, x+ \n\t" \ + \ + "mul r2, r6 \n\t" \ + "mov r10, r0 \n\t" \ + "mov r11, r1 \n\t" \ + "mov r12, r25 \n\t" \ + "mov r13, r25 \n\t" \ + "mul r2, r7 \n\t" \ + "add r11, r0 \n\t" \ + "adc r12, r1 \n\t" \ + "adc r13, r25 \n\t" \ + "mul r3, r6 \n\t" \ + "add r11, r0 \n\t" \ + "adc r12, r1 \n\t" \ + "adc r13, r25 \n\t" \ + \ + "mov r14, r25 \n\t" \ + "mul r2, r8 \n\t" \ + "add r12, r0 \n\t" \ + "adc r13, r1 \n\t" \ + "adc r14, r25 \n\t" \ + "mul r3, r7 \n\t" \ + "add r12, r0 \n\t" \ + "adc r13, r1 \n\t" \ + "adc r14, r25 \n\t" \ + "mul r4, r6 \n\t" \ + "add r12, r0 \n\t" \ + "adc r13, r1 \n\t" \ + "adc r14, r25 \n\t" \ + \ + "mov r15, r25 \n\t" \ + "mul r2, r9 \n\t" \ + "add r13, r0 \n\t" \ + "adc r14, r1 \n\t" \ + "adc r15, r25 \n\t" \ + "mul r3, r8 \n\t" \ + "add r13, r0 \n\t" \ + "adc r14, r1 \n\t" \ + "adc r15, r25 \n\t" \ + "mul r4, r7 \n\t" \ + "add r13, r0 \n\t" \ + "adc r14, r1 \n\t" \ + "adc r15, r25 \n\t" \ + "mul r5, r6 \n\t" \ + "add r13, r0 \n\t" \ + "adc r14, r1 \n\t" \ + "adc r15, r25 \n\t" \ + \ + "ld r6, x+ \n\t" \ + "mov r16, r25 \n\t" \ + "mul r2, r6 \n\t" \ + "add r14, r0 \n\t" \ + "adc r15, r1 \n\t" \ + "adc r16, r25 \n\t" \ + "mul r3, r9 \n\t" \ + "add r14, r0 \n\t" \ + "adc r15, r1 \n\t" \ + "adc r16, r25 \n\t" \ + "mul r4, r8 \n\t" \ + "add r14, r0 \n\t" \ + "adc r15, r1 \n\t" \ + "adc r16, r25 \n\t" \ + "mul r5, r7 \n\t" \ + "add r14, r0 \n\t" \ + "adc r15, r1 \n\t" \ + "adc r16, r25 \n\t" \ + \ + "ld r7, x+ \n\t" \ + "mov r17, r25 \n\t" \ + "mul r2, r7 \n\t" \ + "add r15, r0 \n\t" \ + "adc r16, r1 \n\t" \ + "adc r17, r25 \n\t" \ + "mul r3, r6 \n\t" \ + "add r15, r0 \n\t" \ + "adc r16, r1 \n\t" \ + "adc r17, r25 \n\t" \ + "mul r4, r9 \n\t" \ + "add r15, r0 \n\t" \ + "adc r16, r1 \n\t" \ + "adc r17, r25 \n\t" \ + "mul r5, r8 \n\t" \ + "add r15, r0 \n\t" \ + "adc r16, r1 \n\t" \ + "adc r17, r25 \n\t" \ + \ + "ld r8, x+ \n\t" \ + "mov r18, r25 \n\t" \ + "mul r2, r8 \n\t" \ + "add r16, r0 \n\t" \ + "adc r17, r1 \n\t" \ + "adc r18, r25 \n\t" \ + "mul r3, r7 \n\t" \ + "add r16, r0 \n\t" \ + "adc r17, r1 \n\t" \ + "adc r18, r25 \n\t" \ + "mul r4, r6 \n\t" \ + "add r16, r0 \n\t" \ + "adc r17, r1 \n\t" \ + "adc r18, r25 \n\t" \ + "mul r5, r9 \n\t" \ + "add r16, r0 \n\t" \ + "adc r17, r1 \n\t" \ + "adc r18, r25 \n\t" \ + \ + "ld r9, x+ \n\t" \ + "mov r19, r25 \n\t" \ + "mul r2, r9 \n\t" \ + "add r17, r0 \n\t" \ + "adc r18, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r3, r8 \n\t" \ + "add r17, r0 \n\t" \ + "adc r18, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r4, r7 \n\t" \ + "add r17, r0 \n\t" \ + "adc r18, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r5, r6 \n\t" \ + "add r17, r0 \n\t" \ + "adc r18, r1 \n\t" \ + "adc r19, r25 \n\t" \ + \ + "ld r6, x+ \n\t" \ + "mov r21, r25 \n\t" \ + "mul r2, r6 \n\t" \ + "add r18, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r3, r9 \n\t" \ + "add r18, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r4, r8 \n\t" \ + "add r18, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r5, r7 \n\t" \ + "add r18, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r21, r25 \n\t" \ + \ + "ld r7, x+ \n\t" \ + "mov r22, r25 \n\t" \ + "mul r2, r7 \n\t" \ + "add r19, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r3, r6 \n\t" \ + "add r19, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r4, r9 \n\t" \ + "add r19, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r5, r8 \n\t" \ + "add r19, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r22, r25 \n\t" \ + \ + "ld r8, x+ \n\t" \ + "mov r23, r25 \n\t" \ + "mul r2, r8 \n\t" \ + "add r21, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r3, r7 \n\t" \ + "add r21, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r4, r6 \n\t" \ + "add r21, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r5, r9 \n\t" \ + "add r21, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + \ + "ld r9, x+ \n\t" \ + "mov r24, r25 \n\t" \ + "mul r2, r9 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r3, r8 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r4, r7 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r5, r6 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + \ + "ld r6, x+ \n\t" \ + "mov r28, r25 \n\t" \ + "mul r2, r6 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r28, r25 \n\t" \ + "mul r3, r9 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r28, r25 \n\t" \ + "mul r4, r8 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r28, r25 \n\t" \ + "mul r5, r7 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r28, r25 \n\t" \ + \ + "ld r7, x+ \n\t" \ + "mov r29, r25 \n\t" \ + "mul r2, r7 \n\t" \ + "add r24, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r3, r6 \n\t" \ + "add r24, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r4, r9 \n\t" \ + "add r24, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r5, r8 \n\t" \ + "add r24, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + \ + "lsl r10 \n\t" \ + "rol r11 \n\t" \ + "rol r12 \n\t" \ + "rol r13 \n\t" \ + "rol r14 \n\t" \ + "rol r15 \n\t" \ + "rol r16 \n\t" \ + "rol r17 \n\t" \ + "rol r18 \n\t" \ + "rol r19 \n\t" \ + "rol r21 \n\t" \ + "rol r22 \n\t" \ + "rol r23 \n\t" \ + "rol r24 \n\t" \ + "rol r28 \n\t" \ + "rol r29 \n\t" \ + "ld r0, z \n\t" \ + "add r10, r0 \n\t" \ + "st z+, r10 \n\t" \ + "ld r0, z \n\t" \ + "adc r11, r0 \n\t" \ + "st z+, r11 \n\t" \ + "ld r0, z \n\t" \ + "adc r12, r0 \n\t" \ + "st z+, r12 \n\t" \ + "ld r0, z \n\t" \ + "adc r13, r0 \n\t" \ + "st z+, r13 \n\t" \ + "ld r0, z \n\t" \ + "adc r14, r0 \n\t" \ + "st z+, r14 \n\t" \ + "ld r0, z \n\t" \ + "adc r15, r0 \n\t" \ + "st z+, r15 \n\t" \ + "ld r0, z \n\t" \ + "adc r16, r0 \n\t" \ + "st z+, r16 \n\t" \ + "ld r0, z \n\t" \ + "adc r17, r0 \n\t" \ + "st z+, r17 \n\t" \ + "ld r0, z \n\t" \ + "adc r18, r0 \n\t" \ + "st z+, r18 \n\t" \ + "ld r0, z \n\t" \ + "adc r19, r0 \n\t" \ + "st z+, r19 \n\t" \ + "ld r0, z \n\t" \ + "adc r21, r0 \n\t" \ + "st z+, r21 \n\t" \ + "ld r0, z \n\t" \ + "adc r22, r0 \n\t" \ + "st z+, r22 \n\t" \ + "ld r0, z \n\t" \ + "adc r23, r0 \n\t" \ + "st z+, r23 \n\t" \ + "ld r0, z \n\t" \ + "adc r24, r0 \n\t" \ + "st z+, r24 \n\t" \ + "adc r28, r25 \n\t" \ + "adc r29, r25 \n\t" \ + "bst r28, 0 \n\t" \ + "lsr r29 \n\t" \ + "ror r28 \n\t" \ + \ + "ld r8, x+ \n\t" \ + "mov r10, r25 \n\t" \ + "mul r2, r8 \n\t" \ + "add r28, r0 \n\t" \ + "adc r29, r1 \n\t" \ + "adc r10, r25 \n\t" \ + "mul r3, r7 \n\t" \ + "add r28, r0 \n\t" \ + "adc r29, r1 \n\t" \ + "adc r10, r25 \n\t" \ + "mul r4, r6 \n\t" \ + "add r28, r0 \n\t" \ + "adc r29, r1 \n\t" \ + "adc r10, r25 \n\t" \ + "mul r5, r9 \n\t" \ + "add r28, r0 \n\t" \ + "adc r29, r1 \n\t" \ + "adc r10, r25 \n\t" \ + \ + "ld r9, x+ \n\t" \ + "mov r11, r25 \n\t" \ + "mul r2, r9 \n\t" \ + "add r29, r0 \n\t" \ + "adc r10, r1 \n\t" \ + "adc r11, r25 \n\t" \ + "mul r3, r8 \n\t" \ + "add r29, r0 \n\t" \ + "adc r10, r1 \n\t" \ + "adc r11, r25 \n\t" \ + "mul r4, r7 \n\t" \ + "add r29, r0 \n\t" \ + "adc r10, r1 \n\t" \ + "adc r11, r25 \n\t" \ + "mul r5, r6 \n\t" \ + "add r29, r0 \n\t" \ + "adc r10, r1 \n\t" \ + "adc r11, r25 \n\t" \ + \ + "ld r6, x+ \n\t" \ + "mov r12, r25 \n\t" \ + "mul r2, r6 \n\t" \ + "add r10, r0 \n\t" \ + "adc r11, r1 \n\t" \ + "adc r12, r25 \n\t" \ + "mul r3, r9 \n\t" \ + "add r10, r0 \n\t" \ + "adc r11, r1 \n\t" \ + "adc r12, r25 \n\t" \ + "mul r4, r8 \n\t" \ + "add r10, r0 \n\t" \ + "adc r11, r1 \n\t" \ + "adc r12, r25 \n\t" \ + "mul r5, r7 \n\t" \ + "add r10, r0 \n\t" \ + "adc r11, r1 \n\t" \ + "adc r12, r25 \n\t" \ + \ + "ld r7, x+ \n\t" \ + "mov r13, r25 \n\t" \ + "mul r2, r7 \n\t" \ + "add r11, r0 \n\t" \ + "adc r12, r1 \n\t" \ + "adc r13, r25 \n\t" \ + "mul r3, r6 \n\t" \ + "add r11, r0 \n\t" \ + "adc r12, r1 \n\t" \ + "adc r13, r25 \n\t" \ + "mul r4, r9 \n\t" \ + "add r11, r0 \n\t" \ + "adc r12, r1 \n\t" \ + "adc r13, r25 \n\t" \ + "mul r5, r8 \n\t" \ + "add r11, r0 \n\t" \ + "adc r12, r1 \n\t" \ + "adc r13, r25 \n\t" \ + \ + "ld r8, x+ \n\t" \ + "mov r14, r25 \n\t" \ + "mul r2, r8 \n\t" \ + "add r12, r0 \n\t" \ + "adc r13, r1 \n\t" \ + "adc r14, r25 \n\t" \ + "mul r3, r7 \n\t" \ + "add r12, r0 \n\t" \ + "adc r13, r1 \n\t" \ + "adc r14, r25 \n\t" \ + "mul r4, r6 \n\t" \ + "add r12, r0 \n\t" \ + "adc r13, r1 \n\t" \ + "adc r14, r25 \n\t" \ + "mul r5, r9 \n\t" \ + "add r12, r0 \n\t" \ + "adc r13, r1 \n\t" \ + "adc r14, r25 \n\t" \ + \ + "ld r9, x+ \n\t" \ + "mov r15, r25 \n\t" \ + "mul r2, r9 \n\t" \ + "add r13, r0 \n\t" \ + "adc r14, r1 \n\t" \ + "adc r15, r25 \n\t" \ + "mul r3, r8 \n\t" \ + "add r13, r0 \n\t" \ + "adc r14, r1 \n\t" \ + "adc r15, r25 \n\t" \ + "mul r4, r7 \n\t" \ + "add r13, r0 \n\t" \ + "adc r14, r1 \n\t" \ + "adc r15, r25 \n\t" \ + "mul r5, r6 \n\t" \ + "add r13, r0 \n\t" \ + "adc r14, r1 \n\t" \ + "adc r15, r25 \n\t" \ + \ + "ld r6, x+ \n\t" \ + "mov r16, r25 \n\t" \ + "mul r2, r6 \n\t" \ + "add r14, r0 \n\t" \ + "adc r15, r1 \n\t" \ + "adc r16, r25 \n\t" \ + "mul r3, r9 \n\t" \ + "add r14, r0 \n\t" \ + "adc r15, r1 \n\t" \ + "adc r16, r25 \n\t" \ + "mul r4, r8 \n\t" \ + "add r14, r0 \n\t" \ + "adc r15, r1 \n\t" \ + "adc r16, r25 \n\t" \ + "mul r5, r7 \n\t" \ + "add r14, r0 \n\t" \ + "adc r15, r1 \n\t" \ + "adc r16, r25 \n\t" \ + \ + "ld r7, x+ \n\t" \ + "mov r17, r25 \n\t" \ + "mul r2, r7 \n\t" \ + "add r15, r0 \n\t" \ + "adc r16, r1 \n\t" \ + "adc r17, r25 \n\t" \ + "mul r3, r6 \n\t" \ + "add r15, r0 \n\t" \ + "adc r16, r1 \n\t" \ + "adc r17, r25 \n\t" \ + "mul r4, r9 \n\t" \ + "add r15, r0 \n\t" \ + "adc r16, r1 \n\t" \ + "adc r17, r25 \n\t" \ + "mul r5, r8 \n\t" \ + "add r15, r0 \n\t" \ + "adc r16, r1 \n\t" \ + "adc r17, r25 \n\t" \ + \ + "ld r8, x+ \n\t" \ + "mov r18, r25 \n\t" \ + "mul r2, r8 \n\t" \ + "add r16, r0 \n\t" \ + "adc r17, r1 \n\t" \ + "adc r18, r25 \n\t" \ + "mul r3, r7 \n\t" \ + "add r16, r0 \n\t" \ + "adc r17, r1 \n\t" \ + "adc r18, r25 \n\t" \ + "mul r4, r6 \n\t" \ + "add r16, r0 \n\t" \ + "adc r17, r1 \n\t" \ + "adc r18, r25 \n\t" \ + "mul r5, r9 \n\t" \ + "add r16, r0 \n\t" \ + "adc r17, r1 \n\t" \ + "adc r18, r25 \n\t" \ + \ + "ld r9, x+ \n\t" \ + "mov r19, r25 \n\t" \ + "mul r2, r9 \n\t" \ + "add r17, r0 \n\t" \ + "adc r18, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r3, r8 \n\t" \ + "add r17, r0 \n\t" \ + "adc r18, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r4, r7 \n\t" \ + "add r17, r0 \n\t" \ + "adc r18, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r5, r6 \n\t" \ + "add r17, r0 \n\t" \ + "adc r18, r1 \n\t" \ + "adc r19, r25 \n\t" \ + \ + "ld r6, x+ \n\t" \ + "mov r21, r25 \n\t" \ + "mul r2, r6 \n\t" \ + "add r18, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r3, r9 \n\t" \ + "add r18, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r4, r8 \n\t" \ + "add r18, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r5, r7 \n\t" \ + "add r18, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r21, r25 \n\t" \ + \ + "ld r7, x+ \n\t" \ + "mov r22, r25 \n\t" \ + "mul r2, r7 \n\t" \ + "add r19, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r3, r6 \n\t" \ + "add r19, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r4, r9 \n\t" \ + "add r19, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r5, r8 \n\t" \ + "add r19, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r22, r25 \n\t" \ + \ + "ld r8, x+ \n\t" \ + "mov r23, r25 \n\t" \ + "mul r2, r8 \n\t" \ + "add r21, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r3, r7 \n\t" \ + "add r21, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r4, r6 \n\t" \ + "add r21, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r5, r9 \n\t" \ + "add r21, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + \ + "ld r9, x+ \n\t" \ + "mov r24, r25 \n\t" \ + "mul r2, r9 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r3, r8 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r4, r7 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r5, r6 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + \ + "lsl r28 \n\t" \ + "bld r28, 0 \n\t" \ + "rol r29 \n\t" \ + "rol r10 \n\t" \ + "rol r11 \n\t" \ + "rol r12 \n\t" \ + "rol r13 \n\t" \ + "rol r14 \n\t" \ + "rol r15 \n\t" \ + "rol r16 \n\t" \ + "rol r17 \n\t" \ + "rol r18 \n\t" \ + "rol r19 \n\t" \ + "rol r21 \n\t" \ + "rol r22 \n\t" \ + "rol r23 \n\t" \ + "rol r24 \n\t" \ + "ld r0, z \n\t" \ + "add r28, r0 \n\t" \ + "st z+, r28 \n\t" \ + "ld r0, z \n\t" \ + "adc r29, r0 \n\t" \ + "st z+, r29 \n\t" \ + "ld r0, z \n\t" \ + "adc r10, r0 \n\t" \ + "st z+, r10 \n\t" \ + "ld r0, z \n\t" \ + "adc r11, r0 \n\t" \ + "st z+, r11 \n\t" \ + "ld r0, z \n\t" \ + "adc r12, r0 \n\t" \ + "st z+, r12 \n\t" \ + "ld r0, z \n\t" \ + "adc r13, r0 \n\t" \ + "st z+, r13 \n\t" \ + "ld r0, z \n\t" \ + "adc r14, r0 \n\t" \ + "st z+, r14 \n\t" \ + "ld r0, z \n\t" \ + "adc r15, r0 \n\t" \ + "st z+, r15 \n\t" \ + "ld r0, z \n\t" \ + "adc r16, r0 \n\t" \ + "st z+, r16 \n\t" \ + "ld r0, z \n\t" \ + "adc r17, r0 \n\t" \ + "st z+, r17 \n\t" \ + "ld r0, z \n\t" \ + "adc r18, r0 \n\t" \ + "st z+, r18 \n\t" \ + "ld r0, z \n\t" \ + "adc r19, r0 \n\t" \ + "st z+, r19 \n\t" \ + "ld r0, z \n\t" \ + "adc r21, r0 \n\t" \ + "st z+, r21 \n\t" \ + "ld r0, z \n\t" \ + "adc r22, r0 \n\t" \ + "st z+, r22 \n\t" \ + "adc r23, r25 \n\t" \ + "adc r24, r25 \n\t" \ + \ + "mul r2, r2 \n\t" \ + "mov r28, r0 \n\t" \ + "mov r29, r1 \n\t" \ + "mul r3, r3 \n\t" \ + "mov r10, r0 \n\t" \ + "mov r11, r1 \n\t" \ + "mul r4, r4 \n\t" \ + "mov r12, r0 \n\t" \ + "mov r13, r1 \n\t" \ + "mul r5, r5 \n\t" \ + "mov r14, r0 \n\t" \ + "mov r15, r1 \n\t" \ + "add r28, r23 \n\t" \ + "adc r29, r24 \n\t" \ + "adc r10, r25 \n\t" \ + "adc r11, r25 \n\t" \ + \ + "mul r7, r5 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r24, r1 \n\t" \ + "mov r16, r25 \n\t" \ + "mul r8, r4 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r16, r25 \n\t" \ + "mul r9, r3 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r16, r25 \n\t" \ + "mov r17, r25 \n\t" \ + "mul r8, r5 \n\t" \ + "add r24, r0 \n\t" \ + "adc r16, r1 \n\t" \ + "adc r17, r25 \n\t" \ + "mul r9, r4 \n\t" \ + "add r24, r0 \n\t" \ + "adc r16, r1 \n\t" \ + "adc r17, r25 \n\t" \ + "mul r2, r3 \n\t" \ + "add r24, r0 \n\t" \ + "adc r16, r1 \n\t" \ + "adc r17, r25 \n\t" \ + "mov r18, r25 \n\t" \ + "mul r9, r5 \n\t" \ + "add r16, r0 \n\t" \ + "adc r17, r1 \n\t" \ + "adc r18, r25 \n\t" \ + "mul r2, r4 \n\t" \ + "add r16, r0 \n\t" \ + "adc r17, r1 \n\t" \ + "adc r18, r25 \n\t" \ + "mov r19, r25 \n\t" \ + "mul r2, r5 \n\t" \ + "add r17, r0 \n\t" \ + "adc r18, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r3, r4 \n\t" \ + "add r17, r0 \n\t" \ + "adc r18, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mov r21, r25 \n\t" \ + "mul r3, r5 \n\t" \ + "add r18, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r4, r5 \n\t" \ + "add r19, r0 \n\t" \ + "adc r21, r1 \n\t" \ + \ + "lsl r23 \n\t" \ + "rol r24 \n\t" \ + "rol r16 \n\t" \ + "rol r17 \n\t" \ + "rol r18 \n\t" \ + "rol r19 \n\t" \ + "rol r21 \n\t" \ + "adc r15, r25 \n\t" \ + "add r28, r23 \n\t" \ + "adc r29, r24 \n\t" \ + "adc r10, r16 \n\t" \ + "adc r11, r17 \n\t" \ + "adc r12, r18 \n\t" \ + "adc r13, r19 \n\t" \ + "adc r14, r21 \n\t" \ + "adc r15, r25 \n\t" \ + \ + "st z+, r28 \n\t" \ + "st z+, r29 \n\t" \ + "st z+, r10 \n\t" \ + "st z+, r11 \n\t" \ + "st z+, r12 \n\t" \ + "st z+, r13 \n\t" \ + "st z+, r14 \n\t" \ + "st z+, r15 \n\t" \ + "adiw r26, 4 \n\t" + +#define FAST_SQUARE_ASM_32 \ + "ldi r25, 0 \n\t" \ + "movw r28, r26 \n\t" \ + "ld r2, x+ \n\t" \ + "ld r3, x+ \n\t" \ + "ld r4, x+ \n\t" \ + "ld r5, x+ \n\t" \ + "ld r6, x+ \n\t" \ + "ld r7, x+ \n\t" \ + "adiw r28, 20 \n\t" \ + "ld r12, y+ \n\t" \ + "ld r13, y+ \n\t" \ + "ld r14, y+ \n\t" \ + "ld r15, y+ \n\t" \ + "ld r16, y+ \n\t" \ + "ld r17, y+ \n\t" \ + "adiw r30, 20 \n\t" \ + \ + "ldi r23, 0 \n\t" \ + "mul 2, 12 \n\t" \ + "st z+, r0 \n\t" \ + "mov r22, r1 \n\t" \ + \ + "ldi r24, 0 \n\t" \ + "mul r2, r13 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ldi r22, 0 \n\t" \ + "mul r2, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r3, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r23, 0 \n\t" \ + "mul r2, r15 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r3, r14 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "st z+, r24 \n\t" \ + \ + "ldi r24, 0 \n\t" \ + "mul r2, r16 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r3, r15 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r4, r14 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ldi r22, 0 \n\t" \ + "mul r2, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r3, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r4, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ld r12, y+ \n\t" \ + "ldi r23, 0 \n\t" \ + "mul r2, r12 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r3, r17 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r4, r16 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r5, r15 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "st z+, r24 \n\t" \ + \ + "ld r13, y+ \n\t" \ + "ldi r24, 0 \n\t" \ + "mul r2, r13 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r3, r12 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r4, r17 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r5, r16 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ld r14, y+ \n\t" \ + "ldi r22, 0 \n\t" \ + "mul r2, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r3, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r4, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r5, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r6, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ld r15, y+ \n\t" \ + "ldi r23, 0 \n\t" \ + "mul r2, r15 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r3, r14 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r4, r13 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r5, r12 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r6, r17 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "st z+, r24 \n\t" \ + \ + "ld r16, y+ \n\t" \ + "ldi r24, 0 \n\t" \ + "mul r2, r16 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r3, r15 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r4, r14 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r5, r13 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r6, r12 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r7, r17 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ld r17, y+ \n\t" \ + "ldi r22, 0 \n\t" \ + "mul r2, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r3, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r4, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r5, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r6, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r7, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ld r2, x+ \n\t" \ + "ldi r23, 0 \n\t" \ + "mul r3, r17 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r4, r16 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r5, r15 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r6, r14 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r7, r13 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r2, r12 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "st z+, r24 \n\t" \ + \ + "ld r3, x+ \n\t" \ + "ldi r24, 0 \n\t" \ + "mul r4, r17 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r5, r16 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r6, r15 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r7, r14 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r2, r13 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ld r4, x+ \n\t" \ + "ldi r22, 0 \n\t" \ + "mul r5, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r6, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r7, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r2, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r3, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ld r5, x+ \n\t" \ + "ldi r23, 0 \n\t" \ + "mul r6, r17 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r7, r16 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r2, r15 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r3, r14 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "st z+, r24 \n\t" \ + \ + "ld r6, x+ \n\t" \ + "ldi r24, 0 \n\t" \ + "mul r7, r17 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r2, r16 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r3, r15 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r4, r14 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ld r7, x+ \n\t" \ + "ldi r22, 0 \n\t" \ + "mul r2, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r3, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r4, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r23, 0 \n\t" \ + "mul r3, r17 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r4, r16 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r5, r15 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "st z+, r24 \n\t" \ + \ + "ldi r24, 0 \n\t" \ + "mul r4, r17 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r5, r16 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ldi r22, 0 \n\t" \ + "mul r5, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r6, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r23, 0 \n\t" \ + "mul r6, r17 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "st z+, r24 \n\t" \ + \ + "mul r7, r17 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "st z+, r22 \n\t" \ + "st z+, r23 \n\t" \ + \ + "sbiw r26, 12 \n\t" \ + "sbiw r30, 44 \n\t" \ + "ld r2, x+ \n\t" \ + "ld r3, x+ \n\t" \ + "ld r4, x+ \n\t" \ + "ld r5, x+ \n\t" \ + "ld r6, x+ \n\t" \ + "ld r7, x+ \n\t" \ + "ld r8, x+ \n\t" \ + "ld r9, x+ \n\t" \ + "ld r10, x+ \n\t" \ + "ld r11, x+ \n\t" \ + "ld r12, x+ \n\t" \ + "ld r13, x+ \n\t" \ + "ld r14, x+ \n\t" \ + "ld r15, x+ \n\t" \ + "ld r16, x+ \n\t" \ + "ld r17, x+ \n\t" \ + "ld r18, x+ \n\t" \ + "ld r19, x+ \n\t" \ + "ld r20, x+ \n\t" \ + "ld r21, x+ \n\t" \ + \ + "ldi r23, 0 \n\t" \ + "mul r2, r2 \n\t" \ + "st z+, r0 \n\t" \ + "mov r22, r1 \n\t" \ + \ + "ldi r24, 0 \n\t" \ + "mul r2, r3 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ldi r22, 0 \n\t" \ + "mul r2, r4 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r3, r3 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r29, 0 \n\t" \ + "mul r2, r5 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r28, r1 \n\t" \ + "mul r3, r4 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r28 \n\t" \ + "rol r29 \n\t" \ + "add r23, r24 \n\t" \ + "adc r28, r22 \n\t" \ + "adc r29, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r22, 0 \n\t" \ + "mul r2, r6 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r24, r1 \n\t" \ + "mul r3, r5 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r24 \n\t" \ + "rol r22 \n\t" \ + "mul r4, r4 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "add r23, r28 \n\t" \ + "adc r24, r29 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r29, 0 \n\t" \ + "mul r2, r7 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r28, r1 \n\t" \ + "mul r3, r6 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r4, r5 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r28 \n\t" \ + "rol r29 \n\t" \ + "add r23, r24 \n\t" \ + "adc r28, r22 \n\t" \ + "adc r29, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r22, 0 \n\t" \ + "mul r2, r8 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r24, r1 \n\t" \ + "mul r3, r7 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r4, r6 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r24 \n\t" \ + "rol r22 \n\t" \ + "mul r5, r5 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "add r23, r28 \n\t" \ + "adc r24, r29 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r29, 0 \n\t" \ + "mul r2, r9 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r28, r1 \n\t" \ + "mul r3, r8 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r4, r7 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r5, r6 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r28 \n\t" \ + "rol r29 \n\t" \ + "add r23, r24 \n\t" \ + "adc r28, r22 \n\t" \ + "adc r29, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r22, 0 \n\t" \ + "mul r2, r10 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r24, r1 \n\t" \ + "mul r3, r9 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r4, r8 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r5, r7 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r24 \n\t" \ + "rol r22 \n\t" \ + "mul r6, r6 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "add r23, r28 \n\t" \ + "adc r24, r29 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r29, 0 \n\t" \ + "mul r2, r11 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r28, r1 \n\t" \ + "mul r3, r10 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r4, r9 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r5, r8 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r6, r7 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r28 \n\t" \ + "rol r29 \n\t" \ + "add r23, r24 \n\t" \ + "adc r28, r22 \n\t" \ + "adc r29, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r22, 0 \n\t" \ + "mul r2, r12 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r24, r1 \n\t" \ + "mul r3, r11 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r4, r10 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r5, r9 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r6, r8 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r24 \n\t" \ + "rol r22 \n\t" \ + "mul r7, r7 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "add r23, r28 \n\t" \ + "adc r24, r29 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r29, 0 \n\t" \ + "mul r2, r13 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r28, r1 \n\t" \ + "mul r3, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r4, r11 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r5, r10 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r6, r9 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r7, r8 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r28 \n\t" \ + "rol r29 \n\t" \ + "add r23, r24 \n\t" \ + "adc r28, r22 \n\t" \ + "adc r29, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r22, 0 \n\t" \ + "mul r2, r14 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r24, r1 \n\t" \ + "mul r3, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r4, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r5, r11 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r6, r10 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r7, r9 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r24 \n\t" \ + "rol r22 \n\t" \ + "mul r8, r8 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "add r23, r28 \n\t" \ + "adc r24, r29 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r29, 0 \n\t" \ + "mul r2, r15 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r28, r1 \n\t" \ + "mul r3, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r4, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r5, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r6, r11 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r7, r10 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r8, r9 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r28 \n\t" \ + "rol r29 \n\t" \ + "add r23, r24 \n\t" \ + "adc r28, r22 \n\t" \ + "adc r29, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r22, 0 \n\t" \ + "mul r2, r16 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r24, r1 \n\t" \ + "mul r3, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r4, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r5, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r6, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r7, r11 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r8, r10 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r24 \n\t" \ + "rol r22 \n\t" \ + "mul r9, r9 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "add r23, r28 \n\t" \ + "adc r24, r29 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r29, 0 \n\t" \ + "mul r2, r17 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r28, r1 \n\t" \ + "mul r3, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r4, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r5, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r6, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r7, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r8, r11 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r9, r10 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r28 \n\t" \ + "rol r29 \n\t" \ + "add r23, r24 \n\t" \ + "adc r28, r22 \n\t" \ + "adc r29, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r22, 0 \n\t" \ + "mul r2, r18 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r24, r1 \n\t" \ + "mul r3, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r4, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r5, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r6, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r7, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r8, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r9, r11 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r24 \n\t" \ + "rol r22 \n\t" \ + "mul r10, r10 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "add r23, r28 \n\t" \ + "adc r24, r29 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r29, 0 \n\t" \ + "mul r2, r19 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r28, r1 \n\t" \ + "mul r3, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r4, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r5, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r6, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r7, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r8, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r9, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r10, r11 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r28 \n\t" \ + "rol r29 \n\t" \ + "add r23, r24 \n\t" \ + "adc r28, r22 \n\t" \ + "adc r29, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r22, 0 \n\t" \ + "mul r2, r20 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r24, r1 \n\t" \ + "mul r3, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r4, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r5, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r6, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r7, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r8, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r9, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r10, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r24 \n\t" \ + "rol r22 \n\t" \ + "mul r11, r11 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "add r23, r28 \n\t" \ + "adc r24, r29 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r29, 0 \n\t" \ + "mul r2, r21 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r28, r1 \n\t" \ + "mul r3, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r4, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r5, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r6, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r7, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r8, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r9, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r10, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r11, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r28 \n\t" \ + "rol r29 \n\t" \ + "add r23, r24 \n\t" \ + "adc r28, r22 \n\t" \ + "adc r29, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ld r2, x+ \n\t" \ + "ldi r22, 0 \n\t" \ + "mul r3, r21 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r24, r1 \n\t" \ + "mul r4, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r5, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r6, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r7, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r8, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r9, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r10, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r11, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r25 \n\t" \ + "adc r22, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r24 \n\t" \ + "rol r22 \n\t" \ + "mul r12, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "add r23, r28 \n\t" \ + "adc r24, r29 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r29, 0 \n\t" \ + "mul r3, r2 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r28, r1 \n\t" \ + "mul r4, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r5, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r6, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r7, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r8, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r9, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r10, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r11, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r12, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r25 \n\t" \ + "adc r29, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r28 \n\t" \ + "rol r29 \n\t" \ + "add r23, r24 \n\t" \ + "adc r28, r22 \n\t" \ + "adc r29, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ld r3, x+ \n\t" \ + "ldi r22, 0 \n\t" \ + "mul r4, r2 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r24, r1 \n\t" \ + "mul r5, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r6, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r7, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r8, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r9, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r10, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r11, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r12, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r25 \n\t" \ + "adc r22, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r24 \n\t" \ + "rol r22 \n\t" \ + "mul r13, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "add r23, r28 \n\t" \ + "adc r24, r29 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r29, 0 \n\t" \ + "mul r4, r3 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r28, r1 \n\t" \ + "mul r5, r2 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r6, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r7, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r8, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r9, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r10, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r11, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r12, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r13, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r25 \n\t" \ + "adc r29, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r28 \n\t" \ + "rol r29 \n\t" \ + "add r23, r24 \n\t" \ + "adc r28, r22 \n\t" \ + "adc r29, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ld r4, x+ \n\t" \ + "ldi r22, 0 \n\t" \ + "mul r5, r3 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r24, r1 \n\t" \ + "mul r6, r2 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r7, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r8, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r9, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r10, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r11, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r12, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r13, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r25 \n\t" \ + "adc r22, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r24 \n\t" \ + "rol r22 \n\t" \ + "mul r14, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "add r23, r28 \n\t" \ + "adc r24, r29 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r29, 0 \n\t" \ + "mul r5, r4 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r28, r1 \n\t" \ + "mul r6, r3 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r7, r2 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r8, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r9, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r10, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r11, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r12, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r13, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r14, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r25 \n\t" \ + "adc r29, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r28 \n\t" \ + "rol r29 \n\t" \ + "add r23, r24 \n\t" \ + "adc r28, r22 \n\t" \ + "adc r29, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ld r5, x+ \n\t" \ + "ldi r22, 0 \n\t" \ + "mul r6, r4 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r24, r1 \n\t" \ + "mul r7, r3 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r8, r2 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r9, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r10, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r11, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r12, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r13, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r14, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r25 \n\t" \ + "adc r22, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r24 \n\t" \ + "rol r22 \n\t" \ + "mul r15, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "add r23, r28 \n\t" \ + "adc r24, r29 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r29, 0 \n\t" \ + "mul r6, r5 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r28, r1 \n\t" \ + "mul r7, r4 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r8, r3 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r9, r2 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r10, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r11, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r12, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r13, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r14, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r15, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r25 \n\t" \ + "adc r29, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r28 \n\t" \ + "rol r29 \n\t" \ + "add r23, r24 \n\t" \ + "adc r28, r22 \n\t" \ + "adc r29, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ld r6, x+ \n\t" \ + "ldi r22, 0 \n\t" \ + "mul r7, r5 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r24, r1 \n\t" \ + "mul r8, r4 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r9, r3 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r10, r2 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r11, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r12, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r13, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r14, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r15, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r25 \n\t" \ + "adc r22, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r24 \n\t" \ + "rol r22 \n\t" \ + "mul r16, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "add r23, r28 \n\t" \ + "adc r24, r29 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r29, 0 \n\t" \ + "mul r7, r6 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r28, r1 \n\t" \ + "mul r8, r5 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r9, r4 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r10, r3 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r11, r2 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r12, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r13, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r14, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r15, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r16, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r25 \n\t" \ + "adc r29, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r28 \n\t" \ + "rol r29 \n\t" \ + "add r23, r24 \n\t" \ + "adc r28, r22 \n\t" \ + "adc r29, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ld r7, x+ \n\t" \ + "ldi r22, 0 \n\t" \ + "mul r8, r6 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r24, r1 \n\t" \ + "mul r9, r5 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r10, r4 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r11, r3 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r12, r2 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r13, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r14, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r15, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r16, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r25 \n\t" \ + "adc r22, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r24 \n\t" \ + "rol r22 \n\t" \ + "mul r17, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "add r23, r28 \n\t" \ + "adc r24, r29 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r29, 0 \n\t" \ + "mul r8, r7 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r28, r1 \n\t" \ + "mul r9, r6 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r10, r5 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r11, r4 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r12, r3 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r13, r2 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r14, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r15, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r16, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r17, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r25 \n\t" \ + "adc r29, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r28 \n\t" \ + "rol r29 \n\t" \ + "add r23, r24 \n\t" \ + "adc r28, r22 \n\t" \ + "adc r29, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ld r8, x+ \n\t" \ + "ldi r22, 0 \n\t" \ + "mul r9, r7 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r24, r1 \n\t" \ + "mul r10, r6 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r11, r5 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r12, r4 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r13, r3 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r14, r2 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r15, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r16, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r17, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r25 \n\t" \ + "adc r22, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r24 \n\t" \ + "rol r22 \n\t" \ + "mul r18, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "add r23, r28 \n\t" \ + "adc r24, r29 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r29, 0 \n\t" \ + "mul r9, r8 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r28, r1 \n\t" \ + "mul r10, r7 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r11, r6 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r12, r5 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r13, r4 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r14, r3 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r15, r2 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r16, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r17, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r18, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r25 \n\t" \ + "adc r29, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r28 \n\t" \ + "rol r29 \n\t" \ + "add r23, r24 \n\t" \ + "adc r28, r22 \n\t" \ + "adc r29, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ld r9, x+ \n\t" \ + "ldi r22, 0 \n\t" \ + "mul r10, r8 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r24, r1 \n\t" \ + "mul r11, r7 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r12, r6 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r13, r5 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r14, r4 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r15, r3 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r16, r2 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r17, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r18, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r25 \n\t" \ + "adc r22, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r24 \n\t" \ + "rol r22 \n\t" \ + "mul r19, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "add r23, r28 \n\t" \ + "adc r24, r29 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r29, 0 \n\t" \ + "mul r10, r9 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r28, r1 \n\t" \ + "mul r11, r8 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r12, r7 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r13, r6 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r14, r5 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r15, r4 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r16, r3 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r17, r2 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r18, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r19, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r25 \n\t" \ + "adc r29, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r28 \n\t" \ + "rol r29 \n\t" \ + "add r23, r24 \n\t" \ + "adc r28, r22 \n\t" \ + "adc r29, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ld r10, x+ \n\t" \ + "ldi r22, 0 \n\t" \ + "mul r11, r9 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r24, r1 \n\t" \ + "mul r12, r8 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r13, r7 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r14, r6 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r15, r5 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r16, r4 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r17, r3 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r18, r2 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r19, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r25 \n\t" \ + "adc r22, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r24 \n\t" \ + "rol r22 \n\t" \ + "mul r20, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "add r23, r28 \n\t" \ + "adc r24, r29 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r29, 0 \n\t" \ + "mul r11, r10 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r28, r1 \n\t" \ + "mul r12, r9 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r13, r8 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r14, r7 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r15, r6 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r16, r5 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r17, r4 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r18, r3 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r19, r2 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r20, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r25 \n\t" \ + "adc r29, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r28 \n\t" \ + "rol r29 \n\t" \ + "add r23, r24 \n\t" \ + "adc r28, r22 \n\t" \ + "adc r29, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ld r11, x+ \n\t" \ + "ldi r22, 0 \n\t" \ + "mul r12, r10 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r24, r1 \n\t" \ + "mul r13, r9 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r14, r8 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r15, r7 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r16, r6 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r17, r5 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r18, r4 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r19, r3 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r20, r2 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r25 \n\t" \ + "adc r22, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r24 \n\t" \ + "rol r22 \n\t" \ + "mul r21, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "add r23, r28 \n\t" \ + "adc r24, r29 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r29, 0 \n\t" \ + "mul r12, r11 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r28, r1 \n\t" \ + "mul r13, r10 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r14, r9 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r15, r8 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r16, r7 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r17, r6 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r18, r5 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r19, r4 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r20, r3 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r21, r2 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r25 \n\t" \ + "adc r29, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r28 \n\t" \ + "rol r29 \n\t" \ + "add r23, r24 \n\t" \ + "adc r28, r22 \n\t" \ + "adc r29, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ld r12, x+ \n\t" \ + "ldi r22, 0 \n\t" \ + "mul r13, r11 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r24, r1 \n\t" \ + "mul r14, r10 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r15, r9 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r16, r8 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r17, r7 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r18, r6 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r19, r5 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r20, r4 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r21, r3 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r25 \n\t" \ + "adc r22, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r24 \n\t" \ + "rol r22 \n\t" \ + "mul r2, r2 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "add r23, r28 \n\t" \ + "adc r24, r29 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r29, 0 \n\t" \ + "mul r13, r12 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r28, r1 \n\t" \ + "mul r14, r11 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r15, r10 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r16, r9 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r17, r8 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r18, r7 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r19, r6 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r20, r5 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r21, r4 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r2, r3 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r25 \n\t" \ + "adc r29, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r28 \n\t" \ + "rol r29 \n\t" \ + "add r23, r24 \n\t" \ + "adc r28, r22 \n\t" \ + "adc r29, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ld r13, x+ \n\t" \ + "ldi r22, 0 \n\t" \ + "mul r14, r12 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r24, r1 \n\t" \ + "mul r15, r11 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r16, r10 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r17, r9 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r18, r8 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r19, r7 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r20, r6 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r21, r5 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r2, r4 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r25 \n\t" \ + "adc r22, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r24 \n\t" \ + "rol r22 \n\t" \ + "mul r3, r3 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "add r23, r28 \n\t" \ + "adc r24, r29 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r29, 0 \n\t" \ + "mul r14, r13 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r28, r1 \n\t" \ + "mul r15, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r16, r11 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r17, r10 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r18, r9 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r19, r8 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r20, r7 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r21, r6 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r2, r5 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r3, r4 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r25 \n\t" \ + "adc r29, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r28 \n\t" \ + "rol r29 \n\t" \ + "add r23, r24 \n\t" \ + "adc r28, r22 \n\t" \ + "adc r29, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r22, 0 \n\t" \ + "mul r15, r13 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r24, r1 \n\t" \ + "mul r16, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r17, r11 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r18, r10 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r19, r9 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r20, r8 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r21, r7 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r2, r6 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r3, r5 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r24 \n\t" \ + "rol r22 \n\t" \ + "mul r4, r4 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "add r23, r28 \n\t" \ + "adc r24, r29 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r29, 0 \n\t" \ + "mul r16, r13 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r28, r1 \n\t" \ + "mul r17, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r18, r11 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r19, r10 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r20, r9 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r21, r8 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r2, r7 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r3, r6 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r4, r5 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r28 \n\t" \ + "rol r29 \n\t" \ + "add r23, r24 \n\t" \ + "adc r28, r22 \n\t" \ + "adc r29, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r22, 0 \n\t" \ + "mul r17, r13 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r24, r1 \n\t" \ + "mul r18, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r19, r11 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r20, r10 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r21, r9 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r2, r8 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r3, r7 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r4, r6 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r24 \n\t" \ + "rol r22 \n\t" \ + "mul r5, r5 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "add r23, r28 \n\t" \ + "adc r24, r29 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r29, 0 \n\t" \ + "mul r18, r13 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r28, r1 \n\t" \ + "mul r19, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r20, r11 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r21, r10 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r2, r9 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r3, r8 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r4, r7 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r5, r6 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r28 \n\t" \ + "rol r29 \n\t" \ + "add r23, r24 \n\t" \ + "adc r28, r22 \n\t" \ + "adc r29, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r22, 0 \n\t" \ + "mul r19, r13 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r24, r1 \n\t" \ + "mul r20, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r21, r11 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r2, r10 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r3, r9 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r4, r8 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r5, r7 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r24 \n\t" \ + "rol r22 \n\t" \ + "mul r6, r6 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "add r23, r28 \n\t" \ + "adc r24, r29 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r29, 0 \n\t" \ + "mul r20, r13 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r28, r1 \n\t" \ + "mul r21, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r2, r11 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r3, r10 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r4, r9 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r5, r8 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r6, r7 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r28 \n\t" \ + "rol r29 \n\t" \ + "add r23, r24 \n\t" \ + "adc r28, r22 \n\t" \ + "adc r29, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r22, 0 \n\t" \ + "mul r21, r13 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r24, r1 \n\t" \ + "mul r2, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r3, r11 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r4, r10 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r5, r9 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r6, r8 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r24 \n\t" \ + "rol r22 \n\t" \ + "mul r7, r7 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "add r23, r28 \n\t" \ + "adc r24, r29 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r29, 0 \n\t" \ + "mul r2, r13 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r28, r1 \n\t" \ + "mul r3, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r4, r11 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r5, r10 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r6, r9 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r7, r8 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r28 \n\t" \ + "rol r29 \n\t" \ + "add r23, r24 \n\t" \ + "adc r28, r22 \n\t" \ + "adc r29, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r22, 0 \n\t" \ + "mul r3, r13 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r24, r1 \n\t" \ + "mul r4, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r5, r11 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r6, r10 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r7, r9 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r24 \n\t" \ + "rol r22 \n\t" \ + "mul r8, r8 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "add r23, r28 \n\t" \ + "adc r24, r29 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r29, 0 \n\t" \ + "mul r4, r13 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r28, r1 \n\t" \ + "mul r5, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r6, r11 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r7, r10 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r8, r9 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r28 \n\t" \ + "rol r29 \n\t" \ + "add r23, r24 \n\t" \ + "adc r28, r22 \n\t" \ + "adc r29, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r22, 0 \n\t" \ + "mul r5, r13 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r24, r1 \n\t" \ + "mul r6, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r7, r11 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r8, r10 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r24 \n\t" \ + "rol r22 \n\t" \ + "mul r9, r9 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "add r23, r28 \n\t" \ + "adc r24, r29 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r29, 0 \n\t" \ + "mul r6, r13 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r28, r1 \n\t" \ + "mul r7, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r8, r11 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r9, r10 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r28 \n\t" \ + "rol r29 \n\t" \ + "add r23, r24 \n\t" \ + "adc r28, r22 \n\t" \ + "adc r29, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r22, 0 \n\t" \ + "mul r7, r13 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r24, r1 \n\t" \ + "mul r8, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r9, r11 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r24 \n\t" \ + "rol r22 \n\t" \ + "mul r10, r10 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "add r23, r28 \n\t" \ + "adc r24, r29 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r29, 0 \n\t" \ + "mul r8, r13 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r28, r1 \n\t" \ + "mul r9, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r10, r11 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r28 \n\t" \ + "rol r29 \n\t" \ + "add r23, r24 \n\t" \ + "adc r28, r22 \n\t" \ + "adc r29, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r22, 0 \n\t" \ + "mul r9, r13 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r24, r1 \n\t" \ + "mul r10, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r24 \n\t" \ + "rol r22 \n\t" \ + "mul r11, r11 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "add r23, r28 \n\t" \ + "adc r24, r29 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r29, 0 \n\t" \ + "mul r10, r13 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r28, r1 \n\t" \ + "mul r11, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r28 \n\t" \ + "rol r29 \n\t" \ + "add r23, r24 \n\t" \ + "adc r28, r22 \n\t" \ + "adc r29, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r23, 0 \n\t" \ + "mul r11, r13 \n\t" \ + "add r28, r0 \n\t" \ + "adc r29, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "add r28, r0 \n\t" \ + "adc r29, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r12, r12 \n\t" \ + "add r28, r0 \n\t" \ + "adc r29, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "st z+, r28 \n\t" \ + \ + "ldi r28, 0 \n\t" \ + "mul r12, r13 \n\t" \ + "add r29, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r28, r25 \n\t" \ + "add r29, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r28, r25 \n\t" \ + "st z+, r29 \n\t" \ + \ + "mul r13, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "st z+, r23 \n\t" \ + "st z+, r28 \n\t" + +#endif /* _UECC_ASM_AVR_MULT_SQUARE_H_ */ diff --git a/web/server/h2o/libh2o/deps/picotls/deps/micro-ecc/curve-specific.inc b/web/server/h2o/libh2o/deps/picotls/deps/micro-ecc/curve-specific.inc new file mode 100644 index 00000000..0453b212 --- /dev/null +++ b/web/server/h2o/libh2o/deps/picotls/deps/micro-ecc/curve-specific.inc @@ -0,0 +1,1248 @@ +/* Copyright 2015, Kenneth MacKay. Licensed under the BSD 2-clause license. */ + +#ifndef _UECC_CURVE_SPECIFIC_H_ +#define _UECC_CURVE_SPECIFIC_H_ + +#define num_bytes_secp160r1 20 +#define num_bytes_secp192r1 24 +#define num_bytes_secp224r1 28 +#define num_bytes_secp256r1 32 +#define num_bytes_secp256k1 32 + +#if (uECC_WORD_SIZE == 1) + +#define num_words_secp160r1 20 +#define num_words_secp192r1 24 +#define num_words_secp224r1 28 +#define num_words_secp256r1 32 +#define num_words_secp256k1 32 + +#define BYTES_TO_WORDS_8(a, b, c, d, e, f, g, h) \ + 0x##a, 0x##b, 0x##c, 0x##d, 0x##e, 0x##f, 0x##g, 0x##h +#define BYTES_TO_WORDS_4(a, b, c, d) 0x##a, 0x##b, 0x##c, 0x##d + +#elif (uECC_WORD_SIZE == 4) + +#define num_words_secp160r1 5 +#define num_words_secp192r1 6 +#define num_words_secp224r1 7 +#define num_words_secp256r1 8 +#define num_words_secp256k1 8 + +#define BYTES_TO_WORDS_8(a, b, c, d, e, f, g, h) 0x##d##c##b##a, 0x##h##g##f##e +#define BYTES_TO_WORDS_4(a, b, c, d) 0x##d##c##b##a + +#elif (uECC_WORD_SIZE == 8) + +#define num_words_secp160r1 3 +#define num_words_secp192r1 3 +#define num_words_secp224r1 4 +#define num_words_secp256r1 4 +#define num_words_secp256k1 4 + +#define BYTES_TO_WORDS_8(a, b, c, d, e, f, g, h) 0x##h##g##f##e##d##c##b##a##ull +#define BYTES_TO_WORDS_4(a, b, c, d) 0x##d##c##b##a##ull + +#endif /* uECC_WORD_SIZE */ + +#if uECC_SUPPORTS_secp160r1 || uECC_SUPPORTS_secp192r1 || \ + uECC_SUPPORTS_secp224r1 || uECC_SUPPORTS_secp256r1 +static void double_jacobian_default(uECC_word_t * X1, + uECC_word_t * Y1, + uECC_word_t * Z1, + uECC_Curve curve) { + /* t1 = X, t2 = Y, t3 = Z */ + uECC_word_t t4[uECC_MAX_WORDS]; + uECC_word_t t5[uECC_MAX_WORDS]; + wordcount_t num_words = curve->num_words; + + if (uECC_vli_isZero(Z1, num_words)) { + return; + } + + uECC_vli_modSquare_fast(t4, Y1, curve); /* t4 = y1^2 */ + uECC_vli_modMult_fast(t5, X1, t4, curve); /* t5 = x1*y1^2 = A */ + uECC_vli_modSquare_fast(t4, t4, curve); /* t4 = y1^4 */ + uECC_vli_modMult_fast(Y1, Y1, Z1, curve); /* t2 = y1*z1 = z3 */ + uECC_vli_modSquare_fast(Z1, Z1, curve); /* t3 = z1^2 */ + + uECC_vli_modAdd(X1, X1, Z1, curve->p, num_words); /* t1 = x1 + z1^2 */ + uECC_vli_modAdd(Z1, Z1, Z1, curve->p, num_words); /* t3 = 2*z1^2 */ + uECC_vli_modSub(Z1, X1, Z1, curve->p, num_words); /* t3 = x1 - z1^2 */ + uECC_vli_modMult_fast(X1, X1, Z1, curve); /* t1 = x1^2 - z1^4 */ + + uECC_vli_modAdd(Z1, X1, X1, curve->p, num_words); /* t3 = 2*(x1^2 - z1^4) */ + uECC_vli_modAdd(X1, X1, Z1, curve->p, num_words); /* t1 = 3*(x1^2 - z1^4) */ + if (uECC_vli_testBit(X1, 0)) { + uECC_word_t l_carry = uECC_vli_add(X1, X1, curve->p, num_words); + uECC_vli_rshift1(X1, num_words); + X1[num_words - 1] |= l_carry << (uECC_WORD_BITS - 1); + } else { + uECC_vli_rshift1(X1, num_words); + } + /* t1 = 3/2*(x1^2 - z1^4) = B */ + + uECC_vli_modSquare_fast(Z1, X1, curve); /* t3 = B^2 */ + uECC_vli_modSub(Z1, Z1, t5, curve->p, num_words); /* t3 = B^2 - A */ + uECC_vli_modSub(Z1, Z1, t5, curve->p, num_words); /* t3 = B^2 - 2A = x3 */ + uECC_vli_modSub(t5, t5, Z1, curve->p, num_words); /* t5 = A - x3 */ + uECC_vli_modMult_fast(X1, X1, t5, curve); /* t1 = B * (A - x3) */ + uECC_vli_modSub(t4, X1, t4, curve->p, num_words); /* t4 = B * (A - x3) - y1^4 = y3 */ + + uECC_vli_set(X1, Z1, num_words); + uECC_vli_set(Z1, Y1, num_words); + uECC_vli_set(Y1, t4, num_words); +} + +/* Computes result = x^3 + ax + b. result must not overlap x. */ +static void x_side_default(uECC_word_t *result, const uECC_word_t *x, uECC_Curve curve) { + uECC_word_t _3[uECC_MAX_WORDS] = {3}; /* -a = 3 */ + wordcount_t num_words = curve->num_words; + + uECC_vli_modSquare_fast(result, x, curve); /* r = x^2 */ + uECC_vli_modSub(result, result, _3, curve->p, num_words); /* r = x^2 - 3 */ + uECC_vli_modMult_fast(result, result, x, curve); /* r = x^3 - 3x */ + uECC_vli_modAdd(result, result, curve->b, curve->p, num_words); /* r = x^3 - 3x + b */ +} +#endif /* uECC_SUPPORTS_secp... */ + +#if uECC_SUPPORT_COMPRESSED_POINT +#if uECC_SUPPORTS_secp160r1 || uECC_SUPPORTS_secp192r1 || \ + uECC_SUPPORTS_secp256r1 || uECC_SUPPORTS_secp256k1 +/* Compute a = sqrt(a) (mod curve_p). */ +static void mod_sqrt_default(uECC_word_t *a, uECC_Curve curve) { + bitcount_t i; + uECC_word_t p1[uECC_MAX_WORDS] = {1}; + uECC_word_t l_result[uECC_MAX_WORDS] = {1}; + wordcount_t num_words = curve->num_words; + + /* When curve->p == 3 (mod 4), we can compute + sqrt(a) = a^((curve->p + 1) / 4) (mod curve->p). */ + uECC_vli_add(p1, curve->p, p1, num_words); /* p1 = curve_p + 1 */ + for (i = uECC_vli_numBits(p1, num_words) - 1; i > 1; --i) { + uECC_vli_modSquare_fast(l_result, l_result, curve); + if (uECC_vli_testBit(p1, i)) { + uECC_vli_modMult_fast(l_result, l_result, a, curve); + } + } + uECC_vli_set(a, l_result, num_words); +} +#endif /* uECC_SUPPORTS_secp... */ +#endif /* uECC_SUPPORT_COMPRESSED_POINT */ + +#if uECC_SUPPORTS_secp160r1 + +#if (uECC_OPTIMIZATION_LEVEL > 0) +static void vli_mmod_fast_secp160r1(uECC_word_t *result, uECC_word_t *product); +#endif + +static const struct uECC_Curve_t curve_secp160r1 = { + num_words_secp160r1, + num_bytes_secp160r1, + 161, /* num_n_bits */ + { BYTES_TO_WORDS_8(FF, FF, FF, 7F, FF, FF, FF, FF), + BYTES_TO_WORDS_8(FF, FF, FF, FF, FF, FF, FF, FF), + BYTES_TO_WORDS_4(FF, FF, FF, FF) }, + { BYTES_TO_WORDS_8(57, 22, 75, CA, D3, AE, 27, F9), + BYTES_TO_WORDS_8(C8, F4, 01, 00, 00, 00, 00, 00), + BYTES_TO_WORDS_8(00, 00, 00, 00, 01, 00, 00, 00) }, + { BYTES_TO_WORDS_8(82, FC, CB, 13, B9, 8B, C3, 68), + BYTES_TO_WORDS_8(89, 69, 64, 46, 28, 73, F5, 8E), + BYTES_TO_WORDS_4(68, B5, 96, 4A), + + BYTES_TO_WORDS_8(32, FB, C5, 7A, 37, 51, 23, 04), + BYTES_TO_WORDS_8(12, C9, DC, 59, 7D, 94, 68, 31), + BYTES_TO_WORDS_4(55, 28, A6, 23) }, + { BYTES_TO_WORDS_8(45, FA, 65, C5, AD, D4, D4, 81), + BYTES_TO_WORDS_8(9F, F8, AC, 65, 8B, 7A, BD, 54), + BYTES_TO_WORDS_4(FC, BE, 97, 1C) }, + &double_jacobian_default, +#if uECC_SUPPORT_COMPRESSED_POINT + &mod_sqrt_default, +#endif + &x_side_default, +#if (uECC_OPTIMIZATION_LEVEL > 0) + &vli_mmod_fast_secp160r1 +#endif +}; + +uECC_Curve uECC_secp160r1(void) { return &curve_secp160r1; } + +#if (uECC_OPTIMIZATION_LEVEL > 0 && !asm_mmod_fast_secp160r1) +/* Computes result = product % curve_p + see http://www.isys.uni-klu.ac.at/PDF/2001-0126-MT.pdf page 354 + + Note that this only works if log2(omega) < log2(p) / 2 */ +static void omega_mult_secp160r1(uECC_word_t *result, const uECC_word_t *right); +#if uECC_WORD_SIZE == 8 +static void vli_mmod_fast_secp160r1(uECC_word_t *result, uECC_word_t *product) { + uECC_word_t tmp[2 * num_words_secp160r1]; + uECC_word_t copy; + + uECC_vli_clear(tmp, num_words_secp160r1); + uECC_vli_clear(tmp + num_words_secp160r1, num_words_secp160r1); + + omega_mult_secp160r1(tmp, product + num_words_secp160r1 - 1); /* (Rq, q) = q * c */ + + product[num_words_secp160r1 - 1] &= 0xffffffff; + copy = tmp[num_words_secp160r1 - 1]; + tmp[num_words_secp160r1 - 1] &= 0xffffffff; + uECC_vli_add(result, product, tmp, num_words_secp160r1); /* (C, r) = r + q */ + uECC_vli_clear(product, num_words_secp160r1); + tmp[num_words_secp160r1 - 1] = copy; + omega_mult_secp160r1(product, tmp + num_words_secp160r1 - 1); /* Rq*c */ + uECC_vli_add(result, result, product, num_words_secp160r1); /* (C1, r) = r + Rq*c */ + + while (uECC_vli_cmp_unsafe(result, curve_secp160r1.p, num_words_secp160r1) > 0) { + uECC_vli_sub(result, result, curve_secp160r1.p, num_words_secp160r1); + } +} + +static void omega_mult_secp160r1(uint64_t *result, const uint64_t *right) { + uint32_t carry; + unsigned i; + + /* Multiply by (2^31 + 1). */ + carry = 0; + for (i = 0; i < num_words_secp160r1; ++i) { + uint64_t tmp = (right[i] >> 32) | (right[i + 1] << 32); + result[i] = (tmp << 31) + tmp + carry; + carry = (tmp >> 33) + (result[i] < tmp || (carry && result[i] == tmp)); + } + result[i] = carry; +} +#else +static void vli_mmod_fast_secp160r1(uECC_word_t *result, uECC_word_t *product) { + uECC_word_t tmp[2 * num_words_secp160r1]; + uECC_word_t carry; + + uECC_vli_clear(tmp, num_words_secp160r1); + uECC_vli_clear(tmp + num_words_secp160r1, num_words_secp160r1); + + omega_mult_secp160r1(tmp, product + num_words_secp160r1); /* (Rq, q) = q * c */ + + carry = uECC_vli_add(result, product, tmp, num_words_secp160r1); /* (C, r) = r + q */ + uECC_vli_clear(product, num_words_secp160r1); + omega_mult_secp160r1(product, tmp + num_words_secp160r1); /* Rq*c */ + carry += uECC_vli_add(result, result, product, num_words_secp160r1); /* (C1, r) = r + Rq*c */ + + while (carry > 0) { + --carry; + uECC_vli_sub(result, result, curve_secp160r1.p, num_words_secp160r1); + } + if (uECC_vli_cmp_unsafe(result, curve_secp160r1.p, num_words_secp160r1) > 0) { + uECC_vli_sub(result, result, curve_secp160r1.p, num_words_secp160r1); + } +} +#endif + +#if uECC_WORD_SIZE == 1 +static void omega_mult_secp160r1(uint8_t *result, const uint8_t *right) { + uint8_t carry; + uint8_t i; + + /* Multiply by (2^31 + 1). */ + uECC_vli_set(result + 4, right, num_words_secp160r1); /* 2^32 */ + uECC_vli_rshift1(result + 4, num_words_secp160r1); /* 2^31 */ + result[3] = right[0] << 7; /* get last bit from shift */ + + carry = uECC_vli_add(result, result, right, num_words_secp160r1); /* 2^31 + 1 */ + for (i = num_words_secp160r1; carry; ++i) { + uint16_t sum = (uint16_t)result[i] + carry; + result[i] = (uint8_t)sum; + carry = sum >> 8; + } +} +#elif uECC_WORD_SIZE == 4 +static void omega_mult_secp160r1(uint32_t *result, const uint32_t *right) { + uint32_t carry; + unsigned i; + + /* Multiply by (2^31 + 1). */ + uECC_vli_set(result + 1, right, num_words_secp160r1); /* 2^32 */ + uECC_vli_rshift1(result + 1, num_words_secp160r1); /* 2^31 */ + result[0] = right[0] << 31; /* get last bit from shift */ + + carry = uECC_vli_add(result, result, right, num_words_secp160r1); /* 2^31 + 1 */ + for (i = num_words_secp160r1; carry; ++i) { + uint64_t sum = (uint64_t)result[i] + carry; + result[i] = (uint32_t)sum; + carry = sum >> 32; + } +} +#endif /* uECC_WORD_SIZE */ +#endif /* (uECC_OPTIMIZATION_LEVEL > 0 && !asm_mmod_fast_secp160r1) */ + +#endif /* uECC_SUPPORTS_secp160r1 */ + +#if uECC_SUPPORTS_secp192r1 + +#if (uECC_OPTIMIZATION_LEVEL > 0) +static void vli_mmod_fast_secp192r1(uECC_word_t *result, uECC_word_t *product); +#endif + +static const struct uECC_Curve_t curve_secp192r1 = { + num_words_secp192r1, + num_bytes_secp192r1, + 192, /* num_n_bits */ + { BYTES_TO_WORDS_8(FF, FF, FF, FF, FF, FF, FF, FF), + BYTES_TO_WORDS_8(FE, FF, FF, FF, FF, FF, FF, FF), + BYTES_TO_WORDS_8(FF, FF, FF, FF, FF, FF, FF, FF) }, + { BYTES_TO_WORDS_8(31, 28, D2, B4, B1, C9, 6B, 14), + BYTES_TO_WORDS_8(36, F8, DE, 99, FF, FF, FF, FF), + BYTES_TO_WORDS_8(FF, FF, FF, FF, FF, FF, FF, FF) }, + { BYTES_TO_WORDS_8(12, 10, FF, 82, FD, 0A, FF, F4), + BYTES_TO_WORDS_8(00, 88, A1, 43, EB, 20, BF, 7C), + BYTES_TO_WORDS_8(F6, 90, 30, B0, 0E, A8, 8D, 18), + + BYTES_TO_WORDS_8(11, 48, 79, 1E, A1, 77, F9, 73), + BYTES_TO_WORDS_8(D5, CD, 24, 6B, ED, 11, 10, 63), + BYTES_TO_WORDS_8(78, DA, C8, FF, 95, 2B, 19, 07) }, + { BYTES_TO_WORDS_8(B1, B9, 46, C1, EC, DE, B8, FE), + BYTES_TO_WORDS_8(49, 30, 24, 72, AB, E9, A7, 0F), + BYTES_TO_WORDS_8(E7, 80, 9C, E5, 19, 05, 21, 64) }, + &double_jacobian_default, +#if uECC_SUPPORT_COMPRESSED_POINT + &mod_sqrt_default, +#endif + &x_side_default, +#if (uECC_OPTIMIZATION_LEVEL > 0) + &vli_mmod_fast_secp192r1 +#endif +}; + +uECC_Curve uECC_secp192r1(void) { return &curve_secp192r1; } + +#if (uECC_OPTIMIZATION_LEVEL > 0) +/* Computes result = product % curve_p. + See algorithm 5 and 6 from http://www.isys.uni-klu.ac.at/PDF/2001-0126-MT.pdf */ +#if uECC_WORD_SIZE == 1 +static void vli_mmod_fast_secp192r1(uint8_t *result, uint8_t *product) { + uint8_t tmp[num_words_secp192r1]; + uint8_t carry; + + uECC_vli_set(result, product, num_words_secp192r1); + + uECC_vli_set(tmp, &product[24], num_words_secp192r1); + carry = uECC_vli_add(result, result, tmp, num_words_secp192r1); + + tmp[0] = tmp[1] = tmp[2] = tmp[3] = tmp[4] = tmp[5] = tmp[6] = tmp[7] = 0; + tmp[8] = product[24]; tmp[9] = product[25]; tmp[10] = product[26]; tmp[11] = product[27]; + tmp[12] = product[28]; tmp[13] = product[29]; tmp[14] = product[30]; tmp[15] = product[31]; + tmp[16] = product[32]; tmp[17] = product[33]; tmp[18] = product[34]; tmp[19] = product[35]; + tmp[20] = product[36]; tmp[21] = product[37]; tmp[22] = product[38]; tmp[23] = product[39]; + carry += uECC_vli_add(result, result, tmp, num_words_secp192r1); + + tmp[0] = tmp[8] = product[40]; + tmp[1] = tmp[9] = product[41]; + tmp[2] = tmp[10] = product[42]; + tmp[3] = tmp[11] = product[43]; + tmp[4] = tmp[12] = product[44]; + tmp[5] = tmp[13] = product[45]; + tmp[6] = tmp[14] = product[46]; + tmp[7] = tmp[15] = product[47]; + tmp[16] = tmp[17] = tmp[18] = tmp[19] = tmp[20] = tmp[21] = tmp[22] = tmp[23] = 0; + carry += uECC_vli_add(result, result, tmp, num_words_secp192r1); + + while (carry || uECC_vli_cmp_unsafe(curve_secp192r1.p, result, num_words_secp192r1) != 1) { + carry -= uECC_vli_sub(result, result, curve_secp192r1.p, num_words_secp192r1); + } +} +#elif uECC_WORD_SIZE == 4 +static void vli_mmod_fast_secp192r1(uint32_t *result, uint32_t *product) { + uint32_t tmp[num_words_secp192r1]; + int carry; + + uECC_vli_set(result, product, num_words_secp192r1); + + uECC_vli_set(tmp, &product[6], num_words_secp192r1); + carry = uECC_vli_add(result, result, tmp, num_words_secp192r1); + + tmp[0] = tmp[1] = 0; + tmp[2] = product[6]; + tmp[3] = product[7]; + tmp[4] = product[8]; + tmp[5] = product[9]; + carry += uECC_vli_add(result, result, tmp, num_words_secp192r1); + + tmp[0] = tmp[2] = product[10]; + tmp[1] = tmp[3] = product[11]; + tmp[4] = tmp[5] = 0; + carry += uECC_vli_add(result, result, tmp, num_words_secp192r1); + + while (carry || uECC_vli_cmp_unsafe(curve_secp192r1.p, result, num_words_secp192r1) != 1) { + carry -= uECC_vli_sub(result, result, curve_secp192r1.p, num_words_secp192r1); + } +} +#else +static void vli_mmod_fast_secp192r1(uint64_t *result, uint64_t *product) { + uint64_t tmp[num_words_secp192r1]; + int carry; + + uECC_vli_set(result, product, num_words_secp192r1); + + uECC_vli_set(tmp, &product[3], num_words_secp192r1); + carry = (int)uECC_vli_add(result, result, tmp, num_words_secp192r1); + + tmp[0] = 0; + tmp[1] = product[3]; + tmp[2] = product[4]; + carry += uECC_vli_add(result, result, tmp, num_words_secp192r1); + + tmp[0] = tmp[1] = product[5]; + tmp[2] = 0; + carry += uECC_vli_add(result, result, tmp, num_words_secp192r1); + + while (carry || uECC_vli_cmp_unsafe(curve_secp192r1.p, result, num_words_secp192r1) != 1) { + carry -= uECC_vli_sub(result, result, curve_secp192r1.p, num_words_secp192r1); + } +} +#endif /* uECC_WORD_SIZE */ +#endif /* (uECC_OPTIMIZATION_LEVEL > 0) */ + +#endif /* uECC_SUPPORTS_secp192r1 */ + +#if uECC_SUPPORTS_secp224r1 + +#if uECC_SUPPORT_COMPRESSED_POINT +static void mod_sqrt_secp224r1(uECC_word_t *a, uECC_Curve curve); +#endif +#if (uECC_OPTIMIZATION_LEVEL > 0) +static void vli_mmod_fast_secp224r1(uECC_word_t *result, uECC_word_t *product); +#endif + +static const struct uECC_Curve_t curve_secp224r1 = { + num_words_secp224r1, + num_bytes_secp224r1, + 224, /* num_n_bits */ + { BYTES_TO_WORDS_8(01, 00, 00, 00, 00, 00, 00, 00), + BYTES_TO_WORDS_8(00, 00, 00, 00, FF, FF, FF, FF), + BYTES_TO_WORDS_8(FF, FF, FF, FF, FF, FF, FF, FF), + BYTES_TO_WORDS_4(FF, FF, FF, FF) }, + { BYTES_TO_WORDS_8(3D, 2A, 5C, 5C, 45, 29, DD, 13), + BYTES_TO_WORDS_8(3E, F0, B8, E0, A2, 16, FF, FF), + BYTES_TO_WORDS_8(FF, FF, FF, FF, FF, FF, FF, FF), + BYTES_TO_WORDS_4(FF, FF, FF, FF) }, + { BYTES_TO_WORDS_8(21, 1D, 5C, 11, D6, 80, 32, 34), + BYTES_TO_WORDS_8(22, 11, C2, 56, D3, C1, 03, 4A), + BYTES_TO_WORDS_8(B9, 90, 13, 32, 7F, BF, B4, 6B), + BYTES_TO_WORDS_4(BD, 0C, 0E, B7), + + BYTES_TO_WORDS_8(34, 7E, 00, 85, 99, 81, D5, 44), + BYTES_TO_WORDS_8(64, 47, 07, 5A, A0, 75, 43, CD), + BYTES_TO_WORDS_8(E6, DF, 22, 4C, FB, 23, F7, B5), + BYTES_TO_WORDS_4(88, 63, 37, BD) }, + { BYTES_TO_WORDS_8(B4, FF, 55, 23, 43, 39, 0B, 27), + BYTES_TO_WORDS_8(BA, D8, BF, D7, B7, B0, 44, 50), + BYTES_TO_WORDS_8(56, 32, 41, F5, AB, B3, 04, 0C), + BYTES_TO_WORDS_4(85, 0A, 05, B4) }, + &double_jacobian_default, +#if uECC_SUPPORT_COMPRESSED_POINT + &mod_sqrt_secp224r1, +#endif + &x_side_default, +#if (uECC_OPTIMIZATION_LEVEL > 0) + &vli_mmod_fast_secp224r1 +#endif +}; + +uECC_Curve uECC_secp224r1(void) { return &curve_secp224r1; } + + +#if uECC_SUPPORT_COMPRESSED_POINT +/* Routine 3.2.4 RS; from http://www.nsa.gov/ia/_files/nist-routines.pdf */ +static void mod_sqrt_secp224r1_rs(uECC_word_t *d1, + uECC_word_t *e1, + uECC_word_t *f1, + const uECC_word_t *d0, + const uECC_word_t *e0, + const uECC_word_t *f0) { + uECC_word_t t[num_words_secp224r1]; + + uECC_vli_modSquare_fast(t, d0, &curve_secp224r1); /* t <-- d0 ^ 2 */ + uECC_vli_modMult_fast(e1, d0, e0, &curve_secp224r1); /* e1 <-- d0 * e0 */ + uECC_vli_modAdd(d1, t, f0, curve_secp224r1.p, num_words_secp224r1); /* d1 <-- t + f0 */ + uECC_vli_modAdd(e1, e1, e1, curve_secp224r1.p, num_words_secp224r1); /* e1 <-- e1 + e1 */ + uECC_vli_modMult_fast(f1, t, f0, &curve_secp224r1); /* f1 <-- t * f0 */ + uECC_vli_modAdd(f1, f1, f1, curve_secp224r1.p, num_words_secp224r1); /* f1 <-- f1 + f1 */ + uECC_vli_modAdd(f1, f1, f1, curve_secp224r1.p, num_words_secp224r1); /* f1 <-- f1 + f1 */ +} + +/* Routine 3.2.5 RSS; from http://www.nsa.gov/ia/_files/nist-routines.pdf */ +static void mod_sqrt_secp224r1_rss(uECC_word_t *d1, + uECC_word_t *e1, + uECC_word_t *f1, + const uECC_word_t *d0, + const uECC_word_t *e0, + const uECC_word_t *f0, + const bitcount_t j) { + bitcount_t i; + + uECC_vli_set(d1, d0, num_words_secp224r1); /* d1 <-- d0 */ + uECC_vli_set(e1, e0, num_words_secp224r1); /* e1 <-- e0 */ + uECC_vli_set(f1, f0, num_words_secp224r1); /* f1 <-- f0 */ + for (i = 1; i <= j; i++) { + mod_sqrt_secp224r1_rs(d1, e1, f1, d1, e1, f1); /* RS (d1,e1,f1,d1,e1,f1) */ + } +} + +/* Routine 3.2.6 RM; from http://www.nsa.gov/ia/_files/nist-routines.pdf */ +static void mod_sqrt_secp224r1_rm(uECC_word_t *d2, + uECC_word_t *e2, + uECC_word_t *f2, + const uECC_word_t *c, + const uECC_word_t *d0, + const uECC_word_t *e0, + const uECC_word_t *d1, + const uECC_word_t *e1) { + uECC_word_t t1[num_words_secp224r1]; + uECC_word_t t2[num_words_secp224r1]; + + uECC_vli_modMult_fast(t1, e0, e1, &curve_secp224r1); /* t1 <-- e0 * e1 */ + uECC_vli_modMult_fast(t1, t1, c, &curve_secp224r1); /* t1 <-- t1 * c */ + /* t1 <-- p - t1 */ + uECC_vli_modSub(t1, curve_secp224r1.p, t1, curve_secp224r1.p, num_words_secp224r1); + uECC_vli_modMult_fast(t2, d0, d1, &curve_secp224r1); /* t2 <-- d0 * d1 */ + uECC_vli_modAdd(t2, t2, t1, curve_secp224r1.p, num_words_secp224r1); /* t2 <-- t2 + t1 */ + uECC_vli_modMult_fast(t1, d0, e1, &curve_secp224r1); /* t1 <-- d0 * e1 */ + uECC_vli_modMult_fast(e2, d1, e0, &curve_secp224r1); /* e2 <-- d1 * e0 */ + uECC_vli_modAdd(e2, e2, t1, curve_secp224r1.p, num_words_secp224r1); /* e2 <-- e2 + t1 */ + uECC_vli_modSquare_fast(f2, e2, &curve_secp224r1); /* f2 <-- e2^2 */ + uECC_vli_modMult_fast(f2, f2, c, &curve_secp224r1); /* f2 <-- f2 * c */ + /* f2 <-- p - f2 */ + uECC_vli_modSub(f2, curve_secp224r1.p, f2, curve_secp224r1.p, num_words_secp224r1); + uECC_vli_set(d2, t2, num_words_secp224r1); /* d2 <-- t2 */ +} + +/* Routine 3.2.7 RP; from http://www.nsa.gov/ia/_files/nist-routines.pdf */ +static void mod_sqrt_secp224r1_rp(uECC_word_t *d1, + uECC_word_t *e1, + uECC_word_t *f1, + const uECC_word_t *c, + const uECC_word_t *r) { + wordcount_t i; + wordcount_t pow2i = 1; + uECC_word_t d0[num_words_secp224r1]; + uECC_word_t e0[num_words_secp224r1] = {1}; /* e0 <-- 1 */ + uECC_word_t f0[num_words_secp224r1]; + + uECC_vli_set(d0, r, num_words_secp224r1); /* d0 <-- r */ + /* f0 <-- p - c */ + uECC_vli_modSub(f0, curve_secp224r1.p, c, curve_secp224r1.p, num_words_secp224r1); + for (i = 0; i <= 6; i++) { + mod_sqrt_secp224r1_rss(d1, e1, f1, d0, e0, f0, pow2i); /* RSS (d1,e1,f1,d0,e0,f0,2^i) */ + mod_sqrt_secp224r1_rm(d1, e1, f1, c, d1, e1, d0, e0); /* RM (d1,e1,f1,c,d1,e1,d0,e0) */ + uECC_vli_set(d0, d1, num_words_secp224r1); /* d0 <-- d1 */ + uECC_vli_set(e0, e1, num_words_secp224r1); /* e0 <-- e1 */ + uECC_vli_set(f0, f1, num_words_secp224r1); /* f0 <-- f1 */ + pow2i *= 2; + } +} + +/* Compute a = sqrt(a) (mod curve_p). */ +/* Routine 3.2.8 mp_mod_sqrt_224; from http://www.nsa.gov/ia/_files/nist-routines.pdf */ +static void mod_sqrt_secp224r1(uECC_word_t *a, uECC_Curve curve) { + bitcount_t i; + uECC_word_t e1[num_words_secp224r1]; + uECC_word_t f1[num_words_secp224r1]; + uECC_word_t d0[num_words_secp224r1]; + uECC_word_t e0[num_words_secp224r1]; + uECC_word_t f0[num_words_secp224r1]; + uECC_word_t d1[num_words_secp224r1]; + + /* s = a; using constant instead of random value */ + mod_sqrt_secp224r1_rp(d0, e0, f0, a, a); /* RP (d0, e0, f0, c, s) */ + mod_sqrt_secp224r1_rs(d1, e1, f1, d0, e0, f0); /* RS (d1, e1, f1, d0, e0, f0) */ + for (i = 1; i <= 95; i++) { + uECC_vli_set(d0, d1, num_words_secp224r1); /* d0 <-- d1 */ + uECC_vli_set(e0, e1, num_words_secp224r1); /* e0 <-- e1 */ + uECC_vli_set(f0, f1, num_words_secp224r1); /* f0 <-- f1 */ + mod_sqrt_secp224r1_rs(d1, e1, f1, d0, e0, f0); /* RS (d1, e1, f1, d0, e0, f0) */ + if (uECC_vli_isZero(d1, num_words_secp224r1)) { /* if d1 == 0 */ + break; + } + } + uECC_vli_modInv(f1, e0, curve_secp224r1.p, num_words_secp224r1); /* f1 <-- 1 / e0 */ + uECC_vli_modMult_fast(a, d0, f1, &curve_secp224r1); /* a <-- d0 / e0 */ +} +#endif /* uECC_SUPPORT_COMPRESSED_POINT */ + +#if (uECC_OPTIMIZATION_LEVEL > 0) +/* Computes result = product % curve_p + from http://www.nsa.gov/ia/_files/nist-routines.pdf */ +#if uECC_WORD_SIZE == 1 +static void vli_mmod_fast_secp224r1(uint8_t *result, uint8_t *product) { + uint8_t tmp[num_words_secp224r1]; + int8_t carry; + + /* t */ + uECC_vli_set(result, product, num_words_secp224r1); + + /* s1 */ + tmp[0] = tmp[1] = tmp[2] = tmp[3] = 0; + tmp[4] = tmp[5] = tmp[6] = tmp[7] = 0; + tmp[8] = tmp[9] = tmp[10] = tmp[11] = 0; + tmp[12] = product[28]; tmp[13] = product[29]; tmp[14] = product[30]; tmp[15] = product[31]; + tmp[16] = product[32]; tmp[17] = product[33]; tmp[18] = product[34]; tmp[19] = product[35]; + tmp[20] = product[36]; tmp[21] = product[37]; tmp[22] = product[38]; tmp[23] = product[39]; + tmp[24] = product[40]; tmp[25] = product[41]; tmp[26] = product[42]; tmp[27] = product[43]; + carry = uECC_vli_add(result, result, tmp, num_words_secp224r1); + + /* s2 */ + tmp[12] = product[44]; tmp[13] = product[45]; tmp[14] = product[46]; tmp[15] = product[47]; + tmp[16] = product[48]; tmp[17] = product[49]; tmp[18] = product[50]; tmp[19] = product[51]; + tmp[20] = product[52]; tmp[21] = product[53]; tmp[22] = product[54]; tmp[23] = product[55]; + tmp[24] = tmp[25] = tmp[26] = tmp[27] = 0; + carry += uECC_vli_add(result, result, tmp, num_words_secp224r1); + + /* d1 */ + tmp[0] = product[28]; tmp[1] = product[29]; tmp[2] = product[30]; tmp[3] = product[31]; + tmp[4] = product[32]; tmp[5] = product[33]; tmp[6] = product[34]; tmp[7] = product[35]; + tmp[8] = product[36]; tmp[9] = product[37]; tmp[10] = product[38]; tmp[11] = product[39]; + tmp[12] = product[40]; tmp[13] = product[41]; tmp[14] = product[42]; tmp[15] = product[43]; + tmp[16] = product[44]; tmp[17] = product[45]; tmp[18] = product[46]; tmp[19] = product[47]; + tmp[20] = product[48]; tmp[21] = product[49]; tmp[22] = product[50]; tmp[23] = product[51]; + tmp[24] = product[52]; tmp[25] = product[53]; tmp[26] = product[54]; tmp[27] = product[55]; + carry -= uECC_vli_sub(result, result, tmp, num_words_secp224r1); + + /* d2 */ + tmp[0] = product[44]; tmp[1] = product[45]; tmp[2] = product[46]; tmp[3] = product[47]; + tmp[4] = product[48]; tmp[5] = product[49]; tmp[6] = product[50]; tmp[7] = product[51]; + tmp[8] = product[52]; tmp[9] = product[53]; tmp[10] = product[54]; tmp[11] = product[55]; + tmp[12] = tmp[13] = tmp[14] = tmp[15] = 0; + tmp[16] = tmp[17] = tmp[18] = tmp[19] = 0; + tmp[20] = tmp[21] = tmp[22] = tmp[23] = 0; + tmp[24] = tmp[25] = tmp[26] = tmp[27] = 0; + carry -= uECC_vli_sub(result, result, tmp, num_words_secp224r1); + + if (carry < 0) { + do { + carry += uECC_vli_add(result, result, curve_secp224r1.p, num_words_secp224r1); + } while (carry < 0); + } else { + while (carry || uECC_vli_cmp_unsafe(curve_secp224r1.p, result, num_words_secp224r1) != 1) { + carry -= uECC_vli_sub(result, result, curve_secp224r1.p, num_words_secp224r1); + } + } +} +#elif uECC_WORD_SIZE == 4 +static void vli_mmod_fast_secp224r1(uint32_t *result, uint32_t *product) +{ + uint32_t tmp[num_words_secp224r1]; + int carry; + + /* t */ + uECC_vli_set(result, product, num_words_secp224r1); + + /* s1 */ + tmp[0] = tmp[1] = tmp[2] = 0; + tmp[3] = product[7]; + tmp[4] = product[8]; + tmp[5] = product[9]; + tmp[6] = product[10]; + carry = uECC_vli_add(result, result, tmp, num_words_secp224r1); + + /* s2 */ + tmp[3] = product[11]; + tmp[4] = product[12]; + tmp[5] = product[13]; + tmp[6] = 0; + carry += uECC_vli_add(result, result, tmp, num_words_secp224r1); + + /* d1 */ + tmp[0] = product[7]; + tmp[1] = product[8]; + tmp[2] = product[9]; + tmp[3] = product[10]; + tmp[4] = product[11]; + tmp[5] = product[12]; + tmp[6] = product[13]; + carry -= uECC_vli_sub(result, result, tmp, num_words_secp224r1); + + /* d2 */ + tmp[0] = product[11]; + tmp[1] = product[12]; + tmp[2] = product[13]; + tmp[3] = tmp[4] = tmp[5] = tmp[6] = 0; + carry -= uECC_vli_sub(result, result, tmp, num_words_secp224r1); + + if (carry < 0) { + do { + carry += uECC_vli_add(result, result, curve_secp224r1.p, num_words_secp224r1); + } while (carry < 0); + } else { + while (carry || uECC_vli_cmp_unsafe(curve_secp224r1.p, result, num_words_secp224r1) != 1) { + carry -= uECC_vli_sub(result, result, curve_secp224r1.p, num_words_secp224r1); + } + } +} +#else +static void vli_mmod_fast_secp224r1(uint64_t *result, uint64_t *product) +{ + uint64_t tmp[num_words_secp224r1]; + int carry = 0; + + /* t */ + uECC_vli_set(result, product, num_words_secp224r1); + result[num_words_secp224r1 - 1] &= 0xffffffff; + + /* s1 */ + tmp[0] = 0; + tmp[1] = product[3] & 0xffffffff00000000ull; + tmp[2] = product[4]; + tmp[3] = product[5] & 0xffffffff; + uECC_vli_add(result, result, tmp, num_words_secp224r1); + + /* s2 */ + tmp[1] = product[5] & 0xffffffff00000000ull; + tmp[2] = product[6]; + tmp[3] = 0; + uECC_vli_add(result, result, tmp, num_words_secp224r1); + + /* d1 */ + tmp[0] = (product[3] >> 32) | (product[4] << 32); + tmp[1] = (product[4] >> 32) | (product[5] << 32); + tmp[2] = (product[5] >> 32) | (product[6] << 32); + tmp[3] = product[6] >> 32; + carry -= uECC_vli_sub(result, result, tmp, num_words_secp224r1); + + /* d2 */ + tmp[0] = (product[5] >> 32) | (product[6] << 32); + tmp[1] = product[6] >> 32; + tmp[2] = tmp[3] = 0; + carry -= uECC_vli_sub(result, result, tmp, num_words_secp224r1); + + if (carry < 0) { + do { + carry += uECC_vli_add(result, result, curve_secp224r1.p, num_words_secp224r1); + } while (carry < 0); + } else { + while (uECC_vli_cmp_unsafe(curve_secp224r1.p, result, num_words_secp224r1) != 1) { + uECC_vli_sub(result, result, curve_secp224r1.p, num_words_secp224r1); + } + } +} +#endif /* uECC_WORD_SIZE */ +#endif /* (uECC_OPTIMIZATION_LEVEL > 0) */ + +#endif /* uECC_SUPPORTS_secp224r1 */ + +#if uECC_SUPPORTS_secp256r1 + +#if (uECC_OPTIMIZATION_LEVEL > 0) +static void vli_mmod_fast_secp256r1(uECC_word_t *result, uECC_word_t *product); +#endif + +static const struct uECC_Curve_t curve_secp256r1 = { + num_words_secp256r1, + num_bytes_secp256r1, + 256, /* num_n_bits */ + { BYTES_TO_WORDS_8(FF, FF, FF, FF, FF, FF, FF, FF), + BYTES_TO_WORDS_8(FF, FF, FF, FF, 00, 00, 00, 00), + BYTES_TO_WORDS_8(00, 00, 00, 00, 00, 00, 00, 00), + BYTES_TO_WORDS_8(01, 00, 00, 00, FF, FF, FF, FF) }, + { BYTES_TO_WORDS_8(51, 25, 63, FC, C2, CA, B9, F3), + BYTES_TO_WORDS_8(84, 9E, 17, A7, AD, FA, E6, BC), + BYTES_TO_WORDS_8(FF, FF, FF, FF, FF, FF, FF, FF), + BYTES_TO_WORDS_8(00, 00, 00, 00, FF, FF, FF, FF) }, + { BYTES_TO_WORDS_8(96, C2, 98, D8, 45, 39, A1, F4), + BYTES_TO_WORDS_8(A0, 33, EB, 2D, 81, 7D, 03, 77), + BYTES_TO_WORDS_8(F2, 40, A4, 63, E5, E6, BC, F8), + BYTES_TO_WORDS_8(47, 42, 2C, E1, F2, D1, 17, 6B), + + BYTES_TO_WORDS_8(F5, 51, BF, 37, 68, 40, B6, CB), + BYTES_TO_WORDS_8(CE, 5E, 31, 6B, 57, 33, CE, 2B), + BYTES_TO_WORDS_8(16, 9E, 0F, 7C, 4A, EB, E7, 8E), + BYTES_TO_WORDS_8(9B, 7F, 1A, FE, E2, 42, E3, 4F) }, + { BYTES_TO_WORDS_8(4B, 60, D2, 27, 3E, 3C, CE, 3B), + BYTES_TO_WORDS_8(F6, B0, 53, CC, B0, 06, 1D, 65), + BYTES_TO_WORDS_8(BC, 86, 98, 76, 55, BD, EB, B3), + BYTES_TO_WORDS_8(E7, 93, 3A, AA, D8, 35, C6, 5A) }, + &double_jacobian_default, +#if uECC_SUPPORT_COMPRESSED_POINT + &mod_sqrt_default, +#endif + &x_side_default, +#if (uECC_OPTIMIZATION_LEVEL > 0) + &vli_mmod_fast_secp256r1 +#endif +}; + +uECC_Curve uECC_secp256r1(void) { return &curve_secp256r1; } + + +#if (uECC_OPTIMIZATION_LEVEL > 0 && !asm_mmod_fast_secp256r1) +/* Computes result = product % curve_p + from http://www.nsa.gov/ia/_files/nist-routines.pdf */ +#if uECC_WORD_SIZE == 1 +static void vli_mmod_fast_secp256r1(uint8_t *result, uint8_t *product) { + uint8_t tmp[num_words_secp256r1]; + int8_t carry; + + /* t */ + uECC_vli_set(result, product, num_words_secp256r1); + + /* s1 */ + tmp[0] = tmp[1] = tmp[2] = tmp[3] = 0; + tmp[4] = tmp[5] = tmp[6] = tmp[7] = 0; + tmp[8] = tmp[9] = tmp[10] = tmp[11] = 0; + tmp[12] = product[44]; tmp[13] = product[45]; tmp[14] = product[46]; tmp[15] = product[47]; + tmp[16] = product[48]; tmp[17] = product[49]; tmp[18] = product[50]; tmp[19] = product[51]; + tmp[20] = product[52]; tmp[21] = product[53]; tmp[22] = product[54]; tmp[23] = product[55]; + tmp[24] = product[56]; tmp[25] = product[57]; tmp[26] = product[58]; tmp[27] = product[59]; + tmp[28] = product[60]; tmp[29] = product[61]; tmp[30] = product[62]; tmp[31] = product[63]; + carry = uECC_vli_add(tmp, tmp, tmp, num_words_secp256r1); + carry += uECC_vli_add(result, result, tmp, num_words_secp256r1); + + /* s2 */ + tmp[12] = product[48]; tmp[13] = product[49]; tmp[14] = product[50]; tmp[15] = product[51]; + tmp[16] = product[52]; tmp[17] = product[53]; tmp[18] = product[54]; tmp[19] = product[55]; + tmp[20] = product[56]; tmp[21] = product[57]; tmp[22] = product[58]; tmp[23] = product[59]; + tmp[24] = product[60]; tmp[25] = product[61]; tmp[26] = product[62]; tmp[27] = product[63]; + tmp[28] = tmp[29] = tmp[30] = tmp[31] = 0; + carry += uECC_vli_add(tmp, tmp, tmp, num_words_secp256r1); + carry += uECC_vli_add(result, result, tmp, num_words_secp256r1); + + /* s3 */ + tmp[0] = product[32]; tmp[1] = product[33]; tmp[2] = product[34]; tmp[3] = product[35]; + tmp[4] = product[36]; tmp[5] = product[37]; tmp[6] = product[38]; tmp[7] = product[39]; + tmp[8] = product[40]; tmp[9] = product[41]; tmp[10] = product[42]; tmp[11] = product[43]; + tmp[12] = tmp[13] = tmp[14] = tmp[15] = 0; + tmp[16] = tmp[17] = tmp[18] = tmp[19] = 0; + tmp[20] = tmp[21] = tmp[22] = tmp[23] = 0; + tmp[24] = product[56]; tmp[25] = product[57]; tmp[26] = product[58]; tmp[27] = product[59]; + tmp[28] = product[60]; tmp[29] = product[61]; tmp[30] = product[62]; tmp[31] = product[63]; + carry += uECC_vli_add(result, result, tmp, num_words_secp256r1); + + /* s4 */ + tmp[0] = product[36]; tmp[1] = product[37]; tmp[2] = product[38]; tmp[3] = product[39]; + tmp[4] = product[40]; tmp[5] = product[41]; tmp[6] = product[42]; tmp[7] = product[43]; + tmp[8] = product[44]; tmp[9] = product[45]; tmp[10] = product[46]; tmp[11] = product[47]; + tmp[12] = product[52]; tmp[13] = product[53]; tmp[14] = product[54]; tmp[15] = product[55]; + tmp[16] = product[56]; tmp[17] = product[57]; tmp[18] = product[58]; tmp[19] = product[59]; + tmp[20] = product[60]; tmp[21] = product[61]; tmp[22] = product[62]; tmp[23] = product[63]; + tmp[24] = product[52]; tmp[25] = product[53]; tmp[26] = product[54]; tmp[27] = product[55]; + tmp[28] = product[32]; tmp[29] = product[33]; tmp[30] = product[34]; tmp[31] = product[35]; + carry += uECC_vli_add(result, result, tmp, num_words_secp256r1); + + /* d1 */ + tmp[0] = product[44]; tmp[1] = product[45]; tmp[2] = product[46]; tmp[3] = product[47]; + tmp[4] = product[48]; tmp[5] = product[49]; tmp[6] = product[50]; tmp[7] = product[51]; + tmp[8] = product[52]; tmp[9] = product[53]; tmp[10] = product[54]; tmp[11] = product[55]; + tmp[12] = tmp[13] = tmp[14] = tmp[15] = 0; + tmp[16] = tmp[17] = tmp[18] = tmp[19] = 0; + tmp[20] = tmp[21] = tmp[22] = tmp[23] = 0; + tmp[24] = product[32]; tmp[25] = product[33]; tmp[26] = product[34]; tmp[27] = product[35]; + tmp[28] = product[40]; tmp[29] = product[41]; tmp[30] = product[42]; tmp[31] = product[43]; + carry -= uECC_vli_sub(result, result, tmp, num_words_secp256r1); + + /* d2 */ + tmp[0] = product[48]; tmp[1] = product[49]; tmp[2] = product[50]; tmp[3] = product[51]; + tmp[4] = product[52]; tmp[5] = product[53]; tmp[6] = product[54]; tmp[7] = product[55]; + tmp[8] = product[56]; tmp[9] = product[57]; tmp[10] = product[58]; tmp[11] = product[59]; + tmp[12] = product[60]; tmp[13] = product[61]; tmp[14] = product[62]; tmp[15] = product[63]; + tmp[16] = tmp[17] = tmp[18] = tmp[19] = 0; + tmp[20] = tmp[21] = tmp[22] = tmp[23] = 0; + tmp[24] = product[36]; tmp[25] = product[37]; tmp[26] = product[38]; tmp[27] = product[39]; + tmp[28] = product[44]; tmp[29] = product[45]; tmp[30] = product[46]; tmp[31] = product[47]; + carry -= uECC_vli_sub(result, result, tmp, num_words_secp256r1); + + /* d3 */ + tmp[0] = product[52]; tmp[1] = product[53]; tmp[2] = product[54]; tmp[3] = product[55]; + tmp[4] = product[56]; tmp[5] = product[57]; tmp[6] = product[58]; tmp[7] = product[59]; + tmp[8] = product[60]; tmp[9] = product[61]; tmp[10] = product[62]; tmp[11] = product[63]; + tmp[12] = product[32]; tmp[13] = product[33]; tmp[14] = product[34]; tmp[15] = product[35]; + tmp[16] = product[36]; tmp[17] = product[37]; tmp[18] = product[38]; tmp[19] = product[39]; + tmp[20] = product[40]; tmp[21] = product[41]; tmp[22] = product[42]; tmp[23] = product[43]; + tmp[24] = tmp[25] = tmp[26] = tmp[27] = 0; + tmp[28] = product[48]; tmp[29] = product[49]; tmp[30] = product[50]; tmp[31] = product[51]; + carry -= uECC_vli_sub(result, result, tmp, num_words_secp256r1); + + /* d4 */ + tmp[0] = product[56]; tmp[1] = product[57]; tmp[2] = product[58]; tmp[3] = product[59]; + tmp[4] = product[60]; tmp[5] = product[61]; tmp[6] = product[62]; tmp[7] = product[63]; + tmp[8] = tmp[9] = tmp[10] = tmp[11] = 0; + tmp[12] = product[36]; tmp[13] = product[37]; tmp[14] = product[38]; tmp[15] = product[39]; + tmp[16] = product[40]; tmp[17] = product[41]; tmp[18] = product[42]; tmp[19] = product[43]; + tmp[20] = product[44]; tmp[21] = product[45]; tmp[22] = product[46]; tmp[23] = product[47]; + tmp[24] = tmp[25] = tmp[26] = tmp[27] = 0; + tmp[28] = product[52]; tmp[29] = product[53]; tmp[30] = product[54]; tmp[31] = product[55]; + carry -= uECC_vli_sub(result, result, tmp, num_words_secp256r1); + + if (carry < 0) { + do { + carry += uECC_vli_add(result, result, curve_secp256r1.p, num_words_secp256r1); + } while (carry < 0); + } else { + while (carry || uECC_vli_cmp_unsafe(curve_secp256r1.p, result, num_words_secp256r1) != 1) { + carry -= uECC_vli_sub(result, result, curve_secp256r1.p, num_words_secp256r1); + } + } +} +#elif uECC_WORD_SIZE == 4 +static void vli_mmod_fast_secp256r1(uint32_t *result, uint32_t *product) { + uint32_t tmp[num_words_secp256r1]; + int carry; + + /* t */ + uECC_vli_set(result, product, num_words_secp256r1); + + /* s1 */ + tmp[0] = tmp[1] = tmp[2] = 0; + tmp[3] = product[11]; + tmp[4] = product[12]; + tmp[5] = product[13]; + tmp[6] = product[14]; + tmp[7] = product[15]; + carry = uECC_vli_add(tmp, tmp, tmp, num_words_secp256r1); + carry += uECC_vli_add(result, result, tmp, num_words_secp256r1); + + /* s2 */ + tmp[3] = product[12]; + tmp[4] = product[13]; + tmp[5] = product[14]; + tmp[6] = product[15]; + tmp[7] = 0; + carry += uECC_vli_add(tmp, tmp, tmp, num_words_secp256r1); + carry += uECC_vli_add(result, result, tmp, num_words_secp256r1); + + /* s3 */ + tmp[0] = product[8]; + tmp[1] = product[9]; + tmp[2] = product[10]; + tmp[3] = tmp[4] = tmp[5] = 0; + tmp[6] = product[14]; + tmp[7] = product[15]; + carry += uECC_vli_add(result, result, tmp, num_words_secp256r1); + + /* s4 */ + tmp[0] = product[9]; + tmp[1] = product[10]; + tmp[2] = product[11]; + tmp[3] = product[13]; + tmp[4] = product[14]; + tmp[5] = product[15]; + tmp[6] = product[13]; + tmp[7] = product[8]; + carry += uECC_vli_add(result, result, tmp, num_words_secp256r1); + + /* d1 */ + tmp[0] = product[11]; + tmp[1] = product[12]; + tmp[2] = product[13]; + tmp[3] = tmp[4] = tmp[5] = 0; + tmp[6] = product[8]; + tmp[7] = product[10]; + carry -= uECC_vli_sub(result, result, tmp, num_words_secp256r1); + + /* d2 */ + tmp[0] = product[12]; + tmp[1] = product[13]; + tmp[2] = product[14]; + tmp[3] = product[15]; + tmp[4] = tmp[5] = 0; + tmp[6] = product[9]; + tmp[7] = product[11]; + carry -= uECC_vli_sub(result, result, tmp, num_words_secp256r1); + + /* d3 */ + tmp[0] = product[13]; + tmp[1] = product[14]; + tmp[2] = product[15]; + tmp[3] = product[8]; + tmp[4] = product[9]; + tmp[5] = product[10]; + tmp[6] = 0; + tmp[7] = product[12]; + carry -= uECC_vli_sub(result, result, tmp, num_words_secp256r1); + + /* d4 */ + tmp[0] = product[14]; + tmp[1] = product[15]; + tmp[2] = 0; + tmp[3] = product[9]; + tmp[4] = product[10]; + tmp[5] = product[11]; + tmp[6] = 0; + tmp[7] = product[13]; + carry -= uECC_vli_sub(result, result, tmp, num_words_secp256r1); + + if (carry < 0) { + do { + carry += uECC_vli_add(result, result, curve_secp256r1.p, num_words_secp256r1); + } while (carry < 0); + } else { + while (carry || uECC_vli_cmp_unsafe(curve_secp256r1.p, result, num_words_secp256r1) != 1) { + carry -= uECC_vli_sub(result, result, curve_secp256r1.p, num_words_secp256r1); + } + } +} +#else +static void vli_mmod_fast_secp256r1(uint64_t *result, uint64_t *product) { + uint64_t tmp[num_words_secp256r1]; + int carry; + + /* t */ + uECC_vli_set(result, product, num_words_secp256r1); + + /* s1 */ + tmp[0] = 0; + tmp[1] = product[5] & 0xffffffff00000000ull; + tmp[2] = product[6]; + tmp[3] = product[7]; + carry = (int)uECC_vli_add(tmp, tmp, tmp, num_words_secp256r1); + carry += uECC_vli_add(result, result, tmp, num_words_secp256r1); + + /* s2 */ + tmp[1] = product[6] << 32; + tmp[2] = (product[6] >> 32) | (product[7] << 32); + tmp[3] = product[7] >> 32; + carry += uECC_vli_add(tmp, tmp, tmp, num_words_secp256r1); + carry += uECC_vli_add(result, result, tmp, num_words_secp256r1); + + /* s3 */ + tmp[0] = product[4]; + tmp[1] = product[5] & 0xffffffff; + tmp[2] = 0; + tmp[3] = product[7]; + carry += uECC_vli_add(result, result, tmp, num_words_secp256r1); + + /* s4 */ + tmp[0] = (product[4] >> 32) | (product[5] << 32); + tmp[1] = (product[5] >> 32) | (product[6] & 0xffffffff00000000ull); + tmp[2] = product[7]; + tmp[3] = (product[6] >> 32) | (product[4] << 32); + carry += uECC_vli_add(result, result, tmp, num_words_secp256r1); + + /* d1 */ + tmp[0] = (product[5] >> 32) | (product[6] << 32); + tmp[1] = (product[6] >> 32); + tmp[2] = 0; + tmp[3] = (product[4] & 0xffffffff) | (product[5] << 32); + carry -= uECC_vli_sub(result, result, tmp, num_words_secp256r1); + + /* d2 */ + tmp[0] = product[6]; + tmp[1] = product[7]; + tmp[2] = 0; + tmp[3] = (product[4] >> 32) | (product[5] & 0xffffffff00000000ull); + carry -= uECC_vli_sub(result, result, tmp, num_words_secp256r1); + + /* d3 */ + tmp[0] = (product[6] >> 32) | (product[7] << 32); + tmp[1] = (product[7] >> 32) | (product[4] << 32); + tmp[2] = (product[4] >> 32) | (product[5] << 32); + tmp[3] = (product[6] << 32); + carry -= uECC_vli_sub(result, result, tmp, num_words_secp256r1); + + /* d4 */ + tmp[0] = product[7]; + tmp[1] = product[4] & 0xffffffff00000000ull; + tmp[2] = product[5]; + tmp[3] = product[6] & 0xffffffff00000000ull; + carry -= uECC_vli_sub(result, result, tmp, num_words_secp256r1); + + if (carry < 0) { + do { + carry += uECC_vli_add(result, result, curve_secp256r1.p, num_words_secp256r1); + } while (carry < 0); + } else { + while (carry || uECC_vli_cmp_unsafe(curve_secp256r1.p, result, num_words_secp256r1) != 1) { + carry -= uECC_vli_sub(result, result, curve_secp256r1.p, num_words_secp256r1); + } + } +} +#endif /* uECC_WORD_SIZE */ +#endif /* (uECC_OPTIMIZATION_LEVEL > 0 && !asm_mmod_fast_secp256r1) */ + +#endif /* uECC_SUPPORTS_secp256r1 */ + +#if uECC_SUPPORTS_secp256k1 + +static void double_jacobian_secp256k1(uECC_word_t * X1, + uECC_word_t * Y1, + uECC_word_t * Z1, + uECC_Curve curve); +static void x_side_secp256k1(uECC_word_t *result, const uECC_word_t *x, uECC_Curve curve); +#if (uECC_OPTIMIZATION_LEVEL > 0) +static void vli_mmod_fast_secp256k1(uECC_word_t *result, uECC_word_t *product); +#endif + +static const struct uECC_Curve_t curve_secp256k1 = { + num_words_secp256k1, + num_bytes_secp256k1, + 256, /* num_n_bits */ + { BYTES_TO_WORDS_8(2F, FC, FF, FF, FE, FF, FF, FF), + BYTES_TO_WORDS_8(FF, FF, FF, FF, FF, FF, FF, FF), + BYTES_TO_WORDS_8(FF, FF, FF, FF, FF, FF, FF, FF), + BYTES_TO_WORDS_8(FF, FF, FF, FF, FF, FF, FF, FF) }, + { BYTES_TO_WORDS_8(41, 41, 36, D0, 8C, 5E, D2, BF), + BYTES_TO_WORDS_8(3B, A0, 48, AF, E6, DC, AE, BA), + BYTES_TO_WORDS_8(FE, FF, FF, FF, FF, FF, FF, FF), + BYTES_TO_WORDS_8(FF, FF, FF, FF, FF, FF, FF, FF) }, + { BYTES_TO_WORDS_8(98, 17, F8, 16, 5B, 81, F2, 59), + BYTES_TO_WORDS_8(D9, 28, CE, 2D, DB, FC, 9B, 02), + BYTES_TO_WORDS_8(07, 0B, 87, CE, 95, 62, A0, 55), + BYTES_TO_WORDS_8(AC, BB, DC, F9, 7E, 66, BE, 79), + + BYTES_TO_WORDS_8(B8, D4, 10, FB, 8F, D0, 47, 9C), + BYTES_TO_WORDS_8(19, 54, 85, A6, 48, B4, 17, FD), + BYTES_TO_WORDS_8(A8, 08, 11, 0E, FC, FB, A4, 5D), + BYTES_TO_WORDS_8(65, C4, A3, 26, 77, DA, 3A, 48) }, + { BYTES_TO_WORDS_8(07, 00, 00, 00, 00, 00, 00, 00), + BYTES_TO_WORDS_8(00, 00, 00, 00, 00, 00, 00, 00), + BYTES_TO_WORDS_8(00, 00, 00, 00, 00, 00, 00, 00), + BYTES_TO_WORDS_8(00, 00, 00, 00, 00, 00, 00, 00) }, + &double_jacobian_secp256k1, +#if uECC_SUPPORT_COMPRESSED_POINT + &mod_sqrt_default, +#endif + &x_side_secp256k1, +#if (uECC_OPTIMIZATION_LEVEL > 0) + &vli_mmod_fast_secp256k1 +#endif +}; + +uECC_Curve uECC_secp256k1(void) { return &curve_secp256k1; } + + +/* Double in place */ +static void double_jacobian_secp256k1(uECC_word_t * X1, + uECC_word_t * Y1, + uECC_word_t * Z1, + uECC_Curve curve) { + /* t1 = X, t2 = Y, t3 = Z */ + uECC_word_t t4[num_words_secp256k1]; + uECC_word_t t5[num_words_secp256k1]; + + if (uECC_vli_isZero(Z1, num_words_secp256k1)) { + return; + } + + uECC_vli_modSquare_fast(t5, Y1, curve); /* t5 = y1^2 */ + uECC_vli_modMult_fast(t4, X1, t5, curve); /* t4 = x1*y1^2 = A */ + uECC_vli_modSquare_fast(X1, X1, curve); /* t1 = x1^2 */ + uECC_vli_modSquare_fast(t5, t5, curve); /* t5 = y1^4 */ + uECC_vli_modMult_fast(Z1, Y1, Z1, curve); /* t3 = y1*z1 = z3 */ + + uECC_vli_modAdd(Y1, X1, X1, curve->p, num_words_secp256k1); /* t2 = 2*x1^2 */ + uECC_vli_modAdd(Y1, Y1, X1, curve->p, num_words_secp256k1); /* t2 = 3*x1^2 */ + if (uECC_vli_testBit(Y1, 0)) { + uECC_word_t carry = uECC_vli_add(Y1, Y1, curve->p, num_words_secp256k1); + uECC_vli_rshift1(Y1, num_words_secp256k1); + Y1[num_words_secp256k1 - 1] |= carry << (uECC_WORD_BITS - 1); + } else { + uECC_vli_rshift1(Y1, num_words_secp256k1); + } + /* t2 = 3/2*(x1^2) = B */ + + uECC_vli_modSquare_fast(X1, Y1, curve); /* t1 = B^2 */ + uECC_vli_modSub(X1, X1, t4, curve->p, num_words_secp256k1); /* t1 = B^2 - A */ + uECC_vli_modSub(X1, X1, t4, curve->p, num_words_secp256k1); /* t1 = B^2 - 2A = x3 */ + + uECC_vli_modSub(t4, t4, X1, curve->p, num_words_secp256k1); /* t4 = A - x3 */ + uECC_vli_modMult_fast(Y1, Y1, t4, curve); /* t2 = B * (A - x3) */ + uECC_vli_modSub(Y1, Y1, t5, curve->p, num_words_secp256k1); /* t2 = B * (A - x3) - y1^4 = y3 */ +} + +/* Computes result = x^3 + b. result must not overlap x. */ +static void x_side_secp256k1(uECC_word_t *result, const uECC_word_t *x, uECC_Curve curve) { + uECC_vli_modSquare_fast(result, x, curve); /* r = x^2 */ + uECC_vli_modMult_fast(result, result, x, curve); /* r = x^3 */ + uECC_vli_modAdd(result, result, curve->b, curve->p, num_words_secp256k1); /* r = x^3 + b */ +} + +#if (uECC_OPTIMIZATION_LEVEL > 0 && !asm_mmod_fast_secp256k1) +static void omega_mult_secp256k1(uECC_word_t *result, const uECC_word_t *right); +static void vli_mmod_fast_secp256k1(uECC_word_t *result, uECC_word_t *product) { + uECC_word_t tmp[2 * num_words_secp256k1]; + uECC_word_t carry; + + uECC_vli_clear(tmp, num_words_secp256k1); + uECC_vli_clear(tmp + num_words_secp256k1, num_words_secp256k1); + + omega_mult_secp256k1(tmp, product + num_words_secp256k1); /* (Rq, q) = q * c */ + + carry = uECC_vli_add(result, product, tmp, num_words_secp256k1); /* (C, r) = r + q */ + uECC_vli_clear(product, num_words_secp256k1); + omega_mult_secp256k1(product, tmp + num_words_secp256k1); /* Rq*c */ + carry += uECC_vli_add(result, result, product, num_words_secp256k1); /* (C1, r) = r + Rq*c */ + + while (carry > 0) { + --carry; + uECC_vli_sub(result, result, curve_secp256k1.p, num_words_secp256k1); + } + if (uECC_vli_cmp_unsafe(result, curve_secp256k1.p, num_words_secp256k1) > 0) { + uECC_vli_sub(result, result, curve_secp256k1.p, num_words_secp256k1); + } +} + +#if uECC_WORD_SIZE == 1 +static void omega_mult_secp256k1(uint8_t * result, const uint8_t * right) { + /* Multiply by (2^32 + 2^9 + 2^8 + 2^7 + 2^6 + 2^4 + 1). */ + uECC_word_t r0 = 0; + uECC_word_t r1 = 0; + uECC_word_t r2 = 0; + wordcount_t k; + + /* Multiply by (2^9 + 2^8 + 2^7 + 2^6 + 2^4 + 1). */ + muladd(0xD1, right[0], &r0, &r1, &r2); + result[0] = r0; + r0 = r1; + r1 = r2; + /* r2 is still 0 */ + + for (k = 1; k < num_words_secp256k1; ++k) { + muladd(0x03, right[k - 1], &r0, &r1, &r2); + muladd(0xD1, right[k], &r0, &r1, &r2); + result[k] = r0; + r0 = r1; + r1 = r2; + r2 = 0; + } + muladd(0x03, right[num_words_secp256k1 - 1], &r0, &r1, &r2); + result[num_words_secp256k1] = r0; + result[num_words_secp256k1 + 1] = r1; + /* add the 2^32 multiple */ + result[4 + num_words_secp256k1] = + uECC_vli_add(result + 4, result + 4, right, num_words_secp256k1); +} +#elif uECC_WORD_SIZE == 4 +static void omega_mult_secp256k1(uint32_t * result, const uint32_t * right) { + /* Multiply by (2^9 + 2^8 + 2^7 + 2^6 + 2^4 + 1). */ + uint32_t carry = 0; + wordcount_t k; + + for (k = 0; k < num_words_secp256k1; ++k) { + uint64_t p = (uint64_t)0x3D1 * right[k] + carry; + result[k] = (uint32_t) p; + carry = p >> 32; + } + result[num_words_secp256k1] = carry; + /* add the 2^32 multiple */ + result[1 + num_words_secp256k1] = + uECC_vli_add(result + 1, result + 1, right, num_words_secp256k1); +} +#else +static void omega_mult_secp256k1(uint64_t * result, const uint64_t * right) { + uECC_word_t r0 = 0; + uECC_word_t r1 = 0; + uECC_word_t r2 = 0; + wordcount_t k; + + /* Multiply by (2^32 + 2^9 + 2^8 + 2^7 + 2^6 + 2^4 + 1). */ + for (k = 0; k < num_words_secp256k1; ++k) { + muladd(0x1000003D1ull, right[k], &r0, &r1, &r2); + result[k] = r0; + r0 = r1; + r1 = r2; + r2 = 0; + } + result[num_words_secp256k1] = r0; +} +#endif /* uECC_WORD_SIZE */ +#endif /* (uECC_OPTIMIZATION_LEVEL > 0 && && !asm_mmod_fast_secp256k1) */ + +#endif /* uECC_SUPPORTS_secp256k1 */ + +#endif /* _UECC_CURVE_SPECIFIC_H_ */ diff --git a/web/server/h2o/libh2o/deps/picotls/deps/micro-ecc/emk_project.py b/web/server/h2o/libh2o/deps/picotls/deps/micro-ecc/emk_project.py new file mode 100644 index 00000000..940fadc2 --- /dev/null +++ b/web/server/h2o/libh2o/deps/picotls/deps/micro-ecc/emk_project.py @@ -0,0 +1,127 @@ +import os + +c, link, asm, utils = emk.module("c", "link", "asm", "utils") + +default_compile_flags = ["-fvisibility=hidden", "-Wall", "-Wextra", "-Wshadow", "-Werror", "-Wno-missing-field-initializers", "-Wno-unused-parameter", \ + "-Wno-comment", "-Wno-unused", "-Wno-unknown-pragmas"] +default_link_flags = [] +opt_flags = {"dbg":["-g"], "std":["-O2"], "max":["-O3"], "small":["-Os"]} +opt_link_flags = {"dbg":[], "std":[], "max":[], "small":[]} +c_flags = ["-std=c99"] +cxx_flags = ["-std=c++11", "-Wno-reorder", "-fno-rtti", "-fno-exceptions"] +c_link_flags = [] +cxx_link_flags = ["-fno-rtti", "-fno-exceptions"] + +def setup_build_dir(): + build_arch = None + if "arch" in emk.options: + build_arch = emk.options["arch"] + elif not emk.cleaning: + build_arch = "osx" + emk.options["arch"] = build_arch + + opt_level = None + if "opt" in emk.options: + level = emk.options["opt"] + if level in opt_flags: + opt_level = level + else: + emk.log.warning("Unknown optimization level '%s'" % (level)) + elif not emk.cleaning: + opt_level = "dbg" + emk.options["opt"] = opt_level + + dirs = ["__build__"] + if build_arch: + dirs.append(build_arch) + if opt_level: + dirs.append(opt_level) + emk.build_dir = os.path.join(*dirs) + +def setup_osx(): + global c + global link + + flags = [("-arch", "x86_64"), "-fno-common", "-Wnewline-eof"] + c.flags.extend(flags) + c.cxx.flags += ["-stdlib=libc++"] + link.cxx.flags += ["-stdlib=libc++"] + + link_flags = [("-arch", "x86_64")] + link.local_flags.extend(link_flags) + +def setup_avr(): + global c + global link + + c.compiler = c.GccCompiler("/Projects/avr-tools/bin/avr-") + c.flags += ["-mmcu=atmega256rfr2", "-ffunction-sections", "-fdata-sections"] + link.linker = link.GccLinker("/Projects/avr-tools/bin/avr-") + link.flags += ["-mmcu=atmega256rfr2", "-mrelax", "-Wl,--gc-sections"] + link.strip = True + +def setup_arm_thumb(): + global c + global link + global asm + global utils + + asm.assembler = asm.GccAssembler("/cross/arm_cortex/bin/arm-none-eabi-") + c.compiler = c.GccCompiler("/cross/arm_cortex/bin/arm-none-eabi-") + link.linker = link.GccLinker("/cross/arm_cortex/bin/arm-none-eabi-") + + c.flags.extend(["-mcpu=cortex-m0", "-mthumb", "-ffunction-sections", "-fdata-sections", "-fno-builtin-fprintf", "-fno-builtin-printf"]) + c.defines["LPC11XX"] = 1 + + link.local_flags.extend(["-mcpu=cortex-m0", "-mthumb", "-nostartfiles", "-nostdlib", "-Wl,--gc-sections"]) + link.local_flags.extend(["-Tflash.lds", "-L/Projects/lpc11xx/core", "/Projects/lpc11xx/core/" + emk.build_dir + "/board_cstartup.o"]) + link.local_syslibs += ["gcc"] + link.depdirs += ["/Projects/lpc11xx/stdlib"] + + def do_objcopy(produces, requires): + utils.call("/cross/arm_cortex/bin/arm-none-eabi-objcopy", "-O", "binary", requires[0], produces[0]) + + def handle_exe(path): + emk.depend(path, "/Projects/lpc11xx/core/" + emk.build_dir + "/board_cstartup.o") + emk.rule(do_objcopy, path + ".bin", path, cwd_safe=True, ex_safe=True) + emk.autobuild(path + ".bin") + + link.exe_funcs.append(handle_exe) + link.strip = True + + emk.recurse("/Projects/lpc11xx/core") + +def setup_linux_rpi(): + global c + global link + + c.compiler = c.GccCompiler("/Volumes/xtools/arm-none-linux-gnueabi/bin/arm-none-linux-gnueabi-") + link.linker = link.GccLinker("/Volumes/xtools/arm-none-linux-gnueabi/bin/arm-none-linux-gnueabi-") + + c.flags.extend(["-fomit-frame-pointer"]) + +setup_build_dir() + +setup_funcs = {"osx":setup_osx, "avr":setup_avr, "arm_thumb":setup_arm_thumb, "rpi": setup_linux_rpi} + +if not emk.cleaning: + build_arch = emk.options["arch"] + opt_level = emk.options["opt"] + + c.flags.extend(default_compile_flags) + c.flags.extend(opt_flags[opt_level]) + c.c.flags.extend(c_flags) + c.cxx.flags.extend(cxx_flags) + link.local_flags.extend(default_link_flags) + link.local_flags.extend(opt_link_flags[opt_level]) + link.c.local_flags.extend(c_link_flags) + link.cxx.local_flags.extend(cxx_link_flags) + + c.include_dirs.append("$:proj:$") + + if build_arch in setup_funcs: + setup_funcs[build_arch]() + else: + raise emk.BuildError("Unknown target arch '%s'" % (build_arch)) + + c.defines["TARGET_ARCH_" + build_arch.upper()] = 1 diff --git a/web/server/h2o/libh2o/deps/picotls/deps/micro-ecc/emk_rules.py b/web/server/h2o/libh2o/deps/picotls/deps/micro-ecc/emk_rules.py new file mode 100644 index 00000000..b1d76c81 --- /dev/null +++ b/web/server/h2o/libh2o/deps/picotls/deps/micro-ecc/emk_rules.py @@ -0,0 +1,3 @@ +c, link = emk.module("c", "link") + +emk.subdir("test") diff --git a/web/server/h2o/libh2o/deps/picotls/deps/micro-ecc/platform-specific.inc b/web/server/h2o/libh2o/deps/picotls/deps/micro-ecc/platform-specific.inc new file mode 100644 index 00000000..1bb595ad --- /dev/null +++ b/web/server/h2o/libh2o/deps/picotls/deps/micro-ecc/platform-specific.inc @@ -0,0 +1,67 @@ +/* Copyright 2015, Kenneth MacKay. Licensed under the BSD 2-clause license. */ + +#ifndef _UECC_PLATFORM_SPECIFIC_H_ +#define _UECC_PLATFORM_SPECIFIC_H_ + +#include "types.h" + +#if (defined(_WIN32) || defined(_WIN64)) +/* Windows */ + +#define WIN32_LEAN_AND_MEAN +#include +#include + +static int default_RNG(uint8_t *dest, unsigned size) { + HCRYPTPROV prov; + if (!CryptAcquireContext(&prov, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT)) { + return 0; + } + + CryptGenRandom(prov, size, (BYTE *)dest); + CryptReleaseContext(prov, 0); + return 1; +} +#define default_RNG_defined 1 + +#elif defined(unix) || defined(__linux__) || defined(__unix__) || defined(__unix) || \ + (defined(__APPLE__) && defined(__MACH__)) || defined(uECC_POSIX) + +/* Some POSIX-like system with /dev/urandom or /dev/random. */ +#include +#include +#include + +#ifndef O_CLOEXEC + #define O_CLOEXEC 0 +#endif + +static int default_RNG(uint8_t *dest, unsigned size) { + int fd = open("/dev/urandom", O_RDONLY | O_CLOEXEC); + if (fd == -1) { + fd = open("/dev/random", O_RDONLY | O_CLOEXEC); + if (fd == -1) { + return 0; + } + } + + char *ptr = (char *)dest; + size_t left = size; + while (left > 0) { + ssize_t bytes_read = read(fd, ptr, left); + if (bytes_read <= 0) { // read failed + close(fd); + return 0; + } + left -= bytes_read; + ptr += bytes_read; + } + + close(fd); + return 1; +} +#define default_RNG_defined 1 + +#endif /* platform */ + +#endif /* _UECC_PLATFORM_SPECIFIC_H_ */ diff --git a/web/server/h2o/libh2o/deps/picotls/deps/micro-ecc/scripts/mult_arm.py b/web/server/h2o/libh2o/deps/picotls/deps/micro-ecc/scripts/mult_arm.py new file mode 100755 index 00000000..402ace19 --- /dev/null +++ b/web/server/h2o/libh2o/deps/picotls/deps/micro-ecc/scripts/mult_arm.py @@ -0,0 +1,188 @@ +#!/usr/bin/env python + +import sys + +if len(sys.argv) < 2: + print "Provide the integer size in 32-bit words" + sys.exit(1) + +size = int(sys.argv[1]) + +full_rows = size // 3 +init_size = size % 3 + +if init_size == 0: + full_rows = full_rows - 1 + init_size = 3 + +def emit(line, *args): + s = '"' + line + r' \n\t"' + print s % args + +rx = [3, 4, 5] +ry = [6, 7, 8] + +#### set up registers +emit("add r0, %s", (size - init_size) * 4) # move z +emit("add r2, %s", (size - init_size) * 4) # move y + +emit("ldmia r1!, {%s}", ", ".join(["r%s" % (rx[i]) for i in xrange(init_size)])) +emit("ldmia r2!, {%s}", ", ".join(["r%s" % (ry[i]) for i in xrange(init_size)])) + +print "" +if init_size == 1: + emit("umull r9, r10, r3, r6") + emit("stmia r0!, {r9, r10}") +else: + #### first two multiplications of initial block + emit("umull r11, r12, r3, r6") + emit("stmia r0!, {r11}") + print "" + emit("mov r10, #0") + emit("umull r11, r9, r3, r7") + emit("adds r12, r12, r11") + emit("adc r9, r9, #0") + emit("umull r11, r14, r4, r6") + emit("adds r12, r12, r11") + emit("adcs r9, r9, r14") + emit("adc r10, r10, #0") + emit("stmia r0!, {r12}") + print "" + + #### rest of initial block, with moving accumulator registers + acc = [9, 10, 11, 12, 14] + if init_size == 3: + emit("mov r%s, #0", acc[2]) + for i in xrange(0, 3): + emit("umull r%s, r%s, r%s, r%s", acc[3], acc[4], rx[i], ry[2 - i]) + emit("adds r%s, r%s, r%s", acc[0], acc[0], acc[3]) + emit("adcs r%s, r%s, r%s", acc[1], acc[1], acc[4]) + emit("adc r%s, r%s, #0", acc[2], acc[2]) + emit("stmia r0!, {r%s}", acc[0]) + print "" + acc = acc[1:] + acc[:1] + + emit("mov r%s, #0", acc[2]) + for i in xrange(0, 2): + emit("umull r%s, r%s, r%s, r%s", acc[3], acc[4], rx[i + 1], ry[2 - i]) + emit("adds r%s, r%s, r%s", acc[0], acc[0], acc[3]) + emit("adcs r%s, r%s, r%s", acc[1], acc[1], acc[4]) + emit("adc r%s, r%s, #0", acc[2], acc[2]) + emit("stmia r0!, {r%s}", acc[0]) + print "" + acc = acc[1:] + acc[:1] + + emit("umull r%s, r%s, r%s, r%s", acc[3], acc[4], rx[init_size-1], ry[init_size-1]) + emit("adds r%s, r%s, r%s", acc[0], acc[0], acc[3]) + emit("adc r%s, r%s, r%s", acc[1], acc[1], acc[4]) + emit("stmia r0!, {r%s}", acc[0]) + emit("stmia r0!, {r%s}", acc[1]) +print "" + +#### reset y and z pointers +emit("sub r0, %s", (2 * init_size + 3) * 4) +emit("sub r2, %s", (init_size + 3) * 4) + +#### load y registers +emit("ldmia r2!, {%s}", ", ".join(["r%s" % (ry[i]) for i in xrange(3)])) + +#### load additional x registers +if init_size != 3: + emit("ldmia r1!, {%s}", ", ".join(["r%s" % (rx[i]) for i in xrange(init_size, 3)])) +print "" + +prev_size = init_size +for row in xrange(full_rows): + emit("umull r11, r12, r3, r6") + emit("stmia r0!, {r11}") + print "" + emit("mov r10, #0") + emit("umull r11, r9, r3, r7") + emit("adds r12, r12, r11") + emit("adc r9, r9, #0") + emit("umull r11, r14, r4, r6") + emit("adds r12, r12, r11") + emit("adcs r9, r9, r14") + emit("adc r10, r10, #0") + emit("stmia r0!, {r12}") + print "" + + acc = [9, 10, 11, 12, 14] + emit("mov r%s, #0", acc[2]) + for i in xrange(0, 3): + emit("umull r%s, r%s, r%s, r%s", acc[3], acc[4], rx[i], ry[2 - i]) + emit("adds r%s, r%s, r%s", acc[0], acc[0], acc[3]) + emit("adcs r%s, r%s, r%s", acc[1], acc[1], acc[4]) + emit("adc r%s, r%s, #0", acc[2], acc[2]) + emit("stmia r0!, {r%s}", acc[0]) + print "" + acc = acc[1:] + acc[:1] + + #### now we need to start shifting x and loading from z + x_regs = [3, 4, 5] + for r in xrange(0, prev_size): + x_regs = x_regs[1:] + x_regs[:1] + emit("ldmia r1!, {r%s}", x_regs[2]) + emit("mov r%s, #0", acc[2]) + for i in xrange(0, 3): + emit("umull r%s, r%s, r%s, r%s", acc[3], acc[4], x_regs[i], ry[2 - i]) + emit("adds r%s, r%s, r%s", acc[0], acc[0], acc[3]) + emit("adcs r%s, r%s, r%s", acc[1], acc[1], acc[4]) + emit("adc r%s, r%s, #0", acc[2], acc[2]) + emit("ldr r%s, [r0]", acc[3]) # load stored value from initial block, and add to accumulator + emit("adds r%s, r%s, r%s", acc[0], acc[0], acc[3]) + emit("adcs r%s, r%s, #0", acc[1], acc[1]) + emit("adc r%s, r%s, #0", acc[2], acc[2]) + emit("stmia r0!, {r%s}", acc[0]) + print "" + acc = acc[1:] + acc[:1] + + # done shifting x, start shifting y + y_regs = [6, 7, 8] + for r in xrange(0, prev_size): + y_regs = y_regs[1:] + y_regs[:1] + emit("ldmia r2!, {r%s}", y_regs[2]) + emit("mov r%s, #0", acc[2]) + for i in xrange(0, 3): + emit("umull r%s, r%s, r%s, r%s", acc[3], acc[4], x_regs[i], y_regs[2 - i]) + emit("adds r%s, r%s, r%s", acc[0], acc[0], acc[3]) + emit("adcs r%s, r%s, r%s", acc[1], acc[1], acc[4]) + emit("adc r%s, r%s, #0", acc[2], acc[2]) + emit("ldr r%s, [r0]", acc[3]) # load stored value from initial block, and add to accumulator + emit("adds r%s, r%s, r%s", acc[0], acc[0], acc[3]) + emit("adcs r%s, r%s, #0", acc[1], acc[1]) + emit("adc r%s, r%s, #0", acc[2], acc[2]) + emit("stmia r0!, {r%s}", acc[0]) + print "" + acc = acc[1:] + acc[:1] + + # done both shifts, do remaining corner + emit("mov r%s, #0", acc[2]) + for i in xrange(0, 2): + emit("umull r%s, r%s, r%s, r%s", acc[3], acc[4], x_regs[i + 1], y_regs[2 - i]) + emit("adds r%s, r%s, r%s", acc[0], acc[0], acc[3]) + emit("adcs r%s, r%s, r%s", acc[1], acc[1], acc[4]) + emit("adc r%s, r%s, #0", acc[2], acc[2]) + emit("stmia r0!, {r%s}", acc[0]) + print "" + acc = acc[1:] + acc[:1] + + emit("umull r%s, r%s, r%s, r%s", acc[3], acc[4], x_regs[2], y_regs[2]) + emit("adds r%s, r%s, r%s", acc[0], acc[0], acc[3]) + emit("adc r%s, r%s, r%s", acc[1], acc[1], acc[4]) + emit("stmia r0!, {r%s}", acc[0]) + emit("stmia r0!, {r%s}", acc[1]) + print "" + + prev_size = prev_size + 3 + if row < full_rows - 1: + #### reset x, y and z pointers + emit("sub r0, %s", (2 * prev_size + 3) * 4) + emit("sub r1, %s", prev_size * 4) + emit("sub r2, %s", (prev_size + 3) * 4) + + #### load x and y registers + emit("ldmia r1!, {%s}", ",".join(["r%s" % (rx[i]) for i in xrange(3)])) + emit("ldmia r2!, {%s}", ",".join(["r%s" % (ry[i]) for i in xrange(3)])) + + print "" diff --git a/web/server/h2o/libh2o/deps/picotls/deps/micro-ecc/scripts/mult_avr.py b/web/server/h2o/libh2o/deps/picotls/deps/micro-ecc/scripts/mult_avr.py new file mode 100755 index 00000000..d40e4c23 --- /dev/null +++ b/web/server/h2o/libh2o/deps/picotls/deps/micro-ecc/scripts/mult_avr.py @@ -0,0 +1,203 @@ +#!/usr/bin/env python + +import sys + +if len(sys.argv) < 2: + print "Provide the integer size in bytes" + sys.exit(1) + +size = int(sys.argv[1]) + +full_rows = size // 10 +init_size = size % 10 + +if init_size == 0: + full_rows = full_rows - 1 + init_size = 10 + +def rx(i): + return i + 2 + +def ry(i): + return i + 12 + +def emit(line, *args): + s = '"' + line + r' \n\t"' + print s % args + +#### set up registers +emit("adiw r30, %s", size - init_size) # move z +emit("adiw r28, %s", size - init_size) # move y + +for i in xrange(init_size): + emit("ld r%s, x+", rx(i)) +for i in xrange(init_size): + emit("ld r%s, y+", ry(i)) + +emit("ldi r25, 0") +print "" +if init_size == 1: + emit("mul r2, r12") + emit("st z+, r0") + emit("st z+, r1") +else: + #### first two multiplications of initial block + emit("ldi r23, 0") + emit("mul r2, r12") + emit("st z+, r0") + emit("mov r22, r1") + print "" + emit("ldi r24, 0") + emit("mul r2, r13") + emit("add r22, r0") + emit("adc r23, r1") + emit("mul r3, r12") + emit("add r22, r0") + emit("adc r23, r1") + emit("adc r24, r25") + emit("st z+, r22") + print "" + + #### rest of initial block, with moving accumulator registers + acc = [23, 24, 22] + for r in xrange(2, init_size): + emit("ldi r%s, 0", acc[2]) + for i in xrange(0, r+1): + emit("mul r%s, r%s", rx(i), ry(r - i)) + emit("add r%s, r0", acc[0]) + emit("adc r%s, r1", acc[1]) + emit("adc r%s, r25", acc[2]) + emit("st z+, r%s", acc[0]) + print "" + acc = acc[1:] + acc[:1] + for r in xrange(1, init_size-1): + emit("ldi r%s, 0", acc[2]) + for i in xrange(0, init_size-r): + emit("mul r%s, r%s", rx(r+i), ry((init_size-1) - i)) + emit("add r%s, r0", acc[0]) + emit("adc r%s, r1", acc[1]) + emit("adc r%s, r25", acc[2]) + emit("st z+, r%s", acc[0]) + print "" + acc = acc[1:] + acc[:1] + emit("mul r%s, r%s", rx(init_size-1), ry(init_size-1)) + emit("add r%s, r0", acc[0]) + emit("adc r%s, r1", acc[1]) + emit("st z+, r%s", acc[0]) + emit("st z+, r%s", acc[1]) +print "" + +#### reset y and z pointers +emit("sbiw r30, %s", 2 * init_size + 10) +emit("sbiw r28, %s", init_size + 10) + +#### load y registers +for i in xrange(10): + emit("ld r%s, y+", ry(i)) + +#### load additional x registers +for i in xrange(init_size, 10): + emit("ld r%s, x+", rx(i)) +print "" + +prev_size = init_size +for row in xrange(full_rows): + #### do x = 0-9, y = 0-9 multiplications + emit("ldi r23, 0") + emit("mul r2, r12") + emit("st z+, r0") + emit("mov r22, r1") + print "" + emit("ldi r24, 0") + emit("mul r2, r13") + emit("add r22, r0") + emit("adc r23, r1") + emit("mul r3, r12") + emit("add r22, r0") + emit("adc r23, r1") + emit("adc r24, r25") + emit("st z+, r22") + print "" + + acc = [23, 24, 22] + for r in xrange(2, 10): + emit("ldi r%s, 0", acc[2]) + for i in xrange(0, r+1): + emit("mul r%s, r%s", rx(i), ry(r - i)) + emit("add r%s, r0", acc[0]) + emit("adc r%s, r1", acc[1]) + emit("adc r%s, r25", acc[2]) + emit("st z+, r%s", acc[0]) + print "" + acc = acc[1:] + acc[:1] + + #### now we need to start shifting x and loading from z + x_regs = [2, 3, 4, 5, 6, 7, 8, 9, 10, 11] + for r in xrange(0, prev_size): + x_regs = x_regs[1:] + x_regs[:1] + emit("ld r%s, x+", x_regs[9]) # load next byte of left + emit("ldi r%s, 0", acc[2]) + for i in xrange(0, 10): + emit("mul r%s, r%s", x_regs[i], ry(9 - i)) + emit("add r%s, r0", acc[0]) + emit("adc r%s, r1", acc[1]) + emit("adc r%s, r25", acc[2]) + emit("ld r0, z") # load stored value from initial block, and add to accumulator (note z does not increment) + emit("add r%s, r0", acc[0]) + emit("adc r%s, r25", acc[1]) + emit("adc r%s, r25", acc[2]) + emit("st z+, r%s", acc[0]) # store next byte (z increments) + print "" + acc = acc[1:] + acc[:1] + + # done shifting x, start shifting y + y_regs = [12, 13, 14, 15, 16, 17, 18, 19, 20, 21] + for r in xrange(0, prev_size): + y_regs = y_regs[1:] + y_regs[:1] + emit("ld r%s, y+", y_regs[9]) # load next byte of right + emit("ldi r%s, 0", acc[2]) + for i in xrange(0, 10): + emit("mul r%s, r%s", x_regs[i], y_regs[9 -i]) + emit("add r%s, r0", acc[0]) + emit("adc r%s, r1", acc[1]) + emit("adc r%s, r25", acc[2]) + emit("ld r0, z") # load stored value from initial block, and add to accumulator (note z does not increment) + emit("add r%s, r0", acc[0]) + emit("adc r%s, r25", acc[1]) + emit("adc r%s, r25", acc[2]) + emit("st z+, r%s", acc[0]) # store next byte (z increments) + print "" + acc = acc[1:] + acc[:1] + + # done both shifts, do remaining corner + for r in xrange(1, 9): + emit("ldi r%s, 0", acc[2]) + for i in xrange(0, 10-r): + emit("mul r%s, r%s", x_regs[r+i], y_regs[9 - i]) + emit("add r%s, r0", acc[0]) + emit("adc r%s, r1", acc[1]) + emit("adc r%s, r25", acc[2]) + emit("st z+, r%s", acc[0]) + print "" + acc = acc[1:] + acc[:1] + emit("mul r%s, r%s", x_regs[9], y_regs[9]) + emit("add r%s, r0", acc[0]) + emit("adc r%s, r1", acc[1]) + emit("st z+, r%s", acc[0]) + emit("st z+, r%s", acc[1]) + print "" + + prev_size = prev_size + 10 + if row < full_rows - 1: + #### reset x, y and z pointers + emit("sbiw r30, %s", 2 * prev_size + 10) + emit("sbiw r28, %s", prev_size + 10) + emit("sbiw r26, %s", prev_size) + + #### load x and y registers + for i in xrange(10): + emit("ld r%s, x+", rx(i)) + emit("ld r%s, y+", ry(i)) + print "" + +emit("eor r1, r1") diff --git a/web/server/h2o/libh2o/deps/picotls/deps/micro-ecc/scripts/mult_avr_extra.py b/web/server/h2o/libh2o/deps/picotls/deps/micro-ecc/scripts/mult_avr_extra.py new file mode 100755 index 00000000..f6e654f6 --- /dev/null +++ b/web/server/h2o/libh2o/deps/picotls/deps/micro-ecc/scripts/mult_avr_extra.py @@ -0,0 +1,143 @@ +#!/usr/bin/env python + +import sys + +if len(sys.argv) < 2: + print "Provide the integer size in bytes" + sys.exit(1) + +size = int(sys.argv[1]) + +def lhi(i): + return i + 2 + +def rhi(i): + return i + 6 + +left_lo = [10, 11, 12, 13] +right_lo = [14, 15, 16, 17] + +def llo(i): + return left_lo[i] + +def rlo(i): + return right_lo[i] + +def emit(line, *args): + s = '"' + line + r' \n\t"' + print s % args + +def update_low(): + global left_lo + global right_lo + left_lo = left_lo[1:] + left_lo[:1] + right_lo = right_lo[1:] + right_lo[:1] + emit("ld r%s, x+", left_lo[3]) + emit("ld r%s, y+", right_lo[3]) + +accum = [19, 20, 21] + +def acc(i): + return accum[i] + +def rotate_acc(): + global accum + accum = accum[1:] + accum[:1] + +# Load high values +for i in xrange(4): + emit("ld r%s, x+", lhi(i)) + emit("ld r%s, y+", rhi(i)) + +emit("sbiw r26, %s", size + 4) +emit("sbiw r28, %s", size + 4) +emit("sbiw r30, %s", size) + +# Load low values +for i in xrange(4): + emit("ld r%s, x+", llo(i)) + emit("ld r%s, y+", rlo(i)) +print "" + +# Compute initial triangles +emit("mul r%s, r%s", lhi(0), rlo(0)) +emit("mov r%s, r0", acc(0)) +emit("mov r%s, r1", acc(1)) +emit("ldi r%s, 0", acc(2)) +emit("ld r0, z") +emit("add r%s, r0", acc(0)) +emit("adc r%s, r25", acc(1)) +emit("mul r%s, r%s", rhi(0), llo(0)) +emit("add r%s, r0", acc(0)) +emit("adc r%s, r1", acc(1)) +emit("adc r%s, r25", acc(2)) +emit("st z+, r%s", acc(0)) +print "" +rotate_acc() + +for i in xrange(1, 4): + emit("ldi r%s, 0", acc(2)) + emit("ld r0, z") + emit("add r%s, r0", acc(0)) + emit("adc r%s, r25", acc(1)) + for j in xrange(i + 1): + emit("mul r%s, r%s", lhi(j), rlo(i-j)) + emit("add r%s, r0", acc(0)) + emit("adc r%s, r1", acc(1)) + emit("adc r%s, r25", acc(2)) + emit("mul r%s, r%s", rhi(j), llo(i-j)) + emit("add r%s, r0", acc(0)) + emit("adc r%s, r1", acc(1)) + emit("adc r%s, r25", acc(2)) + emit("st z+, r%s", acc(0)) + print "" + rotate_acc() + +# Compute rows overlapping old block +for i in xrange(4, size): + emit("ldi r%s, 0", acc(2)) + emit("ld r0, z") + emit("add r%s, r0", acc(0)) + emit("adc r%s, r25", acc(1)) + update_low() + for j in xrange(4): + emit("mul r%s, r%s", lhi(j), rlo(3-j)) + emit("add r%s, r0", acc(0)) + emit("adc r%s, r1", acc(1)) + emit("adc r%s, r25", acc(2)) + emit("mul r%s, r%s", rhi(j), llo(3-j)) + emit("add r%s, r0", acc(0)) + emit("adc r%s, r1", acc(1)) + emit("adc r%s, r25", acc(2)) + emit("st z+, r%s", acc(0)) + print "" + rotate_acc() + +# Compute new triangle +left_combined = [llo(1), llo(2), llo(3), lhi(0), lhi(1), lhi(2), lhi(3)] +right_combined = [rlo(1), rlo(2), rlo(3), rhi(0), rhi(1), rhi(2), rhi(3)] + +def left(i): + return left_combined[i] + +def right(i): + return right_combined[i] + +for i in xrange(6): + emit("ldi r%s, 0", acc(2)) + for j in xrange(7 - i): + emit("mul r%s, r%s", left(i+j), right(6-j)) + emit("add r%s, r0", acc(0)) + emit("adc r%s, r1", acc(1)) + emit("adc r%s, r25", acc(2)) + emit("st z+, r%s", acc(0)) + print "" + rotate_acc() + +emit("mul r%s, r%s", left(6), right(6)) +emit("add r%s, r0", acc(0)) +emit("adc r%s, r1", acc(1)) +emit("st z+, r%s", acc(0)) +emit("st z+, r%s", acc(1)) +emit("adiw r26, 4") +emit("adiw r28, 4") diff --git a/web/server/h2o/libh2o/deps/picotls/deps/micro-ecc/scripts/square_arm.py b/web/server/h2o/libh2o/deps/picotls/deps/micro-ecc/scripts/square_arm.py new file mode 100755 index 00000000..5330c7e6 --- /dev/null +++ b/web/server/h2o/libh2o/deps/picotls/deps/micro-ecc/scripts/square_arm.py @@ -0,0 +1,242 @@ +#!/usr/bin/env python + +import sys + +if len(sys.argv) < 2: + print "Provide the integer size in 32-bit words" + sys.exit(1) + +size = int(sys.argv[1]) + +if size > 8: + print "This script doesn't work with integer size %s due to laziness" % (size) + sys.exit(1) + +init_size = 0 +if size > 6: + init_size = size - 6 + +def emit(line, *args): + s = '"' + line + r' \n\t"' + print s % args + +def mulacc(acc, r1, r2): + if size <= 6: + emit("umull r1, r14, r%s, r%s", r1, r2) + emit("adds r%s, r%s, r1", acc[0], acc[0]) + emit("adcs r%s, r%s, r14", acc[1], acc[1]) + emit("adc r%s, r%s, #0", acc[2], acc[2]) + else: + emit("mov r14, r%s", acc[1]) + emit("umlal r%s, r%s, r%s, r%s", acc[0], acc[1], r1, r2) + emit("cmp r14, r%s", acc[1]) + emit("it hi") + emit("adchi r%s, r%s, #0", acc[2], acc[2]) + +r = [2, 3, 4, 5, 6, 7] + +s = size - init_size + +if init_size == 1: + emit("ldmia r1!, {r2}") + emit("add r1, %s", (size - init_size * 2) * 4) + emit("ldmia r1!, {r5}") + + emit("add r0, %s", (size - init_size) * 4) + emit("umull r8, r9, r2, r5") + emit("stmia r0!, {r8, r9}") + + emit("sub r0, %s", (size + init_size) * 4) + emit("sub r1, %s", (size) * 4) + print "" +elif init_size == 2: + emit("ldmia r1!, {r2, r3}") + emit("add r1, %s", (size - init_size * 2) * 4) + emit("ldmia r1!, {r5, r6}") + + emit("add r0, %s", (size - init_size) * 4) + print "" + + emit("umull r8, r9, r2, r5") + emit("stmia r0!, {r8}") + print "" + + emit("umull r12, r10, r2, r6") + emit("adds r9, r9, r12") + emit("adc r10, r10, #0") + emit("stmia r0!, {r9}") + print "" + + emit("umull r8, r9, r3, r6") + emit("adds r10, r10, r8") + emit("adc r11, r9, #0") + emit("stmia r0!, {r10, r11}") + print "" + + emit("sub r0, %s", (size + init_size) * 4) + emit("sub r1, %s", (size) * 4) + +# load input words +emit("ldmia r1!, {%s}", ", ".join(["r%s" % (r[i]) for i in xrange(s)])) +print "" + +emit("umull r11, r12, r2, r2") +emit("stmia r0!, {r11}") +print "" +emit("mov r9, #0") +emit("umull r10, r11, r2, r3") +emit("adds r12, r12, r10") +emit("adcs r8, r11, #0") +emit("adc r9, r9, #0") +emit("adds r12, r12, r10") +emit("adcs r8, r8, r11") +emit("adc r9, r9, #0") +emit("stmia r0!, {r12}") +print "" +emit("mov r10, #0") +emit("umull r11, r12, r2, r4") +emit("adds r11, r11, r11") +emit("adcs r12, r12, r12") +emit("adc r10, r10, #0") +emit("adds r8, r8, r11") +emit("adcs r9, r9, r12") +emit("adc r10, r10, #0") +emit("umull r11, r12, r3, r3") +emit("adds r8, r8, r11") +emit("adcs r9, r9, r12") +emit("adc r10, r10, #0") +emit("stmia r0!, {r8}") +print "" + +acc = [8, 9, 10] +old_acc = [11, 12] +for i in xrange(3, s): + emit("mov r%s, #0", old_acc[1]) + tmp = [acc[1], acc[2]] + acc = [acc[0], old_acc[0], old_acc[1]] + old_acc = tmp + + # gather non-equal words + emit("umull r%s, r%s, r%s, r%s", acc[0], acc[1], r[0], r[i]) + for j in xrange(1, (i+1)//2): + mulacc(acc, r[j], r[i-j]) + # multiply by 2 + emit("adds r%s, r%s, r%s", acc[0], acc[0], acc[0]) + emit("adcs r%s, r%s, r%s", acc[1], acc[1], acc[1]) + emit("adc r%s, r%s, r%s", acc[2], acc[2], acc[2]) + + # add equal word (if any) + if ((i+1) % 2) != 0: + mulacc(acc, r[i//2], r[i//2]) + + # add old accumulator + emit("adds r%s, r%s, r%s", acc[0], acc[0], old_acc[0]) + emit("adcs r%s, r%s, r%s", acc[1], acc[1], old_acc[1]) + emit("adc r%s, r%s, #0", acc[2], acc[2]) + + # store + emit("stmia r0!, {r%s}", acc[0]) + print "" + +regs = list(r) +for i in xrange(init_size): + regs = regs[1:] + regs[:1] + emit("ldmia r1!, {r%s}", regs[5]) + + for limit in [4, 5]: + emit("mov r%s, #0", old_acc[1]) + tmp = [acc[1], acc[2]] + acc = [acc[0], old_acc[0], old_acc[1]] + old_acc = tmp + + # gather non-equal words + emit("umull r%s, r%s, r%s, r%s", acc[0], acc[1], regs[0], regs[limit]) + for j in xrange(1, (limit+1)//2): + mulacc(acc, regs[j], regs[limit-j]) + + emit("ldr r14, [r0]") # load stored value from initial block, and add to accumulator + emit("adds r%s, r%s, r14", acc[0], acc[0]) + emit("adcs r%s, r%s, #0", acc[1], acc[1]) + emit("adc r%s, r%s, #0", acc[2], acc[2]) + + # multiply by 2 + emit("adds r%s, r%s, r%s", acc[0], acc[0], acc[0]) + emit("adcs r%s, r%s, r%s", acc[1], acc[1], acc[1]) + emit("adc r%s, r%s, r%s", acc[2], acc[2], acc[2]) + + # add equal word + if limit == 4: + mulacc(acc, regs[2], regs[2]) + + # add old accumulator + emit("adds r%s, r%s, r%s", acc[0], acc[0], old_acc[0]) + emit("adcs r%s, r%s, r%s", acc[1], acc[1], old_acc[1]) + emit("adc r%s, r%s, #0", acc[2], acc[2]) + + # store + emit("stmia r0!, {r%s}", acc[0]) + print "" + +for i in xrange(1, s-3): + emit("mov r%s, #0", old_acc[1]) + tmp = [acc[1], acc[2]] + acc = [acc[0], old_acc[0], old_acc[1]] + old_acc = tmp + + # gather non-equal words + emit("umull r%s, r%s, r%s, r%s", acc[0], acc[1], regs[i], regs[s - 1]) + for j in xrange(1, (s-i)//2): + mulacc(acc, regs[i+j], regs[s - 1 - j]) + + # multiply by 2 + emit("adds r%s, r%s, r%s", acc[0], acc[0], acc[0]) + emit("adcs r%s, r%s, r%s", acc[1], acc[1], acc[1]) + emit("adc r%s, r%s, r%s", acc[2], acc[2], acc[2]) + + # add equal word (if any) + if ((s-i) % 2) != 0: + mulacc(acc, regs[i + (s-i)//2], regs[i + (s-i)//2]) + + # add old accumulator + emit("adds r%s, r%s, r%s", acc[0], acc[0], old_acc[0]) + emit("adcs r%s, r%s, r%s", acc[1], acc[1], old_acc[1]) + emit("adc r%s, r%s, #0", acc[2], acc[2]) + + # store + emit("stmia r0!, {r%s}", acc[0]) + print "" + +acc = acc[1:] + acc[:1] +emit("mov r%s, #0", acc[2]) +emit("umull r1, r%s, r%s, r%s", old_acc[1], regs[s - 3], regs[s - 1]) +emit("adds r1, r1, r1") +emit("adcs r%s, r%s, r%s", old_acc[1], old_acc[1], old_acc[1]) +emit("adc r%s, r%s, #0", acc[2], acc[2]) +emit("adds r%s, r%s, r1", acc[0], acc[0]) +emit("adcs r%s, r%s, r%s", acc[1], acc[1], old_acc[1]) +emit("adc r%s, r%s, #0", acc[2], acc[2]) +emit("umull r1, r%s, r%s, r%s", old_acc[1], regs[s - 2], regs[s - 2]) +emit("adds r%s, r%s, r1", acc[0], acc[0]) +emit("adcs r%s, r%s, r%s", acc[1], acc[1], old_acc[1]) +emit("adc r%s, r%s, #0", acc[2], acc[2]) +emit("stmia r0!, {r%s}", acc[0]) +print "" + +acc = acc[1:] + acc[:1] +emit("mov r%s, #0", acc[2]) +emit("umull r1, r%s, r%s, r%s", old_acc[1], regs[s - 2], regs[s - 1]) +emit("adds r1, r1, r1") +emit("adcs r%s, r%s, r%s", old_acc[1], old_acc[1], old_acc[1]) +emit("adc r%s, r%s, #0", acc[2], acc[2]) +emit("adds r%s, r%s, r1", acc[0], acc[0]) +emit("adcs r%s, r%s, r%s", acc[1], acc[1], old_acc[1]) +emit("adc r%s, r%s, #0", acc[2], acc[2]) +emit("stmia r0!, {r%s}", acc[0]) +print "" + +acc = acc[1:] + acc[:1] +emit("umull r1, r%s, r%s, r%s", old_acc[1], regs[s - 1], regs[s - 1]) +emit("adds r%s, r%s, r1", acc[0], acc[0]) +emit("adcs r%s, r%s, r%s", acc[1], acc[1], old_acc[1]) +emit("stmia r0!, {r%s}", acc[0]) +emit("stmia r0!, {r%s}", acc[1]) diff --git a/web/server/h2o/libh2o/deps/picotls/deps/micro-ecc/scripts/square_avr.py b/web/server/h2o/libh2o/deps/picotls/deps/micro-ecc/scripts/square_avr.py new file mode 100755 index 00000000..6571c3b3 --- /dev/null +++ b/web/server/h2o/libh2o/deps/picotls/deps/micro-ecc/scripts/square_avr.py @@ -0,0 +1,327 @@ +#!/usr/bin/env python + +import sys + +if len(sys.argv) < 2: + print "Provide the integer size in bytes" + sys.exit(1) + +size = int(sys.argv[1]) + +if size > 40: + print "This script doesn't work with integer size %s due to laziness" % (size) + sys.exit(1) + +init_size = size - 20 +if size < 20: + init_size = 0 + +def rg(i): + return i + 2 + +def lo(i): + return i + 2 + +def hi(i): + return i + 12 + +def emit(line, *args): + s = '"' + line + r' \n\t"' + print s % args + +#### set up registers +zero = "r25" +emit("ldi %s, 0", zero) # zero register + +if init_size > 0: + emit("movw r28, r26") # y = x + h = (init_size + 1)//2 + + for i in xrange(h): + emit("ld r%s, x+", lo(i)) + emit("adiw r28, %s", size - init_size) # move y to other end + for i in xrange(h): + emit("ld r%s, y+", hi(i)) + + emit("adiw r30, %s", size - init_size) # move z + + if init_size == 1: + emit("mul %s, %s", lo(0), hi(0)) + emit("st z+, r0") + emit("st z+, r1") + else: + #### first one + print "" + emit("ldi r23, 0") + emit("mul %s, %s", lo(0), hi(0)) + emit("st z+, r0") + emit("mov r22, r1") + print "" + + #### rest of initial block, with moving accumulator registers + acc = [22, 23, 24] + for r in xrange(1, h): + emit("ldi r%s, 0", acc[2]) + for i in xrange(0, (r+2)//2): + emit("mul r%s, r%s", lo(i), hi(r - i)) + emit("add r%s, r0", acc[0]) + emit("adc r%s, r1", acc[1]) + emit("adc r%s, %s", acc[2], zero) + emit("st z+, r%s", acc[0]) + print "" + acc = acc[1:] + acc[:1] + + lo_r = range(2, 2 + h) + hi_r = range(12, 12 + h) + + # now we need to start loading more from the high end + for r in xrange(h, init_size): + hi_r = hi_r[1:] + hi_r[:1] + emit("ld r%s, y+", hi_r[h-1]) + + emit("ldi r%s, 0", acc[2]) + for i in xrange(0, (r+2)//2): + emit("mul r%s, r%s", lo(i), hi_r[h - 1 - i]) + emit("add r%s, r0", acc[0]) + emit("adc r%s, r1", acc[1]) + emit("adc r%s, %s", acc[2], zero) + emit("st z+, r%s", acc[0]) + print "" + acc = acc[1:] + acc[:1] + + # loaded all of the high end bytes; now need to start loading the rest of the low end + for r in xrange(1, init_size-h): + lo_r = lo_r[1:] + lo_r[:1] + emit("ld r%s, x+", lo_r[h-1]) + + emit("ldi r%s, 0", acc[2]) + for i in xrange(0, (init_size+1 - r)//2): + emit("mul r%s, r%s", lo_r[i], hi_r[h - 1 - i]) + emit("add r%s, r0", acc[0]) + emit("adc r%s, r1", acc[1]) + emit("adc r%s, %s", acc[2], zero) + emit("st z+, r%s", acc[0]) + print "" + acc = acc[1:] + acc[:1] + + lo_r = lo_r[1:] + lo_r[:1] + emit("ld r%s, x+", lo_r[h-1]) + + # now we have loaded everything, and we just need to finish the last corner + for r in xrange(init_size-h, init_size-1): + emit("ldi r%s, 0", acc[2]) + for i in xrange(0, (init_size+1 - r)//2): + emit("mul r%s, r%s", lo_r[i], hi_r[h - 1 - i]) + emit("add r%s, r0", acc[0]) + emit("adc r%s, r1", acc[1]) + emit("adc r%s, %s", acc[2], zero) + emit("st z+, r%s", acc[0]) + print "" + acc = acc[1:] + acc[:1] + lo_r = lo_r[1:] + lo_r[:1] # make the indexing easy + + emit("mul r%s, r%s", lo_r[0], hi_r[h - 1]) + emit("add r%s, r0", acc[0]) + emit("adc r%s, r1", acc[1]) + emit("st z+, r%s", acc[0]) + emit("st z+, r%s", acc[1]) + print "" + emit("sbiw r26, %s", init_size) # reset x + emit("sbiw r30, %s", size + init_size) # reset z + +# TODO you could do more rows of size 20 here if your integers are larger than 40 bytes + +s = size - init_size + +for i in xrange(s): + emit("ld r%s, x+", rg(i)) + +#### first few columns +# NOTE: this is only valid if size >= 3 +print "" +emit("ldi r23, 0") +emit("mul r%s, r%s", rg(0), rg(0)) +emit("st z+, r0") +emit("mov r22, r1") +print "" +emit("ldi r24, 0") +emit("mul r%s, r%s", rg(0), rg(1)) +emit("add r22, r0") +emit("adc r23, r1") +emit("adc r24, %s", zero) +emit("add r22, r0") +emit("adc r23, r1") +emit("adc r24, %s", zero) +emit("st z+, r22") +print "" +emit("ldi r22, 0") +emit("mul r%s, r%s", rg(0), rg(2)) +emit("add r23, r0") +emit("adc r24, r1") +emit("adc r22, %s", zero) +emit("add r23, r0") +emit("adc r24, r1") +emit("adc r22, %s", zero) +emit("mul r%s, r%s", rg(1), rg(1)) +emit("add r23, r0") +emit("adc r24, r1") +emit("adc r22, %s", zero) +emit("st z+, r23") +print "" + +acc = [23, 24, 22] +old_acc = [28, 29] +for i in xrange(3, s): + emit("ldi r%s, 0", old_acc[1]) + tmp = [acc[1], acc[2]] + acc = [acc[0], old_acc[0], old_acc[1]] + old_acc = tmp + + # gather non-equal words + emit("mul r%s, r%s", rg(0), rg(i)) + emit("mov r%s, r0", acc[0]) + emit("mov r%s, r1", acc[1]) + for j in xrange(1, (i+1)//2): + emit("mul r%s, r%s", rg(j), rg(i-j)) + emit("add r%s, r0", acc[0]) + emit("adc r%s, r1", acc[1]) + emit("adc r%s, %s", acc[2], zero) + # multiply by 2 + emit("lsl r%s", acc[0]) + emit("rol r%s", acc[1]) + emit("rol r%s", acc[2]) + + # add equal word (if any) + if ((i+1) % 2) != 0: + emit("mul r%s, r%s", rg(i//2), rg(i//2)) + emit("add r%s, r0", acc[0]) + emit("adc r%s, r1", acc[1]) + emit("adc r%s, %s", acc[2], zero) + + # add old accumulator + emit("add r%s, r%s", acc[0], old_acc[0]) + emit("adc r%s, r%s", acc[1], old_acc[1]) + emit("adc r%s, %s", acc[2], zero) + + # store + emit("st z+, r%s", acc[0]) + print "" + +regs = range(2, 22) +for i in xrange(init_size): + regs = regs[1:] + regs[:1] + emit("ld r%s, x+", regs[19]) + + for limit in [18, 19]: + emit("ldi r%s, 0", old_acc[1]) + tmp = [acc[1], acc[2]] + acc = [acc[0], old_acc[0], old_acc[1]] + old_acc = tmp + + # gather non-equal words + emit("mul r%s, r%s", regs[0], regs[limit]) + emit("mov r%s, r0", acc[0]) + emit("mov r%s, r1", acc[1]) + for j in xrange(1, (limit+1)//2): + emit("mul r%s, r%s", regs[j], regs[limit-j]) + emit("add r%s, r0", acc[0]) + emit("adc r%s, r1", acc[1]) + emit("adc r%s, %s", acc[2], zero) + + emit("ld r0, z") # load stored value from initial block, and add to accumulator (note z does not increment) + emit("add r%s, r0", acc[0]) + emit("adc r%s, r25", acc[1]) + emit("adc r%s, r25", acc[2]) + + # multiply by 2 + emit("lsl r%s", acc[0]) + emit("rol r%s", acc[1]) + emit("rol r%s", acc[2]) + + # add equal word + if limit == 18: + emit("mul r%s, r%s", regs[9], regs[9]) + emit("add r%s, r0", acc[0]) + emit("adc r%s, r1", acc[1]) + emit("adc r%s, %s", acc[2], zero) + + # add old accumulator + emit("add r%s, r%s", acc[0], old_acc[0]) + emit("adc r%s, r%s", acc[1], old_acc[1]) + emit("adc r%s, %s", acc[2], zero) + + # store + emit("st z+, r%s", acc[0]) + print "" + +for i in xrange(1, s-3): + emit("ldi r%s, 0", old_acc[1]) + tmp = [acc[1], acc[2]] + acc = [acc[0], old_acc[0], old_acc[1]] + old_acc = tmp + + # gather non-equal words + emit("mul r%s, r%s", regs[i], regs[s - 1]) + emit("mov r%s, r0", acc[0]) + emit("mov r%s, r1", acc[1]) + for j in xrange(1, (s-i)//2): + emit("mul r%s, r%s", regs[i+j], regs[s - 1 - j]) + emit("add r%s, r0", acc[0]) + emit("adc r%s, r1", acc[1]) + emit("adc r%s, %s", acc[2], zero) + # multiply by 2 + emit("lsl r%s", acc[0]) + emit("rol r%s", acc[1]) + emit("rol r%s", acc[2]) + + # add equal word (if any) + if ((s-i) % 2) != 0: + emit("mul r%s, r%s", regs[i + (s-i)//2], regs[i + (s-i)//2]) + emit("add r%s, r0", acc[0]) + emit("adc r%s, r1", acc[1]) + emit("adc r%s, %s", acc[2], zero) + + # add old accumulator + emit("add r%s, r%s", acc[0], old_acc[0]) + emit("adc r%s, r%s", acc[1], old_acc[1]) + emit("adc r%s, %s", acc[2], zero) + + # store + emit("st z+, r%s", acc[0]) + print "" + +acc = acc[1:] + acc[:1] +emit("ldi r%s, 0", acc[2]) +emit("mul r%s, r%s", regs[17], regs[19]) +emit("add r%s, r0", acc[0]) +emit("adc r%s, r1", acc[1]) +emit("adc r%s, %s", acc[2], zero) +emit("add r%s, r0", acc[0]) +emit("adc r%s, r1", acc[1]) +emit("adc r%s, %s", acc[2], zero) +emit("mul r%s, r%s", regs[18], regs[18]) +emit("add r%s, r0", acc[0]) +emit("adc r%s, r1", acc[1]) +emit("adc r%s, %s", acc[2], zero) +emit("st z+, r%s", acc[0]) +print "" + +acc = acc[1:] + acc[:1] +emit("ldi r%s, 0", acc[2]) +emit("mul r%s, r%s", regs[18], regs[19]) +emit("add r%s, r0", acc[0]) +emit("adc r%s, r1", acc[1]) +emit("adc r%s, %s", acc[2], zero) +emit("add r%s, r0", acc[0]) +emit("adc r%s, r1", acc[1]) +emit("adc r%s, %s", acc[2], zero) +emit("st z+, r%s", acc[0]) +print "" + +emit("mul r%s, r%s", regs[19], regs[19]) +emit("add r%s, r0", acc[1]) +emit("adc r%s, r1", acc[2]) +emit("st z+, r%s", acc[1]) + +emit("st z+, r%s", acc[2]) +emit("eor r1, r1") diff --git a/web/server/h2o/libh2o/deps/picotls/deps/micro-ecc/test/ecc_test/ecc_test.ino b/web/server/h2o/libh2o/deps/picotls/deps/micro-ecc/test/ecc_test/ecc_test.ino new file mode 100644 index 00000000..c3c8900d --- /dev/null +++ b/web/server/h2o/libh2o/deps/picotls/deps/micro-ecc/test/ecc_test/ecc_test.ino @@ -0,0 +1,85 @@ +#include + +extern "C" { + +static int RNG(uint8_t *dest, unsigned size) { + // Use the least-significant bits from the ADC for an unconnected pin (or connected to a source of + // random noise). This can take a long time to generate random data if the result of analogRead(0) + // doesn't change very frequently. + while (size) { + uint8_t val = 0; + for (unsigned i = 0; i < 8; ++i) { + int init = analogRead(0); + int count = 0; + while (analogRead(0) == init) { + ++count; + } + + if (count == 0) { + val = (val << 1) | (init & 0x01); + } else { + val = (val << 1) | (count & 0x01); + } + } + *dest = val; + ++dest; + --size; + } + // NOTE: it would be a good idea to hash the resulting random data using SHA-256 or similar. + return 1; +} + +} // extern "C" + +void setup() { + Serial.begin(115200); + Serial.print("Testing ecc\n"); + uECC_set_rng(&RNG); +} + +void loop() { + const struct uECC_Curve_t * curve = uECC_secp160r1(); + uint8_t private1[21]; + uint8_t private2[21]; + + uint8_t public1[40]; + uint8_t public2[40]; + + uint8_t secret1[20]; + uint8_t secret2[20]; + + unsigned long a = millis(); + uECC_make_key(public1, private1, curve); + unsigned long b = millis(); + + Serial.print("Made key 1 in "); Serial.println(b-a); + a = millis(); + uECC_make_key(public2, private2, curve); + b = millis(); + Serial.print("Made key 2 in "); Serial.println(b-a); + + a = millis(); + int r = uECC_shared_secret(public2, private1, secret1, curve); + b = millis(); + Serial.print("Shared secret 1 in "); Serial.println(b-a); + if (!r) { + Serial.print("shared_secret() failed (1)\n"); + return; + } + + a = millis(); + r = uECC_shared_secret(public1, private2, secret2, curve); + b = millis(); + Serial.print("Shared secret 2 in "); Serial.println(b-a); + if (!r) { + Serial.print("shared_secret() failed (2)\n"); + return; + } + + if (memcmp(secret1, secret2, 20) != 0) { + Serial.print("Shared secrets are not identical!\n"); + } else { + Serial.print("Shared secrets are identical\n"); + } +} + diff --git a/web/server/h2o/libh2o/deps/picotls/deps/micro-ecc/test/emk_rules.py b/web/server/h2o/libh2o/deps/picotls/deps/micro-ecc/test/emk_rules.py new file mode 100644 index 00000000..956ccf5f --- /dev/null +++ b/web/server/h2o/libh2o/deps/picotls/deps/micro-ecc/test/emk_rules.py @@ -0,0 +1,4 @@ +c, link = emk.module("c", "link") +link.depdirs += [ + "$:proj:$" +] diff --git a/web/server/h2o/libh2o/deps/picotls/deps/micro-ecc/test/test_compress.c b/web/server/h2o/libh2o/deps/picotls/deps/micro-ecc/test/test_compress.c new file mode 100644 index 00000000..aef374cd --- /dev/null +++ b/web/server/h2o/libh2o/deps/picotls/deps/micro-ecc/test/test_compress.c @@ -0,0 +1,79 @@ +/* Copyright 2014, Kenneth MacKay. Licensed under the BSD 2-clause license. */ + +#include "uECC.h" + +#include +#include + +#ifndef uECC_TEST_NUMBER_OF_ITERATIONS +#define uECC_TEST_NUMBER_OF_ITERATIONS 256 +#endif + +void vli_print(char *str, uint8_t *vli, unsigned int size) { + printf("%s ", str); + for(unsigned i=0; i +#include + +void vli_print(char *str, uint8_t *vli, unsigned int size) { + printf("%s ", str); + for(unsigned i=0; i +#include + +void vli_print(uint8_t *vli, unsigned int size) { + for(unsigned i=0; i +#include + +int main() { + int i, c; + uint8_t private[32] = {0}; + uint8_t public[64] = {0}; + uint8_t hash[32] = {0}; + uint8_t sig[64] = {0}; + + const struct uECC_Curve_t * curves[5]; + int num_curves = 0; +#if uECC_SUPPORTS_secp160r1 + curves[num_curves++] = uECC_secp160r1(); +#endif +#if uECC_SUPPORTS_secp192r1 + curves[num_curves++] = uECC_secp192r1(); +#endif +#if uECC_SUPPORTS_secp224r1 + curves[num_curves++] = uECC_secp224r1(); +#endif +#if uECC_SUPPORTS_secp256r1 + curves[num_curves++] = uECC_secp256r1(); +#endif +#if uECC_SUPPORTS_secp256k1 + curves[num_curves++] = uECC_secp256k1(); +#endif + + printf("Testing 256 signatures\n"); + for (c = 0; c < num_curves; ++c) { + for (i = 0; i < 256; ++i) { + printf("."); + fflush(stdout); + + if (!uECC_make_key(public, private, curves[c])) { + printf("uECC_make_key() failed\n"); + return 1; + } + memcpy(hash, public, sizeof(hash)); + + if (!uECC_sign(private, hash, sizeof(hash), sig, curves[c])) { + printf("uECC_sign() failed\n"); + return 1; + } + + if (!uECC_verify(public, hash, sizeof(hash), sig, curves[c])) { + printf("uECC_verify() failed\n"); + return 1; + } + } + printf("\n"); + } + + return 0; +} diff --git a/web/server/h2o/libh2o/deps/picotls/deps/micro-ecc/test/test_ecdsa_deterministic.c.example b/web/server/h2o/libh2o/deps/picotls/deps/micro-ecc/test/test_ecdsa_deterministic.c.example new file mode 100644 index 00000000..df9aa101 --- /dev/null +++ b/web/server/h2o/libh2o/deps/picotls/deps/micro-ecc/test/test_ecdsa_deterministic.c.example @@ -0,0 +1,93 @@ +/* Copyright 2014, Kenneth MacKay. Licensed under the BSD 2-clause license. */ + +#include "uECC.h" + +#include +#include + +#define SHA256_BLOCK_LENGTH 64 +#define SHA256_DIGEST_LENGTH 32 + +typedef struct SHA256_CTX { + uint32_t state[8]; + uint64_t bitcount; + uint8_t buffer[SHA256_BLOCK_LENGTH]; +} SHA256_CTX; + +extern void SHA256_Init(SHA256_CTX *ctx); +extern void SHA256_Update(SHA256_CTX *ctx, const uint8_t *message, size_t message_size); +extern void SHA256_Final(uint8_t digest[SHA256_DIGEST_LENGTH], SHA256_CTX *ctx); + +typedef struct SHA256_HashContext { + uECC_HashContext uECC; + SHA256_CTX ctx; +} SHA256_HashContext; + +static void init_SHA256(const uECC_HashContext *base) { + SHA256_HashContext *context = (SHA256_HashContext *)base; + SHA256_Init(&context->ctx); +} + +static void update_SHA256(const uECC_HashContext *base, + const uint8_t *message, + unsigned message_size) { + SHA256_HashContext *context = (SHA256_HashContext *)base; + SHA256_Update(&context->ctx, message, message_size); +} + +static void finish_SHA256(const uECC_HashContext *base, uint8_t *hash_result) { + SHA256_HashContext *context = (SHA256_HashContext *)base; + SHA256_Final(hash_result, &context->ctx); +} + +int main() { + int i, c; + uint8_t private[32] = {0}; + uint8_t public[64] = {0}; + uint8_t hash[32] = {0}; + uint8_t sig[64] = {0}; + + uint8_t tmp[2 * SHA256_DIGEST_LENGTH + SHA256_BLOCK_LENGTH]; + SHA256_HashContext ctx = {{ + &init_SHA256, + &update_SHA256, + &finish_SHA256, + SHA256_BLOCK_LENGTH, + SHA256_DIGEST_LENGTH, + tmp + }}; + + const struct uECC_Curve_t * curves[5]; + curves[0] = uECC_secp160r1(); + curves[1] = uECC_secp192r1(); + curves[2] = uECC_secp224r1(); + curves[3] = uECC_secp256r1(); + curves[4] = uECC_secp256k1(); + + printf("Testing 256 signatures\n"); + for (c = 0; c < 5; ++c) { + for (i = 0; i < 256; ++i) { + printf("."); + fflush(stdout); + + if (!uECC_make_key(public, private, curves[c])) { + printf("uECC_make_key() failed\n"); + return 1; + } + memcpy(hash, public, sizeof(hash)); + + if (!uECC_sign_deterministic(private, hash, sizeof(hash), &ctx.uECC, sig, curves[c])) { + printf("uECC_sign() failed\n"); + return 1; + } + + if (!uECC_verify(public, hash, sizeof(hash), sig, curves[c])) { + printf("uECC_verify() failed\n"); + return 1; + } + } + printf("\n"); + } + + return 0; +} diff --git a/web/server/h2o/libh2o/deps/picotls/deps/micro-ecc/types.h b/web/server/h2o/libh2o/deps/picotls/deps/micro-ecc/types.h new file mode 100644 index 00000000..9ee81438 --- /dev/null +++ b/web/server/h2o/libh2o/deps/picotls/deps/micro-ecc/types.h @@ -0,0 +1,108 @@ +/* Copyright 2015, Kenneth MacKay. Licensed under the BSD 2-clause license. */ + +#ifndef _UECC_TYPES_H_ +#define _UECC_TYPES_H_ + +#ifndef uECC_PLATFORM + #if __AVR__ + #define uECC_PLATFORM uECC_avr + #elif defined(__thumb2__) || defined(_M_ARMT) /* I think MSVC only supports Thumb-2 targets */ + #define uECC_PLATFORM uECC_arm_thumb2 + #elif defined(__thumb__) + #define uECC_PLATFORM uECC_arm_thumb + #elif defined(__arm__) || defined(_M_ARM) + #define uECC_PLATFORM uECC_arm + #elif defined(__aarch64__) + #define uECC_PLATFORM uECC_arm64 + #elif defined(__i386__) || defined(_M_IX86) || defined(_X86_) || defined(__I86__) + #define uECC_PLATFORM uECC_x86 + #elif defined(__amd64__) || defined(_M_X64) + #define uECC_PLATFORM uECC_x86_64 + #else + #define uECC_PLATFORM uECC_arch_other + #endif +#endif + +#ifndef uECC_ARM_USE_UMAAL + #if (uECC_PLATFORM == uECC_arm) && (__ARM_ARCH >= 6) + #define uECC_ARM_USE_UMAAL 1 + #elif (uECC_PLATFORM == uECC_arm_thumb2) && (__ARM_ARCH >= 6) && !__ARM_ARCH_7M__ + #define uECC_ARM_USE_UMAAL 1 + #else + #define uECC_ARM_USE_UMAAL 0 + #endif +#endif + +#ifndef uECC_WORD_SIZE + #if uECC_PLATFORM == uECC_avr + #define uECC_WORD_SIZE 1 + #elif (uECC_PLATFORM == uECC_x86_64 || uECC_PLATFORM == uECC_arm64) + #define uECC_WORD_SIZE 8 + #else + #define uECC_WORD_SIZE 4 + #endif +#endif + +#if (uECC_WORD_SIZE != 1) && (uECC_WORD_SIZE != 4) && (uECC_WORD_SIZE != 8) + #error "Unsupported value for uECC_WORD_SIZE" +#endif + +#if ((uECC_PLATFORM == uECC_avr) && (uECC_WORD_SIZE != 1)) + #pragma message ("uECC_WORD_SIZE must be 1 for AVR") + #undef uECC_WORD_SIZE + #define uECC_WORD_SIZE 1 +#endif + +#if ((uECC_PLATFORM == uECC_arm || uECC_PLATFORM == uECC_arm_thumb || \ + uECC_PLATFORM == uECC_arm_thumb2) && \ + (uECC_WORD_SIZE != 4)) + #pragma message ("uECC_WORD_SIZE must be 4 for ARM") + #undef uECC_WORD_SIZE + #define uECC_WORD_SIZE 4 +#endif + +#if defined(__SIZEOF_INT128__) || ((__clang_major__ * 100 + __clang_minor__) >= 302) + #define SUPPORTS_INT128 1 +#else + #define SUPPORTS_INT128 0 +#endif + +typedef int8_t wordcount_t; +typedef int16_t bitcount_t; +typedef int8_t cmpresult_t; + +#if (uECC_WORD_SIZE == 1) + +typedef uint8_t uECC_word_t; +typedef uint16_t uECC_dword_t; + +#define HIGH_BIT_SET 0x80 +#define uECC_WORD_BITS 8 +#define uECC_WORD_BITS_SHIFT 3 +#define uECC_WORD_BITS_MASK 0x07 + +#elif (uECC_WORD_SIZE == 4) + +typedef uint32_t uECC_word_t; +typedef uint64_t uECC_dword_t; + +#define HIGH_BIT_SET 0x80000000 +#define uECC_WORD_BITS 32 +#define uECC_WORD_BITS_SHIFT 5 +#define uECC_WORD_BITS_MASK 0x01F + +#elif (uECC_WORD_SIZE == 8) + +typedef uint64_t uECC_word_t; +#if SUPPORTS_INT128 +typedef unsigned __int128 uECC_dword_t; +#endif + +#define HIGH_BIT_SET 0x8000000000000000ull +#define uECC_WORD_BITS 64 +#define uECC_WORD_BITS_SHIFT 6 +#define uECC_WORD_BITS_MASK 0x03F + +#endif /* uECC_WORD_SIZE */ + +#endif /* _UECC_TYPES_H_ */ diff --git a/web/server/h2o/libh2o/deps/picotls/deps/micro-ecc/uECC.c b/web/server/h2o/libh2o/deps/picotls/deps/micro-ecc/uECC.c new file mode 100644 index 00000000..daa144a5 --- /dev/null +++ b/web/server/h2o/libh2o/deps/picotls/deps/micro-ecc/uECC.c @@ -0,0 +1,1634 @@ +/* Copyright 2014, Kenneth MacKay. Licensed under the BSD 2-clause license. */ + +#include "uECC.h" +#include "uECC_vli.h" + +#ifndef uECC_RNG_MAX_TRIES + #define uECC_RNG_MAX_TRIES 64 +#endif + +#if uECC_ENABLE_VLI_API + #define uECC_VLI_API +#else + #define uECC_VLI_API static +#endif + +#define CONCATX(a, ...) a ## __VA_ARGS__ +#define CONCAT(a, ...) CONCATX(a, __VA_ARGS__) + +#define STRX(a) #a +#define STR(a) STRX(a) + +#define EVAL(...) EVAL1(EVAL1(EVAL1(EVAL1(__VA_ARGS__)))) +#define EVAL1(...) EVAL2(EVAL2(EVAL2(EVAL2(__VA_ARGS__)))) +#define EVAL2(...) EVAL3(EVAL3(EVAL3(EVAL3(__VA_ARGS__)))) +#define EVAL3(...) EVAL4(EVAL4(EVAL4(EVAL4(__VA_ARGS__)))) +#define EVAL4(...) __VA_ARGS__ + +#define DEC_1 0 +#define DEC_2 1 +#define DEC_3 2 +#define DEC_4 3 +#define DEC_5 4 +#define DEC_6 5 +#define DEC_7 6 +#define DEC_8 7 +#define DEC_9 8 +#define DEC_10 9 +#define DEC_11 10 +#define DEC_12 11 +#define DEC_13 12 +#define DEC_14 13 +#define DEC_15 14 +#define DEC_16 15 +#define DEC_17 16 +#define DEC_18 17 +#define DEC_19 18 +#define DEC_20 19 +#define DEC_21 20 +#define DEC_22 21 +#define DEC_23 22 +#define DEC_24 23 +#define DEC_25 24 +#define DEC_26 25 +#define DEC_27 26 +#define DEC_28 27 +#define DEC_29 28 +#define DEC_30 29 +#define DEC_31 30 +#define DEC_32 31 + +#define DEC(N) CONCAT(DEC_, N) + +#define SECOND_ARG(_, val, ...) val +#define SOME_CHECK_0 ~, 0 +#define GET_SECOND_ARG(...) SECOND_ARG(__VA_ARGS__, SOME,) +#define SOME_OR_0(N) GET_SECOND_ARG(CONCAT(SOME_CHECK_, N)) + +#define EMPTY(...) +#define DEFER(...) __VA_ARGS__ EMPTY() + +#define REPEAT_NAME_0() REPEAT_0 +#define REPEAT_NAME_SOME() REPEAT_SOME +#define REPEAT_0(...) +#define REPEAT_SOME(N, stuff) DEFER(CONCAT(REPEAT_NAME_, SOME_OR_0(DEC(N))))()(DEC(N), stuff) stuff +#define REPEAT(N, stuff) EVAL(REPEAT_SOME(N, stuff)) + +#define REPEATM_NAME_0() REPEATM_0 +#define REPEATM_NAME_SOME() REPEATM_SOME +#define REPEATM_0(...) +#define REPEATM_SOME(N, macro) macro(N) \ + DEFER(CONCAT(REPEATM_NAME_, SOME_OR_0(DEC(N))))()(DEC(N), macro) +#define REPEATM(N, macro) EVAL(REPEATM_SOME(N, macro)) + +#include "platform-specific.inc" + +#if (uECC_WORD_SIZE == 1) + #if uECC_SUPPORTS_secp160r1 + #define uECC_MAX_WORDS 21 /* Due to the size of curve_n. */ + #endif + #if uECC_SUPPORTS_secp192r1 + #undef uECC_MAX_WORDS + #define uECC_MAX_WORDS 24 + #endif + #if uECC_SUPPORTS_secp224r1 + #undef uECC_MAX_WORDS + #define uECC_MAX_WORDS 28 + #endif + #if (uECC_SUPPORTS_secp256r1 || uECC_SUPPORTS_secp256k1) + #undef uECC_MAX_WORDS + #define uECC_MAX_WORDS 32 + #endif +#elif (uECC_WORD_SIZE == 4) + #if uECC_SUPPORTS_secp160r1 + #define uECC_MAX_WORDS 6 /* Due to the size of curve_n. */ + #endif + #if uECC_SUPPORTS_secp192r1 + #undef uECC_MAX_WORDS + #define uECC_MAX_WORDS 6 + #endif + #if uECC_SUPPORTS_secp224r1 + #undef uECC_MAX_WORDS + #define uECC_MAX_WORDS 7 + #endif + #if (uECC_SUPPORTS_secp256r1 || uECC_SUPPORTS_secp256k1) + #undef uECC_MAX_WORDS + #define uECC_MAX_WORDS 8 + #endif +#elif (uECC_WORD_SIZE == 8) + #if uECC_SUPPORTS_secp160r1 + #define uECC_MAX_WORDS 3 + #endif + #if uECC_SUPPORTS_secp192r1 + #undef uECC_MAX_WORDS + #define uECC_MAX_WORDS 3 + #endif + #if uECC_SUPPORTS_secp224r1 + #undef uECC_MAX_WORDS + #define uECC_MAX_WORDS 4 + #endif + #if (uECC_SUPPORTS_secp256r1 || uECC_SUPPORTS_secp256k1) + #undef uECC_MAX_WORDS + #define uECC_MAX_WORDS 4 + #endif +#endif /* uECC_WORD_SIZE */ + +#define BITS_TO_WORDS(num_bits) ((num_bits + ((uECC_WORD_SIZE * 8) - 1)) / (uECC_WORD_SIZE * 8)) +#define BITS_TO_BYTES(num_bits) ((num_bits + 7) / 8) + +struct uECC_Curve_t { + wordcount_t num_words; + wordcount_t num_bytes; + bitcount_t num_n_bits; + uECC_word_t p[uECC_MAX_WORDS]; + uECC_word_t n[uECC_MAX_WORDS]; + uECC_word_t G[uECC_MAX_WORDS * 2]; + uECC_word_t b[uECC_MAX_WORDS]; + void (*double_jacobian)(uECC_word_t * X1, + uECC_word_t * Y1, + uECC_word_t * Z1, + uECC_Curve curve); +#if uECC_SUPPORT_COMPRESSED_POINT + void (*mod_sqrt)(uECC_word_t *a, uECC_Curve curve); +#endif + void (*x_side)(uECC_word_t *result, const uECC_word_t *x, uECC_Curve curve); +#if (uECC_OPTIMIZATION_LEVEL > 0) + void (*mmod_fast)(uECC_word_t *result, uECC_word_t *product); +#endif +}; + +#if uECC_VLI_NATIVE_LITTLE_ENDIAN +static void bcopy(uint8_t *dst, + const uint8_t *src, + unsigned num_bytes) { + while (0 != num_bytes) { + num_bytes--; + dst[num_bytes] = src[num_bytes]; + } +} +#endif + +static cmpresult_t uECC_vli_cmp_unsafe(const uECC_word_t *left, + const uECC_word_t *right, + wordcount_t num_words); + +#if (uECC_PLATFORM == uECC_arm || uECC_PLATFORM == uECC_arm_thumb || \ + uECC_PLATFORM == uECC_arm_thumb2) + #include "asm_arm.inc" +#endif + +#if (uECC_PLATFORM == uECC_avr) + #include "asm_avr.inc" +#endif + +#if default_RNG_defined +static uECC_RNG_Function g_rng_function = &default_RNG; +#else +static uECC_RNG_Function g_rng_function = 0; +#endif + +void uECC_set_rng(uECC_RNG_Function rng_function) { + g_rng_function = rng_function; +} + +uECC_RNG_Function uECC_get_rng(void) { + return g_rng_function; +} + +int uECC_curve_private_key_size(uECC_Curve curve) { + return BITS_TO_BYTES(curve->num_n_bits); +} + +int uECC_curve_public_key_size(uECC_Curve curve) { + return 2 * curve->num_bytes; +} + +#if !asm_clear +uECC_VLI_API void uECC_vli_clear(uECC_word_t *vli, wordcount_t num_words) { + wordcount_t i; + for (i = 0; i < num_words; ++i) { + vli[i] = 0; + } +} +#endif /* !asm_clear */ + +/* Constant-time comparison to zero - secure way to compare long integers */ +/* Returns 1 if vli == 0, 0 otherwise. */ +uECC_VLI_API uECC_word_t uECC_vli_isZero(const uECC_word_t *vli, wordcount_t num_words) { + uECC_word_t bits = 0; + wordcount_t i; + for (i = 0; i < num_words; ++i) { + bits |= vli[i]; + } + return (bits == 0); +} + +/* Returns nonzero if bit 'bit' of vli is set. */ +uECC_VLI_API uECC_word_t uECC_vli_testBit(const uECC_word_t *vli, bitcount_t bit) { + return (vli[bit >> uECC_WORD_BITS_SHIFT] & ((uECC_word_t)1 << (bit & uECC_WORD_BITS_MASK))); +} + +/* Counts the number of words in vli. */ +static wordcount_t vli_numDigits(const uECC_word_t *vli, const wordcount_t max_words) { + wordcount_t i; + /* Search from the end until we find a non-zero digit. + We do it in reverse because we expect that most digits will be nonzero. */ + for (i = max_words - 1; i >= 0 && vli[i] == 0; --i) { + } + + return (i + 1); +} + +/* Counts the number of bits required to represent vli. */ +uECC_VLI_API bitcount_t uECC_vli_numBits(const uECC_word_t *vli, const wordcount_t max_words) { + uECC_word_t i; + uECC_word_t digit; + + wordcount_t num_digits = vli_numDigits(vli, max_words); + if (num_digits == 0) { + return 0; + } + + digit = vli[num_digits - 1]; + for (i = 0; digit; ++i) { + digit >>= 1; + } + + return (((bitcount_t)(num_digits - 1) << uECC_WORD_BITS_SHIFT) + i); +} + +/* Sets dest = src. */ +#if !asm_set +uECC_VLI_API void uECC_vli_set(uECC_word_t *dest, const uECC_word_t *src, wordcount_t num_words) { + wordcount_t i; + for (i = 0; i < num_words; ++i) { + dest[i] = src[i]; + } +} +#endif /* !asm_set */ + +/* Returns sign of left - right. */ +static cmpresult_t uECC_vli_cmp_unsafe(const uECC_word_t *left, + const uECC_word_t *right, + wordcount_t num_words) { + wordcount_t i; + for (i = num_words - 1; i >= 0; --i) { + if (left[i] > right[i]) { + return 1; + } else if (left[i] < right[i]) { + return -1; + } + } + return 0; +} + +/* Constant-time comparison function - secure way to compare long integers */ +/* Returns one if left == right, zero otherwise. */ +uECC_VLI_API uECC_word_t uECC_vli_equal(const uECC_word_t *left, + const uECC_word_t *right, + wordcount_t num_words) { + uECC_word_t diff = 0; + wordcount_t i; + for (i = num_words - 1; i >= 0; --i) { + diff |= (left[i] ^ right[i]); + } + return (diff == 0); +} + +uECC_VLI_API uECC_word_t uECC_vli_sub(uECC_word_t *result, + const uECC_word_t *left, + const uECC_word_t *right, + wordcount_t num_words); + +/* Returns sign of left - right, in constant time. */ +uECC_VLI_API cmpresult_t uECC_vli_cmp(const uECC_word_t *left, + const uECC_word_t *right, + wordcount_t num_words) { + uECC_word_t tmp[uECC_MAX_WORDS]; + uECC_word_t neg = !!uECC_vli_sub(tmp, left, right, num_words); + uECC_word_t equal = uECC_vli_isZero(tmp, num_words); + return (!equal - 2 * neg); +} + +/* Computes vli = vli >> 1. */ +#if !asm_rshift1 +uECC_VLI_API void uECC_vli_rshift1(uECC_word_t *vli, wordcount_t num_words) { + uECC_word_t *end = vli; + uECC_word_t carry = 0; + + vli += num_words; + while (vli-- > end) { + uECC_word_t temp = *vli; + *vli = (temp >> 1) | carry; + carry = temp << (uECC_WORD_BITS - 1); + } +} +#endif /* !asm_rshift1 */ + +/* Computes result = left + right, returning carry. Can modify in place. */ +#if !asm_add +uECC_VLI_API uECC_word_t uECC_vli_add(uECC_word_t *result, + const uECC_word_t *left, + const uECC_word_t *right, + wordcount_t num_words) { + uECC_word_t carry = 0; + wordcount_t i; + for (i = 0; i < num_words; ++i) { + uECC_word_t sum = left[i] + right[i] + carry; + if (sum != left[i]) { + carry = (sum < left[i]); + } + result[i] = sum; + } + return carry; +} +#endif /* !asm_add */ + +/* Computes result = left - right, returning borrow. Can modify in place. */ +#if !asm_sub +uECC_VLI_API uECC_word_t uECC_vli_sub(uECC_word_t *result, + const uECC_word_t *left, + const uECC_word_t *right, + wordcount_t num_words) { + uECC_word_t borrow = 0; + wordcount_t i; + for (i = 0; i < num_words; ++i) { + uECC_word_t diff = left[i] - right[i] - borrow; + if (diff != left[i]) { + borrow = (diff > left[i]); + } + result[i] = diff; + } + return borrow; +} +#endif /* !asm_sub */ + +#if !asm_mult || (uECC_SQUARE_FUNC && !asm_square) || \ + (uECC_SUPPORTS_secp256k1 && (uECC_OPTIMIZATION_LEVEL > 0) && \ + ((uECC_WORD_SIZE == 1) || (uECC_WORD_SIZE == 8))) +static void muladd(uECC_word_t a, + uECC_word_t b, + uECC_word_t *r0, + uECC_word_t *r1, + uECC_word_t *r2) { +#if uECC_WORD_SIZE == 8 && !SUPPORTS_INT128 + uint64_t a0 = a & 0xffffffffull; + uint64_t a1 = a >> 32; + uint64_t b0 = b & 0xffffffffull; + uint64_t b1 = b >> 32; + + uint64_t i0 = a0 * b0; + uint64_t i1 = a0 * b1; + uint64_t i2 = a1 * b0; + uint64_t i3 = a1 * b1; + + uint64_t p0, p1; + + i2 += (i0 >> 32); + i2 += i1; + if (i2 < i1) { /* overflow */ + i3 += 0x100000000ull; + } + + p0 = (i0 & 0xffffffffull) | (i2 << 32); + p1 = i3 + (i2 >> 32); + + *r0 += p0; + *r1 += (p1 + (*r0 < p0)); + *r2 += ((*r1 < p1) || (*r1 == p1 && *r0 < p0)); +#else + uECC_dword_t p = (uECC_dword_t)a * b; + uECC_dword_t r01 = ((uECC_dword_t)(*r1) << uECC_WORD_BITS) | *r0; + r01 += p; + *r2 += (r01 < p); + *r1 = r01 >> uECC_WORD_BITS; + *r0 = (uECC_word_t)r01; +#endif +} +#endif /* muladd needed */ + +#if !asm_mult +uECC_VLI_API void uECC_vli_mult(uECC_word_t *result, + const uECC_word_t *left, + const uECC_word_t *right, + wordcount_t num_words) { + uECC_word_t r0 = 0; + uECC_word_t r1 = 0; + uECC_word_t r2 = 0; + wordcount_t i, k; + + /* Compute each digit of result in sequence, maintaining the carries. */ + for (k = 0; k < num_words; ++k) { + for (i = 0; i <= k; ++i) { + muladd(left[i], right[k - i], &r0, &r1, &r2); + } + result[k] = r0; + r0 = r1; + r1 = r2; + r2 = 0; + } + for (k = num_words; k < num_words * 2 - 1; ++k) { + for (i = (k + 1) - num_words; i < num_words; ++i) { + muladd(left[i], right[k - i], &r0, &r1, &r2); + } + result[k] = r0; + r0 = r1; + r1 = r2; + r2 = 0; + } + result[num_words * 2 - 1] = r0; +} +#endif /* !asm_mult */ + +#if uECC_SQUARE_FUNC + +#if !asm_square +static void mul2add(uECC_word_t a, + uECC_word_t b, + uECC_word_t *r0, + uECC_word_t *r1, + uECC_word_t *r2) { +#if uECC_WORD_SIZE == 8 && !SUPPORTS_INT128 + uint64_t a0 = a & 0xffffffffull; + uint64_t a1 = a >> 32; + uint64_t b0 = b & 0xffffffffull; + uint64_t b1 = b >> 32; + + uint64_t i0 = a0 * b0; + uint64_t i1 = a0 * b1; + uint64_t i2 = a1 * b0; + uint64_t i3 = a1 * b1; + + uint64_t p0, p1; + + i2 += (i0 >> 32); + i2 += i1; + if (i2 < i1) + { /* overflow */ + i3 += 0x100000000ull; + } + + p0 = (i0 & 0xffffffffull) | (i2 << 32); + p1 = i3 + (i2 >> 32); + + *r2 += (p1 >> 63); + p1 = (p1 << 1) | (p0 >> 63); + p0 <<= 1; + + *r0 += p0; + *r1 += (p1 + (*r0 < p0)); + *r2 += ((*r1 < p1) || (*r1 == p1 && *r0 < p0)); +#else + uECC_dword_t p = (uECC_dword_t)a * b; + uECC_dword_t r01 = ((uECC_dword_t)(*r1) << uECC_WORD_BITS) | *r0; + *r2 += (p >> (uECC_WORD_BITS * 2 - 1)); + p *= 2; + r01 += p; + *r2 += (r01 < p); + *r1 = r01 >> uECC_WORD_BITS; + *r0 = (uECC_word_t)r01; +#endif +} + +uECC_VLI_API void uECC_vli_square(uECC_word_t *result, + const uECC_word_t *left, + wordcount_t num_words) { + uECC_word_t r0 = 0; + uECC_word_t r1 = 0; + uECC_word_t r2 = 0; + + wordcount_t i, k; + + for (k = 0; k < num_words * 2 - 1; ++k) { + uECC_word_t min = (k < num_words ? 0 : (k + 1) - num_words); + for (i = min; i <= k && i <= k - i; ++i) { + if (i < k-i) { + mul2add(left[i], left[k - i], &r0, &r1, &r2); + } else { + muladd(left[i], left[k - i], &r0, &r1, &r2); + } + } + result[k] = r0; + r0 = r1; + r1 = r2; + r2 = 0; + } + + result[num_words * 2 - 1] = r0; +} +#endif /* !asm_square */ + +#else /* uECC_SQUARE_FUNC */ + +#if uECC_ENABLE_VLI_API +uECC_VLI_API void uECC_vli_square(uECC_word_t *result, + const uECC_word_t *left, + wordcount_t num_words) { + uECC_vli_mult(result, left, left, num_words); +} +#endif /* uECC_ENABLE_VLI_API */ + +#endif /* uECC_SQUARE_FUNC */ + +/* Computes result = (left + right) % mod. + Assumes that left < mod and right < mod, and that result does not overlap mod. */ +uECC_VLI_API void uECC_vli_modAdd(uECC_word_t *result, + const uECC_word_t *left, + const uECC_word_t *right, + const uECC_word_t *mod, + wordcount_t num_words) { + uECC_word_t carry = uECC_vli_add(result, left, right, num_words); + if (carry || uECC_vli_cmp_unsafe(mod, result, num_words) != 1) { + /* result > mod (result = mod + remainder), so subtract mod to get remainder. */ + uECC_vli_sub(result, result, mod, num_words); + } +} + +/* Computes result = (left - right) % mod. + Assumes that left < mod and right < mod, and that result does not overlap mod. */ +uECC_VLI_API void uECC_vli_modSub(uECC_word_t *result, + const uECC_word_t *left, + const uECC_word_t *right, + const uECC_word_t *mod, + wordcount_t num_words) { + uECC_word_t l_borrow = uECC_vli_sub(result, left, right, num_words); + if (l_borrow) { + /* In this case, result == -diff == (max int) - diff. Since -x % d == d - x, + we can get the correct result from result + mod (with overflow). */ + uECC_vli_add(result, result, mod, num_words); + } +} + +/* Computes result = product % mod, where product is 2N words long. */ +/* Currently only designed to work for curve_p or curve_n. */ +uECC_VLI_API void uECC_vli_mmod(uECC_word_t *result, + uECC_word_t *product, + const uECC_word_t *mod, + wordcount_t num_words) { + uECC_word_t mod_multiple[2 * uECC_MAX_WORDS]; + uECC_word_t tmp[2 * uECC_MAX_WORDS]; + uECC_word_t *v[2] = {tmp, product}; + uECC_word_t index; + + /* Shift mod so its highest set bit is at the maximum position. */ + bitcount_t shift = (num_words * 2 * uECC_WORD_BITS) - uECC_vli_numBits(mod, num_words); + wordcount_t word_shift = shift / uECC_WORD_BITS; + wordcount_t bit_shift = shift % uECC_WORD_BITS; + uECC_word_t carry = 0; + uECC_vli_clear(mod_multiple, word_shift); + if (bit_shift > 0) { + for(index = 0; index < (uECC_word_t)num_words; ++index) { + mod_multiple[word_shift + index] = (mod[index] << bit_shift) | carry; + carry = mod[index] >> (uECC_WORD_BITS - bit_shift); + } + } else { + uECC_vli_set(mod_multiple + word_shift, mod, num_words); + } + + for (index = 1; shift >= 0; --shift) { + uECC_word_t borrow = 0; + wordcount_t i; + for (i = 0; i < num_words * 2; ++i) { + uECC_word_t diff = v[index][i] - mod_multiple[i] - borrow; + if (diff != v[index][i]) { + borrow = (diff > v[index][i]); + } + v[1 - index][i] = diff; + } + index = !(index ^ borrow); /* Swap the index if there was no borrow */ + uECC_vli_rshift1(mod_multiple, num_words); + mod_multiple[num_words - 1] |= mod_multiple[num_words] << (uECC_WORD_BITS - 1); + uECC_vli_rshift1(mod_multiple + num_words, num_words); + } + uECC_vli_set(result, v[index], num_words); +} + +/* Computes result = (left * right) % mod. */ +uECC_VLI_API void uECC_vli_modMult(uECC_word_t *result, + const uECC_word_t *left, + const uECC_word_t *right, + const uECC_word_t *mod, + wordcount_t num_words) { + uECC_word_t product[2 * uECC_MAX_WORDS]; + uECC_vli_mult(product, left, right, num_words); + uECC_vli_mmod(result, product, mod, num_words); +} + +uECC_VLI_API void uECC_vli_modMult_fast(uECC_word_t *result, + const uECC_word_t *left, + const uECC_word_t *right, + uECC_Curve curve) { + uECC_word_t product[2 * uECC_MAX_WORDS]; + uECC_vli_mult(product, left, right, curve->num_words); +#if (uECC_OPTIMIZATION_LEVEL > 0) + curve->mmod_fast(result, product); +#else + uECC_vli_mmod(result, product, curve->p, curve->num_words); +#endif +} + +#if uECC_SQUARE_FUNC + +#if uECC_ENABLE_VLI_API +/* Computes result = left^2 % mod. */ +uECC_VLI_API void uECC_vli_modSquare(uECC_word_t *result, + const uECC_word_t *left, + const uECC_word_t *mod, + wordcount_t num_words) { + uECC_word_t product[2 * uECC_MAX_WORDS]; + uECC_vli_square(product, left, num_words); + uECC_vli_mmod(result, product, mod, num_words); +} +#endif /* uECC_ENABLE_VLI_API */ + +uECC_VLI_API void uECC_vli_modSquare_fast(uECC_word_t *result, + const uECC_word_t *left, + uECC_Curve curve) { + uECC_word_t product[2 * uECC_MAX_WORDS]; + uECC_vli_square(product, left, curve->num_words); +#if (uECC_OPTIMIZATION_LEVEL > 0) + curve->mmod_fast(result, product); +#else + uECC_vli_mmod(result, product, curve->p, curve->num_words); +#endif +} + +#else /* uECC_SQUARE_FUNC */ + +#if uECC_ENABLE_VLI_API +uECC_VLI_API void uECC_vli_modSquare(uECC_word_t *result, + const uECC_word_t *left, + const uECC_word_t *mod, + wordcount_t num_words) { + uECC_vli_modMult(result, left, left, mod, num_words); +} +#endif /* uECC_ENABLE_VLI_API */ + +uECC_VLI_API void uECC_vli_modSquare_fast(uECC_word_t *result, + const uECC_word_t *left, + uECC_Curve curve) { + uECC_vli_modMult_fast(result, left, left, curve); +} + +#endif /* uECC_SQUARE_FUNC */ + +#define EVEN(vli) (!(vli[0] & 1)) +static void vli_modInv_update(uECC_word_t *uv, + const uECC_word_t *mod, + wordcount_t num_words) { + uECC_word_t carry = 0; + if (!EVEN(uv)) { + carry = uECC_vli_add(uv, uv, mod, num_words); + } + uECC_vli_rshift1(uv, num_words); + if (carry) { + uv[num_words - 1] |= HIGH_BIT_SET; + } +} + +/* Computes result = (1 / input) % mod. All VLIs are the same size. + See "From Euclid's GCD to Montgomery Multiplication to the Great Divide" */ +uECC_VLI_API void uECC_vli_modInv(uECC_word_t *result, + const uECC_word_t *input, + const uECC_word_t *mod, + wordcount_t num_words) { + uECC_word_t a[uECC_MAX_WORDS], b[uECC_MAX_WORDS], u[uECC_MAX_WORDS], v[uECC_MAX_WORDS]; + cmpresult_t cmpResult; + + if (uECC_vli_isZero(input, num_words)) { + uECC_vli_clear(result, num_words); + return; + } + + uECC_vli_set(a, input, num_words); + uECC_vli_set(b, mod, num_words); + uECC_vli_clear(u, num_words); + u[0] = 1; + uECC_vli_clear(v, num_words); + while ((cmpResult = uECC_vli_cmp_unsafe(a, b, num_words)) != 0) { + if (EVEN(a)) { + uECC_vli_rshift1(a, num_words); + vli_modInv_update(u, mod, num_words); + } else if (EVEN(b)) { + uECC_vli_rshift1(b, num_words); + vli_modInv_update(v, mod, num_words); + } else if (cmpResult > 0) { + uECC_vli_sub(a, a, b, num_words); + uECC_vli_rshift1(a, num_words); + if (uECC_vli_cmp_unsafe(u, v, num_words) < 0) { + uECC_vli_add(u, u, mod, num_words); + } + uECC_vli_sub(u, u, v, num_words); + vli_modInv_update(u, mod, num_words); + } else { + uECC_vli_sub(b, b, a, num_words); + uECC_vli_rshift1(b, num_words); + if (uECC_vli_cmp_unsafe(v, u, num_words) < 0) { + uECC_vli_add(v, v, mod, num_words); + } + uECC_vli_sub(v, v, u, num_words); + vli_modInv_update(v, mod, num_words); + } + } + uECC_vli_set(result, u, num_words); +} + +/* ------ Point operations ------ */ + +#include "curve-specific.inc" + +/* Returns 1 if 'point' is the point at infinity, 0 otherwise. */ +#define EccPoint_isZero(point, curve) uECC_vli_isZero((point), (curve)->num_words * 2) + +/* Point multiplication algorithm using Montgomery's ladder with co-Z coordinates. +From http://eprint.iacr.org/2011/338.pdf +*/ + +/* Modify (x1, y1) => (x1 * z^2, y1 * z^3) */ +static void apply_z(uECC_word_t * X1, + uECC_word_t * Y1, + const uECC_word_t * const Z, + uECC_Curve curve) { + uECC_word_t t1[uECC_MAX_WORDS]; + + uECC_vli_modSquare_fast(t1, Z, curve); /* z^2 */ + uECC_vli_modMult_fast(X1, X1, t1, curve); /* x1 * z^2 */ + uECC_vli_modMult_fast(t1, t1, Z, curve); /* z^3 */ + uECC_vli_modMult_fast(Y1, Y1, t1, curve); /* y1 * z^3 */ +} + +/* P = (x1, y1) => 2P, (x2, y2) => P' */ +static void XYcZ_initial_double(uECC_word_t * X1, + uECC_word_t * Y1, + uECC_word_t * X2, + uECC_word_t * Y2, + const uECC_word_t * const initial_Z, + uECC_Curve curve) { + uECC_word_t z[uECC_MAX_WORDS]; + wordcount_t num_words = curve->num_words; + if (initial_Z) { + uECC_vli_set(z, initial_Z, num_words); + } else { + uECC_vli_clear(z, num_words); + z[0] = 1; + } + + uECC_vli_set(X2, X1, num_words); + uECC_vli_set(Y2, Y1, num_words); + + apply_z(X1, Y1, z, curve); + curve->double_jacobian(X1, Y1, z, curve); + apply_z(X2, Y2, z, curve); +} + +/* Input P = (x1, y1, Z), Q = (x2, y2, Z) + Output P' = (x1', y1', Z3), P + Q = (x3, y3, Z3) + or P => P', Q => P + Q +*/ +static void XYcZ_add(uECC_word_t * X1, + uECC_word_t * Y1, + uECC_word_t * X2, + uECC_word_t * Y2, + uECC_Curve curve) { + /* t1 = X1, t2 = Y1, t3 = X2, t4 = Y2 */ + uECC_word_t t5[uECC_MAX_WORDS]; + wordcount_t num_words = curve->num_words; + + uECC_vli_modSub(t5, X2, X1, curve->p, num_words); /* t5 = x2 - x1 */ + uECC_vli_modSquare_fast(t5, t5, curve); /* t5 = (x2 - x1)^2 = A */ + uECC_vli_modMult_fast(X1, X1, t5, curve); /* t1 = x1*A = B */ + uECC_vli_modMult_fast(X2, X2, t5, curve); /* t3 = x2*A = C */ + uECC_vli_modSub(Y2, Y2, Y1, curve->p, num_words); /* t4 = y2 - y1 */ + uECC_vli_modSquare_fast(t5, Y2, curve); /* t5 = (y2 - y1)^2 = D */ + + uECC_vli_modSub(t5, t5, X1, curve->p, num_words); /* t5 = D - B */ + uECC_vli_modSub(t5, t5, X2, curve->p, num_words); /* t5 = D - B - C = x3 */ + uECC_vli_modSub(X2, X2, X1, curve->p, num_words); /* t3 = C - B */ + uECC_vli_modMult_fast(Y1, Y1, X2, curve); /* t2 = y1*(C - B) */ + uECC_vli_modSub(X2, X1, t5, curve->p, num_words); /* t3 = B - x3 */ + uECC_vli_modMult_fast(Y2, Y2, X2, curve); /* t4 = (y2 - y1)*(B - x3) */ + uECC_vli_modSub(Y2, Y2, Y1, curve->p, num_words); /* t4 = y3 */ + + uECC_vli_set(X2, t5, num_words); +} + +/* Input P = (x1, y1, Z), Q = (x2, y2, Z) + Output P + Q = (x3, y3, Z3), P - Q = (x3', y3', Z3) + or P => P - Q, Q => P + Q +*/ +static void XYcZ_addC(uECC_word_t * X1, + uECC_word_t * Y1, + uECC_word_t * X2, + uECC_word_t * Y2, + uECC_Curve curve) { + /* t1 = X1, t2 = Y1, t3 = X2, t4 = Y2 */ + uECC_word_t t5[uECC_MAX_WORDS]; + uECC_word_t t6[uECC_MAX_WORDS]; + uECC_word_t t7[uECC_MAX_WORDS]; + wordcount_t num_words = curve->num_words; + + uECC_vli_modSub(t5, X2, X1, curve->p, num_words); /* t5 = x2 - x1 */ + uECC_vli_modSquare_fast(t5, t5, curve); /* t5 = (x2 - x1)^2 = A */ + uECC_vli_modMult_fast(X1, X1, t5, curve); /* t1 = x1*A = B */ + uECC_vli_modMult_fast(X2, X2, t5, curve); /* t3 = x2*A = C */ + uECC_vli_modAdd(t5, Y2, Y1, curve->p, num_words); /* t5 = y2 + y1 */ + uECC_vli_modSub(Y2, Y2, Y1, curve->p, num_words); /* t4 = y2 - y1 */ + + uECC_vli_modSub(t6, X2, X1, curve->p, num_words); /* t6 = C - B */ + uECC_vli_modMult_fast(Y1, Y1, t6, curve); /* t2 = y1 * (C - B) = E */ + uECC_vli_modAdd(t6, X1, X2, curve->p, num_words); /* t6 = B + C */ + uECC_vli_modSquare_fast(X2, Y2, curve); /* t3 = (y2 - y1)^2 = D */ + uECC_vli_modSub(X2, X2, t6, curve->p, num_words); /* t3 = D - (B + C) = x3 */ + + uECC_vli_modSub(t7, X1, X2, curve->p, num_words); /* t7 = B - x3 */ + uECC_vli_modMult_fast(Y2, Y2, t7, curve); /* t4 = (y2 - y1)*(B - x3) */ + uECC_vli_modSub(Y2, Y2, Y1, curve->p, num_words); /* t4 = (y2 - y1)*(B - x3) - E = y3 */ + + uECC_vli_modSquare_fast(t7, t5, curve); /* t7 = (y2 + y1)^2 = F */ + uECC_vli_modSub(t7, t7, t6, curve->p, num_words); /* t7 = F - (B + C) = x3' */ + uECC_vli_modSub(t6, t7, X1, curve->p, num_words); /* t6 = x3' - B */ + uECC_vli_modMult_fast(t6, t6, t5, curve); /* t6 = (y2+y1)*(x3' - B) */ + uECC_vli_modSub(Y1, t6, Y1, curve->p, num_words); /* t2 = (y2+y1)*(x3' - B) - E = y3' */ + + uECC_vli_set(X1, t7, num_words); +} + +/* result may overlap point. */ +static void EccPoint_mult(uECC_word_t * result, + const uECC_word_t * point, + const uECC_word_t * scalar, + const uECC_word_t * initial_Z, + bitcount_t num_bits, + uECC_Curve curve) { + /* R0 and R1 */ + uECC_word_t Rx[2][uECC_MAX_WORDS]; + uECC_word_t Ry[2][uECC_MAX_WORDS]; + uECC_word_t z[uECC_MAX_WORDS]; + bitcount_t i; + uECC_word_t nb; + wordcount_t num_words = curve->num_words; + + uECC_vli_set(Rx[1], point, num_words); + uECC_vli_set(Ry[1], point + num_words, num_words); + + XYcZ_initial_double(Rx[1], Ry[1], Rx[0], Ry[0], initial_Z, curve); + + for (i = num_bits - 2; i > 0; --i) { + nb = !uECC_vli_testBit(scalar, i); + XYcZ_addC(Rx[1 - nb], Ry[1 - nb], Rx[nb], Ry[nb], curve); + XYcZ_add(Rx[nb], Ry[nb], Rx[1 - nb], Ry[1 - nb], curve); + } + + nb = !uECC_vli_testBit(scalar, 0); + XYcZ_addC(Rx[1 - nb], Ry[1 - nb], Rx[nb], Ry[nb], curve); + + /* Find final 1/Z value. */ + uECC_vli_modSub(z, Rx[1], Rx[0], curve->p, num_words); /* X1 - X0 */ + uECC_vli_modMult_fast(z, z, Ry[1 - nb], curve); /* Yb * (X1 - X0) */ + uECC_vli_modMult_fast(z, z, point, curve); /* xP * Yb * (X1 - X0) */ + uECC_vli_modInv(z, z, curve->p, num_words); /* 1 / (xP * Yb * (X1 - X0)) */ + /* yP / (xP * Yb * (X1 - X0)) */ + uECC_vli_modMult_fast(z, z, point + num_words, curve); + uECC_vli_modMult_fast(z, z, Rx[1 - nb], curve); /* Xb * yP / (xP * Yb * (X1 - X0)) */ + /* End 1/Z calculation */ + + XYcZ_add(Rx[nb], Ry[nb], Rx[1 - nb], Ry[1 - nb], curve); + apply_z(Rx[0], Ry[0], z, curve); + + uECC_vli_set(result, Rx[0], num_words); + uECC_vli_set(result + num_words, Ry[0], num_words); +} + +static uECC_word_t regularize_k(const uECC_word_t * const k, + uECC_word_t *k0, + uECC_word_t *k1, + uECC_Curve curve) { + wordcount_t num_n_words = BITS_TO_WORDS(curve->num_n_bits); + bitcount_t num_n_bits = curve->num_n_bits; + uECC_word_t carry = uECC_vli_add(k0, k, curve->n, num_n_words) || + (num_n_bits < ((bitcount_t)num_n_words * uECC_WORD_SIZE * 8) && + uECC_vli_testBit(k0, num_n_bits)); + uECC_vli_add(k1, k0, curve->n, num_n_words); + return carry; +} + +static uECC_word_t EccPoint_compute_public_key(uECC_word_t *result, + uECC_word_t *private_key, + uECC_Curve curve) { + uECC_word_t tmp1[uECC_MAX_WORDS]; + uECC_word_t tmp2[uECC_MAX_WORDS]; + uECC_word_t *p2[2] = {tmp1, tmp2}; + uECC_word_t carry; + + /* Regularize the bitcount for the private key so that attackers cannot use a side channel + attack to learn the number of leading zeros. */ + carry = regularize_k(private_key, tmp1, tmp2, curve); + + EccPoint_mult(result, curve->G, p2[!carry], 0, curve->num_n_bits + 1, curve); + + if (EccPoint_isZero(result, curve)) { + return 0; + } + return 1; +} + +#if uECC_WORD_SIZE == 1 + +uECC_VLI_API void uECC_vli_nativeToBytes(uint8_t *bytes, + int num_bytes, + const uint8_t *native) { + wordcount_t i; + for (i = 0; i < num_bytes; ++i) { + bytes[i] = native[(num_bytes - 1) - i]; + } +} + +uECC_VLI_API void uECC_vli_bytesToNative(uint8_t *native, + const uint8_t *bytes, + int num_bytes) { + uECC_vli_nativeToBytes(native, num_bytes, bytes); +} + +#else + +uECC_VLI_API void uECC_vli_nativeToBytes(uint8_t *bytes, + int num_bytes, + const uECC_word_t *native) { + wordcount_t i; + for (i = 0; i < num_bytes; ++i) { + unsigned b = num_bytes - 1 - i; + bytes[i] = native[b / uECC_WORD_SIZE] >> (8 * (b % uECC_WORD_SIZE)); + } +} + +uECC_VLI_API void uECC_vli_bytesToNative(uECC_word_t *native, + const uint8_t *bytes, + int num_bytes) { + wordcount_t i; + uECC_vli_clear(native, (num_bytes + (uECC_WORD_SIZE - 1)) / uECC_WORD_SIZE); + for (i = 0; i < num_bytes; ++i) { + unsigned b = num_bytes - 1 - i; + native[b / uECC_WORD_SIZE] |= + (uECC_word_t)bytes[i] << (8 * (b % uECC_WORD_SIZE)); + } +} + +#endif /* uECC_WORD_SIZE */ + +/* Generates a random integer in the range 0 < random < top. + Both random and top have num_words words. */ +uECC_VLI_API int uECC_generate_random_int(uECC_word_t *random, + const uECC_word_t *top, + wordcount_t num_words) { + uECC_word_t mask = (uECC_word_t)-1; + uECC_word_t tries; + bitcount_t num_bits = uECC_vli_numBits(top, num_words); + + if (!g_rng_function) { + return 0; + } + + for (tries = 0; tries < uECC_RNG_MAX_TRIES; ++tries) { + if (!g_rng_function((uint8_t *)random, num_words * uECC_WORD_SIZE)) { + return 0; + } + random[num_words - 1] &= mask >> ((bitcount_t)(num_words * uECC_WORD_SIZE * 8 - num_bits)); + if (!uECC_vli_isZero(random, num_words) && + uECC_vli_cmp(top, random, num_words) == 1) { + return 1; + } + } + return 0; +} + +int uECC_make_key(uint8_t *public_key, + uint8_t *private_key, + uECC_Curve curve) { +#if uECC_VLI_NATIVE_LITTLE_ENDIAN + uECC_word_t *_private = (uECC_word_t *)private_key; + uECC_word_t *_public = (uECC_word_t *)public_key; +#else + uECC_word_t _private[uECC_MAX_WORDS]; + uECC_word_t _public[uECC_MAX_WORDS * 2]; +#endif + uECC_word_t tries; + + for (tries = 0; tries < uECC_RNG_MAX_TRIES; ++tries) { + if (!uECC_generate_random_int(_private, curve->n, BITS_TO_WORDS(curve->num_n_bits))) { + return 0; + } + + if (EccPoint_compute_public_key(_public, _private, curve)) { +#if uECC_VLI_NATIVE_LITTLE_ENDIAN == 0 + uECC_vli_nativeToBytes(private_key, BITS_TO_BYTES(curve->num_n_bits), _private); + uECC_vli_nativeToBytes(public_key, curve->num_bytes, _public); + uECC_vli_nativeToBytes( + public_key + curve->num_bytes, curve->num_bytes, _public + curve->num_words); +#endif + return 1; + } + } + return 0; +} + +int uECC_shared_secret(const uint8_t *public_key, + const uint8_t *private_key, + uint8_t *secret, + uECC_Curve curve) { + uECC_word_t _public[uECC_MAX_WORDS * 2]; + uECC_word_t _private[uECC_MAX_WORDS]; + + uECC_word_t tmp[uECC_MAX_WORDS]; + uECC_word_t *p2[2] = {_private, tmp}; + uECC_word_t *initial_Z = 0; + uECC_word_t carry; + wordcount_t num_words = curve->num_words; + wordcount_t num_bytes = curve->num_bytes; + +#if uECC_VLI_NATIVE_LITTLE_ENDIAN + bcopy((uint8_t *) _private, private_key, num_bytes); + bcopy((uint8_t *) _public, public_key, num_bytes*2); +#else + uECC_vli_bytesToNative(_private, private_key, BITS_TO_BYTES(curve->num_n_bits)); + uECC_vli_bytesToNative(_public, public_key, num_bytes); + uECC_vli_bytesToNative(_public + num_words, public_key + num_bytes, num_bytes); +#endif + + /* Regularize the bitcount for the private key so that attackers cannot use a side channel + attack to learn the number of leading zeros. */ + carry = regularize_k(_private, _private, tmp, curve); + + /* If an RNG function was specified, try to get a random initial Z value to improve + protection against side-channel attacks. */ + if (g_rng_function) { + if (!uECC_generate_random_int(p2[carry], curve->p, num_words)) { + return 0; + } + initial_Z = p2[carry]; + } + + EccPoint_mult(_public, _public, p2[!carry], initial_Z, curve->num_n_bits + 1, curve); +#if uECC_VLI_NATIVE_LITTLE_ENDIAN + bcopy((uint8_t *) secret, (uint8_t *) _public, num_bytes); +#else + uECC_vli_nativeToBytes(secret, num_bytes, _public); +#endif + return !EccPoint_isZero(_public, curve); +} + +#if uECC_SUPPORT_COMPRESSED_POINT +void uECC_compress(const uint8_t *public_key, uint8_t *compressed, uECC_Curve curve) { + wordcount_t i; + for (i = 0; i < curve->num_bytes; ++i) { + compressed[i+1] = public_key[i]; + } +#if uECC_VLI_NATIVE_LITTLE_ENDIAN + compressed[0] = 2 + (public_key[curve->num_bytes] & 0x01); +#else + compressed[0] = 2 + (public_key[curve->num_bytes * 2 - 1] & 0x01); +#endif +} + +void uECC_decompress(const uint8_t *compressed, uint8_t *public_key, uECC_Curve curve) { +#if uECC_VLI_NATIVE_LITTLE_ENDIAN + uECC_word_t *point = (uECC_word_t *)public_key; +#else + uECC_word_t point[uECC_MAX_WORDS * 2]; +#endif + uECC_word_t *y = point + curve->num_words; +#if uECC_VLI_NATIVE_LITTLE_ENDIAN + bcopy(public_key, compressed+1, curve->num_bytes); +#else + uECC_vli_bytesToNative(point, compressed + 1, curve->num_bytes); +#endif + curve->x_side(y, point, curve); + curve->mod_sqrt(y, curve); + + if ((y[0] & 0x01) != (compressed[0] & 0x01)) { + uECC_vli_sub(y, curve->p, y, curve->num_words); + } + +#if uECC_VLI_NATIVE_LITTLE_ENDIAN == 0 + uECC_vli_nativeToBytes(public_key, curve->num_bytes, point); + uECC_vli_nativeToBytes(public_key + curve->num_bytes, curve->num_bytes, y); +#endif +} +#endif /* uECC_SUPPORT_COMPRESSED_POINT */ + +int uECC_valid_point(const uECC_word_t *point, uECC_Curve curve) { + uECC_word_t tmp1[uECC_MAX_WORDS]; + uECC_word_t tmp2[uECC_MAX_WORDS]; + wordcount_t num_words = curve->num_words; + + /* The point at infinity is invalid. */ + if (EccPoint_isZero(point, curve)) { + return 0; + } + + /* x and y must be smaller than p. */ + if (uECC_vli_cmp_unsafe(curve->p, point, num_words) != 1 || + uECC_vli_cmp_unsafe(curve->p, point + num_words, num_words) != 1) { + return 0; + } + + uECC_vli_modSquare_fast(tmp1, point + num_words, curve); + curve->x_side(tmp2, point, curve); /* tmp2 = x^3 + ax + b */ + + /* Make sure that y^2 == x^3 + ax + b */ + return (int)(uECC_vli_equal(tmp1, tmp2, num_words)); +} + +int uECC_valid_public_key(const uint8_t *public_key, uECC_Curve curve) { +#if uECC_VLI_NATIVE_LITTLE_ENDIAN + uECC_word_t *_public = (uECC_word_t *)public_key; +#else + uECC_word_t _public[uECC_MAX_WORDS * 2]; +#endif + +#if uECC_VLI_NATIVE_LITTLE_ENDIAN == 0 + uECC_vli_bytesToNative(_public, public_key, curve->num_bytes); + uECC_vli_bytesToNative( + _public + curve->num_words, public_key + curve->num_bytes, curve->num_bytes); +#endif + return uECC_valid_point(_public, curve); +} + +int uECC_compute_public_key(const uint8_t *private_key, uint8_t *public_key, uECC_Curve curve) { +#if uECC_VLI_NATIVE_LITTLE_ENDIAN + uECC_word_t *_private = (uECC_word_t *)private_key; + uECC_word_t *_public = (uECC_word_t *)public_key; +#else + uECC_word_t _private[uECC_MAX_WORDS]; + uECC_word_t _public[uECC_MAX_WORDS * 2]; +#endif + +#if uECC_VLI_NATIVE_LITTLE_ENDIAN == 0 + uECC_vli_bytesToNative(_private, private_key, BITS_TO_BYTES(curve->num_n_bits)); +#endif + + /* Make sure the private key is in the range [1, n-1]. */ + if (uECC_vli_isZero(_private, BITS_TO_WORDS(curve->num_n_bits))) { + return 0; + } + + if (uECC_vli_cmp(curve->n, _private, BITS_TO_WORDS(curve->num_n_bits)) != 1) { + return 0; + } + + /* Compute public key. */ + if (!EccPoint_compute_public_key(_public, _private, curve)) { + return 0; + } + +#if uECC_VLI_NATIVE_LITTLE_ENDIAN == 0 + uECC_vli_nativeToBytes(public_key, curve->num_bytes, _public); + uECC_vli_nativeToBytes( + public_key + curve->num_bytes, curve->num_bytes, _public + curve->num_words); +#endif + return 1; +} + + +/* -------- ECDSA code -------- */ + +static void bits2int(uECC_word_t *native, + const uint8_t *bits, + unsigned bits_size, + uECC_Curve curve) { + unsigned num_n_bytes = BITS_TO_BYTES(curve->num_n_bits); + unsigned num_n_words = BITS_TO_WORDS(curve->num_n_bits); + int shift; + uECC_word_t carry; + uECC_word_t *ptr; + + if (bits_size > num_n_bytes) { + bits_size = num_n_bytes; + } + + uECC_vli_clear(native, num_n_words); +#if uECC_VLI_NATIVE_LITTLE_ENDIAN + bcopy((uint8_t *) native, bits, bits_size); +#else + uECC_vli_bytesToNative(native, bits, bits_size); +#endif + if (bits_size * 8 <= (unsigned)curve->num_n_bits) { + return; + } + shift = bits_size * 8 - curve->num_n_bits; + carry = 0; + ptr = native + num_n_words; + while (ptr-- > native) { + uECC_word_t temp = *ptr; + *ptr = (temp >> shift) | carry; + carry = temp << (uECC_WORD_BITS - shift); + } + + /* Reduce mod curve_n */ + if (uECC_vli_cmp_unsafe(curve->n, native, num_n_words) != 1) { + uECC_vli_sub(native, native, curve->n, num_n_words); + } +} + +static int uECC_sign_with_k(const uint8_t *private_key, + const uint8_t *message_hash, + unsigned hash_size, + uECC_word_t *k, + uint8_t *signature, + uECC_Curve curve) { + + uECC_word_t tmp[uECC_MAX_WORDS]; + uECC_word_t s[uECC_MAX_WORDS]; + uECC_word_t *k2[2] = {tmp, s}; +#if uECC_VLI_NATIVE_LITTLE_ENDIAN + uECC_word_t *p = (uECC_word_t *)signature; +#else + uECC_word_t p[uECC_MAX_WORDS * 2]; +#endif + uECC_word_t carry; + wordcount_t num_words = curve->num_words; + wordcount_t num_n_words = BITS_TO_WORDS(curve->num_n_bits); + bitcount_t num_n_bits = curve->num_n_bits; + + /* Make sure 0 < k < curve_n */ + if (uECC_vli_isZero(k, num_words) || uECC_vli_cmp(curve->n, k, num_n_words) != 1) { + return 0; + } + + carry = regularize_k(k, tmp, s, curve); + EccPoint_mult(p, curve->G, k2[!carry], 0, num_n_bits + 1, curve); + if (uECC_vli_isZero(p, num_words)) { + return 0; + } + + /* If an RNG function was specified, get a random number + to prevent side channel analysis of k. */ + if (!g_rng_function) { + uECC_vli_clear(tmp, num_n_words); + tmp[0] = 1; + } else if (!uECC_generate_random_int(tmp, curve->n, num_n_words)) { + return 0; + } + + /* Prevent side channel analysis of uECC_vli_modInv() to determine + bits of k / the private key by premultiplying by a random number */ + uECC_vli_modMult(k, k, tmp, curve->n, num_n_words); /* k' = rand * k */ + uECC_vli_modInv(k, k, curve->n, num_n_words); /* k = 1 / k' */ + uECC_vli_modMult(k, k, tmp, curve->n, num_n_words); /* k = 1 / k */ + +#if uECC_VLI_NATIVE_LITTLE_ENDIAN == 0 + uECC_vli_nativeToBytes(signature, curve->num_bytes, p); /* store r */ +#endif + +#if uECC_VLI_NATIVE_LITTLE_ENDIAN + bcopy((uint8_t *) tmp, private_key, BITS_TO_BYTES(curve->num_n_bits)); +#else + uECC_vli_bytesToNative(tmp, private_key, BITS_TO_BYTES(curve->num_n_bits)); /* tmp = d */ +#endif + + s[num_n_words - 1] = 0; + uECC_vli_set(s, p, num_words); + uECC_vli_modMult(s, tmp, s, curve->n, num_n_words); /* s = r*d */ + + bits2int(tmp, message_hash, hash_size, curve); + uECC_vli_modAdd(s, tmp, s, curve->n, num_n_words); /* s = e + r*d */ + uECC_vli_modMult(s, s, k, curve->n, num_n_words); /* s = (e + r*d) / k */ + if (uECC_vli_numBits(s, num_n_words) > (bitcount_t)curve->num_bytes * 8) { + return 0; + } +#if uECC_VLI_NATIVE_LITTLE_ENDIAN + bcopy((uint8_t *) signature + curve->num_bytes, (uint8_t *) s, curve->num_bytes); +#else + uECC_vli_nativeToBytes(signature + curve->num_bytes, curve->num_bytes, s); +#endif + return 1; +} + +int uECC_sign(const uint8_t *private_key, + const uint8_t *message_hash, + unsigned hash_size, + uint8_t *signature, + uECC_Curve curve) { + uECC_word_t k[uECC_MAX_WORDS]; + uECC_word_t tries; + + for (tries = 0; tries < uECC_RNG_MAX_TRIES; ++tries) { + if (!uECC_generate_random_int(k, curve->n, BITS_TO_WORDS(curve->num_n_bits))) { + return 0; + } + + if (uECC_sign_with_k(private_key, message_hash, hash_size, k, signature, curve)) { + return 1; + } + } + return 0; +} + +/* Compute an HMAC using K as a key (as in RFC 6979). Note that K is always + the same size as the hash result size. */ +static void HMAC_init(const uECC_HashContext *hash_context, const uint8_t *K) { + uint8_t *pad = hash_context->tmp + 2 * hash_context->result_size; + unsigned i; + for (i = 0; i < hash_context->result_size; ++i) + pad[i] = K[i] ^ 0x36; + for (; i < hash_context->block_size; ++i) + pad[i] = 0x36; + + hash_context->init_hash(hash_context); + hash_context->update_hash(hash_context, pad, hash_context->block_size); +} + +static void HMAC_update(const uECC_HashContext *hash_context, + const uint8_t *message, + unsigned message_size) { + hash_context->update_hash(hash_context, message, message_size); +} + +static void HMAC_finish(const uECC_HashContext *hash_context, + const uint8_t *K, + uint8_t *result) { + uint8_t *pad = hash_context->tmp + 2 * hash_context->result_size; + unsigned i; + for (i = 0; i < hash_context->result_size; ++i) + pad[i] = K[i] ^ 0x5c; + for (; i < hash_context->block_size; ++i) + pad[i] = 0x5c; + + hash_context->finish_hash(hash_context, result); + + hash_context->init_hash(hash_context); + hash_context->update_hash(hash_context, pad, hash_context->block_size); + hash_context->update_hash(hash_context, result, hash_context->result_size); + hash_context->finish_hash(hash_context, result); +} + +/* V = HMAC_K(V) */ +static void update_V(const uECC_HashContext *hash_context, uint8_t *K, uint8_t *V) { + HMAC_init(hash_context, K); + HMAC_update(hash_context, V, hash_context->result_size); + HMAC_finish(hash_context, K, V); +} + +/* Deterministic signing, similar to RFC 6979. Differences are: + * We just use H(m) directly rather than bits2octets(H(m)) + (it is not reduced modulo curve_n). + * We generate a value for k (aka T) directly rather than converting endianness. + + Layout of hash_context->tmp: | | (1 byte overlapped 0x00 or 0x01) / */ +int uECC_sign_deterministic(const uint8_t *private_key, + const uint8_t *message_hash, + unsigned hash_size, + const uECC_HashContext *hash_context, + uint8_t *signature, + uECC_Curve curve) { + uint8_t *K = hash_context->tmp; + uint8_t *V = K + hash_context->result_size; + wordcount_t num_bytes = curve->num_bytes; + wordcount_t num_n_words = BITS_TO_WORDS(curve->num_n_bits); + bitcount_t num_n_bits = curve->num_n_bits; + uECC_word_t tries; + unsigned i; + for (i = 0; i < hash_context->result_size; ++i) { + V[i] = 0x01; + K[i] = 0; + } + + /* K = HMAC_K(V || 0x00 || int2octets(x) || h(m)) */ + HMAC_init(hash_context, K); + V[hash_context->result_size] = 0x00; + HMAC_update(hash_context, V, hash_context->result_size + 1); + HMAC_update(hash_context, private_key, num_bytes); + HMAC_update(hash_context, message_hash, hash_size); + HMAC_finish(hash_context, K, K); + + update_V(hash_context, K, V); + + /* K = HMAC_K(V || 0x01 || int2octets(x) || h(m)) */ + HMAC_init(hash_context, K); + V[hash_context->result_size] = 0x01; + HMAC_update(hash_context, V, hash_context->result_size + 1); + HMAC_update(hash_context, private_key, num_bytes); + HMAC_update(hash_context, message_hash, hash_size); + HMAC_finish(hash_context, K, K); + + update_V(hash_context, K, V); + + for (tries = 0; tries < uECC_RNG_MAX_TRIES; ++tries) { + uECC_word_t T[uECC_MAX_WORDS]; + uint8_t *T_ptr = (uint8_t *)T; + wordcount_t T_bytes = 0; + for (;;) { + update_V(hash_context, K, V); + for (i = 0; i < hash_context->result_size; ++i) { + T_ptr[T_bytes++] = V[i]; + if (T_bytes >= num_n_words * uECC_WORD_SIZE) { + goto filled; + } + } + } + filled: + if ((bitcount_t)num_n_words * uECC_WORD_SIZE * 8 > num_n_bits) { + uECC_word_t mask = (uECC_word_t)-1; + T[num_n_words - 1] &= + mask >> ((bitcount_t)(num_n_words * uECC_WORD_SIZE * 8 - num_n_bits)); + } + + if (uECC_sign_with_k(private_key, message_hash, hash_size, T, signature, curve)) { + return 1; + } + + /* K = HMAC_K(V || 0x00) */ + HMAC_init(hash_context, K); + V[hash_context->result_size] = 0x00; + HMAC_update(hash_context, V, hash_context->result_size + 1); + HMAC_finish(hash_context, K, K); + + update_V(hash_context, K, V); + } + return 0; +} + +static bitcount_t smax(bitcount_t a, bitcount_t b) { + return (a > b ? a : b); +} + +int uECC_verify(const uint8_t *public_key, + const uint8_t *message_hash, + unsigned hash_size, + const uint8_t *signature, + uECC_Curve curve) { + uECC_word_t u1[uECC_MAX_WORDS], u2[uECC_MAX_WORDS]; + uECC_word_t z[uECC_MAX_WORDS]; + uECC_word_t sum[uECC_MAX_WORDS * 2]; + uECC_word_t rx[uECC_MAX_WORDS]; + uECC_word_t ry[uECC_MAX_WORDS]; + uECC_word_t tx[uECC_MAX_WORDS]; + uECC_word_t ty[uECC_MAX_WORDS]; + uECC_word_t tz[uECC_MAX_WORDS]; + const uECC_word_t *points[4]; + const uECC_word_t *point; + bitcount_t num_bits; + bitcount_t i; +#if uECC_VLI_NATIVE_LITTLE_ENDIAN + uECC_word_t *_public = (uECC_word_t *)public_key; +#else + uECC_word_t _public[uECC_MAX_WORDS * 2]; +#endif + uECC_word_t r[uECC_MAX_WORDS], s[uECC_MAX_WORDS]; + wordcount_t num_words = curve->num_words; + wordcount_t num_n_words = BITS_TO_WORDS(curve->num_n_bits); + + rx[num_n_words - 1] = 0; + r[num_n_words - 1] = 0; + s[num_n_words - 1] = 0; + +#if uECC_VLI_NATIVE_LITTLE_ENDIAN + bcopy((uint8_t *) r, signature, curve->num_bytes); + bcopy((uint8_t *) s, signature + curve->num_bytes, curve->num_bytes); +#else + uECC_vli_bytesToNative(_public, public_key, curve->num_bytes); + uECC_vli_bytesToNative( + _public + num_words, public_key + curve->num_bytes, curve->num_bytes); + uECC_vli_bytesToNative(r, signature, curve->num_bytes); + uECC_vli_bytesToNative(s, signature + curve->num_bytes, curve->num_bytes); +#endif + + /* r, s must not be 0. */ + if (uECC_vli_isZero(r, num_words) || uECC_vli_isZero(s, num_words)) { + return 0; + } + + /* r, s must be < n. */ + if (uECC_vli_cmp_unsafe(curve->n, r, num_n_words) != 1 || + uECC_vli_cmp_unsafe(curve->n, s, num_n_words) != 1) { + return 0; + } + + /* Calculate u1 and u2. */ + uECC_vli_modInv(z, s, curve->n, num_n_words); /* z = 1/s */ + u1[num_n_words - 1] = 0; + bits2int(u1, message_hash, hash_size, curve); + uECC_vli_modMult(u1, u1, z, curve->n, num_n_words); /* u1 = e/s */ + uECC_vli_modMult(u2, r, z, curve->n, num_n_words); /* u2 = r/s */ + + /* Calculate sum = G + Q. */ + uECC_vli_set(sum, _public, num_words); + uECC_vli_set(sum + num_words, _public + num_words, num_words); + uECC_vli_set(tx, curve->G, num_words); + uECC_vli_set(ty, curve->G + num_words, num_words); + uECC_vli_modSub(z, sum, tx, curve->p, num_words); /* z = x2 - x1 */ + XYcZ_add(tx, ty, sum, sum + num_words, curve); + uECC_vli_modInv(z, z, curve->p, num_words); /* z = 1/z */ + apply_z(sum, sum + num_words, z, curve); + + /* Use Shamir's trick to calculate u1*G + u2*Q */ + points[0] = 0; + points[1] = curve->G; + points[2] = _public; + points[3] = sum; + num_bits = smax(uECC_vli_numBits(u1, num_n_words), + uECC_vli_numBits(u2, num_n_words)); + + point = points[(!!uECC_vli_testBit(u1, num_bits - 1)) | + ((!!uECC_vli_testBit(u2, num_bits - 1)) << 1)]; + uECC_vli_set(rx, point, num_words); + uECC_vli_set(ry, point + num_words, num_words); + uECC_vli_clear(z, num_words); + z[0] = 1; + + for (i = num_bits - 2; i >= 0; --i) { + uECC_word_t index; + curve->double_jacobian(rx, ry, z, curve); + + index = (!!uECC_vli_testBit(u1, i)) | ((!!uECC_vli_testBit(u2, i)) << 1); + point = points[index]; + if (point) { + uECC_vli_set(tx, point, num_words); + uECC_vli_set(ty, point + num_words, num_words); + apply_z(tx, ty, z, curve); + uECC_vli_modSub(tz, rx, tx, curve->p, num_words); /* Z = x2 - x1 */ + XYcZ_add(tx, ty, rx, ry, curve); + uECC_vli_modMult_fast(z, z, tz, curve); + } + } + + uECC_vli_modInv(z, z, curve->p, num_words); /* Z = 1/Z */ + apply_z(rx, ry, z, curve); + + /* v = x1 (mod n) */ + if (uECC_vli_cmp_unsafe(curve->n, rx, num_n_words) != 1) { + uECC_vli_sub(rx, rx, curve->n, num_n_words); + } + + /* Accept only if v == r. */ + return (int)(uECC_vli_equal(rx, r, num_words)); +} + +#if uECC_ENABLE_VLI_API + +unsigned uECC_curve_num_words(uECC_Curve curve) { + return curve->num_words; +} + +unsigned uECC_curve_num_bytes(uECC_Curve curve) { + return curve->num_bytes; +} + +unsigned uECC_curve_num_bits(uECC_Curve curve) { + return curve->num_bytes * 8; +} + +unsigned uECC_curve_num_n_words(uECC_Curve curve) { + return BITS_TO_WORDS(curve->num_n_bits); +} + +unsigned uECC_curve_num_n_bytes(uECC_Curve curve) { + return BITS_TO_BYTES(curve->num_n_bits); +} + +unsigned uECC_curve_num_n_bits(uECC_Curve curve) { + return curve->num_n_bits; +} + +const uECC_word_t *uECC_curve_p(uECC_Curve curve) { + return curve->p; +} + +const uECC_word_t *uECC_curve_n(uECC_Curve curve) { + return curve->n; +} + +const uECC_word_t *uECC_curve_G(uECC_Curve curve) { + return curve->G; +} + +const uECC_word_t *uECC_curve_b(uECC_Curve curve) { + return curve->b; +} + +#if uECC_SUPPORT_COMPRESSED_POINT +void uECC_vli_mod_sqrt(uECC_word_t *a, uECC_Curve curve) { + curve->mod_sqrt(a, curve); +} +#endif + +void uECC_vli_mmod_fast(uECC_word_t *result, uECC_word_t *product, uECC_Curve curve) { +#if (uECC_OPTIMIZATION_LEVEL > 0) + curve->mmod_fast(result, product); +#else + uECC_vli_mmod(result, product, curve->p, curve->num_words); +#endif +} + +void uECC_point_mult(uECC_word_t *result, + const uECC_word_t *point, + const uECC_word_t *scalar, + uECC_Curve curve) { + uECC_word_t tmp1[uECC_MAX_WORDS]; + uECC_word_t tmp2[uECC_MAX_WORDS]; + uECC_word_t *p2[2] = {tmp1, tmp2}; + uECC_word_t carry = regularize_k(scalar, tmp1, tmp2, curve); + + EccPoint_mult(result, point, p2[!carry], 0, curve->num_n_bits + 1, curve); +} + +#endif /* uECC_ENABLE_VLI_API */ diff --git a/web/server/h2o/libh2o/deps/picotls/deps/micro-ecc/uECC.h b/web/server/h2o/libh2o/deps/picotls/deps/micro-ecc/uECC.h new file mode 100644 index 00000000..99117631 --- /dev/null +++ b/web/server/h2o/libh2o/deps/picotls/deps/micro-ecc/uECC.h @@ -0,0 +1,362 @@ +/* Copyright 2014, Kenneth MacKay. Licensed under the BSD 2-clause license. */ + +#ifndef _UECC_H_ +#define _UECC_H_ + +#include + +/* Platform selection options. +If uECC_PLATFORM is not defined, the code will try to guess it based on compiler macros. +Possible values for uECC_PLATFORM are defined below: */ +#define uECC_arch_other 0 +#define uECC_x86 1 +#define uECC_x86_64 2 +#define uECC_arm 3 +#define uECC_arm_thumb 4 +#define uECC_arm_thumb2 5 +#define uECC_arm64 6 +#define uECC_avr 7 + +/* If desired, you can define uECC_WORD_SIZE as appropriate for your platform (1, 4, or 8 bytes). +If uECC_WORD_SIZE is not explicitly defined then it will be automatically set based on your +platform. */ + +/* Optimization level; trade speed for code size. + Larger values produce code that is faster but larger. + Currently supported values are 0 - 4; 0 is unusably slow for most applications. + Optimization level 4 currently only has an effect ARM platforms where more than one + curve is enabled. */ +#ifndef uECC_OPTIMIZATION_LEVEL + #define uECC_OPTIMIZATION_LEVEL 2 +#endif + +/* uECC_SQUARE_FUNC - If enabled (defined as nonzero), this will cause a specific function to be +used for (scalar) squaring instead of the generic multiplication function. This can make things +faster somewhat faster, but increases the code size. */ +#ifndef uECC_SQUARE_FUNC + #define uECC_SQUARE_FUNC 0 +#endif + +/* uECC_VLI_NATIVE_LITTLE_ENDIAN - If enabled (defined as nonzero), this will switch to native +little-endian format for *all* arrays passed in and out of the public API. This includes public +and private keys, shared secrets, signatures and message hashes. +Using this switch reduces the amount of call stack memory used by uECC, since less intermediate +translations are required. +Note that this will *only* work on native little-endian processors and it will treat the uint8_t +arrays passed into the public API as word arrays, therefore requiring the provided byte arrays +to be word aligned on architectures that do not support unaligned accesses. */ +#ifndef uECC_VLI_NATIVE_LITTLE_ENDIAN + #define uECC_VLI_NATIVE_LITTLE_ENDIAN 0 +#endif + +/* Curve support selection. Set to 0 to remove that curve. */ +#ifndef uECC_SUPPORTS_secp160r1 + #define uECC_SUPPORTS_secp160r1 1 +#endif +#ifndef uECC_SUPPORTS_secp192r1 + #define uECC_SUPPORTS_secp192r1 1 +#endif +#ifndef uECC_SUPPORTS_secp224r1 + #define uECC_SUPPORTS_secp224r1 1 +#endif +#ifndef uECC_SUPPORTS_secp256r1 + #define uECC_SUPPORTS_secp256r1 1 +#endif +#ifndef uECC_SUPPORTS_secp256k1 + #define uECC_SUPPORTS_secp256k1 1 +#endif + +/* Specifies whether compressed point format is supported. + Set to 0 to disable point compression/decompression functions. */ +#ifndef uECC_SUPPORT_COMPRESSED_POINT + #define uECC_SUPPORT_COMPRESSED_POINT 1 +#endif + +struct uECC_Curve_t; +typedef const struct uECC_Curve_t * uECC_Curve; + +#ifdef __cplusplus +extern "C" +{ +#endif + +#if uECC_SUPPORTS_secp160r1 +uECC_Curve uECC_secp160r1(void); +#endif +#if uECC_SUPPORTS_secp192r1 +uECC_Curve uECC_secp192r1(void); +#endif +#if uECC_SUPPORTS_secp224r1 +uECC_Curve uECC_secp224r1(void); +#endif +#if uECC_SUPPORTS_secp256r1 +uECC_Curve uECC_secp256r1(void); +#endif +#if uECC_SUPPORTS_secp256k1 +uECC_Curve uECC_secp256k1(void); +#endif + +/* uECC_RNG_Function type +The RNG function should fill 'size' random bytes into 'dest'. It should return 1 if +'dest' was filled with random data, or 0 if the random data could not be generated. +The filled-in values should be either truly random, or from a cryptographically-secure PRNG. + +A correctly functioning RNG function must be set (using uECC_set_rng()) before calling +uECC_make_key() or uECC_sign(). + +Setting a correctly functioning RNG function improves the resistance to side-channel attacks +for uECC_shared_secret() and uECC_sign_deterministic(). + +A correct RNG function is set by default when building for Windows, Linux, or OS X. +If you are building on another POSIX-compliant system that supports /dev/random or /dev/urandom, +you can define uECC_POSIX to use the predefined RNG. For embedded platforms there is no predefined +RNG function; you must provide your own. +*/ +typedef int (*uECC_RNG_Function)(uint8_t *dest, unsigned size); + +/* uECC_set_rng() function. +Set the function that will be used to generate random bytes. The RNG function should +return 1 if the random data was generated, or 0 if the random data could not be generated. + +On platforms where there is no predefined RNG function (eg embedded platforms), this must +be called before uECC_make_key() or uECC_sign() are used. + +Inputs: + rng_function - The function that will be used to generate random bytes. +*/ +void uECC_set_rng(uECC_RNG_Function rng_function); + +/* uECC_get_rng() function. + +Returns the function that will be used to generate random bytes. +*/ +uECC_RNG_Function uECC_get_rng(void); + +/* uECC_curve_private_key_size() function. + +Returns the size of a private key for the curve in bytes. +*/ +int uECC_curve_private_key_size(uECC_Curve curve); + +/* uECC_curve_public_key_size() function. + +Returns the size of a public key for the curve in bytes. +*/ +int uECC_curve_public_key_size(uECC_Curve curve); + +/* uECC_make_key() function. +Create a public/private key pair. + +Outputs: + public_key - Will be filled in with the public key. Must be at least 2 * the curve size + (in bytes) long. For example, if the curve is secp256r1, public_key must be 64 + bytes long. + private_key - Will be filled in with the private key. Must be as long as the curve order; this + is typically the same as the curve size, except for secp160r1. For example, if the + curve is secp256r1, private_key must be 32 bytes long. + + For secp160r1, private_key must be 21 bytes long! Note that the first byte will + almost always be 0 (there is about a 1 in 2^80 chance of it being non-zero). + +Returns 1 if the key pair was generated successfully, 0 if an error occurred. +*/ +int uECC_make_key(uint8_t *public_key, uint8_t *private_key, uECC_Curve curve); + +/* uECC_shared_secret() function. +Compute a shared secret given your secret key and someone else's public key. +Note: It is recommended that you hash the result of uECC_shared_secret() before using it for +symmetric encryption or HMAC. + +Inputs: + public_key - The public key of the remote party. + private_key - Your private key. + +Outputs: + secret - Will be filled in with the shared secret value. Must be the same size as the + curve size; for example, if the curve is secp256r1, secret must be 32 bytes long. + +Returns 1 if the shared secret was generated successfully, 0 if an error occurred. +*/ +int uECC_shared_secret(const uint8_t *public_key, + const uint8_t *private_key, + uint8_t *secret, + uECC_Curve curve); + +#if uECC_SUPPORT_COMPRESSED_POINT +/* uECC_compress() function. +Compress a public key. + +Inputs: + public_key - The public key to compress. + +Outputs: + compressed - Will be filled in with the compressed public key. Must be at least + (curve size + 1) bytes long; for example, if the curve is secp256r1, + compressed must be 33 bytes long. +*/ +void uECC_compress(const uint8_t *public_key, uint8_t *compressed, uECC_Curve curve); + +/* uECC_decompress() function. +Decompress a compressed public key. + +Inputs: + compressed - The compressed public key. + +Outputs: + public_key - Will be filled in with the decompressed public key. +*/ +void uECC_decompress(const uint8_t *compressed, uint8_t *public_key, uECC_Curve curve); +#endif /* uECC_SUPPORT_COMPRESSED_POINT */ + +/* uECC_valid_public_key() function. +Check to see if a public key is valid. + +Note that you are not required to check for a valid public key before using any other uECC +functions. However, you may wish to avoid spending CPU time computing a shared secret or +verifying a signature using an invalid public key. + +Inputs: + public_key - The public key to check. + +Returns 1 if the public key is valid, 0 if it is invalid. +*/ +int uECC_valid_public_key(const uint8_t *public_key, uECC_Curve curve); + +/* uECC_compute_public_key() function. +Compute the corresponding public key for a private key. + +Inputs: + private_key - The private key to compute the public key for + +Outputs: + public_key - Will be filled in with the corresponding public key + +Returns 1 if the key was computed successfully, 0 if an error occurred. +*/ +int uECC_compute_public_key(const uint8_t *private_key, uint8_t *public_key, uECC_Curve curve); + +/* uECC_sign() function. +Generate an ECDSA signature for a given hash value. + +Usage: Compute a hash of the data you wish to sign (SHA-2 is recommended) and pass it in to +this function along with your private key. + +Inputs: + private_key - Your private key. + message_hash - The hash of the message to sign. + hash_size - The size of message_hash in bytes. + +Outputs: + signature - Will be filled in with the signature value. Must be at least 2 * curve size long. + For example, if the curve is secp256r1, signature must be 64 bytes long. + +Returns 1 if the signature generated successfully, 0 if an error occurred. +*/ +int uECC_sign(const uint8_t *private_key, + const uint8_t *message_hash, + unsigned hash_size, + uint8_t *signature, + uECC_Curve curve); + +/* uECC_HashContext structure. +This is used to pass in an arbitrary hash function to uECC_sign_deterministic(). +The structure will be used for multiple hash computations; each time a new hash +is computed, init_hash() will be called, followed by one or more calls to +update_hash(), and finally a call to finish_hash() to produce the resulting hash. + +The intention is that you will create a structure that includes uECC_HashContext +followed by any hash-specific data. For example: + +typedef struct SHA256_HashContext { + uECC_HashContext uECC; + SHA256_CTX ctx; +} SHA256_HashContext; + +void init_SHA256(uECC_HashContext *base) { + SHA256_HashContext *context = (SHA256_HashContext *)base; + SHA256_Init(&context->ctx); +} + +void update_SHA256(uECC_HashContext *base, + const uint8_t *message, + unsigned message_size) { + SHA256_HashContext *context = (SHA256_HashContext *)base; + SHA256_Update(&context->ctx, message, message_size); +} + +void finish_SHA256(uECC_HashContext *base, uint8_t *hash_result) { + SHA256_HashContext *context = (SHA256_HashContext *)base; + SHA256_Final(hash_result, &context->ctx); +} + +... when signing ... +{ + uint8_t tmp[32 + 32 + 64]; + SHA256_HashContext ctx = {{&init_SHA256, &update_SHA256, &finish_SHA256, 64, 32, tmp}}; + uECC_sign_deterministic(key, message_hash, &ctx.uECC, signature); +} +*/ +typedef struct uECC_HashContext { + void (*init_hash)(const struct uECC_HashContext *context); + void (*update_hash)(const struct uECC_HashContext *context, + const uint8_t *message, + unsigned message_size); + void (*finish_hash)(const struct uECC_HashContext *context, uint8_t *hash_result); + unsigned block_size; /* Hash function block size in bytes, eg 64 for SHA-256. */ + unsigned result_size; /* Hash function result size in bytes, eg 32 for SHA-256. */ + uint8_t *tmp; /* Must point to a buffer of at least (2 * result_size + block_size) bytes. */ +} uECC_HashContext; + +/* uECC_sign_deterministic() function. +Generate an ECDSA signature for a given hash value, using a deterministic algorithm +(see RFC 6979). You do not need to set the RNG using uECC_set_rng() before calling +this function; however, if the RNG is defined it will improve resistance to side-channel +attacks. + +Usage: Compute a hash of the data you wish to sign (SHA-2 is recommended) and pass it to +this function along with your private key and a hash context. Note that the message_hash +does not need to be computed with the same hash function used by hash_context. + +Inputs: + private_key - Your private key. + message_hash - The hash of the message to sign. + hash_size - The size of message_hash in bytes. + hash_context - A hash context to use. + +Outputs: + signature - Will be filled in with the signature value. + +Returns 1 if the signature generated successfully, 0 if an error occurred. +*/ +int uECC_sign_deterministic(const uint8_t *private_key, + const uint8_t *message_hash, + unsigned hash_size, + const uECC_HashContext *hash_context, + uint8_t *signature, + uECC_Curve curve); + +/* uECC_verify() function. +Verify an ECDSA signature. + +Usage: Compute the hash of the signed data using the same hash as the signer and +pass it to this function along with the signer's public key and the signature values (r and s). + +Inputs: + public_key - The signer's public key. + message_hash - The hash of the signed data. + hash_size - The size of message_hash in bytes. + signature - The signature value. + +Returns 1 if the signature is valid, 0 if it is invalid. +*/ +int uECC_verify(const uint8_t *public_key, + const uint8_t *message_hash, + unsigned hash_size, + const uint8_t *signature, + uECC_Curve curve); + +#ifdef __cplusplus +} /* end of extern "C" */ +#endif + +#endif /* _UECC_H_ */ diff --git a/web/server/h2o/libh2o/deps/picotls/deps/micro-ecc/uECC_vli.h b/web/server/h2o/libh2o/deps/picotls/deps/micro-ecc/uECC_vli.h new file mode 100644 index 00000000..864cc333 --- /dev/null +++ b/web/server/h2o/libh2o/deps/picotls/deps/micro-ecc/uECC_vli.h @@ -0,0 +1,172 @@ +/* Copyright 2015, Kenneth MacKay. Licensed under the BSD 2-clause license. */ + +#ifndef _UECC_VLI_H_ +#define _UECC_VLI_H_ + +#include "uECC.h" +#include "types.h" + +/* Functions for raw large-integer manipulation. These are only available + if uECC.c is compiled with uECC_ENABLE_VLI_API defined to 1. */ +#ifndef uECC_ENABLE_VLI_API + #define uECC_ENABLE_VLI_API 0 +#endif + +#ifdef __cplusplus +extern "C" +{ +#endif + +#if uECC_ENABLE_VLI_API + +void uECC_vli_clear(uECC_word_t *vli, wordcount_t num_words); + +/* Constant-time comparison to zero - secure way to compare long integers */ +/* Returns 1 if vli == 0, 0 otherwise. */ +uECC_word_t uECC_vli_isZero(const uECC_word_t *vli, wordcount_t num_words); + +/* Returns nonzero if bit 'bit' of vli is set. */ +uECC_word_t uECC_vli_testBit(const uECC_word_t *vli, bitcount_t bit); + +/* Counts the number of bits required to represent vli. */ +bitcount_t uECC_vli_numBits(const uECC_word_t *vli, const wordcount_t max_words); + +/* Sets dest = src. */ +void uECC_vli_set(uECC_word_t *dest, const uECC_word_t *src, wordcount_t num_words); + +/* Constant-time comparison function - secure way to compare long integers */ +/* Returns one if left == right, zero otherwise */ +uECC_word_t uECC_vli_equal(const uECC_word_t *left, + const uECC_word_t *right, + wordcount_t num_words); + +/* Constant-time comparison function - secure way to compare long integers */ +/* Returns sign of left - right, in constant time. */ +cmpresult_t uECC_vli_cmp(const uECC_word_t *left, const uECC_word_t *right, wordcount_t num_words); + +/* Computes vli = vli >> 1. */ +void uECC_vli_rshift1(uECC_word_t *vli, wordcount_t num_words); + +/* Computes result = left + right, returning carry. Can modify in place. */ +uECC_word_t uECC_vli_add(uECC_word_t *result, + const uECC_word_t *left, + const uECC_word_t *right, + wordcount_t num_words); + +/* Computes result = left - right, returning borrow. Can modify in place. */ +uECC_word_t uECC_vli_sub(uECC_word_t *result, + const uECC_word_t *left, + const uECC_word_t *right, + wordcount_t num_words); + +/* Computes result = left * right. Result must be 2 * num_words long. */ +void uECC_vli_mult(uECC_word_t *result, + const uECC_word_t *left, + const uECC_word_t *right, + wordcount_t num_words); + +/* Computes result = left^2. Result must be 2 * num_words long. */ +void uECC_vli_square(uECC_word_t *result, const uECC_word_t *left, wordcount_t num_words); + +/* Computes result = (left + right) % mod. + Assumes that left < mod and right < mod, and that result does not overlap mod. */ +void uECC_vli_modAdd(uECC_word_t *result, + const uECC_word_t *left, + const uECC_word_t *right, + const uECC_word_t *mod, + wordcount_t num_words); + +/* Computes result = (left - right) % mod. + Assumes that left < mod and right < mod, and that result does not overlap mod. */ +void uECC_vli_modSub(uECC_word_t *result, + const uECC_word_t *left, + const uECC_word_t *right, + const uECC_word_t *mod, + wordcount_t num_words); + +/* Computes result = product % mod, where product is 2N words long. + Currently only designed to work for mod == curve->p or curve_n. */ +void uECC_vli_mmod(uECC_word_t *result, + uECC_word_t *product, + const uECC_word_t *mod, + wordcount_t num_words); + +/* Calculates result = product (mod curve->p), where product is up to + 2 * curve->num_words long. */ +void uECC_vli_mmod_fast(uECC_word_t *result, uECC_word_t *product, uECC_Curve curve); + +/* Computes result = (left * right) % mod. + Currently only designed to work for mod == curve->p or curve_n. */ +void uECC_vli_modMult(uECC_word_t *result, + const uECC_word_t *left, + const uECC_word_t *right, + const uECC_word_t *mod, + wordcount_t num_words); + +/* Computes result = (left * right) % curve->p. */ +void uECC_vli_modMult_fast(uECC_word_t *result, + const uECC_word_t *left, + const uECC_word_t *right, + uECC_Curve curve); + +/* Computes result = left^2 % mod. + Currently only designed to work for mod == curve->p or curve_n. */ +void uECC_vli_modSquare(uECC_word_t *result, + const uECC_word_t *left, + const uECC_word_t *mod, + wordcount_t num_words); + +/* Computes result = left^2 % curve->p. */ +void uECC_vli_modSquare_fast(uECC_word_t *result, const uECC_word_t *left, uECC_Curve curve); + +/* Computes result = (1 / input) % mod.*/ +void uECC_vli_modInv(uECC_word_t *result, + const uECC_word_t *input, + const uECC_word_t *mod, + wordcount_t num_words); + +#if uECC_SUPPORT_COMPRESSED_POINT +/* Calculates a = sqrt(a) (mod curve->p) */ +void uECC_vli_mod_sqrt(uECC_word_t *a, uECC_Curve curve); +#endif + +/* Converts an integer in uECC native format to big-endian bytes. */ +void uECC_vli_nativeToBytes(uint8_t *bytes, int num_bytes, const uECC_word_t *native); +/* Converts big-endian bytes to an integer in uECC native format. */ +void uECC_vli_bytesToNative(uECC_word_t *native, const uint8_t *bytes, int num_bytes); + +unsigned uECC_curve_num_words(uECC_Curve curve); +unsigned uECC_curve_num_bytes(uECC_Curve curve); +unsigned uECC_curve_num_bits(uECC_Curve curve); +unsigned uECC_curve_num_n_words(uECC_Curve curve); +unsigned uECC_curve_num_n_bytes(uECC_Curve curve); +unsigned uECC_curve_num_n_bits(uECC_Curve curve); + +const uECC_word_t *uECC_curve_p(uECC_Curve curve); +const uECC_word_t *uECC_curve_n(uECC_Curve curve); +const uECC_word_t *uECC_curve_G(uECC_Curve curve); +const uECC_word_t *uECC_curve_b(uECC_Curve curve); + +int uECC_valid_point(const uECC_word_t *point, uECC_Curve curve); + +/* Multiplies a point by a scalar. Points are represented by the X coordinate followed by + the Y coordinate in the same array, both coordinates are curve->num_words long. Note + that scalar must be curve->num_n_words long (NOT curve->num_words). */ +void uECC_point_mult(uECC_word_t *result, + const uECC_word_t *point, + const uECC_word_t *scalar, + uECC_Curve curve); + +/* Generates a random integer in the range 0 < random < top. + Both random and top have num_words words. */ +int uECC_generate_random_int(uECC_word_t *random, + const uECC_word_t *top, + wordcount_t num_words); + +#endif /* uECC_ENABLE_VLI_API */ + +#ifdef __cplusplus +} /* end of extern "C" */ +#endif + +#endif /* _UECC_VLI_H_ */ diff --git a/web/server/h2o/libh2o/deps/picotls/include/picotls.h b/web/server/h2o/libh2o/deps/picotls/include/picotls.h new file mode 100644 index 00000000..a862075f --- /dev/null +++ b/web/server/h2o/libh2o/deps/picotls/include/picotls.h @@ -0,0 +1,998 @@ +/* + * Copyright (c) 2016 DeNA Co., Ltd., Kazuho Oku + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ +#ifndef picotls_h +#define picotls_h + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include +#include + +#define PTLS_AES128_KEY_SIZE 16 +#define PTLS_AES256_KEY_SIZE 32 +#define PTLS_AES_IV_SIZE 16 +#define PTLS_AESGCM_IV_SIZE 12 +#define PTLS_AESGCM_TAG_SIZE 16 + +#define PTLS_CHACHA20_KEY_SIZE 32 +#define PTLS_CHACHA20_IV_SIZE 16 +#define PTLS_CHACHA20POLY1305_IV_SIZE 12 +#define PTLS_CHACHA20POLY1305_TAG_SIZE 16 + +#define PTLS_SHA256_BLOCK_SIZE 64 +#define PTLS_SHA256_DIGEST_SIZE 32 + +#define PTLS_SHA384_BLOCK_SIZE 128 +#define PTLS_SHA384_DIGEST_SIZE 48 + +#define PTLS_MAX_SECRET_SIZE 32 +#define PTLS_MAX_IV_SIZE 16 +#define PTLS_MAX_DIGEST_SIZE 64 + +/* cipher-suites */ +#define PTLS_CIPHER_SUITE_AES_128_GCM_SHA256 0x1301 +#define PTLS_CIPHER_SUITE_AES_256_GCM_SHA384 0x1302 +#define PTLS_CIPHER_SUITE_CHACHA20_POLY1305_SHA256 0x1303 + +/* negotiated_groups */ +#define PTLS_GROUP_SECP256R1 23 +#define PTLS_GROUP_X25519 29 + +/* signature algorithms */ +#define PTLS_SIGNATURE_RSA_PKCS1_SHA1 0x0201 +#define PTLS_SIGNATURE_RSA_PKCS1_SHA256 0x0401 +#define PTLS_SIGNATURE_ECDSA_SECP256R1_SHA256 0x0403 +#define PTLS_SIGNATURE_ECDSA_SECP384R1_SHA384 0x0503 +#define PTLS_SIGNATURE_ECDSA_SECP521R1_SHA512 0x0603 +#define PTLS_SIGNATURE_RSA_PSS_RSAE_SHA256 0x0804 +#define PTLS_SIGNATURE_RSA_PSS_RSAE_SHA384 0x0805 +#define PTLS_SIGNATURE_RSA_PSS_RSAE_SHA512 0x0806 + +/* error classes and macros */ +#define PTLS_ERROR_CLASS_SELF_ALERT 0 +#define PTLS_ERROR_CLASS_PEER_ALERT 0x100 +#define PTLS_ERROR_CLASS_INTERNAL 0x200 + +#define PTLS_ERROR_GET_CLASS(e) ((e) & ~0xff) +#define PTLS_ALERT_TO_SELF_ERROR(e) ((e) + PTLS_ERROR_CLASS_SELF_ALERT) +#define PTLS_ALERT_TO_PEER_ERROR(e) ((e) + PTLS_ERROR_CLASS_PEER_ALERT) +#define PTLS_ERROR_TO_ALERT(e) ((e)&0xff) + +/* alerts */ +#define PTLS_ALERT_LEVEL_WARNING 1 +#define PTLS_ALERT_LEVEL_FATAL 2 + +#define PTLS_ALERT_CLOSE_NOTIFY 0 +#define PTLS_ALERT_UNEXPECTED_MESSAGE 10 +#define PTLS_ALERT_BAD_RECORD_MAC 20 +#define PTLS_ALERT_HANDSHAKE_FAILURE 40 +#define PTLS_ALERT_BAD_CERTIFICATE 42 +#define PTLS_ALERT_CERTIFICATE_REVOKED 44 +#define PTLS_ALERT_CERTIFICATE_EXPIRED 45 +#define PTLS_ALERT_CERTIFICATE_UNKNOWN 46 +#define PTLS_ALERT_ILLEGAL_PARAMETER 47 +#define PTLS_ALERT_DECODE_ERROR 50 +#define PTLS_ALERT_DECRYPT_ERROR 51 +#define PTLS_ALERT_PROTOCOL_VERSION 70 +#define PTLS_ALERT_INTERNAL_ERROR 80 +#define PTLS_ALERT_USER_CANCELED 90 +#define PTLS_ALERT_MISSING_EXTENSION 109 +#define PTLS_ALERT_UNRECOGNIZED_NAME 112 +#define PTLS_ALERT_NO_APPLICATION_PROTOCOL 120 + +/* internal errors */ +#define PTLS_ERROR_NO_MEMORY (PTLS_ERROR_CLASS_INTERNAL + 1) +#define PTLS_ERROR_IN_PROGRESS (PTLS_ERROR_CLASS_INTERNAL + 2) +#define PTLS_ERROR_LIBRARY (PTLS_ERROR_CLASS_INTERNAL + 3) +#define PTLS_ERROR_INCOMPATIBLE_KEY (PTLS_ERROR_CLASS_INTERNAL + 4) +#define PTLS_ERROR_SESSION_NOT_FOUND (PTLS_ERROR_CLASS_INTERNAL + 5) +#define PTLS_ERROR_STATELESS_RETRY (PTLS_ERROR_CLASS_INTERNAL + 6) + +#define PTLS_ERROR_INCORRECT_BASE64 (PTLS_ERROR_CLASS_INTERNAL + 50) +#define PTLS_ERROR_PEM_LABEL_NOT_FOUND (PTLS_ERROR_CLASS_INTERNAL + 51) +#define PTLS_ERROR_BER_INCORRECT_ENCODING (PTLS_ERROR_CLASS_INTERNAL + 52) +#define PTLS_ERROR_BER_MALFORMED_TYPE (PTLS_ERROR_CLASS_INTERNAL + 53) +#define PTLS_ERROR_BER_MALFORMED_LENGTH (PTLS_ERROR_CLASS_INTERNAL + 54) +#define PTLS_ERROR_BER_EXCESSIVE_LENGTH (PTLS_ERROR_CLASS_INTERNAL + 55) +#define PTLS_ERROR_BER_ELEMENT_TOO_SHORT (PTLS_ERROR_CLASS_INTERNAL + 56) +#define PTLS_ERROR_BER_UNEXPECTED_EOC (PTLS_ERROR_CLASS_INTERNAL + 57) +#define PTLS_ERROR_DER_INDEFINITE_LENGTH (PTLS_ERROR_CLASS_INTERNAL + 58) +#define PTLS_ERROR_INCORRECT_ASN1_SYNTAX (PTLS_ERROR_CLASS_INTERNAL + 59) +#define PTLS_ERROR_INCORRECT_PEM_KEY_VERSION (PTLS_ERROR_CLASS_INTERNAL + 60) +#define PTLS_ERROR_INCORRECT_PEM_ECDSA_KEY_VERSION (PTLS_ERROR_CLASS_INTERNAL + 61) +#define PTLS_ERROR_INCORRECT_PEM_ECDSA_CURVE (PTLS_ERROR_CLASS_INTERNAL + 62) +#define PTLS_ERROR_INCORRECT_PEM_ECDSA_KEYSIZE (PTLS_ERROR_CLASS_INTERNAL + 63) +#define PTLS_ERROR_INCORRECT_ASN1_ECDSA_KEY_SYNTAX (PTLS_ERROR_CLASS_INTERNAL + 64) + +#define PTLS_ZERO_DIGEST_SHA256 \ + { \ + 0xe3, 0xb0, 0xc4, 0x42, 0x98, 0xfc, 0x1c, 0x14, 0x9a, 0xfb, 0xf4, 0xc8, 0x99, 0x6f, 0xb9, 0x24, 0x27, 0xae, 0x41, 0xe4, \ + 0x64, 0x9b, 0x93, 0x4c, 0xa4, 0x95, 0x99, 0x1b, 0x78, 0x52, 0xb8, 0x55 \ + } + +#define PTLS_ZERO_DIGEST_SHA384 \ + { \ + 0x38, 0xb0, 0x60, 0xa7, 0x51, 0xac, 0x96, 0x38, 0x4c, 0xd9, 0x32, 0x7e, 0xb1, 0xb1, 0xe3, 0x6a, 0x21, 0xfd, 0xb7, 0x11, \ + 0x14, 0xbe, 0x07, 0x43, 0x4c, 0x0c, 0xc7, 0xbf, 0x63, 0xf6, 0xe1, 0xda, 0x27, 0x4e, 0xde, 0xbf, 0xe7, 0x6f, 0x65, \ + 0xfb, 0xd5, 0x1a, 0xd2, 0xf1, 0x48, 0x98, 0xb9, 0x5b \ + } + +typedef struct st_ptls_t ptls_t; +typedef struct st_ptls_context_t ptls_context_t; + +/** + * represents a sequence of octets + */ +typedef struct st_ptls_iovec_t { + uint8_t *base; + size_t len; +} ptls_iovec_t; + +/** + * used for storing output + */ +typedef struct st_ptls_buffer_t { + uint8_t *base; + size_t capacity; + size_t off; + int is_allocated; +} ptls_buffer_t; + +/** + * key exchange context built by ptls_key_exchange_algorithm::create. + */ +typedef struct st_ptls_key_exchange_context_t { + /** + * called once per created context. Callee must free resources allocated to the context and set *keyex to NULL. Secret and + * peerkey will be NULL in case the exchange never happened. + */ + int (*on_exchange)(struct st_ptls_key_exchange_context_t **keyex, ptls_iovec_t *secret, ptls_iovec_t peerkey); +} ptls_key_exchange_context_t; + +/** + * A key exchange algorithm. + */ +typedef const struct st_ptls_key_exchange_algorithm_t { + /** + * ID defined by the TLS specification + */ + uint16_t id; + /** + * creates a context for asynchronous key exchange. The function is called when ClientHello is generated. The on_exchange + * callback of the created context is called when the client receives ServerHello. + */ + int (*create)(ptls_key_exchange_context_t **ctx, ptls_iovec_t *pubkey); + /** + * implements synchronous key exchange. Called when receiving a ServerHello. + */ + int (*exchange)(ptls_iovec_t *pubkey, ptls_iovec_t *secret, ptls_iovec_t peerkey); +} ptls_key_exchange_algorithm_t; + +/** + * context of a symmetric cipher + */ +typedef struct st_ptls_cipher_context_t { + const struct st_ptls_cipher_algorithm_t *algo; + /* field above this line must not be altered by the crypto binding */ + void (*do_dispose)(struct st_ptls_cipher_context_t *ctx); + void (*do_init)(struct st_ptls_cipher_context_t *ctx, const void *iv); + void (*do_transform)(struct st_ptls_cipher_context_t *ctx, void *output, const void *input, size_t len); +} ptls_cipher_context_t; + +/** + * a symmetric cipher + */ +typedef const struct st_ptls_cipher_algorithm_t { + const char *name; + size_t key_size; + size_t iv_size; + size_t context_size; + int (*setup_crypto)(ptls_cipher_context_t *ctx, int is_enc, const void *key); +} ptls_cipher_algorithm_t; + +/** + * AEAD context. AEAD implementations are allowed to stuff data at the end of the struct. The size of the memory allocated for the + * struct is governed by ptls_aead_algorithm_t::context_size. + */ +typedef struct st_ptls_aead_context_t { + const struct st_ptls_aead_algorithm_t *algo; + uint8_t static_iv[PTLS_MAX_IV_SIZE]; + /* field above this line must not be altered by the crypto binding */ + void (*dispose_crypto)(struct st_ptls_aead_context_t *ctx); + void (*do_encrypt_init)(struct st_ptls_aead_context_t *ctx, const void *iv, const void *aad, size_t aadlen); + size_t (*do_encrypt_update)(struct st_ptls_aead_context_t *ctx, void *output, const void *input, size_t inlen); + size_t (*do_encrypt_final)(struct st_ptls_aead_context_t *ctx, void *output); + size_t (*do_decrypt)(struct st_ptls_aead_context_t *ctx, void *output, const void *input, size_t inlen, const void *iv, + const void *aad, size_t aadlen); +} ptls_aead_context_t; + +/** + * An AEAD cipher. + */ +typedef const struct st_ptls_aead_algorithm_t { + /** + * name (following the convention of `openssl ciphers -v ALL`) + */ + const char *name; + /** + * the underlying key stream + */ + ptls_cipher_algorithm_t *ctr_cipher; + /** + * key size + */ + size_t key_size; + /** + * size of the IV + */ + size_t iv_size; + /** + * size of the tag + */ + size_t tag_size; + /** + * size of memory allocated for ptls_aead_context_t. AEAD implementations can set this value to something greater than + * sizeof(ptls_aead_context_t) and stuff additional data at the bottom of the struct. + */ + size_t context_size; + /** + * callback that sets up the crypto + */ + int (*setup_crypto)(ptls_aead_context_t *ctx, int is_enc, const void *key); +} ptls_aead_algorithm_t; + +/** + * + */ +typedef enum en_ptls_hash_final_mode_t { + /** + * obtains the digest and frees the context + */ + PTLS_HASH_FINAL_MODE_FREE = 0, + /** + * obtains the digest and reset the context to initial state + */ + PTLS_HASH_FINAL_MODE_RESET = 1, + /** + * obtains the digest while leaving the context as-is + */ + PTLS_HASH_FINAL_MODE_SNAPSHOT = 2 +} ptls_hash_final_mode_t; + +/** + * A hash context. + */ +typedef struct st_ptls_hash_context_t { + /** + * feeds additional data into the hash context + */ + void (*update)(struct st_ptls_hash_context_t *ctx, const void *src, size_t len); + /** + * returns the digest and performs necessary operation specified by mode + */ + void (* final)(struct st_ptls_hash_context_t *ctx, void *md, ptls_hash_final_mode_t mode); + /** + * creates a copy of the hash context + */ + struct st_ptls_hash_context_t *(*clone_)(struct st_ptls_hash_context_t *src); +} ptls_hash_context_t; + +/** + * A hash algorithm and its properties. + */ +typedef const struct st_ptls_hash_algorithm_t { + /** + * block size + */ + size_t block_size; + /** + * digest size + */ + size_t digest_size; + /** + * constructor that creates the hash context + */ + ptls_hash_context_t *(*create)(void); + /** + * digest of zero-length octets + */ + uint8_t empty_digest[PTLS_MAX_DIGEST_SIZE]; +} ptls_hash_algorithm_t; + +typedef const struct st_ptls_cipher_suite_t { + uint16_t id; + ptls_aead_algorithm_t *aead; + ptls_hash_algorithm_t *hash; +} ptls_cipher_suite_t; + +#define PTLS_CALLBACK_TYPE0(ret, name) \ + typedef struct st_ptls_##name##_t { \ + ret (*cb)(struct st_ptls_##name##_t * self); \ + } ptls_##name##_t + +#define PTLS_CALLBACK_TYPE(ret, name, ...) \ + typedef struct st_ptls_##name##_t { \ + ret (*cb)(struct st_ptls_##name##_t * self, __VA_ARGS__); \ + } ptls_##name##_t + +/** + * returns current time in milliseconds (ptls_get_time can be used to return the physical time) + */ +PTLS_CALLBACK_TYPE0(uint64_t, get_time); +/** + * after receiving ClientHello, the core calls the optional callback to give a chance to the swap the context depending on the input + * values. The callback is required to call `ptls_set_server_name` if an SNI extension needs to be sent to the client. + */ +PTLS_CALLBACK_TYPE(int, on_client_hello, ptls_t *tls, ptls_iovec_t server_name, const ptls_iovec_t *negotiated_protocols, + size_t num_negotiated_protocols, const uint16_t *signature_algorithms, size_t num_signature_algorithms); +/** + * when generating Certificate, the core calls the callback to obtain the OCSP response for stapling. + */ +PTLS_CALLBACK_TYPE(int, staple_ocsp, ptls_t *tls, ptls_buffer_t *output, size_t cert_index); +/** + * when gerenating CertificateVerify, the core calls the callback to sign the handshake context using the certificate. + */ +PTLS_CALLBACK_TYPE(int, sign_certificate, ptls_t *tls, uint16_t *selected_algorithm, ptls_buffer_t *output, ptls_iovec_t input, + const uint16_t *algorithms, size_t num_algorithms); +/** + * after receiving Certificate, the core calls the callback to verify the certificate chain and to obtain a pointer to a + * callback that should be used for verifying CertificateVerify. If an error occurs between a successful return from this + * callback to the invocation of the verify_sign callback, verify_sign is called with both data and sign set to an empty buffer. + * The implementor of the callback should use that as the opportunity to free any temporary data allocated for the verify_sign + * callback. + */ +PTLS_CALLBACK_TYPE(int, verify_certificate, ptls_t *tls, + int (**verify_sign)(void *verify_ctx, ptls_iovec_t data, ptls_iovec_t sign), void **verify_data, + ptls_iovec_t *certs, size_t num_certs); +/** + * encrypt-and-signs (or verify-and-decrypts) a ticket (server-only) + */ +PTLS_CALLBACK_TYPE(int, encrypt_ticket, ptls_t *tls, int is_encrypt, ptls_buffer_t *dst, ptls_iovec_t src); +/** + * saves a ticket (client-only) + */ +PTLS_CALLBACK_TYPE(int, save_ticket, ptls_t *tls, ptls_iovec_t input); +/** + * secret logginng + */ +PTLS_CALLBACK_TYPE(void, log_secret, ptls_t *tls, const char *label, ptls_iovec_t secret); +/** + * reference counting + */ +PTLS_CALLBACK_TYPE(void, update_open_count, ssize_t delta); + +/** + * the configuration + */ +struct st_ptls_context_t { + /** + * PRNG to be used + */ + void (*random_bytes)(void *buf, size_t len); + /** + * + */ + ptls_get_time_t *get_time; + /** + * list of supported key-exchange algorithms terminated by NULL + */ + ptls_key_exchange_algorithm_t **key_exchanges; + /** + * list of supported cipher-suites terminated by NULL + */ + ptls_cipher_suite_t **cipher_suites; + /** + * list of certificates + */ + struct { + ptls_iovec_t *list; + size_t count; + } certificates; + /** + * + */ + ptls_on_client_hello_t *on_client_hello; + /** + * + */ + ptls_staple_ocsp_t *staple_ocsp; + /** + * + */ + ptls_sign_certificate_t *sign_certificate; + /** + * + */ + ptls_verify_certificate_t *verify_certificate; + /** + * lifetime of a session ticket (server-only) + */ + uint32_t ticket_lifetime; + /** + * maximum permitted size of early data (server-only) + */ + uint32_t max_early_data_size; + /** + * if set, psk handshakes use (ec)dhe + */ + unsigned require_dhe_on_psk : 1; + /** + * if exporter master secrets should be recorded + */ + unsigned use_exporter : 1; + /** + * if ChangeCipherSpec message should be sent during handshake + */ + unsigned send_change_cipher_spec : 1; + /** + * + */ + ptls_encrypt_ticket_t *encrypt_ticket; + /** + * + */ + ptls_save_ticket_t *save_ticket; + /** + * + */ + ptls_log_secret_t *log_secret; + /** + * + */ + ptls_update_open_count_t *update_open_count; +}; + +typedef struct st_ptls_raw_extension_t { + uint16_t type; + ptls_iovec_t data; +} ptls_raw_extension_t; + +/** + * optional arguments to client-driven handshake + */ +#ifdef _WINDOWS +/* suppress warning C4201: nonstandard extension used: nameless struct/union */ +#pragma warning(push) +#pragma warning(disable : 4201) +#endif +typedef struct st_ptls_handshake_properties_t { + union { + struct { + /** + * list of protocols offered through ALPN + */ + struct { + const ptls_iovec_t *list; + size_t count; + } negotiated_protocols; + /** + * session ticket sent to the application via save_ticket callback + */ + ptls_iovec_t session_ticket; + /** + * pointer to store the maximum size of early-data that can be sent immediately (if NULL, early data is not used) + */ + size_t *max_early_data_size; + /** + * + */ + unsigned early_data_accepted_by_peer : 1; + /** + * negotiate the key exchange method before sending key_share + */ + unsigned negotiate_before_key_exchange : 1; + } client; + struct { + /** + * psk binder being selected (len is set to zero if none) + */ + struct { + uint8_t base[PTLS_MAX_DIGEST_SIZE]; + size_t len; + } selected_psk_binder; + /** + * parameters related to use of the Cookie extension + */ + struct { + /** + * HMAC key to protect the integrity of the cookie. The key should be as long as the digest size of the first + * ciphersuite specified in ptls_context_t (i.e. the hash algorithm of the best ciphersuite that can be chosen). + */ + const void *key; + /** + * additional data to be used for verifying the cookie + */ + ptls_iovec_t additional_data; + } cookie; + /** + * if HRR should always be sent + */ + unsigned enforce_retry : 1; + /** + * if retry should be stateless (cookie.key MUST be set when this option is used) + */ + unsigned retry_uses_cookie : 1; + } server; + }; + /** + * an optional list of additional extensions to send either in CH or EE, terminated by type == UINT16_MAX + */ + ptls_raw_extension_t *additional_extensions; + /** + * an optional callback that returns a boolean value indicating if a particular extension should be collected + */ + int (*collect_extension)(ptls_t *tls, struct st_ptls_handshake_properties_t *properties, uint16_t type); + /** + * an optional callback that reports the extensions being collected + */ + int (*collected_extensions)(ptls_t *tls, struct st_ptls_handshake_properties_t *properties, ptls_raw_extension_t *extensions); +} ptls_handshake_properties_t; +#ifdef _WINDOWS +#pragma warning(pop) +#endif + +/** + * builds a new ptls_iovec_t instance using the supplied parameters + */ +static ptls_iovec_t ptls_iovec_init(const void *p, size_t len); +/** + * initializes a buffer, setting the default destination to the small buffer provided as the argument. + */ +static void ptls_buffer_init(ptls_buffer_t *buf, void *smallbuf, size_t smallbuf_size); +/** + * disposes a buffer, freeing resources allocated by the buffer itself (if any) + */ +static void ptls_buffer_dispose(ptls_buffer_t *buf); +/** + * internal + */ +void ptls_buffer__release_memory(ptls_buffer_t *buf); +/** + * reserves space for additional amount of memory + */ +int ptls_buffer_reserve(ptls_buffer_t *buf, size_t delta); +/** + * internal + */ +int ptls_buffer__do_pushv(ptls_buffer_t *buf, const void *src, size_t len); +/** + * internal + */ +int ptls_buffer__adjust_asn1_blocksize(ptls_buffer_t *buf, size_t body_size); +/** + * pushes an unsigned bigint + */ +int ptls_buffer_push_asn1_ubigint(ptls_buffer_t *buf, const void *bignum, size_t size); + +#define ptls_buffer_pushv(buf, src, len) \ + do { \ + if ((ret = ptls_buffer__do_pushv((buf), (src), (len))) != 0) \ + goto Exit; \ + } while (0) + +#define ptls_buffer_push(buf, ...) \ + do { \ + if ((ret = ptls_buffer__do_pushv((buf), (uint8_t[]){__VA_ARGS__}, sizeof((uint8_t[]){__VA_ARGS__}))) != 0) \ + goto Exit; \ + } while (0) + +#define ptls_buffer_push16(buf, v) \ + do { \ + uint16_t _v = (v); \ + ptls_buffer_push(buf, (uint8_t)(_v >> 8), (uint8_t)_v); \ + } while (0) + +#define ptls_buffer_push32(buf, v) \ + do { \ + uint32_t _v = (v); \ + ptls_buffer_push(buf, (uint8_t)(_v >> 24), (uint8_t)(_v >> 16), (uint8_t)(_v >> 8), (uint8_t)_v); \ + } while (0) + +#define ptls_buffer_push64(buf, v) \ + do { \ + uint64_t _v = (v); \ + ptls_buffer_push(buf, (uint8_t)(_v >> 56), (uint8_t)(_v >> 48), (uint8_t)(_v >> 40), (uint8_t)(_v >> 32), \ + (uint8_t)(_v >> 24), (uint8_t)(_v >> 16), (uint8_t)(_v >> 8), (uint8_t)_v); \ + } while (0) + +#define ptls_buffer_push_block(buf, _capacity, block) \ + do { \ + size_t capacity = (_capacity); \ + ptls_buffer_pushv((buf), (uint8_t *)"\0\0\0\0\0\0\0", capacity); \ + size_t body_start = (buf)->off; \ + do { \ + block \ + } while (0); \ + size_t body_size = (buf)->off - body_start; \ + for (; capacity != 0; --capacity) \ + (buf)->base[body_start - capacity] = (uint8_t)(body_size >> (8 * (capacity - 1))); \ + } while (0) + +#define ptls_buffer_push_asn1_block(buf, block) \ + do { \ + ptls_buffer_push((buf), 0xff); /* dummy */ \ + size_t body_start = (buf)->off; \ + do { \ + block \ + } while (0); \ + size_t body_size = (buf)->off - body_start; \ + if (body_size < 128) { \ + (buf)->base[body_start - 1] = (uint8_t)body_size; \ + } else { \ + if ((ret = ptls_buffer__adjust_asn1_blocksize((buf), body_size)) != 0) \ + goto Exit; \ + } \ + } while (0) + +#define ptls_buffer_push_asn1_sequence(buf, block) \ + do { \ + ptls_buffer_push((buf), 0x30); \ + ptls_buffer_push_asn1_block((buf), block); \ + } while (0) + +int ptls_decode16(uint16_t *value, const uint8_t **src, const uint8_t *end); +int ptls_decode32(uint32_t *value, const uint8_t **src, const uint8_t *end); +int ptls_decode64(uint64_t *value, const uint8_t **src, const uint8_t *end); + +#define ptls_decode_open_block(src, end, capacity, block) \ + do { \ + size_t _capacity = (capacity); \ + if (_capacity > (size_t)(end - (src))) { \ + ret = PTLS_ALERT_DECODE_ERROR; \ + goto Exit; \ + } \ + size_t _block_size = 0; \ + do { \ + _block_size = _block_size << 8 | *(src)++; \ + } while (--_capacity != 0); \ + if (_block_size > (size_t)(end - (src))) { \ + ret = PTLS_ALERT_DECODE_ERROR; \ + goto Exit; \ + } \ + do { \ + const uint8_t *const end = (src) + _block_size; \ + do { \ + block \ + } while (0); \ + if ((src) != end) { \ + ret = PTLS_ALERT_DECODE_ERROR; \ + goto Exit; \ + } \ + } while (0); \ + } while (0) + +#define ptls_decode_assert_block_close(src, end) \ + do { \ + if ((src) != end) { \ + ret = PTLS_ALERT_DECODE_ERROR; \ + goto Exit; \ + } \ + } while (0); + +#define ptls_decode_block(src, end, capacity, block) \ + do { \ + ptls_decode_open_block((src), end, capacity, block); \ + ptls_decode_assert_block_close((src), end); \ + } while (0) + +/** + * create a object to handle new TLS connection. Client-side of a TLS connection is created if server_name is non-NULL. Otherwise, + * a server-side connection is created. + */ +ptls_t *ptls_new(ptls_context_t *ctx, int is_server); +/** + * releases all resources associated to the object + */ +void ptls_free(ptls_t *tls); +/** + * returns address of the crypto callbacks that the connection is using + */ +ptls_context_t *ptls_get_context(ptls_t *tls); +/** + * updates the context of a connection. Can be called from `on_client_hello` callback. + */ +void ptls_set_context(ptls_t *tls, ptls_context_t *ctx); +/** + * returns the client-random + */ +ptls_iovec_t ptls_get_client_random(ptls_t *tls); +/** + * returns the cipher-suite being used + */ +ptls_cipher_suite_t *ptls_get_cipher(ptls_t *tls); +/** + * returns the server-name (NULL if SNI is not used or failed to negotiate) + */ +const char *ptls_get_server_name(ptls_t *tls); +/** + * sets the server-name (for client the value sent in SNI). If server_name_len is zero, then strlen(server_name) is called to + * determine + * the length of the name. + */ +int ptls_set_server_name(ptls_t *tls, const char *server_name, size_t server_name_len); +/** + * returns the negotiated protocol (or NULL) + */ +const char *ptls_get_negotiated_protocol(ptls_t *tls); +/** + * sets the negotiated protocol. If protocol_len is zero, strlen(protocol) is called to determine the length of the protocol name. + */ +int ptls_set_negotiated_protocol(ptls_t *tls, const char *protocol, size_t protocol_len); +/** + * returns if the handshake has been completed + */ +int ptls_handshake_is_complete(ptls_t *tls); +/** + * returns if a PSK (or PSK-DHE) handshake was performed + */ +int ptls_is_psk_handshake(ptls_t *tls); +/** + * returns a pointer to user data pointer (client is reponsible for freeing the associated data prior to calling ptls_free) + */ +void **ptls_get_data_ptr(ptls_t *tls); +/** + * proceeds with the handshake, optionally taking some input from peer. The function returns zero in case the handshake completed + * successfully. PTLS_ERROR_IN_PROGRESS is returned in case the handshake is incomplete. Otherwise, an error value is returned. The + * contents of sendbuf should be sent to the client, regardless of whether if an error is returned. inlen is an argument used for + * both input and output. As an input, the arguments takes the size of the data available as input. Upon return the value is updated + * to the number of bytes consumed by the handshake. In case the returned value is PTLS_ERROR_IN_PROGRESS there is a guarantee that + * all the input are consumed (i.e. the value of inlen does not change). + */ +int ptls_handshake(ptls_t *tls, ptls_buffer_t *sendbuf, const void *input, size_t *inlen, ptls_handshake_properties_t *args); +/** + * decrypts the first record within given buffer + */ +int ptls_receive(ptls_t *tls, ptls_buffer_t *plaintextbuf, const void *input, size_t *len); +/** + * encrypts given buffer into multiple TLS records + */ +int ptls_send(ptls_t *tls, ptls_buffer_t *sendbuf, const void *input, size_t inlen); +/** + * returns per-record overhead + */ +size_t ptls_get_record_overhead(ptls_t *tls); +/** + * sends an alert + */ +int ptls_send_alert(ptls_t *tls, ptls_buffer_t *sendbuf, uint8_t level, uint8_t description); +/** + * + */ +int ptls_export_secret(ptls_t *tls, void *output, size_t outlen, const char *label, ptls_iovec_t context_value, int is_early); +/** + * + */ +ptls_hash_context_t *ptls_hmac_create(ptls_hash_algorithm_t *algo, const void *key, size_t key_size); +/** + * + */ +int ptls_hkdf_extract(ptls_hash_algorithm_t *hash, void *output, ptls_iovec_t salt, ptls_iovec_t ikm); +/** + * + */ +int ptls_hkdf_expand(ptls_hash_algorithm_t *hash, void *output, size_t outlen, ptls_iovec_t prk, ptls_iovec_t info); +/** + * + */ +int ptls_hkdf_expand_label(ptls_hash_algorithm_t *algo, void *output, size_t outlen, ptls_iovec_t secret, const char *label, + ptls_iovec_t hash_value, const char *base_label); +/** + * instantiates a symmetric cipher + */ +ptls_cipher_context_t *ptls_cipher_new(ptls_cipher_algorithm_t *algo, int is_enc, const void *key); +/** + * destroys a symmetric cipher + */ +void ptls_cipher_free(ptls_cipher_context_t *ctx); +/** + * initializes the IV; this function must be called prior to calling ptls_cipher_encrypt + */ +static void ptls_cipher_init(ptls_cipher_context_t *ctx, const void *iv); +/** + * encrypts given text + */ +static void ptls_cipher_encrypt(ptls_cipher_context_t *ctx, void *output, const void *input, size_t len); +/** + * instantiates an AEAD cipher given a secret, which is expanded using hkdf to a set of key and iv + * @param aead + * @param hash + * @param is_enc 1 if creating a context for encryption, 0 if creating a context for decryption + * @param secret the secret. The size must be the digest length of the hash algorithm + * @return pointer to an AEAD context if successful, otherwise NULL + */ +ptls_aead_context_t *ptls_aead_new(ptls_aead_algorithm_t *aead, ptls_hash_algorithm_t *hash, int is_enc, const void *secret, + const char *base_label); +/** + * destroys an AEAD cipher context + */ +void ptls_aead_free(ptls_aead_context_t *ctx); +/** + * + */ +size_t ptls_aead_encrypt(ptls_aead_context_t *ctx, void *output, const void *input, size_t inlen, uint64_t seq, const void *aad, + size_t aadlen); +/** + * initializes the internal state of the encryptor + */ +static void ptls_aead_encrypt_init(ptls_aead_context_t *ctx, uint64_t seq, const void *aad, size_t aadlen); +/** + * encrypts the input and updates the GCM state + * @return number of bytes emitted to output + */ +static size_t ptls_aead_encrypt_update(ptls_aead_context_t *ctx, void *output, const void *input, size_t inlen); +/** + * emits buffered data (if any) and the GCM tag + * @return number of bytes emitted to output + */ +static size_t ptls_aead_encrypt_final(ptls_aead_context_t *ctx, void *output); +/** + * decrypts an AEAD record + * @return number of bytes emitted to output if successful, or SIZE_MAX if the input is invalid (e.g. broken MAC) + */ +static size_t ptls_aead_decrypt(ptls_aead_context_t *ctx, void *output, const void *input, size_t inlen, uint64_t seq, + const void *aad, size_t aadlen); +/** + * internal + */ +void ptls_aead__build_iv(ptls_aead_context_t *ctx, uint8_t *iv, uint64_t seq); +/** + * clears memory + */ +extern void (*volatile ptls_clear_memory)(void *p, size_t len); +/** + * + */ +static ptls_iovec_t ptls_iovec_init(const void *p, size_t len); + +/* inline functions */ +inline ptls_iovec_t ptls_iovec_init(const void *p, size_t len) +{ + /* avoid the "return (ptls_iovec_t){(uint8_t *)p, len};" construct because it requires C99 + * and triggers a warning "C4204: nonstandard extension used: non-constant aggregate initializer" + * in Visual Studio */ + ptls_iovec_t r; + r.base = (uint8_t *)p; + r.len = len; + return r; +} + +inline void ptls_buffer_init(ptls_buffer_t *buf, void *smallbuf, size_t smallbuf_size) +{ + assert(smallbuf != NULL); + buf->base = (uint8_t *)smallbuf; + buf->off = 0; + buf->capacity = smallbuf_size; + buf->is_allocated = 0; +} + +inline void ptls_buffer_dispose(ptls_buffer_t *buf) +{ + ptls_buffer__release_memory(buf); + *buf = (ptls_buffer_t){NULL}; +} + +inline void ptls_cipher_init(ptls_cipher_context_t *ctx, const void *iv) +{ + ctx->do_init(ctx, iv); +} + +inline void ptls_cipher_encrypt(ptls_cipher_context_t *ctx, void *output, const void *input, size_t len) +{ + ctx->do_transform(ctx, output, input, len); +} + +inline void ptls_aead_encrypt_init(ptls_aead_context_t *ctx, uint64_t seq, const void *aad, size_t aadlen) +{ + uint8_t iv[PTLS_MAX_IV_SIZE]; + + ptls_aead__build_iv(ctx, iv, seq); + ctx->do_encrypt_init(ctx, iv, aad, aadlen); +} + +inline size_t ptls_aead_encrypt_update(ptls_aead_context_t *ctx, void *output, const void *input, size_t inlen) +{ + return ctx->do_encrypt_update(ctx, output, input, inlen); +} + +inline size_t ptls_aead_encrypt_final(ptls_aead_context_t *ctx, void *output) +{ + return ctx->do_encrypt_final(ctx, output); +} + +inline size_t ptls_aead_decrypt(ptls_aead_context_t *ctx, void *output, const void *input, size_t inlen, uint64_t seq, + const void *aad, size_t aadlen) +{ + uint8_t iv[PTLS_MAX_IV_SIZE]; + + ptls_aead__build_iv(ctx, iv, seq); + return ctx->do_decrypt(ctx, output, input, inlen, iv, aad, aadlen); +} + +int ptls_load_certificates(ptls_context_t *ctx, char *cert_pem_file); + +extern ptls_get_time_t ptls_get_time; + +#define ptls_define_hash(name, ctx_type, init_func, update_func, final_func) \ + \ + struct name##_context_t { \ + ptls_hash_context_t super; \ + ctx_type ctx; \ + }; \ + \ + static void name##_update(ptls_hash_context_t *_ctx, const void *src, size_t len) \ + { \ + struct name##_context_t *ctx = (struct name##_context_t *)_ctx; \ + update_func(&ctx->ctx, src, len); \ + } \ + \ + static void name##_final(ptls_hash_context_t *_ctx, void *md, ptls_hash_final_mode_t mode) \ + { \ + struct name##_context_t *ctx = (struct name##_context_t *)_ctx; \ + if (mode == PTLS_HASH_FINAL_MODE_SNAPSHOT) { \ + ctx_type copy = ctx->ctx; \ + final_func(©, md); \ + ptls_clear_memory(©, sizeof(copy)); \ + return; \ + } \ + if (md != NULL) \ + final_func(&ctx->ctx, md); \ + switch (mode) { \ + case PTLS_HASH_FINAL_MODE_FREE: \ + ptls_clear_memory(&ctx->ctx, sizeof(ctx->ctx)); \ + free(ctx); \ + break; \ + case PTLS_HASH_FINAL_MODE_RESET: \ + init_func(&ctx->ctx); \ + break; \ + default: \ + assert(!"FIXME"); \ + break; \ + } \ + } \ + \ + static ptls_hash_context_t *name##_clone(ptls_hash_context_t *_src) \ + { \ + struct name##_context_t *dst, *src = (struct name##_context_t *)_src; \ + if ((dst = malloc(sizeof(*dst))) == NULL) \ + return NULL; \ + *dst = *src; \ + return &dst->super; \ + } \ + \ + static ptls_hash_context_t *name##_create(void) \ + { \ + struct name##_context_t *ctx; \ + if ((ctx = malloc(sizeof(*ctx))) == NULL) \ + return NULL; \ + ctx->super = (ptls_hash_context_t){name##_update, name##_final, name##_clone}; \ + init_func(&ctx->ctx); \ + return &ctx->super; \ + } + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/web/server/h2o/libh2o/deps/picotls/include/picotls/asn1.h b/web/server/h2o/libh2o/deps/picotls/include/picotls/asn1.h new file mode 100644 index 00000000..5314c58a --- /dev/null +++ b/web/server/h2o/libh2o/deps/picotls/include/picotls/asn1.h @@ -0,0 +1,64 @@ +/* +* Copyright (c) 2017 Christian Huitema +* +* Permission to use, copy, modify, and distribute this software for any +* purpose with or without fee is hereby granted, provided that the above +* copyright notice and this permission notice appear in all copies. +* +* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +*/ + +#ifndef PTLS_ASN1_H +#define PTLS_ASN1_H + +// #include "picotls/minicrypto.h" + +/* +* The ASN.1 functions take a "log context" parameter of type ptls_minicrypto_log_ctx_t. +* +* The log function in that code can be instantiated for example as: +* +* void log_printf(void * ctx, const char * format, ...) +* { +* va_list argptr; +* va_start(argptr, format); +* vfprintf(stderr, format, argptr); +* } +* +* Using definitions from and +*/ + +typedef struct st_ptls_minicrypto_log_ctx_t { + void *ctx; + void (*fn)(void *ctx, const char *format, ...); +} ptls_minicrypto_log_ctx_t; + +size_t ptls_asn1_error_message(char const *error_label, size_t bytes_max, size_t byte_index, int level, + ptls_minicrypto_log_ctx_t *log_ctx); + +void ptls_asn1_dump_content(const uint8_t *bytes, size_t bytes_max, size_t byte_index, ptls_minicrypto_log_ctx_t *log_ctx); + +size_t ptls_asn1_read_type(const uint8_t *bytes, size_t bytes_max, int *structure_bit, int *type_class, uint32_t *type_number, + int *decode_error, int level, ptls_minicrypto_log_ctx_t *log_ctx); + +void ptls_asn1_print_type(int type_class, uint32_t type_number, int level, ptls_minicrypto_log_ctx_t *log_ctx); + +size_t ptls_asn1_read_length(const uint8_t *bytes, size_t bytes_max, size_t byte_index, uint32_t *length, int *indefinite_length, + size_t *last_byte, int *decode_error, int level, ptls_minicrypto_log_ctx_t *log_ctx); + +size_t ptls_asn1_get_expected_type_and_length(const uint8_t *bytes, size_t bytes_max, size_t byte_index, uint8_t expected_type, + uint32_t *length, int *indefinite_length, size_t *last_byte, int *decode_error, + ptls_minicrypto_log_ctx_t *log_ctx); + +size_t ptls_asn1_validation_recursive(const uint8_t *bytes, size_t bytes_max, int *decode_error, int level, + ptls_minicrypto_log_ctx_t *log_ctx); + +int ptls_asn1_validation(const uint8_t *bytes, size_t length, ptls_minicrypto_log_ctx_t *log_ctx); + +#endif diff --git a/web/server/h2o/libh2o/deps/picotls/include/picotls/minicrypto.h b/web/server/h2o/libh2o/deps/picotls/include/picotls/minicrypto.h new file mode 100644 index 00000000..ce7e58ec --- /dev/null +++ b/web/server/h2o/libh2o/deps/picotls/include/picotls/minicrypto.h @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2016 DeNA Co., Ltd., Kazuho Oku + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ +#ifndef picotls_minicrypto_h +#define picotls_minicrypto_h + +#include "picotls.h" + +#define SECP256R1_PRIVATE_KEY_SIZE 32 +#define SECP256R1_PUBLIC_KEY_SIZE 65 /* including the header */ +#define SECP256R1_SHARED_SECRET_SIZE 32 + +typedef struct st_ptls_minicrypto_secp256r1sha256_sign_certificate_t { + ptls_sign_certificate_t super; + uint8_t key[SECP256R1_PRIVATE_KEY_SIZE]; +} ptls_minicrypto_secp256r1sha256_sign_certificate_t; + +void ptls_minicrypto_random_bytes(void *buf, size_t len); + +int ptls_minicrypto_init_secp256r1sha256_sign_certificate(ptls_minicrypto_secp256r1sha256_sign_certificate_t *self, + ptls_iovec_t key); + +extern ptls_key_exchange_algorithm_t ptls_minicrypto_secp256r1, ptls_minicrypto_x25519; +extern ptls_key_exchange_algorithm_t *ptls_minicrypto_key_exchanges[]; +extern ptls_cipher_algorithm_t ptls_minicrypto_aes128ctr, ptls_minicrypto_aes256ctr, ptls_minicrypto_chacha20; +extern ptls_aead_algorithm_t ptls_minicrypto_aes128gcm, ptls_minicrypto_aes256gcm, ptls_minicrypto_chacha20poly1305; +extern ptls_hash_algorithm_t ptls_minicrypto_sha256, ptls_minicrypto_sha384; +extern ptls_cipher_suite_t ptls_minicrypto_aes128gcmsha256, ptls_minicrypto_aes256gcmsha384, ptls_minicrypto_chacha20poly1305sha256; +extern ptls_cipher_suite_t *ptls_minicrypto_cipher_suites[]; + +typedef struct st_ptls_asn1_pkcs8_private_key_t { + ptls_iovec_t vec; + size_t algorithm_index; + uint32_t algorithm_length; + size_t parameters_index; + uint32_t parameters_length; + size_t key_data_index; + uint32_t key_data_length; +} ptls_asn1_pkcs8_private_key_t; + +int ptls_minicrypto_load_private_key(ptls_context_t *ctx, char const *pem_fname); + +#endif diff --git a/web/server/h2o/libh2o/deps/picotls/include/picotls/openssl.h b/web/server/h2o/libh2o/deps/picotls/include/picotls/openssl.h new file mode 100644 index 00000000..459474ad --- /dev/null +++ b/web/server/h2o/libh2o/deps/picotls/include/picotls/openssl.h @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2016 DeNA Co., Ltd., Kazuho Oku + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ +#ifndef picotls_openssl_h +#define picotls_openssl_h + +#include +#include +#include +#include +#include "../picotls.h" + +#if OPENSSL_VERSION_NUMBER >= 0x10100000L && !defined(LIBRESSL_VERSION_NUMBER) +#define PTLS_OPENSSL_HAVE_CHACHA20_POLY1305 +#endif + +extern ptls_key_exchange_algorithm_t ptls_openssl_secp256r1; +extern ptls_key_exchange_algorithm_t *ptls_openssl_key_exchanges[]; +extern ptls_cipher_algorithm_t ptls_openssl_aes128ctr; +extern ptls_aead_algorithm_t ptls_openssl_aes128gcm; +extern ptls_cipher_algorithm_t ptls_openssl_aes256ctr; +extern ptls_aead_algorithm_t ptls_openssl_aes256gcm; +extern ptls_hash_algorithm_t ptls_openssl_sha256; +extern ptls_hash_algorithm_t ptls_openssl_sha384; +extern ptls_cipher_suite_t ptls_openssl_aes128gcmsha256; +extern ptls_cipher_suite_t ptls_openssl_aes256gcmsha384; +extern ptls_cipher_suite_t *ptls_openssl_cipher_suites[]; + +#if defined(PTLS_OPENSSL_HAVE_CHACHA20_POLY1305) +extern ptls_cipher_algorithm_t ptls_openssl_chacha20; +extern ptls_aead_algorithm_t ptls_openssl_chacha20poly1305; +extern ptls_cipher_suite_t ptls_openssl_chacha20poly1305sha256; +#endif + +void ptls_openssl_random_bytes(void *buf, size_t len); + +struct st_ptls_openssl_signature_scheme_t { + uint16_t scheme_id; + const EVP_MD *scheme_md; +}; + +typedef struct st_ptls_openssl_sign_certificate_t { + ptls_sign_certificate_t super; + EVP_PKEY *key; + struct st_ptls_openssl_signature_scheme_t schemes[4]; /* terminated by .scheme_id == UINT16_MAX */ +} ptls_openssl_sign_certificate_t; + +int ptls_openssl_init_sign_certificate(ptls_openssl_sign_certificate_t *self, EVP_PKEY *key); +void ptls_openssl_dispose_sign_certificate(ptls_openssl_sign_certificate_t *self); +int ptls_openssl_load_certificates(ptls_context_t *ctx, X509 *cert, STACK_OF(X509) * chain); + +typedef struct st_ptls_openssl_verify_certificate_t { + ptls_verify_certificate_t super; + X509_STORE *cert_store; +} ptls_openssl_verify_certificate_t; + +#define PTLS_OPENSSL_DEFAULT_CERTIFICATE_STORE ((X509_STORE *)1) + +int ptls_openssl_init_verify_certificate(ptls_openssl_verify_certificate_t *self, X509_STORE *store); +void ptls_openssl_dispose_verify_certificate(ptls_openssl_verify_certificate_t *self); + +int ptls_openssl_encrypt_ticket(ptls_buffer_t *dst, ptls_iovec_t src, + int (*cb)(unsigned char *, unsigned char *, EVP_CIPHER_CTX *, HMAC_CTX *, int)); +int ptls_openssl_decrypt_ticket(ptls_buffer_t *dst, ptls_iovec_t src, + int (*cb)(unsigned char *, unsigned char *, EVP_CIPHER_CTX *, HMAC_CTX *, int)); + +#endif diff --git a/web/server/h2o/libh2o/deps/picotls/include/picotls/pembase64.h b/web/server/h2o/libh2o/deps/picotls/include/picotls/pembase64.h new file mode 100644 index 00000000..1b59910b --- /dev/null +++ b/web/server/h2o/libh2o/deps/picotls/include/picotls/pembase64.h @@ -0,0 +1,44 @@ +/* +* Copyright (c) 2017 Christian Huitema +* +* Permission to use, copy, modify, and distribute this software for any +* purpose with or without fee is hereby granted, provided that the above +* copyright notice and this permission notice appear in all copies. +* +* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +*/ + +#ifndef PTLS_PEMBASE64_H +#define PTLS_PEMBASE64_H + +/* +* Base64 functions used in encoding and decoding of PEM files +*/ + +#define PTLS_BASE64_DECODE_DONE 0 +#define PTLS_BASE64_DECODE_IN_PROGRESS 1 +#define PTLS_BASE64_DECODE_FAILED -1 + +typedef struct st_ptls_base64_decode_state_t { + int nbc; + int nbo; + int status; + uint32_t v; +} ptls_base64_decode_state_t; + +int ptls_base64_encode(const uint8_t *data, size_t data_len, char *base64_text); + +size_t ptls_base64_howlong(size_t data_length); + +void ptls_base64_decode_init(ptls_base64_decode_state_t *state); +int ptls_base64_decode(const char *base64_text, ptls_base64_decode_state_t *state, ptls_buffer_t *buf); + +int ptls_load_pem_objects(char const *pem_fname, const char *label, ptls_iovec_t *list, size_t list_max, size_t *nb_objects); + +#endif /* PTLS_PEMBASE64_H */ diff --git a/web/server/h2o/libh2o/deps/picotls/lib/asn1.c b/web/server/h2o/libh2o/deps/picotls/lib/asn1.c new file mode 100644 index 00000000..4422bed9 --- /dev/null +++ b/web/server/h2o/libh2o/deps/picotls/lib/asn1.c @@ -0,0 +1,295 @@ +/* +* Copyright (c) 2016 Christian Huitema +* +* Permission to use, copy, modify, and distribute this software for any +* purpose with or without fee is hereby granted, provided that the above +* copyright notice and this permission notice appear in all copies. +* +* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +*/ + +/* +* Basic ASN1 validation and optional print-out +*/ + +#ifdef _WINDOWS +#include "wincompat.h" +#else +#include +#endif +#include +#include +#include +#include +#include "picotls.h" +#include "picotls/minicrypto.h" +#include "picotls/asn1.h" + +static char const *asn1_type_classes[4] = {"Universal", "Application", "Context-specific", "Private"}; + +static char const *asn1_universal_types[] = { + "End-of-Content", "BOOLEAN", "INTEGER", "BIT STRING", "OCTET STRING", "NULL", + "OBJECT IDENTIFIER", "Object Descriptor", "EXTERNAL", "REAL", "ENUMERATED", "EMBEDDED PDV", + "UTF8String", "RELATIVE-OID", "Reserved (16)", "Reserved (17)", "SEQUENCE", "SET", + "NumericString", "PrintableString", "T61String", "VideotexString", "IA5String", "UTCTime", + "GeneralizedTime", "GraphicString", "VisibleString", "GeneralString", "UniversalString", "CHARACTER STRING", + "BMPString"}; + +static size_t nb_asn1_universal_types = sizeof(asn1_universal_types) / sizeof(char const *); + +static void ptls_asn1_print_indent(int level, ptls_minicrypto_log_ctx_t *log_ctx) +{ + for (int indent = 0; indent <= level; indent++) { + log_ctx->fn(log_ctx->ctx, " "); + } +} + +size_t ptls_asn1_error_message(char const *error_label, size_t bytes_max, size_t byte_index, int level, + ptls_minicrypto_log_ctx_t *log_ctx) +{ + if (log_ctx != NULL) { + ptls_asn1_print_indent(level, log_ctx); + log_ctx->fn(log_ctx->ctx, "Error: %s (near position: %d (0x%x) out of %d)", error_label, (int)byte_index, + (uint32_t)byte_index, (int)bytes_max); + } + return byte_index; +} + +void ptls_asn1_dump_content(const uint8_t *bytes, size_t bytes_max, size_t byte_index, ptls_minicrypto_log_ctx_t *log_ctx) +{ + if (log_ctx != NULL && bytes_max > byte_index) { + size_t nb_bytes = bytes_max - byte_index; + + log_ctx->fn(log_ctx->ctx, " "); + + for (size_t i = 0; i < 16 && i < nb_bytes; i++) { + log_ctx->fn(log_ctx->ctx, "%02x", bytes[byte_index + i]); + } + + if (nb_bytes > 16) { + log_ctx->fn(log_ctx->ctx, "..."); + } + } +} + +size_t ptls_asn1_read_type(const uint8_t *bytes, size_t bytes_max, int *structure_bit, int *type_class, uint32_t *type_number, + int *decode_error, int level, ptls_minicrypto_log_ctx_t *log_ctx) +{ + /* Get the type byte */ + size_t byte_index = 1; + uint8_t first_byte = bytes[0]; + *structure_bit = (first_byte >> 5) & 1; + *type_class = (first_byte >> 6) & 3; + *type_number = first_byte & 31; + + if (*type_number == 31) { + uint32_t long_type = 0; + const uint32_t type_number_limit = 0x07FFFFFFF; + int next_byte; + int end_found = 0; + + while (byte_index < bytes_max && long_type <= type_number_limit) { + next_byte = bytes[byte_index++]; + long_type <<= 7; + long_type |= next_byte & 127; + if ((next_byte & 128) == 0) { + end_found = 1; + break; + } + } + + if (end_found) { + *type_number = long_type; + } else { + /* This is an error */ + byte_index = ptls_asn1_error_message("Incorrect type coding", bytes_max, byte_index, level, log_ctx); + *decode_error = PTLS_ERROR_BER_MALFORMED_TYPE; + } + } + + return byte_index; +} + +void ptls_asn1_print_type(int type_class, uint32_t type_number, int level, ptls_minicrypto_log_ctx_t *log_ctx) +{ + /* Print the type */ + ptls_asn1_print_indent(level, log_ctx); + if (type_class == 0 && type_number < nb_asn1_universal_types) { + log_ctx->fn(log_ctx->ctx, "%s", asn1_universal_types[type_number]); + } else if (type_class == 2) { + log_ctx->fn(log_ctx->ctx, "[%d]", type_number); + } else { + log_ctx->fn(log_ctx->ctx, "%s[%d]", asn1_type_classes[type_class], type_number); + } +} + +size_t ptls_asn1_read_length(const uint8_t *bytes, size_t bytes_max, size_t byte_index, uint32_t *length, int *indefinite_length, + size_t *last_byte, int *decode_error, int level, ptls_minicrypto_log_ctx_t *log_ctx) +{ + int length_of_length = 0; + + *indefinite_length = 0; + *length = 0; + *last_byte = bytes_max; + + if (byte_index < bytes_max) { + *length = bytes[byte_index++]; + if ((*length & 128) != 0) { + length_of_length = *length & 127; + *length = 0; + + if (byte_index + length_of_length >= bytes_max) { + /* This is an error */ + byte_index = ptls_asn1_error_message("Incorrect length coding", bytes_max, byte_index, level, log_ctx); + *decode_error = PTLS_ERROR_BER_MALFORMED_LENGTH; + } else { + for (int i = 0; i < length_of_length && byte_index < bytes_max; i++) { + *length <<= 8; + *length |= bytes[byte_index++]; + } + + if (length_of_length == 0) { + *last_byte = bytes_max; + *indefinite_length = 1; + } else { + *last_byte = byte_index + *length; + } + } + } else { + *last_byte = byte_index + *length; + } + + if (*decode_error == 0) { + /* TODO: verify that the length makes sense */ + if (*last_byte > bytes_max) { + byte_index = ptls_asn1_error_message("Length larger than message", bytes_max, byte_index, level, log_ctx); + *decode_error = PTLS_ERROR_BER_EXCESSIVE_LENGTH; + } + } + } + + return byte_index; +} + +size_t ptls_asn1_get_expected_type_and_length(const uint8_t *bytes, size_t bytes_max, size_t byte_index, uint8_t expected_type, + uint32_t *length, int *indefinite_length, size_t *last_byte, int *decode_error, + ptls_minicrypto_log_ctx_t *log_ctx) +{ + int is_indefinite = 0; + + /* Check that the expected type is present */ + if (bytes[byte_index] != expected_type) { + byte_index = ptls_asn1_error_message("Unexpected type", bytes_max, byte_index, 0, log_ctx); + *decode_error = PTLS_ERROR_INCORRECT_ASN1_SYNTAX; + } else { + /* get length of element */ + byte_index++; + byte_index = + ptls_asn1_read_length(bytes, bytes_max, byte_index, length, &is_indefinite, last_byte, decode_error, 0, log_ctx); + + if (indefinite_length != NULL) { + *indefinite_length = is_indefinite; + } else if (is_indefinite) { + byte_index = ptls_asn1_error_message("Incorrect length for DER", bytes_max, byte_index, 0, log_ctx); + *decode_error = PTLS_ERROR_DER_INDEFINITE_LENGTH; + } + } + + return byte_index; +} + +size_t ptls_asn1_validation_recursive(const uint8_t *bytes, size_t bytes_max, int *decode_error, int level, + ptls_minicrypto_log_ctx_t *log_ctx) +{ + /* Get the type byte */ + int structure_bit = 0; + int type_class = 0; + uint32_t type_number = 0; + uint32_t length = 0; + int indefinite_length = 0; + size_t last_byte = 0; + /* Decode the type */ + size_t byte_index = + ptls_asn1_read_type(bytes, bytes_max, &structure_bit, &type_class, &type_number, decode_error, level, log_ctx); + + if (*decode_error == 0 && log_ctx != NULL) { + ptls_asn1_print_type(type_class, type_number, level, log_ctx); + } + + /* Get the length */ + byte_index = + ptls_asn1_read_length(bytes, bytes_max, byte_index, &length, &indefinite_length, &last_byte, decode_error, level, log_ctx); + + if (last_byte <= bytes_max) { + if (structure_bit) { + /* If structured, recurse on a loop */ + if (log_ctx != NULL) { + log_ctx->fn(log_ctx->ctx, " {\n"); + } + + while (byte_index < last_byte) { + if (indefinite_length != 0 && bytes[byte_index] == 0) { + if (byte_index + 2 > bytes_max || bytes[byte_index + 1] != 0) { + byte_index = + ptls_asn1_error_message("EOC: unexpected end of content", bytes_max, byte_index, level + 1, log_ctx); + + *decode_error = PTLS_ERROR_BER_UNEXPECTED_EOC; + } else { + if (log_ctx != NULL) { + ptls_asn1_print_indent(level, log_ctx); + log_ctx->fn(log_ctx->ctx, "EOC\n"); + } + byte_index += 2; + break; + } + } else { + byte_index += ptls_asn1_validation_recursive(bytes + byte_index, last_byte - byte_index, decode_error, + level + 1, log_ctx); + + if (*decode_error) { + byte_index = bytes_max; + break; + } + } + + if (log_ctx != NULL) { + if (byte_index < last_byte) { + log_ctx->fn(log_ctx->ctx, ","); + } + log_ctx->fn(log_ctx->ctx, "\n"); + } + } + + if (log_ctx != NULL) { + ptls_asn1_print_indent(level, log_ctx); + log_ctx->fn(log_ctx->ctx, "}"); + } + } else { + ptls_asn1_dump_content(bytes, last_byte, byte_index, log_ctx); + byte_index = last_byte; + } + } + + return byte_index; +} + +int ptls_asn1_validation(const uint8_t *bytes, size_t length, ptls_minicrypto_log_ctx_t *log_ctx) +{ + int decode_error = 0; + size_t decoded = ptls_asn1_validation_recursive(bytes, length, &decode_error, 0, log_ctx); + + if (decode_error == 0 && decoded < length) { + decode_error = PTLS_ERROR_BER_ELEMENT_TOO_SHORT; + if (log_ctx != NULL) { + log_ctx->fn(log_ctx->ctx, "Type too short, %d bytes only out of %d\n", (int)decoded, (int)length); + } + } + + return decode_error; +} diff --git a/web/server/h2o/libh2o/deps/picotls/lib/cifra.c b/web/server/h2o/libh2o/deps/picotls/lib/cifra.c new file mode 100644 index 00000000..af33c33f --- /dev/null +++ b/web/server/h2o/libh2o/deps/picotls/lib/cifra.c @@ -0,0 +1,530 @@ +/* + * Copyright (c) 2016 DeNA Co., Ltd., Kazuho Oku + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ +#ifndef _XOPEN_SOURCE +#define _XOPEN_SOURCE 700 /* required for glibc to use getaddrinfo, etc. */ +#endif +#include +#include +#include +#include +#ifdef _WINDOWS +#include "wincompat.h" +#else +#include +#endif +#include "aes.h" +#include "bitops.h" +#include "drbg.h" +#include "curve25519.h" +#include "../deps/cifra/src/ext/handy.h" +#include "modes.h" +#include "poly1305.h" +#include "salsa20.h" +#include "sha2.h" +#include "picotls.h" +#include "picotls/minicrypto.h" + +#ifdef _WINDOWS +#include +static void read_entropy(uint8_t *entropy, size_t size) +{ + HCRYPTPROV hCryptProv = 0; + BOOL ret = FALSE; + + if (CryptAcquireContext(&hCryptProv, NULL, NULL, PROV_RSA_FULL, 0)) { + ret = CryptGenRandom(hCryptProv, (DWORD)size, entropy); + (void)CryptReleaseContext(hCryptProv, 0); + } + + if (ret == FALSE) { + abort(); + } +} +#else +static void read_entropy(uint8_t *entropy, size_t size) +{ + int fd; + + if ((fd = open("/dev/urandom", O_RDONLY | O_CLOEXEC)) == -1) { + if ((fd = open("/dev/random", O_RDONLY | O_CLOEXEC)) == -1) { + perror("ptls_minicrypto_random_bytes: could not open neither /dev/random or /dev/urandom"); + abort(); + } + } + + while (size != 0) { + ssize_t rret; + while ((rret = read(fd, entropy, size)) == -1 && errno == EINTR) + ; + if (rret < 0) { + perror("ptls_minicrypto_random_bytes"); + abort(); + } + entropy += rret; + size -= rret; + } + + close(fd); +} +#endif + +void ptls_minicrypto_random_bytes(void *buf, size_t len) +{ +#ifdef _WINDOWS + static __declspec(thread) cf_hash_drbg_sha256 ctx; +#else + static __thread cf_hash_drbg_sha256 ctx; +#endif + + if (cf_hash_drbg_sha256_needs_reseed(&ctx)) { + uint8_t entropy[256]; + read_entropy(entropy, sizeof(entropy)); + cf_hash_drbg_sha256_init(&ctx, entropy, sizeof(entropy) / 2, entropy + sizeof(entropy) / 2, sizeof(entropy) / 2, "ptls", 4); + } + cf_hash_drbg_sha256_gen(&ctx, buf, len); +} + +#define X25519_KEY_SIZE 32 + +struct st_x25519_key_exchange_t { + ptls_key_exchange_context_t super; + uint8_t priv[X25519_KEY_SIZE]; + uint8_t pub[X25519_KEY_SIZE]; +}; + +static void x25519_create_keypair(uint8_t *priv, uint8_t *pub) +{ + ptls_minicrypto_random_bytes(priv, X25519_KEY_SIZE); + cf_curve25519_mul_base(pub, priv); +} + +static int x25519_derive_secret(ptls_iovec_t *secret, const uint8_t *clientpriv, const uint8_t *clientpub, + const uint8_t *serverpriv, const uint8_t *serverpub) +{ + if ((secret->base = malloc(X25519_KEY_SIZE)) == NULL) + return PTLS_ERROR_NO_MEMORY; + + cf_curve25519_mul(secret->base, clientpriv != NULL ? clientpriv : serverpriv, clientpriv != NULL ? serverpub : clientpub); + secret->len = X25519_KEY_SIZE; + return 0; +} + +static int x25519_on_exchange(ptls_key_exchange_context_t **_ctx, ptls_iovec_t *secret, ptls_iovec_t peerkey) +{ + struct st_x25519_key_exchange_t *ctx = (struct st_x25519_key_exchange_t *)*_ctx; + int ret; + + *_ctx = NULL; + + if (secret == NULL) { + ret = 0; + goto Exit; + } + + if (peerkey.len != X25519_KEY_SIZE) { + ret = PTLS_ALERT_DECRYPT_ERROR; + goto Exit; + } + ret = x25519_derive_secret(secret, ctx->priv, ctx->pub, NULL, peerkey.base); + +Exit: + ptls_clear_memory(ctx->priv, sizeof(ctx->priv)); + free(ctx); + return ret; +} + +static int x25519_create_key_exchange(ptls_key_exchange_context_t **_ctx, ptls_iovec_t *pubkey) +{ + struct st_x25519_key_exchange_t *ctx; + + if ((ctx = (struct st_x25519_key_exchange_t *)malloc(sizeof(*ctx))) == NULL) + return PTLS_ERROR_NO_MEMORY; + ctx->super = (ptls_key_exchange_context_t){x25519_on_exchange}; + x25519_create_keypair(ctx->priv, ctx->pub); + + *_ctx = &ctx->super; + *pubkey = ptls_iovec_init(ctx->pub, sizeof(ctx->pub)); + return 0; +} + +static int x25519_key_exchange(ptls_iovec_t *pubkey, ptls_iovec_t *secret, ptls_iovec_t peerkey) +{ + uint8_t priv[X25519_KEY_SIZE], *pub = NULL; + int ret; + + if (peerkey.len != X25519_KEY_SIZE) { + ret = PTLS_ALERT_DECRYPT_ERROR; + goto Exit; + } + if ((pub = malloc(X25519_KEY_SIZE)) == NULL) { + ret = PTLS_ERROR_NO_MEMORY; + goto Exit; + } + + x25519_create_keypair(priv, pub); + if ((ret = x25519_derive_secret(secret, NULL, peerkey.base, priv, pub)) != 0) + goto Exit; + + *pubkey = ptls_iovec_init(pub, X25519_KEY_SIZE); + ret = 0; + +Exit: + ptls_clear_memory(priv, sizeof(priv)); + if (pub != NULL && ret != 0) + ptls_clear_memory(pub, X25519_KEY_SIZE); + return ret; +} + +struct aesctr_context_t { + ptls_cipher_context_t super; + cf_aes_context aes; + cf_ctr ctr; +}; + +static void aesctr_dispose(ptls_cipher_context_t *_ctx) +{ + struct aesctr_context_t *ctx = (struct aesctr_context_t *)_ctx; + ptls_clear_memory(ctx, sizeof(*ctx)); +} + +static void aesctr_init(ptls_cipher_context_t *_ctx, const void *iv) +{ + struct aesctr_context_t *ctx = (struct aesctr_context_t *)_ctx; + cf_ctr_init(&ctx->ctr, &cf_aes, &ctx->aes, iv); +} + +static void aesctr_transform(ptls_cipher_context_t *_ctx, void *output, const void *input, size_t len) +{ + struct aesctr_context_t *ctx = (struct aesctr_context_t *)_ctx; + cf_ctr_cipher(&ctx->ctr, input, output, len); +} + +static int aesctr_setup_crypto(ptls_cipher_context_t *_ctx, int is_enc, const void *key, size_t key_size) +{ + struct aesctr_context_t *ctx = (struct aesctr_context_t *)_ctx; + ctx->super.do_dispose = aesctr_dispose; + ctx->super.do_init = aesctr_init; + ctx->super.do_transform = aesctr_transform; + cf_aes_init(&ctx->aes, key, key_size); + return 0; +} + +static int aes128ctr_setup_crypto(ptls_cipher_context_t *ctx, int is_enc, const void *key) +{ + return aesctr_setup_crypto(ctx, is_enc, key, PTLS_AES128_KEY_SIZE); +} + +static int aes256ctr_setup_crypto(ptls_cipher_context_t *ctx, int is_enc, const void *key) +{ + return aesctr_setup_crypto(ctx, is_enc, key, PTLS_AES256_KEY_SIZE); +} + +struct aesgcm_context_t { + ptls_aead_context_t super; + cf_aes_context aes; + cf_gcm_ctx gcm; +}; + +static void aesgcm_dispose_crypto(ptls_aead_context_t *_ctx) +{ + struct aesgcm_context_t *ctx = (struct aesgcm_context_t *)_ctx; + + /* clear all memory except super */ + ptls_clear_memory((uint8_t *)ctx + sizeof(ctx->super), sizeof(*ctx) - sizeof(ctx->super)); +} + +static void aesgcm_encrypt_init(ptls_aead_context_t *_ctx, const void *iv, const void *aad, size_t aadlen) +{ + struct aesgcm_context_t *ctx = (struct aesgcm_context_t *)_ctx; + + cf_gcm_encrypt_init(&cf_aes, &ctx->aes, &ctx->gcm, aad, aadlen, iv, PTLS_AESGCM_IV_SIZE); +} + +static size_t aesgcm_encrypt_update(ptls_aead_context_t *_ctx, void *output, const void *input, size_t inlen) +{ + struct aesgcm_context_t *ctx = (struct aesgcm_context_t *)_ctx; + + cf_gcm_encrypt_update(&ctx->gcm, input, inlen, output); + return inlen; +} + +static size_t aesgcm_encrypt_final(ptls_aead_context_t *_ctx, void *output) +{ + struct aesgcm_context_t *ctx = (struct aesgcm_context_t *)_ctx; + + cf_gcm_encrypt_final(&ctx->gcm, output, PTLS_AESGCM_TAG_SIZE); + return PTLS_AESGCM_TAG_SIZE; +} + +static size_t aesgcm_decrypt(ptls_aead_context_t *_ctx, void *output, const void *input, size_t inlen, const void *iv, + const void *aad, size_t aadlen) +{ + struct aesgcm_context_t *ctx = (struct aesgcm_context_t *)_ctx; + + if (inlen < PTLS_AESGCM_TAG_SIZE) + return SIZE_MAX; + size_t tag_offset = inlen - PTLS_AESGCM_TAG_SIZE; + + if (cf_gcm_decrypt(&cf_aes, &ctx->aes, input, tag_offset, aad, aadlen, iv, PTLS_AESGCM_IV_SIZE, (uint8_t *)input + tag_offset, + PTLS_AESGCM_TAG_SIZE, output) != 0) + return SIZE_MAX; + + return tag_offset; +} + +static int aead_aesgcm_setup_crypto(ptls_aead_context_t *_ctx, int is_enc, const void *key, size_t key_size) +{ + struct aesgcm_context_t *ctx = (struct aesgcm_context_t *)_ctx; + + ctx->super.dispose_crypto = aesgcm_dispose_crypto; + if (is_enc) { + ctx->super.do_encrypt_init = aesgcm_encrypt_init; + ctx->super.do_encrypt_update = aesgcm_encrypt_update; + ctx->super.do_encrypt_final = aesgcm_encrypt_final; + ctx->super.do_decrypt = NULL; + } else { + ctx->super.do_encrypt_init = NULL; + ctx->super.do_encrypt_update = NULL; + ctx->super.do_encrypt_final = NULL; + ctx->super.do_decrypt = aesgcm_decrypt; + } + + cf_aes_init(&ctx->aes, key, key_size); + return 0; +} + +static int aead_aes128gcm_setup_crypto(ptls_aead_context_t *ctx, int is_enc, const void *key) +{ + return aead_aesgcm_setup_crypto(ctx, is_enc, key, PTLS_AES128_KEY_SIZE); +} + +static int aead_aes256gcm_setup_crypto(ptls_aead_context_t *ctx, int is_enc, const void *key) +{ + return aead_aesgcm_setup_crypto(ctx, is_enc, key, PTLS_AES256_KEY_SIZE); +} + +struct chacha20_context_t { + ptls_cipher_context_t super; + cf_chacha20_ctx chacha; + uint8_t key[PTLS_CHACHA20_KEY_SIZE]; +}; + +static void chacha20_dispose(ptls_cipher_context_t *_ctx) +{ + struct chacha20_context_t *ctx = (struct chacha20_context_t *)_ctx; + ptls_clear_memory(ctx, sizeof(*ctx)); +} + +static void chacha20_init(ptls_cipher_context_t *_ctx, const void *iv) +{ + struct chacha20_context_t *ctx = (struct chacha20_context_t *)_ctx; + ctx->chacha.nblock = 0; + ctx->chacha.ncounter = 0; + memcpy(ctx->chacha.nonce, iv, sizeof ctx->chacha.nonce); +} + +static void chacha20_transform(ptls_cipher_context_t *_ctx, void *output, const void *input, size_t len) +{ + struct chacha20_context_t *ctx = (struct chacha20_context_t *)_ctx; + cf_chacha20_cipher(&ctx->chacha, input, output, len); +} + +static int chacha20_setup_crypto(ptls_cipher_context_t *_ctx, int is_enc, const void *key) +{ + struct chacha20_context_t *ctx = (struct chacha20_context_t *)_ctx; + ctx->super.do_dispose = chacha20_dispose; + ctx->super.do_init = chacha20_init; + ctx->super.do_transform = chacha20_transform; + cf_chacha20_init(&ctx->chacha, key, PTLS_CHACHA20_KEY_SIZE, (const uint8_t *)"01234567" /* not used */); + return 0; +} + +struct chacha20poly1305_context_t { + ptls_aead_context_t super; + uint8_t key[PTLS_CHACHA20_KEY_SIZE]; + cf_chacha20_ctx chacha; + cf_poly1305 poly; + size_t aadlen; + size_t textlen; +}; + +static void chacha20poly1305_dispose_crypto(ptls_aead_context_t *_ctx) +{ + struct chacha20poly1305_context_t *ctx = (struct chacha20poly1305_context_t *)_ctx; + + /* clear all memory except super */ + ptls_clear_memory(&ctx->key, sizeof(*ctx) - offsetof(struct chacha20poly1305_context_t, key)); +} + +static const uint8_t zeros64[64] = {0}; + +static void chacha20poly1305_encrypt_pad(cf_poly1305 *poly, size_t n) +{ + if (n % 16 != 0) + cf_poly1305_update(poly, zeros64, 16 - (n % 16)); +} + +static void chacha20poly1305_finalize(struct chacha20poly1305_context_t *ctx, uint8_t *tag) +{ + uint8_t lenbuf[16]; + + chacha20poly1305_encrypt_pad(&ctx->poly, ctx->textlen); + + write64_le(ctx->aadlen, lenbuf); + write64_le(ctx->textlen, lenbuf + 8); + cf_poly1305_update(&ctx->poly, lenbuf, sizeof(lenbuf)); + + cf_poly1305_finish(&ctx->poly, tag); +} + +static void chacha20poly1305_init(ptls_aead_context_t *_ctx, const void *iv, const void *aad, size_t aadlen) +{ + struct chacha20poly1305_context_t *ctx = (struct chacha20poly1305_context_t *)_ctx; + uint8_t tmpbuf[64]; + + /* init chacha */ + memset(tmpbuf, 0, 16 - PTLS_CHACHA20POLY1305_IV_SIZE); + memcpy(tmpbuf + 16 - PTLS_CHACHA20POLY1305_IV_SIZE, iv, PTLS_CHACHA20POLY1305_IV_SIZE); + cf_chacha20_init_custom(&ctx->chacha, ctx->key, sizeof(ctx->key), tmpbuf, 4); + + /* init poly1305 (by using first 16 bytes of the key stream of the first block) */ + cf_chacha20_cipher(&ctx->chacha, zeros64, tmpbuf, 64); + cf_poly1305_init(&ctx->poly, tmpbuf, tmpbuf + 16); + + ptls_clear_memory(tmpbuf, sizeof(tmpbuf)); + + /* aad */ + if (aadlen != 0) { + cf_poly1305_update(&ctx->poly, aad, aadlen); + chacha20poly1305_encrypt_pad(&ctx->poly, aadlen); + } + + ctx->aadlen = aadlen; + ctx->textlen = 0; +} + +static size_t chacha20poly1305_encrypt_update(ptls_aead_context_t *_ctx, void *output, const void *input, size_t inlen) +{ + struct chacha20poly1305_context_t *ctx = (struct chacha20poly1305_context_t *)_ctx; + + cf_chacha20_cipher(&ctx->chacha, input, output, inlen); + cf_poly1305_update(&ctx->poly, output, inlen); + ctx->textlen += inlen; + + return inlen; +} + +static size_t chacha20poly1305_encrypt_final(ptls_aead_context_t *_ctx, void *output) +{ + struct chacha20poly1305_context_t *ctx = (struct chacha20poly1305_context_t *)_ctx; + + chacha20poly1305_finalize(ctx, output); + + ptls_clear_memory(&ctx->chacha, sizeof(ctx->chacha)); + return PTLS_CHACHA20POLY1305_TAG_SIZE; +} + +static size_t chacha20poly1305_decrypt(ptls_aead_context_t *_ctx, void *output, const void *input, size_t inlen, const void *iv, + const void *aad, size_t aadlen) +{ + struct chacha20poly1305_context_t *ctx = (struct chacha20poly1305_context_t *)_ctx; + uint8_t tag[PTLS_CHACHA20POLY1305_TAG_SIZE]; + size_t ret; + + if (inlen < sizeof(tag)) + return SIZE_MAX; + + chacha20poly1305_init(&ctx->super, iv, aad, aadlen); + + cf_poly1305_update(&ctx->poly, input, inlen - sizeof(tag)); + ctx->textlen = inlen - sizeof(tag); + + chacha20poly1305_finalize(ctx, tag); + if (mem_eq(tag, (const uint8_t *)input + inlen - sizeof(tag), sizeof(tag))) { + cf_chacha20_cipher(&ctx->chacha, input, output, inlen - sizeof(tag)); + ret = inlen - sizeof(tag); + } else { + ret = SIZE_MAX; + } + + ptls_clear_memory(tag, sizeof(tag)); + ptls_clear_memory(&ctx->poly, sizeof(ctx->poly)); + + return ret; +} + +static int aead_chacha20poly1305_setup_crypto(ptls_aead_context_t *_ctx, int is_enc, const void *key) +{ + struct chacha20poly1305_context_t *ctx = (struct chacha20poly1305_context_t *)_ctx; + + ctx->super.dispose_crypto = chacha20poly1305_dispose_crypto; + if (is_enc) { + ctx->super.do_encrypt_init = chacha20poly1305_init; + ctx->super.do_encrypt_update = chacha20poly1305_encrypt_update; + ctx->super.do_encrypt_final = chacha20poly1305_encrypt_final; + ctx->super.do_decrypt = NULL; + } else { + ctx->super.do_encrypt_init = NULL; + ctx->super.do_encrypt_update = NULL; + ctx->super.do_encrypt_final = NULL; + ctx->super.do_decrypt = chacha20poly1305_decrypt; + } + + memcpy(ctx->key, key, sizeof(ctx->key)); + return 0; +} + +ptls_define_hash(sha256, cf_sha256_context, cf_sha256_init, cf_sha256_update, cf_sha256_digest_final); +ptls_define_hash(sha384, cf_sha512_context, cf_sha384_init, cf_sha384_update, cf_sha384_digest_final); + +ptls_key_exchange_algorithm_t ptls_minicrypto_x25519 = {PTLS_GROUP_X25519, x25519_create_key_exchange, x25519_key_exchange}; +ptls_cipher_algorithm_t ptls_minicrypto_aes128ctr = {"AES128-CTR", PTLS_AES128_KEY_SIZE, PTLS_AES_IV_SIZE, + sizeof(struct aesctr_context_t), aes128ctr_setup_crypto}; +ptls_aead_algorithm_t ptls_minicrypto_aes128gcm = { + "AES128-GCM", &ptls_minicrypto_aes128ctr, PTLS_AES128_KEY_SIZE, PTLS_AESGCM_IV_SIZE, + PTLS_AESGCM_TAG_SIZE, sizeof(struct aesgcm_context_t), aead_aes128gcm_setup_crypto}; +ptls_cipher_algorithm_t ptls_minicrypto_aes256ctr = {"AES256-CTR", PTLS_AES256_KEY_SIZE, PTLS_AES_IV_SIZE, + sizeof(struct aesctr_context_t), aes256ctr_setup_crypto}; +ptls_aead_algorithm_t ptls_minicrypto_aes256gcm = { + "AES256-GCM", &ptls_minicrypto_aes256ctr, PTLS_AES256_KEY_SIZE, PTLS_AESGCM_IV_SIZE, + PTLS_AESGCM_TAG_SIZE, sizeof(struct aesgcm_context_t), aead_aes256gcm_setup_crypto}; +ptls_hash_algorithm_t ptls_minicrypto_sha256 = {PTLS_SHA256_BLOCK_SIZE, PTLS_SHA256_DIGEST_SIZE, sha256_create, + PTLS_ZERO_DIGEST_SHA256}; +ptls_hash_algorithm_t ptls_minicrypto_sha384 = {PTLS_SHA384_BLOCK_SIZE, PTLS_SHA384_DIGEST_SIZE, sha384_create, + PTLS_ZERO_DIGEST_SHA384}; +ptls_cipher_algorithm_t ptls_minicrypto_chacha20 = {"CHACHA20", PTLS_CHACHA20_KEY_SIZE, PTLS_CHACHA20_IV_SIZE, + sizeof(struct chacha20_context_t), chacha20_setup_crypto}; +ptls_aead_algorithm_t ptls_minicrypto_chacha20poly1305 = {"CHACHA20-POLY1305", + &ptls_minicrypto_chacha20, + PTLS_CHACHA20_KEY_SIZE, + PTLS_CHACHA20POLY1305_IV_SIZE, + PTLS_CHACHA20POLY1305_TAG_SIZE, + sizeof(struct chacha20poly1305_context_t), + aead_chacha20poly1305_setup_crypto}; +ptls_cipher_suite_t ptls_minicrypto_aes128gcmsha256 = {PTLS_CIPHER_SUITE_AES_128_GCM_SHA256, &ptls_minicrypto_aes128gcm, + &ptls_minicrypto_sha256}; +ptls_cipher_suite_t ptls_minicrypto_aes256gcmsha384 = {PTLS_CIPHER_SUITE_AES_256_GCM_SHA384, &ptls_minicrypto_aes256gcm, + &ptls_minicrypto_sha384}; +ptls_cipher_suite_t ptls_minicrypto_chacha20poly1305sha256 = {PTLS_CIPHER_SUITE_CHACHA20_POLY1305_SHA256, + &ptls_minicrypto_chacha20poly1305, &ptls_minicrypto_sha256}; +ptls_cipher_suite_t *ptls_minicrypto_cipher_suites[] = {&ptls_minicrypto_aes256gcmsha384, &ptls_minicrypto_aes128gcmsha256, + &ptls_minicrypto_chacha20poly1305sha256, NULL}; diff --git a/web/server/h2o/libh2o/deps/picotls/lib/minicrypto-pem.c b/web/server/h2o/libh2o/deps/picotls/lib/minicrypto-pem.c new file mode 100644 index 00000000..2b82a91e --- /dev/null +++ b/web/server/h2o/libh2o/deps/picotls/lib/minicrypto-pem.c @@ -0,0 +1,339 @@ +/* + * Copyright (c) 2017,2018 Christian Huitema + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ +#include +#include +#include +#include +#ifdef _WINDOWS +#include "wincompat.h" +#else +#include +#endif +#include "picotls.h" +#include "picotls/minicrypto.h" +#include "picotls/asn1.h" +#include "picotls/pembase64.h" + + +/* + * This function could be declared as static, but we want to access it + * in the unit tests. + */ +size_t ptls_minicrypto_asn1_decode_private_key(ptls_asn1_pkcs8_private_key_t *pkey, int *decode_error, + ptls_minicrypto_log_ctx_t *log_ctx) +{ + uint8_t *bytes = pkey->vec.base; + size_t bytes_max = pkey->vec.len; + + /* read the ASN1 messages */ + size_t byte_index = 0; + uint32_t seq0_length = 0; + size_t last_byte0; + uint32_t seq1_length = 0; + size_t last_byte1 = 0; + uint32_t oid_length; + size_t last_oid_byte; + uint32_t key_data_length; + size_t key_data_last; + + /* start with sequence */ + byte_index = ptls_asn1_get_expected_type_and_length(bytes, bytes_max, byte_index, 0x30, &seq0_length, NULL, &last_byte0, + decode_error, log_ctx); + + if (*decode_error == 0 && bytes_max != last_byte0) { + byte_index = ptls_asn1_error_message("Length larger than message", bytes_max, byte_index, 0, log_ctx); + *decode_error = PTLS_ERROR_BER_EXCESSIVE_LENGTH; + } + + if (*decode_error == 0) { + /* get first component: version, INTEGER, expect value 0 */ + if (byte_index + 3 > bytes_max) { + byte_index = ptls_asn1_error_message("Cannot find key version", bytes_max, byte_index, 0, log_ctx); + *decode_error = PTLS_ERROR_INCORRECT_PEM_KEY_VERSION; + } else if (bytes[byte_index] != 0x02 || bytes[byte_index + 1] != 0x01 || bytes[byte_index + 2] != 0x00) { + *decode_error = PTLS_ERROR_INCORRECT_PEM_KEY_VERSION; + byte_index = ptls_asn1_error_message("Incorrect PEM Version", bytes_max, byte_index, 0, log_ctx); + } else { + byte_index += 3; + if (log_ctx != NULL) { + log_ctx->fn(log_ctx->ctx, " Version = 1,\n"); + } + } + } + + if (*decode_error == 0) { + /* open embedded sequence */ + byte_index = ptls_asn1_get_expected_type_and_length(bytes, bytes_max, byte_index, 0x30, &seq1_length, NULL, &last_byte1, + decode_error, log_ctx); + } + + if (*decode_error == 0) { + if (log_ctx != NULL) { + log_ctx->fn(log_ctx->ctx, " Algorithm Identifier:\n"); + } + /* get length of OID */ + byte_index = ptls_asn1_get_expected_type_and_length(bytes, last_byte1, byte_index, 0x06, &oid_length, NULL, &last_oid_byte, + decode_error, log_ctx); + + if (*decode_error == 0) { + if (log_ctx != NULL) { + /* print the OID value */ + log_ctx->fn(log_ctx->ctx, " Algorithm:"); + ptls_asn1_dump_content(bytes + byte_index, oid_length, 0, log_ctx); + log_ctx->fn(log_ctx->ctx, ",\n"); + } + pkey->algorithm_index = byte_index; + pkey->algorithm_length = oid_length; + byte_index += oid_length; + } + } + + if (*decode_error == 0) { + /* get parameters, ANY */ + if (log_ctx != NULL) { + log_ctx->fn(log_ctx->ctx, " Parameters:\n"); + } + + pkey->parameters_index = byte_index; + + pkey->parameters_length = + ptls_asn1_validation_recursive(bytes + byte_index, last_byte1 - byte_index, decode_error, 2, log_ctx); + + byte_index += pkey->parameters_length; + + if (log_ctx != NULL) { + log_ctx->fn(log_ctx->ctx, "\n"); + } + /* close sequence */ + if (byte_index != last_byte1) { + byte_index = ptls_asn1_error_message("Length larger than element", bytes_max, byte_index, 2, log_ctx); + *decode_error = PTLS_ERROR_BER_ELEMENT_TOO_SHORT; + } + } + + /* get octet string, key */ + if (*decode_error == 0) { + byte_index = ptls_asn1_get_expected_type_and_length(bytes, last_byte0, byte_index, 0x04, &key_data_length, NULL, + &key_data_last, decode_error, log_ctx); + + if (*decode_error == 0) { + pkey->key_data_index = byte_index; + pkey->key_data_length = key_data_length; + byte_index += key_data_length; + + if (log_ctx != NULL) { + log_ctx->fn(log_ctx->ctx, " Key data (%d bytes):\n", key_data_length); + + (void)ptls_asn1_validation_recursive(bytes + pkey->key_data_index, key_data_length, decode_error, 1, log_ctx); + log_ctx->fn(log_ctx->ctx, "\n"); + } + } + } + + if (*decode_error == 0 && byte_index != last_byte0) { + byte_index = ptls_asn1_error_message("Length larger than element", bytes_max, byte_index, 0, log_ctx); + *decode_error = PTLS_ERROR_BER_ELEMENT_TOO_SHORT; + } + + if (log_ctx != NULL) { + log_ctx->fn(log_ctx->ctx, "\n"); + } + + return byte_index; +} + +static int ptls_pem_parse_private_key(char const *pem_fname, ptls_asn1_pkcs8_private_key_t *pkey, + ptls_minicrypto_log_ctx_t *log_ctx) +{ + size_t nb_keys = 0; + int ret = ptls_load_pem_objects(pem_fname, "PRIVATE KEY", &pkey->vec, 1, &nb_keys); + + if (ret == 0) { + if (nb_keys != 1) { + ret = PTLS_ERROR_PEM_LABEL_NOT_FOUND; + } + } + + if (ret == 0 && nb_keys == 1) { + int decode_error = 0; + + if (log_ctx != NULL) { + log_ctx->fn(log_ctx->ctx, "\nFound PRIVATE KEY, length = %d bytes\n", (int)pkey->vec.len); + } + + (void)ptls_minicrypto_asn1_decode_private_key(pkey, &decode_error, log_ctx); + + if (decode_error != 0) { + ret = decode_error; + } + } + + return ret; +} + +static const uint8_t ptls_asn1_algorithm_ecdsa[] = {0x2a, 0x86, 0x48, 0xce, 0x3d, 0x02, 0x01}; + +static const uint8_t ptls_asn1_curve_secp256r1[] = {0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x07}; + +static int ptls_set_ecdsa_private_key(ptls_context_t *ctx, ptls_asn1_pkcs8_private_key_t *pkey, ptls_minicrypto_log_ctx_t *log_ctx) +{ + uint8_t *bytes = pkey->vec.base + pkey->parameters_index; + size_t bytes_max = pkey->parameters_length; + size_t byte_index = 0; + uint8_t *curve_id = NULL; + uint32_t curve_id_length = 0; + int decode_error = 0; + uint32_t seq_length; + size_t last_byte = 0; + uint8_t *ecdsa_key_data = NULL; + uint32_t ecdsa_key_data_length = 0; + size_t ecdsa_key_data_last = 0; + + /* We expect the parameters to include just the curve ID */ + + byte_index = ptls_asn1_get_expected_type_and_length(bytes, bytes_max, byte_index, 0x06, &curve_id_length, NULL, &last_byte, + &decode_error, log_ctx); + + if (decode_error == 0 && bytes_max != last_byte) { + byte_index = ptls_asn1_error_message("Length larger than parameters", bytes_max, byte_index, 0, log_ctx); + decode_error = PTLS_ERROR_BER_EXCESSIVE_LENGTH; + } + + if (decode_error == 0) { + curve_id = bytes + byte_index; + + if (log_ctx != NULL) { + /* print the OID value */ + log_ctx->fn(log_ctx->ctx, "Curve: "); + ptls_asn1_dump_content(curve_id, curve_id_length, 0, log_ctx); + log_ctx->fn(log_ctx->ctx, "\n"); + } + } + + /* We expect the key data to follow the ECDSA structure per RFC 5915 */ + bytes = pkey->vec.base + pkey->key_data_index; + bytes_max = pkey->key_data_length; + byte_index = 0; + + /* decode the wrapping sequence */ + if (decode_error == 0) { + byte_index = ptls_asn1_get_expected_type_and_length(bytes, bytes_max, byte_index, 0x30, &seq_length, NULL, &last_byte, + &decode_error, log_ctx); + } + + if (decode_error == 0 && bytes_max != last_byte) { + byte_index = ptls_asn1_error_message("Length larger than key data", bytes_max, byte_index, 0, log_ctx); + decode_error = PTLS_ERROR_BER_ELEMENT_TOO_SHORT; + } + + /* verify and skip the version number 1 */ + if (decode_error == 0) { + /* get first component: version, INTEGER, expect value 0 */ + if (byte_index + 3 > bytes_max) { + byte_index = ptls_asn1_error_message("Cannot find ECDSA Key Data Version", bytes_max, byte_index, 0, log_ctx); + decode_error = PTLS_ERROR_INCORRECT_ASN1_ECDSA_KEY_SYNTAX; + } else if (bytes[byte_index] != 0x02 || bytes[byte_index + 1] != 0x01 || bytes[byte_index + 2] != 0x01) { + decode_error = PTLS_ERROR_INCORRECT_PEM_ECDSA_KEY_VERSION; + byte_index = ptls_asn1_error_message("Incorrect ECDSA Key Data Version", bytes_max, byte_index, 0, log_ctx); + } else { + byte_index += 3; + if (log_ctx != NULL) { + log_ctx->fn(log_ctx->ctx, "ECDSA Version = 1,\n"); + } + } + } + + /* obtain the octet string that contains the ECDSA private key */ + if (decode_error == 0) { + byte_index = ptls_asn1_get_expected_type_and_length(bytes, last_byte, byte_index, 0x04, &ecdsa_key_data_length, NULL, + &ecdsa_key_data_last, &decode_error, log_ctx); + + if (decode_error == 0) { + ecdsa_key_data = bytes + byte_index; + } + } + + /* If everything is fine, associate the ECDSA key with the context */ + if (curve_id_length == sizeof(ptls_asn1_curve_secp256r1) && curve_id != NULL && + memcmp(curve_id, ptls_asn1_curve_secp256r1, sizeof(ptls_asn1_curve_secp256r1)) == 0) { + if (SECP256R1_PRIVATE_KEY_SIZE != ecdsa_key_data_length) { + decode_error = PTLS_ERROR_INCORRECT_PEM_ECDSA_KEYSIZE; + if (log_ctx != NULL) { + /* print the OID value */ + log_ctx->fn(log_ctx->ctx, "Wrong SECP256R1 key length, %d instead of %d.\n", ecdsa_key_data_length, + SECP256R1_PRIVATE_KEY_SIZE); + } + } else { + ptls_minicrypto_secp256r1sha256_sign_certificate_t *minicrypto_sign_certificate; + + minicrypto_sign_certificate = (ptls_minicrypto_secp256r1sha256_sign_certificate_t *)malloc( + sizeof(ptls_minicrypto_secp256r1sha256_sign_certificate_t)); + + if (minicrypto_sign_certificate == NULL) { + decode_error = PTLS_ERROR_NO_MEMORY; + } else { + memset(minicrypto_sign_certificate, 0, sizeof(ptls_minicrypto_secp256r1sha256_sign_certificate_t)); + decode_error = ptls_minicrypto_init_secp256r1sha256_sign_certificate( + minicrypto_sign_certificate, ptls_iovec_init(ecdsa_key_data, ecdsa_key_data_length)); + } + if (decode_error == 0) { + ctx->sign_certificate = &minicrypto_sign_certificate->super; + + if (log_ctx != NULL) { + /* print the OID value */ + log_ctx->fn(log_ctx->ctx, "Initialized SECP512R1 signing key with %d bytes.\n", ecdsa_key_data_length); + } + } else if (log_ctx != NULL) { + log_ctx->fn(log_ctx->ctx, "SECP512R1 init with %d bytes returns %d.\n", ecdsa_key_data_length, decode_error); + } + } + } else { + decode_error = PTLS_ERROR_INCORRECT_PEM_ECDSA_CURVE; + if (log_ctx != NULL) { + /* print the OID value */ + log_ctx->fn(log_ctx->ctx, "Curve is not supported for signatures.\n"); + } + } + + return decode_error; +} + +int ptls_minicrypto_load_private_key(ptls_context_t *ctx, char const *pem_fname) +{ + ptls_asn1_pkcs8_private_key_t pkey = {{0}}; + int ret = ptls_pem_parse_private_key(pem_fname, &pkey, NULL); + + /* Check that this is the expected key type. + * At this point, the minicrypto library only supports ECDSA keys. + * In theory, we could add support for RSA keys at some point. + */ + if (ret == 0) { + if (pkey.algorithm_length == sizeof(ptls_asn1_algorithm_ecdsa) && + memcmp(pkey.vec.base + pkey.algorithm_index, ptls_asn1_algorithm_ecdsa, sizeof(ptls_asn1_algorithm_ecdsa)) == 0) { + ret = ptls_set_ecdsa_private_key(ctx, &pkey, NULL); + } else { + ret = -1; + } + } + + return ret; +} diff --git a/web/server/h2o/libh2o/deps/picotls/lib/openssl.c b/web/server/h2o/libh2o/deps/picotls/lib/openssl.c new file mode 100644 index 00000000..2c9ee700 --- /dev/null +++ b/web/server/h2o/libh2o/deps/picotls/lib/openssl.c @@ -0,0 +1,1066 @@ +/* + * Copyright (c) 2016 DeNA Co., Ltd., Kazuho Oku + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#ifdef _WINDOWS +#include "wincompat.h" +#else +#include +#endif +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "picotls.h" +#include "picotls/openssl.h" + +#if !defined(LIBRESSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER >= 0x10100000L +#define OPENSSL_1_1_API 1 +#elif defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER >= 0x2070000fL +#define OPENSSL_1_1_API 1 +#else +#define OPENSSL_1_1_API 0 +#endif + +#if !OPENSSL_1_1_API + +#define EVP_PKEY_up_ref(p) CRYPTO_add(&(p)->references, 1, CRYPTO_LOCK_EVP_PKEY) +#define X509_STORE_up_ref(p) CRYPTO_add(&(p)->references, 1, CRYPTO_LOCK_X509_STORE) + +static HMAC_CTX *HMAC_CTX_new(void) +{ + HMAC_CTX *ctx; + + if ((ctx = OPENSSL_malloc(sizeof(*ctx))) == NULL) + return NULL; + HMAC_CTX_init(ctx); + return ctx; +} + +static void HMAC_CTX_free(HMAC_CTX *ctx) +{ + HMAC_CTX_cleanup(ctx); + OPENSSL_free(ctx); +} + +#endif + +void ptls_openssl_random_bytes(void *buf, size_t len) +{ + RAND_bytes(buf, (int)len); +} + +static EC_KEY *ecdh_gerenate_key(EC_GROUP *group) +{ + EC_KEY *key; + + if ((key = EC_KEY_new()) == NULL) + return NULL; + if (!EC_KEY_set_group(key, group) || !EC_KEY_generate_key(key)) { + EC_KEY_free(key); + return NULL; + } + + return key; +} + +static int ecdh_calc_secret(ptls_iovec_t *out, EC_GROUP *group, EC_KEY *privkey, EC_POINT *peer_point) +{ + ptls_iovec_t secret; + int ret; + + secret.len = (EC_GROUP_get_degree(group) + 7) / 8; + if ((secret.base = malloc(secret.len)) == NULL) { + ret = PTLS_ERROR_NO_MEMORY; + goto Exit; + } + if (ECDH_compute_key(secret.base, secret.len, peer_point, privkey, NULL) <= 0) { + ret = PTLS_ALERT_HANDSHAKE_FAILURE; /* ??? */ + goto Exit; + } + ret = 0; + +Exit: + if (ret == 0) { + *out = secret; + } else { + free(secret.base); + *out = (ptls_iovec_t){NULL}; + } + return ret; +} + +static EC_POINT *x9_62_decode_point(EC_GROUP *group, ptls_iovec_t vec, BN_CTX *bn_ctx) +{ + EC_POINT *point = NULL; + + if ((point = EC_POINT_new(group)) == NULL) + return NULL; + if (!EC_POINT_oct2point(group, point, vec.base, vec.len, bn_ctx)) { + EC_POINT_free(point); + return NULL; + } + + return point; +} + +static ptls_iovec_t x9_62_encode_point(EC_GROUP *group, const EC_POINT *point, BN_CTX *bn_ctx) +{ + ptls_iovec_t vec; + + if ((vec.len = EC_POINT_point2oct(group, point, POINT_CONVERSION_UNCOMPRESSED, NULL, 0, bn_ctx)) == 0) + return (ptls_iovec_t){NULL}; + if ((vec.base = malloc(vec.len)) == NULL) + return (ptls_iovec_t){NULL}; + if (EC_POINT_point2oct(group, point, POINT_CONVERSION_UNCOMPRESSED, vec.base, vec.len, bn_ctx) != vec.len) { + free(vec.base); + return (ptls_iovec_t){NULL}; + } + + return vec; +} + +struct st_x9_62_keyex_context_t { + ptls_key_exchange_context_t super; + BN_CTX *bn_ctx; + EC_GROUP *group; + EC_KEY *privkey; + ptls_iovec_t pubkey; +}; + +static void x9_62_free_context(struct st_x9_62_keyex_context_t *ctx) +{ + free(ctx->pubkey.base); + if (ctx->privkey != NULL) + EC_KEY_free(ctx->privkey); + if (ctx->group != NULL) + EC_GROUP_free(ctx->group); + if (ctx->bn_ctx != NULL) + BN_CTX_free(ctx->bn_ctx); + free(ctx); +} + +static int x9_62_on_exchange(ptls_key_exchange_context_t **_ctx, ptls_iovec_t *secret, ptls_iovec_t peerkey) +{ + struct st_x9_62_keyex_context_t *ctx = (struct st_x9_62_keyex_context_t *)*_ctx; + EC_POINT *peer_point = NULL; + int ret; + + *_ctx = NULL; + + if ((peer_point = x9_62_decode_point(ctx->group, peerkey, ctx->bn_ctx)) == NULL) { + ret = PTLS_ALERT_DECODE_ERROR; + goto Exit; + } + if ((ret = ecdh_calc_secret(secret, ctx->group, ctx->privkey, peer_point)) != 0) + goto Exit; + +Exit: + if (peer_point != NULL) + EC_POINT_free(peer_point); + x9_62_free_context(ctx); + return ret; +} + +static int x9_62_create_key_exchange(ptls_key_exchange_context_t **_ctx, ptls_iovec_t *pubkey, int nid) +{ + struct st_x9_62_keyex_context_t *ctx = NULL; + int ret; + + if ((ctx = (struct st_x9_62_keyex_context_t *)malloc(sizeof(*ctx))) == NULL) { + ret = PTLS_ERROR_NO_MEMORY; + goto Exit; + } + *ctx = (struct st_x9_62_keyex_context_t){{x9_62_on_exchange}}; + + if ((ctx->bn_ctx = BN_CTX_new()) == NULL) { + ret = PTLS_ERROR_NO_MEMORY; + goto Exit; + } + if ((ctx->group = EC_GROUP_new_by_curve_name(nid)) == NULL) { + ret = PTLS_ERROR_LIBRARY; + goto Exit; + } + if ((ctx->privkey = ecdh_gerenate_key(ctx->group)) == NULL) { + ret = PTLS_ERROR_LIBRARY; + goto Exit; + } + + if ((ctx->pubkey = x9_62_encode_point(ctx->group, EC_KEY_get0_public_key(ctx->privkey), ctx->bn_ctx)).base == NULL) { + ret = PTLS_ERROR_NO_MEMORY; + goto Exit; + } + + *pubkey = ctx->pubkey; + ret = 0; + +Exit: + if (ret == 0) { + *_ctx = &ctx->super; + } else { + if (ctx != NULL) + x9_62_free_context(ctx); + *_ctx = NULL; + *pubkey = (ptls_iovec_t){NULL}; + } + + return ret; +} + +static int secp256r1_create_key_exchange(ptls_key_exchange_context_t **ctx, ptls_iovec_t *pubkey) +{ + return x9_62_create_key_exchange(ctx, pubkey, NID_X9_62_prime256v1); +} + +static int x9_62_key_exchange(EC_GROUP *group, ptls_iovec_t *pubkey, ptls_iovec_t *secret, ptls_iovec_t peerkey, BN_CTX *bn_ctx) +{ + EC_POINT *peer_point = NULL; + EC_KEY *privkey = NULL; + int ret; + + *pubkey = (ptls_iovec_t){NULL}; + *secret = (ptls_iovec_t){NULL}; + + /* decode peer key */ + if ((peer_point = x9_62_decode_point(group, peerkey, bn_ctx)) == NULL) { + ret = PTLS_ALERT_DECODE_ERROR; + goto Exit; + } + + /* create private key */ + if ((privkey = ecdh_gerenate_key(group)) == NULL) { + ret = PTLS_ERROR_NO_MEMORY; + goto Exit; + } + + /* encode public key */ + if ((*pubkey = x9_62_encode_point(group, EC_KEY_get0_public_key(privkey), bn_ctx)).base == NULL) { + ret = PTLS_ERROR_NO_MEMORY; + goto Exit; + } + + /* calc secret */ + secret->len = (EC_GROUP_get_degree(group) + 7) / 8; + if ((secret->base = malloc(secret->len)) == NULL) { + ret = PTLS_ERROR_NO_MEMORY; + goto Exit; + } + + /* ecdh! */ + if (ECDH_compute_key(secret->base, secret->len, peer_point, privkey, NULL) <= 0) { + ret = PTLS_ALERT_HANDSHAKE_FAILURE; /* ??? */ + goto Exit; + } + + ret = 0; + +Exit: + if (peer_point != NULL) + EC_POINT_free(peer_point); + if (privkey != NULL) + EC_KEY_free(privkey); + if (ret != 0) { + free(pubkey->base); + *pubkey = (ptls_iovec_t){NULL}; + free(secret->base); + *secret = (ptls_iovec_t){NULL}; + } + return ret; +} + +static int secp_key_exchange(int nid, ptls_iovec_t *pubkey, ptls_iovec_t *secret, ptls_iovec_t peerkey) +{ + EC_GROUP *group = NULL; + BN_CTX *bn_ctx = NULL; + int ret; + + if ((group = EC_GROUP_new_by_curve_name(nid)) == NULL) { + ret = PTLS_ERROR_LIBRARY; + goto Exit; + } + if ((bn_ctx = BN_CTX_new()) == NULL) { + ret = PTLS_ERROR_NO_MEMORY; + goto Exit; + } + + ret = x9_62_key_exchange(group, pubkey, secret, peerkey, bn_ctx); + +Exit: + if (bn_ctx != NULL) + BN_CTX_free(bn_ctx); + if (group != NULL) + EC_GROUP_free(group); + return ret; +} + +static int secp256r1_key_exchange(ptls_iovec_t *pubkey, ptls_iovec_t *secret, ptls_iovec_t peerkey) +{ + return secp_key_exchange(NID_X9_62_prime256v1, pubkey, secret, peerkey); +} + +static int do_sign(EVP_PKEY *key, ptls_buffer_t *outbuf, ptls_iovec_t input, const EVP_MD *md) +{ + EVP_MD_CTX *ctx = NULL; + EVP_PKEY_CTX *pkey_ctx; + size_t siglen; + int ret; + + if ((ctx = EVP_MD_CTX_create()) == NULL) { + ret = PTLS_ERROR_NO_MEMORY; + goto Exit; + } + if (EVP_DigestSignInit(ctx, &pkey_ctx, md, NULL, key) != 1) { + ret = PTLS_ERROR_LIBRARY; + goto Exit; + } + if (EVP_PKEY_id(key) == EVP_PKEY_RSA) { + if (EVP_PKEY_CTX_set_rsa_padding(pkey_ctx, RSA_PKCS1_PSS_PADDING) != 1) { + ret = PTLS_ERROR_LIBRARY; + goto Exit; + } + if (EVP_PKEY_CTX_set_rsa_pss_saltlen(pkey_ctx, -1) != 1) { + ret = PTLS_ERROR_LIBRARY; + goto Exit; + } + if (EVP_PKEY_CTX_set_rsa_mgf1_md(pkey_ctx, EVP_sha256()) != 1) { + ret = PTLS_ERROR_LIBRARY; + goto Exit; + } + } + if (EVP_DigestSignUpdate(ctx, input.base, input.len) != 1) { + ret = PTLS_ERROR_LIBRARY; + goto Exit; + } + if (EVP_DigestSignFinal(ctx, NULL, &siglen) != 1) { + ret = PTLS_ERROR_LIBRARY; + goto Exit; + } + if ((ret = ptls_buffer_reserve(outbuf, siglen)) != 0) + goto Exit; + if (EVP_DigestSignFinal(ctx, outbuf->base + outbuf->off, &siglen) != 1) { + ret = PTLS_ERROR_LIBRARY; + goto Exit; + } + outbuf->off += siglen; + + ret = 0; +Exit: + if (ctx != NULL) + EVP_MD_CTX_destroy(ctx); + return ret; +} + +struct cipher_context_t { + ptls_cipher_context_t super; + EVP_CIPHER_CTX *evp; +}; + +static void cipher_dispose(ptls_cipher_context_t *_ctx) +{ + struct cipher_context_t *ctx = (struct cipher_context_t *)_ctx; + EVP_CIPHER_CTX_free(ctx->evp); +} + +static void cipher_do_init(ptls_cipher_context_t *_ctx, const void *iv) +{ + struct cipher_context_t *ctx = (struct cipher_context_t *)_ctx; + int ret; + ret = EVP_EncryptInit_ex(ctx->evp, NULL, NULL, NULL, iv); + assert(ret); +} + +static int cipher_setup_crypto(ptls_cipher_context_t *_ctx, const void *key, const EVP_CIPHER *cipher, + void (*do_transform)(ptls_cipher_context_t *, void *, const void *, size_t)) +{ + struct cipher_context_t *ctx = (struct cipher_context_t *)_ctx; + + ctx->super.do_dispose = cipher_dispose; + ctx->super.do_init = cipher_do_init; + ctx->super.do_transform = do_transform; + + if ((ctx->evp = EVP_CIPHER_CTX_new()) == NULL) + return PTLS_ERROR_NO_MEMORY; + if (!EVP_EncryptInit_ex(ctx->evp, cipher, NULL, key, NULL)) { + EVP_CIPHER_CTX_free(ctx->evp); + return PTLS_ERROR_LIBRARY; + } + + return 0; +} + +static void cipher_encrypt(ptls_cipher_context_t *_ctx, void *output, const void *input, size_t _len) +{ + struct cipher_context_t *ctx = (struct cipher_context_t *)_ctx; + int len = (int)_len, ret = EVP_EncryptUpdate(ctx->evp, output, &len, input, len); + assert(ret); +} + +static int aes128ctr_setup_crypto(ptls_cipher_context_t *ctx, int is_enc, const void *key) +{ + return cipher_setup_crypto(ctx, key, EVP_aes_128_ctr(), cipher_encrypt); +} + +static int aes256ctr_setup_crypto(ptls_cipher_context_t *ctx, int is_enc, const void *key) +{ + return cipher_setup_crypto(ctx, key, EVP_aes_256_ctr(), cipher_encrypt); +} + +#if defined(PTLS_OPENSSL_HAVE_CHACHA20_POLY1305) + +static int chacha20_setup_crypto(ptls_cipher_context_t *ctx, int is_enc, const void *key) +{ + return cipher_setup_crypto(ctx, key, EVP_chacha20(), cipher_encrypt); +} + +#endif + +struct aead_crypto_context_t { + ptls_aead_context_t super; + EVP_CIPHER_CTX *evp_ctx; +}; + +static void aead_dispose_crypto(ptls_aead_context_t *_ctx) +{ + struct aead_crypto_context_t *ctx = (struct aead_crypto_context_t *)_ctx; + + if (ctx->evp_ctx != NULL) + EVP_CIPHER_CTX_free(ctx->evp_ctx); +} + +static void aead_do_encrypt_init(ptls_aead_context_t *_ctx, const void *iv, const void *aad, size_t aadlen) +{ + struct aead_crypto_context_t *ctx = (struct aead_crypto_context_t *)_ctx; + int ret; + + /* FIXME for performance, preserve the expanded key instead of the raw key */ + ret = EVP_EncryptInit_ex(ctx->evp_ctx, NULL, NULL, NULL, iv); + assert(ret); + + if (aadlen != 0) { + int blocklen; + ret = EVP_EncryptUpdate(ctx->evp_ctx, NULL, &blocklen, aad, (int)aadlen); + assert(ret); + } +} + +static size_t aead_do_encrypt_update(ptls_aead_context_t *_ctx, void *output, const void *input, size_t inlen) +{ + struct aead_crypto_context_t *ctx = (struct aead_crypto_context_t *)_ctx; + int blocklen, ret; + + ret = EVP_EncryptUpdate(ctx->evp_ctx, output, &blocklen, input, (int)inlen); + assert(ret); + + return blocklen; +} + +static size_t aead_do_encrypt_final(ptls_aead_context_t *_ctx, void *_output) +{ + struct aead_crypto_context_t *ctx = (struct aead_crypto_context_t *)_ctx; + uint8_t *output = _output; + size_t off = 0, tag_size = ctx->super.algo->tag_size; + int blocklen, ret; + + ret = EVP_EncryptFinal_ex(ctx->evp_ctx, output + off, &blocklen); + assert(ret); + off += blocklen; + ret = EVP_CIPHER_CTX_ctrl(ctx->evp_ctx, EVP_CTRL_GCM_GET_TAG, (int)tag_size, output + off); + assert(ret); + off += tag_size; + + return off; +} + +static size_t aead_do_decrypt(ptls_aead_context_t *_ctx, void *_output, const void *input, size_t inlen, const void *iv, + const void *aad, size_t aadlen) +{ + struct aead_crypto_context_t *ctx = (struct aead_crypto_context_t *)_ctx; + uint8_t *output = _output; + size_t off = 0, tag_size = ctx->super.algo->tag_size; + int blocklen, ret; + + if (inlen < tag_size) + return SIZE_MAX; + + ret = EVP_DecryptInit_ex(ctx->evp_ctx, NULL, NULL, NULL, iv); + assert(ret); + if (aadlen != 0) { + ret = EVP_DecryptUpdate(ctx->evp_ctx, NULL, &blocklen, aad, (int)aadlen); + assert(ret); + } + ret = EVP_DecryptUpdate(ctx->evp_ctx, output + off, &blocklen, input, (int)(inlen - tag_size)); + assert(ret); + off += blocklen; + if (!EVP_CIPHER_CTX_ctrl(ctx->evp_ctx, EVP_CTRL_GCM_SET_TAG, (int)tag_size, (void *)((uint8_t *)input + inlen - tag_size))) + return SIZE_MAX; + if (!EVP_DecryptFinal_ex(ctx->evp_ctx, output + off, &blocklen)) + return SIZE_MAX; + off += blocklen; + + return off; +} + +static int aead_setup_crypto(ptls_aead_context_t *_ctx, int is_enc, const void *key, const EVP_CIPHER *cipher) +{ + struct aead_crypto_context_t *ctx = (struct aead_crypto_context_t *)_ctx; + int ret; + + ctx->super.dispose_crypto = aead_dispose_crypto; + if (is_enc) { + ctx->super.do_encrypt_init = aead_do_encrypt_init; + ctx->super.do_encrypt_update = aead_do_encrypt_update; + ctx->super.do_encrypt_final = aead_do_encrypt_final; + ctx->super.do_decrypt = NULL; + } else { + ctx->super.do_encrypt_init = NULL; + ctx->super.do_encrypt_update = NULL; + ctx->super.do_encrypt_final = NULL; + ctx->super.do_decrypt = aead_do_decrypt; + } + ctx->evp_ctx = NULL; + + if ((ctx->evp_ctx = EVP_CIPHER_CTX_new()) == NULL) { + ret = PTLS_ERROR_NO_MEMORY; + goto Error; + } + if (is_enc) { + if (!EVP_EncryptInit_ex(ctx->evp_ctx, cipher, NULL, key, NULL)) { + ret = PTLS_ERROR_LIBRARY; + goto Error; + } + } else { + if (!EVP_DecryptInit_ex(ctx->evp_ctx, cipher, NULL, key, NULL)) { + ret = PTLS_ERROR_LIBRARY; + goto Error; + } + } + if (!EVP_CIPHER_CTX_ctrl(ctx->evp_ctx, EVP_CTRL_GCM_SET_IVLEN, (int)ctx->super.algo->iv_size, NULL)) { + ret = PTLS_ERROR_LIBRARY; + goto Error; + } + + return 0; + +Error: + aead_dispose_crypto(&ctx->super); + return ret; +} + +static int aead_aes128gcm_setup_crypto(ptls_aead_context_t *ctx, int is_enc, const void *key) +{ + return aead_setup_crypto(ctx, is_enc, key, EVP_aes_128_gcm()); +} + +static int aead_aes256gcm_setup_crypto(ptls_aead_context_t *ctx, int is_enc, const void *key) +{ + return aead_setup_crypto(ctx, is_enc, key, EVP_aes_256_gcm()); +} + +#if defined(PTLS_OPENSSL_HAVE_CHACHA20_POLY1305) +static int aead_chacha20poly1305_setup_crypto(ptls_aead_context_t *ctx, int is_enc, const void *key) +{ + return aead_setup_crypto(ctx, is_enc, key, EVP_chacha20_poly1305()); +} +#endif + +#define _sha256_final(ctx, md) SHA256_Final((md), (ctx)) +ptls_define_hash(sha256, SHA256_CTX, SHA256_Init, SHA256_Update, _sha256_final); + +#define _sha384_final(ctx, md) SHA384_Final((md), (ctx)) +ptls_define_hash(sha384, SHA512_CTX, SHA384_Init, SHA384_Update, _sha384_final); + +static int sign_certificate(ptls_sign_certificate_t *_self, ptls_t *tls, uint16_t *selected_algorithm, ptls_buffer_t *outbuf, + ptls_iovec_t input, const uint16_t *algorithms, size_t num_algorithms) +{ + ptls_openssl_sign_certificate_t *self = (ptls_openssl_sign_certificate_t *)_self; + const struct st_ptls_openssl_signature_scheme_t *scheme; + + /* select the algorithm */ + for (scheme = self->schemes; scheme->scheme_id != UINT16_MAX; ++scheme) { + size_t i; + for (i = 0; i != num_algorithms; ++i) + if (algorithms[i] == scheme->scheme_id) + goto Found; + } + return PTLS_ALERT_HANDSHAKE_FAILURE; + +Found: + *selected_algorithm = scheme->scheme_id; + return do_sign(self->key, outbuf, input, scheme->scheme_md); +} + +static X509 *to_x509(ptls_iovec_t vec) +{ + const uint8_t *p = vec.base; + return d2i_X509(NULL, &p, vec.len); +} + +static int verify_sign(void *verify_ctx, ptls_iovec_t data, ptls_iovec_t signature) +{ + EVP_PKEY *key = verify_ctx; + EVP_MD_CTX *ctx = NULL; + EVP_PKEY_CTX *pkey_ctx = NULL; + int ret = 0; + + if (data.base == NULL) + goto Exit; + + if ((ctx = EVP_MD_CTX_create()) == NULL) { + ret = PTLS_ERROR_NO_MEMORY; + goto Exit; + } + if (EVP_DigestVerifyInit(ctx, &pkey_ctx, EVP_sha256(), NULL, key) != 1) { + ret = PTLS_ERROR_LIBRARY; + goto Exit; + } + if (EVP_PKEY_id(key) == EVP_PKEY_RSA) { + if (EVP_PKEY_CTX_set_rsa_padding(pkey_ctx, RSA_PKCS1_PSS_PADDING) != 1) { + ret = PTLS_ERROR_LIBRARY; + goto Exit; + } + if (EVP_PKEY_CTX_set_rsa_pss_saltlen(pkey_ctx, -1) != 1) { + ret = PTLS_ERROR_LIBRARY; + goto Exit; + } + if (EVP_PKEY_CTX_set_rsa_mgf1_md(pkey_ctx, EVP_sha256()) != 1) { + ret = PTLS_ERROR_LIBRARY; + goto Exit; + } + } + if (EVP_DigestVerifyUpdate(ctx, data.base, data.len) != 1) { + ret = PTLS_ERROR_LIBRARY; + goto Exit; + } + if (EVP_DigestVerifyFinal(ctx, signature.base, signature.len) != 1) { + ret = PTLS_ALERT_DECRYPT_ERROR; + goto Exit; + } + ret = 0; + +Exit: + if (ctx != NULL) + EVP_MD_CTX_destroy(ctx); + EVP_PKEY_free(key); + return ret; +} + +int ptls_openssl_init_sign_certificate(ptls_openssl_sign_certificate_t *self, EVP_PKEY *key) +{ + *self = (ptls_openssl_sign_certificate_t){{sign_certificate}}; + size_t scheme_index = 0; + +#define PUSH_SCHEME(id, md) \ + self->schemes[scheme_index++] = (struct st_ptls_openssl_signature_scheme_t) \ + { \ + id, md \ + } + + switch (EVP_PKEY_id(key)) { + case EVP_PKEY_RSA: + PUSH_SCHEME(PTLS_SIGNATURE_RSA_PSS_RSAE_SHA256, EVP_sha256()); + PUSH_SCHEME(PTLS_SIGNATURE_RSA_PSS_RSAE_SHA384, EVP_sha384()); + PUSH_SCHEME(PTLS_SIGNATURE_RSA_PSS_RSAE_SHA512, EVP_sha512()); + break; + case EVP_PKEY_EC: { + EC_KEY *eckey = EVP_PKEY_get1_EC_KEY(key); + switch (EC_GROUP_get_curve_name(EC_KEY_get0_group(eckey))) { + case NID_X9_62_prime256v1: + PUSH_SCHEME(PTLS_SIGNATURE_ECDSA_SECP256R1_SHA256, EVP_sha256()); + break; +#if defined(NID_secp384r1) && !OPENSSL_NO_SHA384 + case NID_secp384r1: + PUSH_SCHEME(PTLS_SIGNATURE_ECDSA_SECP384R1_SHA384, EVP_sha384()); + break; +#endif +#if defined(NID_secp384r1) && !OPENSSL_NO_SHA512 + case NID_secp521r1: + PUSH_SCHEME(PTLS_SIGNATURE_ECDSA_SECP521R1_SHA512, EVP_sha512()); + break; +#endif + default: + EC_KEY_free(eckey); + return PTLS_ERROR_INCOMPATIBLE_KEY; + } + EC_KEY_free(eckey); + } break; + default: + return PTLS_ERROR_INCOMPATIBLE_KEY; + } + PUSH_SCHEME(UINT16_MAX, NULL); + assert(scheme_index <= sizeof(self->schemes) / sizeof(self->schemes[0])); + +#undef PUSH_SCHEME + + EVP_PKEY_up_ref(key); + self->key = key; + + return 0; +} + +void ptls_openssl_dispose_sign_certificate(ptls_openssl_sign_certificate_t *self) +{ + EVP_PKEY_free(self->key); +} + +static int serialize_cert(X509 *cert, ptls_iovec_t *dst) +{ + int len = i2d_X509(cert, NULL); + assert(len > 0); + + if ((dst->base = malloc(len)) == NULL) + return PTLS_ERROR_NO_MEMORY; + unsigned char *p = dst->base; + dst->len = i2d_X509(cert, &p); + assert(len == dst->len); + + return 0; +} + +int ptls_openssl_load_certificates(ptls_context_t *ctx, X509 *cert, STACK_OF(X509) * chain) +{ + ptls_iovec_t *list = NULL; + size_t slot = 0, count = (cert != NULL) + (chain != NULL ? sk_X509_num(chain) : 0); + int ret; + + assert(ctx->certificates.list == NULL); + + if ((list = malloc(sizeof(*list) * count)) == NULL) { + ret = PTLS_ERROR_NO_MEMORY; + goto Exit; + } + if (cert != NULL) { + if ((ret = serialize_cert(cert, list + slot++)) != 0) + goto Exit; + } + if (chain != NULL) { + int i; + for (i = 0; i != sk_X509_num(chain); ++i) { + if ((ret = serialize_cert(sk_X509_value(chain, i), list + slot++)) != 0) + goto Exit; + } + } + + assert(slot == count); + + ctx->certificates.list = list; + ctx->certificates.count = count; + ret = 0; + +Exit: + if (ret != 0 && list != NULL) { + size_t i; + for (i = 0; i != slot; ++i) + free(list[i].base); + free(list); + } + return ret; +} + +static int verify_certificate(ptls_verify_certificate_t *_self, ptls_t *tls, int (**verifier)(void *, ptls_iovec_t, ptls_iovec_t), + void **verify_data, ptls_iovec_t *certs, size_t num_certs) +{ + ptls_openssl_verify_certificate_t *self = (ptls_openssl_verify_certificate_t *)_self; + X509 *cert = NULL; + STACK_OF(X509) *chain = NULL; + X509_STORE_CTX *verify_ctx = NULL; + int ret = 0; + + assert(num_certs != 0); + + if ((cert = to_x509(certs[0])) == NULL) { + ret = PTLS_ALERT_BAD_CERTIFICATE; + goto Exit; + } + + if (self->cert_store != NULL) { + size_t i; + for (i = 1; i != num_certs; ++i) { + X509 *interm = to_x509(certs[i]); + if (interm == NULL) { + ret = PTLS_ALERT_BAD_CERTIFICATE; + goto Exit; + } + } + if ((verify_ctx = X509_STORE_CTX_new()) == NULL) { + ret = PTLS_ERROR_NO_MEMORY; + goto Exit; + } + if (X509_STORE_CTX_init(verify_ctx, self->cert_store, cert, chain) != 1) { + ret = PTLS_ERROR_LIBRARY; + goto Exit; + } + X509_STORE_CTX_set_purpose(verify_ctx, X509_PURPOSE_SSL_CLIENT); + if (X509_verify_cert(verify_ctx) == 1) { + ret = 0; + } else { + switch (X509_STORE_CTX_get_error(verify_ctx)) { + case X509_V_ERR_OUT_OF_MEM: + ret = PTLS_ERROR_NO_MEMORY; + goto Exit; + case X509_V_ERR_CERT_REVOKED: + ret = PTLS_ALERT_CERTIFICATE_REVOKED; + goto Exit; + case X509_V_ERR_CERT_HAS_EXPIRED: + ret = PTLS_ALERT_CERTIFICATE_EXPIRED; + goto Exit; + default: + ret = PTLS_ALERT_CERTIFICATE_UNKNOWN; + goto Exit; + } + } + } + + if ((*verify_data = X509_get_pubkey(cert)) == NULL) { + ret = PTLS_ALERT_BAD_CERTIFICATE; + goto Exit; + } + *verifier = verify_sign; + +Exit: + if (verify_ctx != NULL) + X509_STORE_CTX_free(verify_ctx); + if (chain != NULL) + sk_X509_free(chain); + if (cert != NULL) + X509_free(cert); + return ret; +} + +int ptls_openssl_init_verify_certificate(ptls_openssl_verify_certificate_t *self, X509_STORE *store) +{ + *self = (ptls_openssl_verify_certificate_t){{verify_certificate}}; + + if (store != NULL) { + if (store != PTLS_OPENSSL_DEFAULT_CERTIFICATE_STORE) { + X509_STORE_up_ref(store); + self->cert_store = store; + } else { + X509_LOOKUP *lookup; + if ((self->cert_store = X509_STORE_new()) == NULL) + return -1; + if ((lookup = X509_STORE_add_lookup(self->cert_store, X509_LOOKUP_file())) == NULL) + return -1; + X509_LOOKUP_load_file(lookup, NULL, X509_FILETYPE_DEFAULT); + if ((lookup = X509_STORE_add_lookup(self->cert_store, X509_LOOKUP_hash_dir())) == NULL) + return -1; + X509_LOOKUP_add_dir(lookup, NULL, X509_FILETYPE_DEFAULT); + } + } + + return 0; +} + +void ptls_openssl_dispose_verify_certificate(ptls_openssl_verify_certificate_t *self) +{ + X509_STORE_free(self->cert_store); + free(self); +} + +#define TICKET_LABEL_SIZE 16 +#define TICKET_IV_SIZE EVP_MAX_IV_LENGTH + +int ptls_openssl_encrypt_ticket(ptls_buffer_t *buf, ptls_iovec_t src, + int (*cb)(unsigned char *key_name, unsigned char *iv, EVP_CIPHER_CTX *ctx, HMAC_CTX *hctx, int enc)) +{ + EVP_CIPHER_CTX *cctx = NULL; + HMAC_CTX *hctx = NULL; + uint8_t *dst; + int clen, ret; + + if ((cctx = EVP_CIPHER_CTX_new()) == NULL) { + ret = PTLS_ERROR_NO_MEMORY; + goto Exit; + } + if ((hctx = HMAC_CTX_new()) == NULL) { + ret = PTLS_ERROR_NO_MEMORY; + goto Exit; + } + + if ((ret = ptls_buffer_reserve(buf, TICKET_LABEL_SIZE + TICKET_IV_SIZE + src.len + EVP_MAX_BLOCK_LENGTH + EVP_MAX_MD_SIZE)) != + 0) + goto Exit; + dst = buf->base + buf->off; + + /* fill label and iv, as well as obtaining the keys */ + if (!(*cb)(dst, dst + TICKET_LABEL_SIZE, cctx, hctx, 1)) { + ret = PTLS_ERROR_LIBRARY; + goto Exit; + } + dst += TICKET_LABEL_SIZE + TICKET_IV_SIZE; + + /* encrypt */ + if (!EVP_EncryptUpdate(cctx, dst, &clen, src.base, (int)src.len)) { + ret = PTLS_ERROR_LIBRARY; + goto Exit; + } + dst += clen; + if (!EVP_EncryptFinal_ex(cctx, dst, &clen)) { + ret = PTLS_ERROR_LIBRARY; + goto Exit; + } + dst += clen; + + /* append hmac */ + if (!HMAC_Update(hctx, buf->base + buf->off, dst - (buf->base + buf->off)) || !HMAC_Final(hctx, dst, NULL)) { + ret = PTLS_ERROR_LIBRARY; + goto Exit; + } + dst += HMAC_size(hctx); + + assert(dst <= buf->base + buf->capacity); + buf->off += dst - (buf->base + buf->off); + ret = 0; + +Exit: + if (cctx != NULL) + EVP_CIPHER_CTX_cleanup(cctx); + if (hctx != NULL) + HMAC_CTX_free(hctx); + return ret; +} + +int ptls_openssl_decrypt_ticket(ptls_buffer_t *buf, ptls_iovec_t src, + int (*cb)(unsigned char *key_name, unsigned char *iv, EVP_CIPHER_CTX *ctx, HMAC_CTX *hctx, int enc)) +{ + EVP_CIPHER_CTX *cctx = NULL; + HMAC_CTX *hctx = NULL; + int clen, ret; + + if ((cctx = EVP_CIPHER_CTX_new()) == NULL) { + ret = PTLS_ERROR_NO_MEMORY; + goto Exit; + } + if ((hctx = HMAC_CTX_new()) == NULL) { + ret = PTLS_ERROR_NO_MEMORY; + goto Exit; + } + + /* obtain cipher and hash context. + * Note: no need to handle renew, since in picotls we always send a new ticket to minimize the chance of ticket reuse */ + if (src.len < TICKET_LABEL_SIZE + TICKET_IV_SIZE) { + ret = PTLS_ALERT_DECODE_ERROR; + goto Exit; + } + if (!(*cb)(src.base, src.base + TICKET_LABEL_SIZE, cctx, hctx, 0)) { + ret = PTLS_ERROR_LIBRARY; + goto Exit; + } + + /* check hmac, and exclude label, iv, hmac */ + size_t hmac_size = HMAC_size(hctx); + if (src.len < TICKET_LABEL_SIZE + TICKET_IV_SIZE + hmac_size) { + ret = PTLS_ALERT_DECODE_ERROR; + goto Exit; + } + src.len -= hmac_size; + uint8_t hmac[EVP_MAX_MD_SIZE]; + if (!HMAC_Update(hctx, src.base, src.len) || !HMAC_Final(hctx, hmac, NULL)) { + ret = PTLS_ERROR_LIBRARY; + goto Exit; + } + if (memcmp(src.base + src.len, hmac, hmac_size) != 0) { + ret = PTLS_ALERT_HANDSHAKE_FAILURE; + goto Exit; + } + src.base += TICKET_LABEL_SIZE + TICKET_IV_SIZE; + src.len -= TICKET_LABEL_SIZE + TICKET_IV_SIZE; + + /* decrypt */ + if ((ret = ptls_buffer_reserve(buf, src.len)) != 0) + goto Exit; + if (!EVP_DecryptUpdate(cctx, buf->base + buf->off, &clen, src.base, (int)src.len)) { + ret = PTLS_ERROR_LIBRARY; + goto Exit; + } + buf->off += clen; + if (!EVP_DecryptFinal_ex(cctx, buf->base + buf->off, &clen)) { + ret = PTLS_ERROR_LIBRARY; + goto Exit; + } + buf->off += clen; + + ret = 0; + +Exit: + if (cctx != NULL) + EVP_CIPHER_CTX_cleanup(cctx); + if (hctx != NULL) + HMAC_CTX_free(hctx); + return ret; +} + +ptls_key_exchange_algorithm_t ptls_openssl_secp256r1 = {PTLS_GROUP_SECP256R1, secp256r1_create_key_exchange, + secp256r1_key_exchange}; +ptls_key_exchange_algorithm_t *ptls_openssl_key_exchanges[] = {&ptls_openssl_secp256r1, NULL}; +ptls_cipher_algorithm_t ptls_openssl_aes128ctr = {"AES128-CTR", PTLS_AES128_KEY_SIZE, PTLS_AES_IV_SIZE, + sizeof(struct cipher_context_t), aes128ctr_setup_crypto}; +ptls_aead_algorithm_t ptls_openssl_aes128gcm = {"AES128-GCM", + &ptls_openssl_aes128ctr, + PTLS_AES128_KEY_SIZE, + PTLS_AESGCM_IV_SIZE, + PTLS_AESGCM_TAG_SIZE, + sizeof(struct aead_crypto_context_t), + aead_aes128gcm_setup_crypto}; +ptls_cipher_algorithm_t ptls_openssl_aes256ctr = {"AES256-CTR", PTLS_AES256_KEY_SIZE, PTLS_AES_IV_SIZE, + sizeof(struct cipher_context_t), aes256ctr_setup_crypto}; +ptls_aead_algorithm_t ptls_openssl_aes256gcm = {"AES256-GCM", + &ptls_openssl_aes256ctr, + PTLS_AES256_KEY_SIZE, + PTLS_AESGCM_IV_SIZE, + PTLS_AESGCM_TAG_SIZE, + sizeof(struct aead_crypto_context_t), + aead_aes256gcm_setup_crypto}; +ptls_hash_algorithm_t ptls_openssl_sha256 = {PTLS_SHA256_BLOCK_SIZE, PTLS_SHA256_DIGEST_SIZE, sha256_create, + PTLS_ZERO_DIGEST_SHA256}; +ptls_hash_algorithm_t ptls_openssl_sha384 = {PTLS_SHA384_BLOCK_SIZE, PTLS_SHA384_DIGEST_SIZE, sha384_create, + PTLS_ZERO_DIGEST_SHA384}; +ptls_cipher_suite_t ptls_openssl_aes128gcmsha256 = {PTLS_CIPHER_SUITE_AES_128_GCM_SHA256, &ptls_openssl_aes128gcm, + &ptls_openssl_sha256}; +ptls_cipher_suite_t ptls_openssl_aes256gcmsha384 = {PTLS_CIPHER_SUITE_AES_256_GCM_SHA384, &ptls_openssl_aes256gcm, + &ptls_openssl_sha384}; +#if defined(PTLS_OPENSSL_HAVE_CHACHA20_POLY1305) +ptls_cipher_algorithm_t ptls_openssl_chacha20 = {"CHACHA20", PTLS_CHACHA20_KEY_SIZE, PTLS_CHACHA20_IV_SIZE, + sizeof(struct cipher_context_t), chacha20_setup_crypto}; +ptls_aead_algorithm_t ptls_openssl_chacha20poly1305 = {"CHACHA20-POLY1305", + &ptls_openssl_chacha20, + PTLS_CHACHA20_KEY_SIZE, + PTLS_CHACHA20POLY1305_IV_SIZE, + PTLS_CHACHA20POLY1305_TAG_SIZE, + sizeof(struct aead_crypto_context_t), + aead_chacha20poly1305_setup_crypto}; +ptls_cipher_suite_t ptls_openssl_chacha20poly1305sha256 = {PTLS_CIPHER_SUITE_CHACHA20_POLY1305_SHA256, + &ptls_openssl_chacha20poly1305, &ptls_openssl_sha256}; +#endif +ptls_cipher_suite_t *ptls_openssl_cipher_suites[] = {&ptls_openssl_aes256gcmsha384, &ptls_openssl_aes128gcmsha256, +#if defined(PTLS_OPENSSL_HAVE_CHACHA20_POLY1305) + &ptls_openssl_chacha20poly1305sha256, +#endif + NULL}; diff --git a/web/server/h2o/libh2o/deps/picotls/lib/pembase64.c b/web/server/h2o/libh2o/deps/picotls/lib/pembase64.c new file mode 100644 index 00000000..de44c538 --- /dev/null +++ b/web/server/h2o/libh2o/deps/picotls/lib/pembase64.c @@ -0,0 +1,373 @@ +/* +* Copyright (c) 2016 Christian Huitema +* +* Permission to use, copy, modify, and distribute this software for any +* purpose with or without fee is hereby granted, provided that the above +* copyright notice and this permission notice appear in all copies. +* +* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +*/ + +/* + * Manage Base64 encoding. + */ +#ifdef _WINDOWS +#include "wincompat.h" +#else +#include +#endif +#include +#include +#include +#include +#include "picotls.h" +#include "picotls/pembase64.h" + +static char ptls_base64_alphabet[] = {'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', + 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', + 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', + 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/'}; + +static char ptls_base64_values[] = { + /* 0x00 to 0x0F */ + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + /* 0x10 to 0x1F */ + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + /* 0x20 to 0x2F. '+' at 2B, '/' at 2F */ + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63, + /* 0x30 to 0x3F -- digits 0 to 9 at 0x30 to 0x39*/ + 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1, + /* 0x40 to 0x4F -- chars 'A' to 'O' at 0x41 to 0x4F */ + -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, + /* 0x50 to 0x5F -- chars 'P' to 'Z' at 0x50 to 0x5A */ + 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1, + /* 0x60 to 0x6F -- chars 'a' to 'o' at 0x61 to 0x6F */ + -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, + /* 0x70 to 0x7F -- chars 'p' to 'z' at 0x70 to 0x7A */ + 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1}; + +static void ptls_base64_cell(const uint8_t *data, char *text) +{ + int n[4]; + + n[0] = data[0] >> 2; + n[1] = ((data[0] & 3) << 4) | (data[1] >> 4); + n[2] = ((data[1] & 15) << 2) | (data[2] >> 6); + n[3] = data[2] & 63; + + for (int i = 0; i < 4; i++) { + text[i] = ptls_base64_alphabet[n[i]]; + } +} + +size_t ptls_base64_howlong(size_t data_length) +{ + return (((data_length + 2) / 3) * 4); +} + +int ptls_base64_encode(const uint8_t *data, size_t data_len, char *ptls_base64_text) +{ + int l = 0; + int lt = 0; + + while ((data_len - l) >= 3) { + ptls_base64_cell(data + l, ptls_base64_text + lt); + l += 3; + lt += 4; + } + + switch (data_len - l) { + case 0: + break; + case 1: + ptls_base64_text[lt++] = ptls_base64_alphabet[data[l] >> 2]; + ptls_base64_text[lt++] = ptls_base64_alphabet[(data[l] & 3) << 4]; + ptls_base64_text[lt++] = '='; + ptls_base64_text[lt++] = '='; + break; + case 2: + ptls_base64_text[lt++] = ptls_base64_alphabet[data[l] >> 2]; + ptls_base64_text[lt++] = ptls_base64_alphabet[((data[l] & 3) << 4) | (data[l + 1] >> 4)]; + ptls_base64_text[lt++] = ptls_base64_alphabet[((data[l + 1] & 15) << 2)]; + ptls_base64_text[lt++] = '='; + break; + default: + break; + } + ptls_base64_text[lt++] = 0; + + return lt; +} + +/* + * Take into input a line of text, so as to work by increments. + * The intermediate text of the decoding is kept in a state variable. + * The decoded data is accumulated in a PTLS buffer. + * The parsing is consistent with the lax definition in RFC 7468 + */ + +void ptls_base64_decode_init(ptls_base64_decode_state_t *state) +{ + state->nbc = 0; + state->nbo = 3; + state->v = 0; + state->status = PTLS_BASE64_DECODE_IN_PROGRESS; +} + +int ptls_base64_decode(const char *text, ptls_base64_decode_state_t *state, ptls_buffer_t *buf) +{ + int ret = 0; + uint8_t decoded[3]; + size_t text_index = 0; + int c; + char vc; + + /* skip initial blanks */ + while (text[text_index] != 0) { + c = text[text_index]; + + if (c == ' ' || c == '\t' || c == '\r' || c == '\n') { + text_index++; + } else { + break; + } + } + + while (text[text_index] != 0 && ret == 0 && state->status == PTLS_BASE64_DECODE_IN_PROGRESS) { + c = text[text_index++]; + + vc = 0 < c && c < 0x7f ? ptls_base64_values[c] : -1; + if (vc == -1) { + if (state->nbc == 2 && c == '=' && text[text_index] == '=') { + state->nbc = 4; + text_index++; + state->nbo = 1; + state->v <<= 12; + } else if (state->nbc == 3 && c == '=') { + state->nbc = 4; + state->nbo = 2; + state->v <<= 6; + } else { + /* Skip final blanks */ + text_index--; + while (text[text_index] != 0) { + c = text[text_index++]; + + if (c == ' ' || c == '\t' || c == '\r' || c == '\n' || c == 0x0B || c == 0x0C) { + continue; + } + } + + /* Should now be at end of buffer */ + if (text[text_index] == 0) { + break; + } else { + /* Not at end of buffer, signal a decoding error */ + state->nbo = 0; + state->status = PTLS_BASE64_DECODE_FAILED; + ret = PTLS_ERROR_INCORRECT_BASE64; + } + } + } else { + state->nbc++; + state->v <<= 6; + state->v |= vc; + } + + if (ret == 0 && state->nbc == 4) { + /* Convert to up to 3 octets */ + for (int j = 0; j < state->nbo; j++) { + decoded[j] = (uint8_t)(state->v >> (8 * (2 - j))); + } + + ret = ptls_buffer__do_pushv(buf, decoded, state->nbo); + + if (ret == 0) { + /* test for fin or continuation */ + if (state->nbo < 3) { + /* Check that there are only trainling blanks on this line */ + while (text[text_index] != 0) { + c = text[text_index++]; + + if (c == ' ' || c == '\t' || c == '\r' || c == '\n' || c == 0x0B || c == 0x0C) { + continue; + } + } + if (text[text_index] == 0) { + state->status = PTLS_BASE64_DECODE_DONE; + } else { + state->status = PTLS_BASE64_DECODE_FAILED; + ret = PTLS_ERROR_INCORRECT_BASE64; + } + break; + } else { + state->v = 0; + state->nbo = 3; + state->nbc = 0; + } + } + } + } + return ret; +} + +/* + * Reading a PEM file, to get an object: + * + * - Find first object, get the object name. + * - If object label is what the application expects, parse, else skip to end. + * + * The following labels are defined in RFC 7468: + * + * Sec. Label ASN.1 Type Reference Module + * ----+----------------------+-----------------------+---------+---------- + * 5 CERTIFICATE Certificate [RFC5280] id-pkix1-e + * 6 X509 CRL CertificateList [RFC5280] id-pkix1-e + * 7 CERTIFICATE REQUEST CertificationRequest [RFC2986] id-pkcs10 + * 8 PKCS7 ContentInfo [RFC2315] id-pkcs7* + * 9 CMS ContentInfo [RFC5652] id-cms2004 + * 10 PRIVATE KEY PrivateKeyInfo ::= [RFC5208] id-pkcs8 + * OneAsymmetricKey [RFC5958] id-aKPV1 + * 11 ENCRYPTED PRIVATE KEY EncryptedPrivateKeyInfo [RFC5958] id-aKPV1 + * 12 ATTRIBUTE CERTIFICATE AttributeCertificate [RFC5755] id-acv2 + * 13 PUBLIC KEY SubjectPublicKeyInfo [RFC5280] id-pkix1-e + */ + +static int ptls_compare_separator_line(const char *line, const char *begin_or_end, const char *label) +{ + int ret = strncmp(line, "-----", 5); + size_t text_index = 5; + + if (ret == 0) { + size_t begin_or_end_length = strlen(begin_or_end); + ret = strncmp(line + text_index, begin_or_end, begin_or_end_length); + text_index += begin_or_end_length; + } + + if (ret == 0) { + ret = line[text_index] - ' '; + text_index++; + } + + if (ret == 0) { + size_t label_length = strlen(label); + ret = strncmp(line + text_index, label, label_length); + text_index += label_length; + } + + if (ret == 0) { + ret = strncmp(line + text_index, "-----", 5); + } + + return ret; +} + +static int ptls_get_pem_object(FILE *F, const char *label, ptls_buffer_t *buf) +{ + int ret = PTLS_ERROR_PEM_LABEL_NOT_FOUND; + char line[256]; + ptls_base64_decode_state_t state; + + /* Get the label on a line by itself */ + while (fgets(line, 256, F)) { + if (ptls_compare_separator_line(line, "BEGIN", label) == 0) { + ret = 0; + ptls_base64_decode_init(&state); + break; + } + } + /* Get the data in the buffer */ + while (ret == 0 && fgets(line, 256, F)) { + if (ptls_compare_separator_line(line, "END", label) == 0) { + if (state.status == PTLS_BASE64_DECODE_DONE || (state.status == PTLS_BASE64_DECODE_IN_PROGRESS && state.nbc == 0)) { + ret = 0; + } else { + ret = PTLS_ERROR_INCORRECT_BASE64; + } + break; + } else { + ret = ptls_base64_decode(line, &state, buf); + } + } + + return ret; +} + +int ptls_load_pem_objects(char const *pem_fname, const char *label, ptls_iovec_t *list, size_t list_max, size_t *nb_objects) +{ + FILE *F; + int ret = 0; + size_t count = 0; +#ifdef _WINDOWS + errno_t err = fopen_s(&F, pem_fname, "r"); + if (err != 0) { + ret = -1; + } +#else + F = fopen(pem_fname, "r"); + if (F == NULL) { + ret = -1; + } +#endif + + *nb_objects = 0; + + if (ret == 0) { + while (count < list_max) { + ptls_buffer_t buf; + + ptls_buffer_init(&buf, "", 0); + + ret = ptls_get_pem_object(F, label, &buf); + + if (ret == 0) { + if (buf.off > 0 && buf.is_allocated) { + list[count].base = buf.base; + list[count].len = buf.off; + count++; + } else { + ptls_buffer_dispose(&buf); + } + } else { + ptls_buffer_dispose(&buf); + break; + } + } + } + + if (ret == PTLS_ERROR_PEM_LABEL_NOT_FOUND && count > 0) { + ret = 0; + } + + *nb_objects = count; + + if (F != NULL) { + fclose(F); + } + + return ret; +} + +#define PTLS_MAX_CERTS_IN_CONTEXT 16 + +int ptls_load_certificates(ptls_context_t *ctx, char *cert_pem_file) +{ + int ret = 0; + + ctx->certificates.list = (ptls_iovec_t *)malloc(PTLS_MAX_CERTS_IN_CONTEXT * sizeof(ptls_iovec_t)); + + if (ctx->certificates.list == NULL) { + ret = PTLS_ERROR_NO_MEMORY; + } else { + ret = ptls_load_pem_objects(cert_pem_file, "CERTIFICATE", ctx->certificates.list, PTLS_MAX_CERTS_IN_CONTEXT, + &ctx->certificates.count); + } + + return ret; +} diff --git a/web/server/h2o/libh2o/deps/picotls/lib/picotls.c b/web/server/h2o/libh2o/deps/picotls/lib/picotls.c new file mode 100644 index 00000000..d328aaac --- /dev/null +++ b/web/server/h2o/libh2o/deps/picotls/lib/picotls.c @@ -0,0 +1,3761 @@ +/* + * Copyright (c) 2016 DeNA Co., Ltd., Kazuho Oku + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ +#include +#include +#include +#include +#include +#ifdef _WINDOWS +#include "wincompat.h" +#else +#include +#endif +#include "picotls.h" + +#define PTLS_MAX_PLAINTEXT_RECORD_SIZE 16384 +#define PTLS_MAX_ENCRYPTED_RECORD_SIZE (16384 + 256) + +#define PTLS_RECORD_VERSION_MAJOR 3 +#define PTLS_RECORD_VERSION_MINOR 3 + +#define PTLS_HELLO_RANDOM_SIZE 32 + +#define PTLS_CONTENT_TYPE_CHANGE_CIPHER_SPEC 20 +#define PTLS_CONTENT_TYPE_ALERT 21 +#define PTLS_CONTENT_TYPE_HANDSHAKE 22 +#define PTLS_CONTENT_TYPE_APPDATA 23 + +#define PTLS_HANDSHAKE_TYPE_CLIENT_HELLO 1 +#define PTLS_HANDSHAKE_TYPE_SERVER_HELLO 2 +#define PTLS_HANDSHAKE_TYPE_NEW_SESSION_TICKET 4 +#define PTLS_HANDSHAKE_TYPE_END_OF_EARLY_DATA 5 +#define PTLS_HANDSHAKE_TYPE_ENCRYPTED_EXTENSIONS 8 +#define PTLS_HANDSHAKE_TYPE_CERTIFICATE 11 +#define PTLS_HANDSHAKE_TYPE_CERTIFICATE_REQUEST 13 +#define PTLS_HANDSHAKE_TYPE_CERTIFICATE_VERIFY 15 +#define PTLS_HANDSHAKE_TYPE_FINISHED 20 +#define PTLS_HANDSHAKE_TYPE_KEY_UPDATE 24 +#define PTLS_HANDSHAKE_TYPE_MESSAGE_HASH 254 + +#define PTLS_PSK_KE_MODE_PSK 0 +#define PTLS_PSK_KE_MODE_PSK_DHE 1 + +#define PTLS_HANDSHAKE_HEADER_SIZE 4 + +#define PTLS_EXTENSION_TYPE_SERVER_NAME 0 +#define PTLS_EXTENSION_TYPE_STATUS_REQUEST 5 +#define PTLS_EXTENSION_TYPE_SUPPORTED_GROUPS 10 +#define PTLS_EXTENSION_TYPE_SIGNATURE_ALGORITHMS 13 +#define PTLS_EXTENSION_TYPE_ALPN 16 +#define PTLS_EXTENSION_TYPE_PRE_SHARED_KEY 41 +#define PTLS_EXTENSION_TYPE_EARLY_DATA 42 +#define PTLS_EXTENSION_TYPE_SUPPORTED_VERSIONS 43 +#define PTLS_EXTENSION_TYPE_COOKIE 44 +#define PTLS_EXTENSION_TYPE_PSK_KEY_EXCHANGE_MODES 45 +#define PTLS_EXTENSION_TYPE_KEY_SHARE 51 + +#define PTLS_PROTOCOL_VERSION_DRAFT26 0x7f1a +#define PTLS_PROTOCOL_VERSION_DRAFT27 0x7f1b +#define PTLS_PROTOCOL_VERSION_DRAFT28 0x7f1c + +#define PTLS_SERVER_NAME_TYPE_HOSTNAME 0 + +#define PTLS_SERVER_CERTIFICATE_VERIFY_CONTEXT_STRING "TLS 1.3, server CertificateVerify" +#define PTLS_CLIENT_CERTIFICATE_VERIFY_CONTEXT_STRING "TLS 1.3, client CertificateVerify" +#define PTLS_MAX_CERTIFICATE_VERIFY_SIGNDATA_SIZE \ + (64 + sizeof(PTLS_SERVER_CERTIFICATE_VERIFY_CONTEXT_STRING) + PTLS_MAX_DIGEST_SIZE * 2) + +#define PTLS_EARLY_DATA_MAX_DELAY 10000 /* max. RTT (in msec) to permit early data */ + +#if defined(PTLS_DEBUG) && PTLS_DEBUG +#define PTLS_DEBUGF(...) fprintf(stderr, __VA_ARGS__) +#else +#define PTLS_DEBUGF(...) +#endif + +#ifndef PTLS_MEMORY_DEBUG +#define PTLS_MEMORY_DEBUG 0 +#endif + +/** + * list of supported versions in the preferred order + */ +static const uint16_t supported_versions[] = {PTLS_PROTOCOL_VERSION_DRAFT28, PTLS_PROTOCOL_VERSION_DRAFT27, + PTLS_PROTOCOL_VERSION_DRAFT26}; + +static const uint8_t hello_retry_random[PTLS_HELLO_RANDOM_SIZE] = {0xCF, 0x21, 0xAD, 0x74, 0xE5, 0x9A, 0x61, 0x11, 0xBE, 0x1D, 0x8C, + 0x02, 0x1E, 0x65, 0xB8, 0x91, 0xC2, 0xA2, 0x11, 0x16, 0x7A, 0xBB, + 0x8C, 0x5E, 0x07, 0x9E, 0x09, 0xE2, 0xC8, 0xA8, 0x33, 0x9C}; + +struct st_ptls_traffic_protection_t { + uint8_t secret[PTLS_MAX_DIGEST_SIZE]; + ptls_aead_context_t *aead; + uint64_t seq; +}; + +struct st_ptls_early_data_t { + uint8_t next_secret[PTLS_MAX_DIGEST_SIZE]; +}; + +struct st_ptls_t { + /** + * the context + */ + ptls_context_t *ctx; + /** + * the state + */ + enum { + PTLS_STATE_CLIENT_HANDSHAKE_START, + PTLS_STATE_CLIENT_EXPECT_SERVER_HELLO, + PTLS_STATE_CLIENT_EXPECT_SECOND_SERVER_HELLO, + PTLS_STATE_CLIENT_EXPECT_ENCRYPTED_EXTENSIONS, + PTLS_STATE_CLIENT_EXPECT_CERTIFICATE, + PTLS_STATE_CLIENT_EXPECT_CERTIFICATE_VERIFY, + PTLS_STATE_CLIENT_EXPECT_FINISHED, + PTLS_STATE_SERVER_EXPECT_CLIENT_HELLO, + PTLS_STATE_SERVER_EXPECT_SECOND_CLIENT_HELLO, + /* ptls_send can be called if the state is below here */ + PTLS_STATE_SERVER_EXPECT_END_OF_EARLY_DATA, + PTLS_STATE_SERVER_EXPECT_FINISHED, + PTLS_STATE_POST_HANDSHAKE_MIN, + PTLS_STATE_CLIENT_POST_HANDSHAKE = PTLS_STATE_POST_HANDSHAKE_MIN, + PTLS_STATE_SERVER_POST_HANDSHAKE + } state; + /** + * receive buffers + */ + struct { + ptls_buffer_t rec; + ptls_buffer_t mess; + } recvbuf; + /** + * key schedule + */ + struct st_ptls_key_schedule_t *key_schedule; + /** + * values used for record protection + */ + struct { + struct st_ptls_traffic_protection_t dec; + struct st_ptls_traffic_protection_t enc; + } traffic_protection; + /** + * server-name passed using SNI + */ + char *server_name; + /** + * result of ALPN + */ + char *negotiated_protocol; + /** + * selected key-exchange + */ + ptls_key_exchange_algorithm_t *key_share; + /** + * selected cipher-suite + */ + ptls_cipher_suite_t *cipher_suite; + /** + * clienthello.random + */ + uint8_t client_random[PTLS_HELLO_RANDOM_SIZE]; + /* flags */ + unsigned is_server : 1; + unsigned is_psk_handshake : 1; + unsigned skip_early_data : 1; /* if early-data is not recognized by the server */ + unsigned send_change_cipher_spec : 1; + /** + * exporter master secret (either 0rtt or 1rtt) + */ + struct { + uint8_t *early; + uint8_t *one_rtt; + } exporter_master_secret; + /** + * misc. + */ + union { + struct { + uint8_t legacy_session_id[16]; + ptls_key_exchange_context_t *key_share_ctx; + struct { + int (*cb)(void *verify_ctx, ptls_iovec_t data, ptls_iovec_t signature); + void *verify_ctx; + } certificate_verify; + unsigned offered_psk : 1; + } client; + struct { + uint8_t pending_traffic_secret[PTLS_MAX_DIGEST_SIZE]; + } server; + }; + /** + * the value contains the traffic secret to be commisioned after END_OF_EARLY_DATA + * END_OF_EARLY_DATA + */ + struct st_ptls_early_data_t *early_data; + /** + * user data + */ + void *data_ptr; +}; + +struct st_ptls_record_t { + uint8_t type; + uint16_t version; + size_t length; + const uint8_t *fragment; +}; + +struct st_ptls_client_hello_psk_t { + ptls_iovec_t identity; + uint32_t obfuscated_ticket_age; + ptls_iovec_t binder; +}; + +#define MAX_UNKNOWN_EXTENSIONS 16 + +struct st_ptls_client_hello_t { + const uint8_t *random_bytes; + ptls_iovec_t legacy_session_id; + struct { + const uint8_t *ids; + size_t count; + } compression_methods; + uint16_t selected_version; + ptls_iovec_t cipher_suites; + ptls_iovec_t negotiated_groups; + ptls_iovec_t key_shares; + struct { + uint16_t list[16]; /* expand? */ + size_t count; + } signature_algorithms; + ptls_iovec_t server_name; + struct { + ptls_iovec_t list[16]; + size_t count; + } alpn; + struct { + ptls_iovec_t all; + ptls_iovec_t tbs; + ptls_iovec_t ch1_hash; + ptls_iovec_t signature; + unsigned sent_key_share : 1; + } cookie; + struct { + const uint8_t *hash_end; + struct { + struct st_ptls_client_hello_psk_t list[4]; + size_t count; + } identities; + unsigned ke_modes; + int early_data_indication; + } psk; + ptls_raw_extension_t unknown_extensions[MAX_UNKNOWN_EXTENSIONS + 1]; + unsigned status_request : 1; +}; + +struct st_ptls_server_hello_t { + uint8_t random_[PTLS_HELLO_RANDOM_SIZE]; + ptls_iovec_t legacy_session_id; + int is_retry_request; + union { + ptls_iovec_t peerkey; + struct { + uint16_t selected_group; + ptls_iovec_t cookie; + } retry_request; + }; +}; + +struct st_ptls_key_schedule_t { + unsigned generation; /* early secret (1), hanshake secret (2), master secret (3) */ + uint8_t secret[PTLS_MAX_DIGEST_SIZE]; + size_t num_hashes; + struct { + ptls_hash_algorithm_t *algo; + ptls_hash_context_t *ctx; + } hashes[1]; +}; + +struct st_ptls_extension_decoder_t { + uint16_t type; + int (*cb)(ptls_t *tls, void *arg, const uint8_t *src, const uint8_t *const end); +}; + +struct st_ptls_extension_bitmap_t { + uint8_t bits[8]; /* only ids below 64 is tracked */ +}; + +static uint8_t zeroes_of_max_digest_size[PTLS_MAX_DIGEST_SIZE] = {0}; + +static int is_supported_version(uint16_t v) +{ + size_t i; + for (i = 0; i != sizeof(supported_versions) / sizeof(supported_versions[0]); ++i) + if (supported_versions[i] == v) + return 1; + return 0; +} + +static inline int extension_bitmap_is_set(struct st_ptls_extension_bitmap_t *bitmap, uint16_t id) +{ + if (id < sizeof(bitmap->bits) * 8) + return (bitmap->bits[id / 8] & (1 << (id % 8))) != 0; + return 0; +} + +static inline void extension_bitmap_set(struct st_ptls_extension_bitmap_t *bitmap, uint16_t id) +{ + if (id < sizeof(bitmap->bits) * 8) + bitmap->bits[id / 8] |= 1 << (id % 8); +} + +static inline void init_extension_bitmap(struct st_ptls_extension_bitmap_t *bitmap, uint8_t hstype) +{ + *bitmap = (struct st_ptls_extension_bitmap_t){{0}}; + +#define EXT(extid, proc) \ + do { \ + int _found = 0; \ + do { \ + proc \ + } while (0); \ + if (!_found) \ + extension_bitmap_set(bitmap, PTLS_EXTENSION_TYPE_##extid); \ + } while (0) +#define ALLOW(allowed_hstype) _found = _found || hstype == PTLS_HANDSHAKE_TYPE_##allowed_hstype + + /* Implements the table found in section 4.2 of draft-19; "If an implementation receives an extension which it recognizes and + * which is not specified for the message in which it appears it MUST abort the handshake with an “illegal_parameter†alert." + */ + EXT(SERVER_NAME, { + ALLOW(CLIENT_HELLO); + ALLOW(ENCRYPTED_EXTENSIONS); + }); + EXT(STATUS_REQUEST, { + ALLOW(CLIENT_HELLO); + ALLOW(CERTIFICATE); + }); + EXT(SUPPORTED_GROUPS, { + ALLOW(CLIENT_HELLO); + ALLOW(ENCRYPTED_EXTENSIONS); + }); + EXT(SIGNATURE_ALGORITHMS, { ALLOW(CLIENT_HELLO); }); + EXT(ALPN, { + ALLOW(CLIENT_HELLO); + ALLOW(ENCRYPTED_EXTENSIONS); + }); + EXT(KEY_SHARE, { + ALLOW(CLIENT_HELLO); + ALLOW(SERVER_HELLO); + }); + EXT(PRE_SHARED_KEY, { + ALLOW(CLIENT_HELLO); + ALLOW(SERVER_HELLO); + }); + EXT(PSK_KEY_EXCHANGE_MODES, { ALLOW(CLIENT_HELLO); }); + EXT(EARLY_DATA, { + ALLOW(CLIENT_HELLO); + ALLOW(ENCRYPTED_EXTENSIONS); + ALLOW(NEW_SESSION_TICKET); + }); + EXT(COOKIE, { + ALLOW(CLIENT_HELLO); + ALLOW(SERVER_HELLO); + }); + EXT(SUPPORTED_VERSIONS, { + ALLOW(CLIENT_HELLO); + ALLOW(SERVER_HELLO); + }); + +#undef ALLOW +#undef EXT +} + +static uint16_t ntoh16(const uint8_t *src) +{ + return (uint16_t)src[0] << 8 | src[1]; +} + +static uint32_t ntoh24(const uint8_t *src) +{ + return (uint32_t)src[0] << 16 | (uint32_t)src[1] << 8 | src[2]; +} + +static uint32_t ntoh32(const uint8_t *src) +{ + return (uint32_t)src[0] << 24 | (uint32_t)src[1] << 16 | (uint32_t)src[2] << 8 | src[3]; +} + +static uint64_t ntoh64(const uint8_t *src) +{ + return (uint64_t)src[0] << 56 | (uint64_t)src[1] << 48 | (uint64_t)src[2] << 40 | (uint64_t)src[3] << 32 | + (uint64_t)src[4] << 24 | (uint64_t)src[5] << 16 | (uint64_t)src[6] << 8 | src[7]; +} + +void ptls_buffer__release_memory(ptls_buffer_t *buf) +{ + ptls_clear_memory(buf->base, buf->off); + if (buf->is_allocated) + free(buf->base); +} + +int ptls_buffer_reserve(ptls_buffer_t *buf, size_t delta) +{ + if (buf->base == NULL) + return PTLS_ERROR_NO_MEMORY; + + if (PTLS_MEMORY_DEBUG || buf->capacity < buf->off + delta) { + uint8_t *newp; + size_t new_capacity = buf->capacity; + if (new_capacity < 1024) + new_capacity = 1024; + while (new_capacity < buf->off + delta) { + new_capacity *= 2; + } + if ((newp = malloc(new_capacity)) == NULL) + return PTLS_ERROR_NO_MEMORY; + memcpy(newp, buf->base, buf->off); + ptls_buffer__release_memory(buf); + buf->base = newp; + buf->capacity = new_capacity; + buf->is_allocated = 1; + } + + return 0; +} + +int ptls_buffer__do_pushv(ptls_buffer_t *buf, const void *src, size_t len) +{ + int ret; + + if (len == 0) + return 0; + if ((ret = ptls_buffer_reserve(buf, len)) != 0) + return ret; + memcpy(buf->base + buf->off, src, len); + buf->off += len; + return 0; +} + +int ptls_buffer__adjust_asn1_blocksize(ptls_buffer_t *buf, size_t body_size) +{ + fprintf(stderr, "unimplemented\n"); + abort(); +} + +int ptls_buffer_push_asn1_ubigint(ptls_buffer_t *buf, const void *bignum, size_t size) +{ + const uint8_t *p = bignum, *const end = p + size; + int ret; + + /* skip zeroes */ + for (; end - p >= 1; ++p) + if (*p != 0) + break; + + /* emit */ + ptls_buffer_push(buf, 2); + ptls_buffer_push_asn1_block(buf, { + if (*p >= 0x80) + ptls_buffer_push(buf, 0); + if (p != end) { + ptls_buffer_pushv(buf, p, end - p); + } else { + ptls_buffer_pushv(buf, "", 1); + } + }); + ret = 0; + +Exit: + return ret; +} + +static void build_aad(uint8_t aad[5], size_t reclen) +{ + aad[0] = PTLS_CONTENT_TYPE_APPDATA; + aad[1] = PTLS_RECORD_VERSION_MAJOR; + aad[2] = PTLS_RECORD_VERSION_MINOR; + aad[3] = (uint8_t)(reclen >> 8); + aad[4] = (uint8_t)reclen; +} + +static size_t aead_encrypt(struct st_ptls_traffic_protection_t *ctx, void *output, const void *input, size_t inlen, + uint8_t content_type) +{ + uint8_t aad[5]; + size_t off = 0; + + build_aad(aad, inlen + 1 + ctx->aead->algo->tag_size); + ptls_aead_encrypt_init(ctx->aead, ctx->seq++, aad, sizeof(aad)); + off += ptls_aead_encrypt_update(ctx->aead, ((uint8_t *)output) + off, input, inlen); + off += ptls_aead_encrypt_update(ctx->aead, ((uint8_t *)output) + off, &content_type, 1); + off += ptls_aead_encrypt_final(ctx->aead, ((uint8_t *)output) + off); + + return off; +} + +static int aead_decrypt(struct st_ptls_traffic_protection_t *ctx, void *output, size_t *outlen, const void *input, size_t inlen) +{ + uint8_t aad[5]; + + build_aad(aad, inlen); + if ((*outlen = ptls_aead_decrypt(ctx->aead, output, input, inlen, ctx->seq, aad, sizeof(aad))) == SIZE_MAX) + return PTLS_ALERT_BAD_RECORD_MAC; + ++ctx->seq; + return 0; +} + +#define buffer_push_record(buf, type, block) \ + do { \ + ptls_buffer_push((buf), (type), PTLS_RECORD_VERSION_MAJOR, PTLS_RECORD_VERSION_MINOR); \ + ptls_buffer_push_block((buf), 2, block); \ + } while (0) + +static int buffer_push_encrypted_records(ptls_buffer_t *buf, uint8_t type, const uint8_t *src, size_t len, + struct st_ptls_traffic_protection_t *enc) +{ + int ret = 0; + + while (len != 0) { + size_t chunk_size = len; + if (chunk_size > PTLS_MAX_PLAINTEXT_RECORD_SIZE) + chunk_size = PTLS_MAX_PLAINTEXT_RECORD_SIZE; + buffer_push_record(buf, PTLS_CONTENT_TYPE_APPDATA, { + if ((ret = ptls_buffer_reserve(buf, chunk_size + enc->aead->algo->tag_size + 1)) != 0) + goto Exit; + buf->off += aead_encrypt(enc, buf->base + buf->off, src, chunk_size, type); + }); + src += chunk_size; + len -= chunk_size; + } + +Exit: + return ret; +} + +static int buffer_encrypt_record(ptls_buffer_t *buf, size_t rec_start, struct st_ptls_traffic_protection_t *enc) +{ + size_t bodylen = buf->off - rec_start - 5; + uint8_t *tmpbuf, type = buf->base[rec_start]; + int ret; + + /* fast path: do in-place encryption if only one record needs to be emitted */ + if (bodylen <= PTLS_MAX_PLAINTEXT_RECORD_SIZE) { + size_t overhead = 1 + enc->aead->algo->tag_size; + if ((ret = ptls_buffer_reserve(buf, overhead)) != 0) + return ret; + size_t encrypted_len = aead_encrypt(enc, buf->base + rec_start + 5, buf->base + rec_start + 5, bodylen, type); + assert(encrypted_len == bodylen + overhead); + buf->off += overhead; + buf->base[rec_start] = PTLS_CONTENT_TYPE_APPDATA; + buf->base[rec_start + 3] = (encrypted_len >> 8) & 0xff; + buf->base[rec_start + 4] = encrypted_len & 0xff; + return 0; + } + + /* move plaintext to temporary buffer */ + if ((tmpbuf = malloc(bodylen)) == NULL) { + ret = PTLS_ERROR_NO_MEMORY; + goto Exit; + } + memcpy(tmpbuf, buf->base + rec_start + 5, bodylen); + ptls_clear_memory(buf->base + rec_start, bodylen + 5); + buf->off = rec_start; + + /* push encrypted records */ + ret = buffer_push_encrypted_records(buf, type, tmpbuf, bodylen, enc); + +Exit: + if (tmpbuf != NULL) { + ptls_clear_memory(tmpbuf, bodylen); + free(tmpbuf); + } + return ret; +} + +#define buffer_push_handshake_body(buf, key_sched, type, block) \ + do { \ + size_t mess_start = (buf)->off; \ + ptls_buffer_push((buf), (type)); \ + ptls_buffer_push_block((buf), 3, { \ + do { \ + block \ + } while (0); \ + }); \ + if ((key_sched) != NULL) \ + key_schedule_update_hash((key_sched), (buf)->base + (mess_start), (buf)->off - (mess_start)); \ + } while (0) + +#define buffer_push_handshake(buf, key_sched, enc, type, block) \ + do { \ + size_t rec_start = (buf)->off; \ + buffer_push_record((buf), PTLS_CONTENT_TYPE_HANDSHAKE, \ + { buffer_push_handshake_body((buf), (key_sched), (type), block); }); \ + if ((enc) != NULL) { \ + if ((ret = buffer_encrypt_record((buf), rec_start, (enc))) != 0) \ + goto Exit; \ + } \ + } while (0) + +#define buffer_push_extension(buf, type, block) \ + do { \ + ptls_buffer_push16((buf), (type)); \ + ptls_buffer_push_block((buf), 2, block); \ + } while (0); + +#define decode_open_extensions(src, end, hstype, exttype, block) \ + do { \ + struct st_ptls_extension_bitmap_t bitmap; \ + init_extension_bitmap(&bitmap, (hstype)); \ + ptls_decode_open_block((src), end, 2, { \ + while ((src) != end) { \ + if ((ret = ptls_decode16((exttype), &(src), end)) != 0) \ + goto Exit; \ + if (extension_bitmap_is_set(&bitmap, *(exttype)) != 0) { \ + ret = PTLS_ALERT_ILLEGAL_PARAMETER; \ + goto Exit; \ + } \ + extension_bitmap_set(&bitmap, *(exttype)); \ + ptls_decode_open_block((src), end, 2, block); \ + } \ + }); \ + } while (0) + +#define decode_extensions(src, end, hstype, exttype, block) \ + do { \ + decode_open_extensions((src), end, hstype, exttype, block); \ + ptls_decode_assert_block_close((src), end); \ + } while (0) + +int ptls_decode16(uint16_t *value, const uint8_t **src, const uint8_t *end) +{ + if (end - *src < 2) + return PTLS_ALERT_DECODE_ERROR; + *value = ntoh16(*src); + *src += 2; + return 0; +} + +int ptls_decode32(uint32_t *value, const uint8_t **src, const uint8_t *end) +{ + if (end - *src < 4) + return PTLS_ALERT_DECODE_ERROR; + *value = ntoh32(*src); + *src += 4; + return 0; +} + +int ptls_decode64(uint64_t *value, const uint8_t **src, const uint8_t *end) +{ + if (end - *src < 8) + return PTLS_ALERT_DECODE_ERROR; + *value = ntoh64(*src); + *src += 8; + return 0; +} + +static void key_schedule_free(struct st_ptls_key_schedule_t *sched) +{ + size_t i; + ptls_clear_memory(sched->secret, sizeof(sched->secret)); + for (i = 0; i != sched->num_hashes; ++i) + sched->hashes[i].ctx->final(sched->hashes[i].ctx, NULL, PTLS_HASH_FINAL_MODE_FREE); + free(sched); +} + +static struct st_ptls_key_schedule_t *key_schedule_new(ptls_cipher_suite_t *preferred, ptls_cipher_suite_t **offered) +{ +#define FOREACH_HASH(block) \ + do { \ + ptls_cipher_suite_t *cs; \ + if ((cs = preferred) != NULL) { \ + block \ + } \ + if (offered != NULL) { \ + size_t i, j; \ + for (i = 0; (cs = offered[i]) != NULL; ++i) { \ + if (preferred == NULL || cs->hash != preferred->hash) { \ + for (j = 0; j != i; ++j) \ + if (cs->hash == offered[j]->hash) \ + break; \ + if (j == i) { \ + block \ + } \ + } \ + } \ + } \ + } while (0) + + struct st_ptls_key_schedule_t *sched; + + { /* allocate */ + size_t num_hashes = 0; + FOREACH_HASH({ ++num_hashes; }); + if ((sched = malloc(offsetof(struct st_ptls_key_schedule_t, hashes) + sizeof(sched->hashes[0]) * num_hashes)) == NULL) + return NULL; + *sched = (struct st_ptls_key_schedule_t){0}; + } + + /* setup the hash algos and contexts */ + FOREACH_HASH({ + sched->hashes[sched->num_hashes].algo = cs->hash; + if ((sched->hashes[sched->num_hashes].ctx = cs->hash->create()) == NULL) + goto Fail; + ++sched->num_hashes; + }); + + return sched; +Fail: + key_schedule_free(sched); + return NULL; + +#undef FOREACH_HASH +} + +static int key_schedule_extract(struct st_ptls_key_schedule_t *sched, ptls_iovec_t ikm) +{ + int ret; + + if (ikm.base == NULL) + ikm = ptls_iovec_init(zeroes_of_max_digest_size, sched->hashes[0].algo->digest_size); + + if (sched->generation != 0 && + (ret = ptls_hkdf_expand_label(sched->hashes[0].algo, sched->secret, sched->hashes[0].algo->digest_size, + ptls_iovec_init(sched->secret, sched->hashes[0].algo->digest_size), "derived", + ptls_iovec_init(sched->hashes[0].algo->empty_digest, sched->hashes[0].algo->digest_size), + NULL)) != 0) + return ret; + + ++sched->generation; + ret = ptls_hkdf_extract(sched->hashes[0].algo, sched->secret, + ptls_iovec_init(sched->secret, sched->hashes[0].algo->digest_size), ikm); + PTLS_DEBUGF("%s: %u, %02x%02x\n", __FUNCTION__, sched->generation, (int)sched->secret[0], (int)sched->secret[1]); + return ret; +} + +static int key_schedule_select_one(struct st_ptls_key_schedule_t *sched, ptls_cipher_suite_t *cs, int reset) +{ + size_t found_slot = SIZE_MAX, i; + int ret; + + assert(sched->generation == 1); + + /* find the one, while freeing others */ + for (i = 0; i != sched->num_hashes; ++i) { + if (sched->hashes[i].algo == cs->hash) { + assert(found_slot == SIZE_MAX); + found_slot = i; + } else { + sched->hashes[i].ctx->final(sched->hashes[i].ctx, NULL, PTLS_HASH_FINAL_MODE_FREE); + } + } + if (found_slot != 0) { + sched->hashes[0] = sched->hashes[found_slot]; + reset = 1; + } + sched->num_hashes = 1; + + /* recalculate the hash if a different hash as been selected than the one we used for calculating the early secrets */ + if (reset) { + --sched->generation; + memset(sched->secret, 0, sizeof(sched->secret)); + if ((ret = key_schedule_extract(sched, ptls_iovec_init(NULL, 0))) != 0) + goto Exit; + } + + ret = 0; +Exit: + return ret; +} + +static void key_schedule_update_hash(struct st_ptls_key_schedule_t *sched, const uint8_t *msg, size_t msglen) +{ + size_t i; + + PTLS_DEBUGF("%s:%zu\n", __FUNCTION__, msglen); + for (i = 0; i != sched->num_hashes; ++i) + sched->hashes[i].ctx->update(sched->hashes[i].ctx, msg, msglen); +} + +static void key_schedule_update_ch1hash_prefix(struct st_ptls_key_schedule_t *sched) +{ + uint8_t prefix[4] = {PTLS_HANDSHAKE_TYPE_MESSAGE_HASH, 0, 0, (uint8_t)sched->hashes[0].algo->digest_size}; + key_schedule_update_hash(sched, prefix, sizeof(prefix)); +} + +static void key_schedule_extract_ch1hash(struct st_ptls_key_schedule_t *sched, uint8_t *hash) +{ + sched->hashes[0].ctx->final(sched->hashes[0].ctx, hash, PTLS_HASH_FINAL_MODE_RESET); +} + +static void key_schedule_transform_post_ch1hash(struct st_ptls_key_schedule_t *sched) +{ + uint8_t ch1hash[PTLS_MAX_DIGEST_SIZE]; + + key_schedule_extract_ch1hash(sched, ch1hash); + + key_schedule_update_ch1hash_prefix(sched); + key_schedule_update_hash(sched, ch1hash, sched->hashes[0].algo->digest_size); +} + +static int derive_secret_with_hash(struct st_ptls_key_schedule_t *sched, void *secret, const char *label, const uint8_t *hash) +{ + int ret = ptls_hkdf_expand_label(sched->hashes[0].algo, secret, sched->hashes[0].algo->digest_size, + ptls_iovec_init(sched->secret, sched->hashes[0].algo->digest_size), label, + ptls_iovec_init(hash, sched->hashes[0].algo->digest_size), NULL); + PTLS_DEBUGF("%s: (label=%s, hash=%02x%02x) => %02x%02x\n", __FUNCTION__, label, hash[0], hash[1], ((uint8_t *)secret)[0], + ((uint8_t *)secret)[1]); + return ret; +} + +static int derive_secret(struct st_ptls_key_schedule_t *sched, void *secret, const char *label) +{ + uint8_t hash_value[PTLS_MAX_DIGEST_SIZE]; + + sched->hashes[0].ctx->final(sched->hashes[0].ctx, hash_value, PTLS_HASH_FINAL_MODE_SNAPSHOT); + int ret = derive_secret_with_hash(sched, secret, label, hash_value); + ptls_clear_memory(hash_value, sizeof(hash_value)); + return ret; +} + +static int derive_secret_with_empty_digest(struct st_ptls_key_schedule_t *sched, void *secret, const char *label) +{ + return derive_secret_with_hash(sched, secret, label, sched->hashes[0].algo->empty_digest); +} + +static int derive_exporter_secret(ptls_t *tls, int is_early) +{ + if (tls->ctx->use_exporter) + return 0; + + uint8_t **slot = is_early ? &tls->exporter_master_secret.early : &tls->exporter_master_secret.one_rtt; + assert(*slot == NULL); + if ((*slot = malloc(tls->key_schedule->hashes[0].algo->digest_size)) == NULL) + return PTLS_ERROR_NO_MEMORY; + return derive_secret(tls->key_schedule, *slot, is_early ? "e exp master" : "exp master"); +} + +static void free_exporter_master_secret(ptls_t *tls, int is_early) +{ + uint8_t *slot = is_early ? tls->exporter_master_secret.early : tls->exporter_master_secret.one_rtt; + if (slot == NULL) + return; + assert(tls->key_schedule != NULL); + ptls_clear_memory(slot, tls->key_schedule->hashes[0].algo->digest_size); + free(slot); +} + +static int derive_resumption_secret(struct st_ptls_key_schedule_t *sched, uint8_t *secret, ptls_iovec_t nonce) +{ + int ret; + + if ((ret = derive_secret(sched, secret, "res master")) != 0) + goto Exit; + if ((ret = ptls_hkdf_expand_label(sched->hashes[0].algo, secret, sched->hashes[0].algo->digest_size, + ptls_iovec_init(secret, sched->hashes[0].algo->digest_size), "resumption", nonce, NULL)) != 0) + goto Exit; + +Exit: + if (ret != 0) + ptls_clear_memory(secret, sched->hashes[0].algo->digest_size); + return ret; +} + +static int decode_new_session_ticket(uint32_t *lifetime, uint32_t *age_add, ptls_iovec_t *nonce, ptls_iovec_t *ticket, + uint32_t *max_early_data_size, const uint8_t *src, const uint8_t *const end) +{ + uint16_t exttype; + int ret; + + if ((ret = ptls_decode32(lifetime, &src, end)) != 0) + goto Exit; + if ((ret = ptls_decode32(age_add, &src, end)) != 0) + goto Exit; + ptls_decode_open_block(src, end, 1, { + *nonce = ptls_iovec_init(src, end - src); + src = end; + }); + ptls_decode_open_block(src, end, 2, { + if (src == end) { + ret = PTLS_ALERT_DECODE_ERROR; + goto Exit; + } + *ticket = ptls_iovec_init(src, end - src); + src = end; + }); + + *max_early_data_size = 0; + decode_extensions(src, end, PTLS_HANDSHAKE_TYPE_NEW_SESSION_TICKET, &exttype, { + switch (exttype) { + case PTLS_EXTENSION_TYPE_EARLY_DATA: + if ((ret = ptls_decode32(max_early_data_size, &src, end)) != 0) + goto Exit; + break; + default: + src = end; + break; + } + }); + + ret = 0; +Exit: + return ret; +} + +static int decode_stored_session_ticket(ptls_context_t *ctx, ptls_key_exchange_algorithm_t **key_share, ptls_cipher_suite_t **cs, + ptls_iovec_t *secret, uint32_t *obfuscated_ticket_age, ptls_iovec_t *ticket, + uint32_t *max_early_data_size, const uint8_t *src, const uint8_t *const end) +{ + uint16_t kxid, csid; + uint32_t lifetime, age_add; + uint64_t obtained_at, now; + ptls_iovec_t nonce; + int ret; + + /* decode */ + if ((ret = ptls_decode64(&obtained_at, &src, end)) != 0) + goto Exit; + if ((ret = ptls_decode16(&kxid, &src, end)) != 0) + goto Exit; + if ((ret = ptls_decode16(&csid, &src, end)) != 0) + goto Exit; + ptls_decode_open_block(src, end, 3, { + if ((ret = decode_new_session_ticket(&lifetime, &age_add, &nonce, ticket, max_early_data_size, src, end)) != 0) + goto Exit; + src = end; + }); + ptls_decode_block(src, end, 2, { + *secret = ptls_iovec_init(src, end - src); + src = end; + }); + + { /* determine the key-exchange */ + ptls_key_exchange_algorithm_t **cand; + for (cand = ctx->key_exchanges; *cand != NULL; ++cand) + if ((*cand)->id == kxid) + break; + if (*cand == NULL) { + ret = PTLS_ERROR_LIBRARY; + goto Exit; + } + *key_share = *cand; + } + + { /* determine the cipher-suite */ + ptls_cipher_suite_t **cand; + for (cand = ctx->cipher_suites; *cand != NULL; ++cand) + if ((*cand)->id == csid) + break; + if (*cand == NULL) { + ret = PTLS_ERROR_LIBRARY; + goto Exit; + } + *cs = *cand; + } + + /* calculate obfuscated_ticket_age */ + now = ctx->get_time->cb(ctx->get_time); + if (!(obtained_at <= now && now - obtained_at < 7 * 86400 * 1000)) { + ret = PTLS_ERROR_LIBRARY; + goto Exit; + } + *obfuscated_ticket_age = (uint32_t)(now - obtained_at) + age_add; + + ret = 0; +Exit: + return ret; +} + +static int get_traffic_key(ptls_hash_algorithm_t *algo, void *key, size_t key_size, int is_iv, const void *secret, + const char *base_label) +{ + return ptls_hkdf_expand_label(algo, key, key_size, ptls_iovec_init(secret, algo->digest_size), is_iv ? "iv" : "key", + ptls_iovec_init(NULL, 0), base_label); +} + +static int setup_traffic_protection(ptls_t *tls, int is_enc, const char *secret_label, const char *log_label) +{ + struct st_ptls_traffic_protection_t *ctx = is_enc ? &tls->traffic_protection.enc : &tls->traffic_protection.dec; + + if (secret_label != NULL) { + int ret; + if ((ret = derive_secret(tls->key_schedule, ctx->secret, secret_label)) != 0) + return ret; + } + + if (ctx->aead != NULL) + ptls_aead_free(ctx->aead); + if ((ctx->aead = ptls_aead_new(tls->cipher_suite->aead, tls->cipher_suite->hash, is_enc, ctx->secret, NULL)) == NULL) + return PTLS_ERROR_NO_MEMORY; /* TODO obtain error from ptls_aead_new */ + ctx->seq = 0; + + if (tls->ctx->log_secret != NULL) + tls->ctx->log_secret->cb(tls->ctx->log_secret, tls, log_label, + ptls_iovec_init(ctx->secret, tls->key_schedule->hashes[0].algo->digest_size)); + PTLS_DEBUGF("[%s] %02x%02x,%02x%02x\n", log_label, (unsigned)ctx->secret[0], (unsigned)ctx->secret[1], + (unsigned)ctx->aead->static_iv[0], (unsigned)ctx->aead->static_iv[1]); + + return 0; +} + +static int retire_early_data_secret(ptls_t *tls, int is_enc) +{ + assert(tls->early_data != NULL); + memcpy((is_enc ? &tls->traffic_protection.enc : &tls->traffic_protection.dec)->secret, tls->early_data->next_secret, + PTLS_MAX_DIGEST_SIZE); + ptls_clear_memory(tls->early_data, sizeof(*tls->early_data)); + free(tls->early_data); + tls->early_data = NULL; + + return setup_traffic_protection(tls, is_enc, NULL, "CLIENT_HANDSHAKE_TRAFFIC_SECRET"); +} + +#define SESSION_IDENTIFIER_MAGIC "ptls0001" /* the number should be changed upon incompatible format change */ +#define SESSION_IDENTIFIER_MAGIC_SIZE (sizeof(SESSION_IDENTIFIER_MAGIC) - 1) + +static int encode_session_identifier(ptls_context_t *ctx, ptls_buffer_t *buf, uint32_t ticket_age_add, ptls_iovec_t ticket_nonce, + struct st_ptls_key_schedule_t *sched, const char *server_name, uint16_t key_exchange_id, + uint16_t csid, const char *negotiated_protocol) +{ + int ret = 0; + + ptls_buffer_push_block(buf, 2, { + /* format id */ + ptls_buffer_pushv(buf, SESSION_IDENTIFIER_MAGIC, SESSION_IDENTIFIER_MAGIC_SIZE); + /* date */ + ptls_buffer_push64(buf, ctx->get_time->cb(ctx->get_time)); + /* resumption master secret */ + ptls_buffer_push_block(buf, 2, { + if ((ret = ptls_buffer_reserve(buf, sched->hashes[0].algo->digest_size)) != 0) + goto Exit; + if ((ret = derive_resumption_secret(sched, buf->base + buf->off, ticket_nonce)) != 0) + goto Exit; + buf->off += sched->hashes[0].algo->digest_size; + }); + /* key-exchange */ + ptls_buffer_push16(buf, key_exchange_id); + /* cipher-suite */ + ptls_buffer_push16(buf, csid); + /* ticket_age_add */ + ptls_buffer_push32(buf, ticket_age_add); + /* server-name */ + ptls_buffer_push_block(buf, 2, { + if (server_name != NULL) + ptls_buffer_pushv(buf, server_name, strlen(server_name)); + }); + /* alpn */ + ptls_buffer_push_block(buf, 1, { + if (negotiated_protocol != NULL) + ptls_buffer_pushv(buf, negotiated_protocol, strlen(negotiated_protocol)); + }); + }); + +Exit: + return ret; +} + +int decode_session_identifier(uint64_t *issued_at, ptls_iovec_t *psk, uint32_t *ticket_age_add, ptls_iovec_t *server_name, + uint16_t *key_exchange_id, uint16_t *csid, ptls_iovec_t *negotiated_protocol, const uint8_t *src, + const uint8_t *const end) +{ + int ret = 0; + + ptls_decode_block(src, end, 2, { + if (end - src < SESSION_IDENTIFIER_MAGIC_SIZE || + memcmp(src, SESSION_IDENTIFIER_MAGIC, SESSION_IDENTIFIER_MAGIC_SIZE) != 0) { + ret = PTLS_ALERT_DECODE_ERROR; + goto Exit; + } + src += SESSION_IDENTIFIER_MAGIC_SIZE; + if ((ret = ptls_decode64(issued_at, &src, end)) != 0) + goto Exit; + ptls_decode_open_block(src, end, 2, { + *psk = ptls_iovec_init(src, end - src); + src = end; + }); + if ((ret = ptls_decode16(key_exchange_id, &src, end)) != 0) + goto Exit; + if ((ret = ptls_decode16(csid, &src, end)) != 0) + goto Exit; + if ((ret = ptls_decode32(ticket_age_add, &src, end)) != 0) + goto Exit; + ptls_decode_open_block(src, end, 2, { + *server_name = ptls_iovec_init(src, end - src); + src = end; + }); + ptls_decode_open_block(src, end, 1, { + *negotiated_protocol = ptls_iovec_init(src, end - src); + src = end; + }); + }); + +Exit: + return ret; +} + +static size_t build_certificate_verify_signdata(uint8_t *data, struct st_ptls_key_schedule_t *sched, const char *context_string) +{ + size_t datalen = 0; + + memset(data + datalen, 32, 64); + datalen += 64; + memcpy(data + datalen, context_string, strlen(context_string) + 1); + datalen += strlen(context_string) + 1; + sched->hashes[0].ctx->final(sched->hashes[0].ctx, data + datalen, PTLS_HASH_FINAL_MODE_SNAPSHOT); + datalen += sched->hashes[0].algo->digest_size; + assert(datalen <= PTLS_MAX_CERTIFICATE_VERIFY_SIGNDATA_SIZE); + + return datalen; +} + +static int calc_verify_data(void *output, struct st_ptls_key_schedule_t *sched, const void *secret) +{ + ptls_hash_context_t *hmac; + uint8_t digest[PTLS_MAX_DIGEST_SIZE]; + int ret; + + if ((ret = ptls_hkdf_expand_label(sched->hashes[0].algo, digest, sched->hashes[0].algo->digest_size, + ptls_iovec_init(secret, sched->hashes[0].algo->digest_size), "finished", + ptls_iovec_init(NULL, 0), NULL)) != 0) + return ret; + if ((hmac = ptls_hmac_create(sched->hashes[0].algo, digest, sched->hashes[0].algo->digest_size)) == NULL) { + ptls_clear_memory(digest, sizeof(digest)); + return PTLS_ERROR_NO_MEMORY; + } + + sched->hashes[0].ctx->final(sched->hashes[0].ctx, digest, PTLS_HASH_FINAL_MODE_SNAPSHOT); + PTLS_DEBUGF("%s: %02x%02x,%02x%02x\n", __FUNCTION__, ((uint8_t *)secret)[0], ((uint8_t *)secret)[1], digest[0], digest[1]); + hmac->update(hmac, digest, sched->hashes[0].algo->digest_size); + ptls_clear_memory(digest, sizeof(digest)); + hmac->final(hmac, output, PTLS_HASH_FINAL_MODE_FREE); + + return 0; +} + +static int verify_finished(ptls_t *tls, ptls_iovec_t message) +{ + uint8_t verify_data[PTLS_MAX_DIGEST_SIZE]; + int ret; + + if (PTLS_HANDSHAKE_HEADER_SIZE + tls->key_schedule->hashes[0].algo->digest_size != message.len) { + ret = PTLS_ALERT_DECODE_ERROR; + goto Exit; + } + + if ((ret = calc_verify_data(verify_data, tls->key_schedule, tls->traffic_protection.dec.secret)) != 0) + goto Exit; + if (memcmp(message.base + PTLS_HANDSHAKE_HEADER_SIZE, verify_data, tls->key_schedule->hashes[0].algo->digest_size) != 0) { + ret = PTLS_ALERT_HANDSHAKE_FAILURE; + goto Exit; + } + +Exit: + ptls_clear_memory(verify_data, sizeof(verify_data)); + return ret; +} + +static int send_finished(ptls_t *tls, ptls_buffer_t *sendbuf) +{ + int ret; + + buffer_push_handshake(sendbuf, tls->key_schedule, &tls->traffic_protection.enc, PTLS_HANDSHAKE_TYPE_FINISHED, { + if ((ret = ptls_buffer_reserve(sendbuf, tls->key_schedule->hashes[0].algo->digest_size)) != 0) + goto Exit; + if ((ret = calc_verify_data(sendbuf->base + sendbuf->off, tls->key_schedule, tls->traffic_protection.enc.secret)) != 0) + goto Exit; + sendbuf->off += tls->key_schedule->hashes[0].algo->digest_size; + }); + +Exit: + return ret; +} + +static int send_session_ticket(ptls_t *tls, ptls_buffer_t *sendbuf) +{ + ptls_hash_context_t *msghash_backup = tls->key_schedule->hashes[0].ctx->clone_(tls->key_schedule->hashes[0].ctx); + ptls_buffer_t session_id; + char session_id_smallbuf[128]; + uint32_t ticket_age_add; + int ret = 0; + + assert(tls->ctx->ticket_lifetime != 0); + assert(tls->ctx->encrypt_ticket != NULL); + + { /* calculate verify-data that will be sent by the client */ + size_t orig_off = sendbuf->off; + if (tls->early_data != NULL) { + assert(tls->state == PTLS_STATE_SERVER_EXPECT_END_OF_EARLY_DATA); + buffer_push_handshake_body(sendbuf, tls->key_schedule, PTLS_HANDSHAKE_TYPE_END_OF_EARLY_DATA, {}); + sendbuf->off = orig_off; + } + buffer_push_handshake_body(sendbuf, tls->key_schedule, PTLS_HANDSHAKE_TYPE_FINISHED, { + if ((ret = ptls_buffer_reserve(sendbuf, tls->key_schedule->hashes[0].algo->digest_size)) != 0) + goto Exit; + if ((ret = calc_verify_data(sendbuf->base + sendbuf->off, tls->key_schedule, + tls->early_data != NULL ? tls->early_data->next_secret + : tls->traffic_protection.dec.secret)) != 0) + goto Exit; + sendbuf->off += tls->key_schedule->hashes[0].algo->digest_size; + }); + sendbuf->off = orig_off; + } + + tls->ctx->random_bytes(&ticket_age_add, sizeof(ticket_age_add)); + + /* build the raw nsk */ + ptls_buffer_init(&session_id, session_id_smallbuf, sizeof(session_id_smallbuf)); + ret = encode_session_identifier(tls->ctx, &session_id, ticket_age_add, ptls_iovec_init(NULL, 0), tls->key_schedule, + tls->server_name, tls->key_share->id, tls->cipher_suite->id, tls->negotiated_protocol); + if (ret != 0) + goto Exit; + + /* encrypt and send */ + buffer_push_handshake(sendbuf, tls->key_schedule, &tls->traffic_protection.enc, PTLS_HANDSHAKE_TYPE_NEW_SESSION_TICKET, { + ptls_buffer_push32(sendbuf, tls->ctx->ticket_lifetime); + ptls_buffer_push32(sendbuf, ticket_age_add); + ptls_buffer_push_block(sendbuf, 1, {}); + ptls_buffer_push_block(sendbuf, 2, { + if ((ret = tls->ctx->encrypt_ticket->cb(tls->ctx->encrypt_ticket, tls, 1, sendbuf, + ptls_iovec_init(session_id.base, session_id.off))) != 0) + goto Exit; + }); + ptls_buffer_push_block(sendbuf, 2, { + if (tls->ctx->max_early_data_size != 0) + buffer_push_extension(sendbuf, PTLS_EXTENSION_TYPE_EARLY_DATA, + { ptls_buffer_push32(sendbuf, tls->ctx->max_early_data_size); }); + }); + }); + +Exit: + ptls_buffer_dispose(&session_id); + + /* restore handshake state */ + tls->key_schedule->hashes[0].ctx->final(tls->key_schedule->hashes[0].ctx, NULL, PTLS_HASH_FINAL_MODE_FREE); + tls->key_schedule->hashes[0].ctx = msghash_backup; + + return ret; +} + +static int push_change_cipher_spec(ptls_t *tls, ptls_buffer_t *sendbuf) +{ + int ret = 0; + + if (!tls->send_change_cipher_spec) + goto Exit; + buffer_push_record(sendbuf, PTLS_CONTENT_TYPE_CHANGE_CIPHER_SPEC, { ptls_buffer_push(sendbuf, 1); }); + tls->send_change_cipher_spec = 0; +Exit: + return ret; +} + +static int push_additional_extensions(ptls_handshake_properties_t *properties, ptls_buffer_t *sendbuf) +{ + int ret; + + if (properties != NULL && properties->additional_extensions != NULL) { + ptls_raw_extension_t *ext; + for (ext = properties->additional_extensions; ext->type != UINT16_MAX; ++ext) { + buffer_push_extension(sendbuf, ext->type, { ptls_buffer_pushv(sendbuf, ext->data.base, ext->data.len); }); + } + } + ret = 0; +Exit: + return ret; +} + +static int send_client_hello(ptls_t *tls, ptls_buffer_t *sendbuf, ptls_handshake_properties_t *properties, ptls_iovec_t *cookie) +{ + ptls_iovec_t resumption_secret = {NULL}, resumption_ticket; + uint32_t obfuscated_ticket_age = 0; + size_t msghash_off; + uint8_t binder_key[PTLS_MAX_DIGEST_SIZE]; + int ret, is_second_flight = tls->key_schedule != NULL; + + if (properties != NULL) { + /* setup resumption-related data. If successful, resumption_secret becomes a non-zero value. */ + if (properties->client.session_ticket.base != NULL) { + ptls_key_exchange_algorithm_t *key_share = NULL; + ptls_cipher_suite_t *cipher_suite = NULL; + uint32_t max_early_data_size; + if (decode_stored_session_ticket(tls->ctx, &key_share, &cipher_suite, &resumption_secret, &obfuscated_ticket_age, + &resumption_ticket, &max_early_data_size, properties->client.session_ticket.base, + properties->client.session_ticket.base + properties->client.session_ticket.len) == 0) { + tls->client.offered_psk = 1; + tls->key_share = key_share; + tls->cipher_suite = cipher_suite; + if (!is_second_flight && max_early_data_size != 0 && properties->client.max_early_data_size != NULL) { + *properties->client.max_early_data_size = max_early_data_size; + if ((tls->early_data = malloc(sizeof(*tls->early_data))) == NULL) { + ret = PTLS_ERROR_NO_MEMORY; + goto Exit; + } + } + } else { + resumption_secret = ptls_iovec_init(NULL, 0); + } + } + if (properties->client.max_early_data_size != NULL && tls->early_data == NULL) + *properties->client.max_early_data_size = 0; + } + + /* use the default key share if still not undetermined */ + if (tls->key_share == NULL && !(properties != NULL && properties->client.negotiate_before_key_exchange)) + tls->key_share = tls->ctx->key_exchanges[0]; + + if (!is_second_flight) { + tls->key_schedule = key_schedule_new(tls->cipher_suite, tls->ctx->cipher_suites); + if ((ret = key_schedule_extract(tls->key_schedule, resumption_secret)) != 0) + goto Exit; + } + + msghash_off = sendbuf->off + 5; + buffer_push_handshake(sendbuf, NULL, NULL, PTLS_HANDSHAKE_TYPE_CLIENT_HELLO, { + /* legacy_version */ + ptls_buffer_push16(sendbuf, 0x0303); + /* random_bytes */ + ptls_buffer_pushv(sendbuf, tls->client_random, sizeof(tls->client_random)); + /* lecagy_session_id */ + ptls_buffer_push_block( + sendbuf, 1, { ptls_buffer_pushv(sendbuf, tls->client.legacy_session_id, sizeof(tls->client.legacy_session_id)); }); + /* cipher_suites */ + ptls_buffer_push_block(sendbuf, 2, { + ptls_cipher_suite_t **cs = tls->ctx->cipher_suites; + for (; *cs != NULL; ++cs) + ptls_buffer_push16(sendbuf, (*cs)->id); + }); + /* legacy_compression_methods */ + ptls_buffer_push_block(sendbuf, 1, { ptls_buffer_push(sendbuf, 0); }); + /* extensions */ + ptls_buffer_push_block(sendbuf, 2, { + if (tls->server_name != NULL) { + buffer_push_extension(sendbuf, PTLS_EXTENSION_TYPE_SERVER_NAME, { + ptls_buffer_push_block(sendbuf, 2, { + ptls_buffer_push(sendbuf, PTLS_SERVER_NAME_TYPE_HOSTNAME); + ptls_buffer_push_block(sendbuf, 2, + { ptls_buffer_pushv(sendbuf, tls->server_name, strlen(tls->server_name)); }); + }); + }); + } + if (properties != NULL && properties->client.negotiated_protocols.count != 0) { + buffer_push_extension(sendbuf, PTLS_EXTENSION_TYPE_ALPN, { + ptls_buffer_push_block(sendbuf, 2, { + size_t i; + for (i = 0; i != properties->client.negotiated_protocols.count; ++i) { + ptls_buffer_push_block(sendbuf, 1, { + ptls_iovec_t p = properties->client.negotiated_protocols.list[i]; + ptls_buffer_pushv(sendbuf, p.base, p.len); + }); + } + }); + }); + } + buffer_push_extension(sendbuf, PTLS_EXTENSION_TYPE_SUPPORTED_VERSIONS, { + ptls_buffer_push_block(sendbuf, 1, { + size_t i; + for (i = 0; i != sizeof(supported_versions) / sizeof(supported_versions[0]); ++i) + ptls_buffer_push16(sendbuf, supported_versions[i]); + }); + }); + buffer_push_extension(sendbuf, PTLS_EXTENSION_TYPE_SIGNATURE_ALGORITHMS, { + ptls_buffer_push_block(sendbuf, 2, { + ptls_buffer_push16(sendbuf, PTLS_SIGNATURE_RSA_PSS_RSAE_SHA256); + ptls_buffer_push16(sendbuf, PTLS_SIGNATURE_ECDSA_SECP256R1_SHA256); + ptls_buffer_push16(sendbuf, PTLS_SIGNATURE_RSA_PKCS1_SHA256); + ptls_buffer_push16(sendbuf, PTLS_SIGNATURE_RSA_PKCS1_SHA1); + }); + }); + buffer_push_extension(sendbuf, PTLS_EXTENSION_TYPE_SUPPORTED_GROUPS, { + ptls_key_exchange_algorithm_t **algo = tls->ctx->key_exchanges; + ptls_buffer_push_block(sendbuf, 2, { + for (; *algo != NULL; ++algo) + ptls_buffer_push16(sendbuf, (*algo)->id); + }); + }); + buffer_push_extension(sendbuf, PTLS_EXTENSION_TYPE_KEY_SHARE, { + ptls_buffer_push_block(sendbuf, 2, { + if (tls->key_share != NULL) { + ptls_iovec_t pubkey; + if ((ret = tls->key_share->create(&tls->client.key_share_ctx, &pubkey)) != 0) + goto Exit; + ptls_buffer_push16(sendbuf, tls->key_share->id); + ptls_buffer_push_block(sendbuf, 2, { ptls_buffer_pushv(sendbuf, pubkey.base, pubkey.len); }); + } + }); + }); + if (cookie != NULL && cookie->base != NULL) { + buffer_push_extension(sendbuf, PTLS_EXTENSION_TYPE_COOKIE, { + ptls_buffer_push_block(sendbuf, 2, { ptls_buffer_pushv(sendbuf, cookie->base, cookie->len); }); + }); + } + if ((ret = push_additional_extensions(properties, sendbuf)) != 0) + goto Exit; + if (tls->ctx->save_ticket != NULL) { + buffer_push_extension(sendbuf, PTLS_EXTENSION_TYPE_PSK_KEY_EXCHANGE_MODES, { + ptls_buffer_push_block(sendbuf, 1, { + if (!tls->ctx->require_dhe_on_psk) + ptls_buffer_push(sendbuf, PTLS_PSK_KE_MODE_PSK); + ptls_buffer_push(sendbuf, PTLS_PSK_KE_MODE_PSK_DHE); + }); + }); + if (resumption_secret.base != NULL) { + if (tls->early_data != NULL && !is_second_flight) + buffer_push_extension(sendbuf, PTLS_EXTENSION_TYPE_EARLY_DATA, {}); + /* pre-shared key "MUST be the last extension in the ClientHello" (draft-17 section 4.2.6) */ + buffer_push_extension(sendbuf, PTLS_EXTENSION_TYPE_PRE_SHARED_KEY, { + ptls_buffer_push_block(sendbuf, 2, { + ptls_buffer_push_block(sendbuf, 2, + { ptls_buffer_pushv(sendbuf, resumption_ticket.base, resumption_ticket.len); }); + ptls_buffer_push32(sendbuf, obfuscated_ticket_age); + }); + /* allocate space for PSK binder. the space is filled at the bottom of the function */ + ptls_buffer_push_block(sendbuf, 2, { + ptls_buffer_push_block(sendbuf, 1, { + if ((ret = ptls_buffer_reserve(sendbuf, tls->key_schedule->hashes[0].algo->digest_size)) != 0) + goto Exit; + sendbuf->off += tls->key_schedule->hashes[0].algo->digest_size; + }); + }); + }); + } + } + }); + }); + + /* update the message hash, filling in the PSK binder HMAC if necessary */ + if (resumption_secret.base != NULL) { + size_t psk_binder_off = sendbuf->off - (3 + tls->key_schedule->hashes[0].algo->digest_size); + if ((ret = derive_secret_with_empty_digest(tls->key_schedule, binder_key, "res binder")) != 0) + goto Exit; + key_schedule_update_hash(tls->key_schedule, sendbuf->base + msghash_off, psk_binder_off - msghash_off); + msghash_off = psk_binder_off; + if ((ret = calc_verify_data(sendbuf->base + psk_binder_off + 3, tls->key_schedule, binder_key)) != 0) + goto Exit; + } + key_schedule_update_hash(tls->key_schedule, sendbuf->base + msghash_off, sendbuf->off - msghash_off); + + if (tls->early_data != NULL) { + if ((ret = setup_traffic_protection(tls, 1, "c e traffic", "CLIENT_EARLY_TRAFFIC_SECRET")) != 0) + goto Exit; + if ((ret = push_change_cipher_spec(tls, sendbuf)) != 0) + goto Exit; + } + if (resumption_secret.base != NULL && !is_second_flight) { + if ((ret = derive_exporter_secret(tls, 1)) != 0) + goto Exit; + } + tls->state = cookie == NULL ? PTLS_STATE_CLIENT_EXPECT_SERVER_HELLO : PTLS_STATE_CLIENT_EXPECT_SECOND_SERVER_HELLO; + ret = PTLS_ERROR_IN_PROGRESS; + +Exit: + ptls_clear_memory(binder_key, sizeof(binder_key)); + return ret; +} + +static int decode_key_share_entry(uint16_t *group, ptls_iovec_t *key_exchange, const uint8_t **src, const uint8_t *const end) +{ + int ret; + + if ((ret = ptls_decode16(group, src, end)) != 0) + goto Exit; + ptls_decode_open_block(*src, end, 2, { + *key_exchange = ptls_iovec_init(*src, end - *src); + *src = end; + }); + +Exit: + return ret; +} + +static ptls_cipher_suite_t *find_cipher_suite(ptls_context_t *ctx, uint16_t id) +{ + ptls_cipher_suite_t **cs; + + for (cs = ctx->cipher_suites; *cs != NULL && (*cs)->id != id; ++cs) + ; + return *cs; +} + +static int decode_server_hello(ptls_t *tls, struct st_ptls_server_hello_t *sh, const uint8_t *src, const uint8_t *const end) +{ + int ret; + + *sh = (struct st_ptls_server_hello_t){{0}}; + + /* ignore legacy-version */ + if (end - src < 2) { + ret = PTLS_ALERT_DECODE_ERROR; + goto Exit; + } + src += 2; + + /* random */ + if (end - src < PTLS_HELLO_RANDOM_SIZE) { + ret = PTLS_ALERT_DECODE_ERROR; + goto Exit; + } + sh->is_retry_request = memcmp(src, hello_retry_random, PTLS_HELLO_RANDOM_SIZE) == 0; + src += PTLS_HELLO_RANDOM_SIZE; + + /* legacy_session_id */ + ptls_decode_open_block(src, end, 1, { + if (end - src > 32) { + ret = PTLS_ALERT_DECODE_ERROR; + goto Exit; + } + sh->legacy_session_id = ptls_iovec_init(src, end - src); + src = end; + }); + + { /* select cipher_suite */ + uint16_t csid; + if ((ret = ptls_decode16(&csid, &src, end)) != 0) + goto Exit; + if ((tls->cipher_suite = find_cipher_suite(tls->ctx, csid)) == NULL) { + ret = PTLS_ALERT_ILLEGAL_PARAMETER; + goto Exit; + } + } + + /* legacy_compression_method */ + if (src == end || *src++ != 0) { + ret = PTLS_ALERT_ILLEGAL_PARAMETER; + goto Exit; + } + + if (sh->is_retry_request) + sh->retry_request.selected_group = UINT16_MAX; + + uint16_t exttype, found_version = UINT16_MAX, selected_psk_identity = UINT16_MAX; + decode_extensions(src, end, PTLS_HANDSHAKE_TYPE_SERVER_HELLO, &exttype, { + switch (exttype) { + case PTLS_EXTENSION_TYPE_SUPPORTED_VERSIONS: + if ((ret = ptls_decode16(&found_version, &src, end)) != 0) + goto Exit; + break; + case PTLS_EXTENSION_TYPE_KEY_SHARE: + if (sh->is_retry_request) { + if ((ret = ptls_decode16(&sh->retry_request.selected_group, &src, end)) != 0) + goto Exit; + } else { + uint16_t group; + if ((ret = decode_key_share_entry(&group, &sh->peerkey, &src, end)) != 0) + goto Exit; + if (src != end) { + ret = PTLS_ALERT_DECODE_ERROR; + goto Exit; + } + if (tls->key_share == NULL || tls->key_share->id != group) { + ret = PTLS_ALERT_ILLEGAL_PARAMETER; + goto Exit; + } + } + break; + case PTLS_EXTENSION_TYPE_COOKIE: + if (sh->is_retry_request) { + ptls_decode_block(src, end, 2, { + if (src == end) { + ret = PTLS_ALERT_DECODE_ERROR; + goto Exit; + } + sh->retry_request.cookie = ptls_iovec_init(src, end - src); + src = end; + }); + } else { + ret = PTLS_ALERT_ILLEGAL_PARAMETER; + goto Exit; + } + break; + case PTLS_EXTENSION_TYPE_PRE_SHARED_KEY: + if (sh->is_retry_request) { + ret = PTLS_ALERT_ILLEGAL_PARAMETER; + goto Exit; + } else { + if ((ret = ptls_decode16(&selected_psk_identity, &src, end)) != 0) + goto Exit; + } + break; + default: + src = end; + break; + } + }); + + if (!is_supported_version(found_version)) { + ret = PTLS_ALERT_ILLEGAL_PARAMETER; + goto Exit; + } + if (!sh->is_retry_request) { + if (selected_psk_identity != UINT16_MAX) { + if (!tls->client.offered_psk) { + ret = PTLS_ALERT_ILLEGAL_PARAMETER; + goto Exit; + } + if (selected_psk_identity != 0) { + ret = PTLS_ALERT_ILLEGAL_PARAMETER; + goto Exit; + } + tls->is_psk_handshake = 1; + } + if (sh->peerkey.base == NULL && !tls->is_psk_handshake) { + ret = PTLS_ALERT_ILLEGAL_PARAMETER; + goto Exit; + } + } + + ret = 0; +Exit: + return ret; +} + +static int handle_hello_retry_request(ptls_t *tls, ptls_buffer_t *sendbuf, struct st_ptls_server_hello_t *sh, ptls_iovec_t message, + ptls_handshake_properties_t *properties) +{ + int ret; + + if (tls->client.key_share_ctx != NULL) { + tls->client.key_share_ctx->on_exchange(&tls->client.key_share_ctx, NULL, ptls_iovec_init(NULL, 0)); + tls->client.key_share_ctx = NULL; + } + + if (sh->retry_request.selected_group != UINT16_MAX) { + /* we offer the first key_exchanges[0] as KEY_SHARE unless client.negotiate_before_key_exchange is set */ + ptls_key_exchange_algorithm_t **cand; + for (cand = tls->ctx->key_exchanges; *cand != NULL; ++cand) + if ((*cand)->id == sh->retry_request.selected_group) + break; + if (*cand == NULL) { + ret = PTLS_ALERT_ILLEGAL_PARAMETER; + goto Exit; + } + tls->key_share = *cand; + } else if (tls->key_share != NULL) { + /* retain the key-share using in first CH, if server does not specify one */ + } else { + ret = PTLS_ALERT_ILLEGAL_PARAMETER; + goto Exit; + } + + key_schedule_transform_post_ch1hash(tls->key_schedule); + key_schedule_update_hash(tls->key_schedule, message.base, message.len); + ret = send_client_hello(tls, sendbuf, properties, &sh->retry_request.cookie); + +Exit: + return ret; +} + +static int client_handle_hello(ptls_t *tls, ptls_buffer_t *sendbuf, ptls_iovec_t message, ptls_handshake_properties_t *properties) +{ + struct st_ptls_server_hello_t sh; + ptls_iovec_t ecdh_secret = {NULL}; + int ret; + + if ((ret = decode_server_hello(tls, &sh, message.base + PTLS_HANDSHAKE_HEADER_SIZE, message.base + message.len)) != 0) + goto Exit; + if (!(sh.legacy_session_id.len == sizeof(tls->client.legacy_session_id) && + memcmp(sh.legacy_session_id.base, tls->client.legacy_session_id, sizeof(tls->client.legacy_session_id)) == 0)) { + ret = PTLS_ALERT_ILLEGAL_PARAMETER; + goto Exit; + } + + if (sh.is_retry_request) { + if ((ret = key_schedule_select_one(tls->key_schedule, tls->cipher_suite, 0)) != 0) + goto Exit; + return handle_hello_retry_request(tls, sendbuf, &sh, message, properties); + } + + if ((ret = key_schedule_select_one(tls->key_schedule, tls->cipher_suite, tls->client.offered_psk && !tls->is_psk_handshake)) != + 0) + goto Exit; + + if (sh.peerkey.base != NULL) { + if ((ret = tls->client.key_share_ctx->on_exchange(&tls->client.key_share_ctx, &ecdh_secret, sh.peerkey)) != 0) + goto Exit; + } + + key_schedule_update_hash(tls->key_schedule, message.base, message.len); + + if ((ret = key_schedule_extract(tls->key_schedule, ecdh_secret)) != 0) + goto Exit; + if ((ret = setup_traffic_protection(tls, 0, "s hs traffic", "SERVER_HANDSHAKE_TRAFFIC_SECRET")) != 0) + goto Exit; + + tls->state = PTLS_STATE_CLIENT_EXPECT_ENCRYPTED_EXTENSIONS; + ret = PTLS_ERROR_IN_PROGRESS; + +Exit: + if (ecdh_secret.base != NULL) { + ptls_clear_memory(ecdh_secret.base, ecdh_secret.len); + free(ecdh_secret.base); + } + return ret; +} + +static int handle_unknown_extension(ptls_t *tls, ptls_handshake_properties_t *properties, uint16_t type, const uint8_t *src, + const uint8_t *const end, ptls_raw_extension_t *slots) +{ + + if (properties != NULL && properties->collect_extension != NULL && properties->collect_extension(tls, properties, type)) { + size_t i; + for (i = 0; slots[i].type != UINT16_MAX; ++i) { + assert(i < MAX_UNKNOWN_EXTENSIONS); + if (slots[i].type == type) + return PTLS_ALERT_ILLEGAL_PARAMETER; + } + if (i < MAX_UNKNOWN_EXTENSIONS) { + slots[i].type = type; + slots[i].data = ptls_iovec_init(src, end - src); + slots[i + 1].type = UINT16_MAX; + } + } + return 0; +} + +static int report_unknown_extensions(ptls_t *tls, ptls_handshake_properties_t *properties, ptls_raw_extension_t *slots) +{ + if (properties != NULL && properties->collect_extension != NULL) { + assert(properties->collected_extensions != NULL); + return properties->collected_extensions(tls, properties, slots); + } else { + return 0; + } +} + +static int client_handle_encrypted_extensions(ptls_t *tls, ptls_iovec_t message, ptls_handshake_properties_t *properties) +{ + const uint8_t *src = message.base + PTLS_HANDSHAKE_HEADER_SIZE, *const end = message.base + message.len; + uint16_t type; + ptls_raw_extension_t unknown_extensions[MAX_UNKNOWN_EXTENSIONS + 1]; + int ret, skip_early_data = 1; + + unknown_extensions[0].type = UINT16_MAX; + + decode_extensions(src, end, PTLS_HANDSHAKE_TYPE_ENCRYPTED_EXTENSIONS, &type, { + switch (type) { + case PTLS_EXTENSION_TYPE_SERVER_NAME: + if (src != end) { + ret = PTLS_ALERT_DECODE_ERROR; + goto Exit; + } + if (tls->server_name == NULL) { + ret = PTLS_ALERT_ILLEGAL_PARAMETER; + goto Exit; + } + break; + case PTLS_EXTENSION_TYPE_ALPN: + ptls_decode_block(src, end, 2, { + ptls_decode_open_block(src, end, 1, { + if ((ret = ptls_set_negotiated_protocol(tls, (const char *)src, end - src)) != 0) + goto Exit; + src = end; + }); + if (src != end) { + ret = PTLS_ALERT_HANDSHAKE_FAILURE; + goto Exit; + } + }); + break; + case PTLS_EXTENSION_TYPE_EARLY_DATA: + if (tls->early_data == NULL) { + ret = PTLS_ALERT_ILLEGAL_PARAMETER; + goto Exit; + } + skip_early_data = 0; + break; + default: + handle_unknown_extension(tls, properties, type, src, end, unknown_extensions); + break; + } + src = end; + }); + + if (tls->early_data != NULL) { + tls->skip_early_data = skip_early_data; + if (properties != NULL && !skip_early_data) + properties->client.early_data_accepted_by_peer = 1; + if ((ret = derive_secret(tls->key_schedule, tls->early_data->next_secret, "c hs traffic")) != 0) + goto Exit; + } else { + if ((ret = setup_traffic_protection(tls, 1, "c hs traffic", "CLIENT_HANDSHAKE_TRAFFIC_SECRET")) != 0) + goto Exit; + } + if ((ret = report_unknown_extensions(tls, properties, unknown_extensions)) != 0) + goto Exit; + + key_schedule_update_hash(tls->key_schedule, message.base, message.len); + tls->state = tls->is_psk_handshake ? PTLS_STATE_CLIENT_EXPECT_FINISHED : PTLS_STATE_CLIENT_EXPECT_CERTIFICATE; + ret = PTLS_ERROR_IN_PROGRESS; + +Exit: + return ret; +} + +static int client_handle_certificate(ptls_t *tls, ptls_iovec_t message) +{ + const uint8_t *src = message.base + PTLS_HANDSHAKE_HEADER_SIZE, *const end = message.base + message.len; + ptls_iovec_t certs[16]; + size_t num_certs = 0; + int ret; + + /* certificate request context */ + ptls_decode_open_block(src, end, 1, { + if (src != end) { + ret = PTLS_ALERT_ILLEGAL_PARAMETER; + goto Exit; + } + }); + /* certificate_list */ + ptls_decode_block(src, end, 3, { + do { + ptls_decode_open_block(src, end, 3, { + if (num_certs < sizeof(certs) / sizeof(certs[0])) + certs[num_certs++] = ptls_iovec_init(src, end - src); + src = end; + }); + uint16_t type; + decode_open_extensions(src, end, PTLS_HANDSHAKE_TYPE_CERTIFICATE, &type, { src = end; }); + } while (src != end); + }); + + if (tls->ctx->verify_certificate != NULL) { + if ((ret = tls->ctx->verify_certificate->cb(tls->ctx->verify_certificate, tls, &tls->client.certificate_verify.cb, + &tls->client.certificate_verify.verify_ctx, certs, num_certs)) != 0) + goto Exit; + } + + key_schedule_update_hash(tls->key_schedule, message.base, message.len); + tls->state = PTLS_STATE_CLIENT_EXPECT_CERTIFICATE_VERIFY; + ret = PTLS_ERROR_IN_PROGRESS; + +Exit: + return ret; +} + +static int client_handle_certificate_verify(ptls_t *tls, ptls_iovec_t message) +{ + const uint8_t *src = message.base + PTLS_HANDSHAKE_HEADER_SIZE, *const end = message.base + message.len; + uint16_t algo; + ptls_iovec_t signature; + uint8_t signdata[PTLS_MAX_CERTIFICATE_VERIFY_SIGNDATA_SIZE]; + size_t signdata_size; + int ret; + + /* decode */ + if ((ret = ptls_decode16(&algo, &src, end)) != 0) + goto Exit; + ptls_decode_block(src, end, 2, { + signature = ptls_iovec_init(src, end - src); + src = end; + }); + + /* validate */ + switch (algo) { + case PTLS_SIGNATURE_RSA_PSS_RSAE_SHA256: + case PTLS_SIGNATURE_ECDSA_SECP256R1_SHA256: + /* ok */ + break; + default: + ret = PTLS_ALERT_ILLEGAL_PARAMETER; + goto Exit; + } + signdata_size = build_certificate_verify_signdata(signdata, tls->key_schedule, PTLS_SERVER_CERTIFICATE_VERIFY_CONTEXT_STRING); + if (tls->client.certificate_verify.cb != NULL) { + ret = tls->client.certificate_verify.cb(tls->client.certificate_verify.verify_ctx, ptls_iovec_init(signdata, signdata_size), + signature); + } else { + ret = 0; + } + ptls_clear_memory(signdata, signdata_size); + tls->client.certificate_verify.cb = NULL; + if (ret != 0) + goto Exit; + + key_schedule_update_hash(tls->key_schedule, message.base, message.len); + tls->state = PTLS_STATE_CLIENT_EXPECT_FINISHED; + ret = PTLS_ERROR_IN_PROGRESS; + +Exit: + return ret; +} + +static int client_handle_finished(ptls_t *tls, ptls_buffer_t *sendbuf, ptls_iovec_t message) +{ + uint8_t send_secret[PTLS_MAX_DIGEST_SIZE]; + int ret; + + if ((ret = verify_finished(tls, message)) != 0) + goto Exit; + key_schedule_update_hash(tls->key_schedule, message.base, message.len); + + /* update traffic keys by using messages upto ServerFinished, but commission them after sending ClientFinished */ + if ((ret = key_schedule_extract(tls->key_schedule, ptls_iovec_init(NULL, 0))) != 0) + goto Exit; + if ((ret = setup_traffic_protection(tls, 0, "s ap traffic", "SERVER_TRAFFIC_SECRET_0")) != 0) + goto Exit; + if ((ret = derive_secret(tls->key_schedule, send_secret, "c ap traffic")) != 0) + goto Exit; + if ((ret = derive_exporter_secret(tls, 0)) != 0) + goto Exit; + + /* if sending early data, emit EOED and commision the client handshake traffic secret */ + if (tls->early_data != NULL) { + assert(tls->traffic_protection.enc.aead != NULL); + if (!tls->skip_early_data) { + buffer_push_handshake(sendbuf, tls->key_schedule, &tls->traffic_protection.enc, PTLS_HANDSHAKE_TYPE_END_OF_EARLY_DATA, + {}); + } + if ((ret = retire_early_data_secret(tls, 1)) != 0) + goto Exit; + } + + if ((ret = push_change_cipher_spec(tls, sendbuf)) != 0) + goto Exit; + ret = send_finished(tls, sendbuf); + + memcpy(tls->traffic_protection.enc.secret, send_secret, sizeof(send_secret)); + if ((ret = setup_traffic_protection(tls, 1, NULL, "CLIENT_TRAFFIC_SECRET_0")) != 0) + goto Exit; + + tls->state = PTLS_STATE_CLIENT_POST_HANDSHAKE; + +Exit: + ptls_clear_memory(send_secret, sizeof(send_secret)); + return ret; +} + +static int client_handle_new_session_ticket(ptls_t *tls, ptls_iovec_t message) +{ + const uint8_t *src = message.base + PTLS_HANDSHAKE_HEADER_SIZE, *const end = message.base + message.len; + ptls_iovec_t ticket_nonce; + int ret; + + { /* verify the format */ + uint32_t ticket_lifetime, ticket_age_add, max_early_data_size; + ptls_iovec_t ticket; + if ((ret = decode_new_session_ticket(&ticket_lifetime, &ticket_age_add, &ticket_nonce, &ticket, &max_early_data_size, src, + end)) != 0) + return ret; + } + + /* do nothing if use of session ticket is disabled */ + if (tls->ctx->save_ticket == NULL) + return 0; + + /* save the extension, along with the key of myself */ + ptls_buffer_t ticket_buf; + uint8_t ticket_buf_small[512]; + ptls_buffer_init(&ticket_buf, ticket_buf_small, sizeof(ticket_buf_small)); + ptls_buffer_push64(&ticket_buf, tls->ctx->get_time->cb(tls->ctx->get_time)); + ptls_buffer_push16(&ticket_buf, tls->key_share->id); + ptls_buffer_push16(&ticket_buf, tls->cipher_suite->id); + ptls_buffer_push_block(&ticket_buf, 3, { ptls_buffer_pushv(&ticket_buf, src, end - src); }); + ptls_buffer_push_block(&ticket_buf, 2, { + if ((ret = ptls_buffer_reserve(&ticket_buf, tls->key_schedule->hashes[0].algo->digest_size)) != 0) + goto Exit; + if ((ret = derive_resumption_secret(tls->key_schedule, ticket_buf.base + ticket_buf.off, ticket_nonce)) != 0) + goto Exit; + ticket_buf.off += tls->key_schedule->hashes[0].algo->digest_size; + }); + + if ((ret = tls->ctx->save_ticket->cb(tls->ctx->save_ticket, tls, ptls_iovec_init(ticket_buf.base, ticket_buf.off))) != 0) + goto Exit; + + ret = 0; +Exit: + ptls_buffer_dispose(&ticket_buf); + return ret; +} + +static int client_hello_decode_server_name(ptls_iovec_t *name, const uint8_t *src, const uint8_t *const end) +{ + int ret = 0; + + ptls_decode_block(src, end, 2, { + if (src == end) { + ret = PTLS_ALERT_DECODE_ERROR; + goto Exit; + } + do { + uint8_t type = *src++; + ptls_decode_open_block(src, end, 2, { + switch (type) { + case PTLS_SERVER_NAME_TYPE_HOSTNAME: + if (memchr(src, '\0', end - src) != 0) { + ret = PTLS_ALERT_ILLEGAL_PARAMETER; + goto Exit; + } + *name = ptls_iovec_init(src, end - src); + break; + default: + break; + } + src = end; + }); + } while (src != end); + }); + +Exit: + return ret; +} + +static int select_cipher_suite(ptls_cipher_suite_t **selected, ptls_cipher_suite_t **candidates, const uint8_t *src, + const uint8_t *const end) +{ + int ret; + + ptls_decode_block(src, end, 2, { + while (src != end) { + uint16_t id; + if ((ret = ptls_decode16(&id, &src, end)) != 0) + goto Exit; + ptls_cipher_suite_t **c = candidates; + for (; *c != NULL; ++c) { + if ((*c)->id == id) { + *selected = *c; + return 0; + } + } + } + }); + + ret = PTLS_ALERT_HANDSHAKE_FAILURE; + +Exit: + return ret; +} + +static int select_key_share(ptls_key_exchange_algorithm_t **selected, ptls_iovec_t *peer_key, + ptls_key_exchange_algorithm_t **candidates, const uint8_t *src, const uint8_t *const end) +{ + int ret; + + ptls_decode_block(src, end, 2, { + while (src != end) { + uint16_t group; + ptls_iovec_t key; + if ((ret = decode_key_share_entry(&group, &key, &src, end)) != 0) + goto Exit; + ptls_key_exchange_algorithm_t **c = candidates; + for (; *c != NULL; ++c) { + if ((*c)->id == group) { + *selected = *c; + *peer_key = key; + return 0; + } + } + } + }); + + *selected = NULL; + ret = 0; + +Exit: + return ret; +} + +static int select_negotiated_group(ptls_key_exchange_algorithm_t **selected, ptls_key_exchange_algorithm_t **candidates, + const uint8_t *src, const uint8_t *const end) +{ + int ret; + + ptls_decode_block(src, end, 2, { + while (src != end) { + uint16_t group; + if ((ret = ptls_decode16(&group, &src, end)) != 0) + goto Exit; + ptls_key_exchange_algorithm_t **c = candidates; + for (; *c != NULL; ++c) { + if ((*c)->id == group) { + *selected = *c; + return 0; + } + } + } + }); + + ret = PTLS_ALERT_HANDSHAKE_FAILURE; + +Exit: + return ret; +} + +static int decode_client_hello(ptls_t *tls, struct st_ptls_client_hello_t *ch, const uint8_t *src, const uint8_t *const end, + ptls_handshake_properties_t *properties) +{ + uint16_t exttype = 0; + int ret; + + { /* check protocol version */ + uint16_t protver; + if ((ret = ptls_decode16(&protver, &src, end)) != 0) + goto Exit; + if (protver != 0x0303) { + ret = PTLS_ALERT_HANDSHAKE_FAILURE; + goto Exit; + } + } + + /* skip random */ + if (end - src < PTLS_HELLO_RANDOM_SIZE) { + ret = PTLS_ALERT_DECODE_ERROR; + goto Exit; + } + ch->random_bytes = src; + src += PTLS_HELLO_RANDOM_SIZE; + + /* skip legacy_session_id */ + ptls_decode_open_block(src, end, 1, { + if (end - src > 32) { + ret = PTLS_ALERT_DECODE_ERROR; + goto Exit; + } + ch->legacy_session_id = ptls_iovec_init(src, end - src); + src = end; + }); + + /* decode and select from ciphersuites */ + ptls_decode_open_block(src, end, 2, { + ch->cipher_suites = ptls_iovec_init(src - 2, end - src + 2); + src = end; + }); + + /* decode legacy_compression_methods */ + ptls_decode_open_block(src, end, 1, { + if (src == end) { + ret = PTLS_ALERT_DECODE_ERROR; + goto Exit; + } + ch->compression_methods.ids = src; + ch->compression_methods.count = end - src; + src = end; + }); + + /* decode extensions */ + decode_extensions(src, end, PTLS_HANDSHAKE_TYPE_CLIENT_HELLO, &exttype, { + switch (exttype) { + case PTLS_EXTENSION_TYPE_SERVER_NAME: + if ((ret = client_hello_decode_server_name(&ch->server_name, src, end)) != 0) + goto Exit; + break; + case PTLS_EXTENSION_TYPE_ALPN: + ptls_decode_block(src, end, 2, { + do { + ptls_decode_open_block(src, end, 1, { + if (ch->alpn.count < sizeof(ch->alpn.list) / sizeof(ch->alpn.list[0])) + ch->alpn.list[ch->alpn.count++] = ptls_iovec_init(src, end - src); + src = end; + }); + } while (src != end); + }); + break; + case PTLS_EXTENSION_TYPE_SUPPORTED_GROUPS: + ch->negotiated_groups = ptls_iovec_init(src, end - src); + break; + case PTLS_EXTENSION_TYPE_SIGNATURE_ALGORITHMS: + ptls_decode_block(src, end, 2, { + do { + uint16_t id; + if ((ret = ptls_decode16(&id, &src, end)) != 0) + goto Exit; + if (ch->signature_algorithms.count < + sizeof(ch->signature_algorithms.list) / sizeof(ch->signature_algorithms.list[0])) + ch->signature_algorithms.list[ch->signature_algorithms.count++] = id; + } while (src != end); + }); + break; + case PTLS_EXTENSION_TYPE_KEY_SHARE: + ch->key_shares = ptls_iovec_init(src, end - src); + break; + case PTLS_EXTENSION_TYPE_SUPPORTED_VERSIONS: + ptls_decode_block(src, end, 1, { + size_t selected_index = sizeof(supported_versions) / sizeof(supported_versions[0]); + do { + size_t i; + uint16_t v; + if ((ret = ptls_decode16(&v, &src, end)) != 0) + goto Exit; + for (i = 0; i != selected_index; ++i) { + if (supported_versions[i] == v) { + selected_index = i; + break; + } + } + } while (src != end); + if (selected_index != sizeof(supported_versions) / sizeof(supported_versions[0])) + ch->selected_version = supported_versions[selected_index]; + }); + break; + case PTLS_EXTENSION_TYPE_COOKIE: + if (properties->server.cookie.key == NULL) { + ret = PTLS_ALERT_ILLEGAL_PARAMETER; + goto Exit; + } + ch->cookie.all = ptls_iovec_init(src, end - src); + ptls_decode_block(src, end, 2, { + ch->cookie.tbs.base = (void *)src; + ptls_decode_open_block(src, end, 2, { + ptls_decode_open_block(src, end, 1, { + ch->cookie.ch1_hash = ptls_iovec_init(src, end - src); + src = end; + }); + if (src == end) { + ret = PTLS_ALERT_DECODE_ERROR; + goto Exit; + } + switch (*src++) { + case 0: + assert(!ch->cookie.sent_key_share); + break; + case 1: + ch->cookie.sent_key_share = 1; + break; + default: + ret = PTLS_ALERT_DECODE_ERROR; + goto Exit; + } + }); + ch->cookie.tbs.len = src - ch->cookie.tbs.base; + ptls_decode_block(src, end, 1, { + ch->cookie.signature = ptls_iovec_init(src, end - src); + src = end; + }); + }); + break; + case PTLS_EXTENSION_TYPE_PRE_SHARED_KEY: { + size_t num_identities = 0; + ptls_decode_open_block(src, end, 2, { + do { + struct st_ptls_client_hello_psk_t psk = {{NULL}}; + ptls_decode_open_block(src, end, 2, { + psk.identity = ptls_iovec_init(src, end - src); + src = end; + }); + if ((ret = ptls_decode32(&psk.obfuscated_ticket_age, &src, end)) != 0) + goto Exit; + if (ch->psk.identities.count < sizeof(ch->psk.identities.list) / sizeof(ch->psk.identities.list[0])) + ch->psk.identities.list[ch->psk.identities.count++] = psk; + ++num_identities; + } while (src != end); + }); + ch->psk.hash_end = src; + ptls_decode_block(src, end, 2, { + size_t num_binders = 0; + do { + ptls_decode_open_block(src, end, 1, { + if (num_binders < ch->psk.identities.count) + ch->psk.identities.list[num_binders].binder = ptls_iovec_init(src, end - src); + src = end; + }); + ++num_binders; + } while (src != end); + if (num_identities != num_binders) { + ret = PTLS_ALERT_ILLEGAL_PARAMETER; + goto Exit; + } + }); + } break; + case PTLS_EXTENSION_TYPE_PSK_KEY_EXCHANGE_MODES: + ptls_decode_block(src, end, 1, { + if (src == end) { + ret = PTLS_ALERT_DECODE_ERROR; + goto Exit; + } + for (; src != end; ++src) { + if (*src < sizeof(ch->psk.ke_modes) * 8) + ch->psk.ke_modes |= 1u << *src; + } + }); + break; + case PTLS_EXTENSION_TYPE_EARLY_DATA: + ch->psk.early_data_indication = 1; + break; + case PTLS_EXTENSION_TYPE_STATUS_REQUEST: + ch->status_request = 1; + break; + default: + handle_unknown_extension(tls, properties, exttype, src, end, ch->unknown_extensions); + break; + } + src = end; + }); + + /* check if client hello make sense */ + if (is_supported_version(ch->selected_version)) { + if (!(ch->compression_methods.count == 1 && ch->compression_methods.ids[0] == 0)) { + ret = PTLS_ALERT_ILLEGAL_PARAMETER; + goto Exit; + } + /* pre-shared key */ + if (ch->psk.hash_end != NULL) { + /* PSK must be the last extension */ + if (exttype != PTLS_EXTENSION_TYPE_PRE_SHARED_KEY) { + ret = PTLS_ALERT_ILLEGAL_PARAMETER; + goto Exit; + } + } else { + if (ch->psk.early_data_indication) { + ret = PTLS_ALERT_ILLEGAL_PARAMETER; + goto Exit; + } + } + } else { + ret = PTLS_ALERT_PROTOCOL_VERSION; + goto Exit; + } + + ret = 0; +Exit: + return ret; +} + +static int vec_is_string(ptls_iovec_t x, const char *y) +{ + return strncmp((const char *)x.base, y, x.len) == 0 && y[x.len] == '\0'; +} + +static int try_psk_handshake(ptls_t *tls, size_t *psk_index, int *accept_early_data, struct st_ptls_client_hello_t *ch, + ptls_iovec_t ch_trunc) +{ + ptls_buffer_t decbuf; + ptls_iovec_t ticket_psk, ticket_server_name, ticket_negotiated_protocol; + uint64_t issue_at, now = tls->ctx->get_time->cb(tls->ctx->get_time); + uint32_t age_add; + uint16_t ticket_key_exchange_id, ticket_csid; + uint8_t decbuf_small[256], binder_key[PTLS_MAX_DIGEST_SIZE], verify_data[PTLS_MAX_DIGEST_SIZE]; + int ret; + + ptls_buffer_init(&decbuf, decbuf_small, sizeof(decbuf_small)); + + for (*psk_index = 0; *psk_index < ch->psk.identities.count; ++*psk_index) { + struct st_ptls_client_hello_psk_t *identity = ch->psk.identities.list + *psk_index; + /* decrypt and decode */ + decbuf.off = 0; + if ((tls->ctx->encrypt_ticket->cb(tls->ctx->encrypt_ticket, tls, 0, &decbuf, identity->identity)) != 0) + continue; + if (decode_session_identifier(&issue_at, &ticket_psk, &age_add, &ticket_server_name, &ticket_key_exchange_id, &ticket_csid, + &ticket_negotiated_protocol, decbuf.base, decbuf.base + decbuf.off) != 0) + continue; + /* check age */ + if (now < issue_at) + continue; + if (now - issue_at > (uint64_t)tls->ctx->ticket_lifetime * 1000) + continue; + *accept_early_data = 0; + if (ch->psk.early_data_indication) { + int64_t delta = (now - issue_at) - (identity->obfuscated_ticket_age - age_add); + if (delta <= PTLS_EARLY_DATA_MAX_DELAY) + *accept_early_data = 1; + } + /* check server-name */ + if (ticket_server_name.len != 0) { + if (tls->server_name == NULL) + continue; + if (!vec_is_string(ticket_server_name, tls->server_name)) + continue; + } else { + if (tls->server_name != NULL) + continue; + } + { /* check key-exchange */ + ptls_key_exchange_algorithm_t **a; + for (a = tls->ctx->key_exchanges; *a != NULL && (*a)->id != ticket_key_exchange_id; ++a) + ; + if (*a == NULL) + continue; + tls->key_share = *a; + } + /* check cipher-suite */ + if (ticket_csid != tls->cipher_suite->id) + continue; + /* check negotiated-protocol */ + if (ticket_negotiated_protocol.len != 0) { + if (tls->negotiated_protocol == NULL) + continue; + if (!vec_is_string(ticket_negotiated_protocol, tls->negotiated_protocol)) + continue; + } + /* check the length of the decrypted psk and the PSK binder */ + if (ticket_psk.len != tls->key_schedule->hashes[0].algo->digest_size) + continue; + if (ch->psk.identities.list[*psk_index].binder.len != tls->key_schedule->hashes[0].algo->digest_size) + continue; + + /* found */ + goto Found; + } + + /* not found */ + *psk_index = SIZE_MAX; + *accept_early_data = 0; + tls->key_share = NULL; + ret = 0; + goto Exit; + +Found: + if ((ret = key_schedule_extract(tls->key_schedule, ticket_psk)) != 0) + goto Exit; + if ((ret = derive_secret(tls->key_schedule, binder_key, "res binder")) != 0) + goto Exit; + key_schedule_update_hash(tls->key_schedule, ch_trunc.base, ch_trunc.len); + if ((ret = calc_verify_data(verify_data, tls->key_schedule, binder_key)) != 0) + goto Exit; + if (memcmp(ch->psk.identities.list[*psk_index].binder.base, verify_data, tls->key_schedule->hashes[0].algo->digest_size) != 0) { + ret = PTLS_ALERT_DECRYPT_ERROR; + goto Exit; + } + ret = 0; + +Exit: + ptls_buffer_dispose(&decbuf); + ptls_clear_memory(binder_key, sizeof(binder_key)); + ptls_clear_memory(verify_data, sizeof(verify_data)); + return ret; +} + +static int calc_cookie_signature(ptls_t *tls, ptls_handshake_properties_t *properties, + ptls_key_exchange_algorithm_t *negotiated_group, ptls_iovec_t tbs, uint8_t *sig) +{ + ptls_hash_algorithm_t *algo = tls->ctx->cipher_suites[0]->hash; + ptls_hash_context_t *hctx; + + if ((hctx = ptls_hmac_create(algo, properties->server.cookie.key, algo->digest_size)) == NULL) + return PTLS_ERROR_NO_MEMORY; + +#define UPDATE_BLOCK(p, _len) \ + do { \ + size_t len = (_len); \ + assert(len < UINT8_MAX); \ + uint8_t len8 = (uint8_t)len; \ + hctx->update(hctx, &len8, 1); \ + hctx->update(hctx, (p), len); \ + } while (0) +#define UPDATE16(_v) \ + do { \ + uint16_t v = (_v); \ + uint8_t b[2] = {v >> 8, v & 0xff}; \ + hctx->update(hctx, b, 2); \ + } while (0) + + UPDATE_BLOCK(tls->client_random, sizeof(tls->client_random)); + UPDATE_BLOCK(tls->server_name, tls->server_name != NULL ? strlen(tls->server_name) : 0); + UPDATE16(tls->cipher_suite->id); + UPDATE16(negotiated_group->id); + UPDATE_BLOCK(properties->server.cookie.additional_data.base, properties->server.cookie.additional_data.len); + + UPDATE_BLOCK(tbs.base, tbs.len); + +#undef UPDATE_BLOCK +#undef UPDATE16 + + hctx->final(hctx, sig, PTLS_HASH_FINAL_MODE_FREE); + return 0; +} + +static int server_handle_hello(ptls_t *tls, ptls_buffer_t *sendbuf, ptls_iovec_t message, ptls_handshake_properties_t *properties) +{ +#define EMIT_SERVER_HELLO(sched, fill_rand, extensions) \ + buffer_push_handshake(sendbuf, (sched), NULL, PTLS_HANDSHAKE_TYPE_SERVER_HELLO, { \ + ptls_buffer_push16(sendbuf, 0x0303 /* legacy version */); \ + if ((ret = ptls_buffer_reserve(sendbuf, PTLS_HELLO_RANDOM_SIZE)) != 0) \ + goto Exit; \ + do { \ + fill_rand \ + } while (0); \ + sendbuf->off += PTLS_HELLO_RANDOM_SIZE; \ + ptls_buffer_push_block(sendbuf, 1, { ptls_buffer_pushv(sendbuf, ch.legacy_session_id.base, ch.legacy_session_id.len); }); \ + ptls_buffer_push16(sendbuf, tls->cipher_suite->id); \ + ptls_buffer_push(sendbuf, 0); \ + ptls_buffer_push_block(sendbuf, 2, { \ + buffer_push_extension(sendbuf, PTLS_EXTENSION_TYPE_SUPPORTED_VERSIONS, \ + { ptls_buffer_push16(sendbuf, ch.selected_version); }); \ + do { \ + extensions \ + } while (0); \ + }); \ + }); + +#define EMIT_HELLO_RETRY_REQUEST(sched, negotiated_group, additional_extensions) \ + EMIT_SERVER_HELLO((sched), { memcpy(sendbuf->base + sendbuf->off, hello_retry_random, PTLS_HELLO_RANDOM_SIZE); }, \ + { \ + ptls_key_exchange_algorithm_t *_negotiated_group = (negotiated_group); \ + if (_negotiated_group != NULL) { \ + buffer_push_extension(sendbuf, PTLS_EXTENSION_TYPE_KEY_SHARE, \ + { ptls_buffer_push16(sendbuf, _negotiated_group->id); }); \ + } \ + do { \ + additional_extensions \ + } while (0); \ + }); + + struct st_ptls_client_hello_t ch = {NULL, {NULL}, {NULL}, 0, {NULL}, {NULL}, {NULL}, + {{0}}, {NULL}, {{{NULL}}}, {{NULL}}, {NULL}, {{UINT16_MAX}}}; + struct { + ptls_key_exchange_algorithm_t *algorithm; + ptls_iovec_t peer_key; + } key_share = {NULL}; + enum { HANDSHAKE_MODE_FULL, HANDSHAKE_MODE_PSK, HANDSHAKE_MODE_PSK_DHE } mode; + size_t psk_index = SIZE_MAX; + ptls_iovec_t pubkey = {0}, ecdh_secret = {0}; + uint8_t finished_key[PTLS_MAX_DIGEST_SIZE]; + int accept_early_data = 0, is_second_flight = tls->state == PTLS_STATE_SERVER_EXPECT_SECOND_CLIENT_HELLO, ret; + + /* decode ClientHello */ + if ((ret = decode_client_hello(tls, &ch, message.base + PTLS_HANDSHAKE_HEADER_SIZE, message.base + message.len, properties)) != + 0) + goto Exit; + if (tls->ctx->require_dhe_on_psk) + ch.psk.ke_modes &= ~(1u << PTLS_PSK_KE_MODE_PSK); + + /* handle client_random and SNI */ + if (!is_second_flight) { + memcpy(tls->client_random, ch.random_bytes, sizeof(tls->client_random)); + if (ch.server_name.base != NULL) { + if ((tls->server_name = malloc(ch.server_name.len + 1)) == NULL) { + ret = PTLS_ERROR_NO_MEMORY; + goto Exit; + } + memcpy(tls->server_name, ch.server_name.base, ch.server_name.len); + tls->server_name[ch.server_name.len] = '\0'; + } + if (tls->ctx->on_client_hello != NULL && + (ret = tls->ctx->on_client_hello->cb(tls->ctx->on_client_hello, tls, ch.server_name, ch.alpn.list, ch.alpn.count, + ch.signature_algorithms.list, ch.signature_algorithms.count)) != 0) + goto Exit; + } else { + if (ch.psk.early_data_indication) { + ret = PTLS_ALERT_DECODE_ERROR; + goto Exit; + } + if (memcmp(tls->client_random, ch.random_bytes, sizeof(tls->client_random)) != 0 || + (tls->server_name != NULL) != (ch.server_name.base != NULL) || + (tls->server_name != NULL && + !(strncmp(tls->server_name, (char *)ch.server_name.base, ch.server_name.len) == 0 && + tls->server_name[ch.server_name.len] == '\0'))) { + ret = PTLS_ALERT_HANDSHAKE_FAILURE; + goto Exit; + } + } + + { /* select (or check) cipher-suite, create key_schedule */ + ptls_cipher_suite_t *cs; + if ((ret = select_cipher_suite(&cs, tls->ctx->cipher_suites, ch.cipher_suites.base, + ch.cipher_suites.base + ch.cipher_suites.len)) != 0) + goto Exit; + if (!is_second_flight) { + tls->cipher_suite = cs; + tls->key_schedule = key_schedule_new(cs, NULL); + } else { + if (tls->cipher_suite != cs) { + ret = PTLS_ALERT_HANDSHAKE_FAILURE; + goto Exit; + } + } + } + + /* select key_share */ + if (ch.key_shares.base != NULL && + (ret = select_key_share(&key_share.algorithm, &key_share.peer_key, tls->ctx->key_exchanges, ch.key_shares.base, + ch.key_shares.base + ch.key_shares.len)) != 0) + goto Exit; + + if (!is_second_flight) { + if (ch.cookie.all.len != 0 && key_share.algorithm != NULL) { + + /* use cookie to check the integrity of the handshake, and update the context */ + uint8_t sig[PTLS_MAX_DIGEST_SIZE]; + size_t sigsize = tls->ctx->cipher_suites[0]->hash->digest_size; + if ((ret = calc_cookie_signature(tls, properties, key_share.algorithm, ch.cookie.tbs, sig)) != 0) + goto Exit; + if (!(ch.cookie.signature.len == sigsize && memcmp(ch.cookie.signature.base, sig, sigsize) == 0)) { + ret = PTLS_ALERT_HANDSHAKE_FAILURE; + goto Exit; + } + /* integrity check passed; update states */ + key_schedule_update_ch1hash_prefix(tls->key_schedule); + key_schedule_update_hash(tls->key_schedule, ch.cookie.ch1_hash.base, ch.cookie.ch1_hash.len); + key_schedule_extract(tls->key_schedule, ptls_iovec_init(NULL, 0)); + /* ... reusing sendbuf to rebuild HRR for hash calculation */ + size_t hrr_start = sendbuf->off; + EMIT_HELLO_RETRY_REQUEST(tls->key_schedule, ch.cookie.sent_key_share ? key_share.algorithm : NULL, { + buffer_push_extension(sendbuf, PTLS_EXTENSION_TYPE_COOKIE, + { ptls_buffer_pushv(sendbuf, ch.cookie.all.base, ch.cookie.all.len); }); + }); + sendbuf->off = hrr_start; + is_second_flight = 1; + + } else if (key_share.algorithm == NULL || (properties != NULL && properties->server.enforce_retry)) { + + /* send HelloRetryRequest */ + if (ch.negotiated_groups.base == NULL) { + ret = PTLS_ALERT_MISSING_EXTENSION; + goto Exit; + } + ptls_key_exchange_algorithm_t *negotiated_group; + if ((ret = select_negotiated_group(&negotiated_group, tls->ctx->key_exchanges, ch.negotiated_groups.base, + ch.negotiated_groups.base + ch.negotiated_groups.len)) != 0) + goto Exit; + key_schedule_update_hash(tls->key_schedule, message.base, message.len); + assert(tls->key_schedule->generation == 0); + if (properties != NULL && properties->server.retry_uses_cookie) { + /* emit HRR with cookie (note: we MUST omit KeyShare if the client has specified the correct one; see 46554f0) */ + EMIT_HELLO_RETRY_REQUEST(NULL, key_share.algorithm != NULL ? NULL : negotiated_group, { + buffer_push_extension(sendbuf, PTLS_EXTENSION_TYPE_COOKIE, { + ptls_buffer_push_block(sendbuf, 2, { + /* push to-be-signed data */ + size_t tbs_start = sendbuf->off; + ptls_buffer_push_block(sendbuf, 2, { + /* first block of the cookie data is the hash(ch1) */ + ptls_buffer_push_block(sendbuf, 1, { + size_t sz = tls->cipher_suite->hash->digest_size; + if ((ret = ptls_buffer_reserve(sendbuf, sz)) != 0) + goto Exit; + key_schedule_extract_ch1hash(tls->key_schedule, sendbuf->base + sendbuf->off); + sendbuf->off += sz; + }); + /* second is if we have sent key_share extension */ + ptls_buffer_push(sendbuf, key_share.algorithm == NULL); + /* we can add more data here */ + }); + size_t tbs_len = sendbuf->off - tbs_start; + /* push the signature */ + ptls_buffer_push_block(sendbuf, 1, { + size_t sz = tls->ctx->cipher_suites[0]->hash->digest_size; + if ((ret = ptls_buffer_reserve(sendbuf, sz)) != 0) + goto Exit; + if ((ret = calc_cookie_signature(tls, properties, negotiated_group, + ptls_iovec_init(sendbuf->base + tbs_start, tbs_len), + sendbuf->base + sendbuf->off)) != 0) + goto Exit; + sendbuf->off += sz; + }); + }); + }); + }); + if ((ret = push_change_cipher_spec(tls, sendbuf)) != 0) + goto Exit; + ret = PTLS_ERROR_STATELESS_RETRY; + } else { + /* invoking stateful retry; roll the key schedule and emit HRR */ + key_schedule_transform_post_ch1hash(tls->key_schedule); + key_schedule_extract(tls->key_schedule, ptls_iovec_init(NULL, 0)); + EMIT_HELLO_RETRY_REQUEST(tls->key_schedule, key_share.algorithm != NULL ? NULL : negotiated_group, {}); + if ((ret = push_change_cipher_spec(tls, sendbuf)) != 0) + goto Exit; + tls->state = PTLS_STATE_SERVER_EXPECT_SECOND_CLIENT_HELLO; + if (ch.psk.early_data_indication) + tls->skip_early_data = 1; + ret = PTLS_ERROR_IN_PROGRESS; + } + goto Exit; + } + } + + /* handle unknown extensions */ + if ((ret = report_unknown_extensions(tls, properties, ch.unknown_extensions)) != 0) + goto Exit; + + /* try psk handshake */ + if (!is_second_flight && ch.psk.hash_end != 0 && + (ch.psk.ke_modes & ((1u << PTLS_PSK_KE_MODE_PSK) | (1u << PTLS_PSK_KE_MODE_PSK_DHE))) != 0 && + tls->ctx->encrypt_ticket != NULL) { + if ((ret = try_psk_handshake(tls, &psk_index, &accept_early_data, &ch, + ptls_iovec_init(message.base, ch.psk.hash_end - message.base))) != 0) + goto Exit; + } + + /* adjust key_schedule, determine handshake mode */ + if (psk_index == SIZE_MAX) { + key_schedule_update_hash(tls->key_schedule, message.base, message.len); + if (!is_second_flight) { + assert(tls->key_schedule->generation == 0); + key_schedule_extract(tls->key_schedule, ptls_iovec_init(NULL, 0)); + } + mode = HANDSHAKE_MODE_FULL; + if (properties != NULL) + properties->server.selected_psk_binder.len = 0; + } else { + key_schedule_update_hash(tls->key_schedule, ch.psk.hash_end, message.base + message.len - ch.psk.hash_end); + if ((ch.psk.ke_modes & (1u << PTLS_PSK_KE_MODE_PSK)) != 0) { + mode = HANDSHAKE_MODE_PSK; + } else { + assert((ch.psk.ke_modes & (1u << PTLS_PSK_KE_MODE_PSK_DHE)) != 0); + mode = HANDSHAKE_MODE_PSK_DHE; + } + tls->is_psk_handshake = 1; + if (properties != NULL) { + ptls_iovec_t *selected = &ch.psk.identities.list[psk_index].binder; + memcpy(properties->server.selected_psk_binder.base, selected->base, selected->len); + properties->server.selected_psk_binder.len = selected->len; + } + if ((ret = derive_exporter_secret(tls, 1)) != 0) + goto Exit; + } + + if (accept_early_data && tls->ctx->max_early_data_size != 0 && psk_index == 0) { + if ((tls->early_data = malloc(sizeof(*tls->early_data))) == NULL) { + ret = PTLS_ERROR_NO_MEMORY; + goto Exit; + } + if ((ret = setup_traffic_protection(tls, 0, "c e traffic", "CLIENT_EARLY_TRAFFIC_SECRET")) != 0) + goto Exit; + } + + /* run key-exchange, to obtain pubkey and secret */ + if (mode != HANDSHAKE_MODE_PSK) { + if (key_share.algorithm == NULL) { + ret = ch.key_shares.base != NULL ? PTLS_ALERT_HANDSHAKE_FAILURE : PTLS_ALERT_MISSING_EXTENSION; + goto Exit; + } + if ((ret = key_share.algorithm->exchange(&pubkey, &ecdh_secret, key_share.peer_key)) != 0) + goto Exit; + tls->key_share = key_share.algorithm; + } + + /* send ServerHello */ + EMIT_SERVER_HELLO(tls->key_schedule, { tls->ctx->random_bytes(sendbuf->base + sendbuf->off, PTLS_HELLO_RANDOM_SIZE); }, + { + if (mode != HANDSHAKE_MODE_PSK) { + buffer_push_extension(sendbuf, PTLS_EXTENSION_TYPE_KEY_SHARE, { + ptls_buffer_push16(sendbuf, key_share.algorithm->id); + ptls_buffer_push_block(sendbuf, 2, { ptls_buffer_pushv(sendbuf, pubkey.base, pubkey.len); }); + }); + } + if (mode != HANDSHAKE_MODE_FULL) { + buffer_push_extension(sendbuf, PTLS_EXTENSION_TYPE_PRE_SHARED_KEY, + { ptls_buffer_push16(sendbuf, (uint16_t)psk_index); }); + } + }); + if ((ret = push_change_cipher_spec(tls, sendbuf)) != 0) + goto Exit; + + /* create protection contexts for the handshake */ + assert(tls->key_schedule->generation == 1); + key_schedule_extract(tls->key_schedule, ecdh_secret); + if ((ret = setup_traffic_protection(tls, 1, "s hs traffic", "SERVER_HANDSHAKE_TRAFFIC_SECRET")) != 0) + goto Exit; + if (tls->early_data != NULL) { + if ((ret = derive_secret(tls->key_schedule, tls->early_data->next_secret, "c hs traffic")) != 0) + goto Exit; + } else { + if ((ret = setup_traffic_protection(tls, 0, "c hs traffic", "CLIENT_HANDSHAKE_TRAFFIC_SECRET")) != 0) + goto Exit; + if (ch.psk.early_data_indication) + tls->skip_early_data = 1; + } + + /* send EncryptedExtensions */ + buffer_push_handshake(sendbuf, tls->key_schedule, &tls->traffic_protection.enc, PTLS_HANDSHAKE_TYPE_ENCRYPTED_EXTENSIONS, { + ptls_buffer_push_block(sendbuf, 2, { + if (tls->server_name != NULL) { + /* In this event, the server SHALL include an extension of type "server_name" in the (extended) server + * hello. The "extension_data" field of this extension SHALL be empty. (RFC 6066 section 3) */ + buffer_push_extension(sendbuf, PTLS_EXTENSION_TYPE_SERVER_NAME, {}); + } + if (tls->negotiated_protocol != NULL) { + buffer_push_extension(sendbuf, PTLS_EXTENSION_TYPE_ALPN, { + ptls_buffer_push_block(sendbuf, 2, { + ptls_buffer_push_block(sendbuf, 1, { + ptls_buffer_pushv(sendbuf, tls->negotiated_protocol, strlen(tls->negotiated_protocol)); + }); + }); + }); + } + if (tls->early_data != NULL && tls->traffic_protection.dec.aead != NULL) + buffer_push_extension(sendbuf, PTLS_EXTENSION_TYPE_EARLY_DATA, {}); + if ((ret = push_additional_extensions(properties, sendbuf)) != 0) + goto Exit; + }); + }); + + if (mode == HANDSHAKE_MODE_FULL) { + if (ch.signature_algorithms.count == 0) { + ret = PTLS_ALERT_MISSING_EXTENSION; + goto Exit; + } + /* send Certificate */ + buffer_push_handshake(sendbuf, tls->key_schedule, &tls->traffic_protection.enc, PTLS_HANDSHAKE_TYPE_CERTIFICATE, { + ptls_buffer_push(sendbuf, 0); + ptls_buffer_push_block(sendbuf, 3, { + size_t i; + for (i = 0; i != tls->ctx->certificates.count; ++i) { + ptls_buffer_push_block(sendbuf, 3, { + ptls_buffer_pushv(sendbuf, tls->ctx->certificates.list[i].base, tls->ctx->certificates.list[i].len); + }); + ptls_buffer_push_block(sendbuf, 2, { + /* emit OCSP stapling only when requested and when the callback successfully returns one */ + if (ch.status_request && i == 0 && tls->ctx->staple_ocsp != NULL) { + size_t reset_off_to = sendbuf->off; + buffer_push_extension(sendbuf, PTLS_EXTENSION_TYPE_STATUS_REQUEST, { + ptls_buffer_push(sendbuf, 1); /* status_type == ocsp */ + ptls_buffer_push_block(sendbuf, 3, { + if ((ret = tls->ctx->staple_ocsp->cb(tls->ctx->staple_ocsp, tls, sendbuf, i)) == 0) + reset_off_to = 0; + }); + }); + if (reset_off_to != 0) + sendbuf->off = reset_off_to; + } + }); + } + }); + }); + /* build and send CertificateVerify */ + buffer_push_handshake(sendbuf, tls->key_schedule, &tls->traffic_protection.enc, PTLS_HANDSHAKE_TYPE_CERTIFICATE_VERIFY, { + size_t algo_off = sendbuf->off; + ptls_buffer_push16(sendbuf, 0); /* filled in later */ + ptls_buffer_push_block(sendbuf, 2, { + uint16_t algo; + uint8_t data[PTLS_MAX_CERTIFICATE_VERIFY_SIGNDATA_SIZE]; + size_t datalen = + build_certificate_verify_signdata(data, tls->key_schedule, PTLS_SERVER_CERTIFICATE_VERIFY_CONTEXT_STRING); + if ((ret = tls->ctx->sign_certificate->cb(tls->ctx->sign_certificate, tls, &algo, sendbuf, + ptls_iovec_init(data, datalen), ch.signature_algorithms.list, + ch.signature_algorithms.count)) != 0) + goto Exit; + sendbuf->base[algo_off] = (uint8_t)(algo >> 8); + sendbuf->base[algo_off + 1] = (uint8_t)algo; + }); + }); + } + + send_finished(tls, sendbuf); + + assert(tls->key_schedule->generation == 2); + if ((ret = key_schedule_extract(tls->key_schedule, ptls_iovec_init(NULL, 0))) != 0) + goto Exit; + if ((ret = setup_traffic_protection(tls, 1, "s ap traffic", "SERVER_TRAFFIC_SECRET_0")) != 0) + goto Exit; + if ((ret = derive_secret(tls->key_schedule, tls->server.pending_traffic_secret, "c ap traffic")) != 0) + goto Exit; + if ((ret = derive_exporter_secret(tls, 0)) != 0) + goto Exit; + + tls->state = tls->early_data != NULL ? PTLS_STATE_SERVER_EXPECT_END_OF_EARLY_DATA : PTLS_STATE_SERVER_EXPECT_FINISHED; + + /* send session ticket if necessary */ + if (ch.psk.ke_modes != 0 && tls->ctx->ticket_lifetime != 0) { + if ((ret = send_session_ticket(tls, sendbuf)) != 0) + goto Exit; + } + + ret = 0; + +Exit: + free(pubkey.base); + free(ecdh_secret.base); + ptls_clear_memory(finished_key, sizeof(finished_key)); + return ret; + +#undef EMIT_SERVER_HELLO +#undef EMIT_HELLO_RETRY_REQUEST +} + +static int server_handle_end_of_early_data(ptls_t *tls, ptls_iovec_t message) +{ + int ret; + + if ((ret = retire_early_data_secret(tls, 0)) != 0) + goto Exit; + + key_schedule_update_hash(tls->key_schedule, message.base, message.len); + tls->state = PTLS_STATE_SERVER_EXPECT_FINISHED; + ret = PTLS_ERROR_IN_PROGRESS; + +Exit: + return ret; +} + +static int server_handle_finished(ptls_t *tls, ptls_iovec_t message) +{ + int ret; + + if ((ret = verify_finished(tls, message)) != 0) + return ret; + + memcpy(tls->traffic_protection.dec.secret, tls->server.pending_traffic_secret, sizeof(tls->server.pending_traffic_secret)); + ptls_clear_memory(tls->server.pending_traffic_secret, sizeof(tls->server.pending_traffic_secret)); + if ((ret = setup_traffic_protection(tls, 0, NULL, "CLIENT_TRAFFIC_SECRET_0")) != 0) + return ret; + + key_schedule_update_hash(tls->key_schedule, message.base, message.len); + + tls->state = PTLS_STATE_SERVER_POST_HANDSHAKE; + return 0; +} + +static int parse_record_header(struct st_ptls_record_t *rec, const uint8_t *src) +{ + rec->type = src[0]; + rec->version = ntoh16(src + 1); + rec->length = ntoh16(src + 3); + + if (rec->length > + (size_t)(rec->type == PTLS_CONTENT_TYPE_APPDATA ? PTLS_MAX_ENCRYPTED_RECORD_SIZE : PTLS_MAX_PLAINTEXT_RECORD_SIZE)) + return PTLS_ALERT_DECODE_ERROR; + + return 0; +} + +static int parse_record(ptls_t *tls, struct st_ptls_record_t *rec, const uint8_t *src, size_t *len) +{ + int ret; + + if (tls->recvbuf.rec.base == NULL && *len >= 5) { + /* fast path */ + if ((ret = parse_record_header(rec, src)) != 0) + return ret; + if (5 + rec->length <= *len) { + rec->fragment = src + 5; + *len = rec->length + 5; + return 0; + } + } + + /* slow path */ + const uint8_t *const end = src + *len; + *rec = (struct st_ptls_record_t){0}; + + if (tls->recvbuf.rec.base == NULL) { + ptls_buffer_init(&tls->recvbuf.rec, "", 0); + if ((ret = ptls_buffer_reserve(&tls->recvbuf.rec, 5)) != 0) + return ret; + } + + /* fill and parse the header */ + while (tls->recvbuf.rec.off < 5) { + if (src == end) + return PTLS_ERROR_IN_PROGRESS; + tls->recvbuf.rec.base[tls->recvbuf.rec.off++] = *src++; + } + if ((ret = parse_record_header(rec, tls->recvbuf.rec.base)) != 0) + return ret; + + /* fill the fragment */ + size_t addlen = rec->length + 5 - tls->recvbuf.rec.off; + if (addlen != 0) { + if ((ret = ptls_buffer_reserve(&tls->recvbuf.rec, addlen)) != 0) + return ret; + if (addlen > (size_t)(end - src)) + addlen = end - src; + if (addlen != 0) { + memcpy(tls->recvbuf.rec.base + tls->recvbuf.rec.off, src, addlen); + tls->recvbuf.rec.off += addlen; + src += addlen; + } + } + + /* set rec->fragment if a complete record has been parsed */ + if (tls->recvbuf.rec.off == rec->length + 5) { + rec->fragment = tls->recvbuf.rec.base + 5; + ret = 0; + } else { + ret = PTLS_ERROR_IN_PROGRESS; + } + + *len -= end - src; + return ret; +} + +static void update_open_count(ptls_context_t *ctx, ssize_t delta) +{ + if (ctx->update_open_count != NULL) + ctx->update_open_count->cb(ctx->update_open_count, delta); +} + +ptls_t *ptls_new(ptls_context_t *ctx, int is_server) +{ + ptls_t *tls; + + assert(ctx->get_time != NULL && "please set ctx->get_time to `&ptls_get_time`; see #92"); + + if ((tls = malloc(sizeof(*tls))) == NULL) + return NULL; + + update_open_count(ctx, 1); + *tls = (ptls_t){ctx}; + tls->is_server = is_server; + tls->send_change_cipher_spec = ctx->send_change_cipher_spec; + if (!is_server) { + tls->state = PTLS_STATE_CLIENT_HANDSHAKE_START; + tls->ctx->random_bytes(tls->client_random, sizeof(tls->client_random)); + tls->ctx->random_bytes(tls->client.legacy_session_id, sizeof(tls->client.legacy_session_id)); + } else { + tls->state = PTLS_STATE_SERVER_EXPECT_CLIENT_HELLO; + } + + return tls; +} + +void ptls_free(ptls_t *tls) +{ + ptls_buffer_dispose(&tls->recvbuf.rec); + ptls_buffer_dispose(&tls->recvbuf.mess); + free_exporter_master_secret(tls, 1); + free_exporter_master_secret(tls, 0); + if (tls->key_schedule != NULL) + key_schedule_free(tls->key_schedule); + if (tls->traffic_protection.dec.aead != NULL) + ptls_aead_free(tls->traffic_protection.dec.aead); + if (tls->traffic_protection.enc.aead != NULL) + ptls_aead_free(tls->traffic_protection.enc.aead); + free(tls->server_name); + free(tls->negotiated_protocol); + if (tls->is_server) { + /* nothing to do */ + } else { + if (tls->client.key_share_ctx != NULL) + tls->client.key_share_ctx->on_exchange(&tls->client.key_share_ctx, NULL, ptls_iovec_init(NULL, 0)); + if (tls->client.certificate_verify.cb != NULL) + tls->client.certificate_verify.cb(tls->client.certificate_verify.verify_ctx, ptls_iovec_init(NULL, 0), + ptls_iovec_init(NULL, 0)); + } + if (tls->early_data != NULL) { + ptls_clear_memory(tls->early_data, sizeof(*tls->early_data)); + free(tls->early_data); + } + update_open_count(tls->ctx, -1); + ptls_clear_memory(tls, sizeof(*tls)); + free(tls); +} + +ptls_context_t *ptls_get_context(ptls_t *tls) +{ + return tls->ctx; +} + +void ptls_set_context(ptls_t *tls, ptls_context_t *ctx) +{ + update_open_count(ctx, 1); + update_open_count(tls->ctx, -1); + tls->ctx = ctx; +} + +ptls_iovec_t ptls_get_client_random(ptls_t *tls) +{ + return ptls_iovec_init(tls->client_random, PTLS_HELLO_RANDOM_SIZE); +} + +ptls_cipher_suite_t *ptls_get_cipher(ptls_t *tls) +{ + return tls->cipher_suite; +} + +const char *ptls_get_server_name(ptls_t *tls) +{ + return tls->server_name; +} + +int ptls_set_server_name(ptls_t *tls, const char *server_name, size_t server_name_len) +{ + char *duped = NULL; + + if (server_name != NULL) { + if (server_name_len == 0) + server_name_len = strlen(server_name); + if ((duped = malloc(server_name_len + 1)) == NULL) + return PTLS_ERROR_NO_MEMORY; + memcpy(duped, server_name, server_name_len); + duped[server_name_len] = '\0'; + } + + free(tls->server_name); + tls->server_name = duped; + + return 0; +} + +const char *ptls_get_negotiated_protocol(ptls_t *tls) +{ + return tls->negotiated_protocol; +} + +int ptls_set_negotiated_protocol(ptls_t *tls, const char *protocol, size_t protocol_len) +{ + char *duped = NULL; + + if (protocol != NULL) { + if (protocol_len == 0) + protocol_len = strlen(protocol); + if ((duped = malloc(protocol_len + 1)) == NULL) + return PTLS_ERROR_NO_MEMORY; + memcpy(duped, protocol, protocol_len); + duped[protocol_len] = '\0'; + } + + free(tls->negotiated_protocol); + tls->negotiated_protocol = duped; + + return 0; +} + +int ptls_handshake_is_complete(ptls_t *tls) +{ + return tls->state >= PTLS_STATE_POST_HANDSHAKE_MIN; +} + +int ptls_is_psk_handshake(ptls_t *tls) +{ + return tls->is_psk_handshake; +} + +void **ptls_get_data_ptr(ptls_t *tls) +{ + return &tls->data_ptr; +} + +static int handle_handshake_message(ptls_t *tls, ptls_buffer_t *sendbuf, ptls_iovec_t message, int is_end_of_record, + ptls_handshake_properties_t *properties) +{ + uint8_t type = message.base[0]; + int ret; + + switch (tls->state) { + case PTLS_STATE_CLIENT_EXPECT_SERVER_HELLO: + case PTLS_STATE_CLIENT_EXPECT_SECOND_SERVER_HELLO: + if (type == PTLS_HANDSHAKE_TYPE_SERVER_HELLO && is_end_of_record) { + ret = client_handle_hello(tls, sendbuf, message, properties); + } else { + ret = PTLS_ALERT_UNEXPECTED_MESSAGE; + } + break; + case PTLS_STATE_CLIENT_EXPECT_ENCRYPTED_EXTENSIONS: + if (type == PTLS_HANDSHAKE_TYPE_ENCRYPTED_EXTENSIONS) { + ret = client_handle_encrypted_extensions(tls, message, properties); + } else { + ret = PTLS_ALERT_UNEXPECTED_MESSAGE; + } + break; + case PTLS_STATE_CLIENT_EXPECT_CERTIFICATE: + if (type == PTLS_HANDSHAKE_TYPE_CERTIFICATE) { + ret = client_handle_certificate(tls, message); + } else { + ret = PTLS_ALERT_UNEXPECTED_MESSAGE; + } + break; + case PTLS_STATE_CLIENT_EXPECT_CERTIFICATE_VERIFY: + if (type == PTLS_HANDSHAKE_TYPE_CERTIFICATE_VERIFY) { + ret = client_handle_certificate_verify(tls, message); + } else { + ret = PTLS_ALERT_UNEXPECTED_MESSAGE; + } + break; + case PTLS_STATE_CLIENT_EXPECT_FINISHED: + if (type == PTLS_HANDSHAKE_TYPE_FINISHED && is_end_of_record) { + ret = client_handle_finished(tls, sendbuf, message); + } else { + ret = PTLS_ALERT_UNEXPECTED_MESSAGE; + } + break; + case PTLS_STATE_SERVER_EXPECT_CLIENT_HELLO: + case PTLS_STATE_SERVER_EXPECT_SECOND_CLIENT_HELLO: + if (type == PTLS_HANDSHAKE_TYPE_CLIENT_HELLO && is_end_of_record) { + ret = server_handle_hello(tls, sendbuf, message, properties); + } else { + ret = PTLS_ALERT_HANDSHAKE_FAILURE; + } + break; + case PTLS_STATE_SERVER_EXPECT_END_OF_EARLY_DATA: + if (type == PTLS_HANDSHAKE_TYPE_END_OF_EARLY_DATA) { + ret = server_handle_end_of_early_data(tls, message); + } else { + ret = PTLS_ALERT_UNEXPECTED_MESSAGE; + } + break; + case PTLS_STATE_SERVER_EXPECT_FINISHED: + if (type == PTLS_HANDSHAKE_TYPE_FINISHED && is_end_of_record) { + ret = server_handle_finished(tls, message); + } else { + ret = PTLS_ALERT_HANDSHAKE_FAILURE; + } + break; + case PTLS_STATE_CLIENT_POST_HANDSHAKE: + switch (type) { + case PTLS_HANDSHAKE_TYPE_NEW_SESSION_TICKET: + ret = client_handle_new_session_ticket(tls, message); + break; + default: + ret = PTLS_ALERT_UNEXPECTED_MESSAGE; + break; + } + break; + case PTLS_STATE_SERVER_POST_HANDSHAKE: + ret = PTLS_ALERT_UNEXPECTED_MESSAGE; + break; + default: + assert(!"unexpected state"); + break; + } + + return ret; +} + +static int handle_alert(ptls_t *tls, const uint8_t *src, size_t len) +{ + if (len != 2) + return PTLS_ALERT_DECODE_ERROR; + + uint8_t level = src[0], desc = src[1]; + + /* ignore certain warnings */ + if (level == PTLS_ALERT_LEVEL_WARNING) { + switch (desc) { + case PTLS_ALERT_USER_CANCELED: + return 0; + default: + break; + } + } + + /* all other alerts are considered fatal, regardless of the transmitted level (section 6) */ + return PTLS_ALERT_TO_PEER_ERROR(desc); +} + +static int handle_handshake_record(ptls_t *tls, int (*cb)(ptls_t *tls, ptls_buffer_t *sendbuf, ptls_iovec_t message, + int is_end_of_record, ptls_handshake_properties_t *properties), + ptls_buffer_t *sendbuf, struct st_ptls_record_t *rec, ptls_handshake_properties_t *properties) +{ + int ret; + + /* handshake */ + if (rec->type != PTLS_CONTENT_TYPE_HANDSHAKE) + return PTLS_ALERT_DECODE_ERROR; + + /* flatten the unhandled messages */ + const uint8_t *src, *src_end; + if (tls->recvbuf.mess.base == NULL) { + src = rec->fragment; + src_end = src + rec->length; + } else { + if ((ret = ptls_buffer_reserve(&tls->recvbuf.mess, rec->length)) != 0) + return ret; + memcpy(tls->recvbuf.mess.base + tls->recvbuf.mess.off, rec->fragment, rec->length); + tls->recvbuf.mess.off += rec->length; + src = tls->recvbuf.mess.base; + src_end = src + tls->recvbuf.mess.off; + } + + /* handle the messages */ + ret = PTLS_ERROR_IN_PROGRESS; + while (src_end - src >= 4) { + size_t mess_len = 4 + ntoh24(src + 1); + if (src_end - src < (int)mess_len) + break; + ret = cb(tls, sendbuf, ptls_iovec_init(src, mess_len), src_end - src == mess_len, properties); + switch (ret) { + case 0: + case PTLS_ERROR_IN_PROGRESS: + break; + default: + ptls_buffer_dispose(&tls->recvbuf.mess); + return ret; + } + src += mess_len; + } + + /* keep last partial message in buffer */ + if (src != src_end) { + if (tls->recvbuf.mess.base == NULL) { + ptls_buffer_init(&tls->recvbuf.mess, "", 0); + if ((ret = ptls_buffer_reserve(&tls->recvbuf.mess, src_end - src)) != 0) + return ret; + memcpy(tls->recvbuf.mess.base, src, src_end - src); + } else { + memmove(tls->recvbuf.mess.base, src, src_end - src); + } + tls->recvbuf.mess.off = src_end - src; + ret = PTLS_ERROR_IN_PROGRESS; + } else { + ptls_buffer_dispose(&tls->recvbuf.mess); + } + + return ret; +} + +static int handle_input(ptls_t *tls, ptls_buffer_t *sendbuf, ptls_buffer_t *decryptbuf, const void *input, size_t *inlen, + ptls_handshake_properties_t *properties) +{ + struct st_ptls_record_t rec; + int ret; + + /* extract the record */ + if ((ret = parse_record(tls, &rec, input, inlen)) != 0) + return ret; + assert(rec.fragment != NULL); + + /* decrypt the record */ + if (rec.type == PTLS_CONTENT_TYPE_CHANGE_CIPHER_SPEC) { + if (tls->state < PTLS_STATE_POST_HANDSHAKE_MIN) { + if (!(rec.length == 1 && rec.fragment[0] == 0x01)) + return PTLS_ALERT_ILLEGAL_PARAMETER; + } else { + return PTLS_ALERT_HANDSHAKE_FAILURE; + } + ret = PTLS_ERROR_IN_PROGRESS; + goto NextRecord; + } + if (tls->traffic_protection.dec.aead != NULL && rec.type != PTLS_CONTENT_TYPE_ALERT) { + if (rec.type != PTLS_CONTENT_TYPE_APPDATA) + return PTLS_ALERT_HANDSHAKE_FAILURE; + if ((ret = ptls_buffer_reserve(decryptbuf, 5 + rec.length)) != 0) + return ret; + if ((ret = aead_decrypt(&tls->traffic_protection.dec, decryptbuf->base + decryptbuf->off, &rec.length, rec.fragment, + rec.length)) != 0) { + if (tls->skip_early_data) { + ret = PTLS_ERROR_IN_PROGRESS; + goto NextRecord; + } + return ret; + } + rec.fragment = decryptbuf->base + decryptbuf->off; + /* skip padding */ + for (; rec.length != 0; --rec.length) + if (rec.fragment[rec.length - 1] != 0) + break; + if (rec.length == 0) + return PTLS_ALERT_UNEXPECTED_MESSAGE; + rec.type = rec.fragment[--rec.length]; + } else if (rec.type == PTLS_CONTENT_TYPE_APPDATA && tls->skip_early_data) { + ret = PTLS_ERROR_IN_PROGRESS; + goto NextRecord; + } + + if (tls->recvbuf.mess.base != NULL || rec.type == PTLS_CONTENT_TYPE_HANDSHAKE) { + /* handshake record */ + ret = handle_handshake_record(tls, handle_handshake_message, sendbuf, &rec, properties); + } else { + /* handling of an alert or an application record */ + switch (rec.type) { + case PTLS_CONTENT_TYPE_APPDATA: + if (tls->state >= PTLS_STATE_POST_HANDSHAKE_MIN) { + decryptbuf->off += rec.length; + ret = 0; + } else if (tls->state == PTLS_STATE_SERVER_EXPECT_END_OF_EARLY_DATA) { + if (tls->traffic_protection.dec.aead != NULL) + decryptbuf->off += rec.length; + ret = 0; + } else { + ret = PTLS_ALERT_UNEXPECTED_MESSAGE; + } + break; + case PTLS_CONTENT_TYPE_ALERT: + ret = handle_alert(tls, rec.fragment, rec.length); + break; + default: + ret = PTLS_ALERT_UNEXPECTED_MESSAGE; + break; + } + } + +NextRecord: + ptls_buffer_dispose(&tls->recvbuf.rec); + return ret; +} + +int ptls_handshake(ptls_t *tls, ptls_buffer_t *sendbuf, const void *input, size_t *inlen, ptls_handshake_properties_t *properties) +{ + size_t sendbuf_orig_off = sendbuf->off; + int ret; + + assert(tls->state < PTLS_STATE_POST_HANDSHAKE_MIN); + + /* special handlings */ + switch (tls->state) { + case PTLS_STATE_CLIENT_HANDSHAKE_START: + assert(input == NULL || *inlen == 0); + assert(tls->ctx->key_exchanges[0] != NULL); + return send_client_hello(tls, sendbuf, properties, NULL); + default: + break; + } + + const uint8_t *src = input, *const src_end = src + *inlen; + ptls_buffer_t decryptbuf; + uint8_t decryptbuf_small[256]; + + ptls_buffer_init(&decryptbuf, decryptbuf_small, sizeof(decryptbuf_small)); + + /* perform handhake until completion or until all the input has been swallowed */ + ret = PTLS_ERROR_IN_PROGRESS; + while (ret == PTLS_ERROR_IN_PROGRESS && src != src_end) { + size_t consumed = src_end - src; + ret = handle_input(tls, sendbuf, &decryptbuf, src, &consumed, properties); + src += consumed; + assert(decryptbuf.off == 0); + } + + ptls_buffer_dispose(&decryptbuf); + + switch (ret) { + case 0: + case PTLS_ERROR_IN_PROGRESS: + case PTLS_ERROR_STATELESS_RETRY: + break; + default: + /* flush partially written response */ + ptls_clear_memory(sendbuf->base + sendbuf_orig_off, sendbuf->off - sendbuf_orig_off); + sendbuf->off = sendbuf_orig_off; + /* send alert immediately */ + if (PTLS_ERROR_GET_CLASS(ret) != PTLS_ERROR_CLASS_PEER_ALERT) + if (ptls_send_alert(tls, sendbuf, PTLS_ALERT_LEVEL_FATAL, + PTLS_ERROR_GET_CLASS(ret) == PTLS_ERROR_CLASS_SELF_ALERT ? ret : PTLS_ALERT_INTERNAL_ERROR) != 0) + sendbuf->off = sendbuf_orig_off; + break; + } + + *inlen -= src_end - src; + return ret; +} + +int ptls_receive(ptls_t *tls, ptls_buffer_t *decryptbuf, const void *_input, size_t *inlen) +{ + const uint8_t *input = (const uint8_t *)_input, *const end = input + *inlen; + size_t decryptbuf_orig_size = decryptbuf->off; + int ret = 0; + + assert(tls->state >= PTLS_STATE_SERVER_EXPECT_END_OF_EARLY_DATA); + + /* loop until we decrypt some application data (or an error) */ + while (ret == 0 && input != end && decryptbuf_orig_size == decryptbuf->off) { + size_t consumed = end - input; + ret = handle_input(tls, NULL, decryptbuf, input, &consumed, NULL); + input += consumed; + + switch (ret) { + case 0: + break; + case PTLS_ERROR_IN_PROGRESS: + ret = 0; + break; + case PTLS_ERROR_CLASS_PEER_ALERT + PTLS_ALERT_CLOSE_NOTIFY: + /* TODO send close alert */ + break; + default: + if (PTLS_ERROR_GET_CLASS(ret) == PTLS_ERROR_CLASS_SELF_ALERT) { + /* TODO send alert */ + } + break; + } + } + + *inlen -= end - input; + + return ret; +} + +int ptls_send(ptls_t *tls, ptls_buffer_t *sendbuf, const void *input, size_t inlen) +{ + assert(tls->traffic_protection.enc.aead != NULL); + return buffer_push_encrypted_records(sendbuf, PTLS_CONTENT_TYPE_APPDATA, input, inlen, &tls->traffic_protection.enc); +} + +size_t ptls_get_record_overhead(ptls_t *tls) +{ + return 6 + tls->traffic_protection.enc.aead->algo->tag_size; +} + +int ptls_send_alert(ptls_t *tls, ptls_buffer_t *sendbuf, uint8_t level, uint8_t description) +{ + size_t rec_start = sendbuf->off; + int ret = 0; + + buffer_push_record(sendbuf, PTLS_CONTENT_TYPE_ALERT, { ptls_buffer_push(sendbuf, level, description); }); + /* encrypt the alert if we have the encryption keys, unless when it is the early data key */ + if (tls->traffic_protection.enc.aead != NULL && !(tls->state <= PTLS_STATE_CLIENT_EXPECT_FINISHED)) { + if ((ret = buffer_encrypt_record(sendbuf, rec_start, &tls->traffic_protection.enc)) != 0) + goto Exit; + } + +Exit: + return ret; +} + +int ptls_export_secret(ptls_t *tls, void *output, size_t outlen, const char *label, ptls_iovec_t context_value, int is_early) +{ + ptls_hash_algorithm_t *algo = tls->key_schedule->hashes[0].algo; + ptls_hash_context_t *hctx; + uint8_t *master_secret = is_early ? tls->exporter_master_secret.early : tls->exporter_master_secret.one_rtt, + derived_secret[PTLS_MAX_DIGEST_SIZE], context_value_hash[PTLS_MAX_DIGEST_SIZE]; + int ret; + + if (master_secret == NULL) + return PTLS_ERROR_IN_PROGRESS; + + if ((hctx = algo->create()) == NULL) + return PTLS_ERROR_NO_MEMORY; + hctx->update(hctx, context_value.base, context_value.len); + hctx->final(hctx, context_value_hash, PTLS_HASH_FINAL_MODE_FREE); + + if ((ret = ptls_hkdf_expand_label(algo, derived_secret, algo->digest_size, ptls_iovec_init(master_secret, algo->digest_size), + label, ptls_iovec_init(algo->empty_digest, algo->digest_size), NULL)) != 0) + goto Exit; + ret = ptls_hkdf_expand_label(algo, output, outlen, ptls_iovec_init(derived_secret, algo->digest_size), "exporter", + ptls_iovec_init(context_value_hash, algo->digest_size), NULL); + +Exit: + ptls_clear_memory(derived_secret, sizeof(derived_secret)); + ptls_clear_memory(context_value_hash, sizeof(context_value_hash)); + return ret; +} + +struct st_picotls_hmac_context_t { + ptls_hash_context_t super; + ptls_hash_algorithm_t *algo; + ptls_hash_context_t *hash; + uint8_t key[1]; +}; + +static void hmac_update(ptls_hash_context_t *_ctx, const void *src, size_t len) +{ + struct st_picotls_hmac_context_t *ctx = (struct st_picotls_hmac_context_t *)_ctx; + ctx->hash->update(ctx->hash, src, len); +} + +static void hmac_apply_key(struct st_picotls_hmac_context_t *ctx, uint8_t pad) +{ + size_t i; + + for (i = 0; i != ctx->algo->block_size; ++i) + ctx->key[i] ^= pad; + ctx->hash->update(ctx->hash, ctx->key, ctx->algo->block_size); + for (i = 0; i != ctx->algo->block_size; ++i) + ctx->key[i] ^= pad; +} + +static void hmac_final(ptls_hash_context_t *_ctx, void *md, ptls_hash_final_mode_t mode) +{ + struct st_picotls_hmac_context_t *ctx = (struct st_picotls_hmac_context_t *)_ctx; + + assert(mode != PTLS_HASH_FINAL_MODE_SNAPSHOT || !"not supported"); + + if (md != NULL) { + ctx->hash->final(ctx->hash, md, PTLS_HASH_FINAL_MODE_RESET); + hmac_apply_key(ctx, 0x5c); + ctx->hash->update(ctx->hash, md, ctx->algo->digest_size); + } + ctx->hash->final(ctx->hash, md, mode); + + switch (mode) { + case PTLS_HASH_FINAL_MODE_FREE: + ptls_clear_memory(ctx->key, ctx->algo->block_size); + free(ctx); + break; + case PTLS_HASH_FINAL_MODE_RESET: + hmac_apply_key(ctx, 0x36); + break; + default: + assert(!"FIXME"); + break; + } +} + +ptls_hash_context_t *ptls_hmac_create(ptls_hash_algorithm_t *algo, const void *key, size_t key_size) +{ + struct st_picotls_hmac_context_t *ctx; + + if ((ctx = malloc(offsetof(struct st_picotls_hmac_context_t, key) + algo->block_size)) == NULL) + return NULL; + + *ctx = (struct st_picotls_hmac_context_t){{hmac_update, hmac_final}, algo}; + if ((ctx->hash = algo->create()) == NULL) { + free(ctx); + return NULL; + } + memset(ctx->key, 0, algo->block_size); + memcpy(ctx->key, key, key_size); + + hmac_apply_key(ctx, 0x36); + + return &ctx->super; +} + +int ptls_hkdf_extract(ptls_hash_algorithm_t *algo, void *output, ptls_iovec_t salt, ptls_iovec_t ikm) +{ + ptls_hash_context_t *hash; + + if (salt.len == 0) + salt = ptls_iovec_init(zeroes_of_max_digest_size, algo->digest_size); + + if ((hash = ptls_hmac_create(algo, salt.base, salt.len)) == NULL) + return PTLS_ERROR_NO_MEMORY; + hash->update(hash, ikm.base, ikm.len); + hash->final(hash, output, PTLS_HASH_FINAL_MODE_FREE); + return 0; +} + +int ptls_hkdf_expand(ptls_hash_algorithm_t *algo, void *output, size_t outlen, ptls_iovec_t prk, ptls_iovec_t info) +{ + ptls_hash_context_t *hmac = NULL; + size_t i; + uint8_t digest[PTLS_MAX_DIGEST_SIZE]; + + for (i = 0; (i * algo->digest_size) < outlen; ++i) { + if (hmac == NULL) { + if ((hmac = ptls_hmac_create(algo, prk.base, prk.len)) == NULL) + return PTLS_ERROR_NO_MEMORY; + } else { + hmac->update(hmac, digest, algo->digest_size); + } + hmac->update(hmac, info.base, info.len); + uint8_t gen = (uint8_t)(i + 1); + hmac->update(hmac, &gen, 1); + hmac->final(hmac, digest, 1); + + size_t off_start = i * algo->digest_size, off_end = off_start + algo->digest_size; + if (off_end > outlen) + off_end = outlen; + memcpy((uint8_t *)output + off_start, digest, off_end - off_start); + } + + if (hmac != NULL) + hmac->final(hmac, NULL, PTLS_HASH_FINAL_MODE_FREE); + + ptls_clear_memory(digest, algo->digest_size); + + return 0; +} + +int ptls_hkdf_expand_label(ptls_hash_algorithm_t *algo, void *output, size_t outlen, ptls_iovec_t secret, const char *label, + ptls_iovec_t hash_value, const char *base_label) +{ + ptls_buffer_t hkdf_label; + uint8_t hkdf_label_buf[512]; + int ret; + + ptls_buffer_init(&hkdf_label, hkdf_label_buf, sizeof(hkdf_label_buf)); + + ptls_buffer_push16(&hkdf_label, (uint16_t)outlen); + ptls_buffer_push_block(&hkdf_label, 1, { + if (base_label == NULL) + base_label = "tls13 "; + ptls_buffer_pushv(&hkdf_label, base_label, strlen(base_label)); + ptls_buffer_pushv(&hkdf_label, label, strlen(label)); + }); + ptls_buffer_push_block(&hkdf_label, 1, { ptls_buffer_pushv(&hkdf_label, hash_value.base, hash_value.len); }); + + ret = ptls_hkdf_expand(algo, output, outlen, secret, ptls_iovec_init(hkdf_label.base, hkdf_label.off)); + +Exit: + ptls_buffer_dispose(&hkdf_label); + return ret; +} + +ptls_cipher_context_t *ptls_cipher_new(ptls_cipher_algorithm_t *algo, int is_enc, const void *key) +{ + ptls_cipher_context_t *ctx; + + if ((ctx = (ptls_cipher_context_t *)malloc(algo->context_size)) == NULL) + return NULL; + *ctx = (ptls_cipher_context_t){algo}; + if (algo->setup_crypto(ctx, is_enc, key) != 0) { + free(ctx); + ctx = NULL; + } + return ctx; +} + +void ptls_cipher_free(ptls_cipher_context_t *ctx) +{ + ctx->do_dispose(ctx); + free(ctx); +} + +ptls_aead_context_t *ptls_aead_new(ptls_aead_algorithm_t *aead, ptls_hash_algorithm_t *hash, int is_enc, const void *secret, + const char *base_label) +{ + ptls_aead_context_t *ctx; + uint8_t key[PTLS_MAX_SECRET_SIZE]; + int ret; + + if ((ctx = (ptls_aead_context_t *)malloc(aead->context_size)) == NULL) + return NULL; + + *ctx = (ptls_aead_context_t){aead}; + if ((ret = get_traffic_key(hash, key, aead->key_size, 0, secret, base_label)) != 0) + goto Exit; + if ((ret = get_traffic_key(hash, ctx->static_iv, aead->iv_size, 1, secret, base_label)) != 0) + goto Exit; + ret = aead->setup_crypto(ctx, is_enc, key); + +Exit: + ptls_clear_memory(key, aead->key_size); + if (ret != 0) { + ptls_clear_memory(ctx->static_iv, aead->iv_size); + free(ctx); + ctx = NULL; + } + + return ctx; +} + +void ptls_aead_free(ptls_aead_context_t *ctx) +{ + ctx->dispose_crypto(ctx); + ptls_clear_memory(ctx->static_iv, ctx->algo->iv_size); + free(ctx); +} + +size_t ptls_aead_encrypt(ptls_aead_context_t *ctx, void *output, const void *input, size_t inlen, uint64_t seq, const void *aad, + size_t aadlen) +{ + size_t off = 0; + + ptls_aead_encrypt_init(ctx, seq, aad, aadlen); + off += ptls_aead_encrypt_update(ctx, ((uint8_t *)output) + off, input, inlen); + off += ptls_aead_encrypt_final(ctx, ((uint8_t *)output) + off); + + return off; +} + +void ptls_aead__build_iv(ptls_aead_context_t *ctx, uint8_t *iv, uint64_t seq) +{ + size_t iv_size = ctx->algo->iv_size, i; + const uint8_t *s = ctx->static_iv; + uint8_t *d = iv; + + /* build iv */ + for (i = iv_size - 8; i != 0; --i) + *d++ = *s++; + i = 64; + do { + i -= 8; + *d++ = *s++ ^ (uint8_t)(seq >> i); + } while (i != 0); +} + +static void clear_memory(void *p, size_t len) +{ + if (len != 0) + memset(p, 0, len); +} + +void (*volatile ptls_clear_memory)(void *p, size_t len) = clear_memory; + +static uint64_t get_time(ptls_get_time_t *self) +{ + struct timeval tv; + gettimeofday(&tv, NULL); + return (uint64_t)tv.tv_sec * 1000 + tv.tv_usec / 1000; +} + +ptls_get_time_t ptls_get_time = {get_time}; + diff --git a/web/server/h2o/libh2o/deps/picotls/lib/uecc.c b/web/server/h2o/libh2o/deps/picotls/lib/uecc.c new file mode 100644 index 00000000..10f32520 --- /dev/null +++ b/web/server/h2o/libh2o/deps/picotls/lib/uecc.c @@ -0,0 +1,190 @@ +/* + * Copyright (c) 2016 DeNA Co., Ltd., Kazuho Oku + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ +#include +#include +#include +#include +#ifdef _WINDOWS +#include "wincompat.h" +#else +#include +#endif +#include "sha2.h" +#include "uECC.h" +#include "uECC_vli.h" +#include "picotls.h" +#include "picotls/minicrypto.h" + +#define TYPE_UNCOMPRESSED_PUBLIC_KEY 4 + +struct st_secp256r1_key_exhchange_t { + ptls_key_exchange_context_t super; + uint8_t priv[SECP256R1_PRIVATE_KEY_SIZE]; + uint8_t pub[SECP256R1_PUBLIC_KEY_SIZE]; +}; + +static int secp256r1_on_exchange(ptls_key_exchange_context_t **_ctx, ptls_iovec_t *secret, ptls_iovec_t peerkey) +{ + struct st_secp256r1_key_exhchange_t *ctx = (struct st_secp256r1_key_exhchange_t *)*_ctx; + uint8_t *secbytes = NULL; + int ret; + + *_ctx = NULL; + + if (secret == NULL) { + ret = 0; + goto Exit; + } + + if (peerkey.len != SECP256R1_PUBLIC_KEY_SIZE || peerkey.base[0] != TYPE_UNCOMPRESSED_PUBLIC_KEY) { + ret = PTLS_ALERT_DECRYPT_ERROR; + goto Exit; + } + if ((secbytes = (uint8_t *)malloc(SECP256R1_SHARED_SECRET_SIZE)) == NULL) { + ret = PTLS_ERROR_NO_MEMORY; + goto Exit; + } + if (!uECC_shared_secret(peerkey.base + 1, ctx->priv, secbytes, uECC_secp256r1())) { + ret = PTLS_ALERT_DECRYPT_ERROR; + goto Exit; + } + *secret = ptls_iovec_init(secbytes, SECP256R1_SHARED_SECRET_SIZE); + ret = 0; + +Exit: + if (ret != 0) + free(secbytes); + ptls_clear_memory(ctx->priv, sizeof(ctx->priv)); + free(ctx); + return ret; +} + +static int secp256r1_create_key_exchange(ptls_key_exchange_context_t **_ctx, ptls_iovec_t *pubkey) +{ + struct st_secp256r1_key_exhchange_t *ctx; + + if ((ctx = (struct st_secp256r1_key_exhchange_t *)malloc(sizeof(*ctx))) == NULL) + return PTLS_ERROR_NO_MEMORY; + ctx->super = (ptls_key_exchange_context_t){secp256r1_on_exchange}; + ctx->pub[0] = TYPE_UNCOMPRESSED_PUBLIC_KEY; + uECC_make_key(ctx->pub + 1, ctx->priv, uECC_secp256r1()); + + *_ctx = &ctx->super; + *pubkey = ptls_iovec_init(ctx->pub, sizeof(ctx->pub)); + return 0; +} + +static int secp256r1_key_exchange(ptls_iovec_t *pubkey, ptls_iovec_t *secret, ptls_iovec_t peerkey) +{ + uint8_t priv[SECP256R1_PRIVATE_KEY_SIZE], *pub = NULL, *secbytes = NULL; + int ret; + + if (peerkey.len != SECP256R1_PUBLIC_KEY_SIZE || peerkey.base[0] != TYPE_UNCOMPRESSED_PUBLIC_KEY) { + ret = PTLS_ALERT_DECRYPT_ERROR; + goto Exit; + } + if ((pub = malloc(SECP256R1_PUBLIC_KEY_SIZE)) == NULL) { + ret = PTLS_ERROR_NO_MEMORY; + goto Exit; + } + if ((secbytes = malloc(SECP256R1_SHARED_SECRET_SIZE)) == NULL) { + ret = PTLS_ERROR_NO_MEMORY; + goto Exit; + } + + pub[0] = TYPE_UNCOMPRESSED_PUBLIC_KEY; + uECC_make_key(pub + 1, priv, uECC_secp256r1()); + if (!uECC_shared_secret(peerkey.base + 1, priv, secbytes, uECC_secp256r1())) { + ret = PTLS_ALERT_DECRYPT_ERROR; + goto Exit; + } + *pubkey = ptls_iovec_init(pub, SECP256R1_PUBLIC_KEY_SIZE); + *secret = ptls_iovec_init(secbytes, SECP256R1_SHARED_SECRET_SIZE); + ret = 0; + +Exit: + ptls_clear_memory(priv, sizeof(priv)); + if (ret != 0) { + free(secbytes); + free(pub); + } + return ret; +} + +static int secp256r1sha256_sign(ptls_sign_certificate_t *_self, ptls_t *tls, uint16_t *selected_algorithm, ptls_buffer_t *outbuf, + ptls_iovec_t input, const uint16_t *algorithms, size_t num_algorithms) +{ + ptls_minicrypto_secp256r1sha256_sign_certificate_t *self = (ptls_minicrypto_secp256r1sha256_sign_certificate_t *)_self; + uint8_t hash[32], sig[64]; + size_t i; + int ret; + + /* check algorithm */ + for (i = 0; i != num_algorithms; ++i) + if (algorithms[i] == PTLS_SIGNATURE_ECDSA_SECP256R1_SHA256) + break; + if (i == num_algorithms) + return PTLS_ALERT_HANDSHAKE_FAILURE; + + { /* calc hash */ + cf_sha256_context ctx; + cf_sha256_init(&ctx); + cf_sha256_update(&ctx, input.base, input.len); + cf_sha256_digest_final(&ctx, hash); + ptls_clear_memory(&ctx, sizeof(ctx)); + } + + /* sign */ + uECC_sign(self->key, hash, sizeof(hash), sig, uECC_secp256r1()); + + /* encode using DER */ + ptls_buffer_push_asn1_sequence(outbuf, { + if ((ret = ptls_buffer_push_asn1_ubigint(outbuf, sig, 32)) != 0) + goto Exit; + if ((ret = ptls_buffer_push_asn1_ubigint(outbuf, sig + 32, 32)) != 0) + goto Exit; + }); + + *selected_algorithm = PTLS_SIGNATURE_ECDSA_SECP256R1_SHA256; + ret = 0; + +Exit: + ptls_clear_memory(hash, sizeof(hash)); + ptls_clear_memory(sig, sizeof(sig)); + return ret; +} + +int ptls_minicrypto_init_secp256r1sha256_sign_certificate(ptls_minicrypto_secp256r1sha256_sign_certificate_t *self, + ptls_iovec_t key) +{ + if (key.len != sizeof(self->key)) + return PTLS_ERROR_INCOMPATIBLE_KEY; + + self->super.cb = secp256r1sha256_sign; + memcpy(self->key, key.base, sizeof(self->key)); + + return 0; +} + +ptls_key_exchange_algorithm_t ptls_minicrypto_secp256r1 = {PTLS_GROUP_SECP256R1, secp256r1_create_key_exchange, + secp256r1_key_exchange}; +ptls_key_exchange_algorithm_t *ptls_minicrypto_key_exchanges[] = {&ptls_minicrypto_secp256r1, NULL}; diff --git a/web/server/h2o/libh2o/deps/picotls/misc/dump-github-repository.pl b/web/server/h2o/libh2o/deps/picotls/misc/dump-github-repository.pl new file mode 100755 index 00000000..ab811575 --- /dev/null +++ b/web/server/h2o/libh2o/deps/picotls/misc/dump-github-repository.pl @@ -0,0 +1,41 @@ +#! /usr/bin/perl + +use strict; +use warnings; +use Errno (); +use File::Basename qw(basename); + +die "Usage: $0 []\n" + if @ARGV < 3; + +my ($repo, $commit, $dest, $path) = @ARGV; +my $strip_components = 1; +my ($rm_path, $tar_path); + +if (defined $path) { + $path =~ s|/*$||; + $strip_components += scalar(split "/", $path) - 1; + $rm_path = "$dest/" . basename $path; + $tar_path = "*/$path"; +} else { + $path = ""; + $rm_path = "$dest"; + $tar_path = ""; +} + +run("rm -rf $rm_path"); + +mkdir("$dest") + or $! == Errno::EEXIST or die "failed to (re)create directory:$dest:$!"; +run("curl --silent --show-error --location $repo/archive/$commit.tar.gz | (cd $dest && tar x --strip-components $strip_components -zf - $tar_path)") == 0 + or die "failed to extract $repo/archive/$commit.tar.gz to $dest"; +run("git add -f `find $rm_path -type f`") == 0 + or die "failed to add files under $dest"; +run("git commit --allow-empty -m 'extract $repo @ $commit @{[defined $path ? qq{($path)} : '']} at $dest' $dest") == 0 + or die "failed to commit"; + +sub run { + my $cmd = shift; + print "$cmd\n"; + system($cmd); +} diff --git a/web/server/h2o/libh2o/deps/picotls/picotls.xcodeproj/project.pbxproj b/web/server/h2o/libh2o/deps/picotls/picotls.xcodeproj/project.pbxproj new file mode 100644 index 00000000..881b8f44 --- /dev/null +++ b/web/server/h2o/libh2o/deps/picotls/picotls.xcodeproj/project.pbxproj @@ -0,0 +1,1023 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + objects = { + +/* Begin PBXBuildFile section */ + 105900431DC8D57000FB4085 /* picotls.c in Sources */ = {isa = PBXBuildFile; fileRef = 106530E91D9B7C13005B2C60 /* picotls.c */; }; + 105900441DC8D57000FB4085 /* picotest.c in Sources */ = {isa = PBXBuildFile; fileRef = 106530E31D9B4021005B2C60 /* picotest.c */; }; + 1059004C1DC8D5B700FB4085 /* openssl.c in Sources */ = {isa = PBXBuildFile; fileRef = 106530C51D9B1A98005B2C60 /* openssl.c */; }; + 1059004E1DC8D61800FB4085 /* minicrypto.c in Sources */ = {isa = PBXBuildFile; fileRef = 1059003D1DC8D4E300FB4085 /* minicrypto.c */; }; + 105900501DC8D64E00FB4085 /* minicrypto.h in Headers */ = {isa = PBXBuildFile; fileRef = 1059004F1DC8D64E00FB4085 /* minicrypto.h */; }; + 105900611DC8DF8C00FB4085 /* sha256.c in Sources */ = {isa = PBXBuildFile; fileRef = 1059005F1DC8DE4400FB4085 /* sha256.c */; }; + 105900641DC8DFA700FB4085 /* curve25519.c in Sources */ = {isa = PBXBuildFile; fileRef = 105900391DC8D46A00FB4085 /* curve25519.c */; }; + 105900691DC8DFDF00FB4085 /* blockwise.c in Sources */ = {isa = PBXBuildFile; fileRef = 105900291DC8D39800FB4085 /* blockwise.c */; }; + 1059006A1DC8DFE300FB4085 /* hmac.c in Sources */ = {isa = PBXBuildFile; fileRef = 105900651DC8DFD300FB4085 /* hmac.c */; }; + 1059006F1DC8E00B00FB4085 /* chash.c in Sources */ = {isa = PBXBuildFile; fileRef = 1059006B1DC8E00400FB4085 /* chash.c */; }; + 105900761DC8E1A300FB4085 /* openssl.c in Sources */ = {isa = PBXBuildFile; fileRef = 106530C21D9B004B005B2C60 /* openssl.c */; }; + 1059008F1DC8E1FF00FB4085 /* aes.h in Headers */ = {isa = PBXBuildFile; fileRef = 105900251DC8D37500FB4085 /* aes.h */; }; + 105900911DC8E1FF00FB4085 /* bitops.h in Headers */ = {isa = PBXBuildFile; fileRef = 105900281DC8D39800FB4085 /* bitops.h */; }; + 105900921DC8E1FF00FB4085 /* blockwise.h in Headers */ = {isa = PBXBuildFile; fileRef = 1059002A1DC8D39800FB4085 /* blockwise.h */; }; + 105900941DC8E1FF00FB4085 /* chash.h in Headers */ = {isa = PBXBuildFile; fileRef = 1059006C1DC8E00400FB4085 /* chash.h */; }; + 105900961DC8E1FF00FB4085 /* curve25519.h in Headers */ = {isa = PBXBuildFile; fileRef = 105900361DC8D44E00FB4085 /* curve25519.h */; }; + 105900991DC8E1FF00FB4085 /* cf_config.h in Headers */ = {isa = PBXBuildFile; fileRef = 105900321DC8D41A00FB4085 /* cf_config.h */; }; + 1059009A1DC8E1FF00FB4085 /* drbg.h in Headers */ = {isa = PBXBuildFile; fileRef = 105900521DC8D79300FB4085 /* drbg.h */; }; + 1059009C1DC8E1FF00FB4085 /* handy.h in Headers */ = {isa = PBXBuildFile; fileRef = 1059002B1DC8D39800FB4085 /* handy.h */; }; + 1059009D1DC8E1FF00FB4085 /* hmac.h in Headers */ = {isa = PBXBuildFile; fileRef = 105900661DC8DFD300FB4085 /* hmac.h */; }; + 1059009F1DC8E1FF00FB4085 /* sha2.h in Headers */ = {isa = PBXBuildFile; fileRef = 1059005D1DC8DE3800FB4085 /* sha2.h */; }; + 105900A11DC8E1FF00FB4085 /* tassert.h in Headers */ = {isa = PBXBuildFile; fileRef = 105900301DC8D3DF00FB4085 /* tassert.h */; }; + 105900A21DC8E20D00FB4085 /* openssl.h in Headers */ = {isa = PBXBuildFile; fileRef = 106530ED1D9CEFF7005B2C60 /* openssl.h */; }; + 105900A41DC8E23B00FB4085 /* libpicotls-openssl.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 1059008C1DC8E1A300FB4085 /* libpicotls-openssl.a */; }; + 105900AE1DC941D700FB4085 /* gf128.h in Headers */ = {isa = PBXBuildFile; fileRef = 105900AB1DC941D700FB4085 /* gf128.h */; }; + 105900B21DC9438200FB4085 /* modes.h in Headers */ = {isa = PBXBuildFile; fileRef = 105900B01DC9438200FB4085 /* modes.h */; }; + 105900B31DC9439800FB4085 /* modes.c in Sources */ = {isa = PBXBuildFile; fileRef = 105900AF1DC9438200FB4085 /* modes.c */; }; + 105900B41DC943B500FB4085 /* gf128.c in Sources */ = {isa = PBXBuildFile; fileRef = 105900AA1DC941D700FB4085 /* gf128.c */; }; + 105900B51DC943B900FB4085 /* gcm.c in Sources */ = {isa = PBXBuildFile; fileRef = 105900A91DC941D700FB4085 /* gcm.c */; }; + 105900B61DC943D400FB4085 /* aes.c in Sources */ = {isa = PBXBuildFile; fileRef = 105900241DC8D37500FB4085 /* aes.c */; }; + 105900BE1DC96A3500FB4085 /* types.h in Headers */ = {isa = PBXBuildFile; fileRef = 105900BA1DC96A3500FB4085 /* types.h */; }; + 105900BF1DC96A3500FB4085 /* uECC_vli.h in Headers */ = {isa = PBXBuildFile; fileRef = 105900BB1DC96A3500FB4085 /* uECC_vli.h */; }; + 105900C11DC96A3500FB4085 /* uECC.h in Headers */ = {isa = PBXBuildFile; fileRef = 105900BD1DC96A3500FB4085 /* uECC.h */; }; + 105900C41DC96B2200FB4085 /* uECC.c in Sources */ = {isa = PBXBuildFile; fileRef = 105900BC1DC96A3500FB4085 /* uECC.c */; }; + 105900C71DCBECD800FB4085 /* aes.c in Sources */ = {isa = PBXBuildFile; fileRef = 105900241DC8D37500FB4085 /* aes.c */; }; + 105900C81DCBECDD00FB4085 /* blockwise.c in Sources */ = {isa = PBXBuildFile; fileRef = 105900291DC8D39800FB4085 /* blockwise.c */; }; + 105900C91DCBECE100FB4085 /* chash.c in Sources */ = {isa = PBXBuildFile; fileRef = 1059006B1DC8E00400FB4085 /* chash.c */; }; + 105900CA1DCBECE500FB4085 /* curve25519.c in Sources */ = {isa = PBXBuildFile; fileRef = 105900391DC8D46A00FB4085 /* curve25519.c */; }; + 105900CB1DCBECEA00FB4085 /* drbg.c in Sources */ = {isa = PBXBuildFile; fileRef = 105900511DC8D79300FB4085 /* drbg.c */; }; + 105900CC1DCBECF100FB4085 /* hmac.c in Sources */ = {isa = PBXBuildFile; fileRef = 105900651DC8DFD300FB4085 /* hmac.c */; }; + 105900CD1DCBECF400FB4085 /* gcm.c in Sources */ = {isa = PBXBuildFile; fileRef = 105900A91DC941D700FB4085 /* gcm.c */; }; + 105900CE1DCBECF700FB4085 /* gf128.c in Sources */ = {isa = PBXBuildFile; fileRef = 105900AA1DC941D700FB4085 /* gf128.c */; }; + 105900CF1DCBECFB00FB4085 /* modes.c in Sources */ = {isa = PBXBuildFile; fileRef = 105900AF1DC9438200FB4085 /* modes.c */; }; + 105900D01DCBECFE00FB4085 /* sha256.c in Sources */ = {isa = PBXBuildFile; fileRef = 1059005F1DC8DE4400FB4085 /* sha256.c */; }; + 105900D11DCBED0600FB4085 /* cifra.c in Sources */ = {isa = PBXBuildFile; fileRef = 1059003F1DC8D53200FB4085 /* cifra.c */; }; + 105900D21DCBED0A00FB4085 /* uecc.c in Sources */ = {isa = PBXBuildFile; fileRef = 105900C51DC9798800FB4085 /* uecc.c */; }; + 105900D31DCBED1D00FB4085 /* uECC.c in Sources */ = {isa = PBXBuildFile; fileRef = 105900BC1DC96A3500FB4085 /* uECC.c */; }; + 106530E51D9B4021005B2C60 /* picotest.c in Sources */ = {isa = PBXBuildFile; fileRef = 106530E31D9B4021005B2C60 /* picotest.c */; }; + 106530EA1D9B7C13005B2C60 /* picotls.c in Sources */ = {isa = PBXBuildFile; fileRef = 106530E91D9B7C13005B2C60 /* picotls.c */; }; + 106530EB1D9B7C5C005B2C60 /* picotls.c in Sources */ = {isa = PBXBuildFile; fileRef = 106530BF1D998641005B2C60 /* picotls.c */; }; + 106530FF1DAD8A3C005B2C60 /* cli.c in Sources */ = {isa = PBXBuildFile; fileRef = 106530FE1DAD8A3C005B2C60 /* cli.c */; }; + 10EACAF01DCC843A00CA0341 /* drbg.c in Sources */ = {isa = PBXBuildFile; fileRef = 105900511DC8D79300FB4085 /* drbg.c */; }; + 10EACAF31DCEAF0F00CA0341 /* uECC.c in Sources */ = {isa = PBXBuildFile; fileRef = 105900BC1DC96A3500FB4085 /* uECC.c */; }; + 10EACAF41DCEAF0F00CA0341 /* uecc.c in Sources */ = {isa = PBXBuildFile; fileRef = 105900C51DC9798800FB4085 /* uecc.c */; }; + 10EACAF51DCEAF0F00CA0341 /* gf128.c in Sources */ = {isa = PBXBuildFile; fileRef = 105900AA1DC941D700FB4085 /* gf128.c */; }; + 10EACAF61DCEAF0F00CA0341 /* gcm.c in Sources */ = {isa = PBXBuildFile; fileRef = 105900A91DC941D700FB4085 /* gcm.c */; }; + 10EACAF71DCEAF0F00CA0341 /* sha256.c in Sources */ = {isa = PBXBuildFile; fileRef = 1059005F1DC8DE4400FB4085 /* sha256.c */; }; + 10EACAF81DCEAF0F00CA0341 /* aes.c in Sources */ = {isa = PBXBuildFile; fileRef = 105900241DC8D37500FB4085 /* aes.c */; }; + 10EACAF91DCEAF0F00CA0341 /* modes.c in Sources */ = {isa = PBXBuildFile; fileRef = 105900AF1DC9438200FB4085 /* modes.c */; }; + 10EACAFB1DCEAF0F00CA0341 /* chash.c in Sources */ = {isa = PBXBuildFile; fileRef = 1059006B1DC8E00400FB4085 /* chash.c */; }; + 10EACAFC1DCEAF0F00CA0341 /* curve25519.c in Sources */ = {isa = PBXBuildFile; fileRef = 105900391DC8D46A00FB4085 /* curve25519.c */; }; + 10EACAFD1DCEAF0F00CA0341 /* hmac.c in Sources */ = {isa = PBXBuildFile; fileRef = 105900651DC8DFD300FB4085 /* hmac.c */; }; + 10EACAFE1DCEAF0F00CA0341 /* drbg.c in Sources */ = {isa = PBXBuildFile; fileRef = 105900511DC8D79300FB4085 /* drbg.c */; }; + 10EACAFF1DCEAF0F00CA0341 /* cifra.c in Sources */ = {isa = PBXBuildFile; fileRef = 1059003F1DC8D53200FB4085 /* cifra.c */; }; + 10EACB001DCEAF0F00CA0341 /* blockwise.c in Sources */ = {isa = PBXBuildFile; fileRef = 105900291DC8D39800FB4085 /* blockwise.c */; }; + 10EACB031DCEAF0F00CA0341 /* blockwise.h in Headers */ = {isa = PBXBuildFile; fileRef = 1059002A1DC8D39800FB4085 /* blockwise.h */; }; + 10EACB041DCEAF0F00CA0341 /* types.h in Headers */ = {isa = PBXBuildFile; fileRef = 105900BA1DC96A3500FB4085 /* types.h */; }; + 10EACB051DCEAF0F00CA0341 /* uECC_vli.h in Headers */ = {isa = PBXBuildFile; fileRef = 105900BB1DC96A3500FB4085 /* uECC_vli.h */; }; + 10EACB061DCEAF0F00CA0341 /* modes.h in Headers */ = {isa = PBXBuildFile; fileRef = 105900B01DC9438200FB4085 /* modes.h */; }; + 10EACB071DCEAF0F00CA0341 /* bitops.h in Headers */ = {isa = PBXBuildFile; fileRef = 105900281DC8D39800FB4085 /* bitops.h */; }; + 10EACB081DCEAF0F00CA0341 /* cf_config.h in Headers */ = {isa = PBXBuildFile; fileRef = 105900321DC8D41A00FB4085 /* cf_config.h */; }; + 10EACB091DCEAF0F00CA0341 /* handy.h in Headers */ = {isa = PBXBuildFile; fileRef = 1059002B1DC8D39800FB4085 /* handy.h */; }; + 10EACB0A1DCEAF0F00CA0341 /* uECC.h in Headers */ = {isa = PBXBuildFile; fileRef = 105900BD1DC96A3500FB4085 /* uECC.h */; }; + 10EACB0B1DCEAF0F00CA0341 /* drbg.h in Headers */ = {isa = PBXBuildFile; fileRef = 105900521DC8D79300FB4085 /* drbg.h */; }; + 10EACB0C1DCEAF0F00CA0341 /* tassert.h in Headers */ = {isa = PBXBuildFile; fileRef = 105900301DC8D3DF00FB4085 /* tassert.h */; }; + 10EACB0D1DCEAF0F00CA0341 /* hmac.h in Headers */ = {isa = PBXBuildFile; fileRef = 105900661DC8DFD300FB4085 /* hmac.h */; }; + 10EACB0E1DCEAF0F00CA0341 /* chash.h in Headers */ = {isa = PBXBuildFile; fileRef = 1059006C1DC8E00400FB4085 /* chash.h */; }; + 10EACB0F1DCEAF0F00CA0341 /* sha2.h in Headers */ = {isa = PBXBuildFile; fileRef = 1059005D1DC8DE3800FB4085 /* sha2.h */; }; + 10EACB101DCEAF0F00CA0341 /* aes.h in Headers */ = {isa = PBXBuildFile; fileRef = 105900251DC8D37500FB4085 /* aes.h */; }; + 10EACB111DCEAF0F00CA0341 /* minicrypto.h in Headers */ = {isa = PBXBuildFile; fileRef = 1059004F1DC8D64E00FB4085 /* minicrypto.h */; }; + 10EACB121DCEAF0F00CA0341 /* gf128.h in Headers */ = {isa = PBXBuildFile; fileRef = 105900AB1DC941D700FB4085 /* gf128.h */; }; + 10EACB131DCEAF0F00CA0341 /* curve25519.h in Headers */ = {isa = PBXBuildFile; fileRef = 105900361DC8D44E00FB4085 /* curve25519.h */; }; + 10EACB1A1DCEC2A300CA0341 /* libpicotls-core.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 106530DA1D9B3E6F005B2C60 /* libpicotls-core.a */; }; + E949EF282073629300511ECA /* minicrypto-pem.c in Sources */ = {isa = PBXBuildFile; fileRef = E949EF272073629300511ECA /* minicrypto-pem.c */; }; + E99B75E01F5CDDB500CF503E /* asn1.c in Sources */ = {isa = PBXBuildFile; fileRef = E99B75DE1F5CDDB500CF503E /* asn1.c */; }; + E99B75E11F5CDDB500CF503E /* pembase64.c in Sources */ = {isa = PBXBuildFile; fileRef = E99B75DF1F5CDDB500CF503E /* pembase64.c */; }; + E99B75E21F5CE54D00CF503E /* asn1.c in Sources */ = {isa = PBXBuildFile; fileRef = E99B75DE1F5CDDB500CF503E /* asn1.c */; }; + E99B75E31F5CE54D00CF503E /* asn1.c in Sources */ = {isa = PBXBuildFile; fileRef = E99B75DE1F5CDDB500CF503E /* asn1.c */; }; + E99B75E41F5CE64E00CF503E /* pembase64.c in Sources */ = {isa = PBXBuildFile; fileRef = E99B75DF1F5CDDB500CF503E /* pembase64.c */; }; + E99B75E51F5CE64E00CF503E /* pembase64.c in Sources */ = {isa = PBXBuildFile; fileRef = E99B75DF1F5CDDB500CF503E /* pembase64.c */; }; + E9BC76CF1EF3A35E00EB7A09 /* chacha20.c in Sources */ = {isa = PBXBuildFile; fileRef = E9BC76C61EF3A2F700EB7A09 /* chacha20.c */; }; + E9BC76D21EF3A36A00EB7A09 /* chacha20.c in Sources */ = {isa = PBXBuildFile; fileRef = E9BC76C61EF3A2F700EB7A09 /* chacha20.c */; }; + E9BC76D41EF3A37200EB7A09 /* chacha20.c in Sources */ = {isa = PBXBuildFile; fileRef = E9BC76C61EF3A2F700EB7A09 /* chacha20.c */; }; + E9BC76DD1EF3CCD100EB7A09 /* poly1305.c in Sources */ = {isa = PBXBuildFile; fileRef = E9BC76D61EF3C1C200EB7A09 /* poly1305.c */; }; + E9BC76DE1EF3CCD100EB7A09 /* poly1305.h in Headers */ = {isa = PBXBuildFile; fileRef = E9BC76D71EF3C1C200EB7A09 /* poly1305.h */; }; + E9BC76DF1EF3CCD100EB7A09 /* salsa20.h in Headers */ = {isa = PBXBuildFile; fileRef = E9BC76CC1EF3A31000EB7A09 /* salsa20.h */; }; + E9BC76E01EF3CCDD00EB7A09 /* poly1305.c in Sources */ = {isa = PBXBuildFile; fileRef = E9BC76D61EF3C1C200EB7A09 /* poly1305.c */; }; + E9BC76E11EF3CCDE00EB7A09 /* poly1305.c in Sources */ = {isa = PBXBuildFile; fileRef = E9BC76D61EF3C1C200EB7A09 /* poly1305.c */; }; + E9E865EB203BD46600E2FFCD /* sha512.c in Sources */ = {isa = PBXBuildFile; fileRef = E9E865E9203BD45600E2FFCD /* sha512.c */; }; + E9E865EC203BD46600E2FFCD /* sha512.c in Sources */ = {isa = PBXBuildFile; fileRef = E9E865E9203BD45600E2FFCD /* sha512.c */; }; + E9E865ED203BD46700E2FFCD /* sha512.c in Sources */ = {isa = PBXBuildFile; fileRef = E9E865E9203BD45600E2FFCD /* sha512.c */; }; +/* End PBXBuildFile section */ + +/* Begin PBXContainerItemProxy section */ + 105900A71DC8E2E100FB4085 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 106530AA1D9985E0005B2C60 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 105900701DC8E1A300FB4085; + remoteInfo = "picotls-openssl"; + }; + 10EACB181DCEAF4A00CA0341 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 106530AA1D9985E0005B2C60 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 106530D91D9B3E6F005B2C60; + remoteInfo = "picotls-core"; + }; +/* End PBXContainerItemProxy section */ + +/* Begin PBXCopyFilesBuildPhase section */ + 105900471DC8D57000FB4085 /* CopyFiles */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = /usr/share/man/man1/; + dstSubfolderSpec = 0; + files = ( + ); + runOnlyForDeploymentPostprocessing = 1; + }; + 106530CA1D9B3D45005B2C60 /* CopyFiles */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = /usr/share/man/man1/; + dstSubfolderSpec = 0; + files = ( + ); + runOnlyForDeploymentPostprocessing = 1; + }; + 106530F81DAD8985005B2C60 /* CopyFiles */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = /usr/share/man/man1/; + dstSubfolderSpec = 0; + files = ( + ); + runOnlyForDeploymentPostprocessing = 1; + }; +/* End PBXCopyFilesBuildPhase section */ + +/* Begin PBXFileReference section */ + 105900241DC8D37500FB4085 /* aes.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = aes.c; path = src/aes.c; sourceTree = ""; }; + 105900251DC8D37500FB4085 /* aes.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = aes.h; path = src/aes.h; sourceTree = ""; }; + 105900281DC8D39800FB4085 /* bitops.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = bitops.h; path = src/bitops.h; sourceTree = ""; }; + 105900291DC8D39800FB4085 /* blockwise.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = blockwise.c; path = src/blockwise.c; sourceTree = ""; }; + 1059002A1DC8D39800FB4085 /* blockwise.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = blockwise.h; path = src/blockwise.h; sourceTree = ""; }; + 1059002B1DC8D39800FB4085 /* handy.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = handy.h; path = src/ext/handy.h; sourceTree = ""; }; + 105900301DC8D3DF00FB4085 /* tassert.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = tassert.h; path = src/tassert.h; sourceTree = ""; }; + 105900321DC8D41A00FB4085 /* cf_config.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = cf_config.h; path = src/cf_config.h; sourceTree = ""; }; + 105900361DC8D44E00FB4085 /* curve25519.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = curve25519.h; path = src/curve25519.h; sourceTree = ""; }; + 105900391DC8D46A00FB4085 /* curve25519.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = curve25519.c; path = src/curve25519.c; sourceTree = ""; }; + 1059003B1DC8D49E00FB4085 /* curve25519.tweetnacl.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = curve25519.tweetnacl.c; path = src/curve25519.tweetnacl.c; sourceTree = ""; }; + 1059003D1DC8D4E300FB4085 /* minicrypto.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = minicrypto.c; sourceTree = ""; }; + 1059003F1DC8D53200FB4085 /* cifra.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = cifra.c; sourceTree = ""; }; + 1059004B1DC8D57000FB4085 /* test-minicrypto */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = "test-minicrypto"; sourceTree = BUILT_PRODUCTS_DIR; }; + 1059004F1DC8D64E00FB4085 /* minicrypto.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = minicrypto.h; sourceTree = ""; }; + 105900511DC8D79300FB4085 /* drbg.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = drbg.c; path = src/drbg.c; sourceTree = ""; }; + 105900521DC8D79300FB4085 /* drbg.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = drbg.h; path = src/drbg.h; sourceTree = ""; }; + 1059005D1DC8DE3800FB4085 /* sha2.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = sha2.h; path = src/sha2.h; sourceTree = ""; }; + 1059005F1DC8DE4400FB4085 /* sha256.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = sha256.c; path = src/sha256.c; sourceTree = ""; }; + 105900651DC8DFD300FB4085 /* hmac.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = hmac.c; path = src/hmac.c; sourceTree = ""; }; + 105900661DC8DFD300FB4085 /* hmac.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = hmac.h; path = src/hmac.h; sourceTree = ""; }; + 1059006B1DC8E00400FB4085 /* chash.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = chash.c; path = src/chash.c; sourceTree = ""; }; + 1059006C1DC8E00400FB4085 /* chash.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = chash.h; path = src/chash.h; sourceTree = ""; }; + 1059008C1DC8E1A300FB4085 /* libpicotls-openssl.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libpicotls-openssl.a"; sourceTree = BUILT_PRODUCTS_DIR; }; + 105900A91DC941D700FB4085 /* gcm.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = gcm.c; path = src/gcm.c; sourceTree = ""; }; + 105900AA1DC941D700FB4085 /* gf128.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = gf128.c; path = src/gf128.c; sourceTree = ""; }; + 105900AB1DC941D700FB4085 /* gf128.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = gf128.h; path = src/gf128.h; sourceTree = ""; }; + 105900AF1DC9438200FB4085 /* modes.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = modes.c; path = src/modes.c; sourceTree = ""; }; + 105900B01DC9438200FB4085 /* modes.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = modes.h; path = src/modes.h; sourceTree = ""; }; + 105900BA1DC96A3500FB4085 /* types.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = types.h; sourceTree = ""; }; + 105900BB1DC96A3500FB4085 /* uECC_vli.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = uECC_vli.h; sourceTree = ""; }; + 105900BC1DC96A3500FB4085 /* uECC.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = uECC.c; sourceTree = ""; }; + 105900BD1DC96A3500FB4085 /* uECC.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = uECC.h; sourceTree = ""; }; + 105900C51DC9798800FB4085 /* uecc.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = uecc.c; sourceTree = ""; }; + 106530BE1D99863B005B2C60 /* picotls.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = picotls.h; sourceTree = ""; }; + 106530BF1D998641005B2C60 /* picotls.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = picotls.c; sourceTree = ""; }; + 106530C21D9B004B005B2C60 /* openssl.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = openssl.c; sourceTree = ""; }; + 106530C51D9B1A98005B2C60 /* openssl.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = openssl.c; sourceTree = ""; }; + 106530CC1D9B3D45005B2C60 /* test-openssl */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = "test-openssl"; sourceTree = BUILT_PRODUCTS_DIR; }; + 106530DA1D9B3E6F005B2C60 /* libpicotls-core.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libpicotls-core.a"; sourceTree = BUILT_PRODUCTS_DIR; }; + 106530E31D9B4021005B2C60 /* picotest.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = picotest.c; sourceTree = ""; }; + 106530E41D9B4021005B2C60 /* picotest.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = picotest.h; sourceTree = ""; }; + 106530E61D9B7AF6005B2C60 /* test.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = test.h; sourceTree = ""; }; + 106530E91D9B7C13005B2C60 /* picotls.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = picotls.c; sourceTree = ""; }; + 106530ED1D9CEFF7005B2C60 /* openssl.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = openssl.h; path = include/picotls/openssl.h; sourceTree = SOURCE_ROOT; }; + 106530FC1DAD8985005B2C60 /* cli */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = cli; sourceTree = BUILT_PRODUCTS_DIR; }; + 106530FE1DAD8A3C005B2C60 /* cli.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = cli.c; sourceTree = ""; }; + 10EACB171DCEAF0F00CA0341 /* libpicotls-minicrypto.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libpicotls-minicrypto.a"; sourceTree = BUILT_PRODUCTS_DIR; }; + E949EF272073629300511ECA /* minicrypto-pem.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = "minicrypto-pem.c"; sourceTree = ""; }; + E99B75DE1F5CDDB500CF503E /* asn1.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = asn1.c; sourceTree = ""; }; + E99B75DF1F5CDDB500CF503E /* pembase64.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = pembase64.c; sourceTree = ""; }; + E9BC76C61EF3A2F700EB7A09 /* chacha20.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = chacha20.c; path = src/chacha20.c; sourceTree = ""; }; + E9BC76CC1EF3A31000EB7A09 /* salsa20.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = salsa20.h; path = src/salsa20.h; sourceTree = ""; }; + E9BC76D61EF3C1C200EB7A09 /* poly1305.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = poly1305.c; path = src/poly1305.c; sourceTree = ""; }; + E9BC76D71EF3C1C200EB7A09 /* poly1305.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = poly1305.h; path = src/poly1305.h; sourceTree = ""; }; + E9E3849C1F0748DD00D50990 /* util.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = util.h; sourceTree = ""; }; + E9E865E9203BD45600E2FFCD /* sha512.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = sha512.c; path = src/sha512.c; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 105900461DC8D57000FB4085 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 1059007B1DC8E1A300FB4085 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 106530C91D9B3D45005B2C60 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 106530D71D9B3E6F005B2C60 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 106530F71DAD8985005B2C60 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 105900A41DC8E23B00FB4085 /* libpicotls-openssl.a in Frameworks */, + 10EACB1A1DCEC2A300CA0341 /* libpicotls-core.a in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 10EACB011DCEAF0F00CA0341 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 105900231DC8D34400FB4085 /* cifra */ = { + isa = PBXGroup; + children = ( + 105900251DC8D37500FB4085 /* aes.h */, + 105900241DC8D37500FB4085 /* aes.c */, + 105900281DC8D39800FB4085 /* bitops.h */, + 1059002A1DC8D39800FB4085 /* blockwise.h */, + 105900291DC8D39800FB4085 /* blockwise.c */, + E9BC76C61EF3A2F700EB7A09 /* chacha20.c */, + 1059006C1DC8E00400FB4085 /* chash.h */, + 1059006B1DC8E00400FB4085 /* chash.c */, + 105900361DC8D44E00FB4085 /* curve25519.h */, + 105900391DC8D46A00FB4085 /* curve25519.c */, + 1059003B1DC8D49E00FB4085 /* curve25519.tweetnacl.c */, + 105900321DC8D41A00FB4085 /* cf_config.h */, + 105900521DC8D79300FB4085 /* drbg.h */, + 105900511DC8D79300FB4085 /* drbg.c */, + 1059002B1DC8D39800FB4085 /* handy.h */, + 105900661DC8DFD300FB4085 /* hmac.h */, + 105900651DC8DFD300FB4085 /* hmac.c */, + 105900A91DC941D700FB4085 /* gcm.c */, + 105900AB1DC941D700FB4085 /* gf128.h */, + 105900AA1DC941D700FB4085 /* gf128.c */, + 105900B01DC9438200FB4085 /* modes.h */, + 105900AF1DC9438200FB4085 /* modes.c */, + E9BC76D71EF3C1C200EB7A09 /* poly1305.h */, + E9BC76D61EF3C1C200EB7A09 /* poly1305.c */, + E9BC76CC1EF3A31000EB7A09 /* salsa20.h */, + 1059005D1DC8DE3800FB4085 /* sha2.h */, + 1059005F1DC8DE4400FB4085 /* sha256.c */, + E9E865E9203BD45600E2FFCD /* sha512.c */, + 105900301DC8D3DF00FB4085 /* tassert.h */, + ); + path = cifra; + sourceTree = ""; + }; + 105900B91DC96A1B00FB4085 /* micro-ecc */ = { + isa = PBXGroup; + children = ( + 105900BA1DC96A3500FB4085 /* types.h */, + 105900BD1DC96A3500FB4085 /* uECC.h */, + 105900BB1DC96A3500FB4085 /* uECC_vli.h */, + 105900BC1DC96A3500FB4085 /* uECC.c */, + ); + path = "micro-ecc"; + sourceTree = ""; + }; + 106530A91D9985E0005B2C60 = { + isa = PBXGroup; + children = ( + 106530E11D9B4000005B2C60 /* deps */, + 106530BC1D998616005B2C60 /* include */, + 106530BD1D998624005B2C60 /* lib */, + 106530C41D9B1A0E005B2C60 /* t */, + 106530B31D9985E0005B2C60 /* Products */, + ); + sourceTree = ""; + }; + 106530B31D9985E0005B2C60 /* Products */ = { + isa = PBXGroup; + children = ( + 106530CC1D9B3D45005B2C60 /* test-openssl */, + 106530DA1D9B3E6F005B2C60 /* libpicotls-core.a */, + 106530FC1DAD8985005B2C60 /* cli */, + 1059004B1DC8D57000FB4085 /* test-minicrypto */, + 1059008C1DC8E1A300FB4085 /* libpicotls-openssl.a */, + 10EACB171DCEAF0F00CA0341 /* libpicotls-minicrypto.a */, + ); + name = Products; + sourceTree = ""; + }; + 106530BC1D998616005B2C60 /* include */ = { + isa = PBXGroup; + children = ( + 106530EE1D9E3476005B2C60 /* picotls */, + 106530BE1D99863B005B2C60 /* picotls.h */, + ); + path = include; + sourceTree = ""; + }; + 106530BD1D998624005B2C60 /* lib */ = { + isa = PBXGroup; + children = ( + E99B75DE1F5CDDB500CF503E /* asn1.c */, + E99B75DF1F5CDDB500CF503E /* pembase64.c */, + 1059003F1DC8D53200FB4085 /* cifra.c */, + 106530C21D9B004B005B2C60 /* openssl.c */, + 106530BF1D998641005B2C60 /* picotls.c */, + 105900C51DC9798800FB4085 /* uecc.c */, + E949EF272073629300511ECA /* minicrypto-pem.c */, + ); + path = lib; + sourceTree = ""; + }; + 106530C41D9B1A0E005B2C60 /* t */ = { + isa = PBXGroup; + children = ( + 106530FE1DAD8A3C005B2C60 /* cli.c */, + 106530E91D9B7C13005B2C60 /* picotls.c */, + 1059003D1DC8D4E300FB4085 /* minicrypto.c */, + 106530C51D9B1A98005B2C60 /* openssl.c */, + 106530E61D9B7AF6005B2C60 /* test.h */, + E9E3849C1F0748DD00D50990 /* util.h */, + ); + path = t; + sourceTree = ""; + }; + 106530E11D9B4000005B2C60 /* deps */ = { + isa = PBXGroup; + children = ( + 105900B91DC96A1B00FB4085 /* micro-ecc */, + 105900231DC8D34400FB4085 /* cifra */, + 106530E21D9B4005005B2C60 /* picotest */, + ); + path = deps; + sourceTree = ""; + }; + 106530E21D9B4005005B2C60 /* picotest */ = { + isa = PBXGroup; + children = ( + 106530E41D9B4021005B2C60 /* picotest.h */, + 106530E31D9B4021005B2C60 /* picotest.c */, + ); + path = picotest; + sourceTree = ""; + }; + 106530EE1D9E3476005B2C60 /* picotls */ = { + isa = PBXGroup; + children = ( + 1059004F1DC8D64E00FB4085 /* minicrypto.h */, + 106530ED1D9CEFF7005B2C60 /* openssl.h */, + ); + path = picotls; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXHeadersBuildPhase section */ + 1059007C1DC8E1A300FB4085 /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + 105900A21DC8E20D00FB4085 /* openssl.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 106530D81D9B3E6F005B2C60 /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + 105900921DC8E1FF00FB4085 /* blockwise.h in Headers */, + 105900BE1DC96A3500FB4085 /* types.h in Headers */, + 105900BF1DC96A3500FB4085 /* uECC_vli.h in Headers */, + 105900B21DC9438200FB4085 /* modes.h in Headers */, + 105900911DC8E1FF00FB4085 /* bitops.h in Headers */, + 105900991DC8E1FF00FB4085 /* cf_config.h in Headers */, + 1059009C1DC8E1FF00FB4085 /* handy.h in Headers */, + 105900C11DC96A3500FB4085 /* uECC.h in Headers */, + 1059009A1DC8E1FF00FB4085 /* drbg.h in Headers */, + 105900A11DC8E1FF00FB4085 /* tassert.h in Headers */, + 1059009D1DC8E1FF00FB4085 /* hmac.h in Headers */, + 105900941DC8E1FF00FB4085 /* chash.h in Headers */, + 1059009F1DC8E1FF00FB4085 /* sha2.h in Headers */, + 1059008F1DC8E1FF00FB4085 /* aes.h in Headers */, + 105900501DC8D64E00FB4085 /* minicrypto.h in Headers */, + 105900AE1DC941D700FB4085 /* gf128.h in Headers */, + 105900961DC8E1FF00FB4085 /* curve25519.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 10EACB021DCEAF0F00CA0341 /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + 10EACB031DCEAF0F00CA0341 /* blockwise.h in Headers */, + 10EACB041DCEAF0F00CA0341 /* types.h in Headers */, + 10EACB051DCEAF0F00CA0341 /* uECC_vli.h in Headers */, + 10EACB061DCEAF0F00CA0341 /* modes.h in Headers */, + E9BC76DF1EF3CCD100EB7A09 /* salsa20.h in Headers */, + 10EACB071DCEAF0F00CA0341 /* bitops.h in Headers */, + 10EACB081DCEAF0F00CA0341 /* cf_config.h in Headers */, + 10EACB091DCEAF0F00CA0341 /* handy.h in Headers */, + 10EACB0A1DCEAF0F00CA0341 /* uECC.h in Headers */, + 10EACB0B1DCEAF0F00CA0341 /* drbg.h in Headers */, + 10EACB0C1DCEAF0F00CA0341 /* tassert.h in Headers */, + 10EACB0D1DCEAF0F00CA0341 /* hmac.h in Headers */, + 10EACB0E1DCEAF0F00CA0341 /* chash.h in Headers */, + 10EACB0F1DCEAF0F00CA0341 /* sha2.h in Headers */, + E9BC76DE1EF3CCD100EB7A09 /* poly1305.h in Headers */, + 10EACB101DCEAF0F00CA0341 /* aes.h in Headers */, + 10EACB111DCEAF0F00CA0341 /* minicrypto.h in Headers */, + 10EACB121DCEAF0F00CA0341 /* gf128.h in Headers */, + 10EACB131DCEAF0F00CA0341 /* curve25519.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXHeadersBuildPhase section */ + +/* Begin PBXNativeTarget section */ + 105900411DC8D57000FB4085 /* test-minicrypto */ = { + isa = PBXNativeTarget; + buildConfigurationList = 105900481DC8D57000FB4085 /* Build configuration list for PBXNativeTarget "test-minicrypto" */; + buildPhases = ( + 105900421DC8D57000FB4085 /* Sources */, + 105900461DC8D57000FB4085 /* Frameworks */, + 105900471DC8D57000FB4085 /* CopyFiles */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = "test-minicrypto"; + productName = "test-crypto-openssl"; + productReference = 1059004B1DC8D57000FB4085 /* test-minicrypto */; + productType = "com.apple.product-type.tool"; + }; + 105900701DC8E1A300FB4085 /* picotls-openssl */ = { + isa = PBXNativeTarget; + buildConfigurationList = 105900891DC8E1A300FB4085 /* Build configuration list for PBXNativeTarget "picotls-openssl" */; + buildPhases = ( + 105900711DC8E1A300FB4085 /* Sources */, + 1059007B1DC8E1A300FB4085 /* Frameworks */, + 1059007C1DC8E1A300FB4085 /* Headers */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = "picotls-openssl"; + productName = picotls; + productReference = 1059008C1DC8E1A300FB4085 /* libpicotls-openssl.a */; + productType = "com.apple.product-type.library.static"; + }; + 106530CB1D9B3D45005B2C60 /* test-openssl */ = { + isa = PBXNativeTarget; + buildConfigurationList = 106530D01D9B3D45005B2C60 /* Build configuration list for PBXNativeTarget "test-openssl" */; + buildPhases = ( + 106530C81D9B3D45005B2C60 /* Sources */, + 106530C91D9B3D45005B2C60 /* Frameworks */, + 106530CA1D9B3D45005B2C60 /* CopyFiles */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = "test-openssl"; + productName = "test-crypto-openssl"; + productReference = 106530CC1D9B3D45005B2C60 /* test-openssl */; + productType = "com.apple.product-type.tool"; + }; + 106530D91D9B3E6F005B2C60 /* picotls-core */ = { + isa = PBXNativeTarget; + buildConfigurationList = 106530DD1D9B3E6F005B2C60 /* Build configuration list for PBXNativeTarget "picotls-core" */; + buildPhases = ( + 106530D61D9B3E6F005B2C60 /* Sources */, + 106530D71D9B3E6F005B2C60 /* Frameworks */, + 106530D81D9B3E6F005B2C60 /* Headers */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = "picotls-core"; + productName = picotls; + productReference = 106530DA1D9B3E6F005B2C60 /* libpicotls-core.a */; + productType = "com.apple.product-type.library.static"; + }; + 106530F11DAD8985005B2C60 /* cli */ = { + isa = PBXNativeTarget; + buildConfigurationList = 106530F91DAD8985005B2C60 /* Build configuration list for PBXNativeTarget "cli" */; + buildPhases = ( + 106530F21DAD8985005B2C60 /* Sources */, + 106530F71DAD8985005B2C60 /* Frameworks */, + 106530F81DAD8985005B2C60 /* CopyFiles */, + ); + buildRules = ( + ); + dependencies = ( + 10EACB191DCEAF4A00CA0341 /* PBXTargetDependency */, + 105900A81DC8E2E100FB4085 /* PBXTargetDependency */, + ); + name = cli; + productName = "test-crypto-openssl"; + productReference = 106530FC1DAD8985005B2C60 /* cli */; + productType = "com.apple.product-type.tool"; + }; + 10EACAF11DCEAF0F00CA0341 /* picotls-minicrypto */ = { + isa = PBXNativeTarget; + buildConfigurationList = 10EACB141DCEAF0F00CA0341 /* Build configuration list for PBXNativeTarget "picotls-minicrypto" */; + buildPhases = ( + 10EACAF21DCEAF0F00CA0341 /* Sources */, + 10EACB011DCEAF0F00CA0341 /* Frameworks */, + 10EACB021DCEAF0F00CA0341 /* Headers */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = "picotls-minicrypto"; + productName = picotls; + productReference = 10EACB171DCEAF0F00CA0341 /* libpicotls-minicrypto.a */; + productType = "com.apple.product-type.library.static"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 106530AA1D9985E0005B2C60 /* Project object */ = { + isa = PBXProject; + attributes = { + LastUpgradeCheck = 0830; + ORGANIZATIONNAME = "DeNA Co., Ltd."; + TargetAttributes = { + 106530CB1D9B3D45005B2C60 = { + CreatedOnToolsVersion = 7.3.1; + }; + 106530D91D9B3E6F005B2C60 = { + CreatedOnToolsVersion = 7.3.1; + }; + }; + }; + buildConfigurationList = 106530AD1D9985E0005B2C60 /* Build configuration list for PBXProject "picotls" */; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = English; + hasScannedForEncodings = 0; + knownRegions = ( + en, + ); + mainGroup = 106530A91D9985E0005B2C60; + productRefGroup = 106530B31D9985E0005B2C60 /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 106530D91D9B3E6F005B2C60 /* picotls-core */, + 10EACAF11DCEAF0F00CA0341 /* picotls-minicrypto */, + 105900701DC8E1A300FB4085 /* picotls-openssl */, + 106530F11DAD8985005B2C60 /* cli */, + 106530CB1D9B3D45005B2C60 /* test-openssl */, + 105900411DC8D57000FB4085 /* test-minicrypto */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXSourcesBuildPhase section */ + 105900421DC8D57000FB4085 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 105900B61DC943D400FB4085 /* aes.c in Sources */, + E99B75E51F5CE64E00CF503E /* pembase64.c in Sources */, + 105900431DC8D57000FB4085 /* picotls.c in Sources */, + 105900C41DC96B2200FB4085 /* uECC.c in Sources */, + 105900441DC8D57000FB4085 /* picotest.c in Sources */, + 105900611DC8DF8C00FB4085 /* sha256.c in Sources */, + E9BC76D21EF3A36A00EB7A09 /* chacha20.c in Sources */, + 1059004E1DC8D61800FB4085 /* minicrypto.c in Sources */, + E99B75E31F5CE54D00CF503E /* asn1.c in Sources */, + E9E865ED203BD46700E2FFCD /* sha512.c in Sources */, + 10EACAF01DCC843A00CA0341 /* drbg.c in Sources */, + E9BC76E11EF3CCDE00EB7A09 /* poly1305.c in Sources */, + 1059006A1DC8DFE300FB4085 /* hmac.c in Sources */, + 1059006F1DC8E00B00FB4085 /* chash.c in Sources */, + 105900B41DC943B500FB4085 /* gf128.c in Sources */, + 105900641DC8DFA700FB4085 /* curve25519.c in Sources */, + 105900B51DC943B900FB4085 /* gcm.c in Sources */, + 105900B31DC9439800FB4085 /* modes.c in Sources */, + 105900691DC8DFDF00FB4085 /* blockwise.c in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 105900711DC8E1A300FB4085 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 105900761DC8E1A300FB4085 /* openssl.c in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 106530C81D9B3D45005B2C60 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + E9BC76E01EF3CCDD00EB7A09 /* poly1305.c in Sources */, + 105900CF1DCBECFB00FB4085 /* modes.c in Sources */, + 106530EA1D9B7C13005B2C60 /* picotls.c in Sources */, + 105900CD1DCBECF400FB4085 /* gcm.c in Sources */, + E9E865EC203BD46600E2FFCD /* sha512.c in Sources */, + 105900D01DCBECFE00FB4085 /* sha256.c in Sources */, + 1059004C1DC8D5B700FB4085 /* openssl.c in Sources */, + 105900D21DCBED0A00FB4085 /* uecc.c in Sources */, + E99B75E21F5CE54D00CF503E /* asn1.c in Sources */, + 105900C81DCBECDD00FB4085 /* blockwise.c in Sources */, + 105900D31DCBED1D00FB4085 /* uECC.c in Sources */, + 105900C91DCBECE100FB4085 /* chash.c in Sources */, + 106530E51D9B4021005B2C60 /* picotest.c in Sources */, + 105900C71DCBECD800FB4085 /* aes.c in Sources */, + 105900D11DCBED0600FB4085 /* cifra.c in Sources */, + 105900CE1DCBECF700FB4085 /* gf128.c in Sources */, + 105900CC1DCBECF100FB4085 /* hmac.c in Sources */, + E9BC76D41EF3A37200EB7A09 /* chacha20.c in Sources */, + 105900CB1DCBECEA00FB4085 /* drbg.c in Sources */, + 105900CA1DCBECE500FB4085 /* curve25519.c in Sources */, + E99B75E41F5CE64E00CF503E /* pembase64.c in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 106530D61D9B3E6F005B2C60 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + E99B75E01F5CDDB500CF503E /* asn1.c in Sources */, + E99B75E11F5CDDB500CF503E /* pembase64.c in Sources */, + 106530EB1D9B7C5C005B2C60 /* picotls.c in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 106530F21DAD8985005B2C60 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 106530FF1DAD8A3C005B2C60 /* cli.c in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 10EACAF21DCEAF0F00CA0341 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 10EACAF31DCEAF0F00CA0341 /* uECC.c in Sources */, + 10EACAF41DCEAF0F00CA0341 /* uecc.c in Sources */, + E949EF282073629300511ECA /* minicrypto-pem.c in Sources */, + 10EACAF51DCEAF0F00CA0341 /* gf128.c in Sources */, + 10EACAF61DCEAF0F00CA0341 /* gcm.c in Sources */, + 10EACAF71DCEAF0F00CA0341 /* sha256.c in Sources */, + 10EACAF81DCEAF0F00CA0341 /* aes.c in Sources */, + E9BC76DD1EF3CCD100EB7A09 /* poly1305.c in Sources */, + 10EACAF91DCEAF0F00CA0341 /* modes.c in Sources */, + E9BC76CF1EF3A35E00EB7A09 /* chacha20.c in Sources */, + 10EACAFB1DCEAF0F00CA0341 /* chash.c in Sources */, + 10EACAFC1DCEAF0F00CA0341 /* curve25519.c in Sources */, + 10EACAFD1DCEAF0F00CA0341 /* hmac.c in Sources */, + 10EACAFE1DCEAF0F00CA0341 /* drbg.c in Sources */, + E9E865EB203BD46600E2FFCD /* sha512.c in Sources */, + 10EACAFF1DCEAF0F00CA0341 /* cifra.c in Sources */, + 10EACB001DCEAF0F00CA0341 /* blockwise.c in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXTargetDependency section */ + 105900A81DC8E2E100FB4085 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 105900701DC8E1A300FB4085 /* picotls-openssl */; + targetProxy = 105900A71DC8E2E100FB4085 /* PBXContainerItemProxy */; + }; + 10EACB191DCEAF4A00CA0341 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 106530D91D9B3E6F005B2C60 /* picotls-core */; + targetProxy = 10EACB181DCEAF4A00CA0341 /* PBXContainerItemProxy */; + }; +/* End PBXTargetDependency section */ + +/* Begin XCBuildConfiguration section */ + 105900491DC8D57000FB4085 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + GCC_PREPROCESSOR_DEFINITIONS = ""; + OTHER_LDFLAGS = ""; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Debug; + }; + 1059004A1DC8D57000FB4085 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + GCC_PREPROCESSOR_DEFINITIONS = ""; + OTHER_LDFLAGS = ""; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Release; + }; + 1059008A1DC8E1A300FB4085 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + EXECUTABLE_PREFIX = lib; + HEADER_SEARCH_PATHS = ( + "/usr/local/openssl-1.0.2/include", + include, + ); + LIBRARY_SEARCH_PATHS = "/usr/local/openssl-1.0.2/lib"; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Debug; + }; + 1059008B1DC8E1A300FB4085 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + EXECUTABLE_PREFIX = lib; + HEADER_SEARCH_PATHS = ( + "/usr/local/openssl-1.0.2/include", + include, + ); + LIBRARY_SEARCH_PATHS = "/usr/local/openssl-1.0.2/lib"; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Release; + }; + 106530B71D9985E0005B2C60 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + CODE_SIGN_IDENTITY = "-"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + HEADER_SEARCH_PATHS = include; + LIBRARY_SEARCH_PATHS = ""; + MACOSX_DEPLOYMENT_TARGET = 10.11; + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = macosx; + }; + name = Debug; + }; + 106530B81D9985E0005B2C60 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + CODE_SIGN_IDENTITY = "-"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + HEADER_SEARCH_PATHS = include; + LIBRARY_SEARCH_PATHS = ""; + MACOSX_DEPLOYMENT_TARGET = 10.11; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = macosx; + }; + name = Release; + }; + 106530D11D9B3D45005B2C60 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + GCC_PREPROCESSOR_DEFINITIONS = ""; + HEADER_SEARCH_PATHS = ( + "/usr/local/openssl-1.0.2/include", + include, + ); + LIBRARY_SEARCH_PATHS = "/usr/local/openssl-1.0.2/lib"; + OTHER_LDFLAGS = "-lcrypto"; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Debug; + }; + 106530D21D9B3D45005B2C60 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + GCC_PREPROCESSOR_DEFINITIONS = ""; + HEADER_SEARCH_PATHS = ( + "/usr/local/openssl-1.0.2/include", + include, + ); + LIBRARY_SEARCH_PATHS = "/usr/local/openssl-1.0.2/lib"; + OTHER_LDFLAGS = "-lcrypto"; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Release; + }; + 106530DB1D9B3E6F005B2C60 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + EXECUTABLE_PREFIX = lib; + GCC_PREPROCESSOR_DEFINITIONS = ""; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Debug; + }; + 106530DC1D9B3E6F005B2C60 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + EXECUTABLE_PREFIX = lib; + GCC_PREPROCESSOR_DEFINITIONS = ""; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Release; + }; + 106530FA1DAD8985005B2C60 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + HEADER_SEARCH_PATHS = ( + "/usr/local/openssl-1.0.2/include", + include, + ); + LIBRARY_SEARCH_PATHS = "/usr/local/openssl-1.0.2/lib"; + OTHER_LDFLAGS = "-lcrypto"; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Debug; + }; + 106530FB1DAD8985005B2C60 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + HEADER_SEARCH_PATHS = ( + "/usr/local/openssl-1.0.2/include", + include, + ); + LIBRARY_SEARCH_PATHS = "/usr/local/openssl-1.0.2/lib"; + OTHER_LDFLAGS = "-lcrypto"; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Release; + }; + 10EACB151DCEAF0F00CA0341 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + EXECUTABLE_PREFIX = lib; + GCC_PREPROCESSOR_DEFINITIONS = ""; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Debug; + }; + 10EACB161DCEAF0F00CA0341 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + EXECUTABLE_PREFIX = lib; + GCC_PREPROCESSOR_DEFINITIONS = ""; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 105900481DC8D57000FB4085 /* Build configuration list for PBXNativeTarget "test-minicrypto" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 105900491DC8D57000FB4085 /* Debug */, + 1059004A1DC8D57000FB4085 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 105900891DC8E1A300FB4085 /* Build configuration list for PBXNativeTarget "picotls-openssl" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 1059008A1DC8E1A300FB4085 /* Debug */, + 1059008B1DC8E1A300FB4085 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 106530AD1D9985E0005B2C60 /* Build configuration list for PBXProject "picotls" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 106530B71D9985E0005B2C60 /* Debug */, + 106530B81D9985E0005B2C60 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 106530D01D9B3D45005B2C60 /* Build configuration list for PBXNativeTarget "test-openssl" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 106530D11D9B3D45005B2C60 /* Debug */, + 106530D21D9B3D45005B2C60 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 106530DD1D9B3E6F005B2C60 /* Build configuration list for PBXNativeTarget "picotls-core" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 106530DB1D9B3E6F005B2C60 /* Debug */, + 106530DC1D9B3E6F005B2C60 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 106530F91DAD8985005B2C60 /* Build configuration list for PBXNativeTarget "cli" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 106530FA1DAD8985005B2C60 /* Debug */, + 106530FB1DAD8985005B2C60 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 10EACB141DCEAF0F00CA0341 /* Build configuration list for PBXNativeTarget "picotls-minicrypto" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 10EACB151DCEAF0F00CA0341 /* Debug */, + 10EACB161DCEAF0F00CA0341 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 106530AA1D9985E0005B2C60 /* Project object */; +} diff --git a/web/server/h2o/libh2o/deps/picotls/picotls.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/web/server/h2o/libh2o/deps/picotls/picotls.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 00000000..5cd1211d --- /dev/null +++ b/web/server/h2o/libh2o/deps/picotls/picotls.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/web/server/h2o/libh2o/deps/picotls/picotlsvs/cifra/ReadMe.txt b/web/server/h2o/libh2o/deps/picotls/picotlsvs/cifra/ReadMe.txt new file mode 100644 index 00000000..c1a42b27 --- /dev/null +++ b/web/server/h2o/libh2o/deps/picotls/picotlsvs/cifra/ReadMe.txt @@ -0,0 +1,29 @@ +======================================================================== + STATIC LIBRARY : cifra Project Overview +======================================================================== + +AppWizard has created this cifra library project for you. + +No source files were created as part of your project. + + +cifra.vcxproj + This is the main project file for VC++ projects generated using an Application Wizard. + It contains information about the version of Visual C++ that generated the file, and + information about the platforms, configurations, and project features selected with the + Application Wizard. + +cifra.vcxproj.filters + This is the filters file for VC++ projects generated using an Application Wizard. + It contains information about the association between the files in your project + and the filters. This association is used in the IDE to show grouping of files with + similar extensions under a specific node (for e.g. ".cpp" files are associated with the + "Source Files" filter). + +///////////////////////////////////////////////////////////////////////////// +Other notes: + +AppWizard uses "TODO:" comments to indicate parts of the source code you +should add to or customize. + +///////////////////////////////////////////////////////////////////////////// diff --git a/web/server/h2o/libh2o/deps/picotls/picotlsvs/cifra/cifra.vcxproj b/web/server/h2o/libh2o/deps/picotls/picotlsvs/cifra/cifra.vcxproj new file mode 100644 index 00000000..53c73cfe --- /dev/null +++ b/web/server/h2o/libh2o/deps/picotls/picotlsvs/cifra/cifra.vcxproj @@ -0,0 +1,188 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + 15.0 + {5D4DA3A3-7851-4CAE-AE4F-C421A2C8C440} + Win32Proj + cifra + 10.0.14393.0 + + + + StaticLibrary + true + v141 + Unicode + + + StaticLibrary + false + v141 + true + Unicode + + + StaticLibrary + true + v141 + Unicode + + + StaticLibrary + false + v141 + true + Unicode + + + + + + + + + + + + + + + + + + + + + + + + + Level3 + Disabled + WIN32;_DEBUG;_LIB;_WINDOWS;%(PreprocessorDefinitions) + $(ProjectDir);$(ProjectDir)..\..\picotls;$(ProjectDir)..\..\include;$(ProjectDir)..\..\deps\cifra\src;$(ProjectDir)..\..\deps\cifra\src\ext;%(AdditionalIncludeDirectories) + + + Windows + + + + + + + Level3 + Disabled + _DEBUG;_LIB;_WINDOWS;%(PreprocessorDefinitions) + $(ProjectDir);$(ProjectDir)..\..\picotls;$(ProjectDir)..\..\include;$(ProjectDir)..\..\deps\cifra\src;$(ProjectDir)..\..\deps\cifra\src\ext;%(AdditionalIncludeDirectories) + + + Windows + + + + + Level3 + + + MaxSpeed + true + true + WIN32;NDEBUG;_LIB;_WINDOWS;%(PreprocessorDefinitions) + $(ProjectDir);$(ProjectDir)..\..\picotls;$(ProjectDir)..\..\include;$(ProjectDir)..\..\deps\cifra\src;$(ProjectDir)..\..\deps\cifra\src\ext;$(ProjectDir)\..\..\deps\micro-ecc;$(OPENSSLDIR)\include\;%(AdditionalIncludeDirectories) + + + Windows + true + true + + + + + Level3 + + + MaxSpeed + true + true + NDEBUG;_LIB;_WINDOWS;%(PreprocessorDefinitions) + $(ProjectDir);$(ProjectDir)..\..\picotls;$(ProjectDir)..\..\include;$(ProjectDir)..\..\deps\cifra\src;$(ProjectDir)..\..\deps\cifra\src\ext;%(AdditionalIncludeDirectories) + + + Windows + true + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/web/server/h2o/libh2o/deps/picotls/picotlsvs/cifra/cifra.vcxproj.filters b/web/server/h2o/libh2o/deps/picotls/picotlsvs/cifra/cifra.vcxproj.filters new file mode 100644 index 00000000..6c0de7f3 --- /dev/null +++ b/web/server/h2o/libh2o/deps/picotls/picotlsvs/cifra/cifra.vcxproj.filters @@ -0,0 +1,150 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + + + + \ No newline at end of file diff --git a/web/server/h2o/libh2o/deps/picotls/picotlsvs/microecc/ReadMe.txt b/web/server/h2o/libh2o/deps/picotls/picotlsvs/microecc/ReadMe.txt new file mode 100644 index 00000000..ed0a5281 --- /dev/null +++ b/web/server/h2o/libh2o/deps/picotls/picotlsvs/microecc/ReadMe.txt @@ -0,0 +1,29 @@ +======================================================================== + STATIC LIBRARY : microecc Project Overview +======================================================================== + +AppWizard has created this microecc library project for you. + +No source files were created as part of your project. + + +microecc.vcxproj + This is the main project file for VC++ projects generated using an Application Wizard. + It contains information about the version of Visual C++ that generated the file, and + information about the platforms, configurations, and project features selected with the + Application Wizard. + +microecc.vcxproj.filters + This is the filters file for VC++ projects generated using an Application Wizard. + It contains information about the association between the files in your project + and the filters. This association is used in the IDE to show grouping of files with + similar extensions under a specific node (for e.g. ".cpp" files are associated with the + "Source Files" filter). + +///////////////////////////////////////////////////////////////////////////// +Other notes: + +AppWizard uses "TODO:" comments to indicate parts of the source code you +should add to or customize. + +///////////////////////////////////////////////////////////////////////////// diff --git a/web/server/h2o/libh2o/deps/picotls/picotlsvs/microecc/microecc.vcxproj b/web/server/h2o/libh2o/deps/picotls/picotlsvs/microecc/microecc.vcxproj new file mode 100644 index 00000000..46ebc5b9 --- /dev/null +++ b/web/server/h2o/libh2o/deps/picotls/picotlsvs/microecc/microecc.vcxproj @@ -0,0 +1,140 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + 15.0 + {3440FDEA-84D2-4424-BB19-B4B26A6ADC8A} + Win32Proj + microecc + 10.0.14393.0 + + + + StaticLibrary + true + v141 + Unicode + + + StaticLibrary + false + v141 + true + Unicode + + + StaticLibrary + true + v141 + Unicode + + + StaticLibrary + false + v141 + true + Unicode + + + + + + + + + + + + + + + + + + + + + + + + + Level3 + Disabled + WIN32;_DEBUG;_LIB;_WINDOWS;%(PreprocessorDefinitions) + + + Windows + + + + + + + Level3 + Disabled + _DEBUG;_LIB;_WINDOWS;%(PreprocessorDefinitions) + + + Windows + + + + + Level3 + + + MaxSpeed + true + true + WIN32;NDEBUG;_LIB;_WINDOWS;%(PreprocessorDefinitions) + $(ProjectDir);$(ProjectDir)\..\..\picotls;$(ProjectDir)\..\..\include;$(ProjectDir)\..\..\deps\cifra\src;$(ProjectDir)\..\..\deps\cifra\src\ext;$(ProjectDir)\..\..\deps\micro-ecc;$(OPENSSLDIR)\include\;%(AdditionalIncludeDirectories) + + + Windows + true + true + + + + + Level3 + + + MaxSpeed + true + true + NDEBUG;_LIB;_WINDOWS;%(PreprocessorDefinitions) + + + Windows + true + true + + + + + + + + + + + + \ No newline at end of file diff --git a/web/server/h2o/libh2o/deps/picotls/picotlsvs/microecc/microecc.vcxproj.filters b/web/server/h2o/libh2o/deps/picotls/picotlsvs/microecc/microecc.vcxproj.filters new file mode 100644 index 00000000..b7ed7be3 --- /dev/null +++ b/web/server/h2o/libh2o/deps/picotls/picotlsvs/microecc/microecc.vcxproj.filters @@ -0,0 +1,25 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + + + + Source Files + + + \ No newline at end of file diff --git a/web/server/h2o/libh2o/deps/picotls/picotlsvs/openssl.cnf b/web/server/h2o/libh2o/deps/picotls/picotlsvs/openssl.cnf new file mode 100644 index 00000000..c96e8432 --- /dev/null +++ b/web/server/h2o/libh2o/deps/picotls/picotlsvs/openssl.cnf @@ -0,0 +1,35 @@ +[ req ] +default_bits = 1024 +default_keyfile= privkey.pem +distinguished_name = req_distinguished_name + + +[ req_distinguished_name ] +countryName= US +countryName_min= 2 +countryName_max = 2 +stateOrProvinceName= Washington +localityName = Seattle +organizationName = Example +commonName = Localhost +commonName_max = 64 +emailAddress = localhost@example.com +emailAddress_max = 40 + + +[ alternate_names ] + +DNS.1 = example.com +DNS.2 = www.example.com +DNS.3 = mail.example.com +DNS.4 = ftp.example.com + +# Add these if you need them. But usually you don't want them or +# need them in production. You may need them for development. +# DNS.5 = localhost +# DNS.6 = localhost.localdomain +# DNS.7 = 127.0.0.1 + +# IPv6 localhost +# DNS.8 = ::1 + diff --git a/web/server/h2o/libh2o/deps/picotls/picotlsvs/picotls/ReadMe.txt b/web/server/h2o/libh2o/deps/picotls/picotlsvs/picotls/ReadMe.txt new file mode 100644 index 00000000..08baa570 --- /dev/null +++ b/web/server/h2o/libh2o/deps/picotls/picotlsvs/picotls/ReadMe.txt @@ -0,0 +1,37 @@ +======================================================================== + STATIC LIBRARY : picotls Project Overview +======================================================================== + +AppWizard has created this picotls library project for you. + +This file contains a summary of what you will find in each of the files that +make up your picotls application. + + +picotls.vcxproj + This is the main project file for VC++ projects generated using an Application Wizard. + It contains information about the version of Visual C++ that generated the file, and + information about the platforms, configurations, and project features selected with the + Application Wizard. + +picotls.vcxproj.filters + This is the filters file for VC++ projects generated using an Application Wizard. + It contains information about the association between the files in your project + and the filters. This association is used in the IDE to show grouping of files with + similar extensions under a specific node (for e.g. ".cpp" files are associated with the + "Source Files" filter). + + +///////////////////////////////////////////////////////////////////////////// + +StdAfx.h, StdAfx.cpp + These files are used to build a precompiled header (PCH) file + named picotls.pch and a precompiled types file named StdAfx.obj. + +///////////////////////////////////////////////////////////////////////////// +Other notes: + +AppWizard uses "TODO:" comments to indicate parts of the source code you +should add to or customize. + +///////////////////////////////////////////////////////////////////////////// diff --git a/web/server/h2o/libh2o/deps/picotls/picotlsvs/picotls/picotls.vcxproj b/web/server/h2o/libh2o/deps/picotls/picotlsvs/picotls/picotls.vcxproj new file mode 100644 index 00000000..1eea9ea1 --- /dev/null +++ b/web/server/h2o/libh2o/deps/picotls/picotlsvs/picotls/picotls.vcxproj @@ -0,0 +1,175 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + 15.0 + {46E6D6E9-7A30-4058-9661-DF70CC07E821} + Win32Proj + picotls + 10.0.14393.0 + + + + StaticLibrary + true + v141 + Unicode + + + StaticLibrary + false + v141 + true + Unicode + + + StaticLibrary + true + v141 + Unicode + + + StaticLibrary + false + v141 + true + Unicode + + + + + + + + + + + + + + + + + + + + + + + NotUsing + Level3 + Disabled + WIN32;_DEBUG;_LIB;_WINDOWS;%(PreprocessorDefinitions) + $(ProjectDir);$(ProjectDir)\..\..\picotls;$(ProjectDir)\..\..\include;$(ProjectDir)\..\..\deps\cifra\src;$(ProjectDir)\..\..\deps\cifra\src\ext;$(ProjectDir)\..\..\deps\micro-ecc;$(OPENSSLDIR)\include\;%(AdditionalIncludeDirectories) + + + Windows + + + + + NotUsing + Level3 + Disabled + _DEBUG;_LIB;_WINDOWS;%(PreprocessorDefinitions) + $(ProjectDir);$(ProjectDir)..\..\picotls;$(ProjectDir)..\..\include;$(ProjectDir)..\..\include\picotls;$(ProjectDir)..\..\deps\cifra\src;$(ProjectDir)..\..\deps\micro-ecc;$(OPENSSL64DIR)\include\;%(AdditionalIncludeDirectories) + + + Windows + + + + + Level3 + NotUsing + MaxSpeed + true + true + WIN32;NDEBUG;_LIB;_WINDOWS;%(PreprocessorDefinitions) + $(ProjectDir);$(ProjectDir)\..\..\picotls;$(ProjectDir)\..\..\include;$(ProjectDir)\..\..\deps\cifra\src;$(ProjectDir)\..\..\deps\micro-ecc;$(OPENSSLDIR)\include\;%(AdditionalIncludeDirectories) + + + Windows + true + true + + + + + Level3 + NotUsing + MaxSpeed + true + true + NDEBUG;_LIB;_WINDOWS;%(PreprocessorDefinitions) + $(ProjectDir);$(ProjectDir)..\..\picotls;$(ProjectDir)..\..\include;$(ProjectDir)..\..\include\picotls;$(ProjectDir)..\..\deps\cifra\src;$(ProjectDir)..\..\deps\micro-ecc;$(OPENSSL64DIR)\include\;%(AdditionalIncludeDirectories) + + + Windows + true + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/web/server/h2o/libh2o/deps/picotls/picotlsvs/picotls/picotls.vcxproj.filters b/web/server/h2o/libh2o/deps/picotls/picotlsvs/picotls/picotls.vcxproj.filters new file mode 100644 index 00000000..4603cc47 --- /dev/null +++ b/web/server/h2o/libh2o/deps/picotls/picotlsvs/picotls/picotls.vcxproj.filters @@ -0,0 +1,123 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + + + + \ No newline at end of file diff --git a/web/server/h2o/libh2o/deps/picotls/picotlsvs/picotls/picotls.vcxproj.user b/web/server/h2o/libh2o/deps/picotls/picotlsvs/picotls/picotls.vcxproj.user new file mode 100644 index 00000000..be250787 --- /dev/null +++ b/web/server/h2o/libh2o/deps/picotls/picotlsvs/picotls/picotls.vcxproj.user @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/web/server/h2o/libh2o/deps/picotls/picotlsvs/picotls/targetver.h b/web/server/h2o/libh2o/deps/picotls/picotlsvs/picotls/targetver.h new file mode 100644 index 00000000..87c0086d --- /dev/null +++ b/web/server/h2o/libh2o/deps/picotls/picotlsvs/picotls/targetver.h @@ -0,0 +1,8 @@ +#pragma once + +// Including SDKDDKVer.h defines the highest available Windows platform. + +// If you wish to build your application for a previous Windows platform, include WinSDKVer.h and +// set the _WIN32_WINNT macro to the platform you wish to support before including SDKDDKVer.h. + +#include diff --git a/web/server/h2o/libh2o/deps/picotls/picotlsvs/picotls/wincompat.h b/web/server/h2o/libh2o/deps/picotls/picotlsvs/picotls/wincompat.h new file mode 100644 index 00000000..8ff26bfb --- /dev/null +++ b/web/server/h2o/libh2o/deps/picotls/picotlsvs/picotls/wincompat.h @@ -0,0 +1,35 @@ +#ifndef WINCOMPAT_H +#define WINCOMPAT_H + +#include +#define ssize_t int +#include + +#ifndef gettimeofday +#define gettimeofday wintimeofday + +#ifndef __attribute__ +#define __attribute__(X) +#endif + +#ifdef __cplusplus +extern "C" { +#endif + struct timezone { + int tz_minuteswest; /* minutes west of Greenwich */ + int tz_dsttime; /* type of DST correction */ + }; + + int wintimeofday(struct timeval* tv, struct timezone* tz); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + + + + +#endif + + +#endif /* WINCOMPAT_H */ \ No newline at end of file diff --git a/web/server/h2o/libh2o/deps/picotls/picotlsvs/picotls/wintimeofday.c b/web/server/h2o/libh2o/deps/picotls/picotlsvs/picotls/wintimeofday.c new file mode 100644 index 00000000..a293707e --- /dev/null +++ b/web/server/h2o/libh2o/deps/picotls/picotlsvs/picotls/wintimeofday.c @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2016 Christian Huitema + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifdef _WINDOWS +#include "wincompat.h" + + /* + * This is a simple replacement for the "gettimeofday" finction, + * which is not available on Windows + */ + +int wintimeofday(struct timeval* tv, struct timezone* tz) +{ + FILETIME ft; + uint64_t now = 0; + + /* + * The GetSystemTimeAsFileTime API returns the number + * of 100-nanosecond intervals since January 1, 1601 (UTC), + * in FILETIME format. + */ + GetSystemTimeAsFileTime(&ft); + + /* + * Convert to plain 64 bit format, without making + * assumptions about the FILETIME structure alignment. + */ + now = ft.dwHighDateTime; + now <<= 32; + now |= ft.dwLowDateTime; + /* + * Convert units from 100ns to 1us + */ + now /= 10; + /* + * Account for microseconds elapsed between 1601 and 1970. + */ + now -= 11644473600000000ULL; + + if (tv != NULL) + { + uint64_t sec = now / 1000000; + uint64_t usec = now % 1000000; + + tv->tv_sec = (long)sec; + tv->tv_usec = (long)usec; + } + + if (tz != NULL) + { + /* + * TODO: implement a timezone retrieval function. + * Not urgent, since the GetDNS code always set this parameter to NULL. + */ + return -1; + } + + return 0; +} +#endif /* WIN32 */ \ No newline at end of file diff --git a/web/server/h2o/libh2o/deps/picotls/picotlsvs/picotlsvs.sln b/web/server/h2o/libh2o/deps/picotls/picotlsvs/picotlsvs.sln new file mode 100644 index 00000000..dd273a45 --- /dev/null +++ b/web/server/h2o/libh2o/deps/picotls/picotlsvs/picotlsvs.sln @@ -0,0 +1,78 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 15 +VisualStudioVersion = 15.0.26228.9 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "picotlsvs", "picotlsvs\picotlsvs.vcxproj", "{D0265367-FCCF-47A4-95FD-C33BECAB3486}" + ProjectSection(ProjectDependencies) = postProject + {5D4DA3A3-7851-4CAE-AE4F-C421A2C8C440} = {5D4DA3A3-7851-4CAE-AE4F-C421A2C8C440} + {46E6D6E9-7A30-4058-9661-DF70CC07E821} = {46E6D6E9-7A30-4058-9661-DF70CC07E821} + {3440FDEA-84D2-4424-BB19-B4B26A6ADC8A} = {3440FDEA-84D2-4424-BB19-B4B26A6ADC8A} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "picotls", "picotls\picotls.vcxproj", "{46E6D6E9-7A30-4058-9661-DF70CC07E821}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "testopenssl", "testopenssl\testopenssl.vcxproj", "{8750EE3B-9440-48BF-8D83-7274E94B06A7}" + ProjectSection(ProjectDependencies) = postProject + {5D4DA3A3-7851-4CAE-AE4F-C421A2C8C440} = {5D4DA3A3-7851-4CAE-AE4F-C421A2C8C440} + {46E6D6E9-7A30-4058-9661-DF70CC07E821} = {46E6D6E9-7A30-4058-9661-DF70CC07E821} + {3440FDEA-84D2-4424-BB19-B4B26A6ADC8A} = {3440FDEA-84D2-4424-BB19-B4B26A6ADC8A} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "microecc", "microecc\microecc.vcxproj", "{3440FDEA-84D2-4424-BB19-B4B26A6ADC8A}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "cifra", "cifra\cifra.vcxproj", "{5D4DA3A3-7851-4CAE-AE4F-C421A2C8C440}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 + Release|x64 = Release|x64 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {D0265367-FCCF-47A4-95FD-C33BECAB3486}.Debug|x64.ActiveCfg = Debug|x64 + {D0265367-FCCF-47A4-95FD-C33BECAB3486}.Debug|x64.Build.0 = Debug|x64 + {D0265367-FCCF-47A4-95FD-C33BECAB3486}.Debug|x86.ActiveCfg = Debug|Win32 + {D0265367-FCCF-47A4-95FD-C33BECAB3486}.Debug|x86.Build.0 = Debug|Win32 + {D0265367-FCCF-47A4-95FD-C33BECAB3486}.Release|x64.ActiveCfg = Release|x64 + {D0265367-FCCF-47A4-95FD-C33BECAB3486}.Release|x64.Build.0 = Release|x64 + {D0265367-FCCF-47A4-95FD-C33BECAB3486}.Release|x86.ActiveCfg = Release|Win32 + {D0265367-FCCF-47A4-95FD-C33BECAB3486}.Release|x86.Build.0 = Release|Win32 + {46E6D6E9-7A30-4058-9661-DF70CC07E821}.Debug|x64.ActiveCfg = Debug|x64 + {46E6D6E9-7A30-4058-9661-DF70CC07E821}.Debug|x64.Build.0 = Debug|x64 + {46E6D6E9-7A30-4058-9661-DF70CC07E821}.Debug|x86.ActiveCfg = Debug|Win32 + {46E6D6E9-7A30-4058-9661-DF70CC07E821}.Debug|x86.Build.0 = Debug|Win32 + {46E6D6E9-7A30-4058-9661-DF70CC07E821}.Release|x64.ActiveCfg = Release|x64 + {46E6D6E9-7A30-4058-9661-DF70CC07E821}.Release|x64.Build.0 = Release|x64 + {46E6D6E9-7A30-4058-9661-DF70CC07E821}.Release|x86.ActiveCfg = Release|Win32 + {46E6D6E9-7A30-4058-9661-DF70CC07E821}.Release|x86.Build.0 = Release|Win32 + {8750EE3B-9440-48BF-8D83-7274E94B06A7}.Debug|x64.ActiveCfg = Debug|x64 + {8750EE3B-9440-48BF-8D83-7274E94B06A7}.Debug|x64.Build.0 = Debug|x64 + {8750EE3B-9440-48BF-8D83-7274E94B06A7}.Debug|x86.ActiveCfg = Debug|Win32 + {8750EE3B-9440-48BF-8D83-7274E94B06A7}.Debug|x86.Build.0 = Debug|Win32 + {8750EE3B-9440-48BF-8D83-7274E94B06A7}.Release|x64.ActiveCfg = Release|x64 + {8750EE3B-9440-48BF-8D83-7274E94B06A7}.Release|x64.Build.0 = Release|x64 + {8750EE3B-9440-48BF-8D83-7274E94B06A7}.Release|x86.ActiveCfg = Release|Win32 + {8750EE3B-9440-48BF-8D83-7274E94B06A7}.Release|x86.Build.0 = Release|Win32 + {3440FDEA-84D2-4424-BB19-B4B26A6ADC8A}.Debug|x64.ActiveCfg = Debug|x64 + {3440FDEA-84D2-4424-BB19-B4B26A6ADC8A}.Debug|x64.Build.0 = Debug|x64 + {3440FDEA-84D2-4424-BB19-B4B26A6ADC8A}.Debug|x86.ActiveCfg = Debug|Win32 + {3440FDEA-84D2-4424-BB19-B4B26A6ADC8A}.Debug|x86.Build.0 = Debug|Win32 + {3440FDEA-84D2-4424-BB19-B4B26A6ADC8A}.Release|x64.ActiveCfg = Release|x64 + {3440FDEA-84D2-4424-BB19-B4B26A6ADC8A}.Release|x64.Build.0 = Release|x64 + {3440FDEA-84D2-4424-BB19-B4B26A6ADC8A}.Release|x86.ActiveCfg = Release|Win32 + {3440FDEA-84D2-4424-BB19-B4B26A6ADC8A}.Release|x86.Build.0 = Release|Win32 + {5D4DA3A3-7851-4CAE-AE4F-C421A2C8C440}.Debug|x64.ActiveCfg = Debug|x64 + {5D4DA3A3-7851-4CAE-AE4F-C421A2C8C440}.Debug|x64.Build.0 = Debug|x64 + {5D4DA3A3-7851-4CAE-AE4F-C421A2C8C440}.Debug|x86.ActiveCfg = Debug|Win32 + {5D4DA3A3-7851-4CAE-AE4F-C421A2C8C440}.Debug|x86.Build.0 = Debug|Win32 + {5D4DA3A3-7851-4CAE-AE4F-C421A2C8C440}.Release|x64.ActiveCfg = Release|x64 + {5D4DA3A3-7851-4CAE-AE4F-C421A2C8C440}.Release|x64.Build.0 = Release|x64 + {5D4DA3A3-7851-4CAE-AE4F-C421A2C8C440}.Release|x86.ActiveCfg = Release|Win32 + {5D4DA3A3-7851-4CAE-AE4F-C421A2C8C440}.Release|x86.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/web/server/h2o/libh2o/deps/picotls/picotlsvs/picotlsvs/ReadMe.txt b/web/server/h2o/libh2o/deps/picotls/picotlsvs/picotlsvs/ReadMe.txt new file mode 100644 index 00000000..b12bf060 --- /dev/null +++ b/web/server/h2o/libh2o/deps/picotls/picotlsvs/picotlsvs/ReadMe.txt @@ -0,0 +1,40 @@ +======================================================================== + CONSOLE APPLICATION : picotlsvs Project Overview +======================================================================== + +AppWizard has created this picotlsvs application for you. + +This file contains a summary of what you will find in each of the files that +make up your picotlsvs application. + + +picotlsvs.vcxproj + This is the main project file for VC++ projects generated using an Application Wizard. + It contains information about the version of Visual C++ that generated the file, and + information about the platforms, configurations, and project features selected with the + Application Wizard. + +picotlsvs.vcxproj.filters + This is the filters file for VC++ projects generated using an Application Wizard. + It contains information about the association between the files in your project + and the filters. This association is used in the IDE to show grouping of files with + similar extensions under a specific node (for e.g. ".cpp" files are associated with the + "Source Files" filter). + +picotlsvs.cpp + This is the main application source file. + +///////////////////////////////////////////////////////////////////////////// +Other standard files: + +StdAfx.h, StdAfx.cpp + These files are used to build a precompiled header (PCH) file + named picotlsvs.pch and a precompiled types file named StdAfx.obj. + +///////////////////////////////////////////////////////////////////////////// +Other notes: + +AppWizard uses "TODO:" comments to indicate parts of the source code you +should add to or customize. + +///////////////////////////////////////////////////////////////////////////// diff --git a/web/server/h2o/libh2o/deps/picotls/picotlsvs/picotlsvs/cert.pem b/web/server/h2o/libh2o/deps/picotls/picotlsvs/picotlsvs/cert.pem new file mode 100644 index 00000000..a7fbf0a0 --- /dev/null +++ b/web/server/h2o/libh2o/deps/picotls/picotlsvs/picotlsvs/cert.pem @@ -0,0 +1,20 @@ +-----BEGIN CERTIFICATE----- +MIIDMDCCAhgCCQDKfyE0Al0a3TANBgkqhkiG9w0BAQsFADBaMQswCQYDVQQGEwJV +UzETMBEGA1UECAwKV2FzaGluZ3RvbjEQMA4GA1UEBwwHU2VhdHRsZTEQMA4GA1UE +CgwHRXhhbXBsZTESMBAGA1UEAwwJTG9jYWxIb3N0MB4XDTE3MDYyNjA0NDUzMloX +DTE4MDYyNjA0NDUzMlowWjELMAkGA1UEBhMCVVMxEzARBgNVBAgMCldhc2hpbmd0 +b24xEDAOBgNVBAcMB1NlYXR0bGUxEDAOBgNVBAoMB0V4YW1wbGUxEjAQBgNVBAMM +CUxvY2FsSG9zdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALk0szcy +JGaCu3N1l3e4oippgWn8COAckw1DDUvp9ml8bZnaZ841nbCA38O6Blnu1gxgS/F8 +FSIu29z4bJPQgStYOTxbxGym/jHMzbS9xzI5Byv3+G7tu/1QEoHcm9DyzSiIvWqM +ytkloPdEgl+qUinWjvWGht9QzPSk6vNSM1Vqd2Gz7ZJIxNp6muzaSd5mQBSeO1AO +uIhyIhIWMPpeR3BrtI2PCj5svrQ5OVlyKc6yoXYKDUFxIEKhOwjCU027ACdJRDcD +WW+GzqR4EamWztQ016YcrlAa0PpAewDa1FQoXWy6Gl+6YF8GIhn+ZHsJN0RgdqKE +u1bkhL7iUl4vnjcCAwEAATANBgkqhkiG9w0BAQsFAAOCAQEAEZjmYK+qoXImkUw3 +mangy2sUt9UHLQENGBhLbaMny8RRxcKedpf8COwsP56ONyZazzzyUgjlphQhunEe +HsNQWD7s04cC3wuNWXvnFW/MsABjnzrGk1m6VDc5uxqBSrFFP1UtqwMleDIlgzVw +H2mx4R1IyhGW+BYkDBwWpHmMFR9fXjdkVSzb5THwhhq7y2xJhrkKhj/iCTGlIMke +d207w3vqw1X6dep1CMYj/B+ar/3l5AJSr+K1jsqVIzHugGuRMtV5DsKtS/DNqXG5 +sP+2YA/ohrXv/MCzHzVZ77lCetj7jHl2muX3rLF4IVTKWMrpi18ZwobB3JieFy1h +WZydqg== +-----END CERTIFICATE----- diff --git a/web/server/h2o/libh2o/deps/picotls/picotlsvs/picotlsvs/ec_cert.pem b/web/server/h2o/libh2o/deps/picotls/picotlsvs/picotlsvs/ec_cert.pem new file mode 100644 index 00000000..51bf0443 --- /dev/null +++ b/web/server/h2o/libh2o/deps/picotls/picotlsvs/picotlsvs/ec_cert.pem @@ -0,0 +1,14 @@ +-----BEGIN CERTIFICATE----- +MIICITCCAcigAwIBAgIJAJpmLpw+2sHYMAkGByqGSM49BAEwQzELMAkGA1UEBhMC +VVMxCzAJBgNVBAgTAldBMRAwDgYDVQQHEwdTZWF0dGxlMRUwEwYDVQQKEwxQaWNv +VExTIFRlc3QwHhcNMTcwNzI1MDQyOTAyWhcNMTgwNzI1MDQyOTAyWjBDMQswCQYD +VQQGEwJVUzELMAkGA1UECBMCV0ExEDAOBgNVBAcTB1NlYXR0bGUxFTATBgNVBAoT +DFBpY29UTFMgVGVzdDBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABK3/SPaRAh80 +1BERnxzh1Fi1FZtYGPmbMPoQNpkPchxwSsJBcm+IwOh0xtK/a+xKqOFjpVo8i7SW +ARulK3XErOmjgaUwgaIwHQYDVR0OBBYEFA3LAgzzAyPVpIG0jsz1QSYQrMUgMHMG +A1UdIwRsMGqAFA3LAgzzAyPVpIG0jsz1QSYQrMUgoUekRTBDMQswCQYDVQQGEwJV +UzELMAkGA1UECBMCV0ExEDAOBgNVBAcTB1NlYXR0bGUxFTATBgNVBAoTDFBpY29U +TFMgVGVzdIIJAJpmLpw+2sHYMAwGA1UdEwQFMAMBAf8wCQYHKoZIzj0EAQNIADBF +AiAKr/C59Tfk+edPt6LBvNErf1x8HyD5mSmidjmMTznvQQIhALxOamTazSM0U0iL +4IUfSjOChw4W1DWIRPDjZm97HEpY +-----END CERTIFICATE----- diff --git a/web/server/h2o/libh2o/deps/picotls/picotlsvs/picotlsvs/ec_key.pem b/web/server/h2o/libh2o/deps/picotls/picotlsvs/picotlsvs/ec_key.pem new file mode 100644 index 00000000..29932c1c --- /dev/null +++ b/web/server/h2o/libh2o/deps/picotls/picotlsvs/picotlsvs/ec_key.pem @@ -0,0 +1,5 @@ +-----BEGIN PRIVATE KEY----- +MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg8rWCKftLG3r00UO8 +BKfR3+4jyiyyo9mz3UIDA+iATXyhRANCAASt/0j2kQIfNNQREZ8c4dRYtRWbWBj5 +mzD6EDaZD3IccErCQXJviMDodMbSv2vsSqjhY6VaPIu0lgEbpSt1xKzp +-----END PRIVATE KEY----- diff --git a/web/server/h2o/libh2o/deps/picotls/picotlsvs/picotlsvs/key-test-1.pem b/web/server/h2o/libh2o/deps/picotls/picotlsvs/picotlsvs/key-test-1.pem new file mode 100644 index 00000000..1fb5f17b --- /dev/null +++ b/web/server/h2o/libh2o/deps/picotls/picotlsvs/picotlsvs/key-test-1.pem @@ -0,0 +1,5 @@ +-----BEGIN PRIVATE KEY----- +MIGEAgEAMBAGByqGSM49AgEGBSuBBAAKBG0wawIBAQQgVcB/UNPxalR9zDYAjQIf +jojUDiQuGnSJrFEEzZPT/92hRANCAASc7UJtgnF/abqWM60T3XNJEzBv5ez9TdwK +H0M6xpM2q+53wmsN/eYLdgtjgBd3DBmHtPilCkiFICXyaA8z9LkJ +-----END PRIVATE KEY----- diff --git a/web/server/h2o/libh2o/deps/picotls/picotlsvs/picotlsvs/key-test-2.pem b/web/server/h2o/libh2o/deps/picotls/picotlsvs/picotlsvs/key-test-2.pem new file mode 100644 index 00000000..f4aeb5ef --- /dev/null +++ b/web/server/h2o/libh2o/deps/picotls/picotlsvs/picotlsvs/key-test-2.pem @@ -0,0 +1,9 @@ +-----BEGIN PRIVATE KEY----- +MIIBMAIBADCB0wYHKoZIzj0CATCBxwIBATAkBgcqhkjOPQEBAhkA//////////// +/////////v//////////MEsEGP////////////////////7//////////AQYIhI9 +wjlaBcqnQj2uzMlHYKfUYiVr1WkWAxUAxGloRDXes3jEtlypWR4qV2MFmi4EMQR9 +KXeBAMZaHaF4NxZYjc4ri0rujiKPGJY4qQ8iY3M3M0tJ3LZqbcj5l4rKdkipQ7AC +GQD///////////////96YtAxyD9ClPZA7BMCAQEEVTBTAgEBBBiKtwssqrxHY/gu +KDD4QgmyLDKaqBv2wEWhNAMyAAT5j6o+ojeB6jaFAfx4rtGf5hYbT1N6NnlAWiP1 ++bEWtTJiEVqnpeZN0m0SLybIGZY= +-----END PRIVATE KEY----- \ No newline at end of file diff --git a/web/server/h2o/libh2o/deps/picotls/picotlsvs/picotlsvs/key-test-3.pem b/web/server/h2o/libh2o/deps/picotls/picotlsvs/picotlsvs/key-test-3.pem new file mode 100644 index 00000000..08c9496a --- /dev/null +++ b/web/server/h2o/libh2o/deps/picotls/picotlsvs/picotlsvs/key-test-3.pem @@ -0,0 +1,5 @@ +-----BEGIN EC PRIVATE KEY----- +MHQCAQEEILNvumjK/H0ioec3gNnn07vM/yDUfwAlInWQYtTY+NpsoAcGBSuBBAAK +oUQDQgAEVw4JNyAuRNukW7+FFRLZW2Y8dNTAZ3SJp5AB+P+becKkbwtLLlO+PENe +7ZC02lGb4Sak2Wc2jBdsheCzfJOloQ== +-----END EC PRIVATE KEY----- diff --git a/web/server/h2o/libh2o/deps/picotls/picotlsvs/picotlsvs/key-test-4.pem b/web/server/h2o/libh2o/deps/picotls/picotlsvs/picotlsvs/key-test-4.pem new file mode 100644 index 00000000..4018db1c --- /dev/null +++ b/web/server/h2o/libh2o/deps/picotls/picotlsvs/picotlsvs/key-test-4.pem @@ -0,0 +1,5 @@ +-----BEGIN PRIVATE KEY----- +MIGEAgEAMBAGByqGSM49AgEGBSuBBAAKBG0wawIBAQQgocwnJPlQe7sRiRc0obuy +ddukwdOK73PgNnqZUIFm64WhRANCAAQ1FDasoi8+SmGUBtKW5brq9+gCiE/Ymz53 +BPUYN8AeHABM64AqWwX0oFCM027E4qRjGGjd7O+T+M/tXTJJR5p4 +-----END PRIVATE KEY----- diff --git a/web/server/h2o/libh2o/deps/picotls/picotlsvs/picotlsvs/key.pem b/web/server/h2o/libh2o/deps/picotls/picotlsvs/picotlsvs/key.pem new file mode 100644 index 00000000..8f86e717 --- /dev/null +++ b/web/server/h2o/libh2o/deps/picotls/picotlsvs/picotlsvs/key.pem @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQC5NLM3MiRmgrtz +dZd3uKIqaYFp/AjgHJMNQw1L6fZpfG2Z2mfONZ2wgN/DugZZ7tYMYEvxfBUiLtvc ++GyT0IErWDk8W8Rspv4xzM20vccyOQcr9/hu7bv9UBKB3JvQ8s0oiL1qjMrZJaD3 +RIJfqlIp1o71hobfUMz0pOrzUjNVandhs+2SSMTaeprs2kneZkAUnjtQDriIciIS +FjD6Xkdwa7SNjwo+bL60OTlZcinOsqF2Cg1BcSBCoTsIwlNNuwAnSUQ3A1lvhs6k +eBGpls7UNNemHK5QGtD6QHsA2tRUKF1suhpfumBfBiIZ/mR7CTdEYHaihLtW5IS+ +4lJeL543AgMBAAECggEARINOWPjfplxuY8P4iH1w4CevjDmEPwPTEnDfllmyoks5 +cFTvWcVT1FuYa5uBhftoi6OD9I1mdALJqvDrmbLkVdiJM97uxxLvrhSJdHdQHTAj +iwxshvzDMm5QqmGl8qIfawNKrwPudm4JIe/iGumzA28v63wcoLgPWeE4WVLrUoky +WUc4eOhdqgB1I1Ma/pOZGIMMF8kdmvqau7XSrc7u51wAQgf8Y+MF6E2WWwKLfd75 +oWlmyJtzY0zVQ+brHmRPMiwvWwtoahLS1rVvkLf62bWlUcVT4IEDNhd0Igftee7n +0G+GEpaVjL+FGdnzJ9EVsTH7CQ7fPS0E1fvm0BK7IQKBgQDvId7NHGUgkw2Ekdu0 +CXrSo52ZEDEFt0yyv1RYCWk+IWF3IOj2QIGQ5cR9fQPI0sKXU4poMgIbEv2NRnVY +JIQ11Z8tXQe9+Hk56MvhjQhni6WwmuoNTw6yGlWFMWZgkKauSNaQW0v+CdCDlG2o +I1Iuv4nT1sq9orT2uxQVr6PNqwKBgQDGRQ2p+9CQyFqjg8A39niLrqAH4nd4O5/H +Mc5orbLNAxEWH09MFZPl11+WTksVlhPcrvKczYUcQsVAW1MIB46VtRjyJ8wC+RE+ ++ayLR26PpPgUgfuz/dPytDdi2e3Y5vtZ6ZDwVfwBEUfYoC9TcunJWaIXIJpvyUJp +3sxJJF8tpQKBgQDUUiFtwnFz271b4NnO37/i+Iz8k2jDZ329E65CwJBmLuNID7to +sduYmLm+pdpPW/qUvAMfAo/mFBV2c4HK8hlFZ1f+wiQWo2CXb0BfEobM0SwbQ2De +0jv9HO6j5Tm+MZEdG+UOpVEyzOoLeiVm7X2RrlUk9whqGeZNT8vEeX+aIwKBgQCc +ueckME7cs9OaH8JpOmZtnBsaQHVJ0G/ryL4t1uhY0IzIHPXU4dWoQMhpivglVx3a +O1zCgF8xSMKdrdMDrN2UD7RpbvYAf5uXWUuASXXnDHOh2mH6FLJezwBdHoG6DFQx +7cRJht6OhXdykKT4ZQTSygysFXSe2sup3plDVAH8lQKBgECy9w2481N3RoET7Z0x +1RHQSLNduFBOekdBMmJzbQJm1r5G+j9iUrwESboi5ZwodpMT3DS+rXye6GmJhOKi +e+M3uATC+lsHnU3AInf/t3N8NvYS9AOIkWV/p/+IjzMPTyEJH2nUBUZA8f32bcnL +3qG4F2xvUiz0/vVrbQyJm/LQ +-----END PRIVATE KEY----- diff --git a/web/server/h2o/libh2o/deps/picotls/picotlsvs/picotlsvs/myec1.pem b/web/server/h2o/libh2o/deps/picotls/picotlsvs/picotlsvs/myec1.pem new file mode 100644 index 00000000..8a19bb09 --- /dev/null +++ b/web/server/h2o/libh2o/deps/picotls/picotlsvs/picotlsvs/myec1.pem @@ -0,0 +1,5 @@ +-----BEGIN EC PRIVATE KEY----- +MHQCAQEEIKHMJyT5UHu7EYkXNKG7snXbpMHTiu9z4DZ6mVCBZuuFoAcGBSuBBAAK +oUQDQgAENRQ2rKIvPkphlAbSluW66vfoAohP2Js+dwT1GDfAHhwATOuAKlsF9KBQ +jNNuxOKkYxho3ezvk/jP7V0ySUeaeA== +-----END EC PRIVATE KEY----- diff --git a/web/server/h2o/libh2o/deps/picotls/picotlsvs/picotlsvs/openssl.cnf b/web/server/h2o/libh2o/deps/picotls/picotlsvs/picotlsvs/openssl.cnf new file mode 100644 index 00000000..c96e8432 --- /dev/null +++ b/web/server/h2o/libh2o/deps/picotls/picotlsvs/picotlsvs/openssl.cnf @@ -0,0 +1,35 @@ +[ req ] +default_bits = 1024 +default_keyfile= privkey.pem +distinguished_name = req_distinguished_name + + +[ req_distinguished_name ] +countryName= US +countryName_min= 2 +countryName_max = 2 +stateOrProvinceName= Washington +localityName = Seattle +organizationName = Example +commonName = Localhost +commonName_max = 64 +emailAddress = localhost@example.com +emailAddress_max = 40 + + +[ alternate_names ] + +DNS.1 = example.com +DNS.2 = www.example.com +DNS.3 = mail.example.com +DNS.4 = ftp.example.com + +# Add these if you need them. But usually you don't want them or +# need them in production. You may need them for development. +# DNS.5 = localhost +# DNS.6 = localhost.localdomain +# DNS.7 = 127.0.0.1 + +# IPv6 localhost +# DNS.8 = ::1 + diff --git a/web/server/h2o/libh2o/deps/picotls/picotlsvs/picotlsvs/picotlsvs.c b/web/server/h2o/libh2o/deps/picotls/picotlsvs/picotlsvs/picotlsvs.c new file mode 100644 index 00000000..251b2909 --- /dev/null +++ b/web/server/h2o/libh2o/deps/picotls/picotlsvs/picotlsvs/picotlsvs.c @@ -0,0 +1,674 @@ +/* picotlsvs: test program for the TLS 1.3 library. */ +#include +#include +#include +#include "../picotls/wincompat.h" +#include "../../include/picotls.h" +#include "../../include/picotls/openssl.h" +#include "../../include/picotls/minicrypto.h" +#include "../../include/picotls/asn1.h" +#include "../../include/picotls/pembase64.h" + +void log_printf(void * ctx, const char * format, ...) +{ + va_list argptr; + va_start(argptr, format); + vfprintf(stderr, format, argptr); +} + +ptls_minicrypto_log_ctx_t log_ctx = { NULL, log_printf }; + +int ptls_export_secret(ptls_t *tls, void *output, size_t outlen, const char *label, ptls_iovec_t context_value, int is_early); + +/* + * Testing the Base64 and ASN1 verifiers. + * Start by loading the private key object, then do a mini fuzz test. + * The goal is to verify that the decoding returns something correct, + * even in presence of errors. + */ + +size_t ptls_minicrypto_asn1_decode_private_key( + ptls_asn1_pkcs8_private_key_t * pkey, + int * decode_error, ptls_minicrypto_log_ctx_t * log_ctx); + +int openPemTest(char const * filename) +{ + ptls_iovec_t buf = { 0 }; + size_t count = 1; + size_t fuzz_index = 0; + uint8_t original_byte = 0; + uint8_t fuzz_byte = 0xAA; + size_t byte_index = 0; + int decode_error; + + int ret = ptls_load_pem_objects(filename, "PRIVATE KEY", &buf, 1, &count); + + + if (ret == 0) + { + for (fuzz_index = 0; ret == 0 && fuzz_index < buf.len; fuzz_index++) + { + ptls_asn1_pkcs8_private_key_t pkey = { {0} }; + original_byte = buf.base[fuzz_index]; + decode_error = 0; + buf.base[fuzz_index] ^= fuzz_byte; + + pkey.vec.base = buf.base; + pkey.vec.len = buf.len; + + byte_index = ptls_minicrypto_asn1_decode_private_key( + &pkey, &decode_error, NULL); + + if (decode_error != 0) + { + if (decode_error == 1) + { + ret = -1; + } + } + + buf.base[fuzz_index] = original_byte; + } + } + + if (buf.base != NULL) + { + free(buf.base); + } + + return ret; +} + +/* + * Using the open ssl library to load the test certificate + */ + +X509* openPemFile(char* filename) +{ + + X509* cert = X509_new(); + BIO* bio_cert = BIO_new_file(filename, "rb"); + PEM_read_bio_X509(bio_cert, &cert, NULL, NULL); + return cert; +} + +int get_certificates(char * pem_fname, ptls_iovec_t ** list, int * nb_certs) +{ + int ret = 0; + size_t count = 0; + X509 *cert; + static ptls_iovec_t certs[16]; + + *nb_certs = 0; + *list = NULL; + + cert = openPemFile(pem_fname); + + if (cert == NULL) + { + fprintf(stderr, "Could not read cert in %s\n", pem_fname); + ret = -1; + } + else + { + ptls_iovec_t *dst = certs + count++; + dst->len = i2d_X509(cert, &dst->base); + } + + *nb_certs = (int) count; + *list = certs; + + return ret; +} + +void SetSignCertificate(char * keypem, ptls_context_t * ctx) +{ + static ptls_openssl_sign_certificate_t signer; + + EVP_PKEY *pkey = EVP_PKEY_new(); + BIO* bio_key = BIO_new_file(keypem, "rb"); + PEM_read_bio_PrivateKey(bio_key, &pkey, NULL, NULL); + ptls_openssl_init_sign_certificate(&signer, pkey); + EVP_PKEY_free(pkey); + ctx->sign_certificate = &signer.super; +} + +int handshake_init(ptls_t * tls, ptls_buffer_t * sendbuf, ptls_handshake_properties_t * ph_prop) +{ + size_t inlen = 0, roff = 0; + + ptls_buffer_init(sendbuf, "", 0); + int ret = ptls_handshake(tls, sendbuf, NULL, NULL, ph_prop); + + return ret; +} + + +int handshake_progress(ptls_t * tls, ptls_buffer_t * sendbuf, ptls_buffer_t * recvbuf, ptls_handshake_properties_t * ph_prop) +{ + size_t inlen = 0, roff = 0; + int ret = 0; + + ptls_buffer_init(sendbuf, "", 0); + + /* Provide the data */ + while (roff < recvbuf->off && (ret == 0 || ret == PTLS_ERROR_IN_PROGRESS)) + { + inlen = recvbuf->off - roff; + ret = ptls_handshake(tls, sendbuf, recvbuf->base + roff, &inlen, ph_prop); + roff += inlen; + } + + if (roff < recvbuf->off) + { + // Could not consume all the data. This is bad. + fprintf(stderr, "Could only process %d bytes out of %d\n", (int) roff, (int) recvbuf->off); + } + ptls_buffer_dispose(recvbuf); + + return ret; +} + +/* + Verify the secret extraction functionality + at the end of the handshake. + */ + +int extract_1rtt_secret( + ptls_t *tls, const char *label, + ptls_cipher_suite_t ** cipher, + uint8_t * secret, size_t secret_max) +{ + int ret = 0; + *cipher = ptls_get_cipher(tls); + + if (*cipher == NULL) + { + ret = -1; + } + else if ((*cipher)->hash->digest_size > secret_max) + { + ret = -1; + } + else + { + ret = ptls_export_secret(tls, secret, (*cipher)->hash->digest_size, + label, ptls_iovec_init(NULL, 0), 1); + } + + return 0; +} + +int verify_1rtt_secret_extraction(ptls_t *tls_client, ptls_t *tls_server) +{ + int ret = 0; + ptls_cipher_suite_t * cipher_client; + ptls_cipher_suite_t * cipher_server; + uint8_t secret_client[64]; + uint8_t secret_server[64]; + char const * label = "This is just a test"; + + ret = extract_1rtt_secret(tls_client, label, &cipher_client, + secret_client, sizeof(secret_client)); + + if (ret != 0) + { + fprintf(stderr, "Cannot extract client 1RTT secret, ret=%d\n", ret); + } + else + { + ret = extract_1rtt_secret(tls_server, label, &cipher_server, + secret_server, sizeof(secret_server)); + if (ret != 0) + { + fprintf(stderr, "Cannot extract client 1RTT secret, ret=%d\n", ret); + } + } + + if (ret == 0) + { + if (strcmp(cipher_client->aead->name, cipher_server->aead->name) != 0) + { + fprintf(stderr, "AEAD differ, client:%s, server:%s\n", + cipher_client->aead->name, cipher_server->aead->name); + ret = -1; + } + else if (cipher_client->hash->digest_size != cipher_server->hash->digest_size) + { + fprintf(stderr, "Key length differ, client:%d, server:%d\n", + (int) cipher_client->hash->digest_size, (int) cipher_server->hash->digest_size); + ret = -1; + } + else if (memcmp(secret_client, secret_server, cipher_client->hash->digest_size) != 0) + { + fprintf(stderr, "Key of client and server differ!\n"); + ret = -1; + } + } + + return ret; +} + +int openssl_init_test_client(ptls_context_t *ctx_client) +{ + int ret = 0; + static ptls_openssl_verify_certificate_t verifier; + + /* Initialize the client context */ + memset(ctx_client, 0, sizeof(ptls_context_t)); + ctx_client->random_bytes = ptls_openssl_random_bytes; + ctx_client->get_time = &ptls_get_time; + ctx_client->key_exchanges = ptls_openssl_key_exchanges; + ctx_client->cipher_suites = ptls_openssl_cipher_suites; + ptls_openssl_init_verify_certificate(&verifier, NULL); + ctx_client->verify_certificate = &verifier.super; + + return ret; +} + +int openssl_init_test_server(ptls_context_t *ctx_server, char * key_file, char * cert_file) +{ + int ret = 0; + /* Initialize the server context */ + memset(ctx_server, 0, sizeof(ptls_context_t)); + ctx_server->random_bytes = ptls_openssl_random_bytes; + ctx_server->get_time = &ptls_get_time; + ctx_server->key_exchanges = ptls_openssl_key_exchanges; + ctx_server->cipher_suites = ptls_openssl_cipher_suites; + + ret = ptls_load_certificates(ctx_server, cert_file); + if (ret != 0) + { + fprintf(stderr, "Could not read the server certificates\n"); + } + else + { + SetSignCertificate(key_file, ctx_server); + } + + return ret; +} + +int minicrypto_init_test_client(ptls_context_t *ctx_client) +{ + int ret = 0; + // static ptls_openssl_verify_certificate_t verifier; + + /* Initialize the client context */ + memset(ctx_client, 0, sizeof(ptls_context_t)); + ctx_client->random_bytes = ptls_minicrypto_random_bytes; + ctx_client->get_time = &ptls_get_time; + ctx_client->key_exchanges = ptls_minicrypto_key_exchanges; + ctx_client->cipher_suites = ptls_minicrypto_cipher_suites; + // ptls_openssl_init_verify_certificate(&verifier, NULL); + ctx_client->verify_certificate = NULL; // &verifier.super; + + return ret; +} + +int minicrypto_init_test_server(ptls_context_t *ctx_server, char * key_file, char * cert_file) +{ + int ret = 0; + + /* Initialize the server context */ + memset(ctx_server, 0, sizeof(ptls_context_t)); + ctx_server->random_bytes = ptls_minicrypto_random_bytes; + ctx_server->get_time = &ptls_get_time; + ctx_server->key_exchanges = ptls_minicrypto_key_exchanges; + ctx_server->cipher_suites = ptls_minicrypto_cipher_suites; + + ret = ptls_load_certificates(ctx_server, cert_file); + + if (ret != 0) + { + fprintf(stderr, "Could not read the server certificates\n"); + } + else + { + ret = ptls_minicrypto_load_private_key(ctx_server, key_file); + } + + return ret; +} + +#define PICOTLS_VS_TEST_EXTENSION 1234 +static uint8_t testExtensionClient[] = { 1, 2, 3 }; +static uint8_t testExtensionServer[] = { 1, 2, 3, 4, 5, 6, 7, 8 }; +char const test_sni[] = "picotls.example.com"; +char const test_alpn[] = "picotls"; +static const ptls_iovec_t proposed_alpn[] = { + { (uint8_t *) "grease", 6}, + { (uint8_t *)test_alpn, sizeof(test_alpn) -1 } +}; + + +struct st_picotls_vs_test_context_t +{ + int client_mode; + size_t received_extension_length; + uint8_t received_extension[16]; + ptls_raw_extension_t ext[2]; + + ptls_handshake_properties_t handshake_properties; + +}; + +int collect_test_extension(ptls_t *tls, struct st_ptls_handshake_properties_t *properties, uint16_t type) +{ + return type == PICOTLS_VS_TEST_EXTENSION; +} + +void set_test_extensions(ptls_raw_extension_t ext[2], uint8_t * data, size_t len) +{ + ext[0].type = PICOTLS_VS_TEST_EXTENSION; + ext[0].data.base = data; + ext[0].data.len = len; + ext[1].type = 0xFFFF; + ext[1].data.base = NULL; + ext[1].data.len = 0; +} + +int collected_test_extensions(ptls_t *tls, ptls_handshake_properties_t *properties, + ptls_raw_extension_t *slots) +{ + struct st_picotls_vs_test_context_t * ctx = (struct st_picotls_vs_test_context_t *) + ((char *)properties - offsetof(struct st_picotls_vs_test_context_t, handshake_properties)); + + if (slots[0].type == PICOTLS_VS_TEST_EXTENSION && slots[1].type == 0xFFFF) + { + ctx->received_extension_length = slots[0].data.len; + memcpy(ctx->received_extension, slots[0].data.base, + (slots[0].data.len < sizeof(ctx->received_extension)) ? + slots[0].data.len : sizeof(ctx->received_extension)); + + if (ctx->client_mode == 0) + { + properties->additional_extensions = ctx->ext; + set_test_extensions(ctx->ext, testExtensionServer, sizeof(testExtensionServer)); + } + } + + return 0; +} + +int client_hello_call_back(ptls_on_client_hello_t * on_hello_cb_ctx, + ptls_t *tls, ptls_iovec_t server_name, const ptls_iovec_t *negotiated_protocols, + size_t num_negotiated_protocols, const uint16_t *signature_algorithms, size_t num_signature_algorithms) +{ + for (size_t i = 0; i < num_negotiated_protocols; i++) + { + if (negotiated_protocols[i].len == sizeof(test_alpn) - 1 && + memcmp(negotiated_protocols[i].base, test_alpn, sizeof(test_alpn) - 1) == 0) + { + ptls_set_negotiated_protocol(tls, test_alpn, sizeof(test_alpn) - 1); + break; + } + } + return 0; +} + +void set_handshake_context(struct st_picotls_vs_test_context_t * ctx, int client_mode) +{ + memset(ctx, 0, sizeof(struct st_picotls_vs_test_context_t)); + + if ((ctx->client_mode = client_mode) != 0) + { + ctx->handshake_properties.client.negotiated_protocols.list = proposed_alpn; + ctx->handshake_properties.client.negotiated_protocols.count = + sizeof(proposed_alpn) / sizeof(ptls_iovec_t); + + ctx->handshake_properties.additional_extensions = ctx->ext; + set_test_extensions(ctx->ext, testExtensionClient, sizeof(testExtensionClient)); + } + + ctx->handshake_properties.collect_extension = collect_test_extension; + ctx->handshake_properties.collected_extensions = collected_test_extensions; +} + +int verify_handshake_extension(struct st_picotls_vs_test_context_t * app_ctx_client, + struct st_picotls_vs_test_context_t *app_ctx_server) +{ + int ret = 0; + + if (app_ctx_server->received_extension_length == 0) + { + fprintf(stderr, "Server did not receive the client extension.\n"); + ret = -1; + } + else if (app_ctx_server->received_extension_length != sizeof(testExtensionClient) || + memcmp(app_ctx_server->received_extension, testExtensionClient, sizeof(testExtensionClient))) + { + fprintf(stderr, "Server did not correctly receive the client extension.\n"); + ret = -1; + } + else if (app_ctx_client->received_extension_length == 0) + { + fprintf(stderr, "Client did not receive the server extension.\n"); + ret = -1; + } + else if (app_ctx_client->received_extension_length != sizeof(testExtensionServer) || + memcmp(app_ctx_client->received_extension, testExtensionServer, sizeof(testExtensionServer))) + { + fprintf(stderr, "Client did not correctly receive the server extension.\n"); + ret = -1; + } + + return ret; +} + +int ptls_memory_loopback_test(int openssl_client, int openssl_server, char * key_file, char * cert_file) +{ + ptls_context_t ctx_client, ctx_server; + ptls_t *tls_client = NULL, *tls_server = NULL; + int ret = 0; + ptls_buffer_t client_buf, server_buf; + struct st_picotls_vs_test_context_t app_ctx_client, app_ctx_server; + ptls_on_client_hello_t client_hello_cb; + + + /* init the contexts */ + if (ret == 0 && openssl_client) + { + ret = openssl_init_test_client(&ctx_client); + } + else + { + ret = minicrypto_init_test_client(&ctx_client); + } + + if (ret == 0 && openssl_server) + { + ret = openssl_init_test_server(&ctx_server, key_file, cert_file); + } + else + { + ret = minicrypto_init_test_server(&ctx_server, key_file, cert_file); + } + + /* Create the connections */ + if (ret == 0) + { + tls_client = ptls_new(&ctx_client, 0); + tls_server = ptls_new(&ctx_server, 1); + + if (tls_server == NULL || tls_client == NULL) + { + fprintf(stderr, "Could not create the TLS connection objects\n"); + ret = -1; + } + } + + /* Perform the handshake */ + if (ret == 0) + { + int nb_rounds = 0; + + set_handshake_context(&app_ctx_client, 1); + set_handshake_context(&app_ctx_server, 0); + + client_hello_cb.cb = client_hello_call_back; + ctx_server.on_client_hello = &client_hello_cb; + + ptls_set_server_name(tls_client, test_sni, sizeof(test_sni) - 1); + + ret = handshake_init(tls_client, &client_buf, + &app_ctx_client.handshake_properties); + printf("First message from client, ret = %d, %d bytes.\n", ret, (int) client_buf.off); + + while ((ret == 0 || ret == PTLS_ERROR_IN_PROGRESS) && client_buf.off > 0 && nb_rounds < 12) + { + nb_rounds++; + + ret = handshake_progress(tls_server, &server_buf, &client_buf, + &app_ctx_server.handshake_properties); + app_ctx_server.handshake_properties.additional_extensions = NULL; + + printf("Message from server, ret = %d, %d bytes.\n", ret, (int) server_buf.off); + + if ((ret == 0 || ret == PTLS_ERROR_IN_PROGRESS) && server_buf.off > 0) + { + app_ctx_client.handshake_properties.additional_extensions = NULL; + + ret = handshake_progress(tls_client, &client_buf, &server_buf, + &app_ctx_client.handshake_properties); + + printf("Message from client, ret = %d, %d bytes.\n", ret, (int) client_buf.off); + } + } + + printf("Exit handshake after %d rounds, ret = %d.\n", nb_rounds, ret); + + if (ret == 0) + { + ret = verify_1rtt_secret_extraction(tls_client, tls_server); + + if (ret == 0) + { + printf("Key extracted and matches!\n"); + } + } + + if (ret == 0) + { + ret = verify_handshake_extension(&app_ctx_client, &app_ctx_server); + + if (ret == 0) + { + printf("Extensions received and match!\n"); + } + } + + if (ret == 0) + { + const char * sni_received = ptls_get_server_name(tls_server); + + if (sni_received == NULL) + { + fprintf(stderr, "Server did not receive the SNI set by the client\n"); + ret = -1; + } + else if (strcmp(sni_received, test_sni) != 0) + { + fprintf(stderr, "Server receives SNI: <%s>, does not match <%s>\n", + sni_received, test_sni); + ret = -1; + } + } + + if (ret == 0) + { + const char * alpn_received = ptls_get_negotiated_protocol(tls_server); + + if (alpn_received == NULL) + { + fprintf(stderr, "Server did not negotiate ALPN\n"); + ret = -1; + } + else if (strcmp(alpn_received, test_alpn) != 0) + { + fprintf(stderr, "Server receives ALPN: <%s>, does not match <%s>\n", + alpn_received, test_alpn); + ret = -1; + } + } + + if (ret == 0) + { + printf("SNI and ALPN match.\n"); + } + } + + if (tls_client != NULL) + { + ptls_free(tls_client); + } + + if (tls_server != NULL) + { + ptls_free(tls_server); + } + + if (openssl_server == 0 && ctx_server.sign_certificate != NULL) + { + free(ctx_server.sign_certificate); + } + + return ret; +} + +static char const * test_keys[] = { + "key.pem", + "ec_key.pem", + "key-test-1.pem", + "key-test-2.pem", + "key-test-4.pem" +}; + +static const size_t nb_test_keys = sizeof(test_keys) / sizeof(char const *); + +int main() +{ + int ret = 0; + +#if 1 + /* TODO: move to ASN.1 unit test*/ + + for (size_t i = 0; ret == 0 && i < nb_test_keys; i++) + { + ret = openPemTest(test_keys[i]); + } +#endif + + if (ret == 0) + { + printf("\nStarting the RSA test with OpenSSL\n"); + ret = ptls_memory_loopback_test(1, 1, "key.pem", "cert.pem"); + } + + if (ret == 0) + { + printf("\nStarting the P256R1 test with OpenSSL\n"); + ret = ptls_memory_loopback_test(1, 1, "ec_key.pem", "ec_cert.pem"); + } + + if (ret == 0) + { + printf("\nStarting the P256R1 test with OpenSSL server and Minicrypto client\n"); + ret = ptls_memory_loopback_test(0, 1, "ec_key.pem", "ec_cert.pem"); + } + + if (ret == 0) + { + printf("\nStarting the P256R1 test with Minicrypto\n"); + ret = ptls_memory_loopback_test(0, 0, "ec_key.pem", "ec_cert.pem"); + } + + if (ret == 0) + { + printf("\nStarting the P256R1 test with Minicrypto server and OpenSSL client\n"); + ret = ptls_memory_loopback_test(1, 0, "ec_key.pem", "ec_cert.pem"); + } + + return ret; +} + diff --git a/web/server/h2o/libh2o/deps/picotls/picotlsvs/picotlsvs/picotlsvs.vcxproj b/web/server/h2o/libh2o/deps/picotls/picotlsvs/picotlsvs/picotlsvs.vcxproj new file mode 100644 index 00000000..792cf302 --- /dev/null +++ b/web/server/h2o/libh2o/deps/picotls/picotlsvs/picotlsvs/picotlsvs.vcxproj @@ -0,0 +1,161 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + 15.0 + {D0265367-FCCF-47A4-95FD-C33BECAB3486} + Win32Proj + picotlsvs + 10.0.14393.0 + + + + Application + true + v141 + Unicode + + + Application + false + v141 + true + Unicode + + + Application + true + v141 + Unicode + + + Application + false + v141 + true + Unicode + + + + + + + + + + + + + + + + + + + + + true + + + true + + + false + + + false + + + + NotUsing + Level3 + Disabled + WIN32;_DEBUG;_CONSOLE;_WINDOWS;%(PreprocessorDefinitions) + $(OPENSSLDIR)\include;$(ProjectDir)..\..\include;%(AdditionalIncludeDirectories) + + + Console + $(OPENSSLDIR);$(OutDir) + picotls.lib;libcrypto.lib;libssl.lib;microecc.lib;cifra.lib;%(AdditionalDependencies) + + + + + NotUsing + Level3 + Disabled + _DEBUG;_CONSOLE;_WINDOWS;%(PreprocessorDefinitions) + $(ProjectDir)..\..\include;$(OPENSSL64DIR)\include;%(AdditionalIncludeDirectories) + + + Console + $(OPENSSL64DIR);$(OutDir);%(AdditionalLibraryDirectories) + picotls.lib;cifra.lib;microecc.lib;libcrypto.lib;%(AdditionalDependencies) + + + + + Level3 + NotUsing + MaxSpeed + true + true + WIN32;NDEBUG;_CONSOLE;_WINDOWS;%(PreprocessorDefinitions) + $(OPENSSLDIR)\include;$(ProjectDir)..\..\include;%(AdditionalIncludeDirectories) + + + Console + true + true + $(OPENSSLDIR);$(OutDir) + picotls.lib;cifra.lib;microecc.lib;libcrypto.lib;%(AdditionalDependencies) + + + + + Level3 + NotUsing + MaxSpeed + true + true + NDEBUG;_CONSOLE;_WINDOWS;%(PreprocessorDefinitions) + $(ProjectDir)..\..\include;$(OPENSSL64DIR)\include;%(AdditionalIncludeDirectories) + + + Console + true + true + $(OPENSSL64DIR);$(OutDir);%(AdditionalLibraryDirectories) + picotls.lib;cifra.lib;microecc.lib;libcrypto.lib;%(AdditionalDependencies) + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/web/server/h2o/libh2o/deps/picotls/picotlsvs/picotlsvs/picotlsvs.vcxproj.filters b/web/server/h2o/libh2o/deps/picotls/picotlsvs/picotlsvs/picotlsvs.vcxproj.filters new file mode 100644 index 00000000..a52d6d47 --- /dev/null +++ b/web/server/h2o/libh2o/deps/picotls/picotlsvs/picotlsvs/picotlsvs.vcxproj.filters @@ -0,0 +1,30 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + + + + Header Files + + + + + Source Files + + + \ No newline at end of file diff --git a/web/server/h2o/libh2o/deps/picotls/picotlsvs/picotlsvs/picotlsvs.vcxproj.user b/web/server/h2o/libh2o/deps/picotls/picotlsvs/picotlsvs/picotlsvs.vcxproj.user new file mode 100644 index 00000000..be250787 --- /dev/null +++ b/web/server/h2o/libh2o/deps/picotls/picotlsvs/picotlsvs/picotlsvs.vcxproj.user @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/web/server/h2o/libh2o/deps/picotls/picotlsvs/picotlsvs/targetver.h b/web/server/h2o/libh2o/deps/picotls/picotlsvs/picotlsvs/targetver.h new file mode 100644 index 00000000..87c0086d --- /dev/null +++ b/web/server/h2o/libh2o/deps/picotls/picotlsvs/picotlsvs/targetver.h @@ -0,0 +1,8 @@ +#pragma once + +// Including SDKDDKVer.h defines the highest available Windows platform. + +// If you wish to build your application for a previous Windows platform, include WinSDKVer.h and +// set the _WIN32_WINNT macro to the platform you wish to support before including SDKDDKVer.h. + +#include diff --git a/web/server/h2o/libh2o/deps/picotls/picotlsvs/testopenssl/testopenssl.vcxproj b/web/server/h2o/libh2o/deps/picotls/picotlsvs/testopenssl/testopenssl.vcxproj new file mode 100644 index 00000000..f5bf9ba2 --- /dev/null +++ b/web/server/h2o/libh2o/deps/picotls/picotlsvs/testopenssl/testopenssl.vcxproj @@ -0,0 +1,168 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + 15.0 + {8750EE3B-9440-48BF-8D83-7274E94B06A7} + Win32Proj + testopenssl + 10.0.14393.0 + + + + Application + true + v141 + Unicode + + + Application + false + v141 + true + Unicode + + + Application + true + v141 + Unicode + + + Application + false + v141 + true + Unicode + + + + + + + + + + + + + + + + + + + + + true + + + true + + + false + + + false + + + + + + Level3 + Disabled + WIN32;_DEBUG;_CONSOLE;_WINDOWS;%(PreprocessorDefinitions) + $(ProjectDir)..\picotls;$(ProjectDir)..\..\include;$(ProjectDir)\..\..\deps\cifra\src;$(ProjectDir)\..\..\deps\cifra\src\ext;$(ProjectDir)\..\..\deps\micro-ecc;$(OPENSSLDIR)\include;%(AdditionalIncludeDirectories) + + + Console + $(OPENSSLDIR);$(OutDir) + picotls.lib;cifra.lib;microecc.lib;libcrypto.lib;%(AdditionalDependencies) + + + + + + + Level3 + Disabled + _DEBUG;_CONSOLE;_WINDOWS;%(PreprocessorDefinitions) + $(ProjectDir)..\picotls;$(ProjectDir)..\..\include;$(ProjectDir)\..\..\deps\cifra\src;$(ProjectDir)\..\..\deps\cifra\src\ext;$(ProjectDir)\..\..\deps\micro-ecc;$(OPENSSL64DIR)\include;%(AdditionalIncludeDirectories) + + + Console + $(OPENSSL64DIR);$(OutDir);%(AdditionalLibraryDirectories) + picotls.lib;cifra.lib;microecc.lib;libcrypto.lib;%(AdditionalDependencies) + + + + + Level3 + + + MaxSpeed + true + true + WIN32;NDEBUG;_CONSOLE;_WINDOWS;%(PreprocessorDefinitions) + $(ProjectDir)..\picotls;$(ProjectDir)..\..\include;$(ProjectDir)\..\..\deps\cifra\src;$(ProjectDir)\..\..\deps\cifra\src\ext;$(ProjectDir)\..\..\deps\micro-ecc;$(OPENSSLDIR)\include;%(AdditionalIncludeDirectories) + + + Console + true + true + $(OPENSSLDIR);$(OutDir) + picotls.lib;cifra.lib;microecc.lib;libcrypto.lib;%(AdditionalDependencies) + + + + + Level3 + + + MaxSpeed + true + true + NDEBUG;_CONSOLE;_WINDOWS;%(PreprocessorDefinitions) + $(ProjectDir)..\picotls;$(ProjectDir)..\..\include;$(ProjectDir)\..\..\deps\cifra\src;$(ProjectDir)\..\..\deps\cifra\src\ext;$(ProjectDir)\..\..\deps\micro-ecc;$(OPENSSL64DIR)\include;%(AdditionalIncludeDirectories) + + + Console + true + true + $(OPENSSL64DIR);$(OutDir);%(AdditionalLibraryDirectories) + picotls.lib;cifra.lib;microecc.lib;libcrypto.lib;%(AdditionalDependencies) + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/web/server/h2o/libh2o/deps/picotls/picotlsvs/testopenssl/testopenssl.vcxproj.filters b/web/server/h2o/libh2o/deps/picotls/picotlsvs/testopenssl/testopenssl.vcxproj.filters new file mode 100644 index 00000000..b6ccd2fb --- /dev/null +++ b/web/server/h2o/libh2o/deps/picotls/picotlsvs/testopenssl/testopenssl.vcxproj.filters @@ -0,0 +1,41 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + Source Files + + + Source Files + + + Header Files + + + + + Header Files + + + + + Header Files + + + Header Files + + + \ No newline at end of file diff --git a/web/server/h2o/libh2o/deps/picotls/t/cli.c b/web/server/h2o/libh2o/deps/picotls/t/cli.c new file mode 100644 index 00000000..fc734999 --- /dev/null +++ b/web/server/h2o/libh2o/deps/picotls/t/cli.c @@ -0,0 +1,392 @@ +/* + * Copyright (c) 2016 DeNA Co., Ltd., Kazuho Oku + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ +#ifndef _XOPEN_SOURCE +#define _XOPEN_SOURCE 700 /* required for glibc to use getaddrinfo, etc. */ +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "picotls.h" +#include "picotls/openssl.h" +#include "util.h" + +static void shift_buffer(ptls_buffer_t *buf, size_t delta) +{ + if (delta != 0) { + assert(delta <= buf->off); + if (delta != buf->off) + memmove(buf->base, buf->base + delta, buf->off - delta); + buf->off -= delta; + } +} + +static int handle_connection(int sockfd, ptls_context_t *ctx, const char *server_name, const char *input_file, + ptls_handshake_properties_t *hsprop) +{ + ptls_t *tls = ptls_new(ctx, server_name == NULL); + ptls_buffer_t rbuf, encbuf, ptbuf; + char bytebuf[16384]; + enum { IN_HANDSHAKE, IN_1RTT, IN_SHUTDOWN } state = IN_HANDSHAKE; + int inputfd = 0, ret = 0; + size_t early_bytes_sent = 0; + ssize_t ioret; + + ptls_buffer_init(&rbuf, "", 0); + ptls_buffer_init(&encbuf, "", 0); + ptls_buffer_init(&ptbuf, "", 0); + + fcntl(sockfd, F_SETFL, O_NONBLOCK); + + if (input_file != NULL) { + if ((inputfd = open(input_file, O_RDONLY)) == -1) { + fprintf(stderr, "failed to open file:%s:%s\n", input_file, strerror(errno)); + ret = 1; + goto Exit; + } + } + if (server_name != NULL) { + ptls_set_server_name(tls, server_name, 0); + if ((ret = ptls_handshake(tls, &encbuf, NULL, NULL, hsprop)) != PTLS_ERROR_IN_PROGRESS) { + fprintf(stderr, "ptls_handshake:%d\n", ret); + ret = 1; + goto Exit; + } + } + + while (1) { + /* check if data is available */ + fd_set readfds, writefds, exceptfds; + int maxfd = 0; + struct timeval timeout; + do { + FD_ZERO(&readfds); + FD_ZERO(&writefds); + FD_ZERO(&exceptfds); + FD_SET(sockfd, &readfds); + if (encbuf.off != 0) + FD_SET(sockfd, &writefds); + FD_SET(sockfd, &exceptfds); + maxfd = sockfd + 1; + if (inputfd != -1) { + FD_SET(inputfd, &readfds); + FD_SET(inputfd, &exceptfds); + if (maxfd <= inputfd) + maxfd = inputfd + 1; + } + timeout.tv_sec = encbuf.off != 0 ? 0 : 3600; + timeout.tv_usec = 0; + } while (select(maxfd, &readfds, &writefds, &exceptfds, &timeout) == -1); + + /* consume incoming messages */ + if (FD_ISSET(sockfd, &readfds) || FD_ISSET(sockfd, &exceptfds)) { + size_t off = 0, leftlen; + while ((ioret = read(sockfd, bytebuf, sizeof(bytebuf))) == -1 && errno == EINTR) + ; + if (ioret == -1 && (errno == EWOULDBLOCK || errno == EAGAIN)) { + /* no data */ + ioret = 0; + } else if (ioret <= 0) { + goto Exit; + } + while ((leftlen = ioret - off) != 0) { + if (state == IN_HANDSHAKE) { + if ((ret = ptls_handshake(tls, &encbuf, bytebuf + off, &leftlen, hsprop)) == 0) { + state = IN_1RTT; + /* release data sent as early-data, if server accepted it */ + if (hsprop->client.early_data_accepted_by_peer) + shift_buffer(&ptbuf, early_bytes_sent); + if (ptbuf.off != 0) { + if ((ret = ptls_send(tls, &encbuf, ptbuf.base, ptbuf.off)) != 0) { + fprintf(stderr, "ptls_send(1rtt):%d\n", ret); + goto Exit; + } + ptbuf.off = 0; + } + } else if (ret == PTLS_ERROR_IN_PROGRESS) { + /* ok */ + } else { + fprintf(stderr, "ptls_handshake:%d\n", ret); + goto Exit; + } + } else { + if ((ret = ptls_receive(tls, &rbuf, bytebuf + off, &leftlen)) == 0) { + if (rbuf.off != 0) { + write(1, rbuf.base, rbuf.off); + rbuf.off = 0; + } + } else if (ret == PTLS_ERROR_IN_PROGRESS) { + /* ok */ + } else { + fprintf(stderr, "ptls_receive:%d\n", ret); + goto Exit; + } + } + off += leftlen; + } + } + + /* read input (and send if possible) */ + if (inputfd != -1 && (FD_ISSET(inputfd, &readfds) || FD_ISSET(inputfd, &exceptfds))) { + while ((ioret = read(inputfd, bytebuf, sizeof(bytebuf))) == -1 && errno == EINTR) + ; + if (ioret > 0) { + ptls_buffer_pushv(&ptbuf, bytebuf, ioret); + if (state == IN_HANDSHAKE) { + size_t send_amount = 0; + if (hsprop->client.max_early_data_size != NULL) { + size_t max_can_be_sent = *hsprop->client.max_early_data_size; + if (max_can_be_sent > ptbuf.off) + max_can_be_sent = ptbuf.off; + send_amount = max_can_be_sent - early_bytes_sent; + } + if (send_amount != 0) { + if ((ret = ptls_send(tls, &encbuf, ptbuf.base, send_amount)) != 0) { + fprintf(stderr, "ptls_send(early_data):%d\n", ret); + goto Exit; + } + early_bytes_sent += send_amount; + } + } else { + if ((ret = ptls_send(tls, &encbuf, bytebuf, ioret)) != 0) { + fprintf(stderr, "ptls_send(1rtt):%d\n", ret); + goto Exit; + } + ptbuf.off = 0; + } + } else { + /* closed */ + if (input_file != NULL) + close(inputfd); + inputfd = -1; + } + } + + /* send any data */ + if (encbuf.off != 0) { + while ((ioret = write(sockfd, encbuf.base, encbuf.off)) == -1 && errno == EINTR) + ; + if (ioret == -1 && (errno == EWOULDBLOCK || errno == EAGAIN)) { + /* no data */ + } else if (ioret <= 0) { + goto Exit; + } else { + shift_buffer(&encbuf, ioret); + } + } + + /* close the sender side when necessary */ + if (state == IN_1RTT && inputfd == -1) { + /* FIXME send close_alert */ + shutdown(sockfd, SHUT_WR); + state = IN_SHUTDOWN; + } + } + +Exit: + if (sockfd != -1) + close(sockfd); + if (input_file != NULL && inputfd != -1) + close(inputfd); + ptls_buffer_dispose(&rbuf); + ptls_buffer_dispose(&encbuf); + ptls_buffer_dispose(&ptbuf); + ptls_free(tls); + return ret != 0; +} + +static int run_server(struct sockaddr *sa, socklen_t salen, ptls_context_t *ctx, const char *input_file, + ptls_handshake_properties_t *hsprop) +{ + int listen_fd, conn_fd, on = 1; + + if ((listen_fd = socket(sa->sa_family, SOCK_STREAM, 0)) == -1) { + perror("socket(2) failed"); + return 1; + } + if (setsockopt(listen_fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) != 0) { + perror("setsockopt(SO_REUSEADDR) failed"); + return 1; + } + if (bind(listen_fd, sa, salen) != 0) { + perror("bind(2) failed"); + return 1; + } + if (listen(listen_fd, SOMAXCONN) != 0) { + perror("listen(2) failed"); + return 1; + } + + while (1) { + if ((conn_fd = accept(listen_fd, NULL, 0)) != -1) + handle_connection(conn_fd, ctx, NULL, input_file, hsprop); + } + + return 0; +} + +static int run_client(struct sockaddr *sa, socklen_t salen, ptls_context_t *ctx, const char *server_name, const char *input_file, + ptls_handshake_properties_t *hsprop) +{ + int fd; + + if ((fd = socket(sa->sa_family, SOCK_STREAM, 0)) == 1) { + perror("socket(2) failed"); + return 1; + } + if (connect(fd, sa, salen) != 0) { + perror("connect(2) failed"); + return 1; + } + + return handle_connection(fd, ctx, server_name, input_file, hsprop); +} + +static void usage(const char *cmd) +{ + printf("Usage: %s [options] host port\n" + "\n" + "Options:\n" + " -4 force IPv4\n" + " -6 force IPv6\n" + " -c certificate-file\n" + " -i file a file to read from and send to the peer (default: stdin)\n" + " -k key-file specifies the credentials to be used for running the\n" + " server. If omitted, the command runs as a client.\n" + " -l log-file file to log traffic secrets\n" + " -n negotiates the key exchange method (i.e. wait for HRR)\n" + " -s session-file file to read/write the session ticket\n" + " -S require public key exchange when resuming a session\n" + " -e when resuming a session, send first 8,192 bytes of input\n" + " as early data\n" + " -v verify peer using the default certificates\n" + " -h print this help\n" + "\n", + cmd); +} + +int main(int argc, char **argv) +{ + ERR_load_crypto_strings(); + OpenSSL_add_all_algorithms(); +#if !defined(OPENSSL_NO_ENGINE) + /* Load all compiled-in ENGINEs */ + ENGINE_load_builtin_engines(); + ENGINE_register_all_ciphers(); + ENGINE_register_all_digests(); +#endif + + ptls_context_t ctx = {ptls_openssl_random_bytes, &ptls_get_time, ptls_openssl_key_exchanges, ptls_openssl_cipher_suites}; + ptls_handshake_properties_t hsprop = {{{{NULL}}}}; + const char *host, *port, *file = NULL; + int use_early_data = 0, ch; + struct sockaddr_storage sa; + socklen_t salen; + int family = 0; + + while ((ch = getopt(argc, argv, "46c:i:k:nes:Sl:vh")) != -1) { + switch (ch) { + case '4': + family = AF_INET; + break; + case '6': + family = AF_INET6; + break; + case 'c': + load_certificate_chain(&ctx, optarg); + break; + case 'i': + file = optarg; + break; + case 'k': + load_private_key(&ctx, optarg); + break; + case 'n': + hsprop.client.negotiate_before_key_exchange = 1; + break; + case 'e': + use_early_data = 1; + break; + case 's': + setup_session_file(&ctx, &hsprop, optarg); + break; + case 'S': + ctx.require_dhe_on_psk = 1; + break; + case 'l': + setup_log_secret(&ctx, optarg); + break; + case 'v': + setup_verify_certificate(&ctx); + break; + default: + usage(argv[0]); + exit(1); + } + } + argc -= optind; + argv += optind; + if (ctx.certificates.count != 0 || ctx.sign_certificate != NULL) { + /* server */ + if (ctx.certificates.count == 0 || ctx.sign_certificate == NULL) { + fprintf(stderr, "-c and -k options must be used together\n"); + return 1; + } + setup_session_cache(&ctx); + } else { + /* client */ + if (use_early_data) { + static size_t max_early_data_size; + hsprop.client.max_early_data_size = &max_early_data_size; + } + } + if (argc != 2) { + fprintf(stderr, "missing host and port\n"); + return 1; + } + host = (--argc, *argv++); + port = (--argc, *argv++); + + if (resolve_address((struct sockaddr *)&sa, &salen, host, port, family, SOCK_STREAM, IPPROTO_TCP) != 0) + exit(1); + + if (ctx.certificates.count != 0) { + return run_server((struct sockaddr *)&sa, salen, &ctx, file, &hsprop); + } else { + return run_client((struct sockaddr *)&sa, salen, &ctx, host, file, &hsprop); + } +} diff --git a/web/server/h2o/libh2o/deps/picotls/t/minicrypto.c b/web/server/h2o/libh2o/deps/picotls/t/minicrypto.c new file mode 100644 index 00000000..0c18a908 --- /dev/null +++ b/web/server/h2o/libh2o/deps/picotls/t/minicrypto.c @@ -0,0 +1,165 @@ +/* + * Copyright (c) 2016 DeNA Co., Ltd., Kazuho Oku + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ +#ifndef _XOPEN_SOURCE +#define _XOPEN_SOURCE 700 /* required for glibc to use getaddrinfo, etc. */ +#endif +#include +#include +#include +#include "../deps/picotest/picotest.h" +#include "../lib/cifra.c" +#include "../lib/uecc.c" +#include "test.h" + +static void test_secp256r1_key_exchange(void) +{ + test_key_exchange(&ptls_minicrypto_secp256r1); +} + +static void test_x25519_key_exchange(void) +{ + test_key_exchange(&ptls_minicrypto_x25519); +} + +static void test_secp256r1_sign(void) +{ + const char *msg = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdef"; + ptls_minicrypto_secp256r1sha256_sign_certificate_t signer = {{secp256r1sha256_sign}}; + uint8_t pub[SECP256R1_PUBLIC_KEY_SIZE]; + uint16_t selected; + ptls_buffer_t sigbuf; + uint32_t sigbuf_small[128]; + + uECC_make_key(pub, signer.key, uECC_secp256r1()); + ptls_buffer_init(&sigbuf, sigbuf_small, sizeof(sigbuf_small)); + + ok(secp256r1sha256_sign(&signer.super, NULL, &selected, &sigbuf, ptls_iovec_init(msg, 32), + (uint16_t[]){PTLS_SIGNATURE_ECDSA_SECP256R1_SHA256}, 1) == 0); + ok(selected == PTLS_SIGNATURE_ECDSA_SECP256R1_SHA256); + + /* FIXME verify sign */ + + ptls_buffer_dispose(&sigbuf); +} + +static void test_hrr(void) +{ + ptls_key_exchange_algorithm_t *client_keyex[] = {&ptls_minicrypto_x25519, &ptls_minicrypto_secp256r1, NULL}; + ptls_context_t client_ctx = {ptls_minicrypto_random_bytes, &ptls_get_time, client_keyex, ptls_minicrypto_cipher_suites}; + ptls_t *client, *server; + ptls_buffer_t cbuf, sbuf, decbuf; + uint8_t cbuf_small[16384], sbuf_small[16384], decbuf_small[16384]; + size_t consumed; + int ret; + + assert(ctx_peer->key_exchanges[0] != NULL && ctx_peer->key_exchanges[0]->id == PTLS_GROUP_SECP256R1); + assert(ctx_peer->key_exchanges[1] == NULL); + + client = ptls_new(&client_ctx, 0); + server = ptls_new(ctx_peer, 1); + ptls_buffer_init(&cbuf, cbuf_small, sizeof(cbuf_small)); + ptls_buffer_init(&sbuf, sbuf_small, sizeof(sbuf_small)); + ptls_buffer_init(&decbuf, decbuf_small, sizeof(decbuf_small)); + + ret = ptls_handshake(client, &cbuf, NULL, NULL, NULL); + ok(ret == PTLS_ERROR_IN_PROGRESS); + + consumed = cbuf.off; + ret = ptls_handshake(server, &sbuf, cbuf.base, &consumed, NULL); + ok(ret == PTLS_ERROR_IN_PROGRESS); + ok(consumed == cbuf.off); + cbuf.off = 0; + + ok(sbuf.off > 5 + 4); + ok(sbuf.base[5] == 2 /* PTLS_HANDSHAKE_TYPE_SERVER_HELLO (RETRY_REQUEST) */); + + consumed = sbuf.off; + ret = ptls_handshake(client, &cbuf, sbuf.base, &consumed, NULL); + ok(ret == PTLS_ERROR_IN_PROGRESS); + ok(consumed == sbuf.off); + sbuf.off = 0; + + ok(cbuf.off >= 5 + 4); + ok(cbuf.base[5] == 1 /* PTLS_HANDSHAKE_TYPE_CLIENT_HELLO */); + + consumed = cbuf.off; + ret = ptls_handshake(server, &sbuf, cbuf.base, &consumed, NULL); + ok(ret == 0); + ok(consumed == cbuf.off); + cbuf.off = 0; + + ok(sbuf.off >= 5 + 4); + ok(sbuf.base[5] == 2 /* PTLS_HANDSHAKE_TYPE_SERVER_HELLO */); + + consumed = sbuf.off; + ret = ptls_handshake(client, &cbuf, sbuf.base, &consumed, NULL); + ok(ret == 0); + ok(consumed == sbuf.off); + sbuf.off = 0; + + ret = ptls_send(client, &cbuf, "hello world", 11); + ok(ret == 0); + + consumed = cbuf.off; + ret = ptls_receive(server, &decbuf, cbuf.base, &consumed); + ok(ret == 0); + ok(consumed == cbuf.off); + cbuf.off = 0; + + ok(decbuf.off == 11); + ok(memcmp(decbuf.base, "hello world", 11) == 0); + + ptls_buffer_dispose(&decbuf); + ptls_buffer_dispose(&sbuf); + ptls_buffer_dispose(&cbuf); + ptls_free(client); + ptls_free(server); +} + +int main(int argc, char **argv) +{ + subtest("secp256r1", test_secp256r1_key_exchange); + subtest("x25519", test_x25519_key_exchange); + subtest("secp256r1-sign", test_secp256r1_sign); + + ptls_iovec_t cert = ptls_iovec_init(SECP256R1_CERTIFICATE, sizeof(SECP256R1_CERTIFICATE) - 1); + + ptls_minicrypto_secp256r1sha256_sign_certificate_t sign_certificate; + ptls_minicrypto_init_secp256r1sha256_sign_certificate(&sign_certificate, + ptls_iovec_init(SECP256R1_PRIVATE_KEY, SECP256R1_PRIVATE_KEY_SIZE)); + + ptls_context_t ctxbuf = {ptls_minicrypto_random_bytes, + &ptls_get_time, + ptls_minicrypto_key_exchanges, + ptls_minicrypto_cipher_suites, + {&cert, 1}, + NULL, + NULL, + &sign_certificate.super}; + ctx = ctx_peer = &ctxbuf; + + subtest("picotls", test_picotls); + subtest("hrr", test_hrr); + + return done_testing(); + return done_testing(); +} diff --git a/web/server/h2o/libh2o/deps/picotls/t/openssl.c b/web/server/h2o/libh2o/deps/picotls/t/openssl.c new file mode 100644 index 00000000..9a7fc539 --- /dev/null +++ b/web/server/h2o/libh2o/deps/picotls/t/openssl.c @@ -0,0 +1,227 @@ +/* + * Copyright (c) 2016 DeNA Co., Ltd., Kazuho Oku + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ +#ifdef _WINDOWS +#include "wincompat.h" +#endif +#include +#include +#include +#include +#include +#include +#include "picotls.h" +#include "picotls/minicrypto.h" +#include "../deps/picotest/picotest.h" +#include "../lib/openssl.c" +#include "test.h" + +#define RSA_PRIVATE_KEY \ + "-----BEGIN RSA PRIVATE KEY-----\n" \ + "MIIEowIBAAKCAQEA5soWzSG7iyawQlHM1yaX2dUAATUkhpbg2WPFOEem7E3zYzc6\n" \ + "A/Z+bViFlfEgL37cbDUb4pnOAHrrsjGgkyBYh5i9iCTVfCk+H6SOHZJORO1Tq8X9\n" \ + "C7WcNcshpSdm2Pa8hmv9hsHbLSeoPNeg8NkTPwMVaMZ2GpdmiyAmhzSZ2H9mzNI7\n" \ + "ntPW/XCchVf+ax2yt9haZ+mQE2NPYwHDjqCtdGkP5ZXXnYhJSBzSEhxfGckIiKDy\n" \ + "OxiNkLFLvUdT4ERSFBjauP2cSI0XoOUsiBxJNwHH310AU8jZbveSTcXGYgEuu2MI\n" \ + "uDo7Vhkq5+TCqXsIFNbjy0taOoPRvUbPsbqFlQIDAQABAoIBAQCWcUv1wjR/2+Nw\n" \ + "B+Swp267R9bt8pdxyK6f5yKrskGErremiFygMrFtVBQYjws9CsRjISehSkN4GqjE\n" \ + "CweygJZVJeL++YvUmQnvFJSzgCjXU6GEStbOKD/A7T5sa0fmzMhOE907V+kpAT3x\n" \ + "E1rNRaP/ImJ1X1GjuefVb0rOPiK/dehFQWfsUkOvh+J3PU76wcnexxzJgxhVxdfX\n" \ + "qNa7UDsWzTImUjcHIfnhXc1K/oSKk6HjImQi/oE4lgoJUCEDaUbq0nXNrM0EmTTv\n" \ + "OQ5TVP5Lds9p8UDEa55eZllGXam0zKjhDKtkQ/5UfnxsAv2adY5cuH+XN0ExfKD8\n" \ + "wIZ5qINtAoGBAPRbQGZZkP/HOYA4YZ9HYAUQwFS9IZrQ8Y7C/UbL01Xli13nKalH\n" \ + "xXdG6Zv6Yv0FCJKA3N945lEof9rwriwhuZbyrA1TcKok/s7HR8Bhcsm2DzRD5OiC\n" \ + "3HK+Xy+6fBaMebffqBPp3Lfj/lSPNt0w/8DdrKBTw/cAy40g0n1zEu07AoGBAPHJ\n" \ + "V4IfQBiblCqDh77FfQRUNR4hVbbl00Gviigiw563nk7sxdrOJ1edTyTOUBHtM3zg\n" \ + "AT9sYz2CUXvsyEPqzMDANWMb9e2R//NcP6aM4k7WQRnwkZkp0WOIH95U2o1MHCYc\n" \ + "5meAHVf2UMl+64xU2ZfY3rjMmPLjWMt0hKYsOmtvAoGAClIQVkJSLXtsok2/Ucrh\n" \ + "81TRysJyOOe6TB1QNT1Gn8oiKMUqrUuqu27zTvM0WxtrUUTAD3A7yhG71LN1p8eE\n" \ + "3ytAuQ9dItKNMI6aKTX0czCNU9fKQ0fDp9UCkDGALDOisHFx1+V4vQuUIl4qIw1+\n" \ + "v9adA+iFzljqP/uy6DmEAyECgYAyWCgecf9YoFxzlbuYH2rukdIVmf9M/AHG9ZQg\n" \ + "00xEKhuOd4KjErXiamDmWwcVFHzaDZJ08E6hqhbpZN42Nhe4Ms1q+5FzjCjtNVIT\n" \ + "jdY5cCdSDWNjru9oeBmao7R2I1jhHrdi6awyeplLu1+0cp50HbYSaJeYS3pbssFE\n" \ + "EIWBhQKBgG3xleD4Sg9rG2OWQz5IrvLFg/Hy7YWyushVez61kZeLDnt9iM2um76k\n" \ + "/xFNIW0a+eL2VxRTCbXr9z86hjc/6CeSJHKYFQl4zsSAZkaIJ0+HbrhDNBAYh9b2\n" \ + "mRdX+OMdZ7Z5J3Glt8ENFRqe8RlESMpAKxjR+dID0bjwAjVr2KCh\n" \ + "-----END RSA PRIVATE KEY-----\n" + +#define RSA_CERTIFICATE \ + "-----BEGIN CERTIFICATE-----\n" \ + "MIICqDCCAZACCQDI5jeEvExN+TANBgkqhkiG9w0BAQUFADAWMRQwEgYDVQQDEwtl\n" \ + "eGFtcGxlLmNvbTAeFw0xNjA5MzAwMzQ0NTFaFw0yNjA5MjgwMzQ0NTFaMBYxFDAS\n" \ + "BgNVBAMTC2V4YW1wbGUuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC\n" \ + "AQEA5soWzSG7iyawQlHM1yaX2dUAATUkhpbg2WPFOEem7E3zYzc6A/Z+bViFlfEg\n" \ + "L37cbDUb4pnOAHrrsjGgkyBYh5i9iCTVfCk+H6SOHZJORO1Tq8X9C7WcNcshpSdm\n" \ + "2Pa8hmv9hsHbLSeoPNeg8NkTPwMVaMZ2GpdmiyAmhzSZ2H9mzNI7ntPW/XCchVf+\n" \ + "ax2yt9haZ+mQE2NPYwHDjqCtdGkP5ZXXnYhJSBzSEhxfGckIiKDyOxiNkLFLvUdT\n" \ + "4ERSFBjauP2cSI0XoOUsiBxJNwHH310AU8jZbveSTcXGYgEuu2MIuDo7Vhkq5+TC\n" \ + "qXsIFNbjy0taOoPRvUbPsbqFlQIDAQABMA0GCSqGSIb3DQEBBQUAA4IBAQAwZQsG\n" \ + "E/3DQFBOnmBITFsaIVJVXU0fbfIjy3p1r6O9z2zvrfB1i8AMxOORAVjE5wHstGnK\n" \ + "3sLMjkMYXqu1XEfQbStQN+Bsi8m+nE/x9MmuLthpzJHXUmPYZ4TKs0KJmFPLTXYi\n" \ + "j0OrP0a5BNcyGj/B4Z33aaU9N3z0TWBwx4OPjJoK3iInBx80sC1Ig2PE6mDBxLOg\n" \ + "5Ohm/XU/43MrtH8SgYkxr3OyzXTm8J0RFMWhYlo1uqR+pWV3TgacixNnUq5w5h4m\n" \ + "sqXcikh+j8ReNXsKnMOAfFo+HbRqyKWNE3DekCIiiQ5ds4A4SfT7pYyGAmBkAxht\n" \ + "sS919x2o8l97kaYf\n" \ + "-----END CERTIFICATE-----\n" + +static void test_ecdh_key_exchange(void) +{ + test_key_exchange(&ptls_openssl_secp256r1); +} + +static void test_rsa_sign(void) +{ + ptls_openssl_sign_certificate_t *sc = (ptls_openssl_sign_certificate_t *)ctx->sign_certificate; + + const void *message = "hello world"; + ptls_buffer_t sigbuf; + uint8_t sigbuf_small[1024]; + + ptls_buffer_init(&sigbuf, sigbuf_small, sizeof(sigbuf_small)); + ok(do_sign(sc->key, &sigbuf, ptls_iovec_init(message, strlen(message)), EVP_sha256()) == 0); + EVP_PKEY_up_ref(sc->key); + ok(verify_sign(sc->key, ptls_iovec_init(message, strlen(message)), ptls_iovec_init(sigbuf.base, sigbuf.off)) == 0); + + ptls_buffer_dispose(&sigbuf); +} + +static void test_ecdsa_sign(void) +{ + EVP_PKEY *pkey; + + { /* create pkey */ + EC_KEY *eckey = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1); + EC_KEY_generate_key(eckey); + pkey = EVP_PKEY_new(); + EVP_PKEY_set1_EC_KEY(pkey, eckey); + EC_KEY_free(eckey); + } + + const char *message = "hello world"; + ptls_buffer_t sigbuf; + uint8_t sigbuf_small[1024]; + + ptls_buffer_init(&sigbuf, sigbuf_small, sizeof(sigbuf_small)); + ok(do_sign(pkey, &sigbuf, ptls_iovec_init(message, strlen(message)), EVP_sha256()) == 0); + EVP_PKEY_up_ref(pkey); + ok(verify_sign(pkey, ptls_iovec_init(message, strlen(message)), ptls_iovec_init(sigbuf.base, sigbuf.off)) == 0); + + ptls_buffer_dispose(&sigbuf); + EVP_PKEY_free(pkey); +} + +static void setup_certificate(ptls_iovec_t *dst) +{ + BIO *bio = BIO_new_mem_buf(RSA_CERTIFICATE, strlen(RSA_CERTIFICATE)); + X509 *cert = PEM_read_bio_X509(bio, NULL, NULL, NULL); + assert(cert != NULL || !!"failed to load certificate"); + BIO_free(bio); + + dst->base = NULL; + dst->len = i2d_X509(cert, &dst->base); + + X509_free(cert); +} + +static void setup_sign_certificate(ptls_openssl_sign_certificate_t *sc) +{ + BIO *bio = BIO_new_mem_buf(RSA_PRIVATE_KEY, strlen(RSA_PRIVATE_KEY)); + EVP_PKEY *pkey = PEM_read_bio_PrivateKey(bio, NULL, NULL, NULL); + assert(pkey != NULL || !"failed to load private key"); + BIO_free(bio); + + ptls_openssl_init_sign_certificate(sc, pkey); + + EVP_PKEY_free(pkey); +} + +int main(int argc, char **argv) +{ + ptls_openssl_sign_certificate_t openssl_sign_certificate; + ptls_openssl_verify_certificate_t openssl_verify_certificate; + + ERR_load_crypto_strings(); + OpenSSL_add_all_algorithms(); +#if !defined(OPENSSL_NO_ENGINE) + /* Load all compiled-in ENGINEs */ + ENGINE_load_builtin_engines(); + ENGINE_register_all_ciphers(); + ENGINE_register_all_digests(); +#endif + + ptls_iovec_t cert; + setup_certificate(&cert); + setup_sign_certificate(&openssl_sign_certificate); + ptls_openssl_init_verify_certificate(&openssl_verify_certificate, NULL); + ptls_context_t openssl_ctx = {ptls_openssl_random_bytes, + &ptls_get_time, + ptls_openssl_key_exchanges, + ptls_openssl_cipher_suites, + {&cert, 1}, + NULL, + NULL, + &openssl_sign_certificate.super, + &openssl_verify_certificate.super}; + assert(openssl_ctx.cipher_suites[0]->hash->digest_size == 48); /* sha384 */ + ptls_context_t openssl_ctx_sha256only = openssl_ctx; + ++openssl_ctx_sha256only.cipher_suites; + assert(openssl_ctx_sha256only.cipher_suites[0]->hash->digest_size == 32); /* sha256 */ + + ctx = ctx_peer = &openssl_ctx; + + subtest("ecdh-key-exchange", test_ecdh_key_exchange); + subtest("rsa-sign", test_rsa_sign); + subtest("ecdsa-sign", test_ecdsa_sign); + subtest("picotls", test_picotls); + + ctx = ctx_peer = &openssl_ctx_sha256only; + subtest("picotls", test_picotls); + + ctx = &openssl_ctx_sha256only; + ctx_peer = &openssl_ctx; + subtest("picotls", test_picotls); + + ctx = &openssl_ctx; + ctx_peer = &openssl_ctx_sha256only; + subtest("picotls", test_picotls); + + ptls_minicrypto_secp256r1sha256_sign_certificate_t minicrypto_sign_certificate; + ptls_iovec_t minicrypto_certificate = ptls_iovec_init(SECP256R1_CERTIFICATE, sizeof(SECP256R1_CERTIFICATE) - 1); + ptls_minicrypto_init_secp256r1sha256_sign_certificate( + &minicrypto_sign_certificate, ptls_iovec_init(SECP256R1_PRIVATE_KEY, sizeof(SECP256R1_PRIVATE_KEY) - 1)); + ptls_context_t minicrypto_ctx = {ptls_minicrypto_random_bytes, + &ptls_get_time, + ptls_minicrypto_key_exchanges, + ptls_minicrypto_cipher_suites, + {&minicrypto_certificate, 1}, + NULL, + NULL, + &minicrypto_sign_certificate.super}; + ctx = &openssl_ctx; + ctx_peer = &minicrypto_ctx; + subtest("vs. minicrypto", test_picotls); + + ctx = &minicrypto_ctx; + ctx_peer = &openssl_ctx; + subtest("minicrypto vs.", test_picotls); + + return done_testing(); +} diff --git a/web/server/h2o/libh2o/deps/picotls/t/picotls.c b/web/server/h2o/libh2o/deps/picotls/t/picotls.c new file mode 100644 index 00000000..bb90c62c --- /dev/null +++ b/web/server/h2o/libh2o/deps/picotls/t/picotls.c @@ -0,0 +1,843 @@ +/* + * Copyright (c) 2016 DeNA Co., Ltd., Kazuho Oku + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ +#ifdef _WINDOWS +#include "wincompat.h" +#endif +#include +#include +#include +#include "picotls.h" +#include "picotls/minicrypto.h" +#include "../deps/picotest/picotest.h" +#include "../lib/picotls.c" +#include "test.h" + +ptls_context_t *ctx, *ctx_peer; + +static ptls_cipher_suite_t *find_cipher(ptls_context_t *ctx, uint16_t id) +{ + ptls_cipher_suite_t **cs; + for (cs = ctx->cipher_suites; *cs != NULL; ++cs) + if ((*cs)->id == id) + return *cs; + return NULL; +} + +static void test_hash(ptls_hash_algorithm_t *hash) +{ + ptls_hash_context_t *hctx = hash->create(); + uint8_t digest[PTLS_MAX_DIGEST_SIZE]; + + hctx->final(hctx, digest, PTLS_HASH_FINAL_MODE_FREE); + ok(memcmp(digest, hash->empty_digest, hash->digest_size) == 0); +} + +static void test_sha256(void) +{ + test_hash(find_cipher(ctx, PTLS_CIPHER_SUITE_AES_128_GCM_SHA256)->hash); +} + +static void test_sha384(void) +{ + ptls_cipher_suite_t *cs = find_cipher(ctx, PTLS_CIPHER_SUITE_AES_256_GCM_SHA384); + if (cs != NULL) + test_hash(cs->hash); +} + +static void test_hmac_sha256(void) +{ + /* test vector from RFC 4231 */ + const char *secret = "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b", *message = "Hi There"; + uint8_t digest[32]; + + ptls_hash_context_t *hctx = + ptls_hmac_create(find_cipher(ctx, PTLS_CIPHER_SUITE_AES_128_GCM_SHA256)->hash, secret, strlen(secret)); + hctx->update(hctx, message, strlen(message)); + hctx->final(hctx, digest, 0); + + ok(memcmp(digest, "\xb0\x34\x4c\x61\xd8\xdb\x38\x53\x5c\xa8\xaf\xce\xaf\x0b\xf1\x2b\x88\x1d\xc2\x00\xc9\x83\x3d\xa7\x26\xe9\x37" + "\x6c\x2e\x32\xcf\xf7", + 32) == 0); +} + +static void test_hkdf(void) +{ + ptls_hash_algorithm_t *sha256 = find_cipher(ctx, PTLS_CIPHER_SUITE_AES_128_GCM_SHA256)->hash; + const char salt[] = "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c"; + const char ikm[] = "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b"; + const char info[] = "\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9"; + uint8_t prk[PTLS_MAX_DIGEST_SIZE]; + uint8_t okm[42]; + + ptls_hkdf_extract(sha256, prk, ptls_iovec_init(salt, sizeof(salt) - 1), ptls_iovec_init(ikm, sizeof(ikm) - 1)); + ok(memcmp(prk, "\x07\x77\x09\x36\x2c\x2e\x32\xdf\x0d\xdc\x3f\x0d\xc4\x7b\xba\x63\x90\xb6\xc7\x3b\xb5\x0f\x9c\x31\x22\xec\x84" + "\x4a\xd7\xc2\xb3\xe5", + 32) == 0); + + ptls_hkdf_expand(sha256, okm, sizeof(okm), ptls_iovec_init(prk, sha256->digest_size), ptls_iovec_init(info, sizeof(info) - 1)); + ok(memcmp(okm, "\x3c\xb2\x5f\x25\xfa\xac\xd5\x7a\x90\x43\x4f\x64\xd0\x36\x2f\x2a\x2d\x2d\x0a\x90\xcf\x1a\x5a\x4c\x5d\xb0\x2d" + "\x56\xec\xc4\xc5\xbf\x34\x00\x72\x08\xd5\xb8\x87\x18\x58\x65", + sizeof(okm)) == 0); +} + +static void test_ciphersuite(ptls_cipher_suite_t *cs1, ptls_cipher_suite_t *cs2) +{ + const char *traffic_secret = "01234567890123456789012345678901", *src1 = "hello world", *src2 = "good bye, all"; + ptls_aead_context_t *c; + char enc1[256], enc2[256], dec1[256], dec2[256]; + size_t enc1len, enc2len, dec1len, dec2len; + + /* encrypt */ + c = ptls_aead_new(cs1->aead, cs1->hash, 1, traffic_secret, NULL); + assert(c != NULL); + ptls_aead_encrypt_init(c, 0, NULL, 0); + enc1len = ptls_aead_encrypt_update(c, enc1, src1, strlen(src1)); + enc1len += ptls_aead_encrypt_final(c, enc1 + enc1len); + ptls_aead_encrypt_init(c, 1, NULL, 0); + enc2len = ptls_aead_encrypt_update(c, enc2, src2, strlen(src2)); + enc2len += ptls_aead_encrypt_final(c, enc2 + enc2len); + ptls_aead_free(c); + + c = ptls_aead_new(cs2->aead, cs2->hash, 0, traffic_secret, NULL); + assert(c != NULL); + + /* decrypt and compare */ + dec1len = ptls_aead_decrypt(c, dec1, enc1, enc1len, 0, NULL, 0); + ok(dec1len != SIZE_MAX); + dec2len = ptls_aead_decrypt(c, dec2, enc2, enc2len, 1, NULL, 0); + ok(dec2len != SIZE_MAX); + ok(strlen(src1) == dec1len); + ok(memcmp(src1, dec1, dec1len) == 0); + ok(strlen(src2) == dec2len); + ok(memcmp(src2, dec2, dec2len - 1) == 0); + + /* alter and decrypt to detect failure */ + enc1[0] ^= 1; + dec1len = ptls_aead_decrypt(c, dec1, enc1, enc1len, 0, NULL, 0); + ok(dec1len == SIZE_MAX); + + ptls_aead_free(c); +} + +static void test_aad_ciphersuite(ptls_cipher_suite_t *cs1, ptls_cipher_suite_t *cs2) +{ + const char *traffic_secret = "01234567890123456789012345678901", *src = "hello world", *aad = "my true aad"; + ptls_aead_context_t *c; + char enc[256], dec[256]; + size_t enclen, declen; + + /* encrypt */ + c = ptls_aead_new(cs1->aead, cs1->hash, 1, traffic_secret, NULL); + assert(c != NULL); + ptls_aead_encrypt_init(c, 123, aad, strlen(aad)); + enclen = ptls_aead_encrypt_update(c, enc, src, strlen(src)); + enclen += ptls_aead_encrypt_final(c, enc + enclen); + ptls_aead_free(c); + + /* decrypt */ + c = ptls_aead_new(cs2->aead, cs2->hash, 0, traffic_secret, NULL); + assert(c != NULL); + declen = ptls_aead_decrypt(c, dec, enc, enclen, 123, aad, strlen(aad)); + ok(declen == strlen(src)); + ok(memcmp(src, dec, declen) == 0); + declen = ptls_aead_decrypt(c, dec, enc, enclen, 123, "my fake aad", strlen(aad)); + ok(declen == SIZE_MAX); + ptls_aead_free(c); +} + +static void test_ctr(ptls_cipher_suite_t *cs, const uint8_t *key, size_t key_len, const void *iv, size_t iv_len, + const void *expected, size_t expected_len) +{ + static uint8_t zeroes[64] = {0}; + + if (cs == NULL) + return; + + ptls_cipher_algorithm_t *algo = cs->aead->ctr_cipher; + uint8_t buf[sizeof(zeroes)]; + + assert(expected_len <= sizeof(zeroes)); + ok(algo->key_size == key_len); + ok(algo->iv_size == iv_len); + + ptls_cipher_context_t *ctx = ptls_cipher_new(algo, 1, key); + assert(ctx != NULL); + ptls_cipher_init(ctx, iv); + ptls_cipher_encrypt(ctx, buf, zeroes, expected_len); + ptls_cipher_free(ctx); + + ok(memcmp(buf, expected, expected_len) == 0); +} + +static void test_aes128ctr(void) +{ + static const uint8_t key[] = {0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c}, + iv[] = {0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a}, + expected[] = {0x3a, 0xd7, 0x7b, 0xb4, 0x0d, 0x7a, 0x36, 0x60, + 0xa8, 0x9e, 0xca, 0xf3, 0x24, 0x66, 0xef, 0x97}; + + test_ctr(find_cipher(ctx, PTLS_CIPHER_SUITE_AES_128_GCM_SHA256), key, sizeof(key), iv, sizeof(iv), expected, sizeof(expected)); +} + +static void test_chacha20(void) +{ + static const uint8_t key[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31}, + iv[] = {1, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0x4a, 0, 0, 0, 0}, + expected[] = {0x10, 0xf1, 0xe7, 0xe4, 0xd1, 0x3b, 0x59, 0x15, 0x50, 0x0f, 0xdd, + 0x1f, 0xa3, 0x20, 0x71, 0xc4, 0xc7, 0xd1, 0xf4, 0xc7, 0x33, 0xc0, + 0x68, 0x03, 0x04, 0x22, 0xaa, 0x9a, 0xc3, 0xd4, 0x6c, 0x4e}; + + test_ctr(find_cipher(ctx, PTLS_CIPHER_SUITE_CHACHA20_POLY1305_SHA256), key, sizeof(key), iv, sizeof(iv), expected, + sizeof(expected)); +} + +static void test_aes128gcm(void) +{ + ptls_cipher_suite_t *cs = find_cipher(ctx, PTLS_CIPHER_SUITE_AES_128_GCM_SHA256), + *cs_peer = find_cipher(ctx, PTLS_CIPHER_SUITE_AES_128_GCM_SHA256); + + test_ciphersuite(cs, cs_peer); + test_aad_ciphersuite(cs, cs_peer); +} + +static void test_aes256gcm(void) +{ + ptls_cipher_suite_t *cs = find_cipher(ctx, PTLS_CIPHER_SUITE_AES_256_GCM_SHA384), + *cs_peer = find_cipher(ctx, PTLS_CIPHER_SUITE_AES_256_GCM_SHA384); + + if (cs != NULL && cs_peer != NULL) { + test_ciphersuite(cs, cs_peer); + test_aad_ciphersuite(cs, cs_peer); + } +} + +static void test_chacha20poly1305(void) +{ + ptls_cipher_suite_t *cs = find_cipher(ctx, PTLS_CIPHER_SUITE_CHACHA20_POLY1305_SHA256), + *cs_peer = find_cipher(ctx, PTLS_CIPHER_SUITE_CHACHA20_POLY1305_SHA256); + + if (cs != NULL && cs_peer != NULL) { + test_ciphersuite(cs, cs_peer); + test_aad_ciphersuite(cs, cs_peer); + } +} + +static struct { + struct { + uint8_t buf[32]; + size_t len; + int is_end_of_record; + } vec[16]; + size_t count; +} test_fragmented_message_queue = {{{{0}}}}; + +static int test_fragmented_message_record(ptls_t *tls, ptls_buffer_t *sendbuf, ptls_iovec_t message, int is_end_of_record, + ptls_handshake_properties_t *properties) +{ + memcpy(test_fragmented_message_queue.vec[test_fragmented_message_queue.count].buf, message.base, message.len); + test_fragmented_message_queue.vec[test_fragmented_message_queue.count].len = message.len; + test_fragmented_message_queue.vec[test_fragmented_message_queue.count].is_end_of_record = is_end_of_record; + ++test_fragmented_message_queue.count; + + return 0; +} + +static void test_fragmented_message(void) +{ + ptls_t tls = {NULL}; + struct st_ptls_record_t rec = {PTLS_CONTENT_TYPE_HANDSHAKE, 0x0301}; + int ret; + +#define SET_RECORD(lit) \ + do { \ + rec.length = sizeof(lit) - 1; \ + rec.fragment = (const uint8_t *)(lit); \ + } while (0) + + /* not fragmented */ + test_fragmented_message_queue.count = 0; + SET_RECORD("\x01\x00\x00\x03" + "abc"); + ret = handle_handshake_record(&tls, test_fragmented_message_record, NULL, &rec, NULL); + ok(ret == 0); + ok(test_fragmented_message_queue.count == 1); + ok(test_fragmented_message_queue.vec[0].len == rec.length); + ok(memcmp(test_fragmented_message_queue.vec[0].buf, rec.fragment, rec.length) == 0); + ok(test_fragmented_message_queue.vec[0].is_end_of_record); + ok(tls.recvbuf.mess.base == NULL); + + /* fragmented */ + test_fragmented_message_queue.count = 0; + SET_RECORD("\x01\x00\x00\x03" + "a"); + ret = handle_handshake_record(&tls, test_fragmented_message_record, NULL, &rec, NULL); + ok(ret == PTLS_ERROR_IN_PROGRESS); + ok(tls.recvbuf.mess.base != NULL); + ok(test_fragmented_message_queue.count == 0); + SET_RECORD("bc\x02\x00\x00\x02" + "de" + "\x03"); + ret = handle_handshake_record(&tls, test_fragmented_message_record, NULL, &rec, NULL); + ok(ret == PTLS_ERROR_IN_PROGRESS); + ok(test_fragmented_message_queue.count == 2); + ok(test_fragmented_message_queue.vec[0].len == 7); + ok(memcmp(test_fragmented_message_queue.vec[0].buf, "\x01\x00\x00\x03" + "abc", + 7) == 0); + ok(!test_fragmented_message_queue.vec[0].is_end_of_record); + ok(test_fragmented_message_queue.vec[1].len == 6); + ok(memcmp(test_fragmented_message_queue.vec[1].buf, "\x02\x00\x00\x02" + "de", + 6) == 0); + ok(!test_fragmented_message_queue.vec[1].is_end_of_record); + SET_RECORD("\x00\x00\x03" + "end"); + ret = handle_handshake_record(&tls, test_fragmented_message_record, NULL, &rec, NULL); + ok(ret == 0); + ok(tls.recvbuf.mess.base == NULL); + ok(test_fragmented_message_queue.count == 3); + ok(test_fragmented_message_queue.vec[2].len == 7); + ok(memcmp(test_fragmented_message_queue.vec[2].buf, "\x03\x00\x00\x03" + "end", + 7) == 0); + ok(test_fragmented_message_queue.vec[2].is_end_of_record); + +#undef SET_RECORD +} + +static int save_client_hello(ptls_on_client_hello_t *self, ptls_t *tls, ptls_iovec_t server_name, const ptls_iovec_t *protocols, + size_t num_protocols, const uint16_t *signature_algorithms, size_t num_signature_algorithms) +{ + ptls_set_server_name(tls, (const char *)server_name.base, server_name.len); + ptls_set_negotiated_protocol(tls, (const char *)protocols[0].base, protocols[0].len); + return 0; +} + +enum { TEST_HANDSHAKE_1RTT, TEST_HANDSHAKE_2RTT, TEST_HANDSHAKE_HRR, TEST_HANDSHAKE_HRR_STATELESS, TEST_HANDSHAKE_EARLY_DATA }; + +static void test_handshake(ptls_iovec_t ticket, int mode, int expect_ticket, int check_ch) +{ + ptls_t *client, *server; + ptls_handshake_properties_t client_hs_prop = {{{{NULL}, ticket}}}, server_hs_prop = {{{{NULL}}}}; + uint8_t cbuf_small[16384], sbuf_small[16384], decbuf_small[16384]; + ptls_buffer_t cbuf, sbuf, decbuf; + size_t consumed, max_early_data_size = 0; + int ret; + const char *req = "GET / HTTP/1.0\r\n\r\n"; + const char *resp = "HTTP/1.0 200 OK\r\n\r\nhello world\n"; + + client = ptls_new(ctx, 0); + server = ptls_new(ctx_peer, 1); + ptls_buffer_init(&cbuf, cbuf_small, sizeof(cbuf_small)); + ptls_buffer_init(&sbuf, sbuf_small, sizeof(sbuf_small)); + ptls_buffer_init(&decbuf, decbuf_small, sizeof(decbuf_small)); + + if (check_ch) { + static ptls_on_client_hello_t cb = {save_client_hello}; + ctx_peer->on_client_hello = &cb; + static const ptls_iovec_t protocols[] = {{(uint8_t *)"h2", 2}, {(uint8_t *)"http/1.1", 8}}; + client_hs_prop.client.negotiated_protocols.list = protocols; + client_hs_prop.client.negotiated_protocols.count = sizeof(protocols) / sizeof(protocols[0]); + ptls_set_server_name(client, "example.com", 0); + } + + switch (mode) { + case TEST_HANDSHAKE_HRR: + client_hs_prop.client.negotiate_before_key_exchange = 1; + break; + case TEST_HANDSHAKE_HRR_STATELESS: + client_hs_prop.client.negotiate_before_key_exchange = 1; + server_hs_prop.server.cookie.key = "0123456789abcdef0123456789abcdef"; + server_hs_prop.server.retry_uses_cookie = 1; + break; + case TEST_HANDSHAKE_EARLY_DATA: + assert(ctx_peer->max_early_data_size != 0); + client_hs_prop.client.max_early_data_size = &max_early_data_size; + break; + } + + ret = ptls_handshake(client, &cbuf, NULL, NULL, &client_hs_prop); + ok(ret == PTLS_ERROR_IN_PROGRESS); + ok(cbuf.off != 0); + + switch (mode) { + case TEST_HANDSHAKE_2RTT: + case TEST_HANDSHAKE_HRR: + case TEST_HANDSHAKE_HRR_STATELESS: + consumed = cbuf.off; + ret = ptls_handshake(server, &sbuf, cbuf.base, &consumed, &server_hs_prop); + if (mode == TEST_HANDSHAKE_HRR_STATELESS) { + ok(ret == PTLS_ERROR_STATELESS_RETRY); + ptls_free(server); + server = ptls_new(ctx_peer, 1); + } else { + ok(ret == PTLS_ERROR_IN_PROGRESS); + } + ok(cbuf.off == consumed); + ok(sbuf.off != 0); + cbuf.off = 0; + consumed = sbuf.off; + ret = ptls_handshake(client, &cbuf, sbuf.base, &consumed, &client_hs_prop); + ok(ret == PTLS_ERROR_IN_PROGRESS); + ok(sbuf.off == consumed); + ok(cbuf.off != 0); + sbuf.off = 0; + break; + case TEST_HANDSHAKE_EARLY_DATA: + ok(max_early_data_size == ctx_peer->max_early_data_size); + ret = ptls_send(client, &cbuf, req, strlen(req)); + ok(ret == 0); + break; + } + + consumed = cbuf.off; + ret = ptls_handshake(server, &sbuf, cbuf.base, &consumed, &server_hs_prop); + ok(ret == 0); + ok(sbuf.off != 0); + if (check_ch) { + ok(ptls_get_server_name(server) != NULL); + ok(strcmp(ptls_get_server_name(server), "example.com") == 0); + ok(ptls_get_negotiated_protocol(server) != NULL); + ok(strcmp(ptls_get_negotiated_protocol(server), "h2") == 0); + } else { + ok(ptls_get_server_name(server) == NULL); + ok(ptls_get_negotiated_protocol(server) == NULL); + } + + if (mode == TEST_HANDSHAKE_EARLY_DATA) { + ok(consumed < cbuf.off); + memmove(cbuf.base, cbuf.base + consumed, cbuf.off - consumed); + cbuf.off -= consumed; + + consumed = cbuf.off; + ret = ptls_receive(server, &decbuf, cbuf.base, &consumed); + ok(ret == 0); + ok(consumed == cbuf.off); + ok(decbuf.off == strlen(req)); + ok(memcmp(decbuf.base, req, decbuf.off) == 0); + ok(!ptls_handshake_is_complete(server)); + cbuf.off = 0; + decbuf.off = 0; + + ret = ptls_send(server, &sbuf, resp, strlen(resp)); + ok(ret == 0); + } else { + ok(consumed == cbuf.off); + cbuf.off = 0; + } + + consumed = sbuf.off; + ret = ptls_handshake(client, &cbuf, sbuf.base, &consumed, NULL); + ok(ret == 0); + ok(cbuf.off != 0); + if (check_ch) { + ok(ptls_get_server_name(client) != NULL); + ok(strcmp(ptls_get_server_name(client), "example.com") == 0); + ok(ptls_get_negotiated_protocol(client) != NULL); + ok(strcmp(ptls_get_negotiated_protocol(client), "h2") == 0); + } else { + ok(ptls_get_server_name(server) == NULL); + ok(ptls_get_negotiated_protocol(server) == NULL); + } + + if (expect_ticket) { + ok(consumed < sbuf.off); + memmove(sbuf.base, sbuf.base + consumed, sbuf.off - consumed); + sbuf.off -= consumed; + } else { + ok(consumed == sbuf.off); + sbuf.off = 0; + } + + if (mode != TEST_HANDSHAKE_EARLY_DATA) { + ret = ptls_send(client, &cbuf, req, strlen(req)); + ok(ret == 0); + + consumed = cbuf.off; + ret = ptls_receive(server, &decbuf, cbuf.base, &consumed); + ok(ret == 0); + ok(consumed == cbuf.off); + ok(decbuf.off == strlen(req)); + ok(memcmp(decbuf.base, req, strlen(req)) == 0); + ok(ptls_handshake_is_complete(server)); + decbuf.off = 0; + + ret = ptls_send(server, &sbuf, resp, strlen(resp)); + ok(ret == 0); + } + + consumed = sbuf.off; + ret = ptls_receive(client, &decbuf, sbuf.base, &consumed); + ok(ret == 0); + ok(consumed == sbuf.off); + ok(decbuf.off == strlen(resp)); + ok(memcmp(decbuf.base, resp, strlen(resp)) == 0); + ok(ptls_handshake_is_complete(client)); + decbuf.off = 0; + + if (mode == TEST_HANDSHAKE_EARLY_DATA) { + consumed = cbuf.off; + ret = ptls_receive(server, &decbuf, cbuf.base, &consumed); + ok(ret == 0); + ok(cbuf.off == consumed); + ok(decbuf.off == 0); + ok(ptls_handshake_is_complete(client)); + } + + ptls_buffer_dispose(&cbuf); + ptls_buffer_dispose(&sbuf); + ptls_buffer_dispose(&decbuf); + ptls_free(client); + ptls_free(server); + + if (check_ch) + ctx_peer->on_client_hello = NULL; +} + +static ptls_sign_certificate_t *sc_orig; +size_t sc_callcnt; + +static int sign_certificate(ptls_sign_certificate_t *self, ptls_t *tls, uint16_t *selected_algorithm, ptls_buffer_t *output, + ptls_iovec_t input, const uint16_t *algorithms, size_t num_algorithms) +{ + ++sc_callcnt; + return sc_orig->cb(sc_orig, tls, selected_algorithm, output, input, algorithms, num_algorithms); +} + +static void test_full_handshake(void) +{ + sc_callcnt = 0; + test_handshake(ptls_iovec_init(NULL, 0), TEST_HANDSHAKE_1RTT, 0, 0); + ok(sc_callcnt == 1); + test_handshake(ptls_iovec_init(NULL, 0), TEST_HANDSHAKE_1RTT, 0, 0); + ok(sc_callcnt == 2); + test_handshake(ptls_iovec_init(NULL, 0), TEST_HANDSHAKE_1RTT, 0, 1); + ok(sc_callcnt == 3); +} + +static void test_hrr_handshake(void) +{ + sc_callcnt = 0; + test_handshake(ptls_iovec_init(NULL, 0), TEST_HANDSHAKE_HRR, 0, 0); + ok(sc_callcnt == 1); +} + +static void test_hrr_stateless_handshake(void) +{ + sc_callcnt = 0; + test_handshake(ptls_iovec_init(NULL, 0), TEST_HANDSHAKE_HRR_STATELESS, 0, 0); + ok(sc_callcnt == 1); +} + +static int copy_ticket(ptls_encrypt_ticket_t *self, ptls_t *tls, int is_encrypt, ptls_buffer_t *dst, ptls_iovec_t src) +{ + int ret; + + if ((ret = ptls_buffer_reserve(dst, src.len)) != 0) + return ret; + memcpy(dst->base + dst->off, src.base, src.len); + dst->off += src.len; + + return 0; +} + +static ptls_iovec_t saved_ticket = {NULL}; + +static int save_ticket(ptls_save_ticket_t *self, ptls_t *tls, ptls_iovec_t src) +{ + saved_ticket.base = malloc(src.len); + memcpy(saved_ticket.base, src.base, src.len); + saved_ticket.len = src.len; + return 0; +} + +static void do_test_resumption(int different_preferred_key_share) +{ + assert(ctx->key_exchanges[0]->id == ctx_peer->key_exchanges[0]->id); + assert(ctx->key_exchanges[1] == NULL); + assert(ctx_peer->key_exchanges[1] == NULL); + assert(ctx->key_exchanges[0]->id != ptls_minicrypto_x25519.id); + ptls_key_exchange_algorithm_t *different_key_exchanges[] = {&ptls_minicrypto_x25519, ctx->key_exchanges[0], NULL}, + **key_exchanges_orig = ctx->key_exchanges; + + if (different_preferred_key_share) + ctx->key_exchanges = different_key_exchanges; + + ptls_encrypt_ticket_t et = {copy_ticket}; + ptls_save_ticket_t st = {save_ticket}; + + assert(ctx_peer->ticket_lifetime == 0); + assert(ctx_peer->max_early_data_size == 0); + assert(ctx_peer->encrypt_ticket == NULL); + assert(ctx_peer->save_ticket == NULL); + saved_ticket = ptls_iovec_init(NULL, 0); + + ctx_peer->ticket_lifetime = 86400; + ctx_peer->max_early_data_size = 8192; + ctx_peer->encrypt_ticket = &et; + ctx->save_ticket = &st; + + sc_callcnt = 0; + test_handshake(saved_ticket, different_preferred_key_share ? TEST_HANDSHAKE_2RTT : TEST_HANDSHAKE_1RTT, 1, 0); + ok(sc_callcnt == 1); + ok(saved_ticket.base != NULL); + + /* psk using saved ticket */ + test_handshake(saved_ticket, TEST_HANDSHAKE_1RTT, 1, 0); + ok(sc_callcnt == 1); + + /* 0-rtt psk using saved ticket */ + test_handshake(saved_ticket, TEST_HANDSHAKE_EARLY_DATA, 1, 0); + ok(sc_callcnt == 1); + + ctx->require_dhe_on_psk = 1; + + /* psk-dhe using saved ticket */ + test_handshake(saved_ticket, TEST_HANDSHAKE_1RTT, 1, 0); + ok(sc_callcnt == 1); + + /* 0-rtt psk-dhe using saved ticket */ + test_handshake(saved_ticket, TEST_HANDSHAKE_EARLY_DATA, 1, 0); + ok(sc_callcnt == 1); + + ctx->require_dhe_on_psk = 0; + ctx_peer->ticket_lifetime = 0; + ctx_peer->max_early_data_size = 0; + ctx_peer->encrypt_ticket = NULL; + ctx->save_ticket = NULL; + ctx->key_exchanges = key_exchanges_orig; +} + +static void test_resumption(void) +{ + do_test_resumption(0); +} + +static void test_resumption_different_preferred_key_share(void) +{ + if (ctx == ctx_peer) + return; + do_test_resumption(1); +} + +static void test_enforce_retry(int use_cookie) +{ + ptls_t *client, *server; + ptls_handshake_properties_t server_hs_prop = {{{{NULL}}}}; + ptls_buffer_t cbuf, sbuf, decbuf; + size_t consumed; + int ret; + + server_hs_prop.server.cookie.key = "0123456789abcdef0123456789abcdef"; + server_hs_prop.server.cookie.additional_data = ptls_iovec_init("1.2.3.4:1234", 12); + server_hs_prop.server.enforce_retry = 1; + server_hs_prop.server.retry_uses_cookie = use_cookie; + + ptls_buffer_init(&cbuf, "", 0); + ptls_buffer_init(&sbuf, "", 0); + ptls_buffer_init(&decbuf, "", 0); + + client = ptls_new(ctx, 0); + + ret = ptls_handshake(client, &cbuf, NULL, NULL, NULL); + ok(ret == PTLS_ERROR_IN_PROGRESS); + ok(cbuf.off != 0); + + server = ptls_new(ctx, 1); + + consumed = cbuf.off; + ret = ptls_handshake(server, &sbuf, cbuf.base, &consumed, &server_hs_prop); + cbuf.off = 0; + + if (use_cookie) { + ok(ret == PTLS_ERROR_STATELESS_RETRY); + ptls_free(server); + server = ptls_new(ctx, 1); + } else { + ok(ret == PTLS_ERROR_IN_PROGRESS); + } + + consumed = sbuf.off; + ret = ptls_handshake(client, &cbuf, sbuf.base, &consumed, NULL); + ok(ret == PTLS_ERROR_IN_PROGRESS); + ok(sbuf.off == consumed); + sbuf.off = 0; + + consumed = cbuf.off; + ret = ptls_handshake(server, &sbuf, cbuf.base, &consumed, &server_hs_prop); + ok(ret == 0); + ok(cbuf.off == consumed); + cbuf.off = 0; + + consumed = sbuf.off; + ret = ptls_handshake(client, &cbuf, sbuf.base, &consumed, NULL); + ok(ret == 0); + ok(sbuf.off == consumed); + sbuf.off = 0; + + ret = ptls_send(client, &cbuf, "hello world", 11); + ok(ret == 0); + + consumed = cbuf.off; + ret = ptls_receive(server, &decbuf, cbuf.base, &consumed); + ok(ret == 0); + ok(cbuf.off == consumed); + cbuf.off = 0; + + ok(decbuf.off == 11); + ok(memcmp(decbuf.base, "hello world", 11) == 0); + decbuf.off = 0; + + ptls_free(client); + ptls_free(server); + + ptls_buffer_dispose(&cbuf); + ptls_buffer_dispose(&sbuf); + ptls_buffer_dispose(&decbuf); +} + +static void test_enforce_retry_stateful(void) +{ + test_enforce_retry(0); +} + +static void test_enforce_retry_stateless(void) +{ + test_enforce_retry(1); +} + +static ptls_t *stateless_hrr_prepare(ptls_buffer_t *sbuf, ptls_handshake_properties_t *server_hs_prop) +{ + ptls_t *client = ptls_new(ctx, 0), *server = ptls_new(ctx_peer, 1); + ptls_buffer_t cbuf; + size_t consumed; + int ret; + + ptls_buffer_init(&cbuf, "", 0); + ptls_buffer_init(sbuf, "", 0); + + ret = ptls_handshake(client, &cbuf, NULL, NULL, NULL); + ok(ret == PTLS_ERROR_IN_PROGRESS); + + consumed = cbuf.off; + ret = ptls_handshake(server, sbuf, cbuf.base, &consumed, server_hs_prop); + ok(ret == PTLS_ERROR_STATELESS_RETRY); + + ptls_buffer_dispose(&cbuf); + ptls_free(server); + + return client; +} + +static void test_stateless_hrr_aad_change(void) +{ + ptls_t *client, *server; + ptls_handshake_properties_t server_hs_prop = {{{{NULL}}}}; + ptls_buffer_t cbuf, sbuf; + size_t consumed; + int ret; + + server_hs_prop.server.cookie.key = "0123456789abcdef0123456789abcdef"; + server_hs_prop.server.cookie.additional_data = ptls_iovec_init("1.2.3.4:1234", 12); + server_hs_prop.server.enforce_retry = 1; + server_hs_prop.server.retry_uses_cookie = 1; + + client = stateless_hrr_prepare(&sbuf, &server_hs_prop); + ptls_buffer_init(&cbuf, "", 0); + + consumed = sbuf.off; + ret = ptls_handshake(client, &cbuf, sbuf.base, &consumed, NULL); + ok(ret == PTLS_ERROR_IN_PROGRESS); + ok(sbuf.off == consumed); + sbuf.off = 0; + + server = ptls_new(ctx_peer, 1); + server_hs_prop.server.cookie.additional_data = ptls_iovec_init("1.2.3.4:4321", 12); + + consumed = cbuf.off; + ret = ptls_handshake(server, &sbuf, cbuf.base, &consumed, &server_hs_prop); + ok(ret == PTLS_ALERT_HANDSHAKE_FAILURE); + + ptls_free(client); + ptls_free(server); + + ptls_buffer_dispose(&cbuf); + ptls_buffer_dispose(&sbuf); +} + +void test_picotls(void) +{ + subtest("sha256", test_sha256); + subtest("sha384", test_sha384); + subtest("hmac-sha256", test_hmac_sha256); + subtest("hkdf", test_hkdf); + subtest("aes128gcm", test_aes128gcm); + subtest("aes256gcm", test_aes256gcm); + subtest("chacha20poly1305", test_chacha20poly1305); + subtest("aes128ctr", test_aes128ctr); + subtest("chacha20", test_chacha20); + + subtest("fragmented-message", test_fragmented_message); + + ptls_sign_certificate_t sc = {sign_certificate}; + sc_orig = ctx_peer->sign_certificate; + ctx_peer->sign_certificate = ≻ + + subtest("full-handshake", test_full_handshake); + subtest("hrr-handshake", test_hrr_handshake); + subtest("hrr-stateless-handshake", test_hrr_stateless_handshake); + subtest("resumption", test_resumption); + subtest("resumption-different-preferred-key-share", test_resumption_different_preferred_key_share); + + subtest("enforce-retry-stateful", test_enforce_retry_stateful); + subtest("enforce-retry-stateless", test_enforce_retry_stateless); + + subtest("stateless-hrr-aad-change", test_stateless_hrr_aad_change); + + ctx_peer->sign_certificate = sc_orig; +} + +void test_key_exchange(ptls_key_exchange_algorithm_t *algo) +{ + ptls_key_exchange_context_t *ctx; + ptls_iovec_t client_pubkey, client_secret, server_pubkey, server_secret; + int ret; + + /* fail */ + ret = algo->exchange(&server_pubkey, &server_secret, (ptls_iovec_t){NULL}); + ok(ret != 0); + + /* perform ecdh */ + ret = algo->create(&ctx, &client_pubkey); + ok(ret == 0); + ret = algo->exchange(&server_pubkey, &server_secret, client_pubkey); + ok(ret == 0); + ret = ctx->on_exchange(&ctx, &client_secret, server_pubkey); + ok(ret == 0); + ok(client_secret.len == server_secret.len); + ok(memcmp(client_secret.base, server_secret.base, client_secret.len) == 0); + + free(client_secret.base); + free(server_pubkey.base); + free(server_secret.base); +} diff --git a/web/server/h2o/libh2o/deps/picotls/t/test.h b/web/server/h2o/libh2o/deps/picotls/t/test.h new file mode 100644 index 00000000..2f338764 --- /dev/null +++ b/web/server/h2o/libh2o/deps/picotls/t/test.h @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2016 DeNA Co., Ltd., Kazuho Oku + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ +#ifndef test_h +#define test_h + +#include "picotls.h" + +/* raw private key and certificate using secp256v1 */ +#define SECP256R1_PRIVATE_KEY \ + "\x92\xbe\xc7\x34\x58\xc8\xa7\x1a\x25\x22\xf0\x29\x81\xc8\xca\x33\x84\xa5\xca\x0b\x8f\x0f\x19\x94\x83\xcb\xaf\x3f\x3d\x9f\x19" \ + "\xa1" +#define SECP256R1_CERTIFICATE \ + "\x30\x82\x01\x97\x30\x82\x01\x3f\xa0\x03\x02\x01\x02\x02\x09\x00\xa5\x28\xf1\x53\xe1\x92\xb8\x1c\x30\x09\x06\x07\x2a\x86\x48" \ + "\xce\x3d\x04\x01\x30\x16\x31\x14\x30\x12\x06\x03\x55\x04\x03\x13\x0b\x65\x78\x61\x6d\x70\x6c\x65\x2e\x63\x6f\x6d\x30\x1e\x17" \ + "\x0d\x31\x36\x31\x31\x30\x33\x30\x37\x31\x33\x32\x39\x5a\x17\x0d\x32\x36\x31\x31\x30\x31\x30\x37\x31\x33\x32\x39\x5a\x30\x16" \ + "\x31\x14\x30\x12\x06\x03\x55\x04\x03\x13\x0b\x65\x78\x61\x6d\x70\x6c\x65\x2e\x63\x6f\x6d\x30\x59\x30\x13\x06\x07\x2a\x86\x48" \ + "\xce\x3d\x02\x01\x06\x08\x2a\x86\x48\xce\x3d\x03\x01\x07\x03\x42\x00\x04\x73\x47\xc4\x07\x56\x9a\x5a\x83\xa2\x49\xba\x34\x73" \ + "\x66\xd8\xb5\x95\x1e\xd6\xe9\x4e\xaf\x76\x09\x9f\x96\xb6\xb6\xab\xd3\xb9\xf0\x3e\x96\x10\x6f\xb2\xb4\x42\x93\x95\xfc\x30\x61" \ + "\x3b\xb4\x4b\xa1\x46\x92\xec\xf9\xf1\x0f\x7a\x25\x5c\x87\x29\x3e\x23\x56\x77\x91\xa3\x77\x30\x75\x30\x1d\x06\x03\x55\x1d\x0e" \ + "\x04\x16\x04\x14\x24\x7a\x07\x7b\x93\xd2\x3a\x60\x5e\xea\xb3\xdf\x21\xdf\x02\x63\x7d\x89\x40\xdd\x30\x46\x06\x03\x55\x1d\x23" \ + "\x04\x3f\x30\x3d\x80\x14\x24\x7a\x07\x7b\x93\xd2\x3a\x60\x5e\xea\xb3\xdf\x21\xdf\x02\x63\x7d\x89\x40\xdd\xa1\x1a\xa4\x18\x30" \ + "\x16\x31\x14\x30\x12\x06\x03\x55\x04\x03\x13\x0b\x65\x78\x61\x6d\x70\x6c\x65\x2e\x63\x6f\x6d\x82\x09\x00\xa5\x28\xf1\x53\xe1" \ + "\x92\xb8\x1c\x30\x0c\x06\x03\x55\x1d\x13\x04\x05\x30\x03\x01\x01\xff\x30\x09\x06\x07\x2a\x86\x48\xce\x3d\x04\x01\x03\x47\x00" \ + "\x30\x44\x02\x20\x3f\xfc\x14\x45\xa4\xc6\x21\x37\xa9\x4a\x6b\x79\x4d\x86\xea\x48\x2c\xa8\xea\xb8\x18\xd9\xc9\x94\xd0\x15\x38" \ + "\xa5\xfd\x23\xf1\xb0\x02\x20\x2e\xd4\x93\xfe\x19\xfa\x31\x82\xa0\xfe\xa2\x04\xbd\xf4\x8b\x68\xdb\xee\x7a\xe8\x33\x2c\xe1\x35" \ + "\x6d\xdc\x08\x37\xfd\x49\x35\x90" + +extern ptls_context_t *ctx, *ctx_peer; + +void test_key_exchange(ptls_key_exchange_algorithm_t *algo); +void test_picotls(void); + +#endif diff --git a/web/server/h2o/libh2o/deps/picotls/t/util.h b/web/server/h2o/libh2o/deps/picotls/t/util.h new file mode 100644 index 00000000..78ce87c3 --- /dev/null +++ b/web/server/h2o/libh2o/deps/picotls/t/util.h @@ -0,0 +1,240 @@ +/* + * Copyright (c) 2016,2017 DeNA Co., Ltd., Kazuho Oku, Fastly + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ +#ifndef util_h +#define util_h + +#ifndef _XOPEN_SOURCE +#define _XOPEN_SOURCE 700 /* required for glibc to use getaddrinfo, etc. */ +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "picotls/openssl.h" + +static inline void load_certificate_chain(ptls_context_t *ctx, const char *fn) +{ + if (ptls_load_certificates(ctx, (char *)fn) != 0) { + fprintf(stderr, "failed to load certificate:%s:%s\n", fn, strerror(errno)); + exit(1); + } +} + +static inline void load_private_key(ptls_context_t *ctx, const char *fn) +{ + static ptls_openssl_sign_certificate_t sc; + FILE *fp; + EVP_PKEY *pkey; + + if ((fp = fopen(fn, "rb")) == NULL) { + fprintf(stderr, "failed to open file:%s:%s\n", fn, strerror(errno)); + exit(1); + } + pkey = PEM_read_PrivateKey(fp, NULL, NULL, NULL); + fclose(fp); + + if (pkey == NULL) { + fprintf(stderr, "failed to read private key from file:%s\n", fn); + exit(1); + } + + ptls_openssl_init_sign_certificate(&sc, pkey); + EVP_PKEY_free(pkey); + + ctx->sign_certificate = &sc.super; +} + +struct st_util_save_ticket_t { + ptls_save_ticket_t super; + char fn[MAXPATHLEN]; +}; + +static int save_ticket_cb(ptls_save_ticket_t *_self, ptls_t *tls, ptls_iovec_t src) +{ + struct st_util_save_ticket_t *self = (void *)_self; + FILE *fp; + + if ((fp = fopen(self->fn, "wb")) == NULL) { + fprintf(stderr, "failed to open file:%s:%s\n", self->fn, strerror(errno)); + return PTLS_ERROR_LIBRARY; + } + fwrite(src.base, 1, src.len, fp); + fclose(fp); + + return 0; +} + +static inline void setup_session_file(ptls_context_t *ctx, ptls_handshake_properties_t *hsprop, const char *fn) +{ + static struct st_util_save_ticket_t st; + FILE *fp; + + /* setup save_ticket callback */ + strcpy(st.fn, fn); + st.super.cb = save_ticket_cb; + ctx->save_ticket = &st.super; + + /* load session ticket if possible */ + if ((fp = fopen(fn, "rb")) != NULL) { + static uint8_t ticket[16384]; + size_t ticket_size = fread(ticket, 1, sizeof(ticket), fp); + if (ticket_size == 0 || !feof(fp)) { + fprintf(stderr, "failed to load ticket from file:%s\n", fn); + exit(1); + } + fclose(fp); + hsprop->client.session_ticket = ptls_iovec_init(ticket, ticket_size); + } +} + +static inline void setup_verify_certificate(ptls_context_t *ctx) +{ + static ptls_openssl_verify_certificate_t vc; + ptls_openssl_init_verify_certificate(&vc, NULL); + ctx->verify_certificate = &vc.super; +} + +struct st_util_log_secret_t { + ptls_log_secret_t super; + FILE *fp; +}; + +static void fprinthex(FILE *fp, ptls_iovec_t vec) +{ + size_t i; + for (i = 0; i != vec.len; ++i) + fprintf(fp, "%02x", vec.base[i]); +} + +static void log_secret_cb(ptls_log_secret_t *_self, ptls_t *tls, const char *label, ptls_iovec_t secret) +{ + struct st_util_log_secret_t *self = (void *)_self; + + fprintf(self->fp, "%s ", label); + fprinthex(self->fp, ptls_get_client_random(tls)); + fprintf(self->fp, " "); + fprinthex(self->fp, secret); + fprintf(self->fp, "\n"); + fflush(self->fp); +} + +static inline void setup_log_secret(ptls_context_t *ctx, const char *fn) +{ + static struct st_util_log_secret_t ls; + + if ((ls.fp = fopen(fn, "at")) == NULL) { + fprintf(stderr, "failed to open file:%s:%s\n", fn, strerror(errno)); + exit(1); + } + ls.super.cb = log_secret_cb; + ctx->log_secret = &ls.super; +} + +/* single-entry session cache */ +struct st_util_session_cache_t { + ptls_encrypt_ticket_t super; + uint8_t id[32]; + ptls_iovec_t data; +}; + +static int encrypt_ticket_cb(ptls_encrypt_ticket_t *_self, ptls_t *tls, int is_encrypt, ptls_buffer_t *dst, ptls_iovec_t src) +{ + struct st_util_session_cache_t *self = (void *)_self; + int ret; + + if (is_encrypt) { + + /* replace the cached entry along with a newly generated session id */ + free(self->data.base); + if ((self->data.base = malloc(src.len)) == NULL) + return PTLS_ERROR_NO_MEMORY; + + ptls_get_context(tls)->random_bytes(self->id, sizeof(self->id)); + memcpy(self->data.base, src.base, src.len); + self->data.len = src.len; + + /* store the session id in buffer */ + if ((ret = ptls_buffer_reserve(dst, sizeof(self->id))) != 0) + return ret; + memcpy(dst->base + dst->off, self->id, sizeof(self->id)); + dst->off += sizeof(self->id); + + } else { + + /* check if session id is the one stored in cache */ + if (src.len != sizeof(self->id)) + return PTLS_ERROR_SESSION_NOT_FOUND; + if (memcmp(self->id, src.base, sizeof(self->id)) != 0) + return PTLS_ERROR_SESSION_NOT_FOUND; + + /* return the cached value */ + if ((ret = ptls_buffer_reserve(dst, self->data.len)) != 0) + return ret; + memcpy(dst->base + dst->off, self->data.base, self->data.len); + dst->off += self->data.len; + } + + return 0; +} + +static inline void setup_session_cache(ptls_context_t *ctx) +{ + static struct st_util_session_cache_t sc; + + sc.super.cb = encrypt_ticket_cb; + + ctx->ticket_lifetime = 86400; + ctx->max_early_data_size = 8192; + ctx->encrypt_ticket = &sc.super; +} + +static inline int resolve_address(struct sockaddr *sa, socklen_t *salen, const char *host, const char *port, int family, int type, + int proto) +{ + struct addrinfo hints, *res; + int err; + + memset(&hints, 0, sizeof(hints)); + hints.ai_family = family; + hints.ai_socktype = type; + hints.ai_protocol = proto; + hints.ai_flags = AI_ADDRCONFIG | AI_NUMERICSERV | AI_PASSIVE; + if ((err = getaddrinfo(host, port, &hints, &res)) != 0 || res == NULL) { + fprintf(stderr, "failed to resolve address:%s:%s:%s\n", host, port, + err != 0 ? gai_strerror(err) : "getaddrinfo returned NULL"); + return -1; + } + + memcpy(sa, res->ai_addr, res->ai_addrlen); + *salen = res->ai_addrlen; + + freeaddrinfo(res); + return 0; +} + +#endif diff --git a/web/server/h2o/libh2o/deps/ssl-conservatory/.gitattributes b/web/server/h2o/libh2o/deps/ssl-conservatory/.gitattributes new file mode 100644 index 00000000..7d61439d --- /dev/null +++ b/web/server/h2o/libh2o/deps/ssl-conservatory/.gitattributes @@ -0,0 +1,5 @@ +# These files are text and should be normalized (convert crlf => lf) +*.c text +*.h text +*.txt text +*.md text diff --git a/web/server/h2o/libh2o/deps/ssl-conservatory/.gitignore b/web/server/h2o/libh2o/deps/ssl-conservatory/.gitignore new file mode 100644 index 00000000..3b15853b --- /dev/null +++ b/web/server/h2o/libh2o/deps/ssl-conservatory/.gitignore @@ -0,0 +1,34 @@ +# Compiled Object files +*.slo +*.lo +*.o + +# Compiled Dynamic libraries +*.so + +# Compiled Static libraries +*.lai +*.la +*.a + +# Windows binaries +*.exe + +# Xcode +.DS_Store +build/ +*.pbxuser +!default.pbxuser +*.mode1v3 +!default.mode1v3 +*.mode2v3 +!default.mode2v3 +*.perspectivev3 +!default.perspectivev3 +*.xcworkspace +!default.xcworkspace +xcuserdata +profile +*.moved-aside +DerivedData +.idea/ diff --git a/web/server/h2o/libh2o/deps/ssl-conservatory/LICENSE b/web/server/h2o/libh2o/deps/ssl-conservatory/LICENSE new file mode 100644 index 00000000..fe3a4167 --- /dev/null +++ b/web/server/h2o/libh2o/deps/ssl-conservatory/LICENSE @@ -0,0 +1,19 @@ +Copyright (C) 2012, iSEC Partners. + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is furnished to do +so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/web/server/h2o/libh2o/deps/ssl-conservatory/README.md b/web/server/h2o/libh2o/deps/ssl-conservatory/README.md new file mode 100644 index 00000000..8000ec47 --- /dev/null +++ b/web/server/h2o/libh2o/deps/ssl-conservatory/README.md @@ -0,0 +1,28 @@ +The SSL Conservatory +==================== + +Correct implementation of SSL is crucial to secure transmission of data +between clients and servers. However, this crucial task is frequently done +improperly, due to complex APIs and lack of understanding of SSL fundamentals. + +This is intended to be a clearinghouse for well-documented and secure sample +code to correctly implement SSL clients. Pull requests with examples for +other languages or frameworks are encouraged. + + +Content +------- + +### openssl/ + +Whitepaper and sample code on how to perform certificate validation within an +SSL client using the OpenSSL library. + +### ios/ +SSL certificate pinning implementation for iOS applications. + + +License +------- + +See LICENSE. \ No newline at end of file diff --git a/web/server/h2o/libh2o/deps/ssl-conservatory/ios/README.md b/web/server/h2o/libh2o/deps/ssl-conservatory/ios/README.md new file mode 100644 index 00000000..34bf4eda --- /dev/null +++ b/web/server/h2o/libh2o/deps/ssl-conservatory/ios/README.md @@ -0,0 +1,89 @@ +The SSL Conservatory: iOS Certificate Pinning +============================================= + + +When an iOS application only needs to communicate to a well-defined set of +servers over SSL or HTTPS, the security of the app's network communications can +be improved through SSL pinning. By requiring a specific certificate to be part +of the server's certificate chain, the threat of a rogue CA or a CA compromise +is significantly reduced. + + +### The ISPCertificatePinning class + +#### Description + +This class allows developers to whitelist a list of certificates for a given +domain in order to require at least one these "pinned" certificates to be part +of the server's certificate chain received when connecting to the domain over +SSL or HTTPS. + +This gives developers the flexibility to pin the CA/anchor certificate, the +server/leaf certificate, or any intermediate certificate for a given domain. +Each option has different advantages and limitations; for example, pinning the +server/leaf certificate provides the best security but this certificate is going +to change more often than the CA/anchor certificate. + +A change in the certificate presented by the server (for example because the +previous certificate expired) will result in the application being unable to +connect to the server until its pinned certificate has been updated as well. +To address this scenario, multiple certificates can be pinned to a single +domain. This gives developers the ability to transition from an expiring +certificate to a new one by releasing a new version of their application that +pins both certificates to the server's domain. + + +#### API + +The ISPCertificatePinning class exposes two methods: + +##### +(BOOL)setupSSLPinsUsingDictionnary:(NSDictionary*)domainsAndCertificates +This method takes a dictionary with domain names as keys and arrays of +DER-encoded certificates as values, and stores them in a pre-defined location on +the filesystem. The ability to specify multiple certificates for a single +domain is useful when transitioning from an expiring certificate to a new one + +##### +(BOOL)verifyPinnedCertificateForTrust:(SecTrustRef)trust andDomain:(NSString*)domain +This method accesses the certificates previously loaded using the +setupSSLPinsUsingDictionnary: method and inspects the trust object's +certificate chain in order to find at least one certificate pinned to the +given domain. SecTrustEvaluate() should always be called before this method to +ensure that the certificate chain is valid. + + +### Convenience delegate classes for NSURLConnection and NSURLSession + +This library also provides convenience classes for connections relying on +NSURLConnection and NSURLSession. The ISPPinnedNSURLConnectionDelegate and +ISPPinnedNSURLSessionDelegate implement the connection authentication methods +within respectively the NSURLConnectionDelegate and NSURLSessionDelegate +protocols, in order to automatically validate the server's certificate based on +SSL pins loaded using the setupSSLPinsUsingDictionnary: method. + +To implement certificate pinning in their Apps, developers should simply extend +these classes when creating their own connection delegates. + + +### Sample code + +The Xcode unit tests within SSLCertificatePinningTests contain sample code +demonstrating how to implement certificate pinning when using NSURLConnection +and NSURLSession. + + +### Changelog + +* v3: Turned the Xcode project into a static library. + Added certificate pinning delegate class for NSURLSession connections. +* v2: Added the ability to pin multiple certificates to a single domain. +* v1: Initial release. + + +### License + +See ../LICENSE. + + +### Author + +Alban Diquet - https://github.com/nabla-c0d3 diff --git a/web/server/h2o/libh2o/deps/ssl-conservatory/ios/SSLCertificatePinning/SSLCertificatePinning.xcodeproj/project.pbxproj b/web/server/h2o/libh2o/deps/ssl-conservatory/ios/SSLCertificatePinning/SSLCertificatePinning.xcodeproj/project.pbxproj new file mode 100644 index 00000000..84ee1521 --- /dev/null +++ b/web/server/h2o/libh2o/deps/ssl-conservatory/ios/SSLCertificatePinning/SSLCertificatePinning.xcodeproj/project.pbxproj @@ -0,0 +1,456 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + objects = { + +/* Begin PBXBuildFile section */ + 8C40DA3C188600A600A231CD /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8C40DA3B188600A600A231CD /* Foundation.framework */; }; + 8C40DA41188600A600A231CD /* ISPCertificatePinning.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 8C40DA40188600A600A231CD /* ISPCertificatePinning.h */; }; + 8C40DA43188600A600A231CD /* ISPCertificatePinning.m in Sources */ = {isa = PBXBuildFile; fileRef = 8C40DA42188600A600A231CD /* ISPCertificatePinning.m */; }; + 8C40DA4A188600A600A231CD /* XCTest.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8C40DA49188600A600A231CD /* XCTest.framework */; }; + 8C40DA4B188600A600A231CD /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8C40DA3B188600A600A231CD /* Foundation.framework */; }; + 8C40DA4D188600A600A231CD /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8C40DA4C188600A600A231CD /* UIKit.framework */; }; + 8C40DA50188600A600A231CD /* libSSLCertificatePinning.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 8C40DA38188600A600A231CD /* libSSLCertificatePinning.a */; }; + 8C40DA56188600A600A231CD /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 8C40DA54188600A600A231CD /* InfoPlist.strings */; }; + 8C40DA631886017400A231CD /* ISPPinnedNSURLConnectionDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 8C40DA621886017400A231CD /* ISPPinnedNSURLConnectionDelegate.m */; }; + 8C40DA661886045C00A231CD /* ISPPinnedNSURLSessionDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 8C40DA651886045C00A231CD /* ISPPinnedNSURLSessionDelegate.m */; }; + 8C40DA681886071000A231CD /* NSURLConnectionTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 8C40DA671886071000A231CD /* NSURLConnectionTests.m */; }; + 8C40DA6A1886071C00A231CD /* NSURLSessionTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 8C40DA691886071C00A231CD /* NSURLSessionTests.m */; }; + 8C40DA6D1886080800A231CD /* VeriSignClass3PublicPrimaryCertificationAuthority-G5.der in Resources */ = {isa = PBXBuildFile; fileRef = 8C40DA6C1886080800A231CD /* VeriSignClass3PublicPrimaryCertificationAuthority-G5.der */; }; + 8C40DA6F1886142800A231CD /* www.isecpartners.com.der in Resources */ = {isa = PBXBuildFile; fileRef = 8C40DA6E1886142800A231CD /* www.isecpartners.com.der */; }; + 8CC9C1F9189EF097000525D6 /* SSLPinsTestUtility.m in Sources */ = {isa = PBXBuildFile; fileRef = 8CC9C1F8189EF097000525D6 /* SSLPinsTestUtility.m */; }; +/* End PBXBuildFile section */ + +/* Begin PBXContainerItemProxy section */ + 8C40DA4E188600A600A231CD /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 8C40DA30188600A600A231CD /* Project object */; + proxyType = 1; + remoteGlobalIDString = 8C40DA37188600A600A231CD; + remoteInfo = SSLCertificatePinning; + }; +/* End PBXContainerItemProxy section */ + +/* Begin PBXCopyFilesBuildPhase section */ + 8C40DA36188600A600A231CD /* CopyFiles */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = "include/$(PRODUCT_NAME)"; + dstSubfolderSpec = 16; + files = ( + 8C40DA41188600A600A231CD /* ISPCertificatePinning.h in CopyFiles */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXCopyFilesBuildPhase section */ + +/* Begin PBXFileReference section */ + 8C40DA38188600A600A231CD /* libSSLCertificatePinning.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libSSLCertificatePinning.a; sourceTree = BUILT_PRODUCTS_DIR; }; + 8C40DA3B188600A600A231CD /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; + 8C40DA3F188600A600A231CD /* SSLCertificatePinning-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "SSLCertificatePinning-Prefix.pch"; sourceTree = ""; }; + 8C40DA40188600A600A231CD /* ISPCertificatePinning.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ISPCertificatePinning.h; sourceTree = ""; }; + 8C40DA42188600A600A231CD /* ISPCertificatePinning.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ISPCertificatePinning.m; sourceTree = ""; }; + 8C40DA48188600A600A231CD /* SSLCertificatePinningTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = SSLCertificatePinningTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + 8C40DA49188600A600A231CD /* XCTest.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = XCTest.framework; path = Library/Frameworks/XCTest.framework; sourceTree = DEVELOPER_DIR; }; + 8C40DA4C188600A600A231CD /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = Library/Frameworks/UIKit.framework; sourceTree = DEVELOPER_DIR; }; + 8C40DA53188600A600A231CD /* SSLCertificatePinningTests-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "SSLCertificatePinningTests-Info.plist"; sourceTree = ""; }; + 8C40DA55188600A600A231CD /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = ""; }; + 8C40DA611886017400A231CD /* ISPPinnedNSURLConnectionDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ISPPinnedNSURLConnectionDelegate.h; sourceTree = ""; }; + 8C40DA621886017400A231CD /* ISPPinnedNSURLConnectionDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ISPPinnedNSURLConnectionDelegate.m; sourceTree = ""; }; + 8C40DA641886045C00A231CD /* ISPPinnedNSURLSessionDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ISPPinnedNSURLSessionDelegate.h; sourceTree = ""; }; + 8C40DA651886045C00A231CD /* ISPPinnedNSURLSessionDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ISPPinnedNSURLSessionDelegate.m; sourceTree = ""; }; + 8C40DA671886071000A231CD /* NSURLConnectionTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NSURLConnectionTests.m; sourceTree = ""; }; + 8C40DA691886071C00A231CD /* NSURLSessionTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NSURLSessionTests.m; sourceTree = ""; }; + 8C40DA6C1886080800A231CD /* VeriSignClass3PublicPrimaryCertificationAuthority-G5.der */ = {isa = PBXFileReference; lastKnownFileType = file; path = "VeriSignClass3PublicPrimaryCertificationAuthority-G5.der"; sourceTree = ""; }; + 8C40DA6E1886142800A231CD /* www.isecpartners.com.der */ = {isa = PBXFileReference; lastKnownFileType = file; path = www.isecpartners.com.der; sourceTree = ""; }; + 8CC9C1F7189EF097000525D6 /* SSLPinsTestUtility.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SSLPinsTestUtility.h; sourceTree = ""; }; + 8CC9C1F8189EF097000525D6 /* SSLPinsTestUtility.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SSLPinsTestUtility.m; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 8C40DA35188600A600A231CD /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 8C40DA3C188600A600A231CD /* Foundation.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 8C40DA45188600A600A231CD /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 8C40DA50188600A600A231CD /* libSSLCertificatePinning.a in Frameworks */, + 8C40DA4A188600A600A231CD /* XCTest.framework in Frameworks */, + 8C40DA4D188600A600A231CD /* UIKit.framework in Frameworks */, + 8C40DA4B188600A600A231CD /* Foundation.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 8C40DA2F188600A600A231CD = { + isa = PBXGroup; + children = ( + 8C40DA3D188600A600A231CD /* SSLCertificatePinning */, + 8C40DA51188600A600A231CD /* SSLCertificatePinningTests */, + 8C40DA3A188600A600A231CD /* Frameworks */, + 8C40DA39188600A600A231CD /* Products */, + ); + sourceTree = ""; + }; + 8C40DA39188600A600A231CD /* Products */ = { + isa = PBXGroup; + children = ( + 8C40DA38188600A600A231CD /* libSSLCertificatePinning.a */, + 8C40DA48188600A600A231CD /* SSLCertificatePinningTests.xctest */, + ); + name = Products; + sourceTree = ""; + }; + 8C40DA3A188600A600A231CD /* Frameworks */ = { + isa = PBXGroup; + children = ( + 8C40DA3B188600A600A231CD /* Foundation.framework */, + 8C40DA49188600A600A231CD /* XCTest.framework */, + 8C40DA4C188600A600A231CD /* UIKit.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; + 8C40DA3D188600A600A231CD /* SSLCertificatePinning */ = { + isa = PBXGroup; + children = ( + 8C40DA40188600A600A231CD /* ISPCertificatePinning.h */, + 8C40DA42188600A600A231CD /* ISPCertificatePinning.m */, + 8C40DA3E188600A600A231CD /* Supporting Files */, + 8C40DA611886017400A231CD /* ISPPinnedNSURLConnectionDelegate.h */, + 8C40DA641886045C00A231CD /* ISPPinnedNSURLSessionDelegate.h */, + 8C40DA651886045C00A231CD /* ISPPinnedNSURLSessionDelegate.m */, + 8C40DA621886017400A231CD /* ISPPinnedNSURLConnectionDelegate.m */, + ); + path = SSLCertificatePinning; + sourceTree = ""; + }; + 8C40DA3E188600A600A231CD /* Supporting Files */ = { + isa = PBXGroup; + children = ( + 8C40DA3F188600A600A231CD /* SSLCertificatePinning-Prefix.pch */, + ); + name = "Supporting Files"; + sourceTree = ""; + }; + 8C40DA51188600A600A231CD /* SSLCertificatePinningTests */ = { + isa = PBXGroup; + children = ( + 8C40DA6E1886142800A231CD /* www.isecpartners.com.der */, + 8C40DA6C1886080800A231CD /* VeriSignClass3PublicPrimaryCertificationAuthority-G5.der */, + 8C40DA671886071000A231CD /* NSURLConnectionTests.m */, + 8C40DA691886071C00A231CD /* NSURLSessionTests.m */, + 8CC9C1F7189EF097000525D6 /* SSLPinsTestUtility.h */, + 8CC9C1F8189EF097000525D6 /* SSLPinsTestUtility.m */, + 8C40DA52188600A600A231CD /* Supporting Files */, + ); + path = SSLCertificatePinningTests; + sourceTree = ""; + }; + 8C40DA52188600A600A231CD /* Supporting Files */ = { + isa = PBXGroup; + children = ( + 8C40DA53188600A600A231CD /* SSLCertificatePinningTests-Info.plist */, + 8C40DA54188600A600A231CD /* InfoPlist.strings */, + ); + name = "Supporting Files"; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 8C40DA37188600A600A231CD /* SSLCertificatePinning */ = { + isa = PBXNativeTarget; + buildConfigurationList = 8C40DA5B188600A600A231CD /* Build configuration list for PBXNativeTarget "SSLCertificatePinning" */; + buildPhases = ( + 8C40DA34188600A600A231CD /* Sources */, + 8C40DA35188600A600A231CD /* Frameworks */, + 8C40DA36188600A600A231CD /* CopyFiles */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = SSLCertificatePinning; + productName = SSLCertificatePinning; + productReference = 8C40DA38188600A600A231CD /* libSSLCertificatePinning.a */; + productType = "com.apple.product-type.library.static"; + }; + 8C40DA47188600A600A231CD /* SSLCertificatePinningTests */ = { + isa = PBXNativeTarget; + buildConfigurationList = 8C40DA5E188600A600A231CD /* Build configuration list for PBXNativeTarget "SSLCertificatePinningTests" */; + buildPhases = ( + 8C40DA44188600A600A231CD /* Sources */, + 8C40DA45188600A600A231CD /* Frameworks */, + 8C40DA46188600A600A231CD /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + 8C40DA4F188600A600A231CD /* PBXTargetDependency */, + ); + name = SSLCertificatePinningTests; + productName = SSLCertificatePinningTests; + productReference = 8C40DA48188600A600A231CD /* SSLCertificatePinningTests.xctest */; + productType = "com.apple.product-type.bundle.unit-test"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 8C40DA30188600A600A231CD /* Project object */ = { + isa = PBXProject; + attributes = { + LastUpgradeCheck = 0500; + ORGANIZATIONNAME = "iSEC Partners"; + }; + buildConfigurationList = 8C40DA33188600A600A231CD /* Build configuration list for PBXProject "SSLCertificatePinning" */; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = English; + hasScannedForEncodings = 0; + knownRegions = ( + en, + ); + mainGroup = 8C40DA2F188600A600A231CD; + productRefGroup = 8C40DA39188600A600A231CD /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 8C40DA37188600A600A231CD /* SSLCertificatePinning */, + 8C40DA47188600A600A231CD /* SSLCertificatePinningTests */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 8C40DA46188600A600A231CD /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 8C40DA6D1886080800A231CD /* VeriSignClass3PublicPrimaryCertificationAuthority-G5.der in Resources */, + 8C40DA6F1886142800A231CD /* www.isecpartners.com.der in Resources */, + 8C40DA56188600A600A231CD /* InfoPlist.strings in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 8C40DA34188600A600A231CD /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 8C40DA43188600A600A231CD /* ISPCertificatePinning.m in Sources */, + 8C40DA631886017400A231CD /* ISPPinnedNSURLConnectionDelegate.m in Sources */, + 8C40DA661886045C00A231CD /* ISPPinnedNSURLSessionDelegate.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 8C40DA44188600A600A231CD /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 8C40DA681886071000A231CD /* NSURLConnectionTests.m in Sources */, + 8C40DA6A1886071C00A231CD /* NSURLSessionTests.m in Sources */, + 8CC9C1F9189EF097000525D6 /* SSLPinsTestUtility.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXTargetDependency section */ + 8C40DA4F188600A600A231CD /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 8C40DA37188600A600A231CD /* SSLCertificatePinning */; + targetProxy = 8C40DA4E188600A600A231CD /* PBXContainerItemProxy */; + }; +/* End PBXTargetDependency section */ + +/* Begin PBXVariantGroup section */ + 8C40DA54188600A600A231CD /* InfoPlist.strings */ = { + isa = PBXVariantGroup; + children = ( + 8C40DA55188600A600A231CD /* en */, + ); + name = InfoPlist.strings; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 8C40DA59188600A600A231CD /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ARCHS = "$(ARCHS_STANDARD_INCLUDING_64_BIT)"; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_DYNAMIC_NO_PIC = NO; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_SYMBOLS_PRIVATE_EXTERN = NO; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 7.0; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + }; + name = Debug; + }; + 8C40DA5A188600A600A231CD /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ARCHS = "$(ARCHS_STANDARD_INCLUDING_64_BIT)"; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = YES; + ENABLE_NS_ASSERTIONS = NO; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 7.0; + SDKROOT = iphoneos; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 8C40DA5C188600A600A231CD /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + DSTROOT = /tmp/SSLCertificatePinning.dst; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = "SSLCertificatePinning/SSLCertificatePinning-Prefix.pch"; + OTHER_LDFLAGS = "-ObjC"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SKIP_INSTALL = YES; + }; + name = Debug; + }; + 8C40DA5D188600A600A231CD /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + DSTROOT = /tmp/SSLCertificatePinning.dst; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = "SSLCertificatePinning/SSLCertificatePinning-Prefix.pch"; + OTHER_LDFLAGS = "-ObjC"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SKIP_INSTALL = YES; + }; + name = Release; + }; + 8C40DA5F188600A600A231CD /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = "$(ARCHS_STANDARD_INCLUDING_64_BIT)"; + FRAMEWORK_SEARCH_PATHS = ( + "$(SDKROOT)/Developer/Library/Frameworks", + "$(inherited)", + "$(DEVELOPER_FRAMEWORKS_DIR)", + ); + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = "SSLCertificatePinning/SSLCertificatePinning-Prefix.pch"; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + INFOPLIST_FILE = "SSLCertificatePinningTests/SSLCertificatePinningTests-Info.plist"; + PRODUCT_NAME = "$(TARGET_NAME)"; + WRAPPER_EXTENSION = xctest; + }; + name = Debug; + }; + 8C40DA60188600A600A231CD /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = "$(ARCHS_STANDARD_INCLUDING_64_BIT)"; + FRAMEWORK_SEARCH_PATHS = ( + "$(SDKROOT)/Developer/Library/Frameworks", + "$(inherited)", + "$(DEVELOPER_FRAMEWORKS_DIR)", + ); + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = "SSLCertificatePinning/SSLCertificatePinning-Prefix.pch"; + INFOPLIST_FILE = "SSLCertificatePinningTests/SSLCertificatePinningTests-Info.plist"; + PRODUCT_NAME = "$(TARGET_NAME)"; + WRAPPER_EXTENSION = xctest; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 8C40DA33188600A600A231CD /* Build configuration list for PBXProject "SSLCertificatePinning" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 8C40DA59188600A600A231CD /* Debug */, + 8C40DA5A188600A600A231CD /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 8C40DA5B188600A600A231CD /* Build configuration list for PBXNativeTarget "SSLCertificatePinning" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 8C40DA5C188600A600A231CD /* Debug */, + 8C40DA5D188600A600A231CD /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 8C40DA5E188600A600A231CD /* Build configuration list for PBXNativeTarget "SSLCertificatePinningTests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 8C40DA5F188600A600A231CD /* Debug */, + 8C40DA60188600A600A231CD /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 8C40DA30188600A600A231CD /* Project object */; +} diff --git a/web/server/h2o/libh2o/deps/ssl-conservatory/ios/SSLCertificatePinning/SSLCertificatePinning/ISPCertificatePinning.h b/web/server/h2o/libh2o/deps/ssl-conservatory/ios/SSLCertificatePinning/SSLCertificatePinning/ISPCertificatePinning.h new file mode 100644 index 00000000..fddc504e --- /dev/null +++ b/web/server/h2o/libh2o/deps/ssl-conservatory/ios/SSLCertificatePinning/SSLCertificatePinning/ISPCertificatePinning.h @@ -0,0 +1,62 @@ +// +// ISPCertificatePinning.h +// SSLCertificatePinning v3 +// +// Created by Alban Diquet on 1/14/14. +// Copyright (c) 2014 iSEC Partners. All rights reserved. +// + + +/** This class implements certificate pinning utility functions. + + First, the certificates and domains to pin should be loaded using + setupSSLPinsUsingDictionnary:. This method will store them in + "~/Library/SSLPins.plist". + + Then, the verifyPinnedCertificateForTrust:andDomain: method can be + used to validate that at least one the certificates pinned to a + specific domain is in the server's certificate chain when connecting to + it. This method should be used for example in the + connection:willSendRequestForAuthenticationChallenge: method of the + NSURLConnectionDelegate object that is used to perform the connection. + + Alternatively, the ISPPinnedNSURLSessionDelegate or + ISPPinnedNSURLConnectionDelegate classes can be directly used + to create a delegate class performing certificate pinning. + + */ +@interface ISPCertificatePinning : NSObject + + +/** + Certificate pinning loading method + + This method takes a dictionary with domain names as keys and arrays of DER- + encoded certificates as values, and stores them in a pre-defined location on + the filesystem. The ability to specify multiple certificates for a single + domain is useful when transitioning from an expiring certificate to a new one. + + @param certificates a dictionnary with domain names as keys and arrays of DER-encoded certificates as values + @return BOOL successfully loaded the public keys and domains + + */ ++ (BOOL)setupSSLPinsUsingDictionnary:(NSDictionary*)domainsAndCertificates; + + +/** + Certificate pinning validation method + + This method accesses the certificates previously loaded using the + setupSSLPinsUsingDictionnary: method and inspects the trust object's + certificate chain in order to find at least one certificate pinned to the + given domain. SecTrustEvaluate() should always be called before this method to + ensure that the certificate chain is valid. + + @param trust the trust object whose certificate chain must contain the certificate previously pinned to the given domain + @param domain the domain we're trying to connect to + @return BOOL found the domain's pinned certificate in the trust object's certificate chain + + */ ++ (BOOL)verifyPinnedCertificateForTrust:(SecTrustRef)trust andDomain:(NSString*)domain; + +@end diff --git a/web/server/h2o/libh2o/deps/ssl-conservatory/ios/SSLCertificatePinning/SSLCertificatePinning/ISPCertificatePinning.m b/web/server/h2o/libh2o/deps/ssl-conservatory/ios/SSLCertificatePinning/SSLCertificatePinning/ISPCertificatePinning.m new file mode 100644 index 00000000..584b974f --- /dev/null +++ b/web/server/h2o/libh2o/deps/ssl-conservatory/ios/SSLCertificatePinning/SSLCertificatePinning/ISPCertificatePinning.m @@ -0,0 +1,112 @@ +// +// ISPCertificatePinning.m +// SSLCertificatePinning +// +// Created by Alban Diquet on 1/14/14. +// Copyright (c) 2014 iSEC Partners. All rights reserved. +// + +#import "ISPCertificatePinning.h" + + +// All the pinned certificate are stored in this plist on the filesystem +#define PINNED_KEYS_FILE_PATH "~/Library/SSLPins.plist" + + +@implementation ISPCertificatePinning + + + ++ (BOOL)setupSSLPinsUsingDictionnary:(NSDictionary*)domainsAndCertificates { + if (domainsAndCertificates == nil) { + return NO; + } + + // Serialize the dictionary to a plist + NSError *error; + NSData *plistData = [NSPropertyListSerialization dataWithPropertyList:domainsAndCertificates + format:NSPropertyListXMLFormat_v1_0 + options:0 + error:&error]; + if (plistData == nil) { + NSLog(@"Error serializing plist: %@", error); + return NO; + } + + // Write the plist to a pre-defined location on the filesystem + NSError *writeError; + if ([plistData writeToFile:[@PINNED_KEYS_FILE_PATH stringByExpandingTildeInPath] + options:NSDataWritingAtomic + error:&writeError] == NO) { + NSLog(@"Error saving plist to the filesystem: %@", writeError); + return NO; + } + + return YES; +} + + ++ (BOOL)verifyPinnedCertificateForTrust:(SecTrustRef)trust andDomain:(NSString*)domain { + if ((trust == NULL) || (domain == nil)) { + return NO; + } + + // Deserialize the plist that contains our SSL pins + NSDictionary *SSLPinsDict = [NSDictionary dictionaryWithContentsOfFile:[@PINNED_KEYS_FILE_PATH stringByExpandingTildeInPath]]; + if (SSLPinsDict == nil) { + NSLog(@"Error accessing the SSL Pins plist at %@", @PINNED_KEYS_FILE_PATH); + return NO; + } + + // Do we have certificates pinned for this domain ? + NSArray *trustedCertificates = [SSLPinsDict objectForKey:domain]; + if ((trustedCertificates == nil) || ([trustedCertificates count] < 1)) { + return NO; + } + + // For each pinned certificate, check if it is part of the server's cert trust chain + // We only need one of the pinned certificates to be in the server's trust chain + for (NSData *pinnedCertificate in trustedCertificates) { + + // Check each certificate in the server's trust chain (the trust object) + // Unfortunately the anchor/CA certificate cannot be accessed this way + CFIndex certsNb = SecTrustGetCertificateCount(trust); + for(int i=0;i + +#import "ISPPinnedNSURLSessionDelegate.h" +#import "ISPCertificatePinning.h" + + +@implementation ISPPinnedNSURLSessionDelegate + +- (void)URLSession:(NSURLSession *)session didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition disposition, NSURLCredential *credential))completionHandler { + + if([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust]) { + + SecTrustRef serverTrust = [[challenge protectionSpace] serverTrust]; + NSString *domain = [[challenge protectionSpace] host]; + SecTrustResultType trustResult; + + // Validate the certificate chain with the device's trust store anyway + // This *might* give use revocation checking + SecTrustEvaluate(serverTrust, &trustResult); + if (trustResult == kSecTrustResultUnspecified) { + + // Look for a pinned certificate in the server's certificate chain + if ([ISPCertificatePinning verifyPinnedCertificateForTrust:serverTrust andDomain:domain]) { + + // Found the certificate; continue connecting + completionHandler(NSURLSessionAuthChallengeUseCredential, [NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust]); + } + else { + // The certificate wasn't found in the certificate chain; cancel the connection + completionHandler(NSURLSessionAuthChallengeCancelAuthenticationChallenge, [NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust]); + } + } + else { + // Certificate chain validation failed; cancel the connection + completionHandler(NSURLSessionAuthChallengeCancelAuthenticationChallenge, [NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust]); + } + } +} + +@end diff --git a/web/server/h2o/libh2o/deps/ssl-conservatory/ios/SSLCertificatePinning/SSLCertificatePinning/SSLCertificatePinning-Prefix.pch b/web/server/h2o/libh2o/deps/ssl-conservatory/ios/SSLCertificatePinning/SSLCertificatePinning/SSLCertificatePinning-Prefix.pch new file mode 100644 index 00000000..eb2007ec --- /dev/null +++ b/web/server/h2o/libh2o/deps/ssl-conservatory/ios/SSLCertificatePinning/SSLCertificatePinning/SSLCertificatePinning-Prefix.pch @@ -0,0 +1,9 @@ +// +// Prefix header +// +// The contents of this file are implicitly included at the beginning of every source file. +// + +#ifdef __OBJC__ + #import +#endif diff --git a/web/server/h2o/libh2o/deps/ssl-conservatory/ios/SSLCertificatePinning/SSLCertificatePinningTests/NSURLConnectionTests.m b/web/server/h2o/libh2o/deps/ssl-conservatory/ios/SSLCertificatePinning/SSLCertificatePinningTests/NSURLConnectionTests.m new file mode 100644 index 00000000..53d86078 --- /dev/null +++ b/web/server/h2o/libh2o/deps/ssl-conservatory/ios/SSLCertificatePinning/SSLCertificatePinningTests/NSURLConnectionTests.m @@ -0,0 +1,154 @@ +// +// NSURLConnectionTests.m +// SSLCertificatePinning +// +// Created by Alban Diquet on 1/14/14. +// Copyright (c) 2014 iSEC Partners. All rights reserved. +// + +#import + +#import "ISPPinnedNSURLConnectionDelegate.h" +#import "ISPCertificatePinning.h" +#import "SSLPinsTestUtility.h" + + +// Delegate we'll use for our tests +@interface NSURLConnectionDelegateTest : ISPPinnedNSURLConnectionDelegate + @property BOOL connectionFinished; + @property BOOL connectionSucceeded; +@end + + + +@interface NSURLConnectionTests : XCTestCase + +@end + + +@implementation NSURLConnectionTests + + +- (void)setUp +{ + [super setUp]; +} + +- (void)tearDown +{ + [super tearDown]; +} + +#pragma mark SSL pinning test + + +// This is sample code to demonstrate how to implement certificate pinning with NSURLConnection +- (void)testNSURLConnectionSSLPinning +{ + + // Create our SSL pins dictionnary for Twitter, iSEC and NCC + NSDictionary *domainsToPin = [SSLPinsTestUtility setupTestSSLPinsDictionnary]; + if (domainsToPin == nil) { + NSLog(@"Failed to pin a certificate"); + } + + + // Save the SSL pins so that our connection delegates automatically use them + if ([ISPCertificatePinning setupSSLPinsUsingDictionnary:domainsToPin] != YES) { + NSLog(@"Failed to pin the certificates"); + } + + // Connect to Twitter + NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"https://twitter.com/"]]; + NSURLConnectionDelegateTest *connectionDelegate = [[NSURLConnectionDelegateTest alloc] init]; + NSURLConnection *connection=[[NSURLConnection alloc] initWithRequest:request delegate:connectionDelegate]; + [connection start]; + + // Connect to iSEC + NSURLRequest *request2 = [NSURLRequest requestWithURL:[NSURL URLWithString:@"https://www.isecpartners.com/"]]; + NSURLConnectionDelegateTest *connectionDelegate2 = [[NSURLConnectionDelegateTest alloc] init]; + NSURLConnection *connection2 = [[NSURLConnection alloc] initWithRequest:request2 delegate:connectionDelegate2]; + [connection2 start]; + + // Connect to NCC Group => will fail because we pinned a wrong certificate + NSURLRequest *request3 = [NSURLRequest requestWithURL:[NSURL URLWithString:@"https://www.nccgroup.com/"]]; + NSURLConnectionDelegateTest *connectionDelegate3 = [[NSURLConnectionDelegateTest alloc] init]; + NSURLConnection *connection3 = [[NSURLConnection alloc] initWithRequest:request3 delegate:connectionDelegate3]; + [connection3 start]; + + + // Do some polling to wait for the connections to complete +#define POLL_INTERVAL 0.2 // 200ms +#define N_SEC_TO_POLL 3.0 // poll for 3s +#define MAX_POLL_COUNT N_SEC_TO_POLL / POLL_INTERVAL + + NSUInteger pollCount = 0; + while (!(connectionDelegate.connectionFinished && connectionDelegate2.connectionFinished && connectionDelegate3.connectionFinished) && (pollCount < MAX_POLL_COUNT)) { + NSDate* untilDate = [NSDate dateWithTimeIntervalSinceNow:POLL_INTERVAL]; + [[NSRunLoop currentRunLoop] runUntilDate:untilDate]; + pollCount++; + } + + if (pollCount == MAX_POLL_COUNT) { + XCTFail(@"Could not connect in time"); + } + + + // The first two connections should succeed + XCTAssertTrue(connectionDelegate.connectionSucceeded, @"Connection to Twitter failed"); + XCTAssertTrue(connectionDelegate2.connectionSucceeded, @"Connection to iSEC Partners failed"); + + // The last connection should fail + XCTAssertFalse(connectionDelegate3.connectionSucceeded, @"Connection to NCC succeeded"); +} + + +@end + + +#pragma mark Delegate class + +@implementation NSURLConnectionDelegateTest + +@synthesize connectionSucceeded; +@synthesize connectionFinished; + +-(instancetype) init { + if (self = [super init]) + { + self.connectionSucceeded = NO; + self.connectionFinished = NO; + } + return self; +} + + +- (void)connectionDidFinishLoading:(NSURLConnection *)connection { + self.connectionSucceeded = YES; + self.connectionFinished = YES; +} + +- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error { + self.connectionSucceeded = NO; + self.connectionFinished = YES; +} + +- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data { + self.connectionSucceeded = YES; + self.connectionFinished = YES; +} + +- (NSCachedURLResponse *)connection:(NSURLConnection *)connection willCacheResponse:(NSCachedURLResponse *)cachedResponse { + return cachedResponse; +} + +- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response { + self.connectionSucceeded = YES; + self.connectionFinished = YES; +} + +- (NSURLRequest *)connection:(NSURLConnection *)connection willSendRequest:(NSURLRequest *)request redirectResponse:(NSURLResponse *)redirectResponse { + return request; +} + +@end \ No newline at end of file diff --git a/web/server/h2o/libh2o/deps/ssl-conservatory/ios/SSLCertificatePinning/SSLCertificatePinningTests/NSURLSessionTests.m b/web/server/h2o/libh2o/deps/ssl-conservatory/ios/SSLCertificatePinning/SSLCertificatePinningTests/NSURLSessionTests.m new file mode 100644 index 00000000..5f1da51b --- /dev/null +++ b/web/server/h2o/libh2o/deps/ssl-conservatory/ios/SSLCertificatePinning/SSLCertificatePinningTests/NSURLSessionTests.m @@ -0,0 +1,145 @@ +// +// NSURLSessionTests.m +// SSLCertificatePinning +// +// Created by Alban Diquet on 1/14/14. +// Copyright (c) 2014 iSEC Partners. All rights reserved. +// + +#import + +#import "ISPPinnedNSURLSessionDelegate.h" +#import "ISPCertificatePinning.h" +#import "SSLPinsTestUtility.h" + + +// Delegate we'll use for our tests +@interface NSURLSessionTaskDelegateTest : ISPPinnedNSURLSessionDelegate +@property BOOL connectionFinished; +@property BOOL connectionSucceeded; +@end + + +@interface NSURLSessionTests : XCTestCase + +@end + +@implementation NSURLSessionTests + +- (void)setUp +{ + [super setUp]; +} + +- (void)tearDown +{ + [super tearDown]; +} + + +#pragma mark SSL pinning test +- (void)testNSURLSessionSSLPinning +{ + + // Create our SSL pins dictionnary for Twitter, iSEC and NCC + NSDictionary *domainsToPin = [SSLPinsTestUtility setupTestSSLPinsDictionnary]; + if (domainsToPin == nil) { + NSLog(@"Failed to pin a certificate"); + } + + // Save the SSL pins so that our session delegates automatically use them + if ([ISPCertificatePinning setupSSLPinsUsingDictionnary:domainsToPin] != YES) { + NSLog(@"Failed to pin the certificates"); + } + + + // Connect to Twitter + NSURLSessionTaskDelegateTest *sessionDelegate1 = [[NSURLSessionTaskDelegateTest alloc] init]; + NSURLSession *session1 = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration ephemeralSessionConfiguration] delegate:sessionDelegate1 delegateQueue:nil]; + + NSURLSessionDataTask *dataTask1 = [session1 dataTaskWithURL:[NSURL URLWithString:@"https://twitter.com/"] completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) { + + sessionDelegate1.connectionFinished = YES; + if (!error) { + sessionDelegate1.connectionSucceeded = YES; + } + }]; + [dataTask1 resume]; + + + // Connect to iSEC + NSURLSessionTaskDelegateTest *sessionDelegate2 = [[NSURLSessionTaskDelegateTest alloc] init]; + NSURLSession *session2 = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration ephemeralSessionConfiguration] delegate:sessionDelegate2 delegateQueue:nil]; + + NSURLSessionDataTask *dataTask2 = [session2 dataTaskWithURL:[NSURL URLWithString:@"https://www.isecpartners.com/"] completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) { + + sessionDelegate2.connectionFinished = YES; + if (!error) { + sessionDelegate2.connectionSucceeded = YES; + } + }]; + [dataTask2 resume]; + + + // Connect to NCC Group => will fail because we pinned a wrong certificate + NSURLSessionTaskDelegateTest *sessionDelegate3 = [[NSURLSessionTaskDelegateTest alloc] init]; + NSURLSession *session3 = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration ephemeralSessionConfiguration] delegate:sessionDelegate3 delegateQueue:nil]; + + NSURLSessionDataTask *dataTask3 = [session3 dataTaskWithURL:[NSURL URLWithString:@"https://www.nccgroup.com/"] completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) { + + sessionDelegate3.connectionFinished = YES; + if (!error) { + sessionDelegate3.connectionSucceeded = YES; + } + }]; + [dataTask3 resume]; + + + // Do some polling to wait for the connections to complete +#define POLL_INTERVAL 0.2 // 200ms +#define N_SEC_TO_POLL 3.0 // poll for 3s +#define MAX_POLL_COUNT N_SEC_TO_POLL / POLL_INTERVAL + + NSUInteger pollCount = 0; + while (!(sessionDelegate1.connectionFinished && sessionDelegate2.connectionFinished && sessionDelegate3.connectionFinished) && (pollCount < MAX_POLL_COUNT)) { + NSDate* untilDate = [NSDate dateWithTimeIntervalSinceNow:POLL_INTERVAL]; + [[NSRunLoop currentRunLoop] runUntilDate:untilDate]; + pollCount++; + } + + if (pollCount == MAX_POLL_COUNT) { + XCTFail(@"Could not connect in time"); + } + + + // The first two connections should succeed + XCTAssertTrue(sessionDelegate1.connectionSucceeded, @"Connection to Twitter failed"); + XCTAssertTrue(sessionDelegate2.connectionSucceeded, @"Connection to iSEC Partners failed"); + + // The last connection should fail + XCTAssertFalse(sessionDelegate3.connectionSucceeded, @"Connection to NCC succeeded"); +} + + +@end + + + + +#pragma mark Delegate class + +@implementation NSURLSessionTaskDelegateTest + + @synthesize connectionSucceeded; + @synthesize connectionFinished; + + -(instancetype) init { + if (self = [super init]) + { + self.connectionSucceeded = NO; + self.connectionFinished = NO; + } + return self; + } + +@end diff --git a/web/server/h2o/libh2o/deps/ssl-conservatory/ios/SSLCertificatePinning/SSLCertificatePinningTests/SSLCertificatePinningTests-Info.plist b/web/server/h2o/libh2o/deps/ssl-conservatory/ios/SSLCertificatePinning/SSLCertificatePinningTests/SSLCertificatePinningTests-Info.plist new file mode 100644 index 00000000..ccba61f8 --- /dev/null +++ b/web/server/h2o/libh2o/deps/ssl-conservatory/ios/SSLCertificatePinning/SSLCertificatePinningTests/SSLCertificatePinningTests-Info.plist @@ -0,0 +1,22 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleIdentifier + com.isecpartners.${PRODUCT_NAME:rfc1034identifier} + CFBundleInfoDictionaryVersion + 6.0 + CFBundlePackageType + BNDL + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + 1 + + diff --git a/web/server/h2o/libh2o/deps/ssl-conservatory/ios/SSLCertificatePinning/SSLCertificatePinningTests/SSLPinsTestUtility.h b/web/server/h2o/libh2o/deps/ssl-conservatory/ios/SSLCertificatePinning/SSLCertificatePinningTests/SSLPinsTestUtility.h new file mode 100644 index 00000000..56dde1ac --- /dev/null +++ b/web/server/h2o/libh2o/deps/ssl-conservatory/ios/SSLCertificatePinning/SSLCertificatePinningTests/SSLPinsTestUtility.h @@ -0,0 +1,15 @@ +// +// SSLPinsTestUtility.h +// SSLCertificatePinning +// +// Created by Alban Diquet on 2/2/14. +// Copyright (c) 2014 iSEC Partners. All rights reserved. +// + +#import + +@interface SSLPinsTestUtility : NSObject + ++ (NSDictionary*) setupTestSSLPinsDictionnary; + +@end diff --git a/web/server/h2o/libh2o/deps/ssl-conservatory/ios/SSLCertificatePinning/SSLCertificatePinningTests/SSLPinsTestUtility.m b/web/server/h2o/libh2o/deps/ssl-conservatory/ios/SSLCertificatePinning/SSLCertificatePinningTests/SSLPinsTestUtility.m new file mode 100644 index 00000000..7a5eb22c --- /dev/null +++ b/web/server/h2o/libh2o/deps/ssl-conservatory/ios/SSLCertificatePinning/SSLCertificatePinningTests/SSLPinsTestUtility.m @@ -0,0 +1,57 @@ +// +// SSLPinsTestUtility.m +// SSLCertificatePinning +// +// Created by Alban Diquet on 2/2/14. +// Copyright (c) 2014 iSEC Partners. All rights reserved. +// + +#import "SSLPinsTestUtility.h" +#import "ISPCertificatePinning.h" + +@implementation SSLPinsTestUtility + + ++ (NSData*)loadCertificateFromFile:(NSString*)fileName { + NSString *certPath = [[NSBundle bundleForClass:[self class]] pathForResource:fileName ofType:@"der"]; + NSData *certData = [[NSData alloc] initWithContentsOfFile:certPath]; + return certData; +} + + ++ (NSDictionary*) setupTestSSLPinsDictionnary { + // Build our dictionnary of domain => certificates + NSMutableDictionary *domainsToPin = [[NSMutableDictionary alloc] init]; + + + // For Twitter, we pin the anchor/CA certificate + NSData *twitterCertData = [SSLPinsTestUtility loadCertificateFromFile:@"VeriSignClass3PublicPrimaryCertificationAuthority-G5"]; + if (twitterCertData == nil) { + NSLog(@"Failed to load a certificate"); + return nil; + } + NSArray *twitterTrustedCerts = [NSArray arrayWithObject:twitterCertData]; + [domainsToPin setObject:twitterTrustedCerts forKey:@"twitter.com"]; + + + // For iSEC, we pin the server/leaf certificate + NSData *isecCertData = [SSLPinsTestUtility loadCertificateFromFile:@"www.isecpartners.com"]; + if (isecCertData == nil) { + NSLog(@"Failed to load a certificate"); + return nil; + } + // We also pin Twitter's CA cert just to show that you can pin multiple certs to a single domain + // This is useful when transitioning between two certificates on the server + // The connection will be succesful if at least one of the pinned certs is found in the server's certificate trust chain + NSArray *iSECTrustedCerts = [NSArray arrayWithObjects:isecCertData, twitterCertData, nil]; + [domainsToPin setObject:iSECTrustedCerts forKey:@"www.isecpartners.com"]; + + + // For NCC group, we pin an invalid certificate (Twitter's) + NSArray *NCCTrustedCerts = [NSArray arrayWithObject:twitterCertData]; + [domainsToPin setObject:NCCTrustedCerts forKey:@"www.nccgroup.com"]; + + return domainsToPin; +} + +@end diff --git a/web/server/h2o/libh2o/deps/ssl-conservatory/ios/SSLCertificatePinning/SSLCertificatePinningTests/VeriSignClass3PublicPrimaryCertificationAuthority-G5.der b/web/server/h2o/libh2o/deps/ssl-conservatory/ios/SSLCertificatePinning/SSLCertificatePinningTests/VeriSignClass3PublicPrimaryCertificationAuthority-G5.der new file mode 100644 index 00000000..9818d19d Binary files /dev/null and b/web/server/h2o/libh2o/deps/ssl-conservatory/ios/SSLCertificatePinning/SSLCertificatePinningTests/VeriSignClass3PublicPrimaryCertificationAuthority-G5.der differ diff --git a/web/server/h2o/libh2o/deps/ssl-conservatory/ios/SSLCertificatePinning/SSLCertificatePinningTests/en.lproj/InfoPlist.strings b/web/server/h2o/libh2o/deps/ssl-conservatory/ios/SSLCertificatePinning/SSLCertificatePinningTests/en.lproj/InfoPlist.strings new file mode 100644 index 00000000..477b28ff --- /dev/null +++ b/web/server/h2o/libh2o/deps/ssl-conservatory/ios/SSLCertificatePinning/SSLCertificatePinningTests/en.lproj/InfoPlist.strings @@ -0,0 +1,2 @@ +/* Localized versions of Info.plist keys */ + diff --git a/web/server/h2o/libh2o/deps/ssl-conservatory/ios/SSLCertificatePinning/SSLCertificatePinningTests/www.isecpartners.com.der b/web/server/h2o/libh2o/deps/ssl-conservatory/ios/SSLCertificatePinning/SSLCertificatePinningTests/www.isecpartners.com.der new file mode 100644 index 00000000..886cf483 Binary files /dev/null and b/web/server/h2o/libh2o/deps/ssl-conservatory/ios/SSLCertificatePinning/SSLCertificatePinningTests/www.isecpartners.com.der differ diff --git a/web/server/h2o/libh2o/deps/ssl-conservatory/openssl/DigiCertHighAssuranceEVRootCA.pem b/web/server/h2o/libh2o/deps/ssl-conservatory/openssl/DigiCertHighAssuranceEVRootCA.pem new file mode 100644 index 00000000..4b1bc66b --- /dev/null +++ b/web/server/h2o/libh2o/deps/ssl-conservatory/openssl/DigiCertHighAssuranceEVRootCA.pem @@ -0,0 +1,23 @@ +-----BEGIN CERTIFICATE----- +MIIDxTCCAq2gAwIBAgIQAqxcJmoLQJuPC3nyrkYldzANBgkqhkiG9w0BAQUFADBs +MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 +d3cuZGlnaWNlcnQuY29tMSswKQYDVQQDEyJEaWdpQ2VydCBIaWdoIEFzc3VyYW5j +ZSBFViBSb290IENBMB4XDTA2MTExMDAwMDAwMFoXDTMxMTExMDAwMDAwMFowbDEL +MAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3 +LmRpZ2ljZXJ0LmNvbTErMCkGA1UEAxMiRGlnaUNlcnQgSGlnaCBBc3N1cmFuY2Ug +RVYgUm9vdCBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMbM5XPm ++9S75S0tMqbf5YE/yc0lSbZxKsPVlDRnogocsF9ppkCxxLeyj9CYpKlBWTrT3JTW +PNt0OKRKzE0lgvdKpVMSOO7zSW1xkX5jtqumX8OkhPhPYlG++MXs2ziS4wblCJEM +xChBVfvLWokVfnHoNb9Ncgk9vjo4UFt3MRuNs8ckRZqnrG0AFFoEt7oT61EKmEFB +Ik5lYYeBQVCmeVyJ3hlKV9Uu5l0cUyx+mM0aBhakaHPQNAQTXKFx01p8VdteZOE3 +hzBWBOURtCmAEvF5OYiiAhF8J2a3iLd48soKqDirCmTCv2ZdlYTBoSUeh10aUAsg +EsxBu24LUTi4S8sCAwEAAaNjMGEwDgYDVR0PAQH/BAQDAgGGMA8GA1UdEwEB/wQF +MAMBAf8wHQYDVR0OBBYEFLE+w2kD+L9HAdSYJhoIAu9jZCvDMB8GA1UdIwQYMBaA +FLE+w2kD+L9HAdSYJhoIAu9jZCvDMA0GCSqGSIb3DQEBBQUAA4IBAQAcGgaX3Nec +nzyIZgYIVyHbIUf4KmeqvxgydkAQV8GK83rZEWWONfqe/EW1ntlMMUu4kehDLI6z +eM7b41N5cdblIZQB2lWHmiRk9opmzN6cN82oNLFpmyPInngiK3BD41VHMWEZ71jF +hS9OMPagMRYjyOfiZRYzy78aG6A9+MpeizGLYAiJLQwGXFK3xPkKmNEVX58Svnw2 +Yzi9RKR/5CYrCsSXaQ3pjOLAEFe4yHYSkVXySGnYvCoCWw9E1CAx2/S6cCZdkGCe +vEsXCS+0yx5DaMkHJ8HSXPfqIbloEpw8nL+e/IBcm2PN7EeqJSdnoDfzAIJ9VNep ++OkuE6N36B9K +-----END CERTIFICATE----- diff --git a/web/server/h2o/libh2o/deps/ssl-conservatory/openssl/Makefile b/web/server/h2o/libh2o/deps/ssl-conservatory/openssl/Makefile new file mode 100644 index 00000000..0edaa7cb --- /dev/null +++ b/web/server/h2o/libh2o/deps/ssl-conservatory/openssl/Makefile @@ -0,0 +1,12 @@ +# Tested on FreeBSD, Ubuntu 10.04 and Cygwin +CC=gcc +CFLAGS=-c -Wall -std=c99 -pedantic +LDFLAGS=-lcrypto -lssl + +all: test_client + +test_client: test_client.o openssl_hostname_validation.o + $(CC) test_client.o openssl_hostname_validation.o -o test_client $(LDFLAGS) + +clean: + rm -rf *.o test_client diff --git a/web/server/h2o/libh2o/deps/ssl-conservatory/openssl/Makefile_mingw b/web/server/h2o/libh2o/deps/ssl-conservatory/openssl/Makefile_mingw new file mode 100644 index 00000000..00f63144 --- /dev/null +++ b/web/server/h2o/libh2o/deps/ssl-conservatory/openssl/Makefile_mingw @@ -0,0 +1,18 @@ +# Tested on Windows 7 with MinGW-w64 +CC=gcc +CFLAGS=-c -Wall +LDFLAGS= -leay32 -lssl32 + +all: test_client + +test_client: test_client.o openssl_hostname_validation.o + $(CC) test_client.o openssl_hostname_validation.o -o test_client $(LDFLAGS) + +test_client.o: test_client.c + $(CC) $(CFLAGS) test_client.c + +openssl_hostname_validation.o: openssl_hostname_validation.c + $(CC) $(CFLAGS) openssl_hostname_validation.c + +clean: + rm -rf *.o test_client.exe diff --git a/web/server/h2o/libh2o/deps/ssl-conservatory/openssl/README.md b/web/server/h2o/libh2o/deps/ssl-conservatory/openssl/README.md new file mode 100644 index 00000000..14ca84ae --- /dev/null +++ b/web/server/h2o/libh2o/deps/ssl-conservatory/openssl/README.md @@ -0,0 +1,61 @@ +The SSL Conservatory: OpenSSL Certificate Validation +==================================================== + +This sample code demonstrates how to perform certificate validation when using +the OpenSSL library to connect to an SSL/TLS server. It was tested on Windows +7, OS X and Linux. + + +Read The Whitepaper +------------------- + +Before using this code, please read the white paper "Everything you've always +wanted to know about certificate validation with OpenSSL (but were afraid to +ask)" available at ./everything-you-wanted-to-know-about-openssl.pdf. + + +OS-Specific Instructions +------------------------ + +### Linux + +The code was compiled and tested on Ubuntu 11.04. + +You will have to install the libssl and libcrypto development libraries and +header files. In most Linux distros they are part of the "libssl-dev" package. + + +### OS X + +The code was compiled and tested on OS X Mountain Lion. + +OS X comes the OpenSSL development libraries pre-installed. However, libssl has +been modified by Apple to automatically use the system's trust store when +validating certificate chains; this behavior cannot be changed. Therefore, +specifying a trust store using SSL_CTX_load_verify_locations() will always be +ignored on OS X. + +Additionally, compiling the code on OS X will generate a lot of "is +deprecated" warnings because Apple is migrating from OpenSSL to the Common +Crypto framework. + + +### Windows + +The code was compiled using minGW and tested on Windows 7. + +You will have to install minGW as well as the OpenSSL development libraries. +The OpenSSL project provides a link to pre-compiled libraries for Windows at +the following URL: http://www.openssl.org/related/binaries.html + +If you used those binaries, here are additional instructions to compile the +sample code. First add the OpenSSL headers and libraries to MinGW: + + Copy /include/ to /include/ + Copy /libeay32.dll to /lib/libeay32.dll + Copy /libssl32.dll to /lib/libssl32.dll + +Then compile the test_client: + + make -f Makefile_mingw + diff --git a/web/server/h2o/libh2o/deps/ssl-conservatory/openssl/everything-you-wanted-to-know-about-openssl.pdf b/web/server/h2o/libh2o/deps/ssl-conservatory/openssl/everything-you-wanted-to-know-about-openssl.pdf new file mode 100644 index 00000000..9e6524f6 Binary files /dev/null and b/web/server/h2o/libh2o/deps/ssl-conservatory/openssl/everything-you-wanted-to-know-about-openssl.pdf differ diff --git a/web/server/h2o/libh2o/deps/ssl-conservatory/openssl/openssl_hostname_validation.c b/web/server/h2o/libh2o/deps/ssl-conservatory/openssl/openssl_hostname_validation.c new file mode 100644 index 00000000..066fd6dd --- /dev/null +++ b/web/server/h2o/libh2o/deps/ssl-conservatory/openssl/openssl_hostname_validation.c @@ -0,0 +1,181 @@ +/* + * Helper functions to perform basic hostname validation using OpenSSL. + * + * Please read "everything-you-wanted-to-know-about-openssl.pdf" before + * attempting to use this code. This whitepaper describes how the code works, + * how it should be used, and what its limitations are. + * + * Author: Alban Diquet + * License: See LICENSE + * + */ + + +#include +#include +#include + +#include "openssl_hostname_validation.h" + + +#define HOSTNAME_MAX_SIZE 255 + +static int lowercase(int ch) { + if ('A' <= ch && ch <= 'Z') + return ch - 'A' + 'a'; + return ch; +} + +static int memeq_ncase(const char *x, const char *y, size_t l) { + if (l == 0) + return 1; + do { + if (lowercase(*x++) != lowercase(*y++)) + return 0; + } while (--l != 0); + return 1; +} + +static int has_nul(const char *s, size_t l) { + if (l == 0) + return 0; + do { + if (*s++ == '\0') + return 1; + } while (--l != 0); + return 0; +} + +static HostnameValidationResult validate_name(const char *hostname, ASN1_STRING *certname_asn1) { +#if (OPENSSL_VERSION_NUMBER >= 0x10100000L) && !defined(LIBRESSL_VERSION_NUMBER) + char *certname_s = (char *) ASN1_STRING_get0_data(certname_asn1); +#else + char *certname_s = (char *) ASN1_STRING_data(certname_asn1); +#endif + int certname_len = ASN1_STRING_length(certname_asn1), hostname_len = strlen(hostname); + + // Make sure there isn't an embedded NUL character in the DNS name + if (has_nul(certname_s, certname_len)) { + return MalformedCertificate; + } + // remove last '.' from hostname + if (hostname_len != 0 && hostname[hostname_len - 1] == '.') + --hostname_len; + // skip the first segment if wildcard + if (certname_len > 2 && certname_s[0] == '*' && certname_s[1] == '.') { + if (hostname_len != 0) { + do { + --hostname_len; + if (*hostname++ == '.') + break; + } while (hostname_len != 0); + } + certname_s += 2; + certname_len -= 2; + } + // Compare expected hostname with the DNS name + if (certname_len != hostname_len) { + return MatchNotFound; + } + return memeq_ncase(hostname, certname_s, hostname_len) ? MatchFound : MatchNotFound; +} + +/** +* Tries to find a match for hostname in the certificate's Common Name field. +* +* Returns MatchFound if a match was found. +* Returns MatchNotFound if no matches were found. +* Returns MalformedCertificate if the Common Name had a NUL character embedded in it. +* Returns Error if the Common Name could not be extracted. +*/ +static HostnameValidationResult matches_common_name(const char *hostname, const X509 *server_cert) { + int common_name_loc = -1; + X509_NAME_ENTRY *common_name_entry = NULL; + ASN1_STRING *common_name_asn1 = NULL; + + // Find the position of the CN field in the Subject field of the certificate + common_name_loc = X509_NAME_get_index_by_NID(X509_get_subject_name((X509 *) server_cert), NID_commonName, -1); + if (common_name_loc < 0) { + return Error; + } + + // Extract the CN field + common_name_entry = X509_NAME_get_entry(X509_get_subject_name((X509 *) server_cert), common_name_loc); + if (common_name_entry == NULL) { + return Error; + } + common_name_asn1 = X509_NAME_ENTRY_get_data(common_name_entry); + if (common_name_asn1 == NULL) { + return Error; + } + + // validate the names + return validate_name(hostname, common_name_asn1); +} + + +/** +* Tries to find a match for hostname in the certificate's Subject Alternative Name extension. +* +* Returns MatchFound if a match was found. +* Returns MatchNotFound if no matches were found. +* Returns MalformedCertificate if any of the hostnames had a NUL character embedded in it. +* Returns NoSANPresent if the SAN extension was not present in the certificate. +*/ +static HostnameValidationResult matches_subject_alternative_name(const char *hostname, const X509 *server_cert) { + HostnameValidationResult result = MatchNotFound; + int i; + int san_names_nb = -1; + STACK_OF(GENERAL_NAME) *san_names = NULL; + + // Try to extract the names within the SAN extension from the certificate + san_names = X509_get_ext_d2i((X509 *) server_cert, NID_subject_alt_name, NULL, NULL); + if (san_names == NULL) { + return NoSANPresent; + } + san_names_nb = sk_GENERAL_NAME_num(san_names); + + // Check each name within the extension + for (i=0; itype == GEN_DNS) { + // Current name is a DNS name, let's check it + result = validate_name(hostname, current_name->d.dNSName); + if (result != MatchNotFound) { + break; + } + } + } + sk_GENERAL_NAME_pop_free(san_names, GENERAL_NAME_free); + + return result; +} + + +/** +* Validates the server's identity by looking for the expected hostname in the +* server's certificate. As described in RFC 6125, it first tries to find a match +* in the Subject Alternative Name extension. If the extension is not present in +* the certificate, it checks the Common Name instead. +* +* Returns MatchFound if a match was found. +* Returns MatchNotFound if no matches were found. +* Returns MalformedCertificate if any of the hostnames had a NUL character embedded in it. +* Returns Error if there was an error. +*/ +HostnameValidationResult validate_hostname(const char *hostname, const X509 *server_cert) { + HostnameValidationResult result; + + if((hostname == NULL) || (server_cert == NULL)) + return Error; + + // First try the Subject Alternative Names extension + result = matches_subject_alternative_name(hostname, server_cert); + if (result == NoSANPresent) { + // Extension was not found: try the Common Name + result = matches_common_name(hostname, server_cert); + } + + return result; +} diff --git a/web/server/h2o/libh2o/deps/ssl-conservatory/openssl/openssl_hostname_validation.h b/web/server/h2o/libh2o/deps/ssl-conservatory/openssl/openssl_hostname_validation.h new file mode 100644 index 00000000..ca4b9be9 --- /dev/null +++ b/web/server/h2o/libh2o/deps/ssl-conservatory/openssl/openssl_hostname_validation.h @@ -0,0 +1,40 @@ +/* + * Helper functions to perform basic hostname validation using OpenSSL. + * + * Please read "everything-you-wanted-to-know-about-openssl.pdf" before + * attempting to use this code. This whitepaper describes how the code works, + * how it should be used, and what its limitations are. + * + * Author: Alban Diquet + * License: See LICENSE + * + */ +#ifndef openssl_hostname_validation_h +#define openssl_hostname_validation_h + +#ifndef OPENSSL_HOSTNAME_VALIDATION_LINKAGE +#define OPENSSL_HOSTNAME_VALIDATION_LINKAGE extern +#endif + +typedef enum { + MatchFound, + MatchNotFound, + NoSANPresent, + MalformedCertificate, + Error +} HostnameValidationResult; + +/** +* Validates the server's identity by looking for the expected hostname in the +* server's certificate. As described in RFC 6125, it first tries to find a match +* in the Subject Alternative Name extension. If the extension is not present in +* the certificate, it checks the Common Name instead. +* +* Returns MatchFound if a match was found. +* Returns MatchNotFound if no matches were found. +* Returns MalformedCertificate if any of the hostnames had a NUL character embedded in it. +* Returns Error if there was an error. +*/ +OPENSSL_HOSTNAME_VALIDATION_LINKAGE HostnameValidationResult validate_hostname(const char *hostname, const X509 *server_cert); + +#endif diff --git a/web/server/h2o/libh2o/deps/ssl-conservatory/openssl/test_client b/web/server/h2o/libh2o/deps/ssl-conservatory/openssl/test_client new file mode 100755 index 00000000..054fd8cd Binary files /dev/null and b/web/server/h2o/libh2o/deps/ssl-conservatory/openssl/test_client differ diff --git a/web/server/h2o/libh2o/deps/ssl-conservatory/openssl/test_client.c b/web/server/h2o/libh2o/deps/ssl-conservatory/openssl/test_client.c new file mode 100644 index 00000000..916a22ed --- /dev/null +++ b/web/server/h2o/libh2o/deps/ssl-conservatory/openssl/test_client.c @@ -0,0 +1,142 @@ +/* + * Sample HTTPS client to demonstrate how to do certificate validation using + * OpenSSL. + * This client will securely connect to www.isecpartners.com:443 and print the + * server's response to an HTTP GET request. + * + * Please read "everything-you-wanted-to-know-about-openssl.pdf" before + * attempting to use this code. This whitepaper describes how the code works, + * how it should be used, and what its limitations are. + * + * Author: Alban Diquet + * License: See LICENSE + * + */ + +#include +#include +#include +#include + +#include "openssl_hostname_validation.h" + + +// Sample SSL client for https://www.isecpartners.com +#define TARGET_HOST "www.isecpartners.com" +#define TARGET_PORT "443" + +// CA certificate that signed www.isecpartners.com's certificate +#define TRUSTED_CA_PATHNAME "DigiCertHighAssuranceEVRootCA.pem" + + + +#define TARGET_SERVER TARGET_HOST":"TARGET_PORT +// 'High' cipher suites minus Anonymous DH and Camellia +#define SECURE_CIPHER_LIST "RC4-SHA:HIGH:!ADH:!AECDH:!CAMELLIA" + +/* Sends an HTTP GET and prints the server's response */ +static void send_http_get_and_print(BIO * sbio) { + int len; + char tmpbuf[1024]; + BIO * out = BIO_new_fp(stdout, BIO_NOCLOSE); + + BIO_puts(sbio, "GET / HTTP/1.0\n\n"); + for(;;) { + len = BIO_read(sbio, tmpbuf, 1024); + if(len <= 0) break; + BIO_write(out, tmpbuf, len); + } + BIO_free(out); +} + + +int main(int argc, char *argv[]) { + BIO *sbio; + SSL_CTX *ssl_ctx; + SSL *ssl; + X509 *server_cert; + + // Initialize OpenSSL + SSL_library_init(); + SSL_load_error_strings(); + + // Check OpenSSL PRNG + if(RAND_status() != 1) { + fprintf(stderr, "OpenSSL PRNG not seeded with enough data."); + goto error_1; + } + + ssl_ctx = SSL_CTX_new(TLSv1_client_method()); + + // Enable certificate validation + SSL_CTX_set_verify(ssl_ctx, SSL_VERIFY_PEER, NULL); + // Configure the CA trust store to be used + if (SSL_CTX_load_verify_locations(ssl_ctx, TRUSTED_CA_PATHNAME, NULL) != 1) { + fprintf(stderr, "Couldn't load certificate trust store.\n"); + goto error_2; + } + + // Only support secure cipher suites + if (SSL_CTX_set_cipher_list(ssl_ctx, SECURE_CIPHER_LIST) != 1) + goto error_2; + + // Create the SSL connection + sbio = BIO_new_ssl_connect(ssl_ctx); + BIO_get_ssl(sbio, &ssl); + if(!ssl) { + fprintf(stderr, "Can't locate SSL pointer\n"); + goto error_3; + } + + // Do the SSL handshake + BIO_set_conn_hostname(sbio, TARGET_SERVER); + if(SSL_do_handshake(ssl) <= 0) { + // SSL Handshake failed + long verify_err = SSL_get_verify_result(ssl); + if (verify_err != X509_V_OK) { + // It failed because the certificate chain validation failed + fprintf(stderr, "Certificate chain validation failed: %s\n", X509_verify_cert_error_string(verify_err)); + } + else { + // It failed for another reason + ERR_print_errors_fp(stderr); + } + goto error_3; + } + + // Recover the server's certificate + server_cert = SSL_get_peer_certificate(ssl); + if (server_cert == NULL) { + // The handshake was successful although the server did not provide a certificate + // Most likely using an insecure anonymous cipher suite... get out! + goto error_4; + } + + // Validate the hostname + if (validate_hostname(TARGET_HOST, server_cert) != MatchFound) { + fprintf(stderr, "Hostname validation failed.\n"); + goto error_5; + } + + // Hostname validation succeeded; we can start sending data + send_http_get_and_print(sbio); + + +error_5: + X509_free(server_cert); + +error_4: + BIO_ssl_shutdown(sbio); + +error_3: + BIO_free_all(sbio); + +error_2: + SSL_CTX_free(ssl_ctx); + +error_1: // OpenSSL cleanup + EVP_cleanup(); + ERR_free_strings(); + + return 0; +} diff --git a/web/server/h2o/libh2o/deps/yaml/CMakeLists.txt b/web/server/h2o/libh2o/deps/yaml/CMakeLists.txt new file mode 100644 index 00000000..e84c28cd --- /dev/null +++ b/web/server/h2o/libh2o/deps/yaml/CMakeLists.txt @@ -0,0 +1,16 @@ +# Minimal CMake project for building a static library under Windows. + +cmake_minimum_required (VERSION 2.8) +project (yaml C) + +set (YAML_VERSION_MAJOR 0) +set (YAML_VERSION_MINOR 1) +set (YAML_VERSION_PATCH 6) +set (YAML_VERSION_STRING "${YAML_VERSION_MAJOR}.${YAML_VERSION_MINOR}.${YAML_VERSION_PATCH}") + +file (GLOB SRC src/*.c) + +include_directories (include win32) +add_definitions (-DHAVE_CONFIG_H -DYAML_DECLARE_STATIC) +add_library (yaml STATIC ${SRC}) + diff --git a/web/server/h2o/libh2o/deps/yaml/LICENSE b/web/server/h2o/libh2o/deps/yaml/LICENSE new file mode 100644 index 00000000..050ced23 --- /dev/null +++ b/web/server/h2o/libh2o/deps/yaml/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2006 Kirill Simonov + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is furnished to do +so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/web/server/h2o/libh2o/deps/yaml/Makefile.am b/web/server/h2o/libh2o/deps/yaml/Makefile.am new file mode 100644 index 00000000..de2a3cd0 --- /dev/null +++ b/web/server/h2o/libh2o/deps/yaml/Makefile.am @@ -0,0 +1,18 @@ +## Run `./bootstrap` to generate the "Makefile.in" files in this directory and +## the "$SUBDIRS" subdirectories. + +SUBDIRS = include src . tests win32 + +EXTRA_DIST = README LICENSE CMakeLists.txt doc/doxygen.cfg + +pkgconfigdir = $(libdir)/pkgconfig +pkgconfig_DATA = yaml-0.1.pc + +maintainer-clean-local: + -rm -f aclocal.m4 config.h.in configure config/* + -find ${builddir} -name Makefile.in -exec rm -f '{}' ';' + +.PHONY: bootstrap +bootstrap: maintainer-clean + ./bootstrap + diff --git a/web/server/h2o/libh2o/deps/yaml/Makefile.in b/web/server/h2o/libh2o/deps/yaml/Makefile.in new file mode 100644 index 00000000..3a928c36 --- /dev/null +++ b/web/server/h2o/libh2o/deps/yaml/Makefile.in @@ -0,0 +1,810 @@ +# Makefile.in generated by automake 1.11.3 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software +# Foundation, Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +subdir = . +DIST_COMMON = README $(am__configure_deps) $(srcdir)/Makefile.am \ + $(srcdir)/Makefile.in $(srcdir)/config.h.in \ + $(srcdir)/yaml-0.1.pc.in $(top_srcdir)/configure \ + config/config.guess config/config.sub config/depcomp \ + config/install-sh config/ltmain.sh config/missing +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \ + configure.lineno config.status.lineno +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = config.h +CONFIG_CLEAN_FILES = yaml-0.1.pc +CONFIG_CLEAN_VPATH_FILES = +SOURCES = +DIST_SOURCES = +RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \ + html-recursive info-recursive install-data-recursive \ + install-dvi-recursive install-exec-recursive \ + install-html-recursive install-info-recursive \ + install-pdf-recursive install-ps-recursive install-recursive \ + installcheck-recursive installdirs-recursive pdf-recursive \ + ps-recursive uninstall-recursive +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; +am__install_max = 40 +am__nobase_strip_setup = \ + srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` +am__nobase_strip = \ + for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" +am__nobase_list = $(am__nobase_strip_setup); \ + for p in $$list; do echo "$$p $$p"; done | \ + sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ + $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ + if (++n[$$2] == $(am__install_max)) \ + { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ + END { for (dir in files) print dir, files[dir] }' +am__base_list = \ + sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ + sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +am__uninstall_files_from_dir = { \ + test -z "$$files" \ + || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ + || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ + $(am__cd) "$$dir" && rm -f $$files; }; \ + } +am__installdirs = "$(DESTDIR)$(pkgconfigdir)" +DATA = $(pkgconfig_DATA) +RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ + distclean-recursive maintainer-clean-recursive +AM_RECURSIVE_TARGETS = $(RECURSIVE_TARGETS:-recursive=) \ + $(RECURSIVE_CLEAN_TARGETS:-recursive=) tags TAGS ctags CTAGS \ + distdir dist dist-all distcheck +ETAGS = etags +CTAGS = ctags +DIST_SUBDIRS = $(SUBDIRS) +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +distdir = $(PACKAGE)-$(VERSION) +top_distdir = $(distdir) +am__remove_distdir = \ + if test -d "$(distdir)"; then \ + find "$(distdir)" -type d ! -perm -200 -exec chmod u+w {} ';' \ + && rm -rf "$(distdir)" \ + || { sleep 5 && rm -rf "$(distdir)"; }; \ + else :; fi +am__relativize = \ + dir0=`pwd`; \ + sed_first='s,^\([^/]*\)/.*$$,\1,'; \ + sed_rest='s,^[^/]*/*,,'; \ + sed_last='s,^.*/\([^/]*\)$$,\1,'; \ + sed_butlast='s,/*[^/]*$$,,'; \ + while test -n "$$dir1"; do \ + first=`echo "$$dir1" | sed -e "$$sed_first"`; \ + if test "$$first" != "."; then \ + if test "$$first" = ".."; then \ + dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ + dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ + else \ + first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ + if test "$$first2" = "$$first"; then \ + dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ + else \ + dir2="../$$dir2"; \ + fi; \ + dir0="$$dir0"/"$$first"; \ + fi; \ + fi; \ + dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ + done; \ + reldir="$$dir2" +DIST_ARCHIVES = $(distdir).tar.gz +GZIP_ENV = --best +distuninstallcheck_listfiles = find . -type f -print +am__distuninstallcheck_listfiles = $(distuninstallcheck_listfiles) \ + | sed 's|^\./|$(prefix)/|' | grep -v '$(infodir)/dir$$' +distcleancheck_listfiles = find . -type f -print +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DOXYGEN = @DOXYGEN@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +GREP = @GREP@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +YAML_LT_AGE = @YAML_LT_AGE@ +YAML_LT_CURRENT = @YAML_LT_CURRENT@ +YAML_LT_RELEASE = @YAML_LT_RELEASE@ +YAML_LT_REVISION = @YAML_LT_REVISION@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +SUBDIRS = include src . tests win32 +EXTRA_DIST = README LICENSE CMakeLists.txt doc/doxygen.cfg +pkgconfigdir = $(libdir)/pkgconfig +pkgconfig_DATA = yaml-0.1.pc +all: config.h + $(MAKE) $(AM_MAKEFLAGS) all-recursive + +.SUFFIXES: +am--refresh: Makefile + @: +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + echo ' cd $(srcdir) && $(AUTOMAKE) --foreign'; \ + $(am__cd) $(srcdir) && $(AUTOMAKE) --foreign \ + && exit 0; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --foreign Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + echo ' $(SHELL) ./config.status'; \ + $(SHELL) ./config.status;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + $(SHELL) ./config.status --recheck + +$(top_srcdir)/configure: $(am__configure_deps) + $(am__cd) $(srcdir) && $(AUTOCONF) +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + $(am__cd) $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS) +$(am__aclocal_m4_deps): + +config.h: stamp-h1 + @if test ! -f $@; then rm -f stamp-h1; else :; fi + @if test ! -f $@; then $(MAKE) $(AM_MAKEFLAGS) stamp-h1; else :; fi + +stamp-h1: $(srcdir)/config.h.in $(top_builddir)/config.status + @rm -f stamp-h1 + cd $(top_builddir) && $(SHELL) ./config.status config.h +$(srcdir)/config.h.in: $(am__configure_deps) + ($(am__cd) $(top_srcdir) && $(AUTOHEADER)) + rm -f stamp-h1 + touch $@ + +distclean-hdr: + -rm -f config.h stamp-h1 +yaml-0.1.pc: $(top_builddir)/config.status $(srcdir)/yaml-0.1.pc.in + cd $(top_builddir) && $(SHELL) ./config.status $@ + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +distclean-libtool: + -rm -f libtool config.lt +install-pkgconfigDATA: $(pkgconfig_DATA) + @$(NORMAL_INSTALL) + test -z "$(pkgconfigdir)" || $(MKDIR_P) "$(DESTDIR)$(pkgconfigdir)" + @list='$(pkgconfig_DATA)'; test -n "$(pkgconfigdir)" || list=; \ + for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; \ + done | $(am__base_list) | \ + while read files; do \ + echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(pkgconfigdir)'"; \ + $(INSTALL_DATA) $$files "$(DESTDIR)$(pkgconfigdir)" || exit $$?; \ + done + +uninstall-pkgconfigDATA: + @$(NORMAL_UNINSTALL) + @list='$(pkgconfig_DATA)'; test -n "$(pkgconfigdir)" || list=; \ + files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ + dir='$(DESTDIR)$(pkgconfigdir)'; $(am__uninstall_files_from_dir) + +# This directory's subdirectories are mostly independent; you can cd +# into them and run `make' without going through this Makefile. +# To change the values of `make' variables: instead of editing Makefiles, +# (1) if the variable is set in `config.status', edit `config.status' +# (which will cause the Makefiles to be regenerated when you run `make'); +# (2) otherwise, pass the desired values on the `make' command line. +$(RECURSIVE_TARGETS): + @fail= failcom='exit 1'; \ + for f in x $$MAKEFLAGS; do \ + case $$f in \ + *=* | --[!k]*);; \ + *k*) failcom='fail=yes';; \ + esac; \ + done; \ + dot_seen=no; \ + target=`echo $@ | sed s/-recursive//`; \ + list='$(SUBDIRS)'; for subdir in $$list; do \ + echo "Making $$target in $$subdir"; \ + if test "$$subdir" = "."; then \ + dot_seen=yes; \ + local_target="$$target-am"; \ + else \ + local_target="$$target"; \ + fi; \ + ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ + || eval $$failcom; \ + done; \ + if test "$$dot_seen" = "no"; then \ + $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ + fi; test -z "$$fail" + +$(RECURSIVE_CLEAN_TARGETS): + @fail= failcom='exit 1'; \ + for f in x $$MAKEFLAGS; do \ + case $$f in \ + *=* | --[!k]*);; \ + *k*) failcom='fail=yes';; \ + esac; \ + done; \ + dot_seen=no; \ + case "$@" in \ + distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ + *) list='$(SUBDIRS)' ;; \ + esac; \ + rev=''; for subdir in $$list; do \ + if test "$$subdir" = "."; then :; else \ + rev="$$subdir $$rev"; \ + fi; \ + done; \ + rev="$$rev ."; \ + target=`echo $@ | sed s/-recursive//`; \ + for subdir in $$rev; do \ + echo "Making $$target in $$subdir"; \ + if test "$$subdir" = "."; then \ + local_target="$$target-am"; \ + else \ + local_target="$$target"; \ + fi; \ + ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ + || eval $$failcom; \ + done && test -z "$$fail" +tags-recursive: + list='$(SUBDIRS)'; for subdir in $$list; do \ + test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \ + done +ctags-recursive: + list='$(SUBDIRS)'; for subdir in $$list; do \ + test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \ + done + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: tags-recursive $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + set x; \ + here=`pwd`; \ + if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ + include_option=--etags-include; \ + empty_fix=.; \ + else \ + include_option=--include; \ + empty_fix=; \ + fi; \ + list='$(SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + test ! -f $$subdir/TAGS || \ + set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ + fi; \ + done; \ + list='$(SOURCES) $(HEADERS) config.h.in $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: CTAGS +CTAGS: ctags-recursive $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + list='$(SOURCES) $(HEADERS) config.h.in $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + $(am__remove_distdir) + test -d "$(distdir)" || mkdir "$(distdir)" + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done + @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + test -d "$(distdir)/$$subdir" \ + || $(MKDIR_P) "$(distdir)/$$subdir" \ + || exit 1; \ + fi; \ + done + @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ + $(am__relativize); \ + new_distdir=$$reldir; \ + dir1=$$subdir; dir2="$(top_distdir)"; \ + $(am__relativize); \ + new_top_distdir=$$reldir; \ + echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ + echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ + ($(am__cd) $$subdir && \ + $(MAKE) $(AM_MAKEFLAGS) \ + top_distdir="$$new_top_distdir" \ + distdir="$$new_distdir" \ + am__remove_distdir=: \ + am__skip_length_check=: \ + am__skip_mode_fix=: \ + distdir) \ + || exit 1; \ + fi; \ + done + -test -n "$(am__skip_mode_fix)" \ + || find "$(distdir)" -type d ! -perm -755 \ + -exec chmod u+rwx,go+rx {} \; -o \ + ! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \ + ! -type d ! -perm -400 -exec chmod a+r {} \; -o \ + ! -type d ! -perm -444 -exec $(install_sh) -c -m a+r {} {} \; \ + || chmod -R a+r "$(distdir)" +dist-gzip: distdir + tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz + $(am__remove_distdir) + +dist-bzip2: distdir + tardir=$(distdir) && $(am__tar) | BZIP2=$${BZIP2--9} bzip2 -c >$(distdir).tar.bz2 + $(am__remove_distdir) + +dist-lzip: distdir + tardir=$(distdir) && $(am__tar) | lzip -c $${LZIP_OPT--9} >$(distdir).tar.lz + $(am__remove_distdir) + +dist-lzma: distdir + tardir=$(distdir) && $(am__tar) | lzma -9 -c >$(distdir).tar.lzma + $(am__remove_distdir) + +dist-xz: distdir + tardir=$(distdir) && $(am__tar) | XZ_OPT=$${XZ_OPT--e} xz -c >$(distdir).tar.xz + $(am__remove_distdir) + +dist-tarZ: distdir + tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z + $(am__remove_distdir) + +dist-shar: distdir + shar $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).shar.gz + $(am__remove_distdir) + +dist-zip: distdir + -rm -f $(distdir).zip + zip -rq $(distdir).zip $(distdir) + $(am__remove_distdir) + +dist dist-all: distdir + tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz + $(am__remove_distdir) + +# This target untars the dist file and tries a VPATH configuration. Then +# it guarantees that the distribution is self-contained by making another +# tarfile. +distcheck: dist + case '$(DIST_ARCHIVES)' in \ + *.tar.gz*) \ + GZIP=$(GZIP_ENV) gzip -dc $(distdir).tar.gz | $(am__untar) ;;\ + *.tar.bz2*) \ + bzip2 -dc $(distdir).tar.bz2 | $(am__untar) ;;\ + *.tar.lzma*) \ + lzma -dc $(distdir).tar.lzma | $(am__untar) ;;\ + *.tar.lz*) \ + lzip -dc $(distdir).tar.lz | $(am__untar) ;;\ + *.tar.xz*) \ + xz -dc $(distdir).tar.xz | $(am__untar) ;;\ + *.tar.Z*) \ + uncompress -c $(distdir).tar.Z | $(am__untar) ;;\ + *.shar.gz*) \ + GZIP=$(GZIP_ENV) gzip -dc $(distdir).shar.gz | unshar ;;\ + *.zip*) \ + unzip $(distdir).zip ;;\ + esac + chmod -R a-w $(distdir); chmod a+w $(distdir) + mkdir $(distdir)/_build + mkdir $(distdir)/_inst + chmod a-w $(distdir) + test -d $(distdir)/_build || exit 0; \ + dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \ + && dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \ + && am__cwd=`pwd` \ + && $(am__cd) $(distdir)/_build \ + && ../configure --srcdir=.. --prefix="$$dc_install_base" \ + $(AM_DISTCHECK_CONFIGURE_FLAGS) \ + $(DISTCHECK_CONFIGURE_FLAGS) \ + && $(MAKE) $(AM_MAKEFLAGS) \ + && $(MAKE) $(AM_MAKEFLAGS) dvi \ + && $(MAKE) $(AM_MAKEFLAGS) check \ + && $(MAKE) $(AM_MAKEFLAGS) install \ + && $(MAKE) $(AM_MAKEFLAGS) installcheck \ + && $(MAKE) $(AM_MAKEFLAGS) uninstall \ + && $(MAKE) $(AM_MAKEFLAGS) distuninstallcheck_dir="$$dc_install_base" \ + distuninstallcheck \ + && chmod -R a-w "$$dc_install_base" \ + && ({ \ + (cd ../.. && umask 077 && mkdir "$$dc_destdir") \ + && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" install \ + && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" uninstall \ + && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" \ + distuninstallcheck_dir="$$dc_destdir" distuninstallcheck; \ + } || { rm -rf "$$dc_destdir"; exit 1; }) \ + && rm -rf "$$dc_destdir" \ + && $(MAKE) $(AM_MAKEFLAGS) dist \ + && rm -rf $(DIST_ARCHIVES) \ + && $(MAKE) $(AM_MAKEFLAGS) distcleancheck \ + && cd "$$am__cwd" \ + || exit 1 + $(am__remove_distdir) + @(echo "$(distdir) archives ready for distribution: "; \ + list='$(DIST_ARCHIVES)'; for i in $$list; do echo $$i; done) | \ + sed -e 1h -e 1s/./=/g -e 1p -e 1x -e '$$p' -e '$$x' +distuninstallcheck: + @test -n '$(distuninstallcheck_dir)' || { \ + echo 'ERROR: trying to run $@ with an empty' \ + '$$(distuninstallcheck_dir)' >&2; \ + exit 1; \ + }; \ + $(am__cd) '$(distuninstallcheck_dir)' || { \ + echo 'ERROR: cannot chdir into $(distuninstallcheck_dir)' >&2; \ + exit 1; \ + }; \ + test `$(am__distuninstallcheck_listfiles) | wc -l` -eq 0 \ + || { echo "ERROR: files left after uninstall:" ; \ + if test -n "$(DESTDIR)"; then \ + echo " (check DESTDIR support)"; \ + fi ; \ + $(distuninstallcheck_listfiles) ; \ + exit 1; } >&2 +distcleancheck: distclean + @if test '$(srcdir)' = . ; then \ + echo "ERROR: distcleancheck can only run from a VPATH build" ; \ + exit 1 ; \ + fi + @test `$(distcleancheck_listfiles) | wc -l` -eq 0 \ + || { echo "ERROR: files left in build directory after distclean:" ; \ + $(distcleancheck_listfiles) ; \ + exit 1; } >&2 +check-am: all-am +check: check-recursive +all-am: Makefile $(DATA) config.h +installdirs: installdirs-recursive +installdirs-am: + for dir in "$(DESTDIR)$(pkgconfigdir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +install: install-recursive +install-exec: install-exec-recursive +install-data: install-data-recursive +uninstall: uninstall-recursive + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-recursive +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-recursive + +clean-am: clean-generic clean-libtool mostlyclean-am + +distclean: distclean-recursive + -rm -f $(am__CONFIG_DISTCLEAN_FILES) + -rm -f Makefile +distclean-am: clean-am distclean-generic distclean-hdr \ + distclean-libtool distclean-tags + +dvi: dvi-recursive + +dvi-am: + +html: html-recursive + +html-am: + +info: info-recursive + +info-am: + +install-data-am: install-pkgconfigDATA + +install-dvi: install-dvi-recursive + +install-dvi-am: + +install-exec-am: + +install-html: install-html-recursive + +install-html-am: + +install-info: install-info-recursive + +install-info-am: + +install-man: + +install-pdf: install-pdf-recursive + +install-pdf-am: + +install-ps: install-ps-recursive + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-recursive + -rm -f $(am__CONFIG_DISTCLEAN_FILES) + -rm -rf $(top_srcdir)/autom4te.cache + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic \ + maintainer-clean-local + +mostlyclean: mostlyclean-recursive + +mostlyclean-am: mostlyclean-generic mostlyclean-libtool + +pdf: pdf-recursive + +pdf-am: + +ps: ps-recursive + +ps-am: + +uninstall-am: uninstall-pkgconfigDATA + +.MAKE: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) all \ + ctags-recursive install-am install-strip tags-recursive + +.PHONY: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) CTAGS GTAGS \ + all all-am am--refresh check check-am clean clean-generic \ + clean-libtool ctags ctags-recursive dist dist-all dist-bzip2 \ + dist-gzip dist-lzip dist-lzma dist-shar dist-tarZ dist-xz \ + dist-zip distcheck distclean distclean-generic distclean-hdr \ + distclean-libtool distclean-tags distcleancheck distdir \ + distuninstallcheck dvi dvi-am html html-am info info-am \ + install install-am install-data install-data-am install-dvi \ + install-dvi-am install-exec install-exec-am install-html \ + install-html-am install-info install-info-am install-man \ + install-pdf install-pdf-am install-pkgconfigDATA install-ps \ + install-ps-am install-strip installcheck installcheck-am \ + installdirs installdirs-am maintainer-clean \ + maintainer-clean-generic maintainer-clean-local mostlyclean \ + mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ + tags tags-recursive uninstall uninstall-am \ + uninstall-pkgconfigDATA + + +maintainer-clean-local: + -rm -f aclocal.m4 config.h.in configure config/* + -find ${builddir} -name Makefile.in -exec rm -f '{}' ';' + +.PHONY: bootstrap +bootstrap: maintainer-clean + ./bootstrap + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/web/server/h2o/libh2o/deps/yaml/README b/web/server/h2o/libh2o/deps/yaml/README new file mode 100644 index 00000000..d35ebcc9 --- /dev/null +++ b/web/server/h2o/libh2o/deps/yaml/README @@ -0,0 +1,27 @@ +LibYAML - A C library for parsing and emitting YAML. + +To build and install the library, run: +$ ./configure +$ make +# make install + +If you checked the source code from the Subversion repository, run +$ ./bootstrap +$ ./configure +$ make +# make install + +For more information, check the LibYAML homepage: +'http://pyyaml.org/wiki/LibYAML'. + +Post your questions and opinions to the YAML-Core mailing list: +'http://lists.sourceforge.net/lists/listinfo/yaml-core'. + +Submit bug reports and feature requests to the LibYAML bug tracker: +'http://pyyaml.org/newticket?component=libyaml'. + +LibYAML is written by Kirill Simonov . It is released +under the MIT license. See the file LICENSE for more details. + +This project is developed for Python Software Foundation as a part of +Google Summer of Code under the mentorship of Clark Evans. diff --git a/web/server/h2o/libh2o/deps/yaml/aclocal.m4 b/web/server/h2o/libh2o/deps/yaml/aclocal.m4 new file mode 100644 index 00000000..a8e16e43 --- /dev/null +++ b/web/server/h2o/libh2o/deps/yaml/aclocal.m4 @@ -0,0 +1,9577 @@ +# generated automatically by aclocal 1.11.3 -*- Autoconf -*- + +# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, +# 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software Foundation, +# Inc. +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +m4_ifndef([AC_AUTOCONF_VERSION], + [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl +m4_if(m4_defn([AC_AUTOCONF_VERSION]), [2.68],, +[m4_warning([this file was generated for autoconf 2.68. +You have another version of autoconf. It may work, but is not guaranteed to. +If you have problems, you may need to regenerate the build system entirely. +To do so, use the procedure documented by the package, typically `autoreconf'.])]) + +# libtool.m4 - Configure libtool for the host system. -*-Autoconf-*- +# +# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, +# 2006, 2007, 2008, 2009, 2010, 2011 Free Software +# Foundation, Inc. +# Written by Gordon Matzigkeit, 1996 +# +# This file is free software; the Free Software Foundation gives +# unlimited permission to copy and/or distribute it, with or without +# modifications, as long as this notice is preserved. + +m4_define([_LT_COPYING], [dnl +# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, +# 2006, 2007, 2008, 2009, 2010, 2011 Free Software +# Foundation, Inc. +# Written by Gordon Matzigkeit, 1996 +# +# This file is part of GNU Libtool. +# +# GNU Libtool is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# +# As a special exception to the GNU General Public License, +# if you distribute this file as part of a program or library that +# is built using GNU Libtool, you may include this file under the +# same distribution terms that you use for the rest of that program. +# +# GNU Libtool is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GNU Libtool; see the file COPYING. If not, a copy +# can be downloaded from http://www.gnu.org/licenses/gpl.html, or +# obtained by writing to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +]) + +# serial 57 LT_INIT + + +# LT_PREREQ(VERSION) +# ------------------ +# Complain and exit if this libtool version is less that VERSION. +m4_defun([LT_PREREQ], +[m4_if(m4_version_compare(m4_defn([LT_PACKAGE_VERSION]), [$1]), -1, + [m4_default([$3], + [m4_fatal([Libtool version $1 or higher is required], + 63)])], + [$2])]) + + +# _LT_CHECK_BUILDDIR +# ------------------ +# Complain if the absolute build directory name contains unusual characters +m4_defun([_LT_CHECK_BUILDDIR], +[case `pwd` in + *\ * | *\ *) + AC_MSG_WARN([Libtool does not cope well with whitespace in `pwd`]) ;; +esac +]) + + +# LT_INIT([OPTIONS]) +# ------------------ +AC_DEFUN([LT_INIT], +[AC_PREREQ([2.58])dnl We use AC_INCLUDES_DEFAULT +AC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT])dnl +AC_BEFORE([$0], [LT_LANG])dnl +AC_BEFORE([$0], [LT_OUTPUT])dnl +AC_BEFORE([$0], [LTDL_INIT])dnl +m4_require([_LT_CHECK_BUILDDIR])dnl + +dnl Autoconf doesn't catch unexpanded LT_ macros by default: +m4_pattern_forbid([^_?LT_[A-Z_]+$])dnl +m4_pattern_allow([^(_LT_EOF|LT_DLGLOBAL|LT_DLLAZY_OR_NOW|LT_MULTI_MODULE)$])dnl +dnl aclocal doesn't pull ltoptions.m4, ltsugar.m4, or ltversion.m4 +dnl unless we require an AC_DEFUNed macro: +AC_REQUIRE([LTOPTIONS_VERSION])dnl +AC_REQUIRE([LTSUGAR_VERSION])dnl +AC_REQUIRE([LTVERSION_VERSION])dnl +AC_REQUIRE([LTOBSOLETE_VERSION])dnl +m4_require([_LT_PROG_LTMAIN])dnl + +_LT_SHELL_INIT([SHELL=${CONFIG_SHELL-/bin/sh}]) + +dnl Parse OPTIONS +_LT_SET_OPTIONS([$0], [$1]) + +# This can be used to rebuild libtool when needed +LIBTOOL_DEPS="$ltmain" + +# Always use our own libtool. +LIBTOOL='$(SHELL) $(top_builddir)/libtool' +AC_SUBST(LIBTOOL)dnl + +_LT_SETUP + +# Only expand once: +m4_define([LT_INIT]) +])# LT_INIT + +# Old names: +AU_ALIAS([AC_PROG_LIBTOOL], [LT_INIT]) +AU_ALIAS([AM_PROG_LIBTOOL], [LT_INIT]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_PROG_LIBTOOL], []) +dnl AC_DEFUN([AM_PROG_LIBTOOL], []) + + +# _LT_CC_BASENAME(CC) +# ------------------- +# Calculate cc_basename. Skip known compiler wrappers and cross-prefix. +m4_defun([_LT_CC_BASENAME], +[for cc_temp in $1""; do + case $cc_temp in + compile | *[[\\/]]compile | ccache | *[[\\/]]ccache ) ;; + distcc | *[[\\/]]distcc | purify | *[[\\/]]purify ) ;; + \-*) ;; + *) break;; + esac +done +cc_basename=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"` +]) + + +# _LT_FILEUTILS_DEFAULTS +# ---------------------- +# It is okay to use these file commands and assume they have been set +# sensibly after `m4_require([_LT_FILEUTILS_DEFAULTS])'. +m4_defun([_LT_FILEUTILS_DEFAULTS], +[: ${CP="cp -f"} +: ${MV="mv -f"} +: ${RM="rm -f"} +])# _LT_FILEUTILS_DEFAULTS + + +# _LT_SETUP +# --------- +m4_defun([_LT_SETUP], +[AC_REQUIRE([AC_CANONICAL_HOST])dnl +AC_REQUIRE([AC_CANONICAL_BUILD])dnl +AC_REQUIRE([_LT_PREPARE_SED_QUOTE_VARS])dnl +AC_REQUIRE([_LT_PROG_ECHO_BACKSLASH])dnl + +_LT_DECL([], [PATH_SEPARATOR], [1], [The PATH separator for the build system])dnl +dnl +_LT_DECL([], [host_alias], [0], [The host system])dnl +_LT_DECL([], [host], [0])dnl +_LT_DECL([], [host_os], [0])dnl +dnl +_LT_DECL([], [build_alias], [0], [The build system])dnl +_LT_DECL([], [build], [0])dnl +_LT_DECL([], [build_os], [0])dnl +dnl +AC_REQUIRE([AC_PROG_CC])dnl +AC_REQUIRE([LT_PATH_LD])dnl +AC_REQUIRE([LT_PATH_NM])dnl +dnl +AC_REQUIRE([AC_PROG_LN_S])dnl +test -z "$LN_S" && LN_S="ln -s" +_LT_DECL([], [LN_S], [1], [Whether we need soft or hard links])dnl +dnl +AC_REQUIRE([LT_CMD_MAX_LEN])dnl +_LT_DECL([objext], [ac_objext], [0], [Object file suffix (normally "o")])dnl +_LT_DECL([], [exeext], [0], [Executable file suffix (normally "")])dnl +dnl +m4_require([_LT_FILEUTILS_DEFAULTS])dnl +m4_require([_LT_CHECK_SHELL_FEATURES])dnl +m4_require([_LT_PATH_CONVERSION_FUNCTIONS])dnl +m4_require([_LT_CMD_RELOAD])dnl +m4_require([_LT_CHECK_MAGIC_METHOD])dnl +m4_require([_LT_CHECK_SHAREDLIB_FROM_LINKLIB])dnl +m4_require([_LT_CMD_OLD_ARCHIVE])dnl +m4_require([_LT_CMD_GLOBAL_SYMBOLS])dnl +m4_require([_LT_WITH_SYSROOT])dnl + +_LT_CONFIG_LIBTOOL_INIT([ +# See if we are running on zsh, and set the options which allow our +# commands through without removal of \ escapes INIT. +if test -n "\${ZSH_VERSION+set}" ; then + setopt NO_GLOB_SUBST +fi +]) +if test -n "${ZSH_VERSION+set}" ; then + setopt NO_GLOB_SUBST +fi + +_LT_CHECK_OBJDIR + +m4_require([_LT_TAG_COMPILER])dnl + +case $host_os in +aix3*) + # AIX sometimes has problems with the GCC collect2 program. For some + # reason, if we set the COLLECT_NAMES environment variable, the problems + # vanish in a puff of smoke. + if test "X${COLLECT_NAMES+set}" != Xset; then + COLLECT_NAMES= + export COLLECT_NAMES + fi + ;; +esac + +# Global variables: +ofile=libtool +can_build_shared=yes + +# All known linkers require a `.a' archive for static linking (except MSVC, +# which needs '.lib'). +libext=a + +with_gnu_ld="$lt_cv_prog_gnu_ld" + +old_CC="$CC" +old_CFLAGS="$CFLAGS" + +# Set sane defaults for various variables +test -z "$CC" && CC=cc +test -z "$LTCC" && LTCC=$CC +test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS +test -z "$LD" && LD=ld +test -z "$ac_objext" && ac_objext=o + +_LT_CC_BASENAME([$compiler]) + +# Only perform the check for file, if the check method requires it +test -z "$MAGIC_CMD" && MAGIC_CMD=file +case $deplibs_check_method in +file_magic*) + if test "$file_magic_cmd" = '$MAGIC_CMD'; then + _LT_PATH_MAGIC + fi + ;; +esac + +# Use C for the default configuration in the libtool script +LT_SUPPORTED_TAG([CC]) +_LT_LANG_C_CONFIG +_LT_LANG_DEFAULT_CONFIG +_LT_CONFIG_COMMANDS +])# _LT_SETUP + + +# _LT_PREPARE_SED_QUOTE_VARS +# -------------------------- +# Define a few sed substitution that help us do robust quoting. +m4_defun([_LT_PREPARE_SED_QUOTE_VARS], +[# Backslashify metacharacters that are still active within +# double-quoted strings. +sed_quote_subst='s/\([["`$\\]]\)/\\\1/g' + +# Same as above, but do not quote variable references. +double_quote_subst='s/\([["`\\]]\)/\\\1/g' + +# Sed substitution to delay expansion of an escaped shell variable in a +# double_quote_subst'ed string. +delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g' + +# Sed substitution to delay expansion of an escaped single quote. +delay_single_quote_subst='s/'\''/'\'\\\\\\\'\''/g' + +# Sed substitution to avoid accidental globbing in evaled expressions +no_glob_subst='s/\*/\\\*/g' +]) + +# _LT_PROG_LTMAIN +# --------------- +# Note that this code is called both from `configure', and `config.status' +# now that we use AC_CONFIG_COMMANDS to generate libtool. Notably, +# `config.status' has no value for ac_aux_dir unless we are using Automake, +# so we pass a copy along to make sure it has a sensible value anyway. +m4_defun([_LT_PROG_LTMAIN], +[m4_ifdef([AC_REQUIRE_AUX_FILE], [AC_REQUIRE_AUX_FILE([ltmain.sh])])dnl +_LT_CONFIG_LIBTOOL_INIT([ac_aux_dir='$ac_aux_dir']) +ltmain="$ac_aux_dir/ltmain.sh" +])# _LT_PROG_LTMAIN + + + +# So that we can recreate a full libtool script including additional +# tags, we accumulate the chunks of code to send to AC_CONFIG_COMMANDS +# in macros and then make a single call at the end using the `libtool' +# label. + + +# _LT_CONFIG_LIBTOOL_INIT([INIT-COMMANDS]) +# ---------------------------------------- +# Register INIT-COMMANDS to be passed to AC_CONFIG_COMMANDS later. +m4_define([_LT_CONFIG_LIBTOOL_INIT], +[m4_ifval([$1], + [m4_append([_LT_OUTPUT_LIBTOOL_INIT], + [$1 +])])]) + +# Initialize. +m4_define([_LT_OUTPUT_LIBTOOL_INIT]) + + +# _LT_CONFIG_LIBTOOL([COMMANDS]) +# ------------------------------ +# Register COMMANDS to be passed to AC_CONFIG_COMMANDS later. +m4_define([_LT_CONFIG_LIBTOOL], +[m4_ifval([$1], + [m4_append([_LT_OUTPUT_LIBTOOL_COMMANDS], + [$1 +])])]) + +# Initialize. +m4_define([_LT_OUTPUT_LIBTOOL_COMMANDS]) + + +# _LT_CONFIG_SAVE_COMMANDS([COMMANDS], [INIT_COMMANDS]) +# ----------------------------------------------------- +m4_defun([_LT_CONFIG_SAVE_COMMANDS], +[_LT_CONFIG_LIBTOOL([$1]) +_LT_CONFIG_LIBTOOL_INIT([$2]) +]) + + +# _LT_FORMAT_COMMENT([COMMENT]) +# ----------------------------- +# Add leading comment marks to the start of each line, and a trailing +# full-stop to the whole comment if one is not present already. +m4_define([_LT_FORMAT_COMMENT], +[m4_ifval([$1], [ +m4_bpatsubst([m4_bpatsubst([$1], [^ *], [# ])], + [['`$\]], [\\\&])]m4_bmatch([$1], [[!?.]$], [], [.]) +)]) + + + + + +# _LT_DECL([CONFIGNAME], VARNAME, VALUE, [DESCRIPTION], [IS-TAGGED?]) +# ------------------------------------------------------------------- +# CONFIGNAME is the name given to the value in the libtool script. +# VARNAME is the (base) name used in the configure script. +# VALUE may be 0, 1 or 2 for a computed quote escaped value based on +# VARNAME. Any other value will be used directly. +m4_define([_LT_DECL], +[lt_if_append_uniq([lt_decl_varnames], [$2], [, ], + [lt_dict_add_subkey([lt_decl_dict], [$2], [libtool_name], + [m4_ifval([$1], [$1], [$2])]) + lt_dict_add_subkey([lt_decl_dict], [$2], [value], [$3]) + m4_ifval([$4], + [lt_dict_add_subkey([lt_decl_dict], [$2], [description], [$4])]) + lt_dict_add_subkey([lt_decl_dict], [$2], + [tagged?], [m4_ifval([$5], [yes], [no])])]) +]) + + +# _LT_TAGDECL([CONFIGNAME], VARNAME, VALUE, [DESCRIPTION]) +# -------------------------------------------------------- +m4_define([_LT_TAGDECL], [_LT_DECL([$1], [$2], [$3], [$4], [yes])]) + + +# lt_decl_tag_varnames([SEPARATOR], [VARNAME1...]) +# ------------------------------------------------ +m4_define([lt_decl_tag_varnames], +[_lt_decl_filter([tagged?], [yes], $@)]) + + +# _lt_decl_filter(SUBKEY, VALUE, [SEPARATOR], [VARNAME1..]) +# --------------------------------------------------------- +m4_define([_lt_decl_filter], +[m4_case([$#], + [0], [m4_fatal([$0: too few arguments: $#])], + [1], [m4_fatal([$0: too few arguments: $#: $1])], + [2], [lt_dict_filter([lt_decl_dict], [$1], [$2], [], lt_decl_varnames)], + [3], [lt_dict_filter([lt_decl_dict], [$1], [$2], [$3], lt_decl_varnames)], + [lt_dict_filter([lt_decl_dict], $@)])[]dnl +]) + + +# lt_decl_quote_varnames([SEPARATOR], [VARNAME1...]) +# -------------------------------------------------- +m4_define([lt_decl_quote_varnames], +[_lt_decl_filter([value], [1], $@)]) + + +# lt_decl_dquote_varnames([SEPARATOR], [VARNAME1...]) +# --------------------------------------------------- +m4_define([lt_decl_dquote_varnames], +[_lt_decl_filter([value], [2], $@)]) + + +# lt_decl_varnames_tagged([SEPARATOR], [VARNAME1...]) +# --------------------------------------------------- +m4_define([lt_decl_varnames_tagged], +[m4_assert([$# <= 2])dnl +_$0(m4_quote(m4_default([$1], [[, ]])), + m4_ifval([$2], [[$2]], [m4_dquote(lt_decl_tag_varnames)]), + m4_split(m4_normalize(m4_quote(_LT_TAGS)), [ ]))]) +m4_define([_lt_decl_varnames_tagged], +[m4_ifval([$3], [lt_combine([$1], [$2], [_], $3)])]) + + +# lt_decl_all_varnames([SEPARATOR], [VARNAME1...]) +# ------------------------------------------------ +m4_define([lt_decl_all_varnames], +[_$0(m4_quote(m4_default([$1], [[, ]])), + m4_if([$2], [], + m4_quote(lt_decl_varnames), + m4_quote(m4_shift($@))))[]dnl +]) +m4_define([_lt_decl_all_varnames], +[lt_join($@, lt_decl_varnames_tagged([$1], + lt_decl_tag_varnames([[, ]], m4_shift($@))))dnl +]) + + +# _LT_CONFIG_STATUS_DECLARE([VARNAME]) +# ------------------------------------ +# Quote a variable value, and forward it to `config.status' so that its +# declaration there will have the same value as in `configure'. VARNAME +# must have a single quote delimited value for this to work. +m4_define([_LT_CONFIG_STATUS_DECLARE], +[$1='`$ECHO "$][$1" | $SED "$delay_single_quote_subst"`']) + + +# _LT_CONFIG_STATUS_DECLARATIONS +# ------------------------------ +# We delimit libtool config variables with single quotes, so when +# we write them to config.status, we have to be sure to quote all +# embedded single quotes properly. In configure, this macro expands +# each variable declared with _LT_DECL (and _LT_TAGDECL) into: +# +# ='`$ECHO "$" | $SED "$delay_single_quote_subst"`' +m4_defun([_LT_CONFIG_STATUS_DECLARATIONS], +[m4_foreach([_lt_var], m4_quote(lt_decl_all_varnames), + [m4_n([_LT_CONFIG_STATUS_DECLARE(_lt_var)])])]) + + +# _LT_LIBTOOL_TAGS +# ---------------- +# Output comment and list of tags supported by the script +m4_defun([_LT_LIBTOOL_TAGS], +[_LT_FORMAT_COMMENT([The names of the tagged configurations supported by this script])dnl +available_tags="_LT_TAGS"dnl +]) + + +# _LT_LIBTOOL_DECLARE(VARNAME, [TAG]) +# ----------------------------------- +# Extract the dictionary values for VARNAME (optionally with TAG) and +# expand to a commented shell variable setting: +# +# # Some comment about what VAR is for. +# visible_name=$lt_internal_name +m4_define([_LT_LIBTOOL_DECLARE], +[_LT_FORMAT_COMMENT(m4_quote(lt_dict_fetch([lt_decl_dict], [$1], + [description])))[]dnl +m4_pushdef([_libtool_name], + m4_quote(lt_dict_fetch([lt_decl_dict], [$1], [libtool_name])))[]dnl +m4_case(m4_quote(lt_dict_fetch([lt_decl_dict], [$1], [value])), + [0], [_libtool_name=[$]$1], + [1], [_libtool_name=$lt_[]$1], + [2], [_libtool_name=$lt_[]$1], + [_libtool_name=lt_dict_fetch([lt_decl_dict], [$1], [value])])[]dnl +m4_ifval([$2], [_$2])[]m4_popdef([_libtool_name])[]dnl +]) + + +# _LT_LIBTOOL_CONFIG_VARS +# ----------------------- +# Produce commented declarations of non-tagged libtool config variables +# suitable for insertion in the LIBTOOL CONFIG section of the `libtool' +# script. Tagged libtool config variables (even for the LIBTOOL CONFIG +# section) are produced by _LT_LIBTOOL_TAG_VARS. +m4_defun([_LT_LIBTOOL_CONFIG_VARS], +[m4_foreach([_lt_var], + m4_quote(_lt_decl_filter([tagged?], [no], [], lt_decl_varnames)), + [m4_n([_LT_LIBTOOL_DECLARE(_lt_var)])])]) + + +# _LT_LIBTOOL_TAG_VARS(TAG) +# ------------------------- +m4_define([_LT_LIBTOOL_TAG_VARS], +[m4_foreach([_lt_var], m4_quote(lt_decl_tag_varnames), + [m4_n([_LT_LIBTOOL_DECLARE(_lt_var, [$1])])])]) + + +# _LT_TAGVAR(VARNAME, [TAGNAME]) +# ------------------------------ +m4_define([_LT_TAGVAR], [m4_ifval([$2], [$1_$2], [$1])]) + + +# _LT_CONFIG_COMMANDS +# ------------------- +# Send accumulated output to $CONFIG_STATUS. Thanks to the lists of +# variables for single and double quote escaping we saved from calls +# to _LT_DECL, we can put quote escaped variables declarations +# into `config.status', and then the shell code to quote escape them in +# for loops in `config.status'. Finally, any additional code accumulated +# from calls to _LT_CONFIG_LIBTOOL_INIT is expanded. +m4_defun([_LT_CONFIG_COMMANDS], +[AC_PROVIDE_IFELSE([LT_OUTPUT], + dnl If the libtool generation code has been placed in $CONFIG_LT, + dnl instead of duplicating it all over again into config.status, + dnl then we will have config.status run $CONFIG_LT later, so it + dnl needs to know what name is stored there: + [AC_CONFIG_COMMANDS([libtool], + [$SHELL $CONFIG_LT || AS_EXIT(1)], [CONFIG_LT='$CONFIG_LT'])], + dnl If the libtool generation code is destined for config.status, + dnl expand the accumulated commands and init code now: + [AC_CONFIG_COMMANDS([libtool], + [_LT_OUTPUT_LIBTOOL_COMMANDS], [_LT_OUTPUT_LIBTOOL_COMMANDS_INIT])]) +])#_LT_CONFIG_COMMANDS + + +# Initialize. +m4_define([_LT_OUTPUT_LIBTOOL_COMMANDS_INIT], +[ + +# The HP-UX ksh and POSIX shell print the target directory to stdout +# if CDPATH is set. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + +sed_quote_subst='$sed_quote_subst' +double_quote_subst='$double_quote_subst' +delay_variable_subst='$delay_variable_subst' +_LT_CONFIG_STATUS_DECLARATIONS +LTCC='$LTCC' +LTCFLAGS='$LTCFLAGS' +compiler='$compiler_DEFAULT' + +# A function that is used when there is no print builtin or printf. +func_fallback_echo () +{ + eval 'cat <<_LTECHO_EOF +\$[]1 +_LTECHO_EOF' +} + +# Quote evaled strings. +for var in lt_decl_all_varnames([[ \ +]], lt_decl_quote_varnames); do + case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in + *[[\\\\\\\`\\"\\\$]]*) + eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED \\"\\\$sed_quote_subst\\"\\\`\\\\\\"" + ;; + *) + eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" + ;; + esac +done + +# Double-quote double-evaled strings. +for var in lt_decl_all_varnames([[ \ +]], lt_decl_dquote_varnames); do + case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in + *[[\\\\\\\`\\"\\\$]]*) + eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\"" + ;; + *) + eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" + ;; + esac +done + +_LT_OUTPUT_LIBTOOL_INIT +]) + +# _LT_GENERATED_FILE_INIT(FILE, [COMMENT]) +# ------------------------------------ +# Generate a child script FILE with all initialization necessary to +# reuse the environment learned by the parent script, and make the +# file executable. If COMMENT is supplied, it is inserted after the +# `#!' sequence but before initialization text begins. After this +# macro, additional text can be appended to FILE to form the body of +# the child script. The macro ends with non-zero status if the +# file could not be fully written (such as if the disk is full). +m4_ifdef([AS_INIT_GENERATED], +[m4_defun([_LT_GENERATED_FILE_INIT],[AS_INIT_GENERATED($@)])], +[m4_defun([_LT_GENERATED_FILE_INIT], +[m4_require([AS_PREPARE])]dnl +[m4_pushdef([AS_MESSAGE_LOG_FD])]dnl +[lt_write_fail=0 +cat >$1 <<_ASEOF || lt_write_fail=1 +#! $SHELL +# Generated by $as_me. +$2 +SHELL=\${CONFIG_SHELL-$SHELL} +export SHELL +_ASEOF +cat >>$1 <<\_ASEOF || lt_write_fail=1 +AS_SHELL_SANITIZE +_AS_PREPARE +exec AS_MESSAGE_FD>&1 +_ASEOF +test $lt_write_fail = 0 && chmod +x $1[]dnl +m4_popdef([AS_MESSAGE_LOG_FD])])])# _LT_GENERATED_FILE_INIT + +# LT_OUTPUT +# --------- +# This macro allows early generation of the libtool script (before +# AC_OUTPUT is called), incase it is used in configure for compilation +# tests. +AC_DEFUN([LT_OUTPUT], +[: ${CONFIG_LT=./config.lt} +AC_MSG_NOTICE([creating $CONFIG_LT]) +_LT_GENERATED_FILE_INIT(["$CONFIG_LT"], +[# Run this file to recreate a libtool stub with the current configuration.]) + +cat >>"$CONFIG_LT" <<\_LTEOF +lt_cl_silent=false +exec AS_MESSAGE_LOG_FD>>config.log +{ + echo + AS_BOX([Running $as_me.]) +} >&AS_MESSAGE_LOG_FD + +lt_cl_help="\ +\`$as_me' creates a local libtool stub from the current configuration, +for use in further configure time tests before the real libtool is +generated. + +Usage: $[0] [[OPTIONS]] + + -h, --help print this help, then exit + -V, --version print version number, then exit + -q, --quiet do not print progress messages + -d, --debug don't remove temporary files + +Report bugs to ." + +lt_cl_version="\ +m4_ifset([AC_PACKAGE_NAME], [AC_PACKAGE_NAME ])config.lt[]dnl +m4_ifset([AC_PACKAGE_VERSION], [ AC_PACKAGE_VERSION]) +configured by $[0], generated by m4_PACKAGE_STRING. + +Copyright (C) 2011 Free Software Foundation, Inc. +This config.lt script is free software; the Free Software Foundation +gives unlimited permision to copy, distribute and modify it." + +while test $[#] != 0 +do + case $[1] in + --version | --v* | -V ) + echo "$lt_cl_version"; exit 0 ;; + --help | --h* | -h ) + echo "$lt_cl_help"; exit 0 ;; + --debug | --d* | -d ) + debug=: ;; + --quiet | --q* | --silent | --s* | -q ) + lt_cl_silent=: ;; + + -*) AC_MSG_ERROR([unrecognized option: $[1] +Try \`$[0] --help' for more information.]) ;; + + *) AC_MSG_ERROR([unrecognized argument: $[1] +Try \`$[0] --help' for more information.]) ;; + esac + shift +done + +if $lt_cl_silent; then + exec AS_MESSAGE_FD>/dev/null +fi +_LTEOF + +cat >>"$CONFIG_LT" <<_LTEOF +_LT_OUTPUT_LIBTOOL_COMMANDS_INIT +_LTEOF + +cat >>"$CONFIG_LT" <<\_LTEOF +AC_MSG_NOTICE([creating $ofile]) +_LT_OUTPUT_LIBTOOL_COMMANDS +AS_EXIT(0) +_LTEOF +chmod +x "$CONFIG_LT" + +# configure is writing to config.log, but config.lt does its own redirection, +# appending to config.log, which fails on DOS, as config.log is still kept +# open by configure. Here we exec the FD to /dev/null, effectively closing +# config.log, so it can be properly (re)opened and appended to by config.lt. +lt_cl_success=: +test "$silent" = yes && + lt_config_lt_args="$lt_config_lt_args --quiet" +exec AS_MESSAGE_LOG_FD>/dev/null +$SHELL "$CONFIG_LT" $lt_config_lt_args || lt_cl_success=false +exec AS_MESSAGE_LOG_FD>>config.log +$lt_cl_success || AS_EXIT(1) +])# LT_OUTPUT + + +# _LT_CONFIG(TAG) +# --------------- +# If TAG is the built-in tag, create an initial libtool script with a +# default configuration from the untagged config vars. Otherwise add code +# to config.status for appending the configuration named by TAG from the +# matching tagged config vars. +m4_defun([_LT_CONFIG], +[m4_require([_LT_FILEUTILS_DEFAULTS])dnl +_LT_CONFIG_SAVE_COMMANDS([ + m4_define([_LT_TAG], m4_if([$1], [], [C], [$1]))dnl + m4_if(_LT_TAG, [C], [ + # See if we are running on zsh, and set the options which allow our + # commands through without removal of \ escapes. + if test -n "${ZSH_VERSION+set}" ; then + setopt NO_GLOB_SUBST + fi + + cfgfile="${ofile}T" + trap "$RM \"$cfgfile\"; exit 1" 1 2 15 + $RM "$cfgfile" + + cat <<_LT_EOF >> "$cfgfile" +#! $SHELL + +# `$ECHO "$ofile" | sed 's%^.*/%%'` - Provide generalized library-building support services. +# Generated automatically by $as_me ($PACKAGE$TIMESTAMP) $VERSION +# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`: +# NOTE: Changes made to this file will be lost: look at ltmain.sh. +# +_LT_COPYING +_LT_LIBTOOL_TAGS + +# ### BEGIN LIBTOOL CONFIG +_LT_LIBTOOL_CONFIG_VARS +_LT_LIBTOOL_TAG_VARS +# ### END LIBTOOL CONFIG + +_LT_EOF + + case $host_os in + aix3*) + cat <<\_LT_EOF >> "$cfgfile" +# AIX sometimes has problems with the GCC collect2 program. For some +# reason, if we set the COLLECT_NAMES environment variable, the problems +# vanish in a puff of smoke. +if test "X${COLLECT_NAMES+set}" != Xset; then + COLLECT_NAMES= + export COLLECT_NAMES +fi +_LT_EOF + ;; + esac + + _LT_PROG_LTMAIN + + # We use sed instead of cat because bash on DJGPP gets confused if + # if finds mixed CR/LF and LF-only lines. Since sed operates in + # text mode, it properly converts lines to CR/LF. This bash problem + # is reportedly fixed, but why not run on old versions too? + sed '$q' "$ltmain" >> "$cfgfile" \ + || (rm -f "$cfgfile"; exit 1) + + _LT_PROG_REPLACE_SHELLFNS + + mv -f "$cfgfile" "$ofile" || + (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile") + chmod +x "$ofile" +], +[cat <<_LT_EOF >> "$ofile" + +dnl Unfortunately we have to use $1 here, since _LT_TAG is not expanded +dnl in a comment (ie after a #). +# ### BEGIN LIBTOOL TAG CONFIG: $1 +_LT_LIBTOOL_TAG_VARS(_LT_TAG) +# ### END LIBTOOL TAG CONFIG: $1 +_LT_EOF +])dnl /m4_if +], +[m4_if([$1], [], [ + PACKAGE='$PACKAGE' + VERSION='$VERSION' + TIMESTAMP='$TIMESTAMP' + RM='$RM' + ofile='$ofile'], []) +])dnl /_LT_CONFIG_SAVE_COMMANDS +])# _LT_CONFIG + + +# LT_SUPPORTED_TAG(TAG) +# --------------------- +# Trace this macro to discover what tags are supported by the libtool +# --tag option, using: +# autoconf --trace 'LT_SUPPORTED_TAG:$1' +AC_DEFUN([LT_SUPPORTED_TAG], []) + + +# C support is built-in for now +m4_define([_LT_LANG_C_enabled], []) +m4_define([_LT_TAGS], []) + + +# LT_LANG(LANG) +# ------------- +# Enable libtool support for the given language if not already enabled. +AC_DEFUN([LT_LANG], +[AC_BEFORE([$0], [LT_OUTPUT])dnl +m4_case([$1], + [C], [_LT_LANG(C)], + [C++], [_LT_LANG(CXX)], + [Go], [_LT_LANG(GO)], + [Java], [_LT_LANG(GCJ)], + [Fortran 77], [_LT_LANG(F77)], + [Fortran], [_LT_LANG(FC)], + [Windows Resource], [_LT_LANG(RC)], + [m4_ifdef([_LT_LANG_]$1[_CONFIG], + [_LT_LANG($1)], + [m4_fatal([$0: unsupported language: "$1"])])])dnl +])# LT_LANG + + +# _LT_LANG(LANGNAME) +# ------------------ +m4_defun([_LT_LANG], +[m4_ifdef([_LT_LANG_]$1[_enabled], [], + [LT_SUPPORTED_TAG([$1])dnl + m4_append([_LT_TAGS], [$1 ])dnl + m4_define([_LT_LANG_]$1[_enabled], [])dnl + _LT_LANG_$1_CONFIG($1)])dnl +])# _LT_LANG + + +m4_ifndef([AC_PROG_GO], [ +# NOTE: This macro has been submitted for inclusion into # +# GNU Autoconf as AC_PROG_GO. When it is available in # +# a released version of Autoconf we should remove this # +# macro and use it instead. # +m4_defun([AC_PROG_GO], +[AC_LANG_PUSH(Go)dnl +AC_ARG_VAR([GOC], [Go compiler command])dnl +AC_ARG_VAR([GOFLAGS], [Go compiler flags])dnl +_AC_ARG_VAR_LDFLAGS()dnl +AC_CHECK_TOOL(GOC, gccgo) +if test -z "$GOC"; then + if test -n "$ac_tool_prefix"; then + AC_CHECK_PROG(GOC, [${ac_tool_prefix}gccgo], [${ac_tool_prefix}gccgo]) + fi +fi +if test -z "$GOC"; then + AC_CHECK_PROG(GOC, gccgo, gccgo, false) +fi +])#m4_defun +])#m4_ifndef + + +# _LT_LANG_DEFAULT_CONFIG +# ----------------------- +m4_defun([_LT_LANG_DEFAULT_CONFIG], +[AC_PROVIDE_IFELSE([AC_PROG_CXX], + [LT_LANG(CXX)], + [m4_define([AC_PROG_CXX], defn([AC_PROG_CXX])[LT_LANG(CXX)])]) + +AC_PROVIDE_IFELSE([AC_PROG_F77], + [LT_LANG(F77)], + [m4_define([AC_PROG_F77], defn([AC_PROG_F77])[LT_LANG(F77)])]) + +AC_PROVIDE_IFELSE([AC_PROG_FC], + [LT_LANG(FC)], + [m4_define([AC_PROG_FC], defn([AC_PROG_FC])[LT_LANG(FC)])]) + +dnl The call to [A][M_PROG_GCJ] is quoted like that to stop aclocal +dnl pulling things in needlessly. +AC_PROVIDE_IFELSE([AC_PROG_GCJ], + [LT_LANG(GCJ)], + [AC_PROVIDE_IFELSE([A][M_PROG_GCJ], + [LT_LANG(GCJ)], + [AC_PROVIDE_IFELSE([LT_PROG_GCJ], + [LT_LANG(GCJ)], + [m4_ifdef([AC_PROG_GCJ], + [m4_define([AC_PROG_GCJ], defn([AC_PROG_GCJ])[LT_LANG(GCJ)])]) + m4_ifdef([A][M_PROG_GCJ], + [m4_define([A][M_PROG_GCJ], defn([A][M_PROG_GCJ])[LT_LANG(GCJ)])]) + m4_ifdef([LT_PROG_GCJ], + [m4_define([LT_PROG_GCJ], defn([LT_PROG_GCJ])[LT_LANG(GCJ)])])])])]) + +AC_PROVIDE_IFELSE([AC_PROG_GO], + [LT_LANG(GO)], + [m4_define([AC_PROG_GO], defn([AC_PROG_GO])[LT_LANG(GO)])]) + +AC_PROVIDE_IFELSE([LT_PROG_RC], + [LT_LANG(RC)], + [m4_define([LT_PROG_RC], defn([LT_PROG_RC])[LT_LANG(RC)])]) +])# _LT_LANG_DEFAULT_CONFIG + +# Obsolete macros: +AU_DEFUN([AC_LIBTOOL_CXX], [LT_LANG(C++)]) +AU_DEFUN([AC_LIBTOOL_F77], [LT_LANG(Fortran 77)]) +AU_DEFUN([AC_LIBTOOL_FC], [LT_LANG(Fortran)]) +AU_DEFUN([AC_LIBTOOL_GCJ], [LT_LANG(Java)]) +AU_DEFUN([AC_LIBTOOL_RC], [LT_LANG(Windows Resource)]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LIBTOOL_CXX], []) +dnl AC_DEFUN([AC_LIBTOOL_F77], []) +dnl AC_DEFUN([AC_LIBTOOL_FC], []) +dnl AC_DEFUN([AC_LIBTOOL_GCJ], []) +dnl AC_DEFUN([AC_LIBTOOL_RC], []) + + +# _LT_TAG_COMPILER +# ---------------- +m4_defun([_LT_TAG_COMPILER], +[AC_REQUIRE([AC_PROG_CC])dnl + +_LT_DECL([LTCC], [CC], [1], [A C compiler])dnl +_LT_DECL([LTCFLAGS], [CFLAGS], [1], [LTCC compiler flags])dnl +_LT_TAGDECL([CC], [compiler], [1], [A language specific compiler])dnl +_LT_TAGDECL([with_gcc], [GCC], [0], [Is the compiler the GNU compiler?])dnl + +# If no C compiler was specified, use CC. +LTCC=${LTCC-"$CC"} + +# If no C compiler flags were specified, use CFLAGS. +LTCFLAGS=${LTCFLAGS-"$CFLAGS"} + +# Allow CC to be a program name with arguments. +compiler=$CC +])# _LT_TAG_COMPILER + + +# _LT_COMPILER_BOILERPLATE +# ------------------------ +# Check for compiler boilerplate output or warnings with +# the simple compiler test code. +m4_defun([_LT_COMPILER_BOILERPLATE], +[m4_require([_LT_DECL_SED])dnl +ac_outfile=conftest.$ac_objext +echo "$lt_simple_compile_test_code" >conftest.$ac_ext +eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_compiler_boilerplate=`cat conftest.err` +$RM conftest* +])# _LT_COMPILER_BOILERPLATE + + +# _LT_LINKER_BOILERPLATE +# ---------------------- +# Check for linker boilerplate output or warnings with +# the simple link test code. +m4_defun([_LT_LINKER_BOILERPLATE], +[m4_require([_LT_DECL_SED])dnl +ac_outfile=conftest.$ac_objext +echo "$lt_simple_link_test_code" >conftest.$ac_ext +eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_linker_boilerplate=`cat conftest.err` +$RM -r conftest* +])# _LT_LINKER_BOILERPLATE + +# _LT_REQUIRED_DARWIN_CHECKS +# ------------------------- +m4_defun_once([_LT_REQUIRED_DARWIN_CHECKS],[ + case $host_os in + rhapsody* | darwin*) + AC_CHECK_TOOL([DSYMUTIL], [dsymutil], [:]) + AC_CHECK_TOOL([NMEDIT], [nmedit], [:]) + AC_CHECK_TOOL([LIPO], [lipo], [:]) + AC_CHECK_TOOL([OTOOL], [otool], [:]) + AC_CHECK_TOOL([OTOOL64], [otool64], [:]) + _LT_DECL([], [DSYMUTIL], [1], + [Tool to manipulate archived DWARF debug symbol files on Mac OS X]) + _LT_DECL([], [NMEDIT], [1], + [Tool to change global to local symbols on Mac OS X]) + _LT_DECL([], [LIPO], [1], + [Tool to manipulate fat objects and archives on Mac OS X]) + _LT_DECL([], [OTOOL], [1], + [ldd/readelf like tool for Mach-O binaries on Mac OS X]) + _LT_DECL([], [OTOOL64], [1], + [ldd/readelf like tool for 64 bit Mach-O binaries on Mac OS X 10.4]) + + AC_CACHE_CHECK([for -single_module linker flag],[lt_cv_apple_cc_single_mod], + [lt_cv_apple_cc_single_mod=no + if test -z "${LT_MULTI_MODULE}"; then + # By default we will add the -single_module flag. You can override + # by either setting the environment variable LT_MULTI_MODULE + # non-empty at configure time, or by adding -multi_module to the + # link flags. + rm -rf libconftest.dylib* + echo "int foo(void){return 1;}" > conftest.c + echo "$LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ +-dynamiclib -Wl,-single_module conftest.c" >&AS_MESSAGE_LOG_FD + $LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ + -dynamiclib -Wl,-single_module conftest.c 2>conftest.err + _lt_result=$? + # If there is a non-empty error log, and "single_module" + # appears in it, assume the flag caused a linker warning + if test -s conftest.err && $GREP single_module conftest.err; then + cat conftest.err >&AS_MESSAGE_LOG_FD + # Otherwise, if the output was created with a 0 exit code from + # the compiler, it worked. + elif test -f libconftest.dylib && test $_lt_result -eq 0; then + lt_cv_apple_cc_single_mod=yes + else + cat conftest.err >&AS_MESSAGE_LOG_FD + fi + rm -rf libconftest.dylib* + rm -f conftest.* + fi]) + + AC_CACHE_CHECK([for -exported_symbols_list linker flag], + [lt_cv_ld_exported_symbols_list], + [lt_cv_ld_exported_symbols_list=no + save_LDFLAGS=$LDFLAGS + echo "_main" > conftest.sym + LDFLAGS="$LDFLAGS -Wl,-exported_symbols_list,conftest.sym" + AC_LINK_IFELSE([AC_LANG_PROGRAM([],[])], + [lt_cv_ld_exported_symbols_list=yes], + [lt_cv_ld_exported_symbols_list=no]) + LDFLAGS="$save_LDFLAGS" + ]) + + AC_CACHE_CHECK([for -force_load linker flag],[lt_cv_ld_force_load], + [lt_cv_ld_force_load=no + cat > conftest.c << _LT_EOF +int forced_loaded() { return 2;} +_LT_EOF + echo "$LTCC $LTCFLAGS -c -o conftest.o conftest.c" >&AS_MESSAGE_LOG_FD + $LTCC $LTCFLAGS -c -o conftest.o conftest.c 2>&AS_MESSAGE_LOG_FD + echo "$AR cru libconftest.a conftest.o" >&AS_MESSAGE_LOG_FD + $AR cru libconftest.a conftest.o 2>&AS_MESSAGE_LOG_FD + echo "$RANLIB libconftest.a" >&AS_MESSAGE_LOG_FD + $RANLIB libconftest.a 2>&AS_MESSAGE_LOG_FD + cat > conftest.c << _LT_EOF +int main() { return 0;} +_LT_EOF + echo "$LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a" >&AS_MESSAGE_LOG_FD + $LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a 2>conftest.err + _lt_result=$? + if test -s conftest.err && $GREP force_load conftest.err; then + cat conftest.err >&AS_MESSAGE_LOG_FD + elif test -f conftest && test $_lt_result -eq 0 && $GREP forced_load conftest >/dev/null 2>&1 ; then + lt_cv_ld_force_load=yes + else + cat conftest.err >&AS_MESSAGE_LOG_FD + fi + rm -f conftest.err libconftest.a conftest conftest.c + rm -rf conftest.dSYM + ]) + case $host_os in + rhapsody* | darwin1.[[012]]) + _lt_dar_allow_undefined='${wl}-undefined ${wl}suppress' ;; + darwin1.*) + _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;; + darwin*) # darwin 5.x on + # if running on 10.5 or later, the deployment target defaults + # to the OS version, if on x86, and 10.4, the deployment + # target defaults to 10.4. Don't you love it? + case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in + 10.0,*86*-darwin8*|10.0,*-darwin[[91]]*) + _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;; + 10.[[012]]*) + _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;; + 10.*) + _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;; + esac + ;; + esac + if test "$lt_cv_apple_cc_single_mod" = "yes"; then + _lt_dar_single_mod='$single_module' + fi + if test "$lt_cv_ld_exported_symbols_list" = "yes"; then + _lt_dar_export_syms=' ${wl}-exported_symbols_list,$output_objdir/${libname}-symbols.expsym' + else + _lt_dar_export_syms='~$NMEDIT -s $output_objdir/${libname}-symbols.expsym ${lib}' + fi + if test "$DSYMUTIL" != ":" && test "$lt_cv_ld_force_load" = "no"; then + _lt_dsymutil='~$DSYMUTIL $lib || :' + else + _lt_dsymutil= + fi + ;; + esac +]) + + +# _LT_DARWIN_LINKER_FEATURES([TAG]) +# --------------------------------- +# Checks for linker and compiler features on darwin +m4_defun([_LT_DARWIN_LINKER_FEATURES], +[ + m4_require([_LT_REQUIRED_DARWIN_CHECKS]) + _LT_TAGVAR(archive_cmds_need_lc, $1)=no + _LT_TAGVAR(hardcode_direct, $1)=no + _LT_TAGVAR(hardcode_automatic, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported + if test "$lt_cv_ld_force_load" = "yes"; then + _LT_TAGVAR(whole_archive_flag_spec, $1)='`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience ${wl}-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`' + m4_case([$1], [F77], [_LT_TAGVAR(compiler_needs_object, $1)=yes], + [FC], [_LT_TAGVAR(compiler_needs_object, $1)=yes]) + else + _LT_TAGVAR(whole_archive_flag_spec, $1)='' + fi + _LT_TAGVAR(link_all_deplibs, $1)=yes + _LT_TAGVAR(allow_undefined_flag, $1)="$_lt_dar_allow_undefined" + case $cc_basename in + ifort*) _lt_dar_can_shared=yes ;; + *) _lt_dar_can_shared=$GCC ;; + esac + if test "$_lt_dar_can_shared" = "yes"; then + output_verbose_link_cmd=func_echo_all + _LT_TAGVAR(archive_cmds, $1)="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}" + _LT_TAGVAR(module_cmds, $1)="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" + _LT_TAGVAR(archive_expsym_cmds, $1)="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}" + _LT_TAGVAR(module_expsym_cmds, $1)="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" + m4_if([$1], [CXX], +[ if test "$lt_cv_apple_cc_single_mod" != "yes"; then + _LT_TAGVAR(archive_cmds, $1)="\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dsymutil}" + _LT_TAGVAR(archive_expsym_cmds, $1)="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dar_export_syms}${_lt_dsymutil}" + fi +],[]) + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi +]) + +# _LT_SYS_MODULE_PATH_AIX([TAGNAME]) +# ---------------------------------- +# Links a minimal program and checks the executable +# for the system default hardcoded library path. In most cases, +# this is /usr/lib:/lib, but when the MPI compilers are used +# the location of the communication and MPI libs are included too. +# If we don't find anything, use the default library path according +# to the aix ld manual. +# Store the results from the different compilers for each TAGNAME. +# Allow to override them for all tags through lt_cv_aix_libpath. +m4_defun([_LT_SYS_MODULE_PATH_AIX], +[m4_require([_LT_DECL_SED])dnl +if test "${lt_cv_aix_libpath+set}" = set; then + aix_libpath=$lt_cv_aix_libpath +else + AC_CACHE_VAL([_LT_TAGVAR([lt_cv_aix_libpath_], [$1])], + [AC_LINK_IFELSE([AC_LANG_PROGRAM],[ + lt_aix_libpath_sed='[ + /Import File Strings/,/^$/ { + /^0/ { + s/^0 *\([^ ]*\) *$/\1/ + p + } + }]' + _LT_TAGVAR([lt_cv_aix_libpath_], [$1])=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` + # Check for a 64-bit object if we didn't find anything. + if test -z "$_LT_TAGVAR([lt_cv_aix_libpath_], [$1])"; then + _LT_TAGVAR([lt_cv_aix_libpath_], [$1])=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` + fi],[]) + if test -z "$_LT_TAGVAR([lt_cv_aix_libpath_], [$1])"; then + _LT_TAGVAR([lt_cv_aix_libpath_], [$1])="/usr/lib:/lib" + fi + ]) + aix_libpath=$_LT_TAGVAR([lt_cv_aix_libpath_], [$1]) +fi +])# _LT_SYS_MODULE_PATH_AIX + + +# _LT_SHELL_INIT(ARG) +# ------------------- +m4_define([_LT_SHELL_INIT], +[m4_divert_text([M4SH-INIT], [$1 +])])# _LT_SHELL_INIT + + + +# _LT_PROG_ECHO_BACKSLASH +# ----------------------- +# Find how we can fake an echo command that does not interpret backslash. +# In particular, with Autoconf 2.60 or later we add some code to the start +# of the generated configure script which will find a shell with a builtin +# printf (which we can use as an echo command). +m4_defun([_LT_PROG_ECHO_BACKSLASH], +[ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' +ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO +ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO + +AC_MSG_CHECKING([how to print strings]) +# Test print first, because it will be a builtin if present. +if test "X`( print -r -- -n ) 2>/dev/null`" = X-n && \ + test "X`print -r -- $ECHO 2>/dev/null`" = "X$ECHO"; then + ECHO='print -r --' +elif test "X`printf %s $ECHO 2>/dev/null`" = "X$ECHO"; then + ECHO='printf %s\n' +else + # Use this function as a fallback that always works. + func_fallback_echo () + { + eval 'cat <<_LTECHO_EOF +$[]1 +_LTECHO_EOF' + } + ECHO='func_fallback_echo' +fi + +# func_echo_all arg... +# Invoke $ECHO with all args, space-separated. +func_echo_all () +{ + $ECHO "$*" +} + +case "$ECHO" in + printf*) AC_MSG_RESULT([printf]) ;; + print*) AC_MSG_RESULT([print -r]) ;; + *) AC_MSG_RESULT([cat]) ;; +esac + +m4_ifdef([_AS_DETECT_SUGGESTED], +[_AS_DETECT_SUGGESTED([ + test -n "${ZSH_VERSION+set}${BASH_VERSION+set}" || ( + ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' + ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO + ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO + PATH=/empty FPATH=/empty; export PATH FPATH + test "X`printf %s $ECHO`" = "X$ECHO" \ + || test "X`print -r -- $ECHO`" = "X$ECHO" )])]) + +_LT_DECL([], [SHELL], [1], [Shell to use when invoking shell scripts]) +_LT_DECL([], [ECHO], [1], [An echo program that protects backslashes]) +])# _LT_PROG_ECHO_BACKSLASH + + +# _LT_WITH_SYSROOT +# ---------------- +AC_DEFUN([_LT_WITH_SYSROOT], +[AC_MSG_CHECKING([for sysroot]) +AC_ARG_WITH([sysroot], +[ --with-sysroot[=DIR] Search for dependent libraries within DIR + (or the compiler's sysroot if not specified).], +[], [with_sysroot=no]) + +dnl lt_sysroot will always be passed unquoted. We quote it here +dnl in case the user passed a directory name. +lt_sysroot= +case ${with_sysroot} in #( + yes) + if test "$GCC" = yes; then + lt_sysroot=`$CC --print-sysroot 2>/dev/null` + fi + ;; #( + /*) + lt_sysroot=`echo "$with_sysroot" | sed -e "$sed_quote_subst"` + ;; #( + no|'') + ;; #( + *) + AC_MSG_RESULT([${with_sysroot}]) + AC_MSG_ERROR([The sysroot must be an absolute path.]) + ;; +esac + + AC_MSG_RESULT([${lt_sysroot:-no}]) +_LT_DECL([], [lt_sysroot], [0], [The root where to search for ]dnl +[dependent libraries, and in which our libraries should be installed.])]) + +# _LT_ENABLE_LOCK +# --------------- +m4_defun([_LT_ENABLE_LOCK], +[AC_ARG_ENABLE([libtool-lock], + [AS_HELP_STRING([--disable-libtool-lock], + [avoid locking (might break parallel builds)])]) +test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes + +# Some flags need to be propagated to the compiler or linker for good +# libtool support. +case $host in +ia64-*-hpux*) + # Find out which ABI we are using. + echo 'int i;' > conftest.$ac_ext + if AC_TRY_EVAL(ac_compile); then + case `/usr/bin/file conftest.$ac_objext` in + *ELF-32*) + HPUX_IA64_MODE="32" + ;; + *ELF-64*) + HPUX_IA64_MODE="64" + ;; + esac + fi + rm -rf conftest* + ;; +*-*-irix6*) + # Find out which ABI we are using. + echo '[#]line '$LINENO' "configure"' > conftest.$ac_ext + if AC_TRY_EVAL(ac_compile); then + if test "$lt_cv_prog_gnu_ld" = yes; then + case `/usr/bin/file conftest.$ac_objext` in + *32-bit*) + LD="${LD-ld} -melf32bsmip" + ;; + *N32*) + LD="${LD-ld} -melf32bmipn32" + ;; + *64-bit*) + LD="${LD-ld} -melf64bmip" + ;; + esac + else + case `/usr/bin/file conftest.$ac_objext` in + *32-bit*) + LD="${LD-ld} -32" + ;; + *N32*) + LD="${LD-ld} -n32" + ;; + *64-bit*) + LD="${LD-ld} -64" + ;; + esac + fi + fi + rm -rf conftest* + ;; + +x86_64-*kfreebsd*-gnu|x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*| \ +s390*-*linux*|s390*-*tpf*|sparc*-*linux*) + # Find out which ABI we are using. + echo 'int i;' > conftest.$ac_ext + if AC_TRY_EVAL(ac_compile); then + case `/usr/bin/file conftest.o` in + *32-bit*) + case $host in + x86_64-*kfreebsd*-gnu) + LD="${LD-ld} -m elf_i386_fbsd" + ;; + x86_64-*linux*) + LD="${LD-ld} -m elf_i386" + ;; + ppc64-*linux*|powerpc64-*linux*) + LD="${LD-ld} -m elf32ppclinux" + ;; + s390x-*linux*) + LD="${LD-ld} -m elf_s390" + ;; + sparc64-*linux*) + LD="${LD-ld} -m elf32_sparc" + ;; + esac + ;; + *64-bit*) + case $host in + x86_64-*kfreebsd*-gnu) + LD="${LD-ld} -m elf_x86_64_fbsd" + ;; + x86_64-*linux*) + LD="${LD-ld} -m elf_x86_64" + ;; + ppc*-*linux*|powerpc*-*linux*) + LD="${LD-ld} -m elf64ppc" + ;; + s390*-*linux*|s390*-*tpf*) + LD="${LD-ld} -m elf64_s390" + ;; + sparc*-*linux*) + LD="${LD-ld} -m elf64_sparc" + ;; + esac + ;; + esac + fi + rm -rf conftest* + ;; + +*-*-sco3.2v5*) + # On SCO OpenServer 5, we need -belf to get full-featured binaries. + SAVE_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS -belf" + AC_CACHE_CHECK([whether the C compiler needs -belf], lt_cv_cc_needs_belf, + [AC_LANG_PUSH(C) + AC_LINK_IFELSE([AC_LANG_PROGRAM([[]],[[]])],[lt_cv_cc_needs_belf=yes],[lt_cv_cc_needs_belf=no]) + AC_LANG_POP]) + if test x"$lt_cv_cc_needs_belf" != x"yes"; then + # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf + CFLAGS="$SAVE_CFLAGS" + fi + ;; +*-*solaris*) + # Find out which ABI we are using. + echo 'int i;' > conftest.$ac_ext + if AC_TRY_EVAL(ac_compile); then + case `/usr/bin/file conftest.o` in + *64-bit*) + case $lt_cv_prog_gnu_ld in + yes*) + case $host in + i?86-*-solaris*) + LD="${LD-ld} -m elf_x86_64" + ;; + sparc*-*-solaris*) + LD="${LD-ld} -m elf64_sparc" + ;; + esac + # GNU ld 2.21 introduced _sol2 emulations. Use them if available. + if ${LD-ld} -V | grep _sol2 >/dev/null 2>&1; then + LD="${LD-ld}_sol2" + fi + ;; + *) + if ${LD-ld} -64 -r -o conftest2.o conftest.o >/dev/null 2>&1; then + LD="${LD-ld} -64" + fi + ;; + esac + ;; + esac + fi + rm -rf conftest* + ;; +esac + +need_locks="$enable_libtool_lock" +])# _LT_ENABLE_LOCK + + +# _LT_PROG_AR +# ----------- +m4_defun([_LT_PROG_AR], +[AC_CHECK_TOOLS(AR, [ar], false) +: ${AR=ar} +: ${AR_FLAGS=cru} +_LT_DECL([], [AR], [1], [The archiver]) +_LT_DECL([], [AR_FLAGS], [1], [Flags to create an archive]) + +AC_CACHE_CHECK([for archiver @FILE support], [lt_cv_ar_at_file], + [lt_cv_ar_at_file=no + AC_COMPILE_IFELSE([AC_LANG_PROGRAM], + [echo conftest.$ac_objext > conftest.lst + lt_ar_try='$AR $AR_FLAGS libconftest.a @conftest.lst >&AS_MESSAGE_LOG_FD' + AC_TRY_EVAL([lt_ar_try]) + if test "$ac_status" -eq 0; then + # Ensure the archiver fails upon bogus file names. + rm -f conftest.$ac_objext libconftest.a + AC_TRY_EVAL([lt_ar_try]) + if test "$ac_status" -ne 0; then + lt_cv_ar_at_file=@ + fi + fi + rm -f conftest.* libconftest.a + ]) + ]) + +if test "x$lt_cv_ar_at_file" = xno; then + archiver_list_spec= +else + archiver_list_spec=$lt_cv_ar_at_file +fi +_LT_DECL([], [archiver_list_spec], [1], + [How to feed a file listing to the archiver]) +])# _LT_PROG_AR + + +# _LT_CMD_OLD_ARCHIVE +# ------------------- +m4_defun([_LT_CMD_OLD_ARCHIVE], +[_LT_PROG_AR + +AC_CHECK_TOOL(STRIP, strip, :) +test -z "$STRIP" && STRIP=: +_LT_DECL([], [STRIP], [1], [A symbol stripping program]) + +AC_CHECK_TOOL(RANLIB, ranlib, :) +test -z "$RANLIB" && RANLIB=: +_LT_DECL([], [RANLIB], [1], + [Commands used to install an old-style archive]) + +# Determine commands to create old-style static archives. +old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs' +old_postinstall_cmds='chmod 644 $oldlib' +old_postuninstall_cmds= + +if test -n "$RANLIB"; then + case $host_os in + openbsd*) + old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$tool_oldlib" + ;; + *) + old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$tool_oldlib" + ;; + esac + old_archive_cmds="$old_archive_cmds~\$RANLIB \$tool_oldlib" +fi + +case $host_os in + darwin*) + lock_old_archive_extraction=yes ;; + *) + lock_old_archive_extraction=no ;; +esac +_LT_DECL([], [old_postinstall_cmds], [2]) +_LT_DECL([], [old_postuninstall_cmds], [2]) +_LT_TAGDECL([], [old_archive_cmds], [2], + [Commands used to build an old-style archive]) +_LT_DECL([], [lock_old_archive_extraction], [0], + [Whether to use a lock for old archive extraction]) +])# _LT_CMD_OLD_ARCHIVE + + +# _LT_COMPILER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS, +# [OUTPUT-FILE], [ACTION-SUCCESS], [ACTION-FAILURE]) +# ---------------------------------------------------------------- +# Check whether the given compiler option works +AC_DEFUN([_LT_COMPILER_OPTION], +[m4_require([_LT_FILEUTILS_DEFAULTS])dnl +m4_require([_LT_DECL_SED])dnl +AC_CACHE_CHECK([$1], [$2], + [$2=no + m4_if([$4], , [ac_outfile=conftest.$ac_objext], [ac_outfile=$4]) + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + lt_compiler_flag="$3" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + # The option is referenced via a variable to avoid confusing sed. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&AS_MESSAGE_LOG_FD) + (eval "$lt_compile" 2>conftest.err) + ac_status=$? + cat conftest.err >&AS_MESSAGE_LOG_FD + echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD + if (exit $ac_status) && test -s "$ac_outfile"; then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings other than the usual output. + $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then + $2=yes + fi + fi + $RM conftest* +]) + +if test x"[$]$2" = xyes; then + m4_if([$5], , :, [$5]) +else + m4_if([$6], , :, [$6]) +fi +])# _LT_COMPILER_OPTION + +# Old name: +AU_ALIAS([AC_LIBTOOL_COMPILER_OPTION], [_LT_COMPILER_OPTION]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LIBTOOL_COMPILER_OPTION], []) + + +# _LT_LINKER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS, +# [ACTION-SUCCESS], [ACTION-FAILURE]) +# ---------------------------------------------------- +# Check whether the given linker option works +AC_DEFUN([_LT_LINKER_OPTION], +[m4_require([_LT_FILEUTILS_DEFAULTS])dnl +m4_require([_LT_DECL_SED])dnl +AC_CACHE_CHECK([$1], [$2], + [$2=no + save_LDFLAGS="$LDFLAGS" + LDFLAGS="$LDFLAGS $3" + echo "$lt_simple_link_test_code" > conftest.$ac_ext + if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then + # The linker can only warn and ignore the option if not recognized + # So say no if there are warnings + if test -s conftest.err; then + # Append any errors to the config.log. + cat conftest.err 1>&AS_MESSAGE_LOG_FD + $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if diff conftest.exp conftest.er2 >/dev/null; then + $2=yes + fi + else + $2=yes + fi + fi + $RM -r conftest* + LDFLAGS="$save_LDFLAGS" +]) + +if test x"[$]$2" = xyes; then + m4_if([$4], , :, [$4]) +else + m4_if([$5], , :, [$5]) +fi +])# _LT_LINKER_OPTION + +# Old name: +AU_ALIAS([AC_LIBTOOL_LINKER_OPTION], [_LT_LINKER_OPTION]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LIBTOOL_LINKER_OPTION], []) + + +# LT_CMD_MAX_LEN +#--------------- +AC_DEFUN([LT_CMD_MAX_LEN], +[AC_REQUIRE([AC_CANONICAL_HOST])dnl +# find the maximum length of command line arguments +AC_MSG_CHECKING([the maximum length of command line arguments]) +AC_CACHE_VAL([lt_cv_sys_max_cmd_len], [dnl + i=0 + teststring="ABCD" + + case $build_os in + msdosdjgpp*) + # On DJGPP, this test can blow up pretty badly due to problems in libc + # (any single argument exceeding 2000 bytes causes a buffer overrun + # during glob expansion). Even if it were fixed, the result of this + # check would be larger than it should be. + lt_cv_sys_max_cmd_len=12288; # 12K is about right + ;; + + gnu*) + # Under GNU Hurd, this test is not required because there is + # no limit to the length of command line arguments. + # Libtool will interpret -1 as no limit whatsoever + lt_cv_sys_max_cmd_len=-1; + ;; + + cygwin* | mingw* | cegcc*) + # On Win9x/ME, this test blows up -- it succeeds, but takes + # about 5 minutes as the teststring grows exponentially. + # Worse, since 9x/ME are not pre-emptively multitasking, + # you end up with a "frozen" computer, even though with patience + # the test eventually succeeds (with a max line length of 256k). + # Instead, let's just punt: use the minimum linelength reported by + # all of the supported platforms: 8192 (on NT/2K/XP). + lt_cv_sys_max_cmd_len=8192; + ;; + + mint*) + # On MiNT this can take a long time and run out of memory. + lt_cv_sys_max_cmd_len=8192; + ;; + + amigaos*) + # On AmigaOS with pdksh, this test takes hours, literally. + # So we just punt and use a minimum line length of 8192. + lt_cv_sys_max_cmd_len=8192; + ;; + + netbsd* | freebsd* | openbsd* | darwin* | dragonfly*) + # This has been around since 386BSD, at least. Likely further. + if test -x /sbin/sysctl; then + lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax` + elif test -x /usr/sbin/sysctl; then + lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax` + else + lt_cv_sys_max_cmd_len=65536 # usable default for all BSDs + fi + # And add a safety zone + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` + ;; + + interix*) + # We know the value 262144 and hardcode it with a safety zone (like BSD) + lt_cv_sys_max_cmd_len=196608 + ;; + + os2*) + # The test takes a long time on OS/2. + lt_cv_sys_max_cmd_len=8192 + ;; + + osf*) + # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure + # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not + # nice to cause kernel panics so lets avoid the loop below. + # First set a reasonable default. + lt_cv_sys_max_cmd_len=16384 + # + if test -x /sbin/sysconfig; then + case `/sbin/sysconfig -q proc exec_disable_arg_limit` in + *1*) lt_cv_sys_max_cmd_len=-1 ;; + esac + fi + ;; + sco3.2v5*) + lt_cv_sys_max_cmd_len=102400 + ;; + sysv5* | sco5v6* | sysv4.2uw2*) + kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null` + if test -n "$kargmax"; then + lt_cv_sys_max_cmd_len=`echo $kargmax | sed 's/.*[[ ]]//'` + else + lt_cv_sys_max_cmd_len=32768 + fi + ;; + *) + lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null` + if test -n "$lt_cv_sys_max_cmd_len"; then + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` + else + # Make teststring a little bigger before we do anything with it. + # a 1K string should be a reasonable start. + for i in 1 2 3 4 5 6 7 8 ; do + teststring=$teststring$teststring + done + SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}} + # If test is not a shell built-in, we'll probably end up computing a + # maximum length that is only half of the actual maximum length, but + # we can't tell. + while { test "X"`env echo "$teststring$teststring" 2>/dev/null` \ + = "X$teststring$teststring"; } >/dev/null 2>&1 && + test $i != 17 # 1/2 MB should be enough + do + i=`expr $i + 1` + teststring=$teststring$teststring + done + # Only check the string length outside the loop. + lt_cv_sys_max_cmd_len=`expr "X$teststring" : ".*" 2>&1` + teststring= + # Add a significant safety factor because C++ compilers can tack on + # massive amounts of additional arguments before passing them to the + # linker. It appears as though 1/2 is a usable value. + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2` + fi + ;; + esac +]) +if test -n $lt_cv_sys_max_cmd_len ; then + AC_MSG_RESULT($lt_cv_sys_max_cmd_len) +else + AC_MSG_RESULT(none) +fi +max_cmd_len=$lt_cv_sys_max_cmd_len +_LT_DECL([], [max_cmd_len], [0], + [What is the maximum length of a command?]) +])# LT_CMD_MAX_LEN + +# Old name: +AU_ALIAS([AC_LIBTOOL_SYS_MAX_CMD_LEN], [LT_CMD_MAX_LEN]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LIBTOOL_SYS_MAX_CMD_LEN], []) + + +# _LT_HEADER_DLFCN +# ---------------- +m4_defun([_LT_HEADER_DLFCN], +[AC_CHECK_HEADERS([dlfcn.h], [], [], [AC_INCLUDES_DEFAULT])dnl +])# _LT_HEADER_DLFCN + + +# _LT_TRY_DLOPEN_SELF (ACTION-IF-TRUE, ACTION-IF-TRUE-W-USCORE, +# ACTION-IF-FALSE, ACTION-IF-CROSS-COMPILING) +# ---------------------------------------------------------------- +m4_defun([_LT_TRY_DLOPEN_SELF], +[m4_require([_LT_HEADER_DLFCN])dnl +if test "$cross_compiling" = yes; then : + [$4] +else + lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 + lt_status=$lt_dlunknown + cat > conftest.$ac_ext <<_LT_EOF +[#line $LINENO "configure" +#include "confdefs.h" + +#if HAVE_DLFCN_H +#include +#endif + +#include + +#ifdef RTLD_GLOBAL +# define LT_DLGLOBAL RTLD_GLOBAL +#else +# ifdef DL_GLOBAL +# define LT_DLGLOBAL DL_GLOBAL +# else +# define LT_DLGLOBAL 0 +# endif +#endif + +/* We may have to define LT_DLLAZY_OR_NOW in the command line if we + find out it does not work in some platform. */ +#ifndef LT_DLLAZY_OR_NOW +# ifdef RTLD_LAZY +# define LT_DLLAZY_OR_NOW RTLD_LAZY +# else +# ifdef DL_LAZY +# define LT_DLLAZY_OR_NOW DL_LAZY +# else +# ifdef RTLD_NOW +# define LT_DLLAZY_OR_NOW RTLD_NOW +# else +# ifdef DL_NOW +# define LT_DLLAZY_OR_NOW DL_NOW +# else +# define LT_DLLAZY_OR_NOW 0 +# endif +# endif +# endif +# endif +#endif + +/* When -fvisbility=hidden is used, assume the code has been annotated + correspondingly for the symbols needed. */ +#if defined(__GNUC__) && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)) +int fnord () __attribute__((visibility("default"))); +#endif + +int fnord () { return 42; } +int main () +{ + void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); + int status = $lt_dlunknown; + + if (self) + { + if (dlsym (self,"fnord")) status = $lt_dlno_uscore; + else + { + if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; + else puts (dlerror ()); + } + /* dlclose (self); */ + } + else + puts (dlerror ()); + + return status; +}] +_LT_EOF + if AC_TRY_EVAL(ac_link) && test -s conftest${ac_exeext} 2>/dev/null; then + (./conftest; exit; ) >&AS_MESSAGE_LOG_FD 2>/dev/null + lt_status=$? + case x$lt_status in + x$lt_dlno_uscore) $1 ;; + x$lt_dlneed_uscore) $2 ;; + x$lt_dlunknown|x*) $3 ;; + esac + else : + # compilation failed + $3 + fi +fi +rm -fr conftest* +])# _LT_TRY_DLOPEN_SELF + + +# LT_SYS_DLOPEN_SELF +# ------------------ +AC_DEFUN([LT_SYS_DLOPEN_SELF], +[m4_require([_LT_HEADER_DLFCN])dnl +if test "x$enable_dlopen" != xyes; then + enable_dlopen=unknown + enable_dlopen_self=unknown + enable_dlopen_self_static=unknown +else + lt_cv_dlopen=no + lt_cv_dlopen_libs= + + case $host_os in + beos*) + lt_cv_dlopen="load_add_on" + lt_cv_dlopen_libs= + lt_cv_dlopen_self=yes + ;; + + mingw* | pw32* | cegcc*) + lt_cv_dlopen="LoadLibrary" + lt_cv_dlopen_libs= + ;; + + cygwin*) + lt_cv_dlopen="dlopen" + lt_cv_dlopen_libs= + ;; + + darwin*) + # if libdl is installed we need to link against it + AC_CHECK_LIB([dl], [dlopen], + [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"],[ + lt_cv_dlopen="dyld" + lt_cv_dlopen_libs= + lt_cv_dlopen_self=yes + ]) + ;; + + *) + AC_CHECK_FUNC([shl_load], + [lt_cv_dlopen="shl_load"], + [AC_CHECK_LIB([dld], [shl_load], + [lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-ldld"], + [AC_CHECK_FUNC([dlopen], + [lt_cv_dlopen="dlopen"], + [AC_CHECK_LIB([dl], [dlopen], + [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"], + [AC_CHECK_LIB([svld], [dlopen], + [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld"], + [AC_CHECK_LIB([dld], [dld_link], + [lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-ldld"]) + ]) + ]) + ]) + ]) + ]) + ;; + esac + + if test "x$lt_cv_dlopen" != xno; then + enable_dlopen=yes + else + enable_dlopen=no + fi + + case $lt_cv_dlopen in + dlopen) + save_CPPFLAGS="$CPPFLAGS" + test "x$ac_cv_header_dlfcn_h" = xyes && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H" + + save_LDFLAGS="$LDFLAGS" + wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\" + + save_LIBS="$LIBS" + LIBS="$lt_cv_dlopen_libs $LIBS" + + AC_CACHE_CHECK([whether a program can dlopen itself], + lt_cv_dlopen_self, [dnl + _LT_TRY_DLOPEN_SELF( + lt_cv_dlopen_self=yes, lt_cv_dlopen_self=yes, + lt_cv_dlopen_self=no, lt_cv_dlopen_self=cross) + ]) + + if test "x$lt_cv_dlopen_self" = xyes; then + wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\" + AC_CACHE_CHECK([whether a statically linked program can dlopen itself], + lt_cv_dlopen_self_static, [dnl + _LT_TRY_DLOPEN_SELF( + lt_cv_dlopen_self_static=yes, lt_cv_dlopen_self_static=yes, + lt_cv_dlopen_self_static=no, lt_cv_dlopen_self_static=cross) + ]) + fi + + CPPFLAGS="$save_CPPFLAGS" + LDFLAGS="$save_LDFLAGS" + LIBS="$save_LIBS" + ;; + esac + + case $lt_cv_dlopen_self in + yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;; + *) enable_dlopen_self=unknown ;; + esac + + case $lt_cv_dlopen_self_static in + yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;; + *) enable_dlopen_self_static=unknown ;; + esac +fi +_LT_DECL([dlopen_support], [enable_dlopen], [0], + [Whether dlopen is supported]) +_LT_DECL([dlopen_self], [enable_dlopen_self], [0], + [Whether dlopen of programs is supported]) +_LT_DECL([dlopen_self_static], [enable_dlopen_self_static], [0], + [Whether dlopen of statically linked programs is supported]) +])# LT_SYS_DLOPEN_SELF + +# Old name: +AU_ALIAS([AC_LIBTOOL_DLOPEN_SELF], [LT_SYS_DLOPEN_SELF]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LIBTOOL_DLOPEN_SELF], []) + + +# _LT_COMPILER_C_O([TAGNAME]) +# --------------------------- +# Check to see if options -c and -o are simultaneously supported by compiler. +# This macro does not hard code the compiler like AC_PROG_CC_C_O. +m4_defun([_LT_COMPILER_C_O], +[m4_require([_LT_DECL_SED])dnl +m4_require([_LT_FILEUTILS_DEFAULTS])dnl +m4_require([_LT_TAG_COMPILER])dnl +AC_CACHE_CHECK([if $compiler supports -c -o file.$ac_objext], + [_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)], + [_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=no + $RM -r conftest 2>/dev/null + mkdir conftest + cd conftest + mkdir out + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + lt_compiler_flag="-o out/conftest2.$ac_objext" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&AS_MESSAGE_LOG_FD) + (eval "$lt_compile" 2>out/conftest.err) + ac_status=$? + cat out/conftest.err >&AS_MESSAGE_LOG_FD + echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD + if (exit $ac_status) && test -s out/conftest2.$ac_objext + then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings + $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp + $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 + if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then + _LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes + fi + fi + chmod u+w . 2>&AS_MESSAGE_LOG_FD + $RM conftest* + # SGI C++ compiler will create directory out/ii_files/ for + # template instantiation + test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files + $RM out/* && rmdir out + cd .. + $RM -r conftest + $RM conftest* +]) +_LT_TAGDECL([compiler_c_o], [lt_cv_prog_compiler_c_o], [1], + [Does compiler simultaneously support -c and -o options?]) +])# _LT_COMPILER_C_O + + +# _LT_COMPILER_FILE_LOCKS([TAGNAME]) +# ---------------------------------- +# Check to see if we can do hard links to lock some files if needed +m4_defun([_LT_COMPILER_FILE_LOCKS], +[m4_require([_LT_ENABLE_LOCK])dnl +m4_require([_LT_FILEUTILS_DEFAULTS])dnl +_LT_COMPILER_C_O([$1]) + +hard_links="nottested" +if test "$_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)" = no && test "$need_locks" != no; then + # do not overwrite the value of need_locks provided by the user + AC_MSG_CHECKING([if we can lock with hard links]) + hard_links=yes + $RM conftest* + ln conftest.a conftest.b 2>/dev/null && hard_links=no + touch conftest.a + ln conftest.a conftest.b 2>&5 || hard_links=no + ln conftest.a conftest.b 2>/dev/null && hard_links=no + AC_MSG_RESULT([$hard_links]) + if test "$hard_links" = no; then + AC_MSG_WARN([`$CC' does not support `-c -o', so `make -j' may be unsafe]) + need_locks=warn + fi +else + need_locks=no +fi +_LT_DECL([], [need_locks], [1], [Must we lock files when doing compilation?]) +])# _LT_COMPILER_FILE_LOCKS + + +# _LT_CHECK_OBJDIR +# ---------------- +m4_defun([_LT_CHECK_OBJDIR], +[AC_CACHE_CHECK([for objdir], [lt_cv_objdir], +[rm -f .libs 2>/dev/null +mkdir .libs 2>/dev/null +if test -d .libs; then + lt_cv_objdir=.libs +else + # MS-DOS does not allow filenames that begin with a dot. + lt_cv_objdir=_libs +fi +rmdir .libs 2>/dev/null]) +objdir=$lt_cv_objdir +_LT_DECL([], [objdir], [0], + [The name of the directory that contains temporary libtool files])dnl +m4_pattern_allow([LT_OBJDIR])dnl +AC_DEFINE_UNQUOTED(LT_OBJDIR, "$lt_cv_objdir/", + [Define to the sub-directory in which libtool stores uninstalled libraries.]) +])# _LT_CHECK_OBJDIR + + +# _LT_LINKER_HARDCODE_LIBPATH([TAGNAME]) +# -------------------------------------- +# Check hardcoding attributes. +m4_defun([_LT_LINKER_HARDCODE_LIBPATH], +[AC_MSG_CHECKING([how to hardcode library paths into programs]) +_LT_TAGVAR(hardcode_action, $1)= +if test -n "$_LT_TAGVAR(hardcode_libdir_flag_spec, $1)" || + test -n "$_LT_TAGVAR(runpath_var, $1)" || + test "X$_LT_TAGVAR(hardcode_automatic, $1)" = "Xyes" ; then + + # We can hardcode non-existent directories. + if test "$_LT_TAGVAR(hardcode_direct, $1)" != no && + # If the only mechanism to avoid hardcoding is shlibpath_var, we + # have to relink, otherwise we might link with an installed library + # when we should be linking with a yet-to-be-installed one + ## test "$_LT_TAGVAR(hardcode_shlibpath_var, $1)" != no && + test "$_LT_TAGVAR(hardcode_minus_L, $1)" != no; then + # Linking always hardcodes the temporary library directory. + _LT_TAGVAR(hardcode_action, $1)=relink + else + # We can link without hardcoding, and we can hardcode nonexisting dirs. + _LT_TAGVAR(hardcode_action, $1)=immediate + fi +else + # We cannot hardcode anything, or else we can only hardcode existing + # directories. + _LT_TAGVAR(hardcode_action, $1)=unsupported +fi +AC_MSG_RESULT([$_LT_TAGVAR(hardcode_action, $1)]) + +if test "$_LT_TAGVAR(hardcode_action, $1)" = relink || + test "$_LT_TAGVAR(inherit_rpath, $1)" = yes; then + # Fast installation is not supported + enable_fast_install=no +elif test "$shlibpath_overrides_runpath" = yes || + test "$enable_shared" = no; then + # Fast installation is not necessary + enable_fast_install=needless +fi +_LT_TAGDECL([], [hardcode_action], [0], + [How to hardcode a shared library path into an executable]) +])# _LT_LINKER_HARDCODE_LIBPATH + + +# _LT_CMD_STRIPLIB +# ---------------- +m4_defun([_LT_CMD_STRIPLIB], +[m4_require([_LT_DECL_EGREP]) +striplib= +old_striplib= +AC_MSG_CHECKING([whether stripping libraries is possible]) +if test -n "$STRIP" && $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then + test -z "$old_striplib" && old_striplib="$STRIP --strip-debug" + test -z "$striplib" && striplib="$STRIP --strip-unneeded" + AC_MSG_RESULT([yes]) +else +# FIXME - insert some real tests, host_os isn't really good enough + case $host_os in + darwin*) + if test -n "$STRIP" ; then + striplib="$STRIP -x" + old_striplib="$STRIP -S" + AC_MSG_RESULT([yes]) + else + AC_MSG_RESULT([no]) + fi + ;; + *) + AC_MSG_RESULT([no]) + ;; + esac +fi +_LT_DECL([], [old_striplib], [1], [Commands to strip libraries]) +_LT_DECL([], [striplib], [1]) +])# _LT_CMD_STRIPLIB + + +# _LT_SYS_DYNAMIC_LINKER([TAG]) +# ----------------------------- +# PORTME Fill in your ld.so characteristics +m4_defun([_LT_SYS_DYNAMIC_LINKER], +[AC_REQUIRE([AC_CANONICAL_HOST])dnl +m4_require([_LT_DECL_EGREP])dnl +m4_require([_LT_FILEUTILS_DEFAULTS])dnl +m4_require([_LT_DECL_OBJDUMP])dnl +m4_require([_LT_DECL_SED])dnl +m4_require([_LT_CHECK_SHELL_FEATURES])dnl +AC_MSG_CHECKING([dynamic linker characteristics]) +m4_if([$1], + [], [ +if test "$GCC" = yes; then + case $host_os in + darwin*) lt_awk_arg="/^libraries:/,/LR/" ;; + *) lt_awk_arg="/^libraries:/" ;; + esac + case $host_os in + mingw* | cegcc*) lt_sed_strip_eq="s,=\([[A-Za-z]]:\),\1,g" ;; + *) lt_sed_strip_eq="s,=/,/,g" ;; + esac + lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e $lt_sed_strip_eq` + case $lt_search_path_spec in + *\;*) + # if the path contains ";" then we assume it to be the separator + # otherwise default to the standard path separator (i.e. ":") - it is + # assumed that no part of a normal pathname contains ";" but that should + # okay in the real world where ";" in dirpaths is itself problematic. + lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED 's/;/ /g'` + ;; + *) + lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED "s/$PATH_SEPARATOR/ /g"` + ;; + esac + # Ok, now we have the path, separated by spaces, we can step through it + # and add multilib dir if necessary. + lt_tmp_lt_search_path_spec= + lt_multi_os_dir=`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null` + for lt_sys_path in $lt_search_path_spec; do + if test -d "$lt_sys_path/$lt_multi_os_dir"; then + lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path/$lt_multi_os_dir" + else + test -d "$lt_sys_path" && \ + lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path" + fi + done + lt_search_path_spec=`$ECHO "$lt_tmp_lt_search_path_spec" | awk ' +BEGIN {RS=" "; FS="/|\n";} { + lt_foo=""; + lt_count=0; + for (lt_i = NF; lt_i > 0; lt_i--) { + if ($lt_i != "" && $lt_i != ".") { + if ($lt_i == "..") { + lt_count++; + } else { + if (lt_count == 0) { + lt_foo="/" $lt_i lt_foo; + } else { + lt_count--; + } + } + } + } + if (lt_foo != "") { lt_freq[[lt_foo]]++; } + if (lt_freq[[lt_foo]] == 1) { print lt_foo; } +}'` + # AWK program above erroneously prepends '/' to C:/dos/paths + # for these hosts. + case $host_os in + mingw* | cegcc*) lt_search_path_spec=`$ECHO "$lt_search_path_spec" |\ + $SED 's,/\([[A-Za-z]]:\),\1,g'` ;; + esac + sys_lib_search_path_spec=`$ECHO "$lt_search_path_spec" | $lt_NL2SP` +else + sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" +fi]) +library_names_spec= +libname_spec='lib$name' +soname_spec= +shrext_cmds=".so" +postinstall_cmds= +postuninstall_cmds= +finish_cmds= +finish_eval= +shlibpath_var= +shlibpath_overrides_runpath=unknown +version_type=none +dynamic_linker="$host_os ld.so" +sys_lib_dlsearch_path_spec="/lib /usr/lib" +need_lib_prefix=unknown +hardcode_into_libs=no + +# when you set need_version to no, make sure it does not cause -set_version +# flags to be left without arguments +need_version=unknown + +case $host_os in +aix3*) + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a' + shlibpath_var=LIBPATH + + # AIX 3 has no versioning support, so we append a major version to the name. + soname_spec='${libname}${release}${shared_ext}$major' + ;; + +aix[[4-9]]*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + hardcode_into_libs=yes + if test "$host_cpu" = ia64; then + # AIX 5 supports IA64 + library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + else + # With GCC up to 2.95.x, collect2 would create an import file + # for dependence libraries. The import file would start with + # the line `#! .'. This would cause the generated library to + # depend on `.', always an invalid library. This was fixed in + # development snapshots of GCC prior to 3.0. + case $host_os in + aix4 | aix4.[[01]] | aix4.[[01]].*) + if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' + echo ' yes ' + echo '#endif'; } | ${CC} -E - | $GREP yes > /dev/null; then + : + else + can_build_shared=no + fi + ;; + esac + # AIX (on Power*) has no versioning support, so currently we can not hardcode correct + # soname into executable. Probably we can add versioning support to + # collect2, so additional links can be useful in future. + if test "$aix_use_runtimelinking" = yes; then + # If using run time linking (on AIX 4.2 or later) use lib.so + # instead of lib.a to let people know that these are not + # typical AIX shared libraries. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + else + # We preserve .a as extension for shared libraries through AIX4.2 + # and later when we are not doing run time linking. + library_names_spec='${libname}${release}.a $libname.a' + soname_spec='${libname}${release}${shared_ext}$major' + fi + shlibpath_var=LIBPATH + fi + ;; + +amigaos*) + case $host_cpu in + powerpc) + # Since July 2007 AmigaOS4 officially supports .so libraries. + # When compiling the executable, add -use-dynld -Lsobjs: to the compileline. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + ;; + m68k) + library_names_spec='$libname.ixlibrary $libname.a' + # Create ${libname}_ixlibrary.a entries in /sys/libs. + finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([[^/]]*\)\.ixlibrary$%\1%'\''`; test $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' + ;; + esac + ;; + +beos*) + library_names_spec='${libname}${shared_ext}' + dynamic_linker="$host_os ld.so" + shlibpath_var=LIBRARY_PATH + ;; + +bsdi[[45]]*) + version_type=linux # correct to gnu/linux during the next big refactor + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" + sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" + # the default ld.so.conf also contains /usr/contrib/lib and + # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow + # libtool to hard-code these into programs + ;; + +cygwin* | mingw* | pw32* | cegcc*) + version_type=windows + shrext_cmds=".dll" + need_version=no + need_lib_prefix=no + + case $GCC,$cc_basename in + yes,*) + # gcc + library_names_spec='$libname.dll.a' + # DLL is installed to $(libdir)/../bin by postinstall_cmds + postinstall_cmds='base_file=`basename \${file}`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + test -d \$dldir || mkdir -p \$dldir~ + $install_prog $dir/$dlname \$dldir/$dlname~ + chmod a+x \$dldir/$dlname~ + if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then + eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; + fi' + postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ + dlpath=$dir/\$dldll~ + $RM \$dlpath' + shlibpath_overrides_runpath=yes + + case $host_os in + cygwin*) + # Cygwin DLLs use 'cyg' prefix rather than 'lib' + soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}' +m4_if([$1], [],[ + sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/lib/w32api"]) + ;; + mingw* | cegcc*) + # MinGW DLLs use traditional 'lib' prefix + soname_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}' + ;; + pw32*) + # pw32 DLLs use 'pw' prefix rather than 'lib' + library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}' + ;; + esac + dynamic_linker='Win32 ld.exe' + ;; + + *,cl*) + # Native MSVC + libname_spec='$name' + soname_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}' + library_names_spec='${libname}.dll.lib' + + case $build_os in + mingw*) + sys_lib_search_path_spec= + lt_save_ifs=$IFS + IFS=';' + for lt_path in $LIB + do + IFS=$lt_save_ifs + # Let DOS variable expansion print the short 8.3 style file name. + lt_path=`cd "$lt_path" 2>/dev/null && cmd //C "for %i in (".") do @echo %~si"` + sys_lib_search_path_spec="$sys_lib_search_path_spec $lt_path" + done + IFS=$lt_save_ifs + # Convert to MSYS style. + sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | sed -e 's|\\\\|/|g' -e 's| \\([[a-zA-Z]]\\):| /\\1|g' -e 's|^ ||'` + ;; + cygwin*) + # Convert to unix form, then to dos form, then back to unix form + # but this time dos style (no spaces!) so that the unix form looks + # like /cygdrive/c/PROGRA~1:/cygdr... + sys_lib_search_path_spec=`cygpath --path --unix "$LIB"` + sys_lib_search_path_spec=`cygpath --path --dos "$sys_lib_search_path_spec" 2>/dev/null` + sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` + ;; + *) + sys_lib_search_path_spec="$LIB" + if $ECHO "$sys_lib_search_path_spec" | [$GREP ';[c-zC-Z]:/' >/dev/null]; then + # It is most probably a Windows format PATH. + sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` + else + sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` + fi + # FIXME: find the short name or the path components, as spaces are + # common. (e.g. "Program Files" -> "PROGRA~1") + ;; + esac + + # DLL is installed to $(libdir)/../bin by postinstall_cmds + postinstall_cmds='base_file=`basename \${file}`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + test -d \$dldir || mkdir -p \$dldir~ + $install_prog $dir/$dlname \$dldir/$dlname' + postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ + dlpath=$dir/\$dldll~ + $RM \$dlpath' + shlibpath_overrides_runpath=yes + dynamic_linker='Win32 link.exe' + ;; + + *) + # Assume MSVC wrapper + library_names_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext} $libname.lib' + dynamic_linker='Win32 ld.exe' + ;; + esac + # FIXME: first we should search . and the directory the executable is in + shlibpath_var=PATH + ;; + +darwin* | rhapsody*) + dynamic_linker="$host_os dyld" + version_type=darwin + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${major}$shared_ext ${libname}$shared_ext' + soname_spec='${libname}${release}${major}$shared_ext' + shlibpath_overrides_runpath=yes + shlibpath_var=DYLD_LIBRARY_PATH + shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' +m4_if([$1], [],[ + sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/local/lib"]) + sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' + ;; + +dgux*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +freebsd* | dragonfly*) + # DragonFly does not have aout. When/if they implement a new + # versioning mechanism, adjust this. + if test -x /usr/bin/objformat; then + objformat=`/usr/bin/objformat` + else + case $host_os in + freebsd[[23]].*) objformat=aout ;; + *) objformat=elf ;; + esac + fi + version_type=freebsd-$objformat + case $version_type in + freebsd-elf*) + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' + need_version=no + need_lib_prefix=no + ;; + freebsd-*) + library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix' + need_version=yes + ;; + esac + shlibpath_var=LD_LIBRARY_PATH + case $host_os in + freebsd2.*) + shlibpath_overrides_runpath=yes + ;; + freebsd3.[[01]]* | freebsdelf3.[[01]]*) + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + freebsd3.[[2-9]]* | freebsdelf3.[[2-9]]* | \ + freebsd4.[[0-5]] | freebsdelf4.[[0-5]] | freebsd4.1.1 | freebsdelf4.1.1) + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + *) # from 4.6 on, and DragonFly + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + esac + ;; + +gnu*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + +haiku*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + dynamic_linker="$host_os runtime_loader" + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LIBRARY_PATH + shlibpath_overrides_runpath=yes + sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib' + hardcode_into_libs=yes + ;; + +hpux9* | hpux10* | hpux11*) + # Give a soname corresponding to the major version so that dld.sl refuses to + # link against other versions. + version_type=sunos + need_lib_prefix=no + need_version=no + case $host_cpu in + ia64*) + shrext_cmds='.so' + hardcode_into_libs=yes + dynamic_linker="$host_os dld.so" + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + if test "X$HPUX_IA64_MODE" = X32; then + sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" + else + sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" + fi + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + hppa*64*) + shrext_cmds='.sl' + hardcode_into_libs=yes + dynamic_linker="$host_os dld.sl" + shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH + shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + *) + shrext_cmds='.sl' + dynamic_linker="$host_os dld.sl" + shlibpath_var=SHLIB_PATH + shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + ;; + esac + # HP-UX runs *really* slowly unless shared libraries are mode 555, ... + postinstall_cmds='chmod 555 $lib' + # or fails outright, so override atomically: + install_override_mode=555 + ;; + +interix[[3-9]]*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + +irix5* | irix6* | nonstopux*) + case $host_os in + nonstopux*) version_type=nonstopux ;; + *) + if test "$lt_cv_prog_gnu_ld" = yes; then + version_type=linux # correct to gnu/linux during the next big refactor + else + version_type=irix + fi ;; + esac + need_lib_prefix=no + need_version=no + soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}' + case $host_os in + irix5* | nonstopux*) + libsuff= shlibsuff= + ;; + *) + case $LD in # libtool.m4 will add one of these switches to LD + *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") + libsuff= shlibsuff= libmagic=32-bit;; + *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") + libsuff=32 shlibsuff=N32 libmagic=N32;; + *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") + libsuff=64 shlibsuff=64 libmagic=64-bit;; + *) libsuff= shlibsuff= libmagic=never-match;; + esac + ;; + esac + shlibpath_var=LD_LIBRARY${shlibsuff}_PATH + shlibpath_overrides_runpath=no + sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}" + sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}" + hardcode_into_libs=yes + ;; + +# No shared lib support for Linux oldld, aout, or coff. +linux*oldld* | linux*aout* | linux*coff*) + dynamic_linker=no + ;; + +# This must be glibc/ELF. +linux* | k*bsd*-gnu | kopensolaris*-gnu) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + + # Some binutils ld are patched to set DT_RUNPATH + AC_CACHE_VAL([lt_cv_shlibpath_overrides_runpath], + [lt_cv_shlibpath_overrides_runpath=no + save_LDFLAGS=$LDFLAGS + save_libdir=$libdir + eval "libdir=/foo; wl=\"$_LT_TAGVAR(lt_prog_compiler_wl, $1)\"; \ + LDFLAGS=\"\$LDFLAGS $_LT_TAGVAR(hardcode_libdir_flag_spec, $1)\"" + AC_LINK_IFELSE([AC_LANG_PROGRAM([],[])], + [AS_IF([ ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null], + [lt_cv_shlibpath_overrides_runpath=yes])]) + LDFLAGS=$save_LDFLAGS + libdir=$save_libdir + ]) + shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath + + # This implies no fast_install, which is unacceptable. + # Some rework will be needed to allow for fast_install + # before this can be enabled. + hardcode_into_libs=yes + + # Append ld.so.conf contents to the search path + if test -f /etc/ld.so.conf; then + lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \[$]2)); skip = 1; } { if (!skip) print \[$]0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '` + sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra" + fi + + # We used to test for /lib/ld.so.1 and disable shared libraries on + # powerpc, because MkLinux only supported shared libraries with the + # GNU dynamic linker. Since this was broken with cross compilers, + # most powerpc-linux boxes support dynamic linking these days and + # people can always --disable-shared, the test was removed, and we + # assume the GNU/Linux dynamic linker is in use. + dynamic_linker='GNU/Linux ld.so' + ;; + +netbsdelf*-gnu) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + dynamic_linker='NetBSD ld.elf_so' + ;; + +netbsd*) + version_type=sunos + need_lib_prefix=no + need_version=no + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + dynamic_linker='NetBSD (a.out) ld.so' + else + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + dynamic_linker='NetBSD ld.elf_so' + fi + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + +newsos6) + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + ;; + +*nto* | *qnx*) + version_type=qnx + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + dynamic_linker='ldqnx.so' + ;; + +openbsd*) + version_type=sunos + sys_lib_dlsearch_path_spec="/usr/lib" + need_lib_prefix=no + # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs. + case $host_os in + openbsd3.3 | openbsd3.3.*) need_version=yes ;; + *) need_version=no ;; + esac + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + shlibpath_var=LD_LIBRARY_PATH + if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + case $host_os in + openbsd2.[[89]] | openbsd2.[[89]].*) + shlibpath_overrides_runpath=no + ;; + *) + shlibpath_overrides_runpath=yes + ;; + esac + else + shlibpath_overrides_runpath=yes + fi + ;; + +os2*) + libname_spec='$name' + shrext_cmds=".dll" + need_lib_prefix=no + library_names_spec='$libname${shared_ext} $libname.a' + dynamic_linker='OS/2 ld.exe' + shlibpath_var=LIBPATH + ;; + +osf3* | osf4* | osf5*) + version_type=osf + need_lib_prefix=no + need_version=no + soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" + sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec" + ;; + +rdos*) + dynamic_linker=no + ;; + +solaris*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + # ldd complains unless libraries are executable + postinstall_cmds='chmod +x $lib' + ;; + +sunos4*) + version_type=sunos + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + if test "$with_gnu_ld" = yes; then + need_lib_prefix=no + fi + need_version=yes + ;; + +sysv4 | sysv4.3*) + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + case $host_vendor in + sni) + shlibpath_overrides_runpath=no + need_lib_prefix=no + runpath_var=LD_RUN_PATH + ;; + siemens) + need_lib_prefix=no + ;; + motorola) + need_lib_prefix=no + need_version=no + shlibpath_overrides_runpath=no + sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' + ;; + esac + ;; + +sysv4*MP*) + if test -d /usr/nec ;then + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}' + soname_spec='$libname${shared_ext}.$major' + shlibpath_var=LD_LIBRARY_PATH + fi + ;; + +sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) + version_type=freebsd-elf + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + if test "$with_gnu_ld" = yes; then + sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' + else + sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' + case $host_os in + sco3.2v5*) + sys_lib_search_path_spec="$sys_lib_search_path_spec /lib" + ;; + esac + fi + sys_lib_dlsearch_path_spec='/usr/lib' + ;; + +tpf*) + # TPF is a cross-target only. Preferred cross-host = GNU/Linux. + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + +uts4*) + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +*) + dynamic_linker=no + ;; +esac +AC_MSG_RESULT([$dynamic_linker]) +test "$dynamic_linker" = no && can_build_shared=no + +variables_saved_for_relink="PATH $shlibpath_var $runpath_var" +if test "$GCC" = yes; then + variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" +fi + +if test "${lt_cv_sys_lib_search_path_spec+set}" = set; then + sys_lib_search_path_spec="$lt_cv_sys_lib_search_path_spec" +fi +if test "${lt_cv_sys_lib_dlsearch_path_spec+set}" = set; then + sys_lib_dlsearch_path_spec="$lt_cv_sys_lib_dlsearch_path_spec" +fi + +_LT_DECL([], [variables_saved_for_relink], [1], + [Variables whose values should be saved in libtool wrapper scripts and + restored at link time]) +_LT_DECL([], [need_lib_prefix], [0], + [Do we need the "lib" prefix for modules?]) +_LT_DECL([], [need_version], [0], [Do we need a version for libraries?]) +_LT_DECL([], [version_type], [0], [Library versioning type]) +_LT_DECL([], [runpath_var], [0], [Shared library runtime path variable]) +_LT_DECL([], [shlibpath_var], [0],[Shared library path variable]) +_LT_DECL([], [shlibpath_overrides_runpath], [0], + [Is shlibpath searched before the hard-coded library search path?]) +_LT_DECL([], [libname_spec], [1], [Format of library name prefix]) +_LT_DECL([], [library_names_spec], [1], + [[List of archive names. First name is the real one, the rest are links. + The last name is the one that the linker finds with -lNAME]]) +_LT_DECL([], [soname_spec], [1], + [[The coded name of the library, if different from the real name]]) +_LT_DECL([], [install_override_mode], [1], + [Permission mode override for installation of shared libraries]) +_LT_DECL([], [postinstall_cmds], [2], + [Command to use after installation of a shared archive]) +_LT_DECL([], [postuninstall_cmds], [2], + [Command to use after uninstallation of a shared archive]) +_LT_DECL([], [finish_cmds], [2], + [Commands used to finish a libtool library installation in a directory]) +_LT_DECL([], [finish_eval], [1], + [[As "finish_cmds", except a single script fragment to be evaled but + not shown]]) +_LT_DECL([], [hardcode_into_libs], [0], + [Whether we should hardcode library paths into libraries]) +_LT_DECL([], [sys_lib_search_path_spec], [2], + [Compile-time system search path for libraries]) +_LT_DECL([], [sys_lib_dlsearch_path_spec], [2], + [Run-time system search path for libraries]) +])# _LT_SYS_DYNAMIC_LINKER + + +# _LT_PATH_TOOL_PREFIX(TOOL) +# -------------------------- +# find a file program which can recognize shared library +AC_DEFUN([_LT_PATH_TOOL_PREFIX], +[m4_require([_LT_DECL_EGREP])dnl +AC_MSG_CHECKING([for $1]) +AC_CACHE_VAL(lt_cv_path_MAGIC_CMD, +[case $MAGIC_CMD in +[[\\/*] | ?:[\\/]*]) + lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path. + ;; +*) + lt_save_MAGIC_CMD="$MAGIC_CMD" + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR +dnl $ac_dummy forces splitting on constant user-supplied paths. +dnl POSIX.2 word splitting is done only on the output of word expansions, +dnl not every word. This closes a longstanding sh security hole. + ac_dummy="m4_if([$2], , $PATH, [$2])" + for ac_dir in $ac_dummy; do + IFS="$lt_save_ifs" + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$1; then + lt_cv_path_MAGIC_CMD="$ac_dir/$1" + if test -n "$file_magic_test_file"; then + case $deplibs_check_method in + "file_magic "*) + file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` + MAGIC_CMD="$lt_cv_path_MAGIC_CMD" + if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | + $EGREP "$file_magic_regex" > /dev/null; then + : + else + cat <<_LT_EOF 1>&2 + +*** Warning: the command libtool uses to detect shared libraries, +*** $file_magic_cmd, produces output that libtool cannot recognize. +*** The result is that libtool may fail to recognize shared libraries +*** as such. This will affect the creation of libtool libraries that +*** depend on shared libraries, but programs linked with such libtool +*** libraries will work regardless of this problem. Nevertheless, you +*** may want to report the problem to your system manager and/or to +*** bug-libtool@gnu.org + +_LT_EOF + fi ;; + esac + fi + break + fi + done + IFS="$lt_save_ifs" + MAGIC_CMD="$lt_save_MAGIC_CMD" + ;; +esac]) +MAGIC_CMD="$lt_cv_path_MAGIC_CMD" +if test -n "$MAGIC_CMD"; then + AC_MSG_RESULT($MAGIC_CMD) +else + AC_MSG_RESULT(no) +fi +_LT_DECL([], [MAGIC_CMD], [0], + [Used to examine libraries when file_magic_cmd begins with "file"])dnl +])# _LT_PATH_TOOL_PREFIX + +# Old name: +AU_ALIAS([AC_PATH_TOOL_PREFIX], [_LT_PATH_TOOL_PREFIX]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_PATH_TOOL_PREFIX], []) + + +# _LT_PATH_MAGIC +# -------------- +# find a file program which can recognize a shared library +m4_defun([_LT_PATH_MAGIC], +[_LT_PATH_TOOL_PREFIX(${ac_tool_prefix}file, /usr/bin$PATH_SEPARATOR$PATH) +if test -z "$lt_cv_path_MAGIC_CMD"; then + if test -n "$ac_tool_prefix"; then + _LT_PATH_TOOL_PREFIX(file, /usr/bin$PATH_SEPARATOR$PATH) + else + MAGIC_CMD=: + fi +fi +])# _LT_PATH_MAGIC + + +# LT_PATH_LD +# ---------- +# find the pathname to the GNU or non-GNU linker +AC_DEFUN([LT_PATH_LD], +[AC_REQUIRE([AC_PROG_CC])dnl +AC_REQUIRE([AC_CANONICAL_HOST])dnl +AC_REQUIRE([AC_CANONICAL_BUILD])dnl +m4_require([_LT_DECL_SED])dnl +m4_require([_LT_DECL_EGREP])dnl +m4_require([_LT_PROG_ECHO_BACKSLASH])dnl + +AC_ARG_WITH([gnu-ld], + [AS_HELP_STRING([--with-gnu-ld], + [assume the C compiler uses GNU ld @<:@default=no@:>@])], + [test "$withval" = no || with_gnu_ld=yes], + [with_gnu_ld=no])dnl + +ac_prog=ld +if test "$GCC" = yes; then + # Check if gcc -print-prog-name=ld gives a path. + AC_MSG_CHECKING([for ld used by $CC]) + case $host in + *-*-mingw*) + # gcc leaves a trailing carriage return which upsets mingw + ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; + *) + ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; + esac + case $ac_prog in + # Accept absolute paths. + [[\\/]]* | ?:[[\\/]]*) + re_direlt='/[[^/]][[^/]]*/\.\./' + # Canonicalize the pathname of ld + ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'` + while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do + ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"` + done + test -z "$LD" && LD="$ac_prog" + ;; + "") + # If it fails, then pretend we aren't using GCC. + ac_prog=ld + ;; + *) + # If it is relative, then search for the first ld in PATH. + with_gnu_ld=unknown + ;; + esac +elif test "$with_gnu_ld" = yes; then + AC_MSG_CHECKING([for GNU ld]) +else + AC_MSG_CHECKING([for non-GNU ld]) +fi +AC_CACHE_VAL(lt_cv_path_LD, +[if test -z "$LD"; then + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + for ac_dir in $PATH; do + IFS="$lt_save_ifs" + test -z "$ac_dir" && ac_dir=. + if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then + lt_cv_path_LD="$ac_dir/$ac_prog" + # Check to see if the program is GNU ld. I'd rather use --version, + # but apparently some variants of GNU ld only accept -v. + # Break only if it was the GNU/non-GNU ld that we prefer. + case `"$lt_cv_path_LD" -v 2>&1 &1 /dev/null 2>&1; then + lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' + lt_cv_file_magic_cmd='func_win32_libid' + else + # Keep this pattern in sync with the one in func_win32_libid. + lt_cv_deplibs_check_method='file_magic file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)' + lt_cv_file_magic_cmd='$OBJDUMP -f' + fi + ;; + +cegcc*) + # use the weaker test based on 'objdump'. See mingw*. + lt_cv_deplibs_check_method='file_magic file format pe-arm-.*little(.*architecture: arm)?' + lt_cv_file_magic_cmd='$OBJDUMP -f' + ;; + +darwin* | rhapsody*) + lt_cv_deplibs_check_method=pass_all + ;; + +freebsd* | dragonfly*) + if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then + case $host_cpu in + i*86 ) + # Not sure whether the presence of OpenBSD here was a mistake. + # Let's accept both of them until this is cleared up. + lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[[3-9]]86 (compact )?demand paged shared library' + lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*` + ;; + esac + else + lt_cv_deplibs_check_method=pass_all + fi + ;; + +gnu*) + lt_cv_deplibs_check_method=pass_all + ;; + +haiku*) + lt_cv_deplibs_check_method=pass_all + ;; + +hpux10.20* | hpux11*) + lt_cv_file_magic_cmd=/usr/bin/file + case $host_cpu in + ia64*) + lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|ELF-[[0-9]][[0-9]]) shared object file - IA64' + lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so + ;; + hppa*64*) + [lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF[ -][0-9][0-9])(-bit)?( [LM]SB)? shared object( file)?[, -]* PA-RISC [0-9]\.[0-9]'] + lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl + ;; + *) + lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|PA-RISC[[0-9]]\.[[0-9]]) shared library' + lt_cv_file_magic_test_file=/usr/lib/libc.sl + ;; + esac + ;; + +interix[[3-9]]*) + # PIC code is broken on Interix 3.x, that's why |\.a not |_pic\.a here + lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so|\.a)$' + ;; + +irix5* | irix6* | nonstopux*) + case $LD in + *-32|*"-32 ") libmagic=32-bit;; + *-n32|*"-n32 ") libmagic=N32;; + *-64|*"-64 ") libmagic=64-bit;; + *) libmagic=never-match;; + esac + lt_cv_deplibs_check_method=pass_all + ;; + +# This must be glibc/ELF. +linux* | k*bsd*-gnu | kopensolaris*-gnu) + lt_cv_deplibs_check_method=pass_all + ;; + +netbsd* | netbsdelf*-gnu) + if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then + lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$' + else + lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so|_pic\.a)$' + fi + ;; + +newos6*) + lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (executable|dynamic lib)' + lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_test_file=/usr/lib/libnls.so + ;; + +*nto* | *qnx*) + lt_cv_deplibs_check_method=pass_all + ;; + +openbsd*) + if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|\.so|_pic\.a)$' + else + lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$' + fi + ;; + +osf3* | osf4* | osf5*) + lt_cv_deplibs_check_method=pass_all + ;; + +rdos*) + lt_cv_deplibs_check_method=pass_all + ;; + +solaris*) + lt_cv_deplibs_check_method=pass_all + ;; + +sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) + lt_cv_deplibs_check_method=pass_all + ;; + +sysv4 | sysv4.3*) + case $host_vendor in + motorola) + lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (shared object|dynamic lib) M[[0-9]][[0-9]]* Version [[0-9]]' + lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*` + ;; + ncr) + lt_cv_deplibs_check_method=pass_all + ;; + sequent) + lt_cv_file_magic_cmd='/bin/file' + lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB (shared object|dynamic lib )' + ;; + sni) + lt_cv_file_magic_cmd='/bin/file' + lt_cv_deplibs_check_method="file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB dynamic lib" + lt_cv_file_magic_test_file=/lib/libc.so + ;; + siemens) + lt_cv_deplibs_check_method=pass_all + ;; + pc) + lt_cv_deplibs_check_method=pass_all + ;; + esac + ;; + +tpf*) + lt_cv_deplibs_check_method=pass_all + ;; +esac +]) + +file_magic_glob= +want_nocaseglob=no +if test "$build" = "$host"; then + case $host_os in + mingw* | pw32*) + if ( shopt | grep nocaseglob ) >/dev/null 2>&1; then + want_nocaseglob=yes + else + file_magic_glob=`echo aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ | $SED -e "s/\(..\)/s\/[[\1]]\/[[\1]]\/g;/g"` + fi + ;; + esac +fi + +file_magic_cmd=$lt_cv_file_magic_cmd +deplibs_check_method=$lt_cv_deplibs_check_method +test -z "$deplibs_check_method" && deplibs_check_method=unknown + +_LT_DECL([], [deplibs_check_method], [1], + [Method to check whether dependent libraries are shared objects]) +_LT_DECL([], [file_magic_cmd], [1], + [Command to use when deplibs_check_method = "file_magic"]) +_LT_DECL([], [file_magic_glob], [1], + [How to find potential files when deplibs_check_method = "file_magic"]) +_LT_DECL([], [want_nocaseglob], [1], + [Find potential files using nocaseglob when deplibs_check_method = "file_magic"]) +])# _LT_CHECK_MAGIC_METHOD + + +# LT_PATH_NM +# ---------- +# find the pathname to a BSD- or MS-compatible name lister +AC_DEFUN([LT_PATH_NM], +[AC_REQUIRE([AC_PROG_CC])dnl +AC_CACHE_CHECK([for BSD- or MS-compatible name lister (nm)], lt_cv_path_NM, +[if test -n "$NM"; then + # Let the user override the test. + lt_cv_path_NM="$NM" +else + lt_nm_to_check="${ac_tool_prefix}nm" + if test -n "$ac_tool_prefix" && test "$build" = "$host"; then + lt_nm_to_check="$lt_nm_to_check nm" + fi + for lt_tmp_nm in $lt_nm_to_check; do + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do + IFS="$lt_save_ifs" + test -z "$ac_dir" && ac_dir=. + tmp_nm="$ac_dir/$lt_tmp_nm" + if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext" ; then + # Check to see if the nm accepts a BSD-compat flag. + # Adding the `sed 1q' prevents false positives on HP-UX, which says: + # nm: unknown option "B" ignored + # Tru64's nm complains that /dev/null is an invalid object file + case `"$tmp_nm" -B /dev/null 2>&1 | sed '1q'` in + */dev/null* | *'Invalid file or object type'*) + lt_cv_path_NM="$tmp_nm -B" + break + ;; + *) + case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in + */dev/null*) + lt_cv_path_NM="$tmp_nm -p" + break + ;; + *) + lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but + continue # so that we can try to find one that supports BSD flags + ;; + esac + ;; + esac + fi + done + IFS="$lt_save_ifs" + done + : ${lt_cv_path_NM=no} +fi]) +if test "$lt_cv_path_NM" != "no"; then + NM="$lt_cv_path_NM" +else + # Didn't find any BSD compatible name lister, look for dumpbin. + if test -n "$DUMPBIN"; then : + # Let the user override the test. + else + AC_CHECK_TOOLS(DUMPBIN, [dumpbin "link -dump"], :) + case `$DUMPBIN -symbols /dev/null 2>&1 | sed '1q'` in + *COFF*) + DUMPBIN="$DUMPBIN -symbols" + ;; + *) + DUMPBIN=: + ;; + esac + fi + AC_SUBST([DUMPBIN]) + if test "$DUMPBIN" != ":"; then + NM="$DUMPBIN" + fi +fi +test -z "$NM" && NM=nm +AC_SUBST([NM]) +_LT_DECL([], [NM], [1], [A BSD- or MS-compatible name lister])dnl + +AC_CACHE_CHECK([the name lister ($NM) interface], [lt_cv_nm_interface], + [lt_cv_nm_interface="BSD nm" + echo "int some_variable = 0;" > conftest.$ac_ext + (eval echo "\"\$as_me:$LINENO: $ac_compile\"" >&AS_MESSAGE_LOG_FD) + (eval "$ac_compile" 2>conftest.err) + cat conftest.err >&AS_MESSAGE_LOG_FD + (eval echo "\"\$as_me:$LINENO: $NM \\\"conftest.$ac_objext\\\"\"" >&AS_MESSAGE_LOG_FD) + (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out) + cat conftest.err >&AS_MESSAGE_LOG_FD + (eval echo "\"\$as_me:$LINENO: output\"" >&AS_MESSAGE_LOG_FD) + cat conftest.out >&AS_MESSAGE_LOG_FD + if $GREP 'External.*some_variable' conftest.out > /dev/null; then + lt_cv_nm_interface="MS dumpbin" + fi + rm -f conftest*]) +])# LT_PATH_NM + +# Old names: +AU_ALIAS([AM_PROG_NM], [LT_PATH_NM]) +AU_ALIAS([AC_PROG_NM], [LT_PATH_NM]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AM_PROG_NM], []) +dnl AC_DEFUN([AC_PROG_NM], []) + +# _LT_CHECK_SHAREDLIB_FROM_LINKLIB +# -------------------------------- +# how to determine the name of the shared library +# associated with a specific link library. +# -- PORTME fill in with the dynamic library characteristics +m4_defun([_LT_CHECK_SHAREDLIB_FROM_LINKLIB], +[m4_require([_LT_DECL_EGREP]) +m4_require([_LT_DECL_OBJDUMP]) +m4_require([_LT_DECL_DLLTOOL]) +AC_CACHE_CHECK([how to associate runtime and link libraries], +lt_cv_sharedlib_from_linklib_cmd, +[lt_cv_sharedlib_from_linklib_cmd='unknown' + +case $host_os in +cygwin* | mingw* | pw32* | cegcc*) + # two different shell functions defined in ltmain.sh + # decide which to use based on capabilities of $DLLTOOL + case `$DLLTOOL --help 2>&1` in + *--identify-strict*) + lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib + ;; + *) + lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib_fallback + ;; + esac + ;; +*) + # fallback: assume linklib IS sharedlib + lt_cv_sharedlib_from_linklib_cmd="$ECHO" + ;; +esac +]) +sharedlib_from_linklib_cmd=$lt_cv_sharedlib_from_linklib_cmd +test -z "$sharedlib_from_linklib_cmd" && sharedlib_from_linklib_cmd=$ECHO + +_LT_DECL([], [sharedlib_from_linklib_cmd], [1], + [Command to associate shared and link libraries]) +])# _LT_CHECK_SHAREDLIB_FROM_LINKLIB + + +# _LT_PATH_MANIFEST_TOOL +# ---------------------- +# locate the manifest tool +m4_defun([_LT_PATH_MANIFEST_TOOL], +[AC_CHECK_TOOL(MANIFEST_TOOL, mt, :) +test -z "$MANIFEST_TOOL" && MANIFEST_TOOL=mt +AC_CACHE_CHECK([if $MANIFEST_TOOL is a manifest tool], [lt_cv_path_mainfest_tool], + [lt_cv_path_mainfest_tool=no + echo "$as_me:$LINENO: $MANIFEST_TOOL '-?'" >&AS_MESSAGE_LOG_FD + $MANIFEST_TOOL '-?' 2>conftest.err > conftest.out + cat conftest.err >&AS_MESSAGE_LOG_FD + if $GREP 'Manifest Tool' conftest.out > /dev/null; then + lt_cv_path_mainfest_tool=yes + fi + rm -f conftest*]) +if test "x$lt_cv_path_mainfest_tool" != xyes; then + MANIFEST_TOOL=: +fi +_LT_DECL([], [MANIFEST_TOOL], [1], [Manifest tool])dnl +])# _LT_PATH_MANIFEST_TOOL + + +# LT_LIB_M +# -------- +# check for math library +AC_DEFUN([LT_LIB_M], +[AC_REQUIRE([AC_CANONICAL_HOST])dnl +LIBM= +case $host in +*-*-beos* | *-*-cegcc* | *-*-cygwin* | *-*-haiku* | *-*-pw32* | *-*-darwin*) + # These system don't have libm, or don't need it + ;; +*-ncr-sysv4.3*) + AC_CHECK_LIB(mw, _mwvalidcheckl, LIBM="-lmw") + AC_CHECK_LIB(m, cos, LIBM="$LIBM -lm") + ;; +*) + AC_CHECK_LIB(m, cos, LIBM="-lm") + ;; +esac +AC_SUBST([LIBM]) +])# LT_LIB_M + +# Old name: +AU_ALIAS([AC_CHECK_LIBM], [LT_LIB_M]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_CHECK_LIBM], []) + + +# _LT_COMPILER_NO_RTTI([TAGNAME]) +# ------------------------------- +m4_defun([_LT_COMPILER_NO_RTTI], +[m4_require([_LT_TAG_COMPILER])dnl + +_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)= + +if test "$GCC" = yes; then + case $cc_basename in + nvcc*) + _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -Xcompiler -fno-builtin' ;; + *) + _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin' ;; + esac + + _LT_COMPILER_OPTION([if $compiler supports -fno-rtti -fno-exceptions], + lt_cv_prog_compiler_rtti_exceptions, + [-fno-rtti -fno-exceptions], [], + [_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)="$_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1) -fno-rtti -fno-exceptions"]) +fi +_LT_TAGDECL([no_builtin_flag], [lt_prog_compiler_no_builtin_flag], [1], + [Compiler flag to turn off builtin functions]) +])# _LT_COMPILER_NO_RTTI + + +# _LT_CMD_GLOBAL_SYMBOLS +# ---------------------- +m4_defun([_LT_CMD_GLOBAL_SYMBOLS], +[AC_REQUIRE([AC_CANONICAL_HOST])dnl +AC_REQUIRE([AC_PROG_CC])dnl +AC_REQUIRE([AC_PROG_AWK])dnl +AC_REQUIRE([LT_PATH_NM])dnl +AC_REQUIRE([LT_PATH_LD])dnl +m4_require([_LT_DECL_SED])dnl +m4_require([_LT_DECL_EGREP])dnl +m4_require([_LT_TAG_COMPILER])dnl + +# Check for command to grab the raw symbol name followed by C symbol from nm. +AC_MSG_CHECKING([command to parse $NM output from $compiler object]) +AC_CACHE_VAL([lt_cv_sys_global_symbol_pipe], +[ +# These are sane defaults that work on at least a few old systems. +# [They come from Ultrix. What could be older than Ultrix?!! ;)] + +# Character class describing NM global symbol codes. +symcode='[[BCDEGRST]]' + +# Regexp to match symbols that can be accessed directly from C. +sympat='\([[_A-Za-z]][[_A-Za-z0-9]]*\)' + +# Define system-specific variables. +case $host_os in +aix*) + symcode='[[BCDT]]' + ;; +cygwin* | mingw* | pw32* | cegcc*) + symcode='[[ABCDGISTW]]' + ;; +hpux*) + if test "$host_cpu" = ia64; then + symcode='[[ABCDEGRST]]' + fi + ;; +irix* | nonstopux*) + symcode='[[BCDEGRST]]' + ;; +osf*) + symcode='[[BCDEGQRST]]' + ;; +solaris*) + symcode='[[BDRT]]' + ;; +sco3.2v5*) + symcode='[[DT]]' + ;; +sysv4.2uw2*) + symcode='[[DT]]' + ;; +sysv5* | sco5v6* | unixware* | OpenUNIX*) + symcode='[[ABDT]]' + ;; +sysv4) + symcode='[[DFNSTU]]' + ;; +esac + +# If we're using GNU nm, then use its standard symbol codes. +case `$NM -V 2>&1` in +*GNU* | *'with BFD'*) + symcode='[[ABCDGIRSTW]]' ;; +esac + +# Transform an extracted symbol line into a proper C declaration. +# Some systems (esp. on ia64) link data and code symbols differently, +# so use this general approach. +lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'" + +# Transform an extracted symbol line into symbol name and symbol address +lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([[^ ]]*\)[[ ]]*$/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([[^ ]]*\) \([[^ ]]*\)$/ {\"\2\", (void *) \&\2},/p'" +lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n -e 's/^: \([[^ ]]*\)[[ ]]*$/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([[^ ]]*\) \(lib[[^ ]]*\)$/ {\"\2\", (void *) \&\2},/p' -e 's/^$symcode* \([[^ ]]*\) \([[^ ]]*\)$/ {\"lib\2\", (void *) \&\2},/p'" + +# Handle CRLF in mingw tool chain +opt_cr= +case $build_os in +mingw*) + opt_cr=`$ECHO 'x\{0,1\}' | tr x '\015'` # option cr in regexp + ;; +esac + +# Try without a prefix underscore, then with it. +for ac_symprfx in "" "_"; do + + # Transform symcode, sympat, and symprfx into a raw symbol and a C symbol. + symxfrm="\\1 $ac_symprfx\\2 \\2" + + # Write the raw and C identifiers. + if test "$lt_cv_nm_interface" = "MS dumpbin"; then + # Fake it for dumpbin and say T for any non-static function + # and D for any global variable. + # Also find C++ and __fastcall symbols from MSVC++, + # which start with @ or ?. + lt_cv_sys_global_symbol_pipe="$AWK ['"\ +" {last_section=section; section=\$ 3};"\ +" /^COFF SYMBOL TABLE/{for(i in hide) delete hide[i]};"\ +" /Section length .*#relocs.*(pick any)/{hide[last_section]=1};"\ +" \$ 0!~/External *\|/{next};"\ +" / 0+ UNDEF /{next}; / UNDEF \([^|]\)*()/{next};"\ +" {if(hide[section]) next};"\ +" {f=0}; \$ 0~/\(\).*\|/{f=1}; {printf f ? \"T \" : \"D \"};"\ +" {split(\$ 0, a, /\||\r/); split(a[2], s)};"\ +" s[1]~/^[@?]/{print s[1], s[1]; next};"\ +" s[1]~prfx {split(s[1],t,\"@\"); print t[1], substr(t[1],length(prfx))}"\ +" ' prfx=^$ac_symprfx]" + else + lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[[ ]]\($symcode$symcode*\)[[ ]][[ ]]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'" + fi + lt_cv_sys_global_symbol_pipe="$lt_cv_sys_global_symbol_pipe | sed '/ __gnu_lto/d'" + + # Check to see that the pipe works correctly. + pipe_works=no + + rm -f conftest* + cat > conftest.$ac_ext <<_LT_EOF +#ifdef __cplusplus +extern "C" { +#endif +char nm_test_var; +void nm_test_func(void); +void nm_test_func(void){} +#ifdef __cplusplus +} +#endif +int main(){nm_test_var='a';nm_test_func();return(0);} +_LT_EOF + + if AC_TRY_EVAL(ac_compile); then + # Now try to grab the symbols. + nlist=conftest.nm + if AC_TRY_EVAL(NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist) && test -s "$nlist"; then + # Try sorting and uniquifying the output. + if sort "$nlist" | uniq > "$nlist"T; then + mv -f "$nlist"T "$nlist" + else + rm -f "$nlist"T + fi + + # Make sure that we snagged all the symbols we need. + if $GREP ' nm_test_var$' "$nlist" >/dev/null; then + if $GREP ' nm_test_func$' "$nlist" >/dev/null; then + cat <<_LT_EOF > conftest.$ac_ext +/* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests. */ +#if defined(_WIN32) || defined(__CYGWIN__) || defined(_WIN32_WCE) +/* DATA imports from DLLs on WIN32 con't be const, because runtime + relocations are performed -- see ld's documentation on pseudo-relocs. */ +# define LT@&t@_DLSYM_CONST +#elif defined(__osf__) +/* This system does not cope well with relocations in const data. */ +# define LT@&t@_DLSYM_CONST +#else +# define LT@&t@_DLSYM_CONST const +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +_LT_EOF + # Now generate the symbol file. + eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | $GREP -v main >> conftest.$ac_ext' + + cat <<_LT_EOF >> conftest.$ac_ext + +/* The mapping between symbol names and symbols. */ +LT@&t@_DLSYM_CONST struct { + const char *name; + void *address; +} +lt__PROGRAM__LTX_preloaded_symbols[[]] = +{ + { "@PROGRAM@", (void *) 0 }, +_LT_EOF + $SED "s/^$symcode$symcode* \(.*\) \(.*\)$/ {\"\2\", (void *) \&\2},/" < "$nlist" | $GREP -v main >> conftest.$ac_ext + cat <<\_LT_EOF >> conftest.$ac_ext + {0, (void *) 0} +}; + +/* This works around a problem in FreeBSD linker */ +#ifdef FREEBSD_WORKAROUND +static const void *lt_preloaded_setup() { + return lt__PROGRAM__LTX_preloaded_symbols; +} +#endif + +#ifdef __cplusplus +} +#endif +_LT_EOF + # Now try linking the two files. + mv conftest.$ac_objext conftstm.$ac_objext + lt_globsym_save_LIBS=$LIBS + lt_globsym_save_CFLAGS=$CFLAGS + LIBS="conftstm.$ac_objext" + CFLAGS="$CFLAGS$_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)" + if AC_TRY_EVAL(ac_link) && test -s conftest${ac_exeext}; then + pipe_works=yes + fi + LIBS=$lt_globsym_save_LIBS + CFLAGS=$lt_globsym_save_CFLAGS + else + echo "cannot find nm_test_func in $nlist" >&AS_MESSAGE_LOG_FD + fi + else + echo "cannot find nm_test_var in $nlist" >&AS_MESSAGE_LOG_FD + fi + else + echo "cannot run $lt_cv_sys_global_symbol_pipe" >&AS_MESSAGE_LOG_FD + fi + else + echo "$progname: failed program was:" >&AS_MESSAGE_LOG_FD + cat conftest.$ac_ext >&5 + fi + rm -rf conftest* conftst* + + # Do not use the global_symbol_pipe unless it works. + if test "$pipe_works" = yes; then + break + else + lt_cv_sys_global_symbol_pipe= + fi +done +]) +if test -z "$lt_cv_sys_global_symbol_pipe"; then + lt_cv_sys_global_symbol_to_cdecl= +fi +if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then + AC_MSG_RESULT(failed) +else + AC_MSG_RESULT(ok) +fi + +# Response file support. +if test "$lt_cv_nm_interface" = "MS dumpbin"; then + nm_file_list_spec='@' +elif $NM --help 2>/dev/null | grep '[[@]]FILE' >/dev/null; then + nm_file_list_spec='@' +fi + +_LT_DECL([global_symbol_pipe], [lt_cv_sys_global_symbol_pipe], [1], + [Take the output of nm and produce a listing of raw symbols and C names]) +_LT_DECL([global_symbol_to_cdecl], [lt_cv_sys_global_symbol_to_cdecl], [1], + [Transform the output of nm in a proper C declaration]) +_LT_DECL([global_symbol_to_c_name_address], + [lt_cv_sys_global_symbol_to_c_name_address], [1], + [Transform the output of nm in a C name address pair]) +_LT_DECL([global_symbol_to_c_name_address_lib_prefix], + [lt_cv_sys_global_symbol_to_c_name_address_lib_prefix], [1], + [Transform the output of nm in a C name address pair when lib prefix is needed]) +_LT_DECL([], [nm_file_list_spec], [1], + [Specify filename containing input files for $NM]) +]) # _LT_CMD_GLOBAL_SYMBOLS + + +# _LT_COMPILER_PIC([TAGNAME]) +# --------------------------- +m4_defun([_LT_COMPILER_PIC], +[m4_require([_LT_TAG_COMPILER])dnl +_LT_TAGVAR(lt_prog_compiler_wl, $1)= +_LT_TAGVAR(lt_prog_compiler_pic, $1)= +_LT_TAGVAR(lt_prog_compiler_static, $1)= + +m4_if([$1], [CXX], [ + # C++ specific cases for pic, static, wl, etc. + if test "$GXX" = yes; then + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' + + case $host_os in + aix*) + # All AIX code is PIC. + if test "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + fi + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + m68k) + # FIXME: we need at least 68020 code to build shared libraries, but + # adding the `-m68020' flag to GCC prevents building anything better, + # like `-m68040'. + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4' + ;; + esac + ;; + + beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) + # PIC is the default for these OSes. + ;; + mingw* | cygwin* | os2* | pw32* | cegcc*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + # Although the cygwin gcc ignores -fPIC, still need this for old-style + # (--disable-auto-import) libraries + m4_if([$1], [GCJ], [], + [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) + ;; + darwin* | rhapsody*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common' + ;; + *djgpp*) + # DJGPP does not support shared libraries at all + _LT_TAGVAR(lt_prog_compiler_pic, $1)= + ;; + haiku*) + # PIC is the default for Haiku. + # The "-static" flag exists, but is broken. + _LT_TAGVAR(lt_prog_compiler_static, $1)= + ;; + interix[[3-9]]*) + # Interix 3.x gcc -fpic/-fPIC options generate broken code. + # Instead, we relocate shared libraries at runtime. + ;; + sysv4*MP*) + if test -d /usr/nec; then + _LT_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic + fi + ;; + hpux*) + # PIC is the default for 64-bit PA HP-UX, but not for 32-bit + # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag + # sets the default TLS model and affects inlining. + case $host_cpu in + hppa*64*) + ;; + *) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + esac + ;; + *qnx* | *nto*) + # QNX uses GNU C++, but need to define -shared option too, otherwise + # it will coredump. + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' + ;; + *) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + esac + else + case $host_os in + aix[[4-9]]*) + # All AIX code is PIC. + if test "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + else + _LT_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp' + fi + ;; + chorus*) + case $cc_basename in + cxch68*) + # Green Hills C++ Compiler + # _LT_TAGVAR(lt_prog_compiler_static, $1)="--no_auto_instantiation -u __main -u __premain -u _abort -r $COOL_DIR/lib/libOrb.a $MVME_DIR/lib/CC/libC.a $MVME_DIR/lib/classix/libcx.s.a" + ;; + esac + ;; + mingw* | cygwin* | os2* | pw32* | cegcc*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + m4_if([$1], [GCJ], [], + [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) + ;; + dgux*) + case $cc_basename in + ec++*) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + ;; + ghcx*) + # Green Hills C++ Compiler + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' + ;; + *) + ;; + esac + ;; + freebsd* | dragonfly*) + # FreeBSD uses GNU C++ + ;; + hpux9* | hpux10* | hpux11*) + case $cc_basename in + CC*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive' + if test "$host_cpu" != ia64; then + _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z' + fi + ;; + aCC*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive' + case $host_cpu in + hppa*64*|ia64*) + # +Z the default + ;; + *) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z' + ;; + esac + ;; + *) + ;; + esac + ;; + interix*) + # This is c89, which is MS Visual C++ (no shared libs) + # Anyone wants to do a port? + ;; + irix5* | irix6* | nonstopux*) + case $cc_basename in + CC*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + # CC pic flag -KPIC is the default. + ;; + *) + ;; + esac + ;; + linux* | k*bsd*-gnu | kopensolaris*-gnu) + case $cc_basename in + KCC*) + # KAI C++ Compiler + _LT_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + ecpc* ) + # old Intel C++ for x86_64 which still supported -KPIC. + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' + ;; + icpc* ) + # Intel C++, used to be incompatible with GCC. + # ICC 10 doesn't accept -KPIC any more. + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' + ;; + pgCC* | pgcpp*) + # Portland Group C++ compiler + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + cxx*) + # Compaq C++ + # Make sure the PIC flag is empty. It appears that all Alpha + # Linux and Compaq Tru64 Unix objects are PIC. + _LT_TAGVAR(lt_prog_compiler_pic, $1)= + _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + ;; + xlc* | xlC* | bgxl[[cC]]* | mpixl[[cC]]*) + # IBM XL 8.0, 9.0 on PPC and BlueGene + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-qpic' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-qstaticlink' + ;; + *) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) + # Sun C++ 5.9 + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' + ;; + esac + ;; + esac + ;; + lynxos*) + ;; + m88k*) + ;; + mvs*) + case $cc_basename in + cxx*) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-W c,exportall' + ;; + *) + ;; + esac + ;; + netbsd* | netbsdelf*-gnu) + ;; + *qnx* | *nto*) + # QNX uses GNU C++, but need to define -shared option too, otherwise + # it will coredump. + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' + ;; + osf3* | osf4* | osf5*) + case $cc_basename in + KCC*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,' + ;; + RCC*) + # Rational C++ 2.4.1 + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' + ;; + cxx*) + # Digital/Compaq C++ + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + # Make sure the PIC flag is empty. It appears that all Alpha + # Linux and Compaq Tru64 Unix objects are PIC. + _LT_TAGVAR(lt_prog_compiler_pic, $1)= + _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + ;; + *) + ;; + esac + ;; + psos*) + ;; + solaris*) + case $cc_basename in + CC* | sunCC*) + # Sun C++ 4.2, 5.x and Centerline C++ + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' + ;; + gcx*) + # Green Hills C++ Compiler + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' + ;; + *) + ;; + esac + ;; + sunos4*) + case $cc_basename in + CC*) + # Sun C++ 4.x + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + lcc*) + # Lucid + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' + ;; + *) + ;; + esac + ;; + sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) + case $cc_basename in + CC*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + esac + ;; + tandem*) + case $cc_basename in + NCC*) + # NonStop-UX NCC 3.20 + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + ;; + *) + ;; + esac + ;; + vxworks*) + ;; + *) + _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no + ;; + esac + fi +], +[ + if test "$GCC" = yes; then + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' + + case $host_os in + aix*) + # All AIX code is PIC. + if test "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + fi + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + m68k) + # FIXME: we need at least 68020 code to build shared libraries, but + # adding the `-m68020' flag to GCC prevents building anything better, + # like `-m68040'. + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4' + ;; + esac + ;; + + beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) + # PIC is the default for these OSes. + ;; + + mingw* | cygwin* | pw32* | os2* | cegcc*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + # Although the cygwin gcc ignores -fPIC, still need this for old-style + # (--disable-auto-import) libraries + m4_if([$1], [GCJ], [], + [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) + ;; + + darwin* | rhapsody*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common' + ;; + + haiku*) + # PIC is the default for Haiku. + # The "-static" flag exists, but is broken. + _LT_TAGVAR(lt_prog_compiler_static, $1)= + ;; + + hpux*) + # PIC is the default for 64-bit PA HP-UX, but not for 32-bit + # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag + # sets the default TLS model and affects inlining. + case $host_cpu in + hppa*64*) + # +Z the default + ;; + *) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + esac + ;; + + interix[[3-9]]*) + # Interix 3.x gcc -fpic/-fPIC options generate broken code. + # Instead, we relocate shared libraries at runtime. + ;; + + msdosdjgpp*) + # Just because we use GCC doesn't mean we suddenly get shared libraries + # on systems that don't support them. + _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no + enable_shared=no + ;; + + *nto* | *qnx*) + # QNX uses GNU C++, but need to define -shared option too, otherwise + # it will coredump. + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' + ;; + + sysv4*MP*) + if test -d /usr/nec; then + _LT_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic + fi + ;; + + *) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + esac + + case $cc_basename in + nvcc*) # Cuda Compiler Driver 2.2 + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Xlinker ' + if test -n "$_LT_TAGVAR(lt_prog_compiler_pic, $1)"; then + _LT_TAGVAR(lt_prog_compiler_pic, $1)="-Xcompiler $_LT_TAGVAR(lt_prog_compiler_pic, $1)" + fi + ;; + esac + else + # PORTME Check for flag to pass linker flags through the system compiler. + case $host_os in + aix*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + if test "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + else + _LT_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp' + fi + ;; + + mingw* | cygwin* | pw32* | os2* | cegcc*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + m4_if([$1], [GCJ], [], + [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) + ;; + + hpux9* | hpux10* | hpux11*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but + # not for PA HP-UX. + case $host_cpu in + hppa*64*|ia64*) + # +Z the default + ;; + *) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z' + ;; + esac + # Is there a better lt_prog_compiler_static that works with the bundled CC? + _LT_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive' + ;; + + irix5* | irix6* | nonstopux*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + # PIC (with -KPIC) is the default. + _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + ;; + + linux* | k*bsd*-gnu | kopensolaris*-gnu) + case $cc_basename in + # old Intel for x86_64 which still supported -KPIC. + ecc*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' + ;; + # icc used to be incompatible with GCC. + # ICC 10 doesn't accept -KPIC any more. + icc* | ifort*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' + ;; + # Lahey Fortran 8.1. + lf95*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='--shared' + _LT_TAGVAR(lt_prog_compiler_static, $1)='--static' + ;; + nagfor*) + # NAG Fortran compiler + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,-Wl,,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*) + # Portland Group compilers (*not* the Pentium gcc compiler, + # which looks to be a dead project) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + ccc*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + # All Alpha code is PIC. + _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + ;; + xl* | bgxl* | bgf* | mpixl*) + # IBM XL C 8.0/Fortran 10.1, 11.1 on PPC and BlueGene + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-qpic' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-qstaticlink' + ;; + *) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ Ceres\ Fortran* | *Sun*Fortran*\ [[1-7]].* | *Sun*Fortran*\ 8.[[0-3]]*) + # Sun Fortran 8.3 passes all unrecognized flags to the linker + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + _LT_TAGVAR(lt_prog_compiler_wl, $1)='' + ;; + *Sun\ F* | *Sun*Fortran*) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' + ;; + *Sun\ C*) + # Sun C 5.9 + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + ;; + *Intel*\ [[CF]]*Compiler*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' + ;; + *Portland\ Group*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + esac + ;; + esac + ;; + + newsos6) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + + *nto* | *qnx*) + # QNX uses GNU C++, but need to define -shared option too, otherwise + # it will coredump. + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' + ;; + + osf3* | osf4* | osf5*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + # All OSF/1 code is PIC. + _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + ;; + + rdos*) + _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + ;; + + solaris*) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + case $cc_basename in + f77* | f90* | f95* | sunf77* | sunf90* | sunf95*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ';; + *) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,';; + esac + ;; + + sunos4*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + + sysv4 | sysv4.2uw2* | sysv4.3*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + + sysv4*MP*) + if test -d /usr/nec ;then + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-Kconform_pic' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + fi + ;; + + sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + + unicos*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no + ;; + + uts4*) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + + *) + _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no + ;; + esac + fi +]) +case $host_os in + # For platforms which do not support PIC, -DPIC is meaningless: + *djgpp*) + _LT_TAGVAR(lt_prog_compiler_pic, $1)= + ;; + *) + _LT_TAGVAR(lt_prog_compiler_pic, $1)="$_LT_TAGVAR(lt_prog_compiler_pic, $1)@&t@m4_if([$1],[],[ -DPIC],[m4_if([$1],[CXX],[ -DPIC],[])])" + ;; +esac + +AC_CACHE_CHECK([for $compiler option to produce PIC], + [_LT_TAGVAR(lt_cv_prog_compiler_pic, $1)], + [_LT_TAGVAR(lt_cv_prog_compiler_pic, $1)=$_LT_TAGVAR(lt_prog_compiler_pic, $1)]) +_LT_TAGVAR(lt_prog_compiler_pic, $1)=$_LT_TAGVAR(lt_cv_prog_compiler_pic, $1) + +# +# Check to make sure the PIC flag actually works. +# +if test -n "$_LT_TAGVAR(lt_prog_compiler_pic, $1)"; then + _LT_COMPILER_OPTION([if $compiler PIC flag $_LT_TAGVAR(lt_prog_compiler_pic, $1) works], + [_LT_TAGVAR(lt_cv_prog_compiler_pic_works, $1)], + [$_LT_TAGVAR(lt_prog_compiler_pic, $1)@&t@m4_if([$1],[],[ -DPIC],[m4_if([$1],[CXX],[ -DPIC],[])])], [], + [case $_LT_TAGVAR(lt_prog_compiler_pic, $1) in + "" | " "*) ;; + *) _LT_TAGVAR(lt_prog_compiler_pic, $1)=" $_LT_TAGVAR(lt_prog_compiler_pic, $1)" ;; + esac], + [_LT_TAGVAR(lt_prog_compiler_pic, $1)= + _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no]) +fi +_LT_TAGDECL([pic_flag], [lt_prog_compiler_pic], [1], + [Additional compiler flags for building library objects]) + +_LT_TAGDECL([wl], [lt_prog_compiler_wl], [1], + [How to pass a linker flag through the compiler]) +# +# Check to make sure the static flag actually works. +# +wl=$_LT_TAGVAR(lt_prog_compiler_wl, $1) eval lt_tmp_static_flag=\"$_LT_TAGVAR(lt_prog_compiler_static, $1)\" +_LT_LINKER_OPTION([if $compiler static flag $lt_tmp_static_flag works], + _LT_TAGVAR(lt_cv_prog_compiler_static_works, $1), + $lt_tmp_static_flag, + [], + [_LT_TAGVAR(lt_prog_compiler_static, $1)=]) +_LT_TAGDECL([link_static_flag], [lt_prog_compiler_static], [1], + [Compiler flag to prevent dynamic linking]) +])# _LT_COMPILER_PIC + + +# _LT_LINKER_SHLIBS([TAGNAME]) +# ---------------------------- +# See if the linker supports building shared libraries. +m4_defun([_LT_LINKER_SHLIBS], +[AC_REQUIRE([LT_PATH_LD])dnl +AC_REQUIRE([LT_PATH_NM])dnl +m4_require([_LT_PATH_MANIFEST_TOOL])dnl +m4_require([_LT_FILEUTILS_DEFAULTS])dnl +m4_require([_LT_DECL_EGREP])dnl +m4_require([_LT_DECL_SED])dnl +m4_require([_LT_CMD_GLOBAL_SYMBOLS])dnl +m4_require([_LT_TAG_COMPILER])dnl +AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries]) +m4_if([$1], [CXX], [ + _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' + _LT_TAGVAR(exclude_expsyms, $1)=['_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*'] + case $host_os in + aix[[4-9]]*) + # If we're using GNU nm, then we don't want the "-C" option. + # -C means demangle to AIX nm, but means don't demangle with GNU nm + # Also, AIX nm treats weak defined symbols like other global defined + # symbols, whereas GNU nm marks them as "W". + if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then + _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' + else + _LT_TAGVAR(export_symbols_cmds, $1)='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' + fi + ;; + pw32*) + _LT_TAGVAR(export_symbols_cmds, $1)="$ltdll_cmds" + ;; + cygwin* | mingw* | cegcc*) + case $cc_basename in + cl*) + _LT_TAGVAR(exclude_expsyms, $1)='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*' + ;; + *) + _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/;s/^.*[[ ]]__nm__\([[^ ]]*\)[[ ]][[^ ]]*/\1 DATA/;/^I[[ ]]/d;/^[[AITW]][[ ]]/s/.* //'\'' | sort | uniq > $export_symbols' + _LT_TAGVAR(exclude_expsyms, $1)=['[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname'] + ;; + esac + ;; + linux* | k*bsd*-gnu | gnu*) + _LT_TAGVAR(link_all_deplibs, $1)=no + ;; + *) + _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' + ;; + esac +], [ + runpath_var= + _LT_TAGVAR(allow_undefined_flag, $1)= + _LT_TAGVAR(always_export_symbols, $1)=no + _LT_TAGVAR(archive_cmds, $1)= + _LT_TAGVAR(archive_expsym_cmds, $1)= + _LT_TAGVAR(compiler_needs_object, $1)=no + _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no + _LT_TAGVAR(export_dynamic_flag_spec, $1)= + _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' + _LT_TAGVAR(hardcode_automatic, $1)=no + _LT_TAGVAR(hardcode_direct, $1)=no + _LT_TAGVAR(hardcode_direct_absolute, $1)=no + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= + _LT_TAGVAR(hardcode_libdir_separator, $1)= + _LT_TAGVAR(hardcode_minus_L, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported + _LT_TAGVAR(inherit_rpath, $1)=no + _LT_TAGVAR(link_all_deplibs, $1)=unknown + _LT_TAGVAR(module_cmds, $1)= + _LT_TAGVAR(module_expsym_cmds, $1)= + _LT_TAGVAR(old_archive_from_new_cmds, $1)= + _LT_TAGVAR(old_archive_from_expsyms_cmds, $1)= + _LT_TAGVAR(thread_safe_flag_spec, $1)= + _LT_TAGVAR(whole_archive_flag_spec, $1)= + # include_expsyms should be a list of space-separated symbols to be *always* + # included in the symbol list + _LT_TAGVAR(include_expsyms, $1)= + # exclude_expsyms can be an extended regexp of symbols to exclude + # it will be wrapped by ` (' and `)$', so one must not match beginning or + # end of line. Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc', + # as well as any symbol that contains `d'. + _LT_TAGVAR(exclude_expsyms, $1)=['_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*'] + # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out + # platforms (ab)use it in PIC code, but their linkers get confused if + # the symbol is explicitly referenced. Since portable code cannot + # rely on this symbol name, it's probably fine to never include it in + # preloaded symbol tables. + # Exclude shared library initialization/finalization symbols. +dnl Note also adjust exclude_expsyms for C++ above. + extract_expsyms_cmds= + + case $host_os in + cygwin* | mingw* | pw32* | cegcc*) + # FIXME: the MSVC++ port hasn't been tested in a loooong time + # When not using gcc, we currently assume that we are using + # Microsoft Visual C++. + if test "$GCC" != yes; then + with_gnu_ld=no + fi + ;; + interix*) + # we just hope/assume this is gcc and not c89 (= MSVC++) + with_gnu_ld=yes + ;; + openbsd*) + with_gnu_ld=no + ;; + linux* | k*bsd*-gnu | gnu*) + _LT_TAGVAR(link_all_deplibs, $1)=no + ;; + esac + + _LT_TAGVAR(ld_shlibs, $1)=yes + + # On some targets, GNU ld is compatible enough with the native linker + # that we're better off using the native interface for both. + lt_use_gnu_ld_interface=no + if test "$with_gnu_ld" = yes; then + case $host_os in + aix*) + # The AIX port of GNU ld has always aspired to compatibility + # with the native linker. However, as the warning in the GNU ld + # block says, versions before 2.19.5* couldn't really create working + # shared libraries, regardless of the interface used. + case `$LD -v 2>&1` in + *\ \(GNU\ Binutils\)\ 2.19.5*) ;; + *\ \(GNU\ Binutils\)\ 2.[[2-9]]*) ;; + *\ \(GNU\ Binutils\)\ [[3-9]]*) ;; + *) + lt_use_gnu_ld_interface=yes + ;; + esac + ;; + *) + lt_use_gnu_ld_interface=yes + ;; + esac + fi + + if test "$lt_use_gnu_ld_interface" = yes; then + # If archive_cmds runs LD, not CC, wlarc should be empty + wlarc='${wl}' + + # Set some defaults for GNU ld with shared library support. These + # are reset later if shared libraries are not supported. Putting them + # here allows them to be overridden if necessary. + runpath_var=LD_RUN_PATH + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' + # ancient GNU ld didn't support --whole-archive et. al. + if $LD --help 2>&1 | $GREP 'no-whole-archive' > /dev/null; then + _LT_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' + else + _LT_TAGVAR(whole_archive_flag_spec, $1)= + fi + supports_anon_versioning=no + case `$LD -v 2>&1` in + *GNU\ gold*) supports_anon_versioning=yes ;; + *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.10.*) ;; # catch versions < 2.11 + *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ... + *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ... + *\ 2.11.*) ;; # other 2.11 versions + *) supports_anon_versioning=yes ;; + esac + + # See if GNU ld supports shared libraries. + case $host_os in + aix[[3-9]]*) + # On AIX/PPC, the GNU linker is very broken + if test "$host_cpu" != ia64; then + _LT_TAGVAR(ld_shlibs, $1)=no + cat <<_LT_EOF 1>&2 + +*** Warning: the GNU linker, at least up to release 2.19, is reported +*** to be unable to reliably create shared libraries on AIX. +*** Therefore, libtool is disabling shared libraries support. If you +*** really care for shared libraries, you may want to install binutils +*** 2.20 or above, or modify your PATH so that a non-GNU linker is found. +*** You will then need to restart the configuration process. + +_LT_EOF + fi + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='' + ;; + m68k) + _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_minus_L, $1)=yes + ;; + esac + ;; + + beos*) + if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + # Joseph Beckenbach says some releases of gcc + # support --undefined. This deserves some investigation. FIXME + _LT_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + cygwin* | mingw* | pw32* | cegcc*) + # _LT_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless, + # as there is no search path for DLLs. + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-all-symbols' + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + _LT_TAGVAR(always_export_symbols, $1)=no + _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes + _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/;s/^.*[[ ]]__nm__\([[^ ]]*\)[[ ]][[^ ]]*/\1 DATA/;/^I[[ ]]/d;/^[[AITW]][[ ]]/s/.* //'\'' | sort | uniq > $export_symbols' + _LT_TAGVAR(exclude_expsyms, $1)=['[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname'] + + if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + # If the export-symbols file already is a .def file (1st line + # is EXPORTS), use it as is; otherwise, prepend... + _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then + cp $export_symbols $output_objdir/$soname.def; + else + echo EXPORTS > $output_objdir/$soname.def; + cat $export_symbols >> $output_objdir/$soname.def; + fi~ + $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + haiku*) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_TAGVAR(link_all_deplibs, $1)=yes + ;; + + interix[[3-9]]*) + _LT_TAGVAR(hardcode_direct, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. + # Instead, shared libraries are loaded at an image base (0x10000000 by + # default) and relocated if they conflict, which is a slow very memory + # consuming and fragmenting process. To avoid this, we pick a random, + # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link + # time. Moving up from 0x10000000 also allows more sbrk(2) space. + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + ;; + + gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu) + tmp_diet=no + if test "$host_os" = linux-dietlibc; then + case $cc_basename in + diet\ *) tmp_diet=yes;; # linux-dietlibc with static linking (!diet-dyn) + esac + fi + if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \ + && test "$tmp_diet" = no + then + tmp_addflag=' $pic_flag' + tmp_sharedflag='-shared' + case $cc_basename,$host_cpu in + pgcc*) # Portland Group C compiler + _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' + tmp_addflag=' $pic_flag' + ;; + pgf77* | pgf90* | pgf95* | pgfortran*) + # Portland Group f77 and f90 compilers + _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' + tmp_addflag=' $pic_flag -Mnomain' ;; + ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64 + tmp_addflag=' -i_dynamic' ;; + efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64 + tmp_addflag=' -i_dynamic -nofor_main' ;; + ifc* | ifort*) # Intel Fortran compiler + tmp_addflag=' -nofor_main' ;; + lf95*) # Lahey Fortran 8.1 + _LT_TAGVAR(whole_archive_flag_spec, $1)= + tmp_sharedflag='--shared' ;; + xl[[cC]]* | bgxl[[cC]]* | mpixl[[cC]]*) # IBM XL C 8.0 on PPC (deal with xlf below) + tmp_sharedflag='-qmkshrobj' + tmp_addflag= ;; + nvcc*) # Cuda Compiler Driver 2.2 + _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' + _LT_TAGVAR(compiler_needs_object, $1)=yes + ;; + esac + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) # Sun C 5.9 + _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' + _LT_TAGVAR(compiler_needs_object, $1)=yes + tmp_sharedflag='-G' ;; + *Sun\ F*) # Sun Fortran 8.3 + tmp_sharedflag='-G' ;; + esac + _LT_TAGVAR(archive_cmds, $1)='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + + if test "x$supports_anon_versioning" = xyes; then + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~ + cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ + echo "local: *; };" >> $output_objdir/$libname.ver~ + $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' + fi + + case $cc_basename in + xlf* | bgf* | bgxlf* | mpixlf*) + # IBM XL Fortran 10.1 on PPC cannot create shared libs itself + _LT_TAGVAR(whole_archive_flag_spec, $1)='--whole-archive$convenience --no-whole-archive' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_TAGVAR(archive_cmds, $1)='$LD -shared $libobjs $deplibs $linker_flags -soname $soname -o $lib' + if test "x$supports_anon_versioning" = xyes; then + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~ + cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ + echo "local: *; };" >> $output_objdir/$libname.ver~ + $LD -shared $libobjs $deplibs $linker_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib' + fi + ;; + esac + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + netbsd* | netbsdelf*-gnu) + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' + wlarc= + else + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + fi + ;; + + solaris*) + if $LD -v 2>&1 | $GREP 'BFD 2\.8' > /dev/null; then + _LT_TAGVAR(ld_shlibs, $1)=no + cat <<_LT_EOF 1>&2 + +*** Warning: The releases 2.8.* of the GNU linker cannot reliably +*** create shared libraries on Solaris systems. Therefore, libtool +*** is disabling shared libraries support. We urge you to upgrade GNU +*** binutils to release 2.9.1 or newer. Another option is to modify +*** your PATH or compiler configuration so that the native linker is +*** used, and then restart. + +_LT_EOF + elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*) + case `$LD -v 2>&1` in + *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.1[[0-5]].*) + _LT_TAGVAR(ld_shlibs, $1)=no + cat <<_LT_EOF 1>&2 + +*** Warning: Releases of the GNU linker prior to 2.16.91.0.3 can not +*** reliably create shared libraries on SCO systems. Therefore, libtool +*** is disabling shared libraries support. We urge you to upgrade GNU +*** binutils to release 2.16.91.0.3 or newer. Another option is to modify +*** your PATH or compiler configuration so that the native linker is +*** used, and then restart. + +_LT_EOF + ;; + *) + # For security reasons, it is highly recommended that you always + # use absolute paths for naming shared libraries, and exclude the + # DT_RUNPATH tag from executables and libraries. But doing so + # requires that you compile everything twice, which is a pain. + if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + esac + ;; + + sunos4*) + _LT_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags' + wlarc= + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + *) + if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + esac + + if test "$_LT_TAGVAR(ld_shlibs, $1)" = no; then + runpath_var= + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= + _LT_TAGVAR(export_dynamic_flag_spec, $1)= + _LT_TAGVAR(whole_archive_flag_spec, $1)= + fi + else + # PORTME fill in a description of your system's linker (not GNU ld) + case $host_os in + aix3*) + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + _LT_TAGVAR(always_export_symbols, $1)=yes + _LT_TAGVAR(archive_expsym_cmds, $1)='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname' + # Note: this linker hardcodes the directories in LIBPATH if there + # are no directories specified by -L. + _LT_TAGVAR(hardcode_minus_L, $1)=yes + if test "$GCC" = yes && test -z "$lt_prog_compiler_static"; then + # Neither direct hardcoding nor static linking is supported with a + # broken collect2. + _LT_TAGVAR(hardcode_direct, $1)=unsupported + fi + ;; + + aix[[4-9]]*) + if test "$host_cpu" = ia64; then + # On IA64, the linker does run time linking by default, so we don't + # have to do anything special. + aix_use_runtimelinking=no + exp_sym_flag='-Bexport' + no_entry_flag="" + else + # If we're using GNU nm, then we don't want the "-C" option. + # -C means demangle to AIX nm, but means don't demangle with GNU nm + # Also, AIX nm treats weak defined symbols like other global + # defined symbols, whereas GNU nm marks them as "W". + if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then + _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' + else + _LT_TAGVAR(export_symbols_cmds, $1)='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' + fi + aix_use_runtimelinking=no + + # Test if we are trying to use run time linking or normal + # AIX style linking. If -brtl is somewhere in LDFLAGS, we + # need to do runtime linking. + case $host_os in aix4.[[23]]|aix4.[[23]].*|aix[[5-9]]*) + for ld_flag in $LDFLAGS; do + if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then + aix_use_runtimelinking=yes + break + fi + done + ;; + esac + + exp_sym_flag='-bexport' + no_entry_flag='-bnoentry' + fi + + # When large executables or shared objects are built, AIX ld can + # have problems creating the table of contents. If linking a library + # or program results in "error TOC overflow" add -mminimal-toc to + # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not + # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. + + _LT_TAGVAR(archive_cmds, $1)='' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_direct_absolute, $1)=yes + _LT_TAGVAR(hardcode_libdir_separator, $1)=':' + _LT_TAGVAR(link_all_deplibs, $1)=yes + _LT_TAGVAR(file_list_spec, $1)='${wl}-f,' + + if test "$GCC" = yes; then + case $host_os in aix4.[[012]]|aix4.[[012]].*) + # We only want to do this on AIX 4.2 and lower, the check + # below for broken collect2 doesn't work under 4.3+ + collect2name=`${CC} -print-prog-name=collect2` + if test -f "$collect2name" && + strings "$collect2name" | $GREP resolve_lib_name >/dev/null + then + # We have reworked collect2 + : + else + # We have old collect2 + _LT_TAGVAR(hardcode_direct, $1)=unsupported + # It fails to find uninstalled libraries when the uninstalled + # path is not listed in the libpath. Setting hardcode_minus_L + # to unsupported forces relinking + _LT_TAGVAR(hardcode_minus_L, $1)=yes + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)= + fi + ;; + esac + shared_flag='-shared' + if test "$aix_use_runtimelinking" = yes; then + shared_flag="$shared_flag "'${wl}-G' + fi + _LT_TAGVAR(link_all_deplibs, $1)=no + else + # not using gcc + if test "$host_cpu" = ia64; then + # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release + # chokes on -Wl,-G. The following line is correct: + shared_flag='-G' + else + if test "$aix_use_runtimelinking" = yes; then + shared_flag='${wl}-G' + else + shared_flag='${wl}-bM:SRE' + fi + fi + fi + + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-bexpall' + # It seems that -bexpall does not export symbols beginning with + # underscore (_), so it is better to generate a list of symbols to export. + _LT_TAGVAR(always_export_symbols, $1)=yes + if test "$aix_use_runtimelinking" = yes; then + # Warning - without using the other runtime loading flags (-brtl), + # -berok will link without error, but may produce a broken library. + _LT_TAGVAR(allow_undefined_flag, $1)='-berok' + # Determine the default libpath from the value encoded in an + # empty executable. + _LT_SYS_MODULE_PATH_AIX([$1]) + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then func_echo_all "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" + else + if test "$host_cpu" = ia64; then + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $libdir:/usr/lib:/lib' + _LT_TAGVAR(allow_undefined_flag, $1)="-z nodefs" + _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols" + else + # Determine the default libpath from the value encoded in an + # empty executable. + _LT_SYS_MODULE_PATH_AIX([$1]) + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" + # Warning - without using the other run time loading flags, + # -berok will link without error, but may produce a broken library. + _LT_TAGVAR(no_undefined_flag, $1)=' ${wl}-bernotok' + _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-berok' + if test "$with_gnu_ld" = yes; then + # We only use this code for GNU lds that support --whole-archive. + _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive$convenience ${wl}--no-whole-archive' + else + # Exported symbols can be pulled into shared objects from archives + _LT_TAGVAR(whole_archive_flag_spec, $1)='$convenience' + fi + _LT_TAGVAR(archive_cmds_need_lc, $1)=yes + # This is similar to how AIX traditionally builds its shared libraries. + _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' + fi + fi + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='' + ;; + m68k) + _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_minus_L, $1)=yes + ;; + esac + ;; + + bsdi[[45]]*) + _LT_TAGVAR(export_dynamic_flag_spec, $1)=-rdynamic + ;; + + cygwin* | mingw* | pw32* | cegcc*) + # When not using gcc, we currently assume that we are using + # Microsoft Visual C++. + # hardcode_libdir_flag_spec is actually meaningless, as there is + # no search path for DLLs. + case $cc_basename in + cl*) + # Native MSVC + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' ' + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + _LT_TAGVAR(always_export_symbols, $1)=yes + _LT_TAGVAR(file_list_spec, $1)='@' + # Tell ltmain to make .lib files, not .a files. + libext=lib + # Tell ltmain to make .dll files, not .so files. + shrext_cmds=".dll" + # FIXME: Setting linknames here is a bad hack. + _LT_TAGVAR(archive_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-dll~linknames=' + _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then + sed -n -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' -e '1\\\!p' < $export_symbols > $output_objdir/$soname.exp; + else + sed -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' < $export_symbols > $output_objdir/$soname.exp; + fi~ + $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ + linknames=' + # The linker will not automatically build a static lib if we build a DLL. + # _LT_TAGVAR(old_archive_from_new_cmds, $1)='true' + _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes + _LT_TAGVAR(exclude_expsyms, $1)='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*' + _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1,DATA/'\'' | $SED -e '\''/^[[AITW]][[ ]]/s/.*[[ ]]//'\'' | sort | uniq > $export_symbols' + # Don't use ranlib + _LT_TAGVAR(old_postinstall_cmds, $1)='chmod 644 $oldlib' + _LT_TAGVAR(postlink_cmds, $1)='lt_outputfile="@OUTPUT@"~ + lt_tool_outputfile="@TOOL_OUTPUT@"~ + case $lt_outputfile in + *.exe|*.EXE) ;; + *) + lt_outputfile="$lt_outputfile.exe" + lt_tool_outputfile="$lt_tool_outputfile.exe" + ;; + esac~ + if test "$MANIFEST_TOOL" != ":" && test -f "$lt_outputfile.manifest"; then + $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1; + $RM "$lt_outputfile.manifest"; + fi' + ;; + *) + # Assume MSVC wrapper + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' ' + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + # Tell ltmain to make .lib files, not .a files. + libext=lib + # Tell ltmain to make .dll files, not .so files. + shrext_cmds=".dll" + # FIXME: Setting linknames here is a bad hack. + _LT_TAGVAR(archive_cmds, $1)='$CC -o $lib $libobjs $compiler_flags `func_echo_all "$deplibs" | $SED '\''s/ -lc$//'\''` -link -dll~linknames=' + # The linker will automatically build a .lib file if we build a DLL. + _LT_TAGVAR(old_archive_from_new_cmds, $1)='true' + # FIXME: Should let the user specify the lib program. + _LT_TAGVAR(old_archive_cmds, $1)='lib -OUT:$oldlib$oldobjs$old_deplibs' + _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes + ;; + esac + ;; + + darwin* | rhapsody*) + _LT_DARWIN_LINKER_FEATURES($1) + ;; + + dgux*) + _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor + # support. Future versions do this automatically, but an explicit c++rt0.o + # does not break anything, and helps significantly (at the cost of a little + # extra space). + freebsd2.2*) + _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + # Unfortunately, older versions of FreeBSD 2 do not have this feature. + freebsd2.*) + _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_minus_L, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + # FreeBSD 3 and greater uses gcc -shared to do shared libraries. + freebsd* | dragonfly*) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + hpux9*) + if test "$GCC" = yes; then + _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared $pic_flag ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + else + _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + fi + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + _LT_TAGVAR(hardcode_direct, $1)=yes + + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + _LT_TAGVAR(hardcode_minus_L, $1)=yes + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + ;; + + hpux10*) + if test "$GCC" = yes && test "$with_gnu_ld" = no; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' + else + _LT_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' + fi + if test "$with_gnu_ld" = no; then + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_direct_absolute, $1)=yes + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + _LT_TAGVAR(hardcode_minus_L, $1)=yes + fi + ;; + + hpux11*) + if test "$GCC" = yes && test "$with_gnu_ld" = no; then + case $host_cpu in + hppa*64*) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + ia64*) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + else + case $host_cpu in + hppa*64*) + _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + ia64*) + _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + m4_if($1, [], [ + # Older versions of the 11.00 compiler do not understand -b yet + # (HP92453-01 A.11.01.20 doesn't, HP92453-01 B.11.X.35175-35176.GP does) + _LT_LINKER_OPTION([if $CC understands -b], + _LT_TAGVAR(lt_cv_prog_compiler__b, $1), [-b], + [_LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'], + [_LT_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'])], + [_LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags']) + ;; + esac + fi + if test "$with_gnu_ld" = no; then + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + + case $host_cpu in + hppa*64*|ia64*) + _LT_TAGVAR(hardcode_direct, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + *) + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_direct_absolute, $1)=yes + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + _LT_TAGVAR(hardcode_minus_L, $1)=yes + ;; + esac + fi + ;; + + irix5* | irix6* | nonstopux*) + if test "$GCC" = yes; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + # Try to use the -exported_symbol ld option, if it does not + # work, assume that -exports_file does not work either and + # implicitly export all symbols. + # This should be the same for all languages, so no per-tag cache variable. + AC_CACHE_CHECK([whether the $host_os linker accepts -exported_symbol], + [lt_cv_irix_exported_symbol], + [save_LDFLAGS="$LDFLAGS" + LDFLAGS="$LDFLAGS -shared ${wl}-exported_symbol ${wl}foo ${wl}-update_registry ${wl}/dev/null" + AC_LINK_IFELSE( + [AC_LANG_SOURCE( + [AC_LANG_CASE([C], [[int foo (void) { return 0; }]], + [C++], [[int foo (void) { return 0; }]], + [Fortran 77], [[ + subroutine foo + end]], + [Fortran], [[ + subroutine foo + end]])])], + [lt_cv_irix_exported_symbol=yes], + [lt_cv_irix_exported_symbol=no]) + LDFLAGS="$save_LDFLAGS"]) + if test "$lt_cv_irix_exported_symbol" = yes; then + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations ${wl}-exports_file ${wl}$export_symbols -o $lib' + fi + else + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -exports_file $export_symbols -o $lib' + fi + _LT_TAGVAR(archive_cmds_need_lc, $1)='no' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + _LT_TAGVAR(inherit_rpath, $1)=yes + _LT_TAGVAR(link_all_deplibs, $1)=yes + ;; + + netbsd* | netbsdelf*-gnu) + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out + else + _LT_TAGVAR(archive_cmds, $1)='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF + fi + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + newsos6) + _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + *nto* | *qnx*) + ;; + + openbsd*) + if test -f /usr/libexec/ld.so; then + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_TAGVAR(hardcode_direct_absolute, $1)=yes + if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-retain-symbols-file,$export_symbols' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + else + case $host_os in + openbsd[[01]].* | openbsd2.[[0-7]] | openbsd2.[[0-7]].*) + _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + ;; + *) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' + ;; + esac + fi + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + os2*) + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_minus_L, $1)=yes + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + _LT_TAGVAR(archive_cmds, $1)='$ECHO "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~echo DATA >> $output_objdir/$libname.def~echo " SINGLE NONSHARED" >> $output_objdir/$libname.def~echo EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def' + _LT_TAGVAR(old_archive_from_new_cmds, $1)='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def' + ;; + + osf3*) + if test "$GCC" = yes; then + _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + else + _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' + fi + _LT_TAGVAR(archive_cmds_need_lc, $1)='no' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + ;; + + osf4* | osf5*) # as osf3* with the addition of -msym flag + if test "$GCC" = yes; then + _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $pic_flag $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + else + _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; printf "%s\\n" "-hidden">> $lib.exp~ + $CC -shared${allow_undefined_flag} ${wl}-input ${wl}$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib~$RM $lib.exp' + + # Both c and cxx compiler support -rpath directly + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' + fi + _LT_TAGVAR(archive_cmds_need_lc, $1)='no' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + ;; + + solaris*) + _LT_TAGVAR(no_undefined_flag, $1)=' -z defs' + if test "$GCC" = yes; then + wlarc='${wl}' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag ${wl}-z ${wl}text ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -shared $pic_flag ${wl}-z ${wl}text ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' + else + case `$CC -V 2>&1` in + *"Compilers 5.0"*) + wlarc='' + _LT_TAGVAR(archive_cmds, $1)='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp' + ;; + *) + wlarc='${wl}' + _LT_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' + ;; + esac + fi + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + case $host_os in + solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; + *) + # The compiler driver will combine and reorder linker options, + # but understands `-z linker_flag'. GCC discards it without `$wl', + # but is careful enough not to reorder. + # Supported since Solaris 2.6 (maybe 2.5.1?) + if test "$GCC" = yes; then + _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract' + else + _LT_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract' + fi + ;; + esac + _LT_TAGVAR(link_all_deplibs, $1)=yes + ;; + + sunos4*) + if test "x$host_vendor" = xsequent; then + # Use $CC to link under sequent, because it throws in some extra .o + # files that make .init and .fini sections work. + _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags' + else + _LT_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags' + fi + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_minus_L, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + sysv4) + case $host_vendor in + sni) + _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_direct, $1)=yes # is this really true??? + ;; + siemens) + ## LD is ld it makes a PLAMLIB + ## CC just makes a GrossModule. + _LT_TAGVAR(archive_cmds, $1)='$LD -G -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(reload_cmds, $1)='$CC -r -o $output$reload_objs' + _LT_TAGVAR(hardcode_direct, $1)=no + ;; + motorola) + _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_direct, $1)=no #Motorola manual says yes, but my tests say they lie + ;; + esac + runpath_var='LD_RUN_PATH' + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + sysv4.3*) + _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_TAGVAR(export_dynamic_flag_spec, $1)='-Bexport' + ;; + + sysv4*MP*) + if test -d /usr/nec; then + _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + runpath_var=LD_RUN_PATH + hardcode_runpath_var=yes + _LT_TAGVAR(ld_shlibs, $1)=yes + fi + ;; + + sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*) + _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text' + _LT_TAGVAR(archive_cmds_need_lc, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + runpath_var='LD_RUN_PATH' + + if test "$GCC" = yes; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + else + _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + fi + ;; + + sysv5* | sco3.2v5* | sco5v6*) + # Note: We can NOT use -z defs as we might desire, because we do not + # link with -lc, and that would cause any symbols used from libc to + # always be unresolved, which means just about no library would + # ever link correctly. If we're not using GNU ld we use -z text + # though, which does catch some bad symbols but isn't as heavy-handed + # as -z defs. + _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text' + _LT_TAGVAR(allow_undefined_flag, $1)='${wl}-z,nodefs' + _LT_TAGVAR(archive_cmds_need_lc, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R,$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=':' + _LT_TAGVAR(link_all_deplibs, $1)=yes + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Bexport' + runpath_var='LD_RUN_PATH' + + if test "$GCC" = yes; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + else + _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + fi + ;; + + uts4*) + _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + *) + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + esac + + if test x$host_vendor = xsni; then + case $host in + sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Blargedynsym' + ;; + esac + fi + fi +]) +AC_MSG_RESULT([$_LT_TAGVAR(ld_shlibs, $1)]) +test "$_LT_TAGVAR(ld_shlibs, $1)" = no && can_build_shared=no + +_LT_TAGVAR(with_gnu_ld, $1)=$with_gnu_ld + +_LT_DECL([], [libext], [0], [Old archive suffix (normally "a")])dnl +_LT_DECL([], [shrext_cmds], [1], [Shared library suffix (normally ".so")])dnl +_LT_DECL([], [extract_expsyms_cmds], [2], + [The commands to extract the exported symbol list from a shared archive]) + +# +# Do we need to explicitly link libc? +# +case "x$_LT_TAGVAR(archive_cmds_need_lc, $1)" in +x|xyes) + # Assume -lc should be added + _LT_TAGVAR(archive_cmds_need_lc, $1)=yes + + if test "$enable_shared" = yes && test "$GCC" = yes; then + case $_LT_TAGVAR(archive_cmds, $1) in + *'~'*) + # FIXME: we may have to deal with multi-command sequences. + ;; + '$CC '*) + # Test whether the compiler implicitly links with -lc since on some + # systems, -lgcc has to come before -lc. If gcc already passes -lc + # to ld, don't add -lc before -lgcc. + AC_CACHE_CHECK([whether -lc should be explicitly linked in], + [lt_cv_]_LT_TAGVAR(archive_cmds_need_lc, $1), + [$RM conftest* + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + if AC_TRY_EVAL(ac_compile) 2>conftest.err; then + soname=conftest + lib=conftest + libobjs=conftest.$ac_objext + deplibs= + wl=$_LT_TAGVAR(lt_prog_compiler_wl, $1) + pic_flag=$_LT_TAGVAR(lt_prog_compiler_pic, $1) + compiler_flags=-v + linker_flags=-v + verstring= + output_objdir=. + libname=conftest + lt_save_allow_undefined_flag=$_LT_TAGVAR(allow_undefined_flag, $1) + _LT_TAGVAR(allow_undefined_flag, $1)= + if AC_TRY_EVAL(_LT_TAGVAR(archive_cmds, $1) 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) + then + lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1)=no + else + lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1)=yes + fi + _LT_TAGVAR(allow_undefined_flag, $1)=$lt_save_allow_undefined_flag + else + cat conftest.err 1>&5 + fi + $RM conftest* + ]) + _LT_TAGVAR(archive_cmds_need_lc, $1)=$lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1) + ;; + esac + fi + ;; +esac + +_LT_TAGDECL([build_libtool_need_lc], [archive_cmds_need_lc], [0], + [Whether or not to add -lc for building shared libraries]) +_LT_TAGDECL([allow_libtool_libs_with_static_runtimes], + [enable_shared_with_static_runtimes], [0], + [Whether or not to disallow shared libs when runtime libs are static]) +_LT_TAGDECL([], [export_dynamic_flag_spec], [1], + [Compiler flag to allow reflexive dlopens]) +_LT_TAGDECL([], [whole_archive_flag_spec], [1], + [Compiler flag to generate shared objects directly from archives]) +_LT_TAGDECL([], [compiler_needs_object], [1], + [Whether the compiler copes with passing no objects directly]) +_LT_TAGDECL([], [old_archive_from_new_cmds], [2], + [Create an old-style archive from a shared archive]) +_LT_TAGDECL([], [old_archive_from_expsyms_cmds], [2], + [Create a temporary old-style archive to link instead of a shared archive]) +_LT_TAGDECL([], [archive_cmds], [2], [Commands used to build a shared archive]) +_LT_TAGDECL([], [archive_expsym_cmds], [2]) +_LT_TAGDECL([], [module_cmds], [2], + [Commands used to build a loadable module if different from building + a shared archive.]) +_LT_TAGDECL([], [module_expsym_cmds], [2]) +_LT_TAGDECL([], [with_gnu_ld], [1], + [Whether we are building with GNU ld or not]) +_LT_TAGDECL([], [allow_undefined_flag], [1], + [Flag that allows shared libraries with undefined symbols to be built]) +_LT_TAGDECL([], [no_undefined_flag], [1], + [Flag that enforces no undefined symbols]) +_LT_TAGDECL([], [hardcode_libdir_flag_spec], [1], + [Flag to hardcode $libdir into a binary during linking. + This must work even if $libdir does not exist]) +_LT_TAGDECL([], [hardcode_libdir_separator], [1], + [Whether we need a single "-rpath" flag with a separated argument]) +_LT_TAGDECL([], [hardcode_direct], [0], + [Set to "yes" if using DIR/libNAME${shared_ext} during linking hardcodes + DIR into the resulting binary]) +_LT_TAGDECL([], [hardcode_direct_absolute], [0], + [Set to "yes" if using DIR/libNAME${shared_ext} during linking hardcodes + DIR into the resulting binary and the resulting library dependency is + "absolute", i.e impossible to change by setting ${shlibpath_var} if the + library is relocated]) +_LT_TAGDECL([], [hardcode_minus_L], [0], + [Set to "yes" if using the -LDIR flag during linking hardcodes DIR + into the resulting binary]) +_LT_TAGDECL([], [hardcode_shlibpath_var], [0], + [Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR + into the resulting binary]) +_LT_TAGDECL([], [hardcode_automatic], [0], + [Set to "yes" if building a shared library automatically hardcodes DIR + into the library and all subsequent libraries and executables linked + against it]) +_LT_TAGDECL([], [inherit_rpath], [0], + [Set to yes if linker adds runtime paths of dependent libraries + to runtime path list]) +_LT_TAGDECL([], [link_all_deplibs], [0], + [Whether libtool must link a program against all its dependency libraries]) +_LT_TAGDECL([], [always_export_symbols], [0], + [Set to "yes" if exported symbols are required]) +_LT_TAGDECL([], [export_symbols_cmds], [2], + [The commands to list exported symbols]) +_LT_TAGDECL([], [exclude_expsyms], [1], + [Symbols that should not be listed in the preloaded symbols]) +_LT_TAGDECL([], [include_expsyms], [1], + [Symbols that must always be exported]) +_LT_TAGDECL([], [prelink_cmds], [2], + [Commands necessary for linking programs (against libraries) with templates]) +_LT_TAGDECL([], [postlink_cmds], [2], + [Commands necessary for finishing linking programs]) +_LT_TAGDECL([], [file_list_spec], [1], + [Specify filename containing input files]) +dnl FIXME: Not yet implemented +dnl _LT_TAGDECL([], [thread_safe_flag_spec], [1], +dnl [Compiler flag to generate thread safe objects]) +])# _LT_LINKER_SHLIBS + + +# _LT_LANG_C_CONFIG([TAG]) +# ------------------------ +# Ensure that the configuration variables for a C compiler are suitably +# defined. These variables are subsequently used by _LT_CONFIG to write +# the compiler configuration to `libtool'. +m4_defun([_LT_LANG_C_CONFIG], +[m4_require([_LT_DECL_EGREP])dnl +lt_save_CC="$CC" +AC_LANG_PUSH(C) + +# Source file extension for C test sources. +ac_ext=c + +# Object file extension for compiled C test sources. +objext=o +_LT_TAGVAR(objext, $1)=$objext + +# Code to be used in simple compile tests +lt_simple_compile_test_code="int some_variable = 0;" + +# Code to be used in simple link tests +lt_simple_link_test_code='int main(){return(0);}' + +_LT_TAG_COMPILER +# Save the default compiler, since it gets overwritten when the other +# tags are being tested, and _LT_TAGVAR(compiler, []) is a NOP. +compiler_DEFAULT=$CC + +# save warnings/boilerplate of simple test code +_LT_COMPILER_BOILERPLATE +_LT_LINKER_BOILERPLATE + +if test -n "$compiler"; then + _LT_COMPILER_NO_RTTI($1) + _LT_COMPILER_PIC($1) + _LT_COMPILER_C_O($1) + _LT_COMPILER_FILE_LOCKS($1) + _LT_LINKER_SHLIBS($1) + _LT_SYS_DYNAMIC_LINKER($1) + _LT_LINKER_HARDCODE_LIBPATH($1) + LT_SYS_DLOPEN_SELF + _LT_CMD_STRIPLIB + + # Report which library types will actually be built + AC_MSG_CHECKING([if libtool supports shared libraries]) + AC_MSG_RESULT([$can_build_shared]) + + AC_MSG_CHECKING([whether to build shared libraries]) + test "$can_build_shared" = "no" && enable_shared=no + + # On AIX, shared libraries and static libraries use the same namespace, and + # are all built from PIC. + case $host_os in + aix3*) + test "$enable_shared" = yes && enable_static=no + if test -n "$RANLIB"; then + archive_cmds="$archive_cmds~\$RANLIB \$lib" + postinstall_cmds='$RANLIB $lib' + fi + ;; + + aix[[4-9]]*) + if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then + test "$enable_shared" = yes && enable_static=no + fi + ;; + esac + AC_MSG_RESULT([$enable_shared]) + + AC_MSG_CHECKING([whether to build static libraries]) + # Make sure either enable_shared or enable_static is yes. + test "$enable_shared" = yes || enable_static=yes + AC_MSG_RESULT([$enable_static]) + + _LT_CONFIG($1) +fi +AC_LANG_POP +CC="$lt_save_CC" +])# _LT_LANG_C_CONFIG + + +# _LT_LANG_CXX_CONFIG([TAG]) +# -------------------------- +# Ensure that the configuration variables for a C++ compiler are suitably +# defined. These variables are subsequently used by _LT_CONFIG to write +# the compiler configuration to `libtool'. +m4_defun([_LT_LANG_CXX_CONFIG], +[m4_require([_LT_FILEUTILS_DEFAULTS])dnl +m4_require([_LT_DECL_EGREP])dnl +m4_require([_LT_PATH_MANIFEST_TOOL])dnl +if test -n "$CXX" && ( test "X$CXX" != "Xno" && + ( (test "X$CXX" = "Xg++" && `g++ -v >/dev/null 2>&1` ) || + (test "X$CXX" != "Xg++"))) ; then + AC_PROG_CXXCPP +else + _lt_caught_CXX_error=yes +fi + +AC_LANG_PUSH(C++) +_LT_TAGVAR(archive_cmds_need_lc, $1)=no +_LT_TAGVAR(allow_undefined_flag, $1)= +_LT_TAGVAR(always_export_symbols, $1)=no +_LT_TAGVAR(archive_expsym_cmds, $1)= +_LT_TAGVAR(compiler_needs_object, $1)=no +_LT_TAGVAR(export_dynamic_flag_spec, $1)= +_LT_TAGVAR(hardcode_direct, $1)=no +_LT_TAGVAR(hardcode_direct_absolute, $1)=no +_LT_TAGVAR(hardcode_libdir_flag_spec, $1)= +_LT_TAGVAR(hardcode_libdir_separator, $1)= +_LT_TAGVAR(hardcode_minus_L, $1)=no +_LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported +_LT_TAGVAR(hardcode_automatic, $1)=no +_LT_TAGVAR(inherit_rpath, $1)=no +_LT_TAGVAR(module_cmds, $1)= +_LT_TAGVAR(module_expsym_cmds, $1)= +_LT_TAGVAR(link_all_deplibs, $1)=unknown +_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds +_LT_TAGVAR(reload_flag, $1)=$reload_flag +_LT_TAGVAR(reload_cmds, $1)=$reload_cmds +_LT_TAGVAR(no_undefined_flag, $1)= +_LT_TAGVAR(whole_archive_flag_spec, $1)= +_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no + +# Source file extension for C++ test sources. +ac_ext=cpp + +# Object file extension for compiled C++ test sources. +objext=o +_LT_TAGVAR(objext, $1)=$objext + +# No sense in running all these tests if we already determined that +# the CXX compiler isn't working. Some variables (like enable_shared) +# are currently assumed to apply to all compilers on this platform, +# and will be corrupted by setting them based on a non-working compiler. +if test "$_lt_caught_CXX_error" != yes; then + # Code to be used in simple compile tests + lt_simple_compile_test_code="int some_variable = 0;" + + # Code to be used in simple link tests + lt_simple_link_test_code='int main(int, char *[[]]) { return(0); }' + + # ltmain only uses $CC for tagged configurations so make sure $CC is set. + _LT_TAG_COMPILER + + # save warnings/boilerplate of simple test code + _LT_COMPILER_BOILERPLATE + _LT_LINKER_BOILERPLATE + + # Allow CC to be a program name with arguments. + lt_save_CC=$CC + lt_save_CFLAGS=$CFLAGS + lt_save_LD=$LD + lt_save_GCC=$GCC + GCC=$GXX + lt_save_with_gnu_ld=$with_gnu_ld + lt_save_path_LD=$lt_cv_path_LD + if test -n "${lt_cv_prog_gnu_ldcxx+set}"; then + lt_cv_prog_gnu_ld=$lt_cv_prog_gnu_ldcxx + else + $as_unset lt_cv_prog_gnu_ld + fi + if test -n "${lt_cv_path_LDCXX+set}"; then + lt_cv_path_LD=$lt_cv_path_LDCXX + else + $as_unset lt_cv_path_LD + fi + test -z "${LDCXX+set}" || LD=$LDCXX + CC=${CXX-"c++"} + CFLAGS=$CXXFLAGS + compiler=$CC + _LT_TAGVAR(compiler, $1)=$CC + _LT_CC_BASENAME([$compiler]) + + if test -n "$compiler"; then + # We don't want -fno-exception when compiling C++ code, so set the + # no_builtin_flag separately + if test "$GXX" = yes; then + _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin' + else + _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)= + fi + + if test "$GXX" = yes; then + # Set up default GNU C++ configuration + + LT_PATH_LD + + # Check if GNU C++ uses GNU ld as the underlying linker, since the + # archiving commands below assume that GNU ld is being used. + if test "$with_gnu_ld" = yes; then + _LT_TAGVAR(archive_cmds, $1)='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' + + # If archive_cmds runs LD, not CC, wlarc should be empty + # XXX I think wlarc can be eliminated in ltcf-cxx, but I need to + # investigate it a little bit more. (MM) + wlarc='${wl}' + + # ancient GNU ld didn't support --whole-archive et. al. + if eval "`$CC -print-prog-name=ld` --help 2>&1" | + $GREP 'no-whole-archive' > /dev/null; then + _LT_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' + else + _LT_TAGVAR(whole_archive_flag_spec, $1)= + fi + else + with_gnu_ld=no + wlarc= + + # A generic and very simple default shared library creation + # command for GNU C++ for the case where it uses the native + # linker, instead of GNU ld. If possible, this setting should + # overridden to take advantage of the native linker features on + # the platform it is being used on. + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' + fi + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' + + else + GXX=no + with_gnu_ld=no + wlarc= + fi + + # PORTME: fill in a description of your system's C++ link characteristics + AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries]) + _LT_TAGVAR(ld_shlibs, $1)=yes + case $host_os in + aix3*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + aix[[4-9]]*) + if test "$host_cpu" = ia64; then + # On IA64, the linker does run time linking by default, so we don't + # have to do anything special. + aix_use_runtimelinking=no + exp_sym_flag='-Bexport' + no_entry_flag="" + else + aix_use_runtimelinking=no + + # Test if we are trying to use run time linking or normal + # AIX style linking. If -brtl is somewhere in LDFLAGS, we + # need to do runtime linking. + case $host_os in aix4.[[23]]|aix4.[[23]].*|aix[[5-9]]*) + for ld_flag in $LDFLAGS; do + case $ld_flag in + *-brtl*) + aix_use_runtimelinking=yes + break + ;; + esac + done + ;; + esac + + exp_sym_flag='-bexport' + no_entry_flag='-bnoentry' + fi + + # When large executables or shared objects are built, AIX ld can + # have problems creating the table of contents. If linking a library + # or program results in "error TOC overflow" add -mminimal-toc to + # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not + # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. + + _LT_TAGVAR(archive_cmds, $1)='' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_direct_absolute, $1)=yes + _LT_TAGVAR(hardcode_libdir_separator, $1)=':' + _LT_TAGVAR(link_all_deplibs, $1)=yes + _LT_TAGVAR(file_list_spec, $1)='${wl}-f,' + + if test "$GXX" = yes; then + case $host_os in aix4.[[012]]|aix4.[[012]].*) + # We only want to do this on AIX 4.2 and lower, the check + # below for broken collect2 doesn't work under 4.3+ + collect2name=`${CC} -print-prog-name=collect2` + if test -f "$collect2name" && + strings "$collect2name" | $GREP resolve_lib_name >/dev/null + then + # We have reworked collect2 + : + else + # We have old collect2 + _LT_TAGVAR(hardcode_direct, $1)=unsupported + # It fails to find uninstalled libraries when the uninstalled + # path is not listed in the libpath. Setting hardcode_minus_L + # to unsupported forces relinking + _LT_TAGVAR(hardcode_minus_L, $1)=yes + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)= + fi + esac + shared_flag='-shared' + if test "$aix_use_runtimelinking" = yes; then + shared_flag="$shared_flag "'${wl}-G' + fi + else + # not using gcc + if test "$host_cpu" = ia64; then + # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release + # chokes on -Wl,-G. The following line is correct: + shared_flag='-G' + else + if test "$aix_use_runtimelinking" = yes; then + shared_flag='${wl}-G' + else + shared_flag='${wl}-bM:SRE' + fi + fi + fi + + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-bexpall' + # It seems that -bexpall does not export symbols beginning with + # underscore (_), so it is better to generate a list of symbols to + # export. + _LT_TAGVAR(always_export_symbols, $1)=yes + if test "$aix_use_runtimelinking" = yes; then + # Warning - without using the other runtime loading flags (-brtl), + # -berok will link without error, but may produce a broken library. + _LT_TAGVAR(allow_undefined_flag, $1)='-berok' + # Determine the default libpath from the value encoded in an empty + # executable. + _LT_SYS_MODULE_PATH_AIX([$1]) + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" + + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then func_echo_all "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" + else + if test "$host_cpu" = ia64; then + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $libdir:/usr/lib:/lib' + _LT_TAGVAR(allow_undefined_flag, $1)="-z nodefs" + _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols" + else + # Determine the default libpath from the value encoded in an + # empty executable. + _LT_SYS_MODULE_PATH_AIX([$1]) + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" + # Warning - without using the other run time loading flags, + # -berok will link without error, but may produce a broken library. + _LT_TAGVAR(no_undefined_flag, $1)=' ${wl}-bernotok' + _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-berok' + if test "$with_gnu_ld" = yes; then + # We only use this code for GNU lds that support --whole-archive. + _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive$convenience ${wl}--no-whole-archive' + else + # Exported symbols can be pulled into shared objects from archives + _LT_TAGVAR(whole_archive_flag_spec, $1)='$convenience' + fi + _LT_TAGVAR(archive_cmds_need_lc, $1)=yes + # This is similar to how AIX traditionally builds its shared + # libraries. + _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' + fi + fi + ;; + + beos*) + if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + # Joseph Beckenbach says some releases of gcc + # support --undefined. This deserves some investigation. FIXME + _LT_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + chorus*) + case $cc_basename in + *) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + esac + ;; + + cygwin* | mingw* | pw32* | cegcc*) + case $GXX,$cc_basename in + ,cl* | no,cl*) + # Native MSVC + # hardcode_libdir_flag_spec is actually meaningless, as there is + # no search path for DLLs. + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' ' + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + _LT_TAGVAR(always_export_symbols, $1)=yes + _LT_TAGVAR(file_list_spec, $1)='@' + # Tell ltmain to make .lib files, not .a files. + libext=lib + # Tell ltmain to make .dll files, not .so files. + shrext_cmds=".dll" + # FIXME: Setting linknames here is a bad hack. + _LT_TAGVAR(archive_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-dll~linknames=' + _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then + $SED -n -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' -e '1\\\!p' < $export_symbols > $output_objdir/$soname.exp; + else + $SED -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' < $export_symbols > $output_objdir/$soname.exp; + fi~ + $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ + linknames=' + # The linker will not automatically build a static lib if we build a DLL. + # _LT_TAGVAR(old_archive_from_new_cmds, $1)='true' + _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes + # Don't use ranlib + _LT_TAGVAR(old_postinstall_cmds, $1)='chmod 644 $oldlib' + _LT_TAGVAR(postlink_cmds, $1)='lt_outputfile="@OUTPUT@"~ + lt_tool_outputfile="@TOOL_OUTPUT@"~ + case $lt_outputfile in + *.exe|*.EXE) ;; + *) + lt_outputfile="$lt_outputfile.exe" + lt_tool_outputfile="$lt_tool_outputfile.exe" + ;; + esac~ + func_to_tool_file "$lt_outputfile"~ + if test "$MANIFEST_TOOL" != ":" && test -f "$lt_outputfile.manifest"; then + $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1; + $RM "$lt_outputfile.manifest"; + fi' + ;; + *) + # g++ + # _LT_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless, + # as there is no search path for DLLs. + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-all-symbols' + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + _LT_TAGVAR(always_export_symbols, $1)=no + _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes + + if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + # If the export-symbols file already is a .def file (1st line + # is EXPORTS), use it as is; otherwise, prepend... + _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then + cp $export_symbols $output_objdir/$soname.def; + else + echo EXPORTS > $output_objdir/$soname.def; + cat $export_symbols >> $output_objdir/$soname.def; + fi~ + $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + esac + ;; + darwin* | rhapsody*) + _LT_DARWIN_LINKER_FEATURES($1) + ;; + + dgux*) + case $cc_basename in + ec++*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + ghcx*) + # Green Hills C++ Compiler + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + *) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + esac + ;; + + freebsd2.*) + # C++ shared libraries reported to be fairly broken before + # switch to ELF + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + + freebsd-elf*) + _LT_TAGVAR(archive_cmds_need_lc, $1)=no + ;; + + freebsd* | dragonfly*) + # FreeBSD 3 and later use GNU C++ and GNU ld with standard ELF + # conventions + _LT_TAGVAR(ld_shlibs, $1)=yes + ;; + + gnu*) + ;; + + haiku*) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_TAGVAR(link_all_deplibs, $1)=yes + ;; + + hpux9*) + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH, + # but as the default + # location of the library. + + case $cc_basename in + CC*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + aCC*) + _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -b ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' + ;; + *) + if test "$GXX" = yes; then + _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared -nostdlib $pic_flag ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + else + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + esac + ;; + + hpux10*|hpux11*) + if test $with_gnu_ld = no; then + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + + case $host_cpu in + hppa*64*|ia64*) + ;; + *) + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + ;; + esac + fi + case $host_cpu in + hppa*64*|ia64*) + _LT_TAGVAR(hardcode_direct, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + *) + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_direct_absolute, $1)=yes + _LT_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH, + # but as the default + # location of the library. + ;; + esac + + case $cc_basename in + CC*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + aCC*) + case $host_cpu in + hppa*64*) + _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + ia64*) + _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + *) + _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + esac + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' + ;; + *) + if test "$GXX" = yes; then + if test $with_gnu_ld = no; then + case $host_cpu in + hppa*64*) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + ia64*) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $pic_flag ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + *) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + esac + fi + else + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + esac + ;; + + interix[[3-9]]*) + _LT_TAGVAR(hardcode_direct, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. + # Instead, shared libraries are loaded at an image base (0x10000000 by + # default) and relocated if they conflict, which is a slow very memory + # consuming and fragmenting process. To avoid this, we pick a random, + # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link + # time. Moving up from 0x10000000 also allows more sbrk(2) space. + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + ;; + irix5* | irix6*) + case $cc_basename in + CC*) + # SGI C++ + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -all -multigot $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' + + # Archives containing C++ object files must be created using + # "CC -ar", where "CC" is the IRIX C++ compiler. This is + # necessary to make sure instantiated templates are included + # in the archive. + _LT_TAGVAR(old_archive_cmds, $1)='$CC -ar -WR,-u -o $oldlib $oldobjs' + ;; + *) + if test "$GXX" = yes; then + if test "$with_gnu_ld" = no; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + else + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` -o $lib' + fi + fi + _LT_TAGVAR(link_all_deplibs, $1)=yes + ;; + esac + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + _LT_TAGVAR(inherit_rpath, $1)=yes + ;; + + linux* | k*bsd*-gnu | kopensolaris*-gnu) + case $cc_basename in + KCC*) + # Kuck and Associates, Inc. (KAI) C++ Compiler + + # KCC will only create a shared library if the output file + # ends with ".so" (or ".sl" for HP-UX), so rename the library + # to its proper name (with version) after linking. + _LT_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib ${wl}-retain-symbols-file,$export_symbols; mv \$templib $lib' + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`$CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 | $GREP "ld"`; rm -f libconftest$shared_ext; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' + + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' + + # Archives containing C++ object files must be created using + # "CC -Bstatic", where "CC" is the KAI C++ compiler. + _LT_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs' + ;; + icpc* | ecpc* ) + # Intel C++ + with_gnu_ld=yes + # version 8.0 and above of icpc choke on multiply defined symbols + # if we add $predep_objects and $postdep_objects, however 7.1 and + # earlier do not add the objects themselves. + case `$CC -V 2>&1` in + *"Version 7."*) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + ;; + *) # Version 8.0 or newer + tmp_idyn= + case $host_cpu in + ia64*) tmp_idyn=' -i_dynamic';; + esac + _LT_TAGVAR(archive_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + ;; + esac + _LT_TAGVAR(archive_cmds_need_lc, $1)=no + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' + _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive$convenience ${wl}--no-whole-archive' + ;; + pgCC* | pgcpp*) + # Portland Group C++ compiler + case `$CC -V` in + *pgCC\ [[1-5]].* | *pgcpp\ [[1-5]].*) + _LT_TAGVAR(prelink_cmds, $1)='tpldir=Template.dir~ + rm -rf $tpldir~ + $CC --prelink_objects --instantiation_dir $tpldir $objs $libobjs $compile_deplibs~ + compile_command="$compile_command `find $tpldir -name \*.o | sort | $NL2SP`"' + _LT_TAGVAR(old_archive_cmds, $1)='tpldir=Template.dir~ + rm -rf $tpldir~ + $CC --prelink_objects --instantiation_dir $tpldir $oldobjs$old_deplibs~ + $AR $AR_FLAGS $oldlib$oldobjs$old_deplibs `find $tpldir -name \*.o | sort | $NL2SP`~ + $RANLIB $oldlib' + _LT_TAGVAR(archive_cmds, $1)='tpldir=Template.dir~ + rm -rf $tpldir~ + $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~ + $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='tpldir=Template.dir~ + rm -rf $tpldir~ + $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~ + $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib' + ;; + *) # Version 6 and above use weak symbols + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib' + ;; + esac + + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}--rpath ${wl}$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' + _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' + ;; + cxx*) + # Compaq C++ + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib ${wl}-retain-symbols-file $wl$export_symbols' + + runpath_var=LD_RUN_PATH + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld .*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "X$list" | $Xsed' + ;; + xl* | mpixl* | bgxl*) + # IBM XL 8.0 on PPC, with GNU ld + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' + _LT_TAGVAR(archive_cmds, $1)='$CC -qmkshrobj $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + if test "x$supports_anon_versioning" = xyes; then + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~ + cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ + echo "local: *; };" >> $output_objdir/$libname.ver~ + $CC -qmkshrobj $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' + fi + ;; + *) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) + # Sun C++ 5.9 + _LT_TAGVAR(no_undefined_flag, $1)=' -zdefs' + _LT_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file ${wl}$export_symbols' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' + _LT_TAGVAR(compiler_needs_object, $1)=yes + + # Not sure whether something based on + # $CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 + # would be better. + output_verbose_link_cmd='func_echo_all' + + # Archives containing C++ object files must be created using + # "CC -xar", where "CC" is the Sun C++ compiler. This is + # necessary to make sure instantiated templates are included + # in the archive. + _LT_TAGVAR(old_archive_cmds, $1)='$CC -xar -o $oldlib $oldobjs' + ;; + esac + ;; + esac + ;; + + lynxos*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + + m88k*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + + mvs*) + case $cc_basename in + cxx*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + *) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + esac + ;; + + netbsd*) + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $predep_objects $libobjs $deplibs $postdep_objects $linker_flags' + wlarc= + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + fi + # Workaround some broken pre-1.5 toolchains + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP conftest.$objext | $SED -e "s:-lgcc -lc -lgcc::"' + ;; + + *nto* | *qnx*) + _LT_TAGVAR(ld_shlibs, $1)=yes + ;; + + openbsd2*) + # C++ shared libraries are fairly broken + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + + openbsd*) + if test -f /usr/libexec/ld.so; then + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_TAGVAR(hardcode_direct_absolute, $1)=yes + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' + if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file,$export_symbols -o $lib' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + _LT_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' + fi + output_verbose_link_cmd=func_echo_all + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + osf3* | osf4* | osf5*) + case $cc_basename in + KCC*) + # Kuck and Associates, Inc. (KAI) C++ Compiler + + # KCC will only create a shared library if the output file + # ends with ".so" (or ".sl" for HP-UX), so rename the library + # to its proper name (with version) after linking. + _LT_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo "$lib" | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' + + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + + # Archives containing C++ object files must be created using + # the KAI C++ compiler. + case $host in + osf3*) _LT_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs' ;; + *) _LT_TAGVAR(old_archive_cmds, $1)='$CC -o $oldlib $oldobjs' ;; + esac + ;; + RCC*) + # Rational C++ 2.4.1 + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + cxx*) + case $host in + osf3*) + _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $soname `test -n "$verstring" && func_echo_all "${wl}-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + ;; + *) + _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done~ + echo "-hidden">> $lib.exp~ + $CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname ${wl}-input ${wl}$lib.exp `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib~ + $RM $lib.exp' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' + ;; + esac + + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld" | $GREP -v "ld:"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' + ;; + *) + if test "$GXX" = yes && test "$with_gnu_ld" = no; then + _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' + case $host in + osf3*) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + ;; + *) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + ;; + esac + + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' + + else + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + esac + ;; + + psos*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + + sunos4*) + case $cc_basename in + CC*) + # Sun C++ 4.x + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + lcc*) + # Lucid + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + *) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + esac + ;; + + solaris*) + case $cc_basename in + CC* | sunCC*) + # Sun C++ 4.2, 5.x and Centerline C++ + _LT_TAGVAR(archive_cmds_need_lc,$1)=yes + _LT_TAGVAR(no_undefined_flag, $1)=' -zdefs' + _LT_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -G${allow_undefined_flag} ${wl}-M ${wl}$lib.exp -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' + + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + case $host_os in + solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; + *) + # The compiler driver will combine and reorder linker options, + # but understands `-z linker_flag'. + # Supported since Solaris 2.6 (maybe 2.5.1?) + _LT_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract' + ;; + esac + _LT_TAGVAR(link_all_deplibs, $1)=yes + + output_verbose_link_cmd='func_echo_all' + + # Archives containing C++ object files must be created using + # "CC -xar", where "CC" is the Sun C++ compiler. This is + # necessary to make sure instantiated templates are included + # in the archive. + _LT_TAGVAR(old_archive_cmds, $1)='$CC -xar -o $oldlib $oldobjs' + ;; + gcx*) + # Green Hills C++ Compiler + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' + + # The C++ compiler must be used to create the archive. + _LT_TAGVAR(old_archive_cmds, $1)='$CC $LDFLAGS -archive -o $oldlib $oldobjs' + ;; + *) + # GNU C++ compiler with Solaris linker + if test "$GXX" = yes && test "$with_gnu_ld" = no; then + _LT_TAGVAR(no_undefined_flag, $1)=' ${wl}-z ${wl}defs' + if $CC --version | $GREP -v '^2\.7' > /dev/null; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -shared $pic_flag -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' + else + # g++ 2.7 appears to require `-G' NOT `-shared' on this + # platform. + _LT_TAGVAR(archive_cmds, $1)='$CC -G -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -G -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' + fi + + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $wl$libdir' + case $host_os in + solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; + *) + _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract' + ;; + esac + fi + ;; + esac + ;; + + sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*) + _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text' + _LT_TAGVAR(archive_cmds_need_lc, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + runpath_var='LD_RUN_PATH' + + case $cc_basename in + CC*) + _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + ;; + + sysv5* | sco3.2v5* | sco5v6*) + # Note: We can NOT use -z defs as we might desire, because we do not + # link with -lc, and that would cause any symbols used from libc to + # always be unresolved, which means just about no library would + # ever link correctly. If we're not using GNU ld we use -z text + # though, which does catch some bad symbols but isn't as heavy-handed + # as -z defs. + _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text' + _LT_TAGVAR(allow_undefined_flag, $1)='${wl}-z,nodefs' + _LT_TAGVAR(archive_cmds_need_lc, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R,$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=':' + _LT_TAGVAR(link_all_deplibs, $1)=yes + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Bexport' + runpath_var='LD_RUN_PATH' + + case $cc_basename in + CC*) + _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(old_archive_cmds, $1)='$CC -Tprelink_objects $oldobjs~ + '"$_LT_TAGVAR(old_archive_cmds, $1)" + _LT_TAGVAR(reload_cmds, $1)='$CC -Tprelink_objects $reload_objs~ + '"$_LT_TAGVAR(reload_cmds, $1)" + ;; + *) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + ;; + + tandem*) + case $cc_basename in + NCC*) + # NonStop-UX NCC 3.20 + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + *) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + esac + ;; + + vxworks*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + + *) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + esac + + AC_MSG_RESULT([$_LT_TAGVAR(ld_shlibs, $1)]) + test "$_LT_TAGVAR(ld_shlibs, $1)" = no && can_build_shared=no + + _LT_TAGVAR(GCC, $1)="$GXX" + _LT_TAGVAR(LD, $1)="$LD" + + ## CAVEAT EMPTOR: + ## There is no encapsulation within the following macros, do not change + ## the running order or otherwise move them around unless you know exactly + ## what you are doing... + _LT_SYS_HIDDEN_LIBDEPS($1) + _LT_COMPILER_PIC($1) + _LT_COMPILER_C_O($1) + _LT_COMPILER_FILE_LOCKS($1) + _LT_LINKER_SHLIBS($1) + _LT_SYS_DYNAMIC_LINKER($1) + _LT_LINKER_HARDCODE_LIBPATH($1) + + _LT_CONFIG($1) + fi # test -n "$compiler" + + CC=$lt_save_CC + CFLAGS=$lt_save_CFLAGS + LDCXX=$LD + LD=$lt_save_LD + GCC=$lt_save_GCC + with_gnu_ld=$lt_save_with_gnu_ld + lt_cv_path_LDCXX=$lt_cv_path_LD + lt_cv_path_LD=$lt_save_path_LD + lt_cv_prog_gnu_ldcxx=$lt_cv_prog_gnu_ld + lt_cv_prog_gnu_ld=$lt_save_with_gnu_ld +fi # test "$_lt_caught_CXX_error" != yes + +AC_LANG_POP +])# _LT_LANG_CXX_CONFIG + + +# _LT_FUNC_STRIPNAME_CNF +# ---------------------- +# func_stripname_cnf prefix suffix name +# strip PREFIX and SUFFIX off of NAME. +# PREFIX and SUFFIX must not contain globbing or regex special +# characters, hashes, percent signs, but SUFFIX may contain a leading +# dot (in which case that matches only a dot). +# +# This function is identical to the (non-XSI) version of func_stripname, +# except this one can be used by m4 code that may be executed by configure, +# rather than the libtool script. +m4_defun([_LT_FUNC_STRIPNAME_CNF],[dnl +AC_REQUIRE([_LT_DECL_SED]) +AC_REQUIRE([_LT_PROG_ECHO_BACKSLASH]) +func_stripname_cnf () +{ + case ${2} in + .*) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%\\\\${2}\$%%"`;; + *) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%${2}\$%%"`;; + esac +} # func_stripname_cnf +])# _LT_FUNC_STRIPNAME_CNF + +# _LT_SYS_HIDDEN_LIBDEPS([TAGNAME]) +# --------------------------------- +# Figure out "hidden" library dependencies from verbose +# compiler output when linking a shared library. +# Parse the compiler output and extract the necessary +# objects, libraries and library flags. +m4_defun([_LT_SYS_HIDDEN_LIBDEPS], +[m4_require([_LT_FILEUTILS_DEFAULTS])dnl +AC_REQUIRE([_LT_FUNC_STRIPNAME_CNF])dnl +# Dependencies to place before and after the object being linked: +_LT_TAGVAR(predep_objects, $1)= +_LT_TAGVAR(postdep_objects, $1)= +_LT_TAGVAR(predeps, $1)= +_LT_TAGVAR(postdeps, $1)= +_LT_TAGVAR(compiler_lib_search_path, $1)= + +dnl we can't use the lt_simple_compile_test_code here, +dnl because it contains code intended for an executable, +dnl not a library. It's possible we should let each +dnl tag define a new lt_????_link_test_code variable, +dnl but it's only used here... +m4_if([$1], [], [cat > conftest.$ac_ext <<_LT_EOF +int a; +void foo (void) { a = 0; } +_LT_EOF +], [$1], [CXX], [cat > conftest.$ac_ext <<_LT_EOF +class Foo +{ +public: + Foo (void) { a = 0; } +private: + int a; +}; +_LT_EOF +], [$1], [F77], [cat > conftest.$ac_ext <<_LT_EOF + subroutine foo + implicit none + integer*4 a + a=0 + return + end +_LT_EOF +], [$1], [FC], [cat > conftest.$ac_ext <<_LT_EOF + subroutine foo + implicit none + integer a + a=0 + return + end +_LT_EOF +], [$1], [GCJ], [cat > conftest.$ac_ext <<_LT_EOF +public class foo { + private int a; + public void bar (void) { + a = 0; + } +}; +_LT_EOF +], [$1], [GO], [cat > conftest.$ac_ext <<_LT_EOF +package foo +func foo() { +} +_LT_EOF +]) + +_lt_libdeps_save_CFLAGS=$CFLAGS +case "$CC $CFLAGS " in #( +*\ -flto*\ *) CFLAGS="$CFLAGS -fno-lto" ;; +*\ -fwhopr*\ *) CFLAGS="$CFLAGS -fno-whopr" ;; +*\ -fuse-linker-plugin*\ *) CFLAGS="$CFLAGS -fno-use-linker-plugin" ;; +esac + +dnl Parse the compiler output and extract the necessary +dnl objects, libraries and library flags. +if AC_TRY_EVAL(ac_compile); then + # Parse the compiler output and extract the necessary + # objects, libraries and library flags. + + # Sentinel used to keep track of whether or not we are before + # the conftest object file. + pre_test_object_deps_done=no + + for p in `eval "$output_verbose_link_cmd"`; do + case ${prev}${p} in + + -L* | -R* | -l*) + # Some compilers place space between "-{L,R}" and the path. + # Remove the space. + if test $p = "-L" || + test $p = "-R"; then + prev=$p + continue + fi + + # Expand the sysroot to ease extracting the directories later. + if test -z "$prev"; then + case $p in + -L*) func_stripname_cnf '-L' '' "$p"; prev=-L; p=$func_stripname_result ;; + -R*) func_stripname_cnf '-R' '' "$p"; prev=-R; p=$func_stripname_result ;; + -l*) func_stripname_cnf '-l' '' "$p"; prev=-l; p=$func_stripname_result ;; + esac + fi + case $p in + =*) func_stripname_cnf '=' '' "$p"; p=$lt_sysroot$func_stripname_result ;; + esac + if test "$pre_test_object_deps_done" = no; then + case ${prev} in + -L | -R) + # Internal compiler library paths should come after those + # provided the user. The postdeps already come after the + # user supplied libs so there is no need to process them. + if test -z "$_LT_TAGVAR(compiler_lib_search_path, $1)"; then + _LT_TAGVAR(compiler_lib_search_path, $1)="${prev}${p}" + else + _LT_TAGVAR(compiler_lib_search_path, $1)="${_LT_TAGVAR(compiler_lib_search_path, $1)} ${prev}${p}" + fi + ;; + # The "-l" case would never come before the object being + # linked, so don't bother handling this case. + esac + else + if test -z "$_LT_TAGVAR(postdeps, $1)"; then + _LT_TAGVAR(postdeps, $1)="${prev}${p}" + else + _LT_TAGVAR(postdeps, $1)="${_LT_TAGVAR(postdeps, $1)} ${prev}${p}" + fi + fi + prev= + ;; + + *.lto.$objext) ;; # Ignore GCC LTO objects + *.$objext) + # This assumes that the test object file only shows up + # once in the compiler output. + if test "$p" = "conftest.$objext"; then + pre_test_object_deps_done=yes + continue + fi + + if test "$pre_test_object_deps_done" = no; then + if test -z "$_LT_TAGVAR(predep_objects, $1)"; then + _LT_TAGVAR(predep_objects, $1)="$p" + else + _LT_TAGVAR(predep_objects, $1)="$_LT_TAGVAR(predep_objects, $1) $p" + fi + else + if test -z "$_LT_TAGVAR(postdep_objects, $1)"; then + _LT_TAGVAR(postdep_objects, $1)="$p" + else + _LT_TAGVAR(postdep_objects, $1)="$_LT_TAGVAR(postdep_objects, $1) $p" + fi + fi + ;; + + *) ;; # Ignore the rest. + + esac + done + + # Clean up. + rm -f a.out a.exe +else + echo "libtool.m4: error: problem compiling $1 test program" +fi + +$RM -f confest.$objext +CFLAGS=$_lt_libdeps_save_CFLAGS + +# PORTME: override above test on systems where it is broken +m4_if([$1], [CXX], +[case $host_os in +interix[[3-9]]*) + # Interix 3.5 installs completely hosed .la files for C++, so rather than + # hack all around it, let's just trust "g++" to DTRT. + _LT_TAGVAR(predep_objects,$1)= + _LT_TAGVAR(postdep_objects,$1)= + _LT_TAGVAR(postdeps,$1)= + ;; + +linux*) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) + # Sun C++ 5.9 + + # The more standards-conforming stlport4 library is + # incompatible with the Cstd library. Avoid specifying + # it if it's in CXXFLAGS. Ignore libCrun as + # -library=stlport4 depends on it. + case " $CXX $CXXFLAGS " in + *" -library=stlport4 "*) + solaris_use_stlport4=yes + ;; + esac + + if test "$solaris_use_stlport4" != yes; then + _LT_TAGVAR(postdeps,$1)='-library=Cstd -library=Crun' + fi + ;; + esac + ;; + +solaris*) + case $cc_basename in + CC* | sunCC*) + # The more standards-conforming stlport4 library is + # incompatible with the Cstd library. Avoid specifying + # it if it's in CXXFLAGS. Ignore libCrun as + # -library=stlport4 depends on it. + case " $CXX $CXXFLAGS " in + *" -library=stlport4 "*) + solaris_use_stlport4=yes + ;; + esac + + # Adding this requires a known-good setup of shared libraries for + # Sun compiler versions before 5.6, else PIC objects from an old + # archive will be linked into the output, leading to subtle bugs. + if test "$solaris_use_stlport4" != yes; then + _LT_TAGVAR(postdeps,$1)='-library=Cstd -library=Crun' + fi + ;; + esac + ;; +esac +]) + +case " $_LT_TAGVAR(postdeps, $1) " in +*" -lc "*) _LT_TAGVAR(archive_cmds_need_lc, $1)=no ;; +esac + _LT_TAGVAR(compiler_lib_search_dirs, $1)= +if test -n "${_LT_TAGVAR(compiler_lib_search_path, $1)}"; then + _LT_TAGVAR(compiler_lib_search_dirs, $1)=`echo " ${_LT_TAGVAR(compiler_lib_search_path, $1)}" | ${SED} -e 's! -L! !g' -e 's!^ !!'` +fi +_LT_TAGDECL([], [compiler_lib_search_dirs], [1], + [The directories searched by this compiler when creating a shared library]) +_LT_TAGDECL([], [predep_objects], [1], + [Dependencies to place before and after the objects being linked to + create a shared library]) +_LT_TAGDECL([], [postdep_objects], [1]) +_LT_TAGDECL([], [predeps], [1]) +_LT_TAGDECL([], [postdeps], [1]) +_LT_TAGDECL([], [compiler_lib_search_path], [1], + [The library search path used internally by the compiler when linking + a shared library]) +])# _LT_SYS_HIDDEN_LIBDEPS + + +# _LT_LANG_F77_CONFIG([TAG]) +# -------------------------- +# Ensure that the configuration variables for a Fortran 77 compiler are +# suitably defined. These variables are subsequently used by _LT_CONFIG +# to write the compiler configuration to `libtool'. +m4_defun([_LT_LANG_F77_CONFIG], +[AC_LANG_PUSH(Fortran 77) +if test -z "$F77" || test "X$F77" = "Xno"; then + _lt_disable_F77=yes +fi + +_LT_TAGVAR(archive_cmds_need_lc, $1)=no +_LT_TAGVAR(allow_undefined_flag, $1)= +_LT_TAGVAR(always_export_symbols, $1)=no +_LT_TAGVAR(archive_expsym_cmds, $1)= +_LT_TAGVAR(export_dynamic_flag_spec, $1)= +_LT_TAGVAR(hardcode_direct, $1)=no +_LT_TAGVAR(hardcode_direct_absolute, $1)=no +_LT_TAGVAR(hardcode_libdir_flag_spec, $1)= +_LT_TAGVAR(hardcode_libdir_separator, $1)= +_LT_TAGVAR(hardcode_minus_L, $1)=no +_LT_TAGVAR(hardcode_automatic, $1)=no +_LT_TAGVAR(inherit_rpath, $1)=no +_LT_TAGVAR(module_cmds, $1)= +_LT_TAGVAR(module_expsym_cmds, $1)= +_LT_TAGVAR(link_all_deplibs, $1)=unknown +_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds +_LT_TAGVAR(reload_flag, $1)=$reload_flag +_LT_TAGVAR(reload_cmds, $1)=$reload_cmds +_LT_TAGVAR(no_undefined_flag, $1)= +_LT_TAGVAR(whole_archive_flag_spec, $1)= +_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no + +# Source file extension for f77 test sources. +ac_ext=f + +# Object file extension for compiled f77 test sources. +objext=o +_LT_TAGVAR(objext, $1)=$objext + +# No sense in running all these tests if we already determined that +# the F77 compiler isn't working. Some variables (like enable_shared) +# are currently assumed to apply to all compilers on this platform, +# and will be corrupted by setting them based on a non-working compiler. +if test "$_lt_disable_F77" != yes; then + # Code to be used in simple compile tests + lt_simple_compile_test_code="\ + subroutine t + return + end +" + + # Code to be used in simple link tests + lt_simple_link_test_code="\ + program t + end +" + + # ltmain only uses $CC for tagged configurations so make sure $CC is set. + _LT_TAG_COMPILER + + # save warnings/boilerplate of simple test code + _LT_COMPILER_BOILERPLATE + _LT_LINKER_BOILERPLATE + + # Allow CC to be a program name with arguments. + lt_save_CC="$CC" + lt_save_GCC=$GCC + lt_save_CFLAGS=$CFLAGS + CC=${F77-"f77"} + CFLAGS=$FFLAGS + compiler=$CC + _LT_TAGVAR(compiler, $1)=$CC + _LT_CC_BASENAME([$compiler]) + GCC=$G77 + if test -n "$compiler"; then + AC_MSG_CHECKING([if libtool supports shared libraries]) + AC_MSG_RESULT([$can_build_shared]) + + AC_MSG_CHECKING([whether to build shared libraries]) + test "$can_build_shared" = "no" && enable_shared=no + + # On AIX, shared libraries and static libraries use the same namespace, and + # are all built from PIC. + case $host_os in + aix3*) + test "$enable_shared" = yes && enable_static=no + if test -n "$RANLIB"; then + archive_cmds="$archive_cmds~\$RANLIB \$lib" + postinstall_cmds='$RANLIB $lib' + fi + ;; + aix[[4-9]]*) + if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then + test "$enable_shared" = yes && enable_static=no + fi + ;; + esac + AC_MSG_RESULT([$enable_shared]) + + AC_MSG_CHECKING([whether to build static libraries]) + # Make sure either enable_shared or enable_static is yes. + test "$enable_shared" = yes || enable_static=yes + AC_MSG_RESULT([$enable_static]) + + _LT_TAGVAR(GCC, $1)="$G77" + _LT_TAGVAR(LD, $1)="$LD" + + ## CAVEAT EMPTOR: + ## There is no encapsulation within the following macros, do not change + ## the running order or otherwise move them around unless you know exactly + ## what you are doing... + _LT_COMPILER_PIC($1) + _LT_COMPILER_C_O($1) + _LT_COMPILER_FILE_LOCKS($1) + _LT_LINKER_SHLIBS($1) + _LT_SYS_DYNAMIC_LINKER($1) + _LT_LINKER_HARDCODE_LIBPATH($1) + + _LT_CONFIG($1) + fi # test -n "$compiler" + + GCC=$lt_save_GCC + CC="$lt_save_CC" + CFLAGS="$lt_save_CFLAGS" +fi # test "$_lt_disable_F77" != yes + +AC_LANG_POP +])# _LT_LANG_F77_CONFIG + + +# _LT_LANG_FC_CONFIG([TAG]) +# ------------------------- +# Ensure that the configuration variables for a Fortran compiler are +# suitably defined. These variables are subsequently used by _LT_CONFIG +# to write the compiler configuration to `libtool'. +m4_defun([_LT_LANG_FC_CONFIG], +[AC_LANG_PUSH(Fortran) + +if test -z "$FC" || test "X$FC" = "Xno"; then + _lt_disable_FC=yes +fi + +_LT_TAGVAR(archive_cmds_need_lc, $1)=no +_LT_TAGVAR(allow_undefined_flag, $1)= +_LT_TAGVAR(always_export_symbols, $1)=no +_LT_TAGVAR(archive_expsym_cmds, $1)= +_LT_TAGVAR(export_dynamic_flag_spec, $1)= +_LT_TAGVAR(hardcode_direct, $1)=no +_LT_TAGVAR(hardcode_direct_absolute, $1)=no +_LT_TAGVAR(hardcode_libdir_flag_spec, $1)= +_LT_TAGVAR(hardcode_libdir_separator, $1)= +_LT_TAGVAR(hardcode_minus_L, $1)=no +_LT_TAGVAR(hardcode_automatic, $1)=no +_LT_TAGVAR(inherit_rpath, $1)=no +_LT_TAGVAR(module_cmds, $1)= +_LT_TAGVAR(module_expsym_cmds, $1)= +_LT_TAGVAR(link_all_deplibs, $1)=unknown +_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds +_LT_TAGVAR(reload_flag, $1)=$reload_flag +_LT_TAGVAR(reload_cmds, $1)=$reload_cmds +_LT_TAGVAR(no_undefined_flag, $1)= +_LT_TAGVAR(whole_archive_flag_spec, $1)= +_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no + +# Source file extension for fc test sources. +ac_ext=${ac_fc_srcext-f} + +# Object file extension for compiled fc test sources. +objext=o +_LT_TAGVAR(objext, $1)=$objext + +# No sense in running all these tests if we already determined that +# the FC compiler isn't working. Some variables (like enable_shared) +# are currently assumed to apply to all compilers on this platform, +# and will be corrupted by setting them based on a non-working compiler. +if test "$_lt_disable_FC" != yes; then + # Code to be used in simple compile tests + lt_simple_compile_test_code="\ + subroutine t + return + end +" + + # Code to be used in simple link tests + lt_simple_link_test_code="\ + program t + end +" + + # ltmain only uses $CC for tagged configurations so make sure $CC is set. + _LT_TAG_COMPILER + + # save warnings/boilerplate of simple test code + _LT_COMPILER_BOILERPLATE + _LT_LINKER_BOILERPLATE + + # Allow CC to be a program name with arguments. + lt_save_CC="$CC" + lt_save_GCC=$GCC + lt_save_CFLAGS=$CFLAGS + CC=${FC-"f95"} + CFLAGS=$FCFLAGS + compiler=$CC + GCC=$ac_cv_fc_compiler_gnu + + _LT_TAGVAR(compiler, $1)=$CC + _LT_CC_BASENAME([$compiler]) + + if test -n "$compiler"; then + AC_MSG_CHECKING([if libtool supports shared libraries]) + AC_MSG_RESULT([$can_build_shared]) + + AC_MSG_CHECKING([whether to build shared libraries]) + test "$can_build_shared" = "no" && enable_shared=no + + # On AIX, shared libraries and static libraries use the same namespace, and + # are all built from PIC. + case $host_os in + aix3*) + test "$enable_shared" = yes && enable_static=no + if test -n "$RANLIB"; then + archive_cmds="$archive_cmds~\$RANLIB \$lib" + postinstall_cmds='$RANLIB $lib' + fi + ;; + aix[[4-9]]*) + if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then + test "$enable_shared" = yes && enable_static=no + fi + ;; + esac + AC_MSG_RESULT([$enable_shared]) + + AC_MSG_CHECKING([whether to build static libraries]) + # Make sure either enable_shared or enable_static is yes. + test "$enable_shared" = yes || enable_static=yes + AC_MSG_RESULT([$enable_static]) + + _LT_TAGVAR(GCC, $1)="$ac_cv_fc_compiler_gnu" + _LT_TAGVAR(LD, $1)="$LD" + + ## CAVEAT EMPTOR: + ## There is no encapsulation within the following macros, do not change + ## the running order or otherwise move them around unless you know exactly + ## what you are doing... + _LT_SYS_HIDDEN_LIBDEPS($1) + _LT_COMPILER_PIC($1) + _LT_COMPILER_C_O($1) + _LT_COMPILER_FILE_LOCKS($1) + _LT_LINKER_SHLIBS($1) + _LT_SYS_DYNAMIC_LINKER($1) + _LT_LINKER_HARDCODE_LIBPATH($1) + + _LT_CONFIG($1) + fi # test -n "$compiler" + + GCC=$lt_save_GCC + CC=$lt_save_CC + CFLAGS=$lt_save_CFLAGS +fi # test "$_lt_disable_FC" != yes + +AC_LANG_POP +])# _LT_LANG_FC_CONFIG + + +# _LT_LANG_GCJ_CONFIG([TAG]) +# -------------------------- +# Ensure that the configuration variables for the GNU Java Compiler compiler +# are suitably defined. These variables are subsequently used by _LT_CONFIG +# to write the compiler configuration to `libtool'. +m4_defun([_LT_LANG_GCJ_CONFIG], +[AC_REQUIRE([LT_PROG_GCJ])dnl +AC_LANG_SAVE + +# Source file extension for Java test sources. +ac_ext=java + +# Object file extension for compiled Java test sources. +objext=o +_LT_TAGVAR(objext, $1)=$objext + +# Code to be used in simple compile tests +lt_simple_compile_test_code="class foo {}" + +# Code to be used in simple link tests +lt_simple_link_test_code='public class conftest { public static void main(String[[]] argv) {}; }' + +# ltmain only uses $CC for tagged configurations so make sure $CC is set. +_LT_TAG_COMPILER + +# save warnings/boilerplate of simple test code +_LT_COMPILER_BOILERPLATE +_LT_LINKER_BOILERPLATE + +# Allow CC to be a program name with arguments. +lt_save_CC=$CC +lt_save_CFLAGS=$CFLAGS +lt_save_GCC=$GCC +GCC=yes +CC=${GCJ-"gcj"} +CFLAGS=$GCJFLAGS +compiler=$CC +_LT_TAGVAR(compiler, $1)=$CC +_LT_TAGVAR(LD, $1)="$LD" +_LT_CC_BASENAME([$compiler]) + +# GCJ did not exist at the time GCC didn't implicitly link libc in. +_LT_TAGVAR(archive_cmds_need_lc, $1)=no + +_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds +_LT_TAGVAR(reload_flag, $1)=$reload_flag +_LT_TAGVAR(reload_cmds, $1)=$reload_cmds + +if test -n "$compiler"; then + _LT_COMPILER_NO_RTTI($1) + _LT_COMPILER_PIC($1) + _LT_COMPILER_C_O($1) + _LT_COMPILER_FILE_LOCKS($1) + _LT_LINKER_SHLIBS($1) + _LT_LINKER_HARDCODE_LIBPATH($1) + + _LT_CONFIG($1) +fi + +AC_LANG_RESTORE + +GCC=$lt_save_GCC +CC=$lt_save_CC +CFLAGS=$lt_save_CFLAGS +])# _LT_LANG_GCJ_CONFIG + + +# _LT_LANG_GO_CONFIG([TAG]) +# -------------------------- +# Ensure that the configuration variables for the GNU Go compiler +# are suitably defined. These variables are subsequently used by _LT_CONFIG +# to write the compiler configuration to `libtool'. +m4_defun([_LT_LANG_GO_CONFIG], +[AC_REQUIRE([LT_PROG_GO])dnl +AC_LANG_SAVE + +# Source file extension for Go test sources. +ac_ext=go + +# Object file extension for compiled Go test sources. +objext=o +_LT_TAGVAR(objext, $1)=$objext + +# Code to be used in simple compile tests +lt_simple_compile_test_code="package main; func main() { }" + +# Code to be used in simple link tests +lt_simple_link_test_code='package main; func main() { }' + +# ltmain only uses $CC for tagged configurations so make sure $CC is set. +_LT_TAG_COMPILER + +# save warnings/boilerplate of simple test code +_LT_COMPILER_BOILERPLATE +_LT_LINKER_BOILERPLATE + +# Allow CC to be a program name with arguments. +lt_save_CC=$CC +lt_save_CFLAGS=$CFLAGS +lt_save_GCC=$GCC +GCC=yes +CC=${GOC-"gccgo"} +CFLAGS=$GOFLAGS +compiler=$CC +_LT_TAGVAR(compiler, $1)=$CC +_LT_TAGVAR(LD, $1)="$LD" +_LT_CC_BASENAME([$compiler]) + +# Go did not exist at the time GCC didn't implicitly link libc in. +_LT_TAGVAR(archive_cmds_need_lc, $1)=no + +_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds +_LT_TAGVAR(reload_flag, $1)=$reload_flag +_LT_TAGVAR(reload_cmds, $1)=$reload_cmds + +if test -n "$compiler"; then + _LT_COMPILER_NO_RTTI($1) + _LT_COMPILER_PIC($1) + _LT_COMPILER_C_O($1) + _LT_COMPILER_FILE_LOCKS($1) + _LT_LINKER_SHLIBS($1) + _LT_LINKER_HARDCODE_LIBPATH($1) + + _LT_CONFIG($1) +fi + +AC_LANG_RESTORE + +GCC=$lt_save_GCC +CC=$lt_save_CC +CFLAGS=$lt_save_CFLAGS +])# _LT_LANG_GO_CONFIG + + +# _LT_LANG_RC_CONFIG([TAG]) +# ------------------------- +# Ensure that the configuration variables for the Windows resource compiler +# are suitably defined. These variables are subsequently used by _LT_CONFIG +# to write the compiler configuration to `libtool'. +m4_defun([_LT_LANG_RC_CONFIG], +[AC_REQUIRE([LT_PROG_RC])dnl +AC_LANG_SAVE + +# Source file extension for RC test sources. +ac_ext=rc + +# Object file extension for compiled RC test sources. +objext=o +_LT_TAGVAR(objext, $1)=$objext + +# Code to be used in simple compile tests +lt_simple_compile_test_code='sample MENU { MENUITEM "&Soup", 100, CHECKED }' + +# Code to be used in simple link tests +lt_simple_link_test_code="$lt_simple_compile_test_code" + +# ltmain only uses $CC for tagged configurations so make sure $CC is set. +_LT_TAG_COMPILER + +# save warnings/boilerplate of simple test code +_LT_COMPILER_BOILERPLATE +_LT_LINKER_BOILERPLATE + +# Allow CC to be a program name with arguments. +lt_save_CC="$CC" +lt_save_CFLAGS=$CFLAGS +lt_save_GCC=$GCC +GCC= +CC=${RC-"windres"} +CFLAGS= +compiler=$CC +_LT_TAGVAR(compiler, $1)=$CC +_LT_CC_BASENAME([$compiler]) +_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes + +if test -n "$compiler"; then + : + _LT_CONFIG($1) +fi + +GCC=$lt_save_GCC +AC_LANG_RESTORE +CC=$lt_save_CC +CFLAGS=$lt_save_CFLAGS +])# _LT_LANG_RC_CONFIG + + +# LT_PROG_GCJ +# ----------- +AC_DEFUN([LT_PROG_GCJ], +[m4_ifdef([AC_PROG_GCJ], [AC_PROG_GCJ], + [m4_ifdef([A][M_PROG_GCJ], [A][M_PROG_GCJ], + [AC_CHECK_TOOL(GCJ, gcj,) + test "x${GCJFLAGS+set}" = xset || GCJFLAGS="-g -O2" + AC_SUBST(GCJFLAGS)])])[]dnl +]) + +# Old name: +AU_ALIAS([LT_AC_PROG_GCJ], [LT_PROG_GCJ]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([LT_AC_PROG_GCJ], []) + + +# LT_PROG_GO +# ---------- +AC_DEFUN([LT_PROG_GO], +[AC_CHECK_TOOL(GOC, gccgo,) +]) + + +# LT_PROG_RC +# ---------- +AC_DEFUN([LT_PROG_RC], +[AC_CHECK_TOOL(RC, windres,) +]) + +# Old name: +AU_ALIAS([LT_AC_PROG_RC], [LT_PROG_RC]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([LT_AC_PROG_RC], []) + + +# _LT_DECL_EGREP +# -------------- +# If we don't have a new enough Autoconf to choose the best grep +# available, choose the one first in the user's PATH. +m4_defun([_LT_DECL_EGREP], +[AC_REQUIRE([AC_PROG_EGREP])dnl +AC_REQUIRE([AC_PROG_FGREP])dnl +test -z "$GREP" && GREP=grep +_LT_DECL([], [GREP], [1], [A grep program that handles long lines]) +_LT_DECL([], [EGREP], [1], [An ERE matcher]) +_LT_DECL([], [FGREP], [1], [A literal string matcher]) +dnl Non-bleeding-edge autoconf doesn't subst GREP, so do it here too +AC_SUBST([GREP]) +]) + + +# _LT_DECL_OBJDUMP +# -------------- +# If we don't have a new enough Autoconf to choose the best objdump +# available, choose the one first in the user's PATH. +m4_defun([_LT_DECL_OBJDUMP], +[AC_CHECK_TOOL(OBJDUMP, objdump, false) +test -z "$OBJDUMP" && OBJDUMP=objdump +_LT_DECL([], [OBJDUMP], [1], [An object symbol dumper]) +AC_SUBST([OBJDUMP]) +]) + +# _LT_DECL_DLLTOOL +# ---------------- +# Ensure DLLTOOL variable is set. +m4_defun([_LT_DECL_DLLTOOL], +[AC_CHECK_TOOL(DLLTOOL, dlltool, false) +test -z "$DLLTOOL" && DLLTOOL=dlltool +_LT_DECL([], [DLLTOOL], [1], [DLL creation program]) +AC_SUBST([DLLTOOL]) +]) + +# _LT_DECL_SED +# ------------ +# Check for a fully-functional sed program, that truncates +# as few characters as possible. Prefer GNU sed if found. +m4_defun([_LT_DECL_SED], +[AC_PROG_SED +test -z "$SED" && SED=sed +Xsed="$SED -e 1s/^X//" +_LT_DECL([], [SED], [1], [A sed program that does not truncate output]) +_LT_DECL([], [Xsed], ["\$SED -e 1s/^X//"], + [Sed that helps us avoid accidentally triggering echo(1) options like -n]) +])# _LT_DECL_SED + +m4_ifndef([AC_PROG_SED], [ +# NOTE: This macro has been submitted for inclusion into # +# GNU Autoconf as AC_PROG_SED. When it is available in # +# a released version of Autoconf we should remove this # +# macro and use it instead. # + +m4_defun([AC_PROG_SED], +[AC_MSG_CHECKING([for a sed that does not truncate output]) +AC_CACHE_VAL(lt_cv_path_SED, +[# Loop through the user's path and test for sed and gsed. +# Then use that list of sed's as ones to test for truncation. +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for lt_ac_prog in sed gsed; do + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$lt_ac_prog$ac_exec_ext"; then + lt_ac_sed_list="$lt_ac_sed_list $as_dir/$lt_ac_prog$ac_exec_ext" + fi + done + done +done +IFS=$as_save_IFS +lt_ac_max=0 +lt_ac_count=0 +# Add /usr/xpg4/bin/sed as it is typically found on Solaris +# along with /bin/sed that truncates output. +for lt_ac_sed in $lt_ac_sed_list /usr/xpg4/bin/sed; do + test ! -f $lt_ac_sed && continue + cat /dev/null > conftest.in + lt_ac_count=0 + echo $ECHO_N "0123456789$ECHO_C" >conftest.in + # Check for GNU sed and select it if it is found. + if "$lt_ac_sed" --version 2>&1 < /dev/null | grep 'GNU' > /dev/null; then + lt_cv_path_SED=$lt_ac_sed + break + fi + while true; do + cat conftest.in conftest.in >conftest.tmp + mv conftest.tmp conftest.in + cp conftest.in conftest.nl + echo >>conftest.nl + $lt_ac_sed -e 's/a$//' < conftest.nl >conftest.out || break + cmp -s conftest.out conftest.nl || break + # 10000 chars as input seems more than enough + test $lt_ac_count -gt 10 && break + lt_ac_count=`expr $lt_ac_count + 1` + if test $lt_ac_count -gt $lt_ac_max; then + lt_ac_max=$lt_ac_count + lt_cv_path_SED=$lt_ac_sed + fi + done +done +]) +SED=$lt_cv_path_SED +AC_SUBST([SED]) +AC_MSG_RESULT([$SED]) +])#AC_PROG_SED +])#m4_ifndef + +# Old name: +AU_ALIAS([LT_AC_PROG_SED], [AC_PROG_SED]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([LT_AC_PROG_SED], []) + + +# _LT_CHECK_SHELL_FEATURES +# ------------------------ +# Find out whether the shell is Bourne or XSI compatible, +# or has some other useful features. +m4_defun([_LT_CHECK_SHELL_FEATURES], +[AC_MSG_CHECKING([whether the shell understands some XSI constructs]) +# Try some XSI features +xsi_shell=no +( _lt_dummy="a/b/c" + test "${_lt_dummy##*/},${_lt_dummy%/*},${_lt_dummy#??}"${_lt_dummy%"$_lt_dummy"}, \ + = c,a/b,b/c, \ + && eval 'test $(( 1 + 1 )) -eq 2 \ + && test "${#_lt_dummy}" -eq 5' ) >/dev/null 2>&1 \ + && xsi_shell=yes +AC_MSG_RESULT([$xsi_shell]) +_LT_CONFIG_LIBTOOL_INIT([xsi_shell='$xsi_shell']) + +AC_MSG_CHECKING([whether the shell understands "+="]) +lt_shell_append=no +( foo=bar; set foo baz; eval "$[1]+=\$[2]" && test "$foo" = barbaz ) \ + >/dev/null 2>&1 \ + && lt_shell_append=yes +AC_MSG_RESULT([$lt_shell_append]) +_LT_CONFIG_LIBTOOL_INIT([lt_shell_append='$lt_shell_append']) + +if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then + lt_unset=unset +else + lt_unset=false +fi +_LT_DECL([], [lt_unset], [0], [whether the shell understands "unset"])dnl + +# test EBCDIC or ASCII +case `echo X|tr X '\101'` in + A) # ASCII based system + # \n is not interpreted correctly by Solaris 8 /usr/ucb/tr + lt_SP2NL='tr \040 \012' + lt_NL2SP='tr \015\012 \040\040' + ;; + *) # EBCDIC based system + lt_SP2NL='tr \100 \n' + lt_NL2SP='tr \r\n \100\100' + ;; +esac +_LT_DECL([SP2NL], [lt_SP2NL], [1], [turn spaces into newlines])dnl +_LT_DECL([NL2SP], [lt_NL2SP], [1], [turn newlines into spaces])dnl +])# _LT_CHECK_SHELL_FEATURES + + +# _LT_PROG_FUNCTION_REPLACE (FUNCNAME, REPLACEMENT-BODY) +# ------------------------------------------------------ +# In `$cfgfile', look for function FUNCNAME delimited by `^FUNCNAME ()$' and +# '^} FUNCNAME ', and replace its body with REPLACEMENT-BODY. +m4_defun([_LT_PROG_FUNCTION_REPLACE], +[dnl { +sed -e '/^$1 ()$/,/^} # $1 /c\ +$1 ()\ +{\ +m4_bpatsubsts([$2], [$], [\\], [^\([ ]\)], [\\\1]) +} # Extended-shell $1 implementation' "$cfgfile" > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") +test 0 -eq $? || _lt_function_replace_fail=: +]) + + +# _LT_PROG_REPLACE_SHELLFNS +# ------------------------- +# Replace existing portable implementations of several shell functions with +# equivalent extended shell implementations where those features are available.. +m4_defun([_LT_PROG_REPLACE_SHELLFNS], +[if test x"$xsi_shell" = xyes; then + _LT_PROG_FUNCTION_REPLACE([func_dirname], [dnl + case ${1} in + */*) func_dirname_result="${1%/*}${2}" ;; + * ) func_dirname_result="${3}" ;; + esac]) + + _LT_PROG_FUNCTION_REPLACE([func_basename], [dnl + func_basename_result="${1##*/}"]) + + _LT_PROG_FUNCTION_REPLACE([func_dirname_and_basename], [dnl + case ${1} in + */*) func_dirname_result="${1%/*}${2}" ;; + * ) func_dirname_result="${3}" ;; + esac + func_basename_result="${1##*/}"]) + + _LT_PROG_FUNCTION_REPLACE([func_stripname], [dnl + # pdksh 5.2.14 does not do ${X%$Y} correctly if both X and Y are + # positional parameters, so assign one to ordinary parameter first. + func_stripname_result=${3} + func_stripname_result=${func_stripname_result#"${1}"} + func_stripname_result=${func_stripname_result%"${2}"}]) + + _LT_PROG_FUNCTION_REPLACE([func_split_long_opt], [dnl + func_split_long_opt_name=${1%%=*} + func_split_long_opt_arg=${1#*=}]) + + _LT_PROG_FUNCTION_REPLACE([func_split_short_opt], [dnl + func_split_short_opt_arg=${1#??} + func_split_short_opt_name=${1%"$func_split_short_opt_arg"}]) + + _LT_PROG_FUNCTION_REPLACE([func_lo2o], [dnl + case ${1} in + *.lo) func_lo2o_result=${1%.lo}.${objext} ;; + *) func_lo2o_result=${1} ;; + esac]) + + _LT_PROG_FUNCTION_REPLACE([func_xform], [ func_xform_result=${1%.*}.lo]) + + _LT_PROG_FUNCTION_REPLACE([func_arith], [ func_arith_result=$(( $[*] ))]) + + _LT_PROG_FUNCTION_REPLACE([func_len], [ func_len_result=${#1}]) +fi + +if test x"$lt_shell_append" = xyes; then + _LT_PROG_FUNCTION_REPLACE([func_append], [ eval "${1}+=\\${2}"]) + + _LT_PROG_FUNCTION_REPLACE([func_append_quoted], [dnl + func_quote_for_eval "${2}" +dnl m4 expansion turns \\\\ into \\, and then the shell eval turns that into \ + eval "${1}+=\\\\ \\$func_quote_for_eval_result"]) + + # Save a `func_append' function call where possible by direct use of '+=' + sed -e 's%func_append \([[a-zA-Z_]]\{1,\}\) "%\1+="%g' $cfgfile > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") + test 0 -eq $? || _lt_function_replace_fail=: +else + # Save a `func_append' function call even when '+=' is not available + sed -e 's%func_append \([[a-zA-Z_]]\{1,\}\) "%\1="$\1%g' $cfgfile > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") + test 0 -eq $? || _lt_function_replace_fail=: +fi + +if test x"$_lt_function_replace_fail" = x":"; then + AC_MSG_WARN([Unable to substitute extended shell functions in $ofile]) +fi +]) + +# _LT_PATH_CONVERSION_FUNCTIONS +# ----------------------------- +# Determine which file name conversion functions should be used by +# func_to_host_file (and, implicitly, by func_to_host_path). These are needed +# for certain cross-compile configurations and native mingw. +m4_defun([_LT_PATH_CONVERSION_FUNCTIONS], +[AC_REQUIRE([AC_CANONICAL_HOST])dnl +AC_REQUIRE([AC_CANONICAL_BUILD])dnl +AC_MSG_CHECKING([how to convert $build file names to $host format]) +AC_CACHE_VAL(lt_cv_to_host_file_cmd, +[case $host in + *-*-mingw* ) + case $build in + *-*-mingw* ) # actually msys + lt_cv_to_host_file_cmd=func_convert_file_msys_to_w32 + ;; + *-*-cygwin* ) + lt_cv_to_host_file_cmd=func_convert_file_cygwin_to_w32 + ;; + * ) # otherwise, assume *nix + lt_cv_to_host_file_cmd=func_convert_file_nix_to_w32 + ;; + esac + ;; + *-*-cygwin* ) + case $build in + *-*-mingw* ) # actually msys + lt_cv_to_host_file_cmd=func_convert_file_msys_to_cygwin + ;; + *-*-cygwin* ) + lt_cv_to_host_file_cmd=func_convert_file_noop + ;; + * ) # otherwise, assume *nix + lt_cv_to_host_file_cmd=func_convert_file_nix_to_cygwin + ;; + esac + ;; + * ) # unhandled hosts (and "normal" native builds) + lt_cv_to_host_file_cmd=func_convert_file_noop + ;; +esac +]) +to_host_file_cmd=$lt_cv_to_host_file_cmd +AC_MSG_RESULT([$lt_cv_to_host_file_cmd]) +_LT_DECL([to_host_file_cmd], [lt_cv_to_host_file_cmd], + [0], [convert $build file names to $host format])dnl + +AC_MSG_CHECKING([how to convert $build file names to toolchain format]) +AC_CACHE_VAL(lt_cv_to_tool_file_cmd, +[#assume ordinary cross tools, or native build. +lt_cv_to_tool_file_cmd=func_convert_file_noop +case $host in + *-*-mingw* ) + case $build in + *-*-mingw* ) # actually msys + lt_cv_to_tool_file_cmd=func_convert_file_msys_to_w32 + ;; + esac + ;; +esac +]) +to_tool_file_cmd=$lt_cv_to_tool_file_cmd +AC_MSG_RESULT([$lt_cv_to_tool_file_cmd]) +_LT_DECL([to_tool_file_cmd], [lt_cv_to_tool_file_cmd], + [0], [convert $build files to toolchain format])dnl +])# _LT_PATH_CONVERSION_FUNCTIONS + +# Helper functions for option handling. -*- Autoconf -*- +# +# Copyright (C) 2004, 2005, 2007, 2008, 2009 Free Software Foundation, +# Inc. +# Written by Gary V. Vaughan, 2004 +# +# This file is free software; the Free Software Foundation gives +# unlimited permission to copy and/or distribute it, with or without +# modifications, as long as this notice is preserved. + +# serial 7 ltoptions.m4 + +# This is to help aclocal find these macros, as it can't see m4_define. +AC_DEFUN([LTOPTIONS_VERSION], [m4_if([1])]) + + +# _LT_MANGLE_OPTION(MACRO-NAME, OPTION-NAME) +# ------------------------------------------ +m4_define([_LT_MANGLE_OPTION], +[[_LT_OPTION_]m4_bpatsubst($1__$2, [[^a-zA-Z0-9_]], [_])]) + + +# _LT_SET_OPTION(MACRO-NAME, OPTION-NAME) +# --------------------------------------- +# Set option OPTION-NAME for macro MACRO-NAME, and if there is a +# matching handler defined, dispatch to it. Other OPTION-NAMEs are +# saved as a flag. +m4_define([_LT_SET_OPTION], +[m4_define(_LT_MANGLE_OPTION([$1], [$2]))dnl +m4_ifdef(_LT_MANGLE_DEFUN([$1], [$2]), + _LT_MANGLE_DEFUN([$1], [$2]), + [m4_warning([Unknown $1 option `$2'])])[]dnl +]) + + +# _LT_IF_OPTION(MACRO-NAME, OPTION-NAME, IF-SET, [IF-NOT-SET]) +# ------------------------------------------------------------ +# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise. +m4_define([_LT_IF_OPTION], +[m4_ifdef(_LT_MANGLE_OPTION([$1], [$2]), [$3], [$4])]) + + +# _LT_UNLESS_OPTIONS(MACRO-NAME, OPTION-LIST, IF-NOT-SET) +# ------------------------------------------------------- +# Execute IF-NOT-SET unless all options in OPTION-LIST for MACRO-NAME +# are set. +m4_define([_LT_UNLESS_OPTIONS], +[m4_foreach([_LT_Option], m4_split(m4_normalize([$2])), + [m4_ifdef(_LT_MANGLE_OPTION([$1], _LT_Option), + [m4_define([$0_found])])])[]dnl +m4_ifdef([$0_found], [m4_undefine([$0_found])], [$3 +])[]dnl +]) + + +# _LT_SET_OPTIONS(MACRO-NAME, OPTION-LIST) +# ---------------------------------------- +# OPTION-LIST is a space-separated list of Libtool options associated +# with MACRO-NAME. If any OPTION has a matching handler declared with +# LT_OPTION_DEFINE, dispatch to that macro; otherwise complain about +# the unknown option and exit. +m4_defun([_LT_SET_OPTIONS], +[# Set options +m4_foreach([_LT_Option], m4_split(m4_normalize([$2])), + [_LT_SET_OPTION([$1], _LT_Option)]) + +m4_if([$1],[LT_INIT],[ + dnl + dnl Simply set some default values (i.e off) if boolean options were not + dnl specified: + _LT_UNLESS_OPTIONS([LT_INIT], [dlopen], [enable_dlopen=no + ]) + _LT_UNLESS_OPTIONS([LT_INIT], [win32-dll], [enable_win32_dll=no + ]) + dnl + dnl If no reference was made to various pairs of opposing options, then + dnl we run the default mode handler for the pair. For example, if neither + dnl `shared' nor `disable-shared' was passed, we enable building of shared + dnl archives by default: + _LT_UNLESS_OPTIONS([LT_INIT], [shared disable-shared], [_LT_ENABLE_SHARED]) + _LT_UNLESS_OPTIONS([LT_INIT], [static disable-static], [_LT_ENABLE_STATIC]) + _LT_UNLESS_OPTIONS([LT_INIT], [pic-only no-pic], [_LT_WITH_PIC]) + _LT_UNLESS_OPTIONS([LT_INIT], [fast-install disable-fast-install], + [_LT_ENABLE_FAST_INSTALL]) + ]) +])# _LT_SET_OPTIONS + + + +# _LT_MANGLE_DEFUN(MACRO-NAME, OPTION-NAME) +# ----------------------------------------- +m4_define([_LT_MANGLE_DEFUN], +[[_LT_OPTION_DEFUN_]m4_bpatsubst(m4_toupper([$1__$2]), [[^A-Z0-9_]], [_])]) + + +# LT_OPTION_DEFINE(MACRO-NAME, OPTION-NAME, CODE) +# ----------------------------------------------- +m4_define([LT_OPTION_DEFINE], +[m4_define(_LT_MANGLE_DEFUN([$1], [$2]), [$3])[]dnl +])# LT_OPTION_DEFINE + + +# dlopen +# ------ +LT_OPTION_DEFINE([LT_INIT], [dlopen], [enable_dlopen=yes +]) + +AU_DEFUN([AC_LIBTOOL_DLOPEN], +[_LT_SET_OPTION([LT_INIT], [dlopen]) +AC_DIAGNOSE([obsolete], +[$0: Remove this warning and the call to _LT_SET_OPTION when you +put the `dlopen' option into LT_INIT's first parameter.]) +]) + +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LIBTOOL_DLOPEN], []) + + +# win32-dll +# --------- +# Declare package support for building win32 dll's. +LT_OPTION_DEFINE([LT_INIT], [win32-dll], +[enable_win32_dll=yes + +case $host in +*-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-cegcc*) + AC_CHECK_TOOL(AS, as, false) + AC_CHECK_TOOL(DLLTOOL, dlltool, false) + AC_CHECK_TOOL(OBJDUMP, objdump, false) + ;; +esac + +test -z "$AS" && AS=as +_LT_DECL([], [AS], [1], [Assembler program])dnl + +test -z "$DLLTOOL" && DLLTOOL=dlltool +_LT_DECL([], [DLLTOOL], [1], [DLL creation program])dnl + +test -z "$OBJDUMP" && OBJDUMP=objdump +_LT_DECL([], [OBJDUMP], [1], [Object dumper program])dnl +])# win32-dll + +AU_DEFUN([AC_LIBTOOL_WIN32_DLL], +[AC_REQUIRE([AC_CANONICAL_HOST])dnl +_LT_SET_OPTION([LT_INIT], [win32-dll]) +AC_DIAGNOSE([obsolete], +[$0: Remove this warning and the call to _LT_SET_OPTION when you +put the `win32-dll' option into LT_INIT's first parameter.]) +]) + +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LIBTOOL_WIN32_DLL], []) + + +# _LT_ENABLE_SHARED([DEFAULT]) +# ---------------------------- +# implement the --enable-shared flag, and supports the `shared' and +# `disable-shared' LT_INIT options. +# DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'. +m4_define([_LT_ENABLE_SHARED], +[m4_define([_LT_ENABLE_SHARED_DEFAULT], [m4_if($1, no, no, yes)])dnl +AC_ARG_ENABLE([shared], + [AS_HELP_STRING([--enable-shared@<:@=PKGS@:>@], + [build shared libraries @<:@default=]_LT_ENABLE_SHARED_DEFAULT[@:>@])], + [p=${PACKAGE-default} + case $enableval in + yes) enable_shared=yes ;; + no) enable_shared=no ;; + *) + enable_shared=no + # Look at the argument we got. We use all the common list separators. + lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," + for pkg in $enableval; do + IFS="$lt_save_ifs" + if test "X$pkg" = "X$p"; then + enable_shared=yes + fi + done + IFS="$lt_save_ifs" + ;; + esac], + [enable_shared=]_LT_ENABLE_SHARED_DEFAULT) + + _LT_DECL([build_libtool_libs], [enable_shared], [0], + [Whether or not to build shared libraries]) +])# _LT_ENABLE_SHARED + +LT_OPTION_DEFINE([LT_INIT], [shared], [_LT_ENABLE_SHARED([yes])]) +LT_OPTION_DEFINE([LT_INIT], [disable-shared], [_LT_ENABLE_SHARED([no])]) + +# Old names: +AC_DEFUN([AC_ENABLE_SHARED], +[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[shared]) +]) + +AC_DEFUN([AC_DISABLE_SHARED], +[_LT_SET_OPTION([LT_INIT], [disable-shared]) +]) + +AU_DEFUN([AM_ENABLE_SHARED], [AC_ENABLE_SHARED($@)]) +AU_DEFUN([AM_DISABLE_SHARED], [AC_DISABLE_SHARED($@)]) + +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AM_ENABLE_SHARED], []) +dnl AC_DEFUN([AM_DISABLE_SHARED], []) + + + +# _LT_ENABLE_STATIC([DEFAULT]) +# ---------------------------- +# implement the --enable-static flag, and support the `static' and +# `disable-static' LT_INIT options. +# DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'. +m4_define([_LT_ENABLE_STATIC], +[m4_define([_LT_ENABLE_STATIC_DEFAULT], [m4_if($1, no, no, yes)])dnl +AC_ARG_ENABLE([static], + [AS_HELP_STRING([--enable-static@<:@=PKGS@:>@], + [build static libraries @<:@default=]_LT_ENABLE_STATIC_DEFAULT[@:>@])], + [p=${PACKAGE-default} + case $enableval in + yes) enable_static=yes ;; + no) enable_static=no ;; + *) + enable_static=no + # Look at the argument we got. We use all the common list separators. + lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," + for pkg in $enableval; do + IFS="$lt_save_ifs" + if test "X$pkg" = "X$p"; then + enable_static=yes + fi + done + IFS="$lt_save_ifs" + ;; + esac], + [enable_static=]_LT_ENABLE_STATIC_DEFAULT) + + _LT_DECL([build_old_libs], [enable_static], [0], + [Whether or not to build static libraries]) +])# _LT_ENABLE_STATIC + +LT_OPTION_DEFINE([LT_INIT], [static], [_LT_ENABLE_STATIC([yes])]) +LT_OPTION_DEFINE([LT_INIT], [disable-static], [_LT_ENABLE_STATIC([no])]) + +# Old names: +AC_DEFUN([AC_ENABLE_STATIC], +[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[static]) +]) + +AC_DEFUN([AC_DISABLE_STATIC], +[_LT_SET_OPTION([LT_INIT], [disable-static]) +]) + +AU_DEFUN([AM_ENABLE_STATIC], [AC_ENABLE_STATIC($@)]) +AU_DEFUN([AM_DISABLE_STATIC], [AC_DISABLE_STATIC($@)]) + +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AM_ENABLE_STATIC], []) +dnl AC_DEFUN([AM_DISABLE_STATIC], []) + + + +# _LT_ENABLE_FAST_INSTALL([DEFAULT]) +# ---------------------------------- +# implement the --enable-fast-install flag, and support the `fast-install' +# and `disable-fast-install' LT_INIT options. +# DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'. +m4_define([_LT_ENABLE_FAST_INSTALL], +[m4_define([_LT_ENABLE_FAST_INSTALL_DEFAULT], [m4_if($1, no, no, yes)])dnl +AC_ARG_ENABLE([fast-install], + [AS_HELP_STRING([--enable-fast-install@<:@=PKGS@:>@], + [optimize for fast installation @<:@default=]_LT_ENABLE_FAST_INSTALL_DEFAULT[@:>@])], + [p=${PACKAGE-default} + case $enableval in + yes) enable_fast_install=yes ;; + no) enable_fast_install=no ;; + *) + enable_fast_install=no + # Look at the argument we got. We use all the common list separators. + lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," + for pkg in $enableval; do + IFS="$lt_save_ifs" + if test "X$pkg" = "X$p"; then + enable_fast_install=yes + fi + done + IFS="$lt_save_ifs" + ;; + esac], + [enable_fast_install=]_LT_ENABLE_FAST_INSTALL_DEFAULT) + +_LT_DECL([fast_install], [enable_fast_install], [0], + [Whether or not to optimize for fast installation])dnl +])# _LT_ENABLE_FAST_INSTALL + +LT_OPTION_DEFINE([LT_INIT], [fast-install], [_LT_ENABLE_FAST_INSTALL([yes])]) +LT_OPTION_DEFINE([LT_INIT], [disable-fast-install], [_LT_ENABLE_FAST_INSTALL([no])]) + +# Old names: +AU_DEFUN([AC_ENABLE_FAST_INSTALL], +[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[fast-install]) +AC_DIAGNOSE([obsolete], +[$0: Remove this warning and the call to _LT_SET_OPTION when you put +the `fast-install' option into LT_INIT's first parameter.]) +]) + +AU_DEFUN([AC_DISABLE_FAST_INSTALL], +[_LT_SET_OPTION([LT_INIT], [disable-fast-install]) +AC_DIAGNOSE([obsolete], +[$0: Remove this warning and the call to _LT_SET_OPTION when you put +the `disable-fast-install' option into LT_INIT's first parameter.]) +]) + +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_ENABLE_FAST_INSTALL], []) +dnl AC_DEFUN([AM_DISABLE_FAST_INSTALL], []) + + +# _LT_WITH_PIC([MODE]) +# -------------------- +# implement the --with-pic flag, and support the `pic-only' and `no-pic' +# LT_INIT options. +# MODE is either `yes' or `no'. If omitted, it defaults to `both'. +m4_define([_LT_WITH_PIC], +[AC_ARG_WITH([pic], + [AS_HELP_STRING([--with-pic@<:@=PKGS@:>@], + [try to use only PIC/non-PIC objects @<:@default=use both@:>@])], + [lt_p=${PACKAGE-default} + case $withval in + yes|no) pic_mode=$withval ;; + *) + pic_mode=default + # Look at the argument we got. We use all the common list separators. + lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," + for lt_pkg in $withval; do + IFS="$lt_save_ifs" + if test "X$lt_pkg" = "X$lt_p"; then + pic_mode=yes + fi + done + IFS="$lt_save_ifs" + ;; + esac], + [pic_mode=default]) + +test -z "$pic_mode" && pic_mode=m4_default([$1], [default]) + +_LT_DECL([], [pic_mode], [0], [What type of objects to build])dnl +])# _LT_WITH_PIC + +LT_OPTION_DEFINE([LT_INIT], [pic-only], [_LT_WITH_PIC([yes])]) +LT_OPTION_DEFINE([LT_INIT], [no-pic], [_LT_WITH_PIC([no])]) + +# Old name: +AU_DEFUN([AC_LIBTOOL_PICMODE], +[_LT_SET_OPTION([LT_INIT], [pic-only]) +AC_DIAGNOSE([obsolete], +[$0: Remove this warning and the call to _LT_SET_OPTION when you +put the `pic-only' option into LT_INIT's first parameter.]) +]) + +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LIBTOOL_PICMODE], []) + + +m4_define([_LTDL_MODE], []) +LT_OPTION_DEFINE([LTDL_INIT], [nonrecursive], + [m4_define([_LTDL_MODE], [nonrecursive])]) +LT_OPTION_DEFINE([LTDL_INIT], [recursive], + [m4_define([_LTDL_MODE], [recursive])]) +LT_OPTION_DEFINE([LTDL_INIT], [subproject], + [m4_define([_LTDL_MODE], [subproject])]) + +m4_define([_LTDL_TYPE], []) +LT_OPTION_DEFINE([LTDL_INIT], [installable], + [m4_define([_LTDL_TYPE], [installable])]) +LT_OPTION_DEFINE([LTDL_INIT], [convenience], + [m4_define([_LTDL_TYPE], [convenience])]) + +# ltsugar.m4 -- libtool m4 base layer. -*-Autoconf-*- +# +# Copyright (C) 2004, 2005, 2007, 2008 Free Software Foundation, Inc. +# Written by Gary V. Vaughan, 2004 +# +# This file is free software; the Free Software Foundation gives +# unlimited permission to copy and/or distribute it, with or without +# modifications, as long as this notice is preserved. + +# serial 6 ltsugar.m4 + +# This is to help aclocal find these macros, as it can't see m4_define. +AC_DEFUN([LTSUGAR_VERSION], [m4_if([0.1])]) + + +# lt_join(SEP, ARG1, [ARG2...]) +# ----------------------------- +# Produce ARG1SEPARG2...SEPARGn, omitting [] arguments and their +# associated separator. +# Needed until we can rely on m4_join from Autoconf 2.62, since all earlier +# versions in m4sugar had bugs. +m4_define([lt_join], +[m4_if([$#], [1], [], + [$#], [2], [[$2]], + [m4_if([$2], [], [], [[$2]_])$0([$1], m4_shift(m4_shift($@)))])]) +m4_define([_lt_join], +[m4_if([$#$2], [2], [], + [m4_if([$2], [], [], [[$1$2]])$0([$1], m4_shift(m4_shift($@)))])]) + + +# lt_car(LIST) +# lt_cdr(LIST) +# ------------ +# Manipulate m4 lists. +# These macros are necessary as long as will still need to support +# Autoconf-2.59 which quotes differently. +m4_define([lt_car], [[$1]]) +m4_define([lt_cdr], +[m4_if([$#], 0, [m4_fatal([$0: cannot be called without arguments])], + [$#], 1, [], + [m4_dquote(m4_shift($@))])]) +m4_define([lt_unquote], $1) + + +# lt_append(MACRO-NAME, STRING, [SEPARATOR]) +# ------------------------------------------ +# Redefine MACRO-NAME to hold its former content plus `SEPARATOR'`STRING'. +# Note that neither SEPARATOR nor STRING are expanded; they are appended +# to MACRO-NAME as is (leaving the expansion for when MACRO-NAME is invoked). +# No SEPARATOR is output if MACRO-NAME was previously undefined (different +# than defined and empty). +# +# This macro is needed until we can rely on Autoconf 2.62, since earlier +# versions of m4sugar mistakenly expanded SEPARATOR but not STRING. +m4_define([lt_append], +[m4_define([$1], + m4_ifdef([$1], [m4_defn([$1])[$3]])[$2])]) + + + +# lt_combine(SEP, PREFIX-LIST, INFIX, SUFFIX1, [SUFFIX2...]) +# ---------------------------------------------------------- +# Produce a SEP delimited list of all paired combinations of elements of +# PREFIX-LIST with SUFFIX1 through SUFFIXn. Each element of the list +# has the form PREFIXmINFIXSUFFIXn. +# Needed until we can rely on m4_combine added in Autoconf 2.62. +m4_define([lt_combine], +[m4_if(m4_eval([$# > 3]), [1], + [m4_pushdef([_Lt_sep], [m4_define([_Lt_sep], m4_defn([lt_car]))])]]dnl +[[m4_foreach([_Lt_prefix], [$2], + [m4_foreach([_Lt_suffix], + ]m4_dquote(m4_dquote(m4_shift(m4_shift(m4_shift($@)))))[, + [_Lt_sep([$1])[]m4_defn([_Lt_prefix])[$3]m4_defn([_Lt_suffix])])])])]) + + +# lt_if_append_uniq(MACRO-NAME, VARNAME, [SEPARATOR], [UNIQ], [NOT-UNIQ]) +# ----------------------------------------------------------------------- +# Iff MACRO-NAME does not yet contain VARNAME, then append it (delimited +# by SEPARATOR if supplied) and expand UNIQ, else NOT-UNIQ. +m4_define([lt_if_append_uniq], +[m4_ifdef([$1], + [m4_if(m4_index([$3]m4_defn([$1])[$3], [$3$2$3]), [-1], + [lt_append([$1], [$2], [$3])$4], + [$5])], + [lt_append([$1], [$2], [$3])$4])]) + + +# lt_dict_add(DICT, KEY, VALUE) +# ----------------------------- +m4_define([lt_dict_add], +[m4_define([$1($2)], [$3])]) + + +# lt_dict_add_subkey(DICT, KEY, SUBKEY, VALUE) +# -------------------------------------------- +m4_define([lt_dict_add_subkey], +[m4_define([$1($2:$3)], [$4])]) + + +# lt_dict_fetch(DICT, KEY, [SUBKEY]) +# ---------------------------------- +m4_define([lt_dict_fetch], +[m4_ifval([$3], + m4_ifdef([$1($2:$3)], [m4_defn([$1($2:$3)])]), + m4_ifdef([$1($2)], [m4_defn([$1($2)])]))]) + + +# lt_if_dict_fetch(DICT, KEY, [SUBKEY], VALUE, IF-TRUE, [IF-FALSE]) +# ----------------------------------------------------------------- +m4_define([lt_if_dict_fetch], +[m4_if(lt_dict_fetch([$1], [$2], [$3]), [$4], + [$5], + [$6])]) + + +# lt_dict_filter(DICT, [SUBKEY], VALUE, [SEPARATOR], KEY, [...]) +# -------------------------------------------------------------- +m4_define([lt_dict_filter], +[m4_if([$5], [], [], + [lt_join(m4_quote(m4_default([$4], [[, ]])), + lt_unquote(m4_split(m4_normalize(m4_foreach(_Lt_key, lt_car([m4_shiftn(4, $@)]), + [lt_if_dict_fetch([$1], _Lt_key, [$2], [$3], [_Lt_key ])])))))])[]dnl +]) + +# ltversion.m4 -- version numbers -*- Autoconf -*- +# +# Copyright (C) 2004 Free Software Foundation, Inc. +# Written by Scott James Remnant, 2004 +# +# This file is free software; the Free Software Foundation gives +# unlimited permission to copy and/or distribute it, with or without +# modifications, as long as this notice is preserved. + +# @configure_input@ + +# serial 3337 ltversion.m4 +# This file is part of GNU Libtool + +m4_define([LT_PACKAGE_VERSION], [2.4.2]) +m4_define([LT_PACKAGE_REVISION], [1.3337]) + +AC_DEFUN([LTVERSION_VERSION], +[macro_version='2.4.2' +macro_revision='1.3337' +_LT_DECL(, macro_version, 0, [Which release of libtool.m4 was used?]) +_LT_DECL(, macro_revision, 0) +]) + +# lt~obsolete.m4 -- aclocal satisfying obsolete definitions. -*-Autoconf-*- +# +# Copyright (C) 2004, 2005, 2007, 2009 Free Software Foundation, Inc. +# Written by Scott James Remnant, 2004. +# +# This file is free software; the Free Software Foundation gives +# unlimited permission to copy and/or distribute it, with or without +# modifications, as long as this notice is preserved. + +# serial 5 lt~obsolete.m4 + +# These exist entirely to fool aclocal when bootstrapping libtool. +# +# In the past libtool.m4 has provided macros via AC_DEFUN (or AU_DEFUN) +# which have later been changed to m4_define as they aren't part of the +# exported API, or moved to Autoconf or Automake where they belong. +# +# The trouble is, aclocal is a bit thick. It'll see the old AC_DEFUN +# in /usr/share/aclocal/libtool.m4 and remember it, then when it sees us +# using a macro with the same name in our local m4/libtool.m4 it'll +# pull the old libtool.m4 in (it doesn't see our shiny new m4_define +# and doesn't know about Autoconf macros at all.) +# +# So we provide this file, which has a silly filename so it's always +# included after everything else. This provides aclocal with the +# AC_DEFUNs it wants, but when m4 processes it, it doesn't do anything +# because those macros already exist, or will be overwritten later. +# We use AC_DEFUN over AU_DEFUN for compatibility with aclocal-1.6. +# +# Anytime we withdraw an AC_DEFUN or AU_DEFUN, remember to add it here. +# Yes, that means every name once taken will need to remain here until +# we give up compatibility with versions before 1.7, at which point +# we need to keep only those names which we still refer to. + +# This is to help aclocal find these macros, as it can't see m4_define. +AC_DEFUN([LTOBSOLETE_VERSION], [m4_if([1])]) + +m4_ifndef([AC_LIBTOOL_LINKER_OPTION], [AC_DEFUN([AC_LIBTOOL_LINKER_OPTION])]) +m4_ifndef([AC_PROG_EGREP], [AC_DEFUN([AC_PROG_EGREP])]) +m4_ifndef([_LT_AC_PROG_ECHO_BACKSLASH], [AC_DEFUN([_LT_AC_PROG_ECHO_BACKSLASH])]) +m4_ifndef([_LT_AC_SHELL_INIT], [AC_DEFUN([_LT_AC_SHELL_INIT])]) +m4_ifndef([_LT_AC_SYS_LIBPATH_AIX], [AC_DEFUN([_LT_AC_SYS_LIBPATH_AIX])]) +m4_ifndef([_LT_PROG_LTMAIN], [AC_DEFUN([_LT_PROG_LTMAIN])]) +m4_ifndef([_LT_AC_TAGVAR], [AC_DEFUN([_LT_AC_TAGVAR])]) +m4_ifndef([AC_LTDL_ENABLE_INSTALL], [AC_DEFUN([AC_LTDL_ENABLE_INSTALL])]) +m4_ifndef([AC_LTDL_PREOPEN], [AC_DEFUN([AC_LTDL_PREOPEN])]) +m4_ifndef([_LT_AC_SYS_COMPILER], [AC_DEFUN([_LT_AC_SYS_COMPILER])]) +m4_ifndef([_LT_AC_LOCK], [AC_DEFUN([_LT_AC_LOCK])]) +m4_ifndef([AC_LIBTOOL_SYS_OLD_ARCHIVE], [AC_DEFUN([AC_LIBTOOL_SYS_OLD_ARCHIVE])]) +m4_ifndef([_LT_AC_TRY_DLOPEN_SELF], [AC_DEFUN([_LT_AC_TRY_DLOPEN_SELF])]) +m4_ifndef([AC_LIBTOOL_PROG_CC_C_O], [AC_DEFUN([AC_LIBTOOL_PROG_CC_C_O])]) +m4_ifndef([AC_LIBTOOL_SYS_HARD_LINK_LOCKS], [AC_DEFUN([AC_LIBTOOL_SYS_HARD_LINK_LOCKS])]) +m4_ifndef([AC_LIBTOOL_OBJDIR], [AC_DEFUN([AC_LIBTOOL_OBJDIR])]) +m4_ifndef([AC_LTDL_OBJDIR], [AC_DEFUN([AC_LTDL_OBJDIR])]) +m4_ifndef([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH], [AC_DEFUN([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH])]) +m4_ifndef([AC_LIBTOOL_SYS_LIB_STRIP], [AC_DEFUN([AC_LIBTOOL_SYS_LIB_STRIP])]) +m4_ifndef([AC_PATH_MAGIC], [AC_DEFUN([AC_PATH_MAGIC])]) +m4_ifndef([AC_PROG_LD_GNU], [AC_DEFUN([AC_PROG_LD_GNU])]) +m4_ifndef([AC_PROG_LD_RELOAD_FLAG], [AC_DEFUN([AC_PROG_LD_RELOAD_FLAG])]) +m4_ifndef([AC_DEPLIBS_CHECK_METHOD], [AC_DEFUN([AC_DEPLIBS_CHECK_METHOD])]) +m4_ifndef([AC_LIBTOOL_PROG_COMPILER_NO_RTTI], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_NO_RTTI])]) +m4_ifndef([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE], [AC_DEFUN([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE])]) +m4_ifndef([AC_LIBTOOL_PROG_COMPILER_PIC], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_PIC])]) +m4_ifndef([AC_LIBTOOL_PROG_LD_SHLIBS], [AC_DEFUN([AC_LIBTOOL_PROG_LD_SHLIBS])]) +m4_ifndef([AC_LIBTOOL_POSTDEP_PREDEP], [AC_DEFUN([AC_LIBTOOL_POSTDEP_PREDEP])]) +m4_ifndef([LT_AC_PROG_EGREP], [AC_DEFUN([LT_AC_PROG_EGREP])]) +m4_ifndef([LT_AC_PROG_SED], [AC_DEFUN([LT_AC_PROG_SED])]) +m4_ifndef([_LT_CC_BASENAME], [AC_DEFUN([_LT_CC_BASENAME])]) +m4_ifndef([_LT_COMPILER_BOILERPLATE], [AC_DEFUN([_LT_COMPILER_BOILERPLATE])]) +m4_ifndef([_LT_LINKER_BOILERPLATE], [AC_DEFUN([_LT_LINKER_BOILERPLATE])]) +m4_ifndef([_AC_PROG_LIBTOOL], [AC_DEFUN([_AC_PROG_LIBTOOL])]) +m4_ifndef([AC_LIBTOOL_SETUP], [AC_DEFUN([AC_LIBTOOL_SETUP])]) +m4_ifndef([_LT_AC_CHECK_DLFCN], [AC_DEFUN([_LT_AC_CHECK_DLFCN])]) +m4_ifndef([AC_LIBTOOL_SYS_DYNAMIC_LINKER], [AC_DEFUN([AC_LIBTOOL_SYS_DYNAMIC_LINKER])]) +m4_ifndef([_LT_AC_TAGCONFIG], [AC_DEFUN([_LT_AC_TAGCONFIG])]) +m4_ifndef([AC_DISABLE_FAST_INSTALL], [AC_DEFUN([AC_DISABLE_FAST_INSTALL])]) +m4_ifndef([_LT_AC_LANG_CXX], [AC_DEFUN([_LT_AC_LANG_CXX])]) +m4_ifndef([_LT_AC_LANG_F77], [AC_DEFUN([_LT_AC_LANG_F77])]) +m4_ifndef([_LT_AC_LANG_GCJ], [AC_DEFUN([_LT_AC_LANG_GCJ])]) +m4_ifndef([AC_LIBTOOL_LANG_C_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_C_CONFIG])]) +m4_ifndef([_LT_AC_LANG_C_CONFIG], [AC_DEFUN([_LT_AC_LANG_C_CONFIG])]) +m4_ifndef([AC_LIBTOOL_LANG_CXX_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_CXX_CONFIG])]) +m4_ifndef([_LT_AC_LANG_CXX_CONFIG], [AC_DEFUN([_LT_AC_LANG_CXX_CONFIG])]) +m4_ifndef([AC_LIBTOOL_LANG_F77_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_F77_CONFIG])]) +m4_ifndef([_LT_AC_LANG_F77_CONFIG], [AC_DEFUN([_LT_AC_LANG_F77_CONFIG])]) +m4_ifndef([AC_LIBTOOL_LANG_GCJ_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_GCJ_CONFIG])]) +m4_ifndef([_LT_AC_LANG_GCJ_CONFIG], [AC_DEFUN([_LT_AC_LANG_GCJ_CONFIG])]) +m4_ifndef([AC_LIBTOOL_LANG_RC_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_RC_CONFIG])]) +m4_ifndef([_LT_AC_LANG_RC_CONFIG], [AC_DEFUN([_LT_AC_LANG_RC_CONFIG])]) +m4_ifndef([AC_LIBTOOL_CONFIG], [AC_DEFUN([AC_LIBTOOL_CONFIG])]) +m4_ifndef([_LT_AC_FILE_LTDLL_C], [AC_DEFUN([_LT_AC_FILE_LTDLL_C])]) +m4_ifndef([_LT_REQUIRED_DARWIN_CHECKS], [AC_DEFUN([_LT_REQUIRED_DARWIN_CHECKS])]) +m4_ifndef([_LT_AC_PROG_CXXCPP], [AC_DEFUN([_LT_AC_PROG_CXXCPP])]) +m4_ifndef([_LT_PREPARE_SED_QUOTE_VARS], [AC_DEFUN([_LT_PREPARE_SED_QUOTE_VARS])]) +m4_ifndef([_LT_PROG_ECHO_BACKSLASH], [AC_DEFUN([_LT_PROG_ECHO_BACKSLASH])]) +m4_ifndef([_LT_PROG_F77], [AC_DEFUN([_LT_PROG_F77])]) +m4_ifndef([_LT_PROG_FC], [AC_DEFUN([_LT_PROG_FC])]) +m4_ifndef([_LT_PROG_CXX], [AC_DEFUN([_LT_PROG_CXX])]) + +# Copyright (C) 2002, 2003, 2005, 2006, 2007, 2008, 2011 Free Software +# Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 1 + +# AM_AUTOMAKE_VERSION(VERSION) +# ---------------------------- +# Automake X.Y traces this macro to ensure aclocal.m4 has been +# generated from the m4 files accompanying Automake X.Y. +# (This private macro should not be called outside this file.) +AC_DEFUN([AM_AUTOMAKE_VERSION], +[am__api_version='1.11' +dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to +dnl require some minimum version. Point them to the right macro. +m4_if([$1], [1.11.3], [], + [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl +]) + +# _AM_AUTOCONF_VERSION(VERSION) +# ----------------------------- +# aclocal traces this macro to find the Autoconf version. +# This is a private macro too. Using m4_define simplifies +# the logic in aclocal, which can simply ignore this definition. +m4_define([_AM_AUTOCONF_VERSION], []) + +# AM_SET_CURRENT_AUTOMAKE_VERSION +# ------------------------------- +# Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced. +# This function is AC_REQUIREd by AM_INIT_AUTOMAKE. +AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION], +[AM_AUTOMAKE_VERSION([1.11.3])dnl +m4_ifndef([AC_AUTOCONF_VERSION], + [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl +_AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))]) + +# AM_AUX_DIR_EXPAND -*- Autoconf -*- + +# Copyright (C) 2001, 2003, 2005, 2011 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 1 + +# For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets +# $ac_aux_dir to `$srcdir/foo'. In other projects, it is set to +# `$srcdir', `$srcdir/..', or `$srcdir/../..'. +# +# Of course, Automake must honor this variable whenever it calls a +# tool from the auxiliary directory. The problem is that $srcdir (and +# therefore $ac_aux_dir as well) can be either absolute or relative, +# depending on how configure is run. This is pretty annoying, since +# it makes $ac_aux_dir quite unusable in subdirectories: in the top +# source directory, any form will work fine, but in subdirectories a +# relative path needs to be adjusted first. +# +# $ac_aux_dir/missing +# fails when called from a subdirectory if $ac_aux_dir is relative +# $top_srcdir/$ac_aux_dir/missing +# fails if $ac_aux_dir is absolute, +# fails when called from a subdirectory in a VPATH build with +# a relative $ac_aux_dir +# +# The reason of the latter failure is that $top_srcdir and $ac_aux_dir +# are both prefixed by $srcdir. In an in-source build this is usually +# harmless because $srcdir is `.', but things will broke when you +# start a VPATH build or use an absolute $srcdir. +# +# So we could use something similar to $top_srcdir/$ac_aux_dir/missing, +# iff we strip the leading $srcdir from $ac_aux_dir. That would be: +# am_aux_dir='\$(top_srcdir)/'`expr "$ac_aux_dir" : "$srcdir//*\(.*\)"` +# and then we would define $MISSING as +# MISSING="\${SHELL} $am_aux_dir/missing" +# This will work as long as MISSING is not called from configure, because +# unfortunately $(top_srcdir) has no meaning in configure. +# However there are other variables, like CC, which are often used in +# configure, and could therefore not use this "fixed" $ac_aux_dir. +# +# Another solution, used here, is to always expand $ac_aux_dir to an +# absolute PATH. The drawback is that using absolute paths prevent a +# configured tree to be moved without reconfiguration. + +AC_DEFUN([AM_AUX_DIR_EXPAND], +[dnl Rely on autoconf to set up CDPATH properly. +AC_PREREQ([2.50])dnl +# expand $ac_aux_dir to an absolute path +am_aux_dir=`cd $ac_aux_dir && pwd` +]) + +# AM_CONDITIONAL -*- Autoconf -*- + +# Copyright (C) 1997, 2000, 2001, 2003, 2004, 2005, 2006, 2008 +# Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 9 + +# AM_CONDITIONAL(NAME, SHELL-CONDITION) +# ------------------------------------- +# Define a conditional. +AC_DEFUN([AM_CONDITIONAL], +[AC_PREREQ(2.52)dnl + ifelse([$1], [TRUE], [AC_FATAL([$0: invalid condition: $1])], + [$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl +AC_SUBST([$1_TRUE])dnl +AC_SUBST([$1_FALSE])dnl +_AM_SUBST_NOTMAKE([$1_TRUE])dnl +_AM_SUBST_NOTMAKE([$1_FALSE])dnl +m4_define([_AM_COND_VALUE_$1], [$2])dnl +if $2; then + $1_TRUE= + $1_FALSE='#' +else + $1_TRUE='#' + $1_FALSE= +fi +AC_CONFIG_COMMANDS_PRE( +[if test -z "${$1_TRUE}" && test -z "${$1_FALSE}"; then + AC_MSG_ERROR([[conditional "$1" was never defined. +Usually this means the macro was only invoked conditionally.]]) +fi])]) + +# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2009, +# 2010, 2011 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 12 + +# There are a few dirty hacks below to avoid letting `AC_PROG_CC' be +# written in clear, in which case automake, when reading aclocal.m4, +# will think it sees a *use*, and therefore will trigger all it's +# C support machinery. Also note that it means that autoscan, seeing +# CC etc. in the Makefile, will ask for an AC_PROG_CC use... + + +# _AM_DEPENDENCIES(NAME) +# ---------------------- +# See how the compiler implements dependency checking. +# NAME is "CC", "CXX", "GCJ", or "OBJC". +# We try a few techniques and use that to set a single cache variable. +# +# We don't AC_REQUIRE the corresponding AC_PROG_CC since the latter was +# modified to invoke _AM_DEPENDENCIES(CC); we would have a circular +# dependency, and given that the user is not expected to run this macro, +# just rely on AC_PROG_CC. +AC_DEFUN([_AM_DEPENDENCIES], +[AC_REQUIRE([AM_SET_DEPDIR])dnl +AC_REQUIRE([AM_OUTPUT_DEPENDENCY_COMMANDS])dnl +AC_REQUIRE([AM_MAKE_INCLUDE])dnl +AC_REQUIRE([AM_DEP_TRACK])dnl + +ifelse([$1], CC, [depcc="$CC" am_compiler_list=], + [$1], CXX, [depcc="$CXX" am_compiler_list=], + [$1], OBJC, [depcc="$OBJC" am_compiler_list='gcc3 gcc'], + [$1], UPC, [depcc="$UPC" am_compiler_list=], + [$1], GCJ, [depcc="$GCJ" am_compiler_list='gcc3 gcc'], + [depcc="$$1" am_compiler_list=]) + +AC_CACHE_CHECK([dependency style of $depcc], + [am_cv_$1_dependencies_compiler_type], +[if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then + # We make a subdir and do the tests there. Otherwise we can end up + # making bogus files that we don't know about and never remove. For + # instance it was reported that on HP-UX the gcc test will end up + # making a dummy file named `D' -- because `-MD' means `put the output + # in D'. + rm -rf conftest.dir + mkdir conftest.dir + # Copy depcomp to subdir because otherwise we won't find it if we're + # using a relative directory. + cp "$am_depcomp" conftest.dir + cd conftest.dir + # We will build objects and dependencies in a subdirectory because + # it helps to detect inapplicable dependency modes. For instance + # both Tru64's cc and ICC support -MD to output dependencies as a + # side effect of compilation, but ICC will put the dependencies in + # the current directory while Tru64 will put them in the object + # directory. + mkdir sub + + am_cv_$1_dependencies_compiler_type=none + if test "$am_compiler_list" = ""; then + am_compiler_list=`sed -n ['s/^#*\([a-zA-Z0-9]*\))$/\1/p'] < ./depcomp` + fi + am__universal=false + m4_case([$1], [CC], + [case " $depcc " in #( + *\ -arch\ *\ -arch\ *) am__universal=true ;; + esac], + [CXX], + [case " $depcc " in #( + *\ -arch\ *\ -arch\ *) am__universal=true ;; + esac]) + + for depmode in $am_compiler_list; do + # Setup a source with many dependencies, because some compilers + # like to wrap large dependency lists on column 80 (with \), and + # we should not choose a depcomp mode which is confused by this. + # + # We need to recreate these files for each test, as the compiler may + # overwrite some of them when testing with obscure command lines. + # This happens at least with the AIX C compiler. + : > sub/conftest.c + for i in 1 2 3 4 5 6; do + echo '#include "conftst'$i'.h"' >> sub/conftest.c + # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with + # Solaris 8's {/usr,}/bin/sh. + touch sub/conftst$i.h + done + echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf + + # We check with `-c' and `-o' for the sake of the "dashmstdout" + # mode. It turns out that the SunPro C++ compiler does not properly + # handle `-M -o', and we need to detect this. Also, some Intel + # versions had trouble with output in subdirs + am__obj=sub/conftest.${OBJEXT-o} + am__minus_obj="-o $am__obj" + case $depmode in + gcc) + # This depmode causes a compiler race in universal mode. + test "$am__universal" = false || continue + ;; + nosideeffect) + # after this tag, mechanisms are not by side-effect, so they'll + # only be used when explicitly requested + if test "x$enable_dependency_tracking" = xyes; then + continue + else + break + fi + ;; + msvc7 | msvc7msys | msvisualcpp | msvcmsys) + # This compiler won't grok `-c -o', but also, the minuso test has + # not run yet. These depmodes are late enough in the game, and + # so weak that their functioning should not be impacted. + am__obj=conftest.${OBJEXT-o} + am__minus_obj= + ;; + none) break ;; + esac + if depmode=$depmode \ + source=sub/conftest.c object=$am__obj \ + depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ + $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ + >/dev/null 2>conftest.err && + grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && + grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && + grep $am__obj sub/conftest.Po > /dev/null 2>&1 && + ${MAKE-make} -s -f confmf > /dev/null 2>&1; then + # icc doesn't choke on unknown options, it will just issue warnings + # or remarks (even with -Werror). So we grep stderr for any message + # that says an option was ignored or not supported. + # When given -MP, icc 7.0 and 7.1 complain thusly: + # icc: Command line warning: ignoring option '-M'; no argument required + # The diagnosis changed in icc 8.0: + # icc: Command line remark: option '-MP' not supported + if (grep 'ignoring option' conftest.err || + grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else + am_cv_$1_dependencies_compiler_type=$depmode + break + fi + fi + done + + cd .. + rm -rf conftest.dir +else + am_cv_$1_dependencies_compiler_type=none +fi +]) +AC_SUBST([$1DEPMODE], [depmode=$am_cv_$1_dependencies_compiler_type]) +AM_CONDITIONAL([am__fastdep$1], [ + test "x$enable_dependency_tracking" != xno \ + && test "$am_cv_$1_dependencies_compiler_type" = gcc3]) +]) + + +# AM_SET_DEPDIR +# ------------- +# Choose a directory name for dependency files. +# This macro is AC_REQUIREd in _AM_DEPENDENCIES +AC_DEFUN([AM_SET_DEPDIR], +[AC_REQUIRE([AM_SET_LEADING_DOT])dnl +AC_SUBST([DEPDIR], ["${am__leading_dot}deps"])dnl +]) + + +# AM_DEP_TRACK +# ------------ +AC_DEFUN([AM_DEP_TRACK], +[AC_ARG_ENABLE(dependency-tracking, +[ --disable-dependency-tracking speeds up one-time build + --enable-dependency-tracking do not reject slow dependency extractors]) +if test "x$enable_dependency_tracking" != xno; then + am_depcomp="$ac_aux_dir/depcomp" + AMDEPBACKSLASH='\' + am__nodep='_no' +fi +AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno]) +AC_SUBST([AMDEPBACKSLASH])dnl +_AM_SUBST_NOTMAKE([AMDEPBACKSLASH])dnl +AC_SUBST([am__nodep])dnl +_AM_SUBST_NOTMAKE([am__nodep])dnl +]) + +# Generate code to set up dependency tracking. -*- Autoconf -*- + +# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2008 +# Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +#serial 5 + +# _AM_OUTPUT_DEPENDENCY_COMMANDS +# ------------------------------ +AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS], +[{ + # Autoconf 2.62 quotes --file arguments for eval, but not when files + # are listed without --file. Let's play safe and only enable the eval + # if we detect the quoting. + case $CONFIG_FILES in + *\'*) eval set x "$CONFIG_FILES" ;; + *) set x $CONFIG_FILES ;; + esac + shift + for mf + do + # Strip MF so we end up with the name of the file. + mf=`echo "$mf" | sed -e 's/:.*$//'` + # Check whether this is an Automake generated Makefile or not. + # We used to match only the files named `Makefile.in', but + # some people rename them; so instead we look at the file content. + # Grep'ing the first line is not enough: some people post-process + # each Makefile.in and add a new line on top of each file to say so. + # Grep'ing the whole file is not good either: AIX grep has a line + # limit of 2048, but all sed's we know have understand at least 4000. + if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then + dirpart=`AS_DIRNAME("$mf")` + else + continue + fi + # Extract the definition of DEPDIR, am__include, and am__quote + # from the Makefile without running `make'. + DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` + test -z "$DEPDIR" && continue + am__include=`sed -n 's/^am__include = //p' < "$mf"` + test -z "am__include" && continue + am__quote=`sed -n 's/^am__quote = //p' < "$mf"` + # When using ansi2knr, U may be empty or an underscore; expand it + U=`sed -n 's/^U = //p' < "$mf"` + # Find all dependency output files, they are included files with + # $(DEPDIR) in their names. We invoke sed twice because it is the + # simplest approach to changing $(DEPDIR) to its actual value in the + # expansion. + for file in `sed -n " + s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ + sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do + # Make sure the directory exists. + test -f "$dirpart/$file" && continue + fdir=`AS_DIRNAME(["$file"])` + AS_MKDIR_P([$dirpart/$fdir]) + # echo "creating $dirpart/$file" + echo '# dummy' > "$dirpart/$file" + done + done +} +])# _AM_OUTPUT_DEPENDENCY_COMMANDS + + +# AM_OUTPUT_DEPENDENCY_COMMANDS +# ----------------------------- +# This macro should only be invoked once -- use via AC_REQUIRE. +# +# This code is only required when automatic dependency tracking +# is enabled. FIXME. This creates each `.P' file that we will +# need in order to bootstrap the dependency handling code. +AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS], +[AC_CONFIG_COMMANDS([depfiles], + [test x"$AMDEP_TRUE" != x"" || _AM_OUTPUT_DEPENDENCY_COMMANDS], + [AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"]) +]) + +# Do all the work for Automake. -*- Autoconf -*- + +# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, +# 2005, 2006, 2008, 2009 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 16 + +# This macro actually does too much. Some checks are only needed if +# your package does certain things. But this isn't really a big deal. + +# AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE]) +# AM_INIT_AUTOMAKE([OPTIONS]) +# ----------------------------------------------- +# The call with PACKAGE and VERSION arguments is the old style +# call (pre autoconf-2.50), which is being phased out. PACKAGE +# and VERSION should now be passed to AC_INIT and removed from +# the call to AM_INIT_AUTOMAKE. +# We support both call styles for the transition. After +# the next Automake release, Autoconf can make the AC_INIT +# arguments mandatory, and then we can depend on a new Autoconf +# release and drop the old call support. +AC_DEFUN([AM_INIT_AUTOMAKE], +[AC_PREREQ([2.62])dnl +dnl Autoconf wants to disallow AM_ names. We explicitly allow +dnl the ones we care about. +m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl +AC_REQUIRE([AM_SET_CURRENT_AUTOMAKE_VERSION])dnl +AC_REQUIRE([AC_PROG_INSTALL])dnl +if test "`cd $srcdir && pwd`" != "`pwd`"; then + # Use -I$(srcdir) only when $(srcdir) != ., so that make's output + # is not polluted with repeated "-I." + AC_SUBST([am__isrc], [' -I$(srcdir)'])_AM_SUBST_NOTMAKE([am__isrc])dnl + # test to see if srcdir already configured + if test -f $srcdir/config.status; then + AC_MSG_ERROR([source directory already configured; run "make distclean" there first]) + fi +fi + +# test whether we have cygpath +if test -z "$CYGPATH_W"; then + if (cygpath --version) >/dev/null 2>/dev/null; then + CYGPATH_W='cygpath -w' + else + CYGPATH_W=echo + fi +fi +AC_SUBST([CYGPATH_W]) + +# Define the identity of the package. +dnl Distinguish between old-style and new-style calls. +m4_ifval([$2], +[m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl + AC_SUBST([PACKAGE], [$1])dnl + AC_SUBST([VERSION], [$2])], +[_AM_SET_OPTIONS([$1])dnl +dnl Diagnose old-style AC_INIT with new-style AM_AUTOMAKE_INIT. +m4_if(m4_ifdef([AC_PACKAGE_NAME], 1)m4_ifdef([AC_PACKAGE_VERSION], 1), 11,, + [m4_fatal([AC_INIT should be called with package and version arguments])])dnl + AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl + AC_SUBST([VERSION], ['AC_PACKAGE_VERSION'])])dnl + +_AM_IF_OPTION([no-define],, +[AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE", [Name of package]) + AC_DEFINE_UNQUOTED(VERSION, "$VERSION", [Version number of package])])dnl + +# Some tools Automake needs. +AC_REQUIRE([AM_SANITY_CHECK])dnl +AC_REQUIRE([AC_ARG_PROGRAM])dnl +AM_MISSING_PROG(ACLOCAL, aclocal-${am__api_version}) +AM_MISSING_PROG(AUTOCONF, autoconf) +AM_MISSING_PROG(AUTOMAKE, automake-${am__api_version}) +AM_MISSING_PROG(AUTOHEADER, autoheader) +AM_MISSING_PROG(MAKEINFO, makeinfo) +AC_REQUIRE([AM_PROG_INSTALL_SH])dnl +AC_REQUIRE([AM_PROG_INSTALL_STRIP])dnl +AC_REQUIRE([AM_PROG_MKDIR_P])dnl +# We need awk for the "check" target. The system "awk" is bad on +# some platforms. +AC_REQUIRE([AC_PROG_AWK])dnl +AC_REQUIRE([AC_PROG_MAKE_SET])dnl +AC_REQUIRE([AM_SET_LEADING_DOT])dnl +_AM_IF_OPTION([tar-ustar], [_AM_PROG_TAR([ustar])], + [_AM_IF_OPTION([tar-pax], [_AM_PROG_TAR([pax])], + [_AM_PROG_TAR([v7])])]) +_AM_IF_OPTION([no-dependencies],, +[AC_PROVIDE_IFELSE([AC_PROG_CC], + [_AM_DEPENDENCIES(CC)], + [define([AC_PROG_CC], + defn([AC_PROG_CC])[_AM_DEPENDENCIES(CC)])])dnl +AC_PROVIDE_IFELSE([AC_PROG_CXX], + [_AM_DEPENDENCIES(CXX)], + [define([AC_PROG_CXX], + defn([AC_PROG_CXX])[_AM_DEPENDENCIES(CXX)])])dnl +AC_PROVIDE_IFELSE([AC_PROG_OBJC], + [_AM_DEPENDENCIES(OBJC)], + [define([AC_PROG_OBJC], + defn([AC_PROG_OBJC])[_AM_DEPENDENCIES(OBJC)])])dnl +]) +_AM_IF_OPTION([silent-rules], [AC_REQUIRE([AM_SILENT_RULES])])dnl +dnl The `parallel-tests' driver may need to know about EXEEXT, so add the +dnl `am__EXEEXT' conditional if _AM_COMPILER_EXEEXT was seen. This macro +dnl is hooked onto _AC_COMPILER_EXEEXT early, see below. +AC_CONFIG_COMMANDS_PRE(dnl +[m4_provide_if([_AM_COMPILER_EXEEXT], + [AM_CONDITIONAL([am__EXEEXT], [test -n "$EXEEXT"])])])dnl +]) + +dnl Hook into `_AC_COMPILER_EXEEXT' early to learn its expansion. Do not +dnl add the conditional right here, as _AC_COMPILER_EXEEXT may be further +dnl mangled by Autoconf and run in a shell conditional statement. +m4_define([_AC_COMPILER_EXEEXT], +m4_defn([_AC_COMPILER_EXEEXT])[m4_provide([_AM_COMPILER_EXEEXT])]) + + +# When config.status generates a header, we must update the stamp-h file. +# This file resides in the same directory as the config header +# that is generated. The stamp files are numbered to have different names. + +# Autoconf calls _AC_AM_CONFIG_HEADER_HOOK (when defined) in the +# loop where config.status creates the headers, so we can generate +# our stamp files there. +AC_DEFUN([_AC_AM_CONFIG_HEADER_HOOK], +[# Compute $1's index in $config_headers. +_am_arg=$1 +_am_stamp_count=1 +for _am_header in $config_headers :; do + case $_am_header in + $_am_arg | $_am_arg:* ) + break ;; + * ) + _am_stamp_count=`expr $_am_stamp_count + 1` ;; + esac +done +echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count]) + +# Copyright (C) 2001, 2003, 2005, 2008, 2011 Free Software Foundation, +# Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 1 + +# AM_PROG_INSTALL_SH +# ------------------ +# Define $install_sh. +AC_DEFUN([AM_PROG_INSTALL_SH], +[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl +if test x"${install_sh}" != xset; then + case $am_aux_dir in + *\ * | *\ *) + install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;; + *) + install_sh="\${SHELL} $am_aux_dir/install-sh" + esac +fi +AC_SUBST(install_sh)]) + +# Copyright (C) 2003, 2005 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 2 + +# Check whether the underlying file-system supports filenames +# with a leading dot. For instance MS-DOS doesn't. +AC_DEFUN([AM_SET_LEADING_DOT], +[rm -rf .tst 2>/dev/null +mkdir .tst 2>/dev/null +if test -d .tst; then + am__leading_dot=. +else + am__leading_dot=_ +fi +rmdir .tst 2>/dev/null +AC_SUBST([am__leading_dot])]) + +# Check to see how 'make' treats includes. -*- Autoconf -*- + +# Copyright (C) 2001, 2002, 2003, 2005, 2009 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 4 + +# AM_MAKE_INCLUDE() +# ----------------- +# Check to see how make treats includes. +AC_DEFUN([AM_MAKE_INCLUDE], +[am_make=${MAKE-make} +cat > confinc << 'END' +am__doit: + @echo this is the am__doit target +.PHONY: am__doit +END +# If we don't find an include directive, just comment out the code. +AC_MSG_CHECKING([for style of include used by $am_make]) +am__include="#" +am__quote= +_am_result=none +# First try GNU make style include. +echo "include confinc" > confmf +# Ignore all kinds of additional output from `make'. +case `$am_make -s -f confmf 2> /dev/null` in #( +*the\ am__doit\ target*) + am__include=include + am__quote= + _am_result=GNU + ;; +esac +# Now try BSD make style include. +if test "$am__include" = "#"; then + echo '.include "confinc"' > confmf + case `$am_make -s -f confmf 2> /dev/null` in #( + *the\ am__doit\ target*) + am__include=.include + am__quote="\"" + _am_result=BSD + ;; + esac +fi +AC_SUBST([am__include]) +AC_SUBST([am__quote]) +AC_MSG_RESULT([$_am_result]) +rm -f confinc confmf +]) + +# Fake the existence of programs that GNU maintainers use. -*- Autoconf -*- + +# Copyright (C) 1997, 1999, 2000, 2001, 2003, 2004, 2005, 2008 +# Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 6 + +# AM_MISSING_PROG(NAME, PROGRAM) +# ------------------------------ +AC_DEFUN([AM_MISSING_PROG], +[AC_REQUIRE([AM_MISSING_HAS_RUN]) +$1=${$1-"${am_missing_run}$2"} +AC_SUBST($1)]) + + +# AM_MISSING_HAS_RUN +# ------------------ +# Define MISSING if not defined so far and test if it supports --run. +# If it does, set am_missing_run to use it, otherwise, to nothing. +AC_DEFUN([AM_MISSING_HAS_RUN], +[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl +AC_REQUIRE_AUX_FILE([missing])dnl +if test x"${MISSING+set}" != xset; then + case $am_aux_dir in + *\ * | *\ *) + MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;; + *) + MISSING="\${SHELL} $am_aux_dir/missing" ;; + esac +fi +# Use eval to expand $SHELL +if eval "$MISSING --run true"; then + am_missing_run="$MISSING --run " +else + am_missing_run= + AC_MSG_WARN([`missing' script is too old or missing]) +fi +]) + +# Copyright (C) 2003, 2004, 2005, 2006, 2011 Free Software Foundation, +# Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 1 + +# AM_PROG_MKDIR_P +# --------------- +# Check for `mkdir -p'. +AC_DEFUN([AM_PROG_MKDIR_P], +[AC_PREREQ([2.60])dnl +AC_REQUIRE([AC_PROG_MKDIR_P])dnl +dnl Automake 1.8 to 1.9.6 used to define mkdir_p. We now use MKDIR_P, +dnl while keeping a definition of mkdir_p for backward compatibility. +dnl @MKDIR_P@ is magic: AC_OUTPUT adjusts its value for each Makefile. +dnl However we cannot define mkdir_p as $(MKDIR_P) for the sake of +dnl Makefile.ins that do not define MKDIR_P, so we do our own +dnl adjustment using top_builddir (which is defined more often than +dnl MKDIR_P). +AC_SUBST([mkdir_p], ["$MKDIR_P"])dnl +case $mkdir_p in + [[\\/$]]* | ?:[[\\/]]*) ;; + */*) mkdir_p="\$(top_builddir)/$mkdir_p" ;; +esac +]) + +# Helper functions for option handling. -*- Autoconf -*- + +# Copyright (C) 2001, 2002, 2003, 2005, 2008, 2010 Free Software +# Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 5 + +# _AM_MANGLE_OPTION(NAME) +# ----------------------- +AC_DEFUN([_AM_MANGLE_OPTION], +[[_AM_OPTION_]m4_bpatsubst($1, [[^a-zA-Z0-9_]], [_])]) + +# _AM_SET_OPTION(NAME) +# -------------------- +# Set option NAME. Presently that only means defining a flag for this option. +AC_DEFUN([_AM_SET_OPTION], +[m4_define(_AM_MANGLE_OPTION([$1]), 1)]) + +# _AM_SET_OPTIONS(OPTIONS) +# ------------------------ +# OPTIONS is a space-separated list of Automake options. +AC_DEFUN([_AM_SET_OPTIONS], +[m4_foreach_w([_AM_Option], [$1], [_AM_SET_OPTION(_AM_Option)])]) + +# _AM_IF_OPTION(OPTION, IF-SET, [IF-NOT-SET]) +# ------------------------------------------- +# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise. +AC_DEFUN([_AM_IF_OPTION], +[m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])]) + +# Check to make sure that the build environment is sane. -*- Autoconf -*- + +# Copyright (C) 1996, 1997, 2000, 2001, 2003, 2005, 2008 +# Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 5 + +# AM_SANITY_CHECK +# --------------- +AC_DEFUN([AM_SANITY_CHECK], +[AC_MSG_CHECKING([whether build environment is sane]) +# Just in case +sleep 1 +echo timestamp > conftest.file +# Reject unsafe characters in $srcdir or the absolute working directory +# name. Accept space and tab only in the latter. +am_lf=' +' +case `pwd` in + *[[\\\"\#\$\&\'\`$am_lf]]*) + AC_MSG_ERROR([unsafe absolute working directory name]);; +esac +case $srcdir in + *[[\\\"\#\$\&\'\`$am_lf\ \ ]]*) + AC_MSG_ERROR([unsafe srcdir value: `$srcdir']);; +esac + +# Do `set' in a subshell so we don't clobber the current shell's +# arguments. Must try -L first in case configure is actually a +# symlink; some systems play weird games with the mod time of symlinks +# (eg FreeBSD returns the mod time of the symlink's containing +# directory). +if ( + set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` + if test "$[*]" = "X"; then + # -L didn't work. + set X `ls -t "$srcdir/configure" conftest.file` + fi + rm -f conftest.file + if test "$[*]" != "X $srcdir/configure conftest.file" \ + && test "$[*]" != "X conftest.file $srcdir/configure"; then + + # If neither matched, then we have a broken ls. This can happen + # if, for instance, CONFIG_SHELL is bash and it inherits a + # broken ls alias from the environment. This has actually + # happened. Such a system could not be considered "sane". + AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken +alias in your environment]) + fi + + test "$[2]" = conftest.file + ) +then + # Ok. + : +else + AC_MSG_ERROR([newly created file is older than distributed files! +Check your system clock]) +fi +AC_MSG_RESULT(yes)]) + +# Copyright (C) 2001, 2003, 2005, 2011 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 1 + +# AM_PROG_INSTALL_STRIP +# --------------------- +# One issue with vendor `install' (even GNU) is that you can't +# specify the program used to strip binaries. This is especially +# annoying in cross-compiling environments, where the build's strip +# is unlikely to handle the host's binaries. +# Fortunately install-sh will honor a STRIPPROG variable, so we +# always use install-sh in `make install-strip', and initialize +# STRIPPROG with the value of the STRIP variable (set by the user). +AC_DEFUN([AM_PROG_INSTALL_STRIP], +[AC_REQUIRE([AM_PROG_INSTALL_SH])dnl +# Installed binaries are usually stripped using `strip' when the user +# run `make install-strip'. However `strip' might not be the right +# tool to use in cross-compilation environments, therefore Automake +# will honor the `STRIP' environment variable to overrule this program. +dnl Don't test for $cross_compiling = yes, because it might be `maybe'. +if test "$cross_compiling" != no; then + AC_CHECK_TOOL([STRIP], [strip], :) +fi +INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" +AC_SUBST([INSTALL_STRIP_PROGRAM])]) + +# Copyright (C) 2006, 2008, 2010 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 3 + +# _AM_SUBST_NOTMAKE(VARIABLE) +# --------------------------- +# Prevent Automake from outputting VARIABLE = @VARIABLE@ in Makefile.in. +# This macro is traced by Automake. +AC_DEFUN([_AM_SUBST_NOTMAKE]) + +# AM_SUBST_NOTMAKE(VARIABLE) +# -------------------------- +# Public sister of _AM_SUBST_NOTMAKE. +AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)]) + +# Check how to create a tarball. -*- Autoconf -*- + +# Copyright (C) 2004, 2005, 2012 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 2 + +# _AM_PROG_TAR(FORMAT) +# -------------------- +# Check how to create a tarball in format FORMAT. +# FORMAT should be one of `v7', `ustar', or `pax'. +# +# Substitute a variable $(am__tar) that is a command +# writing to stdout a FORMAT-tarball containing the directory +# $tardir. +# tardir=directory && $(am__tar) > result.tar +# +# Substitute a variable $(am__untar) that extract such +# a tarball read from stdin. +# $(am__untar) < result.tar +AC_DEFUN([_AM_PROG_TAR], +[# Always define AMTAR for backward compatibility. Yes, it's still used +# in the wild :-( We should find a proper way to deprecate it ... +AC_SUBST([AMTAR], ['$${TAR-tar}']) +m4_if([$1], [v7], + [am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -'], + [m4_case([$1], [ustar],, [pax],, + [m4_fatal([Unknown tar format])]) +AC_MSG_CHECKING([how to create a $1 tar archive]) +# Loop over all known methods to create a tar archive until one works. +_am_tools='gnutar m4_if([$1], [ustar], [plaintar]) pax cpio none' +_am_tools=${am_cv_prog_tar_$1-$_am_tools} +# Do not fold the above two line into one, because Tru64 sh and +# Solaris sh will not grok spaces in the rhs of `-'. +for _am_tool in $_am_tools +do + case $_am_tool in + gnutar) + for _am_tar in tar gnutar gtar; + do + AM_RUN_LOG([$_am_tar --version]) && break + done + am__tar="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$$tardir"' + am__tar_="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$tardir"' + am__untar="$_am_tar -xf -" + ;; + plaintar) + # Must skip GNU tar: if it does not support --format= it doesn't create + # ustar tarball either. + (tar --version) >/dev/null 2>&1 && continue + am__tar='tar chf - "$$tardir"' + am__tar_='tar chf - "$tardir"' + am__untar='tar xf -' + ;; + pax) + am__tar='pax -L -x $1 -w "$$tardir"' + am__tar_='pax -L -x $1 -w "$tardir"' + am__untar='pax -r' + ;; + cpio) + am__tar='find "$$tardir" -print | cpio -o -H $1 -L' + am__tar_='find "$tardir" -print | cpio -o -H $1 -L' + am__untar='cpio -i -H $1 -d' + ;; + none) + am__tar=false + am__tar_=false + am__untar=false + ;; + esac + + # If the value was cached, stop now. We just wanted to have am__tar + # and am__untar set. + test -n "${am_cv_prog_tar_$1}" && break + + # tar/untar a dummy directory, and stop if the command works + rm -rf conftest.dir + mkdir conftest.dir + echo GrepMe > conftest.dir/file + AM_RUN_LOG([tardir=conftest.dir && eval $am__tar_ >conftest.tar]) + rm -rf conftest.dir + if test -s conftest.tar; then + AM_RUN_LOG([$am__untar /dev/null 2>&1 && break + fi +done +rm -rf conftest.dir + +AC_CACHE_VAL([am_cv_prog_tar_$1], [am_cv_prog_tar_$1=$_am_tool]) +AC_MSG_RESULT([$am_cv_prog_tar_$1])]) +AC_SUBST([am__tar]) +AC_SUBST([am__untar]) +]) # _AM_PROG_TAR + diff --git a/web/server/h2o/libh2o/deps/yaml/config.h.in b/web/server/h2o/libh2o/deps/yaml/config.h.in new file mode 100644 index 00000000..18365460 --- /dev/null +++ b/web/server/h2o/libh2o/deps/yaml/config.h.in @@ -0,0 +1,80 @@ +/* config.h.in. Generated from configure.ac by autoheader. */ + +/* Define to 1 if you have the header file. */ +#undef HAVE_DLFCN_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_INTTYPES_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_MEMORY_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STDINT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STDLIB_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STRINGS_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STRING_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_STAT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_TYPES_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_UNISTD_H + +/* Define to the sub-directory in which libtool stores uninstalled libraries. + */ +#undef LT_OBJDIR + +/* Name of package */ +#undef PACKAGE + +/* Define to the address where bug reports for this package should be sent. */ +#undef PACKAGE_BUGREPORT + +/* Define to the full name of this package. */ +#undef PACKAGE_NAME + +/* Define to the full name and version of this package. */ +#undef PACKAGE_STRING + +/* Define to the one symbol short name of this package. */ +#undef PACKAGE_TARNAME + +/* Define to the home page for this package. */ +#undef PACKAGE_URL + +/* Define to the version of this package. */ +#undef PACKAGE_VERSION + +/* Define to 1 if you have the ANSI C header files. */ +#undef STDC_HEADERS + +/* Version number of package */ +#undef VERSION + +/* Define the major version number. */ +#undef YAML_VERSION_MAJOR + +/* Define the minor version number. */ +#undef YAML_VERSION_MINOR + +/* Define the patch version number. */ +#undef YAML_VERSION_PATCH + +/* Define the version string. */ +#undef YAML_VERSION_STRING + +/* Define to empty if `const' does not conform to ANSI C. */ +#undef const + +/* Define to `unsigned int' if does not define. */ +#undef size_t diff --git a/web/server/h2o/libh2o/deps/yaml/config/config.guess b/web/server/h2o/libh2o/deps/yaml/config/config.guess new file mode 100755 index 00000000..d622a44e --- /dev/null +++ b/web/server/h2o/libh2o/deps/yaml/config/config.guess @@ -0,0 +1,1530 @@ +#! /bin/sh +# Attempt to guess a canonical system name. +# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, +# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, +# 2011, 2012 Free Software Foundation, Inc. + +timestamp='2012-02-10' + +# This file is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + + +# Originally written by Per Bothner. Please send patches (context +# diff format) to and include a ChangeLog +# entry. +# +# This script attempts to guess a canonical system name similar to +# config.sub. If it succeeds, it prints the system name on stdout, and +# exits with 0. Otherwise, it exits with 1. +# +# You can get the latest version of this script from: +# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD + +me=`echo "$0" | sed -e 's,.*/,,'` + +usage="\ +Usage: $0 [OPTION] + +Output the configuration name of the system \`$me' is run on. + +Operation modes: + -h, --help print this help, then exit + -t, --time-stamp print date of last modification, then exit + -v, --version print version number, then exit + +Report bugs and patches to ." + +version="\ +GNU config.guess ($timestamp) + +Originally written by Per Bothner. +Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, +2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012 +Free Software Foundation, Inc. + +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." + +help=" +Try \`$me --help' for more information." + +# Parse command line +while test $# -gt 0 ; do + case $1 in + --time-stamp | --time* | -t ) + echo "$timestamp" ; exit ;; + --version | -v ) + echo "$version" ; exit ;; + --help | --h* | -h ) + echo "$usage"; exit ;; + -- ) # Stop option processing + shift; break ;; + - ) # Use stdin as input. + break ;; + -* ) + echo "$me: invalid option $1$help" >&2 + exit 1 ;; + * ) + break ;; + esac +done + +if test $# != 0; then + echo "$me: too many arguments$help" >&2 + exit 1 +fi + +trap 'exit 1' 1 2 15 + +# CC_FOR_BUILD -- compiler used by this script. Note that the use of a +# compiler to aid in system detection is discouraged as it requires +# temporary files to be created and, as you can see below, it is a +# headache to deal with in a portable fashion. + +# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still +# use `HOST_CC' if defined, but it is deprecated. + +# Portable tmp directory creation inspired by the Autoconf team. + +set_cc_for_build=' +trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ; +trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ; +: ${TMPDIR=/tmp} ; + { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } || + { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } || + { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } || + { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ; +dummy=$tmp/dummy ; +tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ; +case $CC_FOR_BUILD,$HOST_CC,$CC in + ,,) echo "int x;" > $dummy.c ; + for c in cc gcc c89 c99 ; do + if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then + CC_FOR_BUILD="$c"; break ; + fi ; + done ; + if test x"$CC_FOR_BUILD" = x ; then + CC_FOR_BUILD=no_compiler_found ; + fi + ;; + ,,*) CC_FOR_BUILD=$CC ;; + ,*,*) CC_FOR_BUILD=$HOST_CC ;; +esac ; set_cc_for_build= ;' + +# This is needed to find uname on a Pyramid OSx when run in the BSD universe. +# (ghazi@noc.rutgers.edu 1994-08-24) +if (test -f /.attbin/uname) >/dev/null 2>&1 ; then + PATH=$PATH:/.attbin ; export PATH +fi + +UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown +UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown +UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown +UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown + +# Note: order is significant - the case branches are not exclusive. + +case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in + *:NetBSD:*:*) + # NetBSD (nbsd) targets should (where applicable) match one or + # more of the tuples: *-*-netbsdelf*, *-*-netbsdaout*, + # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently + # switched to ELF, *-*-netbsd* would select the old + # object file format. This provides both forward + # compatibility and a consistent mechanism for selecting the + # object file format. + # + # Note: NetBSD doesn't particularly care about the vendor + # portion of the name. We always set it to "unknown". + sysctl="sysctl -n hw.machine_arch" + UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \ + /usr/sbin/$sysctl 2>/dev/null || echo unknown)` + case "${UNAME_MACHINE_ARCH}" in + armeb) machine=armeb-unknown ;; + arm*) machine=arm-unknown ;; + sh3el) machine=shl-unknown ;; + sh3eb) machine=sh-unknown ;; + sh5el) machine=sh5le-unknown ;; + *) machine=${UNAME_MACHINE_ARCH}-unknown ;; + esac + # The Operating System including object format, if it has switched + # to ELF recently, or will in the future. + case "${UNAME_MACHINE_ARCH}" in + arm*|i386|m68k|ns32k|sh3*|sparc|vax) + eval $set_cc_for_build + if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep -q __ELF__ + then + # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout). + # Return netbsd for either. FIX? + os=netbsd + else + os=netbsdelf + fi + ;; + *) + os=netbsd + ;; + esac + # The OS release + # Debian GNU/NetBSD machines have a different userland, and + # thus, need a distinct triplet. However, they do not need + # kernel version information, so it can be replaced with a + # suitable tag, in the style of linux-gnu. + case "${UNAME_VERSION}" in + Debian*) + release='-gnu' + ;; + *) + release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` + ;; + esac + # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: + # contains redundant information, the shorter form: + # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. + echo "${machine}-${os}${release}" + exit ;; + *:OpenBSD:*:*) + UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'` + echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE} + exit ;; + *:ekkoBSD:*:*) + echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE} + exit ;; + *:SolidBSD:*:*) + echo ${UNAME_MACHINE}-unknown-solidbsd${UNAME_RELEASE} + exit ;; + macppc:MirBSD:*:*) + echo powerpc-unknown-mirbsd${UNAME_RELEASE} + exit ;; + *:MirBSD:*:*) + echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE} + exit ;; + alpha:OSF1:*:*) + case $UNAME_RELEASE in + *4.0) + UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` + ;; + *5.*) + UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'` + ;; + esac + # According to Compaq, /usr/sbin/psrinfo has been available on + # OSF/1 and Tru64 systems produced since 1995. I hope that + # covers most systems running today. This code pipes the CPU + # types through head -n 1, so we only detect the type of CPU 0. + ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1` + case "$ALPHA_CPU_TYPE" in + "EV4 (21064)") + UNAME_MACHINE="alpha" ;; + "EV4.5 (21064)") + UNAME_MACHINE="alpha" ;; + "LCA4 (21066/21068)") + UNAME_MACHINE="alpha" ;; + "EV5 (21164)") + UNAME_MACHINE="alphaev5" ;; + "EV5.6 (21164A)") + UNAME_MACHINE="alphaev56" ;; + "EV5.6 (21164PC)") + UNAME_MACHINE="alphapca56" ;; + "EV5.7 (21164PC)") + UNAME_MACHINE="alphapca57" ;; + "EV6 (21264)") + UNAME_MACHINE="alphaev6" ;; + "EV6.7 (21264A)") + UNAME_MACHINE="alphaev67" ;; + "EV6.8CB (21264C)") + UNAME_MACHINE="alphaev68" ;; + "EV6.8AL (21264B)") + UNAME_MACHINE="alphaev68" ;; + "EV6.8CX (21264D)") + UNAME_MACHINE="alphaev68" ;; + "EV6.9A (21264/EV69A)") + UNAME_MACHINE="alphaev69" ;; + "EV7 (21364)") + UNAME_MACHINE="alphaev7" ;; + "EV7.9 (21364A)") + UNAME_MACHINE="alphaev79" ;; + esac + # A Pn.n version is a patched version. + # A Vn.n version is a released version. + # A Tn.n version is a released field test version. + # A Xn.n version is an unreleased experimental baselevel. + # 1.2 uses "1.2" for uname -r. + echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` + # Reset EXIT trap before exiting to avoid spurious non-zero exit code. + exitcode=$? + trap '' 0 + exit $exitcode ;; + Alpha\ *:Windows_NT*:*) + # How do we know it's Interix rather than the generic POSIX subsystem? + # Should we change UNAME_MACHINE based on the output of uname instead + # of the specific Alpha model? + echo alpha-pc-interix + exit ;; + 21064:Windows_NT:50:3) + echo alpha-dec-winnt3.5 + exit ;; + Amiga*:UNIX_System_V:4.0:*) + echo m68k-unknown-sysv4 + exit ;; + *:[Aa]miga[Oo][Ss]:*:*) + echo ${UNAME_MACHINE}-unknown-amigaos + exit ;; + *:[Mm]orph[Oo][Ss]:*:*) + echo ${UNAME_MACHINE}-unknown-morphos + exit ;; + *:OS/390:*:*) + echo i370-ibm-openedition + exit ;; + *:z/VM:*:*) + echo s390-ibm-zvmoe + exit ;; + *:OS400:*:*) + echo powerpc-ibm-os400 + exit ;; + arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) + echo arm-acorn-riscix${UNAME_RELEASE} + exit ;; + arm:riscos:*:*|arm:RISCOS:*:*) + echo arm-unknown-riscos + exit ;; + SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*) + echo hppa1.1-hitachi-hiuxmpp + exit ;; + Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*) + # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE. + if test "`(/bin/universe) 2>/dev/null`" = att ; then + echo pyramid-pyramid-sysv3 + else + echo pyramid-pyramid-bsd + fi + exit ;; + NILE*:*:*:dcosx) + echo pyramid-pyramid-svr4 + exit ;; + DRS?6000:unix:4.0:6*) + echo sparc-icl-nx6 + exit ;; + DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*) + case `/usr/bin/uname -p` in + sparc) echo sparc-icl-nx7; exit ;; + esac ;; + s390x:SunOS:*:*) + echo ${UNAME_MACHINE}-ibm-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + sun4H:SunOS:5.*:*) + echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) + echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + i86pc:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*) + echo i386-pc-auroraux${UNAME_RELEASE} + exit ;; + i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*) + eval $set_cc_for_build + SUN_ARCH="i386" + # If there is a compiler, see if it is configured for 64-bit objects. + # Note that the Sun cc does not turn __LP64__ into 1 like gcc does. + # This test works for both compilers. + if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then + if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \ + (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \ + grep IS_64BIT_ARCH >/dev/null + then + SUN_ARCH="x86_64" + fi + fi + echo ${SUN_ARCH}-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + sun4*:SunOS:6*:*) + # According to config.sub, this is the proper way to canonicalize + # SunOS6. Hard to guess exactly what SunOS6 will be like, but + # it's likely to be more like Solaris than SunOS4. + echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + sun4*:SunOS:*:*) + case "`/usr/bin/arch -k`" in + Series*|S4*) + UNAME_RELEASE=`uname -v` + ;; + esac + # Japanese Language versions have a version number like `4.1.3-JL'. + echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'` + exit ;; + sun3*:SunOS:*:*) + echo m68k-sun-sunos${UNAME_RELEASE} + exit ;; + sun*:*:4.2BSD:*) + UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` + test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3 + case "`/bin/arch`" in + sun3) + echo m68k-sun-sunos${UNAME_RELEASE} + ;; + sun4) + echo sparc-sun-sunos${UNAME_RELEASE} + ;; + esac + exit ;; + aushp:SunOS:*:*) + echo sparc-auspex-sunos${UNAME_RELEASE} + exit ;; + # The situation for MiNT is a little confusing. The machine name + # can be virtually everything (everything which is not + # "atarist" or "atariste" at least should have a processor + # > m68000). The system name ranges from "MiNT" over "FreeMiNT" + # to the lowercase version "mint" (or "freemint"). Finally + # the system name "TOS" denotes a system which is actually not + # MiNT. But MiNT is downward compatible to TOS, so this should + # be no problem. + atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit ;; + atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit ;; + *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit ;; + milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) + echo m68k-milan-mint${UNAME_RELEASE} + exit ;; + hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) + echo m68k-hades-mint${UNAME_RELEASE} + exit ;; + *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) + echo m68k-unknown-mint${UNAME_RELEASE} + exit ;; + m68k:machten:*:*) + echo m68k-apple-machten${UNAME_RELEASE} + exit ;; + powerpc:machten:*:*) + echo powerpc-apple-machten${UNAME_RELEASE} + exit ;; + RISC*:Mach:*:*) + echo mips-dec-mach_bsd4.3 + exit ;; + RISC*:ULTRIX:*:*) + echo mips-dec-ultrix${UNAME_RELEASE} + exit ;; + VAX*:ULTRIX*:*:*) + echo vax-dec-ultrix${UNAME_RELEASE} + exit ;; + 2020:CLIX:*:* | 2430:CLIX:*:*) + echo clipper-intergraph-clix${UNAME_RELEASE} + exit ;; + mips:*:*:UMIPS | mips:*:*:RISCos) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c +#ifdef __cplusplus +#include /* for printf() prototype */ + int main (int argc, char *argv[]) { +#else + int main (argc, argv) int argc; char *argv[]; { +#endif + #if defined (host_mips) && defined (MIPSEB) + #if defined (SYSTYPE_SYSV) + printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0); + #endif + #if defined (SYSTYPE_SVR4) + printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0); + #endif + #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD) + printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0); + #endif + #endif + exit (-1); + } +EOF + $CC_FOR_BUILD -o $dummy $dummy.c && + dummyarg=`echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` && + SYSTEM_NAME=`$dummy $dummyarg` && + { echo "$SYSTEM_NAME"; exit; } + echo mips-mips-riscos${UNAME_RELEASE} + exit ;; + Motorola:PowerMAX_OS:*:*) + echo powerpc-motorola-powermax + exit ;; + Motorola:*:4.3:PL8-*) + echo powerpc-harris-powermax + exit ;; + Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*) + echo powerpc-harris-powermax + exit ;; + Night_Hawk:Power_UNIX:*:*) + echo powerpc-harris-powerunix + exit ;; + m88k:CX/UX:7*:*) + echo m88k-harris-cxux7 + exit ;; + m88k:*:4*:R4*) + echo m88k-motorola-sysv4 + exit ;; + m88k:*:3*:R3*) + echo m88k-motorola-sysv3 + exit ;; + AViiON:dgux:*:*) + # DG/UX returns AViiON for all architectures + UNAME_PROCESSOR=`/usr/bin/uname -p` + if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ] + then + if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \ + [ ${TARGET_BINARY_INTERFACE}x = x ] + then + echo m88k-dg-dgux${UNAME_RELEASE} + else + echo m88k-dg-dguxbcs${UNAME_RELEASE} + fi + else + echo i586-dg-dgux${UNAME_RELEASE} + fi + exit ;; + M88*:DolphinOS:*:*) # DolphinOS (SVR3) + echo m88k-dolphin-sysv3 + exit ;; + M88*:*:R3*:*) + # Delta 88k system running SVR3 + echo m88k-motorola-sysv3 + exit ;; + XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3) + echo m88k-tektronix-sysv3 + exit ;; + Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD) + echo m68k-tektronix-bsd + exit ;; + *:IRIX*:*:*) + echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'` + exit ;; + ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. + echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id + exit ;; # Note that: echo "'`uname -s`'" gives 'AIX ' + i*86:AIX:*:*) + echo i386-ibm-aix + exit ;; + ia64:AIX:*:*) + if [ -x /usr/bin/oslevel ] ; then + IBM_REV=`/usr/bin/oslevel` + else + IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} + fi + echo ${UNAME_MACHINE}-ibm-aix${IBM_REV} + exit ;; + *:AIX:2:3) + if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #include + + main() + { + if (!__power_pc()) + exit(1); + puts("powerpc-ibm-aix3.2.5"); + exit(0); + } +EOF + if $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` + then + echo "$SYSTEM_NAME" + else + echo rs6000-ibm-aix3.2.5 + fi + elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then + echo rs6000-ibm-aix3.2.4 + else + echo rs6000-ibm-aix3.2 + fi + exit ;; + *:AIX:*:[4567]) + IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'` + if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then + IBM_ARCH=rs6000 + else + IBM_ARCH=powerpc + fi + if [ -x /usr/bin/oslevel ] ; then + IBM_REV=`/usr/bin/oslevel` + else + IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} + fi + echo ${IBM_ARCH}-ibm-aix${IBM_REV} + exit ;; + *:AIX:*:*) + echo rs6000-ibm-aix + exit ;; + ibmrt:4.4BSD:*|romp-ibm:BSD:*) + echo romp-ibm-bsd4.4 + exit ;; + ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and + echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to + exit ;; # report: romp-ibm BSD 4.3 + *:BOSX:*:*) + echo rs6000-bull-bosx + exit ;; + DPX/2?00:B.O.S.:*:*) + echo m68k-bull-sysv3 + exit ;; + 9000/[34]??:4.3bsd:1.*:*) + echo m68k-hp-bsd + exit ;; + hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) + echo m68k-hp-bsd4.4 + exit ;; + 9000/[34678]??:HP-UX:*:*) + HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` + case "${UNAME_MACHINE}" in + 9000/31? ) HP_ARCH=m68000 ;; + 9000/[34]?? ) HP_ARCH=m68k ;; + 9000/[678][0-9][0-9]) + if [ -x /usr/bin/getconf ]; then + sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null` + sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` + case "${sc_cpu_version}" in + 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0 + 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1 + 532) # CPU_PA_RISC2_0 + case "${sc_kernel_bits}" in + 32) HP_ARCH="hppa2.0n" ;; + 64) HP_ARCH="hppa2.0w" ;; + '') HP_ARCH="hppa2.0" ;; # HP-UX 10.20 + esac ;; + esac + fi + if [ "${HP_ARCH}" = "" ]; then + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + + #define _HPUX_SOURCE + #include + #include + + int main () + { + #if defined(_SC_KERNEL_BITS) + long bits = sysconf(_SC_KERNEL_BITS); + #endif + long cpu = sysconf (_SC_CPU_VERSION); + + switch (cpu) + { + case CPU_PA_RISC1_0: puts ("hppa1.0"); break; + case CPU_PA_RISC1_1: puts ("hppa1.1"); break; + case CPU_PA_RISC2_0: + #if defined(_SC_KERNEL_BITS) + switch (bits) + { + case 64: puts ("hppa2.0w"); break; + case 32: puts ("hppa2.0n"); break; + default: puts ("hppa2.0"); break; + } break; + #else /* !defined(_SC_KERNEL_BITS) */ + puts ("hppa2.0"); break; + #endif + default: puts ("hppa1.0"); break; + } + exit (0); + } +EOF + (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy` + test -z "$HP_ARCH" && HP_ARCH=hppa + fi ;; + esac + if [ ${HP_ARCH} = "hppa2.0w" ] + then + eval $set_cc_for_build + + # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating + # 32-bit code. hppa64-hp-hpux* has the same kernel and a compiler + # generating 64-bit code. GNU and HP use different nomenclature: + # + # $ CC_FOR_BUILD=cc ./config.guess + # => hppa2.0w-hp-hpux11.23 + # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess + # => hppa64-hp-hpux11.23 + + if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | + grep -q __LP64__ + then + HP_ARCH="hppa2.0w" + else + HP_ARCH="hppa64" + fi + fi + echo ${HP_ARCH}-hp-hpux${HPUX_REV} + exit ;; + ia64:HP-UX:*:*) + HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` + echo ia64-hp-hpux${HPUX_REV} + exit ;; + 3050*:HI-UX:*:*) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #include + int + main () + { + long cpu = sysconf (_SC_CPU_VERSION); + /* The order matters, because CPU_IS_HP_MC68K erroneously returns + true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct + results, however. */ + if (CPU_IS_PA_RISC (cpu)) + { + switch (cpu) + { + case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break; + case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break; + case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break; + default: puts ("hppa-hitachi-hiuxwe2"); break; + } + } + else if (CPU_IS_HP_MC68K (cpu)) + puts ("m68k-hitachi-hiuxwe2"); + else puts ("unknown-hitachi-hiuxwe2"); + exit (0); + } +EOF + $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` && + { echo "$SYSTEM_NAME"; exit; } + echo unknown-hitachi-hiuxwe2 + exit ;; + 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* ) + echo hppa1.1-hp-bsd + exit ;; + 9000/8??:4.3bsd:*:*) + echo hppa1.0-hp-bsd + exit ;; + *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*) + echo hppa1.0-hp-mpeix + exit ;; + hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* ) + echo hppa1.1-hp-osf + exit ;; + hp8??:OSF1:*:*) + echo hppa1.0-hp-osf + exit ;; + i*86:OSF1:*:*) + if [ -x /usr/sbin/sysversion ] ; then + echo ${UNAME_MACHINE}-unknown-osf1mk + else + echo ${UNAME_MACHINE}-unknown-osf1 + fi + exit ;; + parisc*:Lites*:*:*) + echo hppa1.1-hp-lites + exit ;; + C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) + echo c1-convex-bsd + exit ;; + C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) + if getsysinfo -f scalar_acc + then echo c32-convex-bsd + else echo c2-convex-bsd + fi + exit ;; + C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) + echo c34-convex-bsd + exit ;; + C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) + echo c38-convex-bsd + exit ;; + C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) + echo c4-convex-bsd + exit ;; + CRAY*Y-MP:*:*:*) + echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*[A-Z]90:*:*:*) + echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \ + | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \ + -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \ + -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*TS:*:*:*) + echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*T3E:*:*:*) + echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*SV1:*:*:*) + echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + *:UNICOS/mp:*:*) + echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*) + FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` + FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` + FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'` + echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" + exit ;; + 5000:UNIX_System_V:4.*:*) + FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` + FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'` + echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" + exit ;; + i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) + echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE} + exit ;; + sparc*:BSD/OS:*:*) + echo sparc-unknown-bsdi${UNAME_RELEASE} + exit ;; + *:BSD/OS:*:*) + echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE} + exit ;; + *:FreeBSD:*:*) + UNAME_PROCESSOR=`/usr/bin/uname -p` + case ${UNAME_PROCESSOR} in + amd64) + echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; + *) + echo ${UNAME_PROCESSOR}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; + esac + exit ;; + i*:CYGWIN*:*) + echo ${UNAME_MACHINE}-pc-cygwin + exit ;; + *:MINGW*:*) + echo ${UNAME_MACHINE}-pc-mingw32 + exit ;; + i*:MSYS*:*) + echo ${UNAME_MACHINE}-pc-msys + exit ;; + i*:windows32*:*) + # uname -m includes "-pc" on this system. + echo ${UNAME_MACHINE}-mingw32 + exit ;; + i*:PW*:*) + echo ${UNAME_MACHINE}-pc-pw32 + exit ;; + *:Interix*:*) + case ${UNAME_MACHINE} in + x86) + echo i586-pc-interix${UNAME_RELEASE} + exit ;; + authenticamd | genuineintel | EM64T) + echo x86_64-unknown-interix${UNAME_RELEASE} + exit ;; + IA64) + echo ia64-unknown-interix${UNAME_RELEASE} + exit ;; + esac ;; + [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*) + echo i${UNAME_MACHINE}-pc-mks + exit ;; + 8664:Windows_NT:*) + echo x86_64-pc-mks + exit ;; + i*:Windows_NT*:* | Pentium*:Windows_NT*:*) + # How do we know it's Interix rather than the generic POSIX subsystem? + # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we + # UNAME_MACHINE based on the output of uname instead of i386? + echo i586-pc-interix + exit ;; + i*:UWIN*:*) + echo ${UNAME_MACHINE}-pc-uwin + exit ;; + amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*) + echo x86_64-unknown-cygwin + exit ;; + p*:CYGWIN*:*) + echo powerpcle-unknown-cygwin + exit ;; + prep*:SunOS:5.*:*) + echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + *:GNU:*:*) + # the GNU system + echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` + exit ;; + *:GNU/*:*:*) + # other systems with GNU libc and userland + echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-gnu + exit ;; + i*86:Minix:*:*) + echo ${UNAME_MACHINE}-pc-minix + exit ;; + aarch64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + aarch64_be:Linux:*:*) + UNAME_MACHINE=aarch64_be + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + alpha:Linux:*:*) + case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in + EV5) UNAME_MACHINE=alphaev5 ;; + EV56) UNAME_MACHINE=alphaev56 ;; + PCA56) UNAME_MACHINE=alphapca56 ;; + PCA57) UNAME_MACHINE=alphapca56 ;; + EV6) UNAME_MACHINE=alphaev6 ;; + EV67) UNAME_MACHINE=alphaev67 ;; + EV68*) UNAME_MACHINE=alphaev68 ;; + esac + objdump --private-headers /bin/sh | grep -q ld.so.1 + if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi + echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC} + exit ;; + arm*:Linux:*:*) + eval $set_cc_for_build + if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep -q __ARM_EABI__ + then + echo ${UNAME_MACHINE}-unknown-linux-gnu + else + if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep -q __ARM_PCS_VFP + then + echo ${UNAME_MACHINE}-unknown-linux-gnueabi + else + echo ${UNAME_MACHINE}-unknown-linux-gnueabihf + fi + fi + exit ;; + avr32*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + cris:Linux:*:*) + echo ${UNAME_MACHINE}-axis-linux-gnu + exit ;; + crisv32:Linux:*:*) + echo ${UNAME_MACHINE}-axis-linux-gnu + exit ;; + frv:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + hexagon:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + i*86:Linux:*:*) + LIBC=gnu + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #ifdef __dietlibc__ + LIBC=dietlibc + #endif +EOF + eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC'` + echo "${UNAME_MACHINE}-pc-linux-${LIBC}" + exit ;; + ia64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + m32r*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + m68*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + mips:Linux:*:* | mips64:Linux:*:*) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #undef CPU + #undef ${UNAME_MACHINE} + #undef ${UNAME_MACHINE}el + #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) + CPU=${UNAME_MACHINE}el + #else + #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) + CPU=${UNAME_MACHINE} + #else + CPU= + #endif + #endif +EOF + eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^CPU'` + test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; } + ;; + or32:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + padre:Linux:*:*) + echo sparc-unknown-linux-gnu + exit ;; + parisc64:Linux:*:* | hppa64:Linux:*:*) + echo hppa64-unknown-linux-gnu + exit ;; + parisc:Linux:*:* | hppa:Linux:*:*) + # Look for CPU level + case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in + PA7*) echo hppa1.1-unknown-linux-gnu ;; + PA8*) echo hppa2.0-unknown-linux-gnu ;; + *) echo hppa-unknown-linux-gnu ;; + esac + exit ;; + ppc64:Linux:*:*) + echo powerpc64-unknown-linux-gnu + exit ;; + ppc:Linux:*:*) + echo powerpc-unknown-linux-gnu + exit ;; + s390:Linux:*:* | s390x:Linux:*:*) + echo ${UNAME_MACHINE}-ibm-linux + exit ;; + sh64*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + sh*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + sparc:Linux:*:* | sparc64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + tile*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + vax:Linux:*:*) + echo ${UNAME_MACHINE}-dec-linux-gnu + exit ;; + x86_64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + xtensa*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + i*86:DYNIX/ptx:4*:*) + # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. + # earlier versions are messed up and put the nodename in both + # sysname and nodename. + echo i386-sequent-sysv4 + exit ;; + i*86:UNIX_SV:4.2MP:2.*) + # Unixware is an offshoot of SVR4, but it has its own version + # number series starting with 2... + # I am not positive that other SVR4 systems won't match this, + # I just have to hope. -- rms. + # Use sysv4.2uw... so that sysv4* matches it. + echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION} + exit ;; + i*86:OS/2:*:*) + # If we were able to find `uname', then EMX Unix compatibility + # is probably installed. + echo ${UNAME_MACHINE}-pc-os2-emx + exit ;; + i*86:XTS-300:*:STOP) + echo ${UNAME_MACHINE}-unknown-stop + exit ;; + i*86:atheos:*:*) + echo ${UNAME_MACHINE}-unknown-atheos + exit ;; + i*86:syllable:*:*) + echo ${UNAME_MACHINE}-pc-syllable + exit ;; + i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.[02]*:*) + echo i386-unknown-lynxos${UNAME_RELEASE} + exit ;; + i*86:*DOS:*:*) + echo ${UNAME_MACHINE}-pc-msdosdjgpp + exit ;; + i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*) + UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'` + if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then + echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL} + else + echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL} + fi + exit ;; + i*86:*:5:[678]*) + # UnixWare 7.x, OpenUNIX and OpenServer 6. + case `/bin/uname -X | grep "^Machine"` in + *486*) UNAME_MACHINE=i486 ;; + *Pentium) UNAME_MACHINE=i586 ;; + *Pent*|*Celeron) UNAME_MACHINE=i686 ;; + esac + echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION} + exit ;; + i*86:*:3.2:*) + if test -f /usr/options/cb.name; then + UNAME_REL=`sed -n 's/.*Version //p' /dev/null >/dev/null ; then + UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')` + (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486 + (/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \ + && UNAME_MACHINE=i586 + (/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \ + && UNAME_MACHINE=i686 + (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \ + && UNAME_MACHINE=i686 + echo ${UNAME_MACHINE}-pc-sco$UNAME_REL + else + echo ${UNAME_MACHINE}-pc-sysv32 + fi + exit ;; + pc:*:*:*) + # Left here for compatibility: + # uname -m prints for DJGPP always 'pc', but it prints nothing about + # the processor, so we play safe by assuming i586. + # Note: whatever this is, it MUST be the same as what config.sub + # prints for the "djgpp" host, or else GDB configury will decide that + # this is a cross-build. + echo i586-pc-msdosdjgpp + exit ;; + Intel:Mach:3*:*) + echo i386-pc-mach3 + exit ;; + paragon:*:*:*) + echo i860-intel-osf1 + exit ;; + i860:*:4.*:*) # i860-SVR4 + if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then + echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4 + else # Add other i860-SVR4 vendors below as they are discovered. + echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4 + fi + exit ;; + mini*:CTIX:SYS*5:*) + # "miniframe" + echo m68010-convergent-sysv + exit ;; + mc68k:UNIX:SYSTEM5:3.51m) + echo m68k-convergent-sysv + exit ;; + M680?0:D-NIX:5.3:*) + echo m68k-diab-dnix + exit ;; + M68*:*:R3V[5678]*:*) + test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;; + 3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0) + OS_REL='' + test -r /etc/.relid \ + && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && { echo i486-ncr-sysv4.3${OS_REL}; exit; } + /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ + && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; + 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && { echo i486-ncr-sysv4; exit; } ;; + NCR*:*:4.2:* | MPRAS*:*:4.2:*) + OS_REL='.3' + test -r /etc/.relid \ + && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && { echo i486-ncr-sysv4.3${OS_REL}; exit; } + /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ + && { echo i586-ncr-sysv4.3${OS_REL}; exit; } + /bin/uname -p 2>/dev/null | /bin/grep pteron >/dev/null \ + && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; + m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*) + echo m68k-unknown-lynxos${UNAME_RELEASE} + exit ;; + mc68030:UNIX_System_V:4.*:*) + echo m68k-atari-sysv4 + exit ;; + TSUNAMI:LynxOS:2.*:*) + echo sparc-unknown-lynxos${UNAME_RELEASE} + exit ;; + rs6000:LynxOS:2.*:*) + echo rs6000-unknown-lynxos${UNAME_RELEASE} + exit ;; + PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.[02]*:*) + echo powerpc-unknown-lynxos${UNAME_RELEASE} + exit ;; + SM[BE]S:UNIX_SV:*:*) + echo mips-dde-sysv${UNAME_RELEASE} + exit ;; + RM*:ReliantUNIX-*:*:*) + echo mips-sni-sysv4 + exit ;; + RM*:SINIX-*:*:*) + echo mips-sni-sysv4 + exit ;; + *:SINIX-*:*:*) + if uname -p 2>/dev/null >/dev/null ; then + UNAME_MACHINE=`(uname -p) 2>/dev/null` + echo ${UNAME_MACHINE}-sni-sysv4 + else + echo ns32k-sni-sysv + fi + exit ;; + PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort + # says + echo i586-unisys-sysv4 + exit ;; + *:UNIX_System_V:4*:FTX*) + # From Gerald Hewes . + # How about differentiating between stratus architectures? -djm + echo hppa1.1-stratus-sysv4 + exit ;; + *:*:*:FTX*) + # From seanf@swdc.stratus.com. + echo i860-stratus-sysv4 + exit ;; + i*86:VOS:*:*) + # From Paul.Green@stratus.com. + echo ${UNAME_MACHINE}-stratus-vos + exit ;; + *:VOS:*:*) + # From Paul.Green@stratus.com. + echo hppa1.1-stratus-vos + exit ;; + mc68*:A/UX:*:*) + echo m68k-apple-aux${UNAME_RELEASE} + exit ;; + news*:NEWS-OS:6*:*) + echo mips-sony-newsos6 + exit ;; + R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) + if [ -d /usr/nec ]; then + echo mips-nec-sysv${UNAME_RELEASE} + else + echo mips-unknown-sysv${UNAME_RELEASE} + fi + exit ;; + BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. + echo powerpc-be-beos + exit ;; + BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only. + echo powerpc-apple-beos + exit ;; + BePC:BeOS:*:*) # BeOS running on Intel PC compatible. + echo i586-pc-beos + exit ;; + BePC:Haiku:*:*) # Haiku running on Intel PC compatible. + echo i586-pc-haiku + exit ;; + SX-4:SUPER-UX:*:*) + echo sx4-nec-superux${UNAME_RELEASE} + exit ;; + SX-5:SUPER-UX:*:*) + echo sx5-nec-superux${UNAME_RELEASE} + exit ;; + SX-6:SUPER-UX:*:*) + echo sx6-nec-superux${UNAME_RELEASE} + exit ;; + SX-7:SUPER-UX:*:*) + echo sx7-nec-superux${UNAME_RELEASE} + exit ;; + SX-8:SUPER-UX:*:*) + echo sx8-nec-superux${UNAME_RELEASE} + exit ;; + SX-8R:SUPER-UX:*:*) + echo sx8r-nec-superux${UNAME_RELEASE} + exit ;; + Power*:Rhapsody:*:*) + echo powerpc-apple-rhapsody${UNAME_RELEASE} + exit ;; + *:Rhapsody:*:*) + echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE} + exit ;; + *:Darwin:*:*) + UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown + case $UNAME_PROCESSOR in + i386) + eval $set_cc_for_build + if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then + if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \ + (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \ + grep IS_64BIT_ARCH >/dev/null + then + UNAME_PROCESSOR="x86_64" + fi + fi ;; + unknown) UNAME_PROCESSOR=powerpc ;; + esac + echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE} + exit ;; + *:procnto*:*:* | *:QNX:[0123456789]*:*) + UNAME_PROCESSOR=`uname -p` + if test "$UNAME_PROCESSOR" = "x86"; then + UNAME_PROCESSOR=i386 + UNAME_MACHINE=pc + fi + echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE} + exit ;; + *:QNX:*:4*) + echo i386-pc-qnx + exit ;; + NEO-?:NONSTOP_KERNEL:*:*) + echo neo-tandem-nsk${UNAME_RELEASE} + exit ;; + NSE-?:NONSTOP_KERNEL:*:*) + echo nse-tandem-nsk${UNAME_RELEASE} + exit ;; + NSR-?:NONSTOP_KERNEL:*:*) + echo nsr-tandem-nsk${UNAME_RELEASE} + exit ;; + *:NonStop-UX:*:*) + echo mips-compaq-nonstopux + exit ;; + BS2000:POSIX*:*:*) + echo bs2000-siemens-sysv + exit ;; + DS/*:UNIX_System_V:*:*) + echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE} + exit ;; + *:Plan9:*:*) + # "uname -m" is not consistent, so use $cputype instead. 386 + # is converted to i386 for consistency with other x86 + # operating systems. + if test "$cputype" = "386"; then + UNAME_MACHINE=i386 + else + UNAME_MACHINE="$cputype" + fi + echo ${UNAME_MACHINE}-unknown-plan9 + exit ;; + *:TOPS-10:*:*) + echo pdp10-unknown-tops10 + exit ;; + *:TENEX:*:*) + echo pdp10-unknown-tenex + exit ;; + KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*) + echo pdp10-dec-tops20 + exit ;; + XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*) + echo pdp10-xkl-tops20 + exit ;; + *:TOPS-20:*:*) + echo pdp10-unknown-tops20 + exit ;; + *:ITS:*:*) + echo pdp10-unknown-its + exit ;; + SEI:*:*:SEIUX) + echo mips-sei-seiux${UNAME_RELEASE} + exit ;; + *:DragonFly:*:*) + echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` + exit ;; + *:*VMS:*:*) + UNAME_MACHINE=`(uname -p) 2>/dev/null` + case "${UNAME_MACHINE}" in + A*) echo alpha-dec-vms ; exit ;; + I*) echo ia64-dec-vms ; exit ;; + V*) echo vax-dec-vms ; exit ;; + esac ;; + *:XENIX:*:SysV) + echo i386-pc-xenix + exit ;; + i*86:skyos:*:*) + echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE}` | sed -e 's/ .*$//' + exit ;; + i*86:rdos:*:*) + echo ${UNAME_MACHINE}-pc-rdos + exit ;; + i*86:AROS:*:*) + echo ${UNAME_MACHINE}-pc-aros + exit ;; + x86_64:VMkernel:*:*) + echo ${UNAME_MACHINE}-unknown-esx + exit ;; +esac + +#echo '(No uname command or uname output not recognized.)' 1>&2 +#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2 + +eval $set_cc_for_build +cat >$dummy.c < +# include +#endif +main () +{ +#if defined (sony) +#if defined (MIPSEB) + /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed, + I don't know.... */ + printf ("mips-sony-bsd\n"); exit (0); +#else +#include + printf ("m68k-sony-newsos%s\n", +#ifdef NEWSOS4 + "4" +#else + "" +#endif + ); exit (0); +#endif +#endif + +#if defined (__arm) && defined (__acorn) && defined (__unix) + printf ("arm-acorn-riscix\n"); exit (0); +#endif + +#if defined (hp300) && !defined (hpux) + printf ("m68k-hp-bsd\n"); exit (0); +#endif + +#if defined (NeXT) +#if !defined (__ARCHITECTURE__) +#define __ARCHITECTURE__ "m68k" +#endif + int version; + version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`; + if (version < 4) + printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version); + else + printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version); + exit (0); +#endif + +#if defined (MULTIMAX) || defined (n16) +#if defined (UMAXV) + printf ("ns32k-encore-sysv\n"); exit (0); +#else +#if defined (CMU) + printf ("ns32k-encore-mach\n"); exit (0); +#else + printf ("ns32k-encore-bsd\n"); exit (0); +#endif +#endif +#endif + +#if defined (__386BSD__) + printf ("i386-pc-bsd\n"); exit (0); +#endif + +#if defined (sequent) +#if defined (i386) + printf ("i386-sequent-dynix\n"); exit (0); +#endif +#if defined (ns32000) + printf ("ns32k-sequent-dynix\n"); exit (0); +#endif +#endif + +#if defined (_SEQUENT_) + struct utsname un; + + uname(&un); + + if (strncmp(un.version, "V2", 2) == 0) { + printf ("i386-sequent-ptx2\n"); exit (0); + } + if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */ + printf ("i386-sequent-ptx1\n"); exit (0); + } + printf ("i386-sequent-ptx\n"); exit (0); + +#endif + +#if defined (vax) +# if !defined (ultrix) +# include +# if defined (BSD) +# if BSD == 43 + printf ("vax-dec-bsd4.3\n"); exit (0); +# else +# if BSD == 199006 + printf ("vax-dec-bsd4.3reno\n"); exit (0); +# else + printf ("vax-dec-bsd\n"); exit (0); +# endif +# endif +# else + printf ("vax-dec-bsd\n"); exit (0); +# endif +# else + printf ("vax-dec-ultrix\n"); exit (0); +# endif +#endif + +#if defined (alliant) && defined (i860) + printf ("i860-alliant-bsd\n"); exit (0); +#endif + + exit (1); +} +EOF + +$CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null && SYSTEM_NAME=`$dummy` && + { echo "$SYSTEM_NAME"; exit; } + +# Apollos put the system type in the environment. + +test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit; } + +# Convex versions that predate uname can use getsysinfo(1) + +if [ -x /usr/convex/getsysinfo ] +then + case `getsysinfo -f cpu_type` in + c1*) + echo c1-convex-bsd + exit ;; + c2*) + if getsysinfo -f scalar_acc + then echo c32-convex-bsd + else echo c2-convex-bsd + fi + exit ;; + c34*) + echo c34-convex-bsd + exit ;; + c38*) + echo c38-convex-bsd + exit ;; + c4*) + echo c4-convex-bsd + exit ;; + esac +fi + +cat >&2 < in order to provide the needed +information to handle your system. + +config.guess timestamp = $timestamp + +uname -m = `(uname -m) 2>/dev/null || echo unknown` +uname -r = `(uname -r) 2>/dev/null || echo unknown` +uname -s = `(uname -s) 2>/dev/null || echo unknown` +uname -v = `(uname -v) 2>/dev/null || echo unknown` + +/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null` +/bin/uname -X = `(/bin/uname -X) 2>/dev/null` + +hostinfo = `(hostinfo) 2>/dev/null` +/bin/universe = `(/bin/universe) 2>/dev/null` +/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null` +/bin/arch = `(/bin/arch) 2>/dev/null` +/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null` +/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null` + +UNAME_MACHINE = ${UNAME_MACHINE} +UNAME_RELEASE = ${UNAME_RELEASE} +UNAME_SYSTEM = ${UNAME_SYSTEM} +UNAME_VERSION = ${UNAME_VERSION} +EOF + +exit 1 + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "timestamp='" +# time-stamp-format: "%:y-%02m-%02d" +# time-stamp-end: "'" +# End: diff --git a/web/server/h2o/libh2o/deps/yaml/config/config.sub b/web/server/h2o/libh2o/deps/yaml/config/config.sub new file mode 100755 index 00000000..c894da45 --- /dev/null +++ b/web/server/h2o/libh2o/deps/yaml/config/config.sub @@ -0,0 +1,1773 @@ +#! /bin/sh +# Configuration validation subroutine script. +# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, +# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, +# 2011, 2012 Free Software Foundation, Inc. + +timestamp='2012-02-10' + +# This file is (in principle) common to ALL GNU software. +# The presence of a machine in this file suggests that SOME GNU software +# can handle that machine. It does not imply ALL GNU software can. +# +# This file is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + + +# Please send patches to . Submit a context +# diff and a properly formatted GNU ChangeLog entry. +# +# Configuration subroutine to validate and canonicalize a configuration type. +# Supply the specified configuration type as an argument. +# If it is invalid, we print an error message on stderr and exit with code 1. +# Otherwise, we print the canonical config type on stdout and succeed. + +# You can get the latest version of this script from: +# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD + +# This file is supposed to be the same for all GNU packages +# and recognize all the CPU types, system types and aliases +# that are meaningful with *any* GNU software. +# Each package is responsible for reporting which valid configurations +# it does not support. The user should be able to distinguish +# a failure to support a valid configuration from a meaningless +# configuration. + +# The goal of this file is to map all the various variations of a given +# machine specification into a single specification in the form: +# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM +# or in some cases, the newer four-part form: +# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM +# It is wrong to echo any other type of specification. + +me=`echo "$0" | sed -e 's,.*/,,'` + +usage="\ +Usage: $0 [OPTION] CPU-MFR-OPSYS + $0 [OPTION] ALIAS + +Canonicalize a configuration name. + +Operation modes: + -h, --help print this help, then exit + -t, --time-stamp print date of last modification, then exit + -v, --version print version number, then exit + +Report bugs and patches to ." + +version="\ +GNU config.sub ($timestamp) + +Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, +2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012 +Free Software Foundation, Inc. + +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." + +help=" +Try \`$me --help' for more information." + +# Parse command line +while test $# -gt 0 ; do + case $1 in + --time-stamp | --time* | -t ) + echo "$timestamp" ; exit ;; + --version | -v ) + echo "$version" ; exit ;; + --help | --h* | -h ) + echo "$usage"; exit ;; + -- ) # Stop option processing + shift; break ;; + - ) # Use stdin as input. + break ;; + -* ) + echo "$me: invalid option $1$help" + exit 1 ;; + + *local*) + # First pass through any local machine types. + echo $1 + exit ;; + + * ) + break ;; + esac +done + +case $# in + 0) echo "$me: missing argument$help" >&2 + exit 1;; + 1) ;; + *) echo "$me: too many arguments$help" >&2 + exit 1;; +esac + +# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any). +# Here we must recognize all the valid KERNEL-OS combinations. +maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'` +case $maybe_os in + nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc | linux-newlib* | \ + linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \ + knetbsd*-gnu* | netbsd*-gnu* | \ + kopensolaris*-gnu* | \ + storm-chaos* | os2-emx* | rtmk-nova*) + os=-$maybe_os + basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` + ;; + android-linux) + os=-linux-android + basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`-unknown + ;; + *) + basic_machine=`echo $1 | sed 's/-[^-]*$//'` + if [ $basic_machine != $1 ] + then os=`echo $1 | sed 's/.*-/-/'` + else os=; fi + ;; +esac + +### Let's recognize common machines as not being operating systems so +### that things like config.sub decstation-3100 work. We also +### recognize some manufacturers as not being operating systems, so we +### can provide default operating systems below. +case $os in + -sun*os*) + # Prevent following clause from handling this invalid input. + ;; + -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \ + -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \ + -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \ + -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\ + -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \ + -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \ + -apple | -axis | -knuth | -cray | -microblaze) + os= + basic_machine=$1 + ;; + -bluegene*) + os=-cnk + ;; + -sim | -cisco | -oki | -wec | -winbond) + os= + basic_machine=$1 + ;; + -scout) + ;; + -wrs) + os=-vxworks + basic_machine=$1 + ;; + -chorusos*) + os=-chorusos + basic_machine=$1 + ;; + -chorusrdb) + os=-chorusrdb + basic_machine=$1 + ;; + -hiux*) + os=-hiuxwe2 + ;; + -sco6) + os=-sco5v6 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco5) + os=-sco3.2v5 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco4) + os=-sco3.2v4 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco3.2.[4-9]*) + os=`echo $os | sed -e 's/sco3.2./sco3.2v/'` + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco3.2v[4-9]*) + # Don't forget version if it is 3.2v4 or newer. + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco5v6*) + # Don't forget version if it is 3.2v4 or newer. + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco*) + os=-sco3.2v2 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -udk*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -isc) + os=-isc2.2 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -clix*) + basic_machine=clipper-intergraph + ;; + -isc*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -lynx*) + os=-lynxos + ;; + -ptx*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'` + ;; + -windowsnt*) + os=`echo $os | sed -e 's/windowsnt/winnt/'` + ;; + -psos*) + os=-psos + ;; + -mint | -mint[0-9]*) + basic_machine=m68k-atari + os=-mint + ;; +esac + +# Decode aliases for certain CPU-COMPANY combinations. +case $basic_machine in + # Recognize the basic CPU types without company name. + # Some are omitted here because they have special meanings below. + 1750a | 580 \ + | a29k \ + | aarch64 | aarch64_be \ + | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \ + | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \ + | am33_2.0 \ + | arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr | avr32 \ + | be32 | be64 \ + | bfin \ + | c4x | clipper \ + | d10v | d30v | dlx | dsp16xx \ + | epiphany \ + | fido | fr30 | frv \ + | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ + | hexagon \ + | i370 | i860 | i960 | ia64 \ + | ip2k | iq2000 \ + | le32 | le64 \ + | lm32 \ + | m32c | m32r | m32rle | m68000 | m68k | m88k \ + | maxq | mb | microblaze | mcore | mep | metag \ + | mips | mipsbe | mipseb | mipsel | mipsle \ + | mips16 \ + | mips64 | mips64el \ + | mips64octeon | mips64octeonel \ + | mips64orion | mips64orionel \ + | mips64r5900 | mips64r5900el \ + | mips64vr | mips64vrel \ + | mips64vr4100 | mips64vr4100el \ + | mips64vr4300 | mips64vr4300el \ + | mips64vr5000 | mips64vr5000el \ + | mips64vr5900 | mips64vr5900el \ + | mipsisa32 | mipsisa32el \ + | mipsisa32r2 | mipsisa32r2el \ + | mipsisa64 | mipsisa64el \ + | mipsisa64r2 | mipsisa64r2el \ + | mipsisa64sb1 | mipsisa64sb1el \ + | mipsisa64sr71k | mipsisa64sr71kel \ + | mipstx39 | mipstx39el \ + | mn10200 | mn10300 \ + | moxie \ + | mt \ + | msp430 \ + | nds32 | nds32le | nds32be \ + | nios | nios2 \ + | ns16k | ns32k \ + | open8 \ + | or32 \ + | pdp10 | pdp11 | pj | pjl \ + | powerpc | powerpc64 | powerpc64le | powerpcle \ + | pyramid \ + | rl78 | rx \ + | score \ + | sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \ + | sh64 | sh64le \ + | sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \ + | sparcv8 | sparcv9 | sparcv9b | sparcv9v \ + | spu \ + | tahoe | tic4x | tic54x | tic55x | tic6x | tic80 | tron \ + | ubicom32 \ + | v850 | v850e | v850e1 | v850e2 | v850es | v850e2v3 \ + | we32k \ + | x86 | xc16x | xstormy16 | xtensa \ + | z8k | z80) + basic_machine=$basic_machine-unknown + ;; + c54x) + basic_machine=tic54x-unknown + ;; + c55x) + basic_machine=tic55x-unknown + ;; + c6x) + basic_machine=tic6x-unknown + ;; + m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | picochip) + basic_machine=$basic_machine-unknown + os=-none + ;; + m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k) + ;; + ms1) + basic_machine=mt-unknown + ;; + + strongarm | thumb | xscale) + basic_machine=arm-unknown + ;; + xgate) + basic_machine=$basic_machine-unknown + os=-none + ;; + xscaleeb) + basic_machine=armeb-unknown + ;; + + xscaleel) + basic_machine=armel-unknown + ;; + + # We use `pc' rather than `unknown' + # because (1) that's what they normally are, and + # (2) the word "unknown" tends to confuse beginning users. + i*86 | x86_64) + basic_machine=$basic_machine-pc + ;; + # Object if more than one company name word. + *-*-*) + echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 + exit 1 + ;; + # Recognize the basic CPU types with company name. + 580-* \ + | a29k-* \ + | aarch64-* | aarch64_be-* \ + | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \ + | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \ + | alphapca5[67]-* | alpha64pca5[67]-* | arc-* \ + | arm-* | armbe-* | armle-* | armeb-* | armv*-* \ + | avr-* | avr32-* \ + | be32-* | be64-* \ + | bfin-* | bs2000-* \ + | c[123]* | c30-* | [cjt]90-* | c4x-* \ + | clipper-* | craynv-* | cydra-* \ + | d10v-* | d30v-* | dlx-* \ + | elxsi-* \ + | f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \ + | h8300-* | h8500-* \ + | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \ + | hexagon-* \ + | i*86-* | i860-* | i960-* | ia64-* \ + | ip2k-* | iq2000-* \ + | le32-* | le64-* \ + | lm32-* \ + | m32c-* | m32r-* | m32rle-* \ + | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \ + | m88110-* | m88k-* | maxq-* | mcore-* | metag-* | microblaze-* \ + | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \ + | mips16-* \ + | mips64-* | mips64el-* \ + | mips64octeon-* | mips64octeonel-* \ + | mips64orion-* | mips64orionel-* \ + | mips64r5900-* | mips64r5900el-* \ + | mips64vr-* | mips64vrel-* \ + | mips64vr4100-* | mips64vr4100el-* \ + | mips64vr4300-* | mips64vr4300el-* \ + | mips64vr5000-* | mips64vr5000el-* \ + | mips64vr5900-* | mips64vr5900el-* \ + | mipsisa32-* | mipsisa32el-* \ + | mipsisa32r2-* | mipsisa32r2el-* \ + | mipsisa64-* | mipsisa64el-* \ + | mipsisa64r2-* | mipsisa64r2el-* \ + | mipsisa64sb1-* | mipsisa64sb1el-* \ + | mipsisa64sr71k-* | mipsisa64sr71kel-* \ + | mipstx39-* | mipstx39el-* \ + | mmix-* \ + | mt-* \ + | msp430-* \ + | nds32-* | nds32le-* | nds32be-* \ + | nios-* | nios2-* \ + | none-* | np1-* | ns16k-* | ns32k-* \ + | open8-* \ + | orion-* \ + | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ + | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \ + | pyramid-* \ + | rl78-* | romp-* | rs6000-* | rx-* \ + | sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \ + | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \ + | sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \ + | sparclite-* \ + | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | sv1-* | sx?-* \ + | tahoe-* \ + | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \ + | tile*-* \ + | tron-* \ + | ubicom32-* \ + | v850-* | v850e-* | v850e1-* | v850es-* | v850e2-* | v850e2v3-* \ + | vax-* \ + | we32k-* \ + | x86-* | x86_64-* | xc16x-* | xps100-* \ + | xstormy16-* | xtensa*-* \ + | ymp-* \ + | z8k-* | z80-*) + ;; + # Recognize the basic CPU types without company name, with glob match. + xtensa*) + basic_machine=$basic_machine-unknown + ;; + # Recognize the various machine names and aliases which stand + # for a CPU type and a company and sometimes even an OS. + 386bsd) + basic_machine=i386-unknown + os=-bsd + ;; + 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) + basic_machine=m68000-att + ;; + 3b*) + basic_machine=we32k-att + ;; + a29khif) + basic_machine=a29k-amd + os=-udi + ;; + abacus) + basic_machine=abacus-unknown + ;; + adobe68k) + basic_machine=m68010-adobe + os=-scout + ;; + alliant | fx80) + basic_machine=fx80-alliant + ;; + altos | altos3068) + basic_machine=m68k-altos + ;; + am29k) + basic_machine=a29k-none + os=-bsd + ;; + amd64) + basic_machine=x86_64-pc + ;; + amd64-*) + basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + amdahl) + basic_machine=580-amdahl + os=-sysv + ;; + amiga | amiga-*) + basic_machine=m68k-unknown + ;; + amigaos | amigados) + basic_machine=m68k-unknown + os=-amigaos + ;; + amigaunix | amix) + basic_machine=m68k-unknown + os=-sysv4 + ;; + apollo68) + basic_machine=m68k-apollo + os=-sysv + ;; + apollo68bsd) + basic_machine=m68k-apollo + os=-bsd + ;; + aros) + basic_machine=i386-pc + os=-aros + ;; + aux) + basic_machine=m68k-apple + os=-aux + ;; + balance) + basic_machine=ns32k-sequent + os=-dynix + ;; + blackfin) + basic_machine=bfin-unknown + os=-linux + ;; + blackfin-*) + basic_machine=bfin-`echo $basic_machine | sed 's/^[^-]*-//'` + os=-linux + ;; + bluegene*) + basic_machine=powerpc-ibm + os=-cnk + ;; + c54x-*) + basic_machine=tic54x-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + c55x-*) + basic_machine=tic55x-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + c6x-*) + basic_machine=tic6x-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + c90) + basic_machine=c90-cray + os=-unicos + ;; + cegcc) + basic_machine=arm-unknown + os=-cegcc + ;; + convex-c1) + basic_machine=c1-convex + os=-bsd + ;; + convex-c2) + basic_machine=c2-convex + os=-bsd + ;; + convex-c32) + basic_machine=c32-convex + os=-bsd + ;; + convex-c34) + basic_machine=c34-convex + os=-bsd + ;; + convex-c38) + basic_machine=c38-convex + os=-bsd + ;; + cray | j90) + basic_machine=j90-cray + os=-unicos + ;; + craynv) + basic_machine=craynv-cray + os=-unicosmp + ;; + cr16 | cr16-*) + basic_machine=cr16-unknown + os=-elf + ;; + crds | unos) + basic_machine=m68k-crds + ;; + crisv32 | crisv32-* | etraxfs*) + basic_machine=crisv32-axis + ;; + cris | cris-* | etrax*) + basic_machine=cris-axis + ;; + crx) + basic_machine=crx-unknown + os=-elf + ;; + da30 | da30-*) + basic_machine=m68k-da30 + ;; + decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn) + basic_machine=mips-dec + ;; + decsystem10* | dec10*) + basic_machine=pdp10-dec + os=-tops10 + ;; + decsystem20* | dec20*) + basic_machine=pdp10-dec + os=-tops20 + ;; + delta | 3300 | motorola-3300 | motorola-delta \ + | 3300-motorola | delta-motorola) + basic_machine=m68k-motorola + ;; + delta88) + basic_machine=m88k-motorola + os=-sysv3 + ;; + dicos) + basic_machine=i686-pc + os=-dicos + ;; + djgpp) + basic_machine=i586-pc + os=-msdosdjgpp + ;; + dpx20 | dpx20-*) + basic_machine=rs6000-bull + os=-bosx + ;; + dpx2* | dpx2*-bull) + basic_machine=m68k-bull + os=-sysv3 + ;; + ebmon29k) + basic_machine=a29k-amd + os=-ebmon + ;; + elxsi) + basic_machine=elxsi-elxsi + os=-bsd + ;; + encore | umax | mmax) + basic_machine=ns32k-encore + ;; + es1800 | OSE68k | ose68k | ose | OSE) + basic_machine=m68k-ericsson + os=-ose + ;; + fx2800) + basic_machine=i860-alliant + ;; + genix) + basic_machine=ns32k-ns + ;; + gmicro) + basic_machine=tron-gmicro + os=-sysv + ;; + go32) + basic_machine=i386-pc + os=-go32 + ;; + h3050r* | hiux*) + basic_machine=hppa1.1-hitachi + os=-hiuxwe2 + ;; + h8300hms) + basic_machine=h8300-hitachi + os=-hms + ;; + h8300xray) + basic_machine=h8300-hitachi + os=-xray + ;; + h8500hms) + basic_machine=h8500-hitachi + os=-hms + ;; + harris) + basic_machine=m88k-harris + os=-sysv3 + ;; + hp300-*) + basic_machine=m68k-hp + ;; + hp300bsd) + basic_machine=m68k-hp + os=-bsd + ;; + hp300hpux) + basic_machine=m68k-hp + os=-hpux + ;; + hp3k9[0-9][0-9] | hp9[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hp9k2[0-9][0-9] | hp9k31[0-9]) + basic_machine=m68000-hp + ;; + hp9k3[2-9][0-9]) + basic_machine=m68k-hp + ;; + hp9k6[0-9][0-9] | hp6[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hp9k7[0-79][0-9] | hp7[0-79][0-9]) + basic_machine=hppa1.1-hp + ;; + hp9k78[0-9] | hp78[0-9]) + # FIXME: really hppa2.0-hp + basic_machine=hppa1.1-hp + ;; + hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893) + # FIXME: really hppa2.0-hp + basic_machine=hppa1.1-hp + ;; + hp9k8[0-9][13679] | hp8[0-9][13679]) + basic_machine=hppa1.1-hp + ;; + hp9k8[0-9][0-9] | hp8[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hppa-next) + os=-nextstep3 + ;; + hppaosf) + basic_machine=hppa1.1-hp + os=-osf + ;; + hppro) + basic_machine=hppa1.1-hp + os=-proelf + ;; + i370-ibm* | ibm*) + basic_machine=i370-ibm + ;; + i*86v32) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv32 + ;; + i*86v4*) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv4 + ;; + i*86v) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv + ;; + i*86sol2) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-solaris2 + ;; + i386mach) + basic_machine=i386-mach + os=-mach + ;; + i386-vsta | vsta) + basic_machine=i386-unknown + os=-vsta + ;; + iris | iris4d) + basic_machine=mips-sgi + case $os in + -irix*) + ;; + *) + os=-irix4 + ;; + esac + ;; + isi68 | isi) + basic_machine=m68k-isi + os=-sysv + ;; + m68knommu) + basic_machine=m68k-unknown + os=-linux + ;; + m68knommu-*) + basic_machine=m68k-`echo $basic_machine | sed 's/^[^-]*-//'` + os=-linux + ;; + m88k-omron*) + basic_machine=m88k-omron + ;; + magnum | m3230) + basic_machine=mips-mips + os=-sysv + ;; + merlin) + basic_machine=ns32k-utek + os=-sysv + ;; + microblaze) + basic_machine=microblaze-xilinx + ;; + mingw32) + basic_machine=i386-pc + os=-mingw32 + ;; + mingw32ce) + basic_machine=arm-unknown + os=-mingw32ce + ;; + miniframe) + basic_machine=m68000-convergent + ;; + *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*) + basic_machine=m68k-atari + os=-mint + ;; + mips3*-*) + basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'` + ;; + mips3*) + basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown + ;; + monitor) + basic_machine=m68k-rom68k + os=-coff + ;; + morphos) + basic_machine=powerpc-unknown + os=-morphos + ;; + msdos) + basic_machine=i386-pc + os=-msdos + ;; + ms1-*) + basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'` + ;; + msys) + basic_machine=i386-pc + os=-msys + ;; + mvs) + basic_machine=i370-ibm + os=-mvs + ;; + nacl) + basic_machine=le32-unknown + os=-nacl + ;; + ncr3000) + basic_machine=i486-ncr + os=-sysv4 + ;; + netbsd386) + basic_machine=i386-unknown + os=-netbsd + ;; + netwinder) + basic_machine=armv4l-rebel + os=-linux + ;; + news | news700 | news800 | news900) + basic_machine=m68k-sony + os=-newsos + ;; + news1000) + basic_machine=m68030-sony + os=-newsos + ;; + news-3600 | risc-news) + basic_machine=mips-sony + os=-newsos + ;; + necv70) + basic_machine=v70-nec + os=-sysv + ;; + next | m*-next ) + basic_machine=m68k-next + case $os in + -nextstep* ) + ;; + -ns2*) + os=-nextstep2 + ;; + *) + os=-nextstep3 + ;; + esac + ;; + nh3000) + basic_machine=m68k-harris + os=-cxux + ;; + nh[45]000) + basic_machine=m88k-harris + os=-cxux + ;; + nindy960) + basic_machine=i960-intel + os=-nindy + ;; + mon960) + basic_machine=i960-intel + os=-mon960 + ;; + nonstopux) + basic_machine=mips-compaq + os=-nonstopux + ;; + np1) + basic_machine=np1-gould + ;; + neo-tandem) + basic_machine=neo-tandem + ;; + nse-tandem) + basic_machine=nse-tandem + ;; + nsr-tandem) + basic_machine=nsr-tandem + ;; + op50n-* | op60c-*) + basic_machine=hppa1.1-oki + os=-proelf + ;; + openrisc | openrisc-*) + basic_machine=or32-unknown + ;; + os400) + basic_machine=powerpc-ibm + os=-os400 + ;; + OSE68000 | ose68000) + basic_machine=m68000-ericsson + os=-ose + ;; + os68k) + basic_machine=m68k-none + os=-os68k + ;; + pa-hitachi) + basic_machine=hppa1.1-hitachi + os=-hiuxwe2 + ;; + paragon) + basic_machine=i860-intel + os=-osf + ;; + parisc) + basic_machine=hppa-unknown + os=-linux + ;; + parisc-*) + basic_machine=hppa-`echo $basic_machine | sed 's/^[^-]*-//'` + os=-linux + ;; + pbd) + basic_machine=sparc-tti + ;; + pbb) + basic_machine=m68k-tti + ;; + pc532 | pc532-*) + basic_machine=ns32k-pc532 + ;; + pc98) + basic_machine=i386-pc + ;; + pc98-*) + basic_machine=i386-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentium | p5 | k5 | k6 | nexgen | viac3) + basic_machine=i586-pc + ;; + pentiumpro | p6 | 6x86 | athlon | athlon_*) + basic_machine=i686-pc + ;; + pentiumii | pentium2 | pentiumiii | pentium3) + basic_machine=i686-pc + ;; + pentium4) + basic_machine=i786-pc + ;; + pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*) + basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentiumpro-* | p6-* | 6x86-* | athlon-*) + basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*) + basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentium4-*) + basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pn) + basic_machine=pn-gould + ;; + power) basic_machine=power-ibm + ;; + ppc | ppcbe) basic_machine=powerpc-unknown + ;; + ppc-* | ppcbe-*) + basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppcle | powerpclittle | ppc-le | powerpc-little) + basic_machine=powerpcle-unknown + ;; + ppcle-* | powerpclittle-*) + basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppc64) basic_machine=powerpc64-unknown + ;; + ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppc64le | powerpc64little | ppc64-le | powerpc64-little) + basic_machine=powerpc64le-unknown + ;; + ppc64le-* | powerpc64little-*) + basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ps2) + basic_machine=i386-ibm + ;; + pw32) + basic_machine=i586-unknown + os=-pw32 + ;; + rdos) + basic_machine=i386-pc + os=-rdos + ;; + rom68k) + basic_machine=m68k-rom68k + os=-coff + ;; + rm[46]00) + basic_machine=mips-siemens + ;; + rtpc | rtpc-*) + basic_machine=romp-ibm + ;; + s390 | s390-*) + basic_machine=s390-ibm + ;; + s390x | s390x-*) + basic_machine=s390x-ibm + ;; + sa29200) + basic_machine=a29k-amd + os=-udi + ;; + sb1) + basic_machine=mipsisa64sb1-unknown + ;; + sb1el) + basic_machine=mipsisa64sb1el-unknown + ;; + sde) + basic_machine=mipsisa32-sde + os=-elf + ;; + sei) + basic_machine=mips-sei + os=-seiux + ;; + sequent) + basic_machine=i386-sequent + ;; + sh) + basic_machine=sh-hitachi + os=-hms + ;; + sh5el) + basic_machine=sh5le-unknown + ;; + sh64) + basic_machine=sh64-unknown + ;; + sparclite-wrs | simso-wrs) + basic_machine=sparclite-wrs + os=-vxworks + ;; + sps7) + basic_machine=m68k-bull + os=-sysv2 + ;; + spur) + basic_machine=spur-unknown + ;; + st2000) + basic_machine=m68k-tandem + ;; + stratus) + basic_machine=i860-stratus + os=-sysv4 + ;; + strongarm-* | thumb-*) + basic_machine=arm-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + sun2) + basic_machine=m68000-sun + ;; + sun2os3) + basic_machine=m68000-sun + os=-sunos3 + ;; + sun2os4) + basic_machine=m68000-sun + os=-sunos4 + ;; + sun3os3) + basic_machine=m68k-sun + os=-sunos3 + ;; + sun3os4) + basic_machine=m68k-sun + os=-sunos4 + ;; + sun4os3) + basic_machine=sparc-sun + os=-sunos3 + ;; + sun4os4) + basic_machine=sparc-sun + os=-sunos4 + ;; + sun4sol2) + basic_machine=sparc-sun + os=-solaris2 + ;; + sun3 | sun3-*) + basic_machine=m68k-sun + ;; + sun4) + basic_machine=sparc-sun + ;; + sun386 | sun386i | roadrunner) + basic_machine=i386-sun + ;; + sv1) + basic_machine=sv1-cray + os=-unicos + ;; + symmetry) + basic_machine=i386-sequent + os=-dynix + ;; + t3e) + basic_machine=alphaev5-cray + os=-unicos + ;; + t90) + basic_machine=t90-cray + os=-unicos + ;; + tile*) + basic_machine=$basic_machine-unknown + os=-linux-gnu + ;; + tx39) + basic_machine=mipstx39-unknown + ;; + tx39el) + basic_machine=mipstx39el-unknown + ;; + toad1) + basic_machine=pdp10-xkl + os=-tops20 + ;; + tower | tower-32) + basic_machine=m68k-ncr + ;; + tpf) + basic_machine=s390x-ibm + os=-tpf + ;; + udi29k) + basic_machine=a29k-amd + os=-udi + ;; + ultra3) + basic_machine=a29k-nyu + os=-sym1 + ;; + v810 | necv810) + basic_machine=v810-nec + os=-none + ;; + vaxv) + basic_machine=vax-dec + os=-sysv + ;; + vms) + basic_machine=vax-dec + os=-vms + ;; + vpp*|vx|vx-*) + basic_machine=f301-fujitsu + ;; + vxworks960) + basic_machine=i960-wrs + os=-vxworks + ;; + vxworks68) + basic_machine=m68k-wrs + os=-vxworks + ;; + vxworks29k) + basic_machine=a29k-wrs + os=-vxworks + ;; + w65*) + basic_machine=w65-wdc + os=-none + ;; + w89k-*) + basic_machine=hppa1.1-winbond + os=-proelf + ;; + xbox) + basic_machine=i686-pc + os=-mingw32 + ;; + xps | xps100) + basic_machine=xps100-honeywell + ;; + xscale-* | xscalee[bl]-*) + basic_machine=`echo $basic_machine | sed 's/^xscale/arm/'` + ;; + ymp) + basic_machine=ymp-cray + os=-unicos + ;; + z8k-*-coff) + basic_machine=z8k-unknown + os=-sim + ;; + z80-*-coff) + basic_machine=z80-unknown + os=-sim + ;; + none) + basic_machine=none-none + os=-none + ;; + +# Here we handle the default manufacturer of certain CPU types. It is in +# some cases the only manufacturer, in others, it is the most popular. + w89k) + basic_machine=hppa1.1-winbond + ;; + op50n) + basic_machine=hppa1.1-oki + ;; + op60c) + basic_machine=hppa1.1-oki + ;; + romp) + basic_machine=romp-ibm + ;; + mmix) + basic_machine=mmix-knuth + ;; + rs6000) + basic_machine=rs6000-ibm + ;; + vax) + basic_machine=vax-dec + ;; + pdp10) + # there are many clones, so DEC is not a safe bet + basic_machine=pdp10-unknown + ;; + pdp11) + basic_machine=pdp11-dec + ;; + we32k) + basic_machine=we32k-att + ;; + sh[1234] | sh[24]a | sh[24]aeb | sh[34]eb | sh[1234]le | sh[23]ele) + basic_machine=sh-unknown + ;; + sparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v) + basic_machine=sparc-sun + ;; + cydra) + basic_machine=cydra-cydrome + ;; + orion) + basic_machine=orion-highlevel + ;; + orion105) + basic_machine=clipper-highlevel + ;; + mac | mpw | mac-mpw) + basic_machine=m68k-apple + ;; + pmac | pmac-mpw) + basic_machine=powerpc-apple + ;; + *-unknown) + # Make sure to match an already-canonicalized machine name. + ;; + *) + echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 + exit 1 + ;; +esac + +# Here we canonicalize certain aliases for manufacturers. +case $basic_machine in + *-digital*) + basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'` + ;; + *-commodore*) + basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'` + ;; + *) + ;; +esac + +# Decode manufacturer-specific aliases for certain operating systems. + +if [ x"$os" != x"" ] +then +case $os in + # First match some system type aliases + # that might get confused with valid system types. + # -solaris* is a basic system type, with this one exception. + -auroraux) + os=-auroraux + ;; + -solaris1 | -solaris1.*) + os=`echo $os | sed -e 's|solaris1|sunos4|'` + ;; + -solaris) + os=-solaris2 + ;; + -svr4*) + os=-sysv4 + ;; + -unixware*) + os=-sysv4.2uw + ;; + -gnu/linux*) + os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'` + ;; + # First accept the basic system types. + # The portable systems comes first. + # Each alternative MUST END IN A *, to match a version number. + # -sysv* is not here because it comes later, after sysvr4. + -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \ + | -*vms* | -sco* | -esix* | -isc* | -aix* | -cnk* | -sunos | -sunos[34]*\ + | -hpux* | -unos* | -osf* | -luna* | -dgux* | -auroraux* | -solaris* \ + | -sym* | -kopensolaris* \ + | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ + | -aos* | -aros* \ + | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ + | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ + | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \ + | -openbsd* | -solidbsd* \ + | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \ + | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \ + | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ + | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ + | -chorusos* | -chorusrdb* | -cegcc* \ + | -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ + | -mingw32* | -linux-gnu* | -linux-android* \ + | -linux-newlib* | -linux-uclibc* \ + | -uxpv* | -beos* | -mpeix* | -udk* \ + | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \ + | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \ + | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \ + | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \ + | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \ + | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \ + | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es*) + # Remember, each alternative MUST END IN *, to match a version number. + ;; + -qnx*) + case $basic_machine in + x86-* | i*86-*) + ;; + *) + os=-nto$os + ;; + esac + ;; + -nto-qnx*) + ;; + -nto*) + os=`echo $os | sed -e 's|nto|nto-qnx|'` + ;; + -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \ + | -windows* | -osx | -abug | -netware* | -os9* | -beos* | -haiku* \ + | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*) + ;; + -mac*) + os=`echo $os | sed -e 's|mac|macos|'` + ;; + -linux-dietlibc) + os=-linux-dietlibc + ;; + -linux*) + os=`echo $os | sed -e 's|linux|linux-gnu|'` + ;; + -sunos5*) + os=`echo $os | sed -e 's|sunos5|solaris2|'` + ;; + -sunos6*) + os=`echo $os | sed -e 's|sunos6|solaris3|'` + ;; + -opened*) + os=-openedition + ;; + -os400*) + os=-os400 + ;; + -wince*) + os=-wince + ;; + -osfrose*) + os=-osfrose + ;; + -osf*) + os=-osf + ;; + -utek*) + os=-bsd + ;; + -dynix*) + os=-bsd + ;; + -acis*) + os=-aos + ;; + -atheos*) + os=-atheos + ;; + -syllable*) + os=-syllable + ;; + -386bsd) + os=-bsd + ;; + -ctix* | -uts*) + os=-sysv + ;; + -nova*) + os=-rtmk-nova + ;; + -ns2 ) + os=-nextstep2 + ;; + -nsk*) + os=-nsk + ;; + # Preserve the version number of sinix5. + -sinix5.*) + os=`echo $os | sed -e 's|sinix|sysv|'` + ;; + -sinix*) + os=-sysv4 + ;; + -tpf*) + os=-tpf + ;; + -triton*) + os=-sysv3 + ;; + -oss*) + os=-sysv3 + ;; + -svr4) + os=-sysv4 + ;; + -svr3) + os=-sysv3 + ;; + -sysvr4) + os=-sysv4 + ;; + # This must come after -sysvr4. + -sysv*) + ;; + -ose*) + os=-ose + ;; + -es1800*) + os=-ose + ;; + -xenix) + os=-xenix + ;; + -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) + os=-mint + ;; + -aros*) + os=-aros + ;; + -kaos*) + os=-kaos + ;; + -zvmoe) + os=-zvmoe + ;; + -dicos*) + os=-dicos + ;; + -nacl*) + ;; + -none) + ;; + *) + # Get rid of the `-' at the beginning of $os. + os=`echo $os | sed 's/[^-]*-//'` + echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2 + exit 1 + ;; +esac +else + +# Here we handle the default operating systems that come with various machines. +# The value should be what the vendor currently ships out the door with their +# machine or put another way, the most popular os provided with the machine. + +# Note that if you're going to try to match "-MANUFACTURER" here (say, +# "-sun"), then you have to tell the case statement up towards the top +# that MANUFACTURER isn't an operating system. Otherwise, code above +# will signal an error saying that MANUFACTURER isn't an operating +# system, and we'll never get to this point. + +case $basic_machine in + score-*) + os=-elf + ;; + spu-*) + os=-elf + ;; + *-acorn) + os=-riscix1.2 + ;; + arm*-rebel) + os=-linux + ;; + arm*-semi) + os=-aout + ;; + c4x-* | tic4x-*) + os=-coff + ;; + tic54x-*) + os=-coff + ;; + tic55x-*) + os=-coff + ;; + tic6x-*) + os=-coff + ;; + # This must come before the *-dec entry. + pdp10-*) + os=-tops20 + ;; + pdp11-*) + os=-none + ;; + *-dec | vax-*) + os=-ultrix4.2 + ;; + m68*-apollo) + os=-domain + ;; + i386-sun) + os=-sunos4.0.2 + ;; + m68000-sun) + os=-sunos3 + ;; + m68*-cisco) + os=-aout + ;; + mep-*) + os=-elf + ;; + mips*-cisco) + os=-elf + ;; + mips*-*) + os=-elf + ;; + or32-*) + os=-coff + ;; + *-tti) # must be before sparc entry or we get the wrong os. + os=-sysv3 + ;; + sparc-* | *-sun) + os=-sunos4.1.1 + ;; + *-be) + os=-beos + ;; + *-haiku) + os=-haiku + ;; + *-ibm) + os=-aix + ;; + *-knuth) + os=-mmixware + ;; + *-wec) + os=-proelf + ;; + *-winbond) + os=-proelf + ;; + *-oki) + os=-proelf + ;; + *-hp) + os=-hpux + ;; + *-hitachi) + os=-hiux + ;; + i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent) + os=-sysv + ;; + *-cbm) + os=-amigaos + ;; + *-dg) + os=-dgux + ;; + *-dolphin) + os=-sysv3 + ;; + m68k-ccur) + os=-rtu + ;; + m88k-omron*) + os=-luna + ;; + *-next ) + os=-nextstep + ;; + *-sequent) + os=-ptx + ;; + *-crds) + os=-unos + ;; + *-ns) + os=-genix + ;; + i370-*) + os=-mvs + ;; + *-next) + os=-nextstep3 + ;; + *-gould) + os=-sysv + ;; + *-highlevel) + os=-bsd + ;; + *-encore) + os=-bsd + ;; + *-sgi) + os=-irix + ;; + *-siemens) + os=-sysv4 + ;; + *-masscomp) + os=-rtu + ;; + f30[01]-fujitsu | f700-fujitsu) + os=-uxpv + ;; + *-rom68k) + os=-coff + ;; + *-*bug) + os=-coff + ;; + *-apple) + os=-macos + ;; + *-atari*) + os=-mint + ;; + *) + os=-none + ;; +esac +fi + +# Here we handle the case where we know the os, and the CPU type, but not the +# manufacturer. We pick the logical manufacturer. +vendor=unknown +case $basic_machine in + *-unknown) + case $os in + -riscix*) + vendor=acorn + ;; + -sunos*) + vendor=sun + ;; + -cnk*|-aix*) + vendor=ibm + ;; + -beos*) + vendor=be + ;; + -hpux*) + vendor=hp + ;; + -mpeix*) + vendor=hp + ;; + -hiux*) + vendor=hitachi + ;; + -unos*) + vendor=crds + ;; + -dgux*) + vendor=dg + ;; + -luna*) + vendor=omron + ;; + -genix*) + vendor=ns + ;; + -mvs* | -opened*) + vendor=ibm + ;; + -os400*) + vendor=ibm + ;; + -ptx*) + vendor=sequent + ;; + -tpf*) + vendor=ibm + ;; + -vxsim* | -vxworks* | -windiss*) + vendor=wrs + ;; + -aux*) + vendor=apple + ;; + -hms*) + vendor=hitachi + ;; + -mpw* | -macos*) + vendor=apple + ;; + -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) + vendor=atari + ;; + -vos*) + vendor=stratus + ;; + esac + basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"` + ;; +esac + +echo $basic_machine$os +exit + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "timestamp='" +# time-stamp-format: "%:y-%02m-%02d" +# time-stamp-end: "'" +# End: diff --git a/web/server/h2o/libh2o/deps/yaml/config/depcomp b/web/server/h2o/libh2o/deps/yaml/config/depcomp new file mode 100755 index 00000000..bd0ac089 --- /dev/null +++ b/web/server/h2o/libh2o/deps/yaml/config/depcomp @@ -0,0 +1,688 @@ +#! /bin/sh +# depcomp - compile a program generating dependencies as side-effects + +scriptversion=2011-12-04.11; # UTC + +# Copyright (C) 1999, 2000, 2003, 2004, 2005, 2006, 2007, 2009, 2010, +# 2011 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# Originally written by Alexandre Oliva . + +case $1 in + '') + echo "$0: No command. Try \`$0 --help' for more information." 1>&2 + exit 1; + ;; + -h | --h*) + cat <<\EOF +Usage: depcomp [--help] [--version] PROGRAM [ARGS] + +Run PROGRAMS ARGS to compile a file, generating dependencies +as side-effects. + +Environment variables: + depmode Dependency tracking mode. + source Source file read by `PROGRAMS ARGS'. + object Object file output by `PROGRAMS ARGS'. + DEPDIR directory where to store dependencies. + depfile Dependency file to output. + tmpdepfile Temporary file to use when outputting dependencies. + libtool Whether libtool is used (yes/no). + +Report bugs to . +EOF + exit $? + ;; + -v | --v*) + echo "depcomp $scriptversion" + exit $? + ;; +esac + +if test -z "$depmode" || test -z "$source" || test -z "$object"; then + echo "depcomp: Variables source, object and depmode must be set" 1>&2 + exit 1 +fi + +# Dependencies for sub/bar.o or sub/bar.obj go into sub/.deps/bar.Po. +depfile=${depfile-`echo "$object" | + sed 's|[^\\/]*$|'${DEPDIR-.deps}'/&|;s|\.\([^.]*\)$|.P\1|;s|Pobj$|Po|'`} +tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`} + +rm -f "$tmpdepfile" + +# Some modes work just like other modes, but use different flags. We +# parameterize here, but still list the modes in the big case below, +# to make depend.m4 easier to write. Note that we *cannot* use a case +# here, because this file can only contain one case statement. +if test "$depmode" = hp; then + # HP compiler uses -M and no extra arg. + gccflag=-M + depmode=gcc +fi + +if test "$depmode" = dashXmstdout; then + # This is just like dashmstdout with a different argument. + dashmflag=-xM + depmode=dashmstdout +fi + +cygpath_u="cygpath -u -f -" +if test "$depmode" = msvcmsys; then + # This is just like msvisualcpp but w/o cygpath translation. + # Just convert the backslash-escaped backslashes to single forward + # slashes to satisfy depend.m4 + cygpath_u='sed s,\\\\,/,g' + depmode=msvisualcpp +fi + +if test "$depmode" = msvc7msys; then + # This is just like msvc7 but w/o cygpath translation. + # Just convert the backslash-escaped backslashes to single forward + # slashes to satisfy depend.m4 + cygpath_u='sed s,\\\\,/,g' + depmode=msvc7 +fi + +case "$depmode" in +gcc3) +## gcc 3 implements dependency tracking that does exactly what +## we want. Yay! Note: for some reason libtool 1.4 doesn't like +## it if -MD -MP comes after the -MF stuff. Hmm. +## Unfortunately, FreeBSD c89 acceptance of flags depends upon +## the command line argument order; so add the flags where they +## appear in depend2.am. Note that the slowdown incurred here +## affects only configure: in makefiles, %FASTDEP% shortcuts this. + for arg + do + case $arg in + -c) set fnord "$@" -MT "$object" -MD -MP -MF "$tmpdepfile" "$arg" ;; + *) set fnord "$@" "$arg" ;; + esac + shift # fnord + shift # $arg + done + "$@" + stat=$? + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile" + exit $stat + fi + mv "$tmpdepfile" "$depfile" + ;; + +gcc) +## There are various ways to get dependency output from gcc. Here's +## why we pick this rather obscure method: +## - Don't want to use -MD because we'd like the dependencies to end +## up in a subdir. Having to rename by hand is ugly. +## (We might end up doing this anyway to support other compilers.) +## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like +## -MM, not -M (despite what the docs say). +## - Using -M directly means running the compiler twice (even worse +## than renaming). + if test -z "$gccflag"; then + gccflag=-MD, + fi + "$@" -Wp,"$gccflag$tmpdepfile" + stat=$? + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile" + exit $stat + fi + rm -f "$depfile" + echo "$object : \\" > "$depfile" + alpha=ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz +## The second -e expression handles DOS-style file names with drive letters. + sed -e 's/^[^:]*: / /' \ + -e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile" +## This next piece of magic avoids the `deleted header file' problem. +## The problem is that when a header file which appears in a .P file +## is deleted, the dependency causes make to die (because there is +## typically no way to rebuild the header). We avoid this by adding +## dummy dependencies for each header file. Too bad gcc doesn't do +## this for us directly. + tr ' ' ' +' < "$tmpdepfile" | +## Some versions of gcc put a space before the `:'. On the theory +## that the space means something, we add a space to the output as +## well. hp depmode also adds that space, but also prefixes the VPATH +## to the object. Take care to not repeat it in the output. +## Some versions of the HPUX 10.20 sed can't process this invocation +## correctly. Breaking it into two sed invocations is a workaround. + sed -e 's/^\\$//' -e '/^$/d' -e "s|.*$object$||" -e '/:$/d' \ + | sed -e 's/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +hp) + # This case exists only to let depend.m4 do its work. It works by + # looking at the text of this script. This case will never be run, + # since it is checked for above. + exit 1 + ;; + +sgi) + if test "$libtool" = yes; then + "$@" "-Wp,-MDupdate,$tmpdepfile" + else + "$@" -MDupdate "$tmpdepfile" + fi + stat=$? + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile" + exit $stat + fi + rm -f "$depfile" + + if test -f "$tmpdepfile"; then # yes, the sourcefile depend on other files + echo "$object : \\" > "$depfile" + + # Clip off the initial element (the dependent). Don't try to be + # clever and replace this with sed code, as IRIX sed won't handle + # lines with more than a fixed number of characters (4096 in + # IRIX 6.2 sed, 8192 in IRIX 6.5). We also remove comment lines; + # the IRIX cc adds comments like `#:fec' to the end of the + # dependency line. + tr ' ' ' +' < "$tmpdepfile" \ + | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' | \ + tr ' +' ' ' >> "$depfile" + echo >> "$depfile" + + # The second pass generates a dummy entry for each header file. + tr ' ' ' +' < "$tmpdepfile" \ + | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \ + >> "$depfile" + else + # The sourcefile does not contain any dependencies, so just + # store a dummy comment line, to avoid errors with the Makefile + # "include basename.Plo" scheme. + echo "#dummy" > "$depfile" + fi + rm -f "$tmpdepfile" + ;; + +aix) + # The C for AIX Compiler uses -M and outputs the dependencies + # in a .u file. In older versions, this file always lives in the + # current directory. Also, the AIX compiler puts `$object:' at the + # start of each line; $object doesn't have directory information. + # Version 6 uses the directory in both cases. + dir=`echo "$object" | sed -e 's|/[^/]*$|/|'` + test "x$dir" = "x$object" && dir= + base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'` + if test "$libtool" = yes; then + tmpdepfile1=$dir$base.u + tmpdepfile2=$base.u + tmpdepfile3=$dir.libs/$base.u + "$@" -Wc,-M + else + tmpdepfile1=$dir$base.u + tmpdepfile2=$dir$base.u + tmpdepfile3=$dir$base.u + "$@" -M + fi + stat=$? + + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" + exit $stat + fi + + for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" + do + test -f "$tmpdepfile" && break + done + if test -f "$tmpdepfile"; then + # Each line is of the form `foo.o: dependent.h'. + # Do two passes, one to just change these to + # `$object: dependent.h' and one to simply `dependent.h:'. + sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile" + # That's a tab and a space in the []. + sed -e 's,^.*\.[a-z]*:[ ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile" + else + # The sourcefile does not contain any dependencies, so just + # store a dummy comment line, to avoid errors with the Makefile + # "include basename.Plo" scheme. + echo "#dummy" > "$depfile" + fi + rm -f "$tmpdepfile" + ;; + +icc) + # Intel's C compiler understands `-MD -MF file'. However on + # icc -MD -MF foo.d -c -o sub/foo.o sub/foo.c + # ICC 7.0 will fill foo.d with something like + # foo.o: sub/foo.c + # foo.o: sub/foo.h + # which is wrong. We want: + # sub/foo.o: sub/foo.c + # sub/foo.o: sub/foo.h + # sub/foo.c: + # sub/foo.h: + # ICC 7.1 will output + # foo.o: sub/foo.c sub/foo.h + # and will wrap long lines using \ : + # foo.o: sub/foo.c ... \ + # sub/foo.h ... \ + # ... + + "$@" -MD -MF "$tmpdepfile" + stat=$? + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile" + exit $stat + fi + rm -f "$depfile" + # Each line is of the form `foo.o: dependent.h', + # or `foo.o: dep1.h dep2.h \', or ` dep3.h dep4.h \'. + # Do two passes, one to just change these to + # `$object: dependent.h' and one to simply `dependent.h:'. + sed "s,^[^:]*:,$object :," < "$tmpdepfile" > "$depfile" + # Some versions of the HPUX 10.20 sed can't process this invocation + # correctly. Breaking it into two sed invocations is a workaround. + sed 's,^[^:]*: \(.*\)$,\1,;s/^\\$//;/^$/d;/:$/d' < "$tmpdepfile" | + sed -e 's/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +hp2) + # The "hp" stanza above does not work with aCC (C++) and HP's ia64 + # compilers, which have integrated preprocessors. The correct option + # to use with these is +Maked; it writes dependencies to a file named + # 'foo.d', which lands next to the object file, wherever that + # happens to be. + # Much of this is similar to the tru64 case; see comments there. + dir=`echo "$object" | sed -e 's|/[^/]*$|/|'` + test "x$dir" = "x$object" && dir= + base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'` + if test "$libtool" = yes; then + tmpdepfile1=$dir$base.d + tmpdepfile2=$dir.libs/$base.d + "$@" -Wc,+Maked + else + tmpdepfile1=$dir$base.d + tmpdepfile2=$dir$base.d + "$@" +Maked + fi + stat=$? + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile1" "$tmpdepfile2" + exit $stat + fi + + for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" + do + test -f "$tmpdepfile" && break + done + if test -f "$tmpdepfile"; then + sed -e "s,^.*\.[a-z]*:,$object:," "$tmpdepfile" > "$depfile" + # Add `dependent.h:' lines. + sed -ne '2,${ + s/^ *// + s/ \\*$// + s/$/:/ + p + }' "$tmpdepfile" >> "$depfile" + else + echo "#dummy" > "$depfile" + fi + rm -f "$tmpdepfile" "$tmpdepfile2" + ;; + +tru64) + # The Tru64 compiler uses -MD to generate dependencies as a side + # effect. `cc -MD -o foo.o ...' puts the dependencies into `foo.o.d'. + # At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put + # dependencies in `foo.d' instead, so we check for that too. + # Subdirectories are respected. + dir=`echo "$object" | sed -e 's|/[^/]*$|/|'` + test "x$dir" = "x$object" && dir= + base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'` + + if test "$libtool" = yes; then + # With Tru64 cc, shared objects can also be used to make a + # static library. This mechanism is used in libtool 1.4 series to + # handle both shared and static libraries in a single compilation. + # With libtool 1.4, dependencies were output in $dir.libs/$base.lo.d. + # + # With libtool 1.5 this exception was removed, and libtool now + # generates 2 separate objects for the 2 libraries. These two + # compilations output dependencies in $dir.libs/$base.o.d and + # in $dir$base.o.d. We have to check for both files, because + # one of the two compilations can be disabled. We should prefer + # $dir$base.o.d over $dir.libs/$base.o.d because the latter is + # automatically cleaned when .libs/ is deleted, while ignoring + # the former would cause a distcleancheck panic. + tmpdepfile1=$dir.libs/$base.lo.d # libtool 1.4 + tmpdepfile2=$dir$base.o.d # libtool 1.5 + tmpdepfile3=$dir.libs/$base.o.d # libtool 1.5 + tmpdepfile4=$dir.libs/$base.d # Compaq CCC V6.2-504 + "$@" -Wc,-MD + else + tmpdepfile1=$dir$base.o.d + tmpdepfile2=$dir$base.d + tmpdepfile3=$dir$base.d + tmpdepfile4=$dir$base.d + "$@" -MD + fi + + stat=$? + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4" + exit $stat + fi + + for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4" + do + test -f "$tmpdepfile" && break + done + if test -f "$tmpdepfile"; then + sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile" + # That's a tab and a space in the []. + sed -e 's,^.*\.[a-z]*:[ ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile" + else + echo "#dummy" > "$depfile" + fi + rm -f "$tmpdepfile" + ;; + +msvc7) + if test "$libtool" = yes; then + showIncludes=-Wc,-showIncludes + else + showIncludes=-showIncludes + fi + "$@" $showIncludes > "$tmpdepfile" + stat=$? + grep -v '^Note: including file: ' "$tmpdepfile" + if test "$stat" = 0; then : + else + rm -f "$tmpdepfile" + exit $stat + fi + rm -f "$depfile" + echo "$object : \\" > "$depfile" + # The first sed program below extracts the file names and escapes + # backslashes for cygpath. The second sed program outputs the file + # name when reading, but also accumulates all include files in the + # hold buffer in order to output them again at the end. This only + # works with sed implementations that can handle large buffers. + sed < "$tmpdepfile" -n ' +/^Note: including file: *\(.*\)/ { + s//\1/ + s/\\/\\\\/g + p +}' | $cygpath_u | sort -u | sed -n ' +s/ /\\ /g +s/\(.*\)/ \1 \\/p +s/.\(.*\) \\/\1:/ +H +$ { + s/.*/ / + G + p +}' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +msvc7msys) + # This case exists only to let depend.m4 do its work. It works by + # looking at the text of this script. This case will never be run, + # since it is checked for above. + exit 1 + ;; + +#nosideeffect) + # This comment above is used by automake to tell side-effect + # dependency tracking mechanisms from slower ones. + +dashmstdout) + # Important note: in order to support this mode, a compiler *must* + # always write the preprocessed file to stdout, regardless of -o. + "$@" || exit $? + + # Remove the call to Libtool. + if test "$libtool" = yes; then + while test "X$1" != 'X--mode=compile'; do + shift + done + shift + fi + + # Remove `-o $object'. + IFS=" " + for arg + do + case $arg in + -o) + shift + ;; + $object) + shift + ;; + *) + set fnord "$@" "$arg" + shift # fnord + shift # $arg + ;; + esac + done + + test -z "$dashmflag" && dashmflag=-M + # Require at least two characters before searching for `:' + # in the target name. This is to cope with DOS-style filenames: + # a dependency such as `c:/foo/bar' could be seen as target `c' otherwise. + "$@" $dashmflag | + sed 's:^[ ]*[^: ][^:][^:]*\:[ ]*:'"$object"'\: :' > "$tmpdepfile" + rm -f "$depfile" + cat < "$tmpdepfile" > "$depfile" + tr ' ' ' +' < "$tmpdepfile" | \ +## Some versions of the HPUX 10.20 sed can't process this invocation +## correctly. Breaking it into two sed invocations is a workaround. + sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +dashXmstdout) + # This case only exists to satisfy depend.m4. It is never actually + # run, as this mode is specially recognized in the preamble. + exit 1 + ;; + +makedepend) + "$@" || exit $? + # Remove any Libtool call + if test "$libtool" = yes; then + while test "X$1" != 'X--mode=compile'; do + shift + done + shift + fi + # X makedepend + shift + cleared=no eat=no + for arg + do + case $cleared in + no) + set ""; shift + cleared=yes ;; + esac + if test $eat = yes; then + eat=no + continue + fi + case "$arg" in + -D*|-I*) + set fnord "$@" "$arg"; shift ;; + # Strip any option that makedepend may not understand. Remove + # the object too, otherwise makedepend will parse it as a source file. + -arch) + eat=yes ;; + -*|$object) + ;; + *) + set fnord "$@" "$arg"; shift ;; + esac + done + obj_suffix=`echo "$object" | sed 's/^.*\././'` + touch "$tmpdepfile" + ${MAKEDEPEND-makedepend} -o"$obj_suffix" -f"$tmpdepfile" "$@" + rm -f "$depfile" + # makedepend may prepend the VPATH from the source file name to the object. + # No need to regex-escape $object, excess matching of '.' is harmless. + sed "s|^.*\($object *:\)|\1|" "$tmpdepfile" > "$depfile" + sed '1,2d' "$tmpdepfile" | tr ' ' ' +' | \ +## Some versions of the HPUX 10.20 sed can't process this invocation +## correctly. Breaking it into two sed invocations is a workaround. + sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" "$tmpdepfile".bak + ;; + +cpp) + # Important note: in order to support this mode, a compiler *must* + # always write the preprocessed file to stdout. + "$@" || exit $? + + # Remove the call to Libtool. + if test "$libtool" = yes; then + while test "X$1" != 'X--mode=compile'; do + shift + done + shift + fi + + # Remove `-o $object'. + IFS=" " + for arg + do + case $arg in + -o) + shift + ;; + $object) + shift + ;; + *) + set fnord "$@" "$arg" + shift # fnord + shift # $arg + ;; + esac + done + + "$@" -E | + sed -n -e '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \ + -e '/^#line [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' | + sed '$ s: \\$::' > "$tmpdepfile" + rm -f "$depfile" + echo "$object : \\" > "$depfile" + cat < "$tmpdepfile" >> "$depfile" + sed < "$tmpdepfile" '/^$/d;s/^ //;s/ \\$//;s/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +msvisualcpp) + # Important note: in order to support this mode, a compiler *must* + # always write the preprocessed file to stdout. + "$@" || exit $? + + # Remove the call to Libtool. + if test "$libtool" = yes; then + while test "X$1" != 'X--mode=compile'; do + shift + done + shift + fi + + IFS=" " + for arg + do + case "$arg" in + -o) + shift + ;; + $object) + shift + ;; + "-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI") + set fnord "$@" + shift + shift + ;; + *) + set fnord "$@" "$arg" + shift + shift + ;; + esac + done + "$@" -E 2>/dev/null | + sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::\1:p' | $cygpath_u | sort -u > "$tmpdepfile" + rm -f "$depfile" + echo "$object : \\" > "$depfile" + sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s:: \1 \\:p' >> "$depfile" + echo " " >> "$depfile" + sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::\1\::p' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +msvcmsys) + # This case exists only to let depend.m4 do its work. It works by + # looking at the text of this script. This case will never be run, + # since it is checked for above. + exit 1 + ;; + +none) + exec "$@" + ;; + +*) + echo "Unknown depmode $depmode" 1>&2 + exit 1 + ;; +esac + +exit 0 + +# Local Variables: +# mode: shell-script +# sh-indentation: 2 +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-time-zone: "UTC" +# time-stamp-end: "; # UTC" +# End: diff --git a/web/server/h2o/libh2o/deps/yaml/config/install-sh b/web/server/h2o/libh2o/deps/yaml/config/install-sh new file mode 100755 index 00000000..a9244eb0 --- /dev/null +++ b/web/server/h2o/libh2o/deps/yaml/config/install-sh @@ -0,0 +1,527 @@ +#!/bin/sh +# install - install a program, script, or datafile + +scriptversion=2011-01-19.21; # UTC + +# This originates from X11R5 (mit/util/scripts/install.sh), which was +# later released in X11R6 (xc/config/util/install.sh) with the +# following copyright and license. +# +# Copyright (C) 1994 X Consortium +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to +# deal in the Software without restriction, including without limitation the +# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +# sell copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- +# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# +# Except as contained in this notice, the name of the X Consortium shall not +# be used in advertising or otherwise to promote the sale, use or other deal- +# ings in this Software without prior written authorization from the X Consor- +# tium. +# +# +# FSF changes to this file are in the public domain. +# +# Calling this script install-sh is preferred over install.sh, to prevent +# `make' implicit rules from creating a file called install from it +# when there is no Makefile. +# +# This script is compatible with the BSD install script, but was written +# from scratch. + +nl=' +' +IFS=" "" $nl" + +# set DOITPROG to echo to test this script + +# Don't use :- since 4.3BSD and earlier shells don't like it. +doit=${DOITPROG-} +if test -z "$doit"; then + doit_exec=exec +else + doit_exec=$doit +fi + +# Put in absolute file names if you don't have them in your path; +# or use environment vars. + +chgrpprog=${CHGRPPROG-chgrp} +chmodprog=${CHMODPROG-chmod} +chownprog=${CHOWNPROG-chown} +cmpprog=${CMPPROG-cmp} +cpprog=${CPPROG-cp} +mkdirprog=${MKDIRPROG-mkdir} +mvprog=${MVPROG-mv} +rmprog=${RMPROG-rm} +stripprog=${STRIPPROG-strip} + +posix_glob='?' +initialize_posix_glob=' + test "$posix_glob" != "?" || { + if (set -f) 2>/dev/null; then + posix_glob= + else + posix_glob=: + fi + } +' + +posix_mkdir= + +# Desired mode of installed file. +mode=0755 + +chgrpcmd= +chmodcmd=$chmodprog +chowncmd= +mvcmd=$mvprog +rmcmd="$rmprog -f" +stripcmd= + +src= +dst= +dir_arg= +dst_arg= + +copy_on_change=false +no_target_directory= + +usage="\ +Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE + or: $0 [OPTION]... SRCFILES... DIRECTORY + or: $0 [OPTION]... -t DIRECTORY SRCFILES... + or: $0 [OPTION]... -d DIRECTORIES... + +In the 1st form, copy SRCFILE to DSTFILE. +In the 2nd and 3rd, copy all SRCFILES to DIRECTORY. +In the 4th, create DIRECTORIES. + +Options: + --help display this help and exit. + --version display version info and exit. + + -c (ignored) + -C install only if different (preserve the last data modification time) + -d create directories instead of installing files. + -g GROUP $chgrpprog installed files to GROUP. + -m MODE $chmodprog installed files to MODE. + -o USER $chownprog installed files to USER. + -s $stripprog installed files. + -t DIRECTORY install into DIRECTORY. + -T report an error if DSTFILE is a directory. + +Environment variables override the default commands: + CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG + RMPROG STRIPPROG +" + +while test $# -ne 0; do + case $1 in + -c) ;; + + -C) copy_on_change=true;; + + -d) dir_arg=true;; + + -g) chgrpcmd="$chgrpprog $2" + shift;; + + --help) echo "$usage"; exit $?;; + + -m) mode=$2 + case $mode in + *' '* | *' '* | *' +'* | *'*'* | *'?'* | *'['*) + echo "$0: invalid mode: $mode" >&2 + exit 1;; + esac + shift;; + + -o) chowncmd="$chownprog $2" + shift;; + + -s) stripcmd=$stripprog;; + + -t) dst_arg=$2 + # Protect names problematic for `test' and other utilities. + case $dst_arg in + -* | [=\(\)!]) dst_arg=./$dst_arg;; + esac + shift;; + + -T) no_target_directory=true;; + + --version) echo "$0 $scriptversion"; exit $?;; + + --) shift + break;; + + -*) echo "$0: invalid option: $1" >&2 + exit 1;; + + *) break;; + esac + shift +done + +if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then + # When -d is used, all remaining arguments are directories to create. + # When -t is used, the destination is already specified. + # Otherwise, the last argument is the destination. Remove it from $@. + for arg + do + if test -n "$dst_arg"; then + # $@ is not empty: it contains at least $arg. + set fnord "$@" "$dst_arg" + shift # fnord + fi + shift # arg + dst_arg=$arg + # Protect names problematic for `test' and other utilities. + case $dst_arg in + -* | [=\(\)!]) dst_arg=./$dst_arg;; + esac + done +fi + +if test $# -eq 0; then + if test -z "$dir_arg"; then + echo "$0: no input file specified." >&2 + exit 1 + fi + # It's OK to call `install-sh -d' without argument. + # This can happen when creating conditional directories. + exit 0 +fi + +if test -z "$dir_arg"; then + do_exit='(exit $ret); exit $ret' + trap "ret=129; $do_exit" 1 + trap "ret=130; $do_exit" 2 + trap "ret=141; $do_exit" 13 + trap "ret=143; $do_exit" 15 + + # Set umask so as not to create temps with too-generous modes. + # However, 'strip' requires both read and write access to temps. + case $mode in + # Optimize common cases. + *644) cp_umask=133;; + *755) cp_umask=22;; + + *[0-7]) + if test -z "$stripcmd"; then + u_plus_rw= + else + u_plus_rw='% 200' + fi + cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;; + *) + if test -z "$stripcmd"; then + u_plus_rw= + else + u_plus_rw=,u+rw + fi + cp_umask=$mode$u_plus_rw;; + esac +fi + +for src +do + # Protect names problematic for `test' and other utilities. + case $src in + -* | [=\(\)!]) src=./$src;; + esac + + if test -n "$dir_arg"; then + dst=$src + dstdir=$dst + test -d "$dstdir" + dstdir_status=$? + else + + # Waiting for this to be detected by the "$cpprog $src $dsttmp" command + # might cause directories to be created, which would be especially bad + # if $src (and thus $dsttmp) contains '*'. + if test ! -f "$src" && test ! -d "$src"; then + echo "$0: $src does not exist." >&2 + exit 1 + fi + + if test -z "$dst_arg"; then + echo "$0: no destination specified." >&2 + exit 1 + fi + dst=$dst_arg + + # If destination is a directory, append the input filename; won't work + # if double slashes aren't ignored. + if test -d "$dst"; then + if test -n "$no_target_directory"; then + echo "$0: $dst_arg: Is a directory" >&2 + exit 1 + fi + dstdir=$dst + dst=$dstdir/`basename "$src"` + dstdir_status=0 + else + # Prefer dirname, but fall back on a substitute if dirname fails. + dstdir=` + (dirname "$dst") 2>/dev/null || + expr X"$dst" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$dst" : 'X\(//\)[^/]' \| \ + X"$dst" : 'X\(//\)$' \| \ + X"$dst" : 'X\(/\)' \| . 2>/dev/null || + echo X"$dst" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q' + ` + + test -d "$dstdir" + dstdir_status=$? + fi + fi + + obsolete_mkdir_used=false + + if test $dstdir_status != 0; then + case $posix_mkdir in + '') + # Create intermediate dirs using mode 755 as modified by the umask. + # This is like FreeBSD 'install' as of 1997-10-28. + umask=`umask` + case $stripcmd.$umask in + # Optimize common cases. + *[2367][2367]) mkdir_umask=$umask;; + .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;; + + *[0-7]) + mkdir_umask=`expr $umask + 22 \ + - $umask % 100 % 40 + $umask % 20 \ + - $umask % 10 % 4 + $umask % 2 + `;; + *) mkdir_umask=$umask,go-w;; + esac + + # With -d, create the new directory with the user-specified mode. + # Otherwise, rely on $mkdir_umask. + if test -n "$dir_arg"; then + mkdir_mode=-m$mode + else + mkdir_mode= + fi + + posix_mkdir=false + case $umask in + *[123567][0-7][0-7]) + # POSIX mkdir -p sets u+wx bits regardless of umask, which + # is incompatible with FreeBSD 'install' when (umask & 300) != 0. + ;; + *) + tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$ + trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0 + + if (umask $mkdir_umask && + exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1 + then + if test -z "$dir_arg" || { + # Check for POSIX incompatibilities with -m. + # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or + # other-writeable bit of parent directory when it shouldn't. + # FreeBSD 6.1 mkdir -m -p sets mode of existing directory. + ls_ld_tmpdir=`ls -ld "$tmpdir"` + case $ls_ld_tmpdir in + d????-?r-*) different_mode=700;; + d????-?--*) different_mode=755;; + *) false;; + esac && + $mkdirprog -m$different_mode -p -- "$tmpdir" && { + ls_ld_tmpdir_1=`ls -ld "$tmpdir"` + test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1" + } + } + then posix_mkdir=: + fi + rmdir "$tmpdir/d" "$tmpdir" + else + # Remove any dirs left behind by ancient mkdir implementations. + rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null + fi + trap '' 0;; + esac;; + esac + + if + $posix_mkdir && ( + umask $mkdir_umask && + $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir" + ) + then : + else + + # The umask is ridiculous, or mkdir does not conform to POSIX, + # or it failed possibly due to a race condition. Create the + # directory the slow way, step by step, checking for races as we go. + + case $dstdir in + /*) prefix='/';; + [-=\(\)!]*) prefix='./';; + *) prefix='';; + esac + + eval "$initialize_posix_glob" + + oIFS=$IFS + IFS=/ + $posix_glob set -f + set fnord $dstdir + shift + $posix_glob set +f + IFS=$oIFS + + prefixes= + + for d + do + test X"$d" = X && continue + + prefix=$prefix$d + if test -d "$prefix"; then + prefixes= + else + if $posix_mkdir; then + (umask=$mkdir_umask && + $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break + # Don't fail if two instances are running concurrently. + test -d "$prefix" || exit 1 + else + case $prefix in + *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;; + *) qprefix=$prefix;; + esac + prefixes="$prefixes '$qprefix'" + fi + fi + prefix=$prefix/ + done + + if test -n "$prefixes"; then + # Don't fail if two instances are running concurrently. + (umask $mkdir_umask && + eval "\$doit_exec \$mkdirprog $prefixes") || + test -d "$dstdir" || exit 1 + obsolete_mkdir_used=true + fi + fi + fi + + if test -n "$dir_arg"; then + { test -z "$chowncmd" || $doit $chowncmd "$dst"; } && + { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } && + { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false || + test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1 + else + + # Make a couple of temp file names in the proper directory. + dsttmp=$dstdir/_inst.$$_ + rmtmp=$dstdir/_rm.$$_ + + # Trap to clean up those temp files at exit. + trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 + + # Copy the file name to the temp name. + (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") && + + # and set any options; do chmod last to preserve setuid bits. + # + # If any of these fail, we abort the whole thing. If we want to + # ignore errors from any of these, just make sure not to ignore + # errors from the above "$doit $cpprog $src $dsttmp" command. + # + { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } && + { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } && + { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } && + { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } && + + # If -C, don't bother to copy if it wouldn't change the file. + if $copy_on_change && + old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` && + new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` && + + eval "$initialize_posix_glob" && + $posix_glob set -f && + set X $old && old=:$2:$4:$5:$6 && + set X $new && new=:$2:$4:$5:$6 && + $posix_glob set +f && + + test "$old" = "$new" && + $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1 + then + rm -f "$dsttmp" + else + # Rename the file to the real destination. + $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null || + + # The rename failed, perhaps because mv can't rename something else + # to itself, or perhaps because mv is so ancient that it does not + # support -f. + { + # Now remove or move aside any old file at destination location. + # We try this two ways since rm can't unlink itself on some + # systems and the destination file might be busy for other + # reasons. In this case, the final cleanup might fail but the new + # file should still install successfully. + { + test ! -f "$dst" || + $doit $rmcmd -f "$dst" 2>/dev/null || + { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null && + { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; } + } || + { echo "$0: cannot unlink or rename $dst" >&2 + (exit 1); exit 1 + } + } && + + # Now rename the file to the real destination. + $doit $mvcmd "$dsttmp" "$dst" + } + fi || exit 1 + + trap '' 0 + fi +done + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-time-zone: "UTC" +# time-stamp-end: "; # UTC" +# End: diff --git a/web/server/h2o/libh2o/deps/yaml/config/ltmain.sh b/web/server/h2o/libh2o/deps/yaml/config/ltmain.sh new file mode 100644 index 00000000..c2852d85 --- /dev/null +++ b/web/server/h2o/libh2o/deps/yaml/config/ltmain.sh @@ -0,0 +1,9661 @@ + +# libtool (GNU libtool) 2.4.2 +# Written by Gordon Matzigkeit , 1996 + +# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, 2006, +# 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc. +# This is free software; see the source for copying conditions. There is NO +# warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +# GNU Libtool is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# As a special exception to the GNU General Public License, +# if you distribute this file as part of a program or library that +# is built using GNU Libtool, you may include this file under the +# same distribution terms that you use for the rest of that program. +# +# GNU Libtool is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GNU Libtool; see the file COPYING. If not, a copy +# can be downloaded from http://www.gnu.org/licenses/gpl.html, +# or obtained by writing to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + +# Usage: $progname [OPTION]... [MODE-ARG]... +# +# Provide generalized library-building support services. +# +# --config show all configuration variables +# --debug enable verbose shell tracing +# -n, --dry-run display commands without modifying any files +# --features display basic configuration information and exit +# --mode=MODE use operation mode MODE +# --preserve-dup-deps don't remove duplicate dependency libraries +# --quiet, --silent don't print informational messages +# --no-quiet, --no-silent +# print informational messages (default) +# --no-warn don't display warning messages +# --tag=TAG use configuration variables from tag TAG +# -v, --verbose print more informational messages than default +# --no-verbose don't print the extra informational messages +# --version print version information +# -h, --help, --help-all print short, long, or detailed help message +# +# MODE must be one of the following: +# +# clean remove files from the build directory +# compile compile a source file into a libtool object +# execute automatically set library path, then run a program +# finish complete the installation of libtool libraries +# install install libraries or executables +# link create a library or an executable +# uninstall remove libraries from an installed directory +# +# MODE-ARGS vary depending on the MODE. When passed as first option, +# `--mode=MODE' may be abbreviated as `MODE' or a unique abbreviation of that. +# Try `$progname --help --mode=MODE' for a more detailed description of MODE. +# +# When reporting a bug, please describe a test case to reproduce it and +# include the following information: +# +# host-triplet: $host +# shell: $SHELL +# compiler: $LTCC +# compiler flags: $LTCFLAGS +# linker: $LD (gnu? $with_gnu_ld) +# $progname: (GNU libtool) 2.4.2 Debian-2.4.2-1ubuntu1 +# automake: $automake_version +# autoconf: $autoconf_version +# +# Report bugs to . +# GNU libtool home page: . +# General help using GNU software: . + +PROGRAM=libtool +PACKAGE=libtool +VERSION="2.4.2 Debian-2.4.2-1ubuntu1" +TIMESTAMP="" +package_revision=1.3337 + +# Be Bourne compatible +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then + emulate sh + NULLCMD=: + # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in *posix*) set -o posix;; esac +fi +BIN_SH=xpg4; export BIN_SH # for Tru64 +DUALCASE=1; export DUALCASE # for MKS sh + +# A function that is used when there is no print builtin or printf. +func_fallback_echo () +{ + eval 'cat <<_LTECHO_EOF +$1 +_LTECHO_EOF' +} + +# NLS nuisances: We save the old values to restore during execute mode. +lt_user_locale= +lt_safe_locale= +for lt_var in LANG LANGUAGE LC_ALL LC_CTYPE LC_COLLATE LC_MESSAGES +do + eval "if test \"\${$lt_var+set}\" = set; then + save_$lt_var=\$$lt_var + $lt_var=C + export $lt_var + lt_user_locale=\"$lt_var=\\\$save_\$lt_var; \$lt_user_locale\" + lt_safe_locale=\"$lt_var=C; \$lt_safe_locale\" + fi" +done +LC_ALL=C +LANGUAGE=C +export LANGUAGE LC_ALL + +$lt_unset CDPATH + + +# Work around backward compatibility issue on IRIX 6.5. On IRIX 6.4+, sh +# is ksh but when the shell is invoked as "sh" and the current value of +# the _XPG environment variable is not equal to 1 (one), the special +# positional parameter $0, within a function call, is the name of the +# function. +progpath="$0" + + + +: ${CP="cp -f"} +test "${ECHO+set}" = set || ECHO=${as_echo-'printf %s\n'} +: ${MAKE="make"} +: ${MKDIR="mkdir"} +: ${MV="mv -f"} +: ${RM="rm -f"} +: ${SHELL="${CONFIG_SHELL-/bin/sh}"} +: ${Xsed="$SED -e 1s/^X//"} + +# Global variables: +EXIT_SUCCESS=0 +EXIT_FAILURE=1 +EXIT_MISMATCH=63 # $? = 63 is used to indicate version mismatch to missing. +EXIT_SKIP=77 # $? = 77 is used to indicate a skipped test to automake. + +exit_status=$EXIT_SUCCESS + +# Make sure IFS has a sensible default +lt_nl=' +' +IFS=" $lt_nl" + +dirname="s,/[^/]*$,," +basename="s,^.*/,," + +# func_dirname file append nondir_replacement +# Compute the dirname of FILE. If nonempty, add APPEND to the result, +# otherwise set result to NONDIR_REPLACEMENT. +func_dirname () +{ + func_dirname_result=`$ECHO "${1}" | $SED "$dirname"` + if test "X$func_dirname_result" = "X${1}"; then + func_dirname_result="${3}" + else + func_dirname_result="$func_dirname_result${2}" + fi +} # func_dirname may be replaced by extended shell implementation + + +# func_basename file +func_basename () +{ + func_basename_result=`$ECHO "${1}" | $SED "$basename"` +} # func_basename may be replaced by extended shell implementation + + +# func_dirname_and_basename file append nondir_replacement +# perform func_basename and func_dirname in a single function +# call: +# dirname: Compute the dirname of FILE. If nonempty, +# add APPEND to the result, otherwise set result +# to NONDIR_REPLACEMENT. +# value returned in "$func_dirname_result" +# basename: Compute filename of FILE. +# value retuned in "$func_basename_result" +# Implementation must be kept synchronized with func_dirname +# and func_basename. For efficiency, we do not delegate to +# those functions but instead duplicate the functionality here. +func_dirname_and_basename () +{ + # Extract subdirectory from the argument. + func_dirname_result=`$ECHO "${1}" | $SED -e "$dirname"` + if test "X$func_dirname_result" = "X${1}"; then + func_dirname_result="${3}" + else + func_dirname_result="$func_dirname_result${2}" + fi + func_basename_result=`$ECHO "${1}" | $SED -e "$basename"` +} # func_dirname_and_basename may be replaced by extended shell implementation + + +# func_stripname prefix suffix name +# strip PREFIX and SUFFIX off of NAME. +# PREFIX and SUFFIX must not contain globbing or regex special +# characters, hashes, percent signs, but SUFFIX may contain a leading +# dot (in which case that matches only a dot). +# func_strip_suffix prefix name +func_stripname () +{ + case ${2} in + .*) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%\\\\${2}\$%%"`;; + *) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%${2}\$%%"`;; + esac +} # func_stripname may be replaced by extended shell implementation + + +# These SED scripts presuppose an absolute path with a trailing slash. +pathcar='s,^/\([^/]*\).*$,\1,' +pathcdr='s,^/[^/]*,,' +removedotparts=':dotsl + s@/\./@/@g + t dotsl + s,/\.$,/,' +collapseslashes='s@/\{1,\}@/@g' +finalslash='s,/*$,/,' + +# func_normal_abspath PATH +# Remove doubled-up and trailing slashes, "." path components, +# and cancel out any ".." path components in PATH after making +# it an absolute path. +# value returned in "$func_normal_abspath_result" +func_normal_abspath () +{ + # Start from root dir and reassemble the path. + func_normal_abspath_result= + func_normal_abspath_tpath=$1 + func_normal_abspath_altnamespace= + case $func_normal_abspath_tpath in + "") + # Empty path, that just means $cwd. + func_stripname '' '/' "`pwd`" + func_normal_abspath_result=$func_stripname_result + return + ;; + # The next three entries are used to spot a run of precisely + # two leading slashes without using negated character classes; + # we take advantage of case's first-match behaviour. + ///*) + # Unusual form of absolute path, do nothing. + ;; + //*) + # Not necessarily an ordinary path; POSIX reserves leading '//' + # and for example Cygwin uses it to access remote file shares + # over CIFS/SMB, so we conserve a leading double slash if found. + func_normal_abspath_altnamespace=/ + ;; + /*) + # Absolute path, do nothing. + ;; + *) + # Relative path, prepend $cwd. + func_normal_abspath_tpath=`pwd`/$func_normal_abspath_tpath + ;; + esac + # Cancel out all the simple stuff to save iterations. We also want + # the path to end with a slash for ease of parsing, so make sure + # there is one (and only one) here. + func_normal_abspath_tpath=`$ECHO "$func_normal_abspath_tpath" | $SED \ + -e "$removedotparts" -e "$collapseslashes" -e "$finalslash"` + while :; do + # Processed it all yet? + if test "$func_normal_abspath_tpath" = / ; then + # If we ascended to the root using ".." the result may be empty now. + if test -z "$func_normal_abspath_result" ; then + func_normal_abspath_result=/ + fi + break + fi + func_normal_abspath_tcomponent=`$ECHO "$func_normal_abspath_tpath" | $SED \ + -e "$pathcar"` + func_normal_abspath_tpath=`$ECHO "$func_normal_abspath_tpath" | $SED \ + -e "$pathcdr"` + # Figure out what to do with it + case $func_normal_abspath_tcomponent in + "") + # Trailing empty path component, ignore it. + ;; + ..) + # Parent dir; strip last assembled component from result. + func_dirname "$func_normal_abspath_result" + func_normal_abspath_result=$func_dirname_result + ;; + *) + # Actual path component, append it. + func_normal_abspath_result=$func_normal_abspath_result/$func_normal_abspath_tcomponent + ;; + esac + done + # Restore leading double-slash if one was found on entry. + func_normal_abspath_result=$func_normal_abspath_altnamespace$func_normal_abspath_result +} + +# func_relative_path SRCDIR DSTDIR +# generates a relative path from SRCDIR to DSTDIR, with a trailing +# slash if non-empty, suitable for immediately appending a filename +# without needing to append a separator. +# value returned in "$func_relative_path_result" +func_relative_path () +{ + func_relative_path_result= + func_normal_abspath "$1" + func_relative_path_tlibdir=$func_normal_abspath_result + func_normal_abspath "$2" + func_relative_path_tbindir=$func_normal_abspath_result + + # Ascend the tree starting from libdir + while :; do + # check if we have found a prefix of bindir + case $func_relative_path_tbindir in + $func_relative_path_tlibdir) + # found an exact match + func_relative_path_tcancelled= + break + ;; + $func_relative_path_tlibdir*) + # found a matching prefix + func_stripname "$func_relative_path_tlibdir" '' "$func_relative_path_tbindir" + func_relative_path_tcancelled=$func_stripname_result + if test -z "$func_relative_path_result"; then + func_relative_path_result=. + fi + break + ;; + *) + func_dirname $func_relative_path_tlibdir + func_relative_path_tlibdir=${func_dirname_result} + if test "x$func_relative_path_tlibdir" = x ; then + # Have to descend all the way to the root! + func_relative_path_result=../$func_relative_path_result + func_relative_path_tcancelled=$func_relative_path_tbindir + break + fi + func_relative_path_result=../$func_relative_path_result + ;; + esac + done + + # Now calculate path; take care to avoid doubling-up slashes. + func_stripname '' '/' "$func_relative_path_result" + func_relative_path_result=$func_stripname_result + func_stripname '/' '/' "$func_relative_path_tcancelled" + if test "x$func_stripname_result" != x ; then + func_relative_path_result=${func_relative_path_result}/${func_stripname_result} + fi + + # Normalisation. If bindir is libdir, return empty string, + # else relative path ending with a slash; either way, target + # file name can be directly appended. + if test ! -z "$func_relative_path_result"; then + func_stripname './' '' "$func_relative_path_result/" + func_relative_path_result=$func_stripname_result + fi +} + +# The name of this program: +func_dirname_and_basename "$progpath" +progname=$func_basename_result + +# Make sure we have an absolute path for reexecution: +case $progpath in + [\\/]*|[A-Za-z]:\\*) ;; + *[\\/]*) + progdir=$func_dirname_result + progdir=`cd "$progdir" && pwd` + progpath="$progdir/$progname" + ;; + *) + save_IFS="$IFS" + IFS=${PATH_SEPARATOR-:} + for progdir in $PATH; do + IFS="$save_IFS" + test -x "$progdir/$progname" && break + done + IFS="$save_IFS" + test -n "$progdir" || progdir=`pwd` + progpath="$progdir/$progname" + ;; +esac + +# Sed substitution that helps us do robust quoting. It backslashifies +# metacharacters that are still active within double-quoted strings. +Xsed="${SED}"' -e 1s/^X//' +sed_quote_subst='s/\([`"$\\]\)/\\\1/g' + +# Same as above, but do not quote variable references. +double_quote_subst='s/\(["`\\]\)/\\\1/g' + +# Sed substitution that turns a string into a regex matching for the +# string literally. +sed_make_literal_regex='s,[].[^$\\*\/],\\&,g' + +# Sed substitution that converts a w32 file name or path +# which contains forward slashes, into one that contains +# (escaped) backslashes. A very naive implementation. +lt_sed_naive_backslashify='s|\\\\*|\\|g;s|/|\\|g;s|\\|\\\\|g' + +# Re-`\' parameter expansions in output of double_quote_subst that were +# `\'-ed in input to the same. If an odd number of `\' preceded a '$' +# in input to double_quote_subst, that '$' was protected from expansion. +# Since each input `\' is now two `\'s, look for any number of runs of +# four `\'s followed by two `\'s and then a '$'. `\' that '$'. +bs='\\' +bs2='\\\\' +bs4='\\\\\\\\' +dollar='\$' +sed_double_backslash="\ + s/$bs4/&\\ +/g + s/^$bs2$dollar/$bs&/ + s/\\([^$bs]\\)$bs2$dollar/\\1$bs2$bs$dollar/g + s/\n//g" + +# Standard options: +opt_dry_run=false +opt_help=false +opt_quiet=false +opt_verbose=false +opt_warning=: + +# func_echo arg... +# Echo program name prefixed message, along with the current mode +# name if it has been set yet. +func_echo () +{ + $ECHO "$progname: ${opt_mode+$opt_mode: }$*" +} + +# func_verbose arg... +# Echo program name prefixed message in verbose mode only. +func_verbose () +{ + $opt_verbose && func_echo ${1+"$@"} + + # A bug in bash halts the script if the last line of a function + # fails when set -e is in force, so we need another command to + # work around that: + : +} + +# func_echo_all arg... +# Invoke $ECHO with all args, space-separated. +func_echo_all () +{ + $ECHO "$*" +} + +# func_error arg... +# Echo program name prefixed message to standard error. +func_error () +{ + $ECHO "$progname: ${opt_mode+$opt_mode: }"${1+"$@"} 1>&2 +} + +# func_warning arg... +# Echo program name prefixed warning message to standard error. +func_warning () +{ + $opt_warning && $ECHO "$progname: ${opt_mode+$opt_mode: }warning: "${1+"$@"} 1>&2 + + # bash bug again: + : +} + +# func_fatal_error arg... +# Echo program name prefixed message to standard error, and exit. +func_fatal_error () +{ + func_error ${1+"$@"} + exit $EXIT_FAILURE +} + +# func_fatal_help arg... +# Echo program name prefixed message to standard error, followed by +# a help hint, and exit. +func_fatal_help () +{ + func_error ${1+"$@"} + func_fatal_error "$help" +} +help="Try \`$progname --help' for more information." ## default + + +# func_grep expression filename +# Check whether EXPRESSION matches any line of FILENAME, without output. +func_grep () +{ + $GREP "$1" "$2" >/dev/null 2>&1 +} + + +# func_mkdir_p directory-path +# Make sure the entire path to DIRECTORY-PATH is available. +func_mkdir_p () +{ + my_directory_path="$1" + my_dir_list= + + if test -n "$my_directory_path" && test "$opt_dry_run" != ":"; then + + # Protect directory names starting with `-' + case $my_directory_path in + -*) my_directory_path="./$my_directory_path" ;; + esac + + # While some portion of DIR does not yet exist... + while test ! -d "$my_directory_path"; do + # ...make a list in topmost first order. Use a colon delimited + # list incase some portion of path contains whitespace. + my_dir_list="$my_directory_path:$my_dir_list" + + # If the last portion added has no slash in it, the list is done + case $my_directory_path in */*) ;; *) break ;; esac + + # ...otherwise throw away the child directory and loop + my_directory_path=`$ECHO "$my_directory_path" | $SED -e "$dirname"` + done + my_dir_list=`$ECHO "$my_dir_list" | $SED 's,:*$,,'` + + save_mkdir_p_IFS="$IFS"; IFS=':' + for my_dir in $my_dir_list; do + IFS="$save_mkdir_p_IFS" + # mkdir can fail with a `File exist' error if two processes + # try to create one of the directories concurrently. Don't + # stop in that case! + $MKDIR "$my_dir" 2>/dev/null || : + done + IFS="$save_mkdir_p_IFS" + + # Bail out if we (or some other process) failed to create a directory. + test -d "$my_directory_path" || \ + func_fatal_error "Failed to create \`$1'" + fi +} + + +# func_mktempdir [string] +# Make a temporary directory that won't clash with other running +# libtool processes, and avoids race conditions if possible. If +# given, STRING is the basename for that directory. +func_mktempdir () +{ + my_template="${TMPDIR-/tmp}/${1-$progname}" + + if test "$opt_dry_run" = ":"; then + # Return a directory name, but don't create it in dry-run mode + my_tmpdir="${my_template}-$$" + else + + # If mktemp works, use that first and foremost + my_tmpdir=`mktemp -d "${my_template}-XXXXXXXX" 2>/dev/null` + + if test ! -d "$my_tmpdir"; then + # Failing that, at least try and use $RANDOM to avoid a race + my_tmpdir="${my_template}-${RANDOM-0}$$" + + save_mktempdir_umask=`umask` + umask 0077 + $MKDIR "$my_tmpdir" + umask $save_mktempdir_umask + fi + + # If we're not in dry-run mode, bomb out on failure + test -d "$my_tmpdir" || \ + func_fatal_error "cannot create temporary directory \`$my_tmpdir'" + fi + + $ECHO "$my_tmpdir" +} + + +# func_quote_for_eval arg +# Aesthetically quote ARG to be evaled later. +# This function returns two values: FUNC_QUOTE_FOR_EVAL_RESULT +# is double-quoted, suitable for a subsequent eval, whereas +# FUNC_QUOTE_FOR_EVAL_UNQUOTED_RESULT has merely all characters +# which are still active within double quotes backslashified. +func_quote_for_eval () +{ + case $1 in + *[\\\`\"\$]*) + func_quote_for_eval_unquoted_result=`$ECHO "$1" | $SED "$sed_quote_subst"` ;; + *) + func_quote_for_eval_unquoted_result="$1" ;; + esac + + case $func_quote_for_eval_unquoted_result in + # Double-quote args containing shell metacharacters to delay + # word splitting, command substitution and and variable + # expansion for a subsequent eval. + # Many Bourne shells cannot handle close brackets correctly + # in scan sets, so we specify it separately. + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + func_quote_for_eval_result="\"$func_quote_for_eval_unquoted_result\"" + ;; + *) + func_quote_for_eval_result="$func_quote_for_eval_unquoted_result" + esac +} + + +# func_quote_for_expand arg +# Aesthetically quote ARG to be evaled later; same as above, +# but do not quote variable references. +func_quote_for_expand () +{ + case $1 in + *[\\\`\"]*) + my_arg=`$ECHO "$1" | $SED \ + -e "$double_quote_subst" -e "$sed_double_backslash"` ;; + *) + my_arg="$1" ;; + esac + + case $my_arg in + # Double-quote args containing shell metacharacters to delay + # word splitting and command substitution for a subsequent eval. + # Many Bourne shells cannot handle close brackets correctly + # in scan sets, so we specify it separately. + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + my_arg="\"$my_arg\"" + ;; + esac + + func_quote_for_expand_result="$my_arg" +} + + +# func_show_eval cmd [fail_exp] +# Unless opt_silent is true, then output CMD. Then, if opt_dryrun is +# not true, evaluate CMD. If the evaluation of CMD fails, and FAIL_EXP +# is given, then evaluate it. +func_show_eval () +{ + my_cmd="$1" + my_fail_exp="${2-:}" + + ${opt_silent-false} || { + func_quote_for_expand "$my_cmd" + eval "func_echo $func_quote_for_expand_result" + } + + if ${opt_dry_run-false}; then :; else + eval "$my_cmd" + my_status=$? + if test "$my_status" -eq 0; then :; else + eval "(exit $my_status); $my_fail_exp" + fi + fi +} + + +# func_show_eval_locale cmd [fail_exp] +# Unless opt_silent is true, then output CMD. Then, if opt_dryrun is +# not true, evaluate CMD. If the evaluation of CMD fails, and FAIL_EXP +# is given, then evaluate it. Use the saved locale for evaluation. +func_show_eval_locale () +{ + my_cmd="$1" + my_fail_exp="${2-:}" + + ${opt_silent-false} || { + func_quote_for_expand "$my_cmd" + eval "func_echo $func_quote_for_expand_result" + } + + if ${opt_dry_run-false}; then :; else + eval "$lt_user_locale + $my_cmd" + my_status=$? + eval "$lt_safe_locale" + if test "$my_status" -eq 0; then :; else + eval "(exit $my_status); $my_fail_exp" + fi + fi +} + +# func_tr_sh +# Turn $1 into a string suitable for a shell variable name. +# Result is stored in $func_tr_sh_result. All characters +# not in the set a-zA-Z0-9_ are replaced with '_'. Further, +# if $1 begins with a digit, a '_' is prepended as well. +func_tr_sh () +{ + case $1 in + [0-9]* | *[!a-zA-Z0-9_]*) + func_tr_sh_result=`$ECHO "$1" | $SED 's/^\([0-9]\)/_\1/; s/[^a-zA-Z0-9_]/_/g'` + ;; + * ) + func_tr_sh_result=$1 + ;; + esac +} + + +# func_version +# Echo version message to standard output and exit. +func_version () +{ + $opt_debug + + $SED -n '/(C)/!b go + :more + /\./!{ + N + s/\n# / / + b more + } + :go + /^# '$PROGRAM' (GNU /,/# warranty; / { + s/^# // + s/^# *$// + s/\((C)\)[ 0-9,-]*\( [1-9][0-9]*\)/\1\2/ + p + }' < "$progpath" + exit $? +} + +# func_usage +# Echo short help message to standard output and exit. +func_usage () +{ + $opt_debug + + $SED -n '/^# Usage:/,/^# *.*--help/ { + s/^# // + s/^# *$// + s/\$progname/'$progname'/ + p + }' < "$progpath" + echo + $ECHO "run \`$progname --help | more' for full usage" + exit $? +} + +# func_help [NOEXIT] +# Echo long help message to standard output and exit, +# unless 'noexit' is passed as argument. +func_help () +{ + $opt_debug + + $SED -n '/^# Usage:/,/# Report bugs to/ { + :print + s/^# // + s/^# *$// + s*\$progname*'$progname'* + s*\$host*'"$host"'* + s*\$SHELL*'"$SHELL"'* + s*\$LTCC*'"$LTCC"'* + s*\$LTCFLAGS*'"$LTCFLAGS"'* + s*\$LD*'"$LD"'* + s/\$with_gnu_ld/'"$with_gnu_ld"'/ + s/\$automake_version/'"`(${AUTOMAKE-automake} --version) 2>/dev/null |$SED 1q`"'/ + s/\$autoconf_version/'"`(${AUTOCONF-autoconf} --version) 2>/dev/null |$SED 1q`"'/ + p + d + } + /^# .* home page:/b print + /^# General help using/b print + ' < "$progpath" + ret=$? + if test -z "$1"; then + exit $ret + fi +} + +# func_missing_arg argname +# Echo program name prefixed message to standard error and set global +# exit_cmd. +func_missing_arg () +{ + $opt_debug + + func_error "missing argument for $1." + exit_cmd=exit +} + + +# func_split_short_opt shortopt +# Set func_split_short_opt_name and func_split_short_opt_arg shell +# variables after splitting SHORTOPT after the 2nd character. +func_split_short_opt () +{ + my_sed_short_opt='1s/^\(..\).*$/\1/;q' + my_sed_short_rest='1s/^..\(.*\)$/\1/;q' + + func_split_short_opt_name=`$ECHO "$1" | $SED "$my_sed_short_opt"` + func_split_short_opt_arg=`$ECHO "$1" | $SED "$my_sed_short_rest"` +} # func_split_short_opt may be replaced by extended shell implementation + + +# func_split_long_opt longopt +# Set func_split_long_opt_name and func_split_long_opt_arg shell +# variables after splitting LONGOPT at the `=' sign. +func_split_long_opt () +{ + my_sed_long_opt='1s/^\(--[^=]*\)=.*/\1/;q' + my_sed_long_arg='1s/^--[^=]*=//' + + func_split_long_opt_name=`$ECHO "$1" | $SED "$my_sed_long_opt"` + func_split_long_opt_arg=`$ECHO "$1" | $SED "$my_sed_long_arg"` +} # func_split_long_opt may be replaced by extended shell implementation + +exit_cmd=: + + + + + +magic="%%%MAGIC variable%%%" +magic_exe="%%%MAGIC EXE variable%%%" + +# Global variables. +nonopt= +preserve_args= +lo2o="s/\\.lo\$/.${objext}/" +o2lo="s/\\.${objext}\$/.lo/" +extracted_archives= +extracted_serial=0 + +# If this variable is set in any of the actions, the command in it +# will be execed at the end. This prevents here-documents from being +# left over by shells. +exec_cmd= + +# func_append var value +# Append VALUE to the end of shell variable VAR. +func_append () +{ + eval "${1}=\$${1}\${2}" +} # func_append may be replaced by extended shell implementation + +# func_append_quoted var value +# Quote VALUE and append to the end of shell variable VAR, separated +# by a space. +func_append_quoted () +{ + func_quote_for_eval "${2}" + eval "${1}=\$${1}\\ \$func_quote_for_eval_result" +} # func_append_quoted may be replaced by extended shell implementation + + +# func_arith arithmetic-term... +func_arith () +{ + func_arith_result=`expr "${@}"` +} # func_arith may be replaced by extended shell implementation + + +# func_len string +# STRING may not start with a hyphen. +func_len () +{ + func_len_result=`expr "${1}" : ".*" 2>/dev/null || echo $max_cmd_len` +} # func_len may be replaced by extended shell implementation + + +# func_lo2o object +func_lo2o () +{ + func_lo2o_result=`$ECHO "${1}" | $SED "$lo2o"` +} # func_lo2o may be replaced by extended shell implementation + + +# func_xform libobj-or-source +func_xform () +{ + func_xform_result=`$ECHO "${1}" | $SED 's/\.[^.]*$/.lo/'` +} # func_xform may be replaced by extended shell implementation + + +# func_fatal_configuration arg... +# Echo program name prefixed message to standard error, followed by +# a configuration failure hint, and exit. +func_fatal_configuration () +{ + func_error ${1+"$@"} + func_error "See the $PACKAGE documentation for more information." + func_fatal_error "Fatal configuration error." +} + + +# func_config +# Display the configuration for all the tags in this script. +func_config () +{ + re_begincf='^# ### BEGIN LIBTOOL' + re_endcf='^# ### END LIBTOOL' + + # Default configuration. + $SED "1,/$re_begincf CONFIG/d;/$re_endcf CONFIG/,\$d" < "$progpath" + + # Now print the configurations for the tags. + for tagname in $taglist; do + $SED -n "/$re_begincf TAG CONFIG: $tagname\$/,/$re_endcf TAG CONFIG: $tagname\$/p" < "$progpath" + done + + exit $? +} + +# func_features +# Display the features supported by this script. +func_features () +{ + echo "host: $host" + if test "$build_libtool_libs" = yes; then + echo "enable shared libraries" + else + echo "disable shared libraries" + fi + if test "$build_old_libs" = yes; then + echo "enable static libraries" + else + echo "disable static libraries" + fi + + exit $? +} + +# func_enable_tag tagname +# Verify that TAGNAME is valid, and either flag an error and exit, or +# enable the TAGNAME tag. We also add TAGNAME to the global $taglist +# variable here. +func_enable_tag () +{ + # Global variable: + tagname="$1" + + re_begincf="^# ### BEGIN LIBTOOL TAG CONFIG: $tagname\$" + re_endcf="^# ### END LIBTOOL TAG CONFIG: $tagname\$" + sed_extractcf="/$re_begincf/,/$re_endcf/p" + + # Validate tagname. + case $tagname in + *[!-_A-Za-z0-9,/]*) + func_fatal_error "invalid tag name: $tagname" + ;; + esac + + # Don't test for the "default" C tag, as we know it's + # there but not specially marked. + case $tagname in + CC) ;; + *) + if $GREP "$re_begincf" "$progpath" >/dev/null 2>&1; then + taglist="$taglist $tagname" + + # Evaluate the configuration. Be careful to quote the path + # and the sed script, to avoid splitting on whitespace, but + # also don't use non-portable quotes within backquotes within + # quotes we have to do it in 2 steps: + extractedcf=`$SED -n -e "$sed_extractcf" < "$progpath"` + eval "$extractedcf" + else + func_error "ignoring unknown tag $tagname" + fi + ;; + esac +} + +# func_check_version_match +# Ensure that we are using m4 macros, and libtool script from the same +# release of libtool. +func_check_version_match () +{ + if test "$package_revision" != "$macro_revision"; then + if test "$VERSION" != "$macro_version"; then + if test -z "$macro_version"; then + cat >&2 <<_LT_EOF +$progname: Version mismatch error. This is $PACKAGE $VERSION, but the +$progname: definition of this LT_INIT comes from an older release. +$progname: You should recreate aclocal.m4 with macros from $PACKAGE $VERSION +$progname: and run autoconf again. +_LT_EOF + else + cat >&2 <<_LT_EOF +$progname: Version mismatch error. This is $PACKAGE $VERSION, but the +$progname: definition of this LT_INIT comes from $PACKAGE $macro_version. +$progname: You should recreate aclocal.m4 with macros from $PACKAGE $VERSION +$progname: and run autoconf again. +_LT_EOF + fi + else + cat >&2 <<_LT_EOF +$progname: Version mismatch error. This is $PACKAGE $VERSION, revision $package_revision, +$progname: but the definition of this LT_INIT comes from revision $macro_revision. +$progname: You should recreate aclocal.m4 with macros from revision $package_revision +$progname: of $PACKAGE $VERSION and run autoconf again. +_LT_EOF + fi + + exit $EXIT_MISMATCH + fi +} + + +# Shorthand for --mode=foo, only valid as the first argument +case $1 in +clean|clea|cle|cl) + shift; set dummy --mode clean ${1+"$@"}; shift + ;; +compile|compil|compi|comp|com|co|c) + shift; set dummy --mode compile ${1+"$@"}; shift + ;; +execute|execut|execu|exec|exe|ex|e) + shift; set dummy --mode execute ${1+"$@"}; shift + ;; +finish|finis|fini|fin|fi|f) + shift; set dummy --mode finish ${1+"$@"}; shift + ;; +install|instal|insta|inst|ins|in|i) + shift; set dummy --mode install ${1+"$@"}; shift + ;; +link|lin|li|l) + shift; set dummy --mode link ${1+"$@"}; shift + ;; +uninstall|uninstal|uninsta|uninst|unins|unin|uni|un|u) + shift; set dummy --mode uninstall ${1+"$@"}; shift + ;; +esac + + + +# Option defaults: +opt_debug=: +opt_dry_run=false +opt_config=false +opt_preserve_dup_deps=false +opt_features=false +opt_finish=false +opt_help=false +opt_help_all=false +opt_silent=: +opt_warning=: +opt_verbose=: +opt_silent=false +opt_verbose=false + + +# Parse options once, thoroughly. This comes as soon as possible in the +# script to make things like `--version' happen as quickly as we can. +{ + # this just eases exit handling + while test $# -gt 0; do + opt="$1" + shift + case $opt in + --debug|-x) opt_debug='set -x' + func_echo "enabling shell trace mode" + $opt_debug + ;; + --dry-run|--dryrun|-n) + opt_dry_run=: + ;; + --config) + opt_config=: +func_config + ;; + --dlopen|-dlopen) + optarg="$1" + opt_dlopen="${opt_dlopen+$opt_dlopen +}$optarg" + shift + ;; + --preserve-dup-deps) + opt_preserve_dup_deps=: + ;; + --features) + opt_features=: +func_features + ;; + --finish) + opt_finish=: +set dummy --mode finish ${1+"$@"}; shift + ;; + --help) + opt_help=: + ;; + --help-all) + opt_help_all=: +opt_help=': help-all' + ;; + --mode) + test $# = 0 && func_missing_arg $opt && break + optarg="$1" + opt_mode="$optarg" +case $optarg in + # Valid mode arguments: + clean|compile|execute|finish|install|link|relink|uninstall) ;; + + # Catch anything else as an error + *) func_error "invalid argument for $opt" + exit_cmd=exit + break + ;; +esac + shift + ;; + --no-silent|--no-quiet) + opt_silent=false +func_append preserve_args " $opt" + ;; + --no-warning|--no-warn) + opt_warning=false +func_append preserve_args " $opt" + ;; + --no-verbose) + opt_verbose=false +func_append preserve_args " $opt" + ;; + --silent|--quiet) + opt_silent=: +func_append preserve_args " $opt" + opt_verbose=false + ;; + --verbose|-v) + opt_verbose=: +func_append preserve_args " $opt" +opt_silent=false + ;; + --tag) + test $# = 0 && func_missing_arg $opt && break + optarg="$1" + opt_tag="$optarg" +func_append preserve_args " $opt $optarg" +func_enable_tag "$optarg" + shift + ;; + + -\?|-h) func_usage ;; + --help) func_help ;; + --version) func_version ;; + + # Separate optargs to long options: + --*=*) + func_split_long_opt "$opt" + set dummy "$func_split_long_opt_name" "$func_split_long_opt_arg" ${1+"$@"} + shift + ;; + + # Separate non-argument short options: + -\?*|-h*|-n*|-v*) + func_split_short_opt "$opt" + set dummy "$func_split_short_opt_name" "-$func_split_short_opt_arg" ${1+"$@"} + shift + ;; + + --) break ;; + -*) func_fatal_help "unrecognized option \`$opt'" ;; + *) set dummy "$opt" ${1+"$@"}; shift; break ;; + esac + done + + # Validate options: + + # save first non-option argument + if test "$#" -gt 0; then + nonopt="$opt" + shift + fi + + # preserve --debug + test "$opt_debug" = : || func_append preserve_args " --debug" + + case $host in + *cygwin* | *mingw* | *pw32* | *cegcc*) + # don't eliminate duplications in $postdeps and $predeps + opt_duplicate_compiler_generated_deps=: + ;; + *) + opt_duplicate_compiler_generated_deps=$opt_preserve_dup_deps + ;; + esac + + $opt_help || { + # Sanity checks first: + func_check_version_match + + if test "$build_libtool_libs" != yes && test "$build_old_libs" != yes; then + func_fatal_configuration "not configured to build any kind of library" + fi + + # Darwin sucks + eval std_shrext=\"$shrext_cmds\" + + # Only execute mode is allowed to have -dlopen flags. + if test -n "$opt_dlopen" && test "$opt_mode" != execute; then + func_error "unrecognized option \`-dlopen'" + $ECHO "$help" 1>&2 + exit $EXIT_FAILURE + fi + + # Change the help message to a mode-specific one. + generic_help="$help" + help="Try \`$progname --help --mode=$opt_mode' for more information." + } + + + # Bail if the options were screwed + $exit_cmd $EXIT_FAILURE +} + + + + +## ----------- ## +## Main. ## +## ----------- ## + +# func_lalib_p file +# True iff FILE is a libtool `.la' library or `.lo' object file. +# This function is only a basic sanity check; it will hardly flush out +# determined imposters. +func_lalib_p () +{ + test -f "$1" && + $SED -e 4q "$1" 2>/dev/null \ + | $GREP "^# Generated by .*$PACKAGE" > /dev/null 2>&1 +} + +# func_lalib_unsafe_p file +# True iff FILE is a libtool `.la' library or `.lo' object file. +# This function implements the same check as func_lalib_p without +# resorting to external programs. To this end, it redirects stdin and +# closes it afterwards, without saving the original file descriptor. +# As a safety measure, use it only where a negative result would be +# fatal anyway. Works if `file' does not exist. +func_lalib_unsafe_p () +{ + lalib_p=no + if test -f "$1" && test -r "$1" && exec 5<&0 <"$1"; then + for lalib_p_l in 1 2 3 4 + do + read lalib_p_line + case "$lalib_p_line" in + \#\ Generated\ by\ *$PACKAGE* ) lalib_p=yes; break;; + esac + done + exec 0<&5 5<&- + fi + test "$lalib_p" = yes +} + +# func_ltwrapper_script_p file +# True iff FILE is a libtool wrapper script +# This function is only a basic sanity check; it will hardly flush out +# determined imposters. +func_ltwrapper_script_p () +{ + func_lalib_p "$1" +} + +# func_ltwrapper_executable_p file +# True iff FILE is a libtool wrapper executable +# This function is only a basic sanity check; it will hardly flush out +# determined imposters. +func_ltwrapper_executable_p () +{ + func_ltwrapper_exec_suffix= + case $1 in + *.exe) ;; + *) func_ltwrapper_exec_suffix=.exe ;; + esac + $GREP "$magic_exe" "$1$func_ltwrapper_exec_suffix" >/dev/null 2>&1 +} + +# func_ltwrapper_scriptname file +# Assumes file is an ltwrapper_executable +# uses $file to determine the appropriate filename for a +# temporary ltwrapper_script. +func_ltwrapper_scriptname () +{ + func_dirname_and_basename "$1" "" "." + func_stripname '' '.exe' "$func_basename_result" + func_ltwrapper_scriptname_result="$func_dirname_result/$objdir/${func_stripname_result}_ltshwrapper" +} + +# func_ltwrapper_p file +# True iff FILE is a libtool wrapper script or wrapper executable +# This function is only a basic sanity check; it will hardly flush out +# determined imposters. +func_ltwrapper_p () +{ + func_ltwrapper_script_p "$1" || func_ltwrapper_executable_p "$1" +} + + +# func_execute_cmds commands fail_cmd +# Execute tilde-delimited COMMANDS. +# If FAIL_CMD is given, eval that upon failure. +# FAIL_CMD may read-access the current command in variable CMD! +func_execute_cmds () +{ + $opt_debug + save_ifs=$IFS; IFS='~' + for cmd in $1; do + IFS=$save_ifs + eval cmd=\"$cmd\" + func_show_eval "$cmd" "${2-:}" + done + IFS=$save_ifs +} + + +# func_source file +# Source FILE, adding directory component if necessary. +# Note that it is not necessary on cygwin/mingw to append a dot to +# FILE even if both FILE and FILE.exe exist: automatic-append-.exe +# behavior happens only for exec(3), not for open(2)! Also, sourcing +# `FILE.' does not work on cygwin managed mounts. +func_source () +{ + $opt_debug + case $1 in + */* | *\\*) . "$1" ;; + *) . "./$1" ;; + esac +} + + +# func_resolve_sysroot PATH +# Replace a leading = in PATH with a sysroot. Store the result into +# func_resolve_sysroot_result +func_resolve_sysroot () +{ + func_resolve_sysroot_result=$1 + case $func_resolve_sysroot_result in + =*) + func_stripname '=' '' "$func_resolve_sysroot_result" + func_resolve_sysroot_result=$lt_sysroot$func_stripname_result + ;; + esac +} + +# func_replace_sysroot PATH +# If PATH begins with the sysroot, replace it with = and +# store the result into func_replace_sysroot_result. +func_replace_sysroot () +{ + case "$lt_sysroot:$1" in + ?*:"$lt_sysroot"*) + func_stripname "$lt_sysroot" '' "$1" + func_replace_sysroot_result="=$func_stripname_result" + ;; + *) + # Including no sysroot. + func_replace_sysroot_result=$1 + ;; + esac +} + +# func_infer_tag arg +# Infer tagged configuration to use if any are available and +# if one wasn't chosen via the "--tag" command line option. +# Only attempt this if the compiler in the base compile +# command doesn't match the default compiler. +# arg is usually of the form 'gcc ...' +func_infer_tag () +{ + $opt_debug + if test -n "$available_tags" && test -z "$tagname"; then + CC_quoted= + for arg in $CC; do + func_append_quoted CC_quoted "$arg" + done + CC_expanded=`func_echo_all $CC` + CC_quoted_expanded=`func_echo_all $CC_quoted` + case $@ in + # Blanks in the command may have been stripped by the calling shell, + # but not from the CC environment variable when configure was run. + " $CC "* | "$CC "* | " $CC_expanded "* | "$CC_expanded "* | \ + " $CC_quoted"* | "$CC_quoted "* | " $CC_quoted_expanded "* | "$CC_quoted_expanded "*) ;; + # Blanks at the start of $base_compile will cause this to fail + # if we don't check for them as well. + *) + for z in $available_tags; do + if $GREP "^# ### BEGIN LIBTOOL TAG CONFIG: $z$" < "$progpath" > /dev/null; then + # Evaluate the configuration. + eval "`${SED} -n -e '/^# ### BEGIN LIBTOOL TAG CONFIG: '$z'$/,/^# ### END LIBTOOL TAG CONFIG: '$z'$/p' < $progpath`" + CC_quoted= + for arg in $CC; do + # Double-quote args containing other shell metacharacters. + func_append_quoted CC_quoted "$arg" + done + CC_expanded=`func_echo_all $CC` + CC_quoted_expanded=`func_echo_all $CC_quoted` + case "$@ " in + " $CC "* | "$CC "* | " $CC_expanded "* | "$CC_expanded "* | \ + " $CC_quoted"* | "$CC_quoted "* | " $CC_quoted_expanded "* | "$CC_quoted_expanded "*) + # The compiler in the base compile command matches + # the one in the tagged configuration. + # Assume this is the tagged configuration we want. + tagname=$z + break + ;; + esac + fi + done + # If $tagname still isn't set, then no tagged configuration + # was found and let the user know that the "--tag" command + # line option must be used. + if test -z "$tagname"; then + func_echo "unable to infer tagged configuration" + func_fatal_error "specify a tag with \`--tag'" +# else +# func_verbose "using $tagname tagged configuration" + fi + ;; + esac + fi +} + + + +# func_write_libtool_object output_name pic_name nonpic_name +# Create a libtool object file (analogous to a ".la" file), +# but don't create it if we're doing a dry run. +func_write_libtool_object () +{ + write_libobj=${1} + if test "$build_libtool_libs" = yes; then + write_lobj=\'${2}\' + else + write_lobj=none + fi + + if test "$build_old_libs" = yes; then + write_oldobj=\'${3}\' + else + write_oldobj=none + fi + + $opt_dry_run || { + cat >${write_libobj}T </dev/null` + if test "$?" -eq 0 && test -n "${func_convert_core_file_wine_to_w32_tmp}"; then + func_convert_core_file_wine_to_w32_result=`$ECHO "$func_convert_core_file_wine_to_w32_tmp" | + $SED -e "$lt_sed_naive_backslashify"` + else + func_convert_core_file_wine_to_w32_result= + fi + fi +} +# end: func_convert_core_file_wine_to_w32 + + +# func_convert_core_path_wine_to_w32 ARG +# Helper function used by path conversion functions when $build is *nix, and +# $host is mingw, cygwin, or some other w32 environment. Relies on a correctly +# configured wine environment available, with the winepath program in $build's +# $PATH. Assumes ARG has no leading or trailing path separator characters. +# +# ARG is path to be converted from $build format to win32. +# Result is available in $func_convert_core_path_wine_to_w32_result. +# Unconvertible file (directory) names in ARG are skipped; if no directory names +# are convertible, then the result may be empty. +func_convert_core_path_wine_to_w32 () +{ + $opt_debug + # unfortunately, winepath doesn't convert paths, only file names + func_convert_core_path_wine_to_w32_result="" + if test -n "$1"; then + oldIFS=$IFS + IFS=: + for func_convert_core_path_wine_to_w32_f in $1; do + IFS=$oldIFS + func_convert_core_file_wine_to_w32 "$func_convert_core_path_wine_to_w32_f" + if test -n "$func_convert_core_file_wine_to_w32_result" ; then + if test -z "$func_convert_core_path_wine_to_w32_result"; then + func_convert_core_path_wine_to_w32_result="$func_convert_core_file_wine_to_w32_result" + else + func_append func_convert_core_path_wine_to_w32_result ";$func_convert_core_file_wine_to_w32_result" + fi + fi + done + IFS=$oldIFS + fi +} +# end: func_convert_core_path_wine_to_w32 + + +# func_cygpath ARGS... +# Wrapper around calling the cygpath program via LT_CYGPATH. This is used when +# when (1) $build is *nix and Cygwin is hosted via a wine environment; or (2) +# $build is MSYS and $host is Cygwin, or (3) $build is Cygwin. In case (1) or +# (2), returns the Cygwin file name or path in func_cygpath_result (input +# file name or path is assumed to be in w32 format, as previously converted +# from $build's *nix or MSYS format). In case (3), returns the w32 file name +# or path in func_cygpath_result (input file name or path is assumed to be in +# Cygwin format). Returns an empty string on error. +# +# ARGS are passed to cygpath, with the last one being the file name or path to +# be converted. +# +# Specify the absolute *nix (or w32) name to cygpath in the LT_CYGPATH +# environment variable; do not put it in $PATH. +func_cygpath () +{ + $opt_debug + if test -n "$LT_CYGPATH" && test -f "$LT_CYGPATH"; then + func_cygpath_result=`$LT_CYGPATH "$@" 2>/dev/null` + if test "$?" -ne 0; then + # on failure, ensure result is empty + func_cygpath_result= + fi + else + func_cygpath_result= + func_error "LT_CYGPATH is empty or specifies non-existent file: \`$LT_CYGPATH'" + fi +} +#end: func_cygpath + + +# func_convert_core_msys_to_w32 ARG +# Convert file name or path ARG from MSYS format to w32 format. Return +# result in func_convert_core_msys_to_w32_result. +func_convert_core_msys_to_w32 () +{ + $opt_debug + # awkward: cmd appends spaces to result + func_convert_core_msys_to_w32_result=`( cmd //c echo "$1" ) 2>/dev/null | + $SED -e 's/[ ]*$//' -e "$lt_sed_naive_backslashify"` +} +#end: func_convert_core_msys_to_w32 + + +# func_convert_file_check ARG1 ARG2 +# Verify that ARG1 (a file name in $build format) was converted to $host +# format in ARG2. Otherwise, emit an error message, but continue (resetting +# func_to_host_file_result to ARG1). +func_convert_file_check () +{ + $opt_debug + if test -z "$2" && test -n "$1" ; then + func_error "Could not determine host file name corresponding to" + func_error " \`$1'" + func_error "Continuing, but uninstalled executables may not work." + # Fallback: + func_to_host_file_result="$1" + fi +} +# end func_convert_file_check + + +# func_convert_path_check FROM_PATHSEP TO_PATHSEP FROM_PATH TO_PATH +# Verify that FROM_PATH (a path in $build format) was converted to $host +# format in TO_PATH. Otherwise, emit an error message, but continue, resetting +# func_to_host_file_result to a simplistic fallback value (see below). +func_convert_path_check () +{ + $opt_debug + if test -z "$4" && test -n "$3"; then + func_error "Could not determine the host path corresponding to" + func_error " \`$3'" + func_error "Continuing, but uninstalled executables may not work." + # Fallback. This is a deliberately simplistic "conversion" and + # should not be "improved". See libtool.info. + if test "x$1" != "x$2"; then + lt_replace_pathsep_chars="s|$1|$2|g" + func_to_host_path_result=`echo "$3" | + $SED -e "$lt_replace_pathsep_chars"` + else + func_to_host_path_result="$3" + fi + fi +} +# end func_convert_path_check + + +# func_convert_path_front_back_pathsep FRONTPAT BACKPAT REPL ORIG +# Modifies func_to_host_path_result by prepending REPL if ORIG matches FRONTPAT +# and appending REPL if ORIG matches BACKPAT. +func_convert_path_front_back_pathsep () +{ + $opt_debug + case $4 in + $1 ) func_to_host_path_result="$3$func_to_host_path_result" + ;; + esac + case $4 in + $2 ) func_append func_to_host_path_result "$3" + ;; + esac +} +# end func_convert_path_front_back_pathsep + + +################################################## +# $build to $host FILE NAME CONVERSION FUNCTIONS # +################################################## +# invoked via `$to_host_file_cmd ARG' +# +# In each case, ARG is the path to be converted from $build to $host format. +# Result will be available in $func_to_host_file_result. + + +# func_to_host_file ARG +# Converts the file name ARG from $build format to $host format. Return result +# in func_to_host_file_result. +func_to_host_file () +{ + $opt_debug + $to_host_file_cmd "$1" +} +# end func_to_host_file + + +# func_to_tool_file ARG LAZY +# converts the file name ARG from $build format to toolchain format. Return +# result in func_to_tool_file_result. If the conversion in use is listed +# in (the comma separated) LAZY, no conversion takes place. +func_to_tool_file () +{ + $opt_debug + case ,$2, in + *,"$to_tool_file_cmd",*) + func_to_tool_file_result=$1 + ;; + *) + $to_tool_file_cmd "$1" + func_to_tool_file_result=$func_to_host_file_result + ;; + esac +} +# end func_to_tool_file + + +# func_convert_file_noop ARG +# Copy ARG to func_to_host_file_result. +func_convert_file_noop () +{ + func_to_host_file_result="$1" +} +# end func_convert_file_noop + + +# func_convert_file_msys_to_w32 ARG +# Convert file name ARG from (mingw) MSYS to (mingw) w32 format; automatic +# conversion to w32 is not available inside the cwrapper. Returns result in +# func_to_host_file_result. +func_convert_file_msys_to_w32 () +{ + $opt_debug + func_to_host_file_result="$1" + if test -n "$1"; then + func_convert_core_msys_to_w32 "$1" + func_to_host_file_result="$func_convert_core_msys_to_w32_result" + fi + func_convert_file_check "$1" "$func_to_host_file_result" +} +# end func_convert_file_msys_to_w32 + + +# func_convert_file_cygwin_to_w32 ARG +# Convert file name ARG from Cygwin to w32 format. Returns result in +# func_to_host_file_result. +func_convert_file_cygwin_to_w32 () +{ + $opt_debug + func_to_host_file_result="$1" + if test -n "$1"; then + # because $build is cygwin, we call "the" cygpath in $PATH; no need to use + # LT_CYGPATH in this case. + func_to_host_file_result=`cygpath -m "$1"` + fi + func_convert_file_check "$1" "$func_to_host_file_result" +} +# end func_convert_file_cygwin_to_w32 + + +# func_convert_file_nix_to_w32 ARG +# Convert file name ARG from *nix to w32 format. Requires a wine environment +# and a working winepath. Returns result in func_to_host_file_result. +func_convert_file_nix_to_w32 () +{ + $opt_debug + func_to_host_file_result="$1" + if test -n "$1"; then + func_convert_core_file_wine_to_w32 "$1" + func_to_host_file_result="$func_convert_core_file_wine_to_w32_result" + fi + func_convert_file_check "$1" "$func_to_host_file_result" +} +# end func_convert_file_nix_to_w32 + + +# func_convert_file_msys_to_cygwin ARG +# Convert file name ARG from MSYS to Cygwin format. Requires LT_CYGPATH set. +# Returns result in func_to_host_file_result. +func_convert_file_msys_to_cygwin () +{ + $opt_debug + func_to_host_file_result="$1" + if test -n "$1"; then + func_convert_core_msys_to_w32 "$1" + func_cygpath -u "$func_convert_core_msys_to_w32_result" + func_to_host_file_result="$func_cygpath_result" + fi + func_convert_file_check "$1" "$func_to_host_file_result" +} +# end func_convert_file_msys_to_cygwin + + +# func_convert_file_nix_to_cygwin ARG +# Convert file name ARG from *nix to Cygwin format. Requires Cygwin installed +# in a wine environment, working winepath, and LT_CYGPATH set. Returns result +# in func_to_host_file_result. +func_convert_file_nix_to_cygwin () +{ + $opt_debug + func_to_host_file_result="$1" + if test -n "$1"; then + # convert from *nix to w32, then use cygpath to convert from w32 to cygwin. + func_convert_core_file_wine_to_w32 "$1" + func_cygpath -u "$func_convert_core_file_wine_to_w32_result" + func_to_host_file_result="$func_cygpath_result" + fi + func_convert_file_check "$1" "$func_to_host_file_result" +} +# end func_convert_file_nix_to_cygwin + + +############################################# +# $build to $host PATH CONVERSION FUNCTIONS # +############################################# +# invoked via `$to_host_path_cmd ARG' +# +# In each case, ARG is the path to be converted from $build to $host format. +# The result will be available in $func_to_host_path_result. +# +# Path separators are also converted from $build format to $host format. If +# ARG begins or ends with a path separator character, it is preserved (but +# converted to $host format) on output. +# +# All path conversion functions are named using the following convention: +# file name conversion function : func_convert_file_X_to_Y () +# path conversion function : func_convert_path_X_to_Y () +# where, for any given $build/$host combination the 'X_to_Y' value is the +# same. If conversion functions are added for new $build/$host combinations, +# the two new functions must follow this pattern, or func_init_to_host_path_cmd +# will break. + + +# func_init_to_host_path_cmd +# Ensures that function "pointer" variable $to_host_path_cmd is set to the +# appropriate value, based on the value of $to_host_file_cmd. +to_host_path_cmd= +func_init_to_host_path_cmd () +{ + $opt_debug + if test -z "$to_host_path_cmd"; then + func_stripname 'func_convert_file_' '' "$to_host_file_cmd" + to_host_path_cmd="func_convert_path_${func_stripname_result}" + fi +} + + +# func_to_host_path ARG +# Converts the path ARG from $build format to $host format. Return result +# in func_to_host_path_result. +func_to_host_path () +{ + $opt_debug + func_init_to_host_path_cmd + $to_host_path_cmd "$1" +} +# end func_to_host_path + + +# func_convert_path_noop ARG +# Copy ARG to func_to_host_path_result. +func_convert_path_noop () +{ + func_to_host_path_result="$1" +} +# end func_convert_path_noop + + +# func_convert_path_msys_to_w32 ARG +# Convert path ARG from (mingw) MSYS to (mingw) w32 format; automatic +# conversion to w32 is not available inside the cwrapper. Returns result in +# func_to_host_path_result. +func_convert_path_msys_to_w32 () +{ + $opt_debug + func_to_host_path_result="$1" + if test -n "$1"; then + # Remove leading and trailing path separator characters from ARG. MSYS + # behavior is inconsistent here; cygpath turns them into '.;' and ';.'; + # and winepath ignores them completely. + func_stripname : : "$1" + func_to_host_path_tmp1=$func_stripname_result + func_convert_core_msys_to_w32 "$func_to_host_path_tmp1" + func_to_host_path_result="$func_convert_core_msys_to_w32_result" + func_convert_path_check : ";" \ + "$func_to_host_path_tmp1" "$func_to_host_path_result" + func_convert_path_front_back_pathsep ":*" "*:" ";" "$1" + fi +} +# end func_convert_path_msys_to_w32 + + +# func_convert_path_cygwin_to_w32 ARG +# Convert path ARG from Cygwin to w32 format. Returns result in +# func_to_host_file_result. +func_convert_path_cygwin_to_w32 () +{ + $opt_debug + func_to_host_path_result="$1" + if test -n "$1"; then + # See func_convert_path_msys_to_w32: + func_stripname : : "$1" + func_to_host_path_tmp1=$func_stripname_result + func_to_host_path_result=`cygpath -m -p "$func_to_host_path_tmp1"` + func_convert_path_check : ";" \ + "$func_to_host_path_tmp1" "$func_to_host_path_result" + func_convert_path_front_back_pathsep ":*" "*:" ";" "$1" + fi +} +# end func_convert_path_cygwin_to_w32 + + +# func_convert_path_nix_to_w32 ARG +# Convert path ARG from *nix to w32 format. Requires a wine environment and +# a working winepath. Returns result in func_to_host_file_result. +func_convert_path_nix_to_w32 () +{ + $opt_debug + func_to_host_path_result="$1" + if test -n "$1"; then + # See func_convert_path_msys_to_w32: + func_stripname : : "$1" + func_to_host_path_tmp1=$func_stripname_result + func_convert_core_path_wine_to_w32 "$func_to_host_path_tmp1" + func_to_host_path_result="$func_convert_core_path_wine_to_w32_result" + func_convert_path_check : ";" \ + "$func_to_host_path_tmp1" "$func_to_host_path_result" + func_convert_path_front_back_pathsep ":*" "*:" ";" "$1" + fi +} +# end func_convert_path_nix_to_w32 + + +# func_convert_path_msys_to_cygwin ARG +# Convert path ARG from MSYS to Cygwin format. Requires LT_CYGPATH set. +# Returns result in func_to_host_file_result. +func_convert_path_msys_to_cygwin () +{ + $opt_debug + func_to_host_path_result="$1" + if test -n "$1"; then + # See func_convert_path_msys_to_w32: + func_stripname : : "$1" + func_to_host_path_tmp1=$func_stripname_result + func_convert_core_msys_to_w32 "$func_to_host_path_tmp1" + func_cygpath -u -p "$func_convert_core_msys_to_w32_result" + func_to_host_path_result="$func_cygpath_result" + func_convert_path_check : : \ + "$func_to_host_path_tmp1" "$func_to_host_path_result" + func_convert_path_front_back_pathsep ":*" "*:" : "$1" + fi +} +# end func_convert_path_msys_to_cygwin + + +# func_convert_path_nix_to_cygwin ARG +# Convert path ARG from *nix to Cygwin format. Requires Cygwin installed in a +# a wine environment, working winepath, and LT_CYGPATH set. Returns result in +# func_to_host_file_result. +func_convert_path_nix_to_cygwin () +{ + $opt_debug + func_to_host_path_result="$1" + if test -n "$1"; then + # Remove leading and trailing path separator characters from + # ARG. msys behavior is inconsistent here, cygpath turns them + # into '.;' and ';.', and winepath ignores them completely. + func_stripname : : "$1" + func_to_host_path_tmp1=$func_stripname_result + func_convert_core_path_wine_to_w32 "$func_to_host_path_tmp1" + func_cygpath -u -p "$func_convert_core_path_wine_to_w32_result" + func_to_host_path_result="$func_cygpath_result" + func_convert_path_check : : \ + "$func_to_host_path_tmp1" "$func_to_host_path_result" + func_convert_path_front_back_pathsep ":*" "*:" : "$1" + fi +} +# end func_convert_path_nix_to_cygwin + + +# func_mode_compile arg... +func_mode_compile () +{ + $opt_debug + # Get the compilation command and the source file. + base_compile= + srcfile="$nonopt" # always keep a non-empty value in "srcfile" + suppress_opt=yes + suppress_output= + arg_mode=normal + libobj= + later= + pie_flag= + + for arg + do + case $arg_mode in + arg ) + # do not "continue". Instead, add this to base_compile + lastarg="$arg" + arg_mode=normal + ;; + + target ) + libobj="$arg" + arg_mode=normal + continue + ;; + + normal ) + # Accept any command-line options. + case $arg in + -o) + test -n "$libobj" && \ + func_fatal_error "you cannot specify \`-o' more than once" + arg_mode=target + continue + ;; + + -pie | -fpie | -fPIE) + func_append pie_flag " $arg" + continue + ;; + + -shared | -static | -prefer-pic | -prefer-non-pic) + func_append later " $arg" + continue + ;; + + -no-suppress) + suppress_opt=no + continue + ;; + + -Xcompiler) + arg_mode=arg # the next one goes into the "base_compile" arg list + continue # The current "srcfile" will either be retained or + ;; # replaced later. I would guess that would be a bug. + + -Wc,*) + func_stripname '-Wc,' '' "$arg" + args=$func_stripname_result + lastarg= + save_ifs="$IFS"; IFS=',' + for arg in $args; do + IFS="$save_ifs" + func_append_quoted lastarg "$arg" + done + IFS="$save_ifs" + func_stripname ' ' '' "$lastarg" + lastarg=$func_stripname_result + + # Add the arguments to base_compile. + func_append base_compile " $lastarg" + continue + ;; + + *) + # Accept the current argument as the source file. + # The previous "srcfile" becomes the current argument. + # + lastarg="$srcfile" + srcfile="$arg" + ;; + esac # case $arg + ;; + esac # case $arg_mode + + # Aesthetically quote the previous argument. + func_append_quoted base_compile "$lastarg" + done # for arg + + case $arg_mode in + arg) + func_fatal_error "you must specify an argument for -Xcompile" + ;; + target) + func_fatal_error "you must specify a target with \`-o'" + ;; + *) + # Get the name of the library object. + test -z "$libobj" && { + func_basename "$srcfile" + libobj="$func_basename_result" + } + ;; + esac + + # Recognize several different file suffixes. + # If the user specifies -o file.o, it is replaced with file.lo + case $libobj in + *.[cCFSifmso] | \ + *.ada | *.adb | *.ads | *.asm | \ + *.c++ | *.cc | *.ii | *.class | *.cpp | *.cxx | \ + *.[fF][09]? | *.for | *.java | *.go | *.obj | *.sx | *.cu | *.cup) + func_xform "$libobj" + libobj=$func_xform_result + ;; + esac + + case $libobj in + *.lo) func_lo2o "$libobj"; obj=$func_lo2o_result ;; + *) + func_fatal_error "cannot determine name of library object from \`$libobj'" + ;; + esac + + func_infer_tag $base_compile + + for arg in $later; do + case $arg in + -shared) + test "$build_libtool_libs" != yes && \ + func_fatal_configuration "can not build a shared library" + build_old_libs=no + continue + ;; + + -static) + build_libtool_libs=no + build_old_libs=yes + continue + ;; + + -prefer-pic) + pic_mode=yes + continue + ;; + + -prefer-non-pic) + pic_mode=no + continue + ;; + esac + done + + func_quote_for_eval "$libobj" + test "X$libobj" != "X$func_quote_for_eval_result" \ + && $ECHO "X$libobj" | $GREP '[]~#^*{};<>?"'"'"' &()|`$[]' \ + && func_warning "libobj name \`$libobj' may not contain shell special characters." + func_dirname_and_basename "$obj" "/" "" + objname="$func_basename_result" + xdir="$func_dirname_result" + lobj=${xdir}$objdir/$objname + + test -z "$base_compile" && \ + func_fatal_help "you must specify a compilation command" + + # Delete any leftover library objects. + if test "$build_old_libs" = yes; then + removelist="$obj $lobj $libobj ${libobj}T" + else + removelist="$lobj $libobj ${libobj}T" + fi + + # On Cygwin there's no "real" PIC flag so we must build both object types + case $host_os in + cygwin* | mingw* | pw32* | os2* | cegcc*) + pic_mode=default + ;; + esac + if test "$pic_mode" = no && test "$deplibs_check_method" != pass_all; then + # non-PIC code in shared libraries is not supported + pic_mode=default + fi + + # Calculate the filename of the output object if compiler does + # not support -o with -c + if test "$compiler_c_o" = no; then + output_obj=`$ECHO "$srcfile" | $SED 's%^.*/%%; s%\.[^.]*$%%'`.${objext} + lockfile="$output_obj.lock" + else + output_obj= + need_locks=no + lockfile= + fi + + # Lock this critical section if it is needed + # We use this script file to make the link, it avoids creating a new file + if test "$need_locks" = yes; then + until $opt_dry_run || ln "$progpath" "$lockfile" 2>/dev/null; do + func_echo "Waiting for $lockfile to be removed" + sleep 2 + done + elif test "$need_locks" = warn; then + if test -f "$lockfile"; then + $ECHO "\ +*** ERROR, $lockfile exists and contains: +`cat $lockfile 2>/dev/null` + +This indicates that another process is trying to use the same +temporary object file, and libtool could not work around it because +your compiler does not support \`-c' and \`-o' together. If you +repeat this compilation, it may succeed, by chance, but you had better +avoid parallel builds (make -j) in this platform, or get a better +compiler." + + $opt_dry_run || $RM $removelist + exit $EXIT_FAILURE + fi + func_append removelist " $output_obj" + $ECHO "$srcfile" > "$lockfile" + fi + + $opt_dry_run || $RM $removelist + func_append removelist " $lockfile" + trap '$opt_dry_run || $RM $removelist; exit $EXIT_FAILURE' 1 2 15 + + func_to_tool_file "$srcfile" func_convert_file_msys_to_w32 + srcfile=$func_to_tool_file_result + func_quote_for_eval "$srcfile" + qsrcfile=$func_quote_for_eval_result + + # Only build a PIC object if we are building libtool libraries. + if test "$build_libtool_libs" = yes; then + # Without this assignment, base_compile gets emptied. + fbsd_hideous_sh_bug=$base_compile + + if test "$pic_mode" != no; then + command="$base_compile $qsrcfile $pic_flag" + else + # Don't build PIC code + command="$base_compile $qsrcfile" + fi + + func_mkdir_p "$xdir$objdir" + + if test -z "$output_obj"; then + # Place PIC objects in $objdir + func_append command " -o $lobj" + fi + + func_show_eval_locale "$command" \ + 'test -n "$output_obj" && $RM $removelist; exit $EXIT_FAILURE' + + if test "$need_locks" = warn && + test "X`cat $lockfile 2>/dev/null`" != "X$srcfile"; then + $ECHO "\ +*** ERROR, $lockfile contains: +`cat $lockfile 2>/dev/null` + +but it should contain: +$srcfile + +This indicates that another process is trying to use the same +temporary object file, and libtool could not work around it because +your compiler does not support \`-c' and \`-o' together. If you +repeat this compilation, it may succeed, by chance, but you had better +avoid parallel builds (make -j) in this platform, or get a better +compiler." + + $opt_dry_run || $RM $removelist + exit $EXIT_FAILURE + fi + + # Just move the object if needed, then go on to compile the next one + if test -n "$output_obj" && test "X$output_obj" != "X$lobj"; then + func_show_eval '$MV "$output_obj" "$lobj"' \ + 'error=$?; $opt_dry_run || $RM $removelist; exit $error' + fi + + # Allow error messages only from the first compilation. + if test "$suppress_opt" = yes; then + suppress_output=' >/dev/null 2>&1' + fi + fi + + # Only build a position-dependent object if we build old libraries. + if test "$build_old_libs" = yes; then + if test "$pic_mode" != yes; then + # Don't build PIC code + command="$base_compile $qsrcfile$pie_flag" + else + command="$base_compile $qsrcfile $pic_flag" + fi + if test "$compiler_c_o" = yes; then + func_append command " -o $obj" + fi + + # Suppress compiler output if we already did a PIC compilation. + func_append command "$suppress_output" + func_show_eval_locale "$command" \ + '$opt_dry_run || $RM $removelist; exit $EXIT_FAILURE' + + if test "$need_locks" = warn && + test "X`cat $lockfile 2>/dev/null`" != "X$srcfile"; then + $ECHO "\ +*** ERROR, $lockfile contains: +`cat $lockfile 2>/dev/null` + +but it should contain: +$srcfile + +This indicates that another process is trying to use the same +temporary object file, and libtool could not work around it because +your compiler does not support \`-c' and \`-o' together. If you +repeat this compilation, it may succeed, by chance, but you had better +avoid parallel builds (make -j) in this platform, or get a better +compiler." + + $opt_dry_run || $RM $removelist + exit $EXIT_FAILURE + fi + + # Just move the object if needed + if test -n "$output_obj" && test "X$output_obj" != "X$obj"; then + func_show_eval '$MV "$output_obj" "$obj"' \ + 'error=$?; $opt_dry_run || $RM $removelist; exit $error' + fi + fi + + $opt_dry_run || { + func_write_libtool_object "$libobj" "$objdir/$objname" "$objname" + + # Unlock the critical section if it was locked + if test "$need_locks" != no; then + removelist=$lockfile + $RM "$lockfile" + fi + } + + exit $EXIT_SUCCESS +} + +$opt_help || { + test "$opt_mode" = compile && func_mode_compile ${1+"$@"} +} + +func_mode_help () +{ + # We need to display help for each of the modes. + case $opt_mode in + "") + # Generic help is extracted from the usage comments + # at the start of this file. + func_help + ;; + + clean) + $ECHO \ +"Usage: $progname [OPTION]... --mode=clean RM [RM-OPTION]... FILE... + +Remove files from the build directory. + +RM is the name of the program to use to delete files associated with each FILE +(typically \`/bin/rm'). RM-OPTIONS are options (such as \`-f') to be passed +to RM. + +If FILE is a libtool library, object or program, all the files associated +with it are deleted. Otherwise, only FILE itself is deleted using RM." + ;; + + compile) + $ECHO \ +"Usage: $progname [OPTION]... --mode=compile COMPILE-COMMAND... SOURCEFILE + +Compile a source file into a libtool library object. + +This mode accepts the following additional options: + + -o OUTPUT-FILE set the output file name to OUTPUT-FILE + -no-suppress do not suppress compiler output for multiple passes + -prefer-pic try to build PIC objects only + -prefer-non-pic try to build non-PIC objects only + -shared do not build a \`.o' file suitable for static linking + -static only build a \`.o' file suitable for static linking + -Wc,FLAG pass FLAG directly to the compiler + +COMPILE-COMMAND is a command to be used in creating a \`standard' object file +from the given SOURCEFILE. + +The output file name is determined by removing the directory component from +SOURCEFILE, then substituting the C source code suffix \`.c' with the +library object suffix, \`.lo'." + ;; + + execute) + $ECHO \ +"Usage: $progname [OPTION]... --mode=execute COMMAND [ARGS]... + +Automatically set library path, then run a program. + +This mode accepts the following additional options: + + -dlopen FILE add the directory containing FILE to the library path + +This mode sets the library path environment variable according to \`-dlopen' +flags. + +If any of the ARGS are libtool executable wrappers, then they are translated +into their corresponding uninstalled binary, and any of their required library +directories are added to the library path. + +Then, COMMAND is executed, with ARGS as arguments." + ;; + + finish) + $ECHO \ +"Usage: $progname [OPTION]... --mode=finish [LIBDIR]... + +Complete the installation of libtool libraries. + +Each LIBDIR is a directory that contains libtool libraries. + +The commands that this mode executes may require superuser privileges. Use +the \`--dry-run' option if you just want to see what would be executed." + ;; + + install) + $ECHO \ +"Usage: $progname [OPTION]... --mode=install INSTALL-COMMAND... + +Install executables or libraries. + +INSTALL-COMMAND is the installation command. The first component should be +either the \`install' or \`cp' program. + +The following components of INSTALL-COMMAND are treated specially: + + -inst-prefix-dir PREFIX-DIR Use PREFIX-DIR as a staging area for installation + +The rest of the components are interpreted as arguments to that command (only +BSD-compatible install options are recognized)." + ;; + + link) + $ECHO \ +"Usage: $progname [OPTION]... --mode=link LINK-COMMAND... + +Link object files or libraries together to form another library, or to +create an executable program. + +LINK-COMMAND is a command using the C compiler that you would use to create +a program from several object files. + +The following components of LINK-COMMAND are treated specially: + + -all-static do not do any dynamic linking at all + -avoid-version do not add a version suffix if possible + -bindir BINDIR specify path to binaries directory (for systems where + libraries must be found in the PATH setting at runtime) + -dlopen FILE \`-dlpreopen' FILE if it cannot be dlopened at runtime + -dlpreopen FILE link in FILE and add its symbols to lt_preloaded_symbols + -export-dynamic allow symbols from OUTPUT-FILE to be resolved with dlsym(3) + -export-symbols SYMFILE + try to export only the symbols listed in SYMFILE + -export-symbols-regex REGEX + try to export only the symbols matching REGEX + -LLIBDIR search LIBDIR for required installed libraries + -lNAME OUTPUT-FILE requires the installed library libNAME + -module build a library that can dlopened + -no-fast-install disable the fast-install mode + -no-install link a not-installable executable + -no-undefined declare that a library does not refer to external symbols + -o OUTPUT-FILE create OUTPUT-FILE from the specified objects + -objectlist FILE Use a list of object files found in FILE to specify objects + -precious-files-regex REGEX + don't remove output files matching REGEX + -release RELEASE specify package release information + -rpath LIBDIR the created library will eventually be installed in LIBDIR + -R[ ]LIBDIR add LIBDIR to the runtime path of programs and libraries + -shared only do dynamic linking of libtool libraries + -shrext SUFFIX override the standard shared library file extension + -static do not do any dynamic linking of uninstalled libtool libraries + -static-libtool-libs + do not do any dynamic linking of libtool libraries + -version-info CURRENT[:REVISION[:AGE]] + specify library version info [each variable defaults to 0] + -weak LIBNAME declare that the target provides the LIBNAME interface + -Wc,FLAG + -Xcompiler FLAG pass linker-specific FLAG directly to the compiler + -Wl,FLAG + -Xlinker FLAG pass linker-specific FLAG directly to the linker + -XCClinker FLAG pass link-specific FLAG to the compiler driver (CC) + +All other options (arguments beginning with \`-') are ignored. + +Every other argument is treated as a filename. Files ending in \`.la' are +treated as uninstalled libtool libraries, other files are standard or library +object files. + +If the OUTPUT-FILE ends in \`.la', then a libtool library is created, +only library objects (\`.lo' files) may be specified, and \`-rpath' is +required, except when creating a convenience library. + +If OUTPUT-FILE ends in \`.a' or \`.lib', then a standard library is created +using \`ar' and \`ranlib', or on Windows using \`lib'. + +If OUTPUT-FILE ends in \`.lo' or \`.${objext}', then a reloadable object file +is created, otherwise an executable program is created." + ;; + + uninstall) + $ECHO \ +"Usage: $progname [OPTION]... --mode=uninstall RM [RM-OPTION]... FILE... + +Remove libraries from an installation directory. + +RM is the name of the program to use to delete files associated with each FILE +(typically \`/bin/rm'). RM-OPTIONS are options (such as \`-f') to be passed +to RM. + +If FILE is a libtool library, all the files associated with it are deleted. +Otherwise, only FILE itself is deleted using RM." + ;; + + *) + func_fatal_help "invalid operation mode \`$opt_mode'" + ;; + esac + + echo + $ECHO "Try \`$progname --help' for more information about other modes." +} + +# Now that we've collected a possible --mode arg, show help if necessary +if $opt_help; then + if test "$opt_help" = :; then + func_mode_help + else + { + func_help noexit + for opt_mode in compile link execute install finish uninstall clean; do + func_mode_help + done + } | sed -n '1p; 2,$s/^Usage:/ or: /p' + { + func_help noexit + for opt_mode in compile link execute install finish uninstall clean; do + echo + func_mode_help + done + } | + sed '1d + /^When reporting/,/^Report/{ + H + d + } + $x + /information about other modes/d + /more detailed .*MODE/d + s/^Usage:.*--mode=\([^ ]*\) .*/Description of \1 mode:/' + fi + exit $? +fi + + +# func_mode_execute arg... +func_mode_execute () +{ + $opt_debug + # The first argument is the command name. + cmd="$nonopt" + test -z "$cmd" && \ + func_fatal_help "you must specify a COMMAND" + + # Handle -dlopen flags immediately. + for file in $opt_dlopen; do + test -f "$file" \ + || func_fatal_help "\`$file' is not a file" + + dir= + case $file in + *.la) + func_resolve_sysroot "$file" + file=$func_resolve_sysroot_result + + # Check to see that this really is a libtool archive. + func_lalib_unsafe_p "$file" \ + || func_fatal_help "\`$lib' is not a valid libtool archive" + + # Read the libtool library. + dlname= + library_names= + func_source "$file" + + # Skip this library if it cannot be dlopened. + if test -z "$dlname"; then + # Warn if it was a shared library. + test -n "$library_names" && \ + func_warning "\`$file' was not linked with \`-export-dynamic'" + continue + fi + + func_dirname "$file" "" "." + dir="$func_dirname_result" + + if test -f "$dir/$objdir/$dlname"; then + func_append dir "/$objdir" + else + if test ! -f "$dir/$dlname"; then + func_fatal_error "cannot find \`$dlname' in \`$dir' or \`$dir/$objdir'" + fi + fi + ;; + + *.lo) + # Just add the directory containing the .lo file. + func_dirname "$file" "" "." + dir="$func_dirname_result" + ;; + + *) + func_warning "\`-dlopen' is ignored for non-libtool libraries and objects" + continue + ;; + esac + + # Get the absolute pathname. + absdir=`cd "$dir" && pwd` + test -n "$absdir" && dir="$absdir" + + # Now add the directory to shlibpath_var. + if eval "test -z \"\$$shlibpath_var\""; then + eval "$shlibpath_var=\"\$dir\"" + else + eval "$shlibpath_var=\"\$dir:\$$shlibpath_var\"" + fi + done + + # This variable tells wrapper scripts just to set shlibpath_var + # rather than running their programs. + libtool_execute_magic="$magic" + + # Check if any of the arguments is a wrapper script. + args= + for file + do + case $file in + -* | *.la | *.lo ) ;; + *) + # Do a test to see if this is really a libtool program. + if func_ltwrapper_script_p "$file"; then + func_source "$file" + # Transform arg to wrapped name. + file="$progdir/$program" + elif func_ltwrapper_executable_p "$file"; then + func_ltwrapper_scriptname "$file" + func_source "$func_ltwrapper_scriptname_result" + # Transform arg to wrapped name. + file="$progdir/$program" + fi + ;; + esac + # Quote arguments (to preserve shell metacharacters). + func_append_quoted args "$file" + done + + if test "X$opt_dry_run" = Xfalse; then + if test -n "$shlibpath_var"; then + # Export the shlibpath_var. + eval "export $shlibpath_var" + fi + + # Restore saved environment variables + for lt_var in LANG LANGUAGE LC_ALL LC_CTYPE LC_COLLATE LC_MESSAGES + do + eval "if test \"\${save_$lt_var+set}\" = set; then + $lt_var=\$save_$lt_var; export $lt_var + else + $lt_unset $lt_var + fi" + done + + # Now prepare to actually exec the command. + exec_cmd="\$cmd$args" + else + # Display what would be done. + if test -n "$shlibpath_var"; then + eval "\$ECHO \"\$shlibpath_var=\$$shlibpath_var\"" + echo "export $shlibpath_var" + fi + $ECHO "$cmd$args" + exit $EXIT_SUCCESS + fi +} + +test "$opt_mode" = execute && func_mode_execute ${1+"$@"} + + +# func_mode_finish arg... +func_mode_finish () +{ + $opt_debug + libs= + libdirs= + admincmds= + + for opt in "$nonopt" ${1+"$@"} + do + if test -d "$opt"; then + func_append libdirs " $opt" + + elif test -f "$opt"; then + if func_lalib_unsafe_p "$opt"; then + func_append libs " $opt" + else + func_warning "\`$opt' is not a valid libtool archive" + fi + + else + func_fatal_error "invalid argument \`$opt'" + fi + done + + if test -n "$libs"; then + if test -n "$lt_sysroot"; then + sysroot_regex=`$ECHO "$lt_sysroot" | $SED "$sed_make_literal_regex"` + sysroot_cmd="s/\([ ']\)$sysroot_regex/\1/g;" + else + sysroot_cmd= + fi + + # Remove sysroot references + if $opt_dry_run; then + for lib in $libs; do + echo "removing references to $lt_sysroot and \`=' prefixes from $lib" + done + else + tmpdir=`func_mktempdir` + for lib in $libs; do + sed -e "${sysroot_cmd} s/\([ ']-[LR]\)=/\1/g; s/\([ ']\)=/\1/g" $lib \ + > $tmpdir/tmp-la + mv -f $tmpdir/tmp-la $lib + done + ${RM}r "$tmpdir" + fi + fi + + if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then + for libdir in $libdirs; do + if test -n "$finish_cmds"; then + # Do each command in the finish commands. + func_execute_cmds "$finish_cmds" 'admincmds="$admincmds +'"$cmd"'"' + fi + if test -n "$finish_eval"; then + # Do the single finish_eval. + eval cmds=\"$finish_eval\" + $opt_dry_run || eval "$cmds" || func_append admincmds " + $cmds" + fi + done + fi + + # Exit here if they wanted silent mode. + $opt_silent && exit $EXIT_SUCCESS + + if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then + echo "----------------------------------------------------------------------" + echo "Libraries have been installed in:" + for libdir in $libdirs; do + $ECHO " $libdir" + done + echo + echo "If you ever happen to want to link against installed libraries" + echo "in a given directory, LIBDIR, you must either use libtool, and" + echo "specify the full pathname of the library, or use the \`-LLIBDIR'" + echo "flag during linking and do at least one of the following:" + if test -n "$shlibpath_var"; then + echo " - add LIBDIR to the \`$shlibpath_var' environment variable" + echo " during execution" + fi + if test -n "$runpath_var"; then + echo " - add LIBDIR to the \`$runpath_var' environment variable" + echo " during linking" + fi + if test -n "$hardcode_libdir_flag_spec"; then + libdir=LIBDIR + eval flag=\"$hardcode_libdir_flag_spec\" + + $ECHO " - use the \`$flag' linker flag" + fi + if test -n "$admincmds"; then + $ECHO " - have your system administrator run these commands:$admincmds" + fi + if test -f /etc/ld.so.conf; then + echo " - have your system administrator add LIBDIR to \`/etc/ld.so.conf'" + fi + echo + + echo "See any operating system documentation about shared libraries for" + case $host in + solaris2.[6789]|solaris2.1[0-9]) + echo "more information, such as the ld(1), crle(1) and ld.so(8) manual" + echo "pages." + ;; + *) + echo "more information, such as the ld(1) and ld.so(8) manual pages." + ;; + esac + echo "----------------------------------------------------------------------" + fi + exit $EXIT_SUCCESS +} + +test "$opt_mode" = finish && func_mode_finish ${1+"$@"} + + +# func_mode_install arg... +func_mode_install () +{ + $opt_debug + # There may be an optional sh(1) argument at the beginning of + # install_prog (especially on Windows NT). + if test "$nonopt" = "$SHELL" || test "$nonopt" = /bin/sh || + # Allow the use of GNU shtool's install command. + case $nonopt in *shtool*) :;; *) false;; esac; then + # Aesthetically quote it. + func_quote_for_eval "$nonopt" + install_prog="$func_quote_for_eval_result " + arg=$1 + shift + else + install_prog= + arg=$nonopt + fi + + # The real first argument should be the name of the installation program. + # Aesthetically quote it. + func_quote_for_eval "$arg" + func_append install_prog "$func_quote_for_eval_result" + install_shared_prog=$install_prog + case " $install_prog " in + *[\\\ /]cp\ *) install_cp=: ;; + *) install_cp=false ;; + esac + + # We need to accept at least all the BSD install flags. + dest= + files= + opts= + prev= + install_type= + isdir=no + stripme= + no_mode=: + for arg + do + arg2= + if test -n "$dest"; then + func_append files " $dest" + dest=$arg + continue + fi + + case $arg in + -d) isdir=yes ;; + -f) + if $install_cp; then :; else + prev=$arg + fi + ;; + -g | -m | -o) + prev=$arg + ;; + -s) + stripme=" -s" + continue + ;; + -*) + ;; + *) + # If the previous option needed an argument, then skip it. + if test -n "$prev"; then + if test "x$prev" = x-m && test -n "$install_override_mode"; then + arg2=$install_override_mode + no_mode=false + fi + prev= + else + dest=$arg + continue + fi + ;; + esac + + # Aesthetically quote the argument. + func_quote_for_eval "$arg" + func_append install_prog " $func_quote_for_eval_result" + if test -n "$arg2"; then + func_quote_for_eval "$arg2" + fi + func_append install_shared_prog " $func_quote_for_eval_result" + done + + test -z "$install_prog" && \ + func_fatal_help "you must specify an install program" + + test -n "$prev" && \ + func_fatal_help "the \`$prev' option requires an argument" + + if test -n "$install_override_mode" && $no_mode; then + if $install_cp; then :; else + func_quote_for_eval "$install_override_mode" + func_append install_shared_prog " -m $func_quote_for_eval_result" + fi + fi + + if test -z "$files"; then + if test -z "$dest"; then + func_fatal_help "no file or destination specified" + else + func_fatal_help "you must specify a destination" + fi + fi + + # Strip any trailing slash from the destination. + func_stripname '' '/' "$dest" + dest=$func_stripname_result + + # Check to see that the destination is a directory. + test -d "$dest" && isdir=yes + if test "$isdir" = yes; then + destdir="$dest" + destname= + else + func_dirname_and_basename "$dest" "" "." + destdir="$func_dirname_result" + destname="$func_basename_result" + + # Not a directory, so check to see that there is only one file specified. + set dummy $files; shift + test "$#" -gt 1 && \ + func_fatal_help "\`$dest' is not a directory" + fi + case $destdir in + [\\/]* | [A-Za-z]:[\\/]*) ;; + *) + for file in $files; do + case $file in + *.lo) ;; + *) + func_fatal_help "\`$destdir' must be an absolute directory name" + ;; + esac + done + ;; + esac + + # This variable tells wrapper scripts just to set variables rather + # than running their programs. + libtool_install_magic="$magic" + + staticlibs= + future_libdirs= + current_libdirs= + for file in $files; do + + # Do each installation. + case $file in + *.$libext) + # Do the static libraries later. + func_append staticlibs " $file" + ;; + + *.la) + func_resolve_sysroot "$file" + file=$func_resolve_sysroot_result + + # Check to see that this really is a libtool archive. + func_lalib_unsafe_p "$file" \ + || func_fatal_help "\`$file' is not a valid libtool archive" + + library_names= + old_library= + relink_command= + func_source "$file" + + # Add the libdir to current_libdirs if it is the destination. + if test "X$destdir" = "X$libdir"; then + case "$current_libdirs " in + *" $libdir "*) ;; + *) func_append current_libdirs " $libdir" ;; + esac + else + # Note the libdir as a future libdir. + case "$future_libdirs " in + *" $libdir "*) ;; + *) func_append future_libdirs " $libdir" ;; + esac + fi + + func_dirname "$file" "/" "" + dir="$func_dirname_result" + func_append dir "$objdir" + + if test -n "$relink_command"; then + # Determine the prefix the user has applied to our future dir. + inst_prefix_dir=`$ECHO "$destdir" | $SED -e "s%$libdir\$%%"` + + # Don't allow the user to place us outside of our expected + # location b/c this prevents finding dependent libraries that + # are installed to the same prefix. + # At present, this check doesn't affect windows .dll's that + # are installed into $libdir/../bin (currently, that works fine) + # but it's something to keep an eye on. + test "$inst_prefix_dir" = "$destdir" && \ + func_fatal_error "error: cannot install \`$file' to a directory not ending in $libdir" + + if test -n "$inst_prefix_dir"; then + # Stick the inst_prefix_dir data into the link command. + relink_command=`$ECHO "$relink_command" | $SED "s%@inst_prefix_dir@%-inst-prefix-dir $inst_prefix_dir%"` + else + relink_command=`$ECHO "$relink_command" | $SED "s%@inst_prefix_dir@%%"` + fi + + func_warning "relinking \`$file'" + func_show_eval "$relink_command" \ + 'func_fatal_error "error: relink \`$file'\'' with the above command before installing it"' + fi + + # See the names of the shared library. + set dummy $library_names; shift + if test -n "$1"; then + realname="$1" + shift + + srcname="$realname" + test -n "$relink_command" && srcname="$realname"T + + # Install the shared library and build the symlinks. + func_show_eval "$install_shared_prog $dir/$srcname $destdir/$realname" \ + 'exit $?' + tstripme="$stripme" + case $host_os in + cygwin* | mingw* | pw32* | cegcc*) + case $realname in + *.dll.a) + tstripme="" + ;; + esac + ;; + esac + if test -n "$tstripme" && test -n "$striplib"; then + func_show_eval "$striplib $destdir/$realname" 'exit $?' + fi + + if test "$#" -gt 0; then + # Delete the old symlinks, and create new ones. + # Try `ln -sf' first, because the `ln' binary might depend on + # the symlink we replace! Solaris /bin/ln does not understand -f, + # so we also need to try rm && ln -s. + for linkname + do + test "$linkname" != "$realname" \ + && func_show_eval "(cd $destdir && { $LN_S -f $realname $linkname || { $RM $linkname && $LN_S $realname $linkname; }; })" + done + fi + + # Do each command in the postinstall commands. + lib="$destdir/$realname" + func_execute_cmds "$postinstall_cmds" 'exit $?' + fi + + # Install the pseudo-library for information purposes. + func_basename "$file" + name="$func_basename_result" + instname="$dir/$name"i + func_show_eval "$install_prog $instname $destdir/$name" 'exit $?' + + # Maybe install the static library, too. + test -n "$old_library" && func_append staticlibs " $dir/$old_library" + ;; + + *.lo) + # Install (i.e. copy) a libtool object. + + # Figure out destination file name, if it wasn't already specified. + if test -n "$destname"; then + destfile="$destdir/$destname" + else + func_basename "$file" + destfile="$func_basename_result" + destfile="$destdir/$destfile" + fi + + # Deduce the name of the destination old-style object file. + case $destfile in + *.lo) + func_lo2o "$destfile" + staticdest=$func_lo2o_result + ;; + *.$objext) + staticdest="$destfile" + destfile= + ;; + *) + func_fatal_help "cannot copy a libtool object to \`$destfile'" + ;; + esac + + # Install the libtool object if requested. + test -n "$destfile" && \ + func_show_eval "$install_prog $file $destfile" 'exit $?' + + # Install the old object if enabled. + if test "$build_old_libs" = yes; then + # Deduce the name of the old-style object file. + func_lo2o "$file" + staticobj=$func_lo2o_result + func_show_eval "$install_prog \$staticobj \$staticdest" 'exit $?' + fi + exit $EXIT_SUCCESS + ;; + + *) + # Figure out destination file name, if it wasn't already specified. + if test -n "$destname"; then + destfile="$destdir/$destname" + else + func_basename "$file" + destfile="$func_basename_result" + destfile="$destdir/$destfile" + fi + + # If the file is missing, and there is a .exe on the end, strip it + # because it is most likely a libtool script we actually want to + # install + stripped_ext="" + case $file in + *.exe) + if test ! -f "$file"; then + func_stripname '' '.exe' "$file" + file=$func_stripname_result + stripped_ext=".exe" + fi + ;; + esac + + # Do a test to see if this is really a libtool program. + case $host in + *cygwin* | *mingw*) + if func_ltwrapper_executable_p "$file"; then + func_ltwrapper_scriptname "$file" + wrapper=$func_ltwrapper_scriptname_result + else + func_stripname '' '.exe' "$file" + wrapper=$func_stripname_result + fi + ;; + *) + wrapper=$file + ;; + esac + if func_ltwrapper_script_p "$wrapper"; then + notinst_deplibs= + relink_command= + + func_source "$wrapper" + + # Check the variables that should have been set. + test -z "$generated_by_libtool_version" && \ + func_fatal_error "invalid libtool wrapper script \`$wrapper'" + + finalize=yes + for lib in $notinst_deplibs; do + # Check to see that each library is installed. + libdir= + if test -f "$lib"; then + func_source "$lib" + fi + libfile="$libdir/"`$ECHO "$lib" | $SED 's%^.*/%%g'` ### testsuite: skip nested quoting test + if test -n "$libdir" && test ! -f "$libfile"; then + func_warning "\`$lib' has not been installed in \`$libdir'" + finalize=no + fi + done + + relink_command= + func_source "$wrapper" + + outputname= + if test "$fast_install" = no && test -n "$relink_command"; then + $opt_dry_run || { + if test "$finalize" = yes; then + tmpdir=`func_mktempdir` + func_basename "$file$stripped_ext" + file="$func_basename_result" + outputname="$tmpdir/$file" + # Replace the output file specification. + relink_command=`$ECHO "$relink_command" | $SED 's%@OUTPUT@%'"$outputname"'%g'` + + $opt_silent || { + func_quote_for_expand "$relink_command" + eval "func_echo $func_quote_for_expand_result" + } + if eval "$relink_command"; then : + else + func_error "error: relink \`$file' with the above command before installing it" + $opt_dry_run || ${RM}r "$tmpdir" + continue + fi + file="$outputname" + else + func_warning "cannot relink \`$file'" + fi + } + else + # Install the binary that we compiled earlier. + file=`$ECHO "$file$stripped_ext" | $SED "s%\([^/]*\)$%$objdir/\1%"` + fi + fi + + # remove .exe since cygwin /usr/bin/install will append another + # one anyway + case $install_prog,$host in + */usr/bin/install*,*cygwin*) + case $file:$destfile in + *.exe:*.exe) + # this is ok + ;; + *.exe:*) + destfile=$destfile.exe + ;; + *:*.exe) + func_stripname '' '.exe' "$destfile" + destfile=$func_stripname_result + ;; + esac + ;; + esac + func_show_eval "$install_prog\$stripme \$file \$destfile" 'exit $?' + $opt_dry_run || if test -n "$outputname"; then + ${RM}r "$tmpdir" + fi + ;; + esac + done + + for file in $staticlibs; do + func_basename "$file" + name="$func_basename_result" + + # Set up the ranlib parameters. + oldlib="$destdir/$name" + func_to_tool_file "$oldlib" func_convert_file_msys_to_w32 + tool_oldlib=$func_to_tool_file_result + + func_show_eval "$install_prog \$file \$oldlib" 'exit $?' + + if test -n "$stripme" && test -n "$old_striplib"; then + func_show_eval "$old_striplib $tool_oldlib" 'exit $?' + fi + + # Do each command in the postinstall commands. + func_execute_cmds "$old_postinstall_cmds" 'exit $?' + done + + test -n "$future_libdirs" && \ + func_warning "remember to run \`$progname --finish$future_libdirs'" + + if test -n "$current_libdirs"; then + # Maybe just do a dry run. + $opt_dry_run && current_libdirs=" -n$current_libdirs" + exec_cmd='$SHELL $progpath $preserve_args --finish$current_libdirs' + else + exit $EXIT_SUCCESS + fi +} + +test "$opt_mode" = install && func_mode_install ${1+"$@"} + + +# func_generate_dlsyms outputname originator pic_p +# Extract symbols from dlprefiles and create ${outputname}S.o with +# a dlpreopen symbol table. +func_generate_dlsyms () +{ + $opt_debug + my_outputname="$1" + my_originator="$2" + my_pic_p="${3-no}" + my_prefix=`$ECHO "$my_originator" | sed 's%[^a-zA-Z0-9]%_%g'` + my_dlsyms= + + if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then + if test -n "$NM" && test -n "$global_symbol_pipe"; then + my_dlsyms="${my_outputname}S.c" + else + func_error "not configured to extract global symbols from dlpreopened files" + fi + fi + + if test -n "$my_dlsyms"; then + case $my_dlsyms in + "") ;; + *.c) + # Discover the nlist of each of the dlfiles. + nlist="$output_objdir/${my_outputname}.nm" + + func_show_eval "$RM $nlist ${nlist}S ${nlist}T" + + # Parse the name list into a source file. + func_verbose "creating $output_objdir/$my_dlsyms" + + $opt_dry_run || $ECHO > "$output_objdir/$my_dlsyms" "\ +/* $my_dlsyms - symbol resolution table for \`$my_outputname' dlsym emulation. */ +/* Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION */ + +#ifdef __cplusplus +extern \"C\" { +#endif + +#if defined(__GNUC__) && (((__GNUC__ == 4) && (__GNUC_MINOR__ >= 4)) || (__GNUC__ > 4)) +#pragma GCC diagnostic ignored \"-Wstrict-prototypes\" +#endif + +/* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests. */ +#if defined(_WIN32) || defined(__CYGWIN__) || defined(_WIN32_WCE) +/* DATA imports from DLLs on WIN32 con't be const, because runtime + relocations are performed -- see ld's documentation on pseudo-relocs. */ +# define LT_DLSYM_CONST +#elif defined(__osf__) +/* This system does not cope well with relocations in const data. */ +# define LT_DLSYM_CONST +#else +# define LT_DLSYM_CONST const +#endif + +/* External symbol declarations for the compiler. */\ +" + + if test "$dlself" = yes; then + func_verbose "generating symbol list for \`$output'" + + $opt_dry_run || echo ': @PROGRAM@ ' > "$nlist" + + # Add our own program objects to the symbol list. + progfiles=`$ECHO "$objs$old_deplibs" | $SP2NL | $SED "$lo2o" | $NL2SP` + for progfile in $progfiles; do + func_to_tool_file "$progfile" func_convert_file_msys_to_w32 + func_verbose "extracting global C symbols from \`$func_to_tool_file_result'" + $opt_dry_run || eval "$NM $func_to_tool_file_result | $global_symbol_pipe >> '$nlist'" + done + + if test -n "$exclude_expsyms"; then + $opt_dry_run || { + eval '$EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T' + eval '$MV "$nlist"T "$nlist"' + } + fi + + if test -n "$export_symbols_regex"; then + $opt_dry_run || { + eval '$EGREP -e "$export_symbols_regex" "$nlist" > "$nlist"T' + eval '$MV "$nlist"T "$nlist"' + } + fi + + # Prepare the list of exported symbols + if test -z "$export_symbols"; then + export_symbols="$output_objdir/$outputname.exp" + $opt_dry_run || { + $RM $export_symbols + eval "${SED} -n -e '/^: @PROGRAM@ $/d' -e 's/^.* \(.*\)$/\1/p' "'< "$nlist" > "$export_symbols"' + case $host in + *cygwin* | *mingw* | *cegcc* ) + eval "echo EXPORTS "'> "$output_objdir/$outputname.def"' + eval 'cat "$export_symbols" >> "$output_objdir/$outputname.def"' + ;; + esac + } + else + $opt_dry_run || { + eval "${SED} -e 's/\([].[*^$]\)/\\\\\1/g' -e 's/^/ /' -e 's/$/$/'"' < "$export_symbols" > "$output_objdir/$outputname.exp"' + eval '$GREP -f "$output_objdir/$outputname.exp" < "$nlist" > "$nlist"T' + eval '$MV "$nlist"T "$nlist"' + case $host in + *cygwin* | *mingw* | *cegcc* ) + eval "echo EXPORTS "'> "$output_objdir/$outputname.def"' + eval 'cat "$nlist" >> "$output_objdir/$outputname.def"' + ;; + esac + } + fi + fi + + for dlprefile in $dlprefiles; do + func_verbose "extracting global C symbols from \`$dlprefile'" + func_basename "$dlprefile" + name="$func_basename_result" + case $host in + *cygwin* | *mingw* | *cegcc* ) + # if an import library, we need to obtain dlname + if func_win32_import_lib_p "$dlprefile"; then + func_tr_sh "$dlprefile" + eval "curr_lafile=\$libfile_$func_tr_sh_result" + dlprefile_dlbasename="" + if test -n "$curr_lafile" && func_lalib_p "$curr_lafile"; then + # Use subshell, to avoid clobbering current variable values + dlprefile_dlname=`source "$curr_lafile" && echo "$dlname"` + if test -n "$dlprefile_dlname" ; then + func_basename "$dlprefile_dlname" + dlprefile_dlbasename="$func_basename_result" + else + # no lafile. user explicitly requested -dlpreopen . + $sharedlib_from_linklib_cmd "$dlprefile" + dlprefile_dlbasename=$sharedlib_from_linklib_result + fi + fi + $opt_dry_run || { + if test -n "$dlprefile_dlbasename" ; then + eval '$ECHO ": $dlprefile_dlbasename" >> "$nlist"' + else + func_warning "Could not compute DLL name from $name" + eval '$ECHO ": $name " >> "$nlist"' + fi + func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32 + eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe | + $SED -e '/I __imp/d' -e 's/I __nm_/D /;s/_nm__//' >> '$nlist'" + } + else # not an import lib + $opt_dry_run || { + eval '$ECHO ": $name " >> "$nlist"' + func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32 + eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe >> '$nlist'" + } + fi + ;; + *) + $opt_dry_run || { + eval '$ECHO ": $name " >> "$nlist"' + func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32 + eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe >> '$nlist'" + } + ;; + esac + done + + $opt_dry_run || { + # Make sure we have at least an empty file. + test -f "$nlist" || : > "$nlist" + + if test -n "$exclude_expsyms"; then + $EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T + $MV "$nlist"T "$nlist" + fi + + # Try sorting and uniquifying the output. + if $GREP -v "^: " < "$nlist" | + if sort -k 3 /dev/null 2>&1; then + sort -k 3 + else + sort +2 + fi | + uniq > "$nlist"S; then + : + else + $GREP -v "^: " < "$nlist" > "$nlist"S + fi + + if test -f "$nlist"S; then + eval "$global_symbol_to_cdecl"' < "$nlist"S >> "$output_objdir/$my_dlsyms"' + else + echo '/* NONE */' >> "$output_objdir/$my_dlsyms" + fi + + echo >> "$output_objdir/$my_dlsyms" "\ + +/* The mapping between symbol names and symbols. */ +typedef struct { + const char *name; + void *address; +} lt_dlsymlist; +extern LT_DLSYM_CONST lt_dlsymlist +lt_${my_prefix}_LTX_preloaded_symbols[]; +LT_DLSYM_CONST lt_dlsymlist +lt_${my_prefix}_LTX_preloaded_symbols[] = +{\ + { \"$my_originator\", (void *) 0 }," + + case $need_lib_prefix in + no) + eval "$global_symbol_to_c_name_address" < "$nlist" >> "$output_objdir/$my_dlsyms" + ;; + *) + eval "$global_symbol_to_c_name_address_lib_prefix" < "$nlist" >> "$output_objdir/$my_dlsyms" + ;; + esac + echo >> "$output_objdir/$my_dlsyms" "\ + {0, (void *) 0} +}; + +/* This works around a problem in FreeBSD linker */ +#ifdef FREEBSD_WORKAROUND +static const void *lt_preloaded_setup() { + return lt_${my_prefix}_LTX_preloaded_symbols; +} +#endif + +#ifdef __cplusplus +} +#endif\ +" + } # !$opt_dry_run + + pic_flag_for_symtable= + case "$compile_command " in + *" -static "*) ;; + *) + case $host in + # compiling the symbol table file with pic_flag works around + # a FreeBSD bug that causes programs to crash when -lm is + # linked before any other PIC object. But we must not use + # pic_flag when linking with -static. The problem exists in + # FreeBSD 2.2.6 and is fixed in FreeBSD 3.1. + *-*-freebsd2.*|*-*-freebsd3.0*|*-*-freebsdelf3.0*) + pic_flag_for_symtable=" $pic_flag -DFREEBSD_WORKAROUND" ;; + *-*-hpux*) + pic_flag_for_symtable=" $pic_flag" ;; + *) + if test "X$my_pic_p" != Xno; then + pic_flag_for_symtable=" $pic_flag" + fi + ;; + esac + ;; + esac + symtab_cflags= + for arg in $LTCFLAGS; do + case $arg in + -pie | -fpie | -fPIE) ;; + *) func_append symtab_cflags " $arg" ;; + esac + done + + # Now compile the dynamic symbol file. + func_show_eval '(cd $output_objdir && $LTCC$symtab_cflags -c$no_builtin_flag$pic_flag_for_symtable "$my_dlsyms")' 'exit $?' + + # Clean up the generated files. + func_show_eval '$RM "$output_objdir/$my_dlsyms" "$nlist" "${nlist}S" "${nlist}T"' + + # Transform the symbol file into the correct name. + symfileobj="$output_objdir/${my_outputname}S.$objext" + case $host in + *cygwin* | *mingw* | *cegcc* ) + if test -f "$output_objdir/$my_outputname.def"; then + compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$output_objdir/$my_outputname.def $symfileobj%"` + finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$output_objdir/$my_outputname.def $symfileobj%"` + else + compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$symfileobj%"` + finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$symfileobj%"` + fi + ;; + *) + compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$symfileobj%"` + finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$symfileobj%"` + ;; + esac + ;; + *) + func_fatal_error "unknown suffix for \`$my_dlsyms'" + ;; + esac + else + # We keep going just in case the user didn't refer to + # lt_preloaded_symbols. The linker will fail if global_symbol_pipe + # really was required. + + # Nullify the symbol file. + compile_command=`$ECHO "$compile_command" | $SED "s% @SYMFILE@%%"` + finalize_command=`$ECHO "$finalize_command" | $SED "s% @SYMFILE@%%"` + fi +} + +# func_win32_libid arg +# return the library type of file 'arg' +# +# Need a lot of goo to handle *both* DLLs and import libs +# Has to be a shell function in order to 'eat' the argument +# that is supplied when $file_magic_command is called. +# Despite the name, also deal with 64 bit binaries. +func_win32_libid () +{ + $opt_debug + win32_libid_type="unknown" + win32_fileres=`file -L $1 2>/dev/null` + case $win32_fileres in + *ar\ archive\ import\ library*) # definitely import + win32_libid_type="x86 archive import" + ;; + *ar\ archive*) # could be an import, or static + # Keep the egrep pattern in sync with the one in _LT_CHECK_MAGIC_METHOD. + if eval $OBJDUMP -f $1 | $SED -e '10q' 2>/dev/null | + $EGREP 'file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)' >/dev/null; then + func_to_tool_file "$1" func_convert_file_msys_to_w32 + win32_nmres=`eval $NM -f posix -A \"$func_to_tool_file_result\" | + $SED -n -e ' + 1,100{ + / I /{ + s,.*,import, + p + q + } + }'` + case $win32_nmres in + import*) win32_libid_type="x86 archive import";; + *) win32_libid_type="x86 archive static";; + esac + fi + ;; + *DLL*) + win32_libid_type="x86 DLL" + ;; + *executable*) # but shell scripts are "executable" too... + case $win32_fileres in + *MS\ Windows\ PE\ Intel*) + win32_libid_type="x86 DLL" + ;; + esac + ;; + esac + $ECHO "$win32_libid_type" +} + +# func_cygming_dll_for_implib ARG +# +# Platform-specific function to extract the +# name of the DLL associated with the specified +# import library ARG. +# Invoked by eval'ing the libtool variable +# $sharedlib_from_linklib_cmd +# Result is available in the variable +# $sharedlib_from_linklib_result +func_cygming_dll_for_implib () +{ + $opt_debug + sharedlib_from_linklib_result=`$DLLTOOL --identify-strict --identify "$1"` +} + +# func_cygming_dll_for_implib_fallback_core SECTION_NAME LIBNAMEs +# +# The is the core of a fallback implementation of a +# platform-specific function to extract the name of the +# DLL associated with the specified import library LIBNAME. +# +# SECTION_NAME is either .idata$6 or .idata$7, depending +# on the platform and compiler that created the implib. +# +# Echos the name of the DLL associated with the +# specified import library. +func_cygming_dll_for_implib_fallback_core () +{ + $opt_debug + match_literal=`$ECHO "$1" | $SED "$sed_make_literal_regex"` + $OBJDUMP -s --section "$1" "$2" 2>/dev/null | + $SED '/^Contents of section '"$match_literal"':/{ + # Place marker at beginning of archive member dllname section + s/.*/====MARK====/ + p + d + } + # These lines can sometimes be longer than 43 characters, but + # are always uninteresting + /:[ ]*file format pe[i]\{,1\}-/d + /^In archive [^:]*:/d + # Ensure marker is printed + /^====MARK====/p + # Remove all lines with less than 43 characters + /^.\{43\}/!d + # From remaining lines, remove first 43 characters + s/^.\{43\}//' | + $SED -n ' + # Join marker and all lines until next marker into a single line + /^====MARK====/ b para + H + $ b para + b + :para + x + s/\n//g + # Remove the marker + s/^====MARK====// + # Remove trailing dots and whitespace + s/[\. \t]*$// + # Print + /./p' | + # we now have a list, one entry per line, of the stringified + # contents of the appropriate section of all members of the + # archive which possess that section. Heuristic: eliminate + # all those which have a first or second character that is + # a '.' (that is, objdump's representation of an unprintable + # character.) This should work for all archives with less than + # 0x302f exports -- but will fail for DLLs whose name actually + # begins with a literal '.' or a single character followed by + # a '.'. + # + # Of those that remain, print the first one. + $SED -e '/^\./d;/^.\./d;q' +} + +# func_cygming_gnu_implib_p ARG +# This predicate returns with zero status (TRUE) if +# ARG is a GNU/binutils-style import library. Returns +# with nonzero status (FALSE) otherwise. +func_cygming_gnu_implib_p () +{ + $opt_debug + func_to_tool_file "$1" func_convert_file_msys_to_w32 + func_cygming_gnu_implib_tmp=`$NM "$func_to_tool_file_result" | eval "$global_symbol_pipe" | $EGREP ' (_head_[A-Za-z0-9_]+_[ad]l*|[A-Za-z0-9_]+_[ad]l*_iname)$'` + test -n "$func_cygming_gnu_implib_tmp" +} + +# func_cygming_ms_implib_p ARG +# This predicate returns with zero status (TRUE) if +# ARG is an MS-style import library. Returns +# with nonzero status (FALSE) otherwise. +func_cygming_ms_implib_p () +{ + $opt_debug + func_to_tool_file "$1" func_convert_file_msys_to_w32 + func_cygming_ms_implib_tmp=`$NM "$func_to_tool_file_result" | eval "$global_symbol_pipe" | $GREP '_NULL_IMPORT_DESCRIPTOR'` + test -n "$func_cygming_ms_implib_tmp" +} + +# func_cygming_dll_for_implib_fallback ARG +# Platform-specific function to extract the +# name of the DLL associated with the specified +# import library ARG. +# +# This fallback implementation is for use when $DLLTOOL +# does not support the --identify-strict option. +# Invoked by eval'ing the libtool variable +# $sharedlib_from_linklib_cmd +# Result is available in the variable +# $sharedlib_from_linklib_result +func_cygming_dll_for_implib_fallback () +{ + $opt_debug + if func_cygming_gnu_implib_p "$1" ; then + # binutils import library + sharedlib_from_linklib_result=`func_cygming_dll_for_implib_fallback_core '.idata$7' "$1"` + elif func_cygming_ms_implib_p "$1" ; then + # ms-generated import library + sharedlib_from_linklib_result=`func_cygming_dll_for_implib_fallback_core '.idata$6' "$1"` + else + # unknown + sharedlib_from_linklib_result="" + fi +} + + +# func_extract_an_archive dir oldlib +func_extract_an_archive () +{ + $opt_debug + f_ex_an_ar_dir="$1"; shift + f_ex_an_ar_oldlib="$1" + if test "$lock_old_archive_extraction" = yes; then + lockfile=$f_ex_an_ar_oldlib.lock + until $opt_dry_run || ln "$progpath" "$lockfile" 2>/dev/null; do + func_echo "Waiting for $lockfile to be removed" + sleep 2 + done + fi + func_show_eval "(cd \$f_ex_an_ar_dir && $AR x \"\$f_ex_an_ar_oldlib\")" \ + 'stat=$?; rm -f "$lockfile"; exit $stat' + if test "$lock_old_archive_extraction" = yes; then + $opt_dry_run || rm -f "$lockfile" + fi + if ($AR t "$f_ex_an_ar_oldlib" | sort | sort -uc >/dev/null 2>&1); then + : + else + func_fatal_error "object name conflicts in archive: $f_ex_an_ar_dir/$f_ex_an_ar_oldlib" + fi +} + + +# func_extract_archives gentop oldlib ... +func_extract_archives () +{ + $opt_debug + my_gentop="$1"; shift + my_oldlibs=${1+"$@"} + my_oldobjs="" + my_xlib="" + my_xabs="" + my_xdir="" + + for my_xlib in $my_oldlibs; do + # Extract the objects. + case $my_xlib in + [\\/]* | [A-Za-z]:[\\/]*) my_xabs="$my_xlib" ;; + *) my_xabs=`pwd`"/$my_xlib" ;; + esac + func_basename "$my_xlib" + my_xlib="$func_basename_result" + my_xlib_u=$my_xlib + while :; do + case " $extracted_archives " in + *" $my_xlib_u "*) + func_arith $extracted_serial + 1 + extracted_serial=$func_arith_result + my_xlib_u=lt$extracted_serial-$my_xlib ;; + *) break ;; + esac + done + extracted_archives="$extracted_archives $my_xlib_u" + my_xdir="$my_gentop/$my_xlib_u" + + func_mkdir_p "$my_xdir" + + case $host in + *-darwin*) + func_verbose "Extracting $my_xabs" + # Do not bother doing anything if just a dry run + $opt_dry_run || { + darwin_orig_dir=`pwd` + cd $my_xdir || exit $? + darwin_archive=$my_xabs + darwin_curdir=`pwd` + darwin_base_archive=`basename "$darwin_archive"` + darwin_arches=`$LIPO -info "$darwin_archive" 2>/dev/null | $GREP Architectures 2>/dev/null || true` + if test -n "$darwin_arches"; then + darwin_arches=`$ECHO "$darwin_arches" | $SED -e 's/.*are://'` + darwin_arch= + func_verbose "$darwin_base_archive has multiple architectures $darwin_arches" + for darwin_arch in $darwin_arches ; do + func_mkdir_p "unfat-$$/${darwin_base_archive}-${darwin_arch}" + $LIPO -thin $darwin_arch -output "unfat-$$/${darwin_base_archive}-${darwin_arch}/${darwin_base_archive}" "${darwin_archive}" + cd "unfat-$$/${darwin_base_archive}-${darwin_arch}" + func_extract_an_archive "`pwd`" "${darwin_base_archive}" + cd "$darwin_curdir" + $RM "unfat-$$/${darwin_base_archive}-${darwin_arch}/${darwin_base_archive}" + done # $darwin_arches + ## Okay now we've a bunch of thin objects, gotta fatten them up :) + darwin_filelist=`find unfat-$$ -type f -name \*.o -print -o -name \*.lo -print | $SED -e "$basename" | sort -u` + darwin_file= + darwin_files= + for darwin_file in $darwin_filelist; do + darwin_files=`find unfat-$$ -name $darwin_file -print | sort | $NL2SP` + $LIPO -create -output "$darwin_file" $darwin_files + done # $darwin_filelist + $RM -rf unfat-$$ + cd "$darwin_orig_dir" + else + cd $darwin_orig_dir + func_extract_an_archive "$my_xdir" "$my_xabs" + fi # $darwin_arches + } # !$opt_dry_run + ;; + *) + func_extract_an_archive "$my_xdir" "$my_xabs" + ;; + esac + my_oldobjs="$my_oldobjs "`find $my_xdir -name \*.$objext -print -o -name \*.lo -print | sort | $NL2SP` + done + + func_extract_archives_result="$my_oldobjs" +} + + +# func_emit_wrapper [arg=no] +# +# Emit a libtool wrapper script on stdout. +# Don't directly open a file because we may want to +# incorporate the script contents within a cygwin/mingw +# wrapper executable. Must ONLY be called from within +# func_mode_link because it depends on a number of variables +# set therein. +# +# ARG is the value that the WRAPPER_SCRIPT_BELONGS_IN_OBJDIR +# variable will take. If 'yes', then the emitted script +# will assume that the directory in which it is stored is +# the $objdir directory. This is a cygwin/mingw-specific +# behavior. +func_emit_wrapper () +{ + func_emit_wrapper_arg1=${1-no} + + $ECHO "\ +#! $SHELL + +# $output - temporary wrapper script for $objdir/$outputname +# Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION +# +# The $output program cannot be directly executed until all the libtool +# libraries that it depends on are installed. +# +# This wrapper script should never be moved out of the build directory. +# If it is, it will not operate correctly. + +# Sed substitution that helps us do robust quoting. It backslashifies +# metacharacters that are still active within double-quoted strings. +sed_quote_subst='$sed_quote_subst' + +# Be Bourne compatible +if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then + emulate sh + NULLCMD=: + # Zsh 3.x and 4.x performs word splitting on \${1+\"\$@\"}, which + # is contrary to our usage. Disable this feature. + alias -g '\${1+\"\$@\"}'='\"\$@\"' + setopt NO_GLOB_SUBST +else + case \`(set -o) 2>/dev/null\` in *posix*) set -o posix;; esac +fi +BIN_SH=xpg4; export BIN_SH # for Tru64 +DUALCASE=1; export DUALCASE # for MKS sh + +# The HP-UX ksh and POSIX shell print the target directory to stdout +# if CDPATH is set. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + +relink_command=\"$relink_command\" + +# This environment variable determines our operation mode. +if test \"\$libtool_install_magic\" = \"$magic\"; then + # install mode needs the following variables: + generated_by_libtool_version='$macro_version' + notinst_deplibs='$notinst_deplibs' +else + # When we are sourced in execute mode, \$file and \$ECHO are already set. + if test \"\$libtool_execute_magic\" != \"$magic\"; then + file=\"\$0\"" + + qECHO=`$ECHO "$ECHO" | $SED "$sed_quote_subst"` + $ECHO "\ + +# A function that is used when there is no print builtin or printf. +func_fallback_echo () +{ + eval 'cat <<_LTECHO_EOF +\$1 +_LTECHO_EOF' +} + ECHO=\"$qECHO\" + fi + +# Very basic option parsing. These options are (a) specific to +# the libtool wrapper, (b) are identical between the wrapper +# /script/ and the wrapper /executable/ which is used only on +# windows platforms, and (c) all begin with the string "--lt-" +# (application programs are unlikely to have options which match +# this pattern). +# +# There are only two supported options: --lt-debug and +# --lt-dump-script. There is, deliberately, no --lt-help. +# +# The first argument to this parsing function should be the +# script's $0 value, followed by "$@". +lt_option_debug= +func_parse_lt_options () +{ + lt_script_arg0=\$0 + shift + for lt_opt + do + case \"\$lt_opt\" in + --lt-debug) lt_option_debug=1 ;; + --lt-dump-script) + lt_dump_D=\`\$ECHO \"X\$lt_script_arg0\" | $SED -e 's/^X//' -e 's%/[^/]*$%%'\` + test \"X\$lt_dump_D\" = \"X\$lt_script_arg0\" && lt_dump_D=. + lt_dump_F=\`\$ECHO \"X\$lt_script_arg0\" | $SED -e 's/^X//' -e 's%^.*/%%'\` + cat \"\$lt_dump_D/\$lt_dump_F\" + exit 0 + ;; + --lt-*) + \$ECHO \"Unrecognized --lt- option: '\$lt_opt'\" 1>&2 + exit 1 + ;; + esac + done + + # Print the debug banner immediately: + if test -n \"\$lt_option_debug\"; then + echo \"${outputname}:${output}:\${LINENO}: libtool wrapper (GNU $PACKAGE$TIMESTAMP) $VERSION\" 1>&2 + fi +} + +# Used when --lt-debug. Prints its arguments to stdout +# (redirection is the responsibility of the caller) +func_lt_dump_args () +{ + lt_dump_args_N=1; + for lt_arg + do + \$ECHO \"${outputname}:${output}:\${LINENO}: newargv[\$lt_dump_args_N]: \$lt_arg\" + lt_dump_args_N=\`expr \$lt_dump_args_N + 1\` + done +} + +# Core function for launching the target application +func_exec_program_core () +{ +" + case $host in + # Backslashes separate directories on plain windows + *-*-mingw | *-*-os2* | *-cegcc*) + $ECHO "\ + if test -n \"\$lt_option_debug\"; then + \$ECHO \"${outputname}:${output}:\${LINENO}: newargv[0]: \$progdir\\\\\$program\" 1>&2 + func_lt_dump_args \${1+\"\$@\"} 1>&2 + fi + exec \"\$progdir\\\\\$program\" \${1+\"\$@\"} +" + ;; + + *) + $ECHO "\ + if test -n \"\$lt_option_debug\"; then + \$ECHO \"${outputname}:${output}:\${LINENO}: newargv[0]: \$progdir/\$program\" 1>&2 + func_lt_dump_args \${1+\"\$@\"} 1>&2 + fi + exec \"\$progdir/\$program\" \${1+\"\$@\"} +" + ;; + esac + $ECHO "\ + \$ECHO \"\$0: cannot exec \$program \$*\" 1>&2 + exit 1 +} + +# A function to encapsulate launching the target application +# Strips options in the --lt-* namespace from \$@ and +# launches target application with the remaining arguments. +func_exec_program () +{ + case \" \$* \" in + *\\ --lt-*) + for lt_wr_arg + do + case \$lt_wr_arg in + --lt-*) ;; + *) set x \"\$@\" \"\$lt_wr_arg\"; shift;; + esac + shift + done ;; + esac + func_exec_program_core \${1+\"\$@\"} +} + + # Parse options + func_parse_lt_options \"\$0\" \${1+\"\$@\"} + + # Find the directory that this script lives in. + thisdir=\`\$ECHO \"\$file\" | $SED 's%/[^/]*$%%'\` + test \"x\$thisdir\" = \"x\$file\" && thisdir=. + + # Follow symbolic links until we get to the real thisdir. + file=\`ls -ld \"\$file\" | $SED -n 's/.*-> //p'\` + while test -n \"\$file\"; do + destdir=\`\$ECHO \"\$file\" | $SED 's%/[^/]*\$%%'\` + + # If there was a directory component, then change thisdir. + if test \"x\$destdir\" != \"x\$file\"; then + case \"\$destdir\" in + [\\\\/]* | [A-Za-z]:[\\\\/]*) thisdir=\"\$destdir\" ;; + *) thisdir=\"\$thisdir/\$destdir\" ;; + esac + fi + + file=\`\$ECHO \"\$file\" | $SED 's%^.*/%%'\` + file=\`ls -ld \"\$thisdir/\$file\" | $SED -n 's/.*-> //p'\` + done + + # Usually 'no', except on cygwin/mingw when embedded into + # the cwrapper. + WRAPPER_SCRIPT_BELONGS_IN_OBJDIR=$func_emit_wrapper_arg1 + if test \"\$WRAPPER_SCRIPT_BELONGS_IN_OBJDIR\" = \"yes\"; then + # special case for '.' + if test \"\$thisdir\" = \".\"; then + thisdir=\`pwd\` + fi + # remove .libs from thisdir + case \"\$thisdir\" in + *[\\\\/]$objdir ) thisdir=\`\$ECHO \"\$thisdir\" | $SED 's%[\\\\/][^\\\\/]*$%%'\` ;; + $objdir ) thisdir=. ;; + esac + fi + + # Try to get the absolute directory name. + absdir=\`cd \"\$thisdir\" && pwd\` + test -n \"\$absdir\" && thisdir=\"\$absdir\" +" + + if test "$fast_install" = yes; then + $ECHO "\ + program=lt-'$outputname'$exeext + progdir=\"\$thisdir/$objdir\" + + if test ! -f \"\$progdir/\$program\" || + { file=\`ls -1dt \"\$progdir/\$program\" \"\$progdir/../\$program\" 2>/dev/null | ${SED} 1q\`; \\ + test \"X\$file\" != \"X\$progdir/\$program\"; }; then + + file=\"\$\$-\$program\" + + if test ! -d \"\$progdir\"; then + $MKDIR \"\$progdir\" + else + $RM \"\$progdir/\$file\" + fi" + + $ECHO "\ + + # relink executable if necessary + if test -n \"\$relink_command\"; then + if relink_command_output=\`eval \$relink_command 2>&1\`; then : + else + $ECHO \"\$relink_command_output\" >&2 + $RM \"\$progdir/\$file\" + exit 1 + fi + fi + + $MV \"\$progdir/\$file\" \"\$progdir/\$program\" 2>/dev/null || + { $RM \"\$progdir/\$program\"; + $MV \"\$progdir/\$file\" \"\$progdir/\$program\"; } + $RM \"\$progdir/\$file\" + fi" + else + $ECHO "\ + program='$outputname' + progdir=\"\$thisdir/$objdir\" +" + fi + + $ECHO "\ + + if test -f \"\$progdir/\$program\"; then" + + # fixup the dll searchpath if we need to. + # + # Fix the DLL searchpath if we need to. Do this before prepending + # to shlibpath, because on Windows, both are PATH and uninstalled + # libraries must come first. + if test -n "$dllsearchpath"; then + $ECHO "\ + # Add the dll search path components to the executable PATH + PATH=$dllsearchpath:\$PATH +" + fi + + # Export our shlibpath_var if we have one. + if test "$shlibpath_overrides_runpath" = yes && test -n "$shlibpath_var" && test -n "$temp_rpath"; then + $ECHO "\ + # Add our own library path to $shlibpath_var + $shlibpath_var=\"$temp_rpath\$$shlibpath_var\" + + # Some systems cannot cope with colon-terminated $shlibpath_var + # The second colon is a workaround for a bug in BeOS R4 sed + $shlibpath_var=\`\$ECHO \"\$$shlibpath_var\" | $SED 's/::*\$//'\` + + export $shlibpath_var +" + fi + + $ECHO "\ + if test \"\$libtool_execute_magic\" != \"$magic\"; then + # Run the actual program with our arguments. + func_exec_program \${1+\"\$@\"} + fi + else + # The program doesn't exist. + \$ECHO \"\$0: error: \\\`\$progdir/\$program' does not exist\" 1>&2 + \$ECHO \"This script is just a wrapper for \$program.\" 1>&2 + \$ECHO \"See the $PACKAGE documentation for more information.\" 1>&2 + exit 1 + fi +fi\ +" +} + + +# func_emit_cwrapperexe_src +# emit the source code for a wrapper executable on stdout +# Must ONLY be called from within func_mode_link because +# it depends on a number of variable set therein. +func_emit_cwrapperexe_src () +{ + cat < +#include +#ifdef _MSC_VER +# include +# include +# include +#else +# include +# include +# ifdef __CYGWIN__ +# include +# endif +#endif +#include +#include +#include +#include +#include +#include +#include +#include + +/* declarations of non-ANSI functions */ +#if defined(__MINGW32__) +# ifdef __STRICT_ANSI__ +int _putenv (const char *); +# endif +#elif defined(__CYGWIN__) +# ifdef __STRICT_ANSI__ +char *realpath (const char *, char *); +int putenv (char *); +int setenv (const char *, const char *, int); +# endif +/* #elif defined (other platforms) ... */ +#endif + +/* portability defines, excluding path handling macros */ +#if defined(_MSC_VER) +# define setmode _setmode +# define stat _stat +# define chmod _chmod +# define getcwd _getcwd +# define putenv _putenv +# define S_IXUSR _S_IEXEC +# ifndef _INTPTR_T_DEFINED +# define _INTPTR_T_DEFINED +# define intptr_t int +# endif +#elif defined(__MINGW32__) +# define setmode _setmode +# define stat _stat +# define chmod _chmod +# define getcwd _getcwd +# define putenv _putenv +#elif defined(__CYGWIN__) +# define HAVE_SETENV +# define FOPEN_WB "wb" +/* #elif defined (other platforms) ... */ +#endif + +#if defined(PATH_MAX) +# define LT_PATHMAX PATH_MAX +#elif defined(MAXPATHLEN) +# define LT_PATHMAX MAXPATHLEN +#else +# define LT_PATHMAX 1024 +#endif + +#ifndef S_IXOTH +# define S_IXOTH 0 +#endif +#ifndef S_IXGRP +# define S_IXGRP 0 +#endif + +/* path handling portability macros */ +#ifndef DIR_SEPARATOR +# define DIR_SEPARATOR '/' +# define PATH_SEPARATOR ':' +#endif + +#if defined (_WIN32) || defined (__MSDOS__) || defined (__DJGPP__) || \ + defined (__OS2__) +# define HAVE_DOS_BASED_FILE_SYSTEM +# define FOPEN_WB "wb" +# ifndef DIR_SEPARATOR_2 +# define DIR_SEPARATOR_2 '\\' +# endif +# ifndef PATH_SEPARATOR_2 +# define PATH_SEPARATOR_2 ';' +# endif +#endif + +#ifndef DIR_SEPARATOR_2 +# define IS_DIR_SEPARATOR(ch) ((ch) == DIR_SEPARATOR) +#else /* DIR_SEPARATOR_2 */ +# define IS_DIR_SEPARATOR(ch) \ + (((ch) == DIR_SEPARATOR) || ((ch) == DIR_SEPARATOR_2)) +#endif /* DIR_SEPARATOR_2 */ + +#ifndef PATH_SEPARATOR_2 +# define IS_PATH_SEPARATOR(ch) ((ch) == PATH_SEPARATOR) +#else /* PATH_SEPARATOR_2 */ +# define IS_PATH_SEPARATOR(ch) ((ch) == PATH_SEPARATOR_2) +#endif /* PATH_SEPARATOR_2 */ + +#ifndef FOPEN_WB +# define FOPEN_WB "w" +#endif +#ifndef _O_BINARY +# define _O_BINARY 0 +#endif + +#define XMALLOC(type, num) ((type *) xmalloc ((num) * sizeof(type))) +#define XFREE(stale) do { \ + if (stale) { free ((void *) stale); stale = 0; } \ +} while (0) + +#if defined(LT_DEBUGWRAPPER) +static int lt_debug = 1; +#else +static int lt_debug = 0; +#endif + +const char *program_name = "libtool-wrapper"; /* in case xstrdup fails */ + +void *xmalloc (size_t num); +char *xstrdup (const char *string); +const char *base_name (const char *name); +char *find_executable (const char *wrapper); +char *chase_symlinks (const char *pathspec); +int make_executable (const char *path); +int check_executable (const char *path); +char *strendzap (char *str, const char *pat); +void lt_debugprintf (const char *file, int line, const char *fmt, ...); +void lt_fatal (const char *file, int line, const char *message, ...); +static const char *nonnull (const char *s); +static const char *nonempty (const char *s); +void lt_setenv (const char *name, const char *value); +char *lt_extend_str (const char *orig_value, const char *add, int to_end); +void lt_update_exe_path (const char *name, const char *value); +void lt_update_lib_path (const char *name, const char *value); +char **prepare_spawn (char **argv); +void lt_dump_script (FILE *f); +EOF + + cat <= 0) + && (st.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH))) + return 1; + else + return 0; +} + +int +make_executable (const char *path) +{ + int rval = 0; + struct stat st; + + lt_debugprintf (__FILE__, __LINE__, "(make_executable): %s\n", + nonempty (path)); + if ((!path) || (!*path)) + return 0; + + if (stat (path, &st) >= 0) + { + rval = chmod (path, st.st_mode | S_IXOTH | S_IXGRP | S_IXUSR); + } + return rval; +} + +/* Searches for the full path of the wrapper. Returns + newly allocated full path name if found, NULL otherwise + Does not chase symlinks, even on platforms that support them. +*/ +char * +find_executable (const char *wrapper) +{ + int has_slash = 0; + const char *p; + const char *p_next; + /* static buffer for getcwd */ + char tmp[LT_PATHMAX + 1]; + int tmp_len; + char *concat_name; + + lt_debugprintf (__FILE__, __LINE__, "(find_executable): %s\n", + nonempty (wrapper)); + + if ((wrapper == NULL) || (*wrapper == '\0')) + return NULL; + + /* Absolute path? */ +#if defined (HAVE_DOS_BASED_FILE_SYSTEM) + if (isalpha ((unsigned char) wrapper[0]) && wrapper[1] == ':') + { + concat_name = xstrdup (wrapper); + if (check_executable (concat_name)) + return concat_name; + XFREE (concat_name); + } + else + { +#endif + if (IS_DIR_SEPARATOR (wrapper[0])) + { + concat_name = xstrdup (wrapper); + if (check_executable (concat_name)) + return concat_name; + XFREE (concat_name); + } +#if defined (HAVE_DOS_BASED_FILE_SYSTEM) + } +#endif + + for (p = wrapper; *p; p++) + if (*p == '/') + { + has_slash = 1; + break; + } + if (!has_slash) + { + /* no slashes; search PATH */ + const char *path = getenv ("PATH"); + if (path != NULL) + { + for (p = path; *p; p = p_next) + { + const char *q; + size_t p_len; + for (q = p; *q; q++) + if (IS_PATH_SEPARATOR (*q)) + break; + p_len = q - p; + p_next = (*q == '\0' ? q : q + 1); + if (p_len == 0) + { + /* empty path: current directory */ + if (getcwd (tmp, LT_PATHMAX) == NULL) + lt_fatal (__FILE__, __LINE__, "getcwd failed: %s", + nonnull (strerror (errno))); + tmp_len = strlen (tmp); + concat_name = + XMALLOC (char, tmp_len + 1 + strlen (wrapper) + 1); + memcpy (concat_name, tmp, tmp_len); + concat_name[tmp_len] = '/'; + strcpy (concat_name + tmp_len + 1, wrapper); + } + else + { + concat_name = + XMALLOC (char, p_len + 1 + strlen (wrapper) + 1); + memcpy (concat_name, p, p_len); + concat_name[p_len] = '/'; + strcpy (concat_name + p_len + 1, wrapper); + } + if (check_executable (concat_name)) + return concat_name; + XFREE (concat_name); + } + } + /* not found in PATH; assume curdir */ + } + /* Relative path | not found in path: prepend cwd */ + if (getcwd (tmp, LT_PATHMAX) == NULL) + lt_fatal (__FILE__, __LINE__, "getcwd failed: %s", + nonnull (strerror (errno))); + tmp_len = strlen (tmp); + concat_name = XMALLOC (char, tmp_len + 1 + strlen (wrapper) + 1); + memcpy (concat_name, tmp, tmp_len); + concat_name[tmp_len] = '/'; + strcpy (concat_name + tmp_len + 1, wrapper); + + if (check_executable (concat_name)) + return concat_name; + XFREE (concat_name); + return NULL; +} + +char * +chase_symlinks (const char *pathspec) +{ +#ifndef S_ISLNK + return xstrdup (pathspec); +#else + char buf[LT_PATHMAX]; + struct stat s; + char *tmp_pathspec = xstrdup (pathspec); + char *p; + int has_symlinks = 0; + while (strlen (tmp_pathspec) && !has_symlinks) + { + lt_debugprintf (__FILE__, __LINE__, + "checking path component for symlinks: %s\n", + tmp_pathspec); + if (lstat (tmp_pathspec, &s) == 0) + { + if (S_ISLNK (s.st_mode) != 0) + { + has_symlinks = 1; + break; + } + + /* search backwards for last DIR_SEPARATOR */ + p = tmp_pathspec + strlen (tmp_pathspec) - 1; + while ((p > tmp_pathspec) && (!IS_DIR_SEPARATOR (*p))) + p--; + if ((p == tmp_pathspec) && (!IS_DIR_SEPARATOR (*p))) + { + /* no more DIR_SEPARATORS left */ + break; + } + *p = '\0'; + } + else + { + lt_fatal (__FILE__, __LINE__, + "error accessing file \"%s\": %s", + tmp_pathspec, nonnull (strerror (errno))); + } + } + XFREE (tmp_pathspec); + + if (!has_symlinks) + { + return xstrdup (pathspec); + } + + tmp_pathspec = realpath (pathspec, buf); + if (tmp_pathspec == 0) + { + lt_fatal (__FILE__, __LINE__, + "could not follow symlinks for %s", pathspec); + } + return xstrdup (tmp_pathspec); +#endif +} + +char * +strendzap (char *str, const char *pat) +{ + size_t len, patlen; + + assert (str != NULL); + assert (pat != NULL); + + len = strlen (str); + patlen = strlen (pat); + + if (patlen <= len) + { + str += len - patlen; + if (strcmp (str, pat) == 0) + *str = '\0'; + } + return str; +} + +void +lt_debugprintf (const char *file, int line, const char *fmt, ...) +{ + va_list args; + if (lt_debug) + { + (void) fprintf (stderr, "%s:%s:%d: ", program_name, file, line); + va_start (args, fmt); + (void) vfprintf (stderr, fmt, args); + va_end (args); + } +} + +static void +lt_error_core (int exit_status, const char *file, + int line, const char *mode, + const char *message, va_list ap) +{ + fprintf (stderr, "%s:%s:%d: %s: ", program_name, file, line, mode); + vfprintf (stderr, message, ap); + fprintf (stderr, ".\n"); + + if (exit_status >= 0) + exit (exit_status); +} + +void +lt_fatal (const char *file, int line, const char *message, ...) +{ + va_list ap; + va_start (ap, message); + lt_error_core (EXIT_FAILURE, file, line, "FATAL", message, ap); + va_end (ap); +} + +static const char * +nonnull (const char *s) +{ + return s ? s : "(null)"; +} + +static const char * +nonempty (const char *s) +{ + return (s && !*s) ? "(empty)" : nonnull (s); +} + +void +lt_setenv (const char *name, const char *value) +{ + lt_debugprintf (__FILE__, __LINE__, + "(lt_setenv) setting '%s' to '%s'\n", + nonnull (name), nonnull (value)); + { +#ifdef HAVE_SETENV + /* always make a copy, for consistency with !HAVE_SETENV */ + char *str = xstrdup (value); + setenv (name, str, 1); +#else + int len = strlen (name) + 1 + strlen (value) + 1; + char *str = XMALLOC (char, len); + sprintf (str, "%s=%s", name, value); + if (putenv (str) != EXIT_SUCCESS) + { + XFREE (str); + } +#endif + } +} + +char * +lt_extend_str (const char *orig_value, const char *add, int to_end) +{ + char *new_value; + if (orig_value && *orig_value) + { + int orig_value_len = strlen (orig_value); + int add_len = strlen (add); + new_value = XMALLOC (char, add_len + orig_value_len + 1); + if (to_end) + { + strcpy (new_value, orig_value); + strcpy (new_value + orig_value_len, add); + } + else + { + strcpy (new_value, add); + strcpy (new_value + add_len, orig_value); + } + } + else + { + new_value = xstrdup (add); + } + return new_value; +} + +void +lt_update_exe_path (const char *name, const char *value) +{ + lt_debugprintf (__FILE__, __LINE__, + "(lt_update_exe_path) modifying '%s' by prepending '%s'\n", + nonnull (name), nonnull (value)); + + if (name && *name && value && *value) + { + char *new_value = lt_extend_str (getenv (name), value, 0); + /* some systems can't cope with a ':'-terminated path #' */ + int len = strlen (new_value); + while (((len = strlen (new_value)) > 0) && IS_PATH_SEPARATOR (new_value[len-1])) + { + new_value[len-1] = '\0'; + } + lt_setenv (name, new_value); + XFREE (new_value); + } +} + +void +lt_update_lib_path (const char *name, const char *value) +{ + lt_debugprintf (__FILE__, __LINE__, + "(lt_update_lib_path) modifying '%s' by prepending '%s'\n", + nonnull (name), nonnull (value)); + + if (name && *name && value && *value) + { + char *new_value = lt_extend_str (getenv (name), value, 0); + lt_setenv (name, new_value); + XFREE (new_value); + } +} + +EOF + case $host_os in + mingw*) + cat <<"EOF" + +/* Prepares an argument vector before calling spawn(). + Note that spawn() does not by itself call the command interpreter + (getenv ("COMSPEC") != NULL ? getenv ("COMSPEC") : + ({ OSVERSIONINFO v; v.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); + GetVersionEx(&v); + v.dwPlatformId == VER_PLATFORM_WIN32_NT; + }) ? "cmd.exe" : "command.com"). + Instead it simply concatenates the arguments, separated by ' ', and calls + CreateProcess(). We must quote the arguments since Win32 CreateProcess() + interprets characters like ' ', '\t', '\\', '"' (but not '<' and '>') in a + special way: + - Space and tab are interpreted as delimiters. They are not treated as + delimiters if they are surrounded by double quotes: "...". + - Unescaped double quotes are removed from the input. Their only effect is + that within double quotes, space and tab are treated like normal + characters. + - Backslashes not followed by double quotes are not special. + - But 2*n+1 backslashes followed by a double quote become + n backslashes followed by a double quote (n >= 0): + \" -> " + \\\" -> \" + \\\\\" -> \\" + */ +#define SHELL_SPECIAL_CHARS "\"\\ \001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037" +#define SHELL_SPACE_CHARS " \001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037" +char ** +prepare_spawn (char **argv) +{ + size_t argc; + char **new_argv; + size_t i; + + /* Count number of arguments. */ + for (argc = 0; argv[argc] != NULL; argc++) + ; + + /* Allocate new argument vector. */ + new_argv = XMALLOC (char *, argc + 1); + + /* Put quoted arguments into the new argument vector. */ + for (i = 0; i < argc; i++) + { + const char *string = argv[i]; + + if (string[0] == '\0') + new_argv[i] = xstrdup ("\"\""); + else if (strpbrk (string, SHELL_SPECIAL_CHARS) != NULL) + { + int quote_around = (strpbrk (string, SHELL_SPACE_CHARS) != NULL); + size_t length; + unsigned int backslashes; + const char *s; + char *quoted_string; + char *p; + + length = 0; + backslashes = 0; + if (quote_around) + length++; + for (s = string; *s != '\0'; s++) + { + char c = *s; + if (c == '"') + length += backslashes + 1; + length++; + if (c == '\\') + backslashes++; + else + backslashes = 0; + } + if (quote_around) + length += backslashes + 1; + + quoted_string = XMALLOC (char, length + 1); + + p = quoted_string; + backslashes = 0; + if (quote_around) + *p++ = '"'; + for (s = string; *s != '\0'; s++) + { + char c = *s; + if (c == '"') + { + unsigned int j; + for (j = backslashes + 1; j > 0; j--) + *p++ = '\\'; + } + *p++ = c; + if (c == '\\') + backslashes++; + else + backslashes = 0; + } + if (quote_around) + { + unsigned int j; + for (j = backslashes; j > 0; j--) + *p++ = '\\'; + *p++ = '"'; + } + *p = '\0'; + + new_argv[i] = quoted_string; + } + else + new_argv[i] = (char *) string; + } + new_argv[argc] = NULL; + + return new_argv; +} +EOF + ;; + esac + + cat <<"EOF" +void lt_dump_script (FILE* f) +{ +EOF + func_emit_wrapper yes | + $SED -n -e ' +s/^\(.\{79\}\)\(..*\)/\1\ +\2/ +h +s/\([\\"]\)/\\\1/g +s/$/\\n/ +s/\([^\n]*\).*/ fputs ("\1", f);/p +g +D' + cat <<"EOF" +} +EOF +} +# end: func_emit_cwrapperexe_src + +# func_win32_import_lib_p ARG +# True if ARG is an import lib, as indicated by $file_magic_cmd +func_win32_import_lib_p () +{ + $opt_debug + case `eval $file_magic_cmd \"\$1\" 2>/dev/null | $SED -e 10q` in + *import*) : ;; + *) false ;; + esac +} + +# func_mode_link arg... +func_mode_link () +{ + $opt_debug + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*) + # It is impossible to link a dll without this setting, and + # we shouldn't force the makefile maintainer to figure out + # which system we are compiling for in order to pass an extra + # flag for every libtool invocation. + # allow_undefined=no + + # FIXME: Unfortunately, there are problems with the above when trying + # to make a dll which has undefined symbols, in which case not + # even a static library is built. For now, we need to specify + # -no-undefined on the libtool link line when we can be certain + # that all symbols are satisfied, otherwise we get a static library. + allow_undefined=yes + ;; + *) + allow_undefined=yes + ;; + esac + libtool_args=$nonopt + base_compile="$nonopt $@" + compile_command=$nonopt + finalize_command=$nonopt + + compile_rpath= + finalize_rpath= + compile_shlibpath= + finalize_shlibpath= + convenience= + old_convenience= + deplibs= + old_deplibs= + compiler_flags= + linker_flags= + dllsearchpath= + lib_search_path=`pwd` + inst_prefix_dir= + new_inherited_linker_flags= + + avoid_version=no + bindir= + dlfiles= + dlprefiles= + dlself=no + export_dynamic=no + export_symbols= + export_symbols_regex= + generated= + libobjs= + ltlibs= + module=no + no_install=no + objs= + non_pic_objects= + precious_files_regex= + prefer_static_libs=no + preload=no + prev= + prevarg= + release= + rpath= + xrpath= + perm_rpath= + temp_rpath= + thread_safe=no + vinfo= + vinfo_number=no + weak_libs= + single_module="${wl}-single_module" + func_infer_tag $base_compile + + # We need to know -static, to get the right output filenames. + for arg + do + case $arg in + -shared) + test "$build_libtool_libs" != yes && \ + func_fatal_configuration "can not build a shared library" + build_old_libs=no + break + ;; + -all-static | -static | -static-libtool-libs) + case $arg in + -all-static) + if test "$build_libtool_libs" = yes && test -z "$link_static_flag"; then + func_warning "complete static linking is impossible in this configuration" + fi + if test -n "$link_static_flag"; then + dlopen_self=$dlopen_self_static + fi + prefer_static_libs=yes + ;; + -static) + if test -z "$pic_flag" && test -n "$link_static_flag"; then + dlopen_self=$dlopen_self_static + fi + prefer_static_libs=built + ;; + -static-libtool-libs) + if test -z "$pic_flag" && test -n "$link_static_flag"; then + dlopen_self=$dlopen_self_static + fi + prefer_static_libs=yes + ;; + esac + build_libtool_libs=no + build_old_libs=yes + break + ;; + esac + done + + # See if our shared archives depend on static archives. + test -n "$old_archive_from_new_cmds" && build_old_libs=yes + + # Go through the arguments, transforming them on the way. + while test "$#" -gt 0; do + arg="$1" + shift + func_quote_for_eval "$arg" + qarg=$func_quote_for_eval_unquoted_result + func_append libtool_args " $func_quote_for_eval_result" + + # If the previous option needs an argument, assign it. + if test -n "$prev"; then + case $prev in + output) + func_append compile_command " @OUTPUT@" + func_append finalize_command " @OUTPUT@" + ;; + esac + + case $prev in + bindir) + bindir="$arg" + prev= + continue + ;; + dlfiles|dlprefiles) + if test "$preload" = no; then + # Add the symbol object into the linking commands. + func_append compile_command " @SYMFILE@" + func_append finalize_command " @SYMFILE@" + preload=yes + fi + case $arg in + *.la | *.lo) ;; # We handle these cases below. + force) + if test "$dlself" = no; then + dlself=needless + export_dynamic=yes + fi + prev= + continue + ;; + self) + if test "$prev" = dlprefiles; then + dlself=yes + elif test "$prev" = dlfiles && test "$dlopen_self" != yes; then + dlself=yes + else + dlself=needless + export_dynamic=yes + fi + prev= + continue + ;; + *) + if test "$prev" = dlfiles; then + func_append dlfiles " $arg" + else + func_append dlprefiles " $arg" + fi + prev= + continue + ;; + esac + ;; + expsyms) + export_symbols="$arg" + test -f "$arg" \ + || func_fatal_error "symbol file \`$arg' does not exist" + prev= + continue + ;; + expsyms_regex) + export_symbols_regex="$arg" + prev= + continue + ;; + framework) + case $host in + *-*-darwin*) + case "$deplibs " in + *" $qarg.ltframework "*) ;; + *) func_append deplibs " $qarg.ltframework" # this is fixed later + ;; + esac + ;; + esac + prev= + continue + ;; + inst_prefix) + inst_prefix_dir="$arg" + prev= + continue + ;; + objectlist) + if test -f "$arg"; then + save_arg=$arg + moreargs= + for fil in `cat "$save_arg"` + do +# func_append moreargs " $fil" + arg=$fil + # A libtool-controlled object. + + # Check to see that this really is a libtool object. + if func_lalib_unsafe_p "$arg"; then + pic_object= + non_pic_object= + + # Read the .lo file + func_source "$arg" + + if test -z "$pic_object" || + test -z "$non_pic_object" || + test "$pic_object" = none && + test "$non_pic_object" = none; then + func_fatal_error "cannot find name of object for \`$arg'" + fi + + # Extract subdirectory from the argument. + func_dirname "$arg" "/" "" + xdir="$func_dirname_result" + + if test "$pic_object" != none; then + # Prepend the subdirectory the object is found in. + pic_object="$xdir$pic_object" + + if test "$prev" = dlfiles; then + if test "$build_libtool_libs" = yes && test "$dlopen_support" = yes; then + func_append dlfiles " $pic_object" + prev= + continue + else + # If libtool objects are unsupported, then we need to preload. + prev=dlprefiles + fi + fi + + # CHECK ME: I think I busted this. -Ossama + if test "$prev" = dlprefiles; then + # Preload the old-style object. + func_append dlprefiles " $pic_object" + prev= + fi + + # A PIC object. + func_append libobjs " $pic_object" + arg="$pic_object" + fi + + # Non-PIC object. + if test "$non_pic_object" != none; then + # Prepend the subdirectory the object is found in. + non_pic_object="$xdir$non_pic_object" + + # A standard non-PIC object + func_append non_pic_objects " $non_pic_object" + if test -z "$pic_object" || test "$pic_object" = none ; then + arg="$non_pic_object" + fi + else + # If the PIC object exists, use it instead. + # $xdir was prepended to $pic_object above. + non_pic_object="$pic_object" + func_append non_pic_objects " $non_pic_object" + fi + else + # Only an error if not doing a dry-run. + if $opt_dry_run; then + # Extract subdirectory from the argument. + func_dirname "$arg" "/" "" + xdir="$func_dirname_result" + + func_lo2o "$arg" + pic_object=$xdir$objdir/$func_lo2o_result + non_pic_object=$xdir$func_lo2o_result + func_append libobjs " $pic_object" + func_append non_pic_objects " $non_pic_object" + else + func_fatal_error "\`$arg' is not a valid libtool object" + fi + fi + done + else + func_fatal_error "link input file \`$arg' does not exist" + fi + arg=$save_arg + prev= + continue + ;; + precious_regex) + precious_files_regex="$arg" + prev= + continue + ;; + release) + release="-$arg" + prev= + continue + ;; + rpath | xrpath) + # We need an absolute path. + case $arg in + [\\/]* | [A-Za-z]:[\\/]*) ;; + *) + func_fatal_error "only absolute run-paths are allowed" + ;; + esac + if test "$prev" = rpath; then + case "$rpath " in + *" $arg "*) ;; + *) func_append rpath " $arg" ;; + esac + else + case "$xrpath " in + *" $arg "*) ;; + *) func_append xrpath " $arg" ;; + esac + fi + prev= + continue + ;; + shrext) + shrext_cmds="$arg" + prev= + continue + ;; + weak) + func_append weak_libs " $arg" + prev= + continue + ;; + xcclinker) + func_append linker_flags " $qarg" + func_append compiler_flags " $qarg" + prev= + func_append compile_command " $qarg" + func_append finalize_command " $qarg" + continue + ;; + xcompiler) + func_append compiler_flags " $qarg" + prev= + func_append compile_command " $qarg" + func_append finalize_command " $qarg" + continue + ;; + xlinker) + func_append linker_flags " $qarg" + func_append compiler_flags " $wl$qarg" + prev= + func_append compile_command " $wl$qarg" + func_append finalize_command " $wl$qarg" + continue + ;; + *) + eval "$prev=\"\$arg\"" + prev= + continue + ;; + esac + fi # test -n "$prev" + + prevarg="$arg" + + case $arg in + -all-static) + if test -n "$link_static_flag"; then + # See comment for -static flag below, for more details. + func_append compile_command " $link_static_flag" + func_append finalize_command " $link_static_flag" + fi + continue + ;; + + -allow-undefined) + # FIXME: remove this flag sometime in the future. + func_fatal_error "\`-allow-undefined' must not be used because it is the default" + ;; + + -avoid-version) + avoid_version=yes + continue + ;; + + -bindir) + prev=bindir + continue + ;; + + -dlopen) + prev=dlfiles + continue + ;; + + -dlpreopen) + prev=dlprefiles + continue + ;; + + -export-dynamic) + export_dynamic=yes + continue + ;; + + -export-symbols | -export-symbols-regex) + if test -n "$export_symbols" || test -n "$export_symbols_regex"; then + func_fatal_error "more than one -exported-symbols argument is not allowed" + fi + if test "X$arg" = "X-export-symbols"; then + prev=expsyms + else + prev=expsyms_regex + fi + continue + ;; + + -framework) + prev=framework + continue + ;; + + -inst-prefix-dir) + prev=inst_prefix + continue + ;; + + # The native IRIX linker understands -LANG:*, -LIST:* and -LNO:* + # so, if we see these flags be careful not to treat them like -L + -L[A-Z][A-Z]*:*) + case $with_gcc/$host in + no/*-*-irix* | /*-*-irix*) + func_append compile_command " $arg" + func_append finalize_command " $arg" + ;; + esac + continue + ;; + + -L*) + func_stripname "-L" '' "$arg" + if test -z "$func_stripname_result"; then + if test "$#" -gt 0; then + func_fatal_error "require no space between \`-L' and \`$1'" + else + func_fatal_error "need path for \`-L' option" + fi + fi + func_resolve_sysroot "$func_stripname_result" + dir=$func_resolve_sysroot_result + # We need an absolute path. + case $dir in + [\\/]* | [A-Za-z]:[\\/]*) ;; + *) + absdir=`cd "$dir" && pwd` + test -z "$absdir" && \ + func_fatal_error "cannot determine absolute directory name of \`$dir'" + dir="$absdir" + ;; + esac + case "$deplibs " in + *" -L$dir "* | *" $arg "*) + # Will only happen for absolute or sysroot arguments + ;; + *) + # Preserve sysroot, but never include relative directories + case $dir in + [\\/]* | [A-Za-z]:[\\/]* | =*) func_append deplibs " $arg" ;; + *) func_append deplibs " -L$dir" ;; + esac + func_append lib_search_path " $dir" + ;; + esac + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*) + testbindir=`$ECHO "$dir" | $SED 's*/lib$*/bin*'` + case :$dllsearchpath: in + *":$dir:"*) ;; + ::) dllsearchpath=$dir;; + *) func_append dllsearchpath ":$dir";; + esac + case :$dllsearchpath: in + *":$testbindir:"*) ;; + ::) dllsearchpath=$testbindir;; + *) func_append dllsearchpath ":$testbindir";; + esac + ;; + esac + continue + ;; + + -l*) + if test "X$arg" = "X-lc" || test "X$arg" = "X-lm"; then + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-beos* | *-cegcc* | *-*-haiku*) + # These systems don't actually have a C or math library (as such) + continue + ;; + *-*-os2*) + # These systems don't actually have a C library (as such) + test "X$arg" = "X-lc" && continue + ;; + *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*) + # Do not include libc due to us having libc/libc_r. + test "X$arg" = "X-lc" && continue + ;; + *-*-rhapsody* | *-*-darwin1.[012]) + # Rhapsody C and math libraries are in the System framework + func_append deplibs " System.ltframework" + continue + ;; + *-*-sco3.2v5* | *-*-sco5v6*) + # Causes problems with __ctype + test "X$arg" = "X-lc" && continue + ;; + *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*) + # Compiler inserts libc in the correct place for threads to work + test "X$arg" = "X-lc" && continue + ;; + esac + elif test "X$arg" = "X-lc_r"; then + case $host in + *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*) + # Do not include libc_r directly, use -pthread flag. + continue + ;; + esac + fi + func_append deplibs " $arg" + continue + ;; + + -module) + module=yes + continue + ;; + + # Tru64 UNIX uses -model [arg] to determine the layout of C++ + # classes, name mangling, and exception handling. + # Darwin uses the -arch flag to determine output architecture. + -model|-arch|-isysroot|--sysroot) + func_append compiler_flags " $arg" + func_append compile_command " $arg" + func_append finalize_command " $arg" + prev=xcompiler + continue + ;; + + -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe \ + |-threads|-fopenmp|-openmp|-mp|-xopenmp|-omp|-qsmp=*) + func_append compiler_flags " $arg" + func_append compile_command " $arg" + func_append finalize_command " $arg" + case "$new_inherited_linker_flags " in + *" $arg "*) ;; + * ) func_append new_inherited_linker_flags " $arg" ;; + esac + continue + ;; + + -multi_module) + single_module="${wl}-multi_module" + continue + ;; + + -no-fast-install) + fast_install=no + continue + ;; + + -no-install) + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-darwin* | *-cegcc*) + # The PATH hackery in wrapper scripts is required on Windows + # and Darwin in order for the loader to find any dlls it needs. + func_warning "\`-no-install' is ignored for $host" + func_warning "assuming \`-no-fast-install' instead" + fast_install=no + ;; + *) no_install=yes ;; + esac + continue + ;; + + -no-undefined) + allow_undefined=no + continue + ;; + + -objectlist) + prev=objectlist + continue + ;; + + -o) prev=output ;; + + -precious-files-regex) + prev=precious_regex + continue + ;; + + -release) + prev=release + continue + ;; + + -rpath) + prev=rpath + continue + ;; + + -R) + prev=xrpath + continue + ;; + + -R*) + func_stripname '-R' '' "$arg" + dir=$func_stripname_result + # We need an absolute path. + case $dir in + [\\/]* | [A-Za-z]:[\\/]*) ;; + =*) + func_stripname '=' '' "$dir" + dir=$lt_sysroot$func_stripname_result + ;; + *) + func_fatal_error "only absolute run-paths are allowed" + ;; + esac + case "$xrpath " in + *" $dir "*) ;; + *) func_append xrpath " $dir" ;; + esac + continue + ;; + + -shared) + # The effects of -shared are defined in a previous loop. + continue + ;; + + -shrext) + prev=shrext + continue + ;; + + -static | -static-libtool-libs) + # The effects of -static are defined in a previous loop. + # We used to do the same as -all-static on platforms that + # didn't have a PIC flag, but the assumption that the effects + # would be equivalent was wrong. It would break on at least + # Digital Unix and AIX. + continue + ;; + + -thread-safe) + thread_safe=yes + continue + ;; + + -version-info) + prev=vinfo + continue + ;; + + -version-number) + prev=vinfo + vinfo_number=yes + continue + ;; + + -weak) + prev=weak + continue + ;; + + -Wc,*) + func_stripname '-Wc,' '' "$arg" + args=$func_stripname_result + arg= + save_ifs="$IFS"; IFS=',' + for flag in $args; do + IFS="$save_ifs" + func_quote_for_eval "$flag" + func_append arg " $func_quote_for_eval_result" + func_append compiler_flags " $func_quote_for_eval_result" + done + IFS="$save_ifs" + func_stripname ' ' '' "$arg" + arg=$func_stripname_result + ;; + + -Wl,*) + func_stripname '-Wl,' '' "$arg" + args=$func_stripname_result + arg= + save_ifs="$IFS"; IFS=',' + for flag in $args; do + IFS="$save_ifs" + func_quote_for_eval "$flag" + func_append arg " $wl$func_quote_for_eval_result" + func_append compiler_flags " $wl$func_quote_for_eval_result" + func_append linker_flags " $func_quote_for_eval_result" + done + IFS="$save_ifs" + func_stripname ' ' '' "$arg" + arg=$func_stripname_result + ;; + + -Xcompiler) + prev=xcompiler + continue + ;; + + -Xlinker) + prev=xlinker + continue + ;; + + -XCClinker) + prev=xcclinker + continue + ;; + + # -msg_* for osf cc + -msg_*) + func_quote_for_eval "$arg" + arg="$func_quote_for_eval_result" + ;; + + # Flags to be passed through unchanged, with rationale: + # -64, -mips[0-9] enable 64-bit mode for the SGI compiler + # -r[0-9][0-9]* specify processor for the SGI compiler + # -xarch=*, -xtarget=* enable 64-bit mode for the Sun compiler + # +DA*, +DD* enable 64-bit mode for the HP compiler + # -q* compiler args for the IBM compiler + # -m*, -t[45]*, -txscale* architecture-specific flags for GCC + # -F/path path to uninstalled frameworks, gcc on darwin + # -p, -pg, --coverage, -fprofile-* profiling flags for GCC + # @file GCC response files + # -tp=* Portland pgcc target processor selection + # --sysroot=* for sysroot support + # -O*, -flto*, -fwhopr*, -fuse-linker-plugin GCC link-time optimization + -64|-mips[0-9]|-r[0-9][0-9]*|-xarch=*|-xtarget=*|+DA*|+DD*|-q*|-m*| \ + -t[45]*|-txscale*|-p|-pg|--coverage|-fprofile-*|-F*|@*|-tp=*|--sysroot=*| \ + -O*|-flto*|-fwhopr*|-fuse-linker-plugin) + func_quote_for_eval "$arg" + arg="$func_quote_for_eval_result" + func_append compile_command " $arg" + func_append finalize_command " $arg" + func_append compiler_flags " $arg" + continue + ;; + + # Some other compiler flag. + -* | +*) + func_quote_for_eval "$arg" + arg="$func_quote_for_eval_result" + ;; + + *.$objext) + # A standard object. + func_append objs " $arg" + ;; + + *.lo) + # A libtool-controlled object. + + # Check to see that this really is a libtool object. + if func_lalib_unsafe_p "$arg"; then + pic_object= + non_pic_object= + + # Read the .lo file + func_source "$arg" + + if test -z "$pic_object" || + test -z "$non_pic_object" || + test "$pic_object" = none && + test "$non_pic_object" = none; then + func_fatal_error "cannot find name of object for \`$arg'" + fi + + # Extract subdirectory from the argument. + func_dirname "$arg" "/" "" + xdir="$func_dirname_result" + + if test "$pic_object" != none; then + # Prepend the subdirectory the object is found in. + pic_object="$xdir$pic_object" + + if test "$prev" = dlfiles; then + if test "$build_libtool_libs" = yes && test "$dlopen_support" = yes; then + func_append dlfiles " $pic_object" + prev= + continue + else + # If libtool objects are unsupported, then we need to preload. + prev=dlprefiles + fi + fi + + # CHECK ME: I think I busted this. -Ossama + if test "$prev" = dlprefiles; then + # Preload the old-style object. + func_append dlprefiles " $pic_object" + prev= + fi + + # A PIC object. + func_append libobjs " $pic_object" + arg="$pic_object" + fi + + # Non-PIC object. + if test "$non_pic_object" != none; then + # Prepend the subdirectory the object is found in. + non_pic_object="$xdir$non_pic_object" + + # A standard non-PIC object + func_append non_pic_objects " $non_pic_object" + if test -z "$pic_object" || test "$pic_object" = none ; then + arg="$non_pic_object" + fi + else + # If the PIC object exists, use it instead. + # $xdir was prepended to $pic_object above. + non_pic_object="$pic_object" + func_append non_pic_objects " $non_pic_object" + fi + else + # Only an error if not doing a dry-run. + if $opt_dry_run; then + # Extract subdirectory from the argument. + func_dirname "$arg" "/" "" + xdir="$func_dirname_result" + + func_lo2o "$arg" + pic_object=$xdir$objdir/$func_lo2o_result + non_pic_object=$xdir$func_lo2o_result + func_append libobjs " $pic_object" + func_append non_pic_objects " $non_pic_object" + else + func_fatal_error "\`$arg' is not a valid libtool object" + fi + fi + ;; + + *.$libext) + # An archive. + func_append deplibs " $arg" + func_append old_deplibs " $arg" + continue + ;; + + *.la) + # A libtool-controlled library. + + func_resolve_sysroot "$arg" + if test "$prev" = dlfiles; then + # This library was specified with -dlopen. + func_append dlfiles " $func_resolve_sysroot_result" + prev= + elif test "$prev" = dlprefiles; then + # The library was specified with -dlpreopen. + func_append dlprefiles " $func_resolve_sysroot_result" + prev= + else + func_append deplibs " $func_resolve_sysroot_result" + fi + continue + ;; + + # Some other compiler argument. + *) + # Unknown arguments in both finalize_command and compile_command need + # to be aesthetically quoted because they are evaled later. + func_quote_for_eval "$arg" + arg="$func_quote_for_eval_result" + ;; + esac # arg + + # Now actually substitute the argument into the commands. + if test -n "$arg"; then + func_append compile_command " $arg" + func_append finalize_command " $arg" + fi + done # argument parsing loop + + test -n "$prev" && \ + func_fatal_help "the \`$prevarg' option requires an argument" + + if test "$export_dynamic" = yes && test -n "$export_dynamic_flag_spec"; then + eval arg=\"$export_dynamic_flag_spec\" + func_append compile_command " $arg" + func_append finalize_command " $arg" + fi + + oldlibs= + # calculate the name of the file, without its directory + func_basename "$output" + outputname="$func_basename_result" + libobjs_save="$libobjs" + + if test -n "$shlibpath_var"; then + # get the directories listed in $shlibpath_var + eval shlib_search_path=\`\$ECHO \"\${$shlibpath_var}\" \| \$SED \'s/:/ /g\'\` + else + shlib_search_path= + fi + eval sys_lib_search_path=\"$sys_lib_search_path_spec\" + eval sys_lib_dlsearch_path=\"$sys_lib_dlsearch_path_spec\" + + func_dirname "$output" "/" "" + output_objdir="$func_dirname_result$objdir" + func_to_tool_file "$output_objdir/" + tool_output_objdir=$func_to_tool_file_result + # Create the object directory. + func_mkdir_p "$output_objdir" + + # Determine the type of output + case $output in + "") + func_fatal_help "you must specify an output file" + ;; + *.$libext) linkmode=oldlib ;; + *.lo | *.$objext) linkmode=obj ;; + *.la) linkmode=lib ;; + *) linkmode=prog ;; # Anything else should be a program. + esac + + specialdeplibs= + + libs= + # Find all interdependent deplibs by searching for libraries + # that are linked more than once (e.g. -la -lb -la) + for deplib in $deplibs; do + if $opt_preserve_dup_deps ; then + case "$libs " in + *" $deplib "*) func_append specialdeplibs " $deplib" ;; + esac + fi + func_append libs " $deplib" + done + + if test "$linkmode" = lib; then + libs="$predeps $libs $compiler_lib_search_path $postdeps" + + # Compute libraries that are listed more than once in $predeps + # $postdeps and mark them as special (i.e., whose duplicates are + # not to be eliminated). + pre_post_deps= + if $opt_duplicate_compiler_generated_deps; then + for pre_post_dep in $predeps $postdeps; do + case "$pre_post_deps " in + *" $pre_post_dep "*) func_append specialdeplibs " $pre_post_deps" ;; + esac + func_append pre_post_deps " $pre_post_dep" + done + fi + pre_post_deps= + fi + + deplibs= + newdependency_libs= + newlib_search_path= + need_relink=no # whether we're linking any uninstalled libtool libraries + notinst_deplibs= # not-installed libtool libraries + notinst_path= # paths that contain not-installed libtool libraries + + case $linkmode in + lib) + passes="conv dlpreopen link" + for file in $dlfiles $dlprefiles; do + case $file in + *.la) ;; + *) + func_fatal_help "libraries can \`-dlopen' only libtool libraries: $file" + ;; + esac + done + ;; + prog) + compile_deplibs= + finalize_deplibs= + alldeplibs=no + newdlfiles= + newdlprefiles= + passes="conv scan dlopen dlpreopen link" + ;; + *) passes="conv" + ;; + esac + + for pass in $passes; do + # The preopen pass in lib mode reverses $deplibs; put it back here + # so that -L comes before libs that need it for instance... + if test "$linkmode,$pass" = "lib,link"; then + ## FIXME: Find the place where the list is rebuilt in the wrong + ## order, and fix it there properly + tmp_deplibs= + for deplib in $deplibs; do + tmp_deplibs="$deplib $tmp_deplibs" + done + deplibs="$tmp_deplibs" + fi + + if test "$linkmode,$pass" = "lib,link" || + test "$linkmode,$pass" = "prog,scan"; then + libs="$deplibs" + deplibs= + fi + if test "$linkmode" = prog; then + case $pass in + dlopen) libs="$dlfiles" ;; + dlpreopen) libs="$dlprefiles" ;; + link) + libs="$deplibs %DEPLIBS%" + test "X$link_all_deplibs" != Xno && libs="$libs $dependency_libs" + ;; + esac + fi + if test "$linkmode,$pass" = "lib,dlpreopen"; then + # Collect and forward deplibs of preopened libtool libs + for lib in $dlprefiles; do + # Ignore non-libtool-libs + dependency_libs= + func_resolve_sysroot "$lib" + case $lib in + *.la) func_source "$func_resolve_sysroot_result" ;; + esac + + # Collect preopened libtool deplibs, except any this library + # has declared as weak libs + for deplib in $dependency_libs; do + func_basename "$deplib" + deplib_base=$func_basename_result + case " $weak_libs " in + *" $deplib_base "*) ;; + *) func_append deplibs " $deplib" ;; + esac + done + done + libs="$dlprefiles" + fi + if test "$pass" = dlopen; then + # Collect dlpreopened libraries + save_deplibs="$deplibs" + deplibs= + fi + + for deplib in $libs; do + lib= + found=no + case $deplib in + -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe \ + |-threads|-fopenmp|-openmp|-mp|-xopenmp|-omp|-qsmp=*) + if test "$linkmode,$pass" = "prog,link"; then + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + else + func_append compiler_flags " $deplib" + if test "$linkmode" = lib ; then + case "$new_inherited_linker_flags " in + *" $deplib "*) ;; + * ) func_append new_inherited_linker_flags " $deplib" ;; + esac + fi + fi + continue + ;; + -l*) + if test "$linkmode" != lib && test "$linkmode" != prog; then + func_warning "\`-l' is ignored for archives/objects" + continue + fi + func_stripname '-l' '' "$deplib" + name=$func_stripname_result + if test "$linkmode" = lib; then + searchdirs="$newlib_search_path $lib_search_path $compiler_lib_search_dirs $sys_lib_search_path $shlib_search_path" + else + searchdirs="$newlib_search_path $lib_search_path $sys_lib_search_path $shlib_search_path" + fi + for searchdir in $searchdirs; do + for search_ext in .la $std_shrext .so .a; do + # Search the libtool library + lib="$searchdir/lib${name}${search_ext}" + if test -f "$lib"; then + if test "$search_ext" = ".la"; then + found=yes + else + found=no + fi + break 2 + fi + done + done + if test "$found" != yes; then + # deplib doesn't seem to be a libtool library + if test "$linkmode,$pass" = "prog,link"; then + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + else + deplibs="$deplib $deplibs" + test "$linkmode" = lib && newdependency_libs="$deplib $newdependency_libs" + fi + continue + else # deplib is a libtool library + # If $allow_libtool_libs_with_static_runtimes && $deplib is a stdlib, + # We need to do some special things here, and not later. + if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then + case " $predeps $postdeps " in + *" $deplib "*) + if func_lalib_p "$lib"; then + library_names= + old_library= + func_source "$lib" + for l in $old_library $library_names; do + ll="$l" + done + if test "X$ll" = "X$old_library" ; then # only static version available + found=no + func_dirname "$lib" "" "." + ladir="$func_dirname_result" + lib=$ladir/$old_library + if test "$linkmode,$pass" = "prog,link"; then + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + else + deplibs="$deplib $deplibs" + test "$linkmode" = lib && newdependency_libs="$deplib $newdependency_libs" + fi + continue + fi + fi + ;; + *) ;; + esac + fi + fi + ;; # -l + *.ltframework) + if test "$linkmode,$pass" = "prog,link"; then + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + else + deplibs="$deplib $deplibs" + if test "$linkmode" = lib ; then + case "$new_inherited_linker_flags " in + *" $deplib "*) ;; + * ) func_append new_inherited_linker_flags " $deplib" ;; + esac + fi + fi + continue + ;; + -L*) + case $linkmode in + lib) + deplibs="$deplib $deplibs" + test "$pass" = conv && continue + newdependency_libs="$deplib $newdependency_libs" + func_stripname '-L' '' "$deplib" + func_resolve_sysroot "$func_stripname_result" + func_append newlib_search_path " $func_resolve_sysroot_result" + ;; + prog) + if test "$pass" = conv; then + deplibs="$deplib $deplibs" + continue + fi + if test "$pass" = scan; then + deplibs="$deplib $deplibs" + else + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + fi + func_stripname '-L' '' "$deplib" + func_resolve_sysroot "$func_stripname_result" + func_append newlib_search_path " $func_resolve_sysroot_result" + ;; + *) + func_warning "\`-L' is ignored for archives/objects" + ;; + esac # linkmode + continue + ;; # -L + -R*) + if test "$pass" = link; then + func_stripname '-R' '' "$deplib" + func_resolve_sysroot "$func_stripname_result" + dir=$func_resolve_sysroot_result + # Make sure the xrpath contains only unique directories. + case "$xrpath " in + *" $dir "*) ;; + *) func_append xrpath " $dir" ;; + esac + fi + deplibs="$deplib $deplibs" + continue + ;; + *.la) + func_resolve_sysroot "$deplib" + lib=$func_resolve_sysroot_result + ;; + *.$libext) + if test "$pass" = conv; then + deplibs="$deplib $deplibs" + continue + fi + case $linkmode in + lib) + # Linking convenience modules into shared libraries is allowed, + # but linking other static libraries is non-portable. + case " $dlpreconveniencelibs " in + *" $deplib "*) ;; + *) + valid_a_lib=no + case $deplibs_check_method in + match_pattern*) + set dummy $deplibs_check_method; shift + match_pattern_regex=`expr "$deplibs_check_method" : "$1 \(.*\)"` + if eval "\$ECHO \"$deplib\"" 2>/dev/null | $SED 10q \ + | $EGREP "$match_pattern_regex" > /dev/null; then + valid_a_lib=yes + fi + ;; + pass_all) + valid_a_lib=yes + ;; + esac + if test "$valid_a_lib" != yes; then + echo + $ECHO "*** Warning: Trying to link with static lib archive $deplib." + echo "*** I have the capability to make that library automatically link in when" + echo "*** you link to this library. But I can only do this if you have a" + echo "*** shared version of the library, which you do not appear to have" + echo "*** because the file extensions .$libext of this argument makes me believe" + echo "*** that it is just a static archive that I should not use here." + else + echo + $ECHO "*** Warning: Linking the shared library $output against the" + $ECHO "*** static library $deplib is not portable!" + deplibs="$deplib $deplibs" + fi + ;; + esac + continue + ;; + prog) + if test "$pass" != link; then + deplibs="$deplib $deplibs" + else + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + fi + continue + ;; + esac # linkmode + ;; # *.$libext + *.lo | *.$objext) + if test "$pass" = conv; then + deplibs="$deplib $deplibs" + elif test "$linkmode" = prog; then + if test "$pass" = dlpreopen || test "$dlopen_support" != yes || test "$build_libtool_libs" = no; then + # If there is no dlopen support or we're linking statically, + # we need to preload. + func_append newdlprefiles " $deplib" + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + else + func_append newdlfiles " $deplib" + fi + fi + continue + ;; + %DEPLIBS%) + alldeplibs=yes + continue + ;; + esac # case $deplib + + if test "$found" = yes || test -f "$lib"; then : + else + func_fatal_error "cannot find the library \`$lib' or unhandled argument \`$deplib'" + fi + + # Check to see that this really is a libtool archive. + func_lalib_unsafe_p "$lib" \ + || func_fatal_error "\`$lib' is not a valid libtool archive" + + func_dirname "$lib" "" "." + ladir="$func_dirname_result" + + dlname= + dlopen= + dlpreopen= + libdir= + library_names= + old_library= + inherited_linker_flags= + # If the library was installed with an old release of libtool, + # it will not redefine variables installed, or shouldnotlink + installed=yes + shouldnotlink=no + avoidtemprpath= + + + # Read the .la file + func_source "$lib" + + # Convert "-framework foo" to "foo.ltframework" + if test -n "$inherited_linker_flags"; then + tmp_inherited_linker_flags=`$ECHO "$inherited_linker_flags" | $SED 's/-framework \([^ $]*\)/\1.ltframework/g'` + for tmp_inherited_linker_flag in $tmp_inherited_linker_flags; do + case " $new_inherited_linker_flags " in + *" $tmp_inherited_linker_flag "*) ;; + *) func_append new_inherited_linker_flags " $tmp_inherited_linker_flag";; + esac + done + fi + dependency_libs=`$ECHO " $dependency_libs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` + if test "$linkmode,$pass" = "lib,link" || + test "$linkmode,$pass" = "prog,scan" || + { test "$linkmode" != prog && test "$linkmode" != lib; }; then + test -n "$dlopen" && func_append dlfiles " $dlopen" + test -n "$dlpreopen" && func_append dlprefiles " $dlpreopen" + fi + + if test "$pass" = conv; then + # Only check for convenience libraries + deplibs="$lib $deplibs" + if test -z "$libdir"; then + if test -z "$old_library"; then + func_fatal_error "cannot find name of link library for \`$lib'" + fi + # It is a libtool convenience library, so add in its objects. + func_append convenience " $ladir/$objdir/$old_library" + func_append old_convenience " $ladir/$objdir/$old_library" + tmp_libs= + for deplib in $dependency_libs; do + deplibs="$deplib $deplibs" + if $opt_preserve_dup_deps ; then + case "$tmp_libs " in + *" $deplib "*) func_append specialdeplibs " $deplib" ;; + esac + fi + func_append tmp_libs " $deplib" + done + elif test "$linkmode" != prog && test "$linkmode" != lib; then + func_fatal_error "\`$lib' is not a convenience library" + fi + continue + fi # $pass = conv + + + # Get the name of the library we link against. + linklib= + if test -n "$old_library" && + { test "$prefer_static_libs" = yes || + test "$prefer_static_libs,$installed" = "built,no"; }; then + linklib=$old_library + else + for l in $old_library $library_names; do + linklib="$l" + done + fi + if test -z "$linklib"; then + func_fatal_error "cannot find name of link library for \`$lib'" + fi + + # This library was specified with -dlopen. + if test "$pass" = dlopen; then + if test -z "$libdir"; then + func_fatal_error "cannot -dlopen a convenience library: \`$lib'" + fi + if test -z "$dlname" || + test "$dlopen_support" != yes || + test "$build_libtool_libs" = no; then + # If there is no dlname, no dlopen support or we're linking + # statically, we need to preload. We also need to preload any + # dependent libraries so libltdl's deplib preloader doesn't + # bomb out in the load deplibs phase. + func_append dlprefiles " $lib $dependency_libs" + else + func_append newdlfiles " $lib" + fi + continue + fi # $pass = dlopen + + # We need an absolute path. + case $ladir in + [\\/]* | [A-Za-z]:[\\/]*) abs_ladir="$ladir" ;; + *) + abs_ladir=`cd "$ladir" && pwd` + if test -z "$abs_ladir"; then + func_warning "cannot determine absolute directory name of \`$ladir'" + func_warning "passing it literally to the linker, although it might fail" + abs_ladir="$ladir" + fi + ;; + esac + func_basename "$lib" + laname="$func_basename_result" + + # Find the relevant object directory and library name. + if test "X$installed" = Xyes; then + if test ! -f "$lt_sysroot$libdir/$linklib" && test -f "$abs_ladir/$linklib"; then + func_warning "library \`$lib' was moved." + dir="$ladir" + absdir="$abs_ladir" + libdir="$abs_ladir" + else + dir="$lt_sysroot$libdir" + absdir="$lt_sysroot$libdir" + fi + test "X$hardcode_automatic" = Xyes && avoidtemprpath=yes + else + if test ! -f "$ladir/$objdir/$linklib" && test -f "$abs_ladir/$linklib"; then + dir="$ladir" + absdir="$abs_ladir" + # Remove this search path later + func_append notinst_path " $abs_ladir" + else + dir="$ladir/$objdir" + absdir="$abs_ladir/$objdir" + # Remove this search path later + func_append notinst_path " $abs_ladir" + fi + fi # $installed = yes + func_stripname 'lib' '.la' "$laname" + name=$func_stripname_result + + # This library was specified with -dlpreopen. + if test "$pass" = dlpreopen; then + if test -z "$libdir" && test "$linkmode" = prog; then + func_fatal_error "only libraries may -dlpreopen a convenience library: \`$lib'" + fi + case "$host" in + # special handling for platforms with PE-DLLs. + *cygwin* | *mingw* | *cegcc* ) + # Linker will automatically link against shared library if both + # static and shared are present. Therefore, ensure we extract + # symbols from the import library if a shared library is present + # (otherwise, the dlopen module name will be incorrect). We do + # this by putting the import library name into $newdlprefiles. + # We recover the dlopen module name by 'saving' the la file + # name in a special purpose variable, and (later) extracting the + # dlname from the la file. + if test -n "$dlname"; then + func_tr_sh "$dir/$linklib" + eval "libfile_$func_tr_sh_result=\$abs_ladir/\$laname" + func_append newdlprefiles " $dir/$linklib" + else + func_append newdlprefiles " $dir/$old_library" + # Keep a list of preopened convenience libraries to check + # that they are being used correctly in the link pass. + test -z "$libdir" && \ + func_append dlpreconveniencelibs " $dir/$old_library" + fi + ;; + * ) + # Prefer using a static library (so that no silly _DYNAMIC symbols + # are required to link). + if test -n "$old_library"; then + func_append newdlprefiles " $dir/$old_library" + # Keep a list of preopened convenience libraries to check + # that they are being used correctly in the link pass. + test -z "$libdir" && \ + func_append dlpreconveniencelibs " $dir/$old_library" + # Otherwise, use the dlname, so that lt_dlopen finds it. + elif test -n "$dlname"; then + func_append newdlprefiles " $dir/$dlname" + else + func_append newdlprefiles " $dir/$linklib" + fi + ;; + esac + fi # $pass = dlpreopen + + if test -z "$libdir"; then + # Link the convenience library + if test "$linkmode" = lib; then + deplibs="$dir/$old_library $deplibs" + elif test "$linkmode,$pass" = "prog,link"; then + compile_deplibs="$dir/$old_library $compile_deplibs" + finalize_deplibs="$dir/$old_library $finalize_deplibs" + else + deplibs="$lib $deplibs" # used for prog,scan pass + fi + continue + fi + + + if test "$linkmode" = prog && test "$pass" != link; then + func_append newlib_search_path " $ladir" + deplibs="$lib $deplibs" + + linkalldeplibs=no + if test "$link_all_deplibs" != no || test -z "$library_names" || + test "$build_libtool_libs" = no; then + linkalldeplibs=yes + fi + + tmp_libs= + for deplib in $dependency_libs; do + case $deplib in + -L*) func_stripname '-L' '' "$deplib" + func_resolve_sysroot "$func_stripname_result" + func_append newlib_search_path " $func_resolve_sysroot_result" + ;; + esac + # Need to link against all dependency_libs? + if test "$linkalldeplibs" = yes; then + deplibs="$deplib $deplibs" + else + # Need to hardcode shared library paths + # or/and link against static libraries + newdependency_libs="$deplib $newdependency_libs" + fi + if $opt_preserve_dup_deps ; then + case "$tmp_libs " in + *" $deplib "*) func_append specialdeplibs " $deplib" ;; + esac + fi + func_append tmp_libs " $deplib" + done # for deplib + continue + fi # $linkmode = prog... + + if test "$linkmode,$pass" = "prog,link"; then + if test -n "$library_names" && + { { test "$prefer_static_libs" = no || + test "$prefer_static_libs,$installed" = "built,yes"; } || + test -z "$old_library"; }; then + # We need to hardcode the library path + if test -n "$shlibpath_var" && test -z "$avoidtemprpath" ; then + # Make sure the rpath contains only unique directories. + case "$temp_rpath:" in + *"$absdir:"*) ;; + *) func_append temp_rpath "$absdir:" ;; + esac + fi + + # Hardcode the library path. + # Skip directories that are in the system default run-time + # search path. + case " $sys_lib_dlsearch_path " in + *" $absdir "*) ;; + *) + case "$compile_rpath " in + *" $absdir "*) ;; + *) func_append compile_rpath " $absdir" ;; + esac + ;; + esac + case " $sys_lib_dlsearch_path " in + *" $libdir "*) ;; + *) + case "$finalize_rpath " in + *" $libdir "*) ;; + *) func_append finalize_rpath " $libdir" ;; + esac + ;; + esac + fi # $linkmode,$pass = prog,link... + + if test "$alldeplibs" = yes && + { test "$deplibs_check_method" = pass_all || + { test "$build_libtool_libs" = yes && + test -n "$library_names"; }; }; then + # We only need to search for static libraries + continue + fi + fi + + link_static=no # Whether the deplib will be linked statically + use_static_libs=$prefer_static_libs + if test "$use_static_libs" = built && test "$installed" = yes; then + use_static_libs=no + fi + if test -n "$library_names" && + { test "$use_static_libs" = no || test -z "$old_library"; }; then + case $host in + *cygwin* | *mingw* | *cegcc*) + # No point in relinking DLLs because paths are not encoded + func_append notinst_deplibs " $lib" + need_relink=no + ;; + *) + if test "$installed" = no; then + func_append notinst_deplibs " $lib" + need_relink=yes + fi + ;; + esac + # This is a shared library + + # Warn about portability, can't link against -module's on some + # systems (darwin). Don't bleat about dlopened modules though! + dlopenmodule="" + for dlpremoduletest in $dlprefiles; do + if test "X$dlpremoduletest" = "X$lib"; then + dlopenmodule="$dlpremoduletest" + break + fi + done + if test -z "$dlopenmodule" && test "$shouldnotlink" = yes && test "$pass" = link; then + echo + if test "$linkmode" = prog; then + $ECHO "*** Warning: Linking the executable $output against the loadable module" + else + $ECHO "*** Warning: Linking the shared library $output against the loadable module" + fi + $ECHO "*** $linklib is not portable!" + fi + if test "$linkmode" = lib && + test "$hardcode_into_libs" = yes; then + # Hardcode the library path. + # Skip directories that are in the system default run-time + # search path. + case " $sys_lib_dlsearch_path " in + *" $absdir "*) ;; + *) + case "$compile_rpath " in + *" $absdir "*) ;; + *) func_append compile_rpath " $absdir" ;; + esac + ;; + esac + case " $sys_lib_dlsearch_path " in + *" $libdir "*) ;; + *) + case "$finalize_rpath " in + *" $libdir "*) ;; + *) func_append finalize_rpath " $libdir" ;; + esac + ;; + esac + fi + + if test -n "$old_archive_from_expsyms_cmds"; then + # figure out the soname + set dummy $library_names + shift + realname="$1" + shift + libname=`eval "\\$ECHO \"$libname_spec\""` + # use dlname if we got it. it's perfectly good, no? + if test -n "$dlname"; then + soname="$dlname" + elif test -n "$soname_spec"; then + # bleh windows + case $host in + *cygwin* | mingw* | *cegcc*) + func_arith $current - $age + major=$func_arith_result + versuffix="-$major" + ;; + esac + eval soname=\"$soname_spec\" + else + soname="$realname" + fi + + # Make a new name for the extract_expsyms_cmds to use + soroot="$soname" + func_basename "$soroot" + soname="$func_basename_result" + func_stripname 'lib' '.dll' "$soname" + newlib=libimp-$func_stripname_result.a + + # If the library has no export list, then create one now + if test -f "$output_objdir/$soname-def"; then : + else + func_verbose "extracting exported symbol list from \`$soname'" + func_execute_cmds "$extract_expsyms_cmds" 'exit $?' + fi + + # Create $newlib + if test -f "$output_objdir/$newlib"; then :; else + func_verbose "generating import library for \`$soname'" + func_execute_cmds "$old_archive_from_expsyms_cmds" 'exit $?' + fi + # make sure the library variables are pointing to the new library + dir=$output_objdir + linklib=$newlib + fi # test -n "$old_archive_from_expsyms_cmds" + + if test "$linkmode" = prog || test "$opt_mode" != relink; then + add_shlibpath= + add_dir= + add= + lib_linked=yes + case $hardcode_action in + immediate | unsupported) + if test "$hardcode_direct" = no; then + add="$dir/$linklib" + case $host in + *-*-sco3.2v5.0.[024]*) add_dir="-L$dir" ;; + *-*-sysv4*uw2*) add_dir="-L$dir" ;; + *-*-sysv5OpenUNIX* | *-*-sysv5UnixWare7.[01].[10]* | \ + *-*-unixware7*) add_dir="-L$dir" ;; + *-*-darwin* ) + # if the lib is a (non-dlopened) module then we can not + # link against it, someone is ignoring the earlier warnings + if /usr/bin/file -L $add 2> /dev/null | + $GREP ": [^:]* bundle" >/dev/null ; then + if test "X$dlopenmodule" != "X$lib"; then + $ECHO "*** Warning: lib $linklib is a module, not a shared library" + if test -z "$old_library" ; then + echo + echo "*** And there doesn't seem to be a static archive available" + echo "*** The link will probably fail, sorry" + else + add="$dir/$old_library" + fi + elif test -n "$old_library"; then + add="$dir/$old_library" + fi + fi + esac + elif test "$hardcode_minus_L" = no; then + case $host in + *-*-sunos*) add_shlibpath="$dir" ;; + esac + add_dir="-L$dir" + add="-l$name" + elif test "$hardcode_shlibpath_var" = no; then + add_shlibpath="$dir" + add="-l$name" + else + lib_linked=no + fi + ;; + relink) + if test "$hardcode_direct" = yes && + test "$hardcode_direct_absolute" = no; then + add="$dir/$linklib" + elif test "$hardcode_minus_L" = yes; then + add_dir="-L$absdir" + # Try looking first in the location we're being installed to. + if test -n "$inst_prefix_dir"; then + case $libdir in + [\\/]*) + func_append add_dir " -L$inst_prefix_dir$libdir" + ;; + esac + fi + add="-l$name" + elif test "$hardcode_shlibpath_var" = yes; then + add_shlibpath="$dir" + add="-l$name" + else + lib_linked=no + fi + ;; + *) lib_linked=no ;; + esac + + if test "$lib_linked" != yes; then + func_fatal_configuration "unsupported hardcode properties" + fi + + if test -n "$add_shlibpath"; then + case :$compile_shlibpath: in + *":$add_shlibpath:"*) ;; + *) func_append compile_shlibpath "$add_shlibpath:" ;; + esac + fi + if test "$linkmode" = prog; then + test -n "$add_dir" && compile_deplibs="$add_dir $compile_deplibs" + test -n "$add" && compile_deplibs="$add $compile_deplibs" + else + test -n "$add_dir" && deplibs="$add_dir $deplibs" + test -n "$add" && deplibs="$add $deplibs" + if test "$hardcode_direct" != yes && + test "$hardcode_minus_L" != yes && + test "$hardcode_shlibpath_var" = yes; then + case :$finalize_shlibpath: in + *":$libdir:"*) ;; + *) func_append finalize_shlibpath "$libdir:" ;; + esac + fi + fi + fi + + if test "$linkmode" = prog || test "$opt_mode" = relink; then + add_shlibpath= + add_dir= + add= + # Finalize command for both is simple: just hardcode it. + if test "$hardcode_direct" = yes && + test "$hardcode_direct_absolute" = no; then + add="$libdir/$linklib" + elif test "$hardcode_minus_L" = yes; then + add_dir="-L$libdir" + add="-l$name" + elif test "$hardcode_shlibpath_var" = yes; then + case :$finalize_shlibpath: in + *":$libdir:"*) ;; + *) func_append finalize_shlibpath "$libdir:" ;; + esac + add="-l$name" + elif test "$hardcode_automatic" = yes; then + if test -n "$inst_prefix_dir" && + test -f "$inst_prefix_dir$libdir/$linklib" ; then + add="$inst_prefix_dir$libdir/$linklib" + else + add="$libdir/$linklib" + fi + else + # We cannot seem to hardcode it, guess we'll fake it. + add_dir="-L$libdir" + # Try looking first in the location we're being installed to. + if test -n "$inst_prefix_dir"; then + case $libdir in + [\\/]*) + func_append add_dir " -L$inst_prefix_dir$libdir" + ;; + esac + fi + add="-l$name" + fi + + if test "$linkmode" = prog; then + test -n "$add_dir" && finalize_deplibs="$add_dir $finalize_deplibs" + test -n "$add" && finalize_deplibs="$add $finalize_deplibs" + else + test -n "$add_dir" && deplibs="$add_dir $deplibs" + test -n "$add" && deplibs="$add $deplibs" + fi + fi + elif test "$linkmode" = prog; then + # Here we assume that one of hardcode_direct or hardcode_minus_L + # is not unsupported. This is valid on all known static and + # shared platforms. + if test "$hardcode_direct" != unsupported; then + test -n "$old_library" && linklib="$old_library" + compile_deplibs="$dir/$linklib $compile_deplibs" + finalize_deplibs="$dir/$linklib $finalize_deplibs" + else + compile_deplibs="-l$name -L$dir $compile_deplibs" + finalize_deplibs="-l$name -L$dir $finalize_deplibs" + fi + elif test "$build_libtool_libs" = yes; then + # Not a shared library + if test "$deplibs_check_method" != pass_all; then + # We're trying link a shared library against a static one + # but the system doesn't support it. + + # Just print a warning and add the library to dependency_libs so + # that the program can be linked against the static library. + echo + $ECHO "*** Warning: This system can not link to static lib archive $lib." + echo "*** I have the capability to make that library automatically link in when" + echo "*** you link to this library. But I can only do this if you have a" + echo "*** shared version of the library, which you do not appear to have." + if test "$module" = yes; then + echo "*** But as you try to build a module library, libtool will still create " + echo "*** a static module, that should work as long as the dlopening application" + echo "*** is linked with the -dlopen flag to resolve symbols at runtime." + if test -z "$global_symbol_pipe"; then + echo + echo "*** However, this would only work if libtool was able to extract symbol" + echo "*** lists from a program, using \`nm' or equivalent, but libtool could" + echo "*** not find such a program. So, this module is probably useless." + echo "*** \`nm' from GNU binutils and a full rebuild may help." + fi + if test "$build_old_libs" = no; then + build_libtool_libs=module + build_old_libs=yes + else + build_libtool_libs=no + fi + fi + else + deplibs="$dir/$old_library $deplibs" + link_static=yes + fi + fi # link shared/static library? + + if test "$linkmode" = lib; then + if test -n "$dependency_libs" && + { test "$hardcode_into_libs" != yes || + test "$build_old_libs" = yes || + test "$link_static" = yes; }; then + # Extract -R from dependency_libs + temp_deplibs= + for libdir in $dependency_libs; do + case $libdir in + -R*) func_stripname '-R' '' "$libdir" + temp_xrpath=$func_stripname_result + case " $xrpath " in + *" $temp_xrpath "*) ;; + *) func_append xrpath " $temp_xrpath";; + esac;; + *) func_append temp_deplibs " $libdir";; + esac + done + dependency_libs="$temp_deplibs" + fi + + func_append newlib_search_path " $absdir" + # Link against this library + test "$link_static" = no && newdependency_libs="$abs_ladir/$laname $newdependency_libs" + # ... and its dependency_libs + tmp_libs= + for deplib in $dependency_libs; do + newdependency_libs="$deplib $newdependency_libs" + case $deplib in + -L*) func_stripname '-L' '' "$deplib" + func_resolve_sysroot "$func_stripname_result";; + *) func_resolve_sysroot "$deplib" ;; + esac + if $opt_preserve_dup_deps ; then + case "$tmp_libs " in + *" $func_resolve_sysroot_result "*) + func_append specialdeplibs " $func_resolve_sysroot_result" ;; + esac + fi + func_append tmp_libs " $func_resolve_sysroot_result" + done + + if test "$link_all_deplibs" != no; then + # Add the search paths of all dependency libraries + for deplib in $dependency_libs; do + path= + case $deplib in + -L*) path="$deplib" ;; + *.la) + func_resolve_sysroot "$deplib" + deplib=$func_resolve_sysroot_result + func_dirname "$deplib" "" "." + dir=$func_dirname_result + # We need an absolute path. + case $dir in + [\\/]* | [A-Za-z]:[\\/]*) absdir="$dir" ;; + *) + absdir=`cd "$dir" && pwd` + if test -z "$absdir"; then + func_warning "cannot determine absolute directory name of \`$dir'" + absdir="$dir" + fi + ;; + esac + if $GREP "^installed=no" $deplib > /dev/null; then + case $host in + *-*-darwin*) + depdepl= + eval deplibrary_names=`${SED} -n -e 's/^library_names=\(.*\)$/\1/p' $deplib` + if test -n "$deplibrary_names" ; then + for tmp in $deplibrary_names ; do + depdepl=$tmp + done + if test -f "$absdir/$objdir/$depdepl" ; then + depdepl="$absdir/$objdir/$depdepl" + darwin_install_name=`${OTOOL} -L $depdepl | awk '{if (NR == 2) {print $1;exit}}'` + if test -z "$darwin_install_name"; then + darwin_install_name=`${OTOOL64} -L $depdepl | awk '{if (NR == 2) {print $1;exit}}'` + fi + func_append compiler_flags " ${wl}-dylib_file ${wl}${darwin_install_name}:${depdepl}" + func_append linker_flags " -dylib_file ${darwin_install_name}:${depdepl}" + path= + fi + fi + ;; + *) + path="-L$absdir/$objdir" + ;; + esac + else + eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $deplib` + test -z "$libdir" && \ + func_fatal_error "\`$deplib' is not a valid libtool archive" + test "$absdir" != "$libdir" && \ + func_warning "\`$deplib' seems to be moved" + + path="-L$absdir" + fi + ;; + esac + case " $deplibs " in + *" $path "*) ;; + *) deplibs="$path $deplibs" ;; + esac + done + fi # link_all_deplibs != no + fi # linkmode = lib + done # for deplib in $libs + if test "$pass" = link; then + if test "$linkmode" = "prog"; then + compile_deplibs="$new_inherited_linker_flags $compile_deplibs" + finalize_deplibs="$new_inherited_linker_flags $finalize_deplibs" + else + compiler_flags="$compiler_flags "`$ECHO " $new_inherited_linker_flags" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` + fi + fi + dependency_libs="$newdependency_libs" + if test "$pass" = dlpreopen; then + # Link the dlpreopened libraries before other libraries + for deplib in $save_deplibs; do + deplibs="$deplib $deplibs" + done + fi + if test "$pass" != dlopen; then + if test "$pass" != conv; then + # Make sure lib_search_path contains only unique directories. + lib_search_path= + for dir in $newlib_search_path; do + case "$lib_search_path " in + *" $dir "*) ;; + *) func_append lib_search_path " $dir" ;; + esac + done + newlib_search_path= + fi + + if test "$linkmode,$pass" != "prog,link"; then + vars="deplibs" + else + vars="compile_deplibs finalize_deplibs" + fi + for var in $vars dependency_libs; do + # Add libraries to $var in reverse order + eval tmp_libs=\"\$$var\" + new_libs= + for deplib in $tmp_libs; do + # FIXME: Pedantically, this is the right thing to do, so + # that some nasty dependency loop isn't accidentally + # broken: + #new_libs="$deplib $new_libs" + # Pragmatically, this seems to cause very few problems in + # practice: + case $deplib in + -L*) new_libs="$deplib $new_libs" ;; + -R*) ;; + *) + # And here is the reason: when a library appears more + # than once as an explicit dependence of a library, or + # is implicitly linked in more than once by the + # compiler, it is considered special, and multiple + # occurrences thereof are not removed. Compare this + # with having the same library being listed as a + # dependency of multiple other libraries: in this case, + # we know (pedantically, we assume) the library does not + # need to be listed more than once, so we keep only the + # last copy. This is not always right, but it is rare + # enough that we require users that really mean to play + # such unportable linking tricks to link the library + # using -Wl,-lname, so that libtool does not consider it + # for duplicate removal. + case " $specialdeplibs " in + *" $deplib "*) new_libs="$deplib $new_libs" ;; + *) + case " $new_libs " in + *" $deplib "*) ;; + *) new_libs="$deplib $new_libs" ;; + esac + ;; + esac + ;; + esac + done + tmp_libs= + for deplib in $new_libs; do + case $deplib in + -L*) + case " $tmp_libs " in + *" $deplib "*) ;; + *) func_append tmp_libs " $deplib" ;; + esac + ;; + *) func_append tmp_libs " $deplib" ;; + esac + done + eval $var=\"$tmp_libs\" + done # for var + fi + # Last step: remove runtime libs from dependency_libs + # (they stay in deplibs) + tmp_libs= + for i in $dependency_libs ; do + case " $predeps $postdeps $compiler_lib_search_path " in + *" $i "*) + i="" + ;; + esac + if test -n "$i" ; then + func_append tmp_libs " $i" + fi + done + dependency_libs=$tmp_libs + done # for pass + if test "$linkmode" = prog; then + dlfiles="$newdlfiles" + fi + if test "$linkmode" = prog || test "$linkmode" = lib; then + dlprefiles="$newdlprefiles" + fi + + case $linkmode in + oldlib) + if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then + func_warning "\`-dlopen' is ignored for archives" + fi + + case " $deplibs" in + *\ -l* | *\ -L*) + func_warning "\`-l' and \`-L' are ignored for archives" ;; + esac + + test -n "$rpath" && \ + func_warning "\`-rpath' is ignored for archives" + + test -n "$xrpath" && \ + func_warning "\`-R' is ignored for archives" + + test -n "$vinfo" && \ + func_warning "\`-version-info/-version-number' is ignored for archives" + + test -n "$release" && \ + func_warning "\`-release' is ignored for archives" + + test -n "$export_symbols$export_symbols_regex" && \ + func_warning "\`-export-symbols' is ignored for archives" + + # Now set the variables for building old libraries. + build_libtool_libs=no + oldlibs="$output" + func_append objs "$old_deplibs" + ;; + + lib) + # Make sure we only generate libraries of the form `libNAME.la'. + case $outputname in + lib*) + func_stripname 'lib' '.la' "$outputname" + name=$func_stripname_result + eval shared_ext=\"$shrext_cmds\" + eval libname=\"$libname_spec\" + ;; + *) + test "$module" = no && \ + func_fatal_help "libtool library \`$output' must begin with \`lib'" + + if test "$need_lib_prefix" != no; then + # Add the "lib" prefix for modules if required + func_stripname '' '.la' "$outputname" + name=$func_stripname_result + eval shared_ext=\"$shrext_cmds\" + eval libname=\"$libname_spec\" + else + func_stripname '' '.la' "$outputname" + libname=$func_stripname_result + fi + ;; + esac + + if test -n "$objs"; then + if test "$deplibs_check_method" != pass_all; then + func_fatal_error "cannot build libtool library \`$output' from non-libtool objects on this host:$objs" + else + echo + $ECHO "*** Warning: Linking the shared library $output against the non-libtool" + $ECHO "*** objects $objs is not portable!" + func_append libobjs " $objs" + fi + fi + + test "$dlself" != no && \ + func_warning "\`-dlopen self' is ignored for libtool libraries" + + set dummy $rpath + shift + test "$#" -gt 1 && \ + func_warning "ignoring multiple \`-rpath's for a libtool library" + + install_libdir="$1" + + oldlibs= + if test -z "$rpath"; then + if test "$build_libtool_libs" = yes; then + # Building a libtool convenience library. + # Some compilers have problems with a `.al' extension so + # convenience libraries should have the same extension an + # archive normally would. + oldlibs="$output_objdir/$libname.$libext $oldlibs" + build_libtool_libs=convenience + build_old_libs=yes + fi + + test -n "$vinfo" && \ + func_warning "\`-version-info/-version-number' is ignored for convenience libraries" + + test -n "$release" && \ + func_warning "\`-release' is ignored for convenience libraries" + else + + # Parse the version information argument. + save_ifs="$IFS"; IFS=':' + set dummy $vinfo 0 0 0 + shift + IFS="$save_ifs" + + test -n "$7" && \ + func_fatal_help "too many parameters to \`-version-info'" + + # convert absolute version numbers to libtool ages + # this retains compatibility with .la files and attempts + # to make the code below a bit more comprehensible + + case $vinfo_number in + yes) + number_major="$1" + number_minor="$2" + number_revision="$3" + # + # There are really only two kinds -- those that + # use the current revision as the major version + # and those that subtract age and use age as + # a minor version. But, then there is irix + # which has an extra 1 added just for fun + # + case $version_type in + # correct linux to gnu/linux during the next big refactor + darwin|linux|osf|windows|none) + func_arith $number_major + $number_minor + current=$func_arith_result + age="$number_minor" + revision="$number_revision" + ;; + freebsd-aout|freebsd-elf|qnx|sunos) + current="$number_major" + revision="$number_minor" + age="0" + ;; + irix|nonstopux) + func_arith $number_major + $number_minor + current=$func_arith_result + age="$number_minor" + revision="$number_minor" + lt_irix_increment=no + ;; + *) + func_fatal_configuration "$modename: unknown library version type \`$version_type'" + ;; + esac + ;; + no) + current="$1" + revision="$2" + age="$3" + ;; + esac + + # Check that each of the things are valid numbers. + case $current in + 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; + *) + func_error "CURRENT \`$current' must be a nonnegative integer" + func_fatal_error "\`$vinfo' is not valid version information" + ;; + esac + + case $revision in + 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; + *) + func_error "REVISION \`$revision' must be a nonnegative integer" + func_fatal_error "\`$vinfo' is not valid version information" + ;; + esac + + case $age in + 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; + *) + func_error "AGE \`$age' must be a nonnegative integer" + func_fatal_error "\`$vinfo' is not valid version information" + ;; + esac + + if test "$age" -gt "$current"; then + func_error "AGE \`$age' is greater than the current interface number \`$current'" + func_fatal_error "\`$vinfo' is not valid version information" + fi + + # Calculate the version variables. + major= + versuffix= + verstring= + case $version_type in + none) ;; + + darwin) + # Like Linux, but with the current version available in + # verstring for coding it into the library header + func_arith $current - $age + major=.$func_arith_result + versuffix="$major.$age.$revision" + # Darwin ld doesn't like 0 for these options... + func_arith $current + 1 + minor_current=$func_arith_result + xlcverstring="${wl}-compatibility_version ${wl}$minor_current ${wl}-current_version ${wl}$minor_current.$revision" + verstring="-compatibility_version $minor_current -current_version $minor_current.$revision" + ;; + + freebsd-aout) + major=".$current" + versuffix=".$current.$revision"; + ;; + + freebsd-elf) + major=".$current" + versuffix=".$current" + ;; + + irix | nonstopux) + if test "X$lt_irix_increment" = "Xno"; then + func_arith $current - $age + else + func_arith $current - $age + 1 + fi + major=$func_arith_result + + case $version_type in + nonstopux) verstring_prefix=nonstopux ;; + *) verstring_prefix=sgi ;; + esac + verstring="$verstring_prefix$major.$revision" + + # Add in all the interfaces that we are compatible with. + loop=$revision + while test "$loop" -ne 0; do + func_arith $revision - $loop + iface=$func_arith_result + func_arith $loop - 1 + loop=$func_arith_result + verstring="$verstring_prefix$major.$iface:$verstring" + done + + # Before this point, $major must not contain `.'. + major=.$major + versuffix="$major.$revision" + ;; + + linux) # correct to gnu/linux during the next big refactor + func_arith $current - $age + major=.$func_arith_result + versuffix="$major.$age.$revision" + ;; + + osf) + func_arith $current - $age + major=.$func_arith_result + versuffix=".$current.$age.$revision" + verstring="$current.$age.$revision" + + # Add in all the interfaces that we are compatible with. + loop=$age + while test "$loop" -ne 0; do + func_arith $current - $loop + iface=$func_arith_result + func_arith $loop - 1 + loop=$func_arith_result + verstring="$verstring:${iface}.0" + done + + # Make executables depend on our current version. + func_append verstring ":${current}.0" + ;; + + qnx) + major=".$current" + versuffix=".$current" + ;; + + sunos) + major=".$current" + versuffix=".$current.$revision" + ;; + + windows) + # Use '-' rather than '.', since we only want one + # extension on DOS 8.3 filesystems. + func_arith $current - $age + major=$func_arith_result + versuffix="-$major" + ;; + + *) + func_fatal_configuration "unknown library version type \`$version_type'" + ;; + esac + + # Clear the version info if we defaulted, and they specified a release. + if test -z "$vinfo" && test -n "$release"; then + major= + case $version_type in + darwin) + # we can't check for "0.0" in archive_cmds due to quoting + # problems, so we reset it completely + verstring= + ;; + *) + verstring="0.0" + ;; + esac + if test "$need_version" = no; then + versuffix= + else + versuffix=".0.0" + fi + fi + + # Remove version info from name if versioning should be avoided + if test "$avoid_version" = yes && test "$need_version" = no; then + major= + versuffix= + verstring="" + fi + + # Check to see if the archive will have undefined symbols. + if test "$allow_undefined" = yes; then + if test "$allow_undefined_flag" = unsupported; then + func_warning "undefined symbols not allowed in $host shared libraries" + build_libtool_libs=no + build_old_libs=yes + fi + else + # Don't allow undefined symbols. + allow_undefined_flag="$no_undefined_flag" + fi + + fi + + func_generate_dlsyms "$libname" "$libname" "yes" + func_append libobjs " $symfileobj" + test "X$libobjs" = "X " && libobjs= + + if test "$opt_mode" != relink; then + # Remove our outputs, but don't remove object files since they + # may have been created when compiling PIC objects. + removelist= + tempremovelist=`$ECHO "$output_objdir/*"` + for p in $tempremovelist; do + case $p in + *.$objext | *.gcno) + ;; + $output_objdir/$outputname | $output_objdir/$libname.* | $output_objdir/${libname}${release}.*) + if test "X$precious_files_regex" != "X"; then + if $ECHO "$p" | $EGREP -e "$precious_files_regex" >/dev/null 2>&1 + then + continue + fi + fi + func_append removelist " $p" + ;; + *) ;; + esac + done + test -n "$removelist" && \ + func_show_eval "${RM}r \$removelist" + fi + + # Now set the variables for building old libraries. + if test "$build_old_libs" = yes && test "$build_libtool_libs" != convenience ; then + func_append oldlibs " $output_objdir/$libname.$libext" + + # Transform .lo files to .o files. + oldobjs="$objs "`$ECHO "$libobjs" | $SP2NL | $SED "/\.${libext}$/d; $lo2o" | $NL2SP` + fi + + # Eliminate all temporary directories. + #for path in $notinst_path; do + # lib_search_path=`$ECHO "$lib_search_path " | $SED "s% $path % %g"` + # deplibs=`$ECHO "$deplibs " | $SED "s% -L$path % %g"` + # dependency_libs=`$ECHO "$dependency_libs " | $SED "s% -L$path % %g"` + #done + + if test -n "$xrpath"; then + # If the user specified any rpath flags, then add them. + temp_xrpath= + for libdir in $xrpath; do + func_replace_sysroot "$libdir" + func_append temp_xrpath " -R$func_replace_sysroot_result" + case "$finalize_rpath " in + *" $libdir "*) ;; + *) func_append finalize_rpath " $libdir" ;; + esac + done + if test "$hardcode_into_libs" != yes || test "$build_old_libs" = yes; then + dependency_libs="$temp_xrpath $dependency_libs" + fi + fi + + # Make sure dlfiles contains only unique files that won't be dlpreopened + old_dlfiles="$dlfiles" + dlfiles= + for lib in $old_dlfiles; do + case " $dlprefiles $dlfiles " in + *" $lib "*) ;; + *) func_append dlfiles " $lib" ;; + esac + done + + # Make sure dlprefiles contains only unique files + old_dlprefiles="$dlprefiles" + dlprefiles= + for lib in $old_dlprefiles; do + case "$dlprefiles " in + *" $lib "*) ;; + *) func_append dlprefiles " $lib" ;; + esac + done + + if test "$build_libtool_libs" = yes; then + if test -n "$rpath"; then + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-beos* | *-cegcc* | *-*-haiku*) + # these systems don't actually have a c library (as such)! + ;; + *-*-rhapsody* | *-*-darwin1.[012]) + # Rhapsody C library is in the System framework + func_append deplibs " System.ltframework" + ;; + *-*-netbsd*) + # Don't link with libc until the a.out ld.so is fixed. + ;; + *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*) + # Do not include libc due to us having libc/libc_r. + ;; + *-*-sco3.2v5* | *-*-sco5v6*) + # Causes problems with __ctype + ;; + *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*) + # Compiler inserts libc in the correct place for threads to work + ;; + *) + # Add libc to deplibs on all other systems if necessary. + if test "$build_libtool_need_lc" = "yes"; then + func_append deplibs " -lc" + fi + ;; + esac + fi + + # Transform deplibs into only deplibs that can be linked in shared. + name_save=$name + libname_save=$libname + release_save=$release + versuffix_save=$versuffix + major_save=$major + # I'm not sure if I'm treating the release correctly. I think + # release should show up in the -l (ie -lgmp5) so we don't want to + # add it in twice. Is that correct? + release="" + versuffix="" + major="" + newdeplibs= + droppeddeps=no + case $deplibs_check_method in + pass_all) + # Don't check for shared/static. Everything works. + # This might be a little naive. We might want to check + # whether the library exists or not. But this is on + # osf3 & osf4 and I'm not really sure... Just + # implementing what was already the behavior. + newdeplibs=$deplibs + ;; + test_compile) + # This code stresses the "libraries are programs" paradigm to its + # limits. Maybe even breaks it. We compile a program, linking it + # against the deplibs as a proxy for the library. Then we can check + # whether they linked in statically or dynamically with ldd. + $opt_dry_run || $RM conftest.c + cat > conftest.c </dev/null` + $nocaseglob + else + potential_libs=`ls $i/$libnameglob[.-]* 2>/dev/null` + fi + for potent_lib in $potential_libs; do + # Follow soft links. + if ls -lLd "$potent_lib" 2>/dev/null | + $GREP " -> " >/dev/null; then + continue + fi + # The statement above tries to avoid entering an + # endless loop below, in case of cyclic links. + # We might still enter an endless loop, since a link + # loop can be closed while we follow links, + # but so what? + potlib="$potent_lib" + while test -h "$potlib" 2>/dev/null; do + potliblink=`ls -ld $potlib | ${SED} 's/.* -> //'` + case $potliblink in + [\\/]* | [A-Za-z]:[\\/]*) potlib="$potliblink";; + *) potlib=`$ECHO "$potlib" | $SED 's,[^/]*$,,'`"$potliblink";; + esac + done + if eval $file_magic_cmd \"\$potlib\" 2>/dev/null | + $SED -e 10q | + $EGREP "$file_magic_regex" > /dev/null; then + func_append newdeplibs " $a_deplib" + a_deplib="" + break 2 + fi + done + done + fi + if test -n "$a_deplib" ; then + droppeddeps=yes + echo + $ECHO "*** Warning: linker path does not have real file for library $a_deplib." + echo "*** I have the capability to make that library automatically link in when" + echo "*** you link to this library. But I can only do this if you have a" + echo "*** shared version of the library, which you do not appear to have" + echo "*** because I did check the linker path looking for a file starting" + if test -z "$potlib" ; then + $ECHO "*** with $libname but no candidates were found. (...for file magic test)" + else + $ECHO "*** with $libname and none of the candidates passed a file format test" + $ECHO "*** using a file magic. Last file checked: $potlib" + fi + fi + ;; + *) + # Add a -L argument. + func_append newdeplibs " $a_deplib" + ;; + esac + done # Gone through all deplibs. + ;; + match_pattern*) + set dummy $deplibs_check_method; shift + match_pattern_regex=`expr "$deplibs_check_method" : "$1 \(.*\)"` + for a_deplib in $deplibs; do + case $a_deplib in + -l*) + func_stripname -l '' "$a_deplib" + name=$func_stripname_result + if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then + case " $predeps $postdeps " in + *" $a_deplib "*) + func_append newdeplibs " $a_deplib" + a_deplib="" + ;; + esac + fi + if test -n "$a_deplib" ; then + libname=`eval "\\$ECHO \"$libname_spec\""` + for i in $lib_search_path $sys_lib_search_path $shlib_search_path; do + potential_libs=`ls $i/$libname[.-]* 2>/dev/null` + for potent_lib in $potential_libs; do + potlib="$potent_lib" # see symlink-check above in file_magic test + if eval "\$ECHO \"$potent_lib\"" 2>/dev/null | $SED 10q | \ + $EGREP "$match_pattern_regex" > /dev/null; then + func_append newdeplibs " $a_deplib" + a_deplib="" + break 2 + fi + done + done + fi + if test -n "$a_deplib" ; then + droppeddeps=yes + echo + $ECHO "*** Warning: linker path does not have real file for library $a_deplib." + echo "*** I have the capability to make that library automatically link in when" + echo "*** you link to this library. But I can only do this if you have a" + echo "*** shared version of the library, which you do not appear to have" + echo "*** because I did check the linker path looking for a file starting" + if test -z "$potlib" ; then + $ECHO "*** with $libname but no candidates were found. (...for regex pattern test)" + else + $ECHO "*** with $libname and none of the candidates passed a file format test" + $ECHO "*** using a regex pattern. Last file checked: $potlib" + fi + fi + ;; + *) + # Add a -L argument. + func_append newdeplibs " $a_deplib" + ;; + esac + done # Gone through all deplibs. + ;; + none | unknown | *) + newdeplibs="" + tmp_deplibs=`$ECHO " $deplibs" | $SED 's/ -lc$//; s/ -[LR][^ ]*//g'` + if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then + for i in $predeps $postdeps ; do + # can't use Xsed below, because $i might contain '/' + tmp_deplibs=`$ECHO " $tmp_deplibs" | $SED "s,$i,,"` + done + fi + case $tmp_deplibs in + *[!\ \ ]*) + echo + if test "X$deplibs_check_method" = "Xnone"; then + echo "*** Warning: inter-library dependencies are not supported in this platform." + else + echo "*** Warning: inter-library dependencies are not known to be supported." + fi + echo "*** All declared inter-library dependencies are being dropped." + droppeddeps=yes + ;; + esac + ;; + esac + versuffix=$versuffix_save + major=$major_save + release=$release_save + libname=$libname_save + name=$name_save + + case $host in + *-*-rhapsody* | *-*-darwin1.[012]) + # On Rhapsody replace the C library with the System framework + newdeplibs=`$ECHO " $newdeplibs" | $SED 's/ -lc / System.ltframework /'` + ;; + esac + + if test "$droppeddeps" = yes; then + if test "$module" = yes; then + echo + echo "*** Warning: libtool could not satisfy all declared inter-library" + $ECHO "*** dependencies of module $libname. Therefore, libtool will create" + echo "*** a static module, that should work as long as the dlopening" + echo "*** application is linked with the -dlopen flag." + if test -z "$global_symbol_pipe"; then + echo + echo "*** However, this would only work if libtool was able to extract symbol" + echo "*** lists from a program, using \`nm' or equivalent, but libtool could" + echo "*** not find such a program. So, this module is probably useless." + echo "*** \`nm' from GNU binutils and a full rebuild may help." + fi + if test "$build_old_libs" = no; then + oldlibs="$output_objdir/$libname.$libext" + build_libtool_libs=module + build_old_libs=yes + else + build_libtool_libs=no + fi + else + echo "*** The inter-library dependencies that have been dropped here will be" + echo "*** automatically added whenever a program is linked with this library" + echo "*** or is declared to -dlopen it." + + if test "$allow_undefined" = no; then + echo + echo "*** Since this library must not contain undefined symbols," + echo "*** because either the platform does not support them or" + echo "*** it was explicitly requested with -no-undefined," + echo "*** libtool will only create a static version of it." + if test "$build_old_libs" = no; then + oldlibs="$output_objdir/$libname.$libext" + build_libtool_libs=module + build_old_libs=yes + else + build_libtool_libs=no + fi + fi + fi + fi + # Done checking deplibs! + deplibs=$newdeplibs + fi + # Time to change all our "foo.ltframework" stuff back to "-framework foo" + case $host in + *-*-darwin*) + newdeplibs=`$ECHO " $newdeplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` + new_inherited_linker_flags=`$ECHO " $new_inherited_linker_flags" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` + deplibs=`$ECHO " $deplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` + ;; + esac + + # move library search paths that coincide with paths to not yet + # installed libraries to the beginning of the library search list + new_libs= + for path in $notinst_path; do + case " $new_libs " in + *" -L$path/$objdir "*) ;; + *) + case " $deplibs " in + *" -L$path/$objdir "*) + func_append new_libs " -L$path/$objdir" ;; + esac + ;; + esac + done + for deplib in $deplibs; do + case $deplib in + -L*) + case " $new_libs " in + *" $deplib "*) ;; + *) func_append new_libs " $deplib" ;; + esac + ;; + *) func_append new_libs " $deplib" ;; + esac + done + deplibs="$new_libs" + + # All the library-specific variables (install_libdir is set above). + library_names= + old_library= + dlname= + + # Test again, we may have decided not to build it any more + if test "$build_libtool_libs" = yes; then + # Remove ${wl} instances when linking with ld. + # FIXME: should test the right _cmds variable. + case $archive_cmds in + *\$LD\ *) wl= ;; + esac + if test "$hardcode_into_libs" = yes; then + # Hardcode the library paths + hardcode_libdirs= + dep_rpath= + rpath="$finalize_rpath" + test "$opt_mode" != relink && rpath="$compile_rpath$rpath" + for libdir in $rpath; do + if test -n "$hardcode_libdir_flag_spec"; then + if test -n "$hardcode_libdir_separator"; then + func_replace_sysroot "$libdir" + libdir=$func_replace_sysroot_result + if test -z "$hardcode_libdirs"; then + hardcode_libdirs="$libdir" + else + # Just accumulate the unique libdirs. + case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in + *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) + ;; + *) + func_append hardcode_libdirs "$hardcode_libdir_separator$libdir" + ;; + esac + fi + else + eval flag=\"$hardcode_libdir_flag_spec\" + func_append dep_rpath " $flag" + fi + elif test -n "$runpath_var"; then + case "$perm_rpath " in + *" $libdir "*) ;; + *) func_append perm_rpath " $libdir" ;; + esac + fi + done + # Substitute the hardcoded libdirs into the rpath. + if test -n "$hardcode_libdir_separator" && + test -n "$hardcode_libdirs"; then + libdir="$hardcode_libdirs" + eval "dep_rpath=\"$hardcode_libdir_flag_spec\"" + fi + if test -n "$runpath_var" && test -n "$perm_rpath"; then + # We should set the runpath_var. + rpath= + for dir in $perm_rpath; do + func_append rpath "$dir:" + done + eval "$runpath_var='$rpath\$$runpath_var'; export $runpath_var" + fi + test -n "$dep_rpath" && deplibs="$dep_rpath $deplibs" + fi + + shlibpath="$finalize_shlibpath" + test "$opt_mode" != relink && shlibpath="$compile_shlibpath$shlibpath" + if test -n "$shlibpath"; then + eval "$shlibpath_var='$shlibpath\$$shlibpath_var'; export $shlibpath_var" + fi + + # Get the real and link names of the library. + eval shared_ext=\"$shrext_cmds\" + eval library_names=\"$library_names_spec\" + set dummy $library_names + shift + realname="$1" + shift + + if test -n "$soname_spec"; then + eval soname=\"$soname_spec\" + else + soname="$realname" + fi + if test -z "$dlname"; then + dlname=$soname + fi + + lib="$output_objdir/$realname" + linknames= + for link + do + func_append linknames " $link" + done + + # Use standard objects if they are pic + test -z "$pic_flag" && libobjs=`$ECHO "$libobjs" | $SP2NL | $SED "$lo2o" | $NL2SP` + test "X$libobjs" = "X " && libobjs= + + delfiles= + if test -n "$export_symbols" && test -n "$include_expsyms"; then + $opt_dry_run || cp "$export_symbols" "$output_objdir/$libname.uexp" + export_symbols="$output_objdir/$libname.uexp" + func_append delfiles " $export_symbols" + fi + + orig_export_symbols= + case $host_os in + cygwin* | mingw* | cegcc*) + if test -n "$export_symbols" && test -z "$export_symbols_regex"; then + # exporting using user supplied symfile + if test "x`$SED 1q $export_symbols`" != xEXPORTS; then + # and it's NOT already a .def file. Must figure out + # which of the given symbols are data symbols and tag + # them as such. So, trigger use of export_symbols_cmds. + # export_symbols gets reassigned inside the "prepare + # the list of exported symbols" if statement, so the + # include_expsyms logic still works. + orig_export_symbols="$export_symbols" + export_symbols= + always_export_symbols=yes + fi + fi + ;; + esac + + # Prepare the list of exported symbols + if test -z "$export_symbols"; then + if test "$always_export_symbols" = yes || test -n "$export_symbols_regex"; then + func_verbose "generating symbol list for \`$libname.la'" + export_symbols="$output_objdir/$libname.exp" + $opt_dry_run || $RM $export_symbols + cmds=$export_symbols_cmds + save_ifs="$IFS"; IFS='~' + for cmd1 in $cmds; do + IFS="$save_ifs" + # Take the normal branch if the nm_file_list_spec branch + # doesn't work or if tool conversion is not needed. + case $nm_file_list_spec~$to_tool_file_cmd in + *~func_convert_file_noop | *~func_convert_file_msys_to_w32 | ~*) + try_normal_branch=yes + eval cmd=\"$cmd1\" + func_len " $cmd" + len=$func_len_result + ;; + *) + try_normal_branch=no + ;; + esac + if test "$try_normal_branch" = yes \ + && { test "$len" -lt "$max_cmd_len" \ + || test "$max_cmd_len" -le -1; } + then + func_show_eval "$cmd" 'exit $?' + skipped_export=false + elif test -n "$nm_file_list_spec"; then + func_basename "$output" + output_la=$func_basename_result + save_libobjs=$libobjs + save_output=$output + output=${output_objdir}/${output_la}.nm + func_to_tool_file "$output" + libobjs=$nm_file_list_spec$func_to_tool_file_result + func_append delfiles " $output" + func_verbose "creating $NM input file list: $output" + for obj in $save_libobjs; do + func_to_tool_file "$obj" + $ECHO "$func_to_tool_file_result" + done > "$output" + eval cmd=\"$cmd1\" + func_show_eval "$cmd" 'exit $?' + output=$save_output + libobjs=$save_libobjs + skipped_export=false + else + # The command line is too long to execute in one step. + func_verbose "using reloadable object file for export list..." + skipped_export=: + # Break out early, otherwise skipped_export may be + # set to false by a later but shorter cmd. + break + fi + done + IFS="$save_ifs" + if test -n "$export_symbols_regex" && test "X$skipped_export" != "X:"; then + func_show_eval '$EGREP -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"' + func_show_eval '$MV "${export_symbols}T" "$export_symbols"' + fi + fi + fi + + if test -n "$export_symbols" && test -n "$include_expsyms"; then + tmp_export_symbols="$export_symbols" + test -n "$orig_export_symbols" && tmp_export_symbols="$orig_export_symbols" + $opt_dry_run || eval '$ECHO "$include_expsyms" | $SP2NL >> "$tmp_export_symbols"' + fi + + if test "X$skipped_export" != "X:" && test -n "$orig_export_symbols"; then + # The given exports_symbols file has to be filtered, so filter it. + func_verbose "filter symbol list for \`$libname.la' to tag DATA exports" + # FIXME: $output_objdir/$libname.filter potentially contains lots of + # 's' commands which not all seds can handle. GNU sed should be fine + # though. Also, the filter scales superlinearly with the number of + # global variables. join(1) would be nice here, but unfortunately + # isn't a blessed tool. + $opt_dry_run || $SED -e '/[ ,]DATA/!d;s,\(.*\)\([ \,].*\),s|^\1$|\1\2|,' < $export_symbols > $output_objdir/$libname.filter + func_append delfiles " $export_symbols $output_objdir/$libname.filter" + export_symbols=$output_objdir/$libname.def + $opt_dry_run || $SED -f $output_objdir/$libname.filter < $orig_export_symbols > $export_symbols + fi + + tmp_deplibs= + for test_deplib in $deplibs; do + case " $convenience " in + *" $test_deplib "*) ;; + *) + func_append tmp_deplibs " $test_deplib" + ;; + esac + done + deplibs="$tmp_deplibs" + + if test -n "$convenience"; then + if test -n "$whole_archive_flag_spec" && + test "$compiler_needs_object" = yes && + test -z "$libobjs"; then + # extract the archives, so we have objects to list. + # TODO: could optimize this to just extract one archive. + whole_archive_flag_spec= + fi + if test -n "$whole_archive_flag_spec"; then + save_libobjs=$libobjs + eval libobjs=\"\$libobjs $whole_archive_flag_spec\" + test "X$libobjs" = "X " && libobjs= + else + gentop="$output_objdir/${outputname}x" + func_append generated " $gentop" + + func_extract_archives $gentop $convenience + func_append libobjs " $func_extract_archives_result" + test "X$libobjs" = "X " && libobjs= + fi + fi + + if test "$thread_safe" = yes && test -n "$thread_safe_flag_spec"; then + eval flag=\"$thread_safe_flag_spec\" + func_append linker_flags " $flag" + fi + + # Make a backup of the uninstalled library when relinking + if test "$opt_mode" = relink; then + $opt_dry_run || eval '(cd $output_objdir && $RM ${realname}U && $MV $realname ${realname}U)' || exit $? + fi + + # Do each of the archive commands. + if test "$module" = yes && test -n "$module_cmds" ; then + if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then + eval test_cmds=\"$module_expsym_cmds\" + cmds=$module_expsym_cmds + else + eval test_cmds=\"$module_cmds\" + cmds=$module_cmds + fi + else + if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then + eval test_cmds=\"$archive_expsym_cmds\" + cmds=$archive_expsym_cmds + else + eval test_cmds=\"$archive_cmds\" + cmds=$archive_cmds + fi + fi + + if test "X$skipped_export" != "X:" && + func_len " $test_cmds" && + len=$func_len_result && + test "$len" -lt "$max_cmd_len" || test "$max_cmd_len" -le -1; then + : + else + # The command line is too long to link in one step, link piecewise + # or, if using GNU ld and skipped_export is not :, use a linker + # script. + + # Save the value of $output and $libobjs because we want to + # use them later. If we have whole_archive_flag_spec, we + # want to use save_libobjs as it was before + # whole_archive_flag_spec was expanded, because we can't + # assume the linker understands whole_archive_flag_spec. + # This may have to be revisited, in case too many + # convenience libraries get linked in and end up exceeding + # the spec. + if test -z "$convenience" || test -z "$whole_archive_flag_spec"; then + save_libobjs=$libobjs + fi + save_output=$output + func_basename "$output" + output_la=$func_basename_result + + # Clear the reloadable object creation command queue and + # initialize k to one. + test_cmds= + concat_cmds= + objlist= + last_robj= + k=1 + + if test -n "$save_libobjs" && test "X$skipped_export" != "X:" && test "$with_gnu_ld" = yes; then + output=${output_objdir}/${output_la}.lnkscript + func_verbose "creating GNU ld script: $output" + echo 'INPUT (' > $output + for obj in $save_libobjs + do + func_to_tool_file "$obj" + $ECHO "$func_to_tool_file_result" >> $output + done + echo ')' >> $output + func_append delfiles " $output" + func_to_tool_file "$output" + output=$func_to_tool_file_result + elif test -n "$save_libobjs" && test "X$skipped_export" != "X:" && test "X$file_list_spec" != X; then + output=${output_objdir}/${output_la}.lnk + func_verbose "creating linker input file list: $output" + : > $output + set x $save_libobjs + shift + firstobj= + if test "$compiler_needs_object" = yes; then + firstobj="$1 " + shift + fi + for obj + do + func_to_tool_file "$obj" + $ECHO "$func_to_tool_file_result" >> $output + done + func_append delfiles " $output" + func_to_tool_file "$output" + output=$firstobj\"$file_list_spec$func_to_tool_file_result\" + else + if test -n "$save_libobjs"; then + func_verbose "creating reloadable object files..." + output=$output_objdir/$output_la-${k}.$objext + eval test_cmds=\"$reload_cmds\" + func_len " $test_cmds" + len0=$func_len_result + len=$len0 + + # Loop over the list of objects to be linked. + for obj in $save_libobjs + do + func_len " $obj" + func_arith $len + $func_len_result + len=$func_arith_result + if test "X$objlist" = X || + test "$len" -lt "$max_cmd_len"; then + func_append objlist " $obj" + else + # The command $test_cmds is almost too long, add a + # command to the queue. + if test "$k" -eq 1 ; then + # The first file doesn't have a previous command to add. + reload_objs=$objlist + eval concat_cmds=\"$reload_cmds\" + else + # All subsequent reloadable object files will link in + # the last one created. + reload_objs="$objlist $last_robj" + eval concat_cmds=\"\$concat_cmds~$reload_cmds~\$RM $last_robj\" + fi + last_robj=$output_objdir/$output_la-${k}.$objext + func_arith $k + 1 + k=$func_arith_result + output=$output_objdir/$output_la-${k}.$objext + objlist=" $obj" + func_len " $last_robj" + func_arith $len0 + $func_len_result + len=$func_arith_result + fi + done + # Handle the remaining objects by creating one last + # reloadable object file. All subsequent reloadable object + # files will link in the last one created. + test -z "$concat_cmds" || concat_cmds=$concat_cmds~ + reload_objs="$objlist $last_robj" + eval concat_cmds=\"\${concat_cmds}$reload_cmds\" + if test -n "$last_robj"; then + eval concat_cmds=\"\${concat_cmds}~\$RM $last_robj\" + fi + func_append delfiles " $output" + + else + output= + fi + + if ${skipped_export-false}; then + func_verbose "generating symbol list for \`$libname.la'" + export_symbols="$output_objdir/$libname.exp" + $opt_dry_run || $RM $export_symbols + libobjs=$output + # Append the command to create the export file. + test -z "$concat_cmds" || concat_cmds=$concat_cmds~ + eval concat_cmds=\"\$concat_cmds$export_symbols_cmds\" + if test -n "$last_robj"; then + eval concat_cmds=\"\$concat_cmds~\$RM $last_robj\" + fi + fi + + test -n "$save_libobjs" && + func_verbose "creating a temporary reloadable object file: $output" + + # Loop through the commands generated above and execute them. + save_ifs="$IFS"; IFS='~' + for cmd in $concat_cmds; do + IFS="$save_ifs" + $opt_silent || { + func_quote_for_expand "$cmd" + eval "func_echo $func_quote_for_expand_result" + } + $opt_dry_run || eval "$cmd" || { + lt_exit=$? + + # Restore the uninstalled library and exit + if test "$opt_mode" = relink; then + ( cd "$output_objdir" && \ + $RM "${realname}T" && \ + $MV "${realname}U" "$realname" ) + fi + + exit $lt_exit + } + done + IFS="$save_ifs" + + if test -n "$export_symbols_regex" && ${skipped_export-false}; then + func_show_eval '$EGREP -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"' + func_show_eval '$MV "${export_symbols}T" "$export_symbols"' + fi + fi + + if ${skipped_export-false}; then + if test -n "$export_symbols" && test -n "$include_expsyms"; then + tmp_export_symbols="$export_symbols" + test -n "$orig_export_symbols" && tmp_export_symbols="$orig_export_symbols" + $opt_dry_run || eval '$ECHO "$include_expsyms" | $SP2NL >> "$tmp_export_symbols"' + fi + + if test -n "$orig_export_symbols"; then + # The given exports_symbols file has to be filtered, so filter it. + func_verbose "filter symbol list for \`$libname.la' to tag DATA exports" + # FIXME: $output_objdir/$libname.filter potentially contains lots of + # 's' commands which not all seds can handle. GNU sed should be fine + # though. Also, the filter scales superlinearly with the number of + # global variables. join(1) would be nice here, but unfortunately + # isn't a blessed tool. + $opt_dry_run || $SED -e '/[ ,]DATA/!d;s,\(.*\)\([ \,].*\),s|^\1$|\1\2|,' < $export_symbols > $output_objdir/$libname.filter + func_append delfiles " $export_symbols $output_objdir/$libname.filter" + export_symbols=$output_objdir/$libname.def + $opt_dry_run || $SED -f $output_objdir/$libname.filter < $orig_export_symbols > $export_symbols + fi + fi + + libobjs=$output + # Restore the value of output. + output=$save_output + + if test -n "$convenience" && test -n "$whole_archive_flag_spec"; then + eval libobjs=\"\$libobjs $whole_archive_flag_spec\" + test "X$libobjs" = "X " && libobjs= + fi + # Expand the library linking commands again to reset the + # value of $libobjs for piecewise linking. + + # Do each of the archive commands. + if test "$module" = yes && test -n "$module_cmds" ; then + if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then + cmds=$module_expsym_cmds + else + cmds=$module_cmds + fi + else + if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then + cmds=$archive_expsym_cmds + else + cmds=$archive_cmds + fi + fi + fi + + if test -n "$delfiles"; then + # Append the command to remove temporary files to $cmds. + eval cmds=\"\$cmds~\$RM $delfiles\" + fi + + # Add any objects from preloaded convenience libraries + if test -n "$dlprefiles"; then + gentop="$output_objdir/${outputname}x" + func_append generated " $gentop" + + func_extract_archives $gentop $dlprefiles + func_append libobjs " $func_extract_archives_result" + test "X$libobjs" = "X " && libobjs= + fi + + save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + IFS="$save_ifs" + eval cmd=\"$cmd\" + $opt_silent || { + func_quote_for_expand "$cmd" + eval "func_echo $func_quote_for_expand_result" + } + $opt_dry_run || eval "$cmd" || { + lt_exit=$? + + # Restore the uninstalled library and exit + if test "$opt_mode" = relink; then + ( cd "$output_objdir" && \ + $RM "${realname}T" && \ + $MV "${realname}U" "$realname" ) + fi + + exit $lt_exit + } + done + IFS="$save_ifs" + + # Restore the uninstalled library and exit + if test "$opt_mode" = relink; then + $opt_dry_run || eval '(cd $output_objdir && $RM ${realname}T && $MV $realname ${realname}T && $MV ${realname}U $realname)' || exit $? + + if test -n "$convenience"; then + if test -z "$whole_archive_flag_spec"; then + func_show_eval '${RM}r "$gentop"' + fi + fi + + exit $EXIT_SUCCESS + fi + + # Create links to the real library. + for linkname in $linknames; do + if test "$realname" != "$linkname"; then + func_show_eval '(cd "$output_objdir" && $RM "$linkname" && $LN_S "$realname" "$linkname")' 'exit $?' + fi + done + + # If -module or -export-dynamic was specified, set the dlname. + if test "$module" = yes || test "$export_dynamic" = yes; then + # On all known operating systems, these are identical. + dlname="$soname" + fi + fi + ;; + + obj) + if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then + func_warning "\`-dlopen' is ignored for objects" + fi + + case " $deplibs" in + *\ -l* | *\ -L*) + func_warning "\`-l' and \`-L' are ignored for objects" ;; + esac + + test -n "$rpath" && \ + func_warning "\`-rpath' is ignored for objects" + + test -n "$xrpath" && \ + func_warning "\`-R' is ignored for objects" + + test -n "$vinfo" && \ + func_warning "\`-version-info' is ignored for objects" + + test -n "$release" && \ + func_warning "\`-release' is ignored for objects" + + case $output in + *.lo) + test -n "$objs$old_deplibs" && \ + func_fatal_error "cannot build library object \`$output' from non-libtool objects" + + libobj=$output + func_lo2o "$libobj" + obj=$func_lo2o_result + ;; + *) + libobj= + obj="$output" + ;; + esac + + # Delete the old objects. + $opt_dry_run || $RM $obj $libobj + + # Objects from convenience libraries. This assumes + # single-version convenience libraries. Whenever we create + # different ones for PIC/non-PIC, this we'll have to duplicate + # the extraction. + reload_conv_objs= + gentop= + # reload_cmds runs $LD directly, so let us get rid of + # -Wl from whole_archive_flag_spec and hope we can get by with + # turning comma into space.. + wl= + + if test -n "$convenience"; then + if test -n "$whole_archive_flag_spec"; then + eval tmp_whole_archive_flags=\"$whole_archive_flag_spec\" + reload_conv_objs=$reload_objs\ `$ECHO "$tmp_whole_archive_flags" | $SED 's|,| |g'` + else + gentop="$output_objdir/${obj}x" + func_append generated " $gentop" + + func_extract_archives $gentop $convenience + reload_conv_objs="$reload_objs $func_extract_archives_result" + fi + fi + + # If we're not building shared, we need to use non_pic_objs + test "$build_libtool_libs" != yes && libobjs="$non_pic_objects" + + # Create the old-style object. + reload_objs="$objs$old_deplibs "`$ECHO "$libobjs" | $SP2NL | $SED "/\.${libext}$/d; /\.lib$/d; $lo2o" | $NL2SP`" $reload_conv_objs" ### testsuite: skip nested quoting test + + output="$obj" + func_execute_cmds "$reload_cmds" 'exit $?' + + # Exit if we aren't doing a library object file. + if test -z "$libobj"; then + if test -n "$gentop"; then + func_show_eval '${RM}r "$gentop"' + fi + + exit $EXIT_SUCCESS + fi + + if test "$build_libtool_libs" != yes; then + if test -n "$gentop"; then + func_show_eval '${RM}r "$gentop"' + fi + + # Create an invalid libtool object if no PIC, so that we don't + # accidentally link it into a program. + # $show "echo timestamp > $libobj" + # $opt_dry_run || eval "echo timestamp > $libobj" || exit $? + exit $EXIT_SUCCESS + fi + + if test -n "$pic_flag" || test "$pic_mode" != default; then + # Only do commands if we really have different PIC objects. + reload_objs="$libobjs $reload_conv_objs" + output="$libobj" + func_execute_cmds "$reload_cmds" 'exit $?' + fi + + if test -n "$gentop"; then + func_show_eval '${RM}r "$gentop"' + fi + + exit $EXIT_SUCCESS + ;; + + prog) + case $host in + *cygwin*) func_stripname '' '.exe' "$output" + output=$func_stripname_result.exe;; + esac + test -n "$vinfo" && \ + func_warning "\`-version-info' is ignored for programs" + + test -n "$release" && \ + func_warning "\`-release' is ignored for programs" + + test "$preload" = yes \ + && test "$dlopen_support" = unknown \ + && test "$dlopen_self" = unknown \ + && test "$dlopen_self_static" = unknown && \ + func_warning "\`LT_INIT([dlopen])' not used. Assuming no dlopen support." + + case $host in + *-*-rhapsody* | *-*-darwin1.[012]) + # On Rhapsody replace the C library is the System framework + compile_deplibs=`$ECHO " $compile_deplibs" | $SED 's/ -lc / System.ltframework /'` + finalize_deplibs=`$ECHO " $finalize_deplibs" | $SED 's/ -lc / System.ltframework /'` + ;; + esac + + case $host in + *-*-darwin*) + # Don't allow lazy linking, it breaks C++ global constructors + # But is supposedly fixed on 10.4 or later (yay!). + if test "$tagname" = CXX ; then + case ${MACOSX_DEPLOYMENT_TARGET-10.0} in + 10.[0123]) + func_append compile_command " ${wl}-bind_at_load" + func_append finalize_command " ${wl}-bind_at_load" + ;; + esac + fi + # Time to change all our "foo.ltframework" stuff back to "-framework foo" + compile_deplibs=`$ECHO " $compile_deplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` + finalize_deplibs=`$ECHO " $finalize_deplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` + ;; + esac + + + # move library search paths that coincide with paths to not yet + # installed libraries to the beginning of the library search list + new_libs= + for path in $notinst_path; do + case " $new_libs " in + *" -L$path/$objdir "*) ;; + *) + case " $compile_deplibs " in + *" -L$path/$objdir "*) + func_append new_libs " -L$path/$objdir" ;; + esac + ;; + esac + done + for deplib in $compile_deplibs; do + case $deplib in + -L*) + case " $new_libs " in + *" $deplib "*) ;; + *) func_append new_libs " $deplib" ;; + esac + ;; + *) func_append new_libs " $deplib" ;; + esac + done + compile_deplibs="$new_libs" + + + func_append compile_command " $compile_deplibs" + func_append finalize_command " $finalize_deplibs" + + if test -n "$rpath$xrpath"; then + # If the user specified any rpath flags, then add them. + for libdir in $rpath $xrpath; do + # This is the magic to use -rpath. + case "$finalize_rpath " in + *" $libdir "*) ;; + *) func_append finalize_rpath " $libdir" ;; + esac + done + fi + + # Now hardcode the library paths + rpath= + hardcode_libdirs= + for libdir in $compile_rpath $finalize_rpath; do + if test -n "$hardcode_libdir_flag_spec"; then + if test -n "$hardcode_libdir_separator"; then + if test -z "$hardcode_libdirs"; then + hardcode_libdirs="$libdir" + else + # Just accumulate the unique libdirs. + case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in + *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) + ;; + *) + func_append hardcode_libdirs "$hardcode_libdir_separator$libdir" + ;; + esac + fi + else + eval flag=\"$hardcode_libdir_flag_spec\" + func_append rpath " $flag" + fi + elif test -n "$runpath_var"; then + case "$perm_rpath " in + *" $libdir "*) ;; + *) func_append perm_rpath " $libdir" ;; + esac + fi + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*) + testbindir=`${ECHO} "$libdir" | ${SED} -e 's*/lib$*/bin*'` + case :$dllsearchpath: in + *":$libdir:"*) ;; + ::) dllsearchpath=$libdir;; + *) func_append dllsearchpath ":$libdir";; + esac + case :$dllsearchpath: in + *":$testbindir:"*) ;; + ::) dllsearchpath=$testbindir;; + *) func_append dllsearchpath ":$testbindir";; + esac + ;; + esac + done + # Substitute the hardcoded libdirs into the rpath. + if test -n "$hardcode_libdir_separator" && + test -n "$hardcode_libdirs"; then + libdir="$hardcode_libdirs" + eval rpath=\" $hardcode_libdir_flag_spec\" + fi + compile_rpath="$rpath" + + rpath= + hardcode_libdirs= + for libdir in $finalize_rpath; do + if test -n "$hardcode_libdir_flag_spec"; then + if test -n "$hardcode_libdir_separator"; then + if test -z "$hardcode_libdirs"; then + hardcode_libdirs="$libdir" + else + # Just accumulate the unique libdirs. + case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in + *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) + ;; + *) + func_append hardcode_libdirs "$hardcode_libdir_separator$libdir" + ;; + esac + fi + else + eval flag=\"$hardcode_libdir_flag_spec\" + func_append rpath " $flag" + fi + elif test -n "$runpath_var"; then + case "$finalize_perm_rpath " in + *" $libdir "*) ;; + *) func_append finalize_perm_rpath " $libdir" ;; + esac + fi + done + # Substitute the hardcoded libdirs into the rpath. + if test -n "$hardcode_libdir_separator" && + test -n "$hardcode_libdirs"; then + libdir="$hardcode_libdirs" + eval rpath=\" $hardcode_libdir_flag_spec\" + fi + finalize_rpath="$rpath" + + if test -n "$libobjs" && test "$build_old_libs" = yes; then + # Transform all the library objects into standard objects. + compile_command=`$ECHO "$compile_command" | $SP2NL | $SED "$lo2o" | $NL2SP` + finalize_command=`$ECHO "$finalize_command" | $SP2NL | $SED "$lo2o" | $NL2SP` + fi + + func_generate_dlsyms "$outputname" "@PROGRAM@" "no" + + # template prelinking step + if test -n "$prelink_cmds"; then + func_execute_cmds "$prelink_cmds" 'exit $?' + fi + + wrappers_required=yes + case $host in + *cegcc* | *mingw32ce*) + # Disable wrappers for cegcc and mingw32ce hosts, we are cross compiling anyway. + wrappers_required=no + ;; + *cygwin* | *mingw* ) + if test "$build_libtool_libs" != yes; then + wrappers_required=no + fi + ;; + *) + if test "$need_relink" = no || test "$build_libtool_libs" != yes; then + wrappers_required=no + fi + ;; + esac + if test "$wrappers_required" = no; then + # Replace the output file specification. + compile_command=`$ECHO "$compile_command" | $SED 's%@OUTPUT@%'"$output"'%g'` + link_command="$compile_command$compile_rpath" + + # We have no uninstalled library dependencies, so finalize right now. + exit_status=0 + func_show_eval "$link_command" 'exit_status=$?' + + if test -n "$postlink_cmds"; then + func_to_tool_file "$output" + postlink_cmds=`func_echo_all "$postlink_cmds" | $SED -e 's%@OUTPUT@%'"$output"'%g' -e 's%@TOOL_OUTPUT@%'"$func_to_tool_file_result"'%g'` + func_execute_cmds "$postlink_cmds" 'exit $?' + fi + + # Delete the generated files. + if test -f "$output_objdir/${outputname}S.${objext}"; then + func_show_eval '$RM "$output_objdir/${outputname}S.${objext}"' + fi + + exit $exit_status + fi + + if test -n "$compile_shlibpath$finalize_shlibpath"; then + compile_command="$shlibpath_var=\"$compile_shlibpath$finalize_shlibpath\$$shlibpath_var\" $compile_command" + fi + if test -n "$finalize_shlibpath"; then + finalize_command="$shlibpath_var=\"$finalize_shlibpath\$$shlibpath_var\" $finalize_command" + fi + + compile_var= + finalize_var= + if test -n "$runpath_var"; then + if test -n "$perm_rpath"; then + # We should set the runpath_var. + rpath= + for dir in $perm_rpath; do + func_append rpath "$dir:" + done + compile_var="$runpath_var=\"$rpath\$$runpath_var\" " + fi + if test -n "$finalize_perm_rpath"; then + # We should set the runpath_var. + rpath= + for dir in $finalize_perm_rpath; do + func_append rpath "$dir:" + done + finalize_var="$runpath_var=\"$rpath\$$runpath_var\" " + fi + fi + + if test "$no_install" = yes; then + # We don't need to create a wrapper script. + link_command="$compile_var$compile_command$compile_rpath" + # Replace the output file specification. + link_command=`$ECHO "$link_command" | $SED 's%@OUTPUT@%'"$output"'%g'` + # Delete the old output file. + $opt_dry_run || $RM $output + # Link the executable and exit + func_show_eval "$link_command" 'exit $?' + + if test -n "$postlink_cmds"; then + func_to_tool_file "$output" + postlink_cmds=`func_echo_all "$postlink_cmds" | $SED -e 's%@OUTPUT@%'"$output"'%g' -e 's%@TOOL_OUTPUT@%'"$func_to_tool_file_result"'%g'` + func_execute_cmds "$postlink_cmds" 'exit $?' + fi + + exit $EXIT_SUCCESS + fi + + if test "$hardcode_action" = relink; then + # Fast installation is not supported + link_command="$compile_var$compile_command$compile_rpath" + relink_command="$finalize_var$finalize_command$finalize_rpath" + + func_warning "this platform does not like uninstalled shared libraries" + func_warning "\`$output' will be relinked during installation" + else + if test "$fast_install" != no; then + link_command="$finalize_var$compile_command$finalize_rpath" + if test "$fast_install" = yes; then + relink_command=`$ECHO "$compile_var$compile_command$compile_rpath" | $SED 's%@OUTPUT@%\$progdir/\$file%g'` + else + # fast_install is set to needless + relink_command= + fi + else + link_command="$compile_var$compile_command$compile_rpath" + relink_command="$finalize_var$finalize_command$finalize_rpath" + fi + fi + + # Replace the output file specification. + link_command=`$ECHO "$link_command" | $SED 's%@OUTPUT@%'"$output_objdir/$outputname"'%g'` + + # Delete the old output files. + $opt_dry_run || $RM $output $output_objdir/$outputname $output_objdir/lt-$outputname + + func_show_eval "$link_command" 'exit $?' + + if test -n "$postlink_cmds"; then + func_to_tool_file "$output_objdir/$outputname" + postlink_cmds=`func_echo_all "$postlink_cmds" | $SED -e 's%@OUTPUT@%'"$output_objdir/$outputname"'%g' -e 's%@TOOL_OUTPUT@%'"$func_to_tool_file_result"'%g'` + func_execute_cmds "$postlink_cmds" 'exit $?' + fi + + # Now create the wrapper script. + func_verbose "creating $output" + + # Quote the relink command for shipping. + if test -n "$relink_command"; then + # Preserve any variables that may affect compiler behavior + for var in $variables_saved_for_relink; do + if eval test -z \"\${$var+set}\"; then + relink_command="{ test -z \"\${$var+set}\" || $lt_unset $var || { $var=; export $var; }; }; $relink_command" + elif eval var_value=\$$var; test -z "$var_value"; then + relink_command="$var=; export $var; $relink_command" + else + func_quote_for_eval "$var_value" + relink_command="$var=$func_quote_for_eval_result; export $var; $relink_command" + fi + done + relink_command="(cd `pwd`; $relink_command)" + relink_command=`$ECHO "$relink_command" | $SED "$sed_quote_subst"` + fi + + # Only actually do things if not in dry run mode. + $opt_dry_run || { + # win32 will think the script is a binary if it has + # a .exe suffix, so we strip it off here. + case $output in + *.exe) func_stripname '' '.exe' "$output" + output=$func_stripname_result ;; + esac + # test for cygwin because mv fails w/o .exe extensions + case $host in + *cygwin*) + exeext=.exe + func_stripname '' '.exe' "$outputname" + outputname=$func_stripname_result ;; + *) exeext= ;; + esac + case $host in + *cygwin* | *mingw* ) + func_dirname_and_basename "$output" "" "." + output_name=$func_basename_result + output_path=$func_dirname_result + cwrappersource="$output_path/$objdir/lt-$output_name.c" + cwrapper="$output_path/$output_name.exe" + $RM $cwrappersource $cwrapper + trap "$RM $cwrappersource $cwrapper; exit $EXIT_FAILURE" 1 2 15 + + func_emit_cwrapperexe_src > $cwrappersource + + # The wrapper executable is built using the $host compiler, + # because it contains $host paths and files. If cross- + # compiling, it, like the target executable, must be + # executed on the $host or under an emulation environment. + $opt_dry_run || { + $LTCC $LTCFLAGS -o $cwrapper $cwrappersource + $STRIP $cwrapper + } + + # Now, create the wrapper script for func_source use: + func_ltwrapper_scriptname $cwrapper + $RM $func_ltwrapper_scriptname_result + trap "$RM $func_ltwrapper_scriptname_result; exit $EXIT_FAILURE" 1 2 15 + $opt_dry_run || { + # note: this script will not be executed, so do not chmod. + if test "x$build" = "x$host" ; then + $cwrapper --lt-dump-script > $func_ltwrapper_scriptname_result + else + func_emit_wrapper no > $func_ltwrapper_scriptname_result + fi + } + ;; + * ) + $RM $output + trap "$RM $output; exit $EXIT_FAILURE" 1 2 15 + + func_emit_wrapper no > $output + chmod +x $output + ;; + esac + } + exit $EXIT_SUCCESS + ;; + esac + + # See if we need to build an old-fashioned archive. + for oldlib in $oldlibs; do + + if test "$build_libtool_libs" = convenience; then + oldobjs="$libobjs_save $symfileobj" + addlibs="$convenience" + build_libtool_libs=no + else + if test "$build_libtool_libs" = module; then + oldobjs="$libobjs_save" + build_libtool_libs=no + else + oldobjs="$old_deplibs $non_pic_objects" + if test "$preload" = yes && test -f "$symfileobj"; then + func_append oldobjs " $symfileobj" + fi + fi + addlibs="$old_convenience" + fi + + if test -n "$addlibs"; then + gentop="$output_objdir/${outputname}x" + func_append generated " $gentop" + + func_extract_archives $gentop $addlibs + func_append oldobjs " $func_extract_archives_result" + fi + + # Do each command in the archive commands. + if test -n "$old_archive_from_new_cmds" && test "$build_libtool_libs" = yes; then + cmds=$old_archive_from_new_cmds + else + + # Add any objects from preloaded convenience libraries + if test -n "$dlprefiles"; then + gentop="$output_objdir/${outputname}x" + func_append generated " $gentop" + + func_extract_archives $gentop $dlprefiles + func_append oldobjs " $func_extract_archives_result" + fi + + # POSIX demands no paths to be encoded in archives. We have + # to avoid creating archives with duplicate basenames if we + # might have to extract them afterwards, e.g., when creating a + # static archive out of a convenience library, or when linking + # the entirety of a libtool archive into another (currently + # not supported by libtool). + if (for obj in $oldobjs + do + func_basename "$obj" + $ECHO "$func_basename_result" + done | sort | sort -uc >/dev/null 2>&1); then + : + else + echo "copying selected object files to avoid basename conflicts..." + gentop="$output_objdir/${outputname}x" + func_append generated " $gentop" + func_mkdir_p "$gentop" + save_oldobjs=$oldobjs + oldobjs= + counter=1 + for obj in $save_oldobjs + do + func_basename "$obj" + objbase="$func_basename_result" + case " $oldobjs " in + " ") oldobjs=$obj ;; + *[\ /]"$objbase "*) + while :; do + # Make sure we don't pick an alternate name that also + # overlaps. + newobj=lt$counter-$objbase + func_arith $counter + 1 + counter=$func_arith_result + case " $oldobjs " in + *[\ /]"$newobj "*) ;; + *) if test ! -f "$gentop/$newobj"; then break; fi ;; + esac + done + func_show_eval "ln $obj $gentop/$newobj || cp $obj $gentop/$newobj" + func_append oldobjs " $gentop/$newobj" + ;; + *) func_append oldobjs " $obj" ;; + esac + done + fi + func_to_tool_file "$oldlib" func_convert_file_msys_to_w32 + tool_oldlib=$func_to_tool_file_result + eval cmds=\"$old_archive_cmds\" + + func_len " $cmds" + len=$func_len_result + if test "$len" -lt "$max_cmd_len" || test "$max_cmd_len" -le -1; then + cmds=$old_archive_cmds + elif test -n "$archiver_list_spec"; then + func_verbose "using command file archive linking..." + for obj in $oldobjs + do + func_to_tool_file "$obj" + $ECHO "$func_to_tool_file_result" + done > $output_objdir/$libname.libcmd + func_to_tool_file "$output_objdir/$libname.libcmd" + oldobjs=" $archiver_list_spec$func_to_tool_file_result" + cmds=$old_archive_cmds + else + # the command line is too long to link in one step, link in parts + func_verbose "using piecewise archive linking..." + save_RANLIB=$RANLIB + RANLIB=: + objlist= + concat_cmds= + save_oldobjs=$oldobjs + oldobjs= + # Is there a better way of finding the last object in the list? + for obj in $save_oldobjs + do + last_oldobj=$obj + done + eval test_cmds=\"$old_archive_cmds\" + func_len " $test_cmds" + len0=$func_len_result + len=$len0 + for obj in $save_oldobjs + do + func_len " $obj" + func_arith $len + $func_len_result + len=$func_arith_result + func_append objlist " $obj" + if test "$len" -lt "$max_cmd_len"; then + : + else + # the above command should be used before it gets too long + oldobjs=$objlist + if test "$obj" = "$last_oldobj" ; then + RANLIB=$save_RANLIB + fi + test -z "$concat_cmds" || concat_cmds=$concat_cmds~ + eval concat_cmds=\"\${concat_cmds}$old_archive_cmds\" + objlist= + len=$len0 + fi + done + RANLIB=$save_RANLIB + oldobjs=$objlist + if test "X$oldobjs" = "X" ; then + eval cmds=\"\$concat_cmds\" + else + eval cmds=\"\$concat_cmds~\$old_archive_cmds\" + fi + fi + fi + func_execute_cmds "$cmds" 'exit $?' + done + + test -n "$generated" && \ + func_show_eval "${RM}r$generated" + + # Now create the libtool archive. + case $output in + *.la) + old_library= + test "$build_old_libs" = yes && old_library="$libname.$libext" + func_verbose "creating $output" + + # Preserve any variables that may affect compiler behavior + for var in $variables_saved_for_relink; do + if eval test -z \"\${$var+set}\"; then + relink_command="{ test -z \"\${$var+set}\" || $lt_unset $var || { $var=; export $var; }; }; $relink_command" + elif eval var_value=\$$var; test -z "$var_value"; then + relink_command="$var=; export $var; $relink_command" + else + func_quote_for_eval "$var_value" + relink_command="$var=$func_quote_for_eval_result; export $var; $relink_command" + fi + done + # Quote the link command for shipping. + relink_command="(cd `pwd`; $SHELL $progpath $preserve_args --mode=relink $libtool_args @inst_prefix_dir@)" + relink_command=`$ECHO "$relink_command" | $SED "$sed_quote_subst"` + if test "$hardcode_automatic" = yes ; then + relink_command= + fi + + # Only create the output if not a dry run. + $opt_dry_run || { + for installed in no yes; do + if test "$installed" = yes; then + if test -z "$install_libdir"; then + break + fi + output="$output_objdir/$outputname"i + # Replace all uninstalled libtool libraries with the installed ones + newdependency_libs= + for deplib in $dependency_libs; do + case $deplib in + *.la) + func_basename "$deplib" + name="$func_basename_result" + func_resolve_sysroot "$deplib" + eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $func_resolve_sysroot_result` + test -z "$libdir" && \ + func_fatal_error "\`$deplib' is not a valid libtool archive" + func_append newdependency_libs " ${lt_sysroot:+=}$libdir/$name" + ;; + -L*) + func_stripname -L '' "$deplib" + func_replace_sysroot "$func_stripname_result" + func_append newdependency_libs " -L$func_replace_sysroot_result" + ;; + -R*) + func_stripname -R '' "$deplib" + func_replace_sysroot "$func_stripname_result" + func_append newdependency_libs " -R$func_replace_sysroot_result" + ;; + *) func_append newdependency_libs " $deplib" ;; + esac + done + dependency_libs="$newdependency_libs" + newdlfiles= + + for lib in $dlfiles; do + case $lib in + *.la) + func_basename "$lib" + name="$func_basename_result" + eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $lib` + test -z "$libdir" && \ + func_fatal_error "\`$lib' is not a valid libtool archive" + func_append newdlfiles " ${lt_sysroot:+=}$libdir/$name" + ;; + *) func_append newdlfiles " $lib" ;; + esac + done + dlfiles="$newdlfiles" + newdlprefiles= + for lib in $dlprefiles; do + case $lib in + *.la) + # Only pass preopened files to the pseudo-archive (for + # eventual linking with the app. that links it) if we + # didn't already link the preopened objects directly into + # the library: + func_basename "$lib" + name="$func_basename_result" + eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $lib` + test -z "$libdir" && \ + func_fatal_error "\`$lib' is not a valid libtool archive" + func_append newdlprefiles " ${lt_sysroot:+=}$libdir/$name" + ;; + esac + done + dlprefiles="$newdlprefiles" + else + newdlfiles= + for lib in $dlfiles; do + case $lib in + [\\/]* | [A-Za-z]:[\\/]*) abs="$lib" ;; + *) abs=`pwd`"/$lib" ;; + esac + func_append newdlfiles " $abs" + done + dlfiles="$newdlfiles" + newdlprefiles= + for lib in $dlprefiles; do + case $lib in + [\\/]* | [A-Za-z]:[\\/]*) abs="$lib" ;; + *) abs=`pwd`"/$lib" ;; + esac + func_append newdlprefiles " $abs" + done + dlprefiles="$newdlprefiles" + fi + $RM $output + # place dlname in correct position for cygwin + # In fact, it would be nice if we could use this code for all target + # systems that can't hard-code library paths into their executables + # and that have no shared library path variable independent of PATH, + # but it turns out we can't easily determine that from inspecting + # libtool variables, so we have to hard-code the OSs to which it + # applies here; at the moment, that means platforms that use the PE + # object format with DLL files. See the long comment at the top of + # tests/bindir.at for full details. + tdlname=$dlname + case $host,$output,$installed,$module,$dlname in + *cygwin*,*lai,yes,no,*.dll | *mingw*,*lai,yes,no,*.dll | *cegcc*,*lai,yes,no,*.dll) + # If a -bindir argument was supplied, place the dll there. + if test "x$bindir" != x ; + then + func_relative_path "$install_libdir" "$bindir" + tdlname=$func_relative_path_result$dlname + else + # Otherwise fall back on heuristic. + tdlname=../bin/$dlname + fi + ;; + esac + $ECHO > $output "\ +# $outputname - a libtool library file +# Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION +# +# Please DO NOT delete this file! +# It is necessary for linking the library. + +# The name that we can dlopen(3). +dlname='$tdlname' + +# Names of this library. +library_names='$library_names' + +# The name of the static archive. +old_library='$old_library' + +# Linker flags that can not go in dependency_libs. +inherited_linker_flags='$new_inherited_linker_flags' + +# Libraries that this one depends upon. +dependency_libs='$dependency_libs' + +# Names of additional weak libraries provided by this library +weak_library_names='$weak_libs' + +# Version information for $libname. +current=$current +age=$age +revision=$revision + +# Is this an already installed library? +installed=$installed + +# Should we warn about portability when linking against -modules? +shouldnotlink=$module + +# Files to dlopen/dlpreopen +dlopen='$dlfiles' +dlpreopen='$dlprefiles' + +# Directory that this library needs to be installed in: +libdir='$install_libdir'" + if test "$installed" = no && test "$need_relink" = yes; then + $ECHO >> $output "\ +relink_command=\"$relink_command\"" + fi + done + } + + # Do a symbolic link so that the libtool archive can be found in + # LD_LIBRARY_PATH before the program is installed. + func_show_eval '( cd "$output_objdir" && $RM "$outputname" && $LN_S "../$outputname" "$outputname" )' 'exit $?' + ;; + esac + exit $EXIT_SUCCESS +} + +{ test "$opt_mode" = link || test "$opt_mode" = relink; } && + func_mode_link ${1+"$@"} + + +# func_mode_uninstall arg... +func_mode_uninstall () +{ + $opt_debug + RM="$nonopt" + files= + rmforce= + exit_status=0 + + # This variable tells wrapper scripts just to set variables rather + # than running their programs. + libtool_install_magic="$magic" + + for arg + do + case $arg in + -f) func_append RM " $arg"; rmforce=yes ;; + -*) func_append RM " $arg" ;; + *) func_append files " $arg" ;; + esac + done + + test -z "$RM" && \ + func_fatal_help "you must specify an RM program" + + rmdirs= + + for file in $files; do + func_dirname "$file" "" "." + dir="$func_dirname_result" + if test "X$dir" = X.; then + odir="$objdir" + else + odir="$dir/$objdir" + fi + func_basename "$file" + name="$func_basename_result" + test "$opt_mode" = uninstall && odir="$dir" + + # Remember odir for removal later, being careful to avoid duplicates + if test "$opt_mode" = clean; then + case " $rmdirs " in + *" $odir "*) ;; + *) func_append rmdirs " $odir" ;; + esac + fi + + # Don't error if the file doesn't exist and rm -f was used. + if { test -L "$file"; } >/dev/null 2>&1 || + { test -h "$file"; } >/dev/null 2>&1 || + test -f "$file"; then + : + elif test -d "$file"; then + exit_status=1 + continue + elif test "$rmforce" = yes; then + continue + fi + + rmfiles="$file" + + case $name in + *.la) + # Possibly a libtool archive, so verify it. + if func_lalib_p "$file"; then + func_source $dir/$name + + # Delete the libtool libraries and symlinks. + for n in $library_names; do + func_append rmfiles " $odir/$n" + done + test -n "$old_library" && func_append rmfiles " $odir/$old_library" + + case "$opt_mode" in + clean) + case " $library_names " in + *" $dlname "*) ;; + *) test -n "$dlname" && func_append rmfiles " $odir/$dlname" ;; + esac + test -n "$libdir" && func_append rmfiles " $odir/$name $odir/${name}i" + ;; + uninstall) + if test -n "$library_names"; then + # Do each command in the postuninstall commands. + func_execute_cmds "$postuninstall_cmds" 'test "$rmforce" = yes || exit_status=1' + fi + + if test -n "$old_library"; then + # Do each command in the old_postuninstall commands. + func_execute_cmds "$old_postuninstall_cmds" 'test "$rmforce" = yes || exit_status=1' + fi + # FIXME: should reinstall the best remaining shared library. + ;; + esac + fi + ;; + + *.lo) + # Possibly a libtool object, so verify it. + if func_lalib_p "$file"; then + + # Read the .lo file + func_source $dir/$name + + # Add PIC object to the list of files to remove. + if test -n "$pic_object" && + test "$pic_object" != none; then + func_append rmfiles " $dir/$pic_object" + fi + + # Add non-PIC object to the list of files to remove. + if test -n "$non_pic_object" && + test "$non_pic_object" != none; then + func_append rmfiles " $dir/$non_pic_object" + fi + fi + ;; + + *) + if test "$opt_mode" = clean ; then + noexename=$name + case $file in + *.exe) + func_stripname '' '.exe' "$file" + file=$func_stripname_result + func_stripname '' '.exe' "$name" + noexename=$func_stripname_result + # $file with .exe has already been added to rmfiles, + # add $file without .exe + func_append rmfiles " $file" + ;; + esac + # Do a test to see if this is a libtool program. + if func_ltwrapper_p "$file"; then + if func_ltwrapper_executable_p "$file"; then + func_ltwrapper_scriptname "$file" + relink_command= + func_source $func_ltwrapper_scriptname_result + func_append rmfiles " $func_ltwrapper_scriptname_result" + else + relink_command= + func_source $dir/$noexename + fi + + # note $name still contains .exe if it was in $file originally + # as does the version of $file that was added into $rmfiles + func_append rmfiles " $odir/$name $odir/${name}S.${objext}" + if test "$fast_install" = yes && test -n "$relink_command"; then + func_append rmfiles " $odir/lt-$name" + fi + if test "X$noexename" != "X$name" ; then + func_append rmfiles " $odir/lt-${noexename}.c" + fi + fi + fi + ;; + esac + func_show_eval "$RM $rmfiles" 'exit_status=1' + done + + # Try to remove the ${objdir}s in the directories where we deleted files + for dir in $rmdirs; do + if test -d "$dir"; then + func_show_eval "rmdir $dir >/dev/null 2>&1" + fi + done + + exit $exit_status +} + +{ test "$opt_mode" = uninstall || test "$opt_mode" = clean; } && + func_mode_uninstall ${1+"$@"} + +test -z "$opt_mode" && { + help="$generic_help" + func_fatal_help "you must specify a MODE" +} + +test -z "$exec_cmd" && \ + func_fatal_help "invalid operation mode \`$opt_mode'" + +if test -n "$exec_cmd"; then + eval exec "$exec_cmd" + exit $EXIT_FAILURE +fi + +exit $exit_status + + +# The TAGs below are defined such that we never get into a situation +# in which we disable both kinds of libraries. Given conflicting +# choices, we go for a static library, that is the most portable, +# since we can't tell whether shared libraries were disabled because +# the user asked for that or because the platform doesn't support +# them. This is particularly important on AIX, because we don't +# support having both static and shared libraries enabled at the same +# time on that platform, so we default to a shared-only configuration. +# If a disable-shared tag is given, we'll fallback to a static-only +# configuration. But we'll never go from static-only to shared-only. + +# ### BEGIN LIBTOOL TAG CONFIG: disable-shared +build_libtool_libs=no +build_old_libs=yes +# ### END LIBTOOL TAG CONFIG: disable-shared + +# ### BEGIN LIBTOOL TAG CONFIG: disable-static +build_old_libs=`case $build_libtool_libs in yes) echo no;; *) echo yes;; esac` +# ### END LIBTOOL TAG CONFIG: disable-static + +# Local Variables: +# mode:shell-script +# sh-indentation:2 +# End: +# vi:sw=2 + diff --git a/web/server/h2o/libh2o/deps/yaml/config/missing b/web/server/h2o/libh2o/deps/yaml/config/missing new file mode 100755 index 00000000..86a8fc31 --- /dev/null +++ b/web/server/h2o/libh2o/deps/yaml/config/missing @@ -0,0 +1,331 @@ +#! /bin/sh +# Common stub for a few missing GNU programs while installing. + +scriptversion=2012-01-06.13; # UTC + +# Copyright (C) 1996, 1997, 1999, 2000, 2002, 2003, 2004, 2005, 2006, +# 2008, 2009, 2010, 2011, 2012 Free Software Foundation, Inc. +# Originally by Fran,cois Pinard , 1996. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +if test $# -eq 0; then + echo 1>&2 "Try \`$0 --help' for more information" + exit 1 +fi + +run=: +sed_output='s/.* --output[ =]\([^ ]*\).*/\1/p' +sed_minuso='s/.* -o \([^ ]*\).*/\1/p' + +# In the cases where this matters, `missing' is being run in the +# srcdir already. +if test -f configure.ac; then + configure_ac=configure.ac +else + configure_ac=configure.in +fi + +msg="missing on your system" + +case $1 in +--run) + # Try to run requested program, and just exit if it succeeds. + run= + shift + "$@" && exit 0 + # Exit code 63 means version mismatch. This often happens + # when the user try to use an ancient version of a tool on + # a file that requires a minimum version. In this case we + # we should proceed has if the program had been absent, or + # if --run hadn't been passed. + if test $? = 63; then + run=: + msg="probably too old" + fi + ;; + + -h|--h|--he|--hel|--help) + echo "\ +$0 [OPTION]... PROGRAM [ARGUMENT]... + +Handle \`PROGRAM [ARGUMENT]...' for when PROGRAM is missing, or return an +error status if there is no known handling for PROGRAM. + +Options: + -h, --help display this help and exit + -v, --version output version information and exit + --run try to run the given command, and emulate it if it fails + +Supported PROGRAM values: + aclocal touch file \`aclocal.m4' + autoconf touch file \`configure' + autoheader touch file \`config.h.in' + autom4te touch the output file, or create a stub one + automake touch all \`Makefile.in' files + bison create \`y.tab.[ch]', if possible, from existing .[ch] + flex create \`lex.yy.c', if possible, from existing .c + help2man touch the output file + lex create \`lex.yy.c', if possible, from existing .c + makeinfo touch the output file + yacc create \`y.tab.[ch]', if possible, from existing .[ch] + +Version suffixes to PROGRAM as well as the prefixes \`gnu-', \`gnu', and +\`g' are ignored when checking the name. + +Send bug reports to ." + exit $? + ;; + + -v|--v|--ve|--ver|--vers|--versi|--versio|--version) + echo "missing $scriptversion (GNU Automake)" + exit $? + ;; + + -*) + echo 1>&2 "$0: Unknown \`$1' option" + echo 1>&2 "Try \`$0 --help' for more information" + exit 1 + ;; + +esac + +# normalize program name to check for. +program=`echo "$1" | sed ' + s/^gnu-//; t + s/^gnu//; t + s/^g//; t'` + +# Now exit if we have it, but it failed. Also exit now if we +# don't have it and --version was passed (most likely to detect +# the program). This is about non-GNU programs, so use $1 not +# $program. +case $1 in + lex*|yacc*) + # Not GNU programs, they don't have --version. + ;; + + *) + if test -z "$run" && ($1 --version) > /dev/null 2>&1; then + # We have it, but it failed. + exit 1 + elif test "x$2" = "x--version" || test "x$2" = "x--help"; then + # Could not run --version or --help. This is probably someone + # running `$TOOL --version' or `$TOOL --help' to check whether + # $TOOL exists and not knowing $TOOL uses missing. + exit 1 + fi + ;; +esac + +# If it does not exist, or fails to run (possibly an outdated version), +# try to emulate it. +case $program in + aclocal*) + echo 1>&2 "\ +WARNING: \`$1' is $msg. You should only need it if + you modified \`acinclude.m4' or \`${configure_ac}'. You might want + to install the \`Automake' and \`Perl' packages. Grab them from + any GNU archive site." + touch aclocal.m4 + ;; + + autoconf*) + echo 1>&2 "\ +WARNING: \`$1' is $msg. You should only need it if + you modified \`${configure_ac}'. You might want to install the + \`Autoconf' and \`GNU m4' packages. Grab them from any GNU + archive site." + touch configure + ;; + + autoheader*) + echo 1>&2 "\ +WARNING: \`$1' is $msg. You should only need it if + you modified \`acconfig.h' or \`${configure_ac}'. You might want + to install the \`Autoconf' and \`GNU m4' packages. Grab them + from any GNU archive site." + files=`sed -n 's/^[ ]*A[CM]_CONFIG_HEADER(\([^)]*\)).*/\1/p' ${configure_ac}` + test -z "$files" && files="config.h" + touch_files= + for f in $files; do + case $f in + *:*) touch_files="$touch_files "`echo "$f" | + sed -e 's/^[^:]*://' -e 's/:.*//'`;; + *) touch_files="$touch_files $f.in";; + esac + done + touch $touch_files + ;; + + automake*) + echo 1>&2 "\ +WARNING: \`$1' is $msg. You should only need it if + you modified \`Makefile.am', \`acinclude.m4' or \`${configure_ac}'. + You might want to install the \`Automake' and \`Perl' packages. + Grab them from any GNU archive site." + find . -type f -name Makefile.am -print | + sed 's/\.am$/.in/' | + while read f; do touch "$f"; done + ;; + + autom4te*) + echo 1>&2 "\ +WARNING: \`$1' is needed, but is $msg. + You might have modified some files without having the + proper tools for further handling them. + You can get \`$1' as part of \`Autoconf' from any GNU + archive site." + + file=`echo "$*" | sed -n "$sed_output"` + test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"` + if test -f "$file"; then + touch $file + else + test -z "$file" || exec >$file + echo "#! /bin/sh" + echo "# Created by GNU Automake missing as a replacement of" + echo "# $ $@" + echo "exit 0" + chmod +x $file + exit 1 + fi + ;; + + bison*|yacc*) + echo 1>&2 "\ +WARNING: \`$1' $msg. You should only need it if + you modified a \`.y' file. You may need the \`Bison' package + in order for those modifications to take effect. You can get + \`Bison' from any GNU archive site." + rm -f y.tab.c y.tab.h + if test $# -ne 1; then + eval LASTARG=\${$#} + case $LASTARG in + *.y) + SRCFILE=`echo "$LASTARG" | sed 's/y$/c/'` + if test -f "$SRCFILE"; then + cp "$SRCFILE" y.tab.c + fi + SRCFILE=`echo "$LASTARG" | sed 's/y$/h/'` + if test -f "$SRCFILE"; then + cp "$SRCFILE" y.tab.h + fi + ;; + esac + fi + if test ! -f y.tab.h; then + echo >y.tab.h + fi + if test ! -f y.tab.c; then + echo 'main() { return 0; }' >y.tab.c + fi + ;; + + lex*|flex*) + echo 1>&2 "\ +WARNING: \`$1' is $msg. You should only need it if + you modified a \`.l' file. You may need the \`Flex' package + in order for those modifications to take effect. You can get + \`Flex' from any GNU archive site." + rm -f lex.yy.c + if test $# -ne 1; then + eval LASTARG=\${$#} + case $LASTARG in + *.l) + SRCFILE=`echo "$LASTARG" | sed 's/l$/c/'` + if test -f "$SRCFILE"; then + cp "$SRCFILE" lex.yy.c + fi + ;; + esac + fi + if test ! -f lex.yy.c; then + echo 'main() { return 0; }' >lex.yy.c + fi + ;; + + help2man*) + echo 1>&2 "\ +WARNING: \`$1' is $msg. You should only need it if + you modified a dependency of a manual page. You may need the + \`Help2man' package in order for those modifications to take + effect. You can get \`Help2man' from any GNU archive site." + + file=`echo "$*" | sed -n "$sed_output"` + test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"` + if test -f "$file"; then + touch $file + else + test -z "$file" || exec >$file + echo ".ab help2man is required to generate this page" + exit $? + fi + ;; + + makeinfo*) + echo 1>&2 "\ +WARNING: \`$1' is $msg. You should only need it if + you modified a \`.texi' or \`.texinfo' file, or any other file + indirectly affecting the aspect of the manual. The spurious + call might also be the consequence of using a buggy \`make' (AIX, + DU, IRIX). You might want to install the \`Texinfo' package or + the \`GNU make' package. Grab either from any GNU archive site." + # The file to touch is that specified with -o ... + file=`echo "$*" | sed -n "$sed_output"` + test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"` + if test -z "$file"; then + # ... or it is the one specified with @setfilename ... + infile=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'` + file=`sed -n ' + /^@setfilename/{ + s/.* \([^ ]*\) *$/\1/ + p + q + }' $infile` + # ... or it is derived from the source name (dir/f.texi becomes f.info) + test -z "$file" && file=`echo "$infile" | sed 's,.*/,,;s,.[^.]*$,,'`.info + fi + # If the file does not exist, the user really needs makeinfo; + # let's fail without touching anything. + test -f $file || exit 1 + touch $file + ;; + + *) + echo 1>&2 "\ +WARNING: \`$1' is needed, and is $msg. + You might have modified some files without having the + proper tools for further handling them. Check the \`README' file, + it often tells you about the needed prerequisites for installing + this package. You may also peek at any GNU archive site, in case + some other package would contain this missing \`$1' program." + exit 1 + ;; +esac + +exit 0 + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-time-zone: "UTC" +# time-stamp-end: "; # UTC" +# End: diff --git a/web/server/h2o/libh2o/deps/yaml/configure b/web/server/h2o/libh2o/deps/yaml/configure new file mode 100755 index 00000000..46126520 --- /dev/null +++ b/web/server/h2o/libh2o/deps/yaml/configure @@ -0,0 +1,14029 @@ +#! /bin/sh +# Guess values for system-dependent variables and create Makefiles. +# Generated by GNU Autoconf 2.68 for yaml 0.1.6. +# +# Report bugs to . +# +# +# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, +# 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free Software +# Foundation, Inc. +# +# +# This configure script is free software; the Free Software Foundation +# gives unlimited permission to copy, distribute and modify it. +## -------------------- ## +## M4sh Initialization. ## +## -------------------- ## + +# Be more Bourne compatible +DUALCASE=1; export DUALCASE # for MKS sh +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : + emulate sh + NULLCMD=: + # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in #( + *posix*) : + set -o posix ;; #( + *) : + ;; +esac +fi + + +as_nl=' +' +export as_nl +# Printing a long string crashes Solaris 7 /usr/bin/printf. +as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo +# Prefer a ksh shell builtin over an external printf program on Solaris, +# but without wasting forks for bash or zsh. +if test -z "$BASH_VERSION$ZSH_VERSION" \ + && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='print -r --' + as_echo_n='print -rn --' +elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='printf %s\n' + as_echo_n='printf %s' +else + if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then + as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' + as_echo_n='/usr/ucb/echo -n' + else + as_echo_body='eval expr "X$1" : "X\\(.*\\)"' + as_echo_n_body='eval + arg=$1; + case $arg in #( + *"$as_nl"*) + expr "X$arg" : "X\\(.*\\)$as_nl"; + arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; + esac; + expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" + ' + export as_echo_n_body + as_echo_n='sh -c $as_echo_n_body as_echo' + fi + export as_echo_body + as_echo='sh -c $as_echo_body as_echo' +fi + +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + PATH_SEPARATOR=: + (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { + (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || + PATH_SEPARATOR=';' + } +fi + + +# IFS +# We need space, tab and new line, in precisely that order. Quoting is +# there to prevent editors from complaining about space-tab. +# (If _AS_PATH_WALK were called with IFS unset, it would disable word +# splitting by setting IFS to empty value.) +IFS=" "" $as_nl" + +# Find who we are. Look in the path if we contain no directory separator. +as_myself= +case $0 in #(( + *[\\/]* ) as_myself=$0 ;; + *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break + done +IFS=$as_save_IFS + + ;; +esac +# We did not find ourselves, most probably we were run as `sh COMMAND' +# in which case we are not to be found in the path. +if test "x$as_myself" = x; then + as_myself=$0 +fi +if test ! -f "$as_myself"; then + $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 + exit 1 +fi + +# Unset variables that we do not need and which cause bugs (e.g. in +# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" +# suppresses any "Segmentation fault" message there. '((' could +# trigger a bug in pdksh 5.2.14. +for as_var in BASH_ENV ENV MAIL MAILPATH +do eval test x\${$as_var+set} = xset \ + && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : +done +PS1='$ ' +PS2='> ' +PS4='+ ' + +# NLS nuisances. +LC_ALL=C +export LC_ALL +LANGUAGE=C +export LANGUAGE + +# CDPATH. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + +if test "x$CONFIG_SHELL" = x; then + as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then : + emulate sh + NULLCMD=: + # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which + # is contrary to our usage. Disable this feature. + alias -g '\${1+\"\$@\"}'='\"\$@\"' + setopt NO_GLOB_SUBST +else + case \`(set -o) 2>/dev/null\` in #( + *posix*) : + set -o posix ;; #( + *) : + ;; +esac +fi +" + as_required="as_fn_return () { (exit \$1); } +as_fn_success () { as_fn_return 0; } +as_fn_failure () { as_fn_return 1; } +as_fn_ret_success () { return 0; } +as_fn_ret_failure () { return 1; } + +exitcode=0 +as_fn_success || { exitcode=1; echo as_fn_success failed.; } +as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; } +as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; } +as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; } +if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then : + +else + exitcode=1; echo positional parameters were not saved. +fi +test x\$exitcode = x0 || exit 1" + as_suggested=" as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO + as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO + eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" && + test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1 + + test -n \"\${ZSH_VERSION+set}\${BASH_VERSION+set}\" || ( + ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' + ECHO=\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO + ECHO=\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO + PATH=/empty FPATH=/empty; export PATH FPATH + test \"X\`printf %s \$ECHO\`\" = \"X\$ECHO\" \\ + || test \"X\`print -r -- \$ECHO\`\" = \"X\$ECHO\" ) || exit 1 +test \$(( 1 + 1 )) = 2 || exit 1" + if (eval "$as_required") 2>/dev/null; then : + as_have_required=yes +else + as_have_required=no +fi + if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null; then : + +else + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +as_found=false +for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + as_found=: + case $as_dir in #( + /*) + for as_base in sh bash ksh sh5; do + # Try only shells that exist, to save several forks. + as_shell=$as_dir/$as_base + if { test -f "$as_shell" || test -f "$as_shell.exe"; } && + { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$as_shell"; } 2>/dev/null; then : + CONFIG_SHELL=$as_shell as_have_required=yes + if { $as_echo "$as_bourne_compatible""$as_suggested" | as_run=a "$as_shell"; } 2>/dev/null; then : + break 2 +fi +fi + done;; + esac + as_found=false +done +$as_found || { if { test -f "$SHELL" || test -f "$SHELL.exe"; } && + { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$SHELL"; } 2>/dev/null; then : + CONFIG_SHELL=$SHELL as_have_required=yes +fi; } +IFS=$as_save_IFS + + + if test "x$CONFIG_SHELL" != x; then : + # We cannot yet assume a decent shell, so we have to provide a + # neutralization value for shells without unset; and this also + # works around shells that cannot unset nonexistent variables. + # Preserve -v and -x to the replacement shell. + BASH_ENV=/dev/null + ENV=/dev/null + (unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV + export CONFIG_SHELL + case $- in # (((( + *v*x* | *x*v* ) as_opts=-vx ;; + *v* ) as_opts=-v ;; + *x* ) as_opts=-x ;; + * ) as_opts= ;; + esac + exec "$CONFIG_SHELL" $as_opts "$as_myself" ${1+"$@"} +fi + + if test x$as_have_required = xno; then : + $as_echo "$0: This script requires a shell more modern than all" + $as_echo "$0: the shells that I found on your system." + if test x${ZSH_VERSION+set} = xset ; then + $as_echo "$0: In particular, zsh $ZSH_VERSION has bugs and should" + $as_echo "$0: be upgraded to zsh 4.3.4 or later." + else + $as_echo "$0: Please tell bug-autoconf@gnu.org and http://pyyaml.org/newticket?component=libyaml about +$0: your system, including any error possibly output before +$0: this message. Then install a modern shell, or manually +$0: run the script under such a shell if you do have one." + fi + exit 1 +fi +fi +fi +SHELL=${CONFIG_SHELL-/bin/sh} +export SHELL +# Unset more variables known to interfere with behavior of common tools. +CLICOLOR_FORCE= GREP_OPTIONS= +unset CLICOLOR_FORCE GREP_OPTIONS + +## --------------------- ## +## M4sh Shell Functions. ## +## --------------------- ## +# as_fn_unset VAR +# --------------- +# Portably unset VAR. +as_fn_unset () +{ + { eval $1=; unset $1;} +} +as_unset=as_fn_unset + +# as_fn_set_status STATUS +# ----------------------- +# Set $? to STATUS, without forking. +as_fn_set_status () +{ + return $1 +} # as_fn_set_status + +# as_fn_exit STATUS +# ----------------- +# Exit the shell with STATUS, even in a "trap 0" or "set -e" context. +as_fn_exit () +{ + set +e + as_fn_set_status $1 + exit $1 +} # as_fn_exit + +# as_fn_mkdir_p +# ------------- +# Create "$as_dir" as a directory, including parents if necessary. +as_fn_mkdir_p () +{ + + case $as_dir in #( + -*) as_dir=./$as_dir;; + esac + test -d "$as_dir" || eval $as_mkdir_p || { + as_dirs= + while :; do + case $as_dir in #( + *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( + *) as_qdir=$as_dir;; + esac + as_dirs="'$as_qdir' $as_dirs" + as_dir=`$as_dirname -- "$as_dir" || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + test -d "$as_dir" && break + done + test -z "$as_dirs" || eval "mkdir $as_dirs" + } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" + + +} # as_fn_mkdir_p +# as_fn_append VAR VALUE +# ---------------------- +# Append the text in VALUE to the end of the definition contained in VAR. Take +# advantage of any shell optimizations that allow amortized linear growth over +# repeated appends, instead of the typical quadratic growth present in naive +# implementations. +if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : + eval 'as_fn_append () + { + eval $1+=\$2 + }' +else + as_fn_append () + { + eval $1=\$$1\$2 + } +fi # as_fn_append + +# as_fn_arith ARG... +# ------------------ +# Perform arithmetic evaluation on the ARGs, and store the result in the +# global $as_val. Take advantage of shells that can avoid forks. The arguments +# must be portable across $(()) and expr. +if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : + eval 'as_fn_arith () + { + as_val=$(( $* )) + }' +else + as_fn_arith () + { + as_val=`expr "$@" || test $? -eq 1` + } +fi # as_fn_arith + + +# as_fn_error STATUS ERROR [LINENO LOG_FD] +# ---------------------------------------- +# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are +# provided, also output the error to LOG_FD, referencing LINENO. Then exit the +# script with STATUS, using 1 if that was 0. +as_fn_error () +{ + as_status=$1; test $as_status -eq 0 && as_status=1 + if test "$4"; then + as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 + fi + $as_echo "$as_me: error: $2" >&2 + as_fn_exit $as_status +} # as_fn_error + +if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; then + as_expr=expr +else + as_expr=false +fi + +if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then + as_basename=basename +else + as_basename=false +fi + +if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then + as_dirname=dirname +else + as_dirname=false +fi + +as_me=`$as_basename -- "$0" || +$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ + s//\1/ + q + } + /^X\/\(\/\/\)$/{ + s//\1/ + q + } + /^X\/\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + +# Avoid depending upon Character Ranges. +as_cr_letters='abcdefghijklmnopqrstuvwxyz' +as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' +as_cr_Letters=$as_cr_letters$as_cr_LETTERS +as_cr_digits='0123456789' +as_cr_alnum=$as_cr_Letters$as_cr_digits + + + as_lineno_1=$LINENO as_lineno_1a=$LINENO + as_lineno_2=$LINENO as_lineno_2a=$LINENO + eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" && + test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || { + # Blame Lee E. McMahon (1931-1989) for sed's syntax. :-) + sed -n ' + p + /[$]LINENO/= + ' <$as_myself | + sed ' + s/[$]LINENO.*/&-/ + t lineno + b + :lineno + N + :loop + s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ + t loop + s/-\n.*// + ' >$as_me.lineno && + chmod +x "$as_me.lineno" || + { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; } + + # Don't try to exec as it changes $[0], causing all sort of problems + # (the dirname of $[0] is not the place where we might find the + # original and so on. Autoconf is especially sensitive to this). + . "./$as_me.lineno" + # Exit status is that of the last command. + exit +} + +ECHO_C= ECHO_N= ECHO_T= +case `echo -n x` in #((((( +-n*) + case `echo 'xy\c'` in + *c*) ECHO_T=' ';; # ECHO_T is single tab character. + xy) ECHO_C='\c';; + *) echo `echo ksh88 bug on AIX 6.1` > /dev/null + ECHO_T=' ';; + esac;; +*) + ECHO_N='-n';; +esac + +rm -f conf$$ conf$$.exe conf$$.file +if test -d conf$$.dir; then + rm -f conf$$.dir/conf$$.file +else + rm -f conf$$.dir + mkdir conf$$.dir 2>/dev/null +fi +if (echo >conf$$.file) 2>/dev/null; then + if ln -s conf$$.file conf$$ 2>/dev/null; then + as_ln_s='ln -s' + # ... but there are two gotchas: + # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. + # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. + # In both cases, we have to default to `cp -p'. + ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || + as_ln_s='cp -p' + elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln + else + as_ln_s='cp -p' + fi +else + as_ln_s='cp -p' +fi +rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file +rmdir conf$$.dir 2>/dev/null + +if mkdir -p . 2>/dev/null; then + as_mkdir_p='mkdir -p "$as_dir"' +else + test -d ./-p && rmdir ./-p + as_mkdir_p=false +fi + +if test -x / >/dev/null 2>&1; then + as_test_x='test -x' +else + if ls -dL / >/dev/null 2>&1; then + as_ls_L_option=L + else + as_ls_L_option= + fi + as_test_x=' + eval sh -c '\'' + if test -d "$1"; then + test -d "$1/."; + else + case $1 in #( + -*)set "./$1";; + esac; + case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in #(( + ???[sx]*):;;*)false;;esac;fi + '\'' sh + ' +fi +as_executable_p=$as_test_x + +# Sed expression to map a string onto a valid CPP name. +as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" + +# Sed expression to map a string onto a valid variable name. +as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" + +SHELL=${CONFIG_SHELL-/bin/sh} + + +test -n "$DJDIR" || exec 7<&0 &1 + +# Name of the host. +# hostname on some systems (SVR3.2, old GNU/Linux) returns a bogus exit status, +# so uname gets run too. +ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` + +# +# Initializations. +# +ac_default_prefix=/usr/local +ac_clean_files= +ac_config_libobj_dir=. +LIBOBJS= +cross_compiling=no +subdirs= +MFLAGS= +MAKEFLAGS= + +# Identity of this package. +PACKAGE_NAME='yaml' +PACKAGE_TARNAME='yaml' +PACKAGE_VERSION='0.1.6' +PACKAGE_STRING='yaml 0.1.6' +PACKAGE_BUGREPORT='http://pyyaml.org/newticket?component=libyaml' +PACKAGE_URL='' + +# Factoring default headers for most tests. +ac_includes_default="\ +#include +#ifdef HAVE_SYS_TYPES_H +# include +#endif +#ifdef HAVE_SYS_STAT_H +# include +#endif +#ifdef STDC_HEADERS +# include +# include +#else +# ifdef HAVE_STDLIB_H +# include +# endif +#endif +#ifdef HAVE_STRING_H +# if !defined STDC_HEADERS && defined HAVE_MEMORY_H +# include +# endif +# include +#endif +#ifdef HAVE_STRINGS_H +# include +#endif +#ifdef HAVE_INTTYPES_H +# include +#endif +#ifdef HAVE_STDINT_H +# include +#endif +#ifdef HAVE_UNISTD_H +# include +#endif" + +ac_subst_vars='am__EXEEXT_FALSE +am__EXEEXT_TRUE +LTLIBOBJS +LIBOBJS +DOXYGEN_FALSE +DOXYGEN_TRUE +DOXYGEN +OTOOL64 +OTOOL +LIPO +NMEDIT +DSYMUTIL +MANIFEST_TOOL +RANLIB +ac_ct_AR +AR +DLLTOOL +OBJDUMP +NM +ac_ct_DUMPBIN +DUMPBIN +LD +FGREP +EGREP +GREP +SED +host_os +host_vendor +host_cpu +host +build_os +build_vendor +build_cpu +build +LIBTOOL +LN_S +CPP +am__fastdepCC_FALSE +am__fastdepCC_TRUE +CCDEPMODE +am__nodep +AMDEPBACKSLASH +AMDEP_FALSE +AMDEP_TRUE +am__quote +am__include +DEPDIR +OBJEXT +EXEEXT +ac_ct_CC +CPPFLAGS +LDFLAGS +CFLAGS +CC +YAML_LT_AGE +YAML_LT_REVISION +YAML_LT_CURRENT +YAML_LT_RELEASE +am__untar +am__tar +AMTAR +am__leading_dot +SET_MAKE +AWK +mkdir_p +MKDIR_P +INSTALL_STRIP_PROGRAM +STRIP +install_sh +MAKEINFO +AUTOHEADER +AUTOMAKE +AUTOCONF +ACLOCAL +VERSION +PACKAGE +CYGPATH_W +am__isrc +INSTALL_DATA +INSTALL_SCRIPT +INSTALL_PROGRAM +target_alias +host_alias +build_alias +LIBS +ECHO_T +ECHO_N +ECHO_C +DEFS +mandir +localedir +libdir +psdir +pdfdir +dvidir +htmldir +infodir +docdir +oldincludedir +includedir +localstatedir +sharedstatedir +sysconfdir +datadir +datarootdir +libexecdir +sbindir +bindir +program_transform_name +prefix +exec_prefix +PACKAGE_URL +PACKAGE_BUGREPORT +PACKAGE_STRING +PACKAGE_VERSION +PACKAGE_TARNAME +PACKAGE_NAME +PATH_SEPARATOR +SHELL' +ac_subst_files='' +ac_user_opts=' +enable_option_checking +enable_dependency_tracking +enable_shared +enable_static +with_pic +enable_fast_install +with_gnu_ld +with_sysroot +enable_libtool_lock +' + ac_precious_vars='build_alias +host_alias +target_alias +CC +CFLAGS +LDFLAGS +LIBS +CPPFLAGS +CPP' + + +# Initialize some variables set by options. +ac_init_help= +ac_init_version=false +ac_unrecognized_opts= +ac_unrecognized_sep= +# The variables have the same names as the options, with +# dashes changed to underlines. +cache_file=/dev/null +exec_prefix=NONE +no_create= +no_recursion= +prefix=NONE +program_prefix=NONE +program_suffix=NONE +program_transform_name=s,x,x, +silent= +site= +srcdir= +verbose= +x_includes=NONE +x_libraries=NONE + +# Installation directory options. +# These are left unexpanded so users can "make install exec_prefix=/foo" +# and all the variables that are supposed to be based on exec_prefix +# by default will actually change. +# Use braces instead of parens because sh, perl, etc. also accept them. +# (The list follows the same order as the GNU Coding Standards.) +bindir='${exec_prefix}/bin' +sbindir='${exec_prefix}/sbin' +libexecdir='${exec_prefix}/libexec' +datarootdir='${prefix}/share' +datadir='${datarootdir}' +sysconfdir='${prefix}/etc' +sharedstatedir='${prefix}/com' +localstatedir='${prefix}/var' +includedir='${prefix}/include' +oldincludedir='/usr/include' +docdir='${datarootdir}/doc/${PACKAGE_TARNAME}' +infodir='${datarootdir}/info' +htmldir='${docdir}' +dvidir='${docdir}' +pdfdir='${docdir}' +psdir='${docdir}' +libdir='${exec_prefix}/lib' +localedir='${datarootdir}/locale' +mandir='${datarootdir}/man' + +ac_prev= +ac_dashdash= +for ac_option +do + # If the previous option needs an argument, assign it. + if test -n "$ac_prev"; then + eval $ac_prev=\$ac_option + ac_prev= + continue + fi + + case $ac_option in + *=?*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;; + *=) ac_optarg= ;; + *) ac_optarg=yes ;; + esac + + # Accept the important Cygnus configure options, so we can diagnose typos. + + case $ac_dashdash$ac_option in + --) + ac_dashdash=yes ;; + + -bindir | --bindir | --bindi | --bind | --bin | --bi) + ac_prev=bindir ;; + -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) + bindir=$ac_optarg ;; + + -build | --build | --buil | --bui | --bu) + ac_prev=build_alias ;; + -build=* | --build=* | --buil=* | --bui=* | --bu=*) + build_alias=$ac_optarg ;; + + -cache-file | --cache-file | --cache-fil | --cache-fi \ + | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) + ac_prev=cache_file ;; + -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ + | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) + cache_file=$ac_optarg ;; + + --config-cache | -C) + cache_file=config.cache ;; + + -datadir | --datadir | --datadi | --datad) + ac_prev=datadir ;; + -datadir=* | --datadir=* | --datadi=* | --datad=*) + datadir=$ac_optarg ;; + + -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \ + | --dataroo | --dataro | --datar) + ac_prev=datarootdir ;; + -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \ + | --dataroot=* | --dataroo=* | --dataro=* | --datar=*) + datarootdir=$ac_optarg ;; + + -disable-* | --disable-*) + ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid feature name: $ac_useropt" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"enable_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval enable_$ac_useropt=no ;; + + -docdir | --docdir | --docdi | --doc | --do) + ac_prev=docdir ;; + -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*) + docdir=$ac_optarg ;; + + -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv) + ac_prev=dvidir ;; + -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*) + dvidir=$ac_optarg ;; + + -enable-* | --enable-*) + ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid feature name: $ac_useropt" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"enable_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval enable_$ac_useropt=\$ac_optarg ;; + + -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ + | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ + | --exec | --exe | --ex) + ac_prev=exec_prefix ;; + -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ + | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ + | --exec=* | --exe=* | --ex=*) + exec_prefix=$ac_optarg ;; + + -gas | --gas | --ga | --g) + # Obsolete; use --with-gas. + with_gas=yes ;; + + -help | --help | --hel | --he | -h) + ac_init_help=long ;; + -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) + ac_init_help=recursive ;; + -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) + ac_init_help=short ;; + + -host | --host | --hos | --ho) + ac_prev=host_alias ;; + -host=* | --host=* | --hos=* | --ho=*) + host_alias=$ac_optarg ;; + + -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht) + ac_prev=htmldir ;; + -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \ + | --ht=*) + htmldir=$ac_optarg ;; + + -includedir | --includedir | --includedi | --included | --include \ + | --includ | --inclu | --incl | --inc) + ac_prev=includedir ;; + -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ + | --includ=* | --inclu=* | --incl=* | --inc=*) + includedir=$ac_optarg ;; + + -infodir | --infodir | --infodi | --infod | --info | --inf) + ac_prev=infodir ;; + -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) + infodir=$ac_optarg ;; + + -libdir | --libdir | --libdi | --libd) + ac_prev=libdir ;; + -libdir=* | --libdir=* | --libdi=* | --libd=*) + libdir=$ac_optarg ;; + + -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ + | --libexe | --libex | --libe) + ac_prev=libexecdir ;; + -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ + | --libexe=* | --libex=* | --libe=*) + libexecdir=$ac_optarg ;; + + -localedir | --localedir | --localedi | --localed | --locale) + ac_prev=localedir ;; + -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*) + localedir=$ac_optarg ;; + + -localstatedir | --localstatedir | --localstatedi | --localstated \ + | --localstate | --localstat | --localsta | --localst | --locals) + ac_prev=localstatedir ;; + -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ + | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*) + localstatedir=$ac_optarg ;; + + -mandir | --mandir | --mandi | --mand | --man | --ma | --m) + ac_prev=mandir ;; + -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) + mandir=$ac_optarg ;; + + -nfp | --nfp | --nf) + # Obsolete; use --without-fp. + with_fp=no ;; + + -no-create | --no-create | --no-creat | --no-crea | --no-cre \ + | --no-cr | --no-c | -n) + no_create=yes ;; + + -no-recursion | --no-recursion | --no-recursio | --no-recursi \ + | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) + no_recursion=yes ;; + + -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ + | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ + | --oldin | --oldi | --old | --ol | --o) + ac_prev=oldincludedir ;; + -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ + | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ + | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) + oldincludedir=$ac_optarg ;; + + -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) + ac_prev=prefix ;; + -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) + prefix=$ac_optarg ;; + + -program-prefix | --program-prefix | --program-prefi | --program-pref \ + | --program-pre | --program-pr | --program-p) + ac_prev=program_prefix ;; + -program-prefix=* | --program-prefix=* | --program-prefi=* \ + | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) + program_prefix=$ac_optarg ;; + + -program-suffix | --program-suffix | --program-suffi | --program-suff \ + | --program-suf | --program-su | --program-s) + ac_prev=program_suffix ;; + -program-suffix=* | --program-suffix=* | --program-suffi=* \ + | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) + program_suffix=$ac_optarg ;; + + -program-transform-name | --program-transform-name \ + | --program-transform-nam | --program-transform-na \ + | --program-transform-n | --program-transform- \ + | --program-transform | --program-transfor \ + | --program-transfo | --program-transf \ + | --program-trans | --program-tran \ + | --progr-tra | --program-tr | --program-t) + ac_prev=program_transform_name ;; + -program-transform-name=* | --program-transform-name=* \ + | --program-transform-nam=* | --program-transform-na=* \ + | --program-transform-n=* | --program-transform-=* \ + | --program-transform=* | --program-transfor=* \ + | --program-transfo=* | --program-transf=* \ + | --program-trans=* | --program-tran=* \ + | --progr-tra=* | --program-tr=* | --program-t=*) + program_transform_name=$ac_optarg ;; + + -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd) + ac_prev=pdfdir ;; + -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*) + pdfdir=$ac_optarg ;; + + -psdir | --psdir | --psdi | --psd | --ps) + ac_prev=psdir ;; + -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*) + psdir=$ac_optarg ;; + + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + silent=yes ;; + + -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) + ac_prev=sbindir ;; + -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ + | --sbi=* | --sb=*) + sbindir=$ac_optarg ;; + + -sharedstatedir | --sharedstatedir | --sharedstatedi \ + | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ + | --sharedst | --shareds | --shared | --share | --shar \ + | --sha | --sh) + ac_prev=sharedstatedir ;; + -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ + | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ + | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ + | --sha=* | --sh=*) + sharedstatedir=$ac_optarg ;; + + -site | --site | --sit) + ac_prev=site ;; + -site=* | --site=* | --sit=*) + site=$ac_optarg ;; + + -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) + ac_prev=srcdir ;; + -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) + srcdir=$ac_optarg ;; + + -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ + | --syscon | --sysco | --sysc | --sys | --sy) + ac_prev=sysconfdir ;; + -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ + | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) + sysconfdir=$ac_optarg ;; + + -target | --target | --targe | --targ | --tar | --ta | --t) + ac_prev=target_alias ;; + -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) + target_alias=$ac_optarg ;; + + -v | -verbose | --verbose | --verbos | --verbo | --verb) + verbose=yes ;; + + -version | --version | --versio | --versi | --vers | -V) + ac_init_version=: ;; + + -with-* | --with-*) + ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid package name: $ac_useropt" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"with_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval with_$ac_useropt=\$ac_optarg ;; + + -without-* | --without-*) + ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid package name: $ac_useropt" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"with_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval with_$ac_useropt=no ;; + + --x) + # Obsolete; use --with-x. + with_x=yes ;; + + -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ + | --x-incl | --x-inc | --x-in | --x-i) + ac_prev=x_includes ;; + -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ + | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) + x_includes=$ac_optarg ;; + + -x-libraries | --x-libraries | --x-librarie | --x-librari \ + | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) + ac_prev=x_libraries ;; + -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ + | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) + x_libraries=$ac_optarg ;; + + -*) as_fn_error $? "unrecognized option: \`$ac_option' +Try \`$0 --help' for more information" + ;; + + *=*) + ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` + # Reject names that are not valid shell variable names. + case $ac_envvar in #( + '' | [0-9]* | *[!_$as_cr_alnum]* ) + as_fn_error $? "invalid variable name: \`$ac_envvar'" ;; + esac + eval $ac_envvar=\$ac_optarg + export $ac_envvar ;; + + *) + # FIXME: should be removed in autoconf 3.0. + $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2 + expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && + $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2 + : "${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}" + ;; + + esac +done + +if test -n "$ac_prev"; then + ac_option=--`echo $ac_prev | sed 's/_/-/g'` + as_fn_error $? "missing argument to $ac_option" +fi + +if test -n "$ac_unrecognized_opts"; then + case $enable_option_checking in + no) ;; + fatal) as_fn_error $? "unrecognized options: $ac_unrecognized_opts" ;; + *) $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;; + esac +fi + +# Check all directory arguments for consistency. +for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ + datadir sysconfdir sharedstatedir localstatedir includedir \ + oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ + libdir localedir mandir +do + eval ac_val=\$$ac_var + # Remove trailing slashes. + case $ac_val in + */ ) + ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'` + eval $ac_var=\$ac_val;; + esac + # Be sure to have absolute directory names. + case $ac_val in + [\\/$]* | ?:[\\/]* ) continue;; + NONE | '' ) case $ac_var in *prefix ) continue;; esac;; + esac + as_fn_error $? "expected an absolute directory name for --$ac_var: $ac_val" +done + +# There might be people who depend on the old broken behavior: `$host' +# used to hold the argument of --host etc. +# FIXME: To remove some day. +build=$build_alias +host=$host_alias +target=$target_alias + +# FIXME: To remove some day. +if test "x$host_alias" != x; then + if test "x$build_alias" = x; then + cross_compiling=maybe + $as_echo "$as_me: WARNING: if you wanted to set the --build type, don't use --host. + If a cross compiler is detected then cross compile mode will be used" >&2 + elif test "x$build_alias" != "x$host_alias"; then + cross_compiling=yes + fi +fi + +ac_tool_prefix= +test -n "$host_alias" && ac_tool_prefix=$host_alias- + +test "$silent" = yes && exec 6>/dev/null + + +ac_pwd=`pwd` && test -n "$ac_pwd" && +ac_ls_di=`ls -di .` && +ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` || + as_fn_error $? "working directory cannot be determined" +test "X$ac_ls_di" = "X$ac_pwd_ls_di" || + as_fn_error $? "pwd does not report name of working directory" + + +# Find the source files, if location was not specified. +if test -z "$srcdir"; then + ac_srcdir_defaulted=yes + # Try the directory containing this script, then the parent directory. + ac_confdir=`$as_dirname -- "$as_myself" || +$as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_myself" : 'X\(//\)[^/]' \| \ + X"$as_myself" : 'X\(//\)$' \| \ + X"$as_myself" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$as_myself" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + srcdir=$ac_confdir + if test ! -r "$srcdir/$ac_unique_file"; then + srcdir=.. + fi +else + ac_srcdir_defaulted=no +fi +if test ! -r "$srcdir/$ac_unique_file"; then + test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .." + as_fn_error $? "cannot find sources ($ac_unique_file) in $srcdir" +fi +ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work" +ac_abs_confdir=`( + cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error $? "$ac_msg" + pwd)` +# When building in place, set srcdir=. +if test "$ac_abs_confdir" = "$ac_pwd"; then + srcdir=. +fi +# Remove unnecessary trailing slashes from srcdir. +# Double slashes in file names in object file debugging info +# mess up M-x gdb in Emacs. +case $srcdir in +*/) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;; +esac +for ac_var in $ac_precious_vars; do + eval ac_env_${ac_var}_set=\${${ac_var}+set} + eval ac_env_${ac_var}_value=\$${ac_var} + eval ac_cv_env_${ac_var}_set=\${${ac_var}+set} + eval ac_cv_env_${ac_var}_value=\$${ac_var} +done + +# +# Report the --help message. +# +if test "$ac_init_help" = "long"; then + # Omit some internal or obsolete options to make the list less imposing. + # This message is too long to be a string in the A/UX 3.1 sh. + cat <<_ACEOF +\`configure' configures yaml 0.1.6 to adapt to many kinds of systems. + +Usage: $0 [OPTION]... [VAR=VALUE]... + +To assign environment variables (e.g., CC, CFLAGS...), specify them as +VAR=VALUE. See below for descriptions of some of the useful variables. + +Defaults for the options are specified in brackets. + +Configuration: + -h, --help display this help and exit + --help=short display options specific to this package + --help=recursive display the short help of all the included packages + -V, --version display version information and exit + -q, --quiet, --silent do not print \`checking ...' messages + --cache-file=FILE cache test results in FILE [disabled] + -C, --config-cache alias for \`--cache-file=config.cache' + -n, --no-create do not create output files + --srcdir=DIR find the sources in DIR [configure dir or \`..'] + +Installation directories: + --prefix=PREFIX install architecture-independent files in PREFIX + [$ac_default_prefix] + --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX + [PREFIX] + +By default, \`make install' will install all the files in +\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify +an installation prefix other than \`$ac_default_prefix' using \`--prefix', +for instance \`--prefix=\$HOME'. + +For better control, use the options below. + +Fine tuning of the installation directories: + --bindir=DIR user executables [EPREFIX/bin] + --sbindir=DIR system admin executables [EPREFIX/sbin] + --libexecdir=DIR program executables [EPREFIX/libexec] + --sysconfdir=DIR read-only single-machine data [PREFIX/etc] + --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] + --localstatedir=DIR modifiable single-machine data [PREFIX/var] + --libdir=DIR object code libraries [EPREFIX/lib] + --includedir=DIR C header files [PREFIX/include] + --oldincludedir=DIR C header files for non-gcc [/usr/include] + --datarootdir=DIR read-only arch.-independent data root [PREFIX/share] + --datadir=DIR read-only architecture-independent data [DATAROOTDIR] + --infodir=DIR info documentation [DATAROOTDIR/info] + --localedir=DIR locale-dependent data [DATAROOTDIR/locale] + --mandir=DIR man documentation [DATAROOTDIR/man] + --docdir=DIR documentation root [DATAROOTDIR/doc/yaml] + --htmldir=DIR html documentation [DOCDIR] + --dvidir=DIR dvi documentation [DOCDIR] + --pdfdir=DIR pdf documentation [DOCDIR] + --psdir=DIR ps documentation [DOCDIR] +_ACEOF + + cat <<\_ACEOF + +Program names: + --program-prefix=PREFIX prepend PREFIX to installed program names + --program-suffix=SUFFIX append SUFFIX to installed program names + --program-transform-name=PROGRAM run sed PROGRAM on installed program names + +System types: + --build=BUILD configure for building on BUILD [guessed] + --host=HOST cross-compile to build programs to run on HOST [BUILD] +_ACEOF +fi + +if test -n "$ac_init_help"; then + case $ac_init_help in + short | recursive ) echo "Configuration of yaml 0.1.6:";; + esac + cat <<\_ACEOF + +Optional Features: + --disable-option-checking ignore unrecognized --enable/--with options + --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) + --enable-FEATURE[=ARG] include FEATURE [ARG=yes] + --disable-dependency-tracking speeds up one-time build + --enable-dependency-tracking do not reject slow dependency extractors + --enable-shared[=PKGS] build shared libraries [default=yes] + --enable-static[=PKGS] build static libraries [default=yes] + --enable-fast-install[=PKGS] + optimize for fast installation [default=yes] + --disable-libtool-lock avoid locking (might break parallel builds) + +Optional Packages: + --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] + --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) + --with-pic[=PKGS] try to use only PIC/non-PIC objects [default=use + both] + --with-gnu-ld assume the C compiler uses GNU ld [default=no] + --with-sysroot=DIR Search for dependent libraries within DIR + (or the compiler's sysroot if not specified). + +Some influential environment variables: + CC C compiler command + CFLAGS C compiler flags + LDFLAGS linker flags, e.g. -L if you have libraries in a + nonstandard directory + LIBS libraries to pass to the linker, e.g. -l + CPPFLAGS (Objective) C/C++ preprocessor flags, e.g. -I if + you have headers in a nonstandard directory + CPP C preprocessor + +Use these variables to override the choices made by `configure' or to help +it to find libraries and programs with nonstandard names/locations. + +Report bugs to . +_ACEOF +ac_status=$? +fi + +if test "$ac_init_help" = "recursive"; then + # If there are subdirs, report their specific --help. + for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue + test -d "$ac_dir" || + { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } || + continue + ac_builddir=. + +case "$ac_dir" in +.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; +*) + ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` + # A ".." for each directory in $ac_dir_suffix. + ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` + case $ac_top_builddir_sub in + "") ac_top_builddir_sub=. ac_top_build_prefix= ;; + *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; + esac ;; +esac +ac_abs_top_builddir=$ac_pwd +ac_abs_builddir=$ac_pwd$ac_dir_suffix +# for backward compatibility: +ac_top_builddir=$ac_top_build_prefix + +case $srcdir in + .) # We are building in place. + ac_srcdir=. + ac_top_srcdir=$ac_top_builddir_sub + ac_abs_top_srcdir=$ac_pwd ;; + [\\/]* | ?:[\\/]* ) # Absolute name. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir + ac_abs_top_srcdir=$srcdir ;; + *) # Relative name. + ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_build_prefix$srcdir + ac_abs_top_srcdir=$ac_pwd/$srcdir ;; +esac +ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix + + cd "$ac_dir" || { ac_status=$?; continue; } + # Check for guested configure. + if test -f "$ac_srcdir/configure.gnu"; then + echo && + $SHELL "$ac_srcdir/configure.gnu" --help=recursive + elif test -f "$ac_srcdir/configure"; then + echo && + $SHELL "$ac_srcdir/configure" --help=recursive + else + $as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 + fi || ac_status=$? + cd "$ac_pwd" || { ac_status=$?; break; } + done +fi + +test -n "$ac_init_help" && exit $ac_status +if $ac_init_version; then + cat <<\_ACEOF +yaml configure 0.1.6 +generated by GNU Autoconf 2.68 + +Copyright (C) 2010 Free Software Foundation, Inc. +This configure script is free software; the Free Software Foundation +gives unlimited permission to copy, distribute and modify it. +_ACEOF + exit +fi + +## ------------------------ ## +## Autoconf initialization. ## +## ------------------------ ## + +# ac_fn_c_try_compile LINENO +# -------------------------- +# Try to compile conftest.$ac_ext, and return whether this succeeded. +ac_fn_c_try_compile () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + rm -f conftest.$ac_objext + if { { ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compile") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_c_try_compile + +# ac_fn_c_try_cpp LINENO +# ---------------------- +# Try to preprocess conftest.$ac_ext, and return whether this succeeded. +ac_fn_c_try_cpp () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + if { { ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } > conftest.i && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_c_try_cpp + +# ac_fn_c_try_link LINENO +# ----------------------- +# Try to link conftest.$ac_ext, and return whether this succeeded. +ac_fn_c_try_link () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + rm -f conftest.$ac_objext conftest$ac_exeext + if { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && { + test "$cross_compiling" = yes || + $as_test_x conftest$ac_exeext + }; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information + # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would + # interfere with the next link command; also delete a directory that is + # left behind by Apple's compiler. We do this before executing the actions. + rm -rf conftest.dSYM conftest_ipa8_conftest.oo + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_c_try_link + +# ac_fn_c_check_header_compile LINENO HEADER VAR INCLUDES +# ------------------------------------------------------- +# Tests whether HEADER exists and can be compiled using the include files in +# INCLUDES, setting the cache variable VAR accordingly. +ac_fn_c_check_header_compile () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +#include <$2> +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + eval "$3=yes" +else + eval "$3=no" +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + +} # ac_fn_c_check_header_compile + +# ac_fn_c_try_run LINENO +# ---------------------- +# Try to link conftest.$ac_ext, and return whether this succeeded. Assumes +# that executables *can* be run. +ac_fn_c_try_run () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + if { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { ac_try='./conftest$ac_exeext' + { { case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; }; then : + ac_retval=0 +else + $as_echo "$as_me: program exited with status $ac_status" >&5 + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=$ac_status +fi + rm -rf conftest.dSYM conftest_ipa8_conftest.oo + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_c_try_run + +# ac_fn_c_check_func LINENO FUNC VAR +# ---------------------------------- +# Tests whether FUNC exists, setting the cache variable VAR accordingly +ac_fn_c_check_func () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +/* Define $2 to an innocuous variant, in case declares $2. + For example, HP-UX 11i declares gettimeofday. */ +#define $2 innocuous_$2 + +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $2 (); below. + Prefer to if __STDC__ is defined, since + exists even on freestanding compilers. */ + +#ifdef __STDC__ +# include +#else +# include +#endif + +#undef $2 + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char $2 (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined __stub_$2 || defined __stub___$2 +choke me +#endif + +int +main () +{ +return $2 (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + eval "$3=yes" +else + eval "$3=no" +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + +} # ac_fn_c_check_func + +# ac_fn_c_check_header_mongrel LINENO HEADER VAR INCLUDES +# ------------------------------------------------------- +# Tests whether HEADER exists, giving a warning if it cannot be compiled using +# the include files in INCLUDES and setting the cache variable VAR +# accordingly. +ac_fn_c_check_header_mongrel () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + if eval \${$3+:} false; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } +else + # Is the header compilable? +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 usability" >&5 +$as_echo_n "checking $2 usability... " >&6; } +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +#include <$2> +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_header_compiler=yes +else + ac_header_compiler=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_compiler" >&5 +$as_echo "$ac_header_compiler" >&6; } + +# Is the header present? +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 presence" >&5 +$as_echo_n "checking $2 presence... " >&6; } +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <$2> +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + ac_header_preproc=yes +else + ac_header_preproc=no +fi +rm -f conftest.err conftest.i conftest.$ac_ext +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_preproc" >&5 +$as_echo "$ac_header_preproc" >&6; } + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in #(( + yes:no: ) + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&5 +$as_echo "$as_me: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 +$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} + ;; + no:yes:* ) + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: present but cannot be compiled" >&5 +$as_echo "$as_me: WARNING: $2: present but cannot be compiled" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: check for missing prerequisite headers?" >&5 +$as_echo "$as_me: WARNING: $2: check for missing prerequisite headers?" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: see the Autoconf documentation" >&5 +$as_echo "$as_me: WARNING: $2: see the Autoconf documentation" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&5 +$as_echo "$as_me: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 +$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} +( $as_echo "## ------------------------------------------------------------ ## +## Report this to http://pyyaml.org/newticket?component=libyaml ## +## ------------------------------------------------------------ ##" + ) | sed "s/^/$as_me: WARNING: /" >&2 + ;; +esac + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +else + eval "$3=\$ac_header_compiler" +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } +fi + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + +} # ac_fn_c_check_header_mongrel + +# ac_fn_c_check_type LINENO TYPE VAR INCLUDES +# ------------------------------------------- +# Tests whether TYPE exists after having included INCLUDES, setting cache +# variable VAR accordingly. +ac_fn_c_check_type () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +else + eval "$3=no" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +int +main () +{ +if (sizeof ($2)) + return 0; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +int +main () +{ +if (sizeof (($2))) + return 0; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + +else + eval "$3=yes" +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + +} # ac_fn_c_check_type +cat >config.log <<_ACEOF +This file contains any messages produced by compilers while +running configure, to aid debugging if configure makes a mistake. + +It was created by yaml $as_me 0.1.6, which was +generated by GNU Autoconf 2.68. Invocation command line was + + $ $0 $@ + +_ACEOF +exec 5>>config.log +{ +cat <<_ASUNAME +## --------- ## +## Platform. ## +## --------- ## + +hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` +uname -m = `(uname -m) 2>/dev/null || echo unknown` +uname -r = `(uname -r) 2>/dev/null || echo unknown` +uname -s = `(uname -s) 2>/dev/null || echo unknown` +uname -v = `(uname -v) 2>/dev/null || echo unknown` + +/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` +/bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` + +/bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` +/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` +/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` +/usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown` +/bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` +/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` +/bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` + +_ASUNAME + +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + $as_echo "PATH: $as_dir" + done +IFS=$as_save_IFS + +} >&5 + +cat >&5 <<_ACEOF + + +## ----------- ## +## Core tests. ## +## ----------- ## + +_ACEOF + + +# Keep a trace of the command line. +# Strip out --no-create and --no-recursion so they do not pile up. +# Strip out --silent because we don't want to record it for future runs. +# Also quote any args containing shell meta-characters. +# Make two passes to allow for proper duplicate-argument suppression. +ac_configure_args= +ac_configure_args0= +ac_configure_args1= +ac_must_keep_next=false +for ac_pass in 1 2 +do + for ac_arg + do + case $ac_arg in + -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;; + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + continue ;; + *\'*) + ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; + esac + case $ac_pass in + 1) as_fn_append ac_configure_args0 " '$ac_arg'" ;; + 2) + as_fn_append ac_configure_args1 " '$ac_arg'" + if test $ac_must_keep_next = true; then + ac_must_keep_next=false # Got value, back to normal. + else + case $ac_arg in + *=* | --config-cache | -C | -disable-* | --disable-* \ + | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \ + | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \ + | -with-* | --with-* | -without-* | --without-* | --x) + case "$ac_configure_args0 " in + "$ac_configure_args1"*" '$ac_arg' "* ) continue ;; + esac + ;; + -* ) ac_must_keep_next=true ;; + esac + fi + as_fn_append ac_configure_args " '$ac_arg'" + ;; + esac + done +done +{ ac_configure_args0=; unset ac_configure_args0;} +{ ac_configure_args1=; unset ac_configure_args1;} + +# When interrupted or exit'd, cleanup temporary files, and complete +# config.log. We remove comments because anyway the quotes in there +# would cause problems or look ugly. +# WARNING: Use '\'' to represent an apostrophe within the trap. +# WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug. +trap 'exit_status=$? + # Save into config.log some information that might help in debugging. + { + echo + + $as_echo "## ---------------- ## +## Cache variables. ## +## ---------------- ##" + echo + # The following way of writing the cache mishandles newlines in values, +( + for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do + eval ac_val=\$$ac_var + case $ac_val in #( + *${as_nl}*) + case $ac_var in #( + *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 +$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; + esac + case $ac_var in #( + _ | IFS | as_nl) ;; #( + BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( + *) { eval $ac_var=; unset $ac_var;} ;; + esac ;; + esac + done + (set) 2>&1 | + case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #( + *${as_nl}ac_space=\ *) + sed -n \ + "s/'\''/'\''\\\\'\'''\''/g; + s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p" + ;; #( + *) + sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" + ;; + esac | + sort +) + echo + + $as_echo "## ----------------- ## +## Output variables. ## +## ----------------- ##" + echo + for ac_var in $ac_subst_vars + do + eval ac_val=\$$ac_var + case $ac_val in + *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; + esac + $as_echo "$ac_var='\''$ac_val'\''" + done | sort + echo + + if test -n "$ac_subst_files"; then + $as_echo "## ------------------- ## +## File substitutions. ## +## ------------------- ##" + echo + for ac_var in $ac_subst_files + do + eval ac_val=\$$ac_var + case $ac_val in + *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; + esac + $as_echo "$ac_var='\''$ac_val'\''" + done | sort + echo + fi + + if test -s confdefs.h; then + $as_echo "## ----------- ## +## confdefs.h. ## +## ----------- ##" + echo + cat confdefs.h + echo + fi + test "$ac_signal" != 0 && + $as_echo "$as_me: caught signal $ac_signal" + $as_echo "$as_me: exit $exit_status" + } >&5 + rm -f core *.core core.conftest.* && + rm -f -r conftest* confdefs* conf$$* $ac_clean_files && + exit $exit_status +' 0 +for ac_signal in 1 2 13 15; do + trap 'ac_signal='$ac_signal'; as_fn_exit 1' $ac_signal +done +ac_signal=0 + +# confdefs.h avoids OS command line length limits that DEFS can exceed. +rm -f -r conftest* confdefs.h + +$as_echo "/* confdefs.h */" > confdefs.h + +# Predefined preprocessor variables. + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_NAME "$PACKAGE_NAME" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_TARNAME "$PACKAGE_TARNAME" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_VERSION "$PACKAGE_VERSION" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_STRING "$PACKAGE_STRING" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_URL "$PACKAGE_URL" +_ACEOF + + +# Let the site file select an alternate cache file if it wants to. +# Prefer an explicitly selected file to automatically selected ones. +ac_site_file1=NONE +ac_site_file2=NONE +if test -n "$CONFIG_SITE"; then + # We do not want a PATH search for config.site. + case $CONFIG_SITE in #(( + -*) ac_site_file1=./$CONFIG_SITE;; + */*) ac_site_file1=$CONFIG_SITE;; + *) ac_site_file1=./$CONFIG_SITE;; + esac +elif test "x$prefix" != xNONE; then + ac_site_file1=$prefix/share/config.site + ac_site_file2=$prefix/etc/config.site +else + ac_site_file1=$ac_default_prefix/share/config.site + ac_site_file2=$ac_default_prefix/etc/config.site +fi +for ac_site_file in "$ac_site_file1" "$ac_site_file2" +do + test "x$ac_site_file" = xNONE && continue + if test /dev/null != "$ac_site_file" && test -r "$ac_site_file"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5 +$as_echo "$as_me: loading site script $ac_site_file" >&6;} + sed 's/^/| /' "$ac_site_file" >&5 + . "$ac_site_file" \ + || { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "failed to load site script $ac_site_file +See \`config.log' for more details" "$LINENO" 5; } + fi +done + +if test -r "$cache_file"; then + # Some versions of bash will fail to source /dev/null (special files + # actually), so we avoid doing that. DJGPP emulates it as a regular file. + if test /dev/null != "$cache_file" && test -f "$cache_file"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5 +$as_echo "$as_me: loading cache $cache_file" >&6;} + case $cache_file in + [\\/]* | ?:[\\/]* ) . "$cache_file";; + *) . "./$cache_file";; + esac + fi +else + { $as_echo "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5 +$as_echo "$as_me: creating cache $cache_file" >&6;} + >$cache_file +fi + +# Check that the precious variables saved in the cache have kept the same +# value. +ac_cache_corrupted=false +for ac_var in $ac_precious_vars; do + eval ac_old_set=\$ac_cv_env_${ac_var}_set + eval ac_new_set=\$ac_env_${ac_var}_set + eval ac_old_val=\$ac_cv_env_${ac_var}_value + eval ac_new_val=\$ac_env_${ac_var}_value + case $ac_old_set,$ac_new_set in + set,) + { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 +$as_echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} + ac_cache_corrupted=: ;; + ,set) + { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5 +$as_echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} + ac_cache_corrupted=: ;; + ,);; + *) + if test "x$ac_old_val" != "x$ac_new_val"; then + # differences in whitespace do not lead to failure. + ac_old_val_w=`echo x $ac_old_val` + ac_new_val_w=`echo x $ac_new_val` + if test "$ac_old_val_w" != "$ac_new_val_w"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5 +$as_echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} + ac_cache_corrupted=: + else + { $as_echo "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5 +$as_echo "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;} + eval $ac_var=\$ac_old_val + fi + { $as_echo "$as_me:${as_lineno-$LINENO}: former value: \`$ac_old_val'" >&5 +$as_echo "$as_me: former value: \`$ac_old_val'" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: current value: \`$ac_new_val'" >&5 +$as_echo "$as_me: current value: \`$ac_new_val'" >&2;} + fi;; + esac + # Pass precious variables to config.status. + if test "$ac_new_set" = set; then + case $ac_new_val in + *\'*) ac_arg=$ac_var=`$as_echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; + *) ac_arg=$ac_var=$ac_new_val ;; + esac + case " $ac_configure_args " in + *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. + *) as_fn_append ac_configure_args " '$ac_arg'" ;; + esac + fi +done +if $ac_cache_corrupted; then + { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5 +$as_echo "$as_me: error: changes in the environment can compromise the build" >&2;} + as_fn_error $? "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5 +fi +## -------------------- ## +## Main body of script. ## +## -------------------- ## + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + +ac_aux_dir= +for ac_dir in config "$srcdir"/config; do + if test -f "$ac_dir/install-sh"; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install-sh -c" + break + elif test -f "$ac_dir/install.sh"; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install.sh -c" + break + elif test -f "$ac_dir/shtool"; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/shtool install -c" + break + fi +done +if test -z "$ac_aux_dir"; then + as_fn_error $? "cannot find install-sh, install.sh, or shtool in config \"$srcdir\"/config" "$LINENO" 5 +fi + +# These three variables are undocumented and unsupported, +# and are intended to be withdrawn in a future Autoconf release. +# They can cause serious problems if a builder's source tree is in a directory +# whose full name contains unusual characters. +ac_config_guess="$SHELL $ac_aux_dir/config.guess" # Please don't use this var. +ac_config_sub="$SHELL $ac_aux_dir/config.sub" # Please don't use this var. +ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var. + + +ac_config_headers="$ac_config_headers config.h" + +am__api_version='1.11' + +# Find a good install program. We prefer a C program (faster), +# so one script is as good as another. But avoid the broken or +# incompatible versions: +# SysV /etc/install, /usr/sbin/install +# SunOS /usr/etc/install +# IRIX /sbin/install +# AIX /bin/install +# AmigaOS /C/install, which installs bootblocks on floppy discs +# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag +# AFS /usr/afsws/bin/install, which mishandles nonexistent args +# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" +# OS/2's system install, which has a completely different semantic +# ./install, which can be erroneously created by make from ./install.sh. +# Reject install programs that cannot install multiple files. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a BSD-compatible install" >&5 +$as_echo_n "checking for a BSD-compatible install... " >&6; } +if test -z "$INSTALL"; then +if ${ac_cv_path_install+:} false; then : + $as_echo_n "(cached) " >&6 +else + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + # Account for people who put trailing slashes in PATH elements. +case $as_dir/ in #(( + ./ | .// | /[cC]/* | \ + /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \ + ?:[\\/]os2[\\/]install[\\/]* | ?:[\\/]OS2[\\/]INSTALL[\\/]* | \ + /usr/ucb/* ) ;; + *) + # OSF1 and SCO ODT 3.0 have their own names for install. + # Don't use installbsd from OSF since it installs stuff as root + # by default. + for ac_prog in ginstall scoinst install; do + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_test_x "$as_dir/$ac_prog$ac_exec_ext"; }; then + if test $ac_prog = install && + grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then + # AIX install. It has an incompatible calling convention. + : + elif test $ac_prog = install && + grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then + # program-specific install script used by HP pwplus--don't use. + : + else + rm -rf conftest.one conftest.two conftest.dir + echo one > conftest.one + echo two > conftest.two + mkdir conftest.dir + if "$as_dir/$ac_prog$ac_exec_ext" -c conftest.one conftest.two "`pwd`/conftest.dir" && + test -s conftest.one && test -s conftest.two && + test -s conftest.dir/conftest.one && + test -s conftest.dir/conftest.two + then + ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c" + break 3 + fi + fi + fi + done + done + ;; +esac + + done +IFS=$as_save_IFS + +rm -rf conftest.one conftest.two conftest.dir + +fi + if test "${ac_cv_path_install+set}" = set; then + INSTALL=$ac_cv_path_install + else + # As a last resort, use the slow shell script. Don't cache a + # value for INSTALL within a source directory, because that will + # break other packages using the cache if that directory is + # removed, or if the value is a relative name. + INSTALL=$ac_install_sh + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $INSTALL" >&5 +$as_echo "$INSTALL" >&6; } + +# Use test -z because SunOS4 sh mishandles braces in ${var-val}. +# It thinks the first close brace ends the variable substitution. +test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' + +test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}' + +test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether build environment is sane" >&5 +$as_echo_n "checking whether build environment is sane... " >&6; } +# Just in case +sleep 1 +echo timestamp > conftest.file +# Reject unsafe characters in $srcdir or the absolute working directory +# name. Accept space and tab only in the latter. +am_lf=' +' +case `pwd` in + *[\\\"\#\$\&\'\`$am_lf]*) + as_fn_error $? "unsafe absolute working directory name" "$LINENO" 5;; +esac +case $srcdir in + *[\\\"\#\$\&\'\`$am_lf\ \ ]*) + as_fn_error $? "unsafe srcdir value: \`$srcdir'" "$LINENO" 5;; +esac + +# Do `set' in a subshell so we don't clobber the current shell's +# arguments. Must try -L first in case configure is actually a +# symlink; some systems play weird games with the mod time of symlinks +# (eg FreeBSD returns the mod time of the symlink's containing +# directory). +if ( + set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` + if test "$*" = "X"; then + # -L didn't work. + set X `ls -t "$srcdir/configure" conftest.file` + fi + rm -f conftest.file + if test "$*" != "X $srcdir/configure conftest.file" \ + && test "$*" != "X conftest.file $srcdir/configure"; then + + # If neither matched, then we have a broken ls. This can happen + # if, for instance, CONFIG_SHELL is bash and it inherits a + # broken ls alias from the environment. This has actually + # happened. Such a system could not be considered "sane". + as_fn_error $? "ls -t appears to fail. Make sure there is not a broken +alias in your environment" "$LINENO" 5 + fi + + test "$2" = conftest.file + ) +then + # Ok. + : +else + as_fn_error $? "newly created file is older than distributed files! +Check your system clock" "$LINENO" 5 +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +test "$program_prefix" != NONE && + program_transform_name="s&^&$program_prefix&;$program_transform_name" +# Use a double $ so make ignores it. +test "$program_suffix" != NONE && + program_transform_name="s&\$&$program_suffix&;$program_transform_name" +# Double any \ or $. +# By default was `s,x,x', remove it if useless. +ac_script='s/[\\$]/&&/g;s/;s,x,x,$//' +program_transform_name=`$as_echo "$program_transform_name" | sed "$ac_script"` + +# expand $ac_aux_dir to an absolute path +am_aux_dir=`cd $ac_aux_dir && pwd` + +if test x"${MISSING+set}" != xset; then + case $am_aux_dir in + *\ * | *\ *) + MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;; + *) + MISSING="\${SHELL} $am_aux_dir/missing" ;; + esac +fi +# Use eval to expand $SHELL +if eval "$MISSING --run true"; then + am_missing_run="$MISSING --run " +else + am_missing_run= + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: \`missing' script is too old or missing" >&5 +$as_echo "$as_me: WARNING: \`missing' script is too old or missing" >&2;} +fi + +if test x"${install_sh}" != xset; then + case $am_aux_dir in + *\ * | *\ *) + install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;; + *) + install_sh="\${SHELL} $am_aux_dir/install-sh" + esac +fi + +# Installed binaries are usually stripped using `strip' when the user +# run `make install-strip'. However `strip' might not be the right +# tool to use in cross-compilation environments, therefore Automake +# will honor the `STRIP' environment variable to overrule this program. +if test "$cross_compiling" != no; then + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. +set dummy ${ac_tool_prefix}strip; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_STRIP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$STRIP"; then + ac_cv_prog_STRIP="$STRIP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_STRIP="${ac_tool_prefix}strip" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +STRIP=$ac_cv_prog_STRIP +if test -n "$STRIP"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5 +$as_echo "$STRIP" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_STRIP"; then + ac_ct_STRIP=$STRIP + # Extract the first word of "strip", so it can be a program name with args. +set dummy strip; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_STRIP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_STRIP"; then + ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_STRIP="strip" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP +if test -n "$ac_ct_STRIP"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5 +$as_echo "$ac_ct_STRIP" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_STRIP" = x; then + STRIP=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + STRIP=$ac_ct_STRIP + fi +else + STRIP="$ac_cv_prog_STRIP" +fi + +fi +INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a thread-safe mkdir -p" >&5 +$as_echo_n "checking for a thread-safe mkdir -p... " >&6; } +if test -z "$MKDIR_P"; then + if ${ac_cv_path_mkdir+:} false; then : + $as_echo_n "(cached) " >&6 +else + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/opt/sfw/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in mkdir gmkdir; do + for ac_exec_ext in '' $ac_executable_extensions; do + { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_test_x "$as_dir/$ac_prog$ac_exec_ext"; } || continue + case `"$as_dir/$ac_prog$ac_exec_ext" --version 2>&1` in #( + 'mkdir (GNU coreutils) '* | \ + 'mkdir (coreutils) '* | \ + 'mkdir (fileutils) '4.1*) + ac_cv_path_mkdir=$as_dir/$ac_prog$ac_exec_ext + break 3;; + esac + done + done + done +IFS=$as_save_IFS + +fi + + test -d ./--version && rmdir ./--version + if test "${ac_cv_path_mkdir+set}" = set; then + MKDIR_P="$ac_cv_path_mkdir -p" + else + # As a last resort, use the slow shell script. Don't cache a + # value for MKDIR_P within a source directory, because that will + # break other packages using the cache if that directory is + # removed, or if the value is a relative name. + MKDIR_P="$ac_install_sh -d" + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $MKDIR_P" >&5 +$as_echo "$MKDIR_P" >&6; } + +mkdir_p="$MKDIR_P" +case $mkdir_p in + [\\/$]* | ?:[\\/]*) ;; + */*) mkdir_p="\$(top_builddir)/$mkdir_p" ;; +esac + +for ac_prog in gawk mawk nawk awk +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_AWK+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$AWK"; then + ac_cv_prog_AWK="$AWK" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_AWK="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +AWK=$ac_cv_prog_AWK +if test -n "$AWK"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AWK" >&5 +$as_echo "$AWK" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$AWK" && break +done + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} sets \$(MAKE)" >&5 +$as_echo_n "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; } +set x ${MAKE-make} +ac_make=`$as_echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'` +if eval \${ac_cv_prog_make_${ac_make}_set+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat >conftest.make <<\_ACEOF +SHELL = /bin/sh +all: + @echo '@@@%%%=$(MAKE)=@@@%%%' +_ACEOF +# GNU make sometimes prints "make[1]: Entering ...", which would confuse us. +case `${MAKE-make} -f conftest.make 2>/dev/null` in + *@@@%%%=?*=@@@%%%*) + eval ac_cv_prog_make_${ac_make}_set=yes;; + *) + eval ac_cv_prog_make_${ac_make}_set=no;; +esac +rm -f conftest.make +fi +if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + SET_MAKE= +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + SET_MAKE="MAKE=${MAKE-make}" +fi + +rm -rf .tst 2>/dev/null +mkdir .tst 2>/dev/null +if test -d .tst; then + am__leading_dot=. +else + am__leading_dot=_ +fi +rmdir .tst 2>/dev/null + +if test "`cd $srcdir && pwd`" != "`pwd`"; then + # Use -I$(srcdir) only when $(srcdir) != ., so that make's output + # is not polluted with repeated "-I." + am__isrc=' -I$(srcdir)' + # test to see if srcdir already configured + if test -f $srcdir/config.status; then + as_fn_error $? "source directory already configured; run \"make distclean\" there first" "$LINENO" 5 + fi +fi + +# test whether we have cygpath +if test -z "$CYGPATH_W"; then + if (cygpath --version) >/dev/null 2>/dev/null; then + CYGPATH_W='cygpath -w' + else + CYGPATH_W=echo + fi +fi + + +# Define the identity of the package. + PACKAGE='yaml' + VERSION='0.1.6' + + +cat >>confdefs.h <<_ACEOF +#define PACKAGE "$PACKAGE" +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define VERSION "$VERSION" +_ACEOF + +# Some tools Automake needs. + +ACLOCAL=${ACLOCAL-"${am_missing_run}aclocal-${am__api_version}"} + + +AUTOCONF=${AUTOCONF-"${am_missing_run}autoconf"} + + +AUTOMAKE=${AUTOMAKE-"${am_missing_run}automake-${am__api_version}"} + + +AUTOHEADER=${AUTOHEADER-"${am_missing_run}autoheader"} + + +MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"} + +# We need awk for the "check" target. The system "awk" is bad on +# some platforms. +# Always define AMTAR for backward compatibility. Yes, it's still used +# in the wild :-( We should find a proper way to deprecate it ... +AMTAR='$${TAR-tar}' + +am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -' + + + + + + +# Define macro variables for the package version numbers. + +$as_echo "#define YAML_VERSION_MAJOR 0" >>confdefs.h + + +$as_echo "#define YAML_VERSION_MINOR 1" >>confdefs.h + + +$as_echo "#define YAML_VERSION_PATCH 6" >>confdefs.h + + +$as_echo "#define YAML_VERSION_STRING \"0.1.6\"" >>confdefs.h + + +# Define substitutions for the libtool version numbers. +YAML_LT_RELEASE=0 +YAML_LT_CURRENT=2 +YAML_LT_REVISION=4 +YAML_LT_AGE=0 + + + + + +# Note: in order to update checks, run `autoscan` and look through "configure.scan". + +# Checks for programs. +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. +set dummy ${ac_tool_prefix}gcc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_CC="${ac_tool_prefix}gcc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_CC"; then + ac_ct_CC=$CC + # Extract the first word of "gcc", so it can be a program name with args. +set dummy gcc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_CC="gcc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 +$as_echo "$ac_ct_CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_CC" = x; then + CC="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + CC=$ac_ct_CC + fi +else + CC="$ac_cv_prog_CC" +fi + +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. +set dummy ${ac_tool_prefix}cc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_CC="${ac_tool_prefix}cc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + fi +fi +if test -z "$CC"; then + # Extract the first word of "cc", so it can be a program name with args. +set dummy cc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + ac_prog_rejected=no +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then + ac_prog_rejected=yes + continue + fi + ac_cv_prog_CC="cc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +if test $ac_prog_rejected = yes; then + # We found a bogon in the path, so make sure we never use it. + set dummy $ac_cv_prog_CC + shift + if test $# != 0; then + # We chose a different compiler from the bogus one. + # However, it has the same basename, so the bogon will be chosen + # first if we set CC to just the basename; use the full file name. + shift + ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" + fi +fi +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + for ac_prog in cl.exe + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_CC="$ac_tool_prefix$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$CC" && break + done +fi +if test -z "$CC"; then + ac_ct_CC=$CC + for ac_prog in cl.exe +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_CC="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 +$as_echo "$ac_ct_CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$ac_ct_CC" && break +done + + if test "x$ac_ct_CC" = x; then + CC="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + CC=$ac_ct_CC + fi +fi + +fi + + +test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "no acceptable C compiler found in \$PATH +See \`config.log' for more details" "$LINENO" 5; } + +# Provide some information about the compiler. +$as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5 +set X $ac_compile +ac_compiler=$2 +for ac_option in --version -v -V -qversion; do + { { ac_try="$ac_compiler $ac_option >&5" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compiler $ac_option >&5") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + sed '10a\ +... rest of stderr output deleted ... + 10q' conftest.err >conftest.er1 + cat conftest.er1 >&5 + fi + rm -f conftest.er1 conftest.err + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } +done + +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +ac_clean_files_save=$ac_clean_files +ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out" +# Try to create an executable without -o first, disregard a.out. +# It will help us diagnose broken compilers, and finding out an intuition +# of exeext. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler works" >&5 +$as_echo_n "checking whether the C compiler works... " >&6; } +ac_link_default=`$as_echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` + +# The possible output files: +ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*" + +ac_rmfiles= +for ac_file in $ac_files +do + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; + * ) ac_rmfiles="$ac_rmfiles $ac_file";; + esac +done +rm -f $ac_rmfiles + +if { { ac_try="$ac_link_default" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link_default") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then : + # Autoconf-2.13 could set the ac_cv_exeext variable to `no'. +# So ignore a value of `no', otherwise this would lead to `EXEEXT = no' +# in a Makefile. We should not override ac_cv_exeext if it was cached, +# so that the user can short-circuit this test for compilers unknown to +# Autoconf. +for ac_file in $ac_files '' +do + test -f "$ac_file" || continue + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) + ;; + [ab].out ) + # We found the default executable, but exeext='' is most + # certainly right. + break;; + *.* ) + if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no; + then :; else + ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` + fi + # We set ac_cv_exeext here because the later test for it is not + # safe: cross compilers may not add the suffix if given an `-o' + # argument, so we may need to know it at that point already. + # Even if this section looks crufty: it has the advantage of + # actually working. + break;; + * ) + break;; + esac +done +test "$ac_cv_exeext" = no && ac_cv_exeext= + +else + ac_file='' +fi +if test -z "$ac_file"; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +$as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error 77 "C compiler cannot create executables +See \`config.log' for more details" "$LINENO" 5; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler default output file name" >&5 +$as_echo_n "checking for C compiler default output file name... " >&6; } +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5 +$as_echo "$ac_file" >&6; } +ac_exeext=$ac_cv_exeext + +rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out +ac_clean_files=$ac_clean_files_save +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5 +$as_echo_n "checking for suffix of executables... " >&6; } +if { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then : + # If both `conftest.exe' and `conftest' are `present' (well, observable) +# catch `conftest.exe'. For instance with Cygwin, `ls conftest' will +# work properly (i.e., refer to `conftest.exe'), while it won't with +# `rm'. +for ac_file in conftest.exe conftest conftest.*; do + test -f "$ac_file" || continue + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; + *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` + break;; + * ) break;; + esac +done +else + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "cannot compute suffix of executables: cannot compile and link +See \`config.log' for more details" "$LINENO" 5; } +fi +rm -f conftest conftest$ac_cv_exeext +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5 +$as_echo "$ac_cv_exeext" >&6; } + +rm -f conftest.$ac_ext +EXEEXT=$ac_cv_exeext +ac_exeext=$EXEEXT +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +int +main () +{ +FILE *f = fopen ("conftest.out", "w"); + return ferror (f) || fclose (f) != 0; + + ; + return 0; +} +_ACEOF +ac_clean_files="$ac_clean_files conftest.out" +# Check that the compiler produces executables we can run. If not, either +# the compiler is broken, or we cross compile. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5 +$as_echo_n "checking whether we are cross compiling... " >&6; } +if test "$cross_compiling" != yes; then + { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } + if { ac_try='./conftest$ac_cv_exeext' + { { case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; }; then + cross_compiling=no + else + if test "$cross_compiling" = maybe; then + cross_compiling=yes + else + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "cannot run C compiled programs. +If you meant to cross compile, use \`--host'. +See \`config.log' for more details" "$LINENO" 5; } + fi + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5 +$as_echo "$cross_compiling" >&6; } + +rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out +ac_clean_files=$ac_clean_files_save +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5 +$as_echo_n "checking for suffix of object files... " >&6; } +if ${ac_cv_objext+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.o conftest.obj +if { { ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compile") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then : + for ac_file in conftest.o conftest.obj conftest.*; do + test -f "$ac_file" || continue; + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;; + *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` + break;; + esac +done +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "cannot compute suffix of object files: cannot compile +See \`config.log' for more details" "$LINENO" 5; } +fi +rm -f conftest.$ac_cv_objext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5 +$as_echo "$ac_cv_objext" >&6; } +OBJEXT=$ac_cv_objext +ac_objext=$OBJEXT +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5 +$as_echo_n "checking whether we are using the GNU C compiler... " >&6; } +if ${ac_cv_c_compiler_gnu+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ +#ifndef __GNUC__ + choke me +#endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_compiler_gnu=yes +else + ac_compiler_gnu=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +ac_cv_c_compiler_gnu=$ac_compiler_gnu + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5 +$as_echo "$ac_cv_c_compiler_gnu" >&6; } +if test $ac_compiler_gnu = yes; then + GCC=yes +else + GCC= +fi +ac_test_CFLAGS=${CFLAGS+set} +ac_save_CFLAGS=$CFLAGS +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5 +$as_echo_n "checking whether $CC accepts -g... " >&6; } +if ${ac_cv_prog_cc_g+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_save_c_werror_flag=$ac_c_werror_flag + ac_c_werror_flag=yes + ac_cv_prog_cc_g=no + CFLAGS="-g" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_prog_cc_g=yes +else + CFLAGS="" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + +else + ac_c_werror_flag=$ac_save_c_werror_flag + CFLAGS="-g" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_prog_cc_g=yes +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ac_c_werror_flag=$ac_save_c_werror_flag +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5 +$as_echo "$ac_cv_prog_cc_g" >&6; } +if test "$ac_test_CFLAGS" = set; then + CFLAGS=$ac_save_CFLAGS +elif test $ac_cv_prog_cc_g = yes; then + if test "$GCC" = yes; then + CFLAGS="-g -O2" + else + CFLAGS="-g" + fi +else + if test "$GCC" = yes; then + CFLAGS="-O2" + else + CFLAGS= + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5 +$as_echo_n "checking for $CC option to accept ISO C89... " >&6; } +if ${ac_cv_prog_cc_c89+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_cv_prog_cc_c89=no +ac_save_CC=$CC +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +#include +#include +#include +/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ +struct buf { int x; }; +FILE * (*rcsopen) (struct buf *, struct stat *, int); +static char *e (p, i) + char **p; + int i; +{ + return p[i]; +} +static char *f (char * (*g) (char **, int), char **p, ...) +{ + char *s; + va_list v; + va_start (v,p); + s = g (p, va_arg (v,int)); + va_end (v); + return s; +} + +/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has + function prototypes and stuff, but not '\xHH' hex character constants. + These don't provoke an error unfortunately, instead are silently treated + as 'x'. The following induces an error, until -std is added to get + proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an + array size at least. It's necessary to write '\x00'==0 to get something + that's true only with -std. */ +int osf4_cc_array ['\x00' == 0 ? 1 : -1]; + +/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters + inside strings and character constants. */ +#define FOO(x) 'x' +int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1]; + +int test (int i, double x); +struct s1 {int (*f) (int a);}; +struct s2 {int (*f) (double a);}; +int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); +int argc; +char **argv; +int +main () +{ +return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; + ; + return 0; +} +_ACEOF +for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \ + -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" +do + CC="$ac_save_CC $ac_arg" + if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_prog_cc_c89=$ac_arg +fi +rm -f core conftest.err conftest.$ac_objext + test "x$ac_cv_prog_cc_c89" != "xno" && break +done +rm -f conftest.$ac_ext +CC=$ac_save_CC + +fi +# AC_CACHE_VAL +case "x$ac_cv_prog_cc_c89" in + x) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 +$as_echo "none needed" >&6; } ;; + xno) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 +$as_echo "unsupported" >&6; } ;; + *) + CC="$CC $ac_cv_prog_cc_c89" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5 +$as_echo "$ac_cv_prog_cc_c89" >&6; } ;; +esac +if test "x$ac_cv_prog_cc_c89" != xno; then : + +fi + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +DEPDIR="${am__leading_dot}deps" + +ac_config_commands="$ac_config_commands depfiles" + + +am_make=${MAKE-make} +cat > confinc << 'END' +am__doit: + @echo this is the am__doit target +.PHONY: am__doit +END +# If we don't find an include directive, just comment out the code. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for style of include used by $am_make" >&5 +$as_echo_n "checking for style of include used by $am_make... " >&6; } +am__include="#" +am__quote= +_am_result=none +# First try GNU make style include. +echo "include confinc" > confmf +# Ignore all kinds of additional output from `make'. +case `$am_make -s -f confmf 2> /dev/null` in #( +*the\ am__doit\ target*) + am__include=include + am__quote= + _am_result=GNU + ;; +esac +# Now try BSD make style include. +if test "$am__include" = "#"; then + echo '.include "confinc"' > confmf + case `$am_make -s -f confmf 2> /dev/null` in #( + *the\ am__doit\ target*) + am__include=.include + am__quote="\"" + _am_result=BSD + ;; + esac +fi + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $_am_result" >&5 +$as_echo "$_am_result" >&6; } +rm -f confinc confmf + +# Check whether --enable-dependency-tracking was given. +if test "${enable_dependency_tracking+set}" = set; then : + enableval=$enable_dependency_tracking; +fi + +if test "x$enable_dependency_tracking" != xno; then + am_depcomp="$ac_aux_dir/depcomp" + AMDEPBACKSLASH='\' + am__nodep='_no' +fi + if test "x$enable_dependency_tracking" != xno; then + AMDEP_TRUE= + AMDEP_FALSE='#' +else + AMDEP_TRUE='#' + AMDEP_FALSE= +fi + + + +depcc="$CC" am_compiler_list= + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5 +$as_echo_n "checking dependency style of $depcc... " >&6; } +if ${am_cv_CC_dependencies_compiler_type+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then + # We make a subdir and do the tests there. Otherwise we can end up + # making bogus files that we don't know about and never remove. For + # instance it was reported that on HP-UX the gcc test will end up + # making a dummy file named `D' -- because `-MD' means `put the output + # in D'. + rm -rf conftest.dir + mkdir conftest.dir + # Copy depcomp to subdir because otherwise we won't find it if we're + # using a relative directory. + cp "$am_depcomp" conftest.dir + cd conftest.dir + # We will build objects and dependencies in a subdirectory because + # it helps to detect inapplicable dependency modes. For instance + # both Tru64's cc and ICC support -MD to output dependencies as a + # side effect of compilation, but ICC will put the dependencies in + # the current directory while Tru64 will put them in the object + # directory. + mkdir sub + + am_cv_CC_dependencies_compiler_type=none + if test "$am_compiler_list" = ""; then + am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` + fi + am__universal=false + case " $depcc " in #( + *\ -arch\ *\ -arch\ *) am__universal=true ;; + esac + + for depmode in $am_compiler_list; do + # Setup a source with many dependencies, because some compilers + # like to wrap large dependency lists on column 80 (with \), and + # we should not choose a depcomp mode which is confused by this. + # + # We need to recreate these files for each test, as the compiler may + # overwrite some of them when testing with obscure command lines. + # This happens at least with the AIX C compiler. + : > sub/conftest.c + for i in 1 2 3 4 5 6; do + echo '#include "conftst'$i'.h"' >> sub/conftest.c + # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with + # Solaris 8's {/usr,}/bin/sh. + touch sub/conftst$i.h + done + echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf + + # We check with `-c' and `-o' for the sake of the "dashmstdout" + # mode. It turns out that the SunPro C++ compiler does not properly + # handle `-M -o', and we need to detect this. Also, some Intel + # versions had trouble with output in subdirs + am__obj=sub/conftest.${OBJEXT-o} + am__minus_obj="-o $am__obj" + case $depmode in + gcc) + # This depmode causes a compiler race in universal mode. + test "$am__universal" = false || continue + ;; + nosideeffect) + # after this tag, mechanisms are not by side-effect, so they'll + # only be used when explicitly requested + if test "x$enable_dependency_tracking" = xyes; then + continue + else + break + fi + ;; + msvc7 | msvc7msys | msvisualcpp | msvcmsys) + # This compiler won't grok `-c -o', but also, the minuso test has + # not run yet. These depmodes are late enough in the game, and + # so weak that their functioning should not be impacted. + am__obj=conftest.${OBJEXT-o} + am__minus_obj= + ;; + none) break ;; + esac + if depmode=$depmode \ + source=sub/conftest.c object=$am__obj \ + depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ + $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ + >/dev/null 2>conftest.err && + grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && + grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && + grep $am__obj sub/conftest.Po > /dev/null 2>&1 && + ${MAKE-make} -s -f confmf > /dev/null 2>&1; then + # icc doesn't choke on unknown options, it will just issue warnings + # or remarks (even with -Werror). So we grep stderr for any message + # that says an option was ignored or not supported. + # When given -MP, icc 7.0 and 7.1 complain thusly: + # icc: Command line warning: ignoring option '-M'; no argument required + # The diagnosis changed in icc 8.0: + # icc: Command line remark: option '-MP' not supported + if (grep 'ignoring option' conftest.err || + grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else + am_cv_CC_dependencies_compiler_type=$depmode + break + fi + fi + done + + cd .. + rm -rf conftest.dir +else + am_cv_CC_dependencies_compiler_type=none +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_CC_dependencies_compiler_type" >&5 +$as_echo "$am_cv_CC_dependencies_compiler_type" >&6; } +CCDEPMODE=depmode=$am_cv_CC_dependencies_compiler_type + + if + test "x$enable_dependency_tracking" != xno \ + && test "$am_cv_CC_dependencies_compiler_type" = gcc3; then + am__fastdepCC_TRUE= + am__fastdepCC_FALSE='#' +else + am__fastdepCC_TRUE='#' + am__fastdepCC_FALSE= +fi + + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5 +$as_echo_n "checking how to run the C preprocessor... " >&6; } +# On Suns, sometimes $CPP names a directory. +if test -n "$CPP" && test -d "$CPP"; then + CPP= +fi +if test -z "$CPP"; then + if ${ac_cv_prog_CPP+:} false; then : + $as_echo_n "(cached) " >&6 +else + # Double quotes because CPP needs to be expanded + for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp" + do + ac_preproc_ok=false +for ac_c_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer to if __STDC__ is defined, since + # exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#ifdef __STDC__ +# include +#else +# include +#endif + Syntax error +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + +else + # Broken: fails on valid input. +continue +fi +rm -f conftest.err conftest.i conftest.$ac_ext + + # OK, works on sane cases. Now check whether nonexistent headers + # can be detected and how. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + # Broken: success on invalid input. +continue +else + # Passes both tests. +ac_preproc_ok=: +break +fi +rm -f conftest.err conftest.i conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.i conftest.err conftest.$ac_ext +if $ac_preproc_ok; then : + break +fi + + done + ac_cv_prog_CPP=$CPP + +fi + CPP=$ac_cv_prog_CPP +else + ac_cv_prog_CPP=$CPP +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5 +$as_echo "$CPP" >&6; } +ac_preproc_ok=false +for ac_c_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer to if __STDC__ is defined, since + # exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#ifdef __STDC__ +# include +#else +# include +#endif + Syntax error +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + +else + # Broken: fails on valid input. +continue +fi +rm -f conftest.err conftest.i conftest.$ac_ext + + # OK, works on sane cases. Now check whether nonexistent headers + # can be detected and how. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + # Broken: success on invalid input. +continue +else + # Passes both tests. +ac_preproc_ok=: +break +fi +rm -f conftest.err conftest.i conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.i conftest.err conftest.$ac_ext +if $ac_preproc_ok; then : + +else + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "C preprocessor \"$CPP\" fails sanity check +See \`config.log' for more details" "$LINENO" 5; } +fi + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ln -s works" >&5 +$as_echo_n "checking whether ln -s works... " >&6; } +LN_S=$as_ln_s +if test "$LN_S" = "ln -s"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no, using $LN_S" >&5 +$as_echo "no, using $LN_S" >&6; } +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} sets \$(MAKE)" >&5 +$as_echo_n "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; } +set x ${MAKE-make} +ac_make=`$as_echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'` +if eval \${ac_cv_prog_make_${ac_make}_set+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat >conftest.make <<\_ACEOF +SHELL = /bin/sh +all: + @echo '@@@%%%=$(MAKE)=@@@%%%' +_ACEOF +# GNU make sometimes prints "make[1]: Entering ...", which would confuse us. +case `${MAKE-make} -f conftest.make 2>/dev/null` in + *@@@%%%=?*=@@@%%%*) + eval ac_cv_prog_make_${ac_make}_set=yes;; + *) + eval ac_cv_prog_make_${ac_make}_set=no;; +esac +rm -f conftest.make +fi +if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + SET_MAKE= +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + SET_MAKE="MAKE=${MAKE-make}" +fi + +case `pwd` in + *\ * | *\ *) + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&5 +$as_echo "$as_me: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&2;} ;; +esac + + + +macro_version='2.4.2' +macro_revision='1.3337' + + + + + + + + + + + + + +ltmain="$ac_aux_dir/ltmain.sh" + +# Make sure we can run config.sub. +$SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 || + as_fn_error $? "cannot run $SHELL $ac_aux_dir/config.sub" "$LINENO" 5 + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking build system type" >&5 +$as_echo_n "checking build system type... " >&6; } +if ${ac_cv_build+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_build_alias=$build_alias +test "x$ac_build_alias" = x && + ac_build_alias=`$SHELL "$ac_aux_dir/config.guess"` +test "x$ac_build_alias" = x && + as_fn_error $? "cannot guess build type; you must specify one" "$LINENO" 5 +ac_cv_build=`$SHELL "$ac_aux_dir/config.sub" $ac_build_alias` || + as_fn_error $? "$SHELL $ac_aux_dir/config.sub $ac_build_alias failed" "$LINENO" 5 + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_build" >&5 +$as_echo "$ac_cv_build" >&6; } +case $ac_cv_build in +*-*-*) ;; +*) as_fn_error $? "invalid value of canonical build" "$LINENO" 5;; +esac +build=$ac_cv_build +ac_save_IFS=$IFS; IFS='-' +set x $ac_cv_build +shift +build_cpu=$1 +build_vendor=$2 +shift; shift +# Remember, the first character of IFS is used to create $*, +# except with old shells: +build_os=$* +IFS=$ac_save_IFS +case $build_os in *\ *) build_os=`echo "$build_os" | sed 's/ /-/g'`;; esac + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking host system type" >&5 +$as_echo_n "checking host system type... " >&6; } +if ${ac_cv_host+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test "x$host_alias" = x; then + ac_cv_host=$ac_cv_build +else + ac_cv_host=`$SHELL "$ac_aux_dir/config.sub" $host_alias` || + as_fn_error $? "$SHELL $ac_aux_dir/config.sub $host_alias failed" "$LINENO" 5 +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_host" >&5 +$as_echo "$ac_cv_host" >&6; } +case $ac_cv_host in +*-*-*) ;; +*) as_fn_error $? "invalid value of canonical host" "$LINENO" 5;; +esac +host=$ac_cv_host +ac_save_IFS=$IFS; IFS='-' +set x $ac_cv_host +shift +host_cpu=$1 +host_vendor=$2 +shift; shift +# Remember, the first character of IFS is used to create $*, +# except with old shells: +host_os=$* +IFS=$ac_save_IFS +case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac + + +# Backslashify metacharacters that are still active within +# double-quoted strings. +sed_quote_subst='s/\(["`$\\]\)/\\\1/g' + +# Same as above, but do not quote variable references. +double_quote_subst='s/\(["`\\]\)/\\\1/g' + +# Sed substitution to delay expansion of an escaped shell variable in a +# double_quote_subst'ed string. +delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g' + +# Sed substitution to delay expansion of an escaped single quote. +delay_single_quote_subst='s/'\''/'\'\\\\\\\'\''/g' + +# Sed substitution to avoid accidental globbing in evaled expressions +no_glob_subst='s/\*/\\\*/g' + +ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' +ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO +ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to print strings" >&5 +$as_echo_n "checking how to print strings... " >&6; } +# Test print first, because it will be a builtin if present. +if test "X`( print -r -- -n ) 2>/dev/null`" = X-n && \ + test "X`print -r -- $ECHO 2>/dev/null`" = "X$ECHO"; then + ECHO='print -r --' +elif test "X`printf %s $ECHO 2>/dev/null`" = "X$ECHO"; then + ECHO='printf %s\n' +else + # Use this function as a fallback that always works. + func_fallback_echo () + { + eval 'cat <<_LTECHO_EOF +$1 +_LTECHO_EOF' + } + ECHO='func_fallback_echo' +fi + +# func_echo_all arg... +# Invoke $ECHO with all args, space-separated. +func_echo_all () +{ + $ECHO "" +} + +case "$ECHO" in + printf*) { $as_echo "$as_me:${as_lineno-$LINENO}: result: printf" >&5 +$as_echo "printf" >&6; } ;; + print*) { $as_echo "$as_me:${as_lineno-$LINENO}: result: print -r" >&5 +$as_echo "print -r" >&6; } ;; + *) { $as_echo "$as_me:${as_lineno-$LINENO}: result: cat" >&5 +$as_echo "cat" >&6; } ;; +esac + + + + + + + + + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a sed that does not truncate output" >&5 +$as_echo_n "checking for a sed that does not truncate output... " >&6; } +if ${ac_cv_path_SED+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_script=s/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb/ + for ac_i in 1 2 3 4 5 6 7; do + ac_script="$ac_script$as_nl$ac_script" + done + echo "$ac_script" 2>/dev/null | sed 99q >conftest.sed + { ac_script=; unset ac_script;} + if test -z "$SED"; then + ac_path_SED_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in sed gsed; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_SED="$as_dir/$ac_prog$ac_exec_ext" + { test -f "$ac_path_SED" && $as_test_x "$ac_path_SED"; } || continue +# Check for GNU ac_path_SED and select it if it is found. + # Check for GNU $ac_path_SED +case `"$ac_path_SED" --version 2>&1` in +*GNU*) + ac_cv_path_SED="$ac_path_SED" ac_path_SED_found=:;; +*) + ac_count=0 + $as_echo_n 0123456789 >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + $as_echo '' >> "conftest.nl" + "$ac_path_SED" -f conftest.sed < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + as_fn_arith $ac_count + 1 && ac_count=$as_val + if test $ac_count -gt ${ac_path_SED_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_SED="$ac_path_SED" + ac_path_SED_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + $ac_path_SED_found && break 3 + done + done + done +IFS=$as_save_IFS + if test -z "$ac_cv_path_SED"; then + as_fn_error $? "no acceptable sed could be found in \$PATH" "$LINENO" 5 + fi +else + ac_cv_path_SED=$SED +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_SED" >&5 +$as_echo "$ac_cv_path_SED" >&6; } + SED="$ac_cv_path_SED" + rm -f conftest.sed + +test -z "$SED" && SED=sed +Xsed="$SED -e 1s/^X//" + + + + + + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5 +$as_echo_n "checking for grep that handles long lines and -e... " >&6; } +if ${ac_cv_path_GREP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -z "$GREP"; then + ac_path_GREP_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in grep ggrep; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext" + { test -f "$ac_path_GREP" && $as_test_x "$ac_path_GREP"; } || continue +# Check for GNU ac_path_GREP and select it if it is found. + # Check for GNU $ac_path_GREP +case `"$ac_path_GREP" --version 2>&1` in +*GNU*) + ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;; +*) + ac_count=0 + $as_echo_n 0123456789 >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + $as_echo 'GREP' >> "conftest.nl" + "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + as_fn_arith $ac_count + 1 && ac_count=$as_val + if test $ac_count -gt ${ac_path_GREP_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_GREP="$ac_path_GREP" + ac_path_GREP_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + $ac_path_GREP_found && break 3 + done + done + done +IFS=$as_save_IFS + if test -z "$ac_cv_path_GREP"; then + as_fn_error $? "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 + fi +else + ac_cv_path_GREP=$GREP +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5 +$as_echo "$ac_cv_path_GREP" >&6; } + GREP="$ac_cv_path_GREP" + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5 +$as_echo_n "checking for egrep... " >&6; } +if ${ac_cv_path_EGREP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if echo a | $GREP -E '(a|b)' >/dev/null 2>&1 + then ac_cv_path_EGREP="$GREP -E" + else + if test -z "$EGREP"; then + ac_path_EGREP_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in egrep; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext" + { test -f "$ac_path_EGREP" && $as_test_x "$ac_path_EGREP"; } || continue +# Check for GNU ac_path_EGREP and select it if it is found. + # Check for GNU $ac_path_EGREP +case `"$ac_path_EGREP" --version 2>&1` in +*GNU*) + ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;; +*) + ac_count=0 + $as_echo_n 0123456789 >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + $as_echo 'EGREP' >> "conftest.nl" + "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + as_fn_arith $ac_count + 1 && ac_count=$as_val + if test $ac_count -gt ${ac_path_EGREP_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_EGREP="$ac_path_EGREP" + ac_path_EGREP_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + $ac_path_EGREP_found && break 3 + done + done + done +IFS=$as_save_IFS + if test -z "$ac_cv_path_EGREP"; then + as_fn_error $? "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 + fi +else + ac_cv_path_EGREP=$EGREP +fi + + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5 +$as_echo "$ac_cv_path_EGREP" >&6; } + EGREP="$ac_cv_path_EGREP" + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for fgrep" >&5 +$as_echo_n "checking for fgrep... " >&6; } +if ${ac_cv_path_FGREP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if echo 'ab*c' | $GREP -F 'ab*c' >/dev/null 2>&1 + then ac_cv_path_FGREP="$GREP -F" + else + if test -z "$FGREP"; then + ac_path_FGREP_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in fgrep; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_FGREP="$as_dir/$ac_prog$ac_exec_ext" + { test -f "$ac_path_FGREP" && $as_test_x "$ac_path_FGREP"; } || continue +# Check for GNU ac_path_FGREP and select it if it is found. + # Check for GNU $ac_path_FGREP +case `"$ac_path_FGREP" --version 2>&1` in +*GNU*) + ac_cv_path_FGREP="$ac_path_FGREP" ac_path_FGREP_found=:;; +*) + ac_count=0 + $as_echo_n 0123456789 >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + $as_echo 'FGREP' >> "conftest.nl" + "$ac_path_FGREP" FGREP < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + as_fn_arith $ac_count + 1 && ac_count=$as_val + if test $ac_count -gt ${ac_path_FGREP_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_FGREP="$ac_path_FGREP" + ac_path_FGREP_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + $ac_path_FGREP_found && break 3 + done + done + done +IFS=$as_save_IFS + if test -z "$ac_cv_path_FGREP"; then + as_fn_error $? "no acceptable fgrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 + fi +else + ac_cv_path_FGREP=$FGREP +fi + + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_FGREP" >&5 +$as_echo "$ac_cv_path_FGREP" >&6; } + FGREP="$ac_cv_path_FGREP" + + +test -z "$GREP" && GREP=grep + + + + + + + + + + + + + + + + + + + +# Check whether --with-gnu-ld was given. +if test "${with_gnu_ld+set}" = set; then : + withval=$with_gnu_ld; test "$withval" = no || with_gnu_ld=yes +else + with_gnu_ld=no +fi + +ac_prog=ld +if test "$GCC" = yes; then + # Check if gcc -print-prog-name=ld gives a path. + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ld used by $CC" >&5 +$as_echo_n "checking for ld used by $CC... " >&6; } + case $host in + *-*-mingw*) + # gcc leaves a trailing carriage return which upsets mingw + ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; + *) + ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; + esac + case $ac_prog in + # Accept absolute paths. + [\\/]* | ?:[\\/]*) + re_direlt='/[^/][^/]*/\.\./' + # Canonicalize the pathname of ld + ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'` + while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do + ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"` + done + test -z "$LD" && LD="$ac_prog" + ;; + "") + # If it fails, then pretend we aren't using GCC. + ac_prog=ld + ;; + *) + # If it is relative, then search for the first ld in PATH. + with_gnu_ld=unknown + ;; + esac +elif test "$with_gnu_ld" = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GNU ld" >&5 +$as_echo_n "checking for GNU ld... " >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for non-GNU ld" >&5 +$as_echo_n "checking for non-GNU ld... " >&6; } +fi +if ${lt_cv_path_LD+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -z "$LD"; then + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + for ac_dir in $PATH; do + IFS="$lt_save_ifs" + test -z "$ac_dir" && ac_dir=. + if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then + lt_cv_path_LD="$ac_dir/$ac_prog" + # Check to see if the program is GNU ld. I'd rather use --version, + # but apparently some variants of GNU ld only accept -v. + # Break only if it was the GNU/non-GNU ld that we prefer. + case `"$lt_cv_path_LD" -v 2>&1 &5 +$as_echo "$LD" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi +test -z "$LD" && as_fn_error $? "no acceptable ld found in \$PATH" "$LINENO" 5 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if the linker ($LD) is GNU ld" >&5 +$as_echo_n "checking if the linker ($LD) is GNU ld... " >&6; } +if ${lt_cv_prog_gnu_ld+:} false; then : + $as_echo_n "(cached) " >&6 +else + # I'd rather use --version here, but apparently some GNU lds only accept -v. +case `$LD -v 2>&1 &5 +$as_echo "$lt_cv_prog_gnu_ld" >&6; } +with_gnu_ld=$lt_cv_prog_gnu_ld + + + + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for BSD- or MS-compatible name lister (nm)" >&5 +$as_echo_n "checking for BSD- or MS-compatible name lister (nm)... " >&6; } +if ${lt_cv_path_NM+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$NM"; then + # Let the user override the test. + lt_cv_path_NM="$NM" +else + lt_nm_to_check="${ac_tool_prefix}nm" + if test -n "$ac_tool_prefix" && test "$build" = "$host"; then + lt_nm_to_check="$lt_nm_to_check nm" + fi + for lt_tmp_nm in $lt_nm_to_check; do + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do + IFS="$lt_save_ifs" + test -z "$ac_dir" && ac_dir=. + tmp_nm="$ac_dir/$lt_tmp_nm" + if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext" ; then + # Check to see if the nm accepts a BSD-compat flag. + # Adding the `sed 1q' prevents false positives on HP-UX, which says: + # nm: unknown option "B" ignored + # Tru64's nm complains that /dev/null is an invalid object file + case `"$tmp_nm" -B /dev/null 2>&1 | sed '1q'` in + */dev/null* | *'Invalid file or object type'*) + lt_cv_path_NM="$tmp_nm -B" + break + ;; + *) + case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in + */dev/null*) + lt_cv_path_NM="$tmp_nm -p" + break + ;; + *) + lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but + continue # so that we can try to find one that supports BSD flags + ;; + esac + ;; + esac + fi + done + IFS="$lt_save_ifs" + done + : ${lt_cv_path_NM=no} +fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_path_NM" >&5 +$as_echo "$lt_cv_path_NM" >&6; } +if test "$lt_cv_path_NM" != "no"; then + NM="$lt_cv_path_NM" +else + # Didn't find any BSD compatible name lister, look for dumpbin. + if test -n "$DUMPBIN"; then : + # Let the user override the test. + else + if test -n "$ac_tool_prefix"; then + for ac_prog in dumpbin "link -dump" + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_DUMPBIN+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$DUMPBIN"; then + ac_cv_prog_DUMPBIN="$DUMPBIN" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_DUMPBIN="$ac_tool_prefix$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +DUMPBIN=$ac_cv_prog_DUMPBIN +if test -n "$DUMPBIN"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DUMPBIN" >&5 +$as_echo "$DUMPBIN" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$DUMPBIN" && break + done +fi +if test -z "$DUMPBIN"; then + ac_ct_DUMPBIN=$DUMPBIN + for ac_prog in dumpbin "link -dump" +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_DUMPBIN+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_DUMPBIN"; then + ac_cv_prog_ac_ct_DUMPBIN="$ac_ct_DUMPBIN" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_DUMPBIN="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_DUMPBIN=$ac_cv_prog_ac_ct_DUMPBIN +if test -n "$ac_ct_DUMPBIN"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DUMPBIN" >&5 +$as_echo "$ac_ct_DUMPBIN" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$ac_ct_DUMPBIN" && break +done + + if test "x$ac_ct_DUMPBIN" = x; then + DUMPBIN=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + DUMPBIN=$ac_ct_DUMPBIN + fi +fi + + case `$DUMPBIN -symbols /dev/null 2>&1 | sed '1q'` in + *COFF*) + DUMPBIN="$DUMPBIN -symbols" + ;; + *) + DUMPBIN=: + ;; + esac + fi + + if test "$DUMPBIN" != ":"; then + NM="$DUMPBIN" + fi +fi +test -z "$NM" && NM=nm + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking the name lister ($NM) interface" >&5 +$as_echo_n "checking the name lister ($NM) interface... " >&6; } +if ${lt_cv_nm_interface+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_nm_interface="BSD nm" + echo "int some_variable = 0;" > conftest.$ac_ext + (eval echo "\"\$as_me:$LINENO: $ac_compile\"" >&5) + (eval "$ac_compile" 2>conftest.err) + cat conftest.err >&5 + (eval echo "\"\$as_me:$LINENO: $NM \\\"conftest.$ac_objext\\\"\"" >&5) + (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out) + cat conftest.err >&5 + (eval echo "\"\$as_me:$LINENO: output\"" >&5) + cat conftest.out >&5 + if $GREP 'External.*some_variable' conftest.out > /dev/null; then + lt_cv_nm_interface="MS dumpbin" + fi + rm -f conftest* +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_nm_interface" >&5 +$as_echo "$lt_cv_nm_interface" >&6; } + +# find the maximum length of command line arguments +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking the maximum length of command line arguments" >&5 +$as_echo_n "checking the maximum length of command line arguments... " >&6; } +if ${lt_cv_sys_max_cmd_len+:} false; then : + $as_echo_n "(cached) " >&6 +else + i=0 + teststring="ABCD" + + case $build_os in + msdosdjgpp*) + # On DJGPP, this test can blow up pretty badly due to problems in libc + # (any single argument exceeding 2000 bytes causes a buffer overrun + # during glob expansion). Even if it were fixed, the result of this + # check would be larger than it should be. + lt_cv_sys_max_cmd_len=12288; # 12K is about right + ;; + + gnu*) + # Under GNU Hurd, this test is not required because there is + # no limit to the length of command line arguments. + # Libtool will interpret -1 as no limit whatsoever + lt_cv_sys_max_cmd_len=-1; + ;; + + cygwin* | mingw* | cegcc*) + # On Win9x/ME, this test blows up -- it succeeds, but takes + # about 5 minutes as the teststring grows exponentially. + # Worse, since 9x/ME are not pre-emptively multitasking, + # you end up with a "frozen" computer, even though with patience + # the test eventually succeeds (with a max line length of 256k). + # Instead, let's just punt: use the minimum linelength reported by + # all of the supported platforms: 8192 (on NT/2K/XP). + lt_cv_sys_max_cmd_len=8192; + ;; + + mint*) + # On MiNT this can take a long time and run out of memory. + lt_cv_sys_max_cmd_len=8192; + ;; + + amigaos*) + # On AmigaOS with pdksh, this test takes hours, literally. + # So we just punt and use a minimum line length of 8192. + lt_cv_sys_max_cmd_len=8192; + ;; + + netbsd* | freebsd* | openbsd* | darwin* | dragonfly*) + # This has been around since 386BSD, at least. Likely further. + if test -x /sbin/sysctl; then + lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax` + elif test -x /usr/sbin/sysctl; then + lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax` + else + lt_cv_sys_max_cmd_len=65536 # usable default for all BSDs + fi + # And add a safety zone + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` + ;; + + interix*) + # We know the value 262144 and hardcode it with a safety zone (like BSD) + lt_cv_sys_max_cmd_len=196608 + ;; + + os2*) + # The test takes a long time on OS/2. + lt_cv_sys_max_cmd_len=8192 + ;; + + osf*) + # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure + # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not + # nice to cause kernel panics so lets avoid the loop below. + # First set a reasonable default. + lt_cv_sys_max_cmd_len=16384 + # + if test -x /sbin/sysconfig; then + case `/sbin/sysconfig -q proc exec_disable_arg_limit` in + *1*) lt_cv_sys_max_cmd_len=-1 ;; + esac + fi + ;; + sco3.2v5*) + lt_cv_sys_max_cmd_len=102400 + ;; + sysv5* | sco5v6* | sysv4.2uw2*) + kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null` + if test -n "$kargmax"; then + lt_cv_sys_max_cmd_len=`echo $kargmax | sed 's/.*[ ]//'` + else + lt_cv_sys_max_cmd_len=32768 + fi + ;; + *) + lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null` + if test -n "$lt_cv_sys_max_cmd_len"; then + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` + else + # Make teststring a little bigger before we do anything with it. + # a 1K string should be a reasonable start. + for i in 1 2 3 4 5 6 7 8 ; do + teststring=$teststring$teststring + done + SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}} + # If test is not a shell built-in, we'll probably end up computing a + # maximum length that is only half of the actual maximum length, but + # we can't tell. + while { test "X"`env echo "$teststring$teststring" 2>/dev/null` \ + = "X$teststring$teststring"; } >/dev/null 2>&1 && + test $i != 17 # 1/2 MB should be enough + do + i=`expr $i + 1` + teststring=$teststring$teststring + done + # Only check the string length outside the loop. + lt_cv_sys_max_cmd_len=`expr "X$teststring" : ".*" 2>&1` + teststring= + # Add a significant safety factor because C++ compilers can tack on + # massive amounts of additional arguments before passing them to the + # linker. It appears as though 1/2 is a usable value. + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2` + fi + ;; + esac + +fi + +if test -n $lt_cv_sys_max_cmd_len ; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_sys_max_cmd_len" >&5 +$as_echo "$lt_cv_sys_max_cmd_len" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: none" >&5 +$as_echo "none" >&6; } +fi +max_cmd_len=$lt_cv_sys_max_cmd_len + + + + + + +: ${CP="cp -f"} +: ${MV="mv -f"} +: ${RM="rm -f"} + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the shell understands some XSI constructs" >&5 +$as_echo_n "checking whether the shell understands some XSI constructs... " >&6; } +# Try some XSI features +xsi_shell=no +( _lt_dummy="a/b/c" + test "${_lt_dummy##*/},${_lt_dummy%/*},${_lt_dummy#??}"${_lt_dummy%"$_lt_dummy"}, \ + = c,a/b,b/c, \ + && eval 'test $(( 1 + 1 )) -eq 2 \ + && test "${#_lt_dummy}" -eq 5' ) >/dev/null 2>&1 \ + && xsi_shell=yes +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $xsi_shell" >&5 +$as_echo "$xsi_shell" >&6; } + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the shell understands \"+=\"" >&5 +$as_echo_n "checking whether the shell understands \"+=\"... " >&6; } +lt_shell_append=no +( foo=bar; set foo baz; eval "$1+=\$2" && test "$foo" = barbaz ) \ + >/dev/null 2>&1 \ + && lt_shell_append=yes +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_shell_append" >&5 +$as_echo "$lt_shell_append" >&6; } + + +if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then + lt_unset=unset +else + lt_unset=false +fi + + + + + +# test EBCDIC or ASCII +case `echo X|tr X '\101'` in + A) # ASCII based system + # \n is not interpreted correctly by Solaris 8 /usr/ucb/tr + lt_SP2NL='tr \040 \012' + lt_NL2SP='tr \015\012 \040\040' + ;; + *) # EBCDIC based system + lt_SP2NL='tr \100 \n' + lt_NL2SP='tr \r\n \100\100' + ;; +esac + + + + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to convert $build file names to $host format" >&5 +$as_echo_n "checking how to convert $build file names to $host format... " >&6; } +if ${lt_cv_to_host_file_cmd+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $host in + *-*-mingw* ) + case $build in + *-*-mingw* ) # actually msys + lt_cv_to_host_file_cmd=func_convert_file_msys_to_w32 + ;; + *-*-cygwin* ) + lt_cv_to_host_file_cmd=func_convert_file_cygwin_to_w32 + ;; + * ) # otherwise, assume *nix + lt_cv_to_host_file_cmd=func_convert_file_nix_to_w32 + ;; + esac + ;; + *-*-cygwin* ) + case $build in + *-*-mingw* ) # actually msys + lt_cv_to_host_file_cmd=func_convert_file_msys_to_cygwin + ;; + *-*-cygwin* ) + lt_cv_to_host_file_cmd=func_convert_file_noop + ;; + * ) # otherwise, assume *nix + lt_cv_to_host_file_cmd=func_convert_file_nix_to_cygwin + ;; + esac + ;; + * ) # unhandled hosts (and "normal" native builds) + lt_cv_to_host_file_cmd=func_convert_file_noop + ;; +esac + +fi + +to_host_file_cmd=$lt_cv_to_host_file_cmd +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_to_host_file_cmd" >&5 +$as_echo "$lt_cv_to_host_file_cmd" >&6; } + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to convert $build file names to toolchain format" >&5 +$as_echo_n "checking how to convert $build file names to toolchain format... " >&6; } +if ${lt_cv_to_tool_file_cmd+:} false; then : + $as_echo_n "(cached) " >&6 +else + #assume ordinary cross tools, or native build. +lt_cv_to_tool_file_cmd=func_convert_file_noop +case $host in + *-*-mingw* ) + case $build in + *-*-mingw* ) # actually msys + lt_cv_to_tool_file_cmd=func_convert_file_msys_to_w32 + ;; + esac + ;; +esac + +fi + +to_tool_file_cmd=$lt_cv_to_tool_file_cmd +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_to_tool_file_cmd" >&5 +$as_echo "$lt_cv_to_tool_file_cmd" >&6; } + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $LD option to reload object files" >&5 +$as_echo_n "checking for $LD option to reload object files... " >&6; } +if ${lt_cv_ld_reload_flag+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_ld_reload_flag='-r' +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_reload_flag" >&5 +$as_echo "$lt_cv_ld_reload_flag" >&6; } +reload_flag=$lt_cv_ld_reload_flag +case $reload_flag in +"" | " "*) ;; +*) reload_flag=" $reload_flag" ;; +esac +reload_cmds='$LD$reload_flag -o $output$reload_objs' +case $host_os in + cygwin* | mingw* | pw32* | cegcc*) + if test "$GCC" != yes; then + reload_cmds=false + fi + ;; + darwin*) + if test "$GCC" = yes; then + reload_cmds='$LTCC $LTCFLAGS -nostdlib ${wl}-r -o $output$reload_objs' + else + reload_cmds='$LD$reload_flag -o $output$reload_objs' + fi + ;; +esac + + + + + + + + + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}objdump", so it can be a program name with args. +set dummy ${ac_tool_prefix}objdump; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_OBJDUMP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$OBJDUMP"; then + ac_cv_prog_OBJDUMP="$OBJDUMP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_OBJDUMP="${ac_tool_prefix}objdump" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +OBJDUMP=$ac_cv_prog_OBJDUMP +if test -n "$OBJDUMP"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OBJDUMP" >&5 +$as_echo "$OBJDUMP" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_OBJDUMP"; then + ac_ct_OBJDUMP=$OBJDUMP + # Extract the first word of "objdump", so it can be a program name with args. +set dummy objdump; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_OBJDUMP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_OBJDUMP"; then + ac_cv_prog_ac_ct_OBJDUMP="$ac_ct_OBJDUMP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_OBJDUMP="objdump" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_OBJDUMP=$ac_cv_prog_ac_ct_OBJDUMP +if test -n "$ac_ct_OBJDUMP"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OBJDUMP" >&5 +$as_echo "$ac_ct_OBJDUMP" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_OBJDUMP" = x; then + OBJDUMP="false" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + OBJDUMP=$ac_ct_OBJDUMP + fi +else + OBJDUMP="$ac_cv_prog_OBJDUMP" +fi + +test -z "$OBJDUMP" && OBJDUMP=objdump + + + + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to recognize dependent libraries" >&5 +$as_echo_n "checking how to recognize dependent libraries... " >&6; } +if ${lt_cv_deplibs_check_method+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_file_magic_cmd='$MAGIC_CMD' +lt_cv_file_magic_test_file= +lt_cv_deplibs_check_method='unknown' +# Need to set the preceding variable on all platforms that support +# interlibrary dependencies. +# 'none' -- dependencies not supported. +# `unknown' -- same as none, but documents that we really don't know. +# 'pass_all' -- all dependencies passed with no checks. +# 'test_compile' -- check by making test program. +# 'file_magic [[regex]]' -- check by looking for files in library path +# which responds to the $file_magic_cmd with a given extended regex. +# If you have `file' or equivalent on your system and you're not sure +# whether `pass_all' will *always* work, you probably want this one. + +case $host_os in +aix[4-9]*) + lt_cv_deplibs_check_method=pass_all + ;; + +beos*) + lt_cv_deplibs_check_method=pass_all + ;; + +bsdi[45]*) + lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib)' + lt_cv_file_magic_cmd='/usr/bin/file -L' + lt_cv_file_magic_test_file=/shlib/libc.so + ;; + +cygwin*) + # func_win32_libid is a shell function defined in ltmain.sh + lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' + lt_cv_file_magic_cmd='func_win32_libid' + ;; + +mingw* | pw32*) + # Base MSYS/MinGW do not provide the 'file' command needed by + # func_win32_libid shell function, so use a weaker test based on 'objdump', + # unless we find 'file', for example because we are cross-compiling. + # func_win32_libid assumes BSD nm, so disallow it if using MS dumpbin. + if ( test "$lt_cv_nm_interface" = "BSD nm" && file / ) >/dev/null 2>&1; then + lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' + lt_cv_file_magic_cmd='func_win32_libid' + else + # Keep this pattern in sync with the one in func_win32_libid. + lt_cv_deplibs_check_method='file_magic file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)' + lt_cv_file_magic_cmd='$OBJDUMP -f' + fi + ;; + +cegcc*) + # use the weaker test based on 'objdump'. See mingw*. + lt_cv_deplibs_check_method='file_magic file format pe-arm-.*little(.*architecture: arm)?' + lt_cv_file_magic_cmd='$OBJDUMP -f' + ;; + +darwin* | rhapsody*) + lt_cv_deplibs_check_method=pass_all + ;; + +freebsd* | dragonfly*) + if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then + case $host_cpu in + i*86 ) + # Not sure whether the presence of OpenBSD here was a mistake. + # Let's accept both of them until this is cleared up. + lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[3-9]86 (compact )?demand paged shared library' + lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*` + ;; + esac + else + lt_cv_deplibs_check_method=pass_all + fi + ;; + +gnu*) + lt_cv_deplibs_check_method=pass_all + ;; + +haiku*) + lt_cv_deplibs_check_method=pass_all + ;; + +hpux10.20* | hpux11*) + lt_cv_file_magic_cmd=/usr/bin/file + case $host_cpu in + ia64*) + lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - IA64' + lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so + ;; + hppa*64*) + lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF[ -][0-9][0-9])(-bit)?( [LM]SB)? shared object( file)?[, -]* PA-RISC [0-9]\.[0-9]' + lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl + ;; + *) + lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|PA-RISC[0-9]\.[0-9]) shared library' + lt_cv_file_magic_test_file=/usr/lib/libc.sl + ;; + esac + ;; + +interix[3-9]*) + # PIC code is broken on Interix 3.x, that's why |\.a not |_pic\.a here + lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|\.a)$' + ;; + +irix5* | irix6* | nonstopux*) + case $LD in + *-32|*"-32 ") libmagic=32-bit;; + *-n32|*"-n32 ") libmagic=N32;; + *-64|*"-64 ") libmagic=64-bit;; + *) libmagic=never-match;; + esac + lt_cv_deplibs_check_method=pass_all + ;; + +# This must be glibc/ELF. +linux* | k*bsd*-gnu | kopensolaris*-gnu) + lt_cv_deplibs_check_method=pass_all + ;; + +netbsd* | netbsdelf*-gnu) + if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then + lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$' + else + lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|_pic\.a)$' + fi + ;; + +newos6*) + lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (executable|dynamic lib)' + lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_test_file=/usr/lib/libnls.so + ;; + +*nto* | *qnx*) + lt_cv_deplibs_check_method=pass_all + ;; + +openbsd*) + if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|\.so|_pic\.a)$' + else + lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$' + fi + ;; + +osf3* | osf4* | osf5*) + lt_cv_deplibs_check_method=pass_all + ;; + +rdos*) + lt_cv_deplibs_check_method=pass_all + ;; + +solaris*) + lt_cv_deplibs_check_method=pass_all + ;; + +sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) + lt_cv_deplibs_check_method=pass_all + ;; + +sysv4 | sysv4.3*) + case $host_vendor in + motorola) + lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib) M[0-9][0-9]* Version [0-9]' + lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*` + ;; + ncr) + lt_cv_deplibs_check_method=pass_all + ;; + sequent) + lt_cv_file_magic_cmd='/bin/file' + lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [LM]SB (shared object|dynamic lib )' + ;; + sni) + lt_cv_file_magic_cmd='/bin/file' + lt_cv_deplibs_check_method="file_magic ELF [0-9][0-9]*-bit [LM]SB dynamic lib" + lt_cv_file_magic_test_file=/lib/libc.so + ;; + siemens) + lt_cv_deplibs_check_method=pass_all + ;; + pc) + lt_cv_deplibs_check_method=pass_all + ;; + esac + ;; + +tpf*) + lt_cv_deplibs_check_method=pass_all + ;; +esac + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_deplibs_check_method" >&5 +$as_echo "$lt_cv_deplibs_check_method" >&6; } + +file_magic_glob= +want_nocaseglob=no +if test "$build" = "$host"; then + case $host_os in + mingw* | pw32*) + if ( shopt | grep nocaseglob ) >/dev/null 2>&1; then + want_nocaseglob=yes + else + file_magic_glob=`echo aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ | $SED -e "s/\(..\)/s\/[\1]\/[\1]\/g;/g"` + fi + ;; + esac +fi + +file_magic_cmd=$lt_cv_file_magic_cmd +deplibs_check_method=$lt_cv_deplibs_check_method +test -z "$deplibs_check_method" && deplibs_check_method=unknown + + + + + + + + + + + + + + + + + + + + + + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}dlltool", so it can be a program name with args. +set dummy ${ac_tool_prefix}dlltool; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_DLLTOOL+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$DLLTOOL"; then + ac_cv_prog_DLLTOOL="$DLLTOOL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_DLLTOOL="${ac_tool_prefix}dlltool" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +DLLTOOL=$ac_cv_prog_DLLTOOL +if test -n "$DLLTOOL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DLLTOOL" >&5 +$as_echo "$DLLTOOL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_DLLTOOL"; then + ac_ct_DLLTOOL=$DLLTOOL + # Extract the first word of "dlltool", so it can be a program name with args. +set dummy dlltool; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_DLLTOOL+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_DLLTOOL"; then + ac_cv_prog_ac_ct_DLLTOOL="$ac_ct_DLLTOOL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_DLLTOOL="dlltool" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_DLLTOOL=$ac_cv_prog_ac_ct_DLLTOOL +if test -n "$ac_ct_DLLTOOL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DLLTOOL" >&5 +$as_echo "$ac_ct_DLLTOOL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_DLLTOOL" = x; then + DLLTOOL="false" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + DLLTOOL=$ac_ct_DLLTOOL + fi +else + DLLTOOL="$ac_cv_prog_DLLTOOL" +fi + +test -z "$DLLTOOL" && DLLTOOL=dlltool + + + + + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to associate runtime and link libraries" >&5 +$as_echo_n "checking how to associate runtime and link libraries... " >&6; } +if ${lt_cv_sharedlib_from_linklib_cmd+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_sharedlib_from_linklib_cmd='unknown' + +case $host_os in +cygwin* | mingw* | pw32* | cegcc*) + # two different shell functions defined in ltmain.sh + # decide which to use based on capabilities of $DLLTOOL + case `$DLLTOOL --help 2>&1` in + *--identify-strict*) + lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib + ;; + *) + lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib_fallback + ;; + esac + ;; +*) + # fallback: assume linklib IS sharedlib + lt_cv_sharedlib_from_linklib_cmd="$ECHO" + ;; +esac + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_sharedlib_from_linklib_cmd" >&5 +$as_echo "$lt_cv_sharedlib_from_linklib_cmd" >&6; } +sharedlib_from_linklib_cmd=$lt_cv_sharedlib_from_linklib_cmd +test -z "$sharedlib_from_linklib_cmd" && sharedlib_from_linklib_cmd=$ECHO + + + + + + + + +if test -n "$ac_tool_prefix"; then + for ac_prog in ar + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_AR+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$AR"; then + ac_cv_prog_AR="$AR" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_AR="$ac_tool_prefix$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +AR=$ac_cv_prog_AR +if test -n "$AR"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AR" >&5 +$as_echo "$AR" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$AR" && break + done +fi +if test -z "$AR"; then + ac_ct_AR=$AR + for ac_prog in ar +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_AR+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_AR"; then + ac_cv_prog_ac_ct_AR="$ac_ct_AR" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_AR="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_AR=$ac_cv_prog_ac_ct_AR +if test -n "$ac_ct_AR"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_AR" >&5 +$as_echo "$ac_ct_AR" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$ac_ct_AR" && break +done + + if test "x$ac_ct_AR" = x; then + AR="false" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + AR=$ac_ct_AR + fi +fi + +: ${AR=ar} +: ${AR_FLAGS=cru} + + + + + + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for archiver @FILE support" >&5 +$as_echo_n "checking for archiver @FILE support... " >&6; } +if ${lt_cv_ar_at_file+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_ar_at_file=no + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + echo conftest.$ac_objext > conftest.lst + lt_ar_try='$AR $AR_FLAGS libconftest.a @conftest.lst >&5' + { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$lt_ar_try\""; } >&5 + (eval $lt_ar_try) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } + if test "$ac_status" -eq 0; then + # Ensure the archiver fails upon bogus file names. + rm -f conftest.$ac_objext libconftest.a + { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$lt_ar_try\""; } >&5 + (eval $lt_ar_try) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } + if test "$ac_status" -ne 0; then + lt_cv_ar_at_file=@ + fi + fi + rm -f conftest.* libconftest.a + +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ar_at_file" >&5 +$as_echo "$lt_cv_ar_at_file" >&6; } + +if test "x$lt_cv_ar_at_file" = xno; then + archiver_list_spec= +else + archiver_list_spec=$lt_cv_ar_at_file +fi + + + + + + + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. +set dummy ${ac_tool_prefix}strip; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_STRIP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$STRIP"; then + ac_cv_prog_STRIP="$STRIP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_STRIP="${ac_tool_prefix}strip" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +STRIP=$ac_cv_prog_STRIP +if test -n "$STRIP"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5 +$as_echo "$STRIP" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_STRIP"; then + ac_ct_STRIP=$STRIP + # Extract the first word of "strip", so it can be a program name with args. +set dummy strip; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_STRIP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_STRIP"; then + ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_STRIP="strip" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP +if test -n "$ac_ct_STRIP"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5 +$as_echo "$ac_ct_STRIP" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_STRIP" = x; then + STRIP=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + STRIP=$ac_ct_STRIP + fi +else + STRIP="$ac_cv_prog_STRIP" +fi + +test -z "$STRIP" && STRIP=: + + + + + + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args. +set dummy ${ac_tool_prefix}ranlib; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_RANLIB+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$RANLIB"; then + ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +RANLIB=$ac_cv_prog_RANLIB +if test -n "$RANLIB"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $RANLIB" >&5 +$as_echo "$RANLIB" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_RANLIB"; then + ac_ct_RANLIB=$RANLIB + # Extract the first word of "ranlib", so it can be a program name with args. +set dummy ranlib; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_RANLIB+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_RANLIB"; then + ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_RANLIB="ranlib" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB +if test -n "$ac_ct_RANLIB"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_RANLIB" >&5 +$as_echo "$ac_ct_RANLIB" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_RANLIB" = x; then + RANLIB=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + RANLIB=$ac_ct_RANLIB + fi +else + RANLIB="$ac_cv_prog_RANLIB" +fi + +test -z "$RANLIB" && RANLIB=: + + + + + + +# Determine commands to create old-style static archives. +old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs' +old_postinstall_cmds='chmod 644 $oldlib' +old_postuninstall_cmds= + +if test -n "$RANLIB"; then + case $host_os in + openbsd*) + old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$tool_oldlib" + ;; + *) + old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$tool_oldlib" + ;; + esac + old_archive_cmds="$old_archive_cmds~\$RANLIB \$tool_oldlib" +fi + +case $host_os in + darwin*) + lock_old_archive_extraction=yes ;; + *) + lock_old_archive_extraction=no ;; +esac + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +# If no C compiler was specified, use CC. +LTCC=${LTCC-"$CC"} + +# If no C compiler flags were specified, use CFLAGS. +LTCFLAGS=${LTCFLAGS-"$CFLAGS"} + +# Allow CC to be a program name with arguments. +compiler=$CC + + +# Check for command to grab the raw symbol name followed by C symbol from nm. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking command to parse $NM output from $compiler object" >&5 +$as_echo_n "checking command to parse $NM output from $compiler object... " >&6; } +if ${lt_cv_sys_global_symbol_pipe+:} false; then : + $as_echo_n "(cached) " >&6 +else + +# These are sane defaults that work on at least a few old systems. +# [They come from Ultrix. What could be older than Ultrix?!! ;)] + +# Character class describing NM global symbol codes. +symcode='[BCDEGRST]' + +# Regexp to match symbols that can be accessed directly from C. +sympat='\([_A-Za-z][_A-Za-z0-9]*\)' + +# Define system-specific variables. +case $host_os in +aix*) + symcode='[BCDT]' + ;; +cygwin* | mingw* | pw32* | cegcc*) + symcode='[ABCDGISTW]' + ;; +hpux*) + if test "$host_cpu" = ia64; then + symcode='[ABCDEGRST]' + fi + ;; +irix* | nonstopux*) + symcode='[BCDEGRST]' + ;; +osf*) + symcode='[BCDEGQRST]' + ;; +solaris*) + symcode='[BDRT]' + ;; +sco3.2v5*) + symcode='[DT]' + ;; +sysv4.2uw2*) + symcode='[DT]' + ;; +sysv5* | sco5v6* | unixware* | OpenUNIX*) + symcode='[ABDT]' + ;; +sysv4) + symcode='[DFNSTU]' + ;; +esac + +# If we're using GNU nm, then use its standard symbol codes. +case `$NM -V 2>&1` in +*GNU* | *'with BFD'*) + symcode='[ABCDGIRSTW]' ;; +esac + +# Transform an extracted symbol line into a proper C declaration. +# Some systems (esp. on ia64) link data and code symbols differently, +# so use this general approach. +lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'" + +# Transform an extracted symbol line into symbol name and symbol address +lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([^ ]*\)[ ]*$/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([^ ]*\) \([^ ]*\)$/ {\"\2\", (void *) \&\2},/p'" +lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n -e 's/^: \([^ ]*\)[ ]*$/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([^ ]*\) \(lib[^ ]*\)$/ {\"\2\", (void *) \&\2},/p' -e 's/^$symcode* \([^ ]*\) \([^ ]*\)$/ {\"lib\2\", (void *) \&\2},/p'" + +# Handle CRLF in mingw tool chain +opt_cr= +case $build_os in +mingw*) + opt_cr=`$ECHO 'x\{0,1\}' | tr x '\015'` # option cr in regexp + ;; +esac + +# Try without a prefix underscore, then with it. +for ac_symprfx in "" "_"; do + + # Transform symcode, sympat, and symprfx into a raw symbol and a C symbol. + symxfrm="\\1 $ac_symprfx\\2 \\2" + + # Write the raw and C identifiers. + if test "$lt_cv_nm_interface" = "MS dumpbin"; then + # Fake it for dumpbin and say T for any non-static function + # and D for any global variable. + # Also find C++ and __fastcall symbols from MSVC++, + # which start with @ or ?. + lt_cv_sys_global_symbol_pipe="$AWK '"\ +" {last_section=section; section=\$ 3};"\ +" /^COFF SYMBOL TABLE/{for(i in hide) delete hide[i]};"\ +" /Section length .*#relocs.*(pick any)/{hide[last_section]=1};"\ +" \$ 0!~/External *\|/{next};"\ +" / 0+ UNDEF /{next}; / UNDEF \([^|]\)*()/{next};"\ +" {if(hide[section]) next};"\ +" {f=0}; \$ 0~/\(\).*\|/{f=1}; {printf f ? \"T \" : \"D \"};"\ +" {split(\$ 0, a, /\||\r/); split(a[2], s)};"\ +" s[1]~/^[@?]/{print s[1], s[1]; next};"\ +" s[1]~prfx {split(s[1],t,\"@\"); print t[1], substr(t[1],length(prfx))}"\ +" ' prfx=^$ac_symprfx" + else + lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[ ]\($symcode$symcode*\)[ ][ ]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'" + fi + lt_cv_sys_global_symbol_pipe="$lt_cv_sys_global_symbol_pipe | sed '/ __gnu_lto/d'" + + # Check to see that the pipe works correctly. + pipe_works=no + + rm -f conftest* + cat > conftest.$ac_ext <<_LT_EOF +#ifdef __cplusplus +extern "C" { +#endif +char nm_test_var; +void nm_test_func(void); +void nm_test_func(void){} +#ifdef __cplusplus +} +#endif +int main(){nm_test_var='a';nm_test_func();return(0);} +_LT_EOF + + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + # Now try to grab the symbols. + nlist=conftest.nm + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist\""; } >&5 + (eval $NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && test -s "$nlist"; then + # Try sorting and uniquifying the output. + if sort "$nlist" | uniq > "$nlist"T; then + mv -f "$nlist"T "$nlist" + else + rm -f "$nlist"T + fi + + # Make sure that we snagged all the symbols we need. + if $GREP ' nm_test_var$' "$nlist" >/dev/null; then + if $GREP ' nm_test_func$' "$nlist" >/dev/null; then + cat <<_LT_EOF > conftest.$ac_ext +/* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests. */ +#if defined(_WIN32) || defined(__CYGWIN__) || defined(_WIN32_WCE) +/* DATA imports from DLLs on WIN32 con't be const, because runtime + relocations are performed -- see ld's documentation on pseudo-relocs. */ +# define LT_DLSYM_CONST +#elif defined(__osf__) +/* This system does not cope well with relocations in const data. */ +# define LT_DLSYM_CONST +#else +# define LT_DLSYM_CONST const +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +_LT_EOF + # Now generate the symbol file. + eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | $GREP -v main >> conftest.$ac_ext' + + cat <<_LT_EOF >> conftest.$ac_ext + +/* The mapping between symbol names and symbols. */ +LT_DLSYM_CONST struct { + const char *name; + void *address; +} +lt__PROGRAM__LTX_preloaded_symbols[] = +{ + { "@PROGRAM@", (void *) 0 }, +_LT_EOF + $SED "s/^$symcode$symcode* \(.*\) \(.*\)$/ {\"\2\", (void *) \&\2},/" < "$nlist" | $GREP -v main >> conftest.$ac_ext + cat <<\_LT_EOF >> conftest.$ac_ext + {0, (void *) 0} +}; + +/* This works around a problem in FreeBSD linker */ +#ifdef FREEBSD_WORKAROUND +static const void *lt_preloaded_setup() { + return lt__PROGRAM__LTX_preloaded_symbols; +} +#endif + +#ifdef __cplusplus +} +#endif +_LT_EOF + # Now try linking the two files. + mv conftest.$ac_objext conftstm.$ac_objext + lt_globsym_save_LIBS=$LIBS + lt_globsym_save_CFLAGS=$CFLAGS + LIBS="conftstm.$ac_objext" + CFLAGS="$CFLAGS$lt_prog_compiler_no_builtin_flag" + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5 + (eval $ac_link) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && test -s conftest${ac_exeext}; then + pipe_works=yes + fi + LIBS=$lt_globsym_save_LIBS + CFLAGS=$lt_globsym_save_CFLAGS + else + echo "cannot find nm_test_func in $nlist" >&5 + fi + else + echo "cannot find nm_test_var in $nlist" >&5 + fi + else + echo "cannot run $lt_cv_sys_global_symbol_pipe" >&5 + fi + else + echo "$progname: failed program was:" >&5 + cat conftest.$ac_ext >&5 + fi + rm -rf conftest* conftst* + + # Do not use the global_symbol_pipe unless it works. + if test "$pipe_works" = yes; then + break + else + lt_cv_sys_global_symbol_pipe= + fi +done + +fi + +if test -z "$lt_cv_sys_global_symbol_pipe"; then + lt_cv_sys_global_symbol_to_cdecl= +fi +if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: failed" >&5 +$as_echo "failed" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: ok" >&5 +$as_echo "ok" >&6; } +fi + +# Response file support. +if test "$lt_cv_nm_interface" = "MS dumpbin"; then + nm_file_list_spec='@' +elif $NM --help 2>/dev/null | grep '[@]FILE' >/dev/null; then + nm_file_list_spec='@' +fi + + + + + + + + + + + + + + + + + + + + + + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for sysroot" >&5 +$as_echo_n "checking for sysroot... " >&6; } + +# Check whether --with-sysroot was given. +if test "${with_sysroot+set}" = set; then : + withval=$with_sysroot; +else + with_sysroot=no +fi + + +lt_sysroot= +case ${with_sysroot} in #( + yes) + if test "$GCC" = yes; then + lt_sysroot=`$CC --print-sysroot 2>/dev/null` + fi + ;; #( + /*) + lt_sysroot=`echo "$with_sysroot" | sed -e "$sed_quote_subst"` + ;; #( + no|'') + ;; #( + *) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${with_sysroot}" >&5 +$as_echo "${with_sysroot}" >&6; } + as_fn_error $? "The sysroot must be an absolute path." "$LINENO" 5 + ;; +esac + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${lt_sysroot:-no}" >&5 +$as_echo "${lt_sysroot:-no}" >&6; } + + + + + +# Check whether --enable-libtool-lock was given. +if test "${enable_libtool_lock+set}" = set; then : + enableval=$enable_libtool_lock; +fi + +test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes + +# Some flags need to be propagated to the compiler or linker for good +# libtool support. +case $host in +ia64-*-hpux*) + # Find out which ABI we are using. + echo 'int i;' > conftest.$ac_ext + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + case `/usr/bin/file conftest.$ac_objext` in + *ELF-32*) + HPUX_IA64_MODE="32" + ;; + *ELF-64*) + HPUX_IA64_MODE="64" + ;; + esac + fi + rm -rf conftest* + ;; +*-*-irix6*) + # Find out which ABI we are using. + echo '#line '$LINENO' "configure"' > conftest.$ac_ext + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + if test "$lt_cv_prog_gnu_ld" = yes; then + case `/usr/bin/file conftest.$ac_objext` in + *32-bit*) + LD="${LD-ld} -melf32bsmip" + ;; + *N32*) + LD="${LD-ld} -melf32bmipn32" + ;; + *64-bit*) + LD="${LD-ld} -melf64bmip" + ;; + esac + else + case `/usr/bin/file conftest.$ac_objext` in + *32-bit*) + LD="${LD-ld} -32" + ;; + *N32*) + LD="${LD-ld} -n32" + ;; + *64-bit*) + LD="${LD-ld} -64" + ;; + esac + fi + fi + rm -rf conftest* + ;; + +x86_64-*kfreebsd*-gnu|x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*| \ +s390*-*linux*|s390*-*tpf*|sparc*-*linux*) + # Find out which ABI we are using. + echo 'int i;' > conftest.$ac_ext + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + case `/usr/bin/file conftest.o` in + *32-bit*) + case $host in + x86_64-*kfreebsd*-gnu) + LD="${LD-ld} -m elf_i386_fbsd" + ;; + x86_64-*linux*) + LD="${LD-ld} -m elf_i386" + ;; + ppc64-*linux*|powerpc64-*linux*) + LD="${LD-ld} -m elf32ppclinux" + ;; + s390x-*linux*) + LD="${LD-ld} -m elf_s390" + ;; + sparc64-*linux*) + LD="${LD-ld} -m elf32_sparc" + ;; + esac + ;; + *64-bit*) + case $host in + x86_64-*kfreebsd*-gnu) + LD="${LD-ld} -m elf_x86_64_fbsd" + ;; + x86_64-*linux*) + LD="${LD-ld} -m elf_x86_64" + ;; + ppc*-*linux*|powerpc*-*linux*) + LD="${LD-ld} -m elf64ppc" + ;; + s390*-*linux*|s390*-*tpf*) + LD="${LD-ld} -m elf64_s390" + ;; + sparc*-*linux*) + LD="${LD-ld} -m elf64_sparc" + ;; + esac + ;; + esac + fi + rm -rf conftest* + ;; + +*-*-sco3.2v5*) + # On SCO OpenServer 5, we need -belf to get full-featured binaries. + SAVE_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS -belf" + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler needs -belf" >&5 +$as_echo_n "checking whether the C compiler needs -belf... " >&6; } +if ${lt_cv_cc_needs_belf+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + lt_cv_cc_needs_belf=yes +else + lt_cv_cc_needs_belf=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_cc_needs_belf" >&5 +$as_echo "$lt_cv_cc_needs_belf" >&6; } + if test x"$lt_cv_cc_needs_belf" != x"yes"; then + # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf + CFLAGS="$SAVE_CFLAGS" + fi + ;; +*-*solaris*) + # Find out which ABI we are using. + echo 'int i;' > conftest.$ac_ext + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + case `/usr/bin/file conftest.o` in + *64-bit*) + case $lt_cv_prog_gnu_ld in + yes*) + case $host in + i?86-*-solaris*) + LD="${LD-ld} -m elf_x86_64" + ;; + sparc*-*-solaris*) + LD="${LD-ld} -m elf64_sparc" + ;; + esac + # GNU ld 2.21 introduced _sol2 emulations. Use them if available. + if ${LD-ld} -V | grep _sol2 >/dev/null 2>&1; then + LD="${LD-ld}_sol2" + fi + ;; + *) + if ${LD-ld} -64 -r -o conftest2.o conftest.o >/dev/null 2>&1; then + LD="${LD-ld} -64" + fi + ;; + esac + ;; + esac + fi + rm -rf conftest* + ;; +esac + +need_locks="$enable_libtool_lock" + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}mt", so it can be a program name with args. +set dummy ${ac_tool_prefix}mt; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_MANIFEST_TOOL+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$MANIFEST_TOOL"; then + ac_cv_prog_MANIFEST_TOOL="$MANIFEST_TOOL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_MANIFEST_TOOL="${ac_tool_prefix}mt" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +MANIFEST_TOOL=$ac_cv_prog_MANIFEST_TOOL +if test -n "$MANIFEST_TOOL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MANIFEST_TOOL" >&5 +$as_echo "$MANIFEST_TOOL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_MANIFEST_TOOL"; then + ac_ct_MANIFEST_TOOL=$MANIFEST_TOOL + # Extract the first word of "mt", so it can be a program name with args. +set dummy mt; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_MANIFEST_TOOL+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_MANIFEST_TOOL"; then + ac_cv_prog_ac_ct_MANIFEST_TOOL="$ac_ct_MANIFEST_TOOL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_MANIFEST_TOOL="mt" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_MANIFEST_TOOL=$ac_cv_prog_ac_ct_MANIFEST_TOOL +if test -n "$ac_ct_MANIFEST_TOOL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_MANIFEST_TOOL" >&5 +$as_echo "$ac_ct_MANIFEST_TOOL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_MANIFEST_TOOL" = x; then + MANIFEST_TOOL=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + MANIFEST_TOOL=$ac_ct_MANIFEST_TOOL + fi +else + MANIFEST_TOOL="$ac_cv_prog_MANIFEST_TOOL" +fi + +test -z "$MANIFEST_TOOL" && MANIFEST_TOOL=mt +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if $MANIFEST_TOOL is a manifest tool" >&5 +$as_echo_n "checking if $MANIFEST_TOOL is a manifest tool... " >&6; } +if ${lt_cv_path_mainfest_tool+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_path_mainfest_tool=no + echo "$as_me:$LINENO: $MANIFEST_TOOL '-?'" >&5 + $MANIFEST_TOOL '-?' 2>conftest.err > conftest.out + cat conftest.err >&5 + if $GREP 'Manifest Tool' conftest.out > /dev/null; then + lt_cv_path_mainfest_tool=yes + fi + rm -f conftest* +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_path_mainfest_tool" >&5 +$as_echo "$lt_cv_path_mainfest_tool" >&6; } +if test "x$lt_cv_path_mainfest_tool" != xyes; then + MANIFEST_TOOL=: +fi + + + + + + + case $host_os in + rhapsody* | darwin*) + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}dsymutil", so it can be a program name with args. +set dummy ${ac_tool_prefix}dsymutil; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_DSYMUTIL+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$DSYMUTIL"; then + ac_cv_prog_DSYMUTIL="$DSYMUTIL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_DSYMUTIL="${ac_tool_prefix}dsymutil" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +DSYMUTIL=$ac_cv_prog_DSYMUTIL +if test -n "$DSYMUTIL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DSYMUTIL" >&5 +$as_echo "$DSYMUTIL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_DSYMUTIL"; then + ac_ct_DSYMUTIL=$DSYMUTIL + # Extract the first word of "dsymutil", so it can be a program name with args. +set dummy dsymutil; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_DSYMUTIL+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_DSYMUTIL"; then + ac_cv_prog_ac_ct_DSYMUTIL="$ac_ct_DSYMUTIL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_DSYMUTIL="dsymutil" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_DSYMUTIL=$ac_cv_prog_ac_ct_DSYMUTIL +if test -n "$ac_ct_DSYMUTIL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DSYMUTIL" >&5 +$as_echo "$ac_ct_DSYMUTIL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_DSYMUTIL" = x; then + DSYMUTIL=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + DSYMUTIL=$ac_ct_DSYMUTIL + fi +else + DSYMUTIL="$ac_cv_prog_DSYMUTIL" +fi + + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}nmedit", so it can be a program name with args. +set dummy ${ac_tool_prefix}nmedit; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_NMEDIT+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$NMEDIT"; then + ac_cv_prog_NMEDIT="$NMEDIT" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_NMEDIT="${ac_tool_prefix}nmedit" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +NMEDIT=$ac_cv_prog_NMEDIT +if test -n "$NMEDIT"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $NMEDIT" >&5 +$as_echo "$NMEDIT" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_NMEDIT"; then + ac_ct_NMEDIT=$NMEDIT + # Extract the first word of "nmedit", so it can be a program name with args. +set dummy nmedit; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_NMEDIT+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_NMEDIT"; then + ac_cv_prog_ac_ct_NMEDIT="$ac_ct_NMEDIT" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_NMEDIT="nmedit" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_NMEDIT=$ac_cv_prog_ac_ct_NMEDIT +if test -n "$ac_ct_NMEDIT"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_NMEDIT" >&5 +$as_echo "$ac_ct_NMEDIT" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_NMEDIT" = x; then + NMEDIT=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + NMEDIT=$ac_ct_NMEDIT + fi +else + NMEDIT="$ac_cv_prog_NMEDIT" +fi + + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}lipo", so it can be a program name with args. +set dummy ${ac_tool_prefix}lipo; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_LIPO+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$LIPO"; then + ac_cv_prog_LIPO="$LIPO" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_LIPO="${ac_tool_prefix}lipo" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +LIPO=$ac_cv_prog_LIPO +if test -n "$LIPO"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LIPO" >&5 +$as_echo "$LIPO" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_LIPO"; then + ac_ct_LIPO=$LIPO + # Extract the first word of "lipo", so it can be a program name with args. +set dummy lipo; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_LIPO+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_LIPO"; then + ac_cv_prog_ac_ct_LIPO="$ac_ct_LIPO" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_LIPO="lipo" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_LIPO=$ac_cv_prog_ac_ct_LIPO +if test -n "$ac_ct_LIPO"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_LIPO" >&5 +$as_echo "$ac_ct_LIPO" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_LIPO" = x; then + LIPO=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + LIPO=$ac_ct_LIPO + fi +else + LIPO="$ac_cv_prog_LIPO" +fi + + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}otool", so it can be a program name with args. +set dummy ${ac_tool_prefix}otool; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_OTOOL+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$OTOOL"; then + ac_cv_prog_OTOOL="$OTOOL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_OTOOL="${ac_tool_prefix}otool" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +OTOOL=$ac_cv_prog_OTOOL +if test -n "$OTOOL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OTOOL" >&5 +$as_echo "$OTOOL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_OTOOL"; then + ac_ct_OTOOL=$OTOOL + # Extract the first word of "otool", so it can be a program name with args. +set dummy otool; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_OTOOL+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_OTOOL"; then + ac_cv_prog_ac_ct_OTOOL="$ac_ct_OTOOL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_OTOOL="otool" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_OTOOL=$ac_cv_prog_ac_ct_OTOOL +if test -n "$ac_ct_OTOOL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OTOOL" >&5 +$as_echo "$ac_ct_OTOOL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_OTOOL" = x; then + OTOOL=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + OTOOL=$ac_ct_OTOOL + fi +else + OTOOL="$ac_cv_prog_OTOOL" +fi + + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}otool64", so it can be a program name with args. +set dummy ${ac_tool_prefix}otool64; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_OTOOL64+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$OTOOL64"; then + ac_cv_prog_OTOOL64="$OTOOL64" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_OTOOL64="${ac_tool_prefix}otool64" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +OTOOL64=$ac_cv_prog_OTOOL64 +if test -n "$OTOOL64"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OTOOL64" >&5 +$as_echo "$OTOOL64" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_OTOOL64"; then + ac_ct_OTOOL64=$OTOOL64 + # Extract the first word of "otool64", so it can be a program name with args. +set dummy otool64; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_OTOOL64+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_OTOOL64"; then + ac_cv_prog_ac_ct_OTOOL64="$ac_ct_OTOOL64" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_OTOOL64="otool64" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_OTOOL64=$ac_cv_prog_ac_ct_OTOOL64 +if test -n "$ac_ct_OTOOL64"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OTOOL64" >&5 +$as_echo "$ac_ct_OTOOL64" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_OTOOL64" = x; then + OTOOL64=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + OTOOL64=$ac_ct_OTOOL64 + fi +else + OTOOL64="$ac_cv_prog_OTOOL64" +fi + + + + + + + + + + + + + + + + + + + + + + + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -single_module linker flag" >&5 +$as_echo_n "checking for -single_module linker flag... " >&6; } +if ${lt_cv_apple_cc_single_mod+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_apple_cc_single_mod=no + if test -z "${LT_MULTI_MODULE}"; then + # By default we will add the -single_module flag. You can override + # by either setting the environment variable LT_MULTI_MODULE + # non-empty at configure time, or by adding -multi_module to the + # link flags. + rm -rf libconftest.dylib* + echo "int foo(void){return 1;}" > conftest.c + echo "$LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ +-dynamiclib -Wl,-single_module conftest.c" >&5 + $LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ + -dynamiclib -Wl,-single_module conftest.c 2>conftest.err + _lt_result=$? + # If there is a non-empty error log, and "single_module" + # appears in it, assume the flag caused a linker warning + if test -s conftest.err && $GREP single_module conftest.err; then + cat conftest.err >&5 + # Otherwise, if the output was created with a 0 exit code from + # the compiler, it worked. + elif test -f libconftest.dylib && test $_lt_result -eq 0; then + lt_cv_apple_cc_single_mod=yes + else + cat conftest.err >&5 + fi + rm -rf libconftest.dylib* + rm -f conftest.* + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_apple_cc_single_mod" >&5 +$as_echo "$lt_cv_apple_cc_single_mod" >&6; } + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -exported_symbols_list linker flag" >&5 +$as_echo_n "checking for -exported_symbols_list linker flag... " >&6; } +if ${lt_cv_ld_exported_symbols_list+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_ld_exported_symbols_list=no + save_LDFLAGS=$LDFLAGS + echo "_main" > conftest.sym + LDFLAGS="$LDFLAGS -Wl,-exported_symbols_list,conftest.sym" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + lt_cv_ld_exported_symbols_list=yes +else + lt_cv_ld_exported_symbols_list=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + LDFLAGS="$save_LDFLAGS" + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_exported_symbols_list" >&5 +$as_echo "$lt_cv_ld_exported_symbols_list" >&6; } + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -force_load linker flag" >&5 +$as_echo_n "checking for -force_load linker flag... " >&6; } +if ${lt_cv_ld_force_load+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_ld_force_load=no + cat > conftest.c << _LT_EOF +int forced_loaded() { return 2;} +_LT_EOF + echo "$LTCC $LTCFLAGS -c -o conftest.o conftest.c" >&5 + $LTCC $LTCFLAGS -c -o conftest.o conftest.c 2>&5 + echo "$AR cru libconftest.a conftest.o" >&5 + $AR cru libconftest.a conftest.o 2>&5 + echo "$RANLIB libconftest.a" >&5 + $RANLIB libconftest.a 2>&5 + cat > conftest.c << _LT_EOF +int main() { return 0;} +_LT_EOF + echo "$LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a" >&5 + $LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a 2>conftest.err + _lt_result=$? + if test -s conftest.err && $GREP force_load conftest.err; then + cat conftest.err >&5 + elif test -f conftest && test $_lt_result -eq 0 && $GREP forced_load conftest >/dev/null 2>&1 ; then + lt_cv_ld_force_load=yes + else + cat conftest.err >&5 + fi + rm -f conftest.err libconftest.a conftest conftest.c + rm -rf conftest.dSYM + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_force_load" >&5 +$as_echo "$lt_cv_ld_force_load" >&6; } + case $host_os in + rhapsody* | darwin1.[012]) + _lt_dar_allow_undefined='${wl}-undefined ${wl}suppress' ;; + darwin1.*) + _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;; + darwin*) # darwin 5.x on + # if running on 10.5 or later, the deployment target defaults + # to the OS version, if on x86, and 10.4, the deployment + # target defaults to 10.4. Don't you love it? + case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in + 10.0,*86*-darwin8*|10.0,*-darwin[91]*) + _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;; + 10.[012]*) + _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;; + 10.*) + _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;; + esac + ;; + esac + if test "$lt_cv_apple_cc_single_mod" = "yes"; then + _lt_dar_single_mod='$single_module' + fi + if test "$lt_cv_ld_exported_symbols_list" = "yes"; then + _lt_dar_export_syms=' ${wl}-exported_symbols_list,$output_objdir/${libname}-symbols.expsym' + else + _lt_dar_export_syms='~$NMEDIT -s $output_objdir/${libname}-symbols.expsym ${lib}' + fi + if test "$DSYMUTIL" != ":" && test "$lt_cv_ld_force_load" = "no"; then + _lt_dsymutil='~$DSYMUTIL $lib || :' + else + _lt_dsymutil= + fi + ;; + esac + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5 +$as_echo_n "checking for ANSI C header files... " >&6; } +if ${ac_cv_header_stdc+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +#include +#include +#include + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_header_stdc=yes +else + ac_cv_header_stdc=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + +if test $ac_cv_header_stdc = yes; then + # SunOS 4.x string.h does not declare mem*, contrary to ANSI. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "memchr" >/dev/null 2>&1; then : + +else + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "free" >/dev/null 2>&1; then : + +else + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. + if test "$cross_compiling" = yes; then : + : +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +#include +#if ((' ' & 0x0FF) == 0x020) +# define ISLOWER(c) ('a' <= (c) && (c) <= 'z') +# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) +#else +# define ISLOWER(c) \ + (('a' <= (c) && (c) <= 'i') \ + || ('j' <= (c) && (c) <= 'r') \ + || ('s' <= (c) && (c) <= 'z')) +# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) +#endif + +#define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) +int +main () +{ + int i; + for (i = 0; i < 256; i++) + if (XOR (islower (i), ISLOWER (i)) + || toupper (i) != TOUPPER (i)) + return 2; + return 0; +} +_ACEOF +if ac_fn_c_try_run "$LINENO"; then : + +else + ac_cv_header_stdc=no +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + +fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5 +$as_echo "$ac_cv_header_stdc" >&6; } +if test $ac_cv_header_stdc = yes; then + +$as_echo "#define STDC_HEADERS 1" >>confdefs.h + +fi + +# On IRIX 5.3, sys/types and inttypes.h are conflicting. +for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \ + inttypes.h stdint.h unistd.h +do : + as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` +ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default +" +if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + + +for ac_header in dlfcn.h +do : + ac_fn_c_check_header_compile "$LINENO" "dlfcn.h" "ac_cv_header_dlfcn_h" "$ac_includes_default +" +if test "x$ac_cv_header_dlfcn_h" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_DLFCN_H 1 +_ACEOF + +fi + +done + + + + + +# Set options + + + + enable_dlopen=no + + + enable_win32_dll=no + + + # Check whether --enable-shared was given. +if test "${enable_shared+set}" = set; then : + enableval=$enable_shared; p=${PACKAGE-default} + case $enableval in + yes) enable_shared=yes ;; + no) enable_shared=no ;; + *) + enable_shared=no + # Look at the argument we got. We use all the common list separators. + lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," + for pkg in $enableval; do + IFS="$lt_save_ifs" + if test "X$pkg" = "X$p"; then + enable_shared=yes + fi + done + IFS="$lt_save_ifs" + ;; + esac +else + enable_shared=yes +fi + + + + + + + + + + # Check whether --enable-static was given. +if test "${enable_static+set}" = set; then : + enableval=$enable_static; p=${PACKAGE-default} + case $enableval in + yes) enable_static=yes ;; + no) enable_static=no ;; + *) + enable_static=no + # Look at the argument we got. We use all the common list separators. + lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," + for pkg in $enableval; do + IFS="$lt_save_ifs" + if test "X$pkg" = "X$p"; then + enable_static=yes + fi + done + IFS="$lt_save_ifs" + ;; + esac +else + enable_static=yes +fi + + + + + + + + + + +# Check whether --with-pic was given. +if test "${with_pic+set}" = set; then : + withval=$with_pic; lt_p=${PACKAGE-default} + case $withval in + yes|no) pic_mode=$withval ;; + *) + pic_mode=default + # Look at the argument we got. We use all the common list separators. + lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," + for lt_pkg in $withval; do + IFS="$lt_save_ifs" + if test "X$lt_pkg" = "X$lt_p"; then + pic_mode=yes + fi + done + IFS="$lt_save_ifs" + ;; + esac +else + pic_mode=default +fi + + +test -z "$pic_mode" && pic_mode=default + + + + + + + + # Check whether --enable-fast-install was given. +if test "${enable_fast_install+set}" = set; then : + enableval=$enable_fast_install; p=${PACKAGE-default} + case $enableval in + yes) enable_fast_install=yes ;; + no) enable_fast_install=no ;; + *) + enable_fast_install=no + # Look at the argument we got. We use all the common list separators. + lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," + for pkg in $enableval; do + IFS="$lt_save_ifs" + if test "X$pkg" = "X$p"; then + enable_fast_install=yes + fi + done + IFS="$lt_save_ifs" + ;; + esac +else + enable_fast_install=yes +fi + + + + + + + + + + + +# This can be used to rebuild libtool when needed +LIBTOOL_DEPS="$ltmain" + +# Always use our own libtool. +LIBTOOL='$(SHELL) $(top_builddir)/libtool' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +test -z "$LN_S" && LN_S="ln -s" + + + + + + + + + + + + + + +if test -n "${ZSH_VERSION+set}" ; then + setopt NO_GLOB_SUBST +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for objdir" >&5 +$as_echo_n "checking for objdir... " >&6; } +if ${lt_cv_objdir+:} false; then : + $as_echo_n "(cached) " >&6 +else + rm -f .libs 2>/dev/null +mkdir .libs 2>/dev/null +if test -d .libs; then + lt_cv_objdir=.libs +else + # MS-DOS does not allow filenames that begin with a dot. + lt_cv_objdir=_libs +fi +rmdir .libs 2>/dev/null +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_objdir" >&5 +$as_echo "$lt_cv_objdir" >&6; } +objdir=$lt_cv_objdir + + + + + +cat >>confdefs.h <<_ACEOF +#define LT_OBJDIR "$lt_cv_objdir/" +_ACEOF + + + + +case $host_os in +aix3*) + # AIX sometimes has problems with the GCC collect2 program. For some + # reason, if we set the COLLECT_NAMES environment variable, the problems + # vanish in a puff of smoke. + if test "X${COLLECT_NAMES+set}" != Xset; then + COLLECT_NAMES= + export COLLECT_NAMES + fi + ;; +esac + +# Global variables: +ofile=libtool +can_build_shared=yes + +# All known linkers require a `.a' archive for static linking (except MSVC, +# which needs '.lib'). +libext=a + +with_gnu_ld="$lt_cv_prog_gnu_ld" + +old_CC="$CC" +old_CFLAGS="$CFLAGS" + +# Set sane defaults for various variables +test -z "$CC" && CC=cc +test -z "$LTCC" && LTCC=$CC +test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS +test -z "$LD" && LD=ld +test -z "$ac_objext" && ac_objext=o + +for cc_temp in $compiler""; do + case $cc_temp in + compile | *[\\/]compile | ccache | *[\\/]ccache ) ;; + distcc | *[\\/]distcc | purify | *[\\/]purify ) ;; + \-*) ;; + *) break;; + esac +done +cc_basename=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"` + + +# Only perform the check for file, if the check method requires it +test -z "$MAGIC_CMD" && MAGIC_CMD=file +case $deplibs_check_method in +file_magic*) + if test "$file_magic_cmd" = '$MAGIC_CMD'; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ${ac_tool_prefix}file" >&5 +$as_echo_n "checking for ${ac_tool_prefix}file... " >&6; } +if ${lt_cv_path_MAGIC_CMD+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $MAGIC_CMD in +[\\/*] | ?:[\\/]*) + lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path. + ;; +*) + lt_save_MAGIC_CMD="$MAGIC_CMD" + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + ac_dummy="/usr/bin$PATH_SEPARATOR$PATH" + for ac_dir in $ac_dummy; do + IFS="$lt_save_ifs" + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/${ac_tool_prefix}file; then + lt_cv_path_MAGIC_CMD="$ac_dir/${ac_tool_prefix}file" + if test -n "$file_magic_test_file"; then + case $deplibs_check_method in + "file_magic "*) + file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` + MAGIC_CMD="$lt_cv_path_MAGIC_CMD" + if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | + $EGREP "$file_magic_regex" > /dev/null; then + : + else + cat <<_LT_EOF 1>&2 + +*** Warning: the command libtool uses to detect shared libraries, +*** $file_magic_cmd, produces output that libtool cannot recognize. +*** The result is that libtool may fail to recognize shared libraries +*** as such. This will affect the creation of libtool libraries that +*** depend on shared libraries, but programs linked with such libtool +*** libraries will work regardless of this problem. Nevertheless, you +*** may want to report the problem to your system manager and/or to +*** bug-libtool@gnu.org + +_LT_EOF + fi ;; + esac + fi + break + fi + done + IFS="$lt_save_ifs" + MAGIC_CMD="$lt_save_MAGIC_CMD" + ;; +esac +fi + +MAGIC_CMD="$lt_cv_path_MAGIC_CMD" +if test -n "$MAGIC_CMD"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MAGIC_CMD" >&5 +$as_echo "$MAGIC_CMD" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + + + +if test -z "$lt_cv_path_MAGIC_CMD"; then + if test -n "$ac_tool_prefix"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for file" >&5 +$as_echo_n "checking for file... " >&6; } +if ${lt_cv_path_MAGIC_CMD+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $MAGIC_CMD in +[\\/*] | ?:[\\/]*) + lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path. + ;; +*) + lt_save_MAGIC_CMD="$MAGIC_CMD" + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + ac_dummy="/usr/bin$PATH_SEPARATOR$PATH" + for ac_dir in $ac_dummy; do + IFS="$lt_save_ifs" + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/file; then + lt_cv_path_MAGIC_CMD="$ac_dir/file" + if test -n "$file_magic_test_file"; then + case $deplibs_check_method in + "file_magic "*) + file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` + MAGIC_CMD="$lt_cv_path_MAGIC_CMD" + if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | + $EGREP "$file_magic_regex" > /dev/null; then + : + else + cat <<_LT_EOF 1>&2 + +*** Warning: the command libtool uses to detect shared libraries, +*** $file_magic_cmd, produces output that libtool cannot recognize. +*** The result is that libtool may fail to recognize shared libraries +*** as such. This will affect the creation of libtool libraries that +*** depend on shared libraries, but programs linked with such libtool +*** libraries will work regardless of this problem. Nevertheless, you +*** may want to report the problem to your system manager and/or to +*** bug-libtool@gnu.org + +_LT_EOF + fi ;; + esac + fi + break + fi + done + IFS="$lt_save_ifs" + MAGIC_CMD="$lt_save_MAGIC_CMD" + ;; +esac +fi + +MAGIC_CMD="$lt_cv_path_MAGIC_CMD" +if test -n "$MAGIC_CMD"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MAGIC_CMD" >&5 +$as_echo "$MAGIC_CMD" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + else + MAGIC_CMD=: + fi +fi + + fi + ;; +esac + +# Use C for the default configuration in the libtool script + +lt_save_CC="$CC" +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + +# Source file extension for C test sources. +ac_ext=c + +# Object file extension for compiled C test sources. +objext=o +objext=$objext + +# Code to be used in simple compile tests +lt_simple_compile_test_code="int some_variable = 0;" + +# Code to be used in simple link tests +lt_simple_link_test_code='int main(){return(0);}' + + + + + + + +# If no C compiler was specified, use CC. +LTCC=${LTCC-"$CC"} + +# If no C compiler flags were specified, use CFLAGS. +LTCFLAGS=${LTCFLAGS-"$CFLAGS"} + +# Allow CC to be a program name with arguments. +compiler=$CC + +# Save the default compiler, since it gets overwritten when the other +# tags are being tested, and _LT_TAGVAR(compiler, []) is a NOP. +compiler_DEFAULT=$CC + +# save warnings/boilerplate of simple test code +ac_outfile=conftest.$ac_objext +echo "$lt_simple_compile_test_code" >conftest.$ac_ext +eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_compiler_boilerplate=`cat conftest.err` +$RM conftest* + +ac_outfile=conftest.$ac_objext +echo "$lt_simple_link_test_code" >conftest.$ac_ext +eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_linker_boilerplate=`cat conftest.err` +$RM -r conftest* + + +if test -n "$compiler"; then + +lt_prog_compiler_no_builtin_flag= + +if test "$GCC" = yes; then + case $cc_basename in + nvcc*) + lt_prog_compiler_no_builtin_flag=' -Xcompiler -fno-builtin' ;; + *) + lt_prog_compiler_no_builtin_flag=' -fno-builtin' ;; + esac + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -fno-rtti -fno-exceptions" >&5 +$as_echo_n "checking if $compiler supports -fno-rtti -fno-exceptions... " >&6; } +if ${lt_cv_prog_compiler_rtti_exceptions+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_rtti_exceptions=no + ac_outfile=conftest.$ac_objext + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + lt_compiler_flag="-fno-rtti -fno-exceptions" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + # The option is referenced via a variable to avoid confusing sed. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) + (eval "$lt_compile" 2>conftest.err) + ac_status=$? + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s "$ac_outfile"; then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings other than the usual output. + $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then + lt_cv_prog_compiler_rtti_exceptions=yes + fi + fi + $RM conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_rtti_exceptions" >&5 +$as_echo "$lt_cv_prog_compiler_rtti_exceptions" >&6; } + +if test x"$lt_cv_prog_compiler_rtti_exceptions" = xyes; then + lt_prog_compiler_no_builtin_flag="$lt_prog_compiler_no_builtin_flag -fno-rtti -fno-exceptions" +else + : +fi + +fi + + + + + + + lt_prog_compiler_wl= +lt_prog_compiler_pic= +lt_prog_compiler_static= + + + if test "$GCC" = yes; then + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_static='-static' + + case $host_os in + aix*) + # All AIX code is PIC. + if test "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + lt_prog_compiler_static='-Bstatic' + fi + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + lt_prog_compiler_pic='-fPIC' + ;; + m68k) + # FIXME: we need at least 68020 code to build shared libraries, but + # adding the `-m68020' flag to GCC prevents building anything better, + # like `-m68040'. + lt_prog_compiler_pic='-m68020 -resident32 -malways-restore-a4' + ;; + esac + ;; + + beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) + # PIC is the default for these OSes. + ;; + + mingw* | cygwin* | pw32* | os2* | cegcc*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + # Although the cygwin gcc ignores -fPIC, still need this for old-style + # (--disable-auto-import) libraries + lt_prog_compiler_pic='-DDLL_EXPORT' + ;; + + darwin* | rhapsody*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + lt_prog_compiler_pic='-fno-common' + ;; + + haiku*) + # PIC is the default for Haiku. + # The "-static" flag exists, but is broken. + lt_prog_compiler_static= + ;; + + hpux*) + # PIC is the default for 64-bit PA HP-UX, but not for 32-bit + # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag + # sets the default TLS model and affects inlining. + case $host_cpu in + hppa*64*) + # +Z the default + ;; + *) + lt_prog_compiler_pic='-fPIC' + ;; + esac + ;; + + interix[3-9]*) + # Interix 3.x gcc -fpic/-fPIC options generate broken code. + # Instead, we relocate shared libraries at runtime. + ;; + + msdosdjgpp*) + # Just because we use GCC doesn't mean we suddenly get shared libraries + # on systems that don't support them. + lt_prog_compiler_can_build_shared=no + enable_shared=no + ;; + + *nto* | *qnx*) + # QNX uses GNU C++, but need to define -shared option too, otherwise + # it will coredump. + lt_prog_compiler_pic='-fPIC -shared' + ;; + + sysv4*MP*) + if test -d /usr/nec; then + lt_prog_compiler_pic=-Kconform_pic + fi + ;; + + *) + lt_prog_compiler_pic='-fPIC' + ;; + esac + + case $cc_basename in + nvcc*) # Cuda Compiler Driver 2.2 + lt_prog_compiler_wl='-Xlinker ' + if test -n "$lt_prog_compiler_pic"; then + lt_prog_compiler_pic="-Xcompiler $lt_prog_compiler_pic" + fi + ;; + esac + else + # PORTME Check for flag to pass linker flags through the system compiler. + case $host_os in + aix*) + lt_prog_compiler_wl='-Wl,' + if test "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + lt_prog_compiler_static='-Bstatic' + else + lt_prog_compiler_static='-bnso -bI:/lib/syscalls.exp' + fi + ;; + + mingw* | cygwin* | pw32* | os2* | cegcc*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + lt_prog_compiler_pic='-DDLL_EXPORT' + ;; + + hpux9* | hpux10* | hpux11*) + lt_prog_compiler_wl='-Wl,' + # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but + # not for PA HP-UX. + case $host_cpu in + hppa*64*|ia64*) + # +Z the default + ;; + *) + lt_prog_compiler_pic='+Z' + ;; + esac + # Is there a better lt_prog_compiler_static that works with the bundled CC? + lt_prog_compiler_static='${wl}-a ${wl}archive' + ;; + + irix5* | irix6* | nonstopux*) + lt_prog_compiler_wl='-Wl,' + # PIC (with -KPIC) is the default. + lt_prog_compiler_static='-non_shared' + ;; + + linux* | k*bsd*-gnu | kopensolaris*-gnu) + case $cc_basename in + # old Intel for x86_64 which still supported -KPIC. + ecc*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-static' + ;; + # icc used to be incompatible with GCC. + # ICC 10 doesn't accept -KPIC any more. + icc* | ifort*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-fPIC' + lt_prog_compiler_static='-static' + ;; + # Lahey Fortran 8.1. + lf95*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='--shared' + lt_prog_compiler_static='--static' + ;; + nagfor*) + # NAG Fortran compiler + lt_prog_compiler_wl='-Wl,-Wl,,' + lt_prog_compiler_pic='-PIC' + lt_prog_compiler_static='-Bstatic' + ;; + pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*) + # Portland Group compilers (*not* the Pentium gcc compiler, + # which looks to be a dead project) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-fpic' + lt_prog_compiler_static='-Bstatic' + ;; + ccc*) + lt_prog_compiler_wl='-Wl,' + # All Alpha code is PIC. + lt_prog_compiler_static='-non_shared' + ;; + xl* | bgxl* | bgf* | mpixl*) + # IBM XL C 8.0/Fortran 10.1, 11.1 on PPC and BlueGene + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-qpic' + lt_prog_compiler_static='-qstaticlink' + ;; + *) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ Ceres\ Fortran* | *Sun*Fortran*\ [1-7].* | *Sun*Fortran*\ 8.[0-3]*) + # Sun Fortran 8.3 passes all unrecognized flags to the linker + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + lt_prog_compiler_wl='' + ;; + *Sun\ F* | *Sun*Fortran*) + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + lt_prog_compiler_wl='-Qoption ld ' + ;; + *Sun\ C*) + # Sun C 5.9 + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + lt_prog_compiler_wl='-Wl,' + ;; + *Intel*\ [CF]*Compiler*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-fPIC' + lt_prog_compiler_static='-static' + ;; + *Portland\ Group*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-fpic' + lt_prog_compiler_static='-Bstatic' + ;; + esac + ;; + esac + ;; + + newsos6) + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + ;; + + *nto* | *qnx*) + # QNX uses GNU C++, but need to define -shared option too, otherwise + # it will coredump. + lt_prog_compiler_pic='-fPIC -shared' + ;; + + osf3* | osf4* | osf5*) + lt_prog_compiler_wl='-Wl,' + # All OSF/1 code is PIC. + lt_prog_compiler_static='-non_shared' + ;; + + rdos*) + lt_prog_compiler_static='-non_shared' + ;; + + solaris*) + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + case $cc_basename in + f77* | f90* | f95* | sunf77* | sunf90* | sunf95*) + lt_prog_compiler_wl='-Qoption ld ';; + *) + lt_prog_compiler_wl='-Wl,';; + esac + ;; + + sunos4*) + lt_prog_compiler_wl='-Qoption ld ' + lt_prog_compiler_pic='-PIC' + lt_prog_compiler_static='-Bstatic' + ;; + + sysv4 | sysv4.2uw2* | sysv4.3*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + ;; + + sysv4*MP*) + if test -d /usr/nec ;then + lt_prog_compiler_pic='-Kconform_pic' + lt_prog_compiler_static='-Bstatic' + fi + ;; + + sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + ;; + + unicos*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_can_build_shared=no + ;; + + uts4*) + lt_prog_compiler_pic='-pic' + lt_prog_compiler_static='-Bstatic' + ;; + + *) + lt_prog_compiler_can_build_shared=no + ;; + esac + fi + +case $host_os in + # For platforms which do not support PIC, -DPIC is meaningless: + *djgpp*) + lt_prog_compiler_pic= + ;; + *) + lt_prog_compiler_pic="$lt_prog_compiler_pic -DPIC" + ;; +esac + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $compiler option to produce PIC" >&5 +$as_echo_n "checking for $compiler option to produce PIC... " >&6; } +if ${lt_cv_prog_compiler_pic+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_pic=$lt_prog_compiler_pic +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic" >&5 +$as_echo "$lt_cv_prog_compiler_pic" >&6; } +lt_prog_compiler_pic=$lt_cv_prog_compiler_pic + +# +# Check to make sure the PIC flag actually works. +# +if test -n "$lt_prog_compiler_pic"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler PIC flag $lt_prog_compiler_pic works" >&5 +$as_echo_n "checking if $compiler PIC flag $lt_prog_compiler_pic works... " >&6; } +if ${lt_cv_prog_compiler_pic_works+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_pic_works=no + ac_outfile=conftest.$ac_objext + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + lt_compiler_flag="$lt_prog_compiler_pic -DPIC" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + # The option is referenced via a variable to avoid confusing sed. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) + (eval "$lt_compile" 2>conftest.err) + ac_status=$? + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s "$ac_outfile"; then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings other than the usual output. + $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then + lt_cv_prog_compiler_pic_works=yes + fi + fi + $RM conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_works" >&5 +$as_echo "$lt_cv_prog_compiler_pic_works" >&6; } + +if test x"$lt_cv_prog_compiler_pic_works" = xyes; then + case $lt_prog_compiler_pic in + "" | " "*) ;; + *) lt_prog_compiler_pic=" $lt_prog_compiler_pic" ;; + esac +else + lt_prog_compiler_pic= + lt_prog_compiler_can_build_shared=no +fi + +fi + + + + + + + + + + + +# +# Check to make sure the static flag actually works. +# +wl=$lt_prog_compiler_wl eval lt_tmp_static_flag=\"$lt_prog_compiler_static\" +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler static flag $lt_tmp_static_flag works" >&5 +$as_echo_n "checking if $compiler static flag $lt_tmp_static_flag works... " >&6; } +if ${lt_cv_prog_compiler_static_works+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_static_works=no + save_LDFLAGS="$LDFLAGS" + LDFLAGS="$LDFLAGS $lt_tmp_static_flag" + echo "$lt_simple_link_test_code" > conftest.$ac_ext + if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then + # The linker can only warn and ignore the option if not recognized + # So say no if there are warnings + if test -s conftest.err; then + # Append any errors to the config.log. + cat conftest.err 1>&5 + $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if diff conftest.exp conftest.er2 >/dev/null; then + lt_cv_prog_compiler_static_works=yes + fi + else + lt_cv_prog_compiler_static_works=yes + fi + fi + $RM -r conftest* + LDFLAGS="$save_LDFLAGS" + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_static_works" >&5 +$as_echo "$lt_cv_prog_compiler_static_works" >&6; } + +if test x"$lt_cv_prog_compiler_static_works" = xyes; then + : +else + lt_prog_compiler_static= +fi + + + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 +$as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; } +if ${lt_cv_prog_compiler_c_o+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_c_o=no + $RM -r conftest 2>/dev/null + mkdir conftest + cd conftest + mkdir out + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + lt_compiler_flag="-o out/conftest2.$ac_objext" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) + (eval "$lt_compile" 2>out/conftest.err) + ac_status=$? + cat out/conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s out/conftest2.$ac_objext + then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings + $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp + $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 + if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then + lt_cv_prog_compiler_c_o=yes + fi + fi + chmod u+w . 2>&5 + $RM conftest* + # SGI C++ compiler will create directory out/ii_files/ for + # template instantiation + test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files + $RM out/* && rmdir out + cd .. + $RM -r conftest + $RM conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o" >&5 +$as_echo "$lt_cv_prog_compiler_c_o" >&6; } + + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 +$as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; } +if ${lt_cv_prog_compiler_c_o+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_c_o=no + $RM -r conftest 2>/dev/null + mkdir conftest + cd conftest + mkdir out + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + lt_compiler_flag="-o out/conftest2.$ac_objext" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) + (eval "$lt_compile" 2>out/conftest.err) + ac_status=$? + cat out/conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s out/conftest2.$ac_objext + then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings + $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp + $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 + if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then + lt_cv_prog_compiler_c_o=yes + fi + fi + chmod u+w . 2>&5 + $RM conftest* + # SGI C++ compiler will create directory out/ii_files/ for + # template instantiation + test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files + $RM out/* && rmdir out + cd .. + $RM -r conftest + $RM conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o" >&5 +$as_echo "$lt_cv_prog_compiler_c_o" >&6; } + + + + +hard_links="nottested" +if test "$lt_cv_prog_compiler_c_o" = no && test "$need_locks" != no; then + # do not overwrite the value of need_locks provided by the user + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if we can lock with hard links" >&5 +$as_echo_n "checking if we can lock with hard links... " >&6; } + hard_links=yes + $RM conftest* + ln conftest.a conftest.b 2>/dev/null && hard_links=no + touch conftest.a + ln conftest.a conftest.b 2>&5 || hard_links=no + ln conftest.a conftest.b 2>/dev/null && hard_links=no + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $hard_links" >&5 +$as_echo "$hard_links" >&6; } + if test "$hard_links" = no; then + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&5 +$as_echo "$as_me: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&2;} + need_locks=warn + fi +else + need_locks=no +fi + + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $compiler linker ($LD) supports shared libraries" >&5 +$as_echo_n "checking whether the $compiler linker ($LD) supports shared libraries... " >&6; } + + runpath_var= + allow_undefined_flag= + always_export_symbols=no + archive_cmds= + archive_expsym_cmds= + compiler_needs_object=no + enable_shared_with_static_runtimes=no + export_dynamic_flag_spec= + export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' + hardcode_automatic=no + hardcode_direct=no + hardcode_direct_absolute=no + hardcode_libdir_flag_spec= + hardcode_libdir_separator= + hardcode_minus_L=no + hardcode_shlibpath_var=unsupported + inherit_rpath=no + link_all_deplibs=unknown + module_cmds= + module_expsym_cmds= + old_archive_from_new_cmds= + old_archive_from_expsyms_cmds= + thread_safe_flag_spec= + whole_archive_flag_spec= + # include_expsyms should be a list of space-separated symbols to be *always* + # included in the symbol list + include_expsyms= + # exclude_expsyms can be an extended regexp of symbols to exclude + # it will be wrapped by ` (' and `)$', so one must not match beginning or + # end of line. Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc', + # as well as any symbol that contains `d'. + exclude_expsyms='_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*' + # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out + # platforms (ab)use it in PIC code, but their linkers get confused if + # the symbol is explicitly referenced. Since portable code cannot + # rely on this symbol name, it's probably fine to never include it in + # preloaded symbol tables. + # Exclude shared library initialization/finalization symbols. + extract_expsyms_cmds= + + case $host_os in + cygwin* | mingw* | pw32* | cegcc*) + # FIXME: the MSVC++ port hasn't been tested in a loooong time + # When not using gcc, we currently assume that we are using + # Microsoft Visual C++. + if test "$GCC" != yes; then + with_gnu_ld=no + fi + ;; + interix*) + # we just hope/assume this is gcc and not c89 (= MSVC++) + with_gnu_ld=yes + ;; + openbsd*) + with_gnu_ld=no + ;; + linux* | k*bsd*-gnu | gnu*) + link_all_deplibs=no + ;; + esac + + ld_shlibs=yes + + # On some targets, GNU ld is compatible enough with the native linker + # that we're better off using the native interface for both. + lt_use_gnu_ld_interface=no + if test "$with_gnu_ld" = yes; then + case $host_os in + aix*) + # The AIX port of GNU ld has always aspired to compatibility + # with the native linker. However, as the warning in the GNU ld + # block says, versions before 2.19.5* couldn't really create working + # shared libraries, regardless of the interface used. + case `$LD -v 2>&1` in + *\ \(GNU\ Binutils\)\ 2.19.5*) ;; + *\ \(GNU\ Binutils\)\ 2.[2-9]*) ;; + *\ \(GNU\ Binutils\)\ [3-9]*) ;; + *) + lt_use_gnu_ld_interface=yes + ;; + esac + ;; + *) + lt_use_gnu_ld_interface=yes + ;; + esac + fi + + if test "$lt_use_gnu_ld_interface" = yes; then + # If archive_cmds runs LD, not CC, wlarc should be empty + wlarc='${wl}' + + # Set some defaults for GNU ld with shared library support. These + # are reset later if shared libraries are not supported. Putting them + # here allows them to be overridden if necessary. + runpath_var=LD_RUN_PATH + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + export_dynamic_flag_spec='${wl}--export-dynamic' + # ancient GNU ld didn't support --whole-archive et. al. + if $LD --help 2>&1 | $GREP 'no-whole-archive' > /dev/null; then + whole_archive_flag_spec="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' + else + whole_archive_flag_spec= + fi + supports_anon_versioning=no + case `$LD -v 2>&1` in + *GNU\ gold*) supports_anon_versioning=yes ;; + *\ [01].* | *\ 2.[0-9].* | *\ 2.10.*) ;; # catch versions < 2.11 + *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ... + *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ... + *\ 2.11.*) ;; # other 2.11 versions + *) supports_anon_versioning=yes ;; + esac + + # See if GNU ld supports shared libraries. + case $host_os in + aix[3-9]*) + # On AIX/PPC, the GNU linker is very broken + if test "$host_cpu" != ia64; then + ld_shlibs=no + cat <<_LT_EOF 1>&2 + +*** Warning: the GNU linker, at least up to release 2.19, is reported +*** to be unable to reliably create shared libraries on AIX. +*** Therefore, libtool is disabling shared libraries support. If you +*** really care for shared libraries, you may want to install binutils +*** 2.20 or above, or modify your PATH so that a non-GNU linker is found. +*** You will then need to restart the configuration process. + +_LT_EOF + fi + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds='' + ;; + m68k) + archive_cmds='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' + hardcode_libdir_flag_spec='-L$libdir' + hardcode_minus_L=yes + ;; + esac + ;; + + beos*) + if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + allow_undefined_flag=unsupported + # Joseph Beckenbach says some releases of gcc + # support --undefined. This deserves some investigation. FIXME + archive_cmds='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + else + ld_shlibs=no + fi + ;; + + cygwin* | mingw* | pw32* | cegcc*) + # _LT_TAGVAR(hardcode_libdir_flag_spec, ) is actually meaningless, + # as there is no search path for DLLs. + hardcode_libdir_flag_spec='-L$libdir' + export_dynamic_flag_spec='${wl}--export-all-symbols' + allow_undefined_flag=unsupported + always_export_symbols=no + enable_shared_with_static_runtimes=yes + export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1 DATA/;s/^.*[ ]__nm__\([^ ]*\)[ ][^ ]*/\1 DATA/;/^I[ ]/d;/^[AITW][ ]/s/.* //'\'' | sort | uniq > $export_symbols' + exclude_expsyms='[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname' + + if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + # If the export-symbols file already is a .def file (1st line + # is EXPORTS), use it as is; otherwise, prepend... + archive_expsym_cmds='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then + cp $export_symbols $output_objdir/$soname.def; + else + echo EXPORTS > $output_objdir/$soname.def; + cat $export_symbols >> $output_objdir/$soname.def; + fi~ + $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + else + ld_shlibs=no + fi + ;; + + haiku*) + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + link_all_deplibs=yes + ;; + + interix[3-9]*) + hardcode_direct=no + hardcode_shlibpath_var=no + hardcode_libdir_flag_spec='${wl}-rpath,$libdir' + export_dynamic_flag_spec='${wl}-E' + # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. + # Instead, shared libraries are loaded at an image base (0x10000000 by + # default) and relocated if they conflict, which is a slow very memory + # consuming and fragmenting process. To avoid this, we pick a random, + # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link + # time. Moving up from 0x10000000 also allows more sbrk(2) space. + archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + archive_expsym_cmds='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + ;; + + gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu) + tmp_diet=no + if test "$host_os" = linux-dietlibc; then + case $cc_basename in + diet\ *) tmp_diet=yes;; # linux-dietlibc with static linking (!diet-dyn) + esac + fi + if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \ + && test "$tmp_diet" = no + then + tmp_addflag=' $pic_flag' + tmp_sharedflag='-shared' + case $cc_basename,$host_cpu in + pgcc*) # Portland Group C compiler + whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' + tmp_addflag=' $pic_flag' + ;; + pgf77* | pgf90* | pgf95* | pgfortran*) + # Portland Group f77 and f90 compilers + whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' + tmp_addflag=' $pic_flag -Mnomain' ;; + ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64 + tmp_addflag=' -i_dynamic' ;; + efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64 + tmp_addflag=' -i_dynamic -nofor_main' ;; + ifc* | ifort*) # Intel Fortran compiler + tmp_addflag=' -nofor_main' ;; + lf95*) # Lahey Fortran 8.1 + whole_archive_flag_spec= + tmp_sharedflag='--shared' ;; + xl[cC]* | bgxl[cC]* | mpixl[cC]*) # IBM XL C 8.0 on PPC (deal with xlf below) + tmp_sharedflag='-qmkshrobj' + tmp_addflag= ;; + nvcc*) # Cuda Compiler Driver 2.2 + whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' + compiler_needs_object=yes + ;; + esac + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) # Sun C 5.9 + whole_archive_flag_spec='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' + compiler_needs_object=yes + tmp_sharedflag='-G' ;; + *Sun\ F*) # Sun Fortran 8.3 + tmp_sharedflag='-G' ;; + esac + archive_cmds='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + + if test "x$supports_anon_versioning" = xyes; then + archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~ + cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ + echo "local: *; };" >> $output_objdir/$libname.ver~ + $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' + fi + + case $cc_basename in + xlf* | bgf* | bgxlf* | mpixlf*) + # IBM XL Fortran 10.1 on PPC cannot create shared libs itself + whole_archive_flag_spec='--whole-archive$convenience --no-whole-archive' + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + archive_cmds='$LD -shared $libobjs $deplibs $linker_flags -soname $soname -o $lib' + if test "x$supports_anon_versioning" = xyes; then + archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~ + cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ + echo "local: *; };" >> $output_objdir/$libname.ver~ + $LD -shared $libobjs $deplibs $linker_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib' + fi + ;; + esac + else + ld_shlibs=no + fi + ;; + + netbsd* | netbsdelf*-gnu) + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + archive_cmds='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' + wlarc= + else + archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + fi + ;; + + solaris*) + if $LD -v 2>&1 | $GREP 'BFD 2\.8' > /dev/null; then + ld_shlibs=no + cat <<_LT_EOF 1>&2 + +*** Warning: The releases 2.8.* of the GNU linker cannot reliably +*** create shared libraries on Solaris systems. Therefore, libtool +*** is disabling shared libraries support. We urge you to upgrade GNU +*** binutils to release 2.9.1 or newer. Another option is to modify +*** your PATH or compiler configuration so that the native linker is +*** used, and then restart. + +_LT_EOF + elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + else + ld_shlibs=no + fi + ;; + + sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*) + case `$LD -v 2>&1` in + *\ [01].* | *\ 2.[0-9].* | *\ 2.1[0-5].*) + ld_shlibs=no + cat <<_LT_EOF 1>&2 + +*** Warning: Releases of the GNU linker prior to 2.16.91.0.3 can not +*** reliably create shared libraries on SCO systems. Therefore, libtool +*** is disabling shared libraries support. We urge you to upgrade GNU +*** binutils to release 2.16.91.0.3 or newer. Another option is to modify +*** your PATH or compiler configuration so that the native linker is +*** used, and then restart. + +_LT_EOF + ;; + *) + # For security reasons, it is highly recommended that you always + # use absolute paths for naming shared libraries, and exclude the + # DT_RUNPATH tag from executables and libraries. But doing so + # requires that you compile everything twice, which is a pain. + if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + else + ld_shlibs=no + fi + ;; + esac + ;; + + sunos4*) + archive_cmds='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags' + wlarc= + hardcode_direct=yes + hardcode_shlibpath_var=no + ;; + + *) + if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + else + ld_shlibs=no + fi + ;; + esac + + if test "$ld_shlibs" = no; then + runpath_var= + hardcode_libdir_flag_spec= + export_dynamic_flag_spec= + whole_archive_flag_spec= + fi + else + # PORTME fill in a description of your system's linker (not GNU ld) + case $host_os in + aix3*) + allow_undefined_flag=unsupported + always_export_symbols=yes + archive_expsym_cmds='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname' + # Note: this linker hardcodes the directories in LIBPATH if there + # are no directories specified by -L. + hardcode_minus_L=yes + if test "$GCC" = yes && test -z "$lt_prog_compiler_static"; then + # Neither direct hardcoding nor static linking is supported with a + # broken collect2. + hardcode_direct=unsupported + fi + ;; + + aix[4-9]*) + if test "$host_cpu" = ia64; then + # On IA64, the linker does run time linking by default, so we don't + # have to do anything special. + aix_use_runtimelinking=no + exp_sym_flag='-Bexport' + no_entry_flag="" + else + # If we're using GNU nm, then we don't want the "-C" option. + # -C means demangle to AIX nm, but means don't demangle with GNU nm + # Also, AIX nm treats weak defined symbols like other global + # defined symbols, whereas GNU nm marks them as "W". + if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then + export_symbols_cmds='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' + else + export_symbols_cmds='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' + fi + aix_use_runtimelinking=no + + # Test if we are trying to use run time linking or normal + # AIX style linking. If -brtl is somewhere in LDFLAGS, we + # need to do runtime linking. + case $host_os in aix4.[23]|aix4.[23].*|aix[5-9]*) + for ld_flag in $LDFLAGS; do + if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then + aix_use_runtimelinking=yes + break + fi + done + ;; + esac + + exp_sym_flag='-bexport' + no_entry_flag='-bnoentry' + fi + + # When large executables or shared objects are built, AIX ld can + # have problems creating the table of contents. If linking a library + # or program results in "error TOC overflow" add -mminimal-toc to + # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not + # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. + + archive_cmds='' + hardcode_direct=yes + hardcode_direct_absolute=yes + hardcode_libdir_separator=':' + link_all_deplibs=yes + file_list_spec='${wl}-f,' + + if test "$GCC" = yes; then + case $host_os in aix4.[012]|aix4.[012].*) + # We only want to do this on AIX 4.2 and lower, the check + # below for broken collect2 doesn't work under 4.3+ + collect2name=`${CC} -print-prog-name=collect2` + if test -f "$collect2name" && + strings "$collect2name" | $GREP resolve_lib_name >/dev/null + then + # We have reworked collect2 + : + else + # We have old collect2 + hardcode_direct=unsupported + # It fails to find uninstalled libraries when the uninstalled + # path is not listed in the libpath. Setting hardcode_minus_L + # to unsupported forces relinking + hardcode_minus_L=yes + hardcode_libdir_flag_spec='-L$libdir' + hardcode_libdir_separator= + fi + ;; + esac + shared_flag='-shared' + if test "$aix_use_runtimelinking" = yes; then + shared_flag="$shared_flag "'${wl}-G' + fi + link_all_deplibs=no + else + # not using gcc + if test "$host_cpu" = ia64; then + # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release + # chokes on -Wl,-G. The following line is correct: + shared_flag='-G' + else + if test "$aix_use_runtimelinking" = yes; then + shared_flag='${wl}-G' + else + shared_flag='${wl}-bM:SRE' + fi + fi + fi + + export_dynamic_flag_spec='${wl}-bexpall' + # It seems that -bexpall does not export symbols beginning with + # underscore (_), so it is better to generate a list of symbols to export. + always_export_symbols=yes + if test "$aix_use_runtimelinking" = yes; then + # Warning - without using the other runtime loading flags (-brtl), + # -berok will link without error, but may produce a broken library. + allow_undefined_flag='-berok' + # Determine the default libpath from the value encoded in an + # empty executable. + if test "${lt_cv_aix_libpath+set}" = set; then + aix_libpath=$lt_cv_aix_libpath +else + if ${lt_cv_aix_libpath_+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + + lt_aix_libpath_sed=' + /Import File Strings/,/^$/ { + /^0/ { + s/^0 *\([^ ]*\) *$/\1/ + p + } + }' + lt_cv_aix_libpath_=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` + # Check for a 64-bit object if we didn't find anything. + if test -z "$lt_cv_aix_libpath_"; then + lt_cv_aix_libpath_=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` + fi +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + if test -z "$lt_cv_aix_libpath_"; then + lt_cv_aix_libpath_="/usr/lib:/lib" + fi + +fi + + aix_libpath=$lt_cv_aix_libpath_ +fi + + hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath" + archive_expsym_cmds='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then func_echo_all "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" + else + if test "$host_cpu" = ia64; then + hardcode_libdir_flag_spec='${wl}-R $libdir:/usr/lib:/lib' + allow_undefined_flag="-z nodefs" + archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols" + else + # Determine the default libpath from the value encoded in an + # empty executable. + if test "${lt_cv_aix_libpath+set}" = set; then + aix_libpath=$lt_cv_aix_libpath +else + if ${lt_cv_aix_libpath_+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + + lt_aix_libpath_sed=' + /Import File Strings/,/^$/ { + /^0/ { + s/^0 *\([^ ]*\) *$/\1/ + p + } + }' + lt_cv_aix_libpath_=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` + # Check for a 64-bit object if we didn't find anything. + if test -z "$lt_cv_aix_libpath_"; then + lt_cv_aix_libpath_=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` + fi +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + if test -z "$lt_cv_aix_libpath_"; then + lt_cv_aix_libpath_="/usr/lib:/lib" + fi + +fi + + aix_libpath=$lt_cv_aix_libpath_ +fi + + hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath" + # Warning - without using the other run time loading flags, + # -berok will link without error, but may produce a broken library. + no_undefined_flag=' ${wl}-bernotok' + allow_undefined_flag=' ${wl}-berok' + if test "$with_gnu_ld" = yes; then + # We only use this code for GNU lds that support --whole-archive. + whole_archive_flag_spec='${wl}--whole-archive$convenience ${wl}--no-whole-archive' + else + # Exported symbols can be pulled into shared objects from archives + whole_archive_flag_spec='$convenience' + fi + archive_cmds_need_lc=yes + # This is similar to how AIX traditionally builds its shared libraries. + archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' + fi + fi + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds='' + ;; + m68k) + archive_cmds='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' + hardcode_libdir_flag_spec='-L$libdir' + hardcode_minus_L=yes + ;; + esac + ;; + + bsdi[45]*) + export_dynamic_flag_spec=-rdynamic + ;; + + cygwin* | mingw* | pw32* | cegcc*) + # When not using gcc, we currently assume that we are using + # Microsoft Visual C++. + # hardcode_libdir_flag_spec is actually meaningless, as there is + # no search path for DLLs. + case $cc_basename in + cl*) + # Native MSVC + hardcode_libdir_flag_spec=' ' + allow_undefined_flag=unsupported + always_export_symbols=yes + file_list_spec='@' + # Tell ltmain to make .lib files, not .a files. + libext=lib + # Tell ltmain to make .dll files, not .so files. + shrext_cmds=".dll" + # FIXME: Setting linknames here is a bad hack. + archive_cmds='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-dll~linknames=' + archive_expsym_cmds='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then + sed -n -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' -e '1\\\!p' < $export_symbols > $output_objdir/$soname.exp; + else + sed -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' < $export_symbols > $output_objdir/$soname.exp; + fi~ + $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ + linknames=' + # The linker will not automatically build a static lib if we build a DLL. + # _LT_TAGVAR(old_archive_from_new_cmds, )='true' + enable_shared_with_static_runtimes=yes + exclude_expsyms='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*' + export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1,DATA/'\'' | $SED -e '\''/^[AITW][ ]/s/.*[ ]//'\'' | sort | uniq > $export_symbols' + # Don't use ranlib + old_postinstall_cmds='chmod 644 $oldlib' + postlink_cmds='lt_outputfile="@OUTPUT@"~ + lt_tool_outputfile="@TOOL_OUTPUT@"~ + case $lt_outputfile in + *.exe|*.EXE) ;; + *) + lt_outputfile="$lt_outputfile.exe" + lt_tool_outputfile="$lt_tool_outputfile.exe" + ;; + esac~ + if test "$MANIFEST_TOOL" != ":" && test -f "$lt_outputfile.manifest"; then + $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1; + $RM "$lt_outputfile.manifest"; + fi' + ;; + *) + # Assume MSVC wrapper + hardcode_libdir_flag_spec=' ' + allow_undefined_flag=unsupported + # Tell ltmain to make .lib files, not .a files. + libext=lib + # Tell ltmain to make .dll files, not .so files. + shrext_cmds=".dll" + # FIXME: Setting linknames here is a bad hack. + archive_cmds='$CC -o $lib $libobjs $compiler_flags `func_echo_all "$deplibs" | $SED '\''s/ -lc$//'\''` -link -dll~linknames=' + # The linker will automatically build a .lib file if we build a DLL. + old_archive_from_new_cmds='true' + # FIXME: Should let the user specify the lib program. + old_archive_cmds='lib -OUT:$oldlib$oldobjs$old_deplibs' + enable_shared_with_static_runtimes=yes + ;; + esac + ;; + + darwin* | rhapsody*) + + + archive_cmds_need_lc=no + hardcode_direct=no + hardcode_automatic=yes + hardcode_shlibpath_var=unsupported + if test "$lt_cv_ld_force_load" = "yes"; then + whole_archive_flag_spec='`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience ${wl}-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`' + + else + whole_archive_flag_spec='' + fi + link_all_deplibs=yes + allow_undefined_flag="$_lt_dar_allow_undefined" + case $cc_basename in + ifort*) _lt_dar_can_shared=yes ;; + *) _lt_dar_can_shared=$GCC ;; + esac + if test "$_lt_dar_can_shared" = "yes"; then + output_verbose_link_cmd=func_echo_all + archive_cmds="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}" + module_cmds="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" + archive_expsym_cmds="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}" + module_expsym_cmds="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" + + else + ld_shlibs=no + fi + + ;; + + dgux*) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_libdir_flag_spec='-L$libdir' + hardcode_shlibpath_var=no + ;; + + # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor + # support. Future versions do this automatically, but an explicit c++rt0.o + # does not break anything, and helps significantly (at the cost of a little + # extra space). + freebsd2.2*) + archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o' + hardcode_libdir_flag_spec='-R$libdir' + hardcode_direct=yes + hardcode_shlibpath_var=no + ;; + + # Unfortunately, older versions of FreeBSD 2 do not have this feature. + freebsd2.*) + archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct=yes + hardcode_minus_L=yes + hardcode_shlibpath_var=no + ;; + + # FreeBSD 3 and greater uses gcc -shared to do shared libraries. + freebsd* | dragonfly*) + archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + hardcode_libdir_flag_spec='-R$libdir' + hardcode_direct=yes + hardcode_shlibpath_var=no + ;; + + hpux9*) + if test "$GCC" = yes; then + archive_cmds='$RM $output_objdir/$soname~$CC -shared $pic_flag ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + else + archive_cmds='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + fi + hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' + hardcode_libdir_separator=: + hardcode_direct=yes + + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + hardcode_minus_L=yes + export_dynamic_flag_spec='${wl}-E' + ;; + + hpux10*) + if test "$GCC" = yes && test "$with_gnu_ld" = no; then + archive_cmds='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' + else + archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' + fi + if test "$with_gnu_ld" = no; then + hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' + hardcode_libdir_separator=: + hardcode_direct=yes + hardcode_direct_absolute=yes + export_dynamic_flag_spec='${wl}-E' + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + hardcode_minus_L=yes + fi + ;; + + hpux11*) + if test "$GCC" = yes && test "$with_gnu_ld" = no; then + case $host_cpu in + hppa*64*) + archive_cmds='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + ia64*) + archive_cmds='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + archive_cmds='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + else + case $host_cpu in + hppa*64*) + archive_cmds='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + ia64*) + archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + + # Older versions of the 11.00 compiler do not understand -b yet + # (HP92453-01 A.11.01.20 doesn't, HP92453-01 B.11.X.35175-35176.GP does) + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $CC understands -b" >&5 +$as_echo_n "checking if $CC understands -b... " >&6; } +if ${lt_cv_prog_compiler__b+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler__b=no + save_LDFLAGS="$LDFLAGS" + LDFLAGS="$LDFLAGS -b" + echo "$lt_simple_link_test_code" > conftest.$ac_ext + if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then + # The linker can only warn and ignore the option if not recognized + # So say no if there are warnings + if test -s conftest.err; then + # Append any errors to the config.log. + cat conftest.err 1>&5 + $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if diff conftest.exp conftest.er2 >/dev/null; then + lt_cv_prog_compiler__b=yes + fi + else + lt_cv_prog_compiler__b=yes + fi + fi + $RM -r conftest* + LDFLAGS="$save_LDFLAGS" + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler__b" >&5 +$as_echo "$lt_cv_prog_compiler__b" >&6; } + +if test x"$lt_cv_prog_compiler__b" = xyes; then + archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' +else + archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' +fi + + ;; + esac + fi + if test "$with_gnu_ld" = no; then + hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' + hardcode_libdir_separator=: + + case $host_cpu in + hppa*64*|ia64*) + hardcode_direct=no + hardcode_shlibpath_var=no + ;; + *) + hardcode_direct=yes + hardcode_direct_absolute=yes + export_dynamic_flag_spec='${wl}-E' + + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + hardcode_minus_L=yes + ;; + esac + fi + ;; + + irix5* | irix6* | nonstopux*) + if test "$GCC" = yes; then + archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + # Try to use the -exported_symbol ld option, if it does not + # work, assume that -exports_file does not work either and + # implicitly export all symbols. + # This should be the same for all languages, so no per-tag cache variable. + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $host_os linker accepts -exported_symbol" >&5 +$as_echo_n "checking whether the $host_os linker accepts -exported_symbol... " >&6; } +if ${lt_cv_irix_exported_symbol+:} false; then : + $as_echo_n "(cached) " >&6 +else + save_LDFLAGS="$LDFLAGS" + LDFLAGS="$LDFLAGS -shared ${wl}-exported_symbol ${wl}foo ${wl}-update_registry ${wl}/dev/null" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +int foo (void) { return 0; } +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + lt_cv_irix_exported_symbol=yes +else + lt_cv_irix_exported_symbol=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + LDFLAGS="$save_LDFLAGS" +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_irix_exported_symbol" >&5 +$as_echo "$lt_cv_irix_exported_symbol" >&6; } + if test "$lt_cv_irix_exported_symbol" = yes; then + archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations ${wl}-exports_file ${wl}$export_symbols -o $lib' + fi + else + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' + archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -exports_file $export_symbols -o $lib' + fi + archive_cmds_need_lc='no' + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + hardcode_libdir_separator=: + inherit_rpath=yes + link_all_deplibs=yes + ;; + + netbsd* | netbsdelf*-gnu) + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out + else + archive_cmds='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF + fi + hardcode_libdir_flag_spec='-R$libdir' + hardcode_direct=yes + hardcode_shlibpath_var=no + ;; + + newsos6) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct=yes + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + hardcode_libdir_separator=: + hardcode_shlibpath_var=no + ;; + + *nto* | *qnx*) + ;; + + openbsd*) + if test -f /usr/libexec/ld.so; then + hardcode_direct=yes + hardcode_shlibpath_var=no + hardcode_direct_absolute=yes + if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-retain-symbols-file,$export_symbols' + hardcode_libdir_flag_spec='${wl}-rpath,$libdir' + export_dynamic_flag_spec='${wl}-E' + else + case $host_os in + openbsd[01].* | openbsd2.[0-7] | openbsd2.[0-7].*) + archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' + hardcode_libdir_flag_spec='-R$libdir' + ;; + *) + archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + hardcode_libdir_flag_spec='${wl}-rpath,$libdir' + ;; + esac + fi + else + ld_shlibs=no + fi + ;; + + os2*) + hardcode_libdir_flag_spec='-L$libdir' + hardcode_minus_L=yes + allow_undefined_flag=unsupported + archive_cmds='$ECHO "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~echo DATA >> $output_objdir/$libname.def~echo " SINGLE NONSHARED" >> $output_objdir/$libname.def~echo EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def' + old_archive_from_new_cmds='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def' + ;; + + osf3*) + if test "$GCC" = yes; then + allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*' + archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + else + allow_undefined_flag=' -expect_unresolved \*' + archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' + fi + archive_cmds_need_lc='no' + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + hardcode_libdir_separator=: + ;; + + osf4* | osf5*) # as osf3* with the addition of -msym flag + if test "$GCC" = yes; then + allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*' + archive_cmds='$CC -shared${allow_undefined_flag} $pic_flag $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + else + allow_undefined_flag=' -expect_unresolved \*' + archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' + archive_expsym_cmds='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; printf "%s\\n" "-hidden">> $lib.exp~ + $CC -shared${allow_undefined_flag} ${wl}-input ${wl}$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib~$RM $lib.exp' + + # Both c and cxx compiler support -rpath directly + hardcode_libdir_flag_spec='-rpath $libdir' + fi + archive_cmds_need_lc='no' + hardcode_libdir_separator=: + ;; + + solaris*) + no_undefined_flag=' -z defs' + if test "$GCC" = yes; then + wlarc='${wl}' + archive_cmds='$CC -shared $pic_flag ${wl}-z ${wl}text ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -shared $pic_flag ${wl}-z ${wl}text ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' + else + case `$CC -V 2>&1` in + *"Compilers 5.0"*) + wlarc='' + archive_cmds='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags' + archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp' + ;; + *) + wlarc='${wl}' + archive_cmds='$CC -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' + ;; + esac + fi + hardcode_libdir_flag_spec='-R$libdir' + hardcode_shlibpath_var=no + case $host_os in + solaris2.[0-5] | solaris2.[0-5].*) ;; + *) + # The compiler driver will combine and reorder linker options, + # but understands `-z linker_flag'. GCC discards it without `$wl', + # but is careful enough not to reorder. + # Supported since Solaris 2.6 (maybe 2.5.1?) + if test "$GCC" = yes; then + whole_archive_flag_spec='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract' + else + whole_archive_flag_spec='-z allextract$convenience -z defaultextract' + fi + ;; + esac + link_all_deplibs=yes + ;; + + sunos4*) + if test "x$host_vendor" = xsequent; then + # Use $CC to link under sequent, because it throws in some extra .o + # files that make .init and .fini sections work. + archive_cmds='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags' + else + archive_cmds='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags' + fi + hardcode_libdir_flag_spec='-L$libdir' + hardcode_direct=yes + hardcode_minus_L=yes + hardcode_shlibpath_var=no + ;; + + sysv4) + case $host_vendor in + sni) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct=yes # is this really true??? + ;; + siemens) + ## LD is ld it makes a PLAMLIB + ## CC just makes a GrossModule. + archive_cmds='$LD -G -o $lib $libobjs $deplibs $linker_flags' + reload_cmds='$CC -r -o $output$reload_objs' + hardcode_direct=no + ;; + motorola) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct=no #Motorola manual says yes, but my tests say they lie + ;; + esac + runpath_var='LD_RUN_PATH' + hardcode_shlibpath_var=no + ;; + + sysv4.3*) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_shlibpath_var=no + export_dynamic_flag_spec='-Bexport' + ;; + + sysv4*MP*) + if test -d /usr/nec; then + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_shlibpath_var=no + runpath_var=LD_RUN_PATH + hardcode_runpath_var=yes + ld_shlibs=yes + fi + ;; + + sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*) + no_undefined_flag='${wl}-z,text' + archive_cmds_need_lc=no + hardcode_shlibpath_var=no + runpath_var='LD_RUN_PATH' + + if test "$GCC" = yes; then + archive_cmds='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + else + archive_cmds='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + fi + ;; + + sysv5* | sco3.2v5* | sco5v6*) + # Note: We can NOT use -z defs as we might desire, because we do not + # link with -lc, and that would cause any symbols used from libc to + # always be unresolved, which means just about no library would + # ever link correctly. If we're not using GNU ld we use -z text + # though, which does catch some bad symbols but isn't as heavy-handed + # as -z defs. + no_undefined_flag='${wl}-z,text' + allow_undefined_flag='${wl}-z,nodefs' + archive_cmds_need_lc=no + hardcode_shlibpath_var=no + hardcode_libdir_flag_spec='${wl}-R,$libdir' + hardcode_libdir_separator=':' + link_all_deplibs=yes + export_dynamic_flag_spec='${wl}-Bexport' + runpath_var='LD_RUN_PATH' + + if test "$GCC" = yes; then + archive_cmds='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + else + archive_cmds='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + fi + ;; + + uts4*) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_libdir_flag_spec='-L$libdir' + hardcode_shlibpath_var=no + ;; + + *) + ld_shlibs=no + ;; + esac + + if test x$host_vendor = xsni; then + case $host in + sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) + export_dynamic_flag_spec='${wl}-Blargedynsym' + ;; + esac + fi + fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs" >&5 +$as_echo "$ld_shlibs" >&6; } +test "$ld_shlibs" = no && can_build_shared=no + +with_gnu_ld=$with_gnu_ld + + + + + + + + + + + + + + + +# +# Do we need to explicitly link libc? +# +case "x$archive_cmds_need_lc" in +x|xyes) + # Assume -lc should be added + archive_cmds_need_lc=yes + + if test "$enable_shared" = yes && test "$GCC" = yes; then + case $archive_cmds in + *'~'*) + # FIXME: we may have to deal with multi-command sequences. + ;; + '$CC '*) + # Test whether the compiler implicitly links with -lc since on some + # systems, -lgcc has to come before -lc. If gcc already passes -lc + # to ld, don't add -lc before -lgcc. + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether -lc should be explicitly linked in" >&5 +$as_echo_n "checking whether -lc should be explicitly linked in... " >&6; } +if ${lt_cv_archive_cmds_need_lc+:} false; then : + $as_echo_n "(cached) " >&6 +else + $RM conftest* + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } 2>conftest.err; then + soname=conftest + lib=conftest + libobjs=conftest.$ac_objext + deplibs= + wl=$lt_prog_compiler_wl + pic_flag=$lt_prog_compiler_pic + compiler_flags=-v + linker_flags=-v + verstring= + output_objdir=. + libname=conftest + lt_save_allow_undefined_flag=$allow_undefined_flag + allow_undefined_flag= + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1\""; } >&5 + (eval $archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } + then + lt_cv_archive_cmds_need_lc=no + else + lt_cv_archive_cmds_need_lc=yes + fi + allow_undefined_flag=$lt_save_allow_undefined_flag + else + cat conftest.err 1>&5 + fi + $RM conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_archive_cmds_need_lc" >&5 +$as_echo "$lt_cv_archive_cmds_need_lc" >&6; } + archive_cmds_need_lc=$lt_cv_archive_cmds_need_lc + ;; + esac + fi + ;; +esac + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking dynamic linker characteristics" >&5 +$as_echo_n "checking dynamic linker characteristics... " >&6; } + +if test "$GCC" = yes; then + case $host_os in + darwin*) lt_awk_arg="/^libraries:/,/LR/" ;; + *) lt_awk_arg="/^libraries:/" ;; + esac + case $host_os in + mingw* | cegcc*) lt_sed_strip_eq="s,=\([A-Za-z]:\),\1,g" ;; + *) lt_sed_strip_eq="s,=/,/,g" ;; + esac + lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e $lt_sed_strip_eq` + case $lt_search_path_spec in + *\;*) + # if the path contains ";" then we assume it to be the separator + # otherwise default to the standard path separator (i.e. ":") - it is + # assumed that no part of a normal pathname contains ";" but that should + # okay in the real world where ";" in dirpaths is itself problematic. + lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED 's/;/ /g'` + ;; + *) + lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED "s/$PATH_SEPARATOR/ /g"` + ;; + esac + # Ok, now we have the path, separated by spaces, we can step through it + # and add multilib dir if necessary. + lt_tmp_lt_search_path_spec= + lt_multi_os_dir=`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null` + for lt_sys_path in $lt_search_path_spec; do + if test -d "$lt_sys_path/$lt_multi_os_dir"; then + lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path/$lt_multi_os_dir" + else + test -d "$lt_sys_path" && \ + lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path" + fi + done + lt_search_path_spec=`$ECHO "$lt_tmp_lt_search_path_spec" | awk ' +BEGIN {RS=" "; FS="/|\n";} { + lt_foo=""; + lt_count=0; + for (lt_i = NF; lt_i > 0; lt_i--) { + if ($lt_i != "" && $lt_i != ".") { + if ($lt_i == "..") { + lt_count++; + } else { + if (lt_count == 0) { + lt_foo="/" $lt_i lt_foo; + } else { + lt_count--; + } + } + } + } + if (lt_foo != "") { lt_freq[lt_foo]++; } + if (lt_freq[lt_foo] == 1) { print lt_foo; } +}'` + # AWK program above erroneously prepends '/' to C:/dos/paths + # for these hosts. + case $host_os in + mingw* | cegcc*) lt_search_path_spec=`$ECHO "$lt_search_path_spec" |\ + $SED 's,/\([A-Za-z]:\),\1,g'` ;; + esac + sys_lib_search_path_spec=`$ECHO "$lt_search_path_spec" | $lt_NL2SP` +else + sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" +fi +library_names_spec= +libname_spec='lib$name' +soname_spec= +shrext_cmds=".so" +postinstall_cmds= +postuninstall_cmds= +finish_cmds= +finish_eval= +shlibpath_var= +shlibpath_overrides_runpath=unknown +version_type=none +dynamic_linker="$host_os ld.so" +sys_lib_dlsearch_path_spec="/lib /usr/lib" +need_lib_prefix=unknown +hardcode_into_libs=no + +# when you set need_version to no, make sure it does not cause -set_version +# flags to be left without arguments +need_version=unknown + +case $host_os in +aix3*) + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a' + shlibpath_var=LIBPATH + + # AIX 3 has no versioning support, so we append a major version to the name. + soname_spec='${libname}${release}${shared_ext}$major' + ;; + +aix[4-9]*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + hardcode_into_libs=yes + if test "$host_cpu" = ia64; then + # AIX 5 supports IA64 + library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + else + # With GCC up to 2.95.x, collect2 would create an import file + # for dependence libraries. The import file would start with + # the line `#! .'. This would cause the generated library to + # depend on `.', always an invalid library. This was fixed in + # development snapshots of GCC prior to 3.0. + case $host_os in + aix4 | aix4.[01] | aix4.[01].*) + if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' + echo ' yes ' + echo '#endif'; } | ${CC} -E - | $GREP yes > /dev/null; then + : + else + can_build_shared=no + fi + ;; + esac + # AIX (on Power*) has no versioning support, so currently we can not hardcode correct + # soname into executable. Probably we can add versioning support to + # collect2, so additional links can be useful in future. + if test "$aix_use_runtimelinking" = yes; then + # If using run time linking (on AIX 4.2 or later) use lib.so + # instead of lib.a to let people know that these are not + # typical AIX shared libraries. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + else + # We preserve .a as extension for shared libraries through AIX4.2 + # and later when we are not doing run time linking. + library_names_spec='${libname}${release}.a $libname.a' + soname_spec='${libname}${release}${shared_ext}$major' + fi + shlibpath_var=LIBPATH + fi + ;; + +amigaos*) + case $host_cpu in + powerpc) + # Since July 2007 AmigaOS4 officially supports .so libraries. + # When compiling the executable, add -use-dynld -Lsobjs: to the compileline. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + ;; + m68k) + library_names_spec='$libname.ixlibrary $libname.a' + # Create ${libname}_ixlibrary.a entries in /sys/libs. + finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; test $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' + ;; + esac + ;; + +beos*) + library_names_spec='${libname}${shared_ext}' + dynamic_linker="$host_os ld.so" + shlibpath_var=LIBRARY_PATH + ;; + +bsdi[45]*) + version_type=linux # correct to gnu/linux during the next big refactor + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" + sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" + # the default ld.so.conf also contains /usr/contrib/lib and + # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow + # libtool to hard-code these into programs + ;; + +cygwin* | mingw* | pw32* | cegcc*) + version_type=windows + shrext_cmds=".dll" + need_version=no + need_lib_prefix=no + + case $GCC,$cc_basename in + yes,*) + # gcc + library_names_spec='$libname.dll.a' + # DLL is installed to $(libdir)/../bin by postinstall_cmds + postinstall_cmds='base_file=`basename \${file}`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + test -d \$dldir || mkdir -p \$dldir~ + $install_prog $dir/$dlname \$dldir/$dlname~ + chmod a+x \$dldir/$dlname~ + if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then + eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; + fi' + postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ + dlpath=$dir/\$dldll~ + $RM \$dlpath' + shlibpath_overrides_runpath=yes + + case $host_os in + cygwin*) + # Cygwin DLLs use 'cyg' prefix rather than 'lib' + soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' + + sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/lib/w32api" + ;; + mingw* | cegcc*) + # MinGW DLLs use traditional 'lib' prefix + soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' + ;; + pw32*) + # pw32 DLLs use 'pw' prefix rather than 'lib' + library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' + ;; + esac + dynamic_linker='Win32 ld.exe' + ;; + + *,cl*) + # Native MSVC + libname_spec='$name' + soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' + library_names_spec='${libname}.dll.lib' + + case $build_os in + mingw*) + sys_lib_search_path_spec= + lt_save_ifs=$IFS + IFS=';' + for lt_path in $LIB + do + IFS=$lt_save_ifs + # Let DOS variable expansion print the short 8.3 style file name. + lt_path=`cd "$lt_path" 2>/dev/null && cmd //C "for %i in (".") do @echo %~si"` + sys_lib_search_path_spec="$sys_lib_search_path_spec $lt_path" + done + IFS=$lt_save_ifs + # Convert to MSYS style. + sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | sed -e 's|\\\\|/|g' -e 's| \\([a-zA-Z]\\):| /\\1|g' -e 's|^ ||'` + ;; + cygwin*) + # Convert to unix form, then to dos form, then back to unix form + # but this time dos style (no spaces!) so that the unix form looks + # like /cygdrive/c/PROGRA~1:/cygdr... + sys_lib_search_path_spec=`cygpath --path --unix "$LIB"` + sys_lib_search_path_spec=`cygpath --path --dos "$sys_lib_search_path_spec" 2>/dev/null` + sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` + ;; + *) + sys_lib_search_path_spec="$LIB" + if $ECHO "$sys_lib_search_path_spec" | $GREP ';[c-zC-Z]:/' >/dev/null; then + # It is most probably a Windows format PATH. + sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` + else + sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` + fi + # FIXME: find the short name or the path components, as spaces are + # common. (e.g. "Program Files" -> "PROGRA~1") + ;; + esac + + # DLL is installed to $(libdir)/../bin by postinstall_cmds + postinstall_cmds='base_file=`basename \${file}`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + test -d \$dldir || mkdir -p \$dldir~ + $install_prog $dir/$dlname \$dldir/$dlname' + postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ + dlpath=$dir/\$dldll~ + $RM \$dlpath' + shlibpath_overrides_runpath=yes + dynamic_linker='Win32 link.exe' + ;; + + *) + # Assume MSVC wrapper + library_names_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext} $libname.lib' + dynamic_linker='Win32 ld.exe' + ;; + esac + # FIXME: first we should search . and the directory the executable is in + shlibpath_var=PATH + ;; + +darwin* | rhapsody*) + dynamic_linker="$host_os dyld" + version_type=darwin + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${major}$shared_ext ${libname}$shared_ext' + soname_spec='${libname}${release}${major}$shared_ext' + shlibpath_overrides_runpath=yes + shlibpath_var=DYLD_LIBRARY_PATH + shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' + + sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/local/lib" + sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' + ;; + +dgux*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +freebsd* | dragonfly*) + # DragonFly does not have aout. When/if they implement a new + # versioning mechanism, adjust this. + if test -x /usr/bin/objformat; then + objformat=`/usr/bin/objformat` + else + case $host_os in + freebsd[23].*) objformat=aout ;; + *) objformat=elf ;; + esac + fi + version_type=freebsd-$objformat + case $version_type in + freebsd-elf*) + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' + need_version=no + need_lib_prefix=no + ;; + freebsd-*) + library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix' + need_version=yes + ;; + esac + shlibpath_var=LD_LIBRARY_PATH + case $host_os in + freebsd2.*) + shlibpath_overrides_runpath=yes + ;; + freebsd3.[01]* | freebsdelf3.[01]*) + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + freebsd3.[2-9]* | freebsdelf3.[2-9]* | \ + freebsd4.[0-5] | freebsdelf4.[0-5] | freebsd4.1.1 | freebsdelf4.1.1) + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + *) # from 4.6 on, and DragonFly + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + esac + ;; + +gnu*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + +haiku*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + dynamic_linker="$host_os runtime_loader" + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LIBRARY_PATH + shlibpath_overrides_runpath=yes + sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib' + hardcode_into_libs=yes + ;; + +hpux9* | hpux10* | hpux11*) + # Give a soname corresponding to the major version so that dld.sl refuses to + # link against other versions. + version_type=sunos + need_lib_prefix=no + need_version=no + case $host_cpu in + ia64*) + shrext_cmds='.so' + hardcode_into_libs=yes + dynamic_linker="$host_os dld.so" + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + if test "X$HPUX_IA64_MODE" = X32; then + sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" + else + sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" + fi + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + hppa*64*) + shrext_cmds='.sl' + hardcode_into_libs=yes + dynamic_linker="$host_os dld.sl" + shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH + shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + *) + shrext_cmds='.sl' + dynamic_linker="$host_os dld.sl" + shlibpath_var=SHLIB_PATH + shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + ;; + esac + # HP-UX runs *really* slowly unless shared libraries are mode 555, ... + postinstall_cmds='chmod 555 $lib' + # or fails outright, so override atomically: + install_override_mode=555 + ;; + +interix[3-9]*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + +irix5* | irix6* | nonstopux*) + case $host_os in + nonstopux*) version_type=nonstopux ;; + *) + if test "$lt_cv_prog_gnu_ld" = yes; then + version_type=linux # correct to gnu/linux during the next big refactor + else + version_type=irix + fi ;; + esac + need_lib_prefix=no + need_version=no + soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}' + case $host_os in + irix5* | nonstopux*) + libsuff= shlibsuff= + ;; + *) + case $LD in # libtool.m4 will add one of these switches to LD + *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") + libsuff= shlibsuff= libmagic=32-bit;; + *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") + libsuff=32 shlibsuff=N32 libmagic=N32;; + *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") + libsuff=64 shlibsuff=64 libmagic=64-bit;; + *) libsuff= shlibsuff= libmagic=never-match;; + esac + ;; + esac + shlibpath_var=LD_LIBRARY${shlibsuff}_PATH + shlibpath_overrides_runpath=no + sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}" + sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}" + hardcode_into_libs=yes + ;; + +# No shared lib support for Linux oldld, aout, or coff. +linux*oldld* | linux*aout* | linux*coff*) + dynamic_linker=no + ;; + +# This must be glibc/ELF. +linux* | k*bsd*-gnu | kopensolaris*-gnu) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + + # Some binutils ld are patched to set DT_RUNPATH + if ${lt_cv_shlibpath_overrides_runpath+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_shlibpath_overrides_runpath=no + save_LDFLAGS=$LDFLAGS + save_libdir=$libdir + eval "libdir=/foo; wl=\"$lt_prog_compiler_wl\"; \ + LDFLAGS=\"\$LDFLAGS $hardcode_libdir_flag_spec\"" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + if ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null; then : + lt_cv_shlibpath_overrides_runpath=yes +fi +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + LDFLAGS=$save_LDFLAGS + libdir=$save_libdir + +fi + + shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath + + # This implies no fast_install, which is unacceptable. + # Some rework will be needed to allow for fast_install + # before this can be enabled. + hardcode_into_libs=yes + + # Append ld.so.conf contents to the search path + if test -f /etc/ld.so.conf; then + lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '` + sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra" + fi + + # We used to test for /lib/ld.so.1 and disable shared libraries on + # powerpc, because MkLinux only supported shared libraries with the + # GNU dynamic linker. Since this was broken with cross compilers, + # most powerpc-linux boxes support dynamic linking these days and + # people can always --disable-shared, the test was removed, and we + # assume the GNU/Linux dynamic linker is in use. + dynamic_linker='GNU/Linux ld.so' + ;; + +netbsdelf*-gnu) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + dynamic_linker='NetBSD ld.elf_so' + ;; + +netbsd*) + version_type=sunos + need_lib_prefix=no + need_version=no + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + dynamic_linker='NetBSD (a.out) ld.so' + else + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + dynamic_linker='NetBSD ld.elf_so' + fi + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + +newsos6) + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + ;; + +*nto* | *qnx*) + version_type=qnx + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + dynamic_linker='ldqnx.so' + ;; + +openbsd*) + version_type=sunos + sys_lib_dlsearch_path_spec="/usr/lib" + need_lib_prefix=no + # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs. + case $host_os in + openbsd3.3 | openbsd3.3.*) need_version=yes ;; + *) need_version=no ;; + esac + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + shlibpath_var=LD_LIBRARY_PATH + if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + case $host_os in + openbsd2.[89] | openbsd2.[89].*) + shlibpath_overrides_runpath=no + ;; + *) + shlibpath_overrides_runpath=yes + ;; + esac + else + shlibpath_overrides_runpath=yes + fi + ;; + +os2*) + libname_spec='$name' + shrext_cmds=".dll" + need_lib_prefix=no + library_names_spec='$libname${shared_ext} $libname.a' + dynamic_linker='OS/2 ld.exe' + shlibpath_var=LIBPATH + ;; + +osf3* | osf4* | osf5*) + version_type=osf + need_lib_prefix=no + need_version=no + soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" + sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec" + ;; + +rdos*) + dynamic_linker=no + ;; + +solaris*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + # ldd complains unless libraries are executable + postinstall_cmds='chmod +x $lib' + ;; + +sunos4*) + version_type=sunos + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + if test "$with_gnu_ld" = yes; then + need_lib_prefix=no + fi + need_version=yes + ;; + +sysv4 | sysv4.3*) + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + case $host_vendor in + sni) + shlibpath_overrides_runpath=no + need_lib_prefix=no + runpath_var=LD_RUN_PATH + ;; + siemens) + need_lib_prefix=no + ;; + motorola) + need_lib_prefix=no + need_version=no + shlibpath_overrides_runpath=no + sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' + ;; + esac + ;; + +sysv4*MP*) + if test -d /usr/nec ;then + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}' + soname_spec='$libname${shared_ext}.$major' + shlibpath_var=LD_LIBRARY_PATH + fi + ;; + +sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) + version_type=freebsd-elf + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + if test "$with_gnu_ld" = yes; then + sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' + else + sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' + case $host_os in + sco3.2v5*) + sys_lib_search_path_spec="$sys_lib_search_path_spec /lib" + ;; + esac + fi + sys_lib_dlsearch_path_spec='/usr/lib' + ;; + +tpf*) + # TPF is a cross-target only. Preferred cross-host = GNU/Linux. + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + +uts4*) + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +*) + dynamic_linker=no + ;; +esac +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $dynamic_linker" >&5 +$as_echo "$dynamic_linker" >&6; } +test "$dynamic_linker" = no && can_build_shared=no + +variables_saved_for_relink="PATH $shlibpath_var $runpath_var" +if test "$GCC" = yes; then + variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" +fi + +if test "${lt_cv_sys_lib_search_path_spec+set}" = set; then + sys_lib_search_path_spec="$lt_cv_sys_lib_search_path_spec" +fi +if test "${lt_cv_sys_lib_dlsearch_path_spec+set}" = set; then + sys_lib_dlsearch_path_spec="$lt_cv_sys_lib_dlsearch_path_spec" +fi + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to hardcode library paths into programs" >&5 +$as_echo_n "checking how to hardcode library paths into programs... " >&6; } +hardcode_action= +if test -n "$hardcode_libdir_flag_spec" || + test -n "$runpath_var" || + test "X$hardcode_automatic" = "Xyes" ; then + + # We can hardcode non-existent directories. + if test "$hardcode_direct" != no && + # If the only mechanism to avoid hardcoding is shlibpath_var, we + # have to relink, otherwise we might link with an installed library + # when we should be linking with a yet-to-be-installed one + ## test "$_LT_TAGVAR(hardcode_shlibpath_var, )" != no && + test "$hardcode_minus_L" != no; then + # Linking always hardcodes the temporary library directory. + hardcode_action=relink + else + # We can link without hardcoding, and we can hardcode nonexisting dirs. + hardcode_action=immediate + fi +else + # We cannot hardcode anything, or else we can only hardcode existing + # directories. + hardcode_action=unsupported +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $hardcode_action" >&5 +$as_echo "$hardcode_action" >&6; } + +if test "$hardcode_action" = relink || + test "$inherit_rpath" = yes; then + # Fast installation is not supported + enable_fast_install=no +elif test "$shlibpath_overrides_runpath" = yes || + test "$enable_shared" = no; then + # Fast installation is not necessary + enable_fast_install=needless +fi + + + + + + + if test "x$enable_dlopen" != xyes; then + enable_dlopen=unknown + enable_dlopen_self=unknown + enable_dlopen_self_static=unknown +else + lt_cv_dlopen=no + lt_cv_dlopen_libs= + + case $host_os in + beos*) + lt_cv_dlopen="load_add_on" + lt_cv_dlopen_libs= + lt_cv_dlopen_self=yes + ;; + + mingw* | pw32* | cegcc*) + lt_cv_dlopen="LoadLibrary" + lt_cv_dlopen_libs= + ;; + + cygwin*) + lt_cv_dlopen="dlopen" + lt_cv_dlopen_libs= + ;; + + darwin*) + # if libdl is installed we need to link against it + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5 +$as_echo_n "checking for dlopen in -ldl... " >&6; } +if ${ac_cv_lib_dl_dlopen+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-ldl $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char dlopen (); +int +main () +{ +return dlopen (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_dl_dlopen=yes +else + ac_cv_lib_dl_dlopen=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5 +$as_echo "$ac_cv_lib_dl_dlopen" >&6; } +if test "x$ac_cv_lib_dl_dlopen" = xyes; then : + lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl" +else + + lt_cv_dlopen="dyld" + lt_cv_dlopen_libs= + lt_cv_dlopen_self=yes + +fi + + ;; + + *) + ac_fn_c_check_func "$LINENO" "shl_load" "ac_cv_func_shl_load" +if test "x$ac_cv_func_shl_load" = xyes; then : + lt_cv_dlopen="shl_load" +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for shl_load in -ldld" >&5 +$as_echo_n "checking for shl_load in -ldld... " >&6; } +if ${ac_cv_lib_dld_shl_load+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-ldld $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char shl_load (); +int +main () +{ +return shl_load (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_dld_shl_load=yes +else + ac_cv_lib_dld_shl_load=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_shl_load" >&5 +$as_echo "$ac_cv_lib_dld_shl_load" >&6; } +if test "x$ac_cv_lib_dld_shl_load" = xyes; then : + lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-ldld" +else + ac_fn_c_check_func "$LINENO" "dlopen" "ac_cv_func_dlopen" +if test "x$ac_cv_func_dlopen" = xyes; then : + lt_cv_dlopen="dlopen" +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5 +$as_echo_n "checking for dlopen in -ldl... " >&6; } +if ${ac_cv_lib_dl_dlopen+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-ldl $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char dlopen (); +int +main () +{ +return dlopen (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_dl_dlopen=yes +else + ac_cv_lib_dl_dlopen=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5 +$as_echo "$ac_cv_lib_dl_dlopen" >&6; } +if test "x$ac_cv_lib_dl_dlopen" = xyes; then : + lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl" +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -lsvld" >&5 +$as_echo_n "checking for dlopen in -lsvld... " >&6; } +if ${ac_cv_lib_svld_dlopen+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lsvld $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char dlopen (); +int +main () +{ +return dlopen (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_svld_dlopen=yes +else + ac_cv_lib_svld_dlopen=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_svld_dlopen" >&5 +$as_echo "$ac_cv_lib_svld_dlopen" >&6; } +if test "x$ac_cv_lib_svld_dlopen" = xyes; then : + lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld" +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dld_link in -ldld" >&5 +$as_echo_n "checking for dld_link in -ldld... " >&6; } +if ${ac_cv_lib_dld_dld_link+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-ldld $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char dld_link (); +int +main () +{ +return dld_link (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_dld_dld_link=yes +else + ac_cv_lib_dld_dld_link=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_dld_link" >&5 +$as_echo "$ac_cv_lib_dld_dld_link" >&6; } +if test "x$ac_cv_lib_dld_dld_link" = xyes; then : + lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-ldld" +fi + + +fi + + +fi + + +fi + + +fi + + +fi + + ;; + esac + + if test "x$lt_cv_dlopen" != xno; then + enable_dlopen=yes + else + enable_dlopen=no + fi + + case $lt_cv_dlopen in + dlopen) + save_CPPFLAGS="$CPPFLAGS" + test "x$ac_cv_header_dlfcn_h" = xyes && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H" + + save_LDFLAGS="$LDFLAGS" + wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\" + + save_LIBS="$LIBS" + LIBS="$lt_cv_dlopen_libs $LIBS" + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether a program can dlopen itself" >&5 +$as_echo_n "checking whether a program can dlopen itself... " >&6; } +if ${lt_cv_dlopen_self+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test "$cross_compiling" = yes; then : + lt_cv_dlopen_self=cross +else + lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 + lt_status=$lt_dlunknown + cat > conftest.$ac_ext <<_LT_EOF +#line $LINENO "configure" +#include "confdefs.h" + +#if HAVE_DLFCN_H +#include +#endif + +#include + +#ifdef RTLD_GLOBAL +# define LT_DLGLOBAL RTLD_GLOBAL +#else +# ifdef DL_GLOBAL +# define LT_DLGLOBAL DL_GLOBAL +# else +# define LT_DLGLOBAL 0 +# endif +#endif + +/* We may have to define LT_DLLAZY_OR_NOW in the command line if we + find out it does not work in some platform. */ +#ifndef LT_DLLAZY_OR_NOW +# ifdef RTLD_LAZY +# define LT_DLLAZY_OR_NOW RTLD_LAZY +# else +# ifdef DL_LAZY +# define LT_DLLAZY_OR_NOW DL_LAZY +# else +# ifdef RTLD_NOW +# define LT_DLLAZY_OR_NOW RTLD_NOW +# else +# ifdef DL_NOW +# define LT_DLLAZY_OR_NOW DL_NOW +# else +# define LT_DLLAZY_OR_NOW 0 +# endif +# endif +# endif +# endif +#endif + +/* When -fvisbility=hidden is used, assume the code has been annotated + correspondingly for the symbols needed. */ +#if defined(__GNUC__) && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)) +int fnord () __attribute__((visibility("default"))); +#endif + +int fnord () { return 42; } +int main () +{ + void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); + int status = $lt_dlunknown; + + if (self) + { + if (dlsym (self,"fnord")) status = $lt_dlno_uscore; + else + { + if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; + else puts (dlerror ()); + } + /* dlclose (self); */ + } + else + puts (dlerror ()); + + return status; +} +_LT_EOF + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5 + (eval $ac_link) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && test -s conftest${ac_exeext} 2>/dev/null; then + (./conftest; exit; ) >&5 2>/dev/null + lt_status=$? + case x$lt_status in + x$lt_dlno_uscore) lt_cv_dlopen_self=yes ;; + x$lt_dlneed_uscore) lt_cv_dlopen_self=yes ;; + x$lt_dlunknown|x*) lt_cv_dlopen_self=no ;; + esac + else : + # compilation failed + lt_cv_dlopen_self=no + fi +fi +rm -fr conftest* + + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_dlopen_self" >&5 +$as_echo "$lt_cv_dlopen_self" >&6; } + + if test "x$lt_cv_dlopen_self" = xyes; then + wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\" + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether a statically linked program can dlopen itself" >&5 +$as_echo_n "checking whether a statically linked program can dlopen itself... " >&6; } +if ${lt_cv_dlopen_self_static+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test "$cross_compiling" = yes; then : + lt_cv_dlopen_self_static=cross +else + lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 + lt_status=$lt_dlunknown + cat > conftest.$ac_ext <<_LT_EOF +#line $LINENO "configure" +#include "confdefs.h" + +#if HAVE_DLFCN_H +#include +#endif + +#include + +#ifdef RTLD_GLOBAL +# define LT_DLGLOBAL RTLD_GLOBAL +#else +# ifdef DL_GLOBAL +# define LT_DLGLOBAL DL_GLOBAL +# else +# define LT_DLGLOBAL 0 +# endif +#endif + +/* We may have to define LT_DLLAZY_OR_NOW in the command line if we + find out it does not work in some platform. */ +#ifndef LT_DLLAZY_OR_NOW +# ifdef RTLD_LAZY +# define LT_DLLAZY_OR_NOW RTLD_LAZY +# else +# ifdef DL_LAZY +# define LT_DLLAZY_OR_NOW DL_LAZY +# else +# ifdef RTLD_NOW +# define LT_DLLAZY_OR_NOW RTLD_NOW +# else +# ifdef DL_NOW +# define LT_DLLAZY_OR_NOW DL_NOW +# else +# define LT_DLLAZY_OR_NOW 0 +# endif +# endif +# endif +# endif +#endif + +/* When -fvisbility=hidden is used, assume the code has been annotated + correspondingly for the symbols needed. */ +#if defined(__GNUC__) && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)) +int fnord () __attribute__((visibility("default"))); +#endif + +int fnord () { return 42; } +int main () +{ + void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); + int status = $lt_dlunknown; + + if (self) + { + if (dlsym (self,"fnord")) status = $lt_dlno_uscore; + else + { + if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; + else puts (dlerror ()); + } + /* dlclose (self); */ + } + else + puts (dlerror ()); + + return status; +} +_LT_EOF + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5 + (eval $ac_link) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && test -s conftest${ac_exeext} 2>/dev/null; then + (./conftest; exit; ) >&5 2>/dev/null + lt_status=$? + case x$lt_status in + x$lt_dlno_uscore) lt_cv_dlopen_self_static=yes ;; + x$lt_dlneed_uscore) lt_cv_dlopen_self_static=yes ;; + x$lt_dlunknown|x*) lt_cv_dlopen_self_static=no ;; + esac + else : + # compilation failed + lt_cv_dlopen_self_static=no + fi +fi +rm -fr conftest* + + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_dlopen_self_static" >&5 +$as_echo "$lt_cv_dlopen_self_static" >&6; } + fi + + CPPFLAGS="$save_CPPFLAGS" + LDFLAGS="$save_LDFLAGS" + LIBS="$save_LIBS" + ;; + esac + + case $lt_cv_dlopen_self in + yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;; + *) enable_dlopen_self=unknown ;; + esac + + case $lt_cv_dlopen_self_static in + yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;; + *) enable_dlopen_self_static=unknown ;; + esac +fi + + + + + + + + + + + + + + + + + +striplib= +old_striplib= +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether stripping libraries is possible" >&5 +$as_echo_n "checking whether stripping libraries is possible... " >&6; } +if test -n "$STRIP" && $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then + test -z "$old_striplib" && old_striplib="$STRIP --strip-debug" + test -z "$striplib" && striplib="$STRIP --strip-unneeded" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +else +# FIXME - insert some real tests, host_os isn't really good enough + case $host_os in + darwin*) + if test -n "$STRIP" ; then + striplib="$STRIP -x" + old_striplib="$STRIP -S" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + fi + ;; + *) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + ;; + esac +fi + + + + + + + + + + + + + # Report which library types will actually be built + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if libtool supports shared libraries" >&5 +$as_echo_n "checking if libtool supports shared libraries... " >&6; } + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $can_build_shared" >&5 +$as_echo "$can_build_shared" >&6; } + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build shared libraries" >&5 +$as_echo_n "checking whether to build shared libraries... " >&6; } + test "$can_build_shared" = "no" && enable_shared=no + + # On AIX, shared libraries and static libraries use the same namespace, and + # are all built from PIC. + case $host_os in + aix3*) + test "$enable_shared" = yes && enable_static=no + if test -n "$RANLIB"; then + archive_cmds="$archive_cmds~\$RANLIB \$lib" + postinstall_cmds='$RANLIB $lib' + fi + ;; + + aix[4-9]*) + if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then + test "$enable_shared" = yes && enable_static=no + fi + ;; + esac + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_shared" >&5 +$as_echo "$enable_shared" >&6; } + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build static libraries" >&5 +$as_echo_n "checking whether to build static libraries... " >&6; } + # Make sure either enable_shared or enable_static is yes. + test "$enable_shared" = yes || enable_static=yes + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_static" >&5 +$as_echo "$enable_static" >&6; } + + + + +fi +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +CC="$lt_save_CC" + + + + + + + + + + + + + + + + ac_config_commands="$ac_config_commands libtool" + + + + +# Only expand once: + + + +# Extract the first word of "doxygen", so it can be a program name with args. +set dummy doxygen; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_DOXYGEN+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$DOXYGEN"; then + ac_cv_prog_DOXYGEN="$DOXYGEN" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_DOXYGEN="true" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + test -z "$ac_cv_prog_DOXYGEN" && ac_cv_prog_DOXYGEN="false" +fi +fi +DOXYGEN=$ac_cv_prog_DOXYGEN +if test -n "$DOXYGEN"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DOXYGEN" >&5 +$as_echo "$DOXYGEN" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + if test "$DOXYGEN" = true; then + DOXYGEN_TRUE= + DOXYGEN_FALSE='#' +else + DOXYGEN_TRUE='#' + DOXYGEN_FALSE= +fi + + +# Checks for header files. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5 +$as_echo_n "checking for ANSI C header files... " >&6; } +if ${ac_cv_header_stdc+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +#include +#include +#include + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_header_stdc=yes +else + ac_cv_header_stdc=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + +if test $ac_cv_header_stdc = yes; then + # SunOS 4.x string.h does not declare mem*, contrary to ANSI. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "memchr" >/dev/null 2>&1; then : + +else + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "free" >/dev/null 2>&1; then : + +else + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. + if test "$cross_compiling" = yes; then : + : +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +#include +#if ((' ' & 0x0FF) == 0x020) +# define ISLOWER(c) ('a' <= (c) && (c) <= 'z') +# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) +#else +# define ISLOWER(c) \ + (('a' <= (c) && (c) <= 'i') \ + || ('j' <= (c) && (c) <= 'r') \ + || ('s' <= (c) && (c) <= 'z')) +# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) +#endif + +#define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) +int +main () +{ + int i; + for (i = 0; i < 256; i++) + if (XOR (islower (i), ISLOWER (i)) + || toupper (i) != TOUPPER (i)) + return 2; + return 0; +} +_ACEOF +if ac_fn_c_try_run "$LINENO"; then : + +else + ac_cv_header_stdc=no +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + +fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5 +$as_echo "$ac_cv_header_stdc" >&6; } +if test $ac_cv_header_stdc = yes; then + +$as_echo "#define STDC_HEADERS 1" >>confdefs.h + +fi + +for ac_header in stdlib.h +do : + ac_fn_c_check_header_mongrel "$LINENO" "stdlib.h" "ac_cv_header_stdlib_h" "$ac_includes_default" +if test "x$ac_cv_header_stdlib_h" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_STDLIB_H 1 +_ACEOF + +fi + +done + + +# Checks for typedefs, structures, and compiler characteristics. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for an ANSI C-conforming const" >&5 +$as_echo_n "checking for an ANSI C-conforming const... " >&6; } +if ${ac_cv_c_const+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ +/* FIXME: Include the comments suggested by Paul. */ +#ifndef __cplusplus + /* Ultrix mips cc rejects this. */ + typedef int charset[2]; + const charset cs; + /* SunOS 4.1.1 cc rejects this. */ + char const *const *pcpcc; + char **ppc; + /* NEC SVR4.0.2 mips cc rejects this. */ + struct point {int x, y;}; + static struct point const zero = {0,0}; + /* AIX XL C 1.02.0.0 rejects this. + It does not let you subtract one const X* pointer from another in + an arm of an if-expression whose if-part is not a constant + expression */ + const char *g = "string"; + pcpcc = &g + (g ? g-g : 0); + /* HPUX 7.0 cc rejects these. */ + ++pcpcc; + ppc = (char**) pcpcc; + pcpcc = (char const *const *) ppc; + { /* SCO 3.2v4 cc rejects this. */ + char *t; + char const *s = 0 ? (char *) 0 : (char const *) 0; + + *t++ = 0; + if (s) return 0; + } + { /* Someone thinks the Sun supposedly-ANSI compiler will reject this. */ + int x[] = {25, 17}; + const int *foo = &x[0]; + ++foo; + } + { /* Sun SC1.0 ANSI compiler rejects this -- but not the above. */ + typedef const int *iptr; + iptr p = 0; + ++p; + } + { /* AIX XL C 1.02.0.0 rejects this saying + "k.c", line 2.27: 1506-025 (S) Operand must be a modifiable lvalue. */ + struct s { int j; const int *ap[3]; }; + struct s *b; b->j = 5; + } + { /* ULTRIX-32 V3.1 (Rev 9) vcc rejects this */ + const int foo = 10; + if (!foo) return 0; + } + return !cs[0] && !zero.x; +#endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_c_const=yes +else + ac_cv_c_const=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_const" >&5 +$as_echo "$ac_cv_c_const" >&6; } +if test $ac_cv_c_const = no; then + +$as_echo "#define const /**/" >>confdefs.h + +fi + +ac_fn_c_check_type "$LINENO" "size_t" "ac_cv_type_size_t" "$ac_includes_default" +if test "x$ac_cv_type_size_t" = xyes; then : + +else + +cat >>confdefs.h <<_ACEOF +#define size_t unsigned int +_ACEOF + +fi + + +# Define Makefiles. +ac_config_files="$ac_config_files yaml-0.1.pc include/Makefile src/Makefile Makefile tests/Makefile win32/Makefile" + + +# Generate the "configure" script. +cat >confcache <<\_ACEOF +# This file is a shell script that caches the results of configure +# tests run on this system so they can be shared between configure +# scripts and configure runs, see configure's option --config-cache. +# It is not useful on other systems. If it contains results you don't +# want to keep, you may remove or edit it. +# +# config.status only pays attention to the cache file if you give it +# the --recheck option to rerun configure. +# +# `ac_cv_env_foo' variables (set or unset) will be overridden when +# loading this file, other *unset* `ac_cv_foo' will be assigned the +# following values. + +_ACEOF + +# The following way of writing the cache mishandles newlines in values, +# but we know of no workaround that is simple, portable, and efficient. +# So, we kill variables containing newlines. +# Ultrix sh set writes to stderr and can't be redirected directly, +# and sets the high bit in the cache file unless we assign to the vars. +( + for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do + eval ac_val=\$$ac_var + case $ac_val in #( + *${as_nl}*) + case $ac_var in #( + *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 +$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; + esac + case $ac_var in #( + _ | IFS | as_nl) ;; #( + BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( + *) { eval $ac_var=; unset $ac_var;} ;; + esac ;; + esac + done + + (set) 2>&1 | + case $as_nl`(ac_space=' '; set) 2>&1` in #( + *${as_nl}ac_space=\ *) + # `set' does not quote correctly, so add quotes: double-quote + # substitution turns \\\\ into \\, and sed turns \\ into \. + sed -n \ + "s/'/'\\\\''/g; + s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" + ;; #( + *) + # `set' quotes correctly as required by POSIX, so do not add quotes. + sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" + ;; + esac | + sort +) | + sed ' + /^ac_cv_env_/b end + t clear + :clear + s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ + t end + s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ + :end' >>confcache +if diff "$cache_file" confcache >/dev/null 2>&1; then :; else + if test -w "$cache_file"; then + if test "x$cache_file" != "x/dev/null"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5 +$as_echo "$as_me: updating cache $cache_file" >&6;} + if test ! -f "$cache_file" || test -h "$cache_file"; then + cat confcache >"$cache_file" + else + case $cache_file in #( + */* | ?:*) + mv -f confcache "$cache_file"$$ && + mv -f "$cache_file"$$ "$cache_file" ;; #( + *) + mv -f confcache "$cache_file" ;; + esac + fi + fi + else + { $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5 +$as_echo "$as_me: not updating unwritable cache $cache_file" >&6;} + fi +fi +rm -f confcache + +test "x$prefix" = xNONE && prefix=$ac_default_prefix +# Let make expand exec_prefix. +test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' + +DEFS=-DHAVE_CONFIG_H + +ac_libobjs= +ac_ltlibobjs= +U= +for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue + # 1. Remove the extension, and $U if already installed. + ac_script='s/\$U\././;s/\.o$//;s/\.obj$//' + ac_i=`$as_echo "$ac_i" | sed "$ac_script"` + # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR + # will be set to the directory where LIBOBJS objects are built. + as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext" + as_fn_append ac_ltlibobjs " \${LIBOBJDIR}$ac_i"'$U.lo' +done +LIBOBJS=$ac_libobjs + +LTLIBOBJS=$ac_ltlibobjs + + + if test -n "$EXEEXT"; then + am__EXEEXT_TRUE= + am__EXEEXT_FALSE='#' +else + am__EXEEXT_TRUE='#' + am__EXEEXT_FALSE= +fi + +if test -z "${AMDEP_TRUE}" && test -z "${AMDEP_FALSE}"; then + as_fn_error $? "conditional \"AMDEP\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then + as_fn_error $? "conditional \"am__fastdepCC\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${DOXYGEN_TRUE}" && test -z "${DOXYGEN_FALSE}"; then + as_fn_error $? "conditional \"DOXYGEN\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi + +: "${CONFIG_STATUS=./config.status}" +ac_write_fail=0 +ac_clean_files_save=$ac_clean_files +ac_clean_files="$ac_clean_files $CONFIG_STATUS" +{ $as_echo "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5 +$as_echo "$as_me: creating $CONFIG_STATUS" >&6;} +as_write_fail=0 +cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1 +#! $SHELL +# Generated by $as_me. +# Run this file to recreate the current configuration. +# Compiler output produced by configure, useful for debugging +# configure, is in config.log if it exists. + +debug=false +ac_cs_recheck=false +ac_cs_silent=false + +SHELL=\${CONFIG_SHELL-$SHELL} +export SHELL +_ASEOF +cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1 +## -------------------- ## +## M4sh Initialization. ## +## -------------------- ## + +# Be more Bourne compatible +DUALCASE=1; export DUALCASE # for MKS sh +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : + emulate sh + NULLCMD=: + # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in #( + *posix*) : + set -o posix ;; #( + *) : + ;; +esac +fi + + +as_nl=' +' +export as_nl +# Printing a long string crashes Solaris 7 /usr/bin/printf. +as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo +# Prefer a ksh shell builtin over an external printf program on Solaris, +# but without wasting forks for bash or zsh. +if test -z "$BASH_VERSION$ZSH_VERSION" \ + && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='print -r --' + as_echo_n='print -rn --' +elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='printf %s\n' + as_echo_n='printf %s' +else + if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then + as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' + as_echo_n='/usr/ucb/echo -n' + else + as_echo_body='eval expr "X$1" : "X\\(.*\\)"' + as_echo_n_body='eval + arg=$1; + case $arg in #( + *"$as_nl"*) + expr "X$arg" : "X\\(.*\\)$as_nl"; + arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; + esac; + expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" + ' + export as_echo_n_body + as_echo_n='sh -c $as_echo_n_body as_echo' + fi + export as_echo_body + as_echo='sh -c $as_echo_body as_echo' +fi + +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + PATH_SEPARATOR=: + (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { + (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || + PATH_SEPARATOR=';' + } +fi + + +# IFS +# We need space, tab and new line, in precisely that order. Quoting is +# there to prevent editors from complaining about space-tab. +# (If _AS_PATH_WALK were called with IFS unset, it would disable word +# splitting by setting IFS to empty value.) +IFS=" "" $as_nl" + +# Find who we are. Look in the path if we contain no directory separator. +as_myself= +case $0 in #(( + *[\\/]* ) as_myself=$0 ;; + *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break + done +IFS=$as_save_IFS + + ;; +esac +# We did not find ourselves, most probably we were run as `sh COMMAND' +# in which case we are not to be found in the path. +if test "x$as_myself" = x; then + as_myself=$0 +fi +if test ! -f "$as_myself"; then + $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 + exit 1 +fi + +# Unset variables that we do not need and which cause bugs (e.g. in +# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" +# suppresses any "Segmentation fault" message there. '((' could +# trigger a bug in pdksh 5.2.14. +for as_var in BASH_ENV ENV MAIL MAILPATH +do eval test x\${$as_var+set} = xset \ + && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : +done +PS1='$ ' +PS2='> ' +PS4='+ ' + +# NLS nuisances. +LC_ALL=C +export LC_ALL +LANGUAGE=C +export LANGUAGE + +# CDPATH. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + + +# as_fn_error STATUS ERROR [LINENO LOG_FD] +# ---------------------------------------- +# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are +# provided, also output the error to LOG_FD, referencing LINENO. Then exit the +# script with STATUS, using 1 if that was 0. +as_fn_error () +{ + as_status=$1; test $as_status -eq 0 && as_status=1 + if test "$4"; then + as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 + fi + $as_echo "$as_me: error: $2" >&2 + as_fn_exit $as_status +} # as_fn_error + + +# as_fn_set_status STATUS +# ----------------------- +# Set $? to STATUS, without forking. +as_fn_set_status () +{ + return $1 +} # as_fn_set_status + +# as_fn_exit STATUS +# ----------------- +# Exit the shell with STATUS, even in a "trap 0" or "set -e" context. +as_fn_exit () +{ + set +e + as_fn_set_status $1 + exit $1 +} # as_fn_exit + +# as_fn_unset VAR +# --------------- +# Portably unset VAR. +as_fn_unset () +{ + { eval $1=; unset $1;} +} +as_unset=as_fn_unset +# as_fn_append VAR VALUE +# ---------------------- +# Append the text in VALUE to the end of the definition contained in VAR. Take +# advantage of any shell optimizations that allow amortized linear growth over +# repeated appends, instead of the typical quadratic growth present in naive +# implementations. +if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : + eval 'as_fn_append () + { + eval $1+=\$2 + }' +else + as_fn_append () + { + eval $1=\$$1\$2 + } +fi # as_fn_append + +# as_fn_arith ARG... +# ------------------ +# Perform arithmetic evaluation on the ARGs, and store the result in the +# global $as_val. Take advantage of shells that can avoid forks. The arguments +# must be portable across $(()) and expr. +if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : + eval 'as_fn_arith () + { + as_val=$(( $* )) + }' +else + as_fn_arith () + { + as_val=`expr "$@" || test $? -eq 1` + } +fi # as_fn_arith + + +if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; then + as_expr=expr +else + as_expr=false +fi + +if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then + as_basename=basename +else + as_basename=false +fi + +if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then + as_dirname=dirname +else + as_dirname=false +fi + +as_me=`$as_basename -- "$0" || +$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ + s//\1/ + q + } + /^X\/\(\/\/\)$/{ + s//\1/ + q + } + /^X\/\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + +# Avoid depending upon Character Ranges. +as_cr_letters='abcdefghijklmnopqrstuvwxyz' +as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' +as_cr_Letters=$as_cr_letters$as_cr_LETTERS +as_cr_digits='0123456789' +as_cr_alnum=$as_cr_Letters$as_cr_digits + +ECHO_C= ECHO_N= ECHO_T= +case `echo -n x` in #((((( +-n*) + case `echo 'xy\c'` in + *c*) ECHO_T=' ';; # ECHO_T is single tab character. + xy) ECHO_C='\c';; + *) echo `echo ksh88 bug on AIX 6.1` > /dev/null + ECHO_T=' ';; + esac;; +*) + ECHO_N='-n';; +esac + +rm -f conf$$ conf$$.exe conf$$.file +if test -d conf$$.dir; then + rm -f conf$$.dir/conf$$.file +else + rm -f conf$$.dir + mkdir conf$$.dir 2>/dev/null +fi +if (echo >conf$$.file) 2>/dev/null; then + if ln -s conf$$.file conf$$ 2>/dev/null; then + as_ln_s='ln -s' + # ... but there are two gotchas: + # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. + # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. + # In both cases, we have to default to `cp -p'. + ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || + as_ln_s='cp -p' + elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln + else + as_ln_s='cp -p' + fi +else + as_ln_s='cp -p' +fi +rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file +rmdir conf$$.dir 2>/dev/null + + +# as_fn_mkdir_p +# ------------- +# Create "$as_dir" as a directory, including parents if necessary. +as_fn_mkdir_p () +{ + + case $as_dir in #( + -*) as_dir=./$as_dir;; + esac + test -d "$as_dir" || eval $as_mkdir_p || { + as_dirs= + while :; do + case $as_dir in #( + *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( + *) as_qdir=$as_dir;; + esac + as_dirs="'$as_qdir' $as_dirs" + as_dir=`$as_dirname -- "$as_dir" || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + test -d "$as_dir" && break + done + test -z "$as_dirs" || eval "mkdir $as_dirs" + } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" + + +} # as_fn_mkdir_p +if mkdir -p . 2>/dev/null; then + as_mkdir_p='mkdir -p "$as_dir"' +else + test -d ./-p && rmdir ./-p + as_mkdir_p=false +fi + +if test -x / >/dev/null 2>&1; then + as_test_x='test -x' +else + if ls -dL / >/dev/null 2>&1; then + as_ls_L_option=L + else + as_ls_L_option= + fi + as_test_x=' + eval sh -c '\'' + if test -d "$1"; then + test -d "$1/."; + else + case $1 in #( + -*)set "./$1";; + esac; + case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in #(( + ???[sx]*):;;*)false;;esac;fi + '\'' sh + ' +fi +as_executable_p=$as_test_x + +# Sed expression to map a string onto a valid CPP name. +as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" + +# Sed expression to map a string onto a valid variable name. +as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" + + +exec 6>&1 +## ----------------------------------- ## +## Main body of $CONFIG_STATUS script. ## +## ----------------------------------- ## +_ASEOF +test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1 + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +# Save the log message, to keep $0 and so on meaningful, and to +# report actual input values of CONFIG_FILES etc. instead of their +# values after options handling. +ac_log=" +This file was extended by yaml $as_me 0.1.6, which was +generated by GNU Autoconf 2.68. Invocation command line was + + CONFIG_FILES = $CONFIG_FILES + CONFIG_HEADERS = $CONFIG_HEADERS + CONFIG_LINKS = $CONFIG_LINKS + CONFIG_COMMANDS = $CONFIG_COMMANDS + $ $0 $@ + +on `(hostname || uname -n) 2>/dev/null | sed 1q` +" + +_ACEOF + +case $ac_config_files in *" +"*) set x $ac_config_files; shift; ac_config_files=$*;; +esac + +case $ac_config_headers in *" +"*) set x $ac_config_headers; shift; ac_config_headers=$*;; +esac + + +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +# Files that config.status was made for. +config_files="$ac_config_files" +config_headers="$ac_config_headers" +config_commands="$ac_config_commands" + +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +ac_cs_usage="\ +\`$as_me' instantiates files and other configuration actions +from templates according to the current configuration. Unless the files +and actions are specified as TAGs, all are instantiated by default. + +Usage: $0 [OPTION]... [TAG]... + + -h, --help print this help, then exit + -V, --version print version number and configuration settings, then exit + --config print configuration, then exit + -q, --quiet, --silent + do not print progress messages + -d, --debug don't remove temporary files + --recheck update $as_me by reconfiguring in the same conditions + --file=FILE[:TEMPLATE] + instantiate the configuration file FILE + --header=FILE[:TEMPLATE] + instantiate the configuration header FILE + +Configuration files: +$config_files + +Configuration headers: +$config_headers + +Configuration commands: +$config_commands + +Report bugs to ." + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" +ac_cs_version="\\ +yaml config.status 0.1.6 +configured by $0, generated by GNU Autoconf 2.68, + with options \\"\$ac_cs_config\\" + +Copyright (C) 2010 Free Software Foundation, Inc. +This config.status script is free software; the Free Software Foundation +gives unlimited permission to copy, distribute and modify it." + +ac_pwd='$ac_pwd' +srcdir='$srcdir' +INSTALL='$INSTALL' +MKDIR_P='$MKDIR_P' +AWK='$AWK' +test -n "\$AWK" || AWK=awk +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +# The default lists apply if the user does not specify any file. +ac_need_defaults=: +while test $# != 0 +do + case $1 in + --*=?*) + ac_option=`expr "X$1" : 'X\([^=]*\)='` + ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'` + ac_shift=: + ;; + --*=) + ac_option=`expr "X$1" : 'X\([^=]*\)='` + ac_optarg= + ac_shift=: + ;; + *) + ac_option=$1 + ac_optarg=$2 + ac_shift=shift + ;; + esac + + case $ac_option in + # Handling of the options. + -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) + ac_cs_recheck=: ;; + --version | --versio | --versi | --vers | --ver | --ve | --v | -V ) + $as_echo "$ac_cs_version"; exit ;; + --config | --confi | --conf | --con | --co | --c ) + $as_echo "$ac_cs_config"; exit ;; + --debug | --debu | --deb | --de | --d | -d ) + debug=: ;; + --file | --fil | --fi | --f ) + $ac_shift + case $ac_optarg in + *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; + '') as_fn_error $? "missing file argument" ;; + esac + as_fn_append CONFIG_FILES " '$ac_optarg'" + ac_need_defaults=false;; + --header | --heade | --head | --hea ) + $ac_shift + case $ac_optarg in + *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; + esac + as_fn_append CONFIG_HEADERS " '$ac_optarg'" + ac_need_defaults=false;; + --he | --h) + # Conflict between --help and --header + as_fn_error $? "ambiguous option: \`$1' +Try \`$0 --help' for more information.";; + --help | --hel | -h ) + $as_echo "$ac_cs_usage"; exit ;; + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil | --si | --s) + ac_cs_silent=: ;; + + # This is an error. + -*) as_fn_error $? "unrecognized option: \`$1' +Try \`$0 --help' for more information." ;; + + *) as_fn_append ac_config_targets " $1" + ac_need_defaults=false ;; + + esac + shift +done + +ac_configure_extra_args= + +if $ac_cs_silent; then + exec 6>/dev/null + ac_configure_extra_args="$ac_configure_extra_args --silent" +fi + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +if \$ac_cs_recheck; then + set X '$SHELL' '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion + shift + \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6 + CONFIG_SHELL='$SHELL' + export CONFIG_SHELL + exec "\$@" +fi + +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +exec 5>>config.log +{ + echo + sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX +## Running $as_me. ## +_ASBOX + $as_echo "$ac_log" +} >&5 + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +# +# INIT-COMMANDS +# +AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir" + + +# The HP-UX ksh and POSIX shell print the target directory to stdout +# if CDPATH is set. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + +sed_quote_subst='$sed_quote_subst' +double_quote_subst='$double_quote_subst' +delay_variable_subst='$delay_variable_subst' +macro_version='`$ECHO "$macro_version" | $SED "$delay_single_quote_subst"`' +macro_revision='`$ECHO "$macro_revision" | $SED "$delay_single_quote_subst"`' +enable_shared='`$ECHO "$enable_shared" | $SED "$delay_single_quote_subst"`' +enable_static='`$ECHO "$enable_static" | $SED "$delay_single_quote_subst"`' +pic_mode='`$ECHO "$pic_mode" | $SED "$delay_single_quote_subst"`' +enable_fast_install='`$ECHO "$enable_fast_install" | $SED "$delay_single_quote_subst"`' +SHELL='`$ECHO "$SHELL" | $SED "$delay_single_quote_subst"`' +ECHO='`$ECHO "$ECHO" | $SED "$delay_single_quote_subst"`' +PATH_SEPARATOR='`$ECHO "$PATH_SEPARATOR" | $SED "$delay_single_quote_subst"`' +host_alias='`$ECHO "$host_alias" | $SED "$delay_single_quote_subst"`' +host='`$ECHO "$host" | $SED "$delay_single_quote_subst"`' +host_os='`$ECHO "$host_os" | $SED "$delay_single_quote_subst"`' +build_alias='`$ECHO "$build_alias" | $SED "$delay_single_quote_subst"`' +build='`$ECHO "$build" | $SED "$delay_single_quote_subst"`' +build_os='`$ECHO "$build_os" | $SED "$delay_single_quote_subst"`' +SED='`$ECHO "$SED" | $SED "$delay_single_quote_subst"`' +Xsed='`$ECHO "$Xsed" | $SED "$delay_single_quote_subst"`' +GREP='`$ECHO "$GREP" | $SED "$delay_single_quote_subst"`' +EGREP='`$ECHO "$EGREP" | $SED "$delay_single_quote_subst"`' +FGREP='`$ECHO "$FGREP" | $SED "$delay_single_quote_subst"`' +LD='`$ECHO "$LD" | $SED "$delay_single_quote_subst"`' +NM='`$ECHO "$NM" | $SED "$delay_single_quote_subst"`' +LN_S='`$ECHO "$LN_S" | $SED "$delay_single_quote_subst"`' +max_cmd_len='`$ECHO "$max_cmd_len" | $SED "$delay_single_quote_subst"`' +ac_objext='`$ECHO "$ac_objext" | $SED "$delay_single_quote_subst"`' +exeext='`$ECHO "$exeext" | $SED "$delay_single_quote_subst"`' +lt_unset='`$ECHO "$lt_unset" | $SED "$delay_single_quote_subst"`' +lt_SP2NL='`$ECHO "$lt_SP2NL" | $SED "$delay_single_quote_subst"`' +lt_NL2SP='`$ECHO "$lt_NL2SP" | $SED "$delay_single_quote_subst"`' +lt_cv_to_host_file_cmd='`$ECHO "$lt_cv_to_host_file_cmd" | $SED "$delay_single_quote_subst"`' +lt_cv_to_tool_file_cmd='`$ECHO "$lt_cv_to_tool_file_cmd" | $SED "$delay_single_quote_subst"`' +reload_flag='`$ECHO "$reload_flag" | $SED "$delay_single_quote_subst"`' +reload_cmds='`$ECHO "$reload_cmds" | $SED "$delay_single_quote_subst"`' +OBJDUMP='`$ECHO "$OBJDUMP" | $SED "$delay_single_quote_subst"`' +deplibs_check_method='`$ECHO "$deplibs_check_method" | $SED "$delay_single_quote_subst"`' +file_magic_cmd='`$ECHO "$file_magic_cmd" | $SED "$delay_single_quote_subst"`' +file_magic_glob='`$ECHO "$file_magic_glob" | $SED "$delay_single_quote_subst"`' +want_nocaseglob='`$ECHO "$want_nocaseglob" | $SED "$delay_single_quote_subst"`' +DLLTOOL='`$ECHO "$DLLTOOL" | $SED "$delay_single_quote_subst"`' +sharedlib_from_linklib_cmd='`$ECHO "$sharedlib_from_linklib_cmd" | $SED "$delay_single_quote_subst"`' +AR='`$ECHO "$AR" | $SED "$delay_single_quote_subst"`' +AR_FLAGS='`$ECHO "$AR_FLAGS" | $SED "$delay_single_quote_subst"`' +archiver_list_spec='`$ECHO "$archiver_list_spec" | $SED "$delay_single_quote_subst"`' +STRIP='`$ECHO "$STRIP" | $SED "$delay_single_quote_subst"`' +RANLIB='`$ECHO "$RANLIB" | $SED "$delay_single_quote_subst"`' +old_postinstall_cmds='`$ECHO "$old_postinstall_cmds" | $SED "$delay_single_quote_subst"`' +old_postuninstall_cmds='`$ECHO "$old_postuninstall_cmds" | $SED "$delay_single_quote_subst"`' +old_archive_cmds='`$ECHO "$old_archive_cmds" | $SED "$delay_single_quote_subst"`' +lock_old_archive_extraction='`$ECHO "$lock_old_archive_extraction" | $SED "$delay_single_quote_subst"`' +CC='`$ECHO "$CC" | $SED "$delay_single_quote_subst"`' +CFLAGS='`$ECHO "$CFLAGS" | $SED "$delay_single_quote_subst"`' +compiler='`$ECHO "$compiler" | $SED "$delay_single_quote_subst"`' +GCC='`$ECHO "$GCC" | $SED "$delay_single_quote_subst"`' +lt_cv_sys_global_symbol_pipe='`$ECHO "$lt_cv_sys_global_symbol_pipe" | $SED "$delay_single_quote_subst"`' +lt_cv_sys_global_symbol_to_cdecl='`$ECHO "$lt_cv_sys_global_symbol_to_cdecl" | $SED "$delay_single_quote_subst"`' +lt_cv_sys_global_symbol_to_c_name_address='`$ECHO "$lt_cv_sys_global_symbol_to_c_name_address" | $SED "$delay_single_quote_subst"`' +lt_cv_sys_global_symbol_to_c_name_address_lib_prefix='`$ECHO "$lt_cv_sys_global_symbol_to_c_name_address_lib_prefix" | $SED "$delay_single_quote_subst"`' +nm_file_list_spec='`$ECHO "$nm_file_list_spec" | $SED "$delay_single_quote_subst"`' +lt_sysroot='`$ECHO "$lt_sysroot" | $SED "$delay_single_quote_subst"`' +objdir='`$ECHO "$objdir" | $SED "$delay_single_quote_subst"`' +MAGIC_CMD='`$ECHO "$MAGIC_CMD" | $SED "$delay_single_quote_subst"`' +lt_prog_compiler_no_builtin_flag='`$ECHO "$lt_prog_compiler_no_builtin_flag" | $SED "$delay_single_quote_subst"`' +lt_prog_compiler_pic='`$ECHO "$lt_prog_compiler_pic" | $SED "$delay_single_quote_subst"`' +lt_prog_compiler_wl='`$ECHO "$lt_prog_compiler_wl" | $SED "$delay_single_quote_subst"`' +lt_prog_compiler_static='`$ECHO "$lt_prog_compiler_static" | $SED "$delay_single_quote_subst"`' +lt_cv_prog_compiler_c_o='`$ECHO "$lt_cv_prog_compiler_c_o" | $SED "$delay_single_quote_subst"`' +need_locks='`$ECHO "$need_locks" | $SED "$delay_single_quote_subst"`' +MANIFEST_TOOL='`$ECHO "$MANIFEST_TOOL" | $SED "$delay_single_quote_subst"`' +DSYMUTIL='`$ECHO "$DSYMUTIL" | $SED "$delay_single_quote_subst"`' +NMEDIT='`$ECHO "$NMEDIT" | $SED "$delay_single_quote_subst"`' +LIPO='`$ECHO "$LIPO" | $SED "$delay_single_quote_subst"`' +OTOOL='`$ECHO "$OTOOL" | $SED "$delay_single_quote_subst"`' +OTOOL64='`$ECHO "$OTOOL64" | $SED "$delay_single_quote_subst"`' +libext='`$ECHO "$libext" | $SED "$delay_single_quote_subst"`' +shrext_cmds='`$ECHO "$shrext_cmds" | $SED "$delay_single_quote_subst"`' +extract_expsyms_cmds='`$ECHO "$extract_expsyms_cmds" | $SED "$delay_single_quote_subst"`' +archive_cmds_need_lc='`$ECHO "$archive_cmds_need_lc" | $SED "$delay_single_quote_subst"`' +enable_shared_with_static_runtimes='`$ECHO "$enable_shared_with_static_runtimes" | $SED "$delay_single_quote_subst"`' +export_dynamic_flag_spec='`$ECHO "$export_dynamic_flag_spec" | $SED "$delay_single_quote_subst"`' +whole_archive_flag_spec='`$ECHO "$whole_archive_flag_spec" | $SED "$delay_single_quote_subst"`' +compiler_needs_object='`$ECHO "$compiler_needs_object" | $SED "$delay_single_quote_subst"`' +old_archive_from_new_cmds='`$ECHO "$old_archive_from_new_cmds" | $SED "$delay_single_quote_subst"`' +old_archive_from_expsyms_cmds='`$ECHO "$old_archive_from_expsyms_cmds" | $SED "$delay_single_quote_subst"`' +archive_cmds='`$ECHO "$archive_cmds" | $SED "$delay_single_quote_subst"`' +archive_expsym_cmds='`$ECHO "$archive_expsym_cmds" | $SED "$delay_single_quote_subst"`' +module_cmds='`$ECHO "$module_cmds" | $SED "$delay_single_quote_subst"`' +module_expsym_cmds='`$ECHO "$module_expsym_cmds" | $SED "$delay_single_quote_subst"`' +with_gnu_ld='`$ECHO "$with_gnu_ld" | $SED "$delay_single_quote_subst"`' +allow_undefined_flag='`$ECHO "$allow_undefined_flag" | $SED "$delay_single_quote_subst"`' +no_undefined_flag='`$ECHO "$no_undefined_flag" | $SED "$delay_single_quote_subst"`' +hardcode_libdir_flag_spec='`$ECHO "$hardcode_libdir_flag_spec" | $SED "$delay_single_quote_subst"`' +hardcode_libdir_separator='`$ECHO "$hardcode_libdir_separator" | $SED "$delay_single_quote_subst"`' +hardcode_direct='`$ECHO "$hardcode_direct" | $SED "$delay_single_quote_subst"`' +hardcode_direct_absolute='`$ECHO "$hardcode_direct_absolute" | $SED "$delay_single_quote_subst"`' +hardcode_minus_L='`$ECHO "$hardcode_minus_L" | $SED "$delay_single_quote_subst"`' +hardcode_shlibpath_var='`$ECHO "$hardcode_shlibpath_var" | $SED "$delay_single_quote_subst"`' +hardcode_automatic='`$ECHO "$hardcode_automatic" | $SED "$delay_single_quote_subst"`' +inherit_rpath='`$ECHO "$inherit_rpath" | $SED "$delay_single_quote_subst"`' +link_all_deplibs='`$ECHO "$link_all_deplibs" | $SED "$delay_single_quote_subst"`' +always_export_symbols='`$ECHO "$always_export_symbols" | $SED "$delay_single_quote_subst"`' +export_symbols_cmds='`$ECHO "$export_symbols_cmds" | $SED "$delay_single_quote_subst"`' +exclude_expsyms='`$ECHO "$exclude_expsyms" | $SED "$delay_single_quote_subst"`' +include_expsyms='`$ECHO "$include_expsyms" | $SED "$delay_single_quote_subst"`' +prelink_cmds='`$ECHO "$prelink_cmds" | $SED "$delay_single_quote_subst"`' +postlink_cmds='`$ECHO "$postlink_cmds" | $SED "$delay_single_quote_subst"`' +file_list_spec='`$ECHO "$file_list_spec" | $SED "$delay_single_quote_subst"`' +variables_saved_for_relink='`$ECHO "$variables_saved_for_relink" | $SED "$delay_single_quote_subst"`' +need_lib_prefix='`$ECHO "$need_lib_prefix" | $SED "$delay_single_quote_subst"`' +need_version='`$ECHO "$need_version" | $SED "$delay_single_quote_subst"`' +version_type='`$ECHO "$version_type" | $SED "$delay_single_quote_subst"`' +runpath_var='`$ECHO "$runpath_var" | $SED "$delay_single_quote_subst"`' +shlibpath_var='`$ECHO "$shlibpath_var" | $SED "$delay_single_quote_subst"`' +shlibpath_overrides_runpath='`$ECHO "$shlibpath_overrides_runpath" | $SED "$delay_single_quote_subst"`' +libname_spec='`$ECHO "$libname_spec" | $SED "$delay_single_quote_subst"`' +library_names_spec='`$ECHO "$library_names_spec" | $SED "$delay_single_quote_subst"`' +soname_spec='`$ECHO "$soname_spec" | $SED "$delay_single_quote_subst"`' +install_override_mode='`$ECHO "$install_override_mode" | $SED "$delay_single_quote_subst"`' +postinstall_cmds='`$ECHO "$postinstall_cmds" | $SED "$delay_single_quote_subst"`' +postuninstall_cmds='`$ECHO "$postuninstall_cmds" | $SED "$delay_single_quote_subst"`' +finish_cmds='`$ECHO "$finish_cmds" | $SED "$delay_single_quote_subst"`' +finish_eval='`$ECHO "$finish_eval" | $SED "$delay_single_quote_subst"`' +hardcode_into_libs='`$ECHO "$hardcode_into_libs" | $SED "$delay_single_quote_subst"`' +sys_lib_search_path_spec='`$ECHO "$sys_lib_search_path_spec" | $SED "$delay_single_quote_subst"`' +sys_lib_dlsearch_path_spec='`$ECHO "$sys_lib_dlsearch_path_spec" | $SED "$delay_single_quote_subst"`' +hardcode_action='`$ECHO "$hardcode_action" | $SED "$delay_single_quote_subst"`' +enable_dlopen='`$ECHO "$enable_dlopen" | $SED "$delay_single_quote_subst"`' +enable_dlopen_self='`$ECHO "$enable_dlopen_self" | $SED "$delay_single_quote_subst"`' +enable_dlopen_self_static='`$ECHO "$enable_dlopen_self_static" | $SED "$delay_single_quote_subst"`' +old_striplib='`$ECHO "$old_striplib" | $SED "$delay_single_quote_subst"`' +striplib='`$ECHO "$striplib" | $SED "$delay_single_quote_subst"`' + +LTCC='$LTCC' +LTCFLAGS='$LTCFLAGS' +compiler='$compiler_DEFAULT' + +# A function that is used when there is no print builtin or printf. +func_fallback_echo () +{ + eval 'cat <<_LTECHO_EOF +\$1 +_LTECHO_EOF' +} + +# Quote evaled strings. +for var in SHELL \ +ECHO \ +PATH_SEPARATOR \ +SED \ +GREP \ +EGREP \ +FGREP \ +LD \ +NM \ +LN_S \ +lt_SP2NL \ +lt_NL2SP \ +reload_flag \ +OBJDUMP \ +deplibs_check_method \ +file_magic_cmd \ +file_magic_glob \ +want_nocaseglob \ +DLLTOOL \ +sharedlib_from_linklib_cmd \ +AR \ +AR_FLAGS \ +archiver_list_spec \ +STRIP \ +RANLIB \ +CC \ +CFLAGS \ +compiler \ +lt_cv_sys_global_symbol_pipe \ +lt_cv_sys_global_symbol_to_cdecl \ +lt_cv_sys_global_symbol_to_c_name_address \ +lt_cv_sys_global_symbol_to_c_name_address_lib_prefix \ +nm_file_list_spec \ +lt_prog_compiler_no_builtin_flag \ +lt_prog_compiler_pic \ +lt_prog_compiler_wl \ +lt_prog_compiler_static \ +lt_cv_prog_compiler_c_o \ +need_locks \ +MANIFEST_TOOL \ +DSYMUTIL \ +NMEDIT \ +LIPO \ +OTOOL \ +OTOOL64 \ +shrext_cmds \ +export_dynamic_flag_spec \ +whole_archive_flag_spec \ +compiler_needs_object \ +with_gnu_ld \ +allow_undefined_flag \ +no_undefined_flag \ +hardcode_libdir_flag_spec \ +hardcode_libdir_separator \ +exclude_expsyms \ +include_expsyms \ +file_list_spec \ +variables_saved_for_relink \ +libname_spec \ +library_names_spec \ +soname_spec \ +install_override_mode \ +finish_eval \ +old_striplib \ +striplib; do + case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in + *[\\\\\\\`\\"\\\$]*) + eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED \\"\\\$sed_quote_subst\\"\\\`\\\\\\"" + ;; + *) + eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" + ;; + esac +done + +# Double-quote double-evaled strings. +for var in reload_cmds \ +old_postinstall_cmds \ +old_postuninstall_cmds \ +old_archive_cmds \ +extract_expsyms_cmds \ +old_archive_from_new_cmds \ +old_archive_from_expsyms_cmds \ +archive_cmds \ +archive_expsym_cmds \ +module_cmds \ +module_expsym_cmds \ +export_symbols_cmds \ +prelink_cmds \ +postlink_cmds \ +postinstall_cmds \ +postuninstall_cmds \ +finish_cmds \ +sys_lib_search_path_spec \ +sys_lib_dlsearch_path_spec; do + case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in + *[\\\\\\\`\\"\\\$]*) + eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\"" + ;; + *) + eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" + ;; + esac +done + +ac_aux_dir='$ac_aux_dir' +xsi_shell='$xsi_shell' +lt_shell_append='$lt_shell_append' + +# See if we are running on zsh, and set the options which allow our +# commands through without removal of \ escapes INIT. +if test -n "\${ZSH_VERSION+set}" ; then + setopt NO_GLOB_SUBST +fi + + + PACKAGE='$PACKAGE' + VERSION='$VERSION' + TIMESTAMP='$TIMESTAMP' + RM='$RM' + ofile='$ofile' + + + + +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 + +# Handling of arguments. +for ac_config_target in $ac_config_targets +do + case $ac_config_target in + "config.h") CONFIG_HEADERS="$CONFIG_HEADERS config.h" ;; + "depfiles") CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;; + "libtool") CONFIG_COMMANDS="$CONFIG_COMMANDS libtool" ;; + "yaml-0.1.pc") CONFIG_FILES="$CONFIG_FILES yaml-0.1.pc" ;; + "include/Makefile") CONFIG_FILES="$CONFIG_FILES include/Makefile" ;; + "src/Makefile") CONFIG_FILES="$CONFIG_FILES src/Makefile" ;; + "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;; + "tests/Makefile") CONFIG_FILES="$CONFIG_FILES tests/Makefile" ;; + "win32/Makefile") CONFIG_FILES="$CONFIG_FILES win32/Makefile" ;; + + *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;; + esac +done + + +# If the user did not use the arguments to specify the items to instantiate, +# then the envvar interface is used. Set only those that are not. +# We use the long form for the default assignment because of an extremely +# bizarre bug on SunOS 4.1.3. +if $ac_need_defaults; then + test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files + test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers + test "${CONFIG_COMMANDS+set}" = set || CONFIG_COMMANDS=$config_commands +fi + +# Have a temporary directory for convenience. Make it in the build tree +# simply because there is no reason against having it here, and in addition, +# creating and moving files from /tmp can sometimes cause problems. +# Hook for its removal unless debugging. +# Note that there is a small window in which the directory will not be cleaned: +# after its creation but before its name has been assigned to `$tmp'. +$debug || +{ + tmp= ac_tmp= + trap 'exit_status=$? + : "${ac_tmp:=$tmp}" + { test ! -d "$ac_tmp" || rm -fr "$ac_tmp"; } && exit $exit_status +' 0 + trap 'as_fn_exit 1' 1 2 13 15 +} +# Create a (secure) tmp directory for tmp files. + +{ + tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` && + test -d "$tmp" +} || +{ + tmp=./conf$$-$RANDOM + (umask 077 && mkdir "$tmp") +} || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5 +ac_tmp=$tmp + +# Set up the scripts for CONFIG_FILES section. +# No need to generate them if there are no CONFIG_FILES. +# This happens for instance with `./config.status config.h'. +if test -n "$CONFIG_FILES"; then + + +ac_cr=`echo X | tr X '\015'` +# On cygwin, bash can eat \r inside `` if the user requested igncr. +# But we know of no other shell where ac_cr would be empty at this +# point, so we can use a bashism as a fallback. +if test "x$ac_cr" = x; then + eval ac_cr=\$\'\\r\' +fi +ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' /dev/null` +if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then + ac_cs_awk_cr='\\r' +else + ac_cs_awk_cr=$ac_cr +fi + +echo 'BEGIN {' >"$ac_tmp/subs1.awk" && +_ACEOF + + +{ + echo "cat >conf$$subs.awk <<_ACEOF" && + echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' && + echo "_ACEOF" +} >conf$$subs.sh || + as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 +ac_delim_num=`echo "$ac_subst_vars" | grep -c '^'` +ac_delim='%!_!# ' +for ac_last_try in false false false false false :; do + . ./conf$$subs.sh || + as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 + + ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X` + if test $ac_delim_n = $ac_delim_num; then + break + elif $ac_last_try; then + as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 + else + ac_delim="$ac_delim!$ac_delim _$ac_delim!! " + fi +done +rm -f conf$$subs.sh + +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +cat >>"\$ac_tmp/subs1.awk" <<\\_ACAWK && +_ACEOF +sed -n ' +h +s/^/S["/; s/!.*/"]=/ +p +g +s/^[^!]*!// +:repl +t repl +s/'"$ac_delim"'$// +t delim +:nl +h +s/\(.\{148\}\)..*/\1/ +t more1 +s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/ +p +n +b repl +:more1 +s/["\\]/\\&/g; s/^/"/; s/$/"\\/ +p +g +s/.\{148\}// +t nl +:delim +h +s/\(.\{148\}\)..*/\1/ +t more2 +s/["\\]/\\&/g; s/^/"/; s/$/"/ +p +b +:more2 +s/["\\]/\\&/g; s/^/"/; s/$/"\\/ +p +g +s/.\{148\}// +t delim +' >$CONFIG_STATUS || ac_write_fail=1 +rm -f conf$$subs.awk +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +_ACAWK +cat >>"\$ac_tmp/subs1.awk" <<_ACAWK && + for (key in S) S_is_set[key] = 1 + FS = "" + +} +{ + line = $ 0 + nfields = split(line, field, "@") + substed = 0 + len = length(field[1]) + for (i = 2; i < nfields; i++) { + key = field[i] + keylen = length(key) + if (S_is_set[key]) { + value = S[key] + line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3) + len += length(value) + length(field[++i]) + substed = 1 + } else + len += 1 + keylen + } + + print line +} + +_ACAWK +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then + sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g" +else + cat +fi < "$ac_tmp/subs1.awk" > "$ac_tmp/subs.awk" \ + || as_fn_error $? "could not setup config files machinery" "$LINENO" 5 +_ACEOF + +# VPATH may cause trouble with some makes, so we remove sole $(srcdir), +# ${srcdir} and @srcdir@ entries from VPATH if srcdir is ".", strip leading and +# trailing colons and then remove the whole line if VPATH becomes empty +# (actually we leave an empty line to preserve line numbers). +if test "x$srcdir" = x.; then + ac_vpsub='/^[ ]*VPATH[ ]*=[ ]*/{ +h +s/// +s/^/:/ +s/[ ]*$/:/ +s/:\$(srcdir):/:/g +s/:\${srcdir}:/:/g +s/:@srcdir@:/:/g +s/^:*// +s/:*$// +x +s/\(=[ ]*\).*/\1/ +G +s/\n// +s/^[^=]*=[ ]*$// +}' +fi + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +fi # test -n "$CONFIG_FILES" + +# Set up the scripts for CONFIG_HEADERS section. +# No need to generate them if there are no CONFIG_HEADERS. +# This happens for instance with `./config.status Makefile'. +if test -n "$CONFIG_HEADERS"; then +cat >"$ac_tmp/defines.awk" <<\_ACAWK || +BEGIN { +_ACEOF + +# Transform confdefs.h into an awk script `defines.awk', embedded as +# here-document in config.status, that substitutes the proper values into +# config.h.in to produce config.h. + +# Create a delimiter string that does not exist in confdefs.h, to ease +# handling of long lines. +ac_delim='%!_!# ' +for ac_last_try in false false :; do + ac_tt=`sed -n "/$ac_delim/p" confdefs.h` + if test -z "$ac_tt"; then + break + elif $ac_last_try; then + as_fn_error $? "could not make $CONFIG_HEADERS" "$LINENO" 5 + else + ac_delim="$ac_delim!$ac_delim _$ac_delim!! " + fi +done + +# For the awk script, D is an array of macro values keyed by name, +# likewise P contains macro parameters if any. Preserve backslash +# newline sequences. + +ac_word_re=[_$as_cr_Letters][_$as_cr_alnum]* +sed -n ' +s/.\{148\}/&'"$ac_delim"'/g +t rset +:rset +s/^[ ]*#[ ]*define[ ][ ]*/ / +t def +d +:def +s/\\$// +t bsnl +s/["\\]/\\&/g +s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ +D["\1"]=" \3"/p +s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2"/p +d +:bsnl +s/["\\]/\\&/g +s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ +D["\1"]=" \3\\\\\\n"\\/p +t cont +s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2\\\\\\n"\\/p +t cont +d +:cont +n +s/.\{148\}/&'"$ac_delim"'/g +t clear +:clear +s/\\$// +t bsnlc +s/["\\]/\\&/g; s/^/"/; s/$/"/p +d +:bsnlc +s/["\\]/\\&/g; s/^/"/; s/$/\\\\\\n"\\/p +b cont +' >$CONFIG_STATUS || ac_write_fail=1 + +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 + for (key in D) D_is_set[key] = 1 + FS = "" +} +/^[\t ]*#[\t ]*(define|undef)[\t ]+$ac_word_re([\t (]|\$)/ { + line = \$ 0 + split(line, arg, " ") + if (arg[1] == "#") { + defundef = arg[2] + mac1 = arg[3] + } else { + defundef = substr(arg[1], 2) + mac1 = arg[2] + } + split(mac1, mac2, "(") #) + macro = mac2[1] + prefix = substr(line, 1, index(line, defundef) - 1) + if (D_is_set[macro]) { + # Preserve the white space surrounding the "#". + print prefix "define", macro P[macro] D[macro] + next + } else { + # Replace #undef with comments. This is necessary, for example, + # in the case of _POSIX_SOURCE, which is predefined and required + # on some systems where configure will not decide to define it. + if (defundef == "undef") { + print "/*", prefix defundef, macro, "*/" + next + } + } +} +{ print } +_ACAWK +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 + as_fn_error $? "could not setup config headers machinery" "$LINENO" 5 +fi # test -n "$CONFIG_HEADERS" + + +eval set X " :F $CONFIG_FILES :H $CONFIG_HEADERS :C $CONFIG_COMMANDS" +shift +for ac_tag +do + case $ac_tag in + :[FHLC]) ac_mode=$ac_tag; continue;; + esac + case $ac_mode$ac_tag in + :[FHL]*:*);; + :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5;; + :[FH]-) ac_tag=-:-;; + :[FH]*) ac_tag=$ac_tag:$ac_tag.in;; + esac + ac_save_IFS=$IFS + IFS=: + set x $ac_tag + IFS=$ac_save_IFS + shift + ac_file=$1 + shift + + case $ac_mode in + :L) ac_source=$1;; + :[FH]) + ac_file_inputs= + for ac_f + do + case $ac_f in + -) ac_f="$ac_tmp/stdin";; + *) # Look for the file first in the build tree, then in the source tree + # (if the path is not absolute). The absolute path cannot be DOS-style, + # because $ac_f cannot contain `:'. + test -f "$ac_f" || + case $ac_f in + [\\/$]*) false;; + *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";; + esac || + as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5;; + esac + case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac + as_fn_append ac_file_inputs " '$ac_f'" + done + + # Let's still pretend it is `configure' which instantiates (i.e., don't + # use $as_me), people would be surprised to read: + # /* config.h. Generated by config.status. */ + configure_input='Generated from '` + $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g' + `' by configure.' + if test x"$ac_file" != x-; then + configure_input="$ac_file. $configure_input" + { $as_echo "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5 +$as_echo "$as_me: creating $ac_file" >&6;} + fi + # Neutralize special characters interpreted by sed in replacement strings. + case $configure_input in #( + *\&* | *\|* | *\\* ) + ac_sed_conf_input=`$as_echo "$configure_input" | + sed 's/[\\\\&|]/\\\\&/g'`;; #( + *) ac_sed_conf_input=$configure_input;; + esac + + case $ac_tag in + *:-:* | *:-) cat >"$ac_tmp/stdin" \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; + esac + ;; + esac + + ac_dir=`$as_dirname -- "$ac_file" || +$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$ac_file" : 'X\(//\)[^/]' \| \ + X"$ac_file" : 'X\(//\)$' \| \ + X"$ac_file" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$ac_file" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + as_dir="$ac_dir"; as_fn_mkdir_p + ac_builddir=. + +case "$ac_dir" in +.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; +*) + ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` + # A ".." for each directory in $ac_dir_suffix. + ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` + case $ac_top_builddir_sub in + "") ac_top_builddir_sub=. ac_top_build_prefix= ;; + *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; + esac ;; +esac +ac_abs_top_builddir=$ac_pwd +ac_abs_builddir=$ac_pwd$ac_dir_suffix +# for backward compatibility: +ac_top_builddir=$ac_top_build_prefix + +case $srcdir in + .) # We are building in place. + ac_srcdir=. + ac_top_srcdir=$ac_top_builddir_sub + ac_abs_top_srcdir=$ac_pwd ;; + [\\/]* | ?:[\\/]* ) # Absolute name. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir + ac_abs_top_srcdir=$srcdir ;; + *) # Relative name. + ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_build_prefix$srcdir + ac_abs_top_srcdir=$ac_pwd/$srcdir ;; +esac +ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix + + + case $ac_mode in + :F) + # + # CONFIG_FILE + # + + case $INSTALL in + [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;; + *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;; + esac + ac_MKDIR_P=$MKDIR_P + case $MKDIR_P in + [\\/$]* | ?:[\\/]* ) ;; + */*) ac_MKDIR_P=$ac_top_build_prefix$MKDIR_P ;; + esac +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +# If the template does not know about datarootdir, expand it. +# FIXME: This hack should be removed a few years after 2.60. +ac_datarootdir_hack=; ac_datarootdir_seen= +ac_sed_dataroot=' +/datarootdir/ { + p + q +} +/@datadir@/p +/@docdir@/p +/@infodir@/p +/@localedir@/p +/@mandir@/p' +case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in +*datarootdir*) ac_datarootdir_seen=yes;; +*@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*) + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5 +$as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;} +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 + ac_datarootdir_hack=' + s&@datadir@&$datadir&g + s&@docdir@&$docdir&g + s&@infodir@&$infodir&g + s&@localedir@&$localedir&g + s&@mandir@&$mandir&g + s&\\\${datarootdir}&$datarootdir&g' ;; +esac +_ACEOF + +# Neutralize VPATH when `$srcdir' = `.'. +# Shell code in configure.ac might set extrasub. +# FIXME: do we really want to maintain this feature? +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +ac_sed_extra="$ac_vpsub +$extrasub +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +:t +/@[a-zA-Z_][a-zA-Z_0-9]*@/!b +s|@configure_input@|$ac_sed_conf_input|;t t +s&@top_builddir@&$ac_top_builddir_sub&;t t +s&@top_build_prefix@&$ac_top_build_prefix&;t t +s&@srcdir@&$ac_srcdir&;t t +s&@abs_srcdir@&$ac_abs_srcdir&;t t +s&@top_srcdir@&$ac_top_srcdir&;t t +s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t +s&@builddir@&$ac_builddir&;t t +s&@abs_builddir@&$ac_abs_builddir&;t t +s&@abs_top_builddir@&$ac_abs_top_builddir&;t t +s&@INSTALL@&$ac_INSTALL&;t t +s&@MKDIR_P@&$ac_MKDIR_P&;t t +$ac_datarootdir_hack +" +eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$ac_tmp/subs.awk" \ + >$ac_tmp/out || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + +test -z "$ac_datarootdir_hack$ac_datarootdir_seen" && + { ac_out=`sed -n '/\${datarootdir}/p' "$ac_tmp/out"`; test -n "$ac_out"; } && + { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' \ + "$ac_tmp/out"`; test -z "$ac_out"; } && + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir' +which seems to be undefined. Please make sure it is defined" >&5 +$as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir' +which seems to be undefined. Please make sure it is defined" >&2;} + + rm -f "$ac_tmp/stdin" + case $ac_file in + -) cat "$ac_tmp/out" && rm -f "$ac_tmp/out";; + *) rm -f "$ac_file" && mv "$ac_tmp/out" "$ac_file";; + esac \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + ;; + :H) + # + # CONFIG_HEADER + # + if test x"$ac_file" != x-; then + { + $as_echo "/* $configure_input */" \ + && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" + } >"$ac_tmp/config.h" \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + if diff "$ac_file" "$ac_tmp/config.h" >/dev/null 2>&1; then + { $as_echo "$as_me:${as_lineno-$LINENO}: $ac_file is unchanged" >&5 +$as_echo "$as_me: $ac_file is unchanged" >&6;} + else + rm -f "$ac_file" + mv "$ac_tmp/config.h" "$ac_file" \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + fi + else + $as_echo "/* $configure_input */" \ + && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" \ + || as_fn_error $? "could not create -" "$LINENO" 5 + fi +# Compute "$ac_file"'s index in $config_headers. +_am_arg="$ac_file" +_am_stamp_count=1 +for _am_header in $config_headers :; do + case $_am_header in + $_am_arg | $_am_arg:* ) + break ;; + * ) + _am_stamp_count=`expr $_am_stamp_count + 1` ;; + esac +done +echo "timestamp for $_am_arg" >`$as_dirname -- "$_am_arg" || +$as_expr X"$_am_arg" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$_am_arg" : 'X\(//\)[^/]' \| \ + X"$_am_arg" : 'X\(//\)$' \| \ + X"$_am_arg" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$_am_arg" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'`/stamp-h$_am_stamp_count + ;; + + :C) { $as_echo "$as_me:${as_lineno-$LINENO}: executing $ac_file commands" >&5 +$as_echo "$as_me: executing $ac_file commands" >&6;} + ;; + esac + + + case $ac_file$ac_mode in + "depfiles":C) test x"$AMDEP_TRUE" != x"" || { + # Autoconf 2.62 quotes --file arguments for eval, but not when files + # are listed without --file. Let's play safe and only enable the eval + # if we detect the quoting. + case $CONFIG_FILES in + *\'*) eval set x "$CONFIG_FILES" ;; + *) set x $CONFIG_FILES ;; + esac + shift + for mf + do + # Strip MF so we end up with the name of the file. + mf=`echo "$mf" | sed -e 's/:.*$//'` + # Check whether this is an Automake generated Makefile or not. + # We used to match only the files named `Makefile.in', but + # some people rename them; so instead we look at the file content. + # Grep'ing the first line is not enough: some people post-process + # each Makefile.in and add a new line on top of each file to say so. + # Grep'ing the whole file is not good either: AIX grep has a line + # limit of 2048, but all sed's we know have understand at least 4000. + if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then + dirpart=`$as_dirname -- "$mf" || +$as_expr X"$mf" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$mf" : 'X\(//\)[^/]' \| \ + X"$mf" : 'X\(//\)$' \| \ + X"$mf" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$mf" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + else + continue + fi + # Extract the definition of DEPDIR, am__include, and am__quote + # from the Makefile without running `make'. + DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` + test -z "$DEPDIR" && continue + am__include=`sed -n 's/^am__include = //p' < "$mf"` + test -z "am__include" && continue + am__quote=`sed -n 's/^am__quote = //p' < "$mf"` + # When using ansi2knr, U may be empty or an underscore; expand it + U=`sed -n 's/^U = //p' < "$mf"` + # Find all dependency output files, they are included files with + # $(DEPDIR) in their names. We invoke sed twice because it is the + # simplest approach to changing $(DEPDIR) to its actual value in the + # expansion. + for file in `sed -n " + s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ + sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do + # Make sure the directory exists. + test -f "$dirpart/$file" && continue + fdir=`$as_dirname -- "$file" || +$as_expr X"$file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$file" : 'X\(//\)[^/]' \| \ + X"$file" : 'X\(//\)$' \| \ + X"$file" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$file" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + as_dir=$dirpart/$fdir; as_fn_mkdir_p + # echo "creating $dirpart/$file" + echo '# dummy' > "$dirpart/$file" + done + done +} + ;; + "libtool":C) + + # See if we are running on zsh, and set the options which allow our + # commands through without removal of \ escapes. + if test -n "${ZSH_VERSION+set}" ; then + setopt NO_GLOB_SUBST + fi + + cfgfile="${ofile}T" + trap "$RM \"$cfgfile\"; exit 1" 1 2 15 + $RM "$cfgfile" + + cat <<_LT_EOF >> "$cfgfile" +#! $SHELL + +# `$ECHO "$ofile" | sed 's%^.*/%%'` - Provide generalized library-building support services. +# Generated automatically by $as_me ($PACKAGE$TIMESTAMP) $VERSION +# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`: +# NOTE: Changes made to this file will be lost: look at ltmain.sh. +# +# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, +# 2006, 2007, 2008, 2009, 2010, 2011 Free Software +# Foundation, Inc. +# Written by Gordon Matzigkeit, 1996 +# +# This file is part of GNU Libtool. +# +# GNU Libtool is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# +# As a special exception to the GNU General Public License, +# if you distribute this file as part of a program or library that +# is built using GNU Libtool, you may include this file under the +# same distribution terms that you use for the rest of that program. +# +# GNU Libtool is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GNU Libtool; see the file COPYING. If not, a copy +# can be downloaded from http://www.gnu.org/licenses/gpl.html, or +# obtained by writing to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + + +# The names of the tagged configurations supported by this script. +available_tags="" + +# ### BEGIN LIBTOOL CONFIG + +# Which release of libtool.m4 was used? +macro_version=$macro_version +macro_revision=$macro_revision + +# Whether or not to build shared libraries. +build_libtool_libs=$enable_shared + +# Whether or not to build static libraries. +build_old_libs=$enable_static + +# What type of objects to build. +pic_mode=$pic_mode + +# Whether or not to optimize for fast installation. +fast_install=$enable_fast_install + +# Shell to use when invoking shell scripts. +SHELL=$lt_SHELL + +# An echo program that protects backslashes. +ECHO=$lt_ECHO + +# The PATH separator for the build system. +PATH_SEPARATOR=$lt_PATH_SEPARATOR + +# The host system. +host_alias=$host_alias +host=$host +host_os=$host_os + +# The build system. +build_alias=$build_alias +build=$build +build_os=$build_os + +# A sed program that does not truncate output. +SED=$lt_SED + +# Sed that helps us avoid accidentally triggering echo(1) options like -n. +Xsed="\$SED -e 1s/^X//" + +# A grep program that handles long lines. +GREP=$lt_GREP + +# An ERE matcher. +EGREP=$lt_EGREP + +# A literal string matcher. +FGREP=$lt_FGREP + +# A BSD- or MS-compatible name lister. +NM=$lt_NM + +# Whether we need soft or hard links. +LN_S=$lt_LN_S + +# What is the maximum length of a command? +max_cmd_len=$max_cmd_len + +# Object file suffix (normally "o"). +objext=$ac_objext + +# Executable file suffix (normally ""). +exeext=$exeext + +# whether the shell understands "unset". +lt_unset=$lt_unset + +# turn spaces into newlines. +SP2NL=$lt_lt_SP2NL + +# turn newlines into spaces. +NL2SP=$lt_lt_NL2SP + +# convert \$build file names to \$host format. +to_host_file_cmd=$lt_cv_to_host_file_cmd + +# convert \$build files to toolchain format. +to_tool_file_cmd=$lt_cv_to_tool_file_cmd + +# An object symbol dumper. +OBJDUMP=$lt_OBJDUMP + +# Method to check whether dependent libraries are shared objects. +deplibs_check_method=$lt_deplibs_check_method + +# Command to use when deplibs_check_method = "file_magic". +file_magic_cmd=$lt_file_magic_cmd + +# How to find potential files when deplibs_check_method = "file_magic". +file_magic_glob=$lt_file_magic_glob + +# Find potential files using nocaseglob when deplibs_check_method = "file_magic". +want_nocaseglob=$lt_want_nocaseglob + +# DLL creation program. +DLLTOOL=$lt_DLLTOOL + +# Command to associate shared and link libraries. +sharedlib_from_linklib_cmd=$lt_sharedlib_from_linklib_cmd + +# The archiver. +AR=$lt_AR + +# Flags to create an archive. +AR_FLAGS=$lt_AR_FLAGS + +# How to feed a file listing to the archiver. +archiver_list_spec=$lt_archiver_list_spec + +# A symbol stripping program. +STRIP=$lt_STRIP + +# Commands used to install an old-style archive. +RANLIB=$lt_RANLIB +old_postinstall_cmds=$lt_old_postinstall_cmds +old_postuninstall_cmds=$lt_old_postuninstall_cmds + +# Whether to use a lock for old archive extraction. +lock_old_archive_extraction=$lock_old_archive_extraction + +# A C compiler. +LTCC=$lt_CC + +# LTCC compiler flags. +LTCFLAGS=$lt_CFLAGS + +# Take the output of nm and produce a listing of raw symbols and C names. +global_symbol_pipe=$lt_lt_cv_sys_global_symbol_pipe + +# Transform the output of nm in a proper C declaration. +global_symbol_to_cdecl=$lt_lt_cv_sys_global_symbol_to_cdecl + +# Transform the output of nm in a C name address pair. +global_symbol_to_c_name_address=$lt_lt_cv_sys_global_symbol_to_c_name_address + +# Transform the output of nm in a C name address pair when lib prefix is needed. +global_symbol_to_c_name_address_lib_prefix=$lt_lt_cv_sys_global_symbol_to_c_name_address_lib_prefix + +# Specify filename containing input files for \$NM. +nm_file_list_spec=$lt_nm_file_list_spec + +# The root where to search for dependent libraries,and in which our libraries should be installed. +lt_sysroot=$lt_sysroot + +# The name of the directory that contains temporary libtool files. +objdir=$objdir + +# Used to examine libraries when file_magic_cmd begins with "file". +MAGIC_CMD=$MAGIC_CMD + +# Must we lock files when doing compilation? +need_locks=$lt_need_locks + +# Manifest tool. +MANIFEST_TOOL=$lt_MANIFEST_TOOL + +# Tool to manipulate archived DWARF debug symbol files on Mac OS X. +DSYMUTIL=$lt_DSYMUTIL + +# Tool to change global to local symbols on Mac OS X. +NMEDIT=$lt_NMEDIT + +# Tool to manipulate fat objects and archives on Mac OS X. +LIPO=$lt_LIPO + +# ldd/readelf like tool for Mach-O binaries on Mac OS X. +OTOOL=$lt_OTOOL + +# ldd/readelf like tool for 64 bit Mach-O binaries on Mac OS X 10.4. +OTOOL64=$lt_OTOOL64 + +# Old archive suffix (normally "a"). +libext=$libext + +# Shared library suffix (normally ".so"). +shrext_cmds=$lt_shrext_cmds + +# The commands to extract the exported symbol list from a shared archive. +extract_expsyms_cmds=$lt_extract_expsyms_cmds + +# Variables whose values should be saved in libtool wrapper scripts and +# restored at link time. +variables_saved_for_relink=$lt_variables_saved_for_relink + +# Do we need the "lib" prefix for modules? +need_lib_prefix=$need_lib_prefix + +# Do we need a version for libraries? +need_version=$need_version + +# Library versioning type. +version_type=$version_type + +# Shared library runtime path variable. +runpath_var=$runpath_var + +# Shared library path variable. +shlibpath_var=$shlibpath_var + +# Is shlibpath searched before the hard-coded library search path? +shlibpath_overrides_runpath=$shlibpath_overrides_runpath + +# Format of library name prefix. +libname_spec=$lt_libname_spec + +# List of archive names. First name is the real one, the rest are links. +# The last name is the one that the linker finds with -lNAME +library_names_spec=$lt_library_names_spec + +# The coded name of the library, if different from the real name. +soname_spec=$lt_soname_spec + +# Permission mode override for installation of shared libraries. +install_override_mode=$lt_install_override_mode + +# Command to use after installation of a shared archive. +postinstall_cmds=$lt_postinstall_cmds + +# Command to use after uninstallation of a shared archive. +postuninstall_cmds=$lt_postuninstall_cmds + +# Commands used to finish a libtool library installation in a directory. +finish_cmds=$lt_finish_cmds + +# As "finish_cmds", except a single script fragment to be evaled but +# not shown. +finish_eval=$lt_finish_eval + +# Whether we should hardcode library paths into libraries. +hardcode_into_libs=$hardcode_into_libs + +# Compile-time system search path for libraries. +sys_lib_search_path_spec=$lt_sys_lib_search_path_spec + +# Run-time system search path for libraries. +sys_lib_dlsearch_path_spec=$lt_sys_lib_dlsearch_path_spec + +# Whether dlopen is supported. +dlopen_support=$enable_dlopen + +# Whether dlopen of programs is supported. +dlopen_self=$enable_dlopen_self + +# Whether dlopen of statically linked programs is supported. +dlopen_self_static=$enable_dlopen_self_static + +# Commands to strip libraries. +old_striplib=$lt_old_striplib +striplib=$lt_striplib + + +# The linker used to build libraries. +LD=$lt_LD + +# How to create reloadable object files. +reload_flag=$lt_reload_flag +reload_cmds=$lt_reload_cmds + +# Commands used to build an old-style archive. +old_archive_cmds=$lt_old_archive_cmds + +# A language specific compiler. +CC=$lt_compiler + +# Is the compiler the GNU compiler? +with_gcc=$GCC + +# Compiler flag to turn off builtin functions. +no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag + +# Additional compiler flags for building library objects. +pic_flag=$lt_lt_prog_compiler_pic + +# How to pass a linker flag through the compiler. +wl=$lt_lt_prog_compiler_wl + +# Compiler flag to prevent dynamic linking. +link_static_flag=$lt_lt_prog_compiler_static + +# Does compiler simultaneously support -c and -o options? +compiler_c_o=$lt_lt_cv_prog_compiler_c_o + +# Whether or not to add -lc for building shared libraries. +build_libtool_need_lc=$archive_cmds_need_lc + +# Whether or not to disallow shared libs when runtime libs are static. +allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes + +# Compiler flag to allow reflexive dlopens. +export_dynamic_flag_spec=$lt_export_dynamic_flag_spec + +# Compiler flag to generate shared objects directly from archives. +whole_archive_flag_spec=$lt_whole_archive_flag_spec + +# Whether the compiler copes with passing no objects directly. +compiler_needs_object=$lt_compiler_needs_object + +# Create an old-style archive from a shared archive. +old_archive_from_new_cmds=$lt_old_archive_from_new_cmds + +# Create a temporary old-style archive to link instead of a shared archive. +old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds + +# Commands used to build a shared archive. +archive_cmds=$lt_archive_cmds +archive_expsym_cmds=$lt_archive_expsym_cmds + +# Commands used to build a loadable module if different from building +# a shared archive. +module_cmds=$lt_module_cmds +module_expsym_cmds=$lt_module_expsym_cmds + +# Whether we are building with GNU ld or not. +with_gnu_ld=$lt_with_gnu_ld + +# Flag that allows shared libraries with undefined symbols to be built. +allow_undefined_flag=$lt_allow_undefined_flag + +# Flag that enforces no undefined symbols. +no_undefined_flag=$lt_no_undefined_flag + +# Flag to hardcode \$libdir into a binary during linking. +# This must work even if \$libdir does not exist +hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec + +# Whether we need a single "-rpath" flag with a separated argument. +hardcode_libdir_separator=$lt_hardcode_libdir_separator + +# Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes +# DIR into the resulting binary. +hardcode_direct=$hardcode_direct + +# Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes +# DIR into the resulting binary and the resulting library dependency is +# "absolute",i.e impossible to change by setting \${shlibpath_var} if the +# library is relocated. +hardcode_direct_absolute=$hardcode_direct_absolute + +# Set to "yes" if using the -LDIR flag during linking hardcodes DIR +# into the resulting binary. +hardcode_minus_L=$hardcode_minus_L + +# Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR +# into the resulting binary. +hardcode_shlibpath_var=$hardcode_shlibpath_var + +# Set to "yes" if building a shared library automatically hardcodes DIR +# into the library and all subsequent libraries and executables linked +# against it. +hardcode_automatic=$hardcode_automatic + +# Set to yes if linker adds runtime paths of dependent libraries +# to runtime path list. +inherit_rpath=$inherit_rpath + +# Whether libtool must link a program against all its dependency libraries. +link_all_deplibs=$link_all_deplibs + +# Set to "yes" if exported symbols are required. +always_export_symbols=$always_export_symbols + +# The commands to list exported symbols. +export_symbols_cmds=$lt_export_symbols_cmds + +# Symbols that should not be listed in the preloaded symbols. +exclude_expsyms=$lt_exclude_expsyms + +# Symbols that must always be exported. +include_expsyms=$lt_include_expsyms + +# Commands necessary for linking programs (against libraries) with templates. +prelink_cmds=$lt_prelink_cmds + +# Commands necessary for finishing linking programs. +postlink_cmds=$lt_postlink_cmds + +# Specify filename containing input files. +file_list_spec=$lt_file_list_spec + +# How to hardcode a shared library path into an executable. +hardcode_action=$hardcode_action + +# ### END LIBTOOL CONFIG + +_LT_EOF + + case $host_os in + aix3*) + cat <<\_LT_EOF >> "$cfgfile" +# AIX sometimes has problems with the GCC collect2 program. For some +# reason, if we set the COLLECT_NAMES environment variable, the problems +# vanish in a puff of smoke. +if test "X${COLLECT_NAMES+set}" != Xset; then + COLLECT_NAMES= + export COLLECT_NAMES +fi +_LT_EOF + ;; + esac + + +ltmain="$ac_aux_dir/ltmain.sh" + + + # We use sed instead of cat because bash on DJGPP gets confused if + # if finds mixed CR/LF and LF-only lines. Since sed operates in + # text mode, it properly converts lines to CR/LF. This bash problem + # is reportedly fixed, but why not run on old versions too? + sed '$q' "$ltmain" >> "$cfgfile" \ + || (rm -f "$cfgfile"; exit 1) + + if test x"$xsi_shell" = xyes; then + sed -e '/^func_dirname ()$/,/^} # func_dirname /c\ +func_dirname ()\ +{\ +\ case ${1} in\ +\ */*) func_dirname_result="${1%/*}${2}" ;;\ +\ * ) func_dirname_result="${3}" ;;\ +\ esac\ +} # Extended-shell func_dirname implementation' "$cfgfile" > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") +test 0 -eq $? || _lt_function_replace_fail=: + + + sed -e '/^func_basename ()$/,/^} # func_basename /c\ +func_basename ()\ +{\ +\ func_basename_result="${1##*/}"\ +} # Extended-shell func_basename implementation' "$cfgfile" > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") +test 0 -eq $? || _lt_function_replace_fail=: + + + sed -e '/^func_dirname_and_basename ()$/,/^} # func_dirname_and_basename /c\ +func_dirname_and_basename ()\ +{\ +\ case ${1} in\ +\ */*) func_dirname_result="${1%/*}${2}" ;;\ +\ * ) func_dirname_result="${3}" ;;\ +\ esac\ +\ func_basename_result="${1##*/}"\ +} # Extended-shell func_dirname_and_basename implementation' "$cfgfile" > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") +test 0 -eq $? || _lt_function_replace_fail=: + + + sed -e '/^func_stripname ()$/,/^} # func_stripname /c\ +func_stripname ()\ +{\ +\ # pdksh 5.2.14 does not do ${X%$Y} correctly if both X and Y are\ +\ # positional parameters, so assign one to ordinary parameter first.\ +\ func_stripname_result=${3}\ +\ func_stripname_result=${func_stripname_result#"${1}"}\ +\ func_stripname_result=${func_stripname_result%"${2}"}\ +} # Extended-shell func_stripname implementation' "$cfgfile" > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") +test 0 -eq $? || _lt_function_replace_fail=: + + + sed -e '/^func_split_long_opt ()$/,/^} # func_split_long_opt /c\ +func_split_long_opt ()\ +{\ +\ func_split_long_opt_name=${1%%=*}\ +\ func_split_long_opt_arg=${1#*=}\ +} # Extended-shell func_split_long_opt implementation' "$cfgfile" > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") +test 0 -eq $? || _lt_function_replace_fail=: + + + sed -e '/^func_split_short_opt ()$/,/^} # func_split_short_opt /c\ +func_split_short_opt ()\ +{\ +\ func_split_short_opt_arg=${1#??}\ +\ func_split_short_opt_name=${1%"$func_split_short_opt_arg"}\ +} # Extended-shell func_split_short_opt implementation' "$cfgfile" > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") +test 0 -eq $? || _lt_function_replace_fail=: + + + sed -e '/^func_lo2o ()$/,/^} # func_lo2o /c\ +func_lo2o ()\ +{\ +\ case ${1} in\ +\ *.lo) func_lo2o_result=${1%.lo}.${objext} ;;\ +\ *) func_lo2o_result=${1} ;;\ +\ esac\ +} # Extended-shell func_lo2o implementation' "$cfgfile" > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") +test 0 -eq $? || _lt_function_replace_fail=: + + + sed -e '/^func_xform ()$/,/^} # func_xform /c\ +func_xform ()\ +{\ + func_xform_result=${1%.*}.lo\ +} # Extended-shell func_xform implementation' "$cfgfile" > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") +test 0 -eq $? || _lt_function_replace_fail=: + + + sed -e '/^func_arith ()$/,/^} # func_arith /c\ +func_arith ()\ +{\ + func_arith_result=$(( $* ))\ +} # Extended-shell func_arith implementation' "$cfgfile" > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") +test 0 -eq $? || _lt_function_replace_fail=: + + + sed -e '/^func_len ()$/,/^} # func_len /c\ +func_len ()\ +{\ + func_len_result=${#1}\ +} # Extended-shell func_len implementation' "$cfgfile" > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") +test 0 -eq $? || _lt_function_replace_fail=: + +fi + +if test x"$lt_shell_append" = xyes; then + sed -e '/^func_append ()$/,/^} # func_append /c\ +func_append ()\ +{\ + eval "${1}+=\\${2}"\ +} # Extended-shell func_append implementation' "$cfgfile" > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") +test 0 -eq $? || _lt_function_replace_fail=: + + + sed -e '/^func_append_quoted ()$/,/^} # func_append_quoted /c\ +func_append_quoted ()\ +{\ +\ func_quote_for_eval "${2}"\ +\ eval "${1}+=\\\\ \\$func_quote_for_eval_result"\ +} # Extended-shell func_append_quoted implementation' "$cfgfile" > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") +test 0 -eq $? || _lt_function_replace_fail=: + + + # Save a `func_append' function call where possible by direct use of '+=' + sed -e 's%func_append \([a-zA-Z_]\{1,\}\) "%\1+="%g' $cfgfile > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") + test 0 -eq $? || _lt_function_replace_fail=: +else + # Save a `func_append' function call even when '+=' is not available + sed -e 's%func_append \([a-zA-Z_]\{1,\}\) "%\1="$\1%g' $cfgfile > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") + test 0 -eq $? || _lt_function_replace_fail=: +fi + +if test x"$_lt_function_replace_fail" = x":"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Unable to substitute extended shell functions in $ofile" >&5 +$as_echo "$as_me: WARNING: Unable to substitute extended shell functions in $ofile" >&2;} +fi + + + mv -f "$cfgfile" "$ofile" || + (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile") + chmod +x "$ofile" + + ;; + + esac +done # for ac_tag + + +as_fn_exit 0 +_ACEOF +ac_clean_files=$ac_clean_files_save + +test $ac_write_fail = 0 || + as_fn_error $? "write failure creating $CONFIG_STATUS" "$LINENO" 5 + + +# configure is writing to config.log, and then calls config.status. +# config.status does its own redirection, appending to config.log. +# Unfortunately, on DOS this fails, as config.log is still kept open +# by configure, so config.status won't be able to write to it; its +# output is simply discarded. So we exec the FD to /dev/null, +# effectively closing config.log, so it can be properly (re)opened and +# appended to by config.status. When coming back to configure, we +# need to make the FD available again. +if test "$no_create" != yes; then + ac_cs_success=: + ac_config_status_args= + test "$silent" = yes && + ac_config_status_args="$ac_config_status_args --quiet" + exec 5>/dev/null + $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false + exec 5>>config.log + # Use ||, not &&, to avoid exiting from the if with $? = 1, which + # would make configure fail if this is the last instruction. + $ac_cs_success || as_fn_exit 1 +fi +if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5 +$as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;} +fi + diff --git a/web/server/h2o/libh2o/deps/yaml/configure.ac b/web/server/h2o/libh2o/deps/yaml/configure.ac new file mode 100644 index 00000000..dd1aca05 --- /dev/null +++ b/web/server/h2o/libh2o/deps/yaml/configure.ac @@ -0,0 +1,73 @@ +# Run `./bootstrap` to generate the "configure" script. + +# Define the package version numbers and the bug reporting link. +m4_define([YAML_MAJOR], 0) +m4_define([YAML_MINOR], 1) +m4_define([YAML_PATCH], 6) +m4_define([YAML_BUGS], [http://pyyaml.org/newticket?component=libyaml]) + +# Define the libtool version numbers; check the Autobook, Section 11.4. +# Bump the libtool version numbers using the following algorithm: +# if (the current interface has not been changed): +# YAML_REVISION += 1 +# else: +# YAML_REVISION = 0 +# YAML_CURRENT += 1 +# if (this release is backward compatible with the previous release): +# YAML_AGE += 1 +# else: +# YAML_AGE = 0 +m4_define([YAML_RELEASE], 0) +m4_define([YAML_CURRENT], 2) +m4_define([YAML_REVISION], 4) +m4_define([YAML_AGE], 0) + +# Initialize autoconf & automake. +AC_PREREQ(2.59) +AC_INIT([yaml], [YAML_MAJOR.YAML_MINOR.YAML_PATCH], [YAML_BUGS]) +AC_CONFIG_AUX_DIR([config]) +AC_CONFIG_HEADERS([config.h]) +AM_INIT_AUTOMAKE([1.9 foreign]) + +# Define macro variables for the package version numbers. +AC_DEFINE(YAML_VERSION_MAJOR, YAML_MAJOR, [Define the major version number.]) +AC_DEFINE(YAML_VERSION_MINOR, YAML_MINOR, [Define the minor version number.]) +AC_DEFINE(YAML_VERSION_PATCH, YAML_PATCH, [Define the patch version number.]) +AC_DEFINE(YAML_VERSION_STRING, "YAML_MAJOR.YAML_MINOR.YAML_PATCH", [Define the version string.]) + +# Define substitutions for the libtool version numbers. +YAML_LT_RELEASE=YAML_RELEASE +YAML_LT_CURRENT=YAML_CURRENT +YAML_LT_REVISION=YAML_REVISION +YAML_LT_AGE=YAML_AGE +AC_SUBST(YAML_LT_RELEASE) +AC_SUBST(YAML_LT_CURRENT) +AC_SUBST(YAML_LT_REVISION) +AC_SUBST(YAML_LT_AGE) + +# Note: in order to update checks, run `autoscan` and look through "configure.scan". + +# Checks for programs. +AC_PROG_CC +AC_PROG_CPP +AC_PROG_INSTALL +AC_PROG_LN_S +AC_PROG_MAKE_SET +AC_PROG_LIBTOOL + +AC_CHECK_PROG(DOXYGEN, [doxygen], [true], [false]) +AM_CONDITIONAL(DOXYGEN, [test "$DOXYGEN" = true]) + +# Checks for header files. +AC_HEADER_STDC +AC_CHECK_HEADERS([stdlib.h]) + +# Checks for typedefs, structures, and compiler characteristics. +AC_C_CONST +AC_TYPE_SIZE_T + +# Define Makefiles. +AC_CONFIG_FILES([yaml-0.1.pc include/Makefile src/Makefile Makefile tests/Makefile win32/Makefile]) + +# Generate the "configure" script. +AC_OUTPUT diff --git a/web/server/h2o/libh2o/deps/yaml/doc/doxygen.cfg b/web/server/h2o/libh2o/deps/yaml/doc/doxygen.cfg new file mode 100644 index 00000000..a58bb177 --- /dev/null +++ b/web/server/h2o/libh2o/deps/yaml/doc/doxygen.cfg @@ -0,0 +1,222 @@ +# Doxyfile 1.4.4 + +#--------------------------------------------------------------------------- +# Project related configuration options +#--------------------------------------------------------------------------- +PROJECT_NAME = $(PACKAGE) +PROJECT_NUMBER = $(VERSION) +OUTPUT_DIRECTORY = $(top_builddir)/doc/ +CREATE_SUBDIRS = NO +OUTPUT_LANGUAGE = English +USE_WINDOWS_ENCODING = NO +BRIEF_MEMBER_DESC = YES +REPEAT_BRIEF = YES +ABBREVIATE_BRIEF = +ALWAYS_DETAILED_SEC = NO +INLINE_INHERITED_MEMB = NO +FULL_PATH_NAMES = YES +STRIP_FROM_PATH = +STRIP_FROM_INC_PATH = +SHORT_NAMES = NO +JAVADOC_AUTOBRIEF = YES +MULTILINE_CPP_IS_BRIEF = NO +DETAILS_AT_TOP = NO +INHERIT_DOCS = YES +DISTRIBUTE_GROUP_DOC = NO +SEPARATE_MEMBER_PAGES = NO +TAB_SIZE = 8 +ALIASES = +OPTIMIZE_OUTPUT_FOR_C = YES +OPTIMIZE_OUTPUT_JAVA = NO +SUBGROUPING = YES +#--------------------------------------------------------------------------- +# Build related configuration options +#--------------------------------------------------------------------------- +EXTRACT_ALL = NO +EXTRACT_PRIVATE = NO +EXTRACT_STATIC = NO +EXTRACT_LOCAL_CLASSES = NO +EXTRACT_LOCAL_METHODS = NO +HIDE_UNDOC_MEMBERS = NO +HIDE_UNDOC_CLASSES = NO +HIDE_FRIEND_COMPOUNDS = NO +HIDE_IN_BODY_DOCS = NO +INTERNAL_DOCS = NO +CASE_SENSE_NAMES = YES +HIDE_SCOPE_NAMES = NO +SHOW_INCLUDE_FILES = YES +INLINE_INFO = YES +SORT_MEMBER_DOCS = NO +SORT_BRIEF_DOCS = NO +SORT_BY_SCOPE_NAME = NO +GENERATE_TODOLIST = YES +GENERATE_TESTLIST = YES +GENERATE_BUGLIST = YES +GENERATE_DEPRECATEDLIST= YES +ENABLED_SECTIONS = +MAX_INITIALIZER_LINES = 30 +SHOW_USED_FILES = YES +SHOW_DIRECTORIES = YES +FILE_VERSION_FILTER = +#--------------------------------------------------------------------------- +# configuration options related to warning and progress messages +#--------------------------------------------------------------------------- +QUIET = NO +WARNINGS = YES +WARN_IF_UNDOCUMENTED = YES +WARN_IF_DOC_ERROR = YES +WARN_NO_PARAMDOC = NO +WARN_FORMAT = "$file:$line: $text" +WARN_LOGFILE = +#--------------------------------------------------------------------------- +# configuration options related to the input files +#--------------------------------------------------------------------------- +INPUT = $(top_srcdir)/include/ +FILE_PATTERNS = *.h +RECURSIVE = YES +EXCLUDE = +EXCLUDE_SYMLINKS = NO +EXCLUDE_PATTERNS = +EXAMPLE_PATH = +EXAMPLE_PATTERNS = +EXAMPLE_RECURSIVE = NO +IMAGE_PATH = +INPUT_FILTER = +FILTER_PATTERNS = +FILTER_SOURCE_FILES = NO +#--------------------------------------------------------------------------- +# configuration options related to source browsing +#--------------------------------------------------------------------------- +SOURCE_BROWSER = NO +INLINE_SOURCES = NO +STRIP_CODE_COMMENTS = YES +REFERENCED_BY_RELATION = NO +REFERENCES_RELATION = NO +USE_HTAGS = NO +VERBATIM_HEADERS = NO +#--------------------------------------------------------------------------- +# configuration options related to the alphabetical class index +#--------------------------------------------------------------------------- +ALPHABETICAL_INDEX = NO +COLS_IN_ALPHA_INDEX = 5 +IGNORE_PREFIX = +#--------------------------------------------------------------------------- +# configuration options related to the HTML output +#--------------------------------------------------------------------------- +GENERATE_HTML = YES +HTML_OUTPUT = html +HTML_FILE_EXTENSION = .html +HTML_HEADER = +HTML_FOOTER = +HTML_STYLESHEET = +HTML_ALIGN_MEMBERS = YES +GENERATE_HTMLHELP = NO +CHM_FILE = +HHC_LOCATION = +GENERATE_CHI = NO +BINARY_TOC = NO +TOC_EXPAND = NO +DISABLE_INDEX = NO +ENUM_VALUES_PER_LINE = 1 +GENERATE_TREEVIEW = NO +TREEVIEW_WIDTH = 250 +#--------------------------------------------------------------------------- +# configuration options related to the LaTeX output +#--------------------------------------------------------------------------- +GENERATE_LATEX = NO +LATEX_OUTPUT = latex +LATEX_CMD_NAME = latex +MAKEINDEX_CMD_NAME = makeindex +COMPACT_LATEX = NO +PAPER_TYPE = a4wide +EXTRA_PACKAGES = +LATEX_HEADER = +PDF_HYPERLINKS = NO +USE_PDFLATEX = NO +LATEX_BATCHMODE = NO +LATEX_HIDE_INDICES = NO +#--------------------------------------------------------------------------- +# configuration options related to the RTF output +#--------------------------------------------------------------------------- +GENERATE_RTF = NO +RTF_OUTPUT = rtf +COMPACT_RTF = NO +RTF_HYPERLINKS = NO +RTF_STYLESHEET_FILE = +RTF_EXTENSIONS_FILE = +#--------------------------------------------------------------------------- +# configuration options related to the man page output +#--------------------------------------------------------------------------- +GENERATE_MAN = NO +MAN_OUTPUT = man +MAN_EXTENSION = .3 +MAN_LINKS = NO +#--------------------------------------------------------------------------- +# configuration options related to the XML output +#--------------------------------------------------------------------------- +GENERATE_XML = NO +XML_OUTPUT = xml +XML_SCHEMA = +XML_DTD = +XML_PROGRAMLISTING = YES +#--------------------------------------------------------------------------- +# configuration options for the AutoGen Definitions output +#--------------------------------------------------------------------------- +GENERATE_AUTOGEN_DEF = NO +#--------------------------------------------------------------------------- +# configuration options related to the Perl module output +#--------------------------------------------------------------------------- +GENERATE_PERLMOD = NO +PERLMOD_LATEX = NO +PERLMOD_PRETTY = YES +PERLMOD_MAKEVAR_PREFIX = +#--------------------------------------------------------------------------- +# Configuration options related to the preprocessor +#--------------------------------------------------------------------------- +ENABLE_PREPROCESSING = YES +MACRO_EXPANSION = YES +EXPAND_ONLY_PREDEF = YES +SEARCH_INCLUDES = YES +INCLUDE_PATH = +INCLUDE_FILE_PATTERNS = +PREDEFINED = "YAML_DECLARE(type)=type" +EXPAND_AS_DEFINED = +SKIP_FUNCTION_MACROS = YES +#--------------------------------------------------------------------------- +# Configuration::additions related to external references +#--------------------------------------------------------------------------- +TAGFILES = +GENERATE_TAGFILE = +ALLEXTERNALS = NO +EXTERNAL_GROUPS = YES +PERL_PATH = /usr/bin/perl +#--------------------------------------------------------------------------- +# Configuration options related to the dot tool +#--------------------------------------------------------------------------- +CLASS_DIAGRAMS = NO +HIDE_UNDOC_RELATIONS = YES +HAVE_DOT = NO +CLASS_GRAPH = YES +COLLABORATION_GRAPH = YES +GROUP_GRAPHS = YES +UML_LOOK = NO +TEMPLATE_RELATIONS = NO +INCLUDE_GRAPH = YES +INCLUDED_BY_GRAPH = YES +CALL_GRAPH = NO +GRAPHICAL_HIERARCHY = YES +DIRECTORY_GRAPH = YES +DOT_IMAGE_FORMAT = png +DOT_PATH = +DOTFILE_DIRS = +MAX_DOT_GRAPH_WIDTH = 1024 +MAX_DOT_GRAPH_HEIGHT = 1024 +MAX_DOT_GRAPH_DEPTH = 0 +DOT_TRANSPARENT = NO +DOT_MULTI_TARGETS = NO +GENERATE_LEGEND = YES +DOT_CLEANUP = YES +#--------------------------------------------------------------------------- +# Configuration::additions related to the search engine +#--------------------------------------------------------------------------- +SEARCHENGINE = NO diff --git a/web/server/h2o/libh2o/deps/yaml/doc/html/annotated.html b/web/server/h2o/libh2o/deps/yaml/doc/html/annotated.html new file mode 100644 index 00000000..443fc0ef --- /dev/null +++ b/web/server/h2o/libh2o/deps/yaml/doc/html/annotated.html @@ -0,0 +1,83 @@ + + + + + +yaml: Data Structures + + + + + + + + + +
+
+
Data Structures
+
+
+
Here are the data structures with brief descriptions:
+ + + + + + + + + + + + +
yaml_alias_data_sThis structure holds aliases data
yaml_document_sThe document structure
yaml_emitter_sThe emitter structure
yaml_event_sThe event structure
yaml_mark_sThe pointer position
yaml_node_pair_sAn element of a mapping node
yaml_node_sThe node structure
yaml_parser_sThe parser structure
yaml_simple_key_sThis structure holds information about a potential simple key
yaml_tag_directive_sThe tag directive data
yaml_token_sThe token structure
yaml_version_directive_sThe version directive data
+
+ + + + + + diff --git a/web/server/h2o/libh2o/deps/yaml/doc/html/bc_s.png b/web/server/h2o/libh2o/deps/yaml/doc/html/bc_s.png new file mode 100644 index 00000000..e4018628 Binary files /dev/null and b/web/server/h2o/libh2o/deps/yaml/doc/html/bc_s.png differ diff --git a/web/server/h2o/libh2o/deps/yaml/doc/html/classes.html b/web/server/h2o/libh2o/deps/yaml/doc/html/classes.html new file mode 100644 index 00000000..141ce138 --- /dev/null +++ b/web/server/h2o/libh2o/deps/yaml/doc/html/classes.html @@ -0,0 +1,78 @@ + + + + + +yaml: Data Structure Index + + + + + + + + +
+ + +
+ + + + + + + + + + + +
+
yaml +  0.1.6 +
+ +
+
+ + + + +
+
+
+
Data Structure Index
+
+ + + + + + + diff --git a/web/server/h2o/libh2o/deps/yaml/doc/html/closed.png b/web/server/h2o/libh2o/deps/yaml/doc/html/closed.png new file mode 100644 index 00000000..b7d4bd9f Binary files /dev/null and b/web/server/h2o/libh2o/deps/yaml/doc/html/closed.png differ diff --git a/web/server/h2o/libh2o/deps/yaml/doc/html/doxygen.css b/web/server/h2o/libh2o/deps/yaml/doc/html/doxygen.css new file mode 100644 index 00000000..cee0d06b --- /dev/null +++ b/web/server/h2o/libh2o/deps/yaml/doc/html/doxygen.css @@ -0,0 +1,949 @@ +/* The standard CSS for doxygen */ + +body, table, div, p, dl { + font-family: Lucida Grande, Verdana, Geneva, Arial, sans-serif; + font-size: 13px; + line-height: 1.3; +} + +/* @group Heading Levels */ + +h1 { + font-size: 150%; +} + +.title { + font-size: 150%; + font-weight: bold; + margin: 10px 2px; +} + +h2 { + font-size: 120%; +} + +h3 { + font-size: 100%; +} + +dt { + font-weight: bold; +} + +div.multicol { + -moz-column-gap: 1em; + -webkit-column-gap: 1em; + -moz-column-count: 3; + -webkit-column-count: 3; +} + +p.startli, p.startdd, p.starttd { + margin-top: 2px; +} + +p.endli { + margin-bottom: 0px; +} + +p.enddd { + margin-bottom: 4px; +} + +p.endtd { + margin-bottom: 2px; +} + +/* @end */ + +caption { + font-weight: bold; +} + +span.legend { + font-size: 70%; + text-align: center; +} + +h3.version { + font-size: 90%; + text-align: center; +} + +div.qindex, div.navtab{ + background-color: #EBEFF6; + border: 1px solid #A3B4D7; + text-align: center; +} + +div.qindex, div.navpath { + width: 100%; + line-height: 140%; +} + +div.navtab { + margin-right: 15px; +} + +/* @group Link Styling */ + +a { + color: #3D578C; + font-weight: normal; + text-decoration: none; +} + +.contents a:visited { + color: #4665A2; +} + +a:hover { + text-decoration: underline; +} + +a.qindex { + font-weight: bold; +} + +a.qindexHL { + font-weight: bold; + background-color: #9CAFD4; + color: #ffffff; + border: 1px double #869DCA; +} + +.contents a.qindexHL:visited { + color: #ffffff; +} + +a.el { + font-weight: bold; +} + +a.elRef { +} + +a.code, a.code:visited { + color: #4665A2; +} + +a.codeRef, a.codeRef:visited { + color: #4665A2; +} + +/* @end */ + +dl.el { + margin-left: -1cm; +} + +.fragment { + font-family: monospace, fixed; + font-size: 105%; +} + +pre.fragment { + border: 1px solid #C4CFE5; + background-color: #FBFCFD; + padding: 4px 6px; + margin: 4px 8px 4px 2px; + overflow: auto; + word-wrap: break-word; + font-size: 9pt; + line-height: 125%; +} + +div.ah { + background-color: black; + font-weight: bold; + color: #ffffff; + margin-bottom: 3px; + margin-top: 3px; + padding: 0.2em; + border: solid thin #333; + border-radius: 0.5em; + -webkit-border-radius: .5em; + -moz-border-radius: .5em; + box-shadow: 2px 2px 3px #999; + -webkit-box-shadow: 2px 2px 3px #999; + -moz-box-shadow: rgba(0, 0, 0, 0.15) 2px 2px 2px; + background-image: -webkit-gradient(linear, left top, left bottom, from(#eee), to(#000),color-stop(0.3, #444)); + background-image: -moz-linear-gradient(center top, #eee 0%, #444 40%, #000); +} + +div.groupHeader { + margin-left: 16px; + margin-top: 12px; + font-weight: bold; +} + +div.groupText { + margin-left: 16px; + font-style: italic; +} + +body { + background-color: white; + color: black; + margin: 0; +} + +div.contents { + margin-top: 10px; + margin-left: 8px; + margin-right: 8px; +} + +td.indexkey { + background-color: #EBEFF6; + font-weight: bold; + border: 1px solid #C4CFE5; + margin: 2px 0px 2px 0; + padding: 2px 10px; + white-space: nowrap; + vertical-align: top; +} + +td.indexvalue { + background-color: #EBEFF6; + border: 1px solid #C4CFE5; + padding: 2px 10px; + margin: 2px 0px; +} + +tr.memlist { + background-color: #EEF1F7; +} + +p.formulaDsp { + text-align: center; +} + +img.formulaDsp { + +} + +img.formulaInl { + vertical-align: middle; +} + +div.center { + text-align: center; + margin-top: 0px; + margin-bottom: 0px; + padding: 0px; +} + +div.center img { + border: 0px; +} + +address.footer { + text-align: right; + padding-right: 12px; +} + +img.footer { + border: 0px; + vertical-align: middle; +} + +/* @group Code Colorization */ + +span.keyword { + color: #008000 +} + +span.keywordtype { + color: #604020 +} + +span.keywordflow { + color: #e08000 +} + +span.comment { + color: #800000 +} + +span.preprocessor { + color: #806020 +} + +span.stringliteral { + color: #002080 +} + +span.charliteral { + color: #008080 +} + +span.vhdldigit { + color: #ff00ff +} + +span.vhdlchar { + color: #000000 +} + +span.vhdlkeyword { + color: #700070 +} + +span.vhdllogic { + color: #ff0000 +} + +/* @end */ + +/* +.search { + color: #003399; + font-weight: bold; +} + +form.search { + margin-bottom: 0px; + margin-top: 0px; +} + +input.search { + font-size: 75%; + color: #000080; + font-weight: normal; + background-color: #e8eef2; +} +*/ + +td.tiny { + font-size: 75%; +} + +.dirtab { + padding: 4px; + border-collapse: collapse; + border: 1px solid #A3B4D7; +} + +th.dirtab { + background: #EBEFF6; + font-weight: bold; +} + +hr { + height: 0px; + border: none; + border-top: 1px solid #4A6AAA; +} + +hr.footer { + height: 1px; +} + +/* @group Member Descriptions */ + +table.memberdecls { + border-spacing: 0px; + padding: 0px; +} + +.mdescLeft, .mdescRight, +.memItemLeft, .memItemRight, +.memTemplItemLeft, .memTemplItemRight, .memTemplParams { + background-color: #F9FAFC; + border: none; + margin: 4px; + padding: 1px 0 0 8px; +} + +.mdescLeft, .mdescRight { + padding: 0px 8px 4px 8px; + color: #555; +} + +.memItemLeft, .memItemRight, .memTemplParams { + border-top: 1px solid #C4CFE5; +} + +.memItemLeft, .memTemplItemLeft { + white-space: nowrap; +} + +.memItemRight { + width: 100%; +} + +.memTemplParams { + color: #4665A2; + white-space: nowrap; +} + +/* @end */ + +/* @group Member Details */ + +/* Styles for detailed member documentation */ + +.memtemplate { + font-size: 80%; + color: #4665A2; + font-weight: normal; + margin-left: 9px; +} + +.memnav { + background-color: #EBEFF6; + border: 1px solid #A3B4D7; + text-align: center; + margin: 2px; + margin-right: 15px; + padding: 2px; +} + +.mempage { + width: 100%; +} + +.memitem { + padding: 0; + margin-bottom: 10px; + margin-right: 5px; +} + +.memname { + white-space: nowrap; + font-weight: bold; + margin-left: 6px; +} + +.memproto, dl.reflist dt { + border-top: 1px solid #A8B8D9; + border-left: 1px solid #A8B8D9; + border-right: 1px solid #A8B8D9; + padding: 6px 0px 6px 0px; + color: #253555; + font-weight: bold; + text-shadow: 0px 1px 1px rgba(255, 255, 255, 0.9); + /* opera specific markup */ + box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15); + border-top-right-radius: 8px; + border-top-left-radius: 8px; + /* firefox specific markup */ + -moz-box-shadow: rgba(0, 0, 0, 0.15) 5px 5px 5px; + -moz-border-radius-topright: 8px; + -moz-border-radius-topleft: 8px; + /* webkit specific markup */ + -webkit-box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15); + -webkit-border-top-right-radius: 8px; + -webkit-border-top-left-radius: 8px; + background-image:url('nav_f.png'); + background-repeat:repeat-x; + background-color: #E2E8F2; + +} + +.memdoc, dl.reflist dd { + border-bottom: 1px solid #A8B8D9; + border-left: 1px solid #A8B8D9; + border-right: 1px solid #A8B8D9; + padding: 2px 5px; + background-color: #FBFCFD; + border-top-width: 0; + /* opera specific markup */ + border-bottom-left-radius: 8px; + border-bottom-right-radius: 8px; + box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15); + /* firefox specific markup */ + -moz-border-radius-bottomleft: 8px; + -moz-border-radius-bottomright: 8px; + -moz-box-shadow: rgba(0, 0, 0, 0.15) 5px 5px 5px; + background-image: -moz-linear-gradient(center top, #FFFFFF 0%, #FFFFFF 60%, #F7F8FB 95%, #EEF1F7); + /* webkit specific markup */ + -webkit-border-bottom-left-radius: 8px; + -webkit-border-bottom-right-radius: 8px; + -webkit-box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15); + background-image: -webkit-gradient(linear,center top,center bottom,from(#FFFFFF), color-stop(0.6,#FFFFFF), color-stop(0.60,#FFFFFF), color-stop(0.95,#F7F8FB), to(#EEF1F7)); +} + +dl.reflist dt { + padding: 5px; +} + +dl.reflist dd { + margin: 0px 0px 10px 0px; + padding: 5px; +} + +.paramkey { + text-align: right; +} + +.paramtype { + white-space: nowrap; +} + +.paramname { + color: #602020; + white-space: nowrap; +} +.paramname em { + font-style: normal; +} + +.params, .retval, .exception, .tparams { + border-spacing: 6px 2px; +} + +.params .paramname, .retval .paramname { + font-weight: bold; + vertical-align: top; +} + +.params .paramtype { + font-style: italic; + vertical-align: top; +} + +.params .paramdir { + font-family: "courier new",courier,monospace; + vertical-align: top; +} + + + + +/* @end */ + +/* @group Directory (tree) */ + +/* for the tree view */ + +.ftvtree { + font-family: sans-serif; + margin: 0px; +} + +/* these are for tree view when used as main index */ + +.directory { + font-size: 9pt; + font-weight: bold; + margin: 5px; +} + +.directory h3 { + margin: 0px; + margin-top: 1em; + font-size: 11pt; +} + +/* +The following two styles can be used to replace the root node title +with an image of your choice. Simply uncomment the next two styles, +specify the name of your image and be sure to set 'height' to the +proper pixel height of your image. +*/ + +/* +.directory h3.swap { + height: 61px; + background-repeat: no-repeat; + background-image: url("yourimage.gif"); +} +.directory h3.swap span { + display: none; +} +*/ + +.directory > h3 { + margin-top: 0; +} + +.directory p { + margin: 0px; + white-space: nowrap; +} + +.directory div { + display: none; + margin: 0px; +} + +.directory img { + vertical-align: -30%; +} + +/* these are for tree view when not used as main index */ + +.directory-alt { + font-size: 100%; + font-weight: bold; +} + +.directory-alt h3 { + margin: 0px; + margin-top: 1em; + font-size: 11pt; +} + +.directory-alt > h3 { + margin-top: 0; +} + +.directory-alt p { + margin: 0px; + white-space: nowrap; +} + +.directory-alt div { + display: none; + margin: 0px; +} + +.directory-alt img { + vertical-align: -30%; +} + +/* @end */ + +div.dynheader { + margin-top: 8px; +} + +address { + font-style: normal; + color: #2A3D61; +} + +table.doxtable { + border-collapse:collapse; +} + +table.doxtable td, table.doxtable th { + border: 1px solid #2D4068; + padding: 3px 7px 2px; +} + +table.doxtable th { + background-color: #374F7F; + color: #FFFFFF; + font-size: 110%; + padding-bottom: 4px; + padding-top: 5px; + text-align:left; +} + +table.fieldtable { + width: 100%; + margin-bottom: 10px; + border: 1px solid #A8B8D9; + border-spacing: 0px; + -moz-border-radius: 4px; + -webkit-border-radius: 4px; + border-radius: 4px; + -moz-box-shadow: rgba(0, 0, 0, 0.15) 2px 2px 2px; + -webkit-box-shadow: 2px 2px 2px rgba(0, 0, 0, 0.15); + box-shadow: 2px 2px 2px rgba(0, 0, 0, 0.15); +} + +.fieldtable td, .fieldtable th { + padding: 3px 7px 2px; +} + +.fieldtable td.fieldtype, .fieldtable td.fieldname { + white-space: nowrap; + border-right: 1px solid #A8B8D9; + border-bottom: 1px solid #A8B8D9; + vertical-align: top; +} + +.fieldtable td.fielddoc { + border-bottom: 1px solid #A8B8D9; + width: 100%; +} + +.fieldtable tr:last-child td { + border-bottom: none; +} + +.fieldtable th { + background-image:url('nav_f.png'); + background-repeat:repeat-x; + background-color: #E2E8F2; + font-size: 90%; + color: #253555; + padding-bottom: 4px; + padding-top: 5px; + text-align:left; + -moz-border-radius-topleft: 4px; + -moz-border-radius-topright: 4px; + -webkit-border-top-left-radius: 4px; + -webkit-border-top-right-radius: 4px; + border-top-left-radius: 4px; + border-top-right-radius: 4px; + border-bottom: 1px solid #A8B8D9; +} + + +.tabsearch { + top: 0px; + left: 10px; + height: 36px; + background-image: url('tab_b.png'); + z-index: 101; + overflow: hidden; + font-size: 13px; +} + +.navpath ul +{ + font-size: 11px; + background-image:url('tab_b.png'); + background-repeat:repeat-x; + height:30px; + line-height:30px; + color:#8AA0CC; + border:solid 1px #C2CDE4; + overflow:hidden; + margin:0px; + padding:0px; +} + +.navpath li +{ + list-style-type:none; + float:left; + padding-left:10px; + padding-right:15px; + background-image:url('bc_s.png'); + background-repeat:no-repeat; + background-position:right; + color:#364D7C; +} + +.navpath li.navelem a +{ + height:32px; + display:block; + text-decoration: none; + outline: none; +} + +.navpath li.navelem a:hover +{ + color:#6884BD; +} + +.navpath li.footer +{ + list-style-type:none; + float:right; + padding-left:10px; + padding-right:15px; + background-image:none; + background-repeat:no-repeat; + background-position:right; + color:#364D7C; + font-size: 8pt; +} + + +div.summary +{ + float: right; + font-size: 8pt; + padding-right: 5px; + width: 50%; + text-align: right; +} + +div.summary a +{ + white-space: nowrap; +} + +div.ingroups +{ + margin-left: 5px; + font-size: 8pt; + padding-left: 5px; + width: 50%; + text-align: left; +} + +div.ingroups a +{ + white-space: nowrap; +} + +div.header +{ + background-image:url('nav_h.png'); + background-repeat:repeat-x; + background-color: #F9FAFC; + margin: 0px; + border-bottom: 1px solid #C4CFE5; +} + +div.headertitle +{ + padding: 5px 5px 5px 7px; +} + +dl +{ + padding: 0 0 0 10px; +} + +dl.note, dl.warning, dl.attention, dl.pre, dl.post, dl.invariant, dl.deprecated, dl.todo, dl.test, dl.bug +{ + border-left:4px solid; + padding: 0 0 0 6px; +} + +dl.note +{ + border-color: #D0C000; +} + +dl.warning, dl.attention +{ + border-color: #FF0000; +} + +dl.pre, dl.post, dl.invariant +{ + border-color: #00D000; +} + +dl.deprecated +{ + border-color: #505050; +} + +dl.todo +{ + border-color: #00C0E0; +} + +dl.test +{ + border-color: #3030E0; +} + +dl.bug +{ + border-color: #C08050; +} + +#projectlogo +{ + text-align: center; + vertical-align: bottom; + border-collapse: separate; +} + +#projectlogo img +{ + border: 0px none; +} + +#projectname +{ + font: 300% Tahoma, Arial,sans-serif; + margin: 0px; + padding: 2px 0px; +} + +#projectbrief +{ + font: 120% Tahoma, Arial,sans-serif; + margin: 0px; + padding: 0px; +} + +#projectnumber +{ + font: 50% Tahoma, Arial,sans-serif; + margin: 0px; + padding: 0px; +} + +#titlearea +{ + padding: 0px; + margin: 0px; + width: 100%; + border-bottom: 1px solid #5373B4; +} + +.image +{ + text-align: center; +} + +.dotgraph +{ + text-align: center; +} + +.mscgraph +{ + text-align: center; +} + +.caption +{ + font-weight: bold; +} + +div.zoom +{ + border: 1px solid #90A5CE; +} + +dl.citelist { + margin-bottom:50px; +} + +dl.citelist dt { + color:#334975; + float:left; + font-weight:bold; + margin-right:10px; + padding:5px; +} + +dl.citelist dd { + margin:2px 0; + padding:5px 0; +} + +@media print +{ + #top { display: none; } + #side-nav { display: none; } + #nav-path { display: none; } + body { overflow:visible; } + h1, h2, h3, h4, h5, h6 { page-break-after: avoid; } + .summary { display: none; } + .memitem { page-break-inside: avoid; } + #doc-content + { + margin-left:0 !important; + height:auto !important; + width:auto !important; + overflow:inherit; + display:inline; + } + pre.fragment + { + overflow: visible; + text-wrap: unrestricted; + white-space: -moz-pre-wrap; /* Moz */ + white-space: -pre-wrap; /* Opera 4-6 */ + white-space: -o-pre-wrap; /* Opera 7 */ + white-space: pre-wrap; /* CSS3 */ + word-wrap: break-word; /* IE 5.5+ */ + } +} + diff --git a/web/server/h2o/libh2o/deps/yaml/doc/html/doxygen.png b/web/server/h2o/libh2o/deps/yaml/doc/html/doxygen.png new file mode 100644 index 00000000..635ed52f Binary files /dev/null and b/web/server/h2o/libh2o/deps/yaml/doc/html/doxygen.png differ diff --git a/web/server/h2o/libh2o/deps/yaml/doc/html/files.html b/web/server/h2o/libh2o/deps/yaml/doc/html/files.html new file mode 100644 index 00000000..d4932fe3 --- /dev/null +++ b/web/server/h2o/libh2o/deps/yaml/doc/html/files.html @@ -0,0 +1,72 @@ + + + + + +yaml: File List + + + + + + + + +
+ + +
+ + + + + + + + + + + +
+
yaml +  0.1.6 +
+ +
+
+ + + + +
+
+
+
File List
+
+
+
Here is a list of all documented files with brief descriptions:
+ +
yaml.hPublic interface for libyaml
+
+ + + + + + diff --git a/web/server/h2o/libh2o/deps/yaml/doc/html/functions.html b/web/server/h2o/libh2o/deps/yaml/doc/html/functions.html new file mode 100644 index 00000000..a483a215 --- /dev/null +++ b/web/server/h2o/libh2o/deps/yaml/doc/html/functions.html @@ -0,0 +1,123 @@ + + + + + +yaml: Data Fields + + + + + + + + +
+ + +
+ + + + + + + + + + + +
+
yaml +  0.1.6 +
+ +
+
+ + + + + + +
+
+
Here is a list of all documented struct and union fields with links to the struct/union documentation for each field:
+ +

- a -

+
+ + + + + + diff --git a/web/server/h2o/libh2o/deps/yaml/doc/html/functions_0x62.html b/web/server/h2o/libh2o/deps/yaml/doc/html/functions_0x62.html new file mode 100644 index 00000000..08dec05f --- /dev/null +++ b/web/server/h2o/libh2o/deps/yaml/doc/html/functions_0x62.html @@ -0,0 +1,116 @@ + + + + + +yaml: Data Fields + + + + + + + + +
+ + +
+ + + + + + + + + + + +
+
yaml +  0.1.6 +
+ +
+
+ + + + + + +
+
+
Here is a list of all documented struct and union fields with links to the struct/union documentation for each field:
+ +

- b -

+
+ + + + + + diff --git a/web/server/h2o/libh2o/deps/yaml/doc/html/functions_0x63.html b/web/server/h2o/libh2o/deps/yaml/doc/html/functions_0x63.html new file mode 100644 index 00000000..a18cd0df --- /dev/null +++ b/web/server/h2o/libh2o/deps/yaml/doc/html/functions_0x63.html @@ -0,0 +1,119 @@ + + + + + +yaml: Data Fields + + + + + + + + +
+ + +
+ + + + + + + + + + + +
+
yaml +  0.1.6 +
+ +
+
+ + + + + + +
+
+
Here is a list of all documented struct and union fields with links to the struct/union documentation for each field:
+ +

- c -

+
+ + + + + + diff --git a/web/server/h2o/libh2o/deps/yaml/doc/html/functions_0x64.html b/web/server/h2o/libh2o/deps/yaml/doc/html/functions_0x64.html new file mode 100644 index 00000000..b72ca867 --- /dev/null +++ b/web/server/h2o/libh2o/deps/yaml/doc/html/functions_0x64.html @@ -0,0 +1,115 @@ + + + + + +yaml: Data Fields + + + + + + + + +
+ + +
+ + + + + + + + + + + +
+
yaml +  0.1.6 +
+ +
+
+ + + + + + +
+
+
Here is a list of all documented struct and union fields with links to the struct/union documentation for each field:
+ +

- d -

+
+ + + + + + diff --git a/web/server/h2o/libh2o/deps/yaml/doc/html/functions_0x65.html b/web/server/h2o/libh2o/deps/yaml/doc/html/functions_0x65.html new file mode 100644 index 00000000..1bf84e6c --- /dev/null +++ b/web/server/h2o/libh2o/deps/yaml/doc/html/functions_0x65.html @@ -0,0 +1,142 @@ + + + + + +yaml: Data Fields + + + + + + + + +
+ + +
+ + + + + + + + + + + +
+
yaml +  0.1.6 +
+ +
+
+ + + + + + +
+
+
Here is a list of all documented struct and union fields with links to the struct/union documentation for each field:
+ +

- e -

+
+ + + + + + diff --git a/web/server/h2o/libh2o/deps/yaml/doc/html/functions_0x66.html b/web/server/h2o/libh2o/deps/yaml/doc/html/functions_0x66.html new file mode 100644 index 00000000..d023a76f --- /dev/null +++ b/web/server/h2o/libh2o/deps/yaml/doc/html/functions_0x66.html @@ -0,0 +1,111 @@ + + + + + +yaml: Data Fields + + + + + + + + +
+ + +
+ + + + + + + + + + + +
+
yaml +  0.1.6 +
+ +
+
+ + + + + + +
+
+
Here is a list of all documented struct and union fields with links to the struct/union documentation for each field:
+ +

- f -

+
+ + + + + + diff --git a/web/server/h2o/libh2o/deps/yaml/doc/html/functions_0x68.html b/web/server/h2o/libh2o/deps/yaml/doc/html/functions_0x68.html new file mode 100644 index 00000000..32ea5772 --- /dev/null +++ b/web/server/h2o/libh2o/deps/yaml/doc/html/functions_0x68.html @@ -0,0 +1,112 @@ + + + + + +yaml: Data Fields + + + + + + + + +
+ + +
+ + + + + + + + + + + +
+
yaml +  0.1.6 +
+ +
+
+ + + + + + +
+
+
Here is a list of all documented struct and union fields with links to the struct/union documentation for each field:
+ +

- h -

+
+ + + + + + diff --git a/web/server/h2o/libh2o/deps/yaml/doc/html/functions_0x69.html b/web/server/h2o/libh2o/deps/yaml/doc/html/functions_0x69.html new file mode 100644 index 00000000..32adc819 --- /dev/null +++ b/web/server/h2o/libh2o/deps/yaml/doc/html/functions_0x69.html @@ -0,0 +1,124 @@ + + + + + +yaml: Data Fields + + + + + + + + +
+ + +
+ + + + + + + + + + + +
+
yaml +  0.1.6 +
+ +
+
+ + + + + + +
+
+
Here is a list of all documented struct and union fields with links to the struct/union documentation for each field:
+ +

- i -

+
+ + + + + + diff --git a/web/server/h2o/libh2o/deps/yaml/doc/html/functions_0x6b.html b/web/server/h2o/libh2o/deps/yaml/doc/html/functions_0x6b.html new file mode 100644 index 00000000..18ce014a --- /dev/null +++ b/web/server/h2o/libh2o/deps/yaml/doc/html/functions_0x6b.html @@ -0,0 +1,103 @@ + + + + + +yaml: Data Fields + + + + + + + + +
+ + +
+ + + + + + + + + + + +
+
yaml +  0.1.6 +
+ +
+
+ + + + + + +
+
+
Here is a list of all documented struct and union fields with links to the struct/union documentation for each field:
+ +

- k -

+
+ + + + + + diff --git a/web/server/h2o/libh2o/deps/yaml/doc/html/functions_0x6c.html b/web/server/h2o/libh2o/deps/yaml/doc/html/functions_0x6c.html new file mode 100644 index 00000000..76a8ec7b --- /dev/null +++ b/web/server/h2o/libh2o/deps/yaml/doc/html/functions_0x6c.html @@ -0,0 +1,120 @@ + + + + + +yaml: Data Fields + + + + + + + + +
+ + +
+ + + + + + + + + + + +
+
yaml +  0.1.6 +
+ +
+
+ + + + + + +
+
+
Here is a list of all documented struct and union fields with links to the struct/union documentation for each field:
+ +

- l -

+
+ + + + + + diff --git a/web/server/h2o/libh2o/deps/yaml/doc/html/functions_0x6d.html b/web/server/h2o/libh2o/deps/yaml/doc/html/functions_0x6d.html new file mode 100644 index 00000000..7de95aa2 --- /dev/null +++ b/web/server/h2o/libh2o/deps/yaml/doc/html/functions_0x6d.html @@ -0,0 +1,128 @@ + + + + + +yaml: Data Fields + + + + + + + + +
+ + +
+ + + + + + + + + + + +
+
yaml +  0.1.6 +
+ +
+
+ + + + + + +
+
+
Here is a list of all documented struct and union fields with links to the struct/union documentation for each field:
+ +

- m -

+
+ + + + + + diff --git a/web/server/h2o/libh2o/deps/yaml/doc/html/functions_0x6e.html b/web/server/h2o/libh2o/deps/yaml/doc/html/functions_0x6e.html new file mode 100644 index 00000000..b17d502f --- /dev/null +++ b/web/server/h2o/libh2o/deps/yaml/doc/html/functions_0x6e.html @@ -0,0 +1,103 @@ + + + + + +yaml: Data Fields + + + + + + + + +
+ + +
+ + + + + + + + + + + +
+
yaml +  0.1.6 +
+ +
+
+ + + + + + +
+
+
Here is a list of all documented struct and union fields with links to the struct/union documentation for each field:
+ +

- n -

+
+ + + + + + diff --git a/web/server/h2o/libh2o/deps/yaml/doc/html/functions_0x6f.html b/web/server/h2o/libh2o/deps/yaml/doc/html/functions_0x6f.html new file mode 100644 index 00000000..4a01fe4b --- /dev/null +++ b/web/server/h2o/libh2o/deps/yaml/doc/html/functions_0x6f.html @@ -0,0 +1,112 @@ + + + + + +yaml: Data Fields + + + + + + + + +
+ + +
+ + + + + + + + + + + +
+
yaml +  0.1.6 +
+ +
+
+ + + + + + +
+
+
Here is a list of all documented struct and union fields with links to the struct/union documentation for each field:
+ +

- o -

+
+ + + + + + diff --git a/web/server/h2o/libh2o/deps/yaml/doc/html/functions_0x70.html b/web/server/h2o/libh2o/deps/yaml/doc/html/functions_0x70.html new file mode 100644 index 00000000..9b50a480 --- /dev/null +++ b/web/server/h2o/libh2o/deps/yaml/doc/html/functions_0x70.html @@ -0,0 +1,132 @@ + + + + + +yaml: Data Fields + + + + + + + + +
+ + +
+ + + + + + + + + + + +
+
yaml +  0.1.6 +
+ +
+
+ + + + + + +
+
+
Here is a list of all documented struct and union fields with links to the struct/union documentation for each field:
+ +

- p -

+
+ + + + + + diff --git a/web/server/h2o/libh2o/deps/yaml/doc/html/functions_0x71.html b/web/server/h2o/libh2o/deps/yaml/doc/html/functions_0x71.html new file mode 100644 index 00000000..f6f69536 --- /dev/null +++ b/web/server/h2o/libh2o/deps/yaml/doc/html/functions_0x71.html @@ -0,0 +1,103 @@ + + + + + +yaml: Data Fields + + + + + + + + +
+ + +
+ + + + + + + + + + + +
+
yaml +  0.1.6 +
+ +
+
+ + + + + + +
+
+
Here is a list of all documented struct and union fields with links to the struct/union documentation for each field:
+ +

- q -

+
+ + + + + + diff --git a/web/server/h2o/libh2o/deps/yaml/doc/html/functions_0x72.html b/web/server/h2o/libh2o/deps/yaml/doc/html/functions_0x72.html new file mode 100644 index 00000000..35a3919c --- /dev/null +++ b/web/server/h2o/libh2o/deps/yaml/doc/html/functions_0x72.html @@ -0,0 +1,119 @@ + + + + + +yaml: Data Fields + + + + + + + + +
+ + +
+ + + + + + + + + + + +
+
yaml +  0.1.6 +
+ +
+
+ + + + + + +
+
+
Here is a list of all documented struct and union fields with links to the struct/union documentation for each field:
+ +

- r -

+
+ + + + + + diff --git a/web/server/h2o/libh2o/deps/yaml/doc/html/functions_0x73.html b/web/server/h2o/libh2o/deps/yaml/doc/html/functions_0x73.html new file mode 100644 index 00000000..e59762b0 --- /dev/null +++ b/web/server/h2o/libh2o/deps/yaml/doc/html/functions_0x73.html @@ -0,0 +1,195 @@ + + + + + +yaml: Data Fields + + + + + + + + +
+ + +
+ + + + + + + + + + + +
+
yaml +  0.1.6 +
+ +
+
+ + + + + + +
+
+
Here is a list of all documented struct and union fields with links to the struct/union documentation for each field:
+ +

- s -

+
+ + + + + + diff --git a/web/server/h2o/libh2o/deps/yaml/doc/html/functions_0x74.html b/web/server/h2o/libh2o/deps/yaml/doc/html/functions_0x74.html new file mode 100644 index 00000000..1130bf4f --- /dev/null +++ b/web/server/h2o/libh2o/deps/yaml/doc/html/functions_0x74.html @@ -0,0 +1,147 @@ + + + + + +yaml: Data Fields + + + + + + + + +
+ + +
+ + + + + + + + + + + +
+
yaml +  0.1.6 +
+ +
+
+ + + + + + +
+
+
Here is a list of all documented struct and union fields with links to the struct/union documentation for each field:
+ +

- t -

+
+ + + + + + diff --git a/web/server/h2o/libh2o/deps/yaml/doc/html/functions_0x75.html b/web/server/h2o/libh2o/deps/yaml/doc/html/functions_0x75.html new file mode 100644 index 00000000..eb44944f --- /dev/null +++ b/web/server/h2o/libh2o/deps/yaml/doc/html/functions_0x75.html @@ -0,0 +1,103 @@ + + + + + +yaml: Data Fields + + + + + + + + +
+ + +
+ + + + + + + + + + + +
+
yaml +  0.1.6 +
+ +
+
+ + + + + + +
+
+
Here is a list of all documented struct and union fields with links to the struct/union documentation for each field:
+ +

- u -

+
+ + + + + + diff --git a/web/server/h2o/libh2o/deps/yaml/doc/html/functions_0x76.html b/web/server/h2o/libh2o/deps/yaml/doc/html/functions_0x76.html new file mode 100644 index 00000000..fabc810c --- /dev/null +++ b/web/server/h2o/libh2o/deps/yaml/doc/html/functions_0x76.html @@ -0,0 +1,112 @@ + + + + + +yaml: Data Fields + + + + + + + + +
+ + +
+ + + + + + + + + + + +
+
yaml +  0.1.6 +
+ +
+
+ + + + + + +
+
+
Here is a list of all documented struct and union fields with links to the struct/union documentation for each field:
+ +

- v -

+
+ + + + + + diff --git a/web/server/h2o/libh2o/deps/yaml/doc/html/functions_0x77.html b/web/server/h2o/libh2o/deps/yaml/doc/html/functions_0x77.html new file mode 100644 index 00000000..36f79ee0 --- /dev/null +++ b/web/server/h2o/libh2o/deps/yaml/doc/html/functions_0x77.html @@ -0,0 +1,109 @@ + + + + + +yaml: Data Fields + + + + + + + + +
+ + +
+ + + + + + + + + + + +
+
yaml +  0.1.6 +
+ +
+
+ + + + + + +
+
+
Here is a list of all documented struct and union fields with links to the struct/union documentation for each field:
+ +

- w -

+
+ + + + + + diff --git a/web/server/h2o/libh2o/deps/yaml/doc/html/functions_vars.html b/web/server/h2o/libh2o/deps/yaml/doc/html/functions_vars.html new file mode 100644 index 00000000..8ca4bf4e --- /dev/null +++ b/web/server/h2o/libh2o/deps/yaml/doc/html/functions_vars.html @@ -0,0 +1,123 @@ + + + + + +yaml: Data Fields - Variables + + + + + + + + +
+ + +
+ + + + + + + + + + + +
+
yaml +  0.1.6 +
+ +
+
+ + + + + + +
+
+  + +

- a -

+
+ + + + + + diff --git a/web/server/h2o/libh2o/deps/yaml/doc/html/functions_vars_0x62.html b/web/server/h2o/libh2o/deps/yaml/doc/html/functions_vars_0x62.html new file mode 100644 index 00000000..ddae96b5 --- /dev/null +++ b/web/server/h2o/libh2o/deps/yaml/doc/html/functions_vars_0x62.html @@ -0,0 +1,116 @@ + + + + + +yaml: Data Fields - Variables + + + + + + + + +
+ + +
+ + + + + + + + + + + +
+
yaml +  0.1.6 +
+ +
+
+ + + + + + +
+
+  + +

- b -

+
+ + + + + + diff --git a/web/server/h2o/libh2o/deps/yaml/doc/html/functions_vars_0x63.html b/web/server/h2o/libh2o/deps/yaml/doc/html/functions_vars_0x63.html new file mode 100644 index 00000000..e09b0ac9 --- /dev/null +++ b/web/server/h2o/libh2o/deps/yaml/doc/html/functions_vars_0x63.html @@ -0,0 +1,119 @@ + + + + + +yaml: Data Fields - Variables + + + + + + + + +
+ + +
+ + + + + + + + + + + +
+
yaml +  0.1.6 +
+ +
+
+ + + + + + +
+
+  + +

- c -

+
+ + + + + + diff --git a/web/server/h2o/libh2o/deps/yaml/doc/html/functions_vars_0x64.html b/web/server/h2o/libh2o/deps/yaml/doc/html/functions_vars_0x64.html new file mode 100644 index 00000000..a20065bd --- /dev/null +++ b/web/server/h2o/libh2o/deps/yaml/doc/html/functions_vars_0x64.html @@ -0,0 +1,115 @@ + + + + + +yaml: Data Fields - Variables + + + + + + + + +
+ + +
+ + + + + + + + + + + +
+
yaml +  0.1.6 +
+ +
+
+ + + + + + +
+
+  + +

- d -

+
+ + + + + + diff --git a/web/server/h2o/libh2o/deps/yaml/doc/html/functions_vars_0x65.html b/web/server/h2o/libh2o/deps/yaml/doc/html/functions_vars_0x65.html new file mode 100644 index 00000000..47c5f73b --- /dev/null +++ b/web/server/h2o/libh2o/deps/yaml/doc/html/functions_vars_0x65.html @@ -0,0 +1,142 @@ + + + + + +yaml: Data Fields - Variables + + + + + + + + +
+ + +
+ + + + + + + + + + + +
+
yaml +  0.1.6 +
+ +
+
+ + + + + + +
+ + + + + + + diff --git a/web/server/h2o/libh2o/deps/yaml/doc/html/functions_vars_0x66.html b/web/server/h2o/libh2o/deps/yaml/doc/html/functions_vars_0x66.html new file mode 100644 index 00000000..b1e1018f --- /dev/null +++ b/web/server/h2o/libh2o/deps/yaml/doc/html/functions_vars_0x66.html @@ -0,0 +1,111 @@ + + + + + +yaml: Data Fields - Variables + + + + + + + + +
+ + +
+ + + + + + + + + + + +
+
yaml +  0.1.6 +
+ +
+
+ + + + + + +
+
+  + +

- f -

+
+ + + + + + diff --git a/web/server/h2o/libh2o/deps/yaml/doc/html/functions_vars_0x68.html b/web/server/h2o/libh2o/deps/yaml/doc/html/functions_vars_0x68.html new file mode 100644 index 00000000..46fa2225 --- /dev/null +++ b/web/server/h2o/libh2o/deps/yaml/doc/html/functions_vars_0x68.html @@ -0,0 +1,112 @@ + + + + + +yaml: Data Fields - Variables + + + + + + + + +
+ + +
+ + + + + + + + + + + +
+
yaml +  0.1.6 +
+ +
+
+ + + + + + +
+
+  + +

- h -

+
+ + + + + + diff --git a/web/server/h2o/libh2o/deps/yaml/doc/html/functions_vars_0x69.html b/web/server/h2o/libh2o/deps/yaml/doc/html/functions_vars_0x69.html new file mode 100644 index 00000000..2550f4ea --- /dev/null +++ b/web/server/h2o/libh2o/deps/yaml/doc/html/functions_vars_0x69.html @@ -0,0 +1,124 @@ + + + + + +yaml: Data Fields - Variables + + + + + + + + +
+ + +
+ + + + + + + + + + + +
+
yaml +  0.1.6 +
+ +
+
+ + + + + + +
+
+  + +

- i -

+
+ + + + + + diff --git a/web/server/h2o/libh2o/deps/yaml/doc/html/functions_vars_0x6b.html b/web/server/h2o/libh2o/deps/yaml/doc/html/functions_vars_0x6b.html new file mode 100644 index 00000000..3e30ecf7 --- /dev/null +++ b/web/server/h2o/libh2o/deps/yaml/doc/html/functions_vars_0x6b.html @@ -0,0 +1,103 @@ + + + + + +yaml: Data Fields - Variables + + + + + + + + +
+ + +
+ + + + + + + + + + + +
+
yaml +  0.1.6 +
+ +
+
+ + + + + + +
+
+  + +

- k -

+
+ + + + + + diff --git a/web/server/h2o/libh2o/deps/yaml/doc/html/functions_vars_0x6c.html b/web/server/h2o/libh2o/deps/yaml/doc/html/functions_vars_0x6c.html new file mode 100644 index 00000000..6cd9218f --- /dev/null +++ b/web/server/h2o/libh2o/deps/yaml/doc/html/functions_vars_0x6c.html @@ -0,0 +1,120 @@ + + + + + +yaml: Data Fields - Variables + + + + + + + + +
+ + +
+ + + + + + + + + + + +
+
yaml +  0.1.6 +
+ +
+
+ + + + + + +
+
+  + +

- l -

+
+ + + + + + diff --git a/web/server/h2o/libh2o/deps/yaml/doc/html/functions_vars_0x6d.html b/web/server/h2o/libh2o/deps/yaml/doc/html/functions_vars_0x6d.html new file mode 100644 index 00000000..27e5150a --- /dev/null +++ b/web/server/h2o/libh2o/deps/yaml/doc/html/functions_vars_0x6d.html @@ -0,0 +1,128 @@ + + + + + +yaml: Data Fields - Variables + + + + + + + + +
+ + +
+ + + + + + + + + + + +
+
yaml +  0.1.6 +
+ +
+
+ + + + + + +
+
+  + +

- m -

+
+ + + + + + diff --git a/web/server/h2o/libh2o/deps/yaml/doc/html/functions_vars_0x6e.html b/web/server/h2o/libh2o/deps/yaml/doc/html/functions_vars_0x6e.html new file mode 100644 index 00000000..036b5b7b --- /dev/null +++ b/web/server/h2o/libh2o/deps/yaml/doc/html/functions_vars_0x6e.html @@ -0,0 +1,103 @@ + + + + + +yaml: Data Fields - Variables + + + + + + + + +
+ + +
+ + + + + + + + + + + +
+
yaml +  0.1.6 +
+ +
+
+ + + + + + +
+
+  + +

- n -

+
+ + + + + + diff --git a/web/server/h2o/libh2o/deps/yaml/doc/html/functions_vars_0x6f.html b/web/server/h2o/libh2o/deps/yaml/doc/html/functions_vars_0x6f.html new file mode 100644 index 00000000..593182a8 --- /dev/null +++ b/web/server/h2o/libh2o/deps/yaml/doc/html/functions_vars_0x6f.html @@ -0,0 +1,112 @@ + + + + + +yaml: Data Fields - Variables + + + + + + + + +
+ + +
+ + + + + + + + + + + +
+
yaml +  0.1.6 +
+ +
+
+ + + + + + +
+
+  + +

- o -

+
+ + + + + + diff --git a/web/server/h2o/libh2o/deps/yaml/doc/html/functions_vars_0x70.html b/web/server/h2o/libh2o/deps/yaml/doc/html/functions_vars_0x70.html new file mode 100644 index 00000000..7cccada7 --- /dev/null +++ b/web/server/h2o/libh2o/deps/yaml/doc/html/functions_vars_0x70.html @@ -0,0 +1,132 @@ + + + + + +yaml: Data Fields - Variables + + + + + + + + +
+ + +
+ + + + + + + + + + + +
+
yaml +  0.1.6 +
+ +
+
+ + + + + + +
+
+  + +

- p -

+
+ + + + + + diff --git a/web/server/h2o/libh2o/deps/yaml/doc/html/functions_vars_0x71.html b/web/server/h2o/libh2o/deps/yaml/doc/html/functions_vars_0x71.html new file mode 100644 index 00000000..a4e9c139 --- /dev/null +++ b/web/server/h2o/libh2o/deps/yaml/doc/html/functions_vars_0x71.html @@ -0,0 +1,103 @@ + + + + + +yaml: Data Fields - Variables + + + + + + + + +
+ + +
+ + + + + + + + + + + +
+
yaml +  0.1.6 +
+ +
+
+ + + + + + +
+
+  + +

- q -

+
+ + + + + + diff --git a/web/server/h2o/libh2o/deps/yaml/doc/html/functions_vars_0x72.html b/web/server/h2o/libh2o/deps/yaml/doc/html/functions_vars_0x72.html new file mode 100644 index 00000000..9f4031a8 --- /dev/null +++ b/web/server/h2o/libh2o/deps/yaml/doc/html/functions_vars_0x72.html @@ -0,0 +1,119 @@ + + + + + +yaml: Data Fields - Variables + + + + + + + + +
+ + +
+ + + + + + + + + + + +
+
yaml +  0.1.6 +
+ +
+
+ + + + + + +
+
+  + +

- r -

+
+ + + + + + diff --git a/web/server/h2o/libh2o/deps/yaml/doc/html/functions_vars_0x73.html b/web/server/h2o/libh2o/deps/yaml/doc/html/functions_vars_0x73.html new file mode 100644 index 00000000..ba310555 --- /dev/null +++ b/web/server/h2o/libh2o/deps/yaml/doc/html/functions_vars_0x73.html @@ -0,0 +1,195 @@ + + + + + +yaml: Data Fields - Variables + + + + + + + + +
+ + +
+ + + + + + + + + + + +
+
yaml +  0.1.6 +
+ +
+
+ + + + + + +
+
+  + +

- s -

+
+ + + + + + diff --git a/web/server/h2o/libh2o/deps/yaml/doc/html/functions_vars_0x74.html b/web/server/h2o/libh2o/deps/yaml/doc/html/functions_vars_0x74.html new file mode 100644 index 00000000..6b665412 --- /dev/null +++ b/web/server/h2o/libh2o/deps/yaml/doc/html/functions_vars_0x74.html @@ -0,0 +1,147 @@ + + + + + +yaml: Data Fields - Variables + + + + + + + + +
+ + +
+ + + + + + + + + + + +
+
yaml +  0.1.6 +
+ +
+
+ + + + + + +
+
+  + +

- t -

+
+ + + + + + diff --git a/web/server/h2o/libh2o/deps/yaml/doc/html/functions_vars_0x75.html b/web/server/h2o/libh2o/deps/yaml/doc/html/functions_vars_0x75.html new file mode 100644 index 00000000..587477ec --- /dev/null +++ b/web/server/h2o/libh2o/deps/yaml/doc/html/functions_vars_0x75.html @@ -0,0 +1,103 @@ + + + + + +yaml: Data Fields - Variables + + + + + + + + +
+ + +
+ + + + + + + + + + + +
+
yaml +  0.1.6 +
+ +
+
+ + + + + + +
+
+  + +

- u -

+
+ + + + + + diff --git a/web/server/h2o/libh2o/deps/yaml/doc/html/functions_vars_0x76.html b/web/server/h2o/libh2o/deps/yaml/doc/html/functions_vars_0x76.html new file mode 100644 index 00000000..eaeae8fa --- /dev/null +++ b/web/server/h2o/libh2o/deps/yaml/doc/html/functions_vars_0x76.html @@ -0,0 +1,112 @@ + + + + + +yaml: Data Fields - Variables + + + + + + + + +
+ + +
+ + + + + + + + + + + +
+
yaml +  0.1.6 +
+ +
+
+ + + + + + +
+
+  + +

- v -

+
+ + + + + + diff --git a/web/server/h2o/libh2o/deps/yaml/doc/html/functions_vars_0x77.html b/web/server/h2o/libh2o/deps/yaml/doc/html/functions_vars_0x77.html new file mode 100644 index 00000000..3d53b285 --- /dev/null +++ b/web/server/h2o/libh2o/deps/yaml/doc/html/functions_vars_0x77.html @@ -0,0 +1,109 @@ + + + + + +yaml: Data Fields - Variables + + + + + + + + +
+ + +
+ + + + + + + + + + + +
+
yaml +  0.1.6 +
+ +
+
+ + + + + + +
+
+  + +

- w -

+
+ + + + + + diff --git a/web/server/h2o/libh2o/deps/yaml/doc/html/globals.html b/web/server/h2o/libh2o/deps/yaml/doc/html/globals.html new file mode 100644 index 00000000..9d9cb845 --- /dev/null +++ b/web/server/h2o/libh2o/deps/yaml/doc/html/globals.html @@ -0,0 +1,699 @@ + + + + + +yaml: Globals + + + + + + + + +
+ + +
+ + + + + + + + + + + +
+
yaml +  0.1.6 +
+ +
+
+ + + + + + +
+
+
Here is a list of all documented functions, variables, defines, enums, and typedefs with links to the documentation:
+ +

- y -

    +
  • yaml_alias_data_t +: yaml.h +
  • +
  • YAML_ALIAS_EVENT +: yaml.h +
  • +
  • yaml_alias_event_initialize() +: yaml.h +
  • +
  • YAML_ALIAS_TOKEN +: yaml.h +
  • +
  • YAML_ANCHOR_TOKEN +: yaml.h +
  • +
  • YAML_ANY_BREAK +: yaml.h +
  • +
  • YAML_ANY_ENCODING +: yaml.h +
  • +
  • YAML_ANY_MAPPING_STYLE +: yaml.h +
  • +
  • YAML_ANY_SCALAR_STYLE +: yaml.h +
  • +
  • YAML_ANY_SEQUENCE_STYLE +: yaml.h +
  • +
  • YAML_BLOCK_END_TOKEN +: yaml.h +
  • +
  • YAML_BLOCK_ENTRY_TOKEN +: yaml.h +
  • +
  • YAML_BLOCK_MAPPING_START_TOKEN +: yaml.h +
  • +
  • YAML_BLOCK_MAPPING_STYLE +: yaml.h +
  • +
  • YAML_BLOCK_SEQUENCE_START_TOKEN +: yaml.h +
  • +
  • YAML_BLOCK_SEQUENCE_STYLE +: yaml.h +
  • +
  • YAML_BOOL_TAG +: yaml.h +
  • +
  • yaml_break_e +: yaml.h +
  • +
  • yaml_break_t +: yaml.h +
  • +
  • yaml_char_t +: yaml.h +
  • +
  • YAML_COMPOSER_ERROR +: yaml.h +
  • +
  • YAML_CR_BREAK +: yaml.h +
  • +
  • YAML_CRLN_BREAK +: yaml.h +
  • +
  • YAML_DECLARE +: yaml.h +
  • +
  • YAML_DEFAULT_MAPPING_TAG +: yaml.h +
  • +
  • YAML_DEFAULT_SCALAR_TAG +: yaml.h +
  • +
  • YAML_DEFAULT_SEQUENCE_TAG +: yaml.h +
  • +
  • yaml_document_add_mapping() +: yaml.h +
  • +
  • yaml_document_add_scalar() +: yaml.h +
  • +
  • yaml_document_add_sequence() +: yaml.h +
  • +
  • yaml_document_append_mapping_pair() +: yaml.h +
  • +
  • yaml_document_append_sequence_item() +: yaml.h +
  • +
  • yaml_document_delete() +: yaml.h +
  • +
  • YAML_DOCUMENT_END_EVENT +: yaml.h +
  • +
  • yaml_document_end_event_initialize() +: yaml.h +
  • +
  • YAML_DOCUMENT_END_TOKEN +: yaml.h +
  • +
  • yaml_document_get_node() +: yaml.h +
  • +
  • yaml_document_get_root_node() +: yaml.h +
  • +
  • yaml_document_initialize() +: yaml.h +
  • +
  • YAML_DOCUMENT_START_EVENT +: yaml.h +
  • +
  • yaml_document_start_event_initialize() +: yaml.h +
  • +
  • YAML_DOCUMENT_START_TOKEN +: yaml.h +
  • +
  • yaml_document_t +: yaml.h +
  • +
  • YAML_DOUBLE_QUOTED_SCALAR_STYLE +: yaml.h +
  • +
  • YAML_EMIT_BLOCK_MAPPING_FIRST_KEY_STATE +: yaml.h +
  • +
  • YAML_EMIT_BLOCK_MAPPING_KEY_STATE +: yaml.h +
  • +
  • YAML_EMIT_BLOCK_MAPPING_SIMPLE_VALUE_STATE +: yaml.h +
  • +
  • YAML_EMIT_BLOCK_MAPPING_VALUE_STATE +: yaml.h +
  • +
  • YAML_EMIT_BLOCK_SEQUENCE_FIRST_ITEM_STATE +: yaml.h +
  • +
  • YAML_EMIT_BLOCK_SEQUENCE_ITEM_STATE +: yaml.h +
  • +
  • YAML_EMIT_DOCUMENT_CONTENT_STATE +: yaml.h +
  • +
  • YAML_EMIT_DOCUMENT_END_STATE +: yaml.h +
  • +
  • YAML_EMIT_DOCUMENT_START_STATE +: yaml.h +
  • +
  • YAML_EMIT_END_STATE +: yaml.h +
  • +
  • YAML_EMIT_FIRST_DOCUMENT_START_STATE +: yaml.h +
  • +
  • YAML_EMIT_FLOW_MAPPING_FIRST_KEY_STATE +: yaml.h +
  • +
  • YAML_EMIT_FLOW_MAPPING_KEY_STATE +: yaml.h +
  • +
  • YAML_EMIT_FLOW_MAPPING_SIMPLE_VALUE_STATE +: yaml.h +
  • +
  • YAML_EMIT_FLOW_MAPPING_VALUE_STATE +: yaml.h +
  • +
  • YAML_EMIT_FLOW_SEQUENCE_FIRST_ITEM_STATE +: yaml.h +
  • +
  • YAML_EMIT_FLOW_SEQUENCE_ITEM_STATE +: yaml.h +
  • +
  • YAML_EMIT_STREAM_START_STATE +: yaml.h +
  • +
  • yaml_emitter_close() +: yaml.h +
  • +
  • yaml_emitter_delete() +: yaml.h +
  • +
  • yaml_emitter_dump() +: yaml.h +
  • +
  • yaml_emitter_emit() +: yaml.h +
  • +
  • YAML_EMITTER_ERROR +: yaml.h +
  • +
  • yaml_emitter_flush() +: yaml.h +
  • +
  • yaml_emitter_initialize() +: yaml.h +
  • +
  • yaml_emitter_open() +: yaml.h +
  • +
  • yaml_emitter_set_break() +: yaml.h +
  • +
  • yaml_emitter_set_canonical() +: yaml.h +
  • +
  • yaml_emitter_set_encoding() +: yaml.h +
  • +
  • yaml_emitter_set_indent() +: yaml.h +
  • +
  • yaml_emitter_set_output() +: yaml.h +
  • +
  • yaml_emitter_set_output_file() +: yaml.h +
  • +
  • yaml_emitter_set_output_string() +: yaml.h +
  • +
  • yaml_emitter_set_unicode() +: yaml.h +
  • +
  • yaml_emitter_set_width() +: yaml.h +
  • +
  • yaml_emitter_state_e +: yaml.h +
  • +
  • yaml_emitter_state_t +: yaml.h +
  • +
  • yaml_emitter_t +: yaml.h +
  • +
  • yaml_encoding_e +: yaml.h +
  • +
  • yaml_encoding_t +: yaml.h +
  • +
  • yaml_error_type_e +: yaml.h +
  • +
  • yaml_error_type_t +: yaml.h +
  • +
  • yaml_event_delete() +: yaml.h +
  • +
  • yaml_event_t +: yaml.h +
  • +
  • yaml_event_type_e +: yaml.h +
  • +
  • yaml_event_type_t +: yaml.h +
  • +
  • YAML_FLOAT_TAG +: yaml.h +
  • +
  • YAML_FLOW_ENTRY_TOKEN +: yaml.h +
  • +
  • YAML_FLOW_MAPPING_END_TOKEN +: yaml.h +
  • +
  • YAML_FLOW_MAPPING_START_TOKEN +: yaml.h +
  • +
  • YAML_FLOW_MAPPING_STYLE +: yaml.h +
  • +
  • YAML_FLOW_SEQUENCE_END_TOKEN +: yaml.h +
  • +
  • YAML_FLOW_SEQUENCE_START_TOKEN +: yaml.h +
  • +
  • YAML_FLOW_SEQUENCE_STYLE +: yaml.h +
  • +
  • YAML_FOLDED_SCALAR_STYLE +: yaml.h +
  • +
  • yaml_get_version() +: yaml.h +
  • +
  • yaml_get_version_string() +: yaml.h +
  • +
  • YAML_INT_TAG +: yaml.h +
  • +
  • YAML_KEY_TOKEN +: yaml.h +
  • +
  • YAML_LITERAL_SCALAR_STYLE +: yaml.h +
  • +
  • YAML_LN_BREAK +: yaml.h +
  • +
  • YAML_MAP_TAG +: yaml.h +
  • +
  • YAML_MAPPING_END_EVENT +: yaml.h +
  • +
  • yaml_mapping_end_event_initialize() +: yaml.h +
  • +
  • YAML_MAPPING_NODE +: yaml.h +
  • +
  • YAML_MAPPING_START_EVENT +: yaml.h +
  • +
  • yaml_mapping_start_event_initialize() +: yaml.h +
  • +
  • yaml_mapping_style_e +: yaml.h +
  • +
  • yaml_mapping_style_t +: yaml.h +
  • +
  • yaml_mark_t +: yaml.h +
  • +
  • YAML_MEMORY_ERROR +: yaml.h +
  • +
  • YAML_NO_ERROR +: yaml.h +
  • +
  • YAML_NO_EVENT +: yaml.h +
  • +
  • YAML_NO_NODE +: yaml.h +
  • +
  • YAML_NO_TOKEN +: yaml.h +
  • +
  • yaml_node_item_t +: yaml.h +
  • +
  • yaml_node_pair_t +: yaml.h +
  • +
  • yaml_node_t +: yaml.h +
  • +
  • yaml_node_type_e +: yaml.h +
  • +
  • yaml_node_type_t +: yaml.h +
  • +
  • YAML_NULL_TAG +: yaml.h +
  • +
  • YAML_PARSE_BLOCK_MAPPING_FIRST_KEY_STATE +: yaml.h +
  • +
  • YAML_PARSE_BLOCK_MAPPING_KEY_STATE +: yaml.h +
  • +
  • YAML_PARSE_BLOCK_MAPPING_VALUE_STATE +: yaml.h +
  • +
  • YAML_PARSE_BLOCK_NODE_OR_INDENTLESS_SEQUENCE_STATE +: yaml.h +
  • +
  • YAML_PARSE_BLOCK_NODE_STATE +: yaml.h +
  • +
  • YAML_PARSE_BLOCK_SEQUENCE_ENTRY_STATE +: yaml.h +
  • +
  • YAML_PARSE_BLOCK_SEQUENCE_FIRST_ENTRY_STATE +: yaml.h +
  • +
  • YAML_PARSE_DOCUMENT_CONTENT_STATE +: yaml.h +
  • +
  • YAML_PARSE_DOCUMENT_END_STATE +: yaml.h +
  • +
  • YAML_PARSE_DOCUMENT_START_STATE +: yaml.h +
  • +
  • YAML_PARSE_END_STATE +: yaml.h +
  • +
  • YAML_PARSE_FLOW_MAPPING_EMPTY_VALUE_STATE +: yaml.h +
  • +
  • YAML_PARSE_FLOW_MAPPING_FIRST_KEY_STATE +: yaml.h +
  • +
  • YAML_PARSE_FLOW_MAPPING_KEY_STATE +: yaml.h +
  • +
  • YAML_PARSE_FLOW_MAPPING_VALUE_STATE +: yaml.h +
  • +
  • YAML_PARSE_FLOW_NODE_STATE +: yaml.h +
  • +
  • YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_END_STATE +: yaml.h +
  • +
  • YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_KEY_STATE +: yaml.h +
  • +
  • YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_VALUE_STATE +: yaml.h +
  • +
  • YAML_PARSE_FLOW_SEQUENCE_ENTRY_STATE +: yaml.h +
  • +
  • YAML_PARSE_FLOW_SEQUENCE_FIRST_ENTRY_STATE +: yaml.h +
  • +
  • YAML_PARSE_IMPLICIT_DOCUMENT_START_STATE +: yaml.h +
  • +
  • YAML_PARSE_INDENTLESS_SEQUENCE_ENTRY_STATE +: yaml.h +
  • +
  • YAML_PARSE_STREAM_START_STATE +: yaml.h +
  • +
  • yaml_parser_delete() +: yaml.h +
  • +
  • YAML_PARSER_ERROR +: yaml.h +
  • +
  • yaml_parser_initialize() +: yaml.h +
  • +
  • yaml_parser_load() +: yaml.h +
  • +
  • yaml_parser_parse() +: yaml.h +
  • +
  • yaml_parser_scan() +: yaml.h +
  • +
  • yaml_parser_set_encoding() +: yaml.h +
  • +
  • yaml_parser_set_input() +: yaml.h +
  • +
  • yaml_parser_set_input_file() +: yaml.h +
  • +
  • yaml_parser_set_input_string() +: yaml.h +
  • +
  • yaml_parser_state_e +: yaml.h +
  • +
  • yaml_parser_state_t +: yaml.h +
  • +
  • yaml_parser_t +: yaml.h +
  • +
  • YAML_PLAIN_SCALAR_STYLE +: yaml.h +
  • +
  • yaml_read_handler_t +: yaml.h +
  • +
  • YAML_READER_ERROR +: yaml.h +
  • +
  • YAML_SCALAR_EVENT +: yaml.h +
  • +
  • yaml_scalar_event_initialize() +: yaml.h +
  • +
  • YAML_SCALAR_NODE +: yaml.h +
  • +
  • yaml_scalar_style_e +: yaml.h +
  • +
  • yaml_scalar_style_t +: yaml.h +
  • +
  • YAML_SCALAR_TOKEN +: yaml.h +
  • +
  • YAML_SCANNER_ERROR +: yaml.h +
  • +
  • YAML_SEQ_TAG +: yaml.h +
  • +
  • YAML_SEQUENCE_END_EVENT +: yaml.h +
  • +
  • yaml_sequence_end_event_initialize() +: yaml.h +
  • +
  • YAML_SEQUENCE_NODE +: yaml.h +
  • +
  • YAML_SEQUENCE_START_EVENT +: yaml.h +
  • +
  • yaml_sequence_start_event_initialize() +: yaml.h +
  • +
  • yaml_sequence_style_e +: yaml.h +
  • +
  • yaml_sequence_style_t +: yaml.h +
  • +
  • yaml_simple_key_t +: yaml.h +
  • +
  • YAML_SINGLE_QUOTED_SCALAR_STYLE +: yaml.h +
  • +
  • YAML_STR_TAG +: yaml.h +
  • +
  • YAML_STREAM_END_EVENT +: yaml.h +
  • +
  • yaml_stream_end_event_initialize() +: yaml.h +
  • +
  • YAML_STREAM_END_TOKEN +: yaml.h +
  • +
  • YAML_STREAM_START_EVENT +: yaml.h +
  • +
  • yaml_stream_start_event_initialize() +: yaml.h +
  • +
  • YAML_STREAM_START_TOKEN +: yaml.h +
  • +
  • yaml_tag_directive_t +: yaml.h +
  • +
  • YAML_TAG_DIRECTIVE_TOKEN +: yaml.h +
  • +
  • YAML_TAG_TOKEN +: yaml.h +
  • +
  • YAML_TIMESTAMP_TAG +: yaml.h +
  • +
  • yaml_token_delete() +: yaml.h +
  • +
  • yaml_token_t +: yaml.h +
  • +
  • yaml_token_type_e +: yaml.h +
  • +
  • yaml_token_type_t +: yaml.h +
  • +
  • YAML_UTF16BE_ENCODING +: yaml.h +
  • +
  • YAML_UTF16LE_ENCODING +: yaml.h +
  • +
  • YAML_UTF8_ENCODING +: yaml.h +
  • +
  • YAML_VALUE_TOKEN +: yaml.h +
  • +
  • yaml_version_directive_t +: yaml.h +
  • +
  • YAML_VERSION_DIRECTIVE_TOKEN +: yaml.h +
  • +
  • yaml_write_handler_t +: yaml.h +
  • +
  • YAML_WRITER_ERROR +: yaml.h +
  • +
+
+ + + + + + diff --git a/web/server/h2o/libh2o/deps/yaml/doc/html/globals_defs.html b/web/server/h2o/libh2o/deps/yaml/doc/html/globals_defs.html new file mode 100644 index 00000000..c1f8e1c1 --- /dev/null +++ b/web/server/h2o/libh2o/deps/yaml/doc/html/globals_defs.html @@ -0,0 +1,113 @@ + + + + + +yaml: Globals + + + + + + + + +
+ + +
+ + + + + + + + + + + +
+
yaml +  0.1.6 +
+ +
+
+ + + + + +
+
    +
  • YAML_BOOL_TAG +: yaml.h +
  • +
  • YAML_DECLARE +: yaml.h +
  • +
  • YAML_DEFAULT_MAPPING_TAG +: yaml.h +
  • +
  • YAML_DEFAULT_SCALAR_TAG +: yaml.h +
  • +
  • YAML_DEFAULT_SEQUENCE_TAG +: yaml.h +
  • +
  • YAML_FLOAT_TAG +: yaml.h +
  • +
  • YAML_INT_TAG +: yaml.h +
  • +
  • YAML_MAP_TAG +: yaml.h +
  • +
  • YAML_NULL_TAG +: yaml.h +
  • +
  • YAML_SEQ_TAG +: yaml.h +
  • +
  • YAML_STR_TAG +: yaml.h +
  • +
  • YAML_TIMESTAMP_TAG +: yaml.h +
  • +
+
+ + + + + + diff --git a/web/server/h2o/libh2o/deps/yaml/doc/html/globals_enum.html b/web/server/h2o/libh2o/deps/yaml/doc/html/globals_enum.html new file mode 100644 index 00000000..04018283 --- /dev/null +++ b/web/server/h2o/libh2o/deps/yaml/doc/html/globals_enum.html @@ -0,0 +1,110 @@ + + + + + +yaml: Globals + + + + + + + + +
+ + +
+ + + + + + + + + + + +
+
yaml +  0.1.6 +
+ +
+
+ + + + + +
+
    +
  • yaml_break_e +: yaml.h +
  • +
  • yaml_emitter_state_e +: yaml.h +
  • +
  • yaml_encoding_e +: yaml.h +
  • +
  • yaml_error_type_e +: yaml.h +
  • +
  • yaml_event_type_e +: yaml.h +
  • +
  • yaml_mapping_style_e +: yaml.h +
  • +
  • yaml_node_type_e +: yaml.h +
  • +
  • yaml_parser_state_e +: yaml.h +
  • +
  • yaml_scalar_style_e +: yaml.h +
  • +
  • yaml_sequence_style_e +: yaml.h +
  • +
  • yaml_token_type_e +: yaml.h +
  • +
+
+ + + + + + diff --git a/web/server/h2o/libh2o/deps/yaml/doc/html/globals_eval.html b/web/server/h2o/libh2o/deps/yaml/doc/html/globals_eval.html new file mode 100644 index 00000000..37d1fd11 --- /dev/null +++ b/web/server/h2o/libh2o/deps/yaml/doc/html/globals_eval.html @@ -0,0 +1,405 @@ + + + + + +yaml: Globals + + + + + + + + +
+ + +
+ + + + + + + + + + + +
+
yaml +  0.1.6 +
+ +
+
+ + + + + + +
+
+  + +

- y -

    +
  • YAML_ALIAS_EVENT +: yaml.h +
  • +
  • YAML_ALIAS_TOKEN +: yaml.h +
  • +
  • YAML_ANCHOR_TOKEN +: yaml.h +
  • +
  • YAML_ANY_BREAK +: yaml.h +
  • +
  • YAML_ANY_ENCODING +: yaml.h +
  • +
  • YAML_ANY_MAPPING_STYLE +: yaml.h +
  • +
  • YAML_ANY_SCALAR_STYLE +: yaml.h +
  • +
  • YAML_ANY_SEQUENCE_STYLE +: yaml.h +
  • +
  • YAML_BLOCK_END_TOKEN +: yaml.h +
  • +
  • YAML_BLOCK_ENTRY_TOKEN +: yaml.h +
  • +
  • YAML_BLOCK_MAPPING_START_TOKEN +: yaml.h +
  • +
  • YAML_BLOCK_MAPPING_STYLE +: yaml.h +
  • +
  • YAML_BLOCK_SEQUENCE_START_TOKEN +: yaml.h +
  • +
  • YAML_BLOCK_SEQUENCE_STYLE +: yaml.h +
  • +
  • YAML_COMPOSER_ERROR +: yaml.h +
  • +
  • YAML_CR_BREAK +: yaml.h +
  • +
  • YAML_CRLN_BREAK +: yaml.h +
  • +
  • YAML_DOCUMENT_END_EVENT +: yaml.h +
  • +
  • YAML_DOCUMENT_END_TOKEN +: yaml.h +
  • +
  • YAML_DOCUMENT_START_EVENT +: yaml.h +
  • +
  • YAML_DOCUMENT_START_TOKEN +: yaml.h +
  • +
  • YAML_DOUBLE_QUOTED_SCALAR_STYLE +: yaml.h +
  • +
  • YAML_EMIT_BLOCK_MAPPING_FIRST_KEY_STATE +: yaml.h +
  • +
  • YAML_EMIT_BLOCK_MAPPING_KEY_STATE +: yaml.h +
  • +
  • YAML_EMIT_BLOCK_MAPPING_SIMPLE_VALUE_STATE +: yaml.h +
  • +
  • YAML_EMIT_BLOCK_MAPPING_VALUE_STATE +: yaml.h +
  • +
  • YAML_EMIT_BLOCK_SEQUENCE_FIRST_ITEM_STATE +: yaml.h +
  • +
  • YAML_EMIT_BLOCK_SEQUENCE_ITEM_STATE +: yaml.h +
  • +
  • YAML_EMIT_DOCUMENT_CONTENT_STATE +: yaml.h +
  • +
  • YAML_EMIT_DOCUMENT_END_STATE +: yaml.h +
  • +
  • YAML_EMIT_DOCUMENT_START_STATE +: yaml.h +
  • +
  • YAML_EMIT_END_STATE +: yaml.h +
  • +
  • YAML_EMIT_FIRST_DOCUMENT_START_STATE +: yaml.h +
  • +
  • YAML_EMIT_FLOW_MAPPING_FIRST_KEY_STATE +: yaml.h +
  • +
  • YAML_EMIT_FLOW_MAPPING_KEY_STATE +: yaml.h +
  • +
  • YAML_EMIT_FLOW_MAPPING_SIMPLE_VALUE_STATE +: yaml.h +
  • +
  • YAML_EMIT_FLOW_MAPPING_VALUE_STATE +: yaml.h +
  • +
  • YAML_EMIT_FLOW_SEQUENCE_FIRST_ITEM_STATE +: yaml.h +
  • +
  • YAML_EMIT_FLOW_SEQUENCE_ITEM_STATE +: yaml.h +
  • +
  • YAML_EMIT_STREAM_START_STATE +: yaml.h +
  • +
  • YAML_EMITTER_ERROR +: yaml.h +
  • +
  • YAML_FLOW_ENTRY_TOKEN +: yaml.h +
  • +
  • YAML_FLOW_MAPPING_END_TOKEN +: yaml.h +
  • +
  • YAML_FLOW_MAPPING_START_TOKEN +: yaml.h +
  • +
  • YAML_FLOW_MAPPING_STYLE +: yaml.h +
  • +
  • YAML_FLOW_SEQUENCE_END_TOKEN +: yaml.h +
  • +
  • YAML_FLOW_SEQUENCE_START_TOKEN +: yaml.h +
  • +
  • YAML_FLOW_SEQUENCE_STYLE +: yaml.h +
  • +
  • YAML_FOLDED_SCALAR_STYLE +: yaml.h +
  • +
  • YAML_KEY_TOKEN +: yaml.h +
  • +
  • YAML_LITERAL_SCALAR_STYLE +: yaml.h +
  • +
  • YAML_LN_BREAK +: yaml.h +
  • +
  • YAML_MAPPING_END_EVENT +: yaml.h +
  • +
  • YAML_MAPPING_NODE +: yaml.h +
  • +
  • YAML_MAPPING_START_EVENT +: yaml.h +
  • +
  • YAML_MEMORY_ERROR +: yaml.h +
  • +
  • YAML_NO_ERROR +: yaml.h +
  • +
  • YAML_NO_EVENT +: yaml.h +
  • +
  • YAML_NO_NODE +: yaml.h +
  • +
  • YAML_NO_TOKEN +: yaml.h +
  • +
  • YAML_PARSE_BLOCK_MAPPING_FIRST_KEY_STATE +: yaml.h +
  • +
  • YAML_PARSE_BLOCK_MAPPING_KEY_STATE +: yaml.h +
  • +
  • YAML_PARSE_BLOCK_MAPPING_VALUE_STATE +: yaml.h +
  • +
  • YAML_PARSE_BLOCK_NODE_OR_INDENTLESS_SEQUENCE_STATE +: yaml.h +
  • +
  • YAML_PARSE_BLOCK_NODE_STATE +: yaml.h +
  • +
  • YAML_PARSE_BLOCK_SEQUENCE_ENTRY_STATE +: yaml.h +
  • +
  • YAML_PARSE_BLOCK_SEQUENCE_FIRST_ENTRY_STATE +: yaml.h +
  • +
  • YAML_PARSE_DOCUMENT_CONTENT_STATE +: yaml.h +
  • +
  • YAML_PARSE_DOCUMENT_END_STATE +: yaml.h +
  • +
  • YAML_PARSE_DOCUMENT_START_STATE +: yaml.h +
  • +
  • YAML_PARSE_END_STATE +: yaml.h +
  • +
  • YAML_PARSE_FLOW_MAPPING_EMPTY_VALUE_STATE +: yaml.h +
  • +
  • YAML_PARSE_FLOW_MAPPING_FIRST_KEY_STATE +: yaml.h +
  • +
  • YAML_PARSE_FLOW_MAPPING_KEY_STATE +: yaml.h +
  • +
  • YAML_PARSE_FLOW_MAPPING_VALUE_STATE +: yaml.h +
  • +
  • YAML_PARSE_FLOW_NODE_STATE +: yaml.h +
  • +
  • YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_END_STATE +: yaml.h +
  • +
  • YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_KEY_STATE +: yaml.h +
  • +
  • YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_VALUE_STATE +: yaml.h +
  • +
  • YAML_PARSE_FLOW_SEQUENCE_ENTRY_STATE +: yaml.h +
  • +
  • YAML_PARSE_FLOW_SEQUENCE_FIRST_ENTRY_STATE +: yaml.h +
  • +
  • YAML_PARSE_IMPLICIT_DOCUMENT_START_STATE +: yaml.h +
  • +
  • YAML_PARSE_INDENTLESS_SEQUENCE_ENTRY_STATE +: yaml.h +
  • +
  • YAML_PARSE_STREAM_START_STATE +: yaml.h +
  • +
  • YAML_PARSER_ERROR +: yaml.h +
  • +
  • YAML_PLAIN_SCALAR_STYLE +: yaml.h +
  • +
  • YAML_READER_ERROR +: yaml.h +
  • +
  • YAML_SCALAR_EVENT +: yaml.h +
  • +
  • YAML_SCALAR_NODE +: yaml.h +
  • +
  • YAML_SCALAR_TOKEN +: yaml.h +
  • +
  • YAML_SCANNER_ERROR +: yaml.h +
  • +
  • YAML_SEQUENCE_END_EVENT +: yaml.h +
  • +
  • YAML_SEQUENCE_NODE +: yaml.h +
  • +
  • YAML_SEQUENCE_START_EVENT +: yaml.h +
  • +
  • YAML_SINGLE_QUOTED_SCALAR_STYLE +: yaml.h +
  • +
  • YAML_STREAM_END_EVENT +: yaml.h +
  • +
  • YAML_STREAM_END_TOKEN +: yaml.h +
  • +
  • YAML_STREAM_START_EVENT +: yaml.h +
  • +
  • YAML_STREAM_START_TOKEN +: yaml.h +
  • +
  • YAML_TAG_DIRECTIVE_TOKEN +: yaml.h +
  • +
  • YAML_TAG_TOKEN +: yaml.h +
  • +
  • YAML_UTF16BE_ENCODING +: yaml.h +
  • +
  • YAML_UTF16LE_ENCODING +: yaml.h +
  • +
  • YAML_UTF8_ENCODING +: yaml.h +
  • +
  • YAML_VALUE_TOKEN +: yaml.h +
  • +
  • YAML_VERSION_DIRECTIVE_TOKEN +: yaml.h +
  • +
  • YAML_WRITER_ERROR +: yaml.h +
  • +
+
+ + + + + + diff --git a/web/server/h2o/libh2o/deps/yaml/doc/html/globals_func.html b/web/server/h2o/libh2o/deps/yaml/doc/html/globals_func.html new file mode 100644 index 00000000..146848e3 --- /dev/null +++ b/web/server/h2o/libh2o/deps/yaml/doc/html/globals_func.html @@ -0,0 +1,228 @@ + + + + + +yaml: Globals + + + + + + + + +
+ + +
+ + + + + + + + + + + +
+
yaml +  0.1.6 +
+ +
+
+ + + + + + +
+
+  + +

- y -

    +
  • yaml_alias_event_initialize() +: yaml.h +
  • +
  • yaml_document_add_mapping() +: yaml.h +
  • +
  • yaml_document_add_scalar() +: yaml.h +
  • +
  • yaml_document_add_sequence() +: yaml.h +
  • +
  • yaml_document_append_mapping_pair() +: yaml.h +
  • +
  • yaml_document_append_sequence_item() +: yaml.h +
  • +
  • yaml_document_delete() +: yaml.h +
  • +
  • yaml_document_end_event_initialize() +: yaml.h +
  • +
  • yaml_document_get_node() +: yaml.h +
  • +
  • yaml_document_get_root_node() +: yaml.h +
  • +
  • yaml_document_initialize() +: yaml.h +
  • +
  • yaml_document_start_event_initialize() +: yaml.h +
  • +
  • yaml_emitter_close() +: yaml.h +
  • +
  • yaml_emitter_delete() +: yaml.h +
  • +
  • yaml_emitter_dump() +: yaml.h +
  • +
  • yaml_emitter_emit() +: yaml.h +
  • +
  • yaml_emitter_flush() +: yaml.h +
  • +
  • yaml_emitter_initialize() +: yaml.h +
  • +
  • yaml_emitter_open() +: yaml.h +
  • +
  • yaml_emitter_set_break() +: yaml.h +
  • +
  • yaml_emitter_set_canonical() +: yaml.h +
  • +
  • yaml_emitter_set_encoding() +: yaml.h +
  • +
  • yaml_emitter_set_indent() +: yaml.h +
  • +
  • yaml_emitter_set_output() +: yaml.h +
  • +
  • yaml_emitter_set_output_file() +: yaml.h +
  • +
  • yaml_emitter_set_output_string() +: yaml.h +
  • +
  • yaml_emitter_set_unicode() +: yaml.h +
  • +
  • yaml_emitter_set_width() +: yaml.h +
  • +
  • yaml_event_delete() +: yaml.h +
  • +
  • yaml_get_version() +: yaml.h +
  • +
  • yaml_get_version_string() +: yaml.h +
  • +
  • yaml_mapping_end_event_initialize() +: yaml.h +
  • +
  • yaml_mapping_start_event_initialize() +: yaml.h +
  • +
  • yaml_parser_delete() +: yaml.h +
  • +
  • yaml_parser_initialize() +: yaml.h +
  • +
  • yaml_parser_load() +: yaml.h +
  • +
  • yaml_parser_parse() +: yaml.h +
  • +
  • yaml_parser_scan() +: yaml.h +
  • +
  • yaml_parser_set_encoding() +: yaml.h +
  • +
  • yaml_parser_set_input() +: yaml.h +
  • +
  • yaml_parser_set_input_file() +: yaml.h +
  • +
  • yaml_parser_set_input_string() +: yaml.h +
  • +
  • yaml_scalar_event_initialize() +: yaml.h +
  • +
  • yaml_sequence_end_event_initialize() +: yaml.h +
  • +
  • yaml_sequence_start_event_initialize() +: yaml.h +
  • +
  • yaml_stream_end_event_initialize() +: yaml.h +
  • +
  • yaml_stream_start_event_initialize() +: yaml.h +
  • +
  • yaml_token_delete() +: yaml.h +
  • +
+
+ + + + + + diff --git a/web/server/h2o/libh2o/deps/yaml/doc/html/globals_type.html b/web/server/h2o/libh2o/deps/yaml/doc/html/globals_type.html new file mode 100644 index 00000000..520e79b6 --- /dev/null +++ b/web/server/h2o/libh2o/deps/yaml/doc/html/globals_type.html @@ -0,0 +1,158 @@ + + + + + +yaml: Globals + + + + + + + + +
+ + +
+ + + + + + + + + + + +
+
yaml +  0.1.6 +
+ +
+
+ + + + + +
+
    +
  • yaml_alias_data_t +: yaml.h +
  • +
  • yaml_break_t +: yaml.h +
  • +
  • yaml_char_t +: yaml.h +
  • +
  • yaml_document_t +: yaml.h +
  • +
  • yaml_emitter_state_t +: yaml.h +
  • +
  • yaml_emitter_t +: yaml.h +
  • +
  • yaml_encoding_t +: yaml.h +
  • +
  • yaml_error_type_t +: yaml.h +
  • +
  • yaml_event_t +: yaml.h +
  • +
  • yaml_event_type_t +: yaml.h +
  • +
  • yaml_mapping_style_t +: yaml.h +
  • +
  • yaml_mark_t +: yaml.h +
  • +
  • yaml_node_item_t +: yaml.h +
  • +
  • yaml_node_pair_t +: yaml.h +
  • +
  • yaml_node_t +: yaml.h +
  • +
  • yaml_node_type_t +: yaml.h +
  • +
  • yaml_parser_state_t +: yaml.h +
  • +
  • yaml_parser_t +: yaml.h +
  • +
  • yaml_read_handler_t +: yaml.h +
  • +
  • yaml_scalar_style_t +: yaml.h +
  • +
  • yaml_sequence_style_t +: yaml.h +
  • +
  • yaml_simple_key_t +: yaml.h +
  • +
  • yaml_tag_directive_t +: yaml.h +
  • +
  • yaml_token_t +: yaml.h +
  • +
  • yaml_token_type_t +: yaml.h +
  • +
  • yaml_version_directive_t +: yaml.h +
  • +
  • yaml_write_handler_t +: yaml.h +
  • +
+
+ + + + + + diff --git a/web/server/h2o/libh2o/deps/yaml/doc/html/group__basic.html b/web/server/h2o/libh2o/deps/yaml/doc/html/group__basic.html new file mode 100644 index 00000000..12f7d5bc --- /dev/null +++ b/web/server/h2o/libh2o/deps/yaml/doc/html/group__basic.html @@ -0,0 +1,349 @@ + + + + + +yaml: Basic Types + + + + + + + + +
+ + +
+ + + + + + + + + + + +
+
yaml +  0.1.6 +
+ +
+
+ + + +
+
+ +
+
Basic Types
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Data Structures

struct  yaml_version_directive_s
 The version directive data. More...
struct  yaml_tag_directive_s
 The tag directive data. More...
struct  yaml_mark_s
 The pointer position. More...

+Typedefs

typedef unsigned char yaml_char_t
 The character type (UTF-8 octet).
typedef struct
+yaml_version_directive_s 
yaml_version_directive_t
 The version directive data.
typedef struct yaml_tag_directive_s yaml_tag_directive_t
 The tag directive data.
typedef enum yaml_encoding_e yaml_encoding_t
 The stream encoding.
typedef enum yaml_break_e yaml_break_t
 Line break types.
typedef enum yaml_error_type_e yaml_error_type_t
 Many bad things could happen with the parser and emitter.
typedef struct yaml_mark_s yaml_mark_t
 The pointer position.

+Enumerations

enum  yaml_encoding_e {
+  YAML_ANY_ENCODING, +
+  YAML_UTF8_ENCODING, +
+  YAML_UTF16LE_ENCODING, +
+  YAML_UTF16BE_ENCODING +
+ }
 The stream encoding. More...
enum  yaml_break_e {
+  YAML_ANY_BREAK, +
+  YAML_CR_BREAK, +
+  YAML_LN_BREAK, +
+  YAML_CRLN_BREAK +
+ }
 Line break types. More...
enum  yaml_error_type_e {
+  YAML_NO_ERROR, +
+  YAML_MEMORY_ERROR, +
+  YAML_READER_ERROR, +
+  YAML_SCANNER_ERROR, +
+  YAML_PARSER_ERROR, +
+  YAML_COMPOSER_ERROR, +
+  YAML_WRITER_ERROR, +
+  YAML_EMITTER_ERROR +
+ }
 Many bad things could happen with the parser and emitter. More...
+

Typedef Documentation

+ +
+
+ + + + +
typedef unsigned char yaml_char_t
+
+
+ +

The character type (UTF-8 octet).

+ +
+
+ +
+ +
+ +

The version directive data.

+ +
+
+ +
+
+ + + + +
typedef struct yaml_tag_directive_s yaml_tag_directive_t
+
+
+ +

The tag directive data.

+ +
+
+ +
+
+ + + + +
typedef enum yaml_encoding_e yaml_encoding_t
+
+
+ +

The stream encoding.

+ +
+
+ +
+
+ + + + +
typedef enum yaml_break_e yaml_break_t
+
+
+ +

Line break types.

+ +
+
+ +
+
+ + + + +
typedef enum yaml_error_type_e yaml_error_type_t
+
+
+ +

Many bad things could happen with the parser and emitter.

+ +
+
+ +
+
+ + + + +
typedef struct yaml_mark_s yaml_mark_t
+
+
+ +

The pointer position.

+ +
+
+

Enumeration Type Documentation

+ +
+
+ + + + +
enum yaml_encoding_e
+
+
+ +

The stream encoding.

+
Enumerator:
+ + + + +
YAML_ANY_ENCODING  +

Let the parser choose the encoding.

+
YAML_UTF8_ENCODING  +

The default UTF-8 encoding.

+
YAML_UTF16LE_ENCODING  +

The UTF-16-LE encoding with BOM.

+
YAML_UTF16BE_ENCODING  +

The UTF-16-BE encoding with BOM.

+
+
+
+ +
+
+ +
+
+ + + + +
enum yaml_break_e
+
+
+ +

Line break types.

+
Enumerator:
+ + + + +
YAML_ANY_BREAK  +

Let the parser choose the break type.

+
YAML_CR_BREAK  +

Use CR for line breaks (Mac style).

+
YAML_LN_BREAK  +

Use LN for line breaks (Unix style).

+
YAML_CRLN_BREAK  +

Use CR LN for line breaks (DOS style).

+
+
+
+ +
+
+ +
+
+ + + + +
enum yaml_error_type_e
+
+
+ +

Many bad things could happen with the parser and emitter.

+
Enumerator:
+ + + + + + + + +
YAML_NO_ERROR  +

No error is produced.

+
YAML_MEMORY_ERROR  +

Cannot allocate or reallocate a block of memory.

+
YAML_READER_ERROR  +

Cannot read or decode the input stream.

+
YAML_SCANNER_ERROR  +

Cannot scan the input stream.

+
YAML_PARSER_ERROR  +

Cannot parse the input stream.

+
YAML_COMPOSER_ERROR  +

Cannot compose a YAML document.

+
YAML_WRITER_ERROR  +

Cannot write to the output stream.

+
YAML_EMITTER_ERROR  +

Cannot emit a YAML stream.

+
+
+
+ +
+
+
+ + + + + + diff --git a/web/server/h2o/libh2o/deps/yaml/doc/html/group__emitter.html b/web/server/h2o/libh2o/deps/yaml/doc/html/group__emitter.html new file mode 100644 index 00000000..00e08aa6 --- /dev/null +++ b/web/server/h2o/libh2o/deps/yaml/doc/html/group__emitter.html @@ -0,0 +1,845 @@ + + + + + +yaml: Emitter Definitions + + + + + + + + +
+ + +
+ + + + + + + + + + + +
+
yaml +  0.1.6 +
+ +
+
+ + + +
+
+ +
+
Emitter Definitions
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Data Structures

struct  yaml_emitter_s
 The emitter structure. More...

+Typedefs

typedef int yaml_write_handler_t (void *data, unsigned char *buffer, size_t size)
 The prototype of a write handler.
typedef enum yaml_emitter_state_e yaml_emitter_state_t
 The emitter states.
typedef struct yaml_emitter_s yaml_emitter_t
 The emitter structure.

+Enumerations

enum  yaml_emitter_state_e {
+  YAML_EMIT_STREAM_START_STATE, +
+  YAML_EMIT_FIRST_DOCUMENT_START_STATE, +
+  YAML_EMIT_DOCUMENT_START_STATE, +
+  YAML_EMIT_DOCUMENT_CONTENT_STATE, +
+  YAML_EMIT_DOCUMENT_END_STATE, +
+  YAML_EMIT_FLOW_SEQUENCE_FIRST_ITEM_STATE, +
+  YAML_EMIT_FLOW_SEQUENCE_ITEM_STATE, +
+  YAML_EMIT_FLOW_MAPPING_FIRST_KEY_STATE, +
+  YAML_EMIT_FLOW_MAPPING_KEY_STATE, +
+  YAML_EMIT_FLOW_MAPPING_SIMPLE_VALUE_STATE, +
+  YAML_EMIT_FLOW_MAPPING_VALUE_STATE, +
+  YAML_EMIT_BLOCK_SEQUENCE_FIRST_ITEM_STATE, +
+  YAML_EMIT_BLOCK_SEQUENCE_ITEM_STATE, +
+  YAML_EMIT_BLOCK_MAPPING_FIRST_KEY_STATE, +
+  YAML_EMIT_BLOCK_MAPPING_KEY_STATE, +
+  YAML_EMIT_BLOCK_MAPPING_SIMPLE_VALUE_STATE, +
+  YAML_EMIT_BLOCK_MAPPING_VALUE_STATE, +
+  YAML_EMIT_END_STATE +
+ }
 The emitter states. More...

+Functions

int yaml_emitter_initialize (yaml_emitter_t *emitter)
 Initialize an emitter.
void yaml_emitter_delete (yaml_emitter_t *emitter)
 Destroy an emitter.
void yaml_emitter_set_output_string (yaml_emitter_t *emitter, unsigned char *output, size_t size, size_t *size_written)
 Set a string output.
void yaml_emitter_set_output_file (yaml_emitter_t *emitter, FILE *file)
 Set a file output.
void yaml_emitter_set_output (yaml_emitter_t *emitter, yaml_write_handler_t *handler, void *data)
 Set a generic output handler.
void yaml_emitter_set_encoding (yaml_emitter_t *emitter, yaml_encoding_t encoding)
 Set the output encoding.
void yaml_emitter_set_canonical (yaml_emitter_t *emitter, int canonical)
 Set if the output should be in the "canonical" format as in the YAML specification.
void yaml_emitter_set_indent (yaml_emitter_t *emitter, int indent)
 Set the intendation increment.
void yaml_emitter_set_width (yaml_emitter_t *emitter, int width)
 Set the preferred line width.
void yaml_emitter_set_unicode (yaml_emitter_t *emitter, int unicode)
 Set if unescaped non-ASCII characters are allowed.
void yaml_emitter_set_break (yaml_emitter_t *emitter, yaml_break_t line_break)
 Set the preferred line break.
int yaml_emitter_emit (yaml_emitter_t *emitter, yaml_event_t *event)
 Emit an event.
int yaml_emitter_open (yaml_emitter_t *emitter)
 Start a YAML stream.
int yaml_emitter_close (yaml_emitter_t *emitter)
 Finish a YAML stream.
int yaml_emitter_dump (yaml_emitter_t *emitter, yaml_document_t *document)
 Emit a YAML document.
int yaml_emitter_flush (yaml_emitter_t *emitter)
 Flush the accumulated characters to the output.
+

Typedef Documentation

+ +
+
+ + + + +
typedef int yaml_write_handler_t(void *data, unsigned char *buffer, size_t size)
+
+
+ +

The prototype of a write handler.

+

The write handler is called when the emitter needs to flush the accumulated characters to the output. The handler should write size bytes of the buffer to the output.

+
Parameters:
+ + + + +
[in,out]dataA pointer to an application data specified by yaml_emitter_set_output().
[in]bufferThe buffer with bytes to be written.
[in]sizeThe size of the buffer.
+
+
+
Returns:
On success, the handler should return 1. If the handler failed, the returned value should be 0.
+ +
+
+ +
+
+ + + + +
typedef enum yaml_emitter_state_e yaml_emitter_state_t
+
+
+ +

The emitter states.

+ +
+
+ +
+
+ + + + +
typedef struct yaml_emitter_s yaml_emitter_t
+
+
+ +

The emitter structure.

+

All members are internal. Manage the structure using the yaml_emitter_ family of functions.

+ +
+
+

Enumeration Type Documentation

+ +
+
+ + + + +
enum yaml_emitter_state_e
+
+
+ +

The emitter states.

+
Enumerator:
+ + + + + + + + + + + + + + + + + + +
YAML_EMIT_STREAM_START_STATE  +

Expect STREAM-START.

+
YAML_EMIT_FIRST_DOCUMENT_START_STATE  +

Expect the first DOCUMENT-START or STREAM-END.

+
YAML_EMIT_DOCUMENT_START_STATE  +

Expect DOCUMENT-START or STREAM-END.

+
YAML_EMIT_DOCUMENT_CONTENT_STATE  +

Expect the content of a document.

+
YAML_EMIT_DOCUMENT_END_STATE  +

Expect DOCUMENT-END.

+
YAML_EMIT_FLOW_SEQUENCE_FIRST_ITEM_STATE  +

Expect the first item of a flow sequence.

+
YAML_EMIT_FLOW_SEQUENCE_ITEM_STATE  +

Expect an item of a flow sequence.

+
YAML_EMIT_FLOW_MAPPING_FIRST_KEY_STATE  +

Expect the first key of a flow mapping.

+
YAML_EMIT_FLOW_MAPPING_KEY_STATE  +

Expect a key of a flow mapping.

+
YAML_EMIT_FLOW_MAPPING_SIMPLE_VALUE_STATE  +

Expect a value for a simple key of a flow mapping.

+
YAML_EMIT_FLOW_MAPPING_VALUE_STATE  +

Expect a value of a flow mapping.

+
YAML_EMIT_BLOCK_SEQUENCE_FIRST_ITEM_STATE  +

Expect the first item of a block sequence.

+
YAML_EMIT_BLOCK_SEQUENCE_ITEM_STATE  +

Expect an item of a block sequence.

+
YAML_EMIT_BLOCK_MAPPING_FIRST_KEY_STATE  +

Expect the first key of a block mapping.

+
YAML_EMIT_BLOCK_MAPPING_KEY_STATE  +

Expect the key of a block mapping.

+
YAML_EMIT_BLOCK_MAPPING_SIMPLE_VALUE_STATE  +

Expect a value for a simple key of a block mapping.

+
YAML_EMIT_BLOCK_MAPPING_VALUE_STATE  +

Expect a value of a block mapping.

+
YAML_EMIT_END_STATE  +

Expect nothing.

+
+
+
+ +
+
+

Function Documentation

+ +
+
+ + + + + + + + +
int yaml_emitter_initialize (yaml_emitter_temitter)
+
+
+ +

Initialize an emitter.

+

This function creates a new emitter object. An application is responsible for destroying the object using the yaml_emitter_delete() function.

+
Parameters:
+ + +
[out]emitterAn empty parser object.
+
+
+
Returns:
1 if the function succeeded, 0 on error.
+ +
+
+ +
+
+ + + + + + + + +
void yaml_emitter_delete (yaml_emitter_temitter)
+
+
+ +

Destroy an emitter.

+
Parameters:
+ + +
[in,out]emitterAn emitter object.
+
+
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
void yaml_emitter_set_output_string (yaml_emitter_temitter,
unsigned char * output,
size_t size,
size_t * size_written 
)
+
+
+ +

Set a string output.

+

The emitter will write the output characters to the output buffer of the size size. The emitter will set size_written to the number of written bytes. If the buffer is smaller than required, the emitter produces the YAML_WRITE_ERROR error.

+
Parameters:
+ + + + + +
[in,out]emitterAn emitter object.
[in]outputAn output buffer.
[in]sizeThe buffer size.
[in]size_writtenThe pointer to save the number of written bytes.
+
+
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + +
void yaml_emitter_set_output_file (yaml_emitter_temitter,
FILE * file 
)
+
+
+ +

Set a file output.

+

file should be a file object open for writing. The application is responsible for closing the file.

+
Parameters:
+ + + +
[in,out]emitterAn emitter object.
[in]fileAn open file.
+
+
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
void yaml_emitter_set_output (yaml_emitter_temitter,
yaml_write_handler_thandler,
void * data 
)
+
+
+ +

Set a generic output handler.

+
Parameters:
+ + + + +
[in,out]emitterAn emitter object.
[in]handlerA write handler.
[in]dataAny application data for passing to the write handler.
+
+
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + +
void yaml_emitter_set_encoding (yaml_emitter_temitter,
yaml_encoding_t encoding 
)
+
+
+ +

Set the output encoding.

+
Parameters:
+ + + +
[in,out]emitterAn emitter object.
[in]encodingThe output encoding.
+
+
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + +
void yaml_emitter_set_canonical (yaml_emitter_temitter,
int canonical 
)
+
+
+ +

Set if the output should be in the "canonical" format as in the YAML specification.

+
Parameters:
+ + + +
[in,out]emitterAn emitter object.
[in]canonicalIf the output is canonical.
+
+
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + +
void yaml_emitter_set_indent (yaml_emitter_temitter,
int indent 
)
+
+
+ +

Set the intendation increment.

+
Parameters:
+ + + +
[in,out]emitterAn emitter object.
[in]indentThe indentation increment (1 < . < 10).
+
+
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + +
void yaml_emitter_set_width (yaml_emitter_temitter,
int width 
)
+
+
+ +

Set the preferred line width.

+

-1 means unlimited.

+
Parameters:
+ + + +
[in,out]emitterAn emitter object.
[in]widthThe preferred line width.
+
+
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + +
void yaml_emitter_set_unicode (yaml_emitter_temitter,
int unicode 
)
+
+
+ +

Set if unescaped non-ASCII characters are allowed.

+
Parameters:
+ + + +
[in,out]emitterAn emitter object.
[in]unicodeIf unescaped Unicode characters are allowed.
+
+
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + +
void yaml_emitter_set_break (yaml_emitter_temitter,
yaml_break_t line_break 
)
+
+
+ +

Set the preferred line break.

+
Parameters:
+ + + +
[in,out]emitterAn emitter object.
[in]line_breakThe preferred line break.
+
+
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + +
int yaml_emitter_emit (yaml_emitter_temitter,
yaml_event_tevent 
)
+
+
+ +

Emit an event.

+

The event object may be generated using the yaml_parser_parse() function. The emitter takes the responsibility for the event object and destroys its content after it is emitted. The event object is destroyed even if the function fails.

+
Parameters:
+ + + +
[in,out]emitterAn emitter object.
[in,out]eventAn event object.
+
+
+
Returns:
1 if the function succeeded, 0 on error.
+ +
+
+ +
+
+ + + + + + + + +
int yaml_emitter_open (yaml_emitter_temitter)
+
+
+ +

Start a YAML stream.

+

This function should be used before yaml_emitter_dump() is called.

+
Parameters:
+ + +
[in,out]emitterAn emitter object.
+
+
+
Returns:
1 if the function succeeded, 0 on error.
+ +
+
+ +
+
+ + + + + + + + +
int yaml_emitter_close (yaml_emitter_temitter)
+
+
+ +

Finish a YAML stream.

+

This function should be used after yaml_emitter_dump() is called.

+
Parameters:
+ + +
[in,out]emitterAn emitter object.
+
+
+
Returns:
1 if the function succeeded, 0 on error.
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + +
int yaml_emitter_dump (yaml_emitter_temitter,
yaml_document_tdocument 
)
+
+
+ +

Emit a YAML document.

+

The documen object may be generated using the yaml_parser_load() function or the yaml_document_initialize() function. The emitter takes the responsibility for the document object and destoys its content after it is emitted. The document object is destroyedeven if the function fails.

+
Parameters:
+ + + +
[in,out]emitterAn emitter object.
[in,out]documentA document object.
+
+
+
Returns:
1 if the function succeeded, 0 on error.
+ +
+
+ +
+
+ + + + + + + + +
int yaml_emitter_flush (yaml_emitter_temitter)
+
+
+ +

Flush the accumulated characters to the output.

+
Parameters:
+ + +
[in,out]emitterAn emitter object.
+
+
+
Returns:
1 if the function succeeded, 0 on error.
+ +
+
+
+ + + + + + diff --git a/web/server/h2o/libh2o/deps/yaml/doc/html/group__events.html b/web/server/h2o/libh2o/deps/yaml/doc/html/group__events.html new file mode 100644 index 00000000..cab6426c --- /dev/null +++ b/web/server/h2o/libh2o/deps/yaml/doc/html/group__events.html @@ -0,0 +1,691 @@ + + + + + +yaml: Events + + + + + + + + +
+ + +
+ + + + + + + + + + + +
+
yaml +  0.1.6 +
+ +
+
+ + + +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Data Structures

struct  yaml_event_s
 The event structure. More...

+Typedefs

typedef enum yaml_event_type_e yaml_event_type_t
 Event types.
typedef struct yaml_event_s yaml_event_t
 The event structure.

+Enumerations

enum  yaml_event_type_e {
+  YAML_NO_EVENT, +
+  YAML_STREAM_START_EVENT, +
+  YAML_STREAM_END_EVENT, +
+  YAML_DOCUMENT_START_EVENT, +
+  YAML_DOCUMENT_END_EVENT, +
+  YAML_ALIAS_EVENT, +
+  YAML_SCALAR_EVENT, +
+  YAML_SEQUENCE_START_EVENT, +
+  YAML_SEQUENCE_END_EVENT, +
+  YAML_MAPPING_START_EVENT, +
+  YAML_MAPPING_END_EVENT +
+ }
 Event types. More...

+Functions

int yaml_stream_start_event_initialize (yaml_event_t *event, yaml_encoding_t encoding)
 Create the STREAM-START event.
int yaml_stream_end_event_initialize (yaml_event_t *event)
 Create the STREAM-END event.
int yaml_document_start_event_initialize (yaml_event_t *event, yaml_version_directive_t *version_directive, yaml_tag_directive_t *tag_directives_start, yaml_tag_directive_t *tag_directives_end, int implicit)
 Create the DOCUMENT-START event.
int yaml_document_end_event_initialize (yaml_event_t *event, int implicit)
 Create the DOCUMENT-END event.
int yaml_alias_event_initialize (yaml_event_t *event, yaml_char_t *anchor)
 Create an ALIAS event.
int yaml_scalar_event_initialize (yaml_event_t *event, yaml_char_t *anchor, yaml_char_t *tag, yaml_char_t *value, int length, int plain_implicit, int quoted_implicit, yaml_scalar_style_t style)
 Create a SCALAR event.
int yaml_sequence_start_event_initialize (yaml_event_t *event, yaml_char_t *anchor, yaml_char_t *tag, int implicit, yaml_sequence_style_t style)
 Create a SEQUENCE-START event.
int yaml_sequence_end_event_initialize (yaml_event_t *event)
 Create a SEQUENCE-END event.
int yaml_mapping_start_event_initialize (yaml_event_t *event, yaml_char_t *anchor, yaml_char_t *tag, int implicit, yaml_mapping_style_t style)
 Create a MAPPING-START event.
int yaml_mapping_end_event_initialize (yaml_event_t *event)
 Create a MAPPING-END event.
void yaml_event_delete (yaml_event_t *event)
 Free any memory allocated for an event object.
+

Typedef Documentation

+ +
+
+ + + + +
typedef enum yaml_event_type_e yaml_event_type_t
+
+
+ +

Event types.

+ +
+
+ +
+
+ + + + +
typedef struct yaml_event_s yaml_event_t
+
+
+ +

The event structure.

+ +
+
+

Enumeration Type Documentation

+ +
+
+ + + + +
enum yaml_event_type_e
+
+
+ +

Event types.

+
Enumerator:
+ + + + + + + + + + + +
YAML_NO_EVENT  +

An empty event.

+
YAML_STREAM_START_EVENT  +

A STREAM-START event.

+
YAML_STREAM_END_EVENT  +

A STREAM-END event.

+
YAML_DOCUMENT_START_EVENT  +

A DOCUMENT-START event.

+
YAML_DOCUMENT_END_EVENT  +

A DOCUMENT-END event.

+
YAML_ALIAS_EVENT  +

An ALIAS event.

+
YAML_SCALAR_EVENT  +

A SCALAR event.

+
YAML_SEQUENCE_START_EVENT  +

A SEQUENCE-START event.

+
YAML_SEQUENCE_END_EVENT  +

A SEQUENCE-END event.

+
YAML_MAPPING_START_EVENT  +

A MAPPING-START event.

+
YAML_MAPPING_END_EVENT  +

A MAPPING-END event.

+
+
+
+ +
+
+

Function Documentation

+ +
+
+ + + + + + + + + + + + + + + + + + +
int yaml_stream_start_event_initialize (yaml_event_tevent,
yaml_encoding_t encoding 
)
+
+
+ +

Create the STREAM-START event.

+
Parameters:
+ + + +
[out]eventAn empty event object.
[in]encodingThe stream encoding.
+
+
+
Returns:
1 if the function succeeded, 0 on error.
+ +
+
+ +
+
+ + + + + + + + +
int yaml_stream_end_event_initialize (yaml_event_tevent)
+
+
+ +

Create the STREAM-END event.

+
Parameters:
+ + +
[out]eventAn empty event object.
+
+
+
Returns:
1 if the function succeeded, 0 on error.
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
int yaml_document_start_event_initialize (yaml_event_tevent,
yaml_version_directive_tversion_directive,
yaml_tag_directive_ttag_directives_start,
yaml_tag_directive_ttag_directives_end,
int implicit 
)
+
+
+ +

Create the DOCUMENT-START event.

+

The implicit argument is considered as a stylistic parameter and may be ignored by the emitter.

+
Parameters:
+ + + + + + +
[out]eventAn empty event object.
[in]version_directiveThe YAML directive value or NULL.
[in]tag_directives_startThe beginning of the TAG directives list.
[in]tag_directives_endThe end of the TAG directives list.
[in]implicitIf the document start indicator is implicit.
+
+
+
Returns:
1 if the function succeeded, 0 on error.
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + +
int yaml_document_end_event_initialize (yaml_event_tevent,
int implicit 
)
+
+
+ +

Create the DOCUMENT-END event.

+

The implicit argument is considered as a stylistic parameter and may be ignored by the emitter.

+
Parameters:
+ + + +
[out]eventAn empty event object.
[in]implicitIf the document end indicator is implicit.
+
+
+
Returns:
1 if the function succeeded, 0 on error.
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + +
int yaml_alias_event_initialize (yaml_event_tevent,
yaml_char_tanchor 
)
+
+
+ +

Create an ALIAS event.

+
Parameters:
+ + + +
[out]eventAn empty event object.
[in]anchorThe anchor value.
+
+
+
Returns:
1 if the function succeeded, 0 on error.
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
int yaml_scalar_event_initialize (yaml_event_tevent,
yaml_char_tanchor,
yaml_char_ttag,
yaml_char_tvalue,
int length,
int plain_implicit,
int quoted_implicit,
yaml_scalar_style_t style 
)
+
+
+ +

Create a SCALAR event.

+

The style argument may be ignored by the emitter.

+

Either the tag attribute or one of the plain_implicit and quoted_implicit flags must be set.

+
Parameters:
+ + + + + + + + + +
[out]eventAn empty event object.
[in]anchorThe scalar anchor or NULL.
[in]tagThe scalar tag or NULL.
[in]valueThe scalar value.
[in]lengthThe length of the scalar value.
[in]plain_implicitIf the tag may be omitted for the plain style.
[in]quoted_implicitIf the tag may be omitted for any non-plain style.
[in]styleThe scalar style.
+
+
+
Returns:
1 if the function succeeded, 0 on error.
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
int yaml_sequence_start_event_initialize (yaml_event_tevent,
yaml_char_tanchor,
yaml_char_ttag,
int implicit,
yaml_sequence_style_t style 
)
+
+
+ +

Create a SEQUENCE-START event.

+

The style argument may be ignored by the emitter.

+

Either the tag attribute or the implicit flag must be set.

+
Parameters:
+ + + + + + +
[out]eventAn empty event object.
[in]anchorThe sequence anchor or NULL.
[in]tagThe sequence tag or NULL.
[in]implicitIf the tag may be omitted.
[in]styleThe sequence style.
+
+
+
Returns:
1 if the function succeeded, 0 on error.
+ +
+
+ +
+
+ + + + + + + + +
int yaml_sequence_end_event_initialize (yaml_event_tevent)
+
+
+ +

Create a SEQUENCE-END event.

+
Parameters:
+ + +
[out]eventAn empty event object.
+
+
+
Returns:
1 if the function succeeded, 0 on error.
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
int yaml_mapping_start_event_initialize (yaml_event_tevent,
yaml_char_tanchor,
yaml_char_ttag,
int implicit,
yaml_mapping_style_t style 
)
+
+
+ +

Create a MAPPING-START event.

+

The style argument may be ignored by the emitter.

+

Either the tag attribute or the implicit flag must be set.

+
Parameters:
+ + + + + + +
[out]eventAn empty event object.
[in]anchorThe mapping anchor or NULL.
[in]tagThe mapping tag or NULL.
[in]implicitIf the tag may be omitted.
[in]styleThe mapping style.
+
+
+
Returns:
1 if the function succeeded, 0 on error.
+ +
+
+ +
+
+ + + + + + + + +
int yaml_mapping_end_event_initialize (yaml_event_tevent)
+
+
+ +

Create a MAPPING-END event.

+
Parameters:
+ + +
[out]eventAn empty event object.
+
+
+
Returns:
1 if the function succeeded, 0 on error.
+ +
+
+ +
+
+ + + + + + + + +
void yaml_event_delete (yaml_event_tevent)
+
+
+ +

Free any memory allocated for an event object.

+
Parameters:
+ + +
[in,out]eventAn event object.
+
+
+ +
+
+
+ + + + + + diff --git a/web/server/h2o/libh2o/deps/yaml/doc/html/group__export.html b/web/server/h2o/libh2o/deps/yaml/doc/html/group__export.html new file mode 100644 index 00000000..e8aa4030 --- /dev/null +++ b/web/server/h2o/libh2o/deps/yaml/doc/html/group__export.html @@ -0,0 +1,91 @@ + + + + + +yaml: Export Definitions + + + + + + + + +
+ + +
+ + + + + + + + + + + +
+
yaml +  0.1.6 +
+ +
+
+ + + +
+
+ +
+
Export Definitions
+
+
+ + + + +

+Defines

#define YAML_DECLARE(type)   type
 The public API declaration.
+

Define Documentation

+ +
+
+ + + + + + + + +
#define YAML_DECLARE( type)   type
+
+
+ +

The public API declaration.

+ +
+
+
+ + + + + + diff --git a/web/server/h2o/libh2o/deps/yaml/doc/html/group__nodes.html b/web/server/h2o/libh2o/deps/yaml/doc/html/group__nodes.html new file mode 100644 index 00000000..092ab87c --- /dev/null +++ b/web/server/h2o/libh2o/deps/yaml/doc/html/group__nodes.html @@ -0,0 +1,824 @@ + + + + + +yaml: Nodes + + + + + + + + +
+ + +
+ + + + + + + + + + + +
+
yaml +  0.1.6 +
+ +
+
+ + + +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Data Structures

struct  yaml_node_pair_s
 An element of a mapping node. More...
struct  yaml_node_s
 The node structure. More...
struct  yaml_document_s
 The document structure. More...

+Defines

#define YAML_NULL_TAG   "tag:yaml.org,2002:null"
 The tag !!null with the only possible value: null.
#define YAML_BOOL_TAG   "tag:yaml.org,2002:bool"
 The tag !!bool with the values: true and falce.
#define YAML_STR_TAG   "tag:yaml.org,2002:str"
 The tag !!str for string values.
#define YAML_INT_TAG   "tag:yaml.org,2002:int"
 The tag !!int for integer values.
#define YAML_FLOAT_TAG   "tag:yaml.org,2002:float"
 The tag !!float for float values.
#define YAML_TIMESTAMP_TAG   "tag:yaml.org,2002:timestamp"
 The tag !!timestamp for date and time values.
#define YAML_SEQ_TAG   "tag:yaml.org,2002:seq"
 The tag !!seq is used to denote sequences.
#define YAML_MAP_TAG   "tag:yaml.org,2002:map"
 The tag !!map is used to denote mapping.
#define YAML_DEFAULT_SCALAR_TAG   YAML_STR_TAG
 The default scalar tag is !!str.
#define YAML_DEFAULT_SEQUENCE_TAG   YAML_SEQ_TAG
 The default sequence tag is !!seq.
#define YAML_DEFAULT_MAPPING_TAG   YAML_MAP_TAG
 The default mapping tag is !!map.

+Typedefs

typedef enum yaml_node_type_e yaml_node_type_t
 Node types.
typedef struct yaml_node_s yaml_node_t
 The forward definition of a document node structure.
typedef int yaml_node_item_t
 An element of a sequence node.
typedef struct yaml_node_pair_s yaml_node_pair_t
 An element of a mapping node.
typedef struct yaml_document_s yaml_document_t
 The document structure.

+Enumerations

enum  yaml_node_type_e {
+  YAML_NO_NODE, +
+  YAML_SCALAR_NODE, +
+  YAML_SEQUENCE_NODE, +
+  YAML_MAPPING_NODE +
+ }
 Node types. More...

+Functions

int yaml_document_initialize (yaml_document_t *document, yaml_version_directive_t *version_directive, yaml_tag_directive_t *tag_directives_start, yaml_tag_directive_t *tag_directives_end, int start_implicit, int end_implicit)
 Create a YAML document.
void yaml_document_delete (yaml_document_t *document)
 Delete a YAML document and all its nodes.
yaml_node_tyaml_document_get_node (yaml_document_t *document, int index)
 Get a node of a YAML document.
yaml_node_tyaml_document_get_root_node (yaml_document_t *document)
 Get the root of a YAML document node.
int yaml_document_add_scalar (yaml_document_t *document, yaml_char_t *tag, yaml_char_t *value, int length, yaml_scalar_style_t style)
 Create a SCALAR node and attach it to the document.
int yaml_document_add_sequence (yaml_document_t *document, yaml_char_t *tag, yaml_sequence_style_t style)
 Create a SEQUENCE node and attach it to the document.
int yaml_document_add_mapping (yaml_document_t *document, yaml_char_t *tag, yaml_mapping_style_t style)
 Create a MAPPING node and attach it to the document.
int yaml_document_append_sequence_item (yaml_document_t *document, int sequence, int item)
 Add an item to a SEQUENCE node.
int yaml_document_append_mapping_pair (yaml_document_t *document, int mapping, int key, int value)
 Add a pair of a key and a value to a MAPPING node.
+

Define Documentation

+ +
+
+ + + + +
#define YAML_NULL_TAG   "tag:yaml.org,2002:null"
+
+
+ +

The tag !!null with the only possible value: null.

+ +
+
+ +
+
+ + + + +
#define YAML_BOOL_TAG   "tag:yaml.org,2002:bool"
+
+
+ +

The tag !!bool with the values: true and falce.

+ +
+
+ +
+
+ + + + +
#define YAML_STR_TAG   "tag:yaml.org,2002:str"
+
+
+ +

The tag !!str for string values.

+ +
+
+ +
+
+ + + + +
#define YAML_INT_TAG   "tag:yaml.org,2002:int"
+
+
+ +

The tag !!int for integer values.

+ +
+
+ +
+
+ + + + +
#define YAML_FLOAT_TAG   "tag:yaml.org,2002:float"
+
+
+ +

The tag !!float for float values.

+ +
+
+ +
+
+ + + + +
#define YAML_TIMESTAMP_TAG   "tag:yaml.org,2002:timestamp"
+
+
+ +

The tag !!timestamp for date and time values.

+ +
+
+ +
+
+ + + + +
#define YAML_SEQ_TAG   "tag:yaml.org,2002:seq"
+
+
+ +

The tag !!seq is used to denote sequences.

+ +
+
+ +
+
+ + + + +
#define YAML_MAP_TAG   "tag:yaml.org,2002:map"
+
+
+ +

The tag !!map is used to denote mapping.

+ +
+
+ +
+
+ + + + +
#define YAML_DEFAULT_SCALAR_TAG   YAML_STR_TAG
+
+
+ +

The default scalar tag is !!str.

+ +
+
+ +
+
+ + + + +
#define YAML_DEFAULT_SEQUENCE_TAG   YAML_SEQ_TAG
+
+
+ +

The default sequence tag is !!seq.

+ +
+
+ +
+
+ + + + +
#define YAML_DEFAULT_MAPPING_TAG   YAML_MAP_TAG
+
+
+ +

The default mapping tag is !!map.

+ +
+
+

Typedef Documentation

+ +
+
+ + + + +
typedef enum yaml_node_type_e yaml_node_type_t
+
+
+ +

Node types.

+ +
+
+ +
+
+ + + + +
typedef struct yaml_node_s yaml_node_t
+
+
+ +

The forward definition of a document node structure.

+ +
+
+ +
+
+ + + + +
typedef int yaml_node_item_t
+
+
+ +

An element of a sequence node.

+ +
+
+ +
+
+ + + + +
typedef struct yaml_node_pair_s yaml_node_pair_t
+
+
+ +

An element of a mapping node.

+ +
+
+ +
+
+ + + + +
typedef struct yaml_document_s yaml_document_t
+
+
+ +

The document structure.

+ +
+
+

Enumeration Type Documentation

+ +
+
+ + + + +
enum yaml_node_type_e
+
+
+ +

Node types.

+
Enumerator:
+ + + + +
YAML_NO_NODE  +

An empty node.

+
YAML_SCALAR_NODE  +

A scalar node.

+
YAML_SEQUENCE_NODE  +

A sequence node.

+
YAML_MAPPING_NODE  +

A mapping node.

+
+
+
+ +
+
+

Function Documentation

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
int yaml_document_initialize (yaml_document_tdocument,
yaml_version_directive_tversion_directive,
yaml_tag_directive_ttag_directives_start,
yaml_tag_directive_ttag_directives_end,
int start_implicit,
int end_implicit 
)
+
+
+ +

Create a YAML document.

+
Parameters:
+ + + + + + + +
[out]documentAn empty document object.
[in]version_directiveThe YAML directive value or NULL.
[in]tag_directives_startThe beginning of the TAG directives list.
[in]tag_directives_endThe end of the TAG directives list.
[in]start_implicitIf the document start indicator is implicit.
[in]end_implicitIf the document end indicator is implicit.
+
+
+
Returns:
1 if the function succeeded, 0 on error.
+ +
+
+ +
+
+ + + + + + + + +
void yaml_document_delete (yaml_document_tdocument)
+
+
+ +

Delete a YAML document and all its nodes.

+
Parameters:
+ + +
[in,out]documentA document object.
+
+
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + +
yaml_node_t* yaml_document_get_node (yaml_document_tdocument,
int index 
)
+
+
+ +

Get a node of a YAML document.

+

The pointer returned by this function is valid until any of the functions modifying the documents are called.

+
Parameters:
+ + + +
[in]documentA document object.
[in]indexThe node id.
+
+
+
Returns:
the node objct or NULL if node_id is out of range.
+ +
+
+ +
+
+ + + + + + + + +
yaml_node_t* yaml_document_get_root_node (yaml_document_tdocument)
+
+
+ +

Get the root of a YAML document node.

+

The root object is the first object added to the document.

+

The pointer returned by this function is valid until any of the functions modifying the documents are called.

+

An empty document produced by the parser signifies the end of a YAML stream.

+
Parameters:
+ + +
[in]documentA document object.
+
+
+
Returns:
the node object or NULL if the document is empty.
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
int yaml_document_add_scalar (yaml_document_tdocument,
yaml_char_ttag,
yaml_char_tvalue,
int length,
yaml_scalar_style_t style 
)
+
+
+ +

Create a SCALAR node and attach it to the document.

+

The style argument may be ignored by the emitter.

+
Parameters:
+ + + + + + +
[in,out]documentA document object.
[in]tagThe scalar tag.
[in]valueThe scalar value.
[in]lengthThe length of the scalar value.
[in]styleThe scalar style.
+
+
+
Returns:
the node id or 0 on error.
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
int yaml_document_add_sequence (yaml_document_tdocument,
yaml_char_ttag,
yaml_sequence_style_t style 
)
+
+
+ +

Create a SEQUENCE node and attach it to the document.

+

The style argument may be ignored by the emitter.

+
Parameters:
+ + + + +
[in,out]documentA document object.
[in]tagThe sequence tag.
[in]styleThe sequence style.
+
+
+
Returns:
the node id or 0 on error.
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
int yaml_document_add_mapping (yaml_document_tdocument,
yaml_char_ttag,
yaml_mapping_style_t style 
)
+
+
+ +

Create a MAPPING node and attach it to the document.

+

The style argument may be ignored by the emitter.

+
Parameters:
+ + + + +
[in,out]documentA document object.
[in]tagThe sequence tag.
[in]styleThe sequence style.
+
+
+
Returns:
the node id or 0 on error.
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
int yaml_document_append_sequence_item (yaml_document_tdocument,
int sequence,
int item 
)
+
+
+ +

Add an item to a SEQUENCE node.

+
Parameters:
+ + + + +
[in,out]documentA document object.
[in]sequenceThe sequence node id.
[in]itemThe item node id.
+
+
+
Returns:
1 if the function succeeded, 0 on error.
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
int yaml_document_append_mapping_pair (yaml_document_tdocument,
int mapping,
int key,
int value 
)
+
+
+ +

Add a pair of a key and a value to a MAPPING node.

+
Parameters:
+ + + + + +
[in,out]documentA document object.
[in]mappingThe mapping node id.
[in]keyThe key node id.
[in]valueThe value node id.
+
+
+
Returns:
1 if the function succeeded, 0 on error.
+ +
+
+
+ + + + + + diff --git a/web/server/h2o/libh2o/deps/yaml/doc/html/group__parser.html b/web/server/h2o/libh2o/deps/yaml/doc/html/group__parser.html new file mode 100644 index 00000000..d8255920 --- /dev/null +++ b/web/server/h2o/libh2o/deps/yaml/doc/html/group__parser.html @@ -0,0 +1,635 @@ + + + + + +yaml: Parser Definitions + + + + + + + + +
+ + +
+ + + + + + + + + + + +
+
yaml +  0.1.6 +
+ +
+
+ + + +
+
+ +
+
Parser Definitions
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Data Structures

struct  yaml_simple_key_s
 This structure holds information about a potential simple key. More...
struct  yaml_alias_data_s
 This structure holds aliases data. More...
struct  yaml_parser_s
 The parser structure. More...

+Typedefs

typedef int yaml_read_handler_t (void *data, unsigned char *buffer, size_t size, size_t *size_read)
 The prototype of a read handler.
+typedef struct yaml_simple_key_s yaml_simple_key_t
 This structure holds information about a potential simple key.
+typedef enum yaml_parser_state_e yaml_parser_state_t
 The states of the parser.
+typedef struct yaml_alias_data_s yaml_alias_data_t
 This structure holds aliases data.
typedef struct yaml_parser_s yaml_parser_t
 The parser structure.

+Enumerations

enum  yaml_parser_state_e {
+  YAML_PARSE_STREAM_START_STATE, +
+  YAML_PARSE_IMPLICIT_DOCUMENT_START_STATE, +
+  YAML_PARSE_DOCUMENT_START_STATE, +
+  YAML_PARSE_DOCUMENT_CONTENT_STATE, +
+  YAML_PARSE_DOCUMENT_END_STATE, +
+  YAML_PARSE_BLOCK_NODE_STATE, +
+  YAML_PARSE_BLOCK_NODE_OR_INDENTLESS_SEQUENCE_STATE, +
+  YAML_PARSE_FLOW_NODE_STATE, +
+  YAML_PARSE_BLOCK_SEQUENCE_FIRST_ENTRY_STATE, +
+  YAML_PARSE_BLOCK_SEQUENCE_ENTRY_STATE, +
+  YAML_PARSE_INDENTLESS_SEQUENCE_ENTRY_STATE, +
+  YAML_PARSE_BLOCK_MAPPING_FIRST_KEY_STATE, +
+  YAML_PARSE_BLOCK_MAPPING_KEY_STATE, +
+  YAML_PARSE_BLOCK_MAPPING_VALUE_STATE, +
+  YAML_PARSE_FLOW_SEQUENCE_FIRST_ENTRY_STATE, +
+  YAML_PARSE_FLOW_SEQUENCE_ENTRY_STATE, +
+  YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_KEY_STATE, +
+  YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_VALUE_STATE, +
+  YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_END_STATE, +
+  YAML_PARSE_FLOW_MAPPING_FIRST_KEY_STATE, +
+  YAML_PARSE_FLOW_MAPPING_KEY_STATE, +
+  YAML_PARSE_FLOW_MAPPING_VALUE_STATE, +
+  YAML_PARSE_FLOW_MAPPING_EMPTY_VALUE_STATE, +
+  YAML_PARSE_END_STATE +
+ }
 The states of the parser. More...

+Functions

int yaml_parser_initialize (yaml_parser_t *parser)
 Initialize a parser.
void yaml_parser_delete (yaml_parser_t *parser)
 Destroy a parser.
void yaml_parser_set_input_string (yaml_parser_t *parser, const unsigned char *input, size_t size)
 Set a string input.
void yaml_parser_set_input_file (yaml_parser_t *parser, FILE *file)
 Set a file input.
void yaml_parser_set_input (yaml_parser_t *parser, yaml_read_handler_t *handler, void *data)
 Set a generic input handler.
void yaml_parser_set_encoding (yaml_parser_t *parser, yaml_encoding_t encoding)
 Set the source encoding.
int yaml_parser_scan (yaml_parser_t *parser, yaml_token_t *token)
 Scan the input stream and produce the next token.
int yaml_parser_parse (yaml_parser_t *parser, yaml_event_t *event)
 Parse the input stream and produce the next parsing event.
int yaml_parser_load (yaml_parser_t *parser, yaml_document_t *document)
 Parse the input stream and produce the next YAML document.
+

Typedef Documentation

+ +
+
+ + + + +
typedef int yaml_read_handler_t(void *data, unsigned char *buffer, size_t size, size_t *size_read)
+
+
+ +

The prototype of a read handler.

+

The read handler is called when the parser needs to read more bytes from the source. The handler should write not more than size bytes to the buffer. The number of written bytes should be set to the length variable.

+
Parameters:
+ + + + + +
[in,out]dataA pointer to an application data specified by yaml_parser_set_input().
[out]bufferThe buffer to write the data from the source.
[in]sizeThe size of the buffer.
[out]size_readThe actual number of bytes read from the source.
+
+
+
Returns:
On success, the handler should return 1. If the handler failed, the returned value should be 0. On EOF, the handler should set the size_read to 0 and return 1.
+ +
+
+ +
+
+ + + + +
typedef struct yaml_parser_s yaml_parser_t
+
+
+ +

The parser structure.

+

All members are internal. Manage the structure using the yaml_parser_ family of functions.

+ +
+
+

Enumeration Type Documentation

+ +
+
+ + + + +
enum yaml_parser_state_e
+
+
+ +

The states of the parser.

+
Enumerator:
+ + + + + + + + + + + + + + + + + + + + + + + + +
YAML_PARSE_STREAM_START_STATE  +

Expect STREAM-START.

+
YAML_PARSE_IMPLICIT_DOCUMENT_START_STATE  +

Expect the beginning of an implicit document.

+
YAML_PARSE_DOCUMENT_START_STATE  +

Expect DOCUMENT-START.

+
YAML_PARSE_DOCUMENT_CONTENT_STATE  +

Expect the content of a document.

+
YAML_PARSE_DOCUMENT_END_STATE  +

Expect DOCUMENT-END.

+
YAML_PARSE_BLOCK_NODE_STATE  +

Expect a block node.

+
YAML_PARSE_BLOCK_NODE_OR_INDENTLESS_SEQUENCE_STATE  +

Expect a block node or indentless sequence.

+
YAML_PARSE_FLOW_NODE_STATE  +

Expect a flow node.

+
YAML_PARSE_BLOCK_SEQUENCE_FIRST_ENTRY_STATE  +

Expect the first entry of a block sequence.

+
YAML_PARSE_BLOCK_SEQUENCE_ENTRY_STATE  +

Expect an entry of a block sequence.

+
YAML_PARSE_INDENTLESS_SEQUENCE_ENTRY_STATE  +

Expect an entry of an indentless sequence.

+
YAML_PARSE_BLOCK_MAPPING_FIRST_KEY_STATE  +

Expect the first key of a block mapping.

+
YAML_PARSE_BLOCK_MAPPING_KEY_STATE  +

Expect a block mapping key.

+
YAML_PARSE_BLOCK_MAPPING_VALUE_STATE  +

Expect a block mapping value.

+
YAML_PARSE_FLOW_SEQUENCE_FIRST_ENTRY_STATE  +

Expect the first entry of a flow sequence.

+
YAML_PARSE_FLOW_SEQUENCE_ENTRY_STATE  +

Expect an entry of a flow sequence.

+
YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_KEY_STATE  +

Expect a key of an ordered mapping.

+
YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_VALUE_STATE  +

Expect a value of an ordered mapping.

+
YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_END_STATE  +

Expect the and of an ordered mapping entry.

+
YAML_PARSE_FLOW_MAPPING_FIRST_KEY_STATE  +

Expect the first key of a flow mapping.

+
YAML_PARSE_FLOW_MAPPING_KEY_STATE  +

Expect a key of a flow mapping.

+
YAML_PARSE_FLOW_MAPPING_VALUE_STATE  +

Expect a value of a flow mapping.

+
YAML_PARSE_FLOW_MAPPING_EMPTY_VALUE_STATE  +

Expect an empty value of a flow mapping.

+
YAML_PARSE_END_STATE  +

Expect nothing.

+
+
+
+ +
+
+

Function Documentation

+ +
+
+ + + + + + + + +
int yaml_parser_initialize (yaml_parser_tparser)
+
+
+ +

Initialize a parser.

+

This function creates a new parser object. An application is responsible for destroying the object using the yaml_parser_delete() function.

+
Parameters:
+ + +
[out]parserAn empty parser object.
+
+
+
Returns:
1 if the function succeeded, 0 on error.
+ +
+
+ +
+
+ + + + + + + + +
void yaml_parser_delete (yaml_parser_tparser)
+
+
+ +

Destroy a parser.

+
Parameters:
+ + +
[in,out]parserA parser object.
+
+
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
void yaml_parser_set_input_string (yaml_parser_tparser,
const unsigned char * input,
size_t size 
)
+
+
+ +

Set a string input.

+

Note that the input pointer must be valid while the parser object exists. The application is responsible for destroing input after destroying the parser.

+
Parameters:
+ + + + +
[in,out]parserA parser object.
[in]inputA source data.
[in]sizeThe length of the source data in bytes.
+
+
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + +
void yaml_parser_set_input_file (yaml_parser_tparser,
FILE * file 
)
+
+
+ +

Set a file input.

+

file should be a file object open for reading. The application is responsible for closing the file.

+
Parameters:
+ + + +
[in,out]parserA parser object.
[in]fileAn open file.
+
+
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
void yaml_parser_set_input (yaml_parser_tparser,
yaml_read_handler_thandler,
void * data 
)
+
+
+ +

Set a generic input handler.

+
Parameters:
+ + + + +
[in,out]parserA parser object.
[in]handlerA read handler.
[in]dataAny application data for passing to the read handler.
+
+
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + +
void yaml_parser_set_encoding (yaml_parser_tparser,
yaml_encoding_t encoding 
)
+
+
+ +

Set the source encoding.

+
Parameters:
+ + + +
[in,out]parserA parser object.
[in]encodingThe source encoding.
+
+
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + +
int yaml_parser_scan (yaml_parser_tparser,
yaml_token_ttoken 
)
+
+
+ +

Scan the input stream and produce the next token.

+

Call the function subsequently to produce a sequence of tokens corresponding to the input stream. The initial token has the type YAML_STREAM_START_TOKEN while the ending token has the type YAML_STREAM_END_TOKEN.

+

An application is responsible for freeing any buffers associated with the produced token object using the yaml_token_delete function.

+

An application must not alternate the calls of yaml_parser_scan() with the calls of yaml_parser_parse() or yaml_parser_load(). Doing this will break the parser.

+
Parameters:
+ + + +
[in,out]parserA parser object.
[out]tokenAn empty token object.
+
+
+
Returns:
1 if the function succeeded, 0 on error.
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + +
int yaml_parser_parse (yaml_parser_tparser,
yaml_event_tevent 
)
+
+
+ +

Parse the input stream and produce the next parsing event.

+

Call the function subsequently to produce a sequence of events corresponding to the input stream. The initial event has the type YAML_STREAM_START_EVENT while the ending event has the type YAML_STREAM_END_EVENT.

+

An application is responsible for freeing any buffers associated with the produced event object using the yaml_event_delete() function.

+

An application must not alternate the calls of yaml_parser_parse() with the calls of yaml_parser_scan() or yaml_parser_load(). Doing this will break the parser.

+
Parameters:
+ + + +
[in,out]parserA parser object.
[out]eventAn empty event object.
+
+
+
Returns:
1 if the function succeeded, 0 on error.
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + +
int yaml_parser_load (yaml_parser_tparser,
yaml_document_tdocument 
)
+
+
+ +

Parse the input stream and produce the next YAML document.

+

Call this function subsequently to produce a sequence of documents constituting the input stream.

+

If the produced document has no root node, it means that the document end has been reached.

+

An application is responsible for freeing any data associated with the produced document object using the yaml_document_delete() function.

+

An application must not alternate the calls of yaml_parser_load() with the calls of yaml_parser_scan() or yaml_parser_parse(). Doing this will break the parser.

+
Parameters:
+ + + +
[in,out]parserA parser object.
[out]documentAn empty document object.
+
+
+
Returns:
1 if the function succeeded, 0 on error.
+ +
+
+
+ + + + + + diff --git a/web/server/h2o/libh2o/deps/yaml/doc/html/group__styles.html b/web/server/h2o/libh2o/deps/yaml/doc/html/group__styles.html new file mode 100644 index 00000000..4565ca92 --- /dev/null +++ b/web/server/h2o/libh2o/deps/yaml/doc/html/group__styles.html @@ -0,0 +1,251 @@ + + + + + +yaml: Node Styles + + + + + + + + +
+ + +
+ + + + + + + + + + + +
+
yaml +  0.1.6 +
+ +
+
+ + + +
+
+ +
+
Node Styles
+
+
+ + + + + + + + + + + + + + + +

+Typedefs

typedef enum yaml_scalar_style_e yaml_scalar_style_t
 Scalar styles.
typedef enum yaml_sequence_style_e yaml_sequence_style_t
 Sequence styles.
typedef enum yaml_mapping_style_e yaml_mapping_style_t
 Mapping styles.

+Enumerations

enum  yaml_scalar_style_e {
+  YAML_ANY_SCALAR_STYLE, +
+  YAML_PLAIN_SCALAR_STYLE, +
+  YAML_SINGLE_QUOTED_SCALAR_STYLE, +
+  YAML_DOUBLE_QUOTED_SCALAR_STYLE, +
+  YAML_LITERAL_SCALAR_STYLE, +
+  YAML_FOLDED_SCALAR_STYLE +
+ }
 Scalar styles. More...
enum  yaml_sequence_style_e {
+  YAML_ANY_SEQUENCE_STYLE, +
+  YAML_BLOCK_SEQUENCE_STYLE, +
+  YAML_FLOW_SEQUENCE_STYLE +
+ }
 Sequence styles. More...
enum  yaml_mapping_style_e {
+  YAML_ANY_MAPPING_STYLE, +
+  YAML_BLOCK_MAPPING_STYLE, +
+  YAML_FLOW_MAPPING_STYLE +
+ }
 Mapping styles. More...
+

Typedef Documentation

+ +
+
+ + + + +
typedef enum yaml_scalar_style_e yaml_scalar_style_t
+
+
+ +

Scalar styles.

+ +
+
+ +
+ +
+ +

Sequence styles.

+ +
+
+ +
+
+ + + + +
typedef enum yaml_mapping_style_e yaml_mapping_style_t
+
+
+ +

Mapping styles.

+ +
+
+

Enumeration Type Documentation

+ +
+
+ + + + +
enum yaml_scalar_style_e
+
+
+ +

Scalar styles.

+
Enumerator:
+ + + + + + +
YAML_ANY_SCALAR_STYLE  +

Let the emitter choose the style.

+
YAML_PLAIN_SCALAR_STYLE  +

The plain scalar style.

+
YAML_SINGLE_QUOTED_SCALAR_STYLE  +

The single-quoted scalar style.

+
YAML_DOUBLE_QUOTED_SCALAR_STYLE  +

The double-quoted scalar style.

+
YAML_LITERAL_SCALAR_STYLE  +

The literal scalar style.

+
YAML_FOLDED_SCALAR_STYLE  +

The folded scalar style.

+
+
+
+ +
+
+ +
+
+ + + + +
enum yaml_sequence_style_e
+
+
+ +

Sequence styles.

+
Enumerator:
+ + + +
YAML_ANY_SEQUENCE_STYLE  +

Let the emitter choose the style.

+
YAML_BLOCK_SEQUENCE_STYLE  +

The block sequence style.

+
YAML_FLOW_SEQUENCE_STYLE  +

The flow sequence style.

+
+
+
+ +
+
+ +
+
+ + + + +
enum yaml_mapping_style_e
+
+
+ +

Mapping styles.

+
Enumerator:
+ + + +
YAML_ANY_MAPPING_STYLE  +

Let the emitter choose the style.

+
YAML_BLOCK_MAPPING_STYLE  +

The block mapping style.

+
YAML_FLOW_MAPPING_STYLE  +

The flow mapping style.

+
+
+
+ +
+
+
+ + + + + + diff --git a/web/server/h2o/libh2o/deps/yaml/doc/html/group__tokens.html b/web/server/h2o/libh2o/deps/yaml/doc/html/group__tokens.html new file mode 100644 index 00000000..b33d28c8 --- /dev/null +++ b/web/server/h2o/libh2o/deps/yaml/doc/html/group__tokens.html @@ -0,0 +1,276 @@ + + + + + +yaml: Tokens + + + + + + + + +
+ + +
+ + + + + + + + + + + +
+
yaml +  0.1.6 +
+ +
+
+ + + +
+ +
+ + + + + + + + + + + + + + + +

+Data Structures

struct  yaml_token_s
 The token structure. More...

+Typedefs

typedef enum yaml_token_type_e yaml_token_type_t
 Token types.
typedef struct yaml_token_s yaml_token_t
 The token structure.

+Enumerations

enum  yaml_token_type_e {
+  YAML_NO_TOKEN, +
+  YAML_STREAM_START_TOKEN, +
+  YAML_STREAM_END_TOKEN, +
+  YAML_VERSION_DIRECTIVE_TOKEN, +
+  YAML_TAG_DIRECTIVE_TOKEN, +
+  YAML_DOCUMENT_START_TOKEN, +
+  YAML_DOCUMENT_END_TOKEN, +
+  YAML_BLOCK_SEQUENCE_START_TOKEN, +
+  YAML_BLOCK_MAPPING_START_TOKEN, +
+  YAML_BLOCK_END_TOKEN, +
+  YAML_FLOW_SEQUENCE_START_TOKEN, +
+  YAML_FLOW_SEQUENCE_END_TOKEN, +
+  YAML_FLOW_MAPPING_START_TOKEN, +
+  YAML_FLOW_MAPPING_END_TOKEN, +
+  YAML_BLOCK_ENTRY_TOKEN, +
+  YAML_FLOW_ENTRY_TOKEN, +
+  YAML_KEY_TOKEN, +
+  YAML_VALUE_TOKEN, +
+  YAML_ALIAS_TOKEN, +
+  YAML_ANCHOR_TOKEN, +
+  YAML_TAG_TOKEN, +
+  YAML_SCALAR_TOKEN +
+ }
 Token types. More...

+Functions

void yaml_token_delete (yaml_token_t *token)
 Free any memory allocated for a token object.
+

Typedef Documentation

+ +
+
+ + + + +
typedef enum yaml_token_type_e yaml_token_type_t
+
+
+ +

Token types.

+ +
+
+ +
+
+ + + + +
typedef struct yaml_token_s yaml_token_t
+
+
+ +

The token structure.

+ +
+
+

Enumeration Type Documentation

+ +
+
+ + + + +
enum yaml_token_type_e
+
+
+ +

Token types.

+
Enumerator:
+ + + + + + + + + + + + + + + + + + + + + + +
YAML_NO_TOKEN  +

An empty token.

+
YAML_STREAM_START_TOKEN  +

A STREAM-START token.

+
YAML_STREAM_END_TOKEN  +

A STREAM-END token.

+
YAML_VERSION_DIRECTIVE_TOKEN  +

A VERSION-DIRECTIVE token.

+
YAML_TAG_DIRECTIVE_TOKEN  +

A TAG-DIRECTIVE token.

+
YAML_DOCUMENT_START_TOKEN  +

A DOCUMENT-START token.

+
YAML_DOCUMENT_END_TOKEN  +

A DOCUMENT-END token.

+
YAML_BLOCK_SEQUENCE_START_TOKEN  +

A BLOCK-SEQUENCE-START token.

+
YAML_BLOCK_MAPPING_START_TOKEN  +

A BLOCK-SEQUENCE-END token.

+
YAML_BLOCK_END_TOKEN  +

A BLOCK-END token.

+
YAML_FLOW_SEQUENCE_START_TOKEN  +

A FLOW-SEQUENCE-START token.

+
YAML_FLOW_SEQUENCE_END_TOKEN  +

A FLOW-SEQUENCE-END token.

+
YAML_FLOW_MAPPING_START_TOKEN  +

A FLOW-MAPPING-START token.

+
YAML_FLOW_MAPPING_END_TOKEN  +

A FLOW-MAPPING-END token.

+
YAML_BLOCK_ENTRY_TOKEN  +

A BLOCK-ENTRY token.

+
YAML_FLOW_ENTRY_TOKEN  +

A FLOW-ENTRY token.

+
YAML_KEY_TOKEN  +

A KEY token.

+
YAML_VALUE_TOKEN  +

A VALUE token.

+
YAML_ALIAS_TOKEN  +

An ALIAS token.

+
YAML_ANCHOR_TOKEN  +

An ANCHOR token.

+
YAML_TAG_TOKEN  +

A TAG token.

+
YAML_SCALAR_TOKEN  +

A SCALAR token.

+
+
+
+ +
+
+

Function Documentation

+ +
+
+ + + + + + + + +
void yaml_token_delete (yaml_token_ttoken)
+
+
+ +

Free any memory allocated for a token object.

+
Parameters:
+ + +
[in,out]tokenA token object.
+
+
+ +
+
+
+ + + + + + diff --git a/web/server/h2o/libh2o/deps/yaml/doc/html/group__version.html b/web/server/h2o/libh2o/deps/yaml/doc/html/group__version.html new file mode 100644 index 00000000..c2612e64 --- /dev/null +++ b/web/server/h2o/libh2o/deps/yaml/doc/html/group__version.html @@ -0,0 +1,137 @@ + + + + + +yaml: Version Information + + + + + + + + +
+ + +
+ + + + + + + + + + + +
+
yaml +  0.1.6 +
+ +
+
+ + + +
+
+ +
+
Version Information
+
+
+ + + + + + +

+Functions

const char * yaml_get_version_string (void)
 Get the library version as a string.
void yaml_get_version (int *major, int *minor, int *patch)
 Get the library version numbers.
+

Function Documentation

+ +
+
+ + + + + + + + +
const char* yaml_get_version_string (void )
+
+
+ +

Get the library version as a string.

+
Returns:
The function returns the pointer to a static string of the form "X.Y.Z", where X is the major version number, Y is a minor version number, and Z is the patch version number.
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
void yaml_get_version (int * major,
int * minor,
int * patch 
)
+
+
+ +

Get the library version numbers.

+
Parameters:
+ + + + +
[out]majorMajor version number.
[out]minorMinor version number.
[out]patchPatch version number.
+
+
+ +
+
+
+ + + + + + diff --git a/web/server/h2o/libh2o/deps/yaml/doc/html/index.html b/web/server/h2o/libh2o/deps/yaml/doc/html/index.html new file mode 100644 index 00000000..80f4ad26 --- /dev/null +++ b/web/server/h2o/libh2o/deps/yaml/doc/html/index.html @@ -0,0 +1,63 @@ + + + + + +yaml: Main Page + + + + + + + + +
+ + +
+ + + + + + + + + + + +
+
yaml +  0.1.6 +
+ +
+
+ + + +
+
+
+
yaml Documentation
+
+
+
+ + + + + + diff --git a/web/server/h2o/libh2o/deps/yaml/doc/html/modules.html b/web/server/h2o/libh2o/deps/yaml/doc/html/modules.html new file mode 100644 index 00000000..7c47d146 --- /dev/null +++ b/web/server/h2o/libh2o/deps/yaml/doc/html/modules.html @@ -0,0 +1,74 @@ + + + + + +yaml: Modules + + + + + + + + +
+ + +
+ + + + + + + + + + + +
+
yaml +  0.1.6 +
+ +
+
+ + + +
+
+
+
Modules
+
+ + + + + + + diff --git a/web/server/h2o/libh2o/deps/yaml/doc/html/nav_f.png b/web/server/h2o/libh2o/deps/yaml/doc/html/nav_f.png new file mode 100644 index 00000000..1b07a162 Binary files /dev/null and b/web/server/h2o/libh2o/deps/yaml/doc/html/nav_f.png differ diff --git a/web/server/h2o/libh2o/deps/yaml/doc/html/nav_h.png b/web/server/h2o/libh2o/deps/yaml/doc/html/nav_h.png new file mode 100644 index 00000000..01f5fa6a Binary files /dev/null and b/web/server/h2o/libh2o/deps/yaml/doc/html/nav_h.png differ diff --git a/web/server/h2o/libh2o/deps/yaml/doc/html/open.png b/web/server/h2o/libh2o/deps/yaml/doc/html/open.png new file mode 100644 index 00000000..7b35d2c2 Binary files /dev/null and b/web/server/h2o/libh2o/deps/yaml/doc/html/open.png differ diff --git a/web/server/h2o/libh2o/deps/yaml/doc/html/structyaml__alias__data__s.html b/web/server/h2o/libh2o/deps/yaml/doc/html/structyaml__alias__data__s.html new file mode 100644 index 00000000..2e003653 --- /dev/null +++ b/web/server/h2o/libh2o/deps/yaml/doc/html/structyaml__alias__data__s.html @@ -0,0 +1,137 @@ + + + + + +yaml: yaml_alias_data_s Struct Reference + + + + + + + + +
+ + +
+ + + + + + + + + + + +
+
yaml +  0.1.6 +
+ +
+
+ + + + +
+
+ +
+
yaml_alias_data_s Struct Reference
+
+
+ +

This structure holds aliases data. + More...

+ +

#include <yaml.h>

+ + + + + + + + +

+Data Fields

yaml_char_tanchor
 The anchor.
int index
 The node id.
yaml_mark_t mark
 The anchor mark.
+

Detailed Description

+

This structure holds aliases data.

+

Field Documentation

+ +
+ +
+ +

The anchor.

+ +
+
+ +
+
+ + + + +
int yaml_alias_data_s::index
+
+
+ +

The node id.

+ +
+
+ +
+ +
+ +

The anchor mark.

+ +
+
+
The documentation for this struct was generated from the following file: +
+ + + + + + diff --git a/web/server/h2o/libh2o/deps/yaml/doc/html/structyaml__document__s.html b/web/server/h2o/libh2o/deps/yaml/doc/html/structyaml__document__s.html new file mode 100644 index 00000000..68a17184 --- /dev/null +++ b/web/server/h2o/libh2o/deps/yaml/doc/html/structyaml__document__s.html @@ -0,0 +1,264 @@ + + + + + +yaml: yaml_document_s Struct Reference + + + + + + + + +
+ + +
+ + + + + + + + + + + +
+
yaml +  0.1.6 +
+ +
+
+ + + + +
+
+ +
+
yaml_document_s Struct Reference
+
+
+ +

The document structure. + More...

+ +

#include <yaml.h>

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Data Fields

struct {
   yaml_node_t *   start
 The beginning of the stack.
   yaml_node_t *   end
 The end of the stack.
   yaml_node_t *   top
 The top of the stack.
nodes
 The document nodes.
yaml_version_directive_tversion_directive
 The version directive.
struct {
   yaml_tag_directive_t *   start
 The beginning of the tag directives list.
   yaml_tag_directive_t *   end
 The end of the tag directives list.
tag_directives
 The list of tag directives.
+int start_implicit
 Is the document start indicator implicit?
+int end_implicit
 Is the document end indicator implicit?
yaml_mark_t start_mark
 The beginning of the document.
yaml_mark_t end_mark
 The end of the document.
+

Detailed Description

+

The document structure.

+

Field Documentation

+ +
+ +
+ +

The beginning of the stack.

+ +
+
+ +
+ +
+ +

The end of the stack.

+ +
+
+ +
+ +
+ +

The top of the stack.

+ +
+
+ +
+
+ + + + +
struct { ... } yaml_document_s::nodes
+
+
+ +

The document nodes.

+ +
+
+ +
+ +
+ +

The version directive.

+ +
+
+ +
+ +
+ +

The beginning of the tag directives list.

+ +
+
+ +
+ +
+ +

The end of the tag directives list.

+ +
+
+ +
+
+ + + + +
struct { ... } yaml_document_s::tag_directives
+
+
+ +

The list of tag directives.

+ +
+
+ +
+ +
+ +

The beginning of the document.

+ +
+
+ +
+ +
+ +

The end of the document.

+ +
+
+
The documentation for this struct was generated from the following file: +
+ + + + + + diff --git a/web/server/h2o/libh2o/deps/yaml/doc/html/structyaml__emitter__s.html b/web/server/h2o/libh2o/deps/yaml/doc/html/structyaml__emitter__s.html new file mode 100644 index 00000000..4b1b0432 --- /dev/null +++ b/web/server/h2o/libh2o/deps/yaml/doc/html/structyaml__emitter__s.html @@ -0,0 +1,1321 @@ + + + + + +yaml: yaml_emitter_s Struct Reference + + + + + + + + +
+ + +
+ + + + + + + + + + + +
+
yaml +  0.1.6 +
+ +
+
+ + + + +
+
+
+
yaml_emitter_s Struct Reference
+
+
+ +

The emitter structure. + More...

+ +

#include <yaml.h>

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Data Fields

unsigned char * buffer
 The buffer pointer.
size_t size
 The buffer size.
size_t * size_written
 The number of written bytes.
struct {
   unsigned char *   buffer
 The buffer pointer.
   size_t   size
 The buffer size.
   size_t *   size_written
 The number of written bytes.
string
 String output data.
FILE * file
 File output data.
yaml_char_tstart
 The beginning of the buffer.
yaml_char_tend
 The end of the buffer.
yaml_char_tpointer
 The current position of the buffer.
yaml_char_tlast
 The last filled position of the buffer.
unsigned char * start
 The beginning of the buffer.
unsigned char * end
 The end of the buffer.
unsigned char * pointer
 The current position of the buffer.
unsigned char * last
 The last filled position of the buffer.
yaml_emitter_state_tstart
 The beginning of the stack.
yaml_emitter_state_tend
 The end of the stack.
yaml_emitter_state_ttop
 The top of the stack.
yaml_event_tstart
 The beginning of the event queue.
yaml_event_tend
 The end of the event queue.
yaml_event_thead
 The head of the event queue.
yaml_event_ttail
 The tail of the event queue.
int * start
 The beginning of the stack.
int * end
 The end of the stack.
int * top
 The top of the stack.
yaml_tag_directive_tstart
 The beginning of the list.
yaml_tag_directive_tend
 The end of the list.
yaml_tag_directive_ttop
 The top of the list.
yaml_char_tanchor
 The anchor value.
size_t anchor_length
 The anchor length.
+int alias
 Is it an alias?
yaml_char_thandle
 The tag handle.
size_t handle_length
 The tag handle length.
yaml_char_tsuffix
 The tag suffix.
size_t suffix_length
 The tag suffix length.
yaml_char_tvalue
 The scalar value.
size_t length
 The scalar length.
+int multiline
 Does the scalar contain line breaks?
+int flow_plain_allowed
 Can the scalar be expessed in the flow plain style?
+int block_plain_allowed
 Can the scalar be expressed in the block plain style?
+int single_quoted_allowed
 Can the scalar be expressed in the single quoted style?
+int block_allowed
 Can the scalar be expressed in the literal or folded styles?
yaml_scalar_style_t style
 The output style.
int references
 The number of references.
int anchor
 The anchor id.
+int serialized
 If the node has been emitted?
Error handling
yaml_error_type_t error
 Error type.
const char * problem
 Error description.
Writer stuff
yaml_write_handler_twrite_handler
 Write handler.
void * write_handler_data
 A pointer for passing to the white handler.
union {
   struct {
      unsigned char *   buffer
 The buffer pointer.
      size_t   size
 The buffer size.
      size_t *   size_written
 The number of written bytes.
   }   string
 String output data.
   FILE *   file
 File output data.
output
 Standard (string or file) output data.
struct {
   yaml_char_t *   start
 The beginning of the buffer.
   yaml_char_t *   end
 The end of the buffer.
   yaml_char_t *   pointer
 The current position of the buffer.
   yaml_char_t *   last
 The last filled position of the buffer.
buffer
 The working buffer.
struct {
   unsigned char *   start
 The beginning of the buffer.
   unsigned char *   end
 The end of the buffer.
   unsigned char *   pointer
 The current position of the buffer.
   unsigned char *   last
 The last filled position of the buffer.
raw_buffer
 The raw buffer.
yaml_encoding_t encoding
 The stream encoding.
Emitter stuff
+int canonical
 If the output is in the canonical style?
int best_indent
 The number of indentation spaces.
int best_width
 The preferred width of the output lines.
+int unicode
 Allow unescaped non-ASCII characters?
yaml_break_t line_break
 The preferred line break.
struct {
   yaml_emitter_state_t *   start
 The beginning of the stack.
   yaml_emitter_state_t *   end
 The end of the stack.
   yaml_emitter_state_t *   top
 The top of the stack.
states
 The stack of states.
yaml_emitter_state_t state
 The current emitter state.
struct {
   yaml_event_t *   start
 The beginning of the event queue.
   yaml_event_t *   end
 The end of the event queue.
   yaml_event_t *   head
 The head of the event queue.
   yaml_event_t *   tail
 The tail of the event queue.
events
 The event queue.
struct {
   int *   start
 The beginning of the stack.
   int *   end
 The end of the stack.
   int *   top
 The top of the stack.
indents
 The stack of indentation levels.
struct {
   yaml_tag_directive_t *   start
 The beginning of the list.
   yaml_tag_directive_t *   end
 The end of the list.
   yaml_tag_directive_t *   top
 The top of the list.
tag_directives
 The list of tag directives.
int indent
 The current indentation level.
int flow_level
 The current flow level.
+int root_context
 Is it the document root context?
+int sequence_context
 Is it a sequence context?
+int mapping_context
 Is it a mapping context?
+int simple_key_context
 Is it a simple mapping key context?
int line
 The current line.
int column
 The current column.
+int whitespace
 If the last character was a whitespace?
+int indention
 If the last character was an indentation character (' ', '-', '?', ':')?
+int open_ended
 If an explicit document end is required?
struct {
   yaml_char_t *   anchor
 The anchor value.
   size_t   anchor_length
 The anchor length.
   int   alias
 Is it an alias?
anchor_data
 Anchor analysis.
struct {
   yaml_char_t *   handle
 The tag handle.
   size_t   handle_length
 The tag handle length.
   yaml_char_t *   suffix
 The tag suffix.
   size_t   suffix_length
 The tag suffix length.
tag_data
 Tag analysis.
struct {
   yaml_char_t *   value
 The scalar value.
   size_t   length
 The scalar length.
   int   multiline
 Does the scalar contain line breaks?
   int   flow_plain_allowed
 Can the scalar be expessed in the flow plain style?
   int   block_plain_allowed
 Can the scalar be expressed in the block plain style?
   int   single_quoted_allowed
 Can the scalar be expressed in the single quoted style?
   int   block_allowed
 Can the scalar be expressed in the literal or folded styles?
   yaml_scalar_style_t   style
 The output style.
scalar_data
 Scalar analysis.
Dumper stuff
+int opened
 If the stream was already opened?
+int closed
 If the stream was already closed?
struct {
   int   references
 The number of references.
   int   anchor
 The anchor id.
   int   serialized
 If the node has been emitted?
anchors
 The information associated with the document nodes.
int last_anchor_id
 The last assigned anchor id.
yaml_document_tdocument
 The currently emitted document.
+

Detailed Description

+

The emitter structure.

+

All members are internal. Manage the structure using the yaml_emitter_ family of functions.

+

Field Documentation

+ +
+ +
+ +

Error type.

+ +
+
+ +
+
+ + + + +
const char* yaml_emitter_s::problem
+
+
+ +

Error description.

+ +
+
+ +
+ +
+ +

Write handler.

+ +
+
+ +
+ +
+ +

A pointer for passing to the white handler.

+ +
+
+ +
+
+ + + + +
unsigned char* yaml_emitter_s::buffer
+
+
+ +

The buffer pointer.

+ +
+
+ +
+
+ + + + +
size_t yaml_emitter_s::size
+
+
+ +

The buffer size.

+ +
+
+ +
+
+ + + + +
size_t* yaml_emitter_s::size_written
+
+
+ +

The number of written bytes.

+ +
+
+ +
+
+ + + + +
struct { ... } yaml_emitter_s::string
+
+
+ +

String output data.

+ +
+
+ +
+
+ + + + +
FILE* yaml_emitter_s::file
+
+
+ +

File output data.

+ +
+
+ +
+
+ + + + +
union { ... } yaml_emitter_s::output
+
+
+ +

Standard (string or file) output data.

+ +
+
+ +
+ +
+ +

The beginning of the buffer.

+ +
+
+ +
+ +
+ +

The end of the buffer.

+ +
+
+ +
+ +
+ +

The current position of the buffer.

+ +
+
+ +
+ +
+ +

The last filled position of the buffer.

+ +
+
+ +
+
+ + + + +
struct { ... } yaml_emitter_s::buffer
+
+
+ +

The working buffer.

+ +
+
+ +
+
+ + + + +
unsigned char* yaml_emitter_s::start
+
+
+ +

The beginning of the buffer.

+ +
+
+ +
+
+ + + + +
unsigned char* yaml_emitter_s::end
+
+
+ +

The end of the buffer.

+ +
+
+ +
+
+ + + + +
unsigned char* yaml_emitter_s::pointer
+
+
+ +

The current position of the buffer.

+ +
+
+ +
+
+ + + + +
unsigned char* yaml_emitter_s::last
+
+
+ +

The last filled position of the buffer.

+ +
+
+ +
+
+ + + + +
struct { ... } yaml_emitter_s::raw_buffer
+
+
+ +

The raw buffer.

+ +
+
+ +
+ +
+ +

The stream encoding.

+ +
+
+ +
+ +
+ +

The number of indentation spaces.

+ +
+
+ +
+ +
+ +

The preferred width of the output lines.

+ +
+
+ +
+ +
+ +

The preferred line break.

+ +
+
+ +
+ +
+ +

The beginning of the stack.

+ +
+
+ +
+ +
+ +

The end of the stack.

+ +
+
+ +
+ +
+ +

The top of the stack.

+ +
+
+ +
+
+ + + + +
struct { ... } yaml_emitter_s::states
+
+
+ +

The stack of states.

+ +
+
+ +
+ +
+ +

The current emitter state.

+ +
+
+ +
+ +
+ +

The beginning of the event queue.

+ +
+
+ +
+ +
+ +

The end of the event queue.

+ +
+
+ +
+ +
+ +

The head of the event queue.

+ +
+
+ +
+ +
+ +

The tail of the event queue.

+ +
+
+ +
+
+ + + + +
struct { ... } yaml_emitter_s::events
+
+
+ +

The event queue.

+ +
+
+ +
+
+ + + + +
int* yaml_emitter_s::start
+
+
+ +

The beginning of the stack.

+ +
+
+ +
+
+ + + + +
int* yaml_emitter_s::end
+
+
+ +

The end of the stack.

+ +
+
+ +
+
+ + + + +
int* yaml_emitter_s::top
+
+
+ +

The top of the stack.

+ +
+
+ +
+
+ + + + +
struct { ... } yaml_emitter_s::indents
+
+
+ +

The stack of indentation levels.

+ +
+
+ +
+ +
+ +

The beginning of the list.

+ +
+
+ +
+ +
+ +

The end of the list.

+ +
+
+ +
+ +
+ +

The top of the list.

+ +
+
+ +
+
+ + + + +
struct { ... } yaml_emitter_s::tag_directives
+
+
+ +

The list of tag directives.

+ +
+
+ +
+
+ + + + +
int yaml_emitter_s::indent
+
+
+ +

The current indentation level.

+ +
+
+ +
+ +
+ +

The current flow level.

+ +
+
+ +
+
+ + + + +
int yaml_emitter_s::line
+
+
+ +

The current line.

+ +
+
+ +
+
+ + + + +
int yaml_emitter_s::column
+
+
+ +

The current column.

+ +
+
+ +
+ +
+ +

The anchor value.

+ +
+
+ +
+
+ + + + +
size_t yaml_emitter_s::anchor_length
+
+
+ +

The anchor length.

+ +
+
+ +
+
+ + + + +
struct { ... } yaml_emitter_s::anchor_data
+
+
+ +

Anchor analysis.

+ +
+
+ +
+ +
+ +

The tag handle.

+ +
+
+ +
+
+ + + + +
size_t yaml_emitter_s::handle_length
+
+
+ +

The tag handle length.

+ +
+
+ +
+ +
+ +

The tag suffix.

+ +
+
+ +
+
+ + + + +
size_t yaml_emitter_s::suffix_length
+
+
+ +

The tag suffix length.

+ +
+
+ +
+
+ + + + +
struct { ... } yaml_emitter_s::tag_data
+
+
+ +

Tag analysis.

+ +
+
+ +
+ +
+ +

The scalar value.

+ +
+
+ +
+
+ + + + +
size_t yaml_emitter_s::length
+
+
+ +

The scalar length.

+ +
+
+ +
+ +
+ +

The output style.

+ +
+
+ +
+
+ + + + +
struct { ... } yaml_emitter_s::scalar_data
+
+
+ +

Scalar analysis.

+ +
+
+ +
+ +
+ +

The number of references.

+ +
+
+ +
+
+ + + + +
int yaml_emitter_s::anchor
+
+
+ +

The anchor id.

+ +
+
+ +
+
+ + + + +
struct { ... } * yaml_emitter_s::anchors
+
+
+ +

The information associated with the document nodes.

+ +
+
+ +
+ +
+ +

The last assigned anchor id.

+ +
+
+ +
+ +
+ +

The currently emitted document.

+ +
+
+
The documentation for this struct was generated from the following file: +
+ + + + + + diff --git a/web/server/h2o/libh2o/deps/yaml/doc/html/structyaml__event__s.html b/web/server/h2o/libh2o/deps/yaml/doc/html/structyaml__event__s.html new file mode 100644 index 00000000..bf94b1a3 --- /dev/null +++ b/web/server/h2o/libh2o/deps/yaml/doc/html/structyaml__event__s.html @@ -0,0 +1,525 @@ + + + + + +yaml: yaml_event_s Struct Reference + + + + + + + + +
+ + +
+ + + + + + + + + + + +
+
yaml +  0.1.6 +
+ +
+
+ + + + +
+
+ +
+
yaml_event_s Struct Reference
+
+
+ +

The event structure. + More...

+ +

#include <yaml.h>

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Data Fields

yaml_event_type_t type
 The event type.
union {
   struct {
      yaml_encoding_t   encoding
 The document encoding.
   }   stream_start
 The stream parameters (for YAML_STREAM_START_EVENT).
   struct {
      yaml_version_directive_t *   version_directive
 The version directive.
      struct {
         yaml_tag_directive_t *   start
 The beginning of the tag directives list.
         yaml_tag_directive_t *   end
 The end of the tag directives list.
      }   tag_directives
 The list of tag directives.
      int   implicit
 Is the document indicator implicit?
   }   document_start
 The document parameters (for YAML_DOCUMENT_START_EVENT).
   struct {
      int   implicit
 Is the document end indicator implicit?
   }   document_end
 The document end parameters (for YAML_DOCUMENT_END_EVENT).
   struct {
      yaml_char_t *   anchor
 The anchor.
   }   alias
 The alias parameters (for YAML_ALIAS_EVENT).
   struct {
      yaml_char_t *   anchor
 The anchor.
      yaml_char_t *   tag
 The tag.
      yaml_char_t *   value
 The scalar value.
      size_t   length
 The length of the scalar value.
      int   plain_implicit
 Is the tag optional for the plain style?
      int   quoted_implicit
 Is the tag optional for any non-plain style?
      yaml_scalar_style_t   style
 The scalar style.
   }   scalar
 The scalar parameters (for YAML_SCALAR_EVENT).
   struct {
      yaml_char_t *   anchor
 The anchor.
      yaml_char_t *   tag
 The tag.
      int   implicit
 Is the tag optional?
      yaml_sequence_style_t   style
 The sequence style.
   }   sequence_start
 The sequence parameters (for YAML_SEQUENCE_START_EVENT).
   struct {
      yaml_char_t *   anchor
 The anchor.
      yaml_char_t *   tag
 The tag.
      int   implicit
 Is the tag optional?
      yaml_mapping_style_t   style
 The mapping style.
   }   mapping_start
 The mapping parameters (for YAML_MAPPING_START_EVENT).
data
 The event data.
yaml_mark_t start_mark
 The beginning of the event.
yaml_mark_t end_mark
 The end of the event.
+

Detailed Description

+

The event structure.

+

Field Documentation

+ +
+ +
+ +

The event type.

+ +
+
+ +
+ +
+ +

The document encoding.

+ +
+
+ +
+
+ + + + +
struct { ... } yaml_event_s::stream_start
+
+
+ +

The stream parameters (for YAML_STREAM_START_EVENT).

+ +
+
+ +
+ +
+ +

The version directive.

+ +
+
+ +
+ +
+ +

The beginning of the tag directives list.

+ +
+
+ +
+ +
+ +

The end of the tag directives list.

+ +
+
+ +
+
+ + + + +
struct { ... } yaml_event_s::tag_directives
+
+
+ +

The list of tag directives.

+ +
+
+ +
+
+ + + + +
int yaml_event_s::implicit
+
+
+ +

Is the document indicator implicit?

+

Is the tag optional?

+

Is the document end indicator implicit?

+ +
+
+ +
+
+ + + + +
struct { ... } yaml_event_s::document_start
+
+
+ +

The document parameters (for YAML_DOCUMENT_START_EVENT).

+ +
+
+ +
+
+ + + + +
struct { ... } yaml_event_s::document_end
+
+
+ +

The document end parameters (for YAML_DOCUMENT_END_EVENT).

+ +
+
+ +
+ +
+ +

The anchor.

+ +
+
+ +
+
+ + + + +
struct { ... } yaml_event_s::alias
+
+
+ +

The alias parameters (for YAML_ALIAS_EVENT).

+ +
+
+ +
+ +
+ +

The tag.

+ +
+
+ +
+ +
+ +

The scalar value.

+ +
+
+ +
+
+ + + + +
size_t yaml_event_s::length
+
+
+ +

The length of the scalar value.

+ +
+
+ +
+ +
+ +

The scalar style.

+ +
+
+ +
+
+ + + + +
struct { ... } yaml_event_s::scalar
+
+
+ +

The scalar parameters (for YAML_SCALAR_EVENT).

+ +
+
+ +
+ +
+ +

The sequence style.

+ +
+
+ +
+
+ + + + +
struct { ... } yaml_event_s::sequence_start
+
+
+ +

The sequence parameters (for YAML_SEQUENCE_START_EVENT).

+ +
+
+ +
+ +
+ +

The mapping style.

+ +
+
+ +
+
+ + + + +
struct { ... } yaml_event_s::mapping_start
+
+
+ +

The mapping parameters (for YAML_MAPPING_START_EVENT).

+ +
+
+ +
+
+ + + + +
union { ... } yaml_event_s::data
+
+
+ +

The event data.

+ +
+
+ +
+ +
+ +

The beginning of the event.

+ +
+
+ +
+ +
+ +

The end of the event.

+ +
+
+
The documentation for this struct was generated from the following file: +
+ + + + + + diff --git a/web/server/h2o/libh2o/deps/yaml/doc/html/structyaml__mark__s.html b/web/server/h2o/libh2o/deps/yaml/doc/html/structyaml__mark__s.html new file mode 100644 index 00000000..8af7bb22 --- /dev/null +++ b/web/server/h2o/libh2o/deps/yaml/doc/html/structyaml__mark__s.html @@ -0,0 +1,137 @@ + + + + + +yaml: yaml_mark_s Struct Reference + + + + + + + + +
+ + +
+ + + + + + + + + + + +
+
yaml +  0.1.6 +
+ +
+
+ + + + +
+
+ +
+
yaml_mark_s Struct Reference
+
+
+ +

The pointer position. + More...

+ +

#include <yaml.h>

+ + + + + + + + +

+Data Fields

size_t index
 The position index.
size_t line
 The position line.
size_t column
 The position column.
+

Detailed Description

+

The pointer position.

+

Field Documentation

+ +
+
+ + + + +
size_t yaml_mark_s::index
+
+
+ +

The position index.

+ +
+
+ +
+
+ + + + +
size_t yaml_mark_s::line
+
+
+ +

The position line.

+ +
+
+ +
+
+ + + + +
size_t yaml_mark_s::column
+
+
+ +

The position column.

+ +
+
+
The documentation for this struct was generated from the following file: +
+ + + + + + diff --git a/web/server/h2o/libh2o/deps/yaml/doc/html/structyaml__node__pair__s.html b/web/server/h2o/libh2o/deps/yaml/doc/html/structyaml__node__pair__s.html new file mode 100644 index 00000000..48ed0701 --- /dev/null +++ b/web/server/h2o/libh2o/deps/yaml/doc/html/structyaml__node__pair__s.html @@ -0,0 +1,120 @@ + + + + + +yaml: yaml_node_pair_s Struct Reference + + + + + + + + +
+ + +
+ + + + + + + + + + + +
+
yaml +  0.1.6 +
+ +
+
+ + + + +
+
+ +
+
yaml_node_pair_s Struct Reference
+
+
+ +

An element of a mapping node. + More...

+ +

#include <yaml.h>

+ + + + + + +

+Data Fields

int key
 The key of the element.
int value
 The value of the element.
+

Detailed Description

+

An element of a mapping node.

+

Field Documentation

+ +
+
+ + + + +
int yaml_node_pair_s::key
+
+
+ +

The key of the element.

+ +
+
+ +
+
+ + + + +
int yaml_node_pair_s::value
+
+
+ +

The value of the element.

+ +
+
+
The documentation for this struct was generated from the following file: +
+ + + + + + diff --git a/web/server/h2o/libh2o/deps/yaml/doc/html/structyaml__node__s.html b/web/server/h2o/libh2o/deps/yaml/doc/html/structyaml__node__s.html new file mode 100644 index 00000000..12df49cf --- /dev/null +++ b/web/server/h2o/libh2o/deps/yaml/doc/html/structyaml__node__s.html @@ -0,0 +1,449 @@ + + + + + +yaml: yaml_node_s Struct Reference + + + + + + + + +
+ + +
+ + + + + + + + + + + +
+
yaml +  0.1.6 +
+ +
+
+ + + + +
+
+ +
+
yaml_node_s Struct Reference
+
+
+ +

The node structure. + More...

+ +

#include <yaml.h>

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Data Fields

yaml_node_type_t type
 The node type.
yaml_char_ttag
 The node tag.
union {
   struct {
      yaml_char_t *   value
 The scalar value.
      size_t   length
 The length of the scalar value.
      yaml_scalar_style_t   style
 The scalar style.
   }   scalar
 The scalar parameters (for YAML_SCALAR_NODE).
   struct {
      struct {
         yaml_node_item_t *   start
 The beginning of the stack.
         yaml_node_item_t *   end
 The end of the stack.
         yaml_node_item_t *   top
 The top of the stack.
      }   items
 The stack of sequence items.
      yaml_sequence_style_t   style
 The sequence style.
   }   sequence
 The sequence parameters (for YAML_SEQUENCE_NODE).
   struct {
      struct {
         yaml_node_pair_t *   start
 The beginning of the stack.
         yaml_node_pair_t *   end
 The end of the stack.
         yaml_node_pair_t *   top
 The top of the stack.
      }   pairs
 The stack of mapping pairs (key, value).
      yaml_mapping_style_t   style
 The mapping style.
   }   mapping
 The mapping parameters (for YAML_MAPPING_NODE).
data
 The node data.
yaml_mark_t start_mark
 The beginning of the node.
yaml_mark_t end_mark
 The end of the node.
+

Detailed Description

+

The node structure.

+

Field Documentation

+ +
+ +
+ +

The node type.

+ +
+
+ +
+ +
+ +

The node tag.

+ +
+
+ +
+ +
+ +

The scalar value.

+ +
+
+ +
+
+ + + + +
size_t yaml_node_s::length
+
+
+ +

The length of the scalar value.

+ +
+
+ +
+ +
+ +

The scalar style.

+ +
+
+ +
+
+ + + + +
struct { ... } yaml_node_s::scalar
+
+
+ +

The scalar parameters (for YAML_SCALAR_NODE).

+ +
+
+ +
+ +
+ +

The beginning of the stack.

+ +
+
+ +
+ +
+ +

The end of the stack.

+ +
+
+ +
+ +
+ +

The top of the stack.

+ +
+
+ +
+
+ + + + +
struct { ... } yaml_node_s::items
+
+
+ +

The stack of sequence items.

+ +
+
+ +
+ +
+ +

The sequence style.

+ +
+
+ +
+
+ + + + +
struct { ... } yaml_node_s::sequence
+
+
+ +

The sequence parameters (for YAML_SEQUENCE_NODE).

+ +
+
+ +
+ +
+ +

The beginning of the stack.

+ +
+
+ +
+ +
+ +

The end of the stack.

+ +
+
+ +
+ +
+ +

The top of the stack.

+ +
+
+ +
+
+ + + + +
struct { ... } yaml_node_s::pairs
+
+
+ +

The stack of mapping pairs (key, value).

+ +
+
+ +
+ +
+ +

The mapping style.

+ +
+
+ +
+
+ + + + +
struct { ... } yaml_node_s::mapping
+
+
+ +

The mapping parameters (for YAML_MAPPING_NODE).

+ +
+
+ +
+
+ + + + +
union { ... } yaml_node_s::data
+
+
+ +

The node data.

+ +
+
+ +
+ +
+ +

The beginning of the node.

+ +
+
+ +
+ +
+ +

The end of the node.

+ +
+
+
The documentation for this struct was generated from the following file: +
+ + + + + + diff --git a/web/server/h2o/libh2o/deps/yaml/doc/html/structyaml__parser__s.html b/web/server/h2o/libh2o/deps/yaml/doc/html/structyaml__parser__s.html new file mode 100644 index 00000000..8e3a96d7 --- /dev/null +++ b/web/server/h2o/libh2o/deps/yaml/doc/html/structyaml__parser__s.html @@ -0,0 +1,1248 @@ + + + + + +yaml: yaml_parser_s Struct Reference + + + + + + + + +
+ + +
+ + + + + + + + + + + +
+
yaml +  0.1.6 +
+ +
+
+ + + + +
+
+
+
yaml_parser_s Struct Reference
+
+
+ +

The parser structure. + More...

+ +

#include <yaml.h>

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Data Fields

const unsigned char * start
 The string start pointer.
const unsigned char * end
 The string end pointer.
const unsigned char * current
 The string current position.
struct {
   const unsigned char *   start
 The string start pointer.
   const unsigned char *   end
 The string end pointer.
   const unsigned char *   current
 The string current position.
string
 String input data.
FILE * file
 File input data.
yaml_char_tstart
 The beginning of the buffer.
yaml_char_tend
 The end of the buffer.
yaml_char_tpointer
 The current position of the buffer.
yaml_char_tlast
 The last filled position of the buffer.
unsigned char * start
 The beginning of the buffer.
unsigned char * end
 The end of the buffer.
unsigned char * pointer
 The current position of the buffer.
unsigned char * last
 The last filled position of the buffer.
yaml_token_tstart
 The beginning of the tokens queue.
yaml_token_tend
 The end of the tokens queue.
yaml_token_thead
 The head of the tokens queue.
yaml_token_ttail
 The tail of the tokens queue.
int * start
 The beginning of the stack.
int * end
 The end of the stack.
int * top
 The top of the stack.
yaml_simple_key_tstart
 The beginning of the stack.
yaml_simple_key_tend
 The end of the stack.
yaml_simple_key_ttop
 The top of the stack.
yaml_parser_state_tstart
 The beginning of the stack.
yaml_parser_state_tend
 The end of the stack.
yaml_parser_state_ttop
 The top of the stack.
yaml_mark_tstart
 The beginning of the stack.
yaml_mark_tend
 The end of the stack.
yaml_mark_ttop
 The top of the stack.
yaml_tag_directive_tstart
 The beginning of the list.
yaml_tag_directive_tend
 The end of the list.
yaml_tag_directive_ttop
 The top of the list.
yaml_alias_data_tstart
 The beginning of the list.
yaml_alias_data_tend
 The end of the list.
yaml_alias_data_ttop
 The top of the list.
Error handling
yaml_error_type_t error
 Error type.
const char * problem
 Error description.
size_t problem_offset
 The byte about which the problem occured.
int problem_value
 The problematic value (-1 is none).
yaml_mark_t problem_mark
 The problem position.
const char * context
 The error context.
yaml_mark_t context_mark
 The context position.
Reader stuff
yaml_read_handler_tread_handler
 Read handler.
void * read_handler_data
 A pointer for passing to the read handler.
union {
   struct {
      const unsigned char *   start
 The string start pointer.
      const unsigned char *   end
 The string end pointer.
      const unsigned char *   current
 The string current position.
   }   string
 String input data.
   FILE *   file
 File input data.
input
 Standard (string or file) input data.
+int eof
 EOF flag.
struct {
   yaml_char_t *   start
 The beginning of the buffer.
   yaml_char_t *   end
 The end of the buffer.
   yaml_char_t *   pointer
 The current position of the buffer.
   yaml_char_t *   last
 The last filled position of the buffer.
buffer
 The working buffer.
+size_t unread
struct {
   unsigned char *   start
 The beginning of the buffer.
   unsigned char *   end
 The end of the buffer.
   unsigned char *   pointer
 The current position of the buffer.
   unsigned char *   last
 The last filled position of the buffer.
raw_buffer
 The raw buffer.
yaml_encoding_t encoding
 The input encoding.
size_t offset
 The offset of the current position (in bytes).
yaml_mark_t mark
 The mark of the current position.
Scanner stuff
+int stream_start_produced
 Have we started to scan the input stream?
+int stream_end_produced
 Have we reached the end of the input stream?
int flow_level
 The number of unclosed '[' and '{' indicators.
struct {
   yaml_token_t *   start
 The beginning of the tokens queue.
   yaml_token_t *   end
 The end of the tokens queue.
   yaml_token_t *   head
 The head of the tokens queue.
   yaml_token_t *   tail
 The tail of the tokens queue.
tokens
 The tokens queue.
size_t tokens_parsed
 The number of tokens fetched from the queue.
+int token_available
struct {
   int *   start
 The beginning of the stack.
   int *   end
 The end of the stack.
   int *   top
 The top of the stack.
indents
 The indentation levels stack.
int indent
 The current indentation level.
+int simple_key_allowed
 May a simple key occur at the current position?
struct {
   yaml_simple_key_t *   start
 The beginning of the stack.
   yaml_simple_key_t *   end
 The end of the stack.
   yaml_simple_key_t *   top
 The top of the stack.
simple_keys
 The stack of simple keys.
Parser stuff
struct {
   yaml_parser_state_t *   start
 The beginning of the stack.
   yaml_parser_state_t *   end
 The end of the stack.
   yaml_parser_state_t *   top
 The top of the stack.
states
 The parser states stack.
yaml_parser_state_t state
 The current parser state.
struct {
   yaml_mark_t *   start
 The beginning of the stack.
   yaml_mark_t *   end
 The end of the stack.
   yaml_mark_t *   top
 The top of the stack.
marks
 The stack of marks.
struct {
   yaml_tag_directive_t *   start
 The beginning of the list.
   yaml_tag_directive_t *   end
 The end of the list.
   yaml_tag_directive_t *   top
 The top of the list.
tag_directives
 The list of TAG directives.
Dumper stuff
struct {
   yaml_alias_data_t *   start
 The beginning of the list.
   yaml_alias_data_t *   end
 The end of the list.
   yaml_alias_data_t *   top
 The top of the list.
aliases
 The alias data.
yaml_document_tdocument
 The currently parsed document.
+

Detailed Description

+

The parser structure.

+

All members are internal. Manage the structure using the yaml_parser_ family of functions.

+

Field Documentation

+ +
+ +
+ +

Error type.

+ +
+
+ +
+
+ + + + +
const char* yaml_parser_s::problem
+
+
+ +

Error description.

+ +
+
+ +
+
+ + + + +
size_t yaml_parser_s::problem_offset
+
+
+ +

The byte about which the problem occured.

+ +
+
+ +
+ +
+ +

The problematic value (-1 is none).

+ +
+
+ +
+ +
+ +

The problem position.

+ +
+
+ +
+
+ + + + +
const char* yaml_parser_s::context
+
+
+ +

The error context.

+ +
+
+ +
+ +
+ +

The context position.

+ +
+
+ +
+ +
+ +

Read handler.

+ +
+
+ +
+ +
+ +

A pointer for passing to the read handler.

+ +
+
+ +
+
+ + + + +
const unsigned char* yaml_parser_s::start
+
+
+ +

The string start pointer.

+ +
+
+ +
+
+ + + + +
const unsigned char* yaml_parser_s::end
+
+
+ +

The string end pointer.

+ +
+
+ +
+
+ + + + +
const unsigned char* yaml_parser_s::current
+
+
+ +

The string current position.

+ +
+
+ +
+
+ + + + +
struct { ... } yaml_parser_s::string
+
+
+ +

String input data.

+ +
+
+ +
+
+ + + + +
FILE* yaml_parser_s::file
+
+
+ +

File input data.

+ +
+
+ +
+
+ + + + +
union { ... } yaml_parser_s::input
+
+
+ +

Standard (string or file) input data.

+ +
+
+ +
+ +
+ +

The beginning of the buffer.

+ +
+
+ +
+ +
+ +

The end of the buffer.

+ +
+
+ +
+ +
+ +

The current position of the buffer.

+ +
+
+ +
+ +
+ +

The last filled position of the buffer.

+ +
+
+ +
+
+ + + + +
struct { ... } yaml_parser_s::buffer
+
+
+ +

The working buffer.

+ +
+
+ +
+
+ + + + +
unsigned char* yaml_parser_s::start
+
+
+ +

The beginning of the buffer.

+ +
+
+ +
+
+ + + + +
unsigned char* yaml_parser_s::end
+
+
+ +

The end of the buffer.

+ +
+
+ +
+
+ + + + +
unsigned char* yaml_parser_s::pointer
+
+
+ +

The current position of the buffer.

+ +
+
+ +
+
+ + + + +
unsigned char* yaml_parser_s::last
+
+
+ +

The last filled position of the buffer.

+ +
+
+ +
+
+ + + + +
struct { ... } yaml_parser_s::raw_buffer
+
+
+ +

The raw buffer.

+ +
+
+ +
+ +
+ +

The input encoding.

+ +
+
+ +
+
+ + + + +
size_t yaml_parser_s::offset
+
+
+ +

The offset of the current position (in bytes).

+ +
+
+ +
+ +
+ +

The mark of the current position.

+ +
+
+ +
+
+ + + + +
int yaml_parser_s::flow_level
+
+
+ +

The number of unclosed '[' and '{' indicators.

+ +
+
+ +
+ +
+ +

The beginning of the tokens queue.

+ +
+
+ +
+ +
+ +

The end of the tokens queue.

+ +
+
+ +
+ +
+ +

The head of the tokens queue.

+ +
+
+ +
+ +
+ +

The tail of the tokens queue.

+ +
+
+ +
+
+ + + + +
struct { ... } yaml_parser_s::tokens
+
+
+ +

The tokens queue.

+ +
+
+ +
+
+ + + + +
size_t yaml_parser_s::tokens_parsed
+
+
+ +

The number of tokens fetched from the queue.

+ +
+
+ +
+
+ + + + +
int* yaml_parser_s::start
+
+
+ +

The beginning of the stack.

+ +
+
+ +
+
+ + + + +
int* yaml_parser_s::end
+
+
+ +

The end of the stack.

+ +
+
+ +
+
+ + + + +
int* yaml_parser_s::top
+
+
+ +

The top of the stack.

+ +
+
+ +
+
+ + + + +
struct { ... } yaml_parser_s::indents
+
+
+ +

The indentation levels stack.

+ +
+
+ +
+
+ + + + +
int yaml_parser_s::indent
+
+
+ +

The current indentation level.

+ +
+
+ +
+ +
+ +

The beginning of the stack.

+ +
+
+ +
+ +
+ +

The end of the stack.

+ +
+
+ +
+ +
+ +

The top of the stack.

+ +
+
+ +
+
+ + + + +
struct { ... } yaml_parser_s::simple_keys
+
+
+ +

The stack of simple keys.

+ +
+
+ +
+ +
+ +

The beginning of the stack.

+ +
+
+ +
+ +
+ +

The end of the stack.

+ +
+
+ +
+ +
+ +

The top of the stack.

+ +
+
+ +
+
+ + + + +
struct { ... } yaml_parser_s::states
+
+
+ +

The parser states stack.

+ +
+
+ +
+ +
+ +

The current parser state.

+ +
+
+ +
+ +
+ +

The beginning of the stack.

+ +
+
+ +
+ +
+ +

The end of the stack.

+ +
+
+ +
+ +
+ +

The top of the stack.

+ +
+
+ +
+
+ + + + +
struct { ... } yaml_parser_s::marks
+
+
+ +

The stack of marks.

+ +
+
+ +
+ +
+ +

The beginning of the list.

+ +
+
+ +
+ +
+ +

The end of the list.

+ +
+
+ +
+ +
+ +

The top of the list.

+ +
+
+ +
+
+ + + + +
struct { ... } yaml_parser_s::tag_directives
+
+
+ +

The list of TAG directives.

+ +
+
+ +
+ +
+ +

The beginning of the list.

+ +
+
+ +
+ +
+ +

The end of the list.

+ +
+
+ +
+ +
+ +

The top of the list.

+ +
+
+ +
+
+ + + + +
struct { ... } yaml_parser_s::aliases
+
+
+ +

The alias data.

+ +
+
+ +
+ +
+ +

The currently parsed document.

+ +
+
+
The documentation for this struct was generated from the following file: +
+ + + + + + diff --git a/web/server/h2o/libh2o/deps/yaml/doc/html/structyaml__simple__key__s.html b/web/server/h2o/libh2o/deps/yaml/doc/html/structyaml__simple__key__s.html new file mode 100644 index 00000000..946d6fee --- /dev/null +++ b/web/server/h2o/libh2o/deps/yaml/doc/html/structyaml__simple__key__s.html @@ -0,0 +1,126 @@ + + + + + +yaml: yaml_simple_key_s Struct Reference + + + + + + + + +
+ + +
+ + + + + + + + + + + +
+
yaml +  0.1.6 +
+ +
+
+ + + + +
+
+ +
+
yaml_simple_key_s Struct Reference
+
+
+ +

This structure holds information about a potential simple key. + More...

+ +

#include <yaml.h>

+ + + + + + + + + + +

+Data Fields

+int possible
 Is a simple key possible?
+int required
 Is a simple key required?
size_t token_number
 The number of the token.
yaml_mark_t mark
 The position mark.
+

Detailed Description

+

This structure holds information about a potential simple key.

+

Field Documentation

+ +
+ +
+ +

The number of the token.

+ +
+
+ +
+ +
+ +

The position mark.

+ +
+
+
The documentation for this struct was generated from the following file: +
+ + + + + + diff --git a/web/server/h2o/libh2o/deps/yaml/doc/html/structyaml__tag__directive__s.html b/web/server/h2o/libh2o/deps/yaml/doc/html/structyaml__tag__directive__s.html new file mode 100644 index 00000000..37ecbb39 --- /dev/null +++ b/web/server/h2o/libh2o/deps/yaml/doc/html/structyaml__tag__directive__s.html @@ -0,0 +1,120 @@ + + + + + +yaml: yaml_tag_directive_s Struct Reference + + + + + + + + +
+ + +
+ + + + + + + + + + + +
+
yaml +  0.1.6 +
+ +
+
+ + + + +
+
+ +
+
yaml_tag_directive_s Struct Reference
+
+
+ +

The tag directive data. + More...

+ +

#include <yaml.h>

+ + + + + + +

+Data Fields

yaml_char_thandle
 The tag handle.
yaml_char_tprefix
 The tag prefix.
+

Detailed Description

+

The tag directive data.

+

Field Documentation

+ +
+ +
+ +

The tag handle.

+ +
+
+ +
+ +
+ +

The tag prefix.

+ +
+
+
The documentation for this struct was generated from the following file: +
+ + + + + + diff --git a/web/server/h2o/libh2o/deps/yaml/doc/html/structyaml__token__s.html b/web/server/h2o/libh2o/deps/yaml/doc/html/structyaml__token__s.html new file mode 100644 index 00000000..bc290a07 --- /dev/null +++ b/web/server/h2o/libh2o/deps/yaml/doc/html/structyaml__token__s.html @@ -0,0 +1,442 @@ + + + + + +yaml: yaml_token_s Struct Reference + + + + + + + + +
+ + +
+ + + + + + + + + + + +
+
yaml +  0.1.6 +
+ +
+
+ + + + +
+
+ +
+
yaml_token_s Struct Reference
+
+
+ +

The token structure. + More...

+ +

#include <yaml.h>

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Data Fields

yaml_token_type_t type
 The token type.
union {
   struct {
      yaml_encoding_t   encoding
 The stream encoding.
   }   stream_start
 The stream start (for YAML_STREAM_START_TOKEN).
   struct {
      yaml_char_t *   value
 The alias value.
   }   alias
 The alias (for YAML_ALIAS_TOKEN).
   struct {
      yaml_char_t *   value
 The anchor value.
   }   anchor
 The anchor (for YAML_ANCHOR_TOKEN).
   struct {
      yaml_char_t *   handle
 The tag handle.
      yaml_char_t *   suffix
 The tag suffix.
   }   tag
 The tag (for YAML_TAG_TOKEN).
   struct {
      yaml_char_t *   value
 The scalar value.
      size_t   length
 The length of the scalar value.
      yaml_scalar_style_t   style
 The scalar style.
   }   scalar
 The scalar value (for YAML_SCALAR_TOKEN).
   struct {
      int   major
 The major version number.
      int   minor
 The minor version number.
   }   version_directive
 The version directive (for YAML_VERSION_DIRECTIVE_TOKEN).
   struct {
      yaml_char_t *   handle
 The tag handle.
      yaml_char_t *   prefix
 The tag prefix.
   }   tag_directive
 The tag directive (for YAML_TAG_DIRECTIVE_TOKEN).
data
 The token data.
yaml_mark_t start_mark
 The beginning of the token.
yaml_mark_t end_mark
 The end of the token.
+

Detailed Description

+

The token structure.

+

Field Documentation

+ +
+ +
+ +

The token type.

+ +
+
+ +
+ +
+ +

The stream encoding.

+ +
+
+ +
+
+ + + + +
struct { ... } yaml_token_s::stream_start
+
+
+ +

The stream start (for YAML_STREAM_START_TOKEN).

+ +
+
+ +
+ +
+ +

The alias value.

+

The scalar value.

+

The anchor value.

+ +
+
+ +
+
+ + + + +
struct { ... } yaml_token_s::alias
+
+
+ +

The alias (for YAML_ALIAS_TOKEN).

+ +
+
+ +
+
+ + + + +
struct { ... } yaml_token_s::anchor
+
+
+ +

The anchor (for YAML_ANCHOR_TOKEN).

+ +
+
+ +
+ +
+ +

The tag handle.

+ +
+
+ +
+ +
+ +

The tag suffix.

+ +
+
+ +
+
+ + + + +
struct { ... } yaml_token_s::tag
+
+
+ +

The tag (for YAML_TAG_TOKEN).

+ +
+
+ +
+
+ + + + +
size_t yaml_token_s::length
+
+
+ +

The length of the scalar value.

+ +
+
+ +
+ +
+ +

The scalar style.

+ +
+
+ +
+
+ + + + +
struct { ... } yaml_token_s::scalar
+
+
+ +

The scalar value (for YAML_SCALAR_TOKEN).

+ +
+
+ +
+
+ + + + +
int yaml_token_s::major
+
+
+ +

The major version number.

+ +
+
+ +
+
+ + + + +
int yaml_token_s::minor
+
+
+ +

The minor version number.

+ +
+
+ +
+
+ + + + +
struct { ... } yaml_token_s::version_directive
+
+
+ +

The version directive (for YAML_VERSION_DIRECTIVE_TOKEN).

+ +
+
+ +
+ +
+ +

The tag prefix.

+ +
+
+ +
+
+ + + + +
struct { ... } yaml_token_s::tag_directive
+
+
+ +

The tag directive (for YAML_TAG_DIRECTIVE_TOKEN).

+ +
+
+ +
+
+ + + + +
union { ... } yaml_token_s::data
+
+
+ +

The token data.

+ +
+
+ +
+ +
+ +

The beginning of the token.

+ +
+
+ +
+ +
+ +

The end of the token.

+ +
+
+
The documentation for this struct was generated from the following file: +
+ + + + + + diff --git a/web/server/h2o/libh2o/deps/yaml/doc/html/structyaml__version__directive__s.html b/web/server/h2o/libh2o/deps/yaml/doc/html/structyaml__version__directive__s.html new file mode 100644 index 00000000..8a16d90f --- /dev/null +++ b/web/server/h2o/libh2o/deps/yaml/doc/html/structyaml__version__directive__s.html @@ -0,0 +1,120 @@ + + + + + +yaml: yaml_version_directive_s Struct Reference + + + + + + + + +
+ + +
+ + + + + + + + + + + +
+
yaml +  0.1.6 +
+ +
+
+ + + + +
+
+ +
+
yaml_version_directive_s Struct Reference
+
+
+ +

The version directive data. + More...

+ +

#include <yaml.h>

+ + + + + + +

+Data Fields

int major
 The major version number.
int minor
 The minor version number.
+

Detailed Description

+

The version directive data.

+

Field Documentation

+ +
+ +
+ +

The major version number.

+ +
+
+ +
+ +
+ +

The minor version number.

+ +
+
+
The documentation for this struct was generated from the following file: +
+ + + + + + diff --git a/web/server/h2o/libh2o/deps/yaml/doc/html/tab_a.png b/web/server/h2o/libh2o/deps/yaml/doc/html/tab_a.png new file mode 100644 index 00000000..2d99ef23 Binary files /dev/null and b/web/server/h2o/libh2o/deps/yaml/doc/html/tab_a.png differ diff --git a/web/server/h2o/libh2o/deps/yaml/doc/html/tab_b.png b/web/server/h2o/libh2o/deps/yaml/doc/html/tab_b.png new file mode 100644 index 00000000..b2c3d2be Binary files /dev/null and b/web/server/h2o/libh2o/deps/yaml/doc/html/tab_b.png differ diff --git a/web/server/h2o/libh2o/deps/yaml/doc/html/tab_h.png b/web/server/h2o/libh2o/deps/yaml/doc/html/tab_h.png new file mode 100644 index 00000000..c11f48f1 Binary files /dev/null and b/web/server/h2o/libh2o/deps/yaml/doc/html/tab_h.png differ diff --git a/web/server/h2o/libh2o/deps/yaml/doc/html/tab_s.png b/web/server/h2o/libh2o/deps/yaml/doc/html/tab_s.png new file mode 100644 index 00000000..978943ac Binary files /dev/null and b/web/server/h2o/libh2o/deps/yaml/doc/html/tab_s.png differ diff --git a/web/server/h2o/libh2o/deps/yaml/doc/html/tabs.css b/web/server/h2o/libh2o/deps/yaml/doc/html/tabs.css new file mode 100644 index 00000000..21920562 --- /dev/null +++ b/web/server/h2o/libh2o/deps/yaml/doc/html/tabs.css @@ -0,0 +1,59 @@ +.tabs, .tabs2, .tabs3 { + background-image: url('tab_b.png'); + width: 100%; + z-index: 101; + font-size: 13px; +} + +.tabs2 { + font-size: 10px; +} +.tabs3 { + font-size: 9px; +} + +.tablist { + margin: 0; + padding: 0; + display: table; +} + +.tablist li { + float: left; + display: table-cell; + background-image: url('tab_b.png'); + line-height: 36px; + list-style: none; +} + +.tablist a { + display: block; + padding: 0 20px; + font-weight: bold; + background-image:url('tab_s.png'); + background-repeat:no-repeat; + background-position:right; + color: #283A5D; + text-shadow: 0px 1px 1px rgba(255, 255, 255, 0.9); + text-decoration: none; + outline: none; +} + +.tabs3 .tablist a { + padding: 0 10px; +} + +.tablist a:hover { + background-image: url('tab_h.png'); + background-repeat:repeat-x; + color: #fff; + text-shadow: 0px 1px 1px rgba(0, 0, 0, 1.0); + text-decoration: none; +} + +.tablist li.current a { + background-image: url('tab_a.png'); + background-repeat:repeat-x; + color: #fff; + text-shadow: 0px 1px 1px rgba(0, 0, 0, 1.0); +} diff --git a/web/server/h2o/libh2o/deps/yaml/doc/html/yaml_8h.html b/web/server/h2o/libh2o/deps/yaml/doc/html/yaml_8h.html new file mode 100644 index 00000000..e341c31c --- /dev/null +++ b/web/server/h2o/libh2o/deps/yaml/doc/html/yaml_8h.html @@ -0,0 +1,546 @@ + + + + + +yaml: yaml.h File Reference + + + + + + + + +
+ + +
+ + + + + + + + + + + +
+
yaml +  0.1.6 +
+ +
+
+ + + + +
+
+ +
+
yaml.h File Reference
+
+
+ +

Public interface for libyaml. +More...

+
#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Data Structures

struct  yaml_version_directive_s
 The version directive data. More...
struct  yaml_tag_directive_s
 The tag directive data. More...
struct  yaml_mark_s
 The pointer position. More...
struct  yaml_token_s
 The token structure. More...
struct  yaml_event_s
 The event structure. More...
struct  yaml_node_pair_s
 An element of a mapping node. More...
struct  yaml_node_s
 The node structure. More...
struct  yaml_document_s
 The document structure. More...
struct  yaml_simple_key_s
 This structure holds information about a potential simple key. More...
struct  yaml_alias_data_s
 This structure holds aliases data. More...
struct  yaml_parser_s
 The parser structure. More...
struct  yaml_emitter_s
 The emitter structure. More...

+Defines

#define YAML_DECLARE(type)   type
 The public API declaration.
#define YAML_NULL_TAG   "tag:yaml.org,2002:null"
 The tag !!null with the only possible value: null.
#define YAML_BOOL_TAG   "tag:yaml.org,2002:bool"
 The tag !!bool with the values: true and falce.
#define YAML_STR_TAG   "tag:yaml.org,2002:str"
 The tag !!str for string values.
#define YAML_INT_TAG   "tag:yaml.org,2002:int"
 The tag !!int for integer values.
#define YAML_FLOAT_TAG   "tag:yaml.org,2002:float"
 The tag !!float for float values.
#define YAML_TIMESTAMP_TAG   "tag:yaml.org,2002:timestamp"
 The tag !!timestamp for date and time values.
#define YAML_SEQ_TAG   "tag:yaml.org,2002:seq"
 The tag !!seq is used to denote sequences.
#define YAML_MAP_TAG   "tag:yaml.org,2002:map"
 The tag !!map is used to denote mapping.
#define YAML_DEFAULT_SCALAR_TAG   YAML_STR_TAG
 The default scalar tag is !!str.
#define YAML_DEFAULT_SEQUENCE_TAG   YAML_SEQ_TAG
 The default sequence tag is !!seq.
#define YAML_DEFAULT_MAPPING_TAG   YAML_MAP_TAG
 The default mapping tag is !!map.

+Typedefs

typedef unsigned char yaml_char_t
 The character type (UTF-8 octet).
typedef struct
+yaml_version_directive_s 
yaml_version_directive_t
 The version directive data.
typedef struct yaml_tag_directive_s yaml_tag_directive_t
 The tag directive data.
typedef enum yaml_encoding_e yaml_encoding_t
 The stream encoding.
typedef enum yaml_break_e yaml_break_t
 Line break types.
typedef enum yaml_error_type_e yaml_error_type_t
 Many bad things could happen with the parser and emitter.
typedef struct yaml_mark_s yaml_mark_t
 The pointer position.
typedef enum yaml_scalar_style_e yaml_scalar_style_t
 Scalar styles.
typedef enum yaml_sequence_style_e yaml_sequence_style_t
 Sequence styles.
typedef enum yaml_mapping_style_e yaml_mapping_style_t
 Mapping styles.
typedef enum yaml_token_type_e yaml_token_type_t
 Token types.
typedef struct yaml_token_s yaml_token_t
 The token structure.
typedef enum yaml_event_type_e yaml_event_type_t
 Event types.
typedef struct yaml_event_s yaml_event_t
 The event structure.
typedef enum yaml_node_type_e yaml_node_type_t
 Node types.
typedef struct yaml_node_s yaml_node_t
 The forward definition of a document node structure.
typedef int yaml_node_item_t
 An element of a sequence node.
typedef struct yaml_node_pair_s yaml_node_pair_t
 An element of a mapping node.
typedef struct yaml_document_s yaml_document_t
 The document structure.
typedef int yaml_read_handler_t (void *data, unsigned char *buffer, size_t size, size_t *size_read)
 The prototype of a read handler.
+typedef struct yaml_simple_key_s yaml_simple_key_t
 This structure holds information about a potential simple key.
+typedef enum yaml_parser_state_e yaml_parser_state_t
 The states of the parser.
+typedef struct yaml_alias_data_s yaml_alias_data_t
 This structure holds aliases data.
typedef struct yaml_parser_s yaml_parser_t
 The parser structure.
typedef int yaml_write_handler_t (void *data, unsigned char *buffer, size_t size)
 The prototype of a write handler.
typedef enum yaml_emitter_state_e yaml_emitter_state_t
 The emitter states.
typedef struct yaml_emitter_s yaml_emitter_t
 The emitter structure.

+Enumerations

enum  yaml_encoding_e {
+  YAML_ANY_ENCODING, +
+  YAML_UTF8_ENCODING, +
+  YAML_UTF16LE_ENCODING, +
+  YAML_UTF16BE_ENCODING +
+ }
 The stream encoding. More...
enum  yaml_break_e {
+  YAML_ANY_BREAK, +
+  YAML_CR_BREAK, +
+  YAML_LN_BREAK, +
+  YAML_CRLN_BREAK +
+ }
 Line break types. More...
enum  yaml_error_type_e {
+  YAML_NO_ERROR, +
+  YAML_MEMORY_ERROR, +
+  YAML_READER_ERROR, +
+  YAML_SCANNER_ERROR, +
+  YAML_PARSER_ERROR, +
+  YAML_COMPOSER_ERROR, +
+  YAML_WRITER_ERROR, +
+  YAML_EMITTER_ERROR +
+ }
 Many bad things could happen with the parser and emitter. More...
enum  yaml_scalar_style_e {
+  YAML_ANY_SCALAR_STYLE, +
+  YAML_PLAIN_SCALAR_STYLE, +
+  YAML_SINGLE_QUOTED_SCALAR_STYLE, +
+  YAML_DOUBLE_QUOTED_SCALAR_STYLE, +
+  YAML_LITERAL_SCALAR_STYLE, +
+  YAML_FOLDED_SCALAR_STYLE +
+ }
 Scalar styles. More...
enum  yaml_sequence_style_e {
+  YAML_ANY_SEQUENCE_STYLE, +
+  YAML_BLOCK_SEQUENCE_STYLE, +
+  YAML_FLOW_SEQUENCE_STYLE +
+ }
 Sequence styles. More...
enum  yaml_mapping_style_e {
+  YAML_ANY_MAPPING_STYLE, +
+  YAML_BLOCK_MAPPING_STYLE, +
+  YAML_FLOW_MAPPING_STYLE +
+ }
 Mapping styles. More...
enum  yaml_token_type_e {
+  YAML_NO_TOKEN, +
+  YAML_STREAM_START_TOKEN, +
+  YAML_STREAM_END_TOKEN, +
+  YAML_VERSION_DIRECTIVE_TOKEN, +
+  YAML_TAG_DIRECTIVE_TOKEN, +
+  YAML_DOCUMENT_START_TOKEN, +
+  YAML_DOCUMENT_END_TOKEN, +
+  YAML_BLOCK_SEQUENCE_START_TOKEN, +
+  YAML_BLOCK_MAPPING_START_TOKEN, +
+  YAML_BLOCK_END_TOKEN, +
+  YAML_FLOW_SEQUENCE_START_TOKEN, +
+  YAML_FLOW_SEQUENCE_END_TOKEN, +
+  YAML_FLOW_MAPPING_START_TOKEN, +
+  YAML_FLOW_MAPPING_END_TOKEN, +
+  YAML_BLOCK_ENTRY_TOKEN, +
+  YAML_FLOW_ENTRY_TOKEN, +
+  YAML_KEY_TOKEN, +
+  YAML_VALUE_TOKEN, +
+  YAML_ALIAS_TOKEN, +
+  YAML_ANCHOR_TOKEN, +
+  YAML_TAG_TOKEN, +
+  YAML_SCALAR_TOKEN +
+ }
 Token types. More...
enum  yaml_event_type_e {
+  YAML_NO_EVENT, +
+  YAML_STREAM_START_EVENT, +
+  YAML_STREAM_END_EVENT, +
+  YAML_DOCUMENT_START_EVENT, +
+  YAML_DOCUMENT_END_EVENT, +
+  YAML_ALIAS_EVENT, +
+  YAML_SCALAR_EVENT, +
+  YAML_SEQUENCE_START_EVENT, +
+  YAML_SEQUENCE_END_EVENT, +
+  YAML_MAPPING_START_EVENT, +
+  YAML_MAPPING_END_EVENT +
+ }
 Event types. More...
enum  yaml_node_type_e {
+  YAML_NO_NODE, +
+  YAML_SCALAR_NODE, +
+  YAML_SEQUENCE_NODE, +
+  YAML_MAPPING_NODE +
+ }
 Node types. More...
enum  yaml_parser_state_e {
+  YAML_PARSE_STREAM_START_STATE, +
+  YAML_PARSE_IMPLICIT_DOCUMENT_START_STATE, +
+  YAML_PARSE_DOCUMENT_START_STATE, +
+  YAML_PARSE_DOCUMENT_CONTENT_STATE, +
+  YAML_PARSE_DOCUMENT_END_STATE, +
+  YAML_PARSE_BLOCK_NODE_STATE, +
+  YAML_PARSE_BLOCK_NODE_OR_INDENTLESS_SEQUENCE_STATE, +
+  YAML_PARSE_FLOW_NODE_STATE, +
+  YAML_PARSE_BLOCK_SEQUENCE_FIRST_ENTRY_STATE, +
+  YAML_PARSE_BLOCK_SEQUENCE_ENTRY_STATE, +
+  YAML_PARSE_INDENTLESS_SEQUENCE_ENTRY_STATE, +
+  YAML_PARSE_BLOCK_MAPPING_FIRST_KEY_STATE, +
+  YAML_PARSE_BLOCK_MAPPING_KEY_STATE, +
+  YAML_PARSE_BLOCK_MAPPING_VALUE_STATE, +
+  YAML_PARSE_FLOW_SEQUENCE_FIRST_ENTRY_STATE, +
+  YAML_PARSE_FLOW_SEQUENCE_ENTRY_STATE, +
+  YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_KEY_STATE, +
+  YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_VALUE_STATE, +
+  YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_END_STATE, +
+  YAML_PARSE_FLOW_MAPPING_FIRST_KEY_STATE, +
+  YAML_PARSE_FLOW_MAPPING_KEY_STATE, +
+  YAML_PARSE_FLOW_MAPPING_VALUE_STATE, +
+  YAML_PARSE_FLOW_MAPPING_EMPTY_VALUE_STATE, +
+  YAML_PARSE_END_STATE +
+ }
 The states of the parser. More...
enum  yaml_emitter_state_e {
+  YAML_EMIT_STREAM_START_STATE, +
+  YAML_EMIT_FIRST_DOCUMENT_START_STATE, +
+  YAML_EMIT_DOCUMENT_START_STATE, +
+  YAML_EMIT_DOCUMENT_CONTENT_STATE, +
+  YAML_EMIT_DOCUMENT_END_STATE, +
+  YAML_EMIT_FLOW_SEQUENCE_FIRST_ITEM_STATE, +
+  YAML_EMIT_FLOW_SEQUENCE_ITEM_STATE, +
+  YAML_EMIT_FLOW_MAPPING_FIRST_KEY_STATE, +
+  YAML_EMIT_FLOW_MAPPING_KEY_STATE, +
+  YAML_EMIT_FLOW_MAPPING_SIMPLE_VALUE_STATE, +
+  YAML_EMIT_FLOW_MAPPING_VALUE_STATE, +
+  YAML_EMIT_BLOCK_SEQUENCE_FIRST_ITEM_STATE, +
+  YAML_EMIT_BLOCK_SEQUENCE_ITEM_STATE, +
+  YAML_EMIT_BLOCK_MAPPING_FIRST_KEY_STATE, +
+  YAML_EMIT_BLOCK_MAPPING_KEY_STATE, +
+  YAML_EMIT_BLOCK_MAPPING_SIMPLE_VALUE_STATE, +
+  YAML_EMIT_BLOCK_MAPPING_VALUE_STATE, +
+  YAML_EMIT_END_STATE +
+ }
 The emitter states. More...

+Functions

const char * yaml_get_version_string (void)
 Get the library version as a string.
void yaml_get_version (int *major, int *minor, int *patch)
 Get the library version numbers.
void yaml_token_delete (yaml_token_t *token)
 Free any memory allocated for a token object.
int yaml_stream_start_event_initialize (yaml_event_t *event, yaml_encoding_t encoding)
 Create the STREAM-START event.
int yaml_stream_end_event_initialize (yaml_event_t *event)
 Create the STREAM-END event.
int yaml_document_start_event_initialize (yaml_event_t *event, yaml_version_directive_t *version_directive, yaml_tag_directive_t *tag_directives_start, yaml_tag_directive_t *tag_directives_end, int implicit)
 Create the DOCUMENT-START event.
int yaml_document_end_event_initialize (yaml_event_t *event, int implicit)
 Create the DOCUMENT-END event.
int yaml_alias_event_initialize (yaml_event_t *event, yaml_char_t *anchor)
 Create an ALIAS event.
int yaml_scalar_event_initialize (yaml_event_t *event, yaml_char_t *anchor, yaml_char_t *tag, yaml_char_t *value, int length, int plain_implicit, int quoted_implicit, yaml_scalar_style_t style)
 Create a SCALAR event.
int yaml_sequence_start_event_initialize (yaml_event_t *event, yaml_char_t *anchor, yaml_char_t *tag, int implicit, yaml_sequence_style_t style)
 Create a SEQUENCE-START event.
int yaml_sequence_end_event_initialize (yaml_event_t *event)
 Create a SEQUENCE-END event.
int yaml_mapping_start_event_initialize (yaml_event_t *event, yaml_char_t *anchor, yaml_char_t *tag, int implicit, yaml_mapping_style_t style)
 Create a MAPPING-START event.
int yaml_mapping_end_event_initialize (yaml_event_t *event)
 Create a MAPPING-END event.
void yaml_event_delete (yaml_event_t *event)
 Free any memory allocated for an event object.
int yaml_document_initialize (yaml_document_t *document, yaml_version_directive_t *version_directive, yaml_tag_directive_t *tag_directives_start, yaml_tag_directive_t *tag_directives_end, int start_implicit, int end_implicit)
 Create a YAML document.
void yaml_document_delete (yaml_document_t *document)
 Delete a YAML document and all its nodes.
yaml_node_tyaml_document_get_node (yaml_document_t *document, int index)
 Get a node of a YAML document.
yaml_node_tyaml_document_get_root_node (yaml_document_t *document)
 Get the root of a YAML document node.
int yaml_document_add_scalar (yaml_document_t *document, yaml_char_t *tag, yaml_char_t *value, int length, yaml_scalar_style_t style)
 Create a SCALAR node and attach it to the document.
int yaml_document_add_sequence (yaml_document_t *document, yaml_char_t *tag, yaml_sequence_style_t style)
 Create a SEQUENCE node and attach it to the document.
int yaml_document_add_mapping (yaml_document_t *document, yaml_char_t *tag, yaml_mapping_style_t style)
 Create a MAPPING node and attach it to the document.
int yaml_document_append_sequence_item (yaml_document_t *document, int sequence, int item)
 Add an item to a SEQUENCE node.
int yaml_document_append_mapping_pair (yaml_document_t *document, int mapping, int key, int value)
 Add a pair of a key and a value to a MAPPING node.
int yaml_parser_initialize (yaml_parser_t *parser)
 Initialize a parser.
void yaml_parser_delete (yaml_parser_t *parser)
 Destroy a parser.
void yaml_parser_set_input_string (yaml_parser_t *parser, const unsigned char *input, size_t size)
 Set a string input.
void yaml_parser_set_input_file (yaml_parser_t *parser, FILE *file)
 Set a file input.
void yaml_parser_set_input (yaml_parser_t *parser, yaml_read_handler_t *handler, void *data)
 Set a generic input handler.
void yaml_parser_set_encoding (yaml_parser_t *parser, yaml_encoding_t encoding)
 Set the source encoding.
int yaml_parser_scan (yaml_parser_t *parser, yaml_token_t *token)
 Scan the input stream and produce the next token.
int yaml_parser_parse (yaml_parser_t *parser, yaml_event_t *event)
 Parse the input stream and produce the next parsing event.
int yaml_parser_load (yaml_parser_t *parser, yaml_document_t *document)
 Parse the input stream and produce the next YAML document.
int yaml_emitter_initialize (yaml_emitter_t *emitter)
 Initialize an emitter.
void yaml_emitter_delete (yaml_emitter_t *emitter)
 Destroy an emitter.
void yaml_emitter_set_output_string (yaml_emitter_t *emitter, unsigned char *output, size_t size, size_t *size_written)
 Set a string output.
void yaml_emitter_set_output_file (yaml_emitter_t *emitter, FILE *file)
 Set a file output.
void yaml_emitter_set_output (yaml_emitter_t *emitter, yaml_write_handler_t *handler, void *data)
 Set a generic output handler.
void yaml_emitter_set_encoding (yaml_emitter_t *emitter, yaml_encoding_t encoding)
 Set the output encoding.
void yaml_emitter_set_canonical (yaml_emitter_t *emitter, int canonical)
 Set if the output should be in the "canonical" format as in the YAML specification.
void yaml_emitter_set_indent (yaml_emitter_t *emitter, int indent)
 Set the intendation increment.
void yaml_emitter_set_width (yaml_emitter_t *emitter, int width)
 Set the preferred line width.
void yaml_emitter_set_unicode (yaml_emitter_t *emitter, int unicode)
 Set if unescaped non-ASCII characters are allowed.
void yaml_emitter_set_break (yaml_emitter_t *emitter, yaml_break_t line_break)
 Set the preferred line break.
int yaml_emitter_emit (yaml_emitter_t *emitter, yaml_event_t *event)
 Emit an event.
int yaml_emitter_open (yaml_emitter_t *emitter)
 Start a YAML stream.
int yaml_emitter_close (yaml_emitter_t *emitter)
 Finish a YAML stream.
int yaml_emitter_dump (yaml_emitter_t *emitter, yaml_document_t *document)
 Emit a YAML document.
int yaml_emitter_flush (yaml_emitter_t *emitter)
 Flush the accumulated characters to the output.
+

Detailed Description

+

Public interface for libyaml.

+

Include the header file with the code:

+
 #include <yaml.h>
+
+ + + + + + diff --git a/web/server/h2o/libh2o/deps/yaml/include/Makefile.am b/web/server/h2o/libh2o/deps/yaml/include/Makefile.am new file mode 100644 index 00000000..f81863cb --- /dev/null +++ b/web/server/h2o/libh2o/deps/yaml/include/Makefile.am @@ -0,0 +1,17 @@ +INCLUDES = yaml.h +DOXYGEN_CFG = $(top_srcdir)/doc/doxygen.cfg + +nobase_include_HEADERS = $(INCLUDES) + +if DOXYGEN + +html: $(INCLUDES) $(DOXYGEN_CFG) + PACKAGE=$(PACKAGE) VERSION=$(VERSION) top_srcdir=$(top_srcdir) top_builddir=$(top_builddir) doxygen $(DOXYGEN_CFG) + +endif + +maintainer-clean-local: + -rm -rf $(top_builddir)/doc/html + +dist-hook: html + cp -a $(top_builddir)/doc/html $(top_distdir)/doc diff --git a/web/server/h2o/libh2o/deps/yaml/include/Makefile.in b/web/server/h2o/libh2o/deps/yaml/include/Makefile.in new file mode 100644 index 00000000..79b60f5c --- /dev/null +++ b/web/server/h2o/libh2o/deps/yaml/include/Makefile.in @@ -0,0 +1,481 @@ +# Makefile.in generated by automake 1.11.3 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software +# Foundation, Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +subdir = include +DIST_COMMON = $(nobase_include_HEADERS) $(srcdir)/Makefile.am \ + $(srcdir)/Makefile.in +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +SOURCES = +DIST_SOURCES = +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; +am__install_max = 40 +am__nobase_strip_setup = \ + srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` +am__nobase_strip = \ + for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" +am__nobase_list = $(am__nobase_strip_setup); \ + for p in $$list; do echo "$$p $$p"; done | \ + sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ + $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ + if (++n[$$2] == $(am__install_max)) \ + { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ + END { for (dir in files) print dir, files[dir] }' +am__base_list = \ + sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ + sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +am__uninstall_files_from_dir = { \ + test -z "$$files" \ + || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ + || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ + $(am__cd) "$$dir" && rm -f $$files; }; \ + } +am__installdirs = "$(DESTDIR)$(includedir)" +HEADERS = $(nobase_include_HEADERS) +ETAGS = etags +CTAGS = ctags +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DOXYGEN = @DOXYGEN@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +GREP = @GREP@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +YAML_LT_AGE = @YAML_LT_AGE@ +YAML_LT_CURRENT = @YAML_LT_CURRENT@ +YAML_LT_RELEASE = @YAML_LT_RELEASE@ +YAML_LT_REVISION = @YAML_LT_REVISION@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +INCLUDES = yaml.h +DOXYGEN_CFG = $(top_srcdir)/doc/doxygen.cfg +nobase_include_HEADERS = $(INCLUDES) +all: all-am + +.SUFFIXES: +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign include/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --foreign include/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs +install-nobase_includeHEADERS: $(nobase_include_HEADERS) + @$(NORMAL_INSTALL) + test -z "$(includedir)" || $(MKDIR_P) "$(DESTDIR)$(includedir)" + @list='$(nobase_include_HEADERS)'; test -n "$(includedir)" || list=; \ + $(am__nobase_list) | while read dir files; do \ + xfiles=; for file in $$files; do \ + if test -f "$$file"; then xfiles="$$xfiles $$file"; \ + else xfiles="$$xfiles $(srcdir)/$$file"; fi; done; \ + test -z "$$xfiles" || { \ + test "x$$dir" = x. || { \ + echo "$(MKDIR_P) '$(DESTDIR)$(includedir)/$$dir'"; \ + $(MKDIR_P) "$(DESTDIR)$(includedir)/$$dir"; }; \ + echo " $(INSTALL_HEADER) $$xfiles '$(DESTDIR)$(includedir)/$$dir'"; \ + $(INSTALL_HEADER) $$xfiles "$(DESTDIR)$(includedir)/$$dir" || exit $$?; }; \ + done + +uninstall-nobase_includeHEADERS: + @$(NORMAL_UNINSTALL) + @list='$(nobase_include_HEADERS)'; test -n "$(includedir)" || list=; \ + $(am__nobase_strip_setup); files=`$(am__nobase_strip)`; \ + dir='$(DESTDIR)$(includedir)'; $(am__uninstall_files_from_dir) + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + set x; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: CTAGS +CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done + $(MAKE) $(AM_MAKEFLAGS) \ + top_distdir="$(top_distdir)" distdir="$(distdir)" \ + dist-hook +check-am: all-am +check: check-am +all-am: Makefile $(HEADERS) +installdirs: + for dir in "$(DESTDIR)$(includedir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-libtool mostlyclean-am + +distclean: distclean-am + -rm -f Makefile +distclean-am: clean-am distclean-generic distclean-tags + +dvi: dvi-am + +dvi-am: + +@DOXYGEN_FALSE@html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: install-nobase_includeHEADERS + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic \ + maintainer-clean-local + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-generic mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-nobase_includeHEADERS + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ + clean-libtool ctags dist-hook distclean distclean-generic \ + distclean-libtool distclean-tags distdir dvi dvi-am html \ + html-am info info-am install install-am install-data \ + install-data-am install-dvi install-dvi-am install-exec \ + install-exec-am install-html install-html-am install-info \ + install-info-am install-man install-nobase_includeHEADERS \ + install-pdf install-pdf-am install-ps install-ps-am \ + install-strip installcheck installcheck-am installdirs \ + maintainer-clean maintainer-clean-generic \ + maintainer-clean-local mostlyclean mostlyclean-generic \ + mostlyclean-libtool pdf pdf-am ps ps-am tags uninstall \ + uninstall-am uninstall-nobase_includeHEADERS + + +@DOXYGEN_TRUE@html: $(INCLUDES) $(DOXYGEN_CFG) +@DOXYGEN_TRUE@ PACKAGE=$(PACKAGE) VERSION=$(VERSION) top_srcdir=$(top_srcdir) top_builddir=$(top_builddir) doxygen $(DOXYGEN_CFG) + +maintainer-clean-local: + -rm -rf $(top_builddir)/doc/html + +dist-hook: html + cp -a $(top_builddir)/doc/html $(top_distdir)/doc + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/web/server/h2o/libh2o/deps/yaml/include/yaml.h b/web/server/h2o/libh2o/deps/yaml/include/yaml.h new file mode 100644 index 00000000..acd6e875 --- /dev/null +++ b/web/server/h2o/libh2o/deps/yaml/include/yaml.h @@ -0,0 +1,1961 @@ +/** + * @file yaml.h + * @brief Public interface for libyaml. + * + * Include the header file with the code: + * @code + * #include + * @endcode + */ + +#ifndef YAML_H +#define YAML_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include +#include + +/** + * @defgroup export Export Definitions + * @{ + */ + +/** The public API declaration. */ + +#define YAML_DECLARE(type) type + +/** @} */ + +/** + * @defgroup version Version Information + * @{ + */ + +/** + * Get the library version as a string. + * + * @returns The function returns the pointer to a static string of the form + * @c "X.Y.Z", where @c X is the major version number, @c Y is a minor version + * number, and @c Z is the patch version number. + */ + +YAML_DECLARE(const char *) +yaml_get_version_string(void); + +/** + * Get the library version numbers. + * + * @param[out] major Major version number. + * @param[out] minor Minor version number. + * @param[out] patch Patch version number. + */ + +YAML_DECLARE(void) +yaml_get_version(int *major, int *minor, int *patch); + +/** @} */ + +/** + * @defgroup basic Basic Types + * @{ + */ + +/** The character type (UTF-8 octet). */ +typedef unsigned char yaml_char_t; + +/** The version directive data. */ +typedef struct yaml_version_directive_s { + /** The major version number. */ + int major; + /** The minor version number. */ + int minor; +} yaml_version_directive_t; + +/** The tag directive data. */ +typedef struct yaml_tag_directive_s { + /** The tag handle. */ + yaml_char_t *handle; + /** The tag prefix. */ + yaml_char_t *prefix; +} yaml_tag_directive_t; + +/** The stream encoding. */ +typedef enum yaml_encoding_e { + /** Let the parser choose the encoding. */ + YAML_ANY_ENCODING, + /** The default UTF-8 encoding. */ + YAML_UTF8_ENCODING, + /** The UTF-16-LE encoding with BOM. */ + YAML_UTF16LE_ENCODING, + /** The UTF-16-BE encoding with BOM. */ + YAML_UTF16BE_ENCODING +} yaml_encoding_t; + +/** Line break types. */ + +typedef enum yaml_break_e { + /** Let the parser choose the break type. */ + YAML_ANY_BREAK, + /** Use CR for line breaks (Mac style). */ + YAML_CR_BREAK, + /** Use LN for line breaks (Unix style). */ + YAML_LN_BREAK, + /** Use CR LN for line breaks (DOS style). */ + YAML_CRLN_BREAK +} yaml_break_t; + +/** Many bad things could happen with the parser and emitter. */ +typedef enum yaml_error_type_e { + /** No error is produced. */ + YAML_NO_ERROR, + + /** Cannot allocate or reallocate a block of memory. */ + YAML_MEMORY_ERROR, + + /** Cannot read or decode the input stream. */ + YAML_READER_ERROR, + /** Cannot scan the input stream. */ + YAML_SCANNER_ERROR, + /** Cannot parse the input stream. */ + YAML_PARSER_ERROR, + /** Cannot compose a YAML document. */ + YAML_COMPOSER_ERROR, + + /** Cannot write to the output stream. */ + YAML_WRITER_ERROR, + /** Cannot emit a YAML stream. */ + YAML_EMITTER_ERROR +} yaml_error_type_t; + +/** The pointer position. */ +typedef struct yaml_mark_s { + /** The position index. */ + size_t index; + + /** The position line. */ + size_t line; + + /** The position column. */ + size_t column; +} yaml_mark_t; + +/** @} */ + +/** + * @defgroup styles Node Styles + * @{ + */ + +/** Scalar styles. */ +typedef enum yaml_scalar_style_e { + /** Let the emitter choose the style. */ + YAML_ANY_SCALAR_STYLE, + + /** The plain scalar style. */ + YAML_PLAIN_SCALAR_STYLE, + + /** The single-quoted scalar style. */ + YAML_SINGLE_QUOTED_SCALAR_STYLE, + /** The double-quoted scalar style. */ + YAML_DOUBLE_QUOTED_SCALAR_STYLE, + + /** The literal scalar style. */ + YAML_LITERAL_SCALAR_STYLE, + /** The folded scalar style. */ + YAML_FOLDED_SCALAR_STYLE +} yaml_scalar_style_t; + +/** Sequence styles. */ +typedef enum yaml_sequence_style_e { + /** Let the emitter choose the style. */ + YAML_ANY_SEQUENCE_STYLE, + + /** The block sequence style. */ + YAML_BLOCK_SEQUENCE_STYLE, + /** The flow sequence style. */ + YAML_FLOW_SEQUENCE_STYLE +} yaml_sequence_style_t; + +/** Mapping styles. */ +typedef enum yaml_mapping_style_e { + /** Let the emitter choose the style. */ + YAML_ANY_MAPPING_STYLE, + + /** The block mapping style. */ + YAML_BLOCK_MAPPING_STYLE, + /** The flow mapping style. */ + YAML_FLOW_MAPPING_STYLE +/* YAML_FLOW_SET_MAPPING_STYLE */ +} yaml_mapping_style_t; + +/** @} */ + +/** + * @defgroup tokens Tokens + * @{ + */ + +/** Token types. */ +typedef enum yaml_token_type_e { + /** An empty token. */ + YAML_NO_TOKEN, + + /** A STREAM-START token. */ + YAML_STREAM_START_TOKEN, + /** A STREAM-END token. */ + YAML_STREAM_END_TOKEN, + + /** A VERSION-DIRECTIVE token. */ + YAML_VERSION_DIRECTIVE_TOKEN, + /** A TAG-DIRECTIVE token. */ + YAML_TAG_DIRECTIVE_TOKEN, + /** A DOCUMENT-START token. */ + YAML_DOCUMENT_START_TOKEN, + /** A DOCUMENT-END token. */ + YAML_DOCUMENT_END_TOKEN, + + /** A BLOCK-SEQUENCE-START token. */ + YAML_BLOCK_SEQUENCE_START_TOKEN, + /** A BLOCK-SEQUENCE-END token. */ + YAML_BLOCK_MAPPING_START_TOKEN, + /** A BLOCK-END token. */ + YAML_BLOCK_END_TOKEN, + + /** A FLOW-SEQUENCE-START token. */ + YAML_FLOW_SEQUENCE_START_TOKEN, + /** A FLOW-SEQUENCE-END token. */ + YAML_FLOW_SEQUENCE_END_TOKEN, + /** A FLOW-MAPPING-START token. */ + YAML_FLOW_MAPPING_START_TOKEN, + /** A FLOW-MAPPING-END token. */ + YAML_FLOW_MAPPING_END_TOKEN, + + /** A BLOCK-ENTRY token. */ + YAML_BLOCK_ENTRY_TOKEN, + /** A FLOW-ENTRY token. */ + YAML_FLOW_ENTRY_TOKEN, + /** A KEY token. */ + YAML_KEY_TOKEN, + /** A VALUE token. */ + YAML_VALUE_TOKEN, + + /** An ALIAS token. */ + YAML_ALIAS_TOKEN, + /** An ANCHOR token. */ + YAML_ANCHOR_TOKEN, + /** A TAG token. */ + YAML_TAG_TOKEN, + /** A SCALAR token. */ + YAML_SCALAR_TOKEN +} yaml_token_type_t; + +/** The token structure. */ +typedef struct yaml_token_s { + + /** The token type. */ + yaml_token_type_t type; + + /** The token data. */ + union { + + /** The stream start (for @c YAML_STREAM_START_TOKEN). */ + struct { + /** The stream encoding. */ + yaml_encoding_t encoding; + } stream_start; + + /** The alias (for @c YAML_ALIAS_TOKEN). */ + struct { + /** The alias value. */ + yaml_char_t *value; + } alias; + + /** The anchor (for @c YAML_ANCHOR_TOKEN). */ + struct { + /** The anchor value. */ + yaml_char_t *value; + } anchor; + + /** The tag (for @c YAML_TAG_TOKEN). */ + struct { + /** The tag handle. */ + yaml_char_t *handle; + /** The tag suffix. */ + yaml_char_t *suffix; + } tag; + + /** The scalar value (for @c YAML_SCALAR_TOKEN). */ + struct { + /** The scalar value. */ + yaml_char_t *value; + /** The length of the scalar value. */ + size_t length; + /** The scalar style. */ + yaml_scalar_style_t style; + } scalar; + + /** The version directive (for @c YAML_VERSION_DIRECTIVE_TOKEN). */ + struct { + /** The major version number. */ + int major; + /** The minor version number. */ + int minor; + } version_directive; + + /** The tag directive (for @c YAML_TAG_DIRECTIVE_TOKEN). */ + struct { + /** The tag handle. */ + yaml_char_t *handle; + /** The tag prefix. */ + yaml_char_t *prefix; + } tag_directive; + + } data; + + /** The beginning of the token. */ + yaml_mark_t start_mark; + /** The end of the token. */ + yaml_mark_t end_mark; + +} yaml_token_t; + +/** + * Free any memory allocated for a token object. + * + * @param[in,out] token A token object. + */ + +YAML_DECLARE(void) +yaml_token_delete(yaml_token_t *token); + +/** @} */ + +/** + * @defgroup events Events + * @{ + */ + +/** Event types. */ +typedef enum yaml_event_type_e { + /** An empty event. */ + YAML_NO_EVENT, + + /** A STREAM-START event. */ + YAML_STREAM_START_EVENT, + /** A STREAM-END event. */ + YAML_STREAM_END_EVENT, + + /** A DOCUMENT-START event. */ + YAML_DOCUMENT_START_EVENT, + /** A DOCUMENT-END event. */ + YAML_DOCUMENT_END_EVENT, + + /** An ALIAS event. */ + YAML_ALIAS_EVENT, + /** A SCALAR event. */ + YAML_SCALAR_EVENT, + + /** A SEQUENCE-START event. */ + YAML_SEQUENCE_START_EVENT, + /** A SEQUENCE-END event. */ + YAML_SEQUENCE_END_EVENT, + + /** A MAPPING-START event. */ + YAML_MAPPING_START_EVENT, + /** A MAPPING-END event. */ + YAML_MAPPING_END_EVENT +} yaml_event_type_t; + +/** The event structure. */ +typedef struct yaml_event_s { + + /** The event type. */ + yaml_event_type_t type; + + /** The event data. */ + union { + + /** The stream parameters (for @c YAML_STREAM_START_EVENT). */ + struct { + /** The document encoding. */ + yaml_encoding_t encoding; + } stream_start; + + /** The document parameters (for @c YAML_DOCUMENT_START_EVENT). */ + struct { + /** The version directive. */ + yaml_version_directive_t *version_directive; + + /** The list of tag directives. */ + struct { + /** The beginning of the tag directives list. */ + yaml_tag_directive_t *start; + /** The end of the tag directives list. */ + yaml_tag_directive_t *end; + } tag_directives; + + /** Is the document indicator implicit? */ + int implicit; + } document_start; + + /** The document end parameters (for @c YAML_DOCUMENT_END_EVENT). */ + struct { + /** Is the document end indicator implicit? */ + int implicit; + } document_end; + + /** The alias parameters (for @c YAML_ALIAS_EVENT). */ + struct { + /** The anchor. */ + yaml_char_t *anchor; + } alias; + + /** The scalar parameters (for @c YAML_SCALAR_EVENT). */ + struct { + /** The anchor. */ + yaml_char_t *anchor; + /** The tag. */ + yaml_char_t *tag; + /** The scalar value. */ + yaml_char_t *value; + /** The length of the scalar value. */ + size_t length; + /** Is the tag optional for the plain style? */ + int plain_implicit; + /** Is the tag optional for any non-plain style? */ + int quoted_implicit; + /** The scalar style. */ + yaml_scalar_style_t style; + } scalar; + + /** The sequence parameters (for @c YAML_SEQUENCE_START_EVENT). */ + struct { + /** The anchor. */ + yaml_char_t *anchor; + /** The tag. */ + yaml_char_t *tag; + /** Is the tag optional? */ + int implicit; + /** The sequence style. */ + yaml_sequence_style_t style; + } sequence_start; + + /** The mapping parameters (for @c YAML_MAPPING_START_EVENT). */ + struct { + /** The anchor. */ + yaml_char_t *anchor; + /** The tag. */ + yaml_char_t *tag; + /** Is the tag optional? */ + int implicit; + /** The mapping style. */ + yaml_mapping_style_t style; + } mapping_start; + + } data; + + /** The beginning of the event. */ + yaml_mark_t start_mark; + /** The end of the event. */ + yaml_mark_t end_mark; + +} yaml_event_t; + +/** + * Create the STREAM-START event. + * + * @param[out] event An empty event object. + * @param[in] encoding The stream encoding. + * + * @returns @c 1 if the function succeeded, @c 0 on error. + */ + +YAML_DECLARE(int) +yaml_stream_start_event_initialize(yaml_event_t *event, + yaml_encoding_t encoding); + +/** + * Create the STREAM-END event. + * + * @param[out] event An empty event object. + * + * @returns @c 1 if the function succeeded, @c 0 on error. + */ + +YAML_DECLARE(int) +yaml_stream_end_event_initialize(yaml_event_t *event); + +/** + * Create the DOCUMENT-START event. + * + * The @a implicit argument is considered as a stylistic parameter and may be + * ignored by the emitter. + * + * @param[out] event An empty event object. + * @param[in] version_directive The %YAML directive value or + * @c NULL. + * @param[in] tag_directives_start The beginning of the %TAG + * directives list. + * @param[in] tag_directives_end The end of the %TAG directives + * list. + * @param[in] implicit If the document start indicator is + * implicit. + * + * @returns @c 1 if the function succeeded, @c 0 on error. + */ + +YAML_DECLARE(int) +yaml_document_start_event_initialize(yaml_event_t *event, + yaml_version_directive_t *version_directive, + yaml_tag_directive_t *tag_directives_start, + yaml_tag_directive_t *tag_directives_end, + int implicit); + +/** + * Create the DOCUMENT-END event. + * + * The @a implicit argument is considered as a stylistic parameter and may be + * ignored by the emitter. + * + * @param[out] event An empty event object. + * @param[in] implicit If the document end indicator is implicit. + * + * @returns @c 1 if the function succeeded, @c 0 on error. + */ + +YAML_DECLARE(int) +yaml_document_end_event_initialize(yaml_event_t *event, int implicit); + +/** + * Create an ALIAS event. + * + * @param[out] event An empty event object. + * @param[in] anchor The anchor value. + * + * @returns @c 1 if the function succeeded, @c 0 on error. + */ + +YAML_DECLARE(int) +yaml_alias_event_initialize(yaml_event_t *event, yaml_char_t *anchor); + +/** + * Create a SCALAR event. + * + * The @a style argument may be ignored by the emitter. + * + * Either the @a tag attribute or one of the @a plain_implicit and + * @a quoted_implicit flags must be set. + * + * @param[out] event An empty event object. + * @param[in] anchor The scalar anchor or @c NULL. + * @param[in] tag The scalar tag or @c NULL. + * @param[in] value The scalar value. + * @param[in] length The length of the scalar value. + * @param[in] plain_implicit If the tag may be omitted for the plain + * style. + * @param[in] quoted_implicit If the tag may be omitted for any + * non-plain style. + * @param[in] style The scalar style. + * + * @returns @c 1 if the function succeeded, @c 0 on error. + */ + +YAML_DECLARE(int) +yaml_scalar_event_initialize(yaml_event_t *event, + yaml_char_t *anchor, yaml_char_t *tag, + yaml_char_t *value, int length, + int plain_implicit, int quoted_implicit, + yaml_scalar_style_t style); + +/** + * Create a SEQUENCE-START event. + * + * The @a style argument may be ignored by the emitter. + * + * Either the @a tag attribute or the @a implicit flag must be set. + * + * @param[out] event An empty event object. + * @param[in] anchor The sequence anchor or @c NULL. + * @param[in] tag The sequence tag or @c NULL. + * @param[in] implicit If the tag may be omitted. + * @param[in] style The sequence style. + * + * @returns @c 1 if the function succeeded, @c 0 on error. + */ + +YAML_DECLARE(int) +yaml_sequence_start_event_initialize(yaml_event_t *event, + yaml_char_t *anchor, yaml_char_t *tag, int implicit, + yaml_sequence_style_t style); + +/** + * Create a SEQUENCE-END event. + * + * @param[out] event An empty event object. + * + * @returns @c 1 if the function succeeded, @c 0 on error. + */ + +YAML_DECLARE(int) +yaml_sequence_end_event_initialize(yaml_event_t *event); + +/** + * Create a MAPPING-START event. + * + * The @a style argument may be ignored by the emitter. + * + * Either the @a tag attribute or the @a implicit flag must be set. + * + * @param[out] event An empty event object. + * @param[in] anchor The mapping anchor or @c NULL. + * @param[in] tag The mapping tag or @c NULL. + * @param[in] implicit If the tag may be omitted. + * @param[in] style The mapping style. + * + * @returns @c 1 if the function succeeded, @c 0 on error. + */ + +YAML_DECLARE(int) +yaml_mapping_start_event_initialize(yaml_event_t *event, + yaml_char_t *anchor, yaml_char_t *tag, int implicit, + yaml_mapping_style_t style); + +/** + * Create a MAPPING-END event. + * + * @param[out] event An empty event object. + * + * @returns @c 1 if the function succeeded, @c 0 on error. + */ + +YAML_DECLARE(int) +yaml_mapping_end_event_initialize(yaml_event_t *event); + +/** + * Free any memory allocated for an event object. + * + * @param[in,out] event An event object. + */ + +YAML_DECLARE(void) +yaml_event_delete(yaml_event_t *event); + +/** @} */ + +/** + * @defgroup nodes Nodes + * @{ + */ + +/** The tag @c !!null with the only possible value: @c null. */ +#define YAML_NULL_TAG "tag:yaml.org,2002:null" +/** The tag @c !!bool with the values: @c true and @c falce. */ +#define YAML_BOOL_TAG "tag:yaml.org,2002:bool" +/** The tag @c !!str for string values. */ +#define YAML_STR_TAG "tag:yaml.org,2002:str" +/** The tag @c !!int for integer values. */ +#define YAML_INT_TAG "tag:yaml.org,2002:int" +/** The tag @c !!float for float values. */ +#define YAML_FLOAT_TAG "tag:yaml.org,2002:float" +/** The tag @c !!timestamp for date and time values. */ +#define YAML_TIMESTAMP_TAG "tag:yaml.org,2002:timestamp" + +/** The tag @c !!seq is used to denote sequences. */ +#define YAML_SEQ_TAG "tag:yaml.org,2002:seq" +/** The tag @c !!map is used to denote mapping. */ +#define YAML_MAP_TAG "tag:yaml.org,2002:map" + +/** The default scalar tag is @c !!str. */ +#define YAML_DEFAULT_SCALAR_TAG YAML_STR_TAG +/** The default sequence tag is @c !!seq. */ +#define YAML_DEFAULT_SEQUENCE_TAG YAML_SEQ_TAG +/** The default mapping tag is @c !!map. */ +#define YAML_DEFAULT_MAPPING_TAG YAML_MAP_TAG + +/** Node types. */ +typedef enum yaml_node_type_e { + /** An empty node. */ + YAML_NO_NODE, + + /** A scalar node. */ + YAML_SCALAR_NODE, + /** A sequence node. */ + YAML_SEQUENCE_NODE, + /** A mapping node. */ + YAML_MAPPING_NODE +} yaml_node_type_t; + +/** The forward definition of a document node structure. */ +typedef struct yaml_node_s yaml_node_t; + +/** An element of a sequence node. */ +typedef int yaml_node_item_t; + +/** An element of a mapping node. */ +typedef struct yaml_node_pair_s { + /** The key of the element. */ + int key; + /** The value of the element. */ + int value; +} yaml_node_pair_t; + +/** The node structure. */ +struct yaml_node_s { + + /** The node type. */ + yaml_node_type_t type; + + /** The node tag. */ + yaml_char_t *tag; + + /** The node data. */ + union { + + /** The scalar parameters (for @c YAML_SCALAR_NODE). */ + struct { + /** The scalar value. */ + yaml_char_t *value; + /** The length of the scalar value. */ + size_t length; + /** The scalar style. */ + yaml_scalar_style_t style; + } scalar; + + /** The sequence parameters (for @c YAML_SEQUENCE_NODE). */ + struct { + /** The stack of sequence items. */ + struct { + /** The beginning of the stack. */ + yaml_node_item_t *start; + /** The end of the stack. */ + yaml_node_item_t *end; + /** The top of the stack. */ + yaml_node_item_t *top; + } items; + /** The sequence style. */ + yaml_sequence_style_t style; + } sequence; + + /** The mapping parameters (for @c YAML_MAPPING_NODE). */ + struct { + /** The stack of mapping pairs (key, value). */ + struct { + /** The beginning of the stack. */ + yaml_node_pair_t *start; + /** The end of the stack. */ + yaml_node_pair_t *end; + /** The top of the stack. */ + yaml_node_pair_t *top; + } pairs; + /** The mapping style. */ + yaml_mapping_style_t style; + } mapping; + + } data; + + /** The beginning of the node. */ + yaml_mark_t start_mark; + /** The end of the node. */ + yaml_mark_t end_mark; + +}; + +/** The document structure. */ +typedef struct yaml_document_s { + + /** The document nodes. */ + struct { + /** The beginning of the stack. */ + yaml_node_t *start; + /** The end of the stack. */ + yaml_node_t *end; + /** The top of the stack. */ + yaml_node_t *top; + } nodes; + + /** The version directive. */ + yaml_version_directive_t *version_directive; + + /** The list of tag directives. */ + struct { + /** The beginning of the tag directives list. */ + yaml_tag_directive_t *start; + /** The end of the tag directives list. */ + yaml_tag_directive_t *end; + } tag_directives; + + /** Is the document start indicator implicit? */ + int start_implicit; + /** Is the document end indicator implicit? */ + int end_implicit; + + /** The beginning of the document. */ + yaml_mark_t start_mark; + /** The end of the document. */ + yaml_mark_t end_mark; + +} yaml_document_t; + +/** + * Create a YAML document. + * + * @param[out] document An empty document object. + * @param[in] version_directive The %YAML directive value or + * @c NULL. + * @param[in] tag_directives_start The beginning of the %TAG + * directives list. + * @param[in] tag_directives_end The end of the %TAG directives + * list. + * @param[in] start_implicit If the document start indicator is + * implicit. + * @param[in] end_implicit If the document end indicator is + * implicit. + * + * @returns @c 1 if the function succeeded, @c 0 on error. + */ + +YAML_DECLARE(int) +yaml_document_initialize(yaml_document_t *document, + yaml_version_directive_t *version_directive, + yaml_tag_directive_t *tag_directives_start, + yaml_tag_directive_t *tag_directives_end, + int start_implicit, int end_implicit); + +/** + * Delete a YAML document and all its nodes. + * + * @param[in,out] document A document object. + */ + +YAML_DECLARE(void) +yaml_document_delete(yaml_document_t *document); + +/** + * Get a node of a YAML document. + * + * The pointer returned by this function is valid until any of the functions + * modifying the documents are called. + * + * @param[in] document A document object. + * @param[in] index The node id. + * + * @returns the node objct or @c NULL if @c node_id is out of range. + */ + +YAML_DECLARE(yaml_node_t *) +yaml_document_get_node(yaml_document_t *document, int index); + +/** + * Get the root of a YAML document node. + * + * The root object is the first object added to the document. + * + * The pointer returned by this function is valid until any of the functions + * modifying the documents are called. + * + * An empty document produced by the parser signifies the end of a YAML + * stream. + * + * @param[in] document A document object. + * + * @returns the node object or @c NULL if the document is empty. + */ + +YAML_DECLARE(yaml_node_t *) +yaml_document_get_root_node(yaml_document_t *document); + +/** + * Create a SCALAR node and attach it to the document. + * + * The @a style argument may be ignored by the emitter. + * + * @param[in,out] document A document object. + * @param[in] tag The scalar tag. + * @param[in] value The scalar value. + * @param[in] length The length of the scalar value. + * @param[in] style The scalar style. + * + * @returns the node id or @c 0 on error. + */ + +YAML_DECLARE(int) +yaml_document_add_scalar(yaml_document_t *document, + yaml_char_t *tag, yaml_char_t *value, int length, + yaml_scalar_style_t style); + +/** + * Create a SEQUENCE node and attach it to the document. + * + * The @a style argument may be ignored by the emitter. + * + * @param[in,out] document A document object. + * @param[in] tag The sequence tag. + * @param[in] style The sequence style. + * + * @returns the node id or @c 0 on error. + */ + +YAML_DECLARE(int) +yaml_document_add_sequence(yaml_document_t *document, + yaml_char_t *tag, yaml_sequence_style_t style); + +/** + * Create a MAPPING node and attach it to the document. + * + * The @a style argument may be ignored by the emitter. + * + * @param[in,out] document A document object. + * @param[in] tag The sequence tag. + * @param[in] style The sequence style. + * + * @returns the node id or @c 0 on error. + */ + +YAML_DECLARE(int) +yaml_document_add_mapping(yaml_document_t *document, + yaml_char_t *tag, yaml_mapping_style_t style); + +/** + * Add an item to a SEQUENCE node. + * + * @param[in,out] document A document object. + * @param[in] sequence The sequence node id. + * @param[in] item The item node id. +* + * @returns @c 1 if the function succeeded, @c 0 on error. + */ + +YAML_DECLARE(int) +yaml_document_append_sequence_item(yaml_document_t *document, + int sequence, int item); + +/** + * Add a pair of a key and a value to a MAPPING node. + * + * @param[in,out] document A document object. + * @param[in] mapping The mapping node id. + * @param[in] key The key node id. + * @param[in] value The value node id. +* + * @returns @c 1 if the function succeeded, @c 0 on error. + */ + +YAML_DECLARE(int) +yaml_document_append_mapping_pair(yaml_document_t *document, + int mapping, int key, int value); + +/** @} */ + +/** + * @defgroup parser Parser Definitions + * @{ + */ + +/** + * The prototype of a read handler. + * + * The read handler is called when the parser needs to read more bytes from the + * source. The handler should write not more than @a size bytes to the @a + * buffer. The number of written bytes should be set to the @a length variable. + * + * @param[in,out] data A pointer to an application data specified by + * yaml_parser_set_input(). + * @param[out] buffer The buffer to write the data from the source. + * @param[in] size The size of the buffer. + * @param[out] size_read The actual number of bytes read from the source. + * + * @returns On success, the handler should return @c 1. If the handler failed, + * the returned value should be @c 0. On EOF, the handler should set the + * @a size_read to @c 0 and return @c 1. + */ + +typedef int yaml_read_handler_t(void *data, unsigned char *buffer, size_t size, + size_t *size_read); + +/** + * This structure holds information about a potential simple key. + */ + +typedef struct yaml_simple_key_s { + /** Is a simple key possible? */ + int possible; + + /** Is a simple key required? */ + int required; + + /** The number of the token. */ + size_t token_number; + + /** The position mark. */ + yaml_mark_t mark; +} yaml_simple_key_t; + +/** + * The states of the parser. + */ +typedef enum yaml_parser_state_e { + /** Expect STREAM-START. */ + YAML_PARSE_STREAM_START_STATE, + /** Expect the beginning of an implicit document. */ + YAML_PARSE_IMPLICIT_DOCUMENT_START_STATE, + /** Expect DOCUMENT-START. */ + YAML_PARSE_DOCUMENT_START_STATE, + /** Expect the content of a document. */ + YAML_PARSE_DOCUMENT_CONTENT_STATE, + /** Expect DOCUMENT-END. */ + YAML_PARSE_DOCUMENT_END_STATE, + /** Expect a block node. */ + YAML_PARSE_BLOCK_NODE_STATE, + /** Expect a block node or indentless sequence. */ + YAML_PARSE_BLOCK_NODE_OR_INDENTLESS_SEQUENCE_STATE, + /** Expect a flow node. */ + YAML_PARSE_FLOW_NODE_STATE, + /** Expect the first entry of a block sequence. */ + YAML_PARSE_BLOCK_SEQUENCE_FIRST_ENTRY_STATE, + /** Expect an entry of a block sequence. */ + YAML_PARSE_BLOCK_SEQUENCE_ENTRY_STATE, + /** Expect an entry of an indentless sequence. */ + YAML_PARSE_INDENTLESS_SEQUENCE_ENTRY_STATE, + /** Expect the first key of a block mapping. */ + YAML_PARSE_BLOCK_MAPPING_FIRST_KEY_STATE, + /** Expect a block mapping key. */ + YAML_PARSE_BLOCK_MAPPING_KEY_STATE, + /** Expect a block mapping value. */ + YAML_PARSE_BLOCK_MAPPING_VALUE_STATE, + /** Expect the first entry of a flow sequence. */ + YAML_PARSE_FLOW_SEQUENCE_FIRST_ENTRY_STATE, + /** Expect an entry of a flow sequence. */ + YAML_PARSE_FLOW_SEQUENCE_ENTRY_STATE, + /** Expect a key of an ordered mapping. */ + YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_KEY_STATE, + /** Expect a value of an ordered mapping. */ + YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_VALUE_STATE, + /** Expect the and of an ordered mapping entry. */ + YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_END_STATE, + /** Expect the first key of a flow mapping. */ + YAML_PARSE_FLOW_MAPPING_FIRST_KEY_STATE, + /** Expect a key of a flow mapping. */ + YAML_PARSE_FLOW_MAPPING_KEY_STATE, + /** Expect a value of a flow mapping. */ + YAML_PARSE_FLOW_MAPPING_VALUE_STATE, + /** Expect an empty value of a flow mapping. */ + YAML_PARSE_FLOW_MAPPING_EMPTY_VALUE_STATE, + /** Expect nothing. */ + YAML_PARSE_END_STATE +} yaml_parser_state_t; + +/** + * This structure holds aliases data. + */ + +typedef struct yaml_alias_data_s { + /** The anchor. */ + yaml_char_t *anchor; + /** The node id. */ + int index; + /** The anchor mark. */ + yaml_mark_t mark; +} yaml_alias_data_t; + +/** + * The parser structure. + * + * All members are internal. Manage the structure using the @c yaml_parser_ + * family of functions. + */ + +typedef struct yaml_parser_s { + + /** + * @name Error handling + * @{ + */ + + /** Error type. */ + yaml_error_type_t error; + /** Error description. */ + const char *problem; + /** The byte about which the problem occured. */ + size_t problem_offset; + /** The problematic value (@c -1 is none). */ + int problem_value; + /** The problem position. */ + yaml_mark_t problem_mark; + /** The error context. */ + const char *context; + /** The context position. */ + yaml_mark_t context_mark; + + /** + * @} + */ + + /** + * @name Reader stuff + * @{ + */ + + /** Read handler. */ + yaml_read_handler_t *read_handler; + + /** A pointer for passing to the read handler. */ + void *read_handler_data; + + /** Standard (string or file) input data. */ + union { + /** String input data. */ + struct { + /** The string start pointer. */ + const unsigned char *start; + /** The string end pointer. */ + const unsigned char *end; + /** The string current position. */ + const unsigned char *current; + } string; + + /** File input data. */ + FILE *file; + } input; + + /** EOF flag */ + int eof; + + /** The working buffer. */ + struct { + /** The beginning of the buffer. */ + yaml_char_t *start; + /** The end of the buffer. */ + yaml_char_t *end; + /** The current position of the buffer. */ + yaml_char_t *pointer; + /** The last filled position of the buffer. */ + yaml_char_t *last; + } buffer; + + /* The number of unread characters in the buffer. */ + size_t unread; + + /** The raw buffer. */ + struct { + /** The beginning of the buffer. */ + unsigned char *start; + /** The end of the buffer. */ + unsigned char *end; + /** The current position of the buffer. */ + unsigned char *pointer; + /** The last filled position of the buffer. */ + unsigned char *last; + } raw_buffer; + + /** The input encoding. */ + yaml_encoding_t encoding; + + /** The offset of the current position (in bytes). */ + size_t offset; + + /** The mark of the current position. */ + yaml_mark_t mark; + + /** + * @} + */ + + /** + * @name Scanner stuff + * @{ + */ + + /** Have we started to scan the input stream? */ + int stream_start_produced; + + /** Have we reached the end of the input stream? */ + int stream_end_produced; + + /** The number of unclosed '[' and '{' indicators. */ + int flow_level; + + /** The tokens queue. */ + struct { + /** The beginning of the tokens queue. */ + yaml_token_t *start; + /** The end of the tokens queue. */ + yaml_token_t *end; + /** The head of the tokens queue. */ + yaml_token_t *head; + /** The tail of the tokens queue. */ + yaml_token_t *tail; + } tokens; + + /** The number of tokens fetched from the queue. */ + size_t tokens_parsed; + + /* Does the tokens queue contain a token ready for dequeueing. */ + int token_available; + + /** The indentation levels stack. */ + struct { + /** The beginning of the stack. */ + int *start; + /** The end of the stack. */ + int *end; + /** The top of the stack. */ + int *top; + } indents; + + /** The current indentation level. */ + int indent; + + /** May a simple key occur at the current position? */ + int simple_key_allowed; + + /** The stack of simple keys. */ + struct { + /** The beginning of the stack. */ + yaml_simple_key_t *start; + /** The end of the stack. */ + yaml_simple_key_t *end; + /** The top of the stack. */ + yaml_simple_key_t *top; + } simple_keys; + + /** + * @} + */ + + /** + * @name Parser stuff + * @{ + */ + + /** The parser states stack. */ + struct { + /** The beginning of the stack. */ + yaml_parser_state_t *start; + /** The end of the stack. */ + yaml_parser_state_t *end; + /** The top of the stack. */ + yaml_parser_state_t *top; + } states; + + /** The current parser state. */ + yaml_parser_state_t state; + + /** The stack of marks. */ + struct { + /** The beginning of the stack. */ + yaml_mark_t *start; + /** The end of the stack. */ + yaml_mark_t *end; + /** The top of the stack. */ + yaml_mark_t *top; + } marks; + + /** The list of TAG directives. */ + struct { + /** The beginning of the list. */ + yaml_tag_directive_t *start; + /** The end of the list. */ + yaml_tag_directive_t *end; + /** The top of the list. */ + yaml_tag_directive_t *top; + } tag_directives; + + /** + * @} + */ + + /** + * @name Dumper stuff + * @{ + */ + + /** The alias data. */ + struct { + /** The beginning of the list. */ + yaml_alias_data_t *start; + /** The end of the list. */ + yaml_alias_data_t *end; + /** The top of the list. */ + yaml_alias_data_t *top; + } aliases; + + /** The currently parsed document. */ + yaml_document_t *document; + + /** + * @} + */ + +} yaml_parser_t; + +/** + * Initialize a parser. + * + * This function creates a new parser object. An application is responsible + * for destroying the object using the yaml_parser_delete() function. + * + * @param[out] parser An empty parser object. + * + * @returns @c 1 if the function succeeded, @c 0 on error. + */ + +YAML_DECLARE(int) +yaml_parser_initialize(yaml_parser_t *parser); + +/** + * Destroy a parser. + * + * @param[in,out] parser A parser object. + */ + +YAML_DECLARE(void) +yaml_parser_delete(yaml_parser_t *parser); + +/** + * Set a string input. + * + * Note that the @a input pointer must be valid while the @a parser object + * exists. The application is responsible for destroing @a input after + * destroying the @a parser. + * + * @param[in,out] parser A parser object. + * @param[in] input A source data. + * @param[in] size The length of the source data in bytes. + */ + +YAML_DECLARE(void) +yaml_parser_set_input_string(yaml_parser_t *parser, + const unsigned char *input, size_t size); + +/** + * Set a file input. + * + * @a file should be a file object open for reading. The application is + * responsible for closing the @a file. + * + * @param[in,out] parser A parser object. + * @param[in] file An open file. + */ + +YAML_DECLARE(void) +yaml_parser_set_input_file(yaml_parser_t *parser, FILE *file); + +/** + * Set a generic input handler. + * + * @param[in,out] parser A parser object. + * @param[in] handler A read handler. + * @param[in] data Any application data for passing to the read + * handler. + */ + +YAML_DECLARE(void) +yaml_parser_set_input(yaml_parser_t *parser, + yaml_read_handler_t *handler, void *data); + +/** + * Set the source encoding. + * + * @param[in,out] parser A parser object. + * @param[in] encoding The source encoding. + */ + +YAML_DECLARE(void) +yaml_parser_set_encoding(yaml_parser_t *parser, yaml_encoding_t encoding); + +/** + * Scan the input stream and produce the next token. + * + * Call the function subsequently to produce a sequence of tokens corresponding + * to the input stream. The initial token has the type + * @c YAML_STREAM_START_TOKEN while the ending token has the type + * @c YAML_STREAM_END_TOKEN. + * + * An application is responsible for freeing any buffers associated with the + * produced token object using the @c yaml_token_delete function. + * + * An application must not alternate the calls of yaml_parser_scan() with the + * calls of yaml_parser_parse() or yaml_parser_load(). Doing this will break + * the parser. + * + * @param[in,out] parser A parser object. + * @param[out] token An empty token object. + * + * @returns @c 1 if the function succeeded, @c 0 on error. + */ + +YAML_DECLARE(int) +yaml_parser_scan(yaml_parser_t *parser, yaml_token_t *token); + +/** + * Parse the input stream and produce the next parsing event. + * + * Call the function subsequently to produce a sequence of events corresponding + * to the input stream. The initial event has the type + * @c YAML_STREAM_START_EVENT while the ending event has the type + * @c YAML_STREAM_END_EVENT. + * + * An application is responsible for freeing any buffers associated with the + * produced event object using the yaml_event_delete() function. + * + * An application must not alternate the calls of yaml_parser_parse() with the + * calls of yaml_parser_scan() or yaml_parser_load(). Doing this will break the + * parser. + * + * @param[in,out] parser A parser object. + * @param[out] event An empty event object. + * + * @returns @c 1 if the function succeeded, @c 0 on error. + */ + +YAML_DECLARE(int) +yaml_parser_parse(yaml_parser_t *parser, yaml_event_t *event); + +/** + * Parse the input stream and produce the next YAML document. + * + * Call this function subsequently to produce a sequence of documents + * constituting the input stream. + * + * If the produced document has no root node, it means that the document + * end has been reached. + * + * An application is responsible for freeing any data associated with the + * produced document object using the yaml_document_delete() function. + * + * An application must not alternate the calls of yaml_parser_load() with the + * calls of yaml_parser_scan() or yaml_parser_parse(). Doing this will break + * the parser. + * + * @param[in,out] parser A parser object. + * @param[out] document An empty document object. + * + * @return @c 1 if the function succeeded, @c 0 on error. + */ + +YAML_DECLARE(int) +yaml_parser_load(yaml_parser_t *parser, yaml_document_t *document); + +/** @} */ + +/** + * @defgroup emitter Emitter Definitions + * @{ + */ + +/** + * The prototype of a write handler. + * + * The write handler is called when the emitter needs to flush the accumulated + * characters to the output. The handler should write @a size bytes of the + * @a buffer to the output. + * + * @param[in,out] data A pointer to an application data specified by + * yaml_emitter_set_output(). + * @param[in] buffer The buffer with bytes to be written. + * @param[in] size The size of the buffer. + * + * @returns On success, the handler should return @c 1. If the handler failed, + * the returned value should be @c 0. + */ + +typedef int yaml_write_handler_t(void *data, unsigned char *buffer, size_t size); + +/** The emitter states. */ +typedef enum yaml_emitter_state_e { + /** Expect STREAM-START. */ + YAML_EMIT_STREAM_START_STATE, + /** Expect the first DOCUMENT-START or STREAM-END. */ + YAML_EMIT_FIRST_DOCUMENT_START_STATE, + /** Expect DOCUMENT-START or STREAM-END. */ + YAML_EMIT_DOCUMENT_START_STATE, + /** Expect the content of a document. */ + YAML_EMIT_DOCUMENT_CONTENT_STATE, + /** Expect DOCUMENT-END. */ + YAML_EMIT_DOCUMENT_END_STATE, + /** Expect the first item of a flow sequence. */ + YAML_EMIT_FLOW_SEQUENCE_FIRST_ITEM_STATE, + /** Expect an item of a flow sequence. */ + YAML_EMIT_FLOW_SEQUENCE_ITEM_STATE, + /** Expect the first key of a flow mapping. */ + YAML_EMIT_FLOW_MAPPING_FIRST_KEY_STATE, + /** Expect a key of a flow mapping. */ + YAML_EMIT_FLOW_MAPPING_KEY_STATE, + /** Expect a value for a simple key of a flow mapping. */ + YAML_EMIT_FLOW_MAPPING_SIMPLE_VALUE_STATE, + /** Expect a value of a flow mapping. */ + YAML_EMIT_FLOW_MAPPING_VALUE_STATE, + /** Expect the first item of a block sequence. */ + YAML_EMIT_BLOCK_SEQUENCE_FIRST_ITEM_STATE, + /** Expect an item of a block sequence. */ + YAML_EMIT_BLOCK_SEQUENCE_ITEM_STATE, + /** Expect the first key of a block mapping. */ + YAML_EMIT_BLOCK_MAPPING_FIRST_KEY_STATE, + /** Expect the key of a block mapping. */ + YAML_EMIT_BLOCK_MAPPING_KEY_STATE, + /** Expect a value for a simple key of a block mapping. */ + YAML_EMIT_BLOCK_MAPPING_SIMPLE_VALUE_STATE, + /** Expect a value of a block mapping. */ + YAML_EMIT_BLOCK_MAPPING_VALUE_STATE, + /** Expect nothing. */ + YAML_EMIT_END_STATE +} yaml_emitter_state_t; + +/** + * The emitter structure. + * + * All members are internal. Manage the structure using the @c yaml_emitter_ + * family of functions. + */ + +typedef struct yaml_emitter_s { + + /** + * @name Error handling + * @{ + */ + + /** Error type. */ + yaml_error_type_t error; + /** Error description. */ + const char *problem; + + /** + * @} + */ + + /** + * @name Writer stuff + * @{ + */ + + /** Write handler. */ + yaml_write_handler_t *write_handler; + + /** A pointer for passing to the white handler. */ + void *write_handler_data; + + /** Standard (string or file) output data. */ + union { + /** String output data. */ + struct { + /** The buffer pointer. */ + unsigned char *buffer; + /** The buffer size. */ + size_t size; + /** The number of written bytes. */ + size_t *size_written; + } string; + + /** File output data. */ + FILE *file; + } output; + + /** The working buffer. */ + struct { + /** The beginning of the buffer. */ + yaml_char_t *start; + /** The end of the buffer. */ + yaml_char_t *end; + /** The current position of the buffer. */ + yaml_char_t *pointer; + /** The last filled position of the buffer. */ + yaml_char_t *last; + } buffer; + + /** The raw buffer. */ + struct { + /** The beginning of the buffer. */ + unsigned char *start; + /** The end of the buffer. */ + unsigned char *end; + /** The current position of the buffer. */ + unsigned char *pointer; + /** The last filled position of the buffer. */ + unsigned char *last; + } raw_buffer; + + /** The stream encoding. */ + yaml_encoding_t encoding; + + /** + * @} + */ + + /** + * @name Emitter stuff + * @{ + */ + + /** If the output is in the canonical style? */ + int canonical; + /** The number of indentation spaces. */ + int best_indent; + /** The preferred width of the output lines. */ + int best_width; + /** Allow unescaped non-ASCII characters? */ + int unicode; + /** The preferred line break. */ + yaml_break_t line_break; + + /** The stack of states. */ + struct { + /** The beginning of the stack. */ + yaml_emitter_state_t *start; + /** The end of the stack. */ + yaml_emitter_state_t *end; + /** The top of the stack. */ + yaml_emitter_state_t *top; + } states; + + /** The current emitter state. */ + yaml_emitter_state_t state; + + /** The event queue. */ + struct { + /** The beginning of the event queue. */ + yaml_event_t *start; + /** The end of the event queue. */ + yaml_event_t *end; + /** The head of the event queue. */ + yaml_event_t *head; + /** The tail of the event queue. */ + yaml_event_t *tail; + } events; + + /** The stack of indentation levels. */ + struct { + /** The beginning of the stack. */ + int *start; + /** The end of the stack. */ + int *end; + /** The top of the stack. */ + int *top; + } indents; + + /** The list of tag directives. */ + struct { + /** The beginning of the list. */ + yaml_tag_directive_t *start; + /** The end of the list. */ + yaml_tag_directive_t *end; + /** The top of the list. */ + yaml_tag_directive_t *top; + } tag_directives; + + /** The current indentation level. */ + int indent; + + /** The current flow level. */ + int flow_level; + + /** Is it the document root context? */ + int root_context; + /** Is it a sequence context? */ + int sequence_context; + /** Is it a mapping context? */ + int mapping_context; + /** Is it a simple mapping key context? */ + int simple_key_context; + + /** The current line. */ + int line; + /** The current column. */ + int column; + /** If the last character was a whitespace? */ + int whitespace; + /** If the last character was an indentation character (' ', '-', '?', ':')? */ + int indention; + /** If an explicit document end is required? */ + int open_ended; + + /** Anchor analysis. */ + struct { + /** The anchor value. */ + yaml_char_t *anchor; + /** The anchor length. */ + size_t anchor_length; + /** Is it an alias? */ + int alias; + } anchor_data; + + /** Tag analysis. */ + struct { + /** The tag handle. */ + yaml_char_t *handle; + /** The tag handle length. */ + size_t handle_length; + /** The tag suffix. */ + yaml_char_t *suffix; + /** The tag suffix length. */ + size_t suffix_length; + } tag_data; + + /** Scalar analysis. */ + struct { + /** The scalar value. */ + yaml_char_t *value; + /** The scalar length. */ + size_t length; + /** Does the scalar contain line breaks? */ + int multiline; + /** Can the scalar be expessed in the flow plain style? */ + int flow_plain_allowed; + /** Can the scalar be expressed in the block plain style? */ + int block_plain_allowed; + /** Can the scalar be expressed in the single quoted style? */ + int single_quoted_allowed; + /** Can the scalar be expressed in the literal or folded styles? */ + int block_allowed; + /** The output style. */ + yaml_scalar_style_t style; + } scalar_data; + + /** + * @} + */ + + /** + * @name Dumper stuff + * @{ + */ + + /** If the stream was already opened? */ + int opened; + /** If the stream was already closed? */ + int closed; + + /** The information associated with the document nodes. */ + struct { + /** The number of references. */ + int references; + /** The anchor id. */ + int anchor; + /** If the node has been emitted? */ + int serialized; + } *anchors; + + /** The last assigned anchor id. */ + int last_anchor_id; + + /** The currently emitted document. */ + yaml_document_t *document; + + /** + * @} + */ + +} yaml_emitter_t; + +/** + * Initialize an emitter. + * + * This function creates a new emitter object. An application is responsible + * for destroying the object using the yaml_emitter_delete() function. + * + * @param[out] emitter An empty parser object. + * + * @returns @c 1 if the function succeeded, @c 0 on error. + */ + +YAML_DECLARE(int) +yaml_emitter_initialize(yaml_emitter_t *emitter); + +/** + * Destroy an emitter. + * + * @param[in,out] emitter An emitter object. + */ + +YAML_DECLARE(void) +yaml_emitter_delete(yaml_emitter_t *emitter); + +/** + * Set a string output. + * + * The emitter will write the output characters to the @a output buffer of the + * size @a size. The emitter will set @a size_written to the number of written + * bytes. If the buffer is smaller than required, the emitter produces the + * YAML_WRITE_ERROR error. + * + * @param[in,out] emitter An emitter object. + * @param[in] output An output buffer. + * @param[in] size The buffer size. + * @param[in] size_written The pointer to save the number of written + * bytes. + */ + +YAML_DECLARE(void) +yaml_emitter_set_output_string(yaml_emitter_t *emitter, + unsigned char *output, size_t size, size_t *size_written); + +/** + * Set a file output. + * + * @a file should be a file object open for writing. The application is + * responsible for closing the @a file. + * + * @param[in,out] emitter An emitter object. + * @param[in] file An open file. + */ + +YAML_DECLARE(void) +yaml_emitter_set_output_file(yaml_emitter_t *emitter, FILE *file); + +/** + * Set a generic output handler. + * + * @param[in,out] emitter An emitter object. + * @param[in] handler A write handler. + * @param[in] data Any application data for passing to the write + * handler. + */ + +YAML_DECLARE(void) +yaml_emitter_set_output(yaml_emitter_t *emitter, + yaml_write_handler_t *handler, void *data); + +/** + * Set the output encoding. + * + * @param[in,out] emitter An emitter object. + * @param[in] encoding The output encoding. + */ + +YAML_DECLARE(void) +yaml_emitter_set_encoding(yaml_emitter_t *emitter, yaml_encoding_t encoding); + +/** + * Set if the output should be in the "canonical" format as in the YAML + * specification. + * + * @param[in,out] emitter An emitter object. + * @param[in] canonical If the output is canonical. + */ + +YAML_DECLARE(void) +yaml_emitter_set_canonical(yaml_emitter_t *emitter, int canonical); + +/** + * Set the intendation increment. + * + * @param[in,out] emitter An emitter object. + * @param[in] indent The indentation increment (1 < . < 10). + */ + +YAML_DECLARE(void) +yaml_emitter_set_indent(yaml_emitter_t *emitter, int indent); + +/** + * Set the preferred line width. @c -1 means unlimited. + * + * @param[in,out] emitter An emitter object. + * @param[in] width The preferred line width. + */ + +YAML_DECLARE(void) +yaml_emitter_set_width(yaml_emitter_t *emitter, int width); + +/** + * Set if unescaped non-ASCII characters are allowed. + * + * @param[in,out] emitter An emitter object. + * @param[in] unicode If unescaped Unicode characters are allowed. + */ + +YAML_DECLARE(void) +yaml_emitter_set_unicode(yaml_emitter_t *emitter, int unicode); + +/** + * Set the preferred line break. + * + * @param[in,out] emitter An emitter object. + * @param[in] line_break The preferred line break. + */ + +YAML_DECLARE(void) +yaml_emitter_set_break(yaml_emitter_t *emitter, yaml_break_t line_break); + +/** + * Emit an event. + * + * The event object may be generated using the yaml_parser_parse() function. + * The emitter takes the responsibility for the event object and destroys its + * content after it is emitted. The event object is destroyed even if the + * function fails. + * + * @param[in,out] emitter An emitter object. + * @param[in,out] event An event object. + * + * @returns @c 1 if the function succeeded, @c 0 on error. + */ + +YAML_DECLARE(int) +yaml_emitter_emit(yaml_emitter_t *emitter, yaml_event_t *event); + +/** + * Start a YAML stream. + * + * This function should be used before yaml_emitter_dump() is called. + * + * @param[in,out] emitter An emitter object. + * + * @returns @c 1 if the function succeeded, @c 0 on error. + */ + +YAML_DECLARE(int) +yaml_emitter_open(yaml_emitter_t *emitter); + +/** + * Finish a YAML stream. + * + * This function should be used after yaml_emitter_dump() is called. + * + * @param[in,out] emitter An emitter object. + * + * @returns @c 1 if the function succeeded, @c 0 on error. + */ + +YAML_DECLARE(int) +yaml_emitter_close(yaml_emitter_t *emitter); + +/** + * Emit a YAML document. + * + * The documen object may be generated using the yaml_parser_load() function + * or the yaml_document_initialize() function. The emitter takes the + * responsibility for the document object and destoys its content after + * it is emitted. The document object is destroyedeven if the function fails. + * + * @param[in,out] emitter An emitter object. + * @param[in,out] document A document object. + * + * @returns @c 1 if the function succeeded, @c 0 on error. + */ + +YAML_DECLARE(int) +yaml_emitter_dump(yaml_emitter_t *emitter, yaml_document_t *document); + +/** + * Flush the accumulated characters to the output. + * + * @param[in,out] emitter An emitter object. + * + * @returns @c 1 if the function succeeded, @c 0 on error. + */ + +YAML_DECLARE(int) +yaml_emitter_flush(yaml_emitter_t *emitter); + +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif /* #ifndef YAML_H */ + diff --git a/web/server/h2o/libh2o/deps/yaml/src/Makefile.am b/web/server/h2o/libh2o/deps/yaml/src/Makefile.am new file mode 100644 index 00000000..724a1b2d --- /dev/null +++ b/web/server/h2o/libh2o/deps/yaml/src/Makefile.am @@ -0,0 +1,4 @@ +AM_CPPFLAGS = -I$(top_srcdir)/include +lib_LTLIBRARIES = libyaml.la +libyaml_la_SOURCES = yaml_private.h api.c reader.c scanner.c parser.c loader.c writer.c emitter.c dumper.c +libyaml_la_LDFLAGS = -release $(YAML_LT_RELEASE) -version-info $(YAML_LT_CURRENT):$(YAML_LT_REVISION):$(YAML_LT_AGE) diff --git a/web/server/h2o/libh2o/deps/yaml/src/Makefile.in b/web/server/h2o/libh2o/deps/yaml/src/Makefile.in new file mode 100644 index 00000000..196236e7 --- /dev/null +++ b/web/server/h2o/libh2o/deps/yaml/src/Makefile.in @@ -0,0 +1,542 @@ +# Makefile.in generated by automake 1.11.3 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software +# Foundation, Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +subdir = src +DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; +am__install_max = 40 +am__nobase_strip_setup = \ + srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` +am__nobase_strip = \ + for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" +am__nobase_list = $(am__nobase_strip_setup); \ + for p in $$list; do echo "$$p $$p"; done | \ + sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ + $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ + if (++n[$$2] == $(am__install_max)) \ + { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ + END { for (dir in files) print dir, files[dir] }' +am__base_list = \ + sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ + sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +am__uninstall_files_from_dir = { \ + test -z "$$files" \ + || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ + || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ + $(am__cd) "$$dir" && rm -f $$files; }; \ + } +am__installdirs = "$(DESTDIR)$(libdir)" +LTLIBRARIES = $(lib_LTLIBRARIES) +libyaml_la_LIBADD = +am_libyaml_la_OBJECTS = api.lo reader.lo scanner.lo parser.lo \ + loader.lo writer.lo emitter.lo dumper.lo +libyaml_la_OBJECTS = $(am_libyaml_la_OBJECTS) +libyaml_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(libyaml_la_LDFLAGS) $(LDFLAGS) -o $@ +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/config/depcomp +am__depfiles_maybe = depfiles +am__mv = mv -f +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +CCLD = $(CC) +LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ + $(LDFLAGS) -o $@ +SOURCES = $(libyaml_la_SOURCES) +DIST_SOURCES = $(libyaml_la_SOURCES) +ETAGS = etags +CTAGS = ctags +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DOXYGEN = @DOXYGEN@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +GREP = @GREP@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +YAML_LT_AGE = @YAML_LT_AGE@ +YAML_LT_CURRENT = @YAML_LT_CURRENT@ +YAML_LT_RELEASE = @YAML_LT_RELEASE@ +YAML_LT_REVISION = @YAML_LT_REVISION@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +AM_CPPFLAGS = -I$(top_srcdir)/include +lib_LTLIBRARIES = libyaml.la +libyaml_la_SOURCES = yaml_private.h api.c reader.c scanner.c parser.c loader.c writer.c emitter.c dumper.c +libyaml_la_LDFLAGS = -release $(YAML_LT_RELEASE) -version-info $(YAML_LT_CURRENT):$(YAML_LT_REVISION):$(YAML_LT_AGE) +all: all-am + +.SUFFIXES: +.SUFFIXES: .c .lo .o .obj +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign src/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --foreign src/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): +install-libLTLIBRARIES: $(lib_LTLIBRARIES) + @$(NORMAL_INSTALL) + test -z "$(libdir)" || $(MKDIR_P) "$(DESTDIR)$(libdir)" + @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ + list2=; for p in $$list; do \ + if test -f $$p; then \ + list2="$$list2 $$p"; \ + else :; fi; \ + done; \ + test -z "$$list2" || { \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(libdir)'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(libdir)"; \ + } + +uninstall-libLTLIBRARIES: + @$(NORMAL_UNINSTALL) + @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ + for p in $$list; do \ + $(am__strip_dir) \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$f'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$f"; \ + done + +clean-libLTLIBRARIES: + -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES) + @list='$(lib_LTLIBRARIES)'; for p in $$list; do \ + dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \ + test "$$dir" != "$$p" || dir=.; \ + echo "rm -f \"$${dir}/so_locations\""; \ + rm -f "$${dir}/so_locations"; \ + done +libyaml.la: $(libyaml_la_OBJECTS) $(libyaml_la_DEPENDENCIES) $(EXTRA_libyaml_la_DEPENDENCIES) + $(libyaml_la_LINK) -rpath $(libdir) $(libyaml_la_OBJECTS) $(libyaml_la_LIBADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/api.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dumper.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/emitter.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/loader.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/parser.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/reader.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/scanner.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/writer.Plo@am__quote@ + +.c.o: +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c $< + +.c.obj: +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` + +.c.lo: +@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $< + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + set x; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: CTAGS +CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(LTLIBRARIES) +installdirs: + for dir in "$(DESTDIR)$(libdir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-libLTLIBRARIES clean-libtool \ + mostlyclean-am + +distclean: distclean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: install-libLTLIBRARIES + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-libLTLIBRARIES + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ + clean-libLTLIBRARIES clean-libtool ctags distclean \ + distclean-compile distclean-generic distclean-libtool \ + distclean-tags distdir dvi dvi-am html html-am info info-am \ + install install-am install-data install-data-am install-dvi \ + install-dvi-am install-exec install-exec-am install-html \ + install-html-am install-info install-info-am \ + install-libLTLIBRARIES install-man install-pdf install-pdf-am \ + install-ps install-ps-am install-strip installcheck \ + installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-compile \ + mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ + tags uninstall uninstall-am uninstall-libLTLIBRARIES + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/web/server/h2o/libh2o/deps/yaml/src/api.c b/web/server/h2o/libh2o/deps/yaml/src/api.c new file mode 100644 index 00000000..0c4732e1 --- /dev/null +++ b/web/server/h2o/libh2o/deps/yaml/src/api.c @@ -0,0 +1,1392 @@ + +#include "yaml_private.h" + +/* + * Get the library version. + */ + +YAML_DECLARE(const char *) +yaml_get_version_string(void) +{ + return YAML_VERSION_STRING; +} + +/* + * Get the library version numbers. + */ + +YAML_DECLARE(void) +yaml_get_version(int *major, int *minor, int *patch) +{ + *major = YAML_VERSION_MAJOR; + *minor = YAML_VERSION_MINOR; + *patch = YAML_VERSION_PATCH; +} + +/* + * Allocate a dynamic memory block. + */ + +YAML_DECLARE(void *) +yaml_malloc(size_t size) +{ + return malloc(size ? size : 1); +} + +/* + * Reallocate a dynamic memory block. + */ + +YAML_DECLARE(void *) +yaml_realloc(void *ptr, size_t size) +{ + return ptr ? realloc(ptr, size ? size : 1) : malloc(size ? size : 1); +} + +/* + * Free a dynamic memory block. + */ + +YAML_DECLARE(void) +yaml_free(void *ptr) +{ + if (ptr) free(ptr); +} + +/* + * Duplicate a string. + */ + +YAML_DECLARE(yaml_char_t *) +yaml_strdup(const yaml_char_t *str) +{ + if (!str) + return NULL; + + return (yaml_char_t *)strdup((char *)str); +} + +/* + * Extend a string. + */ + +YAML_DECLARE(int) +yaml_string_extend(yaml_char_t **start, + yaml_char_t **pointer, yaml_char_t **end) +{ + yaml_char_t *new_start = yaml_realloc(*start, (*end - *start)*2); + + if (!new_start) return 0; + + memset(new_start + (*end - *start), 0, *end - *start); + + *pointer = new_start + (*pointer - *start); + *end = new_start + (*end - *start)*2; + *start = new_start; + + return 1; +} + +/* + * Append a string B to a string A. + */ + +YAML_DECLARE(int) +yaml_string_join( + yaml_char_t **a_start, yaml_char_t **a_pointer, yaml_char_t **a_end, + yaml_char_t **b_start, yaml_char_t **b_pointer, yaml_char_t **b_end) +{ + if (*b_start == *b_pointer) + return 1; + + while (*a_end - *a_pointer <= *b_pointer - *b_start) { + if (!yaml_string_extend(a_start, a_pointer, a_end)) + return 0; + } + + memcpy(*a_pointer, *b_start, *b_pointer - *b_start); + *a_pointer += *b_pointer - *b_start; + + return 1; +} + +/* + * Extend a stack. + */ + +YAML_DECLARE(int) +yaml_stack_extend(void **start, void **top, void **end) +{ + void *new_start = yaml_realloc(*start, ((char *)*end - (char *)*start)*2); + + if (!new_start) return 0; + + *top = (char *)new_start + ((char *)*top - (char *)*start); + *end = (char *)new_start + ((char *)*end - (char *)*start)*2; + *start = new_start; + + return 1; +} + +/* + * Extend or move a queue. + */ + +YAML_DECLARE(int) +yaml_queue_extend(void **start, void **head, void **tail, void **end) +{ + /* Check if we need to resize the queue. */ + + if (*start == *head && *tail == *end) { + void *new_start = yaml_realloc(*start, + ((char *)*end - (char *)*start)*2); + + if (!new_start) return 0; + + *head = (char *)new_start + ((char *)*head - (char *)*start); + *tail = (char *)new_start + ((char *)*tail - (char *)*start); + *end = (char *)new_start + ((char *)*end - (char *)*start)*2; + *start = new_start; + } + + /* Check if we need to move the queue at the beginning of the buffer. */ + + if (*tail == *end) { + if (*head != *tail) { + memmove(*start, *head, (char *)*tail - (char *)*head); + } + *tail = (char *)*tail - (char *)*head + (char *)*start; + *head = *start; + } + + return 1; +} + + +/* + * Create a new parser object. + */ + +YAML_DECLARE(int) +yaml_parser_initialize(yaml_parser_t *parser) +{ + assert(parser); /* Non-NULL parser object expected. */ + + memset(parser, 0, sizeof(yaml_parser_t)); + if (!BUFFER_INIT(parser, parser->raw_buffer, INPUT_RAW_BUFFER_SIZE)) + goto error; + if (!BUFFER_INIT(parser, parser->buffer, INPUT_BUFFER_SIZE)) + goto error; + if (!QUEUE_INIT(parser, parser->tokens, INITIAL_QUEUE_SIZE)) + goto error; + if (!STACK_INIT(parser, parser->indents, INITIAL_STACK_SIZE)) + goto error; + if (!STACK_INIT(parser, parser->simple_keys, INITIAL_STACK_SIZE)) + goto error; + if (!STACK_INIT(parser, parser->states, INITIAL_STACK_SIZE)) + goto error; + if (!STACK_INIT(parser, parser->marks, INITIAL_STACK_SIZE)) + goto error; + if (!STACK_INIT(parser, parser->tag_directives, INITIAL_STACK_SIZE)) + goto error; + + return 1; + +error: + + BUFFER_DEL(parser, parser->raw_buffer); + BUFFER_DEL(parser, parser->buffer); + QUEUE_DEL(parser, parser->tokens); + STACK_DEL(parser, parser->indents); + STACK_DEL(parser, parser->simple_keys); + STACK_DEL(parser, parser->states); + STACK_DEL(parser, parser->marks); + STACK_DEL(parser, parser->tag_directives); + + return 0; +} + +/* + * Destroy a parser object. + */ + +YAML_DECLARE(void) +yaml_parser_delete(yaml_parser_t *parser) +{ + assert(parser); /* Non-NULL parser object expected. */ + + BUFFER_DEL(parser, parser->raw_buffer); + BUFFER_DEL(parser, parser->buffer); + while (!QUEUE_EMPTY(parser, parser->tokens)) { + yaml_token_delete(&DEQUEUE(parser, parser->tokens)); + } + QUEUE_DEL(parser, parser->tokens); + STACK_DEL(parser, parser->indents); + STACK_DEL(parser, parser->simple_keys); + STACK_DEL(parser, parser->states); + STACK_DEL(parser, parser->marks); + while (!STACK_EMPTY(parser, parser->tag_directives)) { + yaml_tag_directive_t tag_directive = POP(parser, parser->tag_directives); + yaml_free(tag_directive.handle); + yaml_free(tag_directive.prefix); + } + STACK_DEL(parser, parser->tag_directives); + + memset(parser, 0, sizeof(yaml_parser_t)); +} + +/* + * String read handler. + */ + +static int +yaml_string_read_handler(void *data, unsigned char *buffer, size_t size, + size_t *size_read) +{ + yaml_parser_t *parser = data; + + if (parser->input.string.current == parser->input.string.end) { + *size_read = 0; + return 1; + } + + if (size > (size_t)(parser->input.string.end + - parser->input.string.current)) { + size = parser->input.string.end - parser->input.string.current; + } + + memcpy(buffer, parser->input.string.current, size); + parser->input.string.current += size; + *size_read = size; + return 1; +} + +/* + * File read handler. + */ + +static int +yaml_file_read_handler(void *data, unsigned char *buffer, size_t size, + size_t *size_read) +{ + yaml_parser_t *parser = data; + + *size_read = fread(buffer, 1, size, parser->input.file); + return !ferror(parser->input.file); +} + +/* + * Set a string input. + */ + +YAML_DECLARE(void) +yaml_parser_set_input_string(yaml_parser_t *parser, + const unsigned char *input, size_t size) +{ + assert(parser); /* Non-NULL parser object expected. */ + assert(!parser->read_handler); /* You can set the source only once. */ + assert(input); /* Non-NULL input string expected. */ + + parser->read_handler = yaml_string_read_handler; + parser->read_handler_data = parser; + + parser->input.string.start = input; + parser->input.string.current = input; + parser->input.string.end = input+size; +} + +/* + * Set a file input. + */ + +YAML_DECLARE(void) +yaml_parser_set_input_file(yaml_parser_t *parser, FILE *file) +{ + assert(parser); /* Non-NULL parser object expected. */ + assert(!parser->read_handler); /* You can set the source only once. */ + assert(file); /* Non-NULL file object expected. */ + + parser->read_handler = yaml_file_read_handler; + parser->read_handler_data = parser; + + parser->input.file = file; +} + +/* + * Set a generic input. + */ + +YAML_DECLARE(void) +yaml_parser_set_input(yaml_parser_t *parser, + yaml_read_handler_t *handler, void *data) +{ + assert(parser); /* Non-NULL parser object expected. */ + assert(!parser->read_handler); /* You can set the source only once. */ + assert(handler); /* Non-NULL read handler expected. */ + + parser->read_handler = handler; + parser->read_handler_data = data; +} + +/* + * Set the source encoding. + */ + +YAML_DECLARE(void) +yaml_parser_set_encoding(yaml_parser_t *parser, yaml_encoding_t encoding) +{ + assert(parser); /* Non-NULL parser object expected. */ + assert(!parser->encoding); /* Encoding is already set or detected. */ + + parser->encoding = encoding; +} + +/* + * Create a new emitter object. + */ + +YAML_DECLARE(int) +yaml_emitter_initialize(yaml_emitter_t *emitter) +{ + assert(emitter); /* Non-NULL emitter object expected. */ + + memset(emitter, 0, sizeof(yaml_emitter_t)); + if (!BUFFER_INIT(emitter, emitter->buffer, OUTPUT_BUFFER_SIZE)) + goto error; + if (!BUFFER_INIT(emitter, emitter->raw_buffer, OUTPUT_RAW_BUFFER_SIZE)) + goto error; + if (!STACK_INIT(emitter, emitter->states, INITIAL_STACK_SIZE)) + goto error; + if (!QUEUE_INIT(emitter, emitter->events, INITIAL_QUEUE_SIZE)) + goto error; + if (!STACK_INIT(emitter, emitter->indents, INITIAL_STACK_SIZE)) + goto error; + if (!STACK_INIT(emitter, emitter->tag_directives, INITIAL_STACK_SIZE)) + goto error; + + return 1; + +error: + + BUFFER_DEL(emitter, emitter->buffer); + BUFFER_DEL(emitter, emitter->raw_buffer); + STACK_DEL(emitter, emitter->states); + QUEUE_DEL(emitter, emitter->events); + STACK_DEL(emitter, emitter->indents); + STACK_DEL(emitter, emitter->tag_directives); + + return 0; +} + +/* + * Destroy an emitter object. + */ + +YAML_DECLARE(void) +yaml_emitter_delete(yaml_emitter_t *emitter) +{ + assert(emitter); /* Non-NULL emitter object expected. */ + + BUFFER_DEL(emitter, emitter->buffer); + BUFFER_DEL(emitter, emitter->raw_buffer); + STACK_DEL(emitter, emitter->states); + while (!QUEUE_EMPTY(emitter, emitter->events)) { + yaml_event_delete(&DEQUEUE(emitter, emitter->events)); + } + QUEUE_DEL(emitter, emitter->events); + STACK_DEL(emitter, emitter->indents); + while (!STACK_EMPTY(empty, emitter->tag_directives)) { + yaml_tag_directive_t tag_directive = POP(emitter, emitter->tag_directives); + yaml_free(tag_directive.handle); + yaml_free(tag_directive.prefix); + } + STACK_DEL(emitter, emitter->tag_directives); + yaml_free(emitter->anchors); + + memset(emitter, 0, sizeof(yaml_emitter_t)); +} + +/* + * String write handler. + */ + +static int +yaml_string_write_handler(void *data, unsigned char *buffer, size_t size) +{ + yaml_emitter_t *emitter = data; + + if (emitter->output.string.size + *emitter->output.string.size_written + < size) { + memcpy(emitter->output.string.buffer + + *emitter->output.string.size_written, + buffer, + emitter->output.string.size + - *emitter->output.string.size_written); + *emitter->output.string.size_written = emitter->output.string.size; + return 0; + } + + memcpy(emitter->output.string.buffer + + *emitter->output.string.size_written, buffer, size); + *emitter->output.string.size_written += size; + return 1; +} + +/* + * File write handler. + */ + +static int +yaml_file_write_handler(void *data, unsigned char *buffer, size_t size) +{ + yaml_emitter_t *emitter = data; + + return (fwrite(buffer, 1, size, emitter->output.file) == size); +} +/* + * Set a string output. + */ + +YAML_DECLARE(void) +yaml_emitter_set_output_string(yaml_emitter_t *emitter, + unsigned char *output, size_t size, size_t *size_written) +{ + assert(emitter); /* Non-NULL emitter object expected. */ + assert(!emitter->write_handler); /* You can set the output only once. */ + assert(output); /* Non-NULL output string expected. */ + + emitter->write_handler = yaml_string_write_handler; + emitter->write_handler_data = emitter; + + emitter->output.string.buffer = output; + emitter->output.string.size = size; + emitter->output.string.size_written = size_written; + *size_written = 0; +} + +/* + * Set a file output. + */ + +YAML_DECLARE(void) +yaml_emitter_set_output_file(yaml_emitter_t *emitter, FILE *file) +{ + assert(emitter); /* Non-NULL emitter object expected. */ + assert(!emitter->write_handler); /* You can set the output only once. */ + assert(file); /* Non-NULL file object expected. */ + + emitter->write_handler = yaml_file_write_handler; + emitter->write_handler_data = emitter; + + emitter->output.file = file; +} + +/* + * Set a generic output handler. + */ + +YAML_DECLARE(void) +yaml_emitter_set_output(yaml_emitter_t *emitter, + yaml_write_handler_t *handler, void *data) +{ + assert(emitter); /* Non-NULL emitter object expected. */ + assert(!emitter->write_handler); /* You can set the output only once. */ + assert(handler); /* Non-NULL handler object expected. */ + + emitter->write_handler = handler; + emitter->write_handler_data = data; +} + +/* + * Set the output encoding. + */ + +YAML_DECLARE(void) +yaml_emitter_set_encoding(yaml_emitter_t *emitter, yaml_encoding_t encoding) +{ + assert(emitter); /* Non-NULL emitter object expected. */ + assert(!emitter->encoding); /* You can set encoding only once. */ + + emitter->encoding = encoding; +} + +/* + * Set the canonical output style. + */ + +YAML_DECLARE(void) +yaml_emitter_set_canonical(yaml_emitter_t *emitter, int canonical) +{ + assert(emitter); /* Non-NULL emitter object expected. */ + + emitter->canonical = (canonical != 0); +} + +/* + * Set the indentation increment. + */ + +YAML_DECLARE(void) +yaml_emitter_set_indent(yaml_emitter_t *emitter, int indent) +{ + assert(emitter); /* Non-NULL emitter object expected. */ + + emitter->best_indent = (1 < indent && indent < 10) ? indent : 2; +} + +/* + * Set the preferred line width. + */ + +YAML_DECLARE(void) +yaml_emitter_set_width(yaml_emitter_t *emitter, int width) +{ + assert(emitter); /* Non-NULL emitter object expected. */ + + emitter->best_width = (width >= 0) ? width : -1; +} + +/* + * Set if unescaped non-ASCII characters are allowed. + */ + +YAML_DECLARE(void) +yaml_emitter_set_unicode(yaml_emitter_t *emitter, int unicode) +{ + assert(emitter); /* Non-NULL emitter object expected. */ + + emitter->unicode = (unicode != 0); +} + +/* + * Set the preferred line break character. + */ + +YAML_DECLARE(void) +yaml_emitter_set_break(yaml_emitter_t *emitter, yaml_break_t line_break) +{ + assert(emitter); /* Non-NULL emitter object expected. */ + + emitter->line_break = line_break; +} + +/* + * Destroy a token object. + */ + +YAML_DECLARE(void) +yaml_token_delete(yaml_token_t *token) +{ + assert(token); /* Non-NULL token object expected. */ + + switch (token->type) + { + case YAML_TAG_DIRECTIVE_TOKEN: + yaml_free(token->data.tag_directive.handle); + yaml_free(token->data.tag_directive.prefix); + break; + + case YAML_ALIAS_TOKEN: + yaml_free(token->data.alias.value); + break; + + case YAML_ANCHOR_TOKEN: + yaml_free(token->data.anchor.value); + break; + + case YAML_TAG_TOKEN: + yaml_free(token->data.tag.handle); + yaml_free(token->data.tag.suffix); + break; + + case YAML_SCALAR_TOKEN: + yaml_free(token->data.scalar.value); + break; + + default: + break; + } + + memset(token, 0, sizeof(yaml_token_t)); +} + +/* + * Check if a string is a valid UTF-8 sequence. + * + * Check 'reader.c' for more details on UTF-8 encoding. + */ + +static int +yaml_check_utf8(yaml_char_t *start, size_t length) +{ + yaml_char_t *end = start+length; + yaml_char_t *pointer = start; + + while (pointer < end) { + unsigned char octet; + unsigned int width; + unsigned int value; + size_t k; + + octet = pointer[0]; + width = (octet & 0x80) == 0x00 ? 1 : + (octet & 0xE0) == 0xC0 ? 2 : + (octet & 0xF0) == 0xE0 ? 3 : + (octet & 0xF8) == 0xF0 ? 4 : 0; + value = (octet & 0x80) == 0x00 ? octet & 0x7F : + (octet & 0xE0) == 0xC0 ? octet & 0x1F : + (octet & 0xF0) == 0xE0 ? octet & 0x0F : + (octet & 0xF8) == 0xF0 ? octet & 0x07 : 0; + if (!width) return 0; + if (pointer+width > end) return 0; + for (k = 1; k < width; k ++) { + octet = pointer[k]; + if ((octet & 0xC0) != 0x80) return 0; + value = (value << 6) + (octet & 0x3F); + } + if (!((width == 1) || + (width == 2 && value >= 0x80) || + (width == 3 && value >= 0x800) || + (width == 4 && value >= 0x10000))) return 0; + + pointer += width; + } + + return 1; +} + +/* + * Create STREAM-START. + */ + +YAML_DECLARE(int) +yaml_stream_start_event_initialize(yaml_event_t *event, + yaml_encoding_t encoding) +{ + yaml_mark_t mark = { 0, 0, 0 }; + + assert(event); /* Non-NULL event object is expected. */ + + STREAM_START_EVENT_INIT(*event, encoding, mark, mark); + + return 1; +} + +/* + * Create STREAM-END. + */ + +YAML_DECLARE(int) +yaml_stream_end_event_initialize(yaml_event_t *event) +{ + yaml_mark_t mark = { 0, 0, 0 }; + + assert(event); /* Non-NULL event object is expected. */ + + STREAM_END_EVENT_INIT(*event, mark, mark); + + return 1; +} + +/* + * Create DOCUMENT-START. + */ + +YAML_DECLARE(int) +yaml_document_start_event_initialize(yaml_event_t *event, + yaml_version_directive_t *version_directive, + yaml_tag_directive_t *tag_directives_start, + yaml_tag_directive_t *tag_directives_end, + int implicit) +{ + struct { + yaml_error_type_t error; + } context; + yaml_mark_t mark = { 0, 0, 0 }; + yaml_version_directive_t *version_directive_copy = NULL; + struct { + yaml_tag_directive_t *start; + yaml_tag_directive_t *end; + yaml_tag_directive_t *top; + } tag_directives_copy = { NULL, NULL, NULL }; + yaml_tag_directive_t value = { NULL, NULL }; + + assert(event); /* Non-NULL event object is expected. */ + assert((tag_directives_start && tag_directives_end) || + (tag_directives_start == tag_directives_end)); + /* Valid tag directives are expected. */ + + if (version_directive) { + version_directive_copy = yaml_malloc(sizeof(yaml_version_directive_t)); + if (!version_directive_copy) goto error; + version_directive_copy->major = version_directive->major; + version_directive_copy->minor = version_directive->minor; + } + + if (tag_directives_start != tag_directives_end) { + yaml_tag_directive_t *tag_directive; + if (!STACK_INIT(&context, tag_directives_copy, INITIAL_STACK_SIZE)) + goto error; + for (tag_directive = tag_directives_start; + tag_directive != tag_directives_end; tag_directive ++) { + assert(tag_directive->handle); + assert(tag_directive->prefix); + if (!yaml_check_utf8(tag_directive->handle, + strlen((char *)tag_directive->handle))) + goto error; + if (!yaml_check_utf8(tag_directive->prefix, + strlen((char *)tag_directive->prefix))) + goto error; + value.handle = yaml_strdup(tag_directive->handle); + value.prefix = yaml_strdup(tag_directive->prefix); + if (!value.handle || !value.prefix) goto error; + if (!PUSH(&context, tag_directives_copy, value)) + goto error; + value.handle = NULL; + value.prefix = NULL; + } + } + + DOCUMENT_START_EVENT_INIT(*event, version_directive_copy, + tag_directives_copy.start, tag_directives_copy.top, + implicit, mark, mark); + + return 1; + +error: + yaml_free(version_directive_copy); + while (!STACK_EMPTY(context, tag_directives_copy)) { + yaml_tag_directive_t value = POP(context, tag_directives_copy); + yaml_free(value.handle); + yaml_free(value.prefix); + } + STACK_DEL(context, tag_directives_copy); + yaml_free(value.handle); + yaml_free(value.prefix); + + return 0; +} + +/* + * Create DOCUMENT-END. + */ + +YAML_DECLARE(int) +yaml_document_end_event_initialize(yaml_event_t *event, int implicit) +{ + yaml_mark_t mark = { 0, 0, 0 }; + + assert(event); /* Non-NULL emitter object is expected. */ + + DOCUMENT_END_EVENT_INIT(*event, implicit, mark, mark); + + return 1; +} + +/* + * Create ALIAS. + */ + +YAML_DECLARE(int) +yaml_alias_event_initialize(yaml_event_t *event, yaml_char_t *anchor) +{ + yaml_mark_t mark = { 0, 0, 0 }; + yaml_char_t *anchor_copy = NULL; + + assert(event); /* Non-NULL event object is expected. */ + assert(anchor); /* Non-NULL anchor is expected. */ + + if (!yaml_check_utf8(anchor, strlen((char *)anchor))) return 0; + + anchor_copy = yaml_strdup(anchor); + if (!anchor_copy) + return 0; + + ALIAS_EVENT_INIT(*event, anchor_copy, mark, mark); + + return 1; +} + +/* + * Create SCALAR. + */ + +YAML_DECLARE(int) +yaml_scalar_event_initialize(yaml_event_t *event, + yaml_char_t *anchor, yaml_char_t *tag, + yaml_char_t *value, int length, + int plain_implicit, int quoted_implicit, + yaml_scalar_style_t style) +{ + yaml_mark_t mark = { 0, 0, 0 }; + yaml_char_t *anchor_copy = NULL; + yaml_char_t *tag_copy = NULL; + yaml_char_t *value_copy = NULL; + + assert(event); /* Non-NULL event object is expected. */ + assert(value); /* Non-NULL anchor is expected. */ + + if (anchor) { + if (!yaml_check_utf8(anchor, strlen((char *)anchor))) goto error; + anchor_copy = yaml_strdup(anchor); + if (!anchor_copy) goto error; + } + + if (tag) { + if (!yaml_check_utf8(tag, strlen((char *)tag))) goto error; + tag_copy = yaml_strdup(tag); + if (!tag_copy) goto error; + } + + if (length < 0) { + length = strlen((char *)value); + } + + if (!yaml_check_utf8(value, length)) goto error; + value_copy = yaml_malloc(length+1); + if (!value_copy) goto error; + memcpy(value_copy, value, length); + value_copy[length] = '\0'; + + SCALAR_EVENT_INIT(*event, anchor_copy, tag_copy, value_copy, length, + plain_implicit, quoted_implicit, style, mark, mark); + + return 1; + +error: + yaml_free(anchor_copy); + yaml_free(tag_copy); + yaml_free(value_copy); + + return 0; +} + +/* + * Create SEQUENCE-START. + */ + +YAML_DECLARE(int) +yaml_sequence_start_event_initialize(yaml_event_t *event, + yaml_char_t *anchor, yaml_char_t *tag, int implicit, + yaml_sequence_style_t style) +{ + yaml_mark_t mark = { 0, 0, 0 }; + yaml_char_t *anchor_copy = NULL; + yaml_char_t *tag_copy = NULL; + + assert(event); /* Non-NULL event object is expected. */ + + if (anchor) { + if (!yaml_check_utf8(anchor, strlen((char *)anchor))) goto error; + anchor_copy = yaml_strdup(anchor); + if (!anchor_copy) goto error; + } + + if (tag) { + if (!yaml_check_utf8(tag, strlen((char *)tag))) goto error; + tag_copy = yaml_strdup(tag); + if (!tag_copy) goto error; + } + + SEQUENCE_START_EVENT_INIT(*event, anchor_copy, tag_copy, + implicit, style, mark, mark); + + return 1; + +error: + yaml_free(anchor_copy); + yaml_free(tag_copy); + + return 0; +} + +/* + * Create SEQUENCE-END. + */ + +YAML_DECLARE(int) +yaml_sequence_end_event_initialize(yaml_event_t *event) +{ + yaml_mark_t mark = { 0, 0, 0 }; + + assert(event); /* Non-NULL event object is expected. */ + + SEQUENCE_END_EVENT_INIT(*event, mark, mark); + + return 1; +} + +/* + * Create MAPPING-START. + */ + +YAML_DECLARE(int) +yaml_mapping_start_event_initialize(yaml_event_t *event, + yaml_char_t *anchor, yaml_char_t *tag, int implicit, + yaml_mapping_style_t style) +{ + yaml_mark_t mark = { 0, 0, 0 }; + yaml_char_t *anchor_copy = NULL; + yaml_char_t *tag_copy = NULL; + + assert(event); /* Non-NULL event object is expected. */ + + if (anchor) { + if (!yaml_check_utf8(anchor, strlen((char *)anchor))) goto error; + anchor_copy = yaml_strdup(anchor); + if (!anchor_copy) goto error; + } + + if (tag) { + if (!yaml_check_utf8(tag, strlen((char *)tag))) goto error; + tag_copy = yaml_strdup(tag); + if (!tag_copy) goto error; + } + + MAPPING_START_EVENT_INIT(*event, anchor_copy, tag_copy, + implicit, style, mark, mark); + + return 1; + +error: + yaml_free(anchor_copy); + yaml_free(tag_copy); + + return 0; +} + +/* + * Create MAPPING-END. + */ + +YAML_DECLARE(int) +yaml_mapping_end_event_initialize(yaml_event_t *event) +{ + yaml_mark_t mark = { 0, 0, 0 }; + + assert(event); /* Non-NULL event object is expected. */ + + MAPPING_END_EVENT_INIT(*event, mark, mark); + + return 1; +} + +/* + * Destroy an event object. + */ + +YAML_DECLARE(void) +yaml_event_delete(yaml_event_t *event) +{ + yaml_tag_directive_t *tag_directive; + + assert(event); /* Non-NULL event object expected. */ + + switch (event->type) + { + case YAML_DOCUMENT_START_EVENT: + yaml_free(event->data.document_start.version_directive); + for (tag_directive = event->data.document_start.tag_directives.start; + tag_directive != event->data.document_start.tag_directives.end; + tag_directive++) { + yaml_free(tag_directive->handle); + yaml_free(tag_directive->prefix); + } + yaml_free(event->data.document_start.tag_directives.start); + break; + + case YAML_ALIAS_EVENT: + yaml_free(event->data.alias.anchor); + break; + + case YAML_SCALAR_EVENT: + yaml_free(event->data.scalar.anchor); + yaml_free(event->data.scalar.tag); + yaml_free(event->data.scalar.value); + break; + + case YAML_SEQUENCE_START_EVENT: + yaml_free(event->data.sequence_start.anchor); + yaml_free(event->data.sequence_start.tag); + break; + + case YAML_MAPPING_START_EVENT: + yaml_free(event->data.mapping_start.anchor); + yaml_free(event->data.mapping_start.tag); + break; + + default: + break; + } + + memset(event, 0, sizeof(yaml_event_t)); +} + +/* + * Create a document object. + */ + +YAML_DECLARE(int) +yaml_document_initialize(yaml_document_t *document, + yaml_version_directive_t *version_directive, + yaml_tag_directive_t *tag_directives_start, + yaml_tag_directive_t *tag_directives_end, + int start_implicit, int end_implicit) +{ + struct { + yaml_error_type_t error; + } context; + struct { + yaml_node_t *start; + yaml_node_t *end; + yaml_node_t *top; + } nodes = { NULL, NULL, NULL }; + yaml_version_directive_t *version_directive_copy = NULL; + struct { + yaml_tag_directive_t *start; + yaml_tag_directive_t *end; + yaml_tag_directive_t *top; + } tag_directives_copy = { NULL, NULL, NULL }; + yaml_tag_directive_t value = { NULL, NULL }; + yaml_mark_t mark = { 0, 0, 0 }; + + assert(document); /* Non-NULL document object is expected. */ + assert((tag_directives_start && tag_directives_end) || + (tag_directives_start == tag_directives_end)); + /* Valid tag directives are expected. */ + + if (!STACK_INIT(&context, nodes, INITIAL_STACK_SIZE)) goto error; + + if (version_directive) { + version_directive_copy = yaml_malloc(sizeof(yaml_version_directive_t)); + if (!version_directive_copy) goto error; + version_directive_copy->major = version_directive->major; + version_directive_copy->minor = version_directive->minor; + } + + if (tag_directives_start != tag_directives_end) { + yaml_tag_directive_t *tag_directive; + if (!STACK_INIT(&context, tag_directives_copy, INITIAL_STACK_SIZE)) + goto error; + for (tag_directive = tag_directives_start; + tag_directive != tag_directives_end; tag_directive ++) { + assert(tag_directive->handle); + assert(tag_directive->prefix); + if (!yaml_check_utf8(tag_directive->handle, + strlen((char *)tag_directive->handle))) + goto error; + if (!yaml_check_utf8(tag_directive->prefix, + strlen((char *)tag_directive->prefix))) + goto error; + value.handle = yaml_strdup(tag_directive->handle); + value.prefix = yaml_strdup(tag_directive->prefix); + if (!value.handle || !value.prefix) goto error; + if (!PUSH(&context, tag_directives_copy, value)) + goto error; + value.handle = NULL; + value.prefix = NULL; + } + } + + DOCUMENT_INIT(*document, nodes.start, nodes.end, version_directive_copy, + tag_directives_copy.start, tag_directives_copy.top, + start_implicit, end_implicit, mark, mark); + + return 1; + +error: + STACK_DEL(&context, nodes); + yaml_free(version_directive_copy); + while (!STACK_EMPTY(&context, tag_directives_copy)) { + yaml_tag_directive_t value = POP(&context, tag_directives_copy); + yaml_free(value.handle); + yaml_free(value.prefix); + } + STACK_DEL(&context, tag_directives_copy); + yaml_free(value.handle); + yaml_free(value.prefix); + + return 0; +} + +/* + * Destroy a document object. + */ + +YAML_DECLARE(void) +yaml_document_delete(yaml_document_t *document) +{ + struct { + yaml_error_type_t error; + } context; + yaml_tag_directive_t *tag_directive; + + context.error = YAML_NO_ERROR; /* Eliminate a compliler warning. */ + + assert(document); /* Non-NULL document object is expected. */ + + while (!STACK_EMPTY(&context, document->nodes)) { + yaml_node_t node = POP(&context, document->nodes); + yaml_free(node.tag); + switch (node.type) { + case YAML_SCALAR_NODE: + yaml_free(node.data.scalar.value); + break; + case YAML_SEQUENCE_NODE: + STACK_DEL(&context, node.data.sequence.items); + break; + case YAML_MAPPING_NODE: + STACK_DEL(&context, node.data.mapping.pairs); + break; + default: + assert(0); /* Should not happen. */ + } + } + STACK_DEL(&context, document->nodes); + + yaml_free(document->version_directive); + for (tag_directive = document->tag_directives.start; + tag_directive != document->tag_directives.end; + tag_directive++) { + yaml_free(tag_directive->handle); + yaml_free(tag_directive->prefix); + } + yaml_free(document->tag_directives.start); + + memset(document, 0, sizeof(yaml_document_t)); +} + +/** + * Get a document node. + */ + +YAML_DECLARE(yaml_node_t *) +yaml_document_get_node(yaml_document_t *document, int index) +{ + assert(document); /* Non-NULL document object is expected. */ + + if (index > 0 && document->nodes.start + index <= document->nodes.top) { + return document->nodes.start + index - 1; + } + return NULL; +} + +/** + * Get the root object. + */ + +YAML_DECLARE(yaml_node_t *) +yaml_document_get_root_node(yaml_document_t *document) +{ + assert(document); /* Non-NULL document object is expected. */ + + if (document->nodes.top != document->nodes.start) { + return document->nodes.start; + } + return NULL; +} + +/* + * Add a scalar node to a document. + */ + +YAML_DECLARE(int) +yaml_document_add_scalar(yaml_document_t *document, + yaml_char_t *tag, yaml_char_t *value, int length, + yaml_scalar_style_t style) +{ + struct { + yaml_error_type_t error; + } context; + yaml_mark_t mark = { 0, 0, 0 }; + yaml_char_t *tag_copy = NULL; + yaml_char_t *value_copy = NULL; + yaml_node_t node; + + assert(document); /* Non-NULL document object is expected. */ + assert(value); /* Non-NULL value is expected. */ + + if (!tag) { + tag = (yaml_char_t *)YAML_DEFAULT_SCALAR_TAG; + } + + if (!yaml_check_utf8(tag, strlen((char *)tag))) goto error; + tag_copy = yaml_strdup(tag); + if (!tag_copy) goto error; + + if (length < 0) { + length = strlen((char *)value); + } + + if (!yaml_check_utf8(value, length)) goto error; + value_copy = yaml_malloc(length+1); + if (!value_copy) goto error; + memcpy(value_copy, value, length); + value_copy[length] = '\0'; + + SCALAR_NODE_INIT(node, tag_copy, value_copy, length, style, mark, mark); + if (!PUSH(&context, document->nodes, node)) goto error; + + return document->nodes.top - document->nodes.start; + +error: + yaml_free(tag_copy); + yaml_free(value_copy); + + return 0; +} + +/* + * Add a sequence node to a document. + */ + +YAML_DECLARE(int) +yaml_document_add_sequence(yaml_document_t *document, + yaml_char_t *tag, yaml_sequence_style_t style) +{ + struct { + yaml_error_type_t error; + } context; + yaml_mark_t mark = { 0, 0, 0 }; + yaml_char_t *tag_copy = NULL; + struct { + yaml_node_item_t *start; + yaml_node_item_t *end; + yaml_node_item_t *top; + } items = { NULL, NULL, NULL }; + yaml_node_t node; + + assert(document); /* Non-NULL document object is expected. */ + + if (!tag) { + tag = (yaml_char_t *)YAML_DEFAULT_SEQUENCE_TAG; + } + + if (!yaml_check_utf8(tag, strlen((char *)tag))) goto error; + tag_copy = yaml_strdup(tag); + if (!tag_copy) goto error; + + if (!STACK_INIT(&context, items, INITIAL_STACK_SIZE)) goto error; + + SEQUENCE_NODE_INIT(node, tag_copy, items.start, items.end, + style, mark, mark); + if (!PUSH(&context, document->nodes, node)) goto error; + + return document->nodes.top - document->nodes.start; + +error: + STACK_DEL(&context, items); + yaml_free(tag_copy); + + return 0; +} + +/* + * Add a mapping node to a document. + */ + +YAML_DECLARE(int) +yaml_document_add_mapping(yaml_document_t *document, + yaml_char_t *tag, yaml_mapping_style_t style) +{ + struct { + yaml_error_type_t error; + } context; + yaml_mark_t mark = { 0, 0, 0 }; + yaml_char_t *tag_copy = NULL; + struct { + yaml_node_pair_t *start; + yaml_node_pair_t *end; + yaml_node_pair_t *top; + } pairs = { NULL, NULL, NULL }; + yaml_node_t node; + + assert(document); /* Non-NULL document object is expected. */ + + if (!tag) { + tag = (yaml_char_t *)YAML_DEFAULT_MAPPING_TAG; + } + + if (!yaml_check_utf8(tag, strlen((char *)tag))) goto error; + tag_copy = yaml_strdup(tag); + if (!tag_copy) goto error; + + if (!STACK_INIT(&context, pairs, INITIAL_STACK_SIZE)) goto error; + + MAPPING_NODE_INIT(node, tag_copy, pairs.start, pairs.end, + style, mark, mark); + if (!PUSH(&context, document->nodes, node)) goto error; + + return document->nodes.top - document->nodes.start; + +error: + STACK_DEL(&context, pairs); + yaml_free(tag_copy); + + return 0; +} + +/* + * Append an item to a sequence node. + */ + +YAML_DECLARE(int) +yaml_document_append_sequence_item(yaml_document_t *document, + int sequence, int item) +{ + struct { + yaml_error_type_t error; + } context; + + assert(document); /* Non-NULL document is required. */ + assert(sequence > 0 + && document->nodes.start + sequence <= document->nodes.top); + /* Valid sequence id is required. */ + assert(document->nodes.start[sequence-1].type == YAML_SEQUENCE_NODE); + /* A sequence node is required. */ + assert(item > 0 && document->nodes.start + item <= document->nodes.top); + /* Valid item id is required. */ + + if (!PUSH(&context, + document->nodes.start[sequence-1].data.sequence.items, item)) + return 0; + + return 1; +} + +/* + * Append a pair of a key and a value to a mapping node. + */ + +YAML_DECLARE(int) +yaml_document_append_mapping_pair(yaml_document_t *document, + int mapping, int key, int value) +{ + struct { + yaml_error_type_t error; + } context; + + yaml_node_pair_t pair; + + assert(document); /* Non-NULL document is required. */ + assert(mapping > 0 + && document->nodes.start + mapping <= document->nodes.top); + /* Valid mapping id is required. */ + assert(document->nodes.start[mapping-1].type == YAML_MAPPING_NODE); + /* A mapping node is required. */ + assert(key > 0 && document->nodes.start + key <= document->nodes.top); + /* Valid key id is required. */ + assert(value > 0 && document->nodes.start + value <= document->nodes.top); + /* Valid value id is required. */ + + pair.key = key; + pair.value = value; + + if (!PUSH(&context, + document->nodes.start[mapping-1].data.mapping.pairs, pair)) + return 0; + + return 1; +} + + diff --git a/web/server/h2o/libh2o/deps/yaml/src/dumper.c b/web/server/h2o/libh2o/deps/yaml/src/dumper.c new file mode 100644 index 00000000..203c6a70 --- /dev/null +++ b/web/server/h2o/libh2o/deps/yaml/src/dumper.c @@ -0,0 +1,394 @@ + +#include "yaml_private.h" + +/* + * API functions. + */ + +YAML_DECLARE(int) +yaml_emitter_open(yaml_emitter_t *emitter); + +YAML_DECLARE(int) +yaml_emitter_close(yaml_emitter_t *emitter); + +YAML_DECLARE(int) +yaml_emitter_dump(yaml_emitter_t *emitter, yaml_document_t *document); + +/* + * Clean up functions. + */ + +static void +yaml_emitter_delete_document_and_anchors(yaml_emitter_t *emitter); + +/* + * Anchor functions. + */ + +static void +yaml_emitter_anchor_node(yaml_emitter_t *emitter, int index); + +static yaml_char_t * +yaml_emitter_generate_anchor(yaml_emitter_t *emitter, int anchor_id); + + +/* + * Serialize functions. + */ + +static int +yaml_emitter_dump_node(yaml_emitter_t *emitter, int index); + +static int +yaml_emitter_dump_alias(yaml_emitter_t *emitter, yaml_char_t *anchor); + +static int +yaml_emitter_dump_scalar(yaml_emitter_t *emitter, yaml_node_t *node, + yaml_char_t *anchor); + +static int +yaml_emitter_dump_sequence(yaml_emitter_t *emitter, yaml_node_t *node, + yaml_char_t *anchor); + +static int +yaml_emitter_dump_mapping(yaml_emitter_t *emitter, yaml_node_t *node, + yaml_char_t *anchor); + +/* + * Issue a STREAM-START event. + */ + +YAML_DECLARE(int) +yaml_emitter_open(yaml_emitter_t *emitter) +{ + yaml_event_t event; + yaml_mark_t mark = { 0, 0, 0 }; + + assert(emitter); /* Non-NULL emitter object is required. */ + assert(!emitter->opened); /* Emitter should not be opened yet. */ + + STREAM_START_EVENT_INIT(event, YAML_ANY_ENCODING, mark, mark); + + if (!yaml_emitter_emit(emitter, &event)) { + return 0; + } + + emitter->opened = 1; + + return 1; +} + +/* + * Issue a STREAM-END event. + */ + +YAML_DECLARE(int) +yaml_emitter_close(yaml_emitter_t *emitter) +{ + yaml_event_t event; + yaml_mark_t mark = { 0, 0, 0 }; + + assert(emitter); /* Non-NULL emitter object is required. */ + assert(emitter->opened); /* Emitter should be opened. */ + + if (emitter->closed) return 1; + + STREAM_END_EVENT_INIT(event, mark, mark); + + if (!yaml_emitter_emit(emitter, &event)) { + return 0; + } + + emitter->closed = 1; + + return 1; +} + +/* + * Dump a YAML document. + */ + +YAML_DECLARE(int) +yaml_emitter_dump(yaml_emitter_t *emitter, yaml_document_t *document) +{ + yaml_event_t event; + yaml_mark_t mark = { 0, 0, 0 }; + + assert(emitter); /* Non-NULL emitter object is required. */ + assert(document); /* Non-NULL emitter object is expected. */ + + emitter->document = document; + + if (!emitter->opened) { + if (!yaml_emitter_open(emitter)) goto error; + } + + if (STACK_EMPTY(emitter, document->nodes)) { + if (!yaml_emitter_close(emitter)) goto error; + yaml_emitter_delete_document_and_anchors(emitter); + return 1; + } + + assert(emitter->opened); /* Emitter should be opened. */ + + emitter->anchors = yaml_malloc(sizeof(*(emitter->anchors)) + * (document->nodes.top - document->nodes.start)); + if (!emitter->anchors) goto error; + memset(emitter->anchors, 0, sizeof(*(emitter->anchors)) + * (document->nodes.top - document->nodes.start)); + + DOCUMENT_START_EVENT_INIT(event, document->version_directive, + document->tag_directives.start, document->tag_directives.end, + document->start_implicit, mark, mark); + if (!yaml_emitter_emit(emitter, &event)) goto error; + + yaml_emitter_anchor_node(emitter, 1); + if (!yaml_emitter_dump_node(emitter, 1)) goto error; + + DOCUMENT_END_EVENT_INIT(event, document->end_implicit, mark, mark); + if (!yaml_emitter_emit(emitter, &event)) goto error; + + yaml_emitter_delete_document_and_anchors(emitter); + + return 1; + +error: + + yaml_emitter_delete_document_and_anchors(emitter); + + return 0; +} + +/* + * Clean up the emitter object after a document is dumped. + */ + +static void +yaml_emitter_delete_document_and_anchors(yaml_emitter_t *emitter) +{ + int index; + + if (!emitter->anchors) { + yaml_document_delete(emitter->document); + emitter->document = NULL; + return; + } + + for (index = 0; emitter->document->nodes.start + index + < emitter->document->nodes.top; index ++) { + yaml_node_t node = emitter->document->nodes.start[index]; + if (!emitter->anchors[index].serialized) { + yaml_free(node.tag); + if (node.type == YAML_SCALAR_NODE) { + yaml_free(node.data.scalar.value); + } + } + if (node.type == YAML_SEQUENCE_NODE) { + STACK_DEL(emitter, node.data.sequence.items); + } + if (node.type == YAML_MAPPING_NODE) { + STACK_DEL(emitter, node.data.mapping.pairs); + } + } + + STACK_DEL(emitter, emitter->document->nodes); + yaml_free(emitter->anchors); + + emitter->anchors = NULL; + emitter->last_anchor_id = 0; + emitter->document = NULL; +} + +/* + * Check the references of a node and assign the anchor id if needed. + */ + +static void +yaml_emitter_anchor_node(yaml_emitter_t *emitter, int index) +{ + yaml_node_t *node = emitter->document->nodes.start + index - 1; + yaml_node_item_t *item; + yaml_node_pair_t *pair; + + emitter->anchors[index-1].references ++; + + if (emitter->anchors[index-1].references == 1) { + switch (node->type) { + case YAML_SEQUENCE_NODE: + for (item = node->data.sequence.items.start; + item < node->data.sequence.items.top; item ++) { + yaml_emitter_anchor_node(emitter, *item); + } + break; + case YAML_MAPPING_NODE: + for (pair = node->data.mapping.pairs.start; + pair < node->data.mapping.pairs.top; pair ++) { + yaml_emitter_anchor_node(emitter, pair->key); + yaml_emitter_anchor_node(emitter, pair->value); + } + break; + default: + break; + } + } + + else if (emitter->anchors[index-1].references == 2) { + emitter->anchors[index-1].anchor = (++ emitter->last_anchor_id); + } +} + +/* + * Generate a textual representation for an anchor. + */ + +#define ANCHOR_TEMPLATE "id%03d" +#define ANCHOR_TEMPLATE_LENGTH 16 + +static yaml_char_t * +yaml_emitter_generate_anchor(yaml_emitter_t *emitter, int anchor_id) +{ + yaml_char_t *anchor = yaml_malloc(ANCHOR_TEMPLATE_LENGTH); + + if (!anchor) return NULL; + + sprintf((char *)anchor, ANCHOR_TEMPLATE, anchor_id); + + return anchor; +} + +/* + * Serialize a node. + */ + +static int +yaml_emitter_dump_node(yaml_emitter_t *emitter, int index) +{ + yaml_node_t *node = emitter->document->nodes.start + index - 1; + int anchor_id = emitter->anchors[index-1].anchor; + yaml_char_t *anchor = NULL; + + if (anchor_id) { + anchor = yaml_emitter_generate_anchor(emitter, anchor_id); + if (!anchor) return 0; + } + + if (emitter->anchors[index-1].serialized) { + return yaml_emitter_dump_alias(emitter, anchor); + } + + emitter->anchors[index-1].serialized = 1; + + switch (node->type) { + case YAML_SCALAR_NODE: + return yaml_emitter_dump_scalar(emitter, node, anchor); + case YAML_SEQUENCE_NODE: + return yaml_emitter_dump_sequence(emitter, node, anchor); + case YAML_MAPPING_NODE: + return yaml_emitter_dump_mapping(emitter, node, anchor); + default: + assert(0); /* Could not happen. */ + break; + } + + return 0; /* Could not happen. */ +} + +/* + * Serialize an alias. + */ + +static int +yaml_emitter_dump_alias(yaml_emitter_t *emitter, yaml_char_t *anchor) +{ + yaml_event_t event; + yaml_mark_t mark = { 0, 0, 0 }; + + ALIAS_EVENT_INIT(event, anchor, mark, mark); + + return yaml_emitter_emit(emitter, &event); +} + +/* + * Serialize a scalar. + */ + +static int +yaml_emitter_dump_scalar(yaml_emitter_t *emitter, yaml_node_t *node, + yaml_char_t *anchor) +{ + yaml_event_t event; + yaml_mark_t mark = { 0, 0, 0 }; + + int plain_implicit = (strcmp((char *)node->tag, + YAML_DEFAULT_SCALAR_TAG) == 0); + int quoted_implicit = (strcmp((char *)node->tag, + YAML_DEFAULT_SCALAR_TAG) == 0); + + SCALAR_EVENT_INIT(event, anchor, node->tag, node->data.scalar.value, + node->data.scalar.length, plain_implicit, quoted_implicit, + node->data.scalar.style, mark, mark); + + return yaml_emitter_emit(emitter, &event); +} + +/* + * Serialize a sequence. + */ + +static int +yaml_emitter_dump_sequence(yaml_emitter_t *emitter, yaml_node_t *node, + yaml_char_t *anchor) +{ + yaml_event_t event; + yaml_mark_t mark = { 0, 0, 0 }; + + int implicit = (strcmp((char *)node->tag, YAML_DEFAULT_SEQUENCE_TAG) == 0); + + yaml_node_item_t *item; + + SEQUENCE_START_EVENT_INIT(event, anchor, node->tag, implicit, + node->data.sequence.style, mark, mark); + if (!yaml_emitter_emit(emitter, &event)) return 0; + + for (item = node->data.sequence.items.start; + item < node->data.sequence.items.top; item ++) { + if (!yaml_emitter_dump_node(emitter, *item)) return 0; + } + + SEQUENCE_END_EVENT_INIT(event, mark, mark); + if (!yaml_emitter_emit(emitter, &event)) return 0; + + return 1; +} + +/* + * Serialize a mapping. + */ + +static int +yaml_emitter_dump_mapping(yaml_emitter_t *emitter, yaml_node_t *node, + yaml_char_t *anchor) +{ + yaml_event_t event; + yaml_mark_t mark = { 0, 0, 0 }; + + int implicit = (strcmp((char *)node->tag, YAML_DEFAULT_MAPPING_TAG) == 0); + + yaml_node_pair_t *pair; + + MAPPING_START_EVENT_INIT(event, anchor, node->tag, implicit, + node->data.mapping.style, mark, mark); + if (!yaml_emitter_emit(emitter, &event)) return 0; + + for (pair = node->data.mapping.pairs.start; + pair < node->data.mapping.pairs.top; pair ++) { + if (!yaml_emitter_dump_node(emitter, pair->key)) return 0; + if (!yaml_emitter_dump_node(emitter, pair->value)) return 0; + } + + MAPPING_END_EVENT_INIT(event, mark, mark); + if (!yaml_emitter_emit(emitter, &event)) return 0; + + return 1; +} + diff --git a/web/server/h2o/libh2o/deps/yaml/src/emitter.c b/web/server/h2o/libh2o/deps/yaml/src/emitter.c new file mode 100644 index 00000000..c4b56a26 --- /dev/null +++ b/web/server/h2o/libh2o/deps/yaml/src/emitter.c @@ -0,0 +1,2329 @@ + +#include "yaml_private.h" + +/* + * Flush the buffer if needed. + */ + +#define FLUSH(emitter) \ + ((emitter->buffer.pointer+5 < emitter->buffer.end) \ + || yaml_emitter_flush(emitter)) + +/* + * Put a character to the output buffer. + */ + +#define PUT(emitter,value) \ + (FLUSH(emitter) \ + && (*(emitter->buffer.pointer++) = (yaml_char_t)(value), \ + emitter->column ++, \ + 1)) + +/* + * Put a line break to the output buffer. + */ + +#define PUT_BREAK(emitter) \ + (FLUSH(emitter) \ + && ((emitter->line_break == YAML_CR_BREAK ? \ + (*(emitter->buffer.pointer++) = (yaml_char_t) '\r') : \ + emitter->line_break == YAML_LN_BREAK ? \ + (*(emitter->buffer.pointer++) = (yaml_char_t) '\n') : \ + emitter->line_break == YAML_CRLN_BREAK ? \ + (*(emitter->buffer.pointer++) = (yaml_char_t) '\r', \ + *(emitter->buffer.pointer++) = (yaml_char_t) '\n') : 0), \ + emitter->column = 0, \ + emitter->line ++, \ + 1)) + +/* + * Copy a character from a string into buffer. + */ + +#define WRITE(emitter,string) \ + (FLUSH(emitter) \ + && (COPY(emitter->buffer,string), \ + emitter->column ++, \ + 1)) + +/* + * Copy a line break character from a string into buffer. + */ + +#define WRITE_BREAK(emitter,string) \ + (FLUSH(emitter) \ + && (CHECK(string,'\n') ? \ + (PUT_BREAK(emitter), \ + string.pointer ++, \ + 1) : \ + (COPY(emitter->buffer,string), \ + emitter->column = 0, \ + emitter->line ++, \ + 1))) + +/* + * API functions. + */ + +YAML_DECLARE(int) +yaml_emitter_emit(yaml_emitter_t *emitter, yaml_event_t *event); + +/* + * Utility functions. + */ + +static int +yaml_emitter_set_emitter_error(yaml_emitter_t *emitter, const char *problem); + +static int +yaml_emitter_need_more_events(yaml_emitter_t *emitter); + +static int +yaml_emitter_append_tag_directive(yaml_emitter_t *emitter, + yaml_tag_directive_t value, int allow_duplicates); + +static int +yaml_emitter_increase_indent(yaml_emitter_t *emitter, + int flow, int indentless); + +/* + * State functions. + */ + +static int +yaml_emitter_state_machine(yaml_emitter_t *emitter, yaml_event_t *event); + +static int +yaml_emitter_emit_stream_start(yaml_emitter_t *emitter, + yaml_event_t *event); + +static int +yaml_emitter_emit_document_start(yaml_emitter_t *emitter, + yaml_event_t *event, int first); + +static int +yaml_emitter_emit_document_content(yaml_emitter_t *emitter, + yaml_event_t *event); + +static int +yaml_emitter_emit_document_end(yaml_emitter_t *emitter, + yaml_event_t *event); + +static int +yaml_emitter_emit_flow_sequence_item(yaml_emitter_t *emitter, + yaml_event_t *event, int first); + +static int +yaml_emitter_emit_flow_mapping_key(yaml_emitter_t *emitter, + yaml_event_t *event, int first); + +static int +yaml_emitter_emit_flow_mapping_value(yaml_emitter_t *emitter, + yaml_event_t *event, int simple); + +static int +yaml_emitter_emit_block_sequence_item(yaml_emitter_t *emitter, + yaml_event_t *event, int first); + +static int +yaml_emitter_emit_block_mapping_key(yaml_emitter_t *emitter, + yaml_event_t *event, int first); + +static int +yaml_emitter_emit_block_mapping_value(yaml_emitter_t *emitter, + yaml_event_t *event, int simple); + +static int +yaml_emitter_emit_node(yaml_emitter_t *emitter, yaml_event_t *event, + int root, int sequence, int mapping, int simple_key); + +static int +yaml_emitter_emit_alias(yaml_emitter_t *emitter, yaml_event_t *event); + +static int +yaml_emitter_emit_scalar(yaml_emitter_t *emitter, yaml_event_t *event); + +static int +yaml_emitter_emit_sequence_start(yaml_emitter_t *emitter, yaml_event_t *event); + +static int +yaml_emitter_emit_mapping_start(yaml_emitter_t *emitter, yaml_event_t *event); + +/* + * Checkers. + */ + +static int +yaml_emitter_check_empty_document(yaml_emitter_t *emitter); + +static int +yaml_emitter_check_empty_sequence(yaml_emitter_t *emitter); + +static int +yaml_emitter_check_empty_mapping(yaml_emitter_t *emitter); + +static int +yaml_emitter_check_simple_key(yaml_emitter_t *emitter); + +static int +yaml_emitter_select_scalar_style(yaml_emitter_t *emitter, yaml_event_t *event); + +/* + * Processors. + */ + +static int +yaml_emitter_process_anchor(yaml_emitter_t *emitter); + +static int +yaml_emitter_process_tag(yaml_emitter_t *emitter); + +static int +yaml_emitter_process_scalar(yaml_emitter_t *emitter); + +/* + * Analyzers. + */ + +static int +yaml_emitter_analyze_version_directive(yaml_emitter_t *emitter, + yaml_version_directive_t version_directive); + +static int +yaml_emitter_analyze_tag_directive(yaml_emitter_t *emitter, + yaml_tag_directive_t tag_directive); + +static int +yaml_emitter_analyze_anchor(yaml_emitter_t *emitter, + yaml_char_t *anchor, int alias); + +static int +yaml_emitter_analyze_tag(yaml_emitter_t *emitter, + yaml_char_t *tag); + +static int +yaml_emitter_analyze_scalar(yaml_emitter_t *emitter, + yaml_char_t *value, size_t length); + +static int +yaml_emitter_analyze_event(yaml_emitter_t *emitter, + yaml_event_t *event); + +/* + * Writers. + */ + +static int +yaml_emitter_write_bom(yaml_emitter_t *emitter); + +static int +yaml_emitter_write_indent(yaml_emitter_t *emitter); + +static int +yaml_emitter_write_indicator(yaml_emitter_t *emitter, + char *indicator, int need_whitespace, + int is_whitespace, int is_indention); + +static int +yaml_emitter_write_anchor(yaml_emitter_t *emitter, + yaml_char_t *value, size_t length); + +static int +yaml_emitter_write_tag_handle(yaml_emitter_t *emitter, + yaml_char_t *value, size_t length); + +static int +yaml_emitter_write_tag_content(yaml_emitter_t *emitter, + yaml_char_t *value, size_t length, int need_whitespace); + +static int +yaml_emitter_write_plain_scalar(yaml_emitter_t *emitter, + yaml_char_t *value, size_t length, int allow_breaks); + +static int +yaml_emitter_write_single_quoted_scalar(yaml_emitter_t *emitter, + yaml_char_t *value, size_t length, int allow_breaks); + +static int +yaml_emitter_write_double_quoted_scalar(yaml_emitter_t *emitter, + yaml_char_t *value, size_t length, int allow_breaks); + +static int +yaml_emitter_write_block_scalar_hints(yaml_emitter_t *emitter, + yaml_string_t string); + +static int +yaml_emitter_write_literal_scalar(yaml_emitter_t *emitter, + yaml_char_t *value, size_t length); + +static int +yaml_emitter_write_folded_scalar(yaml_emitter_t *emitter, + yaml_char_t *value, size_t length); + +/* + * Set an emitter error and return 0. + */ + +static int +yaml_emitter_set_emitter_error(yaml_emitter_t *emitter, const char *problem) +{ + emitter->error = YAML_EMITTER_ERROR; + emitter->problem = problem; + + return 0; +} + +/* + * Emit an event. + */ + +YAML_DECLARE(int) +yaml_emitter_emit(yaml_emitter_t *emitter, yaml_event_t *event) +{ + if (!ENQUEUE(emitter, emitter->events, *event)) { + yaml_event_delete(event); + return 0; + } + + while (!yaml_emitter_need_more_events(emitter)) { + if (!yaml_emitter_analyze_event(emitter, emitter->events.head)) + return 0; + if (!yaml_emitter_state_machine(emitter, emitter->events.head)) + return 0; + yaml_event_delete(&DEQUEUE(emitter, emitter->events)); + } + + return 1; +} + +/* + * Check if we need to accumulate more events before emitting. + * + * We accumulate extra + * - 1 event for DOCUMENT-START + * - 2 events for SEQUENCE-START + * - 3 events for MAPPING-START + */ + +static int +yaml_emitter_need_more_events(yaml_emitter_t *emitter) +{ + int level = 0; + int accumulate = 0; + yaml_event_t *event; + + if (QUEUE_EMPTY(emitter, emitter->events)) + return 1; + + switch (emitter->events.head->type) { + case YAML_DOCUMENT_START_EVENT: + accumulate = 1; + break; + case YAML_SEQUENCE_START_EVENT: + accumulate = 2; + break; + case YAML_MAPPING_START_EVENT: + accumulate = 3; + break; + default: + return 0; + } + + if (emitter->events.tail - emitter->events.head > accumulate) + return 0; + + for (event = emitter->events.head; event != emitter->events.tail; event ++) { + switch (event->type) { + case YAML_STREAM_START_EVENT: + case YAML_DOCUMENT_START_EVENT: + case YAML_SEQUENCE_START_EVENT: + case YAML_MAPPING_START_EVENT: + level += 1; + break; + case YAML_STREAM_END_EVENT: + case YAML_DOCUMENT_END_EVENT: + case YAML_SEQUENCE_END_EVENT: + case YAML_MAPPING_END_EVENT: + level -= 1; + break; + default: + break; + } + if (!level) + return 0; + } + + return 1; +} + +/* + * Append a directive to the directives stack. + */ + +static int +yaml_emitter_append_tag_directive(yaml_emitter_t *emitter, + yaml_tag_directive_t value, int allow_duplicates) +{ + yaml_tag_directive_t *tag_directive; + yaml_tag_directive_t copy = { NULL, NULL }; + + for (tag_directive = emitter->tag_directives.start; + tag_directive != emitter->tag_directives.top; tag_directive ++) { + if (strcmp((char *)value.handle, (char *)tag_directive->handle) == 0) { + if (allow_duplicates) + return 1; + return yaml_emitter_set_emitter_error(emitter, + "duplicate %TAG directive"); + } + } + + copy.handle = yaml_strdup(value.handle); + copy.prefix = yaml_strdup(value.prefix); + if (!copy.handle || !copy.prefix) { + emitter->error = YAML_MEMORY_ERROR; + goto error; + } + + if (!PUSH(emitter, emitter->tag_directives, copy)) + goto error; + + return 1; + +error: + yaml_free(copy.handle); + yaml_free(copy.prefix); + return 0; +} + +/* + * Increase the indentation level. + */ + +static int +yaml_emitter_increase_indent(yaml_emitter_t *emitter, + int flow, int indentless) +{ + if (!PUSH(emitter, emitter->indents, emitter->indent)) + return 0; + + if (emitter->indent < 0) { + emitter->indent = flow ? emitter->best_indent : 0; + } + else if (!indentless) { + emitter->indent += emitter->best_indent; + } + + return 1; +} + +/* + * State dispatcher. + */ + +static int +yaml_emitter_state_machine(yaml_emitter_t *emitter, yaml_event_t *event) +{ + switch (emitter->state) + { + case YAML_EMIT_STREAM_START_STATE: + return yaml_emitter_emit_stream_start(emitter, event); + + case YAML_EMIT_FIRST_DOCUMENT_START_STATE: + return yaml_emitter_emit_document_start(emitter, event, 1); + + case YAML_EMIT_DOCUMENT_START_STATE: + return yaml_emitter_emit_document_start(emitter, event, 0); + + case YAML_EMIT_DOCUMENT_CONTENT_STATE: + return yaml_emitter_emit_document_content(emitter, event); + + case YAML_EMIT_DOCUMENT_END_STATE: + return yaml_emitter_emit_document_end(emitter, event); + + case YAML_EMIT_FLOW_SEQUENCE_FIRST_ITEM_STATE: + return yaml_emitter_emit_flow_sequence_item(emitter, event, 1); + + case YAML_EMIT_FLOW_SEQUENCE_ITEM_STATE: + return yaml_emitter_emit_flow_sequence_item(emitter, event, 0); + + case YAML_EMIT_FLOW_MAPPING_FIRST_KEY_STATE: + return yaml_emitter_emit_flow_mapping_key(emitter, event, 1); + + case YAML_EMIT_FLOW_MAPPING_KEY_STATE: + return yaml_emitter_emit_flow_mapping_key(emitter, event, 0); + + case YAML_EMIT_FLOW_MAPPING_SIMPLE_VALUE_STATE: + return yaml_emitter_emit_flow_mapping_value(emitter, event, 1); + + case YAML_EMIT_FLOW_MAPPING_VALUE_STATE: + return yaml_emitter_emit_flow_mapping_value(emitter, event, 0); + + case YAML_EMIT_BLOCK_SEQUENCE_FIRST_ITEM_STATE: + return yaml_emitter_emit_block_sequence_item(emitter, event, 1); + + case YAML_EMIT_BLOCK_SEQUENCE_ITEM_STATE: + return yaml_emitter_emit_block_sequence_item(emitter, event, 0); + + case YAML_EMIT_BLOCK_MAPPING_FIRST_KEY_STATE: + return yaml_emitter_emit_block_mapping_key(emitter, event, 1); + + case YAML_EMIT_BLOCK_MAPPING_KEY_STATE: + return yaml_emitter_emit_block_mapping_key(emitter, event, 0); + + case YAML_EMIT_BLOCK_MAPPING_SIMPLE_VALUE_STATE: + return yaml_emitter_emit_block_mapping_value(emitter, event, 1); + + case YAML_EMIT_BLOCK_MAPPING_VALUE_STATE: + return yaml_emitter_emit_block_mapping_value(emitter, event, 0); + + case YAML_EMIT_END_STATE: + return yaml_emitter_set_emitter_error(emitter, + "expected nothing after STREAM-END"); + + default: + assert(1); /* Invalid state. */ + } + + return 0; +} + +/* + * Expect STREAM-START. + */ + +static int +yaml_emitter_emit_stream_start(yaml_emitter_t *emitter, + yaml_event_t *event) +{ + if (event->type == YAML_STREAM_START_EVENT) + { + if (!emitter->encoding) { + emitter->encoding = event->data.stream_start.encoding; + } + + if (!emitter->encoding) { + emitter->encoding = YAML_UTF8_ENCODING; + } + + if (emitter->best_indent < 2 || emitter->best_indent > 9) { + emitter->best_indent = 2; + } + + if (emitter->best_width >= 0 + && emitter->best_width <= emitter->best_indent*2) { + emitter->best_width = 80; + } + + if (emitter->best_width < 0) { + emitter->best_width = INT_MAX; + } + + if (!emitter->line_break) { + emitter->line_break = YAML_LN_BREAK; + } + + emitter->indent = -1; + + emitter->line = 0; + emitter->column = 0; + emitter->whitespace = 1; + emitter->indention = 1; + + if (emitter->encoding != YAML_UTF8_ENCODING) { + if (!yaml_emitter_write_bom(emitter)) + return 0; + } + + emitter->state = YAML_EMIT_FIRST_DOCUMENT_START_STATE; + + return 1; + } + + return yaml_emitter_set_emitter_error(emitter, + "expected STREAM-START"); +} + +/* + * Expect DOCUMENT-START or STREAM-END. + */ + +static int +yaml_emitter_emit_document_start(yaml_emitter_t *emitter, + yaml_event_t *event, int first) +{ + if (event->type == YAML_DOCUMENT_START_EVENT) + { + yaml_tag_directive_t default_tag_directives[] = { + {(yaml_char_t *)"!", (yaml_char_t *)"!"}, + {(yaml_char_t *)"!!", (yaml_char_t *)"tag:yaml.org,2002:"}, + {NULL, NULL} + }; + yaml_tag_directive_t *tag_directive; + int implicit; + + if (event->data.document_start.version_directive) { + if (!yaml_emitter_analyze_version_directive(emitter, + *event->data.document_start.version_directive)) + return 0; + } + + for (tag_directive = event->data.document_start.tag_directives.start; + tag_directive != event->data.document_start.tag_directives.end; + tag_directive ++) { + if (!yaml_emitter_analyze_tag_directive(emitter, *tag_directive)) + return 0; + if (!yaml_emitter_append_tag_directive(emitter, *tag_directive, 0)) + return 0; + } + + for (tag_directive = default_tag_directives; + tag_directive->handle; tag_directive ++) { + if (!yaml_emitter_append_tag_directive(emitter, *tag_directive, 1)) + return 0; + } + + implicit = event->data.document_start.implicit; + if (!first || emitter->canonical) { + implicit = 0; + } + + if ((event->data.document_start.version_directive || + (event->data.document_start.tag_directives.start + != event->data.document_start.tag_directives.end)) && + emitter->open_ended) + { + if (!yaml_emitter_write_indicator(emitter, "...", 1, 0, 0)) + return 0; + if (!yaml_emitter_write_indent(emitter)) + return 0; + } + + if (event->data.document_start.version_directive) { + implicit = 0; + if (!yaml_emitter_write_indicator(emitter, "%YAML", 1, 0, 0)) + return 0; + if (!yaml_emitter_write_indicator(emitter, "1.1", 1, 0, 0)) + return 0; + if (!yaml_emitter_write_indent(emitter)) + return 0; + } + + if (event->data.document_start.tag_directives.start + != event->data.document_start.tag_directives.end) { + implicit = 0; + for (tag_directive = event->data.document_start.tag_directives.start; + tag_directive != event->data.document_start.tag_directives.end; + tag_directive ++) { + if (!yaml_emitter_write_indicator(emitter, "%TAG", 1, 0, 0)) + return 0; + if (!yaml_emitter_write_tag_handle(emitter, tag_directive->handle, + strlen((char *)tag_directive->handle))) + return 0; + if (!yaml_emitter_write_tag_content(emitter, tag_directive->prefix, + strlen((char *)tag_directive->prefix), 1)) + return 0; + if (!yaml_emitter_write_indent(emitter)) + return 0; + } + } + + if (yaml_emitter_check_empty_document(emitter)) { + implicit = 0; + } + + if (!implicit) { + if (!yaml_emitter_write_indent(emitter)) + return 0; + if (!yaml_emitter_write_indicator(emitter, "---", 1, 0, 0)) + return 0; + if (emitter->canonical) { + if (!yaml_emitter_write_indent(emitter)) + return 0; + } + } + + emitter->state = YAML_EMIT_DOCUMENT_CONTENT_STATE; + + return 1; + } + + else if (event->type == YAML_STREAM_END_EVENT) + { + if (emitter->open_ended) + { + if (!yaml_emitter_write_indicator(emitter, "...", 1, 0, 0)) + return 0; + if (!yaml_emitter_write_indent(emitter)) + return 0; + } + + if (!yaml_emitter_flush(emitter)) + return 0; + + emitter->state = YAML_EMIT_END_STATE; + + return 1; + } + + return yaml_emitter_set_emitter_error(emitter, + "expected DOCUMENT-START or STREAM-END"); +} + +/* + * Expect the root node. + */ + +static int +yaml_emitter_emit_document_content(yaml_emitter_t *emitter, + yaml_event_t *event) +{ + if (!PUSH(emitter, emitter->states, YAML_EMIT_DOCUMENT_END_STATE)) + return 0; + + return yaml_emitter_emit_node(emitter, event, 1, 0, 0, 0); +} + +/* + * Expect DOCUMENT-END. + */ + +static int +yaml_emitter_emit_document_end(yaml_emitter_t *emitter, + yaml_event_t *event) +{ + if (event->type == YAML_DOCUMENT_END_EVENT) + { + if (!yaml_emitter_write_indent(emitter)) + return 0; + if (!event->data.document_end.implicit) { + if (!yaml_emitter_write_indicator(emitter, "...", 1, 0, 0)) + return 0; + if (!yaml_emitter_write_indent(emitter)) + return 0; + } + if (!yaml_emitter_flush(emitter)) + return 0; + + emitter->state = YAML_EMIT_DOCUMENT_START_STATE; + + while (!STACK_EMPTY(emitter, emitter->tag_directives)) { + yaml_tag_directive_t tag_directive = POP(emitter, + emitter->tag_directives); + yaml_free(tag_directive.handle); + yaml_free(tag_directive.prefix); + } + + return 1; + } + + return yaml_emitter_set_emitter_error(emitter, + "expected DOCUMENT-END"); +} + +/* + * + * Expect a flow item node. + */ + +static int +yaml_emitter_emit_flow_sequence_item(yaml_emitter_t *emitter, + yaml_event_t *event, int first) +{ + if (first) + { + if (!yaml_emitter_write_indicator(emitter, "[", 1, 1, 0)) + return 0; + if (!yaml_emitter_increase_indent(emitter, 1, 0)) + return 0; + emitter->flow_level ++; + } + + if (event->type == YAML_SEQUENCE_END_EVENT) + { + emitter->flow_level --; + emitter->indent = POP(emitter, emitter->indents); + if (emitter->canonical && !first) { + if (!yaml_emitter_write_indicator(emitter, ",", 0, 0, 0)) + return 0; + if (!yaml_emitter_write_indent(emitter)) + return 0; + } + if (!yaml_emitter_write_indicator(emitter, "]", 0, 0, 0)) + return 0; + emitter->state = POP(emitter, emitter->states); + + return 1; + } + + if (!first) { + if (!yaml_emitter_write_indicator(emitter, ",", 0, 0, 0)) + return 0; + } + + if (emitter->canonical || emitter->column > emitter->best_width) { + if (!yaml_emitter_write_indent(emitter)) + return 0; + } + if (!PUSH(emitter, emitter->states, YAML_EMIT_FLOW_SEQUENCE_ITEM_STATE)) + return 0; + + return yaml_emitter_emit_node(emitter, event, 0, 1, 0, 0); +} + +/* + * Expect a flow key node. + */ + +static int +yaml_emitter_emit_flow_mapping_key(yaml_emitter_t *emitter, + yaml_event_t *event, int first) +{ + if (first) + { + if (!yaml_emitter_write_indicator(emitter, "{", 1, 1, 0)) + return 0; + if (!yaml_emitter_increase_indent(emitter, 1, 0)) + return 0; + emitter->flow_level ++; + } + + if (event->type == YAML_MAPPING_END_EVENT) + { + emitter->flow_level --; + emitter->indent = POP(emitter, emitter->indents); + if (emitter->canonical && !first) { + if (!yaml_emitter_write_indicator(emitter, ",", 0, 0, 0)) + return 0; + if (!yaml_emitter_write_indent(emitter)) + return 0; + } + if (!yaml_emitter_write_indicator(emitter, "}", 0, 0, 0)) + return 0; + emitter->state = POP(emitter, emitter->states); + + return 1; + } + + if (!first) { + if (!yaml_emitter_write_indicator(emitter, ",", 0, 0, 0)) + return 0; + } + if (emitter->canonical || emitter->column > emitter->best_width) { + if (!yaml_emitter_write_indent(emitter)) + return 0; + } + + if (!emitter->canonical && yaml_emitter_check_simple_key(emitter)) + { + if (!PUSH(emitter, emitter->states, + YAML_EMIT_FLOW_MAPPING_SIMPLE_VALUE_STATE)) + return 0; + + return yaml_emitter_emit_node(emitter, event, 0, 0, 1, 1); + } + else + { + if (!yaml_emitter_write_indicator(emitter, "?", 1, 0, 0)) + return 0; + if (!PUSH(emitter, emitter->states, + YAML_EMIT_FLOW_MAPPING_VALUE_STATE)) + return 0; + + return yaml_emitter_emit_node(emitter, event, 0, 0, 1, 0); + } +} + +/* + * Expect a flow value node. + */ + +static int +yaml_emitter_emit_flow_mapping_value(yaml_emitter_t *emitter, + yaml_event_t *event, int simple) +{ + if (simple) { + if (!yaml_emitter_write_indicator(emitter, ":", 0, 0, 0)) + return 0; + } + else { + if (emitter->canonical || emitter->column > emitter->best_width) { + if (!yaml_emitter_write_indent(emitter)) + return 0; + } + if (!yaml_emitter_write_indicator(emitter, ":", 1, 0, 0)) + return 0; + } + if (!PUSH(emitter, emitter->states, YAML_EMIT_FLOW_MAPPING_KEY_STATE)) + return 0; + return yaml_emitter_emit_node(emitter, event, 0, 0, 1, 0); +} + +/* + * Expect a block item node. + */ + +static int +yaml_emitter_emit_block_sequence_item(yaml_emitter_t *emitter, + yaml_event_t *event, int first) +{ + if (first) + { + if (!yaml_emitter_increase_indent(emitter, 0, + (emitter->mapping_context && !emitter->indention))) + return 0; + } + + if (event->type == YAML_SEQUENCE_END_EVENT) + { + emitter->indent = POP(emitter, emitter->indents); + emitter->state = POP(emitter, emitter->states); + + return 1; + } + + if (!yaml_emitter_write_indent(emitter)) + return 0; + if (!yaml_emitter_write_indicator(emitter, "-", 1, 0, 1)) + return 0; + if (!PUSH(emitter, emitter->states, + YAML_EMIT_BLOCK_SEQUENCE_ITEM_STATE)) + return 0; + + return yaml_emitter_emit_node(emitter, event, 0, 1, 0, 0); +} + +/* + * Expect a block key node. + */ + +static int +yaml_emitter_emit_block_mapping_key(yaml_emitter_t *emitter, + yaml_event_t *event, int first) +{ + if (first) + { + if (!yaml_emitter_increase_indent(emitter, 0, 0)) + return 0; + } + + if (event->type == YAML_MAPPING_END_EVENT) + { + emitter->indent = POP(emitter, emitter->indents); + emitter->state = POP(emitter, emitter->states); + + return 1; + } + + if (!yaml_emitter_write_indent(emitter)) + return 0; + + if (yaml_emitter_check_simple_key(emitter)) + { + if (!PUSH(emitter, emitter->states, + YAML_EMIT_BLOCK_MAPPING_SIMPLE_VALUE_STATE)) + return 0; + + return yaml_emitter_emit_node(emitter, event, 0, 0, 1, 1); + } + else + { + if (!yaml_emitter_write_indicator(emitter, "?", 1, 0, 1)) + return 0; + if (!PUSH(emitter, emitter->states, + YAML_EMIT_BLOCK_MAPPING_VALUE_STATE)) + return 0; + + return yaml_emitter_emit_node(emitter, event, 0, 0, 1, 0); + } +} + +/* + * Expect a block value node. + */ + +static int +yaml_emitter_emit_block_mapping_value(yaml_emitter_t *emitter, + yaml_event_t *event, int simple) +{ + if (simple) { + if (!yaml_emitter_write_indicator(emitter, ":", 0, 0, 0)) + return 0; + } + else { + if (!yaml_emitter_write_indent(emitter)) + return 0; + if (!yaml_emitter_write_indicator(emitter, ":", 1, 0, 1)) + return 0; + } + if (!PUSH(emitter, emitter->states, + YAML_EMIT_BLOCK_MAPPING_KEY_STATE)) + return 0; + + return yaml_emitter_emit_node(emitter, event, 0, 0, 1, 0); +} + +/* + * Expect a node. + */ + +static int +yaml_emitter_emit_node(yaml_emitter_t *emitter, yaml_event_t *event, + int root, int sequence, int mapping, int simple_key) +{ + emitter->root_context = root; + emitter->sequence_context = sequence; + emitter->mapping_context = mapping; + emitter->simple_key_context = simple_key; + + switch (event->type) + { + case YAML_ALIAS_EVENT: + return yaml_emitter_emit_alias(emitter, event); + + case YAML_SCALAR_EVENT: + return yaml_emitter_emit_scalar(emitter, event); + + case YAML_SEQUENCE_START_EVENT: + return yaml_emitter_emit_sequence_start(emitter, event); + + case YAML_MAPPING_START_EVENT: + return yaml_emitter_emit_mapping_start(emitter, event); + + default: + return yaml_emitter_set_emitter_error(emitter, + "expected SCALAR, SEQUENCE-START, MAPPING-START, or ALIAS"); + } + + return 0; +} + +/* + * Expect ALIAS. + */ + +static int +yaml_emitter_emit_alias(yaml_emitter_t *emitter, yaml_event_t *event) +{ + if (!yaml_emitter_process_anchor(emitter)) + return 0; + emitter->state = POP(emitter, emitter->states); + + return 1; +} + +/* + * Expect SCALAR. + */ + +static int +yaml_emitter_emit_scalar(yaml_emitter_t *emitter, yaml_event_t *event) +{ + if (!yaml_emitter_select_scalar_style(emitter, event)) + return 0; + if (!yaml_emitter_process_anchor(emitter)) + return 0; + if (!yaml_emitter_process_tag(emitter)) + return 0; + if (!yaml_emitter_increase_indent(emitter, 1, 0)) + return 0; + if (!yaml_emitter_process_scalar(emitter)) + return 0; + emitter->indent = POP(emitter, emitter->indents); + emitter->state = POP(emitter, emitter->states); + + return 1; +} + +/* + * Expect SEQUENCE-START. + */ + +static int +yaml_emitter_emit_sequence_start(yaml_emitter_t *emitter, yaml_event_t *event) +{ + if (!yaml_emitter_process_anchor(emitter)) + return 0; + if (!yaml_emitter_process_tag(emitter)) + return 0; + + if (emitter->flow_level || emitter->canonical + || event->data.sequence_start.style == YAML_FLOW_SEQUENCE_STYLE + || yaml_emitter_check_empty_sequence(emitter)) { + emitter->state = YAML_EMIT_FLOW_SEQUENCE_FIRST_ITEM_STATE; + } + else { + emitter->state = YAML_EMIT_BLOCK_SEQUENCE_FIRST_ITEM_STATE; + } + + return 1; +} + +/* + * Expect MAPPING-START. + */ + +static int +yaml_emitter_emit_mapping_start(yaml_emitter_t *emitter, yaml_event_t *event) +{ + if (!yaml_emitter_process_anchor(emitter)) + return 0; + if (!yaml_emitter_process_tag(emitter)) + return 0; + + if (emitter->flow_level || emitter->canonical + || event->data.mapping_start.style == YAML_FLOW_MAPPING_STYLE + || yaml_emitter_check_empty_mapping(emitter)) { + emitter->state = YAML_EMIT_FLOW_MAPPING_FIRST_KEY_STATE; + } + else { + emitter->state = YAML_EMIT_BLOCK_MAPPING_FIRST_KEY_STATE; + } + + return 1; +} + +/* + * Check if the document content is an empty scalar. + */ + +static int +yaml_emitter_check_empty_document(yaml_emitter_t *emitter) +{ + return 0; +} + +/* + * Check if the next events represent an empty sequence. + */ + +static int +yaml_emitter_check_empty_sequence(yaml_emitter_t *emitter) +{ + if (emitter->events.tail - emitter->events.head < 2) + return 0; + + return (emitter->events.head[0].type == YAML_SEQUENCE_START_EVENT + && emitter->events.head[1].type == YAML_SEQUENCE_END_EVENT); +} + +/* + * Check if the next events represent an empty mapping. + */ + +static int +yaml_emitter_check_empty_mapping(yaml_emitter_t *emitter) +{ + if (emitter->events.tail - emitter->events.head < 2) + return 0; + + return (emitter->events.head[0].type == YAML_MAPPING_START_EVENT + && emitter->events.head[1].type == YAML_MAPPING_END_EVENT); +} + +/* + * Check if the next node can be expressed as a simple key. + */ + +static int +yaml_emitter_check_simple_key(yaml_emitter_t *emitter) +{ + yaml_event_t *event = emitter->events.head; + size_t length = 0; + + switch (event->type) + { + case YAML_ALIAS_EVENT: + length += emitter->anchor_data.anchor_length; + break; + + case YAML_SCALAR_EVENT: + if (emitter->scalar_data.multiline) + return 0; + length += emitter->anchor_data.anchor_length + + emitter->tag_data.handle_length + + emitter->tag_data.suffix_length + + emitter->scalar_data.length; + break; + + case YAML_SEQUENCE_START_EVENT: + if (!yaml_emitter_check_empty_sequence(emitter)) + return 0; + length += emitter->anchor_data.anchor_length + + emitter->tag_data.handle_length + + emitter->tag_data.suffix_length; + break; + + case YAML_MAPPING_START_EVENT: + if (!yaml_emitter_check_empty_mapping(emitter)) + return 0; + length += emitter->anchor_data.anchor_length + + emitter->tag_data.handle_length + + emitter->tag_data.suffix_length; + break; + + default: + return 0; + } + + if (length > 128) + return 0; + + return 1; +} + +/* + * Determine an acceptable scalar style. + */ + +static int +yaml_emitter_select_scalar_style(yaml_emitter_t *emitter, yaml_event_t *event) +{ + yaml_scalar_style_t style = event->data.scalar.style; + int no_tag = (!emitter->tag_data.handle && !emitter->tag_data.suffix); + + if (no_tag && !event->data.scalar.plain_implicit + && !event->data.scalar.quoted_implicit) { + return yaml_emitter_set_emitter_error(emitter, + "neither tag nor implicit flags are specified"); + } + + if (style == YAML_ANY_SCALAR_STYLE) + style = YAML_PLAIN_SCALAR_STYLE; + + if (emitter->canonical) + style = YAML_DOUBLE_QUOTED_SCALAR_STYLE; + + if (emitter->simple_key_context && emitter->scalar_data.multiline) + style = YAML_DOUBLE_QUOTED_SCALAR_STYLE; + + if (style == YAML_PLAIN_SCALAR_STYLE) + { + if ((emitter->flow_level && !emitter->scalar_data.flow_plain_allowed) + || (!emitter->flow_level && !emitter->scalar_data.block_plain_allowed)) + style = YAML_SINGLE_QUOTED_SCALAR_STYLE; + if (!emitter->scalar_data.length + && (emitter->flow_level || emitter->simple_key_context)) + style = YAML_SINGLE_QUOTED_SCALAR_STYLE; + if (no_tag && !event->data.scalar.plain_implicit) + style = YAML_SINGLE_QUOTED_SCALAR_STYLE; + } + + if (style == YAML_SINGLE_QUOTED_SCALAR_STYLE) + { + if (!emitter->scalar_data.single_quoted_allowed) + style = YAML_DOUBLE_QUOTED_SCALAR_STYLE; + } + + if (style == YAML_LITERAL_SCALAR_STYLE || style == YAML_FOLDED_SCALAR_STYLE) + { + if (!emitter->scalar_data.block_allowed + || emitter->flow_level || emitter->simple_key_context) + style = YAML_DOUBLE_QUOTED_SCALAR_STYLE; + } + + if (no_tag && !event->data.scalar.quoted_implicit + && style != YAML_PLAIN_SCALAR_STYLE) + { + emitter->tag_data.handle = (yaml_char_t *)"!"; + emitter->tag_data.handle_length = 1; + } + + emitter->scalar_data.style = style; + + return 1; +} + +/* + * Write an achor. + */ + +static int +yaml_emitter_process_anchor(yaml_emitter_t *emitter) +{ + if (!emitter->anchor_data.anchor) + return 1; + + if (!yaml_emitter_write_indicator(emitter, + (emitter->anchor_data.alias ? "*" : "&"), 1, 0, 0)) + return 0; + + return yaml_emitter_write_anchor(emitter, + emitter->anchor_data.anchor, emitter->anchor_data.anchor_length); +} + +/* + * Write a tag. + */ + +static int +yaml_emitter_process_tag(yaml_emitter_t *emitter) +{ + if (!emitter->tag_data.handle && !emitter->tag_data.suffix) + return 1; + + if (emitter->tag_data.handle) + { + if (!yaml_emitter_write_tag_handle(emitter, emitter->tag_data.handle, + emitter->tag_data.handle_length)) + return 0; + if (emitter->tag_data.suffix) { + if (!yaml_emitter_write_tag_content(emitter, emitter->tag_data.suffix, + emitter->tag_data.suffix_length, 0)) + return 0; + } + } + else + { + if (!yaml_emitter_write_indicator(emitter, "!<", 1, 0, 0)) + return 0; + if (!yaml_emitter_write_tag_content(emitter, emitter->tag_data.suffix, + emitter->tag_data.suffix_length, 0)) + return 0; + if (!yaml_emitter_write_indicator(emitter, ">", 0, 0, 0)) + return 0; + } + + return 1; +} + +/* + * Write a scalar. + */ + +static int +yaml_emitter_process_scalar(yaml_emitter_t *emitter) +{ + switch (emitter->scalar_data.style) + { + case YAML_PLAIN_SCALAR_STYLE: + return yaml_emitter_write_plain_scalar(emitter, + emitter->scalar_data.value, emitter->scalar_data.length, + !emitter->simple_key_context); + + case YAML_SINGLE_QUOTED_SCALAR_STYLE: + return yaml_emitter_write_single_quoted_scalar(emitter, + emitter->scalar_data.value, emitter->scalar_data.length, + !emitter->simple_key_context); + + case YAML_DOUBLE_QUOTED_SCALAR_STYLE: + return yaml_emitter_write_double_quoted_scalar(emitter, + emitter->scalar_data.value, emitter->scalar_data.length, + !emitter->simple_key_context); + + case YAML_LITERAL_SCALAR_STYLE: + return yaml_emitter_write_literal_scalar(emitter, + emitter->scalar_data.value, emitter->scalar_data.length); + + case YAML_FOLDED_SCALAR_STYLE: + return yaml_emitter_write_folded_scalar(emitter, + emitter->scalar_data.value, emitter->scalar_data.length); + + default: + assert(1); /* Impossible. */ + } + + return 0; +} + +/* + * Check if a %YAML directive is valid. + */ + +static int +yaml_emitter_analyze_version_directive(yaml_emitter_t *emitter, + yaml_version_directive_t version_directive) +{ + if (version_directive.major != 1 || version_directive.minor != 1) { + return yaml_emitter_set_emitter_error(emitter, + "incompatible %YAML directive"); + } + + return 1; +} + +/* + * Check if a %TAG directive is valid. + */ + +static int +yaml_emitter_analyze_tag_directive(yaml_emitter_t *emitter, + yaml_tag_directive_t tag_directive) +{ + yaml_string_t handle; + yaml_string_t prefix; + size_t handle_length; + size_t prefix_length; + + handle_length = strlen((char *)tag_directive.handle); + prefix_length = strlen((char *)tag_directive.prefix); + STRING_ASSIGN(handle, tag_directive.handle, handle_length); + STRING_ASSIGN(prefix, tag_directive.prefix, prefix_length); + + if (handle.start == handle.end) { + return yaml_emitter_set_emitter_error(emitter, + "tag handle must not be empty"); + } + + if (handle.start[0] != '!') { + return yaml_emitter_set_emitter_error(emitter, + "tag handle must start with '!'"); + } + + if (handle.end[-1] != '!') { + return yaml_emitter_set_emitter_error(emitter, + "tag handle must end with '!'"); + } + + handle.pointer ++; + + while (handle.pointer < handle.end-1) { + if (!IS_ALPHA(handle)) { + return yaml_emitter_set_emitter_error(emitter, + "tag handle must contain alphanumerical characters only"); + } + MOVE(handle); + } + + if (prefix.start == prefix.end) { + return yaml_emitter_set_emitter_error(emitter, + "tag prefix must not be empty"); + } + + return 1; +} + +/* + * Check if an anchor is valid. + */ + +static int +yaml_emitter_analyze_anchor(yaml_emitter_t *emitter, + yaml_char_t *anchor, int alias) +{ + size_t anchor_length; + yaml_string_t string; + + anchor_length = strlen((char *)anchor); + STRING_ASSIGN(string, anchor, anchor_length); + + if (string.start == string.end) { + return yaml_emitter_set_emitter_error(emitter, alias ? + "alias value must not be empty" : + "anchor value must not be empty"); + } + + while (string.pointer != string.end) { + if (!IS_ALPHA(string)) { + return yaml_emitter_set_emitter_error(emitter, alias ? + "alias value must contain alphanumerical characters only" : + "anchor value must contain alphanumerical characters only"); + } + MOVE(string); + } + + emitter->anchor_data.anchor = string.start; + emitter->anchor_data.anchor_length = string.end - string.start; + emitter->anchor_data.alias = alias; + + return 1; +} + +/* + * Check if a tag is valid. + */ + +static int +yaml_emitter_analyze_tag(yaml_emitter_t *emitter, + yaml_char_t *tag) +{ + size_t tag_length; + yaml_string_t string; + yaml_tag_directive_t *tag_directive; + + tag_length = strlen((char *)tag); + STRING_ASSIGN(string, tag, tag_length); + + if (string.start == string.end) { + return yaml_emitter_set_emitter_error(emitter, + "tag value must not be empty"); + } + + for (tag_directive = emitter->tag_directives.start; + tag_directive != emitter->tag_directives.top; tag_directive ++) { + size_t prefix_length = strlen((char *)tag_directive->prefix); + if (prefix_length < (size_t)(string.end - string.start) + && strncmp((char *)tag_directive->prefix, (char *)string.start, + prefix_length) == 0) + { + emitter->tag_data.handle = tag_directive->handle; + emitter->tag_data.handle_length = + strlen((char *)tag_directive->handle); + emitter->tag_data.suffix = string.start + prefix_length; + emitter->tag_data.suffix_length = + (string.end - string.start) - prefix_length; + return 1; + } + } + + emitter->tag_data.suffix = string.start; + emitter->tag_data.suffix_length = string.end - string.start; + + return 1; +} + +/* + * Check if a scalar is valid. + */ + +static int +yaml_emitter_analyze_scalar(yaml_emitter_t *emitter, + yaml_char_t *value, size_t length) +{ + yaml_string_t string; + + int block_indicators = 0; + int flow_indicators = 0; + int line_breaks = 0; + int special_characters = 0; + + int leading_space = 0; + int leading_break = 0; + int trailing_space = 0; + int trailing_break = 0; + int break_space = 0; + int space_break = 0; + + int preceeded_by_whitespace = 0; + int followed_by_whitespace = 0; + int previous_space = 0; + int previous_break = 0; + + STRING_ASSIGN(string, value, length); + + emitter->scalar_data.value = value; + emitter->scalar_data.length = length; + + if (string.start == string.end) + { + emitter->scalar_data.multiline = 0; + emitter->scalar_data.flow_plain_allowed = 0; + emitter->scalar_data.block_plain_allowed = 1; + emitter->scalar_data.single_quoted_allowed = 1; + emitter->scalar_data.block_allowed = 0; + + return 1; + } + + if ((CHECK_AT(string, '-', 0) + && CHECK_AT(string, '-', 1) + && CHECK_AT(string, '-', 2)) + || (CHECK_AT(string, '.', 0) + && CHECK_AT(string, '.', 1) + && CHECK_AT(string, '.', 2))) { + block_indicators = 1; + flow_indicators = 1; + } + + preceeded_by_whitespace = 1; + followed_by_whitespace = IS_BLANKZ_AT(string, WIDTH(string)); + + while (string.pointer != string.end) + { + if (string.start == string.pointer) + { + if (CHECK(string, '#') || CHECK(string, ',') + || CHECK(string, '[') || CHECK(string, ']') + || CHECK(string, '{') || CHECK(string, '}') + || CHECK(string, '&') || CHECK(string, '*') + || CHECK(string, '!') || CHECK(string, '|') + || CHECK(string, '>') || CHECK(string, '\'') + || CHECK(string, '"') || CHECK(string, '%') + || CHECK(string, '@') || CHECK(string, '`')) { + flow_indicators = 1; + block_indicators = 1; + } + + if (CHECK(string, '?') || CHECK(string, ':')) { + flow_indicators = 1; + if (followed_by_whitespace) { + block_indicators = 1; + } + } + + if (CHECK(string, '-') && followed_by_whitespace) { + flow_indicators = 1; + block_indicators = 1; + } + } + else + { + if (CHECK(string, ',') || CHECK(string, '?') + || CHECK(string, '[') || CHECK(string, ']') + || CHECK(string, '{') || CHECK(string, '}')) { + flow_indicators = 1; + } + + if (CHECK(string, ':')) { + flow_indicators = 1; + if (followed_by_whitespace) { + block_indicators = 1; + } + } + + if (CHECK(string, '#') && preceeded_by_whitespace) { + flow_indicators = 1; + block_indicators = 1; + } + } + + if (!IS_PRINTABLE(string) + || (!IS_ASCII(string) && !emitter->unicode)) { + special_characters = 1; + } + + if (IS_BREAK(string)) { + line_breaks = 1; + } + + if (IS_SPACE(string)) + { + if (string.start == string.pointer) { + leading_space = 1; + } + if (string.pointer+WIDTH(string) == string.end) { + trailing_space = 1; + } + if (previous_break) { + break_space = 1; + } + previous_space = 1; + previous_break = 0; + } + else if (IS_BREAK(string)) + { + if (string.start == string.pointer) { + leading_break = 1; + } + if (string.pointer+WIDTH(string) == string.end) { + trailing_break = 1; + } + if (previous_space) { + space_break = 1; + } + previous_space = 0; + previous_break = 1; + } + else + { + previous_space = 0; + previous_break = 0; + } + + preceeded_by_whitespace = IS_BLANKZ(string); + MOVE(string); + if (string.pointer != string.end) { + followed_by_whitespace = IS_BLANKZ_AT(string, WIDTH(string)); + } + } + + emitter->scalar_data.multiline = line_breaks; + + emitter->scalar_data.flow_plain_allowed = 1; + emitter->scalar_data.block_plain_allowed = 1; + emitter->scalar_data.single_quoted_allowed = 1; + emitter->scalar_data.block_allowed = 1; + + if (leading_space || leading_break || trailing_space || trailing_break) { + emitter->scalar_data.flow_plain_allowed = 0; + emitter->scalar_data.block_plain_allowed = 0; + } + + if (trailing_space) { + emitter->scalar_data.block_allowed = 0; + } + + if (break_space) { + emitter->scalar_data.flow_plain_allowed = 0; + emitter->scalar_data.block_plain_allowed = 0; + emitter->scalar_data.single_quoted_allowed = 0; + } + + if (space_break || special_characters) { + emitter->scalar_data.flow_plain_allowed = 0; + emitter->scalar_data.block_plain_allowed = 0; + emitter->scalar_data.single_quoted_allowed = 0; + emitter->scalar_data.block_allowed = 0; + } + + if (line_breaks) { + emitter->scalar_data.flow_plain_allowed = 0; + emitter->scalar_data.block_plain_allowed = 0; + } + + if (flow_indicators) { + emitter->scalar_data.flow_plain_allowed = 0; + } + + if (block_indicators) { + emitter->scalar_data.block_plain_allowed = 0; + } + + return 1; +} + +/* + * Check if the event data is valid. + */ + +static int +yaml_emitter_analyze_event(yaml_emitter_t *emitter, + yaml_event_t *event) +{ + emitter->anchor_data.anchor = NULL; + emitter->anchor_data.anchor_length = 0; + emitter->tag_data.handle = NULL; + emitter->tag_data.handle_length = 0; + emitter->tag_data.suffix = NULL; + emitter->tag_data.suffix_length = 0; + emitter->scalar_data.value = NULL; + emitter->scalar_data.length = 0; + + switch (event->type) + { + case YAML_ALIAS_EVENT: + if (!yaml_emitter_analyze_anchor(emitter, + event->data.alias.anchor, 1)) + return 0; + return 1; + + case YAML_SCALAR_EVENT: + if (event->data.scalar.anchor) { + if (!yaml_emitter_analyze_anchor(emitter, + event->data.scalar.anchor, 0)) + return 0; + } + if (event->data.scalar.tag && (emitter->canonical || + (!event->data.scalar.plain_implicit + && !event->data.scalar.quoted_implicit))) { + if (!yaml_emitter_analyze_tag(emitter, event->data.scalar.tag)) + return 0; + } + if (!yaml_emitter_analyze_scalar(emitter, + event->data.scalar.value, event->data.scalar.length)) + return 0; + return 1; + + case YAML_SEQUENCE_START_EVENT: + if (event->data.sequence_start.anchor) { + if (!yaml_emitter_analyze_anchor(emitter, + event->data.sequence_start.anchor, 0)) + return 0; + } + if (event->data.sequence_start.tag && (emitter->canonical || + !event->data.sequence_start.implicit)) { + if (!yaml_emitter_analyze_tag(emitter, + event->data.sequence_start.tag)) + return 0; + } + return 1; + + case YAML_MAPPING_START_EVENT: + if (event->data.mapping_start.anchor) { + if (!yaml_emitter_analyze_anchor(emitter, + event->data.mapping_start.anchor, 0)) + return 0; + } + if (event->data.mapping_start.tag && (emitter->canonical || + !event->data.mapping_start.implicit)) { + if (!yaml_emitter_analyze_tag(emitter, + event->data.mapping_start.tag)) + return 0; + } + return 1; + + default: + return 1; + } +} + +/* + * Write the BOM character. + */ + +static int +yaml_emitter_write_bom(yaml_emitter_t *emitter) +{ + if (!FLUSH(emitter)) return 0; + + *(emitter->buffer.pointer++) = (yaml_char_t) '\xEF'; + *(emitter->buffer.pointer++) = (yaml_char_t) '\xBB'; + *(emitter->buffer.pointer++) = (yaml_char_t) '\xBF'; + + return 1; +} + +static int +yaml_emitter_write_indent(yaml_emitter_t *emitter) +{ + int indent = (emitter->indent >= 0) ? emitter->indent : 0; + + if (!emitter->indention || emitter->column > indent + || (emitter->column == indent && !emitter->whitespace)) { + if (!PUT_BREAK(emitter)) return 0; + } + + while (emitter->column < indent) { + if (!PUT(emitter, ' ')) return 0; + } + + emitter->whitespace = 1; + emitter->indention = 1; + + return 1; +} + +static int +yaml_emitter_write_indicator(yaml_emitter_t *emitter, + char *indicator, int need_whitespace, + int is_whitespace, int is_indention) +{ + size_t indicator_length; + yaml_string_t string; + + indicator_length = strlen(indicator); + STRING_ASSIGN(string, (yaml_char_t *)indicator, indicator_length); + + if (need_whitespace && !emitter->whitespace) { + if (!PUT(emitter, ' ')) return 0; + } + + while (string.pointer != string.end) { + if (!WRITE(emitter, string)) return 0; + } + + emitter->whitespace = is_whitespace; + emitter->indention = (emitter->indention && is_indention); + emitter->open_ended = 0; + + return 1; +} + +static int +yaml_emitter_write_anchor(yaml_emitter_t *emitter, + yaml_char_t *value, size_t length) +{ + yaml_string_t string; + STRING_ASSIGN(string, value, length); + + while (string.pointer != string.end) { + if (!WRITE(emitter, string)) return 0; + } + + emitter->whitespace = 0; + emitter->indention = 0; + + return 1; +} + +static int +yaml_emitter_write_tag_handle(yaml_emitter_t *emitter, + yaml_char_t *value, size_t length) +{ + yaml_string_t string; + STRING_ASSIGN(string, value, length); + + if (!emitter->whitespace) { + if (!PUT(emitter, ' ')) return 0; + } + + while (string.pointer != string.end) { + if (!WRITE(emitter, string)) return 0; + } + + emitter->whitespace = 0; + emitter->indention = 0; + + return 1; +} + +static int +yaml_emitter_write_tag_content(yaml_emitter_t *emitter, + yaml_char_t *value, size_t length, + int need_whitespace) +{ + yaml_string_t string; + STRING_ASSIGN(string, value, length); + + if (need_whitespace && !emitter->whitespace) { + if (!PUT(emitter, ' ')) return 0; + } + + while (string.pointer != string.end) { + if (IS_ALPHA(string) + || CHECK(string, ';') || CHECK(string, '/') + || CHECK(string, '?') || CHECK(string, ':') + || CHECK(string, '@') || CHECK(string, '&') + || CHECK(string, '=') || CHECK(string, '+') + || CHECK(string, '$') || CHECK(string, ',') + || CHECK(string, '_') || CHECK(string, '.') + || CHECK(string, '~') || CHECK(string, '*') + || CHECK(string, '\'') || CHECK(string, '(') + || CHECK(string, ')') || CHECK(string, '[') + || CHECK(string, ']')) { + if (!WRITE(emitter, string)) return 0; + } + else { + int width = WIDTH(string); + unsigned int value; + while (width --) { + value = *(string.pointer++); + if (!PUT(emitter, '%')) return 0; + if (!PUT(emitter, (value >> 4) + + ((value >> 4) < 10 ? '0' : 'A' - 10))) + return 0; + if (!PUT(emitter, (value & 0x0F) + + ((value & 0x0F) < 10 ? '0' : 'A' - 10))) + return 0; + } + } + } + + emitter->whitespace = 0; + emitter->indention = 0; + + return 1; +} + +static int +yaml_emitter_write_plain_scalar(yaml_emitter_t *emitter, + yaml_char_t *value, size_t length, int allow_breaks) +{ + yaml_string_t string; + int spaces = 0; + int breaks = 0; + + STRING_ASSIGN(string, value, length); + + if (!emitter->whitespace) { + if (!PUT(emitter, ' ')) return 0; + } + + while (string.pointer != string.end) + { + if (IS_SPACE(string)) + { + if (allow_breaks && !spaces + && emitter->column > emitter->best_width + && !IS_SPACE_AT(string, 1)) { + if (!yaml_emitter_write_indent(emitter)) return 0; + MOVE(string); + } + else { + if (!WRITE(emitter, string)) return 0; + } + spaces = 1; + } + else if (IS_BREAK(string)) + { + if (!breaks && CHECK(string, '\n')) { + if (!PUT_BREAK(emitter)) return 0; + } + if (!WRITE_BREAK(emitter, string)) return 0; + emitter->indention = 1; + breaks = 1; + } + else + { + if (breaks) { + if (!yaml_emitter_write_indent(emitter)) return 0; + } + if (!WRITE(emitter, string)) return 0; + emitter->indention = 0; + spaces = 0; + breaks = 0; + } + } + + emitter->whitespace = 0; + emitter->indention = 0; + if (emitter->root_context) + { + emitter->open_ended = 1; + } + + return 1; +} + +static int +yaml_emitter_write_single_quoted_scalar(yaml_emitter_t *emitter, + yaml_char_t *value, size_t length, int allow_breaks) +{ + yaml_string_t string; + int spaces = 0; + int breaks = 0; + + STRING_ASSIGN(string, value, length); + + if (!yaml_emitter_write_indicator(emitter, "'", 1, 0, 0)) + return 0; + + while (string.pointer != string.end) + { + if (IS_SPACE(string)) + { + if (allow_breaks && !spaces + && emitter->column > emitter->best_width + && string.pointer != string.start + && string.pointer != string.end - 1 + && !IS_SPACE_AT(string, 1)) { + if (!yaml_emitter_write_indent(emitter)) return 0; + MOVE(string); + } + else { + if (!WRITE(emitter, string)) return 0; + } + spaces = 1; + } + else if (IS_BREAK(string)) + { + if (!breaks && CHECK(string, '\n')) { + if (!PUT_BREAK(emitter)) return 0; + } + if (!WRITE_BREAK(emitter, string)) return 0; + emitter->indention = 1; + breaks = 1; + } + else + { + if (breaks) { + if (!yaml_emitter_write_indent(emitter)) return 0; + } + if (CHECK(string, '\'')) { + if (!PUT(emitter, '\'')) return 0; + } + if (!WRITE(emitter, string)) return 0; + emitter->indention = 0; + spaces = 0; + breaks = 0; + } + } + + if (!yaml_emitter_write_indicator(emitter, "'", 0, 0, 0)) + return 0; + + emitter->whitespace = 0; + emitter->indention = 0; + + return 1; +} + +static int +yaml_emitter_write_double_quoted_scalar(yaml_emitter_t *emitter, + yaml_char_t *value, size_t length, int allow_breaks) +{ + yaml_string_t string; + int spaces = 0; + + STRING_ASSIGN(string, value, length); + + if (!yaml_emitter_write_indicator(emitter, "\"", 1, 0, 0)) + return 0; + + while (string.pointer != string.end) + { + if (!IS_PRINTABLE(string) || (!emitter->unicode && !IS_ASCII(string)) + || IS_BOM(string) || IS_BREAK(string) + || CHECK(string, '"') || CHECK(string, '\\')) + { + unsigned char octet; + unsigned int width; + unsigned int value; + int k; + + octet = string.pointer[0]; + width = (octet & 0x80) == 0x00 ? 1 : + (octet & 0xE0) == 0xC0 ? 2 : + (octet & 0xF0) == 0xE0 ? 3 : + (octet & 0xF8) == 0xF0 ? 4 : 0; + value = (octet & 0x80) == 0x00 ? octet & 0x7F : + (octet & 0xE0) == 0xC0 ? octet & 0x1F : + (octet & 0xF0) == 0xE0 ? octet & 0x0F : + (octet & 0xF8) == 0xF0 ? octet & 0x07 : 0; + for (k = 1; k < (int)width; k ++) { + octet = string.pointer[k]; + value = (value << 6) + (octet & 0x3F); + } + string.pointer += width; + + if (!PUT(emitter, '\\')) return 0; + + switch (value) + { + case 0x00: + if (!PUT(emitter, '0')) return 0; + break; + + case 0x07: + if (!PUT(emitter, 'a')) return 0; + break; + + case 0x08: + if (!PUT(emitter, 'b')) return 0; + break; + + case 0x09: + if (!PUT(emitter, 't')) return 0; + break; + + case 0x0A: + if (!PUT(emitter, 'n')) return 0; + break; + + case 0x0B: + if (!PUT(emitter, 'v')) return 0; + break; + + case 0x0C: + if (!PUT(emitter, 'f')) return 0; + break; + + case 0x0D: + if (!PUT(emitter, 'r')) return 0; + break; + + case 0x1B: + if (!PUT(emitter, 'e')) return 0; + break; + + case 0x22: + if (!PUT(emitter, '\"')) return 0; + break; + + case 0x5C: + if (!PUT(emitter, '\\')) return 0; + break; + + case 0x85: + if (!PUT(emitter, 'N')) return 0; + break; + + case 0xA0: + if (!PUT(emitter, '_')) return 0; + break; + + case 0x2028: + if (!PUT(emitter, 'L')) return 0; + break; + + case 0x2029: + if (!PUT(emitter, 'P')) return 0; + break; + + default: + if (value <= 0xFF) { + if (!PUT(emitter, 'x')) return 0; + width = 2; + } + else if (value <= 0xFFFF) { + if (!PUT(emitter, 'u')) return 0; + width = 4; + } + else { + if (!PUT(emitter, 'U')) return 0; + width = 8; + } + for (k = (width-1)*4; k >= 0; k -= 4) { + int digit = (value >> k) & 0x0F; + if (!PUT(emitter, digit + (digit < 10 ? '0' : 'A'-10))) + return 0; + } + } + spaces = 0; + } + else if (IS_SPACE(string)) + { + if (allow_breaks && !spaces + && emitter->column > emitter->best_width + && string.pointer != string.start + && string.pointer != string.end - 1) { + if (!yaml_emitter_write_indent(emitter)) return 0; + if (IS_SPACE_AT(string, 1)) { + if (!PUT(emitter, '\\')) return 0; + } + MOVE(string); + } + else { + if (!WRITE(emitter, string)) return 0; + } + spaces = 1; + } + else + { + if (!WRITE(emitter, string)) return 0; + spaces = 0; + } + } + + if (!yaml_emitter_write_indicator(emitter, "\"", 0, 0, 0)) + return 0; + + emitter->whitespace = 0; + emitter->indention = 0; + + return 1; +} + +static int +yaml_emitter_write_block_scalar_hints(yaml_emitter_t *emitter, + yaml_string_t string) +{ + char indent_hint[2]; + char *chomp_hint = NULL; + + if (IS_SPACE(string) || IS_BREAK(string)) + { + indent_hint[0] = '0' + (char)emitter->best_indent; + indent_hint[1] = '\0'; + if (!yaml_emitter_write_indicator(emitter, indent_hint, 0, 0, 0)) + return 0; + } + + emitter->open_ended = 0; + + string.pointer = string.end; + if (string.start == string.pointer) + { + chomp_hint = "-"; + } + else + { + do { + string.pointer --; + } while ((*string.pointer & 0xC0) == 0x80); + if (!IS_BREAK(string)) + { + chomp_hint = "-"; + } + else if (string.start == string.pointer) + { + chomp_hint = "+"; + emitter->open_ended = 1; + } + else + { + do { + string.pointer --; + } while ((*string.pointer & 0xC0) == 0x80); + if (IS_BREAK(string)) + { + chomp_hint = "+"; + emitter->open_ended = 1; + } + } + } + + if (chomp_hint) + { + if (!yaml_emitter_write_indicator(emitter, chomp_hint, 0, 0, 0)) + return 0; + } + + return 1; +} + +static int +yaml_emitter_write_literal_scalar(yaml_emitter_t *emitter, + yaml_char_t *value, size_t length) +{ + yaml_string_t string; + int breaks = 1; + + STRING_ASSIGN(string, value, length); + + if (!yaml_emitter_write_indicator(emitter, "|", 1, 0, 0)) + return 0; + if (!yaml_emitter_write_block_scalar_hints(emitter, string)) + return 0; + if (!PUT_BREAK(emitter)) return 0; + emitter->indention = 1; + emitter->whitespace = 1; + + while (string.pointer != string.end) + { + if (IS_BREAK(string)) + { + if (!WRITE_BREAK(emitter, string)) return 0; + emitter->indention = 1; + breaks = 1; + } + else + { + if (breaks) { + if (!yaml_emitter_write_indent(emitter)) return 0; + } + if (!WRITE(emitter, string)) return 0; + emitter->indention = 0; + breaks = 0; + } + } + + return 1; +} + +static int +yaml_emitter_write_folded_scalar(yaml_emitter_t *emitter, + yaml_char_t *value, size_t length) +{ + yaml_string_t string; + int breaks = 1; + int leading_spaces = 1; + + STRING_ASSIGN(string, value, length); + + if (!yaml_emitter_write_indicator(emitter, ">", 1, 0, 0)) + return 0; + if (!yaml_emitter_write_block_scalar_hints(emitter, string)) + return 0; + if (!PUT_BREAK(emitter)) return 0; + emitter->indention = 1; + emitter->whitespace = 1; + + while (string.pointer != string.end) + { + if (IS_BREAK(string)) + { + if (!breaks && !leading_spaces && CHECK(string, '\n')) { + int k = 0; + while (IS_BREAK_AT(string, k)) { + k += WIDTH_AT(string, k); + } + if (!IS_BLANKZ_AT(string, k)) { + if (!PUT_BREAK(emitter)) return 0; + } + } + if (!WRITE_BREAK(emitter, string)) return 0; + emitter->indention = 1; + breaks = 1; + } + else + { + if (breaks) { + if (!yaml_emitter_write_indent(emitter)) return 0; + leading_spaces = IS_BLANK(string); + } + if (!breaks && IS_SPACE(string) && !IS_SPACE_AT(string, 1) + && emitter->column > emitter->best_width) { + if (!yaml_emitter_write_indent(emitter)) return 0; + MOVE(string); + } + else { + if (!WRITE(emitter, string)) return 0; + } + emitter->indention = 0; + breaks = 0; + } + } + + return 1; +} + diff --git a/web/server/h2o/libh2o/deps/yaml/src/loader.c b/web/server/h2o/libh2o/deps/yaml/src/loader.c new file mode 100644 index 00000000..871149ab --- /dev/null +++ b/web/server/h2o/libh2o/deps/yaml/src/loader.c @@ -0,0 +1,444 @@ + +#include "yaml_private.h" + +/* + * API functions. + */ + +YAML_DECLARE(int) +yaml_parser_load(yaml_parser_t *parser, yaml_document_t *document); + +/* + * Error handling. + */ + +static int +yaml_parser_set_composer_error(yaml_parser_t *parser, + const char *problem, yaml_mark_t problem_mark); + +static int +yaml_parser_set_composer_error_context(yaml_parser_t *parser, + const char *context, yaml_mark_t context_mark, + const char *problem, yaml_mark_t problem_mark); + + +/* + * Alias handling. + */ + +static int +yaml_parser_register_anchor(yaml_parser_t *parser, + int index, yaml_char_t *anchor); + +/* + * Clean up functions. + */ + +static void +yaml_parser_delete_aliases(yaml_parser_t *parser); + +/* + * Composer functions. + */ + +static int +yaml_parser_load_document(yaml_parser_t *parser, yaml_event_t *first_event); + +static int +yaml_parser_load_node(yaml_parser_t *parser, yaml_event_t *first_event); + +static int +yaml_parser_load_alias(yaml_parser_t *parser, yaml_event_t *first_event); + +static int +yaml_parser_load_scalar(yaml_parser_t *parser, yaml_event_t *first_event); + +static int +yaml_parser_load_sequence(yaml_parser_t *parser, yaml_event_t *first_event); + +static int +yaml_parser_load_mapping(yaml_parser_t *parser, yaml_event_t *first_event); + +/* + * Load the next document of the stream. + */ + +YAML_DECLARE(int) +yaml_parser_load(yaml_parser_t *parser, yaml_document_t *document) +{ + yaml_event_t event; + + assert(parser); /* Non-NULL parser object is expected. */ + assert(document); /* Non-NULL document object is expected. */ + + memset(document, 0, sizeof(yaml_document_t)); + if (!STACK_INIT(parser, document->nodes, INITIAL_STACK_SIZE)) + goto error; + + if (!parser->stream_start_produced) { + if (!yaml_parser_parse(parser, &event)) goto error; + assert(event.type == YAML_STREAM_START_EVENT); + /* STREAM-START is expected. */ + } + + if (parser->stream_end_produced) { + return 1; + } + + if (!yaml_parser_parse(parser, &event)) goto error; + if (event.type == YAML_STREAM_END_EVENT) { + return 1; + } + + if (!STACK_INIT(parser, parser->aliases, INITIAL_STACK_SIZE)) + goto error; + + parser->document = document; + + if (!yaml_parser_load_document(parser, &event)) goto error; + + yaml_parser_delete_aliases(parser); + parser->document = NULL; + + return 1; + +error: + + yaml_parser_delete_aliases(parser); + yaml_document_delete(document); + parser->document = NULL; + + return 0; +} + +/* + * Set composer error. + */ + +static int +yaml_parser_set_composer_error(yaml_parser_t *parser, + const char *problem, yaml_mark_t problem_mark) +{ + parser->error = YAML_COMPOSER_ERROR; + parser->problem = problem; + parser->problem_mark = problem_mark; + + return 0; +} + +/* + * Set composer error with context. + */ + +static int +yaml_parser_set_composer_error_context(yaml_parser_t *parser, + const char *context, yaml_mark_t context_mark, + const char *problem, yaml_mark_t problem_mark) +{ + parser->error = YAML_COMPOSER_ERROR; + parser->context = context; + parser->context_mark = context_mark; + parser->problem = problem; + parser->problem_mark = problem_mark; + + return 0; +} + +/* + * Delete the stack of aliases. + */ + +static void +yaml_parser_delete_aliases(yaml_parser_t *parser) +{ + while (!STACK_EMPTY(parser, parser->aliases)) { + yaml_free(POP(parser, parser->aliases).anchor); + } + STACK_DEL(parser, parser->aliases); +} + +/* + * Compose a document object. + */ + +static int +yaml_parser_load_document(yaml_parser_t *parser, yaml_event_t *first_event) +{ + yaml_event_t event; + + assert(first_event->type == YAML_DOCUMENT_START_EVENT); + /* DOCUMENT-START is expected. */ + + parser->document->version_directive + = first_event->data.document_start.version_directive; + parser->document->tag_directives.start + = first_event->data.document_start.tag_directives.start; + parser->document->tag_directives.end + = first_event->data.document_start.tag_directives.end; + parser->document->start_implicit + = first_event->data.document_start.implicit; + parser->document->start_mark = first_event->start_mark; + + if (!yaml_parser_parse(parser, &event)) return 0; + + if (!yaml_parser_load_node(parser, &event)) return 0; + + if (!yaml_parser_parse(parser, &event)) return 0; + assert(event.type == YAML_DOCUMENT_END_EVENT); + /* DOCUMENT-END is expected. */ + + parser->document->end_implicit = event.data.document_end.implicit; + parser->document->end_mark = event.end_mark; + + return 1; +} + +/* + * Compose a node. + */ + +static int +yaml_parser_load_node(yaml_parser_t *parser, yaml_event_t *first_event) +{ + switch (first_event->type) { + case YAML_ALIAS_EVENT: + return yaml_parser_load_alias(parser, first_event); + case YAML_SCALAR_EVENT: + return yaml_parser_load_scalar(parser, first_event); + case YAML_SEQUENCE_START_EVENT: + return yaml_parser_load_sequence(parser, first_event); + case YAML_MAPPING_START_EVENT: + return yaml_parser_load_mapping(parser, first_event); + default: + assert(0); /* Could not happen. */ + return 0; + } + + return 0; +} + +/* + * Add an anchor. + */ + +static int +yaml_parser_register_anchor(yaml_parser_t *parser, + int index, yaml_char_t *anchor) +{ + yaml_alias_data_t data; + yaml_alias_data_t *alias_data; + + if (!anchor) return 1; + + data.anchor = anchor; + data.index = index; + data.mark = parser->document->nodes.start[index-1].start_mark; + + for (alias_data = parser->aliases.start; + alias_data != parser->aliases.top; alias_data ++) { + if (strcmp((char *)alias_data->anchor, (char *)anchor) == 0) { + yaml_free(anchor); + return yaml_parser_set_composer_error_context(parser, + "found duplicate anchor; first occurence", + alias_data->mark, "second occurence", data.mark); + } + } + + if (!PUSH(parser, parser->aliases, data)) { + yaml_free(anchor); + return 0; + } + + return 1; +} + +/* + * Compose a node corresponding to an alias. + */ + +static int +yaml_parser_load_alias(yaml_parser_t *parser, yaml_event_t *first_event) +{ + yaml_char_t *anchor = first_event->data.alias.anchor; + yaml_alias_data_t *alias_data; + + for (alias_data = parser->aliases.start; + alias_data != parser->aliases.top; alias_data ++) { + if (strcmp((char *)alias_data->anchor, (char *)anchor) == 0) { + yaml_free(anchor); + return alias_data->index; + } + } + + yaml_free(anchor); + return yaml_parser_set_composer_error(parser, "found undefined alias", + first_event->start_mark); +} + +/* + * Compose a scalar node. + */ + +static int +yaml_parser_load_scalar(yaml_parser_t *parser, yaml_event_t *first_event) +{ + yaml_node_t node; + int index; + yaml_char_t *tag = first_event->data.scalar.tag; + + if (!STACK_LIMIT(parser, parser->document->nodes, INT_MAX-1)) goto error; + + if (!tag || strcmp((char *)tag, "!") == 0) { + yaml_free(tag); + tag = yaml_strdup((yaml_char_t *)YAML_DEFAULT_SCALAR_TAG); + if (!tag) goto error; + } + + SCALAR_NODE_INIT(node, tag, first_event->data.scalar.value, + first_event->data.scalar.length, first_event->data.scalar.style, + first_event->start_mark, first_event->end_mark); + + if (!PUSH(parser, parser->document->nodes, node)) goto error; + + index = parser->document->nodes.top - parser->document->nodes.start; + + if (!yaml_parser_register_anchor(parser, index, + first_event->data.scalar.anchor)) return 0; + + return index; + +error: + yaml_free(tag); + yaml_free(first_event->data.scalar.anchor); + yaml_free(first_event->data.scalar.value); + return 0; +} + +/* + * Compose a sequence node. + */ + +static int +yaml_parser_load_sequence(yaml_parser_t *parser, yaml_event_t *first_event) +{ + yaml_event_t event; + yaml_node_t node; + struct { + yaml_node_item_t *start; + yaml_node_item_t *end; + yaml_node_item_t *top; + } items = { NULL, NULL, NULL }; + int index, item_index; + yaml_char_t *tag = first_event->data.sequence_start.tag; + + if (!STACK_LIMIT(parser, parser->document->nodes, INT_MAX-1)) goto error; + + if (!tag || strcmp((char *)tag, "!") == 0) { + yaml_free(tag); + tag = yaml_strdup((yaml_char_t *)YAML_DEFAULT_SEQUENCE_TAG); + if (!tag) goto error; + } + + if (!STACK_INIT(parser, items, INITIAL_STACK_SIZE)) goto error; + + SEQUENCE_NODE_INIT(node, tag, items.start, items.end, + first_event->data.sequence_start.style, + first_event->start_mark, first_event->end_mark); + + if (!PUSH(parser, parser->document->nodes, node)) goto error; + + index = parser->document->nodes.top - parser->document->nodes.start; + + if (!yaml_parser_register_anchor(parser, index, + first_event->data.sequence_start.anchor)) return 0; + + if (!yaml_parser_parse(parser, &event)) return 0; + + while (event.type != YAML_SEQUENCE_END_EVENT) { + if (!STACK_LIMIT(parser, + parser->document->nodes.start[index-1].data.sequence.items, + INT_MAX-1)) return 0; + item_index = yaml_parser_load_node(parser, &event); + if (!item_index) return 0; + if (!PUSH(parser, + parser->document->nodes.start[index-1].data.sequence.items, + item_index)) return 0; + if (!yaml_parser_parse(parser, &event)) return 0; + } + + parser->document->nodes.start[index-1].end_mark = event.end_mark; + + return index; + +error: + yaml_free(tag); + yaml_free(first_event->data.sequence_start.anchor); + return 0; +} + +/* + * Compose a mapping node. + */ + +static int +yaml_parser_load_mapping(yaml_parser_t *parser, yaml_event_t *first_event) +{ + yaml_event_t event; + yaml_node_t node; + struct { + yaml_node_pair_t *start; + yaml_node_pair_t *end; + yaml_node_pair_t *top; + } pairs = { NULL, NULL, NULL }; + int index; + yaml_node_pair_t pair; + yaml_char_t *tag = first_event->data.mapping_start.tag; + + if (!STACK_LIMIT(parser, parser->document->nodes, INT_MAX-1)) goto error; + + if (!tag || strcmp((char *)tag, "!") == 0) { + yaml_free(tag); + tag = yaml_strdup((yaml_char_t *)YAML_DEFAULT_MAPPING_TAG); + if (!tag) goto error; + } + + if (!STACK_INIT(parser, pairs, INITIAL_STACK_SIZE)) goto error; + + MAPPING_NODE_INIT(node, tag, pairs.start, pairs.end, + first_event->data.mapping_start.style, + first_event->start_mark, first_event->end_mark); + + if (!PUSH(parser, parser->document->nodes, node)) goto error; + + index = parser->document->nodes.top - parser->document->nodes.start; + + if (!yaml_parser_register_anchor(parser, index, + first_event->data.mapping_start.anchor)) return 0; + + if (!yaml_parser_parse(parser, &event)) return 0; + + while (event.type != YAML_MAPPING_END_EVENT) { + if (!STACK_LIMIT(parser, + parser->document->nodes.start[index-1].data.mapping.pairs, + INT_MAX-1)) return 0; + pair.key = yaml_parser_load_node(parser, &event); + if (!pair.key) return 0; + if (!yaml_parser_parse(parser, &event)) return 0; + pair.value = yaml_parser_load_node(parser, &event); + if (!pair.value) return 0; + if (!PUSH(parser, + parser->document->nodes.start[index-1].data.mapping.pairs, + pair)) return 0; + if (!yaml_parser_parse(parser, &event)) return 0; + } + + parser->document->nodes.start[index-1].end_mark = event.end_mark; + + return index; + +error: + yaml_free(tag); + yaml_free(first_event->data.mapping_start.anchor); + return 0; +} + diff --git a/web/server/h2o/libh2o/deps/yaml/src/parser.c b/web/server/h2o/libh2o/deps/yaml/src/parser.c new file mode 100644 index 00000000..eb2a2c79 --- /dev/null +++ b/web/server/h2o/libh2o/deps/yaml/src/parser.c @@ -0,0 +1,1374 @@ + +/* + * The parser implements the following grammar: + * + * stream ::= STREAM-START implicit_document? explicit_document* STREAM-END + * implicit_document ::= block_node DOCUMENT-END* + * explicit_document ::= DIRECTIVE* DOCUMENT-START block_node? DOCUMENT-END* + * block_node_or_indentless_sequence ::= + * ALIAS + * | properties (block_content | indentless_block_sequence)? + * | block_content + * | indentless_block_sequence + * block_node ::= ALIAS + * | properties block_content? + * | block_content + * flow_node ::= ALIAS + * | properties flow_content? + * | flow_content + * properties ::= TAG ANCHOR? | ANCHOR TAG? + * block_content ::= block_collection | flow_collection | SCALAR + * flow_content ::= flow_collection | SCALAR + * block_collection ::= block_sequence | block_mapping + * flow_collection ::= flow_sequence | flow_mapping + * block_sequence ::= BLOCK-SEQUENCE-START (BLOCK-ENTRY block_node?)* BLOCK-END + * indentless_sequence ::= (BLOCK-ENTRY block_node?)+ + * block_mapping ::= BLOCK-MAPPING_START + * ((KEY block_node_or_indentless_sequence?)? + * (VALUE block_node_or_indentless_sequence?)?)* + * BLOCK-END + * flow_sequence ::= FLOW-SEQUENCE-START + * (flow_sequence_entry FLOW-ENTRY)* + * flow_sequence_entry? + * FLOW-SEQUENCE-END + * flow_sequence_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)? + * flow_mapping ::= FLOW-MAPPING-START + * (flow_mapping_entry FLOW-ENTRY)* + * flow_mapping_entry? + * FLOW-MAPPING-END + * flow_mapping_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)? + */ + +#include "yaml_private.h" + +/* + * Peek the next token in the token queue. + */ + +#define PEEK_TOKEN(parser) \ + ((parser->token_available || yaml_parser_fetch_more_tokens(parser)) ? \ + parser->tokens.head : NULL) + +/* + * Remove the next token from the queue (must be called after PEEK_TOKEN). + */ + +#define SKIP_TOKEN(parser) \ + (parser->token_available = 0, \ + parser->tokens_parsed ++, \ + parser->stream_end_produced = \ + (parser->tokens.head->type == YAML_STREAM_END_TOKEN), \ + parser->tokens.head ++) + +/* + * Public API declarations. + */ + +YAML_DECLARE(int) +yaml_parser_parse(yaml_parser_t *parser, yaml_event_t *event); + +/* + * Error handling. + */ + +static int +yaml_parser_set_parser_error(yaml_parser_t *parser, + const char *problem, yaml_mark_t problem_mark); + +static int +yaml_parser_set_parser_error_context(yaml_parser_t *parser, + const char *context, yaml_mark_t context_mark, + const char *problem, yaml_mark_t problem_mark); + +/* + * State functions. + */ + +static int +yaml_parser_state_machine(yaml_parser_t *parser, yaml_event_t *event); + +static int +yaml_parser_parse_stream_start(yaml_parser_t *parser, yaml_event_t *event); + +static int +yaml_parser_parse_document_start(yaml_parser_t *parser, yaml_event_t *event, + int implicit); + +static int +yaml_parser_parse_document_content(yaml_parser_t *parser, yaml_event_t *event); + +static int +yaml_parser_parse_document_end(yaml_parser_t *parser, yaml_event_t *event); + +static int +yaml_parser_parse_node(yaml_parser_t *parser, yaml_event_t *event, + int block, int indentless_sequence); + +static int +yaml_parser_parse_block_sequence_entry(yaml_parser_t *parser, + yaml_event_t *event, int first); + +static int +yaml_parser_parse_indentless_sequence_entry(yaml_parser_t *parser, + yaml_event_t *event); + +static int +yaml_parser_parse_block_mapping_key(yaml_parser_t *parser, + yaml_event_t *event, int first); + +static int +yaml_parser_parse_block_mapping_value(yaml_parser_t *parser, + yaml_event_t *event); + +static int +yaml_parser_parse_flow_sequence_entry(yaml_parser_t *parser, + yaml_event_t *event, int first); + +static int +yaml_parser_parse_flow_sequence_entry_mapping_key(yaml_parser_t *parser, + yaml_event_t *event); + +static int +yaml_parser_parse_flow_sequence_entry_mapping_value(yaml_parser_t *parser, + yaml_event_t *event); + +static int +yaml_parser_parse_flow_sequence_entry_mapping_end(yaml_parser_t *parser, + yaml_event_t *event); + +static int +yaml_parser_parse_flow_mapping_key(yaml_parser_t *parser, + yaml_event_t *event, int first); + +static int +yaml_parser_parse_flow_mapping_value(yaml_parser_t *parser, + yaml_event_t *event, int empty); + +/* + * Utility functions. + */ + +static int +yaml_parser_process_empty_scalar(yaml_parser_t *parser, + yaml_event_t *event, yaml_mark_t mark); + +static int +yaml_parser_process_directives(yaml_parser_t *parser, + yaml_version_directive_t **version_directive_ref, + yaml_tag_directive_t **tag_directives_start_ref, + yaml_tag_directive_t **tag_directives_end_ref); + +static int +yaml_parser_append_tag_directive(yaml_parser_t *parser, + yaml_tag_directive_t value, int allow_duplicates, yaml_mark_t mark); + +/* + * Get the next event. + */ + +YAML_DECLARE(int) +yaml_parser_parse(yaml_parser_t *parser, yaml_event_t *event) +{ + assert(parser); /* Non-NULL parser object is expected. */ + assert(event); /* Non-NULL event object is expected. */ + + /* Erase the event object. */ + + memset(event, 0, sizeof(yaml_event_t)); + + /* No events after the end of the stream or error. */ + + if (parser->stream_end_produced || parser->error || + parser->state == YAML_PARSE_END_STATE) { + return 1; + } + + /* Generate the next event. */ + + return yaml_parser_state_machine(parser, event); +} + +/* + * Set parser error. + */ + +static int +yaml_parser_set_parser_error(yaml_parser_t *parser, + const char *problem, yaml_mark_t problem_mark) +{ + parser->error = YAML_PARSER_ERROR; + parser->problem = problem; + parser->problem_mark = problem_mark; + + return 0; +} + +static int +yaml_parser_set_parser_error_context(yaml_parser_t *parser, + const char *context, yaml_mark_t context_mark, + const char *problem, yaml_mark_t problem_mark) +{ + parser->error = YAML_PARSER_ERROR; + parser->context = context; + parser->context_mark = context_mark; + parser->problem = problem; + parser->problem_mark = problem_mark; + + return 0; +} + + +/* + * State dispatcher. + */ + +static int +yaml_parser_state_machine(yaml_parser_t *parser, yaml_event_t *event) +{ + switch (parser->state) + { + case YAML_PARSE_STREAM_START_STATE: + return yaml_parser_parse_stream_start(parser, event); + + case YAML_PARSE_IMPLICIT_DOCUMENT_START_STATE: + return yaml_parser_parse_document_start(parser, event, 1); + + case YAML_PARSE_DOCUMENT_START_STATE: + return yaml_parser_parse_document_start(parser, event, 0); + + case YAML_PARSE_DOCUMENT_CONTENT_STATE: + return yaml_parser_parse_document_content(parser, event); + + case YAML_PARSE_DOCUMENT_END_STATE: + return yaml_parser_parse_document_end(parser, event); + + case YAML_PARSE_BLOCK_NODE_STATE: + return yaml_parser_parse_node(parser, event, 1, 0); + + case YAML_PARSE_BLOCK_NODE_OR_INDENTLESS_SEQUENCE_STATE: + return yaml_parser_parse_node(parser, event, 1, 1); + + case YAML_PARSE_FLOW_NODE_STATE: + return yaml_parser_parse_node(parser, event, 0, 0); + + case YAML_PARSE_BLOCK_SEQUENCE_FIRST_ENTRY_STATE: + return yaml_parser_parse_block_sequence_entry(parser, event, 1); + + case YAML_PARSE_BLOCK_SEQUENCE_ENTRY_STATE: + return yaml_parser_parse_block_sequence_entry(parser, event, 0); + + case YAML_PARSE_INDENTLESS_SEQUENCE_ENTRY_STATE: + return yaml_parser_parse_indentless_sequence_entry(parser, event); + + case YAML_PARSE_BLOCK_MAPPING_FIRST_KEY_STATE: + return yaml_parser_parse_block_mapping_key(parser, event, 1); + + case YAML_PARSE_BLOCK_MAPPING_KEY_STATE: + return yaml_parser_parse_block_mapping_key(parser, event, 0); + + case YAML_PARSE_BLOCK_MAPPING_VALUE_STATE: + return yaml_parser_parse_block_mapping_value(parser, event); + + case YAML_PARSE_FLOW_SEQUENCE_FIRST_ENTRY_STATE: + return yaml_parser_parse_flow_sequence_entry(parser, event, 1); + + case YAML_PARSE_FLOW_SEQUENCE_ENTRY_STATE: + return yaml_parser_parse_flow_sequence_entry(parser, event, 0); + + case YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_KEY_STATE: + return yaml_parser_parse_flow_sequence_entry_mapping_key(parser, event); + + case YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_VALUE_STATE: + return yaml_parser_parse_flow_sequence_entry_mapping_value(parser, event); + + case YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_END_STATE: + return yaml_parser_parse_flow_sequence_entry_mapping_end(parser, event); + + case YAML_PARSE_FLOW_MAPPING_FIRST_KEY_STATE: + return yaml_parser_parse_flow_mapping_key(parser, event, 1); + + case YAML_PARSE_FLOW_MAPPING_KEY_STATE: + return yaml_parser_parse_flow_mapping_key(parser, event, 0); + + case YAML_PARSE_FLOW_MAPPING_VALUE_STATE: + return yaml_parser_parse_flow_mapping_value(parser, event, 0); + + case YAML_PARSE_FLOW_MAPPING_EMPTY_VALUE_STATE: + return yaml_parser_parse_flow_mapping_value(parser, event, 1); + + default: + assert(1); /* Invalid state. */ + } + + return 0; +} + +/* + * Parse the production: + * stream ::= STREAM-START implicit_document? explicit_document* STREAM-END + * ************ + */ + +static int +yaml_parser_parse_stream_start(yaml_parser_t *parser, yaml_event_t *event) +{ + yaml_token_t *token; + + token = PEEK_TOKEN(parser); + if (!token) return 0; + + if (token->type != YAML_STREAM_START_TOKEN) { + return yaml_parser_set_parser_error(parser, + "did not find expected ", token->start_mark); + } + + parser->state = YAML_PARSE_IMPLICIT_DOCUMENT_START_STATE; + STREAM_START_EVENT_INIT(*event, token->data.stream_start.encoding, + token->start_mark, token->start_mark); + SKIP_TOKEN(parser); + + return 1; +} + +/* + * Parse the productions: + * implicit_document ::= block_node DOCUMENT-END* + * * + * explicit_document ::= DIRECTIVE* DOCUMENT-START block_node? DOCUMENT-END* + * ************************* + */ + +static int +yaml_parser_parse_document_start(yaml_parser_t *parser, yaml_event_t *event, + int implicit) +{ + yaml_token_t *token; + yaml_version_directive_t *version_directive = NULL; + struct { + yaml_tag_directive_t *start; + yaml_tag_directive_t *end; + } tag_directives = { NULL, NULL }; + + token = PEEK_TOKEN(parser); + if (!token) return 0; + + /* Parse extra document end indicators. */ + + if (!implicit) + { + while (token->type == YAML_DOCUMENT_END_TOKEN) { + SKIP_TOKEN(parser); + token = PEEK_TOKEN(parser); + if (!token) return 0; + } + } + + /* Parse an implicit document. */ + + if (implicit && token->type != YAML_VERSION_DIRECTIVE_TOKEN && + token->type != YAML_TAG_DIRECTIVE_TOKEN && + token->type != YAML_DOCUMENT_START_TOKEN && + token->type != YAML_STREAM_END_TOKEN) + { + if (!yaml_parser_process_directives(parser, NULL, NULL, NULL)) + return 0; + if (!PUSH(parser, parser->states, YAML_PARSE_DOCUMENT_END_STATE)) + return 0; + parser->state = YAML_PARSE_BLOCK_NODE_STATE; + DOCUMENT_START_EVENT_INIT(*event, NULL, NULL, NULL, 1, + token->start_mark, token->start_mark); + return 1; + } + + /* Parse an explicit document. */ + + else if (token->type != YAML_STREAM_END_TOKEN) + { + yaml_mark_t start_mark, end_mark; + start_mark = token->start_mark; + if (!yaml_parser_process_directives(parser, &version_directive, + &tag_directives.start, &tag_directives.end)) + return 0; + token = PEEK_TOKEN(parser); + if (!token) goto error; + if (token->type != YAML_DOCUMENT_START_TOKEN) { + yaml_parser_set_parser_error(parser, + "did not find expected ", token->start_mark); + goto error; + } + if (!PUSH(parser, parser->states, YAML_PARSE_DOCUMENT_END_STATE)) + goto error; + parser->state = YAML_PARSE_DOCUMENT_CONTENT_STATE; + end_mark = token->end_mark; + DOCUMENT_START_EVENT_INIT(*event, version_directive, + tag_directives.start, tag_directives.end, 0, + start_mark, end_mark); + SKIP_TOKEN(parser); + version_directive = NULL; + tag_directives.start = tag_directives.end = NULL; + return 1; + } + + /* Parse the stream end. */ + + else + { + parser->state = YAML_PARSE_END_STATE; + STREAM_END_EVENT_INIT(*event, token->start_mark, token->end_mark); + SKIP_TOKEN(parser); + return 1; + } + +error: + yaml_free(version_directive); + while (tag_directives.start != tag_directives.end) { + yaml_free(tag_directives.end[-1].handle); + yaml_free(tag_directives.end[-1].prefix); + tag_directives.end --; + } + yaml_free(tag_directives.start); + return 0; +} + +/* + * Parse the productions: + * explicit_document ::= DIRECTIVE* DOCUMENT-START block_node? DOCUMENT-END* + * *********** + */ + +static int +yaml_parser_parse_document_content(yaml_parser_t *parser, yaml_event_t *event) +{ + yaml_token_t *token; + + token = PEEK_TOKEN(parser); + if (!token) return 0; + + if (token->type == YAML_VERSION_DIRECTIVE_TOKEN || + token->type == YAML_TAG_DIRECTIVE_TOKEN || + token->type == YAML_DOCUMENT_START_TOKEN || + token->type == YAML_DOCUMENT_END_TOKEN || + token->type == YAML_STREAM_END_TOKEN) { + parser->state = POP(parser, parser->states); + return yaml_parser_process_empty_scalar(parser, event, + token->start_mark); + } + else { + return yaml_parser_parse_node(parser, event, 1, 0); + } +} + +/* + * Parse the productions: + * implicit_document ::= block_node DOCUMENT-END* + * ************* + * explicit_document ::= DIRECTIVE* DOCUMENT-START block_node? DOCUMENT-END* + * ************* + */ + +static int +yaml_parser_parse_document_end(yaml_parser_t *parser, yaml_event_t *event) +{ + yaml_token_t *token; + yaml_mark_t start_mark, end_mark; + int implicit = 1; + + token = PEEK_TOKEN(parser); + if (!token) return 0; + + start_mark = end_mark = token->start_mark; + + if (token->type == YAML_DOCUMENT_END_TOKEN) { + end_mark = token->end_mark; + SKIP_TOKEN(parser); + implicit = 0; + } + + while (!STACK_EMPTY(parser, parser->tag_directives)) { + yaml_tag_directive_t tag_directive = POP(parser, parser->tag_directives); + yaml_free(tag_directive.handle); + yaml_free(tag_directive.prefix); + } + + parser->state = YAML_PARSE_DOCUMENT_START_STATE; + DOCUMENT_END_EVENT_INIT(*event, implicit, start_mark, end_mark); + + return 1; +} + +/* + * Parse the productions: + * block_node_or_indentless_sequence ::= + * ALIAS + * ***** + * | properties (block_content | indentless_block_sequence)? + * ********** * + * | block_content | indentless_block_sequence + * * + * block_node ::= ALIAS + * ***** + * | properties block_content? + * ********** * + * | block_content + * * + * flow_node ::= ALIAS + * ***** + * | properties flow_content? + * ********** * + * | flow_content + * * + * properties ::= TAG ANCHOR? | ANCHOR TAG? + * ************************* + * block_content ::= block_collection | flow_collection | SCALAR + * ****** + * flow_content ::= flow_collection | SCALAR + * ****** + */ + +static int +yaml_parser_parse_node(yaml_parser_t *parser, yaml_event_t *event, + int block, int indentless_sequence) +{ + yaml_token_t *token; + yaml_char_t *anchor = NULL; + yaml_char_t *tag_handle = NULL; + yaml_char_t *tag_suffix = NULL; + yaml_char_t *tag = NULL; + yaml_mark_t start_mark, end_mark, tag_mark; + int implicit; + + token = PEEK_TOKEN(parser); + if (!token) return 0; + + if (token->type == YAML_ALIAS_TOKEN) + { + parser->state = POP(parser, parser->states); + ALIAS_EVENT_INIT(*event, token->data.alias.value, + token->start_mark, token->end_mark); + SKIP_TOKEN(parser); + return 1; + } + + else + { + start_mark = end_mark = token->start_mark; + + if (token->type == YAML_ANCHOR_TOKEN) + { + anchor = token->data.anchor.value; + start_mark = token->start_mark; + end_mark = token->end_mark; + SKIP_TOKEN(parser); + token = PEEK_TOKEN(parser); + if (!token) goto error; + if (token->type == YAML_TAG_TOKEN) + { + tag_handle = token->data.tag.handle; + tag_suffix = token->data.tag.suffix; + tag_mark = token->start_mark; + end_mark = token->end_mark; + SKIP_TOKEN(parser); + token = PEEK_TOKEN(parser); + if (!token) goto error; + } + } + else if (token->type == YAML_TAG_TOKEN) + { + tag_handle = token->data.tag.handle; + tag_suffix = token->data.tag.suffix; + start_mark = tag_mark = token->start_mark; + end_mark = token->end_mark; + SKIP_TOKEN(parser); + token = PEEK_TOKEN(parser); + if (!token) goto error; + if (token->type == YAML_ANCHOR_TOKEN) + { + anchor = token->data.anchor.value; + end_mark = token->end_mark; + SKIP_TOKEN(parser); + token = PEEK_TOKEN(parser); + if (!token) goto error; + } + } + + if (tag_handle) { + if (!*tag_handle) { + tag = tag_suffix; + yaml_free(tag_handle); + tag_handle = tag_suffix = NULL; + } + else { + yaml_tag_directive_t *tag_directive; + for (tag_directive = parser->tag_directives.start; + tag_directive != parser->tag_directives.top; + tag_directive ++) { + if (strcmp((char *)tag_directive->handle, (char *)tag_handle) == 0) { + size_t prefix_len = strlen((char *)tag_directive->prefix); + size_t suffix_len = strlen((char *)tag_suffix); + tag = yaml_malloc(prefix_len+suffix_len+1); + if (!tag) { + parser->error = YAML_MEMORY_ERROR; + goto error; + } + memcpy(tag, tag_directive->prefix, prefix_len); + memcpy(tag+prefix_len, tag_suffix, suffix_len); + tag[prefix_len+suffix_len] = '\0'; + yaml_free(tag_handle); + yaml_free(tag_suffix); + tag_handle = tag_suffix = NULL; + break; + } + } + if (!tag) { + yaml_parser_set_parser_error_context(parser, + "while parsing a node", start_mark, + "found undefined tag handle", tag_mark); + goto error; + } + } + } + + implicit = (!tag || !*tag); + if (indentless_sequence && token->type == YAML_BLOCK_ENTRY_TOKEN) { + end_mark = token->end_mark; + parser->state = YAML_PARSE_INDENTLESS_SEQUENCE_ENTRY_STATE; + SEQUENCE_START_EVENT_INIT(*event, anchor, tag, implicit, + YAML_BLOCK_SEQUENCE_STYLE, start_mark, end_mark); + return 1; + } + else { + if (token->type == YAML_SCALAR_TOKEN) { + int plain_implicit = 0; + int quoted_implicit = 0; + end_mark = token->end_mark; + if ((token->data.scalar.style == YAML_PLAIN_SCALAR_STYLE && !tag) + || (tag && strcmp((char *)tag, "!") == 0)) { + plain_implicit = 1; + } + else if (!tag) { + quoted_implicit = 1; + } + parser->state = POP(parser, parser->states); + SCALAR_EVENT_INIT(*event, anchor, tag, + token->data.scalar.value, token->data.scalar.length, + plain_implicit, quoted_implicit, + token->data.scalar.style, start_mark, end_mark); + SKIP_TOKEN(parser); + return 1; + } + else if (token->type == YAML_FLOW_SEQUENCE_START_TOKEN) { + end_mark = token->end_mark; + parser->state = YAML_PARSE_FLOW_SEQUENCE_FIRST_ENTRY_STATE; + SEQUENCE_START_EVENT_INIT(*event, anchor, tag, implicit, + YAML_FLOW_SEQUENCE_STYLE, start_mark, end_mark); + return 1; + } + else if (token->type == YAML_FLOW_MAPPING_START_TOKEN) { + end_mark = token->end_mark; + parser->state = YAML_PARSE_FLOW_MAPPING_FIRST_KEY_STATE; + MAPPING_START_EVENT_INIT(*event, anchor, tag, implicit, + YAML_FLOW_MAPPING_STYLE, start_mark, end_mark); + return 1; + } + else if (block && token->type == YAML_BLOCK_SEQUENCE_START_TOKEN) { + end_mark = token->end_mark; + parser->state = YAML_PARSE_BLOCK_SEQUENCE_FIRST_ENTRY_STATE; + SEQUENCE_START_EVENT_INIT(*event, anchor, tag, implicit, + YAML_BLOCK_SEQUENCE_STYLE, start_mark, end_mark); + return 1; + } + else if (block && token->type == YAML_BLOCK_MAPPING_START_TOKEN) { + end_mark = token->end_mark; + parser->state = YAML_PARSE_BLOCK_MAPPING_FIRST_KEY_STATE; + MAPPING_START_EVENT_INIT(*event, anchor, tag, implicit, + YAML_BLOCK_MAPPING_STYLE, start_mark, end_mark); + return 1; + } + else if (anchor || tag) { + yaml_char_t *value = yaml_malloc(1); + if (!value) { + parser->error = YAML_MEMORY_ERROR; + goto error; + } + value[0] = '\0'; + parser->state = POP(parser, parser->states); + SCALAR_EVENT_INIT(*event, anchor, tag, value, 0, + implicit, 0, YAML_PLAIN_SCALAR_STYLE, + start_mark, end_mark); + return 1; + } + else { + yaml_parser_set_parser_error_context(parser, + (block ? "while parsing a block node" + : "while parsing a flow node"), start_mark, + "did not find expected node content", token->start_mark); + goto error; + } + } + } + +error: + yaml_free(anchor); + yaml_free(tag_handle); + yaml_free(tag_suffix); + yaml_free(tag); + + return 0; +} + +/* + * Parse the productions: + * block_sequence ::= BLOCK-SEQUENCE-START (BLOCK-ENTRY block_node?)* BLOCK-END + * ******************** *********** * ********* + */ + +static int +yaml_parser_parse_block_sequence_entry(yaml_parser_t *parser, + yaml_event_t *event, int first) +{ + yaml_token_t *token; + + if (first) { + token = PEEK_TOKEN(parser); + if (!PUSH(parser, parser->marks, token->start_mark)) + return 0; + SKIP_TOKEN(parser); + } + + token = PEEK_TOKEN(parser); + if (!token) return 0; + + if (token->type == YAML_BLOCK_ENTRY_TOKEN) + { + yaml_mark_t mark = token->end_mark; + SKIP_TOKEN(parser); + token = PEEK_TOKEN(parser); + if (!token) return 0; + if (token->type != YAML_BLOCK_ENTRY_TOKEN && + token->type != YAML_BLOCK_END_TOKEN) { + if (!PUSH(parser, parser->states, + YAML_PARSE_BLOCK_SEQUENCE_ENTRY_STATE)) + return 0; + return yaml_parser_parse_node(parser, event, 1, 0); + } + else { + parser->state = YAML_PARSE_BLOCK_SEQUENCE_ENTRY_STATE; + return yaml_parser_process_empty_scalar(parser, event, mark); + } + } + + else if (token->type == YAML_BLOCK_END_TOKEN) + { + yaml_mark_t dummy_mark; /* Used to eliminate a compiler warning. */ + parser->state = POP(parser, parser->states); + dummy_mark = POP(parser, parser->marks); + SEQUENCE_END_EVENT_INIT(*event, token->start_mark, token->end_mark); + SKIP_TOKEN(parser); + return 1; + } + + else + { + return yaml_parser_set_parser_error_context(parser, + "while parsing a block collection", POP(parser, parser->marks), + "did not find expected '-' indicator", token->start_mark); + } +} + +/* + * Parse the productions: + * indentless_sequence ::= (BLOCK-ENTRY block_node?)+ + * *********** * + */ + +static int +yaml_parser_parse_indentless_sequence_entry(yaml_parser_t *parser, + yaml_event_t *event) +{ + yaml_token_t *token; + + token = PEEK_TOKEN(parser); + if (!token) return 0; + + if (token->type == YAML_BLOCK_ENTRY_TOKEN) + { + yaml_mark_t mark = token->end_mark; + SKIP_TOKEN(parser); + token = PEEK_TOKEN(parser); + if (!token) return 0; + if (token->type != YAML_BLOCK_ENTRY_TOKEN && + token->type != YAML_KEY_TOKEN && + token->type != YAML_VALUE_TOKEN && + token->type != YAML_BLOCK_END_TOKEN) { + if (!PUSH(parser, parser->states, + YAML_PARSE_INDENTLESS_SEQUENCE_ENTRY_STATE)) + return 0; + return yaml_parser_parse_node(parser, event, 1, 0); + } + else { + parser->state = YAML_PARSE_INDENTLESS_SEQUENCE_ENTRY_STATE; + return yaml_parser_process_empty_scalar(parser, event, mark); + } + } + + else + { + parser->state = POP(parser, parser->states); + SEQUENCE_END_EVENT_INIT(*event, token->start_mark, token->start_mark); + return 1; + } +} + +/* + * Parse the productions: + * block_mapping ::= BLOCK-MAPPING_START + * ******************* + * ((KEY block_node_or_indentless_sequence?)? + * *** * + * (VALUE block_node_or_indentless_sequence?)?)* + * + * BLOCK-END + * ********* + */ + +static int +yaml_parser_parse_block_mapping_key(yaml_parser_t *parser, + yaml_event_t *event, int first) +{ + yaml_token_t *token; + + if (first) { + token = PEEK_TOKEN(parser); + if (!PUSH(parser, parser->marks, token->start_mark)) + return 0; + SKIP_TOKEN(parser); + } + + token = PEEK_TOKEN(parser); + if (!token) return 0; + + if (token->type == YAML_KEY_TOKEN) + { + yaml_mark_t mark = token->end_mark; + SKIP_TOKEN(parser); + token = PEEK_TOKEN(parser); + if (!token) return 0; + if (token->type != YAML_KEY_TOKEN && + token->type != YAML_VALUE_TOKEN && + token->type != YAML_BLOCK_END_TOKEN) { + if (!PUSH(parser, parser->states, + YAML_PARSE_BLOCK_MAPPING_VALUE_STATE)) + return 0; + return yaml_parser_parse_node(parser, event, 1, 1); + } + else { + parser->state = YAML_PARSE_BLOCK_MAPPING_VALUE_STATE; + return yaml_parser_process_empty_scalar(parser, event, mark); + } + } + + else if (token->type == YAML_BLOCK_END_TOKEN) + { + yaml_mark_t dummy_mark; /* Used to eliminate a compiler warning. */ + parser->state = POP(parser, parser->states); + dummy_mark = POP(parser, parser->marks); + MAPPING_END_EVENT_INIT(*event, token->start_mark, token->end_mark); + SKIP_TOKEN(parser); + return 1; + } + + else + { + return yaml_parser_set_parser_error_context(parser, + "while parsing a block mapping", POP(parser, parser->marks), + "did not find expected key", token->start_mark); + } +} + +/* + * Parse the productions: + * block_mapping ::= BLOCK-MAPPING_START + * + * ((KEY block_node_or_indentless_sequence?)? + * + * (VALUE block_node_or_indentless_sequence?)?)* + * ***** * + * BLOCK-END + * + */ + +static int +yaml_parser_parse_block_mapping_value(yaml_parser_t *parser, + yaml_event_t *event) +{ + yaml_token_t *token; + + token = PEEK_TOKEN(parser); + if (!token) return 0; + + if (token->type == YAML_VALUE_TOKEN) + { + yaml_mark_t mark = token->end_mark; + SKIP_TOKEN(parser); + token = PEEK_TOKEN(parser); + if (!token) return 0; + if (token->type != YAML_KEY_TOKEN && + token->type != YAML_VALUE_TOKEN && + token->type != YAML_BLOCK_END_TOKEN) { + if (!PUSH(parser, parser->states, + YAML_PARSE_BLOCK_MAPPING_KEY_STATE)) + return 0; + return yaml_parser_parse_node(parser, event, 1, 1); + } + else { + parser->state = YAML_PARSE_BLOCK_MAPPING_KEY_STATE; + return yaml_parser_process_empty_scalar(parser, event, mark); + } + } + + else + { + parser->state = YAML_PARSE_BLOCK_MAPPING_KEY_STATE; + return yaml_parser_process_empty_scalar(parser, event, token->start_mark); + } +} + +/* + * Parse the productions: + * flow_sequence ::= FLOW-SEQUENCE-START + * ******************* + * (flow_sequence_entry FLOW-ENTRY)* + * * ********** + * flow_sequence_entry? + * * + * FLOW-SEQUENCE-END + * ***************** + * flow_sequence_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)? + * * + */ + +static int +yaml_parser_parse_flow_sequence_entry(yaml_parser_t *parser, + yaml_event_t *event, int first) +{ + yaml_token_t *token; + yaml_mark_t dummy_mark; /* Used to eliminate a compiler warning. */ + + if (first) { + token = PEEK_TOKEN(parser); + if (!PUSH(parser, parser->marks, token->start_mark)) + return 0; + SKIP_TOKEN(parser); + } + + token = PEEK_TOKEN(parser); + if (!token) return 0; + + if (token->type != YAML_FLOW_SEQUENCE_END_TOKEN) + { + if (!first) { + if (token->type == YAML_FLOW_ENTRY_TOKEN) { + SKIP_TOKEN(parser); + token = PEEK_TOKEN(parser); + if (!token) return 0; + } + else { + return yaml_parser_set_parser_error_context(parser, + "while parsing a flow sequence", POP(parser, parser->marks), + "did not find expected ',' or ']'", token->start_mark); + } + } + + if (token->type == YAML_KEY_TOKEN) { + parser->state = YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_KEY_STATE; + MAPPING_START_EVENT_INIT(*event, NULL, NULL, + 1, YAML_FLOW_MAPPING_STYLE, + token->start_mark, token->end_mark); + SKIP_TOKEN(parser); + return 1; + } + + else if (token->type != YAML_FLOW_SEQUENCE_END_TOKEN) { + if (!PUSH(parser, parser->states, + YAML_PARSE_FLOW_SEQUENCE_ENTRY_STATE)) + return 0; + return yaml_parser_parse_node(parser, event, 0, 0); + } + } + + parser->state = POP(parser, parser->states); + dummy_mark = POP(parser, parser->marks); + SEQUENCE_END_EVENT_INIT(*event, token->start_mark, token->end_mark); + SKIP_TOKEN(parser); + return 1; +} + +/* + * Parse the productions: + * flow_sequence_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)? + * *** * + */ + +static int +yaml_parser_parse_flow_sequence_entry_mapping_key(yaml_parser_t *parser, + yaml_event_t *event) +{ + yaml_token_t *token; + + token = PEEK_TOKEN(parser); + if (!token) return 0; + + if (token->type != YAML_VALUE_TOKEN && token->type != YAML_FLOW_ENTRY_TOKEN + && token->type != YAML_FLOW_SEQUENCE_END_TOKEN) { + if (!PUSH(parser, parser->states, + YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_VALUE_STATE)) + return 0; + return yaml_parser_parse_node(parser, event, 0, 0); + } + else { + yaml_mark_t mark = token->end_mark; + SKIP_TOKEN(parser); + parser->state = YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_VALUE_STATE; + return yaml_parser_process_empty_scalar(parser, event, mark); + } +} + +/* + * Parse the productions: + * flow_sequence_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)? + * ***** * + */ + +static int +yaml_parser_parse_flow_sequence_entry_mapping_value(yaml_parser_t *parser, + yaml_event_t *event) +{ + yaml_token_t *token; + + token = PEEK_TOKEN(parser); + if (!token) return 0; + + if (token->type == YAML_VALUE_TOKEN) { + SKIP_TOKEN(parser); + token = PEEK_TOKEN(parser); + if (!token) return 0; + if (token->type != YAML_FLOW_ENTRY_TOKEN + && token->type != YAML_FLOW_SEQUENCE_END_TOKEN) { + if (!PUSH(parser, parser->states, + YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_END_STATE)) + return 0; + return yaml_parser_parse_node(parser, event, 0, 0); + } + } + parser->state = YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_END_STATE; + return yaml_parser_process_empty_scalar(parser, event, token->start_mark); +} + +/* + * Parse the productions: + * flow_sequence_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)? + * * + */ + +static int +yaml_parser_parse_flow_sequence_entry_mapping_end(yaml_parser_t *parser, + yaml_event_t *event) +{ + yaml_token_t *token; + + token = PEEK_TOKEN(parser); + if (!token) return 0; + + parser->state = YAML_PARSE_FLOW_SEQUENCE_ENTRY_STATE; + + MAPPING_END_EVENT_INIT(*event, token->start_mark, token->start_mark); + return 1; +} + +/* + * Parse the productions: + * flow_mapping ::= FLOW-MAPPING-START + * ****************** + * (flow_mapping_entry FLOW-ENTRY)* + * * ********** + * flow_mapping_entry? + * ****************** + * FLOW-MAPPING-END + * **************** + * flow_mapping_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)? + * * *** * + */ + +static int +yaml_parser_parse_flow_mapping_key(yaml_parser_t *parser, + yaml_event_t *event, int first) +{ + yaml_token_t *token; + yaml_mark_t dummy_mark; /* Used to eliminate a compiler warning. */ + + if (first) { + token = PEEK_TOKEN(parser); + if (!PUSH(parser, parser->marks, token->start_mark)) + return 0; + SKIP_TOKEN(parser); + } + + token = PEEK_TOKEN(parser); + if (!token) return 0; + + if (token->type != YAML_FLOW_MAPPING_END_TOKEN) + { + if (!first) { + if (token->type == YAML_FLOW_ENTRY_TOKEN) { + SKIP_TOKEN(parser); + token = PEEK_TOKEN(parser); + if (!token) return 0; + } + else { + return yaml_parser_set_parser_error_context(parser, + "while parsing a flow mapping", POP(parser, parser->marks), + "did not find expected ',' or '}'", token->start_mark); + } + } + + if (token->type == YAML_KEY_TOKEN) { + SKIP_TOKEN(parser); + token = PEEK_TOKEN(parser); + if (!token) return 0; + if (token->type != YAML_VALUE_TOKEN + && token->type != YAML_FLOW_ENTRY_TOKEN + && token->type != YAML_FLOW_MAPPING_END_TOKEN) { + if (!PUSH(parser, parser->states, + YAML_PARSE_FLOW_MAPPING_VALUE_STATE)) + return 0; + return yaml_parser_parse_node(parser, event, 0, 0); + } + else { + parser->state = YAML_PARSE_FLOW_MAPPING_VALUE_STATE; + return yaml_parser_process_empty_scalar(parser, event, + token->start_mark); + } + } + else if (token->type != YAML_FLOW_MAPPING_END_TOKEN) { + if (!PUSH(parser, parser->states, + YAML_PARSE_FLOW_MAPPING_EMPTY_VALUE_STATE)) + return 0; + return yaml_parser_parse_node(parser, event, 0, 0); + } + } + + parser->state = POP(parser, parser->states); + dummy_mark = POP(parser, parser->marks); + MAPPING_END_EVENT_INIT(*event, token->start_mark, token->end_mark); + SKIP_TOKEN(parser); + return 1; +} + +/* + * Parse the productions: + * flow_mapping_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)? + * * ***** * + */ + +static int +yaml_parser_parse_flow_mapping_value(yaml_parser_t *parser, + yaml_event_t *event, int empty) +{ + yaml_token_t *token; + + token = PEEK_TOKEN(parser); + if (!token) return 0; + + if (empty) { + parser->state = YAML_PARSE_FLOW_MAPPING_KEY_STATE; + return yaml_parser_process_empty_scalar(parser, event, + token->start_mark); + } + + if (token->type == YAML_VALUE_TOKEN) { + SKIP_TOKEN(parser); + token = PEEK_TOKEN(parser); + if (!token) return 0; + if (token->type != YAML_FLOW_ENTRY_TOKEN + && token->type != YAML_FLOW_MAPPING_END_TOKEN) { + if (!PUSH(parser, parser->states, + YAML_PARSE_FLOW_MAPPING_KEY_STATE)) + return 0; + return yaml_parser_parse_node(parser, event, 0, 0); + } + } + + parser->state = YAML_PARSE_FLOW_MAPPING_KEY_STATE; + return yaml_parser_process_empty_scalar(parser, event, token->start_mark); +} + +/* + * Generate an empty scalar event. + */ + +static int +yaml_parser_process_empty_scalar(yaml_parser_t *parser, yaml_event_t *event, + yaml_mark_t mark) +{ + yaml_char_t *value; + + value = yaml_malloc(1); + if (!value) { + parser->error = YAML_MEMORY_ERROR; + return 0; + } + value[0] = '\0'; + + SCALAR_EVENT_INIT(*event, NULL, NULL, value, 0, + 1, 0, YAML_PLAIN_SCALAR_STYLE, mark, mark); + + return 1; +} + +/* + * Parse directives. + */ + +static int +yaml_parser_process_directives(yaml_parser_t *parser, + yaml_version_directive_t **version_directive_ref, + yaml_tag_directive_t **tag_directives_start_ref, + yaml_tag_directive_t **tag_directives_end_ref) +{ + yaml_tag_directive_t default_tag_directives[] = { + {(yaml_char_t *)"!", (yaml_char_t *)"!"}, + {(yaml_char_t *)"!!", (yaml_char_t *)"tag:yaml.org,2002:"}, + {NULL, NULL} + }; + yaml_tag_directive_t *default_tag_directive; + yaml_version_directive_t *version_directive = NULL; + struct { + yaml_tag_directive_t *start; + yaml_tag_directive_t *end; + yaml_tag_directive_t *top; + } tag_directives = { NULL, NULL, NULL }; + yaml_token_t *token; + + if (!STACK_INIT(parser, tag_directives, INITIAL_STACK_SIZE)) + goto error; + + token = PEEK_TOKEN(parser); + if (!token) goto error; + + while (token->type == YAML_VERSION_DIRECTIVE_TOKEN || + token->type == YAML_TAG_DIRECTIVE_TOKEN) + { + if (token->type == YAML_VERSION_DIRECTIVE_TOKEN) { + if (version_directive) { + yaml_parser_set_parser_error(parser, + "found duplicate %YAML directive", token->start_mark); + goto error; + } + if (token->data.version_directive.major != 1 + || token->data.version_directive.minor != 1) { + yaml_parser_set_parser_error(parser, + "found incompatible YAML document", token->start_mark); + goto error; + } + version_directive = yaml_malloc(sizeof(yaml_version_directive_t)); + if (!version_directive) { + parser->error = YAML_MEMORY_ERROR; + goto error; + } + version_directive->major = token->data.version_directive.major; + version_directive->minor = token->data.version_directive.minor; + } + + else if (token->type == YAML_TAG_DIRECTIVE_TOKEN) { + yaml_tag_directive_t value; + value.handle = token->data.tag_directive.handle; + value.prefix = token->data.tag_directive.prefix; + + if (!yaml_parser_append_tag_directive(parser, value, 0, + token->start_mark)) + goto error; + if (!PUSH(parser, tag_directives, value)) + goto error; + } + + SKIP_TOKEN(parser); + token = PEEK_TOKEN(parser); + if (!token) goto error; + } + + for (default_tag_directive = default_tag_directives; + default_tag_directive->handle; default_tag_directive++) { + if (!yaml_parser_append_tag_directive(parser, *default_tag_directive, 1, + token->start_mark)) + goto error; + } + + if (version_directive_ref) { + *version_directive_ref = version_directive; + } + if (tag_directives_start_ref) { + if (STACK_EMPTY(parser, tag_directives)) { + *tag_directives_start_ref = *tag_directives_end_ref = NULL; + STACK_DEL(parser, tag_directives); + } + else { + *tag_directives_start_ref = tag_directives.start; + *tag_directives_end_ref = tag_directives.top; + } + } + else { + STACK_DEL(parser, tag_directives); + } + + return 1; + +error: + yaml_free(version_directive); + while (!STACK_EMPTY(parser, tag_directives)) { + yaml_tag_directive_t tag_directive = POP(parser, tag_directives); + yaml_free(tag_directive.handle); + yaml_free(tag_directive.prefix); + } + STACK_DEL(parser, tag_directives); + return 0; +} + +/* + * Append a tag directive to the directives stack. + */ + +static int +yaml_parser_append_tag_directive(yaml_parser_t *parser, + yaml_tag_directive_t value, int allow_duplicates, yaml_mark_t mark) +{ + yaml_tag_directive_t *tag_directive; + yaml_tag_directive_t copy = { NULL, NULL }; + + for (tag_directive = parser->tag_directives.start; + tag_directive != parser->tag_directives.top; tag_directive ++) { + if (strcmp((char *)value.handle, (char *)tag_directive->handle) == 0) { + if (allow_duplicates) + return 1; + return yaml_parser_set_parser_error(parser, + "found duplicate %TAG directive", mark); + } + } + + copy.handle = yaml_strdup(value.handle); + copy.prefix = yaml_strdup(value.prefix); + if (!copy.handle || !copy.prefix) { + parser->error = YAML_MEMORY_ERROR; + goto error; + } + + if (!PUSH(parser, parser->tag_directives, copy)) + goto error; + + return 1; + +error: + yaml_free(copy.handle); + yaml_free(copy.prefix); + return 0; +} + diff --git a/web/server/h2o/libh2o/deps/yaml/src/reader.c b/web/server/h2o/libh2o/deps/yaml/src/reader.c new file mode 100644 index 00000000..d47921ce --- /dev/null +++ b/web/server/h2o/libh2o/deps/yaml/src/reader.c @@ -0,0 +1,469 @@ + +#include "yaml_private.h" + +/* + * Declarations. + */ + +static int +yaml_parser_set_reader_error(yaml_parser_t *parser, const char *problem, + size_t offset, int value); + +static int +yaml_parser_update_raw_buffer(yaml_parser_t *parser); + +static int +yaml_parser_determine_encoding(yaml_parser_t *parser); + +YAML_DECLARE(int) +yaml_parser_update_buffer(yaml_parser_t *parser, size_t length); + +/* + * Set the reader error and return 0. + */ + +static int +yaml_parser_set_reader_error(yaml_parser_t *parser, const char *problem, + size_t offset, int value) +{ + parser->error = YAML_READER_ERROR; + parser->problem = problem; + parser->problem_offset = offset; + parser->problem_value = value; + + return 0; +} + +/* + * Byte order marks. + */ + +#define BOM_UTF8 "\xef\xbb\xbf" +#define BOM_UTF16LE "\xff\xfe" +#define BOM_UTF16BE "\xfe\xff" + +/* + * Determine the input stream encoding by checking the BOM symbol. If no BOM is + * found, the UTF-8 encoding is assumed. Return 1 on success, 0 on failure. + */ + +static int +yaml_parser_determine_encoding(yaml_parser_t *parser) +{ + /* Ensure that we had enough bytes in the raw buffer. */ + + while (!parser->eof + && parser->raw_buffer.last - parser->raw_buffer.pointer < 3) { + if (!yaml_parser_update_raw_buffer(parser)) { + return 0; + } + } + + /* Determine the encoding. */ + + if (parser->raw_buffer.last - parser->raw_buffer.pointer >= 2 + && !memcmp(parser->raw_buffer.pointer, BOM_UTF16LE, 2)) { + parser->encoding = YAML_UTF16LE_ENCODING; + parser->raw_buffer.pointer += 2; + parser->offset += 2; + } + else if (parser->raw_buffer.last - parser->raw_buffer.pointer >= 2 + && !memcmp(parser->raw_buffer.pointer, BOM_UTF16BE, 2)) { + parser->encoding = YAML_UTF16BE_ENCODING; + parser->raw_buffer.pointer += 2; + parser->offset += 2; + } + else if (parser->raw_buffer.last - parser->raw_buffer.pointer >= 3 + && !memcmp(parser->raw_buffer.pointer, BOM_UTF8, 3)) { + parser->encoding = YAML_UTF8_ENCODING; + parser->raw_buffer.pointer += 3; + parser->offset += 3; + } + else { + parser->encoding = YAML_UTF8_ENCODING; + } + + return 1; +} + +/* + * Update the raw buffer. + */ + +static int +yaml_parser_update_raw_buffer(yaml_parser_t *parser) +{ + size_t size_read = 0; + + /* Return if the raw buffer is full. */ + + if (parser->raw_buffer.start == parser->raw_buffer.pointer + && parser->raw_buffer.last == parser->raw_buffer.end) + return 1; + + /* Return on EOF. */ + + if (parser->eof) return 1; + + /* Move the remaining bytes in the raw buffer to the beginning. */ + + if (parser->raw_buffer.start < parser->raw_buffer.pointer + && parser->raw_buffer.pointer < parser->raw_buffer.last) { + memmove(parser->raw_buffer.start, parser->raw_buffer.pointer, + parser->raw_buffer.last - parser->raw_buffer.pointer); + } + parser->raw_buffer.last -= + parser->raw_buffer.pointer - parser->raw_buffer.start; + parser->raw_buffer.pointer = parser->raw_buffer.start; + + /* Call the read handler to fill the buffer. */ + + if (!parser->read_handler(parser->read_handler_data, parser->raw_buffer.last, + parser->raw_buffer.end - parser->raw_buffer.last, &size_read)) { + return yaml_parser_set_reader_error(parser, "input error", + parser->offset, -1); + } + parser->raw_buffer.last += size_read; + if (!size_read) { + parser->eof = 1; + } + + return 1; +} + +/* + * Ensure that the buffer contains at least `length` characters. + * Return 1 on success, 0 on failure. + * + * The length is supposed to be significantly less that the buffer size. + */ + +YAML_DECLARE(int) +yaml_parser_update_buffer(yaml_parser_t *parser, size_t length) +{ + int first = 1; + + assert(parser->read_handler); /* Read handler must be set. */ + + /* If the EOF flag is set and the raw buffer is empty, do nothing. */ + + if (parser->eof && parser->raw_buffer.pointer == parser->raw_buffer.last) + return 1; + + /* Return if the buffer contains enough characters. */ + + if (parser->unread >= length) + return 1; + + /* Determine the input encoding if it is not known yet. */ + + if (!parser->encoding) { + if (!yaml_parser_determine_encoding(parser)) + return 0; + } + + /* Move the unread characters to the beginning of the buffer. */ + + if (parser->buffer.start < parser->buffer.pointer + && parser->buffer.pointer < parser->buffer.last) { + size_t size = parser->buffer.last - parser->buffer.pointer; + memmove(parser->buffer.start, parser->buffer.pointer, size); + parser->buffer.pointer = parser->buffer.start; + parser->buffer.last = parser->buffer.start + size; + } + else if (parser->buffer.pointer == parser->buffer.last) { + parser->buffer.pointer = parser->buffer.start; + parser->buffer.last = parser->buffer.start; + } + + /* Fill the buffer until it has enough characters. */ + + while (parser->unread < length) + { + /* Fill the raw buffer if necessary. */ + + if (!first || parser->raw_buffer.pointer == parser->raw_buffer.last) { + if (!yaml_parser_update_raw_buffer(parser)) return 0; + } + first = 0; + + /* Decode the raw buffer. */ + + while (parser->raw_buffer.pointer != parser->raw_buffer.last) + { + unsigned int value = 0, value2 = 0; + int incomplete = 0; + unsigned char octet; + unsigned int width = 0; + int low, high; + size_t k; + size_t raw_unread = parser->raw_buffer.last - parser->raw_buffer.pointer; + + /* Decode the next character. */ + + switch (parser->encoding) + { + case YAML_UTF8_ENCODING: + + /* + * Decode a UTF-8 character. Check RFC 3629 + * (http://www.ietf.org/rfc/rfc3629.txt) for more details. + * + * The following table (taken from the RFC) is used for + * decoding. + * + * Char. number range | UTF-8 octet sequence + * (hexadecimal) | (binary) + * --------------------+------------------------------------ + * 0000 0000-0000 007F | 0xxxxxxx + * 0000 0080-0000 07FF | 110xxxxx 10xxxxxx + * 0000 0800-0000 FFFF | 1110xxxx 10xxxxxx 10xxxxxx + * 0001 0000-0010 FFFF | 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx + * + * Additionally, the characters in the range 0xD800-0xDFFF + * are prohibited as they are reserved for use with UTF-16 + * surrogate pairs. + */ + + /* Determine the length of the UTF-8 sequence. */ + + octet = parser->raw_buffer.pointer[0]; + width = (octet & 0x80) == 0x00 ? 1 : + (octet & 0xE0) == 0xC0 ? 2 : + (octet & 0xF0) == 0xE0 ? 3 : + (octet & 0xF8) == 0xF0 ? 4 : 0; + + /* Check if the leading octet is valid. */ + + if (!width) + return yaml_parser_set_reader_error(parser, + "invalid leading UTF-8 octet", + parser->offset, octet); + + /* Check if the raw buffer contains an incomplete character. */ + + if (width > raw_unread) { + if (parser->eof) { + return yaml_parser_set_reader_error(parser, + "incomplete UTF-8 octet sequence", + parser->offset, -1); + } + incomplete = 1; + break; + } + + /* Decode the leading octet. */ + + value = (octet & 0x80) == 0x00 ? octet & 0x7F : + (octet & 0xE0) == 0xC0 ? octet & 0x1F : + (octet & 0xF0) == 0xE0 ? octet & 0x0F : + (octet & 0xF8) == 0xF0 ? octet & 0x07 : 0; + + /* Check and decode the trailing octets. */ + + for (k = 1; k < width; k ++) + { + octet = parser->raw_buffer.pointer[k]; + + /* Check if the octet is valid. */ + + if ((octet & 0xC0) != 0x80) + return yaml_parser_set_reader_error(parser, + "invalid trailing UTF-8 octet", + parser->offset+k, octet); + + /* Decode the octet. */ + + value = (value << 6) + (octet & 0x3F); + } + + /* Check the length of the sequence against the value. */ + + if (!((width == 1) || + (width == 2 && value >= 0x80) || + (width == 3 && value >= 0x800) || + (width == 4 && value >= 0x10000))) + return yaml_parser_set_reader_error(parser, + "invalid length of a UTF-8 sequence", + parser->offset, -1); + + /* Check the range of the value. */ + + if ((value >= 0xD800 && value <= 0xDFFF) || value > 0x10FFFF) + return yaml_parser_set_reader_error(parser, + "invalid Unicode character", + parser->offset, value); + + break; + + case YAML_UTF16LE_ENCODING: + case YAML_UTF16BE_ENCODING: + + low = (parser->encoding == YAML_UTF16LE_ENCODING ? 0 : 1); + high = (parser->encoding == YAML_UTF16LE_ENCODING ? 1 : 0); + + /* + * The UTF-16 encoding is not as simple as one might + * naively think. Check RFC 2781 + * (http://www.ietf.org/rfc/rfc2781.txt). + * + * Normally, two subsequent bytes describe a Unicode + * character. However a special technique (called a + * surrogate pair) is used for specifying character + * values larger than 0xFFFF. + * + * A surrogate pair consists of two pseudo-characters: + * high surrogate area (0xD800-0xDBFF) + * low surrogate area (0xDC00-0xDFFF) + * + * The following formulas are used for decoding + * and encoding characters using surrogate pairs: + * + * U = U' + 0x10000 (0x01 00 00 <= U <= 0x10 FF FF) + * U' = yyyyyyyyyyxxxxxxxxxx (0 <= U' <= 0x0F FF FF) + * W1 = 110110yyyyyyyyyy + * W2 = 110111xxxxxxxxxx + * + * where U is the character value, W1 is the high surrogate + * area, W2 is the low surrogate area. + */ + + /* Check for incomplete UTF-16 character. */ + + if (raw_unread < 2) { + if (parser->eof) { + return yaml_parser_set_reader_error(parser, + "incomplete UTF-16 character", + parser->offset, -1); + } + incomplete = 1; + break; + } + + /* Get the character. */ + + value = parser->raw_buffer.pointer[low] + + (parser->raw_buffer.pointer[high] << 8); + + /* Check for unexpected low surrogate area. */ + + if ((value & 0xFC00) == 0xDC00) + return yaml_parser_set_reader_error(parser, + "unexpected low surrogate area", + parser->offset, value); + + /* Check for a high surrogate area. */ + + if ((value & 0xFC00) == 0xD800) { + + width = 4; + + /* Check for incomplete surrogate pair. */ + + if (raw_unread < 4) { + if (parser->eof) { + return yaml_parser_set_reader_error(parser, + "incomplete UTF-16 surrogate pair", + parser->offset, -1); + } + incomplete = 1; + break; + } + + /* Get the next character. */ + + value2 = parser->raw_buffer.pointer[low+2] + + (parser->raw_buffer.pointer[high+2] << 8); + + /* Check for a low surrogate area. */ + + if ((value2 & 0xFC00) != 0xDC00) + return yaml_parser_set_reader_error(parser, + "expected low surrogate area", + parser->offset+2, value2); + + /* Generate the value of the surrogate pair. */ + + value = 0x10000 + ((value & 0x3FF) << 10) + (value2 & 0x3FF); + } + + else { + width = 2; + } + + break; + + default: + assert(1); /* Impossible. */ + } + + /* Check if the raw buffer contains enough bytes to form a character. */ + + if (incomplete) break; + + /* + * Check if the character is in the allowed range: + * #x9 | #xA | #xD | [#x20-#x7E] (8 bit) + * | #x85 | [#xA0-#xD7FF] | [#xE000-#xFFFD] (16 bit) + * | [#x10000-#x10FFFF] (32 bit) + */ + + if (! (value == 0x09 || value == 0x0A || value == 0x0D + || (value >= 0x20 && value <= 0x7E) + || (value == 0x85) || (value >= 0xA0 && value <= 0xD7FF) + || (value >= 0xE000 && value <= 0xFFFD) + || (value >= 0x10000 && value <= 0x10FFFF))) + return yaml_parser_set_reader_error(parser, + "control characters are not allowed", + parser->offset, value); + + /* Move the raw pointers. */ + + parser->raw_buffer.pointer += width; + parser->offset += width; + + /* Finally put the character into the buffer. */ + + /* 0000 0000-0000 007F -> 0xxxxxxx */ + if (value <= 0x7F) { + *(parser->buffer.last++) = value; + } + /* 0000 0080-0000 07FF -> 110xxxxx 10xxxxxx */ + else if (value <= 0x7FF) { + *(parser->buffer.last++) = 0xC0 + (value >> 6); + *(parser->buffer.last++) = 0x80 + (value & 0x3F); + } + /* 0000 0800-0000 FFFF -> 1110xxxx 10xxxxxx 10xxxxxx */ + else if (value <= 0xFFFF) { + *(parser->buffer.last++) = 0xE0 + (value >> 12); + *(parser->buffer.last++) = 0x80 + ((value >> 6) & 0x3F); + *(parser->buffer.last++) = 0x80 + (value & 0x3F); + } + /* 0001 0000-0010 FFFF -> 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx */ + else { + *(parser->buffer.last++) = 0xF0 + (value >> 18); + *(parser->buffer.last++) = 0x80 + ((value >> 12) & 0x3F); + *(parser->buffer.last++) = 0x80 + ((value >> 6) & 0x3F); + *(parser->buffer.last++) = 0x80 + (value & 0x3F); + } + + parser->unread ++; + } + + /* On EOF, put NUL into the buffer and return. */ + + if (parser->eof) { + *(parser->buffer.last++) = '\0'; + parser->unread ++; + return 1; + } + + } + + if (parser->offset >= PTRDIFF_MAX) + return yaml_parser_set_reader_error(parser, "input is too long", + PTRDIFF_MAX, -1); + + return 1; +} + diff --git a/web/server/h2o/libh2o/deps/yaml/src/scanner.c b/web/server/h2o/libh2o/deps/yaml/src/scanner.c new file mode 100644 index 00000000..88d4fa5d --- /dev/null +++ b/web/server/h2o/libh2o/deps/yaml/src/scanner.c @@ -0,0 +1,3583 @@ + +/* + * Introduction + * ************ + * + * The following notes assume that you are familiar with the YAML specification + * (http://yaml.org/spec/cvs/current.html). We mostly follow it, although in + * some cases we are less restrictive that it requires. + * + * The process of transforming a YAML stream into a sequence of events is + * divided on two steps: Scanning and Parsing. + * + * The Scanner transforms the input stream into a sequence of tokens, while the + * parser transform the sequence of tokens produced by the Scanner into a + * sequence of parsing events. + * + * The Scanner is rather clever and complicated. The Parser, on the contrary, + * is a straightforward implementation of a recursive-descendant parser (or, + * LL(1) parser, as it is usually called). + * + * Actually there are two issues of Scanning that might be called "clever", the + * rest is quite straightforward. The issues are "block collection start" and + * "simple keys". Both issues are explained below in details. + * + * Here the Scanning step is explained and implemented. We start with the list + * of all the tokens produced by the Scanner together with short descriptions. + * + * Now, tokens: + * + * STREAM-START(encoding) # The stream start. + * STREAM-END # The stream end. + * VERSION-DIRECTIVE(major,minor) # The '%YAML' directive. + * TAG-DIRECTIVE(handle,prefix) # The '%TAG' directive. + * DOCUMENT-START # '---' + * DOCUMENT-END # '...' + * BLOCK-SEQUENCE-START # Indentation increase denoting a block + * BLOCK-MAPPING-START # sequence or a block mapping. + * BLOCK-END # Indentation decrease. + * FLOW-SEQUENCE-START # '[' + * FLOW-SEQUENCE-END # ']' + * BLOCK-SEQUENCE-START # '{' + * BLOCK-SEQUENCE-END # '}' + * BLOCK-ENTRY # '-' + * FLOW-ENTRY # ',' + * KEY # '?' or nothing (simple keys). + * VALUE # ':' + * ALIAS(anchor) # '*anchor' + * ANCHOR(anchor) # '&anchor' + * TAG(handle,suffix) # '!handle!suffix' + * SCALAR(value,style) # A scalar. + * + * The following two tokens are "virtual" tokens denoting the beginning and the + * end of the stream: + * + * STREAM-START(encoding) + * STREAM-END + * + * We pass the information about the input stream encoding with the + * STREAM-START token. + * + * The next two tokens are responsible for tags: + * + * VERSION-DIRECTIVE(major,minor) + * TAG-DIRECTIVE(handle,prefix) + * + * Example: + * + * %YAML 1.1 + * %TAG ! !foo + * %TAG !yaml! tag:yaml.org,2002: + * --- + * + * The correspoding sequence of tokens: + * + * STREAM-START(utf-8) + * VERSION-DIRECTIVE(1,1) + * TAG-DIRECTIVE("!","!foo") + * TAG-DIRECTIVE("!yaml","tag:yaml.org,2002:") + * DOCUMENT-START + * STREAM-END + * + * Note that the VERSION-DIRECTIVE and TAG-DIRECTIVE tokens occupy a whole + * line. + * + * The document start and end indicators are represented by: + * + * DOCUMENT-START + * DOCUMENT-END + * + * Note that if a YAML stream contains an implicit document (without '---' + * and '...' indicators), no DOCUMENT-START and DOCUMENT-END tokens will be + * produced. + * + * In the following examples, we present whole documents together with the + * produced tokens. + * + * 1. An implicit document: + * + * 'a scalar' + * + * Tokens: + * + * STREAM-START(utf-8) + * SCALAR("a scalar",single-quoted) + * STREAM-END + * + * 2. An explicit document: + * + * --- + * 'a scalar' + * ... + * + * Tokens: + * + * STREAM-START(utf-8) + * DOCUMENT-START + * SCALAR("a scalar",single-quoted) + * DOCUMENT-END + * STREAM-END + * + * 3. Several documents in a stream: + * + * 'a scalar' + * --- + * 'another scalar' + * --- + * 'yet another scalar' + * + * Tokens: + * + * STREAM-START(utf-8) + * SCALAR("a scalar",single-quoted) + * DOCUMENT-START + * SCALAR("another scalar",single-quoted) + * DOCUMENT-START + * SCALAR("yet another scalar",single-quoted) + * STREAM-END + * + * We have already introduced the SCALAR token above. The following tokens are + * used to describe aliases, anchors, tag, and scalars: + * + * ALIAS(anchor) + * ANCHOR(anchor) + * TAG(handle,suffix) + * SCALAR(value,style) + * + * The following series of examples illustrate the usage of these tokens: + * + * 1. A recursive sequence: + * + * &A [ *A ] + * + * Tokens: + * + * STREAM-START(utf-8) + * ANCHOR("A") + * FLOW-SEQUENCE-START + * ALIAS("A") + * FLOW-SEQUENCE-END + * STREAM-END + * + * 2. A tagged scalar: + * + * !!float "3.14" # A good approximation. + * + * Tokens: + * + * STREAM-START(utf-8) + * TAG("!!","float") + * SCALAR("3.14",double-quoted) + * STREAM-END + * + * 3. Various scalar styles: + * + * --- # Implicit empty plain scalars do not produce tokens. + * --- a plain scalar + * --- 'a single-quoted scalar' + * --- "a double-quoted scalar" + * --- |- + * a literal scalar + * --- >- + * a folded + * scalar + * + * Tokens: + * + * STREAM-START(utf-8) + * DOCUMENT-START + * DOCUMENT-START + * SCALAR("a plain scalar",plain) + * DOCUMENT-START + * SCALAR("a single-quoted scalar",single-quoted) + * DOCUMENT-START + * SCALAR("a double-quoted scalar",double-quoted) + * DOCUMENT-START + * SCALAR("a literal scalar",literal) + * DOCUMENT-START + * SCALAR("a folded scalar",folded) + * STREAM-END + * + * Now it's time to review collection-related tokens. We will start with + * flow collections: + * + * FLOW-SEQUENCE-START + * FLOW-SEQUENCE-END + * FLOW-MAPPING-START + * FLOW-MAPPING-END + * FLOW-ENTRY + * KEY + * VALUE + * + * The tokens FLOW-SEQUENCE-START, FLOW-SEQUENCE-END, FLOW-MAPPING-START, and + * FLOW-MAPPING-END represent the indicators '[', ']', '{', and '}' + * correspondingly. FLOW-ENTRY represent the ',' indicator. Finally the + * indicators '?' and ':', which are used for denoting mapping keys and values, + * are represented by the KEY and VALUE tokens. + * + * The following examples show flow collections: + * + * 1. A flow sequence: + * + * [item 1, item 2, item 3] + * + * Tokens: + * + * STREAM-START(utf-8) + * FLOW-SEQUENCE-START + * SCALAR("item 1",plain) + * FLOW-ENTRY + * SCALAR("item 2",plain) + * FLOW-ENTRY + * SCALAR("item 3",plain) + * FLOW-SEQUENCE-END + * STREAM-END + * + * 2. A flow mapping: + * + * { + * a simple key: a value, # Note that the KEY token is produced. + * ? a complex key: another value, + * } + * + * Tokens: + * + * STREAM-START(utf-8) + * FLOW-MAPPING-START + * KEY + * SCALAR("a simple key",plain) + * VALUE + * SCALAR("a value",plain) + * FLOW-ENTRY + * KEY + * SCALAR("a complex key",plain) + * VALUE + * SCALAR("another value",plain) + * FLOW-ENTRY + * FLOW-MAPPING-END + * STREAM-END + * + * A simple key is a key which is not denoted by the '?' indicator. Note that + * the Scanner still produce the KEY token whenever it encounters a simple key. + * + * For scanning block collections, the following tokens are used (note that we + * repeat KEY and VALUE here): + * + * BLOCK-SEQUENCE-START + * BLOCK-MAPPING-START + * BLOCK-END + * BLOCK-ENTRY + * KEY + * VALUE + * + * The tokens BLOCK-SEQUENCE-START and BLOCK-MAPPING-START denote indentation + * increase that precedes a block collection (cf. the INDENT token in Python). + * The token BLOCK-END denote indentation decrease that ends a block collection + * (cf. the DEDENT token in Python). However YAML has some syntax pecularities + * that makes detections of these tokens more complex. + * + * The tokens BLOCK-ENTRY, KEY, and VALUE are used to represent the indicators + * '-', '?', and ':' correspondingly. + * + * The following examples show how the tokens BLOCK-SEQUENCE-START, + * BLOCK-MAPPING-START, and BLOCK-END are emitted by the Scanner: + * + * 1. Block sequences: + * + * - item 1 + * - item 2 + * - + * - item 3.1 + * - item 3.2 + * - + * key 1: value 1 + * key 2: value 2 + * + * Tokens: + * + * STREAM-START(utf-8) + * BLOCK-SEQUENCE-START + * BLOCK-ENTRY + * SCALAR("item 1",plain) + * BLOCK-ENTRY + * SCALAR("item 2",plain) + * BLOCK-ENTRY + * BLOCK-SEQUENCE-START + * BLOCK-ENTRY + * SCALAR("item 3.1",plain) + * BLOCK-ENTRY + * SCALAR("item 3.2",plain) + * BLOCK-END + * BLOCK-ENTRY + * BLOCK-MAPPING-START + * KEY + * SCALAR("key 1",plain) + * VALUE + * SCALAR("value 1",plain) + * KEY + * SCALAR("key 2",plain) + * VALUE + * SCALAR("value 2",plain) + * BLOCK-END + * BLOCK-END + * STREAM-END + * + * 2. Block mappings: + * + * a simple key: a value # The KEY token is produced here. + * ? a complex key + * : another value + * a mapping: + * key 1: value 1 + * key 2: value 2 + * a sequence: + * - item 1 + * - item 2 + * + * Tokens: + * + * STREAM-START(utf-8) + * BLOCK-MAPPING-START + * KEY + * SCALAR("a simple key",plain) + * VALUE + * SCALAR("a value",plain) + * KEY + * SCALAR("a complex key",plain) + * VALUE + * SCALAR("another value",plain) + * KEY + * SCALAR("a mapping",plain) + * BLOCK-MAPPING-START + * KEY + * SCALAR("key 1",plain) + * VALUE + * SCALAR("value 1",plain) + * KEY + * SCALAR("key 2",plain) + * VALUE + * SCALAR("value 2",plain) + * BLOCK-END + * KEY + * SCALAR("a sequence",plain) + * VALUE + * BLOCK-SEQUENCE-START + * BLOCK-ENTRY + * SCALAR("item 1",plain) + * BLOCK-ENTRY + * SCALAR("item 2",plain) + * BLOCK-END + * BLOCK-END + * STREAM-END + * + * YAML does not always require to start a new block collection from a new + * line. If the current line contains only '-', '?', and ':' indicators, a new + * block collection may start at the current line. The following examples + * illustrate this case: + * + * 1. Collections in a sequence: + * + * - - item 1 + * - item 2 + * - key 1: value 1 + * key 2: value 2 + * - ? complex key + * : complex value + * + * Tokens: + * + * STREAM-START(utf-8) + * BLOCK-SEQUENCE-START + * BLOCK-ENTRY + * BLOCK-SEQUENCE-START + * BLOCK-ENTRY + * SCALAR("item 1",plain) + * BLOCK-ENTRY + * SCALAR("item 2",plain) + * BLOCK-END + * BLOCK-ENTRY + * BLOCK-MAPPING-START + * KEY + * SCALAR("key 1",plain) + * VALUE + * SCALAR("value 1",plain) + * KEY + * SCALAR("key 2",plain) + * VALUE + * SCALAR("value 2",plain) + * BLOCK-END + * BLOCK-ENTRY + * BLOCK-MAPPING-START + * KEY + * SCALAR("complex key") + * VALUE + * SCALAR("complex value") + * BLOCK-END + * BLOCK-END + * STREAM-END + * + * 2. Collections in a mapping: + * + * ? a sequence + * : - item 1 + * - item 2 + * ? a mapping + * : key 1: value 1 + * key 2: value 2 + * + * Tokens: + * + * STREAM-START(utf-8) + * BLOCK-MAPPING-START + * KEY + * SCALAR("a sequence",plain) + * VALUE + * BLOCK-SEQUENCE-START + * BLOCK-ENTRY + * SCALAR("item 1",plain) + * BLOCK-ENTRY + * SCALAR("item 2",plain) + * BLOCK-END + * KEY + * SCALAR("a mapping",plain) + * VALUE + * BLOCK-MAPPING-START + * KEY + * SCALAR("key 1",plain) + * VALUE + * SCALAR("value 1",plain) + * KEY + * SCALAR("key 2",plain) + * VALUE + * SCALAR("value 2",plain) + * BLOCK-END + * BLOCK-END + * STREAM-END + * + * YAML also permits non-indented sequences if they are included into a block + * mapping. In this case, the token BLOCK-SEQUENCE-START is not produced: + * + * key: + * - item 1 # BLOCK-SEQUENCE-START is NOT produced here. + * - item 2 + * + * Tokens: + * + * STREAM-START(utf-8) + * BLOCK-MAPPING-START + * KEY + * SCALAR("key",plain) + * VALUE + * BLOCK-ENTRY + * SCALAR("item 1",plain) + * BLOCK-ENTRY + * SCALAR("item 2",plain) + * BLOCK-END + */ + +#include "yaml_private.h" + +/* + * Ensure that the buffer contains the required number of characters. + * Return 1 on success, 0 on failure (reader error or memory error). + */ + +#define CACHE(parser,length) \ + (parser->unread >= (length) \ + ? 1 \ + : yaml_parser_update_buffer(parser, (length))) + +/* + * Advance the buffer pointer. + */ + +#define SKIP(parser) \ + (parser->mark.index ++, \ + parser->mark.column ++, \ + parser->unread --, \ + parser->buffer.pointer += WIDTH(parser->buffer)) + +#define SKIP_LINE(parser) \ + (IS_CRLF(parser->buffer) ? \ + (parser->mark.index += 2, \ + parser->mark.column = 0, \ + parser->mark.line ++, \ + parser->unread -= 2, \ + parser->buffer.pointer += 2) : \ + IS_BREAK(parser->buffer) ? \ + (parser->mark.index ++, \ + parser->mark.column = 0, \ + parser->mark.line ++, \ + parser->unread --, \ + parser->buffer.pointer += WIDTH(parser->buffer)) : 0) + +/* + * Copy a character to a string buffer and advance pointers. + */ + +#define READ(parser,string) \ + (STRING_EXTEND(parser,string) ? \ + (COPY(string,parser->buffer), \ + parser->mark.index ++, \ + parser->mark.column ++, \ + parser->unread --, \ + 1) : 0) + +/* + * Copy a line break character to a string buffer and advance pointers. + */ + +#define READ_LINE(parser,string) \ + (STRING_EXTEND(parser,string) ? \ + (((CHECK_AT(parser->buffer,'\r',0) \ + && CHECK_AT(parser->buffer,'\n',1)) ? /* CR LF -> LF */ \ + (*((string).pointer++) = (yaml_char_t) '\n', \ + parser->buffer.pointer += 2, \ + parser->mark.index += 2, \ + parser->mark.column = 0, \ + parser->mark.line ++, \ + parser->unread -= 2) : \ + (CHECK_AT(parser->buffer,'\r',0) \ + || CHECK_AT(parser->buffer,'\n',0)) ? /* CR|LF -> LF */ \ + (*((string).pointer++) = (yaml_char_t) '\n', \ + parser->buffer.pointer ++, \ + parser->mark.index ++, \ + parser->mark.column = 0, \ + parser->mark.line ++, \ + parser->unread --) : \ + (CHECK_AT(parser->buffer,'\xC2',0) \ + && CHECK_AT(parser->buffer,'\x85',1)) ? /* NEL -> LF */ \ + (*((string).pointer++) = (yaml_char_t) '\n', \ + parser->buffer.pointer += 2, \ + parser->mark.index ++, \ + parser->mark.column = 0, \ + parser->mark.line ++, \ + parser->unread --) : \ + (CHECK_AT(parser->buffer,'\xE2',0) && \ + CHECK_AT(parser->buffer,'\x80',1) && \ + (CHECK_AT(parser->buffer,'\xA8',2) || \ + CHECK_AT(parser->buffer,'\xA9',2))) ? /* LS|PS -> LS|PS */ \ + (*((string).pointer++) = *(parser->buffer.pointer++), \ + *((string).pointer++) = *(parser->buffer.pointer++), \ + *((string).pointer++) = *(parser->buffer.pointer++), \ + parser->mark.index ++, \ + parser->mark.column = 0, \ + parser->mark.line ++, \ + parser->unread --) : 0), \ + 1) : 0) + +/* + * Public API declarations. + */ + +YAML_DECLARE(int) +yaml_parser_scan(yaml_parser_t *parser, yaml_token_t *token); + +/* + * Error handling. + */ + +static int +yaml_parser_set_scanner_error(yaml_parser_t *parser, const char *context, + yaml_mark_t context_mark, const char *problem); + +/* + * High-level token API. + */ + +YAML_DECLARE(int) +yaml_parser_fetch_more_tokens(yaml_parser_t *parser); + +static int +yaml_parser_fetch_next_token(yaml_parser_t *parser); + +/* + * Potential simple keys. + */ + +static int +yaml_parser_stale_simple_keys(yaml_parser_t *parser); + +static int +yaml_parser_save_simple_key(yaml_parser_t *parser); + +static int +yaml_parser_remove_simple_key(yaml_parser_t *parser); + +static int +yaml_parser_increase_flow_level(yaml_parser_t *parser); + +static int +yaml_parser_decrease_flow_level(yaml_parser_t *parser); + +/* + * Indentation treatment. + */ + +static int +yaml_parser_roll_indent(yaml_parser_t *parser, ptrdiff_t column, + ptrdiff_t number, yaml_token_type_t type, yaml_mark_t mark); + +static int +yaml_parser_unroll_indent(yaml_parser_t *parser, ptrdiff_t column); + +/* + * Token fetchers. + */ + +static int +yaml_parser_fetch_stream_start(yaml_parser_t *parser); + +static int +yaml_parser_fetch_stream_end(yaml_parser_t *parser); + +static int +yaml_parser_fetch_directive(yaml_parser_t *parser); + +static int +yaml_parser_fetch_document_indicator(yaml_parser_t *parser, + yaml_token_type_t type); + +static int +yaml_parser_fetch_flow_collection_start(yaml_parser_t *parser, + yaml_token_type_t type); + +static int +yaml_parser_fetch_flow_collection_end(yaml_parser_t *parser, + yaml_token_type_t type); + +static int +yaml_parser_fetch_flow_entry(yaml_parser_t *parser); + +static int +yaml_parser_fetch_block_entry(yaml_parser_t *parser); + +static int +yaml_parser_fetch_key(yaml_parser_t *parser); + +static int +yaml_parser_fetch_value(yaml_parser_t *parser); + +static int +yaml_parser_fetch_anchor(yaml_parser_t *parser, yaml_token_type_t type); + +static int +yaml_parser_fetch_tag(yaml_parser_t *parser); + +static int +yaml_parser_fetch_block_scalar(yaml_parser_t *parser, int literal); + +static int +yaml_parser_fetch_flow_scalar(yaml_parser_t *parser, int single); + +static int +yaml_parser_fetch_plain_scalar(yaml_parser_t *parser); + +/* + * Token scanners. + */ + +static int +yaml_parser_scan_to_next_token(yaml_parser_t *parser); + +static int +yaml_parser_scan_directive(yaml_parser_t *parser, yaml_token_t *token); + +static int +yaml_parser_scan_directive_name(yaml_parser_t *parser, + yaml_mark_t start_mark, yaml_char_t **name); + +static int +yaml_parser_scan_version_directive_value(yaml_parser_t *parser, + yaml_mark_t start_mark, int *major, int *minor); + +static int +yaml_parser_scan_version_directive_number(yaml_parser_t *parser, + yaml_mark_t start_mark, int *number); + +static int +yaml_parser_scan_tag_directive_value(yaml_parser_t *parser, + yaml_mark_t mark, yaml_char_t **handle, yaml_char_t **prefix); + +static int +yaml_parser_scan_anchor(yaml_parser_t *parser, yaml_token_t *token, + yaml_token_type_t type); + +static int +yaml_parser_scan_tag(yaml_parser_t *parser, yaml_token_t *token); + +static int +yaml_parser_scan_tag_handle(yaml_parser_t *parser, int directive, + yaml_mark_t start_mark, yaml_char_t **handle); + +static int +yaml_parser_scan_tag_uri(yaml_parser_t *parser, int directive, + yaml_char_t *head, yaml_mark_t start_mark, yaml_char_t **uri); + +static int +yaml_parser_scan_uri_escapes(yaml_parser_t *parser, int directive, + yaml_mark_t start_mark, yaml_string_t *string); + +static int +yaml_parser_scan_block_scalar(yaml_parser_t *parser, yaml_token_t *token, + int literal); + +static int +yaml_parser_scan_block_scalar_breaks(yaml_parser_t *parser, + int *indent, yaml_string_t *breaks, + yaml_mark_t start_mark, yaml_mark_t *end_mark); + +static int +yaml_parser_scan_flow_scalar(yaml_parser_t *parser, yaml_token_t *token, + int single); + +static int +yaml_parser_scan_plain_scalar(yaml_parser_t *parser, yaml_token_t *token); + +/* + * Get the next token. + */ + +YAML_DECLARE(int) +yaml_parser_scan(yaml_parser_t *parser, yaml_token_t *token) +{ + assert(parser); /* Non-NULL parser object is expected. */ + assert(token); /* Non-NULL token object is expected. */ + + /* Erase the token object. */ + + memset(token, 0, sizeof(yaml_token_t)); + + /* No tokens after STREAM-END or error. */ + + if (parser->stream_end_produced || parser->error) { + return 1; + } + + /* Ensure that the tokens queue contains enough tokens. */ + + if (!parser->token_available) { + if (!yaml_parser_fetch_more_tokens(parser)) + return 0; + } + + /* Fetch the next token from the queue. */ + + *token = DEQUEUE(parser, parser->tokens); + parser->token_available = 0; + parser->tokens_parsed ++; + + if (token->type == YAML_STREAM_END_TOKEN) { + parser->stream_end_produced = 1; + } + + return 1; +} + +/* + * Set the scanner error and return 0. + */ + +static int +yaml_parser_set_scanner_error(yaml_parser_t *parser, const char *context, + yaml_mark_t context_mark, const char *problem) +{ + parser->error = YAML_SCANNER_ERROR; + parser->context = context; + parser->context_mark = context_mark; + parser->problem = problem; + parser->problem_mark = parser->mark; + + return 0; +} + +/* + * Ensure that the tokens queue contains at least one token which can be + * returned to the Parser. + */ + +YAML_DECLARE(int) +yaml_parser_fetch_more_tokens(yaml_parser_t *parser) +{ + int need_more_tokens; + + /* While we need more tokens to fetch, do it. */ + + while (1) + { + /* + * Check if we really need to fetch more tokens. + */ + + need_more_tokens = 0; + + if (parser->tokens.head == parser->tokens.tail) + { + /* Queue is empty. */ + + need_more_tokens = 1; + } + else + { + yaml_simple_key_t *simple_key; + + /* Check if any potential simple key may occupy the head position. */ + + if (!yaml_parser_stale_simple_keys(parser)) + return 0; + + for (simple_key = parser->simple_keys.start; + simple_key != parser->simple_keys.top; simple_key++) { + if (simple_key->possible + && simple_key->token_number == parser->tokens_parsed) { + need_more_tokens = 1; + break; + } + } + } + + /* We are finished. */ + + if (!need_more_tokens) + break; + + /* Fetch the next token. */ + + if (!yaml_parser_fetch_next_token(parser)) + return 0; + } + + parser->token_available = 1; + + return 1; +} + +/* + * The dispatcher for token fetchers. + */ + +static int +yaml_parser_fetch_next_token(yaml_parser_t *parser) +{ + /* Ensure that the buffer is initialized. */ + + if (!CACHE(parser, 1)) + return 0; + + /* Check if we just started scanning. Fetch STREAM-START then. */ + + if (!parser->stream_start_produced) + return yaml_parser_fetch_stream_start(parser); + + /* Eat whitespaces and comments until we reach the next token. */ + + if (!yaml_parser_scan_to_next_token(parser)) + return 0; + + /* Remove obsolete potential simple keys. */ + + if (!yaml_parser_stale_simple_keys(parser)) + return 0; + + /* Check the indentation level against the current column. */ + + if (!yaml_parser_unroll_indent(parser, parser->mark.column)) + return 0; + + /* + * Ensure that the buffer contains at least 4 characters. 4 is the length + * of the longest indicators ('--- ' and '... '). + */ + + if (!CACHE(parser, 4)) + return 0; + + /* Is it the end of the stream? */ + + if (IS_Z(parser->buffer)) + return yaml_parser_fetch_stream_end(parser); + + /* Is it a directive? */ + + if (parser->mark.column == 0 && CHECK(parser->buffer, '%')) + return yaml_parser_fetch_directive(parser); + + /* Is it the document start indicator? */ + + if (parser->mark.column == 0 + && CHECK_AT(parser->buffer, '-', 0) + && CHECK_AT(parser->buffer, '-', 1) + && CHECK_AT(parser->buffer, '-', 2) + && IS_BLANKZ_AT(parser->buffer, 3)) + return yaml_parser_fetch_document_indicator(parser, + YAML_DOCUMENT_START_TOKEN); + + /* Is it the document end indicator? */ + + if (parser->mark.column == 0 + && CHECK_AT(parser->buffer, '.', 0) + && CHECK_AT(parser->buffer, '.', 1) + && CHECK_AT(parser->buffer, '.', 2) + && IS_BLANKZ_AT(parser->buffer, 3)) + return yaml_parser_fetch_document_indicator(parser, + YAML_DOCUMENT_END_TOKEN); + + /* Is it the flow sequence start indicator? */ + + if (CHECK(parser->buffer, '[')) + return yaml_parser_fetch_flow_collection_start(parser, + YAML_FLOW_SEQUENCE_START_TOKEN); + + /* Is it the flow mapping start indicator? */ + + if (CHECK(parser->buffer, '{')) + return yaml_parser_fetch_flow_collection_start(parser, + YAML_FLOW_MAPPING_START_TOKEN); + + /* Is it the flow sequence end indicator? */ + + if (CHECK(parser->buffer, ']')) + return yaml_parser_fetch_flow_collection_end(parser, + YAML_FLOW_SEQUENCE_END_TOKEN); + + /* Is it the flow mapping end indicator? */ + + if (CHECK(parser->buffer, '}')) + return yaml_parser_fetch_flow_collection_end(parser, + YAML_FLOW_MAPPING_END_TOKEN); + + /* Is it the flow entry indicator? */ + + if (CHECK(parser->buffer, ',')) + return yaml_parser_fetch_flow_entry(parser); + + /* Is it the block entry indicator? */ + + if (CHECK(parser->buffer, '-') && IS_BLANKZ_AT(parser->buffer, 1)) + return yaml_parser_fetch_block_entry(parser); + + /* Is it the key indicator? */ + + if (CHECK(parser->buffer, '?') + && (parser->flow_level || IS_BLANKZ_AT(parser->buffer, 1))) + return yaml_parser_fetch_key(parser); + + /* Is it the value indicator? */ + + if (CHECK(parser->buffer, ':') + && (parser->flow_level || IS_BLANKZ_AT(parser->buffer, 1))) + return yaml_parser_fetch_value(parser); + + /* Is it an alias? */ + + if (CHECK(parser->buffer, '*')) + return yaml_parser_fetch_anchor(parser, YAML_ALIAS_TOKEN); + + /* Is it an anchor? */ + + if (CHECK(parser->buffer, '&')) + return yaml_parser_fetch_anchor(parser, YAML_ANCHOR_TOKEN); + + /* Is it a tag? */ + + if (CHECK(parser->buffer, '!')) + return yaml_parser_fetch_tag(parser); + + /* Is it a literal scalar? */ + + if (CHECK(parser->buffer, '|') && !parser->flow_level) + return yaml_parser_fetch_block_scalar(parser, 1); + + /* Is it a folded scalar? */ + + if (CHECK(parser->buffer, '>') && !parser->flow_level) + return yaml_parser_fetch_block_scalar(parser, 0); + + /* Is it a single-quoted scalar? */ + + if (CHECK(parser->buffer, '\'')) + return yaml_parser_fetch_flow_scalar(parser, 1); + + /* Is it a double-quoted scalar? */ + + if (CHECK(parser->buffer, '"')) + return yaml_parser_fetch_flow_scalar(parser, 0); + + /* + * Is it a plain scalar? + * + * A plain scalar may start with any non-blank characters except + * + * '-', '?', ':', ',', '[', ']', '{', '}', + * '#', '&', '*', '!', '|', '>', '\'', '\"', + * '%', '@', '`'. + * + * In the block context (and, for the '-' indicator, in the flow context + * too), it may also start with the characters + * + * '-', '?', ':' + * + * if it is followed by a non-space character. + * + * The last rule is more restrictive than the specification requires. + */ + + if (!(IS_BLANKZ(parser->buffer) || CHECK(parser->buffer, '-') + || CHECK(parser->buffer, '?') || CHECK(parser->buffer, ':') + || CHECK(parser->buffer, ',') || CHECK(parser->buffer, '[') + || CHECK(parser->buffer, ']') || CHECK(parser->buffer, '{') + || CHECK(parser->buffer, '}') || CHECK(parser->buffer, '#') + || CHECK(parser->buffer, '&') || CHECK(parser->buffer, '*') + || CHECK(parser->buffer, '!') || CHECK(parser->buffer, '|') + || CHECK(parser->buffer, '>') || CHECK(parser->buffer, '\'') + || CHECK(parser->buffer, '"') || CHECK(parser->buffer, '%') + || CHECK(parser->buffer, '@') || CHECK(parser->buffer, '`')) || + (CHECK(parser->buffer, '-') && !IS_BLANK_AT(parser->buffer, 1)) || + (!parser->flow_level && + (CHECK(parser->buffer, '?') || CHECK(parser->buffer, ':')) + && !IS_BLANKZ_AT(parser->buffer, 1))) + return yaml_parser_fetch_plain_scalar(parser); + + /* + * If we don't determine the token type so far, it is an error. + */ + + return yaml_parser_set_scanner_error(parser, + "while scanning for the next token", parser->mark, + "found character that cannot start any token"); +} + +/* + * Check the list of potential simple keys and remove the positions that + * cannot contain simple keys anymore. + */ + +static int +yaml_parser_stale_simple_keys(yaml_parser_t *parser) +{ + yaml_simple_key_t *simple_key; + + /* Check for a potential simple key for each flow level. */ + + for (simple_key = parser->simple_keys.start; + simple_key != parser->simple_keys.top; simple_key ++) + { + /* + * The specification requires that a simple key + * + * - is limited to a single line, + * - is shorter than 1024 characters. + */ + + if (simple_key->possible + && (simple_key->mark.line < parser->mark.line + || simple_key->mark.index+1024 < parser->mark.index)) { + + /* Check if the potential simple key to be removed is required. */ + + if (simple_key->required) { + return yaml_parser_set_scanner_error(parser, + "while scanning a simple key", simple_key->mark, + "could not find expected ':'"); + } + + simple_key->possible = 0; + } + } + + return 1; +} + +/* + * Check if a simple key may start at the current position and add it if + * needed. + */ + +static int +yaml_parser_save_simple_key(yaml_parser_t *parser) +{ + /* + * A simple key is required at the current position if the scanner is in + * the block context and the current column coincides with the indentation + * level. + */ + + int required = (!parser->flow_level + && parser->indent == (ptrdiff_t)parser->mark.column); + + /* + * A simple key is required only when it is the first token in the current + * line. Therefore it is always allowed. But we add a check anyway. + */ + + assert(parser->simple_key_allowed || !required); /* Impossible. */ + + /* + * If the current position may start a simple key, save it. + */ + + if (parser->simple_key_allowed) + { + yaml_simple_key_t simple_key; + simple_key.possible = 1; + simple_key.required = required; + simple_key.token_number = + parser->tokens_parsed + (parser->tokens.tail - parser->tokens.head); + simple_key.mark = parser->mark; + + if (!yaml_parser_remove_simple_key(parser)) return 0; + + *(parser->simple_keys.top-1) = simple_key; + } + + return 1; +} + +/* + * Remove a potential simple key at the current flow level. + */ + +static int +yaml_parser_remove_simple_key(yaml_parser_t *parser) +{ + yaml_simple_key_t *simple_key = parser->simple_keys.top-1; + + if (simple_key->possible) + { + /* If the key is required, it is an error. */ + + if (simple_key->required) { + return yaml_parser_set_scanner_error(parser, + "while scanning a simple key", simple_key->mark, + "could not find expected ':'"); + } + } + + /* Remove the key from the stack. */ + + simple_key->possible = 0; + + return 1; +} + +/* + * Increase the flow level and resize the simple key list if needed. + */ + +static int +yaml_parser_increase_flow_level(yaml_parser_t *parser) +{ + yaml_simple_key_t empty_simple_key = { 0, 0, 0, { 0, 0, 0 } }; + + /* Reset the simple key on the next level. */ + + if (!PUSH(parser, parser->simple_keys, empty_simple_key)) + return 0; + + /* Increase the flow level. */ + + if (parser->flow_level == INT_MAX) { + parser->error = YAML_MEMORY_ERROR; + return 0; + } + + parser->flow_level++; + + return 1; +} + +/* + * Decrease the flow level. + */ + +static int +yaml_parser_decrease_flow_level(yaml_parser_t *parser) +{ + yaml_simple_key_t dummy_key; /* Used to eliminate a compiler warning. */ + + if (parser->flow_level) { + parser->flow_level --; + dummy_key = POP(parser, parser->simple_keys); + } + + return 1; +} + +/* + * Push the current indentation level to the stack and set the new level + * the current column is greater than the indentation level. In this case, + * append or insert the specified token into the token queue. + * + */ + +static int +yaml_parser_roll_indent(yaml_parser_t *parser, ptrdiff_t column, + ptrdiff_t number, yaml_token_type_t type, yaml_mark_t mark) +{ + yaml_token_t token; + + /* In the flow context, do nothing. */ + + if (parser->flow_level) + return 1; + + if (parser->indent < column) + { + /* + * Push the current indentation level to the stack and set the new + * indentation level. + */ + + if (!PUSH(parser, parser->indents, parser->indent)) + return 0; + + if (column > INT_MAX) { + parser->error = YAML_MEMORY_ERROR; + return 0; + } + + parser->indent = column; + + /* Create a token and insert it into the queue. */ + + TOKEN_INIT(token, type, mark, mark); + + if (number == -1) { + if (!ENQUEUE(parser, parser->tokens, token)) + return 0; + } + else { + if (!QUEUE_INSERT(parser, + parser->tokens, number - parser->tokens_parsed, token)) + return 0; + } + } + + return 1; +} + +/* + * Pop indentation levels from the indents stack until the current level + * becomes less or equal to the column. For each intendation level, append + * the BLOCK-END token. + */ + + +static int +yaml_parser_unroll_indent(yaml_parser_t *parser, ptrdiff_t column) +{ + yaml_token_t token; + + /* In the flow context, do nothing. */ + + if (parser->flow_level) + return 1; + + /* Loop through the intendation levels in the stack. */ + + while (parser->indent > column) + { + /* Create a token and append it to the queue. */ + + TOKEN_INIT(token, YAML_BLOCK_END_TOKEN, parser->mark, parser->mark); + + if (!ENQUEUE(parser, parser->tokens, token)) + return 0; + + /* Pop the indentation level. */ + + parser->indent = POP(parser, parser->indents); + } + + return 1; +} + +/* + * Initialize the scanner and produce the STREAM-START token. + */ + +static int +yaml_parser_fetch_stream_start(yaml_parser_t *parser) +{ + yaml_simple_key_t simple_key = { 0, 0, 0, { 0, 0, 0 } }; + yaml_token_t token; + + /* Set the initial indentation. */ + + parser->indent = -1; + + /* Initialize the simple key stack. */ + + if (!PUSH(parser, parser->simple_keys, simple_key)) + return 0; + + /* A simple key is allowed at the beginning of the stream. */ + + parser->simple_key_allowed = 1; + + /* We have started. */ + + parser->stream_start_produced = 1; + + /* Create the STREAM-START token and append it to the queue. */ + + STREAM_START_TOKEN_INIT(token, parser->encoding, + parser->mark, parser->mark); + + if (!ENQUEUE(parser, parser->tokens, token)) + return 0; + + return 1; +} + +/* + * Produce the STREAM-END token and shut down the scanner. + */ + +static int +yaml_parser_fetch_stream_end(yaml_parser_t *parser) +{ + yaml_token_t token; + + /* Force new line. */ + + if (parser->mark.column != 0) { + parser->mark.column = 0; + parser->mark.line ++; + } + + /* Reset the indentation level. */ + + if (!yaml_parser_unroll_indent(parser, -1)) + return 0; + + /* Reset simple keys. */ + + if (!yaml_parser_remove_simple_key(parser)) + return 0; + + parser->simple_key_allowed = 0; + + /* Create the STREAM-END token and append it to the queue. */ + + STREAM_END_TOKEN_INIT(token, parser->mark, parser->mark); + + if (!ENQUEUE(parser, parser->tokens, token)) + return 0; + + return 1; +} + +/* + * Produce a VERSION-DIRECTIVE or TAG-DIRECTIVE token. + */ + +static int +yaml_parser_fetch_directive(yaml_parser_t *parser) +{ + yaml_token_t token; + + /* Reset the indentation level. */ + + if (!yaml_parser_unroll_indent(parser, -1)) + return 0; + + /* Reset simple keys. */ + + if (!yaml_parser_remove_simple_key(parser)) + return 0; + + parser->simple_key_allowed = 0; + + /* Create the YAML-DIRECTIVE or TAG-DIRECTIVE token. */ + + if (!yaml_parser_scan_directive(parser, &token)) + return 0; + + /* Append the token to the queue. */ + + if (!ENQUEUE(parser, parser->tokens, token)) { + yaml_token_delete(&token); + return 0; + } + + return 1; +} + +/* + * Produce the DOCUMENT-START or DOCUMENT-END token. + */ + +static int +yaml_parser_fetch_document_indicator(yaml_parser_t *parser, + yaml_token_type_t type) +{ + yaml_mark_t start_mark, end_mark; + yaml_token_t token; + + /* Reset the indentation level. */ + + if (!yaml_parser_unroll_indent(parser, -1)) + return 0; + + /* Reset simple keys. */ + + if (!yaml_parser_remove_simple_key(parser)) + return 0; + + parser->simple_key_allowed = 0; + + /* Consume the token. */ + + start_mark = parser->mark; + + SKIP(parser); + SKIP(parser); + SKIP(parser); + + end_mark = parser->mark; + + /* Create the DOCUMENT-START or DOCUMENT-END token. */ + + TOKEN_INIT(token, type, start_mark, end_mark); + + /* Append the token to the queue. */ + + if (!ENQUEUE(parser, parser->tokens, token)) + return 0; + + return 1; +} + +/* + * Produce the FLOW-SEQUENCE-START or FLOW-MAPPING-START token. + */ + +static int +yaml_parser_fetch_flow_collection_start(yaml_parser_t *parser, + yaml_token_type_t type) +{ + yaml_mark_t start_mark, end_mark; + yaml_token_t token; + + /* The indicators '[' and '{' may start a simple key. */ + + if (!yaml_parser_save_simple_key(parser)) + return 0; + + /* Increase the flow level. */ + + if (!yaml_parser_increase_flow_level(parser)) + return 0; + + /* A simple key may follow the indicators '[' and '{'. */ + + parser->simple_key_allowed = 1; + + /* Consume the token. */ + + start_mark = parser->mark; + SKIP(parser); + end_mark = parser->mark; + + /* Create the FLOW-SEQUENCE-START of FLOW-MAPPING-START token. */ + + TOKEN_INIT(token, type, start_mark, end_mark); + + /* Append the token to the queue. */ + + if (!ENQUEUE(parser, parser->tokens, token)) + return 0; + + return 1; +} + +/* + * Produce the FLOW-SEQUENCE-END or FLOW-MAPPING-END token. + */ + +static int +yaml_parser_fetch_flow_collection_end(yaml_parser_t *parser, + yaml_token_type_t type) +{ + yaml_mark_t start_mark, end_mark; + yaml_token_t token; + + /* Reset any potential simple key on the current flow level. */ + + if (!yaml_parser_remove_simple_key(parser)) + return 0; + + /* Decrease the flow level. */ + + if (!yaml_parser_decrease_flow_level(parser)) + return 0; + + /* No simple keys after the indicators ']' and '}'. */ + + parser->simple_key_allowed = 0; + + /* Consume the token. */ + + start_mark = parser->mark; + SKIP(parser); + end_mark = parser->mark; + + /* Create the FLOW-SEQUENCE-END of FLOW-MAPPING-END token. */ + + TOKEN_INIT(token, type, start_mark, end_mark); + + /* Append the token to the queue. */ + + if (!ENQUEUE(parser, parser->tokens, token)) + return 0; + + return 1; +} + +/* + * Produce the FLOW-ENTRY token. + */ + +static int +yaml_parser_fetch_flow_entry(yaml_parser_t *parser) +{ + yaml_mark_t start_mark, end_mark; + yaml_token_t token; + + /* Reset any potential simple keys on the current flow level. */ + + if (!yaml_parser_remove_simple_key(parser)) + return 0; + + /* Simple keys are allowed after ','. */ + + parser->simple_key_allowed = 1; + + /* Consume the token. */ + + start_mark = parser->mark; + SKIP(parser); + end_mark = parser->mark; + + /* Create the FLOW-ENTRY token and append it to the queue. */ + + TOKEN_INIT(token, YAML_FLOW_ENTRY_TOKEN, start_mark, end_mark); + + if (!ENQUEUE(parser, parser->tokens, token)) + return 0; + + return 1; +} + +/* + * Produce the BLOCK-ENTRY token. + */ + +static int +yaml_parser_fetch_block_entry(yaml_parser_t *parser) +{ + yaml_mark_t start_mark, end_mark; + yaml_token_t token; + + /* Check if the scanner is in the block context. */ + + if (!parser->flow_level) + { + /* Check if we are allowed to start a new entry. */ + + if (!parser->simple_key_allowed) { + return yaml_parser_set_scanner_error(parser, NULL, parser->mark, + "block sequence entries are not allowed in this context"); + } + + /* Add the BLOCK-SEQUENCE-START token if needed. */ + + if (!yaml_parser_roll_indent(parser, parser->mark.column, -1, + YAML_BLOCK_SEQUENCE_START_TOKEN, parser->mark)) + return 0; + } + else + { + /* + * It is an error for the '-' indicator to occur in the flow context, + * but we let the Parser detect and report about it because the Parser + * is able to point to the context. + */ + } + + /* Reset any potential simple keys on the current flow level. */ + + if (!yaml_parser_remove_simple_key(parser)) + return 0; + + /* Simple keys are allowed after '-'. */ + + parser->simple_key_allowed = 1; + + /* Consume the token. */ + + start_mark = parser->mark; + SKIP(parser); + end_mark = parser->mark; + + /* Create the BLOCK-ENTRY token and append it to the queue. */ + + TOKEN_INIT(token, YAML_BLOCK_ENTRY_TOKEN, start_mark, end_mark); + + if (!ENQUEUE(parser, parser->tokens, token)) + return 0; + + return 1; +} + +/* + * Produce the KEY token. + */ + +static int +yaml_parser_fetch_key(yaml_parser_t *parser) +{ + yaml_mark_t start_mark, end_mark; + yaml_token_t token; + + /* In the block context, additional checks are required. */ + + if (!parser->flow_level) + { + /* Check if we are allowed to start a new key (not nessesary simple). */ + + if (!parser->simple_key_allowed) { + return yaml_parser_set_scanner_error(parser, NULL, parser->mark, + "mapping keys are not allowed in this context"); + } + + /* Add the BLOCK-MAPPING-START token if needed. */ + + if (!yaml_parser_roll_indent(parser, parser->mark.column, -1, + YAML_BLOCK_MAPPING_START_TOKEN, parser->mark)) + return 0; + } + + /* Reset any potential simple keys on the current flow level. */ + + if (!yaml_parser_remove_simple_key(parser)) + return 0; + + /* Simple keys are allowed after '?' in the block context. */ + + parser->simple_key_allowed = (!parser->flow_level); + + /* Consume the token. */ + + start_mark = parser->mark; + SKIP(parser); + end_mark = parser->mark; + + /* Create the KEY token and append it to the queue. */ + + TOKEN_INIT(token, YAML_KEY_TOKEN, start_mark, end_mark); + + if (!ENQUEUE(parser, parser->tokens, token)) + return 0; + + return 1; +} + +/* + * Produce the VALUE token. + */ + +static int +yaml_parser_fetch_value(yaml_parser_t *parser) +{ + yaml_mark_t start_mark, end_mark; + yaml_token_t token; + yaml_simple_key_t *simple_key = parser->simple_keys.top-1; + + /* Have we found a simple key? */ + + if (simple_key->possible) + { + + /* Create the KEY token and insert it into the queue. */ + + TOKEN_INIT(token, YAML_KEY_TOKEN, simple_key->mark, simple_key->mark); + + if (!QUEUE_INSERT(parser, parser->tokens, + simple_key->token_number - parser->tokens_parsed, token)) + return 0; + + /* In the block context, we may need to add the BLOCK-MAPPING-START token. */ + + if (!yaml_parser_roll_indent(parser, simple_key->mark.column, + simple_key->token_number, + YAML_BLOCK_MAPPING_START_TOKEN, simple_key->mark)) + return 0; + + /* Remove the simple key. */ + + simple_key->possible = 0; + + /* A simple key cannot follow another simple key. */ + + parser->simple_key_allowed = 0; + } + else + { + /* The ':' indicator follows a complex key. */ + + /* In the block context, extra checks are required. */ + + if (!parser->flow_level) + { + /* Check if we are allowed to start a complex value. */ + + if (!parser->simple_key_allowed) { + return yaml_parser_set_scanner_error(parser, NULL, parser->mark, + "mapping values are not allowed in this context"); + } + + /* Add the BLOCK-MAPPING-START token if needed. */ + + if (!yaml_parser_roll_indent(parser, parser->mark.column, -1, + YAML_BLOCK_MAPPING_START_TOKEN, parser->mark)) + return 0; + } + + /* Simple keys after ':' are allowed in the block context. */ + + parser->simple_key_allowed = (!parser->flow_level); + } + + /* Consume the token. */ + + start_mark = parser->mark; + SKIP(parser); + end_mark = parser->mark; + + /* Create the VALUE token and append it to the queue. */ + + TOKEN_INIT(token, YAML_VALUE_TOKEN, start_mark, end_mark); + + if (!ENQUEUE(parser, parser->tokens, token)) + return 0; + + return 1; +} + +/* + * Produce the ALIAS or ANCHOR token. + */ + +static int +yaml_parser_fetch_anchor(yaml_parser_t *parser, yaml_token_type_t type) +{ + yaml_token_t token; + + /* An anchor or an alias could be a simple key. */ + + if (!yaml_parser_save_simple_key(parser)) + return 0; + + /* A simple key cannot follow an anchor or an alias. */ + + parser->simple_key_allowed = 0; + + /* Create the ALIAS or ANCHOR token and append it to the queue. */ + + if (!yaml_parser_scan_anchor(parser, &token, type)) + return 0; + + if (!ENQUEUE(parser, parser->tokens, token)) { + yaml_token_delete(&token); + return 0; + } + return 1; +} + +/* + * Produce the TAG token. + */ + +static int +yaml_parser_fetch_tag(yaml_parser_t *parser) +{ + yaml_token_t token; + + /* A tag could be a simple key. */ + + if (!yaml_parser_save_simple_key(parser)) + return 0; + + /* A simple key cannot follow a tag. */ + + parser->simple_key_allowed = 0; + + /* Create the TAG token and append it to the queue. */ + + if (!yaml_parser_scan_tag(parser, &token)) + return 0; + + if (!ENQUEUE(parser, parser->tokens, token)) { + yaml_token_delete(&token); + return 0; + } + + return 1; +} + +/* + * Produce the SCALAR(...,literal) or SCALAR(...,folded) tokens. + */ + +static int +yaml_parser_fetch_block_scalar(yaml_parser_t *parser, int literal) +{ + yaml_token_t token; + + /* Remove any potential simple keys. */ + + if (!yaml_parser_remove_simple_key(parser)) + return 0; + + /* A simple key may follow a block scalar. */ + + parser->simple_key_allowed = 1; + + /* Create the SCALAR token and append it to the queue. */ + + if (!yaml_parser_scan_block_scalar(parser, &token, literal)) + return 0; + + if (!ENQUEUE(parser, parser->tokens, token)) { + yaml_token_delete(&token); + return 0; + } + + return 1; +} + +/* + * Produce the SCALAR(...,single-quoted) or SCALAR(...,double-quoted) tokens. + */ + +static int +yaml_parser_fetch_flow_scalar(yaml_parser_t *parser, int single) +{ + yaml_token_t token; + + /* A plain scalar could be a simple key. */ + + if (!yaml_parser_save_simple_key(parser)) + return 0; + + /* A simple key cannot follow a flow scalar. */ + + parser->simple_key_allowed = 0; + + /* Create the SCALAR token and append it to the queue. */ + + if (!yaml_parser_scan_flow_scalar(parser, &token, single)) + return 0; + + if (!ENQUEUE(parser, parser->tokens, token)) { + yaml_token_delete(&token); + return 0; + } + + return 1; +} + +/* + * Produce the SCALAR(...,plain) token. + */ + +static int +yaml_parser_fetch_plain_scalar(yaml_parser_t *parser) +{ + yaml_token_t token; + + /* A plain scalar could be a simple key. */ + + if (!yaml_parser_save_simple_key(parser)) + return 0; + + /* A simple key cannot follow a flow scalar. */ + + parser->simple_key_allowed = 0; + + /* Create the SCALAR token and append it to the queue. */ + + if (!yaml_parser_scan_plain_scalar(parser, &token)) + return 0; + + if (!ENQUEUE(parser, parser->tokens, token)) { + yaml_token_delete(&token); + return 0; + } + + return 1; +} + +/* + * Eat whitespaces and comments until the next token is found. + */ + +static int +yaml_parser_scan_to_next_token(yaml_parser_t *parser) +{ + /* Until the next token is not found. */ + + while (1) + { + /* Allow the BOM mark to start a line. */ + + if (!CACHE(parser, 1)) return 0; + + if (parser->mark.column == 0 && IS_BOM(parser->buffer)) + SKIP(parser); + + /* + * Eat whitespaces. + * + * Tabs are allowed: + * + * - in the flow context; + * - in the block context, but not at the beginning of the line or + * after '-', '?', or ':' (complex value). + */ + + if (!CACHE(parser, 1)) return 0; + + while (CHECK(parser->buffer,' ') || + ((parser->flow_level || !parser->simple_key_allowed) && + CHECK(parser->buffer, '\t'))) { + SKIP(parser); + if (!CACHE(parser, 1)) return 0; + } + + /* Eat a comment until a line break. */ + + if (CHECK(parser->buffer, '#')) { + while (!IS_BREAKZ(parser->buffer)) { + SKIP(parser); + if (!CACHE(parser, 1)) return 0; + } + } + + /* If it is a line break, eat it. */ + + if (IS_BREAK(parser->buffer)) + { + if (!CACHE(parser, 2)) return 0; + SKIP_LINE(parser); + + /* In the block context, a new line may start a simple key. */ + + if (!parser->flow_level) { + parser->simple_key_allowed = 1; + } + } + else + { + /* We have found a token. */ + + break; + } + } + + return 1; +} + +/* + * Scan a YAML-DIRECTIVE or TAG-DIRECTIVE token. + * + * Scope: + * %YAML 1.1 # a comment \n + * ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + * %TAG !yaml! tag:yaml.org,2002: \n + * ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + */ + +int +yaml_parser_scan_directive(yaml_parser_t *parser, yaml_token_t *token) +{ + yaml_mark_t start_mark, end_mark; + yaml_char_t *name = NULL; + int major, minor; + yaml_char_t *handle = NULL, *prefix = NULL; + + /* Eat '%'. */ + + start_mark = parser->mark; + + SKIP(parser); + + /* Scan the directive name. */ + + if (!yaml_parser_scan_directive_name(parser, start_mark, &name)) + goto error; + + /* Is it a YAML directive? */ + + if (strcmp((char *)name, "YAML") == 0) + { + /* Scan the VERSION directive value. */ + + if (!yaml_parser_scan_version_directive_value(parser, start_mark, + &major, &minor)) + goto error; + + end_mark = parser->mark; + + /* Create a VERSION-DIRECTIVE token. */ + + VERSION_DIRECTIVE_TOKEN_INIT(*token, major, minor, + start_mark, end_mark); + } + + /* Is it a TAG directive? */ + + else if (strcmp((char *)name, "TAG") == 0) + { + /* Scan the TAG directive value. */ + + if (!yaml_parser_scan_tag_directive_value(parser, start_mark, + &handle, &prefix)) + goto error; + + end_mark = parser->mark; + + /* Create a TAG-DIRECTIVE token. */ + + TAG_DIRECTIVE_TOKEN_INIT(*token, handle, prefix, + start_mark, end_mark); + } + + /* Unknown directive. */ + + else + { + yaml_parser_set_scanner_error(parser, "while scanning a directive", + start_mark, "found uknown directive name"); + goto error; + } + + /* Eat the rest of the line including any comments. */ + + if (!CACHE(parser, 1)) goto error; + + while (IS_BLANK(parser->buffer)) { + SKIP(parser); + if (!CACHE(parser, 1)) goto error; + } + + if (CHECK(parser->buffer, '#')) { + while (!IS_BREAKZ(parser->buffer)) { + SKIP(parser); + if (!CACHE(parser, 1)) goto error; + } + } + + /* Check if we are at the end of the line. */ + + if (!IS_BREAKZ(parser->buffer)) { + yaml_parser_set_scanner_error(parser, "while scanning a directive", + start_mark, "did not find expected comment or line break"); + goto error; + } + + /* Eat a line break. */ + + if (IS_BREAK(parser->buffer)) { + if (!CACHE(parser, 2)) goto error; + SKIP_LINE(parser); + } + + yaml_free(name); + + return 1; + +error: + yaml_free(prefix); + yaml_free(handle); + yaml_free(name); + return 0; +} + +/* + * Scan the directive name. + * + * Scope: + * %YAML 1.1 # a comment \n + * ^^^^ + * %TAG !yaml! tag:yaml.org,2002: \n + * ^^^ + */ + +static int +yaml_parser_scan_directive_name(yaml_parser_t *parser, + yaml_mark_t start_mark, yaml_char_t **name) +{ + yaml_string_t string = NULL_STRING; + + if (!STRING_INIT(parser, string, INITIAL_STRING_SIZE)) goto error; + + /* Consume the directive name. */ + + if (!CACHE(parser, 1)) goto error; + + while (IS_ALPHA(parser->buffer)) + { + if (!READ(parser, string)) goto error; + if (!CACHE(parser, 1)) goto error; + } + + /* Check if the name is empty. */ + + if (string.start == string.pointer) { + yaml_parser_set_scanner_error(parser, "while scanning a directive", + start_mark, "could not find expected directive name"); + goto error; + } + + /* Check for an blank character after the name. */ + + if (!IS_BLANKZ(parser->buffer)) { + yaml_parser_set_scanner_error(parser, "while scanning a directive", + start_mark, "found unexpected non-alphabetical character"); + goto error; + } + + *name = string.start; + + return 1; + +error: + STRING_DEL(parser, string); + return 0; +} + +/* + * Scan the value of VERSION-DIRECTIVE. + * + * Scope: + * %YAML 1.1 # a comment \n + * ^^^^^^ + */ + +static int +yaml_parser_scan_version_directive_value(yaml_parser_t *parser, + yaml_mark_t start_mark, int *major, int *minor) +{ + /* Eat whitespaces. */ + + if (!CACHE(parser, 1)) return 0; + + while (IS_BLANK(parser->buffer)) { + SKIP(parser); + if (!CACHE(parser, 1)) return 0; + } + + /* Consume the major version number. */ + + if (!yaml_parser_scan_version_directive_number(parser, start_mark, major)) + return 0; + + /* Eat '.'. */ + + if (!CHECK(parser->buffer, '.')) { + return yaml_parser_set_scanner_error(parser, "while scanning a %YAML directive", + start_mark, "did not find expected digit or '.' character"); + } + + SKIP(parser); + + /* Consume the minor version number. */ + + if (!yaml_parser_scan_version_directive_number(parser, start_mark, minor)) + return 0; + + return 1; +} + +#define MAX_NUMBER_LENGTH 9 + +/* + * Scan the version number of VERSION-DIRECTIVE. + * + * Scope: + * %YAML 1.1 # a comment \n + * ^ + * %YAML 1.1 # a comment \n + * ^ + */ + +static int +yaml_parser_scan_version_directive_number(yaml_parser_t *parser, + yaml_mark_t start_mark, int *number) +{ + int value = 0; + size_t length = 0; + + /* Repeat while the next character is digit. */ + + if (!CACHE(parser, 1)) return 0; + + while (IS_DIGIT(parser->buffer)) + { + /* Check if the number is too long. */ + + if (++length > MAX_NUMBER_LENGTH) { + return yaml_parser_set_scanner_error(parser, "while scanning a %YAML directive", + start_mark, "found extremely long version number"); + } + + value = value*10 + AS_DIGIT(parser->buffer); + + SKIP(parser); + + if (!CACHE(parser, 1)) return 0; + } + + /* Check if the number was present. */ + + if (!length) { + return yaml_parser_set_scanner_error(parser, "while scanning a %YAML directive", + start_mark, "did not find expected version number"); + } + + *number = value; + + return 1; +} + +/* + * Scan the value of a TAG-DIRECTIVE token. + * + * Scope: + * %TAG !yaml! tag:yaml.org,2002: \n + * ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + */ + +static int +yaml_parser_scan_tag_directive_value(yaml_parser_t *parser, + yaml_mark_t start_mark, yaml_char_t **handle, yaml_char_t **prefix) +{ + yaml_char_t *handle_value = NULL; + yaml_char_t *prefix_value = NULL; + + /* Eat whitespaces. */ + + if (!CACHE(parser, 1)) goto error; + + while (IS_BLANK(parser->buffer)) { + SKIP(parser); + if (!CACHE(parser, 1)) goto error; + } + + /* Scan a handle. */ + + if (!yaml_parser_scan_tag_handle(parser, 1, start_mark, &handle_value)) + goto error; + + /* Expect a whitespace. */ + + if (!CACHE(parser, 1)) goto error; + + if (!IS_BLANK(parser->buffer)) { + yaml_parser_set_scanner_error(parser, "while scanning a %TAG directive", + start_mark, "did not find expected whitespace"); + goto error; + } + + /* Eat whitespaces. */ + + while (IS_BLANK(parser->buffer)) { + SKIP(parser); + if (!CACHE(parser, 1)) goto error; + } + + /* Scan a prefix. */ + + if (!yaml_parser_scan_tag_uri(parser, 1, NULL, start_mark, &prefix_value)) + goto error; + + /* Expect a whitespace or line break. */ + + if (!CACHE(parser, 1)) goto error; + + if (!IS_BLANKZ(parser->buffer)) { + yaml_parser_set_scanner_error(parser, "while scanning a %TAG directive", + start_mark, "did not find expected whitespace or line break"); + goto error; + } + + *handle = handle_value; + *prefix = prefix_value; + + return 1; + +error: + yaml_free(handle_value); + yaml_free(prefix_value); + return 0; +} + +static int +yaml_parser_scan_anchor(yaml_parser_t *parser, yaml_token_t *token, + yaml_token_type_t type) +{ + int length = 0; + yaml_mark_t start_mark, end_mark; + yaml_string_t string = NULL_STRING; + + if (!STRING_INIT(parser, string, INITIAL_STRING_SIZE)) goto error; + + /* Eat the indicator character. */ + + start_mark = parser->mark; + + SKIP(parser); + + /* Consume the value. */ + + if (!CACHE(parser, 1)) goto error; + + while (IS_ALPHA(parser->buffer)) { + if (!READ(parser, string)) goto error; + if (!CACHE(parser, 1)) goto error; + length ++; + } + + end_mark = parser->mark; + + /* + * Check if length of the anchor is greater than 0 and it is followed by + * a whitespace character or one of the indicators: + * + * '?', ':', ',', ']', '}', '%', '@', '`'. + */ + + if (!length || !(IS_BLANKZ(parser->buffer) || CHECK(parser->buffer, '?') + || CHECK(parser->buffer, ':') || CHECK(parser->buffer, ',') + || CHECK(parser->buffer, ']') || CHECK(parser->buffer, '}') + || CHECK(parser->buffer, '%') || CHECK(parser->buffer, '@') + || CHECK(parser->buffer, '`'))) { + yaml_parser_set_scanner_error(parser, type == YAML_ANCHOR_TOKEN ? + "while scanning an anchor" : "while scanning an alias", start_mark, + "did not find expected alphabetic or numeric character"); + goto error; + } + + /* Create a token. */ + + if (type == YAML_ANCHOR_TOKEN) { + ANCHOR_TOKEN_INIT(*token, string.start, start_mark, end_mark); + } + else { + ALIAS_TOKEN_INIT(*token, string.start, start_mark, end_mark); + } + + return 1; + +error: + STRING_DEL(parser, string); + return 0; +} + +/* + * Scan a TAG token. + */ + +static int +yaml_parser_scan_tag(yaml_parser_t *parser, yaml_token_t *token) +{ + yaml_char_t *handle = NULL; + yaml_char_t *suffix = NULL; + yaml_mark_t start_mark, end_mark; + + start_mark = parser->mark; + + /* Check if the tag is in the canonical form. */ + + if (!CACHE(parser, 2)) goto error; + + if (CHECK_AT(parser->buffer, '<', 1)) + { + /* Set the handle to '' */ + + handle = yaml_malloc(1); + if (!handle) goto error; + handle[0] = '\0'; + + /* Eat '!<' */ + + SKIP(parser); + SKIP(parser); + + /* Consume the tag value. */ + + if (!yaml_parser_scan_tag_uri(parser, 0, NULL, start_mark, &suffix)) + goto error; + + /* Check for '>' and eat it. */ + + if (!CHECK(parser->buffer, '>')) { + yaml_parser_set_scanner_error(parser, "while scanning a tag", + start_mark, "did not find the expected '>'"); + goto error; + } + + SKIP(parser); + } + else + { + /* The tag has either the '!suffix' or the '!handle!suffix' form. */ + + /* First, try to scan a handle. */ + + if (!yaml_parser_scan_tag_handle(parser, 0, start_mark, &handle)) + goto error; + + /* Check if it is, indeed, handle. */ + + if (handle[0] == '!' && handle[1] != '\0' && handle[strlen((char *)handle)-1] == '!') + { + /* Scan the suffix now. */ + + if (!yaml_parser_scan_tag_uri(parser, 0, NULL, start_mark, &suffix)) + goto error; + } + else + { + /* It wasn't a handle after all. Scan the rest of the tag. */ + + if (!yaml_parser_scan_tag_uri(parser, 0, handle, start_mark, &suffix)) + goto error; + + /* Set the handle to '!'. */ + + yaml_free(handle); + handle = yaml_malloc(2); + if (!handle) goto error; + handle[0] = '!'; + handle[1] = '\0'; + + /* + * A special case: the '!' tag. Set the handle to '' and the + * suffix to '!'. + */ + + if (suffix[0] == '\0') { + yaml_char_t *tmp = handle; + handle = suffix; + suffix = tmp; + } + } + } + + /* Check the character which ends the tag. */ + + if (!CACHE(parser, 1)) goto error; + + if (!IS_BLANKZ(parser->buffer)) { + yaml_parser_set_scanner_error(parser, "while scanning a tag", + start_mark, "did not find expected whitespace or line break"); + goto error; + } + + end_mark = parser->mark; + + /* Create a token. */ + + TAG_TOKEN_INIT(*token, handle, suffix, start_mark, end_mark); + + return 1; + +error: + yaml_free(handle); + yaml_free(suffix); + return 0; +} + +/* + * Scan a tag handle. + */ + +static int +yaml_parser_scan_tag_handle(yaml_parser_t *parser, int directive, + yaml_mark_t start_mark, yaml_char_t **handle) +{ + yaml_string_t string = NULL_STRING; + + if (!STRING_INIT(parser, string, INITIAL_STRING_SIZE)) goto error; + + /* Check the initial '!' character. */ + + if (!CACHE(parser, 1)) goto error; + + if (!CHECK(parser->buffer, '!')) { + yaml_parser_set_scanner_error(parser, directive ? + "while scanning a tag directive" : "while scanning a tag", + start_mark, "did not find expected '!'"); + goto error; + } + + /* Copy the '!' character. */ + + if (!READ(parser, string)) goto error; + + /* Copy all subsequent alphabetical and numerical characters. */ + + if (!CACHE(parser, 1)) goto error; + + while (IS_ALPHA(parser->buffer)) + { + if (!READ(parser, string)) goto error; + if (!CACHE(parser, 1)) goto error; + } + + /* Check if the trailing character is '!' and copy it. */ + + if (CHECK(parser->buffer, '!')) + { + if (!READ(parser, string)) goto error; + } + else + { + /* + * It's either the '!' tag or not really a tag handle. If it's a %TAG + * directive, it's an error. If it's a tag token, it must be a part of + * URI. + */ + + if (directive && !(string.start[0] == '!' && string.start[1] == '\0')) { + yaml_parser_set_scanner_error(parser, "while parsing a tag directive", + start_mark, "did not find expected '!'"); + goto error; + } + } + + *handle = string.start; + + return 1; + +error: + STRING_DEL(parser, string); + return 0; +} + +/* + * Scan a tag. + */ + +static int +yaml_parser_scan_tag_uri(yaml_parser_t *parser, int directive, + yaml_char_t *head, yaml_mark_t start_mark, yaml_char_t **uri) +{ + size_t length = head ? strlen((char *)head) : 0; + yaml_string_t string = NULL_STRING; + + if (!STRING_INIT(parser, string, INITIAL_STRING_SIZE)) goto error; + + /* Resize the string to include the head. */ + + while ((size_t)(string.end - string.start) <= length) { + if (!yaml_string_extend(&string.start, &string.pointer, &string.end)) { + parser->error = YAML_MEMORY_ERROR; + goto error; + } + } + + /* + * Copy the head if needed. + * + * Note that we don't copy the leading '!' character. + */ + + if (length > 1) { + memcpy(string.start, head+1, length-1); + string.pointer += length-1; + } + + /* Scan the tag. */ + + if (!CACHE(parser, 1)) goto error; + + /* + * The set of characters that may appear in URI is as follows: + * + * '0'-'9', 'A'-'Z', 'a'-'z', '_', '-', ';', '/', '?', ':', '@', '&', + * '=', '+', '$', ',', '.', '!', '~', '*', '\'', '(', ')', '[', ']', + * '%'. + */ + + while (IS_ALPHA(parser->buffer) || CHECK(parser->buffer, ';') + || CHECK(parser->buffer, '/') || CHECK(parser->buffer, '?') + || CHECK(parser->buffer, ':') || CHECK(parser->buffer, '@') + || CHECK(parser->buffer, '&') || CHECK(parser->buffer, '=') + || CHECK(parser->buffer, '+') || CHECK(parser->buffer, '$') + || CHECK(parser->buffer, ',') || CHECK(parser->buffer, '.') + || CHECK(parser->buffer, '!') || CHECK(parser->buffer, '~') + || CHECK(parser->buffer, '*') || CHECK(parser->buffer, '\'') + || CHECK(parser->buffer, '(') || CHECK(parser->buffer, ')') + || CHECK(parser->buffer, '[') || CHECK(parser->buffer, ']') + || CHECK(parser->buffer, '%')) + { + /* Check if it is a URI-escape sequence. */ + + if (CHECK(parser->buffer, '%')) { + if (!STRING_EXTEND(parser, string)) + goto error; + + if (!yaml_parser_scan_uri_escapes(parser, + directive, start_mark, &string)) goto error; + } + else { + if (!READ(parser, string)) goto error; + } + + length ++; + if (!CACHE(parser, 1)) goto error; + } + + /* Check if the tag is non-empty. */ + + if (!length) { + if (!STRING_EXTEND(parser, string)) + goto error; + + yaml_parser_set_scanner_error(parser, directive ? + "while parsing a %TAG directive" : "while parsing a tag", + start_mark, "did not find expected tag URI"); + goto error; + } + + *uri = string.start; + + return 1; + +error: + STRING_DEL(parser, string); + return 0; +} + +/* + * Decode an URI-escape sequence corresponding to a single UTF-8 character. + */ + +static int +yaml_parser_scan_uri_escapes(yaml_parser_t *parser, int directive, + yaml_mark_t start_mark, yaml_string_t *string) +{ + int width = 0; + + /* Decode the required number of characters. */ + + do { + + unsigned char octet = 0; + + /* Check for a URI-escaped octet. */ + + if (!CACHE(parser, 3)) return 0; + + if (!(CHECK(parser->buffer, '%') + && IS_HEX_AT(parser->buffer, 1) + && IS_HEX_AT(parser->buffer, 2))) { + return yaml_parser_set_scanner_error(parser, directive ? + "while parsing a %TAG directive" : "while parsing a tag", + start_mark, "did not find URI escaped octet"); + } + + /* Get the octet. */ + + octet = (AS_HEX_AT(parser->buffer, 1) << 4) + AS_HEX_AT(parser->buffer, 2); + + /* If it is the leading octet, determine the length of the UTF-8 sequence. */ + + if (!width) + { + width = (octet & 0x80) == 0x00 ? 1 : + (octet & 0xE0) == 0xC0 ? 2 : + (octet & 0xF0) == 0xE0 ? 3 : + (octet & 0xF8) == 0xF0 ? 4 : 0; + if (!width) { + return yaml_parser_set_scanner_error(parser, directive ? + "while parsing a %TAG directive" : "while parsing a tag", + start_mark, "found an incorrect leading UTF-8 octet"); + } + } + else + { + /* Check if the trailing octet is correct. */ + + if ((octet & 0xC0) != 0x80) { + return yaml_parser_set_scanner_error(parser, directive ? + "while parsing a %TAG directive" : "while parsing a tag", + start_mark, "found an incorrect trailing UTF-8 octet"); + } + } + + /* Copy the octet and move the pointers. */ + + *(string->pointer++) = octet; + SKIP(parser); + SKIP(parser); + SKIP(parser); + + } while (--width); + + return 1; +} + +/* + * Scan a block scalar. + */ + +static int +yaml_parser_scan_block_scalar(yaml_parser_t *parser, yaml_token_t *token, + int literal) +{ + yaml_mark_t start_mark; + yaml_mark_t end_mark; + yaml_string_t string = NULL_STRING; + yaml_string_t leading_break = NULL_STRING; + yaml_string_t trailing_breaks = NULL_STRING; + int chomping = 0; + int increment = 0; + int indent = 0; + int leading_blank = 0; + int trailing_blank = 0; + + if (!STRING_INIT(parser, string, INITIAL_STRING_SIZE)) goto error; + if (!STRING_INIT(parser, leading_break, INITIAL_STRING_SIZE)) goto error; + if (!STRING_INIT(parser, trailing_breaks, INITIAL_STRING_SIZE)) goto error; + + /* Eat the indicator '|' or '>'. */ + + start_mark = parser->mark; + + SKIP(parser); + + /* Scan the additional block scalar indicators. */ + + if (!CACHE(parser, 1)) goto error; + + /* Check for a chomping indicator. */ + + if (CHECK(parser->buffer, '+') || CHECK(parser->buffer, '-')) + { + /* Set the chomping method and eat the indicator. */ + + chomping = CHECK(parser->buffer, '+') ? +1 : -1; + + SKIP(parser); + + /* Check for an indentation indicator. */ + + if (!CACHE(parser, 1)) goto error; + + if (IS_DIGIT(parser->buffer)) + { + /* Check that the intendation is greater than 0. */ + + if (CHECK(parser->buffer, '0')) { + yaml_parser_set_scanner_error(parser, "while scanning a block scalar", + start_mark, "found an intendation indicator equal to 0"); + goto error; + } + + /* Get the intendation level and eat the indicator. */ + + increment = AS_DIGIT(parser->buffer); + + SKIP(parser); + } + } + + /* Do the same as above, but in the opposite order. */ + + else if (IS_DIGIT(parser->buffer)) + { + if (CHECK(parser->buffer, '0')) { + yaml_parser_set_scanner_error(parser, "while scanning a block scalar", + start_mark, "found an intendation indicator equal to 0"); + goto error; + } + + increment = AS_DIGIT(parser->buffer); + + SKIP(parser); + + if (!CACHE(parser, 1)) goto error; + + if (CHECK(parser->buffer, '+') || CHECK(parser->buffer, '-')) { + chomping = CHECK(parser->buffer, '+') ? +1 : -1; + + SKIP(parser); + } + } + + /* Eat whitespaces and comments to the end of the line. */ + + if (!CACHE(parser, 1)) goto error; + + while (IS_BLANK(parser->buffer)) { + SKIP(parser); + if (!CACHE(parser, 1)) goto error; + } + + if (CHECK(parser->buffer, '#')) { + while (!IS_BREAKZ(parser->buffer)) { + SKIP(parser); + if (!CACHE(parser, 1)) goto error; + } + } + + /* Check if we are at the end of the line. */ + + if (!IS_BREAKZ(parser->buffer)) { + yaml_parser_set_scanner_error(parser, "while scanning a block scalar", + start_mark, "did not find expected comment or line break"); + goto error; + } + + /* Eat a line break. */ + + if (IS_BREAK(parser->buffer)) { + if (!CACHE(parser, 2)) goto error; + SKIP_LINE(parser); + } + + end_mark = parser->mark; + + /* Set the intendation level if it was specified. */ + + if (increment) { + indent = parser->indent >= 0 ? parser->indent+increment : increment; + } + + /* Scan the leading line breaks and determine the indentation level if needed. */ + + if (!yaml_parser_scan_block_scalar_breaks(parser, &indent, &trailing_breaks, + start_mark, &end_mark)) goto error; + + /* Scan the block scalar content. */ + + if (!CACHE(parser, 1)) goto error; + + while ((int)parser->mark.column == indent && !IS_Z(parser->buffer)) + { + /* + * We are at the beginning of a non-empty line. + */ + + /* Is it a trailing whitespace? */ + + trailing_blank = IS_BLANK(parser->buffer); + + /* Check if we need to fold the leading line break. */ + + if (!literal && (*leading_break.start == '\n') + && !leading_blank && !trailing_blank) + { + /* Do we need to join the lines by space? */ + + if (*trailing_breaks.start == '\0') { + if (!STRING_EXTEND(parser, string)) goto error; + *(string.pointer ++) = ' '; + } + + CLEAR(parser, leading_break); + } + else { + if (!JOIN(parser, string, leading_break)) goto error; + CLEAR(parser, leading_break); + } + + /* Append the remaining line breaks. */ + + if (!JOIN(parser, string, trailing_breaks)) goto error; + CLEAR(parser, trailing_breaks); + + /* Is it a leading whitespace? */ + + leading_blank = IS_BLANK(parser->buffer); + + /* Consume the current line. */ + + while (!IS_BREAKZ(parser->buffer)) { + if (!READ(parser, string)) goto error; + if (!CACHE(parser, 1)) goto error; + } + + /* Consume the line break. */ + + if (!CACHE(parser, 2)) goto error; + + if (!READ_LINE(parser, leading_break)) goto error; + + /* Eat the following intendation spaces and line breaks. */ + + if (!yaml_parser_scan_block_scalar_breaks(parser, + &indent, &trailing_breaks, start_mark, &end_mark)) goto error; + } + + /* Chomp the tail. */ + + if (chomping != -1) { + if (!JOIN(parser, string, leading_break)) goto error; + } + if (chomping == 1) { + if (!JOIN(parser, string, trailing_breaks)) goto error; + } + + /* Create a token. */ + + SCALAR_TOKEN_INIT(*token, string.start, string.pointer-string.start, + literal ? YAML_LITERAL_SCALAR_STYLE : YAML_FOLDED_SCALAR_STYLE, + start_mark, end_mark); + + STRING_DEL(parser, leading_break); + STRING_DEL(parser, trailing_breaks); + + return 1; + +error: + STRING_DEL(parser, string); + STRING_DEL(parser, leading_break); + STRING_DEL(parser, trailing_breaks); + + return 0; +} + +/* + * Scan intendation spaces and line breaks for a block scalar. Determine the + * intendation level if needed. + */ + +static int +yaml_parser_scan_block_scalar_breaks(yaml_parser_t *parser, + int *indent, yaml_string_t *breaks, + yaml_mark_t start_mark, yaml_mark_t *end_mark) +{ + int max_indent = 0; + + *end_mark = parser->mark; + + /* Eat the intendation spaces and line breaks. */ + + while (1) + { + /* Eat the intendation spaces. */ + + if (!CACHE(parser, 1)) return 0; + + while ((!*indent || (int)parser->mark.column < *indent) + && IS_SPACE(parser->buffer)) { + SKIP(parser); + if (!CACHE(parser, 1)) return 0; + } + + if ((int)parser->mark.column > max_indent) + max_indent = (int)parser->mark.column; + + /* Check for a tab character messing the intendation. */ + + if ((!*indent || (int)parser->mark.column < *indent) + && IS_TAB(parser->buffer)) { + return yaml_parser_set_scanner_error(parser, "while scanning a block scalar", + start_mark, "found a tab character where an intendation space is expected"); + } + + /* Have we found a non-empty line? */ + + if (!IS_BREAK(parser->buffer)) break; + + /* Consume the line break. */ + + if (!CACHE(parser, 2)) return 0; + if (!READ_LINE(parser, *breaks)) return 0; + *end_mark = parser->mark; + } + + /* Determine the indentation level if needed. */ + + if (!*indent) { + *indent = max_indent; + if (*indent < parser->indent + 1) + *indent = parser->indent + 1; + if (*indent < 1) + *indent = 1; + } + + return 1; +} + +/* + * Scan a quoted scalar. + */ + +static int +yaml_parser_scan_flow_scalar(yaml_parser_t *parser, yaml_token_t *token, + int single) +{ + yaml_mark_t start_mark; + yaml_mark_t end_mark; + yaml_string_t string = NULL_STRING; + yaml_string_t leading_break = NULL_STRING; + yaml_string_t trailing_breaks = NULL_STRING; + yaml_string_t whitespaces = NULL_STRING; + int leading_blanks; + + if (!STRING_INIT(parser, string, INITIAL_STRING_SIZE)) goto error; + if (!STRING_INIT(parser, leading_break, INITIAL_STRING_SIZE)) goto error; + if (!STRING_INIT(parser, trailing_breaks, INITIAL_STRING_SIZE)) goto error; + if (!STRING_INIT(parser, whitespaces, INITIAL_STRING_SIZE)) goto error; + + /* Eat the left quote. */ + + start_mark = parser->mark; + + SKIP(parser); + + /* Consume the content of the quoted scalar. */ + + while (1) + { + /* Check that there are no document indicators at the beginning of the line. */ + + if (!CACHE(parser, 4)) goto error; + + if (parser->mark.column == 0 && + ((CHECK_AT(parser->buffer, '-', 0) && + CHECK_AT(parser->buffer, '-', 1) && + CHECK_AT(parser->buffer, '-', 2)) || + (CHECK_AT(parser->buffer, '.', 0) && + CHECK_AT(parser->buffer, '.', 1) && + CHECK_AT(parser->buffer, '.', 2))) && + IS_BLANKZ_AT(parser->buffer, 3)) + { + yaml_parser_set_scanner_error(parser, "while scanning a quoted scalar", + start_mark, "found unexpected document indicator"); + goto error; + } + + /* Check for EOF. */ + + if (IS_Z(parser->buffer)) { + yaml_parser_set_scanner_error(parser, "while scanning a quoted scalar", + start_mark, "found unexpected end of stream"); + goto error; + } + + /* Consume non-blank characters. */ + + if (!CACHE(parser, 2)) goto error; + + leading_blanks = 0; + + while (!IS_BLANKZ(parser->buffer)) + { + /* Check for an escaped single quote. */ + + if (single && CHECK_AT(parser->buffer, '\'', 0) + && CHECK_AT(parser->buffer, '\'', 1)) + { + if (!STRING_EXTEND(parser, string)) goto error; + *(string.pointer++) = '\''; + SKIP(parser); + SKIP(parser); + } + + /* Check for the right quote. */ + + else if (CHECK(parser->buffer, single ? '\'' : '"')) + { + break; + } + + /* Check for an escaped line break. */ + + else if (!single && CHECK(parser->buffer, '\\') + && IS_BREAK_AT(parser->buffer, 1)) + { + if (!CACHE(parser, 3)) goto error; + SKIP(parser); + SKIP_LINE(parser); + leading_blanks = 1; + break; + } + + /* Check for an escape sequence. */ + + else if (!single && CHECK(parser->buffer, '\\')) + { + size_t code_length = 0; + + if (!STRING_EXTEND(parser, string)) goto error; + + /* Check the escape character. */ + + switch (parser->buffer.pointer[1]) + { + case '0': + *(string.pointer++) = '\0'; + break; + + case 'a': + *(string.pointer++) = '\x07'; + break; + + case 'b': + *(string.pointer++) = '\x08'; + break; + + case 't': + case '\t': + *(string.pointer++) = '\x09'; + break; + + case 'n': + *(string.pointer++) = '\x0A'; + break; + + case 'v': + *(string.pointer++) = '\x0B'; + break; + + case 'f': + *(string.pointer++) = '\x0C'; + break; + + case 'r': + *(string.pointer++) = '\x0D'; + break; + + case 'e': + *(string.pointer++) = '\x1B'; + break; + + case ' ': + *(string.pointer++) = '\x20'; + break; + + case '"': + *(string.pointer++) = '"'; + break; + + case '\'': + *(string.pointer++) = '\''; + break; + + case '\\': + *(string.pointer++) = '\\'; + break; + + case 'N': /* NEL (#x85) */ + *(string.pointer++) = '\xC2'; + *(string.pointer++) = '\x85'; + break; + + case '_': /* #xA0 */ + *(string.pointer++) = '\xC2'; + *(string.pointer++) = '\xA0'; + break; + + case 'L': /* LS (#x2028) */ + *(string.pointer++) = '\xE2'; + *(string.pointer++) = '\x80'; + *(string.pointer++) = '\xA8'; + break; + + case 'P': /* PS (#x2029) */ + *(string.pointer++) = '\xE2'; + *(string.pointer++) = '\x80'; + *(string.pointer++) = '\xA9'; + break; + + case 'x': + code_length = 2; + break; + + case 'u': + code_length = 4; + break; + + case 'U': + code_length = 8; + break; + + default: + yaml_parser_set_scanner_error(parser, "while parsing a quoted scalar", + start_mark, "found unknown escape character"); + goto error; + } + + SKIP(parser); + SKIP(parser); + + /* Consume an arbitrary escape code. */ + + if (code_length) + { + unsigned int value = 0; + size_t k; + + /* Scan the character value. */ + + if (!CACHE(parser, code_length)) goto error; + + for (k = 0; k < code_length; k ++) { + if (!IS_HEX_AT(parser->buffer, k)) { + yaml_parser_set_scanner_error(parser, "while parsing a quoted scalar", + start_mark, "did not find expected hexdecimal number"); + goto error; + } + value = (value << 4) + AS_HEX_AT(parser->buffer, k); + } + + /* Check the value and write the character. */ + + if ((value >= 0xD800 && value <= 0xDFFF) || value > 0x10FFFF) { + yaml_parser_set_scanner_error(parser, "while parsing a quoted scalar", + start_mark, "found invalid Unicode character escape code"); + goto error; + } + + if (value <= 0x7F) { + *(string.pointer++) = value; + } + else if (value <= 0x7FF) { + *(string.pointer++) = 0xC0 + (value >> 6); + *(string.pointer++) = 0x80 + (value & 0x3F); + } + else if (value <= 0xFFFF) { + *(string.pointer++) = 0xE0 + (value >> 12); + *(string.pointer++) = 0x80 + ((value >> 6) & 0x3F); + *(string.pointer++) = 0x80 + (value & 0x3F); + } + else { + *(string.pointer++) = 0xF0 + (value >> 18); + *(string.pointer++) = 0x80 + ((value >> 12) & 0x3F); + *(string.pointer++) = 0x80 + ((value >> 6) & 0x3F); + *(string.pointer++) = 0x80 + (value & 0x3F); + } + + /* Advance the pointer. */ + + for (k = 0; k < code_length; k ++) { + SKIP(parser); + } + } + } + + else + { + /* It is a non-escaped non-blank character. */ + + if (!READ(parser, string)) goto error; + } + + if (!CACHE(parser, 2)) goto error; + } + + /* Check if we are at the end of the scalar. */ + + if (CHECK(parser->buffer, single ? '\'' : '"')) + break; + + /* Consume blank characters. */ + + if (!CACHE(parser, 1)) goto error; + + while (IS_BLANK(parser->buffer) || IS_BREAK(parser->buffer)) + { + if (IS_BLANK(parser->buffer)) + { + /* Consume a space or a tab character. */ + + if (!leading_blanks) { + if (!READ(parser, whitespaces)) goto error; + } + else { + SKIP(parser); + } + } + else + { + if (!CACHE(parser, 2)) goto error; + + /* Check if it is a first line break. */ + + if (!leading_blanks) + { + CLEAR(parser, whitespaces); + if (!READ_LINE(parser, leading_break)) goto error; + leading_blanks = 1; + } + else + { + if (!READ_LINE(parser, trailing_breaks)) goto error; + } + } + if (!CACHE(parser, 1)) goto error; + } + + /* Join the whitespaces or fold line breaks. */ + + if (leading_blanks) + { + /* Do we need to fold line breaks? */ + + if (leading_break.start[0] == '\n') { + if (trailing_breaks.start[0] == '\0') { + if (!STRING_EXTEND(parser, string)) goto error; + *(string.pointer++) = ' '; + } + else { + if (!JOIN(parser, string, trailing_breaks)) goto error; + CLEAR(parser, trailing_breaks); + } + CLEAR(parser, leading_break); + } + else { + if (!JOIN(parser, string, leading_break)) goto error; + if (!JOIN(parser, string, trailing_breaks)) goto error; + CLEAR(parser, leading_break); + CLEAR(parser, trailing_breaks); + } + } + else + { + if (!JOIN(parser, string, whitespaces)) goto error; + CLEAR(parser, whitespaces); + } + } + + /* Eat the right quote. */ + + SKIP(parser); + + end_mark = parser->mark; + + /* Create a token. */ + + SCALAR_TOKEN_INIT(*token, string.start, string.pointer-string.start, + single ? YAML_SINGLE_QUOTED_SCALAR_STYLE : YAML_DOUBLE_QUOTED_SCALAR_STYLE, + start_mark, end_mark); + + STRING_DEL(parser, leading_break); + STRING_DEL(parser, trailing_breaks); + STRING_DEL(parser, whitespaces); + + return 1; + +error: + STRING_DEL(parser, string); + STRING_DEL(parser, leading_break); + STRING_DEL(parser, trailing_breaks); + STRING_DEL(parser, whitespaces); + + return 0; +} + +/* + * Scan a plain scalar. + */ + +static int +yaml_parser_scan_plain_scalar(yaml_parser_t *parser, yaml_token_t *token) +{ + yaml_mark_t start_mark; + yaml_mark_t end_mark; + yaml_string_t string = NULL_STRING; + yaml_string_t leading_break = NULL_STRING; + yaml_string_t trailing_breaks = NULL_STRING; + yaml_string_t whitespaces = NULL_STRING; + int leading_blanks = 0; + int indent = parser->indent+1; + + if (!STRING_INIT(parser, string, INITIAL_STRING_SIZE)) goto error; + if (!STRING_INIT(parser, leading_break, INITIAL_STRING_SIZE)) goto error; + if (!STRING_INIT(parser, trailing_breaks, INITIAL_STRING_SIZE)) goto error; + if (!STRING_INIT(parser, whitespaces, INITIAL_STRING_SIZE)) goto error; + + start_mark = end_mark = parser->mark; + + /* Consume the content of the plain scalar. */ + + while (1) + { + /* Check for a document indicator. */ + + if (!CACHE(parser, 4)) goto error; + + if (parser->mark.column == 0 && + ((CHECK_AT(parser->buffer, '-', 0) && + CHECK_AT(parser->buffer, '-', 1) && + CHECK_AT(parser->buffer, '-', 2)) || + (CHECK_AT(parser->buffer, '.', 0) && + CHECK_AT(parser->buffer, '.', 1) && + CHECK_AT(parser->buffer, '.', 2))) && + IS_BLANKZ_AT(parser->buffer, 3)) break; + + /* Check for a comment. */ + + if (CHECK(parser->buffer, '#')) + break; + + /* Consume non-blank characters. */ + + while (!IS_BLANKZ(parser->buffer)) + { + /* Check for 'x:x' in the flow context. TODO: Fix the test "spec-08-13". */ + + if (parser->flow_level + && CHECK(parser->buffer, ':') + && !IS_BLANKZ_AT(parser->buffer, 1)) { + yaml_parser_set_scanner_error(parser, "while scanning a plain scalar", + start_mark, "found unexpected ':'"); + goto error; + } + + /* Check for indicators that may end a plain scalar. */ + + if ((CHECK(parser->buffer, ':') && IS_BLANKZ_AT(parser->buffer, 1)) + || (parser->flow_level && + (CHECK(parser->buffer, ',') || CHECK(parser->buffer, ':') + || CHECK(parser->buffer, '?') || CHECK(parser->buffer, '[') + || CHECK(parser->buffer, ']') || CHECK(parser->buffer, '{') + || CHECK(parser->buffer, '}')))) + break; + + /* Check if we need to join whitespaces and breaks. */ + + if (leading_blanks || whitespaces.start != whitespaces.pointer) + { + if (leading_blanks) + { + /* Do we need to fold line breaks? */ + + if (leading_break.start[0] == '\n') { + if (trailing_breaks.start[0] == '\0') { + if (!STRING_EXTEND(parser, string)) goto error; + *(string.pointer++) = ' '; + } + else { + if (!JOIN(parser, string, trailing_breaks)) goto error; + CLEAR(parser, trailing_breaks); + } + CLEAR(parser, leading_break); + } + else { + if (!JOIN(parser, string, leading_break)) goto error; + if (!JOIN(parser, string, trailing_breaks)) goto error; + CLEAR(parser, leading_break); + CLEAR(parser, trailing_breaks); + } + + leading_blanks = 0; + } + else + { + if (!JOIN(parser, string, whitespaces)) goto error; + CLEAR(parser, whitespaces); + } + } + + /* Copy the character. */ + + if (!READ(parser, string)) goto error; + + end_mark = parser->mark; + + if (!CACHE(parser, 2)) goto error; + } + + /* Is it the end? */ + + if (!(IS_BLANK(parser->buffer) || IS_BREAK(parser->buffer))) + break; + + /* Consume blank characters. */ + + if (!CACHE(parser, 1)) goto error; + + while (IS_BLANK(parser->buffer) || IS_BREAK(parser->buffer)) + { + if (IS_BLANK(parser->buffer)) + { + /* Check for tab character that abuse intendation. */ + + if (leading_blanks && (int)parser->mark.column < indent + && IS_TAB(parser->buffer)) { + yaml_parser_set_scanner_error(parser, "while scanning a plain scalar", + start_mark, "found a tab character that violate intendation"); + goto error; + } + + /* Consume a space or a tab character. */ + + if (!leading_blanks) { + if (!READ(parser, whitespaces)) goto error; + } + else { + SKIP(parser); + } + } + else + { + if (!CACHE(parser, 2)) goto error; + + /* Check if it is a first line break. */ + + if (!leading_blanks) + { + CLEAR(parser, whitespaces); + if (!READ_LINE(parser, leading_break)) goto error; + leading_blanks = 1; + } + else + { + if (!READ_LINE(parser, trailing_breaks)) goto error; + } + } + if (!CACHE(parser, 1)) goto error; + } + + /* Check intendation level. */ + + if (!parser->flow_level && (int)parser->mark.column < indent) + break; + } + + /* Create a token. */ + + SCALAR_TOKEN_INIT(*token, string.start, string.pointer-string.start, + YAML_PLAIN_SCALAR_STYLE, start_mark, end_mark); + + /* Note that we change the 'simple_key_allowed' flag. */ + + if (leading_blanks) { + parser->simple_key_allowed = 1; + } + + STRING_DEL(parser, leading_break); + STRING_DEL(parser, trailing_breaks); + STRING_DEL(parser, whitespaces); + + return 1; + +error: + STRING_DEL(parser, string); + STRING_DEL(parser, leading_break); + STRING_DEL(parser, trailing_breaks); + STRING_DEL(parser, whitespaces); + + return 0; +} + diff --git a/web/server/h2o/libh2o/deps/yaml/src/writer.c b/web/server/h2o/libh2o/deps/yaml/src/writer.c new file mode 100644 index 00000000..b90019f5 --- /dev/null +++ b/web/server/h2o/libh2o/deps/yaml/src/writer.c @@ -0,0 +1,141 @@ + +#include "yaml_private.h" + +/* + * Declarations. + */ + +static int +yaml_emitter_set_writer_error(yaml_emitter_t *emitter, const char *problem); + +YAML_DECLARE(int) +yaml_emitter_flush(yaml_emitter_t *emitter); + +/* + * Set the writer error and return 0. + */ + +static int +yaml_emitter_set_writer_error(yaml_emitter_t *emitter, const char *problem) +{ + emitter->error = YAML_WRITER_ERROR; + emitter->problem = problem; + + return 0; +} + +/* + * Flush the output buffer. + */ + +YAML_DECLARE(int) +yaml_emitter_flush(yaml_emitter_t *emitter) +{ + int low, high; + + assert(emitter); /* Non-NULL emitter object is expected. */ + assert(emitter->write_handler); /* Write handler must be set. */ + assert(emitter->encoding); /* Output encoding must be set. */ + + emitter->buffer.last = emitter->buffer.pointer; + emitter->buffer.pointer = emitter->buffer.start; + + /* Check if the buffer is empty. */ + + if (emitter->buffer.start == emitter->buffer.last) { + return 1; + } + + /* If the output encoding is UTF-8, we don't need to recode the buffer. */ + + if (emitter->encoding == YAML_UTF8_ENCODING) + { + if (emitter->write_handler(emitter->write_handler_data, + emitter->buffer.start, + emitter->buffer.last - emitter->buffer.start)) { + emitter->buffer.last = emitter->buffer.start; + emitter->buffer.pointer = emitter->buffer.start; + return 1; + } + else { + return yaml_emitter_set_writer_error(emitter, "write error"); + } + } + + /* Recode the buffer into the raw buffer. */ + + low = (emitter->encoding == YAML_UTF16LE_ENCODING ? 0 : 1); + high = (emitter->encoding == YAML_UTF16LE_ENCODING ? 1 : 0); + + while (emitter->buffer.pointer != emitter->buffer.last) + { + unsigned char octet; + unsigned int width; + unsigned int value; + size_t k; + + /* + * See the "reader.c" code for more details on UTF-8 encoding. Note + * that we assume that the buffer contains a valid UTF-8 sequence. + */ + + /* Read the next UTF-8 character. */ + + octet = emitter->buffer.pointer[0]; + + width = (octet & 0x80) == 0x00 ? 1 : + (octet & 0xE0) == 0xC0 ? 2 : + (octet & 0xF0) == 0xE0 ? 3 : + (octet & 0xF8) == 0xF0 ? 4 : 0; + + value = (octet & 0x80) == 0x00 ? octet & 0x7F : + (octet & 0xE0) == 0xC0 ? octet & 0x1F : + (octet & 0xF0) == 0xE0 ? octet & 0x0F : + (octet & 0xF8) == 0xF0 ? octet & 0x07 : 0; + + for (k = 1; k < width; k ++) { + octet = emitter->buffer.pointer[k]; + value = (value << 6) + (octet & 0x3F); + } + + emitter->buffer.pointer += width; + + /* Write the character. */ + + if (value < 0x10000) + { + emitter->raw_buffer.last[high] = value >> 8; + emitter->raw_buffer.last[low] = value & 0xFF; + + emitter->raw_buffer.last += 2; + } + else + { + /* Write the character using a surrogate pair (check "reader.c"). */ + + value -= 0x10000; + emitter->raw_buffer.last[high] = 0xD8 + (value >> 18); + emitter->raw_buffer.last[low] = (value >> 10) & 0xFF; + emitter->raw_buffer.last[high+2] = 0xDC + ((value >> 8) & 0xFF); + emitter->raw_buffer.last[low+2] = value & 0xFF; + + emitter->raw_buffer.last += 4; + } + } + + /* Write the raw buffer. */ + + if (emitter->write_handler(emitter->write_handler_data, + emitter->raw_buffer.start, + emitter->raw_buffer.last - emitter->raw_buffer.start)) { + emitter->buffer.last = emitter->buffer.start; + emitter->buffer.pointer = emitter->buffer.start; + emitter->raw_buffer.last = emitter->raw_buffer.start; + emitter->raw_buffer.pointer = emitter->raw_buffer.start; + return 1; + } + else { + return yaml_emitter_set_writer_error(emitter, "write error"); + } +} + diff --git a/web/server/h2o/libh2o/deps/yaml/src/yaml_private.h b/web/server/h2o/libh2o/deps/yaml/src/yaml_private.h new file mode 100644 index 00000000..01ec73d2 --- /dev/null +++ b/web/server/h2o/libh2o/deps/yaml/src/yaml_private.h @@ -0,0 +1,661 @@ + +#define YAML_VERSION_MAJOR 0 +#define YAML_VERSION_MINOR 1 +#define YAML_VERSION_PATCH 6 +#define YAML_VERSION_STRING "0.1.6" + +#include + +#include +#include +#include + +#ifndef _MSC_VER +#include +#else +#ifdef _WIN64 +#define PTRDIFF_MAX _I64_MAX +#else +#define PTRDIFF_MAX INT_MAX +#endif +#endif + +/* + * Memory management. + */ + +YAML_DECLARE(void *) +yaml_malloc(size_t size); + +YAML_DECLARE(void *) +yaml_realloc(void *ptr, size_t size); + +YAML_DECLARE(void) +yaml_free(void *ptr); + +YAML_DECLARE(yaml_char_t *) +yaml_strdup(const yaml_char_t *); + +/* + * Reader: Ensure that the buffer contains at least `length` characters. + */ + +YAML_DECLARE(int) +yaml_parser_update_buffer(yaml_parser_t *parser, size_t length); + +/* + * Scanner: Ensure that the token stack contains at least one token ready. + */ + +YAML_DECLARE(int) +yaml_parser_fetch_more_tokens(yaml_parser_t *parser); + +/* + * The size of the input raw buffer. + */ + +#define INPUT_RAW_BUFFER_SIZE 16384 + +/* + * The size of the input buffer. + * + * It should be possible to decode the whole raw buffer. + */ + +#define INPUT_BUFFER_SIZE (INPUT_RAW_BUFFER_SIZE*3) + +/* + * The size of the output buffer. + */ + +#define OUTPUT_BUFFER_SIZE 16384 + +/* + * The size of the output raw buffer. + * + * It should be possible to encode the whole output buffer. + */ + +#define OUTPUT_RAW_BUFFER_SIZE (OUTPUT_BUFFER_SIZE*2+2) + +/* + * The size of other stacks and queues. + */ + +#define INITIAL_STACK_SIZE 16 +#define INITIAL_QUEUE_SIZE 16 +#define INITIAL_STRING_SIZE 16 + +/* + * Buffer management. + */ + +#define BUFFER_INIT(context,buffer,size) \ + (((buffer).start = yaml_malloc(size)) ? \ + ((buffer).last = (buffer).pointer = (buffer).start, \ + (buffer).end = (buffer).start+(size), \ + 1) : \ + ((context)->error = YAML_MEMORY_ERROR, \ + 0)) + +#define BUFFER_DEL(context,buffer) \ + (yaml_free((buffer).start), \ + (buffer).start = (buffer).pointer = (buffer).end = 0) + +/* + * String management. + */ + +typedef struct { + yaml_char_t *start; + yaml_char_t *end; + yaml_char_t *pointer; +} yaml_string_t; + +YAML_DECLARE(int) +yaml_string_extend(yaml_char_t **start, + yaml_char_t **pointer, yaml_char_t **end); + +YAML_DECLARE(int) +yaml_string_join( + yaml_char_t **a_start, yaml_char_t **a_pointer, yaml_char_t **a_end, + yaml_char_t **b_start, yaml_char_t **b_pointer, yaml_char_t **b_end); + +#define NULL_STRING { NULL, NULL, NULL } + +#define STRING(string,length) { (string), (string)+(length), (string) } + +#define STRING_ASSIGN(value,string,length) \ + ((value).start = (string), \ + (value).end = (string)+(length), \ + (value).pointer = (string)) + +#define STRING_INIT(context,string,size) \ + (((string).start = yaml_malloc(size)) ? \ + ((string).pointer = (string).start, \ + (string).end = (string).start+(size), \ + memset((string).start, 0, (size)), \ + 1) : \ + ((context)->error = YAML_MEMORY_ERROR, \ + 0)) + +#define STRING_DEL(context,string) \ + (yaml_free((string).start), \ + (string).start = (string).pointer = (string).end = 0) + +#define STRING_EXTEND(context,string) \ + ((((string).pointer+5 < (string).end) \ + || yaml_string_extend(&(string).start, \ + &(string).pointer, &(string).end)) ? \ + 1 : \ + ((context)->error = YAML_MEMORY_ERROR, \ + 0)) + +#define CLEAR(context,string) \ + ((string).pointer = (string).start, \ + memset((string).start, 0, (string).end-(string).start)) + +#define JOIN(context,string_a,string_b) \ + ((yaml_string_join(&(string_a).start, &(string_a).pointer, \ + &(string_a).end, &(string_b).start, \ + &(string_b).pointer, &(string_b).end)) ? \ + ((string_b).pointer = (string_b).start, \ + 1) : \ + ((context)->error = YAML_MEMORY_ERROR, \ + 0)) + +/* + * String check operations. + */ + +/* + * Check the octet at the specified position. + */ + +#define CHECK_AT(string,octet,offset) \ + ((string).pointer[offset] == (yaml_char_t)(octet)) + +/* + * Check the current octet in the buffer. + */ + +#define CHECK(string,octet) CHECK_AT((string),(octet),0) + +/* + * Check if the character at the specified position is an alphabetical + * character, a digit, '_', or '-'. + */ + +#define IS_ALPHA_AT(string,offset) \ + (((string).pointer[offset] >= (yaml_char_t) '0' && \ + (string).pointer[offset] <= (yaml_char_t) '9') || \ + ((string).pointer[offset] >= (yaml_char_t) 'A' && \ + (string).pointer[offset] <= (yaml_char_t) 'Z') || \ + ((string).pointer[offset] >= (yaml_char_t) 'a' && \ + (string).pointer[offset] <= (yaml_char_t) 'z') || \ + (string).pointer[offset] == '_' || \ + (string).pointer[offset] == '-') + +#define IS_ALPHA(string) IS_ALPHA_AT((string),0) + +/* + * Check if the character at the specified position is a digit. + */ + +#define IS_DIGIT_AT(string,offset) \ + (((string).pointer[offset] >= (yaml_char_t) '0' && \ + (string).pointer[offset] <= (yaml_char_t) '9')) + +#define IS_DIGIT(string) IS_DIGIT_AT((string),0) + +/* + * Get the value of a digit. + */ + +#define AS_DIGIT_AT(string,offset) \ + ((string).pointer[offset] - (yaml_char_t) '0') + +#define AS_DIGIT(string) AS_DIGIT_AT((string),0) + +/* + * Check if the character at the specified position is a hex-digit. + */ + +#define IS_HEX_AT(string,offset) \ + (((string).pointer[offset] >= (yaml_char_t) '0' && \ + (string).pointer[offset] <= (yaml_char_t) '9') || \ + ((string).pointer[offset] >= (yaml_char_t) 'A' && \ + (string).pointer[offset] <= (yaml_char_t) 'F') || \ + ((string).pointer[offset] >= (yaml_char_t) 'a' && \ + (string).pointer[offset] <= (yaml_char_t) 'f')) + +#define IS_HEX(string) IS_HEX_AT((string),0) + +/* + * Get the value of a hex-digit. + */ + +#define AS_HEX_AT(string,offset) \ + (((string).pointer[offset] >= (yaml_char_t) 'A' && \ + (string).pointer[offset] <= (yaml_char_t) 'F') ? \ + ((string).pointer[offset] - (yaml_char_t) 'A' + 10) : \ + ((string).pointer[offset] >= (yaml_char_t) 'a' && \ + (string).pointer[offset] <= (yaml_char_t) 'f') ? \ + ((string).pointer[offset] - (yaml_char_t) 'a' + 10) : \ + ((string).pointer[offset] - (yaml_char_t) '0')) + +#define AS_HEX(string) AS_HEX_AT((string),0) + +/* + * Check if the character is ASCII. + */ + +#define IS_ASCII_AT(string,offset) \ + ((string).pointer[offset] <= (yaml_char_t) '\x7F') + +#define IS_ASCII(string) IS_ASCII_AT((string),0) + +/* + * Check if the character can be printed unescaped. + */ + +#define IS_PRINTABLE_AT(string,offset) \ + (((string).pointer[offset] == 0x0A) /* . == #x0A */ \ + || ((string).pointer[offset] >= 0x20 /* #x20 <= . <= #x7E */ \ + && (string).pointer[offset] <= 0x7E) \ + || ((string).pointer[offset] == 0xC2 /* #0xA0 <= . <= #xD7FF */ \ + && (string).pointer[offset+1] >= 0xA0) \ + || ((string).pointer[offset] > 0xC2 \ + && (string).pointer[offset] < 0xED) \ + || ((string).pointer[offset] == 0xED \ + && (string).pointer[offset+1] < 0xA0) \ + || ((string).pointer[offset] == 0xEE) \ + || ((string).pointer[offset] == 0xEF /* #xE000 <= . <= #xFFFD */ \ + && !((string).pointer[offset+1] == 0xBB /* && . != #xFEFF */ \ + && (string).pointer[offset+2] == 0xBF) \ + && !((string).pointer[offset+1] == 0xBF \ + && ((string).pointer[offset+2] == 0xBE \ + || (string).pointer[offset+2] == 0xBF)))) + +#define IS_PRINTABLE(string) IS_PRINTABLE_AT((string),0) + +/* + * Check if the character at the specified position is NUL. + */ + +#define IS_Z_AT(string,offset) CHECK_AT((string),'\0',(offset)) + +#define IS_Z(string) IS_Z_AT((string),0) + +/* + * Check if the character at the specified position is BOM. + */ + +#define IS_BOM_AT(string,offset) \ + (CHECK_AT((string),'\xEF',(offset)) \ + && CHECK_AT((string),'\xBB',(offset)+1) \ + && CHECK_AT((string),'\xBF',(offset)+2)) /* BOM (#xFEFF) */ + +#define IS_BOM(string) IS_BOM_AT(string,0) + +/* + * Check if the character at the specified position is space. + */ + +#define IS_SPACE_AT(string,offset) CHECK_AT((string),' ',(offset)) + +#define IS_SPACE(string) IS_SPACE_AT((string),0) + +/* + * Check if the character at the specified position is tab. + */ + +#define IS_TAB_AT(string,offset) CHECK_AT((string),'\t',(offset)) + +#define IS_TAB(string) IS_TAB_AT((string),0) + +/* + * Check if the character at the specified position is blank (space or tab). + */ + +#define IS_BLANK_AT(string,offset) \ + (IS_SPACE_AT((string),(offset)) || IS_TAB_AT((string),(offset))) + +#define IS_BLANK(string) IS_BLANK_AT((string),0) + +/* + * Check if the character at the specified position is a line break. + */ + +#define IS_BREAK_AT(string,offset) \ + (CHECK_AT((string),'\r',(offset)) /* CR (#xD)*/ \ + || CHECK_AT((string),'\n',(offset)) /* LF (#xA) */ \ + || (CHECK_AT((string),'\xC2',(offset)) \ + && CHECK_AT((string),'\x85',(offset)+1)) /* NEL (#x85) */ \ + || (CHECK_AT((string),'\xE2',(offset)) \ + && CHECK_AT((string),'\x80',(offset)+1) \ + && CHECK_AT((string),'\xA8',(offset)+2)) /* LS (#x2028) */ \ + || (CHECK_AT((string),'\xE2',(offset)) \ + && CHECK_AT((string),'\x80',(offset)+1) \ + && CHECK_AT((string),'\xA9',(offset)+2))) /* PS (#x2029) */ + +#define IS_BREAK(string) IS_BREAK_AT((string),0) + +#define IS_CRLF_AT(string,offset) \ + (CHECK_AT((string),'\r',(offset)) && CHECK_AT((string),'\n',(offset)+1)) + +#define IS_CRLF(string) IS_CRLF_AT((string),0) + +/* + * Check if the character is a line break or NUL. + */ + +#define IS_BREAKZ_AT(string,offset) \ + (IS_BREAK_AT((string),(offset)) || IS_Z_AT((string),(offset))) + +#define IS_BREAKZ(string) IS_BREAKZ_AT((string),0) + +/* + * Check if the character is a line break, space, or NUL. + */ + +#define IS_SPACEZ_AT(string,offset) \ + (IS_SPACE_AT((string),(offset)) || IS_BREAKZ_AT((string),(offset))) + +#define IS_SPACEZ(string) IS_SPACEZ_AT((string),0) + +/* + * Check if the character is a line break, space, tab, or NUL. + */ + +#define IS_BLANKZ_AT(string,offset) \ + (IS_BLANK_AT((string),(offset)) || IS_BREAKZ_AT((string),(offset))) + +#define IS_BLANKZ(string) IS_BLANKZ_AT((string),0) + +/* + * Determine the width of the character. + */ + +#define WIDTH_AT(string,offset) \ + (((string).pointer[offset] & 0x80) == 0x00 ? 1 : \ + ((string).pointer[offset] & 0xE0) == 0xC0 ? 2 : \ + ((string).pointer[offset] & 0xF0) == 0xE0 ? 3 : \ + ((string).pointer[offset] & 0xF8) == 0xF0 ? 4 : 0) + +#define WIDTH(string) WIDTH_AT((string),0) + +/* + * Move the string pointer to the next character. + */ + +#define MOVE(string) ((string).pointer += WIDTH((string))) + +/* + * Copy a character and move the pointers of both strings. + */ + +#define COPY(string_a,string_b) \ + ((*(string_b).pointer & 0x80) == 0x00 ? \ + (*((string_a).pointer++) = *((string_b).pointer++)) : \ + (*(string_b).pointer & 0xE0) == 0xC0 ? \ + (*((string_a).pointer++) = *((string_b).pointer++), \ + *((string_a).pointer++) = *((string_b).pointer++)) : \ + (*(string_b).pointer & 0xF0) == 0xE0 ? \ + (*((string_a).pointer++) = *((string_b).pointer++), \ + *((string_a).pointer++) = *((string_b).pointer++), \ + *((string_a).pointer++) = *((string_b).pointer++)) : \ + (*(string_b).pointer & 0xF8) == 0xF0 ? \ + (*((string_a).pointer++) = *((string_b).pointer++), \ + *((string_a).pointer++) = *((string_b).pointer++), \ + *((string_a).pointer++) = *((string_b).pointer++), \ + *((string_a).pointer++) = *((string_b).pointer++)) : 0) + +/* + * Stack and queue management. + */ + +YAML_DECLARE(int) +yaml_stack_extend(void **start, void **top, void **end); + +YAML_DECLARE(int) +yaml_queue_extend(void **start, void **head, void **tail, void **end); + +#define STACK_INIT(context,stack,size) \ + (((stack).start = yaml_malloc((size)*sizeof(*(stack).start))) ? \ + ((stack).top = (stack).start, \ + (stack).end = (stack).start+(size), \ + 1) : \ + ((context)->error = YAML_MEMORY_ERROR, \ + 0)) + +#define STACK_DEL(context,stack) \ + (yaml_free((stack).start), \ + (stack).start = (stack).top = (stack).end = 0) + +#define STACK_EMPTY(context,stack) \ + ((stack).start == (stack).top) + +#define STACK_LIMIT(context,stack,size) \ + ((stack).top - (stack).start < (size) ? \ + 1 : \ + ((context)->error = YAML_MEMORY_ERROR, \ + 0)) + +#define PUSH(context,stack,value) \ + (((stack).top != (stack).end \ + || yaml_stack_extend((void **)&(stack).start, \ + (void **)&(stack).top, (void **)&(stack).end)) ? \ + (*((stack).top++) = value, \ + 1) : \ + ((context)->error = YAML_MEMORY_ERROR, \ + 0)) + +#define POP(context,stack) \ + (*(--(stack).top)) + +#define QUEUE_INIT(context,queue,size) \ + (((queue).start = yaml_malloc((size)*sizeof(*(queue).start))) ? \ + ((queue).head = (queue).tail = (queue).start, \ + (queue).end = (queue).start+(size), \ + 1) : \ + ((context)->error = YAML_MEMORY_ERROR, \ + 0)) + +#define QUEUE_DEL(context,queue) \ + (yaml_free((queue).start), \ + (queue).start = (queue).head = (queue).tail = (queue).end = 0) + +#define QUEUE_EMPTY(context,queue) \ + ((queue).head == (queue).tail) + +#define ENQUEUE(context,queue,value) \ + (((queue).tail != (queue).end \ + || yaml_queue_extend((void **)&(queue).start, (void **)&(queue).head, \ + (void **)&(queue).tail, (void **)&(queue).end)) ? \ + (*((queue).tail++) = value, \ + 1) : \ + ((context)->error = YAML_MEMORY_ERROR, \ + 0)) + +#define DEQUEUE(context,queue) \ + (*((queue).head++)) + +#define QUEUE_INSERT(context,queue,index,value) \ + (((queue).tail != (queue).end \ + || yaml_queue_extend((void **)&(queue).start, (void **)&(queue).head, \ + (void **)&(queue).tail, (void **)&(queue).end)) ? \ + (memmove((queue).head+(index)+1,(queue).head+(index), \ + ((queue).tail-(queue).head-(index))*sizeof(*(queue).start)), \ + *((queue).head+(index)) = value, \ + (queue).tail++, \ + 1) : \ + ((context)->error = YAML_MEMORY_ERROR, \ + 0)) + +/* + * Token initializers. + */ + +#define TOKEN_INIT(token,token_type,token_start_mark,token_end_mark) \ + (memset(&(token), 0, sizeof(yaml_token_t)), \ + (token).type = (token_type), \ + (token).start_mark = (token_start_mark), \ + (token).end_mark = (token_end_mark)) + +#define STREAM_START_TOKEN_INIT(token,token_encoding,start_mark,end_mark) \ + (TOKEN_INIT((token),YAML_STREAM_START_TOKEN,(start_mark),(end_mark)), \ + (token).data.stream_start.encoding = (token_encoding)) + +#define STREAM_END_TOKEN_INIT(token,start_mark,end_mark) \ + (TOKEN_INIT((token),YAML_STREAM_END_TOKEN,(start_mark),(end_mark))) + +#define ALIAS_TOKEN_INIT(token,token_value,start_mark,end_mark) \ + (TOKEN_INIT((token),YAML_ALIAS_TOKEN,(start_mark),(end_mark)), \ + (token).data.alias.value = (token_value)) + +#define ANCHOR_TOKEN_INIT(token,token_value,start_mark,end_mark) \ + (TOKEN_INIT((token),YAML_ANCHOR_TOKEN,(start_mark),(end_mark)), \ + (token).data.anchor.value = (token_value)) + +#define TAG_TOKEN_INIT(token,token_handle,token_suffix,start_mark,end_mark) \ + (TOKEN_INIT((token),YAML_TAG_TOKEN,(start_mark),(end_mark)), \ + (token).data.tag.handle = (token_handle), \ + (token).data.tag.suffix = (token_suffix)) + +#define SCALAR_TOKEN_INIT(token,token_value,token_length,token_style,start_mark,end_mark) \ + (TOKEN_INIT((token),YAML_SCALAR_TOKEN,(start_mark),(end_mark)), \ + (token).data.scalar.value = (token_value), \ + (token).data.scalar.length = (token_length), \ + (token).data.scalar.style = (token_style)) + +#define VERSION_DIRECTIVE_TOKEN_INIT(token,token_major,token_minor,start_mark,end_mark) \ + (TOKEN_INIT((token),YAML_VERSION_DIRECTIVE_TOKEN,(start_mark),(end_mark)), \ + (token).data.version_directive.major = (token_major), \ + (token).data.version_directive.minor = (token_minor)) + +#define TAG_DIRECTIVE_TOKEN_INIT(token,token_handle,token_prefix,start_mark,end_mark) \ + (TOKEN_INIT((token),YAML_TAG_DIRECTIVE_TOKEN,(start_mark),(end_mark)), \ + (token).data.tag_directive.handle = (token_handle), \ + (token).data.tag_directive.prefix = (token_prefix)) + +/* + * Event initializers. + */ + +#define EVENT_INIT(event,event_type,event_start_mark,event_end_mark) \ + (memset(&(event), 0, sizeof(yaml_event_t)), \ + (event).type = (event_type), \ + (event).start_mark = (event_start_mark), \ + (event).end_mark = (event_end_mark)) + +#define STREAM_START_EVENT_INIT(event,event_encoding,start_mark,end_mark) \ + (EVENT_INIT((event),YAML_STREAM_START_EVENT,(start_mark),(end_mark)), \ + (event).data.stream_start.encoding = (event_encoding)) + +#define STREAM_END_EVENT_INIT(event,start_mark,end_mark) \ + (EVENT_INIT((event),YAML_STREAM_END_EVENT,(start_mark),(end_mark))) + +#define DOCUMENT_START_EVENT_INIT(event,event_version_directive, \ + event_tag_directives_start,event_tag_directives_end,event_implicit,start_mark,end_mark) \ + (EVENT_INIT((event),YAML_DOCUMENT_START_EVENT,(start_mark),(end_mark)), \ + (event).data.document_start.version_directive = (event_version_directive), \ + (event).data.document_start.tag_directives.start = (event_tag_directives_start), \ + (event).data.document_start.tag_directives.end = (event_tag_directives_end), \ + (event).data.document_start.implicit = (event_implicit)) + +#define DOCUMENT_END_EVENT_INIT(event,event_implicit,start_mark,end_mark) \ + (EVENT_INIT((event),YAML_DOCUMENT_END_EVENT,(start_mark),(end_mark)), \ + (event).data.document_end.implicit = (event_implicit)) + +#define ALIAS_EVENT_INIT(event,event_anchor,start_mark,end_mark) \ + (EVENT_INIT((event),YAML_ALIAS_EVENT,(start_mark),(end_mark)), \ + (event).data.alias.anchor = (event_anchor)) + +#define SCALAR_EVENT_INIT(event,event_anchor,event_tag,event_value,event_length, \ + event_plain_implicit, event_quoted_implicit,event_style,start_mark,end_mark) \ + (EVENT_INIT((event),YAML_SCALAR_EVENT,(start_mark),(end_mark)), \ + (event).data.scalar.anchor = (event_anchor), \ + (event).data.scalar.tag = (event_tag), \ + (event).data.scalar.value = (event_value), \ + (event).data.scalar.length = (event_length), \ + (event).data.scalar.plain_implicit = (event_plain_implicit), \ + (event).data.scalar.quoted_implicit = (event_quoted_implicit), \ + (event).data.scalar.style = (event_style)) + +#define SEQUENCE_START_EVENT_INIT(event,event_anchor,event_tag, \ + event_implicit,event_style,start_mark,end_mark) \ + (EVENT_INIT((event),YAML_SEQUENCE_START_EVENT,(start_mark),(end_mark)), \ + (event).data.sequence_start.anchor = (event_anchor), \ + (event).data.sequence_start.tag = (event_tag), \ + (event).data.sequence_start.implicit = (event_implicit), \ + (event).data.sequence_start.style = (event_style)) + +#define SEQUENCE_END_EVENT_INIT(event,start_mark,end_mark) \ + (EVENT_INIT((event),YAML_SEQUENCE_END_EVENT,(start_mark),(end_mark))) + +#define MAPPING_START_EVENT_INIT(event,event_anchor,event_tag, \ + event_implicit,event_style,start_mark,end_mark) \ + (EVENT_INIT((event),YAML_MAPPING_START_EVENT,(start_mark),(end_mark)), \ + (event).data.mapping_start.anchor = (event_anchor), \ + (event).data.mapping_start.tag = (event_tag), \ + (event).data.mapping_start.implicit = (event_implicit), \ + (event).data.mapping_start.style = (event_style)) + +#define MAPPING_END_EVENT_INIT(event,start_mark,end_mark) \ + (EVENT_INIT((event),YAML_MAPPING_END_EVENT,(start_mark),(end_mark))) + +/* + * Document initializer. + */ + +#define DOCUMENT_INIT(document,document_nodes_start,document_nodes_end, \ + document_version_directive,document_tag_directives_start, \ + document_tag_directives_end,document_start_implicit, \ + document_end_implicit,document_start_mark,document_end_mark) \ + (memset(&(document), 0, sizeof(yaml_document_t)), \ + (document).nodes.start = (document_nodes_start), \ + (document).nodes.end = (document_nodes_end), \ + (document).nodes.top = (document_nodes_start), \ + (document).version_directive = (document_version_directive), \ + (document).tag_directives.start = (document_tag_directives_start), \ + (document).tag_directives.end = (document_tag_directives_end), \ + (document).start_implicit = (document_start_implicit), \ + (document).end_implicit = (document_end_implicit), \ + (document).start_mark = (document_start_mark), \ + (document).end_mark = (document_end_mark)) + +/* + * Node initializers. + */ + +#define NODE_INIT(node,node_type,node_tag,node_start_mark,node_end_mark) \ + (memset(&(node), 0, sizeof(yaml_node_t)), \ + (node).type = (node_type), \ + (node).tag = (node_tag), \ + (node).start_mark = (node_start_mark), \ + (node).end_mark = (node_end_mark)) + +#define SCALAR_NODE_INIT(node,node_tag,node_value,node_length, \ + node_style,start_mark,end_mark) \ + (NODE_INIT((node),YAML_SCALAR_NODE,(node_tag),(start_mark),(end_mark)), \ + (node).data.scalar.value = (node_value), \ + (node).data.scalar.length = (node_length), \ + (node).data.scalar.style = (node_style)) + +#define SEQUENCE_NODE_INIT(node,node_tag,node_items_start,node_items_end, \ + node_style,start_mark,end_mark) \ + (NODE_INIT((node),YAML_SEQUENCE_NODE,(node_tag),(start_mark),(end_mark)), \ + (node).data.sequence.items.start = (node_items_start), \ + (node).data.sequence.items.end = (node_items_end), \ + (node).data.sequence.items.top = (node_items_start), \ + (node).data.sequence.style = (node_style)) + +#define MAPPING_NODE_INIT(node,node_tag,node_pairs_start,node_pairs_end, \ + node_style,start_mark,end_mark) \ + (NODE_INIT((node),YAML_MAPPING_NODE,(node_tag),(start_mark),(end_mark)), \ + (node).data.mapping.pairs.start = (node_pairs_start), \ + (node).data.mapping.pairs.end = (node_pairs_end), \ + (node).data.mapping.pairs.top = (node_pairs_start), \ + (node).data.mapping.style = (node_style)) + diff --git a/web/server/h2o/libh2o/deps/yaml/tests/Makefile.am b/web/server/h2o/libh2o/deps/yaml/tests/Makefile.am new file mode 100644 index 00000000..72e84d2a --- /dev/null +++ b/web/server/h2o/libh2o/deps/yaml/tests/Makefile.am @@ -0,0 +1,8 @@ +AM_CPPFLAGS = -I$(top_srcdir)/include +#AM_CFLAGS = -Wno-pointer-sign +LDADD = $(top_builddir)/src/libyaml.la +TESTS = test-version test-reader +check_PROGRAMS = test-version test-reader +noinst_PROGRAMS = run-scanner run-parser run-loader run-emitter run-dumper \ + example-reformatter example-reformatter-alt \ + example-deconstructor example-deconstructor-alt diff --git a/web/server/h2o/libh2o/deps/yaml/tests/Makefile.in b/web/server/h2o/libh2o/deps/yaml/tests/Makefile.in new file mode 100644 index 00000000..1aac554e --- /dev/null +++ b/web/server/h2o/libh2o/deps/yaml/tests/Makefile.in @@ -0,0 +1,680 @@ +# Makefile.in generated by automake 1.11.3 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software +# Foundation, Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +TESTS = test-version$(EXEEXT) test-reader$(EXEEXT) +check_PROGRAMS = test-version$(EXEEXT) test-reader$(EXEEXT) +noinst_PROGRAMS = run-scanner$(EXEEXT) run-parser$(EXEEXT) \ + run-loader$(EXEEXT) run-emitter$(EXEEXT) run-dumper$(EXEEXT) \ + example-reformatter$(EXEEXT) example-reformatter-alt$(EXEEXT) \ + example-deconstructor$(EXEEXT) \ + example-deconstructor-alt$(EXEEXT) +subdir = tests +DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +PROGRAMS = $(noinst_PROGRAMS) +example_deconstructor_SOURCES = example-deconstructor.c +example_deconstructor_OBJECTS = example-deconstructor.$(OBJEXT) +example_deconstructor_LDADD = $(LDADD) +example_deconstructor_DEPENDENCIES = $(top_builddir)/src/libyaml.la +example_deconstructor_alt_SOURCES = example-deconstructor-alt.c +example_deconstructor_alt_OBJECTS = \ + example-deconstructor-alt.$(OBJEXT) +example_deconstructor_alt_LDADD = $(LDADD) +example_deconstructor_alt_DEPENDENCIES = \ + $(top_builddir)/src/libyaml.la +example_reformatter_SOURCES = example-reformatter.c +example_reformatter_OBJECTS = example-reformatter.$(OBJEXT) +example_reformatter_LDADD = $(LDADD) +example_reformatter_DEPENDENCIES = $(top_builddir)/src/libyaml.la +example_reformatter_alt_SOURCES = example-reformatter-alt.c +example_reformatter_alt_OBJECTS = example-reformatter-alt.$(OBJEXT) +example_reformatter_alt_LDADD = $(LDADD) +example_reformatter_alt_DEPENDENCIES = $(top_builddir)/src/libyaml.la +run_dumper_SOURCES = run-dumper.c +run_dumper_OBJECTS = run-dumper.$(OBJEXT) +run_dumper_LDADD = $(LDADD) +run_dumper_DEPENDENCIES = $(top_builddir)/src/libyaml.la +run_emitter_SOURCES = run-emitter.c +run_emitter_OBJECTS = run-emitter.$(OBJEXT) +run_emitter_LDADD = $(LDADD) +run_emitter_DEPENDENCIES = $(top_builddir)/src/libyaml.la +run_loader_SOURCES = run-loader.c +run_loader_OBJECTS = run-loader.$(OBJEXT) +run_loader_LDADD = $(LDADD) +run_loader_DEPENDENCIES = $(top_builddir)/src/libyaml.la +run_parser_SOURCES = run-parser.c +run_parser_OBJECTS = run-parser.$(OBJEXT) +run_parser_LDADD = $(LDADD) +run_parser_DEPENDENCIES = $(top_builddir)/src/libyaml.la +run_scanner_SOURCES = run-scanner.c +run_scanner_OBJECTS = run-scanner.$(OBJEXT) +run_scanner_LDADD = $(LDADD) +run_scanner_DEPENDENCIES = $(top_builddir)/src/libyaml.la +test_reader_SOURCES = test-reader.c +test_reader_OBJECTS = test-reader.$(OBJEXT) +test_reader_LDADD = $(LDADD) +test_reader_DEPENDENCIES = $(top_builddir)/src/libyaml.la +test_version_SOURCES = test-version.c +test_version_OBJECTS = test-version.$(OBJEXT) +test_version_LDADD = $(LDADD) +test_version_DEPENDENCIES = $(top_builddir)/src/libyaml.la +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/config/depcomp +am__depfiles_maybe = depfiles +am__mv = mv -f +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +CCLD = $(CC) +LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ + $(LDFLAGS) -o $@ +SOURCES = example-deconstructor.c example-deconstructor-alt.c \ + example-reformatter.c example-reformatter-alt.c run-dumper.c \ + run-emitter.c run-loader.c run-parser.c run-scanner.c \ + test-reader.c test-version.c +DIST_SOURCES = example-deconstructor.c example-deconstructor-alt.c \ + example-reformatter.c example-reformatter-alt.c run-dumper.c \ + run-emitter.c run-loader.c run-parser.c run-scanner.c \ + test-reader.c test-version.c +ETAGS = etags +CTAGS = ctags +am__tty_colors = \ +red=; grn=; lgn=; blu=; std= +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DOXYGEN = @DOXYGEN@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +GREP = @GREP@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +YAML_LT_AGE = @YAML_LT_AGE@ +YAML_LT_CURRENT = @YAML_LT_CURRENT@ +YAML_LT_RELEASE = @YAML_LT_RELEASE@ +YAML_LT_REVISION = @YAML_LT_REVISION@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +AM_CPPFLAGS = -I$(top_srcdir)/include +#AM_CFLAGS = -Wno-pointer-sign +LDADD = $(top_builddir)/src/libyaml.la +all: all-am + +.SUFFIXES: +.SUFFIXES: .c .lo .o .obj +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign tests/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --foreign tests/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +clean-checkPROGRAMS: + @list='$(check_PROGRAMS)'; test -n "$$list" || exit 0; \ + echo " rm -f" $$list; \ + rm -f $$list || exit $$?; \ + test -n "$(EXEEXT)" || exit 0; \ + list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ + echo " rm -f" $$list; \ + rm -f $$list + +clean-noinstPROGRAMS: + @list='$(noinst_PROGRAMS)'; test -n "$$list" || exit 0; \ + echo " rm -f" $$list; \ + rm -f $$list || exit $$?; \ + test -n "$(EXEEXT)" || exit 0; \ + list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ + echo " rm -f" $$list; \ + rm -f $$list +example-deconstructor$(EXEEXT): $(example_deconstructor_OBJECTS) $(example_deconstructor_DEPENDENCIES) $(EXTRA_example_deconstructor_DEPENDENCIES) + @rm -f example-deconstructor$(EXEEXT) + $(LINK) $(example_deconstructor_OBJECTS) $(example_deconstructor_LDADD) $(LIBS) +example-deconstructor-alt$(EXEEXT): $(example_deconstructor_alt_OBJECTS) $(example_deconstructor_alt_DEPENDENCIES) $(EXTRA_example_deconstructor_alt_DEPENDENCIES) + @rm -f example-deconstructor-alt$(EXEEXT) + $(LINK) $(example_deconstructor_alt_OBJECTS) $(example_deconstructor_alt_LDADD) $(LIBS) +example-reformatter$(EXEEXT): $(example_reformatter_OBJECTS) $(example_reformatter_DEPENDENCIES) $(EXTRA_example_reformatter_DEPENDENCIES) + @rm -f example-reformatter$(EXEEXT) + $(LINK) $(example_reformatter_OBJECTS) $(example_reformatter_LDADD) $(LIBS) +example-reformatter-alt$(EXEEXT): $(example_reformatter_alt_OBJECTS) $(example_reformatter_alt_DEPENDENCIES) $(EXTRA_example_reformatter_alt_DEPENDENCIES) + @rm -f example-reformatter-alt$(EXEEXT) + $(LINK) $(example_reformatter_alt_OBJECTS) $(example_reformatter_alt_LDADD) $(LIBS) +run-dumper$(EXEEXT): $(run_dumper_OBJECTS) $(run_dumper_DEPENDENCIES) $(EXTRA_run_dumper_DEPENDENCIES) + @rm -f run-dumper$(EXEEXT) + $(LINK) $(run_dumper_OBJECTS) $(run_dumper_LDADD) $(LIBS) +run-emitter$(EXEEXT): $(run_emitter_OBJECTS) $(run_emitter_DEPENDENCIES) $(EXTRA_run_emitter_DEPENDENCIES) + @rm -f run-emitter$(EXEEXT) + $(LINK) $(run_emitter_OBJECTS) $(run_emitter_LDADD) $(LIBS) +run-loader$(EXEEXT): $(run_loader_OBJECTS) $(run_loader_DEPENDENCIES) $(EXTRA_run_loader_DEPENDENCIES) + @rm -f run-loader$(EXEEXT) + $(LINK) $(run_loader_OBJECTS) $(run_loader_LDADD) $(LIBS) +run-parser$(EXEEXT): $(run_parser_OBJECTS) $(run_parser_DEPENDENCIES) $(EXTRA_run_parser_DEPENDENCIES) + @rm -f run-parser$(EXEEXT) + $(LINK) $(run_parser_OBJECTS) $(run_parser_LDADD) $(LIBS) +run-scanner$(EXEEXT): $(run_scanner_OBJECTS) $(run_scanner_DEPENDENCIES) $(EXTRA_run_scanner_DEPENDENCIES) + @rm -f run-scanner$(EXEEXT) + $(LINK) $(run_scanner_OBJECTS) $(run_scanner_LDADD) $(LIBS) +test-reader$(EXEEXT): $(test_reader_OBJECTS) $(test_reader_DEPENDENCIES) $(EXTRA_test_reader_DEPENDENCIES) + @rm -f test-reader$(EXEEXT) + $(LINK) $(test_reader_OBJECTS) $(test_reader_LDADD) $(LIBS) +test-version$(EXEEXT): $(test_version_OBJECTS) $(test_version_DEPENDENCIES) $(EXTRA_test_version_DEPENDENCIES) + @rm -f test-version$(EXEEXT) + $(LINK) $(test_version_OBJECTS) $(test_version_LDADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/example-deconstructor-alt.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/example-deconstructor.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/example-reformatter-alt.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/example-reformatter.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/run-dumper.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/run-emitter.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/run-loader.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/run-parser.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/run-scanner.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-reader.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-version.Po@am__quote@ + +.c.o: +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c $< + +.c.obj: +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` + +.c.lo: +@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $< + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + set x; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: CTAGS +CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +check-TESTS: $(TESTS) + @failed=0; all=0; xfail=0; xpass=0; skip=0; \ + srcdir=$(srcdir); export srcdir; \ + list=' $(TESTS) '; \ + $(am__tty_colors); \ + if test -n "$$list"; then \ + for tst in $$list; do \ + if test -f ./$$tst; then dir=./; \ + elif test -f $$tst; then dir=; \ + else dir="$(srcdir)/"; fi; \ + if $(TESTS_ENVIRONMENT) $${dir}$$tst; then \ + all=`expr $$all + 1`; \ + case " $(XFAIL_TESTS) " in \ + *[\ \ ]$$tst[\ \ ]*) \ + xpass=`expr $$xpass + 1`; \ + failed=`expr $$failed + 1`; \ + col=$$red; res=XPASS; \ + ;; \ + *) \ + col=$$grn; res=PASS; \ + ;; \ + esac; \ + elif test $$? -ne 77; then \ + all=`expr $$all + 1`; \ + case " $(XFAIL_TESTS) " in \ + *[\ \ ]$$tst[\ \ ]*) \ + xfail=`expr $$xfail + 1`; \ + col=$$lgn; res=XFAIL; \ + ;; \ + *) \ + failed=`expr $$failed + 1`; \ + col=$$red; res=FAIL; \ + ;; \ + esac; \ + else \ + skip=`expr $$skip + 1`; \ + col=$$blu; res=SKIP; \ + fi; \ + echo "$${col}$$res$${std}: $$tst"; \ + done; \ + if test "$$all" -eq 1; then \ + tests="test"; \ + All=""; \ + else \ + tests="tests"; \ + All="All "; \ + fi; \ + if test "$$failed" -eq 0; then \ + if test "$$xfail" -eq 0; then \ + banner="$$All$$all $$tests passed"; \ + else \ + if test "$$xfail" -eq 1; then failures=failure; else failures=failures; fi; \ + banner="$$All$$all $$tests behaved as expected ($$xfail expected $$failures)"; \ + fi; \ + else \ + if test "$$xpass" -eq 0; then \ + banner="$$failed of $$all $$tests failed"; \ + else \ + if test "$$xpass" -eq 1; then passes=pass; else passes=passes; fi; \ + banner="$$failed of $$all $$tests did not behave as expected ($$xpass unexpected $$passes)"; \ + fi; \ + fi; \ + dashes="$$banner"; \ + skipped=""; \ + if test "$$skip" -ne 0; then \ + if test "$$skip" -eq 1; then \ + skipped="($$skip test was not run)"; \ + else \ + skipped="($$skip tests were not run)"; \ + fi; \ + test `echo "$$skipped" | wc -c` -le `echo "$$banner" | wc -c` || \ + dashes="$$skipped"; \ + fi; \ + report=""; \ + if test "$$failed" -ne 0 && test -n "$(PACKAGE_BUGREPORT)"; then \ + report="Please report to $(PACKAGE_BUGREPORT)"; \ + test `echo "$$report" | wc -c` -le `echo "$$banner" | wc -c` || \ + dashes="$$report"; \ + fi; \ + dashes=`echo "$$dashes" | sed s/./=/g`; \ + if test "$$failed" -eq 0; then \ + col="$$grn"; \ + else \ + col="$$red"; \ + fi; \ + echo "$${col}$$dashes$${std}"; \ + echo "$${col}$$banner$${std}"; \ + test -z "$$skipped" || echo "$${col}$$skipped$${std}"; \ + test -z "$$report" || echo "$${col}$$report$${std}"; \ + echo "$${col}$$dashes$${std}"; \ + test "$$failed" -eq 0; \ + else :; fi + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am + $(MAKE) $(AM_MAKEFLAGS) $(check_PROGRAMS) + $(MAKE) $(AM_MAKEFLAGS) check-TESTS +check: check-am +all-am: Makefile $(PROGRAMS) +installdirs: +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-checkPROGRAMS clean-generic clean-libtool \ + clean-noinstPROGRAMS mostlyclean-am + +distclean: distclean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: + +.MAKE: check-am install-am install-strip + +.PHONY: CTAGS GTAGS all all-am check check-TESTS check-am clean \ + clean-checkPROGRAMS clean-generic clean-libtool \ + clean-noinstPROGRAMS ctags distclean distclean-compile \ + distclean-generic distclean-libtool distclean-tags distdir dvi \ + dvi-am html html-am info info-am install install-am \ + install-data install-data-am install-dvi install-dvi-am \ + install-exec install-exec-am install-html install-html-am \ + install-info install-info-am install-man install-pdf \ + install-pdf-am install-ps install-ps-am install-strip \ + installcheck installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-compile \ + mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ + tags uninstall uninstall-am + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/web/server/h2o/libh2o/deps/yaml/tests/example-deconstructor-alt.c b/web/server/h2o/libh2o/deps/yaml/tests/example-deconstructor-alt.c new file mode 100644 index 00000000..7da194a6 --- /dev/null +++ b/web/server/h2o/libh2o/deps/yaml/tests/example-deconstructor-alt.c @@ -0,0 +1,800 @@ + +#include + +#include +#include + +int +main(int argc, char *argv[]) +{ + int help = 0; + int canonical = 0; + int unicode = 0; + int k; + int done = 0; + + yaml_parser_t parser; + yaml_emitter_t emitter; + yaml_event_t input_event; + yaml_document_t output_document; + + int root; + + /* Clear the objects. */ + + memset(&parser, 0, sizeof(parser)); + memset(&emitter, 0, sizeof(emitter)); + memset(&input_event, 0, sizeof(input_event)); + memset(&output_document, 0, sizeof(output_document)); + + /* Analyze command line options. */ + + for (k = 1; k < argc; k ++) + { + if (strcmp(argv[k], "-h") == 0 + || strcmp(argv[k], "--help") == 0) { + help = 1; + } + + else if (strcmp(argv[k], "-c") == 0 + || strcmp(argv[k], "--canonical") == 0) { + canonical = 1; + } + + else if (strcmp(argv[k], "-u") == 0 + || strcmp(argv[k], "--unicode") == 0) { + unicode = 1; + } + + else { + fprintf(stderr, "Unrecognized option: %s\n" + "Try `%s --help` for more information.\n", + argv[k], argv[0]); + return 1; + } + } + + /* Display the help string. */ + + if (help) + { + printf("%s . */ + + if (input_event.data.stream_start.encoding) + { + yaml_encoding_t encoding + = input_event.data.stream_start.encoding; + + key = yaml_document_add_scalar(&output_document, NULL, + "encoding", -1, YAML_PLAIN_SCALAR_STYLE); + if (!key) goto document_error; + value = yaml_document_add_scalar(&output_document, NULL, + (encoding == YAML_UTF8_ENCODING ? "utf-8" : + encoding == YAML_UTF16LE_ENCODING ? "utf-16-le" : + encoding == YAML_UTF16BE_ENCODING ? "utf-16-be" : + "unknown"), -1, YAML_PLAIN_SCALAR_STYLE); + if (!value) goto document_error; + if (!yaml_document_append_mapping_pair(&output_document, + properties, key, value)) goto document_error; + } + + break; + + case YAML_STREAM_END_EVENT: + + /* Add 'type': 'STREAM-END'. */ + + key = yaml_document_add_scalar(&output_document, NULL, + "type", -1, YAML_PLAIN_SCALAR_STYLE); + if (!key) goto document_error; + value = yaml_document_add_scalar(&output_document, NULL, + "STREAM-END", -1, YAML_PLAIN_SCALAR_STYLE); + if (!value) goto document_error; + if (!yaml_document_append_mapping_pair(&output_document, + properties, key, value)) goto document_error; + + break; + + case YAML_DOCUMENT_START_EVENT: + + /* Add 'type': 'DOCUMENT-START'. */ + + key = yaml_document_add_scalar(&output_document, NULL, + "type", -1, YAML_PLAIN_SCALAR_STYLE); + if (!key) goto document_error; + value = yaml_document_add_scalar(&output_document, NULL, + "DOCUMENT-START", -1, YAML_PLAIN_SCALAR_STYLE); + if (!value) goto document_error; + if (!yaml_document_append_mapping_pair(&output_document, + properties, key, value)) goto document_error; + + /* Display the output_document version numbers. */ + + if (input_event.data.document_start.version_directive) + { + yaml_version_directive_t *version + = input_event.data.document_start.version_directive; + char number[64]; + + /* Add 'version': {}. */ + + key = yaml_document_add_scalar(&output_document, NULL, + "version", -1, YAML_PLAIN_SCALAR_STYLE); + if (!key) goto document_error; + map = yaml_document_add_mapping(&output_document, NULL, + YAML_FLOW_MAPPING_STYLE); + if (!map) goto document_error; + if (!yaml_document_append_mapping_pair(&output_document, + properties, key, map)) goto document_error; + + /* Add 'major': . */ + + key = yaml_document_add_scalar(&output_document, NULL, + "major", -1, YAML_PLAIN_SCALAR_STYLE); + if (!key) goto document_error; + sprintf(number, "%d", version->major); + value = yaml_document_add_scalar(&output_document, YAML_INT_TAG, + number, -1, YAML_PLAIN_SCALAR_STYLE); + if (!value) goto document_error; + if (!yaml_document_append_mapping_pair(&output_document, + map, key, value)) goto document_error; + + /* Add 'minor': . */ + + key = yaml_document_add_scalar(&output_document, NULL, + "minor", -1, YAML_PLAIN_SCALAR_STYLE); + if (!key) goto document_error; + sprintf(number, "%d", version->minor); + value = yaml_document_add_scalar(&output_document, YAML_INT_TAG, + number, -1, YAML_PLAIN_SCALAR_STYLE); + if (!value) goto document_error; + if (!yaml_document_append_mapping_pair(&output_document, + map, key, value)) goto document_error; + } + + /* Display the output_document tag directives. */ + + if (input_event.data.document_start.tag_directives.start + != input_event.data.document_start.tag_directives.end) + { + yaml_tag_directive_t *tag; + + /* Add 'tags': []. */ + + key = yaml_document_add_scalar(&output_document, NULL, + "tags", -1, YAML_PLAIN_SCALAR_STYLE); + if (!key) goto document_error; + seq = yaml_document_add_sequence(&output_document, NULL, + YAML_BLOCK_SEQUENCE_STYLE); + if (!seq) goto document_error; + if (!yaml_document_append_mapping_pair(&output_document, + properties, key, seq)) goto document_error; + + for (tag = input_event.data.document_start.tag_directives.start; + tag != input_event.data.document_start.tag_directives.end; + tag ++) + { + /* Add {}. */ + + map = yaml_document_add_mapping(&output_document, NULL, + YAML_FLOW_MAPPING_STYLE); + if (!map) goto document_error; + if (!yaml_document_append_sequence_item(&output_document, + seq, map)) goto document_error; + + /* Add 'handle': . */ + + key = yaml_document_add_scalar(&output_document, NULL, + "handle", -1, YAML_PLAIN_SCALAR_STYLE); + if (!key) goto document_error; + value = yaml_document_add_scalar(&output_document, NULL, + tag->handle, -1, YAML_DOUBLE_QUOTED_SCALAR_STYLE); + if (!value) goto document_error; + if (!yaml_document_append_mapping_pair(&output_document, + map, key, value)) goto document_error; + + /* Add 'prefix': . */ + + key = yaml_document_add_scalar(&output_document, NULL, + "prefix", -1, YAML_PLAIN_SCALAR_STYLE); + if (!key) goto document_error; + value = yaml_document_add_scalar(&output_document, NULL, + tag->prefix, -1, YAML_DOUBLE_QUOTED_SCALAR_STYLE); + if (!value) goto document_error; + if (!yaml_document_append_mapping_pair(&output_document, + map, key, value)) goto document_error; + } + } + + /* Add 'implicit': . */ + + key = yaml_document_add_scalar(&output_document, NULL, + "implicit", -1, YAML_PLAIN_SCALAR_STYLE); + if (!key) goto document_error; + value = yaml_document_add_scalar(&output_document, YAML_BOOL_TAG, + (input_event.data.document_start.implicit ? + "true" : "false"), -1, YAML_PLAIN_SCALAR_STYLE); + if (!value) goto document_error; + if (!yaml_document_append_mapping_pair(&output_document, + properties, key, value)) goto document_error; + + break; + + case YAML_DOCUMENT_END_EVENT: + + /* Add 'type': 'DOCUMENT-END'. */ + + key = yaml_document_add_scalar(&output_document, NULL, + "type", -1, YAML_PLAIN_SCALAR_STYLE); + if (!key) goto document_error; + value = yaml_document_add_scalar(&output_document, NULL, + "DOCUMENT-END", -1, YAML_PLAIN_SCALAR_STYLE); + if (!value) goto document_error; + if (!yaml_document_append_mapping_pair(&output_document, + properties, key, value)) goto document_error; + + /* Add 'implicit': . */ + + key = yaml_document_add_scalar(&output_document, NULL, + "implicit", -1, YAML_PLAIN_SCALAR_STYLE); + if (!key) goto document_error; + value = yaml_document_add_scalar(&output_document, YAML_BOOL_TAG, + (input_event.data.document_end.implicit ? + "true" : "false"), -1, YAML_PLAIN_SCALAR_STYLE); + if (!value) goto document_error; + if (!yaml_document_append_mapping_pair(&output_document, + properties, key, value)) goto document_error; + + break; + + case YAML_ALIAS_EVENT: + + /* Add 'type': 'ALIAS'. */ + + key = yaml_document_add_scalar(&output_document, NULL, + "type", -1, YAML_PLAIN_SCALAR_STYLE); + if (!key) goto document_error; + value = yaml_document_add_scalar(&output_document, NULL, + "ALIAS", -1, YAML_PLAIN_SCALAR_STYLE); + if (!value) goto document_error; + if (!yaml_document_append_mapping_pair(&output_document, + properties, key, value)) goto document_error; + + /* Add 'anchor': . */ + + key = yaml_document_add_scalar(&output_document, NULL, + "anchor", -1, YAML_PLAIN_SCALAR_STYLE); + if (!key) goto document_error; + value = yaml_document_add_scalar(&output_document, NULL, + input_event.data.alias.anchor, -1, + YAML_DOUBLE_QUOTED_SCALAR_STYLE); + if (!value) goto document_error; + if (!yaml_document_append_mapping_pair(&output_document, + properties, key, value)) goto document_error; + + break; + + case YAML_SCALAR_EVENT: + + /* Add 'type': 'SCALAR'. */ + + key = yaml_document_add_scalar(&output_document, NULL, + "type", -1, YAML_PLAIN_SCALAR_STYLE); + if (!key) goto document_error; + value = yaml_document_add_scalar(&output_document, NULL, + "SCALAR", -1, YAML_PLAIN_SCALAR_STYLE); + if (!value) goto document_error; + if (!yaml_document_append_mapping_pair(&output_document, + properties, key, value)) goto document_error; + + /* Add 'anchor': . */ + + if (input_event.data.scalar.anchor) + { + key = yaml_document_add_scalar(&output_document, NULL, + "anchor", -1, YAML_PLAIN_SCALAR_STYLE); + if (!key) goto document_error; + value = yaml_document_add_scalar(&output_document, NULL, + input_event.data.scalar.anchor, -1, + YAML_DOUBLE_QUOTED_SCALAR_STYLE); + if (!value) goto document_error; + if (!yaml_document_append_mapping_pair(&output_document, + properties, key, value)) goto document_error; + } + + /* Add 'tag': . */ + + if (input_event.data.scalar.tag) + { + key = yaml_document_add_scalar(&output_document, NULL, + "tag", -1, YAML_PLAIN_SCALAR_STYLE); + if (!key) goto document_error; + value = yaml_document_add_scalar(&output_document, NULL, + input_event.data.scalar.tag, -1, + YAML_DOUBLE_QUOTED_SCALAR_STYLE); + if (!value) goto document_error; + if (!yaml_document_append_mapping_pair(&output_document, + properties, key, value)) goto document_error; + } + + /* Add 'value': . */ + + key = yaml_document_add_scalar(&output_document, NULL, + "value", -1, YAML_PLAIN_SCALAR_STYLE); + if (!key) goto document_error; + value = yaml_document_add_scalar(&output_document, NULL, + input_event.data.scalar.value, + input_event.data.scalar.length, + YAML_DOUBLE_QUOTED_SCALAR_STYLE); + if (!value) goto document_error; + if (!yaml_document_append_mapping_pair(&output_document, + properties, key, value)) goto document_error; + + /* Display if the scalar tag is implicit. */ + + /* Add 'implicit': {} */ + + key = yaml_document_add_scalar(&output_document, NULL, + "version", -1, YAML_PLAIN_SCALAR_STYLE); + if (!key) goto document_error; + map = yaml_document_add_mapping(&output_document, NULL, + YAML_FLOW_MAPPING_STYLE); + if (!map) goto document_error; + if (!yaml_document_append_mapping_pair(&output_document, + properties, key, map)) goto document_error; + + /* Add 'plain': . */ + + key = yaml_document_add_scalar(&output_document, NULL, + "plain", -1, YAML_PLAIN_SCALAR_STYLE); + if (!key) goto document_error; + value = yaml_document_add_scalar(&output_document, YAML_BOOL_TAG, + (input_event.data.scalar.plain_implicit ? + "true" : "false"), -1, YAML_PLAIN_SCALAR_STYLE); + if (!value) goto document_error; + if (!yaml_document_append_mapping_pair(&output_document, + map, key, value)) goto document_error; + + /* Add 'quoted': . */ + + key = yaml_document_add_scalar(&output_document, NULL, + "quoted", -1, YAML_PLAIN_SCALAR_STYLE); + if (!key) goto document_error; + value = yaml_document_add_scalar(&output_document, YAML_BOOL_TAG, + (input_event.data.scalar.quoted_implicit ? + "true" : "false"), -1, YAML_PLAIN_SCALAR_STYLE); + if (!value) goto document_error; + if (!yaml_document_append_mapping_pair(&output_document, + map, key, value)) goto document_error; + + /* Display the style information. */ + + if (input_event.data.scalar.style) + { + yaml_scalar_style_t style = input_event.data.scalar.style; + + /* Add 'style':